1(()=>{var __webpack_modules__={151:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{"use strict";eval("\n// EXTERNAL MODULE: ./node_modules/bootstrap/js/dist/collapse.js\nvar collapse = __webpack_require__(647);\n;// CONCATENATED MODULE: ./node_modules/ssr-window/ssr-window.esm.js\n/**\n * SSR Window 4.0.2\n * Better handling for window object in SSR environment\n * https://github.com/nolimits4web/ssr-window\n *\n * Copyright 2021, Vladimir Kharlampidi\n *\n * Licensed under MIT\n *\n * Released on: December 13, 2021\n */\n/* eslint-disable no-param-reassign */\nfunction isObject(obj) {\n return (obj !== null &&\n typeof obj === 'object' &&\n 'constructor' in obj &&\n obj.constructor === Object);\n}\nfunction extend(target = {}, src = {}) {\n Object.keys(src).forEach((key) => {\n if (typeof target[key] === 'undefined')\n target[key] = src[key];\n else if (isObject(src[key]) &&\n isObject(target[key]) &&\n Object.keys(src[key]).length > 0) {\n extend(target[key], src[key]);\n }\n });\n}\n\nconst ssrDocument = {\n body: {},\n addEventListener() { },\n removeEventListener() { },\n activeElement: {\n blur() { },\n nodeName: '',\n },\n querySelector() {\n return null;\n },\n querySelectorAll() {\n return [];\n },\n getElementById() {\n return null;\n },\n createEvent() {\n return {\n initEvent() { },\n };\n },\n createElement() {\n return {\n children: [],\n childNodes: [],\n style: {},\n setAttribute() { },\n getElementsByTagName() {\n return [];\n },\n };\n },\n createElementNS() {\n return {};\n },\n importNode() {\n return null;\n },\n location: {\n hash: '',\n host: '',\n hostname: '',\n href: '',\n origin: '',\n pathname: '',\n protocol: '',\n search: '',\n },\n};\nfunction getDocument() {\n const doc = typeof document !== 'undefined' ? document : {};\n extend(doc, ssrDocument);\n return doc;\n}\n\nconst ssrWindow = {\n document: ssrDocument,\n navigator: {\n userAgent: '',\n },\n location: {\n hash: '',\n host: '',\n hostname: '',\n href: '',\n origin: '',\n pathname: '',\n protocol: '',\n search: '',\n },\n history: {\n replaceState() { },\n pushState() { },\n go() { },\n back() { },\n },\n CustomEvent: function CustomEvent() {\n return this;\n },\n addEventListener() { },\n removeEventListener() { },\n getComputedStyle() {\n return {\n getPropertyValue() {\n return '';\n },\n };\n },\n Image() { },\n Date() { },\n screen: {},\n setTimeout() { },\n clearTimeout() { },\n matchMedia() {\n return {};\n },\n requestAnimationFrame(callback) {\n if (typeof setTimeout === 'undefined') {\n callback();\n return null;\n }\n return setTimeout(callback, 0);\n },\n cancelAnimationFrame(id) {\n if (typeof setTimeout === 'undefined') {\n return;\n }\n clearTimeout(id);\n },\n};\nfunction ssr_window_esm_getWindow() {\n const win = typeof window !== 'undefined' ? window : {};\n extend(win, ssrWindow);\n return win;\n}\n\n\n\n;// CONCATENATED MODULE: ./node_modules/dom7/dom7.esm.js\n/**\n * Dom7 4.0.6\n * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API\n * https://framework7.io/docs/dom7.html\n *\n * Copyright 2023, Vladimir Kharlampidi\n *\n * Licensed under MIT\n *\n * Released on: February 2, 2023\n */\n\n\n/* eslint-disable no-proto */\nfunction makeReactive(obj) {\n const proto = obj.__proto__;\n Object.defineProperty(obj, '__proto__', {\n get() {\n return proto;\n },\n\n set(value) {\n proto.__proto__ = value;\n }\n\n });\n}\n\nclass Dom7 extends Array {\n constructor(items) {\n if (typeof items === 'number') {\n super(items);\n } else {\n super(...(items || []));\n makeReactive(this);\n }\n }\n\n}\n\nfunction arrayFlat(arr = []) {\n const res = [];\n arr.forEach(el => {\n if (Array.isArray(el)) {\n res.push(...arrayFlat(el));\n } else {\n res.push(el);\n }\n });\n return res;\n}\nfunction arrayFilter(arr, callback) {\n return Array.prototype.filter.call(arr, callback);\n}\nfunction arrayUnique(arr) {\n const uniqueArray = [];\n\n for (let i = 0; i < arr.length;
1 i += 1) {\n if (uniqueArray.indexOf(arr[i]) === -1) uniqueArray.push(arr[i]);\n }\n\n return uniqueArray;\n}\nfunction toCamelCase(string) {\n return string.toLowerCase().replace(/-(.)/g, (match, group) => group.toUpperCase());\n}\n\n// eslint-disable-next-line\n\nfunction qsa(selector, context) {\n if (typeof selector !== 'string') {\n return [selector];\n }\n\n const a = [];\n const res = context.querySelectorAll(selector);\n\n for (let i = 0; i < res.length; i += 1) {\n a.push(res[i]);\n }\n\n return a;\n}\n\nfunction $(selector, context) {\n const window = ssr_window_esm_getWindow();\n const document = getDocument();\n let arr = [];\n\n if (!context && selector instanceof Dom7) {\n return selector;\n }\n\n if (!selector) {\n return new Dom7(arr);\n }\n\n if (typeof selector === 'string') {\n const html = selector.trim();\n\n if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {\n let toCreate = 'div';\n if (html.indexOf('<li') === 0) toCreate = 'ul';\n if (html.indexOf('<tr') === 0) toCreate = 'tbody';\n if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';\n if (html.indexOf('<tbody') === 0) toCreate = 'table';\n if (html.indexOf('<option') === 0) toCreate = 'select';\n const tempParent = document.createElement(toCreate);\n tempParent.innerHTML = html;\n\n for (let i = 0; i < tempParent.childNodes.length; i += 1) {\n arr.push(tempParent.childNodes[i]);\n }\n } else {\n arr = qsa(selector.trim(), context || document);\n } // arr = qsa(selector, document);\n\n } else if (selector.nodeType || selector === window || selector === document) {\n arr.push(selector);\n } else if (Array.isArray(selector)) {\n if (selector instanceof Dom7) return selector;\n arr = selector;\n }\n\n return new Dom7(arrayUnique(arr));\n}\n\n$.fn = Dom7.prototype;\n\n// eslint-disable-next-line\n\nfunction addClass(...classes) {\n const classNames = arrayFlat(classes.map(c => c.split(' ')));\n this.forEach(el => {\n el.classList.add(...classNames);\n });\n return this;\n}\n\nfunction removeClass(...classes) {\n const classNames = arrayFlat(classes.map(c => c.split(' ')));\n this.forEach(el => {\n el.classList.remove(...classNames);\n });\n return this;\n}\n\nfunction toggleClass(...classes) {\n const classNames = arrayFlat(classes.map(c => c.split(' ')));\n this.forEach(el => {\n classNames.forEach(className => {\n el.classList.toggle(className);\n });\n });\n}\n\nfunction hasClass(...classes) {\n const classNames = arrayFlat(classes.map(c => c.split(' ')));\n return arrayFilter(this, el => {\n return classNames.filter(className => el.classList.contains(className)).length > 0;\n }).length > 0;\n}\n\nfunction attr(attrs, value) {\n if (arguments.length === 1 && typeof attrs === 'string') {\n // Get attr\n if (this[0]) return this[0].getAttribute(attrs);\n return undefined;\n } // Set attrs\n\n\n for (let i = 0; i < this.length; i += 1) {\n if (arguments.length === 2) {\n // String\n this[i].setAttribute(attrs, value);\n } else {\n // Object\n for (const attrName in attrs) {\n this[i][attrName] = attrs[attrName];\n this[i].setAttribute(attrName, attrs[attrName]);\n }\n }\n }\n\n return this;\n}\n\nfunction removeAttr(attr) {\n for (let i = 0; i < this.length; i += 1) {\n this[i].removeAttribute(attr);\n }\n\n return this;\n}\n\nfunction prop(props, value) {\n if (arguments.length === 1 && typeof props === 'string') {\n // Get prop\n if (this[0]) return this[0][props];\n } else {\n // Set props\n for (let i = 0; i < this.length; i += 1) {\n if (arguments.length === 2) {\n // String\n this[i][props] = value;\n } else {\n // Object\n for (const propName in props) {\n this[i][propName] = props[propName];\n }\n }\n }\n\n return this;\n }\n\n return this;\n}\n\nfunction data(key, value) {\n let el;\n\n if (typeof value === 'undefined') {\n el = this[0];\n if (!el) return undefined; // Get value\n\n if (el.dom7ElementDataStorage && key in el.dom7ElementDataStorage) {\n return el.dom7ElementDataStorage[key];\n }\n\n const dataKey = el.getAttribute(`data-${key}`);\n\n if (dataKey) {\n return dataKey;\n }\n\n return undefined;\n } // Set value\n\n\n for (let i = 0; i < this.length; i += 1) {\n el = this[i];\n if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};\n el.dom7ElementDataStorage[key] = value;\n }\n\n return this;\n}\n\nfunction removeData(key) {\n for (let i = 0; i < this.length; i += 1) {\n const el = this[i];\n\n if (el.dom7ElementDataStorage && el.dom7ElementDataStorage[key]) {\n el.dom7ElementDataStorage[key] = null;\n delete el.dom7ElementDataStorage[key];\n }\n }\n}\n\nfunction dataset() {\n const el = this[0];\n if (!el) return undefined;\n const dataset = {}; // eslint-disable-line\n\n if (el.dataset) {\n for (const dataKey in el.dataset) {\n dataset[dataKey] = el.dataset[dataKey];\n }\n } else {\n for (let i = 0; i < el.attributes.length; i += 1) {\n const attr = el.attributes[i];\n\n if (attr.name.indexOf('data-') >
1= 0) {\n dataset[toCamelCase(attr.name.split('data-')[1])] = attr.value;\n }\n }\n }\n\n for (const key in dataset) {\n if (dataset[key] === 'false') dataset[key] = false;else if (dataset[key] === 'true') dataset[key] = true;else if (parseFloat(dataset[key]) === dataset[key] * 1) dataset[key] *= 1;\n }\n\n return dataset;\n}\n\nfunction val(value) {\n if (typeof value === 'undefined') {\n // get value\n const el = this[0];\n if (!el) return undefined;\n\n if (el.multiple && el.nodeName.toLowerCase() === 'select') {\n const values = [];\n\n for (let i = 0; i < el.selectedOptions.length; i += 1) {\n values.push(el.selectedOptions[i].value);\n }\n\n return values;\n }\n\n return el.value;\n } // set value\n\n\n for (let i = 0; i < this.length; i += 1) {\n const el = this[i];\n\n if (Array.isArray(value) && el.multiple && el.nodeName.toLowerCase() === 'select') {\n for (let j = 0; j < el.options.length; j += 1) {\n el.options[j].selected = value.indexOf(el.options[j].value) >= 0;\n }\n } else {\n el.value = value;\n }\n }\n\n return this;\n}\n\nfunction value(value) {\n return this.val(value);\n}\n\nfunction transform(transform) {\n for (let i = 0; i < this.length; i += 1) {\n this[i].style.transform = transform;\n }\n\n return this;\n}\n\nfunction transition(duration) {\n for (let i = 0; i < this.length; i += 1) {\n this[i].style.transitionDuration = typeof duration !== 'string' ? `${duration}ms` : duration;\n }\n\n return this;\n}\n\nfunction on(...args) {\n let [eventType, targetSelector, listener, capture] = args;\n\n if (typeof args[1] === 'function') {\n [eventType, listener, capture] = args;\n targetSelector = undefined;\n }\n\n if (!capture) capture = false;\n\n function handleLiveEvent(e) {\n const target = e.target;\n if (!target) return;\n const eventData = e.target.dom7EventData || [];\n\n if (eventData.indexOf(e) < 0) {\n eventData.unshift(e);\n }\n\n if ($(target).is(targetSelector)) listener.apply(target, eventData);else {\n const parents = $(target).parents(); // eslint-disable-line\n\n for (let k = 0; k < parents.length; k += 1) {\n if ($(parents[k]).is(targetSelector)) listener.apply(parents[k], eventData);\n }\n }\n }\n\n function handleEvent(e) {\n const eventData = e && e.target ? e.target.dom7EventData || [] : [];\n\n if (eventData.indexOf(e) < 0) {\n eventData.unshift(e);\n }\n\n listener.apply(this, eventData);\n }\n\n const events = eventType.split(' ');\n let j;\n\n for (let i = 0; i < this.length; i += 1) {\n const el = this[i];\n\n if (!targetSelector) {\n for (j = 0; j < events.length; j += 1) {\n const event = events[j];\n if (!el.dom7Listeners) el.dom7Listeners = {};\n if (!el.dom7Listeners[event]) el.dom7Listeners[event] = [];\n el.dom7Listeners[event].push({\n listener,\n proxyListener: handleEvent\n });\n el.addEventListener(event, handleEvent, capture);\n }\n } else {\n // Live events\n for (j = 0; j < events.length; j += 1) {\n const event = events[j];\n if (!el.dom7LiveListeners) el.dom7LiveListeners = {};\n if (!el.dom7LiveListeners[event]) el.dom7LiveListeners[event] = [];\n el.dom7LiveListeners[event].push({\n listener,\n proxyListener: handleLiveEvent\n });\n el.addEventListener(event, handleLiveEvent, capture);\n }\n }\n }\n\n return this;\n}\n\nfunction off(...args) {\n let [eventType, targetSelector, listener, capture] = args;\n\n if (typeof args[1] === 'function') {\n [eventType, listener, capture] = args;\n targetSelector = undefined;\n }\n\n if (!capture) capture = false;\n const events = eventType.split(' ');\n\n for (let i = 0; i < events.length; i += 1) {\n const event = events[i];\n\n for (let j = 0; j < this.length; j += 1) {\n const el = this[j];\n let handlers;\n\n if (!targetSelector && el.dom7Listeners) {\n handlers = el.dom7Listeners[event];\n }
1 else if (targetSelector && el.dom7LiveListeners) {\n handlers = el.dom7LiveListeners[event];\n }\n\n if (handlers && handlers.length) {\n for (let k = handlers.length - 1; k >= 0; k -= 1) {\n const handler = handlers[k];\n\n if (listener && handler.listener === listener) {\n el.removeEventListener(event, handler.proxyListener, capture);\n handlers.splice(k, 1);\n } else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) {\n el.removeEventListener(event, handler.proxyListener, capture);\n handlers.splice(k, 1);\n } else if (!listener) {\n el.removeEventListener(event, handler.proxyListener, capture);\n handlers.splice(k, 1);\n }\n }\n }\n }\n }\n\n return this;\n}\n\nfunction once(...args) {\n const dom = this;\n let [eventName, targetSelector, listener, capture] = args;\n\n if (typeof args[1] === 'function') {\n [eventName, listener, capture] = args;\n targetSelector = undefined;\n }\n\n function onceHandler(...eventArgs) {\n listener.apply(this, eventArgs);\n dom.off(eventName, targetSelector, onceHandler, capture);\n\n if (onceHandler.dom7proxy) {\n delete onceHandler.dom7proxy;\n }\n }\n\n onceHandler.dom7proxy = listener;\n return dom.on(eventName, targetSelector, onceHandler, capture);\n}\n\nfunction trigger(...args) {\n const window = ssr_window_esm_getWindow();\n const events = args[0].split(' ');\n const eventData = args[1];\n\n for (let i = 0; i < events.length; i += 1) {\n const event = events[i];\n\n for (let j = 0; j < this.length; j += 1) {\n const el = this[j];\n\n if (window.CustomEvent) {\n const evt = new window.CustomEvent(event, {\n detail: eventData,\n bubbles: true,\n cancelable: true\n });\n el.dom7EventData = args.filter((data, dataIndex) => dataIndex > 0);\n el.dispatchEvent(evt);\n el.dom7EventData = [];\n delete el.dom7EventData;\n }\n }\n }\n\n return this;\n}\n\nfunction transitionStart(callback) {\n const dom = this;\n\n function fireCallBack(e) {\n if (e.target !== this) return;\n callback.call(this, e);\n dom.off('transitionstart', fireCallBack);\n }\n\n if (callback) {\n dom.on('transitionstart', fireCallBack);\n }\n\n return this;\n}\n\nfunction transitionEnd(callback) {\n const dom = this;\n\n function fireCallBack(e) {\n if (e.target !== this) return;\n callback.call(this, e);\n dom.off('transitionend', fireCallBack);\n }\n\n if (callback) {\n dom.on('transitionend', fireCallBack);\n }\n\n return this;\n}\n\nfunction animationEnd(callback) {\n const dom = this;\n\n function fireCallBack(e) {\n if (e.target !== this) return;\n callback.call(this, e);\n dom.off('animationend', fireCallBack);\n }\n\n if (callback) {\n dom.on('animationend', fireCallBack);\n }\n\n return this;\n}\n\nfunction width() {\n const window = getWindow();\n\n if (this[0] === window) {\n return window.innerWidth;\n }\n\n if (this.length > 0) {\n return parseFloat(this.css('width'));\n }\n\n return null;\n}\n\nfunction dom7_esm_outerWidth(includeMargins) {\n if (this.length > 0) {\n if (includeMargins) {\n const styles = this.styles();\n return this[0].offsetWidth + parseFloat(styles.getPropertyValue('margin-right')) + parseFloat(styles.getPropertyValue('margin-left'));\n }\n\n return this[0].offsetWidth;\n }\n\n return null;\n}\n\nfunction height() {\n const window = getWindow();\n\n if (this[0] === window) {\n return window.innerHeight;\n }\n\n if (this.length > 0) {\n return parseFloat(this.css('height'));\n }\n\n return null;\n}\n\nfunction dom7_esm_outerHeight(includeMargins) {\n if (this.length > 0) {\n if (includeMargins) {\n const styles = this.styles();\n return this[0].offsetHeight + parseFloat(styles.getPropertyValue('margin-top')) + parseFloat(styles.getPropertyValue('margin-bottom'));\n }\n\n return this[0].offsetHeight;\n }\n\n return null;\n}\n\nfunction offset() {\n if (this.length > 0) {\n const window = ssr_window_esm_getWindow();\n const document = getDocument();\n const el = this[0];\n const box = el.getBoundingClientRect();\n const body = document.body;\n const clientTop = el.clientTop || body.clientTop || 0;\n const clientLeft = el.clientLeft || body.clientLeft || 0;\n const scrollTop = el === window ? window.scrollY : el.scrollTop;\n const scrollLeft = el === window ? window.scrollX : el.scrollLeft;\n return {\n top: box.top + scrollTop - clientTop,\n left: box.left + scrollLeft - clientLeft\n };\n }\n\n return null;\n}\n\nfunction hide() {\n for (let i = 0; i < this.length; i += 1) {\n this[i].style.display = 'none';\n }\n\n return this;\n}
1\n\nfunction show() {\n const window = getWindow();\n\n for (let i = 0; i < this.length; i += 1) {\n const el = this[i];\n\n if (el.style.display === 'none') {\n el.style.display = '';\n }\n\n if (window.getComputedStyle(el, null).getPropertyValue('display') === 'none') {\n // Still not visible\n el.style.display = 'block';\n }\n }\n\n return this;\n}\n\nfunction styles() {\n const window = ssr_window_esm_getWindow();\n if (this[0]) return window.getComputedStyle(this[0], null);\n return {};\n}\n\nfunction css(props, value) {\n const window = ssr_window_esm_getWindow();\n let i;\n\n if (arguments.length === 1) {\n if (typeof props === 'string') {\n // .css('width')\n if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);\n } else {\n // .css({ width: '100px' })\n for (i = 0; i < this.length; i += 1) {\n for (const prop in props) {\n this[i].style[prop] = props[prop];\n }\n }\n\n return this;\n }\n }\n\n if (arguments.length === 2 && typeof props === 'string') {\n // .css('width', '100px')\n for (i = 0; i < this.length; i += 1) {\n this[i].style[props] = value;\n }\n\n return this;\n }\n\n return this;\n}\n\nfunction each(callback) {\n if (!callback) return this;\n this.forEach((el, index) => {\n callback.apply(el, [el, index]);\n });\n return this;\n}\n\nfunction filter(callback) {\n const result = arrayFilter(this, callback);\n return $(result);\n}\n\nfunction html(html) {\n if (typeof html === 'undefined') {\n return this[0] ? this[0].innerHTML : null;\n }\n\n for (let i = 0; i < this.length; i += 1) {\n this[i].innerHTML = html;\n }\n\n return this;\n}\n\nfunction dom7_esm_text(text) {\n if (typeof text === 'undefined') {\n return this[0] ? this[0].textContent.trim() : null;\n }\n\n for (let i = 0; i < this.length; i += 1) {\n this[i].textContent = text;\n }\n\n return this;\n}\n\nfunction is(selector) {\n const window = ssr_window_esm_getWindow();\n const document = getDocument();\n const el = this[0];\n let compareWith;\n let i;\n if (!el || typeof selector === 'undefined') return false;\n\n if (typeof selector === 'string') {\n if (el.matches) return el.matches(selector);\n if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);\n if (el.msMatchesSelector) return el.msMatchesSelector(selector);\n compareWith = $(selector);\n\n for (i = 0; i < compareWith.length; i += 1) {\n if (compareWith[i] === el) return true;\n }\n\n return false;\n }\n\n if (selector === document) {\n return el === document;\n }\n\n if (selector === window) {\n return el === window;\n }\n\n if (selector.nodeType || selector instanceof Dom7) {\n compareWith = selector.nodeType ? [selector] : selector;\n\n for (i = 0; i < compareWith.length; i += 1) {\n if (compareWith[i] === el) return true;\n }\n\n return false;\n }\n\n return false;\n}\n\nfunction index() {\n let child = this[0];\n let i;\n\n if (child) {\n i = 0; // eslint-disable-next-line\n\n while ((child = child.previousSibling) !== null) {\n if (child.nodeType === 1) i += 1;\n }\n\n return i;\n }\n\n return undefined;\n}\n\nfunction eq(index) {\n if (typeof index === 'undefined') return this;\n const length = this.length;\n\n if (index > length - 1) {\n return $([]);\n }\n\n if (index < 0) {\n const returnIndex = length + index;\n if (returnIndex < 0) return $([]);\n return $([this[returnIndex]]);\n }\n\n return $([this[index]]);\n}\n\nfunction append(...els) {\n let newChild;\n const document = getDocument();\n\n for (let k = 0; k < els.length; k += 1) {\n newChild = els[k];\n\n for (let i = 0; i < this.length; i += 1) {\n if (typeof newChild === 'string') {\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = newChild;\n\n while (tempDiv.firstChild) {\n this[i].appendChild(tempDiv.firstChild);\n }\n } else if (newChild instanceof Dom7) {\n for (let j = 0; j < newChild.length; j += 1) {\n this[i].appendChild(newChild[j]);\n }\n } else {\n this[i].appendChild(newChild);\n }\n }\n }\n\n return this;\n}\n\nfunction appendTo(parent) {\n $(parent).append(this);\n return this;\n}\n\nfunction prepend(newChild) {\n const document = getDocument();\n let i;\n let j;\n\n for (i = 0; i < this.length; i += 1) {\n if (typeof newChild === 'string') {\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = newChild;\n\n for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) {\n this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);\n }\n } else if (newChild instanceof Dom7) {\n for (j = 0; j < newChild.length; j += 1) {\n this[i].insertBefore(newChild[j], this[i].childNodes[0]);\n }\n } else {\n this[i].insertBefore(newChild, this[i].childNodes[0]);\n }\n }\n\n return this;\n}\n\nfunction prependTo(parent) {\n $(parent).prepend(this);\n return this;\n}\n\nfunction insertBefore(selector) {\n const before = $(selector);\n\n for (let i = 0; i < this.length; i += 1) {\n if (before.length === 1) {\n before[0].parentNode.insertBefore(this[i], before[0]);\n } else if (before.length > 1) {\n for (let j = 0; j < before.length; j += 1) {\n before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);\n }\n }\n }\n}\n\nfunction insertAfter(selector) {\n const after = $(selector);\n\n for (let i = 0; i < this.length; i += 1) {\n if (after.length === 1) {\n after[0].parentNode.insertBefore(this[i], after[0].nextSibling);\n } else if (after.length > 1) {\n for (let j = 0; j < after.length; j += 1) {\n after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);\n }\n }\n }\n}\n\nfunction next(selector) {\n if (this.length > 0) {\n if (selector) {\n if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) {\
1n return $([this[0].nextElementSibling]);\n }\n\n return $([]);\n }\n\n if (this[0].nextElementSibling) return $([this[0].nextElementSibling]);\n return $([]);\n }\n\n return $([]);\n}\n\nfunction nextAll(selector) {\n const nextEls = [];\n let el = this[0];\n if (!el) return $([]);\n\n while (el.nextElementSibling) {\n const next = el.nextElementSibling; // eslint-disable-line\n\n if (selector) {\n if ($(next).is(selector)) nextEls.push(next);\n } else nextEls.push(next);\n\n el = next;\n }\n\n return $(nextEls);\n}\n\nfunction prev(selector) {\n if (this.length > 0) {\n const el = this[0];\n\n if (selector) {\n if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) {\n return $([el.previousElementSibling]);\n }\n\n return $([]);\n }\n\n if (el.previousElementSibling) return $([el.previousElementSibling]);\n return $([]);\n }\n\n return $([]);\n}\n\nfunction prevAll(selector) {\n const prevEls = [];\n let el = this[0];\n if (!el) return $([]);\n\n while (el.previousElementSibling) {\n const prev = el.previousElementSibling; // eslint-disable-line\n\n if (selector) {\n if ($(prev).is(selector)) prevEls.push(prev);\n } else prevEls.push(prev);\n\n el = prev;\n }\n\n return $(prevEls);\n}\n\nfunction siblings(selector) {\n return this.nextAll(selector).add(this.prevAll(selector));\n}\n\nfunction dom7_esm_parent(selector) {\n const parents = []; // eslint-disable-line\n\n for (let i = 0; i < this.length; i += 1) {\n if (this[i].parentNode !== null) {\n if (selector) {\n if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);\n } else {\n parents.push(this[i].parentNode);\n }\n }\n }\n\n return $(parents);\n}\n\nfunction parents(selector) {\n const parents = []; // eslint-disable-line\n\n for (let i = 0; i < this.length; i += 1) {\n let parent = this[i].parentNode; // eslint-disable-line\n\n while (parent) {\n if (selector) {\n if ($(parent).is(selector)) parents.push(parent);\n } else {\n parents.push(parent);\n }\n\n parent = parent.parentNode;\n }\n }\n\n return $(parents);\n}\n\nfunction closest(selector) {\n let closest = this; // eslint-disable-line\n\n if (typeof selector === 'undefined') {\n return $([]);\n }\n\n if (!closest.is(selector)) {\n closest = closest.parents(selector).eq(0);\n }\n\n return closest;\n}\n\nfunction find(selector) {\n const foundElements = [];\n\n for (let i = 0; i < this.length; i += 1) {\n const found = this[i].querySelectorAll(selector);\n\n for (let j = 0; j < found.length; j += 1) {\n foundElements.push(found[j]);\n }\n }\n\n return $(foundElements);\n}\n\nfunction children(selector) {\n const children = []; // eslint-disable-line\n\n for (let i = 0; i < this.length; i += 1) {\n const childNodes = this[i].children;\n\n for (let j = 0; j < childNodes.length; j += 1) {\n if (!selector || $(childNodes[j]).is(selector)) {\n children.push(childNodes[j]);\n }\n }\n }\n\n return $(children);\n}\n\nfunction remove() {\n for (let i = 0; i < this.length; i += 1) {\n if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);\n }\n\n return this;\n}\n\nfunction detach() {\n return this.remove();\n}\n\nfunction add(...els) {\n const dom = this;\n let i;\n let j;\n\n for (i = 0; i < els.length; i += 1) {\n const toAdd = $(els[i]);\n\n for (j = 0; j < toAdd.length; j += 1) {\n dom.push(toAdd[j]);\n }\n }\n\n return dom;\n}\n\nfunction empty() {\n for (let i = 0; i < this.length; i += 1) {\n const el = this[i];\n\n if (el.nodeType === 1) {\n for (let j = 0; j < el.childNodes.length; j += 1) {\n if (el.childNodes[j].parentNode) {\n el.childNodes[j].parentNode.removeChild(el.childNodes[j]);\n }\n }\n\n el.textContent = '';\n }\n }\n\n return this;\n}\n\n// eslint-disable-next-line\n\nfunction scrollTo(...args) {\n const window = getWindow();\n let [left, top, duration, easing, callback] = args;\n\n if (args.length === 4 && typeof easing === 'function') {\n callback = easing;\n [left, top, duration, callback, easing] = args;\n }\n\n if (typeof easing === 'undefined') easing = 'swing';\n return this.each(function animate() {\n const el = this;
1\n let currentTop;\n let currentLeft;\n let maxTop;\n let maxLeft;\n let newTop;\n let newLeft;\n let scrollTop; // eslint-disable-line\n\n let scrollLeft; // eslint-disable-line\n\n let animateTop = top > 0 || top === 0;\n let animateLeft = left > 0 || left === 0;\n\n if (typeof easing === 'undefined') {\n easing = 'swing';\n }\n\n if (animateTop) {\n currentTop = el.scrollTop;\n\n if (!duration) {\n el.scrollTop = top;\n }\n }\n\n if (animateLeft) {\n currentLeft = el.scrollLeft;\n\n if (!duration) {\n el.scrollLeft = left;\n }\n }\n\n if (!duration) return;\n\n if (animateTop) {\n maxTop = el.scrollHeight - el.offsetHeight;\n newTop = Math.max(Math.min(top, maxTop), 0);\n }\n\n if (animateLeft) {\n maxLeft = el.scrollWidth - el.offsetWidth;\n newLeft = Math.max(Math.min(left, maxLeft), 0);\n }\n\n let startTime = null;\n if (animateTop && newTop === currentTop) animateTop = false;\n if (animateLeft && newLeft === currentLeft) animateLeft = false;\n\n function render(time = new Date().getTime()) {\n if (startTime === null) {\n startTime = time;\n }\n\n const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);\n const easeProgress = easing === 'linear' ? progress : 0.5 - Math.cos(progress * Math.PI) / 2;\n let done;\n if (animateTop) scrollTop = currentTop + easeProgress * (newTop - currentTop);\n if (animateLeft) scrollLeft = currentLeft + easeProgress * (newLeft - currentLeft);\n\n if (animateTop && newTop > currentTop && scrollTop >= newTop) {\n el.scrollTop = newTop;\n done = true;\n }\n\n if (animateTop && newTop < currentTop && scrollTop <= newTop) {\n el.scrollTop = newTop;\n done = true;\n }\n\n if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {\n el.scrollLeft = newLeft;\n done = true;\n }\n\n if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {\n el.scrollLeft = newLeft;\n done = true;\n }\n\n if (done) {\n if (callback) callback();\n return;\n }\n\n if (animateTop) el.scrollTop = scrollTop;\n if (animateLeft) el.scrollLeft = scrollLeft;\n window.requestAnimationFrame(render);\n }\n\n window.requestAnimationFrame(render);\n });\n} // scrollTop(top, duration, easing, callback) {\n\n\nfunction scrollTop(...args) {\n let [top, duration, easing, callback] = args;\n\n if (args.length === 3 && typeof easing === 'function') {\n [top, duration, callback, easing] = args;\n }\n\n const dom = this;\n\n if (typeof top === 'undefined') {\n if (dom.length > 0) return dom[0].scrollTop;\n return null;\n }\n\n return dom.scrollTo(undefined, top, duration, easing, callback);\n}\n\nfunction scrollLeft(...args) {\n let [left, duration, easing, callback] = args;\n\n if (args.length === 3 && typeof easing === 'function') {\n [left, duration, callback, easing] = args;\n }\n\n const dom = this;\n\n if (typeof left === 'undefined') {\n if (dom.length > 0) return dom[0].scrollLeft;\n return null;\n }\n\n return dom.scrollTo(left, undefined, duration, easing, callback);\n}\n\n// eslint-disable-next-line\n\nfunction animate(initialProps, initialParams) {\n const window = getWindow();\n const els = this;\n const a = {\n props: Object.assign({}, initialProps),\n params: Object.assign({\n duration: 300,\n easing: 'swing' // or 'linear'\n\n /* Callbacks\n begin(elements)\n complete(elements)\n progress(elements, complete, remaining, start, tweenValue)\n */\n\n }, initialParams),\n elements: els,\n animating: false,\n que: [],\n\n easingProgress(easing, progress) {\n if (easing === 'swing') {\n return 0.5 - Math.cos(progress * Math.PI) / 2;\n }\n\n if (typeof easing === 'function') {\n return easing(progress);\n }\n\n return progress;\n },\n\n stop() {\n if (a.frameId) {\n window.cancelAnimationFrame(a.frameId);\n }\n\n a.animating = false;\n a.elements.each(el => {\n const element = el;\n delete element.dom7AnimateInstance;\n });\n a.que = [];\n },\n\n done(complete) {\n a.animating = false;\n a.elements.each(el => {\n const element = el;\n delete element.dom7AnimateInstance;\n });\n if (complete) complete(els);\n\n if (a.que.length > 0) {\n const que = a.que.shift();\n a.animate(que[0], que[1]);\n }\n },\n\n animate(props, params) {\n if (a.animating) {\n a.que.push([props, params]);\n return a;\n }\n\n const elements = []; // Define & Cache Initials & Units\n\n a.elements.each((el, index) =>
1 {\n let initialFullValue;\n let initialValue;\n let unit;\n let finalValue;\n let finalFullValue;\n if (!el.dom7AnimateInstance) a.elements[index].dom7AnimateInstance = a;\n elements[index] = {\n container: el\n };\n Object.keys(props).forEach(prop => {\n initialFullValue = window.getComputedStyle(el, null).getPropertyValue(prop).replace(',', '.');\n initialValue = parseFloat(initialFullValue);\n unit = initialFullValue.replace(initialValue, '');\n finalValue = parseFloat(props[prop]);\n finalFullValue = props[prop] + unit;\n elements[index][prop] = {\n initialFullValue,\n initialValue,\n unit,\n finalValue,\n finalFullValue,\n currentValue: initialValue\n };\n });\n });\n let startTime = null;\n let time;\n let elementsDone = 0;\n let propsDone = 0;\n let done;\n let began = false;\n a.animating = true;\n\n function render() {\n time = new Date().getTime();\n let progress;\n let easeProgress; // let el;\n\n if (!began) {\n began = true;\n if (params.begin) params.begin(els);\n }\n\n if (startTime === null) {\n startTime = time;\n }\n\n if (params.progress) {\n // eslint-disable-next-line\n params.progress(els, Math.max(Math.min((time - startTime) / params.duration, 1), 0), startTime + params.duration - time < 0 ? 0 : startTime + params.duration - time, startTime);\n }\n\n elements.forEach(element => {\n const el = element;\n if (done || el.done) return;\n Object.keys(props).forEach(prop => {\n if (done || el.done) return;\n progress = Math.max(Math.min((time - startTime) / params.duration, 1), 0);\n easeProgress = a.easingProgress(params.easing, progress);\n const {\n initialValue,\n finalValue,\n unit\n } = el[prop];\n el[prop].currentValue = initialValue + easeProgress * (finalValue - initialValue);\n const currentValue = el[prop].currentValue;\n\n if (finalValue > initialValue && currentValue >= finalValue || finalValue < initialValue && currentValue <= finalValue) {\n el.container.style[prop] = finalValue + unit;\n propsDone += 1;\n\n if (propsDone === Object.keys(props).length) {\n el.done = true;\n elementsDone += 1;\n }\n\n if (elementsDone === elements.length) {\n done = true;\n }\n }\n\n if (done) {\n a.done(params.complete);\n return;\n }\n\n el.container.style[prop] = currentValue + unit;\n });\n });\n if (done) return; // Then call\n\n a.frameId = window.requestAnimationFrame(render);\n }\n\n a.frameId = window.requestAnimationFrame(render);\n return a;\n }\n\n };\n\n if (a.elements.length === 0) {\n return els;\n }\n\n let animateInstance;\n\n for (let i = 0; i < a.elements.length; i += 1) {\n if (a.elements[i].dom7AnimateInstance) {\n animateInstance = a.elements[i].dom7AnimateInstance;\n } else a.elements[i].dom7AnimateInstance = a;\n }\n\n if (!animateInstance) {\n animateInstance = a;\n }\n\n if (initialProps === 'stop') {\n animateInstance.stop();\n } else {\n animateInstance.animate(a.props, a.params);\n }\n\n return els;\n}\n\nfunction stop() {\n const els = this;\n\n for (let i = 0; i < els.length; i += 1) {\n if (els[i].dom7AnimateInstance) {\n els[i].dom7AnimateInstance.stop();\n }\n }\n}\n\nconst noTrigger = 'resize scroll'.split(' ');\n\nfunction shortcut(name) {\n function eventHandler(...args) {\n if (typeof args[0] === 'undefined') {\n for (let i = 0; i < this.length; i += 1) {\n if (noTrigger.indexOf(name) < 0) {\n if (name in this[i]) this[i][name]();else {\n $(this[i]).trigger(name);\n }\n }\n }\n\n return this;\n }\n\n return this.on(name, ...args);\n }\n\n return eventHandler;\n}\n\nconst click = shortcut('click');\nconst dom7_esm_blur = shortcut('blur');\nconst dom7_esm_focus = shortcut('focus');\nconst focusin = shortcut('focusin');\nconst focusout = shortcut('focusout');\nconst keyup = shortcut('keyup');\nconst keydown = shortcut('keydown');\nconst keypress = shortcut('keypress');\nconst dom7_esm_submit = shortcut('submit');\nconst change = shortcut('change');\nconst mousedown = shortcut('mousedown');\nconst mousemove = shortcut('mousemove');\nconst mouseup = shortcut('mouseup');\nconst mouseenter = shortcut('mouseenter');\nconst mouseleave = shortcut('mouseleave');\nconst mouseout = shortcut('mouseout');\nconst mouseover = shortcut('mouseover');\nconst touchstart = shortcut('touchstart');\nconst touchend = shortcut('touchend');\nconst touchmove = shortcut('touchmove');\nconst resize = shortcut('resize');\nconst dom7_esm_scroll = shortcut('scroll');\n\n/* harmony default export */ const dom7_esm = ((/* unused pure expression or super */ null && ($)));\n\n\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/dom.js\n\nconst Methods = {\n addClass: addClass,\n removeClass: removeClass,\n hasClass: hasClass,\n toggleClass: toggleClass,\n attr: attr,\n removeAttr: removeAttr,\n transform: transform,\n transition: transition,\n on: on,\n off: off,\n trigger: trigger,\n transitionEnd: transitionEnd,\n outerWidth: dom7_esm_outerWidth,\n outerHeight: dom7_esm_outerHeight,\n styles: styles,\n offset: offset,\n css: css,\n each: each,\n html: html,\n text: dom7_esm_text,\n is: is,\n index: index,\n eq: eq,\n append: append,\n prepend: prepend,\n next: next,\n nextAll: nextAll,\n prev: prev,\n prevAll: prevAll,\n parent: dom7_esm_parent,\n parents: parents,\n closest: closest,\n find: find,\n children: children,\n filter: filter,\n remove: remove\n};
1\nObject.keys(Methods).forEach(methodName => {\n Object.defineProperty($.fn, methodName, {\n value: Methods[methodName],\n writable: true\n });\n});\n/* harmony default export */ const dom = ($);\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/utils.js\n\n\nfunction deleteProps(obj) {\n const object = obj;\n Object.keys(object).forEach(key => {\n try {\n object[key] = null;\n } catch (e) {// no getter for object\n }\n\n try {\n delete object[key];\n } catch (e) {// something got wrong\n }\n });\n}\n\nfunction nextTick(callback, delay = 0) {\n return setTimeout(callback, delay);\n}\n\nfunction now() {\n return Date.now();\n}\n\nfunction utils_getComputedStyle(el) {\n const window = ssr_window_esm_getWindow();\n let style;\n\n if (window.getComputedStyle) {\n style = window.getComputedStyle(el, null);\n }\n\n if (!style && el.currentStyle) {\n style = el.currentStyle;\n }\n\n if (!style) {\n style = el.style;\n }\n\n return style;\n}\n\nfunction getTranslate(el, axis = 'x') {\n const window = ssr_window_esm_getWindow();\n let matrix;\n let curTransform;\n let transformMatrix;\n const curStyle = utils_getComputedStyle(el, null);\n\n if (window.WebKitCSSMatrix) {\n curTransform = curStyle.transform || curStyle.webkitTransform;\n\n if (curTransform.split(',').length > 6) {\n curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', ');\n } // Some old versions of Webkit choke when 'none' is passed; pass\n // empty string instead in this case\n\n\n transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n } else {\n transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n matrix = transformMatrix.toString().split(',');\n }\n\n if (axis === 'x') {\n // Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41; // Crazy IE10 Matrix\n else if (matrix.length === 16) curTransform = parseFloat(matrix[12]); // Normal Browsers\n else curTransform = parseFloat(matrix[4]);\n }\n\n if (axis === 'y') {\n // Latest Chrome and webkits Fix\n if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42; // Crazy IE10 Matrix\n else if (matrix.length === 16) curTransform = parseFloat(matrix[13]); // Normal Browsers\n else curTransform = parseFloat(matrix[5]);\n }\n\n return curTransform || 0;\n}\n\nfunction utils_isObject(o) {\n return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object';\n}\n\nfunction isNode(node) {\n // eslint-disable-next-line\n if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {\n return node instanceof HTMLElement;\n }\n\n return node && (node.nodeType === 1 || node.nodeType === 11);\n}\n\nfunction utils_extend(...args) {\n const to = Object(args[0]);\n const noExtend = ['__proto__', 'constructor', 'prototype'];\n\n for (let i = 1; i < args.length; i += 1) {\n const nextSource = args[i];\n\n if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {\n const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);\n\n for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {\n const nextKey = keysArray[nextIndex];\n const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);\n\n if (desc !== undefined && desc.enumerable) {\n if (utils_isObject(to[nextKey]) && utils_isObject(nextSource[nextKey])) {\n if (nextSource[nextKey].__swiper__) {\n to[nextKey] = nextSource[nextKey];\n } else {\n utils_extend(to[nextKey], nextSource[nextKey]);\n }\n } else if (!utils_isObject(to[nextKey]) && utils_isObject(nextSource[nextKey])) {\n to[nextKey] = {};\n\n if (nextSource[nextKey].__swiper__) {\n to[nextKey] = nextSource[nextKey];\n } else {\n utils_extend(to[nextKey], nextSource[nextKey]);\n }\n } else {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n }\n\n return to;\n}\n\nfunction setCSSProperty(el, varName, varValue) {\n el.style.setProperty(varName, varValue);\n}\n\nfunction animateCSSModeScroll({\n swiper,\n targetPosition,\n side\n}) {\n const window = ssr_window_esm_getWindow();\n const startPosition = -swiper.translate;\n let startTime = null;\n let time;\n const duration = swiper.params.speed;\n swiper.wrapperEl.style.scrollSnapType = 'none';\n window.cancelAnimationFrame(swiper.cssModeFrameID);\n const dir = targetPosition > startPosition ? 'next' : 'prev';\n\n const isOutOfBound = (current, target) => {\n return dir === 'next' && current >= target || dir === 'prev' && current <= target;\n };\n\n const animate = () => {\n time = new Date().getTime();\n\n if (startTime === null) {\n startTime = time;\n }\n\n const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);\n const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
1\n let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);\n\n if (isOutOfBound(currentPosition, targetPosition)) {\n currentPosition = targetPosition;\n }\n\n swiper.wrapperEl.scrollTo({\n [side]: currentPosition\n });\n\n if (isOutOfBound(currentPosition, targetPosition)) {\n swiper.wrapperEl.style.overflow = 'hidden';\n swiper.wrapperEl.style.scrollSnapType = '';\n setTimeout(() => {\n swiper.wrapperEl.style.overflow = '';\n swiper.wrapperEl.scrollTo({\n [side]: currentPosition\n });\n });\n window.cancelAnimationFrame(swiper.cssModeFrameID);\n return;\n }\n\n swiper.cssModeFrameID = window.requestAnimationFrame(animate);\n };\n\n animate();\n}\n\n\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/get-support.js\n\nlet support;\n\nfunction calcSupport() {\n const window = ssr_window_esm_getWindow();\n const document = getDocument();\n return {\n smoothScroll: document.documentElement && 'scrollBehavior' in document.documentElement.style,\n touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch),\n passiveListener: function checkPassiveListener() {\n let supportsPassive = false;\n\n try {\n const opts = Object.defineProperty({}, 'passive', {\n // eslint-disable-next-line\n get() {\n supportsPassive = true;\n }\n\n });\n window.addEventListener('testPassiveListener', null, opts);\n } catch (e) {// No support\n }\n\n return supportsPassive;\n }(),\n gestures: function checkGestures() {\n return 'ongesturestart' in window;\n }()\n };\n}\n\nfunction getSupport() {\n if (!support) {\n support = calcSupport();\n }\n\n return support;\n}\n\n\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/get-device.js\n\n\nlet deviceCached;\n\nfunction calcDevice({\n userAgent\n} = {}
1) {\n const support = getSupport();\n const window = ssr_window_esm_getWindow();\n const platform = window.navigator.platform;\n const ua = userAgent || window.navigator.userAgent;\n const device = {\n ios: false,\n android: false\n };\n const screenWidth = window.screen.width;\n const screenHeight = window.screen.height;\n const android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/); // eslint-disable-line\n\n let ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n const ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n const iphone = !ipad && ua.match(/(iPhone\\sOS|iOS)\\s([\\d_]+)/);\n const windows = platform === 'Win32';\n let macos = platform === 'MacIntel'; // iPadOs 13 fix\n\n const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810'];\n\n if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) {\n ipad = ua.match(/(Version)\\/([\\d.]+)/);\n if (!ipad) ipad = [0, 1, '13_0_0'];\n macos = false;\n } // Android\n\n\n if (android && !windows) {\n device.os = 'android';\n device.android = true;\n }\n\n if (ipad || iphone || ipod) {\n device.os = 'ios';\n device.ios = true;\n } // Export object\n\n\n return device;\n}\n\nfunction getDevice(overrides = {}) {\n if (!deviceCached) {\n deviceCached = calcDevice(overrides);\n }\n\n return deviceCached;\n}\n\n\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/get-browser.js\n\nlet browser;\n\nfunction calcBrowser() {\n const window = ssr_window_esm_getWindow();\n\n function isSafari() {\n const ua = window.navigator.userAgent.toLowerCase();\n return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;\n }\n\n return {\n isSafari: isSafari(),\n isWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent)\n };\n}\n\nfunction getBrowser() {\n if (!browser) {\n browser = calcBrowser();\n }\n\n return browser;\n}\n\n\n;// CONCATENATED MODULE: ./node_modules/swiper/core/modules/resize/resize.js\n\nfunction Resize({\n swiper,\n on,\n emit\n}) {\n const window = ssr_window_esm_getWindow();\n let observer = null;\n let animationFrame = null;\n\n const resizeHandler = () => {\n if (!swiper || swiper.destroyed || !swiper.initialized) return;\n emit('beforeResize');\n emit('resize');\n };\n\n const createObserver = () => {\n if (!swiper || swiper.destroyed || !swiper.initialized) return;\n observer = new ResizeObserver(entries => {\n animationFrame = window.requestAnimationFrame(() => {\n const {\n width,\n height\n } = swiper;\n let newWidth = width;\n let newHeight = height;\n entries.forEach(({\n contentBoxSize,\n contentRect,\n target\n }) => {\n if (target && target !== swiper.el) return;\n newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;\n newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;\n });\n\n if (newWidth !== width || newHeight !== height) {\n resizeHandler();\n }\n });\n });\n observer.observe(swiper.el);\n };\n\n const removeObserver = () => {\n if (animationFrame) {\n window.cancelAnimationFrame(animationFrame);\n }\n\n if (observer && observer.unobserve && swiper.el) {\n observer.unobserve(swiper.el);\n observer = null;\n }\n };\n\n const orientationChangeHandler = () => {\n if (!swiper || swiper.destroyed || !swiper.initialized) return;\n emit('orientationchange');\n };\n\n on('init', () => {\n if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') {\n createObserver();\n return;\n }\n\n window.addEventListener('resize', resizeHandler);\n window.addEventListener('orientationchange', orientationChangeHandler);\n });\n on('destroy', () => {\n removeObserver();\n window.removeEventListener('resize', resizeHandler);\n window.removeEventListener('orientationchange', orientationChangeHandler);\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/modules/observer/observer.js\n\nfunction Observer({\n swiper,\n extendParams,\n on,\n emit\n}) {\n const observers = [];\n const window = ssr_window_esm_getWindow();\n\n const attach = (target, options = {}) =>
1 {\n const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;\n const observer = new ObserverFunc(mutations => {\n // The observerUpdate event should only be triggered\n // once despite the number of mutations. Additional\n // triggers are redundant and are very costly\n if (mutations.length === 1) {\n emit('observerUpdate', mutations[0]);\n return;\n }\n\n const observerUpdate = function observerUpdate() {\n emit('observerUpdate', mutations[0]);\n };\n\n if (window.requestAnimationFrame) {\n window.requestAnimationFrame(observerUpdate);\n } else {\n window.setTimeout(observerUpdate, 0);\n }\n });\n observer.observe(target, {\n attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n childList: typeof options.childList === 'undefined' ? true : options.childList,\n characterData: typeof options.characterData === 'undefined' ? true : options.characterData\n });\n observers.push(observer);\n };\n\n const init = () => {\n if (!swiper.params.observer) return;\n\n if (swiper.params.observeParents) {\n const containerParents = swiper.$el.parents();\n\n for (let i = 0; i < containerParents.length; i += 1) {\n attach(containerParents[i]);\n }\n } // Observe container\n\n\n attach(swiper.$el[0], {\n childList: swiper.params.observeSlideChildren\n }); // Observe wrapper\n\n attach(swiper.$wrapperEl[0], {\n attributes: false\n });\n };\n\n const destroy = () => {\n observers.forEach(observer => {\n observer.disconnect();\n });\n observers.splice(0, observers.length);\n };\n\n extendParams({\n observer: false,\n observeParents: false,\n observeSlideChildren: false\n });\n on('init', init);\n on('destroy', destroy);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/events-emitter.js\n/* eslint-disable no-underscore-dangle */\n/* harmony default export */ const events_emitter = ({\n on(events, handler, priority) {\n const self = this;\n if (!self.eventsListeners || self.destroyed) return self;\n if (typeof handler !== 'function') return self;\n const method = priority ? 'unshift' : 'push';\n events.split(' ').forEach(event => {\n if (!self.eventsListeners[event]) self.eventsListeners[event] = [];\n self.eventsListeners[event][method](handler);\n });\n return self;\n },\n\n once(events, handler, priority) {\n const self = this;\n if (!self.eventsListeners || self.destroyed) return self;\n if (typeof handler !== 'function') return self;\n\n function onceHandler(...args) {\n self.off(events, onceHandler);\n\n if (onceHandler.__emitterProxy) {\n delete onceHandler.__emitterProxy;\n }\n\n handler.apply(self, args);\n }\n\n onceHandler.__emitterProxy = handler;\n return self.on(events, onceHandler, priority);\n },\n\n onAny(handler, priority) {\n const self = this;\n if (!self.eventsListeners || self.destroyed) return self;\n if (typeof handler !== 'function') return self;\n const method = priority ? 'unshift' : 'push';\n\n if (self.eventsAnyListeners.indexOf(handler) < 0) {\n self.eventsAnyListeners[method](handler);\n }\n\n return self;\n },\n\n offAny(handler) {\n const self = this;\n if (!self.eventsListeners || self.destroyed) return self;\n if (!self.eventsAnyListeners) return self;\n const index = self.eventsAnyListeners.indexOf(handler);\n\n if (index >= 0) {\n self.eventsAnyListeners.splice(index, 1);\n }\n\n return self;\n },\n\n off(events, handler) {\n const self = this;\n if (!self.eventsListeners || self.destroyed) return self;\n if (!self.eventsListeners) return self;\n events.split(' ').forEach(event => {\n if (typeof handler === 'undefined') {\n self.eventsListeners[event] = [];\n } else if (self.eventsListeners[event]) {\n self.eventsListeners[event].forEach((eventHandler, index) => {\n if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {\n self.eventsListeners[event].splice(index, 1);\n }\n });\n }\n });\n return self;\n }
1,\n\n emit(...args) {\n const self = this;\n if (!self.eventsListeners || self.destroyed) return self;\n if (!self.eventsListeners) return self;\n let events;\n let data;\n let context;\n\n if (typeof args[0] === 'string' || Array.isArray(args[0])) {\n events = args[0];\n data = args.slice(1, args.length);\n context = self;\n } else {\n events = args[0].events;\n data = args[0].data;\n context = args[0].context || self;\n }\n\n data.unshift(context);\n const eventsArray = Array.isArray(events) ? events : events.split(' ');\n eventsArray.forEach(event => {\n if (self.eventsAnyListeners && self.eventsAnyListeners.length) {\n self.eventsAnyListeners.forEach(eventHandler => {\n eventHandler.apply(context, [event, ...data]);\n });\n }\n\n if (self.eventsListeners && self.eventsListeners[event]) {\n self.eventsListeners[event].forEach(eventHandler => {\n eventHandler.apply(context, data);\n });\n }\n });\n return self;\n }\n\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/updateSize.js\nfunction updateSize() {\n const swiper = this;\n let width;\n let height;\n const $el = swiper.$el;\n\n if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {\n width = swiper.params.width;\n } else {\n width = $el[0].clientWidth;\n }\n\n if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {\n height = swiper.params.height;\n } else {\n height = $el[0].clientHeight;\n }\n\n if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {\n return;\n } // Subtract paddings\n\n\n width = width - parseInt($el.css('padding-left') || 0, 10) - parseInt($el.css('padding-right') || 0, 10);\n height = height - parseInt($el.css('padding-top') || 0, 10) - parseInt($el.css('padding-bottom') || 0, 10);\n if (Number.isNaN(width)) width = 0;\n if (Number.isNaN(height)) height = 0;\n Object.assign(swiper, {\n width,\n height,\n size: swiper.isHorizontal() ? width : height\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/updateSlides.js\n\nfunction updateSlides() {\n const swiper = this;\n\n function getDirectionLabel(property) {\n if (swiper.isHorizontal()) {\n return property;\n } // prettier-ignore\n\n\n return {\n 'width': 'height',\n 'margin-top': 'margin-left',\n 'margin-bottom ': 'margin-right',\n 'margin-left': 'margin-top',\n 'margin-right': 'margin-bottom',\n 'padding-left': 'padding-top',\n 'padding-right': 'padding-bottom',\n 'marginRight': 'marginBottom'\n }[property];\n }\n\n function getDirectionPropertyValue(node, label) {\n return parseFloat(node.getPropertyValue(getDirectionLabel(label)) || 0);\n }\n\n const params = swiper.params;\n const {\n $wrapperEl,\n size: swiperSize,\n rtlTranslate: rtl,\n wrongRTL\n } = swiper;\n const isVirtual = swiper.virtual && params.virtual.enabled;\n const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;\n const slides = $wrapperEl.children(`.${swiper.params.slideClass}`);\n const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;\n let snapGrid = [];\n const slidesGrid = [];\n const slidesSizesGrid = [];\n let offsetBefore = params.slidesOffsetBefore;\n\n if (typeof offsetBefore === 'function') {\n offsetBefore = params.slidesOffsetBefore.call(swiper);\n }\n\n let offsetAfter = params.slidesOffsetAfter;\n\n if (typeof offsetAfter === 'function') {\n offsetAfter = params.slidesOffsetAfter.call(swiper);\n }\n\n const previousSnapGridLength = swiper.snapGrid.length;\n const previousSlidesGridLength = swiper.slidesGrid.length;\n let spaceBetween = params.spaceBetween;\n let slidePosition = -offsetBefore;\n let prevSlideSize = 0;\n let index = 0;\n\n if (typeof swiperSize === 'undefined') {\n return;\n }\n\n if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;\n }\n\n swiper.virtualSize = -spaceBetween; // reset margins\n\n if (rtl) slides.css({\n marginLeft: '',\n marginBottom: '',\n marginTop: ''\n });else slides.css({\n marginRight: '',\n marginBottom: '',\n marginTop: ''\n }); // reset cssMode offsets\n\n if (params.centeredSlides && params.cssMode) {\n setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-before', '');\n setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-after', '');\n }\n\n const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;\n\n if (gridEnabled) {\n swiper.grid.initSlides(slidesLength);\n } // Calc slides\n\n\n let slideSize;\n const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {\n return typeof params.breakpoints[key].slidesPerView !== 'undefined';\n }).length > 0;\n\n for (let i = 0; i < slidesLength; i += 1) {\n slideSize = 0;\n const slide = slides.eq(i);\n\n if (gridEnabled) {\n swiper.grid.updateSlide(i, slide, slidesLength, getDirectionLabel);\n }\n\n if (slide.css('display') === 'none') continue; // eslint-disable-line\n\n if (params.slidesPerView === 'auto') {\n if (shouldResetSlideSize) {\n slides[i].style[getDirectionLabel('width')] = ``;\n }\n\n const slideStyles = getComputedStyle(slide[0]);\n const currentTransform = slide[0].style.transform;\n const currentWebKitTransform = slide[0].style.webkitTransform;\n\n if (currentTransform) {\n slide[0].style.transform = 'none';\n }\n\n if (currentWebKitTransform) {\n slide[0].style.webkitTransform = 'none';\n }\n\n if (params.roundLengths) {\n slideSize = swiper.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);\n } else {\n // eslint-disable-next-line\n const width = getDirectionPropertyValue(slideStyles, 'width');\n const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');\n const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');\n const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');\n const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');\n const boxSizing = slideStyles.getPropertyValue('box-sizing');\n\n if (boxSizing && boxSizing === 'border-box') {\n slideSize = width + marginLeft + marginRight;\n } else {\n const {\n clientWidth,\n offsetWidth\n } = slide[0];\n slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);\n }\n }\n\n if (currentTransform) {\n slide[0].style.transform = currentTransform;\n }\n\n if (currentWebKitTransform) {\n slide[0].style.webkitTransform = currentWebKitTransform;\n }\n\n if (params.roundLengths) slideSize = Math.floor(slideSize);\n } else {\n slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;\n if (params.roundLengths) slideSize = Math.floor(slideSize);\n\n if (slides[i]) {\n slides[i].style[getDirectionLabel('width')] = `${slideSize}px`;\n }\n }\n\n if (slides[i]) {\n slides[i].swiperSlideSize = slideSize;\n }\n\n slidesSizesGrid.push(slideSize);\n\n if (params.centeredSlides) {\n slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;\n if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;\n if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;\n if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;\n if (params.roundLengths) slidePosition = Math.floor(slidePosition);\n if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);\n slidesGrid.push(slidePosition);\n } else {\n if (params.roundLengths) slidePosition = Math.floor(slidePosition);\n if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);\n slidesGrid.push(slidePosition);\n slidePosition = slidePosition + slideSize + spaceBetween;\n }\n\n swiper.virtualSize += slideSize + spaceBetween;\n prevSlideSize = slideSize;\n index += 1;\n }\n\n swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;\n\n if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {\n $wrapperEl.css({\n width: `${swiper.virtualSize + params.spaceBetween}px`\n });\n }\n\n if (params.setWrapperSize) {\n $wrapperEl.css({\n [getDirectionLabel('width')]: `${swiper.virtualSize + params.spaceBetween}px`\n });\n }\n\n if (gridEnabled) {\n swiper.grid.updateWrapperSize(slideSize, snapGrid, getDirectionLabel);\n } // Remove last grid elements depending on width\n\n\n if (!params.centeredSlides) {\n const newSlidesGrid = [];\n\n for (let i = 0; i < snapGrid.length; i += 1) {\n let slidesGridItem = snapGrid[i];\n if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
1\n\n if (snapGrid[i] <= swiper.virtualSize - swiperSize) {\n newSlidesGrid.push(slidesGridItem);\n }\n }\n\n snapGrid = newSlidesGrid;\n\n if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {\n snapGrid.push(swiper.virtualSize - swiperSize);\n }\n }\n\n if (snapGrid.length === 0) snapGrid = [0];\n\n if (params.spaceBetween !== 0) {\n const key = swiper.isHorizontal() && rtl ? 'marginLeft' : getDirectionLabel('marginRight');\n slides.filter((_, slideIndex) => {\n if (!params.cssMode) return true;\n\n if (slideIndex === slides.length - 1) {\n return false;\n }\n\n return true;\n }).css({\n [key]: `${spaceBetween}px`\n });\n }\n\n if (params.centeredSlides && params.centeredSlidesBounds) {\n let allSlidesSize = 0;\n slidesSizesGrid.forEach(slideSizeValue => {\n allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);\n });\n allSlidesSize -= params.spaceBetween;\n const maxSnap = allSlidesSize - swiperSize;\n snapGrid = snapGrid.map(snap => {\n if (snap < 0) return -offsetBefore;\n if (snap > maxSnap) return maxSnap + offsetAfter;\n return snap;\n });\n }\n\n if (params.centerInsufficientSlides) {\n let allSlidesSize = 0;
1\n slidesSizesGrid.forEach(slideSizeValue => {\n allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);\n });\n allSlidesSize -= params.spaceBetween;\n\n if (allSlidesSize < swiperSize) {\n const allSlidesOffset = (swiperSize - allSlidesSize) / 2;\n snapGrid.forEach((snap, snapIndex) => {\n snapGrid[snapIndex] = snap - allSlidesOffset;\n });\n slidesGrid.forEach((snap, snapIndex) => {\n slidesGrid[snapIndex] = snap + allSlidesOffset;\n });\n }\n }\n\n Object.assign(swiper, {\n slides,\n snapGrid,\n slidesGrid,\n slidesSizesGrid\n });\n\n if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {\n setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);\n setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);\n const addToSnapGrid = -swiper.snapGrid[0];\n const addToSlidesGrid = -swiper.slidesGrid[0];\n swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);\n swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);\n }\n\n if (slidesLength !== previousSlidesLength) {\n swiper.emit('slidesLengthChange');\n }\n\n if (snapGrid.length !== previousSnapGridLength) {\n if (swiper.params.watchOverflow) swiper.checkOverflow();\n swiper.emit('snapGridLengthChange');\n }\n\n if (slidesGrid.length !== previousSlidesGridLength) {\n swiper.emit('slidesGridLengthChange');\n }\n\n if (params.watchSlidesProgress) {\n swiper.updateSlidesOffset();\n }\n\n if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {\n const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;\n const hasClassBackfaceClassAdded = swiper.$el.hasClass(backFaceHiddenClass);\n\n if (slidesLength <= params.maxBackfaceHiddenSlides) {\n if (!hasClassBackfaceClassAdded) swiper.$el.addClass(backFaceHiddenClass);\n } else if (hasClassBackfaceClassAdded) {\n swiper.$el.removeClass(backFaceHiddenClass);\n }\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/updateAutoHeight.js\n\nfunction updateAutoHeight(speed) {\n const swiper = this;\n const activeSlides = [];\n const isVirtual = swiper.virtual && swiper.params.virtual.enabled;\n let newHeight = 0;\n let i;\n\n if (typeof speed === 'number') {\n swiper.setTransition(speed);\n } else if (speed === true) {\n swiper.setTransition(swiper.params.speed);\n }\n\n const getSlideByIndex = index => {\n if (isVirtual) {\n return swiper.slides.filter(el => parseInt(el.getAttribute('data-swiper-slide-index'), 10) === index)[0];\n }\n\n return swiper.slides.eq(index)[0];\n }; // Find slides currently in view\n\n\n if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {\n if (swiper.params.centeredSlides) {\n (swiper.visibleSlides || dom([])).each(slide => {\n activeSlides.push(slide);\n });\n } else {\n for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {\n const index = swiper.activeIndex + i;\n if (index > swiper.slides.length && !isVirtual) break;\n activeSlides.push(getSlideByIndex(index));\n }\n }\n } else {\n activeSlides.push(getSlideByIndex(swiper.activeIndex));\n } // Find new height from highest slide in view\n\n\n for (i = 0; i < activeSlides.length; i += 1) {\n if (typeof activeSlides[i] !== 'undefined') {\n const height = activeSlides[i].offsetHeight;\n newHeight = height > newHeight ? height : newHeight;\n }\n } // Update Height\n\n\n if (newHeight || newHeight === 0) swiper.$wrapperEl.css('height', `${newHeight}px`);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/updateSlidesOffset.js\nfunction updateSlidesOffset() {\n const swiper = this;\n const slides = swiper.slides;\n\n for (let i = 0; i < slides.length; i += 1) {\n slides[i].swiperSlideOffset = swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/updateSlidesProgress.js\n\nfunction updateSlidesProgress(translate = this && this.translate || 0) {\n const swiper = this;\n const params = swiper.params;\n const {\n slides,\n rtlTranslate: rtl,\n snapGrid\n } = swiper;\n if (slides.length === 0) return;\n if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();\n let offsetCenter = -translate;\n if (rtl) offsetCenter = translate; // Visible Slides\n\n slides.removeClass(params.slideVisibleClass);\n swiper.visibleSlidesIndexes = [];\n swiper.visibleSlides = [];\n\n for (let i = 0; i < slides.length; i += 1) {\n const slide = slides[i];\n let slideOffset = slide.swiperSlideOffset;\n\n if (params.cssMode && params.centeredSlides) {\n slideOffset -= slides[0].swiperSlideOffset;\n }\n\n const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + params.spaceBetween);\n const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + params.spaceBetween);\n const slideBefore = -(offsetCenter - slideOffset);\n const slideAfter = slideBefore + swiper.slidesSizesGrid[i];\n const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;\n\n if (isVisible) {\n swiper.visibleSlides.push(slide);\n swiper.visibleSlidesIndexes.push(i);\n slides.eq(i).addClass(params.slideVisibleClass);\n }\n\n slide.progress = rtl ? -slideProgress : slideProgress;\n slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;\n }\n\n swiper.visibleSlides = dom(swiper.visibleSlides);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/updateProgress.js\nfunction updateProgress(translate) {\n const swiper = this;\n\n if (typeof translate === 'undefined') {\n const multiplier = swiper.rtlTranslate ? -1 : 1; // eslint-disable-next-line\n\n translate = swiper && swiper.translate && swiper.translate * multiplier || 0;\n }\n\n const params = swiper.params;\n const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();\n let {\n progress,\n isBeginning,\n isEnd\n } = swiper;\n const wasBeginning = isBeginning;\n const wasEnd = isEnd;\n\n if (translatesDiff === 0) {\n progress = 0;\n isBeginning = true;\n isEnd = true;\n } else {\n progress = (translate - swiper.minTranslate()) / translatesDiff;\n isBeginning = progress <= 0;\n isEnd = progress >= 1;\n }\n\n Object.assign(swiper, {\n progress,\n isBeginning,\n isEnd\n });\n if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);\n\n if (isBeginning && !wasBeginning) {\n swiper.emit('reachBeginning toEdge');\n }\n\n if (isEnd && !wasEnd) {\n swiper.emit('reachEnd toEdge');\n }\n\n if (wasBeginning && !isBeginning || wasEnd && !isEnd) {\n swiper.emit('fromEdge');\n }\n\n swiper.emit('progress', progress);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/updateSlidesClasses.js\nfunction updateSlidesClasses() {\n const swiper = this;\n const {\n slides,\n params,\n $wrapperEl,\n activeIndex,\n realIndex\n } = swiper;\n const isVirtual = swiper.virtual && params.virtual.enabled;\n slides.removeClass(`${params.slideActiveClass} ${params.slideNextClass} ${params.slidePrevClass} ${params.slideDuplicateActiveClass} ${params.slideDuplicateNextClass} ${params.slideDuplicatePrevClass}`);\n let activeSlide;\n\n if (isVirtual) {\n activeSlide = swiper.$wrapperEl.find(`.${params.slideClass}[data-swiper-slide-index=\"${activeIndex}\"]`);\n } else {\n activeSlide = slides.eq(activeIndex);\n } // Active classes\n\n\n activeSlide.addClass(params.slideActiveClass);\n\n if (params.loop) {\n // Duplicate to all looped slides\n if (activeSlide.hasClass(params.slideDuplicateClass)) {\n $wrapperEl.children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index=\"${realIndex}\"]`).addClass(params.slideDuplicateActiveClass);\n } else {\n $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index=\"${realIndex}\"]`).addClass(params.slideDuplicateActiveClass);\n }\n } // Next Slide\n\n\n let nextSlide = activeSlide.nextAll(`.${params.slideClass}`).eq(0).addClass(params.slideNextClass);\n\n if (params.loop && nextSlide.length === 0) {\n nextSlide = slides.eq(0);\n nextSlide.addClass(params.slideNextClass);\n } // Prev Slide\n\n\n let prevSlide = activeSlide.prevAll(`.${params.slideClass}`).eq(0).addClass(params.slidePrevClass);\n\n if (params.loop && prevSlide.length === 0) {\n prevSlide = slides.eq(-1);\n prevSlide.addClass(params.slidePrevClass);\n }\n\n if (params.loop) {\n // Duplicate to all looped slides\n if (nextSlide.hasClass(params.slideDuplicateClass)) {\n $wrapperEl.children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index=\"${nextSlide.attr('data-swiper-slide-index')}\"]`).addClass(params.slideDuplicateNextClass);\n } else {\n $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index=\"${nextSlide.attr('data-swiper-slide-index')}\"]`).addClass(params.slideDuplicateNextClass);\n }\n\n if (prevSlide.hasClass(params.slideDuplicateClass)) {\n $wrapperEl.children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index=\"${prevSlide.attr('data-swiper-slide-index')}\"]`).addClass(params.slideDuplicatePrevClass);\n } else {\n $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index=\"${prevSlide.attr('data-swiper-slide-index')}\"]`).addClass(params.slideDuplicatePrevClass);\n }\n }\n\n swiper.emitSlidesClasses();\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/updateActiveIndex.js\nfunction updateActiveIndex(newActiveIndex) {\n const swiper = this;\n const translate = swiper.rtlTranslate ? swiper.translate : -swi
1per.translate;\n const {\n slidesGrid,\n snapGrid,\n params,\n activeIndex: previousIndex,\n realIndex: previousRealIndex,\n snapIndex: previousSnapIndex\n } = swiper;\n let activeIndex = newActiveIndex;\n let snapIndex;\n\n if (typeof activeIndex === 'undefined') {\n for (let i = 0; i < slidesGrid.length; i += 1) {\n if (typeof slidesGrid[i + 1] !== 'undefined') {\n if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {\n activeIndex = i;\n } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {\n activeIndex = i + 1;\n }\n } else if (translate >= slidesGrid[i]) {\n activeIndex = i;\n }\n } // Normalize slideIndex\n\n\n if (params.normalizeSlideIndex) {\n if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;\n }\n }\n\n if (snapGrid.indexOf(translate) >= 0) {\n snapIndex = snapGrid.indexOf(translate);\n } else {\n const skip = Math.min(params.slidesPerGroupSkip, activeIndex);\n snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);\n }\n\n if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;\n\n if (activeIndex === previousIndex) {\n if (snapIndex !== previousSnapIndex) {\n swiper.snapIndex = snapIndex;\n swiper.emit('snapIndexChange');\n }\n\n return;\n } // Get real index\n\n\n const realIndex = parseInt(swiper.slides.eq(activeIndex).attr('data-swiper-slide-index') || activeIndex, 10);\n Object.assign(swiper, {\n snapIndex,\n realIndex,\n previousIndex,\n activeIndex\n });\n swiper.emit('activeIndexChange');\n swiper.emit('snapIndexChange');\n\n if (previousRealIndex !== realIndex) {\n swiper.emit('realIndexChange');\n }\n\n if (swiper.initialized || swiper.params.runCallbacksOnInit) {\n swiper.emit('slideChange');\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/updateClickedSlide.js\n\nfunction updateClickedSlide(e) {\n const swiper = this;\n const params = swiper.params;\n const slide = dom(e).closest(`.${params.slideClass}`)[0];\n let slideFound = false;\n let slideIndex;\n\n if (slide) {\n for (let i = 0; i < swiper.slides.length; i += 1) {\n if (swiper.slides[i] === slide) {\n slideFound = true;\n slideIndex = i;\n break;\n }\n }\n }\n\n if (slide && slideFound) {\n swiper.clickedSlide = slide;\n\n if (swiper.virtual && swiper.params.virtual.enabled) {\n swiper.clickedIndex = parseInt(dom(slide).attr('data-swiper-slide-index'), 10);\n } else {\n swiper.clickedIndex = slideIndex;\n }\n } else {\n swiper.clickedSlide = undefined;\n swiper.clickedIndex = undefined;\n return;\n }\n\n if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {\n swiper.slideToClickedSlide();\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/update/index.js\n\n\n\n\n\n\n\n\n\n/* harmony default export */ const update = ({\n updateSize: updateSize,\n updateSlides: updateSlides,\n updateAutoHeight: updateAutoHeight,\n updateSlidesOffset: updateSlidesOffset,\n updateSlidesProgress: updateSlidesProgress,\n updateProgress: updateProgress,\n updateSlidesClasses: updateSlidesClasses,\n updateActiveIndex: updateActiveIndex,\n updateClickedSlide: updateClickedSlide\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/translate/getTranslate.js\n\nfunction getSwiperTranslate(axis = this.isHorizontal() ? 'x' : 'y') {\n const swiper = this;\n const {\n params,\n rtlTranslate: rtl,\n translate,\n $wrapperEl\n } = swiper;\n\n if (params.virtualTranslate) {\n return rtl ? -translate : translate;\n }\n\n if (params.cssMode) {\n return translate;\n }\n\n let currentTranslate = getTranslate($wrapperEl[0], axis);\n if (rtl) currentTranslate = -currentTranslate;\n return currentTranslate || 0;\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/translate/setTranslate.js\nfunction setTranslate(translate, byController) {\n const swiper = this;\n const {\n rtlTranslate: rtl,\n params,\n $wrapperEl,\n wrapperEl,\n progress\n }
1 = swiper;\n let x = 0;\n let y = 0;\n const z = 0;\n\n if (swiper.isHorizontal()) {\n x = rtl ? -translate : translate;\n } else {\n y = translate;\n }\n\n if (params.roundLengths) {\n x = Math.floor(x);\n y = Math.floor(y);\n }\n\n if (params.cssMode) {\n wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;\n } else if (!params.virtualTranslate) {\n $wrapperEl.transform(`translate3d(${x}px, ${y}px, ${z}px)`);\n }\n\n swiper.previousTranslate = swiper.translate;\n swiper.translate = swiper.isHorizontal() ? x : y; // Check if we need to update progress\n\n let newProgress;\n const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();\n\n if (translatesDiff === 0) {\n newProgress = 0;\n } else {\n newProgress = (translate - swiper.minTranslate()) / translatesDiff;\n }\n\n if (newProgress !== progress) {\n swiper.updateProgress(translate);\n }\n\n swiper.emit('setTranslate', swiper.translate, byController);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/translate/minTranslate.js\nfunction minTranslate() {\n return -this.snapGrid[0];\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/translate/maxTranslate.js\nfunction maxTranslate() {\n return -this.snapGrid[this.snapGrid.length - 1];\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/translate/translateTo.js\n\nfunction translateTo(translate = 0, speed = this.params.speed, runCallbacks = true, translateBounds = true, internal) {\n const swiper = this;\n const {\n params,\n wrapperEl\n } = swiper;\n\n if (swiper.animating && params.preventInteractionOnTransition) {\n return false;\n }\n\n const minTranslate = swiper.minTranslate();\n const maxTranslate = swiper.maxTranslate();\n let newTranslate;\n if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate; // Update progress\n\n swiper.updateProgress(newTranslate);\n\n if (params.cssMode) {\n const isH = swiper.isHorizontal();\n\n if (speed === 0) {\n wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;\n } else {\n if (!swiper.support.smoothScroll) {\n animateCSSModeScroll({\n swiper,\n targetPosition: -newTranslate,\n side: isH ? 'left' : 'top'\n });\n return true;\n }\n\n wrapperEl.scrollTo({\n [isH ? 'left' : 'top']: -newTranslate,\n behavior: 'smooth'\n });\n }\n\n return true;\n }\n\n if (speed === 0) {\n swiper.setTransition(0);\n swiper.setTranslate(newTranslate);\n\n if (runCallbacks) {\n swiper.emit('beforeTransitionStart', speed, internal);\n swiper.emit('transitionEnd');\n }\n } else {\n swiper.setTransition(speed);\n swiper.setTranslate(newTranslate);\n\n if (runCallbacks) {\n swiper.emit('beforeTransitionStart', speed, internal);\n swiper.emit('transitionStart');\n }\n\n if (!swiper.animating) {\n swiper.animating = true;\n\n if (!swiper.onTranslateToWrapperTransitionEnd) {\n swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {\n if (!swiper || swiper.destroyed) return;\n if (e.target !== this) return;\n swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);\n swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd);\n swiper.onTranslateToWrapperTransitionEnd = null;\n delete swiper.onTranslateToWrapperTransitionEnd;\n\n if (runCallbacks) {\n swiper.emit('transitionEnd');\n }\n };\n }\n\n swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);\n swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd);\n }\n }\n\n return true;\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/translate/index.js\n\n\n\n\n\n/* harmony default export */ const translate = ({\n getTranslate: getSwiperTranslate,\n setTranslate: setTranslate,\n minTranslate: minTranslate,\n maxTranslate: maxTranslate,\n translateTo: translateTo\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/transition/setTransition.js\nfunction setTransition(duration, byController) {\n const swiper = this;\n\n if (!swiper.params.cssMode) {\n swiper.$wrapperEl.transition(duration);\n }\n\n swiper.emit('setTransition', duration, byController);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/transition/transitionEmit.js\nfunction transitionEmit({\n swiper,\n runCallbacks,\n direction,\n step\n}) {\n const {\n activeIndex,\n previousIndex\n } = swiper;\n let dir = direction;\n\n if (!dir) {\n if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';\n }\n\n swiper.emit(`transition${step}`);\n\n if (runCallbacks && activeIndex !== previousIndex) {\n if (dir === 'reset') {\n swiper.emit(`slideResetTransition${step}`);\n return;\n }\n\n swiper.emit(`slideChangeTransition${step}`);\n\n if (dir === 'next') {\n swiper.emit(`slideNextTransition${step}`);\n } else {\n swiper.emit(`slidePrevTransition${step}`);\n }\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/transition/transitionStart.js\n\nfunction transitionStart_transitionStart(runCallbacks = true, direction) {\n const swiper = this;\n const {\n params\n } = swiper;\n if (params.cssMode) return;\n\n if (params.autoHeight) {\n swiper.updateAutoHeight();\n }\n\n transitionEmit({\n swiper,\n runCallbacks,\n direction,\n step: 'Start'\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/transition/transitionEnd.js\n\nfunction transitionEnd_transitionEnd(runCallbacks = true, direction) {\n const swiper = this;\n const {\n params\n } = swiper;\n swiper.animating = false;\n if (params.cssMode) return;\n swiper.setTransition(0);\n transitionEmit({\n swiper,\n runCallbacks,\n direction,\n step: 'End'\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/transition/index.js\n\n\n\n/* harmony default export */ const core_transition = ({\n setTransition: setTransition,\n transitionStart: transitionStart_transitionStart,\n transitionEnd: transitionEnd_transitionEnd\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/slide/slideTo.js\n\nfunction slideTo(index = 0, speed = this.params.speed, runCallbacks = true, internal, initial) {\n if (typeof index !== 'number' && typeof index !== 'string') {\n throw new Error(`The 'index' argument cannot have type other than 'number' or 'string'. [${typeof index}] given.`);\n }\n\n if (typeof index === 'string') {\n /**\n * The `index` argument converted from `string` to `number`.\n * @type {number}\n */\n const indexAsNumber = parseInt(index, 10);\n /**\n * Determines whether the `index` argument is a valid `number`\n * after being converted from the `string` type.\n * @type {boolean}\n */\n\n const isValidNumber = isFinite(indexAsNumber);\n\n if (!isValidNumber) {\n throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${index}] given.`);\n } // Knowing that the converted `index` is a valid number,\n // we can update the original argument's value.\n\n\n index = indexAsNumber;\n }\n\n const swiper = this;\n let slideIndex = index;\n if (slideIndex < 0) slideIndex = 0;\n const {\n params,\n snapGrid,\n slidesGrid,\n previousIndex,\n activeIndex,\n rtlTranslate: rtl,\n wrapperEl,\n enabled\n }
1 = swiper;\n\n if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) {\n return false;\n }\n\n const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);\n let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);\n if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;\n const translate = -snapGrid[snapIndex]; // Normalize slideIndex\n\n if (params.normalizeSlideIndex) {\n for (let i = 0; i < slidesGrid.length; i += 1) {\n const normalizedTranslate = -Math.floor(translate * 100);\n const normalizedGrid = Math.floor(slidesGrid[i] * 100);\n const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);\n\n if (typeof slidesGrid[i + 1] !== 'undefined') {\n if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {\n slideIndex = i;\n } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {\n slideIndex = i + 1;\n }\n } else if (normalizedTranslate >= normalizedGrid) {\n slideIndex = i;\n }\n }\n } // Directions locks\n\n\n if (swiper.initialized && slideIndex !== activeIndex) {\n if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {\n return false;\n }\n\n if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {\n if ((activeIndex || 0) !== slideIndex) return false;\n }\n }\n\n if (slideIndex !== (previousIndex || 0) && runCallbacks) {\n swiper.emit('beforeSlideChangeStart');\n } // Update progress\n\n\n swiper.updateProgress(translate);\n let direction;\n if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset'; // Update Index\n\n if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {\n swiper.updateActiveIndex(slideIndex); // Update Height\n\n if (params.autoHeight) {\n swiper.updateAutoHeight();\n }\n\n swiper.updateSlidesClasses();\n\n if (params.effect !== 'slide') {\n swiper.setTranslate(translate);\n }\n\n if (direction !== 'reset') {\n swiper.transitionStart(runCallbacks, direction);\n swiper.transitionEnd(runCallbacks, direction);\n }\n\n return false;\n }\n\n if (params.cssMode) {\n const isH = swiper.isHorizontal();\n const t = rtl ? translate : -translate;\n\n if (speed === 0) {\n const isVirtual = swiper.virtual && swiper.params.virtual.enabled;\n\n if (isVirtual) {\n swiper.wrapperEl.style.scrollSnapType = 'none';\n swiper._immediateVirtual = true;\n }\n\n wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;\n\n if (isVirtual) {\n requestAnimationFrame(() => {\n swiper.wrapperEl.style.scrollSnapType = '';\n swiper._swiperImmediateVirtual = false;\n });\n }\n } else {\n if (!swiper.support.smoothScroll) {\n animateCSSModeScroll({\n swiper,\n targetPosition: t,\n side: isH ? 'left' : 'top'\n });\n return true;\n }\n\n wrapperEl.scrollTo({\n [isH ? 'left' : 'top']: t,\n behavior: 'smooth'\n });\n }\n\n return true;\n }\n\n swiper.setTransition(speed);\n swiper.setTranslate(translate);\n swiper.updateActiveIndex(slideIndex);\n swiper.updateSlidesClasses();\n swiper.emit('beforeTransitionStart', speed, internal);\n swiper.transitionStart(runCallbacks, direction);\n\n if (speed === 0) {\n swiper.transitionEnd(runCallbacks, direction);\n } else if (!swiper.animating) {\n swiper.animating = true;\n\n if (!swiper.onSlideToWrapperTransitionEnd) {\n swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {\n if (!swiper || swiper.destroyed) return;\n if (e.target !== this) return;\n swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);\n swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);\n swiper.onSlideToWrapperTransitionEnd = null;\n delete swiper.onSlideToWrapperTransitionEnd;\n swiper.transitionEnd(runCallbacks, direction);\n };\n }\n\n swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);\n swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);\n }\n\n return true;\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/slide/slideToLoop.js\nfunction slideToLoop(index = 0, speed = this.params.speed, runCallbacks = true, internal) {\n if (typeof index === 'string') {\n /**\n * The `index` argument converted from `string` to `number`.\n * @type {number}\n */\n const indexAsNumber = parseInt(index, 10);\n /**\n * Determines whether the `index` argument is a valid `number`\n * after being converted from the `string` type.\n * @type {boolean}\n */\n\n const isValidNumber = isFinite(indexAsNumber);\n\n if (!isValidNumber) {\n throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${index}] given.`);\n } // Knowing that the converted `index` is a valid number,\n // we can update the original argument's value.\n\n\n index = indexAsNumber;\n }\n\n const swiper = this;\n let newIndex = index;\n\n if (swiper.params.loop) {\n newIndex += swiper.loopedSlides;\n }\n\n return swiper.slideTo(newIndex, speed, runCallbacks, internal);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/slide/slideNext.js\n/* eslint no-unused-vars: \"off\" */\nfunction slideNext(speed = this.params.speed, runCallbacks = true, internal) {\n const swiper = this;\n const {\n animating,\n enabled,\n params\n } = swiper;\n if (!enabled) return swiper;\n let perGroup = params.slidesPerGroup;\n\n if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {\n perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);\n }\n\n const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;\n\n if (params.loop) {\n if (animating && params.loopPreventsSlide) return false;\n swiper.loopFix(); // eslint-disable-next-line\n\n swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;\n }\n\n if (params.rewind && swiper.isEnd) {\n return swiper.slideTo(0, speed, runCallbacks, internal);\n }\n\n return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/slide/slidePrev.js\n/* eslint no-unused-vars: \"off\" */\nfunction slidePrev(speed = this.params.speed, runCallbacks = true, internal) {\n const swiper = this;\n const {\n params,\n animating,\n snapGrid,\n slidesGrid,\n rtlTranslate,\n enabled\n }
1 = swiper;\n if (!enabled) return swiper;\n\n if (params.loop) {\n if (animating && params.loopPreventsSlide) return false;\n swiper.loopFix(); // eslint-disable-next-line\n\n swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;\n }\n\n const translate = rtlTranslate ? swiper.translate : -swiper.translate;\n\n function normalize(val) {\n if (val < 0) return -Math.floor(Math.abs(val));\n return Math.floor(val);\n }\n\n const normalizedTranslate = normalize(translate);\n const normalizedSnapGrid = snapGrid.map(val => normalize(val));\n let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];\n\n if (typeof prevSnap === 'undefined' && params.cssMode) {\n let prevSnapIndex;\n snapGrid.forEach((snap, snapIndex) => {\n if (normalizedTranslate >= snap) {\n // prevSnap = snap;\n prevSnapIndex = snapIndex;\n }\n });\n\n if (typeof prevSnapIndex !== 'undefined') {\n prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];\n }\n }\n\n let prevIndex = 0;\n\n if (typeof prevSnap !== 'undefined') {\n prevIndex = slidesGrid.indexOf(prevSnap);\n if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;\n\n if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {\n prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;\n prevIndex = Math.max(prevIndex, 0);\n }\n }\n\n if (params.rewind && swiper.isBeginning) {\n const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;\n return swiper.slideTo(lastIndex, speed, runCallbacks, internal);\n }\n\n return swiper.slideTo(prevIndex, speed, runCallbacks, internal);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/slide/slideReset.js\n/* eslint no-unused-vars: \"off\" */\nfunction slideReset(speed = this.params.speed, runCallbacks = true, internal) {\n const swiper = this;\n return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/slide/slideToClosest.js\n/* eslint no-unused-vars: \"off\" */\nfunction slideToClosest(speed = this.params.speed, runCallbacks = true, internal, threshold = 0.5) {\n const swiper = this;\n let index = swiper.activeIndex;\n const skip = Math.min(swiper.params.slidesPerGroupSkip, index);\n const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);\n const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;\n\n if (translate >= swiper.snapGrid[snapIndex]) {\n // The current translate is on or after the current snap index, so the choice\n // is between the current index and the one after it.\n const currentSnap = swiper.snapGrid[snapIndex];\n const nextSnap = swiper.snapGrid[snapIndex + 1];\n\n if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {\n index += swiper.params.slidesPerGroup;\n }\n } else {\n // The current translate is before the current snap index, so the choice\n // is between the current index and the one before it.\n const prevSnap = swiper.snapGrid[snapIndex - 1];\n const currentSnap = swiper.snapGrid[snapIndex];\n\n if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {\n index -= swiper.params.slidesPerGroup;\n }\n }\n\n index = Math.max(index, 0);\n index = Math.min(index, swiper.slidesGrid.length - 1);\n return swiper.slideTo(index, speed, runCallbacks, internal);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/slide/slideToClickedSlide.js\n\n\nfunction slideToClickedSlide() {\n const swiper = this;\n const {\n params,\n $wrapperEl\n } = swiper;\n const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;\n let slideToIndex = swiper.clickedIndex;\n let realIndex;\n\n if (params.loop) {\n if (swiper.animating) return;\n realIndex = parseInt(dom(swiper.clickedSlide).attr('data-swiper-slide-index'), 10);\n\n if (params.centeredSlides) {\n if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper.loopedSlides + slidesPerView / 2) {\n swiper.loopFix();\n slideToIndex = $wrapperEl.children(`.${params.slideClass}[data-swiper-slide-index=\"${realIndex}\"]:not(.${params.slideDuplicateClass})`).eq(0).index();\n nextTick(() =>
1 {\n swiper.slideTo(slideToIndex);\n });\n } else {\n swiper.slideTo(slideToIndex);\n }\n } else if (slideToIndex > swiper.slides.length - slidesPerView) {\n swiper.loopFix();\n slideToIndex = $wrapperEl.children(`.${params.slideClass}[data-swiper-slide-index=\"${realIndex}\"]:not(.${params.slideDuplicateClass})`).eq(0).index();\n nextTick(() => {\n swiper.slideTo(slideToIndex);\n });\n } else {\n swiper.slideTo(slideToIndex);\n }\n } else {\n swiper.slideTo(slideToIndex);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/slide/index.js\n\n\n\n\n\n\n\n/* harmony default export */ const slide = ({\n slideTo: slideTo,\n slideToLoop: slideToLoop,\n slideNext: slideNext,\n slidePrev: slidePrev,\n slideReset: slideReset,\n slideToClosest: slideToClosest,\n slideToClickedSlide: slideToClickedSlide\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/loop/loopCreate.js\n\n\nfunction loopCreate() {\n const swiper = this;\n const document = getDocument();\n const {\n params,\n $wrapperEl\n } = swiper; // Remove duplicated slides\n\n const $selector = $wrapperEl.children().length > 0 ? dom($wrapperEl.children()[0].parentNode) : $wrapperEl;\n $selector.children(`.${params.slideClass}.${params.slideDuplicateClass}`).remove();\n let slides = $selector.children(`.${params.slideClass}`);\n\n if (params.loopFillGroupWithBlank) {\n const blankSlidesNum = params.slidesPerGroup - slides.length % params.slidesPerGroup;\n\n if (blankSlidesNum !== params.slidesPerGroup) {\n for (let i = 0; i < blankSlidesNum; i += 1) {\n const blankNode = dom(document.createElement('div')).addClass(`${params.slideClass} ${params.slideBlankClass}`);\n $selector.append(blankNode);\n }\n\n slides = $selector.children(`.${params.slideClass}`);\n }\n }\n\n if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length;\n swiper.loopedSlides = Math.ceil(parseFloat(params.loopedSlides || params.slidesPerView, 10));\n swiper.loopedSlides += params.loopAdditionalSlides;\n\n if (swiper.loopedSlides > slides.length && swiper.params.loopedSlidesLimit) {\n swiper.loopedSlides = slides.length;\n }\n\n const prependSlides = [];\n const appendSlides = [];\n slides.each((el, index) => {\n const slide = dom(el);\n slide.attr('data-swiper-slide-index', index);\n });\n\n for (let i = 0; i < swiper.loopedSlides; i += 1) {\n const index = i - Math.floor(i / slides.length) * slides.length;\n appendSlides.push(slides.eq(index)[0]);\n prependSlides.unshift(slides.eq(slides.length - index - 1)[0]);\n }\n\n for (let i = 0; i < appendSlides.length; i += 1) {\n $selector.append(dom(appendSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass));\n }\n\n for (let i = prependSlides.length - 1; i >= 0; i -= 1) {\n $selector.prepend(dom(prependSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass));\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/loop/loopFix.js\nfunction loopFix() {\n const swiper = this;\n swiper.emit('beforeLoopFix');\n const {\n activeIndex,\n slides,\n loopedSlides,\n allowSlidePrev,\n allowSlideNext,\n snapGrid,\n rtlTranslate: rtl\n } = swiper;\n let newIndex;\n swiper.allowSlidePrev = true;\n swiper.allowSlideNext = true;\n const snapTranslate = -snapGrid[activeIndex];\n const diff = snapTranslate - swiper.getTranslate(); // Fix For Negative Oversliding\n\n if (activeIndex < loopedSlides) {\n newIndex = slides.length - loopedSlides * 3 + activeIndex;\n newIndex += loopedSlides;\n const slideChanged = swiper.slideTo(newIndex, 0, false, true);\n\n if (slideChanged && diff !== 0) {\n swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);\n }\n } else if (activeIndex >= slides.length - loopedSlides) {\n // Fix For Positive Oversliding\n newIndex = -slides.length + activeIndex + loopedSlides;\n newIndex += loopedSlides;\n const slideChanged = swiper.slideTo(newIndex, 0, false, true);\n\n if (slideChanged && diff !== 0) {\n swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);\n }\n }\n\n swiper.allowSlidePrev = allowSlidePrev;\n swiper.allowSlideNext = allowSlideNext;\n swiper.emit('loopFix');\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/loop/loopDestroy.js\nfunction loopDestroy() {\n const swiper = this;\n const {\n $wrapperEl,\n params,\n slides\n } = swiper;\n $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass},.${params.slideClass}.${params.slideBlankClass}`).remove();\n slides.removeAttr('data-swiper-slide-index');\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/loop/index.js\n\n\n\n/* harmony default export */ const loop = ({\n loopCreate: loopCreate,\n loopFix: loopFix,\n loopDestroy: loopDestroy\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/grab-cursor/setGrabCursor.js\nfunction setGrabCursor(moving) {\n const swiper = this;\n if (swiper.support.touch || !swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;\n const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl;\n el.style.cursor = 'move';\n el.style.cursor = moving ? 'grabbing' : 'grab';\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/grab-cursor/unsetGrabCursor.js\nfunction unsetGrabCursor(
1) {\n const swiper = this;\n\n if (swiper.support.touch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {\n return;\n }\n\n swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = '';\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/grab-cursor/index.js\n\n\n/* harmony default export */ const grab_cursor = ({\n setGrabCursor: setGrabCursor,\n unsetGrabCursor: unsetGrabCursor\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/events/onTouchStart.js\n\n\n // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd\n\nfunction closestElement(selector, base = this) {\n function __closestFrom(el) {\n if (!el || el === getDocument() || el === ssr_window_esm_getWindow()) return null;\n if (el.assignedSlot) el = el.assignedSlot;\n const found = el.closest(selector);\n\n if (!found && !el.getRootNode) {\n return null;\n }\n\n return found || __closestFrom(el.getRootNode().host);\n }\n\n return __closestFrom(base);\n}\n\nfunction onTouchStart(event) {\n const swiper = this;\n const document = getDocument();\n const window = ssr_window_esm_getWindow();\n const data = swiper.touchEventsData;\n const {\n params,\n touches,\n enabled\n } = swiper;\n if (!enabled) return;\n\n if (swiper.animating && params.preventInteractionOnTransition) {\n return;\n }\n\n if (!swiper.animating && params.cssMode && params.loop) {\n swiper.loopFix();\n }\n\n let e = event;\n if (e.originalEvent) e = e.originalEvent;\n let $targetEl = dom(e.target);\n\n if (params.touchEventsTarget === 'wrapper') {\n if (!$targetEl.closest(swiper.wrapperEl).length) return;\n }\n\n data.isTouchEvent = e.type === 'touchstart';\n if (!data.isTouchEvent && 'which' in e && e.which === 3) return;\n if (!data.isTouchEvent && 'button' in e && e.button > 0) return;\n if (data.isTouched && data.isMoved) return; // change target el for shadow root component\n\n const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== ''; // eslint-disable-next-line\n\n const eventPath = event.composedPath ? event.composedPath() : event.path;\n\n if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {\n $targetEl = dom(eventPath[0]);\n }\n\n const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;\n const isTargetShadow = !!(e.target && e.target.shadowRoot); // use closestElement for shadow root element to get the actual closest for nested shadow root element\n\n if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, $targetEl[0]) : $targetEl.closest(noSwipingSelector)[0])) {\n swiper.allowClick = true;\n return;\n }\n\n if (params.swipeHandler) {\n if (!$targetEl.closest(params.swipeHandler)[0]) return;\n }\n\n touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n const startX = touches.currentX;\n const startY = touches.currentY; // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore\n\n const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;\n const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;\n\n if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {\n if (edgeSwipeDetection === 'prevent') {\n event.preventDefault();\n } else {\n return;\n }\n }\n\n Object.assign(data, {\n isTouched: true,\n isMoved: false,\n allowTouchCallbacks: true,\n isScrolling: undefined,\n startMoving: undefined\n });\n touches.startX = startX;\n touches.startY = startY;\n data.touchStartTime = now();\n swiper.allowClick = true;\n swiper.updateSize();\n swiper.swipeDirection = undefined;\n if (params.threshold > 0) data.allowThresholdMove = false;\n\n if (e.type !== 'touchstart') {\n let preventDefault = true;\n\n if ($targetEl.is(data.focusableElements)) {\n preventDefault = false;\n\n if ($targetEl[0].nodeName === 'SELECT') {\n data.isTouched = false;\n }\n }\n\n if (document.activeElement && dom(document.activeElement).is(data.focusableElements) && document.activeElement !== $targetEl[0]) {\n document.activeElement.blur();\n }\n\n const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;\n\n if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !$targetEl[0].isContentEditable) {\n e.preventDefault();\n }\n }\n\n if (swiper.params.freeMode && swiper.params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {\n swiper.freeMode.onTouchStart();\n }\n\n swiper.emit('touchStart', e);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/events/onTouchMove.js\n\n\n\nfunction onTouchMove(event) {\n const document = getDocument();\n const swiper = this;\n const data = swiper.touchEventsData;\n const {\n params,\n touches,\n rtlTranslate: rtl,\n enabled\n }
1 = swiper;\n if (!enabled) return;\n let e = event;\n if (e.originalEvent) e = e.originalEvent;\n\n if (!data.isTouched) {\n if (data.startMoving && data.isScrolling) {\n swiper.emit('touchMoveOpposite', e);\n }\n\n return;\n }\n\n if (data.isTouchEvent && e.type !== 'touchmove') return;\n const targetTouch = e.type === 'touchmove' && e.targetTouches && (e.targetTouches[0] || e.changedTouches[0]);\n const pageX = e.type === 'touchmove' ? targetTouch.pageX : e.pageX;\n const pageY = e.type === 'touchmove' ? targetTouch.pageY : e.pageY;\n\n if (e.preventedByNestedSwiper) {\n touches.startX = pageX;\n touches.startY = pageY;\n return;\n }\n\n if (!swiper.allowTouchMove) {\n if (!dom(e.target).is(data.focusableElements)) {\n swiper.allowClick = false;\n }\n\n if (data.isTouched) {\n Object.assign(touches, {\n startX: pageX,\n startY: pageY,\n currentX: pageX,\n currentY: pageY\n });\n data.touchStartTime = now();\n }\n\n return;\n }\n\n if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) {\n if (swiper.isVertical()) {\n // Vertical\n if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {\n data.isTouched = false;\n data.isMoved = false;\n return;\n }\n } else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate()) {\n return;\n }\n }\n\n if (data.isTouchEvent && document.activeElement) {\n if (e.target === document.activeElement && dom(e.target).is(data.focusableElements)) {\n data.isMoved = true;\n swiper.allowClick = false;\n return;\n }\n }\n\n if (data.allowTouchCallbacks) {\n swiper.emit('touchMove', e);\n }\n\n if (e.targetTouches && e.targetTouches.length > 1) return;\n touches.currentX = pageX;\n touches.currentY = pageY;\n const diffX = touches.currentX - touches.startX;\n const diffY = touches.currentY - touches.startY;\n if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;\n\n if (typeof data.isScrolling === 'undefined') {\n let touchAngle;\n\n if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {\n data.isScrolling = false;\n } else {\n // eslint-disable-next-line\n if (diffX * diffX + diffY * diffY >= 25) {\n touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;\n data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;\n }\n }\n }\n\n if (data.isScrolling) {\n swiper.emit('touchMoveOpposite', e);\n }\n\n if (typeof data.startMoving === 'undefined') {\n if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {\n data.startMoving = true;\n }\n }\n\n if (data.isScrolling) {\n data.isTouched = false;\n return;\n }\n\n if (!data.startMoving) {\n return;\n }\n\n swiper.allowClick = false;\n\n if (!params.cssMode && e.cancelable) {\n e.preventDefault();\n }\n\n if (params.touchMoveStopPropagation && !params.nested) {\n e.stopPropagation();\n }\n\n if (!data.isMoved) {\n if (params.loop && !params.cssMode) {\n swiper.loopFix();\n }\n\n data.startTranslate = swiper.getTranslate();\n swiper.setTransition(0);\n\n if (swiper.animating) {\n swiper.$wrapperEl.trigger('webkitTransitionEnd transitionend');\n }\n\n data.allowMomentumBounce = false; // Grab Cursor\n\n if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {\n swiper.setGrabCursor(true);\n }\n\n swiper.emit('sliderFirstMove', e);\n }\n\n swiper.emit('sliderMove', e);\n data.isMoved = true;\n let diff = swiper.isHorizontal() ? diffX : diffY;\n touches.diff = diff;\n diff *= params.touchRatio;\n if (rtl) diff = -diff;\n swiper.swipeDirection = diff > 0 ? 'prev' : 'next';\n data.currentTranslate = diff + data.startTranslate;\n let disableParentSwiper = true;\n let resistanceRatio = params.resistanceRatio;\n\n if (params.touchReleaseOnEdges) {\n resistanceRatio = 0;\n }\n\n if (diff > 0 && data.currentTranslate > swiper.minTranslate()) {\n disableParentSwiper = false;\n if (params.resistance) data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio;\n } else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) {\n disableParentSwiper = false;\n if (params.resistance) data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio;\n }\n\n if (disableParentSwiper) {\n e.preventedByNestedSwiper = true;\n } // Directions locks\n\n\n if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {\n data.currentTranslate = data.startTranslate;\n }\n\n if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {\n data.currentTranslate = data.startTranslate;\n }\n\n if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {\n data.currentTranslate = data.startTranslate;\n } // Threshold\n\n\n if (params.threshold > 0) {\n if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {\n if (!data.allowThresholdMove) {\n data.allowThresholdMove = true;\n touches.startX = touches.currentX;\n touches.startY = touches.currentY;\n data.currentTranslate = data.startTranslate;\n touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;\n return;\n }\n } else {\n data.currentTranslate = data.startTranslate;\n return;\n }\n }\n\n if (!params.followFinger || params.cssMode) return; // Update active index in free mode\n\n if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n\n if (swiper.params.freeMode && params.freeMode.enabled && swiper.freeMode) {\n swiper.freeMode.onTouchMove();\n } // Update progress\n\n\n swiper.updateProgress(data.currentTranslate); // Update translate\n\n swiper.setTranslate(data.currentTranslate);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/events/onTouchEnd.js\n\nfunction onTouchEnd(event) {\n const swiper = this;\n const data = swiper.touchEventsData;\n const {\n params,\n touches,\n rtlTranslate: rtl,\n slidesGrid,\n enabled\n }
1 = swiper;\n if (!enabled) return;\n let e = event;\n if (e.originalEvent) e = e.originalEvent;\n\n if (data.allowTouchCallbacks) {\n swiper.emit('touchEnd', e);\n }\n\n data.allowTouchCallbacks = false;\n\n if (!data.isTouched) {\n if (data.isMoved && params.grabCursor) {\n swiper.setGrabCursor(false);\n }\n\n data.isMoved = false;\n data.startMoving = false;\n return;\n } // Return Grab Cursor\n\n\n if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {\n swiper.setGrabCursor(false);\n } // Time diff\n\n\n const touchEndTime = now();\n const timeDiff = touchEndTime - data.touchStartTime; // Tap, doubleTap, Click\n\n if (swiper.allowClick) {\n const pathTree = e.path || e.composedPath && e.composedPath();\n swiper.updateClickedSlide(pathTree && pathTree[0] || e.target);\n swiper.emit('tap click', e);\n\n if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {\n swiper.emit('doubleTap doubleClick', e);\n }\n }\n\n data.lastClickTime = now();\n nextTick(() => {\n if (!swiper.destroyed) swiper.allowClick = true;\n });\n\n if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) {\n data.isTouched = false;\n data.isMoved = false;\n data.startMoving = false;\n return;\n }\n\n data.isTouched = false;\n data.isMoved = false;\n data.startMoving = false;\n let currentPos;\n\n if (params.followFinger) {\n currentPos = rtl ? swiper.translate : -swiper.translate;\n } else {\n currentPos = -data.currentTranslate;\n }\n\n if (params.cssMode) {\n return;\n }\n\n if (swiper.params.freeMode && params.freeMode.enabled) {\n swiper.freeMode.onTouchEnd({\n currentPos\n });\n return;\n } // Find current slide\n\n\n let stopIndex = 0;\n let groupSize = swiper.slidesSizesGrid[0];\n\n for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {\n const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;\n\n if (typeof slidesGrid[i + increment] !== 'undefined') {\n if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {\n stopIndex = i;\n groupSize = slidesGrid[i + increment] - slidesGrid[i];\n }\n } else if (currentPos >= slidesGrid[i]) {\n stopIndex = i;\n groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];\n }\n }\n\n let rewindFirstIndex = null;\n let rewindLastIndex = null;\n\n if (params.rewind) {\n if (swiper.isBeginning) {\n rewindLastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;\n } else if (swiper.isEnd) {\n rewindFirstIndex = 0;\n }\n } // Find current slide size\n\n\n const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;\n const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;\n\n if (timeDiff > params.longSwipesMs) {\n // Long touches\n if (!params.longSwipes) {\n swiper.slideTo(swiper.activeIndex);\n return;\n }\n\n if (swiper.swipeDirection === 'next') {\n if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex);\n }\n\n if (swiper.swipeDirection === 'prev') {\n if (ratio > 1 - params.longSwipesRatio) {\n swiper.slideTo(stopIndex + increment);\n } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) {\n swiper.slideTo(rewindLastIndex);\n } else {\n swiper.slideTo(stopIndex);\n }\n }\n } else {\n // Short swipes\n if (!params.shortSwipes) {\n swiper.slideTo(swiper.activeIndex);\n return;\n }\n\n const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);\n\n if (!isNavButtonTarget) {\n if (swiper.swipeDirection === 'next') {\n swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment);\n }\n\n if (swiper.swipeDirection === 'prev') {\n swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex);\n }\n } else if (e.target === swiper.navigation.nextEl) {\n swiper.slideTo(stopIndex + increment);\n } else {\n swiper.slideTo(stopIndex);\n }\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/events/onResize.js\nfunction onResize() {\n const swiper = this;\n const {\n params,\n el\n } = swiper;\n if (el && el.offsetWidth === 0) return;
1 // Breakpoints\n\n if (params.breakpoints) {\n swiper.setBreakpoint();\n } // Save locks\n\n\n const {\n allowSlideNext,\n allowSlidePrev,\n snapGrid\n } = swiper; // Disable locks on resize\n\n swiper.allowSlideNext = true;\n swiper.allowSlidePrev = true;\n swiper.updateSize();\n swiper.updateSlides();\n swiper.updateSlidesClasses();\n\n if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides) {\n swiper.slideTo(swiper.slides.length - 1, 0, false, true);\n } else {\n swiper.slideTo(swiper.activeIndex, 0, false, true);\n }\n\n if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {\n swiper.autoplay.run();\n } // Return locks after resize\n\n\n swiper.allowSlidePrev = allowSlidePrev;\n swiper.allowSlideNext = allowSlideNext;\n\n if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {\n swiper.checkOverflow();\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/events/onClick.js\nfunction onClick(e) {\n const swiper = this;\n if (!swiper.enabled) return;\n\n if (!swiper.allowClick) {\n if (swiper.params.preventClicks) e.preventDefault();\n\n if (swiper.params.preventClicksPropagation && swiper.animating) {\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/events/onScroll.js\nfunction onScroll() {\n const swiper = this;\n const {\n wrapperEl,\n rtlTranslate,\n enabled\n } = swiper;\n if (!enabled) return;\n swiper.previousTranslate = swiper.translate;\n\n if (swiper.isHorizontal()) {\n swiper.translate = -wrapperEl.scrollLeft;\n } else {\n swiper.translate = -wrapperEl.scrollTop;\n } // eslint-disable-next-line\n\n\n if (swiper.translate === 0) swiper.translate = 0;\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n let newProgress;\n const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();\n\n if (translatesDiff === 0) {\n newProgress = 0;\n } else {\n newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;\n }\n\n if (newProgress !== swiper.progress) {\n swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);\n }\n\n swiper.emit('setTranslate', swiper.translate, false);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/events/index.js\n\n\n\n\n\n\n\nlet dummyEventAttached = false;\n\nfunction dummyEventListener() {}\n\nconst events = (swiper, method) => {\n const document = getDocument();\n const {\n params,\n touchEvents,\n el,\n wrapperEl,\n device,\n support\n } = swiper;\n const capture = !!params.nested;\n const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';\n const swiperMethod = method; // Touch Events\n\n if (!support.touch) {\n el[domMethod](touchEvents.start, swiper.onTouchStart, false);\n document[domMethod](touchEvents.move, swiper.onTouchMove, capture);\n document[domMethod](touchEvents.end, swiper.onTouchEnd, false);\n } else {\n const passiveListener = touchEvents.start === 'touchstart' && support.passiveListener && params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n el[domMethod](touchEvents.start, swiper.onTouchStart, passiveListener);\n el[domMethod](touchEvents.move, swiper.onTouchMove, support.passiveListener ? {\n passive: false,\n capture\n } : capture);\n el[domMethod](touchEvents.end, swiper.onTouchEnd, passiveListener);\n\n if (touchEvents.cancel) {\n el[domMethod](touchEvents.cancel, swiper.onTouchEnd, passiveListener);\n }\n } // Prevent Links Clicks\n\n\n if (params.preventClicks || params.preventClicksPropagation) {\n el[domMethod]('click', swiper.onClick, true);\n }\n\n if (params.cssMode) {\n wrapperEl[domMethod]('scroll', swiper.onScroll);\n } // Resize handler\n\n\n if (params.updateOnWindowResize) {\n swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true);\n } else {\n swiper[swiperMethod]('observerUpdate', onResize, true);\n }\n};\n\nfunction attachEvents() {\n const swiper = this;\n const document = getDocument();\n const {\n params,\n support\n } = swiper;\n swiper.onTouchStart = onTouchStart.bind(swiper);\n swiper.onTouchMove = onTouchMove.bind(swiper);\n swiper.onTouchEnd = onTouchEnd.bind(swiper);\n\n if (params.cssMode) {\n swiper.onScroll = onScroll.bind(swiper);\n }\n\n swiper.onClick = onClick.bind(swiper);\n\n if (support.touch && !dummyEventAttached) {\n document.addEventListener('touchstart', dummyEventListener);\n dummyEventAttached = true;\n }\n\n events(swiper, 'on');\n}\n\nfunction detachEvents() {\n const swiper = this;\n events(swiper, 'off');\n}\n\n/* harmony default export */ const core_events = ({\n attachEvents,\n detachEvents\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/breakpoints/setBreakpoint.js\n\n\nconst isGridEnabled = (swiper, params) => {\n return swiper.grid && params.grid && params.grid.rows > 1;\n};\n\nfunction setBreakpoint() {\n const swiper = this;\n const {\n activeIndex,\n initialized,\n loopedSlides = 0,\n params,\n $el\n } = swiper;\n const breakpoints = params.breakpoints;\n if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return; // Get breakpoint for window width and update parameters\n\n const breakpoint = swiper.getBreakp
1oint(breakpoints, swiper.params.breakpointsBase, swiper.el);\n if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;\n const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;\n const breakpointParams = breakpointOnlyParams || swiper.originalParams;\n const wasMultiRow = isGridEnabled(swiper, params);\n const isMultiRow = isGridEnabled(swiper, breakpointParams);\n const wasEnabled = params.enabled;\n\n if (wasMultiRow && !isMultiRow) {\n $el.removeClass(`${params.containerModifierClass}grid ${params.containerModifierClass}grid-column`);\n swiper.emitContainerClasses();\n } else if (!wasMultiRow && isMultiRow) {\n $el.addClass(`${params.containerModifierClass}grid`);\n\n if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {\n $el.addClass(`${params.containerModifierClass}grid-column`);\n }\n\n swiper.emitContainerClasses();\n } // Toggle navigation, pagination, scrollbar\n\n\n ['navigation', 'pagination', 'scrollbar'].forEach(prop => {\n const wasModuleEnabled = params[prop] && params[prop].enabled;\n const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;\n\n if (wasModuleEnabled && !isModuleEnabled) {\n swiper[prop].disable();\n }\n\n if (!wasModuleEnabled && isModuleEnabled) {\n swiper[prop].enable();\n }\n });\n const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;\n const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);\n\n if (directionChanged && initialized) {\n swiper.changeDirection();\n }\n\n utils_extend(swiper.params, breakpointParams);\n const isEnabled = swiper.params.enabled;\n Object.assign(swiper, {\n allowTouchMove: swiper.params.allowTouchMove,\n allowSlideNext: swiper.params.allowSlideNext,\n allowSlidePrev: swiper.params.allowSlidePrev\n });\n\n if (wasEnabled && !isEnabled) {\n swiper.disable();\n } else if (!wasEnabled && isEnabled) {\n swiper.enable();\n }\n\n swiper.currentBreakpoint = breakpoint;\n swiper.emit('_beforeBreakpoint', breakpointParams);\n\n if (needsReLoop && initialized) {\n swiper.loopDestroy();\n swiper.loopCreate();\n swiper.updateSlides();\n swiper.slideTo(activeIndex - loopedSlides + swiper.loopedSlides, 0, false);\n }\n\n swiper.emit('breakpoint', breakpointParams);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/breakpoints/getBreakpoint.js\n\nfunction getBreakpoint(breakpoints, base = 'window', containerEl) {\n if (!breakpoints || base === 'container' && !containerEl) return undefined;\n let breakpoint = false;\n const window = ssr_window_esm_getWindow();\n const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;\n const points = Object.keys(breakpoints).map(point => {\n if (typeof point === 'string' && point.indexOf('@') === 0) {\n const minRatio = parseFloat(point.substr(1));\n const value = currentHeight * minRatio;\n return {\n value,\n point\n };\n }\n\n return {\n value: point,\n point\n };\n });\n points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));\n\n for (let i = 0; i < points.length; i += 1) {\n const {\n point,\n value\n } = points[i];\n\n if (base === 'window') {\n if (window.matchMedia(`(min-width: ${value}px)`).matches) {\n breakpoint = point;\n }\n } else if (value <= containerEl.clientWidth) {\n breakpoint = point;\n }\n }\n\n return breakpoint || 'max';\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/breakpoints/index.js\n\n\n/* harmony default export */ const breakpoints = ({\n setBreakpoint: setBreakpoint,\n getBreakpoint: getBreakpoint\n});\n;
1// CONCATENATED MODULE: ./node_modules/swiper/core/classes/addClasses.js\nfunction prepareClasses(entries, prefix) {\n const resultClasses = [];\n entries.forEach(item => {\n if (typeof item === 'object') {\n Object.keys(item).forEach(classNames => {\n if (item[classNames]) {\n resultClasses.push(prefix + classNames);\n }\n });\n } else if (typeof item === 'string') {\n resultClasses.push(prefix + item);\n }\n });\n return resultClasses;\n}\n\nfunction addClasses() {\n const swiper = this;\n const {\n classNames,\n params,\n rtl,\n $el,\n device,\n support\n } = swiper; // prettier-ignore\n\n const suffixes = prepareClasses(['initialized', params.direction, {\n 'pointer-events': !support.touch\n }, {\n 'free-mode': swiper.params.freeMode && params.freeMode.enabled\n }, {\n 'autoheight': params.autoHeight\n }, {\n 'rtl': rtl\n }, {\n 'grid': params.grid && params.grid.rows > 1\n }, {\n 'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'\n }, {\n 'android': device.android\n }, {\n 'ios': device.ios\n }, {\n 'css-mode': params.cssMode\n }, {\n 'centered': params.cssMode && params.centeredSlides\n }, {\n 'watch-progress': params.watchSlidesProgress\n }], params.containerModifierClass);\n classNames.push(...suffixes);\n $el.addClass([...classNames].join(' '));\n swiper.emitContainerClasses();\n}\n;
1// CONCATENATED MODULE: ./node_modules/swiper/core/classes/removeClasses.js\nfunction removeClasses() {\n const swiper = this;\n const {\n $el,\n classNames\n } = swiper;\n $el.removeClass(classNames.join(' '));\n swiper.emitContainerClasses();\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/classes/index.js\n\n\n/* harmony default export */ const classes = ({\n addClasses: addClasses,\n removeClasses: removeClasses\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/images/loadImage.js\n\n\nfunction loadImage(imageEl, src, srcset, sizes, checkForComplete, callback) {\n const window = ssr_window_esm_getWindow();\n let image;\n\n function onReady() {\n if (callback) callback();\n }\n\n const isPicture = dom(imageEl).parent('picture')[0];\n\n if (!isPicture && (!imageEl.complete || !checkForComplete)) {\n if (src) {\n image = new window.Image();\n image.onload = onReady;\n image.onerror = onReady;\n\n if (sizes) {\n image.sizes = sizes;\n }\n\n if (srcset) {\n image.srcset = srcset;\n }\n\n if (src) {\n image.src = src;\n }\n } else {\n onReady();\n }\n } else {\n // image already loaded...\n onReady();\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/images/preloadImages.js\nfunction preloadImages() {\n const swiper = this;\n swiper.imagesToLoad = swiper.$el.find('img');\n\n function onReady() {\n if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper.destroyed) return;\n if (swiper.imagesLoaded !== undefined) swiper.imagesLoaded += 1;\n\n if (swiper.imagesLoaded === swiper.imagesToLoad.length) {\n if (swiper.params.updateOnImagesReady) swiper.update();\n swiper.emit('imagesReady');\n }\n }\n\n for (let i = 0; i < swiper.imagesToLoad.length; i += 1) {\n const imageEl = swiper.imagesToLoad[i];\n swiper.loadImage(imageEl, imageEl.currentSrc || imageEl.getAttribute('src'), imageEl.srcset || imageEl.getAttribute('srcset'), imageEl.sizes || imageEl.getAttribute('sizes'), true, onReady);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/images/index.js\n\n\n/* harmony default export */ const core_images = ({\n loadImage: loadImage,\n preloadImages: preloadImages\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/check-overflow/index.js\nfunction checkOverflow() {\n const swiper = this;\n const {\n isLocked: wasLocked,\n params\n } = swiper;\n const {\n slidesOffsetBefore\n } = params;\n\n if (slidesOffsetBefore) {\n const lastSlideIndex = swiper.slides.length - 1;\n const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2;\n swiper.isLocked = swiper.size > lastSlideRightEdge;\n } else {\n swiper.isLocked = swiper.snapGrid.length === 1;\n }\n\n if (params.allowSlideNext === true) {\n swiper.allowSlideNext = !swiper.isLocked;\n }\n\n if (params.allowSlidePrev === true) {\n swiper.allowSlidePrev = !swiper.isLocked;\n }\n\n if (wasLocked && wasLocked !== swiper.isLocked) {\n swiper.isEnd = false;\n }\n\n if (wasLocked !== swiper.isLocked) {\n swiper.emit(swiper.isLocked ? 'lock' : 'unlock');\n }\n}\n\n/* harmony default export */ const check_overflow = ({\n checkOverflow\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/defaults.js\n/* harmony default export */ const defaults = ({\n init: true,\n direction: 'horizontal',\n touchEventsTarget: 'wrapper',\n initialSlide: 0,\n speed: 300,\n cssMode: false,\n updateOnWindowResize: true,\n resizeObserver: true,\n nested: false,\n createElements: false,\n enabled: true,\n focusableElements: 'input, select, option, textarea, button, video, label',\n // Overrides\n width: null,\n height: null,\n //\n preventInteractionOnTransition: false,\n // ssr\n userAgent: null,\n url: null,\n // To support iOS's swipe-to-go-back gesture (when being used in-app).\n edgeSwipeDetection: false,\n edgeSwipeThreshold: 20,\n // Autoheight\n autoHeight: false,\n // Set wrapper width\n setWrapperSize: false,\n // Virtual Translate\n virtualTranslate: false,\n // Effects\n effect: 'slide',\n // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n // Breakp
1oints\n breakpoints: undefined,\n breakpointsBase: 'window',\n // Slides grid\n spaceBetween: 0,\n slidesPerView: 1,\n slidesPerGroup: 1,\n slidesPerGroupSkip: 0,\n slidesPerGroupAuto: false,\n centeredSlides: false,\n centeredSlidesBounds: false,\n slidesOffsetBefore: 0,\n // in px\n slidesOffsetAfter: 0,\n // in px\n normalizeSlideIndex: true,\n centerInsufficientSlides: false,\n // Disable swiper and hide navigation when container not overflow\n watchOverflow: true,\n // Round length\n roundLengths: false,\n // Touches\n touchRatio: 1,\n touchAngle: 45,\n simulateTouch: true,\n shortSwipes: true,\n longSwipes: true,\n longSwipesRatio: 0.5,\n longSwipesMs: 300,\n followFinger: true,\n allowTouchMove: true,\n threshold: 0,\n touchMoveStopPropagation: false,\n touchStartPreventDefault: true,\n touchStartForcePreventDefault: false,\n touchReleaseOnEdges: false,\n // Unique Navigation Elements\n uniqueNavElements: true,\n // Resistance\n resistance: true,\n resistanceRatio: 0.85,\n // Progress\n watchSlidesProgress: false,\n // Cursor\n grabCursor: false,\n // Clicks\n preventClicks: true,\n preventClicksPropagation: true,\n slideToClickedSlide: false,\n // Images\n preloadImages: true,\n updateOnImagesReady: true,\n // loop\n loop: false,\n loopAdditionalSlides: 0,\n loopedSlides: null,\n loopedSlidesLimit: true,\n loopFillGroupWithBlank: false,\n loopPreventsSlide: true,\n // rewind\n rewind: false,\n // Swiping/no swiping\n allowSlidePrev: true,\n allowSlideNext: true,\n swipeHandler: null,\n // '.swipe-handler',\n noSwiping: true,\n noSwipingClass: 'swiper-no-swiping',\n noSwipingSelector: null,\n // Passive Listeners\n passiveListeners: true,\n maxBackfaceHiddenSlides: 10,\n // NS\n containerModifierClass: 'swiper-',\n // NEW\n slideClass: 'swiper-slide',\n slideBlankClass: 'swiper-slide-invisible-blank',\n slideActiveClass: 'swiper-slide-active',\n slideDuplicateActiveClass: 'swiper-slide-duplicate-active',\n slideVisibleClass: 'swiper-slide-visible',\n slideDuplicateClass: 'swiper-slide-duplicate',\n slideNextClass: 'swiper-slide-next',\n slideDuplicateNextClass: 'swiper-slide-duplicate-next',\n slidePrevClass: 'swiper-slide-prev',\n slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',\n wrapperClass: 'swiper-wrapper',\n // Callbacks\n runCallbacksOnInit: true,\n // Internals\n _emitClasses: false\n});\n;// CONCATENATED MODULE: ./node_modules/swiper/core/moduleExtendParams.js\n\nfunction moduleExtendParams(params, allModulesParams) {\n return function extendParams(obj = {}) {\n const moduleParamName = Object.keys(obj)[0];\n const moduleParams = obj[moduleParamName];\n\n if (typeof moduleParams !== 'object' || moduleParams === null) {\n utils_extend(allModulesParams, obj);\n return;\n }\n\n if (['navigation', 'pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] === true) {\n params[moduleParamName] = {\n auto: true\n };\n }\n\n if (!(moduleParamName in params && 'enabled' in moduleParams)) {\n utils_extend(allModulesParams, obj);\n return;\n }\n\n if (params[moduleParamName] === true) {\n params[moduleParamName] = {\n enabled: true\n };\n }\n\n if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {\n params[moduleParamName].enabled = true;\n }\n\n if (!params[moduleParamName]) params[moduleParamName] = {\n enabled: false\n };\n utils_extend(allModulesParams, obj);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/core/core.js\n/* eslint no-param-reassign: \"off\" */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst prototypes = {\n eventsEmitter: events_emitter,\n update: update,\n translate: translate,\n transition: core_transition,\n slide: slide,\n loop: loop,\n grabCursor: grab_cursor,\n events: core_events,\n breakpoints: breakpoints,\n checkOverflow: check_overflow,\n classes: classes,\n images: core_images\n};\nconst extendedDefaults = {};\n\nclass Swiper {\n constructor(...args) {\n let el;\n let params;
1\n\n if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {\n params = args[0];\n } else {\n [el, params] = args;\n }\n\n if (!params) params = {};\n params = utils_extend({}, params);\n if (el && !params.el) params.el = el;\n\n if (params.el && dom(params.el).length > 1) {\n const swipers = [];\n dom(params.el).each(containerEl => {\n const newParams = utils_extend({}, params, {\n el: containerEl\n });\n swipers.push(new Swiper(newParams));\n }); // eslint-disable-next-line no-constructor-return\n\n return swipers;\n } // Swiper Instance\n\n\n const swiper = this;\n swiper.__swiper__ = true;\n swiper.support = getSupport();\n swiper.device = getDevice({\n userAgent: params.userAgent\n });\n swiper.browser = getBrowser();\n swiper.eventsListeners = {};\n swiper.eventsAnyListeners = [];\n swiper.modules = [...swiper.__modules__];\n\n if (params.modules && Array.isArray(params.modules)) {\n swiper.modules.push(...params.modules);\n }\n\n const allModulesParams = {};\n swiper.modules.forEach(mod => {\n mod({\n swiper,\n extendParams: moduleExtendParams(params, allModulesParams),\n on: swiper.on.bind(swiper),\n once: swiper.once.bind(swiper),\n off: swiper.off.bind(swiper),\n emit: swiper.emit.bind(swiper)\n });\n }); // Extend defaults with modules params\n\n const swiperParams = utils_extend({}, defaults, allModulesParams); // Extend defaults with passed params\n\n swiper.params = utils_extend({}, swiperParams, extendedDefaults, params);\n swiper.originalParams = utils_extend({}, swiper.params);\n swiper.passedParams = utils_extend({}, params); // add event listeners\n\n if (swiper.params && swiper.params.on) {\n Object.keys(swiper.params.on).forEac
1h(eventName => {\n swiper.on(eventName, swiper.params.on[eventName]);\n });\n }\n\n if (swiper.params && swiper.params.onAny) {\n swiper.onAny(swiper.params.onAny);\n } // Save Dom lib\n\n\n swiper.$ = dom; // Extend Swiper\n\n Object.assign(swiper, {\n enabled: swiper.params.enabled,\n el,\n // Classes\n classNames: [],\n // Slides\n slides: dom(),\n slidesGrid: [],\n snapGrid: [],\n slidesSizesGrid: [],\n\n // isDirection\n isHorizontal() {\n return swiper.params.direction === 'horizontal';\n },\n\n isVertical() {\n return swiper.params.direction === 'vertical';\n },\n\n // Indexes\n activeIndex: 0,\n realIndex: 0,\n //\n isBeginning: true,\n isEnd: false,\n // Props\n translate: 0,\n previousTranslate: 0,\n progress: 0,\n velocity: 0,\n animating: false,\n // Locks\n allowSlideNext: swiper.params.allowSlideNext,\n allowSlidePrev: swiper.params.allowSlidePrev,\n // Touch Events\n touchEvents: function touchEvents() {\n const touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel'];\n const desktop = ['pointerdown', 'pointermove', 'pointerup'];\n swiper.touchEventsTouch = {\n start: touch[0],\n move: touch[1],\n end: touch[2],\n cancel: touch[3]\n };\n swiper.touchEventsDesktop = {\n start: desktop[0],\n move: desktop[1],\n end: desktop[2]\n };\n return swiper.support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop;\n }(),\n touchEventsData: {\n isTouched: undefined,\n isMoved: undefined,\n allowTouchCallbacks: undefined,\n touchStartTime: undefined,\n isScrolling: undefined,\n currentTranslate: undefined,\n startTranslate: undefined,\n allowThresholdMove: undefined,\n // Form elements to match\n focusableElements: swiper.params.focusableElements,\n // Last click time\n lastClickTime: now(),\n clickTimeout: undefined,\n // Velocities\n velocities: [],\n allowMomentumBounce: undefined,\n isTouchEvent: undefined,\n startMoving: undefined\n },\n // Clicks\n allowClick: true,\n // Touches\n allowTouchMove: swiper.params.allowTouchMove,\n touches: {\n startX: 0,\n startY: 0,\n currentX: 0,\n currentY: 0,\n diff: 0\n },\n // Images\n imagesToLoad: [],\n imagesLoaded: 0\n });\n swiper.emit('_swiper'); // Init\n\n if (swiper.params.init) {\n swiper.init();\n } // Return app instance\n // eslint-disable-next-line no-constructor-return\n\n\n return swiper;\n }\n\n enable() {\n const swiper = this;\n if (swiper.enabled) return;\n swiper.enabled = true;\n\n if (swiper.params.grabCursor) {\n swiper.setGrabCursor();\n }\n\n swiper.emit('enable');\n }\n\n disable() {\n const swiper = this;\n if (!swiper.enabled) return;\n swiper.enabled = false;\n\n if (swiper.params.grabCursor) {\n swiper.unsetGrabCursor();\n }\n\n swiper.emit('disable');\n }\n\n setProgress(progress, speed) {\n const swiper = this;\n progress = Math.min(Math.max(progress, 0), 1);\n const min = swiper.minTranslate();\n const max = swiper.maxTranslate();\n const current = (max - min) * progress + min;\n swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n\n emitContainerClasses() {\n const swiper = this;\n if (!swiper.params._emitClasses || !swiper.el) return;\n const cls = swiper.el.className.split(' ').filter(className => {\n return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;\n });\n swiper.emit('_containerClasses', cls.join(' '));\n }
1\n\n getSlideClasses(slideEl) {\n const swiper = this;\n if (swiper.destroyed) return '';\n return slideEl.className.split(' ').filter(className => {\n return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;\n }).join(' ');\n }\n\n emitSlidesClasses() {\n const swiper = this;\n if (!swiper.params._emitClasses || !swiper.el) return;\n const updates = [];\n swiper.slides.each(slideEl => {\n const classNames = swiper.getSlideClasses(slideEl);\n updates.push({\n slideEl,\n classNames\n });\n swiper.emit('_slideClass', slideEl, classNames);\n });\n swiper.emit('_slideClasses', updates);\n }\n\n slidesPerViewDynamic(view = 'current', exact = false) {\n const swiper = this;\n const {\n params,\n slides,\n slidesGrid,\n slidesSizesGrid,\n size: swiperSize,\n activeIndex\n } = swiper;\n let spv = 1;\n\n if (params.centeredSlides) {\n let slideSize = slides[activeIndex].swiperSlideSize;\n let breakLoop;\n\n for (let i = activeIndex + 1; i < slides.length; i += 1) {\n if (slides[i] && !breakLoop) {\n slideSize += slides[i].swiperSlideSize;\n spv += 1;\n if (slideSize > swiperSize) breakLoop = true;\n }\n }\n\n for (let i = activeIndex - 1; i >= 0; i -= 1) {\n if (slides[i] && !breakLoop) {\n slideSize += slides[i].swiperSlideSize;\n spv += 1;\n if (slideSize > swiperSize) breakLoop = true;\n }\n }\n } else {\n // eslint-disable-next-line\n if (view === 'current') {\n for (let i = activeIndex + 1; i < slides.length; i += 1) {\n const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;\n\n if (slideInView) {\n spv += 1;\n }\n }\n } else {\n // previous\n for (let i = activeIndex - 1; i >= 0; i -= 1) {\n const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;\n\n if (slideInView) {\n spv += 1;\n }\n }\n }\n }\n\n return spv;\n }\n\n update() {\n const swiper = this;\n if (!swiper || swiper.destroyed) return;\n const {\n snapGrid,\n params\n } = swiper; // Breakpoints\n\n if (params.breakpoints) {\n swiper.setBreakpoint();\n }\n\n swiper.updateSize();\n swiper.updateSlides();\n swiper.updateProgress();\n swiper.updateSlidesClasses();\n\n function setTranslate() {\n const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;\n const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());\n swiper.setTranslate(newTranslate);\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n\n let translated;\n\n if (swiper.params.freeMode && swiper.params.freeMode.enabled) {\n setTranslate();\n\n if (swiper.params.autoHeight) {\n swiper.updateAutoHeight();\n }\n } else {\n if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {\n translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);\n } else {\n translated = swiper.slideTo(swiper.activeIndex, 0, false, true);\n }\n\n if (!translated) {\n setTranslate();\n }\n }\n\n if (params.watchOverflow && snapGrid !== swiper.snapGrid) {\n swiper.checkOverflow();\n }\n\n swiper.emit('update');\n }\n\n changeDirection(newDirection, needUpdate = true) {\n const swiper = this;\n const currentDirection = swiper.params.direction;\n\n if (!newDirection) {\n // eslint-disable-next-line\n newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';\n }\n\n if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {\n return swiper;\n }\n\n swiper.$el.removeClass(`${swiper.params.containerModifierClass}${currentDirection}`).addClass(`${swiper.params.containerModifierClass}${newDirection}`);\n swiper.emitContainerClasses();\n swiper.params.direction = newDirection;\n swiper.slides.each(slideEl => {\n if (newDirection === 'vertical') {\n slideEl.style.width = '';\n } else {\n slideEl.style.height = '';\n }\n });\n swiper.emit('changeDirection');
1\n if (needUpdate) swiper.update();\n return swiper;\n }\n\n changeLanguageDirection(direction) {\n const swiper = this;\n if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return;\n swiper.rtl = direction === 'rtl';\n swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl;\n\n if (swiper.rtl) {\n swiper.$el.addClass(`${swiper.params.containerModifierClass}rtl`);\n swiper.el.dir = 'rtl';\n } else {\n swiper.$el.removeClass(`${swiper.params.containerModifierClass}rtl`);\n swiper.el.dir = 'ltr';\n }\n\n swiper.update();\n }\n\n mount(el) {\n const swiper = this;\n if (swiper.mounted) return true; // Find el\n\n const $el = dom(el || swiper.params.el);\n el = $el[0];\n\n if (!el) {\n return false;\n }\n\n el.swiper = swiper;\n\n const getWrapperSelector = () => {\n return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;\n };\n\n const getWrapper = () => {\n if (el && el.shadowRoot && el.shadowRoot.querySelector) {\n const res = dom(el.shadowRoot.querySelector(getWrapperSelector())); // Children needs to return slot items\n\n res.children = options => $el.children(options);\n\n return res;\n }\n\n if (!$el.children) {\n return dom($el).children(getWrapperSelector());\n }\n\n return $el.children(getWrapperSelector());\n }; // Find Wrapper\n\n\n let $wrapperEl = getWrapper();\n\n if ($wrapperEl.length === 0 && swiper.params.createElements) {\n const document = getDocument();\n const wrapper = document.createElement('div');\n $wrapperEl = dom(wrapper);\n wrapper.className = swiper.params.wrapperClass;\n $el.append(wrapper);\n $el.children(`.${swiper.params.slideClass}`).each(slideEl => {\n $wrapperEl.append(slideEl);\n });\n }\n\n Object.assign(swiper, {\n $el,\n el,\n $wrapperEl,\n wrapperEl: $wrapperEl[0],\n mounted: true,\n // RTL\n rtl: el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl',\n rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),\n wrongRTL: $wrapperEl.css('display') === '-webkit-box'\n });\n return true;\n }\n\n init(el) {\n const swiper = this;\n if (swiper.initialized) return swiper;\n const mounted = swiper.mount(el);\n if (mounted === false) return swiper;\n swiper.emit('beforeInit'); // Set breakpoint\n\n if (swiper.params.breakpoints) {\n swiper.setBreakpoint();\n } // Add Classes\n\n\n swiper.addClasses(); // Create loop\n\n if (swiper.params.loop) {\n swiper.loopCreate();\n } // Update size\n\n\n swiper.updateSize(); // Update slides\n\n swiper.updateSlides();\n\n if (swiper.params.watchOverflow) {\n swiper.checkOverflow();\n } // Set Grab Cursor\n\n\n if (swiper.params.grabCursor && swiper.enabled) {\n swiper.setGrabCursor();\n }\n\n if (swiper.params.preloadImages) {\n swiper.preloadImages();\n } // Slide To Initial Slide\n\n\n if (swiper.params.loop) {\n swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit, false, true);\n } else {\n swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);\n } // Attach events\n\n\n swiper.attachEvents(); // Init Flag\n\n swiper.initialized = true; // Emit\n\n swiper.emit('init');\n swiper.emit('afterInit');\n return swiper;\n }\n\n destroy(deleteInstance = true, cleanStyles = true) {\n const swiper = this;\n const {\n params,\n $el,\n $wrapperEl,\n slides\n } = swiper;\n\n if (typeof swiper.params === 'undefined' || swiper.destroyed) {\n return null;\n }\n\n swiper.emit('beforeDestroy'); // Init Flag\n\n swiper.initialized = false; // Detach events\n\n swiper.detachEvents(); // Destroy loop\n\n if (params.loop) {\n swiper.loopDestroy();\n } // Cleanup styles\n\n\n if (cleanStyles) {\n swiper.removeClasses();\n $el.removeAttr('style');\n $wrapperEl.removeAttr('style');\n\n if (slides && slides.length) {\n slides.removeClass([params.slideVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass].join(' ')).removeAttr('style').removeAttr('data-swiper-slide-index');\n }\n }\n\n swiper.emit('destroy');
1 // Detach emitter events\n\n Object.keys(swiper.eventsListeners).forEach(eventName => {\n swiper.off(eventName);\n });\n\n if (deleteInstance !== false) {\n swiper.$el[0].swiper = null;\n deleteProps(swiper);\n }\n\n swiper.destroyed = true;\n return null;\n }\n\n static extendDefaults(newDefaults) {\n utils_extend(extendedDefaults, newDefaults);\n }\n\n static get extendedDefaults() {\n return extendedDefaults;\n }\n\n static get defaults() {\n return defaults;\n }\n\n static installModule(mod) {\n if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];\n const modules = Swiper.prototype.__modules__;\n\n if (typeof mod === 'function' && modules.indexOf(mod) < 0) {\n modules.push(mod);\n }\n }\n\n static use(module) {\n if (Array.isArray(module)) {\n module.forEach(m => Swiper.installModule(m));\n return Swiper;\n }\n\n Swiper.installModule(module);\n return Swiper;\n }\n\n}\n\nObject.keys(prototypes).forEach(prototypeGroup => {\n Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {\n Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];\n });\n});\nSwiper.use([Resize, Observer]);\n/* harmony default export */ const core = (Swiper);\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/virtual/virtual.js\n\n\nfunction Virtual({\n swiper,\n extendParams,\n on,\n emit\n}) {\n extendParams({\n virtual: {\n enabled: false,\n slides: [],\n cache: true,\n renderSlide: null,\n renderExternal: null,\n renderExternalUpdate: true,\n addSlidesBefore: 0,\n addSlidesAfter: 0\n }\n });\n let cssModeTimeout;\n swiper.virtual = {\n cache: {},\n from: undefined,\n to: undefined,\n slides: [],\n offset: 0,\n slidesGrid: []\n };
1\n\n function renderSlide(slide, index) {\n const params = swiper.params.virtual;\n\n if (params.cache && swiper.virtual.cache[index]) {\n return swiper.virtual.cache[index];\n }\n\n const $slideEl = params.renderSlide ? dom(params.renderSlide.call(swiper, slide, index)) : dom(`<div class=\"${swiper.params.slideClass}\" data-swiper-slide-index=\"${index}\">${slide}</div>`);\n if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index);\n if (params.cache) swiper.virtual.cache[index] = $slideEl;\n return $slideEl;\n }\n\n function update(force) {\n const {\n slidesPerView,\n slidesPerGroup,\n centeredSlides\n } = swiper.params;\n const {\n addSlidesBefore,\n addSlidesAfter\n } = swiper.params.virtual;\n const {\n from: previousFrom,\n to: previousTo,\n slides,\n slidesGrid: previousSlidesGrid,\n offset: previousOffset\n } = swiper.virtual;\n\n if (!swiper.params.cssMode) {\n swiper.updateActiveIndex();\n }\n\n const activeIndex = swiper.activeIndex || 0;\n let offsetProp;\n if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top';\n let slidesAfter;\n let slidesBefore;\n\n if (centeredSlides) {\n slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;\n slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;\n } else {\n slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;\n slidesBefore = slidesPerGroup + addSlidesBefore;\n }\n\n const from = Math.max((activeIndex || 0) - slidesBefore, 0);\n const to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1);\n const offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);\n Object.assign(swiper.virtual, {\n from,\n to,\n offset,\n slidesGrid: swiper.slidesGrid\n });\n\n function onRendered() {\n swiper.updateSlides();\n swiper.updateProgress();\n swiper.updateSlidesClasses();\n\n if (swiper.lazy && swiper.params.lazy.enabled) {\n swiper.lazy.load();\n }\n\n emit('virtualUpdate');\n }\n\n if (previousFrom === from && previousTo === to && !force) {\n if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {\n swiper.slides.css(offsetProp, `${offset}px`);\n }\n\n swiper.updateProgress();\n emit('virtualUpdate');\n return;\n }\n\n if (swiper.params.virtual.renderExternal) {\n swiper.params.virtual.renderExternal.call(swiper, {\n offset,\n from,\n to,\n slides: function getSlides() {\n const slidesToRender = [];\n\n for (let i = from; i <= to; i += 1) {\n slidesToRender.push(slides[i]);\n }\n\n return slidesToRender;\n }()\n });\n\n if (swiper.params.virtual.renderExternalUpdate) {\n onRendered();\n } else {\n emit('virtualUpdate');\n }\n\n return;\n }\n\n const prependIndexes = [];\n const appendIndexes = [];\n\n if (force) {\n swiper.$wrapperEl.find(`.${swiper.params.slideClass}`).remove();\n } else {\n for (let i = previousFrom; i <= previousTo; i += 1) {\n if (i < from || i > to) {\n swiper.$wrapperEl.find(`.${swiper.params.slideClass}[data-swiper-slide-index=\"${i}\"]`).remove();\n }\n }\n }\n\n for (let i = 0; i < slides.length; i += 1) {\n if (i >= from && i <= to) {\n if (typeof previousTo === 'undefined' || force) {\n appendIndexes.push(i);\n } else {\n if (i > previousTo) appendIndexes.push(i);\n if (i < previousFrom) prependIndexes.push(i);\n }\n }\n }\n\n appendIndexes.forEach(index => {\n swiper.$wrapperEl.append(renderSlide(slides[index], index));\n });\n prependIndexes.sort((a, b) => b - a).forEach(index => {\n swiper.$wrapperEl.prepend(renderSlide(slides[index], index));\n });\n swiper.$wrapperEl.children('.swiper-slide').css(offsetProp, `${offset}px`);\n onRendered();\n }\n\n function appendSlide(slides) {\n if (typeof slides === 'object' && 'length' in slides) {\n for (let i = 0; i < slides.length; i += 1) {\n if (slides[i]) swiper.virtual.slides.push(slides[i]);\n }\n } else {\n swiper.virtual.slides.push(slides);\n }\n\n update(true);\n }\n\n function prependSlide(slides) {\n const activeIndex = swiper.activeIndex;\n let newActiveIndex = activeIndex + 1;\n let numberOfNewSlides = 1;\n\n if (Array.isArray(slides)) {\n for (let i = 0; i < slides.length; i += 1) {\n if (slides[i]) swiper.virtual.slides.unshift(slides[i]);\n }\n\n newActiveIndex = activeIndex + slides.length;\n numberOfNewSlides = slides.length;\n } else {\n swiper.virtual.slides.unshift(slides);\n }\n\n if (swiper.params.virtual.cache) {\n const cache = swiper.virtual.cache;\n const newCache = {};\n Object.keys(cache).forEach(cachedIndex =>
1 {\n const $cachedEl = cache[cachedIndex];\n const cachedElIndex = $cachedEl.attr('data-swiper-slide-index');\n\n if (cachedElIndex) {\n $cachedEl.attr('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides);\n }\n\n newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = $cachedEl;\n });\n swiper.virtual.cache = newCache;\n }\n\n update(true);\n swiper.slideTo(newActiveIndex, 0);\n }\n\n function removeSlide(slidesIndexes) {\n if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;\n let activeIndex = swiper.activeIndex;\n\n if (Array.isArray(slidesIndexes)) {\n for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {\n swiper.virtual.slides.splice(slidesIndexes[i], 1);\n\n if (swiper.params.virtual.cache) {\n delete swiper.virtual.cache[slidesIndexes[i]];\n }\n\n if (slidesIndexes[i] < activeIndex) activeIndex -= 1;\n activeIndex = Math.max(activeIndex, 0);\n }\n } else {\n swiper.virtual.slides.splice(slidesIndexes, 1);\n\n if (swiper.params.virtual.cache) {\n delete swiper.virtual.cache[slidesIndexes];\n }\n\n if (slidesIndexes < activeIndex) activeIndex -= 1;\n activeIndex = Math.max(activeIndex, 0);\n }\n\n update(true);\n swiper.slideTo(activeIndex, 0);\n }\n\n function removeAllSlides() {\n swiper.virtual.slides = [];\n\n if (swiper.params.virtual.cache) {\n swiper.virtual.cache = {};\n }\n\n update(true);\n swiper.slideTo(0, 0);\n }\n\n on('beforeInit', () => {\n if (!swiper.params.virtual.enabled) return;\n swiper.virtual.slides = swiper.params.virtual.slides;\n swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);\n swiper.params.watchSlidesProgress = true;\n swiper.originalParams.watchSlidesProgress = true;\n\n if (!swiper.params.initialSlide) {\n update();\n }\n });\n on('setTranslate', () => {\n if (!swiper.params.virtual.enabled) return;\n\n if (swiper.params.cssMode && !swiper._immediateVirtual) {\n clearTimeout(cssModeTimeout);\n cssModeTimeout = setTimeout(() => {\n update();\n }, 100);\n } else {\n update();\n }\n });\n on('init update resize', () => {\n if (!swiper.params.virtual.enabled) return;\n\n if (swiper.params.cssMode) {\n setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`);\n }\n });\n Object.assign(swiper.virtual, {\n appendSlide,\n prependSlide,\n removeSlide,\n removeAllSlides,\n update\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/keyboard/keyboard.js\n/* eslint-disable consistent-return */\n\n\nfunction Keyboard({\n swiper,\n extendParams,\n on,\n emit\n}) {\n const document = getDocument();\n const window = ssr_window_esm_getWindow();\n swiper.keyboard = {\n enabled: false\n };\n extendParams({\n keyboard: {\n enabled: false,\n onlyInViewport: true,\n pageUpDown: true\n }\n });\n\n function handle(event) {\n if (!swiper.enabled) return;\n const {\n rtlTranslate: rtl\n } = swiper;\n let e = event;\n if (e.originalEvent) e = e.originalEvent; // jquery fix\n\n const kc = e.keyCode || e.charCode;\n const pageUpDown = swiper.params.keyboard.pageUpDown;\n const isPageUp = pageUpDown && kc === 33;\n const isPageDown = pageUpDown && kc === 34;\n const isArrowLeft = kc === 37;\n const isArrowRight = kc === 39;\n const isArrowUp = kc === 38;\n const isArrowDown = kc === 40; // Directions locks\n\n if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) {\n return false;\n }\n\n if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) {\n return false;\n }\n\n if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n return undefined;\n }\n\n if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {\n return undefined;\n }\n\n if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) {\n let inView = false; // Check that swiper should be inside of visible area of window\n\n if (swiper.$el.parents(`.${swiper.params.slideClass}`).length > 0 && swiper.$el.parents(`.${swiper.params.slideActiveClass}`).length === 0) {\n return undefined;\n }\n\n const $el = swiper.$el;\n const swiperWidth = $el[0].clientWidth;\n const swiperHeight = $el[0].clientHeight;\n const windowWidth = window.innerWidth;\n const windowHeight = window.innerHeight;\n const swiperOffset = swiper.$el.offset();\n if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft;\n const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiperWidth, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiperHeight], [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight]];\n\n for (let i = 0; i < swiperCoord.length; i += 1) {\n const point = swiperCoord[i];\n\n if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) {\n if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line\n\n inView = true;\n }\n }\n\n if (!inView) return undefined;\n }\n\n if (swiper.isHorizontal()) {\n if (isPageUp || isPageDown || isArrowLeft || isArrowRight) {\n if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n }\n\n if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext();\n if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev();\n } else {\n if (isPageUp || isPageDown || isArrowUp || isArrowDown) {\n if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n }\n\n if (isPageDown || isArrowDown) swiper.slideNext();\n if (isPageUp || isArrowUp) swiper.slidePrev();\n }\n\n emit('keyPress', kc);\n return undefined;\n }\n\n function enable() {\n if (swiper.keyboard.enabled) return;\n dom(document).on('keydown', handle);\n swiper.keyboard.enabled = true;\n }\n\n function disable() {\n if (!swiper.keyboard.enabled) return;\n dom(document).off('keydown', handle);\n swiper.keyboard.enabled = false;\n }\n\n on('init', () => {\n if (swiper.params.keyboard.enabled) {\n enable();\n }\n });\n on('destroy', () => {\n if (swiper.keyboard.enabled) {\n disable();\n }\n });\n Object.assign(swiper.keyboard, {\n enable,\n disable\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/mousewheel/mousewheel.js\n/* eslint-disable consistent-return */\n\n\n\nfunction Mousewheel({\n swiper,\n extendParams,\n on,\n emit\n}) {\n const window = ssr_window_esm_getWindow();\n extendParams({\n mousewheel: {\n enabled: false,\n releaseOnEdges: false,\n invert: false,\n forceToAxis: fal
1se,\n sensitivity: 1,\n eventsTarget: 'container',\n thresholdDelta: null,\n thresholdTime: null\n }\n });\n swiper.mousewheel = {\n enabled: false\n };\n let timeout;\n let lastScrollTime = now();\n let lastEventBeforeSnap;\n const recentWheelEvents = [];\n\n function normalize(e) {\n // Reasonable defaults\n const PIXEL_STEP = 10;\n const LINE_HEIGHT = 40;\n const PAGE_HEIGHT = 800;\n let sX = 0;\n let sY = 0; // spinX, spinY\n\n let pX = 0;\n let pY = 0; // pixelX, pixelY\n // Legacy\n\n if ('detail' in e) {\n sY = e.detail;\n }\n\n if ('wheelDelta' in e) {\n sY = -e.wheelDelta / 120;\n }\n\n if ('wheelDeltaY' in e) {\n sY = -e.wheelDeltaY / 120;\n }\n\n if ('wheelDeltaX' in e) {\n sX = -e.wheelDeltaX / 120;\n } // side scrolling on FF with DOMMouseScroll\n\n\n if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {\n sX = sY;\n sY = 0;\n }\n\n pX = sX * PIXEL_STEP;\n pY = sY * PIXEL_STEP;\n\n if ('deltaY' in e) {\n pY = e.deltaY;\n }\n\n if ('deltaX' in e) {\n pX = e.deltaX;\n }\n\n if (e.shiftKey && !pX) {\n // if user scrolls with shift he wants horizontal scroll\n pX = pY;\n pY = 0;\n }\n\n if ((pX || pY) && e.deltaMode) {\n if (e.deltaMode === 1) {\n // delta in LINE units\n pX *= LINE_HEIGHT;\n pY *= LINE_HEIGHT;\n } else {\n // delta in PAGE units\n pX *= PAGE_HEIGHT;\n pY *= PAGE_HEIGHT;\n }\n } // Fall-back if spin cannot be determined\n\n\n if (pX && !sX) {\n sX = pX < 1 ? -1 : 1;\n }\n\n if (pY && !sY) {\n sY = pY < 1 ? -1 : 1;\n }\n\n return {\n spinX: sX,\n spinY: sY,\n pixelX: pX,\n pixelY: pY\n };\n }\n\n function handleMouseEnter() {\n if (!swiper.enabled) return;\n swiper.mouseEntered = true;\n }\n\n function handleMouseLeave() {\n if (!swiper.enabled) return;\n swiper.mouseEntered = false;\n }\n\n function animateSlider(newEvent) {\n if (swiper.params.mousewheel.thresholdDelta && newEvent.delta < swiper.params.mousewheel.thresholdDelta) {\n // Prevent if delta of wheel scroll delta is below configured threshold\n return false;\n }\n\n if (swiper.params.mousewheel.thresholdTime && now() - lastScrollTime < swiper.params.mousewheel.thresholdTime) {\n // Prevent if time between scrolls is below configured threshold\n return false;\n } // If the movement is NOT big enough and\n // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):\n // Don't go any further (avoid insignificant scroll movement).\n\n\n if (newEvent.delta >= 6 && now() - lastScrollTime < 60) {\n // Return false as a default\n return true;\n } // If user is scrolling towards the end:\n // If the slider hasn't hit the latest slide or\n // if the slider is a loop and\n // if the slider isn't moving right now:\n // Go to next slide and\n // emit a scroll event.\n // Else (the user is scrolling towards the beginning) and\n // if the slider hasn't hit the first slide or\n // if the slider is a loop and\n // if the slider isn't moving right now:\n // Go to prev slide and\n // emit a scroll event.\n\n\n if (newEvent.direction < 0) {\n if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {\n swiper.slideNext();\n emit('scroll', newEvent.raw);\n }\n } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {\n swiper.slidePrev();\n emit('scroll', newEvent.raw);\n } // If you got here is because an animation has been triggered so store the current time\n\n\n lastScrollTime = new window.Date().getTime(); // Return false as a default\n\n return false;\n }\n\n function releaseScroll(newEvent) {\n const params = swiper.params.mousewheel;\n\n if (newEvent.direction < 0) {\n if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {\n // Return true to animate scroll on edges\n return true;\n }\n } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {\n // Return true to animate scroll on edges\n return true;\n }\n\n return false;\n }\n\n function handle(event) {\n let e = event;\n let disableParentSwiper = true;\n if (!swiper.enabled) return;\n const params = swiper.params.mousewheel;\n\n if (swiper.params.cssMode) {\n e.preventDefault();\n }\n\n let target = swiper.$el;\n\n if (swiper.params.mousewheel.eventsTarget !== 'container') {\n target = dom(swiper.params.mousewheel.eventsTarget);\n }\n\n if (!swiper.mouseEntered && !target[0].contains(e.target) && !params.releaseOnEdges) return true;\n if (e.originalEvent) e = e.originalEvent; // jquery fix\n\n let delta = 0;\n const rtlFactor = swiper.rtlTranslate ? -1 : 1;\n const data = normalize(e);\n\n if (params.forceToAxis) {\n if (swiper.isHorizontal()) {\n if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;else return true;\n } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;else return true;\n } else {\n delta = Math.abs(data.pixelX) >
1 Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;\n }\n\n if (delta === 0) return true;\n if (params.invert) delta = -delta; // Get the scroll positions\n\n let positions = swiper.getTranslate() + delta * params.sensitivity;\n if (positions >= swiper.minTranslate()) positions = swiper.minTranslate();\n if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate(); // When loop is true:\n // the disableParentSwiper will be true.\n // When loop is false:\n // if the scroll positions is not on edge,\n // then the disableParentSwiper will be true.\n // if the scroll on edge positions,\n // then the disableParentSwiper will be false.\n\n disableParentSwiper = swiper.params.loop ? true : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate());\n if (disableParentSwiper && swiper.params.nested) e.stopPropagation();\n\n if (!swiper.params.freeMode || !swiper.params.freeMode.enabled) {\n // Register the new event in a variable which stores the relevant data\n const newEvent = {\n time: now(),\n delta: Math.abs(delta),\n direction: Math.sign(delta),\n raw: event\n }; // Keep the most recent events\n\n if (recentWheelEvents.length >= 2) {\n recentWheelEvents.shift(); // only store the last N events\n }\n\n const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;\n recentWheelEvents.push(newEvent); // If there is at least one previous recorded event:\n // If direction has changed or\n // if the scroll is quicker than the previous one:\n // Animate the slider.\n // Else (this is the first time the wheel is moved):\n // Animate the slider.\n\n if (prevEvent) {\n if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {\n animateSlider(newEvent);\n }\n } else {\n animateSlider(newEvent);\n } // If it's time to release the scroll:\n // Return now so you don't hit the preventDefault.\n\n\n if (releaseScroll(newEvent)) {\n return true;\n }\n } else {\n // Freemode or scrollContainer:\n // If we recently snapped after a momentum scroll, then ignore wheel events\n // to give time for the deceleration to finish. Stop ignoring after 500 msecs\n // or if it's a new scroll (larger delta or inverse sign as last event before\n // an end-of-momentum snap).\n const newEvent = {\n time: now(),\n delta: Math.abs(delta),\n direction: Math.sign(delta)\n };\n const ignoreWheelEvents = lastEventBeforeSnap && newEvent.time < lastEventBeforeSnap.time + 500 && newEvent.delta <= lastEventBeforeSnap.delta && newEvent.direction === lastEventBeforeSnap.direction;\n\n if (!ignoreWheelEvents) {\n lastEventBeforeSnap = undefined;\n\n if (swiper.params.loop) {\n swiper.loopFix();\n }\n\n let position = swiper.getTranslate() + delta * params.sensitivity;\n const wasBeginning = swiper.isBeginning;\n const wasEnd = swiper.isEnd;\n if (position >= swiper.minTranslate()) position = swiper.minTranslate();\n if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();\n swiper.setTransition(0);\n swiper.setTranslate(position);\n swiper.updateProgress();\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n\n if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) {\n swiper.updateSlidesClasses();\n }\n\n if (swiper.params.freeMode.sticky) {\n // When wheel scrolling starts with sticky (aka snap) enabled, then detect\n // the end of a momentum scroll by storing recent (N=15?) wheel events.\n // 1. do all N events have decreasing or same (absolute value) delta?\n // 2. did all N events arrive in the last M (M=500?) msecs?\n // 3. does the earliest event have an (absolute value) delta that's\n // at least P (P=1?) larger than the most recent event's delta?\n // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?\n // If 1-4 are \"yes\" then we're near the end of a momentum scroll deceleration.\n // Snap immediately and ignore remaining wheel events in this scroll.\n // See comment above for \"remaining wheel events in this scroll\" determination.\n // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.\n clearTimeout(timeout);\n timeout = undefined;\n\n if (recentWheelEvents.length >= 15) {\n recentWheelEvents.shift(); // only store the last N events\n }\n\n const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;\n const firstEvent = recentWheelEvents[0];\n recentWheelEvents.push(newEvent);\n\n if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {\n // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.\n recentWheelEvents.splice(0);\n } else if (recentWheelEvents.length >= 15 && newEvent.time - firstEvent.time < 500 && firstEvent.delta - newEvent.delta >= 1 && newEvent.delta <= 6) {\n // We're at the end of the deceleration of a momentum scroll, so there's no need\n // to wait for more events. Snap ASAP on the next tick.\n // Also, because there's some remaining momentum we'll bias the snap in the\n // direction of the ongoing scroll because it's better UX for the scroll to snap\n // in the same direction as the scroll instead of reversing to snap. Therefore,\n // if it's already scrolled more than 20% in the current direction, keep going.\n const snapToThreshold = delta > 0 ? 0.8 : 0.2;\n lastEventBeforeSnap = newEvent;\n recentWheelEvents.splice(0);\n timeout = nextTick(() =>
1 {\n swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);\n }, 0); // no delay; move on next tick\n }\n\n if (!timeout) {\n // if we get here, then we haven't detected the end of a momentum scroll, so\n // we'll consider a scroll \"complete\" when there haven't been any wheel events\n // for 500ms.\n timeout = nextTick(() => {\n const snapToThreshold = 0.5;\n lastEventBeforeSnap = newEvent;\n recentWheelEvents.splice(0);\n swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);\n }, 500);\n }\n } // Emit event\n\n\n if (!ignoreWheelEvents) emit('scroll', e); // Stop autoplay\n\n if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop(); // Return page scroll on edge positions\n\n if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true;\n }\n }\n\n if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n return false;\n }\n\n function events(method) {\n let target = swiper.$el;\n\n if (swiper.params.mousewheel.eventsTarget !== 'container') {\n target = dom(swiper.params.mousewheel.eventsTarget);\n }\n\n target[method]('mouseenter', handleMouseEnter);\n target[method]('mouseleave', handleMouseLeave);\n target[method]('wheel', handle);\n }\n\n function enable() {\n if (swiper.params.cssMode) {\n swiper.wrapperEl.removeEventListener('wheel', handle);\n return true;\n }\n\n if (swiper.mousewheel.enabled) return false;\n events('on');\n swiper.mousewheel.enabled = true;\n return true;\n }\n\n function disable() {\n if (swiper.params.cssMode) {\n swiper.wrapperEl.addEventListener(event, handle);\n return true;\n }\n\n if (!swiper.mousewheel.enabled) return false;\n events('off');\n swiper.mousewheel.enabled = false;\n return true;\n }\n\n on('init', () => {\n if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {\n disable();\n }\n\n if (swiper.params.mousewheel.enabled) enable();\n });\n on('destroy', () => {\n if (swiper.params.cssMode) {\n enable();\n }\n\n if (swiper.mousewheel.enabled) disable();\n });\n Object.assign(swiper.mousewheel, {\n enable,\n disable\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/create-element-if-not-defined.js\n\nfunction createElementIfNotDefined(swiper, originalParams, params, checkProps) {\
1n const document = getDocument();\n\n if (swiper.params.createElements) {\n Object.keys(checkProps).forEach(key => {\n if (!params[key] && params.auto === true) {\n let element = swiper.$el.children(`.${checkProps[key]}`)[0];\n\n if (!element) {\n element = document.createElement('div');\n element.className = checkProps[key];\n swiper.$el.append(element);\n }\n\n params[key] = element;\n originalParams[key] = element;\n }\n });\n }\n\n return params;\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/navigation/navigation.js\n\n\nfunction Navigation({\n swiper,\n extendParams,\n on,\n emit\n}) {\n extendParams({\n navigation: {\n nextEl: null,\n prevEl: null,\n hideOnClick: false,\n disabledClass: 'swiper-button-disabled',\n hiddenClass: 'swiper-button-hidden',\n lockClass: 'swiper-button-lock',\n navigationDisabledClass: 'swiper-navigation-disabled'\n }\n });\n swiper.navigation = {\n nextEl: null,\n $nextEl: null,\n prevEl: null,\n $prevEl: null\n };\n\n function getEl(el) {\n let $el;\n\n if (el) {\n $el = dom(el);\n\n if (swiper.params.uniqueNavElements && typeof el === 'string' && $el.length > 1 && swiper.$el.find(el).length === 1) {\n $el = swiper.$el.find(el);\n }\n }\n\n return $el;\n }\n\n function toggleEl($el, disabled) {\n const params = swiper.params.navigation;\n\n if ($el && $el.length > 0) {\n $el[disabled ? 'addClass' : 'removeClass'](params.disabledClass);\n if ($el[0] && $el[0].tagName === 'BUTTON') $el[0].disabled = disabled;\n\n if (swiper.params.watchOverflow && swiper.enabled) {\n $el[swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);\n }\n }\n }\n\n function update() {\n // Update Navigation Buttons\n if (swiper.params.loop) return;\n const {\n $nextEl,\n $prevEl\n } = swiper.navigation;\n toggleEl($prevEl, swiper.isBeginning && !swiper.params.rewind);\n toggleEl($nextEl, swiper.isEnd && !swiper.params.rewind);\n }\n\n function onPrevClick(e) {\n e.preventDefault();\n if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;\n swiper.slidePrev();\n emit('navigationPrev');\n }\n\n function onNextClick(e) {\n e.preventDefault();\n if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;\n swiper.slideNext();\n emit('navigationNext');\n }\n\n function init() {\n const params = swiper.params.navigation;\n swiper.params.navigation = createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, {\n nextEl: 'swiper-button-next',\n prevEl: 'swiper-button-prev'\n });\n if (!(params.nextEl || params.prevEl)) return;\n const $nextEl = getEl(params.nextEl);\n const $prevEl = getEl(params.prevEl);\n\n if ($nextEl && $nextEl.length > 0) {\n $nextEl.on('click', onNextClick);\n }\n\n if ($prevEl && $prevEl.length > 0) {\n $prevEl.on('click', onPrevClick);\n }\n\n Object.assign(swiper.navigation, {\n $nextEl,\n nextEl: $nextEl && $nextEl[0],\n $prevEl,\n prevEl: $prevEl && $prevEl[0]\n });\n\n if (!swiper.enabled) {\n if ($nextEl) $nextEl.addClass(params.lockClass);\n if ($prevEl) $prevEl.addClass(params.lockClass);\n }\n }\n\n function destroy() {\n const {\n $nextEl,\n $prevEl\n } = swiper.navigation;\n\n if ($nextEl && $nextEl.length) {\n $nextEl.off('click', onNextClick);\n $nextEl.removeClass(swiper.params.navigation.disabledClass);\n }\n\n if ($prevEl && $prevEl.length) {\n $prevEl.off('click', onPrevClick);\n $prevEl.removeClass(swiper.params.navigation.disabledClass);\n }\n }\n\n on('init', () => {\n if (swiper.params.navigation.enabled === false) {\n // eslint-disable-next-line\n disable();\n } else {\n init();\n update();\n }\n });\n on('toEdge fromEdge lock unlock', () => {\n update();\n });\n on('destroy', () => {\n destroy();\n });\n on('enable disable', () => {\n const {\n $nextEl,\n $prevEl\n } = swiper.navigation;\n\n if ($nextEl) {\n $nextEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);\n }\n\n if ($prevEl) {\n $prevEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);\n }\n });\n on('click', (_s, e) => {\n const {\n $nextEl,\n $prevEl\n } = swiper.navigation;\n const targetEl = e.target;\n\n if (swiper.params.navigation.hideOnClick && !dom(targetEl).is($prevEl) && !dom(targetEl).is($nextEl)) {\n if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;\n let isHidden;\n\n if ($nextEl) {\n isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass);\n } else if ($prevEl) {\n isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass);\n }\n\n if (isHidden === true) {\n emit('navigationShow');\n } else {\n emit('navigationHide');\n }\n\n if ($nextEl) {\n $nextEl.toggleClass(swiper.params.navigation.hiddenClass);\n }\n\n if ($prevEl) {\n $prevEl.toggleClass(swiper.params.navigation.hiddenClass);\n }\n }\n });\n\n const enable = () => {\n swiper.$el.removeClass(swiper.params.navigation.navigationDisabledClass);\n init();\n update();\n };\n\n const disable = () => {\n swiper.$el.addClass(swiper.params.navigation.navigationDisabledClass);\n destroy();\n };\n\n Object.assign(swiper.navigation, {\n enable,\n disable,\n update,\n init,\n destroy\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/classes-to-selector.js\nfunction classesToSelector(classes = '') {\n return `.${classes.trim().replace(/([\\.:!\\/])/g, '\\\\$1') // eslint-disable-line\n .replace(/ /g, '.')}`;\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/pagination/pagination.js\n\n\n\nfunction Pagination({\n swiper,\n extendParams,\n on,\n emit\n}) {\n const pfx = 'swiper-pagination';\n extendParams({\n pagination: {\n el: null,\n bulletElement: 'span',\n clickable: false,\n hideOnClick: false,\n renderBullet: null,\n renderProgressbar: null,\n renderFraction: null,\n renderCustom: null,\n progressbarOpposite: false,\n type: 'bullets',\n // 'bullets' or 'progressbar' or 'fraction' or 'custom'\n dynamicBullets: false,\n dynamicMainBullets: 1,\n formatFractionCurrent: number => number,\n formatFractionTotal: number => number,\n bulletClass: `${pfx}-bullet`,\n bulletActiveClass: `${pfx}-bullet-active`,\n modifierClass: `${pfx}-`,\n currentClass: `${pfx}-current`,\n totalClass: `${pfx}-total`,\n hiddenClass: `${pfx}-hidden`,\n progressbarFillClass: `${pfx}-progressbar-fill`,\n progressbarOppositeClass: `${pfx}-progressbar-opposite`,\n clickableClass: `${pfx}-clickable`,\n lockClass: `${pfx}-lock`,\n horizontalClass: `${pfx}-horizontal`,\n verticalClass: `${pfx}-vertical`,\n paginationDisabledClass: `${pfx}-disabled`\n }\n });\n swiper.pagination = {\n el: null,\n $el: null,\n bullets: []\n };\n let bulletSize;\n let dynamicBulletIndex = 0;\n\n function isPaginationDisabled() {\n return !swiper.params.pagination.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0;\n }\n\n function setSideBullets($bulletEl, position) {\n const {\n bulletActiveClass\n } = swiper.params.pagination;\n $bulletEl[position]().addClass(`${bulletActiveClass}-${position}`)[position]().addClass(`${bulletActiveClass}-${position}-${position}`);\n }
1\n\n function update() {\n // Render || Update Pagination bullets/items\n const rtl = swiper.rtl;\n const params = swiper.params.pagination;\n if (isPaginationDisabled()) return;\n const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;\n const $el = swiper.pagination.$el; // Current/Total\n\n let current;\n const total = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;\n\n if (swiper.params.loop) {\n current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup);\n\n if (current > slidesLength - 1 - swiper.loopedSlides * 2) {\n current -= slidesLength - swiper.loopedSlides * 2;\n }\n\n if (current > total - 1) current -= total;\n if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current;\n } else if (typeof swiper.snapIndex !== 'undefined') {\n current = swiper.snapIndex;\n } else {\n current = swiper.activeIndex || 0;\n } // Types\n\n\n if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {\n const bullets = swiper.pagination.bullets;\n let firstIndex;\n let lastIndex;\n let midIndex;\n\n if (params.dynamicBullets) {\n bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true);\n $el.css(swiper.isHorizontal() ? 'width' : 'height', `${bulletSize * (params.dynamicMainBullets + 4)}px`);\n\n if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {\n dynamicBulletIndex += current - (swiper.previousIndex - swiper.loopedSlides || 0);\n\n if (dynamicBulletIndex > params.dynamicMainBullets - 1) {\n dynamicBulletIndex = params.dynamicMainBullets - 1;\n } else if (dynamicBulletIndex < 0) {\n dynamicBulletIndex = 0;\n }\n }\n\n firstIndex = Math.max(current - dynamicBulletIndex, 0);\n lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);\n midIndex = (lastIndex + firstIndex) / 2;\n }\n\n bullets.removeClass(['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(suffix => `${params.bulletActiveClass}${suffix}`).join(' '));\n\n if ($el.length > 1) {\n bullets.each(bullet => {\n const $bullet = dom(bullet);\n const bulletIndex = $bullet.index();\n\n if (bulletIndex === current) {\n $bullet.addClass(params.bulletActiveClass);\n }\n\n if (params.dynamicBullets) {\n if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {\n $bullet.addClass(`${params.bulletActiveClass}-main`);\n }\n\n if (bulletIndex === firstIndex) {\n setSideBullets($bullet, 'prev');\n }\n\n if (bulletIndex === lastIndex) {\n setSideBullets($bullet, 'next');\n }\n }\n });\n } else {\n const $bullet = bullets.eq(current);\n const bulletIndex = $bullet.index();\n $bullet.addClass(params.bulletActiveClass);\n\n if (params.dynamicBullets) {\n const $firstDisplayedBullet = bullets.eq(firstIndex);\n const $lastDisplayedBullet = bullets.eq(lastIndex);\n\n for (let i = firstIndex; i <= lastIndex; i += 1) {\n bullets.eq(i).addClass(`${params.bulletActiveClass}-main`);\n }\n\n if (swiper.params.loop) {\n if (bulletIndex >= bullets.length) {\n for (let i = params.dynamicMainBullets; i >= 0; i -= 1) {\n bullets.eq(bullets.length - i).addClass(`${params.bulletActiveClass}-main`);\n }\n\n bullets.eq(bullets.length - params.dynamicMainBullets - 1).addClass(`${params.bulletActiveClass}-prev`);\n } else {\n setSideBullets($firstDisplayedBullet, 'prev');\n setSideBullets($lastDisplayedBullet, 'next');\n }\n } else {\n setSideBullets($firstDisplayedBullet, 'prev');\n setSideBullets($lastDisplayedBullet, 'next');\n }\n }\n }\n\n if (params.dynamicBullets) {\n const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);\n const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;\n const offsetProp = rtl ? 'right' : 'left';\n bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`);\n }\n }\n\n if (params.type === 'fraction') {\n $el.find(classesToSelector(params.currentClass)).text(params.formatFractionCurrent(current + 1));\n $el.find(classesToSelector(params.totalClass)).text(params.formatFractionTotal(total));\n }\n\n if (params.type === 'progressbar') {\n let progressbarDirection;\n\n if (params.progressbarOpposite) {\n progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';\n } else {\n progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';\n }\n\n const scale = (current + 1) / total;\n let scaleX = 1;\n let scaleY = 1;\n\n if (progressbarDirection === 'horizontal') {\n scaleX = scale;\n } else {\n scaleY = scale;\n }\n\n $el.find(classesToSelector(params.progressbarFillClass)).transform(`translate3d(0,
10,0) scaleX(${scaleX}) scaleY(${scaleY})`).transition(swiper.params.speed);\n }\n\n if (params.type === 'custom' && params.renderCustom) {\n $el.html(params.renderCustom(swiper, current + 1, total));\n emit('paginationRender', $el[0]);\n } else {\n emit('paginationUpdate', $el[0]);\n }\n\n if (swiper.params.watchOverflow && swiper.enabled) {\n $el[swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);\n }\n }\n\n function render() {\n // Render Container\n const params = swiper.params.pagination;\n if (isPaginationDisabled()) return;\n const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;\n const $el = swiper.pagination.$el;\n let paginationHTML = '';\n\n if (params.type === 'bullets') {\n let numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;\n\n if (swiper.params.freeMode && swiper.params.freeMode.enabled && !swiper.params.loop && numberOfBullets > slidesLength) {\n numberOfBullets = slidesLength;\n }\n\n for (let i = 0; i < numberOfBullets; i += 1) {\n if (params.renderBullet) {\n paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);\n } else {\n paginationHTML += `<${params.bulletElement} class=\"${params.bulletClass}\"></${params.bulletElement}>`;\n }\n }\n\n $el.html(paginationHTML);\n swiper.pagination.bullets = $el.find(classesToSelector(params.bulletClass));\n }\n\n if (params.type === 'fraction') {\n if (params.renderFraction) {\n paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);\n } else {\n paginationHTML = `<span class=\"${params.currentClass}\"></span>` + ' / ' + `<span class=\"${params.totalClass}\"></span>`;\n }\n\n $el.html(paginationHTML);\n }\n\n if (params.type === 'progressbar') {\n if (params.renderProgressbar) {\n paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);\n } else {\n paginationHTML = `<span class=\"${params.progressbarFillClass}\"></span>`;\n }\n\n $el.html(paginationHTML);\n }\n\n if (params.type !== 'custom') {\n emit('paginationRender', swiper.pagination.$el[0]);\n }\n }\n\n function init() {\n swiper.params.pagination = createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, {\n el: 'swiper-pagination'\n });\n const params = swiper.params.pagination;\n if (!params.el) return;\n let $el = dom(params.el);\n if ($el.length === 0) return;\n\n if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1) {\n $el = swiper.$el.find(params.el); // check if it belongs to another nested Swiper\n\n if ($el.length > 1) {\n $el = $el.filter(el => {\n if (dom(el).parents('.swiper')[0] !== swiper.el) return false;\n return true;\n });\n }\n }\n\n if (params.type === 'bullets' && params.clickable) {\n $el.addClass(params.clickableClass);\n }\n\n $el.addClass(params.modifierClass + params.type);\n $el.addClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);\n\n if (params.type === 'bullets' && params.dynamicBullets) {\n $el.addClass(`${params.modifierClass}${params.type}-dynamic`);\n dynamicBulletIndex = 0;\n\n if (params.dynamicMainBullets < 1) {\n params.dynamicMainBullets = 1;\n }\n }\n\n if (params.type === 'progressbar' && params.progressbarOpposite) {\n $el.addClass(params.progressbarOppositeClass);\n }\n\n if (params.clickable) {\n $el.on('click', classesToSelector(params.bulletClass), function onClick(e) {\n e.preventDefault();\n let index = dom(this).index() * swiper.params.slidesPerGroup;\n if (swiper.params.loop) index += swiper.loopedSlides;\n swiper.slideTo(index);\n });\n }
1\n\n Object.assign(swiper.pagination, {\n $el,\n el: $el[0]\n });\n\n if (!swiper.enabled) {\n $el.addClass(params.lockClass);\n }\n }\n\n function destroy() {\n const params = swiper.params.pagination;\n if (isPaginationDisabled()) return;\n const $el = swiper.pagination.$el;\n $el.removeClass(params.hiddenClass);\n $el.removeClass(params.modifierClass + params.type);\n $el.removeClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);\n if (swiper.pagination.bullets && swiper.pagination.bullets.removeClass) swiper.pagination.bullets.removeClass(params.bulletActiveClass);\n\n if (params.clickable) {\n $el.off('click', classesToSelector(params.bulletClass));\n }\n }\n\n on('init', () => {\n if (swiper.params.pagination.enabled === false) {\n // eslint-disable-next-line\n disable();\n } else {\n init();\n render();\n update();\n }\n });\n on('activeIndexChange', () => {\n if (swiper.params.loop) {\n update();\n } else if (typeof swiper.snapIndex === 'undefined') {\n update();\n }\n });\n on('snapIndexChange', () => {\n if (!swiper.params.loop) {\n update();\n }\n });\n on('slidesLengthChange', () => {\n if (swiper.params.loop) {\n render();\n update();\n }\n });\n on('snapGridLengthChange', () => {\n if (!swiper.params.loop) {\n render();\n update();\n }\n });\n on('destroy', () => {\n destroy();\n });\n on('enable disable', () => {\n const {\n $el\n } = swiper.pagination;\n\n if ($el) {\n $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.pagination.lockClass);\n }\n });\n on('lock unlock', () => {\n update();\n });\n on('click', (_s, e) => {\n const targetEl = e.target;\n const {\n $el\n } = swiper.pagination;\n\n if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && $el && $el.length > 0 && !dom(targetEl).hasClass(swiper.params.pagination.bulletClass)) {\n if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return;\n const isHidden = $el.hasClass(swiper.params.pagination.hiddenClass);\n\n if (isHidden === true) {\n emit('paginationShow');\n } else {\n emit('paginationHide');\n }\n\n $el.toggleClass(swiper.params.pagination.hiddenClass);\n }\n });\n\n const enable = () => {\n swiper.$el.removeClass(swiper.params.pagination.paginationDisabledClass);\n\n if (swiper.pagination.$el) {\n swiper.pagination.$el.removeClass(swiper.params.pagination.paginationDisabledClass);\n }\n\n init();\n render();\n update();\n };\n\n const disable = () => {\n swiper.$el.addClass(swiper.params.pagination.paginationDisabledClass);\n\n if (swiper.pagination.$el) {\n swiper.pagination.$el.addClass(swiper.params.pagination.paginationDisabledClass);\n }\n\n destroy();\n };\n\n Object.assign(swiper.pagination, {\n enable,\n disable,\n render,\n update,\n init,\n destroy\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/scrollbar/scrollbar.js\n\n\n\n\nfunction Scrollbar({\n swiper,\n extendParams,\n on,\n emit\n}) {\n const document = getDocument();\n let isTouched = false;\n let timeout = null;\n let dragTimeout = null;\n let dragStartPos;\n let dragSize;\n let trackSize;\n let divider;\n extendParams({\n scrollbar: {\n el: null,\n dragSize: 'auto',\n hide: false,\n draggable: false,\n snapOnRelease: true,\n lockClass: 'swiper-scrollbar-lock',\n dragClass: 'swiper-scrollbar-drag',\n scrollbarDisabledClass: 'swiper-scrollbar-disabled',\n horizontalClass: `swiper-scrollbar-horizontal`,\n verticalClass: `swiper-scrollbar-vertical`\n }\n });\n swiper.scrollbar = {\n el: null,\n dragEl: null,\n $el: null,\n $dragEl: null\n };\n\n function setTranslate() {\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;\n const {\n scrollbar,\n rtlTranslate: rtl,\n progress\n } = swiper;\n const {\n $dragEl,\n $el\n } = scrollbar;\n const params = swiper.params.scrollbar;\n let newSize = dragSize;\n let newPos = (trackSize - dragSize) * progress;\n\n if (rtl) {\n newPos = -newPos;\n\n if (newPos > 0) {\n newSize = dragSize - newPos;\n newPos = 0;\n } else if (-newPos + dragSize > trackSize) {\n newSize = trackSize + newPos;\n }\n } else if (newPos < 0) {\n newSize = dragSize + newPos;\n newPos = 0;\n } else if (newPos + dragSize > trackSize) {\n newSize = trackSize - newPos;\n }\n\n if (swiper.isHorizontal()) {\n $dragEl.transform(`translate3d(${newPos}px, 0, 0)`);\n $dragEl[0].style.width = `${newSize}px`;\n } else {\n $dragEl.transform(`translate3d(0px, ${newPos}px, 0)`);\n $dragEl[0].style.height = `${newSize}px`;\n }\n\n if (params.hide) {\n clearTimeout(timeout);\n $el[0].style.opacity = 1;\n timeout = setTimeout(() =>
1 {\n $el[0].style.opacity = 0;\n $el.transition(400);\n }, 1000);\n }\n }\n\n function setTransition(duration) {\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;\n swiper.scrollbar.$dragEl.transition(duration);\n }\n\n function updateSize() {\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;\n const {\n scrollbar\n } = swiper;\n const {\n $dragEl,\n $el\n } = scrollbar;\n $dragEl[0].style.width = '';\n $dragEl[0].style.height = '';\n trackSize = swiper.isHorizontal() ? $el[0].offsetWidth : $el[0].offsetHeight;\n divider = swiper.size / (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));\n\n if (swiper.params.scrollbar.dragSize === 'auto') {\n dragSize = trackSize * divider;\n } else {\n dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);\n }\n\n if (swiper.isHorizontal()) {\n $dragEl[0].style.width = `${dragSize}px`;\n } else {\n $dragEl[0].style.height = `${dragSize}px`;\n }\n\n if (divider >= 1) {\n $el[0].style.display = 'none';\n } else {\n $el[0].style.display = '';\n }\n\n if (swiper.params.scrollbar.hide) {\n $el[0].style.opacity = 0;\n }\n\n if (swiper.params.watchOverflow && swiper.enabled) {\n scrollbar.$el[swiper.isLocked ? 'addClass' : 'removeClass'](swiper.params.scrollbar.lockClass);\n }\n }\n\n function getPointerPosition(e) {\n if (swiper.isHorizontal()) {\n return e.type === 'touchstart' || e.type === 'touchmove' ? e.targetTouches[0].clientX : e.clientX;\n }\n\n return e.type === 'touchstart' || e.type === 'touchmove' ? e.targetTouches[0].clientY : e.clientY;\n }\n\n function setDragPosition(e) {\n const {\n scrollbar,\n rtlTranslate: rtl\n } = swiper;\n const {\n $el\n } = scrollbar;\n let positionRatio;\n positionRatio = (getPointerPosition(e) - $el.offset()[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize);\n positionRatio = Math.max(Math.min(positionRatio, 1), 0);\n\n if (rtl) {\n positionRatio = 1 - positionRatio;\n }\n\n const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;\n swiper.updateProgress(position);\n swiper.setTranslate(position);\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n\n function onDragStart(e) {\n const params = swiper.params.scrollbar;\n const {\n scrollbar,\n $wrapperEl\n } = swiper;\n const {\n $el,\n $dragEl\n } = scrollbar;\n isTouched = true;\n dragStartPos = e.target === $dragEl[0] || e.target === $dragEl ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null;\n e.preventDefault();\n e.stopPropagation();\n $wrapperEl.transition(100);\n $dragEl.transition(100);\n setDragPosition(e);\n clearTimeout(dragTimeout);\n $el.transition(0);\n\n if (params.hide) {\n $el.css('opacity', 1);\n }\n\n if (swiper.params.cssMode) {\n swiper.$wrapperEl.css('scroll-snap-type', 'none');\n }\n\n emit('scrollbarDragStart', e);\n }\n\n function onDragMove(e) {\n const {\n scrollbar,\n $wrapperEl\n } = swiper;\n const {\n $el,\n $dragEl\n } = scrollbar;\n if (!isTouched) return;\n if (e.preventDefault) e.preventDefault();else e.returnValue = false;\n setDragPosition(e);\n $wrapperEl.transition(0);\n $el.transition(0);\n $dragEl.transition(0);\n emit('scrollbarDragMove', e);\n }\n\n function onDragEnd(e) {\n const params = swiper.params.scrollbar;\n const {\n scrollbar,\n $wrapperEl\n } = swiper;\n const {\n $el\n } = scrollbar;\n if (!isTouched) return;\n isTouched = false;\n\n if (swiper.params.cssMode) {\n swiper.$wrapperEl.css('scroll-snap-type', '');\n $wrapperEl.transition('');\n }\n\n if (params.hide) {\n clearTimeout(dragTimeout);\n dragTimeout = nextTick(() =>
1 {\n $el.css('opacity', 0);\n $el.transition(400);\n }, 1000);\n }\n\n emit('scrollbarDragEnd', e);\n\n if (params.snapOnRelease) {\n swiper.slideToClosest();\n }\n }\n\n function events(method) {\n const {\n scrollbar,\n touchEventsTouch,\n touchEventsDesktop,\n params,\n support\n } = swiper;\n const $el = scrollbar.$el;\n if (!$el) return;\n const target = $el[0];\n const activeListener = support.passiveListener && params.passiveListeners ? {\n passive: false,\n capture: false\n } : false;\n const passiveListener = support.passiveListener && params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n if (!target) return;\n const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';\n\n if (!support.touch) {\n target[eventMethod](touchEventsDesktop.start, onDragStart, activeListener);\n document[eventMethod](touchEventsDesktop.move, onDragMove, activeListener);\n document[eventMethod](touchEventsDesktop.end, onDragEnd, passiveListener);\n } else {\n target[eventMethod](touchEventsTouch.start, onDragStart, activeListener);\n target[eventMethod](touchEventsTouch.move, onDragMove, activeListener);\n target[eventMethod](touchEventsTouch.end, onDragEnd, passiveListener);\n }\n }\n\n function enableDraggable() {\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;\n events('on');\n }\n\n function disableDraggable() {\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;\n events('off');\n }\n\n function init() {\n const {\n scrollbar,\n $el: $swiperEl\n } = swiper;\n swiper.params.scrollbar = createElementIfNotDefined(swiper, swiper.originalParams.scrollbar, swiper.params.scrollbar, {\n el: 'swiper-scrollbar'\n });\n const params = swiper.params.scrollbar;\n if (!params.el) return;\n let $el = dom(params.el);\n\n if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1 && $swiperEl.find(params.el).length === 1) {\n $el = $swiperEl.find(params.el);\n }\n\n $el.addClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);\n let $dragEl = $el.find(`.${swiper.params.scrollbar.dragClass}`);\n\n if ($dragEl.length === 0) {\n $dragEl = dom(`<div class=\"${swiper.params.scrollbar.dragClass}\"></div>`);\n $el.append($dragEl);\n }\n\n Object.assign(scrollbar, {\n $el,\n el: $el[0],\n $dragEl,\n dragEl: $dragEl[0]\n });\n\n if (params.draggable) {\n enableDraggable();\n }\n\n if ($el) {\n $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass);\n }\n }\n\n function destroy() {\n const params = swiper.params.scrollbar;\n const $el = swiper.scrollbar.$el;\n\n if ($el) {\n $el.removeClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);\n }\n\n disableDraggable();\n }\n\n on('init', () => {\n if (swiper.params.scrollbar.enabled === false) {\n // eslint-disable-next-line\n disable();\n } else {\n init();\n updateSize();\n setTranslate();\n }\n });\n on('update resize observerUpdate lock unlock', () => {\n updateSize();\n });\n on('setTranslate', () => {\n setTranslate();\n });\n on('setTransition', (_s, duration) => {\n setTransition(duration);\n });\n on('enable disable', () => {\n const {\n $el\n } = swiper.scrollbar;\n\n if ($el) {\n $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass);\n }\n });\n on('destroy', () => {\n destroy();\n });\n\n const enable = () => {\n swiper.$el.removeClass(swiper.params.scrollbar.scrollbarDisabledClass);\n\n if (swiper.scrollbar.$el) {\n swiper.scrollbar.$el.removeClass(swiper.params.scrollbar.scrollbarDisabledClass);\n }\n\n init();\n updateSize();\n setTranslate();\n };\n\n const disable = () => {\n swiper.$el.addClass(swiper.params.scrollbar.scrollbarDisabledClass);\n\n if (swiper.scrollbar.$el) {\n swiper.scrollbar.$el.addClass(swiper.params.scrollbar.scrollbarDisabledClass);\n }\n\n destroy();\n };\n\n Object.assign(swiper.scrollbar, {\n enable,\n disable,\n updateSize,\n setTranslate,\n init,\n destroy\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/parallax/parallax.js\n\nfunction Parallax({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n parallax: {\n enabled: false\n }\n });\n\n const setTransform = (el, progress) =>
1 {\n const {\n rtl\n } = swiper;\n const $el = dom(el);\n const rtlFactor = rtl ? -1 : 1;\n const p = $el.attr('data-swiper-parallax') || '0';\n let x = $el.attr('data-swiper-parallax-x');\n let y = $el.attr('data-swiper-parallax-y');\n const scale = $el.attr('data-swiper-parallax-scale');\n const opacity = $el.attr('data-swiper-parallax-opacity');\n\n if (x || y) {\n x = x || '0';\n y = y || '0';\n } else if (swiper.isHorizontal()) {\n x = p;\n y = '0';\n } else {\n y = p;\n x = '0';\n }\n\n if (x.indexOf('%') >= 0) {\n x = `${parseInt(x, 10) * progress * rtlFactor}%`;\n } else {\n x = `${x * progress * rtlFactor}px`;\n }\n\n if (y.indexOf('%') >= 0) {\n y = `${parseInt(y, 10) * progress}%`;\n } else {\n y = `${y * progress}px`;\n }\n\n if (typeof opacity !== 'undefined' && opacity !== null) {\n const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));\n $el[0].style.opacity = currentOpacity;\n }\n\n if (typeof scale === 'undefined' || scale === null) {\n $el.transform(`translate3d(${x}, ${y}, 0px)`);\n } else {\n const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));\n $el.transform(`translate3d(${x}, ${y}, 0px) scale(${currentScale})`);\n }\n };\n\n const setTranslate = () => {\n const {\n $el,\n slides,\n progress,\n snapGrid\n } = swiper;\n $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(el => {\n setTransform(el, progress);\n });\n slides.each((slideEl, slideIndex) => {\n let slideProgress = slideEl.progress;\n\n if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {\n slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);\n }\n\n slideProgress = Math.min(Math.max(slideProgress, -1), 1);\n dom(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(el => {\n setTransform(el, slideProgress);\n });\n });\n };\n\n const setTransition = (duration = swiper.params.speed) => {\n const {\n $el\n } = swiper;\n $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(parallaxEl => {\n const $parallaxEl = dom(parallaxEl);\n let parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration;\n if (duration === 0) parallaxDuration = 0;\n $parallaxEl.transition(parallaxDuration);\n });\n };\n\n on('beforeInit', () => {\n if (!swiper.params.parallax.enabled) return;\n swiper.params.watchSlidesProgress = true;\n swiper.originalParams.watchSlidesProgress = true;\n });\n on('init', () => {\n if (!swiper.params.parallax.enabled) return;\n setTranslate();\n });\n on('setTranslate', () => {\n if (!swiper.params.parallax.enabled) return;\n setTranslate();\n });\n on('setTransition', (_swiper, duration) => {\n if (!swiper.params.parallax.enabled) return;\n setTransition(duration);\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/zoom/zoom.js\n\n\n\nfunction Zoom({\n swiper,\n extendParams,\n on,\n emit\n}) {\n const window = ssr_window_esm_getWindow();\n extendParams({\n zoom: {\n enabled: false,\n maxRatio: 3,\n minRatio: 1,\n toggle: true,\n containerClass: 'swiper-zoom-container',\n zoomedSlideClass: 'swiper-slide-zoomed'\n }\n });\n swiper.zoom = {\n enabled: false\n };\n let currentScale = 1;\n let isScaling = false;\n let gesturesEnabled;\n let fakeGestureTouched;\n let fakeGestureMoved;\n const gesture = {\n $slideEl: undefined,\n slideWidth: undefined,\n slideHeight: undefined,\n $imageEl: undefined,\n $imageWrapEl: undefined,\n maxRatio: 3\n };\n const image = {\n isTouched: undefined,\n isMoved: undefined,\n currentX: undefined,\n currentY: undefined,\n minX: undefined,\n minY: undefined,\n maxX: undefined,\n maxY: undefined,\n width: undefined,\n height: undefined,\n startX: undefined,\n startY: undefined,\n touchesStart: {},\n touchesCurrent: {}\n };\n const velocity = {\n x: undefined,\n y: undefined,\n prevPositionX: undefined,\n prevPositionY: undefined,\n prevTime: undefined\n };\n let scale = 1;\n Object.defineProperty(swiper.zoom, 'scale', {\n get() {\n return scale;\n },\n\n set(value) {\n if (scale !== value) {\n const imageEl = gesture.$imageEl ? gesture.$imageEl[0] : undefined;\n const slideEl = gesture.$slideEl ? gesture.$slideEl[0] : undefined;\n emit('zoomChange', value, imageEl, slideEl);\n }\n\n scale = value;\n }\n\n });\n\n function getDistanceBetweenTouches(e) {\n if (e.targetTouches.length < 2) return 1;\n const x1 = e.targetTouches[0].pageX;\n const y1 = e.targetTouches[0].pageY;\n const x2 = e.targetTouches[1].pageX;\n const y2 = e.targetTouches[1].pageY;\n const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n return distance;\n } // Events\n\n\n function onGestureStart(e) {\n const support = swiper.support;\n const params = swiper.params.zoom;\n fakeGestureTouched = false;\n fakeGestureMoved = false;\n\n if (!support.gestures) {\n if (e.type !== 'touchstart' || e.type === 'touchstart' && e.targetTouches.length < 2) {\n return;\n }\n\n fakeGestureTouched = true;\n gesture.scaleStart = getDistanceBetweenTouches(e);\n }\n\n if (!gesture.$slideEl || !gesture.$slideEl.length) {\n gesture.$slideEl = dom(e.target).closest(`.${swiper.params.slideClass}`);\n if (gesture.$slideEl.length === 0) gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);\n gesture.$imageEl = gesture.$slideEl.find(`.${params.containerClass}`).eq(0).find('picture, img, svg, canvas, .swiper-zoom-target').eq(0);\n gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`);\n gesture.maxRatio = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;\n\n if (gesture.$imageWrapEl.length === 0) {\n gesture.$imageEl = undefined;\n return;\n }\n }\n\n if (gesture.$imageEl) {\n gesture.$imageEl.transition(0);\n }\n\n isScaling = true;\n }\n\n function onGestureChange(e) {\n const support = swiper.support;\n const params = swiper.params.zoom;\n const zoom = swiper.zoom;\n\n if (!support.gestures) {\n if (e.type !== 'touchmove' || e.type === 'touchmove' && e.targetTouches.length < 2) {\n return;\n }\n\n fakeGestureMoved = true;\n gesture.scaleMove = getDistanceBetweenTouches(e);\n }\n\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) {\n if (e.type === 'gesturechange') onGestureStart(e);\n return;\n }\n\n if (support.gestures) {\n zoom.scale = e.scale * currentScale;\n } else {\n zoom.scale = gesture.scaleMove / gesture.scaleStart * currentScale;\n }\n\n if (zoom.scale > gesture.maxRatio) {\n zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5;\n }\n\n if (zoom.scale < params.minRatio) {\n zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5;\n }
1\n\n gesture.$imageEl.transform(`translate3d(0,0,0) scale(${zoom.scale})`);\n }\n\n function onGestureEnd(e) {\n const device = swiper.device;\n const support = swiper.support;\n const params = swiper.params.zoom;\n const zoom = swiper.zoom;\n\n if (!support.gestures) {\n if (!fakeGestureTouched || !fakeGestureMoved) {\n return;\n }\n\n if (e.type !== 'touchend' || e.type === 'touchend' && e.changedTouches.length < 2 && !device.android) {\n return;\n }\n\n fakeGestureTouched = false;\n fakeGestureMoved = false;\n }\n\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);\n gesture.$imageEl.transition(swiper.params.speed).transform(`translate3d(0,0,0) scale(${zoom.scale})`);\n currentScale = zoom.scale;\n isScaling = false;\n if (zoom.scale === 1) gesture.$slideEl = undefined;\n }\n\n function onTouchStart(e) {\n const device = swiper.device;\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n if (image.isTouched) return;\n if (device.android && e.cancelable) e.preventDefault();\n image.isTouched = true;\n image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n }\n\n function onTouchMove(e) {\n const zoom = swiper.zoom;\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n swiper.allowClick = false;\n if (!image.isTouched || !gesture.$slideEl) return;\n\n if (!image.isMoved) {\n image.width = gesture.$imageEl[0].offsetWidth;\n image.height = gesture.$imageEl[0].offsetHeight;\n image.startX = getTranslate(gesture.$imageWrapEl[0], 'x') || 0;\n image.startY = getTranslate(gesture.$imageWrapEl[0], 'y') || 0;\n gesture.slideWidth = gesture.$slideEl[0].offsetWidth;\n gesture.slideHeight = gesture.$slideEl[0].offsetHeight;\n gesture.$imageWrapEl.transition(0);\n } // Define if we need image drag\n\n\n const scaledWidth = image.width * zoom.scale;\n const scaledHeight = image.height * zoom.scale;\n if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return;\n image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);\n image.maxX = -image.minX;\n image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);\n image.maxY = -image.minY;\n image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n\n if (!image.isMoved && !isScaling) {\n if (swiper.isHorizontal() && (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x || Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)) {\n image.isTouched = false;\n return;\n }\n\n if (!swiper.isHorizontal() && (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y || Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)) {\n image.isTouched = false;\n return;\n }\n }\n\n if (e.cancelable) {\n e.preventDefault();\n }\n\n e.stopPropagation();\n image.isMoved = true;\n image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX;\n image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY;\n\n if (image.currentX < image.minX) {\n image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8;\n }\n\n if (image.currentX > image.maxX) {\n image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8;\n }\n\n if (image.currentY < image.minY) {\n image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8;\n }\n\n if (image.currentY > image.maxY) {\n image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8;\n } // Velocity\n\n\n if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;\n if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;\n if (!velocity.prevTime) velocity.prevTime = Date.now();\n velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;\n velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;\n if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;\n if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;\n velocity.prevPositionX = image.touchesCurrent.x;\n velocity.prevPositionY = image.touchesCurrent.y;\n velocity.prevTime = Date.now();\n gesture.$imageWrapEl.transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`);\n }\n\n function onTouchEnd() {\n const zoom = swiper.zoom;\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;\n\n if (!image.isTouched || !image.isMoved) {\n image.isTouched = false;\n image.isMoved = false;\n return;\n }\n\n image.isTouched = false;\n image.isMoved = false;\n let momentumDurationX = 300;\n let momentumDurationY = 300;\n const momentumDistanceX = velocity.x * momentumDurationX;\n const newPositionX = image.currentX + momentumDistanceX;\n const momentumDistanceY = velocity.y * momentumDurationY;\n const newPositionY = image.currentY + momentumDistanceY; // Fix duration\n\n if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);\n if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);\n const momentumDuration = Math.max(momentumDurationX, momentumDurationY);\n image.currentX = newPositionX;\n image.currentY = newPositionY; // Define if we need image drag\n\n const scaledWidth = image.width * zoom.scale;\n const scaledHeight = image.height * zoom.scale;\n image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);\n image.maxX = -image.minX;\n image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);\n image.maxY = -image.minY;\n image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);\n image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);\n gesture.$imageWrapEl.transition(momentumDuration).transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`);\n }\n\n function onTransitionEnd() {\n const zoom = swiper.zoom;\n\n if (gesture.$slideEl && swiper.previousIndex !== swiper.activeIndex) {\n if (gesture.$imageEl) {\n gesture.$imageEl.transform('translate3d(0,
10,0) scale(1)');\n }\n\n if (gesture.$imageWrapEl) {\n gesture.$imageWrapEl.transform('translate3d(0,0,0)');\n }\n\n zoom.scale = 1;\n currentScale = 1;\n gesture.$slideEl = undefined;\n gesture.$imageEl = undefined;\n gesture.$imageWrapEl = undefined;\n }\n }\n\n function zoomIn(e) {\n const zoom = swiper.zoom;\n const params = swiper.params.zoom;\n\n if (!gesture.$slideEl) {\n if (e && e.target) {\n gesture.$slideEl = dom(e.target).closest(`.${swiper.params.slideClass}`);\n }\n\n if (!gesture.$slideEl) {\n if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {\n gesture.$slideEl = swiper.$wrapperEl.children(`.${swiper.params.slideActiveClass}`);\n } else {\n gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);\n }\n }\n\n gesture.$imageEl = gesture.$slideEl.find(`.${params.containerClass}`).eq(0).find('picture, img, svg, canvas, .swiper-zoom-target').eq(0);\n gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`);\n }\n\n if (!gesture.$imageEl || gesture.$imageEl.length === 0 || !gesture.$imageWrapEl || gesture.$imageWrapEl.length === 0) return;\n\n if (swiper.params.cssMode) {\n swiper.wrapperEl.style.overflow = 'hidden';\n swiper.wrapperEl.style.touchAction = 'none';\n }\n\n gesture.$slideEl.addClass(`${params.zoomedSlideClass}`);\n let touchX;\n let touchY;\n let offsetX;\n let offsetY;\n let diffX;\n let diffY;\n let translateX;\n let translateY;\n let imageWidth;\n let imageHeight;\n let scaledWidth;\n let scaledHeight;\n let translateMinX;\n let translateMinY;\n let translateMaxX;\n let translateMaxY;\n let slideWidth;\n let slideHeight;\n\n if (typeof image.touchesStart.x === 'undefined' && e) {\n touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;\n touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;\n } else {\n touchX = image.touchesStart.x;\n touchY = image.touchesStart.y;\n }\n\n zoom.scale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;\n currentScale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;\n\n if (e) {\n slideWidth = gesture.$slideEl[0].offsetWidth;\n slideHeight = gesture.$slideEl[0].offsetHeight;\n offsetX = gesture.$slideEl.offset().left + window.scrollX;\n offsetY = gesture.$slideEl.offset().top + window.scrollY;\n diffX = offsetX + slideWidth / 2 - touchX;\n diffY = offsetY + slideHeight / 2 - touchY;\n imageWidth = gesture.$imageEl[0].offsetWidth;\n imageHeight = gesture.$imageEl[0].offsetHeight;\n scaledWidth = imageWidth * zoom.scale;\n scaledHeight = imageHeight * zoom.scale;\n translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);\n translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);\n translateMaxX = -translateMinX;\n translateMaxY = -translateMinY;\n translateX = diffX * zoom.scale;\n translateY = diffY * zoom.scale;\n\n if (translateX < translateMinX) {\n translateX = translateMinX;\n }\n\n if (translateX > translateMaxX) {\n translateX = translateMaxX;\n }\n\n if (translateY < translateMinY) {\n translateY = translateMinY;\n }\n\n if (translateY > translateMaxY) {\n translateY = translateMaxY;\n }\n } else {\n translateX = 0;\n translateY = 0;\n }\n\n gesture.$imageWrapEl.transition(300).transform(`translate3d(${translateX}px, ${translateY}px,0)`);\n gesture.$imageEl.transition(300).transform(`translate3d(0,0,0) scale(${zoom.scale})`);\n }\n\n function zoomOut() {\n const zoom = swiper.zoom;\n const params = swiper.params.zoom;\n\n if (!gesture.$slideEl) {\n if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {\n gesture.$slideEl = swiper.$wrapperEl.children(`.${swiper.params.slideActiveClass}`);\n } else {\n gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);\n }\n\n gesture.$imageEl = gesture.$slideEl.find(`.${params.containerClass}`).eq(0).find('picture, img, svg, canvas, .swiper-zoom-target').eq(0);\n gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`);\n }\n\n if (!gesture.$imageEl || gesture.$imageEl.length === 0 || !gesture.$imageWrapEl || gesture.$imageWrapEl.length === 0) return;\n\n if (swiper.params.cssMode) {\n swiper.wrapperEl.style.overflow = '';\n swiper.wrapperEl.style.touchAction = '';\n }\n\n zoom.scale = 1;\n currentScale = 1;\n gesture.$imageWrapEl.transition(300).transform('translate3d(0,
10,0)');\n gesture.$imageEl.transition(300).transform('translate3d(0,0,0) scale(1)');\n gesture.$slideEl.removeClass(`${params.zoomedSlideClass}`);\n gesture.$slideEl = undefined;\n } // Toggle Zoom\n\n\n function zoomToggle(e) {\n const zoom = swiper.zoom;\n\n if (zoom.scale && zoom.scale !== 1) {\n // Zoom Out\n zoomOut();\n } else {\n // Zoom In\n zoomIn(e);\n }\n }\n\n function getListeners() {\n const support = swiper.support;\n const passiveListener = swiper.touchEvents.start === 'touchstart' && support.passiveListener && swiper.params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n const activeListenerWithCapture = support.passiveListener ? {\n passive: false,\n capture: true\n } : true;\n return {\n passiveListener,\n activeListenerWithCapture\n };\n }\n\n function getSlideSelector() {\n return `.${swiper.params.slideClass}`;\n }\n\n function toggleGestures(method) {\n const {\n passiveListener\n } = getListeners();\n const slideSelector = getSlideSelector();\n swiper.$wrapperEl[method]('gesturestart', slideSelector, onGestureStart, passiveListener);\n swiper.$wrapperEl[method]('gesturechange', slideSelector, onGestureChange, passiveListener);\n swiper.$wrapperEl[method]('gestureend', slideSelector, onGestureEnd, passiveListener);\n }\n\n function enableGestures() {\n if (gesturesEnabled) return;\n gesturesEnabled = true;\n toggleGestures('on');\n }\n\n function disableGestures() {\n if (!gesturesEnabled) return;\n gesturesEnabled = false;\n toggleGestures('off');\n } // Attach/Detach Events\n\n\n function enable() {\n const zoom = swiper.zoom;\n if (zoom.enabled) return;\n zoom.enabled = true;\n const support = swiper.support;\n const {\n passiveListener,\n activeListenerWithCapture\n } = getListeners();\n const slideSelector = getSlideSelector(); // Scale image\n\n if (support.gestures) {\n swiper.$wrapperEl.on(swiper.touchEvents.start, enableGestures, passiveListener);\n swiper.$wrapperEl.on(swiper.touchEvents.end, disableGestures, passiveListener);\n } else if (swiper.touchEvents.start === 'touchstart') {\n swiper.$wrapperEl.on(swiper.touchEvents.start, slideSelector, onGestureStart, passiveListener);\n swiper.$wrapperEl.on(swiper.touchEvents.move, slideSelector, onGestureChange, activeListenerWithCapture);\n swiper.$wrapperEl.on(swiper.touchEvents.end, slideSelector, onGestureEnd, passiveListener);\n\n if (swiper.touchEvents.cancel) {\n swiper.$wrapperEl.on(swiper.touchEvents.cancel, slideSelector, onGestureEnd, passiveListener);\n }\n } // Move image\n\n\n swiper.$wrapperEl.on(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, onTouchMove, activeListenerWithCapture);\n }\n\n function disable() {\n const zoom = swiper.zoom;\n if (!zoom.enabled) return;\n const support = swiper.support;\n zoom.enabled = false;\n const {\n passiveListener,\n activeListenerWithCapture\n } = getListeners();\n const slideSelector = getSlideSelector(); // Scale image\n\n if (support.gestures) {\n swiper.$wrapperEl.off(swiper.touchEvents.start, enableGestures, passiveListener);\n swiper.$wrapperEl.off(swiper.touchEvents.end, disableGestures, passiveListener);\n } else if (swiper.touchEvents.start === 'touchstart') {\n swiper.$wrapperEl.off(swiper.touchEvents.start, slideSelector, onGestureStart, passiveListener);\n swiper.$wrapperEl.off(swiper.touchEvents.move, slideSelector, onGestureChange, activeListenerWithCapture);\n swiper.$wrapperEl.off(swiper.touchEvents.end, slideSelector, onGestureEnd, passiveListener);\n\n if (swiper.touchEvents.cancel) {\n swiper.$wrapperEl.off(swiper.touchEvents.cancel, slideSelector, onGestureEnd, passiveListener);\n }\n } // Move image\n\n\n swiper.$wrapperEl.off(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, onTouchMove, activeListenerWithCapture);\n }\n\n on('init', () => {\n if (swiper.params.zoom.enabled) {\n enable();\n }\n });\n on('destroy', () => {\n disable();\n });\n on('touchStart', (_s, e) => {\n if (!swiper.zoom.enabled) return;\n onTouchStart(e);\n });\n on('touchEnd', (_s, e) => {\n if (!swiper.zoom.enabled) return;\n onTouchEnd(e);\n });\n on('doubleTap', (_s, e) => {\n if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {\n zoomToggle(e);\n }\n });\n on('transitionEnd', () => {\n if (swiper.zoom.enabled && swiper.params.zoom.enabled) {\n onTransitionEnd();\n }\n });\n on('slideChange', () => {\n if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {\n onTransitionEnd();\n }\n });\n Object.assign(swiper.zoom, {\n enable,\n disable,\n in: zoomIn,\n out: zoomOut,\n toggle: zoomToggle\
1n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/lazy/lazy.js\n\n\nfunction Lazy({\n swiper,\n extendParams,\n on,\n emit\n}) {\n extendParams({\n lazy: {\n checkInView: false,\n enabled: false,\n loadPrevNext: false,\n loadPrevNextAmount: 1,\n loadOnTransitionStart: false,\n scrollingElement: '',\n elementClass: 'swiper-lazy',\n loadingClass: 'swiper-lazy-loading',\n loadedClass: 'swiper-lazy-loaded',\n preloaderClass: 'swiper-lazy-preloader'\n }\n });\n swiper.lazy = {};\n let scrollHandlerAttached = false;\n let initialImageLoaded = false;\n\n function loadInSlide(index, loadInDuplicate = true) {\n const params = swiper.params.lazy;\n if (typeof index === 'undefined') return;\n if (swiper.slides.length === 0) return;\n const isVirtual = swiper.virtual && swiper.params.virtual.enabled;\n const $slideEl = isVirtual ? swiper.$wrapperEl.children(`.${swiper.params.slideClass}[data-swiper-slide-index=\"${index}\"]`) : swiper.slides.eq(index);\n const $images = $slideEl.find(`.${params.elementClass}:not(.${params.loadedClass}):not(.${params.loadingClass})`);\n\n if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) {\n $images.push($slideEl[0]);\n }\n\n if ($images.length === 0) return;\n $images.each(imageEl => {\n const $imageEl = dom(imageEl);\n $imageEl.addClass(params.loadingClass);\n const background = $imageEl.attr('data-background');\n const src = $imageEl.attr('data-src');\n const srcset = $imageEl.attr('data-srcset');\n const sizes = $imageEl.attr('data-sizes');\n const $pictureEl = $imageEl.parent('picture');\n swiper.loadImage($imageEl[0], src || background, srcset, sizes, false, () => {\n if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper && !swiper.params || swiper.destroyed) return;\n\n if (background) {\n $imageEl.css('background-image', `url(\"${background}\")`);\n $imageEl.removeAttr('data-background');\n } else {\n if (srcset) {\n $imageEl.attr('srcset', srcset);\n $imageEl.removeAttr('data-srcset');\n }\n\n if (sizes) {\n $imageEl.attr('sizes', sizes);\n $imageEl.removeAttr('data-sizes');\n }\n\n if ($pictureEl.length) {\n $pictureEl.children('source').each(sourceEl => {\n const $source = dom(sourceEl);\n\n if ($source.attr('data-srcset')) {\n $source.attr('srcset', $source.attr('data-srcset'));\n $source.removeAttr('data-srcset');\n }\n });\n }\n\n if (src) {\n $imageEl.attr('src', src);\n $imageEl.removeAttr('data-src');\n }\n }\n\n $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass);\n $slideEl.find(`.${params.preloaderClass}`).remove();\n\n if (swiper.params.loop && loadInDuplicate) {\n const slideOriginalIndex = $slideEl.attr('data-swiper-slide-index');\n\n if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) {\n const originalSlide = swiper.$wrapperEl.children(`[data-swiper-slide-index=\"${slideOriginalIndex}\"]:not(.${swiper.params.slideDuplicateClass})`);\n loadInSlide(originalSlide.index(), false);\n } else {\n const duplicatedSlide = swiper.$wrapperEl.children(`.${swiper.params.slideDuplicateClass}[data-swiper-slide-index=\"${slideOriginalIndex}\"]`);\n loadInSlide(duplicatedSlide.index(), false);\n }\n }\n\n emit('lazyImageReady', $slideEl[0], $imageEl[0]);\n\n if (swiper.params.autoHeight) {\n swiper.updateAutoHeight();\n }\n });\n emit('lazyImageLoad', $slideEl[0], $imageEl[0]);\n });\n }\n\n function load() {\n const {\n $wrapperEl,\n params: swiperParams,\n slides,\n activeIndex\n } = swiper;\n const isVirtual = swiper.virtual && swiperParams.virtual.enabled;\n const params = swiperParams.lazy;\n let slidesPerView = swiperParams.slidesPerView;\n\n if (slidesPerView === 'auto') {\n slidesPerView = 0;\n }\n\n function slideExist(index) {\n if (isVirtual) {\n if ($wrapperEl.children(`.${swiperParams.slideClass}[data-swiper-slide-index=\"${index}\"]`).length) {\n return true;\n }\n } else if (slides[index]) return true;\n\n return false;\n }\n\n function slideIndex(slideEl) {\n if (isVirtual) {\n return dom(slideEl).attr('data-swiper-slide-index');\n }\n\n return dom(slideEl).index();\n }\n\n if (!initialImageLoaded) initialImageLoaded = true;\n\n if (swiper.params.watchSlidesProgress) {\n $wrapperEl.children(`.${swiperParams.slideVisibleClass}`).each(slideEl => {\n const index = isVirtual ? dom(slideEl).attr('data-swiper-slide-index') : dom(slideEl).index();\n loadInSlide(index);\n });\n } else if (slidesPerView > 1) {\n for (let i = activeIndex; i < activeIndex + slidesPerView; i += 1) {\n if (slideExist(i)) loadInSlide(i);\n }\n } else {\n loadInSlide(activeIndex);\n }\n\n if (params.loadPrevNext) {\n if (slidesPerView > 1 || params.loadPrevNextAmount && params.loadPrevNextAmount > 1) {\n const amount = params.loadPrevNextAmount;
1\n const spv = Math.ceil(slidesPerView);\n const maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length);\n const minIndex = Math.max(activeIndex - Math.max(spv, amount), 0); // Next Slides\n\n for (let i = activeIndex + spv; i < maxIndex; i += 1) {\n if (slideExist(i)) loadInSlide(i);\n } // Prev Slides\n\n\n for (let i = minIndex; i < activeIndex; i += 1) {\n if (slideExist(i)) loadInSlide(i);\n }\n } else {\n const nextSlide = $wrapperEl.children(`.${swiperParams.slideNextClass}`);\n if (nextSlide.length > 0) loadInSlide(slideIndex(nextSlide));\n const prevSlide = $wrapperEl.children(`.${swiperParams.slidePrevClass}`);\n if (prevSlide.length > 0) loadInSlide(slideIndex(prevSlide));\n }\n }\n }\n\n function checkInViewOnLoad() {\n const window = ssr_window_esm_getWindow();\n if (!swiper || swiper.destroyed) return;\n const $scrollElement = swiper.params.lazy.scrollingElement ? dom(swiper.params.lazy.scrollingElement) : dom(window);\n const isWindow = $scrollElement[0] === window;\n const scrollElementWidth = isWindow ? window.innerWidth : $scrollElement[0].offsetWidth;\n const scrollElementHeight = isWindow ? window.innerHeight : $scrollElement[0].offsetHeight;\n const swiperOffset = swiper.$el.offset();\n const {\n rtlTranslate: rtl\n } = swiper;\n let inView = false;\n if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft;\n const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiper.width, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiper.height], [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height]];\n\n for (let i = 0; i < swiperCoord.length; i += 1) {\n const point = swiperCoord[i];\n\n if (point[0] >= 0 && point[0] <= scrollElementWidth && point[1] >= 0 && point[1] <= scrollElementHeight) {\n if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line\n\n inView = true;\n }\n }\n\n const passiveListener = swiper.touchEvents.start === 'touchstart' && swiper.support.passiveListener && swiper.params.passiveListeners ? {\n passive: true,\n capture: false\n } : false;\n\n if (inView) {\n load();\n $scrollElement.off('scroll', checkInViewOnLoad, passiveListener);\n } else if (!scrollHandlerAttached) {\n scrollHandlerAttached = true;\n $scrollElement.on('scroll', checkInViewOnLoad, passiveListener);\n }\n }\n\n on('beforeInit', () => {\n if (swiper.params.lazy.enabled && swiper.params.preloadImages) {\n swiper.params.preloadImages = false;\n }\n });\n on('init', () => {\n if (swiper.params.lazy.enabled) {\n if (swiper.params.lazy.checkInView) {\n checkInViewOnLoad();\n } else {\n load();\n }\n }\n });\n on('scroll', () => {\n if (swiper.params.freeMode && swiper.params.freeMode.enabled && !swiper.params.freeMode.sticky) {\n load();\n }\n });\n on('scrollbarDragMove resize _freeModeNoMomentumRelease', () => {\n if (swiper.params.lazy.enabled) {\n if (swiper.params.lazy.checkInView) {\n checkInViewOnLoad();\n } else {\n load();\n }\n }\n });\n on('transitionStart', () => {\n if (swiper.params.lazy.enabled) {\n if (swiper.params.lazy.loadOnTransitionStart || !swiper.params.lazy.loadOnTransitionStart && !initialImageLoaded) {\n if (swiper.params.lazy.checkInView) {\n checkInViewOnLoad();\n } else {\n load();\n }\n }\n }\n });\n on('transitionEnd', () => {\n if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) {\n if (swiper.params.lazy.checkInView) {\n checkInViewOnLoad();\n } else {\n load();\n }\n }\n });\n on('slideChange', () => {\n const {\n lazy,\n cssMode,\n watchSlidesProgress,\n touchReleaseOnEdges,\n resistanceRatio\n } = swiper.params;\n\n if (lazy.enabled && (cssMode || watchSlidesProgress && (touchReleaseOnEdges || resistanceRatio === 0))) {\n load();\n }\n });\n on('destroy', () => {\n if (!swiper.$el) return;\n swiper.$el.find(`.${swiper.params.lazy.loadingClass}`).removeClass(swiper.params.lazy.loadingClass);\n });\n Object.assign(swiper.lazy, {\n load,\n loadInSlide\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/controller/controller.js\n/* eslint no-bitwise: [\"error\", { \"allow\": [\">>\"] }] */\n\nfunction Controller({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n controller: {\n control: undefined,\n inverse: false,\n by: 'slide' // or 'container'\n\n }\n });\n swiper.controller = {\n control: undefined\n };\n\n function LinearSpline(x, y) {\n const binarySearch = function search() {\n let maxIndex;\n let minIndex;\n let guess;\n return (array, val) => {\n minIndex = -1;\n maxIndex = array.length;\n\n while (maxIndex - minIndex >
1 1) {\n guess = maxIndex + minIndex >> 1;\n\n if (array[guess] <= val) {\n minIndex = guess;\n } else {\n maxIndex = guess;\n }\n }\n\n return maxIndex;\n };\n }();\n\n this.x = x;\n this.y = y;\n this.lastIndex = x.length - 1; // Given an x value (x2), return the expected y2 value:\n // (x1,y1) is the known point before given value,\n // (x3,y3) is the known point after given value.\n\n let i1;\n let i3;\n\n this.interpolate = function interpolate(x2) {\n if (!x2) return 0; // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n\n i3 = binarySearch(this.x, x2);\n i1 = i3 - 1; // We have our indexes i1 & i3, so we can calculate already:\n // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n\n return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1];\n };\n\n return this;\n } // xxx: for now i will just save one spline function to to\n\n\n function getInterpolateFunction(c) {\n if (!swiper.controller.spline) {\n swiper.controller.spline = swiper.params.loop ? new LinearSpline(swiper.slidesGrid, c.slidesGrid) : new LinearSpline(swiper.snapGrid, c.snapGrid);\n }\n }\n\n function setTranslate(_t, byController) {\n const controlled = swiper.controller.control;\n let multiplier;\n let controlledTranslate;\n const Swiper = swiper.constructor;\n\n function setControlledTranslate(c) {\n // this will create an Interpolate function based on the snapGrids\n // x is the Grid of the scrolled scroller and y will be the controlled scroller\n // it makes sense to create this only once and recall it for the interpolation\n // the function does a lot of value caching for performance\n const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;\n\n if (swiper.params.controller.by === 'slide') {\n getInterpolateFunction(c); // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n // but it did not work out\n\n controlledTranslate = -swiper.controller.spline.interpolate(-translate);\n }\n\n if (!controlledTranslate || swiper.params.controller.by === 'container') {\n multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());\n controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate();\n }\n\n if (swiper.params.controller.inverse) {\n controlledTranslate = c.maxTranslate() - controlledTranslate;\n }\n\n c.updateProgress(controlledTranslate);\n c.setTranslate(controlledTranslate, swiper);\n c.updateActiveIndex();\n c.updateSlidesClasses();\n }\n\n if (Array.isArray(controlled)) {\n for (let i = 0; i < controlled.length; i += 1) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n setControlledTranslate(controlled[i]);\n }\n }\n } else if (controlled instanceof Swiper && byController !== controlled) {\n setControlledTranslate(controlled);\n }\n }\n\n function setTransition(duration, byController) {\n const Swiper = swiper.constructor;\n const controlled = swiper.controller.control;\n let i;\n\n function setControlledTransition(c) {\n c.setTransition(duration, swiper);\n\n if (duration !== 0) {\n c.transitionStart();\n\n if (c.params.autoHeight) {\n nextTick(() => {\n c.updateAutoHeight();\n });\n }\n\n c.$wrapperEl.transitionEnd(() => {\n if (!controlled) return;\n\n if (c.params.loop && swiper.params.controller.by === 'slide') {\n c.loopFix();\n }\n\n c.transitionEnd();\n });\n }\n }\n\n if (Array.isArray(controlled)) {\n for (i = 0; i < controlled.length; i += 1) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n setControlledTransition(controlled[i]);\n }\n }\n } else if (controlled instanceof Swiper && byController !== controlled) {\n setControlledTransition(controlled);\n }\n }\n\n function removeSpline() {\n if (!swiper.controller.control) return;\n\n if (swiper.controller.spline) {\n swiper.controller.spline = undefined;\n delete swiper.controller.spline;\n }\n }\n\n on('beforeInit', () => {\n swiper.controller.control = swiper.params.controller.control;\n });\n on('update', () => {\n removeSpline();\n });\n on('resize', () => {\n removeSpline();\n });\n on('observerUpdate', () => {\n removeSpline();\n });\n on('setTranslate', (_s, translate, byController) => {\n if (!swiper.controller.control) return;\n swiper.controller.setTranslate(translate, byController);\n });\n on('setTransition', (_s, duration, byController) => {\n if (!swiper.controller.control) return;\n swiper.controller.setTransition(duration, byController);\n });\n Object.assign(swiper.controller, {\n setTranslate,\n setTransition\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/a11y/a11y.js\n\n\nfunction A11y({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n a11y: {\n enabled: true,\n notificationClass: 'swiper-notification',\n prevSlideMessage: 'Previous slide',\n nextSlideMessage: 'Next slide',\n firstSlideMessage: 'This is the first slide',\n lastSlideMessage: 'This is the last slide',\n paginationBulletMessage: 'Go to slide {{index}}',\n slideLabelMessage: '{{index}} / {{slidesLength}}',\n containerMessage: null,\n containerRoleDescriptionMessage: null,\n itemRoleDescriptionMessage: null,\n slideRole: 'group',\n id: null\n }\n });
1\n swiper.a11y = {\n clicked: false\n };\n let liveRegion = null;\n\n function notify(message) {\n const notification = liveRegion;\n if (notification.length === 0) return;\n notification.html('');\n notification.html(message);\n }\n\n function getRandomNumber(size = 16) {\n const randomChar = () => Math.round(16 * Math.random()).toString(16);\n\n return 'x'.repeat(size).replace(/x/g, randomChar);\n }\n\n function makeElFocusable($el) {\n $el.attr('tabIndex', '0');\n }\n\n function makeElNotFocusable($el) {\n $el.attr('tabIndex', '-1');\n }\n\n function addElRole($el, role) {\n $el.attr('role', role);\n }\n\n function addElRoleDescription($el, description) {\n $el.attr('aria-roledescription', description);\n }\n\n function addElControls($el, controls) {\n $el.attr('aria-controls', controls);\n }\n\n function addElLabel($el, label) {\n $el.attr('aria-label', label);\n }\n\n function addElId($el, id) {\n $el.attr('id', id);\n }\n\n function addElLive($el, live) {\n $el.attr('aria-live', live);\n }\n\n function disableEl($el) {\n $el.attr('aria-disabled', true);\n }\n\n function enableEl($el) {\n $el.attr('aria-disabled', false);\n }\n\n function onEnterOrSpaceKey(e) {\n if (e.keyCode !== 13 && e.keyCode !== 32) return;\n const params = swiper.params.a11y;\n const $targetEl = dom(e.target);\n\n if (swiper.navigation && swiper.navigation.$nextEl && $targetEl.is(swiper.navigation.$nextEl)) {\n if (!(swiper.isEnd && !swiper.params.loop)) {\n swiper.slideNext();\n }\n\n if (swiper.isEnd) {\n notify(params.lastSlideMessage);\n } else {\n notify(params.nextSlideMessage);\n }\n }\n\n if (swiper.navigation && swiper.navigation.$prevEl && $targetEl.is(swiper.navigation.$prevEl)) {\n if (!(swiper.isBeginning && !swiper.params.loop)) {\n swiper.slidePrev();\n }\n\n if (swiper.isBeginning) {\n notify(params.firstSlideMessage);\n } else {\n notify(params.prevSlideMessage);\n }\n }\n\n if (swiper.pagination && $targetEl.is(classesToSelector(swiper.params.pagination.bulletClass))) {\n $targetEl[0].click();\n }\n }\n\n function updateNavigation() {\n if (swiper.params.loop || swiper.params.rewind || !swiper.navigation) return;\n const {\n $nextEl,\n $prevEl\n } = swiper.navigation;\n\n if ($prevEl && $prevEl.length > 0) {\n if (swiper.isBeginning) {\n disableEl($prevEl);\n makeElNotFocusable($prevEl);\n } else {\n enableEl($prevEl);\n makeElFocusable($prevEl);\n }\n }\n\n if ($nextEl && $nextEl.length > 0) {\n if (swiper.isEnd) {\n disableEl($nextEl);\n makeElNotFocusable($nextEl);\n } else {\n enableEl($nextEl);\n makeElFocusable($nextEl);\n }\n }\n }\n\n function hasPagination() {\n return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length;\n }\n\n function hasClickablePagination() {\n return hasPagination() && swiper.params.pagination.clickable;\n }\n\n function updatePagination() {\n const params = swiper.params.a11y;\n if (!hasPagination()) return;\n swiper.pagination.bullets.each(bulletEl => {\n const $bulletEl = dom(bulletEl);\n\n if (swiper.params.pagination.clickable) {\n makeElFocusable($bulletEl);\n\n if (!swiper.params.pagination.renderBullet) {\n addElRole($bulletEl, 'button');\n addElLabel($bulletEl, params.paginationBulletMessage.replace(/\\{\\{index\\}\\}/, $bulletEl.index() + 1));\n }\n }\n\n if ($bulletEl.is(`.${swiper.params.pagination.bulletActiveClass}`)) {\n $bulletEl.attr('aria-current', 'true');\n } else {\n $bulletEl.removeAttr('aria-current');\n }\n });\n }\n\n const initNavEl = ($el, wrapperId, message) => {\n makeElFocusable($el);\n\n if ($el[0].tagName !== 'BUTTON') {\n addElRole($el, 'button');\n $el.on('keydown', onEnterOrSpaceKey);\n }\n\n addElLabel($el, message);\n addElControls($el, wrapperId);\n };\n\n const handlePointerDown = () => {\n swiper.a11y.clicked = true;\n };\n\n const handlePointerUp = () => {\n requestAnimationFrame(() =>
1 {\n requestAnimationFrame(() => {\n if (!swiper.destroyed) {\n swiper.a11y.clicked = false;\n }\n });\n });\n };\n\n const handleFocus = e => {\n if (swiper.a11y.clicked) return;\n const slideEl = e.target.closest(`.${swiper.params.slideClass}`);\n if (!slideEl || !swiper.slides.includes(slideEl)) return;\n const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex;\n const isVisible = swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl);\n if (isActive || isVisible) return;\n if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return;\n\n if (swiper.isHorizontal()) {\n swiper.el.scrollLeft = 0;\n } else {\n swiper.el.scrollTop = 0;\n }\n\n swiper.slideTo(swiper.slides.indexOf(slideEl), 0);\n };\n\n const initSlides = () => {\n const params = swiper.params.a11y;\n\n if (params.itemRoleDescriptionMessage) {\n addElRoleDescription(dom(swiper.slides), params.itemRoleDescriptionMessage);\n }\n\n if (params.slideRole) {\n addElRole(dom(swiper.slides), params.slideRole);\n }\n\n const slidesLength = swiper.params.loop ? swiper.slides.filter(el => !el.classList.contains(swiper.params.slideDuplicateClass)).length : swiper.slides.length;\n\n if (params.slideLabelMessage) {\n swiper.slides.each((slideEl, index) => {\n const $slideEl = dom(slideEl);\n const slideIndex = swiper.params.loop ? parseInt($slideEl.attr('data-swiper-slide-index'), 10) : index;\n const ariaLabelMessage = params.slideLabelMessage.replace(/\\{\\{index\\}\\}/, slideIndex + 1).replace(/\\{\\{slidesLength\\}\\}/, slidesLength);\n addElLabel($slideEl, ariaLabelMessage);\n });\n }\n };\n\n const init = () => {\n const params = swiper.params.a11y;\n swiper.$el.append(liveRegion); // Container\n\n const $containerEl = swiper.$el;\n\n if (params.containerRoleDescriptionMessage) {\n addElRoleDescription($containerEl, params.containerRoleDescriptionMessage);\n }\n\n if (params.containerMessage) {\n addElLabel($containerEl, params.containerMessage);\n } // Wrapper\n\n\n const $wrapperEl = swiper.$wrapperEl;\n const wrapperId = params.id || $wrapperEl.attr('id') || `swiper-wrapper-${getRandomNumber(16)}`;\n const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite';\n addElId($wrapperEl, wrapperId);\n addElLive($wrapperEl, live); // Slide\n\n initSlides(); // Navigation\n\n let $nextEl;\n let $prevEl;\n\n if (swiper.navigation && swiper.navigation.$nextEl) {\n $nextEl = swiper.navigation.$nextEl;\n }\n\n if (swiper.navigation && swiper.navigation.$prevEl) {\n $prevEl = swiper.navigation.$prevEl;\n }\n\n if ($nextEl && $nextEl.length) {\n initNavEl($nextEl, wrapperId, params.nextSlideMessage);\n }\n\n if ($prevEl && $prevEl.length) {\n initNavEl($prevEl, wrapperId, params.prevSlideMessage);\n } // Pagination\n\n\n if (hasClickablePagination()) {\n swiper.pagination.$el.on('keydown', classesToSelector(swiper.params.pagination.bulletClass), onEnterOrSpaceKey);\n } // Tab focus\n\n\n swiper.$el.on('focus', handleFocus, true);\n swiper.$el.on('pointerdown', handlePointerDown, true);\n swiper.$el.on('pointerup', handlePointerUp, true);\n };\n\n function destroy() {\n if (liveRegion && liveRegion.length > 0) liveRegion.remove();\n let $nextEl;\n let $prevEl;\n\n if (swiper.navigation && swiper.navigation.$nextEl) {\n $nextEl = swiper.navigation.$nextEl;\n }\n\n if (swiper.navigation && swiper.navigation.$prevEl) {\n $prevEl = swiper.navigation.$prevEl;\n }\n\n if ($nextEl) {\n $nextEl.off('keydown', onEnterOrSpaceKey);\n }\n\n if ($prevEl) {\n $prevEl.off('keydown', onEnterOrSpaceKey);\n } // Pagination\n\n\n if (hasClickablePagination()) {\n swiper.pagination.$el.off('keydown', classesToSelector(swiper.params.pagination.bulletClass), onEnterOrSpaceKey);\n } // Tab focus\n\n\n swiper.$el.off('focus', handleFocus, true);\n swiper.$el.off('pointerdown', handlePointerDown, true);\n swiper.$el.off('pointerup', handlePointerUp, true);\n }\n\n on('beforeInit', () => {\n liveRegion = dom(`<span class=\"${swiper.params.a11y.notificationClass}\" aria-live=\"assertive\" aria-atomic=\"true\"></span>`);\n });\n on('afterInit', () => {\n if (!swiper.params.a11y.enabled) return;\n init();\n });\n on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => {\n if (!swiper.params.a11y.enabled) return;\n initSlides();\n });\n on('fromEdge toEdge afterInit lock unlock', () => {\n if (!swiper.params.a11y.enabled) return;\n updateNavigation();\n });\n on('paginationUpdate', () => {\n if (!swiper.params.a11y.enabled) return;\n updatePagination();\n });\n on('destroy', () => {\n if (!swiper.params.a11y.enabled) return;\n destroy();\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/history/history.js\n\nfunction History({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n history: {\n enabled: false,\n root: '',\n replaceState: false,\n key: 'slides',\n keepQuery: false\n }\n });\n let initialized = false;\n let paths = {};\n\n const slugify = text => {\n return text.toString().replace(/\\s+/g, '-').replace(/[^\\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, '');\n };\n\n const getPathValues = urlOverride => {\n const window = ssr_window_esm_getWindow();\n let location;\n\n if (urlOverride) {\n location = new URL(urlOverride);\n } else {\n location = window.location;\n }\n\n const pathArray = location.pathname.slice(1).split('/').filter(part => part !== '');\n const total = pathArray.length;
1\n const key = pathArray[total - 2];\n const value = pathArray[total - 1];\n return {\n key,\n value\n };\n };\n\n const setHistory = (key, index) => {\n const window = ssr_window_esm_getWindow();\n if (!initialized || !swiper.params.history.enabled) return;\n let location;\n\n if (swiper.params.url) {\n location = new URL(swiper.params.url);\n } else {\n location = window.location;\n }\n\n const slide = swiper.slides.eq(index);\n let value = slugify(slide.attr('data-history'));\n\n if (swiper.params.history.root.length > 0) {\n let root = swiper.params.history.root;\n if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1);\n value = `${root}/${key}/${value}`;\n } else if (!location.pathname.includes(key)) {\n value = `${key}/${value}`;\n }\n\n if (swiper.params.history.keepQuery) {\n value += location.search;\n }\n\n const currentState = window.history.state;\n\n if (currentState && currentState.value === value) {\n return;\n }\n\n if (swiper.params.history.replaceState) {\n window.history.replaceState({\n value\n }, null, value);\n } else {\n window.history.pushState({\n value\n }, null, value);\n }\n };\n\n const scrollToSlide = (speed, value, runCallbacks) => {\n if (value) {\n for (let i = 0, length = swiper.slides.length; i < length; i += 1) {\n const slide = swiper.slides.eq(i);\n const slideHistory = slugify(slide.attr('data-history'));\n\n if (slideHistory === value && !slide.hasClass(swiper.params.slideDuplicateClass)) {\n const index = slide.index();\n swiper.slideTo(index, speed, runCallbacks);\n }\n }\n } else {\n swiper.slideTo(0, speed, runCallbacks);\n }\n };\n\n const setHistoryPopState = () => {\n paths = getPathValues(swiper.params.url);\n scrollToSlide(swiper.params.speed, paths.value, false);\n };\n\n const init = () => {\n const window = ssr_window_esm_getWindow();\n if (!swiper.params.history) return;\n\n if (!window.history || !window.history.pushState) {\n swiper.params.history.enabled = false;\n swiper.params.hashNavigation.enabled = true;\n return;\n }\n\n initialized = true;\n paths = getPathValues(swiper.params.url);\n if (!paths.key && !paths.value) return;\n scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit);\n\n if (!swiper.params.history.replaceState) {\n window.addEventListener('popstate', setHistoryPopState);\n }\n };\n\n const destroy = () => {\n const window = ssr_window_esm_getWindow();\n\n if (!swiper.params.history.replaceState) {\n window.removeEventListener('popstate', setHistoryPopState);\n }\n };\n\n on('init', () => {\n if (swiper.params.history.enabled) {\n init();\n }\n });\n on('destroy', () => {\n if (swiper.params.history.enabled) {\n destroy();\n }\n });\n on('transitionEnd _freeModeNoMomentumRelease', () => {\n if (initialized) {\n setHistory(swiper.params.history.key, swiper.activeIndex);\n }\n });\n on('slideChange', () => {\n if (initialized && swiper.params.cssMode) {\n setHistory(swiper.params.history.key, swiper.activeIndex);\n }\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/hash-navigation/hash-navigation.js\n\n\nfunction HashNavigation({\n swiper,\n extendParams,\n emit,\n on\n}) {\n let initialized = false;\n const document = getDocument();\n const window = ssr_window_esm_getWindow();\n extendParams({\n hashNavigation: {\n enabled: false,\n replaceState: false,\n watchState: false\n }\n });\n\n const onHashChange = () => {\n emit('hashChange');\n const newHash = document.location.hash.replace('#', '');\n const activeSlideHash = swiper.slides.eq(swiper.activeIndex).attr('data-hash');\n\n if (newHash !== activeSlideHash) {\n const newIndex = swiper.$wrapperEl.children(`.${swiper.params.slideClass}[data-hash=\"${newHash}\"]`).index();\n if (typeof newIndex === 'undefined') return;\n swiper.slideTo(newIndex);\n }\n };\n\n const setHash = () => {\n if (!initialized || !swiper.params.hashNavigation.enabled) return;\n\n if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) {\n window.history.replaceState(null, null, `#${swiper.slides.eq(swiper.activeIndex).attr('data-hash')}` || '');\n emit('hashSet');\n } else {\n const slide = swiper.slides.eq(swiper.activeIndex);\n const hash = slide.attr('data-hash') || slide.attr('data-history');\n document.location.hash = hash || '';\n emit('hashSet');\n }\n };\n\n const init = () => {\n if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return;\n initialized = true;\n const hash = document.location.hash.replace('#', '');\n\n if (hash) {\n const speed = 0;\n\n for (let i = 0, length = swiper.slides.length; i < length; i += 1) {\n const slide = swiper.slides.eq(i);\n const slideHash = slide.attr('data-hash') || slide.attr('data-history');\n\n if (slideHash === hash && !slide.hasClass(swiper.params.slideDuplicateClass)) {\n const index = slide.index();\n swiper.slideTo(index, speed, swiper.params.runCallbacksOnInit, true);\n }\n }\n }\n\n if (swiper.params.hashNavigation.watchState) {\n dom(window).on('hashchange', onHashChange);\n }\n };\n\n const destroy = () => {\n if (swiper.params.hashNavigation.watchState) {\n dom(window).off('hashchange', onHashChange);\n }\n };\n\n on('init', () => {\n if (swiper.params.hashNavigation.enabled) {\n init();\n }\n });\n on('destroy', () => {\n if (swiper.params.hashNavigation.enabled) {\n destroy();\n }\n });\n on('transitionEnd _freeModeNoMomentumRelease', () => {\n if (initialized) {\n setHash();\n }\n });\n on('slideChange', () => {\n if (initialized && swiper.params.cssMode) {\n setHash();\n }\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/autoplay/autoplay.js\n/* eslint no-underscore-dangle: \"off\" */\n\n/* eslint no-u
1se-before-define: \"off\" */\n\n\nfunction Autoplay({\n swiper,\n extendParams,\n on,\n emit\n}) {\n let timeout;\n swiper.autoplay = {\n running: false,\n paused: false\n };\n extendParams({\n autoplay: {\n enabled: false,\n delay: 3000,\n waitForTransition: true,\n disableOnInteraction: true,\n stopOnLastSlide: false,\n reverseDirection: false,\n pauseOnMouseEnter: false\n }\n });\n\n function run() {\n if (!swiper.size) {\n swiper.autoplay.running = false;\n swiper.autoplay.paused = false;\n return;\n }\n\n const $activeSlideEl = swiper.slides.eq(swiper.activeIndex);\n let delay = swiper.params.autoplay.delay;\n\n if ($activeSlideEl.attr('data-swiper-autoplay')) {\n delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;\n }\n\n clearTimeout(timeout);\n timeout = nextTick(() => {\n let autoplayResult;\n\n if (swiper.params.autoplay.reverseDirection) {\n if (swiper.params.loop) {\n swiper.loopFix();\n autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);\n emit('autoplay');\n } else if (!swiper.isBeginning) {\n autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);\n emit('autoplay');\n } else if (!swiper.params.autoplay.stopOnLastSlide) {\n autoplayResult = swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);\n emit('autoplay');\n } else {\n stop();\n }\n } else if (swiper.params.loop) {\n swiper.loopFix();\n autoplayResult = swiper.slideNext(swiper.params.speed, true, true);\n emit('autoplay');\n } else if (!swiper.isEnd) {\n autoplayResult = swiper.slideNext(swiper.params.speed, true, true);\n emit('autoplay');\n } else if (!swiper.params.autoplay.stopOnLastSlide) {\n autoplayResult = swiper.slideTo(0, swiper.params.speed, true, true);\n emit('autoplay');\n } else {\n stop();\n }\n\n if (swiper.params.cssMode && swiper.autoplay.running) run();else if (autoplayResult === false) {\n run();\n }\n }, delay);\n }\n\n function start() {\n if (typeof timeout !== 'undefined') return false;\n if (swiper.autoplay.running) return false;\n swiper.autoplay.running = true;\n emit('autoplayStart');\n run();\n return true;\n }\n\n function stop() {\n if (!swiper.autoplay.running) return false;\n if (typeof timeout === 'undefined') return false;\n\n if (timeout) {\n clearTimeout(timeout);\n timeout = undefined;\n }\n\n swiper.autoplay.running = false;\n emit('autoplayStop');\n return true;\n }\n\n function pause(speed) {\n if (!swiper.autoplay.running) return;\n if (swiper.autoplay.paused) return;\n if (timeout) clearTimeout(timeout);\n swiper.autoplay.paused = true;\n\n if (speed === 0 || !swiper.params.autoplay.waitForTransition) {\n swiper.autoplay.paused = false;\n run();\n } else {\n ['transitionend', 'webkitTransitionEnd'].forEach(event => {\n swiper.$wrapperEl[0].addEventListener(event, onTransitionEnd);\n });\n }\n }\n\n function onVisibilityChange() {\n const document = getDocument();\n\n if (document.visibilityState === 'hidden' && swiper.autoplay.running) {\n pause();\n }\n\n if (document.visibilityState === 'visible' && swiper.autoplay.paused) {\n run();\n swiper.autoplay.paused = false;\n }\n }\n\n function onTransitionEnd(e) {\n if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;\n if (e.target !== swiper.$wrapperEl[0]) return;\n ['transitionend', 'webkitTransitionEnd'].forEach(event => {\n swiper.$wrapperEl[0].removeEventListener(event, onTransitionEnd);\n });\n swiper.autoplay.paused = false;\n\n if (!swiper.autoplay.running) {\n stop();\n } else {\n run();\n }\n }\n\n function onMouseEnter() {\n if (swiper.params.autoplay.disableOnInteraction) {\n stop();\n } else {\n emit('autoplayPause');\n pause();\n }\n\n ['transitionend', 'webkitTransitionEnd'].forEach(event => {\n swiper.$wrapperEl[0].removeEventListener(event, onTransitionEnd);\n });\n }\n\n function onMouseLeave() {\n if (swiper.params.autoplay.disableOnInteraction) {\n return;\n }\n\n swiper.autoplay.paused = false;\n emit('autoplayResume');\n run();\n }\n\n function attachMouseEvents() {\n if (swiper.params.autoplay.pauseOnMouseEnter) {\n swiper.$el.on('mouseenter', onMouseEnter);\n swiper.$el.on('mouseleave', onMouseLeave);\n }\n }\n\n function detachMouseEvents() {\n swiper.$el.off('mouseenter', onMouseEnter);\n swiper.$el.off('mouseleave', onMouseLeave);\n }\n\n on('init', () => {\n if (swiper.params.autoplay.enabled) {\n start();\n const document = getDocument();\n document.addEventListener('visibilitychange', onVisibilityChange);\n attachMouseEvents();\n }\n });\n on('beforeTransitionStart', (_s, speed, internal) => {\n if (swiper.autoplay.running) {\n if (internal || !swiper.params.autoplay.disableOnInteraction) {\n swiper.autoplay.pause(speed);\n } else {\n stop();\n }\n }\n });\n on('sliderFirstMove', () => {\n if (swiper.autoplay.running) {\n if (swiper.params.autoplay.disableOnInteraction) {\n stop();\n } else {\n pause();\n }\n }\n });\n on('touchEnd', () => {\n if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) {\n run();\n }\n });\n on('destroy', () => {\n detachMouseEvents();\n\n if (swiper.autoplay.running) {\n stop();\n }\n\n const document = getDocument();\n document.removeEventListener('visibilitychange', onVisibilityChange);\n });\n Object.assign(swiper.autoplay, {\n pause,\n run,\n start,\n stop\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/thumbs/thumbs.js\n\n\nfunction Thumb({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n thumbs: {\n swiper: null,\n multipleActiveThumbs: true,\n autoScrollOffset: 0,\n slideThumbActiveClass: 'swiper-slide-thumb-active',\n thumbsContainerClass: 'swiper-thumbs'\n }\n });\n let initialized = false;\n let swiperCreated = false;\n swiper.thumbs = {\n swiper: null\n };
1\n\n function onThumbClick() {\n const thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper || thumbsSwiper.destroyed) return;\n const clickedIndex = thumbsSwiper.clickedIndex;\n const clickedSlide = thumbsSwiper.clickedSlide;\n if (clickedSlide && dom(clickedSlide).hasClass(swiper.params.thumbs.slideThumbActiveClass)) return;\n if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;\n let slideToIndex;\n\n if (thumbsSwiper.params.loop) {\n slideToIndex = parseInt(dom(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10);\n } else {\n slideToIndex = clickedIndex;\n }\n\n if (swiper.params.loop) {\n let currentIndex = swiper.activeIndex;\n\n if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) {\n swiper.loopFix(); // eslint-disable-next-line\n\n swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;\n currentIndex = swiper.activeIndex;\n }\n\n const prevIndex = swiper.slides.eq(currentIndex).prevAll(`[data-swiper-slide-index=\"${slideToIndex}\"]`).eq(0).index();\n const nextIndex = swiper.slides.eq(currentIndex).nextAll(`[data-swiper-slide-index=\"${slideToIndex}\"]`).eq(0).index();\n if (typeof prevIndex === 'undefined') slideToIndex = nextIndex;else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex;else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex;else slideToIndex = prevIndex;\n }\n\n swiper.slideTo(slideToIndex);\n }\n\n function init() {\n const {\n thumbs: thumbsParams\n } = swiper.params;\n if (initialized) return false;\n initialized = true;\n const SwiperClass = swiper.constructor;\n\n if (thumbsParams.swiper instanceof SwiperClass) {\n swiper.thumbs.swiper = thumbsParams.swiper;\n Object.assign(swiper.thumbs.swiper.originalParams, {\n watchSlidesProgress: true,\n slideToClickedSlide: false\n });\n Object.assign(swiper.thumbs.swiper.params, {\n watchSlidesProgress: true,\n slideToClickedSlide: false\n });\n } else if (utils_isObject(thumbsParams.swiper)) {\n const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);\n Object.assign(thumbsSwiperParams, {\n watchSlidesProgress: true,\n slideToClickedSlide: false\n });\n swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);\n swiperCreated = true;\n }\n\n swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass);\n swiper.thumbs.swiper.on('tap', onThumbClick);\n return true;\n }\n\n function update(initial) {\n const thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper || thumbsSwiper.destroyed) return;\n const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView; // Activate thumbs\n\n let thumbsToActivate = 1;\n const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;\n\n if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {\n thumbsToActivate = swiper.params.slidesPerView;\n }\n\n if (!swiper.params.thumbs.multipleActiveThumbs) {\n thumbsToActivate = 1;\n }\n\n thumbsToActivate = Math.floor(thumbsToActivate);\n thumbsSwiper.slides.removeClass(thumbActiveClass);\n\n if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {\n for (let i = 0; i < thumbsToActivate; i += 1) {\n thumbsSwiper.$wrapperEl.children(`[data-swiper-slide-index=\"${swiper.realIndex + i}\"]`).addClass(thumbActiveClass);\n }\n } else {\n for (let i = 0; i < thumbsToActivate; i += 1) {\n thumbsSwiper.slides.eq(swiper.realIndex + i).addClass(thumbActiveClass);\n }\n }\n\n const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;\n const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;\n\n if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {\n let currentThumbsIndex = thumbsSwiper.activeIndex;\n let newThumbsIndex;\n let direction;\n\n if (thumbsSwiper.params.loop) {\n if (thumbsSwiper.slides.eq(currentThumbsIndex).hasClass(thumbsSwiper.params.slideDuplicateClass)) {\n thumbsSwiper.loopFix(); // eslint-disable-next-line\n\n thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft;\n currentThumbsIndex = thumbsSwiper.activeIndex;\n } // Find actual thumbs index to slide to\n\n\n const prevThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).prevAll(`[data-swiper-slide-index=\"${swiper.realIndex}\"]`).eq(0).index();\n const nextThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).nextAll(`[data-swiper-slide-index=\"${swiper.realIndex}\"]`).eq(0).index();\n\n if (typeof prevThumbsIndex === 'undefined') {\n newThumbsIndex = nextThumbsIndex;\n } else if (typeof nextThumbsIndex === 'undefined') {\n newThumbsIndex = prevThumbsIndex;\n } else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) {\n newThumbsIndex = thumbsSwiper.params.slidesPerGroup > 1 ? nextThumbsIndex : currentThumbsIndex;\n } else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) {\n newThumbsIndex = nextThumbsIndex;\n } else {\n newThumbsIndex = prevThumbsIndex;\n }\n\n direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';\n } else {\n newThumbsIndex = swiper.realIndex;\n direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';\n }\n\n if (useOffset) {\n newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;\n }\n\n if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {\n if (thumbsSwiper.params.centeredSlides) {\n if (newThumbsIndex > currentThumbsIndex) {\n newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;\n } else {\n newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;\n }\n } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) {// newThumbsIndex = newThumbsIndex - slidesPerView + 1;\n }\n\n thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);\n }\n }\n }\n\n on('beforeInit', () => {\n const {\n thumbs\n } = swiper.params;\n if (!thumbs || !thumbs.swiper) return;\n init();\n update(true);\n });\n on('slideChange update resize observerUpdate', () => {\n update();\n });\n on('setTransition', (_s, duration) =>
1 {\n const thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper || thumbsSwiper.destroyed) return;\n thumbsSwiper.setTransition(duration);\n });\n on('beforeDestroy', () => {\n const thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper || thumbsSwiper.destroyed) return;\n\n if (swiperCreated) {\n thumbsSwiper.destroy();\n }\n });\n Object.assign(swiper.thumbs, {\n init,\n update\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/free-mode/free-mode.js\n\nfunction freeMode({\n swiper,\n extendParams,\n emit,\n once\n}) {\n extendParams({\n freeMode: {\n enabled: false,\n momentum: true,\n momentumRatio: 1,\n momentumBounce: true,\n momentumBounceRatio: 1,\n momentumVelocityRatio: 1,\n sticky: false,\n minimumVelocity: 0.02\n }\n });\n\n function onTouchStart() {\n const translate = swiper.getTranslate();\n swiper.setTranslate(translate);\n swiper.setTransition(0);\n swiper.touchEventsData.velocities.length = 0;\n swiper.freeMode.onTouchEnd({\n currentPos: swiper.rtl ? swiper.translate : -swiper.translate\n });\n }\n\n function onTouchMove() {\n const {\n touchEventsData: data,\n touches\n } = swiper; // Velocity\n\n if (data.velocities.length === 0) {\n data.velocities.push({\n position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],\n time: data.touchStartTime\n });\n }\n\n data.velocities.push({\n position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],\n time: now()\n });\n }\n\n function onTouchEnd({\n currentPos\n }) {\n const {\n params,\n $wrapperEl,\n rtlTranslate: rtl,\n snapGrid,\n touchEventsData: data\n } = swiper; // Time diff\n\n const touchEndTime = now();\n const timeDiff = touchEndTime - data.touchStartTime;
1\n\n if (currentPos < -swiper.minTranslate()) {\n swiper.slideTo(swiper.activeIndex);\n return;\n }\n\n if (currentPos > -swiper.maxTranslate()) {\n if (swiper.slides.length < snapGrid.length) {\n swiper.slideTo(snapGrid.length - 1);\n } else {\n swiper.slideTo(swiper.slides.length - 1);\n }\n\n return;\n }\n\n if (params.freeMode.momentum) {\n if (data.velocities.length > 1) {\n const lastMoveEvent = data.velocities.pop();\n const velocityEvent = data.velocities.pop();\n const distance = lastMoveEvent.position - velocityEvent.position;\n const time = lastMoveEvent.time - velocityEvent.time;\n swiper.velocity = distance / time;\n swiper.velocity /= 2;\n\n if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {\n swiper.velocity = 0;\n } // this implies that the user stopped moving a finger then released.\n // There would be no events with distance zero, so the last event is stale.\n\n\n if (time > 150 || now() - lastMoveEvent.time > 300) {\n swiper.velocity = 0;\n }\n } else {\n swiper.velocity = 0;\n }\n\n swiper.velocity *= params.freeMode.momentumVelocityRatio;\n data.velocities.length = 0;\n let momentumDuration = 1000 * params.freeMode.momentumRatio;\n const momentumDistance = swiper.velocity * momentumDuration;\n let newPosition = swiper.translate + momentumDistance;\n if (rtl) newPosition = -newPosition;\n let doBounce = false;\n let afterBouncePosition;\n const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;\n let needsLoopFix;\n\n if (newPosition < swiper.maxTranslate()) {\n if (params.freeMode.momentumBounce) {\n if (newPosition + swiper.maxTranslate() < -bounceAmount) {\n newPosition = swiper.maxTranslate() - bounceAmount;\n }\n\n afterBouncePosition = swiper.maxTranslate();\n doBounce = true;\n data.allowMomentumBounce = true;\n } else {\n newPosition = swiper.maxTranslate();\n }\n\n if (params.loop && params.centeredSlides) needsLoopFix = true;\n } else if (newPosition > swiper.minTranslate()) {\n if (params.freeMode.momentumBounce) {\n if (newPosition - swiper.minTranslate() > bounceAmount) {\n newPosition = swiper.minTranslate() + bounceAmount;\n }\n\n afterBouncePosition = swiper.minTranslate();\n doBounce = true;\n data.allowMomentumBounce = true;\n } else {\n newPosition = swiper.minTranslate();\n }\n\n if (params.loop && params.centeredSlides) needsLoopFix = true;\n } else if (params.freeMode.sticky) {\n let nextSlide;\n\n for (let j = 0; j < snapGrid.length; j += 1) {\n if (snapGrid[j] > -newPosition) {\n nextSlide = j;\n break;\n }\n }\n\n if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {\n newPosition = snapGrid[nextSlide];\n } else {\n newPosition = snapGrid[nextSlide - 1];\n }\n\n newPosition = -newPosition;\n }\n\n if (needsLoopFix) {\n once('transitionEnd', () => {\n swiper.loopFix();\n });\n } // Fix duration\n\n\n if (swiper.velocity !== 0) {\n if (rtl) {\n momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);\n } else {\n momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);\n }\n\n if (params.freeMode.sticky) {\n // If freeMode.sticky is active and the user ends a swipe with a slow-velocity\n // event, then durations can be 20+ seconds to slide one (or zero!) slides.\n // It's easy to see this when simulating touch with mouse events. To fix this,\n // limit single-slide swipes to the default slide duration. This also has the\n // nice side effect of matching slide speed if the user stopped moving before\n // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.\n // For faster swipes, also apply limits (albeit higher ones).\n const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);\n const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];\n\n if (moveDistance < currentSlideSize) {\n momentumDuration = params.speed;\n } else if (moveDistance < 2 * currentSlideSize) {\n momentumDuration = params.speed * 1.5;\n } else {\n momentumDuration = params.speed * 2.5;\n }\n }\n } else if (params.freeMode.sticky) {\n swiper.slideToClosest();\n return;\n }\n\n if (params.freeMode.momentumBounce && doBounce) {\n swiper.updateProgress(afterBouncePosition);\n swiper.setTransition(momentumDuration);\n swiper.setTranslate(newPosition);\n swiper.transitionStart(true, swiper.swipeDirection);\n swiper.animating = true;\n $wrapperEl.transitionEnd(() =>
1 {\n if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;\n emit('momentumBounce');\n swiper.setTransition(params.speed);\n setTimeout(() => {\n swiper.setTranslate(afterBouncePosition);\n $wrapperEl.transitionEnd(() => {\n if (!swiper || swiper.destroyed) return;\n swiper.transitionEnd();\n });\n }, 0);\n });\n } else if (swiper.velocity) {\n emit('_freeModeNoMomentumRelease');\n swiper.updateProgress(newPosition);\n swiper.setTransition(momentumDuration);\n swiper.setTranslate(newPosition);\n swiper.transitionStart(true, swiper.swipeDirection);\n\n if (!swiper.animating) {\n swiper.animating = true;\n $wrapperEl.transitionEnd(() => {\n if (!swiper || swiper.destroyed) return;\n swiper.transitionEnd();\n });\n }\n } else {\n swiper.updateProgress(newPosition);\n }\n\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n } else if (params.freeMode.sticky) {\n swiper.slideToClosest();\n return;\n } else if (params.freeMode) {\n emit('_freeModeNoMomentumRelease');\n }\n\n if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {\n swiper.updateProgress();\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n }\n\n Object.assign(swiper, {\n freeMode: {\n onTouchStart,\n onTouchMove,\n onTouchEnd\n }\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/grid/grid.js\nfunction Grid({\n swiper,\n extendParams\n}) {\n extendParams({\n grid: {\n rows: 1,\n fill: 'column'\n }\n });\n let slidesNumberEvenToRows;\n let slidesPerRow;\n let numFullColumns;\n\n const initSlides = slidesLength => {\n const {\n slidesPerView\n } = swiper.params;\n const {\n rows,\n fill\n } = swiper.params.grid;\n slidesPerRow = slidesNumberEvenToRows / rows;\n numFullColumns = Math.floor(slidesLength / rows);\n\n if (Math.floor(slidesLength / rows) === slidesLength / rows) {\n slidesNumberEvenToRows = slidesLength;\n } else {\n slidesNumberEvenToRows = Math.ceil(slidesLength / rows) * rows;\n }\n\n if (slidesPerView !== 'auto' && fill === 'row') {\n slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, slidesPerView * rows);\n }\n };\n\n const updateSlide = (i, slide, slidesLength, getDirectionLabel) => {\n const {\n slidesPerGroup,\n spaceBetween\n } = swiper.params;\n const {\n rows,\n fill\n } = swiper.params.grid; // Set slides order\n\n let newSlideOrderIndex;\n let column;\n let row;\n\n if (fill === 'row' && slidesPerGroup > 1) {\n const groupIndex = Math.floor(i / (slidesPerGroup * rows));\n const slideIndexInGroup = i - rows * slidesPerGroup * groupIndex;\n const columnsInGroup = groupIndex === 0 ? slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * rows * slidesPerGroup) / rows), slidesPerGroup);\n row = Math.floor(slideIndexInGroup / columnsInGroup);\n column = slideIndexInGroup - row * columnsInGroup + groupIndex * slidesPerGroup;\n newSlideOrderIndex = column + row * slidesNumberEvenToRows / rows;\n slide.css({\n '-webkit-order': newSlideOrderIndex,\n order: newSlideOrderIndex\n });\n } else if (fill === 'column') {\n column = Math.floor(i / rows);\n row = i - column * rows;\n\n if (column > numFullColumns || column === numFullColumns && row === rows - 1) {\n row += 1;\n\n if (row >= rows) {\n row = 0;\n column += 1;\n }\n }\n } else {\n row = Math.floor(i / slidesPerRow);\n column = i - row * slidesPerRow;\n }\n\n slide.css(getDirectionLabel('margin-top'), row !== 0 ? spaceBetween && `${spaceBetween}px` : '');\n };\n\n const updateWrapperSize = (slideSize, snapGrid, getDirectionLabel) => {\n const {\n spaceBetween,\n centeredSlides,\n roundLengths\n } = swiper.params;\n const {\n rows\n } = swiper.params.grid;\n swiper.virtualSize = (slideSize + spaceBetween) * slidesNumber
1EvenToRows;\n swiper.virtualSize = Math.ceil(swiper.virtualSize / rows) - spaceBetween;\n swiper.$wrapperEl.css({\n [getDirectionLabel('width')]: `${swiper.virtualSize + spaceBetween}px`\n });\n\n if (centeredSlides) {\n snapGrid.splice(0, snapGrid.length);\n const newSlidesGrid = [];\n\n for (let i = 0; i < snapGrid.length; i += 1) {\n let slidesGridItem = snapGrid[i];\n if (roundLengths) slidesGridItem = Math.floor(slidesGridItem);\n if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);\n }\n\n snapGrid.push(...newSlidesGrid);\n }\n };\n\n swiper.grid = {\n initSlides,\n updateSlide,\n updateWrapperSize\n };\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/manipulation/methods/appendSlide.js\nfunction appendSlide(slides) {\n const swiper = this;\n const {\n $wrapperEl,\n params\n } = swiper;\n\n if (params.loop) {\n swiper.loopDestroy();\n }\n\n if (typeof slides === 'object' && 'length' in slides) {\n for (let i = 0; i < slides.length; i += 1) {\n if (slides[i]) $wrapperEl.append(slides[i]);\n }\n } else {\n $wrapperEl.append(slides);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }\n\n if (!params.observer) {\n swiper.update();\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/manipulation/methods/prependSlide.js\nfunction prependSlide(slides) {\n const swiper = this;\n const {\n params,\n $wrapperEl,\n activeIndex\n } = swiper;\n\n if (params.loop) {\n swiper.loopDestroy();\n }\n\n let newActiveIndex = activeIndex + 1;\n\n if (typeof slides === 'object' && 'length' in slides) {\n for (let i = 0; i < slides.length; i += 1) {\n if (slides[i]) $wrapperEl.prepend(slides[i]);\n }\n\n newActiveIndex = activeIndex + slides.length;\n } else {\n $wrapperEl.prepend(slides);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }\n\n if (!params.observer) {\n swiper.update();\n }\n\n swiper.slideTo(newActiveIndex, 0, false);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/manipulation/methods/addSlide.js\nfunction addSlide(index, slides) {\n const swiper = this;\n const {\n $wrapperEl,\n params,\n activeIndex\n } = swiper;\n let activeIndexBuffer = activeIndex;\n\n if (params.loop) {\n activeIndexBuffer -= swiper.loopedSlides;\n swiper.loopDestroy();\n swiper.slides = $wrapperEl.children(`.${params.slideClass}`);\n }\n\n const baseLength = swiper.slides.length;\n\n if (index <= 0) {\n swiper.prependSlide(slides);\n return;\n }\n\n if (index >= baseLength) {\n swiper.appendSlide(slides);\n return;\n }\n\n let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;\n const slidesBuffer = [];\n\n for (let i = baseLength - 1; i >= index; i -= 1) {\n const currentSlide = swiper.slides.eq(i);\n currentSlide.remove();\n slidesBuffer.unshift(currentSlide);\n }\n\n if (typeof slides === 'object' && 'length' in slides) {\n for (let i = 0; i < slides.length; i += 1) {\n if (slides[i]) $wrapperEl.append(slides[i]);\n }\n\n newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;\n } else {\n $wrapperEl.append(slides);\n }\n\n for (let i = 0; i < slidesBuffer.length; i += 1) {\n $wrapperEl.append(slidesBuffer[i]);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }\n\n if (!params.observer) {\n swiper.update();\n }\n\n if (params.loop) {\n swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);\n } else {\n swiper.slideTo(newActiveIndex, 0, false);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/manipulation/methods/removeSlide.js\nfunction removeSlide(slidesIndexes) {\n const swiper = this;\n const {\n params,\n $wrapperEl,\n activeIndex\n } = swiper;\n let activeIndexBuffer = activeIndex;\n\n if (params.loop) {\n activeIndexBuffer -= swiper.loopedSlides;\n swiper.loopDestroy();\n swiper.slides = $wrapperEl.children(`.${params.slideClass}`);\n }\n\n let newActiveIndex = activeIndexBuffer;\n let indexToRemove;\n\n if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {\n for (let i = 0; i < slidesIndexes.length; i += 1) {\n indexToRemove = slidesIndexes[i];\n if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove();\n if (indexToRemove < newActiveIndex) newActiveIndex -= 1;\n }\n\n newActiveIndex = Math.max(newActiveIndex, 0);\n } else {\n indexToRemove = slidesIndexes;\n if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove();\n if (indexToRemove < newActiveIndex) newActiveIndex -= 1;\n newActiveIndex = Math.max(newActiveIndex, 0);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }
1\n\n if (!params.observer) {\n swiper.update();\n }\n\n if (params.loop) {\n swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);\n } else {\n swiper.slideTo(newActiveIndex, 0, false);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/manipulation/methods/removeAllSlides.js\nfunction removeAllSlides() {\n const swiper = this;\n const slidesIndexes = [];\n\n for (let i = 0; i < swiper.slides.length; i += 1) {\n slidesIndexes.push(i);\n }\n\n swiper.removeSlide(slidesIndexes);\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/manipulation/manipulation.js\n\n\n\n\n\nfunction Manipulation({\n swiper\n}) {\n Object.assign(swiper, {\n appendSlide: appendSlide.bind(swiper),\n prependSlide: prependSlide.bind(swiper),\n addSlide: addSlide.bind(swiper),\n removeSlide: removeSlide.bind(swiper),\n removeAllSlides: removeAllSlides.bind(swiper)\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/effect-init.js\nfunction effectInit(params) {\n const {\n effect,\n swiper,\n on,\n setTranslate,\n setTransition,\n overwriteParams,\n perspective,\n recreateShadows,\n getEffectParams\n } = params;\n on('beforeInit', () => {\n if (swiper.params.effect !== effect) return;\n swiper.classNames.push(`${swiper.params.containerModifierClass}${effect}`);\n\n if (perspective && perspective()) {\n swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);\n }\n\n const overwriteParamsResult = overwriteParams ? overwriteParams() : {};\n Object.assign(swiper.params, overwriteParamsResult);\n Object.assign(swiper.originalParams, overwriteParamsResult);\n });\n on('setTranslate', () => {\n if (swiper.params.effect !== effect) return;\n setTranslate();\n });\n on('setTransition', (_s, duration) => {\n if (swiper.params.effect !== effect) return;\n setTransition(duration);\n });\n on('transitionEnd', () => {\n if (swiper.params.effect !== effect) return;\n\n if (recreateShadows) {\n if (!getEffectParams || !getEffectParams().slideShadows) return; // remove shadows\n\n swiper.slides.each(slideEl => {\n const $slideEl = swiper.$(slideEl);\n $slideEl.find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').remove();\n }); // create new one\n\n recreateShadows();\n }\n });\n let requireUpdateOnVirtual;\n on('virtualUpdate', () => {\n if (swiper.params.effect !== effect) return;\n\n if (!swiper.slides.length) {\n requireUpdateOnVirtual = true;\n }\n\n requestAnimationFrame(() => {\n if (requireUpdateOnVirtual && swiper.slides && swiper.slides.length) {\n setTranslate();\n requireUpdateOnVirtual = false;\n }\n });\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/effect-target.js\nfunction effectTarget(effectParams, $slideEl) {\n if (effectParams.transformEl) {\n return $slideEl.find(effectParams.transformEl).css({\n 'backface-visibility': 'hidden',\n '-webkit-backface-visibility': 'hidden'\n });\n }\n\n return $slideEl;\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/effect-virtual-transition-end.js\nfunction effectVirtualTransitionEnd({\n swiper,\n duration,\n transformEl,\n allSlides\n}) {\n const {\n slides,\n activeIndex,\n $wrapperEl\n } = swiper;\n\n if (swiper.params.virtualTranslate && duration !== 0) {\n let eventTriggered = false;\n let $transitionEndTarget;\n\n if (allSlides) {\n $transitionEndTarget = transformEl ? slides.find(transformEl) : slides;\n } else {\n $transitionEndTarget = transformEl ? slides.eq(activeIndex).find(transformEl) : slides.eq(activeIndex);\n }\n\n $transitionEndTarget.transitionEnd(() => {\n if (eventTriggered) return;\n if (!swiper || swiper.destroyed) return;\n eventTriggered = true;\n swiper.animating = false;\n const triggerEvents = ['webkitTransitionEnd', 'transitionend'];\n\n for (let i = 0; i < triggerEvents.length; i += 1) {\n $wrapperEl.trigger(triggerEvents[i]);\n }\n });\n }\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/effect-fade/effect-fade.js\n\n\n\nfunction EffectFade({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n fadeEffect: {\n crossFade: false,\n transformEl: null\n }\n });\n\n const setTranslate = () => {\n const {\n slides\n } = swiper;\n const params = swiper.params.fadeEffect;\n\n for (let i = 0; i < slides.length; i += 1) {\n const $slideEl = swiper.slides.eq(i);\n const offset = $slideEl[0].swiperSlideOffset;\n let tx = -offset;\n if (!swiper.params.virtualTranslate) tx -= swiper.translate;\n let ty = 0;\n\n if (!swiper.isHorizontal()) {\n ty = tx;\n tx = 0;\n }\n\n const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs($slideEl[0].progress), 0) : 1 + Math.min(Math.max($slideEl[0].progress, -1), 0);\n const $targetEl = effectTarget(params, $slideEl);\n $targetEl.css({\n opacity: slideOpacity\n }).transform(`translate3d(${tx}px, ${ty}px, 0px)`);\n }\n };\n\n const setTransition = duration => {\n const {\n transformEl\n } = swiper.params.fadeEffect;\n const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;\n $transitionElements.transition(duration);\n effectVirtualTransitionEnd({\n swiper,\n duration,\n transformEl,\n allSlides: true\n });\n };\n\n effectInit({\n effect: 'fade',\n swiper,\n on,\n setTranslate,\n setTransition,\n overwriteParams: () => ({\n slidesPerView: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n spaceBetween: 0,\n virtualTranslate: !swiper.params.cssMode\n })\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/effect-cube/effect-cube.
1js\n\n\nfunction EffectCube({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n cubeEffect: {\n slideShadows: true,\n shadow: true,\n shadowOffset: 20,\n shadowScale: 0.94\n }\n });\n\n const createSlideShadows = ($slideEl, progress, isHorizontal) => {\n let shadowBefore = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');\n let shadowAfter = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');\n\n if (shadowBefore.length === 0) {\n shadowBefore = dom(`<div class=\"swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}\"></div>`);\n $slideEl.append(shadowBefore);\n }\n\n if (shadowAfter.length === 0) {\n shadowAfter = dom(`<div class=\"swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}\"></div>`);\n $slideEl.append(shadowAfter);\n }\n\n if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n };\n\n const recreateShadows = () => {\n // create new ones\n const isHorizontal = swiper.isHorizontal();\n swiper.slides.each(slideEl => {\n const progress = Math.max(Math.min(slideEl.progress, 1), -1);\n createSlideShadows(dom(slideEl), progress, isHorizontal);\n });\n };\n\n const setTranslate = () => {\n const {\n $el,\n $wrapperEl,\n slides,\n width: swiperWidth,\n height: swiperHeight,\n rtlTranslate: rtl,\n size: swiperSize,\n browser\n } = swiper;\n const params = swiper.params.cubeEffect;\n const isHorizontal = swiper.isHorizontal();\n const isVirtual = swiper.virtual && swiper.params.virtual.enabled;\n let wrapperRotate = 0;\n let $cubeShadowEl;\n\n if (params.shadow) {\n if (isHorizontal) {\n $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow');\n\n if ($cubeShadowEl.length === 0) {\n $cubeShadowEl = dom('<div class=\"swiper-cube-shadow\"></div>');\n $wrapperEl.append($cubeShadowEl);\n }\n\n $cubeShadowEl.css({\n height: `${swiperWidth}px`\n });\n } else {\n $cubeShadowEl = $el.find('.swiper-cube-shadow');\n\n if ($cubeShadowEl.length === 0) {\n $cubeShadowEl = dom('<div class=\"swiper-cube-shadow\"></div>');\n $el.append($cubeShadowEl);\n }\n }\n }\n\n for (let i = 0; i < slides.length; i += 1) {\n const $slideEl = slides.eq(i);\n let slideIndex = i;\n\n if (isVirtual) {\n slideIndex = parseInt($slideEl.attr('data-swiper-slide-index'), 10);\n }\n\n let slideAngle = slideIndex * 90;\n let round = Math.floor(slideAngle / 360);\n\n if (rtl) {\n slideAngle = -slideAngle;\n round = Math.floor(-slideAngle / 360);\n }\n\n const progress = Math.max(Math.min($slideEl[0].progress, 1), -1);\n let tx = 0;\n let ty = 0;\n let tz = 0;\n\n if (slideIndex % 4 === 0) {\n tx = -round * 4 * swiperSize;\n tz = 0;\n } else if ((slideIndex - 1) % 4 === 0) {\n tx = 0;\n tz = -round * 4 * swiperSize;\n } else if ((slideIndex - 2) % 4 === 0) {\n tx = swiperSize + round * 4 * swiperSize;\n tz = swiperSize;\n } else if ((slideIndex - 3) % 4 === 0) {\n tx = -swiperSize;\n tz = 3 * swiperSize + swiperSize * 4 * round;\n }\n\n if (rtl) {\n tx = -tx;\n }\n\n if (!isHorizontal) {\n ty = tx;\n tx = 0;\n }\n\n const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${isHorizontal ? slideAngle : 0}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;\n\n if (progress <= 1 && progress > -1) {\n wrapperRotate = slideIndex * 90 + progress * 90;\n if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;\n }\n\n $slideEl.transform(transform);\n\n if (params.slideShadows) {\n createSlideShadows($slideEl, progress, isHorizontal);\n }\n }\n\n $wrapperEl.css({\n '-webkit-transform-origin': `50% 50% -${swiperSize / 2}px`,\n 'transform-origin': `50% 50% -${swiperSize / 2}px`\n });\n\n if (params.shadow) {\n if (isHorizontal) {\n $cubeShadowEl.transform(`translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`);\n } else {\n const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;\n const multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);\n const scale1 = params.shadowScale;\n const scale2 = params.shadowScale / multiplier;\n const offset = params.shadowOffset;\n $cubeShadowEl.transform(`scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-90deg)`);\n }\n }\n\n const zFactor = browser.isSafari || browser.isWebView ? -swiperSize / 2 : 0;\n $wrapperEl.transform(`translate3d(0px,0,${zFactor}px) rotateX(${swiper.isHorizontal() ? 0 : wrapperRotate}deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`);\n $wrapperEl[0].style.setProperty('--swiper-cube-translate-z', `${zFactor}px`);\n };\n\n const setTransition = duration => {\n const {\n $el,\n slides\n } = swiper;\n slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n\n if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {\n $el.find('.swiper-cube-shadow').transition(duration);\n }\n };\n\n effectInit({\n effect: 'cube',\n swiper,\n on,\n setTranslate,\n setTransition,\n recreateShadows,\n getEffectParams: () => swiper.params.cubeEffect,\n perspective: () => true,\n overwriteParams: () => ({\n slidesPerView: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n resistanceRatio: 0,\n spaceBetween: 0,\n centeredSlides: false,\n virtualTranslate: true\n })\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/shared/create-shadow.js\n\nfunction createShadow(params, $slideEl, side) {\n const shadowClass = `swiper-slide-shadow${side ? `-${side}` : ''}`;\n const $shadowContainer = params.transformEl ? $slideEl.find(params.transformEl) : $slideEl;\n let $shadowEl = $shadowContainer.children(`.${shadowClass}`);\n\n if (!$shadowEl.length) {\n $shadowEl = dom(`<div class=\"swiper-slide-shadow${side ? `-${side}` : ''}\"></div>`);\n $shadowContainer.append($shadowEl);\n }\n\n return $shadowEl;\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/effect-flip/effect-flip.js\n\n\n\n\n\nfunction EffectFlip({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n flipEffect: {\n slideShadows: true,\n limitRotation: true,\n transformEl: null\n }\n });\n\n const createSlideShadows = ($slideEl, progress, params) => {\n let shadowBefore = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');\n let shadowAfter = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');\n\n if (shadowBefore.length === 0) {\n shadowBefore = createShadow(params, $slideEl, swiper.isHorizontal() ? 'left' : 'top');\n }\n\n if (shadowAfter.length === 0) {\n shadowAfter = createShadow(params, $slideEl, swiper.isHorizontal() ? 'right' : 'bottom');\n }\n\n if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);\n if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);\n };\n\n const recreateShadows = () => {\n // Set shadows\n const params = swiper.params.flipEffect;\n swiper.slides.each(slideEl => {\n const $slideEl = dom(slideEl);\n let progress = $slideEl[0].progress;\n\n if (swiper.params.flipEffect.limitRotation) {\n progress = Math.max(Math.min(slideEl.progress, 1), -1);\n }\n\n createSlideShadows($slideEl, progress, params);\n });\n };\n\n const setTranslate = () => {\n const {\n slides,\n rtlTranslate: rtl\n } = swiper;\n const params = swiper.params.flipEffect;\n\n for (let i = 0; i < slides.length; i += 1) {\n const $slideEl = slides.eq(i);\n let progress = $slideEl[0].progress;\n\n if (swiper.params.flipEffect.limitRotation) {\n progress = Math.max(Math.min($slideEl[0].progress, 1), -1);\n }\n\n const offset = $slideEl[0].swiperSlideOffset;\n const rotate = -180 * progress;\n let rotateY = rotate;\n let rotateX = 0;\n let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;\n let ty = 0;\n\n if (!swiper.isHorizontal()) {\n ty = tx;\n tx = 0;\n rotateX = -rotateY;\n rotateY = 0;\n } else if (rtl) {\n rotateY = -rotateY;\n }\n\n $slideEl[0].style.zIndex = -Math.abs(Math.round(progress)) + slides.length;\n\n if (params.slideShadows) {\n createSlideShadows($slideEl, progress, params);\n }\n\n const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;\n const $targetEl = effectTarget(params, $slideEl);\n $targetEl.transform(transform);\n }\n };\n\n const setTransition = duration => {\n const {\n transformEl\n } = swiper.params.flipEffect;\n const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;\n $transitionElements.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n effectVirtualTransitionEnd({\n swiper,\n duration,\n transformEl\n });\n };\n\n effectInit({\n effect: 'flip',\n swiper,\n on,\n setTranslate,\n setTransition,\n recreateShadows,\n getEffectParams: () => swiper.params.flipEffect,\n perspective: () => true,\n overwriteParams: () => ({\n slidesPerView: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n spaceBetween: 0,\n virtualTranslate: !swiper.params.cssMode\n })\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/effect-coverflow/effect-coverflow.js\n\n\n\nfunction EffectCoverflow({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n coverflowEffect: {\n rotate: 50,\n stretch: 0,\n depth: 100,\n scale: 1,\n modifier: 1,\n slideShadows: true,\n transformEl: null\n }\n });\n\n const setTranslate = () => {\n const {\n width: swiperWidth,\n height: swiperHeight,\n slides,\n slidesSizesGrid\n } = swiper;\n const params = swiper.params.coverflowEffect;\n const isHorizontal = swiper.isHorizontal();\n const transform = swiper.translate;\n const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;\n const rotate = isHorizontal ? params.rotate : -params.rotate;\n const translate = params.depth; // Each slide offset from center\n\n for (let i = 0, length = slides.length; i < length; i += 1) {\n const $slideEl = slides.eq(i);\n const slideSize = slidesSizesGrid[i];\n const slideOffset = $slideEl[0].swiperSlideOffset;\n const centerOffset = (center - slideOffset - slideSize / 2) / slideSize;\n const offsetMultiplier = typeof params.modifier === 'function' ? params.modifier(centerOffset) : centerOffset * params.modifier;\n let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;\n let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; // var rotateZ = 0\n\n let translateZ = -translate * Math.abs(offsetMultiplier);\n let stretch = params.stretch; // Allow percentage to make a relative stretch for responsive sliders\n\n if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {\n stretch = parseFloat(params.stretch) / 100 * slideSize;\n }\n\n let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;\n let translateX = isHorizontal ? stretch * offsetMultiplier : 0;\n let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier); // Fix for ultra small values\n\n if (Math.abs(translateX) < 0.001) translateX = 0;\n if (Math.abs(translateY) < 0.001) translateY = 0;\n if (Math.abs(translateZ) < 0.001) translateZ = 0;\n if (Math.abs(rotateY) < 0.001) rotateY = 0;\n if (Math.abs(rotateX) < 0.001) rotateX = 0;\n if (Math.abs(scale) < 0.001) scale = 0;\n const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${scale})`;\n const $targetEl = effectTarget(params, $slideEl);\n $targetEl.transform(slideTransform);\n $slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n\n if (params.slideShadows) {\n // Set shadows\n let $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');\n let $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');\n\n if ($shadowBeforeEl.length === 0) {\n $shadowBeforeEl = createShadow(params, $slideEl, isHorizontal ? 'left' : 'top');\n }\n\n if ($shadowAfterEl.length === 0) {\n $shadowAfterEl = createShadow(params, $slideEl, isHorizontal ? 'right' : 'bottom');\n }\n\n if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;\n if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;\n }\n }\n };\n\n const setTransition = duration => {\n const {\n transformEl\n } = swiper.params.coverflowEffect;\n const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;\n $transitionElements.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);\n };\n\n effectInit({\n effect: 'coverflow',\n swiper,\n on,\n setTranslate,\n setTransition,\n perspective: () => true,\n overwriteParams: () => ({\n watchSlidesProgress: true\n })\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/effect-creative/effect-creative.js\n\n\n\n\nfunction EffectCreative({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n creativeEffect: {\n transformEl: null,\n limitProgress: 1,\n shadowPerProgress: false,\n progressMultiplier: 1,\n perspective: true,\n prev: {\n translate: [0, 0, 0],\n rotate: [0, 0, 0],\n opacity: 1,\n scale: 1\n },\n next: {\n translate: [0, 0, 0],\n rotate: [0, 0, 0],\n opacity: 1,\n scale: 1\n }\n }\n });\n\n const getTranslateValue = value => {\n if (typeof value === 'string') return value;\n return `${value}px`;\n };\n\n const setTranslate = () => {\n const {\n slides,\n $wrapperEl,\n slidesSizesGrid\n } = swiper;\n const params = swiper.params.creativeEffect;\n const {\n progressMultiplier: multiplier\n } = params;\n const isCenteredSlides = swiper.params.centeredSlides;\n\n if (isCenteredSlides) {\n const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;\n $wrapperEl.transform(`translateX(calc(50% - ${margin}px))`);\n }\n\n for (let i = 0; i < slides.length; i += 1) {\n const $slideEl = slides.eq(i);\n const slideProgress = $slideEl[0].progress;\n const progress = Math.min(Math.max($slideEl[0].progress, -params.limitProgress), params.limitProgress);\n let originalProgress = progress;\n\n if (!isCenteredSlides) {\n originalProgress = Math.min(Math.max($slideEl[0].originalProgress, -p
1arams.limitProgress), params.limitProgress);\n }\n\n const offset = $slideEl[0].swiperSlideOffset;\n const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];\n const r = [0, 0, 0];\n let custom = false;\n\n if (!swiper.isHorizontal()) {\n t[1] = t[0];\n t[0] = 0;\n }\n\n let data = {\n translate: [0, 0, 0],\n rotate: [0, 0, 0],\n scale: 1,\n opacity: 1\n };\n\n if (progress < 0) {\n data = params.next;\n custom = true;\n } else if (progress > 0) {\n data = params.prev;\n custom = true;\n } // set translate\n\n\n t.forEach((value, index) => {\n t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(progress * multiplier)}))`;\n }); // set rotates\n\n r.forEach((value, index) => {\n r[index] = data.rotate[index] * Math.abs(progress * multiplier);\n });\n $slideEl[0].style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;\n const translateString = t.join(', ');\n const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`;\n const scaleString = originalProgress < 0 ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})` : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;\n const opacityString = originalProgress < 0 ? 1 + (1 - data.opacity) * originalProgress * multiplier : 1 - (1 - data.opacity) * originalProgress * multiplier;\n const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`; // Set shadows\n\n if (custom && data.shadow || !custom) {\n let $shadowEl = $slideEl.children('.swiper-slide-shadow');\n\n if ($shadowEl.length === 0 && data.shadow) {\n $shadowEl = createShadow(params, $slideEl);\n }\n\n if ($shadowEl.length) {\n const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress;\n $shadowEl[0].style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);\n }\n }\n\n const $targetEl = effectTarget(params, $slideEl);\n $targetEl.transform(transform).css({\n opacity: opacityString\n });\n\n if (data.origin) {\n $targetEl.css('transform-origin', data.origin);\n }\n }\n };\n\n const setTransition = duration => {\n const {\n transformEl\n } = swiper.params.creativeEffect;\n const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;\n $transitionElements.transition(duration).find('.swiper-slide-shadow').transition(duration);\n effectVirtualTransitionEnd({\n swiper,\n duration,\n transformEl,\n allSlides: true\n });\n };\n\n effectInit({\n effect: 'creative',\n swiper,\n on,\n setTranslate,\n setTransition,\n perspective: () => swiper.params.creativeEffect.perspective,\n overwriteParams: () => ({\n watchSlidesProgress: true,\n virtualTranslate: !swiper.params.cssMode\n })\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/modules/effect-cards/effect-cards.js\n\n\n\n\nfunction EffectCards({\n swiper,\n extendParams,\n on\n}) {\n extendParams({\n cardsEffect: {\n slideShadows: true,\n transformEl: null,\n rotate: true,\n perSlideRotate: 2,\n perSlideOffset: 8\n }\n });\n\n const setTranslate = () => {\n const {\n slides,\n activeIndex\n } = swiper;\n const params = swiper.params.cardsEffect;\n const {\n startTranslate,\n isTouched\n } = swiper.touchEventsData;\n const currentTranslate = swiper.translate;\n\n for (let i = 0; i < slides.length; i += 1) {\n const $slideEl = slides.eq(i);\n const slideProgress = $slideEl[0].progress;\n const progress = Math.min(Math.max(slideProgress, -4), 4);\n let offset = $slideEl[0].swiperSlideOffset;\n\n if (swiper.params.centeredSlides && !swiper.params.cssMode) {\n swiper.$wrapperEl.transform(`translateX(${swiper.minTranslate()}px)`);\n }\n\n if (swiper.params.centeredSlides && swiper.params.cssMode) {\n offset -= slides[0].swiperSlideOffset;\n }\n\n let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;\n let tY = 0;\n const tZ = -100 * Math.abs(progress);\n let scale = 1;\n let rotate = -params.perSlideRotate * progress;\n let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;\n const slideIndex = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.from + i : i;\n const isSwipeToNext = (slideIndex === activeIndex || slideIndex === activeIndex - 1) && progress > 0 && progress < 1 && (isTouched || swiper.params.cssMode) && currentTranslate < startTranslate;\n const isSwipeToPrev = (slideIndex === activeIndex || slideIndex === activeIndex + 1) && progress < 0 && progress > -1 && (isTouched || swiper.params.cssMode) && currentTranslate > startTranslate;\n\n if (isSwipeToNext || isSwipeToPrev) {\n const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;\n rotate += -28 * progress * subProgress;\n scale += -0.5 * subProgress;\n tXAdd += 96 * subProgress;\n tY = `${-25 * subProgress * Math.abs(progress)}%`;\n }\n\n if (progress < 0) {\n // next\n tX = `calc(${tX}px + (${tXAdd * Math.abs(progress)}%))`;\n } else if (progress > 0) {\n // prev\n tX = `calc(${tX}px + (-${tXAdd * Math.abs(progress)}%))`;\n } else {\n tX = `${tX}px`;\n }\n\n if (!swiper.isHorizontal()) {\n const prevY = tY;\n tY = tX;\n tX = prevY;\n }
1\n\n const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;\n const transform = `\n translate3d(${tX}, ${tY}, ${tZ}px)\n rotateZ(${params.rotate ? rotate : 0}deg)\n scale(${scaleString})\n `;\n\n if (params.slideShadows) {\n // Set shadows\n let $shadowEl = $slideEl.find('.swiper-slide-shadow');\n\n if ($shadowEl.length === 0) {\n $shadowEl = createShadow(params, $slideEl);\n }\n\n if ($shadowEl.length) $shadowEl[0].style.opacity = Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1);\n }\n\n $slideEl[0].style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;\n const $targetEl = effectTarget(params, $slideEl);\n $targetEl.transform(transform);\n }\n };\n\n const setTransition = duration => {\n const {\n transformEl\n } = swiper.params.cardsEffect;\n const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;\n $transitionElements.transition(duration).find('.swiper-slide-shadow').transition(duration);\n effectVirtualTransitionEnd({\n swiper,\n duration,\n transformEl\n });\n };\n\n effectInit({\n effect: 'cards',\n swiper,\n on,\n setTranslate,\n setTransition,\n perspective: () => true,\n overwriteParams: () => ({\n watchSlidesProgress: true,\n virtualTranslate: !swiper.params.cssMode\n })\n });\n}\n;// CONCATENATED MODULE: ./node_modules/swiper/swiper-bundle.esm.js\n/**\n * Swiper 8.4.7\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * https://swiperjs.com\n *\n * Copyright 2014-2023 Vladimir Kharlampidi\n *\n * Released under the MIT License\n *\n * Released on: January 30, 2023\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// Swiper Class\nconst modules = [Virtual, Keyboard, Mousewheel, Navigation, Pagination, Scrollbar, Parallax, Zoom, Lazy, Controller, A11y, History, HashNavigation, Autoplay, Thumb, freeMode, Grid, Manipulation, EffectFade, EffectCube, EffectFlip, EffectCoverflow, EffectCreative, EffectCards];\ncore.use(modules);\n\n;// CONCATENATED MODULE: ./node_modules/lightgallery/lightgallery.es5.js\n/*!\n * lightgallery | 2.7.2 | September 20th 2023\n * http://www.lightgalleryjs.com/\n * Copyright (c) 2020 Sachin Neravath;\n * @license GPLv3\n */\n\n/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n\r\nvar __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n return __assign.apply(this, arguments);\r\n};\r\n\r\nfunction __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\n\n/**\r\n * List of lightGallery events\r\n * All events should be documented here\r\n * Below interfaces are used to build the website documentations\r\n * */\r\nvar lGEvents = {\r\n afterAppendSlide: 'lgAfterAppendSlide',\r\n init: 'lgInit',\r\n hasVideo: 'lgHasVideo',\r\n containerResize: 'lgContainerResize',\r\n updateSlides: 'lgUpdateSlides',\r\n afterAppendSubHtml: 'lgAfterAppendSubHtml',\r\n beforeOpen: 'lgBeforeOpen',\r\n afterOpen: 'lgAfterOpen',\r\n slideItemLoad: 'lgSlideItemLoad',\r\n beforeSlide: 'lgBeforeSlide',\r\n afterSlide: 'lgAfterSlide',\r\n posterClick: 'lgPosterClick',\r\n dragStart: 'lgDragStart',\r\n dragMove: 'lgDragMove',\r\n dragEnd: 'lgDragEnd',\r\n beforeNextSlide: 'lgBeforeNextSlide',\r\n beforePrevSlide: 'lgBeforePrevSlide',\r\n beforeClose: 'lgBeforeClose',\r\n afterClose: 'lgAfterClose',\r\n rotateLeft: 'lgRotateLeft',\r\n rotateRight: 'lgRotateRight',\r\n flipHorizontal: 'lgFlipHorizontal',\r\n flipVertical: 'lgFlipVertical',\r\n autoplay: 'lgAutoplay',\r\n autoplayStart: 'lgAutoplayStart',\r\n autoplayStop: 'lgAutoplayStop',\r\n};\n\nvar lightGalleryCoreSettings = {\r\n mode: 'lg-slide',\r\n easing: 'ease',\r\n speed: 400,\r\n licenseKey: '0000-0000-000-0000',\r\n height: '100%',\r\n width: '100%',\r\n addClass: '',\r\n startClass: 'lg-start-zoom',\r\n backdropDuration: 300,\r\n container: '',\r\n startAnimationDuration: 400,\r\n zoomFromOrigin: true,\r\n hideBarsDelay: 0,\r\n showBarsAfter: 10000,\r\n slideDelay: 0,\r\n supportLegacyBrowser: true,\r\n allowMediaOverlap: false,\r\n videoMaxSize: '1280-720',\r\n loadYouTubePoster: true,\r\n defaultCaptionHeight: 0,\r\n ariaLabelledby: '',\r\n ariaDescribedby: '',\r\n resetScrollPosition: true,\r\n hideScrollbar: false,\r\n closable: true,\r\n swipeToClose: true,\r\n closeOnTap: true,\r\n showCloseIcon: true,\r\n showMaximizeIcon: false,\r\n loop: true,\r\n escKey: true,\r\n keyPress: true,\r\n trapFocus: true,\r\n controls: true,\r\n slideEndAnimation: true,\r\n hideControlOnEnd: false,\r\n mousewheel: false,\r\n getCaptionFromTitleOrAlt: true,\r\n appendSubHtmlTo: '.lg-sub-html',\r\n subHtmlSelectorRelative: false,\r\n preload: 2,\r\n numberOfSlideItemsInDom: 10,\r\n selector: '',\r\n selectWithin: '',\r\n nextHtml: '',\r\n prevHtml: '',\r\n index: 0,\r\n iframeWidth: '100%',\r\n iframeHeight: '100%',\r\n iframeMaxWidth: '100%',\r\n iframeMaxHeight: '100%',\r\n download: true,\r\n counter: true,\r\n appendCounterTo: '.lg-toolbar',\r\n swipeThreshold: 50,\r\n enableSwipe: true,\r\n enableDrag: true,\r\n dynamic: fal
1se,\r\n dynamicEl: [],\r\n extraProps: [],\r\n exThumbImage: '',\r\n isMobile: undefined,\r\n mobileSettings: {\r\n controls: false,\r\n showCloseIcon: false,\r\n download: false,\r\n },\r\n plugins: [],\r\n strings: {\r\n closeGallery: 'Close gallery',\r\n toggleMaximize: 'Toggle maximize',\r\n previousSlide: 'Previous slide',\r\n nextSlide: 'Next slide',\r\n download: 'Download',\r\n playVideo: 'Play video',\r\n mediaLoadingFailed: 'Oops... Failed to load content...',\r\n },\r\n};\n\nfunction initLgPolyfills() {\r\n (function () {\r\n if (typeof window.CustomEvent === 'function')\r\n return false;\r\n function CustomEvent(event, params) {\r\n params = params || {\r\n bubbles: false,\r\n cancelable: false,\r\n detail: null,\r\n };\r\n var evt = document.createEvent('CustomEvent');\r\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\r\n return evt;\r\n }\r\n window.CustomEvent = CustomEvent;\r\n })();\r\n (function () {\r\n if (!Element.prototype.matches) {\r\n Element.prototype.matches =\r\n Element.prototype.msMatchesSelector ||\r\n Element.prototype.webkitMatchesSelector;\r\n }\r\n })();\r\n}\r\nvar lgQuery = /** @class */ (function () {\r\n function lgQuery(selector) {\r\n this.cssVenderPrefixes = [\r\n 'TransitionDuration',\r\n 'TransitionTimingFunction',\r\n 'Transform',\r\n 'Transition',\r\n ];\r\n this.selector = this._getSelector(selector);\r\n this.firstElement = this._getFirstEl();\r\n return this;\r\n }\r\n lgQuery.generateUUID = function () {\r\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\r\n var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;\r\n return v.toString(16);\r\n });\r\n };\r\n lgQuery.prototype._getSelector = function (selector, context) {\r\n if (context === void 0) { context = document; }\r\n if (typeof selector !== 'string') {\r\n return selector;\r\n }\r\n context = context || document;\r\n var fl = selector.substring(0, 1);\r\n if (fl === '#') {\r\n return context.querySelector(selector);\r\n }\r\n else {\r\n return context.querySelectorAll(selector);\r\n }\r\n };\r\n lgQuery.prototype._each = function (func) {\r\n if (!this.selector) {\r\n return this;\r\n }\r\n if (this.selector.length !== undefined) {\r\n [].forEach.call(this.selector, func);\r\n }\r\n else {\r\n func(this.selector, 0);\r\n }\r\n return this;\r\n };\r\n lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) {\r\n // prettier-ignore\r\n var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) {\r\n return group1.toUpperCase();\r\n });\r\n if (this.cssVenderPrefixes.indexOf(property) !== -1) {\r\n el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value;\r\n el.style['webkit' + property] = value;\r\n el.style['moz' + property] = value;\r\n el.style['ms' + property] = value;\r\n el.style['o' + property] = value;\r\n }\r\n else {\r\n el.style[property] = value;\r\n }\r\n };\r\n lgQuery.prototype._getFirstEl = function () {\r\n if (this.selector && this.selector.length !== undefined) {\r\n return this.selector[0];\r\n }\r\n else {\r\n return this.selector;\r\n }\r\n };\r\n lgQuery.prototype.isEventMatched = function (event, eventName) {\r\n var eventNamespace = eventName.split('.');\r\n return event\r\n .split('.')\r\n .filter(function (e) { return e; })\r\n .every(function (e) {\r\n return eventNamespace.indexOf(e) !== -1;\r\n });\r\n };\r\n lgQuery.prototype.attr = function (attr, value) {\r\n if (value === undefined) {\r\n if (!this.firstElement) {\r\n return '';\r\n }\r\n return this.firstElement.getAttribute(attr);\r\n }\r\n this._each(function (el) {\r\n el.setAttribute(attr, value);\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.find = function (selector) {\r\n return $LG(this._getSelector(selector, this.selector));\r\n };\r\n lgQuery.prototype.first = function () {\r\n if (this.selector && this.selector.length !== undefined) {\r\n return $LG(this.selector[0]);\r\n }\r\n else {\r\n return $LG(this.selector);\r\n }\r\n };\r\n lgQuery.prototype.eq = function (index) {\r\n return $LG(this.selector[index]);\r\n };\r\n lgQuery.prototype.parent = function () {\r\n return $LG(this.selector.parentElement);\r\n };\r\n lgQuery.prototype.get = function () {\r\n return this._getFirstEl();\r\n };\r\n lgQuery.prototype.removeAttr = function (attributes) {\r\n var attrs = attributes.split(' ');\r\n this._each(function (el) {\r\n attrs.forEac
1h(function (attr) { return el.removeAttribute(attr); });\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.wrap = function (className) {\r\n if (!this.firstElement) {\r\n return this;\r\n }\r\n var wrapper = document.createElement('div');\r\n wrapper.className = className;\r\n this.firstElement.parentNode.insertBefore(wrapper, this.firstElement);\r\n this.firstElement.parentNode.removeChild(this.firstElement);\r\n wrapper.appendChild(this.firstElement);\r\n return this;\r\n };\r\n lgQuery.prototype.addClass = function (classNames) {\r\n if (classNames === void 0) { classNames = ''; }\r\n this._each(function (el) {\r\n // IE doesn't support multiple arguments\r\n classNames.split(' ').forEach(function (className) {\r\n if (className) {\r\n el.classList.add(className);\r\n }\r\n });\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.removeClass = function (classNames) {\r\n this._each(function (el) {\r\n // IE doesn't support multiple arguments\r\n classNames.split(' ').forEach(function (className) {\r\n if (className) {\r\n el.classList.remove(className);\r\n }\r\n });\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.hasClass = function (className) {\r\n if (!this.firstElement) {\r\n return false;\r\n }\r\n return this.firstElement.classList.contains(className);\r\n };\r\n lgQuery.prototype.hasAttribute = function (attribute) {\r\n if (!this.firstElement) {\r\n return false;\r\n }\r\n return this.firstElement.hasAttribute(attribute);\r\n };\r\n lgQuery.prototype.toggleClass = function (className) {\r\n if (!this.firstElement) {\r\n return this;\r\n }\r\n if (this.hasClass(className)) {\r\n this.removeClass(className);\r\n }\r\n else {\r\n this.addClass(className);\r\n }\r\n return this;\r\n };\r\n lgQuery.prototype.css = function (property, value) {\r\n var _this = this;\r\n this._each(function (el) {\r\n _this._setCssVendorPrefix(el, property, value);\r\n });\r\n return this;\r\n };\r\n // Need to pass separate namespaces for separate elements\r\n lgQuery.prototype.on = function (events, listener) {\r\n var _this = this;\r\n if (!this.selector) {\r\n return this;\r\n }\r\n events.split(' ').forEach(function (event) {\r\n if (!Array.isArray(lgQuery.eventListeners[event])) {\r\n lgQuery.eventListeners[event] = [];\r\n }\r\n lgQuery.eventListeners[event].push(listener);\r\n _this.selector.addEventListener(event.split('.')[0], listener);\r\n });\r\n return this;\r\n };\r\n // @todo - test this\r\n lgQuery.prototype.once = function (event, listener) {\r\n var _this = this;\r\n this.on(event, function () {\r\n _this.off(event);\r\n listener(event);\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.off = function (event) {\r\n var _this = this;\r\n if (!this.selector) {\r\n return this;\r\n }\r\n Object.keys(lgQuery.eventListeners).forEach(function (eventName) {\r\n if (_this.isEventMatched(event, eventName)) {\r\n lgQuery.eventListeners[eventName].forEach(function (listener) {\r\n _this.selector.removeEventListener(eventName.split('.')[0], listener);\r\n });\r\n lgQuery.eventListeners[eventName] = [];\r\n }\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.trigger = function (event, detail) {\r\n if (!this.firstElement) {\r\n return this;\r\n }\r\n var customEvent = new CustomEvent(event.split('.')[0], {\r\n detail: detail || null,\r\n });\r\n this.firstElement.dispatchEvent(customEvent);\r\n return this;\r\n };\r\n // Does not support IE\r\n lgQuery.prototype.load = function (url) {\r\n var _this = this;\r\n fetch(url)\r\n .then(function (res) { return res.text(); })\r\n .then(function (html) {\r\n _this.selector.innerHTML = html;\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.html = function (html) {\r\n if (html === undefined) {\r\n if (!this.firstElement) {\r\n return '';\r\n }\r\n return this.firstElement.innerHTML;\r\n }\r\n this._each(function (el) {\r\n el.innerHTML = html;\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.append = function (html) {\r\n this._each(function (el) {\r\n if (typeof html === 'string') {\r\n el.insertAdjacentHTML('beforeend', html);\r\n }\r\n else {\r\n el.appendChild(html);\r\n }\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.prepend = function (html) {\r\n this._each(function (el) {\r\n el.insertAdjacentHTML('afterbegin', html);\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.remove = function () {\r\n this._each(function (el) {\r\n el.parentNode.removeChild(el);\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.empty = function () {\r\n this._each(function (el) {\r\n el.innerHTML = '';\r\n });\r\n return this;\r\n };\r\n lgQuery.prototype.scrollTop = function (scrollTop) {\r\n if (scrollTop !== undefined) {\r\n document.body.scrollTop = scrollTop;\r\n document.documentElement.scrollTop = scrollTop;\r\n return this;\r\n }\r\n else {\r\n return (window.pageYOffset ||\r\n document.documentElement.scrollTop ||\r\n document.body.scrollTop ||\r\n 0);\r\n }\r\n };\r\n lgQuery.prototype.scrollLeft = function (scrollLeft) {\r\n if (scrollLeft !== undefined) {\r\n document.body.scrollLeft = scrollLeft;\r\n document.documentElement.scrollLeft = scrollLeft;\r\n return this;\r\n }\r\n else {\r\n return (window.pageXOffset ||\r\n document.documentElement.scrollLeft ||\r\n document.body.scrollLeft ||\r\n 0);\r\n }\r\n };\r\n lgQuery.prototype.offset = function () {\r\n if (!this.firstElement) {\r\n return {\r\n left: 0,\r\n top: 0,\r\n };\r\n }\r\n var rect = this.firstElement.getBoundingClientRect();\r\n var bodyMarginLeft = $LG('body').style().marginLeft;\r\n // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value\r\n return {\r\n left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(),\r\n top: rect.top + this.scrollTop(),\r\n };\r\n };\r\n lgQuery.prototype.style = function () {\r\n if (!this.firstElement) {\r\n return {};\r\n }\r\n return (this.firstElement.currentStyle ||\r\n window.getComputedStyle(this.firstElement));\r\n };\r\n // Width without padding and border even if box-sizing is used.\r\n lgQuery.prototype.width = function () {\r\n var style = this.style();\r\n return (this.firstElement.clientWidth -\r\n parseFloat(style.paddingLeft) -\r\n parseFloat(style.paddingRight));\r\n };\r\n // Height without padding and border even if box-sizing is used.\r\n lgQuery.prototype.height = function () {\r\n var style = this.style();\r\n return (this.firstElement.clientHeight -\r\n parseFloat(style.paddingTop) -\r\n parseFloat(style.paddingBottom));\r\n };\r\n lgQuery.eventListeners = {};\r\n return lgQuery;\r\n}());\r\nfunction $LG(selector) {\r\n initLgPolyfills();\r\n return new lgQuery(selector);\r\n}\n\nvar defaultDynamicOptions = [\r\n 'src',\r\n 'sources',\r\n 'subHtml',\r\n 'subHtmlUrl',\r\n 'html',\r\n 'video',\r\n 'poster',\r\n 'slideName',\r\n 'responsive',\r\n 'srcset',\r\n 'sizes',\r\n 'iframe',\r\n 'downloadUrl',\r\n 'download',\r\n 'width',\r\n 'facebookShareUrl',\r\n 'tweetText',\r\n 'iframeTitle',\r\n 'twitterShareUrl',\r\n 'pinterestShareUrl',\r\n 'pinterestText',\r\n 'fbHtml',\r\n 'disqusIdentifier',\r\n 'disqusUrl',\r\n];\r\n// Convert html data-attribute to camalcase\r\nfunction convertToData(attr) {\r\n // FInd a way for lgsize\r\n if (attr === 'href') {\r\n return 'src';\r\n }\r\n attr = attr.replace('data-', '');\r\n attr = attr.charAt(0).toLowerCase() + attr.slice(1);\r\n attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });\r\n return attr;\r\n}\r\nvar utils = {\r\n /**\r\n * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option\r\n */\r\n getSize: function (el, container, spacing, defaultLgSize) {\r\n if (spacing === void 0) { spacing = 0; }\r\n var LGel = $LG(el);\r\n var lgSize = LGel.attr('data-lg-size') || defaultLgSize;\r\n if (!lgSize) {\r\n return;\r\n }\r\n var isResponsiveSizes = lgSize.split(',');\r\n // if at-least two viewport sizes are available\r\n if (isResponsiveSizes[1]) {\r\n var wWidth = window.innerWidth;\r\n for (var i = 0; i < isResponsiveSizes.length; i++) {\r\n var size_1 = isResponsiveSizes[i];\r\n var responsiveWidth = parseInt(size_1.split('-')[2], 10);\r\n if (responsiveWidth > wWidth) {\r\n lgSize = size_1;\r\n break;\r\n }\r\n // take last item as last option\r\n if (i === isResponsiveSizes.length - 1) {\r\n lgSize = size_1;\r\n }\r\n }\r\n }\r\n var size = lgSize.split('-');\r\n var width = parseInt(size[0], 10);\r\n var height = parseInt(size[1], 10);\r\n var cWidth = container.width();\r\n var cHeight = container.height() - spacing;\r\n var maxWidth = Math.min(cWidth, width);\r\n var maxHeight = Math.min(cHeight, height);\r\n var ratio = Math.min(maxWidth / width, maxHeight / height);\r\n return { width: width * ratio, height: height * ratio };\r\n }
1,\r\n /**\r\n * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option\r\n * @param {jQuery Element}\r\n * @returns {String} Transform CSS string\r\n */\r\n getTransform: function (el, container, top, bottom, imageSize) {\r\n if (!imageSize) {\r\n return;\r\n }\r\n var LGel = $LG(el).find('img').first();\r\n if (!LGel.get()) {\r\n return;\r\n }\r\n var containerRect = container.get().getBoundingClientRect();\r\n var wWidth = containerRect.width;\r\n // using innerWidth to include mobile safari bottom bar\r\n var wHeight = container.height() - (top + bottom);\r\n var elWidth = LGel.width();\r\n var elHeight = LGel.height();\r\n var elStyle = LGel.style();\r\n var x = (wWidth - elWidth) / 2 -\r\n LGel.offset().left +\r\n (parseFloat(elStyle.paddingLeft) || 0) +\r\n (parseFloat(elStyle.borderLeft) || 0) +\r\n $LG(window).scrollLeft() +\r\n containerRect.left;\r\n var y = (wHeight - elHeight) / 2 -\r\n LGel.offset().top +\r\n (parseFloat(elStyle.paddingTop) || 0) +\r\n (parseFloat(elStyle.borderTop) || 0) +\r\n $LG(window).scrollTop() +\r\n top;\r\n var scX = elWidth / imageSize.width;\r\n var scY = elHeight / imageSize.height;\r\n var transform = 'translate3d(' +\r\n (x *= -1) +\r\n 'px, ' +\r\n (y *= -1) +\r\n 'px, 0) scale3d(' +\r\n scX +\r\n ', ' +\r\n scY +\r\n ', 1)';\r\n return transform;\r\n },\r\n getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) {\r\n var title = iframeTitle ? 'title=\"' + iframeTitle + '\"' : '';\r\n return \"<div class=\\\"lg-video-cont lg-has-iframe\\\" style=\\\"width:\" + iframeWidth + \"; max-width:\" + iframeMaxWidth + \"; height: \" + iframeHeight + \"; max-height:\" + iframeMaxHeight + \"\\\">\\n <iframe class=\\\"lg-object\\\" frameborder=\\\"0\\\" \" + title + \" src=\\\"\" + src + \"\\\" allowfullscreen=\\\"true\\\"></iframe>\\n </div>\";\r\n },\r\n getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) {\r\n var srcsetAttr = srcset ? \"srcset=\\\"\" + srcset + \"\\\"\" : '';\r\n var sizesAttr = sizes ? \"sizes=\\\"\" + sizes + \"\\\"\" : '';\r\n var imgMarkup = \"<img \" + altAttr + \" \" + srcsetAttr + \" \" + sizesAttr + \" class=\\\"lg-object lg-image\\\" data-index=\\\"\" + index + \"\\\" src=\\\"\" + src + \"\\\" />\";\r\n var sourceTag = '';\r\n if (sources) {\r\n var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources;\r\n sourceTag = sourceObj.map(function (source) {\r\n var attrs = '';\r\n Object.keys(source).forEach(function (key) {\r\n // Do not remove the first space as it is required to separate the attributes\r\n attrs += \" \" + key + \"=\\\"\" + source[key] + \"\\\"\";\r\n });\r\n return \"<source \" + attrs + \"></source>\";\r\n });\r\n }\r\n return \"\" + sourceTag + imgMarkup;\r\n },\r\n // Get src from responsive src\r\n getResponsiveSrc: function (srcItms) {\r\n var rsWidth = [];\r\n var rsSrc = [];\r\n var src = '';\r\n for (var i = 0; i < srcItms.length; i++) {\r\n var _src = srcItms[i].split(' ');\r\n // Manage empty space\r\n if (_src[0] === '') {\r\n _src.splice(0, 1);\r\n }\r\n rsSrc.push(_src[0]);\r\n rsWidth.push(_src[1]);\r\n }\r\n var wWidth = window.innerWidth;\r\n for (var j = 0; j < rsWidth.length; j++) {\r\n if (parseInt(rsWidth[j], 10) > wWidth) {\r\n src = rsSrc[j];\r\n break;\r\n }\r\n }\r\n return src;\r\n },\r\n isImageLoaded: function (img) {\r\n if (!img)\r\n return false;\r\n // During the onload event, IE correctly identifies any images that\r\n // weren’t downloaded as
1not complete. Others should too. Gecko-based\r\n // browsers act like NS4 in that they report this incorrectly.\r\n if (!img.complete) {\r\n return false;\r\n }\r\n // However, they do have two very useful properties: naturalWidth and\r\n // naturalHeight. These give the true size of the image. If it failed\r\n // to load, either of these should be zero.\r\n if (img.naturalWidth === 0) {\r\n return false;\r\n }\r\n // No other way of checking: assume it’s ok.\r\n return true;\r\n },\r\n getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) {\r\n var videoClass = '';\r\n if (_isVideo && _isVideo.youtube) {\r\n videoClass = 'lg-has-youtube';\r\n }\r\n else if (_isVideo && _isVideo.vimeo) {\r\n videoClass = 'lg-has-vimeo';\r\n }\r\n else {\r\n videoClass = 'lg-has-html5';\r\n }\r\n return \"<div class=\\\"lg-video-cont \" + videoClass + \"\\\" style=\\\"\" + videoContStyle + \"\\\">\\n <div class=\\\"lg-video-play-button\\\">
1\\n <svg\\n viewBox=\\\"0 0 20 20\\\"\\n preserveAspectRatio=\\\"xMidYMid\\\"\\n focusable=\\\"false\\\"\\n aria-labelledby=\\\"\" + playVideoString + \"\\\"\\n role=\\\"img\\\"\\n class=\\\"lg-video-play-icon\\\"\\n >\\n <title>\" + playVideoString + \"</title>\\n <polygon class=\\\"lg-video-play-icon-inner\\\" points=\\\"1,0 20,10 1,20\\\"></polygon>\\n </svg>\\n <svg class=\\\"lg-video-play-icon-bg\\\" viewBox=\\\"0 0 50 50\\\" focusable=\\\"false\\\">\\n <circle cx=\\\"50%\\\" cy=\\\"50%\\\" r=\\\"20\\\"></circle></svg>\\n <svg class=\\\"lg-video-play-icon-circle\\\" viewBox=\\\"0 0 50 50\\\" focusable=\\\"false\\\">\\n <circle cx=\\\"50%\\\" cy=\\\"50%\\\" r=\\\"20\\\"></circle>\\n </svg>\\n </div>\\n \" + (dummyImg || '') + \"\\n <img class=\\\"lg-object lg-video-poster\\\" src=\\\"\" + _poster + \"\\\" />\\n </div>\";\r\n },\r\n getFocusableElements: function (container) {\r\n var elements = container.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type=\"text\"]:not([disabled]), input[type=\"radio\"]:not([disabled]), input[type=\"checkbox\"]:not([disabled]), select:not([disabled])');\r\n var visibleElements = [].filter.call(elements, function (element) {\r\n var style = window.getComputedStyle(element);\r\n return style.display !== 'none' && style.visibility !== 'hidden';\r\n });\r\n return visibleElements;\r\n },\r\n /**\r\n * @desc Create dynamic elements array from gallery items when dynamic option is false\r\n * It helps to avoid frequent DOM interaction\r\n * and avoid multiple checks for dynamic elments\r\n *\r\n * @returns {Array} dynamicEl\r\n */\r\n getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) {\r\n var dynamicElements = [];\r\n var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps);\r\n [].forEach.call(items, function (item) {\r\n var dynamicEl = {};\r\n for (var i = 0; i < item.attributes.length; i++) {\r\n var attr = item.attributes[i];\r\n if (attr.specified) {\r\n var dynamicAttr = convertToData(attr.name);\r\n var label = '';\r\n if (availableDynamicOptions.indexOf(dynamicAttr) > -1) {\r\n label = dynamicAttr;\r\n }\r\n if (label) {\r\n dynamicEl[label] = attr.value;\r\n }\r\n }\r\n }\r\n var currentItem = $LG(item);\r\n var alt = currentItem.find('img').first().attr('alt');\r\n var title = currentItem.attr('title');\r\n var thumb = exThumbImage\r\n ? currentItem.attr(exThumbImage)\r\n : currentItem.find('img').first().attr('src');\r\n dynamicEl.thumb = thumb;\r\n if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) {\r\n dynamicEl.subHtml = title || alt || '';\r\n }\r\n dynamicEl.alt = alt || title || '';\r\n dynamicElements.push(dynamicEl);\r\n });\r\n return dynamicElements;\r\n },\r\n isMobile: function () {\r\n return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);\r\n },\r\n /**\r\n * @desc Check the given src is video\r\n * @param {String} src\r\n * @return {Object} video type\r\n * Ex:{ youtube : [\"//www.youtube.com/watch?v=c0asJgSyxcY\", \"c0asJgSyxcY\"] }\r\n *\r\n * @todo - this information can be moved to dynamicEl to avoid frequent calls\r\n */\r\n isVideo: function (src, isHTML5VIdeo, index) {\r\n if (!src) {\r\n if (isHTML5VIdeo) {\r\n return {\r\n html5: true,\r\n };\r\n }\r\n else {\r\n console.error('lightGallery :- data-src is not provided on slide item ' +\r\n (index + 1) +\r\n '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/');\r\n return;\r\n }\r\n }\r\n var youtube = src.match(/\\/\\/(?:www\\.)?youtu(?:\\.be|be\\.com|be-nocookie\\.com)\\/(?:watch\\?v=|embed\\/)?([a-z0-9\\-\\_\\%]+)([\\&|?][\\S]
1*)*/i);\r\n var vimeo = src.match(/\\/\\/(?:www\\.)?(?:player\\.)?vimeo.com\\/(?:video\\/)?([0-9a-z\\-_]+)(.*)?/i);\r\n var wistia = src.match(/https?:\\/\\/(.+)?(wistia\\.com|wi\\.st)\\/(medias|embed)\\/([0-9a-z\\-_]+)(.*)/);\r\n if (youtube) {\r\n return {\r\n youtube: youtube,\r\n };\r\n }\r\n else if (vimeo) {\r\n return {\r\n vimeo: vimeo,\r\n };\r\n }\r\n else if (wistia) {\r\n return {\r\n wistia: wistia,\r\n };\r\n }\r\n },\r\n};\n\n// @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio\r\n// @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html\r\n// Unique id for each gallery\r\nvar lgId = 0;\r\nvar LightGallery = /** @class */ (function () {\r\n function LightGallery(element, options) {\r\n this.lgOpened = false;\r\n this.index = 0;\r\n // lightGallery modules\r\n this.plugins = [];\r\n // false when lightGallery load first slide content;\r\n this.lGalleryOn = false;\r\n // True when a slide animation is in progress\r\n this.lgBusy = false;\r\n this.currentItemsInDom = [];\r\n // Scroll top value before lightGallery is opened\r\n this.prevScrollTop = 0;\r\n this.bodyPaddingRight = 0;\r\n this.isDummyImageRemoved = false;\r\n this.dragOrSwipeEnabled = false;\r\n this.mediaContainerPosition = {\r\n top: 0,\r\n bottom: 0,\r\n };\r\n if (!element) {\r\n return this;\r\n }\r\n lgId++;\r\n this.lgId = lgId;\r\n this.el = element;\r\n this.LGel = $LG(element);\r\n this.generateSettings(options);\r\n this.buildModules();\r\n // When using dynamic mode, ensure dynamicEl is an array\r\n if (this.settings.dynamic &&\r\n this.settings.dynamicEl !== undefined &&\r\n !Array.isArray(this.settings.dynamicEl)) {\r\n throw 'When using dynamic mode, you must also define dynamicEl as an Array.';\r\n }\r\n this.galleryItems = this.getItems();\r\n this.normalizeSettings();\r\n // Gallery items\r\n this.init();\r\n this.validateLicense();\r\n return this;\r\n }\r\n LightGallery.prototype.generateSettings = function (options) {\r\n // lightGallery settings\r\n this.settings = __assign(__assign({}, lightGalleryCoreSettings), options);\r\n if (this.settings.isMobile &&\r\n typeof this.settings.isMobile === 'function'\r\n ? this.settings.isMobile()\r\n : utils.isMobile()) {\r\n var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings);\r\n this.settings = __assign(__assign({}, this.settings), mobileSettings);\r\n }\r\n };\r\n LightGallery.prototype.normalizeSettings = function () {\r\n if (this.settings.slideEndAnimation) {\r\n this.settings.hideControlOnEnd = false;\r\n }\r\n if (!this.settings.closable) {\r\n this.settings.swipeToClose = false;\r\n }\r\n // And reset it on close to get the correct value next time\r\n this.zoomFromOrigin = this.settings.zoomFromOrigin;\r\n // At the moment, Zoom from image doesn't support dynamic options\r\n // @todo add zoomFromOrigin support for dynamic images\r\n if (this.settings.dynamic) {\r\n this.zoomFromOrigin = false;\r\n }\r\n if (!this.settings.container) {\r\n this.settings.container = document.body;\r\n }\r\n // settings.preload should not be grater than $item.length\r\n this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length);\r\n };\r\n LightGallery.prototype.init = function () {\r\n var _this = this;\r\n this.addSlideVideoInfo(this.galleryItems);\r\n this.buildStructure();\r\n this.LGel.trigger(lGEvents.init, {\r\n instance: this,\r\n });\r\n if (this.settings.keyPress) {\r\n this.keyPress();\r\n }\r\n setTimeout(function () {\r\n _this.enableDrag();\r\n _this.enableSwipe();\r\n _this.triggerPosterClick();\r\n }, 50);\r\n this.arrow();\r\n if (this.settings.mousewheel) {\r\n this.mousewheel();\r\n }\r\n if (!this.settings.dynamic) {\r\n this.openGalleryOnItemClick();\r\n }\r\n };\r\n LightGallery.prototype.openGalleryOnItemClick = function () {\r\n var _this = this;\r\n var _loop_1 = function (index) {\r\n var element = this_1.items[index];\r\n var $element = $LG(element);\r\n // Using different namespace for click because click event should not unbind if selector is same object('this')\r\n // @todo manage all event listners - should have namespace that represent element\r\n var uuid = lgQuery.generateUUID();\r\n $element\r\n .attr('data-lg-id', uuid)\r\n .on(\"click.lgcustom-item-\" + uuid, function (e) {\r\n e.preventDefault();\r\n var currentItemIndex = _this.settings.index || index;\r\n _this.openGallery(currentItemIndex, element);\r\n });\r\n };\r\n var this_1 = this;\r\n // Using for loop instead of using bubbling as the items can be any html element.\r\n for (var index = 0; index < this.items.length; index++) {\r\n _loop_1(index);\r\n }\r\n };\r\n /**\r\n * Module constructor\r\n * Modules are build incrementally.\r\n * Gallery should be opened only once all the modules are initialized.\r\n * use moduleBuildTimeout to make sure this\r\n */\r\n LightGallery.prototype.buildModules = function () {\r\n var _this = this;\r\n this.settings.plugins.forEach(function (plugin) {\r\n _this.plugins.push(new plugin(_this, $LG));\r\n });\r\n };\r\n LightGallery.prototype.validateLicense = function () {\r\n if (!this.settings.licenseKey) {\r\n console.error('Please provide a valid license key');\r\n }\r\n else if (this.settings.licenseKey === '0000-0000-000-0000') {\r\n console.warn(\"lightGallery: \" + this.settings.licenseKey + \" license key is not val
1id for production use\");\r\n }\r\n };\r\n LightGallery.prototype.getSlideItem = function (index) {\r\n return $LG(this.getSlideItemId(index));\r\n };\r\n LightGallery.prototype.getSlideItemId = function (index) {\r\n return \"#lg-item-\" + this.lgId + \"-\" + index;\r\n };\r\n LightGallery.prototype.getIdName = function (id) {\r\n return id + \"-\" + this.lgId;\r\n };\r\n LightGallery.prototype.getElementById = function (id) {\r\n return $LG(\"#\" + this.getIdName(id));\r\n };\r\n LightGallery.prototype.manageSingleSlideClassName = function () {\r\n if (this.galleryItems.length < 2) {\r\n this.outer.addClass('lg-single-item');\r\n }\r\n else {\r\n this.outer.removeClass('lg-single-item');\r\n }\r\n };\r\n LightGallery.prototype.buildStructure = function () {\r\n var _this = this;\r\n var container = this.$container && this.$container.get();\r\n if (container) {\r\n return;\r\n }\r\n var controls = '';\r\n var subHtmlCont = '';\r\n // Create controls\r\n if (this.settings.controls) {\r\n controls = \"<button type=\\\"button\\\" id=\\\"\" + this.getIdName('lg-prev') + \"\\\" aria-label=\\\"\" + this.settings.strings['previousSlide'] + \"\\\" class=\\\"lg-prev lg-icon\\\"> \" + this.settings.prevHtml + \" </button>\\n <button type=\\\"button\\\" id=\\\"\" + this.getIdName('lg-next') + \"\\\" aria-label=\\\"\" + this.settings.strings['nextSlide'] + \"\\\" class=\\\"lg-next lg-icon\\\"> \" + this.settings.nextHtml + \" </button>\";\r\n }\r\n if (this.settings.appendSubHtmlTo !== '.lg-item') {\r\n subHtmlCont =\r\n '<div class=\"lg-sub-html\" role=\"status\" aria-live=\"polite\"></div>';\r\n }\r\n var addClasses = '';\r\n if (this.settings.allowMediaOverlap) {\r\n // Do not remove space before last single quote\r\n addClasses += 'lg-media-overlap ';\r\n }\r\n var ariaLabelledby = this.settings.ariaLabelledby\r\n ? 'aria-labelledby=\"' + this.settings.ariaLabelledby + '\"'\r\n : '';\r\n var ariaDescribedby = this.settings.ariaDescribedby\r\n ? 'aria-describedby=\"' + this.settings.ariaDescribedby + '\"'\r\n : '';\r\n var containerClassName = \"lg-container \" + this.settings.addClass + \" \" + (document.body !== this.settings.container ? 'lg-inline' : '');\r\n var closeIcon = this.settings.closable && this.settings.showCloseIcon\r\n ? \"<button type=\\\"button\\\" aria-label=\\\"\" + this.settings.strings['closeGallery'] + \"\\\" id=\\\"\" + this.getIdName('lg-close') + \"\\\" class=\\\"lg-close lg-icon\\\"></button>\"\r\n : '';\r\n var maximizeIcon = this.settings.showMaximizeIcon\r\n ? \"<button type=\\\"button\\\" aria-label=\\\"\" + this.settings.strings['toggleMaximize'] + \"\\\" id=\\\"\" + this.getIdName('lg-maximize') + \"\\\" class=\\\"lg-maximize lg-icon\\\"></button>\"\r\n : '';\r\n var template = \"\\n <div class=\\\"\" + containerClassName + \"\\\" id=\\\"\" + this.getIdName('lg-container') + \"\\\" tabindex=\\\"-1\\\" aria-modal=\\\"true\\\" \" + ariaLabelledby + \" \" + ariaDescribedby + \" role=\\\"dialog\\\"\\n >\\n <div id=\\\"\" + this.getIdName('lg-backdrop') + \"\\\" class=\\\"lg-backdrop\\\"></div>\\n\\n <div id=\\\"\" + this.getIdName('lg-outer') + \"\\\" class=\\\"lg-outer lg-use-css3 lg-css3 lg-hide-items \" + addClasses + \" \\\">\\n\\n <div id=\\\"\" + this.getIdName('lg-content') + \"\\\" class=\\\"lg-content\\\">\\n <div id=\\\"\" + this.getIdName('lg-inner') + \"\\\" class=\\\"lg-inner\\\">\\n </div>\\n \" + controls + \"\\n </div>\\n <div id=\\\"\" + this.getIdName('lg-toolbar') + \"\\\" class=\\\"lg-toolbar lg-group\\\">\\n \" + maximizeIcon + \"\\n \" + closeIcon + \"\\n </div>\\n \" + (this.settings.appendSubHtmlTo === '.lg-outer'\r\n ? subHtmlCont\r\n : '') + \"\\n <div id=\\\"\" + this.getIdName('lg-components') + \"\\\" class=\\\"lg-components\\\">\\n \" + (this.settings.appendSubHtmlTo === '.lg-sub-html'\r\n ? subHtmlCont\r\n : '') + \"\\n </div>\\n </div>\\n </div>\\n \";\r\n $LG(this.settings.container).append(template);\r\n if (document.body !== this.settings.container) {\r\n $LG(this.settings.container).css('position', 'relative');\r\n }\r\n this.outer = this.getElementById('lg-outer');\r\n this.$lgComponents = this.getElementById('lg-components');\r\n this.$backdrop = this.getElementById('lg-backdrop');\r\n this.$container = this.getElementById('lg-container');\r\n this.$inner = this.getElementById('lg-inner');\r\n this.$content = this.getElementById('lg-content');\r\n this.$toolbar = this.getElementById('lg-toolbar');\r\n this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms');\r\n var outerClassNames = this.settings.mode + \" \";\r\n this.manageSingleSlideClassName();\r\n if (this.settings.enableDrag) {\r\n outerClassNames += 'lg-grab ';\r\n }\r\n this.outer.addClass(outerClassNames);\r\n this.$inner.css('transition-timing-function', this.settings.easing);\r\n this.$inner.css('transition-duration', this.settings.speed + 'ms');\r\n if (this.settings.download) {\r\n this.$toolbar.append(\"<a id=\\\"\" + this.getIdName('lg-download') + \"\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\" aria-label=\\\"\" + this.settings.strings['download'] + \"\\\" download class=\\\"lg-download lg-icon\\\"></a>\");\r\n }\r\n this.counter();\r\n $LG(window).on(\"resize.lg.global\" + this.lgId + \" orientationchange.lg.global\" + this.lgId, function () {\r\n _this.refreshOnResize();\r\n });\r\n this.hideBars();\r\n this.manageCloseGallery();\r\n this.toggleMaximize();\r\n this.initModules();\r\n };\r\n LightGallery.prototype.refreshOnResize = function () {\r\n if (this.lgOpened) {\r\n var currentGalleryItem = this.galleryItems[this.index];\r\n var __slideVideoInfo = currentGalleryItem.__slideVideoInfo;\r\n this.mediaContainerPosition = this.getMediaContainerPosition();\r\n var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom;\r\n this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize);\r\n if (__slideVideoInfo) {\r\n this.resizeVideoSlide(this.index, this.currentImageSize);\r\n }\r\n if (this.zoomFromOrigin && !this.isDummyImageRemoved) {\r\n var imgStyle = this.getDummyImgStyles(this.currentImageSize);\r\n this.outer\r\n .find('.lg-current .lg-dummy-img')\r\n .first()\r\n .attr('style', imgStyle);\r\n }\r\n this.LGel.trigger(lGEvents.containerResize);\r\n }\r\n };\r\n LightGallery.prototype.resizeVideoSlide = function (index, imageSize) {\r\n var lgVideoStyle = this.getVideoContStyle(imageSize);
1\r\n var currentSlide = this.getSlideItem(index);\r\n currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle);\r\n };\r\n /**\r\n * Update slides dynamically.\r\n * Add, edit or delete slides dynamically when lightGallery is opened.\r\n * Modify the current gallery items and pass it via updateSlides method\r\n * @note\r\n * - Do not mutate existing lightGallery items directly.\r\n * - Always pass new list of gallery items\r\n * - You need to take care of thumbnails outside the gallery if any\r\n * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method.\r\n * @param items Gallery items\r\n * @param index After the update operation, which slide gallery should navigate to\r\n * @category lGPublicMethods\r\n * @example\r\n * const plugin = lightGallery();\r\n *\r\n * // Adding slides dynamically\r\n * let galleryItems = [\r\n * // Access existing lightGallery items\r\n * // galleryItems are automatically generated internally from the gallery HTML markup\r\n * // or directly from galleryItems when dynamic gallery is used\r\n * ...plugin.galleryItems,\r\n * ...[\r\n * {\r\n * src: 'img/img-1.png',\r\n * thumb: 'img/thumb1.png',\r\n * },\r\n * ],\r\n * ];\r\n * plugin.updateSlides(\r\n * galleryItems,\r\n * plugin.index,\r\n * );\r\n *\r\n *\r\n * // Remove slides dynamically\r\n * galleryItems = JSON.parse(\r\n * JSON.stringify(updateSlideInstance.galleryItems),\r\n * );\r\n * galleryItems.shift();\r\n * updateSlideInstance.updateSlides(galleryItems, 1);\r\n * @see <a href=\"/demos/update-slides/\">Demo</a>\r\n */\r\n LightGallery.prototype.updateSlides = function (items, index) {\r\n if (this.index > items.length - 1) {\r\n this.index = items.length - 1;\r\n }\r\n if (items.length === 1) {\r\n this.index = 0;\r\n }\r\n if (!items.length) {\r\n this.closeGallery();\r\n return;\r\n }\r\n var currentSrc = this.galleryItems[index].src;\r\n this.galleryItems = items;\r\n this.updateControls();\r\n this.$inner.empty();\r\n this.currentItemsInDom = [];\r\n var _index = 0;\r\n // Find the current index based on source value of the slide\r\n this.galleryItems.some(function (galleryItem, itemIndex) {\r\n if (galleryItem.src === currentSrc) {\r\n _index = itemIndex;\r\n return true;\r\n }\r\n return false;\r\n });\r\n this.currentItemsInDom = this.organizeSlideItems(_index, -1);\r\n this.loadContent(_index, true);
1\r\n this.getSlideItem(_index).addClass('lg-current');\r\n this.index = _index;\r\n this.updateCurrentCounter(_index);\r\n this.LGel.trigger(lGEvents.updateSlides);\r\n };\r\n // Get gallery items based on multiple conditions\r\n LightGallery.prototype.getItems = function () {\r\n // Gallery items\r\n this.items = [];\r\n if (!this.settings.dynamic) {\r\n if (this.settings.selector === 'this') {\r\n this.items.push(this.el);\r\n }\r\n else if (this.settings.selector) {\r\n if (typeof this.settings.selector === 'string') {\r\n if (this.settings.selectWithin) {\r\n var selectWithin = $LG(this.settings.selectWithin);\r\n this.items = selectWithin\r\n .find(this.settings.selector)\r\n .get();\r\n }\r\n else {\r\n this.items = this.el.querySelectorAll(this.settings.selector);\r\n }\r\n }\r\n else {\r\n this.items = this.settings.selector;\r\n }\r\n }\r\n else {\r\n this.items = this.el.children;\r\n }\r\n return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage);\r\n }\r\n else {\r\n return this.settings.dynamicEl || [];\r\n }\r\n };\r\n LightGallery.prototype.shouldHideScrollbar = function () {\r\n return (this.settings.hideScrollbar &&\r\n document.body === this.settings.container);\r\n };\r\n LightGallery.prototype.hideScrollbar = function () {\r\n if (!this.shouldHideScrollbar()) {\r\n return;\r\n }\r\n this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight);\r\n var bodyRect = document.documentElement.getBoundingClientRect();\r\n var scrollbarWidth = window.innerWidth - bodyRect.width;\r\n $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px');\r\n $LG(document.body).addClass('lg-overlay-open');\r\n };\r\n LightGallery.prototype.resetScrollBar = function () {\r\n if (!this.shouldHideScrollbar()) {\r\n return;\r\n }\r\n $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px');\r\n $LG(document.body).removeClass('lg-overlay-open');\r\n };\r\n /**\r\n * Open lightGallery.\r\n * Open gallery with specific slide by passing index of the slide as parameter.\r\n * @category lGPublicMethods\r\n * @param {Number} index - index of the slide\r\n * @param {HTMLElement} element - Which image lightGallery should zoom from\r\n *\r\n * @example\r\n * const $dynamicGallery = document.getElementById('dynamic-gallery-demo');\r\n * const dynamicGallery = lightGallery($dynamicGallery, {\r\n * dynamic: true,\r\n * dynamicEl: [\r\n * {\r\n * src: 'img/1.jpg',\r\n * thumb: 'img/thumb-1.jpg',\r\n * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>',\r\n * },\r\n * ...\r\n * ],\r\n * });\r\n * $dynamicGallery.addEventListener('click', function () {\r\n * // Starts with third item.(Optional).\r\n * // This is useful if you want use dynamic mode with\r\n * // custom thumbnails (thumbnails outside gallery),\r\n * dynamicGallery.openGallery(2);\r\n * });\r\n *\r\n */\r\n LightGallery.prototype.openGallery = function (index, element) {\r\n var _this = this;\r\n if (index === void 0) { index = this.settings.index; }\r\n // prevent accidental double execution\r\n if (this.lgOpened)\r\n return;\r\n this.lgOpened = true;\r\n this.outer.removeClass('lg-hide-items');\r\n this.hideScrollbar();\r\n // Add display block, but still has opacity 0\r\n this.$container.addClass('lg-show');\r\n var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index);\r\n this.currentItemsInDom = itemsToBeInsertedToDom;\r\n var items = '';\r\n itemsToBeInsertedToDom.forEach(function (item) {\r\n items = items + (\"<div id=\\\"\" + item + \"\\\" class=\\\"lg-item\\\"></div>\");\r\n });\r\n this.$inner.append(items);\r\n this.addHtml(index);\r\n var transform = '';\r\n this.mediaContainerPosition = this.getMediaContainerPosition();\r\n var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
1\r\n if (!this.settings.allowMediaOverlap) {\r\n this.setMediaContainerPosition(top, bottom);\r\n }\r\n var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo;\r\n if (this.zoomFromOrigin && element) {\r\n this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize);\r\n transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize);\r\n }\r\n if (!this.zoomFromOrigin || !transform) {\r\n this.outer.addClass(this.settings.startClass);\r\n this.getSlideItem(index).removeClass('lg-complete');\r\n }\r\n var timeout = this.settings.zoomFromOrigin\r\n ? 100\r\n : this.settings.backdropDuration;\r\n setTimeout(function () {\r\n _this.outer.addClass('lg-components-open');\r\n }, timeout);\r\n this.index = index;\r\n this.LGel.trigger(lGEvents.beforeOpen);\r\n // add class lg-current to remove initial transition\r\n this.get
1SlideItem(index).addClass('lg-current');\r\n this.lGalleryOn = false;\r\n // Store the current scroll top value to scroll back after closing the gallery..\r\n this.prevScrollTop = $LG(window).scrollTop();\r\n setTimeout(function () {\r\n // Need to check both zoomFromOrigin and transform values as we need to set set the\r\n // default opening animation if user missed to add the lg-size attribute\r\n if (_this.zoomFromOrigin && transform) {\r\n var currentSlide_1 = _this.getSlideItem(index);\r\n currentSlide_1.css('transform', transform);\r\n setTimeout(function () {\r\n currentSlide_1\r\n .addClass('lg-start-progress lg-start-end-progress')\r\n .css('transition-duration', _this.settings.startAnimationDuration + 'ms');\r\n _this.outer.addClass('lg-zoom-from-image');\r\n });\r\n setTimeout(function () {\r\n currentSlide_1.css('transform', 'translate3d(0, 0, 0)');\r\n }, 100);\r\n }\r\n setTimeout(function () {\r\n _this.$backdrop.addClass('in');\r\n _this.$container.addClass('lg-show-in');\r\n }, 10);\r\n setTimeout(function () {\r\n if (_this.settings.trapFocus &&\r\n document.body === _this.settings.container) {\r\n _this.trapFocus();\r\n }\r\n }, _this.settings.backdropDuration + 50);\r\n // lg-visible class resets gallery opacity to 1\r\n if (!_this.zoomFromOrigin || !transform) {\r\n setTimeout(function () {\r\n _this.outer.addClass('lg-visible');\r\n }, _this.settings.backdropDuration);\r\n }\r\n // initiate slide function\r\n _this.slide(index, false, false, false);\r\n _this.LGel.trigger(lGEvents.afterOpen);\r\n });\r\n if (document.body === this.settings.container) {\r\n $LG('html').addClass('lg-on');\r\n }\r\n };\r\n /**\r\n * Note - Changing the position of the media on every slide transition creates a flickering effect.\r\n * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption.\r\n * if you have dynamic captions for each media,\r\n * you can provide an appropriate height for the captions via allowMediaOverlap option\r\n */\r\n LightGallery.prototype.getMediaContainerPosition = function () {\r\n if (this.settings.allowMediaOverlap) {\r\n return {\r\n top: 0,\r\n bottom: 0,\r\n };\r\n }\r\n var top = this.$toolbar.get().clientHeight || 0;\r\n var subHtml = this.outer.find('.lg-components .lg-sub-html').get();\r\n var captionHeight = this.settings.defaultCaptionHeight ||\r\n (subHtml && subHtml.clientHeight) ||\r\n 0;\r\n var thumbContainer = this.outer.find('.lg-thumb-outer').get();\r\n var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0;\r\n var bottom = thumbHeight + captionHeight;\r\n return {\r\n top: top,\r\n bottom: bottom,\r\n };\r\n };\r\n LightGallery.prototype.setMediaContainerPosition = function (top, bottom) {\r\n if (top === void 0) { top = 0; }\r\n if (bottom === void 0) { bottom = 0; }\r\n this.$content.css('top', top + 'px').css('bottom', bottom + 'px');\r\n };\r\n LightGallery.prototype.hideBars = function () {\r\n var _this = this;\r\n // Hide controllers if mouse doesn't move for some period\r\n setTimeout(function () {\r\n _this.outer.removeClass('lg-hide-items');\r\n if (_this.settings.hideBarsDelay > 0) {\r\n _this.outer.on('mousemove.lg click.lg touchstart.lg', function () {\r\n _this.outer.removeClass('lg-hide-items');\r\n clearTimeout(_this.hideBarTimeout);\r\n // Timeout will be cleared on each slide movement also\r\n _this.hideBarTimeout = setTimeout(function () {\r\n _this.outer.addClass('lg-hide-items');\r\n }, _this.settings.hideBarsDelay);\r\n });\r\n _this.outer.trigger('mousemove.lg');\r\n }\r\n }, this.settings.showBarsAfter);\r\n };\r\n LightGallery.prototype.initPictureFill = function ($img) {\r\n if (this.settings.supportLegacyBrowser) {\r\n try {\r\n picturefill({\r\n elements: [$img.get()],\r\n });\r\n }\r\n catch (e) {\r\n console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.');\r\n }\r\n }\r\n };\r\n /**\r\n * @desc Create image counter\r\n * Ex: 1/10\r\n */\r\n LightGallery.prototype.counter = function () {\r\n if (this.settings.counter) {\r\n var counterHtml = \"<div class=\\\"lg-counter\\\" role=\\\"status\\\" aria-live=\\\"polite\\\">
1\\n <span id=\\\"\" + this.getIdName('lg-counter-current') + \"\\\" class=\\\"lg-counter-current\\\">\" + (this.index + 1) + \" </span> /\\n <span id=\\\"\" + this.getIdName('lg-counter-all') + \"\\\" class=\\\"lg-counter-all\\\">\" + this.galleryItems.length + \" </span></div>\";\r\n this.outer.find(this.settings.appendCounterTo).append(counterHtml);\r\n }\r\n };\r\n /**\r\n * @desc add sub-html into the slide\r\n * @param {Number} index - index of the slide\r\n */\r\n LightGallery.prototype.addHtml = function (index) {\r\n var subHtml;\r\n var subHtmlUrl;\r\n if (this.galleryItems[index].subHtmlUrl) {\r\n subHtmlUrl = this.galleryItems[index].subHtmlUrl;\r\n }\r\n else {\r\n subHtml = this.galleryItems[index].subHtml;\r\n }\r\n if (!subHtmlUrl) {\r\n if (subHtml) {\r\n // get first letter of sub-html\r\n // if first letter starts with . or # get the html form the jQuery object\r\n var fL = subHtml.substring(0, 1);\r\n if (fL === '.' || fL === '#') {\r\n if (this.settings.subHtmlSelectorRelative &&\r\n !this.settings.dynamic) {\r\n subHtml = $LG(this.items)\r\n .eq(index)\r\n .find(subHtml)\r\n .first()\r\n .html();\r\n }\r\n else {\r\n subHtml = $LG(subHtml).first().html();\r\n }\r\n }\r\n }\r\n else {\r\n subHtml = '';\r\n }\r\n }\r\n if (this.settings.appendSubHtmlTo !== '.lg-item') {\r\n if (subHtmlUrl) {\r\n this.outer.find('.lg-sub-html').load(subHtmlUrl);\r\n }\r\n else {\r\n this.outer.find('.lg-sub-html').html(subHtml);\r\n }\r\n }\r\n else {\r\n var currentSlide = $LG(this.getSlideItemId(index));\r\n if (subHtmlUrl) {\r\n currentSlide.load(subHtmlUrl);\r\n }\r\n else {\r\n currentSlide.append(\"<div class=\\\"lg-sub-html\\\">\" + subHtml + \"</div>\");\r\n }\r\n }\r\n // Add lg-empty-html class if title doesn't exist\r\n if (typeof subHtml !== 'undefined' && subHtml !== null) {\r\n if (subHtml === '') {\r\n this.outer\r\n .find(this.settings.appendSubHtmlTo)\r\n .addClass('lg-empty-html');\r\n }\r\n else {\r\n this.outer\r\n .find(this.settings.appendSubHtmlTo)\r\n .removeClass('lg-empty-html');\r\n }\r\n }\r\n this.LGel.trigger(lGEvents.afterAppendSubHtml, {\r\n index: index,\r\n });\r\n };\r\n /**\r\n * @desc Preload slides\r\n * @param {Number} index - index of the slide\r\n * @todo preload not working for the first slide, Also, should work for the first and last slide as well\r\n */\r\n LightGallery.prototype.preload = function (index) {\r\n for (var i = 1; i <= this.settings.preload; i++) {\r\n if (i >= this.galleryItems.length - index) {\r\n break;\r\n }\r\n this.loadContent(index + i, false);\r\n }\r\n for (var j = 1; j <= this.settings.preload; j++) {\r\n if (index - j < 0) {\r\n break;\r\n }\r\n this.loadContent(index - j, false);\r\n }\r\n };\r\n LightGallery.prototype.getDummyImgStyles = function (imageSize) {\r\n if (!imageSize)\r\n return '';\r\n return \"width:\" + imageSize.width + \"px;\\n margin-left: -\" + imageSize.width / 2 + \"px;\\n margin-top: -\" + imageSize.height / 2 + \"px;\\n height:\" + imageSize.height + \"px\";\r\n };\r\n LightGallery.prototype.getVideoContStyle = function (imageSize) {\r\n if (!imageSize)\r\n return '';\r\n return \"width:\" + imageSize.width + \"px;\\n height:\" + imageSize.height + \"px\";\r\n };\r\n LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) {\r\n var $currentItem;\r\n if (!this.settings.dynamic) {\r\n $currentItem = $LG(this.items).eq(index);\r\n }\r\n if ($currentItem) {\r\n var _dummyImgSrc = void 0;\r\n if (!this.settings.exThumbImage) {\r\n _dummyImgSrc = $currentItem.find('img').first().attr('src');\r\n }\r\n else {\r\n _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage);\r\n }\r\n if (!_dummyImgSrc)\r\n return '';\r\n var imgStyle = this.getDummyImgStyles(this.currentImageSize);\r\n var dummyImgContent = \"<img \" + alt + \" style=\\\"\" + imgStyle + \"\\\" class=\\\"lg-dummy-img\\\" src=\\\"\" + _dummyImgSrc + \"\\\" />\";\r\n $currentSlide.addClass('lg-first-slide');\r\n this.outer.addClass('lg-first-slide-loading');\r\n return dummyImgContent;\r\n }\r\n return '';\r\n };\r\n LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) {\r\n var currentGalleryItem = this.galleryItems[index];\r\n var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;\r\n // Use the thumbnail as dummy image which will be resized to actual image size and\r\n // displayed on top of actual image\r\n var imgContent = '';\r\n var altAttr = alt ? 'alt=\"' + alt + '\"' : '';\r\n if (this.isFirstSlideWithZoomAnimation()) {\r\n imgContent = this.getDummyImageContent($currentSlide, index, altAttr);\r\n }\r\n else {\r\n imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources);\r\n }\r\n var imgMarkup = \"<picture class=\\\"lg-img-wrap\\\"> \" + imgContent + \"</picture>\";\r\n $currentSlide.prepend(imgMarkup);\r\n };\r\n LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) {\r\n var mediaObject = $
1slide.find('.lg-object').first();\r\n if (utils.isImageLoaded(mediaObject.get()) ||\r\n isHTML5VideoWithoutPoster) {\r\n onLoad();\r\n }\r\n else {\r\n mediaObject.on('load.lg error.lg', function () {\r\n onLoad && onLoad();\r\n });\r\n mediaObject.on('error.lg', function () {\r\n onError && onError();\r\n });\r\n }\r\n };\r\n /**\r\n *\r\n * @param $el Current slide item\r\n * @param index\r\n * @param delay Delay is 0 except first time\r\n * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin\r\n * @param isFirstSlide\r\n */\r\n LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) {\r\n var _this = this;\r\n this.onSlideObjectLoad(currentSlide, isHTML5VideoWithoutPoster, function () {\r\n _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide);\r\n }, function () {\r\n currentSlide.addClass('lg-complete lg-complete_');\r\n currentSlide.html('<span class=\"lg-error-msg\">' +\r\n _this.settings.strings['mediaLoadingFailed'] +\r\n '</span>');\r\n });\r\n };\r\n LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) {\r\n var _this = this;\r\n var currentGalleryItem = this.galleryItems[index];\r\n // Adding delay for video slides without poster for better performance and user experience\r\n // Videos should start playing once once the gallery is completely loaded\r\n var _speed = isFirstSlide &&\r\n this.get
1SlideType(currentGalleryItem) === 'video' &&\r\n !currentGalleryItem.poster\r\n ? speed\r\n : 0;\r\n setTimeout(function () {\r\n $currentSlide.addClass('lg-complete lg-complete_');\r\n _this.LGel.trigger(lGEvents.slideItemLoad, {\r\n index: index,\r\n delay: delay || 0,\r\n isFirstSlide: isFirstSlide,\r\n });\r\n }, _speed);\r\n };\r\n LightGallery.prototype.isFirstSlideWithZoomAnimation = function () {\r\n return !!(!this.lGalleryOn &&\r\n this.zoomFromOrigin &&\r\n this.currentImageSize);\r\n };\r\n // Add video slideInfo\r\n LightGallery.prototype.addSlideVideoInfo = function (items) {\r\n var _this = this;\r\n items.forEach(function (element, index) {\r\n element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index);\r\n if (element.__slideVideoInfo &&\r\n _this.settings.loadYouTubePoster &&\r\n !element.poster &&\r\n element.__slideVideoInfo.youtube) {\r\n element.poster = \"//img.youtube.com/vi/\" + element.__slideVideoInfo.youtube[1] + \"/maxresdefault.jpg\";\r\n }\r\n });\r\n };\r\n /**\r\n * Load slide content into slide.\r\n * This is used to load content into slides that is not visible too\r\n * @param {Number} index - index of the slide.\r\n * @param {Boolean} rec - if true call loadcontent() function again.\r\n */\r\n LightGallery.prototype.loadContent = function (index, rec) {\r\n var _this = this;\r\n var currentGalleryItem = this.galleryItems[index];\r\n var $currentSlide = $LG(this.getSlideItemId(index));\r\n var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;\r\n var src = currentGalleryItem.src;\r\n var video = currentGalleryItem.video;\r\n var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video;\r\n if (currentGalleryItem.responsive) {\r\n var srcDyItms = currentGalleryItem.responsive.split(',');\r\n src = utils.getResponsiveSrc(srcDyItms) || src;\r\n }\r\n var videoInfo = currentGalleryItem.__slideVideoInfo;\r\n var lgVideoStyle = '';\r\n var iframe = !!currentGalleryItem.iframe;\r\n var isFirstSlide = !this.lGalleryOn;\r\n // delay for adding complete class. it is 0 except first time.\r\n var delay = 0;\r\n if (isFirstSlide) {\r\n if (this.zoomFromOrigin && this.currentImageSize) {\r\n delay = this.settings.startAnimationDuration + 10;\r\n }\r\n else {\r\n delay = this.settings.backdropDuration + 10;\r\n }\r\n }\r\n if (!$currentSlide.hasClass('lg-loaded')) {\r\n if (videoInfo) {\r\n var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom;\r\n var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize);\r\n lgVideoStyle = this.getVideoContStyle(videoSize);\r\n }\r\n if (iframe) {\r\n var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle);\r\n $currentSlide.prepend(markup);\r\n }\r\n else if (poster) {\r\n var dummyImg = '';\r\n var hasStartAnimation = isFirstSlide &&\r\n this.zoomFromOrigin &&\r\n this.currentImageSize;\r\n if (hasStartAnimation) {\r\n dummyImg = this.getDummyImageContent($currentSlide, index, '');\r\n }\r\n var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo);\r\n $currentSlide.prepend(markup);\r\n }\r\n else if (videoInfo) {\r\n var markup = \"<div class=\\\"lg-video-cont \\\" style=\\\"\" + lgVideoStyle + \"\\\"></div>\";\r\n $currentSlide.prepend(markup);\r\n }\r\n else {\r\n this.setImgMarkup(src, $currentSlide, index);\r\n if (srcset || sources) {\r\n var $img = $currentSlide.find('.lg-object');\r\n this.initPictureFill($img);\r\n }\r\n }\r\n if (poster || videoInfo) {\r\n this.LGel.trigger(lGEvents.hasVideo, {\r\n index: index,\r\n src: src,\r\n html5Video: _html5Video,\r\n hasPoster: !!poster,\r\n });\r\n }\r\n this.LGel.trigger(lGEvents.afterAppendSlide, { index: index });\r\n if (this.lGalleryOn &&\r\n this.settings.appendSubHtmlTo === '.lg-item') {\r\n this.addHtml(index);\r\n }\r\n }\r\n // For first time add some delay for displaying the start animation.\r\n var _speed = 0;
1\r\n // Do not change the delay value because it is required for zoom plugin.\r\n // If gallery opened from direct url (hash) speed value should be 0\r\n if (delay && !$LG(document.body).hasClass('lg-from-hash')) {\r\n _speed = delay;\r\n }\r\n // Only for first slide and zoomFromOrigin is enabled\r\n if (this.isFirstSlideWithZoomAnimation()) {\r\n setTimeout(function () {\r\n $currentSlide\r\n .removeClass('lg-start-end-progress lg-start-progress')\r\n .removeAttr('style');\r\n }, this.settings.startAnimationDuration + 100);\r\n if (!$currentSlide.hasClass('lg-loaded')) {\r\n setTimeout(function () {\r\n if (_this.getSlideType(currentGalleryItem) === 'image') {\r\n var alt = currentGalleryItem.alt;\r\n var altAttr = alt ? 'alt=\"' + alt + '\"' : '';\r\n $currentSlide\r\n .find('.lg-img-wrap')\r\n .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources));\r\n if (srcset || sources) {\r\n var $img = $currentSlide.find('.lg-object');\r\n _this.initPictureFill($img);\r\n }\r\n }\r\n if (_this.getSlideType(currentGalleryItem) === 'image' ||\r\n (_this.getSlideType(currentGalleryItem) === 'video' &&\r\n poster)) {\r\n _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false);\r\n // load remaining slides once the slide is completely loaded\r\n _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () {\r\n _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);\r\n }, function () {\r\n _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);\r\n });\r\n }\r\n }, this.settings.startAnimationDuration + 100);\r\n }\r\n }\r\n // SLide content has been added to dom\r\n $currentSlide.addClass('lg-loaded');\r\n if (!this.isFirstSlideWithZoomAnimation() ||\r\n (this.getSlideType(currentGalleryItem) === 'video' && !poster)) {\r\n this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster));\r\n }\r\n // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling\r\n if ((!this.zoomFromOrigin || !this.currentImageSize) &&\r\n $currentSlide.hasClass('lg-complete_') &&\r\n !this.lGalleryOn) {\r\n setTimeout(function () {\r\n $currentSlide.addClass('lg-complete');\r\n }, this.settings.backdropDuration);\r\n }\r\n // Content loaded\r\n // Need to set lGalleryOn before calling preload function\r\n this.lGalleryOn = true;\r\n if (rec === true) {\r\n if (!$currentSlide.hasClass('lg-complete_')) {\r\n $currentSlide\r\n .find('.lg-object')\r\n .first()\r\n .on('load.lg error.lg', function () {\r\n _this.preload(index);\r\n });\r\n }\r\n else {\r\n this.preload(index);\r\n }\r\n }\r\n };\r\n /**\r\n * @desc Remove dummy image content and load next slides\r\n * Called only for the first time if zoomFromOrigin animation is enabled\r\n * @param index\r\n * @param $currentSlide\r\n * @param speed\r\n */\r\n LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) {\r\n var _this = this;\r\n setTimeout(function () {\r\n $currentSlide.find('.lg-dummy-img').remove();\r\n $currentSlide.removeClass('lg-first-slide');\r\n _this.outer.removeClass('lg-first-slide-loading');\r\n _this.isDummyImageRemoved = true;\r\n _this.preload(index);\r\n }, speed + 300);\r\n };\r\n LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) {\r\n var _this = this;\r\n if (numberOfItems === void 0) { numberOfItems = 0; }\r\n var itemsToBeInsertedToDom = [];\r\n // Minimum 2 items should be there\r\n var possibleNumberOfItems = Math.max(numberOfItems, 3);\r\n possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length);\r\n var prevIndexItem = \"lg-item-\" + this.lgId + \"-\" + prevIndex;\r\n if (this.galleryItems.length <= 3) {\r\n this.galleryItems.forEac
1h(function (_element, index) {\r\n itemsToBeInsertedToDom.push(\"lg-item-\" + _this.lgId + \"-\" + index);\r\n });\r\n return itemsToBeInsertedToDom;\r\n }\r\n if (index < (this.galleryItems.length - 1) / 2) {\r\n for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) {\r\n itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + idx);\r\n }\r\n var numberOfExistingItems = itemsToBeInsertedToDom.length;\r\n for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {\r\n itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + (index + idx + 1));\r\n }\r\n }\r\n else {\r\n for (var idx = index; idx <= this.galleryItems.length - 1 &&\r\n idx < index + possibleNumberOfItems / 2; idx++) {\r\n itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + idx);\r\n }\r\n var numberOfExistingItems = itemsToBeInsertedToDom.length;\r\n for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {\r\n itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + (index - idx - 1));\r\n }\r\n }\r\n if (this.settings.loop) {\r\n if (index === this.galleryItems.length - 1) {\r\n itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + 0);\r\n }\r\n else if (index === 0) {\r\n itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + (this.galleryItems.length - 1));\r\n }\r\n }\r\n if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) {\r\n itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + prevIndex);\r\n }\r\n return itemsToBeInsertedToDom;\r\n };\r\n LightGallery.prototype.organizeSlideItems = function (index, prevIndex) {\r\n var _this = this;\r\n var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom);\r\n itemsToBeInsertedToDom.forEach(function (item) {\r\n if (_this.currentItemsInDom.indexOf(item) === -1) {\r\n _this.$inner.append(\"<div id=\\\"\" + item + \"\\\" class=\\\"lg-item\\\"></div>\");\r\n }\r\n });\r\n this.currentItemsInDom.forEach(function (item) {\r\n if (itemsToBeInsertedToDom.indexOf(item) === -1) {\r\n $LG(\"#\" + item).remove();\r\n }\r\n });\r\n return itemsToBeInsertedToDom;\r\n };\r\n /**\r\n * Get previous index of the slide\r\n */\r\n LightGallery.prototype.getPreviousSlideIndex = function () {\r\n var prevIndex = 0;\r\n try {\r\n var currentItemId = this.outer\r\n .find('.lg-current')\r\n .first()\r\n .attr('id');\r\n prevIndex = parseInt(currentItemId.split('-')[3]) || 0;\r\n }\r\n catch (error) {\r\n prevIndex = 0;\r\n }\r\n return prevIndex;\r\n };\r\n LightGallery.prototype.setDownloadValue = function (index) {\r\n if (this.settings.download) {\r\n var currentGalleryItem = this.galleryItems[index];\r\n var hideDownloadBtn = currentGalleryItem.downloadUrl === false ||\r\n currentGalleryItem.downloadUrl === 'false';\r\n if (hideDownloadBtn) {\r\n this.outer.addClass('lg-hide-download');\r\n }\r\n else {\r\n var $download = this.getElementById('lg-download');\r\n this.outer.removeClass('lg-hide-download');\r\n $download.attr('href', currentGalleryItem.downloadUrl ||\r\n currentGalleryItem.src);\r\n if (currentGalleryItem.download) {\r\n $download.attr('download', currentGalleryItem.download);\r\n }\r\n }\r\n }\r\n };\r\n LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) {\r\n var _this = this;\r\n if (this.lGalleryOn) {\r\n previousSlideItem.addClass('lg-slide-progress');\r\n }\r\n setTimeout(function () {\r\n // remove all transitions\r\n _this.outer.addClass('lg-no-trans');\r\n _this.outer\r\n .find('.lg-item')\r\n .removeClass('lg-prev-slide lg-next-slide');\r\n if (direction === 'prev') {\r\n //prevslide\r\n currentSlideItem.addClass('lg-prev-slide');\r\n previousSlideItem.addClass('lg-next-slide');\r\n }\r\n else {\r\n // next slide\r\n currentSlideItem.addClass('lg-next-slide');\r\n previousSlideItem.addClass('lg-prev-slide');\r\n }\r\n // give 50 ms for browser to add/remove class\r\n setTimeout(function () {\r\n _this.outer.find('.lg-item').removeClass('lg-current');\r\n currentSlideItem.addClass('lg-current');\r\n // reset all transitions\r\n _this.outer.removeClass('lg-no-trans');\r\n }, 50);\r\n }, this.lGalleryOn ? this.settings.slideDelay : 0);\r\n };\r\n /**\r\n * Goto a specific slide.\r\n * @param {Number} index - index of the slide\r\n * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag\r\n * @param {Boolean} fromThumb - true if slide function called via thumbnail click\r\n * @param {String} direction - Direction of the slide(next/prev)\r\n * @category lGPublicMethods\r\n * @example\r\n * const plugin = lightGallery();\r\n * // to go to 3rd slide\r\n * plugin.slide(2);\r\n *\r\n */\r\n LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) {\r\n var _this = this;\r\n var prevIndex = this.getPreviousSlideIndex();\r\n this.currentItemsInDom = this.organizeSlideItems(index, prevIndex);\r\n // Prevent multiple call, Required for hsh plugin\r\n if (this.lGalleryOn && prevIndex === index) {\r\n return;\r\n }\r\n var numberOfGalleryItems = this.galleryItems.length;\r\n if (!this.lgBusy) {\r\n if (this.settings.counter) {\r\n this.updateCurrentCounter(index);\r\n }
1\r\n var currentSlideItem = this.getSlideItem(index);\r\n var previousSlideItem_1 = this.getSlideItem(prevIndex);\r\n var currentGalleryItem = this.galleryItems[index];\r\n var videoInfo = currentGalleryItem.__slideVideoInfo;\r\n this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem));\r\n this.setDownloadValue(index);\r\n if (videoInfo) {\r\n var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom;\r\n var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize);\r\n this.resizeVideoSlide(index, videoSize);\r\n }\r\n this.LGel.trigger(lGEvents.beforeSlide, {\r\n prevIndex: prevIndex,\r\n index: index,\r\n fromTouch: !!fromTouch,\r\n fromThumb: !!fromThumb,\r\n });\r\n this.lgBusy = true;\r\n clearTimeout(this.hideBarTimeout);\r\n this.arrowDisable(index);\r\n if (!direction) {\r\n if (index < prevIndex) {\r\n direction = 'prev';\r\n }\r\n else if (index > prevIndex) {\r\n direction = 'next';\r\n }\r\n }\r\n if (!fromTouch) {\r\n this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1);\r\n }\r\n else {\r\n this.outer\r\n .find('.lg-item')\r\n .removeClass('lg-prev-slide lg-current lg-next-slide');\r\n var touchPrev = void 0;\r\n var touchNext = void 0;\r\n if (numberOfGalleryItems > 2) {\r\n touchPrev = index - 1;\r\n touchNext = index + 1;\r\n if (index === 0 && prevIndex === numberOfGalleryItems - 1) {\r\n // next slide\r\n touchNext = 0;\r\n touchPrev = numberOfGalleryItems - 1;\r\n }\r\n else if (index === numberOfGalleryItems - 1 &&\r\n prevIndex === 0) {\r\n // prev slide\r\n touchNext = 0;\r\n touchPrev = numberOfGalleryItems - 1;\r\n }\r\n }\r\n else {\r\n touchPrev = 0;\r\n touchNext = 1;\r\n }\r\n if (direction === 'prev') {\r\n this.get
1SlideItem(touchNext).addClass('lg-next-slide');\r\n }\r\n else {\r\n this.getSlideItem(touchPrev).addClass('lg-prev-slide');\r\n }\r\n currentSlideItem.addClass('lg-current');\r\n }\r\n // Do not put load content in set timeout as it needs to load immediately when the gallery is opened\r\n if (!this.lGalleryOn) {\r\n this.loadContent(index, true);\r\n }\r\n else {\r\n setTimeout(function () {\r\n _this.loadContent(index, true);\r\n // Add title if this.settings.appendSubHtmlTo === lg-sub-html\r\n if (_this.settings.appendSubHtmlTo !== '.lg-item') {\r\n _this.addHtml(index);\r\n }\r\n }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay));\r\n }\r\n setTimeout(function () {\r\n _this.lgBusy = false;\r\n previousSlideItem_1.removeClass('lg-slide-progress');\r\n _this.LGel.trigger(lGEvents.afterSlide, {\r\n prevIndex: prevIndex,\r\n index: index,\r\n fromTouch: fromTouch,\r\n fromThumb: fromThumb,\r\n });\r\n }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay));\r\n }\r\n this.index = index;\r\n };\r\n LightGallery.prototype.updateCurrentCounter = function (index) {\r\n this.getElementById('lg-counter-current').html(index + 1 + '');\r\n };\r\n LightGallery.prototype.updateCounterTotal = function () {\r\n this.getElementById('lg-counter-all').html(this.galleryItems.length + '');\r\n };\r\n LightGallery.prototype.getSlideType = function (item) {\r\n if (item.__slideVideoInfo) {\r\n return 'video';\r\n }\r\n else if (item.iframe) {\r\n return 'iframe';\r\n }\r\n else {\r\n return 'image';\r\n }\r\n };\r\n LightGallery.prototype.touchMove = function (startCoords, endCoords, e) {\r\n var distanceX = endCoords.pageX
1- startCoords.pageX;\r\n var distanceY = endCoords.pageY - startCoords.pageY;\r\n var allowSwipe = false;\r\n if (this.swipeDirection) {\r\n allowSwipe = true;\r\n }\r\n else {\r\n if (Math.abs(distanceX) > 15) {\r\n this.swipeDirection = 'horizontal';\r\n allowSwipe = true;\r\n }\r\n else if (Math.abs(distanceY) > 15) {\r\n this.swipeDirection = 'vertical';\r\n allowSwipe = true;\r\n }\r\n }\r\n if (!allowSwipe) {\r\n return;\r\n }\r\n var $currentSlide = this.getSlideItem(this.index);\r\n if (this.swipeDirection === 'horizontal') {\r\n e === null || e === void 0 ? void 0 : e.preventDefault();\r\n // reset opacity and transition duration\r\n this.outer.addClass('lg-dragging');\r\n // move current slide\r\n this.setTranslate($currentSlide, distanceX, 0);\r\n // move next and prev slide with current slide\r\n var width = $currentSlide.get().offsetWidth;\r\n var slideWidthAmount = (width * 15) / 100;\r\n var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100);\r\n this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0);\r\n this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0);\r\n }\r\n else if (this.swipeDirection === 'vertical') {\r\n if (this.settings.swipeToClose) {\r\n e === null || e === void 0 ? void 0 : e.preventDefault();\r\n this.$container.addClass('lg-dragging-vertical');\r\n var opacity = 1 - Math.abs(distanceY) / window.innerHeight;\r\n this.$backdrop.css('opacity', opacity);\r\n var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2);\r\n this.setTranslate($currentSlide, 0, distanceY, scale, scale);\r\n if (Math.abs(distanceY) > 100) {\r\n this.outer\r\n .addClass('lg-hide-items')\r\n .removeClass('lg-components-open');\r\n }\r\n }\r\n }\r\n };\r\n LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) {\r\n var _this = this;\r\n var distance;\r\n // keep slide animation for any mode while dragg/swipe\r\n if (this.settings.mode !== 'lg-slide') {\r\n this.outer.addClass('lg-slide');\r\n }\r\n // set transition duration\r\n setTimeout(function () {\r\n _this.$container.removeClass('lg-dragging-vertical');\r\n _this.outer\r\n .removeClass('lg-dragging lg-hide-items')\r\n .addClass('lg-components-open');\r\n var triggerClick = true;\r\n if (_this.swipeDirection === 'horizontal') {\r\n distance = endCoords.pageX
1- startCoords.pageX;\r\n var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX);\r\n if (distance < 0 &&\r\n distanceAbs > _this.settings.swipeThreshold) {\r\n _this.goToNextSlide(true);\r\n triggerClick = false;\r\n }\r\n else if (distance > 0 &&\r\n distanceAbs > _this.settings.swipeThreshold) {\r\n _this.goToPrevSlide(true);\r\n triggerClick = false;\r\n }\r\n }\r\n else if (_this.swipeDirection === 'vertical') {\r\n distance = Math.abs(endCoords.pageY - startCoords.pageY);\r\n if (_this.settings.closable &&\r\n _this.settings.swipeToClose &&\r\n distance > 100) {\r\n _this.closeGallery();\r\n return;\r\n }\r\n else {\r\n _this.$backdrop.css('opacity', 1);\r\n }\r\n }\r\n _this.outer.find('.lg-item').removeAttr('style');\r\n if (triggerClick &&\r\n Math.abs(endCoords.pageX
1- startCoords.pageX) < 5) {\r\n // Trigger click if distance is less than 5 pix\r\n var target = $LG(event.target);\r\n if (_this.isPosterElement(target)) {\r\n _this.LGel.trigger(lGEvents.posterClick);\r\n }\r\n }\r\n _this.swipeDirection = undefined;\r\n });\r\n // remove slide class once drag/swipe is completed if mode is not slide\r\n setTimeout(function () {\r\n if (!_this.outer.hasClass('lg-dragging') &&\r\n _this.settings.mode !== 'lg-slide') {\r\n _this.outer.removeClass('lg-slide');\r\n }\r\n }, this.settings.speed + 100);\r\n };\r\n LightGallery.prototype.enableSwipe = function () {\r\n var _this = this;\r\n var startCoords = {};\r\n var endCoords = {};\r\n var isMoved = false;\r\n var isSwiping = false;\r\n if (this.settings.enableSwipe) {\r\n this.$inner.on('touchstart.lg', function (e) {\r\n _this.dragOrSwipeEnabled = true;\r\n var $item = _this.getSlideItem(_this.index);\r\n if (($LG(e.target).hasClass('lg-item') ||\r\n $item.get().contains(e.target)) &&\r\n !_this.outer.hasClass('lg-zoomed') &&\r\n !_this.lgBusy &&\r\n e.touches.length === 1) {\r\n isSwiping = true;\r\n _this.touchAction = 'swipe';\r\n _this.manageSwipeClass();\r\n startCoords = {\r\n pageX: e.touches[0].pageX,\r\n pageY: e.touches[0].pageY,\r\n };\r\n }\r\n });\r\n this.$inner.on('touchmove.lg', function (e) {\r\n if (isSwiping &&\r\n _this.touchAction === 'swipe' &&\r\n e.touches.length === 1) {\r\n endCoords = {\r\n pageX: e.touches[0].pageX,\r\n pageY: e.touches[0].pageY,\r\n };\r\n _this.touchMove(startCoords, endCoords, e);\r\n isMoved = true;\r\n }\r\n });\r\n this.$inner.on('touchend.lg', function (event) {\r\n if (_this.touchAction === 'swipe') {\r\n if (isMoved) {\r\n isMoved = false;\r\n _this.touchEnd(endCoords, startCoords, event);\r\n }\r\n else if (isSwiping) {\r\n var target = $LG(event.target);\r\n if (_this.isPosterElement(target)) {\r\n _this.LGel.trigger(lGEvents.posterClick);\r\n }\r\n }\r\n _this.touchAction = undefined;\r\n isSwiping = false;\r\n }\r\n });\r\n }\r\n };\r\n LightGallery.prototype.enableDrag = function () {\r\n var _this = this;\r\n var startCoords = {};\r\n var endCoords = {};\r\n var isDraging = false;\r\n var isMoved = false;\r\n if (this.settings.enableDrag) {\r\n this.outer.on('mousedown.lg', function (e) {\r\n _this.dragOrSwipeEnabled = true;\r\n var $item = _this.getSlideItem(_this.index);\r\n if ($LG(e.target).hasClass('lg-item') ||\r\n $item.get().contains(e.target)) {\r\n if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) {\r\n e.preventDefault();\r\n if (!_this.lgBusy) {\r\n _this.manageSwipeClass();\r\n startCoords = {\r\n pageX: e.pageX,\r\n pageY: e.pageY,\r\n };\r\n isDraging = true;\r\n // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723\r\n _this.outer.get().scrollLeft += 1;\r\n _this.outer.get().scrollLeft -= 1;\r\n // *\r\n _this.outer\r\n .removeClass('lg-grab')\r\n .addClass('lg-grabbing');\r\n _this.LGel.trigger(lGEvents.dragStart);\r\n }\r\n }\r\n }\r\n });\r\n $LG(window).on(\"mousemove.lg.global\" + this.lgId, function (e) {\r\n if (isDraging && _this.lgOpened) {\r\n isMoved = true;\r\n endCoords = {\r\n pageX: e.pageX,\r\n pageY: e.pageY,\r\n };\r\n _this.touchMove(startCoords, endCoords);\r\n _this.LGel.trigger(lGEvents.dragMove);\r\n }\r\n });\r\n $LG(window).on(\"mouseup.lg.global\" + this.lgId, function (event) {\r\n if (!_this.lgOpened) {\r\n return;\r\n }\r\n var target = $LG(event.target);\r\n if (isMoved) {\r\n isMoved = false;\r\n _this.touchEnd(endCoords, startCoords, event);\r\n _this.LGel.trigger(lGEvents.dragEnd);\r\n }\r\n else if (_this.isPosterElement(target)) {\r\n _this.LGel.trigger(lGEvents.posterClick);\r\n }\r\n // Prevent execution on click\r\n if (isDraging) {\r\n isDraging = false;\r\n _this.outer.removeClass('lg-grabbing').addClass('lg-grab');\r\n }\r\n });\r\n }\r\n };\r\n LightGallery.prototype.triggerPosterClick = function () {\r\n var _this = this;\r\n this.$inner.on('click.lg', function (event) {\r\n if (!_this.dragOrSwipeEnabled &&\r\n _this.isPosterElement($LG(event.target))) {\r\n _this.LGel.trigger(lGEvents.posterClick);\r\n }\r\n });\r\n };\r\n LightGallery.prototype.manageSwipeClass = function () {\r\n var _touchNext = this.index + 1;\r\n var _touchPrev = this.index - 1;\r\n if (this.settings.loop && this.galleryItems.length > 2) {\r\n if (this.index === 0) {\r\n _touchPrev = this.galleryItems.length - 1;\r\n }\r\n else if (this.index === this.galleryItems.length - 1) {\r\n _touchNext = 0;\r\n }\r\n }\r\n this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide');\r\n if (_touchPrev >
1 -1) {\r\n this.getSlideItem(_touchPrev).addClass('lg-prev-slide');\r\n }\r\n this.getSlideItem(_touchNext).addClass('lg-next-slide');\r\n };\r\n /**\r\n * Go to next slide\r\n * @param {Boolean} fromTouch - true if slide function called via touch event\r\n * @category lGPublicMethods\r\n * @example\r\n * const plugin = lightGallery();\r\n * plugin.goToNextSlide();\r\n * @see <a href=\"/demos/methods/\">Demo</a>\r\n */\r\n LightGallery.prototype.goToNextSlide = function (fromTouch) {\r\n var _this = this;\r\n var _loop = this.settings.loop;\r\n if (fromTouch && this.galleryItems.length < 3) {\r\n _loop = false;\r\n }\r\n if (!this.lgBusy) {\r\n if (this.index + 1 < this.galleryItems.length) {\r\n this.index++;\r\n this.LGel.trigger(lGEvents.beforeNextSlide, {\r\n index: this.index,\r\n });\r\n this.slide(this.index, !!fromTouch, false, 'next');\r\n }\r\n else {\r\n if (_loop) {\r\n this.index = 0;\r\n this.LGel.trigger(lGEvents.beforeNextSlide, {\r\n index: this.index,\r\n });\r\n this.slide(this.index, !!fromTouch, false, 'next');\r\n }\r\n else if (this.settings.slideEndAnimation && !fromTouch) {\r\n this.outer.addClass('lg-right-end');\r\n setTimeout(function () {\r\n _this.outer.removeClass('lg-right-end');\r\n }, 400);\r\n }\r\n }\r\n }\r\n };\r\n /**\r\n * Go to previous slides\r\n * @param {Boolean} fromTouch - true if slide function called via touch event\r\n * @category lGPublicMethods\r\n * @example\r\n * const plugin = lightGallery({});\r\n * plugin.goToPrevSlide();\r\n * @see <a href=\"/demos/methods/\">Demo</a>\r\n *\r\n */\r\n LightGallery.prototype.goToPrevSlide = function (fromTouch) {\r\n var _this = this;\r\n var _loop = this.settings.loop;\r\n if (fromTouch && this.galleryItems.length < 3) {\r\n _loop = false;\r\n }\r\n if (!this.lgBusy) {\r\n if (this.index > 0) {\r\n this.index--;\r\n this.LGel.trigger(lGEvents.beforePrevSlide, {\r\n index: this.index,\r\n fromTouch: fromTouch,\r\n });\r\n this.slide(this.index, !!fromTouch, false, 'prev');\r\n }\r\n else {\r\n if (_loop) {\r\n this.index = this.galleryItems.length - 1;\r\n this.LGel.trigger(lGEvents.beforePrevSlide, {\r\n index: this.index,\r\n fromTouch: fromTouch,\r\n });\r\n this.slide(this.index, !!fromTouch, false, 'prev');\r\n }\r\n else if (this.settings.slideEndAnimation && !fromTouch) {\r\n this.outer.addClass('lg-left-end');\r\n setTimeout(function () {\r\n _this.outer.removeClass('lg-left-end');\r\n }, 400);\r\n }\r\n }\r\n }\r\n };\r\n LightGallery.prototype.keyPress = function () {\r\n var _this = this;\r\n $LG(window).on(\"keydown.lg.global\" + this.lgId, function (e) {\r\n if (_this.lgOpened &&\r\n _this.settings.escKey === true &&\r\n e.keyCode === 27) {\r\n e.preventDefault();\r\n if (_this.settings.allowMediaOverlap &&\r\n _this.outer.hasClass('lg-can-toggle') &&\r\n _this.outer.hasClass('lg-components-open')) {\r\n _this.outer.removeClass('lg-components-open');\r\n }\r\n else {\r\n _this.closeGallery();\r\n }\r\n }\r\n if (_this.lgOpened && _this.galleryItems.length > 1) {\r\n if (e.keyCode === 37) {\r\n e.preventDefault();\r\n _this.goToPrevSlide();\r\n }\r\n if (e.keyCode === 39) {\r\n e.preventDefault();\r\n _this.goToNextSlide();\r\n }\r\n }\r\n });\r\n };\r\n LightGallery.prototype.arrow = function () {\r\n var _this = this;\r\n this.getElementById('lg-prev').on('click.lg', function () {\r\n _this.goToPrevSlide();\r\n });\r\n this.getElementById('lg-next').on('click.lg', function () {\r\n _this.goToNextSlide();\r\n });\r\n };\r\n LightGallery.prototype.arrowDisable = function (index) {\r\n // Disable arrows if settings.hideControlOnEnd is true\r\n if (!this.settings.loop && this.settings.hideControlOnEnd) {\r\n var $prev = this.getElementById('lg-prev');\r\n var $next = this.getElementById('lg-next');\r\n if (index + 1 === this.galleryItems.length) {\r\n $next.attr('disabled', 'disabled').addClass('disabled');\r\n }\r\n else {\r\n $next.removeAttr('disabled').removeClass('disabled');\r\n }\r\n if (index === 0) {\r\n $prev.attr('disabled', 'disabled').addClass('disabled');\r\n }\r\n else {\r\n $prev.removeAttr('disabled').removeClass('disabled');\r\n }\r\n }\r\n };\r\n LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) {\r\n if (scaleX === void 0) { scaleX = 1; }\r\n if (scaleY === void 0) { scaleY = 1; }\r\n $el.css('transform', 'translate3d(' +\r\n xValue +\r\n 'px, ' +\r\n yValue +\r\n 'px, 0px) scale3d(' +\r\n scaleX +\r\n ', ' +\r\n scaleY +\r\n ', 1)');\r\n };\r\n LightGallery.prototype.mousewheel = function () {\r\n var _this = this;\r\n var lastCall = 0;\r\n this.outer.on('wheel.lg', function (e) {\r\n if (!e.deltaY || _this.galleryItems.length < 2) {\r\n return;\r\n }\r\n e.preventDefault();\r\n var now = new Date().getTime();\r\n if (now - lastCall < 1000) {\r\n return;\r\n }
1\r\n lastCall = now;\r\n if (e.deltaY > 0) {\r\n _this.goToNextSlide();\r\n }\r\n else if (e.deltaY < 0) {\r\n _this.goToPrevSlide();\r\n }\r\n });\r\n };\r\n LightGallery.prototype.isSlideElement = function (target) {\r\n return (target.hasClass('lg-outer') ||\r\n target.hasClass('lg-item') ||\r\n target.hasClass('lg-img-wrap'));\r\n };\r\n LightGallery.prototype.isPosterElement = function (target) {\r\n var playButton = this.getSlideItem(this.index)\r\n .find('.lg-video-play-button')\r\n .get();\r\n return (target.hasClass('lg-video-poster') ||\r\n target.hasClass('lg-video-play-button') ||\r\n (playButton && playButton.contains(target.get())));\r\n };\r\n /**\r\n * Maximize minimize inline gallery.\r\n * @category lGPublicMethods\r\n */\r\n LightGallery.prototype.toggleMaximize = function () {\r\n var _this = this;\r\n this.getElementById('lg-maximize').on('click.lg', function () {\r\n _this.$container.toggleClass('lg-inline');\r\n _this.refreshOnResize();\r\n });\r\n };\r\n LightGallery.prototype.invalidateItems = function () {\r\n for (var index = 0; index < this.items.length; index++) {\r\n var element = this.items[index];\r\n var $element = $LG(element);\r\n $element.off(\"click.lgcustom-item-\" + $element.attr('data-lg-id'));\r\n }\r\n };\r\n LightGallery.prototype.trapFocus = function () {\r\n var _this = this;\r\n this.$container.get().focus({\r\n preventScroll: true,\r\n });\r\n $LG(window).on(\"keydown.lg.global\" + this.lgId, function (e) {\r\n if (!_this.lgOpened) {\r\n return;\r\n }\r\n var isTabPressed = e.key === 'Tab' || e.keyCode === 9;\r\n if (!isTabPressed) {\r\n return;\r\n }\r\n var focusableEls = utils.getFocusableElements(_this.$container.get());\r\n var firstFocusableEl = focusableEls[0];\r\n var lastFocusableEl = focusableEls[focusableEls.length - 1];\r\n if (e.shiftKey) {\r\n if (document.activeElement === firstFocusableEl) {\r\n lastFocusableEl.focu
1s();\r\n e.preventDefault();\r\n }\r\n }\r\n else {\r\n if (document.activeElement === lastFocusableEl) {\r\n firstFocusableEl.focus();\r\n e.preventDefault();\r\n }\r\n }\r\n });\r\n };\r\n LightGallery.prototype.manageCloseGallery = function () {\r\n var _this = this;\r\n if (!this.settings.closable)\r\n return;\r\n var mousedown = false;\r\n this.getElementById('lg-close').on('click.lg', function () {\r\n _this.closeGallery();\r\n });\r\n if (this.settings.closeOnTap) {\r\n // If you drag the slide and release outside gallery gets close on chrome\r\n // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer\r\n this.outer.on('mousedown.lg', function (e) {\r\n var target = $LG(e.target);\r\n if (_this.isSlideElement(target)) {\r\n mousedown = true;\r\n }\r\n else {\r\n mousedown = false;\r\n }\r\n });\r\n this.outer.on('mousemove.lg', function () {\r\n mousedown = false;\r\n });\r\n this.outer.on('mouseup.lg', function (e) {\r\n var target = $LG(e.target);\r\n if (_this.isSlideElement(target) && mousedown) {\r\n if (!_this.outer.hasClass('lg-dragging')) {\r\n _this.closeGallery();\r\n }\r\n }\r\n });\r\n }\r\n };\r\n /**\r\n * Close lightGallery if it is opened.\r\n *\r\n * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery\r\n * @return returns the estimated time to close gallery completely including the close animation duration\r\n * @category lGPublicMethods\r\n * @example\r\n * const plugin = lightGallery();\r\n * plugin.closeGallery();\r\n *\r\n */\r\n LightGallery.prototype.closeGallery = function (force) {\r\n var _this = this;\r\n if (!this.lgOpened || (!this.settings.closable && !force)) {\r\n return 0;\r\n }\r\n this.LGel.trigger(lGEvents.beforeClose);\r\n if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) {\r\n $LG(window).scrollTop(this.prevScrollTop);\r\n }\r\n var currentItem = this.items[this.index];\r\n var transform;\r\n if (this.zoomFromOrigin && currentItem) {\r\n var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom;\r\n var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster;\r\n var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize);\r\n transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize);\r\n }\r\n if (this.zoomFromOrigin && transform) {\r\n this.outer.addClass('lg-closing lg-zoom-from-image');
1\r\n this.getSlideItem(this.index)\r\n .addClass('lg-start-end-progress')\r\n .css('transition-duration', this.settings.startAnimationDuration + 'ms')\r\n .css('transform', transform);\r\n }\r\n else {\r\n this.outer.addClass('lg-hide-items');\r\n // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true\r\n // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts\r\n this.outer.removeClass('lg-zoom-from-image');\r\n }\r\n // Unbind all events added by lightGallery\r\n // @todo\r\n //this.$el.off('.lg.tm');\r\n this.destroyModules();\r\n this.lGalleryOn = false;\r\n this.isDummyImageRemoved = false;\r\n this.zoomFromOrigin = this.settings.zoomFromOrigin;\r\n clearTimeout(this.hideBarTimeout);\r\n this.hideBarTimeout = false;\r\n $LG('html').removeClass('lg-on');\r\n this.outer.removeClass('lg-visible lg-components-open');\r\n // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity.\r\n this.$backdrop.removeClass('in').css('opacity', 0);\r\n var removeTimeout = this.zoomFromOrigin && transform\r\n ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration)\r\n : this.settings.backdropDuration;\r\n this.$container.removeClass('lg-show-in');\r\n // Once the closign animation is completed and gallery is invisible\r\n setTimeout(function () {\r\n if (_this.zoomFromOrigin && transform) {\r\n _this.outer.removeClass('lg-zoom-from-image');\r\n }\r\n _this.$container.removeClass('lg-show');\r\n // Reset scrollbar\r\n _this.resetScrollBar();\r\n // Need to remove inline opacity as it is used in the stylesheet as well\r\n _this.$backdrop\r\n .removeAttr('style')\r\n .css('transition-duration', _this.settings.backdropDuration + 'ms');\r\n _this.outer.removeClass(\"lg-closing \" + _this.settings.startClass);
1\r\n _this.getSlideItem(_this.index).removeClass('lg-start-end-progress');\r\n _this.$inner.empty();\r\n if (_this.lgOpened) {\r\n _this.LGel.trigger(lGEvents.afterClose, {\r\n instance: _this,\r\n });\r\n }\r\n if (_this.$container.get()) {\r\n _this.$container.get().blur();\r\n }\r\n _this.lgOpened = false;\r\n }, removeTimeout + 100);\r\n return removeTimeout + 100;\r\n };\r\n LightGallery.prototype.initModules = function () {\r\n this.plugins.forEach(function (module) {\r\n try {\r\n module.init();\r\n }\r\n catch (err) {\r\n console.warn(\"lightGallery:- make sure lightGallery module is properly initiated\");\r\n }\r\n });\r\n };\r\n LightGallery.prototype.destroyModules = function (destroy) {\r\n this.plugins.forEach(function (module) {\r\n try {\r\n if (destroy) {\r\n module.destroy();\r\n }\r\n else {\r\n module.closeGallery && module.closeGallery();\r\n }\r\n }\r\n catch (err) {\r\n console.warn(\"lightGallery:- make sure lightGallery module is properly destroyed\");\r\n }\r\n });\r\n };\r\n /**\r\n * Refresh lightGallery with new set of children.\r\n *\r\n * @description This is useful to update the gallery when the child elements are changed without calling destroy method.\r\n *\r\n * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery\r\n * @see <a href=\"/demos/dynamic-mode/\">Demo</a>\r\n * @category lGPublicMethods\r\n * @example\r\n * const plugin = lightGallery();\r\n * // Delete or add children, then call\r\n * plugin.refresh();\r\n *\r\n */\r\n LightGallery.prototype.refresh = function (galleryItems) {\r\n if (!this.settings.dynamic) {\r\n this.invalidateItems();\r\n }\r\n if (galleryItems) {\r\n this.galleryItems = galleryItems;\r\n }\r\n else {\r\n this.galleryItems = this.getItems();\r\n }\r\n this.updateControls();\r\n this.openGalleryOnItemClick();\r\n this.LGel.trigger(lGEvents.updateSlides);\r\n };\r\n LightGallery.prototype.updateControls = function () {\r\n this.addSlideVideoInfo(this.galleryItems);\r\n this.updateCounterTotal();\r\n this.manageSingleSlideClassName();\r\n };\r\n LightGallery.prototype.destroyGallery = function () {\r\n this.destroyModules(true);\r\n if (!this.settings.dynamic) {\r\n this.invalidateItems();\r\n }\r\n $LG(window).off(\".lg.global\" + this.lgId);\r\n this.LGel.off('.lg');\r\n this.$container.remove();\r\n };\r\n /**\r\n * Destroy lightGallery.\r\n * Destroy lightGallery and its plugin instances completely\r\n *\r\n * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance.\r\n * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed.\r\n * You can use refresh method most of the times.\r\n * @category lGPublicMethods\r\n * @example\r\n * const plugin = lightGallery();\r\n * plugin.destroy();\r\n *\r\n */\r\n LightGallery.prototype.destroy = function () {\r\n var closeTimeout = this.closeGallery(true);\r\n if (closeTimeout) {\r\n setTimeout(this.destroyGallery.bind(this), closeTimeout);\r\n }\r\n else {\r\n this.destroyGallery();\r\n }\r\n return closeTimeout;\r\n };\r\n return LightGallery;\r\n}());\n\nfunction lightGallery(el, options) {\r\n return new LightGallery(el, options);\r\n}\n\n/* harmony default export */ const lightgallery_es5 = (lightGallery);\n//# sourceMappingURL=lightgallery.es5.js.map\n\n;// CONCATENATED MODULE: ./node_modules/lightgallery/plugins/zoom/lg-zoom.es5.js\n/*!\n * lightgallery | 2.7.2 | September 20th 2023\n * http://www.lightgalleryjs.com/\n * Copyright (c) 2020 Sachin Neravath;\n * @license GPLv3\n */\n\n/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AN
1D THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n\r\nvar lg_zoom_es5_assign = function() {\r\n lg_zoom_es5_assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n return lg_zoom_es5_assign.apply(this, arguments);\r\n};\n\nvar zoomSettings = {\r\n scale: 1,\r\n zoom: true,\r\n infiniteZoom: true,\r\n actualSize: true,\r\n showZoomInOutIcons: false,\r\n actualSizeIcons: {\r\n zoomIn: 'lg-zoom-in',\r\n zoomOut: 'lg-zoom-out',\r\n },\r\n enableZoomAfter: 300,\r\n zoomPluginStrings: {\r\n zoomIn: 'Zoom in',\r\n zoomOut: 'Zoom out',\r\n viewActualSize: 'View actual size',\r\n },\r\n};\n\n/**\r\n * List of lightGallery events\r\n * All events should be documented here\r\n * Below interfaces are used to build the website documentations\r\n * */\r\nvar lg_zoom_es5_lGEvents = {\r\n afterAppendSlide: 'lgAfterAppendSlide',\r\n init: 'lgInit',\r\n hasVideo: 'lgHasVideo',\r\n containerResize: 'lgContainerResize',\r\n updateSlides: 'lgUpdateSlides',\r\n afterAppendSubHtml: 'lgAfterAppendSubHtml',\r\n beforeOpen: 'lgBeforeOpen',\r\n afterOpen: 'lgAfterOpen',\r\n slideItemLoad: 'lgSlideItemLoad',\r\n beforeSlide: 'lgBeforeSlide',\r\n afterSlide: 'lgAfterSlide',\r\n posterClick: 'lgPosterClick',\r\n dragStart: 'lgDragStart',\r\n dragMove: 'lgDragMove',\r\n dragEnd: 'lgDragEnd',\r\n beforeNextSlide: 'lgBeforeNextSlide',\r\n beforePrevSlide: 'lgBeforePrevSlide',\r\n beforeClose: 'lgBeforeClose',\r\n afterClose: 'lgAfterClose',\r\n rotateLeft: 'lgRotateLeft',\r\n rotateRight: 'lgRotateRight',\r\n flipHorizontal: 'lgFlipHorizontal',\r\n flipVertical: 'lgFlipVertical',\r\n autoplay: 'lgAutoplay',\r\n autoplayStart: 'lgAutoplayStart',\r\n autoplayStop: 'lgAutoplayStop',\r\n};\n\nvar ZOOM_TRANSITION_DURATION = 500;\r\nvar lg_zoom_es5_Zoom = /** @class */ (function () {\r\n function Zoom(instance, $LG) {\r\n // get lightGallery core plugin instance\r\n this.core = instance;\r\n this.$LG = $LG;\r\n this.settings = lg_zoom_es5_assign(lg_zoom_es5_assign({}, zoomSettings), this.core.settings);\r\n return this;\r\n }\r\n // Append Zoom controls. Actual size, Zoom-in, Zoom-out\r\n Zoom.prototype.buildTemplates = function () {\r\n var zoomIcons = this.settings.showZoomInOutIcons\r\n ? \"<button id=\\\"\" + this.core.getIdName('lg-zoom-in') + \"\\\" type=\\\"button\\\" aria-label=\\\"\" + this.settings.zoomPluginStrings['zoomIn'] + \"\\\" class=\\\"lg-zoom-in lg-icon\\\"></button><button id=\\\"\" + this.core.getIdName('lg-zoom-out') + \"\\\" type=\\\"button\\\" aria-label=\\\"\" + this.settings.zoomPluginStrings['zoomIn'] + \"\\\" class=\\\"lg-zoom-out lg-icon\\\"></button>\"\r\n : '';\r\n if (this.settings.actualSize) {\r\n zoomIcons += \"<button id=\\\"\" + this.core.getIdName('lg-actual-size') + \"\\\" type=\\\"button\\\" aria-label=\\\"\" + this.settings.zoomPluginStrings['viewActualSize'] + \"\\\" class=\\\"\" + this.settings.actualSizeIcons.zoomIn + \" lg-icon\\\"></button>\";\r\n }\r\n this.core.outer.addClass('lg-use-transition-for-zoom');\r\n this.core.$toolbar.first().append(zoomIcons);\r\n };\r\n /**\r\n * @desc Enable zoom option only once the image is completely loaded\r\n * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted\r\n *\r\n * Zoom styles are defined under lg-zoomable CSS class.\r\n */\r\n Zoom.prototype.enableZoom = function (event) {\r\n var _this = this;\r\n // delay will be 0 except first time\r\n var _speed = this.settings.enableZoomAfter + event.detail.delay;\r\n // set _speed value 0 if gallery opened from direct url and if it is first slide\r\n if (this.$LG('body').first().hasClass('lg-from-hash') &&\r\n event.detail.delay) {\r\n // will execute only once\r\n _speed = 0;\r\n }\r\n else {\r\n // Remove lg-from-hash to enable starting animation.\r\n this.$LG('body').first().removeClass('lg-from-hash');\r\n }\r\n this.zoomableTimeout = setTimeout(function () {\r\n if (!_this.isImageSlide(_this.core.index)) {\r\n return;\r\n }\r\n _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable');\r\n if (event.detail.index === _this.core.index) {\r\n _this.setZoomEssentials();\r\n }\r\n }, _speed + 30);\r\n };\r\n Zoom.prototype.enableZoomOnSlideItemLoad = function () {\r\n // Add zoomable class\r\n this.core.LGel.on(lg_zoom_es5_lGEvents.slideItemLoad + \".zoom\", this.enableZoom.bind(this));\r\n };\r\n Zoom.prototype.getDragCords = function (e) {\r\n return {\r\n x: e.pageX,\r\n y: e.pageY,\r\n };\r\n };\r\n Zoom.prototype.getSwipeCords = function (e) {\r\n var x = e.touches[0].pageX;\r\n var y = e.touches[0].pageY;\r\n return {\r\n x: x,\r\n y: y,\r\n };\r\n };\r\n Zoom.prototype.getDragAllowedAxises = function (scale, scaleDiff) {\r\n var $image = this.core\r\n .getSlideItem(this.core.index)\r\n .find('.lg-image')\r\n .first()\r\n .get();\r\n var height = 0;\r\n var width = 0;\r\n var rect = $image.getBoundingClientRect();\r\n if (scale) {\r\n height = $image.offsetHeight * scale;\r\n width = $image.offsetWidth * scale;\r\n }\r\n else if (scaleDiff) {\r\n height = rect.height + scaleDiff * rect.height;\r\n width = rect.width + scaleDiff * rect.width;\r\n }\r\n else {\r\n height = rect.height;\r\n width = rect.width;\r\n }
1\r\n var allowY = height > this.containerRect.height;\r\n var allowX = width > this.containerRect.width;\r\n return {\r\n allowX: allowX,\r\n allowY: allowY,\r\n };\r\n };\r\n Zoom.prototype.setZoomEssentials = function () {\r\n this.containerRect = this.core.$content.get().getBoundingClientRect();\r\n };\r\n /**\r\n * @desc Image zoom\r\n * Translate the wrap and scale the image to get better user experience\r\n *\r\n * @param {String} scale - Zoom decrement/increment value\r\n */\r\n Zoom.prototype.zoomImage = function (scale, scaleDiff, reposition, resetToMax) {\r\n if (Math.abs(scaleDiff) <= 0)\r\n return;\r\n var offsetX = this.containerRect.width / 2 + this.containerRect.left;\r\n var offsetY = this.containerRect.height / 2 +\r\n this.containerRect.top +\r\n this.scrollTop;\r\n var originalX;\r\n var originalY;\r\n if (scale === 1) {\r\n this.positionChanged = false;\r\n }\r\n var dragAllowedAxises = this.getDragAllowedAxises(0, scaleDiff);\r\n var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX;\r\n if (this.positionChanged) {\r\n originalX = this.left / (this.scale - scaleDiff);\r\n originalY = this.top / (this.scale - scaleDiff);\r\n this.pageX = offsetX - originalX;\r\n this.pageY = offsetY - originalY;\r\n this.positionChanged = false;\r\n }\r\n var possibleSwipeCords = this.getPossibleSwipeDragCords(scaleDiff);\r\n var x;\r\n var y;\r\n var _x = offsetX - this.pageX;\r\n var _y = offsetY - this.pageY;\r\n if (scale - scaleDiff > 1) {\r\n var scaleVal = (scale - scaleDiff) / Math.abs(scaleDiff);\r\n _x =\r\n (scaleDiff < 0 ? -_x : _x) +\r\n this.left * (scaleVal + (scaleDiff < 0 ? -1 : 1));\r\n _y =\r\n (scaleDiff < 0 ? -_y : _y) +\r\n this.top * (scaleVal + (scaleDiff < 0 ? -1 : 1));\r\n x = _x / scaleVal;\r\n y = _y / scaleVal;\r\n }\r\n else {\r\n var scaleVal = (scale - scaleDiff) * scaleDiff;\r\n x = _x * scaleVal;\r\n y = _y * scaleVal;\r\n }\r\n if (reposition) {\r\n if (allowX) {\r\n if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) {\r\n x = possibleSwipeCords.minX;\r\n }\r\n else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) {\r\n x = possibleSwipeCords.maxX;\r\n }\r\n }\r\n else {\r\n if (scale > 1) {\r\n if (x < possibleSwipeCords.minX) {\r\n x = possibleSwipeCords.minX;\r\n }\r\n else if (x > possibleSwipeCords.maxX) {\r\n x = possibleSwipeCords.maxX;\r\n }\r\n }\r\n }\r\n // @todo fix this\r\n if (allowY) {\r\n if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) {\r\n y = possibleSwipeCords.minY;\r\n }\r\n else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) {\r\n y = possibleSwipeCords.maxY;\r\n }\r\n }\r\n else {\r\n // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out\r\n if (scale > 1) {\r\n //If image goes beyond viewport top, use the minim possible translate value\r\n if (y < possibleSwipeCords.minY) {\r\n y = possibleSwipeCords.minY;\r\n }\r\n else if (y > possibleSwipeCords.maxY) {\r\n y = possibleSwipeCords.maxY;\r\n }\r\n }\r\n }\r\n }\r\n this.setZoomStyles({\r\n x: x,\r\n y: y,\r\n scale: scale,\r\n });\r\n this.left = x;\r\n this.top = y;\r\n if (resetToMax) {\r\n this.setZoomImageSize();\r\n }\r\n };\r\n Zoom.prototype.resetImageTranslate = function (index) {\r\n if (!this.isImageSlide(index)) {\r\n return;\r\n }\r\n var $image = this.core.getSlideItem(index).find('.lg-image').first();\r\n this.imageReset = false;\r\n $image.removeClass('reset-transition reset-transition-y reset-transition-x');\r\n this.core.outer.removeClass('lg-actual-size');\r\n $image.css('width', 'auto').css('height', 'auto');\r\n setTimeout(function () {\r\n $image.removeClass('no-transition');\r\n }, 10);\r\n };\r\n Zoom.prototype.setZoomImageSize = function () {\r\n var _this = this;\r\n var $image = this.core\r\n .getSlideItem(this.core.index)\r\n .find('.lg-image')\r\n .first();\r\n setTimeout(function () {\r\n var actualSizeScale = _this.getCurrentImageActualSizeScale();\r\n if (_this.scale >= actualSizeScale) {\r\n $image.addClass('no-transition');\r\n _this.imageReset = true;\r\n }\r\n }, ZOOM_TRANSITION_DURATION);\r\n setTimeout(function () {\r\n var actualSizeScale = _this.getCurrentImageActualSizeScale();\r\n if (_this.scale >= actualSizeScale) {\r\n var dragAllowedAxises = _this.getDragAllowedAxises(_this.scale);\r\n $image\r\n .css('width', $image.get().naturalWi
1dth + 'px')\r\n .css('height', $image.get().naturalHeight + 'px');\r\n _this.core.outer.addClass('lg-actual-size');\r\n if (dragAllowedAxises.allowX && dragAllowedAxises.allowY) {\r\n $image.addClass('reset-transition');\r\n }\r\n else if (dragAllowedAxises.allowX &&\r\n !dragAllowedAxises.allowY) {\r\n $image.addClass('reset-transition-x');\r\n }\r\n else if (!dragAllowedAxises.allowX &&\r\n dragAllowedAxises.allowY) {\r\n $image.addClass('reset-transition-y');\r\n }\r\n }\r\n }, ZOOM_TRANSITION_DURATION + 50);\r\n };\r\n /**\r\n * @desc apply scale3d to image and translate to image wrap\r\n * @param {style} X,Y and scale\r\n */\r\n Zoom.prototype.setZoomStyles = function (style) {\r\n var $imageWrap = this.core\r\n .getSlideItem(this.core.index)\r\n .find('.lg-img-wrap')\r\n .first();\r\n var $image = this.core\r\n .getSlideItem(this.core.index)\r\n .find('.lg-image')\r\n .first();\r\n var $dummyImage = this.core.outer\r\n .find('.lg-current .lg-dummy-img')\r\n .first();\r\n this.scale = style.scale;\r\n $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');\r\n $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');\r\n var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)';\r\n $imageWrap.css('transform', transform);\r\n };\r\n /**\r\n * @param index - Index of the current slide\r\n * @param event - event will be available only if the function is called on clicking/taping the imags\r\n */\r\n Zoom.prototype.setActualSize = function (index, event) {\r\n var _this = this;\r\n if (this.zoomInProgress) {\r\n return;\r\n }\r\n this.zoomInProgress = true;\r\n var currentItem = this.core.galleryItems[this.core.index];\r\n this.resetImageTranslate(index);\r\n setTimeout(function () {\r\n // Allow zoom only on image\r\n if (!currentItem.src ||\r\n _this.core.outer.hasClass('lg-first-slide-loading')) {\r\n return;\r\n }\r\n var scale = _this.getCurrentImageActualSizeScale();\r\n var prevScale = _this.scale;\r\n if (_this.core.outer.hasClass('lg-zoomed')) {\r\n _this.scale = 1;\r\n }\r\n else {\r\n _this.scale = _this.getScale(scale);\r\n }\r\n _this.setPageCords(event);\r\n _this.beginZoom(_this.scale);\r\n _this.zoomImage(_this.scale, _this.scale - prevScale, true, true);\r\n }, 50);\r\n setTimeout(function () {\r\n _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');\r\n }, 60);\r\n setTimeout(function () {\r\n _this.zoomInProgress = false;\r\n }, ZOOM_TRANSITION_DURATION + 110);\r\n };\r\n Zoom.prototype.getNaturalWidth = function (index) {\r\n var $image = this.core.getSlideItem(index).find('.lg-image').first();\r\n var naturalWidth = this.core.galleryItems[index].width;\r\n return naturalWidth\r\n ? parseFloat(naturalWidth)\r\n : $image.get().naturalWidth;\r\n };\r\n Zoom.prototype.getActualSizeScale = function (naturalWidth, width) {\r\n var _scale;\r\n var scale;
1\r\n if (naturalWidth >= width) {\r\n _scale = naturalWidth / width;\r\n scale = _scale || 2;\r\n }\r\n else {\r\n scale = 1;\r\n }\r\n return scale;\r\n };\r\n Zoom.prototype.getCurrentImageActualSizeScale = function () {\r\n var $image = this.core\r\n .getSlideItem(this.core.index)\r\n .find('.lg-image')\r\n .first();\r\n var width = $image.get().offsetWidth;\r\n var naturalWidth = this.getNaturalWidth(this.core.index) || width;\r\n return this.getActualSizeScale(naturalWidth, width);\r\n };\r\n Zoom.prototype.getPageCords = function (event) {\r\n var cords = {};\r\n if (event) {\r\n cords.x = event.pageX || event.touches[0].pageX;\r\n cords.y = event.pageY || event.touches[0].pageY;\r\n }\r\n else {\r\n var containerRect = this.core.$content\r\n .get()\r\n .getBoundingClientRect();\r\n cords.x = containerRect.width / 2 + containerRect.left;\r\n cords.y =\r\n containerRect.height / 2 + this.scrollTop + containerRect.top;\r\n }\r\n return cords;\r\n };\r\n Zoom.prototype.setPageCords = function (event) {\r\n var pageCords = this.getPageCords(event);\r\n this.pageX = pageCords.x;\r\n this.pageY = pageCords.y;\r\n };\r\n Zoom.prototype.manageActualPixelClassNames = function () {\r\n var $actualSize = this.core.getElementById('lg-actual-size');\r\n $actualSize\r\n .removeClass(this.settings.actualSizeIcons.zoomIn)\r\n .addClass(this.settings.actualSizeIcons.zoomOut);\r\n };\r\n // If true, zoomed - in else zoomed out\r\n Zoom.prototype.beginZoom = function (scale) {\r\n this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');\r\n if (scale > 1) {\r\n this.core.outer.addClass('lg-zoomed');\r\n this.manageActualPixelClassNames();\r\n }\r\n else {\r\n this.resetZoom();\r\n }\r\n return scale > 1;\r\n };\r\n Zoom.prototype.getScale = function (scale) {\r\n var actualSizeScale = this.getCurrentImageActualSizeScale();\r\n if (scale < 1) {\r\n scale = 1;\r\n }\r\n else if (scale > actualSizeScale) {\r\n scale = actualSizeScale;\r\n }\r\n return scale;\r\n };\r\n Zoom.prototype.init = function () {\r\n var _this = this;\r\n if (!this.settings.zoom) {\r\n return;\r\n }\r\n this.buildTemplates();\r\n this.enableZoomOnSlideItemLoad();\r\n var tapped = null;\r\n this.core.outer.on('dblclick.lg', function (event) {\r\n if (!_this.$LG(event.target).hasClass('lg-image')) {\r\n return;\r\n }\r\n _this.setActualSize(_this.core.index, event);\r\n });\r\n this.core.outer.on('touchstart.lg', function (event) {\r\n var $target = _this.$LG(event.target);\r\n if (event.touches.length === 1 && $target.hasClass('lg-image')) {\r\n if (!tapped) {\r\n tapped = setTimeout(function () {\r\n tapped = null;\r\n }, 300);\r\n }\r\n else {\r\n clearTimeout(tapped);\r\n tapped = null;\r\n event.preventDefault();\r\n _this.setActualSize(_this.core.index, event);\r\n }\r\n }\r\n });\r\n this.core.LGel.on(lg_zoom_es5_lGEvents.containerResize + \".zoom \" + lg_zoom_es5_lGEvents.rotateRight + \".zoom \" + lg_zoom_es5_lGEvents.rotateLeft + \".zoom \" + lg_zoom_es5_lGEvents.flipHorizontal + \".zoom \" + lg_zoom_es5_lGEvents.flipVertical + \".zoom\", function () {\r\n if (!_this.core.lgOpened ||\r\n !_this.isImageSlide(_this.core.index) ||\r\n _this.core.touchAction) {\r\n return;\r\n }\r\n var _LGel = _this.core\r\n .getSlideItem(_this.core.index)\r\n .find('.lg-img-wrap')\r\n .first();\r\n _this.top = 0;\r\n _this.left = 0;\r\n _this.setZoomEssentials();\r\n _this.setZoomSwipeStyles(_LGel, { x: 0, y: 0 });\r\n _this.positionChanged = true;\r\n });\r\n // Update zoom on resize and orientationchange\r\n this.$LG(window).on(\"scroll.lg.zoom.global\" + this.core.lgId, function () {\r\n if (!_this.core.lgOpened)\r\n return;\r\n _this.scrollTop = _this.$LG(window).scrollTop();\r\n });\r\n this.core.getElementById('lg-zoom-out').on('click.lg', function () {\r\n // Allow zoom only on image\r\n if (!_this.isImageSlide(_this.core.index)) {\r\n return;\r\n }\r\n var timeout = 0;\r\n if (_this.imageReset) {\r\n _this.resetImageTranslate(_this.core.index);\r\n timeout = 50;\r\n }\r\n setTimeout(function () {\r\n var scale = _this.scale - _this.settings.scale;\r\n if (scale < 1) {\r\n scale = 1;\r\n }\r\n _this.beginZoom(scale);\r\n _this.zoomImage(scale, -_this.settings.scale, true, !_this.settings.infiniteZoom);\r\n }, timeout);\r\n });\r\n this.core.getElementById('lg-zoom-in').on('click.lg', function () {\r\n _this.zoomIn();\r\n });\r\n this.core.getElementById('lg-actual-size').on('click.lg', function () {\r\n _this.setActualSize(_this.core.index);\r\n });\r\n this.core.LGel.on(lg_zoom_es5_lGEvents.beforeOpen + \".zoom\", function () {\r\n _this.core.outer.find('.lg-item').removeClass('lg-zoomable');\r\n });\r\n this.core.LGel.on(lg_zoom_es5_lGEvents.afterOpen + \".zoom\", function () {\r\n _this.scrollTop = _this.$LG(window).scrollTop();\r\n // Set the initial value center\r\n _this.pageX = _this.core.outer.width() / 2;
1\r\n _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop;\r\n _this.scale = 1;\r\n });\r\n // Reset zoom on slide change\r\n this.core.LGel.on(lg_zoom_es5_lGEvents.afterSlide + \".zoom\", function (event) {\r\n var prevIndex = event.detail.prevIndex;\r\n _this.scale = 1;\r\n _this.positionChanged = false;\r\n _this.zoomInProgress = false;\r\n _this.resetZoom(prevIndex);\r\n _this.resetImageTranslate(prevIndex);\r\n if (_this.isImageSlide(_this.core.index)) {\r\n _this.setZoomEssentials();\r\n }\r\n });\r\n // Drag option after zoom\r\n this.zoomDrag();\r\n this.pinchZoom();\r\n this.zoomSwipe();\r\n // Store the zoomable timeout value just to clear it while closing\r\n this.zoomableTimeout = false;\r\n this.positionChanged = false;\r\n this.zoomInProgress = false;\r\n };\r\n Zoom.prototype.zoomIn = function () {\r\n // Allow zoom only on image\r\n if (!this.isImageSlide(this.core.index)) {\r\n return;\r\n }\r\n var scale = this.scale + this.settings.scale;\r\n if (!this.settings.infiniteZoom) {\r\n scale = this.getScale(scale);\r\n }\r\n this.beginZoom(scale);\r\n this.zoomImage(scale, Math.min(this.settings.scale, scale - this.scale), true, !this.settings.infiniteZoom);\r\n };\r\n // Reset zoom effect\r\n Zoom.prototype.resetZoom = function (index) {\r\n this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition');\r\n var $actualSize = this.core.getElementById('lg-actual-size');\r\n var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index);\r\n $actualSize\r\n .removeClass(this.settings.actualSizeIcons.zoomOut)\r\n .addClass(this.settings.actualSizeIcons.zoomIn);\r\n $item.find('.lg-img-wrap').first().removeAttr('style');\r\n $item.find('.lg-image').first().removeAttr('style');\r\n this.scale = 1;\r\n this.left = 0;\r\n this.top = 0;\r\n // Reset pagx pagy values to center\r\n this.setPageCords();\r\n };\r\n Zoom.prototype.getTouchDistance = function (e) {\r\n return Math.sqrt((e.touches[0].pageX - e.touches[1].pageX) *\r\n (e.touches[0].pageX - e.touches[1].pageX) +\r\n (e.touches[0].pageY - e.touches[1].pageY) *\r\n (e.touches[0].pageY - e.touches[1].pageY));\r\n };\r\n Zoom.prototype.pinchZoom = function () {\r\n var _this = this;\r\n var startDist = 0;\r\n var pinchStarted = false;\r\n var initScale = 1;\r\n var prevScale = 0;\r\n var $item = this.core.getSlideItem(this.core.index);\r\n this.core.outer.on('touchstart.lg', function (e) {\r\n $item = _this.core.getSlideItem(_this.core.index);\r\n if (!_this.isImageSlide(_this.core.index)) {\r\n return;\r\n }\r\n if (e.touches.length === 2) {\r\n e.preventDefault();\r\n if (_this.core.outer.hasClass('lg-first-slide-loading')) {\r\n return;\r\n }\r\n initScale = _this.scale || 1;\r\n _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');\r\n _this.setPageCords(e);\r\n _this.resetImageTranslate(_this.core.index);\r\n _this.core.touchAction = 'pinch';\r\n startDist = _this.getTouchDistance(e);\r\n }\r\n });\r\n this.core.$inner.on('touchmove.lg', function (e) {\r\n if (e.touches.length === 2 &&\r\n _this.core.touchAction === 'pinch' &&\r\n (_this.$LG(e.target).hasClass('lg-item') ||\r\n $item.get().contains(e.target))) {\r\n e.preventDefault();\r\n var endDist = _this.getTouchDistance(e);\r\n var distance = startDist - endDist;\r\n if (!pinchStarted && Math.abs(distance) > 5) {\r\n pinchStarted = true;\r\n }\r\n if (pinchStarted) {\r\n prevScale = _this.scale;\r\n var _scale = Math.max(1, initScale + -distance * 0.02);\r\n _this.scale =\r\n Math.round((_scale + Number.EPSILON) * 100) / 100;\r\n var diff = _this.scale - prevScale;\r\n _this.zoomImage(_this.scale, Math.round((diff +
1Number.EPSILON) * 100) / 100, false, false);\r\n }\r\n }\r\n });\r\n this.core.$inner.on('touchend.lg', function (e) {\r\n if (_this.core.touchAction === 'pinch' &&\r\n (_this.$LG(e.target).hasClass('lg-item') ||\r\n $item.get().contains(e.target))) {\r\n pinchStarted = false;\r\n startDist = 0;\r\n if (_this.scale <= 1) {\r\n _this.resetZoom();\r\n }\r\n else {\r\n var actualSizeScale = _this.getCurrentImageActualSizeScale();\r\n if (_this.scale >= actualSizeScale) {\r\n var scaleDiff = actualSizeScale - _this.scale;\r\n if (scaleDiff === 0) {\r\n scaleDiff = 0.01;\r\n }\r\n _this.zoomImage(actualSizeScale, scaleDiff, false, true);\r\n }\r\n _this.manageActualPixelClassNames();\r\n _this.core.outer.addClass('lg-zoomed');\r\n }\r\n _this.core.touchAction = undefined;\r\n }\r\n });\r\n };\r\n Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration) {\r\n var distanceXnew = endCoords.x - startCoords.x;\r\n var distanceYnew = endCoords.y - startCoords.y;\r\n var speedX = Math.abs(distanceXnew) / touchDuration + 1;\r\n var speedY = Math.abs(distanceYnew) / touchDuration + 1;\r\n if (speedX > 2) {\r\n speedX += 1;\r\n }\r\n if (speedY > 2) {\r\n speedY += 1;\r\n }\r\n distanceXnew = distanceXnew * speedX;\r\n distanceYnew = distanceYnew * speedY;\r\n var _LGel = this.core\r\n .getSlideItem(this.core.index)\r\n .find('.lg-img-wrap')\r\n .first();\r\n var distance = {};\r\n distance.x = this.left + distanceXnew;\r\n distance.y = this.top + distanceYnew;\r\n var possibleSwipeCords = this.getPossibleSwipeDragCords();\r\n if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) {\r\n if (allowY) {\r\n if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {\r\n distance.y = possibleSwipeCords.minY;\r\n }\r\n else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {\r\n distance.y = possibleSwipeCords.maxY;\r\n }\r\n }\r\n if (allowX) {\r\n if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {\r\n distance.x = possibleSwipeCords.minX;\r\n }\r\n else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {\r\n distance.x = possibleSwipeCords.maxX;\r\n }\r\n }\r\n if (allowY) {\r\n this.top = distance.y;\r\n }\r\n else {\r\n distance.y = this.top;\r\n }\r\n if (allowX) {\r\n this.left = distance.x;\r\n }\r\n else {\r\n distance.x = this.left;\r\n }\r\n this.setZoomSwipeStyles(_LGel, distance);\r\n this.positionChanged = true;\r\n }\r\n };\r\n Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) {\r\n var distance = {};\r\n if (allowY) {\r\n distance.y = this.top + (endCoords.y - startCoords.y);\r\n if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {\r\n var diffMinY = possibleSwipeCords.minY - distance.y;\r\n distance.y = possibleSwipeCords.minY - diffMinY / 6;\r\n }\r\n else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {\r\n var diffMaxY = distance.y - possibleSwipeCords.maxY;\r\n distance.y = possibleSwipeCords.maxY + diffMaxY / 6;\r\n }\r\n }\r\n else {\r\n distance.y = this.top;\r\n }\r\n if (allowX) {\r\n distance.x = this.left + (endCoords.x - startCoords.x);\r\n if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {\r\n var diffMinX = possibleSwipeCords.minX - distance.x;\r\n distance.x = possibleSwipeCords.minX - diffMinX / 6;\r\n }\r\n else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {\r\n var difMaxX = distance.x - possibleSwipeCords.maxX;\r\n distance.x = possibleSwipeCords.maxX + difMaxX / 6;\r\n }\r\n }\r\n else {\r\n distance.x = this.left;\r\n }\r\n return distance;\r\n };\r\n Zoom.prototype.isBeyondPossibleLeft = function (x, minX) {\r\n return x >= minX;\r\n };\r\n Zoom.prototype.isBeyondPossibleRight = function (x, maxX) {\r\n return x <= maxX;\r\n };\r\n Zoom.prototype.isBeyondPossibleTop = function (y, minY) {\r\n return y >= minY;\r\n };\r\n Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) {\r\n return y <= maxY;\r\n };\r\n Zoom.prototype.isImageSlide = function (index) {\r\n var currentItem = this.core.galleryItems[index];
1\r\n return this.core.getSlideType(currentItem) === 'image';\r\n };\r\n Zoom.prototype.getPossibleSwipeDragCords = function (scale) {\r\n var $image = this.core\r\n .getSlideItem(this.core.index)\r\n .find('.lg-image')\r\n .first();\r\n var bottom = this.core.mediaContainerPosition.bottom;\r\n var imgRect = $image.get().getBoundingClientRect();\r\n var imageHeight = imgRect.height;\r\n var imageWidth = imgRect.width;\r\n if (scale) {\r\n imageHeight = imageHeight + scale * imageHeight;\r\n imageWidth = imageWidth + scale * imageWidth;\r\n }\r\n var minY = (imageHeight - this.containerRect.height) / 2;\r\n var maxY = (this.containerRect.height - imageHeight) / 2 + bottom;\r\n var minX = (imageWidth - this.containerRect.width) / 2;\r\n var maxX = (this.containerRect.width - imageWidth) / 2;\r\n var possibleSwipeCords = {\r\n minY: minY,\r\n maxY: maxY,\r\n minX: minX,\r\n maxX: maxX,\r\n };\r\n return possibleSwipeCords;\r\n };\r\n Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) {\r\n LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)');\r\n };\r\n Zoom.prototype.zoomSwipe = function () {\r\n var _this = this;\r\n var startCoords = {};\r\n var endCoords = {};\r\n var isMoved = false;\r\n // Allow x direction drag\r\n var allowX = false;\r\n // Allow Y direction drag\r\n var allowY = false;\r\n var startTime = new Date();\r\n var endTime = new Date();\r\n var possibleSwipeCords;\r\n var _LGel;\r\n var $item = this.core.getSlideItem(this.core.index);\r\n this.core.$inner.on('touchstart.lg', function (e) {\r\n // Allow zoom only on image\r\n if (!_this.isImageSlide(_this.core.index)) {\r\n return;\r\n }\r\n $item = _this.core.getSlideItem(_this.core.index);\r\n if ((_this.$LG(e.target).hasClass('lg-item') ||\r\n $item.get().contains(e.target)) &&\r\n e.touches.length === 1 &&\r\n _this.core.outer.hasClass('lg-zoomed')) {\r\n e.preventDefault();\r\n startTime = new Date();\r\n _this.core.touchAction = 'zoomSwipe';\r\n _LGel = _this.core\r\n .getSlideItem(_this.core.index)\r\n .find('.lg-img-wrap')\r\n .first();\r\n var dragAllowedAxises = _this.getDragAllowedAxises(0);\r\n allowY = dragAllowedAxises.allowY;\r\n allowX = dragAllowedAxises.allowX;\r\n if (allowX || allowY) {\r\n startCoords = _this.getSwipeCords(e);\r\n }\r\n possibleSwipeCords = _this.getPossibleSwipeDragCords();\r\n // reset opacity and transition duration\r\n _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition');\r\n }\r\n });\r\n this.core.$inner.on('touchmove.lg', function (e) {\r\n if (e.touches.length === 1 &&\r\n _this.core.touchAction === 'zoomSwipe' &&\r\n (_this.$LG(e.target).hasClass('lg-item') ||\r\n $item.get().contains(e.target))) {\r\n e.preventDefault();\r\n _this.core.touchAction = 'zoomSwipe';\r\n endCoords = _this.getSwipeCords(e);\r\n var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);\r\n if (Math.abs(endCoords.x - startCoords.x) > 15 ||\r\n Math.abs(endCoords.y - startCoords.y) > 15) {\r\n isMoved = true;\r\n _this.setZoomSwipeStyles(_LGel, distance);\r\n }\r\n }\r\n });\r\n this.core.$inner.on('touchend.lg', function (e) {\r\n if (_this.core.touchAction === 'zoomSwipe' &&\r\n (_this.$LG(e.target).hasClass('lg-item') ||\r\n $item.get().contains(e.target))) {\r\n e.preventDefault();\r\n _this.core.touchAction = undefined;\r\n _this.core.outer.removeClass('lg-zoom-dragging');\r\n if (!isMoved) {\r\n return;\r\n }\r\n isMoved = false;\r\n endTime = new Date();\r\n var touchDuration = endTime.valueOf() - startTime.valueOf();\r\n _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration);\r\n }\r\n });\r\n };\r\n Zoom.prototype.zoomDrag = function () {\r\n var _this = this;\r\n var startCoords = {};\r\n var endCoords = {};\r\n var isDragging = false;\r\n var isMoved = false;\r\n // Allow x direction drag\r\n var allowX = false;\r\n // Allow Y direction drag\r\n var allowY = false;\r\n var startTime;\r\n var endTime;\r\n var possibleSwipeCords;\r\n var _LGel;\r\n this.core.outer.on('mousedown.lg.zoom', function (e) {\r\n // Allow zoom only on image\r\n if (!_this.isImageSlide(_this.core.index)) {\r\n return;\r\n }\r\n var $item = _this.core.getSlideItem(_this.core.index);\r\n if (_this.$LG(e.target).hasClass('lg-item') ||\r\n $item.get().contains(e.target)) {\r\n startTime = new Date();\r\n _LGel = _this.core\r\n .getSlideItem(_this.core.index)\r\n .find('.lg-img-wrap')\r\n .first();\r\n var dragAllowedAxises = _this.getDragAllowedAxises(0);\r\n allowY = dragAllowedAxises.allowY;\r\n allowX = dragAllowedAxises.allowX;\r\n if (_this.core.outer.hasClass('lg-zoomed')) {\r\n if (_this.$LG(e.target).hasClass('lg-object') &&\r\n (allowX || allowY)) {\r\n e.preventDefault();\r\n startCoords = _this.getDragCords(e);\r\n possibleSwipeCords = _this.getPossibleSwipeDragCords();\r\n isDragging = true;\r\n _this.core.outer\r\n .removeClass('lg-grab')\r\n .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging');\r\n // reset opacity and transition duration\r\n }\r\n }\r\n }\r\n });\r\n this.$LG(window).on(\"mousemove.lg.zoom.global\" + this.core.lgId, function (e) {\r\n if (isDragging) {\r\n isMoved = true;\r\n endCoords = _this.getDragCords(e);\r\n var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);\r\n _this.setZoomSwipeStyles(_LGel, distance);\r\n }\r\n });\r\n this.$LG(window).on(\"mouseup.lg.zoom.global\" + this.core.lgId, function (e) {\r\n if (isDragging) {\r\n endTime = new Date();\r\n isDragging = false;\r\n _this.core.outer.removeClass('lg-zoom-dragging');\r\n // Fix for chrome mouse move on click\r\n if (isMoved &&\r\n (startCoords.x !== endCoords.x ||\r\n startCoords.y !== endCoords.y)) {\r\n endCoords = _this.getDragCords(e);\r\n var touchDuration = endTime.valueOf() - startTime.valueOf();\r\n _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration);\r\n }\r\n isMoved = false;\r\n }\r\n _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');\r\n });\r\n };\r\n Zoom.prototype.closeGallery = function () {\r\n this.resetZoom();\r\n this.zoomInProgress = false;\r\n };\r\n Zoom.prototype.destroy = function () {\r\n // Unbind all events added by lightGallery zoom plugin\r\n this.$LG(window).off(\".lg.zoom.global\" + this.core.lgId);\r\n this.core.LGel.off('.lg.zoom');\r\n this.core.LGel.off('.zoom');\r\n clearTimeout(this.zoomableTimeout);\r\n this.zoomableTimeout = false;\r\n };\r\n return Zoom;\r\n}());\n\n/* harmony default export */ const lg_zoom_es5 = ((/* unused pure expression or super */ null && (lg_zoom_es5_Zoom)));\n//# sourceMappingURL=lg-zoom.es5.js.map\n\n;// CONCATENATED MODULE: ./node_modules/@studio-freight/lenis/dist/lenis.mjs\nfunction t(t,e,i){return Math.max(t,Math.min(e,i))}class Animate{advance(e){if(!this.isRunning)return;let i=!1;if(this.lerp)this.value=(s=this.value,o=this.to,n=60*this.lerp,r=e,function(t,e,
vendor: 13,467 bytes, line 1
1i){return(1-i)*t+i*e}(s,o,1-Math.exp(-n*r))),Math.round(this.value)===this.to&&(this.value=this.to,i=!0);else{this.currentTime+=e;const s=t(0,this.currentTime/this.duration,1);i=s>=1;const o=i?1:this.easing(s);this.value=this.from+(this.to-this.from)*o}var s,o,n,r;this.onUpdate?.(this.value,i),i&&this.stop()}stop(){this.isRunning=!1}fromTo(t,e,{lerp:i=.1,duration:s=1,easing:o=(t=>t),onStart:n,onUpdate:r}){this.from=this.value=t,this.to=e,this.lerp=i,this.duration=s,this.easing=o,this.currentTime=0,this.isRunning=!0,n?.(),this.onUpdate=r}}class Dimensions{constructor({wrapper:t,content:e,autoResize:i=!0,debounce:s=250}={}){this.wrapper=t,this.content=e,i&&(this.debouncedResize=function(t,e){let i;return function(){let s=arguments,o=this;clearTimeout(i),i=setTimeout((function(){t.apply(o,s)}),e)}}(this.resize,s),this.wrapper===window?window.addEventListener(\"resize\",this.debouncedResize,!1):(this.wrapperResizeObserver=new ResizeObserver(this.debouncedResize),this.wrapperResizeObserver.observe(this.wrapper)),this.contentResizeObserver=new ResizeObserver(this.debouncedResize),this.contentResizeObserver.observe(this.content)),this.resize()}destroy(){this.wrapperResizeObserver?.disconnect(),this.contentResizeObserver?.disconnect(),window.removeEventListener(\"resize\",this.debouncedResize,!1)}resize=()=>{this.onWrapperResize(),this.onContentResize()};onWrapperResize=()=>{this.wrapper===window?(this.width=window.innerWidth,this.height=window.innerHeight):(this.width=this.wrapper.clientWidth,this.height=this.wrapper.clientHeight)};onContentResize=()=>{this.wrapper===window?(this.scrollHeight=this.content.scrollHeight,this.scrollWidth=this.content.scrollWidth):(this.scrollHeight=this.wrapper.scrollHeight,this.scrollWidth=this.wrapper.scrollWidth)};get limit(){return{x:this.scrollWidth-this.width,y:this.scrollHeight-this.height}}}class Emitter{constructor(){this.events={}}emit(t,...e){let i=this.events[t]||[];for(let t=0,s=i.length;t<s;t++)i[t](...e)}on(t,e){return this.events[t]?.push(e)||(this.events[t]=[e]),()=>{this.events[t]=this.events[t]?.filter((t=>e!==t))}}off(t,e){this.events[t]=this.events[t]?.filter((t=>e!==t))}destroy(){this.events={}}}const e=100/6;class VirtualScroll{constructor(t,{wheelMultiplier:e=1,touchMultiplier:i=1}){this.element=t,this.wheelMultiplier=e,this.touchMultiplier=i,this.touchStart={x:null,y:null},this.emitter=new Emitter,window.addEventListener(\"resize\",this.onWindowResize,!1),this.onWindowResize(),this.element.addEventListener(\"wheel\",this.onWheel,{passive:!1}),this.element.addEventListener(\"touchstart\",this.onTouchStart,{passive:!1}),this.element.addEventListener(\"touchmove\",this.onTouchMove,{passive:!1}),this.element.addEventListener(\"touchend\",this.onTouchEnd,{passive:!1})}on(t,e){return this.emitter.on(t,e)}destroy(){this.emitter.destroy(),window.removeEventListener(\"resize\",this.onWindowResize,!1),this.element.removeEventListener(\"wheel\",this.onWheel,{passive:!1}),this.element.removeEventListener(\"touchstart\",this.onTouchStart,{passive:!1}),this.element.removeEventListener(\"touchmove\",this.onTouchMove,{passive:!1}),this.element.removeEventListener(\"touchend\",this.onTouchEnd,{passive:!1})}onTouchStart=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:0,y:0},this.emitter.emit(\"scroll\",{deltaX:0,deltaY:0,event:t})};onTouchMove=t=>{const{clientX:e,clientY:i}=t.targetTouches?t.targetTouches[0]:t,s=-(e-this.touchStart.x)*this.touchMultiplier,o=-(i-this.touchStart.y)*this.touchMultiplier;this.touchStart.x=e,this.touchStart.y=i,this.lastDelta={x:s,y:o},this.emitter.emit(\"scroll\",{deltaX:s,deltaY:o,event:t})};onTouchEnd=t=>{this.emitter.emit(\"scroll\",{deltaX:this.lastDelta.x,deltaY:this.lastDelta.y,event:t})};onWheel=t=>{let{deltaX:i,deltaY:s,deltaMode:o}=t;i*=1===o?e:2===o?this.windowWidth:1,s*=1===o?e:2===o?this.windowHeight:1,i*=this.wheelMultiplier,s*=this.wheelMultiplier,this.emitter.emit(\"scroll\",{deltaX:i,deltaY:s,event:t})};onWindowResize=()=>{this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight}}class Lenis{constructor({wrapper:t=window,content:e=document.documentElement,wheelEventsTarget:i=t,eventsTarget:s=i,smoothWheel:o=!0,syncTouch:n=!1,syncTouchLerp:r=.075,touchInertiaMultiplier:l=35,duration:h,easing:a=(t=>Math.min(1,1.001-Math.pow(2,-10*t))),lerp:c=!h&&.1,infinite:d=!1,orientation:p=\"vertical\",gestureOrientation:u=\"vertical\",touchMultiplier:m=1,wheelMultiplier:v=1,autoResize:g=!0,__experimental__naiveDimensions:S=!1}={}){this.__isSmooth=!1,this.__isScrolling=!1,this.__isStopped=!1,this.__isLocked=!1,this.onVirtualScroll=({deltaX:t,deltaY:e,event:i})=>{if(i.ctrlKey)return;const s=i.type.includes(\"touch\"),o=i.type.includes(\"wheel\");if(this.options.syncTouch&&s&&\"touchstart\"===i.type&&!this.isStopped&&!this.isLocked)return void this.reset();const n=0===t&&0===e,r=\"vertical\"===this.options.gestureOrientation&&0===e||\"horizontal\"===this.options.gestureOrientation&&0===t;if(n||r)return;let l=i.composedPath();if(l=l.slice(0,l.indexOf(this.rootElement)),l.find((t=>{var e,i,n,r,l;return(null===(e=t.hasAttribute)||void 0===e?void 0:e.call(t,\"data-lenis-prevent\"))||s&&(null===(i=t.hasAttribute)||void 0===i?void 0:i.call(t,\"data-lenis-prevent-touch\"))||o&&(null===(n=t.hasAttribute)||void 0===n?void 0:n.call(t,\"data-lenis-prevent-wheel\"))||(null===(r=t.classList)||void 0===r?void 0:r.contains(\"lenis\"))&&!(null===(l=t.classList)||void 0===l?void 0:l.contains(\"lenis-stopped\"))})))return;if(this.isStopped||this.isLocked)return void i.preventDefault();if(this.isSmooth=this.options.syncTouch&&s||this.options.smoothWheel&&o,!this.isSmooth)return this.isScrolling=!1,void this.animate.stop();i.preventDefault();let h=e;\"both\"===this.options.gestureOrientation?h=Math.abs(e)>Math.abs(t)?e:t:\"horizontal\"===this.options.gestureOrientation&&(h=t);const a=s&&this.options.syncTouch,c=s&&\"touchend\"===i.type&&Math.abs(h)>5;c&&(h=this.velocity*this.options.touchInertiaMultiplier),this.scrollTo(this.targetScroll+h,Object.assign({programmatic:!1},a?{lerp:c?this.options.syncTouchLerp:1}:{lerp:this.options.lerp,duration:this.options.duration,easing:this.options.easing}))},this.onNativeScroll=()=>{if(!this.__preventNextScrollEvent&&!this.isScrolling){const t=this.animatedScroll;this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.direction=Math.sign(this.animatedScroll-t),this.emit()}},window.lenisVersion=\"1.0.42\",t!==document.documentElement&&t!==document.body||(t=window),this.options={wrapper:t,content:e,wheelEventsTarget:i,eventsTarget:s,smoothWheel:o,syncTouch:n,syncTouchLerp:r,touchInertiaMultiplier:l,duration:h,easing:a,lerp:c,infinite:d,gestureOrientation:u,orientation:p,touchMultiplier:m,wheelMultiplier:v,autoResize:g,__experimental__naiveDimensions:S},this.animate=new Animate,this.emitter=new Emitter,this.dimensions=new Dimensions({wrapper:t,content:e,autoResize:g}),this.toggleClassName(\"lenis\",!0),this.velocity=0,this.isLocked=!1,this.isStopped=!1,this.isSmooth=n||o,this.isScrolling=!1,this.targetScroll=this.animatedScroll=this.actualScroll,this.options.wrapper.addEventListener(\"scroll\",this.onNativeScroll,!1),this.virtualScroll=new VirtualScroll(s,{touchMultiplier:m,wheelMultiplier:v}),this.virtualScroll.on(\"scroll\",this.onVirtualScroll)}destroy(){this.emitter.destroy(),this.options.wrapper.removeEventListener(\"scroll\",this.onNativeScroll,!1),this.virtualScroll.destroy(),this.dimensions.destroy(),this.toggleClassName(\"lenis\",!1),this.toggleClassName(\"lenis-smooth\",!1),this.toggleClassName(\"lenis-scrolling\",!1),this.toggleClassName(\"lenis-stopped\",!1),this.toggleClassName(\"lenis-locked\",!1)}on(t,e){return this.emitter.on(t,e)}off(t,e){return this.emitter.off(t,e)}setScroll(t){this.isHorizontal?this.rootElement.scrollLeft=t:this.rootElement.scrollTop=t}resize(){this.dimensions.resize()}emit(){this.emitter.emit(\"scroll\",this)}reset(){this.isLocked=!1,this.isScrolling=!1,this.animatedScroll=this.targetScroll=this.actualScroll,this.velocity=0,this.animate.stop()}start(){this.isStopped&&(this.isStopped=!1,this.reset())}stop(){this.isStopped||(this.isStopped=!0,this.animate.stop(),this.reset())}raf(t){const e=t-(this.time||t);this.time=t,this.animate.advance(.001*e)}scrollTo(e,{offset:i=0,immediate:s=!1,lock:o=!1,duration:n=this.options.duration,easing:r=this.options.easing,lerp:l=!n&&this.options.lerp,onComplete:h,force:a=!1,programmatic:c=!0}={}){if(!this.isStopped&&!this.isLocked||a){if([\"top\",\"left\",\"start\"].includes(e))e=0;else if([\"bottom\",\"right\",\"end\"].includes(e))e=this.limit;else{let t;if(\"string\"==typeof e?t=document.querySelector(e):(null==e?void 0:e.nodeType)&&(t=e),t){if(this.options.wrapper!==window){const t=this.options.wrapper.getBoundingClientRect();i-=this.isHorizontal?t.left:t.top}const s=t.getBoundingClientRect();e=(this.isHorizontal?s.left:s.top)+this.animatedScroll}}if(\"number\"==typeof e){if(e+=i,e=Math.round(e),this.options.infinite?c&&(this.targetScroll=this.animatedScroll=this.scroll):e=t(0,e,this.limit),s)return this.animatedScroll=this.targetScroll=e,this.setScroll(this.scroll),this.reset(),void(null==h||h(this));if(!c){if(e===this.targetScroll)return;this.targetScroll=e}this.animate.fromTo(this.animatedScroll,e,{duration:n,easing:r,lerp:l,onStart:()=>{o&&(this.isLocked=!0),this.isScrolling=!0},onUpdate:(t,e)=>{this.isScrolling=!0,this.velocity=t-this.animatedScroll,this.direction=Math.sign(this.velocity),this.animatedScroll=t,this.setScroll(this.scroll),c&&(this.targetScroll=t),e||this.emit(),e&&(this.reset(),this.emit(),null==h||h(this),this.__preventNextScrollEvent=!0,requestAnimationFrame((()=>{delete this.__preventNextScrollEvent})))}})}}}get rootElement(){return this.options.wrapper===window?document.documentElement:this.options.wrapper}get limit(){return this.options.__experimental__naiveDimensions?this.isHorizontal?this.rootElement.scrollWidth-this.rootElement.clientWidth:this.rootElement.scrollHeight-this.rootElement.clientHeight:this.dimensions.limit[this.isHorizontal?\"x\":\"y\"]}get isHorizontal(){return\"horizontal\"===this.options.orientation}get actualScroll(){return this.isHorizontal?this.rootElement.scrollLeft:this.rootElement.scrollTop}get scroll(){return this.options.infinite?(t=this.animatedScroll,e=this.limit,(t%e+e)%e):this.animatedScroll;var t,e}get progress(){return 0===this.limit?1:this.scroll/this.limit}get isSmooth(){return this.__isSmooth}set isSmooth(t){this.__isSmooth!==t&&(this.__isSmooth=t,this.toggleClassName(\"lenis-smooth\",t))}get isScrolling(){return this.__isScrolling}set isScrolling(t){this.__isScrolling!==t&&(this.__isScrolling=t,this.toggleClassName(\"lenis-scrolling\",t))}get isStopped(){return this.__isStopped}set isStopped(t){this.__isStopped!==t&&(this.__isStopped=t,this.toggleClassName(\"lenis-stopped\",t))}get isLocked(){return this.__isLocked}set isLocked(t){this.__isLocked!==t&&(this.__isLocked=t,this.toggleClassName(\"lenis-locked\",t))}get className(){let t=\"lenis\";return this.isStopped&&(t+=\" lenis-stopped\"),this.isLocked&&(t+=\" lenis-locked\"),this.isScrolling&&(t+=\" lenis-scrolling\"),this.isSmooth&&(t+=\" lenis-smooth\"),t}toggleClassName(t,e){this.rootElement.classList.toggle(t,e),this.emitter.emit(\"className change\",this)}}\n//# sourceMappingURL=lenis.mjs.map\n\n;// CONCATENATED MODULE: ./node_modules/gsap/gsap-core.js\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\n/*!\n * GSAP 3.12.5\n * https://gsap.com\n *\n * @license Copyright 2008-2024, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license or for\n * Club GSAP members, the agreement issued with that membership.\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar _config = {\n autoSleep: 120,\n force3D: \"auto\",\n nullTargetWarn: 1,\n units: {\n lineHeight: \"\"\n }\n},\n _defaults = {\n duration: .5,\n overwrite: false,\n delay: 0\n},\n _suppressOverwrites,\n _reverting,\n _context,\n _bigNum = 1e8,\n _tinyNum = 1 / _bigNum,\n _2PI = Math.PI * 2,\n _HALF_PI = _2PI / 4,\n _gsID = 0,\n _sqrt = Math.sqrt,\n _cos = Math.cos,\n _sin = Math.sin,\n _isString = function _isString(value) {\n return typeof value === \"string\";\n},\n _isFunction = function _isFunction(value) {\n return typeof value === \"function\";\n},\n _isNumber = function _isNumber(value) {\n return typeof value === \"number\";\n},\n _isUndefined = function _isUndefined(value) {\n return typeof value === \"undefined\";\n},\n _isObject = function _isObject(value) {\n return typeof value === \"object\";\n},\n _isNotFalse = function _isNotFalse(value) {\n return value !== false;\n},\n _windowExists = function _windowExists() {\n return typeof window !== \"undefined\";\n},\n _isFuncOrString = function _isFuncOrString(value) {\n return _isFunction(value) || _isString(value);\n},\n _isTypedArray = typeof ArrayBuffer === \"function\" && ArrayBuffer.isView || function () {},\n // note: IE10 has ArrayBuffer, but NOT ArrayBuffer.isView().\
1n_isArray = Array.isArray,\n _strictNumExp = /(?:-?\\.?\\d|\\.)+/gi,\n //only numbers (including negatives and decimals) but NOT relative values.\n_numExp = /[-+=.]*\\d+[.e\\-+]*\\d*[e\\-+]*\\d*/g,\n //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8.\n_numWithUnitExp = /[-+=.]*\\d+[.e-]*\\d*[a-z%]*/g,\n _complexStringNumExp = /[-+=.]*\\d+\\.?\\d*(?:e-|e\\+)?\\d*/gi,\n //duplicate so that while we're looping through matches from exec(), it doesn't contaminate the lastIndex of _numExp which we use to search for colors too.\n_relExp = /[+-]=-?[.\\d]+/,\n _delimitedValueExp = /[^,'\"\\[\\]\\s]+/gi,\n // previously /[#\\-+.]*\\b[a-z\\d\\-=+%.]+/gi but didn't catch special characters.\n_unitExp = /^[+\\-=e\\s\\d]*\\d+[.\\d]*([a-z]*|%)\\s*$/i,\n _globalTimeline,\n _win,\n _coreInitted,\n _doc,\n _globals = {},\n _installScope = {},\n _coreReady,\n _install = function _install(scope) {\n return (_installScope = _merge(scope, _globals)) && gsap;\n},\n _missingPlugin = function _missingPlugin(property, value) {\n return console.warn(\"Invalid property\", property, \"set to\", value, \"Missing plugin? gsap.registerPlugin()\");\n},\n _warn = function _warn(message, suppress) {\n return !suppress && console.warn(message);\n},\n _addGlobal = function _addGlobal(name, obj) {\n return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals;\n},\n _emptyFunc = function _emptyFunc() {\n return 0;\n},\n _startAtRevertConfig = {\n suppressEvents: true,\n isStart: true,\n kill: false\n},\n _revertConfigNoKill = {\n suppressEvents: true,\n kill: false\n},\n _revertConfig = {\n suppressEvents: true\n},\n _reservedProps = {},\n _lazyTweens = [],\n _lazyLookup = {},\n _lastRenderedFrame,\n _plugins = {},\n _effects = {},\n _nextGCFrame = 30,\n _harnessPlugins = [],\n _callbackNames = \"\",\n _harness = function _harness(targets) {\n var target = targets[0],\n harnessPlugin,\n i;\n _isObject(target) || _isFunction(target) || (targets = [targets]);\n\n if (!(harnessPlugin = (target._gsap || {}).harness)) {\n // find the first target with a harness. We assume targets passed into an animation will be of similar type, meaning the same kind of harness can be used for them all (performance optimization)\n i = _harnessPlugins.length;\n\n while (i-- && !_harnessPlugins[i].targetTest(target)) {}\n\n harnessPlugin = _harnessPlugins[i];\n }\n\n i = targets.length;\n\n while (i--) {\n targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1);\n }\n\n return targets;\n},\n _getCache = function _getCache(target) {\n return target._gsap || _harness(toArray(target))[0]._gsap;\n},\n _getProperty = function _getProperty(target, property, v) {\n return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v;\n},\n _forEachName = function _forEachName(names, func) {\n return (names = names.split(\",\")).forEach(func) || names;\n},\n //split a comma-delimited list of names into an array, then run a forEach() function and return the split array (this is just a way to consolidate/shorten some code).\n_round = function _round(value) {\n return Math.round(value * 100000) / 100000 || 0;\n},\n _roundPrecise = function _roundPrecise(value) {\n return Math.round(value * 10000000) / 10000000 || 0;\n}
1,\n // increased precision mostly for timing values.\n_parseRelative = function _parseRelative(start, value) {\n var operator = value.charAt(0),\n end = parseFloat(value.substr(2));\n start = parseFloat(start);\n return operator === \"+\" ? start + end : operator === \"-\" ? start - end : operator === \"*\" ? start * end : start / end;\n},\n _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) {\n //searches one array to find matches for any of the items in the toFind array. As soon as one is found, it returns true. It does NOT return all the matches; it's simply a boolean search.\n var l = toFind.length,\n i = 0;\n\n for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {}\n\n return i < l;\n},\n _lazyRender = function _lazyRender() {\n var l = _lazyTweens.length,\n a = _lazyTweens.slice(0),\n i,\n tween;\n\n _lazyLookup = {};\n _lazyTweens.length = 0;\n\n for (i = 0; i < l; i++) {\n tween = a[i];\n tween && tween._lazy && (tween.render(tween._lazy[0], tween._lazy[1], true)._lazy = 0);\n }\n},\n _lazySafeRender = function _lazySafeRender(animation, time, suppressEvents, force) {\n _lazyTweens.length && !_reverting && _lazyRender();\n animation.render(time, suppressEvents, force || _reverting && time < 0 && (animation._initted || animation._startAt));\n _lazyTweens.length && !_reverting && _lazyRender(); //in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render.\n},\n _numericIfPossible = function _numericIfPossible(value) {\n var n = parseFloat(value);\n return (n || n === 0) && (value + \"\").match(_delimitedValueExp).length < 2 ? n : _isString(value) ? value.trim() : value;\n},\n _passThrough = function _passThrough(p) {\n return p;\n},\n _setDefaults = function _setDefaults(obj, defaults) {\n for (var p in defaults) {\n p in obj || (obj[p] = defaults[p]);\n }\n\n return obj;\n},\n _setKeyframeDefaults = function _setKeyframeDefaults(excludeDuration) {\n return function (obj, defaults) {\n for (var p in defaults) {\n p in obj || p === \"duration\" && excludeDuration || p === \"ease\" || (obj[p] = defaults[p]);\n }\n };\n},\n _merge = function _merge(base, toMerge) {\n for (var p in toMerge) {\n base[p] = toMerge[p];\n }\n\n return base;\n},\n _mergeDeep = function _mergeDeep(base, toMerge) {\n for (var p in toMerge) {\n p !== \"__proto__\" && p !== \"constructor\" && p !== \"prototype\" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]);\n }\n\n return base;\n},\n _copyExcluding = function _copyExcluding(obj, excluding) {\n var copy = {},\n p;\n\n for (p in obj) {\n p in excluding || (copy[p] = obj[p]);\n }\n\n return copy;\n},\n _inheritDefaults = function _inheritDefaults(vars) {\n var parent = vars.parent || _globalTimeline,\n func = vars.keyframes ? _setKeyframeDefaults(_isArray(vars.keyframes)) : _setDefaults;\n\n if (_isNotFalse(vars.inherit)) {\n while (parent) {\n func(vars, parent.vars.defaults);\n parent = parent.parent || parent._dp;\n }\n }\n\n return vars;\n},\n _arraysMatch = function _arraysMatch(a1, a2) {\n var i = a1.length,\n match = i === a2.length;\n\n while (match && i-- && a1[i] === a2[i]) {}\n\n return i < 0;\n},\n _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) {\n if (firstProp === void 0) {\n firstProp = \"_first\";\n }\n\n if (lastProp === void 0) {\n lastProp = \"_last\";\n }\n\n var prev = parent[lastProp],\n t;\n\n if (sortBy) {\n t = child[sortBy];\n\n while (prev && prev[sortBy] > t) {\n prev = prev._prev;\n }\n }\n\n if (prev) {\n child._next = prev._next;\n prev._next = child;\n } else {\n child._next = parent[firstProp];\n parent[firstProp] = child;\n }\n\n if (child._next) {\n child._next._prev = child;\n } else {\n parent[lastProp] = child;\n }\n\n child._prev = prev;\n child.parent = child._dp = parent;\n return child;\n},\n _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) {\n if (firstProp === void 0) {\n firstProp = \"_first\";\n }\n\n if (lastProp === void 0) {\n lastProp = \"_last\";\n }\n\n var prev = child._prev,\n next = child._next;\n\n if (prev) {\n prev._next = next;\n } else if (parent[firstProp] === child) {\n parent[firstProp] = next;\n }\n\n if (next) {\n next._prev = prev;\n } else if (parent[lastProp] === child) {\n parent[lastProp] = prev;\n }\n\n child._next = child._prev = child.parent = null; // don't delete the _dp just so we can revert if necessary. But parent should be null to indicate the item isn't in a linked list.\n},\n _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) {\n child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove && child.parent.remove(child);\n child._act = 0;\n},\n _uncache = function _uncache(animation, child) {\n if (animation && (!child || child._end > animation._dur || child._start < 0)) {\n // performance optimization: if a child animation is passed in we should only uncache if that child EXTENDS the animation (its end time is beyond the end)\n var a = animation;\n\n while (a) {\n a._dirty = 1;\n a = a.parent;\n }\n }\n\n return animation;\n},\n _recacheAncestors = function _recacheAncestors(animation) {\n var parent = animation.parent;\n\n while (parent && parent.parent) {\n //sometimes we must force a re-sort of all children and update the duration/totalDuration of all ancestor timelines immediately in case, for example, in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though.\n parent._dirty = 1;\n parent.totalDuration();\n parent = parent.parent;\n }\n\n return animation;\n},\n _rewindStartAt = function _rewindStartAt(tween, totalTime, suppressEvents, force) {\n return tween._startAt && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween.vars.immediateRender && !tween.vars.autoRevert || tween._startAt.render(totalTime, true, force));\n},\n _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) {\n return !animation || animation._ts && _hasNoPausedAncestors(animation.parent);\n},\n _elapsedCycleDuration = function _elapsedCycleDuration(animation) {\n return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0;\n},\n // feed in the totalTime and cycleDuration and it'll return the cycle (iteration minus 1) and if the playhead is exactly at the very END, it will NOT bump up to the next cycle.\n_animationCycle = function _animationCycle(tTime, cycleDuration) {\n var whole = Math.floor(tTime /= cycleDuration);\n return tTime && whole === tTime ? whole - 1 : whole;
1\n},\n _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) {\n return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur);\n},\n _setEnd = function _setEnd(animation) {\n return animation._end = _roundPrecise(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0));\n},\n _alignPlayhead = function _alignPlayhead(animation, totalTime) {\n // adjusts the animation's _start and _end according to the provided totalTime (only if the parent's smoothChildTiming is true and the animation isn't paused). It doesn't do any rendering or forcing things back into parent timelines, etc. - that's what totalTime() is for.\n var parent = animation._dp;\n\n if (parent && parent.smoothChildTiming && animation._ts) {\n animation._start = _roundPrecise(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts));\n\n _setEnd(animation);\n\n parent._dirty || _uncache(parent, animation); //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here.\n }\n\n return animation;\n},\n\n/*\n_totalTimeToTime = (clampedTotalTime, duration, repeat, repeatDelay, yoyo) => {\n\tlet cycleDuration = duration + repeatDelay,\n\t\ttime = _round(clampedTotalTime % cycleDuration);\n\tif (time > duration) {\n\t\ttime = duration;\n\t}\n\treturn (yoyo && (~~(clampedTotalTime / cycleDuration) & 1)) ? duration - time : time;\n},\n*/\n_postAddChecks = function _postAddChecks(timeline, child) {\n var t;\n\n if (child._time || !child._dur && child._initted || child._start < timeline._time && (child._dur || !child.add)) {\n // in case, for example, the _start is moved on a tween that has already rendered, or if it's being inserted into a timeline BEFORE where the playhead is currently. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning. Special case: if it's a timeline (has .add() method) and no duration, we can skip rendering because the user may be populating it AFTER adding it to a parent timeline (unconventional, but possible, and we wouldn't want it to get removed if the parent's autoRemoveChildren is true).\n t = _parentToChildTotalTime(timeline.rawTime(), child);\n\n if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) {\n child.render(t, true);\n }\n } //if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate.\n\n\n if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) {\n //in case any of the ancestors had completed but should now be enabled...\n if (timeline._dur < timeline.duration()) {\n t = timeline;\n\n while (t._dp) {\n t.rawTime() >= 0 && t.totalTime(t._tTime); //moves the timeline (shifts its startTime) if necessary, and also enables it. If it's currently zero, though, it may not be scheduled to render until later so there's no need to force it to align with the current playhead position. Only move to catch up with the playhead.\n\n t = t._dp;\n }\n }\n\n timeline._zTime = -_tinyNum; // helps ensure that the next render() will be forced (crossingStart = true in render()), even if the duration hasn't changed (we're adding a child which w
1ould need to get rendered). Definitely an edge case. Note: we MUST do this AFTER the loop above where the totalTime() might trigger a render() because this _addToTimeline() method gets called from the Animation constructor, BEFORE tweens even record their targets, etc. so we wouldn't want things to get triggered in the wrong order.\n }\n},\n _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) {\n child.parent && _removeFromParent(child);\n child._start = _roundPrecise((_isNumber(position) ? position : position || timeline !== _globalTimeline ? _parsePosition(timeline, position, child) : timeline._time) + child._delay);\n child._end = _roundPrecise(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0));\n\n _addLinkedListItem(timeline, child, \"_first\", \"_last\", timeline._sort ? \"_start\" : 0);\n\n _isFromOrFromStart(child) || (timeline._recent = child);\n skipChecks || _postAddChecks(timeline, child);\n timeline._ts < 0 && _alignPlayhead(timeline, timeline._tTime); // if the timeline is reversed and the new child makes it longer, we may need to adjust the parent's _start (push it back)\n\n return timeline;\n},\n _scrollTrigger = function _scrollTrigger(animation, trigger) {\n return (_globals.ScrollTrigger || _missingPlugin(\"scrollTrigger\", trigger)) && _globals.ScrollTrigger.create(trigger, animation);\n},\n _attemptInitTween = function _attemptInitTween(tween, time, force, suppressEvents, tTime) {\n _initTween(tween, time, tTime);\n\n if (!tween._initted) {\n return 1;\n }\n\n if (!force && tween._pt && !_reverting && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) {\n _lazyTweens.push(tween);\n\n tween._lazy = [tTime, suppressEvents];\n return 1;\n }\n},\n _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) {\n var parent = _ref.parent;\n return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent));\n},\n // check parent's _lock because when a timeline repeats/yoyos and does its artificial wrapping, we shouldn't force the ratio back to 0\n_isFromOrFromStart = function _isFromOrFromStart(_ref2) {\n var data = _ref2.data;\n return data === \"isFromStart\" || data === \"isStart\";\n},\n _renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) {\n var prevRatio = tween.ratio,\n ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) && !(!tween._initted && _isFromOrFromStart(tween)) || (tween._ts < 0 || tween._dp._ts < 0) && !_isFromOrFromStart(tween)) ? 0 : 1,\n // if the tween or its parent is reversed and the totalTime is 0, we should go to a ratio of 0. Edge case: if a from() or fromTo() stagger tween is placed later in a timeline, the \"startAt\" zero-duration tween could initially render at a time when the parent timeline's playhead is technically BEFORE where this tween is, so make sure that any \"from\" and \"fromTo\" startAt tweens are rendered the first time at a ratio of 1.\n repeatDelay = tween._rDelay,\n tTime = 0,\n pt,\n iteration,\n prevIteration;\n\n if (repeatDelay && tween._repeat) {\n // in case there's a zero-duration tween that has a repeat with a repeatDelay\n tTime = _clamp(0, tween._tDur, totalTime);\n iteration = _animationCycle(tTime, repeatDelay);\n tween._yoyo && iteration & 1 && (ratio = 1 - ratio);\n\n if (iteration !== _animationCycle(tween._tTime, repeatDelay)) {\n // if iteration changed\n prevRatio = 1 - ratio;\n tween.vars.repeatRefresh && tween._initted && tween.invalidate();\n }\n }\n\n if (ratio !== prevRatio || _reverting || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) {\n if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents, tTime)) {\
1n // if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately.\n return;\n }\n\n prevIteration = tween._zTime;\n tween._zTime = totalTime || (suppressEvents ? _tinyNum : 0); // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect.\n\n suppressEvents || (suppressEvents = totalTime && !prevIteration); // if it was rendered previously at exactly 0 (_zTime) and now the playhead is moving away, DON'T fire callbacks otherwise they'll seem like duplicates.\n\n tween.ratio = ratio;\n tween._from && (ratio = 1 - ratio);\n tween._time = 0;\n tween._tTime = tTime;\n pt = tween._pt;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n\n totalTime < 0 && _rewindStartAt(tween, totalTime, suppressEvents, true);
1\n tween._onUpdate && !suppressEvents && _callback(tween, \"onUpdate\");\n tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, \"onRepeat\");\n\n if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) {\n ratio && _removeFromParent(tween, 1);\n\n if (!suppressEvents && !_reverting) {\n _callback(tween, ratio ? \"onComplete\" : \"onReverseComplete\", true);\n\n tween._prom && tween._prom();\n }\n }\n } else if (!tween._zTime) {\n tween._zTime = totalTime;\n }\n},\n _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) {\n var child;\n\n if (time > prevTime) {\n child = animation._first;\n\n while (child && child._start <= time) {\n if (child.data === \"isPause\" && child._start > prevTime) {\n return child;\n }\n\n child = child._next;\n }\n } else {\n child = animation._last;\n\n while (child && child._start >= time) {\n if (child.data === \"isPause\" && child._start < prevTime) {\n return child;\n }\n\n child = child._prev;\n }\n }\n},\n _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) {\n var repeat = animation._repeat,\n dur = _roundPrecise(duration) || 0,\n totalProgress = animation._tTime / animation._tDur;\n totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur);\n animation._dur = dur;\n animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _roundPrecise(dur * (repeat + 1) + animation._rDelay * repeat);\n totalProgress > 0 && !leavePlayhead && _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress);\n animation.parent && _setEnd(animation);\n skipUncache || _uncache(animation.parent, animation);\n return animation;\n},\n _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) {\n return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur);\n},\n _zeroPosition = {\n _start: 0,\n endTime: _emptyFunc,\n totalDuration: _emptyFunc\n},\n _parsePosition = function _parsePosition(animation, position, percentAnimation) {\n var labels = animation.labels,\n recent = animation._recent || _zeroPosition,\n clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur,\n //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead.\n i,\n offset,\n isPercent;\n\n if (_isString(position) && (isNaN(position) || position in labels)) {\n //if the string is a number like \"1\", check to see if there's a label with that name, otherwise interpret it as a number (absolute value).\n offset = position.charAt(0);\n isPercent = position.substr(-1) === \"%\";\n i = position.indexOf(\"=\");\n\n if (offset === \"<\" || offset === \">\") {\n i >= 0 && (position = position.replace(/=/, \"\"));\n return (offset === \"<\" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0) * (isPercent ? (i < 0 ? recent : percentAnimation).totalDuration() / 100 : 1);\n }\n\n if (i < 0) {\n position in labels || (labels[position] = clippedDuration);\n return labels[position];\n }\n\n offset = parseFloat(position.charAt(i - 1) + position.substr(i + 1));\n\n if (isPercent && percentAnimation) {\n offset = offset / 100 * (_isArray(percentAnimation) ? percentAnimation[0] : percentAnimation).totalDuration();\n }\n\n return i > 1 ? _parsePosition(animation, position.substr(0, i - 1), percentAnimation) + offset : clippedDuration + offset;\n }\n\n return position == null ? clippedDuration : +position;\n},\n _createTweenType = function _createTweenType(type, params, timeline) {\n var isLegacy = _isNumber(params[1]),\n varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1),\n vars = params[varsIndex],\n irVars,\n parent;\n\n isLegacy && (vars.duration = params[1]);\n vars.parent = timeline;\n\n if (type) {\n irVars = vars;\n parent = timeline;
1\n\n while (parent && !(\"immediateRender\" in irVars)) {\n // inheritance hasn't happened yet, but someone may have set a default in an ancestor timeline. We could do vars.immediateRender = _isNotFalse(_inheritDefaults(vars).immediateRender) but that'd exact a slight performance penalty because _inheritDefaults() also runs in the Tween constructor. We're paying a small kb price here to gain speed.\n irVars = parent.vars.defaults || {};\n parent = _isNotFalse(parent.vars.inherit) && parent.parent;\n }\n\n vars.immediateRender = _isNotFalse(irVars.immediateRender);\n type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1]; // \"from\" vars\n }\n\n return new Tween(params[0], vars, params[varsIndex + 1]);\n},\n _conditionalReturn = function _conditionalReturn(value, func) {\n return value || value === 0 ? func(value) : func;\n},\n _clamp = function _clamp(min, max, value) {\n return value < min ? min : value > max ? max : value;\n},\n getUnit = function getUnit(value, v) {\n return !_isString(value) || !(v = _unitExp.exec(value)) ? \"\" : v[1];\n},\n // note: protect against padded numbers as strings, like \"100.100\". That shouldn't return \"00\" as the unit. If it's numeric, return no unit.\nclamp = function clamp(min, max, value) {\n return _conditionalReturn(value, function (v) {\n return _clamp(min, max, v);\n });\n},\n _slice = [].slice,\n _isArrayLike = function _isArrayLike(value, nonEmpty) {\n return value && _isObject(value) && \"length\" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win;\n},\n _flatten = function _flatten(ar, leaveStrings, accumulator) {\n if (accumulator === void 0) {\n accumulator = [];\n }\n\n return ar.forEach(function (value) {\n var _accumulator;\n\n return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value);\n }) || accumulator;\n},\n //takes any value and returns an array. If it's a string (and leaveStrings isn't true), it'll use document.querySelectorAll() and convert that to an array. It'll also accept iterables like jQuery objects.\ntoArray = function toArray(value, scope, leaveStrings) {\n return _context && !scope && _context.selector ? _context.selector(value) : _isString(value) && !leaveStrings && (_coreInitted || !_wake()) ? _slice.call((scope || _doc).querySelectorAll(value), 0) : _isArray(value) ? _flatten(value, leaveStrings) : _isArrayLike(value) ? _slice.call(value, 0) : value ? [value] : [];\n},\n selector = function selector(value) {\n value = toArray(value)[0] || _warn(\"Invalid scope\") || {};\n return function (v) {\n var el = value.current || value.nativeElement || value;\n return toArray(v, el.querySelectorAll ? el : el === value ? _warn(\"Invalid scope\") || _doc.createElement(\"div\") : value);\n };\n},\n shuffle = function shuffle(a) {\n return a.sort(function () {\n return .5 - Math.random();\n });\n},\n // alternative that's a bit faster and more reliably diverse but bigger: for (let j, v, i = a.length; i; j = Math.floor(Math.random() * i), v = a[--i], a[i] = a[j], a[j] = v); return a;\n//for distributing values across an array. Can accept a number, a function or (most commonly) a function which can contain the following properties: {base, amount, from, ease, grid, axis, length, each}. Returns a function that expects the following parameters: index, target, array. Recognizes the following\ndistribute = function distribute(v) {\n if (_isFunction(v)) {\n return v;\n }\n\n var vars = _isObject(v) ? v : {\n each: v\n },\n //n:1 is just to indicate v was a number; we leverage that later to set v according to the length we get. If a number is passed in, we treat it like the old stagger value where 0.1, for example, would mean that things would be distributed with 0.1 between each element in the array rather than a total \"amount\" that's chunked out among them all.\n ease = _parseEase(vars.ease),\n from = vars.from || 0,\n base = parseFloat(vars.base) || 0,\n cache = {},\n isDecimal = from > 0 && from < 1,\n ratios = isNaN(from) || isDecimal,\n axis = vars.axis,\n ratioX = from,\n ratioY = from;\n\n if (_isString(from)) {\n ratioX = ratioY = {\n center: .5,\n edges: .5,\n end: 1\n }[from] || 0;\n } else if (!isDecimal && ratios) {\n ratioX = from[0];\n ratioY = from[1];\n }
1\n\n return function (i, target, a) {\n var l = (a || vars).length,\n distances = cache[l],\n originX,\n originY,\n x,\n y,\n d,\n j,\n max,\n min,\n wrapAt;\n\n if (!distances) {\n wrapAt = vars.grid === \"auto\" ? 0 : (vars.grid || [1, _bigNum])[1];\n\n if (!wrapAt) {\n max = -_bigNum;\n\n while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {}\n\n wrapAt < l && wrapAt--;\n }\n\n distances = cache[l] = [];\n originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt;\n originY = wrapAt === _bigNum ? 0 : ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0;\n max = 0;\n min = _bigNum;\n\n for (j = 0; j < l; j++) {\n x = j % wrapAt - originX;\n y = originY - (j / wrapAt | 0);\n distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === \"y\" ? y : x);\n d > max && (max = d);\n d < min && (min = d);\n }\n\n from === \"random\" && shuffle(distances);\n distances.max = max - min;\n distances.min = min;\n distances.v = l = (parseFloat(vars.amount) || parseFloat(vars.each) * (wrapAt > l ? l - 1 : !axis ? Math.max(wrapAt, l / wrapAt) : axis === \"y\" ? l / wrapAt : wrapAt) || 0) * (from === \"edges\" ? -1 : 1);\n distances.b = l < 0 ? base - l : base;\n distances.u = getUnit(vars.amount || vars.each) || 0; //unit\n\n ease = ease && l < 0 ? _invertEase(ease) : ease;\n }\n\n l = (distances[i] - distances.min) / distances.max || 0;\n return _roundPrecise(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u; //round in order to work around floating point errors\n };\n},\n _roundModifier = function _roundModifier(v) {\n //pass in 0.1 get a function that'll round to the nearest tenth, or 5 to round to the closest 5, or 0.001 to the closest 1000th, etc.\n var p = Math.pow(10, ((v + \"\").split(\".\")[1] || \"\").length); //to avoid floating point math errors (like 24 * 0.1 == 2.4000000000000004), we chop off at a specific number of decimal places (much faster than toFixed())\n\n return function (raw) {\n var n = _roundPrecise(Math.round(parseFloat(raw) / v) * v * p);\n\n return (n - n % 1) / p + (_isNumber(raw) ? 0 : getUnit(raw)); // n - n % 1 replaces Math.floor() in order to handle negative values properly. For example, Math.floor(-150.00000000000003) is 151!\n };\n},\n snap = function snap(snapTo, value) {\n var isArray = _isArray(snapTo),\n radius,\n is2D;\n\n if (!isArray && _isObject(snapTo)) {\n radius = isArray = snapTo.radius || _bigNum;\n\n if (snapTo.values) {\n snapTo = toArray(snapTo.values);\n\n if (is2D = !_isNumber(snapTo[0])) {\n radius *= radius; //performance optimization so we don't have to Math.sqrt() in the loop.\n }\n } else {\n snapTo = _roundModifier(snapTo.increment);\n }\n }\n\n return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) {\n is2D = snapTo(raw);\n return Math.abs(is2D - raw) <= radius ? is2D : raw;\n } : function (raw) {\n var x = parseFloat(is2D ? raw.x : raw),\n y = parseFloat(is2D ? raw.y : 0),\n min = _bigNum,\n closest = 0,\n i = snapTo.length,\n dx,\n dy;\n\n while (i--) {\n if (is2D) {\n dx = snapTo[i].x - x;\n dy = snapTo[i].y - y;\n dx = dx * dx + dy * dy;\n } else {\n dx = Math.abs(snapTo[i] - x);\n }\n\n if (dx < min) {\n min = dx;\n closest = i;\n }\n }\n\n closest = !radius || min <= radius ? snapTo[closest] : raw;\n return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw);\n });\n},\n random = function random(min, max, roundingIncrement, returnFunction) {\n return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () {\n return _isArray(min) ? min[~~(Math.random() * min.length)] : (roundingIncrement = roundingIncrement || 1e
1-5) && (returnFunction = roundingIncrement < 1 ? Math.pow(10, (roundingIncrement + \"\").length - 2) : 1) && Math.floor(Math.round((min - roundingIncrement / 2 + Math.random() * (max - min + roundingIncrement * .99)) / roundingIncrement) * roundingIncrement * returnFunction) / returnFunction;\n });\n},\n pipe = function pipe() {\n for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) {\n functions[_key] = arguments[_key];\n }\n\n return function (value) {\n return functions.reduce(function (v, f) {\n return f(v);\n }, value);\n };\n},\n unitize = function unitize(func, unit) {\n return function (value) {\n return func(parseFloat(value)) + (unit || getUnit(value));\n };\n},\n normalize = function normalize(min, max, value) {\n return mapRange(min, max, 0, 1, value);\n},\n _wrapArray = function _wrapArray(a, wrapper, value) {\n return _conditionalReturn(value, function (index) {\n return a[~~wrapper(index)];\n });\n},\n wrap = function wrap(min, max, value) {\n // NOTE: wrap() CANNOT be an arrow function! A very odd compiling bug causes problems (unrelated to GSAP).\n var range = max - min;\n return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) {\n return (range + (value - min) % range) % range + min;\n });\n},\n wrapYoyo = function wrapYoyo(min, max, value) {\n var range = max - min,\n total = range * 2;\n return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) {\n value = (total + (value - min) % total) % total || 0;\n return min + (value > range ? total - value : value);\n });\n},\n _replaceRandom = function _replaceRandom(value) {\n //replaces all occurrences of random(...) in a string with the calculated random value. can be a range like random(-100, 100, 5) or an array like random([0, 100, 500])\n var prev = 0,\n s = \"\",\n i,\n nums,\n end,\n isArray;\n\n while (~(i = value.indexOf(\"random(\", prev))) {\n end = value.indexOf(\")\", i);\n isArray = value.charAt(i + 7) === \"[\";\n nums = value.substr(i + 7, end - i - 7).match(isArray ? _delimitedValueExp : _strictNumExp);\n s += value.substr(prev, i - prev) + random(isArray ? nums : +nums[0], isArray ? 0 : +nums[1], +nums[2] || 1e-5);\n prev = end + 1;\n }\n\n return s + value.substr(prev, value.length - prev);\n},\n mapRange = function mapRange(inMin, inMax, outMin, outMax, value) {\n var inRange = inMax - inMin,\n outRange = outMax - outMin;\n return _conditionalReturn(value, function (value) {\n return outMin + ((value - inMin) / inRange * outRange || 0);\n });\n},\n interpolate = function interpolate(start, end, progress, mutate) {\n var func = isNaN(start + end) ? 0 : function (p) {\n return (1 - p) * start + p * end;\n };\n\n if (!func) {\n var isString = _isString(start),\n master = {},\n p,\n i,\n interpolators,\n l,\n il;\n\n progress === true && (mutate = 1) && (progress = null);\n\n if (isString) {\n start = {\n p: start\n };\n end = {\n p: end\n };\n } else if (_isArray(start) && !_isArray(end)) {\n interpolators = [];\n l = start.length;\n il = l - 2;\n\n for (i = 1; i < l; i++) {\n interpolators.push(interpolate(start[i - 1], start[i])); //build the interpolators up front as a performance optimization so that when the function is called many times, it can just reuse them.\n }\n\n l--;\n\n func = function func(p) {\n p *= l;\n var i = Math.min(il, ~~p);\n return interpolators[i](p - i);\n };\n\n progress = end;\n } else if (!mutate) {\n start = _merge(_isArray(start) ? [] : {}, start);\n }\n\n if (!interpolators) {\n for (p in end) {\n _addPropTween.call(master, start, p, \"get\", end[p]);\n }\n\n func = function func(p) {\n return _renderPropTweens(p, master) || (isString ? start.p : start);\n };\n }\n }\n\n return _conditionalReturn(progress, func);\n},\n _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) {\n //used for nextLabel() and previousLabel()\n var labels = timeline.labels,\n min = _bigNum,\n p,\n distance,\n label;\n\n for (p in labels) {\n distance = labels[p] - fromTime;\n\n if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) {\n label = p;\n min = distance;\n }\n }\n\n return label;\n},\n _callback = function _callback(animation, type, executeLazyFirst) {\n var v = animation.vars,\n callback = v[type],\n prevContext = _context,\n context = animation._ctx,\n params,\n scope,\n result;\n\n if (!callback) {\n return;\n }\n\n params = v[type + \"Params\"];\n scope = v.callbackScope || animation;\n executeLazyFirst && _lazyTweens.length && _lazyRender(); //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.\
1n\n context && (_context = context);\n result = params ? callback.apply(scope, params) : callback.call(scope);\n _context = prevContext;\n return result;\n},\n _interrupt = function _interrupt(animation) {\n _removeFromParent(animation);\n\n animation.scrollTrigger && animation.scrollTrigger.kill(!!_reverting);\n animation.progress() < 1 && _callback(animation, \"onInterrupt\");\n return animation;\n},\n _quickTween,\n _registerPluginQueue = [],\n _createPlugin = function _createPlugin(config) {\n if (!config) return;\n config = !config.name && config[\"default\"] || config; // UMD packaging wraps things oddly, so for example MotionPathHelper becomes {MotionPathHelper:MotionPathHelper, default:MotionPathHelper}.\n\n if (_windowExists() || config.headless) {\n // edge case: some build tools may pass in a null/undefined value\n var name = config.name,\n isFunc = _isFunction(config),\n Plugin = name && !isFunc && config.init ? function () {\n this._props = [];\n } : config,\n //in case someone passes in an object that's not a plugin, like CustomEase\n instanceDefaults = {\n init: _emptyFunc,\n render: _renderPropTweens,\n add: _addPropTween,\n kill: _killPropTweensOf,\n modifier: _addPluginModifier,\n rawVars: 0\n },\n statics = {\n targetTest: 0,\n get: 0,\n getSetter: _getSetter,\n aliases: {},\n register: 0\n };\n\n _wake();\n\n if (config !== Plugin) {\n if (_plugins[name]) {\n return;\n }\n\n _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); //static methods\n\n\n _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); //instance methods\n\n\n _plugins[Plugin.prop = name] = Plugin;\n\n if (config.targetTest) {\n _harnessPlugins.push(Plugin);\n\n _reservedProps[name] = 1;\n }\n\n name = (name === \"css\" ? \"CSS\" : name.charAt(0).toUpperCase() + name.substr(1)) + \"Plugin\"; //for the global name. \"motionPath\" should become MotionPathPlugin\n }\n\n _addGlobal(name, Plugin);\n\n config.register && config.register(gsap, Plugin, PropTween);\n } else {\n _registerPluginQueue.push(config);\n }\n},\n\n/*\n * --------------------------------------------------------------------------------------\n * COLORS\n * --------------------------------------------------------------------------------------\n */\n_255 = 255,\n _colorLookup = {\n aqua: [0, _255, _255],\n lime: [0, _255, 0],\n silver: [192, 192, 192],\n black: [0, 0, 0],\n maroon: [128, 0, 0],\n teal: [0, 128, 128],\n blue: [0, 0, _255],\n navy: [0, 0, 128],\n white: [_255, _255, _255],\n olive: [128, 128, 0],\n yellow: [_255, _255, 0],\n orange: [_255, 165, 0],\n gray: [128, 128, 128],\n purple: [128, 0, 128],\n green: [0, 128, 0],\n red: [_255, 0, 0],\n pink: [_255, 192, 203],\n cyan: [0, _255, _255],\n transparent: [_255, _255, _255, 0]\n},\n // possible future idea to replace the hard-coded color name values - put this in the ticker.wake() where we set the _doc:\n// let ctx = _doc.createElement(\"canvas\").getContext(\"2d\");\n// _forEachName(\"aqua,lime,silver,black,maroon,teal,blue,navy,white,olive,yellow,orange,gray,purple,green,red,pink,cyan\", color => {ctx.fillStyle = color; _colorLookup[color] = splitColor(ctx.fillStyle)});\n_hue = function _hue(h, m1, m2) {\n h += h < 0 ? 1 : h > 1 ? -1 : 0;\n return (h * 6 < 1 ? m1 + (m2 - m1) * h * 6 : h < .5 ? m2 : h * 3 < 2 ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * _255 + .5 | 0;\n},\n splitColor = function splitColor(v, toHSL, forceAlpha) {\n var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0,\n r,\n g,\n b,\n h,\n s,\n l,\n max,\n min,\n d,\n wasHSL;\n\n if (!a) {\n if (v.substr(-1) === \",\") {\n //sometimes a trailing comma is included and we should chop it off (typically from a comma-delimited list of values like a textShadow:\"2px 2px 2px blue, 5px 5px 5px rgb(255,0,0)\" - in this example \"blue,\" has a trailing comma. We could strip it out inside parseComplex() but we'd need to do it to the beginning and ending values plus it wouldn't provide protection from other potential scenarios like if the user passes in a similar value.\n v = v.substr(0, v.length - 1);\n }\n\n if (_colorLookup[v]) {\n a = _colorLookup[v];\n } else if (v.charAt(0) === \"#\") {\n if (v.length < 6) {\n //for shorthand like #9F0 or #9F0F (could have alpha)\n r = v.charAt(1);\n g = v.charAt(2);\n b = v.charAt(3);\n v = \"#\" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : \"\");\n }\n\n if (v.length === 9) {\n // hex with alpha, like #fd5e53ff\n a = parseInt(v.substr(1, 6), 16);\n return [a >> 16, a >>
1 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255];\n }\n\n v = parseInt(v.substr(1), 16);\n a = [v >> 16, v >> 8 & _255, v & _255];\n } else if (v.substr(0, 3) === \"hsl\") {\n a = wasHSL = v.match(_strictNumExp);\n\n if (!toHSL) {\n h = +a[0] % 360 / 360;\n s = +a[1] / 100;\n l = +a[2] / 100;\n g = l <= .5 ? l * (s + 1) : l + s - l * s;\n r = l * 2 - g;\n a.length > 3 && (a[3] *= 1); //cast as number\n\n a[0] = _hue(h + 1 / 3, r, g);\n a[1] = _hue(h, r, g);\n a[2] = _hue(h - 1 / 3, r, g);\n } else if (~v.indexOf(\"=\")) {\n //if relative values are found, just return the raw strings with the relative prefixes in place.\n a = v.match(_numExp);\n forceAlpha && a.length < 4 && (a[3] = 1);\n return a;\n }\n } else {\n a = v.match(_strictNumExp) || _colorLookup.transparent;\n }\n\n a = a.map(Number);\n }\n\n if (toHSL && !wasHSL) {\n r = a[0] / _255;\n g = a[1] / _255;\n b = a[2] / _255;\n max = Math.max(r, g, b);\n min = Math.min(r, g, b);\n l = (max + min) / 2;\n\n if (max === min) {\n h = s = 0;\n } else {\n d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;\n h *= 60;\n }\n\n a[0] = ~~(h + .5);\n a[1] = ~~(s * 100 + .5);\n a[2] = ~~(l * 100 + .5);\n }\n\n forceAlpha && a.length < 4 && (a[3] = 1);\n return a;\n},\n _colorOrderData = function _colorOrderData(v) {\n // strips out the colors from the string, finds all the numeric slots (with units) and returns an array of those. The Array also has a \"c\" property which is an Array of the index values where the colors belong. This is to help work around issues where there's a mis-matched order of color/numeric data like drop-shadow(#f00 0px 1px 2px) and drop-shadow(0x 1px 2px #f00). This is basically a helper function used in _formatColors()\n var values = [],\n c = [],\n i = -1;\n v.split(_colorExp).forEach(function (v) {\n var a = v.match(_numWithUnitExp) || [];\n values.push.apply(values, a);\n c.push(i += a.length + 1);\n });\n values.c = c;\n return values;\n},\n _formatColors = function _formatColors(s, toHSL, orderMatchData) {\n var result = \"\",\n colors = (s + result).match(_colorExp),\n type = toHSL ? \"hsla(\" : \"rgba(\",\n i = 0,\n c,\n shell,\n d,\n l;\n\n if (!colors) {\n return s;\n }\n\n colors = colors.map(function (color) {\n return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + \",\" + color[1] + \"%,\" + color[2] + \"%,\" + color[3] : color.join(\",\")) + \")\";\n });\n\n if (orderMatchData) {\n d = _colorOrderData(s);\n c = orderMatchData.c;\n\n if (c.join(result) !== d.c.join(result)) {\n shell = s.replace(_colorExp, \"1\").split(_numWithUnitExp);\n l = shell.length - 1;\n\n for (; i < l; i++) {\n result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + \"0,0,0,0)\" : (d.length ? d : colors.length ? colors : orderMatchData).shift());\n }\n }\n }\n\n if (!shell) {\n shell = s.split(_colorExp);\n l = shell.length - 1;\n\n for (; i < l; i++) {\n result += shell[i] + colors[i];\n }\n }\n\n return result + shell[l];\n},\n _colorExp = function () {\n var s = \"(?:\\\\b(?:(?:rgb|rgba|hsl|hsla)\\\\(.+?\\\\))|\\\\B#(?:[0-9a-f]{3,4}){1,2}\\\\b\",\n //we'll dynamically build this Regular Expression to conserve file size. After building it, it will be able to find rgb(), rgba(), # (hexadecimal), and named color values like red, blue, purple, etc.,\n p;\n\n for (p in _colorLookup) {\n s += \"|\" + p + \"\\\\b\";\n }\n\n return new RegExp(s + \")\", \"gi\");\n}(),\n _hslExp = /hsl[a]?\\(/,\n _colorStringFilter = function _colorStringFilter(a) {\n var combined = a.join(\" \"),\n toHSL;\n _colorExp.lastIndex = 0;\n\n if (_colorExp.test(combined)) {\n toHSL = _hslExp.test(combined);\n a[1] = _formatColors(a[1], toHSL);\n a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); // make sure the order of numbers/colors match with the END value.\n\n return true;\n }\n},\n\n/*\n * --------------------------------------------------------------------------------------\n * TICKER\n * --------------------------------------------------------------------------------------\n */\n_tickerActive,\n _ticker = function () {\n var _getTime = Date.now,\n _lagThreshold = 500,\n _adjustedLag = 33,\n _startTime = _getTime(),\n _lastUpdate = _startTime,\n _gap = 1000 / 240,\n _nextTime = _gap,\n _listeners = [],\n _id,\n _req,\n _raf,\n _self,\n _delta,\n _i,\n _tick = function _tick(v) {\n var elapsed
1= _getTime() - _lastUpdate,\n manual = v === true,\n overlap,\n dispatch,\n time,\n frame;\n\n (elapsed > _lagThreshold || elapsed < 0) && (_startTime += elapsed - _adjustedLag);\n _lastUpdate += elapsed;\n time = _lastUpdate - _startTime;\n overlap = time - _nextTime;\n\n if (overlap > 0 || manual) {\n frame = ++_self.frame;\n _delta = time - _self.time * 1000;\n _self.time = time = time / 1000;\n _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap);\n dispatch = 1;\n }\n\n manual || (_id = _req(_tick)); //make sure the request is made before we dispatch the \"tick\" event so that timing is maintained. Otherwise, if processing the \"tick\" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise.\n\n if (dispatch) {\n for (_i = 0; _i < _listeners.length; _i++) {\n // use _i and check _listeners.length instead of a variable because a listener could get removed during the loop, and if that happens to an element less than the current index, it'd throw things off in the loop.\n _listeners[_i](time, _delta, frame, v);\n }\n }\n };\n\n _self = {\n time: 0,\n frame: 0,\n tick: function tick() {\n _tick(true);\n },\n deltaRatio: function deltaRatio(fps) {\n return _delta / (1000 / (fps || 60));\n },\n wake: function wake() {\n if (_coreReady) {\n if (!_coreInitted && _windowExists()) {\n _win = _coreInitted = window;\n _doc = _win.document || {};\n _globals.gsap = gsap;\n (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version);\n\n _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {});\n\n _registerPluginQueue.forEach(_createPlugin);\n }\n\n _raf = typeof requestAnimationFrame !== \"undefined\" && requestAnimationFrame;\n _id && _self.sleep();\n\n _req = _raf || function (f) {\n return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0);\n };\n\n _tickerActive = 1;\n\n _tick(2);\n }\n },\n sleep: function sleep() {\n (_raf ? cancelAnimationFrame : clearTimeout)(_id);\n _tickerActive = 0;\n _req = _emptyFunc;\n },\n lagSmoothing: function lagSmoothing(threshold, adjustedLag) {\n _lagThreshold = threshold || Infinity; // zero should be interpreted as basically unlimited\n\n _adjustedLag = Math.min(adjustedLag || 33, _lagThreshold);\n },\n fps: function fps(_fps) {\n _gap = 1000 / (_fps || 240);\n _nextTime = _self.time * 1000 + _gap;\n },\n add: function add(callback, once, prioritize) {\n var func = once ? function (t, d, f, v) {\n callback(t, d, f, v);\n\n _self.remove(func);\n } : callback;\n\n _self.remove(callback);\n\n _listeners[prioritize ? \"unshift\" : \"push\"](func);\n\n _wake();\n\n return func;\n },\n remove: function remove(callback, i) {\n ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--;\n },\n _listeners: _listeners\n };\n return _self;\n}(),\n _wake = function _wake() {\n return !_tickerActive && _ticker.wake();\n},\n //also ensures the core classes are initialized.\n\n/*\n* -------------------------------------------------\n* EASING\n* -------------------------------------------------\n*/\n_easeMap = {},\n _customEaseExp = /^[\\d.\\-M][\\d.\\-,\\s]/,\n _quotesExp = /[\"']/g,\n _parseObjectInString = function _parseObjectInString(value) {\n //takes a string like \"{wiggles:10, type:anticipate})\" and turns it into a real object. Notice it ends in \")\" and includes the {} wrappers. This is because we only use this function for parsing ease configs and prioritized optimization rather than reusability.\n var obj = {},\n split = value.substr(1, value.length - 3).split(\":\"),\n key = split[0],\n i = 1,\n l = split.length,\n index,\n val,\n parsedVal;\n\n for (; i < l;
1 i++) {\n val = split[i];\n index = i !== l - 1 ? val.lastIndexOf(\",\") : val.length;\n parsedVal = val.substr(0, index);\n obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, \"\").trim() : +parsedVal;\n key = val.substr(index + 1).trim();\n }\n\n return obj;\n},\n _valueInParentheses = function _valueInParentheses(value) {\n var open = value.indexOf(\"(\") + 1,\n close = value.indexOf(\")\"),\n nested = value.indexOf(\"(\", open);\n return value.substring(open, ~nested && nested < close ? value.indexOf(\")\", close + 1) : close);\n},\n _configEaseFromString = function _configEaseFromString(name) {\n //name can be a string like \"elastic.out(1,0.5)\", and pass in _easeMap as obj and it'll parse it out and call the actual function like _easeMap.Elastic.easeOut.config(1,0.5). It will also parse custom ease strings as long as CustomEase is loaded and registered (internally as _easeMap._CE).\n var split = (name + \"\").split(\"(\"),\n ease = _easeMap[split[0]];\n return ease && split.length > 1 && ease.config ? ease.config.apply(null, ~name.indexOf(\"{\") ? [_parseObjectInString(split[1])] : _valueInParentheses(name).split(\",\").map(_numericIfPossible)) : _easeMap._CE && _customEaseExp.test(name) ? _easeMap._CE(\"\", name) : ease;\n},\n _invertEase = function _invertEase(ease) {\n return function (p) {\n return 1 - ease(1 - p);\n };\n},\n // allow yoyoEase to be set in children and have those affected when the parent/ancestor timeline yoyos.\n_propagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) {\n var child = timeline._first,\n ease;\n\n while (child) {\n if (child instanceof Timeline) {\n _propagateYoyoEase(child, isYoyo);\n } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) {\n if (child.timeline) {\n _propagateYoyoEase(child.timeline, isYoyo);\n } else {\n ease = child._ease;\n child._ease = child._yEase;\n child._yEase = ease;\n child._yoyo = isYoyo;\n }\n }\n\n child = child._next;\n }\n},\n _parseEase = function _parseEase(ease, defaultEase) {\n return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase;\n},\n _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) {\n if (easeOut === void 0) {\n easeOut = function easeOut(p) {\n return 1 - easeIn(1 - p);\n };\n }\n\n if (easeInOut === void 0) {\n easeInOut = function easeInOut(p) {\n return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2;\n };\n }\n\n var ease = {\n easeIn: easeIn,\n easeOut: easeOut,\n easeInOut: easeInOut\n },\n lowercaseName;\n\n _forEachName(names, function (name) {\n _easeMap[name] = _globals[name] = ease;\n _easeMap[lowercaseName = name.toLowerCase()] = easeOut;\n\n for (var p in ease) {\n _easeMap[lowercaseName + (p === \"easeIn\" ? \".in\" : p === \"easeOut\" ? \".out\" : \".inOut\")] = _easeMap[name + \".\" + p] = ease[p];\n }\n });\n\n return ease;\n},\n _easeInOutFromOut = function _easeInOutFromOut(easeOut) {\n return function (p) {\n return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2;\n };\n},\n _configElastic = function _configElastic(type, amplitude, period) {\n var p1 = amplitude >= 1 ? amplitude : 1,\n //note: if amplitude is < 1, we simply adjust the period for a more natural feel. Otherwise the math doesn't work right and the curve starts at 1.\n p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1),\n p3 = p2 / _2PI * (Math.asin(1 / p1) || 0),\n easeOut = function easeOut(p) {\n return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1;\n },\n ease = type === \"out\" ? easeOut : type === \"in\" ? function (p) {\n return 1 - easeOut(1 - p);\n } : _easeInOutFromOut(easeOut);\n\n p2 = _2PI / p2; //precalculate to optimize\n\n ease.config = function (amplitude, period) {\n return _configElastic(type, amplitude, period);\n };\n\n return ease;\n},\n _configBack = function _configBack(type, overshoot) {\n if (overshoot === void 0) {\n overshoot = 1.70158;\n }\n\n var easeOut = function easeOut(p) {\n return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0;\n },\n ease = type === \"out\" ? easeOut : type === \"in\" ? function (p) {\n return 1 - easeOut(1 - p);\n } : _easeInOutFromOut(easeOut);\n\n ease.config = function (overshoot) {\n return _configBack(type, overshoot);\n };\n\n return ease;\n}; // a cheaper (kb and cpu) but more mild way to get a parameterized weighted ease by feeding in a value between -1 (easeIn) and 1 (easeOut) where 0 is linear.\n// _weightedEase = ratio => {\n// \tlet y = 0.5 + ratio / 2;\n// \treturn p => (2 * (1 - p) * p * y + p * p);\n// },\n// a stronger (but more expensive kb/cpu) parameterized weighted ease that lets you feed in a value between -1 (easeIn) and 1 (easeOut) where 0 is linear.\n// _weightedEaseStrong = ratio => {\n// \tratio = .5 + ratio / 2;\n// \tlet o = 1 / 3 * (ratio < .5 ? ratio : 1 - ratio),\n// \t\tb = ratio - o,\n// \t\tc = ratio + o;\n// \treturn p => p === 1 ? p : 3 * b * (1 - p) * (1 - p) * p + 3 * c * (1 - p) * p * p + p * p * p;\n// };\n\n\n_forEachName(\"Linear,Quad,Cubic,Quart,Quint,Strong\", function (name, i) {\n var power = i < 5 ? i + 1 : i;\n\n _insertEase(name + \",Power\" + (power - 1), i ? function (p) {\n return Math.pow(p, power);\n }
1 : function (p) {\n return p;\n }, function (p) {\n return 1 - Math.pow(1 - p, power);\n }, function (p) {\n return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2;\n });\n});\n\n_easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn;\n\n_insertEase(\"Elastic\", _configElastic(\"in\"), _configElastic(\"out\"), _configElastic());\n\n(function (n, c) {\n var n1 = 1 / c,\n n2 = 2 * n1,\n n3 = 2.5 * n1,\n easeOut = function easeOut(p) {\n return p < n1 ? n * p * p : p < n2 ? n * Math.pow(p - 1.5 / c, 2) + .75 : p < n3 ? n * (p -= 2.25 / c) * p + .9375 : n * Math.pow(p - 2.625 / c, 2) + .984375;\n };\n\n _insertEase(\"Bounce\", function (p) {\n return 1 - easeOut(1 - p);\n }, easeOut);\n})(7.5625, 2.75);\n\n_insertEase(\"Expo\", function (p) {\n return p ? Math.pow(2, 10 * (p - 1)) : 0;\n});\n\n_insertEase(\"Circ\", function (p) {\n return -(_sqrt(1 - p * p) - 1);\n});\n\n_insertEase(\"Sine\", function (p) {\n return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1;\n});\n\n_insertEase(\"Back\", _configBack(\"in\"), _configBack(\"out\"), _configBack());\n\n_easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = {\n config: function config(steps, immediateStart) {\n if (steps === void 0) {\n steps = 1;\n }\n\n var p1 = 1 / steps,\n p2 = steps + (immediateStart ? 0 : 1),\n p3 = immediateStart ? 1 : 0,\n max = 1 - _tinyNum;\n return function (p) {\n return ((p2 * _clamp(0, max, p) | 0) + p3) * p1;\n };\n }\n};\n_defaults.ease = _easeMap[\"quad.out\"];\n\n_forEachName(\"onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt\", function (name) {\n return _callbackNames += name + \",\" + name + \"Params,\";\n});\n/*\n * --------------------------------------------------------------------------------------\n * CACHE\n * --------------------------------------------------------------------------------------\n */\n\n\nvar GSCache = function GSCache(target, harness) {\n this.id = _gsID++;\n target._gsap = this;\n this.target = target;\n this.harness = harness;\n this.get = harness ? harness.get : _getProperty;\n this.set = harness ? harness.getSetter : _getSetter;\n};\n/*\n * --------------------------------------------------------------------------------------\n * ANIMATION\n * --------------------------------------------------------------------------------------\n */\n\nvar Animation = /*#__PURE__*/function () {\n function Animation(vars) {\n this.vars = vars;\n this._delay = +vars.delay || 0;\n\n if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) {\n // TODO: repeat: Infinity on a timeline's children must flag that timeline internally and affect its totalDuration, otherwise it'll stop in the negative direction when reaching the start.\n this._rDelay = vars.repeatDelay || 0;\n this._yoyo = !!vars.yoyo || !!vars.yoyoEase;\n }\n\n this._ts = 1;\n\n _setDuration(this, +vars.duration, 1, 1);\n\n this.data = vars.data;\n\n if (_context) {\n this._ctx = _context;\n\n _context.data.push(this);\n }\n\n _tickerActive || _ticker.wake();\n }\n\n var _proto = Animation.prototype;\n\n _proto.delay = function delay(value) {\n if (value || value === 0) {\n this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay);\n this._delay = value;\n return this;\n }\n\n return this._delay;\n };\n\n _proto.duration = function duration(value) {\n return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur;\n };\n\n _proto.totalDuration = function totalDuration(value) {\n if (!arguments.length) {\n return this._tDur;\n }\n\n this._dirty = 0;\n return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1));\n };\n\n _proto.totalTime = function totalTime(_totalTime, suppressEvents) {\n _wake();\n\n if (!arguments.length) {\n return this._tTime;\n }\n\n var parent = this._dp;\n\n if (parent && parent.smoothChildTiming && this._ts) {\n _alignPlayhead(this, _totalTime);\n\n !parent._dp || parent.parent || _postAddChecks(parent, this); // edge case: if this is a child of a timeline that already completed, for example, we must re-activate the parent.\n //in case any of the ancestor timelines had completed but should now be enabled, we should reset the
1ir totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The start of that child would get pushed out, but one of the ancestors may have completed.\n\n while (parent && parent.parent) {\n if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) {\n parent.totalTime(parent._tTime, true);\n }\n\n parent = parent.parent;\n }\n\n if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) {\n //if the animation doesn't have a parent, put it back into its last parent (recorded as _dp for exactly cases like this). Limit to parents with autoRemoveChildren (like globalTimeline) so that if the user manually removes an animation from a timeline and then alters its playhead, it doesn't get added back in.\n _addToTimeline(this._dp, this, this._start - this._delay);\n }\n }\n\n if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) {\n // check for _ptLookup on a Tween instance to ensure it has actually finished being instantiated, otherwise if this.reverse() gets called in the Animation constructor, it could trigger a render() here even though the _targets weren't populated, thus when _init() is called there won't be any PropTweens (it'll act like the tween is non-functional)\n this._ts || (this._pTime = _totalTime); // otherwise, if an animation is paused, then the playhead is moved back to zero, then resumed, it'd revert back to the original time at the pause\n //if (!this._lock) { // avoid endless recursion (not sure we need this yet or if it's worth the performance hit)\n // this._lock = 1;\n\n _lazySafeRender(this, _totalTime, suppressEvents); // this._lock = 0;\n //}\n\n }\n\n return this;\n };\n\n _proto.time = function time(value, suppressEvents) {\n return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % (this._dur + this._rDelay) || (value ? this._dur : 0), suppressEvents) : this._time; // note: if the modulus results in 0, the playhead could be exactly at the end or the beginning, and we always defer to the END with a non-zero value, otherwise if you set the time() to the very end (duration()), it would render at the START!\n };\n\n _proto.totalProgress = function totalProgress(value, suppressEvents) {\n return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.rawTime() > 0 ? 1 : 0;\n };\n\n _proto.progress = function progress(value, suppressEvents) {\n return arguments.length ? this.totalTime(this.duration() * (this._yoyo && !(this.iteration() & 1) ? 1 - value : value) + _elapsedCycleDuration(this), suppressEvents) : this.duration() ? Math.min(1, this._time / this._dur) : this.rawTime() > 0 ? 1 : 0;\n };\n\n _proto.iteration = function iteration(value, suppressEvents) {\n var cycleDuration = this.duration() + this._rDelay;\n\n return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1;\n } // potential future addition:\n // isPlayingBackwards() {\n // \tlet animation = this,\n // \t\torientation = 1; // 1 = forward, -1 = backward\n // \twhile (animation) {\n // \t\torientation *= animation.reversed() || (animation.repeat() && !(animation.iteration() & 1)) ? -1 : 1;\n // \t\tanimation = animation.parent;\n // \t}\n // \treturn orientation < 0;\n // }\n ;\n\n _proto.timeScale = function timeScale(value, suppressEvents) {\n if (!arguments.length) {\n return this._rts === -_tinyNum ? 0 : this._rts; // recorded timeScale. Special case: if someone calls reverse() on an animation with timeScale of 0, we assign it -_tinyNum to remember it's reversed.\n }\n\n if (this._rts === value) {\n return this;\n }\n\n var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime; // make sure to do the parentToChildTotalTime() BEFORE setting the new _ts because the old one must be used in that calculation.\n // future addition? Up side: fast and minimal file size. Down side: only w
1orks on this animation; if a timeline is reversed, for example, its childrens' onReverse wouldn't get called.\n //(+value < 0 && this._rts >= 0) && _callback(this, \"onReverse\", true);\n // prioritize rendering where the parent's playhead lines up instead of this._tTime because there could be a tween that's animating another tween's timeScale in the same rendering loop (same parent), thus if the timeScale tween renders first, it would alter _start BEFORE _tTime was set on that tick (in the rendering loop), effectively freezing it until the timeScale tween finishes.\n\n this._rts = +value || 0;\n this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; // _ts is the functional timeScale which would be 0 if the animation is paused.\n\n this.totalTime(_clamp(-Math.abs(this._delay), this._tDur, tTime), suppressEvents !== false);\n\n _setEnd(this); // if parent.smoothChildTiming was false, the end time didn't get updated in the _alignPlayhead() method, so do it here.\n\n\n return _recacheAncestors(this);\n };\n\n _proto.paused = function paused(value) {\n if (!arguments.length) {\n return this._ps;\n }\n\n if (this._ps !== value) {\n this._ps = value;\n\n if (value) {\n this._pTime = this._tTime || Math.max(-this._delay, this.rawTime()); // if the pause occurs during the delay phase, make sure that's factored in when resuming.\n\n this._ts = this._act = 0; // _ts is the functional timeScale, so a paused tween would effectively have a timeScale of 0. We record the \"real\" timeScale as _rts (recorded time scale)\n } else {\n _wake();\n\n this._ts = this._rts; //only defer to _pTime (pauseTime) if tTime is zero. Remember, someone could pause() an animation, then scrub the playhead and resume(). If the parent doesn't have smoothChildTiming, we render at the rawTime() because the startTime won't get updated.\n\n this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && Math.abs(this._zTime) !== _tinyNum && (this._tTime -= _tinyNum)); // edge case: animation.progress(1).pause().play() wouldn't render again because the playhead is already at the end, but the call to totalTime() below will add it back to its parent...and not remove it again (since removing only happens upon rendering at a new time). Offsetting the _tTime slightly is done simply to cause the final render in totalTime() that'll pop it off its timeline (if autoRemoveChildren is true, of course). Check to make sure _zTime isn't -_tinyNum to avoid an edge case where the playhead is pushed to the end but INSIDE a tween/callback, the timeline itself is paused thus halting rendering and leaving a few unrendered. When resuming, it wouldn't render those otherwise.\n }\n }\n\n return this;\n };\n\n _proto.startTime = function startTime(value) {\n if (arguments.length) {\n this._start = value;\n var parent = this.parent || this._dp;\n parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay);\n return this;\n }\n\n return this._start;\n };\n\n _proto.endTime = function endTime(includeRepeats) {\n return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts || 1);\n };\n\n _proto.rawTime = function rawTime(wrapRepeats) {\n var parent = this.parent || this._dp; // _dp = detached parent\n\n return !parent ? this._tTime : wrapRepeats && (!this._ts || this._repeat && this._time && this.totalProgress() < 1) ? this._tTime % (this._dur + this._rDelay) : !this._ts ? this._tTime : _parentToChildTotalTime(parent.rawTime(wrapRepeats), this);\n };\n\n _proto.revert = function revert(config) {\n if (config === void 0) {\n config = _revertConfig;\n }\n\n var prevIsReverting = _reverting;\n _reverting = config;\n\n if (this._initted || this._startAt) {\n this.timeline && this.timeline.revert(config);\n this.totalTime(-0.01, config.suppressEvents);\n }\n\n this.data !== \"nested\" && config.kill !== false && this.kill();\n _reverting = prevIsReverting;\n return this;\n };\n\n _proto.globalTime = function globalTime(rawTime) {\n var animation = this,\n time = arguments.length ? rawTime : animation.rawTime();\n\n while (animation) {\n time = animation._start + time / (Math.abs(animation._ts) || 1
1);\n animation = animation._dp;\n }\n\n return !this.parent && this._sat ? this._sat.globalTime(rawTime) : time; // the _startAt tweens for .fromTo() and .from() that have immediateRender should always be FIRST in the timeline (important for context.revert()). \"_sat\" stands for _startAtTween, referring to the parent tween that created the _startAt. We must discern if that tween had immediateRender so that we can know whether or not to prioritize it in revert().\n };\n\n _proto.repeat = function repeat(value) {\n if (arguments.length) {\n this._repeat = value === Infinity ? -2 : value;\n return _onUpdateTotalDuration(this);\n }\n\n return this._repeat === -2 ? Infinity : this._repeat;\n };\n\n _proto.repeatDelay = function repeatDelay(value) {\n if (arguments.length) {\n var time = this._time;\n this._rDelay = value;\n\n _onUpdateTotalDuration(this);\n\n return time ? this.time(time) : this;\n }\n\n return this._rDelay;\n };\n\n _proto.yoyo = function yoyo(value) {\n if (arguments.length) {\n this._yoyo = value;\n return this;\n }\n\n return this._yoyo;\n };\n\n _proto.seek = function seek(position, suppressEvents) {\n return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents));\n };\n\n _proto.restart = function restart(includeDelay, suppressEvents) {\n return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents));\n };\n\n _proto.play = function play(from, suppressEvents) {\n from != null && this.seek(from, suppressEvents);\n return this.reversed(false).paused(false);\n };\n\n _proto.reverse = function reverse(from, suppressEvents) {\n from != null && this.seek(from || this.totalDuration(), suppressEvents);\n return this.reversed(true).paused(false);\n };\n\n _proto.pause = function pause(atTime, suppressEvents) {\n atTime != null && this.seek(atTime, suppressEvents);\n return this.paused(true);\n };\n\n _proto.resume = function resume() {\n return this.paused(false);\n };\n\n _proto.reversed = function reversed(value) {\n if (arguments.length) {\n !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); // in case timeScale is zero, reversing would have no effect so we use _tinyNum.\n\n return this;\n }\n\n return this._rts < 0;\n };
1\n\n _proto.invalidate = function invalidate() {\n this._initted = this._act = 0;\n this._zTime = -_tinyNum;\n return this;\n };\n\n _proto.isActive = function isActive() {\n var parent = this.parent || this._dp,\n start = this._start,\n rawTime;\n return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum);\n };\n\n _proto.eventCallback = function eventCallback(type, callback, params) {\n var vars = this.vars;\n\n if (arguments.length > 1) {\n if (!callback) {\n delete vars[type];\n } else {\n vars[type] = callback;\n params && (vars[type + \"Params\"] = params);\n type === \"onUpdate\" && (this._onUpdate = callback);\n }\n\n return this;\n }\n\n return vars[type];\n };\n\n _proto.then = function then(onFulfilled) {\n var self = this;\n return new Promise(function (resolve) {\n var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough,\n _resolve = function _resolve() {\n var _then = self.then;\n self.then = null; // temporarily null the then() method to avoid an infinite loop (see https://github.com/greensock/GSAP/issues/322)\n\n _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then);\n resolve(f);\n self.then = _then;\n };\n\n if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) {\n _resolve();\n } else {\n self._prom = _resolve;\n }\n });\n };\n\n _proto.kill = function kill() {\n _interrupt(this);\n };\n\n return Animation;\n}();\n\n_setDefaults(Animation.prototype, {\n _time: 0,\n _start: 0,\n _end: 0,\n _tTime: 0,\n _tDur: 0,\n _dirty: 0,\n _repeat: 0,\n _yoyo: false,\n parent: null,\n _initted: false,\n _rDelay: 0,\n _ts: 1,\n _dp: 0,\n ratio: 0,\n _zTime: -_tinyNum,\n _prom: 0,\n _ps: false,\n _rts: 1\n});\n/*\n * -------------------------------------------------\n * TIMELINE\n * -------------------------------------------------\n */\n\n\nvar Timeline = /*#__PURE__*/function (_Animation) {\n _inheritsLoose(Timeline, _Animation);\n\n function Timeline(vars, position) {\n var _this;\n\n if (vars === void 0) {\n vars = {};\n }\n\n _this = _Animation.call(this, vars) || this;\n _this.labels = {};\n _this.smoothChildTiming = !!vars.smoothChildTiming;\n _this.autoRemoveChildren = !!vars.autoRemoveChildren;\n _this._sort = _isNotFalse(vars.sortChildren);\n _globalTimeline && _addToTimeline(vars.parent || _globalTimeline, _assertThisInitialized(_this), position);\n vars.reversed && _this.reverse();\n vars.paused && _this.paused(true);\n vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger);\n return _this;\n }\n\n var _proto2 = Timeline.prototype;\n\n _proto2.to = function to(targets, vars, position) {\n _createTweenType(0, arguments, this);\n\n return this;\n };\n\n _proto2.from = function from(targets, vars, position) {\n _createTweenType(1, arguments, this);\n\n return this;\n };\n\n _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) {\n _createTweenType(2, arguments, this);\n\n return this;\n };\n\n _proto2.set = function set(targets, vars, position) {\n vars.duration = 0;\n vars.parent = this;\n _inheritDefaults(vars).repeatDelay || (vars.repeat = 0);\n vars.immediateRender = !!vars.immediateRender;\n new Tween(targets, vars, _parsePosition(this, position), 1);\n return this;\n };\n\n _proto2.call = function call(callback, params, position) {\n return _addToTimeline(this, Tween.delayedCall(0, callback, params), position);\n } //ONLY for backward compatibility! Maybe delete?\n ;\n\n _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {\n vars.duration = duration;\n vars.stagger = vars.stagger || stagger;\n vars.onComplete = onCompleteAll;\n vars.onCompleteParams = onCompleteAllParams;\n vars.parent = this;\n new Tween(targets, vars, _parsePosition(this, position));\n return this;\n };\n\n _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {\n vars.runBackwards = 1;\n _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender);\n return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams);\n };\n\n _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) {\n toVars.startAt = fromVars;\n _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender);\n return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams);\n };\n\n _proto2.render = function render(totalTime, suppressEvents, force) {\n var prevTime = this._time,\n tDur = this._dirty ? this.totalDuration() : this._tDur,\n dur = this._dur,\n tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime),\n // if a paused timeline is resumed (or its _start is updated for another reason...which rounds it), that could result in the playhead shifting a **tiny** amount and a zero-duration child at that spot may get rendered at a different ratio, like its totalTime in render() may be 1e-17 instead of 0, for example.\n crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur),\n time,\n child,\n next,\n iteration,\n cycleDuration,\n prevPaused,\n pauseTween,\n timeScale,\n prevStart,\n prevIteration,\n yoyo,\n isYoyo;\n this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur);\n\n if (tTime !== this._tTime || force || crossingStart) {\n if (prevTime !== this._time && dur) {\n //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump).\n tTime += this._time - prevTime;
1\n totalTime += this._time - prevTime;\n }\n\n time = tTime;\n prevStart = this._start;\n timeScale = this._ts;\n prevPaused = !timeScale;\n\n if (crossingStart) {\n dur || (prevTime = this._zTime); //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect.\n\n (totalTime || !suppressEvents) && (this._zTime = totalTime);\n }\n\n if (this._repeat) {\n //adjust the time for repeats and yoyos\n yoyo = this._yoyo;\n cycleDuration = dur + this._rDelay;\n\n if (this._repeat < -1 && totalTime < 0) {\n return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);\n }\n\n time = _roundPrecise(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!)\n\n if (tTime === tDur) {\n // the tDur === tTime is for edge cases where there's a lengthy decimal on the duration and it may reach the very end but the time is rendered as not-quite-there (remember, tDur is rounded to 4 decimals whereas dur isn't)\n iteration = this._repeat;\n time = dur;\n } else {\n iteration = ~~(tTime / cycleDuration);\n\n if (iteration && iteration === tTime / cycleDuration) {\n time = dur;\n iteration--;\n }\n\n time > dur && (time = dur);\n }\n\n prevIteration = _animationCycle(this._tTime, cycleDuration);\n !prevTime && this._tTime && prevIteration !== iteration && this._tTime - prevIteration * cycleDuration - this._dur <= 0 && (prevIteration = iteration); // edge case - if someone does addPause() at the very beginning of a repeating timeline, that pause is technically at the same spot as the end which causes this._time to get set to 0 when the totalTime would normally place the playhead at the end. See https://gsap.com/forums/topic/23823-closing-nav-animation-not-working-on-ie-and-iphone-6-maybe-other-older-browser/?tab=comments#comment-113005 also, this._tTime - prevIteration * cycleDuration - this._dur <= 0 just checks to make sure it wasn't previously in the \"repeatDelay\" portion\n\n if (yoyo && iteration & 1) {\n time = dur - time;\n isYoyo = 1;\n }\n /*\n make sure children at the end/beginning of the timeline are rendered properly. If, for example,\n a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which\n would get translated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there\n could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So\n we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must\n ensure that zero-duration tweens at the very beginning or end of the Timeline work.\n */\n\n\n if (iteration !== prevIteration && !this._lock) {\n var rewinding = yoyo && prevIteration & 1,\n doesWrap = rewinding === (yoyo && iteration & 1);\n iteration < prevIteration && (rewinding = !rewinding);\n prevTime = rewinding ? 0 : tTime % dur ? dur : tTime; // if the playhead is landing exactly at the end of an iteration, use that totalTime rather than only the duration, otherwise it'll skip the 2nd render since it's effectively at the same time.\n\n this._lock = 1;\n this.render(prevTime || (isYoyo ? 0 : _roundPrecise(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0;\n this._tTime = tTime; // if a user gets the iteration() inside the onRepeat, for example, it should be accurate.\n\n !suppressEvents && this.parent && _callback(this, \"onRepeat\");\n this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1);\n\n if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) {\n // if prevTime is 0 and we render at the very end, _time will be the end, thus won't match. So in this edge c
1ase, prevTime won't match _time but that's okay. If it gets killed in the onRepeat, eject as well.\n return this;\n }\n\n dur = this._dur; // in case the duration changed in the onRepeat\n\n tDur = this._tDur;\n\n if (doesWrap) {\n this._lock = 2;\n prevTime = rewinding ? dur : -0.0001;\n this.render(prevTime, true);\n this.vars.repeatRefresh && !isYoyo && this.invalidate();\n }\n\n this._lock = 0;\n\n if (!this._ts && !prevPaused) {\n return this;\n } //in order for yoyoEase to work properly when there's a stagger, we must swap out the ease in each sub-tween.\n\n\n _propagateYoyoEase(this, isYoyo);\n }\n }\n\n if (this._hasPause && !this._forcing && this._lock < 2) {\n pauseTween = _findNextPauseTween(this, _roundPrecise(prevTime), _roundPrecise(time));\n\n if (pauseTween) {\n tTime -= time - (time = pauseTween._start);\n }\n }\n\n this._tTime = tTime;\n this._time = time;\n this._act = !timeScale; //as long as it's not paused, force it to be active so that if the user renders independent of the parent timeline, it'll be forced to re-render on the next tick.\n\n if (!this._initted) {\n this._onUpdate = this.vars.onUpdate;\n this._initted = 1;\n this._zTime = totalTime;\n prevTime = 0; // upon init, the playhead should always go forward;
1 someone could invalidate() a completed timeline and then if they restart(), that would make child tweens render in reverse order which could lock in the wrong starting values if they build on each other, like tl.to(obj, {x: 100}).to(obj, {x: 0}).\n }\n\n if (!prevTime && time && !suppressEvents && !iteration) {\n _callback(this, \"onStart\");\n\n if (this._tTime !== tTime) {\n // in case the onStart triggered a render at a different spot, eject. Like if someone did animation.pause(0.5) or something inside the onStart.\n return this;\n }\n }\n\n if (time >= prevTime && totalTime >= 0) {\n child = this._first;\n\n while (child) {\n next = child._next;\n\n if ((child._act || time >= child._start) && child._ts && pauseTween !== child) {\n if (child.parent !== this) {\n // an extreme edge case - the child's render could do something like kill() the \"next\" one in the linked list, or reparent it. In that case we must re-initiate the whole render to be safe.\n return this.render(totalTime, suppressEvents, force);\n }\n\n child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force);\n\n if (time !== this._time || !this._ts && !prevPaused) {\n //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete\n pauseTween = 0;\n next && (tTime += this._zTime = -_tinyNum); // it didn't finish rendering, so flag zTime as negative so that so that the next time render() is called it'll be forced (to render any remaining children)\n\n break;\n }\n }\n\n child = next;\n }\n } else {\n child = this._last;\n var adjustedTime = totalTime < 0 ? totalTime : time; //when the playhead goes backward beyond the start of this timeline, we must pass that information down to the child animations so that zero-duration tweens know whether to render their starting or ending values.\n\n while (child) {\n next = child._prev;\n\n if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) {\n if (child.parent !== this) {\n // an extreme edge case - the child's render could do something like kill() the \"next\" one in the linked list, or reparent it. In that case we must re-initiate the whole render to be safe.\n return this.render(totalTime, suppressEvents, force);\n }\n\n child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force || _reverting && (child._initted || child._startAt)); // if reverting, we should always force renders of initted tweens (but remember that .fromTo() or .from() may have a _startAt but not _initted yet). If, for example, a .fromTo() tween with a stagger (which creates an internal timeline) gets reverted BEFORE some of its child tweens render for the first time, it may not properly trigger them to revert.\n\n if (time !== this._time || !this._ts && !prevPaused) {\n //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete\n pauseTween = 0;\n next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum); // it didn't finish rendering, so adjust zTime so that so that the next time render() is called it'll be forced (to render any remaining children)\n\n break;\n }\n }\n\n child = next;\n }\n }\n\n if (pauseTween && !suppressEvents) {\n this.pause();\n pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1;\n\n if (this._ts) {\n //the callback resumed playback! So since we may have held back the playhead due to where the pause is positioned, go ahead and jump to where it's SUPPOSED to be (if no pause happened).\n this._start = prevStart; //if the pause was at an earlier time and the user resumed in the callback, it could reposition the timeline (changing its startTime), throwing things off slightly, so we make sure the _start doesn't shift.\n\n _setEnd(this);\n\n return this.render(totalTime, suppressEvents, force);\n }\n }
1\n\n this._onUpdate && !suppressEvents && _callback(this, \"onUpdate\", true);\n if (tTime === tDur && this._tTime >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) {\n // remember, a child's callback may alter this timeline's playhead or timeScale which is why we need to add some of these checks.\n (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); // don't remove if the timeline is reversed and the playhead isn't at 0, otherwise tl.progress(1).reverse() won't work. Only remove if the playhead is at the end and timeScale is positive, or if the playhead is at 0 and the timeScale is negative.\n\n if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime || !tDur)) {\n _callback(this, tTime === tDur && totalTime >= 0 ? \"onComplete\" : \"onReverseComplete\", true);\n\n this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();\n }\n }\n }\n\n return this;\n };\n\n _proto2.add = function add(child, position) {\n var _this2 = this;\n\n _isNumber(position) || (position = _parsePosition(this, position, child));\n\n if (!(child instanceof Animation)) {\n if (_isArray(child)) {\n child.forEach(function (obj) {\n return _this2.add(obj, position);\n });\n return this;\n }\n\n if (_isString(child)) {\n return this.addLabel(child, position);\n }\n\n if (_isFunction(child)) {\n child = Tween.delayedCall(0, child);\n } else {\n return this;\n }\n }\n\n return this !== child ? _addToTimeline(this, child, position) : this; //don't allow a timeline to be added to itself as a child!\n };\n\n _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) {\n if (nested === void 0) {\n nested = true;\n }\n\n if (tweens === void 0) {\n tweens = true;\n }\n\n if (timelines === void 0) {\n timelines = true;\n }\n\n if (ignoreBeforeTime === void 0) {\n ignoreBeforeTime = -_bigNum;\n }\n\n var a = [],\n child = this._first;\n\n while (child) {\n if (child._start >= ignoreBeforeTime) {\n if (child instanceof Tween) {\n tweens && a.push(child);\n } else {\n timelines && a.push(child);\n nested && a.push.apply(a, child.getChildren(true, tweens, timelines));\n }\n }\n\n child = child._next;\n }\n\n return a;\n };\n\n _proto2.getById = function getById(id) {\n var animations = this.getChildren(1, 1, 1),\n i = animations.length;\n\n while (i--) {\n if (animations[i].vars.id === id) {\n return animations[i];\n }\n }\n };\n\n _proto2.remove = function remove(child) {\n if (_isString(child)) {\n return this.removeLabel(child);\n }\n\n if (_isFunction(child)) {\n return this.killTweensOf(child);\n }\n\n _removeLinkedListItem(this, child);\n\n if (child === this._recent) {\n this._recent = this._last;\n }\n\n return _uncache(this);\n };\n\n _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) {\n if (!arguments.length) {\n return this._tTime;\n }\n\n this._forcing = 1;\n\n if (!this._dp && this._ts) {\n //special case for the global timeline (or any other that has no parent or detached parent).\n this._start = _roundPrecise(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts));\n }\n\n _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents);\n\n this._forcing = 0;\n return this;\n };\n\n _proto2.addLabel = function addLabel(label, position) {\n this.labels[label] = _parsePosition(this, position);\n return this;\n };\n\n _proto2.removeLabel = function removeLabel(label) {\n delete this.labels[label];\n return this;\n };\n\n _proto2.addPause = function addPause(position, callback, params) {\n var t = Tween.delayedCall(0, callback || _emptyFunc, params);
1\n t.data = \"isPause\";\n this._hasPause = 1;\n return _addToTimeline(this, t, _parsePosition(this, position));\n };\n\n _proto2.removePause = function removePause(position) {\n var child = this._first;\n position = _parsePosition(this, position);\n\n while (child) {\n if (child._start === position && child.data === \"isPause\") {\n _removeFromParent(child);\n }\n\n child = child._next;\n }\n };\n\n _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) {\n var tweens = this.getTweensOf(targets, onlyActive),\n i = tweens.length;\n\n while (i--) {\n _overwritingTween !== tweens[i] && tweens[i].kill(targets, props);\n }\n\n return this;\n };\n\n _proto2.getTweensOf = function getTweensOf(targets, onlyActive) {\n var a = [],\n parsedTargets = toArray(targets),\n child = this._first,\n isGlobalTime = _isNumber(onlyActive),\n // a number is interpreted as a global time. If the animation spans\n children;\n\n while (child) {\n if (child instanceof Tween) {\n if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) {\n // note: if this is for overwriting, it should only be for tweens that aren't paused and are initted.\n a.push(child);\n }\n } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) {\n a.push.apply(a, children);\n }\n\n child = child._next;\n }\n\n return a;\n } // potential future feature - targets() on timelines\n // targets() {\n // \tlet result = [];\n // \tthis.getChildren(true, true, false).forEach(t => result.push(...t.targets()));\n // \treturn result.filter((v, i) => result.indexOf(v) === i);\n // }\n ;\n\n _proto2.tweenTo = function tweenTo(position, vars) {\n vars = vars || {};\n\n var tl = this,\n endTime = _parsePosition(tl, position),\n _vars = vars,\n startAt = _vars.startAt,\n _onStart = _vars.onStart,\n onStartParams = _vars.onStartParams,\n immediateRender = _vars.immediateRender,\n initted,\n tween = Tween.to(tl, _setDefaults({\n ease: vars.ease || \"none\",\n lazy: false,\n immediateRender: false,\n time: endTime,\n overwrite: \"auto\",\n duration: vars.duration || Math.abs((endTime - (startAt && \"time\" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum,\n onStart: function onStart() {\n tl.pause();\n\n if (!initted) {\n var duration = vars.duration || Math.abs((endTime - (startAt && \"time\" in startAt ? startAt.time : tl._time)) / tl.timeScale());\n tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true);\n initted = 1;\n }\n\n _onStart && _onStart.apply(tween, onStartParams || []); //in case the user had an onStart in the vars - we don't want to overwrite it.\n }\n }, vars));\n\n return immediateRender ? tween.render(0) : tween;\n };\n\n _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) {\n return this.tweenTo(toPosition, _setDefaults({\n startAt: {\n time: _parsePosition(this, fromPosition)\n }\n }, vars));\n };\n\n _proto2.recent = function recent() {\n return this._recent;\n };\n\n _proto2.nextLabel = function nextLabel(afterTime) {\n if (afterTime === void 0) {\n afterTime = this._time;\n }\n\n return _getLabelInDirection(this, _parsePosition(this, afterTime));\n };\n\n _proto2.previousLabel = function previousLabel(beforeTime) {\n if (beforeTime === void 0) {\n beforeTime = this._time;\n }\n\n return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1);\n };\n\n _proto2.currentLabel = function currentLabel(value) {\n return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum);\n };\n\n _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) {\n if (ignoreBeforeTime === void 0) {\n ignoreBeforeTime = 0;\n }\n\n var child = this._first,\n labels = this.labels,\n p;\n\n while (child) {\n if (child._start >= ignoreBeforeTime) {\n child._start += amount;
1\n child._end += amount;\n }\n\n child = child._next;\n }\n\n if (adjustLabels) {\n for (p in labels) {\n if (labels[p] >= ignoreBeforeTime) {\n labels[p] += amount;\n }\n }\n }\n\n return _uncache(this);\n };\n\n _proto2.invalidate = function invalidate(soft) {\n var child = this._first;\n this._lock = 0;\n\n while (child) {\n child.invalidate(soft);\n child = child._next;\n }\n\n return _Animation.prototype.invalidate.call(this, soft);\n };\n\n _proto2.clear = function clear(includeLabels) {\n if (includeLabels === void 0) {\n includeLabels = true;\n }\n\n var child = this._first,\n next;\n\n while (child) {\n next = child._next;\n this.remove(child);\n child = next;\n }\n\n this._dp && (this._time = this._tTime = this._pTime = 0);\n includeLabels && (this.labels = {});\n return _uncache(this);\n };\n\n _proto2.totalDuration = function totalDuration(value) {\n var max = 0,\n self = this,\n child = self._last,\n prevStart = _bigNum,\n prev,\n start,\n parent;\n\n if (arguments.length) {\n return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value));\n }\n\n if (self._dirty) {\n parent = self.parent;\n\n while (child) {\n prev = child._prev; //record it here in case the tween changes position in the sequence...\n\n child._dirty && child.totalDuration(); //could change the tween._startTime, so make sure the animation's cache is clean before analyzing it.\n\n start = child._start;\n\n if (start > prevStart && self._sort && child._ts && !self._lock) {\n //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence\n self._lock = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add().\n\n _addToTimeline(self, child, start - child._delay, 1)._lock = 0;\n } else {\n prevStart = start;\n }\n\n if (start < 0 && child._ts) {\n //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found.\n max -= start;\n\n if (!parent && !self._dp || parent && parent.smoothChildTiming) {\n self._start += start / self._ts;\n self._time -= start;\n self._tTime -= start;\n }\n\n self.shiftChildren(-start, false, -1e999);\n prevStart = 0;\n }\n\n child._end > max && child._ts && (max = child._end);\n child = prev;\n }\n\n _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1);\n\n self._dirty = 0;\n }\n\n return self._tDur;\n };\n\n Timeline.updateRoot = function updateRoot(time) {\n if (_globalTimeline._ts) {\n _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline));\n\n _lastRenderedFrame = _ticker.frame;\n }\n\n if (_ticker.frame >= _nextGCFrame) {\n _nextGCFrame += _config.autoSleep || 120;\n var child = _globalTimeline._first;\n if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) {\n while (child && !child._ts) {\n child = child._next;\n }\n\n child || _ticker.sleep();\n }\n }\n };\n\n return Timeline;\n}(Animation);\n\n_setDefaults(Timeline.prototype, {\n _lock: 0,\n _hasPause: 0,\n _forcing: 0\n});\n\nvar _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) {\n //note: we call _addComplexStringPropTween.call(tweenInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus \"this\" would refer to the plugin.\n var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter),\n index = 0,\n matchIndex = 0,\n result,\n startNums,\n color,\n endNum,\n chunk,\n startNum,\n hasRandom,\n a;\n pt.b = start;\n pt.e = end;\n start += \"\"; //ensure values are strings\n\n end += \"\";\n\n if (hasRandom = ~end.indexOf(\"random(\")) {\n end = _replaceRandom(end);\n }\n\n if (stringFilter) {\n a = [start, end];\n stringFilter(a, target, prop); //pass an array with the starting and ending values and let the filter do whatever it needs to the values.\
1n\n start = a[0];\n end = a[1];\n }\n\n startNums = start.match(_complexStringNumExp) || [];\n\n while (result = _complexStringNumExp.exec(end)) {\n endNum = result[0];\n chunk = end.substring(index, result.index);\n\n if (color) {\n color = (color + 1) % 5;\n } else if (chunk.substr(-5) === \"rgba(\") {\n color = 1;\n }\n\n if (endNum !== startNums[matchIndex++]) {\n startNum = parseFloat(startNums[matchIndex - 1]) || 0; //these nested PropTweens are handled in a special way - we'll never actually call a render or setter method on them. We'll just loop through them in the parent complex string PropTween's render method.\n\n pt._pt = {\n _next: pt._pt,\n p: chunk || matchIndex === 1 ? chunk : \",\",\n //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case.\n s: startNum,\n c: endNum.charAt(1) === \"=\" ? _parseRelative(startNum, endNum) - startNum : parseFloat(endNum) - startNum,\n m: color && color < 4 ? Math.round : 0\n };\n index = _complexStringNumExp.lastIndex;\n }\n }\n\n pt.c = index < end.length ? end.substring(index, end.length) : \"\"; //we use the \"c\" of the PropTween to store the final part of the string (after the last number)\n\n pt.fp = funcParam;\n\n if (_relExp.test(end) || hasRandom) {\n pt.e = 0; //if the end string contains relative values or dynamic random(...) values, delete the end it so that on the final render we don't actually set it to the string with += or -= characters (forces it to use the calculated value).\n }\n\n this._pt = pt; //start the linked list with this new PropTween. Remember, we call _addComplexStringPropTween.call(tweenInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus \"this\" would refer to the plugin.\n\n return pt;\n},\n _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam, optional) {\n _isFunction(end) && (end = end(index || 0, target, targets));\n var currentValue = target[prop],\n parsedStart = start !== \"get\" ? start : !_isFunction(currentValue) ? currentValue : funcParam ? target[prop.indexOf(\"set\") || !_isFunction(target[\"get\" + prop.substr(3)]) ? prop : \"get\" + prop.substr(3)](funcParam) : target[prop](),\n setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc,\n pt;\n\n if (_isString(end)) {\n if (~end.indexOf(\"random(\")) {\n end = _replaceRandom(end);\n }\n\n if (end.charAt(1) === \"=\") {\n pt = _parseRelative(parsedStart, end) + (getUnit(parsedStart) || 0);\n\n if (pt || pt === 0) {\n // to avoid isNaN, like if someone passes in a value like \"!= whatever\"\n end = pt;\n }\n }\n }\n\n if (!optional || parsedStart !== end || _forceAllPropTweens) {\n if (!isNaN(parsedStart * end) && end !== \"\") {\n // fun fact: any number multiplied by \"\" is evaluated as the number 0!\n pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === \"boolean\" ? _renderBoolean : _renderPlain, 0, setter);\n funcParam && (pt.fp = funcParam);\n modifier && pt.modifier(modifier, this, target);\n return this._pt = pt;\n }\n\n !currentValue && !(prop in target) && _missingPlugin(prop, end);\n return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam);\n }\n},\n //creates a copy of the vars object and processes any function-based values (putting the resulting values directly into the copy) as well as strings with \"random()\" in them. It does NOT process relative values.\n_processVars = function _processVars(vars, index, target, targets, tween) {\n _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets));\n\n if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) {\n return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars;\n }\n\n var copy = {},\n p;\n\n for (p in vars) {\n copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets);\n }\n\n return copy;\n},\n _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) {\n var plugin, pt, ptLookup, i;\n\n if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) {\n tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority);\n\n if (tween !== _quickTween) {\n ptLookup = tween._ptLookup[tween._targets.indexOf(target)]; //note: we can't use tween._ptLookup[index] because for staggered tweens, the index from the fullTargets array won't match what it is in each individual tween that spawns from the stagger.\n\n i = plugin._props.length;\n\n while (i--) {\n ptLookup[plugin._props[i]] = pt;\n }\n }\n }\n\n return plugin;\n},\n _overwritingTween,\n //store a reference temporarily so we can avoid overwriting itself.\n_forceAllPropTweens,\n _initTween = function _initTween(tween, time, tTime) {\n var vars = tween.vars,\n ease = vars.ease,\n startAt = vars.startAt,\n immediateRender = vars.immediateRender,\n lazy = vars.lazy,\n onUpdate = vars.onUp
1date,\n runBackwards = vars.runBackwards,\n yoyoEase = vars.yoyoEase,\n keyframes = vars.keyframes,\n autoRevert = vars.autoRevert,\n dur = tween._dur,\n prevStartAt = tween._startAt,\n targets = tween._targets,\n parent = tween.parent,\n fullTargets = parent && parent.data === \"nested\" ? parent.vars.targets : targets,\n autoOverwrite = tween._overwrite === \"auto\" && !_suppressOverwrites,\n tl = tween.timeline,\n cleanVars,\n i,\n p,\n pt,\n target,\n hasPriority,\n gsData,\n harness,\n plugin,\n ptLookup,\n index,\n harnessVars,\n overwritten;\n tl && (!keyframes || !ease) && (ease = \"none\");\n tween._ease = _parseEase(ease, _defaults.ease);\n tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0;\n\n if (yoyoEase && tween._yoyo && !tween._repeat) {\n //there must have been a parent timeline with yoyo:true that is currently in its yoyo phase, so flip the eases.\n yoyoEase = tween._yEase;\n tween._yEase = tween._ease;\n tween._ease = yoyoEase;\n }\n\n tween._from = !tl && !!vars.runBackwards; //nested timelines should never run backwards - the backwards-ness is in the child tweens.\n\n if (!tl || keyframes && !vars.stagger) {\n //if there's an internal timeline, skip all the parsing because we passed that task down the chain.\n harness = targets[0] ? _getCache(targets[0]).harness : 0;\n harnessVars = harness && vars[harness.prop]; //someone may need to specify CSS-specific values AND non-CSS values, like if the element has an \"x\" property plus it's a standard DOM element. We allow people to distinguish by wrapping plugin-specific stuff in a css:{} object for example.\n\n cleanVars = _copyExcluding(vars, _reservedProps);\n\n if (prevStartAt) {\n prevStartAt._zTime < 0 && prevStartAt.progress(1); // in case it's a lazy startAt that hasn't rendered yet.\n\n time < 0 && runBackwards && immediateRender && !autoRevert ? prevStartAt.render(-1, true) : prevStartAt.revert(runBackwards && dur ? _revertConfigNoKill : _startAtRevertConfig); // if it's a \"startAt\" (not \"from()\" or runBackwards: true), we only need to do a shallow revert (keep transforms cached in CSSPlugin)\n // don't just _removeFromParent(prevStartAt.render(-1, true)) because that'll leave inline styles. We're creating a new _startAt for \"startAt\" tweens that re-capture things to ensure that if the pre-tween values changed since the tween was created, they're recorded.\n\n prevStartAt._lazy = 0;\n }\n\n if (startAt) {\n _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({\n data: \"isStart\",\n overwrite: false,\n parent: parent,\n immediateRender: true,\n lazy: !prevStartAt && _isNotFalse(lazy),\n startAt: null,\n delay: 0,\n onUpdate: onUpdate && function () {\n return _callback(tween, \"onUpdate\");\n },\n stagger: 0\n }, startAt))); //copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, from, to).fromTo(e, to, from);\n\n\n tween._startAt._dp = 0; // don't allow it to get put back into root timeline! Like when revert() is called and totalTime() gets set.\n\n tween._startAt._sat = tween; // used in globalTime(). _sat stands for _startAtTween\n\n time < 0 && (_reverting || !immediateRender && !autoRevert) && tween._startAt.revert(_revertConfigNoKill); // rare edge case, like if a render is forced in the negative direction of a non-initted tween.\n\n if (immediateRender) {\n if (dur && time <= 0 && tTime <= 0) {\n // check tTime here because in the case of a yoyo tween whose playhead gets pushed to the end like tween.progress(1), we should allow it through so that the onComplete gets fired properly.\n time && (tween._zTime = time);\n return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a Timeline, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting.\n }\n }\n } else if (runBackwards && dur) {\n //from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards)\n if (!prevStartAt) {\n time && (immediateRender = false); //in rare cases (like if a from() tween runs and then is invali
1date()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0\n\n p = _setDefaults({\n overwrite: false,\n data: \"isFromStart\",\n //we tag the tween with as \"isFromStart\" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a \"from()\" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:\"height\", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in.\n lazy: immediateRender && !prevStartAt && _isNotFalse(lazy),\n immediateRender: immediateRender,\n //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after)\n stagger: 0,\n parent: parent //ensures that nested tweens that had a stagger are handled properly, like gsap.from(\".class\", {y: gsap.utils.wrap([-100,100]), stagger: 0.5})\n\n }, cleanVars);\n harnessVars && (p[harness.prop] = harnessVars); // in case someone does something like .from(..., {css:{}})\n\n _removeFromParent(tween._startAt = Tween.set(targets, p));\n\n tween._startAt._dp = 0; // don't allow it to get put back into root timeline!\n\n tween._startAt._sat = tween; // used in globalTime()\n\n time < 0 && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween._startAt.render(-1, true));\n tween._zTime = time;\n\n if (!immediateRender) {\n _initTween(tween._startAt, _tinyNum, _tinyNum); //ensures that the initial values are recorded\n\n } else if (!time) {\n return;\n }\n }\n }\n\n tween._pt = tween._ptCache = 0;\n lazy = dur && _isNotFalse(lazy) || lazy && !dur;\n\n for (i = 0; i < targets.length; i++) {\n target = targets[i];\n gsData = target._gsap || _harness(targets)[i]._gsap;\n tween._ptLookup[i] = ptLookup = {};\n _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end)\n\n index = fullTargets === targets ? i : fullTargets.indexOf(target);\n\n if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) {\n tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority);\n\n plugin._props.forEach(function (name) {\n ptLookup[name] = pt;\n });\n\n plugin.priority && (hasPriority = 1);\n }\n\n if (!harness || harnessVars) {\n for (p in cleanVars) {\n if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) {\n plugin.priority && (hasPriority = 1);\n } else {\n ptLookup[p] = pt = _addPropTween.call(tween, target, p, \"get\", cleanVars[p], index, fullTargets, 0, vars.stringFilter);\n }\n }\n }\n\n tween._op && tween._op[i] && tween.kill(target, tween._op[i]);\n\n if (autoOverwrite && tween._pt) {\n _overwritingTween = tween;\n\n _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(time)); // make sure the overwriting doesn't overwrite THIS tween!!!\n\n\n overwritten = !tween.parent;\n _overwritingTween = 0;\n }\n\n tween._pt && lazy && (_lazyLookup[gsData.id] = 1);\n }\n\n hasPriority && _sortPropTweensByPriority(tween);\n tween._onInit && tween._onInit(tween); //plugins like RoundProps must wait until ALL of the PropTweens are instantiated. In the plugin's init() function, it sets the _onInit on the tween instance. May not be pretty/intuitive, but it's fast and keeps file size down.\n }\n\n tween._onUpdate = onUpdate;\n tween._initted = (!tween._op || tween._pt) && !overwritten;
1 // if overwrittenProps resulted in the entire tween being killed, do NOT flag it as initted or else it may render for one tick.\n\n keyframes && time <= 0 && tl.render(_bigNum, true, true); // if there's a 0% keyframe, it'll render in the \"before\" state for any staggered/delayed animations thus when the following tween initializes, it'll use the \"before\" state instead of the \"after\" state as the initial values.\n},\n _updatePropTweens = function _updatePropTweens(tween, property, value, start, startIsRelative, ratio, time, skipRecursion) {\n var ptCache = (tween._pt && tween._ptCache || (tween._ptCache = {}))[property],\n pt,\n rootPT,\n lookup,\n i;\n\n if (!ptCache) {\n ptCache = tween._ptCache[property] = [];\n lookup = tween._ptLookup;\n i = tween._targets.length;\n\n while (i--) {\n pt = lookup[i][property];\n\n if (pt && pt.d && pt.d._pt) {\n // it's a plugin, so find the nested PropTween\n pt = pt.d._pt;\n\n while (pt && pt.p !== property && pt.fp !== property) {\n // \"fp\" is functionParam for things like setting CSS variables which require .setProperty(\"--var-name\", value)\n pt = pt._next;\n }\n }\n\n if (!pt) {\n // there is no PropTween associated with that property, so we must FORCE one to be created and ditch out of this\n // if the tween has other properties that already rendered at new positions, we'd normally have to rewind to put them back like tween.render(0, true) before forcing an _initTween(), but that can create another edge case like tweening a timeline's progress would trigger onUpdates to fire which could move other things around. It's better to just inform users that .resetTo() should ONLY be used for tweens that already have that property. For example, you can't gsap.to(...{ y: 0 }) and then tween.restTo(\"x\", 200) for example.\n _forceAllPropTweens = 1; // otherwise, when we _addPropTween() and it finds no change between the start and end values, it skips creating a PropTween (for efficiency...why tween when there's no difference?) but in this case we NEED that PropTween created so we can edit it.\n\n tween.vars[property] = \"+=0\";\n\n _initTween(tween, time);\n\n _forceAllPropTweens = 0;\n return skipRecursion ? _warn(property + \" not eligible for reset\") : 1; // if someone tries to do a quickTo() on a special property like borderRadius which must get split into 4 different properties, that's not eligible for .resetTo().\n }\n\n ptCache.push(pt);\n }\n }\n\n i = ptCache.length;\n\n while (i--) {\n rootPT = ptCache[i];\n pt = rootPT._pt || rootPT; // complex values may have nested PropTweens. We only accommodate the FIRST value.\n\n pt.s = (start || start === 0) && !startIsRelative ? start : pt.s + (start || 0) + ratio * pt.c;\n pt.c = value - pt.s;\n rootPT.e && (rootPT.e = _round(value) + getUnit(rootPT.e)); // mainly for CSSPlugin (end value)\n\n rootPT.b && (rootPT.b = pt.s + getUnit(rootPT.b)); // (beginning value)\n }\n},\n _addAliasesToVars = function _addAliasesToVars(targets, vars) {\n var harness = targets[0] ? _getCache(targets[0]).harness : 0,\n propertyAliases = harness && harness.aliases,\n copy,\n p,\n i,\n aliases;\n\n if (!propertyAliases) {\n return vars;\n }\n\n copy = _merge({}, vars);\n\n for (p in propertyAliases) {\n if (p in copy) {\n aliases = propertyAliases[p].split(\",\");\n i = aliases.length;\n\n while (i--) {\n copy[aliases[i]] = copy[p];\n }\n }\n }\n\n return copy;\n},\n // parses multiple formats, like {\"0%\": {x: 100}, {\"50%\": {x: -20}} and { x: {\"0%\": 100, \"50%\": -20} }, and an \"ease\" can be set on any object. We populate an \"allProps\" object with an Array for each property, like {x: [{}, {}], y:[{}, {}]} with data for each property tween. The objects have a \"t\" (time), \"v\", (value), and \"e\" (ease) property. This allows us to piece together a timeline later.\n_parseKeyframe = function _parseKeyframe(prop, obj, allProps, easeEach) {\n var ease = obj.ease || easeEach || \"power1.inOut\",\n p,\n a;\n\n if (_isArray(obj)) {\n a = allProps[prop] || (allProps[prop] = []); // t = time (out of 100), v = value, e = ease\n\n obj.forEac
1h(function (value, i) {\n return a.push({\n t: i / (obj.length - 1) * 100,\n v: value,\n e: ease\n });\n });\n } else {\n for (p in obj) {\n a = allProps[p] || (allProps[p] = []);\n p === \"ease\" || a.push({\n t: parseFloat(prop),\n v: obj[p],\n e: ease\n });\n }\n }\n},\n _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) {\n return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf(\"random(\") ? _replaceRandom(value) : value;\n},\n _staggerTweenProps = _callbackNames + \"repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert\",\n _staggerPropsToSkip = {};\n\n_forEachName(_staggerTweenProps + \",id,stagger,delay,duration,paused,scrollTrigger\", function (name) {\n return _staggerPropsToSkip[name] = 1;\n});\n/*\n * --------------------------------------------------------------------------------------\n * TWEEN\n * --------------------------------------------------------------------------------------\n */\n\n\nvar Tween = /*#__PURE__*/function (_Animation2) {\n _inheritsLoose(Tween, _Animation2);\n\n function Tween(targets, vars, position, skipInherit) {\n var _this3;\n\n if (typeof vars === \"number\") {\n position.duration = vars;\n vars = position;\n position = null;\n }\n\n _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars)) || this;\n var _this3$vars = _this3.vars,\n duration = _this3$vars.duration,\n delay = _this3$vars.delay,\n immediateRender = _this3$vars.immediateRender,\n stagger = _this3$vars.stagger,\n overwrite = _this3$vars.overwrite,\n keyframes = _this3$vars.keyframes,\n defaults = _this3$vars.defaults,\n scrollTrigger = _this3$vars.scrollTrigger,\n yoyoEase = _this3$vars.yoyoEase,\n parent = vars.parent || _globalTimeline,\n parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : \"length\" in vars) ? [targets] : toArray(targets),\n tl,\n i,\n copy,\n l,\n p,\n curTarget,\n staggerFunc,\n staggerVarsToMerge;\n _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn(\"GSAP target \" + targets + \" not found. https://gsap.com\", !_config.nullTargetWarn) || [];\n _this3._ptLookup = []; //PropTween lookup. An array containing an object for each target, having keys for each tweening property\n\n _this3._overwrite = overwrite;\n\n if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {\n vars = _this3.vars;\n tl = _this3.timeline = new Timeline({\n data: \"nested\",\n defaults: defaults || {},\n targets: parent && parent.data === \"nested\" ? parent.vars.targets : parsedTargets\n }); // we need to store the targets because for staggers and keyframes, we end up creating an individual tween for each but function-based values need to know the index and the whole Array of targets.\n\n tl.kill();\n tl.parent = tl._dp = _assertThisInitialized(_this3);\n tl._start = 0;\n\n if (stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {\n l = parsedTargets.length;\n staggerFunc = stagger && distribute(stagger);\n\n if (_isObject(stagger)) {\n //users can pass in callbacks like onStart/onComplete in the stagger object. These should fire with each individual tween.\n for (p in stagger) {\n if (~_staggerTweenProps.indexOf(p)) {\n staggerVarsToMerge || (staggerVarsToMerge = {});\n staggerVarsToMerge[p] = stagger[p];\n }\n }\n }\n\n for (i = 0; i < l; i++) {\n copy = _copyExcluding(vars, _staggerPropsToSkip);\n copy.stagger = 0;\n yoyoEase && (copy.yoyoEase = yoyoEase);\n staggerVarsToMerge && _merge(copy, staggerVarsToMerge);\n curTarget = parsedTargets[i]; //don't just copy duration or delay because if they're a string or function, we'd end up in an infinite loop because _isFuncOrString() would evaluate as true in the child tweens, entering this loop, etc. So we parse the value straight from vars and default to 0.\n\n copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets);\n copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay;\n\n if (!stagger && l === 1 && copy.delay) {\n // if someone does delay:\"random(1, 5)\", repeat:-1, for example, the delay
1shouldn't be inside the repeat.\n _this3._delay = delay = copy.delay;\n _this3._start += delay;\n copy.delay = 0;\n }\n\n tl.to(curTarget, copy, staggerFunc ? staggerFunc(i, curTarget, parsedTargets) : 0);\n tl._ease = _easeMap.none;\n }\n\n tl.duration() ? duration = delay = 0 : _this3.timeline = 0; // if the timeline's duration is 0, we don't need a timeline internally!\n } else if (keyframes) {\n _inheritDefaults(_setDefaults(tl.vars.defaults, {\n ease: \"none\"\n }));\n\n tl._ease = _parseEase(keyframes.ease || vars.ease || \"none\");\n var time = 0,\n a,\n kf,\n v;\n\n if (_isArray(keyframes)) {\n keyframes.forEach(function (frame) {\n return tl.to(parsedTargets, frame, \">\");\n });\n tl.duration(); // to ensure tl._dur is cached because we tap into it for performance purposes in the render() method.\n } else {\n copy = {};\n\n for (p in keyframes) {\n p === \"ease\" || p === \"easeEach\" || _parseKeyframe(p, keyframes[p], copy, keyframes.easeEach);\n }\n\n for (p in copy) {\n a = copy[p].sort(function (a, b) {\n return a.t - b.t;\n });\n time = 0;\n\n for (i = 0; i < a.length; i++) {\n kf = a[i];\n v = {\n ease: kf.e,\n duration: (kf.t - (i ? a[i - 1].t : 0)) / 100 * duration\n };\n v[p] = kf.v;\n tl.to(parsedTargets, v, time);\n time += v.duration;\n }\n }\n\n tl.duration() < duration && tl.to({}, {\n duration: duration - tl.duration()\n }); // in case keyframes didn't go to 100%\n }\n }\n\n duration || _this3.duration(duration = tl.duration());\n } else {\n _this3.timeline = 0; //speed optimization, faster lookups (no going up the prototype chain)\n }\n\n if (overwrite === true && !_suppressOverwrites) {\n _overwritingTween = _assertThisInitialized(_this3);\n\n _globalTimeline.killTweensOf(parsedTargets);\n\n _overwritingTween = 0;\n }\n\n _addToTimeline(parent, _assertThisInitialized(_this3), position);\n\n vars.reversed && _this3.reverse();\n vars.paused && _this3.paused(true);\n\n if (immediateRender || !duration && !keyframes && _this3._start === _roundPrecise(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== \"nested\") {\n _this3._tTime = -_tinyNum; //forces a render without having to set the render() \"force\" parameter to true because we want to allow lazying by default (using the \"force\" parameter always forces an immediate full render)\n\n _this3.render(Math.max(0, -delay) || 0); //in case delay is negative\n\n }\n\n scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger);\n return _this3;\n }\n\n var _proto3 = Tween.prototype;\n\n _proto3.render = function render(totalTime, suppressEvents, force) {\n var prevTime = this._time,\n tDur = this._tDur,\n dur = this._dur,\n isNegative = totalTime < 0,\n tTime = totalTime > tDur - _tinyNum && !isNegative ? tDur : totalTime < _tinyNum ? 0 : totalTime,\n time,\n pt,\n iteration,\n cycleDuration,\n prevIteration,\n isYoyo,\n ratio,\n timeline,\n yoyoEase;\n\n if (!dur) {\n _renderZeroDurationTween(this, totalTime, suppressEvents, force);\n } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== isNegative) {\n //this senses if we're crossing over the start time, in which case we must record _zTime and force the render, but we do it in this lengthy conditional way for performance reasons (usually we can skip the calculations): this._initted && (this._zTime < 0) !== (totalTime < 0)\n time = tTime;\n timeline = this.timeline;\n\n if (this._repeat) {\n //adjust the time for repeats and yoyos\n cycleDuration = dur + this._rDelay;\n\n if (this._repeat < -1 && isNegative) {\n return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);\n }\n\n time = _roundPrecise(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!)\n\n if (tTime === tDur) {\n // the tDur === tTime is for edge cases where there's a lengthy decimal on the duration and it may reach the very end but the time is rendered as not-quite-there (remember, tDur is rounded to 4 decimals whereas dur isn't)\n iteration = this._repeat;\n time = dur;\n } else {\n iteration = ~~(tTime / cycleDuration);\n\n if (iteration && iteration === _roundPrecise(tTime / cycleDuration)) {\n time = dur;\n iteration--;\n }\n\n time > dur && (time = dur);\n }\n\n isYoyo = this._yoyo && iteration & 1;\n\n if (isYoyo) {\n yoyoEase = this._yEase;\n time = dur - time;\n }\n\n prevIteration = _animationCycle(this._tTime, cycleDuration);\n\n if (time === prevTime && !force && this._initted && iteration === prevIteration) {\n //could be during the repeatDelay part. No need to render and fire callbacks.\n this._tTime = tTime;\n return this;\n }\n\n if (iteration !== prevIteration) {\n timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo); //repeatRefresh functionality\n\n if (this.vars.repeatRefresh && !isYoyo && !this._lock && this._time !== cycleDuration && this._initted) {\n // this._time will === cycleDuration when we render at EXACTLY the end of an iteration. Without this condition, it'd often do the repeatRefresh render TWICE (again on the very next tick).\n this._lock = force = 1; //force, otherwise if lazy is true, the _attemptInitTween() will return and we'll jump out and get caught bouncing on each tick.\n\n this.render(_roundPrecise(cycleDuration * iteration), true).invalidate()._lock = 0;\n }\n }\n }\n\n if (!this._initted) {\n if (_attemptInitTween(this, isNegative ? totalTime : time, force, suppressEvents, tTime)) {\
1n this._tTime = 0; // in constructor if immediateRender is true, we set _tTime to -_tinyNum to have the playhead cross the starting point but we can't leave _tTime as a negative number.\n\n return this;\n }\n\n if (prevTime !== this._time && !(force && this.vars.repeatRefresh && iteration !== prevIteration)) {\n // rare edge case - during initialization, an onUpdate in the _startAt (.fromTo()) might force this tween to render at a different spot in which case we should ditch this render() call so that it doesn't revert the values. But we also don't want to dump if we're doing a repeatRefresh render!\n return this;\n }\n\n if (dur !== this._dur) {\n // while initting, a plugin like InertiaPlugin might alter the duration, so rerun from the start to ensure everything renders as it should.\n return this.render(totalTime, suppressEvents, force);\n }\n }\n\n this._tTime = tTime;\n this._time = time;\n\n if (!this._act && this._ts) {\n this._act = 1; //as long as it's not paused, force it to be active so that if the user renders independent of the parent timeline, it'll be forced to re-render on the next tick.\n\n this._lazy = 0;\n }\n\n this.ratio = ratio = (yoyoEase || this._ease)(time / dur);\n\n if (this._from) {\n this.ratio = ratio = 1 - ratio;\n }\n\n if (time && !prevTime && !suppressEvents && !iteration) {\n _callback(this, \"onStart\");\n\n if (this._tTime !== tTime) {\n // in case the onStart triggered a render at a different spot, eject. Like if someone did animation.pause(0.5) or something inside the onStart.\n return this;\n }\n }\n\n pt = this._pt;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n\n timeline && timeline.render(totalTime < 0 ? totalTime : timeline._dur * timeline._ease(time / this._dur), suppressEvents, force) || this._startAt && (this._zTime = totalTime);\n\n if (this._onUpdate && !suppressEvents) {\n isNegative && _rewindStartAt(this, totalTime, suppressEvents, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete.\n\n _callback(this, \"onUpdate\");\n }\n\n this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, \"onRepeat\");\n\n if ((tTime === this._tDur || !tTime) && this._tTime === tTime) {\n isNegative && !this._onUpdate && _rewindStartAt(this, totalTime, true, true);\n (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); // don't remove if we're rendering at exactly a time of 0, as there could be autoRevert values that should get set on the next tick (if the playhead goes backward beyond the startTime, negative totalTime). Don't remove if the timeline is reversed and the playhead isn't at 0, otherwise tl.progress(1).reverse() won't work. Only remove if the playhead is at the end and timeScale is positive, or if the playhead is at 0 and the timeScale is negative.\n\n if (!suppressEvents && !(isNegative && !prevTime) && (tTime || prevTime || isYoyo)) {\n // if prevTime and tTime are zero, we shouldn't fire the onReverseComplete. This could happen if you gsap.to(... {paused:true}).play();\n _callback(this, tTime === tDur ? \"onComplete\" : \"onReverseComplete\", true);\n\n this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();\n }\n }\n }\n\n return this;\n };\n\n _proto3.targets = function targets() {\n return this._targets;\n };
1\n\n _proto3.invalidate = function invalidate(soft) {\n // \"soft\" gives us a way to clear out everything EXCEPT the recorded pre-\"from\" portion of from() tweens. Otherwise, for example, if you tween.progress(1).render(0, true true).invalidate(), the \"from\" values would persist and then on the next render, the from() tweens would initialize and the current value would match the \"from\" values, thus animate from the same value to the same value (no animation). We tap into this in ScrollTrigger's refresh() where we must push a tween to completion and then back again but honor its init state in case the tween is dependent on another tween further up on the page.\n (!soft || !this.vars.runBackwards) && (this._startAt = 0);\n this._pt = this._op = this._onUpdate = this._lazy = this.ratio = 0;\n this._ptLookup = [];\n this.timeline && this.timeline.invalidate(soft);\n return _Animation2.prototype.invalidate.call(this, soft);\n };\n\n _proto3.resetTo = function resetTo(property, value, start, startIsRelative, skipRecursion) {\n _tickerActive || _ticker.wake();\n this._ts || this.play();\n var time = Math.min(this._dur, (this._dp._time - this._start) * this._ts),\n ratio;\n this._initted || _initTween(this, time);\n ratio = this._ease(time / this._dur); // don't just get tween.ratio because it may not have rendered yet.\n // possible future addition to allow an object with multiple values to update, like tween.resetTo({x: 100, y: 200}); At this point, it doesn't seem worth the added kb given the fact that most users will likely opt for the convenient gsap.quickTo() way of interacting with this method.\n // if (_isObject(property)) { // performance optimization\n // \tfor (p in property) {\n // \t\tif (_updatePropTweens(this, p, property[p], value ? value[p] : null, start, ratio, time)) {\n // \t\t\treturn this.resetTo(property, value, start, startIsRelative); // if a PropTween wasn't found for the property, it'll get forced with a re-initialization so we need to jump out and start over again.\n // \t\t}\n // \t}\n // } else {\n\n if (_updatePropTweens(this, property, value, start, startIsRelative, ratio, time, skipRecursion)) {\n return this.resetTo(property, value, start, startIsRelative, 1); // if a PropTween wasn't found for the property, it'll get forced with a re-initialization so we need to jump out and start over again.\n } //}\n\n\n _alignPlayhead(this, 0);\n\n this.parent || _addLinkedListItem(this._dp, this, \"_first\", \"_last\", this._dp._sort ? \"_start\" : 0);\n return this.render(0);\n };\n\n _proto3.kill = function kill(targets, vars) {\n if (vars === void 0) {\n vars = \"all\";\n }\n\n if (!targets && (!vars || vars === \"all\")) {\n this._lazy = this._pt = 0;\n return this.parent ? _interrupt(this) : this;\n }\n\n if (this.timeline) {\n var tDur = this.timeline.totalDuration();\n this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); // if nothing is left tweening, interrupt.\n\n this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1); // if a nested tween is killed that changes the duration, it should affect this tween's duration. We must use the ratio, though, because sometimes the internal timeline is stretched like for keyframes where they don't all add up to whatever the parent tween's duration was set to.\n\n return this;\n }\n\n var parsedTargets = this._targets,\n killingTargets = targets ? toArray(targets) : parsedTargets,\n propTweenLookup = this._ptLookup,\n firstPT = this._pt,\n overwrittenProps,\n curLookup,\n curOverwriteProps,\n props,\n p,\n pt,\n i;\n\n if ((!vars || vars === \"all\") && _arraysMatch(parsedTargets, killingTargets)) {\n vars === \"all\" && (this._pt = 0);\n return _interrupt(this);\n }\n\n overwrittenProps = this._op = this._op || [];\n\n if (vars !== \"all\") {\n //so people can pass in a comma-delimited list of property names\n if (_isString(vars)) {\n p = {};
1\n\n _forEachName(vars, function (name) {\n return p[name] = 1;\n });\n\n vars = p;\n }\n\n vars = _addAliasesToVars(parsedTargets, vars);\n }\n\n i = parsedTargets.length;\n\n while (i--) {\n if (~killingTargets.indexOf(parsedTargets[i])) {\n curLookup = propTweenLookup[i];\n\n if (vars === \"all\") {\n overwrittenProps[i] = vars;\n props = curLookup;\n curOverwriteProps = {};\n } else {\n curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {};\n props = vars;\n }\n\n for (p in props) {\n pt = curLookup && curLookup[p];\n\n if (pt) {\n if (!(\"kill\" in pt.d) || pt.d.kill(p) === true) {\n _removeLinkedListItem(this, pt, \"_pt\");\n }\n\n delete curLookup[p];\n }\n\n if (curOverwriteProps !== \"all\") {\n curOverwriteProps[p] = 1;\n }\n }\n }\n }\n\n this._initted && !this._pt && firstPT && _interrupt(this); //if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening.\n\n return this;\n };\n\n Tween.to = function to(targets, vars) {\n return new Tween(targets, vars, arguments[2]);\n };\n\n Tween.from = function from(targets, vars) {\n return _createTweenType(1, arguments);\n };\n\n Tween.delayedCall = function delayedCall(delay, callback, params, scope) {\n return new Tween(callback, 0, {\n immediateRender: false,\n lazy: false,\n overwrite: false,\n delay: delay,\n onComplete: callback,\n onReverseComplete: callback,\n onCompleteParams: params,\n onReverseCompleteParams: params,\n callbackScope: scope\n }); // we must use onReverseComplete too for things like timeline.add(() => {...}) which should be triggered in BOTH directions (forward and reverse)\n };\n\n Tween.fromTo = function fromTo(targets, fromVars, toVars) {\n return _createTweenType(2, arguments);\n };\n\n Tween.set = function set(targets, vars) {\n vars.duration = 0;\n vars.repeatDelay || (vars.repeat = 0);\n return new Tween(targets, vars);\n };\n\n Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) {\n return _globalTimeline.killTweensOf(targets, props, onlyActive);\n };\n\n return Tween;\n}(Animation);\n\n_setDefaults(Tween.prototype, {\n _targets: [],\n _lazy: 0,\n _startAt: 0,\n _op: 0,\n _onInit: 0\n}); //add the pertinent timeline methods to Tween instances so that users can chain conveniently and create a timeline automatically. (removed due to concerns that it'd ultimately add to more confusion especially for beginners)\n// _forEachName(\"to,from,fromTo,set,call,add,addLabel,addPause\", name => {\n// \tTween.prototype[name] = function() {\n// \t\tlet tl = new Timeline();\n// \t\treturn _addToTimeline(tl, this)[name].apply(tl, toArray(arguments));\n// \t}\n// });\n//for backward compatibility. Leverage the timeline calls.\n\n\n_forEachName(\"staggerTo,staggerFrom,staggerFromTo\", function (name) {\n Tween[name] = function () {\n var tl = new Timeline(),\n params = _slice.call(arguments, 0);\n\n params.splice(name === \"staggerFromTo\" ? 5 : 4, 0, 0);\n return tl[name].apply(tl, params);\n };\n});\n/*\n * --------------------------------------------------------------------------------------\n * PROPTWEEN\n * --------------------------------------------------------------------------------------\n */\n\n\nvar _setterPlain = function _setterPlain(target, property, value) {\n return target[property] = value;\n},\n _setterFunc = function _setterFunc(target, property, value) {\n return target[property](value);\n},\n _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) {\n return target[property](data.fp, value);\n},\n _setterAttribute = function _setterAttribute(target, property, value) {\n return target.setAttribute(property, value);\n},\n _getSetter = function _getSetter(target, property) {\n return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain;\n}
1,\n _renderPlain = function _renderPlain(ratio, data) {\n return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 1000000) / 1000000, data);\n},\n _renderBoolean = function _renderBoolean(ratio, data) {\n return data.set(data.t, data.p, !!(data.s + data.c * ratio), data);\n},\n _renderComplexString = function _renderComplexString(ratio, data) {\n var pt = data._pt,\n s = \"\";\n\n if (!ratio && data.b) {\n //b = beginning string\n s = data.b;\n } else if (ratio === 1 && data.e) {\n //e = ending string\n s = data.e;\n } else {\n while (pt) {\n s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s; //we use the \"p\" property for the text inbetween (like a suffix). And in the context of a complex string, the modifier (m) is typically just Math.round(), like for RGB colors.\n\n pt = pt._next;\n }\n\n s += data.c; //we use the \"c\" of the PropTween to store the final chunk of non-numeric text.\n }\n\n data.set(data.t, data.p, s, data);\n},\n _renderPropTweens = function _renderPropTweens(ratio, data) {\n var pt = data._pt;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n},\n _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) {\n var pt = this._pt,\n next;\n\n while (pt) {\n next = pt._next;\n pt.p === property && pt.modifier(modifier, tween, target);\n pt = next;\n }\n},\n _killPropTweensOf = function _killPropTweensOf(property) {\n var pt = this._pt,\n hasNonDependentRemaining,\n next;\n\n while (pt) {\n next = pt._next;\n\n if (pt.p === property && !pt.op || pt.op === property) {\n _removeLinkedListItem(this, pt, \"_pt\");\n } else if (!pt.dep) {\n hasNonDependentRemaining = 1;\n }\n\n pt = next;\n }\n\n return !hasNonDependentRemaining;\n},\n _setterWithModifier = function _setterWithModifier(target, property, value, data) {\n data.mSet(target, property, data.m.call(data.tween, value, data.mt), data);\n},\n _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) {\n var pt = parent._pt,\n next,\n pt2,\n first,\n last; //sorts the PropTween linked list in order of priority because some plugins need to do their work after ALL of the PropTweens were created (like RoundPropsPlugin and ModifiersPlugin)\n\n while (pt) {\n next = pt._next;\n pt2 = first;\n\n while (pt2 && pt2.pr > pt.pr) {\n pt2 = pt2._next;\n }\n\n if (pt._prev = pt2 ? pt2._prev : last) {\n pt._prev._next = pt;\n } else {\n first = pt;\n }\n\n if (pt._next = pt2) {\n pt2._prev = pt;\n } else {\n last = pt;\n }\n\n pt = next;\n }\n\n parent._pt = first;\n}; //PropTween key: t = target, p = prop, r = renderer, d = data, s = start, c = change, op = overwriteProperty (ONLY populated when it's different than p), pr = priority, _next/_prev for the linked list siblings, set = setter, m = modifier, mSet = modifierSetter (the original setter, before a modifier was added)\n\n\nvar PropTween = /*#__PURE__*/function () {\n function PropTween(next, target, prop, start, change, renderer, data, setter, priority) {\n this.t = target;\n this.s = start;\n this.c = change;\n this.p = prop;\n this.r = renderer || _renderPlain;\n this.d = data || this;\n this.set = setter || _setterPlain;\n this.pr = priority || 0;\n this._next = next;\n\n if (next) {\n next._prev = this;\n }\n }\n\n var _proto4 = PropTween.prototype;\n\n _proto4.modifier = function modifier(func, tween, target) {\n this.mSet = this.mSet || this.set; //in case it was already set (a PropTween can only have one modifier)\n\n this.set = _setterWithModifier;\n this.m = func;\n this.mt = target; //modifier target\n\n this.tween = tween;\n };\n\n return PropTween;\n}(); //Initialization tasks\n\n_forEachName(_callbackNames + \"parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger\", function (name) {\n return _reservedProps[name] = 1;\n});\n\n_globals.TweenMax = _globals.TweenLite = Tween;\n_globals.TimelineLite = _globals.TimelineMax = Timeline;\n_globalTimeline = new Timeline({\n sortChildren: false,\n defaults: _defaults,\n autoRemoveChildren: true,\n id: \"root\",\n smoothChildTiming: true\n});\n_config.stringFilter = _colorStringFilter;\n\nvar _media = [],\n _listeners = {},\n _emptyArray = [],\n _lastMediaTime = 0,\n _contextID = 0,\n _dispatch = function _dispatch(type) {\n return (_listeners[type] || _emptyArray).map(function (f) {\n return f();\n });\n},\n _onMediaChange = function _onMediaChange() {\n var time = Date.now(),\n matches = [];\n\n if (time - _lastMediaTime > 2) {\n _dispatch(\"matchMediaInit\");
1\n\n _media.forEach(function (c) {\n var queries = c.queries,\n conditions = c.conditions,\n match,\n p,\n anyMatch,\n toggled;\n\n for (p in queries) {\n match = _win.matchMedia(queries[p]).matches; // Firefox doesn't update the \"matches\" property of the MediaQueryList object correctly - it only does so as it calls its change handler - so we must re-create a media query here to ensure it's accurate.\n\n match && (anyMatch = 1);\n\n if (match !== conditions[p]) {\n conditions[p] = match;\n toggled = 1;\n }\n }\n\n if (toggled) {\n c.revert();\n anyMatch && matches.push(c);\n }\n });\n\n _dispatch(\"matchMediaRevert\");\n\n matches.forEach(function (c) {\n return c.onMatch(c, function (func) {\n return c.add(null, func);\n });\n });\n _lastMediaTime = time;\n\n _dispatch(\"matchMedia\");\n }\n};\n\nvar Context = /*#__PURE__*/function () {\n function Context(func, scope) {\n this.selector = scope && selector(scope);\n this.data = [];\n this._r = []; // returned/cleanup functions\n\n this.isReverted = false;\n this.id = _contextID++; // to work around issues that frameworks like Vue cause by making things into Proxies which make it impossible to do something like _media.indexOf(this) because \"this\" would no longer refer to the Context instance itself - it'd refer to a Proxy! We needed a way to identify the context uniquely\n\n func && this.add(func);\n }\n\n var _proto5 = Context.prototype;\n\n _proto5.add = function add(name, func, scope) {\n // possible future addition if we need the ability to add() an animation to a context and for whatever reason cannot create that animation inside of a context.add(() => {...}) function.\n // if (name && _isFunction(name.revert)) {\n // \tthis.data.push(name);\n // \treturn (name._ctx = this);\n // }\n if (_isFunction(name)) {\n scope = func;\n func = name;\n name = _isFunction;\n }\n\n var self = this,\n f = function f() {\n var prev = _context,\n prevSelector = self.selector,\n result;\n prev && prev !== self && prev.data.push(self);\n scope && (self.selector = selector(scope));\n _context = self;\n result = func.apply(self, arguments);\n _isFunction(result) && self._r.push(result);\n _context = prev;\n self.selector = prevSelector;\n self.isReverted = false;\n return result;\n };\n\n self.last = f;\n return name === _isFunction ? f(self, function (func) {\n return self.add(null, func);\n }) : name ? self[name] = f : f;\n };\n\n _proto5.ignore = function ignore(func) {\n var prev = _context;\n _context = null;\n func(this);\n _context = prev;\n };\n\n _proto5.getTweens = function getTweens() {\n var a = [];\n this.data.forEach(function (e) {\n return e instanceof Context ? a.push.apply(a, e.getTweens()) : e instanceof Tween && !(e.parent && e.parent.data === \"nested\") && a.push(e);\n });\n return a;\n };\n\n _proto5.clear = function clear() {\n this._r.length = this.data.length = 0;\n };\n\n _proto5.kill = function kill(revert, matchMedia) {\n var _this4 = this;\n\n if (revert) {\n (function () {\n var tweens = _this4.getTweens(),\n i = _this4.data.length,\n t;\n\n while (i--) {\n // Flip plugin tweens are very different in that they should actually be pushed to their end. The plugin replaces the timeline's .revert() method to do exactly that. But we also need to remove any of those nested tweens inside the flip timeline so that they don't get individually reverted.\n t = _this4.data[i];\n\n if (t.data === \"isFlip\") {\n t.revert();\n t.getChildren(true, true, false).forEach(function (tween) {\n return tweens.splice(tweens.indexOf(tween), 1);\n });\n }\n } // save as an object so that we can cache the globalTime for each tween to optimize performance during the sort\n\n\n tweens.map(function (t) {\n return {\n g: t._dur || t._delay || t._sat && !t._sat.vars.immediateRender ? t.globalTime(0) : -Infinity,\n t: t\n };\n }).sort(function (a, b) {\n return b.g - a.g || -Infinity;\n }
1).forEach(function (o) {\n return o.t.revert(revert);\n }); // note: all of the _startAt tweens should be reverted in reverse order that they were created, and they'll all have the same globalTime (-1) so the \" || -1\" in the sort keeps the order properly.\n\n i = _this4.data.length;\n\n while (i--) {\n // make sure we loop backwards so that, for example, SplitTexts that were created later on the same element get reverted first\n t = _this4.data[i];\n\n if (t instanceof Timeline) {\n if (t.data !== \"nested\") {\n t.scrollTrigger && t.scrollTrigger.revert();\n t.kill(); // don't revert() the timeline because that's duplicating efforts since we already reverted all the tweens\n }\n } else {\n !(t instanceof Tween) && t.revert && t.revert(revert);\n }\n }\n\n _this4._r.forEach(function (f) {\n return f(revert, _this4);\n });\n\n _this4.isReverted = true;\n })();\n } else {\n this.data.forEach(function (e) {\n return e.kill && e.kill();\n });\n }\n\n this.clear();\n\n if (matchMedia) {\n var i = _media.length;\n\n while (i--) {\n // previously, we checked _media.indexOf(this), but some frameworks like Vue enforce Proxy objects that make it impossible to get the proper result that way, so we must use a unique ID number instead.\n _media[i].id === this.id && _media.splice(i, 1);\n }\n }\n };\n\n _proto5.revert = function revert(config) {\n this.kill(config || {});\n };\n\n return Context;\n}();\n\nvar MatchMedia = /*#__PURE__*/function () {\n function MatchMedia(scope) {\n this.contexts = [];\n this.scope = scope;\n _context && _context.data.push(this);\n }\n\n var _proto6 = MatchMedia.prototype;\n\n _proto6.add = function add(conditions, func, scope) {\n _isObject(conditions) || (conditions = {\n matches: conditions\n });\n var context = new Context(0, scope || this.scope),\n cond = context.conditions = {},\n mq,\n p,\n active;\n _context && !context.selector && (context.selector = _context.selector); // in case a context is created inside a context. Like a gsap.matchMedia() that's inside a scoped gsap.context()\n\n this.contexts.push(context);\n func = context.add(\"onMatch\", func);\n context.queries = conditions;\n\n for (p in conditions) {\n if (p === \"all\") {\n active = 1;\n } else {\n mq = _win.matchMedia(conditions[p]);\n\n if (mq) {\n _media.indexOf(context) < 0 && _media.push(context);\n (cond[p] = mq.matches) && (active = 1);\n mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener(\"change\", _onMediaChange);\n }\n }\n }\n\n active && func(context, function (f) {\n return context.add(null, f);\n });\n return this;\n } // refresh() {\n // \tlet time = _lastMediaTime,\n // \t\tmedia = _media;\n // \t_lastMediaTime = -1;\n // \t_media = this.contexts;\n // \t_onMediaChange();\n // \t_lastMediaTime = time;\n // \t_media = media;\n // }\n ;\n\n _proto6.revert = function revert(config) {\n this.kill(config || {});\n };\n\n _proto6.kill = function kill(revert) {\n this.contexts.forEac
1h(function (c) {\n return c.kill(revert, true);\n });\n };\n\n return MatchMedia;\n}();\n/*\n * --------------------------------------------------------------------------------------\n * GSAP\n * --------------------------------------------------------------------------------------\n */\n\n\nvar _gsap = {\n registerPlugin: function registerPlugin() {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n args.forEach(function (config) {\n return _createPlugin(config);\n });\n },\n timeline: function timeline(vars) {\n return new Timeline(vars);\n },\n getTweensOf: function getTweensOf(targets, onlyActive) {\n return _globalTimeline.getTweensOf(targets, onlyActive);\n },\n getProperty: function getProperty(target, property, unit, uncache) {\n _isString(target) && (target = toArray(target)[0]); //in case selector text or an array is passed in\n\n var getter = _getCache(target || {}).get,\n format = unit ? _passThrough : _numericIfPossible;\n\n unit === \"native\" && (unit = \"\");\n return !target ? target : !property ? function (property, unit, uncache) {\n return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));\n } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));\n },\n quickSetter: function quickSetter(target, property, unit) {\n target = toArray(target);\n\n if (target.length > 1) {\n var setters = target.map(function (t) {\n return gsap.quickSetter(t, property, unit);\n }),\n l = setters.length;\n return function (value) {\n var i = l;\n\n while (i--) {\n setters[i](value);\n }\n };\n }\n\n target = target[0] || {};\n\n var Plugin = _plugins[property],\n cache = _getCache(target),\n p = cache.harness && (cache.harness.aliases || {})[property] || property,\n // in case it's an alias, like \"rotate\" for \"rotation\".\n setter = Plugin ? function (value) {\n var p = new Plugin();\n _quickTween._pt = 0;\n p.init(target, unit ? value + unit : value, _quickTween, 0, [target]);\n p.render(1, p);\n _quickTween._pt && _renderPropTweens(1, _quickTween);\n } : cache.set(target, p);\n\n return Plugin ? setter : function (value) {\n return setter(target, p, unit ? value + unit : value, cache, 1);\n };\n },\n quickTo: function quickTo(target, property, vars) {\n var _merge2;\n\n var tween = gsap.to(target, _merge((_merge2 = {}, _merge2[property] = \"+=0.1\", _merge2.paused = true, _merge2), vars || {})),\n func = function func(value, start, startIsRelative) {\n return tween.resetTo(property, value, start, startIsRelative);\n };\n\n func.tween = tween;\n return func;\n },\n isTweening: function isTweening(targets) {\n return _globalTimeline.getTweensOf(targets, true).length > 0;\n },\n defaults: function defaults(value) {\n value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease));\n return _mergeDeep(_defaults, value || {});\n },\n config: function config(value) {\n return _mergeDeep(_config, value || {});\n },\n registerEffect: function registerEffect(_ref3) {\n var name = _ref3.name,\n effect = _ref3.effect,\n plugins = _ref3.plugins,\n defaults = _ref3.defaults,\n extendTimeline = _ref3.extendTimeline;\n (plugins || \"\").split(\",\").forEach(function (pluginName) {\n return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + \" effect requires \" + pluginName + \" plugin.\");\n });\n\n _effects[name] = function (targets, vars, tl) {\n return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl);\n };\n\n if (extendTimeline) {\n Timeline.prototype[name] = function (targets, vars, position) {\n return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position);\n };\n }\n },\n registerEase: function registerEase(name, ease) {\n _easeMap[name] = _parseEase(ease);\n },\n parseEase: function parseEase(ease, defaultEase) {\n return arguments.length ? _parseEase(ease, defaultEase) : _easeMap;\n },\n getById: function getById(id) {\n return _globalTimeline.getById(id);\n },\n exportRoot: function exportRoot(vars, includeDelayedCalls) {\n if (vars === void 0) {\n vars = {};\n }\n\n var tl = new Timeline(vars),\n child,\n next;\n tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming);\n\n _globalTimeline.remove(tl);\n\n tl._dp = 0;
1 //otherwise it'll get re-activated when adding children and be re-introduced into _globalTimeline's linked list (then added to itself).\n\n tl._time = tl._tTime = _globalTimeline._time;\n child = _globalTimeline._first;\n\n while (child) {\n next = child._next;\n\n if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) {\n _addToTimeline(tl, child, child._start - child._delay);\n }\n\n child = next;\n }\n\n _addToTimeline(_globalTimeline, tl, 0);\n\n return tl;\n },\n context: function context(func, scope) {\n return func ? new Context(func, scope) : _context;\n },\n matchMedia: function matchMedia(scope) {\n return new MatchMedia(scope);\n },\n matchMediaRefresh: function matchMediaRefresh() {\n return _media.forEach(function (c) {\n var cond = c.conditions,\n found,\n p;\n\n for (p in cond) {\n if (cond[p]) {\n cond[p] = false;\n found = 1;\n }\n }\n\n found && c.revert();\n }) || _onMediaChange();\n },\n addEventListener: function addEventListener(type, callback) {\n var a = _listeners[type] || (_listeners[type] = []);\n ~a.indexOf(callback) || a.push(callback);\n },\n removeEventListener: function removeEventListener(type, callback) {\n var a = _listeners[type],\n i = a && a.indexOf(callback);\n i >= 0 && a.splice(i, 1);\n },\n utils: {\n wrap: wrap,\n wrapYoyo: wrapYoyo,\n distribute: distribute,\n random: random,\n snap: snap,\n normalize: normalize,\n getUnit: getUnit,\n clamp: clamp,\n splitColor: splitColor,\n toArray: toArray,\n selector: selector,\n mapRange: mapRange,\n pipe: pipe,\n unitize: unitize,\n interpolate: interpolate,\n shuffle: shuffle\n },\n install: _install,\n effects: _effects,\n ticker: _ticker,\n updateRoot: Timeline.updateRoot,\n plugins: _plugins,\n globalTimeline: _globalTimeline,\n core: {\n PropTween: PropTween,\n globals: _addGlobal,\n Tween: Tween,\n Timeline: Timeline,\n Animation: Animation,\n getCache: _getCache,\n _removeLinkedListItem: _removeLinkedListItem,\n reverting: function reverting() {\n return _reverting;\n },\n context: function context(toAdd) {\n if (toAdd && _context) {\n _context.data.push(toAdd);\n\n toAdd._ctx = _context;\n }\n\n return _context;\n },\n suppressOverwrites: function suppressOverwrites(value) {\n return _suppressOverwrites = value;\n }\n }\n};\n\n_forEachName(\"to,from,fromTo,delayedCall,set,killTweensOf\", function (name) {\n return _gsap[name] = Tween[name];\n});\n\n_ticker.add(Timeline.updateRoot);\n\n_quickTween = _gsap.to({}, {\n duration: 0\n}); // ---- EXTRA PLUGINS --------------------------------------------------------\n\nvar _getPluginPropTween = function _getPluginPropTween(plugin, prop
1) {\n var pt = plugin._pt;\n\n while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) {\n pt = pt._next;\n }\n\n return pt;\n},\n _addModifiers = function _addModifiers(tween, modifiers) {\n var targets = tween._targets,\n p,\n i,\n pt;\n\n for (p in modifiers) {\n i = targets.length;\n\n while (i--) {\n pt = tween._ptLookup[i][p];\n\n if (pt && (pt = pt.d)) {\n if (pt._pt) {\n // is a plugin\n pt = _getPluginPropTween(pt, p);\n }\n\n pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p);\n }\n }\n }\n},\n _buildModifierPlugin = function _buildModifierPlugin(name, modifier) {\n return {\n name: name,\n rawVars: 1,\n //don't pre-process function-based values or \"random()\" strings.\n init: function init(target, vars, tween) {\n tween._onInit = function (tween) {\n var temp, p;\n\n if (_isString(vars)) {\n temp = {};\n\n _forEachName(vars, function (name) {\n return temp[name] = 1;\n }); //if the user passes in a comma-delimited list of property names to roundProps, like \"x,y\", we round to whole numbers.\n\n\n vars = temp;\n }\n\n if (modifier) {\n temp = {};\n\n for (p in vars) {\n temp[p] = modifier(vars[p]);\n }\n\n vars = temp;\n }\n\n _addModifiers(tween, vars);\n };\n }\n };\n}; //register core plugins\n\n\nvar gsap = _gsap.registerPlugin({\n name: \"attr\",\n init: function init(target, vars, tween, index, targets) {\n var p, pt, v;\n this.tween = tween;\n\n for (p in vars) {\n v = target.getAttribute(p) || \"\";\n pt = this.add(target, \"setAttribute\", (v || 0) + \"\", vars[p], index, targets, 0, 0, p);\n pt.op = p;\n pt.b = v; // record the beginning value so we can revert()\n\n this._props.push(p);\n }\n },\n render: function render(ratio, data) {\n var pt = data._pt;\n\n while (pt) {\n _reverting ? pt.set(pt.t, pt.p, pt.b, pt) : pt.r(ratio, pt.d); // if reverting, go back to the original (pt.b)\n\n pt = pt._next;\n }\n }\n}, {\n name: \"endArray\",\n init: function init(target, value) {\n var i = value.length;\n\n while (i--) {\n this.add(target, i, target[i] || 0, value[i], 0, 0, 0, 0, 0, 1);\n }\n }\n}, _buildModifierPlugin(\"roundProps\", _roundModifier), _buildModifierPlugin(\"modifiers\"), _buildModifierPlugin(\"snap\", snap)) || _gsap; //to prevent the core plugins from being dropped via aggressive tree shaking, we must include them in the variable declaration in this way.\n\nTween.version = Timeline.version = gsap.version = \"3.12.5\";\n_coreReady = 1;\n_windowExists() && _wake();\nvar Power0 = _easeMap.Power0,\n Power1 = _easeMap.Power1,\n Power2 = _easeMap.Power2,\n Power3 = _easeMap.Power3,\n Power4 = _easeMap.Power4,\n Linear = _easeMap.Linear,\n Quad = _easeMap.Quad,\n Cubic = _easeMap.Cubic,\n Quart = _easeMap.Quart,\n Quint = _easeMap.Quint,\n Strong = _easeMap.Strong,\n Elastic = _easeMap.Elastic,\n Back = _easeMap.Back,\n SteppedEase = _easeMap.SteppedEase,\n Bounce = _easeMap.Bounce,\n Sine = _easeMap.Sine,\n Expo = _easeMap.Expo,\n Circ = _easeMap.Circ;\n\n //export some internal methods/orojects for use in CSSPlugin so that we can externalize that file and allow custom builds that exclude it.\n\n\n;// CONCATENATED MODULE: ./node_modules/gsap/CSSPlugin.js\n/*!\n * CSSPlugin 3.12.5\n * https://gsap.com\n *\n * Copyright 2008-2024, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license or for\n * Club GSAP members, the agreement issued with that membership.\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\n\n\nvar CSSPlugin_win,\n CSSPlugin_doc,\n _docElement,\n _pluginInitted,\n _tempDiv,\n _tempDivStyler,\n _recentSetterPlugin,\n CSSPlugin_reverting,\n CSSPlugin_windowExists = function _windowExists() {\n return typeof window !== \"undefined\";\n},\n _transformProps = {},\n _RAD2DEG = 180 / Math.PI,\n _DEG2RAD = Math.PI / 180,\n _atan2 = Math.atan2,\n CSSPlugin_bigNum = 1e8,\n _capsExp = /([A-Z])/g,\n _horizontalExp = /(left|right|width|margin|padding|x)/i,\n _complexExp = /[\\s,\\(]\\S/,\n _propertyAliases = {\n autoAlpha: \"opacity,visibility\",\n scale: \"scaleX,scaleY\",\n alpha: \"opacity\"\n},\n _renderCSSProp = function _renderCSSProp(ratio, data) {\n return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);\n},\n _renderPropWithEnd = function _renderPropWithEnd(ratio, data) {\n return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);\n},\n _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) {\n return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data);\n},\n //if units change, we need a way to render the original unit/value when the tween goes all the way back to the beginning (ratio:0)\n_renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) {\n var value = data.s + data.c * ratio;\n data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data);\n},\n _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) {\n return data.set(data.t, data.p, ratio ? data.e : data.b, data);\n},\n _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) {\n return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data);\n},\n _setterCSSStyle = function _setterCSSStyle(target, property, value) {\n return target.style[property] = value;\n},\n _setterCSSProp = function _setterCSSProp(target, property, value) {\n return target.style.setProperty(property, value);\n},\n _setterTransform = function _setterTransform(target, property, value) {\n return target._gsap[property] = value;\n},\n _setterScale = function _setterScale(target, property, value) {\n return target._gsap.scaleX = target._gsap.scaleY = value;\n},\n _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) {\n var cache = target._gsap;\n cache.scaleX = cache.scaleY = value;\n cache.renderTransform(ratio, cache);\n},\n _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) {\n var cache = target._gsap;\n cache[property] = value;\n cache.renderTransform(ratio, cache);\n},\n _transformProp = \"transform\",\n _transformOriginProp = _transformProp + \"Origin\",\n _saveStyle = function _saveStyle(property, isNotCSS) {\n var _this = this;\n\n var target = this.target,\n style = target.style,\n cache = target._gsap;\n\n if (property in _transformProps && style) {\n this.tfm = this.tfm || {};\n\n if (property !== \"transform\") {\n property = _propertyAliases[property] || property;\n ~property.indexOf(\",\") ? property.split(\",\").forEach(function (a) {\n return _this.tfm[a] = _get(target, a);\n }) : this.tfm[property] = cache.x ? cache[property] : _get(target, property); // note: scale would map to \"scaleX,scaleY\", thus we loop and apply them both.\n\n property === _transformOriginProp && (this.tfm.zOrigin = cache.zOrigin);\n } else {\n return _propertyAliases.transform.split(\",\").forEach(function (p) {\n return _saveStyle.call(_this, p, isNotCSS);\n });\n }\n\n if (this.props.indexOf(_transformProp) >= 0) {\n return;\n }\n\n if (cache.svg) {\n this.svgo = target.getAttribute(\"data-svg-origin\");\n this.props.push(_transformOriginProp, isNotCSS, \"\");\n }\n\n property = _transformProp;\n }\n\n (style || isNotCSS) && this.props.push(property, isNotCSS, style[property]);\n},\n _removeIndependentTransforms = function _removeIndependentTransforms(style) {\n if (style.translate) {\n style.removeProperty(\"translate\");\n style.removeProperty(\"scale\");\n style.removeProperty(\"rotate\");\n }\n},\n _revertStyle = function _revertStyle() {\n var props = this.props,\n target = this.target,\n style = target.style,\n cache = target._gsap,\n i,\n p;\n\n for (i = 0; i < props.length; i += 3) {\n // stored like this: property, isNotCSS, value\n props[i + 1] ? target[props[i]] = props[i + 2] : props[i + 2] ? style[props[i]] = props[i + 2] : style.removeProperty(props[i].substr(0, 2) === \"--\" ? props[i] : props[i].replace(_capsExp, \"-$1\").toLowerCase());\n }\n\n if (this.tfm) {\n for (p in this.tfm) {\n cache[p] = this.tfm[p];\n }\n\n if (cache.svg) {\n cache.renderTransform();\n target.setAttribute(\"data-svg-origin\", this.svgo || \"\");\n }\n\n i = CSSPlugin_reverting();\n\n if ((!i || !i.isStart) && !style[_transformProp]) {\n _removeIndependentTransforms(style);\n\n if (cache.zOrigin && style[_transformOriginProp]) {\n style[_transformOriginProp] += \" \" + cache.zOrigin + \"px\"; // since we're uncaching, we must put the zOrigin back into the transformOrigin so that we can pull it out accurately when we parse again. Otherwise, we'd lose the z portion of the origin since we extract it to protect from Safari bugs.\n\n cache.zOrigin = 0;\n cache.renderTransform();\n }\n\n cache.uncache = 1; // if it's a startAt that's being reverted in the _initTween() of the core, we don't need to uncache transforms. This is purely a performance optimization.\n }\n }\n},\n _getStyleSaver = function _getStyleSaver(target, properties) {\n var saver = {\n target: target,\n props: [],\n revert: _revertStyle,\n save: _saveStyle\n };\n target._gsap || gsap.core.getCache(target); // just make sure there's a _gsap cache defined because we read from it in _saveStyle() and it's more efficient to just check it here once.\n\n properties && properties.split(\",\").forEach(function (p) {\n return saver.save(p);\n });\n return saver;\n},\n _supports3D,\n _createElement = function _createElement(type, ns) {\n var e = CSSPlugin_doc.createElementNS ? CSSPlugin_doc.createElementNS((ns || \"http://www.w3.org/1999/xhtml\").replace(/^https/, \"http\"), type) : CSSPlugin_doc.createElement(type); //some servers swap in https for http in the namespace which can break things, making \"style\" inaccessible.\n\n return e && e.style ? e : CSSPlugin_doc.createElement(type); //some environments won't allow access to the element's style when created with a namespace in which case we default to the standard createElement() to work around the issue. Also note that when GSAP is embedded directly inside an SVG file, createElement() won't allow access to the style object in Firefox (see https://gsap.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/).\n},\n _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) {\n var cs = getComputedStyle(target);\n return cs[property] || cs.getPropertyValue(property.replace(_capsExp, \"-$1\").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || \"\"; //css variables may not need caps swapped out for dashes and lowercase.\n},\n _prefixes = \"O,Moz,ms,Ms,Webkit\".split(\",\"),\n _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) {\n var e = element || _tempDiv,\n s = e.style,\n i = 5;\n\n if (property in s && !preferPrefix) {\n return property;\n }\n\n property = property.charAt(0).toUpperCase() + property.substr(1);\n\n while (i-- && !(_prefixes[i] + property in s)) {}\n\n return i < 0 ? null : (i === 3 ? \"ms\" : i >= 0 ? _prefixes[i] : \"\") + property;\n},\n _initCore = function _initCore() {\n if (CSSPlugin_windowExists() && window.document) {\n CSSPlugin_win = window;\n CSSPlugin_doc = CSSPlugin_win.document;\n _docElement = CSSPlugin_doc.documentElement;\n _tempDiv = _createElement(\"div\") || {\n style: {}\n };\n _tempDivStyler = _createElement(\"div\");\n _transformProp = _checkPropPrefix(_transformProp);\n _transformOriginProp = _transformProp + \"Origin\";\n _tempDiv.style.cssText = \"border-width:0;line-height:0;position:absolute;padding:0\"; //make sure to override certain properties that may contaminate measurements, in case the user has overreaching style sheets.\n\n _supports3D = !!_checkPropPrefix(\"perspective\");\n CSSPlugin_reverting = gsap.core.reverting;\n _pluginInitted = 1;\n }\n},\n _getBBoxHack = function _getBBoxHack(swapIfPossible) {\n //works around issues in some browsers (like Firefox) that don't correctly report getBBox() on SVG elements inside a <defs> element and/or <mask>. We try creating an SVG, adding it to the documentElement and toss the element in there so that it's definitely part of the rendering tree, then grab the bbox and if it works, we actually swap out the original getBBox() method for our own that does these extra steps whenever getBBox is needed. This helps ensure that performance is optimal (only do all these extra steps when absolutely necessary...most elements don't need it).\n var svg = _createElement(\"svg\", this.ownerSVGElement && this.ownerSVGElement.getAttribute(\"xmlns\") || \"http://www.w3.org/2000/svg\"),\n oldParent = this.parentNode,\n oldSibling = this.nextSibling,\n oldCSS = this.style.cssText,\n bbox;\n\n _docElement.appendChild(svg);\n\n svg.appendChild(this);\n this.style.display = \"block\";\n\n if (swapIfPossible) {\n try {\n bbox = this.getBBox();\n this._gsapBBox = this.getBBox; //store the original\n\n this.getBBox = _getBBoxHack;\n } catch (e) {}\n } else if (this._gsapBBox) {\n bbox = this._gsapBBox();\n }\n\n if (oldParent) {\n if (oldSibling) {\n oldParent.insertBefore(this, oldSibling);\n } else {\n oldParent.appendChild(this);\n }\n }\n\n _docElement.removeChild(svg);\n\n this.style.cssText = oldCSS;\n return bbox;\n},\n _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) {\n var i = attributesArray.length;\n\n while (i--) {\n if (target.hasAttribute(attributesArray[i])) {\n return target.getAttribute(attributesArray[i]);\n }\n }\n},\n _getBBox = function _getBBox(target) {\n var bounds;\n\n try {\n bounds = target.getBBox(); //Firefox throws errors if you try calling getBBox() on an SVG element that's not rendered (like in a <symbol> or <defs>). https://bugzilla.mozilla.org/show_bug.cgi?id=612118\n } catch (error) {\n bounds = _getBBoxHack.call(target, true);\n }\n\n bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true)); //some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes it's at x:0, y:0), thus we need to manually grab the position in that case.\n\n return bounds && !bounds.width && !bounds.x && !bounds.y ? {\n x: +_getAttributeFallbacks(target, [\"x\", \"cx\", \"x1\"]) || 0,\n y: +_getAttributeFallbacks(target, [\"y\", \"cy\", \"y1\"]) || 0,\n width: 0,\n height: 0\n } : bounds;\n},\n _isSVG = function _isSVG(e) {\n return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));\n},\n //reports if the element is an SVG on which getBBox() actually works\n_removeProperty = function _removeProperty(target, property) {\n if (property) {\n var style = target.style,\n first2Chars;\n\n if (property in _transformProps && property !== _transformOriginProp) {\n property = _transformProp;\n }\n\n if (style.removeProperty) {\n first2Chars = property.substr(0, 2);\n\n if (first2Chars === \"ms\" || property.substr(0, 6) === \"webkit\") {\n //Microsoft and some Webkit browsers don't conform to the standard of capitalizing the first prefix character, so we adjust so that when we prefix the caps with a dash,
1 it's correct (otherwise it'd be \"ms-transform\" instead of \"-ms-transform\" for IE9, for example)\n property = \"-\" + property;\n }\n\n style.removeProperty(first2Chars === \"--\" ? property : property.replace(_capsExp, \"-$1\").toLowerCase());\n } else {\n //note: old versions of IE use \"removeAttribute()\" instead of \"removeProperty()\"\n style.removeAttribute(property);\n }\n }\n},\n _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) {\n var pt = new PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue);\n plugin._pt = pt;\n pt.b = beginning;\n pt.e = end;\n\n plugin._props.push(property);\n\n return pt;\n},\n _nonConvertibleUnits = {\n deg: 1,\n rad: 1,\n turn: 1\n},\n _nonStandardLayouts = {\n grid: 1,\n flex: 1\n},\n //takes a single value like 20px and converts it to the unit specified, like \"%\", returning only the numeric amount.\n_convertToUnit = function _convertToUnit(target, property, value, unit) {\n var curValue = parseFloat(value) || 0,\n curUnit = (value + \"\").trim().substr((curValue + \"\").length) || \"px\",\n // some browsers leave extra whitespace at the beginning of CSS variables, hence the need to trim()\n style = _tempDiv.style,\n horizontal = _horizontalExp.test(property),\n isRootSVG = target.tagName.toLowerCase() === \"svg\",\n measureProperty = (isRootSVG ? \"client\" : \"offset\") + (horizontal ? \"Width\" : \"Height\"),\n amount = 100,\n toPixels = unit === \"px\",\n toPercent = unit === \"%\",\n px,\n parent,\n cache,\n isSVG;\n\n if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) {\n return curValue;\n }\n\n curUnit !== \"px\" && !toPixels && (curValue = _convertToUnit(target, property, value, \"px\"));\n isSVG = target.getCTM && _isSVG(target);\n\n if ((toPercent || curUnit === \"%\") && (_transformProps[property] || ~property.indexOf(\"adius\"))) {\n px = isSVG ? target.getBBox()[horizontal ? \"width\" : \"height\"] : target[measureProperty];\n return _round(toPercent ? curValue / px * amount : curValue / 100 * px);\n }\n\n style[horizontal ? \"width\" : \"height\"] = amount + (toPixels ? curUnit : unit);\n parent = ~property.indexOf(\"adius\") || unit === \"em\" && target.appendChild && !isRootSVG ? target : target.parentNode;\n\n if (isSVG) {\n parent = (target.ownerSVGElement || {}).parentNode;\n }\n\n if (!parent || parent === CSSPlugin_doc || !parent.appendChild) {\n parent = CSSPlugin_doc.body;\n }\n\n cache = parent._gsap;\n\n if (cache && toPercent && cache.width && horizontal && cache.time === _ticker.time && !cache.uncache) {\n return _round(curValue / cache.width * amount);\n } else {\n if (toPercent && (property === \"height\" || property === \"width\")) {\n // if we're dealing with width/height that's inside a container with padding and/or it's a flexbox/grid container, we must apply it to the target itself rather than the _tempDiv in order to ensure complete accuracy, factoring in the parent's padding.\n var v = target.style[property];\n target.style[property] = amount + unit;\n px = target[measureProperty];\n v ? target.style[property] = v : _removeProperty(target, property);\n } else {\n (toPercent || curUnit === \"%\") && !_nonStandardLayouts[_getComputedProperty(parent, \"display\")] && (style.position = _getComputedProperty(target, \"position\"));\n parent === target && (style.position = \"static\"); // like for borderRadius, if it's a % we must have it relative to the target itself but that may not have position: relative or position: absolute in which case it'd go up the chain until it finds its offsetParent (bad). position: static protects against that.\n\n parent.appendChild(_tempDiv);\n px = _tempDiv[measureProperty];\n parent.removeChild(_tempDiv);\n style.position = \"absolute\";\n }\n\n if (horizontal && toPercent) {\n cache = _getCache(parent);\n cache.time = _ticker.time;\n cache.width = parent[measureProperty];\n }\n }\n\n return _round(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0);\n},\n _get = function _get(target, property, unit, uncache) {\n var value;\n _pluginInitted || _initCore();\n\n if (property in _propertyAliases && property !== \"transform\") {\n property = _propertyAliases[property];\n\n if (~property.indexOf(\",\")) {\n property = property.split(\",\")[0];\n }\n }\n\n if (_transformProps[property] && property !== \"transform\") {\n value = _parseTransform(target, uncache);\n value = property !== \"transformOrigin\" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + \" \" + value.zOrigin + \"px\";\n } else {\n value = target.style[property];\n\n if (!value || value === \"auto\" || uncache || ~(value + \"\").indexOf(\"calc(\")) {\n value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || _getProperty(target, property) || (property === \"opacity\" ? 1 : 0); // note: some browsers, like Firefox, don't report borderRadius correctly! Instead, it only reports every corner like borderTopLeftRadius\n }\n }\n\n return unit && !~(value + \"\").trim().indexOf(\" \") ? _convertToUnit(target, property, value, unit) + unit : value;\n},\n _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) {\n // note: we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus \"this\" would refer to the plugin.\n if (!start || start === \"none\") {\n // some browsers like Safari actually PREFER the prefixed property and mis-report the unprefixed value like clipPath (BUG). In other words, even though clipPath exists in the style (\"clipPath\" in target.style) and it's set in the CSS properly (along with -webkit-clip-path), Safari reports clipPath as \"none\" whereas WebkitClipPath reports accurately like \"ellipse(100% 0% at 50% 0%)\", so in this case we must SWITCH to using the prefixed property instead. See https://gsap.com/forums/topic/18310-clippath-doesnt-work-on-ios/\n var p = _checkPropPrefix(prop, target, 1),\n s = p && _getComputedProperty(target, p, 1);\n\n if (s && s !== start) {\n prop = p;\n start = s;\n } else if (prop === \"borderColor\") {\n start = _getComputedProperty(target, \"borderTopColor\"); // Firefox bug: always reports \"borderColor\" as \"\", so we must fall back to borderTopColor. See https://gsap.com/forums/topic/24583-how-to-return-colors-that-i-had-after-reverse/\n }\n }\n\n var pt = new PropTween(this._pt, target.style, prop, 0, 1, _renderComplexString),\n index = 0,\n matchIndex = 0,\n a,\n result,\n startValues,\n startNum,\n color,\n startValue,\n endValue,\n endNum,\n chunk,\n endUnit,\n startUnit,\n endValues;\n pt.b = start;\n pt.e = end;\n start += \"\"; // ensure values are strings\n\n end += \"\";\n\n if (end === \"auto\") {\n startValue = target.style[prop];\n target.style[prop] = end;\n end = _getComputedProperty(target, prop) || end;\n startValue ? target.style[prop] = startValue : _removeProperty(target, prop);\n }\n\n a = [start, end];\n\n _colorStringFilter(a); // pass an array with the starting and ending values and let the filter do whatever it needs to the values. If colors are found, it returns true and then we must match where the color shows up order-wise because for things like boxShadow, sometimes the browser provides the computed values with the color FIRST, but the user provides it with the color LAST, so flip them if necessary. Same for drop-shadow().\n\n\n start = a[0];\n end = a[1];\n startValues = start.match(_numWithUnitExp) || [];\n endValues = end.match(_numWithUnitExp) || [];\n\n if (endValues.length) {\n while (result = _numWithUnitExp.exec(end)) {\n endValue = result[0];\n chunk = end.substring(index, result.index);\n\n if (color) {\n color = (color + 1) % 5;\n } else if (chunk.substr(-5) === \"rgba(\" || chunk.substr(-5) === \"hsla(\") {\n color = 1;\n }\n\n if (endValue !== (startValue = startValues[matchIndex++] || \"\")) {\n startNum = parseFloat(startValue) || 0;\n startUnit = startValue.substr((startNum + \"\").length);\n endValue.charAt(1) === \"=\" && (endValue = _parseRelative(startNum, endValue) + startUnit);\n endNum = parseFloat(endValue);\n endUnit = endValue.substr((endNum + \"\").length);\n index = _numWithUnitExp.lastIndex - endUnit.length;\n\n if (!endUnit) {\n //if something like \"perspective:300\" is passed in and we must add a unit to the end\n endUnit = endUnit || _config.units[prop] || startUnit;\n\n if (index === end.length) {\n end += endUnit;\n pt.e += endUnit;\n }\n }\n\n if (startUnit !== endUnit) {\n startNum = _convertToUnit(target, prop, startValue, endUnit) || 0;\n } // these nested PropTweens are handled in a special way - we'll never actually call a render or setter method on them. We'll just loop through them in the parent complex string PropTween's render method.\n\n\n pt._pt = {\n _next: pt._pt,\n p: chunk || matchIndex === 1 ? chunk : \",\",\n //note: SVG spec allows om
1ission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case.\n s: startNum,\n c: endNum - startNum,\n m: color && color < 4 || prop === \"zIndex\" ? Math.round : 0\n };\n }\n }\n\n pt.c = index < end.length ? end.substring(index, end.length) : \"\"; //we use the \"c\" of the PropTween to store the final part of the string (after the last number)\n } else {\n pt.r = prop === \"display\" && end === \"none\" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue;\n }\n\n _relExp.test(end) && (pt.e = 0); //if the end string contains relative values or dynamic random(...) values, delete the end it so that on the final render we don't actually set it to the string with += or -= characters (forces it to use the calculated value).\n\n this._pt = pt; //start the linked list with this new PropTween. Remember, we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within another plugin too, thus \"this\" would refer to the plugin.\n\n return pt;\n},\n _keywordToPercent = {\n top: \"0%\",\n bottom: \"100%\",\n left: \"0%\",\n right: \"100%\",\n center: \"50%\"\n},\n _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) {\n var split = value.split(\" \"),\n x = split[0],\n y = split[1] || \"50%\";\n\n if (x === \"top\" || x === \"bottom\" || y === \"left\" || y === \"right\") {\n //the user provided them in the wrong order, so flip them\n value = x;\n x = y;\n y = value;\n }\n\n split[0] = _keywordToPercent[x] || x;\n split[1] = _keywordToPercent[y] || y;\n return split.join(\" \");\n},\n _renderClearProps = function _renderClearProps(ratio, data) {\n if (data.tween && data.tween._time === data.tween._dur) {\n var target = data.t,\n style = target.style,\n props = data.u,\n cache = target._gsap,\n prop,\n clearTransforms,\n i;\n\n if (props === \"all\" || props === true) {\n style.cssText = \"\";\n clearTransforms = 1;\n } else {\n props = props.split(\",\");\n i = props.length;\n\n while (--i > -1) {\n prop = props[i];\n\n if (_transformProps[prop]) {\n clearTransforms = 1;\n prop = prop === \"transformOrigin\" ? _transformOriginProp : _transformProp;\n }\n\n _removeProperty(target, prop);\n }\n }\n\n if (clearTransforms) {\n _removeProperty(target, _transformProp);\n\n if (cache) {\n cache.svg && target.removeAttribute(\"transform\");\n\n _parseTransform(target, 1); // force all the cached values back to \"normal\"/identity, otherwise if there's another tween that's already set to render transforms on this element, it could display the wrong values.\n\n\n cache.uncache = 1;\n\n _removeIndependentTransforms(style);\n }\n }\n }\n},\n // note: specialProps should return 1 if (and only if) they have a non-zero priority. It indicates we need to sort the linked list.\n_specialProps = {\n clearProps: function clearProps(plugin, target, property, endValue, tween) {\n if (tween.data !== \"isFromStart\") {\n var pt = plugin._pt = new PropTween(plugin._pt, target, property, 0, 0, _renderClearProps);\n pt.u = endValue;\n pt.pr = -10;\n pt.tween = tween;\n\n plugin._props.push(property);\n\n return 1;\n }\n }\n /* className feature (about 0.4kb gzipped).\n , className(plugin, target, property, endValue, tween) {\n \tlet _renderClassName = (ratio, data) => {\n \t\t\tdata.css.render(ratio, data.css);\n \t\t\tif (!ratio || ratio === 1) {\n \t\t\t\tlet inline = data.rmv,\n \t\t\t\t\ttarget = data.t,\n \t\t\t\t\tp;\n \t\t\t\ttarget.setAttribute(\"class\", ratio ? data.e : data.b);\n \t\t\t\tfor (p in inline) {\n \t\t\t\t\t_removeProperty(target, p);\n \t\t\t\t}\n \t\t\t}\n \t\t},\n \t\t_getAllStyles = (target) => {\n \t\t\tlet styles = {},\n \t\t\t\tcomputed = getComputedStyle(target),\n \t\t\t\tp;
1\n \t\t\tfor (p in computed) {\n \t\t\t\tif (isNaN(p) && p !== \"cssText\" && p !== \"length\") {\n \t\t\t\t\tstyles[p] = computed[p];\n \t\t\t\t}\n \t\t\t}\n \t\t\t_setDefaults(styles, _parseTransform(target, 1));\n \t\t\treturn styles;\n \t\t},\n \t\tstartClassList = target.getAttribute(\"class\"),\n \t\tstyle = target.style,\n \t\tcssText = style.cssText,\n \t\tcache = target._gsap,\n \t\tclassPT = cache.classPT,\n \t\tinlineToRemoveAtEnd = {},\n \t\tdata = {t:target, plugin:plugin, rmv:inlineToRemoveAtEnd, b:startClassList, e:(endValue.charAt(1) !== \"=\") ? endValue : startClassList.replace(new RegExp(\"(?:\\\\s|^)\" + endValue.substr(2) + \"(?![\\\\w-])\"), \"\") + ((endValue.charAt(0) === \"+\") ? \" \" + endValue.substr(2) : \"\")},\n \t\tchangingVars = {},\n \t\tstartVars = _getAllStyles(target),\n \t\ttransformRelated = /(transform|perspective)/i,\n \t\tendVars, p;\n \tif (classPT) {\n \t\tclassPT.r(1, classPT.d);\n \t\t_removeLinkedListItem(classPT.d.plugin, classPT, \"_pt\");\n \t}\n \ttarget.setAttribute(\"class\", data.e);\n \tendVars = _getAllStyles(target, true);\n \ttarget.setAttribute(\"class\", startClassList);\n \tfor (p in endVars) {\n \t\tif (endVars[p] !== startVars[p] && !transformRelated.test(p)) {\n \t\t\tchangingVars[p] = endVars[p];\n \t\t\tif (!style[p] && style[p] !== \"0\") {\n \t\t\t\tinlineToRemoveAtEnd[p] = 1;\n \t\t\t}\n \t\t}\n \t}\n \tcache.classPT = plugin._pt = new PropTween(plugin._pt, target, \"className\", 0, 0, _renderClassName, data, 0, -11);\n \tif (style.cssText !== cssText) { //only apply if things change. Otherwise, in cases like a background-image that's pulled dynamically, it could cause a refresh. See https://gsap.com/forums/topic/20368-possible-gsap-bug-switching-classnames-in-chrome/.\n \t\tstyle.cssText = cssText; //we recorded cssText before we swapped classes and ran _getAllStyles() because in cases when a className tween is overwritten, we remove all the related tweening properties from that class change (otherwise class-specific stuff can't override properties we've directly set on the target's style object due to specificity).\n \t}\n \t_parseTransform(target, true); //to clear the caching of transforms\n \tdata.css = new gsap.plugins.css();
1\n \tdata.css.init(target, changingVars, tween);\n \tplugin._props.push(...data.css._props);\n \treturn 1;\n }\n */\n\n},\n\n/*\n * --------------------------------------------------------------------------------------\n * TRANSFORMS\n * --------------------------------------------------------------------------------------\n */\n_identity2DMatrix = [1, 0, 0, 1, 0, 0],\n _rotationalProperties = {},\n _isNullTransform = function _isNullTransform(value) {\n return value === \"matrix(1, 0, 0, 1, 0, 0)\" || value === \"none\" || !value;\n},\n _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) {\n var matrixString = _getComputedProperty(target, _transformProp);\n\n return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_numExp).map(_round);\n},\n _getMatrix = function _getMatrix(target, force2D) {\n var cache = target._gsap || _getCache(target),\n style = target.style,\n matrix = _getComputedTransformMatrixAsArray(target),\n parent,\n nextSibling,\n temp,\n addedToDOM;\n\n if (cache.svg && target.getAttribute(\"transform\")) {\n temp = target.transform.baseVal.consolidate().matrix; //ensures that even complex values like \"translate(50,60) rotate(135,0,0)\" are parsed because it mashes it into a matrix.\n\n matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f];\n return matrix.join(\",\") === \"1,0,0,1,0,0\" ? _identity2DMatrix : matrix;\n } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) {\n //note: if offsetParent is null, that means the element isn't in the normal document flow, like if it has display:none or one of its ancestors has display:none). Firefox returns null for getComputedStyle() if the element is in an iframe that has display:none. https://bugzilla.mozilla.org/show_bug.cgi?id=548397\n //browsers don't report transforms accurately unless the element is in the DOM and has a display value that's not \"none\". Firefox and Microsoft browsers have a partial bug where they'll report transforms even if display:none BUT not any percentage-based values like translate(-50%, 8px) will be reported as if it's translate(0, 8px).\n temp = style.display;\n style.display = \"block\";\n parent = target.parentNode;\n\n if (!parent || !target.offsetParent) {\n // note: in 3.3.0 we switched target.offsetParent to _doc.body.contains(target) to avoid [sometimes unnecessary] MutationObserver calls but that wasn't adequate because there are edge cases where nested position: fixed elements need to get reparented to accurately sense transforms. See https://github.com/greensock/GSAP/issues/388 and https://github.com/greensock/GSAP/issues/375\n addedToDOM = 1; //flag\n\n nextSibling = target.nextElementSibling;\n\n _docElement.appendChild(target); //we must add it to the DOM in order to get values properly\n\n }\n\n matrix = _getComputedTransformMatrixAsArray(target);\n temp ? style.display = temp : _removeProperty(target, \"display\");
1\n\n if (addedToDOM) {\n nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target);\n }\n }\n\n return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix;\n},\n _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) {\n var cache = target._gsap,\n matrix = matrixArray || _getMatrix(target, true),\n xOriginOld = cache.xOrigin || 0,\n yOriginOld = cache.yOrigin || 0,\n xOffsetOld = cache.xOffset || 0,\n yOffsetOld = cache.yOffset || 0,\n a = matrix[0],\n b = matrix[1],\n c = matrix[2],\n d = matrix[3],\n tx = matrix[4],\n ty = matrix[5],\n originSplit = origin.split(\" \"),\n xOrigin = parseFloat(originSplit[0]) || 0,\n yOrigin = parseFloat(originSplit[1]) || 0,\n bounds,\n determinant,\n x,\n y;\n\n if (!originIsAbsolute) {\n bounds = _getBBox(target);\n xOrigin = bounds.x + (~originSplit[0].indexOf(\"%\") ? xOrigin / 100 * boun
1ds.width : xOrigin);\n yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf(\"%\") ? yOrigin / 100 * bounds.height : yOrigin); // if (!(\"xOrigin\" in cache) && (xOrigin || yOrigin)) { // added in 3.12.3, reverted in 3.12.4; requires more exploration\n // \txOrigin -= bounds.x;\n // \tyOrigin -= bounds.y;\n // }\n } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) {\n //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero.\n x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;\n y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;\n xOrigin = x;\n yOrigin = y; // theory: we only had to do this for smoothing and it assumes that the previous one was not originIsAbsolute.\n }\n\n if (smooth || smooth !== false && cache.smooth) {\n tx = xOrigin - xOriginOld;\n ty = yOrigin - yOriginOld;\n cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx;\n cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty;\n } else {\n cache.xOffset = cache.yOffset = 0;\n }\n\n cache.xOrigin = xOrigin;\n cache.yOrigin = yOrigin;\n cache.smooth = !!smooth;\n cache.origin = origin;\n cache.originIsAbsolute = !!originIsAbsolute;\n target.style[_transformOriginProp] = \"0px 0px\"; //otherwise, if someone sets an origin via CSS, it will likely interfere with the SVG transform attribute ones (because remember, we're baking the origin into the matrix() value).\n\n if (pluginToAddPropTweensTo) {\n _addNonTweeningPT(pluginToAddPropTweensTo, cache, \"xOrigin\", xOriginOld, xOrigin);\n\n _addNonTweeningPT(pluginToAddPropTweensTo, cache, \"yOrigin\", yOriginOld, yOrigin);\n\n _addNonTweeningPT(pluginToAddPropTweensTo, cache, \"xOffset\", xOffsetOld, cache.xOffset);\n\n _addNonTweeningPT(pluginToAddPropTweensTo, cache, \"yOffset\", yOffsetOld, cache.yOffset);\n }\n\n target.setAttribute(\"data-svg-origin\", xOrigin + \" \" + yOrigin);\n},\n _parseTransform = function _parseTransform(target, uncache) {\n var cache = target._gsap || new GSCache(target);\n\n if (\"x\" in cache && !uncache && !cache.uncache) {\n return cache;\n }\n\n var style = target.style,\n invertedScaleX = cache.scaleX < 0,\n px = \"px\",\n deg = \"deg\",\n cs = getComputedStyle(target),\n origin = _getComputedProperty(target, _transformOriginProp) || \"0\",\n x,\n y,\n z,\n scaleX,\n scaleY,\n rotation,\n rotationX,\n rotationY,\n skewX,\n skewY,\n perspective,\n xOrigin,\n yOrigin,\n matrix,\n angle,\n cos,\n sin,\n a,\n b,\n c,\n d,\n a12,\n a22,\n t1,\n t2,\n t3,\n a13,\n a23,\n a33,\n a42,\n a43,\n a32;\n x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0;\n scaleX = scaleY = 1;\n cache.svg = !!(target.getCTM && _isSVG(target));\n\n if (cs.translate) {\n // accommodate independent transforms by combining them into normal ones.\n if (cs.translate !== \"none\" || cs.scale !== \"none\" || cs.rotate !== \"none\") {\n style[_transformProp] = (cs.translate !== \"none\" ? \"translate3d(\" + (cs.translate + \" 0 0\").split(\" \").slice(0, 3).join(\", \") + \") \" : \"\") + (cs.rotate !== \"none\" ? \"rotate(\" + cs.rotate + \") \" : \"\") + (cs.scale !== \"none\" ? \"scale(\" + cs.scale.split(\" \").join(\",\") + \") \" : \"\") + (cs[_transformProp] !== \"none\" ? cs[_transformProp] : \"\");\n }\n\n style.scale = style.rotate = style.translate = \"none\";\n }\n\n matrix = _getMatrix(target, cache.svg);\n\n if (cache.svg) {\n if (cache.uncache) {\n // if cache.uncache is true (and maybe if origin is 0,0), we need to set element.style.transformOrigin = (cache.xOrigin - bbox.x) + \"px \" + (cache.yOrigin - bbox.y) + \"px\". Previously we let the data-svg-origin stay instead, but when introducing revert(), it complicated things.\n t2 = target.getBBox();\n origin = cache.xOrigin - t2.x + \"px \" + (cache.yOrigin - t2.y) + \"px\";\n t1 = \"\";\n } else {\n t1 = !uncache && target.getAttribute(\"data-svg-origin\"); // Remember, to work around browser inconsistencies we always force SVG elements' transformOrigin to 0,0 and offset the translation accordingly.\n }\n\n _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix
1);\n }\n\n xOrigin = cache.xOrigin || 0;\n yOrigin = cache.yOrigin || 0;\n\n if (matrix !== _identity2DMatrix) {\n a = matrix[0]; //a11\n\n b = matrix[1]; //a21\n\n c = matrix[2]; //a31\n\n d = matrix[3]; //a41\n\n x = a12 = matrix[4];\n y = a22 = matrix[5]; //2D matrix\n\n if (matrix.length === 6) {\n scaleX = Math.sqrt(a * a + b * b);\n scaleY = Math.sqrt(d * d + c * c);\n rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist).\n\n skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0;\n skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD)));\n\n if (cache.svg) {\n x -= xOrigin - (xOrigin * a + yOrigin * c);\n y -= yOrigin - (xOrigin * b + yOrigin * d);\n } //3D matrix\n\n } else {\n a32 = matrix[6];\n a42 = matrix[7];\n a13 = matrix[8];\n a23 = matrix[9];\n a33 = matrix[10];\n a43 = matrix[11];\n x = matrix[12];\n y = matrix[13];\n z = matrix[14];\n angle = _atan2(a32, a33);\n rotationX = angle * _RAD2DEG; //rotationX\n\n if (angle) {\n cos = Math.cos(-angle);\n sin = Math.sin(-angle);\n t1 = a12 * cos + a13 * sin;\n t2 = a22 * cos + a23 * sin;\n t3 = a32 * cos + a33 * sin;\n a13 = a12 * -sin + a13 * cos;\n a23 = a22 * -sin + a23 * cos;\n a33 = a32 * -sin + a33 * cos;\n a43 = a42 * -sin + a43 * cos;\n a12 = t1;\n a22 = t2;\n a32 = t3;\n } //rotationY\n\n\n angle = _atan2(-c, a33);\n rotationY = angle * _RAD2DEG;\n\n if (angle) {\n cos = Math.cos(-angle);\n sin = Math.sin(-angle);\n t1 = a * cos - a13 * sin;\n t2 = b * cos - a23 * sin;\n t3 = c * cos - a33 * sin;\n a43 = d * sin + a43 * cos;\n a = t1;\n b = t2;\n c = t3;\n } //rotationZ\n\n\n angle = _atan2(b, a);\n rotation = angle * _RAD2DEG;\n\n if (angle) {\n cos = Math.cos(angle);\n sin = Math.sin(angle);\n t1 = a * cos + b * sin;\n t2 = a12 * cos + a22 * sin;\n b = b * cos - a * sin;\n a22 = a22 * cos - a12 * sin;\n a = t1;\n a12 = t2;\n }\n\n if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) {\n //when rotationY is set, it will often be parsed as 180 degrees different than it should be, and rotationX and rotation both being 180 (it looks the same), so we adjust for that here.\n rotationX = rotation = 0;\n rotationY = 180 - rotationY;\n }\n\n scaleX = _round(Math.sqrt(a * a + b * b + c * c));\n scaleY = _round(Math.sqrt(a22 * a22 + a32 * a32));\n angle = _atan2(a12, a22);\n skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0;\n perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;\n }\n\n if (cache.svg) {\n //sense if there are CSS transforms applied on an SVG element in which case we must overwrite them when rendering. The transform attribute is more reliable cross-browser, but we can't just remove the CSS ones because they may be applied in a CSS rule somewhere (not just inline).\n t1 = target.getAttribute(\"transform\");\n cache.forceCSS = target.setAttribute(\"transform\", \"\") || !_isNullTransform(_getComputedProperty(target, _transformProp));\n t1 && target.setAttribute(\"transform\", t1);\n }\n }\n\n if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {\n if (invertedScaleX) {\n scaleX *= -1;\n skewX += rotation <= 0 ? 180 : -180;\n rotation += rotation <= 0 ? 180 : -180;\n } else {\n scaleY *= -1;\n skewX += skewX <= 0 ? 180 : -180;\n }\n }\n\n uncache = uncache || cache.uncache;\n cache.x = x - ((cache.xPercent = x && (!uncache && cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px;\n cache.y = y - ((cache.yPercent = y && (!uncache && cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px;\n cache.z = z + px;\n cache.scaleX = _round(scaleX);\n cache.scaleY = _round(scaleY);\n cache.rotation = _round(rotation) + deg;
1\n cache.rotationX = _round(rotationX) + deg;\n cache.rotationY = _round(rotationY) + deg;\n cache.skewX = skewX + deg;\n cache.skewY = skewY + deg;\n cache.transformPerspective = perspective + px;\n\n if (cache.zOrigin = parseFloat(origin.split(\" \")[2]) || !uncache && cache.zOrigin || 0) {\n style[_transformOriginProp] = _firstTwoOnly(origin);\n }\n\n cache.xOffset = cache.yOffset = 0;\n cache.force3D = _config.force3D;\n cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms;\n cache.uncache = 0;\n return cache;\n},\n _firstTwoOnly = function _firstTwoOnly(value) {\n return (value = value.split(\" \"))[0] + \" \" + value[1];\n},\n //for handling transformOrigin values, stripping out the 3rd dimension\n_addPxTranslate = function _addPxTranslate(target, start, value) {\n var unit = getUnit(start);\n return _round(parseFloat(start) + parseFloat(_convertToUnit(target, \"x\", value + \"px\", unit))) + unit;\n},\n _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) {\n cache.z = \"0px\";\n cache.rotationY = cache.rotationX = \"0deg\";\n cache.force3D = 0;\n\n _renderCSSTransforms(ratio, cache);\n},\n _zeroDeg = \"0deg\",\n _zeroPx = \"0px\",\n _endParenthesis = \") \",\n _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) {\n var _ref = cache || this,\n xPercent = _ref.xPercent,\n yPercent = _ref.yPercent,\n x = _ref.x,\n y = _ref.y,\n z = _ref.z,\n rotation = _ref.rotation,\n rotationY = _ref.rotationY,\n rotationX = _ref.rotationX,\n skewX = _ref.skewX,\n skewY = _ref.skewY,\n scaleX = _ref.scaleX,\n scaleY = _ref.scaleY,\n transformPerspective = _ref.transformPerspective,\n force3D = _ref.force3D,\n target = _ref.target,\n zOrigin = _ref.zOrigin,\n transforms = \"\",\n use3D = force3D === \"auto\" && ratio && ratio !== 1 || force3D === true; // Safari has a bug that causes it not to render 3D transform-origin values properly, so we force the z origin to 0, record it in the cache, and then do the math here to offset the translate values accordingly (basically do the 3D transform-origin part manually)\n\n\n if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) {\n var angle = parseFloat(rotationY) * _DEG2RAD,\n a13 = Math.sin(angle),\n a33 = Math.cos(angle),\n cos;\n\n angle = parseFloat(rotationX) * _DEG2RAD;\n cos = Math.cos(angle);\n x = _addPxTranslate(target, x, a13 * cos * -zOrigin);\n y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin);\n z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin);\n }\n\n if (transformPerspective !== _zeroPx) {\n transforms += \"perspective(\" + transformPerspective + _endParenthesis;\n }\n\n if (xPercent || yPercent) {\n transforms += \"translate(\" + xPercent + \"%, \" + yPercent + \"%) \";\n }\n\n if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) {\n transforms += z !== _zeroPx || use3D ? \"translate3d(\" + x + \", \" + y + \", \" + z + \") \" : \"translate(\" + x + \", \" + y + _endParenthesis;\n }\n\n if (rotation !== _zeroDeg) {\n transforms += \"rotate(\" + rotation + _endParenthesis;\n }\n\n if (rotationY !== _zeroDeg) {\n transforms += \"rotateY(\" + rotationY + _endParenthesis;\n }\n\n if (rotationX !== _zeroDeg) {\n transforms += \"rotateX(\" + rotationX + _endParenthesis;\n }\n\n if (skewX !== _zeroDeg || skewY !== _zeroDeg) {\n transforms += \"skew(\" + skewX + \", \" + skewY + _endParenthesis;\n }\n\n if (scaleX !== 1 || scaleY !== 1) {\n transforms += \"scale(\" + scaleX + \", \" + scaleY + _endParenthesis;\n }\n\n target.style[_transformProp] = transforms || \"translate(0, 0)\";\n},\n _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) {\n var _ref2 = cache || this,\n xPercent = _ref2.xPercent,\n yPercent = _ref2.yPercent,\n x = _ref2.x,\n y = _ref2.y,\n rotation = _ref2.rotation,\n skewX = _ref2.skewX,\n skewY = _ref2.skewY,\n scaleX = _ref2.scaleX,\n scaleY = _ref2.scaleY,\n target = _ref2.target,\n xOrigin = _ref2.xOrigin,\n yOrigin = _ref2.yOrigin,\n xOffset = _ref2.xOffset,\n yOffset = _ref2.yOffset,\n forceCSS = _ref2.forceCSS,\n tx = parseFloat(x),\n ty = parseFloat(y),\n a11,\n a21,\n a12,\n a22,\n temp;\n\n rotation = parseFloat(rotation);\n skewX = parseFloat(skewX);\n skewY = parseFloat(skewY);
1\n\n if (skewY) {\n //for performance reasons, we combine all skewing into the skewX and rotation values. Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of 10 degrees.\n skewY = parseFloat(skewY);\n skewX += skewY;\n rotation += skewY;\n }\n\n if (rotation || skewX) {\n rotation *= _DEG2RAD;\n skewX *= _DEG2RAD;\n a11 = Math.cos(rotation) * scaleX;\n a21 = Math.sin(rotation) * scaleX;\n a12 = Math.sin(rotation - skewX) * -scaleY;\n a22 = Math.cos(rotation - skewX) * scaleY;\n\n if (skewX) {\n skewY *= _DEG2RAD;\n temp = Math.tan(skewX - skewY);\n temp = Math.sqrt(1 + temp * temp);\n a12 *= temp;\n a22 *= temp;\n\n if (skewY) {\n temp = Math.tan(skewY);\n temp = Math.sqrt(1 + temp * temp);\n a11 *= temp;\n a21 *= temp;\n }\n }\n\n a11 = _round(a11);\n a21 = _round(a21);\n a12 = _round(a12);\n a22 = _round(a22);\n } else {\n a11 = scaleX;\n a22 = scaleY;\n a21 = a12 = 0;\n }\n\n if (tx && !~(x + \"\").indexOf(\"px\") || ty && !~(y + \"\").indexOf(\"px\")) {\n tx = _convertToUnit(target, \"x\", x, \"px\");\n ty = _convertToUnit(target, \"y\", y, \"px\");\n }\n\n if (xOrigin || yOrigin || xOffset || yOffset) {\n tx = _round(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset);\n ty = _round(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset);\n }\n\n if (xPercent || yPercent) {\n //The SVG spec doesn't support percentage-based translation in the \"transform\" attribute, so we merge it into the translation to simulate it.\n temp = target.getBBox();\n tx = _round(tx + xPercent / 100 * temp.width);\n ty = _round(ty + yPercent / 100 * temp.height);\n }\n\n temp = \"matrix(\" + a11 + \",\" + a21 + \",\" + a12 + \",\" + a22 + \",\" + tx + \",\" + ty + \")\";\n target.setAttribute(\"transform\", temp);\n forceCSS && (target.style[_transformProp] = temp); //some browsers prioritize CSS transforms over the transform attribute. When we sense that the user has CSS transforms applied, we must overwrite them this way (otherwise some browser simply won't render the transform attribute changes!)\n},\n _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) {\n var cap = 360,\n isString = _isString(endValue),\n endNum = parseFloat(endValue) * (isString && ~endValue.indexOf(\"rad\") ? _RAD2DEG : 1),\n change = endNum - startNum,\n finalValue = startNum + change + \"deg\",\n direction,\n pt;\n\n if (isString) {\n direction = endValue.split(\"_\")[1];\n\n if (direction === \"short\") {\n change %= cap;\n\n if (change !== change % (cap / 2)) {\n change += change < 0 ? cap : -cap;\n }\n }\n\n if (direction === \"cw\" && change < 0) {\n change = (change + cap * CSSPlugin_bigNum) % cap - ~~(change / cap) * cap;\n } else if (direction === \"ccw\" && change > 0) {\n change = (change - cap * CSSPlugin_bigNum) % cap - ~~(change / cap) * cap;\n }\n }\n\n plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd);\n pt.e = finalValue;\n pt.u = \"deg\";\n\n plugin._props.push(property);\n\n return pt;\n},\n _assign = function _assign(target, source) {\n // Internet Explorer doesn't have Object.assign(), so we recreate it here.\n for (var p in source) {\n target[p] = source[p];\n }\n\n return target;\n},\n _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) {\n //for handling cases where someone passes in a whole transform string, like transform: \"scale(2, 3) rotate(20deg) translateY(30em)\"\n var startCache = _assign({}, target._gsap),\n exclude = \"perspective,force3D,transformOrigin,svgOrigin\",\n style = target.style,\n endCache,\n p,\n startValue,\n endValue,\n startNum,\n endNum,\n startUnit,\n endUnit;\n\n if (startCache.svg) {\n startValue = target.getAttribute(\"transform\");\n target.setAttribute(\"transform\", \"\");\n style[_transformProp] = transforms;\n endCache = _parseTransform(target, 1);\n\n _removeProperty(target, _transformProp);\n\n target.setAttribute(\"transform\", startValue);\n } else {\n startValue = getComputedStyle(target)[_transformProp];\n style[_transformProp] = transforms;\n endCache = _parseTransform(target, 1);\n style[_transformProp] = startValue;\n }
1\n\n for (p in _transformProps) {\n startValue = startCache[p];\n endValue = endCache[p];\n\n if (startValue !== endValue && exclude.indexOf(p) < 0) {\n //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.\n startUnit = getUnit(startValue);\n endUnit = getUnit(endValue);\n startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue);\n endNum = parseFloat(endValue);\n plugin._pt = new PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp);\n plugin._pt.u = endUnit || 0;\n\n plugin._props.push(p);\n }\n }\n\n _assign(endCache, startCache);\n}; // handle splitting apart padding, margin, borderWidth, and borderRadius into their 4 components. Firefox, for example, won't report borderRadius correctly - it will only do borderTopLeftRadius and the other corners. We also want to handle paddingTop, marginLeft, borderRightWidth, etc.\n\n\n_forEachName(\"padding,margin,Width,Radius\", function (name, index) {\n var t = \"Top\",\n r = \"Right\",\n b = \"Bottom\",\n l = \"Left\",\n props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) {\n return index < 2 ? name + side : \"border\" + side + name;\n });\n\n _specialProps[index > 1 ? \"border\" + name : name] = function (plugin, target, property, endValue, tween) {\n var a, vars;\n\n if (arguments.length < 4) {\n // getter, passed target, property, and unit (from _get())\n a = props.map(function (prop) {\n return _get(plugin, prop, property);\n });\n vars = a.join(\" \");\n return vars.split(a[0]).length === 5 ? a[0] : vars;\n }\n\n a = (endValue + \"\").split(\" \");\n vars = {};\n props.forEach(function (prop, i) {\n return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0];\n });\n plugin.init(target, vars, tween);\n };\n});\n\nvar CSSPlugin = {\n name: \"css\",\n register: _initCore,\n targetTest: function targetTest(target) {\n return target.style && target.nodeType;\n },\n init: function init(target, vars, tween, index, targets) {\n var props = this._props,\n style = target.style,\n startAt = tween.vars.startAt,\n startValue,\n endValue,\n endNum,\n startNum,\n type,\n specialProp,\n p,\n startUnit,\n endUnit,\n relative,\n isTransformRelated,\n transformPropTween,\n cache,\n smooth,\n hasPriority,\n inlineProps;\n _pluginInitted || _initCore(); // we may call init() multiple times on the same plugin instance, like when adding special properties, so make sure we don't overwrite the revert data or inlineProps\n\n this.styles = this.styles || _getStyleSaver(target);\n inlineProps = this.styles.props;\n this.tween = tween;\n\n for (p in vars) {\n if (p === \"autoRound\") {\n continue;\n }\n\n endValue = vars[p];\n\n if (_plugins[p] && _checkPlugin(p, vars, tween, index, target, targets)) {\n // plugins\n continue;\n }\n\n type = typeof endValue;\n specialProp = _specialProps[p];\n\n if (type === \"function\") {\n endValue = endValue.call(tween, index, target, targets);\n type = typeof endValue;\n }\n\n if (type === \"string\" && ~endValue.indexOf(\"random(\")) {\n endValue = _replaceRandom(endValue);\n }\n\n if (specialProp) {\n specialProp(this, target, p, endValue, tween) && (hasPriority = 1);\n } else if (p.substr(0, 2) === \"--\") {\n //CSS variable\n startValue = (getComputedStyle(target).getPropertyValue(p) + \"\").trim();\n endValue += \"\";\n _colorExp.lastIndex = 0;\n\n if (!_colorExp.test(startValue)) {\n // colors don't have units\n startUnit = getUnit(startValue);\n endUnit = getUnit(endValue);\n }\n\n endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit);\n this.add(style, \"setProperty\", startValue, endValue, index, targets, 0, 0, p);\n props.push(p);\n inlineProps.push(p, 0, style[p]);\n } else if (type !== \"undefined\") {\n if (startAt && p in startAt) {\n // in case someone hard-codes a complex value as the start, like top: \"calc(2vh / 2)\". Without this, it'd use the computed value (always in px)\n startValue = typeof startAt[p] === \"function\" ? startAt[p].call(tween, index, target, targets) : startAt[p];\n _isString(startValue) && ~startValue.indexOf(\"random(\") && (startValue = _replaceRandom(startValue));\n getUnit(startValue + \"\") || startValue === \"auto\" || (startValue += _config.units[p] || getUnit(_get(target, p)) || \"\"); // for cases when someone passes in a unitless value like {x: 100}; if we try setting translate(100, 0px) it won't work.\n\n (startValue + \"\").charAt(1) === \"=\" && (startValue = _get(target, p)); // can't work with relative values\n } else {\n startValue = _get(target, p);\n }\n\n startNum = parseFloat(startValue);\n relative = type === \"string\" && endValue.charAt(1) === \"=\" && endValue.substr(0, 2);\n relative && (endValue = endValue.substr(2));\n endNum = parseFloat(endValue);\n\n if (p in _propertyAliases) {\n if (p === \"autoAlpha\") {\n //special case where we control the visibility along with opacity. We still allow the opacity value to pass through and get tweened.\n if (startNum === 1 && _get(target, \"visibility\") === \"hidden\" && endNum) {\n //if visibility is initially set to \"hidden\", we should interpret that as intent to make opacity 0 (a convenience)\n startNum = 0;\n }\n\n inlineProps.push(\"visibility\", 0, style.visibility);\n\n _addNonTweeningPT(this, style, \"visibility\", startNum ? \"inherit\" : \"hidden\", endNum ? \"inherit\" : \"hidden\", !endNum);\n }\n\n if (p !== \"scale\" && p !== \"transform\") {\n p = _propertyAliases[p];\n ~p.indexOf(\",\") && (p = p.split(\",\")[0]);\n }\n }
1\n\n isTransformRelated = p in _transformProps; //--- TRANSFORM-RELATED ---\n\n if (isTransformRelated) {\n this.styles.save(p);\n\n if (!transformPropTween) {\n cache = target._gsap;\n cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform); // if, for example, gsap.set(... {transform:\"translateX(50vw)\"}), the _get() call doesn't parse the transform, thus cache.renderTransform won't be set yet so force the parsing of the transform here.\n\n smooth = vars.smoothOrigin !== false && cache.smooth;\n transformPropTween = this._pt = new PropTween(this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1); //the first time through, create the rendering PropTween so that it runs LAST (in the linked list, we keep adding to the beginning)\n\n transformPropTween.dep = 1; //flag it as dependent so that if things get killed/overwritten and this is the only PropTween left, we can safely kill the whole tween.\n }\n\n if (p === \"scale\") {\n this._pt = new PropTween(this._pt, cache, \"scaleY\", cache.scaleY, (relative ? _parseRelative(cache.scaleY, relative + endNum) : endNum) - cache.scaleY || 0, _renderCSSProp);\n this._pt.u = 0;\n props.push(\"scaleY\", p);\n p += \"X\";\n } else if (p === \"transformOrigin\") {\n inlineProps.push(_transformOriginProp, 0, style[_transformOriginProp]);\n endValue = _convertKeywordsToPercentages(endValue); //in case something like \"left top\" or \"bottom right\" is passed in. Convert to percentages.\n\n if (cache.svg) {\n _applySVGOrigin(target, endValue, 0, smooth, 0, this);\n } else {\n endUnit = parseFloat(endValue.split(\" \")[2]) || 0; //handle the zOrigin separately!\n\n endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, \"zOrigin\", cache.zOrigin, endUnit);\n\n _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue));\n }\n\n continue;\n } else if (p === \"svgOrigin\") {\n _applySVGOrigin(target, endValue, 1, smooth, 0, this);\n\n continue;\n } else if (p in _rotationalProperties) {\n _addRotationalPropTween(this, cache, p, startNum, relative ? _parseRelative(startNum, relative + endValue) : endValue);\n\n continue;\n } else if (p === \"smoothOrigin\") {\n _addNonTweeningPT(this, cache, \"smooth\", cache.smooth, endValue);\n\n continue;\n } else if (p === \"force3D\") {\n cache[p] = endValue;\n continue;\n } else if (p === \"transform\") {\n _addRawTransformPTs(this, endValue, target);\n\n continue;\n }\n } else if (!(p in style)) {\n p = _checkPropPrefix(p) || p;\n }\n\n if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) {\n startUnit = (startValue + \"\").substr((startNum + \"\").length);\n endNum || (endNum = 0); // protect against NaN\n\n endUnit = getUnit(endValue) || (p in _config.units ? _config.units[p] : startUnit);\n startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit));\n this._pt = new PropTween(this._pt, isTransformRelated ? cache : style, p, startNum, (relative ? _parseRelative(startNum, relative + endNum) : endNum) - startNum, !isTransformRelated && (endUnit === \"px\" || p === \"zIndex\") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp);\n this._pt.u = endUnit || 0;\n\n if (startUnit !== endUnit && endUnit !== \"%\") {\n //when the tween goes all the way back to the beginning, we need to revert it to the OLD/ORIGINAL value (with those units). We record that as a \"b\" (beginning) property and point to a render method that handles that. (performance optimization)\n this._pt.b = startValue;\n this._pt.r = _renderCSSPropWithBeginning;\n }\n }
1 else if (!(p in style)) {\n if (p in target) {\n //maybe it's not a style - it could be a property added directly to an element in which case we'll try to animate that.\n this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets);\n } else if (p !== \"parseTransform\") {\n _missingPlugin(p, endValue);\n\n continue;\n }\n } else {\n _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue);\n }\n\n isTransformRelated || (p in style ? inlineProps.push(p, 0, style[p]) : inlineProps.push(p, 1, startValue || target[p]));\n props.push(p);\n }\n }\n\n hasPriority && _sortPropTweensByPriority(this);\n },\n render: function render(ratio, data) {\n if (data.tween._time || !CSSPlugin_reverting()) {\n var pt = data._pt;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n } else {\n data.styles.revert();\n }\n },\n get: _get,\n aliases: _propertyAliases,\n getSetter: function getSetter(target, property, plugin) {\n //returns a setter function that accepts target, property, value and applies it accordingly. Remember, properties like \"x\" aren't as simple as target.style.property = value because they've got to be applied to a proxy object and then merged into a transform string in a renderer.\n var p = _propertyAliases[property];\n p && p.indexOf(\",\") < 0 && (property = p);\n return property in _transformProps && property !== _transformOriginProp && (target._gsap.x || _get(target, \"x\")) ? plugin && _recentSetterPlugin === plugin ? property === \"scale\" ? _setterScale : _setterTransform : (_recentSetterPlugin = plugin || {}) && (property === \"scale\" ? _setterScaleWithRender : _setterTransformWithRender) : target.style && !_isUndefined(target.style[property]) ? _setterCSSStyle : ~property.indexOf(\"-\") ? _setterCSSProp : _getSetter(target, property);\n },\n core: {\n _removeProperty: _removeProperty,\n _getMatrix: _getMatrix\n }\n};\ngsap.utils.checkPrefix = _checkPropPrefix;\ngsap.core.getStyleSaver = _getStyleSaver;\n\n(function (positionAndScale, rotation, others, aliases) {\n var all = _forEachName(positionAndScale + \",\" + rotation + \",\" + others, function (name) {\n _transformProps[name] = 1;\n });\n\n _forEachName(rotation, function (name) {\n _config.units[name] = \"deg\";\n _rotationalProperties[name] = 1;\n });\n\n _propertyAliases[all[13]] = positionAndScale + \",\" + rotation;\n\n _forEachName(aliases, function (name) {\n var split = name.split(\":\");\n _propertyAliases[split[1]] = all[split[0]];\n });\n})(\"x,y,z,scale,scaleX,scaleY,xPercent,yPercent\", \"rotation,rotationX,rotationY,skewX,skewY\", \"transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective\", \"0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY\");\n\n_forEachName(\"x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective\", function (name) {\n _config.units[name] = \"px\";\n});\n\ngsap.registerPlugin(CSSPlugin);\n\n;// CONCATENATED MODULE: ./node_modules/gsap/all.js\n\n\nvar gsapWithCSS = gsap.registerPlugin(CSSPlugin) || gsap,\n // to protect from tree shaking\nTweenMaxWithCSS = gsapWithCSS.core.Tween;\n\n\n\n\n\n\n\n\n\n\n\n\n\n //BONUS EXPORTS\n// export * from \"./DrawSVGPlugin.js\";\n// export * from \"./Physics2DPlugin.js\";\n// export * from \"./PhysicsPropsPlugin.js\";\n// export * from \"./ScrambleTextPlugin.js\";\n// export * from \"./CustomBounce.js\";\n// export * from \"./CustomWiggle.js\";\n// export * from \"./GSDevTools.js\";\n// export * from \"./InertiaPlugin.js\";\n// export * from \"./MorphSVGPlugin.js\";\n// export * from \"./MotionPathHelper.js\";\n// export * from \"./ScrollSmoother.js\";\n// export * from \"./SplitText.js\";\n;// CONCATENATED MODULE: ./node_modules/gsap/Observer.js\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/*!\n * Observer 3.12.5\n * https://gsap.com\n *\n * @license Copyright 2008-2024, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license or for\n * Club GSAP members, the agreement issued with that membership.\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar Observer_gsap,\n Observer_coreInitted,\n Observer_clamp,\n Observer_win,\n Observer_doc,\n _docEl,\n _body,\n _isTouch,\n _pointerType,\n ScrollTrigger,\n _root,\n _normalizer,\n _eventTypes,\n Observer_context,\n _getGSAP = function _getGSAP() {\n return Observer_gsap || typeof window !== \"undefined\" && (Observer_gsap = window.gsap) && Observer_gsap.registerPlugin && Observer_gsap;\n},\n _startup = 1,\n _observers = [],\n _scrollers = [],\n _proxies = [],\n _getTime = Date.now,\n _bridge = function _bridge(name, value) {\n return value;\n},\n _integrate = function _integrate() {\n var core = ScrollTrigger.core,\n data = core.bridge || {}
1,\n scrollers = core._scrollers,\n proxies = core._proxies;\n scrollers.push.apply(scrollers, _scrollers);\n proxies.push.apply(proxies, _proxies);\n _scrollers = scrollers;\n _proxies = proxies;\n\n _bridge = function _bridge(name, value) {\n return data[name](value);\n };\n},\n _getProxyProp = function _getProxyProp(element, property) {\n return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property];\n},\n _isViewport = function _isViewport(el) {\n return !!~_root.indexOf(el);\n},\n _addListener = function _addListener(element, type, func, passive, capture) {\n return element.addEventListener(type, func, {\n passive: passive !== false,\n capture: !!capture\n });\n},\n _removeListener = function _removeListener(element, type, func, capture) {\n return element.removeEventListener(type, func, !!capture);\n},\n _scrollLeft = \"scrollLeft\",\n _scrollTop = \"scrollTop\",\n _onScroll = function _onScroll() {\n return _normalizer && _normalizer.isPressed || _scrollers.cache++;\n},\n _scrollCacheFunc = function _scrollCacheFunc(f, doNotCache) {\n var cachingFunc = function cachingFunc(value) {\n // since reading the scrollTop/scrollLeft/pageOffsetY/pageOffsetX can trigger a layout, this function allows us to cache the value so it only gets read fresh after a \"scroll\" event fires (or while we're refreshing because that can lengthen the page and alter the scroll position). when \"soft\" is true, that means don't actually set the scroll, but cache the new value instead (useful in ScrollSmoother)\n if (value || value === 0) {\n _startup && (Observer_win.history.scrollRestoration = \"manual\"); // otherwise the new position will get overwritten by the browser onload.\n\n var isNormalizing = _normalizer && _normalizer.isPressed;\n value = cachingFunc.v = Math.round(value) || (_normalizer && _normalizer.iOS ? 1 : 0); //TODO: iOS Bug: if you allow it to go to 0, Safari can start to report super strange (wildly inaccurate) touch positions!\n\n f(value);\n cachingFunc.cacheID = _scrollers.cache;\n isNormalizing && _bridge(\"ss\", value); // set scroll (notify ScrollTrigger so it can dispatch a \"scrollStart\" event if necessary\n } else if (doNotCache || _scrollers.cache !== cachingFunc.cacheID || _bridge(\"ref\")) {\n cachingFunc.cacheID = _scrollers.cache;\n cachingFunc.v = f();\n }\n\n return cachingFunc.v + cachingFunc.offset;\n };\n\n cachingFunc.offset = 0;\n return f && cachingFunc;\n},\n _horizontal = {\n s: _scrollLeft,\n p: \"left\",\n p2: \"Left\",\n os: \"right\",\n os2: \"Right\",\n d: \"width\",\n d2: \"Width\",\n a: \"x\",\n sc: _scrollCacheFunc(function (value) {\n return arguments.length ? Observer_win.scrollTo(value, _vertical.sc()) : Observer_win.pageXOffset || Observer_doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0;\n })\n},\n _vertical = {\n s: _scrollTop,\n p: \"top\",\n p2: \"Top\",\n os: \"bottom\",\n os2: \"Bottom\",\n d: \"height\",\n d2: \"Height\",\n a: \"y\",\n op: _horizontal,\n sc: _scrollCacheFunc(function (value) {\n return arguments.length ? Observer_win.scrollTo(_horizontal.sc(), value) : Observer_win.pageYOffset || Observer_doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0;\n })\n},\n _getTarget = function _getTarget(t, self) {\n return (self && self._ctx && self._ctx.selector || Observer_gsap.utils.toArray)(t)[0] || (typeof t === \"string\" && Observer_gsap.config().nullTargetWarn !== false ? console.warn(\"Element not found:\", t) : null);\n},\n _getScrollFunc = function _getScrollFunc(element, _ref) {\n var s = _ref.s,\n sc = _ref.sc;\n // we store the scroller functions in an alternating sequenced Array like [element, verticalScrollFunc, horizontalScrollFunc, ...] so that we can minimize memory, maximize performance, and we also record the last position as a \".rec\" property in order to revert to that after refreshing to ensure things don't shift around.\n _isViewport(element) && (element = Observer_doc.scrollingElement || _docEl);\n\n var i = _scrollers.indexOf(element),\n offset = sc === _vertical.sc ? 1 : 2;\n\n !~i && (i = _scrollers.push(element) - 1);\n _scrollers[i + offset] || _addListener(element, \"scroll\", _onScroll); // clear the cache when a scroll occurs\n\n var prev = _scrollers[i + offset],\n func = prev || (_scrollers[i + offset] = _scrollCacheFunc(_getProxyProp(element, s), true) || (_isViewport(element) ? sc : _scrollCacheFunc(function (value) {\n return arguments.length ? element[s] = value : element[s];\n })));\n func.target = element;\n prev || (func.smooth = Observer_gsap.getProperty(element, \"scrollBehavior\") === \"smooth\"); // only set it the first time (don't reset every time a scrollFunc is requested because perhaps it happens during a refresh() when it's disabled in ScrollTrigger.\n\n return func;\n},\n _getVelocityProp = function _getVelocityProp(value, minTimeRefresh, useDelta) {\n var v1 = value,\n v2 = value,\n t1 = _getTime(),\n t2 = t1,\n min = minTimeRefresh || 50,\n dropToZeroTime = Math.max(500, min * 3),\n update = function update(value, force) {\n var t = _getTime();\n\n if (force || t - t1 > min) {\n v2 = v1;\n v1 = value;\n t2 = t1;\n t1 = t;\n } else if (useDelta) {\n v1 += value;\n } else {\n // not totally necessary, but makes it a bit more accurate by adjusting the v1 value according to the new slope. This way we're not just ignoring the incoming data. Removing for now because it doesn't seem to make much practical difference and it's probably not worth the kb.\n v1 = v2 + (value - v2) / (t - t2) * (t1 - t2);\n }\n },\n reset = function reset() {\n v2 = v1 = useDelta ? 0 : v1;\n t2 = t1 = 0;\n },\n getVelocity = function getVelocity(latestValue) {\n var tOld = t2,\n vOld = v2,\n t = _getTime();\n\n (latestValue || latestValue === 0) && latestValue !== v1 && update(latestValue);\n return t1 === t2 || t - t2 > dropToZeroTime ? 0 : (v1 + (useDelta ? vOld : -vOld)) / ((useDelta ? t : t1) - tOld) * 1000;\n };\n\n return {\n update: update,\n reset: reset,\n getVelocity: getVelocity\n };\n},\n _getEvent = function _getEvent(e, preventDefault) {\n preventDefault && !e._gsapAllow && e.preventDefault();\n return e.changedTouches ? e.changedTouches[0] : e;
1\n},\n _getAbsoluteMax = function _getAbsoluteMax(a) {\n var max = Math.max.apply(Math, a),\n min = Math.min.apply(Math, a);\n return Math.abs(max) >= Math.abs(min) ? max : min;\n},\n _setScrollTrigger = function _setScrollTrigger() {\n ScrollTrigger = Observer_gsap.core.globals().ScrollTrigger;\n ScrollTrigger && ScrollTrigger.core && _integrate();\n},\n Observer_initCore = function _initCore(core) {\n Observer_gsap = core || _getGSAP();\n\n if (!Observer_coreInitted && Observer_gsap && typeof document !== \"undefined\" && document.body) {\n Observer_win = window;\n Observer_doc = document;\n _docEl = Observer_doc.documentElement;\n _body = Observer_doc.body;\n _root = [Observer_win, Observer_doc, _docEl, _body];\n Observer_clamp = Observer_gsap.utils.clamp;\n\n Observer_context = Observer_gsap.core.context || function () {};\n\n _pointerType = \"onpointerenter\" in _body ? \"pointer\" : \"mouse\"; // isTouch is 0 if no touch, 1 if ONLY touch, and 2 if it can accommodate touch but also other types like mouse/pointer.\n\n _isTouch = Observer_Observer.isTouch = Observer_win.matchMedia && Observer_win.matchMedia(\"(hover: none), (pointer: coarse)\").matches ? 1 : \"ontouchstart\" in Observer_win || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ? 2 : 0;\n _eventTypes = Observer_Observer.eventTypes = (\"ontouchstart\" in _docEl ? \"touchstart,touchmove,touchcancel,touchend\" : !(\"onpointerdown\" in _docEl) ? \"mousedown,mousemove,mouseup,mouseup\" : \"pointerdown,pointermove,pointercancel,pointerup\").split(\",\");\n setTimeout(function () {\n return _startup = 0;\n }, 500);\n\n _setScrollTrigger();\n\n Observer_coreInitted = 1;\n }\n\n return Observer_coreInitted;\n};\n\n_horizontal.op = _vertical;\n_scrollers.cache = 0;\nvar Observer_Observer = /*#__PURE__*/function () {\n function Observer(vars) {\n this.init(vars);\n }\n\n var _proto = Observer.prototype;\n\n _proto.init = function init(vars) {\n Observer_coreInitted || Observer_initCore(Observer_gsap) || console.warn(\"Please gsap.registerPlugin(Observer)\");\n ScrollTrigger || _setScrollTrigger();\n var tolerance = vars.tolerance,\n dragMinimum = vars.dragMinimum,\n type = vars.type,\n target = vars.target,\n lineHeight = vars.lineHeight,\n debounce = vars.debounce,\n preventDefault = vars.preventDefault,\n onStop = vars.onStop,\n onStopDelay = vars.onStopDelay,\n ignore = vars.ignore,\n wheelSpeed = vars.wheelSpeed,\n event = vars.event,\n onDragStart = vars.onDragStart,\n onDragEnd = vars.onDragEnd,\n onDrag = vars.onDrag,\n onPress = vars.onPress,\n onRelease = vars.onRelease,\n onRight = vars.onRight,\n onLeft = vars.onLeft,\n onUp = vars.onUp,\n onDown = vars.onDown,\n onChangeX = vars.onChangeX,\n onChangeY = vars.onChangeY,\n onChange = vars.onChange,\n onToggleX = vars.onToggleX,\n onToggleY = vars.onToggleY,\n onHover = vars.onHover,\n onHoverEnd = vars.onHoverEnd,\n onMove = vars.onMove,\n ignoreCheck = vars.ignoreCheck,\n isNormalizer = vars.isNormalizer,\n onGestureStart = vars.onGestureStart,\n onGestureEnd = vars.onGestureEnd,\n onWheel = vars.onWheel,\n onEnable = vars.onEnable,\n onDisable = vars.onDisable,\n onClick = vars.onClick,\n scrollSpeed = vars.scrollSpeed,\n capture = vars.capture,\n allowClicks = vars.allowClicks,\n lockAxis = vars.lockAxis,\n onLockAxis = vars.onLockAxis;\n this.target = target = _getTarget(target) || _docEl;\n this.vars = vars;\n ignore && (ignore = Observer_gsap.utils.toArray(ignore));\n tolerance = tolerance || 1e-9;\n dragMinimum = dragMinimum || 0;\n wheelSpeed = wheelSpeed || 1;\n scrollSpeed = scrollSpeed || 1;\n type = type || \"wheel,touch,pointer\";\n debounce = debounce !== false;\n lineHeight || (lineHeight = parseFloat(Observer_win.getComputedStyle(_body).lineHeight) || 22); // note: browser may report \"normal\", so default to 22.\n\n var id,\n onStopDelayedCall,\n dragged,\n moved,\n wheeled,\n locked,\n axis,\n self = this,\n prevDeltaX = 0,\n prevDeltaY = 0,\n passive = vars.passive || !preventDefault,\n scrollFuncX = _getScrollFunc(target, _horizontal),\n scrollFuncY = _getScrollFunc(target, _vertical),\n scrollX = scrollFuncX(),\n scrollY = scrollFuncY(),\n limitToTouch = ~type.indexOf(\"touch\") && !~type.indexOf(\"pointer\") && _eventTypes[0] === \"pointerdown\",\n // for devices that accommodate mouse events and touch events, we need to distinguish.\n isViewport = _isViewport(target),\n ownerDoc = target.ownerDocument || Observer_doc,\n deltaX = [0, 0, 0],\n // wheel, scroll, pointer/touch\n deltaY = [0, 0, 0],\n onClickTime = 0,\n clickCapture = function clickCapture() {\n return onClickTime = _getTime();\n },\n _ignoreCheck = function _ignoreCheck(e, isPointerOrTouch) {\n return (self.event = e) && ignore && ~ignore.indexOf(e.target) || isPointerOrTouch && limitToTouch && e.pointerType !== \"touch\" || ignoreCheck && ignoreCheck(e, isPointerOrTouch);\n },\n onStopFunc = function onStopFunc() {\n self._vx.reset();\n\n self._vy.reset();\n\n onStopDelayedCall.pause();\n onStop && onStop(self);\n }
1,\n update = function update() {\n var dx = self.deltaX = _getAbsoluteMax(deltaX),\n dy = self.deltaY = _getAbsoluteMax(deltaY),\n changedX = Math.abs(dx) >= tolerance,\n changedY = Math.abs(dy) >= tolerance;\n\n onChange && (changedX || changedY) && onChange(self, dx, dy, deltaX, deltaY); // in ScrollTrigger.normalizeScroll(), we need to know if it was touch/pointer so we need access to the deltaX/deltaY Arrays before we clear them out.\n\n if (changedX) {\n onRight && self.deltaX > 0 && onRight(self);\n onLeft && self.deltaX < 0 && onLeft(self);\n onChangeX && onChangeX(self);\n onToggleX && self.deltaX < 0 !== prevDeltaX < 0 && onToggleX(self);\n prevDeltaX = self.deltaX;\n deltaX[0] = deltaX[1] = deltaX[2] = 0;\n }\n\n if (changedY) {\n onDown && self.deltaY > 0 && onDown(self);\n onUp && self.deltaY < 0 && onUp(self);\n onChangeY && onChangeY(self);\n onToggleY && self.deltaY < 0 !== prevDeltaY < 0 && onToggleY(self);\n prevDeltaY = self.deltaY;\n deltaY[0] = deltaY[1] = deltaY[2] = 0;\n }\n\n if (moved || dragged) {\n onMove && onMove(self);\n\n if (dragged) {\n onDrag(self);\n dragged = false;\n }\n\n moved = false;\n }\n\n locked && !(locked = false) && onLockAxis && onLockAxis(self);\n\n if (wheeled) {\n onWheel(self);\n wheeled = false;\n }\n\n id = 0;\n },\n onDelta = function onDelta(x, y, index) {\n deltaX[index] += x;\n deltaY[index] += y;\n\n self._vx.update(x);\n\n self._vy.update(y);\n\n debounce ? id || (id = requestAnimationFrame(update)) : update();\n },\n onTouchOrPointerDelta = function onTouchOrPointerDelta(x, y) {\n if (lockAxis && !axis) {\n self.axis = axis = Math.abs(x) > Math.abs(y) ? \"x\" : \"y\";\n locked = true;\n }\n\n if (axis !== \"y\") {\n deltaX[2] += x;\n\n self._vx.update(x, true); // update the velocity as frequently as possible instead of in the debounced function so that very quick touch-scrolls (flicks) feel natural. If it's the mouse/touch/pointer, force it so that we get snappy/accurate momentum scroll.\n\n }\n\n if (axis !== \"x\") {\n deltaY[2] += y;\n\n self._vy.update(y, true);\n }\n\n debounce ? id || (id = requestAnimationFrame(update)) : update();\n },\n _onDrag = function _onDrag(e) {\n if (_ignoreCheck(e, 1)) {\n return;\n }\n\n e = _getEvent(e, preventDefault);\n var x = e.clientX,\n y = e.clientY,\n dx = x - self.x,\n dy = y - self.y,\n isDragging = self.isDragging;\n self.x = x;\n self.y = y;\n\n if (isDragging || Math.abs(self.startX - x) >= dragMinimum || Math.abs(self.startY - y) >= dragMinimum) {\n onDrag && (dragged = true);\n isDragging || (self.isDragging = true);\n onTouchOrPointerDelta(dx, dy);\n isDragging || onDragStart && onDragStart(self);\n }\n },\n _onPress = self.onPress = function (e) {\n if (_ignoreCheck(e, 1) || e && e.button) {\n return;\n }\n\n self.axis = axis = null;\n onStopDelayedCall.pause();\n self.isPressed = true;\n e = _getEvent(e); // note: may need to preventDefault(?) Won't side-scroll on iOS Safari if we do, though.\n\n prevDeltaX = prevDeltaY = 0;\n self.startX = self.x = e.clientX;\n self.startY = self.y = e.clientY;\n\n self._vx.reset(); // otherwise the t2 may be stale if the user touches and flicks super fast and releases in less than 2 requestAnimationFrame ticks, causing velocity to be 0.\n\n\n self._vy.reset();\n\n _addListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, passive, true);\n\n self.deltaX = self.deltaY = 0;\n onPress && onPress(self);\n },\n _onRelease = self.onRelease = function (e) {\n if (_ignoreCheck(e, 1)) {\n return;\n }\n\n _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);\n\n var isTrackingDrag = !isNaN(self.y - self.startY),\n wasDragging = self.isDragging,\n isDragNotClick = wasDragging && (Math.abs(self.x - self.startX) > 3 || Math.abs(self.y - self.startY) > 3),\n // some touch devices need some wiggle room in terms of sensing clicks - the finger may move a few pixels.\n eventData = _getEvent(e);\n\n if (!isDragNotClick && isTrackingDrag) {\n self._vx.reset();\n\n self._vy.reset(); //if (preventDefault && allowClicks && self.isPressed) { // check isPressed because in a rare edge case, the inputObserver in ScrollTrigger may stopPropagation() on the press/drag, so the onRelease may get fired without the onPress/onDrag ever getting called, thus it could trigger a click to occur on a link after scroll-dragging it.\n\n\n if (preventDefault && allowClicks) {\n Observer_gsap.delayedCall(0.08, function () {\n // some browsers (like Firefox) won't trust script-generated clicks, so if the user tries to click on a video to play it, for example, it simply won't work. Since a regular \"click\" event will most likely be generated anyway (one that has its isTrusted flag set to true), we must slightly delay our script-generated click so that the \"real\"/trusted one is prioritized. Remember, when there are duplicate events in quick succession, we suppress all but the first one. Some browsers don't even trigger the \"real\" one at all, so our synthetic one is a safety valve that ensures that no matter what, a click event does get dispatched.\n if (_getTime() - onClickTime > 300 && !e.defaultPrevented) {\n if (e.target.click) {\
1n //some browsers (like mobile Safari) don't properly trigger the click event\n e.target.click();\n } else if (ownerDoc.createEvent) {\n var syntheticEvent = ownerDoc.createEvent(\"MouseEvents\");\n syntheticEvent.initMouseEvent(\"click\", true, true, Observer_win, 1, eventData.screenX, eventData.screenY, eventData.clientX, eventData.clientY, false, false, false, false, 0, null);\n e.target.dispatchEvent(syntheticEvent);\n }\n }\n });\n }\n }\n\n self.isDragging = self.isGesturing = self.isPressed = false;\n onStop && wasDragging && !isNormalizer && onStopDelayedCall.restart(true);\n onDragEnd && wasDragging && onDragEnd(self);\n onRelease && onRelease(self, isDragNotClick);\n },\n _onGestureStart = function _onGestureStart(e) {\n return e.touches && e.touches.length > 1 && (self.isGesturing = true) && onGestureStart(e, self.isDragging);\n },\
1n _onGestureEnd = function _onGestureEnd() {\n return (self.isGesturing = false) || onGestureEnd(self);\n },\n onScroll = function onScroll(e) {\n if (_ignoreCheck(e)) {\n return;\n }\n\n var x = scrollFuncX(),\n y = scrollFuncY();\n onDelta((x - scrollX) * scrollSpeed, (y - scrollY) * scrollSpeed, 1);\n scrollX = x;\n scrollY = y;\n onStop && onStopDelayedCall.restart(true);\n },\n _onWheel = function _onWheel(e) {\n if (_ignoreCheck(e)) {\n return;\n }\n\n e = _getEvent(e, preventDefault);\n onWheel && (wheeled = true);\n var multiplier = (e.deltaMode === 1 ? lineHeight : e.deltaMode === 2 ? Observer_win.innerHeight : 1) * wheelSpeed;\n onDelta(e.deltaX * multiplier, e.deltaY * multiplier, 0);\n onStop && !isNormalizer && onStopDelayedCall.restart(true);\n },\n _onMove = function _onMove(e) {\n if (_ignoreCheck(e)) {\n return;\n }\n\n var x = e.clientX,\n y = e.clientY,\n dx = x - self.x,\n dy = y - self.y;\n self.x = x;\n self.y = y;\n moved = true;\n onStop && onStopDelayedCall.restart(true);\n (dx || dy) && onTouchOrPointerDelta(dx, dy);\n },\n _onHover = function _onHover(e) {\n self.event = e;\n onHover(self);\n },\n _onHoverEnd = function _onHoverEnd(e) {\n self.event = e;\n onHoverEnd(self);\n },\n _onClick = function _onClick(e) {\n return _ignoreCheck(e) || _getEvent(e, preventDefault) && onClick(self);\n };\n\n onStopDelayedCall = self._dc = Observer_gsap.delayedCall(onStopDelay || 0.25, onStopFunc).pause();\n self.deltaX = self.deltaY = 0;\n self._vx = _getVelocityProp(0, 50, true);\n self._vy = _getVelocityProp(0, 50, true);\n self.scrollX = scrollFuncX;\n self.scrollY = scrollFuncY;\n self.isDragging = self.isGesturing = self.isPressed = false;\n\n Observer_context(this);\n\n self.enable = function (e) {\n if (!self.isEnabled) {\n _addListener(isViewport ? ownerDoc : target, \"scroll\", _onScroll);\n\n type.indexOf(\"scroll\") >= 0 && _addListener(isViewport ? ownerDoc : target, \"scroll\", onScroll, passive, capture);\n type.indexOf(\"wheel\") >= 0 && _addListener(target, \"wheel\", _onWheel, passive, capture);\n\n if (type.indexOf(\"touch\") >= 0 && _isTouch || type.indexOf(\"pointer\") >= 0) {\n _addListener(target, _eventTypes[0], _onPress, passive, capture);\n\n _addListener(ownerDoc, _eventTypes[2], _onRelease);\n\n _addListener(ownerDoc, _eventTypes[3], _onRelease);\n\n allowClicks && _addListener(target, \"click\", clickCapture, true, true);\n onClick && _addListener(target, \"click\", _onClick);\n onGestureStart && _addListener(ownerDoc, \"gesturestart\", _onGestureStart);\n onGestureEnd && _addListener(ownerDoc, \"gestureend\", _onGestureEnd);\n onHover && _addListener(target, _pointerType + \"enter\", _onHover);\n onHoverEnd && _addListener(target, _pointerType + \"leave\", _onHoverEnd);\n onMove && _addListener(target, _pointerType + \"move\", _onMove);\n }\n\n self.isEnabled = true;\n e && e.type && _onPress(e);\n onEnable && onEnable(self);\n }\n\n return self;\n };\n\n self.disable = function () {\n if (self.isEnabled) {\n // only remove the _onScroll listener if there aren't any others that rely on the functionality.\n _observers.filter(function (o) {\n return o !== self && _isViewport(o.target);\n }).length || _removeListener(isViewport ? ownerDoc : target, \"scroll\", _onScroll);\n\n if (self.isPressed) {\n self._vx.reset();\n\n self._vy.reset();\n\n _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);\n }\n\n _removeListener(isViewport ? ownerDoc : target, \"scroll\", onScroll, capture);\n\n _removeListener(target, \"wheel\", _onWheel, capture);\n\n _removeListener(target, _eventTypes[0], _onPress, capture);\n\n _removeListener(ownerDoc, _eventTypes[2], _onRelease);\n\n _removeListener(ownerDoc, _eventTypes[3], _onRelease);\n\n _removeListener(target, \"click\", clickCapture, true);\n\n _removeListener(target, \"click\", _onClick);\n\n _removeListener(ownerDoc, \"gesturestart\", _onGestureStart);\n\n _removeListener(ownerDoc, \"gestureend\", _onGestureEnd);\n\n _removeListener(target, _pointerType + \"enter\", _onHover);\n\n _removeListener(target, _pointerType + \"leave\", _onHoverEnd);\n\n _removeListener(target, _pointerType + \"move\", _onMove);\n\n self.isEnabled = self.isPressed = self.isDragging = false;\n onDisable && onDisable(self);\n }\n };\n\n self.kill = self.revert = function () {\n self.disable();\n\n var i = _observers.indexOf(self);\n\n i >= 0 && _observers.splice(i, 1);\n _normalizer === self && (_normalizer = 0);\n };\n\n _observers.push(self);\n\n isNormalizer && _isViewport(target) && (_normalizer = self);\n self.enable(event);\n };\n\n _createClass(Observer, [{\n key: \"velocityX\",\n get: function get() {\n return this._vx.getVelocity();\n }\n }, {\n key: \"velocityY\",\n get: function get() {\n return this._vy.getVelocity();\n }\n }]);\n\n return Observer;\n}();\nObserver_Observer.version = \"3.12.5\";\n\nObserver_Observer.create = function (vars) {\n return new Observer_Observer(vars);\n};\n\nObserver_Observer.register = Observer_initCore;\n\nObserver_Observer.getAll = function () {\n return _observers.slice();\n};\n\nObserver_Observer.getById = function (id) {\n return _observers.filter(function (o) {\n return o.vars.id === id;\n })[0];\n};\n\n_getGSAP() && Observer_gsap.registerPlugin(Observer_Observer);\n\n;// CONCATENATED MODULE: ./node_modules/gsap/ScrollTrigger.js\n/*!\n * ScrollTrigger 3.12.5\n * https://gsap.com\n *\n * @license Copyright 2008-2024, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license or for\n * Club GSAP members, the agreement issued with that membership.\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\n\n\nvar ScrollTrigger_gsap,\n ScrollTrigger_coreInitted,\n ScrollTrigger_win,\n ScrollTrigger_doc,\n ScrollTrigger_docEl,\n ScrollTrigger_body,\n ScrollTrigger_root,\n _resizeDelay,\n _toArray,\n ScrollTrigger_clamp,\n _time2,\n _syncInterval,\n _refreshing,\n _pointerIsDown,\n ScrollTrigger_transformProp,\n _i,\n _prevWidth,\n _prevHeight,\n _autoRefresh,\n _sort,\n ScrollTrigger_suppressOverwrites,\n _ignoreResize,\n ScrollTrigger_normalizer,\n _ignoreMobileResize,\n _baseScreenHeight,\n _baseScreenWidth,\n _fixIOSBug,\n ScrollTrigger_context,\n _scrollRestoration,\n _div100vh,\n _100vh,\n _isReverted,\n _clampingMax,\n _limitCallbacks,\n // if true, we'll only trigger callbacks if the active state toggles, so if you scroll immediately past both the start and end positions of a ScrollTrigger (thus inactive to inactive), neither its onEnter nor onLeave will be called. This is useful during startup.\nScrollTrigger_startup = 1,\n ScrollTrigger_getTime = Date.now,\n _time1 = ScrollTrigger_getTime(),\n _lastScrollTime = 0,\n _enabled = 0,\n _parseClamp = function _parseClamp(value, type, self) {\n var clamp = ScrollTrigger_isString(value) && (value.substr(0, 6) === \"clamp(\" || value.indexOf(\"max\") > -1);\n self[\"_\" + type + \"Clamp\"] = clamp;\n return clamp ? value.substr(6, value.length - 7) : value;\n},\n _keepClamp = function _keepClamp(value, clamp) {\n return clamp && (!ScrollTrigger_isString(value) || value.substr(0, 6) !== \"clamp(\") ? \"clamp(\" + value + \")\" : value;\n},\n _rafBugFix = function _rafBugFix() {\n return _enabled && requestAnimationFrame(_rafBugFix);\n},\n // in some browsers (like Firefox), screen repaints weren't consistent unless we had SOMETHING queued up in requestAnimationFrame()! So this just creates a super simple loop to keep it alive and smooth out repaints.\
1n_pointerDownHandler = function _pointerDownHandler() {\n return _pointerIsDown = 1;\n},\n _pointerUpHandler = function _pointerUpHandler() {\n return _pointerIsDown = 0;\n},\n ScrollTrigger_passThrough = function _passThrough(v) {\n return v;\n},\n ScrollTrigger_round = function _round(value) {\n return Math.round(value * 100000) / 100000 || 0;\n},\n ScrollTrigger_windowExists = function _windowExists() {\n return typeof window !== \"undefined\";\n},\n ScrollTrigger_getGSAP = function _getGSAP() {\n return ScrollTrigger_gsap || ScrollTrigger_windowExists() && (ScrollTrigger_gsap = window.gsap) && ScrollTrigger_gsap.registerPlugin && ScrollTrigger_gsap;\n},\n ScrollTrigger_isViewport = function _isViewport(e) {\n return !!~ScrollTrigger_root.indexOf(e);\n},\n _getViewportDimension = function _getViewportDimension(dimensionProperty) {\n return (dimensionProperty === \"Height\" ? _100vh : ScrollTrigger_win[\"inner\" + dimensionProperty]) || ScrollTrigger_docEl[\"client\" + dimensionProperty] || ScrollTrigger_body[\"client\" + dimensionProperty];\n},\n _getBoundsFunc = function _getBoundsFunc(element) {\n return _getProxyProp(element, \"getBoundingClientRect\") || (ScrollTrigger_isViewport(element) ? function () {\n _winOffsets.width = ScrollTrigger_win.innerWidth;\n _winOffsets.height = _100vh;\n return _winOffsets;\n } : function () {\n return _getBounds(element);\n });\n},\n _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref) {\n var d = _ref.d,\n d2 = _ref.d2,\n a = _ref.a;\n return (a = _getProxyProp(scroller, \"getBoundingClientRect\")) ? function () {\n return a()[d];\n } : function () {\n return (isViewport ? _getViewportDimension(d2) : scroller[\"client\" + d2]) || 0;\n };\n},\n _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) {\n return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () {\n return _winOffsets;\n };\n},\n _maxScroll = function _maxScroll(element, _ref2) {\n var s = _ref2.s,\n d2 = _ref2.d2,\n d = _ref2.d,\n a = _ref2.a;\n return Math.max(0, (s = \"scroll\" + d2) && (a = _getProxyProp(element, s)) ? a() - _getBoundsFunc(element)()[d] : ScrollTrigger_isViewport(element) ? (ScrollTrigger_docEl[s] || ScrollTrigger_body[s]) - _getViewportDimension(d2) : element[s] - element[\"offset\" + d2]);\n},\n _iterateAutoRefresh = function _iterateAutoRefresh(func, events) {\n for (var i = 0; i < _autoRefresh.length; i += 3) {\n (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]);\n }\n},\n ScrollTrigger_isString = function _isString(value) {\n return typeof value === \"string\";\n},\n ScrollTrigger_isFunction = function _isFunction(value) {\n return typeof value === \"function\";\n},\n ScrollTrigger_isNumber = function _isNumber(value) {\n return typeof value === \"number\";\n},\n ScrollTrigger_isObject = function _isObject(value) {\n return typeof value === \"object\";\n},\n _endAnimation = function _endAnimation(animation, reversed, pause) {\n return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause();\n},\n ScrollTrigger_callback = function _callback(self, func) {\n if (self.enabled) {\n var result = self._ctx ? self._ctx.add(function () {\n return func(self);\n }) : func(self);\n result && result.totalTime && (self.callbackAnimation = result);\n }\n},\n _abs = Math.abs,\n _left = \"left\",\n _top = \"top\",\n _right = \"right\",\n _bottom = \"bottom\",\n _width = \"width\",\n _height = \"height\",\n _Right = \"Right\",\n _Left = \"Left\",\n _Top = \"Top\",\n _Bottom = \"Bottom\",\n _padding = \"padding\",\n _margin = \"margin\",\n _Width = \"Width\",\n _Height = \"Height\",\n _px = \"px\",\n _getComputedStyle = function _getComputedStyle(element) {\n return ScrollTrigger_win.getComputedStyle(element);\n},\n _makePositionable = function _makePositionable(element) {\n // if the element already has position: absolute or fixed, leave that, otherwise make it position: relative\n var position = _getComputedStyle(element).position;\n\n element.style.position = position === \"absolute\" || position === \"fixed\" ? position : \"relative\";\n},\n ScrollTrigger_setDefaults = function _setDefaults(obj, defaults) {\n for (var p in defaults) {\n p in obj || (obj[p] = defaults[p]);\n }\n\n return obj;\n},\n _getBounds = function _getBounds(element, withoutTransforms) {\n var tween = withoutTransforms && _getComputedStyle(element)[ScrollTrigger_transformProp] !== \"matrix(1, 0, 0, 1, 0, 0)\" && ScrollTrigger_gsap.to(element, {\n x: 0,\n y: 0,\n xPercent: 0,\n yPercent: 0,\n rotation: 0,\n rotationX: 0,\n rotationY: 0,\n scale: 1,\n skewX: 0,\n skewY: 0\n }).progress(1),\n bounds = element.getBoundingClientRect();\n tween && tween.progress(0).kill();\n return bounds;\n},\n _getSize = function _getSize(element, _ref3) {\n var d2 = _ref3.d2;\n return element[\"offset\" + d2] || element[\"client\" + d2] || 0;\n},\n _getLabelRatioArray = function _getLabelRatioArray(timeline) {\n var a = [],\n labels = timeline.labels,\n duration = timeline.duration(),\n p;\n\n for (p in labels) {\n a.push(labels[p] / duration);\n }\n\n return a;\n},\n _getClosestLabel = function _getClosestLabel(animation) {\n return function (value) {\n return ScrollTrigger_gsap.utils.snap(_getLabelRatioArray(animation), value);\n };\n},\n _snapDirectional = function _snapDirectional(snapIncrementOrArray) {\n var snap = ScrollTrigger_gsap.utils.snap(snapIncrementOrArray),\n a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) {\n return a - b;\n });\n return a ? function (value, direction, threshold) {\n if (threshold === void 0) {\n threshold = 1e-3;\n }\n\n var i;\n\n if (!direction) {\n return snap(value);\n }\n\n if (direction > 0) {\n value -= threshold; // to avoid rounding errors. If we're too strict, it might snap forward, then immediately again, and again.\n\n for (i = 0; i < a.length;
1 i++) {\n if (a[i] >= value) {\n return a[i];\n }\n }\n\n return a[i - 1];\n } else {\n i = a.length;\n value += threshold;\n\n while (i--) {\n if (a[i] <= value) {\n return a[i];\n }\n }\n }\n\n return a[0];\n } : function (value, direction, threshold) {\n if (threshold === void 0) {\n threshold = 1e-3;\n }\n\n var snapped = snap(value);\n return !direction || Math.abs(snapped - value) < threshold || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray);\n };\n},\n _getLabelAtDirection = function _getLabelAtDirection(timeline) {\n return function (value, st) {\n return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction);\n };\n},\n _multiListener = function _multiListener(func, element, types, callback) {\n return types.split(\",\").forEach(function (type) {\n return func(element, type, callback);\n });\n},\n ScrollTrigger_addListener = function _addListener(element, type, func, nonPassive, capture) {\n return element.addEventListener(type, func, {\n passive: !nonPassive,\n capture: !!capture\n });\n},\n ScrollTrigger_removeListener = function _removeListener(element, type, func, capture) {\n return element.removeEventListener(type, func, !!capture);\n},\n _wheelListener = function _wheelListener(func, el, scrollFunc) {\n scrollFunc = scrollFunc && scrollFunc.wheelHandler;\n\n if (scrollFunc) {\n func(el, \"wheel\", scrollFunc);\n func(el, \"touchmove\", scrollFunc);\n }\n},\n _markerDefaults = {\n startColor: \"green\",\n endColor: \"red\",\n indent: 0,\n fontSize: \"16px\",\n fontWeight: \"normal\"\n},\n ScrollTrigger_defaults = {\n toggleActions: \"play\",\n anticipatePin: 0\n},\n _keywords = {\n top: 0,\n left: 0,\n center: 0.5,\n bottom: 1,\n right: 1\n},\n _offsetToPx = function _offsetToPx(value, size) {\n if (ScrollTrigger_isString(value)) {\n var eqIndex = value.indexOf(\"=\"),\n relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0;\n\n if (~eqIndex) {\n value.indexOf(\"%\") > eqIndex && (relative *= size / 100);\n value = value.substr(0, eqIndex - 1);\n }\n\n value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf(\"%\") ? parseFloat(value) * size / 100 : parseFloat(value) || 0);\n }\n\n return value;\n},\n _createMarker = function _createMarker(type, name, container, direction, _ref4, offset, matchWidthEl, containerAnimation) {\n var startColor = _ref4.startColor,\n endColor = _ref4.endColor,\n fontSize = _ref4.fontSize,\n indent = _ref4.indent,\n fontWeight = _ref4.fontWeight;\n\n var e = ScrollTrigger_doc.createElement(\"div\"),\n useFixedPosition = ScrollTrigger_isViewport(container) || _getProxyProp(container, \"pinType\") === \"fixed\",\n isScroller = type.indexOf(\"scroller\") !== -1,\n parent = useFixedPosition ? ScrollTrigger_body : container,\n isStart = type.indexOf(\"start\") !== -1,\n color = isStart ? startColor : endColor,\n css = \"border-color:\" + color + \";font-size:\" + fontSize + \";color:\" + color + \";font-weight:\" + fontWeight + \";pointer-events:none;white-space:nowrap;font-family:sans-serif,Arial;z-index:1000;padding:4px 8px;border-width:0;border-style:solid;\";\n\n css += \"position:\" + ((isScroller || containerAnimation) && useFixedPosition ? \"fixed;\" : \"absolute;\");\n (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + \":\" + (offset + parseFloat(indent)) + \"px;\");\n matchWidthEl && (css += \"box-sizing:border-box;text-align:left;width:\" + matchWidthEl.offsetWidth + \"px;\");\n e._isStart = isStart;\n e.setAttribute(\"class\", \"gsap-marker-\" + type + (name ? \" marker-\" + name : \"\"));\n e.style.cssText = css;\n e.innerText = name || name === 0 ? type + \"-\" + name : type;\n parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e);\n e._offset = e[\"offset\" + direction.op.d2];\n\n _positionMarker(e, 0, direction, isStart);\n\n return e;\n},\n _positionMarker = function _positionMarker(marker, start, direction, flipped) {\n var vars = {\n display: \"block\"\n },\n side = direction[flipped ? \"os2\" : \"p2\"],\n oppositeSide = direction[flipped ? \"p2\" : \"os2\"];\n marker._isFlipped = flipped;\n vars[direction.a + \"Percent\"] = flipped ? -100 : 0;\n vars[direction.a] = flipped ? \"1px\" : 0;\n vars[\"border\" + side + _Width] = 1;\n vars[\"border\" + oppositeSide + _Width] = 0;\n vars[direction.p] = start + \"px\";\n ScrollTrigger_gsap.set(marker, vars);\n},\n _triggers = [],\n _ids = {},\n _rafID,\n _sync = function _sync() {\n return ScrollTrigger_getTime() - _lastScrollTime > 34 && (_rafID || (_rafID = requestAnimationFrame(_updateAll)));\n},\n ScrollTrigger_onScroll = function _onScroll() {\n // previously, we tried to optimize performance by batching/deferring to the next requestAnimationFrame(), but discovered that Safari has a few bugs that make this unworkable (especially on iOS). See https://codepen.io/GreenSock/pen/16c435b12ef09c38125204818e7b45fc?editors=0010 and https://codepen.io/GreenSock/pen/JjOxYpQ/3dd65ccec5a60f1d862c355d84d14562?editors=0010 and https://codepen.io/GreenSock/pen/ExbrPNa/087cef197dc35445a0951e8935c41503?editors=0010\n if (!ScrollTrigger_normalizer || !ScrollTrigger_normalizer.isPressed || ScrollTrigger_normalizer.startX > ScrollTrigger_body.clientWidth) {\n // if the user is dragging the scrollbar, allow it.\n _scrollers.cache++;\n\n if (ScrollTrigger_normalizer) {\n _rafID || (_rafID = requestAnimationFrame(_updateAll));\n } else {\n _updateAll(); // Safari in particular (on desktop) NEEDS the immediate update rather than waiting for a requestAnimationFrame() whereas iOS seems to benefit from waiting for the requestAnimationFrame() tick, at least when normalizing. See https://codepen.io/GreenSock/pen/qBYozqO?editors=0110\n\n }\n\n _lastScrollTime || ScrollTrigger_dispatch(\"scrollStart\");\n _lastScrollTime = ScrollTrigger_getTime();\n }\n},\n _setBaseDimensions = function _setBaseDimensions() {\n _baseScreenWidth = ScrollTrigger_win.innerWidth;\n _baseScreenHeight = ScrollTrigger_win.innerHeight;\n},\n _onResize = function _onResize() {\n _scrollers.cache++;\n !_refreshing && !_ignoreResize && !ScrollTrigger_doc.fullscreenElement && !ScrollTrigger_doc.webkitFullscreenElement && (!_ignoreMobileResize || _baseScreenWidth !== ScrollTrigger_win.innerWidth || Math.abs(ScrollTrigger_win.innerHeight - _baseScreenHeight) > ScrollTrigger_win.innerHeight * 0.25) && _resizeDelay.restart(true);\n},\n // ignore resizes triggered by refresh()\nScrollTrigger_listeners = {},\n ScrollTrigger_emptyArray = [],\n _softRefresh = function _softRefresh() {\n return ScrollTrigger_removeListener(ScrollTrigger_ScrollTrigger, \"scrollEnd\", _softRefresh) || _refreshAll(true);\n},\n ScrollTrigger_dispatch = function _dispatch(type) {\n return ScrollTrigger_listeners[type] && ScrollTrigger_listeners[type].map(function (f) {\n return f();\n }) || ScrollTrigger_emptyArray;\n},\n _savedStyles = [],\n // when ScrollTrigger.saveStyles() is called, the inline styles are recorded in this Array in a sequential format like [element, cssText, gsCache, media]. This keeps it very memory-efficient and fast to iterate through.\n_revertRecorded = function _revertRecorded(media) {\n for (var i = 0; i < _savedStyles.length; i += 5) {\n if (!media || _savedStyles[i + 4] && _savedStyles[i + 4].query === media) {\n _savedStyles[i].style.cssText = _savedStyles[i + 1];\n _savedStyles[i].getBBox && _savedStyles[i].setAttribute(\"transform\", _savedStyles[i + 2] || \"\");\n _savedStyles[i + 3].uncache = 1;\n }\n }\n},\n _revertAll = function _revertAll(kill, media) {\n var trigger;\n\n for (_i = 0; _i < _triggers.length;
1 _i++) {\n trigger = _triggers[_i];\n\n if (trigger && (!media || trigger._ctx === media)) {\n if (kill) {\n trigger.kill(1);\n } else {\n trigger.revert(true, true);\n }\n }\n }\n\n _isReverted = true;\n media && _revertRecorded(media);\n media || ScrollTrigger_dispatch(\"revert\");\n},\n _clearScrollMemory = function _clearScrollMemory(scrollRestoration, force) {\n // zero-out all the recorded scroll positions. Don't use _triggers because if, for example, .matchMedia() is used to create some ScrollTriggers and then the user resizes and it removes ALL ScrollTriggers, and then go back to a size where there are ScrollTriggers, it would have kept the position(s) saved from the initial state.\n _scrollers.cache++;\n (force || !_refreshingAll) && _scrollers.forEach(function (obj) {\n return ScrollTrigger_isFunction(obj) && obj.cacheID++ && (obj.rec = 0);\n });\n ScrollTrigger_isString(scrollRestoration) && (ScrollTrigger_win.history.scrollRestoration = _scrollRestoration = scrollRestoration);\n},\n _refreshingAll,\n _refreshID = 0,\n _queueRefreshID,\n _queueRefreshAll = function _queueRefreshAll() {\n // we don't want to call _refreshAll() every time we create a new ScrollTrigger (for performance reasons) - it's better to batch them. Some frameworks dynamically load content and we can't rely on the window's \"load\" or \"DOMContentLoaded\" events to trigger it.\n if (_queueRefreshID !== _refreshID) {\n var id = _queueRefreshID = _refreshID;\n requestAnimationFrame(function () {\n return id === _refreshID && _refreshAll(true);\n });\n }\n},\n _refresh100vh = function _refresh100vh() {\n ScrollTrigger_body.appendChild(_div100vh);\n\n _100vh = !ScrollTrigger_normalizer && _div100vh.offsetHeight || ScrollTrigger_win.innerHeight;\n\n ScrollTrigger_body.removeChild(_div100vh);\n},\n _hideAllMarkers = function _hideAllMarkers(hide) {\n return _toArray(\".gsap-marker-start, .gsap-marker-end, .gsap-marker-scroller-start, .gsap-marker-scroller-end\").forEach(function (el) {\n return el.style.display = hide ? \"none\" : \"block\";\n });\n},\n _refreshAll = function _refreshAll(force, skipRevert) {\n if (_lastScrollTime && !force && !_isReverted) {\n ScrollTrigger_addListener(ScrollTrigger_ScrollTrigger, \"scrollEnd\", _softRefresh);\n\n return;\n }\n\n _refresh100vh();\n\n _refreshingAll = ScrollTrigger_ScrollTrigger.isRefreshing = true;\n\n _scrollers.forEach(function (obj) {\n return ScrollTrigger_isFunction(obj) && ++obj.cacheID && (obj.rec = obj());\n }); // force the clearing of the cache because some browsers take a little while to dispatch the \"scroll\" event and the user may have changed the scroll position and then called ScrollTrigger.refresh() right away\n\n\n var refreshInits = ScrollTrigger_dispatch(\"refreshInit\");\n\n _sort && ScrollTrigger_ScrollTrigger.sort();\n skipRevert || _revertAll();\n\n _scrollers.forEach(function (obj) {\n if (ScrollTrigger_isFunction(obj)) {\n obj.smooth && (obj.target.style.scrollBehavior = \"auto\"); // smooth scrolling interferes\n\n obj(0);\n }\n });\n\n _triggers.slice(0).forEach(function (t) {\n return t.refresh();\n }); // don't loop with _i because during a refresh() someone could call ScrollTrigger.update(
1) which would iterate through _i resulting in a skip.\n\n\n _isReverted = false;\n\n _triggers.forEach(function (t) {\n // nested pins (pinnedContainer) with pinSpacing may expand the container, so we must accommodate that here.\n if (t._subPinOffset && t.pin) {\n var prop = t.vars.horizontal ? \"offsetWidth\" : \"offsetHeight\",\n original = t.pin[prop];\n t.revert(true, 1);\n t.adjustPinSpacing(t.pin[prop] - original);\n t.refresh();\n }\n });\n\n _clampingMax = 1; // pinSpacing might be propping a page open, thus when we .setPositions() to clamp a ScrollTrigger's end we should leave the pinSpacing alone. That's what this flag is for.\n\n _hideAllMarkers(true);\n\n _triggers.forEach(function (t) {\n // the scroller's max scroll position may change after all the ScrollTriggers refreshed (like pinning could push it down), so we need to loop back and correct any with end: \"max\". Same for anything with a clamped end\n var max = _maxScroll(t.scroller, t._dir),\n endClamp = t.vars.end === \"max\" || t._endClamp && t.end > max,\n startClamp = t._startClamp && t.start >= max;\n\n (endClamp || startClamp) && t.setPositions(startClamp ? max - 1 : t.start, endClamp ? Math.max(startClamp ? max : t.start + 1, max) : t.end, true);\n });\n\n _hideAllMarkers(false);\n\n _clampingMax = 0;\n refreshInits.forEach(function (result) {\n return result && result.render && result.render(-1);\n }); // if the onRefreshInit() returns an animation (typically a gsap.set()), revert it. This makes it easy to put things in a certain spot before refreshing for measurement purposes, and then put things back.\n\n _scrollers.forEach(function (obj) {\n if (ScrollTrigger_isFunction(obj)) {\n obj.smooth && requestAnimationFrame(function () {\n return obj.target.style.scrollBehavior = \"smooth\";\n });\n obj.rec && obj(obj.rec);\n }\n });\n\n _clearScrollMemory(_scrollRestoration, 1);\n\n _resizeDelay.pause();\n\n _refreshID++;\n _refreshingAll = 2;\n\n _updateAll(2);\n\n _triggers.forEach(function (t) {\n return ScrollTrigger_isFunction(t.vars.onRefresh) && t.vars.onRefresh(t);\n });\n\n _refreshingAll = ScrollTrigger_ScrollTrigger.isRefreshing = false;\n\n ScrollTrigger_dispatch(\"refresh\");\n},\n _lastScroll = 0,\n _direction = 1,\n _primary,\n _updateAll = function _updateAll(force) {\n if (force === 2 || !_refreshingAll && !_isReverted) {\n // _isReverted could be true if, for example, a matchMedia() is in the process of executing. We don't want to update during the time everything is reverted.\n ScrollTrigger_ScrollTrigger.isUpdating = true;\n _primary && _primary.update(0); // ScrollSmoother uses refreshPriority -9999 to become the primary that gets updated before all others because it affects the scroll position.\n\n var l = _triggers.length,\n time = ScrollTrigger_getTime(),\n recordVelocity = time - _time1 >= 50,\n scroll = l && _triggers[0].scroll();\n\n _direction = _lastScroll > scroll ? -1 : 1;\n _refreshingAll || (_lastScroll = scroll);\n\n if (recordVelocity) {\n if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) {\n _lastScrollTime = 0;\n\n ScrollTrigger_dispatch(\"scrollEnd\");\n }\n\n _time2 = _time1;\n _time1 = time;\n }\n\n if (_direction < 0) {\n _i = l;\n\n while (_i-- > 0) {\n _triggers[_i] && _triggers[_i].update(0, recordVelocity);\n }\n\n _direction = 1;\n } else {\n for (_i = 0; _i < l; _i++) {\n _triggers[_i] && _triggers[_i].update(0, recordVelocity);\n }\n }\n\n ScrollTrigger_ScrollTrigger.isUpdating = false;\n }\n\n _rafID = 0;\n},\n _propNamesToCopy = [_left, _top, _bottom, _right, _margin + _Bottom, _margin + _Right, _margin + _Top, _margin + _Left, \"display\", \"flexShrink\", \"float\", \"zIndex\", \"gridColumnStart\", \"gridColumnEnd\", \"gridRowStart\", \"gridRowEnd\", \"gridArea\", \"justifySelf\", \"alignSelf\", \"placeSelf\", \"order\"],\n _stateProps = _propNamesToCopy.concat([_width, _height, \"boxSizing\", \"max\" + _Width, \"max\" + _Height, \"position\", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]),\n _swapPinOut = function _swapPinOut(pin, spacer, state) {\n _setState(state);\n\n var cache = pin._gsap;\n\n if (cache.spacerIsNative) {\n _setState(cache.spacerState);\n } else if (pin._gsap.swappedIn) {\n var parent = spacer.parentNode;\n\n if (parent) {\n parent.insertBefore(pin, spacer);\n parent.removeChild(spacer);\n }\n }\n\n pin._gsap.swappedIn = false;\n},\n _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) {\n if (!pin._gsap.swappedIn) {\n var i = _propNamesToCopy.length,\n spacerStyle = spacer.style,\n pinStyle = pin.style,\n p;\n\n while (i--) {\n p = _propNamesToCopy[i];\n spacerStyle[p] = cs[p];\n }\n\n spacerStyle.position = cs.position === \"absolute\" ? \"absolute\" : \"relative\";\n cs.display === \"inline\" && (spacerStyle.display = \"inline-block\");\n pinStyle[_bottom] = pinStyle[_right] = \"auto\";\n spacerStyle.flexBasis = cs.flexBasis || \"auto\";\n spacerStyle.overflow = \"visible\";\n spacerStyle.boxSizing = \"border-box\";\n spacerStyle[_width] = _getSize(pin, _horizontal) + _px;\n spacerStyle[_height] = _getSize(pin, _vertical) + _px;\n spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = \"0\";\n\n _setState(spacerState);\n\n pinStyle[_width] = pinStyle[\"max\" + _Width] = cs[_width];\n pinStyle[_height] = pinStyle[\"max\" + _Height] = cs[_height];\n pinStyle[_padding] = cs[_padding];\n\n if (pin.parentNode !== spacer) {\n pin.parentNode.insertBefore(spacer, pin);\n spacer.appendChild(pin);\n }\n\n pin._gsap.swappedIn = true;\n }\n},\n ScrollTrigger_capsExp = /([A-Z])/g,\n _setState = function _setState(state) {\n if (state) {\n var style = state.t.style,\n l = state.length,\n i = 0,\n p,\n value;\n (state.t._gsap || ScrollTrigger_gsap.core.getCache(state.t)).uncache = 1; // otherwise transforms may be off\n\n for (; i < l; i += 2) {\n value = state[i + 1];\n p = state[i];\n\n if (value) {\n style[p] = value;\n } else if (style[p]) {\n style.removeProperty(p.replace(ScrollTrigger_capsExp, \"-$1\").toLowerCase());\n }\n }\n }\n},\n _getState = function _getState(element) {\n // returns an Array with alternating values like [property, value, property, value] and a \"t\" property pointing to the target (element). Makes it fast and cheap.\n var l = _stateProps.length,\n style = element.style,\n state = [],\n i = 0;\n\n for (; i < l;
1 i++) {\n state.push(_stateProps[i], style[_stateProps[i]]);\n }\n\n state.t = element;\n return state;\n},\n _copyState = function _copyState(state, override, omitOffsets) {\n var result = [],\n l = state.length,\n i = omitOffsets ? 8 : 0,\n // skip top, left, right, bottom if omitOffsets is true\n p;\n\n for (; i < l; i += 2) {\n p = state[i];\n result.push(p, p in override ? override[p] : state[i + 1]);\n }\n\n result.t = state.t;\n return result;\n},\n _winOffsets = {\n left: 0,\n top: 0\n},\n // // potential future feature (?) Allow users to calculate where a trigger hits (scroll position) like getScrollPosition(\"#id\", \"top bottom\")\n// _getScrollPosition = (trigger, position, {scroller, containerAnimation, horizontal}) => {\n// \tscroller = _getTarget(scroller || _win);\n// \tlet direction = horizontal ? _horizontal : _vertical,\n// \t\tisViewport = _isViewport(scroller);\n// \t_getSizeFunc(scroller, isViewport, direction);\n// \treturn _parsePosition(position, _getTarget(trigger), _getSizeFunc(scroller, isViewport, direction)(), direction, _getScrollFunc(scroller, direction)(), 0, 0, 0, _getOffsetsFunc(scroller, isViewport)(), isViewport ? 0 : parseFloat(_getComputedStyle(scroller)[\"border\" + direction.p2 + _Width]) || 0, 0, containerAnimation ? containerAnimation.duration() : _maxScroll(scroller), containerAnimation);\n// },\nScrollTrigger_parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation, clampZeroProp) {\n ScrollTrigger_isFunction(value) && (value = value(self));\n\n if (ScrollTrigger_isString(value) && value.substr(0, 3) === \"max\") {\n value = scrollerMax + (value.charAt(4) === \"=\" ? _offsetToPx(\"0\" + value.substr(3), scrollerSize) : 0);\n }\n\n var time = containerAnimation ? containerAnimation.time() : 0,\n p1,\n p2,\n element;\n containerAnimation && containerAnimation.seek(0);\n isNaN(value) || (value = +value); // convert a string number like \"45\" to an actual number\n\n if (!ScrollTrigger_isNumber(value)) {\n ScrollTrigger_isFunction(trigger) && (trigger = trigger(self));\n var offsets = (value || \"0\").split(\" \"),\n bounds,\n localOffset,\n globalOffset,\n display;\n element = _getTarget(trigger, self) || ScrollTrigger_body;\n bounds = _getBounds(element) || {};\n\n if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === \"none\") {\n // if display is \"none\", it won't report getBoundingClientRect() properly\n display = element.style.display;\n element.style.display = \"block\";\n bounds = _getBounds(element);\n display ? element.style.display = display : element.style.removeProperty(\"display\");\n }\n\n localOffset = _offsetToPx(offsets[0], bounds[direction.d]);\n globalOffset = _offsetToPx(offsets[1] || \"0\", scrollerSize);\n value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset;\n markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20);\n scrollerSize -= scrollerSize - globalOffset; // adjust for the marker\n } else {\n containerAnimation && (value = ScrollTrigger_gsap.utils.mapRange(containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, 0, scrollerMax, value));\n markerScroller && _positionMarker(markerScroller, scrollerSize, direction, true);\n }\n\n if (clampZeroProp) {\n self[clampZeroProp] = value || -0.001;\n value < 0 && (value = 0);\n }\n\n if (marker) {\n var position = value + scrollerSize,\n isStart = marker._isStart;\n p1 = \"scroll\" + direction.d2;\n\n _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(ScrollTrigger_body[p1], ScrollTrigger_docEl[p1]) : marker.parentNode[p1]) <= position + 1);\n\n if (useFixedPosition) {\n scrollerBounds = _getBounds(marker
1Scroller);\n useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px);\n }\n }\n\n if (containerAnimation && element) {\n p1 = _getBounds(element);\n containerAnimation.seek(scrollerMax);\n p2 = _getBounds(element);\n containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p];\n value = value / containerAnimation._caScrollDist * scrollerMax;\n }\n\n containerAnimation && containerAnimation.seek(time);\n return containerAnimation ? value : Math.round(value);\n},\n _prefixExp = /(webkit|moz|length|cssText|inset)/i,\n _reparent = function _reparent(element, parent, top, left) {\n if (element.parentNode !== parent) {\n var style = element.style,\n p,\n cs;\n\n if (parent === ScrollTrigger_body) {\n element._stOrig = style.cssText; // record original inline styles so we can revert them later\n\n cs = _getComputedStyle(element);\n\n for (p in cs) {\n // must copy all relevant styles to ensure that nothing changes visually when we reparent to the <body>. Skip the vendor prefixed ones.\n if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === \"string\" && p !== \"0\") {\n style[p] = cs[p];\n }\n }\n\n style.top = top;\n style.left = left;\n } else {\n style.cssText = element._stOrig;\n }\n\n ScrollTrigger_gsap.core.getCache(element).uncache = 1;\n parent.appendChild(element);\n }\n},\n _interruptionTracker = function _interruptionTracker(getValueFunc, initialValue, onInterrupt) {\n var last1 = initialValue,\n last2 = last1;\n return function (value) {\n var current = Math.round(getValueFunc()); // round because in some [very uncommon] Windows environments, scroll can get reported with decimals even though it was set without.\n\n if (current !== last1 && current !== last2 && Math.abs(current - last1) > 3 && Math.abs(current - last2) > 3) {\n // if the user scrolls, kill the tween. iOS Safari intermittently misreports the scroll position, it may be the most recently-set one or the one before that! When Safari is zoomed (CMD-+), it often misreports as 1 pixel off too! So if we set the scroll position to 125, for example, it'll actually report it as 124.\n value = current;\n onInterrupt && onInterrupt();\n }\n\n last2 = last1;\n last1 = value;\n return value;\n };\n},\n _shiftMarker = function _shiftMarker(marker, direction, value) {\n var vars = {};\n vars[direction.p] = \"+=\" + value;\n ScrollTrigger_gsap.set(marker, vars);\n},\n // _mergeAnimations = animations => {\n// \tlet tl = gsap.timeline({smoothChildTiming: true}).startTime(Math.min(...animations.map(a => a.globalTime(0))));\n// \tanimations.forEach(a => {let time = a.totalTime(); tl.add(a); a.totalTime(time); });\n// \ttl.smoothChildTiming = false;\n// \treturn tl;\n// },\n// returns a function that can be used to tween the scroll position in the direction provided, and when doing so it'll add a .tween property to the FUNCTION itself, and remove it when the tween completes or gets killed. This gives us a way to have multiple ScrollTriggers use a central function for any given scroller and see if there's a scroll tween running (which would affect if/how things get updated)\n_getTweenCreator = function _getTweenCreator(scroller, direction) {\n var getScroll = _getScrollFunc(scroller, direction),\n prop = \"_scroll\" + direction.p2,\n // add a tweenable property to the scroller that's a getter/setter function, like _scrollTop or _scrollLeft. This way, if someone does gsap.killTweensOf(scroller) it'll
1kill the scroll tween.\n getTween = function getTween(scrollTo, vars, initialValue, change1, change2) {\n var tween = getTween.tween,\n onComplete = vars.onComplete,\n modifiers = {};\n initialValue = initialValue || getScroll();\n\n var checkForInterruption = _interruptionTracker(getScroll, initialValue, function () {\n tween.kill();\n getTween.tween = 0;\n });\n\n change2 = change1 && change2 || 0; // if change1 is 0, we set that to the difference and ignore change2. Otherwise, there would be a compound effect.\n\n change1 = change1 || scrollTo - initialValue;\n tween && tween.kill();\n vars[prop] = scrollTo;\n vars.inherit = false;\n vars.modifiers = modifiers;\n\n modifiers[prop] = function () {\n return checkForInterruption(initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio);\n };\n\n vars.onUpdate = function () {\n _scrollers.cache++;\n getTween.tween && _updateAll(); // if it was interrupted/killed, like in a context.revert(), don't force an updateAll()\n };\n\n vars.onComplete = function () {\n getTween.tween = 0;\n onComplete && onComplete.call(tween);\n };\n\n tween = getTween.tween = ScrollTrigger_gsap.to(scroller, vars);\n return tween;\n };\n\n scroller[prop] = getScroll;\n\n getScroll.wheelHandler = function () {\n return getTween.tween && getTween.tween.kill() && (getTween.tween = 0);\n };\n\n ScrollTrigger_addListener(scroller, \"wheel\", getScroll.wheelHandler); // Windows machines handle mousewheel scrolling in chunks (like \"3 lines per scroll\") meaning the typical strategy for cancelling the scroll isn't as sensitive. It's much more likely to match one of the previous 2 scroll event positions. So we kill any snapping as soon as there's a wheel event.\n\n\n ScrollTrigger_ScrollTrigger.isTouch && ScrollTrigger_addListener(scroller, \"touchmove\", getScroll.wheelHandler);\n return getTween;\n};\n\nvar ScrollTrigger_ScrollTrigger = /*#__PURE__*/function () {\n function ScrollTrigger(vars, animation) {\n ScrollTrigger_coreInitted || ScrollTrigger.register(ScrollTrigger_gsap) || console.warn(\"Please gsap.registerPlugin(ScrollTrigger)\");\n\n ScrollTrigger_context(this);\n\n this.init(vars, animation);\n }\n\n var _proto = ScrollTrigger.prototype;\n\n _proto.init = function init(vars, animation) {\n this.progress = this.start = 0;\n this.vars && this.kill(true, true); // in case it's being initted again\n\n if (!_enabled) {\n this.update = this.refresh = this.kill = ScrollTrigger_passThrough;\n return;\n }\n\n vars = ScrollTrigger_setDefaults(ScrollTrigger_isString(vars) || ScrollTrigger_isNumber(vars) || vars.nodeType ? {\n trigger: vars\n } : vars, ScrollTrigger_defaults);\n\n var _vars = vars,\n onUpdate = _vars.onUpdate,\n toggleClass = _vars.toggleClass,\n id = _vars.id,\n onToggle = _vars.onToggle,\n onRefresh = _vars.onRefresh,\n scrub = _vars.scrub,\n trigger = _vars.trigger,\n pin = _vars.pin,\n pinSpacing = _vars.pinSpacing,\n invalidateOnRefresh = _vars.invalidateOnRefresh,\n anticipatePin = _vars.anticipatePin,\n onScrubComplete = _vars.onScrubComplete,\n onSnapComplete = _vars.onSnapComplete,\n once = _vars.once,\n snap = _vars.snap,\n pinReparent = _vars.pinReparent,\n pinSpacer = _vars.pinSpacer,\n containerAnimation = _vars.containerAnimation,\n fastScrollEnd = _vars.fastScrollEnd,\n preventOverlaps = _vars.preventOverlaps,\n direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical,\n isToggle = !scrub && scrub !== 0,\n scroller = _getTarget(vars.scroller || ScrollTrigger_win),\n scrollerCache = ScrollTrigger_gsap.core.getCache(scroller),\n isViewport = ScrollTrigger_isViewport(scroller),\n useFixedPosition = (\"pinType\" in vars ? vars.pinType : _getProxyProp(scroller, \"pinType\") || isViewport && \"fixed\") === \"fixed\",\n callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack],\n toggleActions = isToggle && vars.toggleActions.split(\" \"),\n markers = \"markers\" in vars ? vars.markers : ScrollTrigger_defaults.markers,\n borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)[\"border\" + direction.p2 + _Width]) || 0,\n self = this,\n onRefreshInit = vars.onRefreshInit && function () {\n return vars.onRefreshInit(self);\n }
1,\n getScrollerSize = _getSizeFunc(scroller, isViewport, direction),\n getScrollerOffsets = _getOffsetsFunc(scroller, isViewport),\n lastSnap = 0,\n lastRefresh = 0,\n prevProgress = 0,\n scrollFunc = _getScrollFunc(scroller, direction),\n tweenTo,\n pinCache,\n snapFunc,\n scroll1,\n scroll2,\n start,\n end,\n markerStart,\n markerEnd,\n markerStartTrigger,\n markerEndTrigger,\n markerVars,\n executingOnRefresh,\n change,\n pinOriginalState,\n pinActiveState,\n pinState,\n spacer,\n offset,\n pinGetter,\n pinSetter,\n pinStart,\n pinChange,\n spacingStart,\n spacerState,\n markerStartSetter,\n pinMoves,\n markerEndSetter,\n cs,\n snap1,\n snap2,\n scrubTween,\n scrubSmooth,\n snapDurClamp,\n snapDelayedCall,\n prevScroll,\n prevAnimProgress,\n caMarkerSetter,\n customRevertReturn; // for the sake of efficiency, _startClamp/_endClamp serve like a truthy value indicating that clamping was enabled on the start/end, and ALSO store the actual pre-clamped numeric value. We tap into that in ScrollSmoother for speed effects. So for example, if start=\"clamp(top bottom)\" results in a start of -100 naturally, it would get clamped to 0 but -100 would be stored in _startClamp.\n\n\n self._startClamp = self._endClamp = false;\n self._dir = direction;\n anticipatePin *= 45;\n self.scroller = scroller;\n self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc;\n scroll1 = scrollFunc();\n self.vars = vars;\n animation = animation || vars.animation;\n\n if (\"refreshPriority\" in vars) {\n _sort = 1;\n vars.refreshPriority === -9999 && (_primary = self); // used by ScrollSmoother\n }\n\n scrollerCache.tweenScroll = scrollerCache.tweenScroll || {\n top: _getTweenCreator(scroller, _vertical),\n left: _getTweenCreator(scroller, _horizontal)\n };\n self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p];\n\n self.scrubDuration = function (value) {\n scrubSmooth = ScrollTrigger_isNumber(value) && value;\n\n if (!scrubSmooth) {\n scrubTween && scrubTween.progress(1).kill();\n scrubTween = 0;\n } else {\n scrubTween ? scrubTween.duration(value) : scrubTween = ScrollTrigger_gsap.to(animation, {\n ease: \"expo\",\n totalProgress: \"+=0\",\n inherit: false,\n duration: scrubSmooth,\n paused: true,\n onComplete: function onComplete() {\n return onScrubComplete && onScrubComplete(self);\n }\n });\n }\n };\n\n if (animation) {\n animation.vars.lazy = false;\n animation._initted && !self.isReverted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.duration() && animation.render(0, true, true); // special case: if this ScrollTrigger gets re-initted, a from() tween with a stagger could get initted initially and then reverted on the re-init which means it'll need to get rendered again here to properly display things. Otherwise, See https://gsap.com/forums/topic/36777-scrollsmoother-splittext-nextjs/ and https://codepen.io/GreenSock/pen/eYPyPpd?editors=0010\n\n self.animation = animation.pause();\n animation.scrollTrigger = self;\n self.scrubDuration(scrub);\n snap1 = 0;\n id || (id = animation.vars.id);\n }\n\n if (snap) {\n // TODO: potential idea: use legitimate CSS scroll snapping by pushing invisible elements into the DOM that serve as snap positions, and toggle the document.scrollingElement.style.scrollSnapType onToggle. See https://codepen.io/GreenSock/pen/JjLrgWM for a quick proof of concept.\n if (!ScrollTrigger_isObject(snap) || snap.push) {\n snap = {\n snapTo: snap\n };\n }\n\n \"scrollBehavior\" in ScrollTrigger_body.style && ScrollTrigger_gsap.set(isViewport ? [ScrollTrigger_body, ScrollTrigger_docEl] : scroller, {\n scrollBehavior: \"auto\"\n });
1 // smooth scrolling doesn't work with snap.\n\n _scrollers.forEach(function (o) {\n return ScrollTrigger_isFunction(o) && o.target === (isViewport ? ScrollTrigger_doc.scrollingElement || ScrollTrigger_docEl : scroller) && (o.smooth = false);\n }); // note: set smooth to false on both the vertical and horizontal scroll getters/setters\n\n\n snapFunc = ScrollTrigger_isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === \"labels\" ? _getClosestLabel(animation) : snap.snapTo === \"labelsDirectional\" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) {\n return _snapDirectional(snap.snapTo)(value, ScrollTrigger_getTime() - lastRefresh < 500 ? 0 : st.direction);\n } : ScrollTrigger_gsap.utils.snap(snap.snapTo);\n snapDurClamp = snap.duration || {\n min: 0.1,\n max: 2\n };\n snapDurClamp = ScrollTrigger_isObject(snapDurClamp) ? ScrollTrigger_clamp(snapDurClamp.min, snapDurClamp.max) : ScrollTrigger_clamp(snapDurClamp, snapDurClamp);\n snapDelayedCall = ScrollTrigger_gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () {\n var scroll = scrollFunc(),\n refreshedRecently = ScrollTrigger_getTime() - lastRefresh < 500,\n tween = tweenTo.tween;\n\n if ((refreshedRecently || Math.abs(self.getVelocity()) < 10) && !tween && !_pointerIsDown && lastSnap !== scroll) {\n var progress = (scroll - start) / change,\n totalProgress = animation && !isToggle ? animation.totalProgress() : progress,\n velocity = refreshedRecently ? 0 : (totalProgress - snap2) / (ScrollTrigger_getTime() - _time2) * 1000 || 0,\n change1 = ScrollTrigger_gsap.utils.clamp(-progress, 1 - progress, _abs(velocity / 2) * velocity / 0.185),\n naturalEnd = progress + (snap.inertia === false ? 0 : change1),\n endValue,\n endScroll,\n _snap = snap,\n onStart = _snap.onStart,\n _onInterrupt = _snap.onInterrupt,\n _onComplete = _snap.onComplete;\n endValue = snapFunc(naturalEnd, self);\n ScrollTrigger_isNumber(endValue) || (endValue = naturalEnd); // in case the function didn't return a number, fall back to using the naturalEnd\n\n endScroll = Math.round(start + endValue * change);\n\n if (scroll <= end && scroll >= start && endScroll !== scroll) {\n if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) {\n // there's an overlapping snap! So we must figure out which one is closer and let that tween live.\n return;\n }\n\n if (snap.inertia === false) {\n change1 = endValue - progress;\n }\n\n tweenTo(endScroll, {\n duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)),\n ease: snap.ease || \"power3\",\n data: _abs(endScroll - scroll),\n // record the distance so that if another snap tween occurs (conflict) we
1can prioritize the closest snap.\n onInterrupt: function onInterrupt() {\n return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self);\n },\n onComplete: function onComplete() {\n self.update();\n lastSnap = scrollFunc();\n\n if (animation) {\n // the resolution of the scrollbar is limited, so we should correct the scrubbed animation's playhead at the end to match EXACTLY where it was supposed to snap\n scrubTween ? scrubTween.resetTo(\"totalProgress\", endValue, animation._tTime / animation._tDur) : animation.progress(endValue);\n }\n\n snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress;\n onSnapComplete && onSnapComplete(self);\n _onComplete && _onComplete(self);\n }\n }, scroll, change1 * change, endScroll - scroll - change1 * change);\n onStart && onStart(self, tweenTo.tween);\n }\n } else if (self.isActive && lastSnap !== scroll) {\n snapDelayedCall.restart(true);\n }\n }).pause();\n }\n\n id && (_ids[id] = self);\n trigger = self.trigger = _getTarget(trigger || pin !== true && pin); // if a trigger has some kind of scroll-related effect applied that could contaminate the \"y\" or \"x\" position (like a ScrollSmoother effect), we needed a way to temporarily revert it, so we use the stRevert property of the gsCache. It can return another function that we'll call at the end so it can return to its normal state.\n\n customRevertReturn = trigger && trigger._gsap && trigger._gsap.stRevert;\n customRevertReturn && (customRevertReturn = customRevertReturn(self));\n pin = pin === true ? trigger : _getTarget(pin);\n ScrollTrigger_isString(toggleClass) && (toggleClass = {\n targets: trigger,\n className: toggleClass\n });\n\n if (pin) {\n pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && pin.parentNode && pin.parentNode.style && _getComputedStyle(pin.parentNode).display === \"flex\" ? false : _padding); // if the parent is display: flex, don't apply pinSpacing by default. We should check that pin.parentNode is an element (not shadow dom window)\n\n self.pin = pin;\n pinCache = ScrollTrigger_gsap.core.getCache(pin);\n\n if (!pinCache.spacer) {\n // record the spacer and pinOriginalState on the cache in case someone tries pinning the same element with MULTIPLE ScrollTriggers - we don't want to have multiple spacers or record the \"original\" pin state after it has already been affected by another ScrollTrigger.\n if (pinSpacer) {\n pinSpacer = _getTarget(pinSpacer);\n pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); // for React & Angular\n\n pinCache.spacerIsNative = !!pinSpacer;\n pinSpacer && (pinCache.spacerState = _getState(pinSpacer));\n }\n\n pinCache.spacer = spacer = pinSpacer || ScrollTrigger_doc.createElement(\"div\");\n spacer.classList.add(\"pin-spacer\");\n id && spacer.classList.add(\"pin-spacer-\" + id);\n pinCache.pinState = pinOriginalState = _getState(pin);\n } else {\n pinOriginalState = pinCache.pinState;\n }\n\n vars.force3D !== false && ScrollTrigger_gsap.set(pin, {\n force3D: true\n });\n self.spacer = spacer = pinCache.spacer;\n cs = _getComputedStyle(pin);\n spacingStart = cs[pinSpacing + direction.os2];\n pinGetter = ScrollTrigger_gsap.getProperty(pin);\n pinSetter = ScrollTrigger_gsap.quickSetter(pin, direction.a, _px); // pin.firstChild && !_maxScroll(pin, direction) && (pin.style.overflow = \"hidden\"); // protects from collapsing margins, but can have unintended consequences as demonstrated here: https://codepen.io/GreenSock/pen/1e42c7a73bfa409d2cf1e184e7a4248d so it was removed in favor of just telling people to set up their CSS to avoid the collapsing margins (overflow: hidden | auto is just one option. Another is border-top: 1px solid transparent).\n\n _swapPinIn(pin, spacer, cs);
1\n\n pinState = _getState(pin);\n }\n\n if (markers) {\n markerVars = ScrollTrigger_isObject(markers) ? ScrollTrigger_setDefaults(markers, _markerDefaults) : _markerDefaults;\n markerStartTrigger = _createMarker(\"scroller-start\", id, scroller, direction, markerVars, 0);\n markerEndTrigger = _createMarker(\"scroller-end\", id, scroller, direction, markerVars, 0, markerStartTrigger);\n offset = markerStartTrigger[\"offset\" + direction.op.d2];\n\n var content = _getTarget(_getProxyProp(scroller, \"content\") || scroller);\n\n markerStart = this.markerStart = _createMarker(\"start\", id, content, direction, markerVars, offset, 0, containerAnimation);\n markerEnd = this.markerEnd = _createMarker(\"end\", id, content, direction, markerVars, offset, 0, containerAnimation);\n containerAnimation && (caMarkerSetter = ScrollTrigger_gsap.quickSetter([markerStart, markerEnd], direction.a, _px));\n\n if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, \"fixedMarkers\") === true)) {\n _makePositionable(isViewport ? ScrollTrigger_body : scroller);\n\n ScrollTrigger_gsap.set([markerStartTrigger, markerEndTrigger], {\n force3D: true\n });\n markerStartSetter = ScrollTrigger_gsap.quickSetter(markerStartTrigger, direction.a, _px);\n markerEndSetter = ScrollTrigger_gsap.quickSetter(markerEndTrigger, direction.a, _px);\n }\n }\n\n if (containerAnimation) {\n var oldOnUpdate = containerAnimation.vars.onUpdate,\n oldParams = containerAnimation.vars.onUpdateParams;\n containerAnimation.eventCallback(\"onUpdate\", function () {\n self.update(0, 0, 1);\n oldOnUpdate && oldOnUpdate.apply(containerAnimation, oldParams || []);\n });\n }\n\n self.previous = function () {\n return _triggers[_triggers.indexOf(self) - 1];\n };\n\n self.next = function () {\n return _triggers[_triggers.indexOf(self) + 1];\n };\n\n self.revert = function (revert, temp) {\n if (!temp) {\n return self.kill(true);\n } // for compatibility with gsap.context() and gsap.matchMedia() which call revert()\n\n\n var r = revert !== false || !self.enabled,\n prevRefreshing = _refreshing;\n\n if (r !== self.isReverted) {\n if (r) {\n prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); // record the scroll so we can revert later (repositioning/pinning things can affect scroll position). In the static refresh() method, we first record all the scroll positions as a reference.\n\n prevProgress = self.progress;\n prevAnimProgress = animation && animation.progress();\n }\n\n markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {\n return m.style.display = r ? \"none\" : \"block\";\n });\n\n if (r) {\n _refreshing = self;\n self.update(r); // make sure the pin is back in its original position so that all the measurements are correct. do this BEFORE swapping the pin out\n }\n\n if (pin && (!pinReparent || !self.isActive)) {\n if (r) {\n _swapPinOut(pin, spacer, pinOriginalState);\n } else {\n _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState);\n }\n }\n\n r || self.update(r); // when we're restoring, the update should run AFTER swapping the pin into its pin-spacer.\n\n _refreshing = prevRefreshing; // restore. We set it to true during the update() so that things fire properly in there.\n\n self.isReverted = r;\n }\n };\n\n self.refresh = function (soft, force, position, pinOffset) {\n // position is typically only defined if it's coming from setPositions() - it's a way to skip the normal parsing. pinOffset is also only from setPositions() and is mostly related to fancy stuff we need to do in ScrollSmoother with effects\n if ((_refreshing || !self.enabled) && !force) {\n return;\n }\n\n if (pin && soft && _lastScrollTime) {\n ScrollTrigger_addListener(ScrollTrigger, \"scrollEnd\", _softRefresh);\n\n return;\n }\n\n !_refreshingAll && onRefreshInit && onRefreshInit(self);\n _refreshing = self;\n\n if (tweenTo.tween && !position) {\n // we skip this if a position is passed in because typically that's from .setPositions() and it's best to allow in-progress snapping to continue.\n tweenTo.tween.kill();\n tweenTo.tween = 0;\n }\n\n scrubTween && scrubTween.pause();\n invalidateOnRefresh && animation && animation.revert({\n kill: false\n }).invalidate();\n self.isReverted || self.revert(true, true);\n self._subPinOffset = false; // we'll set this to true in the sub-pins if we find any\n\n var size = getScrollerSize(),\n scrollerBounds = getScrollerOffsets(),\n max = containerAnimation ? c
1ontainerAnimation.duration() : _maxScroll(scroller, direction),\n isFirstRefresh = change <= 0.01,\n offset = 0,\n otherPinOffset = pinOffset || 0,\n parsedEnd = ScrollTrigger_isObject(position) ? position.end : vars.end,\n parsedEndTrigger = vars.endTrigger || trigger,\n parsedStart = ScrollTrigger_isObject(position) ? position.start : vars.start || (vars.start === 0 || !trigger ? 0 : pin ? \"0 0\" : \"0 100%\"),\n pinnedContainer = self.pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer, self),\n triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0,\n i = triggerIndex,\n cs,\n bounds,\n scroll,\n isVertical,\n override,\n curTrigger,\n curPin,\n oppositeScroll,\n initted,\n revertedPins,\n forcedOverflow,\n markerStartOffset,\n markerEndOffset;\n\n if (markers && ScrollTrigger_isObject(position)) {\n // if we alter the start/end positions with .setPositions(), it generally feeds in absolute NUMBERS which don't convey information about where to line up the markers, so to keep it intuitive, we record how far the trigger positions shift after applying the new numbers and then offset by that much in the opposite direction. We do the same to the associated trigger markers too of course.\n markerStartOffset = ScrollTrigger_gsap.getProperty(markerStartTrigger, direction.p);\n markerEndOffset = ScrollTrigger_gsap.getProperty(markerEndTrigger, direction.p);\n }\n\n while (i--) {\n // user might try to pin the same element more than once, so we must find any prior triggers with the same pin, revert them, and determine how long they're pinning so that we can offset things appropriately. Make sure we revert from last to first so that things \"rewind\" properly.\n curTrigger = _triggers[i];\n curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = self); // if it's a timeline-based trigger that hasn't been fully initialized yet because it's waiting for 1 tick, just force the refresh() here, otherwise if it contains a pin that's supposed to affect other ScrollTriggers further down the page, they won't be adjusted properly.\n\n curPin = curTrigger.pin;\n\n if (curPin && (curPin === trigger || curPin === pin || curPin === pinnedContainer) && !curTrigger.isReverted) {\n revertedPins || (revertedPins = []);\n revertedPins.unshift(curTrigger); // we'll revert from first to last to make sure things reach their end state properly\n\n curTrigger.revert(true, true);\n }\n\n if (curTrigger !== _triggers[i]) {\n // in case it got removed.\n triggerIndex--;\n i--;\n }\n }\n\n ScrollTrigger_isFunction(parsedStart) && (parsedStart = parsedStart(self));\n parsedStart = _parseClamp(parsedStart, \"start\", self);\n start = ScrollTrigger_parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._startClamp && \"_startClamp\") || (pin ? -0.001 : 0);\n ScrollTrigger_isFunction(parsedEnd) && (parsedEnd = parsedEnd(self));\n\n if (ScrollTrigger_isString(parsedEnd) && !parsedEnd.indexOf(\"+=\")) {\n if (~parsedEnd.indexOf(\" \")) {\n parsedEnd = (ScrollTrigger_isString(parsedStart) ? parsedStart.split(\" \")[0] : \"\") + parsedEnd;\n } else {\n offset = _offsetToPx(parsedEnd.substr(2), size);\n parsedEnd = ScrollTrigger_isString(parsedStart) ? parsedStart : (containerAnimation ? ScrollTrigger_gsap.utils.mapRange(0, containerAnimation.duration(), containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, start) : start) + offset; // _parsePosition won't factor in the offset if the start is a number, so do it here.\n\n parsedEndTrigger = trigger;\n }\n }\n\n parsedEnd = _parseClamp(parsedEnd, \"end\", self);\n end = Math.max(start, ScrollTrigger_parsePosition(parsedEnd || (parsedEndTrigger ? \"100% 0\" : max), parsedEndTrigger, size, direction, scrollFunc() + offset, markerEnd, markerEndTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._endClamp && \"_endClamp\")) || -0.001;\n offset = 0;\n i = triggerIndex;\n\n while (i--) {\n curTrigger = _triggers[i];\n curPin = curTrigger.pin;\n\n if (curPin && curTrigger.start - curTrigger._pinPush <= start && !containerAnimation && curTrigger.end > 0) {\n cs = curTrigger.end - (self._startClamp ? Math.max(0, curTr
1igger.start) : curTrigger.start);\n\n if ((curPin === trigger && curTrigger.start - curTrigger._pinPush < start || curPin === pinnedContainer) && isNaN(parsedStart)) {\n // numeric start values shouldn't be offset at all - treat them as absolute\n offset += cs * (1 - curTrigger.progress);\n }\n\n curPin === pin && (otherPinOffset += cs);\n }\n }\n\n start += offset;\n end += offset;\n self._startClamp && (self._startClamp += offset);\n\n if (self._endClamp && !_refreshingAll) {\n self._endClamp = end || -0.001;\n end = Math.min(end, _maxScroll(scroller, direction));\n }\n\n change = end - start || (start -= 0.01) && 0.001;\n\n if (isFirstRefresh) {\n // on the very first refresh(), the prevProgress couldn't have been accurate yet because the start/end were never calculated, so we set it here. Before 3.11.5, it could lead to an inaccurate scroll position restoration with snapping.\n prevProgress = ScrollTrigger_gsap.utils.clamp(0, 1, ScrollTrigger_gsap.utils.normalize(start, end, prevScroll));\n }\n\n self._pinPush = otherPinOffset;\n\n if (markerStart && offset) {\n // offset the markers if necessary\n cs = {};\n cs[direction.a] = \"+=\" + offset;\n pinnedContainer && (cs[direction.p] = \"-=\" + scrollFunc());\n ScrollTrigger_gsap.set([markerStart, markerEnd], cs);\n }\n\n if (pin && !(_clampingMax && self.end >= _maxScroll(scroller, direction))) {\n cs = _getComputedStyle(pin);\n isVertical = direction === _vertical;\n scroll = scrollFunc(); // recalculate because the triggers can affect the scroll\n\n pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset;\n\n if (!max && end > 1) {\n // makes sure the scroller has a scrollbar, otherwise if something has width: 100%, for example, it would be too big (exclude the scrollbar). See https://gsap.com/forums/topic/25182-scrolltrigger-width-of-page-increase-where-markers-are-set-to-false/\n forcedOverflow = (isViewport ? ScrollTrigger_doc.scrollingElement || ScrollTrigger_docEl : scroller).style;\n forcedOverflow = {\n style: forcedOverflow,\n value: forcedOverflow[\"overflow\" + direction.a.toUpperCase()]\n };\n\n if (isViewport && _getComputedStyle(ScrollTrigger_body)[\"overflow\" + direction.a.toUpperCase()] !== \"scroll\") {\n // avoid an extra scrollbar if BOTH <html> and <body> have overflow set to \"scroll\"\n forcedOverflow.style[\"overflow\" + direction.a.toUpperCase()] = \"scroll\";\n }\n }\n\n _swapPinIn(pin, spacer, cs);\n\n pinState = _getState(pin); // transforms will interfere with the top/left/right/bottom placement, so remove them temporarily. getBoundingClientRect() factors in transforms.\n\n bounds = _getBounds(pin, true);\n oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)();\n\n if (pinSpacing) {\n spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px];\n spacerState.t = spacer;\n i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0;\n\n if (i) {\n spacerState.push(direction.d, i + _px); // for box-sizing: border-box (must include padding).\n\n spacer.style.flexBasis !== \"auto\" && (spacer.style.flexBasis = i + _px);\n }\n\n _setState(spacerState);\n\n if (pinnedContainer) {\n // in ScrollTrigger.refresh(), we need to re-evaluate the pinContainer's size because this pinSpacing may stretch it out, but we can't just add the exact distance because depending on layout, it may not push things down or it may only do so partially.\n _triggers.forEach(function (t) {\n if (t.pin === pinnedContainer && t.vars.pinSpacing !== false) {\n t._subPinOffset = true;\n }\n });\n }\n\n useFixedPosition && scrollFunc(prevScroll);\n } else {\n i = _getSize(pin, direction);\n i && spacer.style.flexBasis !== \"auto\" && (spacer.style.flexBasis = i + _px);\n }\n\n if (useFixedPosition) {\n override = {\n top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px,\n left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px,\n boxSizing: \"border-box\",\n position: \"fixed\"\n };\n override[_width] = override[\"max\" + _Width] = Math.ceil(bounds.width) + _px;\n override[_height] = override[\"max\" + _Height] = Math.ceil(bounds.height) + _px;\n override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = \"0\";\n override[_padding] = cs[_padding];\n override[_padding + _Top] = cs[_padding + _Top];\n override[_padding + _Right] = cs[_padding + _Right];\n override[_padding + _Bottom] = cs[_padding + _Bottom];\n override[_padding + _Left] = cs[_padding + _Left];\n pinActiveState = _copyState(pinOriginalState, override, pinReparent);\n _refreshingAll && scrollFunc(0);\n }\n\n if (animation) {\n // the animation might be affecting the transform, so we must jump to the end, check the value, and compensate accordingly. Otherwise, when it becomes unpinned, the pinSetter() will get set to a value that doesn't include whatever the animation did.\n initted = animation._initted; // if not, we must invalidate() after this step, otherwise it could lock
1in starting values prematurely.\n\n ScrollTrigger_suppressOverwrites(1);\n\n animation.render(animation.duration(), true, true);\n pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset;\n pinMoves = Math.abs(change - pinChange) > 1;\n useFixedPosition && pinMoves && pinActiveState.splice(pinActiveState.length - 2, 2); // transform is the last property/value set in the state Array. Since the animation is controlling that, we should omit it.\n\n animation.render(0, true, true);\n initted || animation.invalidate(true);\n animation.parent || animation.totalTime(animation.totalTime()); // if, for example, a toggleAction called play() and then refresh() happens and when we render(1) above, it would cause the animation to complete and get removed from its parent, so this makes sure it gets put back in.\n\n ScrollTrigger_suppressOverwrites(0);\n } else {\n pinChange = change;\n }\n\n forcedOverflow && (forcedOverflow.value ? forcedOverflow.style[\"overflow\" + direction.a.toUpperCase()] = forcedOverflow.value : forcedOverflow.style.removeProperty(\"overflow-\" + direction.a));\n } else if (trigger && scrollFunc() && !containerAnimation) {\n // it may be INSIDE a pinned element, so walk up the tree and look for any elements with _pinOffset to compensate because anything with pinSpacing that's already scrolled would throw off the measurements in getBoundingClientRect()\n bounds = trigger.parentNode;\n\n while (bounds && bounds !== ScrollTrigger_body) {\n if (bounds._pinOffset) {\n start -= bounds._pinOffset;\n end -= bounds._pinOffset;\n }\n\n bounds = bounds.parentNode;\n }\n }\n\n revertedPins && revertedPins.forEach(function (t) {\n return t.revert(false, true);\n });\n self.start = start;\n self.end = end;\n scroll1 = scroll2 = _refreshingAll ? prevScroll : scrollFunc(); // reset velocity\n\n if (!containerAnimation && !_refreshingAll) {\n scroll1 < prevScroll && scrollFunc(prevScroll);\n self.scroll.rec = 0;\n }\n\n self.revert(false, true);\n lastRefresh = ScrollTrigger_getTime();\n\n if (snapDelayedCall) {\n lastSnap = -1; // just so snapping gets re-enabled, clear out any recorded last value\n // self.isActive && scrollFunc(start + change * prevProgress); // previously this line was here to ensure that when snapping kicks in, it's from the previous progress but in some cases that's not desirable, like an all-page ScrollTrigger when new content gets added to the page, that'd totally change the progress.\n\n snapDelayedCall.restart(true);\n }\n\n _refreshing = 0;\n animation && isToggle && (animation._initted || prevAnimProgress) && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress || 0, true).render(animation.time(), true, true); // must force a re-render because if saveStyles() was used on the target(s), the styles could have been wiped out during the refresh().\n\n if (isFirstRefresh || prevProgress !== self.progress || containerAnimation || invalidateOnRefresh) {\n // ensures that the direction is set properly (when refreshing, progress is set back to 0 initially, then back again to wherever it needs to be) and that callbacks are triggered.\n animation && !isToggle && animation.totalProgress(containerAnimation && start < -0.001 && !prevProgress ? ScrollTrigger_gsap.utils.normalize(start, end, 0) : prevProgress, true); // to avoid issues where animation callbacks like onStart aren't triggered.\n\n self.progress = isFirstRefresh || (scroll1 - start) / change === prevProgress ? 0 : prevProgress;\n }\n\n pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange));\n scrubTween && scrubTween.invalidate();\n\n if (!isNaN(markerStartOffset)) {\n // numbers were passed in for the position which are absolute, so instead of just putting the markers at the very bottom of the viewport, we figure out how far they shifted down (it's safe to assume they were originally positioned in closer relation to the trigger element with values like \"top\", \"center\", a percentage or whatever, so we offset that much in the opposite direction to basically revert them to the relative position thy were at previously.\n markerStartOffset -= ScrollTrigger_gsap.getProperty(markerStartTrigger, direction.p);\n markerEndOffset -= ScrollTrigger_gsap.getProperty(markerEndTrigger, direction.p);\n\n _shiftMarker(markerStartTrigger, direction, markerStartOffset);\n\n _shiftMarker(markerStart, direction, markerStartOffset - (pinOffset || 0));\n\n _shiftMarker(markerEndTrigger, direction, markerEndOffset);\n\n _shiftMarker(markerEnd, direction, markerEndOffset - (pinOffset || 0));\n }
1\n\n isFirstRefresh && !_refreshingAll && self.update(); // edge case - when you reload a page when it's already scrolled down, some browsers fire a \"scroll\" event before DOMContentLoaded, triggering an updateAll(). If we don't update the self.progress as part of refresh(), then when it happens next, it may record prevProgress as 0 when it really shouldn't, potentially causing a callback in an animation to fire again.\n\n if (onRefresh && !_refreshingAll && !executingOnRefresh) {\n // when refreshing all, we do extra work to correct pinnedContainer sizes and ensure things don't exceed the maxScroll, so we should do all the refreshes at the end after all that work so that the start/end values are corrected.\n executingOnRefresh = true;\n onRefresh(self);\n executingOnRefresh = false;\n }\n };\n\n self.getVelocity = function () {\n return (scrollFunc() - scroll2) / (ScrollTrigger_getTime() - _time2) * 1000 || 0;\n };\n\n self.endAnimation = function () {\n _endAnimation(self.callbackAnimation);\n\n if (animation) {\n scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1);\n }\n };\n\n self.labelToScroll = function (label) {\n return animation && animation.labels && (start || self.refresh() || start) + animation.labels[label] / animation.duration() * change || 0;\n };\n\n self.getTrailing = function (name) {\n var i = _triggers.indexOf(self),\n a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1);\n\n return (ScrollTrigger_isString(name) ? a.filter(function (t) {\n return t.vars.preventOverlaps === name;\n }) : a).filter(function (t) {\n return self.direction > 0 ? t.end <= start : t.start >= end;\n });\n };\n\n self.update = function (reset, recordVelocity, forceFake) {\n if (containerAnimation && !forceFake && !reset) {\n return;\n }\n\n var scroll = _refreshingAll === true ? prevScroll : self.scroll(),\n p = reset ? 0 : (scroll - start) / change,\n clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0,\n prevProgress = self.progress,\n isActive,\n wasActive,\n toggleState,\n action,\n stateChanged,\n toggled,\n isAtMax,\n isTakingAction;\n\n if (recordVelocity) {\n scroll2 = scroll1;\n scroll1 = containerAnimation ? scrollFunc() : scroll;\n\n if (snap) {\n snap2 = snap1;\n snap1 = animation && !isToggle ? animation.totalProgress() : clipped;\n }\n } // anticipate the pinning a few ticks ahead of time based on velocity to avoid a visual glitch due to the fact that most browsers do scrolling on a separate thread (not synced with requestAnimationFrame).\n\n\n if (anticipatePin && pin && !_refreshing && !ScrollTrigger_startup && _lastScrollTime) {\n if (!clipped && start < scroll + (scroll - scroll2) / (ScrollTrigger_getTime() - _time2) * anticipatePin) {\n clipped = 0.0001;\n } else if (clipped === 1 && end > scroll + (scroll - scroll2) / (ScrollTrigger_getTime() - _time2) * anticipatePin) {\n clipped = 0.9999;\n }\n }\n\n if (clipped !== prevProgress && self.enabled) {\n isActive = self.isActive = !!clipped && clipped < 1;\n wasActive = !!prevProgress && prevProgress < 1;\n toggled = isActive !== wasActive;\n stateChanged = toggled || !!clipped !== !!prevProgress; // could go from start all the way to end, thus it didn't toggle but it did change state in a sense (may need to fire a callback)\n\n self.direction = clipped > prevProgress ? 1 : -1;\n self.progress = clipped;\n\n if (stateChanged && !_refreshing) {\n toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; // 0 = enter, 1 = leave, 2 = enterBack, 3 = leaveBack (we prioritize the FIRST encounter, thus if you scroll really fast past the onEnter and onLeave in one tick, it'd prioritize onEnter.\n\n if (isToggle) {\n action = !toggled && toggleActions[toggleState + 1] !== \"none\" && toggleActions[toggleState + 1] || toggleActions[toggleState]; // if it didn't toggle, that means it shot right past and since we prioritize the \"enter\" action, we should switch to the \"leave\" in this case (but only if one is defined)\n\n isTakingAction = animation && (action === \"complete\" || action === \"reset\" || action in animation);\n }\n }\n\n preventOverlaps && (toggled || isTakingAction) && (isTakingAction || scrub || !animation) && (ScrollTrigger_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEac
1h(function (t) {\n return t.endAnimation();\n }));\n\n if (!isToggle) {\n if (scrubTween && !_refreshing && !ScrollTrigger_startup) {\n scrubTween._dp._time - scrubTween._start !== scrubTween._time && scrubTween.render(scrubTween._dp._time - scrubTween._start); // if there's a scrub on both the container animation and this one (or a ScrollSmoother), the update order would cause this one not to have rendered yet, so it wouldn't make any progress before we .restart() it heading toward the new progress so it'd appear stuck thus we force a render here.\n\n if (scrubTween.resetTo) {\n scrubTween.resetTo(\"totalProgress\", clipped, animation._tTime / animation._tDur);\n } else {\n // legacy support (courtesy), before 3.10.0\n scrubTween.vars.totalProgress = clipped;\n scrubTween.invalidate().restart();\n }\n } else if (animation) {\n animation.totalProgress(clipped, !!(_refreshing && (lastRefresh || reset)));\n }\n }\n\n if (pin) {\n reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart);\n\n if (!useFixedPosition) {\n pinSetter(ScrollTrigger_round(pinStart + pinChange * clipped));\n } else if (stateChanged) {\n isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); // if it's at the VERY end of the page, don't switch away from position: fixed because it's pointless and it could cause a brief flash when the user scrolls back up (when it gets pinned again)\n\n if (pinReparent) {\n if (!reset && (isActive || isAtMax)) {\n var bounds = _getBounds(pin, true),\n _offset = scroll - start;\n\n _reparent(pin, ScrollTrigger_body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px);\n } else {\n _reparent(pin, spacer);\n }\n }\n\n _setState(isActive || isAtMax ? pinActiveState : pinState);\n\n pinMoves && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0));\n }\n }\n\n snap && !tweenTo.tween && !_refreshing && !ScrollTrigger_startup && snapDelayedCall.restart(true);\n toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) {\n return el.classList[isActive || once ? \"add\" : \"remove\"](toggleClass.className);\n }); // classes could affect positioning, so do it even if reset or refreshing is true.\n\n onUpdate && !isToggle && !reset && onUpdate(self);\n\n if (stateChanged && !_refreshing) {\n if (isToggle) {\n if (isTakingAction) {\n if (action === \"complete\") {\n animation.pause().totalProgress(1);\n } else if (action === \"reset\") {\n animation.restart(true).pause();\n } else if (action === \"restart\") {\n animation.restart(true);\n } else {\n animation[action]();\n }\n }\n\n onUpdate && onUpdate(self);\n }\n\n if (toggled || !_limitCallbacks) {\n // on startup, the page could be scrolled and we don't want to fire callbacks that didn't toggle. For example onEnter shouldn't fire if the ScrollTrigger isn't actually entered.\n onToggle && toggled && ScrollTrigger_callback(self, onToggle);\n callbacks[toggleState] && ScrollTrigger_callback(self, callbacks[toggleState]);\n once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); // a callback shouldn't be called again if once is true.\n\n if (!toggled) {\n // it's possible to go completely past, like from before the start to after the end (or vice-versa) in which case BOTH callbacks should be fired in that order\n toggleState = clipped === 1 ? 1 : 3;\n callbacks[toggleState] && ScrollTrigger_callback(self, callbacks[toggleState]);\n }\n }\n\n if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (ScrollTrigger_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) {\n _endAnimation(self.callbackA
1nimation);\n\n scrubTween ? scrubTween.progress(1) : _endAnimation(animation, action === \"reverse\" ? 1 : !clipped, 1);\n }\n } else if (isToggle && onUpdate && !_refreshing) {\n onUpdate(self);\n }\n } // update absolutely-positioned markers (only if the scroller isn't the viewport)\n\n\n if (markerEndSetter) {\n var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll;\n markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0));\n markerEndSetter(n);\n }\n\n caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0));\n };\n\n self.enable = function (reset, refresh) {\n if (!self.enabled) {\n self.enabled = true;\n\n ScrollTrigger_addListener(scroller, \"resize\", _onResize);\n\n isViewport || ScrollTrigger_addListener(scroller, \"scroll\", ScrollTrigger_onScroll);\n onRefreshInit && ScrollTrigger_addListener(ScrollTrigger, \"refreshInit\", onRefreshInit);\n\n if (reset !== false) {\n self.progress = prevProgress = 0;\n scroll1 = scroll2 = lastSnap = scrollFunc();\n }\n\n refresh !== false && self.refresh();\n }\n };\n\n self.getTween = function (snap) {\n return snap && tweenTo ? tweenTo.tween : scrubTween;\n };\n\n self.setPositions = function (newStart, newEnd, keepClamp, pinOffset) {\n // doesn't persist after refresh()! Intended to be a way to override values that were set during refresh(), like you could set it in onRefresh()\n if (containerAnimation) {\n // convert ratios into scroll positions. Remember, start/end values on ScrollTriggers that have a containerAnimation refer to the time (in seconds), NOT scroll positions.\n var st = containerAnimation.scrollTrigger,\n duration = containerAnimation.duration(),\n _change = st.end - st.start;\n\n newStart = st.start + _change * newStart / duration;\n newEnd = st.start + _change * newEnd / duration;\n }\n\n self.refresh(false, false, {\n start: _keepClamp(newStart, keepClamp && !!self._startClamp),\n end: _keepClamp(newEnd, keepClamp && !!self._endClamp)\n }, pinOffset);\n self.update();\n };\n\n self.adjustPinSpacing = function (amount) {\n if (spacerState && amount) {\n var i = spacerState.indexOf(direction.d) + 1;\n spacerState[i] = parseFloat(spacerState[i]) + amount + _px;\n spacerState[1] = parseFloat(spacerState[1]) + amount + _px;\n\n _setState(spacerState);\n }\n };\n\n self.disable = function (reset, allowAnimation) {\n if (self.enabled) {\n reset !== false && self.revert(true, true);\n self.enabled = self.isActive = false;\n allowAnimation || scrubTween && scrubTween.pause();\n prevScroll = 0;\n pinCache && (pinCache.uncache = 1);\n onRefreshInit && ScrollTrigger_removeListener(ScrollTrigger, \"refreshInit\", onRefreshInit);\n\n if (snapDelayedCall) {\n snapDelayedCall.pause();\n tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0);\n }\n\n if (!isViewport) {\n var i = _triggers.length;\n\n while (i--) {\n if (_triggers[i].scroller === scroller && _triggers[i] !== self) {\n return; //don't remove the listeners if there are still other triggers referencing it.\n }\n }\n\n ScrollTrigger_removeListener(scroller, \"resize\", _onResize);\n\n isViewport || ScrollTrigger_removeListener(scroller, \"scroll\", ScrollTrigger_onScroll);\n }\n }\n };\n\n self.kill = function (revert, allowAnimation) {\n self.disable(revert, allowAnimation);\n scrubTween && !allowAnimation && scrubTween.kill();\n id && delete _ids[id];\n\n var i = _triggers.indexOf(self);\n\n i >= 0 && _triggers.splice(i, 1);\n i === _i && _direction > 0 && _i--; // if we're in the middle of a refresh() or update(), splicing would cause skips in the index, so adjust...\n // if no other ScrollTrigger instances of the same scroller are found, wipe out any re
1corded scroll position. Otherwise, in a single page application, for example, it could maintain scroll position when it really shouldn't.\n\n i = 0;\n\n _triggers.forEach(function (t) {\n return t.scroller === self.scroller && (i = 1);\n });\n\n i || _refreshingAll || (self.scroll.rec = 0);\n\n if (animation) {\n animation.scrollTrigger = null;\n revert && animation.revert({\n kill: false\n });\n allowAnimation || animation.kill();\n }\n\n markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {\n return m.parentNode && m.parentNode.removeChild(m);\n });\n _primary === self && (_primary = 0);\n\n if (pin) {\n pinCache && (pinCache.uncache = 1);\n i = 0;\n\n _triggers.forEach(function (t) {\n return t.pin === pin && i++;\n });\n\n i || (pinCache.spacer = 0); // if there aren't any more ScrollTriggers with the same pin, remove the spacer, otherwise it could be contaminated with old/stale values if the user re-creates a ScrollTrigger for the same element.\n }\n\n vars.onKill && vars.onKill(self);\n };\n\n _triggers.push(self);\n\n self.enable(false, false);\n customRevertReturn && customRevertReturn(self);\n\n if (animation && animation.add && !change) {\n // if the animation is a timeline, it may not have been populated yet, so it wouldn't render at the proper place on the first refresh(), thus we should schedule one for the next tick. If \"change\" is defined, we know it must be re-enabling, thus we can refresh() right away.\n var updateFunc = self.update; // some browsers may fire a scroll event BEFORE a tick elapses and/or the DOMContentLoaded fires. So there's a chance update() will be called BEFORE a refresh() has happened on a Timeline-attached ScrollTrigger which means the start/end won't be calculated yet. We don't want to add conditional logic inside the update() method (like check to see if end is defined and if not, force a refresh()) because that's a function that gets hit a LOT (performance). So we swap out the real update() method for this one that'll re-attach it the first time it gets called and of course forces a refresh().\n\n self.update = function () {\n self.update = updateFunc;\n start || end || self.refresh();\n };\n\n ScrollTrigger_gsap.delayedCall(0.01, self.update);\n change = 0.01;\n start = end = 0;\n } else {\n self.refresh();\n }\n\n pin && _queueRefreshAll(); // pinning could affect the positions of other things, so make sure we queue a full refresh()\n };\n\n ScrollTrigger.register = function register(core) {\n if (!ScrollTrigger_coreInitted) {\n ScrollTrigger_gsap = core || ScrollTrigger_getGSAP();\n ScrollTrigger_windowExists() && window.document && ScrollTrigger.enable();\n ScrollTrigger_coreInitted = _enabled;\n }\n\n return ScrollTrigger_coreInitted;\n };\n\n ScrollTrigger.defaults = function defaults(config) {\n if (config) {\n for (var p in config) {\n ScrollTrigger_defaults[p] = config[p];\n }\n }\n\n return ScrollTrigger_defaults;\n };\n\n ScrollTrigger.disable = function disable(reset, kill) {\n _enabled = 0;\n\n _triggers.forEach(function (trigger) {\n return trigger[kill ? \"kill\" : \"disable\"](reset);\n });\n\n ScrollTrigger_removeListener(ScrollTrigger_win, \"wheel\", ScrollTrigger_onScroll);\n\n ScrollTrigger_removeListener(ScrollTrigger_doc, \"scroll\", ScrollTrigger_onScroll);\n\n clearInterval(_syncInterval);\n\n ScrollTrigger_removeListener(ScrollTrigger_doc, \"touchcancel\", ScrollTrigger_passThrough);\n\n ScrollTrigger_removeListener(ScrollTrigger_body, \"touchstart\", ScrollTrigger_passThrough);\n\n _multiListener(ScrollTrigger_removeListener, ScrollTrigger_doc, \"pointerdown,touchstart,mousedown\", _pointerDownHandler);\n\n _multiListener(ScrollTrigger_removeListener, ScrollTrigger_doc, \"pointerup,touchend,mouseup\", _pointerUpHandler);\n\n _resizeDelay.kill();\n\n _iterateAutoRefresh(ScrollTrigger_removeListener);\n\n for (var i = 0; i < _scrollers.length; i += 3) {\n _wheelListener(ScrollTrigger_removeListener, _scrollers[i], _scrollers[i + 1]);\n\n _wheelListener(ScrollTrigger_removeListener, _scrollers[i], _scrollers[i + 2]);\n }\n };\n\n ScrollTrigger.enable = function enable() {\n ScrollTrigger_win = window;\n ScrollTrigger_doc = document;\n ScrollTrigger_docEl = ScrollTrigger_doc.documentElement;\n ScrollTrigger_body = ScrollTrigger_doc.body;\n\n if (ScrollTrigger_gsap) {\n _toArray = ScrollTrigger_gsap.utils.toArray;\n ScrollTrigger_clamp = ScrollTrigger_gsap.utils.clamp;\n ScrollTrigger_context = ScrollTrigger_gsap.core.context || ScrollTrigger_passThrough;\n ScrollTrigger_suppressOverwrites = ScrollTrigger_gsap.core.suppressOverwrites || ScrollTrigger_passThrough;\n _scrollRestoration = ScrollTrigger_win.history.scrollRestoration || \"auto\";\n _lastScroll = ScrollTrigger_win.pageYOffset;\n ScrollTrigger_gsap.core.globals(\"ScrollTrigger\", ScrollTrigger); // must register the global manually because in Internet Explorer, functions (classes) don't have a \"name\" property.\n\n if (ScrollTrigger_body) {\
1n _enabled = 1;\n _div100vh = document.createElement(\"div\"); // to solve mobile browser address bar show/hide resizing, we shouldn't rely on window.innerHeight. Instead, use a <div> with its height set to 100vh and measure that since that's what the scrolling is based on anyway and it's not affected by address bar showing/hiding.\n\n _div100vh.style.height = \"100vh\";\n _div100vh.style.position = \"absolute\";\n\n _refresh100vh();\n\n _rafBugFix();\n\n Observer_Observer.register(ScrollTrigger_gsap); // isTouch is 0 if no touch, 1 if ONLY touch, and 2 if it can accommodate touch but also other types like mouse/pointer.\n\n ScrollTrigger.isTouch = Observer_Observer.isTouch;\n _fixIOSBug = Observer_Observer.isTouch && /(iPad|iPhone|iPod|Mac)/g.test(navigator.userAgent); // since 2017, iOS has had a bug that causes event.clientX/Y to be inaccurate when a scroll occurs, thus we must alternate ignoring every other touchmove event to work around it. See https://bugs.webkit.org/show_bug.cgi?id=181954 and https://codepen.io/GreenSock/pen/ExbrPNa/087cef197dc35445a0951e8935c41503\n\n _ignoreMobileResize = Observer_Observer.isTouch === 1;\n\n ScrollTrigger_addListener(ScrollTrigger_win, \"wheel\", ScrollTrigger_onScroll); // mostly for 3rd party smooth scrolling libraries.\n\n\n ScrollTrigger_root = [ScrollTrigger_win, ScrollTrigger_doc, ScrollTrigger_docEl, ScrollTrigger_body];\n\n if (ScrollTrigger_gsap.matchMedia) {\n ScrollTrigger.matchMedia = function (vars) {\n var mm = ScrollTrigger_gsap.matchMedia(),\n p;\n\n for (p in vars) {\n mm.add(p, vars[p]);\n }\n\n return mm;\n };\n\n ScrollTrigger_gsap.addEventListener(\"matchMediaInit\", function () {\n return _revertAll();\n });\n ScrollTrigger_gsap.addEventListener(\"matchMediaRevert\", function () {\n return _revertRecorded();\n });\n ScrollTrigger_gsap.addEventListener(\"matchMedia\", function () {\n _refreshAll(0, 1);\n\n ScrollTrigger_dispatch(\"matchMedia\");\n });\n ScrollTrigger_gsap.matchMedia(\"(orientation: portrait)\", function () {\n // when orientation changes, we should take new base measurements for the ignoreMobileResize feature.\n _setBaseDimensions();\n\n return _setBaseDimensions;\n });\n } else {\n console.warn(\"Requires GSAP 3.11.0 or later\");\n }\n\n _setBaseDimensions();\n\n ScrollTrigger_addListener(ScrollTrigger_doc, \"scroll\", ScrollTrigger_onScroll); // some browsers (like Chrome), the window stops dispatching scroll events on the window if you scroll really fast, but it's consistent on the document!\n\n\n var bodyStyle = ScrollTrigger_body.style,\n border = bodyStyle.borderTopStyle,\n AnimationProto = ScrollTrigger_gsap.core.Animation.prototype,\n bounds,\n i;\n AnimationProto.revert || Object.defineProperty(AnimationProto, \"revert\", {\n value: function value() {\n return this.time(-0.01, true);\n }\n }); // only for backwards compatibility (Animation.revert() was added after 3.10.4)\n\n bodyStyle.borderTopStyle = \"solid\"; // works around an issue where a margin of a child element could throw off the bounds of the _body, making it seem like there's a margin when there actually isn't. The border ensures that the bounds are accurate.\n\n bounds = _getBounds(ScrollTrigger_body);\n _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; // accommodate the offset of the <body> caused by margins and/or padding\n\n _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0;\n border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty(\"border-top-style\"); // TODO: (?) maybe move to leveraging the velocity mechanism in Observer and skip intervals.\n\n _syncInterval = setInterval(_sync, 250);\n ScrollTrigger_gsap.delayedCall(0.5, function () {\n return ScrollTrigger_startup = 0;\n });\n\n ScrollTrigger_addListener(ScrollTrigger_doc, \"touchcancel\", ScrollTrigger_passThrough); // some older Android devices intermittently stop dispatching \"touchmove\" events if we don't listen for \"touchcancel\" on the document.\n\n\n ScrollTrigger_addListener(ScrollTrigger_body, \"touchstart\", ScrollTrigger_passThrough); //works around Safari bug: https://gsap.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/\n\n\n _multiListener(ScrollTrigger_addListener, ScrollTrigger_doc, \"pointerdown,touchstart,mousedown\", _pointerDownHandler);\n\n _multiListener(ScrollTrigger_addListener, ScrollTrigger_doc, \"pointerup,touchend,mouseup\", _pointerUpHandler);\n\n ScrollTrigger_transformProp = ScrollTrigger_gsap.utils.checkPrefix(\"transform\");\n\n _stateProps.push(ScrollTrigger_transformProp);\n\n ScrollTrigger_coreInitted = ScrollTrigger_getTime();\n _resizeDelay = ScrollTrigger_gsap.delayedCall(0.2, _refreshAll).pause();\n _autoRefresh = [ScrollTrigger_doc, \"visibilitychange\", function () {\n var w = ScrollTrigger_win.innerWidth,\n h = ScrollTrigger_win.innerHeight;\n\n if (ScrollTrigger_doc.hidden) {\n _prevWidth = w;\n _prevHeight = h;\n }
1 else if (_prevWidth !== w || _prevHeight !== h) {\n _onResize();\n }\n }, ScrollTrigger_doc, \"DOMContentLoaded\", _refreshAll, ScrollTrigger_win, \"load\", _refreshAll, ScrollTrigger_win, \"resize\", _onResize];\n\n _iterateAutoRefresh(ScrollTrigger_addListener);\n\n _triggers.forEach(function (trigger) {\n return trigger.enable(0, 1);\n });\n\n for (i = 0; i < _scrollers.length; i += 3) {\n _wheelListener(ScrollTrigger_removeListener, _scrollers[i], _scrollers[i + 1]);\n\n _wheelListener(ScrollTrigger_removeListener, _scrollers[i], _scrollers[i + 2]);\n }\n }\n }\n };\n\n ScrollTrigger.config = function config(vars) {\n \"limitCallbacks\" in vars && (_limitCallbacks = !!vars.limitCallbacks);\n var ms = vars.syncInterval;\n ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms);\n \"ignoreMobileResize\" in vars && (_ignoreMobileResize = ScrollTrigger.isTouch === 1 && vars.ignoreMobileResize);\n\n if (\"autoRefreshEvents\" in vars) {\n _iterateAutoRefresh(ScrollTrigger_removeListener) || _iterateAutoRefresh(ScrollTrigger_addListener, vars.autoRefreshEvents || \"none\");\n _ignoreResize = (vars.autoRefreshEvents + \"\").indexOf(\"resize\") === -1;\n }\n };\n\n ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) {\n var t = _getTarget(target),\n i = _scrollers.indexOf(t),\n isViewport = ScrollTrigger_isViewport(t);\n\n if (~i) {\n _scrollers.splice(i, isViewport ? 6 : 2);\n }\n\n if (vars) {\n isViewport ? _proxies.unshift(ScrollTrigger_win, vars, ScrollTrigger_body, vars, ScrollTrigger_docEl, vars) : _proxies.unshift(t, vars);\n }\n };\n\n ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) {\n _triggers.forEach(function (t) {\n return t._ctx && t._ctx.query === query && t._ctx.kill(true, true);\n });\n };\n\n ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) {\n var bounds = (ScrollTrigger_isString(element) ? _getTarget(element) : element).getBoundingClientRect(),\n offset = bounds[horizontal ? _width : _height] * ratio || 0;\n return horizontal ? bounds.right - offset > 0 && bounds.left + offset < ScrollTrigger_win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < ScrollTrigger_win.innerHeight;\n };\n\n ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) {\n ScrollTrigger_isString(element) && (element = _getTarget(element));\n var bounds = element.getBoundingClientRect(),\n size = bounds[horizontal ? _width : _height],\n offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf(\"%\") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0;\n return horizontal ? (bounds.left + offset) / ScrollTrigger_win.innerWidth : (bounds.top + offset) / ScrollTrigger_win.innerHeight;\n };\n\n ScrollTrigger.killAll = function killAll(allowListeners) {\n _triggers.slice(0).forEach(function (t) {\n return t.vars.id !== \"ScrollSmoother\" && t.kill();\n });\n\n if (allowListeners !== true) {\n var listeners = ScrollTrigger_listeners.killAll || [];\n ScrollTrigger_listeners = {};\n listeners.forEach(function (f) {\n return f();\n });\n }\n };\n\n return ScrollTrigger;\n}();\nScrollTrigger_ScrollTrigger.version = \"3.12.5\";\n\nScrollTrigger_ScrollTrigger.saveStyles = function (targets) {\n return targets ? _toArray(targets).forEach(function (target) {\n // saved styles are recorded in a consecutive alternating Array, like [element, cssText, transform attribute, cache, matchMedia, ...]\n if (target && target.style) {\n var i = _savedStyles.indexOf(target);\n\n i >= 0 && _savedStyles.splice(i, 5);\n\n _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute(\"transform\"), ScrollTrigger_gsap.core.getCache(target), ScrollTrigger_context());\n }\n }) : _savedStyles;\n};\n\nScrollTrigger_ScrollTrigger.revert = function (soft, media) {\n return _revertAll(!soft, media);\n};\n\nScrollTrigger_ScrollTrigger.create = function (vars, animation) {\n return new ScrollTrigger_ScrollTrigger(vars, animation);\n};\n\nScrollTrigger_ScrollTrigger.refresh = function (safe) {\n return safe ? _onResize() : (ScrollTrigger_coreInitted || ScrollTrigger_ScrollTrigger.register()) && _refreshAll(true);\n};\n\nScrollTrigger_ScrollTrigger.update = function (force) {\n return ++_scrollers.cache && _updateAll(force === true ? 2 : 0);\n};\n\nScrollTrigger_ScrollTrigger.clearScrollMemory = _clearScrollMemory;\n\nScrollTrigger_ScrollTrigger.maxScroll = function (element, horizontal) {\n return _maxScroll(element, horizontal ? _horizontal : _vertical);\n};\n\nScrollTrigger_ScrollTrigger.getScrollFunc = function (element, horizontal) {\n return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical);\n};\n\nScrollTrigger_ScrollTrigger.getById = function (id) {\n return _ids[id];\n};\n\nScrollTrigger_ScrollTrigger.getAll = function () {\n return _triggers.filter(function (t) {\n return t.vars.id !== \"ScrollSmoother\";\n });\n}; // it's common for people to ScrollTrigger.getAll(t => t.kill()) on page routes, for example, and we don't want it to ruin smooth scrolling by killing the main ScrollSmoother one.\n\n\nScrollTrigger_ScrollTrigger.isScrolling = function () {\n return !!_lastScrollTime;\n};\n\nScrollTrigger_ScrollTrigger.snapDirectional = _snapDirectional;\n\nScrollTrigger_ScrollTrigger.addEventListener = function (type, callback) {\n var a = ScrollTrigger_listeners[type] || (ScrollTrigger_listeners[type] = []);\n ~a.indexOf(callback) || a.push(callback);\n};\n\nScrollTrigger_ScrollTrigger.removeEventListener = function (type, callback) {\n var a = ScrollTrigger_listeners[type],\n i = a && a.indexOf(callback);\n i >= 0 && a.splice(i, 1);\n};\n\nScrollTrigger_ScrollTrigger.batch = function (targets, vars) {\n var result = [],\n varsCopy = {},\n interval = vars.interval || 0.016,\n batchMax = vars.batchMax || 1e9,\n proxyCallback = function proxyCallback(type, callback) {\n var elements = [],\n triggers = [],\n delay
1= ScrollTrigger_gsap.delayedCall(interval, function () {\n callback(elements, triggers);\n elements = [];\n triggers = [];\n }).pause();\n return function (self) {\n elements.length || delay.restart(true);\n elements.push(self.trigger);\n triggers.push(self);\n batchMax <= elements.length && delay.progress(1);\n };\n },\n p;\n\n for (p in vars) {\n varsCopy[p] = p.substr(0, 2) === \"on\" && ScrollTrigger_isFunction(vars[p]) && p !== \"onRefreshInit\" ? proxyCallback(p, vars[p]) : vars[p];\n }\n\n if (ScrollTrigger_isFunction(batchMax)) {\n batchMax = batchMax();\n\n ScrollTrigger_addListener(ScrollTrigger_ScrollTrigger, \"refresh\", function () {\n return batchMax = vars.batchMax();\n });\n }\n\n _toArray(targets).forEach(function (target) {\n var config = {};\n\n for (p in varsCopy) {\n config[p] = varsCopy[p];\n }\n\n config.trigger = target;\n result.push(ScrollTrigger_ScrollTrigger.create(config));\n });\n\n return result;\n}; // to reduce file size. clamps the scroll and also returns a duration multiplier so that if the scroll gets chopped shorter, the duration gets curtailed as well (otherwise if you're very close to the top of the page, for example, and swipe up really fast, it'll suddenly slow down and take a long time to reach the top).\n\n\nvar _clampScrollAndGetDurationMultiplier = function _clampScrollAndGetDurationMultiplier(scrollFunc, current, end, max) {\n current > max ? scrollFunc(max) : current < 0 && scrollFunc(0);\n return end > max ? (max - current) / (end - current) : end < 0 ? current / (current - end) : 1;\n},\n _allowNativePanning = function _allowNativePanning(target, direction) {\n if (direction === true) {\n target.style.removeProperty(\"touch-action\");\n } else {\n target.style.touchAction = direction === true ? \"auto\" : direction ? \"pan-\" + direction + (Observer_Observer.isTouch ? \" pinch-zoom\" : \"\") : \"none\"; // note: Firefox doesn't support it pinch-zoom properly, at least in addition to a pan-x or pan-y.\n }\n\n target === ScrollTrigger_docEl && _allowNativePanning(ScrollTrigger_body, direction);\n},\n _overflow = {\n auto: 1,\n scroll: 1\n},\n _nestedScroll = function _nestedScroll(_ref5) {\n var event = _ref5.event,\n target = _ref5.target,\n axis = _ref5.axis;\n\n var node = (event.changedTouches ? event.changedTouches[0] : event).target,\n cache = node._gsap || ScrollTrigger_gsap.core.getCache(node),\n time = ScrollTrigger_getTime(),\n cs;\n\n if (!cache._isScrollT || time - cache._isScrollT > 2000) {\n // cache for 2 seconds to improve performance.\n while (node && node !== ScrollTrigger_body && (node.scrollHeight <= node.clientHeight && node.scrollWidth <= node.clientWidth || !(_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]))) {\n node = node.parentNode;\n }\n\n cache._isScroll = node && node !== target && !ScrollTrigger_isViewport(node) && (_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]);\n cache._isScrollT = time;\n }\n\n if (cache._isScroll || axis === \"x\") {\n event.stopPropagation();\n event._gsapAllow = true;\n }\n},\n // capture events on scrollable elements INSIDE the <body> and allow those by calling stopPropagation() when we find a scrollable ancestor\n_inputObserver = function _inputObserver(target, type, inputs, nested) {\n return Observer_Observer.create({\n target: target,\n capture: true,\n debounce: false,\n lockAxis: true,\n type: type,\n onWheel: nested = nested && _nestedScroll,\n onPress: nested,\n onDrag: nested,\n onScroll: nested,\n onEnable: function onEnable() {\n return inputs && ScrollTrigger_addListener(ScrollTrigger_doc, Observer_Observer.eventTypes[0], _captureInputs, false, true);\n },\n onDisable: function onDisable() {\n return ScrollTrigger_removeListener(ScrollTrigger_doc, Observer_Observer.eventTypes[0], _captureInputs, true);\n }\n });\n},\n _inputExp = /(input|label|select|textarea)/i,\n _inputIsFocused,\n _captureInputs = function _captureInputs(e) {\n var isInput = _inputExp.test(e.target.tagName);\n\n if (isInput || _inputIsFocused) {\n e._gsapAllow = true;\n _inputIsFocused = isInput;\n }\n},\n _getScrollNormalizer = function _getScrollNormalizer(vars) {\n ScrollTrigger_isObject(vars) || (vars = {});\n vars.preventDefault = vars.isNormalizer = vars.allowClicks = true;
1\n vars.type || (vars.type = \"wheel,touch\");\n vars.debounce = !!vars.debounce;\n vars.id = vars.id || \"normalizer\";\n\n var _vars2 = vars,\n normalizeScrollX = _vars2.normalizeScrollX,\n momentum = _vars2.momentum,\n allowNestedScroll = _vars2.allowNestedScroll,\n onRelease = _vars2.onRelease,\n self,\n maxY,\n target = _getTarget(vars.target) || ScrollTrigger_docEl,\n smoother = ScrollTrigger_gsap.core.globals().ScrollSmoother,\n smootherInstance = smoother && smoother.get(),\n content = _fixIOSBug && (vars.content && _getTarget(vars.content) || smootherInstance && vars.content !== false && !smootherInstance.smooth() && smootherInstance.content()),\n scrollFuncY = _getScrollFunc(target, _vertical),\n scrollFuncX = _getScrollFunc(target, _horizontal),\n scale = 1,\n initialScale = (Observer_Observer.isTouch && ScrollTrigger_win.visualViewport ? ScrollTrigger_win.visualViewport.scale * ScrollTrigger_win.visualViewport.width : ScrollTrigger_win.outerWidth) / ScrollTrigger_win.innerWidth,\n wheelRefresh = 0,\n resolveMomentumDuration = ScrollTrigger_isFunction(momentum) ? function () {\n return momentum(self);\n } : function () {\n return momentum || 2.8;\n },\n lastRefreshID,\n skipTouchMove,\n inputObserver = _inputObserver(target, vars.type, true, allowNestedScroll),\n resumeTouchMove = function resumeTouchMove() {\n return skipTouchMove = false;\n },\n scrollClampX = ScrollTrigger_passThrough,\n scrollClampY = ScrollTrigger_passThrough,\n updateClamps = function updateClamps() {\n maxY = _maxScroll(target, _vertical);\n scrollClampY = ScrollTrigger_clamp(_fixIOSBug ? 1 : 0, maxY);\n normalizeScrollX && (scrollClampX = ScrollTrigger_clamp(0, _maxScroll(target, _horizontal)));\n lastRefreshID = _refreshID;\n },\n removeContentOffset = function removeContentOffset() {\n content._gsap.y = ScrollTrigger_round(parseFloat(content._gsap.y) + scrollFuncY.offset) + \"px\";\n content.style.transform = \"matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, \" + parseFloat(content._gsap.y) + \", 0, 1)\";\n scrollFuncY.offset = scrollFuncY.cacheID = 0;\n },\n ignoreDrag = function ignoreDrag() {\n if (skipTouchMove) {\n requestAnimationFrame(resumeTouchMove);\n\n var offset = ScrollTrigger_round(self.deltaY / 2),\n scroll = scrollClampY(scrollFuncY.v - offset);\n\n if (content && scroll !== scrollFuncY.v + scrollFuncY.offset) {\n scrollFuncY.offset = scroll - scrollFuncY.v;\n\n var y = ScrollTrigger_round((parseFloat(content && content._gsap.y) || 0) - scrollFuncY.offset);\n\n content.style.transform = \"matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, \" + y + \", 0, 1)\";\n content._gsap.y = y + \"px\";\n scrollFuncY.cacheID = _scrollers.cache;\n\n _updateAll();\n }\n\n return true;\n }\n\n scrollFuncY.offset && removeContentOffset();\n skipTouchMove = true;\n },\n tween,\n startScrollX,\n startScrollY,\n onStopDelayedCall,\n onResize = function onResize() {\n // if the window resizes, like on an iPhone which Apple FORCES the address bar to show/hide even if we event.preventDefault(), it may be scrolling too far now that the address bar is showing, so we must dynamically adjust the momentum tween.\n updateClamps();\n\n if (tween.isActive() && tween.vars.scrollY > maxY) {\n scrollFuncY() > maxY ? tween.progress(1) && scrollFuncY(maxY) : tween.resetTo(\"scrollY\", maxY);\n }\n };\n\n content && ScrollTrigger_gsap.set(content, {\n y: \"+=0\"\n }); // to ensure there's a cache (element._gsap)\n\n vars.ignoreCheck = function (e) {\n return _fixIOSBug && e.type === \"touchmove\" && ignoreDrag(e) || scale > 1.05 && e.type !== \"touchstart\" || self.isGesturing || e.touches && e.touches.length > 1;\n };\n\n vars.onPress = function () {\n skipTouchMove = false;\n var prevScale = scale;
1\n scale = ScrollTrigger_round((ScrollTrigger_win.visualViewport && ScrollTrigger_win.visualViewport.scale || 1) / initialScale);\n tween.pause();\n prevScale !== scale && _allowNativePanning(target, scale > 1.01 ? true : normalizeScrollX ? false : \"x\");\n startScrollX = scrollFuncX();\n startScrollY = scrollFuncY();\n updateClamps();\n lastRefreshID = _refreshID;\n };\n\n vars.onRelease = vars.onGestureStart = function (self, wasDragging) {\n scrollFuncY.offset && removeContentOffset();\n\n if (!wasDragging) {\n onStopDelayedCall.restart(true);\n } else {\n _scrollers.cache++; // make sure we're pulling the non-cached value\n // alternate algorithm: durX = Math.min(6, Math.abs(self.velocityX / 800)),\tdur = Math.max(durX, Math.min(6, Math.abs(self.velocityY / 800))); dur = dur * (0.4 + (1 - _power4In(dur / 6)) * 0.6)) * (momentumSpeed || 1)\n\n var dur = resolveMomentumDuration(),\n currentScroll,\n endScroll;\n\n if (normalizeScrollX) {\n currentScroll = scrollFuncX();\n endScroll = currentScroll + dur * 0.05 * -self.velocityX / 0.227; // the constant .227 is from power4(0.05). velocity is inverted because scrolling goes in the opposite direction.\n\n dur *= _clampScrollAndGetDurationMultiplier(scrollFuncX, currentScroll, endScroll, _maxScroll(target, _horizontal));\n tween.vars.scrollX = scrollClampX(endScroll);\n }\n\n currentScroll = scrollFuncY();\n endScroll = currentScroll + dur * 0.05 * -self.velocityY / 0.227; // the constant .227 is from power4(0.05)\n\n dur *= _clampScrollAndGetDurationMultiplier(scrollFuncY, currentScroll, endScroll, _maxScroll(target, _vertical));\n tween.vars.scrollY = scrollClampY(endScroll);\n tween.invalidate().duration(dur).play(0.01);\n\n if (_fixIOSBug && tween.vars.scrollY >= maxY || currentScroll >= maxY - 1) {\n // iOS bug: it'll show the address bar but NOT fire the window \"resize\" event until the animation is done but we must protect against overshoot so we leverage an onUpdate to do so.\n ScrollTrigger_gsap.to({}, {\n onUpdate: onResize,\n duration: dur\n });\n }\n }\n\n onRelease && onRelease(self);\n };\n\n vars.onWheel = function () {\n tween._ts && tween.pause();\n\n if (ScrollTrigger_getTime() - wheelRefresh > 1000) {\n // after 1 second, refresh the clamps otherwise that'll only happen when ScrollTrigger.refresh() is called or for touch-scrolling.\n lastRefreshID = 0;\n wheelRefresh = ScrollTrigger_getTime();\n }\n };\n\n vars.onChange = function (self, dx, dy, xArray, yArray) {\n _refreshID !== lastRefreshID && updateClamps();\n dx && normalizeScrollX && scrollFuncX(scrollClampX(xArray[2] === dx ? startScrollX + (self.startX - self.x) : scrollFuncX() + dx - xArray[1])); // for more precision, we track pointer/touch movement from the start, otherwise it'll drift.\n\n if (dy) {\n scrollFuncY.offset && removeContentOffset();\n var isTouch = yArray[2] === dy,\n y = isTouch ? startScrollY + self.startY - self.y : scrollFuncY() + dy - yArray[1],\n yClamped = scrollClampY(y);\n isTouch && y !== yClamped && (startScrollY += yClamped - y);\n scrollFuncY(yClamped);\n }\n\n (dy || dx) && _updateAll();\n };\n\n vars.onEnable = function () {\n _allowNativePanning(target, normalizeScrollX ? false : \"x\");\n\n ScrollTrigger_ScrollTrigger.addEventListener(\"refresh\", onResize);\n\n ScrollTrigger_addListener(ScrollTrigger_win, \"resize\", onResize);\n\n if (scrollFuncY.smooth) {\n scrollFuncY.target.style.scrollBehavior = \"auto\";\n scrollFuncY.smooth = scrollFuncX.smooth = false;\n }\n\n inputObserver.enable();\n };\n\n vars.onDisable = function () {\n _allowNativePanning(target, true);\n\n ScrollTrigger_removeListener(ScrollTrigger_win, \"resize\", onResize);\n\n ScrollTrigger_ScrollTrigger.removeEventListener(\"refresh\", onResize);\n inputObserver.kill();\n };\n\n vars.lockAxis = vars.lockAxis !== false;\n self = new Observer_Observer(vars);\n self.iOS = _fixIOSBug; // used in the Observer getCachedScroll() function to work around an iOS bug that wreaks havoc with TouchEvent.clientY if we allow scroll to go all the way back to 0.\n\n _fixIOSBug && !scrollFuncY() && scrollFuncY(1); // iOS bug causes event.clientY values to freak out (wildly inaccurate) if the scroll position is exactly 0.\n\n _fixIOSBug && ScrollTrigger_gsap.ticker.add(ScrollTrigger_passThrough); // prevent the ticker from sleeping\n\n onStopDelayedCall = self._dc;\n tween = ScrollTrigger_gsap.to(self, {\n ease: \"power4\",\n paused: true,\n inherit: false,\n scrollX: normalizeScrollX ? \"+=0.1\" : \"+=0\",\n scrollY: \"+=0.1\",\n modifiers: {\n scrollY: _interruptionTracker(scrollFuncY, scrollFuncY(), function () {\n return tween.pause();\n })\n },\n onUpdate: _updateAll,\n onComplete: onStopDelayedCall.vars.onComplete\n }); // we need the modifier to sense if the scroll position is altered outside of the momentum tween (like with a scrollTo tween) so we can pause() it to prevent conflicts.\n\n return self;\n};\n\nScrollTrigger_ScrollTrigger.sort = function (func) {\n return _triggers.sort(func || function (a, b) {\n return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6);\n });\n};\n\nScrollTrigger_ScrollTrigger.observe = function (vars) {\n return new Observer_Observer(vars);\n};\n\nScrollTrigger_ScrollTrigger.normalizeScroll = function (vars) {\n if (typeof vars === \"undefined\") {\n return ScrollTrigger_normalizer;\n }\n\n if (vars === true && ScrollTrigger_normalizer) {\n return ScrollTrigger_normalizer.enable();\n }\n\n if (vars === false) {\n ScrollTrigger_normalizer && ScrollTrigger_normalizer.kill();\n ScrollTrigger_normalizer = vars;\n return;\n }\n\n var normalizer = vars instanceof Observer_Observer ? vars : _getScrollNormalizer(vars);\n ScrollTrigger_normalizer && ScrollTrigger_normalizer.target === normalizer.target && ScrollTrigger_normalizer.kill();\n ScrollTrigger_isViewport(normalizer.target) && (ScrollTrigger_normalizer = normalizer);\n return normalizer;\n};\n\nScrollTrigger_ScrollTrigger.core = {\n // smaller file size way to leverage in ScrollSmoother and Observer\n _getVelocityProp: _getVelocityProp,\
1n _inputObserver: _inputObserver,\n _scrollers: _scrollers,\n _proxies: _proxies,\n bridge: {\n // when normalizeScroll sets the scroll position (ss = setScroll)\n ss: function ss() {\n _lastScrollTime || ScrollTrigger_dispatch(\"scrollStart\");\n _lastScrollTime = ScrollTrigger_getTime();\n },\n // a way to get the _refreshing value in Observer\n ref: function ref() {\n return _refreshing;\n }\n }\n};\nScrollTrigger_getGSAP() && ScrollTrigger_gsap.registerPlugin(ScrollTrigger_ScrollTrigger);\n\n;// CONCATENATED MODULE: ./node_modules/gsap/CSSRulePlugin.js\n/*!\n * CSSRulePlugin 3.12.5\n * https://gsap.com\n *\n * @license Copyright 2008-2024, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license or for\n * Club GSAP members, the agreement issued with that membership.\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar CSSRulePlugin_gsap,\n CSSRulePlugin_coreInitted,\n CSSRulePlugin_win,\n CSSRulePlugin_doc,\n CSSRulePlugin_CSSPlugin,\n CSSRulePlugin_windowExists = function _windowExists() {\n return typeof window !== \"undefined\";\n},\n CSSRulePlugin_getGSAP = function _getGSAP() {\n return CSSRulePlugin_gsap || CSSRulePlugin_windowExists() && (CSSRulePlugin_gsap = window.gsap) && CSSRulePlugin_gsap.registerPlugin && CSSRulePlugin_gsap;\n}
1,\n _checkRegister = function _checkRegister() {\n if (!CSSRulePlugin_coreInitted) {\n CSSRulePlugin_initCore();\n\n if (!CSSRulePlugin_CSSPlugin) {\n console.warn(\"Please gsap.registerPlugin(CSSPlugin, CSSRulePlugin)\");\n }\n }\n\n return CSSRulePlugin_coreInitted;\n},\n CSSRulePlugin_initCore = function _initCore(core) {\n CSSRulePlugin_gsap = core || CSSRulePlugin_getGSAP();\n\n if (CSSRulePlugin_windowExists()) {\n CSSRulePlugin_win = window;\n CSSRulePlugin_doc = document;\n }\n\n if (CSSRulePlugin_gsap) {\n CSSRulePlugin_CSSPlugin = CSSRulePlugin_gsap.plugins.css;\n\n if (CSSRulePlugin_CSSPlugin) {\n CSSRulePlugin_coreInitted = 1;\n }\n }\n};\n\nvar CSSRulePlugin = {\n version: \"3.12.5\",\n name: \"cssRule\",\n init: function init(target, value, tween, index, targets) {\n if (!_checkRegister() || typeof target.cssText === \"undefined\") {\n return false;\n }\n\n var div = target._gsProxy = target._gsProxy || CSSRulePlugin_doc.createElement(\"div\");\n\n this.ss = target;\n this.style = div.style;\n div.style.cssText = target.cssText;\n CSSRulePlugin_CSSPlugin.prototype.init.call(this, div, value, tween, index, targets); //we just offload all the work to the regular CSSPlugin and then copy the cssText back over to the rule in the render() method. This allows us to have all of the updates to CSSPlugin automatically flow through to CSSRulePlugin instead of having to maintain both\n },\n render: function render(ratio, data) {\n var pt = data._pt,\n style = data.style,\n ss = data.ss,\n i;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n\n i = style.length;\n\n while (--i > -1) {\n ss[style[i]] = style[style[i]];\n }\n }
1,\n getRule: function getRule(selector) {\n _checkRegister();\n\n var ruleProp = CSSRulePlugin_doc.all ? \"rules\" : \"cssRules\",\n styleSheets = CSSRulePlugin_doc.styleSheets,\n i = styleSheets.length,\n pseudo = selector.charAt(0) === \":\",\n j,\n curSS,\n cs,\n a;\n selector = (pseudo ? \"\" : \",\") + selector.split(\"::\").join(\":\").toLowerCase() + \",\"; //note: old versions of IE report tag name selectors as upper case, so we just change everything to lowercase.\n\n if (pseudo) {\n a = [];\n }\n\n while (i--) {\n //Firefox may throw insecure operation errors when css is loaded from other domains, so try/catch.\n try {\n curSS = styleSheets[i][ruleProp];\n\n if (!curSS) {\n continue;\n }\n\n j = curSS.length;\n } catch (e) {\n console.warn(e);\n continue;\n }\n\n while (--j > -1) {\n cs = curSS[j];\n\n if (cs.selectorText && (\",\" + cs.selectorText.split(\"::\").join(\":\").toLowerCase() + \",\").indexOf(selector) !== -1) {\n //note: IE adds an extra \":\" to pseudo selectors, so .myClass:after becomes .myClass::after, so we need to strip the extra one out.\n if (pseudo) {\n a.push(cs.style);\n } else {\n return cs.style;\n }\n }\n }\n }\n\n return a;\n },\n register: CSSRulePlugin_initCore\n};\nCSSRulePlugin_getGSAP() && CSSRulePlugin_gsap.registerPlugin(CSSRulePlugin);\n\n;// CONCATENATED MODULE: ./node_modules/gsap/ScrollToPlugin.js\n/*!\n * ScrollToPlugin 3.12.5\n * https://gsap.com\n *\n * @license Copyright 2008-2024, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license or for\n * Club GSAP members, the agreement issued with that membership.\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar ScrollToPlugin_gsap,\n ScrollToPlugin_coreInitted,\n _window,\n ScrollToPlugin_docEl,\n ScrollToPlugin_body,\n ScrollToPlugin_toArray,\n ScrollToPlugin_config,\n ScrollToPlugin_ScrollTrigger,\n ScrollToPlugin_windowExists = function _windowExists() {\n return typeof window !== \"undefined\";\n},\n ScrollToPlugin_getGSAP = function _getGSAP() {\n return ScrollToPlugin_gsap || ScrollToPlugin_windowExists() && (ScrollToPlugin_gsap = window.gsap) && ScrollToPlugin_gsap.registerPlugin && ScrollToPlugin_gsap;\n},\n ScrollToPlugin_isString = function _isString(value) {\n return typeof value === \"string\";\n},\n ScrollToPlugin_isFunction = function _isFunction(value) {\n return typeof value === \"function\";\n},\n _max = function _max(element, axis) {\n var dim = axis === \"x\" ? \"Width\" : \"Height\",\n scroll = \"scroll\" + dim,\n client = \"client\" + dim;\n return element === _window || element === ScrollToPlugin_docEl || element === ScrollToPlugin_body ? Math.max(ScrollToPlugin_docEl[scroll], ScrollToPlugin_body[scroll]) - (_window[\"inner\" + dim] || ScrollToPlugin_docEl[client] || ScrollToPlugin_body[client]) : element[scroll] - element[\"offset\" + dim];\n},\n _buildGetter = function _buildGetter(e, axis) {\n //pass in an element and an axis (\"x\" or \"y\") and it'll return a getter function for the scroll position of that element (like scrollTop or scrollLeft, although if the element is the window, it'll use the pageXOffset/pageYOffset or the documentElement's scrollTop/scrollLeft or document.body's. Basically this streamlines things and makes a very fast getter across browsers.\n var p = \"scroll\" + (axis === \"x\" ? \"Left\" : \"Top\");\n\n if (e === _window) {\n if (e.pageXOffset != null) {\n p = \"page\" + axis.toUpperCase() + \"Offset\";\n } else {\n e = ScrollToPlugin_docEl[p] != null ? ScrollToPlugin_docEl : ScrollToPlugin_body;\n }\n }\n\n return function () {\n return e[p];\n };\n},\n _clean = function _clean(value, index, target, targets) {\n ScrollToPlugin_isFunction(value) && (value = value(index, target, targets));\n\n if (typeof value !== \"object\") {\n return ScrollToPlugin_isString(value) && value !== \"max\" && value.charAt(1) !== \"=\" ? {\n x: value,\n y: value\
1n } : {\n y: value\n }; //if we don't receive an object as the parameter, assume the user intends \"y\".\n } else if (value.nodeType) {\n return {\n y: value,\n x: value\n };\n } else {\n var result = {},\n p;\n\n for (p in value) {\n result[p] = p !== \"onAutoKill\" && ScrollToPlugin_isFunction(value[p]) ? value[p](index, target, targets) : value[p];\n }\n\n return result;\n }\n},\n _getOffset = function _getOffset(element, container) {\n element = ScrollToPlugin_toArray(element)[0];\n\n if (!element || !element.getBoundingClientRect) {\n return console.warn(\"scrollTo target doesn't exist. Using 0\") || {\n x: 0,\n y: 0\n };\n }\n\n var rect = element.getBoundingClientRect(),\n isRoot = !container || container === _window || container === ScrollToPlugin_body,\n cRect = isRoot ? {\n top: ScrollToPlugin_docEl.clientTop - (_window.pageYOffset || ScrollToPlugin_docEl.scrollTop || ScrollToPlugin_body.scrollTop || 0),\n left: ScrollToPlugin_docEl.clientLeft - (_window.pageXOffset || ScrollToPlugin_docEl.scrollLeft || ScrollToPlugin_body.scrollLeft || 0)\n } : container.getBoundingClientRect(),\n offsets = {\n x: rect.left - cRect.left,\n y: rect.top - cRect.top\n };\n\n if (!isRoot && container) {\n //only add the current scroll position if it's not the window/body.\n offsets.x += _buildGetter(container, \"x\")();\n offsets.y += _buildGetter(container, \"y\")();\n }\n\n return offsets;\n},\n _parseVal = function _parseVal(value, target, axis, currentVal, offset) {\n return !isNaN(value) && typeof value !== \"object\" ? parseFloat(value) - offset : ScrollToPlugin_isString(value) && value.charAt(1) === \"=\" ? parseFloat(value.substr(2)) * (value.charAt(0) === \"-\" ? -1 : 1) + currentVal - offset : value === \"max\" ? _max(target, axis) - offset : Math.min(_max(target, axis), _getOffset(value, target)[axis] - offset);\n},\n ScrollToPlugin_initCore = function _initCore() {\n ScrollToPlugin_gsap = ScrollToPlugin_getGSAP();\n\n if (ScrollToPlugin_windowExists() && ScrollToPlugin_gsap && typeof document !== \"undefined\" && document.body) {\n _window = window;\n ScrollToPlugin_body = document.body;\n ScrollToPlugin_docEl = document.documentElement;\n ScrollToPlugin_toArray = ScrollToPlugin_gsap.utils.toArray;\n ScrollToPlugin_gsap.config({\n autoKillThreshold: 7\n });\n ScrollToPlugin_config = ScrollToPlugin_gsap.config();\n ScrollToPlugin_coreInitted = 1;\n }\n};\n\nvar ScrollToPlugin = {\n version: \"3.12.5\",\n name: \"scrollTo\",\n rawVars: 1,\n register: function register(core) {\n ScrollToPlugin_gsap = core;\n\n ScrollToPlugin_initCore();\n },\n init: function init(target, value, tween, index, targets) {\n ScrollToPlugin_coreInitted || ScrollToPlugin_initCore();\n var data = this,\n snapType = ScrollToPlugin_gsap.getProperty(target, \"scrollSnapType\");\n data.isWin = target === _window;\n data.target = target;\n data.tween = tween;\n value = _clean(value, index, target, targets);\n data.vars = value;\n data.autoKill = !!value.autoKill;\n data.getX = _buildGetter(target, \"x\");\n data.getY = _buildGetter(target, \"y\");\n data.x = data.xPrev = data.getX();\n data.y = data.yPrev = data.getY();\n ScrollToPlugin_ScrollTrigger || (ScrollToPlugin_ScrollTrigger = ScrollToPlugin_gsap.core.globals().ScrollTrigger);\n ScrollToPlugin_gsap.getProperty(target, \"scrollBehavior\") === \"smooth\" && ScrollToPlugin_gsap.set(target, {\n scrollBehavior: \"auto\"\n });\n\n if (snapType && snapType !== \"none\") {\n // disable scroll snapping to avoid strange behavior\n data.snap = 1;\n data.snapInline = target.style.scrollSnapType;\n target.style.scrollSnapType = \"none\";\n }\n\n if (value.x != null) {\n data.add(data, \"x\", data.x, _parseVal(value.x, target, \"x\", data.x, value.offsetX || 0), index, targets);\n\n data._props.push(\"scrollTo_x\");\n } else {\n data.skipX = 1;\n }\n\n if (value.y != null) {\n data.add(data, \"y\", data.y, _parseVal(value.y, target, \"y\", data.y, value.offsetY || 0
1), index, targets);\n\n data._props.push(\"scrollTo_y\");\n } else {\n data.skipY = 1;\n }\n },\n render: function render(ratio, data) {\n var pt = data._pt,\n target = data.target,\n tween = data.tween,\n autoKill = data.autoKill,\n xPrev = data.xPrev,\n yPrev = data.yPrev,\n isWin = data.isWin,\n snap = data.snap,\n snapInline = data.snapInline,\n x,\n y,\n yDif,\n xDif,\n threshold;\n\n while (pt) {\n pt.r(ratio, pt.d);\n pt = pt._next;\n }\n\n x = isWin || !data.skipX ? data.getX() : xPrev;\n y = isWin || !data.skipY ? data.getY() : yPrev;\n yDif = y - yPrev;\n xDif = x - xPrev;\n threshold = ScrollToPlugin_config.autoKillThreshold;\n\n if (data.x < 0) {\n //can't scroll to a position less than 0! Might happen if someone uses a Back.easeOut or Elastic.easeOut when scrolling back to the top of the page (for example)\n data.x = 0;\n }\n\n if (data.y < 0) {\n data.y = 0;\n }\n\n if (autoKill) {\n //note: iOS has a bug that throws off the scroll by several pixels, so we need to check if it's within 7 pixels of the previous one that we set instead of just looking for an exact match.\n if (!data.skipX && (xDif > threshold || xDif < -threshold) && x < _max(target, \"x\")) {\n data.skipX = 1; //if the user scrolls separately, we should stop tweening!\n }\n\n if (!data.skipY && (yDif > threshold || yDif < -threshold) && y < _max(target, \"y\")) {\n data.skipY = 1; //if the user scrolls separately, we should stop tweening!\n }\n\n if (data.skipX && data.skipY) {\n tween.kill();\n data.vars.onAutoKill && data.vars.onAutoKill.apply(tween, data.vars.onAutoKillParams || []);\n }\n }\n\n if (isWin) {\n _window.scrollTo(!data.skipX ? data.x : x, !data.skipY ? data.y : y);\n } else {\n data.skipY || (target.scrollTop = data.y);\n data.skipX || (target.scrollLeft = data.x);\n }\n\n if (snap && (ratio === 1 || ratio === 0)) {\n y = target.scrollTop;\n x = target.scrollLeft;\n snapInline ? target.style.scrollSnapType = snapInline : target.style.removeProperty(\"scroll-snap-type\");\n target.scrollTop = y + 1; // bug in Safari causes the element to totally reset its scroll position when scroll-snap-type changes, so we need to set it to a slightly different value and then back again to work around this bug.\n\n target.scrollLeft = x + 1;\n target.scrollTop = y;\n target.scrollLeft = x;\n }\n\n data.xPrev = data.x;\n data.yPrev = data.y;\n ScrollToPlugin_ScrollTrigger && ScrollToPlugin_ScrollTrigger.update(
1);\n },\n kill: function kill(property) {\n var both = property === \"scrollTo\",\n i = this._props.indexOf(property);\n\n if (both || property === \"scrollTo_x\") {\n this.skipX = 1;\n }\n\n if (both || property === \"scrollTo_y\") {\n this.skipY = 1;\n }\n\n i > -1 && this._props.splice(i, 1);\n return !this._props.length;\n }\n};\nScrollToPlugin.max = _max;\nScrollToPlugin.getOffset = _getOffset;\nScrollToPlugin.buildGetter = _buildGetter;\nScrollToPlugin_getGSAP() && ScrollToPlugin_gsap.registerPlugin(ScrollToPlugin);\n\n;// CONCATENATED MODULE: ./src/js/bundle.js\n/* provided dependency */ var bundle_$ = __webpack_require__(692);\n\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\nfunction _iterableToArray(iter) { if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter); }\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar swiper, swiper2, swiper3, swiper4, swiper5, swiper6, swiper7, swiper8, topbar;\nvar mm;\nvar imagesLoaded = __webpack_require__(943);\ngsapWithCSS.registerPlugin(ScrollTrigger_ScrollTrigger, ScrollToPlugin, CSSRulePlugin);\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n imagesLoaded('body', {\n background: true\n }, function () {\n var menuToggle = document.querySelector('.menu-toggle');\n var menu = document.getElementById('menuComparsa');\n var body = document.querySelector('body');\n var background = document.getElementById('background');\n var close = document.getElementById('closeMenu');\n var elemento = document.querySelector('.oldStagione');\n var lenis = new Lenis({\n duration: 1.2,\n easing: function easing(t) {\n return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);\n },\n direction: \"vertical\",\n gestureDirection: \"vertical\",\n smooth: true,\n smoothTouch: false,\n touchMultiplier: 2\n });\n function raf(time) {\n lenis.raf(time);\n lenis2.raf(time);\n requestAnimationFrame(raf);\n }\n requestAnimationFrame(raf);\n if (bundle_$('#loading').length) {\n ScrollTrigger_ScrollTrigger.create({\n trigger: '#loading',\n start: \"top 80%\",\n once: true,\n onEnter: function onEnter(self) {\n var newURL = window.location.protocol + \"//\" + window.location.host + \"/ajax-news/\";\n bundle_$.ajax({\n type: \"POST\",\n url: newURL,\n cache: true,\n data: {\n last: 21\n },\n beforeSend: function beforeSend() {},\n success: function success(e) {\n var a = jQuery.parseJSON(e);\n }\n });\n }\n });\n }\n mm = gsapWithCSS.matchMedia();\n var parts = window.location.search.substr(1).split(\"&\");\n var $_GET = {};\n for (var i = 0; i < parts.length; i++) {\n var temp = parts[i].split(\"=\");\n $_GET[decodeURIComponent(temp[0])] = decodeURIComponent(temp[1]);\n }\n var queryString = window.location.search;
1\n var urlParams = new URLSearchParams(queryString);\n var type = urlParams.get('type');\n checkresize();\n if (type == 'michelin') {\n swiper7 = new core(\".cSwiper\", {\n effect: 'fade',\n autoHeight: true,\n initialSlide: 1,\n fadeEffect: {\n crossFade: true\n },\n allowTouchMove: false,\n spaceBetween: 0,\n freeMode: false\n });\n var topbar3 = document.querySelectorAll('.topbar3 a');\n for (var i = 0; i < topbar3.length; i++) {\n topbar3[i].addEventListener('click', function (event) {\n swiper7.slideTo(event.target.getAttribute('href'), 350, false);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper7.on('slideChange', function (event) {\n topbar3.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n } else if (type == 'team') {\n swiper7 = new core(\".cSwiper\", {\n effect: 'fade',\n autoHeight: true,\n initialSlide: 2,\n fadeEffect: {\n crossFade: true\n },\n allowTouchMove: false,\n spaceBetween: 0,\n freeMode: false\n });\n var topbar3 = document.querySelectorAll('.topbar3 a');\n for (var i = 0; i < topbar3.length; i++) {\n topbar3[i].addEventListener('click', function (event) {\n swiper7.slideTo(event.target.getAttribute('href'), 350, false);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper7.on('slideChange', function (event) {\n topbar3.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n } else {\n if (document.getElementById('slideClassifica')) {\n swiper7 = new core(\".cSwiper\", {\n effect: 'fade',\n autoHeight: true,\n fadeEffect: {\n crossFade: true\n },\n allowTouchMove: false,\n spaceBetween: 0,\n freeMode: false\n });\n var topbar3 = document.querySelectorAll('.topbar3 a');\n for (var i = 0; i < topbar3.length; i++) {\n topbar3[i].addEventListener('click', function (event) {\n swiper7.slideTo(event.target.getAttribute('href'), 350, false);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper7.on('slideChange', function (event) {\n topbar3.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n }\n lightgallery_es5(document.getElementById('customize-thumbnails-gallery'), {\n // Add a custom class to apply style only for the particular gallery\n addClass: 'lg-custom-thumbnails',\n // Remove the starting animations.\n // This can be done by overriding CSS as well\n appendThumbnailsTo: '.lg-outer',\n animateThumb: false,\n allowMediaOverlap: true,\n download: false\n });\n if ($_GET['pilota']) {\n var accordionlist = document.querySelectorAll('#accordionExample .accordion-collapse');\n for (var i = 0; i < accordionlist.length; i++) {\n accordionlist[i].classList.remove('show');\n }\n var questo = document.querySelector('#' + $_GET['pilota'] + ' .accordion-collapse');\n questo.classList.add('show');\n setTimeout(function () {\n var posy = document.querySelector('#' + $_GET['pilota']).getBoundingClientRect().top - 81;\n window.scrollTo(0, posy);\n }, 100);\n }\n if ($_GET['pac']) {\n var posy = document.querySelector('#pacchetti').getBoundingClientRect().top - 81;\n setTimeout(function () {\n window.scrollTo(0, posy);\n }, 100);\n }\n if (document.getElementById('goto')) {\n var _goto = document.getElementById('goto');\n var posy = document.querySelector('#pacchetti').getBoundingClientRect().top - 81;\n _goto.addEventListener('click', function (event) {\n window.scrollTo(0, posy);\n event.preventDefault();\n });\n }
1\n if (document.querySelectorAll('.light-gallery')) {\n var galleryPiloti = document.querySelectorAll('.light-gallery');\n for (var j = 0; j < galleryPiloti.length; ++j) {\n lightgallery_es5(galleryPiloti[j], {\n // Add a custom class to apply style only for the particular gallery\n addClass: 'lg-custom-thumbnails',\n // Remove the starting animations.\n // This can be done by overriding CSS as well\n appendThumbnailsTo: '.lg-outer',\n animateThumb: false,\n allowMediaOverlap: true,\n download: false\n });\n }\n var swiperGP = new core(\".gpSwiper\", {\n slidesPerView: 3,\n spaceBetween: 8,\n freeMode: true,\n scrollbar: {\n el: '.swiper-scrollbar',\n draggable: true\n }\n });\n }\n if (!!document.querySelector('.riga .date')) {\n var righe = document.querySelectorAll('.riga .date');\n for (var j = 0; j < righe.length; ++j) {\n var text = righe[j].innerHTML;\n var old_html = text.split(\" \");\n var new_html = \"\";\n for (var i = 0; i < old_html.length; i++) {\n new_html = new_html + \" <span class='text-\" + i + \"'>\" + old_html[i] + \"</span>\";\n righe[j].innerHTML = new_html;\n }\n }\n }\n var lenis2 = new Lenis({\n wrapper: menu,\n duration: 1.2,\n easing: function easing(t) {\n return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);\n },\n direction: \"vertical\",\n gestureDirection: \"vertical\",\n smooth: true,\n smoothTouch: false,\n touchMultiplier: 2\n });\n menuToggle.addEventListener('click', function () {\n body.classList.toggle('active');
1\n gsapWithCSS.to(menu, {\n right: \"0px\",\n duration: .5,\n ease: \"expo.inOut\",\n onComplete: function onComplete() {\n menu.classList.toggle('active');\n menuToggle.querySelector('.line-1').classList.toggle('active');\n menuToggle.querySelector('.line-2').classList.toggle('active');\n }\n });\n if (!background.classList.contains('active')) {\n gsapWithCSS.to(background, {\n opacity: .2,\n visibility: \"visible\",\n display: \"block\",\n duration: .5,\n ease: \"expo.inOut\",\n onComplete: function onComplete() {\n background.classList.add('active');\n lenis.stop();\n }\n });\n } else {\n gsapWithCSS.to(background, {\n opacity: 0,\n visibility: \"hidden\",\n display: \"none\",\n duration: .5,\n ease: \"expo.inOut\",\n onComplete: function onComplete() {\n background.classList.remove('active');\n lenis.start();\n }\n });\n }\n });\n close.addEventListener('click', function (event) {\n event.preventDefault();\n body.classList.toggle('active');\n gsapWithCSS.to(menu, {\n right: \"-480px\",\n duration: .5,\n ease: \"expo.inOut\",\n onComplete: function onComplete() {\n menu.classList.toggle('active');\n menuToggle.querySelector('.line-1').classList.toggle('active');\n menuToggle.querySelector('.line-2').classList.toggle('active');\n }\n });\n if (!background.classList.contains('active')) {\n gsapWithCSS.to(background, {\n opacity: .2,\n visibility: \"visible\",\n display: \"block\",\n duration: .5,\n ease: \"expo.inOut\",\n onComplete: function onComplete() {\n background.classList.add('active');\n lenis.stop();\n }\n });\n } else {\n gsapWithCSS.to(background, {\n opacity: 0,\n duration: .5,\n ease: \"expo.inOut\",\n onComplete: function onComplete() {\n gsapWithCSS.set(background, {\n visibility: \"hidden\",\n display: \"none\"\n });\n background.classList.remove('active');\n lenis.start();\n }\n });\n }\n });\n background.addEventListener('click', function (event) {\n event.preventDefault();\n body.classList.toggle('active');\n gsapWithCSS.to(menu, {\n right: \"-480px\",\n duration: .5,\n ease: \"expo.inOut\",\n onComplete: function onComplete() {\n menu.classList.toggle('active');\n menuToggle.querySelector('.line-1').classList.toggle('active');\n menuToggle.querySelector('.line-2').classList.toggle('active');\n }\n });\n if (!background.classList.contains('active')) {\n gsapWithCSS.to(background, {\n opacity: .2,\n visibility: \"visible\",\n display: \"block\",\n duration: .5,\n ease: \"expo.inOut\",\n onComplete: function onComplete() {\n background.classList.add('active');\n lenis.stop();\n }\n });\n } else {\n gsapWithCSS.to(background, {\n opacity: 0,\n duration: .5,\n ease: \"expo.inOut\",\n onComplete: function onComplete() {\n gsapWithCSS.set(background, {\n visibility: \"hidden\",\n display: \"none\"\n });\n background.classList.remove('active');\n lenis.start();\n }\n });\n }\n });\n if (elemento) {\n var listaAnni = _toConsumableArray(elemento.querySelectorAll('.oldStagione ul li a'));\n listaAnni.forEach(function (elem) {\n elem.addEventListener('click', function (e) {\n var current = _toConsumableArray(elemento.querySelectorAll('.oldStagione ul li'));\n current.forEach(function (el) {\n el.classList.remove('current');\n });\n e.target.closest('li').classList.add('current');\n if (e.target.innerHTML == '2026') {\n window.location.href = window.location.protocol + \"//\" + window.location.host + \"/classifiche\";\n } else {\n var newURL = window.location.protocol + \"//\" + window.location.host + \"/wp-content/themes/pcci2023/include/ajax-classifiche.php\";\n bundle_$.ajax({\n type: \"POST\",\n url: newURL,\n cache: true,\n data: {\n anno: e.target.innerHTML\n },\n beforeSend: function beforeSend() {\n document.querySelector(\".topbar3\").innerHTML = \"\";\n document.querySelector(\".risultati\").innerHTML = '<div id=\"cssload-wrapper\"><div class=\"cssload-loader\">
1<div class=\"cssload-line\"></div> <div class=\"cssload-line\"></div><div class=\"cssload-line\"></div><div class=\"cssload-line\"></div><div class=\"cssload-line\"></div><div class=\"cssload-line\"></div><div class=\"cssload-subline\"></div><div class=\"cssload-subline\"></div><div class=\"cssload-subline\"></div><div class=\"cssload-subline\"></div><div class=\"cssload-subline\"></div><div class=\"cssload-loader-circle-1\"><div class=\"cssload-loader-circle-2\"></div></div><div class=\"cssload-needle\"></div><div class=\"cssload-loading\">loading</div></div></div>';\n swiper7.destroy();\n },\n success: function success(e) {\n document.querySelector(\".risultati\").innerHTML = '';\n var a = jQuery.parseJSON(e);\n /*a.lista.forEach((item, index) => {\n var valore;\n if(item == 'assoluta'){ valore = \"Assoluta\"};\n if(item == 'michelin'){ valore = \"Michelin Cup\"};\n if(item == 'silver'){ valore = \"Silver\"};\n if(item == 'classe'){ valore = \"Classe MY'07\"};\n if(item == 'teams'){ valore = \"Team\"};\n if(index == 0) {\n document.querySelector(\".topbar3\").innerHTML += \"<a href='\" + index + \"' class='active'>\" + valore + \"</a>\";\n }
1else{\n document.querySelector(\".topbar3\").innerHTML += \"<a href='\" + index + \"'>\" + valore + \"</a>\";\n }\n \n });*/\n document.querySelector(\"#classifiche .label\").remove();\n document.querySelector(\".risultati\").innerHTML += a.classifica;\n swiper7 = new core(\".cSwiper\", {\n effect: 'fade',\n autoHeight: true,\n fadeEffect: {\n crossFade: true\n },\n allowTouchMove: false,\n spaceBetween: 0,\n freeMode: false\n });\n var topbar3 = document.querySelectorAll('.topbar3 a');\n for (var i = 0; i < topbar3.length; i++) {\n topbar3[i].addEventListener('click', function (event) {\n swiper7.slideTo(event.target.getAttribute('href'), 350, false);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper7.on('slideChange', function (event) {\n topbar3.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n });\n }\n });\n });\n }\n });\n});\nwindow.addEventListener(\"resize\", checkresize);\nfunction checkresize() {\n mm = gsapWithCSS.matchMedia();\n mm.add(\"(min-width: 1600px)\", function () {\n if (document.querySelector('.mySwiper')) {\n if (swiper) {\n swiper.destroy();\n }\n swiper = new core(\".mySwiper\", {\n slidesPerView: 2.4,\n grabCursor: true,\n spaceBetween: 32,\n freeMode: false\n });\n }\n if (document.querySelector('.newsSwiper')) {\n if (swiper3) {\n swiper3.destroy();\n }\n swiper3 = new core(\".newsSwiper\", {\n slidesPerView: 4,\n spaceBetween: 32,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.campSwiper')) {\n var label = document.querySelector('.campSwiper .active').getAttribute('data-src');\n if (swiper5) {\n swiper5.destroy();\n }\n swiper5 = new core(\".campSwiper\", {\n slidesPerView: 5,\n spaceBetween: 32,\n initialSlide: label,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.garaSwiper')) {\n if (swiper6) {\n swiper6.destroy();\n }\n swiper6 = new core(\".garaSwiper\", {\n slidesPerView: 1,\n autoHeight: true,\n allowTouchMove: false,\n spaceBetween: 0,\n freeMode: false\n });\n var topbar2 = document.querySelectorAll('.topbar2 a');\n for (var i = 0; i < topbar2.length; i++) {\n topbar2[i].addEventListener('click', function (event) {\n swiper6.slideTo(event.target.getAttribute('href'), 350, false);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper6.on('slideChange', function (event) {\n topbar2.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.querySelector('.teamSwiper')) {\n if (swiper8) {\n swiper8.destroy();\n }\n swiper8 = new core(\".teamSwiper\", {\n slidesPerView: 5,\n spaceBetween: 32,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.claSwiper')) {\n if (swiper2) {\n swiper2.destroy();\n }\n swiper2 = new core(\".claSwiper\", {\n slidesPerView: 2,\n allowTouchMove: false,\n spaceBetween: 32,\n freeMode: false\n });\n topbar = document.querySelectorAll('.topbar a');\n for (var i = 0; i < topbar.length;
1 i++) {\n topbar[i].addEventListener('click', function (event) {\n swiper2.slideTo(event.target.getAttribute('href'), 350);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper2.on('slideChange', function (event) {\n topbar.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.querySelector('.partnerSwiper')) {\n if (swiper4) {\n swiper4.destroy();\n }\n swiper4 = new core(\".partnerSwiper\", {\n slidesPerView: 6,\n spaceBetween: 32,\n freeMode: false,\n allowTouchMove: false,\n autoplay: {\n delay: 2500,\n disableOnInteraction: false\n }\n });\n }\n });\n mm.add(\"(min-width: 1280px) and (max-width: 1599px)\", function () {\n if (document.getElementById('slideGare')) {\n if (swiper) {\n swiper.destroy();\n }\n swiper = new core(\".mySwiper\", {\n slidesPerView: 1.8,\n grabCursor: true,\n spaceBetween: 32,\n freeMode: false\n });\n }\n if (document.getElementById('slideNews')) {\n if (swiper3) {\n swiper3.destroy();\n }\n swiper3 = new core(\".newsSwiper\", {\n slidesPerView: 3,\n spaceBetween: 32,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.campSwiper')) {\n var label = document.querySelector('.campSwiper .active').getAttribute('data-src');\n if (swiper5) {\n swiper5.destroy();\n }\n swiper5 = new core(\".campSwiper\", {\n slidesPerView: 3,\n spaceBetween: 32,\n initialSlide: label,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.getElementById('slideGara')) {\n if (swiper6) {\n swiper6.destroy();\n }\n swiper6 = new core(\".garaSwiper\", {\n slidesPerView: 1,\n autoHeight: true,\n allowTouchMove: false,\n spaceBetween: 0,\n freeMode: false\n });\n var topbar2 = document.querySelectorAll('.topbar2 a');\n for (var i = 0; i < topbar2.length; i++) {\n topbar2[i].addEventListener('click', function (event) {\n swiper6.slideTo(event.target.getAttribute('href'), 350, false);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper6.on('slideChange', function (event) {\n topbar2.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.getElementById('slideTeams')) {\n if (swiper8) {\n swiper8.destroy();\n }\n swiper8 = new core(\".teamSwiper\", {\n slidesPerView: 3,\n spaceBetween: 32,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.getElementById('slideClassifiche')) {\n if (swiper2) {\n swiper2.destroy();\n }\n swiper2 = new core(\".claSwiper\", {\n slidesPerView: 2,\n allowTouchMove: false,\n spaceBetween: 32,\n freeMode: false\n });\n topbar = document.querySelectorAll('.topbar a');\n for (var i = 0; i < topbar.length; i++) {\n topbar[i].addEventListener('click', function (event) {\n swiper2.slideTo(event.target.getAttribute('href'), 350);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper2.on('slideChange', function (event) {\n topbar.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.querySelector('.partnerSwiper')) {\n if (swiper4) {\n swiper4.destroy();\n }\n swiper4 = new core(\".partnerSwiper\", {\n slidesPerView: 6,\n spaceBetween: 32,\n freeMode: false,\n allowTouchMove: false,\n autoplay: {\n delay: 2500,\n disableOnInteraction: false\n }\n });\n }\n });\n mm.add(\"(max-width: 1279px) and (min-width: 533px) and (orientation: portrait)\", function () {\n if (document.querySelector('.mySwiper')) {\n if (swiper) {\n swiper.destroy();\n }\n swiper = new core(\".mySwiper\", {\n slidesPerView: 1,\n grabCursor: true,\n spaceBetween: 0,\n freeMode: false\n });\n }\n if (document.querySelector('.claSwiper')) {\n if (swiper2) {\n swiper2.destroy();\n }\n swiper2 = new core(\".claSwiper\", {\n slidesPerView: 1,\n allowTouchMove: false,\n spaceBetween: 32,\n freeMode: false\n });\n topbar = document.querySelectorAll('.topbar a');\n for (var i = 0; i < topbar.length;
1 i++) {\n topbar[i].addEventListener('click', function (event) {\n swiper2.slideTo(event.target.getAttribute('href'), 350);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper2.on('slideChange', function (event) {\n topbar.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.querySelector('.newsSwiper')) {\n if (swiper3) {\n swiper3.destroy();\n }\n swiper3 = new core(\".newsSwiper\", {\n slidesPerView: 2,\n spaceBetween: 32,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.partnerSwiper')) {\n if (swiper4) {\n swiper4.destroy();\n }\n swiper4 = new core(\".partnerSwiper\", {\n slidesPerView: 3,\n spaceBetween: 32,\n freeMode: false,\n allowTouchMove: false,\n autoplay: {\n delay: 2500,\n disableOnInteraction: false\n }\n });\n }\n if (document.querySelector('.campSwiper')) {\n var label = document.querySelector('.campSwiper .active').getAttribute('data-src');\n if (swiper5) {\n swiper5.destroy();\n }\n swiper5 = new core(\".campSwiper\", {\n slidesPerView: 2,\n spaceBetween: 32,\n initialSlide: label,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.garaSwiper')) {\n if (swiper6) {\n swiper6.destroy();\n }\n swiper6 = new core(\".garaSwiper\", {\n slidesPerView: 1,\n autoHeight: true,\n allowTouchMove: false,\n spaceBetween: 0,\n freeMode: false\n });\n var topbar2 = document.querySelectorAll('.topbar2 a');\n for (var i = 0; i < topbar2.length; i++) {\n topbar2[i].addEventListener('click', function (event) {\n swiper6.slideTo(event.target.getAttribute('href'), 350, false);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper6.on('slideChange', function (event) {\n topbar2.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.querySelector('.teamSwiper')) {\n if (swiper8) {\n swiper8.destroy();\n }\n swiper8 = new core(\".teamSwiper\", {\n slidesPerView: 2,\n spaceBetween: 32,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n });\n mm.add(\"(max-width: 1366px) and (min-width: 533px) and (orientation: landscape)\", function () {\n if (document.querySelector('.mySwiper')) {\n if (swiper) {\n swiper.destroy();\n }\n swiper = new core(\".mySwiper\", {\n slidesPerView: 1.5,\n grabCursor: true,\n spaceBetween: 32,\n freeMode: false\n });\n }\n if (document.querySelector('.claSwiper')) {\n if (swiper2) {\n swiper2.destroy();\n }\n swiper2 = new core(\".claSwiper\", {\n slidesPerView: 1.5,\n allowTouchMove: false,\n spaceBetween: 32,\n freeMode: false\n });\n topbar = document.querySelectorAll('.topbar a');\n for (var i = 0; i < topbar.length; i++) {\n topbar[i].addEventListener('click', function (event) {\n swiper2.slideTo(event.target.getAttribute('href'), 350);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper2.on('slideChange', function (event) {\n topbar.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.querySelector('.newsSwiper')) {\n if (swiper3) {\n swiper3.destroy();\n }\n swiper3 = new core(\".newsSwiper\", {\n slidesPerView: 2,\n spaceBetween: 32,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.partnerSwiper')) {\n if (swiper4) {\n swiper4.destroy();\n }\n swiper4 = new core(\".partnerSwiper\", {\n slidesPerView: 5,\n spaceBetween: 32,\n freeMode: false,\n allowTouchMove: false,\n autoplay: {\n delay: 2500,\n disableOnInteraction: false\n }\n });\n }\n if (document.querySelector('.campSwiper')) {\n var label = document.querySelector('.campSwiper .active').getAttribute('data-src');
1\n if (swiper5) {\n swiper5.destroy();\n }\n swiper5 = new core(\".campSwiper\", {\n slidesPerView: 2,\n spaceBetween: 32,\n initialSlide: label,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.garaSwiper')) {\n if (swiper6) {\n swiper6.destroy();\n }\n swiper6 = new core(\".garaSwiper\", {\n slidesPerView: 1,\n autoHeight: true,\n allowTouchMove: false,\n spaceBetween: 0,\n freeMode: false\n });\n var topbar2 = document.querySelectorAll('.topbar2 a');\n for (var i = 0; i < topbar2.length; i++) {\n topbar2[i].addEventListener('click', function (event) {\n swiper6.slideTo(event.target.getAttribute('href'), 350, false);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper6.on('slideChange', function (event) {\n topbar2.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.querySelector('.teamSwiper')) {\n if (swiper8) {\n swiper8.destroy();\n }\n swiper8 = new core(\".teamSwiper\", {\n slidesPerView: 2,\n spaceBetween: 32,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n });\n mm.add(\"(max-width: 532px) and (min-width: 0px)\", function () {\n if (document.querySelector('.mySwiper')) {\n if (swiper) {\n swiper.destroy();\n }\n swiper = new core(\".mySwiper\", {\n slidesPerView: 1,\n grabCursor: true,\n spaceBetween: 16,\n freeMode: false\n });\n }\n if (document.querySelector('.claSwiper')) {\n if (swiper2) {\n swiper2.destroy();\n }\n swiper2 = new core(\".claSwiper\", {\n slidesPerView: 1,\n allowTouchMove: false,\n spaceBetween: 16,\n freeMode: false\n });\n topbar = document.querySelectorAll('.topbar a');\n for (var i = 0; i < topbar.length; i++) {\n topbar[i].addEventListener('click', function (event) {\n swiper2.slideTo(event.target.getAttribute('href'), 350);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper2.on('slideChange', function (event) {\n topbar.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.querySelector('.newsSwiper')) {\n if (swiper3) {\n swiper3.destroy();\n }\n swiper3 = new core(\".newsSwiper\", {\n slidesPerView: 1,\n spaceBetween: 16,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.partnerSwiper')) {\n if (swiper4) {\n swiper4.destroy();\n }\n swiper4 = new core(\".partnerSwiper\", {\n slidesPerView: 2,\n spaceBetween: 16,\n freeMode: false,\n allowTouchMove: false,\n autoplay: {\n delay: 2500,\n disableOnInteraction: false\n }\n });\n }\n if (document.querySelector('.campSwiper')) {\n var label = document.querySelector('.campSwiper .active').getAttribute('data-src');\n if (swiper5) {\n swiper5.destroy();\n }\n swiper5 = new core(\".campSwiper\", {\n slidesPerView: 1,\n spaceBetween: 16,\n initialSlide: label,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n if (document.querySelector('.garaSwiper')) {\n if (swiper6) {\n swiper6.destroy();\n }\n swiper6 = new core(\".garaSwiper\", {\n slidesPerView: 1,\n autoHeight: true,\n allowTouchMove: false,\n spaceBetween: 0,\n freeMode: false\n });\n var topbar2 = document.querySelectorAll('.topbar2 a');\n for (var i = 0; i < topbar2.length;
1 i++) {\n topbar2[i].addEventListener('click', function (event) {\n swiper6.slideTo(event.target.getAttribute('href'), 350, false);\n event.target.classList.add('active');\n event.preventDefault();\n });\n }\n swiper6.on('slideChange', function (event) {\n topbar2.forEach(function (node) {\n node.classList.remove('active');\n });\n });\n }\n if (document.querySelector('.teamSwiper')) {\n if (swiper8) {\n swiper8.destroy();\n }\n swiper8 = new core(\".teamSwiper\", {\n slidesPerView: 1,\n spaceBetween: 16,\n allowTouchMove: false,\n loop: false,\n freeMode: false,\n navigation: {\n nextEl: \".swiper-button-next\",\n prevEl: \".swiper-button-prev\"\n }\n });\n }\n });\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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BQUNBOztBQUVBO0FBQ0Esa0JBQWtCLGlCQUFpQjtBQUNuQzs7QUFFQTtBQUNBLHNCQUFzQiwwQkFBMEI7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjs7QUFFbkIsb0JBQW9COztBQUVwQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0gsRUFBRTs7O0FBR0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUN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DJDQUFlO0FBQ2YsWUFBWTtBQUNaLFNBQVM7QUFDVCxhQUFhO0FBQ2IsQ0FBQyxFOztBQ1BjO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEM7O0FDTmU7QUFDZjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDOztBQ1IrQztBQUNJO0FBQ25ELGtEQUFlO0FBQ2YsZUFBZTtBQUNmLGlCQUFpQjtBQUNqQixDQUFDLEU7O0FDTG1EO0FBQ2hCO0FBQ1EsQ0FBQzs7QUFFN0M7QUFDQTtBQUNBLHNCQUFzQixXQUFXLGFBQWEsd0JBQVM7QUFDdkQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVlO0FBQ2Y7QUFDQSxtQkFBbUIsV0FBVztBQUM5QixpQkFBaUIsd0JBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0IsR0FBQzs7QUFFbkI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDhDQUE4Qzs7QUFFOUMsd0ZBQXdGOztBQUV4Rjs7QUFFQTtBQUNBLGdCQUFnQixHQUFDO0FBQ2pCOztBQUVBLHNGQUFzRixzQkFBc0I7QUFDNUcsOERBQThEOztBQUU5RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DOztBQUVuQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSx3QkFBd0IsR0FBRztBQUMzQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0NBQWtDLEdBQUM7QUFDbkM7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDOztBQ25JeUM7QUFDTDtBQUNRO0FBQzdCO0FBQ2YsbUJBQW1CLFdBQVc7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVMsR0FBQztBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLDRCQUE0QixHQUFHO0FBQy9COztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwrQ0FBK0MsR0FBQztBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHNDQUFzQzs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7OztBQUdKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7OztBQUdKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNEQUFzRDs7QUFFdEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7OztBQUdKLGdEQUFnRDs7QUFFaEQ7QUFDQSxDOztBQzlOc0Q7QUFDdkM7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7O0FBR0o7QUFDQTtBQUNBLElBQUk7OztBQUdKLHVCQUF1QixHQUFHO0FBQzFCLHVEQUF1RDs7QUFFdkQ7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsdUJBQXVCLEdBQUc7QUFDMUIsRUFBRSxRQUFRO0FBQ1Y7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLElBQUk7OztBQUdKO0FBQ0E7O0FBRUEsa0JBQWtCLHVCQUF1QjtBQUN6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxJQUFJOzs7QUFHSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG9JQUFvSTtBQUNwSTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLEM7O0FDaEtlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osMENBQTBDOztBQUUxQztBQUNBO0FBQ0EsSUFBSTs7O0FBR0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLFVBQVU7O0FBRWQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0F
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FDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsRTs7QUMzSDJDO0FBQzdCO0FBQ2YsdUNBQXVDO0FBQ3ZDO0FBQ0E7O0F
1BRUE7QUFDQSxNQUFNLFlBQU07QUFDWjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNLFlBQU07QUFDWjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUksWUFBTTtBQUNWO0FBQ0EsQzs7QUNyQ0E7QUFDeUM7QUFDUjtBQUM2QjtBQUNSO0FBQ0Y7QUFDRTtBQUNOO0FBQ007QUFDTjtBQUNUO0FBQ007QUFDRTtBQUNWO0FBQ0Y7QUFDYTtBQUNUO0FBQ1U7QUFDUjtBQUNGO0FBQ2U7QUFDakI7QUFDb0I7QUFDekQ7QUFDQSxlQUFlO0FBQ2YsUUFBUTtBQUNSLFdBQVc7QUFDWCxZQUFZO0FBQ1osT0FBTztBQUNQLE1BQU07QUFDTixZQUFZO0FBQ1osUUFBUTtBQUNSLGFBQWE7QUFDYixlQUFlO0FBQ2YsU0FBUztBQUNULFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBLGFBQWEsWUFBTSxHQUFHO0FBQ3RCOztBQUVBLHFCQUFxQixHQUFDO0FBQ3RCO0FBQ0EsTUFBTSxHQUFDO0FBQ1AsMEJBQTBCLFlBQU0sR0FBRztBQUNuQztBQUNBLFNBQVM7QUFDVDtBQUNBLE9BQU8sR0FBRzs7QUFFVjtBQUNBLE1BQU07OztBQUdOO0FBQ0E7QUFDQSxxQkFBcUIsVUFBVTtBQUMvQixvQkFBb0IsU0FBUztBQUM3QjtBQUNBLEtBQUs7QUFDTCxxQkFBcUIsVUFBVTtBQUMvQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGtCQUFrQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLLEdBQUc7O0FBRVIseUJBQXlCLFlBQU0sR0FBRyxFQUFFLFFBQVEscUJBQXFCOztBQUVqRSxvQkFBb0IsWUFBTSxHQUFHO0FBQzdCLDRCQUE0QixZQUFNLEdBQUc7QUFDckMsMEJBQTBCLFlBQU0sR0FBRyxXQUFXOztBQUU5QztBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBLE1BQU07OztBQUdOLGVBQWUsR0FBQyxFQUFFOztBQUVsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLEdBQUM7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsR0FBRztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBLE1BQU07QUFDTjs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQU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FBUTtBQUN0Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTs7QUFFQSxrRUFBa0U7QUFDbEU7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsV0FBVzs7QUFFaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixXQUFXO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0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FDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixXQUFXO0FBQ1gsU0FBUztBQUNULFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQSxRQUFRO0FBQ1I7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEM7O0FDL1BlO0FBQ2Y7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLE1BQU0sc0JBQXNCOztBQUU1QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQT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FFLFVBQVUsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxLQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxXQUFXO0FBQ3BSLElBQU07OztBQ3pDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCxPQUFPO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxRQUFRO0FBQzFELHlDQUF5QyxRQUFRO0FBQ2pELHlEQUF5RCxRQUFRO0FBQ2pFO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsV0FBVztBQUM5QztBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDLGtDQUFrQztBQUM5RSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxvQkFBb0I7QUFDdkQ7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRCw0QkFBNEI7QUFDaEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbE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BQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRDtBQUNyRCxnREFBZ0Q7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLDJCQUEyQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsYUFBYTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QU
1FDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QjtBQUM5QixpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixpQkFBaUI7QUFDakI7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFFBQVE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsUUFBUTtBQUN4QjtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsNEJBQTRCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsNEJBQTRCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCw4REFBOEQsOERBQThEO0FBQzVLO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdEO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFFBQVE7QUFDeEIsZ0JBQWdCLFNBQVM7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLDJEQUEyRCxjQUFjO0FBQ3pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLHFEQUFxRDtBQUN2RjtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIscURBQXFEO0FBQ25GO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLHlEQUF5RDtBQUN6RDtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIscURBQXFEO0FBQ25GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsU0FBUztBQUN4QixlQUFlLFNBQVM7QU
1FDeEIsZUFBZSxRQUFRO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBLHNDQUFzQztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQyxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSw0QkFBNEIsMkJBQTJCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QU
1FDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQSx1REFBZSxZQUFZLEVBQUM7QUFDNUI7OztBQzVxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksa0JBQVE7QUFDWixJQUFJLGtCQUFRO0FBQ1osaURBQWlELE9BQU87QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsa0JBQVE7QUFDbkI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksb0JBQVE7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJLGdCQUFJO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0Isa0JBQVEsQ0FBQyxrQkFBUSxHQUFHO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLG9CQUFRO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QU
1FDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULDBCQUEwQixvQkFBUSw4QkFBOEIsb0JBQVEsMEJBQTBCLG9CQUFRLHlCQUF5QixvQkFBUSw2QkFBNkIsb0JBQVE7QUFDaEw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQThDLFlBQVk7QUFDMUQ7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsMEJBQTBCLG9CQUFRO0FBQ2xDO0FBQ0EsU0FBUztBQUNULDBCQUEwQixvQkFBUTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsMEJBQTBCLG9CQUFRO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ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
1FrQiwwQkFBMEIsbUJBQW1CLHlGQUF5RixnQkFBZ0Isd0JBQXdCLGlCQUFpQixtRkFBbUYsZUFBZSx1QkFBdUIsZ0JBQWdCLGdGQUFnRixnQkFBZ0IsY0FBYyxpS0FBaUsscUJBQXFCLG1GQUE0RztBQUM5cVc7OztBQ0RBLHdDQUF3Qyx1QkFBdUIseUZBQXlGOztBQUV4SixnREFBZ0QsMERBQTBELDJDQUEyQzs7QUFFcko7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRCw2RkFBNkY7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0QsdUJBQXVCO0FBQ3ZCO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0EsaUJBQWlCO0FBQ2pCLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDJDQUEyQztBQUMzQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBLCtKQUErSjtBQUMvSjtBQUNBOztBQUVBLFNBQVMsMkNBQTJDOztBQUVwRDtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsY0FBYyxPQUFPO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxzREFBc0Q7QUFDdEQsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsMklBQTJJO0FBQzNJOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0EsZUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBLG1EQUFtRDtBQUNuRCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLGtEQUFrRDtBQUNsRDs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7OztBQUdKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbURBQW1EOztBQUVuRDtBQUNBO0FBQ0E7O0FBRUEsaUNBQWlDO0FBQ2pDO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxpRUFBaUU7O0FBRWpFO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUVBQWlFOztBQUVqRSxzRUFBc0U7O0FBRXRFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZFQUE2RTtBQUM3RTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0gsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7QUFDRCw0R0FBNEcsR0FBRyx1RUFBdUU7QUFDdEwsc0pBQXNKLG1EQUFtRDtBQUN6TTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNILGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0JBQWtCLE9BQU87QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBNEQ7O0FBRTVEO0FBQ0E7O0FBRUE7QUFDQSwwRkFBMEY7QUFDMUY7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLCtEQUErRDs7QUFFL0Q7QUFDQTs7QUFFQSxrRUFBa0U7QUFDbEU7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7QUFDRDtBQUNBLDJFQUEyRSxhQUFhO0FBQ3hGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQjtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0IsT0FBTztBQUN6QixpRUFBaUU7QUFDakU7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE1BQU07QUFDTiw4Q0FBOEM7QUFDOUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJEQUEyRDs7QUFFM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3REFBd0QsOEVBQThFLDREQUE0RDs7QUFFbE07QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw2RkFBNkY7OztBQUc3RiwyRkFBMkY7OztBQUczRjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsa0dBQWtHO0FBQ2xHOztBQUVBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLG9JQUFvSSx1QkFBdUIsZ0RBQWdEO0FBQzNNO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7O0FBRXJDO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0F
1BRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0Esb0VBQW9FLElBQUksRUFBRSxJQUFJO0FBQzlFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsOERBQThEOztBQUU5RDtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQ0FBbUM7O0FBRW5DO0FBQ0EsbUJBQW1CLHdCQUF3QjtB
1QUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxRkFBcUY7O0FBRXJGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLDZDQUE2Qzs7QUFFN0M7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFFBQVE7O0FBRVI7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiw0QkFBNEIsOEVBQThFO0FBQ3BJLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTLE9BQU87QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRkFBMkY7QUFDM0YsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLElBQUk7O0FBRUosa0JBQWtCOztBQUVsQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSCxDQUFDOztBQUVEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsb0VBQW9FO0FBQ3BFOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOENBQThDO0FBQzlDLDJCQUEyQjtBQUMzQjs7QUFFQSx5REFBeUQ7QUFDekQ7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHdNQUF3TTtBQUN4TTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLHdCQUF3QjtB
1QUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0RBQXNEO0FBQ3REOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwwR0FBMEc7QUFDMUcsc0dBQXNHO0FBQ3RHO0FBQ0E7O0FBRUE7QUFDQSxnRUFBZ0U7O0FBRWhFOztBQUVBLG1CQUFtQjs7O0FBR25CO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDZFQUE2RTs7QUFFN0Usa0NBQWtDO0FBQ2xDLFFBQVE7QUFDUjs7QUFFQSw4QkFBOEI7O0FBRTlCLCtNQUErTTtBQUMvTTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBMEM7O0FBRTFDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNkVBQTZFO0FBQzdFOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0RkFBNEY7O0FBRTVGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCOztBQUUxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx5Q0FBeUM7O0FBRXpDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFEQUFxRDs7QUFFckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGdLQUFnSzs7QUFFaEs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdFQUFnRTs7QUFFaEU7QUFDQTtBQUNBLCtCQUErQjs7QUFFL0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwyQkFBMkI7O0FBRTNCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsWUFBWTs7O0FBR1o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhCQUE4Qjs7QUFFOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IscURBQXFELDZOQUE2TixPQUFPLFdBQVcsS0FBSztBQUMvVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMERBQTBEOztBQUUxRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLDZEQUE2RDs7QUFFN0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1RQUFtUTs7QUFFblE7QUFDQTtBQUNBO0FBQ0Esb0ZBQW9GOztBQUVwRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DOztBQUVuQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUhBQXlIOztBQUV6SDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTs7QUFFQSwwRUFBMEU7QUFDMUU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnRUFBZ0U7QUFDaEU7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0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FFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUEseUJBQXlCO0FBQ3pCO0FBQ0EsQ0FBQyxHQUFHOztBQUVKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLEdBQUc7OztBQUdkO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7OztBQUdJO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7O0FBRWhCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBLHFFQUFxRTs7QUFFckU7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsdUlBQXVJOztBQUV4STtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDbUo7QUFDcUgsQ0FBQzs7OztBQ3A0SXpRO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUV3Qjs7QUFFeEIsSUFBSSxhQUFJO0FBQ1IsSUFBSSxhQUFJO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksbUJBQVU7QUFDZCxJQUFJLHNCQUFhO0FBQ2pCO0FBQ0EsQ0FBQztBQUNELHdCQUF3QjtB
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NBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFVBQVUsTUFBTTtBQUNoQixVQUFVLE1BQU07QUFDaEIsVUFBVSxNQUFNO0FBQ2hCLFVBQVUsTUFBTTtBQUNoQixJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTLE1BQU07QUFDZixTQUFTLE1BQU07QUFDZjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLE1BQU07QUFDZixTQUFTLE1BQU07QUFDZjs7QUFFQTtBQUNBO0FBQ0EscURBQXFEO0FBQ3JELENBQUM7QUFDRDtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwrQkFBK0IsZ0JBQU87QUFDdEMsTUFBTTtBQUNOLCtCQUErQixnQkFBTztBQUN0QztBQUNBOztBQUVBLHdCQUF3QixTQUFTO0FBQ2pDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGtCQUFrQixPQUFPO0FBQ3pCLGdCQUFnQixPQUFPO0FBQ3ZCO0FBQ0E7QUFDQSx1QkFBdUIsU0FBUztBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOzs7QUFHSCxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsQ0FBQzs7QUFFTTtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU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DtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG9GQUFvRjs7QUFFcEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGtDQUFrQzs7QUFFbEM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3Qjs7QUFFeEI7QUFDQTtBQUNBOztBQUVBLHdCQUF3Qjs7O0FBR3hCOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLDBCQUEwQix5REFBeUQ7OztBQUduRjtBQUNBLFVBQVUsYUFBSTtBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxtRUFBbUUsWUFBSTtBQUN2RTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2RUFBNkUsWUFBSTtBQUNqRjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQSxtQ0FBbUMsYUFBSTtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsSUFBSSxnQkFBUTs7QUFFWjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0EsQ0FBQztBQUNELGlCQUFROztBQUVSLGlCQUFRO0FBQ1IsYUFBYSxpQkFBUTtBQUNyQjs7QUFFQSxpQkFBUSxZQUFZLGlCQUFTOztBQUU3QixpQkFBUTtBQUNSO0FBQ0E7O0FBRUEsaUJBQVE7QUFDUjtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLGNBQWMsYUFBSSxnQkFBZ0IsaUJBQVE7OztBQzVxQjFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNvSjs7QUFFcEosSUFBSSxrQkFBSTtBQUNSLElBQUkseUJBQVk7QUFDaEIsSUFBSSxpQkFBSTtBQUNSLElBQUksaUJBQUk7QUFDUixJQUFJLG1CQUFNO0FBQ1YsSUFBSSxrQkFBSztBQUNULElBQUksa0JBQUs7QUFDVDtBQUNBO0FBQ0EsSUFBSSxtQkFBTTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSwyQkFBYztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxnQ0FBbUI7QUFDdkI7QUFDQSxJQUFJLHdCQUFXO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLHFCQUFRO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBUTtBQUNSLElBQUkscUJBQVE7QUFDWixhQUFhLHFCQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLG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FFTDtBQUNBLHlNQUF5TTs7QUFFek07QUFDQSxpQkFBaUIsa0JBQUk7O0FBRXJCO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixVQUFVO0FBQ2hDLDBHQUEwRzs7QUFFMUc7QUFDQTtBQUNBOztBQUVBLGdEQUFnRCxpQkFBSTtBQUNwRDtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTs7QUFFQSxnQ0FBZ0Msa0JBQUk7QUFDcEM7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGtCQUFJO0FBQ3RCLGtCQUFrQixrQkFBSSxxQ0FBcUMscUZBQXFGOztBQUVoSjs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsbUJBQW1CLHNCQUFTLFlBQVkseUJBQVk7QUFDcEQ7QUFDQTtBQUNBOztBQUVBLG9CQUFvQixVQUFVLENBQUMsYUFBYTs7QUFFNUM7QUFDQTtBQUNBLDhDQUE4QyxrQkFBSTs7QUFFbEQsaUNBQWlDLFFBQVEsV0FBVyxhQU
1FhO0FBQ2pFLHVDQUF1QyxrQkFBSzs7QUFFNUMsUUFBUSxrQkFBSTtBQUNaO0FBQ0EsU0FBUztBQUNULDRCQUE0QixrQkFBSTtBQUNoQywwQkFBMEIsa0JBQUk7QUFDOUI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFROzs7QUFHUjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxRUFBcUU7O0FBRXJFO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0EsMEJBQTBCO0FBQzFCOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7O0FBRUEsNkJBQTZCOztBQUU3QixzQ0FBc0M7O0FBRXRDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsUUFBUSx5QkFBWTs7QUFFcEI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0Esa0NBQWtDOztBQUVsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0Isc0JBQVM7QUFDL0I7QUFDQSx3QkFBd0Isc0JBQVM7QUFDakMsMkVBQTJFLFVBQVU7QUFDckY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFCQUFxQixzQkFBUztBQUM5QjtBQUNBLDRCQUE0QixrQkFBSTtBQUNoQywwQkFBMEIsa0JBQUk7QUFDOUI7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFOztBQUU1RTs7QUFFQTtBQUNBO0FBQ0EsNENBQTRDOztBQUU1QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxNQUFNLHdCQUFXO0FBQ2pCO0FBQ0EsY0FBYywyQkFBYztBQUM1QixNQUFNLHdCQUFXOztBQUVqQixVQUFVLHNCQUFTO0FBQ25CO0FBQ0EsdUJBQXVCLHNCQUFTO0FBQ2hDLFVBQVU7QUFDVjtBQUNBLHNCQUFzQixzQkFBUyxvREFBb0Qsa0JBQUksMEpBQTBKOztBQUVqUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0QkFBNEIsMkJBQWM7QUFDMUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSx1QkFBdUIsa0JBQUksbUJBQW1CLGtCQUFJO0FBQ2xEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLGtCQUFJO0FBQ1o7O0FBRUE7QUFDQTtBQUNBLG1DQUFtQyxTQUFTO0FBQzVDLCtCQUErQjs7QUFFL0I7O0FBRUE7QUFDQTtBQUNBLHlDQUF5QyxpQkFBSSxxQkFBcUIsbUJBQU07QUFDeEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsOENBQThDLGtCQUFLO0FBQ25EO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLG1DQUFtQzs7QUFFbkM7QUFDQSw2Q0FBNkMsY0FBYyx3QkFBd0IsV0FBVyxHQUFHLFNBQVM7O0FBRTFHO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0RBQW9EOztBQUVwRDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjs7QUFFQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3Q0FBd0M7O0FBRXhDLFVBQVUsZ0NBQW1COztBQUU3QjtBQUNBO0FBQ0E7QUFDQSwrRkFBK0Y7O0FBRS9GO0FBQ0E7QUFDQSwwRUFBMEU7O0FBRTFFLFVBQVUsZ0NBQW1CO0FBQzdCLFVBQVU7QUFDVjtBQUNBOztBQUVBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7O0FBRUEsb0NBQW9DLGtCQUFLO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxzRUFBc0U7O0FBRXRFO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0JBQW9CLHFCQUFROztBQUU1QjtBQUNBLHVCQUF1QjtBQUN2Qix1RUFBdUU7O0FBRXZFO0FBQ0E7O0FBRUE7QUFDQSw4TUFBOE07O0FBRTlNO0FBQ0E7QUFDQSxrSEFBa0gsa0JBQUksdURBQXVEOztBQUU3SztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixrQkFBSTtBQUNqQywyQkFBMkIsa0JBQUk7O0FBRS9COztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsMERBQTBEOztBQUUxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlDQUF5QyxxQkFBUTtBQUNqRDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsY0FBYyxzQkFBUztBQUN2QjtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTs7O0FBR1IsbURBQW1ELHFCQUFRO0FBQzNELCtEQUErRCxxQkFBUTtBQUN2RTtBQUNBLFVBQVUsK0RBQStELHFCQUFRO0FBQ2pGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdFQUFnRTs7QUFFaEU7QUFDQTs7QUFFQTtBQUNBLHVHQ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U4iLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3NyLXdpbmRvdy9zc3Itd2luZG93LmVzbS5qcz9iNjUxIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9kb203L2RvbTcuZXNtLmpzPzhlYzciLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9zaGFyZWQvZG9tLmpzPzdiYWIiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9zaGFyZWQvdXRpbHMuanM/OWNiOSIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL3NoYXJlZC9nZXQtc3VwcG9ydC5qcz9kNGQzIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvc2hhcmVkL2dldC1kZXZpY2UuanM/ZWFlMSIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL3NoYXJlZC9nZXQtYnJvd3Nlci5qcz84YmM3Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9tb2R1bGVzL3Jlc2l6ZS9yZXNpemUuanM/YjllMiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvbW9kdWxlcy9vYnNlcnZlci9vYnNlcnZlci5qcz8yOGI1Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9ldmVudHMtZW1pdHRlci5qcz82ZWQ0Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS91cGRhdGUvdXBkYXRlU2l6ZS5qcz82YTU1Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS91cGRhdGUvdXBkYXRlU2xpZGVzLmpzPzc5YTMiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3VwZGF0ZS91cGRhdGVBdXRvSGVpZ2h0LmpzP2Y1YzEiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3VwZGF0ZS91cGRhdGVTbGlkZXNPZmZzZXQuanM/ODU1NyIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvdXBkYXRlL3VwZGF0ZVNsaWRlc1Byb2dyZXNzLmpzP2FjN2YiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3VwZGF0ZS91cGRhdGVQcm9ncmVzcy5qcz8zYTkyIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS91cGRhdGUvdXBkYXRlU2xpZGVzQ2xhc3Nlcy5qcz85ZDMxIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS91cGRhdGUvdXBkYXRlQWN0aXZlSW5kZXguanM/OGQzOSIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvdXBkYXRlL3VwZGF0ZUNsaWNrZWRTbGlkZS5qcz9iZTU5Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS91cGRhdGUvaW5kZXguanM/NzZjMCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvdHJhbnNsYXRlL2dldFRyYW5zbGF0ZS5qcz9mNzA5Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS90cmFuc2xhdGUvc2V0VHJhbnNsYXRlLmpzPzllOGIiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3RyYW5zbGF0ZS9taW5UcmFuc2xhdGUuanM/NTQzOCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvdHJhbnNsYXRlL21heFRyYW5zbGF0ZS5qcz8yYTExIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS90cmFuc2xhdGUvdHJhbnNsYXRlVG8uanM/ZGUzNiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvdHJhbnNsYXRlL2luZGV4LmpzP2RlZTYiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3RyYW5zaXRpb24vc2V0VHJhbnNpdGlvbi5qcz8wMGZlIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS90cmFuc2l0aW9uL3RyYW5zaXRpb25FbWl0LmpzPzYxMDEiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3RyYW5zaXRpb24vdHJhbnNpdGlvblN0YXJ0LmpzPzVhYzYiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3RyYW5zaXRpb24vdHJhbnNpdGlvbkVuZC5qcz81ZDkwIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS90cmFuc2l0aW9uL2luZGV4LmpzPzZiZWMiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3NsaWRlL3NsaWRlVG8uanM/NTMxOSIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvc2xpZGUvc2xpZGVUb0xvb3AuanM/NjM2NSIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvc2xpZGUvc2xpZGVOZXh0LmpzPzQ5MTIiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3NsaWRlL3NsaWRlUHJldi5qcz8xYTlmIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9zbGlkZS9zbGlkZVJlc2V0LmpzPzI4OWIiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3NsaWRlL3NsaWRlVG9DbG9zZXN0LmpzPzRkMWEiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL3NsaWRlL3NsaWRlVG9DbGlja2VkU2xpZGUuanM/YmM2NSIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvc2xpZGUvaW5kZXguanM/OTVmNiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvbG9vcC9sb29wQ3JlYXRlLmpzPzBjZmQiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL2xvb3AvbG9vcEZpeC5qcz80OGJiIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9sb29wL2xvb3BEZXN0cm95LmpzPzlmYzIiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL2xvb3AvaW5kZXguanM/NzIyYyIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvZ3JhYi1jdXJzb3Ivc2V0R3JhYkN1cnNvci5qcz81N2JmIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9ncmFiLWN1cnNvci91bnNldEdyYWJDdXJzb3IuanM/ZjRiYyIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvZ3JhYi1jdXJzb3IvaW5kZXguanM/MDAxNiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvZXZlbnRzL29uVG91Y2hTdGFydC5qcz8zOTcwIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9ldmVudHMvb25Ub3VjaE1vdmUuanM/MTY1OCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvZXZlbnRzL29uVG91Y2hFbmQuanM/OTc5MiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvZXZlbnRzL29uUmVzaXplLmpzPzM5ZTUiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL2V2ZW50cy9vbkNsaWNrLmpzP2U2MjciLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL2V2ZW50cy9vblNjcm9sbC5qcz8xZGQ1Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9ldmVudHMvaW5kZXguanM/MTFjZSIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvYnJlYWtwb2ludHMvc2V0QnJlYWtwb2ludC5qcz8wNTQ4Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9icmVha3BvaW50cy9nZXRCcmVha3BvaW50LmpzP2E1ZmIiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL2JyZWFrcG9pbnRzL2luZGV4LmpzPzBjNzMiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL2NsYXNzZXMvYWRkQ2xhc3Nlcy5qcz83ZTIxIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9jbGFzc2VzL3JlbW92ZUNsYXNzZXMuanM/YzE1OSIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvY2xhc3Nlcy9pbmRleC5qcz9hMTJmIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9pbWFnZXMvbG9hZEltYWdlLmpzPzliNDIiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL2ltYWdlcy9wcmVsb2FkSW1hZ2VzLmpzPzVjNDIiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9jb3JlL2ltYWdlcy9pbmRleC5qcz82YTc2Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9jaGVjay1vdmVyZmxvdy9pbmRleC5qcz83ODNkIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9kZWZhdWx0cy5qcz82ZjE0Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvY29yZS9tb2R1bGVFeHRlbmRQYXJhbXMuanM/ZmVjNSIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL2NvcmUvY29yZS5qcz84ZmE1Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy92aXJ0dWFsL3ZpcnR1YWwuanM/YmM1NCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMva2V5Ym9hcmQva2V5Ym9hcmQuanM/NTEyOCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvbW91c2V3aGVlbC9tb3VzZXdoZWVsLmpzPzMwYWQiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9zaGFyZWQvY3JlYXRlLWVsZW1lbnQtaWYtbm90LWRlZmluZWQuanM/MzkxZiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvbmF2aWdhdGlvbi9uYXZpZ2F0aW9uLmpzPzgwZDgiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9zaGFyZWQvY2xhc3Nlcy10by1zZWxlY3Rvci5qcz9hYjJlIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy9wYWdpbmF0aW9uL3BhZ2luYX
1Rpb24uanM/MTRlYyIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvc2Nyb2xsYmFyL3Njcm9sbGJhci5qcz8wNDJhIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy9wYXJhbGxheC9wYXJhbGxheC5qcz9jM2Y0Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy96b29tL3pvb20uanM/MTQ3MyIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvbGF6eS9sYXp5LmpzPzliNzEiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9tb2R1bGVzL2NvbnRyb2xsZXIvY29udHJvbGxlci5qcz9hNjk2Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy9hMTF5L2ExMXkuanM/NmY5NiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvaGlzdG9yeS9oaXN0b3J5LmpzPzdlZDUiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9tb2R1bGVzL2hhc2gtbmF2aWdhdGlvbi9oYXNoLW5hdmlnYXRpb24uanM/NjQ1OCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvYXV0b3BsYXkvYXV0b3BsYXkuanM/M2ZkMCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvdGh1bWJzL3RodW1icy5qcz9kNTgyIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy9mcmVlLW1vZGUvZnJlZS1tb2RlLmpzP2ZmYzYiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9tb2R1bGVzL2dyaWQvZ3JpZC5qcz8wN2FjIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy9tYW5pcHVsYXRpb24vbWV0aG9kcy9hcHBlbmRTbGlkZS5qcz8yOWY0Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy9tYW5pcHVsYXRpb24vbWV0aG9kcy9wcmVwZW5kU2xpZGUuanM/ZDEzMiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvbWFuaXB1bGF0aW9uL21ldGhvZHMvYWRkU2xpZGUuanM/N2JiZCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvbWFuaXB1bGF0aW9uL21ldGhvZHMvcmVtb3ZlU2xpZGUuanM/ZTRiZiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvbWFuaXB1bGF0aW9uL21ldGhvZHMvcmVtb3ZlQWxsU2xpZGVzLmpzPzA2ZTQiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9tb2R1bGVzL21hbmlwdWxhdGlvbi9tYW5pcHVsYXRpb24uanM/ZTkzZiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL3NoYXJlZC9lZmZlY3QtaW5pdC5qcz9hODI3Iiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvc2hhcmVkL2VmZmVjdC10YXJnZXQuanM/ZWFjMyIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL3NoYXJlZC9lZmZlY3QtdmlydHVhbC10cmFuc2l0aW9uLWVuZC5qcz80NzNiIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy9lZmZlY3QtZmFkZS9lZmZlY3QtZmFkZS5qcz9lM2RmIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvbW9kdWxlcy9lZmZlY3QtY3ViZS9lZmZlY3QtY3ViZS5qcz9hMWVmIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvc2hhcmVkL2NyZWF0ZS1zaGFkb3cuanM/YjJkNCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvZWZmZWN0LWZsaXAvZWZmZWN0LWZsaXAuanM/MGFmOCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvZWZmZWN0LWNvdmVyZmxvdy9lZmZlY3QtY292ZXJmbG93LmpzPzdlMGYiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL3N3aXBlci9tb2R1bGVzL2VmZmVjdC1jcmVhdGl2ZS9lZmZlY3QtY3JlYXRpdmUuanM/YTliMiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvc3dpcGVyL21vZHVsZXMvZWZmZWN0LWNhcmRzL2VmZmVjdC1jYXJkcy5qcz9jNzNlIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9zd2lwZXIvc3dpcGVyLWJ1bmRsZS5lc20uanM/ZDQzMiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvbGlnaHRnYWxsZXJ5L2xpZ2h0Z2FsbGVyeS5lczUuanM/MjY5MCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvbGlnaHRnYWxsZXJ5L3BsdWdpbnMvem9vbS9sZy16b29tLmVzNS5qcz9jNzlhIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9Ac3R1ZGlvLWZyZWlnaHQvbGVuaXMvZGlzdC9sZW5pcy5tanM/OWI1MCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvZ3NhcC9nc2FwLWNvcmUuanM/YTVjZiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvZ3NhcC9DU1NQbHVnaW4uanM/OWNlNiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvZ3NhcC9hbGwuanM/NDQ3NiIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvZ3NhcC9PYnNlcnZlci5qcz82NmMzIiwid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9nc2FwL1Njcm9sbFRyaWdnZXIuanM/MWRhYyIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvZ3NhcC9DU1NSdWxlUGx1Z2luLmpzPzRlN2MiLCJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL2dzYXAvU2Nyb2xsVG9QbHVnaW4uanM/OTQyMCIsIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9zcmMvanMvYnVuZGxlLmpzP2Y0OWEiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTU1IgV2luZG93IDQuMC4yXG4gKiBCZXR0ZXIgaGFuZGxpbmcgZm9yIHdpbmRvdyBvYmplY3QgaW4gU1NSIGVudmlyb25tZW50XG4gKiBodHRwczovL2dpdGh1Yi5jb20vbm9saW1pdHM0d2ViL3Nzci13aW5kb3dcbiAqXG4gKiBDb3B5cmlnaHQgMjAyMSwgVmxhZGltaXIgS2hhcmxhbXBpZGlcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciBNSVRcbiAqXG4gKiBSZWxlYXNlZCBvbjogRGVjZW1iZXIgMTMsIDIwMjFcbiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tcGFyYW0tcmVhc3NpZ24gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KG9iaikge1xuICAgIHJldHVybiAob2JqICE9PSBudWxsICYmXG4gICAgICAgI
1HR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmXG4gICAgICAgICdjb25zdHJ1Y3RvcicgaW4gb2JqICYmXG4gICAgICAgIG9iai5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0KTtcbn1cbmZ1bmN0aW9uIGV4dGVuZCh0YXJnZXQgPSB7fSwgc3JjID0ge30pIHtcbiAgICBPYmplY3Qua2V5cyhzcmMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHRhcmdldFtrZXldID09PSAndW5kZWZpbmVkJylcbiAgICAgICAgICAgIHRhcmdldFtrZXldID0gc3JjW2tleV07XG4gICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KHNyY1trZXldKSAmJlxuICAgICAgICAgICAgaXNPYmplY3QodGFyZ2V0W2tleV0pICYmXG4gICAgICAgICAgICBPYmplY3Qua2V5cyhzcmNba2V5XSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZXh0ZW5kKHRhcmdldFtrZXldLCBzcmNba2V5XSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuY29uc3Qgc3NyRG9jdW1lbnQgPSB7XG4gICAgYm9keToge30sXG4gICAgYWRkRXZlbnRMaXN0ZW5lcigpIHsgfSxcbiAgICByZW1vdmVFdmVudExpc3RlbmVyKCkgeyB9LFxuICAgIGFjdGl2ZUVsZW1lbnQ6IHtcbiAgICAgICAgYmx1cigpIHsgfSxcbiAgICAgICAgbm9kZU5hbWU6ICcnLFxuICAgIH0sXG4gICAgcXVlcnlTZWxlY3RvcigpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBxdWVyeVNlbGVjdG9yQWxsKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfSxcbiAgICBnZXRFbGVtZW50QnlJZCgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBjcmVhdGVFdmVudCgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGluaXRFdmVudCgpIHsgfSxcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIGNyZWF0ZUVsZW1lbnQoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjaGlsZHJlbjogW10sXG4gICAgICAgICAgICBjaGlsZE5vZGVzOiBbXSxcbiAgICAgICAgICAgIHN0eWxlOiB7fSxcbiAgICAgICAgICAgIHNldEF0dHJpYnV0ZSgpIHsgfSxcbiAgICAgICAgICAgIGdldEVsZW1lbnRzQnlUYWdOYW1lKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBjcmVhdGVFbGVtZW50TlMoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9LFxuICAgIGltcG9ydE5vZGUoKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0sXG4gICAgbG9jYXRpb246IHtcbiAgICAgICAgaGFzaDogJycsXG4gICAgICAgIGhvc3Q6ICcnLFxuICAgICAgICBob3N0bmFtZTogJycsXG4gICAgICAgIGhyZWY6ICcnLFxuICAgICAgICBvcmlnaW46ICcnLFxuICAgICAgICBwYXRobmFtZTogJycsXG4gICAgICAgIHByb3RvY29sOiAnJyxcbiAgICAgICAgc2VhcmNoOiAnJyxcbiAgICB9LFxufTtcbmZ1bmN0aW9uIGdldERvY3VtZW50KCkge1xuICAgIGNvbnN0IGRvYyA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgPyBkb2N1bWVudCA6IHt9O1xuICAgIGV4dGVuZChkb2MsIHNzckRvY3VtZW50KTtcbiAgICByZXR1cm4gZG9jO1xufVxuXG5jb25zdCBzc3JXaW5kb3cgPSB7XG4gICAgZG9jdW1lbnQ6IHNzckRvY3VtZW50LFxuICAgIG5hdmlnYXRvcjoge1xuICAgICAgICB1c2VyQWdlbnQ6ICcnLFxuICAgIH0sXG4gICAgbG9jYXRpb246IHtcbiAgICAgICAgaGFzaDogJycsXG4gICAgICAgIGhvc3Q6ICcnLFxuICAgICAgICBob3N0bmFtZTogJycsXG4gICAgICAgIGhyZWY6ICcnLFxuICAgICAgICBvcmlnaW46ICcnLFxuICAgICAgICBwYXRobmFtZTogJycsXG4gICAgICAgIHByb3RvY29sOiAnJyxcbiAgICAgICAgc2VhcmNoOiAnJyxcbiAgICB9LFxuICAgIGhpc3Rvcnk6IHtcbiAgICAgICAgcmVwbGFjZVN0YXRlKCkgeyB9LFxuICAgICAgICBwdXNoU3RhdGUoKSB7IH0sXG4gICAgICAgIGdvKCkgeyB9LFxuICAgICAgICBiYWNrKCkgeyB9LFxuICAgIH0sXG4gICAgQ3VzdG9tRXZlbnQ6IGZ1bmN0aW9uIEN1c3RvbUV2ZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGFkZEV2ZW50TGlzdGVuZXIoKSB7IH0sXG4gICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcigpIHsgfSxcbiAgICBnZXRDb21wdXRlZFN0eWxlKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZ2V0UHJvcGVydHlWYWx1ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgSW1hZ2UoKSB7IH0sXG4gICAgRGF0ZSgpIHsgfSxcbiAgICBzY3JlZW46IHt9LFxuICAgIHNldFRpbWVvdXQoKSB7IH0sXG4gICAgY2xlYXJUaW1lb3V0KCkgeyB9LFxuICAgIG1hdGNoTWVkaWEoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9LFxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoY2FsbGJhY2ssIDApO1xuICAgIH0sXG4gICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUoaWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXRUaW
11lb3V0ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNsZWFyVGltZW91dChpZCk7XG4gICAgfSxcbn07XG5mdW5jdGlvbiBnZXRXaW5kb3coKSB7XG4gICAgY29uc3Qgd2luID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB7fTtcbiAgICBleHRlbmQod2luLCBzc3JXaW5kb3cpO1xuICAgIHJldHVybiB3aW47XG59XG5cbmV4cG9ydCB7IGV4dGVuZCwgZ2V0RG9jdW1lbnQsIGdldFdpbmRvdywgc3NyRG9jdW1lbnQsIHNzcldpbmRvdyB9O1xuIiwiLyoqXG4gKiBEb203IDQuMC42XG4gKiBNaW5pbWFsaXN0aWMgSmF2YVNjcmlwdCBsaWJyYXJ5IGZvciBET00gbWFuaXB1bGF0aW9uLCB3aXRoIGEgalF1ZXJ5LWNvbXBhdGlibGUgQVBJXG4gKiBodHRwczovL2ZyYW1ld29yazcuaW8vZG9jcy9kb203Lmh0bWxcbiAqXG4gKiBDb3B5cmlnaHQgMjAyMywgVmxhZGltaXIgS2hhcmxhbXBpZGlcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciBNSVRcbiAqXG4gKiBSZWxlYXNlZCBvbjogRmVicnVhcnkgMiwgMjAyM1xuICovXG5pbXBvcnQgeyBnZXRXaW5kb3csIGdldERvY3VtZW50IH0gZnJvbSAnc3NyLXdpbmRvdyc7XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5mdW5jdGlvbiBtYWtlUmVhY3RpdmUob2JqKSB7XG4gIGNvbnN0IHByb3RvID0gb2JqLl9fcHJvdG9fXztcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgJ19fcHJvdG9fXycsIHtcbiAgICBnZXQoKSB7XG4gICAgICByZXR1cm4gcHJvdG87XG4gICAgfSxcblxuICAgIHNldCh2YWx1ZSkge1xuICAgICAgcHJvdG8uX19wcm90b19fID0gdmFsdWU7XG4gICAgfVxuXG4gIH0pO1xufVxuXG5jbGFzcyBEb203IGV4dGVuZHMgQXJyYXkge1xuICBjb25zdHJ1Y3RvcihpdGVtcykge1xuICAgIGlmICh0eXBlb2YgaXRlbXMgPT09ICdudW1iZXInKSB7XG4gICAgICBzdXBlcihpdGVtcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN1cGVyKC4uLihpdGVtcyB8fCBbXSkpO1xuICAgICAgbWFrZVJlYWN0aXZlKHRoaXMpO1xuICAgIH1cbiAgfVxuXG59XG5cbmZ1bmN0aW9uIGFycmF5RmxhdChhcnIgPSBbXSkge1xuICBjb25zdCByZXMgPSBbXTtcbiAgYXJyLmZvckVhY2goZWwgPT4ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGVsKSkge1xuICAgICAgcmVzLnB1c2goLi4uYXJyYXlGbGF0KGVsKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcy5wdXNoKGVsKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzO1xufVxuZnVuY3Rpb24gYXJyYXlGaWx0ZXIoYXJyLCBjYWxsYmFjaykge1xuICByZXR1cm4gQXJyYXkucHJvdG90eXBlLmZpbHRlci5jYWxsKGFyciwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gYXJyYXlVbmlxdWUoYXJyKSB7XG4gIGNvbnN0IHVuaXF1ZUFycmF5ID0gW107XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBpZiAodW5pcXVlQXJyYXkuaW5kZXhPZihhcnJbaV0pID09PSAtMSkgdW5pcXVlQXJyYXkucHVzaChhcnJbaV0pO1xuICB9XG5cbiAgcmV0dXJuIHVuaXF1ZUFycmF5O1xufVxuZnVuY3Rpb24gdG9DYW1lbENhc2Uoc3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmcudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC8tKC4pL2csIChtYXRjaCwgZ3JvdXApID0+IGdyb3VwLnRvVXBwZXJDYXNlKCkpO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuZnVuY3Rpb24gcXNhKHNlbGVjdG9yLCBjb250ZXh0KSB7XG4gIGlmICh0eXBlb2Ygc2VsZWN0b3IgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIFtzZWxlY3Rvcl07XG4gIH1cblxuICBjb25zdCBhID0gW107XG4gIGNvbnN0IHJlcyA9IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBhLnB1c2gocmVzW2ldKTtcbiAgfVxuXG4gIHJldHVybiBhO1xufVxuXG5mdW5jdGlvbiAkKHNlbGVjdG9yLCBjb250ZXh0KSB7XG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gIGxldCBhcnIgPSBbXTtcblxuICBpZiAoIWNvbnRleHQgJiYgc2VsZWN0b3IgaW5zdGFuY2VvZiBEb203KSB7XG4gICAgcmV0dXJuIHNlbGVjdG9yO1xuICB9XG5cbiAgaWYgKCFzZWxlY3Rvcikge1xuICAgIHJldHVybiBuZXcgRG9tNyhhcnIpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBzZWxlY3RvciA9PT0gJ3N0cmluZycpIHtcbiAgICBjb25zdCBodG1sID0gc2VsZWN0b3IudHJpbSgpO1xuXG4gICAgaWYgKGh0bWwuaW5kZXhPZignPCcpID49IDAgJiYgaHRtbC5pbmRleE9mKCc+JykgPj0gMCkge1xuICAgICAgbGV0IHRvQ3JlYXRlID0gJ2Rpdic7XG4gICAgICBpZiAoaHRtbC5pbmRleE9mKCc8bGknKSA9PT0gMCkgdG9DcmVhdGUgPSAndWwnO1xuICAgICAgaWYgKGh0bWwuaW5kZXhPZignPHRyJykgPT09IDApIHRvQ3JlYXRlID0gJ3Rib2R5JztcbiAgICAgIGlmIChodG1sLmluZGV4T2YoJzx0ZCcpID09PSAwIHx8IGh0bWwuaW5kZXhPZignPHRoJykgPT09IDApIHRvQ3JlYXRlID0gJ3RyJztcbiAgICAgIGlmIChodG1sLmluZGV4T2YoJzx0Ym9keScpID09PSAwKSB0b0NyZWF0ZSA9ICd0YWJsZSc7XG4gICAgICBpZiAoaHRtbC5pbmRleE9mKCc8b3B0aW9uJykgPT09IDApIHRvQ3JlYXRlID0gJ3NlbGVjdCc7XG4gICAgICBjb25zdCB0ZW1wUGFyZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0b0NyZWF0ZSk7XG4gICAgICB0ZW1wUGFyZW50LmlubmVySFRNTCA9IGh0bWw7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGVtcFBhcmVudC5jaGlsZE5vZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGFyci5wdXNoKHRlbXBQYXJlbnQuY2hpbGROb2Rlc1tpXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGFyciA9IHFzYShzZWxlY3Rvci50cmltKCksIGNvbnRleHQgfHwgZG9jdW1lbnQpO1xuICAgIH0gLy8gYXJyID0gcXNhKHNlbGVjdG9yLCBkb2N1bWVudCk7XG5cbiAgfSBlbHNlIGlmIChzZWxlY3Rvci5ub2RlVHlwZSB8fCBzZWxlY3RvciA9PT0gd2luZG93IHx8IHNlbGVjdG9yID09PSBkb2N1bWVudCkge1xuICAgIGFyci5wdXNoKHNlbGVjdG9yKTtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF
15KHNlbGVjdG9yKSkge1xuICAgIGlmIChzZWxlY3RvciBpbnN0YW5jZW9mIERvbTcpIHJldHVybiBzZWxlY3RvcjtcbiAgICBhcnIgPSBzZWxlY3RvcjtcbiAgfVxuXG4gIHJldHVybiBuZXcgRG9tNyhhcnJheVVuaXF1ZShhcnIpKTtcbn1cblxuJC5mbiA9IERvbTcucHJvdG90eXBlO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuZnVuY3Rpb24gYWRkQ2xhc3MoLi4uY2xhc3Nlcykge1xuICBjb25zdCBjbGFzc05hbWVzID0gYXJyYXlGbGF0KGNsYXNzZXMubWFwKGMgPT4gYy5zcGxpdCgnICcpKSk7XG4gIHRoaXMuZm9yRWFjaChlbCA9PiB7XG4gICAgZWwuY2xhc3NMaXN0LmFkZCguLi5jbGFzc05hbWVzKTtcbiAgfSk7XG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiByZW1vdmVDbGFzcyguLi5jbGFzc2VzKSB7XG4gIGNvbnN0IGNsYXNzTmFtZXMgPSBhcnJheUZsYXQoY2xhc3Nlcy5tYXAoYyA9PiBjLnNwbGl0KCcgJykpKTtcbiAgdGhpcy5mb3JFYWNoKGVsID0+IHtcbiAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKC4uLmNsYXNzTmFtZXMpO1xuICB9KTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIHRvZ2dsZUNsYXNzKC4uLmNsYXNzZXMpIHtcbiAgY29uc3QgY2xhc3NOYW1lcyA9IGFycmF5RmxhdChjbGFzc2VzLm1hcChjID0+IGMuc3BsaXQoJyAnKSkpO1xuICB0aGlzLmZvckVhY2goZWwgPT4ge1xuICAgIGNsYXNzTmFtZXMuZm9yRWFjaChjbGFzc05hbWUgPT4ge1xuICAgICAgZWwuY2xhc3NMaXN0LnRvZ2dsZShjbGFzc05hbWUpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gaGFzQ2xhc3MoLi4uY2xhc3Nlcykge1xuICBjb25zdCBjbGFzc05hbWVzID0gYXJyYXlGbGF0KGNsYXNzZXMubWFwKGMgPT4gYy5zcGxpdCgnICcpKSk7XG4gIHJldHVybiBhcnJheUZpbHRlcih0aGlzLCBlbCA9PiB7XG4gICAgcmV0dXJuIGNsYXNzTmFtZXMuZmlsdGVyKGNsYXNzTmFtZSA9PiBlbC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSkubGVuZ3RoID4gMDtcbiAgfSkubGVuZ3RoID4gMDtcbn1cblxuZnVuY3Rpb24gYXR0cihhdHRycywgdmFsdWUpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGF0dHJzID09PSAnc3RyaW5nJykge1xuICAgIC8vIEdldCBhdHRyXG4gICAgaWYgKHRoaXNbMF0pIHJldHVybiB0aGlzWzBdLmdldEF0dHJpYnV0ZShhdHRycyk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSAvLyBTZXQgYXR0cnNcblxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XG4gICAgICAvLyBTdHJpbmdcbiAgICAgIHRoaXNbaV0uc2V0QXR0cmlidXRlKGF0dHJzLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE9iamVjdFxuICAgICAgZm9yIChjb25zdCBhdHRyTmFtZSBpbiBhdHRycykge1xuICAgICAgICB0aGlzW2ldW2F0dHJOYW1lXSA9IGF0dHJzW2F0dHJOYW1lXTtcbiAgICAgICAgdGhpc1tpXS5zZXRBdHRyaWJ1dGUoYXR0ck5hbWUsIGF0dHJzW2F0dHJOYW1lXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUF0dHIoYXR0cikge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGlzW2ldLnJlbW92ZUF0dHJpYnV0ZShhdHRyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiBwcm9wKHByb3BzLCB2YWx1ZSkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJiB0eXBlb2YgcHJvcHMgPT09ICdzdHJpbmcnKSB7XG4gICAgLy8gR2V0IHByb3BcbiAgICBpZiAodGhpc1swXSkgcmV0dXJuIHRoaXNbMF1bcHJvcHNdO1xuICB9IGVsc2Uge1xuICAgIC8vIFNldCBwcm9wc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgLy8gU3RyaW5nXG4gICAgICAgIHRoaXNbaV1bcHJvcHNdID0gdmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBPYmplY3RcbiAgICAgICAgZm9yIChjb25zdCBwcm9wTmFtZSBpbiBwcm9wcykge1xuICAgICAgICAgIHRoaXNbaV1bcHJvcE5hbWVdID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gZGF0YShrZXksIHZhbHVlKSB7XG4gIGxldCBlbDtcblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJykge1xuICAgIGVsID0gdGhpc1swXTtcbiAgICBpZiAoIWVsKSByZXR1cm4gdW5kZWZpbmVkOyAvLyBHZXQgdmFsdWVcblxuICAgIGlmIChlbC5kb203RWxlbWVudERhdGFTdG9yYWdlICYmIGtleSBpbiBlbC5kb203RWxlbWVudERhdGFTdG9yYWdlKSB7XG4gICAgICByZXR1cm4gZWwuZG9tN0VsZW1lbnREYXRhU3RvcmFnZVtrZXldO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGFLZXkgPSBlbC5nZXRBdHRyaWJ1dGUoYGRhdGEtJHtrZXl9YCk7XG5cbiAgICBpZiAoZGF0YUtleSkge1xuICAgICAgcmV0dXJuIGRhdGFLZXk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSAvLyBTZXQgdmFsdWVcblxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGVsID0gdGhpc1tpXTtcbiAgICBpZiAoIWVsLmRvbTdFbGVtZW50RGF0YVN0b3JhZ2UpIGVsLmRvbTdFbGVtZW50RGF0YVN0b3JhZ2UgPSB7fTtcbiAgICBlbC5kb203RWxlbWVudERhdGFTdG9yYWdlW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiByZW1vdmVEYXRhKGtleSkge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCBlbCA9IHRoaXNbaV07XG5cbiAgICBpZiAoZWwuZG9tN0VsZW1lbnREYXRhU3RvcmFnZSAmJiBlbC5kb203RWxlbWVudERhdGFTdG9yYWdlW2tleV0pIHtcbiAgICAgIGVsLmRvbTdFbGVtZW50RGF0YVN0b3JhZ2Vba2V5XSA9IG51bGw7XG4gICAgICBkZWxldGUgZWwuZG9tN0VsZW1lbnREYXRhU3RvcmFnZVtrZXldO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkYXRhc2V0KCkge1xuICBjb25zdCBlbCA9IHRoaXNbMF07XG4gIGlmICghZWwpIHJldHVybi
1B1bmRlZmluZWQ7XG4gIGNvbnN0IGRhdGFzZXQgPSB7fTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gIGlmIChlbC5kYXRhc2V0KSB7XG4gICAgZm9yIChjb25zdCBkYXRhS2V5IGluIGVsLmRhdGFzZXQpIHtcbiAgICAgIGRhdGFzZXRbZGF0YUtleV0gPSBlbC5kYXRhc2V0W2RhdGFLZXldO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsLmF0dHJpYnV0ZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IGF0dHIgPSBlbC5hdHRyaWJ1dGVzW2ldO1xuXG4gICAgICBpZiAoYXR0ci5uYW1lLmluZGV4T2YoJ2RhdGEtJykgPj0gMCkge1xuICAgICAgICBkYXRhc2V0W3RvQ2FtZWxDYXNlKGF0dHIubmFtZS5zcGxpdCgnZGF0YS0nKVsxXSldID0gYXR0ci52YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhc2V0KSB7XG4gICAgaWYgKGRhdGFzZXRba2V5XSA9PT0gJ2ZhbHNlJykgZGF0YXNldFtrZXldID0gZmFsc2U7ZWxzZSBpZiAoZGF0YXNldFtrZXldID09PSAndHJ1ZScpIGRhdGFzZXRba2V5XSA9IHRydWU7ZWxzZSBpZiAocGFyc2VGbG9hdChkYXRhc2V0W2tleV0pID09PSBkYXRhc2V0W2tleV0gKiAxKSBkYXRhc2V0W2tleV0gKj0gMTtcbiAgfVxuXG4gIHJldHVybiBkYXRhc2V0O1xufVxuXG5mdW5jdGlvbiB2YWwodmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAvLyBnZXQgdmFsdWVcbiAgICBjb25zdCBlbCA9IHRoaXNbMF07XG4gICAgaWYgKCFlbCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGlmIChlbC5tdWx0aXBsZSAmJiBlbC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnc2VsZWN0Jykge1xuICAgICAgY29uc3QgdmFsdWVzID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWwuc2VsZWN0ZWRPcHRpb25zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKGVsLnNlbGVjdGVkT3B0aW9uc1tpXS52YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsLnZhbHVlO1xuICB9IC8vIHNldCB2YWx1ZVxuXG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgY29uc3QgZWwgPSB0aGlzW2ldO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIGVsLm11bHRpcGxlICYmIGVsLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdzZWxlY3QnKSB7XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGVsLm9wdGlvbnMubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgZWwub3B0aW9uc1tqXS5zZWxlY3RlZCA9IHZhbHVlLmluZGV4T2YoZWwub3B0aW9uc1tqXS52YWx1ZSkgPj0gMDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZWwudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gdmFsdWUodmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMudmFsKHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gdHJhbnNmb3JtKHRyYW5zZm9ybSkge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGlzW2ldLnN0eWxlLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiB0cmFuc2l0aW9uKGR1cmF0aW9uKSB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoaXNbaV0uc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gdHlwZW9mIGR1cmF0aW9uICE9PSAnc3RyaW5nJyA/IGAke2R1cmF0aW9ufW1zYCA6IGR1cmF0aW9uO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIG9uKC4uLmFyZ3MpIHtcbiAgbGV0IFtldmVudFR5cGUsIHRhcmdldFNlbGVjdG9yLCBsaXN0ZW5lciwgY2FwdHVyZV0gPSBhcmdzO1xuXG4gIGlmICh0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIFtldmVudFR5cGUsIGxpc3RlbmVyLCBjYXB0dXJlXSA9IGFyZ3M7XG4gICAgdGFyZ2V0U2VsZWN0b3IgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoIWNhcHR1cmUpIGNhcHR1cmUgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBoYW5kbGVMaXZlRXZlbnQoZSkge1xuICAgIGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0O1xuICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG4gICAgY29uc3QgZXZlbnREYXRhID0gZS50YXJnZXQuZG9tN0V2ZW50RGF0YSB8fCBbXTtcblxuICAgIGlmIChldmVudERhdGEuaW5kZXhPZihlKSA8IDApIHtcbiAgICAgIGV2ZW50RGF0YS51bnNoaWZ0KGUpO1xuICAgIH1cblxuICAgIGlmICgkKHRhcmdldCkuaXModGFyZ2V0U2VsZWN0b3IpKSBsaXN0ZW5lci5hcHBseSh0YXJnZXQsIGV2ZW50RGF0YSk7ZWxzZSB7XG4gICAgICBjb25zdCBwYXJlbnRzID0gJCh0YXJnZXQpLnBhcmVudHMoKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IHBhcmVudHMubGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgICAgaWYgKCQocGFyZW50c1trXSkuaXModGFyZ2V0U2VsZWN0b3IpKSBsaXN0ZW5lci5hcHBseShwYXJlbnRzW2tdLCBldmVudERhdGEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUV2ZW50KGUpIHtcbiAgICBjb25zdCBldmVudERhdGEgPSBlICYmIGUudGFyZ2V0ID8gZS50YXJnZXQuZG9tN0V2ZW50RGF0YSB8fCBbXSA6IFtdO1xuXG4gICAgaWYgKGV2ZW50RGF0YS5pbmRleE9mKGUpIDwgMCkge1xuICAgICAgZXZlbnREYXRhLnVuc2hpZnQoZSk7XG4gICAgfVxuXG4gICAgbGlzdGVuZXIuYXBwbHkodGhpcywgZXZlbnREYXRhKTtcbiAgfVxuXG4gIGNvbnN0IGV2ZW50cyA9IGV2ZW50VHlwZS5zcGxpdCgnICcpO1xuICBsZXQgajtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCBlbCA9IHRoaXNbaV07XG5cbiAgICBpZiAoIXRhcmdldFNlbGVjdG9yKSB7XG4gICAgICBmb3IgKGogPSAwOyBqIDwgZXZlbnRzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gZXZlbnRzW2pdO1xuICAgICAgICBpZiAoIWVsLmRvbTdMaXN0ZW5lcnMpIGVsLmRvbTdMaXN0ZW5lcnMgPSB7fTtcbiAgICAgICAgaWYgKCFlbC5kb203TGlzdGVuZXJzW2V2ZW50XSkgZWwuZG9tN0xpc3RlbmVyc1tldmVudF0gPSBbXTtcbiAgICAgICAgZWwuZG9tN0xpc3RlbmVyc1tldmVudF0ucHVzaCh7XG4gICAgICAgICAgbGlzdGVuZXIsXG4gICAgICAgICAgcHJveHlMaXN0ZW5lcjogaGFuZGxlRXZlbnRcbiAgICAgICAgfSk7XG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZUV2ZW50LCBjYXB0dXJlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTGl2ZSBldmVudHNcbiAgICAgIGZvciAoaiA9IDA7IGogPCBldmVudHMubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSBldmVudHNbal07XG4gICAgICAgIGlmICghZWwuZG9tN0xpdmVMaXN0ZW5lcnMpIGVsLmRvbTdMaX
1ZlTGlzdGVuZXJzID0ge307XG4gICAgICAgIGlmICghZWwuZG9tN0xpdmVMaXN0ZW5lcnNbZXZlbnRdKSBlbC5kb203TGl2ZUxpc3RlbmVyc1tldmVudF0gPSBbXTtcbiAgICAgICAgZWwuZG9tN0xpdmVMaXN0ZW5lcnNbZXZlbnRdLnB1c2goe1xuICAgICAgICAgIGxpc3RlbmVyLFxuICAgICAgICAgIHByb3h5TGlzdGVuZXI6IGhhbmRsZUxpdmVFdmVudFxuICAgICAgICB9KTtcbiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlTGl2ZUV2ZW50LCBjYXB0dXJlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gb2ZmKC4uLmFyZ3MpIHtcbiAgbGV0IFtldmVudFR5cGUsIHRhcmdldFNlbGVjdG9yLCBsaXN0ZW5lciwgY2FwdHVyZV0gPSBhcmdzO1xuXG4gIGlmICh0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIFtldmVudFR5cGUsIGxpc3RlbmVyLCBjYXB0dXJlXSA9IGFyZ3M7XG4gICAgdGFyZ2V0U2VsZWN0b3IgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoIWNhcHR1cmUpIGNhcHR1cmUgPSBmYWxzZTtcbiAgY29uc3QgZXZlbnRzID0gZXZlbnRUeXBlLnNwbGl0KCcgJyk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCBldmVudCA9IGV2ZW50c1tpXTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgY29uc3QgZWwgPSB0aGlzW2pdO1xuICAgICAgbGV0IGhhbmRsZXJzO1xuXG4gICAgICBpZiAoIXRhcmdldFNlbGVjdG9yICYmIGVsLmRvbTdMaXN0ZW5lcnMpIHtcbiAgICAgICAgaGFuZGxlcnMgPSBlbC5kb203TGlzdGVuZXJzW2V2ZW50XTtcbiAgICAgIH0gZWxzZSBpZiAodGFyZ2V0U2VsZWN0b3IgJiYgZWwuZG9tN0xpdmVMaXN0ZW5lcnMpIHtcbiAgICAgICAgaGFuZGxlcnMgPSBlbC5kb203TGl2ZUxpc3RlbmVyc1tldmVudF07XG4gICAgICB9XG5cbiAgICAgIGlmIChoYW5kbGVycyAmJiBoYW5kbGVycy5sZW5ndGgpIHtcbiAgICAgICAgZm9yIChsZXQgayA9IGhhbmRsZXJzLmxlbmd0aCAtIDE7IGsgPj0gMDsgayAtPSAxKSB7XG4gICAgICAgICAgY29uc3QgaGFuZGxlciA9IGhhbmRsZXJzW2tdO1xuXG4gICAgICAgICAgaWYgKGxpc3RlbmVyICYmIGhhbmRsZXIubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyLnByb3h5TGlzdGVuZXIsIGNhcHR1cmUpO1xuICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGssIDEpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgaGFuZGxlci5saXN0ZW5lciAmJiBoYW5kbGVyLmxpc3RlbmVyLmRvbTdwcm94eSAmJiBoYW5kbGVyLmxpc3RlbmVyLmRvbTdwcm94eSA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXIucHJveHlMaXN0ZW5lciwgY2FwdHVyZSk7XG4gICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaywgMSk7XG4gICAgICAgICAgfSBlbHNlIGlmICghbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXIucHJveHlMaXN0ZW5lciwgY2FwdHVyZSk7XG4gICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaywgMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIG9uY2UoLi4uYXJncykge1xuICBjb25zdCBkb20gPSB0aGlzO1xuICBsZXQgW2V2ZW50TmFtZSwgdGFyZ2V0U2VsZWN0b3IsIGxpc3RlbmVyLCBjYXB0dXJlXSA9IGFyZ3M7XG5cbiAgaWYgKHR5cGVvZiBhcmdzWzFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgW2V2ZW50TmFtZSwgbGlzdGVuZXIsIGNhcHR1cmVdID0gYXJncztcbiAgICB0YXJnZXRTZWxlY3RvciA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uY2VIYW5kbGVyKC4uLmV2ZW50QXJncykge1xuICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGV2ZW50QXJncyk7XG4gICAgZG9tLm9mZihldmVudE5hbWUsIHRhcmdldFNlbGVjdG9yLCBvbmNlSGFuZGxlciwgY2FwdHVyZSk7XG5cbiAgICBpZiAob25jZUhhbmRsZXIuZG9tN3Byb3h5KSB7XG4gICAgICBkZWxldGUgb25jZUhhbmRsZXIuZG9tN3Byb3h5O1xuICAgIH1cbiAgfVxuXG4gIG9uY2VIYW5kbGVyLmRvbTdwcm94eSA9IGxpc3RlbmVyO1xuICByZXR1cm4gZG9tLm9uKGV2ZW50TmFtZSwgdGFyZ2V0U2VsZWN0b3IsIG9uY2VIYW5kbGVyLCBjYXB0dXJlKTtcbn1cblxuZnVuY3Rpb24gdHJpZ2dlciguLi5hcmdzKSB7XG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICBjb25zdCBldmVudHMgPSBhcmdzWzBdLnNwbGl0KCcgJyk7XG4gIGNvbnN0IGV2ZW50RGF0YSA9IGFyZ3NbMV07XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBldmVudHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCBldmVudCA9IGV2ZW50c1tpXTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgY29uc3QgZWwgPSB0aGlzW2pdO1xuXG4gICAgICBpZiAod2luZG93LkN1c3RvbUV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGV2dCA9IG5ldyB3aW5kb3cuQ3VzdG9tRXZlbnQoZXZlbnQsIHtcbiAgICAgICAgICBkZXRhaWw6IGV2ZW50RGF0YSxcbiAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgIGNhbmNlbGFibG
1U6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIGVsLmRvbTdFdmVudERhdGEgPSBhcmdzLmZpbHRlcigoZGF0YSwgZGF0YUluZGV4KSA9PiBkYXRhSW5kZXggPiAwKTtcbiAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChldnQpO1xuICAgICAgICBlbC5kb203RXZlbnREYXRhID0gW107XG4gICAgICAgIGRlbGV0ZSBlbC5kb203RXZlbnREYXRhO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiB0cmFuc2l0aW9uU3RhcnQoY2FsbGJhY2spIHtcbiAgY29uc3QgZG9tID0gdGhpcztcblxuICBmdW5jdGlvbiBmaXJlQ2FsbEJhY2soZSkge1xuICAgIGlmIChlLnRhcmdldCAhPT0gdGhpcykgcmV0dXJuO1xuICAgIGNhbGxiYWNrLmNhbGwodGhpcywgZSk7XG4gICAgZG9tLm9mZigndHJhbnNpdGlvbnN0YXJ0JywgZmlyZUNhbGxCYWNrKTtcbiAgfVxuXG4gIGlmIChjYWxsYmFjaykge1xuICAgIGRvbS5vbigndHJhbnNpdGlvbnN0YXJ0JywgZmlyZUNhbGxCYWNrKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiB0cmFuc2l0aW9uRW5kKGNhbGxiYWNrKSB7XG4gIGNvbnN0IGRvbSA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gZmlyZUNhbGxCYWNrKGUpIHtcbiAgICBpZiAoZS50YXJnZXQgIT09IHRoaXMpIHJldHVybjtcbiAgICBjYWxsYmFjay5jYWxsKHRoaXMsIGUpO1xuICAgIGRvbS5vZmYoJ3RyYW5zaXRpb25lbmQnLCBmaXJlQ2FsbEJhY2spO1xuICB9XG5cbiAgaWYgKGNhbGxiYWNrKSB7XG4gICAgZG9tLm9uKCd0cmFuc2l0aW9uZW5kJywgZmlyZUNhbGxCYWNrKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiBhbmltYXRpb25FbmQoY2FsbGJhY2spIHtcbiAgY29uc3QgZG9tID0gdGhpcztcblxuICBmdW5jdGlvbiBmaXJlQ2FsbEJhY2soZSkge1xuICAgIGlmIChlLnRhcmdldCAhPT0gdGhpcykgcmV0dXJuO1xuICAgIGNhbGxiYWNrLmNhbGwodGhpcywgZSk7XG4gICAgZG9tLm9mZignYW5pbWF0aW9uZW5kJywgZmlyZUNhbGxCYWNrKTtcbiAgfVxuXG4gIGlmIChjYWxsYmFjaykge1xuICAgIGRvbS5vbignYW5pbWF0aW9uZW5kJywgZmlyZUNhbGxCYWNrKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiB3aWR0aCgpIHtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG5cbiAgaWYgKHRoaXNbMF0gPT09IHdpbmRvdykge1xuICAgIHJldHVybiB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgfVxuXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gcGFyc2VGbG9hdCh0aGlzLmNzcygnd2lkdGgnKSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gb3V0ZXJXaWR0aChpbmNsdWRlTWFyZ2lucykge1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgaWYgKGluY2x1ZGVNYXJnaW5zKSB7XG4gICAgICBjb25zdCBzdHlsZXMgPSB0aGlzLnN0eWxlcygpO1xuICAgICAgcmV0dXJuIHRoaXNbMF0ub2Zmc2V0V2lkdGggKyBwYXJzZU
1Zsb2F0KHN0eWxlcy5nZXRQcm9wZXJ0eVZhbHVlKCdtYXJnaW4tcmlnaHQnKSkgKyBwYXJzZUZsb2F0KHN0eWxlcy5nZXRQcm9wZXJ0eVZhbHVlKCdtYXJnaW4tbGVmdCcpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpc1swXS5vZmZzZXRXaWR0aDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBoZWlnaHQoKSB7XG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuXG4gIGlmICh0aGlzWzBdID09PSB3aW5kb3cpIHtcbiAgICByZXR1cm4gd2luZG93LmlubmVySGVpZ2h0O1xuICB9XG5cbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBwYXJzZUZsb2F0KHRoaXMuY3NzKCdoZWlnaHQnKSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gb3V0ZXJIZWlnaHQoaW5jbHVkZU1hcmdpbnMpIHtcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIGlmIChpbmNsdWRlTWFyZ2lucykge1xuICAgICAgY29uc3Qgc3R5bGVzID0gdGhpcy5zdHlsZXMoKTtcbiAgICAgIHJldHVybiB0aGlzWzBdLm9mZnNldEhlaWdodCArIHBhcnNlRmxvYXQoc3R5bGVzLmdldFByb3BlcnR5VmFsdWUoJ21hcmdpbi10b3AnKSkgKyBwYXJzZUZsb2F0KHN0eWxlcy5nZXRQcm9wZXJ0eVZhbHVlKCdtYXJnaW4tYm90dG9tJykpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzWzBdLm9mZnNldEhlaWdodDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBvZmZzZXQoKSB7XG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gICAgY29uc3QgZWwgPSB0aGlzWzBdO1xuICAgIGNvbnN0IGJveCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuICAgIGNvbnN0IGNsaWVudFRvcCA9IGVsLmNsaWVudFRvcCB8fCBib2R5LmNsaWVudFRvcCB8fCAwO1xuICAgIGNvbnN0IGNsaWVudExlZnQgPSBlbC5jbGllbnRMZWZ0IHx8IGJvZHkuY2xpZW50TGVmdCB8fCAwO1xuICAgIGNvbnN0IHNjcm9sbFRvcCA9IGVsID09PSB3aW5kb3cgPyB3aW5kb3cuc2Nyb2xsWSA6IGVsLnNjcm9sbFRvcDtcbiAgICBjb25zdCBzY3JvbGxMZWZ0ID0gZWwgPT09IHdpbmRvdyA/IHdpbmRvdy5zY3JvbGxYIDogZWwuc2Nyb2xsTGVmdDtcbiAgICByZXR1cm4ge1xuICAgICAgdG9wOiBib3gudG9wICsgc2Nyb2xsVG9wIC0gY2xpZW50VG9wLFxuICAgICAgbGVmdDogYm94LmxlZnQgKyBzY3JvbGxMZWZ0IC0gY2xpZW50TGVmdFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gaGlkZSgpIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhpc1tpXS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIHNob3coKSB7XG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGNvbnN0IGVsID0gdGhpc1tpXTtcblxuICAgIGlmIChlbC5zdHlsZS5kaXNwbGF5ID09PSAnbm9uZScpIHtcbiAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICB9XG5cbiAgICBpZiAod2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwsIG51bGwpLmdldFByb3BlcnR5VmFsdWUoJ2Rpc3BsYXknKSA9PT0gJ25vbmUnKSB7XG4gICAgICAvLyBTdGlsbCBub3QgdmlzaWJsZVxuICAgICAgZWwuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIHN0eWxlcygpIHtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gIGlmICh0aGlzWzBdKSByZXR1cm4gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpc1swXSwgbnVsbCk7XG4gIHJldHVybiB7fTtcbn1cblxuZnVuY3Rpb24gY3NzKHByb3BzLCB2YWx1ZSkge1xuICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgbGV0IGk7XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICBpZiAodHlwZW9mIHByb3BzID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gLmNzcygnd2lkdGgnKVxuICAgICAgaWYgKHRoaXNbMF0pIHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzWzBdLCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKHByb3BzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gLmNzcyh7IHdpZHRoOiAnMTAwcHgnIH0pXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBmb3IgKGNvbnN0IHByb3AgaW4gcHJvcHMpIHtcbiAgICAgICAgICB0aGlzW2ldLnN0eWxlW3Byb3BdID0gcHJvcHNbcHJvcF07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICB9XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIgJiYgdHlwZW9mIHByb3BzID09PSAnc3RyaW5nJykge1xuICAgIC8vIC5jc3MoJ3dpZHRoJywgJzEwMHB4JylcbiAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgdGhpc1tpXS5zdHlsZVtwcm9wc10gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiBlYWNoKGNhbGxiYWNrKSB7XG4gIGlmICghY2FsbGJhY2spIHJldHVybiB0aGlzO1xuICB0aGlzLmZvckVhY2goKGVsLCBpbmRleCkgPT4ge1xuICAgIGNhbGxiYWNrLmFwcGx5KGVsLCBbZWwsIGluZGV4XSk7XG4gIH0pO1xuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gZmlsdGVyKGNhbGxiYWNrKSB7XG4gIGNvbnN0IHJlc3VsdCA9IGFycmF5RmlsdGVyKHRoaXMsIGNhbGxiYWNrKTtcbiAgcmV0dXJuICQocmVzdWx0KTtcbn1cblxuZnVuY3Rpb24gaHRtbChodG1sKSB7XG4gIGlmICh0eXBlb2YgaHRtbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gdGhpc1swXSA/IHRoaXNbMF0uaW5uZXJIVE1MIDogbnVsbDtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoaXNbaV0uaW5uZXJIVE1MID0gaHRtbDtcbiAgfVxuXG4gIHJldHVybi
1B0aGlzO1xufVxuXG5mdW5jdGlvbiB0ZXh0KHRleHQpIHtcbiAgaWYgKHR5cGVvZiB0ZXh0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB0aGlzWzBdID8gdGhpc1swXS50ZXh0Q29udGVudC50cmltKCkgOiBudWxsO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhpc1tpXS50ZXh0Q29udGVudCA9IHRleHQ7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gaXMoc2VsZWN0b3IpIHtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgY29uc3QgZWwgPSB0aGlzWzBdO1xuICBsZXQgY29tcGFyZVdpdGg7XG4gIGxldCBpO1xuICBpZiAoIWVsIHx8IHR5cGVvZiBzZWxlY3RvciA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIHNlbGVjdG9yID09PSAnc3RyaW5nJykge1xuICAgIGlmIChlbC5tYXRjaGVzKSByZXR1cm4gZWwubWF0Y2hlcyhzZWxlY3Rvcik7XG4gICAgaWYgKGVsLndlYmtpdE1hdGNoZXNTZWxlY3RvcikgcmV0dXJuIGVsLndlYmtpdE1hdGNoZXNTZWxlY3RvcihzZWxlY3Rvcik7XG4gICAgaWYgKGVsLm1zTWF0Y2hlc1NlbGVjdG9yKSByZXR1cm4gZWwubXNNYXRjaGVzU2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgIGNvbXBhcmVXaXRoID0gJChzZWxlY3Rvcik7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgY29tcGFyZVdpdGgubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGlmIChjb21wYXJlV2l0aFtpXSA9PT0gZWwpIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChzZWxlY3RvciA9PT0gZG9jdW1lbnQpIHtcbiAgICByZXR1cm4gZWwgPT09IGRvY3VtZW50O1xuICB9XG5cbiAgaWYgKHNlbGVjdG9yID09PSB3aW5kb3cpIHtcbiAgICByZXR1cm4gZWwgPT09IHdpbmRvdztcbiAgfVxuXG4gIGlmIChzZWxlY3Rvci5ub2RlVHlwZSB8fCBzZWxlY3RvciBpbnN0YW5jZW9mIERvbTcpIHtcbiAgICBjb21wYXJlV2l0aCA9IHNlbGVjdG9yLm5vZGVUeXBlID8gW3NlbGVjdG9yXSA6IHNlbGVjdG9yO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGNvbXBhcmVXaXRoLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpZiAoY29tcGFyZVdpdGhbaV0gPT09IGVsKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGluZGV4KCkge1xuICBsZXQgY2hpbGQgPSB0aGlzWzBdO1xuICBsZXQgaTtcblxuICBpZiAoY2hpbGQpIHtcbiAgICBpID0gMDsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cbiAgICB3aGlsZSAoKGNoaWxkID0gY2hpbGQucHJldmlvdXNTaWJsaW5nKSAhPT0gbnVsbCkge1xuICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSAxKSBpICs9IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIGk7XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBlcShpbmRleCkge1xuICBpZiAodHlwZW9mIGluZGV4ID09PSAndW5kZWZpbmVkJykgcmV0dXJuIHRoaXM7XG4gIGNvbnN0IGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuXG4gIGlmIChpbmRleCA+IGxlbmd0aCAtIDEpIHtcbiAgICByZXR1cm4gJChbXSk7XG4gIH1cblxuICBpZiAoaW5kZXggPCAwKSB7XG4gICAgY29uc3QgcmV0dXJuSW5kZXggPSBsZW5ndGggKyBpbmRleDtcbiAgICBpZiAocmV0dXJuSW5kZXggPCAwKSByZXR1cm4gJChbXSk7XG4gICAgcmV0dXJuICQoW3RoaXNbcmV0dXJuSW5kZX
1hdXSk7XG4gIH1cblxuICByZXR1cm4gJChbdGhpc1tpbmRleF1dKTtcbn1cblxuZnVuY3Rpb24gYXBwZW5kKC4uLmVscykge1xuICBsZXQgbmV3Q2hpbGQ7XG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcblxuICBmb3IgKGxldCBrID0gMDsgayA8IGVscy5sZW5ndGg7IGsgKz0gMSkge1xuICAgIG5ld0NoaWxkID0gZWxzW2tdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zdCB0ZW1wRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIHRlbXBEaXYuaW5uZXJIVE1MID0gbmV3Q2hpbGQ7XG5cbiAgICAgICAgd2hpbGUgKHRlbXBEaXYuZmlyc3RDaGlsZCkge1xuICAgICAgICAgIHRoaXNbaV0uYXBwZW5kQ2hpbGQodGVtcERpdi5maXJzdENoaWxkKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChuZXdDaGlsZCBpbnN0YW5jZW9mIERvbTcpIHtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBuZXdDaGlsZC5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgIHRoaXNbaV0uYXBwZW5kQ2hpbGQobmV3Q2hpbGRbal0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzW2ldLmFwcGVuZENoaWxkKG5ld0NoaWxkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gYXBwZW5kVG8ocGFyZW50KSB7XG4gICQocGFyZW50KS5hcHBlbmQodGhpcyk7XG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiBwcmVwZW5kKG5ld0NoaWxkKSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgbGV0IGk7XG4gIGxldCBqO1xuXG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgaWYgKHR5cGVvZiBuZXdDaGlsZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IHRlbXBEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHRlbXBEaXYuaW5uZXJIVE1MID0gbmV3Q2hpbGQ7XG5cbiAgICAgIGZvciAoaiA9IHRlbXBEaXYuY2hpbGROb2Rlcy5sZW5ndGggLSAxOyBqID49IDA7IGogLT0gMSkge1xuICAgICAgICB0aGlzW2ldLmluc2VydEJlZm9yZSh0ZW1wRGl2LmNoaWxkTm9kZXNbal0sIHRoaXNbaV0uY2hpbGROb2Rlc1swXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChuZXdDaGlsZCBpbnN0YW5jZW9mIERvbTcpIHtcbiAgICAgIGZvciAoaiA9IDA7IGogPCBuZXdDaGlsZC5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICB0aGlzW2ldLmluc2VydEJlZm9yZShuZXdDaGlsZFtqXSwgdGhpc1tpXS5jaGlsZE5vZGVzWzBdKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpc1tpXS5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHRoaXNbaV0uY2hpbGROb2Rlc1swXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIHByZXBlbmRUbyhwYXJlbnQpIHtcbiAgJChwYXJlbnQpLnByZXBlbmQodGhpcyk7XG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiBpbnNlcnRCZWZvcmUoc2VsZWN0b3IpIHtcbiAgY29uc3QgYmVmb3JlID0gJChzZWxlY3Rvcik7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgaWYgKGJlZm9yZS5sZW5ndGggPT09IDEpIHtcbiAgICAgIGJlZm9yZVswXS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzW2ldLCBiZWZvcmVbMF0pO1xuICAgIH0gZWxzZSBpZiAoYmVmb3JlLmxlbmd0aCA+IDEpIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYmVmb3JlLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIGJlZm9yZVtqXS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzW2ldLmNsb25lTm9kZSh0cnVlKSwgYmVmb3JlW2pdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5zZXJ0QWZ0ZXIoc2VsZWN0b3IpIHtcbiAgY29uc3QgYWZ0ZXIgPSAkKHNlbGVjdG9yKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBpZiAoYWZ0ZXIubGVuZ3RoID09PSAxKSB7XG4gICAgICBhZnRlclswXS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzW2ldLCBhZnRlclswXS5uZXh0U2libGluZyk7XG4gICAgfSBlbHNlIGlmIChhZnRlci5sZW5ndGggPiAxKSB7XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGFmdGVyLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIGFmdGVyW2pdLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXNbaV0uY2xvbmVOb2RlKHRydWUpLCBhZnRlcltqXS5uZXh0U2libGluZyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG5leHQoc2VsZWN0b3IpIHtcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIGlmIChzZWxlY3Rvcikge1xuICAgICAgaWYgKHRoaXNbMF0ubmV4dEVsZW1lbnRTaWJsaW5nICYmICQodGhpc1swXS5uZXh0RWxlbWVudFNpYmxpbmcpLmlzKHNlbGVjdG9yKSkge1xuICAgICAgICByZXR1cm4gJChbdGhpc1swXS5uZXh0RWxlbWVudFNpYmxpbmddKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuICQoW10pO1xuICAgIH1cblxuICAgIGlmICh0aGlzWzBdLm5leHRFbGVtZW50U2libGluZykgcmV0dXJuICQoW3RoaXNbMF0ubmV4dEVsZW1lbnRTaWJsaW5nXSk7XG4gICAgcmV0dXJuICQoW10pO1xuICB9XG5cbiAgcmV0dXJuICQoW10pO1xufVxuXG5mdW5jdGlvbiBuZXh0QWxsKHNlbGVjdG9yKSB7XG4gIGNvbnN0IG5leHRFbHMgPSBbXTtcbiAgbGV0IGVsID0gdGhpc1swXTtcbiAgaWYgKCFlbCkgcmV0dXJuICQoW10pO1xuXG4gIHdoaWxlIChlbC5uZXh0RWxlbWVudFNpYmxpbmcpIHtcbiAgICBjb25zdCBuZXh0ID0gZWwubmV4dEVsZW1lbnRTaWJsaW5nOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbiAgICBpZiAoc2VsZWN0b3IpIHtcbiAgICAgIGlmICgkKG5leHQpLmlzKHNlbGVjdG9yKSkgbmV4dEVscy5wdXNoKG5leHQpO1xuICAgIH0gZWxzZSBuZXh0RWxzLnB1c2gobmV4dCk7XG5cbiAgICBlbCA9IG5leHQ7XG4gIH1cblxuICByZXR1cm4gJChuZXh0RWxzKTtcbn1cblxuZnVuY3Rpb24gcHJldihzZWxlY3Rvcikge1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgZWwgPSB0aGlzWzBdO1xuXG4gICAgaWYgKHNlbGVjdG9yKSB7XG4gICAgICBpZiAoZWwucHJldmlvdXNFbGVtZW50U2libGluZyAmJiAkKGVsLnByZXZpb3VzRWxlbWVudFNpYmxpbmcpLmlzKHNlbGVjdG9yKSkge1xuICAgICAgICByZXR1cm4gJChbZWwucHJldmlvdXNFbGVtZW50U2libGluZ10pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gJChbXSk7XG4gICAgfVxuXG4gICAgaWYgKGVsLnByZXZpb3VzRWxlbWVudFNpYmxpbmcpIHJldHVybiAkKFtlbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nXSk7XG4gICAgcmV0dXJuICQoW10pO1xuICB9XG5cbiAgcmV0dXJuICQoW10pO1xufVxuXG5mdW5jdGlvbiBwcmV2QWxsKHNlbGVjdG9yKSB7XG4gIGNvbnN0IHByZXZFbHMgPSBbXTtcbiAgbGV0IGVsID0gdGhpc1swXTtcbiAgaWYgKCFlbCkgcmV0dXJuICQoW10pO1xuXG4gIHdoaWxlIChlbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nKSB7XG4gICAgY29uc3QgcHJldiA9IGVsLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgIGlmIChzZWxlY3Rvcikge1xuICAgICAgaWYgKCQocHJldikuaXMoc2VsZWN0b3IpKSBwcmV2RWxzLnB1c2gocHJldik7XG4gICAgfSBlbHNlIHByZXZFbHMucHVzaChwcmV2KTtcblxuICAgIGVsID0gcHJldjtcbiAgfVxuXG4gIHJldHVybiAkKHByZXZFbHMpO1xufVxuXG5mdW5jdGlvbiBzaWJsaW5ncyhzZWxlY3Rvcikge1xuICByZXR1cm4gdGhpcy5uZXh0QWxsKHNlbGVjdG9yKS5hZGQodGhpcy5wcmV2QWxsKHNlbGVjdG9yKSk7XG59XG5cbmZ1bmN0aW9uIHBhcmVudChzZWxlY3Rvcikge1xuICBjb25zdCBwYXJlbnRzID0gW107IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBpZiAodGhpc1tpXS5wYXJlbnROb2RlICE9PSBudWxsKSB7XG4gICAgICBpZiAoc2VsZWN0b3IpIHtcbiAgICAgICAgaWYgKCQodGhpc1tpXS5wYXJlbnROb2RlKS5pcyhzZWxlY3RvcikpIHBhcmVudHMucHVzaCh0aGlzW2ldLnBhcmVudE5vZGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFyZW50cy5wdXNoKHRoaXNbaV0ucGFyZW50Tm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICQocGFyZW50cyk7XG59XG5cbmZ1bmN0aW9uIHBhcmVudHMoc2VsZWN0b3IpIHtcbiAgY29uc3QgcGFyZW50cyA9IFtdOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgbGV0IHBhcmVudCA9IHRoaXNbaV0ucGFyZW50Tm9kZTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgaWYgKHNlbGVjdG9yKSB7XG4gICAgICAgIGlmICgkKHBhcmVudCkuaXMoc2VsZWN0b3IpKSBwYXJlbnRzLnB1c2gocGFyZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgI
1HBhcmVudHMucHVzaChwYXJlbnQpO1xuICAgICAgfVxuXG4gICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gJChwYXJlbnRzKTtcbn1cblxuZnVuY3Rpb24gY2xvc2VzdChzZWxlY3Rvcikge1xuICBsZXQgY2xvc2VzdCA9IHRoaXM7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICBpZiAodHlwZW9mIHNlbGVjdG9yID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiAkKFtdKTtcbiAgfVxuXG4gIGlmICghY2xvc2VzdC5pcyhzZWxlY3RvcikpIHtcbiAgICBjbG9zZXN0ID0gY2xvc2VzdC5wYXJlbnRzKHNlbGVjdG9yKS5lcSgwKTtcbiAgfVxuXG4gIHJldHVybiBjbG9zZXN0O1xufVxuXG5mdW5jdGlvbiBmaW5kKHNlbGVjdG9yKSB7XG4gIGNvbnN0IGZvdW5kRWxlbWVudHMgPSBbXTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCBmb3VuZCA9IHRoaXNbaV0ucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGZvdW5kLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICBmb3VuZEVsZW1lbnRzLnB1c2goZm91bmRbal0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAkKGZvdW5kRWxlbWVudHMpO1xufVxuXG5mdW5jdGlvbiBjaGlsZHJlbihzZWxlY3Rvcikge1xuICBjb25zdCBjaGlsZHJlbiA9IFtdOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgY29uc3QgY2hpbGROb2RlcyA9IHRoaXNbaV0uY2hpbGRyZW47XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNoaWxkTm9kZXMubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgIGlmICghc2VsZWN0b3IgfHwgJChjaGlsZE5vZGVzW2pdKS5pcyhzZWxlY3RvcikpIHtcbiAgICAgICAgY2hpbGRyZW4ucHVzaChjaGlsZE5vZGVzW2pdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gJChjaGlsZHJlbik7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZSgpIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgaWYgKHRoaXNbaV0ucGFyZW50Tm9kZSkgdGhpc1tpXS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXNbaV0pO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIGRldGFjaCgpIHtcbiAgcmV0dXJuIHRoaXMucmVtb3ZlKCk7XG59XG5cbmZ1bmN0aW9uIGFkZCguLi5lbHMpIHtcbiAgY29uc3QgZG9tID0gdGhpcztcbiAgbGV0IGk7XG4gIGxldCBqO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBlbHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCB0b0FkZCA9ICQoZWxzW2ldKTtcblxuICAgIGZvciAoaiA9IDA7IGogPCB0b0FkZC5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgZG9tLnB1c2godG9BZGRbal0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkb207XG59XG5cbmZ1bmN0aW9uIGVtcHR5KCkge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCBlbCA9IHRoaXNbaV07XG5cbiAgICBpZiAoZWwubm9kZVR5cGUgPT09IDEpIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZWwuY2hpbGROb2Rlcy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICBpZiAoZWwuY2hpbGROb2Rlc1tqXS5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgZWwuY2hpbGROb2Rlc1tqXS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsLmNoaWxkTm9kZXNbal0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGVsLnRleHRDb250ZW50ID0gJyc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXG5mdW5jdGlvbiBzY3JvbGxUbyguLi5hcmdzKSB7XG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICBsZXQgW2xlZnQsIHRvcCwgZHVyYXRpb24sIGVhc2luZywgY2FsbGJhY2tdID0gYXJncztcblxuICBpZiAoYXJncy5sZW5ndGggPT09IDQgJiYgdHlwZW9mIGVhc2luZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gZWFzaW5nO1xuICAgIFtsZWZ0LCB0b3AsIGR1cmF0aW9uLCBjYWxsYmFjaywgZWFzaW5nXSA9IGFyZ3M7XG4gIH1cblxuICBpZiAodHlwZW9mIGVhc2luZyA9PT0gJ3VuZGVmaW5lZCcpIGVhc2luZyA9ICdzd2luZyc7XG4gIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gYW5pbWF0ZSgpIHtcbiAgICBjb25zdCBlbCA9IHRoaXM7XG4gICAgbGV0IGN1cnJlbnRUb3A7XG4gICAgbGV0IGN1cnJlbnRMZWZ0O1xuICAgIGxldCBtYXhUb3A7XG4gICAgbGV0IG1heExlZnQ7XG4gICAgbGV0IG5ld1RvcDtcbiAgICBsZXQgbmV3TGVmdDtcbiAgICBsZXQgc2Nyb2xsVG9wOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbiAgICBsZXQgc2Nyb2xsTGVmdDsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gICAgbGV0IGFuaW1hdGVUb3AgPSB0b3AgPiAwIHx8IHRvcCA9PT0gMDtcbiAgICBsZXQgYW5pbWF0ZUxlZnQgPSBsZWZ0ID4gMCB8fCBsZWZ0ID09PSAwO1xuXG4gICAgaWYgKHR5cGVvZiBlYXNpbmcgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBlYXNpbmcgPSAnc3dpbmcnO1xuICAgIH1cblxuICAgIGlmIChhbmltYXRlVG9wKSB7XG4gICAgICBjdXJyZW50VG9wID0gZWwuc2Nyb2xsVG9wO1xuXG4gICAgICBpZiAoIWR1cmF0aW9uKSB7XG4gICAgICAgIGVsLnNjcm9sbFRvcCA9IHRvcDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYW5pbWF0ZUxlZnQpIHtcbiAgICAgIGN1cnJlbnRMZWZ0ID0gZWwuc2Nyb2xsTGVmdDtcblxuICAgICAgaWYgKCFkdXJhdGlvbikge1xuICAgICAgICBlbC5zY3JvbGxMZWZ0ID0gbGVmdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWR1cmF0aW9uKSByZXR1cm47XG5cbiAgICBpZiAoYW5pbWF0ZVRvcCkge1xuICAgICAgbWF4VG9wID0gZWwuc2Nyb2xsSGVpZ2h0IC0gZWwub2Zmc2V0SGVpZ2h0O1xuICAgICAgbmV3VG9wID0gTWF0aC5tYXgoTWF0aC5taW4odG9wLCBtYXhUb3ApLCAwKTtcbiAgICB9XG5cbiAgICBpZiAoYW5pbWF0ZUxlZnQpIHtcbiAgICAgIG1heExlZnQgPSBlbC5zY3JvbGxXaWR0aCAtIGVsLm9mZnNldFdpZHRoO1xuICAgICAgbmV3TGVmdCA9IE1hdGgubWF4KE1hdGgubWluKGxlZnQsIG1heExlZnQpLCAwKTtcbiAgICB9XG5cbiAgICBsZXQgc3RhcnRUaW1lID0gbnVsbDtcbiAgICBpZiAoYW5pbWF0ZVRvcCAmJi
1BuZXdUb3AgPT09IGN1cnJlbnRUb3ApIGFuaW1hdGVUb3AgPSBmYWxzZTtcbiAgICBpZiAoYW5pbWF0ZUxlZnQgJiYgbmV3TGVmdCA9PT0gY3VycmVudExlZnQpIGFuaW1hdGVMZWZ0ID0gZmFsc2U7XG5cbiAgICBmdW5jdGlvbiByZW5kZXIodGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpKSB7XG4gICAgICBpZiAoc3RhcnRUaW1lID09PSBudWxsKSB7XG4gICAgICAgIHN0YXJ0VGltZSA9IHRpbWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByb2dyZXNzID0gTWF0aC5tYXgoTWF0aC5taW4oKHRpbWUgLSBzdGFydFRpbWUpIC8gZHVyYXRpb24sIDEpLCAwKTtcbiAgICAgIGNvbnN0IGVhc2VQcm9ncmVzcyA9IGVhc2luZyA9PT0gJ2xpbmVhcicgPyBwcm9ncmVzcyA6IDAuNSAtIE1hdGguY29zKHByb2dyZXNzICogTWF0aC5QSSkgLyAyO1xuICAgICAgbGV0IGRvbmU7XG4gICAgICBpZiAoYW5pbWF0ZVRvcCkgc2Nyb2xsVG9wID0gY3VycmVudFRvcCArIGVhc2VQcm9ncmVzcyAqIChuZXdUb3AgLSBjdXJyZW50VG9wKTtcbiAgICAgIGlmIChhbmltYXRlTGVmdCkgc2Nyb2xsTGVmdCA9IGN1cnJlbnRMZWZ0ICsgZWFzZVByb2dyZXNzICogKG5ld0xlZnQgLSBjdXJyZW50TGVmdCk7XG5cbiAgICAgIGlmIChhbmltYXRlVG9wICYmIG5ld1RvcCA+IGN1cnJlbnRUb3AgJiYgc2Nyb2xsVG9wID49IG5ld1RvcCkge1xuICAgICAgICBlbC5zY3JvbGxUb3AgPSBuZXdUb3A7XG4gICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoYW5pbWF0ZVRvcCAmJiBuZXdUb3AgPCBjdXJyZW50VG9wICYmIHNjcm9sbFRvcCA8PSBuZXdUb3ApIHtcbiAgICAgICAgZWwuc2Nyb2xsVG9wID0gbmV3VG9wO1xuICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFuaW1hdGVMZWZ0ICYmIG5ld0xlZnQgPiBjdXJyZW50TGVmdCAmJiBzY3JvbGxMZWZ0ID49IG5ld0xlZnQpIHtcbiAgICAgICAgZWwuc2Nyb2xsTGVmdCA9IG5ld0xlZnQ7XG4gICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoYW5pbWF0ZUxlZnQgJiYgbmV3TGVmdCA8IGN1cnJlbnRMZWZ0ICYmIHNjcm9sbExlZnQgPD0gbmV3TGVmdCkge1xuICAgICAgICBlbC5zY3JvbGxMZWZ0ID0gbmV3TGVmdDtcbiAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChkb25lKSB7XG4gICAgICAgIGlmIChjYWxsYmFjaykgY2FsbGJhY2soKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoYW5pbWF0ZVRvcCkgZWwuc2Nyb2xsVG9wID0gc2Nyb2xsVG9wO1xuICAgICAgaWYgKGFuaW1hdGVMZWZ0KSBlbC5zY3JvbGxMZWZ0ID0gc2Nyb2xsTGVmdDtcbiAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVuZGVyKTtcbiAgICB9XG5cbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHJlbmRlcik7XG4gIH0pO1xufSAvLyBzY3JvbGxUb3AodG9wLCBkdXJhdGlvbiwgZWFzaW5nLCBjYWxsYmFjaykge1xuXG5cbmZ1bmN0aW9uIHNjcm9sbFRvcCguLi5hcmdzKSB7XG4gIGxldCBbdG9wLCBkdXJhdGlvbiwgZWFzaW5nLCBjYWxsYmFja10gPSBhcmdzO1xuXG4gIGlmIChhcmdzLmxlbmd0aCA9PT0gMyAmJiB0eXBlb2YgZWFzaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgW3RvcCwgZHVyYXRpb24sIGNhbGxiYWNrLCBlYXNpbmddID0gYXJncztcbiAgfVxuXG4gIGNvbnN0IGRvbSA9IHRoaXM7XG5cbiAgaWYgKHR5cGVvZiB0b3AgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKGRvbS5sZW5ndGggPiAwKSByZXR1cm4gZG9tWzBdLnNjcm9sbFRvcDtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBkb20uc2Nyb2xsVG8odW5kZWZpbmVkLCB0b3AsIGR1cmF0aW9uLCBlYXNpbmcsIGNhbGxiYWNrKTtcbn1cblxuZnVuY3Rpb24gc2Nyb2xsTGVmdCguLi5hcmdzKSB7XG4gIGxldCBbbGVmdCwgZHVyYXRpb24sIGVhc2luZywgY2FsbGJhY2tdID0gYXJncztcblxuICBpZiAoYXJncy5sZW5ndGggPT09IDMgJiYgdHlwZW9mIGVhc2luZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIFtsZWZ0LCBkdXJhdGlvbiwgY2FsbGJhY2ssIGVhc2luZ10gPSBhcmdzO1xuICB9XG5cbiAgY29uc3QgZG9tID0gdGhpcztcblxuICBpZiAodHlwZW9mIGxlZnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKGRvbS5sZW5ndGggPiAwKSByZXR1cm4gZG9tWzBdLnNjcm9sbExlZnQ7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gZG9tLnNjcm9sbFRvKGxlZnQsIHVuZGVmaW5lZCwgZHVyYXRpb24sIGVhc2luZywgY2FsbGJhY2spO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuZnVuY3Rpb24gYW5pbWF0ZShpbml0aWFsUHJvcHMsIGluaXRpYWxQYXJhbXMpIHtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gIGNvbnN0IGVscyA9IHRoaXM7XG4gIGNvbnN0IGEgPSB7XG4gICAgcHJvcHM6IE9iamVjdC5hc3NpZ24oe30sIGluaXRpYWxQcm9wcyksXG4gICAgcGFyYW1zOiBPYmplY3QuYXNzaWduKHtcbiAgICAgIGR1cmF0aW9uOiAzMDAsXG4gICAgICBlYXNpbmc6ICdzd2luZycgLy8gb3IgJ2xpbmVhcidcblxuICAgICAgLyogQ2FsbGJhY2tzXG4gICAgICBiZWdpbihlbGVtZW50cylcbiAgICAgIGNvbXBsZXRlKGVsZW1lbnRzKVxuICAgICAgcHJvZ3Jlc3MoZWxlbWVudHMsIGNvbXBsZXRlLCByZW1haW5pbmcsIHN0YXJ0LCB0d2VlblZhbHVlKVxuICAgICAgKi9cblxuICAgIH0sIGluaXRpYWxQYXJhbXMpLFxuICAgIGVsZW1lbnRzOiBlbHMsXG4gICAgYW5pbWF0aW5nOiBmYWxzZSxcbiAgICBxdWU6IFtdLFxuXG4gICAgZWFzaW5nUHJvZ3Jlc3MoZWFzaW5nLCBwcm9ncmVzcykge1xuICAgICAgaWYgKGVhc2luZyA9PT0gJ3N3aW5nJykge1xuICAgICAgICByZXR1cm4gMC41IC0gTWF0aC5jb3MocHJvZ3Jlc3MgKiBNYXRoLlBJKSAvIDI7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgZWFzaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBlYXNpbmcocHJvZ3Jlc3MpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJvZ3Jlc3M7XG4gICAgfSxcblxuICAgI
1HN0b3AoKSB7XG4gICAgICBpZiAoYS5mcmFtZUlkKSB7XG4gICAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShhLmZyYW1lSWQpO1xuICAgICAgfVxuXG4gICAgICBhLmFuaW1hdGluZyA9IGZhbHNlO1xuICAgICAgYS5lbGVtZW50cy5lYWNoKGVsID0+IHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGVsO1xuICAgICAgICBkZWxldGUgZWxlbWVudC5kb203QW5pbWF0ZUluc3RhbmNlO1xuICAgICAgfSk7XG4gICAgICBhLnF1ZSA9IFtdO1xuICAgIH0sXG5cbiAgICBkb25lKGNvbXBsZXRlKSB7XG4gICAgICBhLmFuaW1hdGluZyA9IGZhbHNlO1xuICAgICAgYS5lbGVtZW50cy5lYWNoKGVsID0+IHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGVsO1xuICAgICAgICBkZWxldGUgZWxlbWVudC5kb203QW5pbWF0ZUluc3RhbmNlO1xuICAgICAgfSk7XG4gICAgICBpZiAoY29tcGxldGUpIGNvbXBsZXRlKGVscyk7XG5cbiAgICAgIGlmIChhLnF1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHF1ZSA9IGEucXVlLnNoaWZ0KCk7XG4gICAgICAgIGEuYW5pbWF0ZShxdWVbMF0sIHF1ZVsxXSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFuaW1hdGUocHJvcHMsIHBhcmFtcykge1xuICAgICAgaWYgKGEuYW5pbWF0aW5nKSB7XG4gICAgICAgIGEucXVlLnB1c2goW3Byb3BzLCBwYXJhbXNdKTtcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gW107IC8vIERlZmluZSAmIENhY2hlIEluaXRpYWxzICYgVW5pdHNcblxuICAgICAgYS5lbGVtZW50cy5lYWNoKChlbCwgaW5kZXgpID0+IHtcbiAgICAgICAgbGV0IGluaXRpYWxGdWxsVmFsdWU7XG4gICAgICAgIGxldCBpbml0aWFsVmFsdWU7XG4gICAgICAgIGxldCB1bml0O1xuICAgICAgICBsZXQgZmluYWxWYWx1ZTtcbiAgICAgICAgbGV0IGZpbmFsRnVsbFZhbHVlO1xuICAgICAgICBpZiAoIWVsLmRvbTdBbmltYXRlSW5zdGFuY2UpIGEuZWxlbWVudHNbaW5kZXhdLmRvbTdBbmltYXRlSW5zdGFuY2UgPSBhO1xuICAgICAgICBlbGVtZW50c1tpbmRleF0gPSB7XG4gICAgICAgICAgY29udGFpbmVyOiBlbFxuICAgICAgICB9O1xuICAgICAgICBPYmplY3Qua2V5cyhwcm9wcykuZm9yRWFjaChwcm9wID0+IHtcbiAgICAgICAgICBpbml0aWFsRnVsbFZhbHVlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwsIG51bGwpLmdldFByb3BlcnR5VmFsdWUocHJvcCkucmVwbGFjZSgnLCcsICcuJyk7XG4gICAgICAgICAgaW5pdGlhbFZhbHVlID0gcGFyc2VGbG9hdChpbml0aWFsRnVsbFZhbHVlKTtcbiAgICAgICAgICB1bml0ID0gaW5pdGlhbEZ1bGxWYWx1ZS5yZXBsYWNlKGluaXRpYWxWYWx1ZSwgJycpO1xuICAgICAgICAgIGZpbmFsVmFsdWUgPSBwYXJzZUZsb2F0KHByb3BzW3Byb3BdKTtcbiAgICAgICAgICBmaW5hbEZ1bGxWYWx1ZSA9IHByb3BzW3Byb3BdICsgdW5pdDtcbiAgICAgICAgICBlbGVtZW50c1tpbmRleF1bcHJvcF0gPSB7XG4gICAgICAgICAgICBpbml0aWFsRnVsbFZhbHVlLFxuICAgICAgICAgICAgaW5pdGlhbFZhbHVlLFxuICAgICAgICAgICAgdW5pdCxcbiAgICAgICAgICAgIGZpbmFsVmFsdWUsXG4gICAgICAgICAgICBmaW5hbEZ1bGxWYWx1ZSxcbiAgICAgICAgICAgIGN1cnJlbnRWYWx1ZTogaW5pdGlhbFZhbHVlXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGxldCBzdGFydFRpbWUgPSBudWxsO1xuICAgICAgbGV0IHRpbWU7XG4gICAgICBsZXQgZWxlbWVudHNEb25lID0gMDtcbiAgICAgIGxldCBwcm9wc0RvbmUgPSAwO1xuICAgICAgbGV0IGRvbmU7XG4gICAgICBsZXQgYmVnYW4gPSBmYWxzZTtcbiAgICAgIGEuYW5pbWF0aW5nID0gdHJ1ZTtcblxuICAgICAgZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIGxldCBwcm9ncmVzcztcbiAgICAgICAgbGV0IGVhc2VQcm9ncmVzczsgLy8gbGV0IGVsO1xuXG4gICAgICAgIGlmICghYmVnYW4pIHtcbiAgICAgICAgICBiZWdhbiA9IHRydWU7XG4gICAgICAgICAgaWYgKHBhcmFtcy5iZWdpbikgcGFyYW1zLmJlZ2luKGVscyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhcnRUaW1lID09PSBudWxsKSB7XG4gICAgICAgICAgc3RhcnRUaW1lID0gdGltZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJhbXMucHJvZ3Jlc3MpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgICBwYXJhbXMucHJvZ3Jlc3MoZWxzLCBNYXRoLm1heChNYXRoLm1pbigodGltZSAtIHN0YXJ0VGltZSkgLyBwYXJhbXMuZHVyYXRpb24sIDEpLCAwKSwgc3RhcnRUaW1lICsgcGFyYW1zLmR1cmF0aW9uIC0gdGltZSA8IDAgPyAwIDogc3RhcnRUaW1lICsgcGFyYW1zLmR1cmF0aW9uIC0gdGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsZW1lbnRzLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICAgICAgY29uc3QgZWwgPSBlbGVtZW50O1xuICAgICAgICAgIGlmIChkb25lIHx8IGVsLmRvbmUpIHJldHVybjtcbiAgICAgICAgICBPYmplY3Qua2V5cyhwcm9wcykuZm9yRWFjaChwcm9wID0+IHtcbiAgICAgICAgICAgIGlmIChkb25lIHx8IGVsLmRvbmUpIHJldHVybjtcbiAgICAgICAgICAgIHByb2dyZXNzID0gTWF0aC5tYXgoTWF0aC5taW4oKHRpbWUgLSBzdGFydFRpbWUpIC8gcGFyYW1zLmR1cmF0aW9uLCAxKSwgMCk7XG4gICAgICAgICAgICBlYXNlUHJvZ3Jlc3MgPSBhLmVhc2luZ1Byb2dyZXNzKHBhcmFtcy5lYXNpbmcsIHByb2dyZXNzKTtcbiAgICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgICAgaW5pdGlhbFZhbHVlLFxuICAgICAgICAgICAgICBmaW5hbFZhbHVlLFxuICAgICAgICAgICAgICB1bml0XG4gICAgICAgICAgICB9ID0gZWxbcHJvcF07XG4gICAgICAgICAgICBlbFtwcm9wXS5jdXJyZW50VmFsdWUgPSBpbml0aWFsVmFsdWUgKyBlYXNlUHJvZ3Jlc3MgKiAoZmluYWxWYWx1ZSAtIGluaXRpYWxWYWx1ZSk7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSBlbFtwcm9wXS5jdXJyZW50VmFsdWU7XG5cbiAgICAgICAgICAgIGlmIChmaW5hbFZhbHVlID4gaW5pdGlhbFZhbHVlICYmIGN1cnJlbnRWYWx1ZSA+PSBmaW5hbFZhbHVlIHx8IGZpbmFsVmFsdWUgPCBpbml0aWFsVmFsdWUgJiYgY3VycmVudFZhbHVlIDw9IGZpbmFsVmFsdWUpIHtcbiAgICAgICAgICAgICAgZWwuY29udGFpbmVyLnN0eWxlW3Byb3BdID0gZmluYWxWYWx1ZSArIHVuaXQ7XG4gICAgICAgICAgICAgI
1HByb3BzRG9uZSArPSAxO1xuXG4gICAgICAgICAgICAgIGlmIChwcm9wc0RvbmUgPT09IE9iamVjdC5rZXlzKHByb3BzKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBlbC5kb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBlbGVtZW50c0RvbmUgKz0gMTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChlbGVtZW50c0RvbmUgPT09IGVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICAgIGEuZG9uZShwYXJhbXMuY29tcGxldGUpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGVsLmNvbnRhaW5lci5zdHlsZVtwcm9wXSA9IGN1cnJlbnRWYWx1ZSArIHVuaXQ7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoZG9uZSkgcmV0dXJuOyAvLyBUaGVuIGNhbGxcblxuICAgICAgICBhLmZyYW1lSWQgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHJlbmRlcik7XG4gICAgICB9XG5cbiAgICAgIGEuZnJhbWVJZCA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVuZGVyKTtcbiAgICAgIHJldHVybiBhO1xuICAgIH1cblxuICB9O1xuXG4gIGlmIChhLmVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBlbHM7XG4gIH1cblxuICBsZXQgYW5pbWF0ZUluc3RhbmNlO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYS5lbGVtZW50cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGlmIChhLmVsZW1lbnRzW2ldLmRvbTdBbmltYXRlSW5zdGFuY2UpIHtcbiAgICAgIGFuaW1hdGVJbnN0YW5jZSA9IGEuZWxlbWVudHNbaV0uZG9tN0FuaW1hdGVJbnN0YW5jZTtcbiAgICB9IGVsc2UgYS5lbGVtZW50c1tpXS5kb203QW5pbWF0ZUluc3RhbmNlID0gYTtcbiAgfVxuXG4gIGlmICghYW5pbWF0ZUluc3RhbmNlKSB7XG4gICAgYW5pbWF0ZUluc3RhbmNlID0gYTtcbiAgfVxuXG4gIGlmIChpbml0aWFsUHJvcHMgPT09ICdzdG9wJykge1xuICAgIGFuaW1hdGVJbnN0YW5jZS5zdG9wKCk7XG4gIH0gZWxzZSB7XG4gICAgYW5pbWF0ZUluc3RhbmNlLmFuaW1hdGUoYS5wcm9wcywgYS5wYXJhbXMpO1xuICB9XG5cbiAgcmV0dXJuIGVscztcbn1cblxuZnVuY3Rpb24gc3RvcCgpIHtcbiAgY29uc3QgZWxzID0gdGhpcztcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGVscy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGlmIChlbHNbaV0uZG9tN0FuaW1hdGVJbnN0YW5jZSkge1xuICAgICAgZWxzW2ldLmRvbTdBbmltYXRlSW5zdGFuY2Uuc3RvcCgpO1xuICAgIH1cbiAgfVxufVxuXG5jb25zdCBub1RyaWdnZXIgPSAncmVzaXplIHNjcm9sbCcuc3BsaXQoJyAnKTtcblxuZnVuY3Rpb24gc2hvcnRjdXQobmFtZSkge1xuICBmdW5jdGlvbiBldmVudEhhbmRsZXIoLi4uYXJncykge1xuICAgIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAobm9UcmlnZ2VyLmluZGV4T2YobmFtZSkgPCAwKSB7XG4gICAgICAgICAgaWYgKG5hbWUgaW4gdGhpc1tpXSkgdGhpc1tpXVtuYW1lXSgpO2Vsc2Uge1xuICAgICAgICAgICAgJCh0aGlzW2ldKS50cmlnZ2VyKG5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5vbihuYW1lLCAuLi5hcmdzKTtcbiAgfVxuXG4gIHJldHVybiBldmVudEhhbmRsZXI7XG59XG5cbmNvbnN0IGNsaWNrID0gc2hvcnRjdXQoJ2NsaWNrJyk7XG5jb25zdCBibHVyID0gc2hvcnRjdXQoJ2JsdXInKTtcbmNvbnN0IGZvY3VzID0gc2hvcnRjdXQoJ2ZvY3VzJyk7XG5jb25zdCBmb2N1c2luID0gc2hvcnRjdXQoJ2ZvY3VzaW4nKTtcbmNvbnN0IGZvY3Vzb3V0ID0gc2hvcnRjdXQoJ2ZvY3Vzb3V0Jyk7XG5jb25zdCBrZXl1cCA9IHNob3J0Y3V0KCdrZXl1cCcpO1xuY29uc3Qga2V5ZG93biA9IHNob3J0Y3V0KCdrZXlkb3duJyk7XG5jb25zdCBrZXlwcmVzcyA9IHNob3J0Y3V0KCdrZXlwcmVzcycpO1xuY29uc3Qgc3VibWl0ID0gc2hvcnRjdXQoJ3N1Ym1pdCcpO1xuY29uc3QgY2hhbmdlID0gc2hvcnRjdXQoJ2NoYW5nZScpO1xuY29uc3QgbW91c2Vkb3duID0gc2hvcnRjdXQoJ21vdXNlZG93bicpO1xuY29uc3QgbW91c2Vtb3ZlID0gc2hvcnRjdXQoJ21vdXNlbW92ZScpO1xuY29uc3QgbW91c2V1cCA9IHNob3J0Y3V0KCdtb3VzZXVwJyk7XG5jb25zdCBtb3VzZWVudGVyID0gc2hvcnRjdXQoJ21vdXNlZW50ZXInKTtcbmNvbnN0IG1vdXNlbGVhdmUgPSBzaG9ydGN1dCgnbW91c2VsZWF2ZScpO1xuY29uc3QgbW91c2VvdXQgPSBzaG9ydGN1dCgnbW91c2VvdXQnKTtcbmNvbnN0IG1vdXNlb3ZlciA9IHNob3J0Y3V0KCdtb3VzZW92ZXInKTtcbmNvbnN0IHRvdWNoc3RhcnQgPSBzaG9ydGN1dCgndG91Y2hzdGFydCcpO1xuY29uc3QgdG91Y2hlbmQgPSBzaG9ydGN1dCgndG91Y2hlbmQnKTtcbmNvbnN0IHRvdWNobW92ZSA9IHNob3J0Y3V0KCd0b3VjaG1vdmUnKTtcbmNvbnN0IHJlc2l6ZSA9IHNob3J0Y3V0KCdyZXNpemUnKTtcbmNvbnN0IHNjcm9sbCA9IHNob3J0Y3V0KCdzY3JvbGwnKTtcblxuZXhwb3J0IGRlZmF1bHQgJDtcbmV4cG9ydCB7ICQsIGFkZCwgYWRkQ2xhc3MsIGFuaW1hdGUsIGFuaW1hdGlvbkVuZCwgYXBwZW5kLCBhcHBlbmRUbywgYX
1R0ciwgYmx1ciwgY2hhbmdlLCBjaGlsZHJlbiwgY2xpY2ssIGNsb3Nlc3QsIGNzcywgZGF0YSwgZGF0YXNldCwgZGV0YWNoLCBlYWNoLCBlbXB0eSwgZXEsIGZpbHRlciwgZmluZCwgZm9jdXMsIGZvY3VzaW4sIGZvY3Vzb3V0LCBoYXNDbGFzcywgaGVpZ2h0LCBoaWRlLCBodG1sLCBpbmRleCwgaW5zZXJ0QWZ0ZXIsIGluc2VydEJlZm9yZSwgaXMsIGtleWRvd24sIGtleXByZXNzLCBrZXl1cCwgbW91c2Vkb3duLCBtb3VzZWVudGVyLCBtb3VzZWxlYXZlLCBtb3VzZW1vdmUsIG1vdXNlb3V0LCBtb3VzZW92ZXIsIG1vdXNldXAsIG5leHQsIG5leHRBbGwsIG9mZiwgb2Zmc2V0LCBvbiwgb25jZSwgb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGgsIHBhcmVudCwgcGFyZW50cywgcHJlcGVuZCwgcHJlcGVuZFRvLCBwcmV2LCBwcmV2QWxsLCBwcm9wLCByZW1vdmUsIHJlbW92ZUF0dHIsIHJlbW92ZUNsYXNzLCByZW1vdmVEYXRhLCByZXNpemUsIHNjcm9sbCwgc2Nyb2xsTGVmdCwgc2Nyb2xsVG8sIHNjcm9sbFRvcCwgc2hvdywgc2libGluZ3MsIHN0b3AsIHN0eWxlcywgc3VibWl0LCB0ZXh0LCB0b2dnbGVDbGFzcywgdG91Y2hlbmQsIHRvdWNobW92ZSwgdG91Y2hzdGFydCwgdHJhbnNmb3JtLCB0cmFuc2l0aW9uLCB0cmFuc2l0aW9uRW5kLCB0cmFuc2l0aW9uU3RhcnQsIHRyaWdnZXIsIHZhbCwgdmFsdWUsIHdpZHRoIH07XG4iLCJpbXBvcnQgeyAkLCBhZGRDbGFzcywgcmVtb3ZlQ2xhc3MsIGhhc0NsYXNzLCB0b2dnbGVDbGFzcywgYXR0ciwgcmVtb3ZlQXR0ciwgdHJhbnNmb3JtLCB0cmFuc2l0aW9uLCBvbiwgb2ZmLCB0cmlnZ2VyLCB0cmFuc2l0aW9uRW5kLCBvdXRlcldpZHRoLCBvdXRlckhlaWdodCwgc3R5bGVzLCBvZmZzZXQsIGNzcywgZWFjaCwgaHRtbCwgdGV4dCwgaXMsIGluZGV4LCBlcSwgYXBwZW5kLCBwcmVwZW5kLCBuZXh0LCBuZXh0QWxsLCBwcmV2LCBwcmV2QWxsLCBwYXJlbnQsIHBhcmVudHMsIGNsb3Nlc3QsIGZpbmQsIGNoaWxkcmVuLCBmaWx0ZXIsIHJlbW92ZSB9IGZyb20gJ2RvbTcnO1xuY29uc3QgTWV0aG9kcyA9IHtcbiAgYWRkQ2xhc3MsXG4gIHJlbW92ZUNsYXNzLFxuICBoYXNDbGFzcyxcbiAgdG9nZ2xlQ2xhc3MsXG4gIGF0dHIsXG4gIHJlbW92ZUF0dHIsXG4gIHRyYW5zZm9ybSxcbiAgdHJhbnNpdGlvbixcbiAgb24sXG4gIG9mZixcbiAgdHJpZ2dlcixcbiAgdHJhbnNpdGlvbkVuZCxcbiAgb3V0ZXJXaWR0aCxcbiAgb3V0ZXJIZWlnaHQsXG4gIHN0eWxlcyxcbiAgb2Zmc2V0LFxuICBjc3MsXG4gIGVhY2gsXG4gIGh0bWwsXG4gIHRleHQsXG4gIGlzLFxuICBpbmRleCxcbiAgZXEsXG4gIGFwcGVuZCxcbiAgcHJlcGVuZCxcbiAgbmV4dCxcbiAgbmV4dEFsbCxcbiAgcHJldixcbiAgcHJldkFsbCxcbiAgcGFyZW50LFxuICBwYXJlbnRzLFxuICBjbG9zZXN0LFxuICBmaW5kLFxuICBjaGlsZHJlbixcbiAgZmlsdGVyLFxuICByZW1vdmVcbn07XG5PYmplY3Qua2V5cyhNZXRob2RzKS5mb3JFYWNoKG1ldGhvZE5hbWUgPT4ge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoJC5mbiwgbWV0aG9kTmFtZSwge1xuICAgIHZhbHVlOiBNZXRob2RzW21ldGhvZE5hbWVdLFxuICAgIHdyaXRhYmxlOiB0cnVlXG4gIH0pO1xufSk7XG5leHBvcnQgZGVmYXVsdCAkOyIsImltcG9ydCB7IGdldFdpbmRvdyB9IGZyb20gJ3Nzci13aW5kb3cnO1xuXG5mdW5jdGlvbiBkZWxldGVQcm9wcyhvYmopIHtcbiAgY29uc3Qgb2JqZWN0ID0gb2JqO1xuICBPYmplY3Qua2V5cyhvYmplY3QpLmZvckVhY2goa2V5ID0+IHtcbiAgICB0cnkge1xuICAgICAgb2JqZWN0W2tleV0gPSBudWxsO1xuICAgIH0gY2F0Y2ggKGUpIHsvLyBubyBnZXR0ZXIgZm9yIG9iamVjdFxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBkZWxldGUgb2JqZWN0W2tleV07XG4gICAgfSBjYXRjaCAoZSkgey8vIHNvbWV0aGluZyBnb3Qgd3JvbmdcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBuZXh0VGljayhjYWxsYmFjaywgZGVsYXkgPSAwKSB7XG4gIHJldHVybiBzZXRUaW1lb3V0KGNhbGxiYWNrLCBkZWxheSk7XG59XG5cbmZ1bmN0aW9uIG5vdygpIHtcbiAgcmV0dXJuIERhdGUubm93KCk7XG59XG5cbmZ1bmN0aW9uIGdldENvbXB1dGVkU3R5bGUoZWwpIHtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gIGxldCBzdHlsZTtcblxuICBpZiAod2luZG93LmdldENvbXB1dGVkU3R5bGUpIHtcbiAgICBzdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsLCBudWxsKTtcbiAgfVxuXG4gIGlmICghc3R5bGUgJiYgZWwuY3VycmVudFN0eWxlKSB7XG4gICAgc3R5bGUgPSBlbC5jdXJyZW50U3R5bGU7XG4gIH1cblxuICBpZiAoIXN0eWxlKSB7XG4gICAgc3R5bGUgPSBlbC5zdHlsZTtcbiAgfVxuXG4gIHJldHVybiBzdHlsZTtcbn1cblxuZnVuY3Rpb24gZ2V0VHJhbnNsYXRlKGVsLCBheGlzID0gJ3gnKSB7XG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICBsZXQgbWF0cml4O1xuICBsZXQgY3VyVHJhbnNmb3JtO1xuICBsZXQgdHJhbnNmb3JtTWF0cml4O1xuICBjb25zdCBjdXJTdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoZWwsIG51bGwpO1xuXG4gIGlmICh3aW5kb3cuV2ViS2l0Q1NTTWF0cml4KSB7XG4gICAgY3VyVHJhbnNmb3JtID0gY3VyU3R5bGUudHJhbnNmb3JtIHx8IGN1clN0eWxlLndlYmtpdFRyYW5zZm9ybTtcblxuICAgIGlmIChjdXJUcmFuc2Zvcm0uc3BsaXQoJywnKS5sZW5ndGggPiA2KSB7XG4gICAgICBjdXJUcmFuc2Zvcm0gPSBjdXJUcmFuc2Zvcm0uc3BsaXQoJywgJykubWFwKGEgPT4gYS5yZXBsYWNlKCcsJywgJy4nKSkuam9pbignLCAnKTtcbiAgICB9IC8vIFNvbWUgb2xkIHZlcnNpb25zIG9mIFdlYmtpdCBjaG9rZSB3aGVuICdub25lJyBpcyBwYXNzZWQ7IHBhc3NcbiAgICAvLyBlbXB0eSBzdHJpbmcgaW5zdGVhZCBpbiB0aGlzIGNhc2VcblxuXG4gICAgdHJhbnNmb3JtTWF0cml4ID0gbmV3IHdpbmRvdy5XZWJLaXRDU1NNYXRyaXgoY3VyVHJhbnNmb3JtID09PSAnbm9uZScgPyAnJyA6IGN1clRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNmb3JtTWF0cml4ID0gY3VyU3R5bGUuTW96VHJhbnNmb3JtIHx8IGN1clN0eWxlLk9UcmFuc2Zvcm0gfHwgY3VyU3R5bGUuTXNUcmFuc2Zvcm0gfHwgY3VyU3R5bGUubXNUcmFuc2Zvcm0gfHwgY3VyU3R5bGUudHJhbnNmb3JtIHx8IGN1clN0eWxlLmdldFByb3BlcnR5VmFsdWUoJ3RyYW5zZm9ybScpLnJlcGxhY2UoJ3RyYW5zbGF0ZSgnLCAnbWF0cml4KDEsIDAsIDAsIDEsJyk7XG4gICAgbWF0cml4ID0gdHJhbnNmb3JtTWF0cml4LnRvU3RyaW5nKCkuc3BsaXQoJywnKTtcbiAgfVxuXG4gIGlmIChheGlzID09PSAneCcpIHtcbiAgICAvLyBMYXRlc3QgQ2hyb21lIGFuZCB3ZWJraXRzIEZpeFxuICAgIGlmICh3aW5kb3cuV2ViS2l0Q1NTTWF0cml4KSBjdXJUcmFuc2Zvcm0gPSB0cmFuc2Zvcm1NYXRyaXgubTQxOyAvLyBDcmF6eSBJRTEwIE1hdHJpeFxuICAgIGVsc2UgaWYgKG1hdHJpeC5sZW5ndGggPT09IDE2KSBjdXJUcmFuc2Zvcm0gPSBwYXJzZU
1Zsb2F0KG1hdHJpeFsxMl0pOyAvLyBOb3JtYWwgQnJvd3NlcnNcbiAgICBlbHNlIGN1clRyYW5zZm9ybSA9IHBhcnNlRmxvYXQobWF0cml4WzRdKTtcbiAgfVxuXG4gIGlmIChheGlzID09PSAneScpIHtcbiAgICAvLyBMYXRlc3QgQ2hyb21lIGFuZCB3ZWJraXRzIEZpeFxuICAgIGlmICh3aW5kb3cuV2ViS2l0Q1NTTWF0cml4KSBjdXJUcmFuc2Zvcm0gPSB0cmFuc2Zvcm1NYXRyaXgubTQyOyAvLyBDcmF6eSBJRTEwIE1hdHJpeFxuICAgIGVsc2UgaWYgKG1hdHJpeC5sZW5ndGggPT09IDE2KSBjdXJUcmFuc2Zvcm0gPSBwYXJzZUZsb2F0KG1hdHJpeFsxM10pOyAvLyBOb3JtYWwgQnJvd3NlcnNcbiAgICBlbHNlIGN1clRyYW5zZm9ybSA9IHBhcnNlRmxvYXQobWF0cml4WzVdKTtcbiAgfVxuXG4gIHJldHVybiBjdXJUcmFuc2Zvcm0gfHwgMDtcbn1cblxuZnVuY3Rpb24gaXNPYmplY3Qobykge1xuICByZXR1cm4gdHlwZW9mIG8gPT09ICdvYmplY3QnICYmIG8gIT09IG51bGwgJiYgby5jb25zdHJ1Y3RvciAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobykuc2xpY2UoOCwgLTEpID09PSAnT2JqZWN0Jztcbn1cblxuZnVuY3Rpb24gaXNOb2RlKG5vZGUpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2Ygd2luZG93LkhUTUxFbGVtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQ7XG4gIH1cblxuICByZXR1cm4gbm9kZSAmJiAobm9kZS5ub2RlVHlwZSA9PT0gMSB8fCBub2RlLm5vZGVUeXBlID09PSAxMSk7XG59XG5cbmZ1bmN0aW9uIGV4dGVuZCguLi5hcmdzKSB7XG4gIGNvbnN0IHRvID0gT2JqZWN0KGFyZ3NbMF0pO1xuICBjb25zdCBub0V4dGVuZCA9IFsnX19wcm90b19fJywgJ2NvbnN0cnVjdG9yJywgJ3Byb3RvdHlwZSddO1xuXG4gIGZvciAobGV0IGkgPSAxOyBpIDwgYXJncy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGNvbnN0IG5leHRTb3VyY2UgPSBhcmdzW2ldO
11xuXG4gICAgaWYgKG5leHRTb3VyY2UgIT09IHVuZGVmaW5lZCAmJiBuZXh0U291cmNlICE9PSBudWxsICYmICFpc05vZGUobmV4dFNvdXJjZSkpIHtcbiAgICAgIGNvbnN0IGtleXNBcnJheSA9IE9iamVjdC5rZXlzKE9iamVjdChuZXh0U291cmNlKSkuZmlsdGVyKGtleSA9PiBub0V4dGVuZC5pbmRleE9mKGtleSkgPCAwKTtcblxuICAgICAgZm9yIChsZXQgbmV4dEluZGV4ID0gMCwgbGVuID0ga2V5c0FycmF5Lmxlbmd0aDsgbmV4dEluZGV4IDwgbGVuOyBuZXh0SW5kZXggKz0gMSkge1xuICAgICAgICBjb25zdCBuZXh0S2V5ID0ga2V5c0FycmF5W25leHRJbmRleF07XG4gICAgICAgIGNvbnN0IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG5leHRTb3VyY2UsIG5leHRLZXkpO1xuXG4gICAgICAgIGlmIChkZXNjICE9PSB1bmRlZmluZWQgJiYgZGVzYy5lbnVtZXJhYmxlKSB7XG4gICAgICAgICAgaWYgKGlzT2JqZWN0KHRvW25leHRLZXldKSAmJiBpc09iamVjdChuZXh0U291cmNlW25leHRLZXldKSkge1xuICAgICAgICAgICAgaWYgKG5leHRTb3VyY2VbbmV4dEtleV0uX19zd2lwZXJfXykge1xuICAgICAgICAgICAgICB0b1tuZXh0S2V5XSA9IG5leHRTb3VyY2VbbmV4dEtleV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBleHRlbmQodG9bbmV4dEtleV0sIG5leHRTb3VyY2VbbmV4dEtleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoIWlzT2JqZWN0KHRvW25leHRLZXldKSAmJiBpc09iamVjdChuZXh0U291cmNlW25leHRLZXldKSkge1xuICAgICAgICAgICAgdG9bbmV4dEtleV0gPSB7fTtcblxuICAgICAgICAgICAgaWYgKG5leHRTb3VyY2VbbmV4dEtleV0uX19zd2lwZXJfXykge1xuICAgICAgICAgICAgICB0b1tuZXh0S2V5XSA9IG5leHRTb3VyY2VbbmV4dEtleV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBleHRlbmQodG9bbmV4dEtleV0sIG5leHRTb3VyY2VbbmV4dEtleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b1tuZXh0S2V5XSA9IG5leHRTb3VyY2VbbmV4dEtleV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRvO1xufVxuXG5mdW5jdGlvbiBzZXRDU1NQcm9wZXJ0eShlbCwgdmFyTmFtZSwgdmFyVmFsdWUpIHtcbiAgZWwuc3R5bGUuc2V0UHJvcGVydHkodmFyTmFtZSwgdmFyVmFsdWUpO1xufVxuXG5mdW5jdGlvbiBhbmltYXRlQ1NTTW9kZVNjcm9sbCh7XG4gIHN3aXBlcixcbiAgdGFyZ2V0UG9zaXRpb24sXG4gIHNpZGVcbn0pIHtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gIGNvbnN0IHN0YXJ0UG9zaXRpb24gPSAtc3dpcGVyLnRyYW5zbGF0ZTtcbiAgbGV0IHN0YXJ0VGltZSA9IG51bGw7XG4gIGxldCB0aW1lO1xuICBjb25zdCBkdXJhdGlvbiA9IHN3aXBlci5wYXJhbXMuc3BlZWQ7XG4gIHN3aXBlci53cmFwcGVyRWwuc3R5bGUuc2Nyb2xsU25hcFR5cGUgPSAnbm9uZSc7XG4gIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShzd2lwZXIuY3NzTW9kZUZyYW1lSUQpO1xuICBjb25zdCBkaXIgPSB0YXJnZXRQb3NpdGlvbiA+IHN0YXJ0UG9zaXRpb24gPyAnbmV4dCcgOiAncHJldic7XG5cbiAgY29uc3QgaXNPdXRPZkJvdW5kID0gKGN1cnJlbnQsIHRhcmdldCkgPT4ge1xuICAgIHJldHVybiBkaXIgPT09ICduZXh0JyAmJiBjdXJyZW50ID49IHRhcmdldCB8fCBkaXIgPT09ICdwcmV2JyAmJiBjdXJyZW50IDw9IHRhcmdldDtcbiAgfTtcblxuICBjb25zdCBhbmltYXRlID0gKCkgPT4ge1xuICAgIHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgIGlmIChzdGFydFRpbWUgPT09IG51bGwpIHtcbiAgICAgIHN0YXJ0VGltZSA9IHRpbWU7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvZ3Jlc3MgPSBNYXRoLm1heChNYXRoLm1pbigodGltZSAtIHN0YXJ0VGltZSkgLyBkdXJhdGlvbiwgMSksIDApO1xuICAgIGNvbnN0IGVhc2VQcm9ncmVzcyA9IDAuNSAtIE1hdGguY29zKHByb2dyZXNzICogTWF0aC5QSSkgLyAyO1xuICAgIGxldCBjdXJyZW50UG9zaXRpb24gPSBzdGFydFBvc2l0aW9uICsgZWFzZVByb2dyZXNzICogKHRhcmdldFBvc2l0aW9uIC0gc3RhcnRQb3NpdGlvbik7XG5cbiAgICBpZiAoaXNPdXRPZkJvdW5kKGN1cnJlbnRQb3NpdGlvbiwgdGFyZ2V0UG9zaXRpb24pKSB7XG4gICAgICBjdXJyZW50UG9zaXRpb24gPSB0YXJnZXRQb3NpdGlvbjtcbiAgICB9XG5cbiAgICBzd2lwZXIud3JhcHBlckVsLnNjcm9sbFRvKHtcbiAgICAgIFtzaWRlXTogY3VycmVudFBvc2l0aW9uXG4gICAgfSk7XG5cbiAgICBpZiAoaXNPdXRPZkJvdW5kKGN1cnJlbnRQb3NpdGlvbiwgdGFyZ2V0UG9zaXRpb24pKSB7XG4gICAgICBzd2lwZXIud3JhcHBlckVsLnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XG4gICAgICBzd2lwZXIud3JhcHBlckVsLnN0eWxlLnNjcm9sbFNuYXBUeXBlID0gJyc7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZS5vdmVyZmxvdyA9ICcnO1xuICAgICAgICBzd2lwZXIud3JhcHBlckVsLnNjcm9sbFRvKHtcbiAgICAgICAgICBbc2lkZV06IGN1cnJlbnRQb3NpdGlvblxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lKHN3aXBlci5jc3NNb2RlRnJhbWVJRCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpcGVyLmNzc01vZGVGcmFtZUlEID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShhbmltYXRlKTtcbiAgfTtcblxuICBhbmltYXRlKCk7XG59XG5cbmV4cG9ydCB7IGFuaW1hdGVDU1NNb2RlU2Nyb2xsLCBkZWxldGVQcm9wcywgbmV4dFRpY2ssIG5vdywgZ2V0VHJhbnNsYXRlLCBpc09iamVjdCwgZXh0ZW5kLCBnZXRDb21wdXRlZFN0eWxlLCBzZXRDU1NQcm9wZXJ0eSB9OyIsImltcG9ydCB7IGdldFdpbmRvdywgZ2V0RG9jdW1lbnQgfSBmcm9tICdzc3Itd2luZG93JztcbmxldCBzdXBwb3J0O1xuXG5mdW5jdGlvbiBjYWxjU3VwcG9ydCgpIHtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgcmV0dXJuIHtcbiAgICBzbW9vdGhTY3JvbGw6IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiAnc2Nyb2xsQmVoYXZpb3InIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZSxcbiAgICB0b3VjaDogISEoJ29udG91Y2hzdGFydCcgaW4gd2luZG93IHx8IHdpbmRvdy5Eb2N1bWVudFRvdWNoICYmIGRvY3VtZW50IGluc3RhbmNlb2Ygd2luZG93LkRvY3VtZW50VG91Y2gpLFxuICAgIHBhc3NpdmVMaXN0ZW5lcjogZnVuY3Rpb24gY2hlY2tQYXNzaXZlTGlzdGVuZXIoKSB7XG4gICAgICBsZXQgc3VwcG9ydHNQYXNzaXZlID0gZmFsc2U7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG9wdHMgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdwYXNzaXZlJywge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgI
1HN1cHBvcnRzUGFzc2l2ZSA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndGVzdFBhc3NpdmVMaXN0ZW5lcicsIG51bGwsIG9wdHMpO1xuICAgICAgfSBjYXRjaCAoZSkgey8vIE5vIHN1cHBvcnRcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN1cHBvcnRzUGFzc2l2ZTtcbiAgICB9KCksXG4gICAgZ2VzdHVyZXM6IGZ1bmN0aW9uIGNoZWNrR2VzdHVyZXMoKSB7XG4gICAgICByZXR1cm4gJ29uZ2VzdHVyZXN0YXJ0JyBpbiB3aW5kb3c7XG4gICAgfSgpXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldFN1cHBvcnQoKSB7XG4gIGlmICghc3VwcG9ydCkge1xuICAgIHN1cHBvcnQgPSBjYWxjU3VwcG9ydCgpO1xuICB9XG5cbiAgcmV0dXJuIHN1cHBvcnQ7XG59XG5cbmV4cG9ydCB7IGdldFN1cHBvcnQgfTsiLCJpbXBvcnQgeyBnZXRXaW5kb3cgfSBmcm9tICdzc3Itd2luZG93JztcbmltcG9ydCB7IGdldFN1cHBvcnQgfSBmcm9tICcuL2dldC1zdXBwb3J0LmpzJztcbmxldCBkZXZpY2VDYWNoZWQ7XG5cbmZ1bmN0aW9uIGNhbGNEZXZpY2Uoe1xuICB1c2VyQWdlbnRcbn0gPSB7fSkge1xuICBjb25zdCBzdXBwb3J0ID0gZ2V0U3VwcG9ydCgpO1xuICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgY29uc3QgcGxhdGZvcm0gPSB3aW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtO1xuICBjb25zdCB1YSA9IHVzZXJBZ2VudCB8fCB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgY29uc3QgZGV2aWNlID0ge1xuICAgIGlvczogZmFsc2UsXG4gICAgYW5kcm9pZDogZmFsc2VcbiAgfTtcbiAgY29uc3Qgc2NyZWVuV2lkdGggPSB3aW5kb3cuc2NyZWVuLndpZHRoO1xuICBjb25zdCBzY3JlZW5IZWlnaHQgPSB3aW5kb3cuc2NyZWVuLmhlaWdodDtcbiAgY29uc3QgYW5kcm9pZCA9IHVhLm1hdGNoKC8oQW5kcm9pZCk7P1tcXHNcXC9dKyhbXFxkLl0rKT8vKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gIGxldCBpcGFkID0gdWEubWF0Y2goLyhpUGFkKS4qT1NcXHMoW1xcZF9dKykvKTtcbiAgY29uc3QgaXBvZCA9IHVhLm1hdGNoKC8oaVBvZCkoLipPU1xccyhbXFxkX10rKSk/Lyk7XG4gIGNvbnN0IGlwaG9uZSA9ICFpcGFkICYmIHVhLm1hdGNoKC8oaVBob25lXFxzT1N8aU9TKVxccyhbXFxkX10rKS8pO1xuICBjb25zdCB3aW5kb3dzID0gcGxhdGZvcm0gPT09ICdXaW4zMic7XG4gIGxldCBtYWNvcyA9IHBsYXRmb3JtID09PSAnTWFjSW50ZWwnOyAvLyBpUGFkT3MgMTMgZml4XG5cbiAgY29uc3QgaVBhZFNjcmVlbnMgPSBbJzEwMjR4MTM2NicsICcxMzY2eDEwMjQnLCAnODM0eDExOTQnLCAnMTE5NHg4MzQnLCAnODM0eDExMTInLCAnMTExMng4MzQnLCAnNzY4eDEwMjQnLCAnMTAyNHg3NjgnLCAnODIweDExODAnLCAnMTE4MHg4MjAnLCAnODEweDEwODAnLCAnMTA4MHg4MTAnXTtcblxuICBpZiAoIWlwYWQgJiYgbWFjb3MgJiYgc3VwcG9ydC50b3VjaCAmJiBpUGFkU2NyZWVucy5pbmRleE9mKGAke3NjcmVlbldpZHRofXgke3NjcmVlbkhlaWdodH1gKSA+PSAwKSB7XG4gICAgaXBhZCA9IHVhLm1hdGNoKC8oVmVyc2lvbilcXC8oW1xcZC5dKykvKTtcbiAgICBpZiAoIWlwYWQpIGlwYWQgPSBbMCwgMSwgJzEzXzBfMCddO1xuICAgIG1hY29zID0gZmFsc2U7XG4gIH0gLy8gQW5kcm9pZFxuXG5cbiAgaWYgKGFuZHJvaWQgJiYgIXdpbmRvd3MpIHtcbiAgICBkZXZpY2Uub3MgPSAnYW5kcm9pZCc7XG4gICAgZGV2aWNlLmFuZHJvaWQgPSB0cnVlO1xuICB9XG5cbiAgaWYgKGlwYWQgfHwgaXBob25lIHx8IGlwb2QpIHtcbiAgICBkZXZpY2Uub3MgPSAnaW9zJztcbiAgICBkZXZpY2UuaW9zID0gdHJ1ZTtcbiAgfSAvLyBFeHBvcnQgb2JqZWN0XG5cblxuICByZXR1cm4gZGV2aWNlO1xufVxuXG5mdW5jdGlvbiBnZXREZXZpY2Uob3ZlcnJpZGVzID0ge30pIHtcbiAgaWYgKCFkZXZpY2VDYWNoZWQpIHtcbiAgICBkZXZpY2VDYWNoZWQgPSBjYWxjRGV2aWNlKG92ZXJyaWRlcyk7XG4gIH1cblxuICByZXR1cm4gZGV2aWNlQ2FjaGVkO1xufVxuXG5leHBvcnQgeyBnZXREZXZpY2UgfTsiLCJpbXBvcnQgeyBnZXRXaW5kb3cgfSBmcm9tICdzc3Itd2luZG93JztcbmxldCBicm93c2VyO1xuXG5mdW5jdGlvbiBjYWxjQnJvd3NlcigpIHtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG5cbiAgZnVuY3Rpb24gaXNTYWZhcmkoKSB7XG4gICAgY29uc3QgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpO1xuICAgIHJldHVybiB1YS5pbmRleE9mKCdzYWZhcmknKSA+PSAwICYmIHVhLmluZGV4T2YoJ2Nocm9tZScpIDwgMCAmJiB1YS5pbmRleE9mKCdhbmRyb2lkJykgPCAwO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBpc1NhZmFyaTogaXNTYWZhcmkoKSxcbiAgICBpc1dlYlZpZXc6IC8oaVBob25lfGlQb2R8aVBhZCkuKkFwcGxlV2ViS2l0KD8hLipTYWZhcmkpL2kudGVzdCh3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudClcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0QnJvd3NlcigpIHtcbiAgaWYgKCFicm93c2VyKSB7XG4gICAgYnJvd3NlciA9IGNhbGNCcm93c2VyKCk7XG4gIH1cblxuICByZXR1cm4gYnJvd3Nlcjtcbn1cblxuZXhwb3J0IHsgZ2V0QnJvd3NlciB9OyIsImltcG9ydCB7IGdldFdpbmRvdyB9IGZyb20gJ3Nzci13aW5kb3cnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVzaXplKHtcbiAgc3dpcGVyLFxuICBvbixcbiAgZW1pdFxufSkge1xuICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgbGV0IG9ic2VydmVyID0gbnVsbDtcbiAgbGV0IGFuaW1hdGlvbkZyYW1lID0gbnVsbDtcblxuICBjb25zdCByZXNpemVIYW5kbGVyID0gKCkgPT4ge1xuICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5pbml0aWFsaXplZCkgcmV0dXJuO1xuICAgIGVtaXQoJ2JlZm9yZVJlc2l6ZScpO1xuICAgIGVtaXQoJ3Jlc2l6ZScpO1xuICB9O1xuXG4gIGNvbnN0IGNyZWF0ZU9ic2VydmVyID0gKCkgPT4ge1xuICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQgfHwgIXN3aXBlci5pbml0aWFsaXplZCkgcmV0dXJuO1xuICAgIG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKGVudHJpZXMgPT4ge1xuICAgICAgYW5pbWF0aW9uRnJhbWUgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgI
1HdpZHRoLFxuICAgICAgICAgIGhlaWdodFxuICAgICAgICB9ID0gc3dpcGVyO1xuICAgICAgICBsZXQgbmV3V2lkdGggPSB3aWR0aDtcbiAgICAgICAgbGV0IG5ld0hlaWdodCA9IGhlaWdodDtcbiAgICAgICAgZW50cmllcy5mb3JFYWNoKCh7XG4gICAgICAgICAgY29udGVudEJveFNpemUsXG4gICAgICAgICAgY29udGVudFJlY3QsXG4gICAgICAgICAgdGFyZ2V0XG4gICAgICAgIH0pID0+IHtcbiAgICAgICAgICBpZiAodGFyZ2V0ICYmIHRhcmdldCAhPT0gc3dpcGVyLmVsKSByZXR1cm47XG4gICAgICAgICAgbmV3V2lkdGggPSBjb250ZW50UmVjdCA/IGNvbnRlbnRSZWN0LndpZHRoIDogKGNvbnRlbnRCb3hTaXplWzBdIHx8IGNvbnRlbnRCb3hTaXplKS5pbmxpbmVTaXplO1xuICAgICAgICAgIG5ld0hlaWdodCA9IGNvbnRlbnRSZWN0ID8gY29udGVudFJlY3QuaGVpZ2h0IDogKGNvbnRlbnRCb3hTaXplWzBdIHx8IGNvbnRlbnRCb3hTaXplKS5ibG9ja1NpemU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChuZXdXaWR0aCAhPT0gd2lkdGggfHwgbmV3SGVpZ2h0ICE9PSBoZWlnaHQpIHtcbiAgICAgICAgICByZXNpemVIYW5kbGVyKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoc3dpcGVyLmVsKTtcbiAgfTtcblxuICBjb25zdCByZW1vdmVPYnNlcnZlciA9ICgpID0+IHtcbiAgICBpZiAoYW5pbWF0aW9uRnJhbWUpIHtcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShhbmltYXRpb25GcmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKG9ic2VydmVyICYmIG9ic2VydmVyLnVub2JzZXJ2ZSAmJiBzd2lwZXIuZWwpIHtcbiAgICAgIG9ic2VydmVyLnVub2JzZXJ2ZShzd2lwZXIuZWwpO1xuICAgICAgb2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBvcmllbnRhdGlvbkNoYW5nZUhhbmRsZXIgPSAoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCB8fCAhc3dpcGVyLmluaXRpYWxpemVkKSByZXR1cm47XG4gICAgZW1pdCgnb3JpZW50YXRpb25jaGFuZ2UnKTtcbiAgfTtcblxuICBvbignaW5pdCcsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5yZXNpemVPYnNlcnZlciAmJiB0eXBlb2Ygd2luZG93LlJlc2l6ZU9ic2VydmVyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgY3JlYXRlT2JzZXJ2ZXIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgcmVzaXplSGFuZGxlcik7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ29yaWVudGF0aW9uY2hhbmdlJywgb3JpZW50YXRpb25DaGFuZ2VIYW5kbGVyKTtcbiAgfSk7XG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xuICAgIHJlbW92ZU9ic2VydmVyKCk7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHJlc2l6ZUhhbmRsZXIpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIG9yaWVudGF0aW9uQ2hhbmdlSGFuZGxlcik7XG4gIH0pO1xufSIsImltcG9ydCB7IGdldFdpbmRvdyB9IGZyb20gJ3Nzci13aW5kb3cnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gT2JzZXJ2ZXIoe1xuICBzd2lwZXIsXG4gIGV4dGVuZFBhcmFtcyxcbiAgb24sXG4gIGVtaXRcbn0pIHtcbiAgY29uc3Qgb2JzZXJ2ZXJzID0gW107XG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuXG4gIGNvbnN0IGF0dGFjaCA9ICh0YXJnZXQsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICAgIGNvbnN0IE9ic2VydmVyRnVuYyA9IHdpbmRvdy5NdXRhdGlvbk9ic2VydmVyIHx8IHdpbmRvdy5XZWJraXRNdXRhdGlvbk9ic2VydmVyO1xuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IE9ic2VydmVyRnVuYyhtdXRhdGlvbnMgPT4ge1xuICAgICAgLy8gVGhlIG9ic2VydmVyVXBkYXRlIGV2ZW50IHNob3VsZCBvbmx5IGJlIHRyaWdnZXJlZFxuICAgICAgLy8gb25jZSBkZXNwaXRlIHRoZSBudW1iZXIgb2YgbXV0YXRpb25zLiAgQWRkaXRpb25hbFxuICAgICAgLy8gdHJpZ2dlcnMgYXJlIHJlZHVuZGFudCBhbmQgYXJlIHZlcnkgY29zdGx5XG4gICAgICBpZiAobXV0YXRpb25zLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBlbWl0KCdvYnNlcnZlclVwZGF0ZScsIG11dGF0aW9uc1swXSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb2JzZXJ2ZXJVcGRhdGUgPSBmdW5jdGlvbiBvYnNlcnZlclVwZGF0ZSgpIHtcbiAgICAgICAgZW1pdCgnb2JzZXJ2ZXJVcGRhdGUnLCBtdXRhdGlvbnNbMF0pO1xuICAgICAgfTtcblxuICAgICAgaWYgKHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpIHtcbiAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShvYnNlcnZlclVwZGF0ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW5kb3cuc2V0VGltZW91dChvYnNlcnZlclVwZGF0ZSwgMCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZSh0YXJnZXQsIHtcbiAgICAgIGF0dHJpYnV0ZXM6IHR5cGVvZiBvcHRpb25zLmF0dHJpYnV0ZXMgPT09ICd1bmRlZmluZWQnID8gdHJ1ZSA6IG9wdGlvbnMuYXR0cmlidXRlcyxcbiAgICAgIGNoaWxkTGlzdDogdHlwZW9mIG9wdGlvbnMuY2hpbGRMaXN0ID09PSAndW5kZWZpbmVkJyA/IHRydWUgOiBvcHRpb25zLmNoaWxkTGlzdCxcbiAgICAgIGNoYXJhY3RlckRhdGE6IHR5cGVvZiBvcHRpb25zLmNoYXJhY3RlckRhdGEgPT09ICd1bmRlZmluZWQnID8gdHJ1ZSA6IG9wdGlvbnMuY2hhcmFjdGVyRGF0YVxuICAgIH0pO1xuICAgIG9ic2VydmVycy5wdXNoKG9ic2VydmVyKTtcbiAgfTtcblxuICBjb25zdCBpbml0ID0gKCkgPT4ge1xuICAgIGlmICghc3dpcGVyLnBhcmFtcy5vYnNlcnZlcikgcmV0dXJuO1xuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMub2JzZXJ2ZVBhcmVudHMpIHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lclBhcmVudHMgPSBzd2lwZXIuJGVsLnBhcmVudHMoKTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb250YWluZXJQYXJlbnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGF0dGFjaChjb250YWluZXJQYXJlbnRzW2ldKTtcbiAgICAgIH1cbiAgICB9IC8vIE9ic2VydmUgY29udGFpbmVyXG5cblxuICAgIGF0dGFjaChzd2lwZXIuJGVsWzBdLCB7XG4gICAgICBjaGlsZExpc3Q6IHN3aXBlci5wYXJhbXMub2JzZXJ2ZVNsaWRlQ2hpbGRyZW5cbiAgICB9KTsgLy8gT2JzZXJ2ZSB3cmFwcGVyXG5cbiAgICBhdHRhY2goc3dpcGVyLiR3cmFwcGVyRWxbMF0sIHtcbiAgICAgIGF0dHJpYnV0ZXM6IGZhbHNlXG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgZGVzdHJveSA9ICgpID0+IHtcbiAgICBvYnNlcnZlcnMuZm9yRWFjaChvYnNlcnZlciA9PiB7XG4gICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgfSk7XG4gICAgb2JzZXJ2ZXJzLnNwbGljZSgwLCBvYnNlcnZlcnMubGVuZ3RoKTtcbiAgfTtcblxuICBleHRlbmRQYXJhbXMoe1xuICAgIG9ic2VydmVyOiBmYWxzZSxcbiAgICBvYnNlcnZlUGFyZW50czogZmFsc2UsXG4gICAgb2JzZXJ2ZVNsaWRlQ2hpbGRyZW46IGZhbHNlXG4gI
1H0pO1xuICBvbignaW5pdCcsIGluaXQpO1xuICBvbignZGVzdHJveScsIGRlc3Ryb3kpO1xufSIsIi8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVyc2NvcmUtZGFuZ2xlICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIG9uKGV2ZW50cywgaGFuZGxlciwgcHJpb3JpdHkpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBpZiAoIXNlbGYuZXZlbnRzTGlzdGVuZXJzIHx8IHNlbGYuZGVzdHJveWVkKSByZXR1cm4gc2VsZjtcbiAgICBpZiAodHlwZW9mIGhhbmRsZXIgIT09ICdmdW5jdGlvbicpIHJldHVybiBzZWxmO1xuICAgIGNvbnN0IG1ldGhvZCA9IHByaW9yaXR5ID8gJ3Vuc2hpZnQnIDogJ3B1c2gnO1xuICAgIGV2ZW50cy5zcGxpdCgnICcpLmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgaWYgKCFzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0pIHNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XSA9IFtdO1xuICAgICAgc2VsZi5ldmVudHNMaXN0ZW5lcnNbZXZlbnRdW21ldGhvZF0oaGFuZGxlcik7XG4gICAgfSk7XG4gICAgcmV0dXJuIHNlbGY7XG4gIH0sXG5cbiAgb25jZShldmVudHMsIGhhbmRsZXIsIHByaW9yaXR5KSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgaWYgKCFzZWxmLmV2ZW50c0xpc3RlbmVycyB8fCBzZWxmLmRlc3Ryb3llZCkgcmV0dXJuIHNlbGY7XG4gICAgaWYgKHR5cGVvZiBoYW5kbGVyICE9PSAnZnVuY3Rpb24nKSByZXR1cm4gc2VsZjtcblxuICAgIGZ1bmN0aW9uIG9uY2VIYW5kbGVyKC4uLmFyZ3MpIHtcbiAgICAgIHNlbGYub2ZmKGV2ZW50cywgb25jZUhhbmRsZXIpO1xuXG4gICAgICBpZiAob25jZUhhbmRsZXIuX19lbWl0dGVyUHJveHkpIHtcbiAgICAgICAgZGVsZXRlIG9uY2VIYW5kbGVyLl9fZW1pdHRlclByb3h5O1xuICAgICAgfVxuXG4gICAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgIH1cblxuICAgIG9uY2VIYW5kbGVyLl9fZW1pdHRlclByb3h5ID0gaGFuZGxlcjtcbiAgICByZXR1cm4gc2VsZi5vbihldmVudHMsIG9uY2VIYW5kbGVyLCBwcmlvcml0eSk7XG4gIH0sXG5cbiAgb25BbnkoaGFuZGxlciwgcHJpb3JpdHkpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBpZiAoIXNlbGYuZXZlbnRzTGlzdGVuZXJzIHx8IHNlbGYuZGVzdHJveWVkKSByZXR1cm4gc2VsZjtcbiAgICBpZiAodHlwZW9mIGhhbmRsZXIgIT09ICdmdW5jdGlvbicpIHJldHVybiBzZWxmO1xuICAgIGNvbnN0IG1ldGhvZCA9IHByaW9yaXR5ID8gJ3Vuc2hpZnQnIDogJ3B1c2gnO1xuXG4gICAgaWYgKHNlbGYuZXZlbnRzQW55TGlzdGVuZXJzLmluZGV4T2YoaGFuZGxlcikgPCAwKSB7XG4gICAgICBzZWxmLmV2ZW50c0FueUxpc3RlbmVyc1ttZXRob2RdKGhhbmRsZXIpO1xuICAgIH1cblxuICAgIHJldHVybiBzZWxmO1xuICB9LFxuXG4gIG9mZkFueShoYW5kbGVyKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgaWYgKCFzZWxmLmV2ZW50c0xpc3RlbmVycyB8fCBzZWxmLmRlc3Ryb3llZCkgcmV0dXJuIHNlbGY7XG4gICAgaWYgKCFzZWxmLmV2ZW50c0FueUxpc3RlbmVycykgcmV0dXJuIHNlbGY7XG4gICAgY29uc3QgaW5kZXggPSBzZWxmLmV2ZW50c0FueUxpc3RlbmVycy5pbmRleE9mKGhhbmRsZXIpO1xuXG4gICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgIHNlbGYuZXZlbnRzQW55TGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGY7XG4gIH0sXG5cbiAgb2ZmKGV2ZW50cywgaGFuZGxlcikge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGlmICghc2VsZi5ldmVudHNMaXN0ZW5lcnMgfHwgc2VsZi5kZXN0cm95ZWQpIHJldHVybiBzZWxmO1xuICAgIGlmICghc2VsZi5ldmVudHNMaXN0ZW5lcnMpIHJldHVybiBzZWxmO1xuICAgIGV2ZW50cy5zcGxpdCgnICcpLmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0gPSBbXTtcbiAgICAgIH0gZWxzZSBpZiAoc2VsZi5ldmVudHNMaXN0ZW5lcnNbZXZlbnRdKSB7XG4gICAgICAgIHNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XS5mb3JFYWNoKChldmVudEhhbmRsZXIsIGluZGV4KSA9PiB7XG4gICAgICAgICAgaWYgKGV2ZW50SGFuZGxlciA9PT0gaGFuZGxlciB8fCBldmVudEhhbmRsZXIuX19lbWl0dGVyUHJveHkgJiYgZXZlbnRIYW5kbGVyLl9fZW1pdHRlclByb3h5ID09PSBoYW5kbGVyKSB7XG4gICAgICAgICAgICBzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBzZWxmO1xuICB9LFxuXG4gIGVtaXQoLi4uYXJncykge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGlmICghc2VsZi5ldmVudHNMaXN0ZW5lcnMgfHwgc2VsZi5kZXN0cm95ZWQpIHJldHVybiBzZWxmO1xuICAgIGlmICghc2VsZi5ldmVudHNMaXN0ZW5lcnMpIHJldHVybiBzZWxmO1xuICAgIGxldCBldmVudHM7XG4gICAgbGV0IGRhdGE7XG4gICAgbGV0IGNvbnRleHQ7XG5cbiAgICBpZiAodHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnIHx8IEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcbiAgICAgIGV2ZW50cyA9IGFyZ3NbMF07XG4gICAgICBkYXRhID0gYXJncy5zbGljZSgxLCBhcmdzLmxlbmd0aCk7XG4gICAgICBjb250ZXh0ID0gc2VsZjtcbiAgICB9IGVsc2Uge1xuICAgICAgZXZlbnRzID0gYXJnc1swXS5ldmVudHM7XG4gICAgICBkYXRhID0gYXJnc1swXS5kYXRhO1xuICAgICAgY29udGV4dCA9IGFyZ3NbMF0uY29udGV4dCB8fCBzZWxmO1xuICAgIH1cblxuICAgIGRhdGEudW5zaGlmdChjb250ZXh0KTtcbiAgICBjb25zdCBldmVudHNBcnJheSA9IEFycmF5LmlzQXJyYXkoZXZlbnRzKSA/IGV2ZW50cyA6IGV2ZW50cy5zcGxpdCgnICcpO1xuICAgIGV2ZW50c0FycmF5LmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgaWYgKHNlbGYuZXZlbnRzQW55TGlzdGVuZXJzICYmIHNlbGYuZXZlbnRzQW55TGlzdGVuZXJzLmxlbmd0aCkge1xuICAgICAgICBzZWxmLmV2ZW50c0FueUxpc3RlbmVycy5mb3JFYWNoKGV2ZW50SGFuZGxlciA9PiB7XG4gICAgICAgICAgZXZlbnRIYW5kbGVyLmFwcGx5KGNvbnRleHQsIFtldmVudCwgLi4uZGF0YV0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNlbGYuZXZlbnRzTGlzdGVuZXJzICYmIHNlbGYuZXZlbnRzTGlzdGVuZXJzW2V2ZW50XSkge1xuICAgICAgICBzZWxmLmV2ZW50c0xpc3RlbmVyc1tldmVudF0uZm9yRWFjaChldmVudEhhbmRsZXIgPT4ge1xuICAgICAgICAgIGV2ZW50SGFuZGxlci5hcHBseShjb250ZXh0LCBkYXRhKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHNlbGY7XG4gIH1cblxufTsiLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1cGRhdGVTaXplKCkge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBsZXQgd2lkdGg7XG4gIGxldCBoZWlnaHQ7XG4gIGNvbnN0ICRlbCA9IHN3aXBlci4kZWw7XG5cbiAgaWYgKHR5cGVvZiBzd2lwZXIucGFyYW1zLndpZHRoICE9PSAndW5kZWZpbmVkJyAmJiBzd2lwZXIucGFyYW1zLndpZHRoICE9PSBudWxsKSB7XG4gICAgd2lkdGggPSBzd2lwZXIucGFyYW1zLndpZHRoO1xuICB9IGVsc2Uge1xuICAgIHdpZHRoID0gJGVsWzBdLmNsaWVudFdpZHRoO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBzd2lwZXIucGFyYW1zLmhlaWdodCAhPT0gJ3VuZGVmaW5lZCcgJiYgc3dpcGVyLnBhcmFtcy5oZWlnaHQgIT09IG51bGwpIHtcbiAgICBoZWlnaHQgPSBzd2lwZXIucGFyYW1zLmhlaWdodDtcbiAgfSBlbHNlIHtcbiAgICBoZWlnaHQgPSAkZWxbMF0uY2xpZW50SGVpZ2h0O1xuICB9XG5cbiAgaWYgKHdpZHRoID09PSAwICYmIHN3aXBlci5pc0hvcml6b250YWwoKSB8fCBoZWlnaHQgPT09IDAgJiYgc3dpcGVyLmlzVmVydGljYWwoKSkge1xuICAgIHJldHVybjtcbiAgfSAvLyBTdWJ0cmFjdCBwYWRkaW5nc1xuXG5cbiAgd2lkdGggPSB3aWR0aCAtIHBhcnNlSW50KCRlbC5jc3MoJ3BhZGRpbmctbGVmdCcpIHx8IDAsIDEwKSAtIHBhcnNlSW50KCRlbC5jc3MoJ3BhZGRpbmctcmlnaHQnKSB8fCAwLCAxMCk7XG4gIGhlaWdodCA9IGhlaWdodCAtIHBhcnNlSW50KCRlbC5jc3MoJ3BhZGRpbmctdG9wJykgfHwgMCwgMTApIC0gcGFyc2VJbnQoJGVsLmNzcygncGFkZGluZy1ib3R0b20nKSB8fCAwLCAxMCk7XG4gIGlmIChOdW1iZXIuaXNOYU4od2lkdGgpKSB3aWR0aCA9IDA7XG4gIGlmIChOdW1iZXIuaXNOYU4oaGVpZ2h0KSkgaGVpZ2h0ID0gMDtcbiAgT2JqZWN0LmFzc2lnbihzd2lwZXIsIHtcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgc2l6ZTogc3dpcGVyLmlzSG9yaXpvbn
1RhbCgpID8gd2lkdGggOiBoZWlnaHRcbiAgfSk7XG59IiwiaW1wb3J0IHsgc2V0Q1NTUHJvcGVydHkgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXBkYXRlU2xpZGVzKCkge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuXG4gIGZ1bmN0aW9uIGdldERpcmVjdGlvbkxhYmVsKHByb3BlcnR5KSB7XG4gICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xuICAgICAgcmV0dXJuIHByb3BlcnR5O1xuICAgIH0gLy8gcHJldHRpZXItaWdub3JlXG5cblxuICAgIHJldHVybiB7XG4gICAgICAnd2lkdGgnOiAnaGVpZ2h0JyxcbiAgICAgICdtYXJnaW4tdG9wJzogJ21hcmdpbi1sZWZ0JyxcbiAgICAgICdtYXJnaW4tYm90dG9tICc6ICdtYXJnaW4tcmlnaHQnLFxuICAgICAgJ21hcmdpbi1sZWZ0JzogJ21hcmdpbi10b3AnLFxuICAgICAgJ21hcmdpbi1yaWdodCc6ICdtYXJnaW4tYm90dG9tJyxcbiAgICAgICdwYWRkaW5nLWxlZnQnOiAncGFkZGluZy10b3AnLFxuICAgICAgJ3BhZGRpbmctcmlnaHQnOiAncGFkZGluZy1ib3R0b20nLFxuICAgICAgJ21hcmdpblJpZ2h0JzogJ21hcmdpbkJvdHRvbSdcbiAgICB9W3Byb3BlcnR5XTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldERpcmVjdGlvblByb3BlcnR5VmFsdWUobm9kZSwgbGFiZWwpIHtcbiAgICByZXR1cm4gcGFyc2VGbG9hdChub2RlLmdldFByb3BlcnR5VmFsdWUoZ2V0RGlyZWN0aW9uTGFiZWwobGFiZWwpKSB8fCAwKTtcbiAgfVxuXG4gIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXM7XG4gIGNvbnN0IHtcbiAgICAkd3JhcHBlckVsLFxuICAgIHNpemU6IHN3aXBlclNpemUsXG4gICAgcnRsVHJhbnNsYXRlOiBydGwsXG4gICAgd3JvbmdSVExcbiAgfSA9IHN3aXBlcjtcbiAgY29uc3QgaXNWaXJ0dWFsID0gc3dpcGVyLnZpcnR1YWwgJiYgcGFyYW1zLnZpcnR1YWwuZW5hYmxlZDtcbiAgY29uc3QgcHJldmlvdXNTbGlkZXNMZW5ndGggPSBpc1ZpcnR1YWwgPyBzd2lwZXIudmlydHVhbC5zbGlkZXMubGVuZ3RoIDogc3dpcGVyLnNsaWRlcy5sZW5ndGg7XG4gIGNvbnN0IHNsaWRlcyA9ICR3cmFwcGVyRWwuY2hpbGRyZW4oYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVDbGFzc31gKTtcbiAgY29uc3Qgc2xpZGVzTGVuZ3RoID0gaXNWaXJ0dWFsID8gc3dpcGVyLnZpcnR1YWwuc2xpZGVzLmxlbmd0aCA6IHNsaWRlcy5sZW5ndGg7XG4gIGxldCBzbmFwR3JpZCA9IFtdO1xuICBjb25zdCBzbGlkZXNHcmlkID0gW107XG4gIGNvbnN0IHNsaWRlc1NpemVzR3JpZCA9IFtdO1xuICBsZXQgb2Zmc2V0QmVmb3JlID0gcGFyYW1zLnNsaWRlc09mZnNldEJlZm9yZTtcblxuICBpZiAodHlwZW9mIG9mZnNldEJlZm9yZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIG9mZnNldEJlZm9yZSA9IHBhcmFtcy5zbGlkZXNPZmZzZXRCZWZvcmUuY2FsbChzd2lwZXIpO1xuICB9XG5cbiAgbGV0IG9mZnNldEFmdGVyID0gcGFyYW1zLnNsaWRlc09mZnNldEFmdGVyO1xuXG4gIGlmICh0eXBlb2Ygb2Zmc2V0QWZ0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBvZmZzZXRBZnRlciA9IHBhcmFtcy5zbGlkZXNPZmZzZXRBZnRlci5jYWxsKHN3aXBlcik7XG4gIH1cblxuICBjb25zdCBwcmV2aW91c1NuYXBHcmlkTGVuZ3RoID0gc3dpcGVyLnNuYXBHcmlkLmxlbmd0aDtcbiAgY29uc3QgcHJldmlvdXNTbGlkZXNHcmlkTGVuZ3RoID0gc3dpcGVyLnNsaWRlc0dyaWQubGVuZ3RoO1xuICBsZXQgc3BhY2VCZXR3ZWVuID0gcGFyYW1zLnNwYWNlQmV0d2VlbjtcbiAgbGV0IHNsaWRlUG9zaXRpb24gPSAtb2Zmc2V0QmVmb3JlO1xuICBsZXQgcHJldlNsaWRlU2l6ZSA9IDA7XG4gIGxldCBpbmRleCA9IDA7XG5cbiAgaWYgKHR5cGVvZiBzd2lwZXJTaXplID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygc3BhY2VCZXR3ZWVuID09PSAnc3RyaW5nJyAmJiBzcGFjZUJldHdlZW4uaW5kZXhPZignJScpID49IDApIHtcbiAgICBzcGFjZUJldHdlZW4gPSBwYXJzZUZsb2F0KHNwYWNlQmV0d2Vlbi5yZXBsYWNlKCclJywgJycpKSAvIDEwMCAqIHN3aXBlclNpemU7XG4gIH1cblxuICBzd2lwZXIudmlydHVhbFNpemUgPSAtc3BhY2VCZXR3ZWVuOyAvLyByZXNldCBtYXJnaW5zXG5cbiAgaWYgKHJ0bCkgc2xpZGVzLmNzcyh7XG4gICAgbWFyZ2luTGVmdDogJycsXG4gICAgbWFyZ2luQm90dG9tOiAnJyxcbiAgICBtYXJnaW5Ub3A6ICcnXG4gIH0pO2Vsc2Ugc2xpZGVzLmNzcyh7XG4gICAgbWFyZ2luUmlnaHQ6ICcnLFxuICAgIG1hcmdpbkJvdHRvbTogJycsXG4gICAgbWFyZ2luVG9wOiAnJ1xuICB9KTsgLy8gcmVzZXQgY3NzTW9kZSBvZmZzZXRzXG5cbiAgaWYgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcyAmJiBwYXJhbXMuY3NzTW9kZSkge1xuICAgIHNldENTU1Byb3BlcnR5KHN3aXBlci53cmFwcGVyRWwsICctLXN3aXBlci1jZW50ZXJlZC1vZmZzZXQtYmVmb3JlJywgJycpO1xuICAgIHNldENTU1Byb3BlcnR5KHN3aXBlci53cmFwcGVyRWwsICctLXN3aXBlci1jZW50ZXJlZC1vZmZzZXQtYWZ0ZXInLCAnJyk7XG4gIH1cblxuICBjb25zdCBncmlkRW5hYmxlZCA9IHBhcmFtcy5ncmlkICYmIHBhcmFtcy5ncmlkLnJvd3MgPiAxICYmIHN3aXBlci5ncmlkO1xuXG4gIGlmIChncmlkRW5hYmxlZCkge1xuICAgIHN3aXBlci5ncmlkLmluaXRTbGlkZXMoc2xpZGVzTGVuZ3RoKTtcbiAgfSAvLyBDYWxjIHNsaWRlc1xuXG5cbiAgbGV0IHNsaWRlU2l6ZTtcbiAgY29uc3Qgc2hvdWxkUmVzZXRTbGlkZVNpemUgPSBwYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nICYmIHBhcmFtcy5icmVha3BvaW50cyAmJiBPYmplY3Qua2V5cyhwYXJhbXMuYnJlYWtwb2ludHMpLmZpbHRlcihrZXkgPT4ge1xuICAgIHJldHVybiB0eXBlb2YgcGFyYW1zLmJyZWFrcG9pbnRzW2tleV0uc2xpZGVzUGVyVmlldyAhPT0gJ3VuZGVmaW5lZCc7XG4gIH0pLmxlbmd0aCA+IDA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXNMZW5ndGg7IGkgKz0gMSkge1xuICAgIHNsaWRlU2l6ZSA9IDA7XG4gICAgY29uc3Qgc2xpZGUgPSBzbGlkZXMuZXEoaSk7XG5cbiAgICBpZiAoZ3JpZEVuYWJsZWQpIHtcbiAgICAgIHN3aXBlci5ncmlkLnVwZGF0ZVNsaWRlKGksIHNsaWRlLCBzbGlkZXNMZW5ndGgsIGdldERpcmVjdGlvbkxhYmVsKTtcbiAgICB9XG5cbiAgICBpZiAoc2xpZGUuY3NzKCdkaXNwbGF5J
1ykgPT09ICdub25lJykgY29udGludWU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgIGlmIChwYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nKSB7XG4gICAgICBpZiAoc2hvdWxkUmVzZXRTbGlkZVNpemUpIHtcbiAgICAgICAgc2xpZGVzW2ldLnN0eWxlW2dldERpcmVjdGlvbkxhYmVsKCd3aWR0aCcpXSA9IGBgO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzbGlkZVN0eWxlcyA9IGdldENvbXB1dGVkU3R5bGUoc2xpZGVbMF0pO1xuICAgICAgY29uc3QgY3VycmVudFRyYW5zZm9ybSA9IHNsaWRlWzBdLnN0eWxlLnRyYW5zZm9ybTtcbiAgICAgIGNvbnN0IGN1cnJlbnRXZWJLaXRUcmFuc2Zvcm0gPSBzbGlkZVswXS5zdHlsZS53ZWJraXRUcmFuc2Zvcm07XG5cbiAgICAgIGlmIChjdXJyZW50VHJhbnNmb3JtKSB7XG4gICAgICAgIHNsaWRlWzBdLnN0eWxlLnRyYW5zZm9ybSA9ICdub25lJztcbiAgICAgIH1cblxuICAgICAgaWYgKGN1cnJlbnRXZWJLaXRUcmFuc2Zvcm0pIHtcbiAgICAgICAgc2xpZGVbMF0uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ25vbmUnO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFyYW1zLnJvdW5kTGVuZ3Rocykge1xuICAgICAgICBzbGlkZVNpemUgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBzbGlkZS5vdXRlcldpZHRoKHRydWUpIDogc2xpZGUub3V0ZXJIZWlnaHQodHJ1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgY29uc3Qgd2lkdGggPSBnZXREaXJlY3Rpb25Qcm9wZXJ0eVZhbHVlKHNsaWRlU3R5bGVzLCAnd2lkdGgnKTtcbiAgICAgICAgY29uc3QgcGFkZGluZ0xlZnQgPSBnZXREaXJlY3Rpb25Qcm9wZXJ0eVZhbHVlKHNsaWRlU3R5bGVzLCAncGFkZGluZy1sZWZ0Jyk7XG4gICAgICAgIGNvbnN0IHBhZGRpbmdSaWdodCA9IGdldERpcmVjdGlvblByb3BlcnR5VmFsdWUoc2xpZGVTdHlsZXMsICdwYWRkaW5nLXJpZ2h0Jyk7XG4gICAgICAgIGNvbnN0IG1hcmdpbkxlZnQgPSBnZXREaXJlY3Rpb25Qcm9wZXJ0eVZhbHVlKHNsaWRlU3R5bGVzLCAnbWFyZ2luLWxlZnQnKTtcbiAgICAgICAgY29uc3QgbWFyZ2luUmlnaHQgPSBnZXREaXJlY3Rpb25Qcm9wZXJ0eVZhbHVlKHNsaWRlU3R5bGVzLCAnbWFyZ2luLXJpZ2h0Jyk7XG4gICAgICAgIGNvbnN0IGJveFNpemluZyA9IHNsaWRlU3R5bGVzLmdldFByb3BlcnR5VmFsdWUoJ2JveC1zaXppbmcnKTtcblxuICAgICAgICBpZiAoYm94U2l6aW5nICYmIGJveFNpemluZyA9PT0gJ2JvcmRlci1ib3gnKSB7XG4gICAgICAgICAgc2xpZGVTaXplID0gd2lkdGggKyBtYXJnaW5MZWZ0ICsgbWFyZ2luUmlnaHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgY2xpZW50V2lkdGgsXG4gICAgICAgICAgICBvZmZzZXRXaWR0aFxuICAgICAgICAgIH0gPSBzbGlkZVswXTtcbiAgICAgICAgICBzbGlkZVNpemUgPSB3aWR0aCArIHBhZGRpbmdMZWZ0ICsgcGFkZGluZ1JpZ2h0ICsgbWFyZ2luTGVmdCArIG1hcmdpblJpZ2h0ICsgKG9mZnNldFdpZHRoIC0gY2xpZW50V2lkdGgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50VHJhbnNmb3JtKSB7XG4gICAgICAgIHNsaWRlWzBdLnN0eWxlLnRyYW5zZm9ybSA9IGN1cnJlbnRUcmFuc2Zvcm07XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50V2ViS2l0VHJhbnNmb3JtKSB7XG4gICAgICAgIHNsaWRlWzBdLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9IGN1cnJlbnRXZWJLaXRUcmFuc2Zvcm07XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMucm91bmRMZW5ndGhzKSBzbGlkZVNpemUgPSBNYXRoLmZsb29yKHNsaWRlU2l6ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNsaWRlU2l6ZSA9IChzd2lwZXJTaXplIC0gKHBhcmFtcy5zbGlkZXNQZXJWaWV3IC0gMSkgKiBzcGFjZUJldHdlZW4pIC8gcGFyYW1zLnNsaWRlc1BlclZpZXc7XG4gICAgICBpZiAocGFyYW1zLnJvdW5kTGVuZ3Rocykgc2xpZGVTaXplID0gTWF0aC5mbG9vcihzbGlkZVNpemUpO1xuXG4gICAgICBpZiAoc2xpZGVzW2ldKSB7XG4gICAgICAgIHNsaWRlc1tpXS5zdHlsZVtnZXREaXJlY3Rpb25MYWJlbCgnd2lkdGgnKV0gPSBgJHtzbGlkZVNpemV9cHhgO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzbGlkZXNbaV0pIHtcbiAgICAgIHNsaWRlc1tpXS5zd2lwZXJTbGlkZVNpemUgPSBzbGlkZVNpemU7XG4gICAgfVxuXG4gICAgc2xpZGVzU2l6ZXNHcmlkLnB1c2goc2xpZGVTaXplKTtcblxuICAgIGlmIChwYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcbiAgICAgIHNsaWRlUG9zaXRpb24gPSBzbGlkZVBvc2l0aW9uICsgc2xpZGVTaXplIC8gMiArIHByZXZTbGlkZVNpemUgLyAyICsgc3BhY2VCZXR3ZWVuO1xuICAgICAgaWYgKHByZXZTbGlkZVNpemUgPT09IDAgJiYgaSAhPT0gMCkgc2xpZGVQb3NpdGlvbiA9IHNsaWRlUG9zaXRpb24gLSBzd2lwZXJTaXplIC8gMiAtIHNwYWNlQmV0d2VlbjtcbiAgICAgIGlmIChpID09PSAwKSBzbGlkZVBvc2l0aW9uID0gc2xpZGVQb3NpdGlvbiAtIHN3aXBlclNpemUgLyAyIC0gc3BhY2VCZXR3ZWVuO1xuICAgICAgaWYgKE1hdGguYWJzKHNsaWRlUG9zaXRpb24pIDwgMSAvIDEwMDApIHNsaWRlUG9zaXRpb24gPSAwO1xuICAgICAgaWYgKHBhcmFtcy5yb3VuZExlbmd0aHMpIHNsaWRlUG9zaXRpb24gPSBNYXRoLmZsb29yKHNsaWRlUG9zaXRpb24pO1xuICAgICAgaWYgKGluZGV4ICUgcGFyYW1zLnNsaWRlc1Blckdyb3VwID09PSAwKSBzbmFwR3JpZC5wdXNoKHNsaWRlUG9zaXRpb24pO1xuICAgICAgc2xpZGVzR3JpZC5wdXNoKHNsaWRlUG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocGFyYW1zLnJvdW5kTGVuZ3Rocykgc2xpZGVQb3NpdGlvbiA9IE1hdGguZmxvb3Ioc2xpZGVQb3NpdGlvbik7XG4gICAgICBpZiAoKGluZGV4IC0gTWF0aC5taW4oc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cFNraXAsIGluZGV4KSkgJSBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwID09PSAwKSBzbmFwR3JpZC5wdXNoKHNsaWRlUG9zaXRpb24pO1xuICAgICAgc2xpZGVzR3JpZC5wdXNoKHNsaWRlUG9zaXRpb24pO1xuICAgICAgc2xpZGVQb3NpdGlvbiA9IHNsaWRlUG9zaXRpb24gKyBzbGlkZVNpemUgKyBzcGFjZUJldHdlZW47XG4gICAgfVxuXG4gICAgc3dpcGVyLnZpcnR1YWxTaXplICs9IHNsaWRlU2l6ZSArIHNwYWNlQmV0d2VlbjtcbiAgICBwcmV2U2xpZGVTaXplID0gc2xpZGVTaXplO1xuICAgIGluZGV4ICs9IDE7XG4gIH1cblxuICBzd2lwZXIudmlydHVhbFNpemUgPSBNYXRoLm1heChzd2lwZXIudmlydHVhbFNpemUsIHN3aXBlclNpemUpICsgb2Zmc2V0QWZ0ZXI7XG5cbiAgaWYgKHJ0bCAmJiB3cm9uZ1JUTCAmJiAocGFyYW1zLmVmZmVjdCA9PT0gJ3NsaWRlJyB8fCBwYXJhbXMuZWZmZWN0ID09PSAnY292ZXJmbG93JykpIHtcbiAgICAkd3JhcHBlckVsLmNzcyh7XG4gICAgICB3aWR0aDogYCR7c3dpcGVyLnZpcnR1YWxTaXplICsgcGFyYW1zLnNwYWNlQmV0d2Vlbn1weGBcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChwYXJhbXMuc2V0V3JhcHBlclNpemUpIHtcbiAgICAkd3JhcHBlckVsLmNzcyh7XG4gICAgICBbZ2V0RGlyZWN0aW9uTGFiZWwoJ3dpZHRoJyldOiBgJHtzd2lwZXIudmlydHVhbFNpemUgKyBwYXJhbXMuc3BhY2VCZXR3ZWVufXB4YFxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGdyaWRFbmFibGVkKSB7XG4gICAgc3dpcGVyLmdyaWQudXBkYXRlV3JhcHBlclNpemUoc2xpZGVTaXplLCBzbmFwR3JpZCwgZ2V0RGlyZWN0aW9uTGFiZWwpO1xuICB9IC8vIFJlbW92ZSBsYXN0IGdyaWQgZWxlbWVudHMgZGVwZW5kaW5nIG9uIHdpZHRoXG5cblxuICBpZiAoIXBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xuICAgIGNvbnN0IG5ld1NsaWRlc0dyaWQgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc25hcEdyaWQubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGxldCBzbGlkZXNHcmlkSXRlbSA9IHNuYXBHcmlkW2ldO1xuICAgICAgaWYgKHBhcmFtcy5yb3VuZExlbmd0aHMpIHNsaWRlc0dyaWRJdGVtID0gTWF0aC5mbG9vcihzbGlkZXNHcmlkSXRlbSk7XG5cbiAgICAgIGlmIChzbmFwR3JpZFtpXSA8PSBzd2lwZXIudmlydHVhbFNpemUgLSBzd2lwZXJTaXplKSB7XG4gICAgICAgIG5ld1NsaWRlc0dyaWQucHVzaChzbGlkZXNHcmlkSXRlbSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc25hcEdyaWQgPSBuZXdTbGlkZXNHcmlkO1xuXG4gICAgaWYgKE1hdGguZmxvb3Ioc3dpcGVyLnZpcnR1YWxTaXplIC0gc3dpcGVyU2l6ZSkgLSBNYXRoLmZsb29yKHNuYXBHcmlkW3NuYXBHcmlkLmxlbmd0aCAtIDFdKSA+IDEpIHtcbiAgICAgIHNuYXBHcmlkLnB1c2goc3dpcGVyLnZpcnR1YWxTaXplIC0gc3dpcGVyU2l6ZSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNuYXBHcmlkLmxlbmd0aCA9PT0gMCkgc25hcEdyaWQgPSBbMF07XG5cbiAgaWYgKHBhcmFtcy5zcGFjZUJldHdlZW4gIT09IDApIHtcbiAgICBjb25zdCBrZXkgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgJiYgcnRsID8gJ21hcmdpbkxlZnQnIDogZ2V0RGlyZWN0aW9uTGFiZWwoJ21hcmdpblJpZ2h0Jyk7XG4gICAgc2xpZGVzLmZpbHRlcigoXywgc2xpZGVJbmRleCkgPT4ge1xuICAgICAgaWYgKCFwYXJhbXMuY3NzTW9kZSkgcmV0dXJuIHRydWU7XG5cbiAgICAgIGlmIChzbGlkZUluZGV4ID09PSBzbGlkZXMubGVuZ3RoIC0gMSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybi
1B0cnVlO1xuICAgIH0pLmNzcyh7XG4gICAgICBba2V5XTogYCR7c3BhY2VCZXR3ZWVufXB4YFxuICAgIH0pO1xuICB9XG5cbiAgaWYgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcyAmJiBwYXJhbXMuY2VudGVyZWRTbGlkZXNCb3VuZHMpIHtcbiAgICBsZXQgYWxsU2xpZGVzU2l6ZSA9IDA7XG4gICAgc2xpZGVzU2l6ZXNHcmlkLmZvckVhY2goc2xpZGVTaXplVmFsdWUgPT4ge1xuICAgICAgYWxsU2xpZGVzU2l6ZSArPSBzbGlkZVNpemVWYWx1ZSArIChwYXJhbXMuc3BhY2VCZXR3ZWVuID8gcGFyYW1zLnNwYWNlQmV0d2VlbiA6IDApO1xuICAgIH0pO1xuICAgIGFsbFNsaWRlc1NpemUgLT0gcGFyYW1zLnNwYWNlQmV0d2VlbjtcbiAgICBjb25zdCBtYXhTbmFwID0gYWxsU2xpZGVzU2l6ZSAtIHN3aXBlclNpemU7XG4gICAgc25hcEdyaWQgPSBzbmFwR3JpZC5tYXAoc25hcCA9PiB7XG4gICAgICBpZiAoc25hcCA8IDApIHJldHVybiAtb2Zmc2V0QmVmb3JlO1xuICAgICAgaWYgKHNuYXAgPiBtYXhTbmFwKSByZXR1cm4gbWF4U25hcCArIG9mZnNldEFmdGVyO1xuICAgICAgcmV0dXJuIHNuYXA7XG4gICAgfSk7XG4gIH1cblxuICBpZiAocGFyYW1zLmNlbnRlckluc3VmZmljaWVudFNsaWRlcykge1xuICAgIGxldCBhbGxTbGlkZXNTaXplID0gMDtcbiAgICBzbGlkZXNTaXplc0dyaWQuZm9yRWFjaChzbGlkZVNpemVWYWx1ZSA9PiB7XG4gICAgICBhbGxTbGlkZXNTaXplICs9IHNsaWRlU2l6ZVZhbHVlICsgKHBhcmFtcy5zcGFjZUJldHdlZW4gPyBwYXJhbXMuc3BhY2VCZXR3ZWVuIDogMCk7XG4gICAgfSk7XG4gICAgYWxsU2xpZGVzU2l6ZSAtPSBwYXJhbXMuc3BhY2VCZXR3ZWVuO1xuXG4gICAgaWYgKGFsbFNsaWRlc1NpemUgPCBzd2lwZXJTaXplKSB7XG4gICAgICBjb25zdCBhbGxTbGlkZXNPZmZzZXQgPSAoc3dpcGVyU2l6ZSAtIGFsbFNsaWRlc1NpemUpIC8gMjtcbiAgICAgIHNuYXBHcmlkLmZvckVhY2goKHNuYXAsIHNuYXBJbmRleCkgPT4ge1xuICAgICAgICBzbmFwR3JpZFtzbmFwSW5kZXhdID0gc25hcCAtIGFsbFNsaWRlc09mZnNldDtcbiAgICAgIH0pO1xuICAgICAgc2xpZGVzR3JpZC5mb3JFYWNoKChzbmFwLCBzbmFwSW5kZXgpID0+IHtcbiAgICAgICAgc2xpZGVzR3JpZFtzbmFwSW5kZXhdID0gc25hcCArIGFsbFNsaWRlc09mZnNldDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLCB7XG4gICAgc2xpZGVzLFxuICAgIHNuYXBHcmlkLFxuICAgIHNsaWRlc0dyaWQsXG4gICAgc2xpZGVzU2l6ZXNHcmlkXG4gIH0pO1xuXG4gIGlmIChwYXJhbXMuY2VudGVyZWRTbGlkZXMgJiYgcGFyYW1zLmNzc01vZGUgJiYgIXBhcmFtcy5jZW50ZXJlZFNsaWRlc0JvdW5kcykge1xuICAgIHNldENTU1Byb3BlcnR5KHN3aXBlci53cmFwcGVyRWwsICctLXN3aXBlci1jZW50ZXJlZC1vZmZzZXQtYmVmb3JlJywgYCR7LXNuYXBHcmlkWzBdfXB4YCk7XG4gICAgc2V0Q1NTUHJvcGVydHkoc3dpcGVyLndyYXBwZXJFbCwgJy0tc3dpcGVyLWNlbnRlcmVkLW9mZnNldC1hZnRlcicsIGAke3N3aXBlci5zaXplIC8gMiAtIHNsaWRlc1NpemVzR3JpZFtzbGlkZXNTaXplc0dyaWQubGVuZ3RoIC0gMV0gLyAyfXB4YCk7XG4gICAgY29uc3QgYWRkVG9TbmFwR3JpZCA9IC1zd2lwZXIuc25hcEdyaWRbMF07XG4gICAgY29uc3QgYWRkVG9TbGlkZXNHcmlkID0gLXN3aXBlci5zbGlkZXNHcmlkWzBdO1xuICAgIHN3aXBlci5zbmFwR3JpZCA9IHN3aXBlci5zbmFwR3JpZC5tYXAodiA9PiB2ICsgYWRkVG9TbmFwR3JpZCk7XG4gICAgc3dpcGVyLnNsaWRlc0dyaWQgPSBzd2lwZXIuc2xpZGVzR3JpZC5tYXAodiA9PiB2ICsgYWRkVG9TbGlkZXNHcmlkKTtcbiAgfVxuXG4gIGlmIChzbGlkZXNMZW5ndGggIT09IHByZXZpb3VzU2xpZGVzTGVuZ3RoKSB7XG4gICAgc3dpcGVyLmVtaXQoJ3NsaWRlc0xlbmd0aENoYW5nZScpO1xuICB9XG5cbiAgaWYgKHNuYXBHcmlkLmxlbmd0aCAhPT0gcHJldmlvdXNTbmFwR3JpZExlbmd0aCkge1xuICAgIGlmIChzd2lwZXIucGFyYW1zLndhdGNoT3ZlcmZsb3cpIHN3aXBlci5jaGVja092ZXJmbG93KCk7XG4gICAgc3dpcGVyLmVtaXQoJ3NuYXBHcmlkTGVuZ3RoQ2hhbmdlJyk7XG4gIH1cblxuICBpZiAoc2xpZGVzR3JpZC5sZW5ndGggIT09IHByZXZpb3VzU2xpZGVzR3JpZExlbmd0aCkge1xuICAgIHN3aXBlci5lbWl0KCdzbGlkZXNHcmlkTGVuZ3RoQ2hhbmdlJyk7XG4gIH1cblxuICBpZiAocGFyYW1zLndhdGNoU2xpZGVzUHJvZ3Jlc3MpIHtcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzT2Zmc2V0KCk7XG4gIH1cblxuICBpZiAoIWlzVmlydHVhbCAmJiAhcGFyYW1zLmNzc01vZGUgJiYgKHBhcmFtcy5lZmZlY3QgPT09ICdzbGlkZScgfHwgcGFyYW1zLmVmZmVjdCA9PT0gJ2ZhZGUnKSkge1xuICAgIGNvbnN0IGJhY2tGYWNlSGlkZGVuQ2xhc3MgPSBgJHtwYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzc31iYWNrZmFjZS1oaWRkZW5gO1xuICAgIGNvbnN0IGhhc0NsYXNzQmFja2ZhY2VDbGFzc0FkZGVkID0gc3dpcGVyLiRlbC5oYXNDbGFzcyhiYWNrRmFjZUhpZGRlbkNsYXNzKTtcblxuICAgIGlmIChzbGlkZXNMZW5ndGggPD0gcGFyYW1zLm1heEJhY2tmYWNlSGlkZGVuU2xpZGVzKSB7XG4gICAgICBpZiAoIWhhc0NsYXNzQmFja2ZhY2VDbGFzc0FkZGVkKSBzd2lwZXIuJGVsLmFkZENsYXNzKGJhY2tGYWNlSGlkZGVuQ2xhc3MpO1xuICAgIH0gZWxzZSBpZiAoaGFzQ2xhc3NCYWNrZmFjZUNsYXNzQWRkZWQpIHtcbiAgICAgIHN3aXBlci4kZWwucmVtb3ZlQ2xhc3MoYmFja0ZhY2VIaWRkZW5DbGFzcyk7XG4gICAgfVxuICB9XG59IiwiaW1wb3J0ICQgZnJvbSAnLi4vLi4vc2hhcmVkL2RvbS5qcyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1cGRhdGVBdXRvSGVpZ2h0KHNwZWVkKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IGFjdGl2ZVNsaWRlcyA9IFtdO1xuICBjb25zdCBpc1ZpcnR1YWwgPSBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZDtcbiAgbGV0IG5ld0hlaWdodCA9IDA7XG4gIGxldCBpO1xuXG4gIGlmICh0eXBlb2Ygc3BlZWQgPT09ICdudW1iZXInKSB7XG4gICAgc3dpcGVyLnNldFRyYW5zaXRpb24oc3BlZWQpO1xuICB9IGVsc2UgaWYgKHNwZWVkID09PSB0cnVlKSB7XG4gICAgc3dpcGVyLnNldFRyYW5zaXRpb24oc3dpcGVyLnBhcmFtcy5zcGVlZCk7XG4gIH1cblxuICBjb25zdCBnZXRTbGlkZUJ5SW5kZXggPSBpbmRleCA9PiB7XG4gICAgaWYgKGlzVmlydHVhbCkge1xuICAgICAgcmV0dXJuIHN3aXBlci5zbGlkZXMuZmlsdGVyKGVsID0+IHBhcnNlSW50KGVsLmdldEF0dHJpYnV0ZSgnZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSwgMTApID09PSBpbmRleClbMF07XG4gICAgfVxuXG4gICAgcmV0dXJuIHN3aXBlci5zbGlkZXMuZXEoaW5kZXgpWzBdO1xuICB9OyAvLyBGaW5kIHNsaWRlcyBjdXJyZW50bHkgaW4gdmlld1xuXG5cbiAgaWYgKHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldyAhPT0gJ2F1dG8nICYmIHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldyA+IDEpIHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xuICAgICAgKHN3aXBlci52aXNpYmxlU2xpZGVzIHx8ICQoW10pKS5lYWNoKHNsaWRlID0+IHtcbiAgICAgICAgYWN0aXZlU2xpZGVzLnB1c2goc2xpZGUpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBNYXRoLmNlaWwoc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3
1KTsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4ICsgaTtcbiAgICAgICAgaWYgKGluZGV4ID4gc3dpcGVyLnNsaWRlcy5sZW5ndGggJiYgIWlzVmlydHVhbCkgYnJlYWs7XG4gICAgICAgIGFjdGl2ZVNsaWRlcy5wdXNoKGdldFNsaWRlQnlJbmRleChpbmRleCkpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBhY3RpdmVTbGlkZXMucHVzaChnZXRTbGlkZUJ5SW5kZXgoc3dpcGVyLmFjdGl2ZUluZGV4KSk7XG4gIH0gLy8gRmluZCBuZXcgaGVpZ2h0IGZyb20gaGlnaGVzdCBzbGlkZSBpbiB2aWV3XG5cblxuICBmb3IgKGkgPSAwOyBpIDwgYWN0aXZlU2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgaWYgKHR5cGVvZiBhY3RpdmVTbGlkZXNbaV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjb25zdCBoZWlnaHQgPSBhY3RpdmVTbGlkZXNbaV0ub2Zmc2V0SGVpZ2h0O1xuICAgICAgbmV3SGVpZ2h0ID0gaGVpZ2h0ID4gbmV3SGVpZ2h0ID8gaGVpZ2h0IDogbmV3SGVpZ2h0O1xuICAgIH1cbiAgfSAvLyBVcGRhdGUgSGVpZ2h0XG5cblxuICBpZiAobmV3SGVpZ2h0IHx8IG5ld0hlaWdodCA9PT0gMCkgc3dpcGVyLiR3cmFwcGVyRWwuY3NzKCdoZWlnaHQnLCBgJHtuZXdIZWlnaHR9cHhgKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1cGRhdGVTbGlkZXNPZmZzZXQoKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IHNsaWRlcyA9IHN3aXBlci5zbGlkZXM7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBzbGlkZXNbaV0uc3dpcGVyU2xpZGVPZmZzZXQgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBzbGlkZXNbaV0ub2Zmc2V0TGVmdCA6IHNsaWRlc1tpXS5vZmZzZXRUb3A7XG4gIH1cbn0iLCJpbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVwZGF0ZVNsaWRlc1Byb2dyZXNzKHRyYW5zbGF0ZSA9IHRoaXMgJiYgdGhpcy50cmFuc2xhdGUgfHwgMCkge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zO1xuICBjb25zdCB7XG4gICAgc2xpZGVzLFxuICAgIHJ0bFRyYW5zbGF0ZTogcnRsLFxuICAgIHNuYXBHcmlkXG4gIH0gPSBzd2lwZXI7XG4gIGlmIChzbGlkZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gIGlmICh0eXBlb2Ygc2xpZGVzWzBdLnN3aXBlclNsaWRlT2Zmc2V0ID09PSAndW5kZWZpbmVkJykgc3dpcGVyLnVwZGF0ZVNsaWRlc09mZnNldCgpO1xuICBsZXQgb2Zmc2V0Q2VudGVyID0gLXRyYW5zbGF0ZTtcbiAgaWYgKHJ0bCkgb2Zmc2V0Q2VudGVyID0gdHJhbnNsYXRlOyAvLyBWaXNpYmxlIFNsaWRlc1xuXG4gIHNsaWRlcy5yZW1vdmVDbGFzcyhwYXJhbXMuc2xpZGVWaXNpYmxlQ2xhc3MpO1xuICBzd2lwZXIudmlzaWJsZVNsaWRlc0luZGV4ZXMgPSBbXTtcbiAgc3dpcGVyLnZpc2libGVTbGlkZXMgPSBbXTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGNvbnN0IHNsaWRlID0gc2xpZGVzW2ldO1xuICAgIGxldCBzbGlkZU9mZnNldCA9IHNsaWRlLnN3aXBlclNsaWRlT2Zmc2V0O1xuXG4gICAgaWYgKHBhcmFtcy5jc3NNb2RlICYmIHBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xuICAgICAgc2xpZGVPZmZzZXQgLT0gc2xpZGVzWzBdLnN3aXBlclNsaWRlT2Zmc2V0O1xuICAgIH1cblxuICAgIGNvbnN0IHNsaWRlUHJvZ3Jlc3MgPSAob2Zmc2V0Q2VudGVyICsgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcyA/IHN3aXBlci5taW5UcmFuc2xhdGUoKSA6IDApIC0gc2xpZGVPZmZzZXQpIC8gKHNsaWRlLnN3aXBlclNsaWRlU2l6ZSArIHBhcmFtcy5zcGFjZUJldHdlZW4pO1xuICAgIGNvbnN0IG9yaWdpbmFsU2xpZGVQcm9ncmVzcyA9IChvZmZzZXRDZW50ZXIgLSBzbmFwR3JpZFswXSArIChwYXJhbXMuY2VudGVyZWRTbGlkZXMgPyBzd2lwZXIubWluVHJhbnNsYXRlKCkgOiAwKSAtIHNsaWRlT2Zmc2V0KSAvIChzbGlkZS5zd2lwZXJTbGlkZVNpemUgKyBwYXJhbXMuc3BhY2VCZXR3ZWVuKTtcbiAgICBjb25zdCBzbGlkZUJlZm9yZSA9IC0ob2Zmc2V0Q2VudGVyIC0gc2xpZGVPZmZzZXQpO1xuICAgIGNvbnN0IHNsaWRlQWZ0ZXIgPSBzbGlkZUJlZm9yZSArIHN3aXBlci5zbGlkZXNTaXplc0dyaWRbaV07XG4gICAgY29uc3QgaXNWaXNpYmxlID0gc2xpZGVCZWZvcmUgPj0gMCAmJiBzbGlkZUJlZm9yZSA8IHN3aXBlci5zaXplIC0gMSB8fCBzbGlkZUFmdGVyID4gMSAmJiBzbGlkZUFmdGVyIDw9IHN3aXBlci5zaXplIHx8IHNsaWRlQmVmb3JlIDw9IDAgJiYgc2xpZGVBZnRlciA+PSBzd2lwZXIuc2l6ZTtcblxuICAgIGlmIChpc1Zpc2libGUpIHtcbiAgICAgIHN3aXBlci52aXNpYmxlU2xpZGVzLnB1c2goc2xpZGUpO1xuICAgICAgc3dpcGVyLnZpc2libGVTbGlkZXNJbmRleGVzLnB1c2goaSk7XG4gICAgICBzbGlkZXMuZXEoaSkuYWRkQ2xhc3MocGFyYW1zLnNsaWRlVmlzaWJsZUNsYXNzKTtcbiAgICB9XG5cbiAgICBzbGlkZS5wcm9ncmVzcyA9IHJ0bCA/IC1zbGlkZVByb2dyZXNzIDogc2xpZGVQcm9ncmVzcztcbiAgICBzbGlkZS5vcmlnaW5hbFByb2dyZXNzID0gcnRsID8gLW9yaWdpbmFsU2xpZGVQcm9ncmVzcyA6IG9yaWdpbmFsU2xpZGVQcm9ncmVzcztcbiAgfVxuXG4gIHN3aXBlci52aXNpYmxlU2xpZGVzID0gJChzd2lwZXIudmlzaWJsZVNsaWRlcyk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXBkYXRlUHJvZ3Jlc3ModHJhbnNsYXRlKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG5cbiAgaWYgKHR5cGVvZiB0cmFuc2xhdGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgY29uc3QgbXVsdGlwbGllciA9IHN3aXBlci5ydGxUcmFuc2xhdGUgPyAtMSA6IDE7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXG4gICAgdHJhbnNsYXRlID0gc3dpcGVyICYmIHN3aXBlci50cmFuc2xhdGUgJiYgc3dpcGVyLnRyYW5zbGF0ZSAqIG11bHRpcGxpZXIgfHwgMDtcbiAgfVxuXG4gIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXM7XG4gIGNvbnN0IHRyYW5zbGF0ZXNEaWZmID0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpO1xuICBsZXQge1xuICAgIHByb2dyZXNzLFxuICAgIGlzQmVnaW5uaW5nLFxuICAgIGlzRW5kXG4gIH0gPSBzd2lwZXI7XG4gIGNvbnN0IHdhc0JlZ2lubmluZyA9IGlzQmVnaW5uaW5nO1xuICBjb25zdCB3YXNFbmQgPSBpc0VuZDtcblxuICBpZiAodHJhbnNsYXRlc0RpZmYgPT09IDApIHtcbiAgICBwcm9ncmVzcyA9IDA7XG4gICAgaXNCZWdpbm5pbmcgPSB0cnVlO1xuICAgIGlzRW5kID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICBwcm9ncmVzcyA9ICh0cmFuc2xhdGUgLSBzd2lwZXIubWluVHJhbnNsYXRlKCkpIC8gdHJhbnNsYXRlc0RpZmY7XG4gICAgaXNCZWdpbm5pbmcgPSBwcm9ncmVzcyA8PSAwO1xuICAgIGlzRW5kID0gcHJvZ3Jlc3MgPj0gMTtcbiAgfVxuXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLCB7XG4gICAgcHJvZ3Jlc3MsXG4gICAgaXNCZWdpbm5pbmcsXG4gICAgaXNFbmRcbiAgfSk7XG4gIGlmIChwYXJhbXMud2F0Y2hTbGlkZXNQcm9ncmVzcyB8fCBwYXJhbXMuY2VudGVyZWRTbGlkZXMgJiYgcGFyYW1zLmF1dG9IZWlnaHQpIHN3aXBlci51cGRhdGVTbGlkZXNQcm9ncmVzcyh0cmFuc2xhdGUpO1xuXG4gIGlmIChpc0JlZ2lubmluZyAmJiAhd2FzQmVnaW5uaW5nKSB7XG4gICAgc3dpcGVyLmVtaXQoJ3JlYWNoQmVnaW5uaW5nIHRvRWRnZScpO1xuICB9XG5cbiAgaWYgKGlzRW5kICYmICF3YXNFbmQpIHtcbiAgICBzd2lwZXIuZW1pdCgncmVhY2hFbmQgdG9FZGdlJyk7XG4gIH1cblxuICBpZiAod2FzQmVnaW5uaW5nICYmICFpc0JlZ2lubmluZyB8fCB3YXNFbmQgJiYgIWlzRW5kKSB7XG4gICAgc3dpcGVyLmVtaXQoJ2Zyb21FZGdlJyk7XG4gIH1cblxuICBzd2lwZXIuZW1pdCgnc
1HJvZ3Jlc3MnLCBwcm9ncmVzcyk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXBkYXRlU2xpZGVzQ2xhc3NlcygpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3Qge1xuICAgIHNsaWRlcyxcbiAgICBwYXJhbXMsXG4gICAgJHdyYXBwZXJFbCxcbiAgICBhY3RpdmVJbmRleCxcbiAgICByZWFsSW5kZXhcbiAgfSA9IHN3aXBlcjtcbiAgY29uc3QgaXNWaXJ0dWFsID0gc3dpcGVyLnZpcnR1YWwgJiYgcGFyYW1zLnZpcnR1YWwuZW5hYmxlZDtcbiAgc2xpZGVzLnJlbW92ZUNsYXNzKGAke3BhcmFtcy5zbGlkZUFjdGl2ZUNsYXNzfSAke3BhcmFtcy5zbGlkZU5leHRDbGFzc30gJHtwYXJhbXMuc2xpZGVQcmV2Q2xhc3N9ICR7cGFyYW1zLnNsaWRlRHVwbGljYXRlQWN0aXZlQ2xhc3N9ICR7cGFyYW1zLnNsaWRlRHVwbGljYXRlTmV4dENsYXNzfSAke3BhcmFtcy5zbGlkZUR1cGxpY2F0ZVByZXZDbGFzc31gKTtcbiAgbGV0IGFjdGl2ZVNsaWRlO1xuXG4gIGlmIChpc1ZpcnR1YWwpIHtcbiAgICBhY3RpdmVTbGlkZSA9IHN3aXBlci4kd3JhcHBlckVsLmZpbmQoYC4ke3BhcmFtcy5zbGlkZUNsYXNzfVtkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cIiR7YWN0aXZlSW5kZXh9XCJdYCk7XG4gIH0gZWxzZSB7XG4gICAgYWN0aXZlU2xpZGUgPSBzbGlkZXMuZXEoYWN0aXZlSW5kZXgpO1xuICB9IC8vIEFjdGl2ZSBjbGFzc2VzXG5cblxuICBhY3RpdmVTbGlkZS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVBY3RpdmVDbGFzcyk7XG5cbiAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgLy8gRHVwbGljYXRlIHRvIGFsbCBsb29wZWQgc2xpZGVzXG4gICAgaWYgKGFjdGl2ZVNsaWRlLmhhc0NsYXNzKHBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzKSkge1xuICAgICAgJHdyYXBwZXJFbC5jaGlsZHJlbihgLiR7cGFyYW1zLnNsaWRlQ2xhc3N9Om5vdCguJHtwYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzc30pW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtyZWFsSW5kZXh9XCJdYCkuYWRkQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlQWN0aXZlQ2xhc3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICAkd3JhcHBlckVsLmNoaWxkcmVuKGAuJHtwYXJhbXMuc2xpZGVDbGFzc30uJHtwYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzc31bZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke3JlYWxJbmRleH1cIl1gKS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVEdXBsaWNhdGVBY3RpdmVDbGFzcyk7XG4gICAgfVxuICB9IC8vIE5leHQgU2xpZGVcblxuXG4gIGxldCBuZXh0U2xpZGUgPSBhY3RpdmVTbGlkZS5uZXh0QWxsKGAuJHtwYXJhbXMuc2xpZGVDbGFzc31gKS5lcSgwKS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVOZXh0Q2xhc3MpO1xuXG4gIGlmIChwYXJhbXMubG9vcCAmJiBuZXh0U2xpZGUubGVuZ3RoID09PSAwKSB7XG4gICAgbmV4dFNsaWRlID0gc2xpZGVzLmVxKDApO1xuICAgIG5leHRTbGlkZS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVOZXh0Q2xhc3MpO1xuICB9IC8vIFByZXYgU2xpZGVcblxuXG4gIGxldCBwcmV2U2xpZGUgPSBhY3RpdmVTbGlkZS5wcmV2QWxsKGAuJHtwYXJhbXMuc2xpZGVDbGFzc31gKS5lcSgwKS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVQcmV2Q2xhc3MpO1xuXG4gIGlmIChwYXJhbXMubG9vcCAmJiBwcmV2U2xpZGUubGVuZ3RoID09PSAwKSB7XG4gICAgcHJldlNsaWRlID0gc2xpZGVzLmVxKC0xKTtcbiAgICBwcmV2U2xpZGUuYWRkQ2xhc3MocGFyYW1zLnNsaWRlUHJldkNsYXNzKTtcbiAgfVxuXG4gIGlmIChwYXJhbXMubG9vcCkge1xuICAgIC8vIER1cGxpY2F0ZSB0byBhbGwgbG9vcGVkIHNsaWRlc1xuICAgIGlmIChuZXh0U2xpZGUuaGFzQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MpKSB7XG4gICAgICAkd3JhcHBlckVsLmNoaWxkcmVuKGAuJHtwYXJhbXMuc2xpZGVDbGFzc306bm90KC4ke3BhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzfSlbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke25leHRTbGlkZS5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpfVwiXWApLmFkZENsYXNzKHBhcmFtcy5zbGlkZUR1cGxpY2F0ZU5leHRDbGFzcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICR3cmFwcGVyRWwuY2hpbGRyZW4oYC4ke3BhcmFtcy5zbGlkZUNsYXNzfS4ke3BhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzfVtkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cIiR7bmV4dFNsaWRlLmF0dHIoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4Jyl9XCJdYCkuYWRkQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlTmV4dENsYXNzKTtcbiAgICB9XG5cbiAgICBpZiAocHJldlNsaWRlLmhhc0NsYXNzKHBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzKSkge1xuICAgICAgJHdyYXBwZXJFbC5jaGlsZHJlbihgLiR7cGFyYW1zLnNsaWRlQ2xhc3N9Om5vdCguJHtwYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzc30pW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtwcmV2U2xpZGUuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKX1cIl1gKS5hZGRDbGFzcyhwYXJhbXMuc2xpZGVEdXBsaWNhdGVQcmV2Q2xhc3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICAkd3JhcHBlckVsLmNoaWxkcmVuKGAuJHtwYXJhbXMuc2xpZGVDbGFzc30uJHtwYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzc31bZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke3ByZXZTbGlkZS5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpfVwiXWApLmFkZENsYXNzKHBhcmFtcy5zbGlkZUR1cGxpY2F0ZVByZXZDbGFzcyk7XG4gICAgfVxuICB9XG5cbiAgc3dpcGVyLmVtaXRTbGlkZXNDbGFzc2VzKCk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXBkYXRlQWN0aXZlSW5kZXgobmV3QWN0aXZlSW5kZXgpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3QgdHJhbnNsYXRlID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSA/IHN3aXBlci50cmFuc2xhdGUgOiAtc3dpcGVyLnRyYW5zbGF0ZTtcbiAgY29uc3Qge1xuICAgIHNsaWRlc0dyaWQsXG4gICAgc25hcEdyaWQsXG4gICAgcGFyYW1zLFxuICAgIGFjdGl2ZUluZGV4OiBwcmV2aW91c0luZGV4LFxuICAgIHJlYWxJbmRleDogcHJldmlvdXNSZWFsSW5kZXgsXG4gICAgc25hcEluZGV4OiBwcmV2aW91c1NuYXBJbmRleFxuICB9ID0gc3dpcGVyO1xuICBsZXQgYWN0aXZlSW5kZXggPSBuZXdBY3RpdmVJbmRleDtcbiAgbGV0IHNuYXBJbmRleDtcblxuICBpZiAodHlwZW9mIGFjdGl2ZUluZGV4ID09PSAndW5kZWZpbmVkJykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzR3JpZC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgaWYgKHR5cGVvZiBzbGlkZXNHcmlkW2kgKyAxXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKHRyYW5zbGF0ZSA+PSBzbGlkZXNHcmlkW2ldICYmIHRyYW5zbGF0ZSA8IHNsaWRlc0dyaWRbaSArIDFdIC0gKHNsaWRlc0dyaWRbaSArIDFdIC0gc2xpZGVzR3JpZFtpXSkgLyAyKSB7XG4gICAgICAgICAgYWN0aXZlSW5kZXggPSBpO1xuICAgICAgICB9IGVsc2UgaWYgKHRyYW5zbGF0ZSA+PSBzbGlkZXNHcmlkW2ldICYmIHRyYW5zbGF0ZSA8IHNsaWRlc0dyaWRbaSArIDFdKSB7XG4gICAgICAgICAgYWN0aXZlSW5kZXggPSBpICsgMTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0cmFuc2xhdGUgPj0gc2xpZGVzR3JpZFtpXSkge1xuICAgICAgICBhY3RpdmVJbmRleCA9IG
1k7XG4gICAgICB9XG4gICAgfSAvLyBOb3JtYWxpemUgc2xpZGVJbmRleFxuXG5cbiAgICBpZiAocGFyYW1zLm5vcm1hbGl6ZVNsaWRlSW5kZXgpIHtcbiAgICAgIGlmIChhY3RpdmVJbmRleCA8IDAgfHwgdHlwZW9mIGFjdGl2ZUluZGV4ID09PSAndW5kZWZpbmVkJykgYWN0aXZlSW5kZXggPSAwO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzbmFwR3JpZC5pbmRleE9mKHRyYW5zbGF0ZSkgPj0gMCkge1xuICAgIHNuYXBJbmRleCA9IHNuYXBHcmlkLmluZGV4T2YodHJhbnNsYXRlKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBza2lwID0gTWF0aC5taW4ocGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCwgYWN0aXZlSW5kZXgpO1xuICAgIHNuYXBJbmRleCA9IHNraXAgKyBNYXRoLmZsb29yKChhY3RpdmVJbmRleCAtIHNraXApIC8gcGFyYW1zLnNsaWRlc1Blckdyb3VwKTtcbiAgfVxuXG4gIGlmIChzbmFwSW5kZXggPj0gc25hcEdyaWQubGVuZ3RoKSBzbmFwSW5kZXggPSBzbmFwR3JpZC5sZW5ndGggLSAxO1xuXG4gIGlmIChhY3RpdmVJbmRleCA9PT0gcHJldmlvdXNJbmRleCkge1xuICAgIGlmIChzbmFwSW5kZXggIT09IHByZXZpb3VzU25hcEluZGV4KSB7XG4gICAgICBzd2lwZXIuc25hcEluZGV4ID0gc25hcEluZGV4O1xuICAgICAgc3dpcGVyLmVtaXQoJ3NuYXBJbmRleENoYW5nZScpO1xuICAgIH1cblxuICAgIHJldHVybjtcbiAgfSAvLyBHZXQgcmVhbCBpbmRleFxuXG5cbiAgY29uc3QgcmVhbEluZGV4ID0gcGFyc2VJbnQoc3dpcGVyLnNsaWRlcy5lcShhY3RpdmVJbmRleCkuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSB8fCBhY3RpdmVJbmRleCwgMTApO1xuICBPYmplY3QuYXNzaWduKHN3aXBlciwge1xuICAgIHNuYXBJbmRleCxcbiAgICByZWFsSW5kZXgsXG4gICAgcHJldmlvdXNJbmRleCxcbiAgICBhY3RpdmVJbmRleFxuICB9KTtcbiAgc3dpcGVyLmVtaXQoJ2FjdGl2ZUluZGV4Q2hhbmdlJyk7XG4gIHN3aXBlci5lbWl0KCdzbmFwSW5kZXhDaGFuZ2UnKTtcblxuICBpZiAocHJldmlvdXNSZWFsSW5kZXggIT09IHJlYWxJbmRleCkge1xuICAgIHN3aXBlci5lbWl0KCdyZWFsSW5kZXhDaGFuZ2UnKTtcbiAgfVxuXG4gIGlmIChzd2lwZXIuaW5pdGlhbGl6ZWQgfHwgc3dpcGVyLnBhcmFtcy5ydW5DYWxsYmFja3NPbkluaXQpIHtcbiAgICBzd2lwZXIuZW1pdCgnc2xpZGVDaGFuZ2UnKTtcbiAgfVxufSIsImltcG9ydCAkIGZyb20gJy4uLy4uL3NoYXJlZC9kb20uanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXBkYXRlQ2xpY2tlZFNsaWRlKGUpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcztcbiAgY29uc3Qgc2xpZGUgPSAkKGUpLmNsb3Nlc3QoYC4ke3BhcmFtcy5zbGlkZUNsYXNzfWApWzBdO1xuICBsZXQgc2xpZGVGb3VuZCA9IGZhbHNlO1xuICBsZXQgc2xpZGVJbmRleDtcblxuICBpZiAoc2xpZGUpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN3aXBlci5zbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGlmIChzd2lwZXIuc2xpZGVzW2ldID09PSBzbGlkZSkge1xuICAgICAgICBzbGlkZUZvdW5kID0gdHJ1ZTtcbiAgICAgICAgc2xpZGVJbmRleCA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChzbGlkZSAmJiBzbGlkZUZvdW5kKSB7XG4gICAgc3dpcGVyLmNsaWNrZWRTbGlkZSA9IHNsaWRlO1xuXG4gICAgaWYgKHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkKSB7XG4gICAgICBzd2lwZXIuY2xpY2tlZEluZGV4ID0gcGFyc2VJbnQoJChzbGlkZSkuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSwgMTApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIuY2xpY2tlZEluZGV4ID0gc2xpZGVJbmRleDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc3dpcGVyLmNsaWNrZWRTbGlkZSA9IHVuZGVmaW5lZDtcbiAgICBzd2lwZXIuY2xpY2tlZEluZGV4ID0gdW5kZWZpbmVkO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChwYXJhbXMuc2xpZGVUb0NsaWNrZWRTbGlkZSAmJiBzd2lwZXIuY2xpY2tlZEluZGV4ICE9PSB1bmRlZmluZWQgJiYgc3dpcGVyLmNsaWNrZWRJbmRleCAhPT0gc3dpcGVyLmFjdGl2ZUluZGV4KSB7XG4gICAgc3dpcGVyLnNsaWRlVG9DbGlja2VkU2xpZGUoKTtcbiAgfVxufSIsImltcG9ydCB1cGRhdGVTaXplIGZyb20gJy4vdXBkYXRlU2l6ZS5qcyc7XG5pbXBvcnQgdXBkYXRlU2xpZGVzIGZyb20gJy4vdXBkYXRlU2xpZGVzLmpzJztcbmltcG9ydCB1cGRhdGVBdXRvSGVpZ2h0IGZyb20gJy4vdXBkYXRlQXV0b0hlaWdodC5qcyc7XG5pbXBvcnQgdXBkYXRlU2xpZGVzT2Zmc2V0IGZyb20gJy4vdXBkYXRlU2xpZGVzT2Zmc2V0LmpzJztcbmltcG9ydCB1cGRhdGVTbGlkZXNQcm9ncmVzcyBmcm9tICcuL3VwZGF0ZVNsaWRlc1Byb2dyZXNzLmpzJztcbmltcG9ydCB1cGRhdGVQcm9ncmVzcyBmcm9tICcuL3VwZGF0ZVByb2dyZXNzLmpzJztcbmltcG9ydCB1cGRhdGVTbGlkZXNDbGFzc2VzIGZyb20gJy4vdXBkYXRlU2xpZGVzQ2xhc3Nlcy5qcyc7XG5pbXBvcnQgdXBkYXRlQWN0aXZlSW5kZXggZnJvbSAnLi91cGRhdGVBY3RpdmVJbmRleC5qcyc7XG5pbXBvcnQgdXBkYXRlQ2xpY2tlZFNsaWRlIGZyb20gJy4vdXBkYXRlQ2xpY2tlZFNsaWRlLmpzJztcbmV4cG9ydCBkZWZhdWx0IHtcbiAgdXBkYXRlU2l6ZSxcbiAgdXBkYXRlU2xpZGVzLFxuICB1cGRhdGVBdXRvSGVpZ2h0LFxuICB1cGRhdGVTbGlkZXNPZmZzZXQsXG4gIHVwZGF0ZVNsaWRlc1Byb2dyZXNzLFxuICB1cGRhdGVQcm9ncmVzcyxcbiAgdXBkYXRlU2xpZGVzQ2xhc3NlcyxcbiAgdXBkYXRlQWN0aXZlSW5kZXgsXG4gIHVwZGF0ZUNsaWNrZWRTbGlkZVxufTsiLCJpbXBvcnQgeyBnZXRUcmFuc2xhdGUgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0U3dpcGVyVHJhbnNsYXRlKGF4aXMgPSB0aGlzLmlzSG9yaXpvbnRhbCgpID8gJ3gnIDogJ3knKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IHtcbiAgICBwYXJhbXMsXG4gICAgcnRsVHJhbnNsYXRlOiBydGwsXG4gICAgdHJhbnNsYXRlLFxuICAgICR3cmFwcGVyRWxcbiAgfSA9IHN3aXBlcjtcblxuICBpZiAocGFyYW1zLnZpcnR1YWxUcmFuc2xhdGUpIHtcbiAgICByZXR1cm4gcnRsID8gLXRyYW5zbGF0ZSA6IHRyYW5zbGF0ZTtcbiAgfVxuXG4gIGlmIChwYXJhbXMuY3NzTW9kZSkge1xuICAgIHJldHVybi
1B0cmFuc2xhdGU7XG4gIH1cblxuICBsZXQgY3VycmVudFRyYW5zbGF0ZSA9IGdldFRyYW5zbGF0ZSgkd3JhcHBlckVsWzBdLCBheGlzKTtcbiAgaWYgKHJ0bCkgY3VycmVudFRyYW5zbGF0ZSA9IC1jdXJyZW50VHJhbnNsYXRlO1xuICByZXR1cm4gY3VycmVudFRyYW5zbGF0ZSB8fCAwO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHNldFRyYW5zbGF0ZSh0cmFuc2xhdGUsIGJ5Q29udHJvbGxlcikge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBjb25zdCB7XG4gICAgcnRsVHJhbnNsYXRlOiBydGwsXG4gICAgcGFyYW1zLFxuICAgICR3cmFwcGVyRWwsXG4gICAgd3JhcHBlckVsLFxuICAgIHByb2dyZXNzXG4gIH0gPSBzd2lwZXI7XG4gIGxldCB4ID0gMDtcbiAgbGV0IHkgPSAwO1xuICBjb25zdCB6ID0gMDtcblxuICBpZiAoc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgeCA9IHJ0bCA/IC10cmFuc2xhdGUgOiB0cmFuc2xhdGU7XG4gIH0gZWxzZSB7XG4gICAgeSA9IHRyYW5zbGF0ZTtcbiAgfVxuXG4gIGlmIChwYXJhbXMucm91bmRMZW5ndGhzKSB7XG4gICAgeCA9IE1hdGguZmxvb3IoeCk7XG4gICAgeSA9IE1hdGguZmxvb3IoeSk7XG4gIH1cblxuICBpZiAocGFyYW1zLmNzc01vZGUpIHtcbiAgICB3cmFwcGVyRWxbc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3Njcm9sbExlZnQnIDogJ3Njcm9sbFRvcCddID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gLXggOiAteTtcbiAgfSBlbHNlIGlmICghcGFyYW1zLnZpcnR1YWxUcmFuc2xhdGUpIHtcbiAgICAkd3JhcHBlckVsLnRyYW5zZm9ybShgdHJhbnNsYXRlM2QoJHt4fXB4LCAke3l9cHgsICR7en1weClgKTtcbiAgfVxuXG4gIHN3aXBlci5wcmV2aW91c1RyYW5zbGF0ZSA9IHN3aXBlci50cmFuc2xhdGU7XG4gIHN3aXBlci50cmFuc2xhdGUgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyB4IDogeTsgLy8gQ2hlY2sgaWYgd2UgbmVlZCB0byB1cGRhdGUgcHJvZ3Jlc3NcblxuICBsZXQgbmV3UHJvZ3Jlc3M7XG4gIGNvbnN0IHRyYW5zbGF0ZXNEaWZmID0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpO1xuXG4gIGlmICh0cmFuc2xhdGVzRGlmZiA9PT0gMCkge1xuICAgIG5ld1Byb2dyZXNzID0gMDtcbiAgfSBlbHNlIHtcbiAgICBuZXdQcm9ncmVzcyA9ICh0cmFuc2xhdGUgLSBzd2lwZXIubWluVHJhbnNsYXRlKCkpIC8gdHJhbnNsYXRlc0RpZmY7XG4gIH1cblxuICBpZiAobmV3UHJvZ3Jlc3MgIT09IHByb2dyZXNzKSB7XG4gICAgc3dpcGVyLnVwZGF0ZVByb2dyZXNzKHRyYW5zbGF0ZSk7XG4gIH1cblxuICBzd2lwZXIuZW1pdCgnc2V0VHJhbnNsYXRlJywgc3dpcGVyLnRyYW5zbGF0ZSwgYnlDb250cm9sbGVyKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtaW5UcmFuc2xhdGUoKSB7XG4gIHJldHVybiAtdGhpcy5zbmFwR3JpZFswXTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtYXhUcmFuc2xhdGUoKSB7XG4gIHJldHVybiAtdGhpcy5zbmFwR3JpZFt0aGlzLnNuYXBHcmlkLmxlbmd0aCAtIDFdO1xufSIsImltcG9ydCB7IGFuaW1hdGVDU1NNb2RlU2Nyb2xsIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRyYW5zbGF0ZVRvKHRyYW5zbGF0ZSA9IDAsIHNwZWVkID0gdGhpcy5wYXJhbXMuc3BlZWQsIHJ1bkNhbGxiYWNrcyA9IHRydWUsIHRyYW5zbGF0ZUJvdW5kcyA9IHRydWUsIGludGVybmFsKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IHtcbiAgICBwYXJhbXMsXG4gICAgd3JhcHBlckVsXG4gIH0gPSBzd2lwZXI7XG5cbiAgaWYgKHN3aXBlci5hbmltYXRpbmcgJiYgcGFyYW1zLnByZXZlbnRJbnRlcmFjdGlvbk9uVHJhbnNpdGlvbikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IG1pblRyYW5zbGF0ZSA9IHN3aXBlci5taW5UcmFuc2xhdGUoKTtcbiAgY29uc3QgbWF4VHJhbnNsYXRlID0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpO1xuICBsZXQgbmV3VHJhbnNsYXRlO1xuICBpZiAodHJhbnNsYXRlQm91bmRzICYmIHRyYW5zbGF0ZSA+IG1pblRyYW5zbGF0ZSkgbmV3VHJhbnNsYXRlID0gbWluVHJhbnNsYXRlO2Vsc2UgaWYgKHRyYW5zbGF0ZUJvdW5kcyAmJiB0cmFuc2xhdGUgPCBtYXhUcmFuc2xhdGUpIG5ld1RyYW5zbGF0ZSA9IG1heFRyYW5zbGF0ZTtlbHNlIG5ld1RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTsgLy8gVXBkYXRlIHByb2dyZXNzXG5cbiAgc3dpcGVyLnVwZGF0ZVByb2dyZXNzKG5ld1RyYW5zbGF0ZSk7XG5cbiAgaWYgKHBhcmFtcy5jc3NNb2RlKSB7XG4gICAgY29uc3QgaXNIID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpO1xuXG4gICAgaWYgKHNwZWVkID09PSAwKSB7XG4gICAgICB3cmFwcGVyRWxbaXNIID8gJ3Njcm9sbExlZnQnIDogJ3Njcm9sbFRvcCddID0gLW5ld1RyYW5zbGF0ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFzd2lwZXIuc3VwcG9ydC5zbW9vdGhTY3JvbGwpIHtcbiAgICAgICAgYW5pbWF0ZUNTU01vZGVTY3JvbGwoe1xuICAgICAgICAgIHN3aXBlcixcbiAgICAgICAgICB0YXJnZXRQb3NpdGlvbjogLW5ld1RyYW5zbGF0ZSxcbiAgICAgICAgICBzaWRlOiBpc0ggPyAnbGVmdCcgOiAndG9wJ1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHdyYXBwZXJFbC5zY3JvbGxUbyh7XG4gICAgICAgIFtpc0ggPyAnbGVmdCcgOiAndG9wJ106IC1uZXdUcmFuc2xhdGUsXG4gICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJ1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAoc3BlZWQgPT09IDApIHtcbiAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbigwKTtcbiAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKG5ld1RyYW5zbGF0ZSk7XG5cbiAgICBpZiAocnVuQ2FsbGJhY2tzKSB7XG4gICAgICBzd2lwZXIuZW1pdCgnYmVmb3JlVHJhbnNpdGlvblN0YXJ0Jywgc3BlZWQsIGludGVybmFsKTtcbiAgICAgIHN3aXBlci5lbWl0KCd0cmFuc2l0aW9uRW5kJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHN3aXBlci5zZXRUcmFuc2l0aW9uKHNwZWVkKTtcbiAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKG5ld1RyYW5zbGF0ZSk7XG5cbiAgICBpZiAocnVuQ2FsbGJhY2tzKSB7XG4gICAgICBzd2lwZXIuZW1pdCgnYmVmb3JlVHJhbnNpdGlvblN0YXJ0Jywgc3BlZWQsIGludGVybmFsKTtcbiAgICAgIHN3aXBlci5lbWl0KCd0cmFuc2l0aW9uU3RhcnQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXN3aXBlci5hbmltYXRpbmcpIHtcbiAgICAgIHN3aXBlci5hbmltYXRpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAoIXN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpIHtcbiAgICAgICAgc3dpcGVyLm9uVHJhbnNsYXRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCA9IGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQoZSkge1xuICAgICAgICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcbiAgICAgICAgICBpZiAoZS50YXJnZXQgIT09IHRoaXMpIHJldHVybjtcbiAgICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbFswXS5yZW1vdmVFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgc3dpcGVyLm9uVHJhbnNsYXRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCk7XG4gICAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWxbMF0ucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2Via2l0VHJhbnNpdGlvbkVuZCcsIHN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpO1xuICAgICAgICAgI
1HN3aXBlci5vblRyYW5zbGF0ZVRvV3JhcHBlclRyYW5zaXRpb25FbmQgPSBudWxsO1xuICAgICAgICAgIGRlbGV0ZSBzd2lwZXIub25UcmFuc2xhdGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kO1xuXG4gICAgICAgICAgaWYgKHJ1bkNhbGxiYWNrcykge1xuICAgICAgICAgICAgc3dpcGVyLmVtaXQoJ3RyYW5zaXRpb25FbmQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHN3aXBlci4kd3JhcHBlckVsWzBdLmFkZEV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCBzd2lwZXIub25UcmFuc2xhdGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kKTtcbiAgICAgIHN3aXBlci4kd3JhcHBlckVsWzBdLmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmtpdFRyYW5zaXRpb25FbmQnLCBzd2lwZXIub25UcmFuc2xhdGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn0iLCJpbXBvcnQgZ2V0VHJhbnNsYXRlIGZyb20gJy4vZ2V0VHJhbnNsYXRlLmpzJztcbmltcG9ydCBzZXRUcmFuc2xhdGUgZnJvbSAnLi9zZXRUcmFuc2xhdGUuanMnO1xuaW1wb3J0IG1pblRyYW5zbGF0ZSBmcm9tICcuL21pblRyYW5zbGF0ZS5qcyc7XG5pbXBvcnQgbWF4VHJhbnNsYXRlIGZyb20gJy4vbWF4VHJhbnNsYXRlLmpzJztcbmltcG9ydCB0cmFuc2xhdGVUbyBmcm9tICcuL3RyYW5zbGF0ZVRvLmpzJztcbmV4cG9ydCBkZWZhdWx0IHtcbiAgZ2V0VHJhbnNsYXRlLFxuICBzZXRUcmFuc2xhdGUsXG4gIG1pblRyYW5zbGF0ZSxcbiAgbWF4VHJhbnNsYXRlLFxuICB0cmFuc2xhdGVUb1xufTsiLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBzZXRUcmFuc2l0aW9uKGR1cmF0aW9uLCBieUNvbnRyb2xsZXIpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcblxuICBpZiAoIXN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgIHN3aXBlci4kd3JhcHBlckVsLnRyYW5zaXRpb24oZHVyYXRpb24pO1xuICB9XG5cbiAgc3dpcGVyLmVtaXQoJ3NldFRyYW5zaXRpb24nLCBkdXJhdGlvbiwgYnlDb250cm9sbGVyKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0cmFuc2l0aW9uRW1pdCh7XG4gIHN3aXBlcixcbiAgcnVuQ2FsbGJhY2tzLFxuICBkaXJlY3Rpb24sXG4gIHN0ZXBcbn0pIHtcbiAgY29uc3Qge1xuICAgIGFjdGl2ZUluZGV4LFxuICAgIHByZXZpb3VzSW5kZXhcbiAgfSA9IHN3aXBlcjtcbiAgbGV0IGRpciA9IGRpcmVjdGlvbjtcblxuICBpZiAoIWRpcikge1xuICAgIGlmIChhY3RpdmVJbmRleCA+IHByZXZpb3VzSW5kZXgpIGRpciA9ICduZXh0JztlbHNlIGlmIChhY3RpdmVJbmRleCA8IHByZXZpb3VzSW5kZXgpIGRpciA9ICdwcmV2JztlbHNlIGRpciA9ICdyZXNldCc7XG4gIH1cblxuICBzd2lwZXIuZW1pdChgdHJhbnNpdGlvbiR7c3RlcH1gKTtcblxuICBpZiAocnVuQ2FsbGJhY2tzICYmIGFjdGl2ZUluZGV4ICE9PSBwcmV2aW91c0luZGV4KSB7XG4gICAgaWYgKGRpciA9PT0gJ3Jlc2V0Jykge1xuICAgICAgc3dpcGVyLmVtaXQoYHNsaWRlUmVzZXRUcmFuc2l0aW9uJHtzdGVwfWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN3aXBlci5lbWl0KGBzbGlkZUNoYW5nZVRyYW5zaXRpb24ke3N0ZXB9YCk7XG5cbiAgICBpZiAoZGlyID09PSAnbmV4dCcpIHtcbiAgICAgIHN3aXBlci5lbWl0KGBzbGlkZU5leHRUcmFuc2l0aW9uJHtzdGVwfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIuZW1pdChgc2xpZGVQcmV2VHJhbnNpdGlvbiR7c3RlcH1gKTtcbiAgICB9XG4gIH1cbn0iLCJpbXBvcnQgdHJhbnNpdGlvbkVtaXQgZnJvbSAnLi90cmFuc2l0aW9uRW1pdC5qcyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0cmFuc2l0aW9uU3RhcnQocnVuQ2FsbGJhY2tzID0gdHJ1ZSwgZGlyZWN0aW9uKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IHtcbiAgICBwYXJhbXNcbiAgfSA9IHN3aXBlcjtcbiAgaWYgKHBhcmFtcy5jc3NNb2RlKSByZXR1cm47XG5cbiAgaWYgKHBhcmFtcy5hdXRvSGVpZ2h0KSB7XG4gICAgc3dpcGVyLnVwZGF0ZUF1dG9IZWlnaHQoKTtcbiAgfVxuXG4gIHRyYW5zaXRpb25FbWl0KHtcbiAgICBzd2lwZXIsXG4gICAgcnVuQ2FsbGJhY2tzLFxuICAgIGRpcmVjdGlvbixcbiAgICBzdGVwOiAnU3RhcnQnXG4gIH0pO1xufSIsImltcG9ydCB0cmFuc2l0aW9uRW1pdCBmcm9tICcuL3RyYW5zaXRpb25FbWl0LmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQocnVuQ2FsbGJhY2tzID0gdHJ1ZSwgZGlyZWN0aW9uKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IHtcbiAgICBwYXJhbXNcbiAgfSA9IHN3aXBlcjtcbiAgc3dpcGVyLmFuaW1hdGluZyA9IGZhbHNlO1xuICBpZiAocGFyYW1zLmNzc01vZGUpIHJldHVybjtcbiAgc3dpcGVyLnNldFRyYW5zaXRpb24oMCk7XG4gIHRyYW5zaXRpb25FbWl0KHtcbiAgICBzd2lwZXIsXG4gICAgcnVuQ2FsbGJhY2tzLFxuICAgIGRpcmVjdGlvbixcbiAgICBzdGVwOiAnRW5kJ1xuICB9KTtcbn0iLCJpbXBvcnQgc2V0VHJhbnNpdGlvbiBmcm9tICcuL3NldFRyYW5zaXRpb24uanMnO1xuaW1wb3J0IHRyYW5zaXRpb25TdGFydCBmcm9tICcuL3RyYW5zaXRpb25TdGFydC5qcyc7XG5pbXBvcnQgdHJhbnNpdGlvbkVuZCBmcm9tICcuL3RyYW5zaXRpb25FbmQuanMnO1xuZXhwb3J0IGRlZmF1bHQge1xuICBzZXRUcmFuc2l0aW9uLFxuICB0cmFuc2l0aW9uU3RhcnQsXG4gIHRyYW5zaXRpb25FbmRcbn07IiwiaW1wb3J0IHsgYW5pbWF0ZUNTU01vZGVTY3JvbGwgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc2xpZGVUbyhpbmRleCA9IDAsIHNwZWVkID0gdGhpcy5wYXJhbXMuc3BlZWQsIHJ1bkNhbGxiYWNrcyA9IHRydWUsIGludGVybmFsLCBpbml0aWFsKSB7XG4gIGlmICh0eXBlb2YgaW5kZXggIT09ICdudW1iZXInICYmIHR5cGVvZiBpbmRleCAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSAnaW5kZXgnIGFyZ3VtZW50IGNhbm5vdCBoYXZlIHR5cGUgb3RoZXIgdGhhbiAnbnVtYmVyJyBvciAnc3RyaW5nJy4gWyR7dHlwZW9mIGluZGV4fV0gZ2l2ZW4uYCk7XG4gIH1cblxuICBpZiAodHlwZW9mIGluZGV4ID09PSAnc3RyaW5nJykge1xuICAgIC8qKlxuICAgICAqIFRoZSBgaW5kZXhgIGFyZ3VtZW50IGNvbnZlcnRlZCBmcm9tIGBzdHJpbmdgIHRvIGBudW1iZXJgLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgY29uc3QgaW5kZXhBc051bWJlciA9IHBhcnNlSW50KGluZGV4LCAxMCk7XG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHR
1oZSBgaW5kZXhgIGFyZ3VtZW50IGlzIGEgdmFsaWQgYG51bWJlcmBcbiAgICAgKiBhZnRlciBiZWluZyBjb252ZXJ0ZWQgZnJvbSB0aGUgYHN0cmluZ2AgdHlwZS5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIGNvbnN0IGlzVmFsaWROdW1iZXIgPSBpc0Zpbml0ZShpbmRleEFzTnVtYmVyKTtcblxuICAgIGlmICghaXNWYWxpZE51bWJlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgcGFzc2VkLWluICdpbmRleCcgKHN0cmluZykgY291bGRuJ3QgYmUgY29udmVydGVkIHRvICdudW1iZXInLiBbJHtpbmRleH1dIGdpdmVuLmApO1xuICAgIH0gLy8gS25vd2luZyB0aGF0IHRoZSBjb252ZXJ0ZWQgYGluZGV4YCBpcyBhIHZhbGlkIG51bWJlcixcbiAgICAvLyB3ZSBjYW4gdXBkYXRlIHRoZSBvcmlnaW5hbCBhcmd1bWVudCdzIHZhbHVlLlxuXG5cbiAgICBpbmRleCA9IGluZGV4QXNOdW1iZXI7XG4gIH1cblxuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBsZXQgc2xpZGVJbmRleCA9IGluZGV4O1xuICBpZiAoc2xpZGVJbmRleCA8IDApIHNsaWRlSW5kZXggPSAwO1xuICBjb25zdCB7XG4gICAgcGFyYW1zLFxuICAgIHNuYXBHcmlkLFxuICAgIHNsaWRlc0dyaWQsXG4gICAgcHJldmlvdXNJbmRleCxcbiAgICBhY3RpdmVJbmRleCxcbiAgICBydGxUcmFuc2xhdGU6IHJ0bCxcbiAgICB3cmFwcGVyRWwsXG4gICAgZW5hYmxlZFxuICB9ID0gc3dpcGVyO1xuXG4gIGlmIChzd2lwZXIuYW5pbWF0aW5nICYmIHBhcmFtcy5wcmV2ZW50SW50ZXJhY3Rpb25PblRyYW5zaXRpb24gfHwgIWVuYWJsZWQgJiYgIWludGVybmFsICYmICFpbml0aWFsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3Qgc2tpcCA9IE1hdGgubWluKHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXBTa2lwLCBzbGlkZUluZGV4KTtcbiAgbGV0IHNuYXBJbmRleCA9IHNraXAgKyBNYXRoLmZsb29yKChzbGlkZUluZGV4IC0gc2tpcCkgLyBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwKTtcbiAgaWYgKHNuYXBJbmRleCA+PSBzbmFwR3JpZC5sZW5ndGgpIHNuYXBJbmRleCA9IHNuYXBHcmlkLmxlbmd0aCAtIDE7XG4gIGNvbnN0IHRyYW5zbGF0ZSA9IC1zbmFwR3JpZFtzbmFwSW5kZXhdOyAvLyBOb3JtYWxpemUgc2xpZGVJbmRleFxuXG4gIGlmIChwYXJhbXMubm9ybWFsaXplU2xpZGVJbmRleCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzR3JpZC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFRyYW5zbGF0ZSA9IC1NYXRoLmZsb29yKHRyYW5zbGF0ZSAqIDEwMCk7XG4gICAgICBjb25zdCBub3JtYWxpemVkR3JpZCA9IE1hdGguZmxvb3Ioc2xpZGVzR3JpZFtpXSAqIDEwMCk7XG4gICAgICBjb25zdCBub3JtYWxpemVkR3JpZE5leHQgPSBNYXRoLmZsb29yKHNsaWRlc0dyaWRbaSArIDFdICogMTAwKTtcblxuICAgICAgaWYgKHR5cGVvZiBzbGlkZXNHcmlkW2kgKyAxXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKG5vcm1hbGl6ZWRUcmFuc2xhdGUgPj0gbm9ybWFsaXplZEdyaWQgJiYgbm9ybWFsaXplZFRyYW5zbGF0ZSA8IG5vcm1hbGl6ZWRHcmlkTmV4dCAtIChub3JtYWxpemVkR3JpZE5leHQgLSBub3JtYWxpemVkR3JpZCkgLyAyKSB7XG4gICAgICAgICAgc2xpZGVJbmRleCA9IGk7XG4gICAgICAgIH0gZWxzZSBpZiAobm9ybWFsaXplZFRyYW5zbGF0ZSA+PSBub3JtYWxpemVkR3JpZCAmJiBub3JtYWxpemVkVHJhbnNsYXRlIDwgbm9ybWFsaXplZEdyaWROZXh0KSB7XG4gICAgICAgICAgc2xpZGVJbmRleCA9IGkgKyAxO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWRUcmFuc2xhdGUgPj0gbm9ybWFsaXplZEdyaWQpIHtcbiAgICAgICAgc2xpZGVJbmRleCA9IGk7XG4gICAgICB9XG4gICAgfVxuICB9IC8vIERpcmVjdGlvbnMgbG9ja3NcblxuXG4gIGlmIChzd2lwZXIuaW5pdGlhbGl6ZWQgJiYgc2xpZGVJbmRleCAhPT0gYWN0aXZlSW5kZXgpIHtcbiAgICBpZiAoIXN3aXBlci5hbGxvd1NsaWRlTmV4dCAmJiB0cmFuc2xhdGUgPCBzd2lwZXIudHJhbnNsYXRlICYmIHRyYW5zbGF0ZSA8IHN3aXBlci5taW5UcmFuc2xhdGUoKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghc3dpcGVyLmFsbG93U2xpZGVQcmV2ICYmIHRyYW5zbGF0ZSA+IHN3aXBlci50cmFuc2xhdGUgJiYgdHJhbnNsYXRlID4gc3dpcGVyLm1heFRyYW5zbGF0ZSgpKSB7XG4gICAgICBpZiAoKGFjdGl2ZUluZGV4IHx8IDApICE9PSBzbGlkZUluZGV4KSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNsaWRlSW5kZXggIT09IChwcmV2aW91c0luZGV4IHx8IDApICYmIHJ1bkNhbGxiYWNrcykge1xuICAgIHN3aXBlci5lbWl0KCdiZWZvcmVTbGlkZUNoYW5nZVN0YXJ0Jyk7XG4gIH0gLy8gVXBkYXRlIHByb2dyZXNzXG5cblxuICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3ModHJhbnNsYXRlKTtcbiAgbGV0IGRpcmVjdGlvbjtcbiAgaWYgKHNsaWRlSW5kZXggPiBhY3RpdmVJbmRleCkgZGlyZWN0aW9uID0gJ25leHQnO2Vsc2UgaWYgKHNsaWRlSW5kZXggPCBhY3RpdmVJbmRleCkgZGlyZWN0aW9uID0gJ3ByZXYnO2Vsc2UgZGlyZWN0aW9uID0gJ3Jlc2V0JzsgLy8gVXBkYXRlIEluZGV4XG5cbiAgaWYgKHJ0bCAmJiAtdHJhbnNsYXRlID09PSBzd2lwZXIudHJhbnNsYXRlIHx8ICFydGwgJiYgdHJhbnNsYXRlID09PSBzd2lwZXIudHJhbnNsYXRlKSB7XG4gICAgc3dpcGVyLnVwZGF0ZUFjdGl2ZUluZGV4KHNsaWRlSW5kZXgpOyAvLyBVcGRhdGUgSGVpZ2h0XG5cbiAgICBpZiAocGFyYW1zLmF1dG9IZWlnaHQpIHtcbiAgICAgIHN3aXBlci51cGRhdGVBdXRvSGVpZ2h0KCk7XG4gICAgfVxuXG4gICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcblxuICAgIGlmIChwYXJhbXMuZWZmZWN0ICE9PSAnc2xpZGUnKSB7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKHRyYW5zbGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKGRpcmVjdGlvbiAhPT0gJ3Jlc2V0Jykge1xuICAgICAgc3dpcGVyLnRyYW5zaXRpb25TdGFydChydW5DYWxsYmFja3MsIGRpcmVjdGlvbik7XG4gICAgICBzd2lwZXIudHJhbnNpdGlvbkVuZChydW5DYWxsYmFja3MsIGRpcmVjdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHBhcmFtcy5jc3NNb2RlKSB7XG4gICAgY29uc3QgaXNIID0gc3dpcGVyLmlzSG9yaXpvbn
1RhbCgpO1xuICAgIGNvbnN0IHQgPSBydGwgPyB0cmFuc2xhdGUgOiAtdHJhbnNsYXRlO1xuXG4gICAgaWYgKHNwZWVkID09PSAwKSB7XG4gICAgICBjb25zdCBpc1ZpcnR1YWwgPSBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZDtcblxuICAgICAgaWYgKGlzVmlydHVhbCkge1xuICAgICAgICBzd2lwZXIud3JhcHBlckVsLnN0eWxlLnNjcm9sbFNuYXBUeXBlID0gJ25vbmUnO1xuICAgICAgICBzd2lwZXIuX2ltbWVkaWF0ZVZpcnR1YWwgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICB3cmFwcGVyRWxbaXNIID8gJ3Njcm9sbExlZnQnIDogJ3Njcm9sbFRvcCddID0gdDtcblxuICAgICAgaWYgKGlzVmlydHVhbCkge1xuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIHN3aXBlci53cmFwcGVyRWwuc3R5bGUuc2Nyb2xsU25hcFR5cGUgPSAnJztcbiAgICAgICAgICBzd2lwZXIuX3N3aXBlckltbWVkaWF0ZVZpcnR1YWwgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghc3dpcGVyLnN1cHBvcnQuc21vb3RoU2Nyb2xsKSB7XG4gICAgICAgIGFuaW1hdGVDU1NNb2RlU2Nyb2xsKHtcbiAgICAgICAgICBzd2lwZXIsXG4gICAgICAgICAgdGFyZ2V0UG9zaXRpb246IHQsXG4gICAgICAgICAgc2lkZTogaXNIID8gJ2xlZnQnIDogJ3RvcCdcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICB3cmFwcGVyRWwuc2Nyb2xsVG8oe1xuICAgICAgICBbaXNIID8gJ2xlZnQnIDogJ3RvcCddOiB0LFxuICAgICAgICBiZWhhdmlvcjogJ3Ntb290aCdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc3dpcGVyLnNldFRyYW5zaXRpb24oc3BlZWQpO1xuICBzd2lwZXIuc2V0VHJhbnNsYXRlKHRyYW5zbGF0ZSk7XG4gIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleChzbGlkZUluZGV4KTtcbiAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcbiAgc3dpcGVyLmVtaXQoJ2JlZm9yZVRyYW5zaXRpb25TdGFydCcsIHNwZWVkLCBpbnRlcm5hbCk7XG4gIHN3aXBlci50cmFuc2l0aW9uU3RhcnQocnVuQ2FsbGJhY2tzLCBkaXJlY3Rpb24pO1xuXG4gIGlmIChzcGVlZCA9PT0gMCkge1xuICAgIHN3aXBlci50cmFuc2l0aW9uRW5kKHJ1bkNhbGxiYWNrcywgZGlyZWN0aW9uKTtcbiAgfSBlbHNlIGlmICghc3dpcGVyLmFuaW1hdGluZykge1xuICAgIHN3aXBlci5hbmltYXRpbmcgPSB0cnVlO1xuXG4gICAgaWYgKCFzd2lwZXIub25TbGlkZVRvV3JhcHBlclRyYW5zaXRpb25FbmQpIHtcbiAgICAgIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCA9IGZ1bmN0aW9uIHRyYW5zaXRpb25FbmQoZSkge1xuICAgICAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XG4gICAgICAgIGlmIChlLnRhcmdldCAhPT0gdGhpcykgcmV0dXJuO1xuICAgICAgICBzd2lwZXIuJHdyYXBwZXJFbFswXS5yZW1vdmVFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgc3dpcGVyLm9uU2xpZGVUb1dyYXBwZXJUcmFuc2l0aW9uRW5kKTtcbiAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWxbMF0ucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2Via2l0VHJhbnNpdGlvbkVuZCcsIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCk7XG4gICAgICAgIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCA9IG51bGw7XG4gICAgICAgIGRlbGV0ZSBzd2lwZXIub25TbGlkZVRvV3JhcHBlclRyYW5zaXRpb25FbmQ7XG4gICAgICAgIHN3aXBlci50cmFuc2l0aW9uRW5kKHJ1bkNhbGxiYWNrcywgZGlyZWN0aW9uKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgc3dpcGVyLiR3cmFwcGVyRWxbMF0uYWRkRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCk7XG4gICAgc3dpcGVyLiR3cmFwcGVyRWxbMF0uYWRkRXZlbnRMaXN0ZW5lcignd2Via2l0VHJhbnNpdGlvbkVuZCcsIHN3aXBlci5vblNsaWRlVG9XcmFwcGVyVHJhbnNpdGlvbkVuZCk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBzbGlkZVRvTG9vcChpbmRleCA9IDAsIHNwZWVkID0gdGhpcy5wYXJhbXMuc3BlZWQsIHJ1bkNhbGxiYWNrcyA9IHRydWUsIGludGVybmFsKSB7XG4gIGlmICh0eXBlb2YgaW5kZXggPT09ICdzdHJpbmcnKSB7XG4gICAgLyoqXG4gICAgICogVGhlIGBpbmRleGAgYXJndW1lbnQgY29udmVydGVkIGZyb20gYHN0cmluZ2AgdG8gYG51bWJlcmAuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBjb25zdCBpbmRleEFzTnVtYmVyID0gcGFyc2VJbnQoaW5kZXgsIDEwKTtcbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGBpbmRleGAgYXJndW1lbnQgaXMgYSB2YWxpZCBgbnVtYmVyYFxuICAgICAqIGFmdGVyIGJlaW5nIGNvbnZlcnRlZCBmcm9tIHRoZSBgc3RyaW5nYCB0eXBlLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgY29uc3QgaXNWYWxpZE51bWJlciA9IGlzRmluaXRlKGluZGV4QXNOdW1iZXIpO1xuXG4gICAgaWYgKCFpc1ZhbGlkTnVtYmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBwYXNzZWQtaW4gJ2luZGV4JyAoc3RyaW5nKSBjb3VsZG4ndCBiZSBjb252ZXJ0ZWQgdG8gJ251bWJlcicuIFske2luZGV4fV0gZ2l2ZW4uYCk7XG4gICAgfSAvLyBLbm93aW5nIHRoYXQgdGhlIGNvbnZlcnRlZCBgaW5kZXhgIGlzIGEgdmFsaWQgbnVtYmVyLFxuICAgIC8vIHdlIGNhbiB1cGRhdGUgdGhlIG9yaWdpbmFsIGFyZ3VtZW50J3MgdmFsdWUuXG5cblxuICAgIGluZGV4ID0gaW5kZXhBc051bWJlcjtcbiAgfVxuXG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGxldCBuZXdJbmRleCA9IGluZGV4O1xuXG4gIGlmIChzd2lwZXIucGFyYW1zLmxvb3ApIHtcbiAgICBuZXdJbmRleCArPSBzd2lwZXIubG9vcGVkU2xpZGVzO1xuICB9XG5cbiAgcmV0dXJuIHN3aXBlci5zbGlkZVRvKG5ld0luZGV4LCBzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCk7XG59IiwiLyogZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBzbGlkZU5leHQoc3BlZWQgPSB0aGlzLnBhcmFtcy5zcGVlZCwgcnVuQ2FsbGJhY2tzID0gdHJ1ZSwgaW50ZXJuYWwpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3Qge1xuICAgIGFuaW1hdGluZyxcbiAgICBlbmFibGVkLFxuICAgIHBhcmFtc1xuICB9ID0gc3dpcGVyO1xuICBpZiAoIWVuYWJsZWQpIHJldHVybi
1Bzd2lwZXI7XG4gIGxldCBwZXJHcm91cCA9IHBhcmFtcy5zbGlkZXNQZXJHcm91cDtcblxuICBpZiAocGFyYW1zLnNsaWRlc1BlclZpZXcgPT09ICdhdXRvJyAmJiBwYXJhbXMuc2xpZGVzUGVyR3JvdXAgPT09IDEgJiYgcGFyYW1zLnNsaWRlc1Blckdyb3VwQXV0bykge1xuICAgIHBlckdyb3VwID0gTWF0aC5tYXgoc3dpcGVyLnNsaWRlc1BlclZpZXdEeW5hbWljKCdjdXJyZW50JywgdHJ1ZSksIDEpO1xuICB9XG5cbiAgY29uc3QgaW5jcmVtZW50ID0gc3dpcGVyLmFjdGl2ZUluZGV4IDwgcGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCA/IDEgOiBwZXJHcm91cDtcblxuICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICBpZiAoYW5pbWF0aW5nICYmIHBhcmFtcy5sb29wUHJldmVudHNTbGlkZSkgcmV0dXJuIGZhbHNlO1xuICAgIHN3aXBlci5sb29wRml4KCk7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXG4gICAgc3dpcGVyLl9jbGllbnRMZWZ0ID0gc3dpcGVyLiR3cmFwcGVyRWxbMF0uY2xpZW50TGVmdDtcbiAgfVxuXG4gIGlmIChwYXJhbXMucmV3aW5kICYmIHN3aXBlci5pc0VuZCkge1xuICAgIHJldHVybiBzd2lwZXIuc2xpZGVUbygwLCBzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCk7XG4gIH1cblxuICByZXR1cm4gc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4ICsgaW5jcmVtZW50LCBzcGVlZCwgcnVuQ2FsbGJhY2tzLCBpbnRlcm5hbCk7XG59IiwiLyogZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBzbGlkZVByZXYoc3BlZWQgPSB0aGlzLnBhcmFtcy5zcGVlZCwgcnVuQ2FsbGJhY2tzID0gdHJ1ZSwgaW50ZXJuYWwpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3Qge1xuICAgIHBhcmFtcyxcbiAgICBhbmltYXRpbmcsXG4gICAgc25hcEdyaWQsXG4gICAgc2xpZGVzR3JpZCxcbiAgICBydGxUcmFuc2xhdGUsXG4gICAgZW5hYmxlZFxuICB9ID0gc3dpcGVyO1xuICBpZiAoIWVuYWJsZWQpIHJldHVybiBzd2lwZXI7XG5cbiAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgaWYgKGFuaW1hdGluZyAmJiBwYXJhbXMubG9vcFByZXZlbnRzU2xpZGUpIHJldHVybiBmYWxzZTtcbiAgICBzd2lwZXIubG9vcEZpeCgpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuICAgIHN3aXBlci5fY2xpZW50TGVmdCA9IHN3aXBlci4kd3JhcHBlckVsWzBdLmNsaWVudExlZnQ7XG4gIH1cblxuICBjb25zdCB0cmFuc2xhdGUgPSBydGxUcmFuc2xhdGUgPyBzd2lwZXIudHJhbnNsYXRlIDogLXN3aXBlci50cmFuc2xhdGU7XG5cbiAgZnVuY3Rpb24gbm9ybWFsaXplKHZhbCkge1xuICAgIGlmICh2YWwgPCAwKSByZXR1cm4gLU1hdGguZmxvb3IoTWF0aC5hYnModmFsKSk7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IodmFsKTtcbiAgfVxuXG4gIGNvbnN0IG5vcm1hbGl6ZWRUcmFuc2xhdGUgPSBub3JtYWxpemUodHJhbnNsYXRlKTtcbiAgY29uc3Qgbm9ybWFsaXplZFNuYXBHcmlkID0gc25hcEdyaWQubWFwKHZhbCA9PiBub3JtYWxpemUodmFsKSk7XG4gIGxldCBwcmV2U25hcCA9IHNuYXBHcmlkW25vcm1hbGl6ZWRTbmFwR3JpZC5pbmRleE9mKG5vcm1hbGl6ZWRUcmFuc2xhdGUpIC0gMV07XG5cbiAgaWYgKHR5cGVvZiBwcmV2U25hcCA9PT0gJ3VuZGVmaW5lZCcgJiYgcGFyYW1zLmNzc01vZGUpIHtcbiAgICBsZXQgcHJldlNuYXBJbmRleDtcbiAgICBzbmFwR3JpZC5mb3JFYWNoKChzbmFwLCBzbmFwSW5kZXgpID0+IHtcbiAgICAgIGlmIChub3JtYWxpemVkVHJhbnNsYXRlID49IHNuYXApIHtcbiAgICAgICAgLy8gcHJldlNuYXAgPSBzbmFwO1xuICAgICAgICBwcmV2U25hcEluZGV4ID0gc25hcEluZGV4O1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHR5cGVvZiBwcmV2U25hcEluZGV4ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcHJldlNuYXAgPSBzbmFwR3JpZFtwcmV2U25hcEluZGV4ID4gMCA/IHByZXZTbmFwSW5kZXggLSAxIDogcHJldlNuYXBJbmRleF07XG4gICAgfVxuICB9XG5cbiAgbGV0IHByZXZJbmRleCA9IDA7XG5cbiAgaWYgKHR5cGVvZiBwcmV2U25hcCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBwcmV2SW5kZXggPSBzbGlkZXNHcmlkLmluZGV4T2YocHJldlNuYXApO1xuICAgIGlmIChwcmV2SW5kZXggPCAwKSBwcmV2SW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXggLSAxO1xuXG4gICAgaWYgKHBhcmFtcy5zbGlkZXNQZXJWaWV3ID09PSAnYXV0bycgJiYgcGFyYW1zLnNsaWRlc1Blckdyb3VwID09PSAxICYmIHBhcmFtcy5zbGlkZXNQZXJHcm91cEF1dG8pIHtcbiAgICAgIHByZXZJbmRleCA9IHByZXZJbmRleCAtIHN3aXBlci5zbGlkZXNQZXJWaWV3RHluYW1pYygncHJldmlvdXMnLCB0cnVlKSArIDE7XG4gICAgICBwcmV2SW5kZXggPSBNYXRoLm1heChwcmV2SW5kZXgsIDApO1xuICAgIH1cbiAgfVxuXG4gIGlmIChwYXJhbXMucmV3aW5kICYmIHN3aXBlci5pc0JlZ2lubmluZykge1xuICAgIGNvbnN0IGxhc3RJbmRleCA9IHN3aXBlci5wYXJhbXMudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCAmJiBzd2lwZXIudmlydHVhbCA/IHN3aXBlci52aXJ0dWFsLnNsaWRlcy5sZW5ndGggLSAxIDogc3dpcGVyLnNsaWRlcy5sZW5ndGggLSAxO1xuICAgIHJldHVybiBzd2lwZXIuc2xpZGVUbyhsYXN0SW5kZXgsIHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKTtcbiAgfVxuXG4gIHJldHVybiBzd2lwZXIuc2xpZGVUbyhwcmV2SW5kZXgsIHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKTtcbn0iLCIvKiBlc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIgKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHNsaWRlUmVzZXQoc3BlZWQgPSB0aGlzLnBhcmFtcy5zcGVlZCwgcnVuQ2FsbGJhY2tzID0gdHJ1ZSwgaW50ZXJuYWwpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgcmV0dXJuIHN3aXBlci5zbGlkZVRvKHN3aXBlci5hY3RpdmVJbmRleCwgc3BlZWQsIHJ1bkNhbGxiYWNrcywgaW50ZXJuYWwpO1xufSIsIi8qIGVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc2xpZGVUb0Nsb3Nlc3Qoc3BlZWQgPSB0aGlzLnBhcmFtcy5zcGVlZCwgcnVuQ2FsbGJhY2tzID0gdHJ1ZSwgaW50ZXJuYWwsIHRocmVzaG9sZCA9IDAuNSkge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBsZXQgaW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXg7XG4gIGNvbnN0IHNraXAgPSBNYXRoLm1pbihzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCwgaW5kZXgpO1xuICBjb25zdCBzbmFwSW5kZXggPSBza2lwICsgTWF0aC5mbG9vcigoaW5kZXggLSBza2lwKSAvIHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXApO1xuICBjb25zdCB0cmFuc2xhdGUgPSBzd2lwZXIucnRsVHJhbnNsYXRlID8gc3dpcGVyLnRyYW5zbGF0ZSA6IC1zd2lwZXIudHJhbnNsYXRlO1xuXG4gIGlmICh0cmFuc2xhdGUgPj0gc3dpcGVyLnNuYXBHcmlkW3NuYXBJbmRleF0pIHtcbiAgICAvLyBUaGUgY3VycmVudCB0cmFuc2xhdGUgaXMgb24gb3IgYWZ0ZXIgdGhlIGN1cnJlbnQgc25hcCBpbmRleCwgc28gdGhlIGNob2ljZVxuICAgIC8vIGlzIGJldHdlZW4gdGhlIGN1cnJlbnQgaW5kZXggYW5kIHRoZSBvbmUgYWZ0ZXIgaX
1QuXG4gICAgY29uc3QgY3VycmVudFNuYXAgPSBzd2lwZXIuc25hcEdyaWRbc25hcEluZGV4XTtcbiAgICBjb25zdCBuZXh0U25hcCA9IHN3aXBlci5zbmFwR3JpZFtzbmFwSW5kZXggKyAxXTtcblxuICAgIGlmICh0cmFuc2xhdGUgLSBjdXJyZW50U25hcCA+IChuZXh0U25hcCAtIGN1cnJlbnRTbmFwKSAqIHRocmVzaG9sZCkge1xuICAgICAgaW5kZXggKz0gc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhlIGN1cnJlbnQgdHJhbnNsYXRlIGlzIGJlZm9yZSB0aGUgY3VycmVudCBzbmFwIGluZGV4LCBzbyB0aGUgY2hvaWNlXG4gICAgLy8gaXMgYmV0d2VlbiB0aGUgY3VycmVudCBpbmRleCBhbmQgdGhlIG9uZSBiZWZvcmUgaXQuXG4gICAgY29uc3QgcHJldlNuYXAgPSBzd2lwZXIuc25hcEdyaWRbc25hcEluZGV4IC0gMV07XG4gICAgY29uc3QgY3VycmVudFNuYXAgPSBzd2lwZXIuc25hcEdyaWRbc25hcEluZGV4XTtcblxuICAgIGlmICh0cmFuc2xhdGUgLSBwcmV2U25hcCA8PSAoY3VycmVudFNuYXAgLSBwcmV2U25hcCkgKiB0aHJlc2hvbGQpIHtcbiAgICAgIGluZGV4IC09IHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXA7XG4gICAgfVxuICB9XG5cbiAgaW5kZXggPSBNYXRoLm1heChpbmRleCwgMCk7XG4gIGluZGV4ID0gTWF0aC5taW4oaW5kZXgsIHN3aXBlci5zbGlkZXNHcmlkLmxlbmd0aCAtIDEpO1xuICByZXR1cm4gc3dpcGVyLnNsaWRlVG8oaW5kZXgsIHNwZWVkLCBydW5DYWxsYmFja3MsIGludGVybmFsKTtcbn0iLCJpbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmltcG9ydCB7IG5leHRUaWNrIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHNsaWRlVG9DbGlja2VkU2xpZGUoKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IHtcbiAgICBwYXJhbXMsXG4gICAgJHdyYXBwZXJFbFxuICB9ID0gc3dpcGVyO1xuICBjb25zdCBzbGlkZXNQZXJWaWV3ID0gcGFyYW1zLnNsaWRlc1BlclZpZXcgPT09ICdhdXRvJyA/IHN3aXBlci5zbGlkZXNQZXJWaWV3RHluYW1pYygpIDogcGFyYW1zLnNsaWRlc1BlclZpZXc7XG4gIGxldCBzbGlkZVRvSW5kZXggPSBzd2lwZXIuY2xpY2tlZEluZGV4O1xuICBsZXQgcmVhbEluZGV4O1xuXG4gIGlmIChwYXJhbXMubG9vcCkge1xuICAgIGlmIChzd2lwZXIuYW5pbWF0aW5nKSByZXR1cm47XG4gICAgcmVhbEluZGV4ID0gcGFyc2VJbnQoJChzd2lwZXIuY2xpY2tlZFNsaWRlKS5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpLCAxMCk7XG5cbiAgICBpZiAocGFyYW1zLmNlbnRlcmVkU2xpZGVzKSB7XG4gICAgICBpZiAoc2xpZGVUb0luZGV4IDwgc3dpcGVyLmxvb3BlZFNsaWRlcyAtIHNsaWRlc1BlclZpZXcgLyAyIHx8IHNsaWRlVG9JbmRleCA+IHN3aXBlci5zbGlkZXMubGVuZ3RoIC0gc3dpcGVyLmxvb3BlZFNsaWRlcyArIHNsaWRlc1BlclZpZXcgLyAyKSB7XG4gICAgICAgIHN3aXBlci5sb29wRml4KCk7XG4gICAgICAgIHNsaWRlVG9JbmRleCA9ICR3cmFwcGVyRWwuY2hpbGRyZW4oYC4ke3BhcmFtcy5zbGlkZUNsYXNzfVtkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cIiR7cmVhbEluZGV4fVwiXTpub3QoLiR7cGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3N9KWApLmVxKDApLmluZGV4KCk7XG4gICAgICAgIG5leHRUaWNrKCgpID0+IHtcbiAgICAgICAgICBzd2lwZXIuc2xpZGVUbyhzbGlkZVRvSW5kZXgpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHNsaWRlVG9JbmRleCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzbGlkZVRvSW5kZXggPiBzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIHNsaWRlc1BlclZpZXcpIHtcbiAgICAgIHN3aXBlci5sb29wRml4KCk7XG4gICAgICBzbGlkZVRvSW5kZXggPSAkd3JhcHBlckVsLmNoaWxkcmVuKGAuJHtwYXJhbXMuc2xpZGVDbGFzc31bZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke3JlYWxJbmRleH1cIl06bm90KC4ke3BhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzfSlgKS5lcSgwKS5pbmRleCgpO1xuICAgICAgbmV4dFRpY2soKCkgPT4ge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzbGlkZVRvSW5kZXgpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXBlci5zbGlkZVRvKHNsaWRlVG9JbmRleCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHN3aXBlci5zbGlkZVRvKHNsaWRlVG9JbmRleCk7XG4gIH1cbn0iLCJpbXBvcnQgc2xpZGVUbyBmcm9tICcuL3NsaWRlVG8uanMnO1xuaW1wb3J0IHNsaWRlVG9Mb29wIGZyb20gJy4vc2xpZGVUb0xvb3AuanMnO1xuaW1wb3J0IHNsaWRlTmV4dCBmcm9tICcuL3NsaWRlTmV4dC5qcyc7XG5pbXBvcnQgc2xpZGVQcmV2IGZyb20gJy4vc2xpZGVQcmV2LmpzJztcbmltcG9ydCBzbGlkZVJlc2V0IGZyb20gJy4vc2xpZGVSZXNldC5qcyc7XG5pbXBvcnQgc2xpZGVUb0Nsb3Nlc3QgZnJvbSAnLi9zbGlkZVRvQ2xvc2VzdC5qcyc7XG5pbXBvcnQgc2xpZGVUb0NsaWNrZWRTbGlkZSBmcm9tICcuL3NsaWRlVG9DbGlja2VkU2xpZGUuanMnO1xuZXhwb3J0IGRlZmF1bHQge1xuICBzbGlkZVRvLFxuICBzbGlkZVRvTG9vcCxcbiAgc2xpZGVOZXh0LFxuICBzbGlkZVByZXYsXG4gIHNsaWRlUmVzZXQsXG4gIHNsaWRlVG9DbG9zZXN0LFxuICBzbGlkZVRvQ2xpY2tlZFNsaWRlXG59OyIsImltcG9ydCB7IGdldERvY3VtZW50IH0gZnJvbSAnc3NyLXdpbmRvdyc7XG5pbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxvb3BDcmVhdGUoKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgY29uc3Qge1xuICAgIHBhcmFtcyxcbiAgICAkd3JhcHBlckVsXG4gIH0gPSBzd2lwZXI7IC8vIFJlbW92ZSBkdXBsaWNhdGVkIHNsaWRlc1xuXG4gIGNvbnN0ICRzZWxlY3RvciA9ICR3cmFwcGVyRWwuY2hpbGRyZW4oKS5sZW5ndGggPiAwID8gJCgkd3JhcHBlckVsLmNoaWxkcmVuKClbMF0ucGFyZW50Tm9kZSkgOiAkd3JhcHBlckVsO1xuICAkc2VsZWN0b3IuY2hpbGRyZW4oYC4ke3BhcmFtcy5zbGlkZUNsYXNzfS4ke3BhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzfWApLnJlbW92ZSgpO1xuICBsZXQgc2xpZGVzID0gJHNlbGVjdG9yLmNoaWxkcmVuKGAuJHtwYXJhbXMuc2xpZGVDbGFzc31gKTtcblxuICBpZiAocGFyYW1zLmxvb3BGaWxsR3JvdXBXaXRoQmxhbmspIHtcbiAgICBjb25zdCBibGFua1NsaWRlc051bSA9IHBhcmFtcy5zbGlkZXNQZXJHcm91cCAtIHNsaWRlcy5sZW5ndGggJSBwYXJhbXMuc2xpZGVzUGVyR3JvdXA7XG5cbiAgICBpZiAoYmxhbmtTbGlkZXNOdW0gIT09IHBhcmFtcy5zbGlkZXNQZXJHcm91cCkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBibGFua1NsaWRlc051bTsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IGJsYW5rTm9kZSA9ICQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykpLmFkZENsYXNzKGAke3BhcmFtcy5zbGlkZUNsYXNzfSAke3BhcmFtcy5zbGlkZUJsYW5rQ2xhc3N9YCk7XG4gICAgICAgICRzZWxlY3Rvci5hcHBlbmQoYmxhbmtOb2RlKTtcbiAgICAgIH1cblxuICAgICAgc2xpZGVzID0gJHNlbGVjdG9yLmNoaWxkcmVuKGAuJHtwYXJhbXMuc2xpZGVDbGFzc31gKTtcbiAgICB9XG4gI
1H1cblxuICBpZiAocGFyYW1zLnNsaWRlc1BlclZpZXcgPT09ICdhdXRvJyAmJiAhcGFyYW1zLmxvb3BlZFNsaWRlcykgcGFyYW1zLmxvb3BlZFNsaWRlcyA9IHNsaWRlcy5sZW5ndGg7XG4gIHN3aXBlci5sb29wZWRTbGlkZXMgPSBNYXRoLmNlaWwocGFyc2VGbG9hdChwYXJhbXMubG9vcGVkU2xpZGVzIHx8IHBhcmFtcy5zbGlkZXNQZXJWaWV3LCAxMCkpO1xuICBzd2lwZXIubG9vcGVkU2xpZGVzICs9IHBhcmFtcy5sb29wQWRkaXRpb25hbFNsaWRlcztcblxuICBpZiAoc3dpcGVyLmxvb3BlZFNsaWRlcyA+IHNsaWRlcy5sZW5ndGggJiYgc3dpcGVyLnBhcmFtcy5sb29wZWRTbGlkZXNMaW1pdCkge1xuICAgIHN3aXBlci5sb29wZWRTbGlkZXMgPSBzbGlkZXMubGVuZ3RoO1xuICB9XG5cbiAgY29uc3QgcHJlcGVuZFNsaWRlcyA9IFtdO1xuICBjb25zdCBhcHBlbmRTbGlkZXMgPSBbXTtcbiAgc2xpZGVzLmVhY2goKGVsLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IHNsaWRlID0gJChlbCk7XG4gICAgc2xpZGUuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnLCBpbmRleCk7XG4gIH0pO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3dpcGVyLmxvb3BlZFNsaWRlczsgaSArPSAxKSB7XG4gICAgY29uc3QgaW5kZXggPSBpIC0gTWF0aC5mbG9vcihpIC8gc2xpZGVzLmxlbmd0aCkgKiBzbGlkZXMubGVuZ3RoO1xuICAgIGFwcGVuZFNsaWRlcy5wdXNoKHNsaWRlcy5lcShpbmRleClbMF0pO1xuICAgIHByZXBlbmRTbGlkZXMudW5zaGlmdChzbGlkZXMuZXEoc2xpZGVzLmxlbmd0aCAtIGluZGV4IC0gMSlbMF0pO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcHBlbmRTbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAkc2VsZWN0b3IuYXBwZW5kKCQoYXBwZW5kU2xpZGVzW2ldLmNsb25lTm9kZSh0cnVlKSkuYWRkQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MpKTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSBwcmVwZW5kU2xpZGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaSAtPSAxKSB7XG4gICAgJHNlbGVjdG9yLnByZXBlbmQoJChwcmVwZW5kU2xpZGVzW2ldLmNsb25lTm9kZSh0cnVlKSkuYWRkQ2xhc3MocGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MpKTtcbiAgfVxufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxvb3BGaXgoKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIHN3aXBlci5lbWl0KCdiZWZvcmVMb29wRml4Jyk7XG4gIGNvbnN0IHtcbiAgICBhY3RpdmVJbmRleCxcbiAgICBzbGlkZXMsXG4gICAgbG9vcGVkU2xpZGVzLFxuICAgIGFsbG93U2xpZGVQcmV2LFxuICAgIGFsbG93U2xpZGVOZXh0LFxuICAgIHNuYXBHcmlkLFxuICAgIHJ0bFRyYW5zbGF0ZTogcnRsXG4gIH0gPSBzd2lwZXI7XG4gIGxldCBuZXdJbmRleDtcbiAgc3dpcGVyLmFsbG93U2xpZGVQcmV2ID0gdHJ1ZTtcbiAgc3dpcGVyLmFsbG93U2xpZGVOZXh0ID0gdHJ1ZTtcbiAgY29uc3Qgc25hcFRyYW5zbGF0ZSA9IC1zbmFwR3JpZFthY3RpdmVJbmRleF07XG4gIGNvbnN0IGRpZmYgPSBzbmFwVHJhbnNsYXRlIC0gc3dpcGVyLmdldFRyYW5zbGF0ZSgpOyAvLyBGaXggRm9yIE5lZ2F0aXZlIE92ZXJzbGlkaW5nXG5cbiAgaWYgKGFjdGl2ZUluZGV4IDwgbG9vcGVkU2xpZGVzKSB7XG4gICAgbmV3SW5kZXggPSBzbGlkZXMubGVuZ3RoIC0gbG9vcGVkU2xpZGVzICogMyArIGFjdGl2ZUluZGV4O1xuICAgIG5ld0luZGV4ICs9IGxvb3BlZFNsaWRlcztcbiAgICBjb25zdCBzbGlkZUNoYW5nZWQgPSBzd2lwZXIuc2xpZGVUbyhuZXdJbmRleCwgMCwgZmFsc2UsIHRydWUpO1xuXG4gICAgaWYgKHNsaWRlQ2hhbmdlZCAmJiBkaWZmICE9PSAwKSB7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKChydGwgPyAtc3dpcGVyLnRyYW5zbGF0ZSA6IHN3aXBlci50cmFuc2xhdGUpIC0gZGlmZik7XG4gICAgfVxuICB9IGVsc2UgaWYgKGFjdGl2ZUluZGV4ID49IHNsaWRlcy5sZW5ndGggLSBsb29wZWRTbGlkZXMpIHtcbiAgICAvLyBGaXggRm9yIFBvc2l0aXZlIE92ZXJzbGlkaW5nXG4gICAgbmV3SW5kZXggPSAtc2xpZGVzLmxlbmd0aCArIGFjdGl2ZUluZGV4ICsgbG9vcGVkU2xpZGVzO1xuICAgIG5ld0luZGV4ICs9IGxvb3BlZFNsaWRlcztcbiAgICBjb25zdCBzbGlkZUNoYW5nZWQgPSBzd2lwZXIuc2xpZGVUbyhuZXdJbmRleCwgMCwgZmFsc2UsIHRydWUpO1xuXG4gICAgaWYgKHNsaWRlQ2hhbmdlZCAmJiBkaWZmICE9PSAwKSB7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKChydGwgPyAtc3dpcGVyLnRyYW5zbGF0ZSA6IHN3aXBlci50cmFuc2xhdGUpIC0gZGlmZik7XG4gICAgfVxuICB9XG5cbiAgc3dpcGVyLmFsbG93U2xpZGVQcmV2ID0gYWxsb3dTbGlkZVByZXY7XG4gIHN3aXBlci5hbGxvd1NsaWRlTmV4dCA9IGFsbG93U2xpZGVOZXh0O1xuICBzd2lwZXIuZW1pdCgnbG9vcEZpeCcpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxvb3BEZXN0cm95KCkge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBjb25zdCB7XG4gICAgJHdyYXBwZXJFbCxcbiAgICBwYXJhbXMsXG4gICAgc2xpZGVzXG4gIH0gPSBzd2lwZXI7XG4gICR3cmFwcGVyRWwuY2hpbGRyZW4oYC4ke3BhcmFtcy5zbGlkZUNsYXNzfS4ke3BhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzfSwuJHtwYXJhbXMuc2xpZGVDbGFzc30uJHtwYXJhbXMuc2xpZGVCbGFua0NsYXNzfWApLnJlbW92ZSgpO1xuICBzbGlkZXMucmVtb3ZlQXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKTtcbn0iLCJpbXBvcnQgbG9vcENyZWF0ZSBmcm9tICcuL2xvb3BDcmVhdGUuanMnO1xuaW1wb3J0IGxvb3BGaXggZnJvbSAnLi9sb29wRml4LmpzJztcbmltcG9ydCBsb29wRGVzdHJveSBmcm9tICcuL2xvb3BEZXN0cm95LmpzJztcbmV4cG9ydCBkZWZhdWx0IHtcbiAgbG9vcENyZWF0ZSxcbiAgbG9vcEZpeCxcbiAgbG9vcERlc3Ryb3lcbn07IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc2V0R3JhYkN1cnNvcihtb3ZpbmcpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgaWYgKHN3aXBlci5zdXBwb3J0LnRvdWNoIHx8ICFzd2lwZXIucGFyYW1zLnNpbXVsYXRlVG91Y2ggfHwgc3dpcGVyLnBhcmFtcy53YXRjaE92ZXJmbG93ICYmIHN3aXBlci5pc0xvY2tlZCB8fCBzd2lwZXIucGFyYW1zLmNzc01vZGUpIHJldHVybjtcbiAgY29uc3QgZWwgPSBzd2lwZXIucGFyYW1zLnRvdWNoRXZlbnRzVGFyZ2V0ID09PSAnY29udGFpbmVyJyA/IHN3aXBlci5lbCA6IHN3aXBlci53cmFwcGVyRWw7XG4gIGVsLnN0eWxlLmN1cnNvciA9ICdtb3ZlJztcbiAgZWwuc3R5bGUuY3Vyc29yID0gbW92aW5nID8gJ2dyYWJiaW5nJyA6ICdncmFiJztcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1bnNldEdyYWJDdXJzb3IoKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG5cbiAgaWYgKHN3aXBlci5zdXBwb3J0LnRvdWNoIHx8IHN3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzd2lwZXIuaXNMb2NrZWQgfHwgc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgc3dpcGVyW3N3aXBlci5wYXJhbXMudG91Y2hFdmVudHNUYXJnZXQgPT09ICdjb250YWluZXInID8gJ2VsJyA6ICd3cmFwcGVyRWwnXS5zdHlsZS5jdXJzb3IgPSAnJztcbn0iLCJpbXBvcnQgc2V0R3JhYkN1cnNvciBmcm9tICcuL3NldEdyYWJDdXJzb3IuanMnO1xuaW1wb3J0IHVuc2V0R3JhYkN1cnNvciBmcm9tICcuL3Vuc2V0R3JhYkN1cnNvci5qcyc7XG5leHBvcnQgZGVmYXVsdCB7XG4gIHNldEdyYWJDdXJzb3IsXG4gIHVuc2V0R3JhYkN1cnNvclxufTsiLCJpbXBvcnQgeyBnZXRXaW5kb3csIGdldERvY3VtZW50IH0gZnJvbSAnc3NyLXdpbmRvdyc7XG5pbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmltcG9ydCB7
1IG5vdyB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscy5qcyc7IC8vIE1vZGlmaWVkIGZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTQ1MjA1NTQvY3VzdG9tLWVsZW1lbnQtZ2V0cm9vdG5vZGUtY2xvc2VzdC1mdW5jdGlvbi1jcm9zc2luZy1tdWx0aXBsZS1wYXJlbnQtc2hhZG93ZFxuXG5mdW5jdGlvbiBjbG9zZXN0RWxlbWVudChzZWxlY3RvciwgYmFzZSA9IHRoaXMpIHtcbiAgZnVuY3Rpb24gX19jbG9zZXN0RnJvbShlbCkge1xuICAgIGlmICghZWwgfHwgZWwgPT09IGdldERvY3VtZW50KCkgfHwgZWwgPT09IGdldFdpbmRvdygpKSByZXR1cm4gbnVsbDtcbiAgICBpZiAoZWwuYXNzaWduZWRTbG90KSBlbCA9IGVsLmFzc2lnbmVkU2xvdDtcbiAgICBjb25zdCBmb3VuZCA9IGVsLmNsb3Nlc3Qoc2VsZWN0b3IpO1xuXG4gICAgaWYgKCFmb3VuZCAmJiAhZWwuZ2V0Um9vdE5vZGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBmb3VuZCB8fCBfX2Nsb3Nlc3RGcm9tKGVsLmdldFJvb3ROb2RlKCkuaG9zdCk7XG4gIH1cblxuICByZXR1cm4gX19jbG9zZXN0RnJvbShiYXNlKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gb25Ub3VjaFN0YXJ0KGV2ZW50KSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gIGNvbnN0IGRhdGEgPSBzd2lwZXIudG91Y2hFdmVudHNEYXRhO1xuICBjb25zdCB7XG4gICAgcGFyYW1zLFxuICAgIHRvdWNoZXMsXG4gICAgZW5hYmxlZFxuICB9ID0gc3dpcGVyO1xuICBpZiAoIWVuYWJsZWQpIHJldHVybjtcblxuICBpZiAoc3dpcGVyLmFuaW1hdGluZyAmJiBwYXJhbXMucHJldmVudEludGVyYWN0aW9uT25UcmFuc2l0aW9uKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCFzd2lwZXIuYW5pbWF0aW5nICYmIHBhcmFtcy5jc3NNb2RlICYmIHBhcmFtcy5sb29wKSB7XG4gICAgc3dpcGVyLmxvb3BGaXgoKTtcbiAgfVxuXG4gIGxldCBlID0gZXZlbnQ7XG4gIGlmIChlLm9yaWdpbmFsRXZlbnQpIGUgPSBlLm9yaWdpbmFsRXZlbnQ7XG4gIGxldCAkdGFyZ2V0RWwgPSAkKGUudGFyZ2V0KTtcblxuICBpZiAocGFyYW1zLnRvdWNoRXZlbnRzVGFyZ2V0ID09PSAnd3JhcHBlcicpIHtcbiAgICBpZiAoISR0YXJnZXRFbC5jbG9zZXN0KHN3aXBlci53cmFwcGVyRWwpLmxlbmd0aCkgcmV0dXJuO1xuICB9XG5cbiAgZGF0YS5pc1RvdWNoRXZlbnQgPSBlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JztcbiAgaWYgKCFkYXRhLmlzVG91Y2hFdmVudCAmJiAnd2hpY2gnIGluIGUgJiYgZS53aGljaCA9PT0gMykgcmV0dXJuO1xuICBpZiAoIWRhdGEuaXNUb3VjaEV2ZW50ICYmICdidXR0b24nIGluIGUgJiYgZS5idXR0b24gPiAwKSByZXR1cm47XG4gIGlmIChkYXRhLmlzVG91Y2hlZCAmJiBkYXRhLmlzTW92ZWQpIHJldHVybjsgLy8gY2hhbmdlIHRhcmdldCBlbCBmb3Igc2hhZG93IHJvb3QgY29tcG9uZW50XG5cbiAgY29uc3Qgc3dpcGluZ0NsYXNzSGFzVmFsdWUgPSAhIXBhcmFtcy5ub1N3aXBpbmdDbGFzcyAmJiBwYXJhbXMubm9Td2lwaW5nQ2xhc3MgIT09ICcnOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuICBjb25zdCBldmVudFBhdGggPSBldmVudC5jb21wb3NlZFBhdGggPyBldmVudC5jb21wb3NlZFBhdGgoKSA6IGV2ZW50LnBhdGg7XG5cbiAgaWYgKHN3aXBpbmdDbGFzc0hhc1ZhbHVlICYmIGUudGFyZ2V0ICYmIGUudGFyZ2V0LnNoYWRvd1Jvb3QgJiYgZXZlbnRQYXRoKSB7XG4gICAgJHRhcmdldEVsID0gJChldmVudFBhdGhbMF0pO1xuICB9XG5cbiAgY29uc3Qgbm9Td2lwaW5nU2VsZWN0b3IgPSBwYXJhbXMubm9Td2lwaW5nU2VsZWN0b3IgPyBwYXJhbXMubm9Td2lwaW5nU2VsZWN0b3IgOiBgLiR7cGFyYW1zLm5vU3dpcGluZ0NsYXNzfWA7XG4gIGNvbnN0IGlzVGFyZ2V0U2hhZG93ID0gISEoZS50YXJnZXQgJiYgZS50YXJnZXQuc2hhZG93Um9vdCk7IC8vIHVzZSBjbG9zZXN0RWxlbWVudCBmb3Igc2hhZG93IHJvb3QgZWxlbWVudCB0byBnZXQgdGhlIGFjdHVhbCBjbG9zZXN0IGZvciBuZXN0ZWQgc2hhZG93IHJvb3QgZWxlbWVudFxuXG4gIGlmIChwYXJhbXMubm9Td2lwaW5nICYmIChpc1RhcmdldFNoYWRvdyA/IGNsb3Nlc3RFbGVtZW50KG5vU3dpcGluZ1NlbGVjdG9yLCAkdGFyZ2V0RWxbMF0pIDogJHRhcmdldEVsLmNsb3Nlc3Qobm9Td2lwaW5nU2VsZWN0b3IpWzBdKSkge1xuICAgIHN3aXBlci5hbGxvd0NsaWNrID0gdHJ1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAocGFyYW1zLnN3aXBlSGFuZGxlcikge1xuICAgIGlmICghJHRhcmdldEVsLmNsb3Nlc3QocGFyYW1zLnN3aXBlSGFuZGxlcilbMF0pIHJldHVybjtcbiAgfVxuXG4gIHRvdWNoZXMuY3VycmVudFggPSBlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JyA/IGUudGFyZ2V0VG91Y2hlc1swXS5wYWdlWCA6IGUucGFnZVg7XG4gIHRvdWNoZXMuY3VycmVudFkgPSBlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JyA/IGUudGFyZ2V0VG91Y2hlc1swXS5wYWdlWSA6IGUucGFnZVk7XG4gIGNvbnN0IHN0YXJ0WCA9IHRvdWNoZXMuY3VycmVudFg7XG4gIGNvbnN0IHN0YXJ0WSA9IHRvdWNoZXMuY3VycmVudFk7IC8vIERvIE5PVCBzdGFydCBpZiBpT1MgZWRnZSBzd2lwZSBpcyBkZXRlY3RlZC4gT3RoZXJ3aXNlIGlPUyBhcHAgY2Fubm90IHN3aXBlLXRvLWdvLWJhY2sgYW55bW9yZVxuXG4gIGNvbnN0IGVkZ2VTd2lwZURldGVjdGlvbiA9IHBhcmFtcy5lZGdlU3dpcGVEZXRlY3Rpb24gfHwgcGFyYW1zLmlPU0VkZ2VTd2lwZURldGVjdGlvbjtcbiAgY29uc3QgZWRnZVN3aXBlVGhyZXNob2xkID0gcGFyYW1zLmVkZ2VTd2lwZVRocmVzaG9sZCB8fCBwYXJhbXMuaU9TRWRnZVN3aXBlVGhyZXNob2xkO1xuXG4gIGlmIChlZGdlU3dpcGVEZXRlY3Rpb24gJiYgKHN0YXJ0WCA8PSBlZGdlU3dpcGVUaHJlc2hvbGQgfHwgc3RhcnRYID49IHdpbmRvdy5pbm5lcldpZHRoIC0gZWRnZVN3aXBlVGhyZXNob2xkKSkge1xuICAgIGlmIChlZGdlU3dpcGVEZXRlY3Rpb24gPT09ICdwcmV2ZW50Jykge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIE9iamVjdC5hc3NpZ24oZGF0YSwge1xuICAgIGlzVG91Y2hlZDogdHJ1ZSxcbiAgICBpc01vdmVkOiBmYWxzZSxcbiAgICBhbGxvd1RvdWNoQ2FsbGJhY2tzOiB0cnVlLFxuICAgIGlzU2Nyb2xsaW5nOiB1bmRlZmluZWQsXG4gICAgc3RhcnRNb3Zpbmc6IHVuZGVmaW5lZFxuICB9KTtcbiAgdG91Y2hlcy5zdGFydFggPSBzdGFydFg7XG4gIHRvdWNoZXMuc3RhcnRZID0gc3RhcnRZO1xuICBkYXRhLnRvdWNoU3RhcnRUaW1lID0gbm93KCk7XG4gIHN3aXBlci5hbGxvd0NsaWNrID0gdHJ1ZTtcbiAgc3dpcGVyLnVwZGF0ZVNpemUoKTtcbiAgc3dpcGVyLnN3aXBlRGlyZWN0aW9uID0gdW5kZWZpbmVkO1xuICBpZiAocGFyYW1zLnRocmVzaG9sZCA+IDApIGRhdGEuYWxsb3dUaHJlc2hvbGRNb3ZlID0gZmFsc2U7XG5cbiAgaWYgKGUudHlwZSAhPT0gJ3RvdWNoc3RhcnQnKSB7XG4gICAgbGV0IHByZXZlbn
1REZWZhdWx0ID0gdHJ1ZTtcblxuICAgIGlmICgkdGFyZ2V0RWwuaXMoZGF0YS5mb2N1c2FibGVFbGVtZW50cykpIHtcbiAgICAgIHByZXZlbnREZWZhdWx0ID0gZmFsc2U7XG5cbiAgICAgIGlmICgkdGFyZ2V0RWxbMF0ubm9kZU5hbWUgPT09ICdTRUxFQ1QnKSB7XG4gICAgICAgIGRhdGEuaXNUb3VjaGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgJChkb2N1bWVudC5hY3RpdmVFbGVtZW50KS5pcyhkYXRhLmZvY3VzYWJsZUVsZW1lbnRzKSAmJiBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICE9PSAkdGFyZ2V0RWxbMF0pIHtcbiAgICAgIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuYmx1cigpO1xuICAgIH1cblxuICAgIGNvbnN0IHNob3VsZFByZXZlbnREZWZhdWx0ID0gcHJldmVudERlZmF1bHQgJiYgc3dpcGVyLmFsbG93VG91Y2hNb3ZlICYmIHBhcmFtcy50b3VjaFN0YXJ0UHJldmVudERlZmF1bHQ7XG5cbiAgICBpZiAoKHBhcmFtcy50b3VjaFN0YXJ0Rm9yY2VQcmV2ZW50RGVmYXVsdCB8fCBzaG91bGRQcmV2ZW50RGVmYXVsdCkgJiYgISR0YXJnZXRFbFswXS5pc0NvbnRlbnRFZGl0YWJsZSkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChzd2lwZXIucGFyYW1zLmZyZWVNb2RlICYmIHN3aXBlci5wYXJhbXMuZnJlZU1vZGUuZW5hYmxlZCAmJiBzd2lwZXIuZnJlZU1vZGUgJiYgc3dpcGVyLmFuaW1hdGluZyAmJiAhcGFyYW1zLmNzc01vZGUpIHtcbiAgICBzd2lwZXIuZnJlZU1vZGUub25Ub3VjaFN0YXJ0KCk7XG4gIH1cblxuICBzd2lwZXIuZW1pdCgndG91Y2hTdGFydCcsIGUpO1xufSIsImltcG9ydCB7IGdldERvY3VtZW50IH0gZnJvbSAnc3NyLXdpbmRvdyc7XG5pbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmltcG9ydCB7IG5vdyB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscy5qcyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBvblRvdWNoTW92ZShldmVudCkge1xuICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IGRhdGEgPSBzd2lwZXIudG91Y2hFdmVudHNEYXRhO1xuICBjb25zdCB7XG4gICAgcGFyYW1zLFxuICAgIHRvdWNoZXMsXG4gICAgcnRsVHJhbnNsYXRlOiBydGwsXG4gICAgZW5hYmxlZFxuICB9ID0gc3dpcGVyO1xuICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgbGV0IGUgPSBldmVudDtcbiAgaWYgKGUub3JpZ2luYWxFdmVudCkgZSA9IGUub3JpZ2luYWxFdmVudDtcblxuICBpZiAoIWRhdGEuaXNUb3VjaGVkKSB7XG4gICAgaWYgKGRhdGEuc3RhcnRNb3ZpbmcgJiYgZGF0YS5pc1Njcm9sbGluZykge1xuICAgICAgc3dpcGVyLmVtaXQoJ3RvdWNoTW92ZU9wcG9zaXRlJywgZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGRhdGEuaXNUb3VjaEV2ZW50ICYmIGUudHlwZSAhPT0gJ3RvdWNobW92ZScpIHJldHVybjtcbiAgY29uc3QgdGFyZ2V0VG91Y2ggPSBlLnR5cGUgPT09ICd0b3VjaG1vdmUnICYmIGUudGFyZ2V0VG91Y2hlcyAmJiAoZS50YXJnZXRUb3VjaGVzWzBdIHx8IGUuY2hhbmdlZFRvdWNoZXNbMF0pO1xuICBjb25zdCBwYWdlWCA9IGUudHlwZSA9PT0gJ3RvdWNobW92ZScgPyB0YXJnZXRUb3VjaC5wYWdlWCA6IGUucGFnZVg7XG4gIGNvbnN0IHBhZ2VZID0gZS50eXBlID09PSAndG91Y2htb3ZlJyA/IHRhcmdldFRvdWNoLnBhZ2VZIDogZS5wYWdlWTtcblxuICBpZiAoZS5wcmV2ZW50ZWRCeU5lc3RlZFN3aXBlcikge1xuICAgIHRvdWNoZXMuc3RhcnRYID0gcGFnZVg7XG4gICAgdG91Y2hlcy5zdGFydFkgPSBwYWdlWTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoIXN3aXBlci5hbGxvd1RvdWNoTW92ZSkge1xuICAgIGlmICghJChlLnRhcmdldCkuaXMoZGF0YS5mb2N1c2FibGVFbGVtZW50cykpIHtcbiAgICAgIHN3aXBlci5hbGxvd0NsaWNrID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKGRhdGEuaXNUb3VjaGVkKSB7XG4gICAgICBPYmplY3QuYXNzaWduKHRvdWNoZXMsIHtcbiAgICAgICAgc3RhcnRYOiBwYWdlWCxcbiAgICAgICAgc3RhcnRZOiBwYWdlWSxcbiAgICAgICAgY3VycmVudFg6IHBhZ2VYLFxuICAgICAgICBjdXJyZW50WTogcGFnZVlcbiAgICAgIH0pO1xuICAgICAgZGF0YS50b3VjaFN0YXJ0VGltZSA9IG5vdygpO1xuICAgIH1cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChkYXRhLmlzVG91Y2hFdmVudCAmJiBwYXJhbXMudG91Y2hSZWxlYXNlT25FZGdlcyAmJiAhcGFyYW1zLmxvb3ApIHtcbiAgICBpZiAoc3dpcGVyLmlzVmVydGljYWwoKSkge1xuICAgICAgLy8gVmVydGljYWxcbiAgICAgIGlmIChwYWdlWSA8IHRvdWNoZXMuc3RhcnRZICYmIHN3aXBlci50cmFuc2xhdGUgPD0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpIHx8IHBhZ2VZID4gdG91Y2hlcy5zdGFydFkgJiYgc3dpcGVyLnRyYW5zbGF0ZSA+PSBzd2lwZXIubWluVHJhbnNsYXRlKCkpIHtcbiAgICAgICAgZGF0YS5pc1RvdWNoZWQgPSBmYWxzZTtcbiAgICAgICAgZGF0YS5pc01vdmVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBhZ2VYIDwgdG91Y2hlcy5zdGFydFggJiYgc3dpcGVyLnRyYW5zbGF0ZSA8PSBzd2lwZXIubWF4VHJhbnNsYXRlKCkgfHwgcGFnZVggPiB0b3VjaGVzLnN0YXJ0WCAmJiBzd2lwZXIudHJhbnNsYXRlID49IHN3aXBlci5taW5UcmFuc2xhdGUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmIChkYXRhLmlzVG91Y2hFdmVudCAmJiBkb2N1bWVudC5hY3RpdmVFbGVtZW50KSB7XG4gICAgaWYgKGUudGFyZ2V0ID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmICQoZS50YXJnZXQpLmlzKGRhdGEuZm9jdXNhYmxlRWxlbWVudHMpKSB7XG4gICAgICBkYXRhLmlzTW92ZWQgPSB0cnVlO1xuICAgICAgc3dpcGVyLmFsbG93Q2xpY2sgPSBmYWxzZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBpZiAoZGF0YS5hbGxvd1RvdWNoQ2FsbGJhY2tzKSB7XG4gICAgc3dpcGVyLmVtaXQoJ3RvdWNoTW92ZScsIGUpO1xuICB9XG5cbiAgaWYgKGUudGFyZ2V0VG91Y2hlcyAmJiBlLnRhcmdldFRvdWNoZXMubGVuZ3RoID4gMSkgcmV0dXJuO1xuICB0b3VjaGVzLmN1cnJlbnRYID0gcGFnZVg7XG4gIHRvdWNoZXMuY3VycmVudFkgPSBwYWdlWTtcbiAgY29uc3QgZGlmZlggPSB0b3VjaGVzLmN1cnJlbnRYIC0gdG91Y2hlcy5zdGFydFg7XG4gIGNvbnN0IGRpZmZZID0gdG91Y2hlcy5jdXJyZW50WSAtIHRvdWNoZXMuc3RhcnRZO1xuICBpZiAoc3dpcGVyLnBhcmFtcy50aHJlc2hvbGQgJiYgTWF0aC5zcXJ0KGRpZmZYICoqIDIgKyBkaWZmWSAqKiAyKSA8IHN3aXBlci5wYXJhbXMudGhyZXNob2xkKSByZXR1cm47XG5cbiAgaWYgKHR5cGVvZiBkYXRhLmlzU2Nyb2xsaW5nID09PSAndW5kZWZpbmVkJykge1xuICAgIGxldCB0b3VjaEFuZ2xlO1xuXG4gICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSAmJi
1B0b3VjaGVzLmN1cnJlbnRZID09PSB0b3VjaGVzLnN0YXJ0WSB8fCBzd2lwZXIuaXNWZXJ0aWNhbCgpICYmIHRvdWNoZXMuY3VycmVudFggPT09IHRvdWNoZXMuc3RhcnRYKSB7XG4gICAgICBkYXRhLmlzU2Nyb2xsaW5nID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgaWYgKGRpZmZYICogZGlmZlggKyBkaWZmWSAqIGRpZmZZID49IDI1KSB7XG4gICAgICAgIHRvdWNoQW5nbGUgPSBNYXRoLmF0YW4yKE1hdGguYWJzKGRpZmZZKSwgTWF0aC5hYnMoZGlmZlgpKSAqIDE4MCAvIE1hdGguUEk7XG4gICAgICAgIGRhdGEuaXNTY3JvbGxpbmcgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyB0b3VjaEFuZ2xlID4gcGFyYW1zLnRvdWNoQW5nbGUgOiA5MCAtIHRvdWNoQW5nbGUgPiBwYXJhbXMudG91Y2hBbmdsZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoZGF0YS5pc1Njcm9sbGluZykge1xuICAgIHN3aXBlci5lbWl0KCd0b3VjaE1vdmVPcHBvc2l0ZScsIGUpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBkYXRhLnN0YXJ0TW92aW5nID09PSAndW5kZWZpbmVkJykge1xuICAgIGlmICh0b3VjaGVzLmN1cnJlbnRYICE9PSB0b3VjaGVzLnN0YXJ0WCB8fCB0b3VjaGVzLmN1cnJlbnRZICE9PSB0b3VjaGVzLnN0YXJ0WSkge1xuICAgICAgZGF0YS5zdGFydE1vdmluZyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKGRhdGEuaXNTY3JvbGxpbmcpIHtcbiAgICBkYXRhLmlzVG91Y2hlZCA9IGZhbHNlO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghZGF0YS5zdGFydE1vdmluZykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHN3aXBlci5hbGxvd0NsaWNrID0gZmFsc2U7XG5cbiAgaWYgKCFwYXJhbXMuY3NzTW9kZSAmJiBlLmNhbmNlbGFibG
1UpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICBpZiAocGFyYW1zLnRvdWNoTW92ZVN0b3BQcm9wYWdhdGlvbiAmJiAhcGFyYW1zLm5lc3RlZCkge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBpZiAoIWRhdGEuaXNNb3ZlZCkge1xuICAgIGlmIChwYXJhbXMubG9vcCAmJiAhcGFyYW1zLmNzc01vZGUpIHtcbiAgICAgIHN3aXBlci5sb29wRml4KCk7XG4gICAgfVxuXG4gICAgZGF0YS5zdGFydFRyYW5zbGF0ZSA9IHN3aXBlci5nZXRUcmFuc2xhdGUoKTtcbiAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbigwKTtcblxuICAgIGlmIChzd2lwZXIuYW5pbWF0aW5nKSB7XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbC50cmlnZ2VyKCd3ZWJraXRUcmFuc2l0aW9uRW5kIHRyYW5zaXRpb25lbmQnKTtcbiAgICB9XG5cbiAgICBkYXRhLmFsbG93TW9tZW50dW1Cb3VuY2UgPSBmYWxzZTsgLy8gR3JhYiBDdXJzb3JcblxuICAgIGlmIChwYXJhbXMuZ3JhYkN1cnNvciAmJiAoc3dpcGVyLmFsbG93U2xpZGVOZXh0ID09PSB0cnVlIHx8IHN3aXBlci5hbGxvd1NsaWRlUHJldiA9PT0gdHJ1ZSkpIHtcbiAgICAgIHN3aXBlci5zZXRHcmFiQ3Vyc29yKHRydWUpO1xuICAgIH1cblxuICAgIHN3aXBlci5lbWl0KCdzbGlkZXJGaXJzdE1vdmUnLCBlKTtcbiAgfVxuXG4gIHN3aXBlci5lbWl0KCdzbGlkZXJNb3ZlJywgZSk7XG4gIGRhdGEuaXNNb3ZlZCA9IHRydWU7XG4gIGxldCBkaWZmID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gZGlmZlggOiBkaWZmWTtcbiAgdG91Y2hlcy5kaWZmID0gZGlmZjtcbiAgZGlmZiAqPSBwYXJhbXMudG91Y2hSYXRpbztcbiAgaWYgKHJ0bCkgZGlmZiA9IC1kaWZmO1xuICBzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPSBkaWZmID4gMCA/ICdwcmV2JyA6ICduZXh0JztcbiAgZGF0YS5jdXJyZW50VHJhbnNsYXRlID0gZGlmZiArIGRhdGEuc3RhcnRUcmFuc2xhdGU7XG4gIGxldCBkaXNhYmxlUGFyZW50U3dpcGVyID0gdHJ1ZTtcbiAgbGV0IHJlc2lzdGFuY2VSYXRpbyA9IHBhcmFtcy5yZXNpc3RhbmNlUmF0aW87XG5cbiAgaWYgKHBhcmFtcy50b3VjaFJlbGVhc2VPbkVkZ2VzKSB7XG4gICAgcmVzaXN0YW5jZVJhdGlvID0gMDtcbiAgfVxuXG4gIGlmIChkaWZmID4gMCAmJiBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPiBzd2lwZXIubWluVHJhbnNsYXRlKCkpIHtcbiAgICBkaXNhYmxlUGFyZW50U3dpcGVyID0gZmFsc2U7XG4gICAgaWYgKHBhcmFtcy5yZXNpc3RhbmNlKSBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPSBzd2lwZXIubWluVHJhbnNsYXRlKCkgLSAxICsgKC1zd2lwZXIubWluVHJhbnNsYXRlKCkgKyBkYXRhLnN0YXJ0VHJhbnNsYXRlICsgZGlmZikgKiogcmVzaXN0YW5jZVJhdGlvO1xuICB9IGVsc2UgaWYgKGRpZmYgPCAwICYmIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA8IHN3aXBlci5tYXhUcmFuc2xhdGUoKSkge1xuICAgIGRpc2FibGVQYXJlbnRTd2lwZXIgPSBmYWxzZTtcbiAgICBpZiAocGFyYW1zLnJlc2lzdGFuY2UpIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9IHN3aXBlci5tYXhUcmFuc2xhdGUoKSArIDEgLSAoc3dpcGVyLm1heFRyYW5zbGF0ZSgpIC0gZGF0YS5zdGFydFRyYW5zbGF0ZSAtIGRpZmYpICoqIHJlc2lzdGFuY2VSYXRpbztcbiAgfVxuXG4gIGlmIChkaXNhYmxlUGFyZW50U3dpcGVyKSB7XG4gICAgZS5wcmV2ZW50ZWRCeU5lc3RlZFN3aXBlciA9IHRydWU7XG4gIH0gLy8gRGlyZWN0aW9ucyBsb2Nrc1xuXG5cbiAgaWYgKCFzd2lwZXIuYWxsb3dTbGlkZU5leHQgJiYgc3dpcGVyLnN3aXBlRGlyZWN0aW9uID09PSAnbmV4dCcgJiYgZGF0YS5jdXJyZW50VHJhbnNsYXRlIDwgZGF0YS5zdGFydFRyYW5zbGF0ZSkge1xuICAgIGRhdGEuY3VycmVudFRyYW5zbGF0ZSA9IGRhdGEuc3RhcnRUcmFuc2xhdGU7XG4gIH1cblxuICBpZiAoIXN3aXBlci5hbGxvd1NsaWRlUHJldiAmJiBzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPT09ICdwcmV2JyAmJiBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPiBkYXRhLnN0YXJ0VHJhbnNsYXRlKSB7XG4gICAgZGF0YS5jdXJyZW50VHJhbnNsYXRlID0gZGF0YS5zdGFydFRyYW5zbGF0ZTtcbiAgfVxuXG4gIGlmICghc3dpcGVyLmFsbG93U2xpZGVQcmV2ICYmICFzd2lwZXIuYWxsb3dTbGlkZU5leHQpIHtcbiAgICBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPSBkYXRhLnN0YXJ0VHJhbnNsYXRlO1xuICB9IC8vIFRocmVzaG9sZFxuXG5cbiAgaWYgKHBhcmFtcy50aHJlc2hvbGQgPiAwKSB7XG4gICAgaWYgKE1hdGguYWJzKGRpZmYpID4gcGFyYW1zLnRocmVzaG9sZCB8fCBkYXRhLmFsbG93VGhyZXNob2xkTW92ZSkge1xuICAgICAgaWYgKCFkYXRhLmFsbG93VGhyZXNob2xkTW92ZSkge1xuICAgICAgICBkYXRhLmFsbG93VGhyZXNob2xkTW92ZSA9IHRydWU7XG4gICAgICAgIHRvdWNoZXMuc3RhcnRYID0gdG91Y2hlcy5jdXJyZW50WDtcbiAgICAgICAgdG91Y2hlcy5zdGFydFkgPSB0b3VjaGVzLmN1cnJlbnRZO1xuICAgICAgICBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPSBkYXRhLnN0YXJ0VHJhbnNsYXRlO1xuICAgICAgICB0b3VjaGVzLmRpZmYgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyB0b3VjaGVzLmN1cnJlbnRYIC0gdG91Y2hlcy5zdGFydFggOiB0b3VjaGVzLmN1cnJlbnRZIC0gdG91Y2hlcy5zdGFydFk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5jdXJyZW50VHJhbnNsYXRlID0gZGF0YS5zdGFydFRyYW5zbGF0ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBpZiAoIXBhcmFtcy5mb2xsb3dGaW5nZXIgfHwgcGFyYW1zLmNzc01vZGUpIHJldHVybjsgLy8gVXBkYXRlIGFjdGl2ZSBpbmRleCBpbiBmcmVlIG1vZGVcblxuICBpZiAocGFyYW1zLmZyZWVNb2RlICYmIHBhcmFtcy5mcmVlTW9kZS5lbmFibGVkICYmIHN3aXBlci5mcmVlTW9kZSB8fCBwYXJhbXMud2F0Y2hTbGlkZXNQcm9ncmVzcykge1xuICAgIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleCgpO1xuICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG4gIH1cblxuICBpZiAoc3dpcGVyLnBhcmFtcy5mcmVlTW9kZSAmJiBwYXJhbXMuZnJlZU1vZGUuZW5hYmxlZCAmJiBzd2lwZXIuZnJlZU1vZGUpIHtcbiAgICBzd2lwZXIuZnJlZU1vZGUub25Ub3VjaE1vdmUoKTtcbiAgfSAvLyBVcGRhdGUgcHJvZ3Jlc3NcblxuXG4gI
1HN3aXBlci51cGRhdGVQcm9ncmVzcyhkYXRhLmN1cnJlbnRUcmFuc2xhdGUpOyAvLyBVcGRhdGUgdHJhbnNsYXRlXG5cbiAgc3dpcGVyLnNldFRyYW5zbGF0ZShkYXRhLmN1cnJlbnRUcmFuc2xhdGUpO1xufSIsImltcG9ydCB7IG5vdywgbmV4dFRpY2sgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gb25Ub3VjaEVuZChldmVudCkge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBjb25zdCBkYXRhID0gc3dpcGVyLnRvdWNoRXZlbnRzRGF0YTtcbiAgY29uc3Qge1xuICAgIHBhcmFtcyxcbiAgICB0b3VjaGVzLFxuICAgIHJ0bFRyYW5zbGF0ZTogcnRsLFxuICAgIHNsaWRlc0dyaWQsXG4gICAgZW5hYmxlZFxuICB9ID0gc3dpcGVyO1xuICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgbGV0IGUgPSBldmVudDtcbiAgaWYgKGUub3JpZ2luYWxFdmVudCkgZSA9IGUub3JpZ2luYWxFdmVudDtcblxuICBpZiAoZGF0YS5hbGxvd1RvdWNoQ2FsbGJhY2tzKSB7XG4gICAgc3dpcGVyLmVtaXQoJ3RvdWNoRW5kJywgZSk7XG4gIH1cblxuICBkYXRhLmFsbG93VG91Y2hDYWxsYmFja3MgPSBmYWxzZTtcblxuICBpZiAoIWRhdGEuaXNUb3VjaGVkKSB7XG4gICAgaWYgKGRhdGEuaXNNb3ZlZCAmJiBwYXJhbXMuZ3JhYkN1cnNvcikge1xuICAgICAgc3dpcGVyLnNldEdyYWJDdXJzb3IoZmFsc2UpO1xuICAgIH1cblxuICAgIGRhdGEuaXNNb3ZlZCA9IGZhbHNlO1xuICAgIGRhdGEuc3RhcnRNb3ZpbmcgPSBmYWxzZTtcbiAgICByZXR1cm47XG4gIH0gLy8gUmV0dXJuIEdyYWIgQ3Vyc29yXG5cblxuICBpZiAocGFyYW1zLmdyYWJDdXJzb3IgJiYgZGF0YS5pc01vdmVkICYmIGRhdGEuaXNUb3VjaGVkICYmIChzd2lwZXIuYWxsb3dTbGlkZU5leHQgPT09IHRydWUgfHwgc3dpcGVyLmFsbG93U2xpZGVQcmV2ID09PSB0cnVlKSkge1xuICAgIHN3aXBlci5zZXRHcmFiQ3Vyc29yKGZhbHNlKTtcbiAgfSAvLyBUaW1lIGRpZmZcblxuXG4gIGNvbnN0IHRvdWNoRW5kVGltZSA9IG5vdygpO1xuICBjb25zdCB0aW1lRGlmZiA9IHRvdWNoRW5kVGltZSAtIGRhdGEudG91Y2hTdGFydFRpbWU7IC8vIFRhcCwgZG91YmxlVGFwLCBDbGlja1xuXG4gIGlmIChzd2lwZXIuYWxsb3dDbGljaykge1xuICAgIGNvbnN0IHBhdGhUcmVlID0gZS5wYXRoIHx8IGUuY29tcG9zZWRQYXRoICYmIGUuY29tcG9zZWRQYXRoKCk7XG4gICAgc3dpcGVyLnVwZGF0ZUNsaWNrZWRTbGlkZShwYXRoVHJlZSAmJiBwYXRoVHJlZVswXSB8fCBlLnRhcmdldCk7XG4gICAgc3dpcGVyLmVtaXQoJ3RhcCBjbGljaycsIGUpO1xuXG4gICAgaWYgKHRpbWVEaWZmIDwgMzAwICYmIHRvdWNoRW5kVGltZSAtIGRhdGEubGFzdENsaWNrVGltZSA8IDMwMCkge1xuICAgICAgc3dpcGVyLmVtaXQoJ2RvdWJsZVRhcCBkb3VibGVDbGljaycsIGUpO1xuICAgIH1cbiAgfVxuXG4gIGRhdGEubGFzdENsaWNrVGltZSA9IG5vdygpO1xuICBuZXh0VGljaygoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIuZGVzdHJveWVkKSBzd2lwZXIuYWxsb3dDbGljayA9IHRydWU7XG4gIH0pO1xuXG4gIGlmICghZGF0YS5pc1RvdWNoZWQgfHwgIWRhdGEuaXNNb3ZlZCB8fCAhc3dpcGVyLnN3aXBlRGlyZWN0aW9uIHx8IHRvdWNoZXMuZGlmZiA9PT0gMCB8fCBkYXRhLmN1cnJlbnRUcmFuc2xhdGUgPT09IGRhdGEuc3RhcnRUcmFuc2xhdGUpIHtcbiAgICBkYXRhLmlzVG91Y2hlZCA9IGZhbHNlO1xuICAgIGRhdGEuaXNNb3ZlZCA9IGZhbHNlO1xuICAgIGRhdGEuc3RhcnRNb3ZpbmcgPSBmYWxzZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBkYXRhLmlzVG91Y2hlZCA9IGZhbHNlO1xuICBkYXRhLmlzTW92ZWQgPSBmYWxzZTtcbiAgZGF0YS5zdGFydE1vdmluZyA9IGZhbHNlO1xuICBsZXQgY3VycmVudFBvcztcblxuICBpZiAocGFyYW1zLmZvbGxvd0Zpbmdlcikge1xuICAgIGN1cnJlbnRQb3MgPSBydGwgPyBzd2lwZXIudHJhbnNsYXRlIDogLXN3aXBlci50cmFuc2xhdGU7XG4gIH0gZWxzZSB7XG4gICAgY3VycmVudFBvcyA9IC1kYXRhLmN1cnJlbnRUcmFuc2xhdGU7XG4gIH1cblxuICBpZiAocGFyYW1zLmNzc01vZGUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoc3dpcGVyLnBhcmFtcy5mcmVlTW9kZSAmJiBwYXJhbXMuZnJlZU1vZGUuZW5hYmxlZCkge1xuICAgIHN3aXBlci5mcmVlTW9kZS5vblRvdWNoRW5kKHtcbiAgICAgIGN1cnJlbnRQb3NcbiAgICB9KTtcbiAgICByZXR1cm47XG4gIH0gLy8gRmluZCBjdXJyZW50IHNsaWRlXG5cblxuICBsZXQgc3RvcEluZGV4ID0gMDtcbiAgbGV0IGdyb3VwU2l6ZSA9IHN3aXBlci5zbGlkZXNTaXplc0dyaWRbMF07XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXNHcmlkLmxlbmd0aDsgaSArPSBpIDwgcGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCA/IDEgOiBwYXJhbXMuc2xpZGVzUGVyR3JvdXApIHtcbiAgICBjb25zdCBpbmNyZW1lbnQgPSBpIDwgcGFyYW1zLnNsaWRlc1Blckdyb3VwU2tpcCAtIDEgPyAxIDogcGFyYW1zLnNsaWRlc1Blckdyb3VwO1xuXG4gICAgaWYgKHR5cGVvZiBzbGlkZXNHcmlkW2kgKyBpbmNyZW1lbnRdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKGN1cnJlbnRQb3MgPj0gc2xpZGVzR3JpZFtpXSAmJiBjdXJyZW50UG9zIDwgc2xpZGVzR3JpZFtpICsgaW5jcmVtZW50XSkge1xuICAgICAgICBzdG9wSW5kZXggPSBpO1xuICAgICAgICBncm91cFNpemUgPSBzbGlkZXNHcmlkW2kgKyBpbmNyZW1lbnRdIC0gc2xpZGVzR3JpZFtpXTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGN1cnJlbnRQb3MgPj0gc2xpZGVzR3JpZFtpXSkge1xuICAgICAgc3RvcEluZGV4ID0gaTtcbiAgICAgIGdyb3VwU2l6ZSA9IHNsaWRlc0dyaWRbc2xpZGVzR3JpZC5sZW5ndGggLSAxXSAtIHNsaWRlc0dyaWRbc2xpZGVzR3JpZC5sZW5ndGggLSAyXTtcbiAgICB9XG4gIH1cblxuICBsZXQgcmV3aW5kRmlyc3RJbmRleCA9IG51bGw7XG4gIGxldCByZXdpbmRMYXN0SW5kZXggPSBudWxsO1xuXG4gIGlmIChwYXJhbXMucmV3aW5kKSB7XG4gICAgaWYgKHN3aXBlci5pc0JlZ2lubmluZykge1xuICAgICAgcmV3aW5kTGFzdEluZGV4ID0gc3dpcGVyLnBhcmFtcy52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkICYmIHN3aXBlci52aXJ0dWFsID8gc3dpcGVyLnZpcnR1YWwuc2xpZGVzLmxlbmd0aCAtIDEgOiBzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDE7XG4gICAgfSBlbHNlIGlmIChzd2lwZXIuaXNFbmQpIHtcbiAgICAgIHJld2luZEZpcnN0SW5kZXggPSAwO1xuICAgIH1cbiAgfSAvLyBGaW5kIGN1cnJlbnQgc2xpZGUgc2l6ZVxuXG5cbiAgY29uc3QgcmF0aW8gPSAoY3VycmVudFBvcyAtIHNsaWRlc0dyaWRbc3RvcEluZGV4XSkgLyBncm91cFNpemU7XG4gIGNvbnN0IGluY3JlbWVudCA9IHN0b3BJbmRleCA8IHBhcmFtcy5zbGlkZXNQZXJHcm91cFNraXAgLSAxID8gMSA6IHBhcmFtcy5zbGlkZXNQZXJHcm91cDtcblxuICBpZiAodGltZURpZmYgPiBwYXJhbXMubG9uZ1N3aXBlc01zKSB7XG4gICAgLy8gTG9uZyB0b3VjaGVzXG4gICAgaWYgKCFwYXJhbXMubG9uZ1N3aXBlcykge1xuICAgICAgc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoc3dpcGVyLnN3aXBlRGlyZWN0aW9uID09PSAnbmV4dCcpIHtcbiAgICAgIGlmIChyYXRpbyA+PSBwYXJhbXMubG9uZ1N3aXBlc1JhdGlvKSBzd2lwZXIuc2xpZGVUbyhwYXJhbXMucmV3aW5kICYmIHN3aXBlci5pc0VuZCA/IHJld2luZEZpcnN0SW5kZXggOiBzdG9wSW5kZXggKyBpbmNyZW1lbnQpO2Vsc2Ug
1c3dpcGVyLnNsaWRlVG8oc3RvcEluZGV4KTtcbiAgICB9XG5cbiAgICBpZiAoc3dpcGVyLnN3aXBlRGlyZWN0aW9uID09PSAncHJldicpIHtcbiAgICAgIGlmIChyYXRpbyA+IDEgLSBwYXJhbXMubG9uZ1N3aXBlc1JhdGlvKSB7XG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHN0b3BJbmRleCArIGluY3JlbWVudCk7XG4gICAgICB9IGVsc2UgaWYgKHJld2luZExhc3RJbmRleCAhPT0gbnVsbCAmJiByYXRpbyA8IDAgJiYgTWF0aC5hYnMocmF0aW8pID4gcGFyYW1zLmxvbmdTd2lwZXNSYXRpbykge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhyZXdpbmRMYXN0SW5kZXgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3dpcGVyLnNsaWRlVG8oc3RvcEluZGV4KTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gU2hvcnQgc3dpcGVzXG4gICAgaWYgKCFwYXJhbXMuc2hvcnRTd2lwZXMpIHtcbiAgICAgIHN3aXBlci5zbGlkZVRvKHN3aXBlci5hY3RpdmVJbmRleCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaXNOYXZCdXR0b25UYXJnZXQgPSBzd2lwZXIubmF2aWdhdGlvbiAmJiAoZS50YXJnZXQgPT09IHN3aXBlci5uYXZpZ2F0aW9uLm5leHRFbCB8fCBlLnRhcmdldCA9PT0gc3dpcGVyLm5hdmlnYXRpb24ucHJldkVsKTtcblxuICAgIGlmICghaXNOYXZCdXR0b25UYXJnZXQpIHtcbiAgICAgIGlmIChzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPT09ICduZXh0Jykge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhyZXdpbmRGaXJzdEluZGV4ICE9PSBudWxsID8gcmV3aW5kRmlyc3RJbmRleCA6IHN0b3BJbmRleCArIGluY3JlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIuc3dpcGVEaXJlY3Rpb24gPT09ICdwcmV2Jykge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhyZXdpbmRMYXN0SW5kZXggIT09IG51bGwgPyByZXdpbmRMYXN0SW5kZXggOiBzdG9wSW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZS50YXJnZXQgPT09IHN3aXBlci5uYXZpZ2F0aW9uLm5leHRFbCkge1xuICAgICAgc3dpcGVyLnNsaWRlVG8oc3RvcEluZGV4ICsgaW5jcmVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3dpcGVyLnNsaWRlVG8oc3RvcEluZGV4KTtcbiAgICB9XG4gIH1cbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBvblJlc2l6ZSgpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3Qge1xuICAgIHBhcmFtcyxcbiAgICBlbFxuICB9ID0gc3dpcGVyO1xuICBpZiAoZWwgJiYgZWwub2Zmc2V0V2lkdGggPT09IDApIHJldHVybjsgLy8gQnJlYWtwb2ludHNcblxuICBpZiAocGFyYW1zLmJyZWFrcG9pbnRzKSB7XG4gICAgc3dpcGVyLnNldEJyZWFrcG9pbnQoKTtcbiAgfSAvLyBTYXZlIGxvY2tzXG5cblxuICBjb25zdCB7XG4gICAgYWxsb3dTbGlkZU5leHQsXG4gICAgYWxsb3dTbGlkZVByZXYsXG4gICAgc25hcEdyaWRcbiAgfSA9IHN3aXBlcjsgLy8gRGlzYWJsZSBsb2NrcyBvbiByZXNpemVcblxuICBzd2lwZXIuYWxsb3dTbGlkZU5leHQgPSB0cnVlO1xuICBzd2lwZXIuYWxsb3dTbGlkZVByZXYgPSB0cnVlO1xuICBzd2lwZXIudXBkYXRlU2l6ZSgpO1xuICBzd2lwZXIudXBkYXRlU2xpZGVzKCk7XG4gIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG5cbiAgaWYgKChwYXJhbXMuc2xpZGVzUGVyVmlldyA9PT0gJ2F1dG8nIHx8IHBhcmFtcy5zbGlkZXNQZXJWaWV3ID4gMSkgJiYgc3dpcGVyLmlzRW5kICYmICFzd2lwZXIuaXNCZWdpbm5pbmcgJiYgIXN3aXBlci5wYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcbiAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDEsIDAsIGZhbHNlLCB0cnVlKTtcbiAgfSBlbHNlIHtcbiAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuYWN0aXZlSW5kZXgsIDAsIGZhbHNlLCB0cnVlKTtcbiAgfVxuXG4gIGlmIChzd2lwZXIuYXV0b3BsYXkgJiYgc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcgJiYgc3dpcGVyLmF1dG9wbGF5LnBhdXNlZCkge1xuICAgIHN3aXBlci5hdXRvcGxheS5ydW4oKTtcbiAgfSAvLyBSZXR1cm4gbG9ja3MgYWZ0ZXIgcmVzaXplXG5cblxuICBzd2lwZXIuYWxsb3dTbGlkZVByZXYgPSBhbGxvd1NsaWRlUHJldjtcbiAgc3dpcGVyLmFsbG93U2xpZGVOZXh0ID0gYWxsb3dTbGlkZU5leHQ7XG5cbiAgaWYgKHN3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzbmFwR3JpZCAhPT0gc3dpcGVyLnNuYXBHcmlkKSB7XG4gICAgc3dpcGVyLmNoZWNrT3ZlcmZsb3coKTtcbiAgfVxufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG9uQ2xpY2soZSkge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBpZiAoIXN3aXBlci5lbmFibGVkKSByZXR1cm47XG5cbiAgaWYgKCFzd2lwZXIuYWxsb3dDbGljaykge1xuICAgIGlmIChzd2lwZXIucGFyYW1zLnByZXZlbnRDbGlja3MpIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLnByZXZlbnRDbGlja3NQcm9wYWdhdGlvbiAmJiBzd2lwZXIuYW5pbWF0aW5nKSB7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICB9XG4gIH1cbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBvblNjcm9sbCgpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3Qge1xuICAgIHdyYXBwZXJFbCxcbiAgICBydGxUcmFuc2xhdGUsXG4gICAgZW5hYmxlZFxuICB9ID0gc3dpcGVyO1xuICBpZiAoIWVuYWJsZWQpIHJldHVybjtcbiAgc3dpcGVyLnByZXZpb3VzVHJhbnNsYXRlID0gc3dpcGVyLnRyYW5zbGF0ZTtcblxuICBpZiAoc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgc3dpcGVyLnRyYW5zbGF0ZSA9IC13cmFwcGVyRWwuc2Nyb2xsTGVmdDtcbiAgfSBlbHNlIHtcbiAgICBzd2lwZXIudHJhbnNsYXRlID0gLXdyYXBwZXJFbC5zY3JvbGxUb3A7XG4gIH0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG5cblxuICBpZiAoc3dpcGVyLnRyYW5zbGF0ZSA9PT0gMCkgc3dpcGVyLnRyYW5zbGF0ZSA9IDA7XG4gIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleCgpO1xuICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xuICBsZXQgbm
1V3UHJvZ3Jlc3M7XG4gIGNvbnN0IHRyYW5zbGF0ZXNEaWZmID0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpO1xuXG4gIGlmICh0cmFuc2xhdGVzRGlmZiA9PT0gMCkge1xuICAgIG5ld1Byb2dyZXNzID0gMDtcbiAgfSBlbHNlIHtcbiAgICBuZXdQcm9ncmVzcyA9IChzd2lwZXIudHJhbnNsYXRlIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpKSAvIHRyYW5zbGF0ZXNEaWZmO1xuICB9XG5cbiAgaWYgKG5ld1Byb2dyZXNzICE9PSBzd2lwZXIucHJvZ3Jlc3MpIHtcbiAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MocnRsVHJhbnNsYXRlID8gLXN3aXBlci50cmFuc2xhdGUgOiBzd2lwZXIudHJhbnNsYXRlKTtcbiAgfVxuXG4gIHN3aXBlci5lbWl0KCdzZXRUcmFuc2xhdGUnLCBzd2lwZXIudHJhbnNsYXRlLCBmYWxzZSk7XG59IiwiaW1wb3J0IHsgZ2V0RG9jdW1lbnQgfSBmcm9tICdzc3Itd2luZG93JztcbmltcG9ydCBvblRvdWNoU3RhcnQgZnJvbSAnLi9vblRvdWNoU3RhcnQuanMnO1xuaW1wb3J0IG9uVG91Y2hNb3ZlIGZyb20gJy4vb25Ub3VjaE1vdmUuanMnO1xuaW1wb3J0IG9uVG91Y2hFbmQgZnJvbSAnLi9vblRvdWNoRW5kLmpzJztcbmltcG9ydCBvblJlc2l6ZSBmcm9tICcuL29uUmVzaXplLmpzJztcbmltcG9ydCBvbkNsaWNrIGZyb20gJy4vb25DbGljay5qcyc7XG5pbXBvcnQgb25TY3JvbGwgZnJvbSAnLi9vblNjcm9sbC5qcyc7XG5sZXQgZHVtbXlFdmVudEF0dGFjaGVkID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGR1bW15RXZlbnRMaXN0ZW5lcigpIHt9XG5cbmNvbnN0IGV2ZW50cyA9IChzd2lwZXIsIG1ldGhvZCkgPT4ge1xuICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gIGNvbnN0IHtcbiAgICBwYXJhbXMsXG4gICAgdG91Y2hFdmVudHMsXG4gICAgZWwsXG4gICAgd3JhcHBlckVsLFxuICAgIGRldmljZSxcbiAgICBzdXBwb3J0XG4gIH0gPSBzd2lwZXI7XG4gIGNvbnN0IGNhcHR1cmUgPSAhIXBhcmFtcy5uZXN0ZWQ7XG4gIGNvbnN0IGRvbU1ldGhvZCA9IG1ldGhvZCA9PT0gJ29uJyA/ICdhZGRFdmVudExpc3RlbmVyJyA6ICdyZW1vdmVFdmVudExpc3RlbmVyJztcbiAgY29uc3Qgc3dpcGVyTWV0aG9kID0gbWV0aG9kOyAvLyBUb3VjaCBFdmVudHNcblxuICBpZiAoIXN1cHBvcnQudG91Y2gpIHtcbiAgICBlbFtkb21NZXRob2RdKHRvdWNoRXZlbnRzLnN0YXJ0LCBzd2lwZXIub25Ub3VjaFN0YXJ0LCBmYWxzZSk7XG4gICAgZG9jdW1lbnRbZG9tTWV0aG9kXSh0b3VjaEV2ZW50cy5tb3ZlLCBzd2lwZXIub25Ub3VjaE1vdmUsIGNhcHR1cmUpO1xuICAgIGRvY3VtZW50W2RvbU1ldGhvZF0odG91Y2hFdmVudHMuZW5kLCBzd2lwZXIub25Ub3VjaEVuZCwgZmFsc2UpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHBhc3NpdmVMaXN0ZW5lciA9IHRvdWNoRXZlbnRzLnN0YXJ0ID09PSAndG91Y2hzdGFydCcgJiYgc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgJiYgcGFyYW1zLnBhc3NpdmVMaXN0ZW5lcnMgPyB7XG4gICAgICBwYXNzaXZlOiB0cnVlLFxuICAgICAgY2FwdHVyZTogZmFsc2VcbiAgICB9IDogZmFsc2U7XG4gICAgZWxbZG9tTWV0aG9kXSh0b3VjaEV2ZW50cy5zdGFydCwgc3dpcGVyLm9uVG91Y2hTdGFydCwgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICBlbFtkb21NZXRob2RdKHRvdWNoRXZlbnRzLm1vdmUsIHN3aXBlci5vblRvdWNoTW92ZSwgc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgPyB7XG4gICAgICBwYXNzaXZlOiBmYWxzZSxcbiAgICAgIGNhcHR1cmVcbiAgICB9IDogY2FwdHVyZSk7XG4gICAgZWxbZG9tTWV0aG9kXSh0b3VjaEV2ZW50cy5lbmQsIHN3aXBlci5vblRvdWNoRW5kLCBwYXNzaXZlTGlzdGVuZXIpO1xuXG4gICAgaWYgKHRvdWNoRXZlbnRzLmNhbmNlbCkge1xuICAgICAgZWxbZG9tTWV0aG9kXSh0b3VjaEV2ZW50cy5jYW5jZWwsIHN3aXBlci5vblRvdWNoRW5kLCBwYXNzaXZlTGlzdGVuZXIpO1xuICAgIH1cbiAgfSAvLyBQcmV2ZW50IExpbmtzIENsaWNrc1xuXG5cbiAgaWYgKHBhcmFtcy5wcmV2ZW50Q2xpY2tzIHx8IHBhcmFtcy5wcmV2ZW50Q2xpY2tzUHJvcGFnYXRpb24pIHtcbiAgICBlbFtkb21NZXRob2RdKCdjbGljaycsIHN3aXBlci5vbkNsaWNrLCB0cnVlKTtcbiAgfVxuXG4gIGlmIChwYXJhbXMuY3NzTW9kZSkge1xuICAgIHdyYXBwZXJFbFtkb21NZXRob2RdKCdzY3JvbGwnLCBzd2lwZXIub25TY3JvbGwpO1xuICB9IC8vIFJlc2l6ZSBoYW5kbGVyXG5cblxuICBpZiAocGFyYW1zLnVwZGF0ZU9uV2luZG93UmVzaXplKSB7XG4gICAgc3dpcGVyW3N3aXBlck1ldGhvZF0oZGV2aWNlLmlvcyB8fCBkZXZpY2UuYW5kcm9pZCA/ICdyZXNpemUgb3JpZW50YXRpb25jaGFuZ2Ugb2JzZXJ2ZXJVcGRhdGUnIDogJ3Jlc2l6ZSBvYnNlcnZlclVwZGF0ZScsIG9uUmVzaXplLCB0cnVlKTtcbiAgfSBlbHNlIHtcbiAgICBzd2lwZXJbc3dpcGVyTWV0aG9kXSgnb2JzZXJ2ZXJVcGRhdGUnLCBvblJlc2l6ZSwgdHJ1ZSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGF0dGFjaEV2ZW50cygpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICBjb25zdCB7XG4gICAgcGFyYW1zLFxuICAgIHN1cHBvcnRcbiAgfSA9IHN3aXBlcjtcbiAgc3dpcGVyLm9uVG91Y2hTdGFydCA9IG9uVG91Y2hTdGFydC5iaW5kKHN3aXBlcik7XG4gIHN3aXBlci5vblRvdWNoTW92ZSA9IG9uVG91Y2hNb3ZlLmJpbmQoc3dpcGVyKTtcbiAgc3dpcGVyLm9uVG91Y2hFbmQgPSBvblRvdWNoRW5kLmJpbmQoc3dpcGVyKTtcblxuICBpZiAocGFyYW1zLmNzc01vZGUpIHtcbiAgICBzd2lwZXIub25TY3JvbGwgPSBvblNjcm9sbC5iaW5kKHN3aXBlcik7XG4gIH1cblxuICBzd2lwZXIub25DbGljayA9IG9uQ2xpY2suYmluZChzd2lwZXIpO1xuXG4gIGlmIChzdXBwb3J0LnRvdWNoICYmICFkdW1teUV2ZW50QXR0YWNoZWQpIHtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgZHVtbXlFdmVudExpc3RlbmVyKTtcbiAgICBkdW1teUV2ZW50QXR0YWNoZWQgPSB0cnVlO1xuICB9XG5cbiAgZXZlbnRzKHN3aXBlciwgJ29uJyk7XG59XG5cbmZ1bmN0aW9uIGRldGFjaEV2ZW50cygpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgZXZlbnRzKHN3aXBlciwgJ29mZicpO1xufVxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGF0dGFjaEV2ZW50cyxcbiAgZGV0YWNoRXZlbnRzXG59OyIsImltcG9ydCB7
1IGV4dGVuZCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscy5qcyc7XG5cbmNvbnN0IGlzR3JpZEVuYWJsZWQgPSAoc3dpcGVyLCBwYXJhbXMpID0+IHtcbiAgcmV0dXJuIHN3aXBlci5ncmlkICYmIHBhcmFtcy5ncmlkICYmIHBhcmFtcy5ncmlkLnJvd3MgPiAxO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc2V0QnJlYWtwb2ludCgpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3Qge1xuICAgIGFjdGl2ZUluZGV4LFxuICAgIGluaXRpYWxpemVkLFxuICAgIGxvb3BlZFNsaWRlcyA9IDAsXG4gICAgcGFyYW1zLFxuICAgICRlbFxuICB9ID0gc3dpcGVyO1xuICBjb25zdCBicmVha3BvaW50cyA9IHBhcmFtcy5icmVha3BvaW50cztcbiAgaWYgKCFicmVha3BvaW50cyB8fCBicmVha3BvaW50cyAmJiBPYmplY3Qua2V5cyhicmVha3BvaW50cykubGVuZ3RoID09PSAwKSByZXR1cm47IC8vIEdldCBicmVha3BvaW50IGZvciB3aW5kb3cgd2lkdGggYW5kIHVwZGF0ZSBwYXJhbWV0ZXJzXG5cbiAgY29uc3QgYnJlYWtwb2ludCA9IHN3aXBlci5nZXRCcmVha3BvaW50KGJyZWFrcG9pbnRzLCBzd2lwZXIucGFyYW1zLmJyZWFrcG9pbnRzQmFzZSwgc3dpcGVyLmVsKTtcbiAgaWYgKCFicmVha3BvaW50IHx8IHN3aXBlci5jdXJyZW50QnJlYWtwb2ludCA9PT0gYnJlYWtwb2ludCkgcmV0dXJuO1xuICBjb25zdCBicmVha3BvaW50T25seVBhcmFtcyA9IGJyZWFrcG9pbnQgaW4gYnJlYWtwb2ludHMgPyBicmVha3BvaW50c1ticmVha3BvaW50XSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgYnJlYWtwb2ludFBhcmFtcyA9IGJyZWFrcG9pbnRPbmx5UGFyYW1zIHx8IHN3aXBlci5vcmlnaW5hbFBhcmFtcztcbiAgY29uc3Qgd2FzTXVsdGlSb3cgPSBpc0dyaWRFbmFibGVkKHN3aXBlciwgcGFyYW1zKTtcbiAgY29uc3QgaXNNdWx0aVJvdyA9IGlzR3JpZEVuYWJsZWQoc3dpcGVyLCBicmVha3BvaW50UGFyYW1zKTtcbiAgY29uc3Qgd2FzRW5hYmxlZCA9IHBhcmFtcy5lbmFibGVkO1xuXG4gIGlmICh3YXNNdWx0aVJvdyAmJiAhaXNNdWx0aVJvdykge1xuICAgICRlbC5yZW1vdmVDbGFzcyhgJHtwYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzc31ncmlkICR7cGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3N9Z3JpZC1jb2x1bW5gKTtcbiAgICBzd2lwZXIuZW1pdENvbnRhaW5lckNsYXNzZXMoKTtcbiAgfSBlbHNlIGlmICghd2FzTXVsdGlSb3cgJiYgaXNNdWx0aVJvdykge1xuICAgICRlbC5hZGRDbGFzcyhgJHtwYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzc31ncmlkYCk7XG5cbiAgICBpZiAoYnJlYWtwb2ludFBhcmFtcy5ncmlkLmZpbGwgJiYgYnJlYWtwb2ludFBhcmFtcy5ncmlkLmZpbGwgPT09ICdjb2x1bW4nIHx8ICFicmVha3BvaW50UGFyYW1zLmdyaWQuZmlsbCAmJiBwYXJhbXMuZ3JpZC5maWxsID09PSAnY29sdW1uJykge1xuICAgICAgJGVsLmFkZENsYXNzKGAke3BhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfWdyaWQtY29sdW1uYCk7XG4gICAgfVxuXG4gICAgc3dpcGVyLmVtaXRDb250YWluZXJDbGFzc2VzKCk7XG4gIH0gLy8gVG9nZ2xlIG5hdmlnYXRpb24sIHBhZ2luYXRpb24sIHNjcm9sbGJhclxuXG5cbiAgWyduYXZpZ2F0aW9uJywgJ3BhZ2luYXRpb24nLCAnc2Nyb2xsYmFyJ10uZm9yRWFjaChwcm9wID0+IHtcbiAgICBjb25zdCB3YXNNb2R1bGVFbmFibGVkID0gcGFyYW1zW3Byb3BdICYmIHBhcmFtc1twcm9wXS5lbmFibGVkO1xuICAgIGNvbnN0IGlzTW9kdWxlRW5hYmxlZCA9IGJyZWFrcG9pbnRQYXJhbXNbcHJvcF0gJiYgYnJlYWtwb2ludFBhcmFtc1twcm9wXS5lbmFibGVkO1xuXG4gICAgaWYgKHdhc01vZHVsZUVuYWJsZWQgJiYgIWlzTW9kdWxlRW5hYmxlZCkge1xuICAgICAgc3dpcGVyW3Byb3BdLmRpc2FibGUoKTtcbiAgICB9XG5cbiAgICBpZiAoIXdhc01vZHVsZUVuYWJsZWQgJiYgaXNNb2R1bGVFbmFibGVkKSB7XG4gICAgICBzd2lwZXJbcHJvcF0uZW5hYmxlKCk7XG4gICAgfVxuICB9KTtcbiAgY29uc3QgZGlyZWN0aW9uQ2hhbmdlZCA9IGJyZWFrcG9pbnRQYXJhbXMuZGlyZWN0aW9uICYmIGJyZWFrcG9pbnRQYXJhbXMuZGlyZWN0aW9uICE9PSBwYXJhbXMuZGlyZWN0aW9uO1xuICBjb25zdCBuZWVkc1JlTG9vcCA9IHBhcmFtcy5sb29wICYmIChicmVha3BvaW50UGFyYW1zLnNsaWRlc1BlclZpZXcgIT09IHBhcmFtcy5zbGlkZXNQZXJWaWV3IHx8IGRpcmVjdGlvbkNoYW5nZWQpO1xuXG4gIGlmIChkaXJlY3Rpb25DaGFuZ2VkICYmIGluaXRpYWxpemVkKSB7XG4gICAgc3dpcGVyLmNoYW5nZURpcmVjdGlvbigpO1xuICB9XG5cbiAgZXh0ZW5kKHN3aXBlci5wYXJhbXMsIGJyZWFrcG9pbnRQYXJhbXMpO1xuICBjb25zdCBpc0VuYWJsZWQgPSBzd2lwZXIucGFyYW1zLmVuYWJsZWQ7XG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLCB7XG4gICAgYWxsb3dUb3VjaE1vdmU6IHN3aXBlci5wYXJhbXMuYWxsb3dUb3VjaE1vdmUsXG4gICAgYWxsb3dTbGlkZU5leHQ6IHN3aXBlci5wYXJhbXMuYWxsb3dTbGlkZU5leHQsXG4gICAgYWxsb3dTbGlkZVByZXY6IHN3aXBlci5wYXJhbXMuYWxsb3dTbGlkZVByZXZcbiAgfSk7XG5cbiAgaWYgKHdhc0VuYWJsZWQgJiYgIWlzRW5hYmxlZCkge1xuICAgIHN3aXBlci5kaXNhYmxlKCk7XG4gIH0gZWxzZSBpZiAoIXdhc0VuYWJsZWQgJiYgaXNFbmFibGVkKSB7XG4gICAgc3dpcGVyLmVuYWJsZSgpO1xuICB9XG5cbiAgc3dpcGVyLmN1cnJlbnRCcmVha3BvaW50ID0gYnJlYWtwb2ludDtcbiAgc3dpcGVyLmVtaXQoJ19iZWZvcmVCcmVha3BvaW50JywgYnJlYWtwb2ludFBhcmFtcyk7XG5cbiAgaWYgKG5lZWRzUmVMb29wICYmIGluaXRpYWxpemVkKSB7XG4gICAgc3dpcGVyLmxvb3BEZXN0cm95KCk7XG4gICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzKCk7XG4gICAgc3dpcGVyLnNsaWRlVG8oYWN0aXZlSW5kZXggLSBsb29wZWRTbGlkZXMgKyBzd2lwZXIubG9vcGVkU2xpZGVzLCAwLCBmYWxzZSk7XG4gIH1cblxuICBzd2lwZXIuZW1pdCgnYnJlYWtwb2ludCcsIGJyZWFrcG9pbnRQYXJhbXMpO1xufSIsImltcG9ydCB7
1IGdldFdpbmRvdyB9IGZyb20gJ3Nzci13aW5kb3cnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0QnJlYWtwb2ludChicmVha3BvaW50cywgYmFzZSA9ICd3aW5kb3cnLCBjb250YWluZXJFbCkge1xuICBpZiAoIWJyZWFrcG9pbnRzIHx8IGJhc2UgPT09ICdjb250YWluZXInICYmICFjb250YWluZXJFbCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgbGV0IGJyZWFrcG9pbnQgPSBmYWxzZTtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gIGNvbnN0IGN1cnJlbnRIZWlnaHQgPSBiYXNlID09PSAnd2luZG93JyA/IHdpbmRvdy5pbm5lckhlaWdodCA6IGNvbnRhaW5lckVsLmNsaWVudEhlaWdodDtcbiAgY29uc3QgcG9pbnRzID0gT2JqZWN0LmtleXMoYnJlYWtwb2ludHMpLm1hcChwb2ludCA9PiB7XG4gICAgaWYgKHR5cGVvZiBwb2ludCA9PT0gJ3N0cmluZycgJiYgcG9pbnQuaW5kZXhPZignQCcpID09PSAwKSB7XG4gICAgICBjb25zdCBtaW5SYXRpbyA9IHBhcnNlRmxvYXQocG9pbnQuc3Vic3RyKDEpKTtcbiAgICAgIGNvbnN0IHZhbHVlID0gY3VycmVudEhlaWdodCAqIG1pblJhdGlvO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIHBvaW50XG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZTogcG9pbnQsXG4gICAgICBwb2ludFxuICAgIH07XG4gIH0pO1xuICBwb2ludHMuc29ydCgoYSwgYikgPT4gcGFyc2VJbnQoYS52YWx1ZSwgMTApIC0gcGFyc2VJbnQoYi52YWx1ZSwgMTApKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGNvbnN0IHtcbiAgICAgIHBvaW50LFxuICAgICAgdmFsdWVcbiAgICB9ID0gcG9pbnRzW2ldO1xuXG4gICAgaWYgKGJhc2UgPT09ICd3aW5kb3cnKSB7XG4gICAgICBpZiAod2luZG93Lm1hdGNoTWVkaWEoYChtaW4td2lkdGg6ICR7dmFsdWV9cHgpYCkubWF0Y2hlcykge1xuICAgICAgICBicmVha3BvaW50ID0gcG9pbnQ7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2YWx1ZSA8PSBjb250YWluZXJFbC5jbGllbnRXaWR0aCkge1xuICAgICAgYnJlYWtwb2ludCA9IHBvaW50O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBicmVha3BvaW50IHx8ICdtYXgnO1xufSIsImltcG9ydCBzZXRCcmVha3BvaW50IGZyb20gJy4vc2V0QnJlYWtwb2ludC5qcyc7XG5pbXBvcnQgZ2V0QnJlYWtwb2ludCBmcm9tICcuL2dldEJyZWFrcG9pbnQuanMnO1xuZXhwb3J0IGRlZmF1bHQge1xuICBzZXRCcmVha3BvaW50LFxuICBnZXRCcmVha3BvaW50XG59OyIsImZ1bmN0aW9uIHByZXBhcmVDbGFzc2VzKGVudHJpZXMsIHByZWZpeCkge1xuICBjb25zdCByZXN1bHRDbGFzc2VzID0gW107XG4gIGVudHJpZXMuZm9yRWFjaChpdGVtID0+IHtcbiAgICBpZiAodHlwZW9mIGl0ZW0gPT09ICdvYmplY3QnKSB7XG4gICAgICBPYmplY3Qua2V5cyhpdGVtKS5mb3JFYWNoKGNsYXNzTmFtZXMgPT4ge1xuICAgICAgICBpZiAoaXRlbVtjbGFzc05hbWVzXSkge1xuICAgICAgICAgIHJlc3VsdENsYXNzZXMucHVzaChwcmVmaXggKyBjbGFzc05hbWVzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJlc3VsdENsYXNzZXMucHVzaChwcmVmaXggKyBpdGVtKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0Q2xhc3Nlcztcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gYWRkQ2xhc3NlcygpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3Qge1xuICAgIGNsYXNzTmFtZXMsXG4gICAgcGFyYW1zLFxuICAgIHJ0bCxcbiAgICAkZWwsXG4gICAgZGV2aWNlLFxuICAgIHN1cHBvcnRcbiAgfSA9IHN3aXBlcjsgLy8gcHJldHRpZXItaWdub3JlXG5cbiAgY29uc3Qgc3VmZml4ZXMgPSBwcmVwYXJlQ2xhc3NlcyhbJ2luaXRpYWxpemVkJywgcGFyYW1zLmRpcmVjdGlvbiwge1xuICAgICdwb2ludGVyLWV2ZW50cyc6ICFzdXBwb3J0LnRvdWNoXG4gIH0sIHtcbiAgICAnZnJlZS1tb2RlJzogc3dpcGVyLnBhcmFtcy5mcmVlTW9kZSAmJiBwYXJhbXMuZnJlZU1vZGUuZW5hYmxlZFxuICB9LCB7XG4gICAgJ2F1dG9oZWlnaHQnOiBwYXJhbXMuYXV0b0hlaWdodFxuICB9LCB7XG4gICAgJ3J0bCc6IHJ0bFxuICB9LCB7XG4gICAgJ2dyaWQnOiBwYXJhbXMuZ3JpZCAmJiBwYXJhbXMuZ3JpZC5yb3dzID4gMVxuICB9LCB7XG4gICAgJ2dyaWQtY29sdW1uJzogcGFyYW1zLmdyaWQgJiYgcGFyYW1zLmdyaWQucm93cyA+IDEgJiYgcGFyYW1zLmdyaWQuZmlsbCA9PT0gJ2NvbHVtbidcbiAgfSwge1xuICAgICdhbmRyb2lkJzogZGV2aWNlLmFuZHJvaWRcbiAgfSwge1xuICAgICdpb3MnOiBkZXZpY2UuaW9zXG4gIH0sIHtcbiAgICAnY3NzLW1vZGUnOiBwYXJhbXMuY3NzTW9kZVxuICB9LCB7XG4gICAgJ2NlbnRlcmVkJzogcGFyYW1zLmNzc01vZGUgJiYgcGFyYW1zLmNlbnRlcmVkU2xpZGVzXG4gIH0sIHtcbiAgICAnd2F0Y2gtcHJvZ3Jlc3MnOiBwYXJhbXMud2F0Y2hTbGlkZXNQcm9ncmVzc1xuICB9XSwgcGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3MpO1xuICBjbGFzc05hbWVzLnB1c2goLi4uc3VmZml4ZXMpO1xuICAkZWwuYWRkQ2xhc3MoWy4uLmNsYXNzTmFtZXNdLmpvaW4oJyAnKSk7XG4gIHN3aXBlci5lbWl0Q29udGFpbmVyQ2xhc3NlcygpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlbW92ZUNsYXNzZXMoKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IHtcbiAgICAkZWwsXG4gICAgY2xhc3NOYW1lc1xuICB9ID0gc3dpcGVyO1xuICAkZWwucmVtb3ZlQ2xhc3MoY2xhc3NOYW1lcy5qb2luKCcgJykpO1xuICBzd2lwZXIuZW1pdENvbnRhaW5lckNsYXNzZXMoKTtcbn0iLCJpbXBvcnQgYWRkQ2xhc3NlcyBmcm9tICcuL2FkZENsYXNzZXMuanMnO1xuaW1wb3J0IHJlbW92ZUNsYXNzZXMgZnJvbSAnLi9yZW1vdmVDbGFzc2VzLmpzJztcbmV4cG9ydCBkZWZhdWx0IHtcbiAgYWRkQ2xhc3NlcyxcbiAgcmVtb3ZlQ2xhc3Nlc1xufTsiLCJpbXBvcnQgeyBnZXRXaW5kb3cgfSBmcm9tICdzc3Itd2luZG93JztcbmltcG9ydCAkIGZyb20gJy4uLy4uL3NoYXJlZC9kb20uanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbG9hZEltYWdlKGltYWdlRWwsIHNyYywgc3Jjc2V0LCBzaXplcywgY2hlY2tGb3JDb21wbGV0ZSwgY2FsbGJhY2spIHtcbiAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gIGxldCBpbWFnZTtcblxuICBmdW5jdGlvbiBvblJlYWR5KCkge1xuICAgIGlmIChjYWxsYmFjaykgY2FsbGJhY2soKTtcbiAgfVxuXG4gIGNvbnN0IGlzUGljdHVyZSA9ICQoaW1hZ2VFbCkucGFyZW50KCdwaWN0dXJlJylbMF07XG5cbiAgaWYgKCFpc1BpY3R1cmUgJiYgKCFpbWFnZUVsLmNvbXBsZXRlIHx8ICFjaGVja0ZvckNvbXBsZXRlKSkge1xuICAgIGlmIChzcmMpIHtcbiAgICAgIGltYWdlID0gbmV3IHdpbmRvdy5JbWFnZSgpO1xuICAgICAgaW1hZ2Uub25sb2FkID0gb25SZWFkeTtcbiAgICAgIGltYWdlLm9uZXJyb3IgPSBvblJlYWR5O1xuXG4gICAgICBpZiAoc2l6ZXMpIHtcbiAgICAgICAgaW1hZ2Uuc2l6ZXMgPSBzaXplcztcbiAgICAgIH1cblxuICAgICAgaWYgKHNyY3NldCkge1xuICAgICAgICBpbWFnZS5zcmNzZXQgPSBzcmNzZXQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChzcmMpIHtcbiAgICAgICAgaW1hZ2Uuc3JjID0gc3JjO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvblJlYWR5KCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIGltYWdlIGFscmVhZHkgbG9hZGVkLi4uXG4gICAgb25SZWFkeSgpO1xuICB9XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcHJlbG9hZEltYWdlcygpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgc3dpcGVyLmltYWdlc1RvTG9hZCA9IHN3aXBlci4kZWwuZmluZCgnaW1nJyk7XG5cbiAgZnVuY3Rpb24gb25SZWFkeSgpIHtcbiAgICBpZiAodHlwZW9mIHN3aXBlciA9PT0gJ3VuZGVmaW5lZCcgfHwgc3dpcGVyID09PSBudWxsIHx8ICFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xuICAgIGlmIChzd2lwZXIuaW1hZ2VzTG9h
1ZGVkICE9PSB1bmRlZmluZWQpIHN3aXBlci5pbWFnZXNMb2FkZWQgKz0gMTtcblxuICAgIGlmIChzd2lwZXIuaW1hZ2VzTG9hZGVkID09PSBzd2lwZXIuaW1hZ2VzVG9Mb2FkLmxlbmd0aCkge1xuICAgICAgaWYgKHN3aXBlci5wYXJhbXMudXBkYXRlT25JbWFnZXNSZWFkeSkgc3dpcGVyLnVwZGF0ZSgpO1xuICAgICAgc3dpcGVyLmVtaXQoJ2ltYWdlc1JlYWR5Jyk7XG4gICAgfVxuICB9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzd2lwZXIuaW1hZ2VzVG9Mb2FkLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgY29uc3QgaW1hZ2VFbCA9IHN3aXBlci5pbWFnZXNUb0xvYWRbaV07XG4gICAgc3dpcGVyLmxvYWRJbWFnZShpbWFnZUVsLCBpbWFnZUVsLmN1cnJlbnRTcmMgfHwgaW1hZ2VFbC5nZXRBdHRyaWJ1dGUoJ3NyYycpLCBpbWFnZUVsLnNyY3NldCB8fCBpbWFnZUVsLmdldEF0dHJpYnV0ZSgnc3Jjc2V0JyksIGltYWdlRWwuc2l6ZXMgfHwgaW1hZ2VFbC5nZXRBdHRyaWJ1dGUoJ3NpemVzJyksIHRydWUsIG9uUmVhZHkpO1xuICB9XG59IiwiaW1wb3J0IGxvYWRJbWFnZSBmcm9tICcuL2xvYWRJbWFnZS5qcyc7XG5pbXBvcnQgcHJlbG9hZEltYWdlcyBmcm9tICcuL3ByZWxvYWRJbWFnZXMuanMnO1xuZXhwb3J0IGRlZmF1bHQge1xuICBsb2FkSW1hZ2UsXG4gIHByZWxvYWRJbWFnZXNcbn07IiwiZnVuY3Rpb24gY2hlY2tPdmVyZmxvdygpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3Qge1xuICAgIGlzTG9ja2VkOiB3YXNMb2NrZWQsXG4gICAgcGFyYW1zXG4gIH0gPSBzd2lwZXI7XG4gIGNvbnN0IHtcbiAgICBzbGlkZXNPZmZzZXRCZWZvcmVcbiAgfSA9IHBhcmFtcztcblxuICBpZiAoc2xpZGVzT2Zmc2V0QmVmb3JlKSB7XG4gICAgY29uc3QgbGFzdFNsaWRlSW5kZXggPSBzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDE7XG4gICAgY29uc3QgbGFzdFNsaWRlUmlnaHRFZGdlID0gc3dpcGVyLnNsaWRlc0dyaWRbbGFzdFNsaWRlSW5kZXhdICsgc3dpcGVyLnNsaWRlc1NpemVzR3JpZFtsYXN0U2xpZGVJbmRleF0gKyBzbGlkZXNPZmZzZXRCZWZvcmUgKiAyO1xuICAgIHN3aXBlci5pc0xvY2tlZCA9IHN3aXBlci5zaXplID4gbGFzdFNsaWRlUmlnaHRFZGdlO1xuICB9IGVsc2Uge1xuICAgIHN3aXBlci5pc0xvY2tlZCA9IHN3aXBlci5zbmFwR3JpZC5sZW5ndGggPT09IDE7XG4gIH1cblxuICBpZiAocGFyYW1zLmFsbG93U2xpZGVOZXh0ID09PSB0cnVlKSB7XG4gICAgc3dpcGVyLmFsbG93U2xpZGVOZXh0ID0gIXN3aXBlci5pc0xvY2tlZDtcbiAgfVxuXG4gIGlmIChwYXJhbXMuYWxsb3dTbGlkZVByZXYgPT09IHRydWUpIHtcbiAgICBzd2lwZXIuYWxsb3dTbGlkZVByZXYgPSAhc3dpcGVyLmlzTG9ja2VkO1xuICB9XG5cbiAgaWYgKHdhc0xvY2tlZCAmJiB3YXNMb2NrZWQgIT09IHN3aXBlci5pc0xvY2tlZCkge1xuICAgIHN3aXBlci5pc0VuZCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKHdhc0xvY2tlZCAhPT0gc3dpcGVyLmlzTG9ja2VkKSB7XG4gICAgc3dpcGVyLmVtaXQoc3dpcGVyLmlzTG9ja2VkID8gJ2xvY2snIDogJ3VubG9jaycpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgY2hlY2tPdmVyZmxvd1xufTsiLCJleHBvcnQgZGVmYXVsdCB7XG4gIGluaXQ6IHRydWUsXG4gIGRpcmVjdGlvbjogJ2hvcml6b250YWwnLFxuICB0b3VjaEV2ZW50c1RhcmdldDogJ3dyYXBwZXInLFxuICBpbml0aWFsU2xpZGU6IDAsXG4gIHNwZWVkOiAzMDAsXG4gIGNzc01vZGU6IGZhbHNlLFxuICB1cGRhdGVPbldpbmRvd1Jlc2l6ZTogdHJ1ZSxcbiAgcmVzaXplT2JzZXJ2ZXI6IHRydWUsXG4gIG5lc3RlZDogZmFsc2UsXG4gIGNyZWF0ZUVsZW1lbnRzOiBmYWxzZSxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgZm9jdXNhYmxlRWxlbWVudHM6ICdpbnB1dCwgc2VsZWN0LCBvcHRpb24sIHRleHRhcmVhLCBidXR0b24sIHZpZGVvLCBsYWJlbCcsXG4gIC8vIE92ZXJyaWRlc1xuICB3aWR0aDogbnVsbCxcbiAgaGVpZ2h0OiBudWxsLFxuICAvL1xuICBwcmV2ZW50SW50ZXJhY3Rpb25PblRyYW5zaXRpb246IGZhbHNlLFxuICAvLyBzc3JcbiAgdXNlckFnZW50OiBudWxsLFxuICB1cmw6IG51bGwsXG4gIC8vIFRvIHN1cHBvcnQgaU9TJ3Mgc3dpcGUtdG8tZ28tYmFjayBnZXN0dXJlICh3aGVuIGJlaW5nIHVzZWQgaW4tYXBwKS5cbiAgZWRnZVN3aXBlRGV0ZWN0aW9uOiBmYWxzZSxcbiAgZWRnZVN3aXBlVGhyZXNob2xkOiAyMCxcbiAgLy8gQXV0b2hlaWdodFxuICBhdXRvSGVpZ2h0OiBmYWxzZSxcbiAgLy8gU2V0IHdyYXBwZXIgd2lkdGhcbiAgc2V0V3JhcHBlclNpemU6IGZhbHNlLFxuICAvLyBWaXJ0dWFsIFRyYW5zbGF0ZVxuICB2aXJ0dWFsVHJhbnNsYXRlOiBmYWxzZSxcbiAgLy8gRWZmZWN0c1xuICBlZmZlY3Q6ICdzbGlkZScsXG4gIC8vICdzbGlkZScgb3IgJ2ZhZGUnIG9yICdjdWJlJyBvciAnY292ZXJmbG93JyBvciAnZmxpcCdcbiAgLy8gQnJlYWtwb2ludHNcbiAgYnJlYWtwb2ludHM6IHVuZGVmaW5lZCxcbiAgYnJlYWtwb2ludHNCYXNlOiAnd2luZG93JyxcbiAgLy8gU2xpZGVzIGdyaWRcbiAgc3BhY2VCZXR3ZWVuOiAwLFxuICBzbGlkZXNQZXJWaWV3OiAxLFxuICBzbGlkZXNQZXJHcm91cDogMSxcbiAgc2xpZGVzUGVyR3JvdXBTa2lwOiAwLFxuICBzbGlkZXNQZXJHcm91cEF1dG86IGZhbHNlLFxuICBjZW50ZXJlZFNsaWRlczogZmFsc2UsXG4gIGNlbnRlcmVkU2xpZGVzQm91bmRzOiBmYWxzZSxcbiAgc2xpZGVzT2Zmc2V0QmVmb3JlOiAwLFxuICAvLyBpbiBweFxuICBzbGlkZXNPZmZzZXRBZnRlcjogMCxcbiAgLy8gaW4gcHhcbiAgbm9ybWFsaXplU2xpZGVJbmRleDogdHJ1ZSxcbiAgY2VudGVySW5zdWZmaWNpZW50U2xpZGVzOiBmYWxzZSxcbiAgLy8gRGlzYWJsZSBzd2lwZXIgYW5kIGhpZGUgbmF2aWdhdGlvbiB3aGVuIGNvbnRhaW5lciBub3Qgb3ZlcmZsb3dcbiAgd2F0Y2hPdmVyZmxvdzogdHJ1ZSxcbiAgLy8gUm91bmQgbGVuZ3RoXG4gIHJvdW5kTGVuZ3RoczogZmFsc2UsXG4gIC8vIFRvdWNoZXNcbiAgdG91Y2hSYXRpbzogMSxcbiAgdG91Y2hBbmdsZTogNDUsXG4gIHNpbXVsYXRlVG91Y2g6IHRydWUsXG4gIHNob3J0U3dpcGVzOiB0cnVlLFxuICBsb25nU3dpcGVzOiB0cnVlLFxuICBsb25nU3dpcGVzUmF0aW86IDAuNSxcbiAgbG9uZ1N3aXBlc01zOiAzMDAsXG4gIGZvbGxvd0ZpbmdlcjogdHJ1ZSxcbiAgYWxsb3dUb3VjaE1vdmU6IHRydWUsXG4gIHRocmVzaG9sZDogMCxcbiAgdG91Y2hNb3ZlU3RvcFByb3BhZ2F0aW9uOiBmYWxzZSxcbiAgdG91Y2hTdGFydFByZXZlbn
1REZWZhdWx0OiB0cnVlLFxuICB0b3VjaFN0YXJ0Rm9yY2VQcmV2ZW50RGVmYXVsdDogZmFsc2UsXG4gIHRvdWNoUmVsZWFzZU9uRWRnZXM6IGZhbHNlLFxuICAvLyBVbmlxdWUgTmF2aWdhdGlvbiBFbGVtZW50c1xuICB1bmlxdWVOYXZFbGVtZW50czogdHJ1ZSxcbiAgLy8gUmVzaXN0YW5jZVxuICByZXNpc3RhbmNlOiB0cnVlLFxuICByZXNpc3RhbmNlUmF0aW86IDAuODUsXG4gIC8vIFByb2dyZXNzXG4gIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IGZhbHNlLFxuICAvLyBDdXJzb3JcbiAgZ3JhYkN1cnNvcjogZmFsc2UsXG4gIC8vIENsaWNrc1xuICBwcmV2ZW50Q2xpY2tzOiB0cnVlLFxuICBwcmV2ZW50Q2xpY2tzUHJvcGFnYXRpb246IHRydWUsXG4gIHNsaWRlVG9DbGlja2VkU2xpZGU6IGZhbHNlLFxuICAvLyBJbWFnZXNcbiAgcHJlbG9hZEltYWdlczogdHJ1ZSxcbiAgdXBkYXRlT25JbWFnZXNSZWFkeTogdHJ1ZSxcbiAgLy8gbG9vcFxuICBsb29wOiBmYWxzZSxcbiAgbG9vcEFkZGl0aW9uYWxTbGlkZXM6IDAsXG4gIGxvb3BlZFNsaWRlczogbnVsbCxcbiAgbG9vcGVkU2xpZGVzTGltaXQ6IHRydWUsXG4gIGxvb3BGaWxsR3JvdXBXaXRoQmxhbms6IGZhbHNlLFxuICBsb29wUHJldmVudHNTbGlkZTogdHJ1ZSxcbiAgLy8gcmV3aW5kXG4gIHJld2luZDogZmFsc2UsXG4gIC8vIFN3aXBpbmcvbm8gc3dpcGluZ1xuICBhbGxvd1NsaWRlUHJldjogdHJ1ZSxcbiAgYWxsb3dTbGlkZU5leHQ6IHRydWUsXG4gIHN3aXBlSGFuZGxlcjogbnVsbCxcbiAgLy8gJy5zd2lwZS1oYW5kbGVyJyxcbiAgbm9Td2lwaW5nOiB0cnVlLFxuICBub1N3aXBpbmdDbGFzczogJ3N3aXBlci1uby1zd2lwaW5nJyxcbiAgbm9Td2lwaW5nU2VsZWN0b3I6IG51bGwsXG4gIC8vIFBhc3NpdmUgTGlzdGVuZXJzXG4gIHBhc3NpdmVMaXN0ZW5lcnM6IHRydWUsXG4gIG1heEJhY2tmYWNlSGlkZGVuU2xpZGVzOiAxMCxcbiAgLy8gTlNcbiAgY29udGFpbmVyTW9kaWZpZXJDbGFzczogJ3N3aXBlci0nLFxuICAvLyBORVdcbiAgc2xpZGVDbGFzczogJ3N3aXBlci1zbGlkZScsXG4gIHNsaWRlQmxhbmtDbGFzczogJ3N3aXBlci1zbGlkZS1pbnZpc2libGUtYmxhbmsnLFxuICBzbGlkZUFjdGl2ZUNsYXNzOiAnc3dpcGVyLXNsaWRlLWFjdGl2ZScsXG4gIHNsaWRlRHVwbGljYXRlQWN0aXZlQ2xhc3M6ICdzd2lwZXItc2xpZGUtZHVwbGljYXRlLWFjdGl2ZScsXG4gIHNsaWRlVmlzaWJsZUNsYXNzOiAnc3dpcGVyLXNsaWRlLXZpc2libGUnLFxuICBzbGlkZUR1cGxpY2F0ZUNsYXNzOiAnc3dpcGVyLXNsaWRlLWR1cGxpY2F0ZScsXG4gIHNsaWRlTmV4dENsYXNzOiAnc3dpcGVyLXNsaWRlLW5leHQnLFxuICBzbGlkZUR1cGxpY2F0ZU5leHRDbGFzczogJ3N3aXBlci1zbGlkZS1kdXBsaWNhdGUtbmV4dCcsXG4gIHNsaWRlUHJldkNsYXNzOiAnc3dpcGVyLXNsaWRlLXByZXYnLFxuICBzbGlkZUR1cGxpY2F0ZVByZXZDbGFzczogJ3N3aXBlci1zbGlkZS1kdXBsaWNhdGUtcHJldicsXG4gIHdyYXBwZXJDbGFzczogJ3N3aXBlci13cmFwcGVyJyxcbiAgLy8gQ2FsbGJhY2tzXG4gI
1HJ1bkNhbGxiYWNrc09uSW5pdDogdHJ1ZSxcbiAgLy8gSW50ZXJuYWxzXG4gIF9lbWl0Q2xhc3NlczogZmFsc2Vcbn07IiwiaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSAnLi4vc2hhcmVkL3V0aWxzLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG1vZHVsZUV4dGVuZFBhcmFtcyhwYXJhbXMsIGFsbE1vZHVsZXNQYXJhbXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGV4dGVuZFBhcmFtcyhvYmogPSB7fSkge1xuICAgIGNvbnN0IG1vZHVsZVBhcmFtTmFtZSA9IE9iamVjdC5rZXlzKG9iailbMF07XG4gICAgY29uc3QgbW9kdWxlUGFyYW1zID0gb2JqW21vZHVsZVBhcmFtTmFtZV07XG5cbiAgICBpZiAodHlwZW9mIG1vZHVsZVBhcmFtcyAhPT0gJ29iamVjdCcgfHwgbW9kdWxlUGFyYW1zID09PSBudWxsKSB7XG4gICAgICBleHRlbmQoYWxsTW9kdWxlc1BhcmFtcywgb2JqKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoWyduYXZpZ2F0aW9uJywgJ3BhZ2luYXRpb24nLCAnc2Nyb2xsYmFyJ10uaW5kZXhPZihtb2R1bGVQYXJhbU5hbWUpID49IDAgJiYgcGFyYW1zW21vZHVsZVBhcmFtTmFtZV0gPT09IHRydWUpIHtcbiAgICAgIHBhcmFtc1ttb2R1bGVQYXJhbU5hbWVdID0ge1xuICAgICAgICBhdXRvOiB0cnVlXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICghKG1vZHVsZVBhcmFtTmFtZSBpbiBwYXJhbXMgJiYgJ2VuYWJsZWQnIGluIG1vZHVsZVBhcmFtcykpIHtcbiAgICAgIGV4dGVuZChhbGxNb2R1bGVzUGFyYW1zLCBvYmopO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXSA9PT0gdHJ1ZSkge1xuICAgICAgcGFyYW1zW21vZHVsZVBhcmFtTmFtZV0gPSB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWVcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXSA9PT0gJ29iamVjdCcgJiYgISgnZW5hYmxlZCcgaW4gcGFyYW1zW21vZHVsZVBhcmFtTmFtZV0pKSB7XG4gICAgICBwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXS5lbmFibGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtc1ttb2R1bGVQYXJhbU5hbWVdKSBwYXJhbXNbbW9kdWxlUGFyYW1OYW1lXSA9IHtcbiAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgfTtcbiAgICBleHRlbmQoYWxsTW9kdWxlc1BhcmFtcywgb2JqKTtcbiAgfTtcbn0iLCIvKiBlc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246IFwib2ZmXCIgKi9cbmltcG9ydCB7IGdldERvY3VtZW50IH0gZnJvbSAnc3NyLXdpbmRvdyc7XG5pbXBvcnQgJCBmcm9tICcuLi9zaGFyZWQvZG9tLmpzJztcbmltcG9ydCB7IGV4dGVuZCwgbm93LCBkZWxldGVQcm9wcyB9IGZyb20gJy4uL3NoYXJlZC91dGlscy5qcyc7XG5pbXBvcnQgeyBnZXRTdXBwb3J0IH0gZnJvbSAnLi4vc2hhcmVkL2dldC1zdXBwb3J0LmpzJztcbmltcG9ydCB7IGdldERldmljZSB9IGZyb20gJy4uL3NoYXJlZC9nZXQtZGV2aWNlLmpzJztcbmltcG9ydCB7IGdldEJyb3dzZXIgfSBmcm9tICcuLi9zaGFyZWQvZ2V0LWJyb3dzZXIuanMnO1xuaW1wb3J0IFJlc2l6ZSBmcm9tICcuL21vZHVsZXMvcmVzaXplL3Jlc2l6ZS5qcyc7XG5pbXBvcnQgT2JzZXJ2ZXIgZnJvbSAnLi9tb2R1bGVzL29ic2VydmVyL29ic2VydmVyLmpzJztcbmltcG9ydCBldmVudHNFbWl0dGVyIGZyb20gJy4vZXZlbnRzLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHVwZGF0ZSBmcm9tICcuL3VwZGF0ZS9pbmRleC5qcyc7XG5pbXBvcnQgdHJhbnNsYXRlIGZyb20gJy4vdHJhbnNsYXRlL2luZGV4LmpzJztcbmltcG9ydCB0cmFuc2l0aW9uIGZyb20gJy4vdHJhbnNpdGlvbi9pbmRleC5qcyc7XG5pbXBvcnQgc2xpZGUgZnJvbSAnLi9zbGlkZS9pbmRleC5qcyc7XG5pbXBvcnQgbG9vcCBmcm9tICcuL2xvb3AvaW5kZXguanMnO1xuaW1wb3J0IGdyYWJDdXJzb3IgZnJvbSAnLi9ncmFiLWN1cnNvci9pbmRleC5qcyc7XG5pbXBvcnQgZXZlbnRzIGZyb20gJy4vZXZlbnRzL2luZGV4LmpzJztcbmltcG9ydCBicmVha3BvaW50cyBmcm9tICcuL2JyZWFrcG9pbnRzL2luZGV4LmpzJztcbmltcG9ydCBjbGFzc2VzIGZyb20gJy4vY2xhc3Nlcy9pbmRleC5qcyc7XG5pbXBvcnQgaW1hZ2VzIGZyb20gJy4vaW1hZ2VzL2luZGV4LmpzJztcbmltcG9ydCBjaGVja092ZXJmbG93IGZyb20gJy4vY2hlY2stb3ZlcmZsb3cvaW5kZXguanMnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4vZGVmYXVsdHMuanMnO1xuaW1wb3J0IG1vZHVsZUV4dGVuZFBhcmFtcyBmcm9tICcuL21vZHVsZUV4dGVuZFBhcmFtcy5qcyc7XG5jb25zdCBwcm90b3R5cGVzID0ge1xuICBldmVudHNFbWl0dGVyLFxuICB1cGRhdGUsXG4gIHRyYW5zbGF0ZSxcbiAgdHJhbnNpdGlvbixcbiAgc2xpZGUsXG4gIGxvb3AsXG4gIGdyYWJDdXJzb3IsXG4gIGV2ZW50cyxcbiAgYnJlYWtwb2ludHMsXG4gIGNoZWNrT3ZlcmZsb3csXG4gIGNsYXNzZXMsXG4gIGltYWdlc1xufTtcbmNvbnN0IGV4dGVuZGVkRGVmYXVsdHMgPSB7fTtcblxuY2xhc3MgU3dpcGVyIHtcbiAgY29uc3RydWN0b3IoLi4uYXJncykge1xuICAgIGxldCBlbDtcbiAgICBsZXQgcGFyYW1zO1xuXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAxICYmIGFyZ3NbMF0uY29uc3RydWN0b3IgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZ3NbMF0pLnNsaWNlKDgsIC0xKSA9PT0gJ09iamVjdCcpIHtcbiAgICAgIHBhcmFtcyA9IGFyZ3NbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIFtlbCwgcGFyYW1zXSA9IGFyZ3M7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMpIHBhcmFtcyA9IHt9O1xuICAgIHBhcmFtcyA9IGV4dGVuZCh7fSwgcGFyYW1zKTtcbiAgICBpZiAoZWwgJiYgIXBhcmFtcy5lbCkgcGFyYW1zLmVsID0gZWw7XG5cbiAgICBpZiAocGFyYW1zLmVsICYmICQocGFyYW1zLmVsKS5sZW5ndGggPiAxKSB7XG4gICAgICBjb25zdCBzd2lwZXJzID0gW107XG4gICAgICAkKHBhcmFtcy5lbCkuZWFjaChjb250YWluZXJFbCA9PiB7XG4gICAgICAgIGNvbnN0IG5ld1BhcmFtcyA9IGV4dGVuZCh7fSwgcGFyYW1zLCB7XG4gICAgICAgICAgZWw6IGNvbnRhaW5lckVsXG4gICAgICAgI
1H0pO1xuICAgICAgICBzd2lwZXJzLnB1c2gobmV3IFN3aXBlcihuZXdQYXJhbXMpKTtcbiAgICAgIH0pOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc3RydWN0b3ItcmV0dXJuXG5cbiAgICAgIHJldHVybiBzd2lwZXJzO1xuICAgIH0gLy8gU3dpcGVyIEluc3RhbmNlXG5cblxuICAgIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gICAgc3dpcGVyLl9fc3dpcGVyX18gPSB0cnVlO1xuICAgIHN3aXBlci5zdXBwb3J0ID0gZ2V0U3VwcG9ydCgpO1xuICAgIHN3aXBlci5kZXZpY2UgPSBnZXREZXZpY2Uoe1xuICAgICAgdXNlckFnZW50OiBwYXJhbXMudXNlckFnZW50XG4gICAgfSk7XG4gICAgc3dpcGVyLmJyb3dzZXIgPSBnZXRCcm93c2VyKCk7XG4gICAgc3dpcGVyLmV2ZW50c0xpc3RlbmVycyA9IHt9O1xuICAgIHN3aXBlci5ldmVudHNBbnlMaXN0ZW5lcnMgPSBbXTtcbiAgICBzd2lwZXIubW9kdWxlcyA9IFsuLi5zd2lwZXIuX19tb2R1bGVzX19dO1xuXG4gICAgaWYgKHBhcmFtcy5tb2R1bGVzICYmIEFycmF5LmlzQXJyYXkocGFyYW1zLm1vZHVsZXMpKSB7XG4gICAgICBzd2lwZXIubW9kdWxlcy5wdXNoKC4uLnBhcmFtcy5tb2R1bGVzKTtcbiAgICB9XG5cbiAgICBjb25zdCBhbGxNb2R1bGVzUGFyYW1zID0ge307XG4gICAgc3dpcGVyLm1vZHVsZXMuZm9yRWFjaChtb2QgPT4ge1xuICAgICAgbW9kKHtcbiAgICAgICAgc3dpcGVyLFxuICAgICAgICBleHRlbmRQYXJhbXM6IG1vZHVsZUV4dGVuZFBhcmFtcyhwYXJhbXMsIGFsbE1vZHVsZXNQYXJhbXMpLFxuICAgICAgICBvbjogc3dpcGVyLm9uLmJpbmQoc3dpcGVyKSxcbiAgICAgICAgb25jZTogc3dpcGVyLm9uY2UuYmluZChzd2lwZXIpLFxuICAgICAgICBvZmY6IHN3aXBlci5vZmYuYmluZChzd2lwZXIpLFxuICAgICAgICBlbWl0OiBzd2lwZXIuZW1pdC5iaW5kKHN3aXBlcilcbiAgICAgIH0pO1xuICAgIH0pOyAvLyBFeHRlbmQgZGVmYXVsdHMgd2l0aCBtb2R1bGVzIHBhcmFtc1xuXG4gICAgY29uc3Qgc3dpcGVyUGFyYW1zID0gZXh0ZW5kKHt9LCBkZWZhdWx0cywgYWxsTW9kdWxlc1BhcmFtcyk7IC8vIEV4dGVuZCBkZWZhdWx0cyB3aXRoIHBhc3NlZCBwYXJhbXNcblxuICAgIHN3aXBlci5wYXJhbXMgPSBleHRlbmQoe30sIHN3aXBlclBhcmFtcywgZXh0ZW5kZWREZWZhdWx0cywgcGFyYW1zKTtcbiAgICBzd2lwZXIub3JpZ2luYWxQYXJhbXMgPSBleHRlbmQoe30sIHN3aXBlci5wYXJhbXMpO1xuICAgIHN3aXBlci5wYXNzZWRQYXJhbXMgPSBleHRlbmQoe30sIHBhcmFtcyk7IC8vIGFkZCBldmVudCBsaXN0ZW5lcnNcblxuICAgIGlmIChzd2lwZXIucGFyYW1zICYmIHN3aXBlci5wYXJhbXMub24pIHtcbiAgICAgIE9iamVjdC5rZXlzKHN3aXBlci5wYXJhbXMub24pLmZvckVhY2goZXZlbnROYW1lID0+IHtcbiAgICAgICAgc3dpcGVyLm9uKGV2ZW50TmFtZSwgc3dpcGVyLnBhcmFtcy5vbltldmVudE5hbWVdKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChzd2lwZXIucGFyYW1zICYmIHN3aXBlci5wYXJhbXMub25BbnkpIHtcbiAgICAgIHN3aXBlci5vbkFueShzd2lwZXIucGFyYW1zLm9uQW55KTtcbiAgICB9IC8vIFNhdmUgRG9tIGxpYlxuXG5cbiAgICBzd2lwZXIuJCA9ICQ7IC8vIEV4dGVuZCBTd2lwZXJcblxuICAgIE9iamVjdC5hc3NpZ24oc3dpcGVyLCB7XG4gICAgICBlbmFibGVkOiBzd2lwZXIucGFyYW1zLmVuYWJsZWQsXG4gICAgICBlbCxcbiAgICAgIC8vIENsYXNzZXNcbiAgICAgIGNsYXNzTmFtZXM6IFtdLFxuICAgICAgLy8gU2xpZGVzXG4gICAgICBzbGlkZXM6ICQoKSxcbiAgICAgIHNsaWRlc0dyaWQ6IFtdLFxuICAgICAgc25hcEdyaWQ6IFtdLFxuICAgICAgc2xpZGVzU2l6ZXNHcmlkOiBbXSxcblxuICAgICAgLy8gaXNEaXJlY3Rpb25cbiAgICAgIGlzSG9yaXpvbnRhbCgpIHtcbiAgICAgICAgcmV0dXJuIHN3aXBlci5wYXJhbXMuZGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCc7XG4gICAgICB9LFxuXG4gICAgICBpc1ZlcnRpY2FsKCkge1xuICAgICAgICByZXR1cm4gc3dpcGVyLnBhcmFtcy5kaXJlY3Rpb24gPT09ICd2ZXJ0aWNhbCc7XG4gICAgICB9LFxuXG4gICAgICAvLyBJbmRleGVzXG4gICAgICBhY3RpdmVJbmRleDogMCxcbiAgICAgIHJlYWxJbmRleDogMCxcbiAgICAgIC8vXG4gICAgICBpc0JlZ2lubmluZzogdHJ1ZSxcbiAgICAgIGlzRW5kOiBmYWxzZSxcbiAgICAgIC8vIFByb3BzXG4gICAgICB0cmFuc2xhdGU6IDAsXG4gICAgICBwcmV2aW91c1RyYW5zbGF0ZTogMCxcbiAgICAgIHByb2dyZXNzOiAwLFxuICAgICAgdmVsb2NpdHk6IDAsXG4gICAgICBhbmltYXRpbmc6IGZhbHNlLFxuICAgICAgLy8gTG9ja3NcbiAgICAgIGFsbG93U2xpZGVOZXh0OiBzd2lwZXIucGFyYW1zLmFsbG93U2xpZGVOZXh0LFxuICAgICAgYWxsb3dTbGlkZVByZXY6IHN3aXBlci5wYXJhbXMuYWxsb3dTbGlkZVByZXYsXG4gICAgICAvLyBUb3VjaCBFdmVudHNcbiAgICAgIHRvdWNoRXZlbnRzOiBmdW5jdGlvbiB0b3VjaEV2ZW50cygpIHtcbiAgICAgICAgY29uc3QgdG91Y2ggPSBbJ3RvdWNoc3RhcnQnLCAndG91Y2htb3ZlJywgJ3RvdWNoZW5kJywgJ3RvdWNoY2FuY2VsJ107XG4gICAgICAgIGNvbnN0IGRlc2t0b3AgPSBbJ3BvaW50ZXJkb3duJywgJ3BvaW50ZXJtb3ZlJywgJ3BvaW50ZXJ1cCddO1xuICAgICAgICBzd2lwZXIudG91Y2hFdmVudHNUb3VjaCA9IHtcbiAgICAgICAgICBzdGFydDogdG91Y2hbMF0sXG4gICAgICAgICAgbW92ZTogdG91Y2hbMV0sXG4gICAgICAgICAgZW5kOiB0b3VjaFsyXSxcbiAgICAgICAgICBjYW5jZWw6IHRvdWNoWzNdXG4gICAgICAgIH07XG4gICAgICAgIHN3aXBlci50b3VjaEV2ZW50c0Rlc2t0b3AgPSB7XG4gICAgICAgICAgc3RhcnQ6IGRlc2t0b3BbMF0sXG4gICAgICAgICAgbW92ZTogZGVza3RvcFsxXSxcbiAgICAgICAgICBlbmQ6IGRlc2t0b3BbMl1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHN3aXBlci5zdXBwb3J0LnRvdWNoIHx8ICFzd2lwZXIucGFyYW1zLnNpbXVsYXRlVG91Y2ggPyBzd2lwZXIudG91Y2hFdmVudHNUb3VjaCA6IHN3aXBlci50b3VjaEV2ZW50c0Rlc2t0b3A7XG4gICAgICB9KCksXG4gICAgICB0b3VjaEV2ZW50c0RhdGE6IHtcbiAgICAgICAgaXNUb3VjaGVkOiB1bmRlZmluZWQsXG4gICAgICAgIGlzTW92ZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgYWxsb3dUb3VjaENhbGxiYWNrczogdW5kZWZpbmVkLFxuICAgICAgICB0b3VjaFN0YXJ0VGltZTogdW5kZWZpbmVkLFxuICAgICAgICBpc1Njcm9sbGluZzogdW5kZWZpbmVkLFxuICAgICAgICBjdXJyZW50VHJhbnNsYXRlOiB1bmRlZmluZWQsXG4gICAgICAgI
1HN0YXJ0VHJhbnNsYXRlOiB1bmRlZmluZWQsXG4gICAgICAgIGFsbG93VGhyZXNob2xkTW92ZTogdW5kZWZpbmVkLFxuICAgICAgICAvLyBGb3JtIGVsZW1lbnRzIHRvIG1hdGNoXG4gICAgICAgIGZvY3VzYWJsZUVsZW1lbnRzOiBzd2lwZXIucGFyYW1zLmZvY3VzYWJsZUVsZW1lbnRzLFxuICAgICAgICAvLyBMYXN0IGNsaWNrIHRpbWVcbiAgICAgICAgbGFzdENsaWNrVGltZTogbm93KCksXG4gICAgICAgIGNsaWNrVGltZW91dDogdW5kZWZpbmVkLFxuICAgICAgICAvLyBWZWxvY2l0aWVzXG4gICAgICAgIHZlbG9jaXRpZXM6IFtdLFxuICAgICAgICBhbGxvd01vbWVudHVtQm91bmNlOiB1bmRlZmluZWQsXG4gICAgICAgIGlzVG91Y2hFdmVudDogdW5kZWZpbmVkLFxuICAgICAgICBzdGFydE1vdmluZzogdW5kZWZpbmVkXG4gICAgICB9LFxuICAgICAgLy8gQ2xpY2tzXG4gICAgICBhbGxvd0NsaWNrOiB0cnVlLFxuICAgICAgLy8gVG91Y2hlc1xuICAgICAgYWxsb3dUb3VjaE1vdmU6IHN3aXBlci5wYXJhbXMuYWxsb3dUb3VjaE1vdmUsXG4gICAgICB0b3VjaGVzOiB7XG4gICAgICAgIHN0YXJ0WDogMCxcbiAgICAgICAgc3RhcnRZOiAwLFxuICAgICAgICBjdXJyZW50WDogMCxcbiAgICAgICAgY3VycmVudFk6IDAsXG4gICAgICAgIGRpZmY6IDBcbiAgICAgIH0sXG4gICAgICAvLyBJbWFnZXNcbiAgICAgIGltYWdlc1RvTG9hZDogW10sXG4gICAgICBpbWFnZXNMb2FkZWQ6IDBcbiAgICB9KTtcbiAgICBzd2lwZXIuZW1pdCgnX3N3aXBlcicpOyAvLyBJbml0XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5pbml0KSB7XG4gICAgICBzd2lwZXIuaW5pdCgpO1xuICAgIH0gLy8gUmV0dXJuIGFwcCBpbnN0YW5jZVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zdHJ1Y3Rvci1yZXR1cm5cblxuXG4gICAgcmV0dXJuIHN3aXBlcjtcbiAgfVxuXG4gIGVuYWJsZSgpIHtcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICAgIGlmIChzd2lwZXIuZW5hYmxlZCkgcmV0dXJuO1xuICAgIHN3aXBlci5lbmFibGVkID0gdHJ1ZTtcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmdyYWJDdXJzb3IpIHtcbiAgICAgIHN3aXBlci5zZXRHcmFiQ3Vyc29yKCk7XG4gICAgfVxuXG4gICAgc3dpcGVyLmVtaXQoJ2VuYWJsZScpO1xuICB9XG5cbiAgZGlzYWJsZSgpIHtcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICAgIGlmICghc3dpcGVyLmVuYWJsZWQpIHJldHVybjtcbiAgICBzd2lwZXIuZW5hYmxlZCA9IGZhbHNlO1xuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuZ3JhYkN1cnNvcikge1xuICAgICAgc3dpcGVyLnVuc2V0R3JhYkN1cnNvcigpO1xuICAgIH1cblxuICAgIHN3aXBlci5lbWl0KCdkaXNhYmxlJyk7XG4gIH1cblxuICBzZXRQcm9ncmVzcyhwcm9ncmVzcywgc3BlZWQpIHtcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICAgIHByb2dyZXNzID0gTWF0aC5taW4oTWF0aC5tYXgocHJvZ3Jlc3MsIDApLCAxKTtcbiAgICBjb25zdCBtaW4gPSBzd2lwZXIubWluVHJhbnNsYXRlKCk7XG4gICAgY29uc3QgbWF4ID0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSAobWF4IC0gbWluKSAqIHByb2dyZXNzICsgbWluO1xuICAgIHN3aXBlci50cmFuc2xhdGVUbyhjdXJyZW50LCB0eXBlb2Ygc3BlZWQgPT09ICd1bmRlZmluZWQnID8gMCA6IHNwZWVkKTtcbiAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xuICB9XG5cbiAgZW1pdENvbnRhaW5lckNsYXNzZXMoKSB7XG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuX2VtaXRDbGFzc2VzIHx8ICFzd2lwZXIuZWwpIHJldHVybjtcbiAgICBjb25zdCBjbHMgPSBzd2lwZXIuZWwuY2xhc3NOYW1lLnNwbGl0KCcgJykuZmlsdGVyKGNsYXNzTmFtZSA9PiB7XG4gICAgICByZXR1cm4gY2xhc3NOYW1lLmluZGV4T2YoJ3N3aXBlcicpID09PSAwIHx8IGNsYXNzTmFtZS5pbmRleE9mKHN3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzcykgPT09IDA7XG4gICAgfSk7XG4gICAgc3dpcGVyLmVtaXQoJ19jb250YWluZXJDbGFzc2VzJywgY2xzLmpvaW4oJyAnKSk7XG4gIH1cblxuICBnZXRTbGlkZUNsYXNzZXMoc2xpZGVFbCkge1xuICAgIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gICAgaWYgKHN3aXBlci5kZXN0cm95ZWQpIHJldHVybiAnJztcbiAgICByZXR1cm4gc2xpZGVFbC5jbGFzc05hbWUuc3BsaXQoJyAnKS5maWx0ZXIoY2xhc3NOYW1lID0+IHtcbiAgICAgIHJldHVybiBjbGFzc05hbWUuaW5kZXhPZignc3dpcGVyLXNsaWRlJykgPT09IDAgfHwgY2xhc3NOYW1lLmluZGV4T2Yoc3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzKSA9PT0gMDtcbiAgICB9KS5qb2luKCcgJyk7XG4gIH1cblxuICBlbWl0U2xpZGVzQ2xhc3NlcygpIHtcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICAgIGlmICghc3dpcGVyLnBhcmFtcy5fZW1pdENsYXNzZXMgfHwgIXN3aXBlci5lbCkgcmV0dXJuO1xuICAgIGNvbnN0IHVwZGF0ZXMgPSBbXTtcbiAgICBzd2lwZXIuc2xpZGVzLmVhY2goc2xpZGVFbCA9PiB7XG4gICAgICBjb25zdCBjbGFzc05hbWVzID0gc3dpcGVyLmdldFNsaWRlQ2xhc3NlcyhzbGlkZUVsKTtcbiAgICAgIHVwZGF0ZXMucHVzaCh7XG4gICAgICAgIHNsaWRlRWwsXG4gICAgICAgIGNsYXNzTmFtZXNcbiAgICAgIH0pO1xuICAgICAgc3dpcGVyLmVtaXQoJ19zbGlkZUNsYXNzJywgc2xpZGVFbCwgY2xhc3NOYW1lcyk7XG4gICAgfSk7XG4gICAgc3dpcGVyLmVtaXQoJ19zbGlkZUNsYXNzZXMnLCB1cGRhdGVzKTtcbiAgfVxuXG4gIHNsaWRlc1BlclZpZXdEeW5hbWljKHZpZXcgPSAnY3VycmVudCcsIGV4YWN0ID0gZmFsc2UpIHtcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICAgIGNvbnN0IHtcbiAgICAgIHBhcmFtcyxcbiAgICAgIHNsaWRlcyxcbiAgICAgIHNsaWRlc0dyaWQsXG4gICAgICBzbGlkZXNTaXplc0dyaWQsXG4gICAgICBzaXplOiBzd2lwZXJTaXplLFxuICAgICAgYWN0aXZlSW5kZXhcbiAgICB9ID0gc3dpcGVyO1xuICAgIGxldCBzcHYgPSAxO1xuXG4gICAgaWYgKHBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xuICAgICAgbGV0IHNsaWRlU2l6ZSA9IHNsaWRlc1thY3RpdmVJbmRleF0uc3dpcGVyU2xpZGVTaXplO1xuICAgICAgbGV0IGJyZWFrTG9vcDtcblxuICAgICAgZm9yIChsZXQgaSA9IGFjdGl2ZUluZGV4ICsgMTsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAoc2xpZGVzW2ldICYmICFicmVha0xvb3ApIHtcbiAgICAgICAgICBzbGlkZVNpemUgKz0gc2xpZGVzW2ldLnN3aXBlclNsaWRlU2l6ZTtcbiAgICAgICAgICBzcHYgKz0gMTtcbiAgICAgICAgICBpZiAoc2xpZGVTaXplID4gc3dpcGVyU2l6ZSkgYnJlYWtMb29wID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gYWN0aXZlSW5kZXggLSAxOyBpID49IDA7IGkgLT0gMSkge1xuICAgICAgICBpZiAoc2xpZGVzW2ldICYmICFicmVha0xvb3ApIHtcbiAgICAgICAgICBzbGlkZVNpemUgKz0gc2xpZGVzW2ldLnN3aXBlclNsaWRlU2l6ZTtcbiAgICAgICAgICBzcHYgKz0gMTtcbiAgICAgICAgICBpZiAoc2xpZGVTaXplID4gc3dpcGVyU2l6ZSkgYnJlYWtMb29wID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgIGlmICh2aWV3ID09PSAnY3VycmVudCcpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IGFjdGl2ZUluZGV4ICsgMTsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIGNvbnN0IHNsaWRlSW5WaWV3ID0gZXhhY3QgPyBzbGlkZXNHcmlkW2ldICsgc2xpZGVzU2l6ZXNHcmlkW2ldIC0gc2xpZGVzR3JpZFthY3RpdmVJbmRleF0gPCBzd2lwZXJTaXplIDogc2xpZGVzR3JpZFtpXSAtIHNsaWRlc0dyaWRbYWN0aXZlSW5kZXhdIDwgc3dpcGVyU2l6ZTtcblxuICAgICAgICAgIGlmIChzbGlkZUluVmlldykge1xuICAgICAgICAgICAgc3B2ICs9IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBwcmV2aW91c1xuICAgICAgICBmb3IgKGxldCBpID0gYWN0aXZlSW5kZXggLSAxOyBpID49IDA7IGkgLT0gMSkge1xuICAgICAgICAgIGNvbnN0IHNsaWRlSW5WaWV3ID0gc2xpZGVzR3JpZFthY3RpdmVJbmRleF0gLSBzbGlkZXNHcmlkW2ldIDwgc3dpcGVyU2l6ZTtcblxuICAgICAgICAgIGlmIChzbGlkZUluVmlldykge1xuICAgICAgICAgICAgc3B2ICs9IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHNwdjtcbiAgfVxuXG4gIHVwZGF0ZSgpIHtcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcbiAgICBjb25zdCB7XG4gICAgICBzbmFwR3JpZCxcbiAgICAgIHBhcmFtc1xuICAgIH0gPSBzd2lwZXI7
1IC8vIEJyZWFrcG9pbnRzXG5cbiAgICBpZiAocGFyYW1zLmJyZWFrcG9pbnRzKSB7XG4gICAgICBzd2lwZXIuc2V0QnJlYWtwb2ludCgpO1xuICAgIH1cblxuICAgIHN3aXBlci51cGRhdGVTaXplKCk7XG4gICAgc3dpcGVyLnVwZGF0ZVNsaWRlcygpO1xuICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcygpO1xuICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG5cbiAgICBmdW5jdGlvbiBzZXRUcmFuc2xhdGUoKSB7XG4gICAgICBjb25zdCB0cmFuc2xhdGVWYWx1ZSA9IHN3aXBlci5ydGxUcmFuc2xhdGUgPyBzd2lwZXIudHJhbnNsYXRlICogLTEgOiBzd2lwZXIudHJhbnNsYXRlO1xuICAgICAgY29uc3QgbmV3VHJhbnNsYXRlID0gTWF0aC5taW4oTWF0aC5tYXgodHJhbnNsYXRlVmFsdWUsIHN3aXBlci5tYXhUcmFuc2xhdGUoKSksIHN3aXBlci5taW5UcmFuc2xhdGUoKSk7XG4gICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKG5ld1RyYW5zbGF0ZSk7XG4gICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcbiAgICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG4gICAgfVxuXG4gICAgbGV0IHRyYW5zbGF0ZWQ7XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5mcmVlTW9kZSAmJiBzd2lwZXIucGFyYW1zLmZyZWVNb2RlLmVuYWJsZWQpIHtcbiAgICAgIHNldFRyYW5zbGF0ZSgpO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5hdXRvSGVpZ2h0KSB7XG4gICAgICAgIHN3aXBlci51cGRhdGVBdXRvSGVpZ2h0KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICgoc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ID09PSAnYXV0bycgfHwgc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ID4gMSkgJiYgc3dpcGVyLmlzRW5kICYmICFzd2lwZXIucGFyYW1zLmNlbnRlcmVkU2xpZGVzKSB7XG4gICAgICAgIHRyYW5zbGF0ZWQgPSBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDEsIDAsIGZhbHNlLCB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYW5zbGF0ZWQgPSBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuYWN0aXZlSW5kZXgsIDAsIGZhbHNlLCB0cnVlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0cmFuc2xhdGVkKSB7XG4gICAgICAgIHNldFRyYW5zbGF0ZSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzbmFwR3JpZCAhPT0gc3dpcGVyLnNuYXBHcmlkKSB7XG4gICAgICBzd2lwZXIuY2hlY2tPdmVyZmxvdygpO1xuICAgIH1cblxuICAgIHN3aXBlci5lbWl0KCd1cGRhdGUnKTtcbiAgfVxuXG4gIGNoYW5nZURpcmVjdGlvbihuZXdEaXJlY3Rpb24sIG5lZWRVcGRhdGUgPSB0cnVlKSB7XG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgICBjb25zdCBjdXJyZW50RGlyZWN0aW9uID0gc3dpcGVyLnBhcmFtcy5kaXJlY3Rpb247XG5cbiAgICBpZiAoIW5ld0RpcmVjdGlvbikge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgICBuZXdEaXJlY3Rpb24gPSBjdXJyZW50RGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnO1xuICAgIH1cblxuICAgIGlmIChuZXdEaXJlY3Rpb24gPT09IGN1cnJlbnREaXJlY3Rpb24gfHwgbmV3RGlyZWN0aW9uICE9PSAnaG9yaXpvbnRhbCcgJiYgbmV3RGlyZWN0aW9uICE9PSAndmVydGljYWwnKSB7XG4gICAgICByZXR1cm4gc3dpcGVyO1xuICAgIH1cblxuICAgIHN3aXBlci4kZWwucmVtb3ZlQ2xhc3MoYCR7c3dpcGVyLnBhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfSR7Y3VycmVudERpcmVjdGlvbn1gKS5hZGRDbGFzcyhgJHtzd2lwZXIucGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3N9JHtuZXdEaXJlY3Rpb259YCk7XG4gICAgc3dpcGVyLmVtaXRDb250YWluZXJDbGFzc2VzKCk7XG4gICAgc3dpcGVyLnBhcmFtcy5kaXJlY3Rpb24gPSBuZXdEaXJlY3Rpb247XG4gICAgc3dpcGVyLnNsaWRlcy5lYWNoKHNsaWRlRWwgPT4ge1xuICAgICAgaWYgKG5ld0RpcmVjdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xuICAgICAgICBzbGlkZUVsLnN0eWxlLndpZHRoID0gJyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzbGlkZUVsLnN0eWxlLmhlaWdodCA9ICcnO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHN3aXBlci5lbWl0KCdjaGFuZ2VEaXJlY3Rpb24nKTtcbiAgICBpZiAobmVlZFVwZGF0ZSkgc3dpcGVyLnVwZGF0ZSgpO1xuICAgIHJldHVybiBzd2lwZXI7XG4gIH1cblxuICBjaGFuZ2VMYW5ndWFnZURpcmVjdGlvbihkaXJlY3Rpb24pIHtcbiAgICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICAgIGlmIChzd2lwZXIucnRsICYmIGRpcmVjdGlvbiA9PT0gJ3J0bCcgfHwgIXN3aXBlci5ydGwgJiYgZGlyZWN0aW9uID09PSAnbHRyJykgcmV0dXJuO1xuICAgIHN3aXBlci5ydGwgPSBkaXJlY3Rpb24gPT09ICdydGwnO1xuICAgIHN3aXBlci5ydGxUcmFuc2xhdGUgPSBzd2lwZXIucGFyYW1zLmRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnICYmIHN3aXBlci5ydGw7XG5cbiAgICBpZiAoc3dpcGVyLnJ0bCkge1xuICAgICAgc3dpcGVyLiRlbC5hZGRDbGFzcyhgJHtzd2lwZXIucGFyYW1zLmNvbnRhaW5lck1vZGlmaWVyQ2xhc3N9cnRsYCk7XG4gICAgICBzd2lwZXIuZWwuZGlyID0gJ3J0bCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXBlci4kZWwucmVtb3ZlQ2xhc3MoYCR7c3dpcGVyLnBhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfXJ0bGApO1xuICAgICAgc3dpcGVyLmVsLmRpciA9ICdsdHInO1xuICAgIH1cblxuICAgIHN3aXBlci51cGRhdGUoKTtcbiAgfVxuXG4gIG1vdW50KGVsKSB7XG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgICBpZiAoc3dpcGVyLm1vdW50ZWQpIHJldHVybiB0cnVlOyAvLyBGaW5kIGVsXG5cbiAgICBjb25zdCAkZWwgPSAkKGVsIHx8IHN3aXBlci5wYXJhbXMuZWwpO1xuICAgIGVsID0gJGVsWzBdO1xuXG4gICAgaWYgKCFlbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGVsLnN3aXBlciA9IHN3aXBlcjtcblxuICAgIGNvbnN0IGdldFdyYXBwZXJTZWxlY3RvciA9ICgpID0+IHtcbiAgICAgIHJldHVybi
1BgLiR7KHN3aXBlci5wYXJhbXMud3JhcHBlckNsYXNzIHx8ICcnKS50cmltKCkuc3BsaXQoJyAnKS5qb2luKCcuJyl9YDtcbiAgICB9O1xuXG4gICAgY29uc3QgZ2V0V3JhcHBlciA9ICgpID0+IHtcbiAgICAgIGlmIChlbCAmJiBlbC5zaGFkb3dSb290ICYmIGVsLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3Rvcikge1xuICAgICAgICBjb25zdCByZXMgPSAkKGVsLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihnZXRXcmFwcGVyU2VsZWN0b3IoKSkpOyAvLyBDaGlsZHJlbiBuZWVkcyB0byByZXR1cm4gc2xvdCBpdGVtc1xuXG4gICAgICAgIHJlcy5jaGlsZHJlbiA9IG9wdGlvbnMgPT4gJGVsLmNoaWxkcmVuKG9wdGlvbnMpO1xuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9XG5cbiAgICAgIGlmICghJGVsLmNoaWxkcmVuKSB7XG4gICAgICAgIHJldHVybiAkKCRlbCkuY2hpbGRyZW4oZ2V0V3JhcHBlclNlbGVjdG9yKCkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gJGVsLmNoaWxkcmVuKGdldFdyYXBwZXJTZWxlY3RvcigpKTtcbiAgICB9OyAvLyBGaW5kIFdyYXBwZXJcblxuXG4gICAgbGV0ICR3cmFwcGVyRWwgPSBnZXRXcmFwcGVyKCk7XG5cbiAgICBpZiAoJHdyYXBwZXJFbC5sZW5ndGggPT09IDAgJiYgc3dpcGVyLnBhcmFtcy5jcmVhdGVFbGVtZW50cykge1xuICAgICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgICAgY29uc3Qgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgJHdyYXBwZXJFbCA9ICQod3JhcHBlcik7XG4gICAgICB3cmFwcGVyLmNsYXNzTmFtZSA9IHN3aXBlci5wYXJhbXMud3JhcHBlckNsYXNzO1xuICAgICAgJGVsLmFwcGVuZCh3cmFwcGVyKTtcbiAgICAgICRlbC5jaGlsZHJlbihgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzfWApLmVhY2goc2xpZGVFbCA9PiB7XG4gICAgICAgICR3cmFwcGVyRWwuYXBwZW5kKHNsaWRlRWwpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmFzc2lnbihzd2lwZXIsIHtcbiAgICAgICRlbCxcbiAgICAgIGVsLFxuICAgICAgJHdyYXBwZXJFbCxcbiAgICAgIHdyYXBwZXJFbDogJHdyYXBwZXJFbFswXSxcbiAgICAgIG1vdW50ZWQ6IHRydWUsXG4gICAgICAvLyBSVExcbiAgICAgIHJ0bDogZWwuZGlyLnRvTG93ZXJDYXNlKCkgPT09ICdydGwnIHx8ICRlbC5jc3MoJ2RpcmVjdGlvbicpID09PSAncnRsJyxcbiAgICAgIHJ0bFRyYW5zbGF0ZTogc3dpcGVyLnBhcmFtcy5kaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJyAmJiAoZWwuZGlyLnRvTG93ZXJDYXNlKCkgPT09ICdydGwnIHx8ICRlbC5jc3MoJ2RpcmVjdGlvbicpID09PSAncnRsJyksXG4gICAgICB3cm9uZ1JUTDogJHdyYXBwZXJFbC5jc3MoJ2Rpc3BsYXknKSA9PT0gJy13ZWJraXQtYm94J1xuICAgIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaW5pdChlbCkge1xuICAgIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gICAgaWYgKHN3aXBlci5pbml0aWFsaXplZCkgcmV0dXJuIHN3aXBlcjtcbiAgICBjb25zdCBtb3VudGVkID0gc3dpcGVyLm1vdW50KGVsKTtcbiAgICBpZiAobW91bnRlZCA9PT0gZmFsc2UpIHJldHVybiBzd2lwZXI7XG4gICAgc3dpcGVyLmVtaXQoJ2JlZm9yZUluaXQnKTsgLy8gU2V0IGJyZWFrcG9pbnRcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmJyZWFrcG9pbnRzKSB7XG4gICAgICBzd2lwZXIuc2V0QnJlYWtwb2ludCgpO1xuICAgIH0gLy8gQWRkIENsYXNzZXNcblxuXG4gICAgc3dpcGVyLmFkZENsYXNzZXMoKT
1sgLy8gQ3JlYXRlIGxvb3BcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmxvb3ApIHtcbiAgICAgIHN3aXBlci5sb29wQ3JlYXRlKCk7XG4gICAgfSAvLyBVcGRhdGUgc2l6ZVxuXG5cbiAgICBzd2lwZXIudXBkYXRlU2l6ZSgpOyAvLyBVcGRhdGUgc2xpZGVzXG5cbiAgICBzd2lwZXIudXBkYXRlU2xpZGVzKCk7XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy53YXRjaE92ZXJmbG93KSB7XG4gICAgICBzd2lwZXIuY2hlY2tPdmVyZmxvdygpO1xuICAgIH0gLy8gU2V0IEdyYWIgQ3Vyc29yXG5cblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmdyYWJDdXJzb3IgJiYgc3dpcGVyLmVuYWJsZWQpIHtcbiAgICAgIHN3aXBlci5zZXRHcmFiQ3Vyc29yKCk7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMucHJlbG9hZEltYWdlcykge1xuICAgICAgc3dpcGVyLnByZWxvYWRJbWFnZXMoKTtcbiAgICB9IC8vIFNsaWRlIFRvIEluaXRpYWwgU2xpZGVcblxuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgc3dpcGVyLnNsaWRlVG8oc3dpcGVyLnBhcmFtcy5pbml0aWFsU2xpZGUgKyBzd2lwZXIubG9vcGVkU2xpZGVzLCAwLCBzd2lwZXIucGFyYW1zLnJ1bkNhbGxiYWNrc09uSW5pdCwgZmFsc2UsIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIucGFyYW1zLmluaXRpYWxTbGlkZSwgMCwgc3dpcGVyLnBhcmFtcy5ydW5DYWxsYmFja3NPbkluaXQsIGZhbHNlLCB0cnVlKTtcbiAgICB9IC8vIEF0dGFjaCBldmVudHNcblxuXG4gICAgc3dpcGVyLmF0dGFjaEV2ZW50cygpOyAvLyBJbml0IEZsYWdcblxuICAgIHN3aXBlci5pbml0aWFsaXplZCA9IHRydWU7IC8vIEVtaXRcblxuICAgI
1HN3aXBlci5lbWl0KCdpbml0Jyk7XG4gICAgc3dpcGVyLmVtaXQoJ2FmdGVySW5pdCcpO1xuICAgIHJldHVybiBzd2lwZXI7XG4gIH1cblxuICBkZXN0cm95KGRlbGV0ZUluc3RhbmNlID0gdHJ1ZSwgY2xlYW5TdHlsZXMgPSB0cnVlKSB7XG4gICAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgICBjb25zdCB7XG4gICAgICBwYXJhbXMsXG4gICAgICAkZWwsXG4gICAgICAkd3JhcHBlckVsLFxuICAgICAgc2xpZGVzXG4gICAgfSA9IHN3aXBlcjtcblxuICAgIGlmICh0eXBlb2Ygc3dpcGVyLnBhcmFtcyA9PT0gJ3VuZGVmaW5lZCcgfHwgc3dpcGVyLmRlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgc3dpcGVyLmVtaXQoJ2JlZm9yZURlc3Ryb3knKTsgLy8gSW5pdCBGbGFnXG5cbiAgICBzd2lwZXIuaW5pdGlhbGl6ZWQgPSBmYWxzZTsgLy8gRGV0YWNoIGV2ZW50c1xuXG4gICAgc3dpcGVyLmRldGFjaEV2ZW50cygpOyAvLyBEZXN0cm95IGxvb3BcblxuICAgIGlmIChwYXJhbXMubG9vcCkge1xuICAgICAgc3dpcGVyLmxvb3BEZXN0cm95KCk7XG4gICAgfSAvLyBDbGVhbnVwIHN0eWxlc1xuXG5cbiAgICBpZiAoY2xlYW5TdHlsZXMpIHtcbiAgICAgIHN3aXBlci5yZW1vdmVDbGFzc2VzKCk7XG4gICAgICAkZWwucmVtb3ZlQXR0cignc3R5bGUnKTtcbiAgICAgICR3cmFwcGVyRWwucmVtb3ZlQXR0cignc3R5bGUnKTtcblxuICAgICAgaWYgKHNsaWRlcyAmJiBzbGlkZXMubGVuZ3RoKSB7XG4gICAgICAgIHNsaWRlcy5yZW1vdmVDbGFzcyhbcGFyYW1zLnNsaWRlVmlzaWJsZUNsYXNzLCBwYXJhbXMuc2xpZGVBY3RpdmVDbGFzcywgcGFyYW1zLnNsaWRlTmV4dENsYXNzLCBwYXJhbXMuc2xpZGVQcmV2Q2xhc3NdLmpvaW4oJyAnKSkucmVtb3ZlQXR0cignc3R5bGUnKS5yZW1vdmVBdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHN3aXBlci5lbWl0KCdkZXN0cm95Jyk7IC8vIERldGFjaCBlbWl0dGVyIGV2ZW50c1xuXG4gICAgT2JqZWN0LmtleXMoc3dpcGVyLmV2ZW50c0xpc3RlbmVycykuZm9yRWFjaChldmVudE5hbWUgPT4ge1xuICAgICAgc3dpcGVyLm9mZihldmVudE5hbWUpO1xuICAgIH0pO1xuXG4gICAgaWYgKGRlbGV0ZUluc3RhbmNlICE9PSBmYWxzZSkge1xuICAgICAgc3dpcGVyLiRlbFswXS5zd2lwZXIgPSBudWxsO1xuICAgICAgZGVsZXRlUHJvcHMoc3dpcGVyKTtcbiAgICB9XG5cbiAgICBzd2lwZXIuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBleHRlbmREZWZhdWx0cyhuZXdEZWZhdWx0cykge1xuICAgIGV4dGVuZChleHRlbmRlZERlZmF1bHRzLCBuZXdEZWZhdWx0cyk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGV4dGVuZGVkRGVmYXVsdHMoKSB7XG4gICAgcmV0dXJuIGV4dGVuZGVkRGVmYXVsdHM7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGRlZmF1bHRzKCkge1xuICAgIHJldHVybiBkZWZhdWx0cztcbiAgfVxuXG4gIHN0YXRpYyBpbnN0YWxsTW9kdWxlKG1vZCkge1xuICAgIGlmICghU3dpcGVyLnByb3RvdHlwZS5fX21vZHVsZXNfXykgU3dpcGVyLnByb3RvdHlwZS5fX21vZHVsZXNfXyA9IFtdO1xuICAgIGNvbnN0IG1vZHVsZXMgPSBTd2lwZXIucHJvdG90eXBlLl9fbW9kdWxlc19fO1xuXG4gICAgaWYgKHR5cGVvZiBtb2QgPT09ICdmdW5jdGlvbicgJiYgbW9kdWxlcy5pbmRleE9mKG1vZCkgPCAwKSB7XG4gICAgICBtb2R1bGVzLnB1c2gobW9kKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdXNlKG1vZHVsZSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KG1vZHVsZSkpIHtcbiAgICAgIG1vZHVsZS5mb3JFYWNoKG0gPT4gU3dpcGVyLmluc3RhbGxNb2R1bGUobSkpO1xuICAgICAgcmV0dXJuIFN3aXBlcjtcbiAgICB9XG5cbiAgICBTd2lwZXIuaW5zdGFsbE1vZHVsZShtb2R1bGUpO1xuICAgIHJldHVybiBTd2lwZXI7XG4gIH1cblxufVxuXG5PYmplY3Qua2V5cyhwcm90b3R5cGVzKS5mb3JFYWNoKHByb3RvdHlwZUdyb3VwID0+IHtcbiAgT2JqZWN0LmtleXMocHJvdG90eXBlc1twcm90b3R5cGVHcm91cF0pLmZvckVhY2gocHJvdG9NZXRob2QgPT4ge1xuICAgIFN3aXBlci5wcm90b3R5cGVbcHJvdG9NZXRob2RdID0gcHJvdG90eXBlc1twcm90b3R5cGVHcm91cF1bcHJvdG9NZXRob2RdO1xuICB9KTtcbn0pO1xuU3dpcGVyLnVzZShbUmVzaXplLCBPYnNlcnZlcl0pO1xuZXhwb3J0IGRlZmF1bHQgU3dpcGVyOyIsImltcG9ydCAkIGZyb20gJy4uLy4uL3NoYXJlZC9kb20uanMnO1xuaW1wb3J0IHsgc2V0Q1NTUHJvcGVydHkgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVmlydHVhbCh7XG4gIHN3aXBlcixcbiAgZXh0ZW5kUGFyYW1zLFxuICBvbixcbiAgZW1pdFxufSkge1xuICBleHRlbmRQYXJhbXMoe1xuICAgIHZpcnR1YWw6IHtcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgc2xpZGVzOiBbXSxcbiAgICAgIGNhY2hlOiB0cnVlLFxuICAgICAgcmVuZGVyU2xpZGU6IG51bGwsXG4gICAgICByZW5kZXJFeHRlcm5hbDogbnVsbCxcbiAgICAgIHJlbmRlckV4dGVybmFsVXBkYXRlOiB0cnVlLFxuICAgICAgYWRkU2xpZGVzQmVmb3JlOiAwLFxuICAgICAgYWRkU2xpZGVzQWZ0ZXI6IDBcbiAgICB9XG4gIH0pO1xuICBsZXQgY3NzTW9kZVRpbWVvdXQ7XG4gIHN3aXBlci52aXJ0dWFsID0ge1xuICAgIGNhY2hlOiB7fSxcbiAgICBmcm9tOiB1bmRlZmluZWQsXG4gICAgdG86IHVuZGVmaW5lZCxcbiAgICBzbGlkZXM6IFtdLFxuICAgIG9mZnNldDogMCxcbiAgICBzbGlkZXNHcmlkOiBbXVxuICB9O1xuXG4gIGZ1bmN0aW9uIHJlbmRlclNsaWRlKHNsaWRlLCBpbmRleCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMudmlydHVhbDtcblxuICAgIGlmIChwYXJhbXMuY2FjaGUgJiYgc3dpcGVyLnZpcnR1YWwuY2FjaGVbaW5kZXhdKSB7XG4gICAgICByZXR1cm4gc3dpcGVyLnZpcnR1YWwuY2FjaGVbaW5kZXhdO1xuICAgIH1cblxuICAgIGNvbnN0ICRzbGlkZUVsID0gcGFyYW1zLnJlbmRlclNsaWRlID8gJChwYXJhbXMucmVuZGVyU2xpZGUuY2FsbChzd2lwZXIsIHNsaWRlLCBpbmRleCkpIDogJChgPGRpdiBjbGFzcz1cIiR7c3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzfVwiIGRhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtpbmRleH1cIj4ke3NsaWRlfTwvZGl2PmApO1xuICAgIGlmICghJHNsaWRlRWwuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnKSkgJHNsaWRlRWwuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnLCBpbmRleCk7XG4gICAgaWYgKHBhcmFtcy5jYWNoZSkgc3dpcGVyLnZpcnR1YWwuY2FjaGVbaW5kZXhdID0gJHNsaWRlRWw7XG4gICAgcmV0dXJuICRzbGlkZUVsO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKGZvcmNlKSB7XG4gICAgY29uc3Qge1xuICAgICAgc2xpZGVzUGVyVmlldyxcbiAgICAgIHNsaWRlc1Blckdyb3VwLFxuICAgICAgY2VudGVyZWRTbGlkZXNcbiAgICB9ID0gc3dpcGVyLnBhcmFtcztcbiAgICBjb25zdCB7XG4gICAgICBhZGRTbGlkZXNCZWZvcmUsXG4gICAgICBhZGRTbGlkZXNBZnRlclxuICAgIH0gPSBzd2lwZXIucGFyYW1zLnZpcnR1YWw7XG4gICAgY29uc3Qge1xuICAgICAgZnJvbTogcHJldmlvdXNGcm9tLFxuICAgICAgdG86IHByZXZpb3VzVG8sXG4gICAgICBzbGlkZXMsXG4gICAgICBzbGlkZXNHcmlkOiBwcmV2aW91c1NsaWRlc0dyaWQsXG4gICAgICBvZmZzZXQ6IHByZXZpb3VzT2Zmc2V0XG4gICAgfSA9IHN3aXBlci52aXJ0dWFsO1xuXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleCgpO1xuICAgIH1cblxuICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4IHx8IDA7XG4gICAgbGV0IG9mZnNldFByb3A7XG4gICAgaWYgKHN3aXBlci5ydGxUcmFuc2xhdGUpIG9mZnNldFByb3AgPSAncmlnaHQnO2Vsc2Ugb2Zmc2V0UHJvcCA9IHN3aXBlci5pc0hvcml6b250YWwoKSA/ICdsZWZ0JyA6ICd0b3AnO1xuICAgIGxldCBzbGlkZXNBZnRlcjtcbiAgICBsZXQgc2xpZGVzQmVmb3JlO1xuXG4gICAgaWYgKGNlbnRlcmVkU2xpZGVzKSB7XG4gICAgICBzbGlkZXNBZnRlciA9IE1hdGguZmxvb3Ioc2xpZGVzUGVyVmlldyAvIDIpICsgc2xpZGVzUGVyR3JvdXAgKyBhZGRTbGlkZXNBZnRlcjtcbiAgICAgIHNsaWRlc0JlZm9yZSA9IE1hdGguZmxvb3Ioc2xpZGVzUGVyVmlldyAvIDIpICsgc2xpZGVzUGVyR3JvdXAgKyBhZGRTbGlkZXNCZWZvcmU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNsaWRlc0FmdGVyID0gc2xpZGVzUGVyVmlldyArIChzbGlkZXNQZXJHcm91cCAtIDEpICsgYWRkU2xpZGVzQWZ0ZXI7XG4gICAgICBzbGlkZXNCZWZvcmUgPSBzbGlkZXNQZXJHcm91cCArIGFkZFNsaWRlc0JlZm9yZTtcbiAgICB9XG5cbiAgICBjb25zdCBmcm9tID0gTWF0aC5tYXgoKGFjdGl2ZUluZGV4IHx8IDApIC0gc2xpZGVzQmVmb3JlLCAwKTtcbiAgICBjb25zdCB0byA9IE1hdGgubWluKChhY3RpdmVJbmRleCB8fCAwKSArIHNsaWRlc0FmdGVyLCBzbGlkZXMubGVuZ3RoIC0gMSk7XG4gICAgY29uc3Qgb2Zmc2V0ID0gKHN3aXBlci5zbGlkZXNHcmlkW2Zyb21dIHx8IDApIC0gKHN3aXBlci5zbGlkZXNHcmlkWzBdIHx8IDApO1xuICAgIE9iamVjdC5hc3NpZ24oc3dpcGVyLnZpcnR1YWwsIHtcbiAgICAgIGZyb20sXG4gICAgICB0byxcbiAgICAgIG9mZnNldCxcbiAgICAgIHNsaWRlc0dyaWQ6IHN3aXBlci5zbGlkZXNHcmlkXG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBvblJlbmRlcmVkKCkge1xuICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlcygpO1xuICAgICAgc3dpcGVyLnVwZGF0ZVByb2dyZXNzKCk7XG4gICAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xuXG4gICAgICBpZiAoc3dpcGVyLmxhenkgJiYgc3dpcGVyLnBhcmFtcy5sYXp5LmVuYWJsZWQpIHtcbiAgICAgICAgc3dpcGVyLmxhenkubG9hZCgpO1xuICAgICAgfVxuXG4gICAgICBlbWl0KCd2aXJ0dWFsVXBkYXRlJyk7XG4gICAgfVxuXG4gICAgaWYgKHByZXZpb3VzRnJvbSA9PT0gZnJvbSAmJiBwcmV2aW91c1RvID09PSB0byAmJiAhZm9yY2UpIHtcbiAgICAgIGlmIChzd2lwZXIuc2xpZGVzR3JpZCAhPT0gcHJldmlvdXNTbGlkZXNHcmlkICYmIG9mZnNldCAhPT0gcHJldmlvdXNPZmZzZXQpIHtcbiAgICAgICAgc3dpcGVyLnNsaWRlcy5jc3Mob2Zmc2V0UHJvcCwgYCR7b2Zmc2V0fXB4YCk7XG4gICAgICB9XG5cbiAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcygpO1xuICAgICAgZW1pdCgndmlydHVhbFVwZGF0ZScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWwucmVuZGVyRXh0ZXJuYWwpIHtcbiAgICAgIHN3aXBlci5wYXJhbXMudmlydHVhbC5yZW5kZXJFeHRlcm5hbC5jYWxsKHN3aXBlciwge1xuICAgICAgICBvZmZzZXQsXG4gICAgICAgIGZyb20sXG4gICAgICAgI
1HRvLFxuICAgICAgICBzbGlkZXM6IGZ1bmN0aW9uIGdldFNsaWRlcygpIHtcbiAgICAgICAgICBjb25zdCBzbGlkZXNUb1JlbmRlciA9IFtdO1xuXG4gICAgICAgICAgZm9yIChsZXQgaSA9IGZyb207IGkgPD0gdG87IGkgKz0gMSkge1xuICAgICAgICAgICAgc2xpZGVzVG9SZW5kZXIucHVzaChzbGlkZXNbaV0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBzbGlkZXNUb1JlbmRlcjtcbiAgICAgICAgfSgpXG4gICAgICB9KTtcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMudmlydHVhbC5yZW5kZXJFeHRlcm5hbFVwZGF0ZSkge1xuICAgICAgICBvblJlbmRlcmVkKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbWl0KCd2aXJ0dWFsVXBkYXRlJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwcmVwZW5kSW5kZXhlcyA9IFtdO1xuICAgIGNvbnN0IGFwcGVuZEluZGV4ZXMgPSBbXTtcblxuICAgIGlmIChmb3JjZSkge1xuICAgICAgc3dpcGVyLiR3cmFwcGVyRWwuZmluZChgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzfWApLnJlbW92ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBpID0gcHJldmlvdXNGcm9tOyBpIDw9IHByZXZpb3VzVG87IGkgKz0gMSkge1xuICAgICAgICBpZiAoaSA8IGZyb20gfHwgaSA+IHRvKSB7XG4gICAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWwuZmluZChgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzfVtkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cIiR7aX1cIl1gKS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpZiAoaSA+PSBmcm9tICYmIGkgPD0gdG8pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwcmV2aW91c1RvID09PSAndW5kZWZpbmVkJyB8fCBmb3JjZSkge1xuICAgICAgICAgIGFwcGVuZEluZGV4ZXMucHVzaChpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoaSA+IHByZXZpb3VzVG8pIGFwcGVuZEluZGV4ZXMucHVzaChpKTtcbiAgICAgICAgICBpZiAoaSA8IHByZXZpb3VzRnJvbSkgcHJlcGVuZEluZGV4ZXMucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGFwcGVuZEluZGV4ZXMuZm9yRWFjaChpbmRleCA9PiB7XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbC5hcHBlbmQocmVuZGVyU2xpZGUoc2xpZGVzW2luZGV4XSwgaW5kZXgpKTtcbiAgICB9KTtcbiAgICBwcmVwZW5kSW5kZXhlcy5zb3J0KChhLCBiKSA9PiBiIC0gYSkuZm9yRWFjaChpbmRleCA9PiB7XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbC5wcmVwZW5kKHJlbmRlclNsaWRlKHNsaWRlc1tpbmRleF0sIGluZGV4KSk7XG4gICAgfSk7XG4gICAgc3dpcGVyLiR3cmFwcGVyRWwuY2hpbGRyZW4oJy5zd2lwZXItc2xpZGUnKS5jc3Mob2Zmc2V0UHJvcCwgYCR7b2Zmc2V0fXB4YCk7XG4gICAgb25SZW5kZXJlZCgpO1xuICB9XG5cbiAgZnVuY3Rpb24gYXBwZW5kU2xpZGUoc2xpZGVzKSB7XG4gICAgaWYgKHR5cGVvZiBzbGlkZXMgPT09ICdvYmplY3QnICYmICdsZW5ndGgnIGluIHNsaWRlcykge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgaWYgKHNsaWRlc1tpXSkgc3dpcGVyLnZpcnR1YWwuc2xpZGVzLnB1c2goc2xpZGVzW2ldKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3dpcGVyLnZpcnR1YWwuc2xpZGVzLnB1c2goc2xpZGVzKTtcbiAgICB9XG5cbiAgICB1cGRhdGUodHJ1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBwcmVwZW5kU2xpZGUoc2xpZGVzKSB7XG4gICAgY29uc3QgYWN0aXZlSW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXg7XG4gICAgbGV0IG5ld0FjdGl2ZUluZGV4ID0gYWN0aXZlSW5kZXggKyAxO1xuICAgIGxldCBudW1iZXJPZk5ld1NsaWRlcyA9IDE7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShzbGlkZXMpKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAoc2xpZGVzW2ldKSBzd2lwZXIudmlydHVhbC5zbGlkZXMudW5zaGlmdChzbGlkZXNbaV0pO1xuICAgICAgfVxuXG4gICAgICBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4ICsgc2xpZGVzLmxlbmd0aDtcbiAgICAgIG51bWJlck9mTmV3U2xpZGVzID0gc2xpZGVzLmxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3dpcGVyLnZpcnR1YWwuc2xpZGVzLnVuc2hpZnQoc2xpZGVzKTtcbiAgICB9XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmNhY2hlKSB7XG4gICAgICBjb25zdCBjYWNoZSA9IHN3aXBlci52aXJ0dWFsLmNhY2hlO1xuICAgICAgY29uc3QgbmV3Q2FjaGUgPSB7fTtcbiAgICAgIE9iamVjdC5rZXlzKGNhY2hlKS5mb3JFYWNoKGNhY2hlZEluZGV4ID0+IHtcbiAgICAgICAgY29uc3QgJGNhY2hlZEVsI
1D0gY2FjaGVbY2FjaGVkSW5kZXhdO1xuICAgICAgICBjb25zdCBjYWNoZWRFbEluZGV4ID0gJGNhY2hlZEVsLmF0dHIoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4Jyk7XG5cbiAgICAgICAgaWYgKGNhY2hlZEVsSW5kZXgpIHtcbiAgICAgICAgICAkY2FjaGVkRWwuYXR0cignZGF0YS1zd2lwZXItc2xpZGUtaW5kZXgnLCBwYXJzZUludChjYWNoZWRFbEluZGV4LCAxMCkgKyBudW1iZXJPZk5ld1NsaWRlcyk7XG4gICAgICAgIH1cblxuICAgICAgICBuZXdDYWNoZVtwYXJzZUludChjYWNoZWRJbmRleCwgMTApICsgbnVtYmVyT2ZOZXdTbGlkZXNdID0gJGNhY2hlZEVsO1xuICAgICAgfSk7XG4gICAgICBzd2lwZXIudmlydHVhbC5jYWNoZSA9IG5ld0NhY2hlO1xuICAgIH1cblxuICAgIHVwZGF0ZSh0cnVlKTtcbiAgICBzd2lwZXIuc2xpZGVUbyhuZXdBY3RpdmVJbmRleCwgMCk7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVTbGlkZShzbGlkZXNJbmRleGVzKSB7XG4gICAgaWYgKHR5cGVvZiBzbGlkZXNJbmRleGVzID09PSAndW5kZWZpbmVkJyB8fCBzbGlkZXNJbmRleGVzID09PSBudWxsKSByZXR1cm47XG4gICAgbGV0IGFjdGl2ZUluZGV4ID0gc3dpcGVyLmFjdGl2ZUluZGV4O1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc2xpZGVzSW5kZXhlcykpIHtcbiAgICAgIGZvciAobGV0IGkgPSBzbGlkZXNJbmRleGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaSAtPSAxKSB7XG4gICAgICAgIHN3aXBlci52aXJ0dWFsLnNsaWRlcy5zcGxpY2Uoc2xpZGVzSW5kZXhlc1tpXSwgMSk7XG5cbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMudmlydHVhbC5jYWNoZSkge1xuICAgICAgICAgIGRlbGV0ZSBzd2lwZXIudmlydHVhbC5jYWNoZVtzbGlkZXNJbmRleGVzW2ldXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzbGlkZXNJbmRleGVzW2ldIDwgYWN0aXZlSW5kZXgpIGFjdGl2ZUluZGV4IC09IDE7XG4gICAgICAgIGFjdGl2ZUluZGV4ID0gTWF0aC5tYXgoYWN0aXZlSW5kZXgsIDApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIudmlydHVhbC5zbGlkZXMuc3BsaWNlKHNsaWRlc0luZGV4ZXMsIDEpO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmNhY2hlKSB7XG4gICAgICAgIGRlbGV0ZSBzd2lwZXIudmlydHVhbC5jYWNoZVtzbGlkZXNJbmRleGVzXTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNsaWRlc0luZGV4ZXMgPCBhY3RpdmVJbmRleCkgYWN0aXZlSW5kZXggLT0gMTtcbiAgICAgIGFjdGl2ZUluZGV4ID0gTWF0aC5tYXgoYWN0aXZlSW5kZXgsIDApO1xuICAgIH1cblxuICAgIHVwZGF0ZSh0cnVlKTtcbiAgICBzd2lwZXIuc2xpZGVUbyhhY3RpdmVJbmRleCwgMCk7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVBbGxTbGlkZXMoKSB7XG4gICAgc3dpcGVyLnZpcnR1YWwuc2xpZGVzID0gW107XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmNhY2hlKSB7XG4gICAgICBzd2lwZXIudmlydHVhbC5jYWNoZSA9IHt9O1xuICAgIH1cblxuICAgIHVwZGF0ZSh0cnVlKTtcbiAgICBzd2lwZXIuc2xpZGVUbygwLCAwKTtcbiAgfVxuXG4gIG9uKCdiZWZvcmVJbml0JywgKCkgPT4ge1xuICAgIGlmICghc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQpIHJldHVybjtcbiAgICBzd2lwZXIudmlydHVhbC5zbGlkZXMgPSBzd2lwZXIucGFyYW1zLnZpcnR1YWwuc2xpZGVzO1xuICAgIHN3aXBlci5jbGFzc05hbWVzLnB1c2goYCR7c3dpcGVyLnBhcmFtcy5jb250YWluZXJNb2RpZmllckNsYXNzfXZpcnR1YWxgKTtcbiAgICBzd2lwZXIucGFyYW1zLndhdGNoU2xpZGVzUHJvZ3Jlc3MgPSB0cnVlO1xuICAgIHN3aXBlci5vcmlnaW5hbFBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzID0gdHJ1ZTtcblxuICAgIGlmICghc3dpcGVyLnBhcmFtcy5pbml0aWFsU2xpZGUpIHtcbiAgICAgIHVwZGF0ZSgpO1xuICAgIH1cbiAgfSk7XG4gIG9uKCdzZXRUcmFuc2xhdGUnLCAoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCkgcmV0dXJuO1xuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuY3NzTW9kZSAmJiAhc3dpcGVyLl9pbW1lZGlhdGVWaXJ0dWFsKSB7XG4gICAgICBjbGVhclRpbWVvdXQoY3NzTW9kZVRpbWVvdXQpO1xuICAgICAgY3NzTW9kZVRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdXBkYXRlKCk7XG4gICAgICB9LCAxMDApO1xuICAgIH0gZWxzZSB7XG4gICAgICB1cGRhdGUoKTtcbiAgICB9XG4gIH0pO1xuICBvbignaW5pdCB1cGRhdGUgcmVzaXplJywgKCkgPT4ge1xuICAgIGlmICghc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQpIHJldHVybjtcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgIHNldENTU1Byb3BlcnR5KHN3aXBlci53cmFwcGVyRWwsICctLXN3aXBlci12aXJ0dWFsLXNpemUnLCBgJHtzd2lwZXIudmlydHVhbFNpemV9cHhgKTtcbiAgICB9XG4gIH0pO1xuICBPYmplY3QuYXNzaWduKHN3aXBlci52aXJ0dWFsLCB7XG4gICAgYXBwZW5kU2xpZGUsXG4gICAgcHJlcGVuZFNsaWRlLFxuICAgIHJlbW92ZVNsaWRlLFxuICAgIHJlbW92ZUFsbFNsaWRlcyxcbiAgICB1cGRhdGVcbiAgfSk7XG59IiwiLyogZXNsaW50LWRpc2FibGUgY29uc2lzdGVudC1yZXR1cm4gKi9cbmltcG9ydCB7IGdldFdpbmRvdywgZ2V0RG9jdW1lbnQgfSBmcm9tICdzc3Itd2luZG93JztcbmltcG9ydCAkIGZyb20gJy4uLy4uL3NoYXJlZC9kb20uanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gS2V5Ym9hcmQoe1xuICBzd2lwZXIsXG4gIGV4dGVuZFBhcmFtcyxcbiAgb24sXG4gIGVtaXRcbn0pIHtcbiAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgc3dpcGVyLmtleWJvYXJkID0ge1xuICAgIGVuYWJsZWQ6IGZhbHNlXG4gIH07XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAga2V5Ym9hcmQ6IHtcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgb25seUluVmlld3BvcnQ6IHRydWUsXG4gICAgICBwYWdlVXBEb3duOiB0cnVlXG4gICAgfVxuICB9KTtcblxuICBmdW5jdGlvbiBoYW5kbGUoZXZlbnQpIHtcbiAgICBpZiAoIXN3aXBlci5lbmFibGVkKSByZXR1cm47XG4gICAgY29uc3Qge1xuICAgICAgcnRsVHJhbnNsYXRlOiBydGxcbiAgICB9ID0gc3dpcGVyO1xuICAgIGxldCBlID0gZXZlbnQ7XG4gICAgaWYgKGUub3JpZ2luYWxFdmVudCkgZSA9IGUub3JpZ2luYWxFdmVudDsgLy8ganF1ZXJ5IGZpeFxuXG4gICAgY29uc3Qga2MgPSBlLmtleUNvZGUgfHwgZS5jaGFyQ29kZTtcbiAgICBjb25zdCBwYWdlVXBEb3duID0gc3dpcGVyLnBhcmFtcy5rZXlib2FyZC5wYWdlVXBEb3duO1xuICAgIGNvbnN0IGlzUGFn
1ZVVwID0gcGFnZVVwRG93biAmJiBrYyA9PT0gMzM7XG4gICAgY29uc3QgaXNQYWdlRG93biA9IHBhZ2VVcERvd24gJiYga2MgPT09IDM0O1xuICAgIGNvbnN0IGlzQXJyb3dMZWZ0ID0ga2MgPT09IDM3O1xuICAgIGNvbnN0IGlzQXJyb3dSaWdodCA9IGtjID09PSAzOTtcbiAgICBjb25zdCBpc0Fycm93VXAgPSBrYyA9PT0gMzg7XG4gICAgY29uc3QgaXNBcnJvd0Rvd24gPSBrYyA9PT0gNDA7IC8vIERpcmVjdGlvbnMgbG9ja3NcblxuICAgIGlmICghc3dpcGVyLmFsbG93U2xpZGVOZXh0ICYmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkgJiYgaXNBcnJvd1JpZ2h0IHx8IHN3aXBlci5pc1ZlcnRpY2FsKCkgJiYgaXNBcnJvd0Rvd24gfHwgaXNQYWdlRG93bikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXN3aXBlci5hbGxvd1NsaWRlUHJldiAmJiAoc3dpcGVyLmlzSG9yaXpvbnRhbCgpICYmIGlzQXJyb3dMZWZ0IHx8IHN3aXBlci5pc1ZlcnRpY2FsKCkgJiYgaXNBcnJvd1VwIHx8IGlzUGFnZVVwKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChlLnNoaWZ0S2V5IHx8IGUuYWx0S2V5IHx8IGUuY3RybEtleSB8fCBlLm1ldGFLZXkpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ub2RlTmFtZSAmJiAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnaW5wdXQnIHx8IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ3RleHRhcmVhJykpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMua2V5Ym9hcmQub25seUluVmlld3BvcnQgJiYgKGlzUGFnZVVwIHx8IGlzUGFnZURvd24gfHwgaXNBcnJvd0xlZnQgfHwgaXNBcnJvd1JpZ2h0IHx8IGlzQXJyb3dVcCB8fCBpc0Fycm93RG93bikpIHtcbiAgICAgIGxldCBpblZpZXcgPSBmYWxzZTsgLy8gQ2hlY2sgdGhhdCBzd2lwZXIgc2hvdWxkIGJlIGluc2lkZSBvZiB2aXNpYmxlIGFyZWEgb2Ygd2luZG93XG5cbiAgICAgIGlmIChzd2lwZXIuJGVsLnBhcmVudHMoYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVDbGFzc31gKS5sZW5ndGggPiAwICYmIHN3aXBlci4kZWwucGFyZW50cyhgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUFjdGl2ZUNsYXNzfWApLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBjb25zdCAkZWwgPSBzd2lwZXIuJGVsO1xuICAgICAgY29uc3Qgc3dpcGVyV2lkdGggPSAkZWxbMF0uY2xpZW50V2lkdGg7XG4gICAgICBjb25zdCBzd2lwZXJIZWlnaHQgPSAkZWxbMF0uY2xpZW50SGVpZ2h0O1xuICAgICAgY29uc3Qgd2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICAgIGNvbnN0IHdpbmRvd0hlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICAgIGNvbnN0IHN3aXBlck9mZnNldCA9IHN3aXBlci4kZWwub2Zmc2V0KCk7XG4gICAgICBpZiAocnRsKSBzd2lwZXJPZmZzZXQubGVmdCAtPSBzd2lwZXIuJGVsWzBdLnNjcm9sbExlZnQ7XG4gICAgICBjb25zdCBzd2lwZXJDb29yZCA9IFtbc3dpcGVyT2Zmc2V0LmxlZnQsIHN3aXBlck9mZnNldC50b3BdLCBbc3dpcGVyT2Zmc2V0LmxlZnQgKyBzd2lwZXJXaWR0aCwgc3dpcGVyT2Zmc2V0LnRvcF0sIFtzd2lwZXJPZmZzZXQubGVmdCwgc3dpcGVyT2Zmc2V0LnRvcCArIHN3aXBlckhlaWdodF0sIFtzd2lwZXJPZmZzZXQubGVmdCArIHN3aXBlcldpZHRoLCBzd2lwZXJPZmZzZXQudG9wICsgc3dpcGVySGVpZ2h0XV07XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3dpcGVyQ29vcmQubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBzd2lwZXJDb29yZFtpXTtcblxuICAgICAgICBpZiAocG9pbnRbMF0gPj0gMCAmJiBwb2ludFswXSA8PSB3aW5kb3dXaWR0aCAmJiBwb2ludFsxXSA+PSAwICYmIHBvaW50WzFdIDw9IHdpbmRvd0hlaWdodCkge1xuICAgICAgICAgIGlmIChwb2ludFswXSA9PT0gMCAmJiBwb2ludFsxXSA9PT0gMCkgY29udGludWU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgICAgICAgIGluVmlldyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFpblZpZXcpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xuICAgICAgaWYgKGlzUGFnZVVwIHx8IGlzUGFnZURvd24gfHwgaXNBcnJvd0xlZnQgfHwgaXNBcnJvd1JpZ2h0KSB7XG4gICAgICAgIGlmIChlLnByZXZlbnREZWZhdWx0KSBlLnByZXZlbnREZWZhdWx0KCk7ZWxzZSBlLnJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICgoaXNQYWdlRG93biB8fCBpc0Fycm93UmlnaHQpICYmICFydGwgfHwgKGlzUGFnZVVwIHx8IGlzQXJyb3dMZWZ0KSAmJiBydGwpIHN3aXBlci5zbGlkZU5leHQoKTtcbiAgICAgIGlmICgoaXNQYWdlVXAgfHwgaXNBcnJvd0xlZnQpICYmICFydGwgfHwgKGlzUGFnZURvd24gfHwgaXNBcnJvd1JpZ2h0KSAmJiBydGwpIHN3aXBlci5zbGlkZVByZXYoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzUGFnZVVwIHx8IGlzUGFnZURvd24gfHwgaXNBcnJvd1VwIHx8IGlzQXJyb3dEb3duKSB7XG4gICAgICAgIGlmIChlLnByZXZlbnREZWZhdWx0KSBlLnByZXZlbnREZWZhdWx0KCk7ZWxzZSBlLnJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1BhZ2VEb3duIHx8IGlzQXJyb3dEb3duKSBzd2lwZXIuc2xpZGVOZXh0KCk7XG4gICAgICBpZiAoaXNQYWdlVXAgfHwgaXNBcnJvd1VwKSBzd2lwZXIuc2xpZGVQcmV2KCk7XG4gICAgfVxuXG4gICAgZW1pdCgna2V5UHJlc3MnLCBrYyk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuYWJsZSgpIHtcbiAgICBpZiAoc3dpcGVyLmtleWJvYXJkLmVuYWJsZWQpIHJldHVybjtcbiAgICAkKGRvY3VtZW50KS5vbigna2V5ZG93bicsIGhhbmRsZSk7XG4gICAgc3dpcGVyLmtleWJvYXJkLmVuYWJsZWQgPSB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gZGlzYWJsZSgpIHtcbiAgICBpZiAoIXN3aXBlci5rZXlib2FyZC5lbmFibGVkKSByZXR1cm47XG4gICAgJChkb2N1bWVudCkub2ZmKCdrZXlkb3duJywgaGFuZGxlKTtcbiAgICBzd2lwZXIua2V5Ym9hcmQuZW5hYmxlZCA9IGZhbHNlO1xuICB9XG5cbiAgb24oJ2luaXQnLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMua2V5Ym9hcmQuZW5hYmxlZCkge1xuICAgICAgZW5hYmxlKCk7XG4gICAgfVxuICB9KTtcbiAgb24oJ2Rlc3Ryb3knLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci5rZXlib2FyZC5lbmFibGVkKSB7XG4gICAgICBkaXNhYmxlKCk7XG4gICAgfVxuICB9KTtcbiAgT2JqZWN0LmFzc2lnbihzd2lwZXIua2V5Ym9hcmQsIHtcbiAgICBlbmFibGUsXG4gICAgZGlzYWJsZVxuICB9KTtcbn0iLCIvKiBlc2xpbnQtZGlzYWJsZSBjb25zaXN0ZW50LXJldHVybiAqL1xuaW1wb3J0IHsgZ2V0V2luZG93IH0gZnJvbSAnc3NyLXdpbmRvdyc7XG5pbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmltcG9ydCB7
1IG5vdywgbmV4dFRpY2sgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW91c2V3aGVlbCh7XG4gIHN3aXBlcixcbiAgZXh0ZW5kUGFyYW1zLFxuICBvbixcbiAgZW1pdFxufSkge1xuICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgZXh0ZW5kUGFyYW1zKHtcbiAgICBtb3VzZXdoZWVsOiB7XG4gICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgIHJlbGVhc2VPbkVkZ2VzOiBmYWxzZSxcbiAgICAgIGludmVydDogZmFsc2UsXG4gICAgICBmb3JjZVRvQXhpczogZmFsc2UsXG4gICAgICBzZW5zaXRpdml0eTogMSxcbiAgICAgIGV2ZW50c1RhcmdldDogJ2NvbnRhaW5lcicsXG4gICAgICB0aHJlc2hvbGREZWx0YTogbnVsbCxcbiAgICAgIHRocmVzaG9sZFRpbWU6IG51bGxcbiAgICB9XG4gIH0pO1xuICBzd2lwZXIubW91c2V3aGVlbCA9IHtcbiAgICBlbmFibGVkOiBmYWxzZVxuICB9O1xuICBsZXQgdGltZW91dDtcbiAgbGV0IGxhc3RTY3JvbGxUaW1lID0gbm93KCk7XG4gIGxldCBsYXN0RXZlbnRCZWZvcmVTbmFwO1xuICBjb25zdCByZWNlbnRXaGVlbEV2ZW50cyA9IFtdO1xuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZShlKSB7XG4gICAgLy8gUmVhc29uYWJsZSBkZWZhdWx0c1xuICAgIGNvbnN0IFBJWEVMX1NURVAgPSAxMDtcbiAgICBjb25zdCBMSU5FX0hFSUdIVCA9IDQwO1xuICAgIGNvbnN0IFBBR0VfSEVJR0hUID0gODAwO1xuICAgIGxldCBzWCA9IDA7XG4gICAgbGV0IHNZID0gMDsgLy8gc3BpblgsIHNwaW5ZXG5cbiAgICBsZXQgcFggPSAwO1xuICAgIGxldCBwWSA9IDA7IC8vIHBpeGVsWCwgcGl4ZWxZXG4gICAgLy8gTGVnYWN5XG5cbiAgICBpZiAoJ2RldGFpbCcgaW4gZSkge1xuICAgICAgc1kgPSBlLmRldGFpbDtcbiAgICB9XG5cbiAgICBpZiAoJ3doZWVsRGVsdGEnIGluIGUpIHtcbiAgICAgIHNZID0gLWUud2hlZWxEZWx0YSAvIDEyMDtcbiAgICB9XG5cbiAgICBpZiAoJ3doZWVsRGVsdGFZJyBpbiBlKSB7XG4gICAgICBzWSA9IC1lLndoZWVsRGVsdGFZIC8gMTIwO1xuICAgIH1cblxuICAgIGlmICgnd2hlZWxEZWx0YVgnIGluIGUpIHtcbiAgICAgIHNYID0gLWUud2hlZWxEZWx0YVggLyAxMjA7XG4gICAgfSAvLyBzaWRlIHNjcm9sbGluZyBvbiBGRiB3aXRoIERPTU1vdXNlU2Nyb2xsXG5cblxuICAgIGlmICgnYXhpcycgaW4gZSAmJiBlLmF4aXMgPT09IGUuSE9SSVpPTlRBTF9BWElTKSB7XG4gICAgICBzWCA9IHNZO1xuICAgICAgc1kgPSAwO1xuICAgIH1cblxuICAgIHBYID0gc1ggKiBQSVhFTF9TVEVQO1xuICAgIHBZID0gc1kgKiBQSVhFTF9TVEVQO1xuXG4gICAgaWYgKCdkZWx0YVknIGluIGUpIHtcbiAgICAgIHBZID0gZS5kZWx0YVk7XG4gICAgfVxuXG4gICAgaWYgKCdkZWx0YVgnIGluIGUpIHtcbiAgICAgIHBYID0gZS5kZWx0YVg7XG4gICAgfVxuXG4gICAgaWYgKGUuc2hpZnRLZXkgJiYgIXBYKSB7XG4gICAgICAvLyBpZiB1c2VyIHNjcm9sbHMgd2l0aCBzaGlmdCBoZSB3YW50cyBob3Jpem9udGFsIHNjcm9sbFxuICAgICAgcFggPSBwWTtcbiAgICAgIHBZID0gMDtcbiAgICB9XG5cbiAgICBpZiAoKHBYIHx8IHBZKSAmJiBlLmRlbHRhTW9kZSkge1xuICAgICAgaWYgKGUuZGVsdGFNb2RlID09PSAxKSB7XG4gICAgICAgIC8vIGRlbHRhIGluIExJTkUgdW5pdHNcbiAgICAgICAgcFggKj0gTElORV9IRUlHSFQ7XG4gICAgICAgIHBZICo9IExJTkVfSEVJR0hUO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZGVsdGEgaW4gUEFHRSB1bml0c1xuICAgICAgICBwWCAqPSBQQUdFX0hFSUdIVDtcbiAgICAgICAgcFkgKj0gUEFHRV9IRUlHSFQ7XG4gICAgICB9XG4gICAgfSAvLyBGYWxsLWJhY2sgaWYgc3BpbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZFxuXG5cbiAgICBpZiAocFggJiYgIXNYKSB7XG4gICAgICBzWCA9IHBYIDwgMSA/IC0xIDogMTtcbiAgICB9XG5cbiAgICBpZiAocFkgJiYgIXNZKSB7XG4gICAgICBzWSA9IHBZIDwgMSA/IC0xIDogMTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3Bpblg6IHNYLFxuICAgICAgc3Bpblk6IHNZLFxuICAgICAgcGl4ZWxYOiBwWCxcbiAgICAgIHBpeGVsWTogcFlcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlTW91c2VFbnRlcigpIHtcbiAgICBpZiAoIXN3aXBlci5lbmFibGVkKSByZXR1cm47XG4gICAgc3dpcGVyLm1vdXNlRW50ZXJlZCA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVNb3VzZUxlYXZlKCkge1xuICAgIGlmICghc3dpcGVyLmVuYWJsZWQpIHJldHVybjtcbiAgICBzd2lwZXIubW91c2VFbnRlcmVkID0gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBhbmltYXRlU2xpZGVyKG5ld0V2ZW50KSB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC50aHJlc2hvbGREZWx0YSAmJiBuZXdFdmVudC5kZWx0YSA8IHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC50aHJlc2hvbGREZWx0YSkge1xuICAgICAgLy8gUHJldmVudCBpZiBkZWx0YSBvZiB3aGVlbCBzY3JvbGwgZGVsdGEgaXMgYmVsb3cgY29uZmlndXJlZCB0aHJlc2hvbGRcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsLnRocmVzaG9sZFRpbWUgJiYgbm93KCkgLSBsYXN0U2Nyb2xsVGltZSA8IHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC50aHJlc2hvbGRUaW1lKSB7XG4gICAgICAvLyBQcmV2ZW50IGlmIHRpbWUgYmV0d2VlbiBzY3JvbGxzIGlzIGJlbG93IGNvbmZpZ3VyZWQgdGhyZXNob2xkXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSAvLyBJZiB0aGUgbW92ZW1lbnQgaXMgTk9UIGJpZyBlbm91Z2ggYW5kXG4gICAgLy8gaWYgdGhlIGxhc3QgdGltZSB0aGUgdXNlciBzY3JvbGxlZCB3YXMgdG9vIGNsb3NlIHRvIHRoZSBjdXJyZW50IG9uZSAoYXZvaWQgY29udGludW91c2x5IHRyaWdnZXJpbmcgdGhlIHNsaWRlcik6XG4gICAgLy8gICBEb24ndCBnbyBhbnkgZnVydGhlciAoYXZvaWQgaW5zaWduaWZpY2FudCBzY3JvbGwgbW92ZW1lbnQpLlxuXG5cbiAgICBpZiAobmV3RXZlbnQuZGVsdGEgPj0gNiAmJiBub3coKSAtIGxhc3RTY3JvbGxUaW1lIDwgNjApIHtcbiAgICAgIC8vIFJldHVybi
1BmYWxzZSBhcyBhIGRlZmF1bHRcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gLy8gSWYgdXNlciBpcyBzY3JvbGxpbmcgdG93YXJkcyB0aGUgZW5kOlxuICAgIC8vICAgSWYgdGhlIHNsaWRlciBoYXNuJ3QgaGl0IHRoZSBsYXRlc3Qgc2xpZGUgb3JcbiAgICAvLyAgIGlmIHRoZSBzbGlkZXIgaXMgYSBsb29wIGFuZFxuICAgIC8vICAgaWYgdGhlIHNsaWRlciBpc24ndCBtb3ZpbmcgcmlnaHQgbm93OlxuICAgIC8vICAgICBHbyB0byBuZXh0IHNsaWRlIGFuZFxuICAgIC8vICAgICBlbWl0IGEgc2Nyb2xsIGV2ZW50LlxuICAgIC8vIEVsc2UgKHRoZSB1c2VyIGlzIHNjcm9sbGluZyB0b3dhcmRzIHRoZSBiZWdpbm5pbmcpIGFuZFxuICAgIC8vIGlmIHRoZSBzbGlkZXIgaGFzbid0IGhpdCB0aGUgZmlyc3Qgc2xpZGUgb3JcbiAgICAvLyBpZiB0aGUgc2xpZGVyIGlzIGEgbG9vcCBhbmRcbiAgICAvLyBpZiB0aGUgc2xpZGVyIGlzbid0IG1vdmluZyByaWdodCBub3c6XG4gICAgLy8gICBHbyB0byBwcmV2IHNsaWRlIGFuZFxuICAgIC8vICAgZW1pdCBhIHNjcm9sbCBldmVudC5cblxuXG4gICAgaWYgKG5ld0V2ZW50LmRpcmVjdGlvbiA8IDApIHtcbiAgICAgIGlmICgoIXN3aXBlci5pc0VuZCB8fCBzd2lwZXIucGFyYW1zLmxvb3ApICYmICFzd2lwZXIuYW5pbWF0aW5nKSB7XG4gICAgICAgIHN3aXBlci5zbGlkZU5leHQoKTtcbiAgICAgICAgZW1pdCgnc2Nyb2xsJywgbmV3RXZlbnQucmF3KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCghc3dpcGVyLmlzQmVnaW5uaW5nIHx8IHN3aXBlci5wYXJhbXMubG9vcCkgJiYgIXN3aXBlci5hbmltYXRpbmcpIHtcbiAgICAgIHN3aXBlci5zbGlkZVByZXYoKTtcbiAgICAgIGVtaXQoJ3Njcm9sbCcsIG5ld0V2ZW50LnJhdyk7XG4gICAgfSAvLyBJZiB5b3UgZ290IGhlcmUgaXMgYmVjYXVzZSBhbiBhbmltYXRpb24gaGFzIGJlZW4gdHJpZ2dlcmVkIHNvIHN0b3JlIHRoZSBjdXJyZW50IHRpbWVcblxuXG4gICAgbGFzdFNjcm9sbFRpbWUgPSBuZXcgd2luZG93LkRhdGUoKS5nZXRUaW1lKCk7IC8vIFJldHVybiBmYWxzZSBhcyBhIGRlZmF1bHRcblxuICAgI
1HJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbGVhc2VTY3JvbGwobmV3RXZlbnQpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLm1vdXNld2hlZWw7XG5cbiAgICBpZiAobmV3RXZlbnQuZGlyZWN0aW9uIDwgMCkge1xuICAgICAgaWYgKHN3aXBlci5pc0VuZCAmJiAhc3dpcGVyLnBhcmFtcy5sb29wICYmIHBhcmFtcy5yZWxlYXNlT25FZGdlcykge1xuICAgICAgICAvLyBSZXR1cm4gdHJ1ZSB0byBhbmltYXRlIHNjcm9sbCBvbiBlZGdlc1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHN3aXBlci5pc0JlZ2lubmluZyAmJiAhc3dpcGVyLnBhcmFtcy5sb29wICYmIHBhcmFtcy5yZWxlYXNlT25FZGdlcykge1xuICAgICAgLy8gUmV0dXJuIHRydWUgdG8gYW5pbWF0ZSBzY3JvbGwgb24gZWRnZXNcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZShldmVudCkge1xuICAgIGxldCBlID0gZXZlbnQ7XG4gICAgbGV0IGRpc2FibGVQYXJlbnRTd2lwZXIgPSB0cnVlO1xuICAgIGlmICghc3dpcGVyLmVuYWJsZWQpIHJldHVybjtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLm1vdXNld2hlZWw7XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgbGV0IHRhcmdldCA9IHN3aXBlci4kZWw7XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsLmV2ZW50c1RhcmdldCAhPT0gJ2NvbnRhaW5lcicpIHtcbiAgICAgIHRhcmdldCA9ICQoc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsLmV2ZW50c1RhcmdldCk7XG4gICAgfVxuXG4gICAgaWYgKCFzd2lwZXIubW91c2VFbnRlcmVkICYmICF0YXJnZXRbMF0uY29udGFpbnMoZS50YXJnZXQpICYmICFwYXJhbXMucmVsZWFzZU9uRWRnZXMpIHJldHVybiB0cnVlO1xuICAgIGlmIChlLm9yaWdpbmFsRXZlbnQpIGUgPSBlLm9yaWdpbmFsRXZlbnQ7IC8vIGpxdWVyeSBmaXhcblxuICAgIGxldCBkZWx0YSA9IDA7XG4gICAgY29uc3QgcnRsRmFjdG9yID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSA/IC0xIDogMTtcbiAgICBjb25zdCBkYXRhID0gbm9ybWFsaXplKGUpO1xuXG4gICAgaWYgKHBhcmFtcy5mb3JjZVRvQXhpcykge1xuICAgICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xuICAgICAgICBpZiAoTWF0aC5hYnMoZGF0YS5waXhlbFgpID4gTWF0aC5hYnMoZGF0YS5waXhlbFkpKSBkZWx0YSA9IC1kYXRhLnBpeGVsWCAqIHJ0bEZhY3RvcjtlbHNlIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChNYXRoLmFicyhkYXRhLnBpeGVsWSkgPiBNYXRoLmFicyhkYXRhLnBpeGVsWCkpIGRlbHRhID0gLWRhdGEucGl4ZWxZO2Vsc2UgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbHRhID0gTWF0aC5hYnMoZGF0YS5waXhlbFgpID4gTWF0aC5hYnMoZGF0YS5waXhlbFkpID8gLWRhdGEucGl4ZWxYICogcnRsRmFjdG9yIDogLWRhdGEucGl4ZWxZO1xuICAgIH1cblxuICAgIGlmIChkZWx0YSA9PT0gMCkgcmV0dXJuIHRydWU7XG4gICAgaWYgKHBhcmFtcy5pbnZlcnQpIGRlbHRhID0gLWRlbHRhOyAvLyBHZXQgdGhlIHNjcm9sbCBwb3NpdGlvbnNcblxuICAgIGxldCBwb3NpdGlvbnMgPSBzd2lwZXIuZ2V0VHJhbnNsYXRlKCkgKyBkZWx0YSAqIHBhcmFtcy5zZW5zaXRpdml0eTtcbiAgICBpZiAocG9zaXRpb25zID49IHN3aXBlci5taW5UcmFuc2xhdGUoKSkgcG9zaXRpb25zID0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpO1xuICAgIGlmIChwb3NpdGlvbnMgPD0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpKSBwb3NpdGlvbnMgPSBzd2lwZXIubWF4VHJhbnNsYXRlKCk7IC8vIFdoZW4gbG9vcCBpcyB0cnVlOlxuICAgIC8vICAgICB0aGUgZGlzYWJsZVBhcmVudFN3aXBlciB3aWxsIGJlIHRydWUuXG4gICAgLy8gV2hlbiBsb29wIGlzIGZhbHNlOlxuICAgIC8vICAgICBpZiB0aGUgc2Nyb2xsIHBvc2l0aW9ucyBpcyBub3Qgb24gZWRnZSxcbiAgICAvLyAgICAgdGhlbiB0aGUgZGlzYWJsZVBhcmVudFN3aXBlciB3aWxsIGJlIHRydWUuXG4gICAgLy8gICAgIGlmIHRoZSBzY3JvbGwgb24gZWRnZSBwb3NpdGlvbnMsXG4gICAgLy8gICAgIHRoZW4gdGhlIGRpc2FibGVQYXJlbnRTd2lwZXIgd2lsbCBiZSBmYWxzZS5cblxuICAgIGRpc2FibGVQYXJlbnRTd2lwZXIgPSBzd2lwZXIucGFyYW1zLmxvb3AgPyB0cnVlIDogIShwb3NpdGlvbnMgPT09IHN3aXBlci5taW5UcmFuc2xhdGUoKSB8fCBwb3NpdGlvbnMgPT09IHN3aXBlci5tYXhUcmFuc2xhdGUoKSk7XG4gICAgaWYgKGRpc2FibGVQYXJlbnRTd2lwZXIgJiYgc3dpcGVyLnBhcmFtcy5uZXN0ZWQpIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuZnJlZU1vZGUgfHwgIXN3aXBlci5wYXJhbXMuZnJlZU1vZGUuZW5hYmxlZCkge1xuICAgICAgLy8gUmVnaXN0ZXIgdGhlIG5ldyBldmVudCBpbiBhIHZhcmlhYmxlIHdoaWNoIHN0b3JlcyB0aGUgcmVsZXZhbnQgZGF0YVxuICAgICAgY29uc3QgbmV3RXZlbnQgPSB7XG4gICAgICAgIHRpbWU6IG5vdygpLFxuICAgICAgICBkZWx0YTogTWF0aC5hYnMoZGVsdGEpLFxuICAgICAgICBkaXJlY3Rpb246IE1hdGguc2lnbihkZWx0YSksXG4gICAgICAgIHJhdzogZXZlbnRcbiAgICAgIH07IC8vIEtlZXAgdGhlIG1vc3QgcmVjZW50IGV2ZW50c1xuXG4gICAgICBpZiAocmVjZW50V2hlZWxFdmVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgcmVjZW50V2hlZWxFdmVudHMuc2hpZnQoKTsgLy8gb25seSBzdG9yZSB0aGUgbGFzdCBOIGV2ZW50c1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwcmV2RXZlbnQgPSByZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggPyByZWNlbnRXaGVlbEV2ZW50c1tyZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcbiAgICAgIHJlY2VudFdoZWVsRXZlbnRzLnB1c2gobmV3RXZlbnQpOyAvLyBJZiB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgcHJldmlvdXMgcmVjb3JkZWQgZXZlbnQ6XG4gICAgICAvLyAgIElmIGRpcmVjdGlvbiBoYXMgY2hhbmdlZCBvclxuICAgICAgLy8gICBpZiB0aGUgc2Nyb2xsIGlzIHF1aWNrZXIgdGhhbiB0aGUgcHJldmlvdXMgb25lOlxuICAgICAgLy8gICAgIEFuaW1hdGUgdGhlIHNsaWRlci5cbiAgICAgIC8vIEVsc2UgKHRoaXMgaXMgdGhlIGZpcnN0IHRpbWUgdGhlIHdoZWVsIGlzIG1vdmVkKTpcbiAgICAgIC8vICAgICBBbmltYXRlIHRoZSBzbGlkZXIuXG5cbiAgICAgIGlmIChwcmV2RXZlbnQpIHtcbiAgICAgICAgaWYgKG5ld0V2ZW50LmRpcmVjdGlvbiAhPT0gcHJldkV2ZW50LmRpcmVjdGlvbiB8fCBuZXdFdmVudC5kZWx0YSA+IHByZXZFdmVudC5kZWx0YSB8fCBuZXdFdmVudC50aW1lID4gcHJldkV2ZW50LnRpbWUgKyAxNTApIHtcbiAgICAgICAgICBhbmltYXRlU2xpZGVyKG5ld0V2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYW5pbWF0ZVNsaWRlcihuZXdFdmVudCk7XG4gICAgICB9IC8vIElmIGl0J3MgdGltZSB0byByZWxlYXNlIHRoZSBzY3JvbGw6XG4gICAgICAvLyAgIFJldHVybi
1Bub3cgc28geW91IGRvbid0IGhpdCB0aGUgcHJldmVudERlZmF1bHQuXG5cblxuICAgICAgaWYgKHJlbGVhc2VTY3JvbGwobmV3RXZlbnQpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGcmVlbW9kZSBvciBzY3JvbGxDb250YWluZXI6XG4gICAgICAvLyBJZiB3ZSByZWNlbnRseSBzbmFwcGVkIGFmdGVyIGEgbW9tZW50dW0gc2Nyb2xsLCB0aGVuIGlnbm9yZSB3aGVlbCBldmVudHNcbiAgICAgIC8vIHRvIGdpdmUgdGltZSBmb3IgdGhlIGRlY2VsZXJhdGlvbiB0byBmaW5pc2guIFN0b3AgaWdub3JpbmcgYWZ0ZXIgNTAwIG1zZWNzXG4gICAgICAvLyBvciBpZiBpdCdzIGEgbmV3IHNjcm9sbCAobGFyZ2VyIGRlbHRhIG9yIGludmVyc2Ugc2lnbiBhcyBsYXN0IGV2ZW50IGJlZm9yZVxuICAgICAgLy8gYW4gZW5kLW9mLW1vbWVudHVtIHNuYXApLlxuICAgICAgY29uc3QgbmV3RXZlbnQgPSB7XG4gICAgICAgIHRpbWU6IG5vdygpLFxuICAgICAgICBkZWx0YTogTWF0aC5hYnMoZGVsdGEpLFxuICAgICAgICBkaXJlY3Rpb246IE1hdGguc2lnbihkZWx0YSlcbiAgICAgIH07XG4gICAgICBjb25zdCBpZ25vcmVXaGVlbEV2ZW50cyA9IGxhc3RFdmVudEJlZm9yZVNuYXAgJiYgbmV3RXZlbnQudGltZSA8IGxhc3RFdmVudEJlZm9yZVNuYXAudGltZSArIDUwMCAmJiBuZXdFdmVudC5kZWx0YSA8PSBsYXN0RXZlbnRCZWZvcmVTbmFwLmRlbHRhICYmIG5ld0V2ZW50LmRpcmVjdGlvbiA9PT0gbGFzdEV2ZW50QmVmb3JlU25hcC5kaXJlY3Rpb247XG5cbiAgICAgIGlmICghaWdub3JlV2hlZWxFdmVudHMpIHtcbiAgICAgICAgbGFzdEV2ZW50QmVmb3JlU25hcCA9IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICAgICAgc3dpcGVyLmxvb3BGaXgoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwb3NpdGlvbiA9IHN3aXBlci5nZXRUcmFuc2xhdGUoKSArIGRlbHRhICogcGFyYW1zLnNlbnNpdGl2aXR5O1xuICAgICAgICBjb25zdCB3YXNCZWdpbm5pbmcgPSBzd2lwZXIuaXNCZWdpbm5pbmc7XG4gICAgICAgIGNvbnN0IHdhc0VuZCA9IHN3aXBlci5pc0VuZDtcbiAgICAgICAgaWYgKHBvc2l0aW9uID49IHN3aXBlci5taW5UcmFuc2xhdGUoKSkgcG9zaXRpb24gPSBzd2lwZXIubWluVHJhbnNsYXRlKCk7XG4gICAgICAgIGlmIChwb3NpdGlvbiA8PSBzd2lwZXIubWF4VHJhbnNsYXRlKCkpIHBvc2l0aW9uID0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpO1xuICAgICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbigwKTtcbiAgICAgICAgc3dpcGVyLnNldFRyYW5zbGF0ZShwb3NpdGlvbik7XG4gICAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcygpO1xuICAgICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcbiAgICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcblxuICAgICAgICBpZiAoIXdhc0JlZ2lubmluZyAmJiBzd2lwZXIuaXNCZWdpbm5pbmcgfHwgIXdhc0VuZCAmJiBzd2lwZXIuaXNFbmQpIHtcbiAgICAgICAgICBzd2lwZXIudXBkYXRlU2xpZGVzQ2xhc3NlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuZnJlZU1vZGUuc3RpY2t5KSB7XG4gICAgICAgICAgLy8gV2hlbiB3aGVlbCBzY3JvbGxpbmcgc3RhcnRzIHdpdGggc3RpY2t5IChha2Egc25hcCkgZW5hYmxlZCwgdGhlbiBkZXRlY3RcbiAgICAgICAgICAvLyB0aGUgZW5kIG9mIGEgbW9tZW50dW0gc2Nyb2xsIGJ5IHN0b3JpbmcgcmVjZW50IChOPTE1Pykgd2hlZWwgZXZlbnRzLlxuICAgICAgICAgIC8vIDEuIGRvIGFsbCBOIGV2ZW50cyBoYXZlIGRlY3JlYXNpbmcgb3Igc2FtZSAoYWJzb2x1dGUgdmFsdWUpIGRlbHRhP1xuICAgICAgICAgIC8vIDIuIGRpZCBhbGwgTiBldmVudHMgYXJyaXZlIGluIHRoZSBsYXN0IE0gKE09NTAwPykgbXNlY3M/XG4gICAgICAgICAgLy8gMy4gZG9lcyB0aGUgZWFybGllc3QgZXZlbnQgaGF2ZSBhbiAoYWJzb2x1dGUgdmFsdWUpIGRlbHRhIHRoYXQnc1xuICAgICAgICAgIC8vICAgIGF0IGxlYXN0IFAgKFA9MT8pIGxhcmdlciB0aGFuIHRoZSBtb3N0IHJlY2VudCBldmVudCdzIGRlbHRhP1xuICAgICAgICAgIC8vIDQuIGRvZXMgdGhlIGxhdGVzdCBldmVudCBoYXZlIGEgZGVsdGEgdGhhdCdzIHNtYWxsZXIgdGhhbiBRIChRPTY/KSBwaXhlbHM/XG4gICAgICAgICAgLy8gSWYgMS00IGFyZSBcInllc1wiIHRoZW4gd2UncmUgbmVhciB0aGUgZW5kIG9mIGEgbW9tZW50dW0gc2Nyb2xsIGRlY2VsZXJhdGlvbi5cbiAgICAgICAgICAvLyBTbmFwIGltbWVkaWF0ZWx5IGFuZCBpZ25vcmUgcmVtYWluaW5nIHdoZWVsIGV2ZW50cyBpbiB0aGlzIHNjcm9sbC5cbiAgICAgICAgICAvLyBTZWUgY29tbWVudCBhYm92ZSBmb3IgXCJyZW1haW5pbmcgd2hlZWwgZXZlbnRzIGluIHRoaXMgc2Nyb2xsXCIgZGV0ZXJtaW5hdGlvbi5cbiAgICAgICAgICAvLyBJZiAxLTQgYXJlbid0IHNhdGlzZmllZCwgdGhlbiB3YWl0IHRvIHNuYXAgdW50aWwgNTAwbXMgYWZ0ZXIgdGhlIGxhc3QgZXZlbnQuXG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgIHRpbWVvdXQgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICBpZiAocmVjZW50V2hlZWxFdmVudHMubGVuZ3RoID49IDE1KSB7XG4gICAgICAgICAgICByZWNlbnRXaGVlbEV2ZW50cy5zaGlmdCgpOyAvLyBvbmx5IHN0b3JlIHRoZSBsYXN0IE4gZXZlbnRzXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcHJldkV2ZW50ID0gcmVjZW50V2hlZWxFdmVudHMubGVuZ3RoID8gcmVjZW50V2hlZWxFdmVudHNbcmVjZW50V2hlZWxFdmVudHMubGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgY29uc3QgZmlyc3RFdmVudCA9IHJlY2VudFdoZWVsRXZlbnRzWzBdO1xuICAgICAgICAgIHJlY2VudFdoZWVsRXZlbnRzLnB1c2gobmV3RXZlbnQpO1xuXG4gICAgICAgICAgaWYgKHByZXZFdmVudCAmJiAobmV3RXZlbnQuZGVsdGEgPiBwcmV2RXZlbnQuZGVsdGEgfHwgbmV3RXZlbnQuZGlyZWN0aW9uICE9PSBwcmV2RXZlbnQuZGlyZWN0aW9uKSkge1xuICAgICAgICAgICAgLy8gSW5jcmVhc2luZyBvciByZXZlcnNl
1LXNpZ24gZGVsdGEgbWVhbnMgdGhlIHVzZXIgc3RhcnRlZCBzY3JvbGxpbmcgYWdhaW4uIENsZWFyIHRoZSB3aGVlbCBldmVudCBsb2cuXG4gICAgICAgICAgICByZWNlbnRXaGVlbEV2ZW50cy5zcGxpY2UoMCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZWNlbnRXaGVlbEV2ZW50cy5sZW5ndGggPj0gMTUgJiYgbmV3RXZlbnQudGltZSAtIGZpcnN0RXZlbnQudGltZSA8IDUwMCAmJiBmaXJzdEV2ZW50LmRlbHRhIC0gbmV3RXZlbnQuZGVsdGEgPj0gMSAmJiBuZXdFdmVudC5kZWx0YSA8PSA2KSB7XG4gICAgICAgICAgICAvLyBXZSdyZSBhdCB0aGUgZW5kIG9mIHRoZSBkZWNlbGVyYXRpb24gb2YgYSBtb21lbnR1bSBzY3JvbGwsIHNvIHRoZXJlJ3Mgbm8gbmVlZFxuICAgICAgICAgICAgLy8gdG8gd2FpdCBmb3IgbW9yZSBldmVudHMuIFNuYXAgQVNBUCBvbiB0aGUgbmV4dCB0aWNrLlxuICAgICAgICAgICAgLy8gQWxzbywgYmVjYXVzZSB0aGVyZSdzIHNvbWUgcmVtYWluaW5nIG1vbWVudHVtIHdlJ2xsIGJpYXMgdGhlIHNuYXAgaW4gdGhlXG4gICAgICAgICAgICAvLyBkaXJlY3Rpb24gb2YgdGhlIG9uZ29pbmcgc2Nyb2xsIGJlY2F1c2UgaXQncyBiZXR0ZXIgVVggZm9yIHRoZSBzY3JvbGwgdG8gc25hcFxuICAgICAgICAgICAgLy8gaW4gdGhlIHNhbWUgZGlyZWN0aW9uIGFzIHRoZSBzY3JvbGwgaW5zdGVhZCBvZiByZXZlcnNpbmcgdG8gc25hcC4gIFRoZXJlZm9yZSxcbiAgICAgICAgICAgIC8vIGlmIGl0J3MgYWxyZWFkeSBzY3JvbGxlZCBtb3JlIHRoYW4gMjAlIGluIHRoZSBjdXJyZW50IGRpcmVjdGlvbiwga2VlcCBnb2luZy5cbiAgICAgICAgICAgIGNvbnN0IHNuYXBUb1RocmVzaG9sZCA9IGRlbHRhID4gMCA/IDAuOCA6IDAuMjtcbiAgICAgICAgICAgIGxhc3RFdmVudEJlZm9yZVNuYXAgPSBuZXdFdmVudDtcbiAgICAgICAgICAgIHJlY2VudFdoZWVsRXZlbnRzLnNwbGljZSgwKTtcbiAgICAgICAgICAgIHRpbWVvdXQgPSBuZXh0VGljaygoKSA9PiB7XG4gICAgICAgICAgICAgIHN3aXBlci5zbGlkZVRvQ2xvc2VzdChzd2lwZXIucGFyYW1zLnNwZWVkLCB0cnVlLCB1bmRlZmluZWQsIHNuYXBUb1RocmVzaG9sZCk7XG4gICAgICAgICAgICB9LCAwKTsgLy8gbm8gZGVsYXk7IG1vdmUgb24gbmV4dCB0aWNrXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCF0aW1lb3V0KSB7XG4gICAgICAgICAgICAvLyBpZiB3ZSBnZXQgaGVyZSwgdGhlbiB3ZSBoYXZlbid0IGRldGVjdGVkIHRoZSBlbmQgb2YgYSBtb21lbnR1bSBzY3JvbGwsIHNvXG4gICAgICAgICAgICAvLyB3ZSdsbCBjb25zaWRlciBhIHNjcm9sbCBcImNvbXBsZXRlXCIgd2hlbiB0aGVyZSBoYXZlbid0IGJlZW4gYW55IHdoZWVsIGV2ZW50c1xuICAgICAgICAgICAgLy8gZm9yIDUwMG1zLlxuICAgICAgICAgICAgdGltZW91dCA9IG5leHRUaWNrKCgpID0+IHtcbiAgICAgICAgICAgICAgY29uc3Qgc25hcFRvVGhyZXNob2xkID0gMC41O1xuICAgICAgICAgICAgICBsYXN0RXZlbnRCZWZvcmVTbmFwID0gbmV3RXZlbnQ7XG4gICAgICAgICAgICAgIHJlY2VudFdoZWVsRXZlbnRzLnNwbGljZSgwKTtcbiAgICAgICAgICAgICAgc3dpcGVyLnNsaWRlVG9DbG9zZXN0KHN3aXBlci5wYXJhbXMuc3BlZWQsIHRydWUsIHVuZGVmaW5lZCwgc25hcFRvVGhyZXNob2xkKTtcbiAgICAgICAgICAgIH0sIDUwMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIEVtaXQgZXZlbnRcblxuXG4gICAgICAgIGlmICghaWdub3JlV2hlZWxFdmVudHMpIGVtaXQoJ3Njcm9sbCcsIGUpOyAvLyBTdG9wIGF1dG9wbGF5XG5cbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b3BsYXkgJiYgc3dpcGVyLnBhcmFtcy5hdXRvcGxheURpc2FibGVPbkludGVyYWN0aW9uKSBzd2lwZXIuYXV0b3BsYXkuc3RvcCgpOyAvLyBSZXR1cm4gcGFnZSBzY3JvbGwgb24gZWRnZSBwb3NpdGlvbnNcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IHN3aXBlci5taW5UcmFuc2xhdGUoKSB8fCBwb3NpdGlvbiA9PT0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpKSByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpO2Vsc2UgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGV2ZW50cyhtZXRob2QpIHtcbiAgICBsZXQgdGFyZ2V0ID0gc3dpcGVyLiRlbDtcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLm1vdXNld2hlZWwuZXZlbnRzVGFyZ2V0ICE9PSAnY29udGFpbmVyJykge1xuICAgICAgdGFyZ2V0ID0gJChzd2lwZXIucGFyYW1zLm1vdXNld2hlZWwuZXZlbnRzVGFyZ2V0KTtcbiAgICB9XG5cbiAgICB0YXJnZXRbbWV0aG9kXSgnbW91c2VlbnRlcicsIGhhbmRsZU1vdXNlRW50ZXIpO1xuICAgIHRhcmdldFttZXRob2RdKCdtb3VzZWxlYXZlJywgaGFuZGxlTW91c2VMZWF2ZSk7XG4gICAgdGFyZ2V0W21ldGhvZF0oJ3doZWVsJywgaGFuZGxlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuYWJsZSgpIHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICBzd2lwZXIud3JhcHBlckVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3doZWVsJywgaGFuZGxlKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChzd2lwZXIubW91c2V3aGVlbC5lbmFibGVkKSByZXR1cm4gZmFsc2U7XG4gICAgZXZlbnRzKCdvbicpO1xuICAgIHN3aXBlci5tb3VzZXdoZWVsLmVuYWJsZWQgPSB0cnVlO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gZGlzYWJsZSgpIHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICBzd2lwZXIud3JhcHBlckVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIXN3aXBlci5tb3VzZXdoZWVsLmVuYWJsZWQpIHJldHVybiBmYWxzZTtcbiAgICBldmVudHMoJ29mZicpO1xuICAgIHN3aXBlci5tb3VzZXdoZWVsLmVuYWJsZWQgPSBmYWxzZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIG9uKCdpbml0JywgKCkgPT4ge1xuICAgIGlmICghc3dpcGVyLnBhcmFtcy5tb3VzZXdoZWVsLmVuYWJsZWQgJiYgc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICBkaXNhYmxlKCk7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMubW91c2V3aGVlbC5lbmFibGVkKSBlbmFibGUoKTtcbiAgfSk7XG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgIGVuYWJsZSgpO1xuICAgIH1cblxuICAgIGlmIChzd2lwZXIubW91c2V3aGVlbC5lbmFibGVkKSBkaXNhYmxlKCk7XG4gIH0pO1xuICBPYmplY3QuYXNzaWduKHN3aXBlci5tb3VzZXdoZWVsLCB7XG4gICAgZW5hYmxlLFxuICAgIGRpc2FibGVcbiAgfSk7XG59IiwiaW1wb3J0IHsgZ2V0RG9jdW1lbnQgfSBmcm9tICdzc3Itd2luZG93JztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRJZk5vdERlZmluZWQoc3dpcGVyLCBvcmlnaW5hbFBhcmFtcywgcGFyYW1zLCBjaGVja1Byb3BzKSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcblxuICBpZiAoc3dpcGVyLnBhcmFtcy5jcmVhdGVFbGVtZW50cykge1xuICAgIE9iamVjdC5rZXlzKGNoZWNrUHJvcHMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICghcGFyYW1zW2tleV0gJiYgcGFyYW1zLmF1dG8gPT09IHRydWUpIHtcbiAgICAgICAgbGV0IGVsZW1lbnQgPSBzd2lwZXIuJGVsLmNoaWxkcmVuKGAuJHtjaGVja1Byb3BzW2tleV19YClbMF07XG5cbiAgICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgICAgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gY2hlY2tQcm9wc1trZXldO1xuICAgICAgICAgI
1HN3aXBlci4kZWwuYXBwZW5kKGVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcGFyYW1zW2tleV0gPSBlbGVtZW50O1xuICAgICAgICBvcmlnaW5hbFBhcmFtc1trZXldID0gZWxlbWVudDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBwYXJhbXM7XG59IiwiaW1wb3J0IGNyZWF0ZUVsZW1lbnRJZk5vdERlZmluZWQgZnJvbSAnLi4vLi4vc2hhcmVkL2NyZWF0ZS1lbGVtZW50LWlmLW5vdC1kZWZpbmVkLmpzJztcbmltcG9ydCAkIGZyb20gJy4uLy4uL3NoYXJlZC9kb20uanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTmF2aWdhdGlvbih7XG4gIHN3aXBlcixcbiAgZXh0ZW5kUGFyYW1zLFxuICBvbixcbiAgZW1pdFxufSkge1xuICBleHRlbmRQYXJhbXMoe1xuICAgIG5hdmlnYXRpb246IHtcbiAgICAgIG5leHRFbDogbnVsbCxcbiAgICAgIHByZXZFbDogbnVsbCxcbiAgICAgIGhpZGVPbkNsaWNrOiBmYWxzZSxcbiAgICAgIGRpc2FibGVkQ2xhc3M6ICdzd2lwZXItYnV0dG9uLWRpc2FibGVkJyxcbiAgICAgIGhpZGRlbkNsYXNzOiAnc3dpcGVyLWJ1dHRvbi1oaWRkZW4nLFxuICAgICAgbG9ja0NsYXNzOiAnc3dpcGVyLWJ1dHRvbi1sb2NrJyxcbiAgICAgIG5hdmlnYXRpb25EaXNhYmxlZENsYXNzOiAnc3dpcGVyLW5hdmlnYXRpb24tZGlzYWJsZWQnXG4gICAgfVxuICB9KTtcbiAgc3dpcGVyLm5hdmlnYXRpb24gPSB7XG4gICAgbmV4dEVsOiBudWxsLFxuICAgICRuZXh0RWw6IG51bGwsXG4gICAgcHJldkVsOiBudWxsLFxuICAgICRwcmV2RWw6IG51bGxcbiAgfTtcblxuICBmdW5jdGlvbiBnZXRFbChlbCkge1xuICAgIGxldCAkZWw7XG5cbiAgICBpZiAoZWwpIHtcbiAgICAgICRlbCA9ICQoZWwpO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy51bmlxdWVOYXZFbGVtZW50cyAmJiB0eXBlb2YgZWwgPT09ICdzdHJpbmcnICYmICRlbC5sZW5ndGggPiAxICYmIHN3aXBlci4kZWwuZmluZChlbCkubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICRlbCA9IHN3aXBlci4kZWwuZmluZChlbCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICRlbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvZ2dsZUVsKCRlbCwgZGlzYWJsZWQpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLm5hdmlnYXRpb247XG5cbiAgICBpZiAoJGVsICYmICRlbC5sZW5ndGggPiAwKSB7XG4gICAgICAkZWxbZGlzYWJsZWQgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJ10ocGFyYW1zLmRpc2FibGVkQ2xhc3MpO1xuICAgICAgaWYgKCRlbFswXSAmJiAkZWxbMF0udGFnTmFtZSA9PT0gJ0JVVFRPTicpICRlbFswXS5kaXNhYmxlZCA9IGRpc2FibGVkO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy53YXRjaE92ZXJmbG93ICYmIHN3aXBlci5lbmFibGVkKSB7XG4gICAgICAgICRlbFtzd2lwZXIuaXNMb2NrZWQgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJ10ocGFyYW1zLmxvY2tDbGFzcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKCkge1xuICAgIC8vIFVwZGF0ZSBOYXZpZ2F0aW9uIEJ1dHRvbnNcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSByZXR1cm47XG4gICAgY29uc3Qge1xuICAgICAgJG5leHRFbCxcbiAgICAgICRwcmV2RWxcbiAgICB9ID0gc3dpcGVyLm5hdmlnYXRpb247XG4gICAgdG9nZ2xlRWwoJHByZXZFbCwgc3dpcGVyLmlzQmVnaW5uaW5nICYmICFzd2lwZXIucGFyYW1zLnJld2luZCk7XG4gICAgdG9nZ2xlRWwoJG5leHRFbCwgc3dpcGVyLmlzRW5kICYmICFzd2lwZXIucGFyYW1zLnJld2luZCk7XG4gIH1cblxuICBmdW5jdGlvbiBvblByZXZDbGljayhlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGlmIChzd2lwZXIuaXNCZWdpbm5pbmcgJiYgIXN3aXBlci5wYXJhbXMubG9vcCAmJiAhc3dpcGVyLnBhcmFtcy5yZXdpbmQpIHJldHVybjtcbiAgICBzd2lwZXIuc2xpZGVQcmV2KCk7XG4gICAgZW1pdCgnbmF2aWdhdGlvblByZXYnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uTmV4dENsaWNrKGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgaWYgKHN3aXBlci5pc0VuZCAmJiAhc3dpcGVyLnBhcmFtcy5sb29wICYmICFzd2lwZXIucGFyYW1zLnJld2luZCkgcmV0dXJuO1xuICAgIHN3aXBlci5zbGlkZU5leHQoKTtcbiAgICBlbWl0KCduYXZpZ2F0aW9uTmV4dCcpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5pdCgpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLm5hdmlnYXRpb247XG4gICAgc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uID0gY3JlYXRlRWxlbWVudElmTm90RGVmaW5lZChzd2lwZXIsIHN3aXBlci5vcmlnaW5hbFBhcmFtcy5uYXZpZ2F0aW9uLCBzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24sIHtcbiAgICAgIG5leHRFbDogJ3N3aXBlci1idXR0b24tbmV4dCcsXG4gICAgICBwcmV2RWw6ICdzd2lwZXItYnV0dG9uLXByZXYnXG4gICAgfSk7XG4gICAgaWYgKCEocGFyYW1zLm5leHRFbCB8fCBwYXJhbXMucHJldkVsKSkgcmV0dXJuO1xuICAgIGNvbnN0ICRuZXh0RWwgPSBnZXRFbChwYXJhbXMubmV4dEVsKTtcbiAgICBjb25zdCAkcHJldkVsID0gZ2V0RWwocGFyYW1zLnByZXZFbCk7XG5cbiAgICBpZiAoJG5leHRFbCAmJiAkbmV4dEVsLmxlbmd0aCA+IDApIHtcbiAgICAgICRuZXh0RWwub24oJ2NsaWNrJywgb25OZXh0Q2xpY2spO1xuICAgIH1cblxuICAgIGlmICgkcHJldkVsICYmICRwcmV2RWwubGVuZ3RoID4gMCkge1xuICAgICAgJHByZXZFbC5vbignY2xpY2snLCBvblByZXZDbGljayk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmFzc2lnbihzd2lwZXIubmF2aWdhdGlvbiwge1xuICAgICAgJG5leHRFbCxcbiAgICAgIG5leHRFbDogJG5leHRFbCAmJiAkbmV4dEVsWzBdLFxuICAgICAgJHByZXZFbCxcbiAgICAgIHByZXZFbDogJHByZXZFbCAmJiAkcHJldkVsWzBdXG4gICAgfSk7XG5cbiAgICBpZiAoIXN3aXBlci5lbmFibGVkKSB7XG4gICAgICBpZiAoJG5leHRFbCkgJG5leHRFbC5hZGRDbGFzcyhwYXJhbXMubG9ja0NsYXNzKTtcbiAgICAgIGlmICgkcHJldkVsKSAkcHJldkVsLmFkZENsYXNzKHBhcmFtcy5sb2NrQ2xhc3MpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgY29uc3Qge1xuICAgICAgJG5leHRFbCxcbiAgICAgICRwcmV2RWxcbiAgICB9ID0gc3dpcGVyLm5hdmlnYXRpb247XG5cbiAgICBpZiAoJG5leHRFbCAmJiAkbmV4dEVsLmxlbmd0aCkge1xuICAgICAgJG5leHRFbC5vZmYoJ2NsaWNrJywgb25OZXh0Q2xpY2spO1xuICAgICAgJG5leHRFbC5yZW1vdmVDbGFzcyhzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24uZGlzYWJsZWRDbGFzcyk7XG4gICAgfVxuXG4gICAgaWYgKCRwcmV2RWwgJiYgJHByZXZFbC5sZW5ndGgpIHtcbiAgICAgICRwcmV2RWwub2ZmKCdjbGljaycsIG9uUHJldkNsaWNrKTtcbiAgICAgICRwcmV2RWwucmVtb3ZlQ2xhc3Moc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmRpc2FibGVkQ2xhc3MpO1xuICAgIH1cbiAgfVxuXG4gIG9uKCdpbml0JywgKCkgPT4ge1xuICAgIGlmIChzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24uZW5hYmxlZCA9PT0gZmFsc2UpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgZGlzYWJsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbml0KCk7XG4gICAgICB1cGRhdGUoKTtcbiAgICB9XG4gI
1H0pO1xuICBvbigndG9FZGdlIGZyb21FZGdlIGxvY2sgdW5sb2NrJywgKCkgPT4ge1xuICAgIHVwZGF0ZSgpO1xuICB9KTtcbiAgb24oJ2Rlc3Ryb3knLCAoKSA9PiB7XG4gICAgZGVzdHJveSgpO1xuICB9KTtcbiAgb24oJ2VuYWJsZSBkaXNhYmxlJywgKCkgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgICRuZXh0RWwsXG4gICAgICAkcHJldkVsXG4gICAgfSA9IHN3aXBlci5uYXZpZ2F0aW9uO1xuXG4gICAgaWYgKCRuZXh0RWwpIHtcbiAgICAgICRuZXh0RWxbc3dpcGVyLmVuYWJsZWQgPyAncmVtb3ZlQ2xhc3MnIDogJ2FkZENsYXNzJ10oc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmxvY2tDbGFzcyk7XG4gICAgfVxuXG4gICAgaWYgKCRwcmV2RWwpIHtcbiAgICAgICRwcmV2RWxbc3dpcGVyLmVuYWJsZWQgPyAncmVtb3ZlQ2xhc3MnIDogJ2FkZENsYXNzJ10oc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmxvY2tDbGFzcyk7XG4gICAgfVxuICB9KTtcbiAgb24oJ2NsaWNrJywgKF9zLCBlKSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgJG5leHRFbCxcbiAgICAgICRwcmV2RWxcbiAgICB9ID0gc3dpcGVyLm5hdmlnYXRpb247XG4gICAgY29uc3QgdGFyZ2V0RWwgPSBlLnRhcmdldDtcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24uaGlkZU9uQ2xpY2sgJiYgISQodGFyZ2V0RWwpLmlzKCRwcmV2RWwpICYmICEkKHRhcmdldEVsKS5pcygkbmV4dEVsKSkge1xuICAgICAgaWYgKHN3aXBlci5wYWdpbmF0aW9uICYmIHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbiAmJiBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uY2xpY2thYmxlICYmIChzd2lwZXIucGFnaW5hdGlvbi5lbCA9PT0gdGFyZ2V0RWwgfHwgc3dpcGVyLnBhZ2luYXRpb24uZWwuY29udGFpbnModGFyZ2V0RWwpKSkgcmV0dXJuO1xuICAgICAgbGV0IGlzSGlkZGVuO1xuXG4gICAgICBpZiAoJG5leHRFbCkge1xuICAgICAgICBpc0hpZGRlbiA9ICRuZXh0RWwuaGFzQ2xhc3Moc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmhpZGRlbkNsYXNzKTtcbiAgICAgIH0gZWxzZSBpZiAoJHByZXZFbCkge1xuICAgICAgICBpc0hpZGRlbiA9ICRwcmV2RWwuaGFzQ2xhc3Moc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmhpZGRlbkNsYXNzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzSGlkZGVuID09PSB0cnVlKSB7XG4gICAgICAgIGVtaXQoJ25hdmlnYXRpb25TaG93Jyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbWl0KCduYXZpZ2F0aW9uSGlkZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoJG5leHRFbCkge1xuICAgICAgICAkbmV4dEVsLnRvZ2dsZUNsYXNzKHN3aXBlci5wYXJhbXMubmF2aWdhdGlvbi5oaWRkZW5DbGFzcyk7XG4gICAgICB9XG5cbiAgICAgIGlmICgkcHJldkVsKSB7XG4gICAgICAgICRwcmV2RWwudG9nZ2xlQ2xhc3Moc3dpcGVyLnBhcmFtcy5uYXZpZ2F0aW9uLmhpZGRlbkNsYXNzKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGVuYWJsZSA9ICgpID0+IHtcbiAgICBzd2lwZXIuJGVsLnJlbW92ZUNsYXNzKHN3aXBlci5wYXJhbXMubmF2aWdhdGlvbi5uYXZpZ2F0aW9uRGlzYWJsZWRDbGFzcyk7XG4gICAgaW5pdCgpO1xuICAgIHVwZGF0ZSgpO1xuICB9O1xuXG4gIGNvbnN0IGRpc2FibGUgPSAoKSA9PiB7XG4gICAgc3dpcGVyLiRlbC5hZGRDbGFzcyhzd2lwZXIucGFyYW1zLm5hdmlnYXRpb24ubmF2aWdhdGlvbkRpc2FibGVkQ2xhc3MpO1xuICAgIGRlc3Ryb3koKTtcbiAgfTtcblxuICBPYmplY3QuYXNzaWduKHN3aXBlci5uYXZpZ2F0aW9uLCB7XG4gICAgZW5hYmxlLFxuICAgIGRpc2FibGUsXG4gICAgdXBkYXRlLFxuICAgIGluaXQsXG4gICAgZGVzdHJveVxuICB9KTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjbGFzc2VzVG9TZWxlY3RvcihjbGFzc2VzID0gJycpIHtcbiAgcmV0dXJuIGAuJHtjbGFzc2VzLnRyaW0oKS5yZXBsYWNlKC8oW1xcLjohXFwvXSkvZywgJ1xcXFwkMScpIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgLnJlcGxhY2UoLyAvZywgJy4nKX1gO1xufSIsImltcG9ydCAkIGZyb20gJy4uLy4uL3NoYXJlZC9kb20uanMnO1xuaW1wb3J0IGNsYXNzZXNUb1NlbGVjdG9yIGZyb20gJy4uLy4uL3NoYXJlZC9jbGFzc2VzLXRvLXNlbGVjdG9yLmpzJztcbmltcG9ydCBjcmVhdGVFbGVtZW50SWZOb3REZWZpbmVkIGZyb20gJy4uLy4uL3NoYXJlZC9jcmVhdGUtZWxlbWVudC1pZi1ub3QtZGVmaW5lZC5qcyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBQYWdpbmF0aW9uKHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uLFxuICBlbWl0XG59KSB7XG4gIGNvbnN0IHBmeCA9ICdzd2lwZXItcGFnaW5hdGlvbic7XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAgcGFnaW5hdGlvbjoge1xuICAgICAgZWw6IG51bGwsXG4gICAgICBidWxsZXRFbGVtZW50OiAnc3BhbicsXG4gICAgICBjbGlja2FibGU6IGZhbHNlLFxuICAgICAgaGlkZU9uQ2xpY2s6IGZhbHNlLFxuICAgICAgcmVuZGVyQnVsbGV0OiBudWxsLFxuICAgICAgcmVuZGVyUHJvZ3Jlc3NiYXI6IG51bGwsXG4gICAgICByZW5kZXJGcmFjdGlvbjogbnVsbCxcbiAgICAgIHJlbmRlckN1c3RvbTogbnVsbCxcbiAgICAgIHByb2dyZXNzYmFyT3Bwb3NpdGU6IGZhbHNlLFxuICAgICAgdHlwZTogJ2J1bGxldHMnLFxuICAgICAgLy8gJ2J1bGxldHMnIG9yICdwcm9ncmVzc2Jhcicgb3IgJ2ZyYWN0aW9uJyBvciAnY3VzdG9tJ1xuICAgICAgZHluYW1pY0J1bGxldHM6IGZhbHNlLFxuICAgICAgZHluYW1pY01haW5CdWxsZXRzOiAxLFxuICAgICAgZm9ybWF0RnJhY3Rpb25DdXJyZW50OiBudW1iZXIgPT4gbnVtYmVyLFxuICAgICAgZm9ybWF0RnJhY3Rpb25Ub3RhbDogbnVtYmVyID0+IG51bWJlcixcbiAgICAgIGJ1bGxldENsYXNzOiBgJHtwZnh9LWJ1bGxldGAsXG4gICAgICBidWxsZXRBY3RpdmVDbGFzczogYCR7cGZ4fS1idWxsZXQtYWN0aXZlYCxcbiAgICAgIG1vZGlmaWVyQ2xhc3M6IGAke3BmeH0tYCxcbiAgICAgIGN1cnJlbnRDbGFzczogYCR7cGZ4fS1jdXJyZW50YCxcbiAgICAgIHRvdGFsQ2xhc3M6IGAke3BmeH0tdG90YWxgLFxuICAgICAgaGlkZGVuQ2xhc3M6IGAke3BmeH0taGlkZGVuYCxcbiAgICAgIHByb2dyZXNzYmFyRmlsbENsYXNzOiBgJHtwZnh9LXByb2dyZXNzYmFyLWZpbGxgLFxuICAgICAgcHJvZ3Jlc3NiYXJPcHBvc2l0ZUNsYXNzOiBgJHtwZnh9LXByb2dyZXNzYmFyLW9wcG9zaXRlYCxcbiAgICAgIGNsaWNrYWJsZUNsYXNzOiBgJHtwZnh9LWNsaWNrYWJsZWAsXG4gICAgICBsb2NrQ2xhc3M6IGAke3BmeH0tbG9ja2AsXG4gICAgICBob3Jpem9udGFsQ2xhc3M6IGAke3BmeH0taG9yaXpvbn
1RhbGAsXG4gICAgICB2ZXJ0aWNhbENsYXNzOiBgJHtwZnh9LXZlcnRpY2FsYCxcbiAgICAgIHBhZ2luYXRpb25EaXNhYmxlZENsYXNzOiBgJHtwZnh9LWRpc2FibGVkYFxuICAgIH1cbiAgfSk7XG4gIHN3aXBlci5wYWdpbmF0aW9uID0ge1xuICAgIGVsOiBudWxsLFxuICAgICRlbDogbnVsbCxcbiAgICBidWxsZXRzOiBbXVxuICB9O1xuICBsZXQgYnVsbGV0U2l6ZTtcbiAgbGV0IGR5bmFtaWNCdWxsZXRJbmRleCA9IDA7XG5cbiAgZnVuY3Rpb24gaXNQYWdpbmF0aW9uRGlzYWJsZWQoKSB7XG4gICAgcmV0dXJuICFzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uZWwgfHwgIXN3aXBlci5wYWdpbmF0aW9uLmVsIHx8ICFzd2lwZXIucGFnaW5hdGlvbi4kZWwgfHwgc3dpcGVyLnBhZ2luYXRpb24uJGVsLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFNpZGVCdWxsZXRzKCRidWxsZXRFbCwgcG9zaXRpb24pIHtcbiAgICBjb25zdCB7XG4gICAgICBidWxsZXRBY3RpdmVDbGFzc1xuICAgIH0gPSBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb247XG4gICAgJGJ1bGxldEVsW3Bvc2l0aW9uXSgpLmFkZENsYXNzKGAke2J1bGxldEFjdGl2ZUNsYXNzfS0ke3Bvc2l0aW9ufWApW3Bvc2l0aW9uXSgpLmFkZENsYXNzKGAke2J1bGxldEFjdGl2ZUNsYXNzfS0ke3Bvc2l0aW9ufS0ke3Bvc2l0aW9ufWApO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKCkge1xuICAgIC8vIFJlbmRlciB8fCBVcGRhdGUgUGFnaW5hdGlvbiBidWxsZXRzL2l0ZW1zXG4gICAgY29uc3QgcnRsID0gc3dpcGVyLnJ0bDtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb247XG4gICAgaWYgKGlzUGFnaW5hdGlvbkRpc2FibGVkKCkpIHJldHVybjtcbiAgICBjb25zdCBzbGlkZXNMZW5ndGggPSBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCA/IHN3aXBlci52aXJ0dWFsLnNsaWRlcy5sZW5ndGggOiBzd2lwZXIuc2xpZGVzLmxlbmd0aDtcbiAgICBjb25zdCAkZWwgPSBzd2lwZXIucGFnaW5hdGlvbi4kZWw7IC8vIEN1cnJlbnQvVG90YWxcblxuICAgIGxldCBjdXJyZW50O1xuICAgIGNvbnN0IHRvdGFsID0gc3dpcGVyLnBhcmFtcy5sb29wID8gTWF0aC5jZWlsKChzbGlkZXNMZW5ndGggLSBzd2lwZXIubG9vcGVkU2xpZGVzICogMikgLyBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwKSA6IHN3aXBlci5zbmFwR3JpZC5sZW5ndGg7XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICBjdXJyZW50ID0gTWF0aC5jZWlsKChzd2lwZXIuYWN0aXZlSW5kZXggLSBzd2lwZXIubG9vcGVkU2xpZGVzKSAvIHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyR3JvdXApO1xuXG4gICAgICBpZiAoY3VycmVudCA+IHNsaWRlc0xlbmd0aCAtIDEgLSBzd2lwZXIubG9vcGVkU2xpZGVzICogMikge1xuICAgICAgICBjdXJyZW50IC09IHNsaWRlc0xlbmd0aCAtIHN3aXBlci5sb29wZWRTbGlkZXMgKiAyO1xuICAgICAgfVxuXG4gICAgICBpZiAoY3VycmVudCA+IHRvdGFsIC0gMSkgY3VycmVudCAtPSB0b3RhbDtcbiAgICAgIGlmIChjdXJyZW50IDwgMCAmJiBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb25UeXBlICE9PSAnYnVsbGV0cycpIGN1cnJlbnQgPSB0b3RhbCArIGN1cnJlbnQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc3dpcGVyLnNuYXBJbmRleCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGN1cnJlbnQgPSBzd2lwZXIuc25hcEluZGV4O1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50ID0gc3dpcGVyLmFjdGl2ZUluZGV4IHx8IDA7XG4gICAgfSAvLyBUeXBlc1xuXG5cbiAgICBpZiAocGFyYW1zLnR5cGUgPT09ICdidWxsZXRzJyAmJiBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzICYmIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgYnVsbGV0cyA9IHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHM7XG4gICAgICBsZXQgZmlyc3RJbmRleDtcbiAgICAgIGxldCBsYXN0SW5kZXg7XG4gICAgICBsZXQgbWlkSW5kZXg7XG5cbiAgICAgIGlmIChwYXJhbXMuZHluYW1pY0J1bGxldHMpIHtcbiAgICAgICAgYnVsbGV0U2l6ZSA9IGJ1bGxldHMuZXEoMClbc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ291dGVyV2lkdGgnIDogJ291dGVySGVpZ2h0J10odHJ1ZSk7XG4gICAgICAgICRlbC5jc3Moc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3dpZHRoJyA6ICdoZWlnaHQnLCBgJHtidWxsZXRTaXplICogKHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMgKyA0KX1weGApO1xuXG4gICAgICAgIGlmIChwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzID4gMSAmJiBzd2lwZXIucHJldmlvdXNJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZHluYW1pY0J1bGxldEluZGV4ICs9IGN1cnJlbnQgLSAoc3dpcGVyLnByZXZpb3VzSW5kZXggLSBzd2lwZXIubG9vcGVkU2xpZGVzIHx8IDApO1xuXG4gICAgICAgICAgaWYgKGR5bmFtaWNCdWxsZXRJbmRleCA+IHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMgLSAxKSB7XG4gICAgICAgICAgICBkeW5hbWljQnVsbGV0SW5kZXggPSBwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzIC0gMTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGR5bmFtaWNCdWxsZXRJbmRleCA8IDApIHtcbiAgICAgICAgICAgIGR5bmFtaWNCdWxsZXRJbmRleCA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZmlyc3RJbmRleCA9IE1hdGgubWF4KGN1cnJlbnQgLSBkeW5hbWljQnVsbGV0SW5kZXgsIDApO1xuICAgICAgICBsYXN0SW5kZXggPSBmaXJzdEluZGV4ICsgKE1hdGgubWluKGJ1bGxldHMubGVuZ3RoLCBwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzKSAtIDEpO1xuICAgICAgICBtaWRJbmRleCA9IChsYXN0SW5kZXggKyBmaXJzdEluZGV4KSAvIDI7XG4gICAgICB9XG5cbiAgICAgIGJ1bGxldHMucmVtb3ZlQ2xhc3MoWycnLCAnLW5leHQnLCAnLW5leHQtbmV4dCcsICctcHJldicsICctcHJldi1wcmV2JywgJy1tYWluJ10ubWFwKHN1ZmZpeCA9PiBgJHtwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3N9JHtzdWZmaXh9YCkuam9pbignICcpKTtcblxuICAgICAgaWYgKCRlbC5sZW5ndGggPiAxKSB7XG4gICAgICAgIGJ1bGxldHMuZWFjaChidWxsZXQgPT4ge1xuICAgICAgICAgIGNvbnN0ICRidWxsZXQgPSAkKGJ1bGxldCk7XG4gICAgICAgICAgY29uc3QgYnVsbGV0SW5kZXggPSAkYnVsbGV0LmluZGV4KCk7XG5cbiAgICAgICAgICBpZiAoYnVsbGV0SW5kZXggPT09IGN1cnJlbnQpIHtcbiAgICAgICAgICAgICRidWxsZXQuYWRkQ2xhc3MocGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocGFyYW1zLmR5bmFtaWNCdWxsZXRzKSB7XG4gICAgICAgICAgICBpZiAoYnVsbGV0SW5kZXggPj0gZmlyc3RJbmRleCAmJiBidWxsZXRJbmRleCA8PSBsYXN0SW5kZXgpIHtcbiAgICAgICAgICAgICAgJGJ1bGxldC5hZGRDbGFzcyhgJHtwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3N9LW1haW5gKTtcbiAgICAgICAgICAgI
1H1cblxuICAgICAgICAgICAgaWYgKGJ1bGxldEluZGV4ID09PSBmaXJzdEluZGV4KSB7XG4gICAgICAgICAgICAgIHNldFNpZGVCdWxsZXRzKCRidWxsZXQsICdwcmV2Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChidWxsZXRJbmRleCA9PT0gbGFzdEluZGV4KSB7XG4gICAgICAgICAgICAgIHNldFNpZGVCdWxsZXRzKCRidWxsZXQsICduZXh0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0ICRidWxsZXQgPSBidWxsZXRzLmVxKGN1cnJlbnQpO1xuICAgICAgICBjb25zdCBidWxsZXRJbmRleCA9ICRidWxsZXQuaW5kZXgoKTtcbiAgICAgICAgJGJ1bGxldC5hZGRDbGFzcyhwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3MpO1xuXG4gICAgICAgIGlmIChwYXJhbXMuZHluYW1pY0J1bGxldHMpIHtcbiAgICAgICAgICBjb25zdCAkZmlyc3REaXNwbGF5ZWRCdWxsZXQgPSBidWxsZXRzLmVxKGZpcnN0SW5kZXgpO1xuICAgICAgICAgIGNvbnN0ICRsYXN0RGlzcGxheWVkQnVsbGV0ID0gYnVsbGV0cy5lcShsYXN0SW5kZXgpO1xuXG4gICAgICAgICAgZm9yIChsZXQgaSA9IGZpcnN0SW5kZXg7IGkgPD0gbGFzdEluZGV4OyBpICs9IDEpIHtcbiAgICAgICAgICAgIGJ1bGxldHMuZXEoaSkuYWRkQ2xhc3MoYCR7cGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzfS1tYWluYCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgICAgICAgaWYgKGJ1bGxldEluZGV4ID49IGJ1bGxldHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGZvciAobGV0IGkgPSBwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzOyBpID49IDA7IGkgLT0gMSkge1xuICAgICAgICAgICAgICAgIGJ1bGxldHMuZXEoYnVsbGV0cy5sZW5ndGggLSBpKS5hZGRDbGFzcyhgJHtwYXJhbXMuYnVsbGV0QWN0aXZlQ2xhc3N9LW1haW5gKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGJ1bGxldHMuZXEoYnVsbGV0cy5sZW5ndGggLSBwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzIC0gMSkuYWRkQ2xhc3MoYCR7cGFyYW1zLmJ1bGxldEFjdGl2ZUNsYXNzfS1wcmV2YCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzZXRTaWRlQnVsbGV0cygkZmlyc3REaXNwbGF5ZWRCdWxsZXQsICdwcmV2Jyk7XG4gICAgICAgICAgICAgIHNldFNpZGVCdWxsZXRzKCRsYXN0RGlzcGxheWVkQnVsbGV0LCAnbmV4dCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXRTaWRlQnVsbGV0cygkZmlyc3REaXNwbGF5ZWRCdWxsZXQsICdwcmV2Jyk7XG4gICAgICAgICAgICBzZXRTaWRlQnVsbGV0cygkbGFzdERpc3BsYXllZEJ1bGxldCwgJ25leHQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmFtcy5keW5hbWljQnVsbGV0cykge1xuICAgICAgICBjb25zdCBkeW5hbWljQnVsbGV0c0xlbmd0aCA9IE1hdGgubWluKGJ1bGxldHMubGVuZ3RoLCBwYXJhbXMuZHluYW1pY01haW5CdWxsZXRzICsgNCk7XG4gICAgICAgIGNvbnN0IGJ1bGxldHNPZmZzZXQgPSAoYnVsbGV0U2l6ZSAqIGR5bmFtaWNCdWxsZXRzTGVuZ3RoIC0gYnVsbGV0U2l6ZSkgLyAyIC0gbWlkSW5kZXggKiBidWxsZXRTaXplO1xuICAgICAgICBjb25zdCBvZmZzZXRQcm9wID0gcnRsID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgICAgICAgYnVsbGV0cy5jc3Moc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gb2Zmc2V0UHJvcCA6ICd0b3AnLCBgJHtidWxsZXRzT2Zmc2V0fXB4YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy50eXBlID09PSAnZnJhY3Rpb24nKSB7XG4gICAgICAkZWwuZmluZChjbGFzc2VzVG9TZWxlY3RvcihwYXJhbXMuY3VycmVudENsYXNzKSkudGV4dChwYXJhbXMuZm9ybWF0RnJhY3Rpb25DdXJyZW50KGN1cnJlbnQgKyAxKSk7XG4gICAgICAkZWwuZmluZChjbGFzc2VzVG9TZWxlY3RvcihwYXJhbXMudG90YWxDbGFzcykpLnRleHQocGFyYW1zLmZvcm1hdEZyYWN0aW9uVG90YWwodG90YWwpKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLnR5cGUgPT09ICdwcm9ncmVzc2JhcicpIHtcbiAgICAgIGxldCBwcm9ncmVzc2JhckRpcmVjdGlvbjtcblxuICAgICAgaWYgKHBhcmFtcy5wcm9ncmVzc2Jhck9wcG9zaXRlKSB7XG4gICAgICAgIHByb2dyZXNzYmFyRGlyZWN0aW9uID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3ZlcnRpY2FsJyA6ICdob3Jpem9udGFsJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByb2dyZXNzYmFyRGlyZWN0aW9uID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ2hvcml6b250YWwnIDogJ3ZlcnRpY2FsJztcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2NhbGUgPSAoY3VycmVudCArIDEpIC8gdG90YWw7XG4gICAgICBsZXQgc2NhbGVYID0gMTtcbiAgICAgIGxldCBzY2FsZVkgPSAxO1xuXG4gICAgICBpZiAocHJvZ3Jlc3NiYXJEaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJykge1xuICAgICAgICBzY2FsZVggPSBzY2FsZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNjYWxlWSA9IHNjYWxlO1xuICAgICAgfVxuXG4gICAgICAkZWwuZmluZChjbGFzc2VzVG9TZWxlY3RvcihwYXJhbXMucHJvZ3Jlc3NiYXJGaWxsQ2xhc3MpKS50cmFuc2Zvcm0oYHRyYW5zbGF0ZTNkKDAsMCwwKSBzY2FsZVgoJHtzY2FsZVh9KSBzY2FsZVkoJHtzY2FsZVl9KWApLnRyYW5zaXRpb24oc3dpcGVyLnBhcmFtcy5zcGVlZCk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy50eXBlID09PSAnY3VzdG9tJyAmJiBwYXJhbXMucmVuZGVyQ3VzdG9tKSB7XG4gICAgICAkZWwuaHRtbChwYXJhbXMucmVuZGVyQ3VzdG9tKHN3aXBlciwgY3VycmVudCArIDEsIHRvdGFsKSk7XG4gICAgICBlbWl0KCdwYWdpbmF0aW9uUmVuZGVyJywgJGVsWzBdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW1pdCgncGFnaW5hdGlvblVwZGF0ZScsICRlbFswXSk7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzd2lwZXIuZW5hYmxlZCkge1xuICAgICAgJGVsW3N3aXBlci5pc0xvY2tlZCA/ICdhZGRDbGFzcycgOiAncmVtb3ZlQ2xhc3MnXShwYXJhbXMubG9ja0NsYXNzKTtcbiAgICB9XG4gI
1H1cblxuICBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgLy8gUmVuZGVyIENvbnRhaW5lclxuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbjtcbiAgICBpZiAoaXNQYWdpbmF0aW9uRGlzYWJsZWQoKSkgcmV0dXJuO1xuICAgIGNvbnN0IHNsaWRlc0xlbmd0aCA9IHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkID8gc3dpcGVyLnZpcnR1YWwuc2xpZGVzLmxlbmd0aCA6IHN3aXBlci5zbGlkZXMubGVuZ3RoO1xuICAgIGNvbnN0ICRlbCA9IHN3aXBlci5wYWdpbmF0aW9uLiRlbDtcbiAgICBsZXQgcGFnaW5hdGlvbkhUTUwgPSAnJztcblxuICAgIGlmIChwYXJhbXMudHlwZSA9PT0gJ2J1bGxldHMnKSB7XG4gICAgICBsZXQgbnVtYmVyT2ZCdWxsZXRzID0gc3dpcGVyLnBhcmFtcy5sb29wID8gTWF0aC5jZWlsKChzbGlkZXNMZW5ndGggLSBzd2lwZXIubG9vcGVkU2xpZGVzICogMikgLyBzd2lwZXIucGFyYW1zLnNsaWRlc1Blckdyb3VwKSA6IHN3aXBlci5zbmFwR3JpZC5sZW5ndGg7XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmZyZWVNb2RlICYmIHN3aXBlci5wYXJhbXMuZnJlZU1vZGUuZW5hYmxlZCAmJiAhc3dpcGVyLnBhcmFtcy5sb29wICYmIG51bWJlck9mQnVsbGV0cyA+IHNsaWRlc0xlbmd0aCkge1xuICAgICAgICBudW1iZXJPZkJ1bGxldHMgPSBzbGlkZXNMZW5ndGg7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZCdWxsZXRzOyBpICs9IDEpIHtcbiAgICAgICAgaWYgKHBhcmFtcy5yZW5kZXJCdWxsZXQpIHtcbiAgICAgICAgICBwYWdpbmF0aW9uSFRNTCArPSBwYXJhbXMucmVuZGVyQnVsbGV0LmNhbGwoc3dpcGVyLCBpLCBwYXJhbXMuYnVsbGV0Q2xhc3MpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhZ2luYXRpb25IVE1MICs9IGA8JHtwYXJhbXMuYnVsbGV0RWxlbWVudH0gY2xhc3M9XCIke3BhcmFtcy5idWxsZXRDbGFzc31cIj48LyR7cGFyYW1zLmJ1bGxldEVsZW1lbnR9PmA7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgJGVsLmh0bWwocGFnaW5hdGlvbkhUTUwpO1xuICAgICAgc3dpcGVyLnBhZ2luYXRpb24uYnVsbGV0cyA9ICRlbC5maW5kKGNsYXNzZXNUb1NlbGVjdG9yKHBhcmFtcy5idWxsZXRDbGFzcykpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMudHlwZSA9PT0gJ2ZyYWN0aW9uJykge1xuICAgICAgaWYgKHBhcmFtcy5yZW5kZXJGcmFjdGlvbikge1xuICAgICAgICBwYWdpbmF0aW9uSFRNTCA9IHBhcmFtcy5yZW5kZXJGcmFjdGlvbi5jYWxsKHN3aXBlciwgcGFyYW1zLmN1cnJlbnRDbGFzcywgcGFyYW1zLnRvdGFsQ2xhc3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFnaW5hdGlvbkhUTUwgPSBgPHNwYW4gY2xhc3M9XCIke3BhcmFtcy5jdXJyZW50Q2xhc3N9XCI+PC9zcGFuPmAgKyAnIC8gJyArIGA8c3BhbiBjbGFzcz1cIiR7cGFyYW1zLnRvdGFsQ2xhc3N9XCI+PC9zcGFuPmA7XG4gICAgICB9XG5cbiAgICAgICRlbC5odG1sKHBhZ2luYXRpb25IVE1MKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLnR5cGUgPT09ICdwcm9ncmVzc2JhcicpIHtcbiAgICAgIGlmIChwYXJhbXMucmVuZGVyUHJvZ3Jlc3NiYXIpIHtcbiAgICAgICAgcGFnaW5hdGlvbkhUTUwgPSBwYXJhbXMucmVuZGVyUHJvZ3Jlc3NiYXIuY2FsbChzd2lwZXIsIHBhcmFtcy5wcm9ncmVzc2JhckZpbGxDbGFzcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYWdpbmF0aW9uSFRNTCA9IGA8c3BhbiBjbGFzcz1cIiR7cGFyYW1zLnByb2dyZXNzYmFyRmlsbENsYXNzfVwiPjwvc3Bhbj5gO1xuICAgICAgfVxuXG4gICAgICAkZWwuaHRtbChwYWdpbmF0aW9uSFRNTCk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy50eXBlICE9PSAnY3VzdG9tJykge1xuICAgICAgZW1pdCgncGFnaW5hdGlvblJlbmRlcicsIHN3aXBlci5wYWdpbmF0aW9uLiRlbFswXSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdCgpIHtcbiAgICBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24gPSBjcmVhdGVFbGVtZW50SWZOb3REZWZpbmVkKHN3aXBlciwgc3dpcGVyLm9yaWdpbmFsUGFyYW1zLnBhZ2luYXRpb24sIHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbiwge1xuICAgICAgZWw6ICdzd2lwZXItcGFnaW5hdGlvbidcbiAgICB9KTtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnBhZ2luYXRpb247XG4gICAgaWYgKCFwYXJhbXMuZWwpIHJldHVybjtcbiAgICBsZXQgJGVsID0gJChwYXJhbXMuZWwpO1xuICAgIGlmICgkZWwubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy51bmlxdWVOYXZFbGVtZW50cyAmJiB0eXBlb2YgcGFyYW1zLmVsID09PSAnc3RyaW5nJyAmJiAkZWwubGVuZ3RoID4gMSkge1xuICAgICAgJGVsID0gc3dpcGVyLiRlbC5maW5kKHBhcmFtcy5lbCk7IC8vIGNoZWNrIGlmIGl0IGJlbG9uZ3MgdG8gYW5vdGhlciBuZXN0ZWQgU3dpcGVyXG5cbiAgICAgIGlmICgkZWwubGVuZ3RoID4gMSkge1xuICAgICAgICAkZWwgPSAkZWwuZmlsdGVyKGVsID0+IHtcbiAgICAgICAgICBpZiAoJChlbCkucGFyZW50cygnLnN3aXBlcicpWzBdICE9PSBzd2lwZXIuZWwpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy50eXBlID09PSAnYnVsbGV0cycgJiYgcGFyYW1zLmNsaWNrYWJsZSkge1xuICAgICAgJGVsLmFkZENsYXNzKHBhcmFtcy5jbGlja2FibGVDbGFzcyk7XG4gICAgfVxuXG4gICAgJGVsLmFkZENsYXNzKHBhcmFtcy5tb2RpZmllckNsYXNzICsgcGFyYW1zLnR5cGUpO1xuICAgICRlbC5hZGRDbGFzcyhzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyBwYXJhbXMuaG9yaXpvbn
1RhbENsYXNzIDogcGFyYW1zLnZlcnRpY2FsQ2xhc3MpO1xuXG4gICAgaWYgKHBhcmFtcy50eXBlID09PSAnYnVsbGV0cycgJiYgcGFyYW1zLmR5bmFtaWNCdWxsZXRzKSB7XG4gICAgICAkZWwuYWRkQ2xhc3MoYCR7cGFyYW1zLm1vZGlmaWVyQ2xhc3N9JHtwYXJhbXMudHlwZX0tZHluYW1pY2ApO1xuICAgICAgZHluYW1pY0J1bGxldEluZGV4ID0gMDtcblxuICAgICAgaWYgKHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMgPCAxKSB7XG4gICAgICAgIHBhcmFtcy5keW5hbWljTWFpbkJ1bGxldHMgPSAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwYXJhbXMudHlwZSA9PT0gJ3Byb2dyZXNzYmFyJyAmJiBwYXJhbXMucHJvZ3Jlc3NiYXJPcHBvc2l0ZSkge1xuICAgICAgJGVsLmFkZENsYXNzKHBhcmFtcy5wcm9ncmVzc2Jhck9wcG9zaXRlQ2xhc3MpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuY2xpY2thYmxlKSB7XG4gICAgICAkZWwub24oJ2NsaWNrJywgY2xhc3Nlc1RvU2VsZWN0b3IocGFyYW1zLmJ1bGxldENsYXNzKSwgZnVuY3Rpb24gb25DbGljayhlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgbGV0IGluZGV4ID0gJCh0aGlzKS5pbmRleCgpICogc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cDtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkgaW5kZXggKz0gc3dpcGVyLmxvb3BlZFNsaWRlcztcbiAgICAgICAgc3dpcGVyLnNsaWRlVG8oaW5kZXgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmFzc2lnbihzd2lwZXIucGFnaW5hdGlvbiwge1xuICAgICAgJGVsLFxuICAgICAgZWw6ICRlbFswXVxuICAgIH0pO1xuXG4gICAgaWYgKCFzd2lwZXIuZW5hYmxlZCkge1xuICAgICAgJGVsLmFkZENsYXNzKHBhcmFtcy5sb2NrQ2xhc3MpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uO1xuICAgIGlmIChpc1BhZ2luYXRpb25EaXNhYmxlZCgpKSByZXR1cm47XG4gICAgY29uc3QgJGVsID0gc3dpcGVyLnBhZ2luYXRpb24uJGVsO1xuICAgICRlbC5yZW1vdmVDbGFzcyhwYXJhbXMuaGlkZGVuQ2xhc3MpO1xuICAgICRlbC5yZW1vdmVDbGFzcyhwYXJhbXMubW9kaWZpZXJDbGFzcyArIHBhcmFtcy50eXBlKTtcbiAgICAkZWwucmVtb3ZlQ2xhc3Moc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gcGFyYW1zLmhvcml6b250YWxDbGFzcyA6IHBhcmFtcy52ZXJ0aWNhbENsYXNzKTtcbiAgICBpZiAoc3dpcGVyLnBhZ2luYXRpb24uYnVsbGV0cyAmJiBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzLnJlbW92ZUNsYXNzKSBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzLnJlbW92ZUNsYXNzKHBhcmFtcy5idWxsZXRBY3RpdmVDbGFzcyk7XG5cbiAgICBpZiAocGFyYW1zLmNsaWNrYWJsZSkge1xuICAgICAgJGVsLm9mZignY2xpY2snLCBjbGFzc2VzVG9TZWxlY3RvcihwYXJhbXMuYnVsbGV0Q2xhc3MpKTtcbiAgICB9XG4gIH1cblxuICBvbignaW5pdCcsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmVuYWJsZWQgPT09IGZhbHNlKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgIGRpc2FibGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5pdCgpO1xuICAgICAgcmVuZGVyKCk7XG4gICAgICB1cGRhdGUoKTtcbiAgICB9XG4gIH0pO1xuICBvbignYWN0aXZlSW5kZXhDaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgdXBkYXRlKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc3dpcGVyLnNuYXBJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHVwZGF0ZSgpO1xuICAgIH1cbiAgfSk7XG4gIG9uKCdzbmFwSW5kZXhDaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmxvb3ApIHtcbiAgICAgIHVwZGF0ZSgpO1xuICAgIH1cbiAgfSk7XG4gIG9uKCdzbGlkZXNMZW5ndGhDaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgcmVuZGVyKCk7XG4gICAgICB1cGRhdGUoKTtcbiAgICB9XG4gIH0pO1xuICBvbignc25hcEdyaWRMZW5ndGhDaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmxvb3ApIHtcbiAgICAgIHJlbmRlcigpO1xuICAgICAgdXBkYXRlKCk7XG4gICAgfVxuICB9KTtcbiAgb24oJ2Rlc3Ryb3knLCAoKSA9PiB7XG4gICAgZGVzdHJveSgpO1xuICB9KTtcbiAgb24oJ2VuYWJsZSBkaXNhYmxlJywgKCkgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgICRlbFxuICAgIH0gPSBzd2lwZXIucGFnaW5hdGlvbjtcblxuICAgIGlmICgkZWwpIHtcbiAgICAgICRlbFtzd2lwZXIuZW5hYmxlZCA/ICdyZW1vdmVDbGFzcycgOiAnYWRkQ2xhc3MnXShzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24ubG9ja0NsYXNzKTtcbiAgICB9XG4gIH0pO1xuICBvbignbG9jayB1bmxvY2snLCAoKSA9PiB7XG4gICAgdXBkYXRlKCk7XG4gIH0pO1xuICBvbignY2xpY2snLCAoX3MsIGUpID0+IHtcbiAgICBjb25zdCB0YXJnZXRFbCA9IGUudGFyZ2V0O1xuICAgIGNvbnN0IHtcbiAgICAgICRlbFxuICAgIH0gPSBzd2lwZXIucGFnaW5hdGlvbjtcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uZWwgJiYgc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmhpZGVPbkNsaWNrICYmICRlbCAmJiAkZWwubGVuZ3RoID4gMCAmJiAhJCh0YXJnZXRFbCkuaGFzQ2xhc3Moc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmJ1bGxldENsYXNzKSkge1xuICAgICAgaWYgKHN3aXBlci5uYXZpZ2F0aW9uICYmIChzd2lwZXIubmF2aWdhdGlvbi5uZXh0RWwgJiYgdGFyZ2V0RWwgPT09IHN3aXBlci5uYXZpZ2F0aW9uLm5leHRFbCB8fCBzd2lwZXIubmF2aWdhdGlvbi5wcmV2RWwgJiYgdGFyZ2V0RWwgPT09IHN3aXBlci5uYXZpZ2F0aW9uLnByZXZFbCkpIHJldHVybjtcbiAgICAgIGNvbnN0IGlzSGlkZGVuID0gJGVsLmhhc0NsYXNzKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5oaWRkZW5DbGFzcyk7XG5cbiAgICAgIGlmIChpc0hpZGRlbiA9PT0gdHJ1ZSkge1xuICAgICAgICBlbWl0KCdwYWdpbmF0aW9uU2hvdycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW1pdCgncGFnaW5hdGlvbkhpZGUnKTtcbiAgICAgIH1cblxuICAgICAgJGVsLnRvZ2dsZUNsYXNzKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5oaWRkZW5DbGFzcyk7XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBlbmFibGUgPSAoKSA9PiB7XG4gICAgc3dpcGVyLiRlbC5yZW1vdmVDbGFzcyhzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24ucGFnaW5hdGlvbkRpc2FibGVkQ2xhc3MpO1xuXG4gICAgaWYgKHN3aXBlci5wYWdpbmF0aW9uLiRlbCkge1xuICAgICAgc3dpcGVyLnBhZ2luYXRpb24uJGVsLnJlbW92ZUNsYXNzKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5wYWdpbmF0aW9uRGlzYWJsZWRDbGFzcyk7XG4gICAgfVxuXG4gICAgaW5pdCgpO1xuICAgIHJlbmRlcigpO1xuICAgIHVwZGF0ZSgpO1xuICB9O1xuXG4gIGNvbnN0IGRpc2FibGUgPSAoKSA9PiB7XG4gICAgc3dpcGVyLiRlbC5hZGRDbGFzcyhzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24ucGFnaW5hdGlvbkRpc2FibGVkQ2xhc3MpO1xuXG4gICAgaWYgKHN3aXBlci5wYWdpbmF0aW9uLiRlbCkge1xuICAgICAgc3dpcGVyLnBhZ2luYXRpb24uJGVsLmFkZENsYXNzKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5wYWdpbmF0aW9uRGlzYWJsZWRDbGFzcyk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpO1xuICB9O1xuXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLnBhZ2luYXRpb24sIHtcbiAgICBlbmFibGUsXG4gICAgZGlzYWJsZSxcbiAgICByZW5kZXIsXG4gICAgdXBkYXRlLFxuICAgIGluaXQsXG4gICAgZGVzdHJveVxuICB9KTtcbn0iLCJpbXBvcnQgeyBnZXREb2N1bWVudCB9IGZyb20gJ3Nzci13aW5kb3cnO1xuaW1wb3J0ICQgZnJvbSAnLi4vLi4vc2hhcmVkL2RvbS5qcyc7XG5pbXBvcnQgeyBuZXh0VGljayB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscy5qcyc7XG5pbXBvcnQgY3JlYXRlRWxlbWVudElmTm90RGVmaW5lZCBmcm9tICcuLi8uLi9zaGFyZWQvY3JlYXRlLWVsZW1lbnQtaWYtbm90LWRlZmluZWQuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gU2Nyb2xsYmFyKHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uLFxuICBlbWl0XG59KSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gZ2V0RG9jdW1lbnQoKTtcbiAgbGV0IGlzVG91Y2hlZCA9IGZhbHNlO1xuICBsZXQgdGltZW91dCA9IG51bGw7XG4gIGxldCBkcmFnVGltZW91dCA9IG51bGw7XG4gIGxldCBkcmFnU3RhcnRQb3M7XG4gIGxldCBkcmFnU2l6ZTtcbiAgbGV0IHRyYWNrU2l6ZTtcbiAgbGV0IGRpdmlkZXI7XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAgc2Nyb2xsYmFyOiB7XG4gICAgICBlbDogbnVsbCxcbiAgICAgIGRyYWdTaXplOiAnYXV0bycsXG4gICAgICBoaWRlOiBmYWxzZSxcbiAgICAgIGRyYWdnYWJsZTogZmFsc2UsXG4gICAgICBzbmFwT25SZWxlYXNlOiB0cnVlLFxuICAgICAgbG9ja0NsYXNzOiAnc3dpcGVyLXNjcm9sbGJhci1sb2NrJyxcbiAgICAgIGRyYWdDbGFzczogJ3N3aXBlci1zY3JvbGxiYXItZHJhZycsXG4gICAgICBzY3JvbGxiYXJEaXNhYmxlZENsYXNzOiAnc3dpcGVyLXNjcm9sbGJhci1kaXNhYmxlZCcsXG4gICAgICBob3Jpem9udGFsQ2xhc3M6IGBzd2lwZXItc2Nyb2xsYmFyLWhvcml6b250YWxgLFxuICAgICAgdmVydGljYWxDbGFzczogYHN3aXBlci1zY3JvbGxiYXItdmVydGljYWxgXG4gICAgfVxuICB9KTtcbiAgc3dpcGVyLnNjcm9sbGJhciA9IHtcbiAgICBlbDogbnVsbCxcbiAgICBkcmFnRWw6IG51bGwsXG4gICAgJGVsOiBudWxsLFxuICAgICRkcmFnRWw6IG51bGxcbiAgfTtcblxuICBmdW5jdGlvbiBzZXRUcmFuc2xhdGUoKSB7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5lbCB8fCAhc3dpcGVyLnNjcm9sbGJhci5lbCkgcmV0dXJuO1xuICAgIGNvbnN0IHtcbiAgICAgIHNjcm9sbGJhcixcbiAgICAgIHJ0bFRyYW5zbGF0ZTogcnRsLFxuICAgICAgcHJvZ3Jlc3NcbiAgICB9ID0gc3dpcGVyO1xuICAgIGNvbnN0IHtcbiAgICAgICRkcmFnRWwsXG4gICAgICAkZWxcbiAgICB9ID0gc2Nyb2xsYmFyO1xuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyO1xuICAgIGxldCBuZXdTaXplID0gZHJhZ1NpemU7XG4gICAgbGV0IG5ld1BvcyA9ICh0cmFja1NpemUgLSBkcmFnU2l6ZSkgKiBwcm9ncmVzcztcblxuICAgIGlmIChydGwp
1IHtcbiAgICAgIG5ld1BvcyA9IC1uZXdQb3M7XG5cbiAgICAgIGlmIChuZXdQb3MgPiAwKSB7XG4gICAgICAgIG5ld1NpemUgPSBkcmFnU2l6ZSAtIG5ld1BvcztcbiAgICAgICAgbmV3UG9zID0gMDtcbiAgICAgIH0gZWxzZSBpZiAoLW5ld1BvcyArIGRyYWdTaXplID4gdHJhY2tTaXplKSB7XG4gICAgICAgIG5ld1NpemUgPSB0cmFja1NpemUgKyBuZXdQb3M7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChuZXdQb3MgPCAwKSB7XG4gICAgICBuZXdTaXplID0gZHJhZ1NpemUgKyBuZXdQb3M7XG4gICAgICBuZXdQb3MgPSAwO1xuICAgIH0gZWxzZSBpZiAobmV3UG9zICsgZHJhZ1NpemUgPiB0cmFja1NpemUpIHtcbiAgICAgIG5ld1NpemUgPSB0cmFja1NpemUgLSBuZXdQb3M7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xuICAgICAgJGRyYWdFbC50cmFuc2Zvcm0oYHRyYW5zbGF0ZTNkKCR7bmV3UG9zfXB4LCAwLCAwKWApO1xuICAgICAgJGRyYWdFbFswXS5zdHlsZS53aWR0aCA9IGAke25ld1NpemV9cHhgO1xuICAgIH0gZWxzZSB7XG4gICAgICAkZHJhZ0VsLnRyYW5zZm9ybShgdHJhbnNsYXRlM2QoMHB4LCAke25ld1Bvc31weCwgMClgKTtcbiAgICAgICRkcmFnRWxbMF0uc3R5bGUuaGVpZ2h0ID0gYCR7bmV3U2l6ZX1weGA7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5oaWRlKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAkZWxbMF0uc3R5bGUub3BhY2l0eSA9IDE7XG4gICAgICB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICRlbFswXS5zdHlsZS5vcGFjaXR5ID0gMDtcbiAgICAgICAgJGVsLnRyYW5zaXRpb24oNDAwKTtcbiAgICAgIH0sIDEwMDApO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFRyYW5zaXRpb24oZHVyYXRpb24pIHtcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyLmVsIHx8ICFzd2lwZXIuc2Nyb2xsYmFyLmVsKSByZXR1cm47XG4gICAgc3dpcGVyLnNjcm9sbGJhci4kZHJhZ0VsLnRyYW5zaXRpb24oZHVyYXRpb24pO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlU2l6ZSgpIHtcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyLmVsIHx8ICFzd2lwZXIuc2Nyb2xsYmFyLmVsKSByZXR1cm47XG4gICAgY29uc3Qge1xuICAgICAgc2Nyb2xsYmFyXG4gICAgfSA9IHN3aXBlcjtcbiAgICBjb25zdCB7XG4gICAgICAkZHJhZ0VsLFxuICAgICAgJGVsXG4gICAgfSA9IHNjcm9sbGJhcjtcbiAgICAkZHJhZ0VsWzBdLnN0eWxlLndpZHRoID0gJyc7XG4gICAgJGRyYWdFbFswXS5zdHlsZS5oZWlnaHQgPSAnJztcbiAgICB0cmFja1NpemUgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAkZWxbMF0ub2Zmc2V0V2lkdGggOiAkZWxbMF0ub2Zmc2V0SGVpZ2h0O1xuICAgIGRpdmlkZXIgPSBzd2lwZXIuc2l6ZSAvIChzd2lwZXIudmlydHVhbFNpemUgKyBzd2lwZXIucGFyYW1zLnNsaWRlc09mZnNldEJlZm9yZSAtIChzd2lwZXIucGFyYW1zLmNlbnRlcmVkU2xpZGVzID8gc3dpcGVyLnNuYXBHcmlkWzBdIDogMCkpO1xuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyLmRyYWdTaXplID09PSAnYXV0bycpIHtcbiAgICAgIGRyYWdTaXplID0gdHJhY2tTaXplICogZGl2aWRlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgZHJhZ1NpemUgPSBwYXJzZUludChzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5kcmFnU2l6ZSwgMTApO1xuICAgIH1cblxuICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICRkcmFnRWxbMF0uc3R5bGUud2lkdGggPSBgJHtkcmFnU2l6ZX1weGA7XG4gICAgfSBlbHNlIHtcbiAgICAgICRkcmFnRWxbMF0uc3R5bGUuaGVpZ2h0ID0gYCR7ZHJhZ1NpemV9cHhgO1xuICAgIH1cblxuICAgIGlmIChkaXZpZGVyID49IDEpIHtcbiAgICAgICRlbFswXS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIH0gZWxzZSB7XG4gICAgICAkZWxbMF0uc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgIH1cblxuICAgIGlmIChzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5oaWRlKSB7XG4gICAgICAkZWxbMF0uc3R5bGUub3BhY2l0eSA9IDA7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMud2F0Y2hPdmVyZmxvdyAmJiBzd2lwZXIuZW5hYmxlZCkge1xuICAgICAgc2Nyb2xsYmFyLiRlbFtzd2lwZXIuaXNMb2NrZWQgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJ10oc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIubG9ja0NsYXNzKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBnZXRQb2ludGVyUG9zaXRpb24oZSkge1xuICAgIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgIHJldHVybiBlLnR5cGUgPT09ICd0b3VjaHN0YXJ0JyB8fCBlLnR5cGUgPT09ICd0b3VjaG1vdmUnID8gZS50YXJnZXRUb3VjaGVzWzBdLmNsaWVudFggOiBlLmNsaWVudFg7XG4gICAgfVxuXG4gICAgcmV0dXJuIGUudHlwZSA9PT0gJ3RvdWNoc3RhcnQnIHx8IGUudHlwZSA9PT0gJ3RvdWNobW92ZScgPyBlLnRhcmdldFRvdWNoZXNbMF0uY2xpZW50WSA6IGUuY2xpZW50WTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldERyYWdQb3NpdGlvbihlKSB7XG4gICAgY29uc3Qge1xuICAgICAgc2Nyb2xsYmFyLFxuICAgICAgcnRsVHJhbnNsYXRlOiBydGxcbiAgICB9ID0gc3dpcGVyO1xuICAgIGNvbnN0IHtcbiAgICAgICRlbFxuICAgIH0gPSBzY3JvbGxiYXI7XG4gICAgbGV0IHBvc2l0aW9uUmF0aW87XG4gICAgcG9zaXRpb25SYXRpbyA9IChnZXRQb2ludGVyUG9zaXRpb24oZSkgLSAkZWwub2Zmc2V0KClbc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ2xlZnQnIDogJ3RvcCddIC0gKGRyYWdTdGFydFBvcyAhPT0gbnVsbCA/IGRyYWdTdGFydFBvcyA6IGRyYWdTaXplIC8gMikpIC8gKHRyYWNrU2l6ZSAtIGRyYWdTaXplKTtcbiAgICBwb3NpdGlvblJhdGlvID0gTWF0aC5tYXgoTWF0aC5taW4ocG9zaXRpb25SYXRpbywgMSksIDApO1xuXG4gICAgaWYgKHJ0bCkge1xuICAgICAgcG9zaXRpb25SYXRpbyA9IDEgLSBwb3NpdGlvblJhdGlvO1xuICAgIH1cblxuICAgIGNvbnN0IHBvc2l0aW9uID0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpICsgKHN3aXBlci5tYXhUcmFuc2xhdGUoKSAtIHN3aXBlci5taW5UcmFuc2xhdGUoKSkgKiBwb3NpdGlvblJhdGlvO1xuICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcyhwb3NpdGlvbik7XG4gICAgc3dpcGVyLnNldFRyYW5zbGF0ZShwb3NpdGlvbik7XG4gICAgc3dpcGVyLnVwZGF0ZUFjdGl2ZUluZGV4KCk7XG4gICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uRHJhZ1N0YXJ0KGUpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnNjcm9sbGJhcjtcbiAgICBjb25zdCB7XG4gICAgICBzY3JvbGxiYXIsXG4gICAgICAkd3JhcHBlckVsXG4gICAgfSA9IHN3aXBlcjtcbiAgICBjb25zdCB7XG4gICAgICAkZWwsXG4gICAgICAkZHJhZ0VsXG4gICAgfSA9IHNjcm9sbGJhcjtcbiAgICBpc1RvdWNoZWQgPSB0cnVlO1xuICAgIGRyYWdTdGFydFBvcyA9IGUudGFyZ2V0ID09PSAkZHJhZ0VsWzBdIHx8IGUudGFyZ2V0ID09PSAkZHJhZ0VsID8gZ2V0UG9pbnRlclBvc2l0aW9uKGUpIC0gZS50YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClbc3dpcGVyLmlzSG9yaXpvbn
1RhbCgpID8gJ2xlZnQnIDogJ3RvcCddIDogbnVsbDtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAkd3JhcHBlckVsLnRyYW5zaXRpb24oMTAwKTtcbiAgICAkZHJhZ0VsLnRyYW5zaXRpb24oMTAwKTtcbiAgICBzZXREcmFnUG9zaXRpb24oZSk7XG4gICAgY2xlYXJUaW1lb3V0KGRyYWdUaW1lb3V0KTtcbiAgICAkZWwudHJhbnNpdGlvbigwKTtcblxuICAgIGlmIChwYXJhbXMuaGlkZSkge1xuICAgICAgJGVsLmNzcygnb3BhY2l0eScsIDEpO1xuICAgIH1cblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgIHN3aXBlci4kd3JhcHBlckVsLmNzcygnc2Nyb2xsLXNuYXAtdHlwZScsICdub25lJyk7XG4gICAgfVxuXG4gICAgZW1pdCgnc2Nyb2xsYmFyRHJhZ1N0YXJ0JywgZSk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkRyYWdNb3ZlKGUpIHtcbiAgICBjb25zdCB7XG4gICAgICBzY3JvbGxiYXIsXG4gICAgICAkd3JhcHBlckVsXG4gICAgfSA9IHN3aXBlcjtcbiAgICBjb25zdCB7XG4gICAgICAkZWwsXG4gICAgICAkZHJhZ0VsXG4gICAgfSA9IHNjcm9sbGJhcjtcbiAgICBpZiAoIWlzVG91Y2hlZCkgcmV0dXJuO1xuICAgIGlmIChlLnByZXZlbnREZWZhdWx0KSBlLnByZXZlbnREZWZhdWx0KCk7ZWxzZSBlLnJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgc2V0RHJhZ1Bvc2l0aW9uKGUpO1xuICAgICR3cmFwcGVyRWwudHJhbnNpdGlvbigwKTtcbiAgICAkZWwudHJhbnNpdGlvbigwKTtcbiAgICAkZHJhZ0VsLnRyYW5zaXRpb24oMCk7XG4gICAgZW1pdCgnc2Nyb2xsYmFyRHJhZ01vdmUnLCBlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uRHJhZ0VuZChlKSB7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXI7XG4gICAgY29uc3Qge1xuICAgICAgc2Nyb2xsYmFyLFxuICAgICAgJHdyYXBwZXJFbFxuICAgIH0gPSBzd2lwZXI7XG4gICAgY29uc3Qge1xuICAgICAgJGVsXG4gICAgfSA9IHNjcm9sbGJhcjtcbiAgICBpZiAoIWlzVG91Y2hlZCkgcmV0dXJuO1xuICAgIGlzVG91Y2hlZCA9IGZhbHNlO1xuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgICAgc3dpcGVyLiR3cmFwcGVyRWwuY3NzKCdzY3JvbGwtc25hcC10eXBlJywgJycpO1xuICAgICAgJHdyYXBwZXJFbC50cmFuc2l0aW9uKCcnKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmhpZGUpIHtcbiAgICAgIGNsZWFyVGltZW91dChkcmFnVGltZW91dCk7XG4gICAgICBkcmFnVGltZW91dCA9IG5leHRUaWNrKCgpID0+IHtcbiAgICAgICAgJGVsLmNzcygnb3BhY2l0eScsIDApO1xuICAgICAgICAkZWwudHJhbnNpdGlvbig0MDApO1xuICAgICAgfSwgMTAwMCk7XG4gICAgfVxuXG4gICAgZW1pdCgnc2Nyb2xsYmFyRHJhZ0VuZCcsIGUpO1xuXG4gICAgaWYgKHBhcmFtcy5zbmFwT25SZWxlYXNlKSB7XG4gICAgICBzd2lwZXIuc2xpZGVUb0Nsb3Nlc3QoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBldmVudHMobWV0aG9kKSB7XG4gICAgY29uc3Qge1xuICAgICAgc2Nyb2xsYmFyLFxuICAgICAgdG91Y2hFdmVudHNUb3VjaCxcbiAgICAgIHRvdWNoRXZlbnRzRGVza3RvcCxcbiAgICAgIHBhcmFtcyxcbiAgICAgIHN1cHBvcnRcbiAgICB9ID0gc3dpcGVyO1xuICAgIGNvbnN0ICRlbCA9IHNjcm9sbGJhci4kZWw7XG4gICAgaWYgKCEkZWwpIHJldHVybjtcbiAgICBjb25zdCB0YXJnZXQgPSAkZWxbMF07XG4gICAgY29uc3QgYWN0aXZlTGlzdGVuZXIgPSBzdXBwb3J0LnBhc3NpdmVMaXN0ZW5lciAmJiBwYXJhbXMucGFzc2l2ZUxpc3RlbmVycyA/IHtcbiAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgY2FwdHVyZTogZmFsc2VcbiAgICB9IDogZmFsc2U7XG4gICAgY29uc3QgcGFzc2l2ZUxpc3RlbmVyID0gc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgJiYgcGFyYW1zLnBhc3NpdmVMaXN0ZW5lcnMgPyB7XG4gICAgICBwYXNzaXZlOiB0cnVlLFxuICAgICAgY2FwdHVyZTogZmFsc2VcbiAgICB9IDogZmFsc2U7XG4gICAgaWYgKCF0YXJnZXQpIHJldHVybjtcbiAgICBjb25zdCBldmVudE1ldGhvZCA9IG1ldGhvZCA9PT0gJ29uJyA/ICdhZGRFdmVudExpc3RlbmVyJyA6ICdyZW1vdmVFdmVudExpc3RlbmVyJztcblxuICAgIGlmICghc3VwcG9ydC50b3VjaCkge1xuICAgICAgdGFyZ2V0W2V2ZW50TWV0aG9kXSh0b3VjaEV2ZW50c0Rlc2t0b3Auc3RhcnQsIG9uRHJhZ1N0YXJ0LCBhY3RpdmVMaXN0ZW5lcik7XG4gICAgICBkb2
1N1bWVudFtldmVudE1ldGhvZF0odG91Y2hFdmVudHNEZXNrdG9wLm1vdmUsIG9uRHJhZ01vdmUsIGFjdGl2ZUxpc3RlbmVyKTtcbiAgICAgIGRvY3VtZW50W2V2ZW50TWV0aG9kXSh0b3VjaEV2ZW50c0Rlc2t0b3AuZW5kLCBvbkRyYWdFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhcmdldFtldmVudE1ldGhvZF0odG91Y2hFdmVudHNUb3VjaC5zdGFydCwgb25EcmFnU3RhcnQsIGFjdGl2ZUxpc3RlbmVyKTtcbiAgICAgIHRhcmdldFtldmVudE1ldGhvZF0odG91Y2hFdmVudHNUb3VjaC5tb3ZlLCBvbkRyYWdNb3ZlLCBhY3RpdmVMaXN0ZW5lcik7XG4gICAgICB0YXJnZXRbZXZlbnRNZXRob2RdKHRvdWNoRXZlbnRzVG91Y2guZW5kLCBvbkRyYWdFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZW5hYmxlRHJhZ2dhYmxlKCkge1xuICAgIGlmICghc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZWwgfHwgIXN3aXBlci5zY3JvbGxiYXIuZWwpIHJldHVybjtcbiAgICBldmVudHMoJ29uJyk7XG4gIH1cblxuICBmdW5jdGlvbiBkaXNhYmxlRHJhZ2dhYmxlKCkge1xuICAgIGlmICghc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZWwgfHwgIXN3aXBlci5zY3JvbGxiYXIuZWwpIHJldHVybjtcbiAgICBldmVudHMoJ29mZicpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5pdCgpIHtcbiAgICBjb25zdCB7XG4gICAgICBzY3JvbGxiYXIsXG4gICAgICAkZWw6ICRzd2lwZXJFbFxuICAgIH0gPSBzd2lwZXI7XG4gICAgc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIgPSBjcmVhdGVFbGVtZW50SWZOb3REZWZpbmVkKHN3aXBlciwgc3dpcGVyLm9yaWdpbmFsUGFyYW1zLnNjcm9sbGJhciwgc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIsIHtcbiAgICAgIGVsOiAnc3dpcGVyLXNjcm9sbGJhcidcbiAgICB9KTtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnNjcm9sbGJhcjtcbiAgICBpZiAoIXBhcmFtcy5lbCkgcmV0dXJuO1xuICAgIGxldCAkZWwgPSAkKHBhcmFtcy5lbCk7XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy51bmlxdWVOYXZFbGVtZW50cyAmJiB0eXBlb2YgcGFyYW1zLmVsID09PSAnc3RyaW5nJyAmJiAkZWwubGVuZ3RoID4gMSAmJiAkc3dpcGVyRWwuZmluZChwYXJhbXMuZWwpLmxlbmd0aCA9PT0gMSkge1xuICAgICAgJGVsID0gJHN3aXBlckVsLmZpbmQocGFyYW1zLmVsKTtcbiAgICB9XG5cbiAgICAkZWwuYWRkQ2xhc3Moc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gcGFyYW1zLmhvcml6b250YWxDbGFzcyA6IHBhcmFtcy52ZXJ0aWNhbENsYXNzKTtcbiAgICBsZXQgJGRyYWdFbCA9ICRlbC5maW5kKGAuJHtzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5kcmFnQ2xhc3N9YCk7XG5cbiAgICBpZiAoJGRyYWdFbC5sZW5ndGggPT09IDApIHtcbiAgICAgICRkcmFnRWwgPSAkKGA8ZGl2IGNsYXNzPVwiJHtzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5kcmFnQ2xhc3N9XCI+PC9kaXY+YCk7XG4gICAgICAkZWwuYXBwZW5kKCRkcmFnRWwpO1xuICAgIH1cblxuICAgIE9iamVjdC5hc3NpZ24oc2Nyb2xsYmFyLCB7XG4gICAgICAkZWwsXG4gICAgICBlbDogJGVsWzBdLFxuICAgICAgJGRyYWdFbCxcbiAgICAgIGRyYWdFbDogJGRyYWdFbFswXVxuICAgIH0pO1xuXG4gICAgaWYgKHBhcmFtcy5kcmFnZ2FibGUpIHtcbiAgICAgIGVuYWJsZURyYWdnYWJsZSgpO1xuICAgIH1cblxuICAgIGlmICgkZWwpIHtcbiAgICAgICRlbFtzd2lwZXIuZW5hYmxlZCA/ICdyZW1vdmVDbGFzcycgOiAnYWRkQ2xhc3MnXShzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5sb2NrQ2xhc3MpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXI7XG4gICAgY29uc3QgJGVsID0gc3dpcGVyLnNjcm9sbGJhci4kZWw7XG5cbiAgICBpZiAoJGVsKSB7XG4gICAgICAkZWwucmVtb3ZlQ2xhc3Moc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gcGFyYW1zLmhvcml6b250YWxDbGFzcyA6IHBhcmFtcy52ZXJ0aWNhbENsYXNzKTtcbiAgICB9XG5cbiAgICBkaXNhYmxlRHJhZ2dhYmxlKCk7XG4gIH1cblxuICBvbignaW5pdCcsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuZW5hYmxlZCA9PT0gZmFsc2UpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgZGlzYWJsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbml0KCk7XG4gICAgICB1cGRhdGVTaXplKCk7XG4gICAgICBzZXRUcmFuc2xhdGUoKTtcbiAgICB9XG4gIH0pO1xuICBvbigndXBkYXRlIHJlc2l6ZSBvYnNlcnZlclVwZGF0ZSBsb2NrIHVubG9jaycsICgpID0+IHtcbiAgICB1cGRhdGVTaXplKCk7XG4gIH0pO1xuICBvbignc2V0VHJhbnNsYXRlJywgKCkgPT4ge1xuICAgIHNldFRyYW5zbGF0ZSgpO1xuICB9KTtcbiAgb24oJ3NldFRyYW5zaXRpb24nLCAoX3MsIGR1cmF0aW9uKSA9PiB7XG4gICAgc2V0VHJhbnNpdGlvbihkdXJhdGlvbik7XG4gIH0pO1xuICBvbignZW5hYmxlIGRpc2FibGUnLCAoKSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgJGVsXG4gICAgfSA9IHN3aXBlci5zY3JvbGxiYXI7XG5cbiAgICBpZiAoJGVsKSB7XG4gICAgICAkZWxbc3dpcGVyLmVuYWJsZWQgPyAncmVtb3ZlQ2xhc3MnIDogJ2FkZENsYXNzJ10oc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIubG9ja0NsYXNzKTtcbiAgICB9XG4gIH0pO1xuICBvbignZGVzdHJveScsICgpID0+IHtcbiAgICBkZXN0cm95KCk7XG4gIH0pO1xuXG4gIGNvbnN0IGVuYWJsZSA9ICgpID0+IHtcbiAgICBzd2lwZXIuJGVsLnJlbW92ZUNsYXNzKHN3aXBlci5wYXJhbXMuc2Nyb2xsYmFyLnNjcm9sbGJhckRpc2FibGVkQ2xhc3MpO1xuXG4gICAgaWYgKHN3aXBlci5zY3JvbGxiYXIuJGVsKSB7XG4gICAgICBzd2lwZXIuc2Nyb2xsYmFyLiRlbC5yZW1vdmVDbGFzcyhzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5zY3JvbGxiYXJEaXNhYmxlZENsYXNzKTtcbiAgICB9XG5cbiAgICBpbml0KCk7XG4gICAgdXBkYXRlU2l6ZSgpO1xuICAgIHNldFRyYW5zbGF0ZSgpO1xuICB9O1xuXG4gIGNvbnN0IGRpc2FibGUgPSAoKSA9PiB7XG4gICAgc3dpcGVyLiRlbC5hZGRDbGFzcyhzd2lwZXIucGFyYW1zLnNjcm9sbGJhci5zY3JvbGxiYXJEaXNhYmxlZENsYXNzKTtcblxuICAgIGlmIChzd2lwZXIuc2Nyb2xsYmFyLiRlbCkge1xuICAgICAgc3dpcGVyLnNjcm9sbGJhci4kZWwuYWRkQ2xhc3Moc3dpcGVyLnBhcmFtcy5zY3JvbGxiYXIuc2Nyb2xsYmFyRGlzYWJsZWRDbGFzcyk7XG4gICAgfVxuXG4gICAgZGVzdHJveSgpO1xuICB9O1xuXG4gIE9iamVjdC5hc3NpZ24oc3dpcGVyLnNjcm9sbGJhciwge1xuICAgIGVuYWJsZSxcbiAgICBkaXNhYmxlLFxuICAgIHVwZGF0ZVNpemUsXG4gICAgc2V0VHJhbnNsYXRlLFxuICAgIGluaXQsXG4gICAgZGVzdHJveVxuICB9KTtcbn0iLCJpbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFBhcmFsbGF4KHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uXG59KSB7XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAgcGFyYWxsYXg6IHtcbiAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgfVxuICB9KTtcblxuICBjb25zdCBzZXRUcmFuc2Zvcm0gPSAoZWwsIHByb2dyZXNzKSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgcnRsXG4gICAgfSA9IHN3aXBlcjtcbiAgICBjb25zdCAkZWwgPSAkKGVsKTtcbiAgICBjb25zdCBydGxGYWN0b3IgPSBydGwgPyAtMSA6IDE7XG4gICAgY29uc3QgcCA9ICRlbC5hdHRyKCdkYXRhLXN3aXBlci1wYXJhbGxheCcpIHx8ICcwJztcbiAgICBsZXQgeCA9ICRlbC5hdHRyKCdkYXRhLXN3aXBlci1wYXJhbGxheC14Jyk7XG4gICAgbGV0IHkgPSAkZWwuYXR0cignZGF0YS1zd2lwZXItcGFyYWxsYXgteScpO1xuICAgIGNvbnN0IHNjYWxlID0gJGVsLmF0dHIoJ2RhdGEtc3dpcGVyLXBhcmFsbGF4LXNjYWxlJyk7XG4gICAgY29uc3Qgb3BhY2l0eSA9ICRlbC5hdHRyKCdkYXRhLXN3aXBlci1wYXJhbGxheC1vcGFjaXR5Jyk7XG5cbiAgICBpZiAoeCB8fCB5KSB7XG4gICAgICB4ID0geCB8fCAnMCc7XG4gICAgICB5ID0geSB8fCAnMCc7XG4gICAgfSBlbHNlIGlmIChzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgIHggPSBwO1xuICAgICAgeSA9ICcwJztcbiAgICB9IGVsc2Uge1xuICAgICAgeSA9IHA7XG4gICAgICB4ID0gJzAnO1xuICAgIH1cblxuICAgIGlmICh4LmluZGV4T2YoJyUnKSA+PSAwKSB7XG4gICAgICB4ID0gYCR7cGFyc2VJbnQoeCwgMTApICogcHJvZ3Jlc3MgKiBydGxGYWN0b3J9JWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHggPSBgJHt4ICogcHJvZ3Jlc3MgKiBydGxGYWN0b3J9cHhgO1xuICAgIH1cblxuICAgIGlmICh5LmluZGV4T2YoJyUnKSA+PSAwKSB7XG4gICAgICB5ID0gYCR7cGFyc2VJbnQoeSwgMTApICogcHJvZ3Jlc3N9JWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHkgPSBgJHt5ICogcHJvZ3Jlc3N9cHhgO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3BhY2l0eSAhPT0gJ3VuZGVmaW5lZCcgJiYgb3BhY2l0eSAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgY3VycmVudE9wYWNpdHkgPSBvcGFjaXR5IC0gKG9wYWNpdHkgLSAxKSAqICgxIC0gTWF0aC5hYnMocHJvZ3Jlc3MpKTtcbiAgICAgICRlbFswXS5zdHlsZS5vcGFjaXR5ID0gY3VycmVudE9wYWNpdHk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBzY2FsZSA9PT0gJ3VuZGVmaW5lZCcgfHwgc2NhbGUgPT09IG51bGwpIHtcbiAgICAgICRlbC50cmFuc2Zvcm0oYHRyYW5zbGF0ZTNkKCR7eH0sICR7eX0sIDBweClgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY3VycmVudFNjYWxlID0gc2NhbGUgLSAoc2NhbGUgLSAxKSAqICgxIC0gTWF0aC5hYnMocHJvZ3Jlc3MpKTtcbiAgICAgICRlbC50cmFuc2Zvcm0oYHRyYW5zbGF0ZTNkKCR7eH0sICR7eX0sIDBweCkgc2NhbGUoJHtjdXJyZW50U2NhbGV9KWApO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBzZXRUcmFuc2xhdGUgPSAoKSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgJGVsLFxuICAgICAgc2xpZGVzLFxuICAgICAgcHJvZ3Jlc3MsXG4gICAgICBzbmFwR3JpZFxuICAgIH0gPSBzd2lwZXI7XG4gICAgJGVsLmNoaWxkcmVuKCdbZGF0YS1zd2lwZXItcGFyYWxsYXhdLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgteF0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC15XSwgW2RhdGEtc3dpcGVyLXBhcmFsbGF4LW9wYWNpdHldLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgtc2NhbGVdJykuZWFjaChlbCA9PiB7XG4gICAgICBzZXRUcmFuc2Zvcm0oZWwsIHByb2dyZXNzKTtcbiAgICB9KTtcbiAgICBzbGlkZXMuZWFjaCgoc2xpZGVFbCwgc2xpZGVJbmRleCkgPT4ge1xuICAgICAgbGV0IHNsaWRlUHJvZ3Jlc3MgPSBzbGlkZUVsLnByb2dyZXNzO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCA+IDEgJiYgc3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3ICE9PSAnYXV0bycpIHtcbiAgICAgICAgc2xpZGVQcm9ncmVzcyArPSBNYXRoLmNlaWwoc2xpZGVJbmRleCAvIDIpIC0gcHJvZ3Jlc3MgKiAoc25hcEdyaWQubGVuZ3RoIC0gMSk7XG4gICAgICB9XG5cbiAgICAgIHNsaWRlUHJvZ3Jlc3MgPSBNYXRoLm1pbihNYXRoLm1heChzbGlkZVByb2dyZXNzLCAtMSksIDEpO1xuICAgICAgJChzbGlkZUVsKS5maW5kKCdbZGF0YS1zd2lwZXItcGFyYWxsYXhdLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgteF0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC15XSwgW2RhdGEtc3dpcGVyLXBhcmFsbGF4LW9wYWNpdHldLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgtc2NhbGVdJykuZWFjaChlbCA9PiB7XG4gICAgICAgI
1HNldFRyYW5zZm9ybShlbCwgc2xpZGVQcm9ncmVzcyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBzZXRUcmFuc2l0aW9uID0gKGR1cmF0aW9uID0gc3dpcGVyLnBhcmFtcy5zcGVlZCkgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgICRlbFxuICAgIH0gPSBzd2lwZXI7XG4gICAgJGVsLmZpbmQoJ1tkYXRhLXN3aXBlci1wYXJhbGxheF0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC14XSwgW2RhdGEtc3dpcGVyLXBhcmFsbGF4LXldLCBbZGF0YS1zd2lwZXItcGFyYWxsYXgtb3BhY2l0eV0sIFtkYXRhLXN3aXBlci1wYXJhbGxheC1zY2FsZV0nKS5lYWNoKHBhcmFsbGF4RWwgPT4ge1xuICAgICAgY29uc3QgJHBhcmFsbGF4RWwgPSAkKHBhcmFsbGF4RWwpO1xuICAgICAgbGV0IHBhcmFsbGF4RHVyYXRpb24gPSBwYXJzZUludCgkcGFyYWxsYXhFbC5hdHRyKCdkYXRhLXN3aXBlci1wYXJhbGxheC1kdXJhdGlvbicpLCAxMCkgfHwgZHVyYXRpb247XG4gICAgICBpZiAoZHVyYXRpb24gPT09IDApIHBhcmFsbGF4RHVyYXRpb24gPSAwO1xuICAgICAgJHBhcmFsbGF4RWwudHJhbnNpdGlvbihwYXJhbGxheER1cmF0aW9uKTtcbiAgICB9KTtcbiAgfTtcblxuICBvbignYmVmb3JlSW5pdCcsICgpID0+IHtcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMucGFyYWxsYXguZW5hYmxlZCkgcmV0dXJuO1xuICAgIHN3aXBlci5wYXJhbXMud2F0Y2hTbGlkZXNQcm9ncmVzcyA9IHRydWU7XG4gICAgc3dpcGVyLm9yaWdpbmFsUGFyYW1zLndhdGNoU2xpZGVzUHJvZ3Jlc3MgPSB0cnVlO1xuICB9KTtcbiAgb24oJ2luaXQnLCAoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnBhcmFsbGF4LmVuYWJsZWQpIHJldHVybjtcbiAgICBzZXRUcmFuc2xhdGUoKTtcbiAgfSk7XG4gIG9uKCdzZXRUcmFuc2xhdGUnLCAoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnBhcmFsbGF4LmVuYWJsZWQpIHJldHVybjtcbiAgICBzZXRUcmFuc2xhdGUoKTtcbiAgfSk7XG4gIG9uKCdzZXRUcmFuc2l0aW9uJywgKF9zd2lwZXIsIGR1cmF0aW9uKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnBhcmFsbGF4LmVuYWJsZWQpIHJldHVybjtcbiAgICBzZXRUcmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgfSk7XG59IiwiaW1wb3J0IHsgZ2V0V2luZG93IH0gZnJvbSAnc3NyLXdpbmRvdyc7XG5pbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmltcG9ydCB7IGdldFRyYW5zbGF0ZSB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscy5qcyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBab29tKHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uLFxuICBlbWl0XG59KSB7XG4gIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICBleHRlbmRQYXJhbXMoe1xuICAgIHpvb206IHtcbiAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgbWF4UmF0aW86IDMsXG4gICAgICBtaW5SYXRpbzogMSxcbiAgICAgIHRvZ2dsZTogdHJ1ZSxcbiAgICAgIGNvbnRhaW5lckNsYXNzOiAnc3dpcGVyLXpvb20tY29udGFpbmVyJyxcbiAgICAgIHpvb21lZFNsaWRlQ2xhc3M6ICdzd2lwZXItc2xpZGUtem9vbWVkJ1xuICAgIH1cbiAgfSk7XG4gIHN3aXBlci56b29tID0ge1xuICAgIGVuYWJsZWQ6IGZhbHNlXG4gIH07XG4gIGxldCBjdXJyZW50U2NhbGUgPSAxO1xuICBsZXQgaXNTY2FsaW5nID0gZmFsc2U7XG4gIGxldCBnZXN0dXJlc0VuYWJsZWQ7XG4gIGxldCBmYWtlR2VzdHVyZVRvdWNoZWQ7XG4gIGxldCBmYWtlR2VzdHVyZU1vdmVkO1xuICBjb25zdCBnZXN0dXJlID0ge1xuICAgICRzbGlkZUVsOiB1bmRlZmluZWQsXG4gICAgc2xpZGVXaWR0aDogdW5kZWZpbmVkLFxuICAgIHNsaWRlSGVpZ2h0OiB1bmRlZmluZWQsXG4gICAgJGltYWdlRWw6IHVuZGVmaW5lZCxcbiAgICAkaW1hZ2VXcmFwRWw6IHVuZGVmaW5lZCxcbiAgICBtYXhSYXRpbzogM1xuICB9O1xuICBjb25zdCBpbWFnZSA9IHtcbiAgICBpc1RvdWNoZWQ6IHVuZGVmaW5lZCxcbiAgICBpc01vdmVkOiB1bmRlZmluZWQsXG4gICAgY3VycmVudFg6IHVuZGVmaW5lZCxcbiAgICBjdXJyZW50WTogdW5kZWZpbmVkLFxuICAgIG1pblg6IHVuZGVmaW5lZCxcbiAgICBtaW5ZOiB1bmRlZmluZWQsXG4gICAgbWF4WDogdW5kZWZpbmVkLFxuICAgIG1heFk6IHVuZGVmaW5lZCxcbiAgICB3aWR0aDogdW5kZWZpbmVkLFxuICAgIGhlaWdodDogdW5kZWZpbmVkLFxuICAgIHN0YXJ0WDogdW5kZWZpbmVkLFxuICAgIHN0YXJ0WTogdW5kZWZpbmVkLFxuICAgIHRvdWNoZXNTdGFydDoge30sXG4gICAgdG91Y2hlc0N1cnJlbnQ6IHt9XG4gIH07XG4gIGNvbnN0IHZlbG9jaXR5ID0ge1xuICAgIHg6IHVuZGVmaW5lZCxcbiAgICB5OiB1bmRlZmluZWQsXG4gICAgcHJldlBvc2l0aW9uWDogdW5kZWZpbmVkLFxuICAgIHByZXZQb3NpdGlvblk6IHVuZGVmaW5lZCxcbiAgICBwcmV2VGltZTogdW5kZWZpbmVkXG4gIH07XG4gIGxldCBzY2FsZSA9IDE7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzd2lwZXIuem9vbSwgJ3NjYWxlJywge1xuICAgIGdldCgpIHtcbiAgICAgIHJldHVybiBzY2FsZTtcbiAgICB9LFxuXG4gICAgc2V0KHZhbHVlKSB7XG4gICAgICBpZiAoc2NhbGUgIT09IHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGltYWdlRWwgPSBnZXN0dXJlLiRpbWFnZUVsID8gZ2VzdHVyZS4kaW1hZ2VFbFswXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3Qgc2xpZGVFbCA9IGdlc3R1cmUuJHNsaWRlRWwgPyBnZXN0dXJlLiRzbGlkZUVsWzBdIDogdW5kZWZpbmVkO1xuICAgICAgICBlbWl0KCd6b29tQ2hhbmdlJywgdmFsdWUsIGltYWdlRWwsIHNsaWRlRWwpO1xuICAgICAgfVxuXG4gICAgICBzY2FsZSA9IHZhbHVlO1xuICAgIH1cblxuICB9KTtcblxuICBmdW5jdGlvbiBnZXREaXN0YW5jZUJldHdlZW5Ub3VjaGVzKGUpIHtcbiAgICBpZiAoZS50YXJnZXRUb3VjaGVzLmxlbmd0aCA8IDIpIHJldHVybiAxO1xuICAgIGNvbnN0IHgxID0gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VYO1xuICAgIGNvbnN0IHkxID0gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VZO1xuICAgIGNvbnN0IHgyID0gZS50YXJnZXRUb3VjaGVzWzFdLnBhZ2VYO1xuICAgIGNvbnN0IHkyID0gZS50YXJnZXRUb3VjaGVzWzFdLnBhZ2VZO1xuICAgIGNvbnN0IGRpc3R
1hbmNlID0gTWF0aC5zcXJ0KCh4MiAtIHgxKSAqKiAyICsgKHkyIC0geTEpICoqIDIpO1xuICAgIHJldHVybiBkaXN0YW5jZTtcbiAgfSAvLyBFdmVudHNcblxuXG4gIGZ1bmN0aW9uIG9uR2VzdHVyZVN0YXJ0KGUpIHtcbiAgICBjb25zdCBzdXBwb3J0ID0gc3dpcGVyLnN1cHBvcnQ7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy56b29tO1xuICAgIGZha2VHZXN0dXJlVG91Y2hlZCA9IGZhbHNlO1xuICAgIGZha2VHZXN0dXJlTW92ZWQgPSBmYWxzZTtcblxuICAgIGlmICghc3VwcG9ydC5nZXN0dXJlcykge1xuICAgICAgaWYgKGUudHlwZSAhPT0gJ3RvdWNoc3RhcnQnIHx8IGUudHlwZSA9PT0gJ3RvdWNoc3RhcnQnICYmIGUudGFyZ2V0VG91Y2hlcy5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZmFrZUdlc3R1cmVUb3VjaGVkID0gdHJ1ZTtcbiAgICAgIGdlc3R1cmUuc2NhbGVTdGFydCA9IGdldERpc3RhbmNlQmV0d2VlblRvdWNoZXMoZSk7XG4gICAgfVxuXG4gICAgaWYgKCFnZXN0dXJlLiRzbGlkZUVsIHx8ICFnZXN0dXJlLiRzbGlkZUVsLmxlbmd0aCkge1xuICAgICAgZ2VzdHVyZS4kc2xpZGVFbCA9ICQoZS50YXJnZXQpLmNsb3Nlc3QoYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVDbGFzc31gKTtcbiAgICAgIGlmIChnZXN0dXJlLiRzbGlkZUVsLmxlbmd0aCA9PT0gMCkgZ2VzdHVyZS4kc2xpZGVFbCA9IHN3aXBlci5zbGlkZXMuZXEoc3dpcGVyLmFjdGl2ZUluZGV4KTtcbiAgICAgIGdlc3R1cmUuJGltYWdlRWwgPSBnZXN0dXJlLiRzbGlkZUVsLmZpbmQoYC4ke3BhcmFtcy5jb250YWluZXJDbGFzc31gKS5lcSgwKS5maW5kKCdwaWN0dXJlLCBpbWcsIHN2ZywgY2FudmFzLCAuc3dpcGVyLXpvb20tdGFyZ2V0JykuZXEoMCk7XG4gICAgICBnZXN0dXJlLiRpbWFnZVdyYXBFbCA9IGdlc3R1cmUuJGltYWdlRWwucGFyZW50KGAuJHtwYXJhbXMuY29udGFpbmVyQ2xhc3N9YCk7XG4gICAgICBnZXN0dXJlLm1heFJhdGlvID0gZ2VzdHVyZS4kaW1hZ2VXcmFwRWwuYXR0cignZGF0YS1zd2lwZXItem9vbScpIHx8IHBhcmFtcy5tYXhSYXRpbztcblxuICAgICAgaWYgKGdlc3R1cmUuJGltYWdlV3JhcEVsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBnZXN0dXJlLiRpbWFnZUVsID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGdlc3R1cmUuJGltYWdlRWwpIHtcbiAgICAgIGdlc3R1cmUuJGltYWdlRWwudHJhbnNpdGlvbigwKTtcbiAgICB9XG5cbiAgICBpc1NjYWxpbmcgPSB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gb25HZXN0dXJlQ2hhbmdlKGUpIHtcbiAgICBjb25zdCBzdXBwb3J0ID0gc3dpcGVyLnN1cHBvcnQ7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy56b29tO1xuICAgIGNvbnN0IHpvb20gPSBzd2lwZXIuem9vbTtcblxuICAgIGlmICghc3VwcG9ydC5nZXN0dXJlcykge1xuICAgICAgaWYgKGUudHlwZSAhPT0gJ3RvdWNobW92ZScgfHwgZS50eXBlID09PSAndG91Y2htb3ZlJyAmJiBlLnRhcmdldFRvdWNoZXMubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGZha2VHZXN0dXJlTW92ZWQgPSB0cnVlO1xuICAgICAgZ2VzdHVyZS5zY2FsZU1vdmUgPSBnZXREaXN0YW5jZUJldHdlZW5Ub3VjaGVzKGUpO1xuICAgIH1cblxuICAgIGlmICghZ2VzdHVyZS4kaW1hZ2VFbCB8fCBnZXN0dXJlLiRpbWFnZUVsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKGUudHlwZSA9PT0gJ2dlc3R1cmVjaGFuZ2UnKSBvbkdlc3R1cmVTdGFydChlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoc3VwcG9ydC5nZXN0dXJlcykge1xuICAgICAgem9vbS5zY2FsZSA9IGUuc2NhbGUgKiBjdXJyZW50U2NhbGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHpvb20uc2NhbGUgPSBnZXN0dXJlLnNjYWxlTW92ZSAvIGdlc3R1cmUuc2NhbGVTdGFydCAqIGN1cnJlbnRTY2FsZTtcbiAgICB9XG5cbiAgICBpZiAoem9vbS5zY2FsZSA+IGdlc3R1cmUubWF4UmF0aW8pIHtcbiAgICAgIHpvb20uc2NhbGUgPSBnZXN0dXJlLm1heFJhdGlvIC0gMSArICh6b29tLnNjYWxlIC0gZ2VzdHVyZS5tYXhSYXRpbyArIDEpICoqIDAuNTtcbiAgICB9XG5cbiAgICBpZiAoem9vbS5zY2FsZSA8IHBhcmFtcy5taW5SYXRpbykge1xuICAgICAgem9vbS5zY2FsZSA9IHBhcmFtcy5taW5SYXRpbyArIDEgLSAocGFyYW1zLm1pblJhdGlvIC0gem9vbS5zY2FsZSArIDEpICoqIDAuNTtcbiAgICB9XG5cbiAgICBnZXN0dXJlLiRpbWFnZUVsLnRyYW5zZm9ybShgdHJhbnNsYXRlM2QoMCwwLDApIHNjYWxlKCR7em9vbS5zY2FsZX0pYCk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkdlc3R1cmVFbmQoZSkge1xuICAgIGNvbnN0IGRldmljZSA9IHN3aXBlci5kZXZpY2U7XG4gICAgY29uc3Qgc3VwcG9ydCA9IHN3aXBlci5zdXBwb3J0O1xuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuem9vbTtcbiAgICBjb25zdCB6b29tID0gc3dpcGVyLnpvb207XG5cbiAgICBpZiAoIXN1cHBvcnQuZ2VzdHVyZXMpIHtcbiAgICAgIGlmICghZmFrZUdlc3R1cmVUb3VjaGVkIHx8ICFmYWtlR2VzdHVyZU1vdmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGUudHlwZSAhPT0gJ3RvdWNoZW5kJyB8fCBlLnR5cGUgPT09ICd0b3VjaGVuZCcgJiYgZS5jaGFuZ2VkVG91Y2hlcy5sZW5ndGggPCAyICYmICFkZXZpY2UuYW5kcm9pZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGZha2VHZXN0dXJlVG91Y2hlZCA9IGZhbHNlO1xuICAgICAgZmFrZUdlc3R1cmVNb3ZlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghZ2VzdHVyZS4kaW1hZ2VFbCB8fCBnZXN0dXJlLiRpbWFnZUVsLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIHpvb20uc2NhbGUgPSBNYXRoLm1heChNYXRoLm1pbih6b29tLnNjYWxlLCBnZXN0dXJlLm1heFJhdGlvKSwgcGFyYW1zLm1pblJhdGlvKTtcbiAgICBnZXN0dXJlLiRpbWFnZUVsLnRyYW5zaXRpb24oc3dpcGVyLnBhcmFtcy5zcGVlZCkudHJhbnNmb3JtKGB0cmFuc2xhdGUzZCgwLDAsMCkgc2NhbGUoJHt6b29tLnNjYWxlfSlgKTtcbiAgICBjdXJyZW50U2NhbGUgPSB6b29tLnNjYWxlO1xuICAgIGlzU2NhbGluZyA9IGZhbHNlO1xuICAgIGlmICh6b29tLnNjYWxlID09PSAxKSBnZXN0dXJlLiRzbGlkZUVsID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgZnVuY3Rpb24gb25Ub3VjaFN0YXJ0KGUpIHtcbiAgICBjb25zdCBkZXZpY2UgPSBzd2lwZXIuZGV2aWNlO1xuICAgIGlmICghZ2VzdHVyZS4kaW1hZ2VFbCB8fCBnZXN0dXJlLiRpbWFnZUVsLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIGlmIChpbWFnZS5pc1RvdWNoZWQpIHJldHVybjtcbiAgICBpZiAoZGV2aWNlLmFuZHJvaWQgJiYgZS5jYW5jZWxhYmxlKSBlLnByZXZlbn
1REZWZhdWx0KCk7XG4gICAgaW1hZ2UuaXNUb3VjaGVkID0gdHJ1ZTtcbiAgICBpbWFnZS50b3VjaGVzU3RhcnQueCA9IGUudHlwZSA9PT0gJ3RvdWNoc3RhcnQnID8gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VYIDogZS5wYWdlWDtcbiAgICBpbWFnZS50b3VjaGVzU3RhcnQueSA9IGUudHlwZSA9PT0gJ3RvdWNoc3RhcnQnID8gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VZIDogZS5wYWdlWTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVG91Y2hNb3ZlKGUpIHtcbiAgICBjb25zdCB6b29tID0gc3dpcGVyLnpvb207XG4gICAgaWYgKCFnZXN0dXJlLiRpbWFnZUVsIHx8IGdlc3R1cmUuJGltYWdlRWwubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgc3dpcGVyLmFsbG93Q2xpY2sgPSBmYWxzZTtcbiAgICBpZiAoIWltYWdlLmlzVG91Y2hlZCB8fCAhZ2VzdHVyZS4kc2xpZGVFbCkgcmV0dXJuO1xuXG4gICAgaWYgKCFpbWFnZS5pc01vdmVkKSB7XG4gICAgICBpbWFnZS53aWR0aCA9IGdlc3R1cmUuJGltYWdlRWxbMF0ub2Zmc2V0V2lkdGg7XG4gICAgICBpbWFnZS5oZWlnaHQgPSBnZXN0dXJlLiRpbWFnZUVsWzBdLm9mZnNldEhlaWdodDtcbiAgICAgIGltYWdlLnN0YXJ0WCA9IGdldFRyYW5zbGF0ZShnZXN0dXJlLiRpbWFnZVdyYXBFbFswXSwgJ3gnKSB8fCAwO1xuICAgICAgaW1hZ2Uuc3RhcnRZID0gZ2V0VHJhbnNsYXRlKGdlc3R1cmUuJGltYWdlV3JhcEVsWzBdLCAneScpIHx8IDA7XG4gICAgICBnZXN0dXJlLnNsaWRlV2lkdGggPSBnZXN0dXJlLiRzbGlkZUVsWzBdLm9mZnNldFdpZHRoO1xuICAgICAgZ2VzdHVyZS5zbGlkZUhlaWdodCA9IGdlc3R1cmUuJHNsaWRlRWxbMF0ub2Zmc2V0SGVpZ2h0O1xuICAgICAgZ2VzdHVyZS4kaW1hZ2VXcmFwRWwudHJhbnNpdGlvbigwKTtcbiAgICB9IC8vIERlZmluZSBpZiB3ZSBuZWVkIGltYWdlIGRyYWdcblxuXG4gICAgY29uc3Qgc2NhbGVkV2lkdGggPSBpbWFnZS53aWR0aCAqIHpvb20uc2NhbGU7XG4gICAgY29uc3Qgc2NhbGVkSGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0ICogem9vbS5zY2FsZTtcbiAgICBpZiAoc2NhbGVkV2lkdGggPCBnZXN0dXJlLnNsaWRlV2lkdGggJiYgc2NhbGVkSGVpZ2h0IDwgZ2VzdHVyZS5zbGlkZUhlaWdodCkgcmV0dXJuO1xuICAgIGltYWdlLm1pblggPSBNYXRoLm1pbihnZXN0dXJlLnNsaWRlV2lkdGggLyAyIC0gc2NhbGVkV2lkdGggLyAyLCAwKTtcbiAgICBpbWFnZS5tYXhYID0gLWltYWdlLm1pblg7XG4gICAgaW1hZ2UubWluWSA9IE1hdGgubWluKGdlc3R1cmUuc2xpZGVIZWlnaHQgLyAyIC0gc2NhbGVkSGVpZ2h0IC8gMiwgMCk7XG4gICAgaW1hZ2UubWF4WSA9IC1pbWFnZS5taW5ZO1xuICAgIGltYWdlLnRvdWNoZXNDdXJyZW50LnggPSBlLnR5cGUgPT09ICd0b3VjaG1vdmUnID8gZS50YXJnZXRUb3VjaGVzWzBdLnBhZ2VYIDogZS5wYWdlWDtcbiAgICBpbWFnZS50b3VjaGVzQ3VycmVudC55ID0gZS50eXBlID09PSAndG91Y2htb3ZlJyA/IGUudGFyZ2V0VG91Y2hlc1swXS5wYWdlWSA6IGUucGFnZVk7XG5cbiAgICBpZiAoIWltYWdlLmlzTW92ZWQgJiYgIWlzU2NhbGluZykge1xuICAgICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSAmJiAoTWF0aC5mbG9vcihpbWFnZS5taW5YKSA9PT0gTWF0aC5mbG9vcihpbWFnZS5zdGFydFgpICYmIGltYWdlLnRvdWNoZXNDdXJyZW50LnggPCBpbWFnZS50b3VjaGVzU3RhcnQueCB8fCBNYXRoLmZsb29yKGltYWdlLm1heFgpID09PSBNYXRoLmZsb29yKGltYWdlLnN0YXJ0WCkgJiYgaW1hZ2UudG91Y2hlc0N1cnJlbnQueCA+IGltYWdlLnRvdWNoZXNTdGFydC54KSkge1xuICAgICAgICBpbWFnZS5pc1RvdWNoZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXN3aXBlci5pc0hvcml6b250YWwoKSAmJiAoTWF0aC5mbG9vcihpbWFnZS5taW5ZKSA9PT0gTWF0aC5mbG9vcihpbWFnZS5zdGFydFkpICYmIGltYWdlLnRvdWNoZXNDdXJyZW50LnkgPCBpbWFnZS50b3VjaGVzU3RhcnQueSB8fCBNYXRoLmZsb29yKGltYWdlLm1heFkpID09PSBNYXRoLmZsb29yKGltYWdlLnN0YXJ0WSkgJiYgaW1hZ2UudG91Y2hlc0N1cnJlbnQueSA+IGltYWdlLnRvdWNoZXNTdGFydC55KSkge1xuICAgICAgICBpbWFnZS5pc1RvdWNoZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlLmNhbmNlbGFibG
1UpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGltYWdlLmlzTW92ZWQgPSB0cnVlO1xuICAgIGltYWdlLmN1cnJlbnRYID0gaW1hZ2UudG91Y2hlc0N1cnJlbnQueCAtIGltYWdlLnRvdWNoZXNTdGFydC54ICsgaW1hZ2Uuc3RhcnRYO1xuICAgIGltYWdlLmN1cnJlbnRZID0gaW1hZ2UudG91Y2hlc0N1cnJlbnQueSAtIGltYWdlLnRvdWNoZXNTdGFydC55ICsgaW1hZ2Uuc3RhcnRZO1xuXG4gICAgaWYgKGltYWdlLmN1cnJlbnRYIDwgaW1hZ2UubWluWCkge1xuICAgICAgaW1hZ2UuY3VycmVudFggPSBpbWFnZS5taW5YICsgMSAtIChpbWFnZS5taW5YIC0gaW1hZ2UuY3VycmVudFggKyAxKSAqKiAwLjg7XG4gICAgfVxuXG4gICAgaWYgKGltYWdlLmN1cnJlbnRYID4gaW1hZ2UubWF4WCkge1xuICAgICAgaW1hZ2UuY3VycmVudFggPSBpbWFnZS5tYXhYIC0gMSArIChpbWFnZS5jdXJyZW50WCAtIGltYWdlLm1heFggKyAxKSAqKiAwLjg7XG4gICAgfVxuXG4gICAgaWYgKGltYWdlLmN1cnJlbnRZIDwgaW1hZ2UubWluWSkge1xuICAgICAgaW1hZ2UuY3VycmVudFkgPSBpbWFnZS5taW5ZICsgMSAtIChpbWFnZS5taW5ZIC0gaW1hZ2UuY3VycmVudFkgKyAxKSAqKiAwLjg7XG4gICAgfVxuXG4gICAgaWYgKGltYWdlLmN1cnJlbnRZID4gaW1hZ2UubWF4WSkge1xuICAgICAgaW1hZ2UuY3VycmVudFkgPSBpbWFnZS5tYXhZIC0gMSArIChpbWFnZS5jdXJyZW50WSAtIGltYWdlLm1heFkgKyAxKSAqKiAwLjg7XG4gICAgfSAvLyBWZWxvY2l0eVxuXG5cbiAgICBpZiAoIXZlbG9jaXR5LnByZXZQb3NpdGlvblgpIHZlbG9jaXR5LnByZXZQb3NpdGlvblggPSBpbWFnZS50b3VjaGVzQ3VycmVudC54O1xuICAgIGlmICghdmVsb2NpdHkucHJldlBvc2l0aW9uWSkgdmVsb2NpdHkucHJldlBvc2l0aW9uWSA9IGltYWdlLnRvdWNoZXNDdXJyZW50Lnk7XG4gICAgaWYgKCF2ZWxvY2l0eS5wcmV2VGltZSkgdmVsb2NpdHkucHJldlRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHZlbG9jaXR5LnggPSAoaW1hZ2UudG91Y2hlc0N1cnJlbnQueCAtIHZlbG9jaXR5LnByZXZQb3NpdGlvblgpIC8gKERhdGUubm93KCkgLSB2ZWxvY2l0eS5wcmV2VGltZSkgLyAyO1xuICAgIHZlbG9jaXR5LnkgPSAoaW1hZ2UudG91Y2hlc0N1cnJlbnQueSAtIHZlbG9jaXR5LnByZXZQb3NpdGlvblkpIC8gKERhdGUubm93KCkgLSB2ZWxvY2l0eS5wcmV2VGltZSkgLyAyO1xuICAgIGlmIChNYXRoLmFicyhpbWFnZS50b3VjaGVzQ3VycmVudC54IC0gdmVsb2NpdHkucHJldlBvc2l0aW9uWCkgPCAyKSB2ZWxvY2l0eS54ID0gMDtcbiAgICBpZiAoTWF0aC5hYnMoaW1hZ2UudG91Y2hlc0N1cnJlbnQueSAtIHZlbG9jaXR5LnByZXZQb3NpdGlvblkpIDwgMikgdmVsb2NpdHkueSA9IDA7XG4gICAgdmVsb2NpdHkucHJldlBvc2l0aW9uWCA9IGltYWdlLnRvdWNoZXNDdXJyZW50Lng7XG4gICAgdmVsb2NpdHkucHJldlBvc2l0aW9uWSA9IGltYWdlLnRvdWNoZXNDdXJyZW50Lnk7XG4gICAgdmVsb2NpdHkucHJldlRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGdlc3R1cmUuJGltYWdlV3JhcEVsLnRyYW5zZm9ybShgdHJhbnNsYXRlM2QoJHtpbWFnZS5jdXJyZW50WH1weCwgJHtpbWFnZS5jdXJyZW50WX1weCwwKWApO1xuICB9XG5cbiAgZnVuY3Rpb24gb25Ub3VjaEVuZCgpIHtcbiAgICBjb25zdCB6b29tID0gc3dpcGVyLnpvb207XG4gICAgaWYgKCFnZXN0dXJlLiRpbWFnZUVsIHx8IGdlc3R1cmUuJGltYWdlRWwubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBpZiAoIWltYWdlLmlzVG91Y2hlZCB8fCAhaW1hZ2UuaXNNb3ZlZCkge1xuICAgICAgaW1hZ2UuaXNUb3VjaGVkID0gZmFsc2U7XG4gICAgICBpbWFnZS5pc01vdmVkID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaW1hZ2UuaXNUb3VjaGVkID0gZmFsc2U7XG4gICAgaW1hZ2UuaXNNb3ZlZCA9IGZhbHNlO1xuICAgIGxldCBtb21lbnR1bUR1cmF0aW9uWCA9IDMwMDtcbiAgICBsZXQgbW9tZW50dW1EdXJhdGlvblkgPSAzMDA7XG4gICAgY29uc3QgbW9tZW50dW1EaXN0YW5jZVggPSB2ZWxvY2l0eS54ICogbW9tZW50dW1EdXJhdGlvblg7XG4gICAgY29uc3QgbmV3UG9zaXRpb25YID0gaW1hZ2UuY3VycmVudFggKyBtb21lbnR1bURpc3RhbmNlWDtcbiAgICBjb25zdCBtb21lbnR1bURpc3RhbmNlWSA9IHZlbG9jaXR5LnkgKiBtb21lbnR1bUR1cmF0aW9uWTtcbiAgICBjb25zdCBuZXdQb3NpdGlvblkgPSBpbWFnZS5jdXJyZW50WSArIG1vbWVudHVtRGlzdGFuY2VZOyAvLyBGaXggZHVyYXRpb25cblxuICAgIGlmICh2ZWxvY2l0eS54ICE9PSAwKSBtb21lbnR1bUR1cmF0aW9uWCA9IE1hdGguYWJzKChuZXdQb3NpdGlvblggLSBpbWFnZS5jdXJyZW50WCkgLyB2ZWxvY2l0eS54KTtcbiAgICBpZiAodmVsb2NpdHkueSAhPT0gMCkgbW9tZW50dW1EdXJhdGlvblkgPSBNYXRoLmFicygobmV3UG9zaXRpb25ZIC0gaW1hZ2UuY3VycmVudFkpIC8gdmVsb2NpdHkueSk7XG4gICAgY29uc3QgbW9tZW50dW1EdXJhdGlvbiA9IE1hdGgubWF4KG1vbWVudHVtRHVyYXRpb25YLCBtb21lbnR1bUR1cmF0aW9uWSk7XG4gICAgaW1hZ2UuY3VycmVudFggPSBuZXdQb3NpdGlvblg7XG4gICAgaW1hZ2UuY3VycmVudFkgPSBuZXdQb3NpdGlvblk7IC8vIERlZmluZSBpZiB3ZSBuZWVkIGltYWdlIGRyYWdcblxuICAgIGNvbnN0IHNjYWxlZFdpZHRoID0gaW1hZ2Uud2lkdGggKiB6b29tLnNjYWxlO1xuICAgIGNvbnN0IHNjYWxlZEhlaWdodCA9IGltYWdlLmhlaWdodCAqIHpvb20uc2NhbGU7XG4gICAgaW1hZ2UubWluWCA9IE1hdGgubWluKGdlc3R1cmUuc2xpZGVXaWR0aCAvIDIgLSBzY2FsZWRXaWR0aCAvIDIsIDApO1xuICAgIGltYWdlLm1heFggPSAtaW1hZ2UubWluWDtcbiAgICBpbWFnZS5taW5ZID0gTWF0aC5taW4oZ2VzdHVyZS5zbGlkZUhlaWdodCAvIDIgLSBzY2FsZWRIZWlnaHQgLyAyLCAwKTtcbiAgICBpbWFnZS5tYXhZID0gLWltYWdlLm1pblk7XG4gICAgaW1hZ2UuY3VycmVudFggPSBNYXRoLm1heChNYXRoLm1pbihpbWFnZS5jdXJyZW50WCwgaW1hZ2UubWF4WCksIGltYWdlLm1pblgpO1xuICAgIGltYWdlLmN1cnJlbnRZID0gTWF0aC5tYXgoTWF0aC5taW4oaW1hZ2UuY3VycmVudFksIGltYWdlLm1heFkpLCBpbWFnZS5taW5ZKTtcbiAgICBnZXN0dXJlLiRpbWFnZVdyYXBFbC50cmFuc2l0aW9uKG1vbWVudHVtRHVyYXRpb24pLnRyYW5zZm9ybShgdHJhbnNsYXRlM2QoJHtpbWFnZS5jdXJyZW50WH1weCwgJHtpbWFnZS5jdXJyZW50WX1weCwwKWApO1xuICB9XG5cbiAgZnVuY3Rpb24gb25UcmFuc2l0aW9uRW5kKCkge1xuICAgIGNvbnN0IHpvb20gPSBzd2lwZXIuem9vbTtcblxuICAgIGlmIChnZXN0dXJlLiRzbGlkZUVsICYmIHN3aXBlci5wcmV2aW91c0luZGV4ICE9PSBzd2lwZXIuYWN0aXZlSW5kZXgpIHtcbiAgICAgIGlmIChnZXN0dXJlLiRpbWFnZUVsKSB7XG4gICAgICAgIGdlc3R1cmUuJGltYWdlRWwudHJhbnNmb3JtKCd0cmFuc2xhdGUzZCgwLDAsMCkgc2NhbGUoMSknKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdlc3R1cmUuJGltYWdlV3JhcEVsKSB7XG4gICAgICAgIGdlc3R1cmUuJGltYWdlV3JhcEVsLnRyYW5zZm9ybSgndHJhbnNsYXRlM2QoMCwwLDApJyk7XG4gICAgICB9XG5cbiAgICAgIHpvb20uc2NhbGUgPSAxO1xuICAgICAgY3VycmVudFNjYWxlID0gMTtcbiAgICAgIGdlc3R1cmUuJHNsaWRlRWwgPSB1bmRlZmluZWQ7XG4gICAgICBnZXN0dXJlLiRpbWFnZUVsID0gdW5kZWZpbmVkO1xuICAgICAgZ2VzdHVyZS4kaW1hZ2VXcmFwRWwgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gem9vbUluKGUpIHtcbiAgICBjb25zdCB6b29tID0gc3dpcGVyLnpvb207XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy56b29tO1xuXG4gICAgaWYgKCFnZXN0dXJlLiRzbGlkZUVsKSB7XG4gICAgICBpZiAoZSAmJiBlLnRhcmdldCkge1xuICAgICAgICBnZXN0dXJlLiRzbGlkZUVsID0gJChlLnRhcmdldCkuY2xvc2VzdChgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzfWApO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWdlc3R1cmUuJHNsaWRlRWwpIHtcbiAgICAgICAgaWYgKHN3aXBlci5wYXJhbXMudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCAmJiBzd2lwZXIudmlydHVhbCkge1xuICAgICAgICAgIGdlc3R1cmUuJHNsaWRlRWwgPSBzd2lwZXIuJHdyYXBwZXJFbC5jaGlsZHJlbihgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUFjdGl2ZUNsYXNzfWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGdlc3R1cmUuJHNsaWRlRWwgPSBzd2lwZXIuc2xpZGVzLmVxKHN3aXBlci5hY3RpdmVJbmRleCk7XG4gICAgICAgI
1H1cbiAgICAgIH1cblxuICAgICAgZ2VzdHVyZS4kaW1hZ2VFbCA9IGdlc3R1cmUuJHNsaWRlRWwuZmluZChgLiR7cGFyYW1zLmNvbnRhaW5lckNsYXNzfWApLmVxKDApLmZpbmQoJ3BpY3R1cmUsIGltZywgc3ZnLCBjYW52YXMsIC5zd2lwZXItem9vbS10YXJnZXQnKS5lcSgwKTtcbiAgICAgIGdlc3R1cmUuJGltYWdlV3JhcEVsID0gZ2VzdHVyZS4kaW1hZ2VFbC5wYXJlbnQoYC4ke3BhcmFtcy5jb250YWluZXJDbGFzc31gKTtcbiAgICB9XG5cbiAgICBpZiAoIWdlc3R1cmUuJGltYWdlRWwgfHwgZ2VzdHVyZS4kaW1hZ2VFbC5sZW5ndGggPT09IDAgfHwgIWdlc3R1cmUuJGltYWdlV3JhcEVsIHx8IGdlc3R1cmUuJGltYWdlV3JhcEVsLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgICAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xuICAgICAgc3dpcGVyLndyYXBwZXJFbC5zdHlsZS50b3VjaEFjdGlvbiA9ICdub25lJztcbiAgICB9XG5cbiAgICBnZXN0dXJlLiRzbGlkZUVsLmFkZENsYXNzKGAke3BhcmFtcy56b29tZWRTbGlkZUNsYXNzfWApO1xuICAgIGxldCB0b3VjaFg7XG4gICAgbGV0IHRvdWNoWTtcbiAgICBsZXQgb2Zmc2V0WDtcbiAgICBsZXQgb2Zmc2V0WTtcbiAgICBsZXQgZGlmZlg7XG4gICAgbGV0IGRpZmZZO1xuICAgIGxldCB0cmFuc2xhdGVYO1xuICAgIGxldCB0cmFuc2xhdGVZO1xuICAgIGxldCBpbWFnZVdpZHRoO1xuICAgIGxldCBpbWFnZUhlaWdodDtcbiAgICBsZXQgc2NhbGVkV2lkdGg7XG4gICAgbGV0IHNjYWxlZEhlaWdodDtcbiAgICBsZXQgdHJhbnNsYXRlTWluWDtcbiAgICBsZXQgdHJhbnNsYXRlTWluWTtcbiAgICBsZXQgdHJhbnNsYXRlTWF4WDtcbiAgICBsZXQgdHJhbnNsYXRlTWF4WTtcbiAgICBsZXQgc2xpZGVXaWR0aDtcbiAgICBsZXQgc2xpZGVIZWlnaHQ7XG5cbiAgICBpZiAodHlwZW9mIGltYWdlLnRvdWNoZXNTdGFydC54ID09PSAndW5kZWZpbmVkJyAmJiBlKSB7XG4gICAgICB0b3VjaFggPSBlLnR5cGUgPT09ICd0b3VjaGVuZCcgPyBlLmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VYIDogZS5wYWdlWDtcbiAgICAgIHRvdWNoWSA9IGUudHlwZSA9PT0gJ3RvdWNoZW5kJyA/IGUuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVkgOiBlLnBhZ2VZO1xuICAgIH0gZWxzZSB7XG4gICAgICB0b3VjaFggPSBpbWFnZS50b3VjaGVzU3RhcnQueDtcbiAgICAgIHRvdWNoWSA9IGltYWdlLnRvdWNoZXNTdGFydC55O1xuICAgIH1cblxuICAgIHpvb20uc2NhbGUgPSBnZXN0dXJlLiRpbWFnZVdyYXBFbC5hdHRyKCdkYXRhLXN3aXBlci16b29tJykgfHwgcGFyYW1zLm1heFJhdGlvO1xuICAgIGN1cnJlbnRTY2FsZSA9IGdlc3R1cmUuJGltYWdlV3JhcEVsLmF0dHIoJ2RhdGEtc3dpcGVyLXpvb20nKSB8fCBwYXJhbXMubWF4UmF0aW87XG5cbiAgICBpZiAoZSkge1xuICAgICAgc2xpZGVXaWR0aCA9IGdlc3R1cmUuJHNsaWRlRWxbMF0ub2Zmc2V0V2lkdGg7XG4gICAgICBzbGlkZUhlaWdodCA9IGdlc3R1cmUuJHNsaWRlRWxbMF0ub2Zmc2V0SGVpZ2h0O1xuICAgICAgb2Zmc2V0WCA9IGdlc3R1cmUuJHNsaWRlRWwub2Zmc2V0KCkubGVmdCArIHdpbmRvdy5zY3JvbGxYO1xuICAgICAgb2Zmc2V0WSA9IGdlc3R1cmUuJHNsaWRlRWwub2Zmc2V0KCkudG9wICsgd2luZG93LnNjcm9sbFk7XG4gICAgICBkaWZmWCA9IG9mZnNldFggKyBzbGlkZVdpZHRoIC8gMiAtIHRvdWNoWDtcbiAgICAgIGRpZmZZID0gb2Zmc2V0WSArIHNsaWRlSGVpZ2h0IC8gMiAtIHRvdWNoWTtcbiAgICAgIGltYWdlV2lkdGggPSBnZXN0dXJlLiRpbWFnZUVsWzBdLm9mZnNldFdpZHRoO1xuICAgICAgaW1hZ2VIZWlnaHQgPSBnZXN0dXJlLiRpbWFnZUVsWzBdLm9mZnNldEhlaWdodDtcbiAgICAgIHNjYWxlZFdpZHRoID0gaW1hZ2VXaWR0aCAqIHpvb20uc2NhbGU7XG4gICAgICBzY2FsZWRIZWlnaHQgPSBpbWFnZUhlaWdodCAqIHpvb20uc2NhbGU7XG4gICAgICB0cmFuc2xhdGVNaW5YID0gTWF0aC5taW4oc2xpZGVXaWR0aCAvIDIgLSBzY2FsZWRXaWR0aCAvIDIsIDApO1xuICAgICAgdHJhbnNsYXRlTWluWSA9IE1hdGgubWluKHNsaWRlSGVpZ2h0IC8gMiAtIHNjYWxlZEhlaWdodCAvIDIsIDApO1xuICAgICAgdHJhbnNsYXRlTWF4WCA9IC10cmFuc2xhdGVNaW5YO1xuICAgICAgdHJhbnNsYXRlTWF4WSA9IC10cmFuc2xhdGVNaW5ZO1xuICAgICAgdHJhbnNsYXRlWCA9IGRpZmZYICogem9vbS5zY2FsZTtcbiAgICAgIHRyYW5zbGF0ZVkgPSBkaWZmWSAqIHpvb20uc2NhbGU7XG5cbiAgICAgIGlmICh0cmFuc2xhdGVYIDwgdHJhbnNsYXRlTWluWCkge1xuICAgICAgICB0cmFuc2xhdGVYID0gdHJhbnNsYXRlTWluWDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRyYW5zbGF0ZVggPiB0cmFuc2xhdGVNYXhYKSB7XG4gICAgICAgIHRyYW5zbGF0ZVggPSB0cmFuc2xhdGVNYXhYO1xuICAgICAgfVxuXG4gICAgICBpZiAodHJhbnNsYXRlWSA8IHRyYW5zbGF0ZU1pblkpIHtcbiAgICAgICAgdHJhbnNsYXRlWSA9IHRyYW5zbGF0ZU1pblk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0cmFuc2xhdGVZID4gdHJhbnNsYXRlTWF4WSkge1xuICAgICAgICB0cmFuc2xhdGVZID0gdHJhbnNsYXRlTWF4WTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdHJhbnNsYXRlWCA9IDA7XG4gICAgICB0cmFuc2xhdGVZID0gMDtcbiAgICB9XG5cbiAgICBnZXN0dXJlLiRpbWFnZVdyYXBFbC50cmFuc2l0aW9uKDMwMCkudHJhbnNmb3JtKGB0cmFuc2xhdGUzZCgke3RyYW5zbGF0ZVh9cHgsICR7dHJhbnNsYXRlWX1weCwwKWApO1xuICAgIGdlc3R1cmUuJGltYWdlRWwudHJhbnNpdGlvbigzMDApLnRyYW5zZm9ybShgdHJhbnNsYXRlM2QoMCwwLDApIHNjYWxlKCR7em9vbS5zY2FsZX0pYCk7XG4gIH1cblxuICBmdW5jdGlvbiB6b29tT3V0KCkge1xuICAgIGNvbnN0IHpvb20gPSBzd2lwZXIuem9vbTtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLnpvb207XG5cbiAgICBpZiAoIWdlc3R1cmUuJHNsaWRlRWwpIHtcbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLnZpcnR1YWwgJiYgc3dpcGVyLnBhcmFtcy52aXJ0dWFsLmVuYWJsZWQgJiYgc3dpcGVyLnZpcnR1YWwpIHtcbiAgICAgICAgZ2VzdHVyZS4kc2xpZGVFbCA9IHN3aXBlci4kd3JhcHBlckVsLmNoaWxkcmVuKGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQWN0aXZlQ2xhc3N9YCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBnZXN0dXJlLiRzbGlkZUVsID0gc3dpcGVyLnNsaWRlcy5lcShzd2lwZXIuYWN0aXZlSW5kZXgpO1xuICAgICAgfVxuXG4gICAgICBnZXN0dXJlLiRpbWFnZUVsID0gZ2VzdHVyZS4kc2xpZGVFbC5maW5kKGAuJHtwYXJhbXMuY29udGFpbmVyQ2xhc3N9YCkuZXEoMCkuZmluZCgncGljdHVyZSwgaW1nLCBzdmcsIGNhbnZhcywgLnN3aXBlci16b29tLXRhcmdldCcpLmVxKDApO1xuICAgICAgZ2VzdHVyZS4kaW1hZ2VXcmFwRWwgPSBnZXN0dXJlLiRpbWFnZUVsLnBhcmVudChgLiR7cGFyYW1zLmNvbnRhaW5lckNsYXNzfWApO1xuICAgIH1cblxuICAgIGlmICghZ2VzdHVyZS4kaW1hZ2VFbCB8fCBnZXN0dXJlLiRpbWFnZUVsLmxlbmd0aCA9PT0gMCB8fCAhZ2VzdHVyZS4kaW1hZ2VXcmFwRWwgfHwgZ2VzdHVyZS4kaW1hZ2VXcmFwRWwubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICBzd2lwZXIud3JhcHBlckVsLnN0eWxlLm92ZXJmbG93ID0gJyc7XG4gICAgICBzd2lwZXIud3JhcHBlckVsLnN0eWxlLnRvdWNoQWN0aW9uID0gJyc7XG4gICAgfVxuXG4gICAgem9vbS5zY2FsZSA9IDE7XG4gICAgY3VycmVudFNjYWxlID0gMTtcbiAgICBnZXN0dXJlLiRpbWFnZVdyYXBFbC50cmFuc2l0aW9uKDMwMCkudHJhbnNmb3JtKCd0cmFuc2xhdGUzZCgwLDAsMCknKTtcbiAgICBnZXN0dXJlLiRpbWFnZUVsLnRyYW5zaXRpb24oMzAwKS50cmFuc2Zvcm0oJ3RyYW5zbGF0ZTNkKDAsMCwwKSBzY2FsZSgxKScpO1xuICAgIGdlc3R1cmUuJHNsaWRlRWwucmVtb3ZlQ2xhc3MoYCR7cGFyYW1zLnpvb21lZFNsaWRlQ2xhc3N9YCk7XG4gICAgZ2VzdHVyZS4kc2xpZGVFbCA9IHVuZGVmaW5lZDtcbiAgfSAvLyBUb2dnbGUgWm9vbVxuXG5cbiAgZnVuY3Rpb24gem9vbVRvZ2dsZShlKSB7XG4gICAgY29uc3Qgem9vbSA9IHN3aXBlci56b29tO1xuXG4gICAgaWYgKHpvb20uc2NhbGUgJiYgem9vbS5zY2FsZSAhPT0gMSkge1xuICAgICAgLy8gWm9vbSBPdXRcbiAgICAgIHpvb21PdXQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gWm9vbSBJblxuICAgICAgem9vbUluKGUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGdldExpc3RlbmVycygpIHtcbiAgICBjb25zdCBzdXBwb3J0ID0gc3dpcGVyLnN1cHBvcnQ7XG4gICAgY29uc3QgcGFzc2l2ZUxpc3RlbmVyID0gc3dpcGVyLnRvdWNoRXZlbnRzLnN0YXJ0ID09PSAndG91Y2hzdGFydCcgJiYgc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgJiYgc3dpcGVyLnBhcmFtcy5wYXNzaXZlTGlzdGVuZXJzID8ge1xuICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICAgIGNhcHR1cmU6IGZhbHNlXG4gICAgfSA6IGZhbHNlO1xuICAgIGNvbnN0IGFjdGl2ZUxpc3RlbmVyV2l0aENhcHR1cmUgPSBzdXBwb3J0LnBhc3NpdmVMaXN0ZW5lciA/IHtcbiAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgY2FwdHVyZTogdHJ1ZVxuICAgIH0gOiB0cnVlO1xuICAgIHJldHVybi
1B7XG4gICAgICBwYXNzaXZlTGlzdGVuZXIsXG4gICAgICBhY3RpdmVMaXN0ZW5lcldpdGhDYXB0dXJlXG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFNsaWRlU2VsZWN0b3IoKSB7XG4gICAgcmV0dXJuIGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3N9YDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvZ2dsZUdlc3R1cmVzKG1ldGhvZCkge1xuICAgIGNvbnN0IHtcbiAgICAgIHBhc3NpdmVMaXN0ZW5lclxuICAgIH0gPSBnZXRMaXN0ZW5lcnMoKTtcbiAgICBjb25zdCBzbGlkZVNlbGVjdG9yID0gZ2V0U2xpZGVTZWxlY3RvcigpO1xuICAgIHN3aXBlci4kd3JhcHBlckVsW21ldGhvZF0oJ2dlc3R1cmVzdGFydCcsIHNsaWRlU2VsZWN0b3IsIG9uR2VzdHVyZVN0YXJ0LCBwYXNzaXZlTGlzdGVuZXIpO1xuICAgIHN3aXBlci4kd3JhcHBlckVsW21ldGhvZF0oJ2dlc3R1cmVjaGFuZ2UnLCBzbGlkZVNlbGVjdG9yLCBvbkdlc3R1cmVDaGFuZ2UsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgc3dpcGVyLiR3cmFwcGVyRWxbbWV0aG9kXSgnZ2VzdHVyZWVuZCcsIHNsaWRlU2VsZWN0b3IsIG9uR2VzdHVyZUVuZCwgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuYWJsZUdlc3R1cmVzKCkge1xuICAgIGlmIChnZXN0dXJlc0VuYWJsZWQpIHJldHVybjtcbiAgICBnZXN0dXJlc0VuYWJsZWQgPSB0cnVlO1xuICAgIHRvZ2dsZUdlc3R1cmVzKCdvbicpO1xuICB9XG5cbiAgZnVuY3Rpb24gZGlzYWJsZUdlc3R1cmVzKCkge1xuICAgIGlmICghZ2VzdHVyZXNFbmFibGVkKSByZXR1cm47XG4gICAgZ2VzdHVyZXNFbmFibGVkID0gZmFsc2U7XG4gICAgdG9nZ2xlR2VzdHVyZXMoJ29mZicpO1xuICB9IC8vIEF0dGFjaC9EZXRhY2ggRXZlbnRzXG5cblxuICBmdW5jdGlvbiBlbmFibGUoKSB7XG4gICAgY29uc3Qgem9vbSA9IHN3aXBlci56b29tO1xuICAgIGlmICh6b29tLmVuYWJsZWQpIHJldHVybjtcbiAgICB6b29tLmVuYWJsZWQgPSB0cnVlO1xuICAgIGNvbnN0IHN1cHBvcnQgPSBzd2lwZXIuc3VwcG9ydDtcbiAgICBjb25zdCB7XG4gICAgICBwYXNzaXZlTGlzdGVuZXIsXG4gICAgICBhY3RpdmVMaXN0ZW5lcldpdGhDYXB0dXJlXG4gICAgfSA9IGdldExpc3RlbmVycygpO1xuICAgIGNvbnN0IHNsaWRlU2VsZWN0b3IgPSBnZXRTbGlkZVNlbGVjdG9yKCk7IC8vIFNjYWxlIGltYWdlXG5cbiAgICBpZiAoc3VwcG9ydC5nZXN0dXJlcykge1xuICAgICAgc3dpcGVyLiR3cmFwcGVyRWwub24oc3dpcGVyLnRvdWNoRXZlbnRzLnN0YXJ0LCBlbmFibGVHZXN0dXJlcywgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9uKHN3aXBlci50b3VjaEV2ZW50cy5lbmQsIGRpc2FibGVHZXN0dXJlcywgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICB9IGVsc2UgaWYgKHN3aXBlci50b3VjaEV2ZW50cy5zdGFydCA9PT0gJ3RvdWNoc3RhcnQnKSB7XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbC5vbihzd2lwZXIudG91Y2hFdmVudHMuc3RhcnQsIHNsaWRlU2VsZWN0b3IsIG9uR2VzdHVyZVN0YXJ0LCBwYXNzaXZlTGlzdGVuZXIpO1xuICAgICAgc3dpcGVyLiR3cmFwcGVyRWwub24oc3dpcGVyLnRvdWNoRXZlbnRzLm1vdmUsIHNsaWRlU2VsZWN0b3IsIG9uR2VzdHVyZUNoYW5nZSwgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSk7XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbC5vbihzd2lwZXIudG91Y2hFdmVudHMuZW5kLCBzbGlkZVNlbGVjdG9yLCBvbkdlc3R1cmVFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG5cbiAgICAgIGlmIChzd2lwZXIudG91Y2hFdmVudHMuY2FuY2VsKSB7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9uKHN3aXBlci50b3VjaEV2ZW50cy5jYW5jZWwsIHNsaWRlU2VsZWN0b3IsIG9uR2VzdHVyZUVuZCwgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9IC8vIE1vdmUgaW1hZ2VcblxuXG4gICAgc3dpcGVyLiR3cmFwcGVyRWwub24oc3dpcGVyLnRvdWNoRXZlbnRzLm1vdmUsIGAuJHtzd2lwZXIucGFyYW1zLnpvb20uY29udGFpbmVyQ2xhc3N9YCwgb25Ub3VjaE1vdmUsIGFjdGl2ZUxpc3RlbmVyV2l0aENhcHR1cmUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZGlzYWJsZSgpIHtcbiAgICBjb25zdCB6b29tID0gc3dpcGVyLnpvb207XG4gICAgaWYgKCF6b29tLmVuYWJsZWQpIHJldHVybjtcbiAgICBjb25zdCBzdXBwb3J0ID0gc3dpcGVyLnN1cHBvcnQ7XG4gICAgem9vbS5lbmFibGVkID0gZmFsc2U7XG4gICAgY29uc3Qge1xuICAgICAgcGFzc2l2ZUxpc3RlbmVyLFxuICAgICAgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZVxuICAgIH0gPSBnZXRMaXN0ZW5lcnMoKTtcbiAgICBjb25zdCBzbGlkZVNlbGVjdG9yID0gZ2V0U2xpZGVTZWxlY3RvcigpOyAvLyBTY2FsZSBpbWFnZVxuXG4gICAgaWYgKHN1cHBvcnQuZ2VzdHVyZXMpIHtcbiAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9mZihzd2lwZXIudG91Y2hFdmVudHMuc3RhcnQsIGVuYWJsZUdlc3R1cmVzLCBwYXNzaXZlTGlzdGVuZXIpO1xuICAgICAgc3dpcGVyLiR3cmFwcGVyRWwub2ZmKHN3aXBlci50b3VjaEV2ZW50cy5lbmQsIGRpc2FibGVHZXN0dXJlcywgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICB9IGVsc2UgaWYgKHN3aXBlci50b3VjaEV2ZW50cy5zdGFydCA9PT0gJ3RvdWNoc3RhcnQnKSB7XG4gICAgICBzd2lwZXIuJHdyYXBwZXJFbC5vZmYoc3dpcGVyLnRvdWNoRXZlbnRzLnN0YXJ0LCBzbGlkZVNlbGVjdG9yLCBvbkdlc3R1cmVTdGFydCwgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9mZihzd2lwZXIudG91Y2hFdmVudHMubW92ZSwgc2xpZGVTZWxlY3Rvciwgb25HZXN0dXJlQ2hhbmdlLCBhY3RpdmVMaXN0ZW5lcldpdGhDYXB0dXJlKTtcbiAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9mZihzd2lwZXIudG91Y2hFdmVudHMuZW5kLCBzbGlkZVNlbGVjdG9yLCBvbkdlc3R1cmVFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG5cbiAgICAgIGlmIChzd2lwZXIudG91Y2hFdmVudHMuY2FuY2VsKSB7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsLm9mZihzd2lwZXIudG91Y2hFdmVudHMuY2FuY2VsLCBzbGlkZVNlbGVjdG9yLCBvbkdlc3R1cmVFbmQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfSAvLyBNb3ZlIGltYWdlXG5cblxuICAgI
1HN3aXBlci4kd3JhcHBlckVsLm9mZihzd2lwZXIudG91Y2hFdmVudHMubW92ZSwgYC4ke3N3aXBlci5wYXJhbXMuem9vbS5jb250YWluZXJDbGFzc31gLCBvblRvdWNoTW92ZSwgYWN0aXZlTGlzdGVuZXJXaXRoQ2FwdHVyZSk7XG4gIH1cblxuICBvbignaW5pdCcsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy56b29tLmVuYWJsZWQpIHtcbiAgICAgIGVuYWJsZSgpO1xuICAgIH1cbiAgfSk7XG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xuICAgIGRpc2FibGUoKTtcbiAgfSk7XG4gIG9uKCd0b3VjaFN0YXJ0JywgKF9zLCBlKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIuem9vbS5lbmFibGVkKSByZXR1cm47XG4gICAgb25Ub3VjaFN0YXJ0KGUpO1xuICB9KTtcbiAgb24oJ3RvdWNoRW5kJywgKF9zLCBlKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIuem9vbS5lbmFibGVkKSByZXR1cm47XG4gICAgb25Ub3VjaEVuZChlKTtcbiAgfSk7XG4gIG9uKCdkb3VibGVUYXAnLCAoX3MsIGUpID0+IHtcbiAgICBpZiAoIXN3aXBlci5hbmltYXRpbmcgJiYgc3dpcGVyLnBhcmFtcy56b29tLmVuYWJsZWQgJiYgc3dpcGVyLnpvb20uZW5hYmxlZCAmJiBzd2lwZXIucGFyYW1zLnpvb20udG9nZ2xlKSB7XG4gICAgICB6b29tVG9nZ2xlKGUpO1xuICAgIH1cbiAgfSk7XG4gIG9uKCd0cmFuc2l0aW9uRW5kJywgKCkgPT4ge1xuICAgIGlmIChzd2lwZXIuem9vbS5lbmFibGVkICYmIHN3aXBlci5wYXJhbXMuem9vbS5lbmFibGVkKSB7XG4gICAgICBvblRyYW5zaXRpb25FbmQoKTtcbiAgICB9XG4gIH0pO1xuICBvbignc2xpZGVDaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci56b29tLmVuYWJsZWQgJiYgc3dpcGVyLnBhcmFtcy56b29tLmVuYWJsZWQgJiYgc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSB7XG4gICAgICBvblRyYW5zaXRpb25FbmQoKTtcbiAgICB9XG4gIH0pO1xuICBPYmplY3QuYXNzaWduKHN3aXBlci56b29tLCB7XG4gICAgZW5hYmxlLFxuICAgIGRpc2FibGUsXG4gICAgaW46IHpvb21JbixcbiAgICBvdXQ6IHpvb21PdXQsXG4gICAgdG9nZ2xlOiB6b29tVG9nZ2xlXG4gIH0pO1xufSIsImltcG9ydCB7IGdldFdpbmRvdyB9IGZyb20gJ3Nzci13aW5kb3cnO1xuaW1wb3J0ICQgZnJvbSAnLi4vLi4vc2hhcmVkL2RvbS5qcyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBMYXp5KHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uLFxuICBlbWl0XG59KSB7XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAgbGF6eToge1xuICAgICAgY2hlY2tJblZpZXc6IGZhbHNlLFxuICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICBsb2FkUHJldk5leHQ6IGZhbHNlLFxuICAgICAgbG9hZFByZXZOZXh0QW1vdW50OiAxLFxuICAgICAgbG9hZE9uVHJhbnNpdGlvblN0YXJ0OiBmYWxzZSxcbiAgICAgIHNjcm9sbGluZ0VsZW1lbnQ6ICcnLFxuICAgICAgZWxlbWVudENsYXNzOiAnc3dpcGVyLWxhenknLFxuICAgICAgbG9hZGluZ0NsYXNzOiAnc3dpcGVyLWxhenktbG9hZGluZycsXG4gICAgICBsb2FkZWRDbGFzczogJ3N3aXBlci1sYXp5LWxvYWRlZCcsXG4gICAgICBwcmVsb2FkZXJDbGFzczogJ3N3aXBlci1sYXp5LXByZWxvYWRlcidcbiAgICB9XG4gIH0pO1xuICBzd2lwZXIubGF6eSA9IHt9O1xuICBsZXQgc2Nyb2xsSGFuZGxlckF0dGFjaGVkID0gZmFsc2U7XG4gIGxldCBpbml0aWFsSW1hZ2VMb2FkZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBsb2FkSW5TbGlkZShpbmRleCwgbG9hZEluRHVwbGljYXRlID0gdHJ1ZSkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMubGF6eTtcbiAgICBpZiAodHlwZW9mIGluZGV4ID09PSAndW5kZWZpbmVkJykgcmV0dXJuO1xuICAgIGlmIChzd2lwZXIuc2xpZGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIGNvbnN0IGlzVmlydHVhbCA9IHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkO1xuICAgIGNvbnN0ICRzbGlkZUVsID0gaXNWaXJ0dWFsID8gc3dpcGVyLiR3cmFwcGVyRWwuY2hpbGRyZW4oYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVDbGFzc31bZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke2luZGV4fVwiXWApIDogc3dpcGVyLnNsaWRlcy5lcShpbmRleCk7XG4gICAgY29uc3QgJGltYWdlcyA9ICRzbGlkZUVsLmZpbmQoYC4ke3BhcmFtcy5lbGVtZW50Q2xhc3N9Om5vdCguJHtwYXJhbXMubG9hZGVkQ2xhc3N9KTpub3QoLiR7cGFyYW1zLmxvYWRpbmdDbGFzc30pYCk7XG5cbiAgICBpZiAoJHNsaWRlRWwuaGFzQ2xhc3MocGFyYW1zLmVsZW1lbnRDbGFzcykgJiYgISRzbGlkZUVsLmhhc0NsYXNzKHBhcmFtcy5sb2FkZWRDbGFzcykgJiYgISRzbGlkZUVsLmhhc0NsYXNzKHBhcmFtcy5sb2FkaW5nQ2xhc3MpKSB7XG4gICAgICAkaW1hZ2VzLnB1c2goJHNsaWRlRWxbMF0pO1xuICAgIH1cblxuICAgIGlmICgkaW1hZ2VzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICRpbWFnZXMuZWFjaChpbWFnZUVsID0+IHtcbiAgICAgIGNvbnN0ICRpbWFnZUVsID0gJChpbWFnZUVsKTtcbiAgICAgICRpbWFnZUVsLmFkZENsYXNzKHBhcmFtcy5sb2FkaW5nQ2xhc3MpO1xuICAgICAgY29uc3QgYmFja2dyb3VuZCA9ICRpbWFnZUVsLmF0dHIoJ2RhdGEtYmFja2dyb3VuZCcpO1xuICAgICAgY29uc3Qgc3JjID0gJGltYWdlRWwuYXR0cignZGF0YS1zcmMnKTtcbiAgICAgIGNvbnN0IHNyY3NldCA9ICRpbWFnZUVsLmF0dHIoJ2RhdGEtc3Jjc2V0Jyk7XG4gICAgICBjb25zdCBzaXplcyA9ICRpbWFnZUVsLmF0dHIoJ2RhdGEtc2l6ZXMnKTtcbiAgICAgIGNvbnN0ICRwaWN0dXJlRWwgPSAkaW1hZ2VFbC5wYXJlbnQoJ3BpY3R1cmUnKTtcbiAgICAgIHN3aXBlci5sb2FkSW1hZ2UoJGltYWdlRWxbMF0sIHNyYyB8fCBiYWNrZ3JvdW5kLCBzcmNzZXQsIHNpemVzLCBmYWxzZSwgKCkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHN3aXBlciA9PT0gJ3VuZGVmaW5lZCcgfHwgc3dpcGVyID09PSBudWxsIHx8ICFzd2lwZXIgfHwgc3dpcGVyICYmICFzd2lwZXIucGFyYW1zIHx8IHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcblxuICAgICAgICBpZiAoYmFja2dyb3VuZCkge1xuICAgICAgICAgICRpbWFnZUVsLmNzcygnYmFja2dyb3VuZC1pbWFnZScsIGB1cmwoXCIke2JhY2tncm91bmR9XCIpYCk7XG4gICAgICAgICAgJGltYWdlRWwucmVtb3ZlQXR0cignZGF0YS1iYWNrZ3JvdW5kJyk7XG4gICAgICAgI
1H0gZWxzZSB7XG4gICAgICAgICAgaWYgKHNyY3NldCkge1xuICAgICAgICAgICAgJGltYWdlRWwuYXR0cignc3Jjc2V0Jywgc3Jjc2V0KTtcbiAgICAgICAgICAgICRpbWFnZUVsLnJlbW92ZUF0dHIoJ2RhdGEtc3Jjc2V0Jyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNpemVzKSB7XG4gICAgICAgICAgICAkaW1hZ2VFbC5hdHRyKCdzaXplcycsIHNpemVzKTtcbiAgICAgICAgICAgICRpbWFnZUVsLnJlbW92ZUF0dHIoJ2RhdGEtc2l6ZXMnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoJHBpY3R1cmVFbC5sZW5ndGgpIHtcbiAgICAgICAgICAgICRwaWN0dXJlRWwuY2hpbGRyZW4oJ3NvdXJjZScpLmVhY2goc291cmNlRWwgPT4ge1xuICAgICAgICAgICAgICBjb25zdCAkc291cmNlID0gJChzb3VyY2VFbCk7XG5cbiAgICAgICAgICAgICAgaWYgKCRzb3VyY2UuYXR0cignZGF0YS1zcmNzZXQnKSkge1xuICAgICAgICAgICAgICAgICRzb3VyY2UuYXR0cignc3Jjc2V0JywgJHNvdXJjZS5hdHRyKCdkYXRhLXNyY3NldCcpKTtcbiAgICAgICAgICAgICAgICAkc291cmNlLnJlbW92ZUF0dHIoJ2RhdGEtc3Jjc2V0Jyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChzcmMpIHtcbiAgICAgICAgICAgICRpbWFnZUVsLmF0dHIoJ3NyYycsIHNyYyk7XG4gICAgICAgICAgICAkaW1hZ2VFbC5yZW1vdmVBdHRyKCdkYXRhLXNyYycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgICRpbWFnZUVsLmFkZENsYXNzKHBhcmFtcy5sb2FkZWRDbGFzcykucmVtb3ZlQ2xhc3MocGFyYW1zLmxvYWRpbmdDbGFzcyk7XG4gICAgICAgICRzbGlkZUVsLmZpbmQoYC4ke3BhcmFtcy5wcmVsb2FkZXJDbGFzc31gKS5yZW1vdmUoKTtcblxuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wICYmIGxvYWRJbkR1cGxpY2F0ZSkge1xuICAgICAgICAgIGNvbnN0IHNsaWRlT3JpZ2luYWxJbmRleCA9ICRzbGlkZUVsLmF0dHIoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4Jyk7XG5cbiAgICAgICAgICBpZiAoJHNsaWRlRWwuaGFzQ2xhc3Moc3dpcGVyLnBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzKSkge1xuICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxTbGlkZSA9IHN3aXBlci4kd3JhcHBlckVsLmNoaWxkcmVuKGBbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke3NsaWRlT3JpZ2luYWxJbmRleH1cIl06bm90KC4ke3N3aXBlci5wYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzc30pYCk7XG4gICAgICAgICAgICBsb2FkSW5TbGlkZShvcmlnaW5hbFNsaWRlLmluZGV4KCksIGZhbHNlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZHVwbGljYXRlZFNsaWRlID0gc3dpcGVyLiR3cmFwcGVyRWwuY2hpbGRyZW4oYC4ke3N3aXBlci5wYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzc31bZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke3NsaWRlT3JpZ2luYWxJbmRleH1cIl1gKTtcbiAgICAgICAgICAgIGxvYWRJblNsaWRlKGR1cGxpY2F0ZWRTbGlkZS5pbmRleCgpLCBmYWxzZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZW1pdCgnbGF6eUltYWdlUmVhZHknLCAkc2xpZGVFbFswXSwgJGltYWdlRWxbMF0pO1xuXG4gICAgICAgIGlmIChzd2lwZXIucGFyYW1zLmF1dG9IZWlnaHQpIHtcbiAgICAgICAgICBzd2lwZXIudXBkYXRlQXV0b0hlaWdodCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGVtaXQoJ2xhenlJbWFnZUxvYWQnLCAkc2xpZGVFbFswXSwgJGltYWdlRWxbMF0pO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gbG9hZCgpIHtcbiAgICBjb25zdCB7XG4gICAgICAkd3JhcHBlckVsLFxuICAgICAgcGFyYW1zOiBzd2lwZXJQYXJhbXMsXG4gICAgICBzbGlkZXMsXG4gICAgICBhY3RpdmVJbmRleFxuICAgIH0gPSBzd2lwZXI7XG4gICAgY29uc3QgaXNWaXJ0dWFsID0gc3dpcGVyLnZpcnR1YWwgJiYgc3dpcGVyUGFyYW1zLnZpcnR1YWwuZW5hYmxlZDtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXJQYXJhbXMubGF6eTtcbiAgICBsZXQgc2xpZGVzUGVyVmlldyA9IHN3aXBlclBhcmFtcy5zbGlkZXNQZXJWaWV3O1xuXG4gICAgaWYgKHNsaWRlc1BlclZpZXcgPT09ICdhdXRvJykge1xuICAgICAgc2xpZGVzUGVyVmlldyA9IDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2xpZGVFeGlzdChpbmRleCkge1xuICAgICAgaWYgKGlzVmlydHVhbCkge1xuICAgICAgICBpZiAoJHdyYXBwZXJFbC5jaGlsZHJlbihgLiR7c3dpcGVyUGFyYW1zLnNsaWRlQ2xhc3N9W2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtpbmRleH1cIl1gKS5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzbGlkZXNbaW5kZXhdKSByZXR1cm4gdHJ1ZTtcblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNsaWRlSW5kZXgoc2xpZGVFbCkge1xuICAgICAgaWYgKGlzVmlydHVhbCkge1xuICAgICAgICByZXR1cm4gJChzbGlkZUVsKS5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gJChzbGlkZUVsKS5pbmRleCgpO1xuICAgIH1cblxuICAgIGlmICghaW5pdGlhbEltYWdlTG9hZGVkKSBpbml0aWFsSW1hZ2VMb2FkZWQgPSB0cnVlO1xuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMud2F0Y2hTbGlkZXNQcm9ncmVzcykge1xuICAgICAgJHdyYXBwZXJFbC5jaGlsZHJlbihgLiR7c3dpcGVyUGFyYW1zLnNsaWRlVmlzaWJsZUNsYXNzfWApLmVhY2goc2xpZGVFbCA9PiB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gaXNWaXJ0dWFsID8gJChzbGlkZUVsKS5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpIDogJChzbGlkZUVsKS5pbmRleCgpO1xuICAgICAgICBsb2FkSW5TbGlkZShpbmRleCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHNsaWRlc1BlclZpZXcgPiAxKSB7XG4gICAgICBmb3IgKGxldCBpID0gYWN0aXZlSW5kZXg7IGkgPCBhY3RpdmVJbmRleCArIHNsaWRlc1BlclZpZXc7IGkgKz0gMSkge1xuICAgICAgICBpZiAoc2xpZGVFeGlzdChpKSkgbG9hZEluU2xpZGUoaSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvYWRJblNsaWRlKGFjdGl2ZUluZGV4KTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmxvYWRQcmV2TmV4dCkge1xuICAgICAgaWYgKHNsaWRlc1BlclZpZXcgPiAxIH
1x8IHBhcmFtcy5sb2FkUHJldk5leHRBbW91bnQgJiYgcGFyYW1zLmxvYWRQcmV2TmV4dEFtb3VudCA+IDEpIHtcbiAgICAgICAgY29uc3QgYW1vdW50ID0gcGFyYW1zLmxvYWRQcmV2TmV4dEFtb3VudDtcbiAgICAgICAgY29uc3Qgc3B2ID0gTWF0aC5jZWlsKHNsaWRlc1BlclZpZXcpO1xuICAgICAgICBjb25zdCBtYXhJbmRleCA9IE1hdGgubWluKGFjdGl2ZUluZGV4ICsgc3B2ICsgTWF0aC5tYXgoYW1vdW50LCBzcHYpLCBzbGlkZXMubGVuZ3RoKTtcbiAgICAgICAgY29uc3QgbWluSW5kZXggPSBNYXRoLm1heChhY3RpdmVJbmRleCAtIE1hdGgubWF4KHNwdiwgYW1vdW50KSwgMCk7IC8vIE5leHQgU2xpZGVzXG5cbiAgICAgICAgZm9yIChsZXQgaSA9IGFjdGl2ZUluZGV4ICsgc3B2OyBpIDwgbWF4SW5kZXg7IGkgKz0gMSkge1xuICAgICAgICAgIGlmIChzbGlkZUV4aXN0KGkpKSBsb2FkSW5TbGlkZShpKTtcbiAgICAgICAgfSAvLyBQcmV2IFNsaWRlc1xuXG5cbiAgICAgICAgZm9yIChsZXQgaSA9IG1pbkluZGV4OyBpIDwgYWN0aXZlSW5kZXg7IGkgKz0gMSkge1xuICAgICAgICAgIGlmIChzbGlkZUV4aXN0KGkpKSBsb2FkSW5TbGlkZShpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbmV4dFNsaWRlID0gJHdyYXBwZXJFbC5jaGlsZHJlbihgLiR7c3dpcGVyUGFyYW1zLnNsaWRlTmV4dENsYXNzfWApO1xuICAgICAgICBpZiAobmV4dFNsaWRlLmxlbmd0aCA+IDApIGxvYWRJblNsaWRlKHNsaWRlSW5kZXgobmV4dFNsaWRlKSk7XG4gICAgICAgIGNvbnN0IHByZXZTbGlkZSA9ICR3cmFwcGVyRWwuY2hpbGRyZW4oYC4ke3N3aXBlclBhcmFtcy5zbGlkZVByZXZDbGFzc31gKTtcbiAgICAgICAgaWYgKHByZXZTbGlkZS5sZW5ndGggPiAwKSBsb2FkSW5TbGlkZShzbGlkZUluZGV4KHByZXZTbGlkZSkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNoZWNrSW5WaWV3T25Mb2FkKCkge1xuICAgIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcbiAgICBjb25zdCAkc2Nyb2xsRWxlbWVudCA9IHN3aXBlci5wYXJhbXMubGF6eS5zY3JvbGxpbmdFbGVtZW50ID8gJChzd2lwZXIucGFyYW1zLmxhenkuc2Nyb2xsaW5nRWxlbWVudCkgOiAkKHdpbmRvdyk7XG4gICAgY29uc3QgaXNXaW5kb3cgPSAkc2Nyb2xsRWxlbWVudFswXSA9PT0gd2luZG93O1xuICAgIGNvbnN0IHNjcm9sbEVsZW1lbnRXaWR0aCA9IGlzV2luZG93ID8gd2luZG93LmlubmVyV2lkdGggOiAkc2Nyb2xsRWxlbWVudFswXS5vZmZzZXRXaWR0aDtcbiAgICBjb25zdCBzY3JvbGxFbGVtZW50SGVpZ2h0ID0gaXNXaW5kb3cgPyB3aW5kb3cuaW5uZXJIZWlnaHQgOiAkc2Nyb2xsRWxlbWVudFswXS5vZmZzZXRIZWlnaHQ7XG4gICAgY29uc3Qgc3dpcGVyT2Zmc2V0ID0gc3dpcGVyLiRlbC5vZmZzZXQoKTtcbiAgICBjb25zdCB7XG4gICAgICBydGxUcmFuc2xhdGU6IHJ0bFxuICAgIH0gPSBzd2lwZXI7XG4gICAgbGV0IGluVmlldyA9IGZhbHNlO1xuICAgIGlmIChydGwpIHN3aXBlck9mZnNldC5sZWZ0IC09IHN3aXBlci4kZWxbMF0uc2Nyb2xsTGVmdDtcbiAgICBjb25zdCBzd2lwZXJDb29yZCA9IFtbc3dpcGVyT2Zmc2V0LmxlZnQsIHN3aXBlck9mZnNldC50b3BdLCBbc3dpcGVyT2Zmc2V0LmxlZnQgKyBzd2lwZXIud2lkdGgsIHN3aXBlck9mZnNldC50b3BdLCBbc3dpcGVyT2Zmc2V0LmxlZnQsIHN3aXBlck9mZnNldC50b3AgKyBzd2lwZXIuaGVpZ2h0XSwgW3N3aXBlck9mZnNldC5sZWZ0ICsgc3dpcGVyLndpZHRoLCBzd2lwZXJPZmZzZXQudG9wICsgc3dpcGVyLmhlaWdodF1dO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzd2lwZXJDb29yZC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3QgcG9pbnQgPSBzd2lwZXJDb29yZFtpXTtcblxuICAgICAgaWYgKHBvaW50WzBdID49IDAgJiYgcG9pbnRbMF0gPD0gc2Nyb2xsRWxlbWVudFdpZHRoICYmIHBvaW50WzFdID49IDAgJiYgcG9pbnRbMV0gPD0gc2Nyb2xsRWxlbWVudEhlaWdodCkge1xuICAgICAgICBpZiAocG9pbnRbMF0gPT09IDAgJiYgcG9pbnRbMV0gPT09IDApIGNvbnRpbnVlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbiAgICAgICAgaW5WaWV3ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBwYXNzaXZlTGlzdGVuZXIgPSBzd2lwZXIudG91Y2hFdmVudHMuc3RhcnQgPT09ICd0b3VjaHN0YXJ0JyAmJiBzd2lwZXIuc3VwcG9ydC5wYXNzaXZlTGlzdGVuZXIgJiYgc3dpcGVyLnBhcmFtcy5wYXNzaXZlTGlzdGVuZXJzID8ge1xuICAgICAgcGFzc2l2ZTogdHJ1ZSxcbiAgICAgIGNhcHR1cmU6IGZhbHNlXG4gICAgfSA6IGZhbHNlO1xuXG4gICAgaWYgKGluVmlldykge1xuICAgICAgbG9hZCgpO1xuICAgICAgJHNjcm9sbEVsZW1lbnQub2ZmKCdzY3JvbGwnLCBjaGVja0luVmlld09uTG9hZCwgcGFzc2l2ZUxpc3RlbmVyKTtcbiAgICB9IGVsc2UgaWYgKCFzY3JvbGxIYW5kbGVyQXR0YWNoZWQpIHtcbiAgICAgIHNjcm9sbEhhbmRsZXJBdHRhY2hlZCA9IHRydWU7XG4gICAgICAkc2Nyb2xsRWxlbWVudC5vbignc2Nyb2xsJywgY2hlY2tJblZpZXdPbkxvYWQsIHBhc3NpdmVMaXN0ZW5lcik7XG4gICAgfVxuICB9XG5cbiAgb24oJ2JlZm9yZUluaXQnLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMubGF6eS5lbmFibGVkICYmIHN3aXBlci5wYXJhbXMucHJlbG9hZEltYWdlcykge1xuICAgICAgc3dpcGVyLnBhcmFtcy5wcmVsb2FkSW1hZ2VzID0gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgb24oJ2luaXQnLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMubGF6eS5lbmFibGVkKSB7XG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmNoZWNrSW5WaWV3KSB7XG4gICAgICAgIGNoZWNrSW5WaWV3T25Mb2FkKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2FkKCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgb24oJ3Njcm9sbCcsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5mcmVlTW9kZSAmJiBzd2lwZXIucGFyYW1zLmZyZWVNb2RlLmVuYWJsZWQgJiYgIXN3aXBlci5wYXJhbXMuZnJlZU1vZGUuc3RpY2t5KSB7XG4gICAgICBsb2FkKCk7XG4gICAgfVxuICB9KTtcbiAgb24oJ3Njcm9sbGJhckRyYWdNb3ZlIHJlc2l6ZSBfZnJlZU1vZGVOb01vbWVudHVtUmVsZWFzZScsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmVuYWJsZWQpIHtcbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmxhenkuY2hlY2tJblZpZXcpIHtcbiAgICAgICAgY2hlY2tJblZpZXdPbkxvYWQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvYWQoKTtcbiAgICAgIH1cbiAgICB9XG4gI
1H0pO1xuICBvbigndHJhbnNpdGlvblN0YXJ0JywgKCkgPT4ge1xuICAgIGlmIChzd2lwZXIucGFyYW1zLmxhenkuZW5hYmxlZCkge1xuICAgICAgaWYgKHN3aXBlci5wYXJhbXMubGF6eS5sb2FkT25UcmFuc2l0aW9uU3RhcnQgfHwgIXN3aXBlci5wYXJhbXMubGF6eS5sb2FkT25UcmFuc2l0aW9uU3RhcnQgJiYgIWluaXRpYWxJbWFnZUxvYWRlZCkge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmNoZWNrSW5WaWV3KSB7XG4gICAgICAgICAgY2hlY2tJblZpZXdPbkxvYWQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsb2FkKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICBvbigndHJhbnNpdGlvbkVuZCcsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5sYXp5LmVuYWJsZWQgJiYgIXN3aXBlci5wYXJhbXMubGF6eS5sb2FkT25UcmFuc2l0aW9uU3RhcnQpIHtcbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmxhenkuY2hlY2tJblZpZXcpIHtcbiAgICAgICAgY2hlY2tJblZpZXdPbkxvYWQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvYWQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICBvbignc2xpZGVDaGFuZ2UnLCAoKSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgbGF6eSxcbiAgICAgIGNzc01vZGUsXG4gICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzLFxuICAgICAgdG91Y2hSZWxlYXNlT25FZGdlcyxcbiAgICAgIHJlc2lzdGFuY2VSYXRpb1xuICAgIH0gPSBzd2lwZXIucGFyYW1zO1xuXG4gICAgaWYgKGxhenkuZW5hYmxlZCAmJiAoY3NzTW9kZSB8fCB3YXRjaFNsaWRlc1Byb2dyZXNzICYmICh0b3VjaFJlbGVhc2VPbkVkZ2VzIHx8IHJlc2lzdGFuY2VSYXRpbyA9PT0gMCkpKSB7XG4gICAgICBsb2FkKCk7XG4gICAgfVxuICB9KTtcbiAgb24oJ2Rlc3Ryb3knLCAoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIuJGVsKSByZXR1cm47XG4gICAgc3dpcGVyLiRlbC5maW5kKGAuJHtzd2lwZXIucGFyYW1zLmxhenkubG9hZGluZ0NsYXNzfWApLnJlbW92ZUNsYXNzKHN3aXBlci5wYXJhbXMubGF6eS5sb2FkaW5nQ2xhc3MpO1xuICB9KTtcbiAgT2JqZWN0LmFzc2lnbihzd2lwZXIubGF6eSwge1xuICAgIGxvYWQsXG4gICAgbG9hZEluU2xpZGVcbiAgfSk7XG59IiwiLyogZXNsaW50IG5vLWJpdHdpc2U6IFtcImVycm9yXCIsIHsgXCJhbGxvd1wiOiBbXCI+PlwiXSB9XSAqL1xuaW1wb3J0IHsgbmV4dFRpY2sgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXRpbHMuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ29udHJvbGxlcih7XG4gIHN3aXBlcixcbiAgZXh0ZW5kUGFyYW1zLFxuICBvblxufSkge1xuICBleHRlbmRQYXJhbXMoe1xuICAgIGNvbnRyb2xsZXI6IHtcbiAgICAgIGNvbnRyb2w6IHVuZGVmaW5lZCxcbiAgICAgIGludmVyc2U6IGZhbHNlLFxuICAgICAgYnk6ICdzbGlkZScgLy8gb3IgJ2NvbnRhaW5lcidcblxuICAgI
1H1cbiAgfSk7XG4gIHN3aXBlci5jb250cm9sbGVyID0ge1xuICAgIGNvbnRyb2w6IHVuZGVmaW5lZFxuICB9O1xuXG4gIGZ1bmN0aW9uIExpbmVhclNwbGluZSh4LCB5KSB7XG4gICAgY29uc3QgYmluYXJ5U2VhcmNoID0gZnVuY3Rpb24gc2VhcmNoKCkge1xuICAgICAgbGV0IG1heEluZGV4O1xuICAgICAgbGV0IG1pbkluZGV4O1xuICAgICAgbGV0IGd1ZXNzO1xuICAgICAgcmV0dXJuIChhcnJheSwgdmFsKSA9PiB7XG4gICAgICAgIG1pbkluZGV4ID0gLTE7XG4gICAgICAgIG1heEluZGV4ID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlIChtYXhJbmRleCAtIG1pbkluZGV4ID4gMSkge1xuICAgICAgICAgIGd1ZXNzID0gbWF4SW5kZXggKyBtaW5JbmRleCA+PiAxO1xuXG4gICAgICAgICAgaWYgKGFycmF5W2d1ZXNzXSA8PSB2YWwpIHtcbiAgICAgICAgICAgIG1pbkluZGV4ID0gZ3Vlc3M7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1heEluZGV4ID0gZ3Vlc3M7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1heEluZGV4O1xuICAgICAgfTtcbiAgICB9KCk7XG5cbiAgICB0aGlzLnggPSB4O1xuICAgIHRoaXMueSA9IHk7XG4gICAgdGhpcy5sYXN0SW5kZXggPSB4Lmxlbmd0aCAtIDE7IC8vIEdpdmVuIGFuIHggdmFsdWUgKHgyKSwgcmV0dXJuIHRoZSBleHBlY3RlZCB5MiB2YWx1ZTpcbiAgICAvLyAoeDEseTEpIGlzIHRoZSBrbm93biBwb2ludCBiZWZvcmUgZ2l2ZW4gdmFsdWUsXG4gICAgLy8gKHgzLHkzKSBpcyB0aGUga25vd24gcG9pbnQgYWZ0ZXIgZ2l2ZW4gdmFsdWUuXG5cbiAgICBsZXQgaTE7XG4gICAgbGV0IGkzO1xuXG4gICAgdGhpcy5pbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uIGludGVycG9sYXRlKHgyKSB7XG4gICAgICBpZiAoIXgyKSByZXR1cm4gMDsgLy8gR2V0IHRoZSBpbmRleGVzIG9mIHgxIGFuZCB4MyAodGhlIGFycmF5IGluZGV4ZXMgYmVmb3JlIGFuZCBhZnRlciBnaXZlbiB4Mik6XG5cbiAgICAgIGkzID0gYmluYXJ5U2VhcmNoKHRoaXMueCwgeDIpO1xuICAgICAgaTEgPSBpMyAtIDE7IC8vIFdlIGhhdmUgb3VyIGluZGV4ZXMgaTEgJiBpMywgc28gd2UgY2FuIGNhbGN1bGF0ZSBhbHJlYWR5OlxuICAgICAgLy8geTIgOj0gKCh4MuKIkngxKSDDlyAoeTPiiJJ5MSkpIMO3ICh4M+KIkngxKSArIHkxXG5cbiAgICAgIHJldHVybiAoeDIgLSB0aGlzLnhbaTFdKSAqICh0aGlzLnlbaTNdIC0gdGhpcy55W2kxXSkgLyAodGhpcy54W2kzXSAtIHRoaXMueFtpMV0pICsgdGhpcy55W2kxXTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0gLy8geHh4OiBmb3Igbm93IGkgd2lsbCBqdXN0IHNhdmUgb25lIHNwbGluZSBmdW5jdGlvbiB0byB0b1xuXG5cbiAgZnVuY3Rpb24gZ2V0SW50ZXJwb2xhdGVGdW5jdGlvbihjKSB7XG4gICAgaWYgKCFzd2lwZXIuY29udHJvbGxlci5zcGxpbmUpIHtcbiAgICAgIHN3aXBlci5jb250cm9sbGVyLnNwbGluZSA9IHN3aXBlci5wYXJhbXMubG9vcCA/IG5ldyBMaW5lYXJTcGxpbmUoc3dpcGVyLnNsaWRlc0dyaWQsIGMuc2xpZGVzR3JpZCkgOiBuZXcgTGluZWFyU3BsaW5lKHN3aXBlci5zbmFwR3JpZCwgYy5zbmFwR3JpZCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2V0VHJhbnNsYXRlKF90LCBieUNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBjb250cm9sbGVkID0gc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbDtcbiAgICBsZXQgbXVsdGlwbGllcjtcbiAgICBsZXQgY29udHJvbGxlZFRyYW5zbGF0ZTtcbiAgICBjb25zdCBTd2lwZXIgPSBzd2lwZXIuY29uc3RydWN0b3I7XG5cbiAgICBmdW5jdGlvbiBzZXRDb250cm9sbGVkVHJhbnNsYXRlKGMpIHtcbiAgICAgIC8vIHRoaXMgd2lsbCBjcmVhdGUgYW4gSW50ZXJwb2xhdGUgZnVuY3Rpb24gYmFzZWQgb24gdGhlIHNuYXBHcmlkc1xuICAgICAgLy8geCBpcyB0aGUgR3JpZCBvZiB0aGUgc2Nyb2xsZWQgc2Nyb2xsZXIgYW5kIHkgd2lsbCBiZSB0aGUgY29udHJvbGxlZCBzY3JvbGxlclxuICAgICAgLy8gaXQgbWFrZXMgc2Vuc2UgdG8gY3JlYXRlIHRoaXMgb25seSBvbmNlIGFuZCByZWNhbGwgaXQgZm9yIHRoZSBpbnRlcnBvbGF0aW9uXG4gICAgICAvLyB0aGUgZnVuY3Rpb24gZG9lcyBhIGxvdCBvZiB2YWx1ZSBjYWNoaW5nIGZvciBwZXJmb3JtYW5jZVxuICAgICAgY29uc3QgdHJhbnNsYXRlID0gc3dpcGVyLnJ0bFRyYW5zbGF0ZSA/IC1zd2lwZXIudHJhbnNsYXRlIDogc3dpcGVyLnRyYW5zbGF0ZTtcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5ieSA9PT0gJ3NsaWRlJykge1xuICAgICAgICBnZXRJbnRlcnBvbGF0ZUZ1bmN0aW9uKGMpOyAvLyBpIGFtIG5vdCBzdXJlIHdoeSB0aGUgdmFsdWVzIGhhdmUgdG8gYmUgbXVsdGlwbGljYXRlZCB0aGlzIHdheSwgdHJpZWQgdG8gaW52ZXJ0IHRoZSBzbmFwR3JpZFxuICAgICAgICAvLyBidXQgaXQgZGlkIG5vdCB3b3JrIG91dFxuXG4gICAgICAgIGNvbnRyb2xsZWRUcmFuc2xhdGUgPSAtc3dpcGVyLmNvbnRyb2xsZXIuc3BsaW5lLmludGVycG9sYXRlKC10cmFuc2xhdGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbnRyb2xsZWRUcmFuc2xhdGUgfHwgc3dpcGVyLnBhcmFtcy5jb250cm9sbGVyLmJ5ID09PSAnY29udGFpbmVyJykge1xuICAgICAgICBtdWx0aXBsaWVyID0gKGMubWF4VHJhbnNsYXRlKCkgLSBjLm1pblRyYW5zbGF0ZSgpKSAvIChzd2lwZXIubWF4VHJhbnNsYXRlKCkgLSBzd2lwZXIubWluVHJhbnNsYXRlKCkpO1xuICAgICAgICBjb250cm9sbGVkVHJhbnNsYXRlID0gKHRyYW5zbGF0ZSAtIHN3aXBlci5taW5UcmFuc2xhdGUoKSkgKiBtdWx0aXBsaWVyICsgYy5taW5UcmFuc2xhdGUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5pbnZlcnNlKSB7XG4gICAgICAgIGNvbnRyb2xsZWRUcmFuc2xhdGUgPSBjLm1heFRyYW5zbGF0ZSgpIC0gY29udHJvbGxlZFRyYW5zbGF0ZTtcbiAgICAgIH1cblxuICAgICAgYy51cGRhdGVQcm9ncmVzcyhjb250cm9sbGVkVHJhbnNsYXRlKTtcbiAgICAgIGMuc2V0VHJhbnNsYXRlKGNvbnRyb2xsZWRUcmFuc2xhdGUsIHN3aXBlcik7XG4gICAgICBjLnVwZGF0ZUFjdGl2ZUluZGV4KCk7XG4gICAgICBjLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShjb250cm9sbGVkKSkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb250cm9sbGVkLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGlmIChjb250cm9sbGVkW2ldICE9PSBieUNvbnRyb2xsZXIgJiYgY29udHJvbGxlZFtpXSBpbnN0YW5jZW9mIFN3aXBlcikge1xuICAgICAgICAgI
1HNldENvbnRyb2xsZWRUcmFuc2xhdGUoY29udHJvbGxlZFtpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGNvbnRyb2xsZWQgaW5zdGFuY2VvZiBTd2lwZXIgJiYgYnlDb250cm9sbGVyICE9PSBjb250cm9sbGVkKSB7XG4gICAgICBzZXRDb250cm9sbGVkVHJhbnNsYXRlKGNvbnRyb2xsZWQpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFRyYW5zaXRpb24oZHVyYXRpb24sIGJ5Q29udHJvbGxlcikge1xuICAgIGNvbnN0IFN3aXBlciA9IHN3aXBlci5jb25zdHJ1Y3RvcjtcbiAgICBjb25zdCBjb250cm9sbGVkID0gc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbDtcbiAgICBsZXQgaTtcblxuICAgIGZ1bmN0aW9uIHNldENvbnRyb2xsZWRUcmFuc2l0aW9uKGMpIHtcbiAgICAgIGMuc2V0VHJhbnNpdGlvbihkdXJhdGlvbiwgc3dpcGVyKTtcblxuICAgICAgaWYgKGR1cmF0aW9uICE9PSAwKSB7XG4gICAgICAgIGMudHJhbnNpdGlvblN0YXJ0KCk7XG5cbiAgICAgICAgaWYgKGMucGFyYW1zLmF1dG9IZWlnaHQpIHtcbiAgICAgICAgICBuZXh0VGljaygoKSA9PiB7XG4gICAgICAgICAgICBjLnVwZGF0ZUF1dG9IZWlnaHQoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGMuJHdyYXBwZXJFbC50cmFuc2l0aW9uRW5kKCgpID0+IHtcbiAgICAgICAgICBpZiAoIWNvbnRyb2xsZWQpIHJldHVybjtcblxuICAgICAgICAgIGlmIChjLnBhcmFtcy5sb29wICYmIHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5ieSA9PT0gJ3NsaWRlJykge1xuICAgICAgICAgICAgYy5sb29wRml4KCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYy50cmFuc2l0aW9uRW5kKCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KGNvbnRyb2xsZWQpKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgY29udHJvbGxlZC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAoY29udHJvbGxlZFtpXSAhPT0gYnlDb250cm9sbGVyICYmIGNvbnRyb2xsZWRbaV0gaW5zdGFuY2VvZiBTd2lwZXIpIHtcbiAgICAgICAgICBzZXRDb250cm9sbGVkVHJhbnNpdGlvbihjb250cm9sbGVkW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29udHJvbGxlZCBpbnN0YW5jZW9mIFN3aXBlciAmJiBieUNvbnRyb2xsZXIgIT09IGNvbnRyb2xsZWQpIHtcbiAgICAgIHNldENvbnRyb2xsZWRUcmFuc2l0aW9uKGNvbnRyb2xsZWQpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZVNwbGluZSgpIHtcbiAgICBpZiAoIXN3aXBlci5jb250cm9sbGVyLmNvbnRyb2wpIHJldHVybjtcblxuICAgIGlmIChzd2lwZXIuY29udHJvbGxlci5zcGxpbmUpIHtcbiAgICAgIHN3aXBlci5jb250cm9sbGVyLnNwbGluZSA9IHVuZGVmaW5lZDtcbiAgICAgIGRlbGV0ZSBzd2lwZXIuY29udHJvbGxlci5zcGxpbmU7XG4gICAgfVxuICB9XG5cbiAgb24oJ2JlZm9yZUluaXQnLCAoKSA9PiB7XG4gICAgc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbCA9IHN3aXBlci5wYXJhbXMuY29udHJvbGxlci5jb250cm9sO1xuICB9KTtcbiAgb24oJ3VwZGF0ZScsICgpID0+IHtcbiAgICByZW1vdmVTcGxpbmUoKTtcbiAgfSk7XG4gIG9uKCdyZXNpemUnLCAoKSA9PiB7XG4gICAgcmVtb3ZlU3BsaW5lKCk7XG4gIH0pO1xuICBvbignb2JzZXJ2ZXJVcGRhdGUnLCAoKSA9PiB7XG4gICAgcmVtb3ZlU3BsaW5lKCk7XG4gIH0pO1xuICBvbignc2V0VHJhbnNsYXRlJywgKF9zLCB0cmFuc2xhdGUsIGJ5Q29udHJvbGxlcikgPT4ge1xuICAgIGlmICghc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbCkgcmV0dXJuO1xuICAgIHN3aXBlci5jb250cm9sbGVyLnNldFRyYW5zbGF0ZSh0cmFuc2xhdGUsIGJ5Q29udHJvbGxlcik7XG4gIH0pO1xuICBvbignc2V0VHJhbnNpdGlvbicsIChfcywgZHVyYXRpb24sIGJ5Q29udHJvbGxlcikgPT4ge1xuICAgIGlmICghc3dpcGVyLmNvbnRyb2xsZXIuY29udHJvbCkgcmV0dXJuO1xuICAgIHN3aXBlci5jb250cm9sbGVyLnNldFRyYW5zaXRpb24oZHVyYXRpb24sIGJ5Q29udHJvbGxlcik7XG4gIH0pO1xuICBPYmplY3QuYXNzaWduKHN3aXBlci5jb250cm9sbGVyLCB7XG4gICAgc2V0VHJhbnNsYXRlLFxuICAgIHNldFRyYW5zaXRpb25cbiAgfSk7XG59IiwiaW1wb3J0IGNsYXNzZXNUb1NlbGVjdG9yIGZyb20gJy4uLy4uL3NoYXJlZC9jbGFzc2VzLXRvLXNlbGVjdG9yLmpzJztcbmltcG9ydCAkIGZyb20gJy4uLy4uL3NoYXJlZC9kb20uanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQTExeSh7XG4gIHN3aXBlcixcbiAgZXh0ZW5kUGFyYW1zLFxuICBvblxufSkge1xuICBleHRlbmRQYXJhbXMoe1xuICAgIGExMXk6IHtcbiAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICBub3RpZmljYXRpb25DbGFzczogJ3N3aXBlci1ub3RpZmljYXRpb24nLFxuICAgICAgcHJldlNsaWRlTWVzc2FnZTogJ1ByZXZpb3VzIHNsaWRlJyxcbiAgICAgIG5leHRTbGlkZU1lc3NhZ2U6ICdOZXh0IHNsaWRlJyxcbiAgICAgIGZpcnN0U2xpZGVNZXNzYWdlOiAnVGhpcyBpcyB0aGUgZmlyc3Qgc2xpZGUnLFxuICAgICAgbGFzdFNsaWRlTWVzc2FnZTogJ1RoaXMgaXMgdGhlIGxhc3Qgc2xpZGUnLFxuICAgICAgcGFnaW5hdGlvbkJ1bGxldE1lc3NhZ2U6ICdHbyB0byBzbGlkZSB7e2luZGV4fX0nLFxuICAgICAgc2xpZGVMYWJlbE1lc3NhZ2U6ICd7e2luZGV4fX0gLyB7e3NsaWRlc0xlbmd0aH19JyxcbiAgICAgIGNvbnRhaW5lck1lc3NhZ2U6IG51bGwsXG4gICAgICBjb250YWluZXJSb2xlRGVzY3JpcHRpb25NZXNzYWdlOiBudWxsLFxuICAgICAgaXRlbVJvbGVEZXNjcmlwdGlvbk1lc3NhZ2U6IG51bGwsXG4gICAgICBzbGlkZVJvbGU6ICdncm91cCcsXG4gICAgICBpZDogbnVsbFxuICAgIH1cbiAgfSk7XG4gIHN3aXBlci5hMTF5ID0ge1xuICAgIGNsaWNrZWQ6IGZhbHNlXG4gIH07XG4gIGxldCBsaXZlUmVnaW9uID0gbnVsbDtcblxuICBmdW5jdGlvbiBub3RpZnkobWVzc2FnZSkge1xuICAgIGNvbnN0IG5vdGlmaWNhdGlvbiA9IGxpdmVSZWdpb247XG4gICAgaWYgKG5vdGlmaWNhdGlvbi5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICBub3RpZmljYXRpb24uaHRtbCgnJyk7XG4gICAgbm90aWZpY2F0aW9uLmh0bWwobWVzc2FnZSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRSYW5kb21OdW1iZXIoc2l6ZSA9IDE2KSB7XG4gICAgY29uc3QgcmFuZG9tQ2hhciA9ICgpID0+IE1hdGgucm91bmQoMTYgKiBNYXRoLnJhbmRvbSgpKS50b1N0cmluZygxNik7XG5cbiAgICByZXR1cm4gJ3gnLnJlcGVhdChzaXpl
1KS5yZXBsYWNlKC94L2csIHJhbmRvbUNoYXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFrZUVsRm9jdXNhYmxlKCRlbCkge1xuICAgICRlbC5hdHRyKCd0YWJJbmRleCcsICcwJyk7XG4gIH1cblxuICBmdW5jdGlvbiBtYWtlRWxOb3RGb2N1c2FibGUoJGVsKSB7XG4gICAgJGVsLmF0dHIoJ3RhYkluZGV4JywgJy0xJyk7XG4gIH1cblxuICBmdW5jdGlvbiBhZGRFbFJvbGUoJGVsLCByb2xlKSB7XG4gICAgJGVsLmF0dHIoJ3JvbGUnLCByb2xlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZEVsUm9sZURlc2NyaXB0aW9uKCRlbCwgZGVzY3JpcHRpb24pIHtcbiAgICAkZWwuYXR0cignYXJpYS1yb2xlZGVzY3JpcHRpb24nLCBkZXNjcmlwdGlvbik7XG4gIH1cblxuICBmdW5jdGlvbiBhZGRFbENvbnRyb2xzKCRlbCwgY29udHJvbHMpIHtcbiAgICAkZWwuYXR0cignYXJpYS1jb250cm9scycsIGNvbnRyb2xzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZEVsTGFiZWwoJGVsLCBsYWJlbCkge1xuICAgICRlbC5hdHRyKCdhcmlhLWxhYmVsJywgbGFiZWwpO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkRWxJZCgkZWwsIGlkKSB7XG4gICAgJGVsLmF0dHIoJ2lkJywgaWQpO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkRWxMaXZlKCRlbCwgbGl2ZSkge1xuICAgICRlbC5hdHRyKCdhcmlhLWxpdmUnLCBsaXZlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRpc2FibGVFbCgkZWwpIHtcbiAgICAkZWwuYXR0cignYXJpYS1kaXNhYmxlZCcsIHRydWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5hYmxlRWwoJGVsKSB7XG4gICAgJGVsLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCBmYWxzZSk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkVudGVyT3JTcGFjZUtleShlKSB7XG4gICAgaWYgKGUua2V5Q29kZSAhPT0gMTMgJiYgZS5rZXlDb2RlICE9PSAzMikgcmV0dXJuO1xuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuYTExeTtcbiAgICBjb25zdCAkdGFyZ2V0RWwgPSAkKGUudGFyZ2V0KTtcblxuICAgIGlmIChzd2lwZXIubmF2aWdhdGlvbiAmJiBzd2lwZXIubmF2aWdhdGlvbi4kbmV4dEVsICYmICR0YXJnZXRFbC5pcyhzd2lwZXIubmF2aWdhdGlvbi4kbmV4dEVsKSkge1xuICAgICAgaWYgKCEoc3dpcGVyLmlzRW5kICYmICFzd2lwZXIucGFyYW1zLmxvb3ApKSB7XG4gICAgICAgIHN3aXBlci5zbGlkZU5leHQoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN3aXBlci5pc0VuZCkge1xuICAgICAgICBub3RpZnkocGFyYW1zLmxhc3RTbGlkZU1lc3NhZ2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm90aWZ5KHBhcmFtcy5uZXh0U2xpZGVNZXNzYWdlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3dpcGVyLm5hdmlnYXRpb24gJiYgc3dpcGVyLm5hdmlnYXRpb24uJHByZXZFbCAmJiAkdGFyZ2V0RWwuaXMoc3dpcGVyLm5hdmlnYXRpb24uJHByZXZFbCkpIHtcbiAgICAgIGlmICghKHN3aXBlci5pc0JlZ2lubmluZyAmJiAhc3dpcGVyLnBhcmFtcy5sb29wKSkge1xuICAgICAgICBzd2lwZXIuc2xpZGVQcmV2KCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2lwZXIuaXNCZWdpbm5pbmcpIHtcbiAgICAgICAgbm90aWZ5KHBhcmFtcy5maXJzdFNsaWRlTWVzc2FnZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3RpZnkocGFyYW1zLnByZXZTbGlkZU1lc3NhZ2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzd2lwZXIucGFnaW5hdGlvbiAmJiAkdGFyZ2V0RWwuaXMoY2xhc3Nlc1RvU2VsZWN0b3Ioc3dpcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmJ1bGxldENsYXNzKSkpIHtcbiAgICAgICR0YXJnZXRFbFswXS5jbGljaygpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZU5hdmlnYXRpb24oKSB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMubG9vcCB8fCBzd2lwZXIucGFyYW1zLnJld2luZCB8fCAhc3dpcGVyLm5hdmlnYXRpb24pIHJldHVybjtcbiAgICBjb25zdCB7XG4gICAgICAkbmV4dEVsLFxuICAgICAgJHByZXZFbFxuICAgIH0gPSBzd2lwZXIubmF2aWdhdGlvbjtcblxuICAgIGlmICgkcHJldkVsICYmICRwcmV2RWwubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKHN3aXBlci5pc0JlZ2lubmluZykge1xuICAgICAgICBkaXNhYmxlRWwoJHByZXZFbCk7XG4gICAgICAgIG1ha2VFbE5vdEZvY3VzYWJsZSgkcHJldkVsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVuYWJsZUVsKCRwcmV2RWwpO1xuICAgICAgICBtYWtlRWxGb2N1c2FibGUoJHByZXZFbCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCRuZXh0RWwgJiYgJG5leHRFbC5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoc3dpcGVyLmlzRW5kKSB7XG4gICAgICAgIGRpc2FibGVFbCgkbmV4dEVsKTtcbiAgICAgICAgbWFrZUVsTm90Rm9jdXNhYmxlKCRuZXh0RWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW5hYmxlRWwoJG5leHRFbCk7XG4gICAgICAgIG1ha2VFbEZvY3VzYWJsZSgkbmV4dEVsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYXNQYWdpbmF0aW9uKCkge1xuICAgIHJldHVybiBzd2lwZXIucGFnaW5hdGlvbiAmJiBzd2lwZXIucGFnaW5hdGlvbi5idWxsZXRzICYmIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHMubGVuZ3RoO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFzQ2xpY2thYmxlUGFnaW5hdGlvbigpIHtcbiAgICByZXR1cm4gaGFzUGFnaW5hdGlvbigpICYmIHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5jbGlja2FibGU7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVQYWdpbmF0aW9uKCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuYTExeTtcbiAgICBpZiAoIWhhc1BhZ2luYXRpb24oKSkgcmV0dXJuO1xuICAgIHN3aXBlci5wYWdpbmF0aW9uLmJ1bGxldHMuZWFjaChidWxsZXRFbCA9PiB7XG4gICAgICBjb25zdCAkYnVsbGV0RWwgPSAkKGJ1bGxldEVsKTtcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMucGFnaW5hdGlvbi5jbGlja2FibGUpIHtcbiAgICAgICAgbWFrZUVsRm9jdXNhYmxlKCRidWxsZXRFbCk7XG5cbiAgICAgICAgaWYgKCFzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24ucmVuZGVyQnVsbGV0KSB7XG4gICAgICAgICAgYWRkRWxSb2xlKCRidWxsZXRFbCwgJ2J1dHRvbicpO1xuICAgICAgICAgIGFkZEVsTGFiZWwoJGJ1bGxldEVsLCBwYXJhbXMucGFnaW5hdGlvbkJ1bGxldE1lc3NhZ2UucmVwbGFjZSgvXFx7XFx7aW5kZXhcXH1cXH0vLCAkY
1nVsbGV0RWwuaW5kZXgoKSArIDEpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoJGJ1bGxldEVsLmlzKGAuJHtzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uYnVsbGV0QWN0aXZlQ2xhc3N9YCkpIHtcbiAgICAgICAgJGJ1bGxldEVsLmF0dHIoJ2FyaWEtY3VycmVudCcsICd0cnVlJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAkYnVsbGV0RWwucmVtb3ZlQXR0cignYXJpYS1jdXJyZW50Jyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBpbml0TmF2RWwgPSAoJGVsLCB3cmFwcGVySWQsIG1lc3NhZ2UpID0+IHtcbiAgICBtYWtlRWxGb2N1c2FibGUoJGVsKTtcblxuICAgIGlmICgkZWxbMF0udGFnTmFtZSAhPT0gJ0JVVFRPTicpIHtcbiAgICAgIGFkZEVsUm9sZSgkZWwsICdidXR0b24nKTtcbiAgICAgICRlbC5vbigna2V5ZG93bicsIG9uRW50ZXJPclNwYWNlS2V5KTtcbiAgICB9XG5cbiAgICBhZGRFbExhYmVsKCRlbCwgbWVzc2FnZSk7XG4gICAgYWRkRWxDb250cm9scygkZWwsIHdyYXBwZXJJZCk7XG4gIH07XG5cbiAgY29uc3QgaGFuZGxlUG9pbnRlckRvd24gPSAoKSA9PiB7XG4gICAgc3dpcGVyLmExMXkuY2xpY2tlZCA9IHRydWU7XG4gIH07XG5cbiAgY29uc3QgaGFuZGxlUG9pbnRlclVwID0gKCkgPT4ge1xuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICBpZiAoIXN3aXBlci5kZXN0cm95ZWQpIHtcbiAgICAgICAgICBzd2lwZXIuYTExeS5jbGlja2VkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGhhbmRsZUZvY3VzID0gZSA9PiB7XG4gICAgaWYgKHN3aXBlci5hMTF5LmNsaWNrZWQpIHJldHVybjtcbiAgICBjb25zdCBzbGlkZUVsID0gZS50YXJnZXQuY2xvc2VzdChgLiR7c3dpcGVyLnBhcmFtcy5zbGlkZUNsYXNzfWApO1xuICAgIGlmICghc2xpZGVFbCB8fCAhc3dpcGVyLnNsaWRlcy5pbmNsdWRlcyhzbGlkZUVsKSkgcmV0dXJuO1xuICAgIGNvbnN0IGlzQWN0aXZlID0gc3dpcGVyLnNsaWRlcy5pbmRleE9mKHNsaWRlRWwpID09PSBzd2lwZXIuYWN0aXZlSW5kZXg7XG4gICAgY29uc3QgaXNWaXNpYmxlID0gc3dpcGVyLnBhcmFtcy53YXRjaFNsaWRlc1Byb2dyZXNzICYmIHN3aXBlci52aXNpYmxlU2xpZGVzICYmIHN3aXBlci52aXNpYmxlU2xpZGVzLmluY2x1ZGVzKHNsaWRlRWwpO1xuICAgIGlmIChpc0FjdGl2ZSB8fCBpc1Zpc2libGUpIHJldHVybjtcbiAgICBpZiAoZS5zb3VyY2VDYXBhYmlsaXRpZXMgJiYgZS5zb3VyY2VDYXBhYmlsaXRpZXMuZmlyZXNUb3VjaEV2ZW50cykgcmV0dXJuO1xuXG4gICAgaWYgKHN3aXBlci5pc0hvcml6b250YWwoKSkge1xuICAgICAgc3dpcGVyLmVsLnNjcm9sbExlZnQgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIuZWwuc2Nyb2xsVG9wID0gMDtcbiAgICB9XG5cbiAgICBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmluZGV4T2Yoc2xpZGVFbCksIDApO1xuICB9O1xuXG4gIGNvbnN0IGluaXRTbGlkZXMgPSAoKSA9PiB7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5hMTF5O1xuXG4gICAgaWYgKHBhcmFtcy5pdGVtUm9sZURlc2NyaXB0aW9uTWVzc2FnZSkge1xuICAgICAgYWRkRWxSb2xlRGVzY3JpcHRpb24oJChzd2lwZXIuc2xpZGVzKSwgcGFyYW1zLml0ZW1Sb2xlRGVzY3JpcHRpb25NZXNzYWdlKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLnNsaWRlUm9sZSkge1xuICAgICAgYWRkRWxSb2xlKCQoc3dpcGVyLnNsaWRlcyksIHBhcmFtcy5zbGlkZVJvbGUpO1xuICAgIH1cblxuICAgIGNvbnN0IHNsaWRlc0xlbmd0aCA9IHN3aXBlci5wYXJhbXMubG9vcCA/IHN3aXBlci5zbGlkZXMuZmlsdGVyKGVsID0+ICFlbC5jbGFzc0xpc3QuY29udGFpbnMoc3dpcGVyLnBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzKSkubGVuZ3RoIDogc3dpcGVyLnNsaWRlcy5sZW5ndGg7XG5cbiAgICBpZiAocGFyYW1zLnNsaWRlTGFiZWxNZXNzYWdlKSB7XG4gICAgICBzd2lwZXIuc2xpZGVzLmVhY2goKHNsaWRlRWwsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0ICRzbGlkZUVsID0gJChzbGlkZUVsKTtcbiAgICAgICAgY29uc3Qgc2xpZGVJbmRleCA9IHN3aXBlci5wYXJhbXMubG9vcCA/IHBhcnNlSW50KCRzbGlkZUVsLmF0dHIoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4JyksIDEwKSA6IGluZGV4O1xuICAgICAgICBjb25zdCBhcmlhTGFiZWxNZXNzYWdlID0gcGFyYW1zLnNsaWRlTGFiZWxNZXNzYWdlLnJlcGxhY2UoL1xce1xce2luZGV4XFx9XFx9Lywgc2xpZGVJbmRleCArIDEpLnJlcGxhY2UoL1xce1xce3NsaWRlc0xlbmd0aFxcfVxcfS8sIHNsaWRlc0xlbmd0aCk7XG4gICAgICAgIGFkZEVsTGFiZWwoJHNsaWRlRWwsIGFyaWFMYWJlbE1lc3NhZ2UpO1xuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGluaXQgPSAoKSA9PiB7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5hMTF5O1xuICAgIHN3aXBlci4kZWwuYXBwZW5kKGxpdmVSZWdpb24pOyAvLyBDb250YWluZXJcblxuICAgIGNvbnN0ICRjb250YWluZXJFbCA9IHN3aXBlci4kZWw7XG5cbiAgICBpZiAocGFyYW1zLmNvbnRhaW5lclJvbGVEZXNjcmlwdGlvbk1lc3NhZ2UpIHtcbiAgICAgIGFkZEVsUm9sZURlc2NyaXB0aW9uKCRjb250YWluZXJFbCwgcGFyYW1zLmNvbnRhaW5lclJvbGVEZXNjcmlwdGlvbk1lc3NhZ2UpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuY29udGFpbmVyTWVzc2FnZSkge1xuICAgICAgYWRkRWxMYWJlbCgkY29udGFpbmVyRWwsIHBhcmFtcy5jb250YWluZXJNZXNzYWdlKTtcbiAgICB9IC8vIFdyYXBwZXJcblxuXG4gICAgY29uc3QgJHdyYXBwZXJFbCA9IHN3aXBlci4kd3JhcHBlckVsO1xuICAgIGNvbnN0IHdyYXBwZXJJZCA9IHBhcmFtcy5pZCB8fCAkd3JhcHBlckVsLmF0dHIoJ2lkJykgfHwgYHN3aXBlci13cmFwcGVyLSR7Z2V0UmFuZG9tTnVtYmVyKDE2KX1gO1xuICAgIGNvbnN0IGxpdmUgPSBzd2lwZXIucGFyYW1zLmF1dG9wbGF5ICYmIHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZW5hYmxlZCA/ICdvZmYnIDogJ3BvbGl0ZSc7XG4gICAgYWRkRWxJZCgkd3JhcHBlckVsLCB3cmFwcGVySWQpO1xuICAgIGFkZEVsTGl2ZSgkd3JhcHBlckVsLCBsaXZlKTsgLy8gU2xpZGVcblxuICAgIGluaXRTbGlkZXMoKTsgLy8gTmF2aWdhdGlvblxuXG4gICAgbGV0ICRuZXh0RWw7XG4gICAgbGV0ICRwcmV2RWw7XG5cbiAgICBpZiAoc3dpcGVyLm5hdmlnYXRpb24gJiYgc3dpcGVyLm5hdmlnYXRpb24uJG5leHRFbCkge1xuICAgICAgJG5leHRFbCA9IHN3aXBlci5uYXZpZ2F0aW9uLiRuZXh0RWw7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5uYXZpZ2F0aW9uICYmIHN3aXBlci5uYXZpZ2F0aW9uLiRwcmV2RWwpIHtcbiAgICAgICRwcmV2RWwgPSBzd2lwZXIubmF2aWdhdGlvbi4kcHJldkVsO1xuICAgIH1cblxuICAgIGlmICgkbmV4dEVsICYmICRuZXh0RWwubGVuZ3RoKSB7XG4gICAgICBpbml0TmF2RWwoJG5leHRFbCwgd3JhcHBlcklkLCBwYXJhbXMubmV4dFNsaWRlTWVzc2FnZSk7XG4gICAgfVxuXG4gICAgaWYgKCRwcmV2RWwgJiYgJHByZXZFbC5sZW5ndGgpIHtcbiAgICAgIGluaXROYXZFbCgkcHJldkVsLCB3cmFwcGVySWQsIHBhcmFtcy5wcmV2U2xpZGVNZXNzYWdlKTtcbiAgICB9IC8vIFBhZ2luYXRpb25cblxuXG4gICAgaWYgKGhhc0NsaWNrYWJsZVBhZ2luYXRpb24oKSkge1xuICAgICAgc3dpcGVyLnBhZ2luYXRpb24uJGVsLm9uKCdrZXlkb3duJywgY2xhc3Nlc1RvU2VsZWN0b3Ioc3d
1pcGVyLnBhcmFtcy5wYWdpbmF0aW9uLmJ1bGxldENsYXNzKSwgb25FbnRlck9yU3BhY2VLZXkpO1xuICAgIH0gLy8gVGFiIGZvY3VzXG5cblxuICAgIHN3aXBlci4kZWwub24oJ2ZvY3VzJywgaGFuZGxlRm9jdXMsIHRydWUpO1xuICAgIHN3aXBlci4kZWwub24oJ3BvaW50ZXJkb3duJywgaGFuZGxlUG9pbnRlckRvd24sIHRydWUpO1xuICAgIHN3aXBlci4kZWwub24oJ3BvaW50ZXJ1cCcsIGhhbmRsZVBvaW50ZXJVcCwgdHJ1ZSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICBpZiAobGl2ZVJlZ2lvbiAmJiBsaXZlUmVnaW9uLmxlbmd0aCA+IDApIGxpdmVSZWdpb24ucmVtb3ZlKCk7XG4gICAgbGV0ICRuZXh0RWw7XG4gICAgbGV0ICRwcmV2RWw7XG5cbiAgICBpZiAoc3dpcGVyLm5hdmlnYXRpb24gJiYgc3dpcGVyLm5hdmlnYXRpb24uJG5leHRFbCkge1xuICAgICAgJG5leHRFbCA9IHN3aXBlci5uYXZpZ2F0aW9uLiRuZXh0RWw7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5uYXZpZ2F0aW9uICYmIHN3aXBlci5uYXZpZ2F0aW9uLiRwcmV2RWwpIHtcbiAgICAgICRwcmV2RWwgPSBzd2lwZXIubmF2aWdhdGlvbi4kcHJldkVsO1xuICAgIH1cblxuICAgIGlmICgkbmV4dEVsKSB7XG4gICAgICAkbmV4dEVsLm9mZigna2V5ZG93bicsIG9uRW50ZXJPclNwYWNlS2V5KTtcbiAgICB9XG5cbiAgICBpZiAoJHByZXZFbCkge1xuICAgICAgJHByZXZFbC5vZmYoJ2tleWRvd24nLCBvbkVudGVyT3JTcGFjZUtleSk7XG4gICAgfSAvLyBQYWdpbmF0aW9uXG5cblxuICAgIGlmIChoYXNDbGlja2FibGVQYWdpbmF0aW9uKCkpIHtcbiAgICAgIHN3aXBlci5wYWdpbmF0aW9uLiRlbC5vZmYoJ2tleWRvd24nLCBjbGFzc2VzVG9TZWxlY3Rvcihzd2lwZXIucGFyYW1zLnBhZ2luYXRpb24uYnVsbGV0Q2xhc3MpLCBvbkVudGVyT3JTcGFjZUtleSk7XG4gICAgfSAvLyBUYWIgZm9jdXNcblxuXG4gICAgc3dpcGVyLiRlbC5vZmYoJ2ZvY3VzJywgaGFuZGxlRm9jdXMsIHRydWUpO1xuICAgIHN3aXBlci4kZWwub2ZmKCdwb2ludGVyZG93bicsIGhhbmRsZVBvaW50ZXJEb3duLCB0cnVlKTtcbiAgICBzd2lwZXIuJGVsLm9mZigncG9pbnRlcnVwJywgaGFuZGxlUG9pbnRlclVwLCB0cnVlKTtcbiAgfVxuXG4gIG9uKCdiZWZvcmVJbml0JywgKCkgPT4ge1xuICAgIGxpdmVSZWdpb24gPSAkKGA8c3BhbiBjbGFzcz1cIiR7c3dpcGVyLnBhcmFtcy5hMTF5Lm5vdGlmaWNhdGlvbkNsYXNzfVwiIGFyaWEtbGl2ZT1cImFzc2VydGl2ZVwiIGFyaWEtYXRvbWljPVwidHJ1ZVwiPjwvc3Bhbj5gKTtcbiAgfSk7XG4gIG9uKCdhZnRlckluaXQnLCAoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmExMXkuZW5hYmxlZCkgcmV0dXJuO1xuICAgIGluaXQoKTtcbiAgfSk7XG4gIG9uKCdzbGlkZXNMZW5ndGhDaGFuZ2Ugc25hcEdyaWRMZW5ndGhDaGFuZ2Ugc2xpZGVzR3JpZExlbmd0aENoYW5nZScsICgpID0+IHtcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuYTExeS5lbmFibGVkKSByZXR1cm47XG4gICAgaW5pdFNsaWRlcygpO1xuICB9KTtcbiAgb24oJ2Zyb21FZGdlIHRvRWRnZSBhZnRlckluaXQgbG9jayB1bmxvY2snLCAoKSA9PiB7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmExMXkuZW5hYmxlZCkgcmV0dXJuO1xuICAgIHVwZGF0ZU5hdmlnYXRpb24oKTtcbiAgfSk7XG4gIG9uKCdwYWdpbmF0aW9uVXBkYXRlJywgKCkgPT4ge1xuICAgIGlmICghc3dpcGVyLnBhcmFtcy5hMTF5LmVuYWJsZWQpIHJldHVybjtcbiAgICB1cGRhdGVQYWdpbmF0aW9uKCk7XG4gIH0pO1xuICBvbignZGVzdHJveScsICgpID0+IHtcbiAgICBpZiAoIXN3aXBlci5wYXJhbXMuYTExeS5lbmFibGVkKSByZXR1cm47XG4gICAgZGVzdHJveSgpO1xuICB9KTtcbn0iLCJpbXBvcnQgeyBnZXRXaW5kb3cgfSBmcm9tICdzc3Itd2luZG93JztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEhpc3Rvcnkoe1xuICBzd2lwZXIsXG4gIGV4dGVuZFBhcmFtcyxcbiAgb25cbn0pIHtcbiAgZXh0ZW5kUGFyYW1zKHtcbiAgICBoaXN0b3J5OiB7XG4gICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgIHJvb3Q6ICcnLFxuICAgICAgcmVwbGFjZVN0YXRlOiBmYWxzZSxcbiAgICAgIGtleTogJ3NsaWRlcycsXG4gICAgICBrZWVwUXVlcnk6IGZhbHNlXG4gICAgfVxuICB9KTtcbiAgbGV0IGluaXRpYWxpemVkID0gZmFsc2U7XG4gIGxldCBwYXRocyA9IHt9O1xuXG4gIGNvbnN0IHNsdWdpZnkgPSB0ZXh0ID0+IHtcbiAgICByZXR1cm4gdGV4dC50b1N0cmluZygpLnJlcGxhY2UoL1xccysvZywgJy0nKS5yZXBsYWNlKC9bXlxcdy1dKy9nLCAnJykucmVwbGFjZSgvLS0rL2csICctJykucmVwbGFjZSgvXi0rLywgJycpLnJlcGxhY2UoLy0rJC8sICcnKTtcbiAgfTtcblxuICBjb25zdCBnZXRQYXRoVmFsdWVzID0gdXJsT3ZlcnJpZGUgPT4ge1xuICAgIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuICAgIGxldCBsb2NhdGlvbjtcblxuICAgIGlmICh1cmxPdmVycmlkZSkge1xuICAgICAgbG9jYXRpb24gPSBuZXcgVVJMKHVybE92ZXJyaWRlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9jYXRpb24gPSB3aW5kb3cubG9jYXRpb247XG4gICAgfVxuXG4gICAgY29uc3QgcGF0aEFycmF5ID0gbG9jYXRpb24ucGF0aG5hbWUuc2xpY2UoMSkuc3BsaXQoJy8nKS5maWx0ZXIocGFydCA9PiBwYXJ0ICE9PSAnJyk7XG4gICAgY29uc3QgdG90YWwgPSBwYXRoQXJyYXkubGVuZ3RoO1xuICAgIGNvbnN0IGtleSA9IHBhdGhBcnJheVt0b3RhbCAtIDJdO1xuICAgIGNvbnN0IHZhbHVlID0gcGF0aEFycmF5W3RvdGFsIC0gMV07XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleSxcbiAgICAgIHZhbHVlXG4gICAgfTtcbiAgfTtcblxuICBjb25zdCBzZXRIaXN0b3J5ID0gKGtleSwgaW5kZXgpID0+IHtcbiAgICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgICBpZiAoIWluaXRpYWxpemVkIHx8ICFzd2lwZXIucGFyYW1zLmhpc3RvcnkuZW5hYmxlZCkgcmV0dXJuO1xuICAgIGxldCBsb2NhdGlvbjtcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLnVybCkge1xuICAgICAgbG9jYXRpb24gPSBuZXcgVVJMKHN3aXBlci5wYXJhbXMudXJsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9jYXRpb24gPSB3aW5kb3cubG9jYXRpb247XG4gICAgfVxuXG4gICAgY29uc3Qgc2xpZGUgPSBzd2lwZXIuc2xpZGVzLmVxKGluZGV4KTtcbiAgICBsZXQgdmFsdWUgPSBzbHVnaWZ5KHNsaWRlLmF0dHIoJ2RhdGEtaGlzdG9yeScpKTtcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmhpc3Rvcnkucm9vdC5sZW5ndGggPiAwKSB7XG4gICAgICBsZXQgcm9vdCA9IHN3aXBlci5wYXJhbXMuaGlzdG9yeS5yb290O1xuICAgICAgaWYgKHJvb3Rbcm9vdC5sZW5ndGggLSAxXSA9PT0gJy8nKSByb290ID0gcm9vdC5zbGljZSgwLCByb290Lmxlbmd0aCAtIDEpO1xuICAgICAgdmFsdWUgPSBgJHtyb290fS8ke2tleX0vJHt2YWx1ZX1gO1xuICAgIH0gZWxzZSBpZiAoIWxvY2F0aW9uLnBhdGhuYW1lLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgIHZhbHVlID0gYCR7a2V5fS8ke3ZhbHVlfWA7XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuaGlzdG9yeS5rZWVwUXVlcnkpIHtcbiAgICAgIHZhbHVlICs9IGxvY2F0aW9uLnNlYXJjaDtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50U3RhdGUgPSB3aW5kb3cuaGlzdG9yeS5zdGF0ZTtcblxuICAgIGlmIChjdXJyZW50U3RhdGUgJiYgY3VycmVudFN0YXRlLnZhbHVlID09PSB2YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmhpc3RvcnkucmVwbGFjZVN0YXRlKSB7XG4gICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUoe1xuICAgICAgICB2YWx1ZVxuICAgICAgfSwgbnVsbCwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUoe1xuICAgICAgICB2YWx1ZVxuICAgICAgfSwgbnVsbCwgdmFsdWUpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBzY3JvbGxUb1NsaWRlID0gKHNwZWVkLCB2YWx1ZSwgcnVuQ2FsbGJhY2tzKSA9PiB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBmb3IgKGxldCBpID0gMCwgbGVuZ3RoID0gc3dpcGVyLnNsaWRlcy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBjb25zdCBzbGlkZSA9IHN3aXBlci5zbGlkZXMuZXEoaSk7XG4gICAgICAgIGNvbnN0IHNsaWRlSGlzdG9yeSA9IHNsdWdpZnkoc2xpZGUuYXR0cignZGF0YS1oaXN0b3J5JykpO1xuXG4gICAgICAgIGlmIChzbGlkZUhpc3RvcnkgPT09IHZhbHVlICYmICFzbGlkZS5oYXNDbGFzcyhzd2lwZXIucGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MpKSB7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSBzbGlkZS5pbmRleCgpO1xuICAgICAgICAgI
1HN3aXBlci5zbGlkZVRvKGluZGV4LCBzcGVlZCwgcnVuQ2FsbGJhY2tzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzd2lwZXIuc2xpZGVUbygwLCBzcGVlZCwgcnVuQ2FsbGJhY2tzKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3Qgc2V0SGlzdG9yeVBvcFN0YXRlID0gKCkgPT4ge1xuICAgIHBhdGhzID0gZ2V0UGF0aFZhbHVlcyhzd2lwZXIucGFyYW1zLnVybCk7XG4gICAgc2Nyb2xsVG9TbGlkZShzd2lwZXIucGFyYW1zLnNwZWVkLCBwYXRocy52YWx1ZSwgZmFsc2UpO1xuICB9O1xuXG4gIGNvbnN0IGluaXQgPSAoKSA9PiB7XG4gICAgY29uc3Qgd2luZG93ID0gZ2V0V2luZG93KCk7XG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmhpc3RvcnkpIHJldHVybjtcblxuICAgIGlmICghd2luZG93Lmhpc3RvcnkgfHwgIXdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSkge1xuICAgICAgc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmVuYWJsZWQgPSBmYWxzZTtcbiAgICAgIHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24uZW5hYmxlZCA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIHBhdGhzID0gZ2V0UGF0aFZhbHVlcyhzd2lwZXIucGFyYW1zLnVybCk7XG4gICAgaWYgKCFwYXRocy5rZXkgJiYgIXBhdGhzLnZhbHVlKSByZXR1cm47XG4gICAgc2Nyb2xsVG9TbGlkZSgwLCBwYXRocy52YWx1ZSwgc3dpcGVyLnBhcmFtcy5ydW5DYWxsYmFja3NPbkluaXQpO1xuXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmhpc3RvcnkucmVwbGFjZVN0YXRlKSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBzZXRIaXN0b3J5UG9wU3RhdGUpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBkZXN0cm95ID0gKCkgPT4ge1xuICAgIGNvbnN0IHdpbmRvdyA9IGdldFdpbmRvdygpO1xuXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLmhpc3RvcnkucmVwbGFjZVN0YXRlKSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBzZXRIaXN0b3J5UG9wU3RhdGUpO1xuICAgIH1cbiAgfTtcblxuICBvbignaW5pdCcsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmVuYWJsZWQpIHtcbiAgICAgIGluaXQoKTtcbiAgICB9XG4gIH0pO1xuICBvbignZGVzdHJveScsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmVuYWJsZWQpIHtcbiAgICAgIGRlc3Ryb3koKTtcbiAgICB9XG4gIH0pO1xuICBvbigndHJhbnNpdGlvbkVuZCBfZnJlZU1vZGVOb01vbWVudHVtUmVsZWFzZScsICgpID0+IHtcbiAgICBpZiAoaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHNldEhpc3Rvcnkoc3dpcGVyLnBhcmFtcy5oaXN0b3J5LmtleSwgc3dpcGVyLmFjdGl2ZUluZGV4KTtcbiAgICB9XG4gIH0pO1xuICBvbignc2xpZGVDaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKGluaXRpYWxpemVkICYmIHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgICAgc2V0SGlzdG9yeShzd2lwZXIucGFyYW1zLmhpc3Rvcnkua2V5LCBzd2lwZXIuYWN0aXZlSW5kZXgpO1xuICAgIH1cbiAgfSk7XG59IiwiaW1wb3J0IHsgZ2V0V2luZG93LCBnZXREb2N1bWVudCB9IGZyb20gJ3Nzci13aW5kb3cnO1xuaW1wb3J0ICQgZnJvbSAnLi4vLi4vc2hhcmVkL2RvbS5qcyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBIYXNoTmF2aWdhdGlvbih7XG4gIHN3aXBlcixcbiAgZXh0ZW5kUGFyYW1zLFxuICBlbWl0LFxuICBvblxufSkge1xuICBsZXQgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICBjb25zdCB3aW5kb3cgPSBnZXRXaW5kb3coKTtcbiAgZXh0ZW5kUGFyYW1zKHtcbiAgICBoYXNoTmF2aWdhdGlvbjoge1xuICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICByZXBsYWNlU3RhdGU6IGZhbHNlLFxuICAgICAgd2F0Y2hTdGF0ZTogZmFsc2VcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IG9uSGFzaENoYW5nZSA9ICgpID0+IHtcbiAgICBlbWl0KCdoYXNoQ2hhbmdlJyk7XG4gICAgY29uc3QgbmV3SGFzaCA9IGRvY3VtZW50LmxvY2F0aW9uLmhhc2gucmVwbGFjZSgnIycsICcnKTtcbiAgICBjb25zdCBhY3RpdmVTbGlkZUhhc2ggPSBzd2lwZXIuc2xpZGVzLmVxKHN3aXBlci5hY3RpdmVJbmRleCkuYXR0cignZGF0YS1oYXNoJyk7XG5cbiAgICBpZiAobmV3SGFzaCAhPT0gYWN0aXZlU2xpZGVIYXNoKSB7XG4gICAgICBjb25zdCBuZXdJbmRleCA9IHN3aXBlci4kd3JhcHBlckVsLmNoaWxkcmVuKGAuJHtzd2lwZXIucGFyYW1zLnNsaWRlQ2xhc3N9W2RhdGEtaGFzaD1cIiR7bmV3SGFzaH1cIl1gKS5pbmRleCgpO1xuICAgICAgaWYgKHR5cGVvZiBuZXdJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcbiAgICAgIHN3aXBlci5zbGlkZVRvKG5ld0luZGV4KTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3Qgc2V0SGFzaCA9ICgpID0+IHtcbiAgICBpZiAoIWluaXRpYWxpemVkIHx8ICFzd2lwZXIucGFyYW1zLmhhc2hOYXZpZ2F0aW9uLmVuYWJsZWQpIHJldHVybjtcblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmhhc2hOYXZpZ2F0aW9uLnJlcGxhY2VTdGF0ZSAmJiB3aW5kb3cuaGlzdG9yeSAmJiB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUpIHtcbiAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShudWxsLCBudWxsLCBgIyR7c3dpcGVyLnNsaWRlcy5lcShzd2lwZXIuYWN0aXZlSW5kZXgpLmF0dHIoJ2RhdGEtaGFzaCcpfWAgfHwgJycpO1xuICAgICAgZW1pdCgnaGFzaFNldCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzbGlkZSA9IHN3aXBlci5zbGlkZXMuZXEoc3dpcGVyLmFjdGl2ZUluZGV4KTtcbiAgICAgIGNvbnN0IGhhc2ggPSBzbGlkZS5hdHRyKCdkYXRhLWhhc2gnKSB8fCBzbGlkZS5hdHRyKCdkYXRhLWhpc3RvcnknKTtcbiAgICAgIGRvY3VtZW50LmxvY2F0aW9uLmhhc2ggPSBoYXNoIHx8ICcnO1xuICAgICAgZW1pdCgnaGFzaFNldCcpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBpbml0ID0gKCkgPT4ge1xuICAgIGlmICghc3dpcGVyLnBhcmFtcy5oYXNoTmF2aWdhdGlvbi5lbmFibGVkIHx8IHN3aXBlci5wYXJhbXMuaGlzdG9yeSAmJiBzd2lwZXIucGFyYW1zLmhpc3RvcnkuZW5hYmxlZCkgcmV0dXJuO1xuICAgIGluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICBjb25zdCBoYXNoID0gZG9jdW1lbnQubG9jYXRpb24uaGFzaC5yZXBsYWNlKCcjJywgJycpO1xuXG4gICAgaWYgKGhhc2gpIHtcbiAgICAgIGNvbnN0IHNwZWVkID0gMDtcblxuICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbmd0aCA9IHN3aXBlci5zbGlkZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgY29uc3Qgc2xpZGUgPSBzd2lwZXIuc2xpZGVzLmVxKGkpO1xuICAgICAgICBjb25zdCBzbGlkZUhhc2ggPSBzbGlkZS5hdHRyKCdkYXRhLWhhc2gnKSB8fCBzbGlkZS5hdHRyKCdkYXRhLWhpc3RvcnknKTtcblxuICAgICAgICBpZiAoc2xpZGVIYXNoID09PSBoYXNoICYmICFzbGlkZS5oYXNDbGFzcyhzd2lwZXIucGFyYW1zLnNsaWRlRHVwbGljYXRlQ2xhc3MpKSB7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSBzbGlkZS5pbmRleCgpO1xuICAgICAgICAgI
1HN3aXBlci5zbGlkZVRvKGluZGV4LCBzcGVlZCwgc3dpcGVyLnBhcmFtcy5ydW5DYWxsYmFja3NPbkluaXQsIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24ud2F0Y2hTdGF0ZSkge1xuICAgICAgJCh3aW5kb3cpLm9uKCdoYXNoY2hhbmdlJywgb25IYXNoQ2hhbmdlKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgZGVzdHJveSA9ICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5oYXNoTmF2aWdhdGlvbi53YXRjaFN0YXRlKSB7XG4gICAgICAkKHdpbmRvdykub2ZmKCdoYXNoY2hhbmdlJywgb25IYXNoQ2hhbmdlKTtcbiAgICB9XG4gIH07XG5cbiAgb24oJ2luaXQnLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMuaGFzaE5hdmlnYXRpb24uZW5hYmxlZCkge1xuICAgICAgaW5pdCgpO1xuICAgIH1cbiAgfSk7XG4gIG9uKCdkZXN0cm95JywgKCkgPT4ge1xuICAgIGlmIChzd2lwZXIucGFyYW1zLmhhc2hOYXZpZ2F0aW9uLmVuYWJsZWQpIHtcbiAgICAgIGRlc3Ryb3koKTtcbiAgICB9XG4gIH0pO1xuICBvbigndHJhbnNpdGlvbkVuZCBfZnJlZU1vZGVOb01vbWVudHVtUmVsZWFzZScsICgpID0+IHtcbiAgICBpZiAoaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHNldEhhc2goKTtcbiAgICB9XG4gIH0pO1xuICBvbignc2xpZGVDaGFuZ2UnLCAoKSA9PiB7XG4gICAgaWYgKGluaXRpYWxpemVkICYmIHN3aXBlci5wYXJhbXMuY3NzTW9kZSkge1xuICAgICAgc2V0SGFzaCgpO1xuICAgIH1cbiAgfSk7XG59IiwiLyogZXNsaW50IG5vLXVuZGVyc2NvcmUtZGFuZ2xlOiBcIm9mZlwiICovXG5cbi8qIGVzbGludCBuby11c2UtYmVmb3JlLWRlZmluZTogXCJvZmZcIiAqL1xuaW1wb3J0IHsgZ2V0RG9jdW1lbnQgfSBmcm9tICdzc3Itd2luZG93JztcbmltcG9ydCB7IG5leHRUaWNrIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEF1dG9wbGF5KHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uLFxuICBlbWl0XG59KSB7XG4gIGxldCB0aW1lb3V0O1xuICBzd2lwZXIuYXV0b3BsYXkgPSB7XG4gICAgcnVubmluZzogZmFsc2UsXG4gICAgcGF1c2VkOiBmYWxzZVxuICB9O1xuICBleHRlbmRQYXJhbXMoe1xuICAgIGF1dG9wbGF5OiB7XG4gICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgIGRlbGF5OiAzMDAwLFxuICAgICAgd2FpdEZvclRyYW5zaXRpb246IHRydWUsXG4gICAgICBkaXNhYmxlT25JbnRlcmFjdGlvbjogdHJ1ZSxcbiAgICAgIHN0b3BPbkxhc3RTbGlkZTogZmFsc2UsXG4gICAgICByZXZlcnNlRGlyZWN0aW9uOiBmYWxzZSxcbiAgICAgIHBhdXNlT25Nb3VzZUVudGVyOiBmYWxzZVxuICAgIH1cbiAgfSk7XG5cbiAgZnVuY3Rpb24gcnVuKCkge1xuICAgIGlmICghc3dpcGVyLnNpemUpIHtcbiAgICAgIHN3aXBlci5hdXRvcGxheS5ydW5uaW5nID0gZmFsc2U7XG4gICAgICBzd2lwZXIuYXV0b3BsYXkucGF1c2VkID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgJGFjdGl2ZVNsaWRlRWwgPSBzd2lwZXIuc2xpZGVzLmVxKHN3aXBlci5hY3RpdmVJbmRleCk7XG4gICAgbGV0IGRlbGF5ID0gc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5kZWxheTtcblxuICAgIGlmICgkYWN0aXZlU2xpZGVFbC5hdHRyKCdkYXRhLXN3aXBlci1hdXRvcGxheScpKSB7XG4gICAgICBkZWxheSA9ICRhY3RpdmVTbGlkZUVsLmF0dHIoJ2RhdGEtc3dpcGVyLWF1dG9wbGF5JykgfHwgc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5kZWxheTtcbiAgICB9XG5cbiAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgdGltZW91dCA9IG5leHRUaWNrKCgpID0+IHtcbiAgICAgIGxldCBhdXRvcGxheVJlc3VsdDtcblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b3BsYXkucmV2ZXJzZURpcmVjdGlvbikge1xuICAgICAgICBpZiAoc3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICAgICAgc3dpcGVyLmxvb3BGaXgoKTtcbiAgICAgICAgICBhdXRvcGxheVJlc3VsdCA9IHN3aXBlci5zbGlkZVByZXYoc3dpcGVyLnBhcmFtcy5zcGVlZCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgZW1pdCgnYXV0b3BsYXknKTtcbiAgICAgICAgfSBlbHNlIGlmICghc3dpcGVyLmlzQmVnaW5uaW5nKSB7XG4gICAgICAgICAgYXV0b3BsYXlSZXN1bHQgPSBzd2lwZXIuc2xpZGVQcmV2KHN3aXBlci5wYXJhbXMuc3BlZWQsIHRydWUsIHRydWUpO1xuICAgICAgICAgIGVtaXQoJ2F1dG9wbGF5Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAoIXN3aXBlci5wYXJhbXMuYXV0b3BsYXkuc3RvcE9uTGFzdFNsaWRlKSB7XG4gICAgICAgICAgYXV0b3BsYXlSZXN1bHQgPSBzd2lwZXIuc2xpZGVUbyhzd2lwZXIuc2xpZGVzLmxlbmd0aCAtIDEsIHN3aXBlci5wYXJhbXMuc3BlZWQsIHRydWUsIHRydWUpO1xuICAgICAgICAgIGVtaXQoJ2F1dG9wbGF5Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RvcCgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHN3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgICBzd2lwZXIubG9vcEZpeCgpO1xuICAgICAgICBhdXRvcGxheVJlc3VsdCA9IHN3aXBlci5zbGlkZU5leHQoc3dpcGVyLnBhcmFtcy5zcGVlZCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgIGVtaXQoJ2F1dG9wbGF5Jyk7XG4gICAgICB9IGVsc2UgaWYgKCFzd2lwZXIuaXNFbmQpIHtcbiAgICAgICAgYXV0b3BsYXlSZXN1bHQgPSBzd2lwZXIuc2xpZGVOZXh0KHN3aXBlci5wYXJhbXMuc3BlZWQsIHRydWUsIHRydWUpO1xuICAgICAgICBlbWl0KCdhdXRvcGxheScpO1xuICAgICAgfSBlbHNlIGlmICghc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5zdG9wT25MYXN0U2xpZGUpIHtcbiAgICAgICAgYXV0b3BsYXlSZXN1bHQgPSBzd2lwZXIuc2xpZGVUbygwLCBzd2lwZXIucGFyYW1zLnNwZWVkLCB0cnVlLCB0cnVlKTtcbiAgICAgICAgZW1pdCgnYXV0b3BsYXknKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0b3AoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuY3NzTW9kZSAmJiBzd2lwZXIuYXV0b3BsYXkucnVubmluZykgcnVuKCk7ZWxzZSBpZiAoYXV0b3BsYXlSZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgI
1HJ1bigpO1xuICAgICAgfVxuICAgIH0sIGRlbGF5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgIGlmICh0eXBlb2YgdGltZW91dCAhPT0gJ3VuZGVmaW5lZCcpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcpIHJldHVybiBmYWxzZTtcbiAgICBzd2lwZXIuYXV0b3BsYXkucnVubmluZyA9IHRydWU7XG4gICAgZW1pdCgnYXV0b3BsYXlTdGFydCcpO1xuICAgIHJ1bigpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gc3RvcCgpIHtcbiAgICBpZiAoIXN3aXBlci5hdXRvcGxheS5ydW5uaW5nKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHR5cGVvZiB0aW1lb3V0ID09PSAndW5kZWZpbmVkJykgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHRpbWVvdXQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHRpbWVvdXQgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcgPSBmYWxzZTtcbiAgICBlbWl0KCdhdXRvcGxheVN0b3AnKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhdXNlKHNwZWVkKSB7XG4gICAgaWYgKCFzd2lwZXIuYXV0b3BsYXkucnVubmluZykgcmV0dXJuO1xuICAgIGlmIChzd2lwZXIuYXV0b3BsYXkucGF1c2VkKSByZXR1cm47XG4gICAgaWYgKHRpbWVvdXQpIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICBzd2lwZXIuYXV0b3BsYXkucGF1c2VkID0gdHJ1ZTtcblxuICAgIGlmIChzcGVlZCA9PT0gMCB8fCAhc3dpcGVyLnBhcmFtcy5hdXRvcGxheS53YWl0Rm9yVHJhbnNpdGlvbikge1xuICAgICAgc3dpcGVyLmF1dG9wbGF5LnBhdXNlZCA9IGZhbHNlO1xuICAgICAgcnVuKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFsndHJhbnNpdGlvbmVuZCcsICd3ZWJraXRUcmFuc2l0aW9uRW5kJ10uZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgIHN3aXBlci4kd3JhcHBlckVsWzBdLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIG9uVHJhbnNpdGlvbkVuZCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvblZpc2liaWxpdHlDaGFuZ2UoKSB7XG4gICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuXG4gICAgaWYgKGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZSA9PT0gJ2hpZGRlbicgJiYgc3dpcGVyLmF1dG9wbGF5LnJ1bm5pbmcpIHtcbiAgICAgIHBhdXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZSA9PT0gJ3Zpc2libGUnICYmIHN3aXBlci5hdXRvcGxheS5wYXVzZWQpIHtcbiAgICAgIHJ1bigpO1xuICAgICAgc3dpcGVyLmF1dG9wbGF5LnBhdXNlZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVHJhbnNpdGlvbkVuZChlKSB7XG4gICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCB8fCAhc3dpcGVyLiR3cmFwcGVyRWwpIHJldHVybjtcbiAgICBpZiAoZS50YXJnZXQgIT09IHN3aXBlci4kd3JhcHBlckVsWzBdKSByZXR1cm47XG4gICAgWyd0cmFuc2l0aW9uZW5kJywgJ3dlYmtpdFRyYW5zaXRpb25FbmQnXS5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgIHN3aXBlci4kd3JhcHBlckVsWzBdLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIG9uVHJhbnNpdGlvbkVuZCk7XG4gICAgfSk7XG4gICAgc3dpcGVyLmF1dG9wbGF5LnBhdXNlZCA9IGZhbHNlO1xuXG4gICAgaWYgKCFzd2lwZXIuYXV0b3BsYXkucnVubmluZykge1xuICAgICAgc3RvcCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBydW4oKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbk1vdXNlRW50ZXIoKSB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZGlzYWJsZU9uSW50ZXJhY3Rpb24pIHtcbiAgICAgIHN0b3AoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW1pdCgnYXV0b3BsYXlQYXVzZScpO1xuICAgICAgcGF1c2UoKTtcbiAgICB9XG5cbiAgICBbJ3RyYW5zaXRpb25lbmQnLCAnd2Via2l0VHJhbnNpdGlvbkVuZCddLmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgc3dpcGVyLiR3cmFwcGVyRWxbMF0ucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgb25UcmFuc2l0aW9uRW5kKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uTW91c2VMZWF2ZSgpIHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5hdXRvcGxheS5kaXNhYmxlT25JbnRlcmFjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN3aXBlci5hdXRvcGxheS5wYXVzZWQgPSBmYWxzZTtcbiAgICBlbWl0KCdhdXRvcGxheVJlc3VtZScpO1xuICAgIHJ1bigpO1xuICB9XG5cbiAgZnVuY3Rpb24gYXR0YWNoTW91c2VFdmVudHMoKSB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b3BsYXkucGF1c2VPbk1vdXNlRW50ZXIpIHtcbiAgICAgIHN3aXBlci4kZWwub24oJ21vdXNlZW50ZXInLCBvbk1vdXNlRW50ZXIpO1xuICAgICAgc3dpcGVyLiRlbC5vbignbW91c2VsZWF2ZScsIG9uTW91c2VMZWF2ZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZGV0YWNoTW91c2VFdmVudHMoKSB7XG4gICAgc3dpcGVyLiRlbC5vZmYoJ21vdXNlZW50ZXInLCBvbk1vdXNlRW50ZXIpO1xuICAgIHN3aXBlci4kZWwub2ZmKCdtb3VzZWxlYXZlJywgb25Nb3VzZUxlYXZlKTtcbiAgfVxuXG4gIG9uKCdpbml0JywgKCkgPT4ge1xuICAgIGlmIChzd2lwZXIucGFyYW1zLmF1dG9wbGF5LmVuYWJsZWQpIHtcbiAgICAgIHN0YXJ0KCk7XG4gICAgICBjb25zdCBkb2N1bWVudCA9IGdldERvY3VtZW50KCk7XG4gICAgICBkb2
1N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd2aXNpYmlsaXR5Y2hhbmdlJywgb25WaXNpYmlsaXR5Q2hhbmdlKTtcbiAgICAgIGF0dGFjaE1vdXNlRXZlbnRzKCk7XG4gICAgfVxuICB9KTtcbiAgb24oJ2JlZm9yZVRyYW5zaXRpb25TdGFydCcsIChfcywgc3BlZWQsIGludGVybmFsKSA9PiB7XG4gICAgaWYgKHN3aXBlci5hdXRvcGxheS5ydW5uaW5nKSB7XG4gICAgICBpZiAoaW50ZXJuYWwgfHwgIXN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZGlzYWJsZU9uSW50ZXJhY3Rpb24pIHtcbiAgICAgICAgc3dpcGVyLmF1dG9wbGF5LnBhdXNlKHNwZWVkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0b3AoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICBvbignc2xpZGVyRmlyc3RNb3ZlJywgKCkgPT4ge1xuICAgIGlmIChzd2lwZXIuYXV0b3BsYXkucnVubmluZykge1xuICAgICAgaWYgKHN3aXBlci5wYXJhbXMuYXV0b3BsYXkuZGlzYWJsZU9uSW50ZXJhY3Rpb24pIHtcbiAgICAgICAgc3RvcCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGF1c2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICBvbigndG91Y2hFbmQnLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMuY3NzTW9kZSAmJiBzd2lwZXIuYXV0b3BsYXkucGF1c2VkICYmICFzd2lwZXIucGFyYW1zLmF1dG9wbGF5LmRpc2FibGVPbkludGVyYWN0aW9uKSB7XG4gICAgICBydW4oKTtcbiAgICB9XG4gIH0pO1xuICBvbignZGVzdHJveScsICgpID0+IHtcbiAgICBkZXRhY2hNb3VzZUV2ZW50cygpO1xuXG4gICAgaWYgKHN3aXBlci5hdXRvcGxheS5ydW5uaW5nKSB7XG4gICAgICBzdG9wKCk7XG4gICAgfVxuXG4gICAgY29uc3QgZG9jdW1lbnQgPSBnZXREb2N1bWVudCgpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Zpc2liaWxpdHljaGFuZ2UnLCBvblZpc2liaWxpdHlDaGFuZ2UpO1xuICB9KTtcbiAgT2JqZWN0LmFzc2lnbihzd2lwZXIuYXV0b3BsYXksIHtcbiAgICBwYXVzZSxcbiAgICBydW4sXG4gICAgc3RhcnQsXG4gICAgc3RvcFxuICB9KTtcbn0iLCJpbXBvcnQgeyBpc09iamVjdCB9IGZyb20gJy4uLy4uL3NoYXJlZC91dGlscy5qcyc7XG5pbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRodW1iKHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uXG59KSB7XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAgdGh1bWJzOiB7XG4gICAgICBzd2lwZXI6IG51bGwsXG4gICAgICBtdWx0aXBsZUFjdGl2ZVRodW1iczogdHJ1ZSxcbiAgICAgIGF1dG9TY3JvbGxPZmZzZXQ6IDAsXG4gICAgICBzbGlkZVRodW1iQWN0aXZlQ2xhc3M6ICdzd2lwZXItc2xpZGUtdGh1bWItYWN0aXZlJyxcbiAgICAgIHRodW1ic0NvbnRhaW5lckNsYXNzOiAnc3dpcGVyLXRodW1icydcbiAgICB9XG4gIH0pO1xuICBsZXQgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgbGV0IHN3aXBlckNyZWF0ZWQgPSBmYWxzZTtcbiAgc3dpcGVyLnRodW1icyA9IHtcbiAgICBzd2lwZXI6IG51bGxcbiAgfTtcblxuICBmdW5jdGlvbiBvblRodW1iQ2xpY2soKSB7XG4gICAgY29uc3QgdGh1bWJzU3dpcGVyID0gc3dpcGVyLnRodW1icy5zd2lwZXI7XG4gICAgaWYgKCF0aHVtYnNTd2lwZXIgfHwgdGh1bWJzU3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xuICAgIGNvbnN0IGNsaWNrZWRJbmRleCA9IHRodW1ic1N3aXBlci5jbGlja2VkSW5kZXg7XG4gICAgY29uc3QgY2xpY2tlZFNsaWRlID0gdGh1bWJzU3dpcGVyLmNsaWNrZWRTbGlkZTtcbiAgICBpZiAoY2xpY2tlZFNsaWRlICYmICQoY2xpY2tlZFNsaWRlKS5oYXNDbGFzcyhzd2lwZXIucGFyYW1zLnRodW1icy5zbGlkZVRodW1iQWN0aXZlQ2xhc3MpKSByZXR1cm47XG4gICAgaWYgKHR5cGVvZiBjbGlja2VkSW5kZXggPT09ICd1bmRlZmluZWQnIHx8IGNsaWNrZWRJbmRleCA9PT0gbnVsbCkgcmV0dXJuO1xuICAgIGxldCBzbGlkZVRvSW5kZXg7XG5cbiAgICBpZiAodGh1bWJzU3dpcGVyLnBhcmFtcy5sb29wKSB7XG4gICAgICBzbGlkZVRvSW5kZXggPSBwYXJzZUludCgkKHRodW1ic1N3aXBlci5jbGlja2VkU2xpZGUpLmF0dHIoJ2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4JyksIDEwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2xpZGVUb0luZGV4ID0gY2xpY2tlZEluZGV4O1xuICAgIH1cblxuICAgIGlmIChzd2lwZXIucGFyYW1zLmxvb3ApIHtcbiAgICAgIGxldCBjdXJyZW50SW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXg7XG5cbiAgICAgIGlmIChzd2lwZXIuc2xpZGVzLmVxKGN1cnJlbnRJbmRleCkuaGFzQ2xhc3Moc3dpcGVyLnBhcmFtcy5zbGlkZUR1cGxpY2F0ZUNsYXNzKSkge1xuICAgICAgICBzd2lwZXIubG9vcEZpeCgpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuICAgICAgICBzd2lwZXIuX2NsaWVudExlZnQgPSBzd2lwZXIuJHdyYXBwZXJFbFswXS5jbGllbnRMZWZ0O1xuICAgICAgICBjdXJyZW50SW5kZXggPSBzd2lwZXIuYWN0aXZlSW5kZXg7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByZXZJbmRleCA9IHN3aXBlci5zbGlkZXMuZXEoY3VycmVudEluZGV4KS5wcmV2QWxsKGBbZGF0YS1zd2lwZXItc2xpZGUtaW5kZXg9XCIke3NsaWRlVG9JbmRleH1cIl1gKS5lcSgwKS5pbmRleCgpO1xuICAgICAgY29uc3QgbmV4dEluZGV4ID0gc3dpcGVyLnNsaWRlcy5lcShjdXJyZW50SW5kZXgpLm5leHRBbGwoYFtkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cIiR7c2xpZGVUb0luZGV4fVwiXWApLmVxKDApLmluZGV4KCk7XG4gICAgICBpZiAodHlwZW9mIHByZXZJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHNsaWRlVG9JbmRleCA9IG5leHRJbmRleDtlbHNlIGlmICh0eXBlb2YgbmV4dEluZGV4ID09PSAndW5kZWZpbmVkJykgc2xpZGVUb0luZGV4ID0gcHJldkluZGV4O2Vsc2UgaWYgKG5leHRJbmRleCAtIGN1cnJlbnRJbmRleCA8IGN1cnJlbnRJbmRleCAtIHByZXZJbmRleCkgc2xpZGVUb0luZGV4ID0gbmV4dEluZGV4O2Vsc2Ugc2xpZGVUb0luZGV4ID0gcHJldkluZGV4O1xuICAgIH1cblxuICAgIHN3aXBlci5zbGlkZVRvKHNsaWRlVG9JbmRleCk7XG4gIH1cblxuICBmdW5jdGlvbiBpbml0KCkge1xuICAgIGNvbnN0IHtcbiAgICAgIHRodW1iczogdGh1bWJzUGFyYW1zXG4gICAgfSA9IHN3aXBlci5wYXJhbXM7XG4gICAgaWYgKGluaXRpYWxpemVkKSByZXR1cm4gZmFsc2U7XG4gICAgaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIGNvbnN0IFN3aXBlckNsYXNzID0gc3dpcGVyLmNvbnN0cnVjdG9yO1xuXG4gICAgaWYgKHRodW1ic1BhcmFtcy5zd2lwZXIgaW5zdGFuY2VvZiBTd2lwZXJDbGFzcykge1xuICAgICAgc3dpcGVyLnRodW1icy5zd2lwZXIgPSB0aHVtYnNQYXJhbXMuc3dpcGVyO1xuICAgICAgT2JqZWN0LmFzc2lnbihzd2lwZXIudGh1bWJzLnN3aXBlci5vcmlnaW5hbFBhcmFtcywge1xuICAgICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxuICAgICAgICBzbGlkZVRvQ2xpY2tlZFNsaWRlOiBmYWxzZVxuICAgICAgfSk7XG4gICAgICBPYmplY3QuYXNzaWduKHN3aXBlci50aHVtYnMuc3dpcGVyLnBhcmFtcywge1xuICAgICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxuICAgICAgICBzbGlkZVRvQ2xpY2tlZFNsaWRlOiBmYWxzZVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChpc09iamVjdCh0aHVtYnNQYXJhbXMuc3dpcGVyKSkge1xuICAgICAgY29uc3QgdGh1bWJzU3dpcGVyUGFyYW1zID0gT2JqZWN0LmFzc2lnbih7fSwgdGh1bWJzUGFyYW1zLnN3aXBlcik7XG4gICAgICBPYmplY3QuYXNzaWduKHRodW1ic1N3aXBlclBhcmFtcywge1xuICAgICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxuICAgICAgICBzbGlkZVRvQ2xpY2tlZFNsaWRlOiBmYWxzZVxuICAgICAgfSk7XG4gICAgICBzd2lwZXIudGh1bWJzLnN3aXBlciA9IG5ldyBTd2lwZXJDbGFzcyh0aHVtYnNTd2lwZXJQYXJhbXMpO1xuICAgICAgc3dpcGVyQ3JlYXRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgc3dpcGVyLnRodW1icy5zd2lwZXIuJGVsLmFkZENsYXNzKHN3aXBlci5wYXJhbXMudGh1bWJzLnRodW1ic0NvbnRhaW5lckNsYXNzKTtcbiAgICBzd2lwZXIudGh1bWJzLnN3aXBlci5vbigndGFwJywgb25UaHVtYkNsaWNrKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZShpbml0aWFsKSB7XG4gICAgY29uc3QgdGh1bWJzU3dpcGVyID0gc3dpcGVyLnRodW1icy5zd2lwZXI7XG4gICAgaWYgKCF0aHVtYnNTd2lwZXIgfHwgdGh1bWJzU3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xuICAgIGNvbnN0IHNsaWRlc1BlclZpZXcgPSB0aHVtYnNTd2lwZXIucGFyYW1zLnNsaWRlc1BlclZpZXcgPT09ICdhdXRvJyA/IHRodW1ic1N3aXBlci5zbGlkZXNQZXJWaWV3RHluYW1pYygpIDogdGh1bWJzU3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJWaWV3OyAvLyBBY3RpdmF0ZSB0aHVtYnNcblxuICAgIGxldCB0aHVtYnNUb0FjdGl2YXRlID0gMTtcbiAgICBjb25zdCB0aHVtYkFjdGl2ZUNsYXNzID0gc3dpcGVyLnBhcmFtcy50aHVtYnMuc2xpZGVUaHVtYkFjdGl2ZUNsYXNzO1xuXG4gICAgaWYgKHN3aXBlci5wYXJhbXMuc2xpZGVzUGVyVmlldyA+IDEgJiYgIXN3aXBlci5wYXJhbXMuY2VudGVyZWRTbGlkZXMpIHtcbiAgICAgIHRodW1ic1RvQWN0aXZhdGUgPSBzd2lwZXIucGFyYW1zLnNsaWRlc1BlclZpZXc7XG4gICAgfVxuXG4gICAgaWYgKCFzd2lwZXIucGFyYW1zLnRodW1icy5tdWx0aXBsZUFjdGl2ZVRodW1icykge1xuICAgICAgdGh1bWJzVG9BY3RpdmF0ZSA9IDE7XG4gICAgfVxuXG4gICAgdGh1bWJzVG9BY3RpdmF0ZSA9IE1hdGguZmxvb3IodGh1bWJzVG9BY3RpdmF0ZSk7XG4gICAgdGh1bWJzU3dpcGVyLnNsaWRlcy5yZW1vdmVDbGFzcyh0aHVtYkFjdGl2ZUNsYXNzKTtcblxuICAgIGlmICh0aHVtYnNTd2lwZXIucGFyYW1zLmxvb3AgfHwgdGh1bWJzU3dpcGVyLnBhcmFtcy52aXJ0dWFsICYmIHRodW1ic1N3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRodW1ic1RvQWN0aXZhdGU7IGkgKz
10gMSkge1xuICAgICAgICB0aHVtYnNTd2lwZXIuJHdyYXBwZXJFbC5jaGlsZHJlbihgW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtzd2lwZXIucmVhbEluZGV4ICsgaX1cIl1gKS5hZGRDbGFzcyh0aHVtYkFjdGl2ZUNsYXNzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aHVtYnNUb0FjdGl2YXRlOyBpICs9IDEpIHtcbiAgICAgICAgdGh1bWJzU3dpcGVyLnNsaWRlcy5lcShzd2lwZXIucmVhbEluZGV4ICsgaSkuYWRkQ2xhc3ModGh1bWJBY3RpdmVDbGFzcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYXV0b1Njcm9sbE9mZnNldCA9IHN3aXBlci5wYXJhbXMudGh1bWJzLmF1dG9TY3JvbGxPZmZzZXQ7XG4gICAgY29uc3QgdXNlT2Zmc2V0ID0gYXV0b1Njcm9sbE9mZnNldCAmJiAhdGh1bWJzU3dpcGVyLnBhcmFtcy5sb29wO1xuXG4gICAgaWYgKHN3aXBlci5yZWFsSW5kZXggIT09IHRodW1ic1N3aXBlci5yZWFsSW5kZXggfHwgdXNlT2Zmc2V0KSB7XG4gICAgICBsZXQgY3VycmVudFRodW1ic0luZGV4ID0gdGh1bWJzU3dpcGVyLmFjdGl2ZUluZGV4O1xuICAgICAgbGV0IG5ld1RodW1ic0luZGV4O1xuICAgICAgbGV0IGRpcmVjdGlvbjtcblxuICAgICAgaWYgKHRodW1ic1N3aXBlci5wYXJhbXMubG9vcCkge1xuICAgICAgICBpZiAodGh1bWJzU3dpcGVyLnNsaWRlcy5lcShjdXJyZW50VGh1bWJzSW5kZXgpLmhhc0NsYXNzKHRodW1ic1N3aXBlci5wYXJhbXMuc2xpZGVEdXBsaWNhdGVDbGFzcykpIHtcbiAgICAgICAgICB0aHVtYnNTd2lwZXIubG9vcEZpeCgpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuICAgICAgICAgIHRodW1ic1N3aXBlci5fY2xpZW50TGVmdCA9IHRodW1ic1N3aXBlci4kd3JhcHBlckVsWzBdLmNsaWVudExlZnQ7XG4gICAgICAgICAgY3VycmVudFRodW1ic0luZGV4ID0gdGh1bWJzU3dpcGVyLmFjdGl2ZUluZGV4O1xuICAgICAgICB9IC8vIEZpbmQgYWN0dWFsIHRodW1icyBpbmRleCB0byBzbGlkZSB0b1xuXG5cbiAgICAgICAgY29uc3QgcHJldlRodW1ic0luZGV4ID0gdGh1bWJzU3dpcGVyLnNsaWRlcy5lcShjdXJyZW50VGh1bWJzSW5kZXgpLnByZXZBbGwoYFtkYXRhLXN3aXBlci1zbGlkZS1pbmRleD1cIiR7c3dpcGVyLnJlYWxJbmRleH1cIl1gKS5lcSgwKS5pbmRleCgpO1xuICAgICAgICBjb25zdCBuZXh0VGh1bWJzSW5kZXggPSB0aHVtYnNTd2lwZXIuc2xpZGVzLmVxKGN1cnJlbnRUaHVtYnNJbmRleCkubmV4dEFsbChgW2RhdGEtc3dpcGVyLXNsaWRlLWluZGV4PVwiJHtzd2lwZXIucmVhbEluZGV4fVwiXWApLmVxKDApLmluZGV4KCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBwcmV2VGh1bWJzSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgbmV3VGh1bWJzSW5kZXggPSBuZXh0VGh1bWJzSW5kZXg7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5leHRUaHVtYnNJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBuZXdUaHVtYnNJbmRleCA9IHByZXZUaHVtYnNJbmRleDtcbiAgICAgICAgfSBlbHNlIGlmIChuZXh0VGh1bWJzSW5kZXggLSBjdXJyZW50VGh1bWJzSW5kZXggPT09IGN1cnJlbnRUaHVtYnNJbmRleCAtIHByZXZUaHVtYnNJbmRleCkge1xuICAgICAgICAgIG5ld1RodW1ic0luZGV4ID0gdGh1bWJzU3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCA+IDEgPyBuZXh0VGh1bWJzSW5kZXggOiBjdXJyZW50VGh1bWJzSW5kZXg7XG4gICAgICAgIH0gZWxzZSBpZiAobmV4dFRodW1ic0luZGV4IC0gY3VycmVudFRodW1ic0luZGV4IDwgY3VycmVudFRodW1ic0luZGV4IC0gcHJldlRodW1ic0luZGV4KSB7XG4gICAgICAgICAgbmV3VGh1bWJzSW5kZXggPSBuZXh0VGh1bWJzSW5kZXg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3VGh1bWJzSW5kZXggPSBwcmV2VGh1bWJzSW5kZXg7XG4gICAgICAgIH1cblxuICAgICAgICBkaXJlY3Rpb24gPSBzd2lwZXIuYWN0aXZlSW5kZXggPiBzd2lwZXIucHJldmlvdXNJbmRleCA/ICduZXh0JyA6ICdwcmV2JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld1RodW1ic0luZGV4ID0gc3dpcGVyLnJlYWxJbmRleDtcbiAgICAgICAgZGlyZWN0aW9uID0gbmV3VGh1bWJzSW5kZXggPiBzd2lwZXIucHJldmlvdXNJbmRleCA/ICduZXh0JyA6ICdwcmV2JztcbiAgICAgIH1cblxuICAgICAgaWYgKHVzZU9mZnNldCkge1xuICAgICAgICBuZXdUaHVtYnNJbmRleCArPSBkaXJlY3Rpb24gPT09ICduZXh0JyA/IGF1dG9TY3JvbGxPZmZzZXQgOiAtMSAqIGF1dG9TY3JvbGxPZmZzZXQ7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aHVtYnNTd2lwZXIudmlzaWJsZVNsaWRlc0luZGV4ZXMgJiYgdGh1bWJzU3dpcGVyLnZpc2libGVTbGlkZXNJbmRleGVzLmluZGV4T2YobmV3VGh1bWJzSW5kZXgpIDwgMCkge1xuICAgICAgICBpZiAodGh1bWJzU3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcykge1xuICAgICAgICAgIGlmIChuZXdUaHVtYnNJbmRleCA+IGN1cnJlbnRUaHVtYnNJbmRleCkge1xuICAgICAgICAgICAgbmV3VGh1bWJzSW5kZXggPSBuZXdUaHVtYnNJbmRleCAtIE1hdGguZmxvb3Ioc2xpZGVzUGVyVmlldyAvIDIpICsgMTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3VGh1bWJzSW5kZXggPSBuZXdUaHVtYnNJbmRleCArIE1hdGguZmxvb3Ioc2xpZGVzUGVyVmlldyAvIDIpIC0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAobmV3VGh1bWJzSW5kZXggPiBjdXJyZW50VGh1bWJzSW5kZXggJiYgdGh1bWJzU3dpcGVyLnBhcmFtcy5zbGlkZXNQZXJHcm91cCA9PT0gMSkgey8vIG5ld1RodW1ic0luZGV4ID0gbmV3VGh1bWJzSW5kZXggLSBzbGlkZXNQZXJWaWV3ICsgMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRodW1ic1N3aXBlci5zbGlkZVRvKG5ld1RodW1ic0luZGV4LCBpbml0aWFsID8gMCA6IHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb24oJ2JlZm9yZUluaXQnLCAoKSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgdGh1bWJzXG4gICAgfSA9IHN3aXBlci5wYXJhbXM7XG4gICAgaWYgKCF0aHVtYnMgfHwgIXRodW1icy5zd2lwZXIp
1IHJldHVybjtcbiAgICBpbml0KCk7XG4gICAgdXBkYXRlKHRydWUpO1xuICB9KTtcbiAgb24oJ3NsaWRlQ2hhbmdlIHVwZGF0ZSByZXNpemUgb2JzZXJ2ZXJVcGRhdGUnLCAoKSA9PiB7XG4gICAgdXBkYXRlKCk7XG4gIH0pO1xuICBvbignc2V0VHJhbnNpdGlvbicsIChfcywgZHVyYXRpb24pID0+IHtcbiAgICBjb25zdCB0aHVtYnNTd2lwZXIgPSBzd2lwZXIudGh1bWJzLnN3aXBlcjtcbiAgICBpZiAoIXRodW1ic1N3aXBlciB8fCB0aHVtYnNTd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XG4gICAgdGh1bWJzU3dpcGVyLnNldFRyYW5zaXRpb24oZHVyYXRpb24pO1xuICB9KTtcbiAgb24oJ2JlZm9yZURlc3Ryb3knLCAoKSA9PiB7XG4gICAgY29uc3QgdGh1bWJzU3dpcGVyID0gc3dpcGVyLnRodW1icy5zd2lwZXI7XG4gICAgaWYgKCF0aHVtYnNTd2lwZXIgfHwgdGh1bWJzU3dpcGVyLmRlc3Ryb3llZCkgcmV0dXJuO1xuXG4gICAgaWYgKHN3aXBlckNyZWF0ZWQpIHtcbiAgICAgIHRodW1ic1N3aXBlci5kZXN0cm95KCk7XG4gICAgfVxuICB9KTtcbiAgT2JqZWN0LmFzc2lnbihzd2lwZXIudGh1bWJzLCB7XG4gICAgaW5pdCxcbiAgICB1cGRhdGVcbiAgfSk7XG59IiwiaW1wb3J0IHsgbm93IH0gZnJvbSAnLi4vLi4vc2hhcmVkL3V0aWxzLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGZyZWVNb2RlKHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIGVtaXQsXG4gIG9uY2Vcbn0pIHtcbiAgZXh0ZW5kUGFyYW1zKHtcbiAgICBmcmVlTW9kZToge1xuICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICBtb21lbnR1bTogdHJ1ZSxcbiAgICAgIG1vbWVudHVtUmF0aW86IDEsXG4gICAgICBtb21lbnR1bUJvdW5jZTogdHJ1ZSxcbiAgICAgIG1vbWVudHVtQm91bmNlUmF0aW86IDEsXG4gICAgICBtb21lbnR1bVZlbG9jaXR5UmF0aW86IDEsXG4gICAgICBzdGlja3k6IGZhbHNlLFxuICAgICAgbWluaW11bVZlbG9jaXR5OiAwLjAyXG4gICAgfVxuICB9KTtcblxuICBmdW5jdGlvbiBvblRvdWNoU3RhcnQoKSB7XG4gICAgY29uc3QgdHJhbnNsYXRlID0gc3dpcGVyLmdldFRyYW5zbGF0ZSgpO1xuICAgIHN3aXBlci5zZXRUcmFuc2xhdGUodHJhbnNsYXRlKTtcbiAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbigwKTtcbiAgICBzd2lwZXIudG91Y2hFdmVudHNEYXRhLnZlbG9jaXRpZXMubGVuZ3RoID0gMDtcbiAgICBzd2lwZXIuZnJlZU1vZGUub25Ub3VjaEVuZCh7XG4gICAgICBjdXJyZW50UG9zOiBzd2lwZXIucnRsID8gc3dpcGVyLnRyYW5zbGF0ZSA6IC1zd2lwZXIudHJhbnNsYXRlXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBvblRvdWNoTW92ZSgpIHtcbiAgICBjb25zdCB7XG4gICAgICB0b3VjaEV2ZW50c0RhdGE6IGRhdGEsXG4gICAgICB0b3VjaGVzXG4gICAgfSA9IHN3aXBlcjsgLy8gVmVsb2NpdHlcblxuICAgIGlmIChkYXRhLnZlbG9jaXRpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBkYXRhLnZlbG9jaXRpZXMucHVzaCh7XG4gICAgICAgIHBvc2l0aW9uOiB0b3VjaGVzW3N3aXBlci5pc0hvcml6b250YWwoKSA/ICdzdGFydFgnIDogJ3N0YXJ0WSddLFxuICAgICAgICB0aW1lOiBkYXRhLnRvdWNoU3RhcnRUaW1lXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBkYXRhLnZlbG9jaXRpZXMucHVzaCh7XG4gICAgICBwb3NpdGlvbjogdG91Y2hlc1tzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnY3VycmVudFgnIDogJ2N1cnJlbnRZJ10sXG4gICAgICB0aW1lOiBub3coKVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gb25Ub3VjaEVuZCh7XG4gICAgY3VycmVudFBvc1xuICB9KSB7XG4gICAgY29uc3Qge1xuICAgICAgcGFyYW1zLFxuICAgICAgJHdyYXBwZXJFbCxcbiAgICAgIHJ0bFRyYW5zbGF0ZTogcnRsLFxuICAgICAgc25hcEdyaWQsXG4gICAgICB0b3VjaEV2ZW50c0RhdGE6IGRhdGFcbiAgICB9ID0gc3dpcGVyOyAvLyBUaW1lIGRpZmZcblxuICAgIGNvbnN0IHRvdWNoRW5kVGltZSA9IG5vdygpO1xuICAgIGNvbnN0IHRpbWVEaWZmID0gdG91Y2hFbmRUaW1lIC0gZGF0YS50b3VjaFN0YXJ0VGltZTtcblxuICAgIGlmIChjdXJyZW50UG9zIDwgLXN3aXBlci5taW5UcmFuc2xhdGUoKSkge1xuICAgICAgc3dpcGVyLnNsaWRlVG8oc3dpcGVyLmFjdGl2ZUluZGV4KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY3VycmVudFBvcyA+IC1zd2lwZXIubWF4VHJhbnNsYXRlKCkpIHtcbiAgICAgIGlmIChzd2lwZXIuc2xpZGVzLmxlbmd0aCA8IHNuYXBHcmlkLmxlbmd0aCkge1xuICAgICAgICBzd2lwZXIuc2xpZGVUbyhzbmFwR3JpZC5sZW5ndGggLSAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXBlci5zbGlkZVRvKHN3aXBlci5zbGlkZXMubGVuZ3RoIC0gMSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmZyZWVNb2RlLm1vbWVudHVtKSB7XG4gICAgICBpZiAoZGF0YS52ZWxvY2l0aWVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgY29uc3QgbGFzdE1vdmVFdmVudCA9IGRhdGEudmVsb2NpdGllcy5wb3AoKTtcbiAgICAgICAgY29uc3QgdmVsb2NpdHlFdmVudCA9IGRhdGEudmVsb2NpdGllcy5wb3AoKTtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBsYXN0TW92ZUV2ZW50LnBvc2l0aW9uIC0gdmVsb2NpdHlFdmVudC5wb3NpdGlvbjtcbiAgICAgICAgY29uc3QgdGltZSA9IGxhc3RNb3ZlRXZlbnQudGltZSAtIHZlbG9jaXR5RXZlbnQudGltZTtcbiAgICAgICAgc3dpcGVyLnZlbG9jaXR5ID0gZGlzdGFuY2UgLyB0aW1lO1xuICAgICAgICBzd2lwZXIudmVsb2NpdHkgLz0gMjtcblxuICAgICAgICBpZiAoTWF0aC5hYnMoc3dpcGVyLnZlbG9jaXR5KSA8IHBhcmFtcy5mcmVlTW9kZS5taW5pbXVtVmVsb2NpdHkpIHtcbiAgICAgICAgICBzd2lwZXIudmVsb2NpdHkgPSAwO1xuICAgICAgICB9IC8vIHRoaXMgaW1wbGllcyB0aGF0IHRoZSB1c2VyIHN0b3BwZWQgbW92aW5nIGEgZmluZ2VyIHRoZW4gcmVsZWFzZWQuXG4gICAgICAgIC8vIFRoZXJlIHdvdWxkIGJlIG5vIGV2ZW50cyB3aXRoIGRpc3RhbmNlIHplcm8sIHNvIHRoZSBsYXN0IGV2ZW50IGlzIHN0YWxlLlxuXG5cbiAgICAgICAgaWYgKHRpbWUgPiAxNTAgfHwgbm93KCkgLSBsYXN0TW92ZUV2ZW50LnRpbWUgPiAzMDApIHtcbiAgICAgICAgICBzd2lwZXIudmVsb2NpdHkgPSAwO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2lwZXIudmVsb2NpdHkgPSAwO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIudmVsb2NpdHkgKj0gcGFyYW1zLmZyZWVNb2RlLm1vbWVudHVtVmVsb2NpdHlSYXRpbztcbiAgICAgIGRhdGEudmVsb2NpdGllcy5sZW5ndGggPSAwO1xuICAgICAgbGV0IG1vbWVudHVtRHVyYXRpb24gPSAxMDAwICogcGFyYW1zLmZyZWVNb2RlLm1vbWVudHVtUmF0aW87XG4gICAgICBjb25zdCBtb21lbnR1bURpc3RhbmNlID0gc3dpcGVyLnZlbG9jaXR5ICogbW9tZW50dW1EdXJhdGlvbjtcbiAgICAgIGxldCBuZXdQb3NpdGlvbiA9IHN3aXBlci50cmFuc2xhdGUgKyBtb21lbnR1bURpc3RhbmNlO1xuICAgICAgaWYgKHJ0bCkgbmV3UG9zaXRpb24gPSAtbmV3
1UG9zaXRpb247XG4gICAgICBsZXQgZG9Cb3VuY2UgPSBmYWxzZTtcbiAgICAgIGxldCBhZnRlckJvdW5jZVBvc2l0aW9uO1xuICAgICAgY29uc3QgYm91bmNlQW1vdW50ID0gTWF0aC5hYnMoc3dpcGVyLnZlbG9jaXR5KSAqIDIwICogcGFyYW1zLmZyZWVNb2RlLm1vbWVudHVtQm91bmNlUmF0aW87XG4gICAgICBsZXQgbmVlZHNMb29wRml4O1xuXG4gICAgICBpZiAobmV3UG9zaXRpb24gPCBzd2lwZXIubWF4VHJhbnNsYXRlKCkpIHtcbiAgICAgICAgaWYgKHBhcmFtcy5mcmVlTW9kZS5tb21lbnR1bUJvdW5jZSkge1xuICAgICAgICAgIGlmIChuZXdQb3NpdGlvbiArIHN3aXBlci5tYXhUcmFuc2xhdGUoKSA8IC1ib3VuY2VBbW91bnQpIHtcbiAgICAgICAgICAgIG5ld1Bvc2l0aW9uID0gc3dpcGVyLm1heFRyYW5zbGF0ZSgpIC0gYm91bmNlQW1vdW50O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGFmdGVyQm91bmNlUG9zaXRpb24gPSBzd2lwZXIubWF4VHJhbnNsYXRlKCk7XG4gICAgICAgICAgZG9Cb3VuY2UgPSB0cnVlO1xuICAgICAgICAgIGRhdGEuYWxsb3dNb21lbnR1bUJvdW5jZSA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3UG9zaXRpb24gPSBzd2lwZXIubWF4VHJhbnNsYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFyYW1zLmxvb3AgJiYgcGFyYW1zLmNlbnRlcmVkU2xpZGVzKSBuZWVkc0xvb3BGaXggPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChuZXdQb3NpdGlvbiA+IHN3aXBlci5taW5UcmFuc2xhdGUoKSkge1xuICAgICAgICBpZiAocGFyYW1zLmZyZWVNb2RlLm1vbWVudHVtQm91bmNlKSB7XG4gICAgICAgICAgaWYgKG5ld1Bvc2l0aW9uIC0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpID4gYm91bmNlQW1vdW50KSB7XG4gICAgICAgICAgICBuZXdQb3NpdGlvbiA9IHN3aXBlci5taW5UcmFuc2xhdGUoKSArIGJvdW5jZUFtb3VudDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhZnRlckJvdW5jZVBvc2l0aW9uID0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpO1xuICAgICAgICAgIGRvQm91bmNlID0gdHJ1ZTtcbiAgICAgICAgICBkYXRhLmFsbG93TW9tZW50dW1Cb3VuY2UgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld1Bvc2l0aW9uID0gc3dpcGVyLm1pblRyYW5zbGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcmFtcy5sb29wICYmIHBhcmFtcy5jZW50ZXJlZFNsaWRlcykgbmVlZHNMb29wRml4ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAocGFyYW1zLmZyZWVNb2RlLnN0aWNreSkge1xuICAgICAgICBsZXQgbmV4dFNsaWRlO1xuXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgc25hcEdyaWQubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICBpZiAoc25hcEdyaWRbal0gPiAtbmV3UG9zaXRpb24pIHtcbiAgICAgICAgICAgIG5leHRTbGlkZSA9IGo7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoTWF0aC5hYnMoc25hcEdyaWRbbmV4dFNsaWRlXSAtIG5ld1Bvc2l0aW9uKSA8IE1hdGguYWJzKHNuYXBHcmlkW25leHRTbGlkZSAtIDFdIC0gbmV3UG9zaXRpb24pIHx8IHN3aXBlci5zd2lwZURpcmVjdGlvbiA9PT0gJ25leHQnKSB7XG4gICAgICAgICAgbmV3UG9zaXRpb24gPSBzbmFwR3JpZFtuZXh0U2xpZGVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld1Bvc2l0aW9uID0gc25hcEdyaWRbbmV4dFNsaWRlIC0gMV07XG4gICAgICAgIH1cblxuICAgICAgICBuZXdQb3NpdGlvbiA9IC1uZXdQb3NpdGlvbjtcbiAgICAgIH1cblxuICAgICAgaWYgKG5lZWRzTG9vcEZpeCkge1xuICAgICAgICBvbmNlKCd0cmFuc2l0aW9uRW5kJywgKCkgPT4ge1xuICAgICAgICAgIHN3aXBlci5sb29wRml4KCk7XG4gICAgICAgIH0pO1xuICAgICAgfSAvLyBGaXggZHVyYXRpb25cblxuXG4gICAgICBpZiAoc3dpcGVyLnZlbG9jaXR5ICE9PSAwKSB7XG4gICAgICAgIGlmIChydGwpIHtcbiAgICAgICAgICBtb21lbnR1bUR1cmF0aW9uID0gTWF0aC5hYnMoKC1uZXdQb3NpdGlvbiAtIHN3aXBlci50cmFuc2xhdGUpIC8gc3dpcGVyLnZlbG9jaXR5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtb21lbnR1bUR1cmF0aW9uID0gTWF0aC5hYnMoKG5ld1Bvc2l0aW9uIC0gc3dpcGVyLnRyYW5zbGF0ZSkgLyBzd2lwZXIudmVsb2NpdHkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcmFtcy5mcmVlTW9kZS5zdGlja3kpIHtcbiAgICAgICAgICAvLyBJZiBmcmVlTW9kZS5zdGlja3kgaXMgYWN0aXZlIGFuZCB0aGUgdXNlciBlbmRzIGEgc3dpcGUgd2l0aCBhIHNsb3ctdmVsb2NpdHlcbiAgICAgICAgICAvLyBldmVudCwgdGhlbiBkdXJhdGlvbnMgY2FuIGJlIDIwKyBzZWNvbmRzIHRvIHNsaWRlIG9uZSAob3IgemVybyEpIHNsaWRlcy5cbiAgICAgICAgICAvLyBJdCdzIGVhc3kgdG8gc2VlIHRoaXMgd2hlbiBzaW11bGF0aW5nIHRvdWNoIHdpdGggbW91c2UgZXZlbnRzLiBUbyBmaXggdGhpcyxcbiAgICAgICAgICAvLyBsaW1pdCBzaW5nbGUtc2xpZGUgc3dpcGVzIHRvIHRoZSBkZWZhdWx0IHNsaWRlIGR1cmF0aW9uLiBUaGlzIGFsc28gaGFzIHRoZVxuICAgICAgICAgIC8vIG5pY2Ugc2lkZSBlZmZlY3Qgb2YgbWF0Y2hpbmcgc2xpZGUgc3BlZWQgaWYgdGhlIHVzZXIgc3RvcHBlZCBtb3ZpbmcgYmVmb3JlXG4gICAgICAgICAgLy8gbGlmdGluZyBmaW5nZXIgb3IgbW91c2UgdnMuIG1vdmluZyBzbG93bHkgYmVmb3JlIGxpZnRpbmcgdGhlIGZpbmdlci9tb3VzZS5cbiAgICAgICAgICAvLyBGb3IgZmFzdGVyIHN3aXBlcywgYWxzbyBhcHBseSBsaW1pdHMgKGFsYmVpdCBoaWdoZXIgb25lcykuXG4gICAgICAgICAgY29uc3QgbW92ZURpc3RhbmNlID0gTWF0aC5hYnMoKHJ0bCA/IC1uZXdQb3NpdGlvbiA6IG5ld1Bvc2l0aW9uKSAtIHN3aXBlci50cmFuc2xhdGUpO1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTbGlkZVNpemUgPSBzd2lwZXIuc2xpZGVzU2l6ZXNHcmlkW3N3aXBlci5hY3RpdmVJbmRleF07XG5cbiAgICAgICAgICBpZiAobW92ZURpc3RhbmNlIDwgY3VycmVudFNsaWRlU2l6ZSkge1xuICAgICAgICAgICAgbW9tZW50dW1EdXJhdGlvbiA9IHBhcmFtcy5zcGVlZDtcbiAgICAgICAgICB9IGVsc2UgaWYgKG1vdmVEaXN0YW5jZSA8IDIgKiBjdXJyZW50U2xpZGVTaXplKSB7XG4gICAgICAgICAgICBtb21lbnR1bUR1cmF0aW9uID0gcGFyYW1zLnNwZWVkICogMS41O1xuICAgICAgICAgI
1H0gZWxzZSB7XG4gICAgICAgICAgICBtb21lbnR1bUR1cmF0aW9uID0gcGFyYW1zLnNwZWVkICogMi41O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJhbXMuZnJlZU1vZGUuc3RpY2t5KSB7XG4gICAgICAgIHN3aXBlci5zbGlkZVRvQ2xvc2VzdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJhbXMuZnJlZU1vZGUubW9tZW50dW1Cb3VuY2UgJiYgZG9Cb3VuY2UpIHtcbiAgICAgICAgc3dpcGVyLnVwZGF0ZVByb2dyZXNzKGFmdGVyQm91bmNlUG9zaXRpb24pO1xuICAgICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbihtb21lbnR1bUR1cmF0aW9uKTtcbiAgICAgICAgc3dpcGVyLnNldFRyYW5zbGF0ZShuZXdQb3NpdGlvbik7XG4gICAgICAgIHN3aXBlci50cmFuc2l0aW9uU3RhcnQodHJ1ZSwgc3dpcGVyLnN3aXBlRGlyZWN0aW9uKTtcbiAgICAgICAgc3dpcGVyLmFuaW1hdGluZyA9IHRydWU7XG4gICAgICAgICR3cmFwcGVyRWwudHJhbnNpdGlvbkVuZCgoKSA9PiB7XG4gICAgICAgICAgaWYgKCFzd2lwZXIgfHwgc3dpcGVyLmRlc3Ryb3llZCB8fCAhZGF0YS5hbGxvd01vbWVudHVtQm91bmNlKSByZXR1cm47XG4gICAgICAgICAgZW1pdCgnbW9tZW50dW1Cb3VuY2UnKTtcbiAgICAgICAgICBzd2lwZXIuc2V0VHJhbnNpdGlvbihwYXJhbXMuc3BlZWQpO1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgc3dpcGVyLnNldFRyYW5zbGF0ZShhZnRlckJvdW5jZVBvc2l0aW9uKTtcbiAgICAgICAgICAgICR3cmFwcGVyRWwudHJhbnNpdGlvbkVuZCgoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghc3dpcGVyIHx8IHN3aXBlci5kZXN0cm95ZWQpIHJldHVybjtcbiAgICAgICAgICAgICAgc3dpcGVyLnRyYW5zaXRpb25FbmQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sIDApO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoc3dpcGVyLnZlbG9jaXR5KSB7XG4gICAgICAgIGVtaXQoJ19mcmVlTW9kZU5vTW9tZW50dW1SZWxlYXNlJyk7XG4gICAgICAgIHN3aXBlci51cGRhdGVQcm9ncmVzcyhuZXdQb3NpdGlvbik7XG4gICAgICAgIHN3aXBlci5zZXRUcmFuc2l0aW9uKG1vbWVudHVtRHVyYXRpb24pO1xuICAgICAgICBzd2lwZXIuc2V0VHJhbnNsYXRlKG5ld1Bvc2l0aW9uKTtcbiAgICAgICAgc3dpcGVyLnRyYW5zaXRpb25TdGFydCh0cnVlLCBzd2lwZXIuc3dpcGVEaXJlY3Rpb24pO1xuXG4gICAgICAgIGlmICghc3dpcGVyLmFuaW1hdGluZykge1xuICAgICAgICAgIHN3aXBlci5hbmltYXRpbmcgPSB0cnVlO1xuICAgICAgICAgICR3cmFwcGVyRWwudHJhbnNpdGlvbkVuZCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XG4gICAgICAgICAgICBzd2lwZXIudHJhbnNpdGlvbkVuZCgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MobmV3UG9zaXRpb24pO1xuICAgICAgfVxuXG4gICAgICBzd2lwZXIudXBkYXRlQWN0aXZlSW5kZXgoKTtcbiAgICAgIHN3aXBlci51cGRhdGVTbGlkZXNDbGFzc2VzKCk7XG4gICAgfSBlbHNlIGlmIChwYXJhbXMuZnJlZU1vZGUuc3RpY2t5KSB7XG4gICAgICBzd2lwZXIuc2xpZGVUb0Nsb3Nlc3QoKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKHBhcmFtcy5mcmVlTW9kZSkge1xuICAgICAgZW1pdCgnX2ZyZWVNb2RlTm9Nb21lbnR1bVJlbGVhc2UnKTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy5mcmVlTW9kZS5tb21lbnR1bSB8fCB0aW1lRGlmZiA+PSBwYXJhbXMubG9uZ1N3aXBlc01zKSB7XG4gICAgICBzd2lwZXIudXBkYXRlUHJvZ3Jlc3MoKTtcbiAgICAgIHN3aXBlci51cGRhdGVBY3RpdmVJbmRleCgpO1xuICAgICAgc3dpcGVyLnVwZGF0ZVNsaWRlc0NsYXNzZXMoKTtcbiAgICB9XG4gIH1cblxuICBPYmplY3QuYXNzaWduKHN3aXBlciwge1xuICAgIGZyZWVNb2RlOiB7XG4gICAgICBvblRvdWNoU3RhcnQsXG4gICAgICBvblRvdWNoTW92ZSxcbiAgICAgIG9uVG91Y2hFbmRcbiAgICB9XG4gIH0pO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEdyaWQoe1xuICBzd2lwZXIsXG4gIGV4dGVuZFBhcmFtc1xufSkge1xuICBleHRlbmRQYXJhbXMoe1xuICAgIGdyaWQ6IHtcbiAgICAgIHJvd3M6IDEsXG4gICAgICBmaWxsOiAnY29sdW1uJ1xuICAgIH1cbiAgfSk7XG4gIGxldCBzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzO1xuICBsZXQgc2xpZGVzUGVyUm93O1xuICBsZXQgbnVtRnVsbENvbHVtbnM7XG5cbiAgY29uc3QgaW5pdFNsaWRlcyA9IHNsaWRlc0xlbmd0aCA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgc2xpZGVzUGVyVmlld1xuICAgIH0gPSBzd2lwZXIucGFyYW1zO1xuICAgIGNvbnN0IHtcbiAgICAgIHJvd3MsXG4gICAgICBmaWxsXG4gICAgfSA9IHN3aXBlci5wYXJhbXMuZ3JpZDtcbiAgICBzbGlkZXNQZXJSb3cgPSBzbGlkZXNOdW1iZXJFdmVuVG9Sb3dzIC8gcm93cztcbiAgICBudW1GdWxsQ29sdW1ucyA9IE1hdGguZmxvb3Ioc2xpZGVzTGVuZ3RoIC8gcm93cyk7XG5cbiAgICBpZiAoTWF0aC5mbG9vcihzbGlkZXNMZW5ndGggLyByb3dzKSA9PT0gc2xpZGVzTGVuZ3RoIC8gcm93cykge1xuICAgICAgc2xpZGVzTnVtYmVyRXZlblRvUm93cyA9IHNsaWRlc0xlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2xpZGVzTnVtYmVyRXZlblRvUm93cyA9IE1hdGguY2VpbChzbGlkZXNMZW5ndGggLyByb3dzKSAqIHJvd3M7XG4gICAgfVxuXG4gICAgaWYgKHNsaWRlc1BlclZpZXcgIT09ICdhdXRvJyAmJiBmaWxsID09PSAncm93Jykge1xuICAgICAgc2xpZGVzTnVtYmVyRXZlblRvUm93cyA9IE1hdGgubWF4KHNsaWRlc051bWJlckV2ZW5Ub1Jvd3MsIHNsaWRlc1BlclZpZXcgKiByb3dzKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgdXBkYXRlU2xpZGUgPSAoaSwgc2xpZGUsIHNsaWRlc0xlbmd0aCwgZ2V0RGlyZWN0aW9uTGFiZWwpID0+IHtcbiAgICBjb25zdCB7XG4gICAgICBzbGlkZXNQZXJHcm91cCxcbiAgICAgIHNwYWNlQmV0d2VlblxuICAgI
1H0gPSBzd2lwZXIucGFyYW1zO1xuICAgIGNvbnN0IHtcbiAgICAgIHJvd3MsXG4gICAgICBmaWxsXG4gICAgfSA9IHN3aXBlci5wYXJhbXMuZ3JpZDsgLy8gU2V0IHNsaWRlcyBvcmRlclxuXG4gICAgbGV0IG5ld1NsaWRlT3JkZXJJbmRleDtcbiAgICBsZXQgY29sdW1uO1xuICAgIGxldCByb3c7XG5cbiAgICBpZiAoZmlsbCA9PT0gJ3JvdycgJiYgc2xpZGVzUGVyR3JvdXAgPiAxKSB7XG4gICAgICBjb25zdCBncm91cEluZGV4ID0gTWF0aC5mbG9vcihpIC8gKHNsaWRlc1Blckdyb3VwICogcm93cykpO1xuICAgICAgY29uc3Qgc2xpZGVJbmRleEluR3JvdXAgPSBpIC0gcm93cyAqIHNsaWRlc1Blckdyb3VwICogZ3JvdXBJbmRleDtcbiAgICAgIGNvbnN0IGNvbHVtbnNJbkdyb3VwID0gZ3JvdXBJbmRleCA9PT0gMCA/IHNsaWRlc1Blckdyb3VwIDogTWF0aC5taW4oTWF0aC5jZWlsKChzbGlkZXNMZW5ndGggLSBncm91cEluZGV4ICogcm93cyAqIHNsaWRlc1Blckdyb3VwKSAvIHJvd3MpLCBzbGlkZXNQZXJHcm91cCk7XG4gICAgICByb3cgPSBNYXRoLmZsb29yKHNsaWRlSW5kZXhJbkdyb3VwIC8gY29sdW1uc0luR3JvdXApO1xuICAgICAgY29sdW1uID0gc2xpZGVJbmRleEluR3JvdXAgLSByb3cgKiBjb2x1bW5zSW5Hcm91cCArIGdyb3VwSW5kZXggKiBzbGlkZXNQZXJHcm91cDtcbiAgICAgIG5ld1NsaWRlT3JkZXJJbmRleCA9IGNvbHVtbiArIHJvdyAqIHNsaWRlc051bWJlckV2ZW5Ub1Jvd3MgLyByb3dzO1xuICAgICAgc2xpZGUuY3NzKHtcbiAgICAgICAgJy13ZWJraXQtb3JkZXInOiBuZXdTbGlkZU9yZGVySW5kZXgsXG4gICAgICAgIG9yZGVyOiBuZXdTbGlkZU9yZGVySW5kZXhcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoZmlsbCA9PT0gJ2NvbHVtbicpIHtcbiAgICAgIGNvbHVtbiA9IE1hdGguZmxvb3IoaSAvIHJvd3MpO1xuICAgICAgcm93ID0gaSAtIGNvbHVtbiAqIHJvd3M7XG5cbiAgICAgIGlmIChjb2x1bW4gPiBudW1GdWxsQ29sdW1ucyB8fCBjb2x1bW4gPT09IG51bUZ1bGxDb2x1bW5zICYmIHJvdyA9PT0gcm93cyAtIDEpIHtcbiAgICAgICAgcm93ICs9IDE7XG5cbiAgICAgICAgaWYgKHJvdyA+PSByb3dzKSB7XG4gICAgICAgICAgcm93ID0gMDtcbiAgICAgICAgICBjb2x1bW4gKz0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByb3cgPSBNYXRoLmZsb29yKGkgLyBzbGlkZXNQZXJSb3cpO1xuICAgICAgY29sdW1uID0gaSAtIHJvdyAqIHNsaWRlc1BlclJvdztcbiAgICB9XG5cbiAgICBzbGlkZS5jc3MoZ2V0RGlyZWN0aW9uTGFiZWwoJ21hcmdpbi10b3AnKSwgcm93ICE9PSAwID8gc3BhY2VCZXR3ZWVuICYmIGAke3NwYWNlQmV0d2Vlbn1weGAgOiAnJyk7XG4gIH07XG5cbiAgY29uc3QgdXBkYXRlV3JhcHBlclNpemUgPSAoc2xpZGVTaXplLCBzbmFwR3JpZCwgZ2V0RGlyZWN0aW9uTGFiZWwpID0+IHtcbiAgICBjb25zdCB7XG4gICAgICBzcGFjZUJldHdlZW4sXG4gICAgICBjZW50ZXJlZFNsaWRlcyxcbiAgICAgIHJvdW5kTGVuZ3Roc1xuICAgIH0gPSBzd2lwZXIucGFyYW1zO1xuICAgIGNvbnN0IHtcbiAgICAgIHJvd3NcbiAgICB9ID0gc3dpcGVyLnBhcmFtcy5ncmlkO1xuICAgIHN3aXBlci52aXJ0dWFsU2l6ZSA9IChzbGlkZVNpemUgKyBzcGFjZUJldHdlZW4pICogc2xpZGVzTnVtYmVyRXZlblRvUm93cztcbiAgICBzd2lwZXIudmlydHVhbFNpemUgPSBNYXRoLmNlaWwoc3dpcGVyLnZpcnR1YWxTaXplIC8gcm93cykgLSBzcGFjZUJldHdlZW47XG4gICAgc3dpcGVyLiR3cmFwcGVyRWwuY3NzKHtcbiAgICAgIFtnZXREaXJlY3Rpb25MYWJlbCgnd2lkdGgnKV06IGAke3N3aXBlci52aXJ0dWFsU2l6ZSArIHNwYWNlQmV0d2Vlbn1weGBcbiAgICB9KTtcblxuICAgIGlmIChjZW50ZXJlZFNsaWRlcykge1xuICAgICAgc25hcEdyaWQuc3BsaWNlKDAsIHNuYXBHcmlkLmxlbmd0aCk7XG4gICAgICBjb25zdCBuZXdTbGlkZXNHcmlkID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc25hcEdyaWQubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgbGV0IHNsaWRlc0dyaWRJdGVtID0gc25hcEdyaWRbaV07XG4gICAgICAgIGlmIChyb3VuZExlbmd0aHMpIHNsaWRlc0dyaWRJdGVtID0gTWF0aC5mbG9vcihzbGlkZXNHcmlkSXRlbSk7XG4gICAgICAgIGlmIChzbmFwR3JpZFtpXSA8IHN3aXBlci52aXJ0dWFsU2l6ZSArIHNuYXBHcmlkWzBdKSBuZXdTbGlkZXNHcmlkLnB1c2goc2xpZGVzR3JpZEl0ZW0pO1xuICAgICAgfVxuXG4gICAgICBzbmFwR3JpZC5wdXNoKC4uLm5ld1NsaWRlc0dyaWQpO1xuICAgIH1cbiAgfTtcblxuICBzd2lwZXIuZ3JpZCA9IHtcbiAgICBpbml0U2xpZGVzLFxuICAgIHVwZGF0ZVNsaWRlLFxuICAgIHVwZGF0ZVdyYXBwZXJTaXplXG4gIH07XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gYXBwZW5kU2xpZGUoc2xpZGVzKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IHtcbiAgICAkd3JhcHBlckVsLFxuICAgIHBhcmFtc1xuICB9ID0gc3dpcGVyO1xuXG4gIGlmIChwYXJhbXMubG9vcCkge1xuICAgIHN3aXBlci5sb29wRGVzdHJveSgpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBzbGlkZXMgPT09ICdvYmplY3QnICYmICdsZW5ndGgnIGluIHNsaWRlcykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpZiAoc2xpZGVzW2ldKSAkd3JhcHBlckVsLmFwcGVuZChzbGlkZXNbaV0pO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAkd3JhcHBlckVsLmFwcGVuZChzbGlkZXMpO1xuICB9XG5cbiAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcbiAgfVxuXG4gIGlmICghcGFyYW1zLm9ic2VydmVyKSB7XG4gICAgc3dpcGVyLnVwZGF0ZSgpO1xuICB9XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcHJlcGVuZFNsaWRlKHNsaWRlcykge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBjb25zdCB7XG4gICAgcGFyYW1zLFxuICAgICR3cmFwcGVyRWwsXG4gICAgYWN0aXZlSW5kZXhcbiAgfSA9IHN3aXBlcjtcblxuICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICBzd2lwZXIubG9vcERlc3Ryb3koKTtcbiAgfVxuXG4gIGxldCBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4ICsgMTtcblxuICBpZiAodHlwZW9mIHNsaWRlcyA9PT0gJ29iamVjdCcgJiYgJ2xlbmd0aCcgaW4gc2xpZGVzKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGlmIChzbGlkZXNbaV0pICR3cmFwcGVyRWwucHJlcGVuZChzbGlkZXNbaV0pO1xuICAgIH1cblxuICAgIG5ld0FjdGl2ZUluZGV4ID0gYWN0aXZlSW5kZXggKyBzbGlkZXMubGVuZ3RoO1xuICB9IGVsc2Uge1xuICAgICR3cmFwcGVyRWwucHJlcGVuZChzbGlkZXMpO1xuICB9XG5cbiAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcbiAgfVxuXG4gIGlmICghcGFyYW1zLm9ic2VydmVyKSB7XG4gICAgc3dpcGVyLnVwZGF0ZSgpO1xuICB9XG5cbiAgc3dpcGVyLnNsaWRlVG8obmV3QWN0aXZlSW5kZXgsIDAsIGZhbHNlKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBhZGRTbGlkZShpbmRleCwgc2xpZGVzKSB7XG4gIGNvbnN0IHN3aXBlciA9IHRoaXM7XG4gIGNvbnN0IHtcbiAgICAkd3JhcHBlckVsLFxuICAgIHBhcmFtcyxcbiAgICBhY3RpdmVJbmRleFxuICB9ID0gc3dpcGVyO1xuICBsZXQgYWN0aXZlSW5kZXhCdWZmZXIgPSBhY3RpdmVJbmRleDtcblxuICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICBhY3RpdmVJbmRleEJ1ZmZlciAtPSBzd2lwZXIubG9vcGVkU2xpZGVzO1xuICAgIHN3aXBlci5sb29wRGVzdHJveSgpO1xuICAgIHN3aXBlci5zbGlkZXMgPSAkd3JhcHBlckVsLmNoaWxkcmVuKGAuJHtwYXJhbXMuc2xpZGVDbGFzc31gKTtcbiAgfVxuXG4gIGNvbnN0IGJhc2VMZW5ndGggPSBzd2lwZXIuc2xpZGVzLmxlbmd0aDtcblxuICBpZiAoaW5kZXggPD0gMCkge1xuICAgIHN3aXBlci5wcmVwZW5kU2xpZGUoc2xpZGVzKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoaW5kZXggPj0gYmFzZUxlbmd0aCkge1xuICAgIHN3aXBlci5hcHBlbmRTbGlkZShzbGlkZXMpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBuZXdBY3RpdmVJbmRleCA9IGFjdGl2ZUluZGV4QnVmZmVyID4gaW5kZXggPyBhY3RpdmVJbmRleEJ1ZmZlciArIDEgOiBhY3RpdmVJbmRleEJ1ZmZlcjtcbiAgY29uc3Qgc2xpZGVzQnVmZmVyID0gW107XG5cbiAgZm9yIChsZXQgaSA9IGJhc2VMZW5ndGggLSAxOyBpID49IGluZGV4OyBpIC09IDEpIHtcbiAgICBjb25zdCBjdXJyZW50U2xpZGUgPSBzd2lwZXIuc2xpZGVzLmVxKGkpO1xuICAgIGN1cnJlbnRTbGlkZS5yZW1vdmUoKTtcbiAgICBzbGlkZXNCdWZmZXIudW5zaGlmdChjdXJyZW50U2xpZGUpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBzbGlkZXMgPT09ICdvYmplY3QnICYmICdsZW5ndGgnIGluIHNsaWRlcykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpZiAoc2xpZGVzW2ldKSAkd3JhcHBlckVsLmFwcGVuZChzbGlkZXNbaV0pO1xuICAgIH1cblxuICAgIG5ld0FjdGl2ZUluZGV4ID0gYWN0aXZlSW5kZXhCdWZmZXIgPiBpbmRleCA/IGFjdGl2ZUluZGV4QnVmZmVyICsgc2xpZGVzLmxlbmd0aCA6IGFjdGl2ZUluZGV4QnVmZmVyO1xuICB9IGVsc2Uge1xuICAgICR3cmFwcGVyRWwuYXBwZW5kKHNsaWRlcyk7XG4gIH1cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWRlc0J1ZmZlci5sZW5ndGg7IGkgKz0gMSkge1xuICAgICR3cmFwcGVyRWwuYXBwZW5kKHNsaWRlc0J1ZmZlcltpXSk7XG4gIH1cblxuICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICBzd2lwZXIubG9vcENyZWF0ZSgpO1xuICB9XG5cbiAgaWYgKCFwYXJhbXMub2JzZXJ2ZXIpIHtcbiAgICBzd2lwZXIudXBkYXRlKCk7XG4gIH1cblxuICBpZiAocGFyYW1zLmxvb3ApIHtcbiAgICBzd2lwZXIuc2xpZGVUbyhuZXdBY3RpdmVJbmRleCArIHN3aXBlci5sb29wZWRTbGlkZXMsIDAsIGZhbHNlKTtcbiAgfSBlbHNlIHtcbiAgICBzd2lwZXIuc2xpZGVUbyhuZXdBY3RpdmVJbmRleCwgMCwgZmFsc2UpO1xuICB9XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVtb3ZlU2xpZGUoc2xpZGVzSW5kZX
1hlcykge1xuICBjb25zdCBzd2lwZXIgPSB0aGlzO1xuICBjb25zdCB7XG4gICAgcGFyYW1zLFxuICAgICR3cmFwcGVyRWwsXG4gICAgYWN0aXZlSW5kZXhcbiAgfSA9IHN3aXBlcjtcbiAgbGV0IGFjdGl2ZUluZGV4QnVmZmVyID0gYWN0aXZlSW5kZXg7XG5cbiAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgYWN0aXZlSW5kZXhCdWZmZXIgLT0gc3dpcGVyLmxvb3BlZFNsaWRlcztcbiAgICBzd2lwZXIubG9vcERlc3Ryb3koKTtcbiAgICBzd2lwZXIuc2xpZGVzID0gJHdyYXBwZXJFbC5jaGlsZHJlbihgLiR7cGFyYW1zLnNsaWRlQ2xhc3N9YCk7XG4gIH1cblxuICBsZXQgbmV3QWN0aXZlSW5kZXggPSBhY3RpdmVJbmRleEJ1ZmZlcjtcbiAgbGV0IGluZGV4VG9SZW1vdmU7XG5cbiAgaWYgKHR5cGVvZiBzbGlkZXNJbmRleGVzID09PSAnb2JqZWN0JyAmJiAnbGVuZ3RoJyBpbiBzbGlkZXNJbmRleGVzKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXNJbmRleGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpbmRleFRvUmVtb3ZlID0gc2xpZGVzSW5kZXhlc1tpXTtcbiAgICAgIGlmIChzd2lwZXIuc2xpZGVzW2luZGV4VG9SZW1vdmVdKSBzd2lwZXIuc2xpZGVzLmVxKGluZGV4VG9SZW1vdmUpLnJlbW92ZSgpO1xuICAgICAgaWYgKGluZGV4VG9SZW1vdmUgPCBuZXdBY3RpdmVJbmRleCkgbmV3QWN0aXZlSW5kZXggLT0gMTtcbiAgICB9XG5cbiAgICBuZXdBY3RpdmVJbmRleCA9IE1hdGgubWF4KG5ld0FjdGl2ZUluZGV4LCAwKTtcbiAgfSBlbHNlIHtcbiAgICBpbmRleFRvUmVtb3ZlID0gc2xpZGVzSW5kZXhlcztcbiAgICBpZiAoc3dpcGVyLnNsaWRlc1tpbmRleFRvUmVtb3ZlXSkgc3dpcGVyLnNsaWRlcy5lcShpbmRleFRvUmVtb3ZlKS5yZW1vdmUoKTtcbiAgICBpZiAoaW5kZXhUb1JlbW92ZSA8IG5ld0FjdGl2ZUluZGV4KSBuZXdBY3RpdmVJbmRleCAtPSAxO1xuICAgIG5ld0FjdGl2ZUluZGV4ID0gTWF0aC5tYXgobmV3QWN0aXZlSW5kZXgsIDApO1xuICB9XG5cbiAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgc3dpcGVyLmxvb3BDcmVhdGUoKTtcbiAgfVxuXG4gIGlmICghcGFyYW1zLm9ic2VydmVyKSB7XG4gICAgc3dpcGVyLnVwZGF0ZSgpO1xuICB9XG5cbiAgaWYgKHBhcmFtcy5sb29wKSB7XG4gICAgc3dpcGVyLnNsaWRlVG8obmV3QWN0aXZlSW5kZXggKyBzd2lwZXIubG9vcGVkU2xpZGVzLCAwLCBmYWxzZSk7XG4gIH0gZWxzZSB7XG4gICAgc3dpcGVyLnNsaWRlVG8obmV3QWN0aXZlSW5kZXgsIDAsIGZhbHNlKTtcbiAgfVxufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlbW92ZUFsbFNsaWRlcygpIHtcbiAgY29uc3Qgc3dpcGVyID0gdGhpcztcbiAgY29uc3Qgc2xpZGVzSW5kZXhlcyA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3dpcGVyLnNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIHNsaWRlc0luZGV4ZXMucHVzaChpKTtcbiAgfVxuXG4gIHN3aXBlci5yZW1vdmVTbGlkZShzbGlkZXNJbmRleGVzKTtcbn0iLCJpbXBvcnQgYXBwZW5kU2xpZGUgZnJvbSAnLi9tZXRob2RzL2FwcGVuZFNsaWRlLmpzJztcbmltcG9ydCBwcmVwZW5kU2xpZGUgZnJvbSAnLi9tZXRob2RzL3ByZXBlbmRTbGlkZS5qcyc7XG5pbXBvcnQgYWRkU2xpZGUgZnJvbSAnLi9tZXRob2RzL2FkZFNsaWRlLmpzJztcbmltcG9ydCByZW1vdmVTbGlkZSBmcm9tICcuL21ldGhvZHMvcmVtb3ZlU2xpZGUuanMnO1xuaW1wb3J0IHJlbW92ZUFsbFNsaWRlcyBmcm9tICcuL21ldGhvZHMvcmVtb3ZlQWxsU2xpZGVzLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1hbmlwdWxhdGlvbih7XG4gIHN3aXBlclxufSkge1xuICBPYmplY3QuYXNzaWduKHN3aXBlciwge1xuICAgIGFwcGVuZFNsaWRlOiBhcHBlbmRTbGlkZS5iaW5kKHN3aXBlciksXG4gICAgcHJlcGVuZFNsaWRlOiBwcmVwZW5kU2xpZGUuYmluZChzd2lwZXIpLFxuICAgIGFkZFNsaWRlOiBhZGRTbGlkZS5iaW5kKHN3aXBlciksXG4gICAgcmVtb3ZlU2xpZGU6IHJlbW92ZVNsaWRlLmJpbmQoc3dpcGVyKSxcbiAgICByZW1vdmVBbGxTbGlkZXM6IHJlbW92ZUFsbFNsaWRlcy5iaW5kKHN3aXBlcilcbiAgfSk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZWZmZWN0SW5pdChwYXJhbXMpIHtcbiAgY29uc3Qge1xuICAgIGVmZmVjdCxcbiAgICBzd2lwZXIsXG4gICAgb24sXG4gICAgc2V0VHJhbnNsYXRlLFxuICAgIHNldFRyYW5zaXRpb24sXG4gICAgb3ZlcndyaXRlUGFyYW1zLFxuICAgIHBlcnNwZWN0aXZlLFxuICAgIHJlY3JlYXRlU2hhZG93cyxcbiAgICBnZXRFZmZlY3RQYXJhbXNcbiAgfSA9IHBhcmFtcztcbiAgb24oJ2JlZm9yZUluaXQnLCAoKSA9PiB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMuZWZmZWN0ICE9PSBlZmZlY3QpIHJldHVybjtcbiAgICBzd2lwZXIuY2xhc3NOYW1lcy5wdXNoKGAke3N3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzc30ke2VmZmVjdH1gKTtcblxuICAgIGlmIChwZXJzcGVjdGl2ZSAmJiBwZXJzcGVjdGl2ZSgpKSB7XG4gICAgICBzd2lwZXIuY2xhc3NOYW1lcy5wdXNoKGAke3N3aXBlci5wYXJhbXMuY29udGFpbmVyTW9kaWZpZXJDbGFzc30zZGApO1xuICAgIH1cblxuICAgIGNvbnN0IG92ZXJ3cml0ZVBhcmFtc1Jlc3VsdCA9IG92ZXJ3cml0ZVBhcmFtcyA/IG92ZXJ3cml0ZVBhcmFtcygpIDoge307XG4gICAgT2JqZWN0LmFzc2lnbihzd2lwZXIucGFyYW1zLCBvdmVyd3JpdGVQYXJhbXNSZXN1bHQpO1xuICAgIE9iamVjdC5hc3NpZ24oc3dpcGVyLm9yaWdpbmFsUGFyYW1zLCBvdmVyd3JpdGVQYXJhbXNSZXN1bHQpO1xuICB9KTtcbiAgb24oJ3NldFRyYW5zbGF0ZScsICgpID0+IHtcbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5lZmZlY3QgIT09IGVmZmVjdCkgcmV0dXJuO1xuICAgIHNldFRyYW5zbGF0ZSgpO1xuICB9KTtcbiAgb24oJ3NldFRyYW5zaXRpb24nLCAoX3MsIGR1cmF0aW9uKSA9PiB7XG4gICAgaWYgKHN3aXBlci5wYXJhbXMuZWZmZWN0ICE9PSBlZmZlY3QpIHJldHVybjtcbiAgICBzZXRUcmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgfSk7XG4gIG9uKCd0cmFuc2l0aW9uRW5kJywgKCkgPT4ge1xuICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gZWZmZWN0KSByZXR1cm47XG5cbiAgICBpZiAocmVjcmVhdGVTaGFkb3dzKSB7XG4gICAgICBpZiAoIWdldEVmZmVjdFBhcmFtcyB8fCAhZ2V0RWZmZWN0UGFyYW1zKCkuc2xpZGVTaGFkb3dzKSByZXR1cm47IC8vIHJlbW92ZSBzaGFkb3dzXG5cbiAgICAgIHN3aXBlci5zbGlkZXMuZWFjaChzbGlkZUVsID0+IHtcbiAgICAgICAgY29uc3QgJHNsaWRlRWwgPSBzd2lwZXIuJChzbGlkZUVsKTtcbiAgICAgICAgJHNsaWRlRWwuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1yaWdodCwgLnN3aXBlci1zbGlkZS1zaGFkb3ctYm90dG9tLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0JykucmVtb3ZlKCk7XG4gICAgICB9KTsgLy8gY3JlYXRlIG5ldyBvbmVcblxuICAgICAgcmVjcmVhdGVTaGFkb3dzKCk7XG4gICAgfVxuICB9KTtcbiAgbGV0IHJlcXVpcmVVcGRhdGVPblZpcnR1YWw7XG4gIG9uKCd2aXJ0dWFsVXBkYXRlJywgKCkgPT4ge1xuICAgIGlmIChzd2lwZXIucGFyYW1zLmVmZmVjdCAhPT0gZWZmZWN0KSByZXR1cm47XG5cbiAgICBpZiAoIXN3aXBlci5zbGlkZXMubGVuZ3RoKSB7XG4gICAgICByZXF1aXJlVXBkYXRlT25WaXJ0dWFsID0gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgaWYgKHJlcXVpcmVVcGRhdGVPblZpcnR1YWwgJiYgc3dpcGVyLnNsaWRlcyAmJiBzd2lwZXIuc2xpZGVzLmxlbmd0aCkge1xuICAgICAgICBzZXRUcmFuc2xhdGUoKTtcbiAgICAgICAgcmVxdWlyZVVwZGF0ZU9uVmlydHVhbCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBlZmZlY3RUYXJnZXQoZWZmZWN0UGFyYW1zLCAkc2xpZGVFbCkge1xuICBpZiAoZWZmZWN0UGFyYW1zLnRyYW5zZm9ybUVsKSB7XG4gICAgcmV0dXJuICRzbGlkZUVsLmZpbmQoZWZmZWN0UGFyYW1zLnRyYW5zZm9ybUVsKS5jc3Moe1xuICAgICAgJ2JhY2tmYWNlLX
1Zpc2liaWxpdHknOiAnaGlkZGVuJyxcbiAgICAgICctd2Via2l0LWJhY2tmYWNlLXZpc2liaWxpdHknOiAnaGlkZGVuJ1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuICRzbGlkZUVsO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGVmZmVjdFZpcnR1YWxUcmFuc2l0aW9uRW5kKHtcbiAgc3dpcGVyLFxuICBkdXJhdGlvbixcbiAgdHJhbnNmb3JtRWwsXG4gIGFsbFNsaWRlc1xufSkge1xuICBjb25zdCB7XG4gICAgc2xpZGVzLFxuICAgIGFjdGl2ZUluZGV4LFxuICAgICR3cmFwcGVyRWxcbiAgfSA9IHN3aXBlcjtcblxuICBpZiAoc3dpcGVyLnBhcmFtcy52aXJ0dWFsVHJhbnNsYXRlICYmIGR1cmF0aW9uICE9PSAwKSB7XG4gICAgbGV0IGV2ZW50VHJpZ2dlcmVkID0gZmFsc2U7XG4gICAgbGV0ICR0cmFuc2l0aW9uRW5kVGFyZ2V0O1xuXG4gICAgaWYgKGFsbFNsaWRlcykge1xuICAgICAgJHRyYW5zaXRpb25FbmRUYXJnZXQgPSB0cmFuc2Zvcm1FbCA/IHNsaWRlcy5maW5kKHRyYW5zZm9ybUVsKSA6IHNsaWRlcztcbiAgICB9IGVsc2Uge1xuICAgICAgJHRyYW5zaXRpb25FbmRUYXJnZXQgPSB0cmFuc2Zvcm1FbCA/IHNsaWRlcy5lcShhY3RpdmVJbmRleCkuZmluZCh0cmFuc2Zvcm1FbCkgOiBzbGlkZXMuZXEoYWN0aXZlSW5kZXgpO1xuICAgIH1cblxuICAgICR0cmFuc2l0aW9uRW5kVGFyZ2V0LnRyYW5zaXRpb25FbmQoKCkgPT4ge1xuICAgICAgaWYgKGV2ZW50VHJpZ2dlcmVkKSByZXR1cm47XG4gICAgICBpZiAoIXN3aXBlciB8fCBzd2lwZXIuZGVzdHJveWVkKSByZXR1cm47XG4gICAgICBldmVudFRyaWdnZXJlZCA9IHRydWU7XG4gICAgICBzd2lwZXIuYW5pbWF0aW5nID0gZmFsc2U7XG4gICAgICBjb25zdCB0cmlnZ2VyRXZlbnRzID0gWyd3ZWJraXRUcmFuc2l0aW9uRW5kJywgJ3RyYW5zaXRpb25lbmQnXTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0cmlnZ2VyRXZlbnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICR3cmFwcGVyRWwudHJpZ2dlcih0cmlnZ2VyRXZlbnRzW2ldKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufSIsImltcG9ydCBlZmZlY3RJbml0IGZyb20gJy4uLy4uL3NoYXJlZC9lZmZlY3QtaW5pdC5qcyc7XG5pbXBvcnQgZWZmZWN0VGFyZ2V0IGZyb20gJy4uLy4uL3NoYXJlZC9lZmZlY3QtdGFyZ2V0LmpzJztcbmltcG9ydCBlZmZlY3RWaXJ0dWFsVHJhbnNpdGlvbkVuZCBmcm9tICcuLi8uLi9zaGFyZWQvZWZmZWN0LXZpcnR1YWwtdHJhbnNpdGlvbi1lbmQuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRWZmZWN0RmFkZSh7XG4gIHN3aXBlcixcbiAgZXh0ZW5kUGFyYW1zLFxuICBvblxufSkge1xuICBleHRlbmRQYXJhbXMoe1xuICAgIGZhZGVFZmZlY3Q6IHtcbiAgICAgIGNyb3NzRmFkZTogZmFsc2UsXG4gICAgICB0cmFuc2Zvcm1FbDogbnVsbFxuICAgIH1cbiAgfSk7XG5cbiAgY29uc3Qgc2V0VHJhbnNsYXRlID0gKCkgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgIHNsaWRlc1xuICAgIH0gPSBzd2lwZXI7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5mYWRlRWZmZWN0O1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0ICRzbGlkZUVsID0gc3dpcGVyLnNsaWRlcy5lcShpKTtcbiAgICAgIGNvbnN0IG9mZnNldCA9ICRzbGlkZUVsWzBdLnN3aXBlclNsaWRlT2Zmc2V0O1xuICAgICAgbGV0IHR4ID0gLW9mZnNldDtcbiAgICAgIGlmICghc3dpcGVyLnBhcmFtcy52aXJ0dWFsVHJhbnNsYXRlKSB0eCAtPSBzd2lwZXIudHJhbnNsYXRlO1xuICAgICAgbGV0IHR5ID0gMDtcblxuICAgICAgaWYgKCFzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgdHkgPSB0eDtcbiAgICAgICAgdHggPSAwO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzbGlkZU9wYWNpdHkgPSBzd2lwZXIucGFyYW1zLmZhZGVFZmZlY3QuY3Jvc3NGYWRlID8gTWF0aC5tYXgoMSAtIE1hdGguYWJzKCRzbGlkZUVsWzBdLnByb2dyZXNzKSwgMCkgOiAxICsgTWF0aC5taW4oTWF0aC5tYXgoJHNsaWRlRWxbMF0ucHJvZ3Jlc3MsIC0xKSwgMCk7XG4gICAgICBjb25zdCAkdGFyZ2V0RWwgPSBlZmZlY3RUYXJnZXQocGFyYW1zLCAkc2xpZGVFbCk7XG4gICAgICAkdGFyZ2V0RWwuY3NzKHtcbiAgICAgICAgb3BhY2l0eTogc2xpZGVPcGFjaXR5XG4gICAgICB9KS50cmFuc2Zvcm0oYHRyYW5zbGF0ZTNkKCR7dHh9cHgsICR7dHl9cHgsIDBweClgKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3Qgc2V0VHJhbnNpdGlvbiA9IGR1cmF0aW9uID0+IHtcbiAgICBjb25zdCB7XG4gICAgICB0cmFuc2Zvcm1FbFxuICAgIH0gPSBzd2lwZXIucGFyYW1zLmZhZGVFZmZlY3Q7XG4gICAgY29uc3QgJHRyYW5zaXRpb25FbGVtZW50cyA9IHRyYW5zZm9ybUVsID8gc3dpcGVyLnNsaWRlcy5maW5kKHRyYW5zZm9ybUVsKSA6IHN3aXBlci5zbGlkZXM7XG4gICAgJHRyYW5zaXRpb25FbGVtZW50cy50cmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgICBlZmZlY3RWaXJ0dWFsVHJhbnNpdGlvbkVuZCh7XG4gICAgICBzd2lwZXIsXG4gICAgICBkdXJhdGlvbixcbiAgICAgIHRyYW5zZm9ybUVsLFxuICAgICAgYWxsU2xpZGVzOiB0cnVlXG4gICAgfSk7XG4gIH07XG5cbiAgZWZmZWN0SW5pdCh7XG4gICAgZWZmZWN0OiAnZmFkZScsXG4gICAgc3dpcGVyLFxuICAgIG9uLFxuICAgIHNldFRyYW5zbGF0ZSxcbiAgICBzZXRUcmFuc2l0aW9uLFxuICAgIG92ZXJ3cml0ZVBhcmFtczogKCkgPT4gKHtcbiAgICAgIHNsaWRlc1BlclZpZXc6IDEsXG4gICAgICBzbGlkZXNQZXJHcm91cDogMSxcbiAgICAgIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IHRydWUsXG4gICAgICBzcGFjZUJldHdlZW46IDAsXG4gICAgICB2aXJ0dWFsVHJhbnNsYXRlOiAhc3dpcGVyLnBhcmFtcy5jc3NNb2RlXG4gICAgfSlcbiAgfSk7XG59IiwiaW1wb3J0ICQgZnJvbSAnLi4vLi4vc2hhcmVkL2RvbS5qcyc7XG5pbXBvcnQgZWZmZWN0SW5pdCBmcm9tICcuLi8uLi9zaGFyZWQvZWZmZWN0LWluaXQuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRWZmZWN0Q3ViZSh7XG4gIHN3aXBlcixcbiAgZXh0ZW5kUGFyYW1zLFxuICBvblxufSkge1xuICBleHRlbmRQYXJhbXMoe1xuICAgIGN1YmVFZmZlY3Q6IHtcbiAgICAgIHNsaWRlU2hhZG93czogdHJ1ZSxcbiAgICAgIHNoYWRvdzogdHJ1ZSxcbiAgICAgIHNoYWRvd09mZnNldDogMjAsXG4gICAgICBzaGFkb3dTY2FsZTogMC45NFxuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgY3JlYXRlU2xpZGVTaGFkb3dzID0gKCRzbGlkZUVsLCBwcm9ncmVzcywgaXNIb3Jpem9udGFsKSA9PiB7XG4gICAgbGV0IHNoYWRvd0JlZm9yZSA9IGlzSG9yaXpvbn
1RhbCA/ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LWxlZnQnKSA6ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LXRvcCcpO1xuICAgIGxldCBzaGFkb3dBZnRlciA9IGlzSG9yaXpvbnRhbCA/ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0JykgOiAkc2xpZGVFbC5maW5kKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20nKTtcblxuICAgIGlmIChzaGFkb3dCZWZvcmUubGVuZ3RoID09PSAwKSB7XG4gICAgICBzaGFkb3dCZWZvcmUgPSAkKGA8ZGl2IGNsYXNzPVwic3dpcGVyLXNsaWRlLXNoYWRvdy0ke2lzSG9yaXpvbnRhbCA/ICdsZWZ0JyA6ICd0b3AnfVwiPjwvZGl2PmApO1xuICAgICAgJHNsaWRlRWwuYXBwZW5kKHNoYWRvd0JlZm9yZSk7XG4gICAgfVxuXG4gICAgaWYgKHNoYWRvd0FmdGVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc2hhZG93QWZ0ZXIgPSAkKGA8ZGl2IGNsYXNzPVwic3dpcGVyLXNsaWRlLXNoYWRvdy0ke2lzSG9yaXpvbnRhbCA/ICdyaWdodCcgOiAnYm90dG9tJ31cIj48L2Rpdj5gKTtcbiAgICAgICRzbGlkZUVsLmFwcGVuZChzaGFkb3dBZnRlcik7XG4gICAgfVxuXG4gICAgaWYgKHNoYWRvd0JlZm9yZS5sZW5ndGgpIHNoYWRvd0JlZm9yZVswXS5zdHlsZS5vcGFjaXR5ID0gTWF0aC5tYXgoLXByb2dyZXNzLCAwKTtcbiAgICBpZiAoc2hhZG93QWZ0ZXIubGVuZ3RoKSBzaGFkb3dBZnRlclswXS5zdHlsZS5vcGFjaXR5ID0gTWF0aC5tYXgocHJvZ3Jlc3MsIDApO1xuICB9O1xuXG4gIGNvbnN0IHJlY3JlYXRlU2hhZG93cyA9ICgpID0+IHtcbiAgICAvLyBjcmVhdGUgbmV3IG9uZXNcbiAgICBjb25zdCBpc0hvcml6b250YWwgPSBzd2lwZXIuaXNIb3Jpem9udGFsKCk7XG4gICAgc3dpcGVyLnNsaWRlcy5lYWNoKHNsaWRlRWwgPT4ge1xuICAgICAgY29uc3QgcHJvZ3Jlc3MgPSBNYXRoLm1heChNYXRoLm1pbihzbGlkZUVsLnByb2dyZXNzLCAxKSwgLTEpO1xuICAgICAgY3JlYXRlU2xpZGVTaGFkb3dzKCQoc2xpZGVFbCksIHByb2dyZXNzLCBpc0hvcml6b250YWwpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IHNldFRyYW5zbGF0ZSA9ICgpID0+IHtcbiAgICBjb25zdCB7XG4gICAgICAkZWwsXG4gICAgICAkd3JhcHBlckVsLFxuICAgICAgc2xpZGVzLFxuICAgICAgd2lkdGg6IHN3aXBlcldpZHRoLFxuICAgICAgaGVpZ2h0OiBzd2lwZXJIZWlnaHQsXG4gICAgICBydGxUcmFuc2xhdGU6IHJ0bCxcbiAgICAgIHNpemU6IHN3aXBlclNpemUsXG4gICAgICBicm93c2VyXG4gICAgfSA9IHN3aXBlcjtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLmN1YmVFZmZlY3Q7XG4gICAgY29uc3QgaXNIb3Jpem9udGFsID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpO1xuICAgIGNvbnN0IGlzVmlydHVhbCA9IHN3aXBlci52aXJ0dWFsICYmIHN3aXBlci5wYXJhbXMudmlydHVhbC5lbmFibGVkO1xuICAgIGxldCB3cmFwcGVyUm90YXRlID0gMDtcbiAgICBsZXQgJGN1YmVTaGFkb3dFbDtcblxuICAgIGlmIChwYXJhbXMuc2hhZG93KSB7XG4gICAgICBpZiAoaXNIb3Jpem9udGFsKSB7XG4gICAgICAgICRjdWJlU2hhZG93RWwgPSAkd3JhcHBlckVsLmZpbmQoJy5zd2lwZXItY3ViZS1zaGFkb3cnKTtcblxuICAgICAgICBpZiAoJGN1YmVTaGFkb3dFbC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAkY3ViZVNoYWRvd0VsID0gJCgnPGRpdiBjbGFzcz1cInN3aXBlci1jdWJlLXNoYWRvd1wiPjwvZGl2PicpO1xuICAgICAgICAgICR3cmFwcGVyRWwuYXBwZW5kKCRjdWJlU2hhZG93RWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgJGN1YmVTaGFkb3dFbC5jc3Moe1xuICAgICAgICAgIGhlaWdodDogYCR7c3dpcGVyV2lkdGh9cHhgXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgJGN1YmVTaGFkb3dFbCA9ICRlbC5maW5kKCcuc3dpcGVyLWN1YmUtc2hhZG93Jyk7XG5cbiAgICAgICAgaWYgKCRjdWJlU2hhZG93RWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgJGN1YmVTaGFkb3dFbCA9ICQoJzxkaXYgY2xhc3M9XCJzd2lwZXItY3ViZS1zaGFkb3dcIj48L2Rpdj4nKTtcbiAgICAgICAgICAkZWwuYXBwZW5kKCRjdWJlU2hhZG93RWwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0ICRzbGlkZUVsID0gc2xpZGVzLmVxKGkpO1xuICAgICAgbGV0IHNsaWRlSW5kZXggPSBpO1xuXG4gICAgICBpZiAoaXNWaXJ0dWFsKSB7XG4gICAgICAgIHNsaWRlSW5kZXggPSBwYXJzZUludCgkc2xpZGVFbC5hdHRyKCdkYXRhLXN3aXBlci1zbGlkZS1pbmRleCcpLCAxMCk7XG4gICAgICB9XG5cbiAgICAgIGxldCBzbGlkZUFuZ2xlID0gc2xpZGVJbmRleCAqIDkwO1xuICAgICAgbGV0IHJvdW5kID0gTWF0aC5mbG9vcihzbGlkZUFuZ2xlIC8gMzYwKTtcblxuICAgICAgaWYgKHJ0bCkge1xuICAgICAgICBzbGlkZUFuZ2xlID0gLXNsaWRlQW5nbGU7XG4gICAgICAgIHJvdW5kID0gTWF0aC5mbG9vcigtc2xpZGVBbmdsZSAvIDM2MCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByb2dyZXNzID0gTWF0aC5tYXgoTWF0aC5taW4oJHNsaWRlRWxbMF0ucHJvZ3Jlc3MsIDEpLCAtMSk7XG4gICAgICBsZXQgdHggPSAwO1xuICAgICAgbGV0IHR5ID0gMDtcbiAgICAgIGxldCB0eiA9IDA7XG5cbiAgICAgIGlmIChzbGlkZUluZGV4ICUgNCA9PT0gMCkge1xuICAgICAgICB0eCA9IC1yb3VuZCAqIDQgKiBzd2lwZXJTaXplO1xuICAgICAgICB0eiA9IDA7XG4gICAgICB9IGVsc2UgaWYgKChzbGlkZUluZGV4IC0gMSkgJSA0ID09PSAwKSB7XG4gICAgICAgIHR4ID0gMDtcbiAgICAgICAgdHogPSAtcm91bmQgKiA0ICogc3dpcGVyU2l6ZTtcbiAgICAgIH0gZWxzZSBpZiAoKHNsaWRlSW5kZXggLSAyKSAlIDQgPT09IDApIHtcbiAgICAgICAgdHggPSBzd2lwZXJTaXplICsgcm91bmQgKiA0ICogc3dpcGVyU2l6ZTtcbiAgICAgICAgdHogPSBzd2lwZXJTaXplO1xuICAgICAgfSBlbHNlIGlmICgoc2xpZGVJbmRleCAtIDMpICUgNCA9PT0gMCkge1xuICAgICAgICB0eCA9IC1zd2lwZXJTaXplO1xuICAgICAgICB0eiA9IDMgKiBzd2lwZXJTaXplICsgc3dpcGVyU2l6ZSAqIDQgKiByb3VuZDtcbiAgICAgIH1cblxuICAgICAgaWYgKHJ0bCkge1xuICAgICAgICB0eCA9IC10eDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc0hvcml6b250YWwpIHtcbiAgICAgICAgdHkgPSB0eDtcbiAgICAgICAgdHggPSAwO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0cmFuc2Zvcm0gPSBgcm90YXRlWCgke2lzSG9yaXpvbn
1RhbCA/IDAgOiAtc2xpZGVBbmdsZX1kZWcpIHJvdGF0ZVkoJHtpc0hvcml6b250YWwgPyBzbGlkZUFuZ2xlIDogMH1kZWcpIHRyYW5zbGF0ZTNkKCR7dHh9cHgsICR7dHl9cHgsICR7dHp9cHgpYDtcblxuICAgICAgaWYgKHByb2dyZXNzIDw9IDEgJiYgcHJvZ3Jlc3MgPiAtMSkge1xuICAgICAgICB3cmFwcGVyUm90YXRlID0gc2xpZGVJbmRleCAqIDkwICsgcHJvZ3Jlc3MgKiA5MDtcbiAgICAgICAgaWYgKHJ0bCkgd3JhcHBlclJvdGF0ZSA9IC1zbGlkZUluZGV4ICogOTAgLSBwcm9ncmVzcyAqIDkwO1xuICAgICAgfVxuXG4gICAgICAkc2xpZGVFbC50cmFuc2Zvcm0odHJhbnNmb3JtKTtcblxuICAgICAgaWYgKHBhcmFtcy5zbGlkZVNoYWRvd3MpIHtcbiAgICAgICAgY3JlYXRlU2xpZGVTaGFkb3dzKCRzbGlkZUVsLCBwcm9ncmVzcywgaXNIb3Jpem9udGFsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAkd3JhcHBlckVsLmNzcyh7XG4gICAgICAnLXdlYmtpdC10cmFuc2Zvcm0tb3JpZ2luJzogYDUwJSA1MCUgLSR7c3dpcGVyU2l6ZSAvIDJ9cHhgLFxuICAgICAgJ3RyYW5zZm9ybS1vcmlnaW4nOiBgNTAlIDUwJSAtJHtzd2lwZXJTaXplIC8gMn1weGBcbiAgICB9KTtcblxuICAgIGlmIChwYXJhbXMuc2hhZG93KSB7XG4gICAgICBpZiAoaXNIb3Jpem9udGFsKSB7XG4gICAgICAgICRjdWJlU2hhZG93RWwudHJhbnNmb3JtKGB0cmFuc2xhdGUzZCgwcHgsICR7c3dpcGVyV2lkdGggLyAyICsgcGFyYW1zLnNoYWRvd09mZnNldH1weCwgJHstc3dpcGVyV2lkdGggLyAyfXB4KSByb3RhdGVYKDkwZGVnKSByb3RhdGVaKDBkZWcpIHNjYWxlKCR7cGFyYW1zLnNoYWRvd1NjYWxlfSlgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHNoYWRvd0FuZ2xlID0gTWF0aC5hYnMod3JhcHBlclJvdGF0ZSkgLSBNYXRoLmZsb29yKE1hdGguYWJzKHdyYXBwZXJSb3RhdGUpIC8gOTApICogOTA7XG4gICAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSAxLjUgLSAoTWF0aC5zaW4oc2hhZG93QW5nbGUgKiAyICogTWF0aC5QSSAvIDM2MCkgLyAyICsgTWF0aC5jb3Moc2hhZG93QW5nbGUgKiAyICogTWF0aC5QSSAvIDM2MCkgLyAyKTtcbiAgICAgICAgY29uc3Qgc2NhbGUxID0gcGFyYW1zLnNoYWRvd1NjYWxlO1xuICAgICAgICBjb25zdCBzY2FsZTIgPSBwYXJhbXMuc2hhZG93U2NhbGUgLyBtdWx0aXBsaWVyO1xuICAgICAgICBjb25zdCBvZmZzZXQgPSBwYXJhbXMuc2hhZG93T2Zmc2V0O1xuICAgICAgICAkY3ViZVNoYWRvd0VsLnRyYW5zZm9ybShgc2NhbGUzZCgke3NjYWxlMX0sIDEsICR7c2NhbGUyfSkgdHJhbnNsYXRlM2QoMHB4LCAke3N3aXBlckhlaWdodCAvIDIgKyBvZmZzZXR9cHgsICR7LXN3aXBlckhlaWdodCAvIDIgLyBzY2FsZTJ9cHgpIHJvdGF0ZVgoLTkwZGVnKWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHpGYWN0b3IgPSBicm93c2VyLmlzU2FmYXJpIHx8IGJyb3dzZXIuaXNXZWJWaWV3ID8gLXN3aXBlclNpemUgLyAyIDogMDtcbiAgICAkd3JhcHBlckVsLnRyYW5zZm9ybShgdHJhbnNsYXRlM2QoMHB4LDAsJHt6RmFjdG9yfXB4KSByb3RhdGVYKCR7c3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gMCA6IHdyYXBwZXJSb3RhdGV9ZGVnKSByb3RhdGVZKCR7c3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gLXdyYXBwZXJSb3RhdGUgOiAwfWRlZylgKTtcbiAgICAkd3JhcHBlckVsWzBdLnN0eWxlLnNldFByb3BlcnR5KCctLXN3aXBlci1jdWJlLXRyYW5zbGF0ZS16JywgYCR7ekZhY3Rvcn1weGApO1xuICB9O1xuXG4gIGNvbnN0IHNldFRyYW5zaXRpb24gPSBkdXJhdGlvbiA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgJGVsLFxuICAgICAgc2xpZGVzXG4gICAgfSA9IHN3aXBlcjtcbiAgICBzbGlkZXMudHJhbnNpdGlvbihkdXJhdGlvbikuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1yaWdodCwgLnN3aXBlci1zbGlkZS1zaGFkb3ctYm90dG9tLCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1sZWZ0JykudHJhbnNpdGlvbihkdXJhdGlvbik7XG5cbiAgICBpZiAoc3dpcGVyLnBhcmFtcy5jdWJlRWZmZWN0LnNoYWRvdyAmJiAhc3dpcGVyLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAkZWwuZmluZCgnLnN3aXBlci1jdWJlLXNoYWRvdycpLnRyYW5zaXRpb24oZHVyYXRpb24pO1xuICAgIH1cbiAgfTtcblxuICBlZmZlY3RJbml0KHtcbiAgICBlZmZlY3Q6ICdjdWJlJyxcbiAgICBzd2lwZXIsXG4gICAgb24sXG4gICAgc2V0VHJhbnNsYXRlLFxuICAgIHNldFRyYW5zaXRpb24sXG4gICAgcmVjcmVhdGVTaGFkb3dzLFxuICAgIGdldEVmZmVjdFBhcmFtczogKCkgPT4gc3dpcGVyLnBhcmFtcy5jdWJlRWZmZWN0LFxuICAgIHBlcnNwZWN0aXZlOiAoKSA9PiB0cnVlLFxuICAgIG92ZXJ3cml0ZVBhcmFtczogKCkgPT4gKHtcbiAgICAgIHNsaWRlc1BlclZpZXc6IDEsXG4gICAgICBzbGlkZXNQZXJHcm91cDogMSxcbiAgICAgIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IHRydWUsXG4gICAgICByZXNpc3RhbmNlUmF0aW86IDAsXG4gICAgICBzcGFjZUJldHdlZW46IDAsXG4gICAgICBjZW50ZXJlZFNsaWRlczogZmFsc2UsXG4gICAgICB2aXJ0dWFsVHJhbnNsYXRlOiB0cnVlXG4gICAgfSlcbiAgfSk7XG59IiwiaW1wb3J0ICQgZnJvbSAnLi9kb20uanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY3JlYXRlU2hhZG93KHBhcmFtcywgJHNsaWRlRWwsIHNpZGUpIHtcbiAgY29uc3Qgc2hhZG93Q2xhc3MgPSBgc3dpcGVyLXNsaWRlLXNoYWRvdyR7c2lkZSA/IGAtJHtzaWRlfWAgOiAnJ31gO1xuICBjb25zdCAkc2hhZG93Q29udGFpbmVyID0gcGFyYW1zLnRyYW5zZm9ybUVsID8gJHNsaWRlRWwuZmluZChwYXJhbXMudHJhbnNmb3JtRWwpIDogJHNsaWRlRWw7XG4gIGxldCAkc2hhZG93RWwgPSAkc2hhZG93Q29udGFpbmVyLmNoaWxkcmVuKGAuJHtzaGFkb3dDbGFzc31gKTtcblxuICBpZiAoISRzaGFkb3dFbC5sZW5ndGgpIHtcbiAgICAkc2hhZG93RWwgPSAkKGA8ZGl2IGNsYXNzPVwic3dpcGVyLXNsaWRlLXNoYWRvdyR7c2lkZSA/IGAtJHtzaWRlfWAgOiAnJ31cIj48L2Rpdj5gKTtcbiAgICAkc2hhZG93Q29udGFpbmVyLmFwcGVuZCgkc2hhZG93RWwpO1xuICB9XG5cbiAgcmV0dXJuICRzaGFkb3dFbDtcbn0iLCJpbXBvcnQgJCBmcm9tICcuLi8uLi9zaGFyZWQvZG9tLmpzJztcbmltcG9ydCBjcmVhdGVTaGFkb3cgZnJvbSAnLi4vLi4vc2hhcmVkL2NyZWF0ZS1zaGFkb3cuanMnO1xuaW1wb3J0IGVmZmVjdEluaXQgZnJvbSAnLi4vLi4vc2hhcmVkL2VmZmVjdC1pbml0LmpzJztcbmltcG9ydCBlZmZlY3RUYXJnZXQgZnJvbSAnLi4vLi4vc2hhcmVkL2VmZmVjdC10YXJnZXQuanMnO1xuaW1wb3J0IGVmZmVjdFZpcnR1YWxUcmFuc2l0aW9uRW5kIGZyb20gJy4uLy4uL3NoYXJlZC9lZmZlY3QtdmlydHVhbC10cmFuc2l0aW9uLWVuZC5qcyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBFZmZlY3RGbGlwKHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uXG59KSB7XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAgZmxpcEVmZmVjdDoge1xuICAgICAgc2xpZGVTaGFkb3dzOiB0cnVlLFxuICAgICAgbGltaXRSb3RhdGlvbjogdHJ1ZSxcbiAgICAgIHRyYW5zZm9ybUVsOiBudWxsXG4gICAgfVxuICB9KTtcblxuICBjb25zdCBjcmVhdGVTbGlkZVNoYWRvd3MgPSAoJHNsaWRlRWwsIHByb2dyZXNzLCBwYXJhbXMpID0+IHtcbiAgICBsZXQgc2hhZG93QmVmb3JlID0gc3dpcGVyLmlzSG9yaXpvbn
1RhbCgpID8gJHNsaWRlRWwuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctbGVmdCcpIDogJHNsaWRlRWwuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wJyk7XG4gICAgbGV0IHNoYWRvd0FmdGVyID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJHNsaWRlRWwuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctcmlnaHQnKSA6ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LWJvdHRvbScpO1xuXG4gICAgaWYgKHNoYWRvd0JlZm9yZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHNoYWRvd0JlZm9yZSA9IGNyZWF0ZVNoYWRvdyhwYXJhbXMsICRzbGlkZUVsLCBzd2lwZXIuaXNIb3Jpem9udGFsKCkgPyAnbGVmdCcgOiAndG9wJyk7XG4gICAgfVxuXG4gICAgaWYgKHNoYWRvd0FmdGVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgc2hhZG93QWZ0ZXIgPSBjcmVhdGVTaGFkb3cocGFyYW1zLCAkc2xpZGVFbCwgc3dpcGVyLmlzSG9yaXpvbnRhbCgpID8gJ3JpZ2h0JyA6ICdib3R0b20nKTtcbiAgICB9XG5cbiAgICBpZiAoc2hhZG93QmVmb3JlLmxlbmd0aCkgc2hhZG93QmVmb3JlWzBdLnN0eWxlLm9wYWNpdHkgPSBNYXRoLm1heCgtcHJvZ3Jlc3MsIDApO1xuICAgIGlmIChzaGFkb3dBZnRlci5sZW5ndGgpIHNoYWRvd0FmdGVyWzBdLnN0eWxlLm9wYWNpdHkgPSBNYXRoLm1heChwcm9ncmVzcywgMCk7XG4gIH07XG5cbiAgY29uc3QgcmVjcmVhdGVTaGFkb3dzID0gKCkgPT4ge1xuICAgIC8vIFNldCBzaGFkb3dzXG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5mbGlwRWZmZWN0O1xuICAgIHN3aXBlci5zbGlkZXMuZWFjaChzbGlkZUVsID0+IHtcbiAgICAgIGNvbnN0ICRzbGlkZUVsID0gJChzbGlkZUVsKTtcbiAgICAgIGxldCBwcm9ncmVzcyA9ICRzbGlkZUVsWzBdLnByb2dyZXNzO1xuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5mbGlwRWZmZWN0LmxpbWl0Um90YXRpb24pIHtcbiAgICAgICAgcHJvZ3Jlc3MgPSBNYXRoLm1heChNYXRoLm1pbihzbGlkZUVsLnByb2dyZXNzLCAxKSwgLTEpO1xuICAgICAgfVxuXG4gICAgICBjcmVhdGVTbGlkZVNoYWRvd3MoJHNsaWRlRWwsIHByb2dyZXNzLCBwYXJhbXMpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IHNldFRyYW5zbGF0ZSA9ICgpID0+IHtcbiAgICBjb25zdCB7XG4gICAgICBzbGlkZXMsXG4gICAgICBydGxUcmFuc2xhdGU6IHJ0bFxuICAgIH0gPSBzd2lwZXI7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5mbGlwRWZmZWN0O1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGlkZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0ICRzbGlkZUVsID0gc2xpZGVzLmVxKGkpO1xuICAgICAgbGV0IHByb2dyZXNzID0gJHNsaWRlRWxbMF0ucHJvZ3Jlc3M7XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmZsaXBFZmZlY3QubGltaXRSb3RhdGlvbikge1xuICAgICAgICBwcm9ncmVzcyA9IE1hdGgubWF4KE1hdGgubWluKCRzbGlkZUVsWzBdLnByb2dyZXNzLCAxKSwgLTEpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvZmZzZXQgPSAkc2xpZGVFbFswXS5zd2lwZXJTbGlkZU9mZnNldDtcbiAgICAgIGNvbnN0IHJvdGF0ZSA9IC0xODAgKiBwcm9ncmVzcztcbiAgICAgIGxldCByb3RhdGVZID0gcm90YXRlO1xuICAgICAgbGV0IHJvdGF0ZVggPSAwO1xuICAgICAgbGV0IHR4ID0gc3dpcGVyLnBhcmFtcy5jc3NNb2RlID8gLW9mZnNldCAtIHN3aXBlci50cmFuc2xhdGUgOiAtb2Zmc2V0O1xuICAgICAgbGV0IHR5ID0gMDtcblxuICAgICAgaWYgKCFzd2lwZXIuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgICAgdHkgPSB0eDtcbiAgICAgICAgdHggPSAwO1xuICAgICAgICByb3RhdGVYID0gLXJvdGF0ZVk7XG4gICAgICAgIHJvdGF0ZVkgPSAwO1xuICAgICAgfSBlbHNlIGlmIChydGwpIHtcbiAgICAgICAgcm90YXRlWSA9IC1yb3RhdGVZO1xuICAgICAgfVxuXG4gICAgICAkc2xpZGVFbFswXS5zdHlsZS56SW5kZXggPSAtTWF0aC5hYnMoTWF0aC5yb3VuZChwcm9ncmVzcykpICsgc2xpZGVzLmxlbmd0aDtcblxuICAgICAgaWYgKHBhcmFtcy5zbGlkZVNoYWRvd3MpIHtcbiAgICAgICAgY3JlYXRlU2xpZGVTaGFkb3dzKCRzbGlkZUVsLCBwcm9ncmVzcywgcGFyYW1zKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7dHh9cHgsICR7dHl9cHgsIDBweCkgcm90YXRlWCgke3JvdGF0ZVh9ZGVnKSByb3RhdGVZKCR7cm90YXRlWX1kZWcpYDtcbiAgICAgIGNvbnN0ICR0YXJnZXRFbCA9IGVmZmVjdFRhcmdldChwYXJhbXMsICRzbGlkZUVsKTtcbiAgICAgICR0YXJnZXRFbC50cmFuc2Zvcm0odHJhbnNmb3JtKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3Qgc2V0VHJhbnNpdGlvbiA9IGR1cmF0aW9uID0+IHtcbiAgICBjb25zdCB7XG4gICAgICB0cmFuc2Zvcm1FbFxuICAgIH0gPSBzd2lwZXIucGFyYW1zLmZsaXBFZmZlY3Q7XG4gICAgY29uc3QgJHRyYW5zaXRpb25FbGVtZW50cyA9IHRyYW5zZm9ybUVsID8gc3dpcGVyLnNsaWRlcy5maW5kKHRyYW5zZm9ybUVsKSA6IHN3aXBlci5zbGlkZXM7XG4gICAgJHRyYW5zaXRpb25FbGVtZW50cy50cmFuc2l0aW9uKGR1cmF0aW9uKS5maW5kKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy10b3AsIC5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0LCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20sIC5zd2lwZXItc2xpZGUtc2hhZG93LWxlZnQnKS50cmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgICBlZmZlY3RWaXJ0dWFsVHJhbnNpdGlvbkVuZCh7XG4gICAgICBzd2lwZXIsXG4gICAgICBkdXJhdGlvbixcbiAgICAgIHRyYW5zZm9ybUVsXG4gICAgfSk7XG4gIH07XG5cbiAgZWZmZWN0SW5pdCh7XG4gICAgZWZmZWN0OiAnZmxpcCcsXG4gICAgc3dpcGVyLFxuICAgIG9uLFxuICAgIHNldFRyYW5zbGF0ZSxcbiAgICBzZXRUcmFuc2l0aW9uLFxuICAgIHJlY3JlYXRlU2hhZG93cyxcbiAgICBnZXRFZmZlY3RQYXJhbXM6ICgpID0+IHN3aXBlci5wYXJhbXMuZmxpcEVmZmVjdCxcbiAgICBwZXJzcGVjdGl2ZTogKCkgPT4gdHJ1ZSxcbiAgICBvdmVyd3JpdGVQYXJhbXM6ICgpID0+ICh7XG4gICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgc2xpZGVzUGVyR3JvdXA6IDEsXG4gICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlLFxuICAgICAgc3B
1hY2VCZXR3ZWVuOiAwLFxuICAgICAgdmlydHVhbFRyYW5zbGF0ZTogIXN3aXBlci5wYXJhbXMuY3NzTW9kZVxuICAgIH0pXG4gIH0pO1xufSIsImltcG9ydCBjcmVhdGVTaGFkb3cgZnJvbSAnLi4vLi4vc2hhcmVkL2NyZWF0ZS1zaGFkb3cuanMnO1xuaW1wb3J0IGVmZmVjdEluaXQgZnJvbSAnLi4vLi4vc2hhcmVkL2VmZmVjdC1pbml0LmpzJztcbmltcG9ydCBlZmZlY3RUYXJnZXQgZnJvbSAnLi4vLi4vc2hhcmVkL2VmZmVjdC10YXJnZXQuanMnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRWZmZWN0Q292ZXJmbG93KHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uXG59KSB7XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAgY292ZXJmbG93RWZmZWN0OiB7XG4gICAgICByb3RhdGU6IDUwLFxuICAgICAgc3RyZXRjaDogMCxcbiAgICAgIGRlcHRoOiAxMDAsXG4gICAgICBzY2FsZTogMSxcbiAgICAgIG1vZGlmaWVyOiAxLFxuICAgICAgc2xpZGVTaGFkb3dzOiB0cnVlLFxuICAgICAgdHJhbnNmb3JtRWw6IG51bGxcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IHNldFRyYW5zbGF0ZSA9ICgpID0+IHtcbiAgICBjb25zdCB7XG4gICAgICB3aWR0aDogc3dpcGVyV2lkdGgsXG4gICAgICBoZWlnaHQ6IHN3aXBlckhlaWdodCxcbiAgICAgIHNsaWRlcyxcbiAgICAgIHNsaWRlc1NpemVzR3JpZFxuICAgIH0gPSBzd2lwZXI7XG4gICAgY29uc3QgcGFyYW1zID0gc3dpcGVyLnBhcmFtcy5jb3ZlcmZsb3dFZmZlY3Q7XG4gICAgY29uc3QgaXNIb3Jpem9udGFsID0gc3dpcGVyLmlzSG9yaXpvbnRhbCgpO1xuICAgIGNvbnN0IHRyYW5zZm9ybSA9IHN3aXBlci50cmFuc2xhdGU7XG4gICAgY29uc3QgY2VudGVyID0gaXNIb3Jpem9udGFsID8gLXRyYW5zZm9ybSArIHN3aXBlcldpZHRoIC8gMiA6IC10cmFuc2Zvcm0gKyBzd2lwZXJIZWlnaHQgLyAyO1xuICAgIGNvbnN0IHJvdGF0ZSA9IGlzSG9yaXpvbnRhbCA/IHBhcmFtcy5yb3RhdGUgOiAtcGFyYW1zLnJvdGF0ZTtcbiAgICBjb25zdCB0cmFuc2xhdGUgPSBwYXJhbXMuZGVwdGg7IC8vIEVhY2ggc2xpZGUgb2Zmc2V0IGZyb20gY2VudGVyXG5cbiAgICBmb3IgKGxldCBpID0gMCwgbGVuZ3RoID0gc2xpZGVzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCAkc2xpZGVFbCA9IHNsaWRlcy5lcShpKTtcbiAgICAgIGNvbnN0IHNsaWRlU2l6ZSA9IHNsaWRlc1NpemVzR3JpZFtpXTtcbiAgICAgIGNvbnN0IHNsaWRlT2Zmc2V0ID0gJHNsaWRlRWxbMF0uc3dpcGVyU2xpZGVPZmZzZXQ7XG4gICAgICBjb25zdCBjZW50ZXJPZmZzZXQgPSAoY2VudGVyIC0gc2xpZGVPZmZzZXQgLSBzbGlkZVNpemUgLyAyKSAvIHNsaWRlU2l6ZTtcbiAgICAgIGNvbnN0IG9mZnNldE11bHRpcGxpZXIgPSB0eXBlb2YgcGFyYW1zLm1vZGlmaWVyID09PSAnZnVuY3Rpb24nID8gcGFyYW1zLm1vZGlmaWVyKGNlbnRlck9mZnNldCkgOiBjZW50ZXJPZmZzZXQgKiBwYXJhbXMubW9kaWZpZXI7XG4gICAgICBsZXQgcm90YXRlWSA9IGlzSG9yaXpvbnRhbCA/IHJvdGF0ZSAqIG9mZnNldE11bHRpcGxpZXIgOiAwO1xuICAgICAgbGV0IHJvdGF0ZVggPSBpc0hvcml6b250YWwgPyAwIDogcm90YXRlICogb2Zmc2V0TXVsdGlwbGllcjsgLy8gdmFyIHJvdGF0ZVogPSAwXG5cbiAgICAgIGxldCB0cmFuc2xhdGVaID0gLXRyYW5zbGF0ZSAqIE1hdGguYWJzKG9mZnNldE11bHRpcGxpZXIpO1xuICAgICAgbGV0IHN0cmV0Y2ggPSBwYXJhbXMuc3RyZXRjaDsgLy8gQWxsb3cgcGVyY2VudGFnZSB0byBtYWtlIGEgcmVsYXRpdmUgc3RyZXRjaCBmb3IgcmVzcG9uc2l2ZSBzbGlkZXJzXG5cbiAgICAgIGlmICh0eXBlb2Ygc3RyZXRjaCA9PT0gJ3N0cmluZycgJiYgc3RyZXRjaC5pbmRleE9mKCclJykgIT09IC0xKSB7XG4gICAgICAgIHN0cmV0Y2ggPSBwYXJzZUZsb2F0KHBhcmFtcy5zdHJldGNoKSAvIDEwMCAqIHNsaWRlU2l6ZTtcbiAgICAgIH1cblxuICAgICAgbGV0IHRyYW5zbGF0ZVkgPSBpc0hvcml6b250YWwgPyAwIDogc3RyZXRjaCAqIG9mZnNldE11bHRpcGxpZXI7XG4gICAgICBsZXQgdHJhbnNsYXRlWCA9IGlzSG9yaXpvbnRhbCA/IHN0cmV0Y2ggKiBvZmZzZXRNdWx0aXBsaWVyIDogMDtcbiAgICAgIGxldCBzY2FsZSA9IDEgLSAoMSAtIHBhcmFtcy5zY2FsZSkgKiBNYXRoLmFicyhvZmZzZXRNdWx0aXBsaWVyKTsgLy8gRml4IGZvciB1bHRyYSBzbWFsbCB2YWx1ZXNcblxuICAgICAgaWYgKE1hdGguYWJzKHRyYW5zbGF0ZVgpIDwgMC4wMDEpIHRyYW5zbGF0ZVggPSAwO1xuICAgICAgaWYgKE1hdGguYWJzKHRyYW5zbGF0ZVkpIDwgMC4wMDEpIHRyYW5zbGF0ZVkgPSAwO1xuICAgICAgaWYgKE1hdGguYWJzKHRyYW5zbGF0ZVopIDwgMC4wMDEpIHRyYW5zbGF0ZVogPSAwO1xuICAgICAgaWYgKE1hdGguYWJzKHJvdGF0ZVkpIDwgMC4wMDEpIHJvdGF0ZVkgPSAwO1xuICAgICAgaWYgKE1hdGguYWJzKHJvdGF0ZVgpIDwgMC4wMDEpIHJvdGF0ZVggPSAwO1xuICAgICAgaWYgKE1hdGguYWJzKHNjYWxlKSA8IDAuMDAxKSBzY2FsZSA9IDA7XG4gICAgICBjb25zdCBzbGlkZVRyYW5zZm9ybSA9IGB0cmFuc2xhdGUzZCgke3RyYW5zbGF0ZVh9cHgsJHt0cmFuc2xhdGVZfXB4LCR7dHJhbnNsYXRlWn1weCkgIHJvdGF0ZVgoJHtyb3RhdGVYfWRlZykgcm90YXRlWSgke3JvdGF0ZVl9ZGVnKSBzY2FsZSgke3NjYWxlfSlgO1xuICAgICAgY29uc3QgJHRhcmdldEVsID0gZWZmZWN0VGFyZ2V0KHBhcmFtcywgJHNsaWRlRWwpO1xuICAgICAgJHRhcmdldEVsLnRyYW5zZm9ybShzbGlkZVRyYW5zZm9ybSk7XG4gICAgICAkc2xpZGVFbFswXS5zdHlsZS56SW5kZXggPSAtTWF0aC5hYnMoTWF0aC5yb3VuZChvZmZzZXRNdWx0aXBsaWVyKSkgKyAxO1xuXG4gICAgICBpZiAocGFyYW1zLnNsaWRlU2hhZG93cykge1xuICAgICAgICAvLyBTZXQgc2hhZG93c1xuICAgICAgICBsZXQgJHNoYWRvd0JlZm9yZUVsID0gaXNIb3Jpem9udGFsID8gJHNsaWRlRWwuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctbGVmdCcpIDogJHNsaWRlRWwuZmluZCgnLnN3aXBlci1zbGlkZS1zaGFkb3ctdG9wJyk7XG4gICAgICAgIGxldCAkc2hhZG93QWZ0ZXJFbCA9IGlzSG9yaXpvbn
1RhbCA/ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0JykgOiAkc2xpZGVFbC5maW5kKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20nKTtcblxuICAgICAgICBpZiAoJHNoYWRvd0JlZm9yZUVsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICRzaGFkb3dCZWZvcmVFbCA9IGNyZWF0ZVNoYWRvdyhwYXJhbXMsICRzbGlkZUVsLCBpc0hvcml6b250YWwgPyAnbGVmdCcgOiAndG9wJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoJHNoYWRvd0FmdGVyRWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgJHNoYWRvd0FmdGVyRWwgPSBjcmVhdGVTaGFkb3cocGFyYW1zLCAkc2xpZGVFbCwgaXNIb3Jpem9udGFsID8gJ3JpZ2h0JyA6ICdib3R0b20nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgkc2hhZG93QmVmb3JlRWwubGVuZ3RoKSAkc2hhZG93QmVmb3JlRWxbMF0uc3R5bGUub3BhY2l0eSA9IG9mZnNldE11bHRpcGxpZXIgPiAwID8gb2Zmc2V0TXVsdGlwbGllciA6IDA7XG4gICAgICAgIGlmICgkc2hhZG93QWZ0ZXJFbC5sZW5ndGgpICRzaGFkb3dBZnRlckVsWzBdLnN0eWxlLm9wYWNpdHkgPSAtb2Zmc2V0TXVsdGlwbGllciA+IDAgPyAtb2Zmc2V0TXVsdGlwbGllciA6IDA7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHNldFRyYW5zaXRpb24gPSBkdXJhdGlvbiA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgdHJhbnNmb3JtRWxcbiAgICB9ID0gc3dpcGVyLnBhcmFtcy5jb3ZlcmZsb3dFZmZlY3Q7XG4gICAgY29uc3QgJHRyYW5zaXRpb25FbGVtZW50cyA9IHRyYW5zZm9ybUVsID8gc3dpcGVyLnNsaWRlcy5maW5kKHRyYW5zZm9ybUVsKSA6IHN3aXBlci5zbGlkZXM7XG4gICAgJHRyYW5zaXRpb25FbGVtZW50cy50cmFuc2l0aW9uKGR1cmF0aW9uKS5maW5kKCcuc3dpcGVyLXNsaWRlLXNoYWRvdy10b3AsIC5zd2lwZXItc2xpZGUtc2hhZG93LXJpZ2h0LCAuc3dpcGVyLXNsaWRlLXNoYWRvdy1ib3R0b20sIC5zd2lwZXItc2xpZGUtc2hhZG93LWxlZnQnKS50cmFuc2l0aW9uKGR1cmF0aW9uKTtcbiAgfTtcblxuICBlZmZlY3RJbml0KHtcbiAgICBlZmZlY3Q6ICdjb3ZlcmZsb3cnLFxuICAgIHN3aXBlcixcbiAgICBvbixcbiAgICBzZXRUcmFuc2xhdGUsXG4gICAgc2V0VHJhbnNpdGlvbixcbiAgICBwZXJzcGVjdGl2ZTogKCkgPT4gdHJ1ZSxcbiAgICBvdmVyd3JpdGVQYXJhbXM6ICgpID0+ICh7XG4gICAgICB3YXRjaFNsaWRlc1Byb2dyZXNzOiB0cnVlXG4gICAgfSlcbiAgfSk7XG59IiwiaW1wb3J0IGNyZWF0ZVNoYWRvdyBmcm9tICcuLi8uLi9zaGFyZWQvY3JlYXRlLXNoYWRvdy5qcyc7XG5pbXBvcnQgZWZmZWN0SW5pdCBmcm9tICcuLi8uLi9zaGFyZWQvZWZmZWN0LWluaXQuanMnO1xuaW1wb3J0IGVmZmVjdFRhcmdldCBmcm9tICcuLi8uLi9zaGFyZWQvZWZmZWN0LXRhcmdldC5qcyc7XG5pbXBvcnQgZWZmZWN0VmlydHVhbFRyYW5zaXRpb25FbmQgZnJvbSAnLi4vLi4vc2hhcmVkL2VmZmVjdC12aXJ0dWFsLXRyYW5zaXRpb24tZW5kLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEVmZmVjdENyZWF0aXZlKHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uXG59KSB7XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAgY3JlYXRpdmVFZmZlY3Q6IHtcbiAgICAgIHRyYW5zZm9ybUVsOiBudWxsLFxuICAgICAgbGltaXRQcm9ncmVzczogMSxcbiAgICAgIHNoYWRvd1BlclByb2dyZXNzOiBmYWxzZSxcbiAgICAgIHByb2dyZXNzTXVsdGlwbGllcjogMSxcbiAgICAgIHBlcnNwZWN0aXZlOiB0cnVlLFxuICAgICAgcHJldjoge1xuICAgICAgICB0cmFuc2xhdGU6IFswLCAwLCAwXSxcbiAgICAgICAgcm90YXRlOiBbMCwgMCwgMF0sXG4gICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgIHNjYWxlOiAxXG4gICAgICB9LFxuICAgICAgbmV4dDoge1xuICAgICAgICB0cmFuc2xhdGU6IFswLCAwLCAwXSxcbiAgICAgICAgcm90YXRlOiBbMCwgMCwgMF0sXG4gICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgIHNjYWxlOiAxXG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBnZXRUcmFuc2xhdGVWYWx1ZSA9IHZhbHVlID0+IHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIHZhbHVlO1xuICAgIHJldHVybiBgJHt2YWx1ZX1weGA7XG4gIH07XG5cbiAgY29uc3Qgc2V0VHJhbnNsYXRlID0gKCkgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgIHNsaWRlcyxcbiAgICAgICR3cmFwcGVyRWwsXG4gICAgICBzbGlkZXNTaXplc0dyaWRcbiAgICB9ID0gc3dpcGVyO1xuICAgIGNvbnN0IHBhcmFtcyA9IHN3aXBlci5wYXJhbXMuY3JlYXRpdmVFZmZlY3Q7XG4gICAgY29uc3Qge1xuICAgICAgcHJvZ3Jlc3NNdWx0aXBsaWVyOiBtdWx0aXBsaWVyXG4gICAgfSA9IHBhcmFtcztcbiAgICBjb25zdCBpc0NlbnRlcmVkU2xpZGVzID0gc3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcztcblxuICAgIGlmIChpc0NlbnRlcmVkU2xpZGVzKSB7XG4gICAgICBjb25zdCBtYXJnaW4gPSBzbGlkZXNTaXplc0dyaWRbMF0gLyAyIC0gc3dpcGVyLnBhcmFtcy5zbGlkZXNPZmZzZXRCZWZvcmUgfHwgMDtcbiAgICAgICR3cmFwcGVyRWwudHJhbnNmb3JtKGB0cmFuc2xhdGVYKGNhbGMoNTAlIC0gJHttYXJnaW59cHgpKWApO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCAkc2xpZGVFbCA9IHNsaWRlcy5lcShpKTtcbiAgICAgIGNvbnN0IHNsaWRlUHJvZ3Jlc3MgPSAkc2xpZGVFbFswXS5wcm9ncmVzcztcbiAgICAgIGNvbnN0IHByb2dyZXNzID0gTWF0aC5taW4oTWF0aC5tYXgoJHNsaWRlRWxbMF0ucHJvZ3Jlc3MsIC1wYXJhbXMubGltaXRQcm9ncmVzcyksIHBhcmFtcy5saW1pdFByb2dyZXNzKTtcbiAgICAgIGxldCBvcmlnaW5hbFByb2dyZXNzID0gcHJvZ3Jlc3M7XG5cbiAgICAgIGlmICghaXNDZW50ZXJlZFNsaWRlcykge1xuICAgICAgICBvcmlnaW5hbFByb2dyZXNzID0gTWF0aC5taW4oTWF0aC5tYXgoJHNsaWRlRWxbMF0ub3JpZ2luYWxQcm9ncmVzcywgLXBhcmFtcy5saW1pdFByb2dyZXNzKSwgcGFyYW1zLmxpbWl0UHJvZ3Jlc3MpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvZmZzZXQgPSAkc2xpZGVFbFswXS5zd2lwZXJTbGlkZU9mZnNldDtcbiAgICAgIGNvbnN0IHQgPSBbc3dpcGVyLnBhcmFtcy5jc3NNb2RlID8gLW9mZnNldCAtIHN3aXBlci50cmFuc2xhdGUgOiAtb2Zmc2V0LCAwLCAwXTtcbiAgICAgIGNvbnN0IHIgPSBbMCwgMCwgMF07XG4gICAgICBsZXQgY3VzdG9tID0gZmFsc2U7XG5cbiAgICAgIGlmICghc3dpcGVyLmlzSG9yaXpvbn
1RhbCgpKSB7XG4gICAgICAgIHRbMV0gPSB0WzBdO1xuICAgICAgICB0WzBdID0gMDtcbiAgICAgIH1cblxuICAgICAgbGV0IGRhdGEgPSB7XG4gICAgICAgIHRyYW5zbGF0ZTogWzAsIDAsIDBdLFxuICAgICAgICByb3RhdGU6IFswLCAwLCAwXSxcbiAgICAgICAgc2NhbGU6IDEsXG4gICAgICAgIG9wYWNpdHk6IDFcbiAgICAgIH07XG5cbiAgICAgIGlmIChwcm9ncmVzcyA8IDApIHtcbiAgICAgICAgZGF0YSA9IHBhcmFtcy5uZXh0O1xuICAgICAgICBjdXN0b20gPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChwcm9ncmVzcyA+IDApIHtcbiAgICAgICAgZGF0YSA9IHBhcmFtcy5wcmV2O1xuICAgICAgICBjdXN0b20gPSB0cnVlO1xuICAgICAgfSAvLyBzZXQgdHJhbnNsYXRlXG5cblxuICAgICAgdC5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgdFtpbmRleF0gPSBgY2FsYygke3ZhbHVlfXB4ICsgKCR7Z2V0VHJhbnNsYXRlVmFsdWUoZGF0YS50cmFuc2xhdGVbaW5kZXhdKX0gKiAke01hdGguYWJzKHByb2dyZXNzICogbXVsdGlwbGllcil9KSlgO1xuICAgICAgfSk7IC8vIHNldCByb3RhdGVzXG5cbiAgICAgIHIuZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiB7XG4gICAgICAgIHJbaW5kZXhdID0gZGF0YS5yb3RhdGVbaW5kZXhdICogTWF0aC5hYnMocHJvZ3Jlc3MgKiBtdWx0aXBsaWVyKTtcbiAgICAgIH0pO1xuICAgICAgJHNsaWRlRWxbMF0uc3R5bGUuekluZGV4ID0gLU1hdGguYWJzKE1hdGgucm91bmQoc2xpZGVQcm9ncmVzcykpICsgc2xpZGVzLmxlbmd0aDtcbiAgICAgIGNvbnN0IHRyYW5zbGF0ZVN0cmluZyA9IHQuam9pbignLCAnKTtcbiAgICAgIGNvbnN0IHJvdGF0ZVN0cmluZyA9IGByb3RhdGVYKCR7clswXX1kZWcpIHJvdGF0ZVkoJHtyWzFdfWRlZykgcm90YXRlWigke3JbMl19ZGVnKWA7XG4gICAgICBjb25zdCBzY2FsZVN0cmluZyA9IG9yaWdpbmFsUHJvZ3Jlc3MgPCAwID8gYHNjYWxlKCR7MSArICgxIC0gZGF0YS5zY2FsZSkgKiBvcmlnaW5hbFByb2dyZXNzICogbXVsdGlwbGllcn0pYCA6IGBzY2FsZSgkezEgLSAoMSAtIGRhdGEuc2NhbGUpICogb3JpZ2luYWxQcm9ncmVzcyAqIG11bHRpcGxpZXJ9KWA7XG4gICAgICBjb25zdCBvcGFjaXR5U3RyaW5nID0gb3JpZ2luYWxQcm9ncmVzcyA8IDAgPyAxICsgKDEgLSBkYXRhLm9wYWNpdHkpICogb3JpZ2luYWxQcm9ncmVzcyAqIG11bHRpcGxpZXIgOiAxIC0gKDEgLSBkYXRhLm9wYWNpdHkpICogb3JpZ2luYWxQcm9ncmVzcyAqIG11bHRpcGxpZXI7XG4gICAgICBjb25zdCB0cmFuc2Zvcm0gPSBgdHJhbnNsYXRlM2QoJHt0cmFuc2xhdGVTdHJpbmd9KSAke3JvdGF0ZVN0cmluZ30gJHtzY2FsZVN0cmluZ31gOyAvLyBTZXQgc2hhZG93c1xuXG4gICAgICBpZiAoY3VzdG9tICYmIGRhdGEuc2hhZG93IHx8ICFjdXN0b20pIHtcbiAgICAgICAgbGV0ICRzaGFkb3dFbCA9ICRzbGlkZUVsLmNoaWxkcmVuKCcuc3dpcGVyLXNsaWRlLXNoYWRvdycpO1xuXG4gICAgICAgIGlmICgkc2hhZG93RWwubGVuZ3RoID09PSAwICYmIGRhdGEuc2hhZG93KSB7XG4gICAgICAgICAgJHNoYWRvd0VsID0gY3JlYXRlU2hhZG93KHBhcmFtcywgJHNsaWRlRWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCRzaGFkb3dFbC5sZW5ndGgpIHtcbiAgICAgICAgICBjb25zdCBzaGFkb3dPcGFjaXR5ID0gcGFyYW1zLnNoYWRvd1BlclByb2dyZXNzID8gcHJvZ3Jlc3MgKiAoMSAvIHBhcmFtcy5saW1pdFByb2dyZXNzKSA6IHByb2dyZXNzO1xuICAgICAgICAgICRzaGFkb3dFbFswXS5zdHlsZS5vcGFjaXR5ID0gTWF0aC5taW4oTWF0aC5tYXgoTWF0aC5hYnMoc2hhZG93T3BhY2l0eSksIDApLCAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCAkdGFyZ2V0RWwgPSBlZmZlY3RUYXJnZXQocGFyYW1zLCAkc2xpZGVFbCk7XG4gICAgICAkdGFyZ2V0RWwudHJhbnNmb3JtKHRyYW5zZm9ybSkuY3NzKHtcbiAgICAgICAgb3BhY2l0eTogb3BhY2l0eVN0cmluZ1xuICAgICAgfSk7XG5cbiAgICAgIGlmIChkYXRhLm9yaWdpbikge1xuICAgICAgICAkdGFyZ2V0RWwuY3NzKCd0cmFuc2Zvcm0tb3JpZ2luJywgZGF0YS5vcmlnaW4pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBjb25zdCBzZXRUcmFuc2l0aW9uID0gZHVyYXRpb24gPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgIHRyYW5zZm9ybUVsXG4gICAgfSA9IHN3aXBlci5wYXJhbXMuY3JlYXRpdmVFZmZlY3Q7XG4gICAgY29uc3QgJHRyYW5zaXRpb25FbGVtZW50cyA9IHRyYW5zZm9ybUVsID8gc3dpcGVyLnNsaWRlcy5maW5kKHRyYW5zZm9ybUVsKSA6IHN3aXBlci5zbGlkZXM7XG4gICAgJHRyYW5zaXRpb25FbGVtZW50cy50cmFuc2l0aW9uKGR1cmF0aW9uKS5maW5kKCcuc3dpcGVyLXNsaWRlLXNoYWRvdycpLnRyYW5zaXRpb24oZHVyYXRpb24pO1xuICAgIGVmZmVjdFZpcnR1YWxUcmFuc2l0aW9uRW5kKHtcbiAgICAgIHN3aXBlcixcbiAgICAgIGR1cmF0aW9uLFxuICAgICAgdHJhbnNmb3JtRWwsXG4gICAgICBhbGxTbGlkZXM6IHRydWVcbiAgICB9KTtcbiAgfTtcblxuICBlZmZlY3RJbml0KHtcbiAgICBlZmZlY3Q6ICdjcmVhdGl2ZScsXG4gICAgc3dpcGVyLFxuICAgIG9uLFxuICAgIHNldFRyYW5zbGF0ZSxcbiAgICBzZXRUcmFuc2l0aW9uLFxuICAgIHBlcnNwZWN0aXZlOiAoKSA9PiBzd2lwZXIucGFyYW1zLmNyZWF0aXZlRWZmZWN0LnBlcnNwZWN0aXZlLFxuICAgIG92ZXJ3cml0ZVBhcmFtczogKCkgPT4gKHtcbiAgICAgIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IHRydWUsXG4gICAgICB2aXJ0dWFsVHJhbnNsYXRlOiAhc3dpcGVyLnBhcmFtcy5jc3NNb2RlXG4gICAgfSlcbiAgfSk7XG59IiwiaW1wb3J0IGNyZWF0ZVNoYWRvdyBmcm9tICcuLi8uLi9zaGFyZWQvY3JlYXRlLXNoYWRvdy5qcyc7XG5pbXBvcnQgZWZmZWN0SW5pdCBmcm9tICcuLi8uLi9zaGFyZWQvZWZmZWN0LWluaXQuanMnO1xuaW1wb3J0IGVmZmVjdFRhcmdldCBmcm9tICcuLi8uLi9zaGFyZWQvZWZmZWN0LXRhcmdldC5qcyc7XG5pbXBvcnQgZWZmZWN0VmlydHVhbFRyYW5zaXRpb25FbmQgZnJvbSAnLi4vLi4vc2hhcmVkL2VmZmVjdC12aXJ0dWFsLXRyYW5zaXRpb24tZW5kLmpzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEVmZmVjdENhcmRzKHtcbiAgc3dpcGVyLFxuICBleHRlbmRQYXJhbXMsXG4gIG9uXG59KSB7XG4gIGV4dGVuZFBhcmFtcyh7XG4gICAgY2FyZHNFZmZlY3Q6IHtcbiAgICAgIHNsaWRlU2hhZG93czogdHJ1ZSxcbiAgICAgIHRyYW5zZm9ybUVsOiBudWxsLFxuICAgICAgcm90YXRlOiB0cnVlLFxuICAgICAgcGVyU2xpZGVSb3RhdGU6IDIsXG4gICAgICBwZXJTbGlkZU9mZnNldDogOFxuICAgIH1cbiAgfSk7XG5cbiAgY29uc3Qgc2V0VHJhbnNsYXRlID0gKCkgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgIHNsaWRlcyxcbiAgICAgIGFjdGl2ZUluZGV4XG4gICAgfSA9IHN3aXBlcjtcbiAgICBjb25zdCBwYXJhbXMgPSBzd2lwZXIucGFyYW1zLmNhcmRzRWZmZWN0O1xuICAgIGNvbnN0IHtcbiAgICAgIHN0YXJ0VHJhbnNsYXRlLFxuICAgICAgaXNUb3VjaGVkXG4gICAgfSA9IHN3aXBlci50b3VjaEV2ZW50c0RhdGE7XG4gICAgY29uc3QgY3VycmVudFRyYW5zbGF0ZSA9IHN3aXBlci50cmFuc2xhdGU7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3QgJHNsaWRlRWwgPSBzbGlkZXMuZXEoaSk7XG4gICAgICBjb25zdCBzbGlkZVByb2dyZXNzID0gJHNsaWRlRWxbMF0ucHJvZ3Jlc3M7XG4gICAgICBjb25zdCBwcm9ncmVzcyA9IE1hdGgubWluKE1hdGgubWF4KHNsaWRlUHJvZ3Jlc3MsIC00KSwgNCk7XG4gICAgICBsZXQgb2Zmc2V0ID0gJHNsaWRlRWxbMF0uc3dpcGVyU2xpZGVPZmZzZXQ7XG5cbiAgICAgIGlmIChzd2lwZXIucGFyYW1zLmNlbnRlcmVkU2xpZGVzICYmICFzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgICAgc3dpcGVyLiR3cmFwcGVyRWwudHJhbnNmb3JtKGB0cmFuc2xhdGVYKCR7c3dpcGVyLm1pblRyYW5zbGF0ZSgpfXB4KWApO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3dpcGVyLnBhcmFtcy5jZW50ZXJlZFNsaWRlcyAmJiBzd2lwZXIucGFyYW1zLmNzc01vZGUpIHtcbiAgICAgICAgb2Zmc2V0IC09IHNsaWRlc1swXS5zd2lwZXJTbGlkZU9mZnNldDtcbiAgICAgIH1cblxuICAgICAgbGV0IHRYID0gc3dpcGVyLnBhcmFtcy5jc3NNb2RlID8gLW9mZnNldCAtIHN3aXBlci50cmFuc2xhdGUgOiAtb2Zmc2V0O1xuICAgICAgbGV0IHRZID0gMDtcbiAgICAgIGNvbnN0IHRaID0gLTEwMCAqIE1hdGguYWJzKHByb2dyZXNzKTtcbiAgICAgIGxldCBzY2FsZSA9IDE7XG4gICAgICBsZXQgcm90YXRlID0gLXBhcmFtcy5wZXJTbGlkZVJvdGF0ZSAqIHByb2dyZXNzO1xuICAgICAgbGV0IHRYQWRkID0gcGFyYW1zLnBlclNsaWRlT2Zmc2V0IC0gTWF0aC5hYnMocHJvZ3Jlc3MpICogMC43NTtcbiAgICAgIGNvbnN0IHNsaWRlSW5kZXggPSBzd2lwZXIudmlydHVhbCAmJiBzd2lwZXIucGFyYW1zLnZpcnR1YWwuZW5hYmxlZCA/IHN3aXBlci52aXJ0dWFsLmZyb20gKyBpIDogaTtcbiAgICAgIGNvbnN0IGlzU3dpcGVUb05leHQgPSAoc2xpZGVJbmRleCA9PT0gYWN0aXZlSW5kZXggfHwgc2xpZGVJbmRleCA9PT0gYWN0aXZlSW5kZXggLSAxKSAmJiBwcm9ncmVzcyA+IDAgJiYgcHJvZ3Jlc3MgPCAxICYmIChpc1RvdWNoZWQgfHwgc3dpcGVyLnBhcmFtcy5jc3NNb2RlKSAmJiBjdXJyZW50VHJhbnNsYXRlIDwgc3RhcnRUcmFuc2xhdGU7XG4gICAgICBjb25zdCBpc1N3aXBlVG9QcmV2ID0gKHNsaWRlSW5kZXggPT09IGFjdGl2ZUluZGV4IHx8IHNsaWRlSW5kZXggPT09IGFjdGl2ZUluZGV4ICsgMSkgJiYgcHJvZ3Jlc3MgPCAwICYmIHByb2dyZXNzID4gLTEgJiYgKGlzVG91Y2hlZCB8fCBzd2lwZXIucGFyYW1zLmNzc01vZGUpICYmIGN1cnJlbnRUcmFuc2xhdGUgPiBzdGFydFRyYW5zbGF0ZTtcblxuICAgICAgaWYgKGlzU3dpcGVUb05leHQgfHwgaXNTd2lwZVRvUHJldikge1xuICAgICAgICBjb25zdCBzdWJQcm9ncmVzcyA9ICgxIC0gTWF0aC5hYnMoKE1hdGguYWJzKHByb2dyZXNzKSAtIDAuNSkgLyAwLjUpKSAqKiAwLjU7XG4gICAgICAgI
1HJvdGF0ZSArPSAtMjggKiBwcm9ncmVzcyAqIHN1YlByb2dyZXNzO1xuICAgICAgICBzY2FsZSArPSAtMC41ICogc3ViUHJvZ3Jlc3M7XG4gICAgICAgIHRYQWRkICs9IDk2ICogc3ViUHJvZ3Jlc3M7XG4gICAgICAgIHRZID0gYCR7LTI1ICogc3ViUHJvZ3Jlc3MgKiBNYXRoLmFicyhwcm9ncmVzcyl9JWA7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9ncmVzcyA8IDApIHtcbiAgICAgICAgLy8gbmV4dFxuICAgICAgICB0WCA9IGBjYWxjKCR7dFh9cHggKyAoJHt0WEFkZCAqIE1hdGguYWJzKHByb2dyZXNzKX0lKSlgO1xuICAgICAgfSBlbHNlIGlmIChwcm9ncmVzcyA+IDApIHtcbiAgICAgICAgLy8gcHJldlxuICAgICAgICB0WCA9IGBjYWxjKCR7dFh9cHggKyAoLSR7dFhBZGQgKiBNYXRoLmFicyhwcm9ncmVzcyl9JSkpYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRYID0gYCR7dFh9cHhgO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXN3aXBlci5pc0hvcml6b250YWwoKSkge1xuICAgICAgICBjb25zdCBwcmV2WSA9IHRZO1xuICAgICAgICB0WSA9IHRYO1xuICAgICAgICB0WCA9IHByZXZZO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzY2FsZVN0cmluZyA9IHByb2dyZXNzIDwgMCA/IGAkezEgKyAoMSAtIHNjYWxlKSAqIHByb2dyZXNzfWAgOiBgJHsxIC0gKDEgLSBzY2FsZSkgKiBwcm9ncmVzc31gO1xuICAgICAgY29uc3QgdHJhbnNmb3JtID0gYFxuICAgICAgICB0cmFuc2xhdGUzZCgke3RYfSwgJHt0WX0sICR7dFp9cHgpXG4gICAgICAgIHJvdGF0ZVooJHtwYXJhbXMucm90YXRlID8gcm90YXRlIDogMH1kZWcpXG4gICAgICAgIHNjYWxlKCR7c2NhbGVTdHJpbmd9KVxuICAgICAgYDtcblxuICAgICAgaWYgKHBhcmFtcy5zbGlkZVNoYWRvd3MpIHtcbiAgICAgICAgLy8gU2V0IHNoYWRvd3NcbiAgICAgICAgbGV0ICRzaGFkb3dFbCA9ICRzbGlkZUVsLmZpbmQoJy5zd2lwZXItc2xpZGUtc2hhZG93Jyk7XG5cbiAgICAgICAgaWYgKCRzaGFkb3dFbC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAkc2hhZG93RWwgPSBjcmVhdGVTaGFkb3cocGFyYW1zLCAkc2xpZGVFbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoJHNoYWRvd0VsLmxlbmd0aCkgJHNoYWRvd0VsWzBdLnN0eWxlLm9wYWNpdHkgPSBNYXRoLm1pbihNYXRoLm1heCgoTWF0aC5hYnMocHJvZ3Jlc3MpIC0gMC41KSAvIDAuNSwgMCksIDEpO1xuICAgICAgfVxuXG4gICAgICAkc2xpZGVFbFswXS5zdHlsZS56SW5kZXggPSAtTWF0aC5hYnMoTWF0aC5yb3VuZChzbGlkZVByb2dyZXNzKSkgKyBzbGlkZXMubGVuZ3RoO1xuICAgICAgY29uc3QgJHRhcmdldEVsID0gZWZmZWN0VGFyZ2V0KHBhcmFtcywgJHNsaWRlRWwpO1xuICAgICAgJHRhcmdldEVsLnRyYW5zZm9ybSh0cmFuc2Zvcm0pO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBzZXRUcmFuc2l0aW9uID0gZHVyYXRpb24gPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgIHRyYW5zZm9ybUVsXG4gICAgfSA9IHN3aXBlci5wYXJhbXMuY2FyZHNFZmZlY3Q7XG4gICAgY29uc3QgJHRyYW5zaXRpb25FbGVtZW50cyA9IHRyYW5zZm9ybUVsID8gc3dpcGVyLnNsaWRlcy5maW5kKHRyYW5zZm9ybUVsKSA6IHN3aXBlci5zbGlkZXM7XG4gICAgJHRyYW5zaXRpb25FbGVtZW50cy50cmFuc2l0aW9uKGR1cmF0aW9uKS5maW5kKCcuc3dpcGVyLXNsaWRlLXNoYWRvdycpLnRyYW5zaXRpb24oZHVyYXRpb24pO1xuICAgIGVmZmVjdFZpcnR1YWxUcmFuc2l0aW9uRW5kKHtcbiAgICAgIHN3aXBlcixcbiAgICAgIGR1cmF0aW9uLFxuICAgICAgdHJhbnNmb3JtRWxcbiAgICB9KTtcbiAgfTtcblxuICBlZmZlY3RJbml0KHtcbiAgICBlZmZlY3Q6ICdjYXJkcycsXG4gICAgc3dpcGVyLFxuICAgIG9uLFxuICAgIHNldFRyYW5zbGF0ZSxcbiAgICBzZXRUcmFuc2l0aW9uLFxuICAgIHBlcnNwZWN0aXZlOiAoKSA9PiB0cnVlLFxuICAgIG92ZXJ3cml0ZVBhcmFtczogKCkgPT4gKHtcbiAgICAgIHdhdGNoU2xpZGVzUHJvZ3Jlc3M6IHRydWUsXG4gICAgICB2aXJ0dWFsVHJhbnNsYXRlOiAhc3dpcGVyLnBhcmFtcy5jc3NNb2RlXG4gICAgfSlcbiAgfSk7XG59IiwiLyoqXG4gKiBTd2lwZXIgOC40LjdcbiAqIE1vc3QgbW9kZXJuIG1vYmlsZSB0b3VjaCBzbGlkZXIgYW5kIGZyYW1ld29yayB3aXRoIGhhcmR3YXJlIGFjY2VsZXJhdGVkIHRyYW5zaXRpb25zXG4gKiBodHRwczovL3N3aXBlcmpzLmNvbVxuICpcbiAqIENvcHlyaWdodCAyMDE0LTIwMjMgVmxhZGltaXIgS2hhcmxhbXBpZGlcbiAqXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2VcbiAqXG4gKiBSZWxlYXNlZCBvbjogSmFudWFyeSAzMCwgMjAyM1xuICovXG5cbmltcG9ydCBTd2lwZXIgZnJvbSAnLi9jb3JlL2NvcmUuanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBTd2lwZXIsIGRlZmF1bHQgfSBmcm9tICcuL2NvcmUvY29yZS5qcyc7XG5pbXBvcnQgVmlydHVhbCBmcm9tICcuL21vZHVsZXMvdmlydHVhbC92aXJ0dWFsLmpzJztcbmltcG9ydCBLZXlib2FyZCBmcm9tICcuL21vZHVsZXMva2V5Ym9hcmQva2V5Ym9hcmQuanMnO1xuaW1wb3J0IE1vdXNld2hlZWwgZnJvbSAnLi9tb2R1bGVzL21vdXNld2hlZWwvbW91c2V3aGVlbC5qcyc7XG5pbXBvcnQgTmF2aWdhdGlvbiBmcm9tICcuL21vZHVsZXMvbmF2aWdhdGlvbi9uYXZpZ2F0aW9uLmpzJztcbmltcG9ydCBQYWdpbmF0aW9uIGZyb20gJy4vbW9kdWxlcy9wYWdpbmF0aW9uL3BhZ2luYXRpb24uanMnO1xuaW1wb3J0IFNjcm9sbGJhciBmcm9tICcuL21vZHVsZXMvc2Nyb2xsYmFyL3Njcm9sbGJhci5qcyc7XG5pbXBvcnQgUGFyYWxsYXggZnJvbSAnLi9tb2R1bGVzL3BhcmFsbGF4L3BhcmFsbGF4LmpzJztcbmltcG9ydCBab29tIGZyb20gJy4vbW9kdWxlcy96b29tL3pvb20uanMnO1xuaW1wb3J0IExhenkgZnJvbSAnLi9tb2R1bGVzL2xhenkvbGF6eS5qcyc7XG5pbXBvcnQgQ29udHJvbGxlciBmcm9tICcuL21vZHVsZXMvY29udHJvbGxlci9jb250cm9sbGVyLmpzJztcbmltcG9ydCBBMTF5IGZyb20gJy4vbW9kdWxlcy9hMTF5L2ExMXkuanMnO1xuaW1wb3J0IEhpc3RvcnkgZnJvbSAnLi9tb2R1bGVzL2hpc3RvcnkvaGlzdG9yeS5qcyc7XG5pbXBvcnQgSGFzaE5hdmlnYXRpb24gZnJvbSAnLi9tb2R1bGVzL2hhc2gtbmF2aWdhdGlvbi9oYXNoLW5hdmlnYXRpb24uanMnO1xuaW1wb3J0IEF1dG9wbGF5IGZyb20gJy4vbW9kdWxlcy9hdXRvcGxheS9hdXRvcGxheS5qcyc7XG5pbXBvcnQgVGh1bWJzIGZyb20gJy4vbW9kdWxlcy90aHVtYnMvdGh1bWJzLmpzJztcbmltcG9ydCBGcmVlTW9kZSBmcm9tICcuL21vZHVsZXMvZnJlZS1tb2RlL2ZyZWUtbW9kZS5qcyc7XG5pbXBvcnQgR3JpZCBmcm9tICcuL21vZHVsZXMvZ3JpZC9ncmlkLmpzJztcbmltcG9ydCBNYW5pcHVsYXRpb24gZnJvbSAnLi9tb2R1bGVzL21hbmlwdWxhdGlvbi9tYW5pcHVsYXRpb24uanMnO1xuaW1wb3J0IEVmZmVjdEZhZGUgZnJvbSAnLi9tb2R1bGVzL2VmZmVjdC1mYWRlL2VmZmVjdC1mYWRlLmpzJztcbmltcG9ydCBFZmZlY3RDdWJlIGZyb20gJy4vbW9kdWxlcy9lZmZlY3QtY3ViZS9lZmZlY3QtY3ViZS5qcyc7XG5pbXBvcnQgRWZmZWN0RmxpcCBmcm9tICcuL21vZHVsZXMvZWZmZWN0LWZsaXAvZWZmZWN0LWZsaXAuanMnO1xuaW1wb3J0IEVmZmVjdENvdmVyZmxvdyBmcm9tICcuL21vZHVsZXMvZWZmZWN0LWNvdmVyZmxvdy9lZmZlY3QtY292ZXJmbG93LmpzJztcbmltcG9ydCBFZmZlY3RDcmVhdGl2ZSBmcm9tICcuL21vZHVsZXMvZWZmZWN0LWNyZWF0aXZlL2VmZmVjdC1jcmVhdGl2ZS5qcyc7XG5pbXBvcnQgRWZmZWN0Q2FyZHMgZnJvbSAnLi9tb2R1bGVzL2VmZmVjdC1jYXJkcy9lZmZlY3QtY2FyZHMuanMnO1xuXG4vLyBTd2lwZXIgQ2xhc3NcbmNvbnN0IG1vZHVsZXMgPSBbVmlydHVhbCwgS2V5Ym9hcmQsIE1vdXNld2hlZWwsIE5hdmlnYXRpb24sIFBhZ2luYXRpb24sIFNjcm9sbGJhciwgUGFyYWxsYXgsIFpvb20sIExhenksIENvbnRyb2xsZXIsIEExMXksIEhpc3RvcnksIEhhc2hOYXZpZ2F0aW9uLCBBdXRvcGxheSwgVGh1bWJzLCBGcmVlTW9kZSwgR3JpZCwgTWFuaXB1bGF0aW9uLCBFZmZlY3RGYWRlLCBFZmZlY3RDdWJlLCBFZmZlY3RGbGlwLCBFZmZlY3RDb3ZlcmZsb3csIEVmZmVjdENyZWF0aXZlLCBFZmZlY3RDYXJkc107XG5Td2lwZXIudXNlKG1vZHVsZXMpO1xuIiwiLyohXG4gKiBsaWdodGdhbGxlcnkgfCAyLjcuMiB8IFNlcHRlbWJlciAyMHRoIDIwMjNcbiAqIGh0dHA6Ly93d3cubGlnaHRnYWxsZXJ5anMuY29tL1xuICogQ29weXJpZ2h0IChjKSAyMDIwIFNhY2hpbiBOZXJhdmF0aDtcbiAqIEBsaWNlbnNlIEdQTHYzXG4gKi9cblxuLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuXHJcbnZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn07XHJcblxyXG5mdW5jdGlvbiBfX3NwcmVhZEFycmF
15cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XG5cbi8qKlxyXG4gKiBMaXN0IG9mIGxpZ2h0R2FsbGVyeSBldmVudHNcclxuICogQWxsIGV2ZW50cyBzaG91bGQgYmUgZG9jdW1lbnRlZCBoZXJlXHJcbiAqIEJlbG93IGludGVyZmFjZXMgYXJlIHVzZWQgdG8gYnVpbGQgdGhlIHdlYnNpdGUgZG9jdW1lbnRhdGlvbnNcclxuICogKi9cclxudmFyIGxHRXZlbnRzID0ge1xyXG4gICAgYWZ0ZXJBcHBlbmRTbGlkZTogJ2xnQWZ0ZXJBcHBlbmRTbGlkZScsXHJcbiAgICBpbml0OiAnbGdJbml0JyxcclxuICAgIGhhc1ZpZGVvOiAnbGdIYXNWaWRlbycsXHJcbiAgICBjb250YWluZXJSZXNpemU6ICdsZ0NvbnRhaW5lclJlc2l6ZScsXHJcbiAgICB1cGRhdGVTbGlkZXM6ICdsZ1VwZGF0ZVNsaWRlcycsXHJcbiAgICBhZnRlckFwcGVuZFN1Ykh0bWw6ICdsZ0FmdGVyQXBwZW5kU3ViSHRtbCcsXHJcbiAgICBiZWZvcmVPcGVuOiAnbGdCZWZvcmVPcGVuJyxcclxuICAgIGFmdGVyT3BlbjogJ2xnQWZ0ZXJPcGVuJyxcclxuICAgIHNsaWRlSXRlbUxvYWQ6ICdsZ1NsaWRlSXRlbUxvYWQnLFxyXG4gICAgYmVmb3JlU2xpZGU6ICdsZ0JlZm9yZVNsaWRlJyxcclxuICAgIGFmdGVyU2xpZGU6ICdsZ0FmdGVyU2xpZGUnLFxyXG4gICAgcG9zdGVyQ2xpY2s6ICdsZ1Bvc3RlckNsaWNrJyxcclxuICAgIGRyYWdTdGFydDogJ2xnRHJhZ1N0YXJ0JyxcclxuICAgIGRyYWdNb3ZlOiAnbGdEcmFnTW92ZScsXHJcbiAgICBkcmFnRW5kOiAnbGdEcmFnRW5kJyxcclxuICAgIGJlZm9yZU5leHRTbGlkZTogJ2xnQmVmb3JlTmV4dFNsaWRlJyxcclxuICAgIGJlZm9yZVByZXZTbGlkZTogJ2xnQmVmb3JlUHJldlNsaWRlJyxcclxuICAgIGJlZm9yZUNsb3NlOiAnbGdCZWZvcmVDbG9zZScsXHJcbiAgICBhZnRlckNsb3NlOiAnbGdBZnRlckNsb3NlJyxcclxuICAgIHJvdGF0ZUxlZnQ6ICdsZ1JvdGF0ZUxlZnQnLFxyXG4gICAgcm90YXRlUmlnaHQ6ICdsZ1JvdGF0ZVJpZ2h0JyxcclxuICAgIGZsaXBIb3Jpem9udGFsOiAnbGdGbGlwSG9yaXpvbnRhbCcsXHJcbiAgICBmbGlwVmVydGljYWw6ICdsZ0ZsaXBWZXJ0aWNhbCcsXHJcbiAgICBhdXRvcGxheTogJ2xnQXV0b3BsYXknLFxyXG4gICAgYXV0b3BsYXlTdGFydDogJ2xnQXV0b3BsYXlTdGFydCcsXHJcbiAgICBhdXRvcGxheVN0b3A6ICdsZ0F1dG9wbGF5U3RvcCcsXHJcbn07XG5cbnZhciBsaWdodEdhbGxlcnlDb3JlU2V0dGluZ3MgPSB7XHJcbiAgICBtb2RlOiAnbGctc2xpZGUnLFxyXG4gICAgZWFzaW5nOiAnZWFzZScsXHJcbiAgICBzcGVlZDogNDAwLFxyXG4gICAgbGljZW5zZUtleTogJzAwMDAtMDAwMC0wMDAtMDAwMCcsXHJcbiAgICBoZWlnaHQ6ICcxMDAlJyxcclxuICAgIHdpZHRoOiAnMTAwJScsXHJcbiAgICBhZGRDbGFzczogJycsXHJcbiAgICBzdGFydENsYXNzOiAnbGctc3RhcnQtem9vbScsXHJcbiAgICBiYWNrZHJvcER1cmF0aW9uOiAzMDAsXHJcbiAgICBjb250YWluZXI6ICcnLFxyXG4gICAgc3RhcnRBbmltYXRpb25EdXJhdGlvbjogNDAwLFxyXG4gICAgem9vbUZyb21PcmlnaW46IHRydWUsXHJcbiAgICBoaWRlQmFyc0RlbGF5OiAwLFxyXG4gICAgc2hvd0JhcnNBZnRlcjogMTAwMDAsXHJcbiAgICBzbGlkZURlbGF5OiAwLFxyXG4gICAgc3VwcG9ydExlZ2FjeUJyb3dzZXI6IHRydWUsXHJcbiAgICBhbGxvd01lZGlhT3ZlcmxhcDogZmFsc2UsXHJcbiAgICB2aWRlb01heFNpemU6ICcxMjgwLTcyMCcsXHJcbiAgICBsb2FkWW91VHViZVBvc3RlcjogdHJ1ZSxcclxuICAgIGRlZmF1bHRDYXB0aW9uSGVpZ2h0OiAwLFxyXG4gICAgYXJpYUxhYmVsbGVkYnk6ICcnLFxyXG4gICAgYXJpYURlc2NyaWJlZGJ5OiAnJyxcclxuICAgIHJlc2V0U2Nyb2xsUG9zaXRpb246IHRydWUsXHJcbiAgICBoaWRlU2Nyb2xsYmFyOiBmYWxzZSxcclxuICAgIGNsb3NhYmxlOiB0cnVlLFxyXG4gICAgc3dpcGVUb0Nsb3NlOiB0cnVlLFxyXG4gICAgY2xvc2VPblRhcDogdHJ1ZSxcclxuICAgIHNob3dDbG9zZUljb246IHRydWUsXHJcbiAgICBzaG93TWF4aW1pemVJY29uOiBmYWxzZSxcclxuICAgIGxvb3A6IHRydWUsXHJcbiAgICBlc2NLZXk6IHRydWUsXHJcbiAgICBrZXlQcmVzczogdHJ1ZSxcclxuICAgIHRyYXBGb2N1czogdHJ1ZSxcclxuICAgIGNvbnRyb2xzOiB0cnVlLFxyXG4gICAgc2xpZGVFbmRBbmltYXRpb246IHRydWUsXHJcbiAgICBoaWRlQ29udHJvbE9uRW5kOiBmYWxzZSxcclxuICAgIG1vdXNld2hlZWw6IGZhbHNlLFxyXG4gICAgZ2V0Q2FwdGlvbkZyb21UaXRsZU9yQWx0OiB0cnVlLFxyXG4gICAgYXBwZW5kU3ViSHRtbFRvOiAnLmxnLXN1Yi1odG1sJyxcclxuICAgIHN1Ykh0bWxTZWxlY3RvclJlbGF0aXZlOiBmYWxzZSxcclxuICAgIHByZWxvYWQ6IDIsXHJcbiAgICBudW1iZXJPZlNsaWRlSXRlbXNJbkRvbTogMTAsXHJcbiAgICBzZWxlY3RvcjogJycsXHJcbiAgICBzZWxlY3RXaXRoaW46ICcnLFxyXG4gICAgbmV4dEh0bWw6ICcnLFxyXG4gICAgcHJldkh0bWw6ICcnLFxyXG4gICAgaW5kZXg6IDAsXHJcbiAgICBpZnJhbWVXaWR0aDogJzEwMCUnLFxyXG4gICAgaWZyYW1lSGVpZ2h0OiAnMTAwJScsXHJcbiAgICBpZnJhbWVNYXhXaWR0aDogJzEwMCUnLFxyXG4gICAgaWZyYW1lTWF4SGVpZ2h0OiAnMTAwJScsXHJcbiAgICBkb3dubG9hZDogdHJ1ZSxcclxuICAgIGNvdW50ZXI6IHRydWUsXHJcbiAgICBhcHBlbmRDb3VudGVyVG86ICcubGctdG9vbGJhcicsXHJcbiAgICBzd2lwZVRocmVzaG9sZDogNTAsXHJcbiAgICBlbmFibGVTd2lwZTogdHJ1ZSxcclxuICAgIGVuYWJsZURyYWc6IHRydWUsXHJcbiAgICBkeW5hbWljOi
1BmYWxzZSxcclxuICAgIGR5bmFtaWNFbDogW10sXHJcbiAgICBleHRyYVByb3BzOiBbXSxcclxuICAgIGV4VGh1bWJJbWFnZTogJycsXHJcbiAgICBpc01vYmlsZTogdW5kZWZpbmVkLFxyXG4gICAgbW9iaWxlU2V0dGluZ3M6IHtcclxuICAgICAgICBjb250cm9sczogZmFsc2UsXHJcbiAgICAgICAgc2hvd0Nsb3NlSWNvbjogZmFsc2UsXHJcbiAgICAgICAgZG93bmxvYWQ6IGZhbHNlLFxyXG4gICAgfSxcclxuICAgIHBsdWdpbnM6IFtdLFxyXG4gICAgc3RyaW5nczoge1xyXG4gICAgICAgIGNsb3NlR2FsbGVyeTogJ0Nsb3NlIGdhbGxlcnknLFxyXG4gICAgICAgIHRvZ2dsZU1heGltaXplOiAnVG9nZ2xlIG1heGltaXplJyxcclxuICAgICAgICBwcmV2aW91c1NsaWRlOiAnUHJldmlvdXMgc2xpZGUnLFxyXG4gICAgICAgIG5leHRTbGlkZTogJ05leHQgc2xpZGUnLFxyXG4gICAgICAgIGRvd25sb2FkOiAnRG93bmxvYWQnLFxyXG4gICAgICAgIHBsYXlWaWRlbzogJ1BsYXkgdmlkZW8nLFxyXG4gICAgICAgIG1lZGlhTG9hZGluZ0ZhaWxlZDogJ09vcHMuLi4gRmFpbGVkIHRvIGxvYWQgY29udGVudC4uLicsXHJcbiAgICB9LFxyXG59O1xuXG5mdW5jdGlvbiBpbml0TGdQb2x5ZmlsbHMoKSB7XHJcbiAgICAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93LkN1c3RvbUV2ZW50ID09PSAnZnVuY3Rpb24nKVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgZnVuY3Rpb24gQ3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcykge1xyXG4gICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge1xyXG4gICAgICAgICAgICAgICAgYnViYmxlczogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRldGFpbDogbnVsbCxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdDdXN0b21FdmVudCcpO1xyXG4gICAgICAgICAgICBldnQuaW5pdEN1c3RvbUV2ZW50KGV2ZW50LCBwYXJhbXMuYnViYmxlcywgcGFyYW1zLmNhbmNlbGFibG
1UsIHBhcmFtcy5kZXRhaWwpO1xyXG4gICAgICAgICAgICByZXR1cm4gZXZ0O1xyXG4gICAgICAgIH1cclxuICAgICAgICB3aW5kb3cuQ3VzdG9tRXZlbnQgPSBDdXN0b21FdmVudDtcclxuICAgIH0pKCk7XHJcbiAgICAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICghRWxlbWVudC5wcm90b3R5cGUubWF0Y2hlcykge1xyXG4gICAgICAgICAgICBFbGVtZW50LnByb3RvdHlwZS5tYXRjaGVzID1cclxuICAgICAgICAgICAgICAgIEVsZW1lbnQucHJvdG90eXBlLm1zTWF0Y2hlc1NlbGVjdG9yIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgRWxlbWVudC5wcm90b3R5cGUud2Via2l0TWF0Y2hlc1NlbGVjdG9yO1xyXG4gICAgICAgIH1cclxuICAgIH0pKCk7XHJcbn1cclxudmFyIGxnUXVlcnkgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBsZ1F1ZXJ5KHNlbGVjdG9yKSB7XHJcbiAgICAgICAgdGhpcy5jc3NWZW5kZXJQcmVmaXhlcyA9IFtcclxuICAgICAgICAgICAgJ1RyYW5zaXRpb25EdXJhdGlvbicsXHJcbiAgICAgICAgICAgICdUcmFuc2l0aW9uVGltaW5nRnVuY3Rpb24nLFxyXG4gICAgICAgICAgICAnVHJhbnNmb3JtJyxcclxuICAgICAgICAgICAgJ1RyYW5zaXRpb24nLFxyXG4gICAgICAgIF07XHJcbiAgICAgICAgdGhpcy5zZWxlY3RvciA9IHRoaXMuX2dldFNlbGVjdG9yKHNlbGVjdG9yKTtcclxuICAgICAgICB0aGlzLmZpcnN0RWxlbWVudCA9IHRoaXMuX2dldEZpcnN0RWwoKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuICAgIGxnUXVlcnkuZ2VuZXJhdGVVVUlEID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIGZ1bmN0aW9uIChjKSB7XHJcbiAgICAgICAgICAgIHZhciByID0gKE1hdGgucmFuZG9tKCkgKiAxNikgfCAwLCB2ID0gYyA9PSAneCcgPyByIDogKHIgJiAweDMpIHwgMHg4O1xyXG4gICAgICAgICAgICByZXR1cm4gdi50b1N0cmluZygxNik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUuX2dldFNlbGVjdG9yID0gZnVuY3Rpb24gKHNlbGVjdG9yLCBjb250ZXh0KSB7XHJcbiAgICAgICAgaWYgKGNvbnRleHQgPT09IHZvaWQgMCkgeyBjb250ZXh0ID0gZG9jdW1lbnQ7IH1cclxuICAgICAgICBpZiAodHlwZW9mIHNlbGVjdG9yICE9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICByZXR1cm4gc2VsZWN0b3I7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50O1xyXG4gICAgICAgIHZhciBmbCA9IHNlbGVjdG9yLnN1YnN0cmluZygwLCAxKTtcclxuICAgICAgICBpZiAoZmwgPT09ICcjJykge1xyXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LnF1
1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5fZWFjaCA9IGZ1bmN0aW9uIChmdW5jKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5zZWxlY3Rvci5sZW5ndGggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBbXS5mb3JFYWNoLmNhbGwodGhpcy5zZWxlY3RvciwgZnVuYyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBmdW5jKHRoaXMuc2VsZWN0b3IsIDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5fc2V0Q3NzVmVuZG9yUHJlZml4ID0gZnVuY3Rpb24gKGVsLCBjc3NQcm9wZXJ0eSwgdmFsdWUpIHtcclxuICAgICAgICAvLyBwcmV0dGllci1pZ25vcmVcclxuICAgICAgICB2YXIgcHJvcGVydHkgPSBjc3NQcm9wZXJ0eS5yZXBsYWNlKC8tKFthLXpdKS9naSwgZnVuY3Rpb24gKHMsIGdyb3VwMSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZ3JvdXAxLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKHRoaXMuY3NzVmVuZGVyUHJlZml4ZXMuaW5kZXhPZihwcm9wZXJ0eSkgIT09IC0xKSB7XHJcbiAgICAgICAgICAgIGVsLnN0eWxlW3Byb3BlcnR5LmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgcHJvcGVydHkuc2xpY2UoMSldID0gdmFsdWU7XHJcbiAgICAgICAgICAgIGVsLnN0eWxlWyd3ZWJraXQnICsgcHJvcGVydHldID0gdmFsdWU7XHJcbiAgICAgICAgICAgIGVsLnN0eWxlWydtb3onICsgcHJvcGVydHldID0gdmFsdWU7XHJcbiAgICAgICAgICAgIGVsLnN0eWxlWydtcycgKyBwcm9wZXJ0eV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgZWwuc3R5bGVbJ28nICsgcHJvcGVydHldID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBlbC5zdHlsZVtwcm9wZXJ0eV0gPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUuX2dldEZpcnN0RWwgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0b3IgJiYgdGhpcy5zZWxlY3Rvci5sZW5ndGggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RvclswXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNlbGVjdG9yO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5pc0V2ZW50TWF0Y2hlZCA9IGZ1bmN0aW9uIChldmVudCwgZXZlbnROYW1lKSB7XHJcbiAgICAgICAgdmFyIGV2ZW50TmFtZXNwYWNlID0gZXZlbnROYW1lLnNwbGl0KCcuJyk7XHJcbiAgICAgICAgcmV0dXJuIGV2ZW50XHJcbiAgICAgICAgICAgIC5zcGxpdCgnLicpXHJcbiAgICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGUpIHsgcmV0dXJuIGU7IH0pXHJcbiAgICAgICAgICAgIC5ldmVyeShmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZXZlbnROYW1lc3BhY2UuaW5kZXhPZihlKSAhPT0gLTE7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUuYXR0ciA9IGZ1bmN0aW9uIChhdHRyLCB2YWx1ZSkge1xyXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5maXJzdEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5maXJzdEVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9lYWNoKGZ1bmN0aW9uIChlbCkge1xyXG4gICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoYXR0ciwgdmFsdWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIGxnUXVlcnkucHJvdG90eXBlLmZpbmQgPSBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICByZXR1cm4gJExHKHRoaXMuX2dldFNlbGVjdG9yKHNlbGVjdG9yLCB0aGlzLnNlbGVjdG9yKSk7XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUuZmlyc3QgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0b3IgJiYgdGhpcy5zZWxlY3Rvci5sZW5ndGggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gJExHKHRoaXMuc2VsZWN0b3JbMF0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuICRMRyh0aGlzLnNlbGVjdG9yKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICByZXR1cm4gJExHKHRoaXMuc2VsZWN0b3JbaW5kZXhdKTtcclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5wYXJlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuICRMRyh0aGlzLnNlbGVjdG9yLnBhcmVudEVsZW1lbnQpO1xyXG4gICAgfTtcclxuICAgIGxnUXVlcnkucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Rmlyc3RFbCgpO1xyXG4gICAgfTtcclxuICAgIGxnUXVlcnkucHJvdG90eXBlLnJlbW92ZUF0dHIgPSBmdW5jdGlvbiAoYXR0cmlidXRlcykge1xyXG4gICAgICAgIHZhciBhdHRycyA9IGF0dHJpYnV0ZXMuc3BsaXQoJyAnKTtcclxuICAgICAgICB0aGlzLl9lYWNoKGZ1bmN0aW9uIChlbCkge1xyXG4gICAgICAgICAgICBhdHRycy5mb3JFYWNoKGZ1bmN0aW9uIChhdHRyKSB7IHJldHVybiBlbC5yZW1vdmVBdHRyaWJ1dGUoYXR0cik7IH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIGxnUXVlcnkucHJvdG90eXBlLndyYXAgPSBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmZpcnN0RWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHdyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgICB3cmFwcGVyLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcclxuICAgICAgICB0aGlzLmZpcnN0RWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh3cmFwcGVyLCB0aGlzLmZpcnN0RWxlbWVudCk7XHJcbiAgICAgICAgdGhpcy5maXJzdEVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmZpcnN0RWxlbWVudCk7XHJcbiAgICAgICAgd3JhcHBlci5hcHBlbmRDaGlsZCh0aGlzLmZpcnN0RWxlbWVudCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUuYWRkQ2xhc3MgPSBmdW5jdGlvbiAoY2xhc3NOYW1lcykge1xyXG4gICAgICAgIGlmIChjbGFzc05hbWVzID09PSB2b2lkIDApIHsgY2xhc3NOYW1lcyA9ICcnOyB9XHJcbiAgICAgICAgdGhpcy5fZWFjaChmdW5jdGlvbiAoZWwpIHtcclxuICAgICAgICAgICAgLy8gSUUgZG9lc24ndCBzdXBwb3J0IG11bHRpcGxlIGFyZ3VtZW50c1xyXG4gICAgICAgICAgICBjbGFzc05hbWVzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWwuY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5yZW1vdmVDbGFzcyA9IGZ1bmN0aW9uIChjbGFzc05hbWVzKSB7XHJcbiAgICAgICAgdGhpcy5fZWFjaChmdW5jdGlvbiAoZWwpIHtcclxuICAgICAgICAgICAgLy8gSUUgZG9lc24ndCBzdXBwb3J0IG11bHRpcGxlIGFyZ3VtZW50c1xyXG4gICAgICAgICAgICBjbGFzc05hbWVzLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWwuY2xhc3NMaXN0LnJlbW92ZShjbGFzc05hbWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5oYXNDbGFzcyA9IGZ1bmN0aW9uIChjbGFzc05hbWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZmlyc3RFbGVtZW50KSB7XHJcbiAgICAgICAgICAgI
1HJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZmlyc3RFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpO1xyXG4gICAgfTtcclxuICAgIGxnUXVlcnkucHJvdG90eXBlLmhhc0F0dHJpYnV0ZSA9IGZ1bmN0aW9uIChhdHRyaWJ1dGUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZmlyc3RFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZmlyc3RFbGVtZW50Lmhhc0F0dHJpYnV0ZShhdHRyaWJ1dGUpO1xyXG4gICAgfTtcclxuICAgIGxnUXVlcnkucHJvdG90eXBlLnRvZ2dsZUNsYXNzID0gZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xyXG4gICAgICAgIGlmICghdGhpcy5maXJzdEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmhhc0NsYXNzKGNsYXNzTmFtZSkpIHtcclxuICAgICAgICAgICAgdGhpcy5yZW1vdmVDbGFzcyhjbGFzc05hbWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5hZGRDbGFzcyhjbGFzc05hbWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5jc3MgPSBmdW5jdGlvbiAocHJvcGVydHksIHZhbHVlKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB0aGlzLl9lYWNoKGZ1bmN0aW9uIChlbCkge1xyXG4gICAgICAgICAgICBfdGhpcy5fc2V0Q3NzVmVuZG9yUHJlZml4KGVsLCBwcm9wZXJ0eSwgdmFsdWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8vIE5lZWQgdG8gcGFzcyBzZXBhcmF0ZSBuYW1lc3BhY2VzIGZvciBzZXBhcmF0ZSBlbGVtZW50c1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXZlbnRzLCBsaXN0ZW5lcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBldmVudHMuc3BsaXQoJyAnKS5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobGdRdWVyeS5ldmVudExpc3RlbmVyc1tldmVudF0pKSB7XHJcbiAgICAgICAgICAgICAgICBsZ1F1ZXJ5LmV2ZW50TGlzdGVuZXJzW2V2ZW50XSA9IFtdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGxnUXVlcnkuZXZlbnRMaXN0ZW5lcnNbZXZlbnRdLnB1c2gobGlzdGVuZXIpO1xyXG4gICAgICAgICAgICBfdGhpcy5zZWxlY3Rvci5hZGRFdmVudExpc3RlbmVyKGV2ZW50LnNwbGl0KCcuJylbMF0sIGxpc3RlbmVyKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvLyBAdG9kbyAtIHRlc3QgdGhpc1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIChldmVudCwgbGlzdGVuZXIpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMub24oZXZlbnQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMub2ZmKGV2ZW50KTtcclxuICAgICAgICAgICAgbGlzdGVuZXIoZXZlbnQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIGxnUXVlcnkucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBPYmplY3Qua2V5cyhsZ1F1ZXJ5LmV2ZW50TGlzdGVuZXJzKS5mb3JFYWNoKGZ1bmN0aW9uIChldmVudE5hbWUpIHtcclxuICAgICAgICAgICAgaWYgKF90aGlzLmlzRXZlbnRNYXRjaGVkKGV2ZW50LCBldmVudE5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICBsZ1F1ZXJ5LmV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0uZm9yRWFjaChmdW5jdGlvbiAobGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZWxlY3Rvci5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZS5zcGxpdCgnLicpWzBdLCBsaXN0ZW5lcik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGxnUXVlcnkuZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXSA9IFtdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUudHJpZ2dlciA9IGZ1bmN0aW9uIChldmVudCwgZGV0YWlsKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmZpcnN0RWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGN1c3RvbUV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KGV2ZW50LnNwbGl0KCcuJylbMF0sIHtcclxuICAgICAgICAgICAgZGV0YWlsOiBkZXRhaWwgfHwgbnVsbCxcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmZpcnN0RWxlbWVudC5kaXNwYXRjaEV2ZW50KGN1c3RvbUV2ZW50KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvLyBEb2VzIG5vdCBzdXBwb3J0IElFXHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKHVybCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgZmV0Y2godXJsKVxyXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzKSB7IHJldHVybiByZXMudGV4dCgpOyB9KVxyXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoaHRtbCkge1xyXG4gICAgICAgICAgICBfdGhpcy5zZWxlY3Rvci5pbm5lckhUTUwgPSBodG1sO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIGxnUXVlcnkucHJvdG90eXBlLmh0bWwgPSBmdW5jdGlvbiAoaHRtbCkge1xyXG4gICAgICAgIGlmIChodG1sID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmZpcnN0RWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZpcnN0RWxlbWVudC5pbm5lckhUTUw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX2VhY2goZnVuY3Rpb24gKGVsKSB7XHJcbiAgICAgICAgICAgIGVsLmlubmVySFRNTCA9IGh0bWw7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24gKGh0bWwpIHtcclxuICAgICAgICB0aGlzLl9lYWNoKGZ1bmN0aW9uIChlbCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGh0bWwgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgICAgICBlbC5pbnNlcnRBZGphY2VudEhUTUwoJ2JlZm9yZWVuZCcsIGh0bWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZWwuYXBwZW5kQ2hpbGQoaHRtbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5wcmVwZW5kID0gZnVuY3Rpb24gKGh0bWwpIHtcclxuICAgICAgICB0aGlzLl9lYWNoKGZ1bmN0aW9uIChlbCkge1xyXG4gICAgICAgICAgICBlbC5pbnNlcnRBZGphY2VudEhUTUwoJ2FmdGVyYmVnaW4nLCBodG1sKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5fZWFjaChmdW5jdGlvbiAoZWwpIHtcclxuICAgICAgICAgICAgZWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUuZW1wdHkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5fZWFjaChmdW5jdGlvbiAoZWwpIHtcclxuICAgICAgICAgICAgZWwuaW5uZXJIVE1MID0gJyc7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5wcm90b3R5cGUuc2Nyb2xsVG9wID0gZnVuY3Rpb24gKHNjcm9sbFRvcCkge1xyXG4gICAgICAgIGlmIChzY3JvbGxUb3AgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBkb2
1N1bWVudC5ib2R5LnNjcm9sbFRvcCA9IHNjcm9sbFRvcDtcclxuICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCA9IHNjcm9sbFRvcDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gKHdpbmRvdy5wYWdlWU9mZnNldCB8fFxyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fFxyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3AgfHxcclxuICAgICAgICAgICAgICAgIDApO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5zY3JvbGxMZWZ0ID0gZnVuY3Rpb24gKHNjcm9sbExlZnQpIHtcclxuICAgICAgICBpZiAoc2Nyb2xsTGVmdCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdCA9IHNjcm9sbExlZnQ7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0ID0gc2Nyb2xsTGVmdDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gKHdpbmRvdy5wYWdlWE9mZnNldCB8fFxyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHxcclxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdCB8fFxyXG4gICAgICAgICAgICAgICAgMCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGxnUXVlcnkucHJvdG90eXBlLm9mZnNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZmlyc3RFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBsZWZ0OiAwLFxyXG4gICAgICAgICAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICB2Y
1XIgcmVjdCA9IHRoaXMuZmlyc3RFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIHZhciBib2R5TWFyZ2luTGVmdCA9ICRMRygnYm9keScpLnN0eWxlKCkubWFyZ2luTGVmdDtcclxuICAgICAgICAvLyBNaW51cyBib2R5IG1hcmdpbiAtIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzMwNzExNTQ4L2lzLWdldGJvdW5kaW5nY2xpZW50cmVjdC1sZWZ0LXJldHVybmluZy1hLXdyb25nLXZhbHVlXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgbGVmdDogcmVjdC5sZWZ0IC0gcGFyc2VGbG9hdChib2R5TWFyZ2luTGVmdCkgKyB0aGlzLnNjcm9sbExlZnQoKSxcclxuICAgICAgICAgICAgdG9wOiByZWN0LnRvcCArIHRoaXMuc2Nyb2xsVG9wKCksXHJcbiAgICAgICAgfTtcclxuICAgIH07XHJcbiAgICBsZ1F1ZXJ5LnByb3RvdHlwZS5zdHlsZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZmlyc3RFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7fTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmZpcnN0RWxlbWVudC5jdXJyZW50U3R5bGUgfHxcclxuICAgICAgICAgICAgd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5maXJzdEVsZW1lbnQpKTtcclxuICAgIH07XHJcbiAgICAvLyBXaWR0aCB3aXRob3V0IHBhZGRpbmcgYW5kIGJvcmRlciBldmVuIGlmIGJveC1zaXppbmcgaXMgdXNlZC5cclxuICAgIGxnUXVlcnkucHJvdG90eXBlLndpZHRoID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBzdHlsZSA9IHRoaXMuc3R5bGUoKTtcclxuICAgICAgICByZXR1cm4gKHRoaXMuZmlyc3RFbGVtZW50LmNsaWVudFdpZHRoIC1cclxuICAgICAgICAgICAgcGFyc2VGbG9hdChzdHlsZS5wYWRkaW5nTGVmdCkgLVxyXG4gICAgICAgICAgICBwYXJzZUZsb2F0KHN0eWxlLnBhZGRpbmdSaWdodCkpO1xyXG4gICAgfTtcclxuICAgIC8vIEhlaWdodCB3aXRob3V0IHBhZGRpbmcgYW5kIGJvcmRlciBldmVuIGlmIGJveC1zaXppbmcgaXMgdXNlZC5cclxuICAgIGxnUXVlcnkucHJvdG90eXBlLmhlaWdodCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2Y
1XIgc3R5bGUgPSB0aGlzLnN0eWxlKCk7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmZpcnN0RWxlbWVudC5jbGllbnRIZWlnaHQgLVxyXG4gICAgICAgICAgICBwYXJzZUZsb2F0KHN0eWxlLnBhZGRpbmdUb3ApIC1cclxuICAgICAgICAgICAgcGFyc2VGbG9hdChzdHlsZS5wYWRkaW5nQm90dG9tKSk7XHJcbiAgICB9O1xyXG4gICAgbGdRdWVyeS5ldmVudExpc3RlbmVycyA9IHt9O1xyXG4gICAgcmV0dXJuIGxnUXVlcnk7XHJcbn0oKSk7XHJcbmZ1bmN0aW9uICRMRyhzZWxlY3Rvcikge1xyXG4gICAgaW5pdExnUG9seWZpbGxzKCk7XHJcbiAgICByZXR1cm4gbmV3IGxnUXVlcnkoc2VsZWN0b3IpO1xyXG59XG5cbnZhciBkZWZhdWx0RHluYW1pY09wdGlvbnMgPSBbXHJcbiAgICAnc3JjJyxcclxuICAgICdzb3VyY2VzJyxcclxuICAgICdzdWJIdG1sJyxcclxuICAgICdzdWJIdG1sVXJsJyxcclxuICAgICdodG1sJyxcclxuICAgICd2aWRlbycsXHJcbiAgICAncG9zdGVyJyxcclxuICAgICdzbGlkZU5hbWUnLFxyXG4gICAgJ3Jlc3BvbnNpdmUnLFxyXG4gICAgJ3NyY3NldCcsXHJcbiAgICAnc2l6ZXMnLFxyXG4gICAgJ2lmcmFtZScsXHJcbiAgICAnZG93bmxvYWRVcmwnLFxyXG4gICAgJ2Rvd25sb2FkJyxcclxuICAgICd3aWR0aCcsXHJcbiAgICAnZmFjZWJvb2tTaGFyZVVybCcsXHJcbiAgICAndHdlZXRUZXh0JyxcclxuICAgICdpZnJhbWVUaXRsZScsXHJcbiAgICAndHdpdHRlclNoYXJlVXJsJyxcclxuICAgICdwaW50ZXJlc3RTaGFyZVVybCcsXHJcbiAgICAncGludGVyZXN0VGV4dCcsXHJcbiAgICAnZmJIdG1sJyxcclxuICAgICdkaXNxdXNJZGVudGlmaWVyJyxcclxuICAgICdkaXNxdXNVcmwnLFxyXG5dO1xyXG4vLyBDb252ZXJ0IGh0bWwgZGF0YS1hdHRyaWJ1dGUgdG8gY2FtYWxjYXNlXHJcbmZ1bmN0aW9uIGNvbnZlcnRUb0RhdGEoYXR0cikge1xyXG4gICAgLy8gRkluZCBhIHdheSBmb3IgbGdzaXplXHJcbiAgICBpZiAoYXR0ciA9PT0gJ2hyZWYnKSB7XHJcbiAgICAgICAgcmV0dXJuICdzcmMnO1xyXG4gICAgfVxyXG4gICAgYXR0ciA9IGF0dHIucmVwbGFjZSgnZGF0YS0nLCAnJyk7XHJcbiAgICBhdHRyID0gYXR0ci5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGF0dHIuc2xpY2UoMSk7XHJcbiAgICBhdHRyID0gYXR0ci5yZXBsYWNlKC8tKFthLXpdKS9nLCBmdW5jdGlvbiAoZykgeyByZXR1cm4gZ1sxXS50b1VwcGVyQ2FzZSgpOyB9KTtcclxuICAgIHJldHVybiBhdHRyO1xyXG59XHJcbnZhciB1dGlscyA9IHtcclxuICAgIC8qKlxyXG4gICAgICogZ2V0IHBvc3NpYmxlIHdpZHRoIGFuZCBoZWlnaHQgZnJvbSB0aGUgbGdTaXplIGF0dHJpYnV0ZS4gVXNlZCBmb3IgWm9vbUZyb21PcmlnaW4gb3B0aW9uXHJcbiAgICAgKi9cclxuICAgIGdldFNpemU6IGZ1bmN0aW9uIChlbCwgY29udGFpbmVyLCBzcGFjaW5nLCBkZWZhdWx0TGdTaXplKSB7XHJcbiAgICAgICAgaWYgKHNwYWNpbmcgPT09IHZvaWQgMCkgeyBzcGFjaW5nID0gMDsgfVxyXG4gICAgICAgIHZhciBMR2VsID0gJExHKGVsKTtcclxuICAgICAgICB2Y
1XIgbGdTaXplID0gTEdlbC5hdHRyKCdkYXRhLWxnLXNpemUnKSB8fCBkZWZhdWx0TGdTaXplO1xyXG4gICAgICAgIGlmICghbGdTaXplKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGlzUmVzcG9uc2l2ZVNpemVzID0gbGdTaXplLnNwbGl0KCcsJyk7XHJcbiAgICAgICAgLy8gaWYgYXQtbGVhc3QgdHdvIHZpZXdwb3J0IHNpemVzIGFyZSBhdmFpbGFibGVcclxuICAgICAgICBpZiAoaXNSZXNwb25zaXZlU2l6ZXNbMV0pIHtcclxuICAgICAgICAgICAgdmFyIHdXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlzUmVzcG9uc2l2ZVNpemVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgc2l6ZV8xID0gaXNSZXNwb25zaXZlU2l6ZXNbaV07XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzcG9uc2l2ZVdpZHRoID0gcGFyc2VJbnQoc2l6ZV8xLnNwbGl0KCctJylbMl0sIDEwKTtcclxuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zaXZlV2lkdGggPiB3V2lkdGgpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZ1NpemUgPSBzaXplXzE7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyB0YWtlIGxhc3QgaXRlbSBhcyBsYXN0IG9wdGlvblxyXG4gICAgICAgICAgICAgICAgaWYgKGkgPT09IGlzUmVzcG9uc2l2ZVNpemVzLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZ1NpemUgPSBzaXplXzE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHNpemUgPSBsZ1NpemUuc3BsaXQoJy0nKTtcclxuICAgICAgICB2Y
1XIgd2lkdGggPSBwYXJzZUludChzaXplWzBdLCAxMCk7XHJcbiAgICAgICAgdmFyIGhlaWdodCA9IHBhcnNlSW50KHNpemVbMV0sIDEwKTtcclxuICAgICAgICB2YXIgY1dpZHRoID0gY29udGFpbmVyLndpZHRoKCk7XHJcbiAgICAgICAgdmFyIGNIZWlnaHQgPSBjb250YWluZXIuaGVpZ2h0KCkgLSBzcGFjaW5nO1xyXG4gICAgICAgIHZhciBtYXhXaWR0aCA9IE1hdGgubWluKGNXaWR0aCwgd2lkdGgpO1xyXG4gICAgICAgIHZhciBtYXhIZWlnaHQgPSBNYXRoLm1pbihjSGVpZ2h0LCBoZWlnaHQpO1xyXG4gICAgICAgIHZhciByYXRpbyA9IE1hdGgubWluKG1heFdpZHRoIC8gd2lkdGgsIG1heEhlaWdodCAvIGhlaWdodCk7XHJcbiAgICAgICAgcmV0dXJuIHsgd2lkdGg6IHdpZHRoICogcmF0aW8sIGhlaWdodDogaGVpZ2h0ICogcmF0aW8gfTtcclxuICAgIH0sXHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjIEdldCB0cmFuc2Zvcm0gdmFsdWUgYmFzZWQgb24gdGhlIGltYWdlU2l6ZS4gVXNlZCBmb3IgWm9vbUZyb21PcmlnaW4gb3B0aW9uXHJcbiAgICAgKiBAcGFyYW0ge2pRdWVyeSBFbGVtZW50fVxyXG4gICAgICogQHJldHVybnMge1N0cmluZ30gVHJhbnNmb3JtIENTUyBzdHJpbmdcclxuICAgICAqL1xyXG4gICAgZ2V0VHJhbnNmb3JtOiBmdW5jdGlvbiAoZWwsIGNvbnRhaW5lciwgdG9wLCBib3R0b20sIGltYWdlU2l6ZSkge1xyXG4gICAgICAgIGlmICghaW1hZ2VTaXplKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIExHZWwgPSAkTEcoZWwpLmZpbmQoJ2ltZycpLmZpcnN0KCk7XHJcbiAgICAgICAgaWYgKCFMR2VsLmdldCgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNvbnRhaW5lclJlY3QgPSBjb250YWluZXIuZ2V0KCkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgdmFyIHdXaWR0aCA9IGNvbnRhaW5lclJlY3Qud2lkdGg7XHJcbiAgICAgICAgLy8gdXNpbmcgaW5uZXJXaWR0aCB0byBpbmNsdWRlIG1vYmlsZSBzYWZhcmkgYm90dG9tIGJhclxyXG4gICAgICAgIHZhciB3SGVpZ2h0ID0gY29udGFpbmVyLmhlaWdodCgpIC0gKHRvcCArIGJvdHRvbSk7XHJcbiAgICAgICAgdmFyIGVsV2lkdGggPSBMR2VsLndpZHRoKCk7XHJcbiAgICAgICAgdmFyIGVsSGVpZ2h0ID0gTEdlbC5oZWlnaHQoKTtcclxuICAgICAgICB2Y
1XIgZWxTdHlsZSA9IExHZWwuc3R5bGUoKTtcclxuICAgICAgICB2YXIgeCA9ICh3V2lkdGggLSBlbFdpZHRoKSAvIDIgLVxyXG4gICAgICAgICAgICBMR2VsLm9mZnNldCgpLmxlZnQgK1xyXG4gICAgICAgICAgICAocGFyc2VGbG9hdChlbFN0eWxlLnBhZGRpbmdMZWZ0KSB8fCAwKSArXHJcbiAgICAgICAgICAgIChwYXJzZUZsb2F0KGVsU3R5bGUuYm9yZGVyTGVmdCkgfHwgMCkgK1xyXG4gICAgICAgICAgICAkTEcod2luZG93KS5zY3JvbGxMZWZ0KCkgK1xyXG4gICAgICAgICAgICBjb250YWluZXJSZWN0LmxlZnQ7XHJcbiAgICAgICAgdmFyIHkgPSAod0hlaWdodCAtIGVsSGVpZ2h0KSAvIDIgLVxyXG4gICAgICAgICAgICBMR2VsLm9mZnNldCgpLnRvcCArXHJcbiAgICAgICAgICAgIChwYXJzZUZsb2F0KGVsU3R5bGUucGFkZGluZ1RvcCkgfHwgMCkgK1xyXG4gICAgICAgICAgICAocGFyc2VGbG9hdChlbFN0eWxlLmJvcmRlclRvcCkgfHwgMCkgK1xyXG4gICAgICAgICAgICAkTEcod2luZG93KS5zY3JvbGxUb3AoKSArXHJcbiAgICAgICAgICAgIHRvcDtcclxuICAgICAgICB2YXIgc2NYID0gZWxXaWR0aCAvIGltYWdlU2l6ZS53aWR0aDtcclxuICAgICAgICB2YXIgc2NZID0gZWxIZWlnaHQgLyBpbWFnZVNpemUuaGVpZ2h0O1xyXG4gICAgICAgIHZhciB0cmFuc2Zvcm0gPSAndHJhbnNsYXRlM2QoJyArXHJcbiAgICAgICAgICAgICh4ICo9IC0xKSArXHJcbiAgICAgICAgICAgICdweCwgJyArXHJcbiAgICAgICAgICAgICh5ICo9IC0xKSArXHJcbiAgICAgICAgICAgICdweCwgMCkgc2NhbGUzZCgnICtcclxuICAgICAgICAgICAgc2NYICtcclxuICAgICAgICAgICAgJywgJyArXHJcbiAgICAgICAgICAgIHNjWSArXHJcbiAgICAgICAgICAgICcsIDEpJztcclxuICAgICAgICByZXR1cm4gdHJhbnNmb3JtO1xyXG4gICAgfSxcclxuICAgIGdldElmcmFtZU1hcmt1cDogZnVuY3Rpb24gKGlmcmFtZVdpZHRoLCBpZnJhbWVIZWlnaHQsIGlmcmFtZU1heFdpZHRoLCBpZnJhbWVNYXhIZWlnaHQsIHNyYywgaWZyYW1lVGl0bGUpIHtcclxuICAgICAgICB2Y
1XIgdGl0bGUgPSBpZnJhbWVUaXRsZSA/ICd0aXRsZT1cIicgKyBpZnJhbWVUaXRsZSArICdcIicgOiAnJztcclxuICAgICAgICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJsZy12aWRlby1jb250IGxnLWhhcy1pZnJhbWVcXFwiIHN0eWxlPVxcXCJ3aWR0aDpcIiArIGlmcmFtZVdpZHRoICsgXCI7IG1heC13aWR0aDpcIiArIGlmcmFtZU1heFdpZHRoICsgXCI7IGhlaWdodDogXCIgKyBpZnJhbWVIZWlnaHQgKyBcIjsgbWF4LWhlaWdodDpcIiArIGlmcmFtZU1heEhlaWdodCArIFwiXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxpZnJhbWUgY2xhc3M9XFxcImxnLW9iamVjdFxcXCIgZnJhbWVib3JkZXI9XFxcIjBcXFwiIFwiICsgdGl0bGUgKyBcIiBzcmM9XFxcIlwiICsgc3JjICsgXCJcXFwiICBhbGxvd2Z1bGxzY3JlZW49XFxcInRydWVcXFwiPjwvaWZyYW1lPlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cIjtcclxuICAgIH0sXHJcbiAgICBnZXRJbWdNYXJrdXA6IGZ1bmN0aW9uIChpbmRleCwgc3JjLCBhbHRBdHRyLCBzcmNzZXQsIHNpemVzLCBzb3VyY2VzKSB7XHJcbiAgICAgICAgdmFyIHNyY3NldEF0dHIgPSBzcmNzZXQgPyBcInNyY3NldD1cXFwiXCIgKyBzcmNzZXQgKyBcIlxcXCJcIiA6ICcnO1xyXG4gICAgICAgIHZhciBzaXplc0F0dHIgPSBzaXplcyA/IFwic2l6ZXM9XFxcIlwiICsgc2l6ZXMgKyBcIlxcXCJcIiA6ICcnO1xyXG4gICAgICAgIHZhciBpbWdNYXJrdXAgPSBcIjxpbWcgXCIgKyBhbHRBdHRyICsgXCIgXCIgKyBzcmNzZXRBdHRyICsgXCIgIFwiICsgc2l6ZXNBdHRyICsgXCIgY2xhc3M9XFxcImxnLW9iamVjdCBsZy1pbWFnZVxcXCIgZGF0YS1pbmRleD1cXFwiXCIgKyBpbmRleCArIFwiXFxcIiBzcmM9XFxcIlwiICsgc3JjICsgXCJcXFwiIC8+XCI7XHJcbiAgICAgICAgdmFyIHNvdXJjZVRhZyA9ICcnO1xyXG4gICAgICAgIGlmIChzb3VyY2VzKSB7XHJcbiAgICAgICAgICAgIHZhciBzb3VyY2VPYmogPSB0eXBlb2Ygc291cmNlcyA9PT0gJ3N0cmluZycgPyBKU09OLnBhcnNlKHNvdXJjZXMpIDogc291cmNlcztcclxuICAgICAgICAgICAgc291cmNlVGFnID0gc291cmNlT2JqLm1hcChmdW5jdGlvbiAoc291cmNlKSB7XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgYXR0cnMgPSAnJztcclxuICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKHNvdXJjZSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IHJlbW92ZSB0aGUgZmlyc3Qgc3BhY2UgYXMgaXQgaXMgcmVxdWlyZWQgdG8gc2VwYXJhdGUgdGhlIGF0dHJpYnV0ZXNcclxuICAgICAgICAgICAgICAgICAgICBhdHRycyArPSBcIiBcIiArIGtleSArIFwiPVxcXCJcIiArIHNvdXJjZVtrZXldICsgXCJcXFwiXCI7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBcIjxzb3VyY2UgXCIgKyBhdHRycyArIFwiPjwvc291cmNlPlwiO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFwiXCIgKyBzb3VyY2VUYWcgKyBpbWdNYXJrdXA7XHJcbiAgICB9LFxyXG4gICAgLy8gR2V0IHNyYyBmcm9tIHJlc3BvbnNpdmUgc3JjXHJcbiAgICBnZXRSZXNwb25zaXZlU3JjOiBmdW5jdGlvbiAoc3JjSXRtcykge1xyXG4gICAgICAgIHZhciByc1dpZHRoID0gW107XHJcbiAgICAgICAgdmFyIHJzU3JjID0gW107XHJcbiAgICAgICAgdmFyIHNyYyA9ICcnO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3JjSXRtcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgX3NyYyA9IHNyY0l0bXNbaV0uc3BsaXQoJyAnKTtcclxuICAgICAgICAgICAgLy8gTWFuYWdlIGVtcHR5IHNwYWNlXHJcbiAgICAgICAgICAgIGlmIChfc3JjWzBdID09PSAnJykge1xyXG4gICAgICAgICAgICAgICAgX3NyYy5zcGxpY2UoMCwgMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcnNTcmMucHVzaChfc3JjWzBdKTtcclxuICAgICAgICAgICAgcnNXaWR0aC5wdXNoKF9zcmNbMV0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2Y
1XIgd1dpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCByc1dpZHRoLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICAgIGlmIChwYXJzZUludChyc1dpZHRoW2pdLCAxMCkgPiB3V2lkdGgpIHtcclxuICAgICAgICAgICAgICAgIHNyYyA9IHJzU3JjW2pdO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNyYztcclxuICAgIH0sXHJcbiAgICBpc0ltYWdlTG9hZGVkOiBmdW5jdGlvbiAoaW1nKSB7XHJcbiAgICAgICAgaWYgKCFpbWcpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAvLyBEdXJpbmcgdGhlIG9ubG9hZCBldmVudCwgSUUgY29ycmVjdGx5IGlkZW50aWZpZXMgYW55IGltYWdlcyB0aGF0XHJcbiAgICAgICAgLy8gd2VyZW7igJl0IGRvd25sb2FkZWQgYXMgbm90IGNvbXBsZXRlLiBPdGhlcnMgc2hvdWxkIHRvby4gR2Vja28tYmFzZWRcclxuICAgICAgICAvLyBicm93c2VycyBhY3QgbGlrZSBOUzQgaW4gdGhhdCB0aGV5IHJlcG9ydCB0aGlzIGluY29ycmVjdGx5LlxyXG4gICAgICAgIGlmICghaW1nLmNvbXBsZXRlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gSG93ZXZlciwgdGhleSBkbyBoYXZlIHR3byB2ZXJ5IHVzZWZ1bCBwcm9wZXJ0aWVzOiBuYXR1cmFsV2lkdGggYW5kXHJcbiAgICAgICAgLy8gbmF0dXJhbEhlaWdodC4gVGhlc2UgZ2l2ZSB0aGUgdHJ1ZSBzaXplIG9mIHRoZSBpbWFnZS4gSWYgaXQgZmFpbGVkXHJcbiAgICAgICAgLy8gdG8gbG9hZCwgZWl0aGVyIG9mIHRoZXNlIHNob3VsZCBiZSB6ZXJvLlxyXG4gICAgICAgIGlmIChpbWcubmF0dXJhbFdpZHRoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gTm8gb3RoZXIgd2F5IG9mIGNoZWNraW5nOiBhc3N1bWUgaXTigJlzIG9rLlxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuICAgIGdldFZpZGVvUG9zdGVyTWFya3VwOiBmdW5jdGlvbiAoX3Bvc3RlciwgZHVtbXlJbWcsIHZpZGVvQ29udFN0eWxlLCBwbGF5VmlkZW9TdHJpbmcsIF9pc1ZpZGVvKSB7XHJcbiAgICAgICAgdmFyIHZpZGVvQ2xhc3MgPSAnJztcclxuICAgICAgICBpZiAoX2lzVmlkZW8gJiYgX2lzVmlkZW8ueW91dHViZSkge1xyXG4gICAgICAgICAgICB2aWRlb0NsYXNzID0gJ2xnLWhhcy15b3V0dWJlJztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoX2lzVmlkZW8gJiYgX2lzVmlkZW8udmltZW8pIHtcclxuICAgICAgICAgICAgdmlkZW9DbGFzcyA9ICdsZy1oYXMtdmltZW8nO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdmlkZW9DbGFzcyA9ICdsZy1oYXMtaHRtbDUnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJsZy12aWRlby1jb250IFwiICsgdmlkZW9DbGFzcyArIFwiXFxcIiBzdHlsZT1cXFwiXCIgKyB2aWRlb0NvbnRTdHlsZSArIFwiXFxcIj5cXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwibGctdmlkZW8tcGxheS1idXR0b25cXFwiPlxcbiAgICAgICAgICAgICAgICA8c3ZnXFxuICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVxcXCIwIDAgMjAgMjBcXFwiXFxuICAgICAgICAgICAgICAgICAgICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPVxcXCJ4TWlkWU1pZFxcXCJcXG4gICAgICAgICAgICAgICAgICAgIGZvY3VzYWJsZT1cXFwiZmFsc2VcXFwiXFxuICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsbGVkYnk9XFxcIlwiICsgcGxheVZpZGVvU3RyaW5nICsgXCJcXFwiXFxuICAgICAgICAgICAgICAgICAgICByb2xlPVxcXCJpbWdcXFwiXFxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cXFwibGctdmlkZW8tcGxheS1pY29uXFxcIlxcbiAgICAgICAgICAgICAgICA+XFxuICAgICAgICAgICAgICAgICAgICA8dGl0bGU+XCIgKyBwbGF5VmlkZW9TdHJpbmcgKyBcIjwvdGl0bGU+XFxuICAgICAgICAgICAgICAgICAgICA8cG9seWdvbiBjbGFzcz1cXFwibGctdmlkZW8tcGxheS1pY29uLWlubmVyXFxcIiBwb2ludHM9XFxcIjEsMCAyMCwxMCAxLDIwXFxcIj48L3BvbHlnb24+XFxuICAgICAgICAgICAgICAgIDwvc3ZnPlxcbiAgICAgICAgICAgICAgICA8c3ZnIGNsYXNzPVxcXCJsZy12aWRlby1wbGF5LWljb24tYmdcXFwiIHZpZXdCb3g9XFxcIjAgMCA1MCA1MFxcXCIgZm9jdXNhYmxlPVxcXCJmYWxzZVxcXCI+XFxuICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PVxcXCI1MCVcXFwiIGN5PVxcXCI1MCVcXFwiIHI9XFxcIjIwXFxcIj48L2NpcmNsZT48L3N2Zz5cXG4gICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cXFwibGctdmlkZW8tcGxheS1pY29uLWNpcmNsZVxcXCIgdmlld0JveD1cXFwiMCAwIDUwIDUwXFxcIiBmb2N1c2FibGU9XFxcImZhbHNlXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9XFxcIjUwJVxcXCIgY3k9XFxcIjUwJVxcXCIgcj1cXFwiMjBcXFwiPjwvY2lyY2xlPlxcbiAgICAgICAgICAgICAgICA8L3N2Zz5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICBcIiArIChkdW1teUltZyB8fCAnJykgKyBcIlxcbiAgICAgICAgICAgIDxpbWcgY2xhc3M9XFxcImxnLW9iamVjdCBsZy12aWRlby1wb3N0ZXJcXFwiIHNyYz1cXFwiXCIgKyBfcG9zdGVyICsgXCJcXFwiIC8+XFxuICAgICAgICA8L2Rpdj5cIjtcclxuICAgIH0sXHJcbiAgICBnZXRGb2N1c2FibGVFbGVtZW50czogZnVuY3Rpb24gKGNvbnRhaW5lcikge1xyXG4gICAgICAgIHZhciBlbGVtZW50cyA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCdhW2hyZWZdOm5vdChbZGlzYWJsZWRdKSwgYnV0dG9uOm5vdChbZGlzYWJsZWRdKSwgdGV4dGFyZWE6bm90KFtkaXNhYmxlZF0pLCBpbnB1dFt0eXBlPVwidGV4dFwiXTpub3QoW2Rpc2FibGVkXSksIGlucHV0W3R5cGU9XCJyYWRpb1wiXTpub3QoW2Rpc2FibGVkXSksIGlucHV0W3R5cGU9XCJjaGVja2JveFwiXTpub3QoW2Rpc2FibGVkXSksIHNlbGVjdDpub3QoW2Rpc2FibGVkXSknKTtcclxuICAgICAgICB2Y
1XIgdmlzaWJsZUVsZW1lbnRzID0gW10uZmlsdGVyLmNhbGwoZWxlbWVudHMsIGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHZhciBzdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xyXG4gICAgICAgICAgICByZXR1cm4gc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnICYmIHN0eWxlLnZpc2liaWxpdHkgIT09ICdoaWRkZW4nO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB2aXNpYmxlRWxlbWVudHM7XHJcbiAgICB9LFxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzYyBDcmVhdGUgZHluYW1pYyBlbGVtZW50cyBhcnJheSBmcm9tIGdhbGxlcnkgaXRlbXMgd2hlbiBkeW5hbWljIG9wdGlvbiBpcyBmYWxzZVxyXG4gICAgICogSXQgaGVscHMgdG8gYXZvaWQgZnJlcXVlbnQgRE9NIGludGVyYWN0aW9uXHJcbiAgICAgKiBhbmQgYXZvaWQgbXVsdGlwbGUgY2hlY2tzIGZvciBkeW5hbWljIGVsbWVudHNcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IGR5bmFtaWNFbFxyXG4gICAgICovXHJcbiAgICBnZXREeW5hbWljT3B0aW9uczogZnVuY3Rpb24gKGl0ZW1zLCBleHRyYVByb3BzLCBnZXRDYXB0aW9uRnJvbVRpdGxlT3JBbHQsIGV4VGh1bWJJbWFnZSkge1xyXG4gICAgICAgIHZhciBkeW5hbWljRWxlbWVudHMgPSBbXTtcclxuICAgICAgICB2YXIgYXZhaWxhYmxlRHluYW1pY09wdGlvbnMgPSBfX3NwcmVhZEFycmF5cyhkZWZhdWx0RHluYW1pY09wdGlvbnMsIGV4dHJhUHJvcHMpO1xyXG4gICAgICAgIFtdLmZvckVhY2guY2FsbChpdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcclxuICAgICAgICAgICAgdmFyIGR5bmFtaWNFbCA9IHt9O1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW0uYXR0cmlidXRlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGF0dHIgPSBpdGVtLmF0dHJpYnV0ZXNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoYXR0ci5zcGVjaWZpZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2Y
1XIgZHluYW1pY0F0dHIgPSBjb252ZXJ0VG9EYXRhKGF0dHIubmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxhYmVsID0gJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF2YWlsYWJsZUR5bmFtaWNPcHRpb25zLmluZGV4T2YoZHluYW1pY0F0dHIpID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSBkeW5hbWljQXR0cjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGR5bmFtaWNFbFtsYWJlbF0gPSBhdHRyLnZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgY3VycmVudEl0ZW0gPSAkTEcoaXRlbSk7XHJcbiAgICAgICAgICAgIHZhciBhbHQgPSBjdXJyZW50SXRlbS5maW5kKCdpbWcnKS5maXJzdCgpLmF0dHIoJ2FsdCcpO1xyXG4gICAgICAgICAgICB2YXIgdGl0bGUgPSBjdXJyZW50SXRlbS5hdHRyKCd0aXRsZScpO1xyXG4gICAgICAgICAgICB2YXIgdGh1bWIgPSBleFRodW1iSW1hZ2VcclxuICAgICAgICAgICAgICAgID8gY3VycmVudEl0ZW0uYXR0cihleFRodW1iSW1hZ2UpXHJcbiAgICAgICAgICAgICAgICA6IGN1cnJlbnRJdGVtLmZpbmQoJ2ltZycpLmZpcnN0KCkuYXR0cignc3JjJyk7XHJcbiAgICAgICAgICAgIGR5bmFtaWNFbC50aHVtYiA9IHRodW1iO1xyXG4gICAgICAgICAgICBpZiAoZ2V0Q2FwdGlvbkZyb21UaXRsZU9yQWx0ICYmICFkeW5hbWljRWwuc3ViSHRtbCkge1xyXG4gICAgICAgICAgICAgICAgZHluYW1pY0VsLnN1Ykh0bWwgPSB0aXRsZSB8fCBhbHQgfHwgJyc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZHluYW1pY0VsLmFsdCA9IGFsdCB8fCB0aXRsZSB8fCAnJztcclxuICAgICAgICAgICAgZHluYW1pY0VsZW1lbnRzLnB1c2goZHluYW1pY0VsKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gZHluYW1pY0VsZW1lbnRzO1xyXG4gICAgfSxcclxuICAgIGlzTW9iaWxlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIC9pUGhvbmV8aVBhZHxpUG9kfEFuZHJvaWQvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xyXG4gICAgfSxcclxuICAgIC8qKlxyXG4gICAgICogQGRlc2MgQ2hlY2sgdGhlIGdpdmVuIHNyYyBpcyB2aWRlb1xyXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHNyY1xyXG4gICAgICogQHJldHVybiB7T2JqZWN0fSB2aWRlbyB0eXBlXHJcbiAgICAgKiBFeDp7IHlvdXR1YmUgIDogIFtcIi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9YzBhc0pnU3l4Y1lcIiwgXCJjMGFzSmdTeXhjWVwiXSB9XHJcbiAgICAgKlxyXG4gICAgICogQHRvZG8gLSB0aGlzIGluZm9ybWF0aW9uIGNhbiBiZSBtb3ZlZCB0byBkeW5hbWljRWwgdG8gYXZvaWQgZnJlcXVlbnQgY2FsbHNcclxuICAgICAqL1xyXG4gICAgaXNWaWRlbzogZnVuY3Rpb24gKHNyYywgaXNIVE1MNVZJZGVvLCBpbmRleCkge1xyXG4gICAgICAgIGlmICghc3JjKSB7XHJcbiAgICAgICAgICAgIGlmIChpc0hUTUw1VklkZW8pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaHRtbDU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignbGlnaHRHYWxsZXJ5IDotIGRhdGEtc3JjIGlzIG5vdCBwcm92aWRlZCBvbiBzbGlkZSBpdGVtICcgK1xyXG4gICAgICAgICAgICAgICAgICAgIChpbmRleCArIDEpICtcclxuICAgICAgICAgICAgICAgICAgICAnLiBQbGVhc2UgbWFrZSBzdXJlIHRoZSBzZWxlY3RvciBwcm9wZXJ0eSBpcyBwcm9wZXJseSBjb25maWd1cmVkLiBNb3JlIGluZm8gLSBodHRwczovL3d3dy5saWdodGdhbGxlcnlqcy5jb20vZGVtb3MvaHRtbC1tYXJrdXAvJyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHlvdXR1YmUgPSBzcmMubWF0Y2goL1xcL1xcLyg/Ond3d1xcLik/eW91dHUoPzpcXC5iZXxiZVxcLmNvbXxiZS1ub2Nvb2tpZVxcLmNvbSlcXC8oPzp3YXRjaFxcP3Y9fGVtYmVkXFwvKT8oW2EtejAtOVxcLVxcX1xcJV0rKShbXFwmfD9dW1xcU10qKSovaSk7XHJcbiAgICAgICAgdmFyIHZpbWVvID0gc3JjLm1hdGNoKC9cXC9cXC8oPzp3d3dcXC4pPyg/OnBsYXllclxcLik/dmltZW8uY29tXFwvKD86dmlkZW9cXC8pPyhbMC05YS16XFwtX10rKSguKik/L2kpO1xyXG4gICAgICAgIHZhciB3aXN0aWEgPSBzcmMubWF0Y2goL2h0dHBzPzpcXC9cXC8oLispPyh3aXN0aWFcXC5jb218d2lcXC5zdClcXC8obWVkaWFzfGVtYmVkKVxcLyhbMC05YS16XFwtX10rKSguKikvKTtcclxuICAgICAgICBpZiAoeW91dHViZSkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgeW91dHViZTogeW91dHViZSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodmltZW8pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHZpbWVvOiB2aW1lbyxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAod2lzdGlhKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICB3aXN0aWE6IHdpc3RpYSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG59O1xuXG4vLyBAcmVmIC0gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzk3MTg0MS9ob3ctdG8tcmVzaXplLWltYWdlcy1wcm9wb3J0aW9uYWxseS1rZWVwaW5nLXRoZS1hc3BlY3QtcmF0aW9cclxuLy8gQHJlZiAtIGh0dHBzOi8vMmFsaXR5LmNvbS8yMDE3LzA0L3NldHRpbmctdXAtbXVsdGktcGxhdGZvcm0tcGFja2FnZXMuaHRtbFxyXG4vLyBVbmlxdWUgaWQgZm9yIGVhY2ggZ2FsbGVyeVxyXG52YXIgbGdJZCA9IDA7XHJcbnZhciBMaWdodEdhbGxlcnkgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBMaWdodEdhbGxlcnkoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgICAgI
1HRoaXMubGdPcGVuZWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmluZGV4ID0gMDtcclxuICAgICAgICAvLyBsaWdodEdhbGxlcnkgbW9kdWxlc1xyXG4gICAgICAgIHRoaXMucGx1Z2lucyA9IFtdO1xyXG4gICAgICAgIC8vIGZhbHNlIHdoZW4gbGlnaHRHYWxsZXJ5IGxvYWQgZmlyc3Qgc2xpZGUgY29udGVudDtcclxuICAgICAgICB0aGlzLmxHYWxsZXJ5T24gPSBmYWxzZTtcclxuICAgICAgICAvLyBUcnVlIHdoZW4gYSBzbGlkZSBhbmltYXRpb24gaXMgaW4gcHJvZ3Jlc3NcclxuICAgICAgICB0aGlzLmxnQnVzeSA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuY3VycmVudEl0ZW1zSW5Eb20gPSBbXTtcclxuICAgICAgICAvLyBTY3JvbGwgdG9wIHZhbHVlIGJlZm9yZSBsaWdodEdhbGxlcnkgaXMgb3BlbmVkXHJcbiAgICAgICAgdGhpcy5wcmV2U2Nyb2xsVG9wID0gMDtcclxuICAgICAgICB0aGlzLmJvZHlQYWRkaW5nUmlnaHQgPSAwO1xyXG4gICAgICAgIHRoaXMuaXNEdW1teUltYWdlUmVtb3ZlZCA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuZHJhZ09yU3dpcGVFbmFibGVkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5tZWRpYUNvbnRhaW5lclBvc2l0aW9uID0ge1xyXG4gICAgICAgICAgICB0b3A6IDAsXHJcbiAgICAgICAgICAgIGJvdHRvbTogMCxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmICghZWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgbGdJZCsrO1xyXG4gICAgICAgIHRoaXMubGdJZCA9IGxnSWQ7XHJcbiAgICAgICAgdGhpcy5lbCA9IGVsZW1lbnQ7XHJcbiAgICAgICAgdGhpcy5MR2VsID0gJExHKGVsZW1lbnQpO1xyXG4gICAgICAgIHRoaXMuZ2VuZXJhdGVTZXR0aW5ncyhvcHRpb25zKTtcclxuICAgICAgICB0aGlzLmJ1aWxkTW9kdWxlcygpO1xyXG4gICAgICAgIC8vIFdoZW4gdXNpbmcgZHluYW1pYyBtb2RlLCBlbnN1cmUgZHluYW1pY0VsIGlzIGFuIGFycmF5XHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuZHluYW1pYyAmJlxyXG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzLmR5bmFtaWNFbCAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgICAgICFBcnJheS5pc0FycmF5KHRoaXMuc2V0dGluZ3MuZHluYW1pY0VsKSkge1xyXG4gICAgICAgICAgICB0aHJvdyAnV2hlbiB1c2luZyBkeW5hbWljIG1vZGUsIHlvdSBtdXN0IGFsc28gZGVmaW5lIGR5bmFtaWNFbCBhcyBhbiBBcnJheS4nO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmdhbGxlcnlJdGVtcyA9IHRoaXMuZ2V0SXRlbXMoKTtcclxuICAgICAgICB0aGlzLm5vcm1hbGl6ZVNldHRpbmdzKCk7XHJcbiAgICAgICAgLy8gR2FsbGVyeSBpdGVtc1xyXG4gICAgICAgIHRoaXMuaW5pdCgpO1xyXG4gICAgICAgIHRoaXMudmFsaWRhdGVMaWNlbnNlKCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmdlbmVyYXRlU2V0dGluZ3MgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgIC8vIGxpZ2h0R2FsbGVyeSBzZXR0aW5nc1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MgPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgbGlnaHRHYWxsZXJ5Q29yZVNldHRpbmdzKSwgb3B0aW9ucyk7XHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuaXNNb2JpbGUgJiZcclxuICAgICAgICAgICAgdHlwZW9mIHRoaXMuc2V0dGluZ3MuaXNNb2JpbGUgPT09ICdmdW5jdGlvbidcclxuICAgICAgICAgICAgPyB0aGlzLnNldHRpbmdzLmlzTW9iaWxlKClcclxuICAgICAgICAgICAgOiB1dGlscy5pc01vYmlsZSgpKSB7XHJcbiAgICAgICAgICAgIHZhciBtb2JpbGVTZXR0aW5ncyA9IF9fYXNzaWduKF9fYXNzaWduKHt9LCB0aGlzLnNldHRpbmdzLm1vYmlsZVNldHRpbmdzKSwgdGhpcy5zZXR0aW5ncy5tb2JpbGVTZXR0aW5ncyk7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MgPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgdGhpcy5zZXR0aW5ncyksIG1vYmlsZVNldHRpbmdzKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5ub3JtYWxpemVTZXR0aW5ncyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5zbGlkZUVuZEFuaW1hdGlvbikge1xyXG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzLmhpZGVDb250cm9sT25FbmQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLmNsb3NhYmxlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3Muc3dpcGVUb0Nsb3NlID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEFuZCByZXNldCBpdCBvbiBjbG9zZSB0byBnZXQgdGhlIGNvcnJlY3QgdmFsdWUgbmV4dCB0aW1lXHJcbiAgICAgICAgdGhpcy56b29tRnJvbU9yaWdpbiA9IHRoaXMuc2V0dGluZ3Muem9vbUZyb21PcmlnaW47XHJcbiAgICAgICAgLy8gQXQgdGhlIG1vbWVudCwgWm9vbSBmcm9tIGltYWdlIGRvZXNuJ3Qgc3VwcG9ydCBkeW5hbWljIG9wdGlvbnNcclxuICAgICAgICAvLyBAdG9kbyBhZGQgem9vbUZyb21PcmlnaW4gc3VwcG9ydCBmb3IgZHluYW1pYyBpbWFnZXNcclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5keW5hbWljKSB7XHJcbiAgICAgICAgICAgIHRoaXMuem9vbUZyb21PcmlnaW4gPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLmNvbnRhaW5lcikge1xyXG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzLmNvbnRhaW5lciA9IGRvY3VtZW50LmJvZHk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNldHRpbmdzLnByZWxvYWQgc2hvdWxkIG5vdCBiZSBncmF0ZXIgdGhhbiAkaXRlbS5sZW5ndGhcclxuICAgICAgICB0aGlzLnNldHRpbmdzLnByZWxvYWQgPSBNYXRoLm1pbih0aGlzLnNldHRpbmdzLnByZWxvYWQsIHRoaXMuZ2FsbGVyeUl0ZW1zLmxlbmd0aCk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgI
1HZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdGhpcy5hZGRTbGlkZVZpZGVvSW5mbyh0aGlzLmdhbGxlcnlJdGVtcyk7XHJcbiAgICAgICAgdGhpcy5idWlsZFN0cnVjdHVyZSgpO1xyXG4gICAgICAgIHRoaXMuTEdlbC50cmlnZ2VyKGxHRXZlbnRzLmluaXQsIHtcclxuICAgICAgICAgICAgaW5zdGFuY2U6IHRoaXMsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Mua2V5UHJlc3MpIHtcclxuICAgICAgICAgICAgdGhpcy5rZXlQcmVzcygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuZW5hYmxlRHJhZygpO1xyXG4gICAgICAgICAgICBfdGhpcy5lbmFibGVTd2lwZSgpO1xyXG4gICAgICAgICAgICBfdGhpcy50cmlnZ2VyUG9zdGVyQ2xpY2soKTtcclxuICAgICAgICB9LCA1MCk7XHJcbiAgICAgICAgdGhpcy5hcnJvdygpO1xyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLm1vdXNld2hlZWwpIHtcclxuICAgICAgICAgICAgdGhpcy5tb3VzZXdoZWVsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5zZXR0aW5ncy5keW5hbWljKSB7XHJcbiAgICAgICAgICAgIHRoaXMub3BlbkdhbGxlcnlPbkl0ZW1DbGljaygpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLm9wZW5HYWxsZXJ5T25JdGVtQ2xpY2sgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2Y
1XIgX2xvb3BfMSA9IGZ1bmN0aW9uIChpbmRleCkge1xyXG4gICAgICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXNfMS5pdGVtc1tpbmRleF07XHJcbiAgICAgICAgICAgIHZhciAkZWxlbWVudCA9ICRMRyhlbGVtZW50KTtcclxuICAgICAgICAgICAgLy8gVXNpbmcgZGlmZmVyZW50IG5hbWVzcGFjZSBmb3IgY2xpY2sgYmVjYXVzZSBjbGljayBldmVudCBzaG91bGQgbm90IHVuYmluZCBpZiBzZWxlY3RvciBpcyBzYW1lIG9iamVjdCgndGhpcycpXHJcbiAgICAgICAgICAgIC8vIEB0b2RvIG1hbmFnZSBhbGwgZXZlbnQgbGlzdG5lcnMgLSBzaG91bGQgaGF2ZSBuYW1lc3BhY2UgdGhhdCByZXByZXNlbnQgZWxlbWVudFxyXG4gICAgICAgICAgICB2YXIgdXVpZCA9IGxnUXVlcnkuZ2VuZXJhdGVVVUlEKCk7XHJcbiAgICAgICAgICAgICRlbGVtZW50XHJcbiAgICAgICAgICAgICAgICAuYXR0cignZGF0YS1sZy1pZCcsIHV1aWQpXHJcbiAgICAgICAgICAgICAgICAub24oXCJjbGljay5sZ2N1c3RvbS1pdGVtLVwiICsgdXVpZCwgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIHZhciBjdXJyZW50SXRlbUluZGV4ID0gX3RoaXMuc2V0dGluZ3MuaW5kZXggfHwgaW5kZXg7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5vcGVuR2FsbGVyeShjdXJyZW50SXRlbUluZGV4LCBlbGVtZW50KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB2YXIgdGhpc18xID0gdGhpcztcclxuICAgICAgICAvLyBVc2luZyBmb3IgbG9vcCBpbnN0ZWFkIG9mIHVzaW5nIGJ1YmJsaW5nIGFzIHRoZSBpdGVtcyBjYW4gYmUgYW55IGh0bWwgZWxlbWVudC5cclxuICAgICAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5pdGVtcy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgX2xvb3BfMShpbmRleCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogTW9kdWxlIGNvbnN0cnVjdG9yXHJcbiAgICAgKiBNb2R1bGVzIGFyZSBidWlsZCBpbmNyZW1lbnRhbGx5LlxyXG4gICAgICogR2FsbGVyeSBzaG91bGQgYmUgb3BlbmVkIG9ubHkgb25jZSBhbGwgdGhlIG1vZHVsZXMgYXJlIGluaXRpYWxpemVkLlxyXG4gICAgICogdXNlIG1vZHVsZUJ1aWxkVGltZW91dCB0byBtYWtlIHN1cmUgdGhpc1xyXG4gICAgICovXHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmJ1aWxkTW9kdWxlcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MucGx1Z2lucy5mb3JFYWNoKGZ1bmN0aW9uIChwbHVnaW4pIHtcclxuICAgICAgICAgICAgX3RoaXMucGx1Z2lucy5wdXNoKG5ldyBwbHVnaW4oX3RoaXMsICRMRykpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUudmFsaWRhdGVMaWNlbnNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5zZXR0aW5ncy5saWNlbnNlS2V5KSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1BsZWFzZSBwcm92aWRlIGEgdmFsaWQgbGljZW5zZSBrZXknKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy5zZXR0aW5ncy5saWNlbnNlS2V5ID09PSAnMDAwMC0wMDAwLTAwMC0wMDAwJykge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJsaWdodEdhbGxlcnk6IFwiICsgdGhpcy5zZXR0aW5ncy5saWNlbnNlS2V5ICsgXCIgbGljZW5zZSBrZXkgaXMgbm90IHZhbGlkIGZvciBwcm9kdWN0aW9uIHVzZVwiKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5nZXRTbGlkZUl0ZW0gPSBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICByZXR1cm4gJExHKHRoaXMuZ2V0U2xpZGVJdGVtSWQoaW5kZXgpKTtcclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmdldFNsaWRlSXRlbUlkID0gZnVuY3Rpb24gKGluZGV4KSB7XHJcbiAgICAgICAgcmV0dXJuIFwiI2xnLWl0ZW0tXCIgKyB0aGlzLmxnSWQgKyBcIi1cIiArIGluZGV4O1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuZ2V0SWROYW1lID0gZnVuY3Rpb24gKGlkKSB7XHJcbiAgICAgICAgcmV0dXJuIGlkICsgXCItXCIgKyB0aGlzLmxnSWQ7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5nZXRFbGVtZW50QnlJZCA9IGZ1bmN0aW9uIChpZCkge1xyXG4gICAgICAgIHJldHVybiAkTEcoXCIjXCIgKyB0aGlzLmdldElkTmFtZShpZCkpO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUubWFuYWdlU2luZ2xlU2xpZGVDbGFzc05hbWUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZ2FsbGVyeUl0ZW1zLmxlbmd0aCA8IDIpIHtcclxuICAgICAgICAgICAgdGhpcy5vdXRlci5hZGRDbGFzcygnbGctc2luZ2xlLWl0ZW0nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLXNpbmdsZS1pdGVtJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuYnVpbGRTdHJ1Y3R1cmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2Y
1XIgY29udGFpbmVyID0gdGhpcy4kY29udGFpbmVyICYmIHRoaXMuJGNvbnRhaW5lci5nZXQoKTtcclxuICAgICAgICBpZiAoY29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNvbnRyb2xzID0gJyc7XHJcbiAgICAgICAgdmFyIHN1Ykh0bWxDb250ID0gJyc7XHJcbiAgICAgICAgLy8gQ3JlYXRlIGNvbnRyb2xzXHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuY29udHJvbHMpIHtcclxuICAgICAgICAgICAgY29udHJvbHMgPSBcIjxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBpZD1cXFwiXCIgKyB0aGlzLmdldElkTmFtZSgnbGctcHJldicpICsgXCJcXFwiIGFyaWEtbGFiZWw9XFxcIlwiICsgdGhpcy5zZXR0aW5ncy5zdHJpbmdzWydwcmV2aW91c1NsaWRlJ10gKyBcIlxcXCIgY2xhc3M9XFxcImxnLXByZXYgbGctaWNvblxcXCI+IFwiICsgdGhpcy5zZXR0aW5ncy5wcmV2SHRtbCArIFwiIDwvYnV0dG9uPlxcbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XFxcImJ1dHRvblxcXCIgaWQ9XFxcIlwiICsgdGhpcy5nZXRJZE5hbWUoJ2xnLW5leHQnKSArIFwiXFxcIiBhcmlhLWxhYmVsPVxcXCJcIiArIHRoaXMuc2V0dGluZ3Muc3RyaW5nc1snbmV4dFNsaWRlJ10gKyBcIlxcXCIgY2xhc3M9XFxcImxnLW5leHQgbGctaWNvblxcXCI+IFwiICsgdGhpcy5zZXR0aW5ncy5uZXh0SHRtbCArIFwiIDwvYnV0dG9uPlwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5hcHBlbmRTdWJIdG1sVG8gIT09ICcubGctaXRlbScpIHtcclxuICAgICAgICAgICAgc3ViSHRtbENvbnQgPVxyXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJsZy1zdWItaHRtbFwiIHJvbGU9XCJzdGF0dXNcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIj48L2Rpdj4nO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2Y
1XIgYWRkQ2xhc3NlcyA9ICcnO1xyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLmFsbG93TWVkaWFPdmVybGFwKSB7XHJcbiAgICAgICAgICAgIC8vIERvIG5vdCByZW1vdmUgc3BhY2UgYmVmb3JlIGxhc3Qgc2luZ2xlIHF1b3RlXHJcbiAgICAgICAgICAgIGFkZENsYXNzZXMgKz0gJ2xnLW1lZGlhLW92ZXJsYXAgJztcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGFyaWFMYWJlbGxlZGJ5ID0gdGhpcy5zZXR0aW5ncy5hcmlhTGFiZWxsZWRieVxyXG4gICAgICAgICAgICA/ICdhcmlhLWxhYmVsbGVkYnk9XCInICsgdGhpcy5zZXR0aW5ncy5hcmlhTGFiZWxsZWRieSArICdcIidcclxuICAgICAgICAgICAgOiAnJztcclxuICAgICAgICB2YXIgYXJpYURlc2NyaWJlZGJ5ID0gdGhpcy5zZXR0aW5ncy5hcmlhRGVzY3JpYmVkYnlcclxuICAgICAgICAgICAgPyAnYXJpYS1kZXNjcmliZWRieT1cIicgKyB0aGlzLnNldHRpbmdzLmFyaWFEZXNjcmliZWRieSArICdcIidcclxuICAgICAgICAgICAgOiAnJztcclxuICAgICAgICB2YXIgY29udGFpbmVyQ2xhc3NOYW1lID0gXCJsZy1jb250YWluZXIgXCIgKyB0aGlzLnNldHRpbmdzLmFkZENsYXNzICsgXCIgXCIgKyAoZG9jdW1lbnQuYm9keSAhPT0gdGhpcy5zZXR0aW5ncy5jb250YWluZXIgPyAnbGctaW5saW5lJyA6ICcnKTtcclxuICAgICAgICB2YXIgY2xvc2VJY29uID0gdGhpcy5zZXR0aW5ncy5jbG9zYWJsZSAmJiB0aGlzLnNldHRpbmdzLnNob3dDbG9zZUljb25cclxuICAgICAgICAgICAgPyBcIjxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBhcmlhLWxhYmVsPVxcXCJcIiArIHRoaXMuc2V0dGluZ3Muc3RyaW5nc1snY2xvc2VHYWxsZXJ5J10gKyBcIlxcXCIgaWQ9XFxcIlwiICsgdGhpcy5nZXRJZE5hbWUoJ2xnLWNsb3NlJykgKyBcIlxcXCIgY2xhc3M9XFxcImxnLWNsb3NlIGxnLWljb25cXFwiPjwvYnV0dG9uPlwiXHJcbiAgICAgICAgICAgIDogJyc7XHJcbiAgICAgICAgdmFyIG1heGltaXplSWNvbiA9IHRoaXMuc2V0dGluZ3Muc2hvd01heGltaXplSWNvblxyXG4gICAgICAgICAgICA/IFwiPGJ1dHRvbiB0eXBlPVxcXCJidXR0b25cXFwiIGFyaWEtbGFiZWw9XFxcIlwiICsgdGhpcy5zZXR0aW5ncy5zdHJpbmdzWyd0b2dnbGVNYXhpbWl6ZSddICsgXCJcXFwiIGlkPVxcXCJcIiArIHRoaXMuZ2V0SWROYW1lKCdsZy1tYXhpbWl6ZScpICsgXCJcXFwiIGNsYXNzPVxcXCJsZy1tYXhpbWl6ZSBsZy1pY29uXFxcIj48L2J1dHRvbj5cIlxyXG4gICAgICAgICAgICA6ICcnO1xyXG4gICAgICAgIHZhciB0ZW1wbGF0ZSA9IFwiXFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJcIiArIGNvbnRhaW5lckNsYXNzTmFtZSArIFwiXFxcIiBpZD1cXFwiXCIgKyB0aGlzLmdldElkTmFtZSgnbGctY29udGFpbmVyJykgKyBcIlxcXCIgdGFiaW5kZXg9XFxcIi0xXFxcIiBhcmlhLW1vZGFsPVxcXCJ0cnVlXFxcIiBcIiArIGFyaWFMYWJlbGxlZGJ5ICsgXCIgXCIgKyBhcmlhRGVzY3JpYmVkYnkgKyBcIiByb2xlPVxcXCJkaWFsb2dcXFwiXFxuICAgICAgICA+XFxuICAgICAgICAgICAgPGRpdiBpZD1cXFwiXCIgKyB0aGlzLmdldElkTmFtZSgnbGctYmFja2Ryb3AnKSArIFwiXFxcIiBjbGFzcz1cXFwibGctYmFja2Ryb3BcXFwiPjwvZGl2PlxcblxcbiAgICAgICAgICAgIDxkaXYgaWQ9XFxcIlwiICsgdGhpcy5nZXRJZE5hbWUoJ2xnLW91dGVyJykgKyBcIlxcXCIgY2xhc3M9XFxcImxnLW91dGVyIGxnLXVzZS1jc3MzIGxnLWNzczMgbGctaGlkZS1pdGVtcyBcIiArIGFkZENsYXNzZXMgKyBcIiBcXFwiPlxcblxcbiAgICAgICAgICAgICAgPGRpdiBpZD1cXFwiXCIgKyB0aGlzLmdldElkTmFtZSgnbGctY29udGVudCcpICsgXCJcXFwiIGNsYXNzPVxcXCJsZy1jb250ZW50XFxcIj5cXG4gICAgICAgICAgICAgICAgPGRpdiBpZD1cXFwiXCIgKyB0aGlzLmdldElkTmFtZSgnbGctaW5uZXInKSArIFwiXFxcIiBjbGFzcz1cXFwibGctaW5uZXJcXFwiPlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgXCIgKyBjb250cm9scyArIFwiXFxuICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICAgICAgPGRpdiBpZD1cXFwiXCIgKyB0aGlzLmdldElkTmFtZSgnbGctdG9vbGJhcicpICsgXCJcXFwiIGNsYXNzPVxcXCJsZy10b29sYmFyIGxnLWdyb3VwXFxcIj5cXG4gICAgICAgICAgICAgICAgICAgIFwiICsgbWF4aW1pemVJY29uICsgXCJcXG4gICAgICAgICAgICAgICAgICAgIFwiICsgY2xvc2VJY29uICsgXCJcXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICAgICAgICAgICAgXCIgKyAodGhpcy5zZXR0aW5ncy5hcHBlbmRTdWJIdG1sVG8gPT09ICcubGctb3V0ZXInXHJcbiAgICAgICAgICAgID8gc3ViSHRtbENvbnRcclxuICAgICAgICAgICAgOiAnJykgKyBcIlxcbiAgICAgICAgICAgICAgICA8ZGl2IGlkPVxcXCJcIiArIHRoaXMuZ2V0SWROYW1lKCdsZy1jb21wb25lbnRzJykgKyBcIlxcXCIgY2xhc3M9XFxcImxnLWNvbXBvbmVudHNcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgXCIgKyAodGhpcy5zZXR0aW5ncy5hcHBlbmRTdWJIdG1sVG8gPT09ICcubGctc3ViLWh0bWwnXHJcbiAgICAgICAgICAgID8gc3ViSHRtbENvbnRcclxuICAgICAgICAgICAgOiAnJykgKyBcIlxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICAgICAgXCI7XHJcbiAgICAgICAgJExHKHRoaXMuc2V0dGluZ3MuY29udGFpbmVyKS5hcHBlbmQodGVtcGxhdGUpO1xyXG4gICAgICAgIGlmIChkb2N1bWVudC5ib2R5ICE9PSB0aGlzLnNldHRpbmdzLmNvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAkTEcodGhpcy5zZXR0aW5ncy5jb250YWluZXIpLmNzcygncG9zaXRpb24nLCAncmVsYXRpdmUnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vdXRlciA9IHRoaXMuZ2V0RWxlbWVudEJ5SWQoJ2xnLW91dGVyJyk7XHJcbiAgICAgICAgdGhpcy4kbGdDb21wb25lbnRzID0gdGhpcy5nZXRFbGVtZW50QnlJZCgnbGctY29tcG9uZW50cycpO1xyXG4gICAgICAgI
1HRoaXMuJGJhY2tkcm9wID0gdGhpcy5nZXRFbGVtZW50QnlJZCgnbGctYmFja2Ryb3AnKTtcclxuICAgICAgICB0aGlzLiRjb250YWluZXIgPSB0aGlzLmdldEVsZW1lbnRCeUlkKCdsZy1jb250YWluZXInKTtcclxuICAgICAgICB0aGlzLiRpbm5lciA9IHRoaXMuZ2V0RWxlbWVudEJ5SWQoJ2xnLWlubmVyJyk7XHJcbiAgICAgICAgdGhpcy4kY29udGVudCA9IHRoaXMuZ2V0RWxlbWVudEJ5SWQoJ2xnLWNvbnRlbnQnKTtcclxuICAgICAgICB0aGlzLiR0b29sYmFyID0gdGhpcy5nZXRFbGVtZW50QnlJZCgnbGctdG9vbGJhcicpO1xyXG4gICAgICAgIHRoaXMuJGJhY2tkcm9wLmNzcygndHJhbnNpdGlvbi1kdXJhdGlvbicsIHRoaXMuc2V0dGluZ3MuYmFja2Ryb3BEdXJhdGlvbiArICdtcycpO1xyXG4gICAgICAgIHZhciBvdXRlckNsYXNzTmFtZXMgPSB0aGlzLnNldHRpbmdzLm1vZGUgKyBcIiBcIjtcclxuICAgICAgICB0aGlzLm1hbmFnZVNpbmdsZVNsaWRlQ2xhc3NOYW1lKCk7XHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuZW5hYmxlRHJhZykge1xyXG4gICAgICAgICAgICBvdXRlckNsYXNzTmFtZXMgKz0gJ2xnLWdyYWIgJztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vdXRlci5hZGRDbGFzcyhvdXRlckNsYXNzTmFtZXMpO1xyXG4gICAgICAgIHRoaXMuJGlubmVyLmNzcygndHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb24nLCB0aGlzLnNldHRpbmdzLmVhc2luZyk7XHJcbiAgICAgICAgdGhpcy4kaW5uZXIuY3NzKCd0cmFuc2l0aW9uLWR1cmF0aW9uJywgdGhpcy5zZXR0aW5ncy5zcGVlZCArICdtcycpO1xyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLmRvd25sb2FkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuJHRvb2xiYXIuYXBwZW5kKFwiPGEgaWQ9XFxcIlwiICsgdGhpcy5nZXRJZE5hbWUoJ2xnLWRvd25sb2FkJykgKyBcIlxcXCIgdGFyZ2V0PVxcXCJfYmxhbmtcXFwiIHJlbD1cXFwibm9vcGVuZXJcXFwiIGFyaWEtbGFiZWw9XFxcIlwiICsgdGhpcy5zZXR0aW5ncy5zdHJpbmdzWydkb3dubG9hZCddICsgXCJcXFwiIGRvd25sb2FkIGNsYXNzPVxcXCJsZy1kb3dubG9hZCBsZy1pY29uXFxcIj48L2E+XCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNvdW50ZXIoKTtcclxuICAgICAgICAkTEcod2luZG93KS5vbihcInJlc2l6ZS5sZy5nbG9iYWxcIiArIHRoaXMubGdJZCArIFwiIG9yaWVudGF0aW9uY2hhbmdlLmxnLmdsb2JhbFwiICsgdGhpcy5sZ0lkLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLnJlZnJlc2hPblJlc2l6ZSgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuaGlkZUJhcnMoKTtcclxuICAgICAgICB0aGlzLm1hbmFnZUNsb3NlR2FsbGVyeSgpO1xyXG4gICAgICAgIHRoaXMudG9nZ2xlTWF4aW1pemUoKTtcclxuICAgICAgICB0aGlzLmluaXRNb2R1bGVzKCk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5yZWZyZXNoT25SZXNpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMubGdPcGVuZWQpIHtcclxuICAgICAgICAgICAgdmFyIGN1cnJlbnRHYWxsZXJ5SXRlbSA9IHRoaXMuZ2FsbGVyeUl0ZW1zW3RoaXMuaW5kZXhdO1xyXG4gICAgICAgICAgICB2Y
1XIgX19zbGlkZVZpZGVvSW5mbyA9IGN1cnJlbnRHYWxsZXJ5SXRlbS5fX3NsaWRlVmlkZW9JbmZvO1xyXG4gICAgICAgICAgICB0aGlzLm1lZGlhQ29udGFpbmVyUG9zaXRpb24gPSB0aGlzLmdldE1lZGlhQ29udGFpbmVyUG9zaXRpb24oKTtcclxuICAgICAgICAgICAgdmFyIF9hID0gdGhpcy5tZWRpYUNvbnRhaW5lclBvc2l0aW9uLCB0b3BfMSA9IF9hLnRvcCwgYm90dG9tID0gX2EuYm90dG9tO1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRJbWFnZVNpemUgPSB1dGlscy5nZXRTaXplKHRoaXMuaXRlbXNbdGhpcy5pbmRleF0sIHRoaXMub3V0ZXIsIHRvcF8xICsgYm90dG9tLCBfX3NsaWRlVmlkZW9JbmZvICYmIHRoaXMuc2V0dGluZ3MudmlkZW9NYXhTaXplKTtcclxuICAgICAgICAgICAgaWYgKF9fc2xpZGVWaWRlb0luZm8pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplVmlkZW9TbGlkZSh0aGlzLmluZGV4LCB0aGlzLmN1cnJlbnRJbWFnZVNpemUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnpvb21Gcm9tT3JpZ2luICYmICF0aGlzLmlzRHVtbXlJbWFnZVJlbW92ZWQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBpbWdTdHlsZSA9IHRoaXMuZ2V0RHVtbXlJbWdTdHlsZXModGhpcy5jdXJyZW50SW1hZ2VTaXplKTtcclxuICAgICAgICAgICAgICAgIHRoaXMub3V0ZXJcclxuICAgICAgICAgICAgICAgICAgICAuZmluZCgnLmxnLWN1cnJlbnQgLmxnLWR1bW15LWltZycpXHJcbiAgICAgICAgICAgICAgICAgICAgLmZpcnN0KClcclxuICAgICAgICAgICAgICAgICAgICAuYXR0cignc3R5bGUnLCBpbWdTdHlsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMuY29udGFpbmVyUmVzaXplKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5yZXNpemVWaWRlb1NsaWRlID0gZnVuY3Rpb24gKGluZGV4LCBpbWFnZVNpemUpIHtcclxuICAgICAgICB2Y
1XIgbGdWaWRlb1N0eWxlID0gdGhpcy5nZXRWaWRlb0NvbnRTdHlsZShpbWFnZVNpemUpO1xyXG4gICAgICAgIHZhciBjdXJyZW50U2xpZGUgPSB0aGlzLmdldFNsaWRlSXRlbShpbmRleCk7XHJcbiAgICAgICAgY3VycmVudFNsaWRlLmZpbmQoJy5sZy12aWRlby1jb250JykuYXR0cignc3R5bGUnLCBsZ1ZpZGVvU3R5bGUpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogVXBkYXRlIHNsaWRlcyBkeW5hbWljYWxseS5cclxuICAgICAqIEFkZCwgZWRpdCBvciBkZWxldGUgc2xpZGVzIGR5bmFtaWNhbGx5IHdoZW4gbGlnaHRHYWxsZXJ5IGlzIG9wZW5lZC5cclxuICAgICAqIE1vZGlmeSB0aGUgY3VycmVudCBnYWxsZXJ5IGl0ZW1zIGFuZCBwYXNzIGl0IHZpYSB1cGRhdGVTbGlkZXMgbWV0aG9kXHJcbiAgICAgKiBAbm90ZVxyXG4gICAgICogLSBEbyBub3QgbXV0YXRlIGV4aXN0aW5nIGxpZ2h0R2FsbGVyeSBpdGVtcyBkaXJlY3RseS5cclxuICAgICAqIC0gQWx3YXlzIHBhc3MgbmV3IGxpc3Qgb2YgZ2FsbGVyeSBpdGVtc1xyXG4gICAgICogLSBZb3UgbmVlZCB0byB0YWtlIGNhcmUgb2YgdGh1bWJuYWlscyBvdXRzaWRlIHRoZSBnYWxsZXJ5IGlmIGFueVxyXG4gICAgICogLSB1c2VyIHRoaXMgbWV0aG9kIG9ubHkgaWYgeW91IHdhbnQgdG8gdXBkYXRlIHNsaWRlcyB3aGVuIHRoZSBnYWxsZXJ5IGlzIG9wZW5lZC4gT3RoZXJ3aXNlLCB1c2UgYHJlZnJlc2goKWAgbWV0aG9kLlxyXG4gICAgICogQHBhcmFtIGl0ZW1zIEdhbGxlcnkgaXRlbXNcclxuICAgICAqIEBwYXJhbSBpbmRleCBBZnRlciB0aGUgdXBkYXRlIG9wZXJhdGlvbiwgd2hpY2ggc2xpZGUgZ2FsbGVyeSBzaG91bGQgbmF2aWdhdGUgdG9cclxuICAgICAqIEBjYXRlZ29yeSBsR1B1YmxpY01ldGhvZHNcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiBjb25zdCBwbHVnaW4gPSBsaWdodEdhbGxlcnkoKTtcclxuICAgICAqXHJcbiAgICAgKiAvLyBBZGRpbmcgc2xpZGVzIGR5bmFtaWNhbGx5XHJcbiAgICAgKiBsZXQgZ2FsbGVyeUl0ZW1zID0gW1xyXG4gICAgICogLy8gQWNjZXNzIGV4aXN0aW5nIGxpZ2h0R2FsbGVyeSBpdGVtc1xyXG4gICAgICogLy8gZ2FsbGVyeUl0ZW1zIGFyZSBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBpbnRlcm5hbGx5IGZyb20gdGhlIGdhbGxlcnkgSFRNTCBtYXJrdXBcclxuICAgICAqIC8vIG9yIGRpcmVjdGx5IGZyb20gZ2FsbGVyeUl0ZW1zIHdoZW4gZHluYW1pYyBnYWxsZXJ5IGlzIHVzZWRcclxuICAgICAqICAgLi4ucGx1Z2luLmdhbGxlcnlJdGVtcyxcclxuICAgICAqICAgICAuLi5bXHJcbiAgICAgKiAgICAgICB7XHJcbiAgICAgKiAgICAgICAgIHNyYzogJ2ltZy9pbWctMS5wbmcnLFxyXG4gICAgICogICAgICAgICAgIHRodW1iOiAnaW1nL3RodW1iMS5wbmcnLFxyXG4gICAgICogICAgICAgICB9LFxyXG4gICAgICogICAgIF0sXHJcbiAgICAgKiAgIF07XHJcbiAgICAgKiAgIHBsdWdpbi51cGRhdGVTbGlkZXMoXHJcbiAgICAgKiAgICAgZ2FsbGVyeUl0ZW1zLFxyXG4gICAgICogICAgIHBsdWdpbi5pbmRleCxcclxuICAgICAqICAgKTtcclxuICAgICAqXHJcbiAgICAgKlxyXG4gICAgICogLy8gUmVtb3ZlIHNsaWRlcyBkeW5hbWljYWxseVxyXG4gICAgICogZ2FsbGVyeUl0ZW1zID0gSlNPTi5wYXJzZShcclxuICAgICAqICAgSlNPTi5zdHJpbmdpZnkodXBkYXRlU2xpZGVJbnN0YW5jZS5nYWxsZXJ5SXRlbXMpLFxyXG4gICAgICogKTtcclxuICAgICAqIGdhbGxlcnlJdGVtcy5zaGlmdCgpO1xyXG4gICAgICogdXBkYXRlU2xpZGVJbnN0YW5jZS51cGRhdGVTbGlkZXMoZ2FsbGVyeUl0ZW1zLCAxKTtcclxuICAgICAqIEBzZWUgPGEgaHJlZj1cIi9kZW1vcy91cGRhdGUtc2xpZGVzL1wiPkRlbW88L2E+XHJcbiAgICAgKi9cclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUudXBkYXRlU2xpZGVzID0gZnVuY3Rpb24gKGl0ZW1zLCBpbmRleCkge1xyXG4gICAgICAgIGlmICh0aGlzLmluZGV4ID4gaXRlbXMubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgICAgICB0aGlzLmluZGV4ID0gaXRlbXMubGVuZ3RoIC0gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgICAgICB0aGlzLmluZGV4ID0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFpdGVtcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5jbG9zZUdhbGxlcnkoKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2Y
1XIgY3VycmVudFNyYyA9IHRoaXMuZ2FsbGVyeUl0ZW1zW2luZGV4XS5zcmM7XHJcbiAgICAgICAgdGhpcy5nYWxsZXJ5SXRlbXMgPSBpdGVtcztcclxuICAgICAgICB0aGlzLnVwZGF0ZUNvbnRyb2xzKCk7XHJcbiAgICAgICAgdGhpcy4kaW5uZXIuZW1wdHkoKTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRJdGVtc0luRG9tID0gW107XHJcbiAgICAgICAgdmFyIF9pbmRleCA9IDA7XHJcbiAgICAgICAgLy8gRmluZCB0aGUgY3VycmVudCBpbmRleCBiYXNlZCBvbiBzb3VyY2UgdmFsdWUgb2YgdGhlIHNsaWRlXHJcbiAgICAgICAgdGhpcy5nYWxsZXJ5SXRlbXMuc29tZShmdW5jdGlvbiAoZ2FsbGVyeUl0ZW0sIGl0ZW1JbmRleCkge1xyXG4gICAgICAgICAgICBpZiAoZ2FsbGVyeUl0ZW0uc3JjID09PSBjdXJyZW50U3JjKSB7XHJcbiAgICAgICAgICAgICAgICBfaW5kZXggPSBpdGVtSW5kZXg7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50SXRlbXNJbkRvbSA9IHRoaXMub3JnYW5pemVTbGlkZUl0ZW1zKF9pbmRleCwgLTEpO1xyXG4gICAgICAgIHRoaXMubG9hZENvbnRlbnQoX2luZGV4LCB0cnVlKTtcclxuICAgICAgICB0aGlzLmdldFNsaWRlSXRlbShfaW5kZXgpLmFkZENsYXNzKCdsZy1jdXJyZW50Jyk7XHJcbiAgICAgICAgdGhpcy5pbmRleCA9IF9pbmRleDtcclxuICAgICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRDb3VudGVyKF9pbmRleCk7XHJcbiAgICAgICAgdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMudXBkYXRlU2xpZGVzKTtcclxuICAgIH07XHJcbiAgICAvLyBHZXQgZ2FsbGVyeSBpdGVtcyBiYXNlZCBvbiBtdWx0aXBsZSBjb25kaXRpb25zXHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmdldEl0ZW1zID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIEdhbGxlcnkgaXRlbXNcclxuICAgICAgICB0aGlzLml0ZW1zID0gW107XHJcbiAgICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLmR5bmFtaWMpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Muc2VsZWN0b3IgPT09ICd0aGlzJykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtcy5wdXNoKHRoaXMuZWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuc2V0dGluZ3Muc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5zZXR0aW5ncy5zZWxlY3RvciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5zZWxlY3RXaXRoaW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdFdpdGhpbiA9ICRMRyh0aGlzLnNldHRpbmdzLnNlbGVjdFdpdGhpbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXRlbXMgPSBzZWxlY3RXaXRoaW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maW5kKHRoaXMuc2V0dGluZ3Muc2VsZWN0b3IpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLml0ZW1zID0gdGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKHRoaXMuc2V0dGluZ3Muc2VsZWN0b3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXRlbXMgPSB0aGlzLnNldHRpbmdzLnNlbGVjdG9yO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtcyA9IHRoaXMuZWwuY2hpbGRyZW47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHV0aWxzLmdldER5bmFtaWNPcHRpb25zKHRoaXMuaXRlbXMsIHRoaXMuc2V0dGluZ3MuZXh0cmFQcm9wcywgdGhpcy5zZXR0aW5ncy5nZXRDYXB0aW9uRnJvbVRpdGxlT3JBbHQsIHRoaXMuc2V0dGluZ3MuZXhUaHVtYkltYWdlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLmR5bmFtaWNFbCB8fCBbXTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5zaG91bGRIaWRlU2Nyb2xsYmFyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiAodGhpcy5zZXR0aW5ncy5oaWRlU2Nyb2xsYmFyICYmXHJcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkgPT09IHRoaXMuc2V0dGluZ3MuY29udGFpbmVyKTtcclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmhpZGVTY3JvbGxiYXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZEhpZGVTY3JvbGxiYXIoKSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuYm9keVBhZGRpbmdSaWdodCA9IHBhcnNlRmxvYXQoJExHKCdib2R5Jykuc3R5bGUoKS5wYWRkaW5nUmlnaHQpO1xyXG4gICAgICAgIHZhciBib2R5UmVjdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICB2Y
1XIgc2Nyb2xsYmFyV2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aCAtIGJvZHlSZWN0LndpZHRoO1xyXG4gICAgICAgICRMRyhkb2N1bWVudC5ib2R5KS5jc3MoJ3BhZGRpbmctcmlnaHQnLCBzY3JvbGxiYXJXaWR0aCArIHRoaXMuYm9keVBhZGRpbmdSaWdodCArICdweCcpO1xyXG4gICAgICAgICRMRyhkb2N1bWVudC5ib2R5KS5hZGRDbGFzcygnbGctb3ZlcmxheS1vcGVuJyk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5yZXNldFNjcm9sbEJhciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkSGlkZVNjcm9sbGJhcigpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgJExHKGRvY3VtZW50LmJvZHkpLmNzcygncGFkZGluZy1yaWdodCcsIHRoaXMuYm9keVBhZGRpbmdSaWdodCArICdweCcpO1xyXG4gICAgICAgICRMRyhkb2N1bWVudC5ib2R5KS5yZW1vdmVDbGFzcygnbGctb3ZlcmxheS1vcGVuJyk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBPcGVuIGxpZ2h0R2FsbGVyeS5cclxuICAgICAqIE9wZW4gZ2FsbGVyeSB3aXRoIHNwZWNpZmljIHNsaWRlIGJ5IHBhc3NpbmcgaW5kZXggb2YgdGhlIHNsaWRlIGFzIHBhcmFtZXRlci5cclxuICAgICAqIEBjYXRlZ29yeSBsR1B1YmxpY01ldGhvZHNcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleCAgLSBpbmRleCBvZiB0aGUgc2xpZGVcclxuICAgICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnQgLSBXaGljaCBpbWFnZSBsaWdodEdhbGxlcnkgc2hvdWxkIHpvb20gZnJvbVxyXG4gICAgICpcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiBjb25zdCAkZHluYW1pY0dhbGxlcnkgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHluYW1pYy1nYWxsZXJ5LWRlbW8nKTtcclxuICAgICAqIGNvbnN0IGR5bmFtaWNHYWxsZXJ5ID0gbGlnaHRHYWxsZXJ5KCRkeW5hbWljR2FsbGVyeSwge1xyXG4gICAgICogICAgIGR5bmFtaWM6IHRydWUsXHJcbiAgICAgKiAgICAgZHluYW1pY0VsOiBbXHJcbiAgICAgKiAgICAgICAgIHtcclxuICAgICAqICAgICAgICAgICAgICBzcmM6ICdpbWcvMS5qcGcnLFxyXG4gICAgICogICAgICAgICAgICAgIHRodW1iOiAnaW1nL3RodW1iLTEuanBnJyxcclxuICAgICAqICAgICAgICAgICAgICBzdWJIdG1sOiAnPGg0PkltYWdlIDEgdGl0bGU8L2g0PjxwPkltYWdlIDEgZGVzY3JpcHRpb25zLjwvcD4nLFxyXG4gICAgICogICAgICAgICB9LFxyXG4gICAgICogICAgICAgICAuLi5cclxuICAgICAqICAgICBdLFxyXG4gICAgICogfSk7XHJcbiAgICAgKiAkZHluYW1pY0dhbGxlcnkuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgKiAgICAgLy8gU3RhcnRzIHdpdGggdGhpcmQgaXRlbS4oT3B0aW9uYWwpLlxyXG4gICAgICogICAgIC8vIFRoaXMgaXMgdXNlZnVsIGlmIHlvdSB3YW50IHVzZSBkeW5hbWljIG1vZGUgd2l0aFxyXG4gICAgICogICAgIC8vIGN1c3RvbSB0aHVtYm5haWxzICh0aHVtYm5haWxzIG91dHNpZGUgZ2FsbGVyeSksXHJcbiAgICAgKiAgICAgZHluYW1pY0dhbGxlcnkub3BlbkdhbGxlcnkoMik7XHJcbiAgICAgKiB9KTtcclxuICAgICAqXHJcbiAgICAgKi9cclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUub3BlbkdhbGxlcnkgPSBmdW5jdGlvbiAoaW5kZXgsIGVsZW1lbnQpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmIChpbmRleCA9PT0gdm9pZCAwKSB7IGluZGV4ID0gdGhpcy5zZXR0aW5ncy5pbmRleDsgfVxyXG4gICAgICAgIC8vIHByZXZlbnQgYWNjaWRlbnRhbCBkb3VibGUgZXhlY3V0aW9uXHJcbiAgICAgICAgaWYgKHRoaXMubGdPcGVuZWQpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB0aGlzLmxnT3BlbmVkID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLm91dGVyLnJlbW92ZUNsYXNzKCdsZy1oaWRlLWl0ZW1zJyk7XHJcbiAgICAgICAgdGhpcy5oaWRlU2Nyb2xsYmFyKCk7XHJcbiAgICAgICAgLy8gQWRkIGRpc3BsYXkgYmxvY2ssIGJ1dCBzdGlsbCBoYXMgb3BhY2l0eSAwXHJcbiAgICAgICAgdGhpcy4kY29udGFpbmVyLmFkZENsYXNzKCdsZy1zaG93Jyk7XHJcbiAgICAgICAgdmFyIGl0ZW1zVG9CZUluc2VydGVkVG9Eb20gPSB0aGlzLmdldEl0ZW1zVG9CZUluc2VydGVkVG9Eb20oaW5kZXgsIGluZGV4KTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRJdGVtc0luRG9tID0gaXRlbXNUb0JlSW5zZXJ0ZWRUb0RvbTtcclxuICAgICAgICB2YXIgaXRlbXMgPSAnJztcclxuICAgICAgICBpdGVtc1RvQmVJbnNlcnRlZFRvRG9tLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHtcclxuICAgICAgICAgICAgaXRlbXMgPSBpdGVtcyArIChcIjxkaXYgaWQ9XFxcIlwiICsgaXRlbSArIFwiXFxcIiBjbGFzcz1cXFwibGctaXRlbVxcXCI+PC9kaXY+XCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuJGlubmVyLmFwcGVuZChpdGVtcyk7XHJcbiAgICAgICAgdGhpcy5hZGRIdG1sKGluZGV4KTtcclxuICAgICAgICB2Y
1XIgdHJhbnNmb3JtID0gJyc7XHJcbiAgICAgICAgdGhpcy5tZWRpYUNvbnRhaW5lclBvc2l0aW9uID0gdGhpcy5nZXRNZWRpYUNvbnRhaW5lclBvc2l0aW9uKCk7XHJcbiAgICAgICAgdmFyIF9hID0gdGhpcy5tZWRpYUNvbnRhaW5lclBvc2l0aW9uLCB0b3AgPSBfYS50b3AsIGJvdHRvbSA9IF9hLmJvdHRvbTtcclxuICAgICAgICBpZiAoIXRoaXMuc2V0dGluZ3MuYWxsb3dNZWRpYU92ZXJsYXApIHtcclxuICAgICAgICAgICAgdGhpcy5zZXRNZWRpYUNvbnRhaW5lclBvc2l0aW9uKHRvcCwgYm90dG9tKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIF9fc2xpZGVWaWRlb0luZm8gPSB0aGlzLmdhbGxlcnlJdGVtc1tpbmRleF0uX19zbGlkZVZpZGVvSW5mbztcclxuICAgICAgICBpZiAodGhpcy56b29tRnJvbU9yaWdpbiAmJiBlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEltYWdlU2l6ZSA9IHV0aWxzLmdldFNpemUoZWxlbWVudCwgdGhpcy5vdXRlciwgdG9wICsgYm90dG9tLCBfX3NsaWRlVmlkZW9JbmZvICYmIHRoaXMuc2V0dGluZ3MudmlkZW9NYXhTaXplKTtcclxuICAgICAgICAgICAgdHJhbnNmb3JtID0gdXRpbHMuZ2V0VHJhbnNmb3JtKGVsZW1lbnQsIHRoaXMub3V0ZXIsIHRvcCwgYm90dG9tLCB0aGlzLmN1cnJlbnRJbWFnZVNpemUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMuem9vbUZyb21PcmlnaW4gfHwgIXRyYW5zZm9ybSkge1xyXG4gICAgICAgICAgICB0aGlzLm91dGVyLmFkZENsYXNzKHRoaXMuc2V0dGluZ3Muc3RhcnRDbGFzcyk7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0U2xpZGVJdGVtKGluZGV4KS5yZW1vdmVDbGFzcygnbGctY29tcGxldGUnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHRpbWVvdXQgPSB0aGlzLnNldHRpbmdzLnpvb21Gcm9tT3JpZ2luXHJcbiAgICAgICAgICAgID8gMTAwXHJcbiAgICAgICAgICAgIDogdGhpcy5zZXR0aW5ncy5iYWNrZHJvcER1cmF0aW9uO1xyXG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5vdXRlci5hZGRDbGFzcygnbGctY29tcG9uZW50cy1vcGVuJyk7XHJcbiAgICAgICAgfSwgdGltZW91dCk7XHJcbiAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4O1xyXG4gICAgICAgIHRoaXMuTEdlbC50cmlnZ2VyKGxHRXZlbnRzLmJlZm9yZU9wZW4pO1xyXG4gICAgICAgIC8vIGFkZCBjbGFzcyBsZy1jdXJyZW50IHRvIHJlbW92ZSBpbml0aWFsIHRyYW5zaXRpb25cclxuICAgICAgICB0aGlzLmdldFNsaWRlSXRlbShpbmRleCkuYWRkQ2xhc3MoJ2xnLWN1cnJlbnQnKTtcclxuICAgICAgICB0aGlzLmxHYWxsZXJ5T24gPSBmYWxzZTtcclxuICAgICAgICAvLyBTdG9yZSB0aGUgY3VycmVudCBzY3JvbGwgdG9wIHZhbHVlIHRvIHNjcm9sbCBiYWNrIGFmdGVyIGNsb3NpbmcgdGhlIGdhbGxlcnkuLlxyXG4gICAgICAgIHRoaXMucHJldlNjcm9sbFRvcCA9ICRM
1Ryh3aW5kb3cpLnNjcm9sbFRvcCgpO1xyXG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBOZWVkIHRvIGNoZWNrIGJvdGggem9vbUZyb21PcmlnaW4gYW5kIHRyYW5zZm9ybSB2YWx1ZXMgYXMgd2UgbmVlZCB0byBzZXQgc2V0IHRoZVxyXG4gICAgICAgICAgICAvLyBkZWZhdWx0IG9wZW5pbmcgYW5pbWF0aW9uIGlmIHVzZXIgbWlzc2VkIHRvIGFkZCB0aGUgbGctc2l6ZSBhdHRyaWJ1dGVcclxuICAgICAgICAgICAgaWYgKF90aGlzLnpvb21Gcm9tT3JpZ2luICYmIHRyYW5zZm9ybSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRTbGlkZV8xID0gX3RoaXMuZ2V0U2xpZGVJdGVtKGluZGV4KTtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRTbGlkZV8xLmNzcygndHJhbnNmb3JtJywgdHJhbnNmb3JtKTtcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTbGlkZV8xXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnbGctc3RhcnQtcHJvZ3Jlc3MgbGctc3RhcnQtZW5kLXByb2dyZXNzJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmNzcygndHJhbnNpdGlvbi1kdXJhdGlvbicsIF90aGlzLnNldHRpbmdzLnN0YXJ0QW5pbWF0aW9uRHVyYXRpb24gKyAnbXMnKTtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5vdXRlci5hZGRDbGFzcygnbGctem9vbS1mcm9tLWltYWdlJyk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTbGlkZV8xLmNzcygndHJhbnNmb3JtJywgJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJyk7XHJcbiAgICAgICAgICAgICAgICB9LCAxMDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuJGJhY2tkcm9wLmFkZENsYXNzKCdpbicpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuJGNvbnRhaW5lci5hZGRDbGFzcygnbGctc2hvdy1pbicpO1xyXG4gICAgICAgICAgICB9LCAxMCk7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKF90aGlzLnNldHRpbmdzLnRyYXBGb2N1cyAmJlxyXG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkgPT09IF90aGlzLnNldHRpbmdzLmNvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnRyYXBGb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBfdGhpcy5zZXR0aW5ncy5iYWNrZHJvcER1cmF0aW9uICsgNTApO1xyXG4gICAgICAgICAgICAvLyBsZy12aXNpYmxlIGNsYXNzIHJlc2V0cyBnYWxsZXJ5IG9wYWNpdHkgdG8gMVxyXG4gICAgICAgICAgICBpZiAoIV90aGlzLnpvb21Gcm9tT3JpZ2luIHx8ICF0cmFuc2Zvcm0pIHtcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLmFkZENsYXNzKCdsZy12aXNpYmxlJyk7XHJcbiAgICAgICAgICAgICAgICB9LCBfdGhpcy5zZXR0aW5ncy5iYWNrZHJvcER1cmF0aW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBpbml0aWF0ZSBzbGlkZSBmdW5jdGlvblxyXG4gICAgICAgICAgICBfdGhpcy5zbGlkZShpbmRleCwgZmFsc2UsIGZhbHNlLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIF90aGlzLkxHZWwudHJpZ2dlcihsR0V2ZW50cy5hZnRlck9wZW4pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGlmIChkb2N1bWVudC5ib2R5ID09PSB0aGlzLnNldHRpbmdzLmNvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAkTEcoJ2h0bWwnKS5hZGRDbGFzcygnbGctb24nKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBOb3RlIC0gQ2hhbmdpbmcgdGhlIHBvc2l0aW9uIG9mIHRoZSBtZWRpYSBvbiBldmVyeSBzbGlkZSB0cmFuc2l0aW9uIGNyZWF0ZXMgYSBmbGlja2VyaW5nIGVmZmVjdC5cclxuICAgICAqIFRoZXJlZm9yZSzCoFRoZSBoZWlnaHQgb2YgdGhlIGNhcHRpb24gaXMgY2FsY3VsYXRlZCBkeW5hbWljYWxseSwgb25seSBvbmNlIGJhc2VkIG9uIHRoZSBmaXJzdCBzbGlkZSBjYXB0aW9uLlxyXG4gICAgICogaWYgeW91IGhhdmUgZHluYW1pYyBjYXB0aW9ucyBmb3IgZWFjaCBtZWRpYSxcclxuICAgICAqIHlvdSBjYW4gcHJvdmlkZSBhbiBhcHByb3ByaWF0ZSBoZWlnaHQgZm9yIHRoZSBjYXB0aW9ucyB2aWEgYWxsb3dNZWRpYU92ZXJsYXAgb3B0aW9uXHJcbiAgICAgKi9cclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuZ2V0TWVkaWFDb250YWluZXJQb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5hbGxvd01lZGlhT3ZlcmxhcCkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgICAgICAgICAgYm90dG9tOiAwLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICB2Y
1XIgdG9wID0gdGhpcy4kdG9vbGJhci5nZXQoKS5jbGllbnRIZWlnaHQgfHwgMDtcclxuICAgICAgICB2YXIgc3ViSHRtbCA9IHRoaXMub3V0ZXIuZmluZCgnLmxnLWNvbXBvbmVudHMgLmxnLXN1Yi1odG1sJykuZ2V0KCk7XHJcbiAgICAgICAgdmFyIGNhcHRpb25IZWlnaHQgPSB0aGlzLnNldHRpbmdzLmRlZmF1bHRDYXB0aW9uSGVpZ2h0IHx8XHJcbiAgICAgICAgICAgIChzdWJIdG1sICYmIHN1Ykh0bWwuY2xpZW50SGVpZ2h0KSB8fFxyXG4gICAgICAgICAgICAwO1xyXG4gICAgICAgIHZhciB0aHVtYkNvbnRhaW5lciA9IHRoaXMub3V0ZXIuZmluZCgnLmxnLXRodW1iLW91dGVyJykuZ2V0KCk7XHJcbiAgICAgICAgdmFyIHRodW1iSGVpZ2h0ID0gdGh1bWJDb250YWluZXIgPyB0aHVtYkNvbnRhaW5lci5jbGllbnRIZWlnaHQgOiAwO1xyXG4gICAgICAgIHZhciBib3R0b20gPSB0aHVtYkhlaWdodCArIGNhcHRpb25IZWlnaHQ7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdG9wOiB0b3AsXHJcbiAgICAgICAgICAgIGJvdHRvbTogYm90dG9tLFxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5zZXRNZWRpYUNvbnRhaW5lclBvc2l0aW9uID0gZnVuY3Rpb24gKHRvcCwgYm90dG9tKSB7XHJcbiAgICAgICAgaWYgKHRvcCA9PT0gdm9pZCAwKSB7IHRvcCA9IDA7IH1cclxuICAgICAgICBpZiAoYm90dG9tID09PSB2b2lkIDApIHsgYm90dG9tID0gMDsgfVxyXG4gICAgICAgIHRoaXMuJGNvbnRlbnQuY3NzKCd0b3AnLCB0b3AgKyAncHgnKS5jc3MoJ2JvdHRvbScsIGJvdHRvbSArICdweCcpO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuaGlkZUJhcnMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAvLyBIaWRlIGNvbnRyb2xsZXJzIGlmIG1vdXNlIGRvZXNuJ3QgbW92ZSBmb3Igc29tZSBwZXJpb2RcclxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLWhpZGUtaXRlbXMnKTtcclxuICAgICAgICAgICAgaWYgKF90aGlzLnNldHRpbmdzLmhpZGVCYXJzRGVsYXkgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5vdXRlci5vbignbW91c2Vtb3ZlLmxnIGNsaWNrLmxnIHRvdWNoc3RhcnQubGcnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLWhpZGUtaXRlbXMnKTtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3RoaXMuaGlkZUJhclRpbWVvdXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRpbWVvdXQgd2lsbCBiZSBjbGVhcmVkIG9uIGVhY2ggc2xpZGUgbW92ZW1lbnQgYWxzb1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmhpZGVCYXJUaW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLmFkZENsYXNzKCdsZy1oaWRlLWl0ZW1zJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgX3RoaXMuc2V0dGluZ3MuaGlkZUJhcnNEZWxheSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLnRyaWdnZXIoJ21vdXNlbW92ZS5sZycpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgdGhpcy5zZXR0aW5ncy5zaG93QmFyc0FmdGVyKTtcclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmluaXRQaWN0dXJlRmlsbCA9IGZ1bmN0aW9uICgkaW1nKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Muc3VwcG9ydExlZ2FjeUJyb3dzZXIpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHBpY3R1cmVmaWxsKHtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50czogWyRpbWcuZ2V0KCldLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignbGlnaHRHYWxsZXJ5IDotIElmIHlvdSB3YW50IHNyY3NldCBvciBwaWN0dXJlIHRhZyB0byBiZSBzdXBwb3J0ZWQgZm9yIG9sZGVyIGJyb3dzZXIgcGxlYXNlIGluY2x1ZGUgcGljdHVyZWZpbCBqYXZhc2NyaXB0IGxpYnJhcnkgaW4geW91ciBkb2N1bWVudC4nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqICBAZGVzYyBDcmVhdGUgaW1hZ2UgY291bnRlclxyXG4gICAgICogIEV4OiAxLzEwXHJcbiAgICAgKi9cclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuY291bnRlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5jb3VudGVyKSB7XHJcbiAgICAgICAgICAgIHZhciBjb3VudGVySHRtbCA9IFwiPGRpdiBjbGFzcz1cXFwibGctY291bnRlclxcXCIgcm9sZT1cXFwic3RhdHVzXFxcIiBhcmlhLWxpdmU9XFxcInBvbGl0ZVxcXCI+XFxuICAgICAgICAgICAgICAgIDxzcGFuIGlkPVxcXCJcIiArIHRoaXMuZ2V0SWROYW1lKCdsZy1jb3VudGVyLWN1cnJlbnQnKSArIFwiXFxcIiBjbGFzcz1cXFwibGctY291bnRlci1jdXJyZW50XFxcIj5cIiArICh0aGlzLmluZGV4ICsgMSkgKyBcIiA8L3NwYW4+IC9cXG4gICAgICAgICAgICAgICAgPHNwYW4gaWQ9XFxcIlwiICsgdGhpcy5nZXRJZE5hbWUoJ2xnLWNvdW50ZXItYWxsJykgKyBcIlxcXCIgY2xhc3M9XFxcImxnLWNvdW50ZXItYWxsXFxcIj5cIiArIHRoaXMuZ2FsbGVyeUl0ZW1zLmxlbmd0aCArIFwiIDwvc3Bhbj48L2Rpdj5cIjtcclxuICAgICAgICAgICAgdGhpcy5vdXRlci5maW5kKHRoaXMuc2V0dGluZ3MuYXBwZW5kQ291bnRlclRvKS5hcHBlbmQoY291bnRlckh0bWwpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqICBAZGVzYyBhZGQgc3ViLWh0bWwgaW50byB0aGUgc2xpZGVcclxuICAgICAqICBAcGFyYW0ge051bWJlcn0gaW5kZXggLSBpbmRleCBvZiB0aGUgc2xpZGVcclxuICAgICAqL1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5hZGRIdG1sID0gZnVuY3Rpb24gKGluZGV4KSB7XHJcbiAgICAgICAgdmFyIHN1Ykh0bWw7XHJcbiAgICAgICAgdmFyIHN1Ykh0bWxVcmw7XHJcbiAgICAgICAgaWYgKHRoaXMuZ2FsbGVyeUl0ZW1zW2luZGV4XS5zdWJIdG1sVXJsKSB7X
1HJcbiAgICAgICAgICAgIHN1Ykh0bWxVcmwgPSB0aGlzLmdhbGxlcnlJdGVtc1tpbmRleF0uc3ViSHRtbFVybDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHN1Ykh0bWwgPSB0aGlzLmdhbGxlcnlJdGVtc1tpbmRleF0uc3ViSHRtbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFzdWJIdG1sVXJsKSB7XHJcbiAgICAgICAgICAgIGlmIChzdWJIdG1sKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBnZXQgZmlyc3QgbGV0dGVyIG9mIHN1Yi1odG1sXHJcbiAgICAgICAgICAgICAgICAvLyBpZiBmaXJzdCBsZXR0ZXIgc3RhcnRzIHdpdGggLiBvciAjIGdldCB0aGUgaHRtbCBmb3JtIHRoZSBqUXVlcnkgb2JqZWN0XHJcbiAgICAgICAgICAgICAgICB2YXIgZkwgPSBzdWJIdG1sLnN1YnN0cmluZygwLCAxKTtcclxuICAgICAgICAgICAgICAgIGlmIChmTCA9PT0gJy4nIHx8IGZMID09PSAnIycpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5zdWJIdG1sU2VsZWN0b3JSZWxhdGl2ZSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAhdGhpcy5zZXR0aW5ncy5keW5hbWljKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1Ykh0bWwgPSAkTEcodGhpcy5pdGVtcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5lcShpbmRleClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maW5kKHN1Ykh0bWwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZmlyc3QoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmh0bWwoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1Ykh0bWwgPSAkTEcoc3ViSHRtbCkuZmlyc3QoKS5odG1sKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc3ViSHRtbCA9ICcnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLmFwcGVuZFN1Ykh0bWxUbyAhPT0gJy5sZy1pdGVtJykge1xyXG4gICAgICAgICAgICBpZiAoc3ViSHRtbFVybCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vdXRlci5maW5kKCcubGctc3ViLWh0bWwnKS5sb2FkKHN1Ykh0bWxVcmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vdXRlci5maW5kKCcubGctc3ViLWh0bWwnKS5odG1sKHN1Ykh0bWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2Y
1XIgY3VycmVudFNsaWRlID0gJExHKHRoaXMuZ2V0U2xpZGVJdGVtSWQoaW5kZXgpKTtcclxuICAgICAgICAgICAgaWYgKHN1Ykh0bWxVcmwpIHtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRTbGlkZS5sb2FkKHN1Ykh0bWxVcmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudFNsaWRlLmFwcGVuZChcIjxkaXYgY2xhc3M9XFxcImxnLXN1Yi1odG1sXFxcIj5cIiArIHN1Ykh0bWwgKyBcIjwvZGl2PlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBBZGQgbGctZW1wdHktaHRtbCBjbGFzcyBpZiB0aXRsZSBkb2Vzbid0IGV4aXN0XHJcbiAgICAgICAgaWYgKHR5cGVvZiBzdWJIdG1sICE9PSAndW5kZWZpbmVkJyAmJiBzdWJIdG1sICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIGlmIChzdWJIdG1sID09PSAnJykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vdXRlclxyXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKHRoaXMuc2V0dGluZ3MuYXBwZW5kU3ViSHRtbFRvKVxyXG4gICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnbGctZW1wdHktaHRtbCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vdXRlclxyXG4gICAgICAgICAgICAgICAgICAgIC5maW5kKHRoaXMuc2V0dGluZ3MuYXBwZW5kU3ViSHRtbFRvKVxyXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnbGctZW1wdHktaHRtbCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuTEdlbC50cmlnZ2VyKGxHRXZlbnRzLmFmdGVyQXBwZW5kU3ViSHRtbCwge1xyXG4gICAgICAgICAgICBpbmRleDogaW5kZXgsXHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiAgQGRlc2MgUHJlbG9hZCBzbGlkZXNcclxuICAgICAqICBAcGFyYW0ge051bWJlcn0gaW5kZXggLSBpbmRleCBvZiB0aGUgc2xpZGVcclxuICAgICAqIEB0b2RvIHByZWxvYWQgbm90IHdvcmtpbmcgZm9yIHRoZSBmaXJzdCBzbGlkZSwgQWxzbywgc2hvdWxkIHdvcmsgZm9yIHRoZSBmaXJzdCBhbmQgbGFzdCBzbGlkZSBhcyB3ZWxsXHJcbiAgICAgKi9cclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUucHJlbG9hZCA9IGZ1bmN0aW9uIChpbmRleCkge1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IHRoaXMuc2V0dGluZ3MucHJlbG9hZDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChpID49IHRoaXMuZ2FsbGVyeUl0ZW1zLmxlbmd0aCAtIGluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmxvYWRDb250ZW50KGluZGV4ICsgaSwgZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKHZhciBqID0gMTsgaiA8PSB0aGlzLnNldHRpbmdzLnByZWxvYWQ7IGorKykge1xyXG4gICAgICAgICAgICBpZiAoaW5kZXggLSBqIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5sb2FkQ29udGVudChpbmRleCAtIGosIGZhbHNlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5nZXREdW1teUltZ1N0eWxlcyA9IGZ1bmN0aW9uIChpbWFnZVNpemUpIHtcclxuICAgICAgICBpZiAoIWltYWdlU2l6ZSlcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIHJldHVybiBcIndpZHRoOlwiICsgaW1hZ2VTaXplLndpZHRoICsgXCJweDtcXG4gICAgICAgICAgICAgICAgbWFyZ2luLWxlZnQ6IC1cIiArIGltYWdlU2l6ZS53aWR0aCAvIDIgKyBcInB4O1xcbiAgICAgICAgICAgICAgICBtYXJnaW4tdG9wOiAtXCIgKyBpbWFnZVNpemUuaGVpZ2h0IC8gMiArIFwicHg7XFxuICAgICAgICAgICAgICAgIGhlaWdodDpcIiArIGltYWdlU2l6ZS5oZWlnaHQgKyBcInB4XCI7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5nZXRWaWRlb0NvbnRTdHlsZSA9IGZ1bmN0aW9uIChpbWFnZVNpemUpIHtcclxuICAgICAgICBpZiAoIWltYWdlU2l6ZSlcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIHJldHVybiBcIndpZHRoOlwiICsgaW1hZ2VTaXplLndpZHRoICsgXCJweDtcXG4gICAgICAgICAgICAgICAgaGVpZ2h0OlwiICsgaW1hZ2VTaXplLmhlaWdodCArIFwicHhcIjtcclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmdldER1bW15SW1hZ2VDb250ZW50ID0gZnVuY3Rpb24gKCRjdXJyZW50U2xpZGUsIGluZGV4LCBhbHQpIHtcclxuICAgICAgICB2Y
1XIgJGN1cnJlbnRJdGVtO1xyXG4gICAgICAgIGlmICghdGhpcy5zZXR0aW5ncy5keW5hbWljKSB7XHJcbiAgICAgICAgICAgICRjdXJyZW50SXRlbSA9ICRMRyh0aGlzLml0ZW1zKS5lcShpbmRleCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICgkY3VycmVudEl0ZW0pIHtcclxuICAgICAgICAgICAgdmFyIF9kdW1teUltZ1NyYyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLmV4VGh1bWJJbWFnZSkge1xyXG4gICAgICAgICAgICAgICAgX2R1bW15SW1nU3JjID0gJGN1cnJlbnRJdGVtLmZpbmQoJ2ltZycpLmZpcnN0KCkuYXR0cignc3JjJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfZHVtbXlJbWdTcmMgPSAkY3VycmVudEl0ZW0uYXR0cih0aGlzLnNldHRpbmdzLmV4VGh1bWJJbWFnZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCFfZHVtbXlJbWdTcmMpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XHJcbiAgICAgICAgICAgIHZhciBpbWdTdHlsZSA9IHRoaXMuZ2V0RHVtbXlJbWdTdHlsZXModGhpcy5jdXJyZW50SW1hZ2VTaXplKTtcclxuICAgICAgICAgICAgdmFyIGR1bW15SW1nQ29udGVudCA9IFwiPGltZyBcIiArIGFsdCArIFwiIHN0eWxlPVxcXCJcIiArIGltZ1N0eWxlICsgXCJcXFwiIGNsYXNzPVxcXCJsZy1kdW1teS1pbWdcXFwiIHNyYz1cXFwiXCIgKyBfZHVtbXlJbWdTcmMgKyBcIlxcXCIgLz5cIjtcclxuICAgICAgICAgICAgJGN1cnJlbnRTbGlkZS5hZGRDbGFzcygnbGctZmlyc3Qtc2xpZGUnKTtcclxuICAgICAgICAgICAgdGhpcy5vdXRlci5hZGRDbGFzcygnbGctZmlyc3Qtc2xpZGUtbG9hZGluZycpO1xyXG4gICAgICAgICAgICByZXR1cm4gZHVtbXlJbWdDb250ZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gJyc7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5zZXRJbWdNYXJrdXAgPSBmdW5jdGlvbiAoc3JjLCAkY3VycmVudFNsaWRlLCBpbmRleCkge1xyXG4gICAgICAgIHZhciBjdXJyZW50R2FsbGVyeUl0ZW0gPSB0aGlzLmdhbGxlcnlJdGVtc1tpbmRleF07XHJcbiAgICAgICAgdmFyIGFsdCA9IGN1cnJlbnRHYWxsZXJ5SXRlbS5hbHQsIHNyY3NldCA9IGN1cnJlbnRHYWxsZXJ5SXRlbS5zcmNzZXQsIHNpemVzID0gY3VycmVudEdhbGxlcnlJdGVtLnNpemVzLCBzb3VyY2VzID0gY3VycmVudEdhbGxlcnlJdGVtLnNvdXJjZXM7XHJcbiAgICAgICAgLy8gVXNlIHRoZSB0aHVtYm5haWwgYXMgZHVtbXkgaW1hZ2Ugd2hpY2ggd2lsbCBiZSByZXNpemVkIHRvIGFjdHVhbCBpbWFnZSBzaXplIGFuZFxyXG4gICAgICAgIC8vIGRpc3BsYXllZCBvbiB0b3Agb2YgYWN0dWFsIGltYWdlXHJcbiAgICAgICAgdmFyIGltZ0NvbnRlbnQgPSAnJztcclxuICAgICAgICB2Y
1XIgYWx0QXR0ciA9IGFsdCA/ICdhbHQ9XCInICsgYWx0ICsgJ1wiJyA6ICcnO1xyXG4gICAgICAgIGlmICh0aGlzLmlzRmlyc3RTbGlkZVdpdGhab29tQW5pbWF0aW9uKCkpIHtcclxuICAgICAgICAgICAgaW1nQ29udGVudCA9IHRoaXMuZ2V0RHVtbXlJbWFnZUNvbnRlbnQoJGN1cnJlbnRTbGlkZSwgaW5kZXgsIGFsdEF0dHIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaW1nQ29udGVudCA9IHV0aWxzLmdldEltZ01hcmt1cChpbmRleCwgc3JjLCBhbHRBdHRyLCBzcmNzZXQsIHNpemVzLCBzb3VyY2VzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGltZ01hcmt1cCA9IFwiPHBpY3R1cmUgY2xhc3M9XFxcImxnLWltZy13cmFwXFxcIj4gXCIgKyBpbWdDb250ZW50ICsgXCI8L3BpY3R1cmU+XCI7XHJcbiAgICAgICAgJGN1cnJlbnRTbGlkZS5wcmVwZW5kKGltZ01hcmt1cCk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5vblNsaWRlT2JqZWN0TG9hZCA9IGZ1bmN0aW9uICgkc2xpZGUsIGlzSFRNTDVWaWRlb1dpdGhvdXRQb3N0ZXIsIG9uTG9hZCwgb25FcnJvcikge1xyXG4gICAgICAgIHZhciBtZWRpYU9iamVjdCA9ICRzbGlkZS5maW5kKCcubGctb2JqZWN0JykuZmlyc3QoKTtcclxuICAgICAgICBpZiAodXRpbHMuaXNJbWFnZUxvYWRlZChtZWRpYU9iamVjdC5nZXQoKSkgfHxcclxuICAgICAgICAgICAgaXNIVE1MNVZpZGVvV2l0aG91dFBvc3Rlcikge1xyXG4gICAgICAgICAgICBvbkxvYWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIG1lZGlhT2JqZWN0Lm9uKCdsb2FkLmxnIGVycm9yLmxnJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgb25Mb2FkICYmIG9uTG9hZCgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgbWVkaWFPYmplY3Qub24oJ2Vycm9yLmxnJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgb25FcnJvciAmJiBvbkVycm9yKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gJGVsIEN1cnJlbnQgc2xpZGUgaXRlbVxyXG4gICAgICogQHBhcmFtIGluZGV4XHJcbiAgICAgKiBAcGFyYW0gZGVsYXkgRGVsYXkgaXMgMCBleGNlcHQgZmlyc3QgdGltZVxyXG4gICAgICogQHBhcmFtIHNwZWVkIFNwZWVkIGlzIHNhbWUgYXMgZGVsYXksIGV4Y2VwdCBpdCBpcyAwIGlmIGdhbGxlcnkgaXMgb3BlbmVkIHZpYSBoYXNoIHBsdWdpblxyXG4gICAgICogQHBhcmFtIGlzRmlyc3RTbGlkZVxyXG4gICAgICovXHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLm9uTGdPYmplY3RMb2FkID0gZnVuY3Rpb24gKGN1cnJlbnRTbGlkZSwgaW5kZXgsIGRlbGF5LCBzcGVlZCwgaXNGaXJzdFNsaWRlLCBpc0hUTUw1VmlkZW9XaXRob3V0UG9zdGVyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB0aGlzLm9uU2xpZGVPYmplY3RMb2FkKGN1cnJlbnRTbGlkZSwgaXNIVE1MNVZpZGVvV2l0aG91dFBvc3RlciwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy50cmlnZ2VyU2xpZGVJdGVtTG9hZChjdXJyZW50U2xpZGUsIGluZGV4LCBkZWxheSwgc3BlZWQsIGlzRmlyc3RTbGlkZSk7XHJcbiAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjdXJyZW50U2xpZGUuYWRkQ2xhc3MoJ2xnLWNvbXBsZXRlIGxnLWNvbXBsZXRlXycpO1xyXG4gICAgICAgICAgICBjdXJyZW50U2xpZGUuaHRtbCgnPHNwYW4gY2xhc3M9XCJsZy1lcnJvci1tc2dcIj4nICtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNldHRpbmdzLnN0cmluZ3NbJ21lZGlhTG9hZGluZ0ZhaWxlZCddICtcclxuICAgICAgICAgICAgICAgICc8L3NwYW4+Jyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS50cmlnZ2VyU2xpZGVJdGVtTG9hZCA9IGZ1bmN0aW9uICgkY3VycmVudFNsaWRlLCBpbmRleCwgZGVsYXksIHNwZWVkLCBpc0ZpcnN0U2xpZGUpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBjdXJyZW50R2FsbGVyeUl0ZW0gPSB0aGlzLmdhbGxlcnlJdGVtc1tpbmRleF07XHJcbiAgICAgICAgLy8gQWRkaW5nIGRlbGF5IGZvciB2aWRlbyBzbGlkZXMgd2l0aG91dCBwb3N0ZXIgZm9yIGJldHRlciBwZXJmb3JtYW5jZSBhbmQgdXNlciBleHBlcmllbmNlXHJcbiAgICAgICAgLy8gVmlkZW9zIHNob3VsZCBzdGFydCBwbGF5aW5nIG9uY2Ugb25jZSB0aGUgZ2FsbGVyeSBpcyBjb21wbGV0ZWx5IGxvYWRlZFxyXG4gICAgICAgIHZhciBfc3BlZWQgPSBpc0ZpcnN0U2xpZGUgJiZcclxuICAgICAgICAgICAgdGhpcy5nZXRTbGlkZVR5cGUoY3VycmVudEdhbGxlcnlJdGVtKSA9PT0gJ3ZpZGVvJyAmJlxyXG4gICAgICAgICAgICAhY3VycmVudEdhbGxlcnlJdGVtLnBvc3RlclxyXG4gICAgICAgICAgICA/IHNwZWVkXHJcbiAgICAgICAgICAgIDogMDtcclxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgJGN1cnJlbnRTbGlkZS5hZGRDbGFzcygnbGctY29tcGxldGUgbGctY29tcGxldGVfJyk7XHJcbiAgICAgICAgICAgIF90aGlzLkxHZWwudHJpZ2dlcihsR0V2ZW50cy5zbGlkZUl0ZW1Mb2FkLCB7XHJcbiAgICAgICAgICAgICAgICBpbmRleDogaW5kZXgsXHJcbiAgICAgICAgICAgICAgICBkZWxheTogZGVsYXkgfHwgMCxcclxuICAgICAgICAgICAgICAgIGlzRmlyc3RTbGlkZTogaXNGaXJzdFNsaWRlLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9LCBfc3BlZWQpO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuaXNGaXJzdFNsaWRlV2l0aFpvb21BbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuICEhKCF0aGlzLmxHYWxsZXJ5T24gJiZcclxuICAgICAgICAgICAgdGhpcy56b29tRnJvbU9yaWdpbiAmJlxyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRJbWFnZVNpemUpO1xyXG4gICAgfTtcclxuICAgIC8vIEFkZCB2aWRlbyBzbGlkZUluZm9cclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuYWRkU2xpZGVWaWRlb0luZm8gPSBmdW5jdGlvbiAoaXRlbXMpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGl0ZW1zLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQsIGluZGV4KSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuX19zbGlkZVZpZGVvSW5mbyA9IHV0aWxzLmlzVmlkZW8oZWxlbWVudC5zcmMsICEhZWxlbWVudC52aWRlbywgaW5kZXgpO1xyXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5fX3NsaWRlVmlkZW9JbmZvICYmXHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXR0aW5ncy5sb2FkWW91VHViZVBvc3RlciAmJlxyXG4gICAgICAgICAgICAgICAgIWVsZW1lbnQucG9zdGVyICYmXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50Ll9fc2xpZGVWaWRlb0luZm8ueW91dHViZSkge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5wb3N0ZXIgPSBcIi8vaW1nLnlvdXR1YmUuY29tL3ZpL1wiICsgZWxlbWVudC5fX3NsaWRlVmlkZW9JbmZvLnlvdXR1YmVbMV0gKyBcIi9tYXhyZXNkZWZhdWx0LmpwZ1wiO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiAgTG9hZCBzbGlkZSBjb250ZW50IGludG8gc2xpZGUuXHJcbiAgICAgKiAgVGhpcyBpcyB1c2VkIHRvIGxvYWQgY29udGVudCBpbnRvIHNsaWRlcyB0aGF0IGlzIG5vdCB2aXNpYmxlIHRvb1xyXG4gICAgICogIEBwYXJhbSB7TnVtYmVyfSBpbmRleCAtIGluZGV4IG9mIHRoZSBzbGlkZS5cclxuICAgICAqICBAcGFyYW0ge0Jvb2xlYW59IHJlYyAtIGlmIHRydWUgY2FsbCBsb2FkY29udGVudCgpIGZ1bmN0aW9uIGFnYWluLlxyXG4gICAgICovXHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmxvYWRDb250ZW50ID0gZnVuY3Rpb24gKGluZGV4LCByZWMpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBjdXJyZW50R2FsbGVyeUl0ZW0gPSB0aGlzLmdhbGxlcnlJdGVtc1tpbmRleF07XHJcbiAgICAgICAgdmFyICRjdXJyZW50U2xpZGUgPSAkTEcodGhpcy5nZXRTbGlkZUl0ZW1JZChpbmRleCkpO1xyXG4gICAgICAgIHZhciBwb3N0ZXIgPSBjdXJyZW50R2FsbGVyeUl0ZW0ucG9zdGVyLCBzcmNzZXQgPSBjdXJyZW50R2FsbGVyeUl0ZW0uc3Jjc2V0LCBzaXplcyA9IGN1cnJlbnRHYWxsZXJ5SXRlbS5zaXplcywgc291cmNlcyA9IGN1cnJlbnRHYWxsZXJ5SXRlbS5zb3VyY2VzO1xyXG4gICAgICAgIHZhciBzcmMgPSBjdXJyZW50R2FsbGVyeUl0ZW0uc3JjO1xyXG4gICAgICAgIHZhciB2aWRlbyA9IGN1cnJlbnRHYWxsZXJ5SXRlbS52aWRlbztcclxuICAgICAgICB2YXIgX2h0bWw1VmlkZW8gPSB2aWRlbyAmJiB0eXBlb2YgdmlkZW8gPT09ICdzdHJpbmcnID8gSlNPTi5wYXJzZSh2aWRlbykgOiB2aWRlbztcclxuICAgICAgICBpZiAoY3VycmVudEdhbGxlcnlJdGVtLnJlc3BvbnNpdmUpIHtcclxuICAgICAgICAgICAgdmFyIHNyY0R5SXRtcyA9IGN1cnJlbnRHYWxsZXJ5SXRlbS5yZXNwb25zaXZlLnNwbGl0KCcsJyk7XHJcbiAgICAgICAgICAgIHNyYyA9IHV0aWxzLmdldFJlc3BvbnNpdmVTcmMoc3JjRHlJdG1zKSB8fCBzcmM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2aWRlb0luZm8gPSBjdXJyZW50R2FsbGVyeUl0ZW0uX19zbGlkZVZpZGVvSW5mbztcclxuICAgICAgICB2YXIgbGdWaWRlb1N0eWxlID0gJyc7XHJcbiAgICAgICAgdmFyIGlmcmFtZSA9ICEhY3VycmVudEdhbGxlcnlJdGVtLmlmcmFtZTtcclxuICAgICAgICB2Y
1XIgaXNGaXJzdFNsaWRlID0gIXRoaXMubEdhbGxlcnlPbjtcclxuICAgICAgICAvLyBkZWxheSBmb3IgYWRkaW5nIGNvbXBsZXRlIGNsYXNzLiBpdCBpcyAwIGV4Y2VwdCBmaXJzdCB0aW1lLlxyXG4gICAgICAgIHZhciBkZWxheSA9IDA7XHJcbiAgICAgICAgaWYgKGlzRmlyc3RTbGlkZSkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy56b29tRnJvbU9yaWdpbiAmJiB0aGlzLmN1cnJlbnRJbWFnZVNpemUpIHtcclxuICAgICAgICAgICAgICAgIGRlbGF5ID0gdGhpcy5zZXR0aW5ncy5zdGFydEFuaW1hdGlvbkR1cmF0aW9uICsgMTA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBkZWxheSA9IHRoaXMuc2V0dGluZ3MuYmFja2Ryb3BEdXJhdGlvbiArIDEwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghJGN1cnJlbnRTbGlkZS5oYXNDbGFzcygnbGctbG9hZGVkJykpIHtcclxuICAgICAgICAgICAgaWYgKHZpZGVvSW5mbykge1xyXG4gICAgICAgICAgICAgICAgdmFyIF9hID0gdGhpcy5tZWRpYUNvbnRhaW5lclBvc2l0aW9uLCB0b3BfMiA9IF9hLnRvcCwgYm90dG9tID0gX2EuYm90dG9tO1xyXG4gICAgICAgICAgICAgICAgdmFyIHZpZGVvU2l6ZSA9IHV0aWxzLmdldFNpemUodGhpcy5pdGVtc1tpbmRleF0sIHRoaXMub3V0ZXIsIHRvcF8yICsgYm90dG9tLCB2aWRlb0luZm8gJiYgdGhpcy5zZXR0aW5ncy52aWRlb01heFNpemUpO1xyXG4gICAgICAgICAgICAgICAgbGdWaWRlb1N0eWxlID0gdGhpcy5nZXRWaWRlb0NvbnRTdHlsZSh2aWRlb1NpemUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChpZnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIHZhciBtYXJrdXAgPSB1dGlscy5nZXRJZnJhbWVNYXJrdXAodGhpcy5zZXR0aW5ncy5pZnJhbWVXaWR0aCwgdGhpcy5zZXR0aW5ncy5pZnJhbWVIZWlnaHQsIHRoaXMuc2V0dGluZ3MuaWZyYW1lTWF4V2lkdGgsIHRoaXMuc2V0dGluZ3MuaWZyYW1lTWF4SGVpZ2h0LCBzcmMsIGN1cnJlbnRHYWxsZXJ5SXRlbS5pZnJhbWVUaXRsZSk7XHJcbiAgICAgICAgICAgICAgICAkY3VycmVudFNsaWRlLnByZXBlbmQobWFya3VwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChwb3N0ZXIpIHtcclxuICAgICAgICAgICAgICAgIHZhciBkdW1teUltZyA9ICcnO1xyXG4gICAgICAgICAgICAgICAgdmFyIGhhc1N0YXJ0QW5pbWF0aW9uID0gaXNGaXJzdFNsaWRlICYmXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy56b29tRnJvbU9yaWdpbiAmJlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEltYWdlU2l6ZTtcclxuICAgICAgICAgICAgICAgIGlmIChoYXNTdGFydEFuaW1hdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGR1bW15SW1nID0gdGhpcy5nZXREdW1teUltYWdlQ29udGVudCgkY3VycmVudFNsaWRlLCBpbmRleCwgJycpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIG1hcmt1cCA9IHV0aWxzLmdldFZpZGVvUG9zdGVyTWFya3VwKHBvc3RlciwgZHVtbXlJbWcgfHwgJycsIGxnVmlkZW9TdHlsZSwgdGhpcy5zZXR0aW5ncy5zdHJpbmdzWydwbGF5VmlkZW8nXSwgdmlkZW9JbmZvKTtcclxuICAgICAgICAgICAgICAgICRjdXJyZW50U2xpZGUucHJlcGVuZChtYXJrdXApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHZpZGVvSW5mbykge1xyXG4gICAgICAgICAgICAgICAgdmFyIG1hcmt1cCA9IFwiPGRpdiBjbGFzcz1cXFwibGctdmlkZW8tY29udCBcXFwiIHN0eWxlPVxcXCJcIiArIGxnVmlkZW9TdHlsZSArIFwiXFxcIj48L2Rpdj5cIjtcclxuICAgICAgICAgICAgICAgICRjdXJyZW50U2xpZGUucHJlcGVuZChtYXJrdXApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRJbWdNYXJrdXAoc3JjLCAkY3VycmVudFNsaWRlLCBpbmRleCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3Jjc2V0IHx8IHNvdXJjZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICB2Y
1XIgJGltZyA9ICRjdXJyZW50U2xpZGUuZmluZCgnLmxnLW9iamVjdCcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdFBpY3R1cmVGaWxsKCRpbWcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwb3N0ZXIgfHwgdmlkZW9JbmZvKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLkxHZWwudHJpZ2dlcihsR0V2ZW50cy5oYXNWaWRlbywge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiBpbmRleCxcclxuICAgICAgICAgICAgICAgICAgICBzcmM6IHNyYyxcclxuICAgICAgICAgICAgICAgICAgICBodG1sNVZpZGVvOiBfaHRtbDVWaWRlbyxcclxuICAgICAgICAgICAgICAgICAgICBoYXNQb3N0ZXI6ICEhcG9zdGVyLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMuYWZ0ZXJBcHBlbmRTbGlkZSwgeyBpbmRleDogaW5kZXggfSk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxHYWxsZXJ5T24gJiZcclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZ3MuYXBwZW5kU3ViSHRtbFRvID09PSAnLmxnLWl0ZW0nKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEh0bWwoaW5kZXgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEZvciBmaXJzdCB0aW1lIGFkZCBzb21lIGRlbGF5IGZvciBkaXNwbGF5aW5nIHRoZSBzdGFydCBhbmltYXRpb24uXHJcbiAgICAgICAgdmFyIF9zcGVlZCA9IDA7XHJcbiAgICAgICAgLy8gRG8gbm90IGNoYW5nZSB0aGUgZGVsYXkgdmFsdWUgYmVjYXVzZSBpdCBpcyByZXF1aXJlZCBmb3Igem9vbSBwbHVnaW4uXHJcbiAgICAgICAgLy8gSWYgZ2FsbGVyeSBvcGVuZWQgZnJvbSBkaXJlY3QgdXJsIChoYXNoKSBzcGVlZCB2YWx1ZSBzaG91bGQgYmUgMFxyXG4gICAgICAgIGlmIChkZWxheSAmJiAhJExHKGRvY3VtZW50LmJvZHkpLmhhc0NsYXNzKCdsZy1mcm9tLWhhc2gnKSkge1xyXG4gICAgICAgICAgICBfc3BlZWQgPSBkZWxheTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gT25seSBmb3IgZmlyc3Qgc2xpZGUgYW5kIHpvb21Gcm9tT3JpZ2luIGlzIGVuYWJsZWRcclxuICAgICAgICBpZiAodGhpcy5pc0ZpcnN0U2xpZGVXaXRoWm9vbUFuaW1hdGlvbigpKSB7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgJGN1cnJlbnRTbGlkZVxyXG4gICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnbGctc3RhcnQtZW5kLXByb2dyZXNzIGxnLXN0YXJ0LXByb2dyZXNzJylcclxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignc3R5bGUnKTtcclxuICAgICAgICAgICAgfSwgdGhpcy5zZXR0aW5ncy5zdGFydEFuaW1hdGlvbkR1cmF0aW9uICsgMTAwKTtcclxuICAgICAgICAgICAgaWYgKCEkY3VycmVudFNsaWRlLmhhc0NsYXNzKCdsZy1sb2FkZWQnKSkge1xyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLmdldFNsaWRlVHlwZShjdXJyZW50R2FsbGVyeUl0ZW0pID09PSAnaW1hZ2UnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbHQgPSBjdXJyZW50R2FsbGVyeUl0ZW0uYWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2Y
1XIgYWx0QXR0ciA9IGFsdCA/ICdhbHQ9XCInICsgYWx0ICsgJ1wiJyA6ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAkY3VycmVudFNsaWRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZmluZCgnLmxnLWltZy13cmFwJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hcHBlbmQodXRpbHMuZ2V0SW1nTWFya3VwKGluZGV4LCBzcmMsIGFsdEF0dHIsIHNyY3NldCwgc2l6ZXMsIGN1cnJlbnRHYWxsZXJ5SXRlbS5zb3VyY2VzKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzcmNzZXQgfHwgc291cmNlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyICRpbWcgPSAkY3VycmVudFNsaWRlLmZpbmQoJy5sZy1vYmplY3QnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmluaXRQaWN0dXJlRmlsbCgkaW1nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMuZ2V0U2xpZGVUeXBlKGN1cnJlbnRHYWxsZXJ5SXRlbSkgPT09ICdpbWFnZScgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKF90aGlzLmdldFNsaWRlVHlwZShjdXJyZW50R2FsbGVyeUl0ZW0pID09PSAndmlkZW8nICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3N0ZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLm9uTGdPYmplY3RMb2FkKCRjdXJyZW50U2xpZGUsIGluZGV4LCBkZWxheSwgX3NwZWVkLCB0cnVlLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvYWQgcmVtYWluaW5nIHNsaWRlcyBvbmNlIHRoZSBzbGlkZSBpcyBjb21wbGV0ZWx5IGxvYWRlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5vblNsaWRlT2JqZWN0TG9hZCgkY3VycmVudFNsaWRlLCAhISh2aWRlb0luZm8gJiYgdmlkZW9JbmZvLmh0bWw1ICYmICFwb3N0ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5sb2FkQ29udGVudE9uRmlyc3RTbGlkZUxvYWQoaW5kZXgsICRjdXJyZW50U2xpZGUsIF9zcGVlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmxvYWRDb250ZW50T25GaXJzdFNsaWRlTG9hZChpbmRleCwgJGN1cnJlbnRTbGlkZSwgX3NwZWVkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSwgdGhpcy5zZXR0aW5ncy5zdGFydEFuaW1hdGlvbkR1cmF0aW9uICsgMTAwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBTTGlkZSBjb250ZW50IGhhcyBiZWVuIGFkZGVkIHRvIGRvbVxyXG4gICAgICAgICRjdXJyZW50U2xpZGUuYWRkQ2xhc3MoJ2xnLWxvYWRlZCcpO1xyXG4gICAgICAgIGlmICghdGhpcy5pc0ZpcnN0U2xpZGVXaXRoWm9vbUFuaW1hdGlvbigpIHx8XHJcbiAgICAgICAgICAgICh0aGlzLmdldFNsaWRlVHlwZShjdXJyZW50R2FsbGVyeUl0ZW0pID09PSAndmlkZW8nICYmICFwb3N0ZXIpKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25MZ09iamVjdExvYWQoJGN1cnJlbnRTbGlkZSwgaW5kZXgsIGRlbGF5LCBfc3BlZWQsIGlzRmlyc3RTbGlkZSwgISEodmlkZW9JbmZvICYmIHZpZGVvSW5mby5odG1sNSAmJiAhcG9zdGVyKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFdoZW4gZ2FsbGVyeSBpcyBvcGVuZWQgb25jZSBjb250ZW50IGlzIGxvYWRlZCAoc2Vjb25kIHRpbWUpIG5lZWQgdG8gYWRkIGxnLWNvbXBsZXRlIGNsYXNzIGZvciBjc3Mgc3R5bGluZ1xyXG4gICAgICAgIGlmICgoIXRoaXMuem9vbUZyb21PcmlnaW4gfHwgIXRoaXMuY3VycmVudEltYWdlU2l6ZSkgJiZcclxuICAgICAgICAgICAgJGN1cnJlbnRTbGlkZS5oYXNDbGFzcygnbGctY29tcGxldGVfJykgJiZcclxuICAgICAgICAgICAgIXRoaXMubEdhbGxlcnlPbikge1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICRjdXJyZW50U2xpZGUuYWRkQ2xhc3MoJ2xnLWNvbXBsZXRlJyk7XHJcbiAgICAgICAgICAgIH0sIHRoaXMuc2V0dGluZ3MuYmFja2Ryb3BEdXJhdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIENvbnRlbnQgbG9hZGVkXHJcbiAgICAgICAgLy8gTmVlZCB0byBzZXQgbEdhbGxlcnlPbiBiZWZvcmUgY2FsbGluZyBwcmVsb2FkIGZ1bmN0aW9uXHJcbiAgICAgICAgdGhpcy5sR2FsbGVyeU9uID0gdHJ1ZTtcclxuICAgICAgICBpZiAocmVjID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIGlmICghJGN1cnJlbnRTbGlkZS5oYXNDbGFzcygnbGctY29tcGxldGVfJykpIHtcclxuICAgICAgICAgICAgICAgICRjdXJyZW50U2xpZGVcclxuICAgICAgICAgICAgICAgICAgICAuZmluZCgnLmxnLW9iamVjdCcpXHJcbiAgICAgICAgICAgICAgICAgICAgLmZpcnN0KClcclxuICAgICAgICAgICAgICAgICAgICAub24oJ2xvYWQubGcgZXJyb3IubGcnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucHJlbG9hZChpbmRleCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucHJlbG9hZChpbmRleCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzYyBSZW1vdmUgZHVtbXkgaW1hZ2UgY29udGVudCBhbmQgbG9hZCBuZXh0IHNsaWRlc1xyXG4gICAgICogQ2FsbGVkIG9ubHkgZm9yIHRoZSBmaXJzdCB0aW1lIGlmIHpvb21Gcm9tT3JpZ2luIGFuaW1hdGlvbiBpcyBlbmFibGVkXHJcbiAgICAgKiBAcGFyYW0gaW5kZXhcclxuICAgICAqIEBwYXJhbSAkY3VycmVudFNsaWRlXHJcbiAgICAgKiBAcGFyYW0gc3BlZWRcclxuICAgICAqL1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5sb2FkQ29udGVudE9uRmlyc3RTbGlkZUxvYWQgPSBmdW5jdGlvbiAoaW5kZXgsICRjdXJyZW50U2xpZGUsIHNwZWVkKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBzZXRUaW
11lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgJGN1cnJlbnRTbGlkZS5maW5kKCcubGctZHVtbXktaW1nJykucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgICRjdXJyZW50U2xpZGUucmVtb3ZlQ2xhc3MoJ2xnLWZpcnN0LXNsaWRlJyk7XHJcbiAgICAgICAgICAgIF90aGlzLm91dGVyLnJlbW92ZUNsYXNzKCdsZy1maXJzdC1zbGlkZS1sb2FkaW5nJyk7XHJcbiAgICAgICAgICAgIF90aGlzLmlzRHVtbXlJbWFnZVJlbW92ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBfdGhpcy5wcmVsb2FkKGluZGV4KTtcclxuICAgICAgICB9LCBzcGVlZCArIDMwMCk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5nZXRJdGVtc1RvQmVJbnNlcnRlZFRvRG9tID0gZnVuY3Rpb24gKGluZGV4LCBwcmV2SW5kZXgsIG51bWJlck9mSXRlbXMpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmIChudW1iZXJPZkl0ZW1zID09PSB2b2lkIDApIHsgbnVtYmVyT2ZJdGVtcyA9IDA7IH1cclxuICAgICAgICB2YXIgaXRlbXNUb0JlSW5zZXJ0ZWRUb0RvbSA9IFtdO1xyXG4gICAgICAgIC8vIE1pbmltdW0gMiBpdGVtcyBzaG91bGQgYmUgdGhlcmVcclxuICAgICAgICB2YXIgcG9zc2libGVOdW1iZXJPZkl0ZW1zID0gTWF0aC5tYXgobnVtYmVyT2ZJdGVtcywgMyk7XHJcbiAgICAgICAgcG9zc2libGVOdW1iZXJPZkl0ZW1zID0gTWF0aC5taW4ocG9zc2libGVOdW1iZXJPZkl0ZW1zLCB0aGlzLmdhbGxlcnlJdGVtcy5sZW5ndGgpO1xyXG4gICAgICAgIHZhciBwcmV2SW5kZXhJdGVtID0gXCJsZy1pdGVtLVwiICsgdGhpcy5sZ0lkICsgXCItXCIgKyBwcmV2SW5kZXg7XHJcbiAgICAgICAgaWYgKHRoaXMuZ2FsbGVyeUl0ZW1zLmxlbmd0aCA8PSAzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ2FsbGVyeUl0ZW1zLmZvckVhY2goZnVuY3Rpb24gKF9lbGVtZW50LCBpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgaXRlbXNUb0JlSW5zZXJ0ZWRUb0RvbS5wdXNoKFwibGctaXRlbS1cIiArIF90aGlzLmxnSWQgKyBcIi1cIiArIGluZGV4KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtc1RvQmVJbnNlcnRlZFRvRG9tO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaW5kZXggPCAodGhpcy5nYWxsZXJ5SXRlbXMubGVuZ3RoIC0gMSkgLyAyKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGlkeCA9IGluZGV4OyBpZHggPiBpbmRleCAtIHBvc3NpYmxlTnVtYmVyT2ZJdGVtcyAvIDIgJiYgaWR4ID49IDA7IGlkeC0tKSB7XHJcbiAgICAgICAgICAgICAgICBpdGVtc1RvQmVJbnNlcnRlZFRvRG9tLnB1c2goXCJsZy1pdGVtLVwiICsgdGhpcy5sZ0lkICsgXCItXCIgKyBpZHgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBudW1iZXJPZkV4aXN0aW5nSXRlbXMgPSBpdGVtc1RvQmVJbnNlcnRlZFRvRG9tLmxlbmd0aDtcclxuICAgICAgICAgICAgZm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgcG9zc2libGVOdW1iZXJPZkl0ZW1zIC0gbnVtYmVyT2ZFeGlzdGluZ0l0ZW1zOyBpZHgrKykge1xyXG4gICAgICAgICAgICAgICAgaXRlbXNUb0JlSW5zZXJ0ZWRUb0RvbS5wdXNoKFwibGctaXRlbS1cIiArIHRoaXMubGdJZCArIFwiLVwiICsgKGluZGV4ICsgaWR4ICsgMSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpZHggPSBpbmRleDsgaWR4IDw9IHRoaXMuZ2FsbGVyeUl0ZW1zLmxlbmd0aCAtIDEgJiZcclxuICAgICAgICAgICAgICAgIGlkeCA8IGluZGV4ICsgcG9zc2libGVOdW1iZXJPZkl0ZW1zIC8gMjsgaWR4KyspIHtcclxuICAgICAgICAgICAgICAgIGl0ZW1zVG9CZUluc2VydGVkVG9Eb20ucHVzaChcImxnLWl0ZW0tXCIgKyB0aGlzLmxnSWQgKyBcIi1cIiArIGlkeCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIG51bWJlck9mRXhpc3RpbmdJdGVtcyA9IGl0ZW1zVG9CZUluc2VydGVkVG9Eb20ubGVuZ3RoO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpZHggPSAwOyBpZHggPCBwb3NzaWJsZU51bWJlck9mSXRlbXMgLSBudW1iZXJPZkV4aXN0aW5nSXRlbXM7IGlkeCsrKSB7XHJcbiAgICAgICAgICAgICAgICBpdGVtc1RvQmVJbnNlcnRlZFRvRG9tLnB1c2goXCJsZy1pdGVtLVwiICsgdGhpcy5sZ0lkICsgXCItXCIgKyAoaW5kZXggLSBpZHggLSAxKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MubG9vcCkge1xyXG4gICAgICAgICAgICBpZiAoaW5kZXggPT09IHRoaXMuZ2FsbGVyeUl0ZW1zLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICAgICAgICAgIGl0ZW1zVG9CZUluc2VydGVkVG9Eb20ucHVzaChcImxnLWl0ZW0tXCIgKyB0aGlzLmxnSWQgKyBcIi1cIiArIDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGluZGV4ID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpdGVtc1RvQmVJbnNlcnRlZFRvRG9tLnB1c2goXCJsZy1pdGVtLVwiICsgdGhpcy5sZ0lkICsgXCItXCIgKyAodGhpcy5nYWxsZXJ5SXRlbXMubGVuZ3RoIC0gMSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpdGVtc1RvQmVJbnNlcnRlZFRvRG9tLmluZGV4T2YocHJldkluZGV4SXRlbSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIGl0ZW1zVG9CZUluc2VydGVkVG9Eb20ucHVzaChcImxnLWl0ZW0tXCIgKyB0aGlzLmxnSWQgKyBcIi1cIiArIHByZXZJbmRleCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBpdGVtc1RvQmVJbnNlcnRlZFRvRG9tO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUub3JnYW5pemVTbGlkZUl0ZW1zID0gZnVuY3Rpb24gKGluZGV4LCBwcmV2SW5kZXgpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBpdGVtc1RvQmVJbnNlcnRlZFRvRG9tID0gdGhpcy5nZXRJdGVtc1RvQmVJbnNlcnRlZFRvRG9tKGluZGV4LCBwcmV2SW5kZXgsIHRoaXMuc2V0dGluZ3MubnVtYmVyT2ZTbGlkZUl0ZW1zSW5Eb20pO1xyXG4gICAgICAgIGl0ZW1zVG9CZUluc2VydGVkVG9Eb20uZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuY3VycmVudEl0ZW1zSW5Eb20uaW5kZXhPZihpdGVtKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLiRpbm5lci5hcHBlbmQoXCI8ZGl2IGlkPVxcXCJcIiArIGl0ZW0gKyBcIlxcXCIgY2xhc3M9XFxcImxnLWl0ZW1cXFwiPjwvZGl2PlwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuY3VycmVudEl0ZW1zSW5Eb20uZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgICAgICBpZiAoaXRlbXNUb0JlSW5zZXJ0ZWRUb0RvbS5pbmRleE9mKGl0ZW0pID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgJExHKFwiI1wiICsgaXRlbSkucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gaXRlbXNUb0JlSW5zZXJ0ZWRUb0RvbTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdldCBwcmV2aW91cyBpbmRleCBvZiB0aGUgc2xpZGVcclxuICAgICAqL1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5nZXRQcmV2aW91c1NsaWRlSW5kZXggPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHByZXZJbmRleCA9IDA7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgdmFyIGN1cnJlbnRJdGVtSWQgPSB0aGlzLm91dGVyXHJcbiAgICAgICAgICAgICAgICAuZmluZCgnLmxnLWN1cnJlbnQnKVxyXG4gICAgICAgICAgICAgICAgLmZpcnN0KClcclxuICAgICAgICAgICAgICAgIC5hdHRyKCdpZCcpO1xyXG4gICAgICAgICAgICBwcmV2SW5kZXggPSBwYXJzZUludChjdXJyZW50SXRlbUlkLnNwbGl0KCctJylbM10pIHx8IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICBwcmV2SW5kZXggPSAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcHJldkluZGV4O1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuc2V0RG93bmxvYWRWYWx1ZSA9IGZ1bmN0aW9uIChpbmRleCkge1xyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLmRvd25sb2FkKSB7XHJcbiAgICAgICAgICAgIHZhciBjdXJyZW50R2FsbGVyeUl0ZW0gPSB0aGlzLmdhbGxlcnlJdGVtc1tpbmRleF07XHJcbiAgICAgICAgICAgIHZhciBoaWRlRG93bmxvYWRCdG4gPSBjdXJyZW50R2FsbGVyeUl0ZW0uZG93bmxvYWRVcmwgPT09IGZhbHNlIHx8XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50R2FsbGVyeUl0ZW0uZG93bmxvYWRVcmwgPT09ICdmYWxzZSc7XHJcbiAgICAgICAgICAgIGlmIChoaWRlRG93bmxvYWRCdG4pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub3V0ZXIuYWRkQ2xhc3MoJ2xnLWhpZGUtZG93bmxvYWQnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhciAkZG93bmxvYWQgPSB0aGlzLmdldEVsZW1lbnRCeUlkKCdsZy1kb3dubG9hZCcpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vdXRlci5yZW1vdmVDbGFzcygnbGctaGlkZS1kb3dubG9hZCcpO1xyXG4gICAgICAgICAgICAgICAgJGRvd25sb2FkLmF0dHIoJ2hyZWYnLCBjdXJyZW50R2FsbGVyeUl0ZW0uZG93bmxvYWRVcmwgfHxcclxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50R2FsbGVyeUl0ZW0uc3JjKTtcclxuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50R2FsbGVyeUl0ZW0uZG93bmxvYWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAkZG93bmxvYWQuYXR0cignZG93bmxvYWQnLCBjdXJyZW50R2FsbGVyeUl0ZW0uZG93bmxvYWQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUubWFrZVNsaWRlQW5pbWF0aW9uID0gZnVuY3Rpb24gKGRpcmVjdGlvbiwgY3VycmVudFNsaWRlSXRlbSwgcHJldmlvdXNTbGlkZUl0ZW0pIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmICh0aGlzLmxHYWxsZXJ5T24pIHtcclxuICAgICAgICAgICAgcHJldmlvdXNTbGlkZUl0ZW0uYWRkQ2xhc3MoJ2xnLXNsaWRlLXByb2dyZXNzJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyByZW1vdmUgYWxsIHRyYW5zaXRpb25zXHJcbiAgICAgICAgICAgIF90aGlzLm91dGVyLmFkZENsYXNzKCdsZy1uby10cmFucycpO1xyXG4gICAgICAgICAgICBfdGhpcy5vdXRlclxyXG4gICAgICAgICAgICAgICAgLmZpbmQoJy5sZy1pdGVtJylcclxuICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnbGctcHJldi1zbGlkZSBsZy1uZXh0LXNsaWRlJyk7XHJcbiAgICAgICAgICAgIGlmIChkaXJlY3Rpb24gPT09ICdwcmV2Jykge1xyXG4gICAgICAgICAgICAgICAgLy9wcmV2c2xpZGVcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRTbGlkZUl0ZW0uYWRkQ2xhc3MoJ2xnLXByZXYtc2xpZGUnKTtcclxuICAgICAgICAgICAgICAgIHByZXZpb3VzU2xpZGVJdGVtLmFkZENsYXNzKCdsZy1uZXh0LXNsaWRlJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBuZXh0IHNsaWRlXHJcbiAgICAgICAgICAgICAgICBjdXJyZW50U2xpZGVJdGVtLmFkZENsYXNzKCdsZy1uZXh0LXNsaWRlJyk7XHJcbiAgICAgICAgICAgICAgICBwcmV2aW91c1NsaWRlSXRlbS5hZGRDbGFzcygnbGctcHJldi1zbGlkZScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGdpdmUgNTAgbXMgZm9yIGJyb3dzZXIgdG8gYWRkL3JlbW92ZSBjbGFzc1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLmZpbmQoJy5sZy1pdGVtJykucmVtb3ZlQ2xhc3MoJ2xnLWN1cnJlbnQnKTtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRTbGlkZUl0ZW0uYWRkQ2xhc3MoJ2xnLWN1cnJlbnQnKTtcclxuICAgICAgICAgICAgICAgIC8vIHJlc2V0IGFsbCB0cmFuc2l0aW9uc1xyXG4gICAgICAgICAgICAgICAgX3RoaXMub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLW5vLXRyYW5zJyk7XHJcbiAgICAgICAgICAgIH0sIDUwKTtcclxuICAgICAgICB9LCB0aGlzLmxHYWxsZXJ5T24gPyB0aGlzLnNldHRpbmdzLnNsaWRlRGVsYXkgOiAwKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdvdG8gYSBzcGVjaWZpYyBzbGlkZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleCAtIGluZGV4IG9mIHRoZSBzbGlkZVxyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBmcm9tVG91Y2ggLSB0cnVlIGlmIHNsaWRlIGZ1bmN0aW9uIGNhbGxlZCB2aWEgdG91Y2ggZXZlbnQgb3IgbW91c2UgZHJhZ1xyXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBmcm9tVGh1bWIgLSB0cnVlIGlmIHNsaWRlIGZ1bmN0aW9uIGNhbGxlZCB2aWEgdGh1bWJuYWlsIGNsaWNrXHJcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGlyZWN0aW9uIC0gRGlyZWN0aW9uIG9mIHRoZSBzbGlkZShuZXh0L3ByZXYpXHJcbiAgICAgKiBAY2F0ZWdvcnkgbEdQdWJsaWNNZXRob2RzXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIGNvbnN0IHBsdWdpbiA9IGxpZ2h0R2FsbGVyeSgpO1xyXG4gICAgICogIC8vIHRvIGdvIHRvIDNyZCBzbGlkZVxyXG4gICAgICogIHBsdWdpbi5zbGlkZSgyKTtcclxuICAgICAqXHJcbiAgICAgKi9cclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuc2xpZGUgPSBmdW5jdGlvbiAoaW5kZXgsIGZyb21Ub3VjaCwgZnJvbVRodW1iLCBkaXJlY3Rpb24pIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBwcmV2SW5kZXggPSB0aGlzLmdldFByZXZpb3VzU2xpZGVJbmRleCgpO1xyXG4gICAgICAgIHRoaXMuY3VycmVudEl0ZW1zSW5Eb20gPSB0aGlzLm9yZ2FuaXplU2xpZGVJdGVtcyhpbmRleCwgcHJldkluZGV4KTtcclxuICAgICAgICAvLyBQcmV2ZW50IG11bHRpcGxlIGNhbGwsIFJlcXVpcmVkIGZvciBoc2ggcGx1Z2luXHJcbiAgICAgICAgaWYgKHRoaXMubEdhbGxlcnlPbiAmJiBwcmV2SW5kZXggPT09IGluZGV4KSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIG51bWJlck9mR2FsbGVyeUl0ZW1zID0gdGhpcy5nYWxsZXJ5SXRlbXMubGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy5sZ0J1c3kpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuY291bnRlcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVDdXJyZW50Q291bnRlcihpbmRleCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGN1cnJlbnRTbGlkZUl0ZW0gPSB0aGlzLmdldFNsaWRlSXRlbShpbmRleCk7XHJcbiAgICAgICAgICAgIHZhciBwcmV2aW91c1NsaWRlSXRlbV8xID0gdGhpcy5nZXRTbGlkZUl0ZW0ocHJldkluZGV4KTtcclxuICAgICAgICAgICAgdmFyIGN1cnJlbnRHYWxsZXJ5SXRlbSA9IHRoaXMuZ2FsbGVyeUl0ZW1zW2luZGV4XTtcclxuICAgICAgICAgICAgdmFyIHZpZGVvSW5mbyA9IGN1cnJlbnRHYWxsZXJ5SXRlbS5fX3NsaWRlVmlkZW9JbmZvO1xyXG4gICAgICAgICAgICB0aGlzLm91dGVyLmF0dHIoJ2RhdGEtbGctc2xpZGUtdHlwZScsIHRoaXMuZ2V0U2xpZGVUeXBlKGN1cnJlbnRHYWxsZXJ5SXRlbSkpO1xyXG4gICAgICAgICAgICB0aGlzLnNldERvd25sb2FkVmFsdWUoaW5kZXgpO1xyXG4gICAgICAgICAgICBpZiAodmlkZW9JbmZvKSB7XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgX2EgPSB0aGlzLm1lZGlhQ29udGFpbmVyUG9zaXRpb24sIHRvcF8zID0gX2EudG9wLCBib3R0b20gPSBfYS5ib3R0b207XHJcbiAgICAgICAgICAgICAgICB2YXIgdmlkZW9TaXplID0gdXRpbHMuZ2V0U2l6ZSh0aGlzLml0ZW1zW2luZGV4XSwgdGhpcy5vdXRlciwgdG9wXzMgKyBib3R0b20sIHZpZGVvSW5mbyAmJiB0aGlzLnNldHRpbmdzLnZpZGVvTWF4U2l6ZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZVZpZGVvU2xpZGUoaW5kZXgsIHZpZGVvU2l6ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMuYmVmb3JlU2xpZGUsIHtcclxuICAgICAgICAgICAgICAgIHByZXZJbmRleDogcHJldkluZGV4LFxyXG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxyXG4gICAgICAgICAgICAgICAgZnJvbVRvdWNoOiAhIWZyb21Ub3VjaCxcclxuICAgICAgICAgICAgICAgIGZyb21UaHVtYjogISFmcm9tVGh1bWIsXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLmxnQnVzeSA9IHRydWU7XHJcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmhpZGVCYXJUaW1lb3V0KTtcclxuICAgICAgICAgICAgdGhpcy5hcnJvd0Rpc2FibGUoaW5kZXgpO1xyXG4gICAgICAgICAgICBpZiAoIWRpcmVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgcHJldkluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gJ3ByZXYnO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoaW5kZXggPiBwcmV2SW5kZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAnbmV4dCc7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCFmcm9tVG91Y2gpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubWFrZVNsaWRlQW5pbWF0aW9uKGRpcmVjdGlvbiwgY3VycmVudFNsaWRlSXRlbSwgcHJldmlvdXNTbGlkZUl0ZW1fMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm91dGVyXHJcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoJy5sZy1pdGVtJylcclxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ2xnLXByZXYtc2xpZGUgbGctY3VycmVudCBsZy1uZXh0LXNsaWRlJyk7XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgdG91Y2hQcmV2ID0gdm9pZCAwO1xyXG4gICAgICAgICAgICAgICAgdmFyIHRvdWNoTmV4dCA9IHZvaWQgMDtcclxuICAgICAgICAgICAgICAgIGlmIChudW1iZXJPZkdhbGxlcnlJdGVtcyA+IDIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0b3VjaFByZXYgPSBpbmRleCAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgdG91Y2hOZXh0ID0gaW5kZXggKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCAmJiBwcmV2SW5kZXggPT09IG51bWJlck9mR2FsbGVyeUl0ZW1zIC0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBuZXh0IHNsaWRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdWNoTmV4dCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdWNoUHJldiA9IG51bWJlck9mR2FsbGVyeUl0ZW1zIC0gMTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaW5kZXggPT09IG51bWJlck9mR2FsbGVyeUl0ZW1zIC0gMSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcmV2SW5kZXggPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJldiBzbGlkZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3VjaE5leHQgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3VjaFByZXYgPSBudW1iZXJPZkdhbGxlcnlJdGVtcyAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdG91Y2hQcmV2ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB0b3VjaE5leHQgPSAxO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3ByZXYnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRTbGlkZUl0ZW0odG91Y2hOZXh0KS5hZGRDbGFzcygnbGctbmV4dC1zbGlkZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRTbGlkZUl0ZW0odG91Y2hQcmV2KS5hZGRDbGFzcygnbGctcHJldi1zbGlkZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY3VycmVudFNsaWRlSXRlbS5hZGRDbGFzcygnbGctY3VycmVudCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIERvIG5vdCBwdXQgbG9hZCBjb250ZW50IGluIHNldCB0aW1lb3V0IGFzIGl0IG5lZWRzIHRvIGxvYWQgaW1tZWRpYXRlbHkgd2hlbiB0aGUgZ2FsbGVyeSBpcyBvcGVuZWRcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmxHYWxsZXJ5T24pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9hZENvbnRlbnQoaW5kZXgsIHRydWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMubG9hZENvbnRlbnQoaW5kZXgsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIEFkZCB0aXRsZSBpZiB0aGlzLnNldHRpbmdzLmFwcGVuZFN1Ykh0bWxUbyA9PT0gbGctc3ViLWh0bWxcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMuc2V0dGluZ3MuYXBwZW5kU3ViSHRtbFRvICE9PSAnLmxnLWl0ZW0nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmFkZEh0bWwoaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0sIHRoaXMuc2V0dGluZ3Muc3BlZWQgKyA1MCArIChmcm9tVG91Y2ggPyAwIDogdGhpcy5zZXR0aW5ncy5zbGlkZURlbGF5KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5sZ0J1c3kgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHByZXZpb3VzU2xpZGVJdGVtXzEucmVtb3ZlQ2xhc3MoJ2xnLXNsaWRlLXByb2dyZXNzJyk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMuYWZ0ZXJTbGlkZSwge1xyXG4gICAgICAgICAgICAgICAgICAgIHByZXZJbmRleDogcHJldkluZGV4LFxyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiBpbmRleCxcclxuICAgICAgICAgICAgICAgICAgICBmcm9tVG91Y2g6IGZyb21Ub3VjaCxcclxuICAgICAgICAgICAgICAgICAgICBmcm9tVGh1bWI6IGZyb21UaHVtYixcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9LCAodGhpcy5sR2FsbGVyeU9uID8gdGhpcy5zZXR0aW5ncy5zcGVlZCArIDEwMCA6IDEwMCkgKyAoZnJvbVRvdWNoID8gMCA6IHRoaXMuc2V0dGluZ3Muc2xpZGVEZWxheSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS51cGRhdGVDdXJyZW50Q291bnRlciA9IGZ1bmN0aW9uIChpbmRleCkge1xyXG4gICAgICAgIHRoaXMuZ2V0RWxlbWVudEJ5SWQoJ2xnLWNvdW50ZXItY3VycmVudCcpLmh0bWwoaW5kZXggKyAxICsgJycpO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUudXBkYXRlQ291bnRlclRvdGFsID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMuZ2V0RWxlbWVudEJ5SWQoJ2xnLWNvdW50ZXItYWxsJykuaHRtbCh0aGlzLmdhbGxlcnlJdGVtcy5sZW5ndGggKyAnJyk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5nZXRTbGlkZVR5cGUgPSBmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgIGlmIChpdGVtLl9fc2xpZGVWaWRlb0luZm8pIHtcclxuICAgICAgICAgICAgcmV0dXJuICd2aWRlbyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGl0ZW0uaWZyYW1lKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAnaWZyYW1lJztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgI
1HJldHVybiAnaW1hZ2UnO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLnRvdWNoTW92ZSA9IGZ1bmN0aW9uIChzdGFydENvb3JkcywgZW5kQ29vcmRzLCBlKSB7XHJcbiAgICAgICAgdmFyIGRpc3RhbmNlWCA9IGVuZENvb3Jkcy5wYWdlWCAtIHN0YXJ0Q29vcmRzLnBhZ2VYO1xyXG4gICAgICAgIHZhciBkaXN0YW5jZVkgPSBlbmRDb29yZHMucGFnZVkgLSBzdGFydENvb3Jkcy5wYWdlWTtcclxuICAgICAgICB2YXIgYWxsb3dTd2lwZSA9IGZhbHNlO1xyXG4gICAgICAgIGlmICh0aGlzLnN3aXBlRGlyZWN0aW9uKSB7XHJcbiAgICAgICAgICAgIGFsbG93U3dpcGUgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKE1hdGguYWJzKGRpc3RhbmNlWCkgPiAxNSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zd2lwZURpcmVjdGlvbiA9ICdob3Jpem9udGFsJztcclxuICAgICAgICAgICAgICAgIGFsbG93U3dpcGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKE1hdGguYWJzKGRpc3RhbmNlWSkgPiAxNSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zd2lwZURpcmVjdGlvbiA9ICd2ZXJ0aWNhbCc7XHJcbiAgICAgICAgICAgICAgICBhbGxvd1N3aXBlID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWFsbG93U3dpcGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2Y
1XIgJGN1cnJlbnRTbGlkZSA9IHRoaXMuZ2V0U2xpZGVJdGVtKHRoaXMuaW5kZXgpO1xyXG4gICAgICAgIGlmICh0aGlzLnN3aXBlRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcclxuICAgICAgICAgICAgZSA9PT0gbnVsbCB8fCBlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIC8vIHJlc2V0IG9wYWNpdHkgYW5kIHRyYW5zaXRpb24gZHVyYXRpb25cclxuICAgICAgICAgICAgdGhpcy5vdXRlci5hZGRDbGFzcygnbGctZHJhZ2dpbmcnKTtcclxuICAgICAgICAgICAgLy8gbW92ZSBjdXJyZW50IHNsaWRlXHJcbiAgICAgICAgICAgIHRoaXMuc2V0VHJhbnNsYXRlKCRjdXJyZW50U2xpZGUsIGRpc3RhbmNlWCwgMCk7XHJcbiAgICAgICAgICAgIC8vIG1vdmUgbmV4dCBhbmQgcHJldiBzbGlkZSB3aXRoIGN1cnJlbnQgc2xpZGVcclxuICAgICAgICAgICAgdmFyIHdpZHRoID0gJGN1cnJlbnRTbGlkZS5nZXQoKS5vZmZzZXRXaWR0aDtcclxuICAgICAgICAgICAgdmFyIHNsaWRlV2lkdGhBbW91bnQgPSAod2lkdGggKiAxNSkgLyAxMDA7XHJcbiAgICAgICAgICAgIHZhciBndXR0ZXIgPSBzbGlkZVdpZHRoQW1vdW50IC0gTWF0aC5hYnMoKGRpc3RhbmNlWCAqIDEwKSAvIDEwMCk7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0VHJhbnNsYXRlKHRoaXMub3V0ZXIuZmluZCgnLmxnLXByZXYtc2xpZGUnKS5maXJzdCgpLCAtd2lkdGggKyBkaXN0YW5jZVggLSBndXR0ZXIsIDApO1xyXG4gICAgICAgICAgICB0aGlzLnNldFRyYW5zbGF0ZSh0aGlzLm91dGVyLmZpbmQoJy5sZy1uZXh0LXNsaWRlJykuZmlyc3QoKSwgd2lkdGggKyBkaXN0YW5jZVggKyBndXR0ZXIsIDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0aGlzLnN3aXBlRGlyZWN0aW9uID09PSAndmVydGljYWwnKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmdzLnN3aXBlVG9DbG9zZSkge1xyXG4gICAgICAgICAgICAgICAgZSA9PT0gbnVsbCB8fCBlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLiRjb250YWluZXIuYWRkQ2xhc3MoJ2xnLWRyYWdnaW5nLXZlcnRpY2FsJyk7XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgb3BhY2l0eSA9IDEgLSBNYXRoLmFicyhkaXN0YW5jZVkpIC8gd2luZG93LmlubmVySGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy4kYmFja2Ryb3AuY3NzKCdvcGFjaXR5Jywgb3BhY2l0eSk7XHJcbiAgICAgICAgICAgICAgICB2YXIgc2NhbGUgPSAxIC0gTWF0aC5hYnMoZGlzdGFuY2VZKSAvICh3aW5kb3cuaW5uZXJXaWR0aCAqIDIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUcmFuc2xhdGUoJGN1cnJlbnRTbGlkZSwgMCwgZGlzdGFuY2VZLCBzY2FsZSwgc2NhbGUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKGRpc3RhbmNlWSkgPiAxMDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm91dGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnbGctaGlkZS1pdGVtcycpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnbGctY29tcG9uZW50cy1vcGVuJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS50b3VjaEVuZCA9IGZ1bmN0aW9uIChlbmRDb29yZHMsIHN0YXJ0Q29vcmRzLCBldmVudCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGRpc3RhbmNlO1xyXG4gICAgICAgIC8vIGtlZXAgc2xpZGUgYW5pbWF0aW9uIGZvciBhbnkgbW9kZSB3aGlsZSBkcmFnZy9zd2lwZVxyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLm1vZGUgIT09ICdsZy1zbGlkZScpIHtcclxuICAgICAgICAgICAgdGhpcy5vdXRlci5hZGRDbGFzcygnbGctc2xpZGUnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gc2V0IHRyYW5zaXRpb24gZHVyYXRpb25cclxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuJGNvbnRhaW5lci5yZW1vdmVDbGFzcygnbGctZHJhZ2dpbmctdmVydGljYWwnKTtcclxuICAgICAgICAgICAgX3RoaXMub3V0ZXJcclxuICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnbGctZHJhZ2dpbmcgbGctaGlkZS1pdGVtcycpXHJcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2xnLWNvbXBvbmVudHMtb3BlbicpO1xyXG4gICAgICAgICAgICB2Y
1XIgdHJpZ2dlckNsaWNrID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKF90aGlzLnN3aXBlRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcclxuICAgICAgICAgICAgICAgIGRpc3RhbmNlID0gZW5kQ29vcmRzLnBhZ2VYIC0gc3RhcnRDb29yZHMucGFnZVg7XHJcbiAgICAgICAgICAgICAgICB2YXIgZGlzdGFuY2VBYnMgPSBNYXRoLmFicyhlbmRDb29yZHMucGFnZVggLSBzdGFydENvb3Jkcy5wYWdlWCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGlzdGFuY2UgPCAwICYmXHJcbiAgICAgICAgICAgICAgICAgICAgZGlzdGFuY2VBYnMgPiBfdGhpcy5zZXR0aW5ncy5zd2lwZVRocmVzaG9sZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmdvVG9OZXh0U2xpZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJpZ2dlckNsaWNrID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChkaXN0YW5jZSA+IDAgJiZcclxuICAgICAgICAgICAgICAgICAgICBkaXN0YW5jZUFicyA+IF90aGlzLnNldHRpbmdzLnN3aXBlVGhyZXNob2xkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuZ29Ub1ByZXZTbGlkZSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyQ2xpY2sgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChfdGhpcy5zd2lwZURpcmVjdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xyXG4gICAgICAgICAgICAgICAgZGlzdGFuY2UgPSBNYXRoLmFicyhlbmRDb29yZHMucGFnZVkgLSBzdGFydENvb3Jkcy5wYWdlWSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuc2V0dGluZ3MuY2xvc2FibGUgJiZcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXR0aW5ncy5zd2lwZVRvQ2xvc2UgJiZcclxuICAgICAgICAgICAgICAgICAgICBkaXN0YW5jZSA+IDEwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmNsb3NlR2FsbGVyeSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLiRiYWNrZHJvcC5jc3MoJ29wYWNpdHknLCAxKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5vdXRlci5maW5kKCcubGctaXRlbScpLnJlbW92ZUF0dHIoJ3N0eWxlJyk7XHJcbiAgICAgICAgICAgIGlmICh0cmlnZ2VyQ2xpY2sgJiZcclxuICAgICAgICAgICAgICAgIE1hdGguYWJzKGVuZENvb3Jkcy5wYWdlWCAtIHN0YXJ0Q29vcmRzLnBhZ2VYKSA8IDUpIHtcclxuICAgICAgICAgICAgICAgIC8vIFRyaWdnZXIgY2xpY2sgaWYgZGlzdGFuY2UgaXMgbGVzcyB0aGFuIDUgcGl4XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgdGFyZ2V0ID0gJExHKGV2ZW50LnRhcmdldCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuaXNQb3N0ZXJFbGVtZW50KHRhcmdldCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMucG9zdGVyQ2xpY2spO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLnN3aXBlRGlyZWN0aW9uID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIHJlbW92ZSBzbGlkZSBjbGFzcyBvbmNlIGRyYWcvc3dpcGUgaXMgY29tcGxldGVkIGlmIG1vZGUgaXMgbm90IHNsaWRlXHJcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghX3RoaXMub3V0ZXIuaGFzQ2xhc3MoJ2xnLWRyYWdnaW5nJykgJiZcclxuICAgICAgICAgICAgICAgIF90aGlzLnNldHRpbmdzLm1vZGUgIT09ICdsZy1zbGlkZScpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLnJlbW92ZUNsYXNzKCdsZy1zbGlkZScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgdGhpcy5zZXR0aW5ncy5zcGVlZCArIDEwMCk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5lbmFibGVTd2lwZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBzdGFydENvb3JkcyA9IHt9O1xyXG4gICAgICAgIHZhciBlbmRDb29yZHMgPSB7fTtcclxuICAgICAgICB2Y
1XIgaXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgICAgIHZhciBpc1N3aXBpbmcgPSBmYWxzZTtcclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5lbmFibGVTd2lwZSkge1xyXG4gICAgICAgICAgICB0aGlzLiRpbm5lci5vbigndG91Y2hzdGFydC5sZycsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5kcmFnT3JTd2lwZUVuYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdmFyICRpdGVtID0gX3RoaXMuZ2V0U2xpZGVJdGVtKF90aGlzLmluZGV4KTtcclxuICAgICAgICAgICAgICAgIGlmICgoJExHKGUudGFyZ2V0KS5oYXNDbGFzcygnbGctaXRlbScpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgJGl0ZW0uZ2V0KCkuY29udGFpbnMoZS50YXJnZXQpKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICFfdGhpcy5vdXRlci5oYXNDbGFzcygnbGctem9vbWVkJykgJiZcclxuICAgICAgICAgICAgICAgICAgICAhX3RoaXMubGdCdXN5ICYmXHJcbiAgICAgICAgICAgICAgICAgICAgZS50b3VjaGVzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlzU3dpcGluZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMudG91Y2hBY3Rpb24gPSAnc3dpcGUnO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLm1hbmFnZVN3aXBlQ2xhc3MoKTtcclxuICAgICAgICAgICAgICAgICAgICBzdGFydENvb3JkcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFnZVg6IGUudG91Y2hlc1swXS5wYWdlWCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFnZVk6IGUudG91Y2hlc1swXS5wYWdlWSxcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy4kaW5uZXIub24oJ3RvdWNobW92ZS5sZycsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXNTd2lwaW5nICYmXHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMudG91Y2hBY3Rpb24gPT09ICdzd2lwZScgJiZcclxuICAgICAgICAgICAgICAgICAgICBlLnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW5kQ29vcmRzID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYWdlWDogZS50b3VjaGVzWzBdLnBhZ2VYLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYWdlWTogZS50b3VjaGVzWzBdLnBhZ2VZLFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMudG91Y2hNb3ZlKHN0YXJ0Q29vcmRzLCBlbmRDb29yZHMsIGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlzTW92ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy4kaW5uZXIub24oJ3RvdWNoZW5kLmxnJywgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMudG91Y2hBY3Rpb24gPT09ICdzd2lwZScpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNNb3ZlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc01vdmVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnRvdWNoRW5kKGVuZENvb3Jkcywgc3RhcnRDb29yZHMsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaXNTd2lwaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSAkTEcoZXZlbnQudGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLmlzUG9zdGVyRWxlbWVudCh0YXJnZXQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMucG9zdGVyQ2xpY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnRvdWNoQWN0aW9uID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgIGlzU3dpcGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5lbmFibGVEcmFnID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHN0YXJ0Q29vcmRzID0ge307XHJcbiAgICAgICAgdmFyIGVuZENvb3JkcyA9IHt9O1xyXG4gICAgICAgIHZhciBpc0RyYWdpbmcgPSBmYWxzZTtcclxuICAgICAgICB2Y
1XIgaXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLmVuYWJsZURyYWcpIHtcclxuICAgICAgICAgICAgdGhpcy5vdXRlci5vbignbW91c2Vkb3duLmxnJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmRyYWdPclN3aXBlRW5hYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB2YXIgJGl0ZW0gPSBfdGhpcy5nZXRTbGlkZUl0ZW0oX3RoaXMuaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCRMRyhlLnRhcmdldCkuaGFzQ2xhc3MoJ2xnLWl0ZW0nKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICRpdGVtLmdldCgpLmNvbnRhaW5zKGUudGFyZ2V0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX3RoaXMub3V0ZXIuaGFzQ2xhc3MoJ2xnLXpvb21lZCcpICYmICFfdGhpcy5sZ0J1c3kpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV90aGlzLmxnQnVzeSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMubWFuYWdlU3dpcGVDbGFzcygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRDb29yZHMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFnZVg6IGUucGFnZVgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFnZVk6IGUucGFnZVksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNEcmFnaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICoqIEZpeCBmb3Igd2Via2l0IGN1cnNvciBpc3N1ZSBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9MjY3MjNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLmdldCgpLnNjcm9sbExlZnQgKz0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLmdldCgpLnNjcm9sbExlZnQgLT0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLm91dGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCdsZy1ncmFiJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2xnLWdyYWJiaW5nJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMuZHJhZ1N0YXJ0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICRMRyh3aW5kb3cpLm9uKFwibW91c2Vtb3ZlLmxnLmdsb2JhbFwiICsgdGhpcy5sZ0lkLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzRHJhZ2luZyAmJiBfdGhpcy5sZ09wZW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlzTW92ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGVuZENvb3JkcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFnZVg6IGUucGFnZVgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VZOiBlLnBhZ2VZLFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMudG91Y2hNb3ZlKHN0YXJ0Q29vcmRzLCBlbmRDb29yZHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLkxHZWwudHJpZ2dlcihsR0V2ZW50cy5kcmFnTW92ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAkTEcod2luZG93KS5vbihcIm1vdXNldXAubGcuZ2xvYmFsXCIgKyB0aGlzLmxnSWQsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFfdGhpcy5sZ09wZW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSAkTEcoZXZlbnQudGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgIGlmIChpc01vdmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnRvdWNoRW5kKGVuZENvb3Jkcywgc3RhcnRDb29yZHMsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMuZHJhZ0VuZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChfdGhpcy5pc1Bvc3RlckVsZW1lbnQodGFyZ2V0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLkxHZWwudHJpZ2dlcihsR0V2ZW50cy5wb3N0ZXJDbGljayk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBQcmV2ZW50IGV4ZWN1dGlvbiBvbiBjbGlja1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzRHJhZ2luZykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlzRHJhZ2luZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLnJlbW92ZUNsYXNzKCdsZy1ncmFiYmluZycpLmFkZENsYXNzKCdsZy1ncmFiJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLnRyaWdnZXJQb3N0ZXJDbGljayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMuJGlubmVyLm9uKCdjbGljay5sZycsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICBpZiAoIV90aGlzLmRyYWdPclN3aXBlRW5hYmxlZCAmJlxyXG4gICAgICAgICAgICAgICAgX3RoaXMuaXNQb3N0ZXJFbGVtZW50KCRMRyhldmVudC50YXJnZXQpKSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuTEdlbC50cmlnZ2VyKGxHRXZlbnRzLnBvc3RlckNsaWNrKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUubWFuYWdlU3dpcGVDbGFzcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RvdWNoTmV4dCA9IHRoaXMuaW5kZXggKyAxO1xyXG4gICAgICAgIHZhciBfdG91Y2hQcmV2ID0gdGhpcy5pbmRleCAtIDE7XHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MubG9vcCAmJiB0aGlzLmdhbGxlcnlJdGVtcy5sZW5ndGggPiAyKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmluZGV4ID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBfdG91Y2hQcmV2ID0gdGhpcy5nYWxsZXJ5SXRlbXMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLmluZGV4ID09PSB0aGlzLmdhbGxlcnlJdGVtcy5sZW5ndGggLSAxKSB7XHJcbiAgICAgICAgICAgICAgICBfdG91Y2hOZXh0ID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLm91dGVyLmZpbmQoJy5sZy1pdGVtJykucmVtb3ZlQ2xhc3MoJ2xnLW5leHQtc2xpZGUgbGctcHJldi1zbGlkZScpO1xyXG4gICAgICAgIGlmIChfdG91Y2hQcmV2ID4gLTEpIHtcclxuICAgICAgICAgICAgdGhpcy5nZXRTbGlkZUl0ZW0oX3RvdWNoUHJldikuYWRkQ2xhc3MoJ2xnLXByZXYtc2xpZGUnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5nZXRTbGlkZUl0ZW0oX3RvdWNoTmV4dCkuYWRkQ2xhc3MoJ2xnLW5leHQtc2xpZGUnKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdvIHRvIG5leHQgc2xpZGVcclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZnJvbVRvdWNoIC0gdHJ1ZSBpZiBzbGlkZSBmdW5jdGlvbiBjYWxsZWQgdmlhIHRvdWNoIGV2ZW50XHJcbiAgICAgKiBAY2F0ZWdvcnkgbEdQdWJsaWNNZXRob2RzXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIGNvbnN0IHBsdWdpbiA9IGxpZ2h0R2FsbGVyeSgpO1xyXG4gICAgICogIHBsdWdpbi5nb1RvTmV4dFNsaWRlKCk7XHJcbiAgICAgKiBAc2VlIDxhIGhyZWY9XCIvZGVtb3MvbWV0aG9kcy9cIj5EZW1vPC9hPlxyXG4gICAgICovXHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmdvVG9OZXh0U2xpZGUgPSBmdW5jdGlvbiAoZnJvbVRvdWNoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2Y
1XIgX2xvb3AgPSB0aGlzLnNldHRpbmdzLmxvb3A7XHJcbiAgICAgICAgaWYgKGZyb21Ub3VjaCAmJiB0aGlzLmdhbGxlcnlJdGVtcy5sZW5ndGggPCAzKSB7XHJcbiAgICAgICAgICAgIF9sb29wID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5sZ0J1c3kpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXggKyAxIDwgdGhpcy5nYWxsZXJ5SXRlbXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmluZGV4Kys7XHJcbiAgICAgICAgICAgICAgICB0aGlzLkxHZWwudHJpZ2dlcihsR0V2ZW50cy5iZWZvcmVOZXh0U2xpZGUsIHtcclxuICAgICAgICAgICAgICAgICAgICBpbmRleDogdGhpcy5pbmRleCxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zbGlkZSh0aGlzLmluZGV4LCAhIWZyb21Ub3VjaCwgZmFsc2UsICduZXh0Jyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoX2xvb3ApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGV4ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLkxHZWwudHJpZ2dlcihsR0V2ZW50cy5iZWZvcmVOZXh0U2xpZGUsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHRoaXMuaW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zbGlkZSh0aGlzLmluZGV4LCAhIWZyb21Ub3VjaCwgZmFsc2UsICduZXh0Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLnNldHRpbmdzLnNsaWRlRW5kQW5pbWF0aW9uICYmICFmcm9tVG91Y2gpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm91dGVyLmFkZENsYXNzKCdsZy1yaWdodC1lbmQnKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLXJpZ2h0LWVuZCcpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHbyB0byBwcmV2aW91cyBzbGlkZXNcclxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gZnJvbVRvdWNoIC0gdHJ1ZSBpZiBzbGlkZSBmdW5jdGlvbiBjYWxsZWQgdmlhIHRvdWNoIGV2ZW50XHJcbiAgICAgKiBAY2F0ZWdvcnkgbEdQdWJsaWNNZXRob2RzXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIGNvbnN0IHBsdWdpbiA9IGxpZ2h0R2FsbGVyeSh7fSk7XHJcbiAgICAgKiAgcGx1Z2luLmdvVG9QcmV2U2xpZGUoKTtcclxuICAgICAqIEBzZWUgPGEgaHJlZj1cIi9kZW1vcy9tZXRob2RzL1wiPkRlbW88L2E+XHJcbiAgICAgKlxyXG4gICAgICovXHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmdvVG9QcmV2U2xpZGUgPSBmdW5jdGlvbiAoZnJvbVRvdWNoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2Y
1XIgX2xvb3AgPSB0aGlzLnNldHRpbmdzLmxvb3A7XHJcbiAgICAgICAgaWYgKGZyb21Ub3VjaCAmJiB0aGlzLmdhbGxlcnlJdGVtcy5sZW5ndGggPCAzKSB7XHJcbiAgICAgICAgICAgIF9sb29wID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5sZ0J1c3kpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmluZGV4LS07XHJcbiAgICAgICAgICAgICAgICB0aGlzLkxHZWwudHJpZ2dlcihsR0V2ZW50cy5iZWZvcmVQcmV2U2xpZGUsIHtcclxuICAgICAgICAgICAgICAgICAgICBpbmRleDogdGhpcy5pbmRleCxcclxuICAgICAgICAgICAgICAgICAgICBmcm9tVG91Y2g6IGZyb21Ub3VjaCxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zbGlkZSh0aGlzLmluZGV4LCAhIWZyb21Ub3VjaCwgZmFsc2UsICdwcmV2Jyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoX2xvb3ApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGV4ID0gdGhpcy5nYWxsZXJ5SXRlbXMubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLkxHZWwudHJpZ2dlcihsR0V2ZW50cy5iZWZvcmVQcmV2U2xpZGUsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHRoaXMuaW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZyb21Ub3VjaDogZnJvbVRvdWNoLFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2xpZGUodGhpcy5pbmRleCwgISFmcm9tVG91Y2gsIGZhbHNlLCAncHJldicpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5zZXR0aW5ncy5zbGlkZUVuZEFuaW1hdGlvbiAmJiAhZnJvbVRvdWNoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRlci5hZGRDbGFzcygnbGctbGVmdC1lbmQnKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLWxlZnQtZW5kJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgNDAwKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmtleVByZXNzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgJExHKHdpbmRvdykub24oXCJrZXlkb3duLmxnLmdsb2JhbFwiICsgdGhpcy5sZ0lkLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMubGdPcGVuZWQgJiZcclxuICAgICAgICAgICAgICAgIF90aGlzLnNldHRpbmdzLmVzY0tleSA9PT0gdHJ1ZSAmJlxyXG4gICAgICAgICAgICAgICAgZS5rZXlDb2RlID09PSAyNykge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKF90aGlzLnNldHRpbmdzLmFsbG93TWVkaWFPdmVybGFwICYmXHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMub3V0ZXIuaGFzQ2xhc3MoJ2xnLWNhbi10b2dnbGUnKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLmhhc0NsYXNzKCdsZy1jb21wb25lbnRzLW9wZW4nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLm91dGVyLnJlbW92ZUNsYXNzKCdsZy1jb21wb25lbnRzLW9wZW4nKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmNsb3NlR2FsbGVyeSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5sZ09wZW5lZCAmJiBfdGhpcy5nYWxsZXJ5SXRlbXMubGVuZ3RoID4gMSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gMzcpIHtcclxuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuZ29Ub1ByZXZTbGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gMzkpIHtcclxuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuZ29Ub05leHRTbGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5hcnJvdyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMuZ2V0RWxlbWVudEJ5SWQoJ2xnLXByZXYnKS5vbignY2xpY2subGcnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLmdvVG9QcmV2U2xpZGUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmdldEVsZW1lbnRCeUlkKCdsZy1uZXh0Jykub24oJ2NsaWNrLmxnJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5nb1RvTmV4dFNsaWRlKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5hcnJvd0Rpc2FibGUgPSBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICAvLyBEaXNhYmxlIGFycm93cyBpZiBzZXR0aW5ncy5oaWRlQ29udHJvbE9uRW5kIGlzIHRydWVcclxuICAgICAgICBpZiAoIXRoaXMuc2V0dGluZ3MubG9vcCAmJiB0aGlzLnNldHRpbmdzLmhpZGVDb250cm9sT25FbmQpIHtcclxuICAgICAgICAgICAgdmFyICRwcmV2ID0gdGhpcy5nZXRFbGVtZW50QnlJZCgnbGctcHJldicpO1xyXG4gICAgICAgICAgICB2YXIgJG5leHQgPSB0aGlzLmdldEVsZW1lbnRCeUlkKCdsZy1uZXh0Jyk7XHJcbiAgICAgICAgICAgIGlmIChpbmRleCArIDEgPT09IHRoaXMuZ2FsbGVyeUl0ZW1zLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgJG5leHQuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKS5hZGRDbGFzcygnZGlzYWJsZWQnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICRuZXh0LnJlbW92ZUF0dHIoJ2Rpc2FibGVkJykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAkcHJldi5hdHRyKCdkaXNhYmxlZCcsICdkaXNhYmxlZCcpLmFkZENsYXNzKCdkaXNhYmxlZCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgJHByZXYucmVtb3ZlQXR0cignZGlzYWJsZWQnKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLnNldFRyYW5zbGF0ZSA9IGZ1bmN0aW9uICgkZWwsIHhWYWx1ZSwgeVZhbHVlLCBzY2FsZVgsIHNjYWxlWSkge1xyXG4gICAgICAgIGlmIChzY2FsZVggPT09IHZvaWQgMCkgeyBzY2FsZVggPSAxOyB9XHJcbiAgICAgICAgaWYgKHNjYWxlWSA9PT0gdm9pZCAwKSB7IHNjYWxlWSA9IDE7IH1cclxuICAgICAgICAkZWwuY3NzKCd0cmFuc2Zvcm0nLCAndHJhbnNsYXRlM2QoJyArXHJcbiAgICAgICAgICAgIHhWYWx1ZSArXHJcbiAgICAgICAgICAgICdweCwgJyArXHJcbiAgICAgICAgICAgIHlWYWx1ZSArXHJcbiAgICAgICAgICAgICdweCwgMHB4KSBzY2FsZTNkKCcgK1xyXG4gICAgICAgICAgICBzY2FsZVggK1xyXG4gICAgICAgICAgICAnLCAnICtcclxuICAgICAgICAgICAgc2NhbGVZICtcclxuICAgICAgICAgICAgJywgMSknKTtcclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLm1vdXNld2hlZWwgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2Y
1XIgbGFzdENhbGwgPSAwO1xyXG4gICAgICAgIHRoaXMub3V0ZXIub24oJ3doZWVsLmxnJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgaWYgKCFlLmRlbHRhWSB8fCBfdGhpcy5nYWxsZXJ5SXRlbXMubGVuZ3RoIDwgMikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgdmFyIG5vdyA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgICAgICAgICBpZiAobm93IC0gbGFzdENhbGwgPCAxMDAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbGFzdENhbGwgPSBub3c7XHJcbiAgICAgICAgICAgIGlmIChlLmRlbHRhWSA+IDApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdvVG9OZXh0U2xpZGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChlLmRlbHRhWSA8IDApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdvVG9QcmV2U2xpZGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuaXNTbGlkZUVsZW1lbnQgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XHJcbiAgICAgICAgcmV0dXJuICh0YXJnZXQuaGFzQ2xhc3MoJ2xnLW91dGVyJykgfHxcclxuICAgICAgICAgICAgdGFyZ2V0Lmhhc0NsYXNzKCdsZy1pdGVtJykgfHxcclxuICAgICAgICAgICAgdGFyZ2V0Lmhhc0NsYXNzKCdsZy1pbWctd3JhcCcpKTtcclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmlzUG9zdGVyRWxlbWVudCA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcclxuICAgICAgICB2Y
1XIgcGxheUJ1dHRvbiA9IHRoaXMuZ2V0U2xpZGVJdGVtKHRoaXMuaW5kZXgpXHJcbiAgICAgICAgICAgIC5maW5kKCcubGctdmlkZW8tcGxheS1idXR0b24nKVxyXG4gICAgICAgICAgICAuZ2V0KCk7XHJcbiAgICAgICAgcmV0dXJuICh0YXJnZXQuaGFzQ2xhc3MoJ2xnLXZpZGVvLXBvc3RlcicpIHx8XHJcbiAgICAgICAgICAgIHRhcmdldC5oYXNDbGFzcygnbGctdmlkZW8tcGxheS1idXR0b24nKSB8fFxyXG4gICAgICAgICAgICAocGxheUJ1dHRvbiAmJiBwbGF5QnV0dG9uLmNvbnRhaW5zKHRhcmdldC5nZXQoKSkpKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIE1heGltaXplIG1pbmltaXplIGlubGluZSBnYWxsZXJ5LlxyXG4gICAgICogQGNhdGVnb3J5IGxHUHVibGljTWV0aG9kc1xyXG4gICAgICovXHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLnRvZ2dsZU1heGltaXplID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdGhpcy5nZXRFbGVtZW50QnlJZCgnbGctbWF4aW1pemUnKS5vbignY2xpY2subGcnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLiRjb250YWluZXIudG9nZ2xlQ2xhc3MoJ2xnLWlubGluZScpO1xyXG4gICAgICAgICAgICBfdGhpcy5yZWZyZXNoT25SZXNpemUoKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmludmFsaWRhdGVJdGVtcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5pdGVtcy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzLml0ZW1zW2luZGV4XTtcclxuICAgICAgICAgICAgdmFyICRlbGVtZW50ID0gJExHKGVsZW1lbnQpO1xyXG4gICAgICAgICAgICAkZWxlbWVudC5vZmYoXCJjbGljay5sZ2N1c3RvbS1pdGVtLVwiICsgJGVsZW1lbnQuYXR0cignZGF0YS1sZy1pZCcpKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS50cmFwRm9jdXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB0aGlzLiRjb250YWluZXIuZ2V0KCkuZm9jdXMoe1xyXG4gICAgICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgICRMRyh3aW5kb3cpLm9uKFwia2V5ZG93bi5sZy5nbG9iYWxcIiArIHRoaXMubGdJZCwgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgaWYgKCFfdGhpcy5sZ09wZW5lZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBpc1RhYlByZXNzZWQgPSBlLmtleSA9PT0gJ1RhYicgfHwgZS5rZXlDb2RlID09PSA5O1xyXG4gICAgICAgICAgICBpZiAoIWlzVGFiUHJlc3NlZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBmb2N1c2FibGVFbHMgPSB1dGlscy5nZXRGb2N1c2FibGVFbGVtZW50cyhfdGhpcy4kY29udGFpbmVyLmdldCgpKTtcclxuICAgICAgICAgICAgdmFyIGZpcnN0Rm9jdXNhYmxlRWwgPSBmb2N1c2FibGVFbHNbMF07XHJcbiAgICAgICAgICAgIHZhciBsYXN0Rm9jdXNhYmxlRWwgPSBmb2N1c2FibGVFbHNbZm9jdXNhYmxlRWxzLmxlbmd0aCAtIDFdO1xyXG4gICAgICAgICAgICBpZiAoZS5zaGlmdEtleSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT09IGZpcnN0Rm9jdXNhYmxlRWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBsYXN0Rm9jdXNhYmxlRWwuZm9jdXMoKTtcclxuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCA9PT0gbGFzdEZvY3VzYWJsZUVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RGb2N1c2FibGVFbC5mb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUubWFuYWdlQ2xvc2VHYWxsZXJ5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLmNsb3NhYmxlKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgdmFyIG1vdXNlZG93biA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuZ2V0RWxlbWVudEJ5SWQoJ2xnLWNsb3NlJykub24oJ2NsaWNrLmxnJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5jbG9zZUdhbGxlcnkoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5jbG9zZU9uVGFwKSB7XHJcbiAgICAgICAgICAgIC8vIElmIHlvdSBkcmFnIHRoZSBzbGlkZSBhbmQgcmVsZWFzZSBvdXRzaWRlIGdhbGxlcnkgZ2V0cyBjbG9zZSBvbiBjaHJvbWVcclxuICAgICAgICAgICAgLy8gZm9yIHByZXZlbnRpbmcgdGhpcyBjaGVjayBtb3VzZWRvd24gYW5kIG1vdXNldXAgaGFwcGVuZWQgb24gLmxnLWl0ZW0gb3IgbGctb3V0ZXJcclxuICAgICAgICAgICAgdGhpcy5vdXRlci5vbignbW91c2Vkb3duLmxnJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSAkTEcoZS50YXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKF90aGlzLmlzU2xpZGVFbGVtZW50KHRhcmdldCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBtb3VzZWRvd24gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbW91c2Vkb3duID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgI
1H0pO1xyXG4gICAgICAgICAgICB0aGlzLm91dGVyLm9uKCdtb3VzZW1vdmUubGcnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBtb3VzZWRvd24gPSBmYWxzZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMub3V0ZXIub24oJ21vdXNldXAubGcnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHRhcmdldCA9ICRMRyhlLnRhcmdldCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuaXNTbGlkZUVsZW1lbnQodGFyZ2V0KSAmJiBtb3VzZWRvd24pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIV90aGlzLm91dGVyLmhhc0NsYXNzKCdsZy1kcmFnZ2luZycpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmNsb3NlR2FsbGVyeSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2xvc2UgbGlnaHRHYWxsZXJ5IGlmIGl0IGlzIG9wZW5lZC5cclxuICAgICAqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gSWYgY2xvc2FibGUgaXMgZmFsc2UgaW4gdGhlIHNldHRpbmdzLCB5b3UgbmVlZCB0byBwYXNzIHRydWUgdmlhIGNsb3NlR2FsbGVyeSBtZXRob2QgdG8gZm9yY2UgY2xvc2UgZ2FsbGVyeVxyXG4gICAgICogQHJldHVybiByZXR1cm5zIHRoZSBlc3RpbWF0ZWQgdGltZSB0byBjbG9zZSBnYWxsZXJ5IGNvbXBsZXRlbHkgaW5jbHVkaW5nIHRoZSBjbG9zZSBhbmltYXRpb24gZHVyYXRpb25cclxuICAgICAqIEBjYXRlZ29yeSBsR1B1YmxpY01ldGhvZHNcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgY29uc3QgcGx1Z2luID0gbGlnaHRHYWxsZXJ5KCk7XHJcbiAgICAgKiAgcGx1Z2luLmNsb3NlR2FsbGVyeSgpO1xyXG4gICAgICpcclxuICAgICAqL1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5jbG9zZUdhbGxlcnkgPSBmdW5jdGlvbiAoZm9yY2UpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmICghdGhpcy5sZ09wZW5lZCB8fCAoIXRoaXMuc2V0dGluZ3MuY2xvc2FibGUgJiYgIWZvcmNlKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMuYmVmb3JlQ2xvc2UpO1xyXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLnJlc2V0U2Nyb2xsUG9zaXRpb24gJiYgIXRoaXMuc2V0dGluZ3MuaGlkZVNjcm9sbGJhcikge1xyXG4gICAgICAgICAgICAkTEcod2luZG93KS5zY3JvbGxUb3AodGhpcy5wcmV2U2Nyb2xsVG9wKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGN1cnJlbnRJdGVtID0gdGhpcy5pdGVtc1t0aGlzLmluZGV4XTtcclxuICAgICAgICB2YXIgdHJhbnNmb3JtO1xyXG4gICAgICAgIGlmICh0aGlzLnpvb21Gcm9tT3JpZ2luICYmIGN1cnJlbnRJdGVtKSB7XHJcbiAgICAgICAgICAgIHZhciBfYSA9IHRoaXMubWVkaWFDb250YWluZXJQb3NpdGlvbiwgdG9wXzQgPSBfYS50b3AsIGJvdHRvbSA9IF9hLmJvdHRvbTtcclxuICAgICAgICAgICAgdmFyIF9iID0gdGhpcy5nYWxsZXJ5SXRlbXNbdGhpcy5pbmRleF0sIF9fc2xpZGVWaWRlb0luZm8gPSBfYi5fX3NsaWRlVmlkZW9JbmZvLCBwb3N0ZXIgPSBfYi5wb3N0ZXI7XHJcbiAgICAgICAgICAgIHZhciBpbWFnZVNpemUgPSB1dGlscy5nZXRTaXplKGN1cnJlbnRJdGVtLCB0aGlzLm91dGVyLCB0b3BfNCArIGJvdHRvbSwgX19zbGlkZVZpZGVvSW5mbyAmJiBwb3N0ZXIgJiYgdGhpcy5zZXR0aW5ncy52aWRlb01heFNpemUpO1xyXG4gICAgICAgICAgICB0cmFuc2Zvcm0gPSB1dGlscy5nZXRUcmFuc2Zvcm0oY3VycmVudEl0ZW0sIHRoaXMub3V0ZXIsIHRvcF80LCBib3R0b20sIGltYWdlU2l6ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLnpvb21Gcm9tT3JpZ2luICYmIHRyYW5zZm9ybSkge1xyXG4gICAgICAgICAgICB0aGlzLm91dGVyLmFkZENsYXNzKCdsZy1jbG9zaW5nIGxnLXpvb20tZnJvbS1pbWFnZScpO1xyXG4gICAgICAgICAgICB0aGlzLmdldFNsaWRlSXRlbSh0aGlzLmluZGV4KVxyXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKCdsZy1zdGFydC1lbmQtcHJvZ3Jlc3MnKVxyXG4gICAgICAgICAgICAgICAgLmNzcygndHJhbnNpdGlvbi1kdXJhdGlvbicsIHRoaXMuc2V0dGluZ3Muc3RhcnRBbmltYXRpb25EdXJhdGlvbiArICdtcycpXHJcbiAgICAgICAgICAgICAgICAuY3NzKCd0cmFuc2Zvcm0nLCB0cmFuc2Zvcm0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5vdXRlci5hZGRDbGFzcygnbGctaGlkZS1pdGVtcycpO1xyXG4gICAgICAgICAgICAvLyBsZy16b29tLWZyb20taW1hZ2UgaXMgdXNlZCBmb3Igc2V0dGluZyB0aGUgb3BhY2l0eSB0byAxIGlmIHpvb21Gcm9tT3JpZ2luIGlzIHRydWVcclxuICAgICAgICAgICAgLy8gSWYgdGhlIGNsb3NpbmcgaXRlbSBkb2Vzbid0IGhhdmUgdGhlIGxnLXNpemUgYXR0cmlidXRlLCByZW1vdmUgdGhpcyBjbGFzcyB0byBhdm9pZCB0aGUgY2xvc2luZyBjc3MgY29uZmxpY3RzXHJcbiAgICAgICAgICAgIHRoaXMub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLXpvb20tZnJvbS1pbWFnZScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBVbmJpbmQgYWxsIGV2ZW50cyBhZGRlZCBieSBsaWdodEdhbGxlcnlcclxuICAgICAgICAvLyBAdG9kb1xyXG4gICAgICAgIC8vdGhpcy4kZWwub2ZmKCcubGcudG0nKTtcclxuICAgICAgICB0aGlzLmRlc3Ryb3lNb2R1bGVzKCk7XHJcbiAgICAgICAgdGhpcy5sR2FsbGVyeU9uID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5pc0R1bW15SW1hZ2VSZW1vdmVkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy56b29tRnJvbU9yaWdpbiA9IHRoaXMuc2V0dGluZ3Muem9vbUZyb21PcmlnaW47XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuaGlkZUJhclRpbWVvdXQpO1xyXG4gICAgICAgIHRoaXMuaGlkZUJhclRpbWVvdXQgPSBmYWxzZTtcclxuICAgICAgICAkTEcoJ2h0bWwnKS5yZW1vdmVDbGFzcygnbGctb24nKTtcclxuICAgICAgICB0aGlzLm91dGVyLnJlbW92ZUNsYXNzKCdsZy12aXNpYmxlIGxnLWNvbXBvbmVudHMtb3BlbicpO1xyXG4gICAgICAgIC8vIFJlc2V0dGluZyBvcGFjaXR5IHRvIDAgaXNkIHJlcXVpcmVkIGFzICB2ZXJ0aWNhbCBzd2lwZSB0byBjbG9zZSBmdW5jdGlvbiBhZGRzIGlubGluZSBvcGFjaXR5LlxyXG4gICAgICAgIHRoaXMuJGJhY2tkcm9wLnJlbW92ZUNsYXNzKCdpbicpLmNzcygnb3BhY2l0eScsIDApO1xyXG4gICAgICAgIHZhciByZW1vdmVUaW1lb3V0ID0gdGhpcy56b29tRnJvbU9yaWdpbiAmJiB0cmFuc2Zvcm1cclxuICAgICAgICAgICAgPyBNYXRoLm1heCh0aGlzLnNldHRpbmdzLnN0YXJ0QW5pbWF0aW9uRHVyYXRpb24sIHRoaXMuc2V0dGluZ3MuYmFja2Ryb3BEdXJhdGlvbilcclxuICAgICAgICAgICAgOiB0aGlzLnNldHRpbmdzLmJhY2tkcm9wRHVyYXRpb247XHJcbiAgICAgICAgdGhpcy4kY29udGFpbmVyLnJlbW92ZUNsYXNzKCdsZy1zaG93LWluJyk7XHJcbiAgICAgICAgLy8gT25jZSB0aGUgY2xvc2lnbiBhbmltYXRpb24gaXMgY29tcGxldGVkIGFuZCBnYWxsZXJ5IGlzIGludmlzaWJsZVxyXG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuem9vbUZyb21PcmlnaW4gJiYgdHJhbnNmb3JtKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5vdXRlci5yZW1vdmVDbGFzcygnbGctem9vbS1mcm9tLWltYWdlJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX3RoaXMuJGNvbnRhaW5lci5yZW1vdmVDbGFzcygnbGctc2hvdycpO1xyXG4gICAgICAgICAgICAvLyBSZXNldCBzY3JvbGxiYXJcclxuICAgICAgICAgICAgX3RoaXMucmVzZXRTY3JvbGxCYXIoKTtcclxuICAgICAgICAgICAgLy8gTmVlZCB0byByZW1vdmUgaW5saW5lIG9wYWNpdHkgYXMgaXQgaXMgdXNlZCBpbiB0aGUgc3R5bGVzaGVldCBhcyB3ZWxsXHJcbiAgICAgICAgICAgIF90aGlzLiRiYWNrZHJvcF
1xyXG4gICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ3N0eWxlJylcclxuICAgICAgICAgICAgICAgIC5jc3MoJ3RyYW5zaXRpb24tZHVyYXRpb24nLCBfdGhpcy5zZXR0aW5ncy5iYWNrZHJvcER1cmF0aW9uICsgJ21zJyk7XHJcbiAgICAgICAgICAgIF90aGlzLm91dGVyLnJlbW92ZUNsYXNzKFwibGctY2xvc2luZyBcIiArIF90aGlzLnNldHRpbmdzLnN0YXJ0Q2xhc3MpO1xyXG4gICAgICAgICAgICBfdGhpcy5nZXRTbGlkZUl0ZW0oX3RoaXMuaW5kZXgpLnJlbW92ZUNsYXNzKCdsZy1zdGFydC1lbmQtcHJvZ3Jlc3MnKTtcclxuICAgICAgICAgICAgX3RoaXMuJGlubmVyLmVtcHR5KCk7XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5sZ09wZW5lZCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuTEdlbC50cmlnZ2VyKGxHRXZlbnRzLmFmdGVyQ2xvc2UsIHtcclxuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZTogX3RoaXMsXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoX3RoaXMuJGNvbnRhaW5lci5nZXQoKSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuJGNvbnRhaW5lci5nZXQoKS5ibHVyKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX3RoaXMubGdPcGVuZWQgPSBmYWxzZTtcclxuICAgICAgICB9LCByZW1vdmVUaW1lb3V0ICsgMTAwKTtcclxuICAgICAgICByZXR1cm4gcmVtb3ZlVGltZW91dCArIDEwMDtcclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLmluaXRNb2R1bGVzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMucGx1Z2lucy5mb3JFYWNoKGZ1bmN0aW9uIChtb2R1bGUpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIG1vZHVsZS5pbml0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwibGlnaHRHYWxsZXJ5Oi0gbWFrZSBzdXJlIGxpZ2h0R2FsbGVyeSBtb2R1bGUgaXMgcHJvcGVybHkgaW5pdGlhdGVkXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgTGlnaHRHYWxsZXJ5LnByb3RvdHlwZS5kZXN0cm95TW9kdWxlcyA9IGZ1bmN0aW9uIChkZXN0cm95KSB7XHJcbiAgICAgICAgdGhpcy5wbHVnaW5zLmZvckVhY2goZnVuY3Rpb24gKG1vZHVsZSkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGRlc3Ryb3kpIHtcclxuICAgICAgICAgICAgICAgICAgICBtb2R1bGUuZGVzdHJveSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbW9kdWxlLmNsb3NlR2FsbGVyeSAmJiBtb2R1bGUuY2xvc2VHYWxsZXJ5KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwibGlnaHRHYWxsZXJ5Oi0gbWFrZSBzdXJlIGxpZ2h0R2FsbGVyeSBtb2R1bGUgaXMgcHJvcGVybHkgZGVzdHJveWVkXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZyZXNoIGxpZ2h0R2FsbGVyeSB3aXRoIG5ldyBzZXQgb2YgY2hpbGRyZW4uXHJcbiAgICAgKlxyXG4gICAgICogQGRlc2NyaXB0aW9uIFRoaXMgaXMgdXNlZnVsIHRvIHVwZGF0ZSB0aGUgZ2FsbGVyeSB3aGVuIHRoZSBjaGlsZCBlbGVtZW50cyBhcmUgY2hhbmdlZCB3aXRob3V0IGNhbGxpbmcgZGVzdHJveSBtZXRob2QuXHJcbiAgICAgKlxyXG4gICAgICogSWYgeW91IGFyZSB1c2luZyBkeW5hbWljIG1vZGUsIHlvdSBjYW4gcGFzcyB0aGUgbW9kaWZpZWQgYXJyYXkgb2YgZHluYW1pY0VsIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIgdG8gcmVmcmVzaCB0aGUgZHluYW1pYyBnYWxsZXJ5XHJcbiAgICAgKiBAc2VlIDxhIGhyZWY9XCIvZGVtb3MvZHluYW1pYy1tb2RlL1wiPkRlbW88L2E+XHJcbiAgICAgKiBAY2F0ZWdvcnkgbEdQdWJsaWNNZXRob2RzXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIGNvbnN0IHBsdWdpbiA9IGxpZ2h0R2FsbGVyeSgpO1xyXG4gICAgICogIC8vIERlbGV0ZSBvciBhZGQgY2hpbGRyZW4sIHRoZW4gY2FsbFxyXG4gICAgICogIHBsdWdpbi5yZWZyZXNoKCk7XHJcbiAgICAgKlxyXG4gICAgICovXHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbiAoZ2FsbGVyeUl0ZW1zKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLmR5bmFtaWMpIHtcclxuICAgICAgICAgICAgdGhpcy5pbnZhbGlkYXRlSXRlbXMoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGdhbGxlcnlJdGVtcykge1xyXG4gICAgICAgICAgICB0aGlzLmdhbGxlcnlJdGVtcyA9IGdhbGxlcnlJdGVtcztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ2FsbGVyeUl0ZW1zID0gdGhpcy5nZXRJdGVtcygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnVwZGF0ZUNvbnRyb2xzKCk7XHJcbiAgICAgICAgdGhpcy5vcGVuR2FsbGVyeU9uSXRlbUNsaWNrKCk7XHJcbiAgICAgICAgdGhpcy5MR2VsLnRyaWdnZXIobEdFdmVudHMudXBkYXRlU2xpZGVzKTtcclxuICAgIH07XHJcbiAgICBMaWdodEdhbGxlcnkucHJvdG90eXBlLnVwZGF0ZUNvbnRyb2xzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMuYWRkU2xpZGVWaWRlb0luZm8odGhpcy5nYWxsZXJ5SXRlbXMpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQ291bnRlclRvdGFsKCk7XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VTaW5nbGVTbGlkZUNsYXNzTmFtZSgpO1xyXG4gICAgfTtcclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuZGVzdHJveUdhbGxlcnkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5kZXN0cm95TW9kdWxlcyh0cnVlKTtcclxuICAgICAgICBpZiAoIXRoaXMuc2V0dGluZ3MuZHluYW1pYykge1xyXG4gICAgICAgICAgICB0aGlzLmludmFsaWRhdGVJdGVtcygpO1xyXG4gICAgICAgI
1H1cclxuICAgICAgICAkTEcod2luZG93KS5vZmYoXCIubGcuZ2xvYmFsXCIgKyB0aGlzLmxnSWQpO1xyXG4gICAgICAgIHRoaXMuTEdlbC5vZmYoJy5sZycpO1xyXG4gICAgICAgIHRoaXMuJGNvbnRhaW5lci5yZW1vdmUoKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIERlc3Ryb3kgbGlnaHRHYWxsZXJ5LlxyXG4gICAgICogRGVzdHJveSBsaWdodEdhbGxlcnkgYW5kIGl0cyBwbHVnaW4gaW5zdGFuY2VzIGNvbXBsZXRlbHlcclxuICAgICAqXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gVGhpcyBtZXRob2QgYWxzbyBjYWxscyBDbG9zZUdhbGxlcnkgZnVuY3Rpb24gaW50ZXJuYWxseS4gUmV0dXJucyB0aGUgdGltZSB0YWtlcyB0byBjb21wbGV0ZWx5IGNsb3NlIGFuZCBkZXN0cm95IHRoZSBpbnN0YW5jZS5cclxuICAgICAqIEluIGNhc2UgaWYgeW91IHdhbnQgdG8gcmUtaW5pdGlhbGl6ZSBsaWdodEdhbGxlcnkgcmlnaHQgYWZ0ZXIgZGVzdHJveWluZyBpdCwgaW5pdGlhbGl6ZSBpdCBvbmx5IG9uY2UgdGhlIGRlc3Ryb3kgcHJvY2VzcyBpcyBjb21wbGV0ZWQuXHJcbiAgICAgKiBZb3UgY2FuIHVzZSByZWZyZXNoIG1ldGhvZCBtb3N0IG9mIHRoZSB0aW1lcy5cclxuICAgICAqIEBjYXRlZ29yeSBsR1B1YmxpY01ldGhvZHNcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgY29uc3QgcGx1Z2luID0gbGlnaHRHYWxsZXJ5KCk7XHJcbiAgICAgKiAgcGx1Z2luLmRlc3Ryb3koKTtcclxuICAgICAqXHJcbiAgICAgKi9cclxuICAgIExpZ2h0R2FsbGVyeS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2Y
1XIgY2xvc2VUaW1lb3V0ID0gdGhpcy5jbG9zZUdhbGxlcnkodHJ1ZSk7XHJcbiAgICAgICAgaWYgKGNsb3NlVGltZW91dCkge1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KHRoaXMuZGVzdHJveUdhbGxlcnkuYmluZCh0aGlzKSwgY2xvc2VUaW1lb3V0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveUdhbGxlcnkoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNsb3NlVGltZW91dDtcclxuICAgIH07XHJcbiAgICByZXR1cm4gTGlnaHRHYWxsZXJ5O1xyXG59KCkpO1xuXG5mdW5jdGlvbiBsaWdodEdhbGxlcnkoZWwsIG9wdGlvbnMpIHtcclxuICAgIHJldHVybiBuZXcgTGlnaHRHYWxsZXJ5KGVsLCBvcHRpb25zKTtcclxufVxuXG5leHBvcnQgZGVmYXVsdCBsaWdodEdhbGxlcnk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saWdodGdhbGxlcnkuZXM1LmpzLm1hcFxuIiwiLyohXG4gKiBsaWdodGdhbGxlcnkgfCAyLjcuMiB8IFNlcHRlbWJlciAyMHRoIDIwMjNcbiAqIGh0dHA6Ly93d3cubGlnaHRnYWxsZXJ5anMuY29tL1xuICogQ29weXJpZ2h0IChjKSAyMDIwIFNhY2hpbiBOZXJhdmF0aDtcbiAqIEBsaWNlbnNlIEdQTHYzXG4gKi9cblxuLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuXHJcbnZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn07XG5cbnZhciB6b29tU2V0dGluZ3MgPSB7XHJcbiAgICBzY2FsZTogMSxcclxuICAgIHpvb206IHRydWUsXHJcbiAgICBpbmZpbml0ZVpvb206IHRydWUsXHJcbiAgICBhY3R1YWxTaXplOiB0cnVlLFxyXG4gICAgc2hvd1pvb21Jbk91dEljb25zOiBmYWxzZSxcclxuICAgIGFjdHVhbFNpemVJY29uczoge1xyXG4gICAgICAgIHpvb21JbjogJ2xnLXpvb20taW4nLFxyXG4gICAgICAgIHpvb21PdXQ6ICdsZy16b29tLW91dCcsXHJcbiAgICB9LFxyXG4gICAgZW5hYmxlWm9vbUFmdGVyOiAzMDAsXHJcbiAgICB6b29tUGx1Z2luU3RyaW5nczoge1xyXG4gICAgICAgIHpvb21JbjogJ1pvb20gaW4nLFxyXG4gICAgICAgIHpvb21PdXQ6ICdab29tIG91dCcsXHJcbiAgICAgICAgdmlld0FjdHVhbFNpemU6ICdWaWV3IGFjdHVhbCBzaXplJyxcclxuICAgIH0sXHJcbn07XG5cbi8qKlxyXG4gKiBMaXN0IG9mIGxpZ2h0R2FsbGVyeSBldmVudHNcclxuICogQWxsIGV2ZW50cyBzaG91bGQgYmUgZG9jdW1lbnRlZCBoZXJlXHJcbiAqIEJlbG93IGludGVyZmFjZXMgYXJlIHVzZWQgdG8gYnVpbGQgdGhlIHdlYnNpdGUgZG9jdW1lbnRhdGlvbnNcclxuICogKi9cclxudmFyIGxHRXZlbnRzID0ge1xyXG4gICAgYWZ0ZXJBcHBlbmRTbGlkZTogJ2xnQWZ0ZXJBcHBlbmRTbGlkZScsXHJcbiAgICBpbml0OiAnbGdJbml0JyxcclxuICAgIGhhc1ZpZGVvOiAnbGdIYXNWaWRlbycsXHJcbiAgICBjb250YWluZXJSZXNpemU6ICdsZ0NvbnRhaW5lclJlc2l6ZScsXHJcbiAgICB1cGRhdGVTbGlkZXM6ICdsZ1VwZGF0ZVNsaWRlcycsXHJcbiAgICBhZnRlckFwcGVuZFN1Ykh0bWw6ICdsZ0FmdGVyQXBwZW5kU3ViSHRtbCcsXHJcbiAgICBiZWZvcmVPcGVuOiAnbGdCZWZvcmVPcGVuJyxcclxuICAgIGFmdGVyT3BlbjogJ2xnQWZ0ZXJPcGVuJyxcclxuICAgIHNsaWRlSXRlbUxvYWQ6ICdsZ1NsaWRlSXRlbUxvYWQnLFxyXG4gICAgYmVmb3JlU2xpZGU6ICdsZ0JlZm9yZVNsaWRlJyxcclxuICAgIGFmdGVyU2xpZGU6ICdsZ0FmdGVyU2xpZGUnLFxyXG4gICAgcG9zdGVyQ2xpY2s6ICdsZ1Bvc3RlckNsaWNrJyxcclxuICAgIGRyYWdTdGFydDogJ2xnRHJhZ1N0YXJ0JyxcclxuICAgIGRyYWdNb3ZlOiAnbGdEcmFnTW92ZScsXHJcbiAgICBkcmFnRW5kOiAnbGdEcmFnRW5kJyxcclxuICAgIGJlZm9yZU5leHRTbGlkZTogJ2xnQmVmb3JlTmV4dFNsaWRlJyxcclxuICAgIGJlZm9yZVByZXZTbGlkZTogJ2xnQmVmb3JlUHJldlNsaWRlJyxcclxuICAgIGJlZm9yZUNsb3NlOiAnbGdCZWZvcmVDbG9zZScsXHJcbiAgICBhZnRlckNsb3NlOiAnbGdBZnRlckNsb3NlJyxcclxuICAgIHJvdGF0ZUxlZnQ6ICdsZ1JvdGF0ZUxlZnQnLFxyXG4gICAgcm90YXRlUmlnaHQ6ICdsZ1JvdGF0ZVJpZ2h0JyxcclxuICAgIGZsaXBIb3Jpem9udGFsOiAnbGdGbGlwSG9yaXpvbn
1RhbCcsXHJcbiAgICBmbGlwVmVydGljYWw6ICdsZ0ZsaXBWZXJ0aWNhbCcsXHJcbiAgICBhdXRvcGxheTogJ2xnQXV0b3BsYXknLFxyXG4gICAgYXV0b3BsYXlTdGFydDogJ2xnQXV0b3BsYXlTdGFydCcsXHJcbiAgICBhdXRvcGxheVN0b3A6ICdsZ0F1dG9wbGF5U3RvcCcsXHJcbn07XG5cbnZhciBaT09NX1RSQU5TSVRJT05fRFVSQVRJT04gPSA1MDA7XHJcbnZhciBab29tID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gWm9vbShpbnN0YW5jZSwgJExHKSB7XHJcbiAgICAgICAgLy8gZ2V0IGxpZ2h0R2FsbGVyeSBjb3JlIHBsdWdpbiBpbnN0YW5jZVxyXG4gICAgICAgIHRoaXMuY29yZSA9IGluc3RhbmNlO1xyXG4gICAgICAgIHRoaXMuJExHID0gJExHO1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MgPSBfX2Fzc2lnbihfX2Fzc2lnbih7fSwgem9vbVNldHRpbmdzKSwgdGhpcy5jb3JlLnNldHRpbmdzKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuICAgIC8vIEFwcGVuZCBab29tIGNvbnRyb2xzLiBBY3R1YWwgc2l6ZSwgWm9vbS1pbiwgWm9vbS1vdXRcclxuICAgIFpvb20ucHJvdG90eXBlLmJ1aWxkVGVtcGxhdGVzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciB6b29tSWNvbnMgPSB0aGlzLnNldHRpbmdzLnNob3dab29tSW5PdXRJY29uc1xyXG4gICAgICAgICAgICA/IFwiPGJ1dHRvbiBpZD1cXFwiXCIgKyB0aGlzLmNvcmUuZ2V0SWROYW1lKCdsZy16b29tLWluJykgKyBcIlxcXCIgdHlwZT1cXFwiYnV0dG9uXFxcIiBhcmlhLWxhYmVsPVxcXCJcIiArIHRoaXMuc2V0dGluZ3Muem9vbVBsdWdpblN0cmluZ3NbJ3pvb21JbiddICsgXCJcXFwiIGNsYXNzPVxcXCJsZy16b29tLWluIGxnLWljb25cXFwiPjwvYnV0dG9uPjxidXR0b24gaWQ9XFxcIlwiICsgdGhpcy5jb3JlLmdldElkTmFtZSgnbGctem9vbS1vdXQnKSArIFwiXFxcIiB0eXBlPVxcXCJidXR0b25cXFwiIGFyaWEtbGFiZWw9XFxcIlwiICsgdGhpcy5zZXR0aW5ncy56b29tUGx1Z2luU3RyaW5nc1snem9vbUluJ10gKyBcIlxcXCIgY2xhc3M9XFxcImxnLXpvb20tb3V0IGxnLWljb25cXFwiPjwvYnV0dG9uPlwiXHJcbiAgICAgICAgICAgIDogJyc7XHJcbiAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuYWN0dWFsU2l6ZSkge1xyXG4gICAgICAgICAgICB6b29tSWNvbnMgKz0gXCI8YnV0dG9uIGlkPVxcXCJcIiArIHRoaXMuY29yZS5nZXRJZE5hbWUoJ2xnLWFjdHVhbC1zaXplJykgKyBcIlxcXCIgdHlwZT1cXFwiYnV0dG9uXFxcIiBhcmlhLWxhYmVsPVxcXCJcIiArIHRoaXMuc2V0dGluZ3Muem9vbVBsdWdpblN0cmluZ3NbJ3ZpZXdBY3R1YWxTaXplJ10gKyBcIlxcXCIgY2xhc3M9XFxcIlwiICsgdGhpcy5zZXR0aW5ncy5hY3R1YWxTaXplSWNvbnMuem9vbUluICsgXCIgbGctaWNvblxcXCI+PC9idXR0b24+XCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY29yZS5vdXRlci5hZGRDbGFzcygnbGctdXNlLXRyYW5zaXRpb24tZm9yLXpvb20nKTtcclxuICAgICAgICB0aGlzLmNvcmUuJHRvb2xiYXIuZmlyc3QoKS5hcHBlbmQoem9vbUljb25zKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEBkZXNjIEVuYWJsZSB6b29tIG9wdGlvbiBvbmx5IG9uY2UgdGhlIGltYWdlIGlzIGNvbXBsZXRlbHkgbG9hZGVkXHJcbiAgICAgKiBJZiB6b29tRnJvbU9yaWdpbiBpcyB0cnVlLCBab29tIGlzIGVuYWJsZWQgb25jZSB0aGUgZHVtbXkgaW1hZ2UgaGFzIGJlZW4gaW5zZXJ0ZWRcclxuICAgICAqXHJcbiAgICAgKiBab29tIHN0eWxlcyBhcmUgZGVmaW5lZCB1bmRlciBsZy16b29tYWJsZSBDU1MgY2xhc3MuXHJcbiAgICAgKi9cclxuICAgIFpvb20ucHJvdG90eXBlLmVuYWJsZVpvb20gPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIC8vIGRlbGF5IHdpbGwgYmUgMCBleGNlcHQgZmlyc3QgdGltZVxyXG4gICAgICAgIHZhciBfc3BlZWQgPSB0aGlzLnNldHRpbmdzLmVuYWJsZVpvb21BZnRlciArIGV2ZW50LmRldGFpbC5kZWxheTtcclxuICAgICAgICAvLyBzZXQgX3NwZWVkIHZhbHVlIDAgaWYgZ2FsbGVyeSBvcGVuZWQgZnJvbSBkaXJlY3QgdXJsIGFuZCBpZiBpdCBpcyBmaXJzdCBzbGlkZVxyXG4gICAgICAgIGlmICh0aGlzLiRMRygnYm9keScpLmZpcnN0KCkuaGFzQ2xhc3MoJ2xnLWZyb20taGFzaCcpICYmXHJcbiAgICAgICAgICAgIGV2ZW50LmRldGFpbC5kZWxheSkge1xyXG4gICAgICAgICAgICAvLyB3aWxsIGV4ZWN1dGUgb25seSBvbmNlXHJcbiAgICAgICAgICAgIF9zcGVlZCA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBSZW1vdmUgbGctZnJvbS1oYXNoIHRvIGVuYWJsZSBzdGFydGluZyBhbmltYXRpb24uXHJcbiAgICAgICAgICAgIHRoaXMuJExHKCdib2R5JykuZmlyc3QoKS5yZW1vdmVDbGFzcygnbGctZnJvbS1oYXNoJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuem9vbWFibGVUaW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghX3RoaXMuaXNJbWFnZVNsaWRlKF90aGlzLmNvcmUuaW5kZXgpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX3RoaXMuY29yZS5nZXRTbGlkZUl0ZW0oZXZlbnQuZGV0YWlsLmluZGV4KS5hZGRDbGFzcygnbGctem9vbWFibGUnKTtcclxuICAgICAgICAgICAgaWYgKGV2ZW50LmRldGFpbC5pbmRleCA9PT0gX3RoaXMuY29yZS5pbmRleCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0Wm9vbUVzc2VudGlhbHMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sIF9zcGVlZCArIDMwKTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5lbmFibGVab29tT25TbGlkZUl0ZW1Mb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIEFkZCB6b29tYWJsZSBjbGFzc1xyXG4gICAgICAgIHRoaXMuY29yZS5MR2VsLm9uKGxHRXZlbnRzLnNsaWRlSXRlbUxvYWQgKyBcIi56b29tXCIsIHRoaXMuZW5hYmxlWm9vbS5iaW5kKHRoaXMpKTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5nZXREcmFnQ29yZHMgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHg6IGUucGFnZVgsXHJcbiAgICAgICAgICAgIHk6IGUucGFnZVksXHJcbiAgICAgICAgfTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5nZXRTd2lwZUNvcmRzID0gZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICB2Y
1XIgeCA9IGUudG91Y2hlc1swXS5wYWdlWDtcclxuICAgICAgICB2YXIgeSA9IGUudG91Y2hlc1swXS5wYWdlWTtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB4OiB4LFxyXG4gICAgICAgICAgICB5OiB5LFxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuZ2V0RHJhZ0FsbG93ZWRBeGlzZXMgPSBmdW5jdGlvbiAoc2NhbGUsIHNjYWxlRGlmZikge1xyXG4gICAgICAgIHZhciAkaW1hZ2UgPSB0aGlzLmNvcmVcclxuICAgICAgICAgICAgLmdldFNsaWRlSXRlbSh0aGlzLmNvcmUuaW5kZXgpXHJcbiAgICAgICAgICAgIC5maW5kKCcubGctaW1hZ2UnKVxyXG4gICAgICAgICAgICAuZmlyc3QoKVxyXG4gICAgICAgICAgICAuZ2V0KCk7XHJcbiAgICAgICAgdmFyIGhlaWdodCA9IDA7XHJcbiAgICAgICAgdmFyIHdpZHRoID0gMDtcclxuICAgICAgICB2YXIgcmVjdCA9ICRpbWFnZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICBpZiAoc2NhbGUpIHtcclxuICAgICAgICAgICAgaGVpZ2h0ID0gJGltYWdlLm9mZnNldEhlaWdodCAqIHNjYWxlO1xyXG4gICAgICAgICAgICB3aWR0aCA9ICRpbWFnZS5vZmZzZXRXaWR0aCAqIHNjYWxlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChzY2FsZURpZmYpIHtcclxuICAgICAgICAgICAgaGVpZ2h0ID0gcmVjdC5oZWlnaHQgKyBzY2FsZURpZmYgKiByZWN0LmhlaWdodDtcclxuICAgICAgICAgICAgd2lkdGggPSByZWN0LndpZHRoICsgc2NhbGVEaWZmICogcmVjdC53aWR0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGhlaWdodCA9IHJlY3QuaGVpZ2h0O1xyXG4gICAgICAgICAgICB3aWR0aCA9IHJlY3Qud2lkdGg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBhbGxvd1kgPSBoZWlnaHQgPiB0aGlzLmNvbnRhaW5lclJlY3QuaGVpZ2h0O1xyXG4gICAgICAgIHZhciBhbGxvd1ggPSB3aWR0aCA+IHRoaXMuY29udGFpbmVyUmVjdC53aWR0aDtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBhbGxvd1g6IGFsbG93WCxcclxuICAgICAgICAgICAgYWxsb3dZOiBhbGxvd1ksXHJcbiAgICAgICAgfTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5zZXRab29tRXNzZW50aWFscyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmNvbnRhaW5lclJlY3QgPSB0aGlzLmNvcmUuJGNvbnRlbnQuZ2V0KCkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzYyBJbWFnZSB6b29tXHJcbiAgICAgKiBUcmFuc2xhdGUgdGhlIHdyYXAgYW5kIHNjYWxlIHRoZSBpbWFnZSB0byBnZXQgYmV0dGVyIHVzZXIgZXhwZXJpZW5jZVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzY2FsZSAtIFpvb20gZGVjcmVtZW50L2luY3JlbWVudCB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBab29tLnByb3RvdHlwZS56b29tSW1hZ2UgPSBmdW5jdGlvbiAoc2NhbGUsIHNjYWxlRGlmZiwgcmVwb3NpdGlvbiwgcmVzZXRUb01heCkge1xyXG4gICAgICAgIGlmIChNYXRoLmFicyhzY2FsZURpZmYpIDw9IDApXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB2Y
1XIgb2Zmc2V0WCA9IHRoaXMuY29udGFpbmVyUmVjdC53aWR0aCAvIDIgKyB0aGlzLmNvbnRhaW5lclJlY3QubGVmdDtcclxuICAgICAgICB2YXIgb2Zmc2V0WSA9IHRoaXMuY29udGFpbmVyUmVjdC5oZWlnaHQgLyAyICtcclxuICAgICAgICAgICAgdGhpcy5jb250YWluZXJSZWN0LnRvcCArXHJcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9wO1xyXG4gICAgICAgIHZhciBvcmlnaW5hbFg7XHJcbiAgICAgICAgdmFyIG9yaWdpbmFsWTtcclxuICAgICAgICBpZiAoc2NhbGUgPT09IDEpIHtcclxuICAgICAgICAgICAgdGhpcy5wb3NpdGlvbkNoYW5nZWQgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGRyYWdBbGxvd2VkQXhpc2VzID0gdGhpcy5nZXREcmFnQWxsb3dlZEF4aXNlcygwLCBzY2FsZURpZmYpO1xyXG4gICAgICAgIHZhciBhbGxvd1kgPSBkcmFnQWxsb3dlZEF4aXNlcy5hbGxvd1ksIGFsbG93WCA9IGRyYWdBbGxvd2VkQXhpc2VzLmFsbG93WDtcclxuICAgICAgICBpZiAodGhpcy5wb3NpdGlvbkNoYW5nZWQpIHtcclxuICAgICAgICAgICAgb3JpZ2luYWxYID0gdGhpcy5sZWZ0IC8gKHRoaXMuc2NhbGUgLSBzY2FsZURpZmYpO1xyXG4gICAgICAgICAgICBvcmlnaW5hbFkgPSB0aGlzLnRvcCAvICh0aGlzLnNjYWxlIC0gc2NhbGVEaWZmKTtcclxuICAgICAgICAgICAgdGhpcy5wYWdlWCA9IG9mZnNldFggLSBvcmlnaW5hbFg7XHJcbiAgICAgICAgICAgIHRoaXMucGFnZVkgPSBvZmZzZXRZIC0gb3JpZ2luYWxZO1xyXG4gICAgICAgICAgICB0aGlzLnBvc2l0aW9uQ2hhbmdlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2Y
1XIgcG9zc2libGVTd2lwZUNvcmRzID0gdGhpcy5nZXRQb3NzaWJsZVN3aXBlRHJhZ0NvcmRzKHNjYWxlRGlmZik7XHJcbiAgICAgICAgdmFyIHg7XHJcbiAgICAgICAgdmFyIHk7XHJcbiAgICAgICAgdmFyIF94ID0gb2Zmc2V0WCAtIHRoaXMucGFnZVg7XHJcbiAgICAgICAgdmFyIF95ID0gb2Zmc2V0WSAtIHRoaXMucGFnZVk7XHJcbiAgICAgICAgaWYgKHNjYWxlIC0gc2NhbGVEaWZmID4gMSkge1xyXG4gICAgICAgICAgICB2YXIgc2NhbGVWYWwgPSAoc2NhbGUgLSBzY2FsZURpZmYpIC8gTWF0aC5hYnMoc2NhbGVEaWZmKTtcclxuICAgICAgICAgICAgX3ggPVxyXG4gICAgICAgICAgICAgICAgKHNjYWxlRGlmZiA8IDAgPyAtX3ggOiBfeCkgK1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGVmdCAqIChzY2FsZVZhbCArIChzY2FsZURpZmYgPCAwID8gLTEgOiAxKSk7XHJcbiAgICAgICAgICAgIF95ID1cclxuICAgICAgICAgICAgICAgIChzY2FsZURpZmYgPCAwID8gLV95IDogX3kpICtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvcCAqIChzY2FsZVZhbCArIChzY2FsZURpZmYgPCAwID8gLTEgOiAxKSk7XHJcbiAgICAgICAgICAgIHggPSBfeCAvIHNjYWxlVmFsO1xyXG4gICAgICAgICAgICB5ID0gX3kgLyBzY2FsZVZhbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHZhciBzY2FsZVZhbCA9IChzY2FsZSAtIHNjYWxlRGlmZikgKiBzY2FsZURpZmY7XHJcbiAgICAgICAgICAgIHggPSBfeCAqIHNjYWxlVmFsO1xyXG4gICAgICAgICAgICB5ID0gX3kgKiBzY2FsZVZhbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlcG9zaXRpb24pIHtcclxuICAgICAgICAgICAgaWYgKGFsbG93WCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNCZXlvbmRQb3NzaWJsZUxlZnQoeCwgcG9zc2libGVTd2lwZUNvcmRzLm1pblgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeCA9IHBvc3NpYmxlU3dpcGVDb3Jkcy5taW5YO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5pc0JleW9uZFBvc3NpYmxlUmlnaHQoeCwgcG9zc2libGVTd2lwZUNvcmRzLm1heFgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeCA9IHBvc3NpYmxlU3dpcGVDb3Jkcy5tYXhYO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNjYWxlID4gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh4IDwgcG9zc2libGVTd2lwZUNvcmRzLm1pblgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeCA9IHBvc3NpYmxlU3dpcGVDb3Jkcy5taW5YO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh4ID4gcG9zc2libGVTd2lwZUNvcmRzLm1heFgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeCA9IHBvc3NpYmxlU3dpcGVDb3Jkcy5tYXhYO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBAdG9kbyBmaXggdGhpc1xyXG4gICAgICAgICAgICBpZiAoYWxsb3dZKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0JleW9uZFBvc3NpYmxlVG9wKHksIHBvc3NpYmxlU3dpcGVDb3Jkcy5taW5ZKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHkgPSBwb3NzaWJsZVN3aXBlQ29yZHMubWluWTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuaXNCZXlvbmRQb3NzaWJsZUJvdHRvbSh5LCBwb3NzaWJsZVN3aXBlQ29yZHMubWF4WSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB5ID0gcG9zc2libGVTd2lwZUNvcmRzLm1heFk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdHJhbnNsYXRlIHZhbHVlIGJhc2VkIG9uIGluZGV4IG9mIGJleW9uZCB0aGUgdmlld3BvcnQsIHV0aWxpemUgdGhlIGF2YWlsYWJsZSBzcGFjZSB0byBwcmV2ZW50IGltYWdlIGJlaW5nIGN1dCBvdXRcclxuICAgICAgICAgICAgICAgIGlmIChzY2FsZSA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL0lmIGltYWdlIGdvZXMgYmV5b25kIHZpZXdwb3J0IHRvcCwgdXNlIHRoZSBtaW5pbSBwb3NzaWJsZSB0cmFuc2xhdGUgdmFsdWVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoeSA8IHBvc3NpYmxlU3dpcGVDb3Jkcy5taW5ZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBwb3NzaWJsZVN3aXBlQ29yZHMubWluWTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeSA+IHBvc3NpYmxlU3dpcGVDb3Jkcy5tYXhZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBwb3NzaWJsZVN3aXBlQ29yZHMubWF4WTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5zZXRab29tU3R5bGVzKHtcclxuICAgICAgICAgICAgeDogeCxcclxuICAgICAgICAgICAgeTogeSxcclxuICAgICAgICAgICAgc2NhbGU6IHNjYWxlLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMubGVmdCA9IHg7XHJcbiAgICAgICAgdGhpcy50b3AgPSB5O1xyXG4gICAgICAgIGlmIChyZXNldFRvTWF4KSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0Wm9vbUltYWdlU2l6ZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5yZXNldEltYWdlVHJhbnNsYXRlID0gZnVuY3Rpb24gKGluZGV4KSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmlzSW1hZ2VTbGlkZShpbmRleCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2Y
1XIgJGltYWdlID0gdGhpcy5jb3JlLmdldFNsaWRlSXRlbShpbmRleCkuZmluZCgnLmxnLWltYWdlJykuZmlyc3QoKTtcclxuICAgICAgICB0aGlzLmltYWdlUmVzZXQgPSBmYWxzZTtcclxuICAgICAgICAkaW1hZ2UucmVtb3ZlQ2xhc3MoJ3Jlc2V0LXRyYW5zaXRpb24gcmVzZXQtdHJhbnNpdGlvbi15IHJlc2V0LXRyYW5zaXRpb24teCcpO1xyXG4gICAgICAgIHRoaXMuY29yZS5vdXRlci5yZW1vdmVDbGFzcygnbGctYWN0dWFsLXNpemUnKTtcclxuICAgICAgICAkaW1hZ2UuY3NzKCd3aWR0aCcsICdhdXRvJykuY3NzKCdoZWlnaHQnLCAnYXV0bycpO1xyXG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAkaW1hZ2UucmVtb3ZlQ2xhc3MoJ25vLXRyYW5zaXRpb24nKTtcclxuICAgICAgICB9LCAxMCk7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuc2V0Wm9vbUltYWdlU2l6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciAkaW1hZ2UgPSB0aGlzLmNvcmVcclxuICAgICAgICAgICAgLmdldFNsaWRlSXRlbSh0aGlzLmNvcmUuaW5kZXgpXHJcbiAgICAgICAgICAgIC5maW5kKCcubGctaW1hZ2UnKVxyXG4gICAgICAgICAgICAuZmlyc3QoKTtcclxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIGFjdHVhbFNpemVTY2FsZSA9IF90aGlzLmdldEN1cnJlbnRJbWFnZUFjdHVhbFNpemVTY2FsZSgpO1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuc2NhbGUgPj0gYWN0dWFsU2l6ZVNjYWxlKSB7XHJcbiAgICAgICAgICAgICAgICAkaW1hZ2UuYWRkQ2xhc3MoJ25vLXRyYW5zaXRpb24nKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLmltYWdlUmVzZXQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgWk9PTV9UUkFOU0lUSU9OX0RVUkFUSU9OKTtcclxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIGFjdHVhbFNpemVTY2FsZSA9IF90aGlzLmdldEN1cnJlbnRJbWFnZUFjdHVhbFNpemVTY2FsZSgpO1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuc2NhbGUgPj0gYWN0dWFsU2l6ZVNjYWxlKSB7XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgZHJhZ0FsbG93ZWRBeGlzZXMgPSBfdGhpcy5nZXREcmFnQWxsb3dlZEF4aXNlcyhfdGhpcy5zY2FsZSk7XHJcbiAgICAgICAgICAgICAgICAkaW1hZ2VcclxuICAgICAgICAgICAgICAgICAgICAuY3NzKCd3aWR0aCcsICRpbWFnZS5nZXQoKS5uYXR1cmFsV2lkdGggKyAncHgnKVxyXG4gICAgICAgICAgICAgICAgICAgIC5jc3MoJ2hlaWdodCcsICRpbWFnZS5nZXQoKS5uYXR1cmFsSGVpZ2h0ICsgJ3B4Jyk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5jb3JlLm91dGVyLmFkZENsYXNzKCdsZy1hY3R1YWwtc2l6ZScpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGRyYWdBbGxvd2VkQXhpc2VzLmFsbG93WCAmJiBkcmFnQWxsb3dlZEF4aXNlcy5hbGxvd1kpIHtcclxuICAgICAgICAgICAgICAgICAgICAkaW1hZ2UuYWRkQ2xhc3MoJ3Jlc2V0LXRyYW5zaXRpb24nKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRyYWdBbGxvd2VkQXhpc2VzLmFsbG93WCAmJlxyXG4gICAgICAgICAgICAgICAgICAgICFkcmFnQWxsb3dlZEF4aXNlcy5hbGxvd1kpIHtcclxuICAgICAgICAgICAgICAgICAgICAkaW1hZ2UuYWRkQ2xhc3MoJ3Jlc2V0LXRyYW5zaXRpb24teCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoIWRyYWdBbGxvd2VkQXhpc2VzLmFsbG93WCAmJlxyXG4gICAgICAgICAgICAgICAgICAgIGRyYWdBbGxvd2VkQXhpc2VzLmFsbG93WSkge1xyXG4gICAgICAgICAgICAgICAgICAgICRpbWFnZS5hZGRDbGFzcygncmVzZXQtdHJhbnNpdGlvbi15Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LCBaT09NX1RSQU5TSVRJT05fRFVSQVRJT04gKyA1MCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVzYyBhcHBseSBzY2FsZTNkIHRvIGltYWdlIGFuZCB0cmFuc2xhdGUgdG8gaW1hZ2Ugd3JhcFxyXG4gICAgICogQHBhcmFtIHtzdHlsZX0gWCxZIGFuZCBzY2FsZVxyXG4gICAgICovXHJcbiAgICBab29tLnByb3RvdHlwZS5zZXRab29tU3R5bGVzID0gZnVuY3Rpb24gKHN0eWxlKSB7XHJcbiAgICAgICAgdmFyICRpbWFnZVdyYXAgPSB0aGlzLmNvcmVcclxuICAgICAgICAgICAgLmdldFNsaWRlSXRlbSh0aGlzLmNvcmUuaW5kZXgpXHJcbiAgICAgICAgICAgIC5maW5kKCcubGctaW1nLXdyYXAnKVxyXG4gICAgICAgICAgICAuZmlyc3QoKTtcclxuICAgICAgICB2Y
1XIgJGltYWdlID0gdGhpcy5jb3JlXHJcbiAgICAgICAgICAgIC5nZXRTbGlkZUl0ZW0odGhpcy5jb3JlLmluZGV4KVxyXG4gICAgICAgICAgICAuZmluZCgnLmxnLWltYWdlJylcclxuICAgICAgICAgICAgLmZpcnN0KCk7XHJcbiAgICAgICAgdmFyICRkdW1teUltYWdlID0gdGhpcy5jb3JlLm91dGVyXHJcbiAgICAgICAgICAgIC5maW5kKCcubGctY3VycmVudCAubGctZHVtbXktaW1nJylcclxuICAgICAgICAgICAgLmZpcnN0KCk7XHJcbiAgICAgICAgdGhpcy5zY2FsZSA9IHN0eWxlLnNjYWxlO1xyXG4gICAgICAgICRpbWFnZS5jc3MoJ3RyYW5zZm9ybScsICdzY2FsZTNkKCcgKyBzdHlsZS5zY2FsZSArICcsICcgKyBzdHlsZS5zY2FsZSArICcsIDEpJyk7XHJcbiAgICAgICAgJGR1bW15SW1hZ2UuY3NzKCd0cmFuc2Zvcm0nLCAnc2NhbGUzZCgnICsgc3R5bGUuc2NhbGUgKyAnLCAnICsgc3R5bGUuc2NhbGUgKyAnLCAxKScpO1xyXG4gICAgICAgIHZhciB0cmFuc2Zvcm0gPSAndHJhbnNsYXRlM2QoJyArIHN0eWxlLnggKyAncHgsICcgKyBzdHlsZS55ICsgJ3B4LCAwKSc7XHJcbiAgICAgICAgJGltYWdlV3JhcC5jc3MoJ3RyYW5zZm9ybScsIHRyYW5zZm9ybSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0gaW5kZXggLSBJbmRleCBvZiB0aGUgY3VycmVudCBzbGlkZVxyXG4gICAgICogQHBhcmFtIGV2ZW50IC0gZXZlbnQgd2lsbCBiZSBhdmFpbGFibGUgb25seSBpZiB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkIG9uIGNsaWNraW5nL3RhcGluZyB0aGUgaW1hZ3NcclxuICAgICAqL1xyXG4gICAgWm9vbS5wcm90b3R5cGUuc2V0QWN0dWFsU2l6ZSA9IGZ1bmN0aW9uIChpbmRleCwgZXZlbnQpIHtcclxuICAgICAgICB2Y
1XIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmICh0aGlzLnpvb21JblByb2dyZXNzKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy56b29tSW5Qcm9ncmVzcyA9IHRydWU7XHJcbiAgICAgICAgdmFyIGN1cnJlbnRJdGVtID0gdGhpcy5jb3JlLmdhbGxlcnlJdGVtc1t0aGlzLmNvcmUuaW5kZXhdO1xyXG4gICAgICAgIHRoaXMucmVzZXRJbWFnZVRyYW5zbGF0ZShpbmRleCk7XHJcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIEFsbG93IHpvb20gb25seSBvbiBpbWFnZVxyXG4gICAgICAgICAgICBpZiAoIWN1cnJlbnRJdGVtLnNyYyB8fFxyXG4gICAgICAgICAgICAgICAgX3RoaXMuY29yZS5vdXRlci5oYXNDbGFzcygnbGctZmlyc3Qtc2xpZGUtbG9hZGluZycpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIHNjYWxlID0gX3RoaXMuZ2V0Q3VycmVudEltYWdlQWN0dWFsU2l6ZVNjYWxlKCk7XHJcbiAgICAgICAgICAgIHZhciBwcmV2U2NhbGUgPSBfdGhpcy5zY2FsZTtcclxuICAgICAgICAgICAgaWYgKF90aGlzLmNvcmUub3V0ZXIuaGFzQ2xhc3MoJ2xnLXpvb21lZCcpKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zY2FsZSA9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zY2FsZSA9IF90aGlzLmdldFNjYWxlKHNjYWxlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5zZXRQYWdlQ29yZHMoZXZlbnQpO1xyXG4gICAgICAgICAgICBfdGhpcy5iZWdpblpvb20oX3RoaXMuc2NhbGUpO1xyXG4gICAgICAgICAgICBfdGhpcy56b29tSW1hZ2UoX3RoaXMuc2NhbGUsIF90aGlzLnNjYWxlIC0gcHJldlNjYWxlLCB0cnVlLCB0cnVlKTtcclxuICAgICAgICB9LCA1MCk7XHJcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLmNvcmUub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLWdyYWJiaW5nJykuYWRkQ2xhc3MoJ2xnLWdyYWInKTtcclxuICAgICAgICB9LCA2MCk7XHJcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLnpvb21JblByb2dyZXNzID0gZmFsc2U7XHJcbiAgICAgICAgfSwgWk9PTV9UUkFOU0lUSU9OX0RVUkFUSU9OICsgMTEwKTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5nZXROYXR1cmFsV2lkdGggPSBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICB2Y
1XIgJGltYWdlID0gdGhpcy5jb3JlLmdldFNsaWRlSXRlbShpbmRleCkuZmluZCgnLmxnLWltYWdlJykuZmlyc3QoKTtcclxuICAgICAgICB2YXIgbmF0dXJhbFdpZHRoID0gdGhpcy5jb3JlLmdhbGxlcnlJdGVtc1tpbmRleF0ud2lkdGg7XHJcbiAgICAgICAgcmV0dXJuIG5hdHVyYWxXaWR0aFxyXG4gICAgICAgICAgICA/IHBhcnNlRmxvYXQobmF0dXJhbFdpZHRoKVxyXG4gICAgICAgICAgICA6ICRpbWFnZS5nZXQoKS5uYXR1cmFsV2lkdGg7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuZ2V0QWN0dWFsU2l6ZVNjYWxlID0gZnVuY3Rpb24gKG5hdHVyYWxXaWR0aCwgd2lkdGgpIHtcclxuICAgICAgICB2YXIgX3NjYWxlO1xyXG4gICAgICAgIHZhciBzY2FsZTtcclxuICAgICAgICBpZiAobmF0dXJhbFdpZHRoID49IHdpZHRoKSB7XHJcbiAgICAgICAgICAgIF9zY2FsZSA9IG5hdHVyYWxXaWR0aCAvIHdpZHRoO1xyXG4gICAgICAgICAgICBzY2FsZSA9IF9zY2FsZSB8fCAyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgc2NhbGUgPSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2NhbGU7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuZ2V0Q3VycmVudEltYWdlQWN0dWFsU2l6ZVNjYWxlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciAkaW1hZ2UgPSB0aGlzLmNvcmVcclxuICAgICAgICAgICAgLmdldFNsaWRlSXRlbSh0aGlzLmNvcmUuaW5kZXgpXHJcbiAgICAgICAgICAgIC5maW5kKCcubGctaW1hZ2UnKVxyXG4gICAgICAgICAgICAuZmlyc3QoKTtcclxuICAgICAgICB2Y
1XIgd2lkdGggPSAkaW1hZ2UuZ2V0KCkub2Zmc2V0V2lkdGg7XHJcbiAgICAgICAgdmFyIG5hdHVyYWxXaWR0aCA9IHRoaXMuZ2V0TmF0dXJhbFdpZHRoKHRoaXMuY29yZS5pbmRleCkgfHwgd2lkdGg7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QWN0dWFsU2l6ZVNjYWxlKG5hdHVyYWxXaWR0aCwgd2lkdGgpO1xyXG4gICAgfTtcclxuICAgIFpvb20ucHJvdG90eXBlLmdldFBhZ2VDb3JkcyA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIHZhciBjb3JkcyA9IHt9O1xyXG4gICAgICAgIGlmIChldmVudCkge1xyXG4gICAgICAgICAgICBjb3Jkcy54ID0gZXZlbnQucGFnZVggfHwgZXZlbnQudG91Y2hlc1swXS5wYWdlWDtcclxuICAgICAgICAgICAgY29yZHMueSA9IGV2ZW50LnBhZ2VZIHx8IGV2ZW50LnRvdWNoZXNbMF0ucGFnZVk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgY29udGFpbmVyUmVjdCA9IHRoaXMuY29yZS4kY29udGVudFxyXG4gICAgICAgICAgICAgICAgLmdldCgpXHJcbiAgICAgICAgICAgICAgICAuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgICAgIGNvcmRzLnggPSBjb250YWluZXJSZWN0LndpZHRoIC8gMiArIGNvbnRhaW5lclJlY3QubGVmdDtcclxuICAgICAgICAgICAgY29yZHMueSA9XHJcbiAgICAgICAgICAgICAgICBjb250YWluZXJSZWN0LmhlaWdodCAvIDIgKyB0aGlzLnNjcm9sbFRvcCArIGNvbnRhaW5lclJlY3QudG9wO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY29yZHM7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuc2V0UGFnZUNvcmRzID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgdmFyIHBhZ2VDb3JkcyA9IHRoaXMuZ2V0UGFnZUNvcmRzKGV2ZW50KTtcclxuICAgICAgICB0aGlzLnBhZ2VYID0gcGFnZUNvcmRzLng7XHJcbiAgICAgICAgdGhpcy5wYWdlWSA9IHBhZ2VDb3Jkcy55O1xyXG4gICAgfTtcclxuICAgIFpvb20ucHJvdG90eXBlLm1hbmFnZUFjdHVhbFBpeGVsQ2xhc3NOYW1lcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2Y
1XIgJGFjdHVhbFNpemUgPSB0aGlzLmNvcmUuZ2V0RWxlbWVudEJ5SWQoJ2xnLWFjdHVhbC1zaXplJyk7XHJcbiAgICAgICAgJGFjdHVhbFNpemVcclxuICAgICAgICAgICAgLnJlbW92ZUNsYXNzKHRoaXMuc2V0dGluZ3MuYWN0dWFsU2l6ZUljb25zLnpvb21JbilcclxuICAgICAgICAgICAgLmFkZENsYXNzKHRoaXMuc2V0dGluZ3MuYWN0dWFsU2l6ZUljb25zLnpvb21PdXQpO1xyXG4gICAgfTtcclxuICAgIC8vIElmIHRydWUsIHpvb21lZCAtIGluIGVsc2Ugem9vbWVkIG91dFxyXG4gICAgWm9vbS5wcm90b3R5cGUuYmVnaW5ab29tID0gZnVuY3Rpb24gKHNjYWxlKSB7XHJcbiAgICAgICAgdGhpcy5jb3JlLm91dGVyLnJlbW92ZUNsYXNzKCdsZy16b29tLWRyYWctdHJhbnNpdGlvbiBsZy16b29tLWRyYWdnaW5nJyk7XHJcbiAgICAgICAgaWYgKHNjYWxlID4gMSkge1xyXG4gICAgICAgICAgICB0aGlzLmNvcmUub3V0ZXIuYWRkQ2xhc3MoJ2xnLXpvb21lZCcpO1xyXG4gICAgICAgICAgICB0aGlzLm1hbmFnZUFjdHVhbFBpeGVsQ2xhc3NOYW1lcygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5yZXNldFpvb20oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNjYWxlID4gMTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5nZXRTY2FsZSA9IGZ1bmN0aW9uIChzY2FsZSkge1xyXG4gICAgICAgIHZhciBhY3R1YWxTaXplU2NhbGUgPSB0aGlzLmdldEN1cnJlbnRJbWFnZUFjdHVhbFNpemVTY2FsZSgpO1xyXG4gICAgICAgIGlmIChzY2FsZSA8IDEpIHtcclxuICAgICAgICAgICAgc2NhbGUgPSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChzY2FsZSA+IGFjdHVhbFNpemVTY2FsZSkge1xyXG4gICAgICAgICAgICBzY2FsZSA9IGFjdHVhbFNpemVTY2FsZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNjYWxlO1xyXG4gICAgfTtcclxuICAgIFpvb20ucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBpZiAoIXRoaXMuc2V0dGluZ3Muem9vbSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuYnVpbGRUZW1wbGF0ZXMoKTtcclxuICAgICAgICB0aGlzLmVuYWJsZVpvb21PblNsaWRlSXRlbUxvYWQoKTtcclxuICAgICAgICB2Y
1XIgdGFwcGVkID0gbnVsbDtcclxuICAgICAgICB0aGlzLmNvcmUub3V0ZXIub24oJ2RibGNsaWNrLmxnJywgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIGlmICghX3RoaXMuJExHKGV2ZW50LnRhcmdldCkuaGFzQ2xhc3MoJ2xnLWltYWdlJykpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5zZXRBY3R1YWxTaXplKF90aGlzLmNvcmUuaW5kZXgsIGV2ZW50KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmNvcmUub3V0ZXIub24oJ3RvdWNoc3RhcnQubGcnLCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgdmFyICR0YXJnZXQgPSBfdGhpcy4kTEcoZXZlbnQudGFyZ2V0KTtcclxuICAgICAgICAgICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxICYmICR0YXJnZXQuaGFzQ2xhc3MoJ2xnLWltYWdlJykpIHtcclxuICAgICAgICAgICAgICAgIGlmICghdGFwcGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFwcGVkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcHBlZCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgMzAwKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0YXBwZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcHBlZCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRBY3R1YWxTaXplKF90aGlzLmNvcmUuaW5kZXgsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuY29yZS5MR2VsLm9uKGxHRXZlbnRzLmNvbnRhaW5lclJlc2l6ZSArIFwiLnpvb20gXCIgKyBsR0V2ZW50cy5yb3RhdGVSaWdodCArIFwiLnpvb20gXCIgKyBsR0V2ZW50cy5yb3RhdGVMZWZ0ICsgXCIuem9vbSBcIiArIGxHRXZlbnRzLmZsaXBIb3Jpem9udGFsICsgXCIuem9vbSBcIiArIGxHRXZlbnRzLmZsaXBWZXJ0aWNhbCArIFwiLnpvb21cIiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoIV90aGlzLmNvcmUubGdPcGVuZWQgfHxcclxuICAgICAgICAgICAgICAgICFfdGhpcy5pc0ltYWdlU2xpZGUoX3RoaXMuY29yZS5pbmRleCkgfHxcclxuICAgICAgICAgICAgICAgIF90aGlzLmNvcmUudG91Y2hBY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2Y
1XIgX0xHZWwgPSBfdGhpcy5jb3JlXHJcbiAgICAgICAgICAgICAgICAuZ2V0U2xpZGVJdGVtKF90aGlzLmNvcmUuaW5kZXgpXHJcbiAgICAgICAgICAgICAgICAuZmluZCgnLmxnLWltZy13cmFwJylcclxuICAgICAgICAgICAgICAgIC5maXJzdCgpO1xyXG4gICAgICAgICAgICBfdGhpcy50b3AgPSAwO1xyXG4gICAgICAgICAgICBfdGhpcy5sZWZ0ID0gMDtcclxuICAgICAgICAgICAgX3RoaXMuc2V0Wm9vbUVzc2VudGlhbHMoKTtcclxuICAgICAgICAgICAgX3RoaXMuc2V0Wm9vbVN3aXBlU3R5bGVzKF9MR2VsLCB7IHg6IDAsIHk6IDAgfSk7XHJcbiAgICAgICAgICAgIF90aGlzLnBvc2l0aW9uQ2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gVXBkYXRlIHpvb20gb24gcmVzaXplIGFuZCBvcmllbnRhdGlvbmNoYW5nZVxyXG4gICAgICAgIHRoaXMuJExHKHdpbmRvdykub24oXCJzY3JvbGwubGcuem9vbS5nbG9iYWxcIiArIHRoaXMuY29yZS5sZ0lkLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghX3RoaXMuY29yZS5sZ09wZW5lZClcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgX3RoaXMuc2Nyb2xsVG9wID0gX3RoaXMuJExHKHdpbmRvdykuc2Nyb2xsVG9wKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jb3JlLmdldEVsZW1lbnRCeUlkKCdsZy16b29tLW91dCcpLm9uKCdjbGljay5sZycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gQWxsb3cgem9vbSBvbmx5IG9uIGltYWdlXHJcbiAgICAgICAgICAgIGlmICghX3RoaXMuaXNJbWFnZVNsaWRlKF90aGlzLmNvcmUuaW5kZXgpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIHRpbWVvdXQgPSAwO1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuaW1hZ2VSZXNldCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMucmVzZXRJbWFnZVRyYW5zbGF0ZShfdGhpcy5jb3JlLmluZGV4KTtcclxuICAgICAgICAgICAgICAgIHRpbWVvdXQgPSA1MDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzY2FsZSA9IF90aGlzLnNjYWxlIC0gX3RoaXMuc2V0dGluZ3Muc2NhbGU7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2NhbGUgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2NhbGUgPSAxO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgX3RoaXMuYmVnaW5ab29tKHNjYWxlKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLnpvb21JbWFnZShzY2FsZSwgLV90aGlzLnNldHRpbmdzLnNjYWxlLCB0cnVlLCAhX3RoaXMuc2V0dGluZ3MuaW5maW5pdGVab29tKTtcclxuICAgICAgICAgICAgfSwgdGltZW91dCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jb3JlLmdldEVsZW1lbnRCeUlkKCdsZy16b29tLWluJykub24oJ2NsaWNrLmxnJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy56b29tSW4oKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmNvcmUuZ2V0RWxlbWVudEJ5SWQoJ2xnLWFjdHVhbC1zaXplJykub24oJ2NsaWNrLmxnJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRBY3R1YWxTaXplKF90aGlzLmNvcmUuaW5kZXgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuY29yZS5MR2VsLm9uKGxHRXZlbnRzLmJlZm9yZU9wZW4gKyBcIi56b29tXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuY29yZS5vdXRlci5maW5kKCcubGctaXRlbScpLnJlbW92ZUNsYXNzKCdsZy16b29tYWJsZScpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuY29yZS5MR2VsLm9uKGxHRXZlbnRzLmFmdGVyT3BlbiArIFwiLnpvb21cIiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5zY3JvbGxUb3AgPSBfdGhpcy4kTEcod2luZG93KS5zY3JvbGxUb3AoKTtcclxuICAgICAgICAgICAgLy8gU2V0IHRoZSBpbml0aWFsIHZhbHVlIGNlbnRlclxyXG4gICAgICAgICAgICBfdGhpcy5wYWdlWCA9IF90aGlzLmNvcmUub3V0ZXIud2lkdGgoKSAvIDI7XHJcbiAgICAgICAgICAgIF90aGlzLnBhZ2VZID0gX3RoaXMuY29yZS5vdXRlci5oZWlnaHQoKSAvIDIgKyBfdGhpcy5zY3JvbGxUb3A7XHJcbiAgICAgICAgICAgIF90aGlzLnNjYWxlID0gMTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBSZXNldCB6b29tIG9uIHNsaWRlIGNoYW5nZVxyXG4gICAgICAgIHRoaXMuY29yZS5MR2VsLm9uKGxHRXZlbnRzLmFmdGVyU2xpZGUgKyBcIi56b29tXCIsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICB2Y
1XIgcHJldkluZGV4ID0gZXZlbnQuZGV0YWlsLnByZXZJbmRleDtcclxuICAgICAgICAgICAgX3RoaXMuc2NhbGUgPSAxO1xyXG4gICAgICAgICAgICBfdGhpcy5wb3NpdGlvbkNoYW5nZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgX3RoaXMuem9vbUluUHJvZ3Jlc3MgPSBmYWxzZTtcclxuICAgICAgICAgICAgX3RoaXMucmVzZXRab29tKHByZXZJbmRleCk7XHJcbiAgICAgICAgICAgIF90aGlzLnJlc2V0SW1hZ2VUcmFuc2xhdGUocHJldkluZGV4KTtcclxuICAgICAgICAgICAgaWYgKF90aGlzLmlzSW1hZ2VTbGlkZShfdGhpcy5jb3JlLmluZGV4KSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0Wm9vbUVzc2VudGlhbHMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIERyYWcgb3B0aW9uIGFmdGVyIHpvb21cclxuICAgICAgICB0aGlzLnpvb21EcmFnKCk7XHJcbiAgICAgICAgdGhpcy5waW5jaFpvb20oKTtcclxuICAgICAgICB0aGlzLnpvb21Td2lwZSgpO1xyXG4gICAgICAgIC8vIFN0b3JlIHRoZSB6b29tYWJsZSB0aW1lb3V0IHZhbHVlIGp1c3QgdG8gY2xlYXIgaXQgd2hpbGUgY2xvc2luZ1xyXG4gICAgICAgIHRoaXMuem9vbWFibGVUaW1lb3V0ID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbkNoYW5nZWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnpvb21JblByb2dyZXNzID0gZmFsc2U7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuem9vbUluID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIEFsbG93IHpvb20gb25seSBvbiBpbWFnZVxyXG4gICAgICAgIGlmICghdGhpcy5pc0ltYWdlU2xpZGUodGhpcy5jb3JlLmluZGV4KSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzY2FsZSA9IHRoaXMuc2NhbGUgKyB0aGlzLnNldHRpbmdzLnNjYWxlO1xyXG4gICAgICAgIGlmICghdGhpcy5zZXR0aW5ncy5pbmZpbml0ZVpvb20pIHtcclxuICAgICAgICAgICAgc2NhbGUgPSB0aGlzLmdldFNjYWxlKHNjYWxlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5iZWdpblpvb20oc2NhbGUpO1xyXG4gICAgICAgIHRoaXMuem9vbUltYWdlKHNjYWxlLCBNYXRoLm1pbih0aGlzLnNldHRpbmdzLnNjYWxlLCBzY2FsZSAtIHRoaXMuc2NhbGUpLCB0cnVlLCAhdGhpcy5zZXR0aW5ncy5pbmZpbml0ZVpvb20pO1xyXG4gICAgfTtcclxuICAgIC8vIFJlc2V0IHpvb20gZWZmZWN0XHJcbiAgICBab29tLnByb3RvdHlwZS5yZXNldFpvb20gPSBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICB0aGlzLmNvcmUub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLXpvb21lZCBsZy16b29tLWRyYWctdHJhbnNpdGlvbicpO1xyXG4gICAgICAgIHZhciAkYWN0dWFsU2l6ZSA9IHRoaXMuY29yZS5nZXRFbGVtZW50QnlJZCgnbGctYWN0dWFsLXNpemUnKTtcclxuICAgICAgICB2Y
1XIgJGl0ZW0gPSB0aGlzLmNvcmUuZ2V0U2xpZGVJdGVtKGluZGV4ICE9PSB1bmRlZmluZWQgPyBpbmRleCA6IHRoaXMuY29yZS5pbmRleCk7XHJcbiAgICAgICAgJGFjdHVhbFNpemVcclxuICAgICAgICAgICAgLnJlbW92ZUNsYXNzKHRoaXMuc2V0dGluZ3MuYWN0dWFsU2l6ZUljb25zLnpvb21PdXQpXHJcbiAgICAgICAgICAgIC5hZGRDbGFzcyh0aGlzLnNldHRpbmdzLmFjdHVhbFNpemVJY29ucy56b29tSW4pO1xyXG4gICAgICAgICRpdGVtLmZpbmQoJy5sZy1pbWctd3JhcCcpLmZpcnN0KCkucmVtb3ZlQXR0cignc3R5bGUnKTtcclxuICAgICAgICAkaXRlbS5maW5kKCcubGctaW1hZ2UnKS5maXJzdCgpLnJlbW92ZUF0dHIoJ3N0eWxlJyk7XHJcbiAgICAgICAgdGhpcy5zY2FsZSA9IDE7XHJcbiAgICAgICAgdGhpcy5sZWZ0ID0gMDtcclxuICAgICAgICB0aGlzLnRvcCA9IDA7XHJcbiAgICAgICAgLy8gUmVzZXQgcGFneCBwYWd5IHZhbHVlcyB0byBjZW50ZXJcclxuICAgICAgICB0aGlzLnNldFBhZ2VDb3JkcygpO1xyXG4gICAgfTtcclxuICAgIFpvb20ucHJvdG90eXBlLmdldFRvdWNoRGlzdGFuY2UgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIHJldHVybiBNYXRoLnNxcnQoKGUudG91Y2hlc1swXS5wYWdlWCAtIGUudG91Y2hlc1sxXS5wYWdlWCkgKlxyXG4gICAgICAgICAgICAoZS50b3VjaGVzWzBdLnBhZ2VYIC0gZS50b3VjaGVzWzFdLnBhZ2VYKSArXHJcbiAgICAgICAgICAgIChlLnRvdWNoZXNbMF0ucGFnZVkgLSBlLnRvdWNoZXNbMV0ucGFnZVkpICpcclxuICAgICAgICAgICAgICAgIChlLnRvdWNoZXNbMF0ucGFnZVkgLSBlLnRvdWNoZXNbMV0ucGFnZVkpKTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5waW5jaFpvb20gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2Y
1XIgc3RhcnREaXN0ID0gMDtcclxuICAgICAgICB2YXIgcGluY2hTdGFydGVkID0gZmFsc2U7XHJcbiAgICAgICAgdmFyIGluaXRTY2FsZSA9IDE7XHJcbiAgICAgICAgdmFyIHByZXZTY2FsZSA9IDA7XHJcbiAgICAgICAgdmFyICRpdGVtID0gdGhpcy5jb3JlLmdldFNsaWRlSXRlbSh0aGlzLmNvcmUuaW5kZXgpO1xyXG4gICAgICAgIHRoaXMuY29yZS5vdXRlci5vbigndG91Y2hzdGFydC5sZycsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICRpdGVtID0gX3RoaXMuY29yZS5nZXRTbGlkZUl0ZW0oX3RoaXMuY29yZS5pbmRleCk7XHJcbiAgICAgICAgICAgIGlmICghX3RoaXMuaXNJbWFnZVNsaWRlKF90aGlzLmNvcmUuaW5kZXgpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGUudG91Y2hlcy5sZW5ndGggPT09IDIpIHtcclxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5jb3JlLm91dGVyLmhhc0NsYXNzKCdsZy1maXJzdC1zbGlkZS1sb2FkaW5nJykpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpbml0U2NhbGUgPSBfdGhpcy5zY2FsZSB8fCAxO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuY29yZS5vdXRlci5yZW1vdmVDbGFzcygnbGctem9vbS1kcmFnLXRyYW5zaXRpb24gbGctem9vbS1kcmFnZ2luZycpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0UGFnZUNvcmRzKGUpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMucmVzZXRJbWFnZVRyYW5zbGF0ZShfdGhpcy5jb3JlLmluZGV4KTtcclxuICAgICAgICAgICAgICAgIF90aGlzLmNvcmUudG91Y2hBY3Rpb24gPSAncGluY2gnO1xyXG4gICAgICAgICAgICAgICAgc3RhcnREaXN0ID0gX3RoaXMuZ2V0VG91Y2hEaXN0YW5jZShlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuY29yZS4kaW5uZXIub24oJ3RvdWNobW92ZS5sZycsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGlmIChlLnRvdWNoZXMubGVuZ3RoID09PSAyICYmXHJcbiAgICAgICAgICAgICAgICBfdGhpcy5jb3JlLnRvdWNoQWN0aW9uID09PSAncGluY2gnICYmXHJcbiAgICAgICAgICAgICAgICAoX3RoaXMuJExHKGUudGFyZ2V0KS5oYXNDbGFzcygnbGctaXRlbScpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgJGl0ZW0uZ2V0KCkuY29udGFpbnMoZS50YXJnZXQpKSkge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGVuZERpc3QgPSBfdGhpcy5nZXRUb3VjaERpc3RhbmNlKGUpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGRpc3RhbmNlID0gc3RhcnREaXN0IC0gZW5kRGlzdDtcclxuICAgICAgICAgICAgICAgIGlmICghcGluY2hTdGFydGVkICYmIE1hdGguYWJzKGRpc3RhbmNlKSA+IDUpIHtcclxuICAgICAgICAgICAgICAgICAgICBwaW5jaFN0YXJ0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHBpbmNoU3RhcnRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHByZXZTY2FsZSA9IF90aGlzLnNjYWxlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBfc2NhbGUgPSBNYXRoLm1heCgxLCBpbml0U2NhbGUgKyAtZGlzdGFuY2UgKiAwLjAyKTtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zY2FsZSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgucm91bmQoKF9zY2FsZSArIE51bWJlci5FUFNJTE9OKSAqIDEwMCkgLyAxMDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRpZmYgPSBfdGhpcy5zY2FsZSAtIHByZXZTY2FsZTtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy56b29tSW1hZ2UoX3RoaXMuc2NhbGUsIE1hdGgucm91bmQoKGRpZmYgKyBOdW1iZXIuRVBTSUxPTikgKiAxMDApIC8gMTAwLCBmYWxzZSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jb3JlLiRpbm5lci5vbigndG91Y2hlbmQubGcnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuY29yZS50b3VjaEFjdGlvbiA9PT0gJ3BpbmNoJyAmJlxyXG4gICAgICAgICAgICAgICAgKF90aGlzLiRMRyhlLnRhcmdldCkuaGFzQ2xhc3MoJ2xnLWl0ZW0nKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICRpdGVtLmdldCgpLmNvbnRhaW5zKGUudGFyZ2V0KSkpIHtcclxuICAgICAgICAgICAgICAgIHBpbmNoU3RhcnRlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgc3RhcnREaXN0ID0gMDtcclxuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5zY2FsZSA8PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucmVzZXRab29tKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2Y
1XIgYWN0dWFsU2l6ZVNjYWxlID0gX3RoaXMuZ2V0Q3VycmVudEltYWdlQWN0dWFsU2l6ZVNjYWxlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLnNjYWxlID49IGFjdHVhbFNpemVTY2FsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2NhbGVEaWZmID0gYWN0dWFsU2l6ZVNjYWxlIC0gX3RoaXMuc2NhbGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY2FsZURpZmYgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlRGlmZiA9IDAuMDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuem9vbUltYWdlKGFjdHVhbFNpemVTY2FsZSwgc2NhbGVEaWZmLCBmYWxzZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLm1hbmFnZUFjdHVhbFBpeGVsQ2xhc3NOYW1lcygpO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmNvcmUub3V0ZXIuYWRkQ2xhc3MoJ2xnLXpvb21lZCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgX3RoaXMuY29yZS50b3VjaEFjdGlvbiA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIFpvb20ucHJvdG90eXBlLnRvdWNoZW5kWm9vbSA9IGZ1bmN0aW9uIChzdGFydENvb3JkcywgZW5kQ29vcmRzLCBhbGxvd1gsIGFsbG93WSwgdG91Y2hEdXJhdGlvbikge1xyXG4gICAgICAgIHZhciBkaXN0YW5jZVhuZXcgPSBlbmRDb29yZHMueCAtIHN0YXJ0Q29vcmRzLng7XHJcbiAgICAgICAgdmFyIGRpc3RhbmNlWW5ldyA9IGVuZENvb3Jkcy55IC0gc3RhcnRDb29yZHMueTtcclxuICAgICAgICB2Y
1XIgc3BlZWRYID0gTWF0aC5hYnMoZGlzdGFuY2VYbmV3KSAvIHRvdWNoRHVyYXRpb24gKyAxO1xyXG4gICAgICAgIHZhciBzcGVlZFkgPSBNYXRoLmFicyhkaXN0YW5jZVluZXcpIC8gdG91Y2hEdXJhdGlvbiArIDE7XHJcbiAgICAgICAgaWYgKHNwZWVkWCA+IDIpIHtcclxuICAgICAgICAgICAgc3BlZWRYICs9IDE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzcGVlZFkgPiAyKSB7XHJcbiAgICAgICAgICAgIHNwZWVkWSArPSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICBkaXN0YW5jZVhuZXcgPSBkaXN0YW5jZVhuZXcgKiBzcGVlZFg7XHJcbiAgICAgICAgZGlzdGFuY2VZbmV3ID0gZGlzdGFuY2VZbmV3ICogc3BlZWRZO1xyXG4gICAgICAgIHZhciBfTEdlbCA9IHRoaXMuY29yZVxyXG4gICAgICAgICAgICAuZ2V0U2xpZGVJdGVtKHRoaXMuY29yZS5pbmRleClcclxuICAgICAgICAgICAgLmZpbmQoJy5sZy1pbWctd3JhcCcpXHJcbiAgICAgICAgICAgIC5maXJzdCgpO1xyXG4gICAgICAgIHZhciBkaXN0YW5jZSA9IHt9O1xyXG4gICAgICAgIGRpc3RhbmNlLnggPSB0aGlzLmxlZnQgKyBkaXN0YW5jZVhuZXc7XHJcbiAgICAgICAgZGlzdGFuY2UueSA9IHRoaXMudG9wICsgZGlzdGFuY2VZbmV3O1xyXG4gICAgICAgIHZhciBwb3NzaWJsZVN3aXBlQ29yZHMgPSB0aGlzLmdldFBvc3NpYmxlU3dpcGVEcmFnQ29yZHMoKTtcclxuICAgICAgICBpZiAoTWF0aC5hYnMoZGlzdGFuY2VYbmV3KSA+IDE1IHx8IE1hdGguYWJzKGRpc3RhbmNlWW5ldykgPiAxNSkge1xyXG4gICAgICAgICAgICBpZiAoYWxsb3dZKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0JleW9uZFBvc3NpYmxlVG9wKGRpc3RhbmNlLnksIHBvc3NpYmxlU3dpcGVDb3Jkcy5taW5ZKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRpc3RhbmNlLnkgPSBwb3NzaWJsZVN3aXBlQ29yZHMubWluWTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuaXNCZXlvbmRQb3NzaWJsZUJvdHRvbShkaXN0YW5jZS55LCBwb3NzaWJsZVN3aXBlQ29yZHMubWF4WSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBkaXN0YW5jZS55ID0gcG9zc2libGVTd2lwZUNvcmRzLm1heFk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGFsbG93WCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNCZXlvbmRQb3NzaWJsZUxlZnQoZGlzdGFuY2UueCwgcG9zc2libGVTd2lwZUNvcmRzLm1pblgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlzdGFuY2UueCA9IHBvc3NpYmxlU3dpcGVDb3Jkcy5taW5YO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5pc0JleW9uZFBvc3NpYmxlUmlnaHQoZGlzdGFuY2UueCwgcG9zc2libGVTd2lwZUNvcmRzLm1heFgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlzdGFuY2UueCA9IHBvc3NpYmxlU3dpcGVDb3Jkcy5tYXhYO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChhbGxvd1kpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudG9wID0gZGlzdGFuY2UueTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGRpc3RhbmNlLnkgPSB0aGlzLnRvcDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoYWxsb3dYKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnQgPSBkaXN0YW5jZS54O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZGlzdGFuY2UueCA9IHRoaXMubGVmdDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLnNldFpvb21Td2lwZVN0eWxlcyhfTEdlbCwgZGlzdGFuY2UpO1xyXG4gICAgICAgICAgICB0aGlzLnBvc2l0aW9uQ2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIFpvb20ucHJvdG90eXBlLmdldFpvb21Td2lwZUNvcmRzID0gZnVuY3Rpb24gKHN0YXJ0Q29vcmRzLCBlbmRDb29yZHMsIGFsbG93WCwgYWxsb3dZLCBwb3NzaWJsZVN3aXBlQ29yZHMpIHtcclxuICAgICAgICB2Y
1XIgZGlzdGFuY2UgPSB7fTtcclxuICAgICAgICBpZiAoYWxsb3dZKSB7XHJcbiAgICAgICAgICAgIGRpc3RhbmNlLnkgPSB0aGlzLnRvcCArIChlbmRDb29yZHMueSAtIHN0YXJ0Q29vcmRzLnkpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0JleW9uZFBvc3NpYmxlVG9wKGRpc3RhbmNlLnksIHBvc3NpYmxlU3dpcGVDb3Jkcy5taW5ZKSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGRpZmZNaW5ZID0gcG9zc2libGVTd2lwZUNvcmRzLm1pblkgLSBkaXN0YW5jZS55O1xyXG4gICAgICAgICAgICAgICAgZGlzdGFuY2UueSA9IHBvc3NpYmxlU3dpcGVDb3Jkcy5taW5ZIC0gZGlmZk1pblkgLyA2O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuaXNCZXlvbmRQb3NzaWJsZUJvdHRvbShkaXN0YW5jZS55LCBwb3NzaWJsZVN3aXBlQ29yZHMubWF4WSkpIHtcclxuICAgICAgICAgICAgICAgIHZhciBkaWZmTWF4WSA9IGRpc3RhbmNlLnkgLSBwb3NzaWJsZVN3aXBlQ29yZHMubWF4WTtcclxuICAgICAgICAgICAgICAgIGRpc3RhbmNlLnkgPSBwb3NzaWJsZVN3aXBlQ29yZHMubWF4WSArIGRpZmZNYXhZIC8gNjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZGlzdGFuY2UueSA9IHRoaXMudG9wO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYWxsb3dYKSB7XHJcbiAgICAgICAgICAgIGRpc3RhbmNlLnggPSB0aGlzLmxlZnQgKyAoZW5kQ29vcmRzLnggLSBzdGFydENvb3Jkcy54KTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNCZXlvbmRQb3NzaWJsZUxlZnQoZGlzdGFuY2UueCwgcG9zc2libGVTd2lwZUNvcmRzLm1pblgpKSB7XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgZGlmZk1pblggPSBwb3NzaWJsZVN3aXBlQ29yZHMubWluWCAtIGRpc3RhbmNlLng7XHJcbiAgICAgICAgICAgICAgICBkaXN0YW5jZS54ID0gcG9zc2libGVTd2lwZUNvcmRzLm1pblggLSBkaWZmTWluWCAvIDY7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5pc0JleW9uZFBvc3NpYmxlUmlnaHQoZGlzdGFuY2UueCwgcG9zc2libGVTd2lwZUNvcmRzLm1heFgpKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZGlmTWF4WCA9IGRpc3RhbmNlLnggLSBwb3NzaWJsZVN3aXBlQ29yZHMubWF4WDtcclxuICAgICAgICAgICAgICAgIGRpc3RhbmNlLnggPSBwb3NzaWJsZVN3aXBlQ29yZHMubWF4WCArIGRpZk1heFggLyA2O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBkaXN0YW5jZS54ID0gdGhpcy5sZWZ0O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZGlzdGFuY2U7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuaXNCZXlvbmRQb3NzaWJsZUxlZnQgPSBmdW5jdGlvbiAoeCwgbWluWCkge1xyXG4gICAgICAgIHJldHVybiB4ID49IG1pblg7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuaXNCZXlvbmRQb3NzaWJsZVJpZ2h0ID0gZnVuY3Rpb24gKHgsIG1heFgpIHtcclxuICAgICAgICByZXR1cm4geCA8PSBtYXhYO1xyXG4gICAgfTtcclxuICAgIFpvb20ucHJvdG90eXBlLmlzQmV5b25kUG9zc2libGVUb3AgPSBmdW5jdGlvbiAoeSwgbWluWSkge1xyXG4gICAgICAgIHJldHVybiB5ID49IG1pblk7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuaXNCZXlvbmRQb3NzaWJsZUJvdHRvbSA9IGZ1bmN0aW9uICh5LCBtYXhZKSB7XHJcbiAgICAgICAgcmV0dXJuIHkgPD0gbWF4WTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5pc0ltYWdlU2xpZGUgPSBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICB2Y
1XIgY3VycmVudEl0ZW0gPSB0aGlzLmNvcmUuZ2FsbGVyeUl0ZW1zW2luZGV4XTtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb3JlLmdldFNsaWRlVHlwZShjdXJyZW50SXRlbSkgPT09ICdpbWFnZSc7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuZ2V0UG9zc2libGVTd2lwZURyYWdDb3JkcyA9IGZ1bmN0aW9uIChzY2FsZSkge1xyXG4gICAgICAgIHZhciAkaW1hZ2UgPSB0aGlzLmNvcmVcclxuICAgICAgICAgICAgLmdldFNsaWRlSXRlbSh0aGlzLmNvcmUuaW5kZXgpXHJcbiAgICAgICAgICAgIC5maW5kKCcubGctaW1hZ2UnKVxyXG4gICAgICAgICAgICAuZmlyc3QoKTtcclxuICAgICAgICB2YXIgYm90dG9tID0gdGhpcy5jb3JlLm1lZGlhQ29udGFpbmVyUG9zaXRpb24uYm90dG9tO1xyXG4gICAgICAgIHZhciBpbWdSZWN0ID0gJGltYWdlLmdldCgpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIHZhciBpbWFnZUhlaWdodCA9IGltZ1JlY3QuaGVpZ2h0O1xyXG4gICAgICAgIHZhciBpbWFnZVdpZHRoID0gaW1nUmVjdC53aWR0aDtcclxuICAgICAgICBpZiAoc2NhbGUpIHtcclxuICAgICAgICAgICAgaW1hZ2VIZWlnaHQgPSBpbWFnZUhlaWdodCArIHNjYWxlICogaW1hZ2VIZWlnaHQ7XHJcbiAgICAgICAgICAgIGltYWdlV2lkdGggPSBpbWFnZVdpZHRoICsgc2NhbGUgKiBpbWFnZVdpZHRoO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgbWluWSA9IChpbWFnZUhlaWdodCAtIHRoaXMuY29udGFpbmVyUmVjdC5oZWlnaHQpIC8gMjtcclxuICAgICAgICB2Y
1XIgbWF4WSA9ICh0aGlzLmNvbnRhaW5lclJlY3QuaGVpZ2h0IC0gaW1hZ2VIZWlnaHQpIC8gMiArIGJvdHRvbTtcclxuICAgICAgICB2YXIgbWluWCA9IChpbWFnZVdpZHRoIC0gdGhpcy5jb250YWluZXJSZWN0LndpZHRoKSAvIDI7XHJcbiAgICAgICAgdmFyIG1heFggPSAodGhpcy5jb250YWluZXJSZWN0LndpZHRoIC0gaW1hZ2VXaWR0aCkgLyAyO1xyXG4gICAgICAgIHZhciBwb3NzaWJsZVN3aXBlQ29yZHMgPSB7XHJcbiAgICAgICAgICAgIG1pblk6IG1pblksXHJcbiAgICAgICAgICAgIG1heFk6IG1heFksXHJcbiAgICAgICAgICAgIG1pblg6IG1pblgsXHJcbiAgICAgICAgICAgIG1heFg6IG1heFgsXHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gcG9zc2libGVTd2lwZUNvcmRzO1xyXG4gICAgfTtcclxuICAgIFpvb20ucHJvdG90eXBlLnNldFpvb21Td2lwZVN0eWxlcyA9IGZ1bmN0aW9uIChMR2VsLCBkaXN0YW5jZSkge1xyXG4gICAgICAgIExHZWwuY3NzKCd0cmFuc2Zvcm0nLCAndHJhbnNsYXRlM2QoJyArIGRpc3RhbmNlLnggKyAncHgsICcgKyBkaXN0YW5jZS55ICsgJ3B4LCAwKScpO1xyXG4gICAgfTtcclxuICAgIFpvb20ucHJvdG90eXBlLnpvb21Td2lwZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBzdGFydENvb3JkcyA9IHt9O1xyXG4gICAgICAgIHZhciBlbmRDb29yZHMgPSB7fTtcclxuICAgICAgICB2YXIgaXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgICAgIC8vIEFsbG93IHggZGlyZWN0aW9uIGRyYWdcclxuICAgICAgICB2Y
1XIgYWxsb3dYID0gZmFsc2U7XHJcbiAgICAgICAgLy8gQWxsb3cgWSBkaXJlY3Rpb24gZHJhZ1xyXG4gICAgICAgIHZhciBhbGxvd1kgPSBmYWxzZTtcclxuICAgICAgICB2YXIgc3RhcnRUaW1lID0gbmV3IERhdGUoKTtcclxuICAgICAgICB2YXIgZW5kVGltZSA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgdmFyIHBvc3NpYmxlU3dpcGVDb3JkcztcclxuICAgICAgICB2YXIgX0xHZWw7XHJcbiAgICAgICAgdmFyICRpdGVtID0gdGhpcy5jb3JlLmdldFNsaWRlSXRlbSh0aGlzLmNvcmUuaW5kZXgpO1xyXG4gICAgICAgIHRoaXMuY29yZS4kaW5uZXIub24oJ3RvdWNoc3RhcnQubGcnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAvLyBBbGxvdyB6b29tIG9ubHkgb24gaW1hZ2VcclxuICAgICAgICAgICAgaWYgKCFfdGhpcy5pc0ltYWdlU2xpZGUoX3RoaXMuY29yZS5pbmRleCkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAkaXRlbSA9IF90aGlzLmNvcmUuZ2V0U2xpZGVJdGVtKF90aGlzLmNvcmUuaW5kZXgpO1xyXG4gICAgICAgICAgICBpZiAoKF90aGlzLiRMRyhlLnRhcmdldCkuaGFzQ2xhc3MoJ2xnLWl0ZW0nKSB8fFxyXG4gICAgICAgICAgICAgICAgJGl0ZW0uZ2V0KCkuY29udGFpbnMoZS50YXJnZXQpKSAmJlxyXG4gICAgICAgICAgICAgICAgZS50b3VjaGVzLmxlbmd0aCA9PT0gMSAmJlxyXG4gICAgICAgICAgICAgICAgX3RoaXMuY29yZS5vdXRlci5oYXNDbGFzcygnbGctem9vbWVkJykpIHtcclxuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5jb3JlLnRvdWNoQWN0aW9uID0gJ3pvb21Td2lwZSc7XHJcbiAgICAgICAgICAgICAgICBfTEdlbCA9IF90aGlzLmNvcmVcclxuICAgICAgICAgICAgICAgICAgICAuZ2V0U2xpZGVJdGVtKF90aGlzLmNvcmUuaW5kZXgpXHJcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoJy5sZy1pbWctd3JhcCcpXHJcbiAgICAgICAgICAgICAgICAgICAgLmZpcnN0KCk7XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgZHJhZ0FsbG93ZWRBeGlzZXMgPSBfdGhpcy5nZXREcmFnQWxsb3dlZEF4aXNlcygwKTtcclxuICAgICAgICAgICAgICAgIGFsbG93WSA9IGRyYWdBbGxvd2VkQXhpc2VzLmFsbG93WTtcclxuICAgICAgICAgICAgICAgIGFsbG93WCA9IGRyYWdBbGxvd2VkQXhpc2VzLmFsbG93WDtcclxuICAgICAgICAgICAgICAgIGlmIChhbGxvd1ggfHwgYWxsb3dZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRDb29yZHMgPSBfdGhpcy5nZXRTd2lwZUNvcmRzKGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcG9zc2libGVTd2lwZUNvcmRzID0gX3RoaXMuZ2V0UG9zc2libGVTd2lwZURyYWdDb3JkcygpO1xyXG4gICAgICAgICAgICAgICAgLy8gcmVzZXQgb3BhY2l0eSBhbmQgdHJhbnNpdGlvbiBkdXJhdGlvblxyXG4gICAgICAgICAgICAgICAgX3RoaXMuY29yZS5vdXRlci5hZGRDbGFzcygnbGctem9vbS1kcmFnZ2luZyBsZy16b29tLWRyYWctdHJhbnNpdGlvbicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jb3JlLiRpbm5lci5vbigndG91Y2htb3ZlLmxnJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgaWYgKGUudG91Y2hlcy5sZW5ndGggPT09IDEgJiZcclxuICAgICAgICAgICAgICAgIF90aGlzLmNvcmUudG91Y2hBY3Rpb24gPT09ICd6b29tU3dpcGUnICYmXHJcbiAgICAgICAgICAgICAgICAoX3RoaXMuJExHKGUudGFyZ2V0KS5oYXNDbGFzcygnbGctaXRlbScpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgJGl0ZW0uZ2V0KCkuY29udGFpbnMoZS50YXJnZXQpKSkge1xyXG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuY29yZS50b3VjaEFjdGlvbiA9ICd6b29tU3dpcGUnO1xyXG4gICAgICAgICAgICAgICAgZW5kQ29vcmRzID0gX3RoaXMuZ2V0U3dpcGVDb3JkcyhlKTtcclxuICAgICAgICAgICAgICAgIHZhciBkaXN0YW5jZSA9IF90aGlzLmdldFpvb21Td2lwZUNvcmRzKHN0YXJ0Q29vcmRzLCBlbmRDb29yZHMsIGFsbG93WCwgYWxsb3dZLCBwb3NzaWJsZVN3aXBlQ29yZHMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKGVuZENvb3Jkcy54IC0gc3RhcnRDb29yZHMueCkgPiAxNSB8fFxyXG4gICAgICAgICAgICAgICAgICAgIE1hdGguYWJzKGVuZENvb3Jkcy55IC0gc3RhcnRDb29yZHMueSkgPiAxNSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlzTW92ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFpvb21Td2lwZVN0eWxlcyhfTEdlbCwgZGlzdGFuY2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jb3JlLiRpbm5lci5vbigndG91Y2hlbmQubGcnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuY29yZS50b3VjaEFjdGlvbiA9PT0gJ3pvb21Td2lwZScgJiZcclxuICAgICAgICAgICAgICAgIChfdGhpcy4kTEcoZS50YXJnZXQpLmhhc0NsYXNzKCdsZy1pdGVtJykgfHxcclxuICAgICAgICAgICAgICAgICAgICAkaXRlbS5nZXQoKS5jb250YWlucyhlLnRhcmdldCkpKSB7XHJcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5jb3JlLnRvdWNoQWN0aW9uID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuY29yZS5vdXRlci5yZW1vdmVDbGFzcygnbGctem9vbS1kcmFnZ2luZycpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFpc01vdmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgZW5kVGltZSA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgdG91Y2hEdXJhdGlvbiA9IGVuZFRpbWUudmFsdWVPZigpIC0gc3RhcnRUaW1lLnZhbHVlT2YoKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLnRvdWNoZW5kWm9vbShzdGFydENvb3JkcywgZW5kQ29vcmRzLCBhbGxvd1gsIGFsbG93WSwgdG91Y2hEdXJhdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS56b29tRHJhZyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBzdGFydENvb3JkcyA9IHt9O1xyXG4gICAgICAgIHZhciBlbmRDb29yZHMgPSB7fTtcclxuICAgICAgICB2YXIgaXNEcmFnZ2luZyA9IGZhbHNlO1xyXG4gICAgICAgIHZhciBpc01vdmVkID0gZmFsc2U7XHJcbiAgICAgICAgLy8gQWxsb3cgeCBkaXJlY3Rpb24gZHJhZ1xyXG4gICAgICAgIHZhciBhbGxvd1ggPSBmYWxzZTtcclxuICAgICAgICAvLyBBbGxvdyBZIGRpcmVjdGlvbiBkcmFnXHJcbiAgICAgICAgdmFyIGFsbG93WSA9IGZhbHNlO1xyXG4gICAgICAgIHZhciBzdGFydFRpbWU7XHJcbiAgICAgICAgdmFyIGVuZFRpbWU7XHJcbiAgICAgICAgdmFyIHBvc3NpYmxlU3dpcGVDb3JkcztcclxuICAgICAgICB2YXIgX0xHZWw7XHJcbiAgICAgICAgdGhpcy5jb3JlLm91dGVyLm9uKCdtb3VzZWRvd24ubGcuem9vbScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIC8vIEFsbG93IHpvb20gb25seSBvbiBpbWFnZVxyXG4gICAgICAgICAgICBpZiAoIV90aGlzLmlzSW1hZ2VTbGlkZShfdGhpcy5jb3JlLmluZGV4KSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciAkaXRlbSA9IF90aGlzLmNvcmUuZ2V0U2xpZGVJdGVtKF90aGlzLmNvcmUuaW5kZXgpO1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuJExHKGUudGFyZ2V0KS5oYXNDbGFzcygnbGctaXRlbScpIHx8XHJcbiAgICAgICAgICAgICAgICAkaXRlbS5nZXQoKS5jb250YWlucyhlLnRhcmdldCkpIHtcclxuICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgICAgICAgICBfTEdlbCA9IF90aGlzLmNvcmVcclxuICAgICAgICAgICAgICAgICAgICAuZ2V0U2xpZGVJdGVtKF90aGlzLmNvcmUuaW5kZXgpXHJcbiAgICAgICAgICAgICAgICAgICAgLmZpbmQoJy5sZy1pbWctd3JhcCcpXHJcbiAgICAgICAgICAgICAgICAgICAgLmZpcnN0KCk7XHJcbiAgICAgICAgICAgICAgICB2Y
1XIgZHJhZ0FsbG93ZWRBeGlzZXMgPSBfdGhpcy5nZXREcmFnQWxsb3dlZEF4aXNlcygwKTtcclxuICAgICAgICAgICAgICAgIGFsbG93WSA9IGRyYWdBbGxvd2VkQXhpc2VzLmFsbG93WTtcclxuICAgICAgICAgICAgICAgIGFsbG93WCA9IGRyYWdBbGxvd2VkQXhpc2VzLmFsbG93WDtcclxuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5jb3JlLm91dGVyLmhhc0NsYXNzKCdsZy16b29tZWQnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfdGhpcy4kTEcoZS50YXJnZXQpLmhhc0NsYXNzKCdsZy1vYmplY3QnKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoYWxsb3dYIHx8IGFsbG93WSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydENvb3JkcyA9IF90aGlzLmdldERyYWdDb3JkcyhlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcG9zc2libGVTd2lwZUNvcmRzID0gX3RoaXMuZ2V0UG9zc2libGVTd2lwZURyYWdDb3JkcygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc0RyYWdnaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuY29yZS5vdXRlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCdsZy1ncmFiJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnbGctZ3JhYmJpbmcgbGctem9vbS1kcmFnLXRyYW5zaXRpb24gbGctem9vbS1kcmFnZ2luZycpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyByZXNldCBvcGFjaXR5IGFuZCB0cmFuc2l0aW9uIGR1cmF0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy4kTEcod2luZG93KS5vbihcIm1vdXNlbW92ZS5sZy56b29tLmdsb2JhbFwiICsgdGhpcy5jb3JlLmxnSWQsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGlmIChpc0RyYWdnaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBpc01vdmVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGVuZENvb3JkcyA9IF90aGlzLmdldERyYWdDb3JkcyhlKTtcclxuICAgICAgICAgICAgICAgIHZhciBkaXN0YW5jZSA9IF90aGlzLmdldFpvb21Td2lwZUNvcmRzKHN0YXJ0Q29vcmRzLCBlbmRDb29yZHMsIGFsbG93WCwgYWxsb3dZLCBwb3NzaWJsZVN3aXBlQ29yZHMpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0Wm9vbVN3aXBlU3R5bGVzKF9MR2VsLCBkaXN0YW5jZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLiRMRyh3aW5kb3cpLm9uKFwibW91c2V1cC5sZy56b29tLmdsb2JhbFwiICsgdGhpcy5jb3JlLmxnSWQsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGlmIChpc0RyYWdnaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBlbmRUaW1lID0gbmV3IERhdGUoKTtcclxuICAgICAgICAgICAgICAgIGlzRHJhZ2dpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIF90aGlzLmNvcmUub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLXpvb20tZHJhZ2dpbmcnKTtcclxuICAgICAgICAgICAgICAgIC8vIEZpeCBmb3IgY2hyb21lIG1vdXNlIG1vdmUgb24gY2xpY2tcclxuICAgICAgICAgICAgICAgIGlmIChpc01vdmVkICYmXHJcbiAgICAgICAgICAgICAgICAgICAgKHN0YXJ0Q29vcmRzLnggIT09IGVuZENvb3Jkcy54IHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29vcmRzLnkgIT09IGVuZENvb3Jkcy55KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVuZENvb3JkcyA9IF90aGlzLmdldERyYWdDb3JkcyhlKTtcclxuICAgICAgICAgICAgICAgICAgICB2Y
1XIgdG91Y2hEdXJhdGlvbiA9IGVuZFRpbWUudmFsdWVPZigpIC0gc3RhcnRUaW1lLnZhbHVlT2YoKTtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy50b3VjaGVuZFpvb20oc3RhcnRDb29yZHMsIGVuZENvb3JkcywgYWxsb3dYLCBhbGxvd1ksIHRvdWNoRHVyYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaXNNb3ZlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLmNvcmUub3V0ZXIucmVtb3ZlQ2xhc3MoJ2xnLWdyYWJiaW5nJykuYWRkQ2xhc3MoJ2xnLWdyYWInKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBab29tLnByb3RvdHlwZS5jbG9zZUdhbGxlcnkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5yZXNldFpvb20oKTtcclxuICAgICAgICB0aGlzLnpvb21JblByb2dyZXNzID0gZmFsc2U7XHJcbiAgICB9O1xyXG4gICAgWm9vbS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBVbmJpbmQgYWxsIGV2ZW50cyBhZGRlZCBieSBsaWdodEdhbGxlcnkgem9vbSBwbHVnaW5cclxuICAgICAgICB0aGlzLiRMRyh3aW5kb3cpLm9mZihcIi5sZy56b29tLmdsb2JhbFwiICsgdGhpcy5jb3JlLmxnSWQpO1xyXG4gICAgICAgIHRoaXMuY29yZS5MR2VsLm9mZignLmxnLnpvb20nKTtcclxuICAgICAgICB0aGlzLmNvcmUuTEdlbC5vZmYoJy56b29tJyk7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuem9vbWFibGVUaW1lb3V0KTtcclxuICAgICAgICB0aGlzLnpvb21hYmxlVGltZW91dCA9IGZhbHNlO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBab29tO1xyXG59KCkpO1xuXG5leHBvcnQgZGVmYXVsdCBab29tO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGctem9vbS5lczUuanMubWFwXG4iLCJmdW5jdGlvbiB0KHQsZSxpKXtyZXR1cm4gTWF0aC5tYXgodCxNYXRoLm1pbihlLGkpKX1jbGFzcyBBbmltYXRle2FkdmFuY2UoZSl7aWYoIXRoaXMuaXNSdW5uaW5nKXJldHVybjtsZXQgaT0hMTtpZih0aGlzLmxlcnApdGhpcy52YWx1ZT0ocz10aGlzLnZhbHVlLG89dGhpcy50byxuPTYwKnRoaXMubGVycCxyPWUsZnVuY3Rpb24odCxlLGkpe3JldHVybigxLWkpKnQraSplfShzLG8sMS1NYXRoLmV4cCgtbipyKSkpLE1hdGgucm91bmQodGhpcy52YWx1ZSk9PT10aGlzLnRvJiYodGhpcy52YWx1ZT10aGlzLnRvLGk9ITApO2Vsc2V7dGhpcy5jdXJyZW50VGltZSs9ZTtjb25zdCBzPXQoMCx0aGlzLmN1cnJlbnRUaW1lL3RoaXMuZHVyYXRpb24sMSk7aT1zPj0xO2NvbnN0IG89aT8xOnRoaXMuZWFzaW5nKHMpO3RoaXMudmFsdWU9dGhpcy5mcm9tKyh0aGlzLnRvLXRoaXMuZnJvbSkqb312YXIgcyxvLG4scjt0aGlzLm9uVXBkYXRlPy4odGhpcy52YWx1ZSxpKSxpJiZ0aGlzLnN0b3AoKX1zdG9wKCl7dGhpcy5pc1J1bm5pbmc9ITF9ZnJvbVRvKHQsZSx7bGVycDppPS4xLGR1cmF0aW9uOnM9MSxlYXNpbmc6bz0odD0+dCksb25TdGFydDpuLG9uVXBkYXRlOnJ9KXt0aGlzLmZyb209dGhpcy52YWx1ZT10LHRoaXMudG89ZSx0aGlzLmxlcnA9aSx0aGlzLmR1cmF0aW9uPXMsdGhpcy5lYXNpbmc9byx0aGlzLmN1cnJlbnRUaW1lPTAsdGhpcy5pc1J1bm5pbmc9ITAsbj8uKCksdGhpcy5vblVwZGF0ZT1yfX1jbGFzcyBEaW1lbnNpb25ze2NvbnN0cnVjdG9yKHt3cmFwcGVyOnQsY29udGVudDplLGF1dG9SZXNpemU6aT0hMCxkZWJvdW5jZTpzPTI1MH09e30pe3RoaXMud3JhcHBlcj10LHRoaXMuY29udGVudD1lLGkmJih0aGlzLmRlYm91bmNlZFJlc2l6ZT1mdW5jdGlvbih0LGUpe2xldCBpO3JldHVybiBmdW5jdGlvbigpe2xldCBzPWFyZ3VtZW50cyxvPXRoaXM7Y2xlYXJUaW1lb3V0KGkpLGk9c2V0VGltZW91dCgoZnVuY3Rpb24oKXt0LmFwcGx5KG8scyl9KSxlKX19KHRoaXMucmVzaXplLHMpLHRoaXMud3JhcHBlcj09PXdpbmRvdz93aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLHRoaXMuZGVib3VuY2VkUmVzaXplLCExKToodGhpcy53cmFwcGVyUmVzaXplT2JzZXJ2ZXI9bmV3IFJlc2l6ZU9ic2VydmVyKHRoaXMuZGVib3VuY2VkUmVzaXplKSx0aGlzLndyYXBwZXJSZXNpemVPYnNlcnZlci5vYnNlcnZlKHRoaXMud3JhcHBlcikpLHRoaXMuY29udGVudFJlc2l6ZU9ic2VydmVyPW5ldyBSZXNpemVPYnNlcnZlcih0aGlzLmRlYm91bmNlZFJlc2l6ZSksdGhpcy5jb250ZW50UmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmNvbnRlbnQpKSx0aGlzLnJlc2l6ZSgpfWRlc3Ryb3koKXt0aGlzLndyYXBwZXJSZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpLHRoaXMuY29udGVudFJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCksd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIix0aGlzLmRlYm91bmNlZFJlc2l6ZSwhMSl9cmVzaXplPSgpPT57dGhpcy5vbldyYXBwZXJSZXNpemUoKSx0aGlzLm9uQ29udGVudFJlc2l6ZSgpfTtvbldyYXBwZXJSZXNpemU9KCk9Pnt0aGlzLndyYXBwZXI9PT13aW5kb3c/KHRoaXMud2lkdGg9d2luZG93LmlubmVyV2lkdGgsdGhpcy5oZWlnaHQ9d2luZG93LmlubmVySGVpZ2h0KToodGhpcy53aWR0aD10aGlzLndyYXBwZXIuY2xpZW50V2lkdGgsdGhpcy5oZWlnaHQ9dGhpcy53cmFwcGVyLmNsaWVudEhlaWdodCl9O29uQ29udGVudFJlc2l6ZT0oKT0+e3RoaXMud3JhcHBlcj09PXdpbmRvdz8odGhpcy5zY3JvbGxIZWlnaHQ9dGhpcy5jb250ZW50LnNjcm9sbEhlaWdodCx0aGlzLnNjcm9sbFdpZHR
1oPXRoaXMuY29udGVudC5zY3JvbGxXaWR0aCk6KHRoaXMuc2Nyb2xsSGVpZ2h0PXRoaXMud3JhcHBlci5zY3JvbGxIZWlnaHQsdGhpcy5zY3JvbGxXaWR0aD10aGlzLndyYXBwZXIuc2Nyb2xsV2lkdGgpfTtnZXQgbGltaXQoKXtyZXR1cm57eDp0aGlzLnNjcm9sbFdpZHRoLXRoaXMud2lkdGgseTp0aGlzLnNjcm9sbEhlaWdodC10aGlzLmhlaWdodH19fWNsYXNzIEVtaXR0ZXJ7Y29uc3RydWN0b3IoKXt0aGlzLmV2ZW50cz17fX1lbWl0KHQsLi4uZSl7bGV0IGk9dGhpcy5ldmVudHNbdF18fFtdO2ZvcihsZXQgdD0wLHM9aS5sZW5ndGg7dDxzO3QrKylpW3RdKC4uLmUpfW9uKHQsZSl7cmV0dXJuIHRoaXMuZXZlbnRzW3RdPy5wdXNoKGUpfHwodGhpcy5ldmVudHNbdF09W2VdKSwoKT0+e3RoaXMuZXZlbnRzW3RdPXRoaXMuZXZlbnRzW3RdPy5maWx0ZXIoKHQ9PmUhPT10KSl9fW9mZih0LGUpe3RoaXMuZXZlbnRzW3RdPXRoaXMuZXZlbnRzW3RdPy5maWx0ZXIoKHQ9PmUhPT10KSl9ZGVzdHJveSgpe3RoaXMuZXZlbnRzPXt9fX1jb25zdCBlPTEwMC82O2NsYXNzIFZpcnR1YWxTY3JvbGx7Y29uc3RydWN0b3IodCx7d2hlZWxNdWx0aXBsaWVyOmU9MSx0b3VjaE11bHRpcGxpZXI6aT0xfSl7dGhpcy5lbGVtZW50PXQsdGhpcy53aGVlbE11bHRpcGxpZXI9ZSx0aGlzLnRvdWNoTXVsdGlwbGllcj1pLHRoaXMudG91Y2hTdGFydD17eDpudWxsLHk6bnVsbH0sdGhpcy5lbWl0dGVyPW5ldyBFbWl0dGVyLHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsdGhpcy5vbldpbmRvd1Jlc2l6ZSwhMSksdGhpcy5vbldpbmRvd1Jlc2l6ZSgpLHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwid2hlZWxcIix0aGlzLm9uV2hlZWwse3Bhc3NpdmU6ITF9KSx0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIix0aGlzLm9uVG91Y2hTdGFydCx7cGFzc2l2ZTohMX0pLHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsdGhpcy5vblRvdWNoTW92ZSx7cGFzc2l2ZTohMX0pLHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIix0aGlzLm9uVG91Y2hFbmQse3Bhc3NpdmU6ITF9KX1vbih0LGUpe3JldHVybiB0aGlzLmVtaXR0ZXIub24odCxlKX1kZXN0cm95KCl7dGhpcy5lbWl0dGVyLmRlc3Ryb3koKSx3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLHRoaXMub25XaW5kb3dSZXNpemUsITEpLHRoaXMuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwid2hlZWxcIix0aGlzLm9uV2hlZWwse3Bhc3NpdmU6ITF9KSx0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIix0aGlzLm9uVG91Y2hTdGFydCx7cGFzc2l2ZTohMX0pLHRoaXMuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsdGhpcy5vblRvdWNoTW92ZSx7cGFzc2l2ZTohMX0pLHRoaXMuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIix0aGlzLm9uVG91Y2hFbmQse3Bhc3NpdmU6ITF9KX1vblRvdWNoU3RhcnQ9dD0+e2NvbnN0e2NsaWVudFg6ZSxjbGllbnRZOml9PXQudGFyZ2V0VG91Y2hlcz90LnRhcmdldFRvdWNoZXNbMF06dDt0aGlzLnRvdWNoU3RhcnQueD1lLHRoaXMudG91Y2hTdGFydC55PWksdGhpcy5sYXN0RGVsdGE9e3g6MCx5OjB9LHRoaXMuZW1pdHRlci5lbWl0KFwic2Nyb2xsXCIse2RlbHRhWDowLGRlbHRhWTowLGV2ZW50OnR9KX07b25Ub3VjaE1vdmU9dD0+e2NvbnN0e2NsaWVudFg6ZSxjbGllbnRZOml9PXQudGFyZ2V0VG91Y2hlcz90LnRhcmdldFRvdWNoZXNbMF06dCxzPS0oZS10aGlzLnRvdWNoU3RhcnQueCkqdGhpcy50b3VjaE11bHRpcGxpZXIsbz0tKGktdGhpcy50b3VjaFN0YXJ0LnkpKnRoaXMudG91Y2hNdWx0aXBsaWVyO3RoaXMudG91Y2hTdGFydC54PWUsdGhpcy50b3VjaFN0YXJ0Lnk9aSx0aGlzLmxhc3REZWx0YT17eDpzLHk6b30sdGhpcy5lbWl0dGVyLmVtaXQoXCJzY3JvbGxcIix7ZGVsdGFYOnMsZGVsdGFZOm8sZXZlbnQ6dH0pfTtvblRvdWNoRW5kPXQ9Pnt0aGlzLmVtaXR0ZXIuZW1pdChcInNjcm9sbFwiLHtkZWx0YVg6dGhpcy5sYXN0RGVsdGEueCxkZWx0YVk6dGhpcy5sYXN0RGVsdGEueSxldmVudDp0fSl9O29uV2hlZWw9dD0+e2xldHtkZWx0YVg6aSxkZWx0YVk6cyxkZWx0YU1vZGU6b309dDtpKj0xPT09bz9lOjI9PT1vP3RoaXMud2luZG93V2lkdGg6MSxzKj0xPT09bz9lOjI9PT1vP3RoaXMud2luZG93SGVpZ2h0OjEsaSo9dGhpcy53aGVlbE11bHRpcGxpZXIscyo9dGhpcy53aGVlbE11bHRpcGxpZXIsdGhpcy5lbWl0dGVyLmVtaXQoXCJzY3JvbGxcIix7ZGVsdGFYOmksZGVsdGFZOnMsZXZlbnQ6dH0pfTtvbldpbmRvd1Jlc2l6ZT0oKT0+e3RoaXMud2luZG93V2lkdGg9d2luZG93LmlubmVyV2lkdGgsdGhpcy53aW5kb3dIZWlnaHQ9d2luZG93LmlubmVySGVpZ2h0fX1jbGFzcyBMZW5pc3tjb25zdHJ1Y3Rvcih7d3JhcHBlcjp0PXdpbmRvdyxjb250ZW50OmU9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LHdoZWVsRXZlbnRzVGFyZ2V0Omk9dCxldmVudHNUYXJnZXQ6cz1pLHNtb290aFdoZWVsOm89ITAsc3luY1RvdWNoOm49ITEsc3luY1RvdWNoTGVycDpyPS4wNzUsdG91Y2hJbmVydGlhTXVsdGlwbGllcjpsPTM1LGR1cmF0aW9uOmgsZWFzaW5nOmE9KHQ9Pk1hdGgubWluKDEsMS4wMDEtTWF0aC5wb3coMiwtMTAqdCkpKSxsZXJwOmM9IWgmJi4xLGluZmluaXRlOmQ9ITEsb3JpZW50YXRpb246cD1cInZlcnRpY2FsXCIsZ2VzdHVyZU9yaWVudGF0aW9uOnU9XCJ2ZXJ0aWNhbFwiLHRvdWNoTXVsdGlwbGllcjptPTEsd2hlZWxNdWx0aXBsaWVyOnY9MSxhdXRvUmVzaXplOmc9ITAsX19leHBlcmltZW50YWxfX25haXZlRGltZW5zaW9uczpTPSExfT17fSl7dGhpcy5fX2lzU21vb3RoPSExLHRoaXMuX19pc1Njcm9sbGluZz0hMSx0aGlzLl9faXNTdG9wcGVkPSExLHRoaXMuX19pc0xvY2tlZD0hMSx0aGlzLm9uVmlydHVhbFNjcm9sbD0oe2RlbHRhWDp0LGRlbHRhWTplLGV2ZW50Oml9KT0+e2lmKGkuY3RybEtleSlyZXR1cm47Y29uc3Qgcz1pLnR5cGUuaW5jbHVkZXMoXCJ0b3VjaFwiKSxvPWkudHlwZS5pbmNsdWRlcyhcIndoZWVsXCIpO2lmKHRoaXMub3B0aW9ucy5zeW5jVG91Y2gmJnMmJlwidG91Y2hzdGFydFwiPT09aS50eXBlJiYhdGhpcy5pc1N0b3BwZWQmJiF0aGlzLmlzTG9ja2VkKXJldHVybi
1B2b2lkIHRoaXMucmVzZXQoKTtjb25zdCBuPTA9PT10JiYwPT09ZSxyPVwidmVydGljYWxcIj09PXRoaXMub3B0aW9ucy5nZXN0dXJlT3JpZW50YXRpb24mJjA9PT1lfHxcImhvcml6b250YWxcIj09PXRoaXMub3B0aW9ucy5nZXN0dXJlT3JpZW50YXRpb24mJjA9PT10O2lmKG58fHIpcmV0dXJuO2xldCBsPWkuY29tcG9zZWRQYXRoKCk7aWYobD1sLnNsaWNlKDAsbC5pbmRleE9mKHRoaXMucm9vdEVsZW1lbnQpKSxsLmZpbmQoKHQ9Pnt2YXIgZSxpLG4scixsO3JldHVybihudWxsPT09KGU9dC5oYXNBdHRyaWJ1dGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmNhbGwodCxcImRhdGEtbGVuaXMtcHJldmVudFwiKSl8fHMmJihudWxsPT09KGk9dC5oYXNBdHRyaWJ1dGUpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmNhbGwodCxcImRhdGEtbGVuaXMtcHJldmVudC10b3VjaFwiKSl8fG8mJihudWxsPT09KG49dC5oYXNBdHRyaWJ1dGUpfHx2b2lkIDA9PT1uP3ZvaWQgMDpuLmNhbGwodCxcImRhdGEtbGVuaXMtcHJldmVudC13aGVlbFwiKSl8fChudWxsPT09KHI9dC5jbGFzc0xpc3QpfHx2b2lkIDA9PT1yP3ZvaWQgMDpyLmNvbnRhaW5zKFwibGVuaXNcIikpJiYhKG51bGw9PT0obD10LmNsYXNzTGlzdCl8fHZvaWQgMD09PWw/dm9pZCAwOmwuY29udGFpbnMoXCJsZW5pcy1zdG9wcGVkXCIpKX0pKSlyZXR1cm47aWYodGhpcy5pc1N0b3BwZWR8fHRoaXMuaXNMb2NrZWQpcmV0dXJuIHZvaWQgaS5wcmV2ZW50RGVmYXVsdCgpO2lmKHRoaXMuaXNTbW9vdGg9dGhpcy5vcHRpb25zLnN5bmNUb3VjaCYmc3x8dGhpcy5vcHRpb25zLnNtb290aFdoZWVsJiZvLCF0aGlzLmlzU21vb3RoKXJldHVybiB0aGlzLmlzU2Nyb2xsaW5nPSExLHZvaWQgdGhpcy5hbmltYXRlLnN0b3AoKTtpLnByZXZlbnREZWZhdWx0KCk7bGV0IGg9ZTtcImJvdGhcIj09PXRoaXMub3B0aW9ucy5nZXN0dXJlT3JpZW50YXRpb24/aD1NYXRoLmFicyhlKT5NYXRoLmFicyh0KT9lOnQ6XCJob3Jpem9udGFsXCI9PT10aGlzLm9wdGlvbnMuZ2VzdHVyZU9yaWVudGF0aW9uJiYoaD10KTtjb25zdCBhPXMmJnRoaXMub3B0aW9ucy5zeW5jVG91Y2gsYz1zJiZcInRvdWNoZW5kXCI9PT1pLnR5cGUmJk1hdGguYWJzKGgpPjU7YyYmKGg9dGhpcy52ZWxvY2l0eSp0aGlzLm9wdGlvbnMudG91Y2hJbmVydGlhTXVsdGlwbGllciksdGhpcy5zY3JvbGxUbyh0aGlzLnRhcmdldFNjcm9sbCtoLE9iamVjdC5hc3NpZ24oe3Byb2dyYW1tYXRpYzohMX0sYT97bGVycDpjP3RoaXMub3B0aW9ucy5zeW5jVG91Y2hMZXJwOjF9OntsZXJwOnRoaXMub3B0aW9ucy5sZXJwLGR1cmF0aW9uOnRoaXMub3B0aW9ucy5kdXJhdGlvbixlYXNpbmc6dGhpcy5vcHRpb25zLmVhc2luZ30pKX0sdGhpcy5vbk5hdGl2ZVNjcm9sbD0oKT0+e2lmKCF0aGlzLl9fcHJldmVudE5leHRTY3JvbGxFdmVudCYmIXRoaXMuaXNTY3JvbGxpbmcpe2NvbnN0IHQ9dGhpcy5hbmltYXRlZFNjcm9sbDt0aGlzLmFuaW1hdGVkU2Nyb2xsPXRoaXMudGFyZ2V0U2Nyb2xsPXRoaXMuYWN0dWFsU2Nyb2xsLHRoaXMudmVsb2NpdHk9MCx0aGlzLmRpcmVjdGlvbj1NYXRoLnNpZ24odGhpcy5hbmltYXRlZFNjcm9sbC10KSx0aGlzLmVtaXQoKX19LHdpbmRvdy5sZW5pc1ZlcnNpb249XCIxLjAuNDJcIix0IT09ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50JiZ0IT09ZG9jdW1lbnQuYm9keXx8KHQ9d2luZG93KSx0aGlzLm9wdGlvbnM9e3dyYXBwZXI6dCxjb250ZW50OmUsd2hlZWxFdmVudHNUYXJnZXQ6aSxldmVudHNUYXJnZXQ6cyxzbW9vdGhXaGVlbDpvLHN5bmNUb3VjaDpuLHN5bmNUb3VjaExlcnA6cix0b3VjaEluZXJ0aWFNdWx0aXBsaWVyOmwsZHVyYXRpb246aCxlYXNpbmc6YSxsZXJwOmMsaW5maW5pdGU6ZCxnZXN0dXJlT3JpZW50YXRpb246dSxvcmllbnRhdGlvbjpwLHRvdWNoTXVsdGlwbGllcjptLHdoZWVsTXVsdGlwbGllcjp2LGF1dG9SZXNpemU6ZyxfX2V4cGVyaW1lbnRhbF9fbmFpdmVEaW1lbnNpb25zOlN9LHRoaXMuYW5pbWF0ZT1uZXcgQW5pbWF0ZSx0aGlzLmVtaXR0ZXI9bmV3IEVtaXR0ZXIsdGhpcy5kaW1lbnNpb25zPW5ldyBEaW1lbnNpb25zKHt3cmFwcGVyOnQsY29udGVudDplLGF1dG9SZXNpemU6Z30pLHRoaXMudG9nZ2xlQ2xhc3NOYW1lKFwibGVuaXNcIiwhMCksdGhpcy52ZWxvY2l0eT0wLHRoaXMuaXNMb2NrZWQ9ITEsdGhpcy5pc1N0b3BwZWQ9ITEsdGhpcy5pc1Ntb290aD1ufHxvLHRoaXMuaXNTY3JvbGxpbmc9ITEsdGhpcy50YXJnZXRTY3JvbGw9dGhpcy5hbmltYXRlZFNjcm9sbD10aGlzLmFjdHVhbFNjcm9sbCx0aGlzLm9wdGlvbnMud3JhcHBlci5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsdGhpcy5vbk5hdGl2ZVNjcm9sbCwhMSksdGhpcy52aXJ0dWFsU2Nyb2xsPW5ldyBWaXJ0dWFsU2Nyb2xsKHMse3RvdWNoTXVsdGlwbGllcjptLHdoZWVsTXVsdGlwbGllcjp2fSksdGhpcy52aXJ0dWFsU2Nyb2xsLm9uKFwic2Nyb2xsXCIsdGhpcy5vblZpcnR1YWxTY3JvbGwpfWRlc3Ryb3koKXt0aGlzLmVtaXR0ZXIuZGVzdHJveSgpLHRoaXMub3B0aW9ucy53cmFwcGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIix0aGlzLm9uTmF0aXZlU2Nyb2xsLCExKSx0aGlzLnZpcnR1YWxTY3JvbGwuZGVzdHJveSgpLHRoaXMuZGltZW5zaW9ucy5kZXN0cm95KCksdGhpcy50b2dnbGVDbGFzc05hbWUoXCJsZW5pc1wiLCExKSx0aGlzLnRvZ2dsZUNsYXNzTmFtZShcImxlbmlzLXNtb290aFwiLCExKSx0aGlzLnRvZ2dsZUNsYXNzTmFtZShcImxlbmlzLXNjcm9sbGluZ1wiLCExKSx0aGlzLnRvZ2dsZUNsYXNzTmFtZShcImxlbmlzLXN0b3BwZWRcIiwhMSksdGhpcy50b2dnbGVDbGFzc05hbWUoXCJsZW5pcy1sb2NrZWRcIiwhMSl9b24odCxlKXtyZXR1cm4gdGhpcy5lbWl0dGVyLm9uKHQsZSl9b2ZmKHQsZSl7cmV0dXJuIHRoaXMuZW1pdHRlci5vZmYodCxlKX1zZXRTY3JvbGwodCl7dGhpcy5pc0hvcml6b250YWw/dGhpcy5yb290RWxlbWVudC5zY3JvbGxMZWZ0PXQ6dGhpcy5yb290RWxlbWVudC5zY3JvbGxUb3A9dH1yZXNpemUoKXt0aGlzLmRpbWVuc2lvbnMucmVzaXplKCl9ZW1pdCgpe3RoaXMuZW1pdHRlci5lbWl0KFwic2Nyb2xsXCIsdGhpcyl9cmVzZXQoKXt0aGlzLmlzTG9ja2VkPSExLHRoaXMuaXNTY3JvbGxpbmc9ITEsdGhpcy5hbmltYXRlZFNjcm9sbD10aGlzLnRhcmdldFNjcm9sbD10aGlzLmFjdHVhbFNjcm9sbCx0aGlzLnZlbG9jaXR5PTAsdGhpcy5hbmltYXRlLnN0b3AoKX1zdGFydCgpe3RoaXMuaXNTdG9wcGVkJiYodGhpcy5pc1N0b3BwZWQ9IT
1EsdGhpcy5yZXNldCgpKX1zdG9wKCl7dGhpcy5pc1N0b3BwZWR8fCh0aGlzLmlzU3RvcHBlZD0hMCx0aGlzLmFuaW1hdGUuc3RvcCgpLHRoaXMucmVzZXQoKSl9cmFmKHQpe2NvbnN0IGU9dC0odGhpcy50aW1lfHx0KTt0aGlzLnRpbWU9dCx0aGlzLmFuaW1hdGUuYWR2YW5jZSguMDAxKmUpfXNjcm9sbFRvKGUse29mZnNldDppPTAsaW1tZWRpYXRlOnM9ITEsbG9jazpvPSExLGR1cmF0aW9uOm49dGhpcy5vcHRpb25zLmR1cmF0aW9uLGVhc2luZzpyPXRoaXMub3B0aW9ucy5lYXNpbmcsbGVycDpsPSFuJiZ0aGlzLm9wdGlvbnMubGVycCxvbkNvbXBsZXRlOmgsZm9yY2U6YT0hMSxwcm9ncmFtbWF0aWM6Yz0hMH09e30pe2lmKCF0aGlzLmlzU3RvcHBlZCYmIXRoaXMuaXNMb2NrZWR8fGEpe2lmKFtcInRvcFwiLFwibGVmdFwiLFwic3RhcnRcIl0uaW5jbHVkZXMoZSkpZT0wO2Vsc2UgaWYoW1wiYm90dG9tXCIsXCJyaWdodFwiLFwiZW5kXCJdLmluY2x1ZGVzKGUpKWU9dGhpcy5saW1pdDtlbHNle2xldCB0O2lmKFwic3RyaW5nXCI9PXR5cGVvZiBlP3Q9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKToobnVsbD09ZT92b2lkIDA6ZS5ub2RlVHlwZSkmJih0PWUpLHQpe2lmKHRoaXMub3B0aW9ucy53cmFwcGVyIT09d2luZG93KXtjb25zdCB0PXRoaXMub3B0aW9ucy53cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO2ktPXRoaXMuaXNIb3Jpem9udGFsP3QubGVmdDp0LnRvcH1jb25zdCBzPXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7ZT0odGhpcy5pc0hvcml6b250YWw/cy5sZWZ0OnMudG9wKSt0aGlzLmFuaW1hdGVkU2Nyb2xsfX1pZihcIm51bWJlclwiPT10eXBlb2YgZSl7aWYoZSs9aSxlPU1hdGgucm91bmQoZSksdGhpcy5vcHRpb25zLmluZmluaXRlP2MmJih0aGlzLnRhcmdldFNjcm9sbD10aGlzLmFuaW1hdGVkU2Nyb2xsPXRoaXMuc2Nyb2xsKTplPXQoMCxlLHRoaXMubGltaXQpLHMpcmV0dXJuIHRoaXMuYW5pbWF0ZWRTY3JvbGw9dGhpcy50YXJnZXRTY3JvbGw9ZSx0aGlzLnNldFNjcm9sbCh0aGlzLnNjcm9sbCksdGhpcy5yZXNldCgpLHZvaWQobnVsbD09aHx8aCh0aGlzKSk7aWYoIWMpe2lmKGU9PT10aGlzLnRhcmdldFNjcm9sbClyZXR1cm47dGhpcy50YXJnZXRTY3JvbGw9ZX10aGlzLmFuaW1hdGUuZnJvbVRvKHRoaXMuYW5pbWF0ZWRTY3JvbGwsZSx7ZHVyYXRpb246bixlYXNpbmc6cixsZXJwOmwsb25TdGFydDooKT0+e28mJih0aGlzLmlzTG9ja2VkPSEwKSx0aGlzLmlzU2Nyb2xsaW5nPSEwfSxvblVwZGF0ZToodCxlKT0+e3RoaXMuaXNTY3JvbGxpbmc9ITAsdGhpcy52ZWxvY2l0eT10LXRoaXMuYW5pbWF0ZWRTY3JvbGwsdGhpcy5kaXJlY3Rpb249TWF0aC5zaWduKHRoaXMudmVsb2NpdHkpLHRoaXMuYW5pbWF0ZWRTY3JvbGw9dCx0aGlzLnNldFNjcm9sbCh0aGlzLnNjcm9sbCksYyYmKHRoaXMudGFyZ2V0U2Nyb2xsPXQpLGV8fHRoaXMuZW1pdCgpLGUmJih0aGlzLnJlc2V0KCksdGhpcy5lbWl0KCksbnVsbD09aHx8aCh0aGlzKSx0aGlzLl9fcHJldmVudE5leHRTY3JvbGxFdmVudD0hMCxyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCgpPT57ZGVsZXRlIHRoaXMuX19wcmV2ZW50TmV4dFNjcm9sbEV2ZW50fSkpKX19KX19fWdldCByb290RWxlbWVudCgpe3JldHVybiB0aGlzLm9wdGlvbnMud3JhcHBlcj09PXdpbmRvdz9kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ6dGhpcy5vcHRpb25zLndyYXBwZXJ9Z2V0IGxpbWl0KCl7cmV0dXJuIHRoaXMub3B0aW9ucy5fX2V4cGVyaW1lbnRhbF9fbmFpdmVEaW1lbnNpb25zP3RoaXMuaXNIb3Jpem9udGFsP3RoaXMucm9vdEVsZW1lbnQuc2Nyb2xsV2lkdGgtdGhpcy5yb290RWxlbWVudC5jbGllbnRXaWR0aDp0aGlzLnJvb3RFbGVtZW50LnNjcm9sbEhlaWdodC10aGlzLnJvb3RFbGVtZW50LmNsaWVudEhlaWdodDp0aGlzLmRpbWVuc2lvbnMubGltaXRbdGhpcy5pc0hvcml6b250YWw/XCJ4XCI6XCJ5XCJdfWdldCBpc0hvcml6b250YWwoKXtyZXR1cm5cImhvcml6b250YWxcIj09PXRoaXMub3B0aW9ucy5vcmllbnRhdGlvbn1nZXQgYWN0dWFsU2Nyb2xsKCl7cmV0dXJuIHRoaXMuaXNIb3Jpem9udGFsP3RoaXMucm9vdEVsZW1lbnQuc2Nyb2xsTGVmdDp0aGlzLnJvb3RFbGVtZW50LnNjcm9sbFRvcH1nZXQgc2Nyb2xsKCl7cmV0dXJuIHRoaXMub3B0aW9ucy5pbmZpbml0ZT8odD10aGlzLmFuaW1hdGVkU2Nyb2xsLGU9dGhpcy5saW1pdCwodCVlK2UpJWUpOnRoaXMuYW5pbWF0ZWRTY3JvbGw7dmFyIHQsZX1nZXQgcHJvZ3Jlc3MoKXtyZXR1cm4gMD09PXRoaXMubGltaXQ/MTp0aGlzLnNjcm9sbC90aGlzLmxpbWl0fWdldCBpc1Ntb290aCgpe3JldHVybiB0aGlzLl9faXNTbW9vdGh9c2V0IGlzU21vb3RoKHQpe3RoaXMuX19pc1Ntb290aCE9PXQmJih0aGlzLl9faXNTbW9vdGg9dCx0aGlzLnRvZ2dsZUNsYXNzTmFtZShcImxlbmlzLXNtb290aFwiLHQpKX1nZXQgaXNTY3JvbGxpbmcoKXtyZXR1cm4gdGhpcy5fX2lzU2Nyb2xsaW5nfXNldCBpc1Njcm9sbGluZyh0KXt0aGlzLl9faXNTY3JvbGxpbmchPT10JiYodGhpcy5fX2lzU2Nyb2xsaW5nPXQsdGhpcy50b2dnbGVDbGFzc05hbWUoXCJsZW5pcy1zY3JvbGxpbmdcIix0KSl9Z2V0IGlzU3RvcHBlZCgpe3JldHVybiB0aGlzLl9faXNTdG9wcGVkfXNldCBpc1N0b3BwZWQodCl7dGhpcy5fX2lzU3RvcHBlZCE9PXQmJih0aGlzLl9faXNTdG9wcGVkPXQsdGhpcy50b2dnbGVDbGFzc05hbWUoXCJsZW5pcy1zdG9wcGVkXCIsdCkpfWdldCBpc0xvY2tlZCgpe3JldHVybiB0aGlzLl9faXNMb2NrZWR9c2V0IGlzTG9ja2VkKHQpe3RoaXMuX19pc0xvY2tlZCE9PXQmJih0aGlzLl9faXNMb2NrZWQ9dCx0aGlzLnRvZ2dsZUNsYXNzTmFtZShcImxlbmlzLWxvY2tlZFwiLHQpKX1nZXQgY2xhc3NOYW1lKCl7bGV0IHQ9XCJsZW5pc1wiO3JldHVybiB0aGlzLmlzU3RvcHBlZCYmKHQrPVwiIGxlbmlzLXN0b3BwZWRcIiksdGhpcy5pc0xvY2tlZCYmKHQrPVwiIGxlbmlzLWxvY2tlZFwiKSx0aGlzLmlzU2Nyb2xsaW5nJiYodCs9XCIgbGVuaXMtc2Nyb2xsaW5nXCIpLHRoaXMuaXNTbW9vdGgmJih0Kz1cIiBsZW5pcy1zbW9vdGhcIiksdH10b2dnbGVDbGFzc05hbWUo
1dCxlKXt0aGlzLnJvb3RFbGVtZW50LmNsYXNzTGlzdC50b2dnbGUodCxlKSx0aGlzLmVtaXR0ZXIuZW1pdChcImNsYXNzTmFtZSBjaGFuZ2VcIix0aGlzKX19ZXhwb3J0e0xlbmlzIGFzIGRlZmF1bHR9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGVuaXMubWpzLm1hcFxuIiwiZnVuY3Rpb24gX2Fzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKSB7IGlmIChzZWxmID09PSB2b2lkIDApIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpOyB9IHJldHVybiBzZWxmOyB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0c0xvb3NlKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcy5wcm90b3R5cGUpOyBzdWJDbGFzcy5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBzdWJDbGFzczsgc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG4vKiFcbiAqIEdTQVAgMy4xMi41XG4gKiBodHRwczovL2dzYXAuY29tXG4gKlxuICogQGxpY2Vuc2UgQ29weXJpZ2h0IDIwMDgtMjAyNCwgR3JlZW5Tb2NrLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogU3ViamVjdCB0byB0aGUgdGVybXMgYXQgaHR0cHM6Ly9nc2FwLmNvbS9zdGFuZGFyZC1saWNlbnNlIG9yIGZvclxuICogQ2x1YiBHU0FQIG1lbWJlcnMsIHRoZSBhZ3JlZW1lbnQgaXNzdWVkIHdpdGggdGhhdCBtZW1iZXJzaGlwLlxuICogQGF1dGhvcjogSmFjayBEb3lsZSwgamFja0BncmVlbnNvY2suY29tXG4qL1xuXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xudmFyIF9jb25maWcgPSB7XG4gIGF1dG9TbGVlcDogMTIwLFxuICBmb3JjZTNEOiBcImF1dG9cIixcbiAgbnVsbFRhcmdldFdhcm46IDEsXG4gIHVuaXRzOiB7XG4gICAgbGluZUhlaWdodDogXCJcIlxuICB9XG59LFxuICAgIF9kZWZhdWx0cyA9IHtcbiAgZHVyYXRpb246IC41LFxuICBvdmVyd3JpdGU6IGZhbHNlLFxuICBkZWxheTogMFxufSxcbiAgICBfc3VwcHJlc3NPdmVyd3JpdGVzLFxuICAgIF9yZXZlcnRpbmcsXG4gICAgX2NvbnRleHQsXG4gICAgX2JpZ051bSA9IDFlOCxcbiAgICBfdGlueU51bSA9IDEgLyBfYmlnTnVtLFxuICAgIF8yUEkgPSBNYXRoLlBJICogMixcbiAgICBfSEFMRl9QSSA9IF8yUEkgLyA0LFxuICAgIF9nc0lEID0gMCxcbiAgICBfc3FydCA9IE1hdGguc3FydCxcbiAgICBfY29zID0gTWF0aC5jb3MsXG4gICAgX3NpbiA9IE1hdGguc2luLFxuICAgIF9pc1N0cmluZyA9IGZ1bmN0aW9uIF9pc1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiO1xufSxcbiAgICBfaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIF9pc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIjtcbn0sXG4gICAgX2lzTnVtYmVyID0gZnVuY3Rpb24gX2lzTnVtYmVyKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCI7XG59LFxuICAgIF9pc1VuZGVmaW5lZCA9IGZ1bmN0aW9uIF9pc1VuZGVmaW5lZCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiO1xufSxcbiAgICBfaXNPYmplY3QgPSBmdW5jdGlvbiBfaXNPYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIjtcbn0sXG4gICAgX2lzTm90RmFsc2UgPSBmdW5jdGlvbiBfaXNOb3RGYWxzZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT09IGZhbHNlO1xufSxcbiAgICBfd2luZG93RXhpc3RzID0gZnVuY3Rpb24gX3dpbmRvd0V4aXN0cygpIHtcbiAgcmV0dXJuIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCI7XG59LFxuICAgIF9pc0Z1bmNPclN0cmluZyA9IGZ1bmN0aW9uIF9pc0Z1bmNPclN0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gX2lzRnVuY3Rpb24odmFsdWUpIHx8IF9pc1N0cmluZyh2YWx1ZSk7XG59LFxuICAgIF9pc1R5cGVkQXJyYXkgPSB0eXBlb2YgQXJyYXlCdWZmZXIgPT09IFwiZnVuY3Rpb25cIiAmJiBBcnJheUJ1ZmZlci5pc1ZpZXcgfHwgZnVuY3Rpb24gKCkge30sXG4gICAgLy8gbm90ZTogSUUxMCBoYXMgQXJyYXlCdWZmZXIsIGJ1dCBOT1QgQXJyYXlCdWZmZXIuaXNWaWV3KCkuXG5faXNBcnJheSA9IEFycmF5LmlzQXJyYXksXG4gICAgX3N0cmljdE51bUV4cCA9IC8oPzotP1xcLj9cXGR8XFwuKSsvZ2ksXG4gICAgLy9vbmx5IG51bWJlcnMgKGluY2x1ZGluZyBuZWdhdGl2ZXMgYW5kIGRlY2ltYWxzKSBidXQgTk9UIHJlbGF0aXZlIHZhbHVlcy5cbl9udW1FeHAgPSAvWy0rPS5dKlxcZCtbLmVcXC0rXSpcXGQqW2VcXC0rXSpcXGQqL2csXG4gICAgLy9maW5kcyBhbnkgbnVtYmVycywgaW5jbHVkaW5nIG9uZXMgdGhhdCBzdGFydCB3aXRoICs9IG9yIC09LCBuZWdhdGl2ZSBudW1iZXJzLCBhbmQgb25lcyBpbiBzY2llbnRpZmljIG5vdGF0aW9uIGxpa2UgMWUtOC5cbl9udW1XaXRoVW5pdEV4cCA9IC9bLSs9Ll0qXFxkK1suZS1dKlxcZCpbYS16JV0qL2csXG4gICAgX2NvbXBsZXhTdHJpbmdOdW1FeHAgPSAvWy0rPS5dKlxcZCtcXC4/XFxkKig/OmUtfGVcXCspP1xcZCovZ2ksXG4gICAgLy9kdXBsaWNhdGUgc28gdGhhdCB3aGlsZSB3ZSdyZSBsb29waW5nIHRocm91Z2ggbWF0Y2hlcyBmcm9tIGV4ZWMoKSwgaXQgZG9lc24ndCBjb250YW1pbmF0ZSB0aGUgbGFzdEluZGV4IG9mIF9udW1FeHAgd2hpY2ggd2UgdXNlIHRvIHNlYXJjaCBmb3IgY29sb3JzIHRvby5cbl9yZWxFeHAgPSAvWystXT0tP1suXFxkXSsvLFxuICAgIF9kZWxpbWl0ZWRWYWx1ZUV4cCA9IC9bXiwnXCJcXFtcXF1cXHNdKy9naSxcbiAgICAvLyBwcmV2aW91c2x5IC9bI1xcLSsuXSpcXGJbYS16XFxkXFwtPSslLl0rL2dpIGJ1dCBkaWRuJ3QgY2F0Y2ggc3BlY2lhbCBjaGFyYWN0ZXJzLlxuX3VuaXRFeHAgPSAvXlsrXFwtPWVcXHNcXGRdKlxcZCtbLlxcZF0qKFthLXpdKnwlKVxccyokL2ksXG4gICAgX2dsb2JhbFRpbWVsaW5lLFxuICAgIF93aW4sXG4gICAgX2NvcmVJbml0dGVkLFxuICAgIF9kb2MsXG4gICAgX2dsb2JhbHMgPSB7fSxcbiAgICBfaW5zdGFsbFNjb3BlID0ge30sXG4gICAgX2NvcmVSZWFkeSxcbiAgICBfaW5zdGFsbCA9IGZ1bmN0aW9uIF9pbnN0YWxsKHNjb3BlKSB7XG4gIHJldHVybiAoX2luc3RhbGxTY29wZSA9IF9tZXJnZShzY29wZSwgX2dsb2JhbHMpKSAmJiBnc2FwO1xufSxcbiAgICBfbWlzc2luZ1BsdWdpbiA9IGZ1bmN0aW9uIF9taXNzaW5nUGx1Z2luKHByb3BlcnR5LCB2YWx1ZSkge1xuICByZXR1cm4gY29uc29sZS53YXJuKFwiSW52YWxpZCBwcm9wZXJ0eVwiLCBwcm9wZXJ0eSwgXCJzZXQgdG9cIiwgdmFsdWUsIFwiTWlzc2luZyBwbHVnaW4/IGdzYXAucmVnaXN0ZXJQbHVnaW4oKVwiKTtcbn0sXG4gICAgX3dhcm4gPSBmdW5jdGlvbiBfd2FybihtZXNzYWdlLCBzdXBwcmVzcykge1xuICByZXR1cm4gIXN1cHByZXNzICYmIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbn0sXG4gICAgX2FkZEdsb2JhbCA9IGZ1bmN0aW9uIF9hZGRHbG9iYWwobmFtZSwgb2JqKSB7XG4gIHJldHVybi
1BuYW1lICYmIChfZ2xvYmFsc1tuYW1lXSA9IG9iaikgJiYgX2luc3RhbGxTY29wZSAmJiAoX2luc3RhbGxTY29wZVtuYW1lXSA9IG9iaikgfHwgX2dsb2JhbHM7XG59LFxuICAgIF9lbXB0eUZ1bmMgPSBmdW5jdGlvbiBfZW1wdHlGdW5jKCkge1xuICByZXR1cm4gMDtcbn0sXG4gICAgX3N0YXJ0QXRSZXZlcnRDb25maWcgPSB7XG4gIHN1cHByZXNzRXZlbnRzOiB0cnVlLFxuICBpc1N0YXJ0OiB0cnVlLFxuICBraWxsOiBmYWxzZVxufSxcbiAgICBfcmV2ZXJ0Q29uZmlnTm9LaWxsID0ge1xuICBzdXBwcmVzc0V2ZW50czogdHJ1ZSxcbiAga2lsbDogZmFsc2Vcbn0sXG4gICAgX3JldmVydENvbmZpZyA9IHtcbiAgc3VwcHJlc3NFdmVudHM6IHRydWVcbn0sXG4gICAgX3Jlc2VydmVkUHJvcHMgPSB7fSxcbiAgICBfbGF6eVR3ZWVucyA9IFtdLFxuICAgIF9sYXp5TG9va3VwID0ge30sXG4gICAgX2xhc3RSZW5kZXJlZEZyYW1lLFxuICAgIF9wbHVnaW5zID0ge30sXG4gICAgX2VmZmVjdHMgPSB7fSxcbiAgICBfbmV4dEdDRnJhbWUgPSAzMCxcbiAgICBfaGFybmVzc1BsdWdpbnMgPSBbXSxcbiAgICBfY2FsbGJhY2tOYW1lcyA9IFwiXCIsXG4gICAgX2hhcm5lc3MgPSBmdW5jdGlvbiBfaGFybmVzcyh0YXJnZXRzKSB7XG4gIHZhciB0YXJnZXQgPSB0YXJnZXRzWzBdLFxuICAgICAgaGFybmVzc1BsdWdpbixcbiAgICAgIGk7XG4gIF9pc09iamVjdCh0YXJnZXQpIHx8IF9pc0Z1bmN0aW9uKHRhcmdldCkgfHwgKHRhcmdldHMgPSBbdGFyZ2V0c10pO1xuXG4gIGlmICghKGhhcm5lc3NQbHVnaW4gPSAodGFyZ2V0Ll9nc2FwIHx8IHt9KS5oYXJuZXNzKSkge1xuICAgIC8vIGZpbmQgdGhlIGZpcnN0IHRhcmdldCB3aXRoIGEgaGFybmVzcy4gV2UgYXNzdW1lIHRhcmdldHMgcGFzc2VkIGludG8gYW4gYW5pbWF0aW9uIHdpbGwgYmUgb2Ygc2ltaWxhciB0eXBlLCBtZWFuaW5nIHRoZSBzYW1lIGtpbmQgb2YgaGFybmVzcyBjYW4gYmUgdXNlZCBmb3IgdGhlbSBhbGwgKHBlcmZvcm1hbmNlIG9wdGltaXphdGlvbilcbiAgICBpID0gX2hhcm5lc3NQbHVnaW5zLmxlbmd0aDtcblxuICAgIHdoaWxlIChpLS0gJiYgIV9oYXJuZXNzUGx1Z2luc1tpXS50YXJnZXRUZXN0KHRhcmdldCkpIHt9XG5cbiAgICBoYXJuZXNzUGx1Z2luID0gX2hhcm5lc3NQbHVnaW5zW2ldO1xuICB9XG5cbiAgaSA9IHRhcmdldHMubGVuZ3RoO1xuXG4gIHdoaWxlIChpLS0pIHtcbiAgICB0YXJnZXRzW2ldICYmICh0YXJnZXRzW2ldLl9nc2FwIHx8ICh0YXJnZXRzW2ldLl9nc2FwID0gbmV3IEdTQ2FjaGUodGFyZ2V0c1tpXSwgaGFybmVzc1BsdWdpbikpKSB8fCB0YXJnZXRzLnNwbGljZShpLCAxKTtcbiAgfVxuXG4gIHJldHVybiB0YXJnZXRzO1xufSxcbiAgICBfZ2V0Q2FjaGUgPSBmdW5jdGlvbiBfZ2V0Q2FjaGUodGFyZ2V0KSB7XG4gIHJldHVybiB0YXJnZXQuX2dzYXAgfHwgX2hhcm5lc3ModG9BcnJheSh0YXJnZXQpKVswXS5fZ3NhcDtcbn0sXG4gICAgX2dldFByb3BlcnR5ID0gZnVuY3Rpb24gX2dldFByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIHYpIHtcbiAgcmV0dXJuICh2ID0gdGFyZ2V0W3Byb3BlcnR5XSkgJiYgX2lzRnVuY3Rpb24odikgPyB0YXJnZXRbcHJvcGVydHldKCkgOiBfaXNVbmRlZmluZWQodikgJiYgdGFyZ2V0LmdldEF0dHJpYnV0ZSAmJiB0YXJnZXQuZ2V0QXR0cmlidXRlKHByb3BlcnR5KSB8fCB2O1xufSxcbiAgICBfZm9yRWFjaE5hbWUgPSBmdW5jdGlvbiBfZm9yRWFjaE5hbWUobmFtZXMsIGZ1bmMpIHtcbiAgcmV0dXJuIChuYW1lcyA9IG5hbWVzLnNwbGl0KFwiLFwiKSkuZm9yRWFjaChmdW5jKSB8fCBuYW1lcztcbn0sXG4gICAgLy9zcGxpdCBhIGNvbW1hLWRlbGltaXRlZCBsaXN0IG9mIG5hbWVzIGludG8gYW4gYXJyYXksIHRoZW4gcnVuIGEgZm9yRWFjaCgpIGZ1bmN0aW9uIGFuZCByZXR1cm4gdGhlIHNwbGl0IGFycmF5ICh0aGlzIGlzIGp1c3QgYSB3YXkgdG8gY29uc29saWRhdGUvc2hvcnRlbiBzb21lIGNvZGUpLlxuX3JvdW5kID0gZnVuY3Rpb24gX3JvdW5kKHZhbHVlKSB7XG4gIHJldHVybiBNYXRoLnJvdW5kKHZhbHVlICogMTAwMDAwKSAvIDEwMDAwMCB8fCAwO1xufSxcbiAgICBfcm91bmRQcmVjaXNlID0gZnVuY3Rpb24gX3JvdW5kUHJlY2lzZSh2YWx1ZSkge1xuICByZXR1cm4gTWF0aC5yb3VuZCh2YWx1ZSAqIDEwMDAwMDAwKSAvIDEwMDAwMDAwIHx8IDA7XG59LFxuICAgIC8vIGluY3JlYXNlZCBwcmVjaXNpb24gbW9zdGx5IGZvciB0aW1pbmcgdmFsdWVzLlxuX3BhcnNlUmVsYXRpdmUgPSBmdW5jdGlvbiBfcGFyc2VSZWxhdGl2ZShzdGFydCwgdmFsdWUpIHtcbiAgdmFyIG9wZXJhdG9yID0gdmFsdWUuY2hhckF0KDApLFxuICAgICAgZW5kID0gcGFyc2VGbG9hdCh2YWx1ZS5zdWJzdHIoMikpO1xuICBzdGFydCA9IHBhcnNlRmxvYXQoc3RhcnQpO1xuICByZXR1cm4gb3BlcmF0b3IgPT09IFwiK1wiID8gc3RhcnQgKyBlbmQgOiBvcGVyYXRvciA9PT0gXCItXCIgPyBzdGFydCAtIGVuZCA6IG9wZXJhdG9yID09PSBcIipcIiA/IHN0YXJ0ICogZW5kIDogc3RhcnQgLyBlbmQ7XG59LFxuICAgIF9hcnJheUNvbnRhaW5zQW55ID0gZnVuY3Rpb24gX2FycmF5Q29udGFpbnNBbnkodG9TZWFyY2gsIHRvRmluZCkge1xuICAvL3NlYXJjaGVzIG9uZSBhcnJheSB0byBmaW5kIG1hdGNoZXMgZm9yIGFueSBvZiB0aGUgaXRlbXMgaW4gdGhlIHRvRmluZCBhcnJheS4gQXMgc29vbiBhcyBvbmUgaXMgZm91bmQsIGl0IHJldHVybnMgdHJ1ZS4gSXQgZG9lcyBOT1QgcmV0dXJuIGFsbCB0aGUgbWF0Y2hlczsgaXQncyBzaW1wbHkgYSBib29sZWFuIHNlYXJjaC5cbiAgdmFyIGwgPSB0b0ZpbmQubGVuZ3RoLFxuICAgICAgaSA9IDA7XG5cbiAgZm9yICg7IHRvU2VhcmNoLmluZGV4T2YodG9GaW5kW2ldKSA8IDAgJiYgKytpIDwgbDspIHt9XG5cbiAgcmV0dXJuIGkgPCBsO1xufSxcbiAgICBfbGF6eVJlbmRlciA9IGZ1bmN0aW9uIF9sYXp5UmVuZGVyKCkge1xuICB2YXIgbCA9IF9sYXp5VHdlZW5zLmxlbmd0aCxcbiAgICAgIGEgPSBfbGF6eVR3ZWVucy5zbGljZSgwKSxcbiAgICAgIGksXG4gICAgICB0d2VlbjtcblxuICBfbGF6eUxvb2t1cCA9IHt9O1xuICBfbGF6eVR3ZWVucy5sZW5ndGggPSAwO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICB0d2VlbiA9IGFbaV07XG4gICAgdHdlZW4gJiYgdHdlZW4uX2xhenkgJiYgKHR3ZWVuLnJlbmRlcih0d2Vlbi5fbGF6eVswXSwgdHdlZW4uX2xhenlbMV0sIHRydWUpLl9sYXp5ID0gMCk7XG4gIH1cbn0sXG4gICAgX2xhenlTYWZlUmVuZGVyID0gZnVuY3Rpb24gX2xhenlTYWZlUmVuZGVyKGFuaW1hdGlvbiwgdGltZSwgc3VwcHJlc3NFdmVudHMsIGZvcmNlKSB7XG4gIF9sYXp5VHdlZW5zLmxlbmd0aCAmJiAhX3JldmVydGluZyAmJiBfbGF6eVJlbmRlcigpO1xuICBhbmltYXRpb24ucmVuZGVyKHRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSB8fCBfcmV2ZXJ0aW5nICYmIHRpbWUgPCAwICYmIChhbmltYXRpb24uX2luaXR0ZWQgfHwgYW5pbWF0aW9uLl9zdGFydEF0KSk7XG4gIF9sYXp5VHdlZW5zLmxlbmd0aCAmJiAhX3JldmVydGluZyAmJiBfbGF6eVJlbmRlcigpOyAvL2luIGNhc2UgcmVuZGVyaW5nIGNhdXNlZCBhbnkgdHdlZW5zIHRvIGxhenktaW5pdCwgd2Ugc2hvdWxkIHJlbmRlciB0aGVtIGJlY2F1c2UgdHlwaWNhbGx5IHdoZW4gc29tZW9uZSBjYWxscyBzZWVrKCkgb3IgdGltZSgpIG9yIHByb2dyZXNzKCksIHRoZXkgZXhwZWN0IGFuIGltbWVkaWF0ZSByZW5kZXIuXG59LFxuICAgIF9udW1lcmljSWZQb3NzaWJsZSA9IGZ1bmN0aW9uIF9udW1lcmljSWZQb3NzaWJsZSh2YWx1ZSkge1xuICB2YXIgbiA9IHBhcnNlRmxvYXQodmFsdWUpO1xuICByZXR1cm4gKG4gfHwgbiA9PT0gMCkgJiYgKHZhbHVlICsgXCJcIikubWF0Y2goX2RlbGltaXRlZFZhbHVlRXhwKS5sZW5ndGggPCAyID8gbiA6IF9pc1N0cmluZyh2YWx1ZSkgPyB2YWx1ZS
150cmltKCkgOiB2YWx1ZTtcbn0sXG4gICAgX3Bhc3NUaHJvdWdoID0gZnVuY3Rpb24gX3Bhc3NUaHJvdWdoKHApIHtcbiAgcmV0dXJuIHA7XG59LFxuICAgIF9zZXREZWZhdWx0cyA9IGZ1bmN0aW9uIF9zZXREZWZhdWx0cyhvYmosIGRlZmF1bHRzKSB7XG4gIGZvciAodmFyIHAgaW4gZGVmYXVsdHMpIHtcbiAgICBwIGluIG9iaiB8fCAob2JqW3BdID0gZGVmYXVsdHNbcF0pO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn0sXG4gICAgX3NldEtleWZyYW1lRGVmYXVsdHMgPSBmdW5jdGlvbiBfc2V0S2V5ZnJhbWVEZWZhdWx0cyhleGNsdWRlRHVyYXRpb24pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvYmosIGRlZmF1bHRzKSB7XG4gICAgZm9yICh2YXIgcCBpbiBkZWZhdWx0cykge1xuICAgICAgcCBpbiBvYmogfHwgcCA9PT0gXCJkdXJhdGlvblwiICYmIGV4Y2x1ZGVEdXJhdGlvbiB8fCBwID09PSBcImVhc2VcIiB8fCAob2JqW3BdID0gZGVmYXVsdHNbcF0pO1xuICAgIH1cbiAgfTtcbn0sXG4gICAgX21lcmdlID0gZnVuY3Rpb24gX21lcmdlKGJhc2UsIHRvTWVyZ2UpIHtcbiAgZm9yICh2YXIgcCBpbiB0b01lcmdlKSB7XG4gICAgYmFzZVtwXSA9IHRvTWVyZ2VbcF07XG4gIH1cblxuICByZXR1cm4gYmFzZTtcbn0sXG4gICAgX21lcmdlRGVlcCA9IGZ1bmN0aW9uIF9tZXJnZURlZXAoYmFzZSwgdG9NZXJnZSkge1xuICBmb3IgKHZhciBwIGluIHRvTWVyZ2UpIHtcbiAgICBwICE9PSBcIl9fcHJvdG9fX1wiICYmIHAgIT09IFwiY29uc3RydWN0b3JcIiAmJiBwICE9PSBcInByb3RvdHlwZVwiICYmIChiYXNlW3BdID0gX2lzT2JqZWN0KHRvTWVyZ2VbcF0pID8gX21lcmdlRGVlcChiYXNlW3BdIHx8IChiYXNlW3BdID0ge30pLCB0b01lcmdlW3BdKSA6IHRvTWVyZ2VbcF0pO1xuICB9XG5cbiAgcmV0dXJuIGJhc2U7XG59LFxuICAgIF9jb3B5RXhjbHVkaW5nID0gZnVuY3Rpb24gX2NvcHlFeGNsdWRpbmcob2JqLCBleGNsdWRpbmcpIHtcbiAgdmFyIGNvcHkgPSB7fSxcbiAgICAgIHA7XG5cbiAgZm9yIChwIGluIG9iaikge1xuICAgIHAgaW4gZXhjbHVkaW5nIHx8IChjb3B5W3BdID0gb2JqW3BdKTtcbiAgfVxuXG4gIHJldHVybiBjb3B5O1xufSxcbiAgICBfaW5oZXJpdERlZmF1bHRzID0gZnVuY3Rpb24gX2luaGVyaXREZWZhdWx0cyh2YXJzKSB7XG4gIHZhciBwYXJlbnQgPSB2YXJzLnBhcmVudCB8fCBfZ2xvYmFsVGltZWxpbmUsXG4gICAgICBmdW5jID0gdmFycy5rZXlmcmFtZXMgPyBfc2V0S2V5ZnJhbWVEZWZhdWx0cyhfaXNBcnJheSh2YXJzLmtleWZyYW1lcykpIDogX3NldERlZmF1bHRzO1xuXG4gIGlmIChfaXNOb3RGYWxzZSh2YXJzLmluaGVyaXQpKSB7XG4gICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgZnVuYyh2YXJzLCBwYXJlbnQudmFycy5kZWZhdWx0cyk7XG4gICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50IHx8IHBhcmVudC5fZHA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhcnM7XG59LFxuICAgIF9hcnJheXNNYXRjaCA9IGZ1bmN0aW9uIF9hcnJheXNNYXRjaChhMSwgYTIpIHtcbiAgdmFyIGkgPSBhMS5sZW5ndGgsXG4gICAgICBtYXRjaCA9IGkgPT09IGEyLmxlbmd0aDtcblxuICB3aGlsZSAobWF0Y2ggJiYgaS0tICYmIGExW2ldID09PSBhMltpXSkge31cblxuICByZXR1cm4gaSA8IDA7XG59LFxuICAgIF9hZGRMaW5rZWRMaXN0SXRlbSA9IGZ1bmN0aW9uIF9hZGRMaW5rZWRMaXN0SXRlbShwYXJlbnQsIGNoaWxkLCBmaXJzdFByb3AsIGxhc3RQcm9wLCBzb3J0QnkpIHtcbiAgaWYgKGZpcnN0UHJvcCA9PT0gdm9pZCAwKSB7XG4gICAgZmlyc3RQcm9wID0gXCJfZmlyc3RcIjtcbiAgfVxuXG4gIGlmIChsYXN0UHJvcCA9PT0gdm9pZCAwKSB7XG4gICAgbGFzdFByb3AgPSBcIl9sYXN0XCI7XG4gIH1cblxuICB2YXIgcHJldiA9IHBhcmVudFtsYXN0UHJvcF0sXG4gICAgICB0O1xuXG4gIGlmIChzb3J0QnkpIHtcbiAgICB0ID0gY2hpbGRbc29ydEJ5XTtcblxuICAgIHdoaWxlIChwcmV2ICYmIHByZXZbc29ydEJ5XSA+IHQpIHtcbiAgICAgIHByZXYgPSBwcmV2Ll9wcmV2O1xuICAgIH1cbiAgfVxuXG4gIGlmIChwcmV2KSB7XG4gICAgY2hpbGQuX25leHQgPSBwcmV2Ll9uZXh0O1xuICAgIHByZXYuX25leHQgPSBjaGlsZDtcbiAgfSBlbHNlIHtcbiAgICBjaGlsZC5fbmV4dCA9IHBhcmVudFtmaXJzdFByb3BdO1xuICAgIHBhcmVudFtmaXJzdFByb3BdID0gY2hpbGQ7XG4gIH1cblxuICBpZiAoY2hpbGQuX25leHQpIHtcbiAgICBjaGlsZC5fbmV4dC5fcHJldiA9IGNoaWxkO1xuICB9IGVsc2Uge1xuICAgIHBhcmVudFtsYXN0UHJvcF0gPSBjaGlsZDtcbiAgfVxuXG4gIGNoaWxkLl9wcmV2ID0gcHJldjtcbiAgY2hpbGQucGFyZW50ID0gY2hpbGQuX2RwID0gcGFyZW50O1xuICByZXR1cm4gY2hpbGQ7XG59LFxuICAgIF9yZW1vdmVMaW5rZWRMaXN0SXRlbSA9IGZ1bmN0aW9uIF9yZW1vdmVMaW5rZWRMaXN0SXRlbShwYXJlbnQsIGNoaWxkLCBmaXJzdFByb3AsIGxhc3RQcm9wKSB7XG4gIGlmIChmaXJzdFByb3AgPT09IHZvaWQgMCkge1xuICAgIGZpcnN0UHJvcCA9IFwiX2ZpcnN0XCI7XG4gIH1cblxuICBpZiAobGFzdFByb3AgPT09IHZvaWQgMCkge1xuICAgIGxhc3RQcm9wID0gXCJfbGFzdFwiO1xuICB9XG5cbiAgdmFyIHByZXYgPSBjaGlsZC5fcHJldixcbiAgICAgIG5leHQgPSBjaGlsZC5fbmV4dDtcblxuICBpZiAocHJldikge1xuICAgIHByZXYuX25leHQgPSBuZXh0O1xuICB9IGVsc2UgaWYgKHBhcmVudFtmaXJzdFByb3BdID09PSBjaGlsZCkge1xuICAgIHBhcmVudFtmaXJzdFByb3BdID0gbmV4dDtcbiAgfVxuXG4gIGlmIChuZXh0KSB7XG4gICAgbmV4dC5fcHJldiA9IHByZXY7XG4gIH0gZWxzZSBpZiAocGFyZW50W2xhc3RQcm9wXSA9PT0gY2hpbGQpIHtcbiAgICBwYXJlbnRbbGFzdFByb3BdID0gcHJldjtcbiAgfVxuXG4gIGNoaWxkLl9uZXh0ID0gY2hpbGQuX3ByZXYgPSBjaGlsZC5wYXJlbnQgPSBudWxsOyAvLyBkb24ndCBkZWxldGUgdGhlIF9kcCBqdXN0IHNvIHdlIGNhbiByZXZlcnQgaWYgbmVjZXNzYXJ5LiBCdXQgcGFyZW50IHNob3VsZCBiZSBudWxsIHRvIGluZGljYXRlIHRoZSBpdGVtIGlzbid0IGluIGEgbGlua2VkIGxpc3QuXG59LFxuICAgIF9yZW1vdmVGcm9tUGFyZW50ID0gZnVuY3Rpb24gX3JlbW92ZUZyb21QYXJlbnQoY2hpbGQsIG9ubHlJZlBhcmVudEhhc0F1dG9SZW1vdmUpIHtcbiAgY2hpbGQucGFyZW50ICYmICghb25seUlmUGFyZW50SGFzQXV0b1JlbW92ZSB8fCBjaGlsZC5wYXJlbnQuYXV0b1JlbW92ZUNoaWxkcmVuKSAmJiBjaGlsZC5wYXJlbnQucmVtb3ZlICYmIGNoaWxkLnBhcmVudC5yZW1vdmUoY2hpbGQpO1xuICBjaGlsZC5fYWN0ID0gMDtcbn0sXG4gICAgX3VuY2FjaGUgPSBmdW5jdGlvbiBfdW5jYWNoZShhbmltYXRpb24sIGNoaWxkKSB7XG4gIGlmIChhbmltYXRpb24gJiYgKCFjaGlsZCB8fCBjaGlsZC5fZW5kID4gYW5pbWF0aW9uLl9kdXIgfHwgY2hpbGQuX3N0YXJ0IDwgMCkpIHtcbiAgICAvLyBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb246IGlmIGEgY2hpbGQgYW5pbWF0aW9uIGlzIHBhc3NlZCBpbiB3ZSBzaG91bGQgb25seSB1bmNhY2hlIGlmIHRoYXQgY2hpbGQgRVhURU5EUyB0aGUgYW5pbWF0aW9uIChpdHMgZW5kIHRpbWUgaXMgYmV5b25kIHRoZSBlbmQpXG4gICAgdmFyIGEgPSBhbmltYXRpb247XG5cbiAgICB3aGlsZSAoYSkge1xuICAgICAgYS5fZGlydHkgPSAxO1xuICAgICAgYSA9IGEucGFyZW50O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybi
1BhbmltYXRpb247XG59LFxuICAgIF9yZWNhY2hlQW5jZXN0b3JzID0gZnVuY3Rpb24gX3JlY2FjaGVBbmNlc3RvcnMoYW5pbWF0aW9uKSB7XG4gIHZhciBwYXJlbnQgPSBhbmltYXRpb24ucGFyZW50O1xuXG4gIHdoaWxlIChwYXJlbnQgJiYgcGFyZW50LnBhcmVudCkge1xuICAgIC8vc29tZXRpbWVzIHdlIG11c3QgZm9yY2UgYSByZS1zb3J0IG9mIGFsbCBjaGlsZHJlbiBhbmQgdXBkYXRlIHRoZSBkdXJhdGlvbi90b3RhbER1cmF0aW9uIG9mIGFsbCBhbmNlc3RvciB0aW1lbGluZXMgaW1tZWRpYXRlbHkgaW4gY2FzZSwgZm9yIGV4YW1wbGUsIGluIHRoZSBtaWRkbGUgb2YgYSByZW5kZXIgbG9vcCwgb25lIHR3ZWVuIGFsdGVycyBhbm90aGVyIHR3ZWVuJ3MgdGltZVNjYWxlIHdoaWNoIHNob3ZlcyBpdHMgc3RhcnRUaW1lIGJlZm9yZSAwLCBmb3JjaW5nIHRoZSBwYXJlbnQgdGltZWxpbmUgdG8gc2hpZnQgYXJvdW5kIGFuZCBzaGlmdENoaWxkcmVuKCkgd2hpY2ggY291bGQgYWZmZWN0IHRoYXQgbmV4dCB0d2VlbidzIHJlbmRlciAoc3RhcnRUaW1lKS4gRG9lc24ndCBtYXR0ZXIgZm9yIHRoZSByb290IHRpbWVsaW5lIHRob3VnaC5cbiAgICBwYXJlbnQuX2RpcnR5ID0gMTtcbiAgICBwYXJlbnQudG90YWxEdXJhdGlvbigpO1xuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7XG4gIH1cblxuICByZXR1cm4gYW5pbWF0aW9uO1xufSxcbiAgICBfcmV3aW5kU3RhcnRBdCA9IGZ1bmN0aW9uIF9yZXdpbmRTdGFydEF0KHR3ZWVuLCB0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSkge1xuICByZXR1cm4gdHdlZW4uX3N0YXJ0QXQgJiYgKF9yZXZlcnRpbmcgPyB0d2Vlbi5fc3RhcnRBdC5yZXZlcnQoX3JldmVydENvbmZpZ05vS2lsbCkgOiB0d2Vlbi52YXJzLmltbWVkaWF0ZVJlbmRlciAmJiAhdHdlZW4udmFycy5hdXRvUmV2ZXJ0IHx8IHR3ZWVuLl9zdGFydEF0LnJlbmRlcih0b3RhbFRpbWUsIHRydWUsIGZvcmNlKSk7XG59LFxuICAgIF9oYXNOb1BhdXNlZEFuY2VzdG9ycyA9IGZ1bmN0aW9uIF9oYXNOb1BhdXNlZEFuY2VzdG9ycyhhbmltYXRpb24pIHtcbiAgcmV0dXJuICFhbmltYXRpb24gfHwgYW5pbWF0aW9uLl90cyAmJiBfaGFzTm9QYXVzZWRBbmNlc3RvcnMoYW5pbWF0aW9uLnBhcmVudCk7XG59LFxuICAgIF9lbGFwc2VkQ3ljbGVEdXJhdGlvbiA9IGZ1bmN0aW9uIF9lbGFwc2VkQ3ljbGVEdXJhdGlvbihhbmltYXRpb24pIHtcbiAgcmV0dXJuIGFuaW1hdGlvbi5fcmVwZWF0ID8gX2FuaW1hdGlvbkN5Y2xlKGFuaW1hdGlvbi5fdFRpbWUsIGFuaW1hdGlvbiA9IGFuaW1hdGlvbi5kdXJhdGlvbigpICsgYW5pbWF0aW9uLl9yRGVsYXkpICogYW5pbWF0aW9uIDogMDtcbn0sXG4gICAgLy8gZmVlZCBpbiB0aGUgdG90YWxUaW1lIGFuZCBjeWNsZUR1cmF0aW9uIGFuZCBpdCdsbCByZXR1cm4gdGhlIGN5Y2xlIChpdGVyYXRpb24gbWludXMgMSkgYW5kIGlmIHRoZSBwbGF5aGVhZCBpcyBleGFjdGx5IGF0IHRoZSB2ZXJ5IEVORCwgaXQgd2lsbCBOT1QgYnVtcCB1cCB0byB0aGUgbmV4dCBjeWNsZS5cbl9hbmltYXRpb25DeWNsZSA9IGZ1bmN0aW9uIF9hbmltYXRpb25DeWNsZSh0VGltZSwgY3ljbGVEdXJhdGlvbikge1xuICB2YXIgd2hvbGUgPSBNYXRoLmZsb29yKHRUaW1lIC89IGN5Y2xlRHVyYXRpb24pO1xuICByZXR1cm4gdFRpbWUgJiYgd2hvbGUgPT09IHRUaW1lID8gd2hvbGUgLSAxIDogd2hvbGU7XG59LFxuICAgIF9wYXJlbnRUb0NoaWxkVG90YWxUaW1lID0gZnVuY3Rpb24gX3BhcmVudFRvQ2hpbGRUb3RhbFRpbWUocGFyZW50VGltZSwgY2hpbGQpIHtcbiAgcmV0dXJuIChwYXJlbnRUaW1lIC0gY2hpbGQuX3N0YXJ0KSAqIGNoaWxkLl90cyArIChjaGlsZC5fdHMgPj0gMCA/IDAgOiBjaGlsZC5fZGlydHkgPyBjaGlsZC50b3RhbER1cmF0aW9uKCkgOiBjaGlsZC5fdER1cik7XG59LFxuICAgIF9zZXRFbmQgPSBmdW5jdGlvbiBfc2V0RW5kKGFuaW1hdGlvbikge1xuICByZXR1cm4gYW5pbWF0aW9uLl9lbmQgPSBfcm91bmRQcmVjaXNlKGFuaW1hdGlvbi5fc3RhcnQgKyAoYW5pbWF0aW9uLl90RHVyIC8gTWF0aC5hYnMoYW5pbWF0aW9uLl90cyB8fCBhbmltYXRpb24uX3J0cyB8fCBfdGlueU51bSkgfHwgMCkpO1xufSxcbiAgICBfYWxpZ25QbGF5aGVhZCA9IGZ1bmN0aW9uIF9hbGlnblBsYXloZWFkKGFuaW1hdGlvbiwgdG90YWxUaW1lKSB7XG4gIC8vIGFkanVzdHMgdGhlIGFuaW1hdGlvbidzIF9zdGFydCBhbmQgX2VuZCBhY2NvcmRpbmcgdG8gdGhlIHByb3ZpZGVkIHRvdGFsVGltZSAob25seSBpZiB0aGUgcGFyZW50J3Mgc21vb3RoQ2hpbGRUaW1pbmcgaXMgdHJ1ZSBhbmQgdGhlIGFuaW1hdGlvbiBpc24ndCBwYXVzZWQpLiBJdCBkb2Vzbid0IGRvIGFueSByZW5kZXJpbmcgb3IgZm9yY2luZyB0aGluZ3MgYmFjayBpbnRvIHBhcmVudCB0aW1lbGluZXMsIGV0Yy4gLSB0aGF0J3Mgd2hhdCB0b3RhbFRpbWUoKSBpcyBmb3IuXG4gIHZhciBwYXJlbnQgPSBhbmltYXRpb24uX2RwO1xuXG4gIGlmIChwYXJlbnQgJiYgcGFyZW50LnNtb290aENoaWxkVGltaW5nICYmIGFuaW1hdGlvbi5fdHMpIHtcbiAgICBhbmltYXRpb24uX3N0YXJ0ID0gX3JvdW5kUHJlY2lzZShwYXJlbnQuX3RpbWUgLSAoYW5pbWF0aW9uLl90cyA+IDAgPyB0b3RhbFRpbWUgLyBhbmltYXRpb24uX3RzIDogKChhbmltYXRpb24uX2RpcnR5ID8gYW5pbWF0aW9uLnRvdGFsRHVyYXRpb24oKSA6IGFuaW1hdGlvbi5fdER1cikgLSB0b3RhbFRpbWUpIC8gLWFuaW1hdGlvbi5fdHMpKTtcblxuICAgIF9zZXRFbmQoYW5pbWF0aW9uKTtcblxuICAgIHBhcmVudC5fZGlydHkgfHwgX3VuY2FjaGUocGFyZW50LCBhbmltYXRpb24pOyAvL2ZvciBwZXJmb3JtYW5jZSBpbXByb3ZlbWVudC4gSWYgdGhlIHBhcmVudCdzIGNhY2hlIGlzIGFscmVhZHkgZGlydHksIGl0IGFscmVhZHkgdG9vayBjYXJlIG9mIG1hcmtpbmcgdGhlIGFuY2VzdG9ycyBhcyBkaXJ0eSB0b28sIHNvIHNraXAgdGhlIGZ1bmN0aW9uIGNhbGwgaGVyZS5cbiAgfVxuXG4gIHJldHVybiBhbmltYXRpb247XG59LFxuXG4vKlxuX3RvdGFsVGltZVRvVGltZSA9IChjbGFtcGVkVG90YWxUaW1lLCBkdXJhdGlvbiwgcmVwZWF0LCByZXBlYXREZWxheSwgeW95bykgPT4ge1xuXHRsZXQgY3ljbGVEdXJhdGlvbiA9IGR1cmF0aW9uICsgcmVwZWF0RGVsYXksXG5cdFx0dGltZSA9IF9yb3VuZChjbGFtcGVkVG90YWxUaW1lICUgY3ljbGVEdXJhdGlvbik7XG5cdGlmICh0aW1lID4gZHVyYXRpb24pIHtcblx0XHR0aW1lID0gZHVyYXRpb247XG5cdH1cblx0cmV0dXJuICh5b3lvICYmICh+fihjbGFtcGVkVG90YWxUaW1lIC8gY3ljbGVEdXJhdGlvbikgJiAxKSkgPyBkdXJhdGlvbiAtIHRpbWUgOiB0aW1lO1xufSxcbiovXG5fcG9zdEFkZENoZWNrcyA9IGZ1bmN0aW9uIF9wb3N0QWRkQ2hlY2tzKHRpbWVsaW5lLCBjaGlsZCkge1xuICB2YXIgdDtcblxuICBpZiAoY2hpbGQuX3RpbWUgfHwgIWNoaWxkLl9kdXIgJiYgY2hpbGQuX2luaXR0ZWQgfHwgY2hpbGQuX3N0YXJ0IDwgdGltZWxpbmUuX3RpbWUgJiYgKGNo
1aWxkLl9kdXIgfHwgIWNoaWxkLmFkZCkpIHtcbiAgICAvLyBpbiBjYXNlLCBmb3IgZXhhbXBsZSwgdGhlIF9zdGFydCBpcyBtb3ZlZCBvbiBhIHR3ZWVuIHRoYXQgaGFzIGFscmVhZHkgcmVuZGVyZWQsIG9yIGlmIGl0J3MgYmVpbmcgaW5zZXJ0ZWQgaW50byBhIHRpbWVsaW5lIEJFRk9SRSB3aGVyZSB0aGUgcGxheWhlYWQgaXMgY3VycmVudGx5LiBJbWFnaW5lIGl0J3MgYXQgaXRzIGVuZCBzdGF0ZSwgdGhlbiB0aGUgc3RhcnRUaW1lIGlzIG1vdmVkIFdBWSBsYXRlciAoYWZ0ZXIgdGhlIGVuZCBvZiB0aGlzIHRpbWVsaW5lKSwgaXQgc2hvdWxkIHJlbmRlciBhdCBpdHMgYmVnaW5uaW5nLiBTcGVjaWFsIGNhc2U6IGlmIGl0J3MgYSB0aW1lbGluZSAoaGFzIC5hZGQoKSBtZXRob2QpIGFuZCBubyBkdXJhdGlvbiwgd2UgY2FuIHNraXAgcmVuZGVyaW5nIGJlY2F1c2UgdGhlIHVzZXIgbWF5IGJlIHBvcHVsYXRpbmcgaXQgQUZURVIgYWRkaW5nIGl0IHRvIGEgcGFyZW50IHRpbWVsaW5lICh1bmNvbnZlbnRpb25hbCwgYnV0IHBvc3NpYmxlLCBhbmQgd2Ugd291bGRuJ3Qgd2FudCBpdCB0byBnZXQgcmVtb3ZlZCBpZiB0aGUgcGFyZW50J3MgYXV0b1JlbW92ZUNoaWxkcmVuIGlzIHRydWUpLlxuICAgIHQgPSBfcGFyZW50VG9DaGlsZFRvdGFsVGltZSh0aW1lbGluZS5yYXdUaW1lKCksIGNoaWxkKTtcblxuICAgIGlmICghY2hpbGQuX2R1ciB8fCBfY2xhbXAoMCwgY2hpbGQudG90YWxEdXJhdGlvbigpLCB0KSAtIGNoaWxkLl90VGltZSA+IF90aW55TnVtKSB7XG4gICAgICBjaGlsZC5yZW5kZXIodCwgdHJ1ZSk7XG4gICAgfVxuICB9IC8vaWYgdGhlIHRpbWVsaW5lIGhhcyBhbHJlYWR5IGVuZGVkIGJ1dCB0aGUgaW5zZXJ0ZWQgdHdlZW4vdGltZWxpbmUgZXh0ZW5kcyB0aGUgZHVyYXRpb24sIHdlIHNob3VsZCBlbmFibGUgdGhpcyB0aW1lbGluZSBhZ2FpbiBzbyB0aGF0IGl0IHJlbmRlcnMgcHJvcGVybHkuIFdlIHNob3VsZCBhbHNvIGFsaWduIHRoZSBwbGF5aGVhZCB3aXRoIHRoZSBwYXJlbnQgdGltZWxpbmUncyB3aGVuIGFwcHJvcHJpYXRlLlxuXG5cbiAgaWYgKF91bmNhY2hlKHRpbWVsaW5lLCBjaGlsZCkuX2RwICYmIHRpbWVsaW5lLl9pbml0dGVkICYmIHRpbWVsaW5lLl90aW1lID49IHRpbWVsaW5lLl9kdXIgJiYgdGltZWxpbmUuX3RzKSB7XG4gICAgLy9pbiBjYXNlIGFueSBvZiB0aGUgYW5jZXN0b3JzIGhhZCBjb21wbGV0ZWQgYnV0IHNob3VsZCBub3cgYmUgZW5hYmxlZC4uLlxuICAgIGlmICh0aW1lbGluZS5fZHVyIDwgdGltZWxpbmUuZHVyYXRpb24oKSkge1xuICAgICAgdCA9IHRpbWVsaW5lO1xuXG4gICAgICB3aGlsZSAodC5fZHApIHtcbiAgICAgICAgdC5yYXdUaW1lKCkgPj0gMCAmJiB0LnRvdGFsVGltZSh0Ll90VGltZSk7IC8vbW92ZXMgdGhlIHRpbWVsaW5lIChzaGlmdHMgaXRzIHN0YXJ0VGltZSkgaWYgbmVjZXNzYXJ5LCBhbmQgYWxzbyBlbmFibGVzIGl0LiBJZiBpdCdzIGN1cnJlbnRseSB6ZXJvLCB0aG91Z2gsIGl0IG1heSBub3QgYmUgc2NoZWR1bGVkIHRvIHJlbmRlciB1bnRpbCBsYXRlciBzbyB0aGVyZSdzIG5vIG5lZWQgdG8gZm9yY2UgaXQgdG8gYWxpZ24gd2l0aCB0aGUgY3VycmVudCBwbGF5aGVhZCBwb3NpdGlvbi4gT25seSBtb3ZlIHRvIGNhdGNoIHVwIHdpdGggdGhlIHBsYXloZWFkLlxuXG4gICAgICAgIHQgPSB0Ll9kcDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aW1lbGluZS5felRpbWUgPSAtX3RpbnlOdW07IC8vIGhlbHBzIGVuc3VyZSB0aGF0IHRoZSBuZXh0IHJlbmRlcigpIHdpbGwgYmUgZm9yY2VkIChjcm9zc2luZ1N0YXJ0ID0gdHJ1ZSBpbiByZW5kZXIoKSksIGV2ZW4gaWYgdGhlIGR1cmF0aW9uIGhhc24ndCBjaGFuZ2VkICh3ZSdyZSBhZGRpbmcgYSBjaGlsZCB3aGljaCB3b3VsZCBuZWVkIHRvIGdldCByZW5kZXJlZCkuIERlZmluaXRlbHkgYW4gZWRnZSBjYXNlLiBOb3RlOiB3ZSBNVVNUIGRvIHRoaXMgQUZURVIgdGhlIGxvb3AgYWJvdmUgd2hlcmUgdGhlIHRvdGFsVGltZSgpIG1pZ2h0IHRyaWdnZXIgYSByZW5kZXIoKSBiZWNhdXNlIHRoaXMgX2FkZFRvVGltZWxpbmUoKSBtZXRob2QgZ2V0cyBjYWxsZWQgZnJvbSB0aGUgQW5pbWF0aW9uIGNvbnN0cnVjdG9yLCBCRUZPUkUgdHdlZW5zIGV2ZW4gcmVjb3JkIHRoZWlyIHRhcmdldHMsIGV0Yy4gc28gd2Ugd291bGRuJ3Qgd2FudCB0aGluZ3MgdG8gZ2V0IHRyaWdnZXJlZCBpbiB0aGUgd3Jvbmcgb3JkZXIuXG4gIH1cbn0sXG4gICAgX2FkZFRvVGltZWxpbmUgPSBmdW5jdGlvbiBfYWRkVG9UaW1lbGluZSh0aW1lbGluZSwgY2hpbGQsIHBvc2l0aW9uLCBza2lwQ2hlY2tzKSB7XG4gIGNoaWxkLnBhcmVudCAmJiBfcmVtb3ZlRnJvbVBhcmVudChjaGlsZCk7XG4gIGNoaWxkLl9zdGFydCA9IF9yb3VuZFByZWNpc2UoKF9pc051bWJlcihwb3NpdGlvbikgPyBwb3NpdGlvbiA6IHBvc2l0aW9uIHx8IHRpbWVsaW5lICE9PSBfZ2xvYmFsVGltZWxpbmUgPyBfcGFyc2VQb3NpdGlvbih0aW1lbGluZSwgcG9zaXRpb24sIGNoaWxkKSA6IHRpbWVsaW5lLl90aW1lKSArIGNoaWxkLl9kZWxheSk7XG4gIGNoaWxkLl9lbmQgPSBfcm91bmRQcmVjaXNlKGNoaWxkLl9zdGFydCArIChjaGlsZC50b3RhbER1cmF0aW9uKCkgLyBNYXRoLmFicyhjaGlsZC50aW1lU2NhbGUoKSkgfHwgMCkpO1xuXG4gIF9hZGRMaW5rZWRMaXN0SXRlbSh0aW1lbGluZSwgY2hpbGQsIFwiX2ZpcnN0XCIsIFwiX2xhc3RcIiwgdGltZWxpbmUuX3NvcnQgPyBcIl9zdGFydFwiIDogMCk7XG5cbiAgX2lzRnJvbU9yRnJvbVN0YXJ0KGNoaWxkKSB8fCAodGltZWxpbmUuX3JlY2VudCA9IGNoaWxkKTtcbiAgc2tpcENoZWNrcyB8fCBfcG9zdEFkZENoZWNrcyh0aW1lbGluZSwgY2hpbGQpO1xuICB0aW1lbGluZS5fdHMgPCAwICYmIF9hbGlnblBsYXloZWFkKHRpbWVsaW5lLCB0aW1lbGluZS5fdFRpbWUpOyAvLyBpZiB0aGUgdGltZWxpbmUgaXMgcmV2ZXJzZWQgYW5kIHRoZSBuZXcgY2hpbGQgbWFrZXMgaXQgbG9uZ2VyLCB3ZSBtYXkgbmVlZCB0byBhZGp1c3QgdGhlIHBhcmVudCdzIF9zdGFydCAocHVzaCBpdCBiYWNrKVxuXG4gIHJldHVybiB0aW1lbGluZTtcbn0sXG4gICAgX3Njcm9sbFRyaWdnZXIgPSBmdW5jdGlvbiBfc2Nyb2xsVHJpZ2dlcihhbmltYXRpb24sIHRyaWdnZXIpIHtcbiAgcmV0dXJuIChfZ2xvYmFscy5TY3JvbGxUcmlnZ2VyIHx8IF9taXNzaW5nUGx1Z2luKFwic2Nyb2xsVHJpZ2dlclwiLCB0cmlnZ2VyKSkgJiYgX2dsb2JhbHMuU2Nyb2xsVHJpZ2dlci5jcmVhdGUodHJpZ2dlciwgYW5pbWF0aW9uKTtcbn0sXG4gICAgX2F0dGVtcHRJbml0VHdlZW4gPSBmdW5jdGlvbiBfYXR0ZW1wdEluaXRUd2
1Vlbih0d2VlbiwgdGltZSwgZm9yY2UsIHN1cHByZXNzRXZlbnRzLCB0VGltZSkge1xuICBfaW5pdFR3ZWVuKHR3ZWVuLCB0aW1lLCB0VGltZSk7XG5cbiAgaWYgKCF0d2Vlbi5faW5pdHRlZCkge1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgaWYgKCFmb3JjZSAmJiB0d2Vlbi5fcHQgJiYgIV9yZXZlcnRpbmcgJiYgKHR3ZWVuLl9kdXIgJiYgdHdlZW4udmFycy5sYXp5ICE9PSBmYWxzZSB8fCAhdHdlZW4uX2R1ciAmJiB0d2Vlbi52YXJzLmxhenkpICYmIF9sYXN0UmVuZGVyZWRGcmFtZSAhPT0gX3RpY2tlci5mcmFtZSkge1xuICAgIF9sYXp5VHdlZW5zLnB1c2godHdlZW4pO1xuXG4gICAgdHdlZW4uX2xhenkgPSBbdFRpbWUsIHN1cHByZXNzRXZlbnRzXTtcbiAgICByZXR1cm4gMTtcbiAgfVxufSxcbiAgICBfcGFyZW50UGxheWhlYWRJc0JlZm9yZVN0YXJ0ID0gZnVuY3Rpb24gX3BhcmVudFBsYXloZWFkSXNCZWZvcmVTdGFydChfcmVmKSB7XG4gIHZhciBwYXJlbnQgPSBfcmVmLnBhcmVudDtcbiAgcmV0dXJuIHBhcmVudCAmJiBwYXJlbnQuX3RzICYmIHBhcmVudC5faW5pdHRlZCAmJiAhcGFyZW50Ll9sb2NrICYmIChwYXJlbnQucmF3VGltZSgpIDwgMCB8fCBfcGFyZW50UGxheWhlYWRJc0JlZm9yZVN0YXJ0KHBhcmVudCkpO1xufSxcbiAgICAvLyBjaGVjayBwYXJlbnQncyBfbG9jayBiZWNhdXNlIHdoZW4gYSB0aW1lbGluZSByZXBlYXRzL3lveW9zIGFuZCBkb2VzIGl0cyBhcnRpZmljaWFsIHdyYXBwaW5nLCB3ZSBzaG91bGRuJ3QgZm9yY2UgdGhlIHJhdGlvIGJhY2sgdG8gMFxuX2lzRnJvbU9yRnJvbVN0YXJ0ID0gZnVuY3Rpb24gX2lzRnJvbU9yRnJvbVN0YXJ0KF9yZWYyKSB7XG4gIHZhciBkYXRhID0gX3JlZjIuZGF0YTtcbiAgcmV0dXJuIGRhdGEgPT09IFwiaXNGcm9tU3RhcnRcIiB8fCBkYXRhID09PSBcImlzU3RhcnRcIjtcbn0sXG4gICAgX3JlbmRlclplcm9EdXJhdGlvblR3ZWVuID0gZnVuY3Rpb24gX3JlbmRlclplcm9EdXJhdGlvblR3ZWVuKHR3ZWVuLCB0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSkge1xuICB2YXIgcHJldlJhdGlvID0gdHdlZW4ucmF0aW8sXG4gICAgICByYXRpbyA9IHRvdGFsVGltZSA8IDAgfHwgIXRvdGFsVGltZSAmJiAoIXR3ZWVuLl9zdGFydCAmJiBfcGFyZW50UGxheWhlYWRJc0JlZm9yZVN0YXJ0KHR3ZWVuKSAmJiAhKCF0d2Vlbi5faW5pdHRlZCAmJiBfaXNGcm9tT3JGcm9tU3RhcnQodHdlZW4pKSB8fCAodHdlZW4uX3RzIDwgMCB8fCB0d2Vlbi5fZHAuX3RzIDwgMCkgJiYgIV9pc0Zyb21PckZyb21TdGFydCh0d2VlbikpID8gMCA6IDEsXG4gICAgICAvLyBpZiB0aGUgdHdlZW4gb3IgaXRzIHBhcmVudCBpcyByZXZlcnNlZCBhbmQgdGhlIHRvdGFsVGltZSBpcyAwLCB3ZSBzaG91bGQgZ28gdG8gYSByYXRpbyBvZiAwLiBFZGdlIGNhc2U6IGlmIGEgZnJvbSgpIG9yIGZyb21UbygpIHN0YWdnZXIgdHdlZW4gaXMgcGxhY2VkIGxhdGVyIGluIGEgdGltZWxpbmUsIHRoZSBcInN0YXJ0QXRcIiB6ZXJvLWR1cmF0aW9uIHR3ZWVuIGNvdWxkIGluaXRpYWxseSByZW5kZXIgYXQgYSB0aW1lIHdoZW4gdGhlIHBhcmVudCB0aW1lbGluZSdzIHBsYXloZWFkIGlzIHRlY2huaWNhbGx5IEJFRk9SRSB3aGVyZSB0aGlzIHR3ZWVuIGlzLCBzbyBtYWtlIHN1cmUgdGhhdCBhbnkgXCJmcm9tXCIgYW5kIFwiZnJvbVRvXCIgc3RhcnRBdCB0d2VlbnMgYXJlIHJlbmRlcmVkIHRoZSBmaXJzdCB0aW1lIGF0IGEgcmF0aW8gb2YgMS5cbiAgcmVwZWF0RGVsYXkgPSB0d2Vlbi5fckRlbGF5LFxuICAgICAgdFRpbWUgPSAwLFxuICAgICAgcHQsXG4gICAgICBpdGVyYXRpb24sXG4gICAgICBwcmV2SXRlcmF0aW9uO1xuXG4gIGlmIChyZXBlYXREZWxheSAmJiB0d2Vlbi5fcmVwZWF0KSB7XG4gICAgLy8gaW4gY2FzZSB0aGVyZSdzIGEgemVyby1kdXJhdGlvbiB0d2VlbiB0aGF0IGhhcyBhIHJlcGVhdCB3aXRoIGEgcmVwZWF0RGVsYXlcbiAgICB0VGltZSA9IF9jbGFtcCgwLCB0d2Vlbi5fdER1ciwgdG90YWxUaW1lKTtcbiAgICBpdGVyYXRpb24gPSBfYW5pbWF0aW9uQ3ljbGUodFRpbWUsIHJlcGVhdERlbGF5KTtcbiAgICB0d2Vlbi5feW95byAmJiBpdGVyYXRpb24gJiAxICYmIChyYXRpbyA9IDEgLSByYXRpbyk7XG5cbiAgICBpZiAoaXRlcmF0aW9uICE9PSBfYW5pbWF0aW9uQ3ljbGUodHdlZW4uX3RUaW1lLCByZXBlYXREZWxheSkpIHtcbiAgICAgIC8vIGlmIGl0ZXJhdGlvbiBjaGFuZ2VkXG4gICAgICBwcmV2UmF0aW8gPSAxIC0gcmF0aW87XG4gICAgICB0d2Vlbi52YXJzLnJlcGVhdFJlZnJlc2ggJiYgdHdlZW4uX2luaXR0ZWQgJiYgdHdlZW4uaW52YWxpZGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChyYXRpbyAhPT0gcHJldlJhdGlvIHx8IF9yZXZlcnRpbmcgfHwgZm9yY2UgfHwgdHdlZW4uX3pUaW1lID09PSBfdGlueU51bSB8fCAhdG90YWxUaW1lICYmIHR3ZWVuLl96VGltZSkge1xuICAgIGlmICghdHdlZW4uX2luaXR0ZWQgJiYgX2F0dGVtcHRJbml0VHdlZW4odHdlZW4sIHRvdGFsVGltZSwgZm9yY2UsIHN1cHByZXNzRXZlbnRzLCB0VGltZSkpIHtcbiAgICAgIC8vIGlmIHdlIHJlbmRlciB0aGUgdmVyeSBiZWdpbm5pbmcgKHRpbWUgPT0gMCkgb2YgYSBmcm9tVG8oKSwgd2UgbXVzdCBmb3JjZSB0aGUgcmVuZGVyIChub3JtYWwgdHdlZW5zIHdvdWxkbid0IG5lZWQgdG8gcmVuZGVyIGF0IGEgdGltZSBvZiAwIHdoZW4gdGhlIHByZXZUaW1lIHdhcyBhbHNvIDApLiBUaGlzIGlzIGFsc28gbWFuZGF0b3J5IHRvIG1ha2Ugc3VyZSBvdmVyd3JpdGluZyBraWNrcyBpbiBpbW1lZGlhdGVseS5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwcmV2SXRlcmF0aW9uID0gdHdlZW4uX3pUaW1lO1xuICAgIHR3ZWVuLl96VGltZSA9IHRvdGFsVGltZSB8fCAoc3VwcHJlc3NFdmVudHMgPyBfdGlueU51bSA6IDApOyAvLyB3aGVuIHRoZSBwbGF5aGVhZCBhcnJpdmVzIGF0IEVYQUNUTFkgdGltZSAwIChyaWdodCBvbiB0b3ApIG9mIGEgemVyby1kdXJhdGlvbiB0d2Vlbiwgd2UgbmVlZCB0byBkaXNjZXJuIGlmIGV2ZW50cyBhcmUgc3VwcHJlc3NlZCBzbyB0aGF0IHdoZW4gdGhlIHBsYXloZWFkIG1vdmVzIGFnYWluIChuZXh0IHRpbWUpLCBpdCdsbCB0cmlnZ2VyIHR
1oZSBjYWxsYmFjay4gSWYgZXZlbnRzIGFyZSBOT1Qgc3VwcHJlc3NlZCwgb2J2aW91c2x5IHRoZSBjYWxsYmFjayB3b3VsZCBiZSB0cmlnZ2VyZWQgaW4gdGhpcyByZW5kZXIuIEJhc2ljYWxseSwgdGhlIGNhbGxiYWNrIHNob3VsZCBmaXJlIGVpdGhlciB3aGVuIHRoZSBwbGF5aGVhZCBBUlJJVkVTIG9yIExFQVZFUyB0aGlzIGV4YWN0IHNwb3QsIG5vdCBib3RoLiBJbWFnaW5lIGRvaW5nIGEgdGltZWxpbmUuc2VlaygwKSBhbmQgdGhlcmUncyBhIGNhbGxiYWNrIHRoYXQgc2l0cyBhdCAwLiBTaW5jZSBldmVudHMgYXJlIHN1cHByZXNzZWQgb24gdGhhdCBzZWVrKCkgYnkgZGVmYXVsdCwgbm90aGluZyB3aWxsIGZpcmUsIGJ1dCB3aGVuIHRoZSBwbGF5aGVhZCBtb3ZlcyBvZmYgb2YgdGhhdCBwb3NpdGlvbiwgdGhlIGNhbGxiYWNrIHNob3VsZCBmaXJlLiBUaGlzIGJlaGF2aW9yIGlzIHdoYXQgcGVvcGxlIGludHVpdGl2ZWx5IGV4cGVjdC5cblxuICAgIHN1cHByZXNzRXZlbnRzIHx8IChzdXBwcmVzc0V2ZW50cyA9IHRvdGFsVGltZSAmJiAhcHJldkl0ZXJhdGlvbik7IC8vIGlmIGl0IHdhcyByZW5kZXJlZCBwcmV2aW91c2x5IGF0IGV4YWN0bHkgMCAoX3pUaW1lKSBhbmQgbm93IHRoZSBwbGF5aGVhZCBpcyBtb3ZpbmcgYXdheSwgRE9OJ1QgZmlyZSBjYWxsYmFja3Mgb3RoZXJ3aXNlIHRoZXknbGwgc2VlbSBsaWtlIGR1cGxpY2F0ZXMuXG5cbiAgICB0d2Vlbi5yYXRpbyA9IHJhdGlvO1xuICAgIHR3ZWVuLl9mcm9tICYmIChyYXRpbyA9IDEgLSByYXRpbyk7XG4gICAgdHdlZW4uX3RpbWUgPSAwO1xuICAgIHR3ZWVuLl90VGltZSA9IHRUaW1lO1xuICAgIHB0ID0gdHdlZW4uX3B0O1xuXG4gICAgd2hpbGUgKHB0KSB7XG4gICAgICBwdC5yKHJhdGlvLCBwdC5kKTtcbiAgICAgIHB0ID0gcHQuX25leHQ7XG4gICAgfVxuXG4gICAgdG90YWxUaW1lIDwgMCAmJiBfcmV3aW5kU3RhcnRBdCh0d2VlbiwgdG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgdHJ1ZSk7XG4gICAgdHdlZW4uX29uVXBkYXRlICYmICFzdXBwcmVzc0V2ZW50cyAmJiBfY2FsbGJhY2sodHdlZW4sIFwib25VcGRhdGVcIik7XG4gICAgdFRpbWUgJiYgdHdlZW4uX3JlcGVhdCAmJiAhc3VwcHJlc3NFdmVudHMgJiYgdHdlZW4ucGFyZW50ICYmIF9jYWxsYmFjayh0d2VlbiwgXCJvblJlcGVhdFwiKTtcblxuICAgIGlmICgodG90YWxUaW1lID49IHR3ZWVuLl90RHVyIHx8IHRvdGFsVGltZSA8IDApICYmIHR3ZWVuLnJhdGlvID09PSByYXRpbykge1xuICAgICAgcmF0aW8gJiYgX3JlbW92ZUZyb21QYXJlbnQodHdlZW4sIDEpO1xuXG4gICAgICBpZiAoIXN1cHByZXNzRXZlbnRzICYmICFfcmV2ZXJ0aW5nKSB7XG4gICAgICAgIF9jYWxsYmFjayh0d2VlbiwgcmF0aW8gPyBcIm9uQ29tcGxldGVcIiA6IFwib25SZXZlcnNlQ29tcGxldGVcIiwgdHJ1ZSk7XG5cbiAgICAgICAgdHdlZW4uX3Byb20gJiYgdHdlZW4uX3Byb20oKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoIXR3ZWVuLl96VGltZSkge1xuICAgIHR3ZWVuLl96VGltZSA9IHRvdGFsVGltZTtcbiAgfVxufSxcbiAgICBfZmluZE5leHRQYXVzZVR3ZWVuID0gZnVuY3Rpb24gX2ZpbmROZXh0UGF1c2VUd2VlbihhbmltYXRpb24sIHByZXZUaW1lLCB0aW1lKSB7XG4gIHZhciBjaGlsZDtcblxuICBpZiAodGltZSA+IHByZXZUaW1lKSB7XG4gICAgY2hpbGQgPSBhbmltYXRpb24uX2ZpcnN0O1xuXG4gICAgd2hpbGUgKGNoaWxkICYmIGNoaWxkLl9zdGFydCA8PSB0aW1lKSB7XG4gICAgICBpZiAoY2hpbGQuZGF0YSA9PT0gXCJpc1BhdXNlXCIgJiYgY2hpbGQuX3N0YXJ0ID4gcHJldlRpbWUpIHtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgfVxuXG4gICAgICBjaGlsZCA9IGNoaWxkLl9uZXh0O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBjaGlsZCA9IGFuaW1hdGlvbi5fbGFzdDtcblxuICAgIHdoaWxlIChjaGlsZCAmJiBjaGlsZC5fc3RhcnQgPj0gdGltZSkge1xuICAgICAgaWYgKGNoaWxkLmRhdGEgPT09IFwiaXNQYXVzZVwiICYmIGNoaWxkLl9zdGFydCA8IHByZXZUaW1lKSB7XG4gICAgICAgIHJldHVybiBjaGlsZDtcbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBjaGlsZC5fcHJldjtcbiAgICB9XG4gIH1cbn0sXG4gICAgX3NldER1cmF0aW9uID0gZnVuY3Rpb24gX3NldER1cmF0aW9uKGFuaW1hdGlvbiwgZHVyYXRpb24sIHNraXBVbmNhY2hlLCBsZWF2ZVBsYXloZWFkKSB7XG4gIHZhciByZXBlYXQgPSBhbmltYXRpb24uX3JlcGVhdCxcbiAgICAgIGR1ciA9IF9yb3VuZFByZWNpc2UoZHVyYXRpb24pIHx8IDAsXG4gICAgICB0b3RhbFByb2dyZXNzID0gYW5pbWF0aW9uLl90VGltZSAvIGFuaW1hdGlvbi5fdER1cjtcbiAgdG90YWxQcm9ncmVzcyAmJiAhbGVhdmVQbGF5aGVhZCAmJiAoYW5pbWF0aW9uLl90aW1lICo9IGR1ciAvIGFuaW1hdGlvbi5fZHVyKTtcbiAgYW5pbWF0aW9uLl9kdXIgPSBkdXI7XG4gIGFuaW1hdGlvbi5fdER1ciA9ICFyZXBlYXQgPyBkdXIgOiByZXBlYXQgPCAwID8gMWUxMCA6IF9yb3VuZFByZWNpc2UoZHVyICogKHJlcGVhdCArIDEpICsgYW5pbWF0aW9uLl9yRGVsYXkgKiByZXBlYXQpO1xuICB0b3RhbFByb2dyZXNzID4gMCAmJiAhbGVhdmVQbGF5aGVhZCAmJiBfYWxpZ25QbGF5aGVhZChhbmltYXRpb24sIGFuaW1hdGlvbi5fdFRpbWUgPSBhbmltYXRpb24uX3REdXIgKiB0b3RhbFByb2dyZXNzKTtcbiAgYW5pbWF0aW9uLnBhcmVudCAmJiBfc2V0RW5kKGFuaW1hdGlvbik7XG4gIHNraXBVbmNhY2hlIHx8IF91bmNhY2hlKGFuaW1hdGlvbi5wYXJlbnQsIGFuaW1hdGlvbik7XG4gIHJldHVybiBhbmltYXRpb247XG59LFxuICAgIF9vblVwZGF0ZVRvdGFsRHVyYXRpb24gPSBmdW5jdGlvbiBfb25VcGRhdGVUb3RhbER1cmF0aW9uKGFuaW1hdGlvbikge1xuICByZXR1cm4gYW5pbWF0aW9uIGluc3RhbmNlb2YgVGltZWxpbmUgPyBfdW5jYWNoZShhbmltYXRpb24pIDogX3NldER1cmF0aW9uKGFuaW1hdGlvbiwgYW5pbWF0aW9uLl9kdXIpO1xufSxcbiAgICBfemVyb1Bvc2l0aW9uID0ge1xuICBfc3RhcnQ6IDAsXG4gIGVuZFRpbWU6IF9lbXB0eUZ1bmMsXG4gIHRvdGFsRHVyYXRpb246IF9lbXB0eUZ1bmNcbn0sXG4gICAgX3BhcnNlUG9zaXRpb24gPSBmdW5jdGlvbiBfcGFyc2VQb3NpdGlvbihhbmltYXRpb24sIHBvc2l0aW9uLCBwZXJjZW50QW5pbWF0aW9uKSB7XG4gIHZhciBsYWJlbHMgPSBhbmltYXRpb24ubGFiZWxzLFxuICAgICAgcmVjZW50ID0gYW5pbWF0aW9uLl9yZWNlbnQgfHwgX3plcm9Qb3NpdGlvbixcbiAgICAgIGNsaXBwZWREdXJhdGlvbiA9IGFuaW1hdGlvbi5kdXJhdGlvbigpID49IF9iaWdOdW0gPyByZWNlbnQuZW5kVGltZShmYWxzZSkgOiBhbmltYXRpb24uX2R1cixcbiAgICAgIC8vaW4gY2FzZSB0aGVyZSdzIGEgY2hpbGQgdGhhdCBpbmZpbml0ZWx5IHJlcGVhdHMsIHVzZXJzIGFsbW9zdCBuZXZlciBpbnRlbmQgZm9yIHRoZSBpbnNlcnRpb24gcG9pbnQgb2YgYSBuZXcgY2hpbGQgdG8gYmUgYmFzZWQgb24gYSBTVVBFUiBsb25nIHZhbHVlIGxpa2UgdGhhdCBzbyB3ZSBjbGlwIGl0IGFuZCBhc3N1bWUgdGhlIG1vc3QgcmVjZW50bHktYWRkZWQgY2hpbGQncyBlbmRUaW1lIHNob3VsZCBiZSB1c2VkIGluc3RlYWQuXG4gIGksXG4gICAgICBvZmZzZXQsXG4gICAgICBpc1BlcmNlbnQ7XG5cbiAgaWYgKF9pc1N0cmluZyhwb3NpdGlvbikgJiYgKGlzTmFOKHBvc2l0aW9uKSB8fCBwb3NpdGlvbiBpbiBsYWJlbHMpKSB7XG4gICAgLy9pZiB0aGUgc3RyaW5nIGlzIGEgbnVtYmVyIGxpa2UgXCIxXCIsIGNoZWNrIHRvIHNlZSBpZiB0aGVyZSdzIGEgbGFiZWwgd2l0aCB0aGF0IG5hbW
1UsIG90aGVyd2lzZSBpbnRlcnByZXQgaXQgYXMgYSBudW1iZXIgKGFic29sdXRlIHZhbHVlKS5cbiAgICBvZmZzZXQgPSBwb3NpdGlvbi5jaGFyQXQoMCk7XG4gICAgaXNQZXJjZW50ID0gcG9zaXRpb24uc3Vic3RyKC0xKSA9PT0gXCIlXCI7XG4gICAgaSA9IHBvc2l0aW9uLmluZGV4T2YoXCI9XCIpO1xuXG4gICAgaWYgKG9mZnNldCA9PT0gXCI8XCIgfHwgb2Zmc2V0ID09PSBcIj5cIikge1xuICAgICAgaSA+PSAwICYmIChwb3NpdGlvbiA9IHBvc2l0aW9uLnJlcGxhY2UoLz0vLCBcIlwiKSk7XG4gICAgICByZXR1cm4gKG9mZnNldCA9PT0gXCI8XCIgPyByZWNlbnQuX3N0YXJ0IDogcmVjZW50LmVuZFRpbWUocmVjZW50Ll9yZXBlYXQgPj0gMCkpICsgKHBhcnNlRmxvYXQocG9zaXRpb24uc3Vic3RyKDEpKSB8fCAwKSAqIChpc1BlcmNlbnQgPyAoaSA8IDAgPyByZWNlbnQgOiBwZXJjZW50QW5pbWF0aW9uKS50b3RhbER1cmF0aW9uKCkgLyAxMDAgOiAxKTtcbiAgICB9XG5cbiAgICBpZiAoaSA8IDApIHtcbiAgICAgIHBvc2l0aW9uIGluIGxhYmVscyB8fCAobGFiZWxzW3Bvc2l0aW9uXSA9IGNsaXBwZWREdXJhdGlvbik7XG4gICAgICByZXR1cm4gbGFiZWxzW3Bvc2l0aW9uXTtcbiAgICB9XG5cbiAgICBvZmZzZXQgPSBwYXJzZUZsb2F0KHBvc2l0aW9uLmNoYXJBdChpIC0gMSkgKyBwb3NpdGlvbi5zdWJzdHIoaSArIDEpKTtcblxuICAgIGlmIChpc1BlcmNlbnQgJiYgcGVyY2VudEFuaW1hdGlvbikge1xuICAgICAgb2Zmc2V0ID0gb2Zmc2V0IC8gMTAwICogKF9pc0FycmF5KHBlcmNlbnRBbmltYXRpb24pID8gcGVyY2VudEFuaW1hdGlvblswXSA6IHBlcmNlbnRBbmltYXRpb24pLnRvdGFsRHVyYXRpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaSA+IDEgPyBfcGFyc2VQb3NpdGlvbihhbmltYXRpb24sIHBvc2l0aW9uLnN1YnN0cigwLCBpIC0gMSksIHBlcmNlbnRBbmltYXRpb24pICsgb2Zmc2V0IDogY2xpcHBlZER1cmF0aW9uICsgb2Zmc2V0O1xuICB9XG5cbiAgcmV0dXJuIHBvc2l0aW9uID09IG51bGwgPyBjbGlwcGVkRHVyYXRpb24gOiArcG9zaXRpb247XG59LFxuICAgIF9jcmVhdGVUd2VlblR5cGUgPSBmdW5jdGlvbiBfY3JlYXRlVHdlZW5UeXBlKHR5cGUsIHBhcmFtcywgdGltZWxpbmUpIHtcbiAgdmFyIGlzTGVnYWN5ID0gX2lzTnVtYmVyKHBhcmFtc1sxXSksXG4gICAgICB2Y
1XJzSW5kZXggPSAoaXNMZWdhY3kgPyAyIDogMSkgKyAodHlwZSA8IDIgPyAwIDogMSksXG4gICAgICB2YXJzID0gcGFyYW1zW3ZhcnNJbmRleF0sXG4gICAgICBpclZhcnMsXG4gICAgICBwYXJlbnQ7XG5cbiAgaXNMZWdhY3kgJiYgKHZhcnMuZHVyYXRpb24gPSBwYXJhbXNbMV0pO1xuICB2YXJzLnBhcmVudCA9IHRpbWVsaW5lO1xuXG4gIGlmICh0eXBlKSB7XG4gICAgaXJWYXJzID0gdmFycztcbiAgICBwYXJlbnQgPSB0aW1lbGluZTtcblxuICAgIHdoaWxlIChwYXJlbnQgJiYgIShcImltbWVkaWF0ZVJlbmRlclwiIGluIGlyVmFycykpIHtcbiAgICAgIC8vIGluaGVyaXRhbmNlIGhhc24ndCBoYXBwZW5lZCB5ZXQsIGJ1dCBzb21lb25lIG1heSBoYXZlIHNldCBhIGRlZmF1bHQgaW4gYW4gYW5jZXN0b3IgdGltZWxpbmUuIFdlIGNvdWxkIGRvIHZhcnMuaW1tZWRpYXRlUmVuZGVyID0gX2lzTm90RmFsc2UoX2luaGVyaXREZWZhdWx0cyh2YXJzKS5pbW1lZGlhdGVSZW5kZXIpIGJ1dCB0aGF0J2QgZXhhY3QgYSBzbGlnaHQgcGVyZm9ybWFuY2UgcGVuYWx0eSBiZWNhdXNlIF9pbmhlcml0RGVmYXVsdHMoKSBhbHNvIHJ1bnMgaW4gdGhlIFR3ZWVuIGNvbnN0cnVjdG9yLiBXZSdyZSBwYXlpbmcgYSBzbWFsbCBrYiBwcmljZSBoZXJlIHRvIGdhaW4gc3BlZWQuXG4gICAgICBpclZhcnMgPSBwYXJlbnQudmFycy5kZWZhdWx0cyB8fCB7fTtcbiAgICAgIHBhcmVudCA9IF9pc05vdEZhbHNlKHBhcmVudC52YXJzLmluaGVyaXQpICYmIHBhcmVudC5wYXJlbnQ7XG4gICAgfVxuXG4gICAgdmFycy5pbW1lZGlhdGVSZW5kZXIgPSBfaXNOb3RGYWxzZShpclZhcnMuaW1tZWRpYXRlUmVuZGVyKTtcbiAgICB0eXBlIDwgMiA/IHZhcnMucnVuQmFja3dhcmRzID0gMSA6
1IHZhcnMuc3RhcnRBdCA9IHBhcmFtc1t2YXJzSW5kZXggLSAxXTsgLy8gXCJmcm9tXCIgdmFyc1xuICB9XG5cbiAgcmV0dXJuIG5ldyBUd2VlbihwYXJhbXNbMF0sIHZhcnMsIHBhcmFtc1t2YXJzSW5kZXggKyAxXSk7XG59LFxuICAgIF9jb25kaXRpb25hbFJldHVybiA9IGZ1bmN0aW9uIF9jb25kaXRpb25hbFJldHVybih2YWx1ZSwgZnVuYykge1xuICByZXR1cm4gdmFsdWUgfHwgdmFsdWUgPT09IDAgPyBmdW5jKHZhbHVlKSA6IGZ1bmM7XG59LFxuICAgIF9jbGFtcCA9IGZ1bmN0aW9uIF9jbGFtcChtaW4sIG1heCwgdmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlIDwgbWluID8gbWluIDogdmFsdWUgPiBtYXggPyBtYXggOiB2YWx1ZTtcbn0sXG4gICAgZ2V0VW5pdCA9IGZ1bmN0aW9uIGdldFVuaXQodmFsdWUsIHYpIHtcbiAgcmV0dXJuICFfaXNTdHJpbmcodmFsdWUpIHx8ICEodiA9IF91bml0RXhwLmV4ZWModmFsdWUpKSA/IFwiXCIgOiB2WzFdO1xufSxcbiAgICAvLyBub3RlOiBwcm90ZWN0IGFnYWluc3QgcGFkZGVkIG51bWJlcnMgYXMgc3RyaW5ncywgbGlrZSBcIjEwMC4xMDBcIi4gVGhhdCBzaG91bGRuJ3QgcmV0dXJuIFwiMDBcIiBhcyB0aGUgdW5pdC4gSWYgaXQncyBudW1lcmljLCByZXR1cm4gbm8gdW5pdC5cbmNsYW1wID0gZnVuY3Rpb24gY2xhbXAobWluLCBtYXgsIHZhbHVlKSB7XG4gIHJldHVybiBfY29uZGl0aW9uYWxSZXR1cm4odmFsdWUsIGZ1bmN0aW9uICh2KSB7XG4gICAgcmV0dXJuIF9jbGFtcChtaW4sIG1heCwgdik7XG4gIH0pO1xufSxcbiAgICBfc2xpY2UgPSBbXS5zbGljZSxcbiAgICBfaXNBcnJheUxpa2UgPSBmdW5jdGlvbiBfaXNBcnJheUxpa2UodmFsdWUsIG5vbkVtcHR5KSB7XG4gIHJldHVybiB2YWx1ZSAmJiBfaXNPYmplY3QodmFsdWUpICYmIFwibGVuZ3RoXCIgaW4gdmFsdWUgJiYgKCFub25FbXB0eSAmJiAhdmFsdWUubGVuZ3RoIHx8IHZhbHVlLmxlbmd0aCAtIDEgaW4gdmFsdWUgJiYgX2lzT2JqZWN0KHZhbHVlWzBdKSkgJiYgIXZhbHVlLm5vZGVUeXBlICYmIHZhbHVlICE9PSBfd2luO1xufSxcbiAgICBfZmxhdHRlbiA9IGZ1bmN0aW9uIF9mbGF0dGVuKGFyLCBsZWF2ZVN0cmluZ3MsIGFjY3VtdWxhdG9yKSB7XG4gIGlmIChhY2N1bXVsYXRvciA9PT0gdm9pZCAwKSB7XG4gICAgYWNjdW11bGF0b3IgPSBbXTtcbiAgfVxuXG4gIHJldHVybiBhci5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciBfYWNjdW11bGF0b3I7XG5cbiAgICByZXR1cm4gX2lzU3RyaW5nKHZhbHVlKSAmJiAhbGVhdmVTdHJpbmdzIHx8IF9pc0FycmF5TGlrZSh2YWx1ZSwgMSkgPyAoX2FjY3VtdWxhdG9yID0gYWNjdW11bGF0b3IpLnB1c2guYXBwbHkoX2FjY3VtdWxhdG9yLCB0b0FycmF5KHZhbHVlKSkgOiBhY2N1bXVsYXRvci5wdXNoKHZhbHVlKTtcbiAgfSkgfHwgYWNjdW11bGF0b3I7XG59LFxuICAgIC8vdGFrZXMgYW55IHZhbHVlIGFuZCByZXR1cm5zIGFuIGFycmF5LiBJZiBpdCdzIGEgc3RyaW5nIChhbmQgbGVhdmVTdHJpbmdzIGlzbid0IHRydWUpLCBpdCdsbCB1c2UgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgpIGFuZCBjb252ZXJ0IHRoYXQgdG8gYW4gYXJyYXkuIEl0J2xsIGFsc28gYWNjZXB0IGl0ZXJhYmxlcyBsaWtlIGpRdWVyeSBvYmplY3RzLlxudG9BcnJheSA9IGZ1bmN0aW9uIHRvQXJyYXkodmFsdWUsIHNjb3BlLCBsZWF2ZVN0cmluZ3MpIHtcbiAgcmV0dXJuIF9jb250ZXh0ICYmICFzY29wZSAmJiBfY29udGV4dC5zZWxlY3RvciA/IF9jb250ZXh0LnNlbGVjdG9yKHZhbHVlKSA6IF9pc1N0cmluZyh2YWx1ZSkgJiYgIWxlYXZlU3RyaW5ncyAmJiAoX2NvcmVJbml0dGVkIHx8ICFfd2FrZSgpKSA/IF9zbGljZS5jYWxsKChzY29wZSB8fCBfZG9jKS5xdWVyeVNlbGVjdG9yQWxsKHZhbHVlKSwgMCkgOiBfaXNBcnJheSh2YWx1ZSkgPyBfZmxhdHRlbih2YWx1ZSwgbGVhdmVTdHJpbmdzKSA6IF9pc0FycmF5TGlrZSh2YWx1ZSkgPyBfc2xpY2UuY2FsbCh2YWx1ZSwgMCkgOiB2YWx1ZSA/IFt2YWx1ZV0gOiBbXTtcbn0sXG4gICAgc2VsZWN0b3IgPSBmdW5jdGlvbiBzZWxlY3Rvcih2YWx1ZSkge1xuICB2YWx1ZSA9IHRvQXJyYXkodmFsdWUpWzBdIHx8IF93YXJuKFwiSW52YWxpZCBzY29wZVwiKSB8fCB7fTtcbiAgcmV0dXJuIGZ1bmN0aW9uICh2KSB7XG4gICAgdmFyIGVsID0gdmFsdWUuY3VycmVudCB8fCB2YWx1ZS5uYXRpdmVFbGVtZW50IHx8IHZhbHVlO1xuICAgIHJldHVybiB0b0FycmF5KHYsIGVsLnF1ZXJ5U2VsZWN0b3JBbGwgPyBlbCA6IGVsID09PSB2YWx1ZSA/IF93YXJuKFwiSW52YWxpZCBzY29wZVwiKSB8fCBfZG9jLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikgOiB2YWx1ZSk7XG4gIH07XG59LFxuICAgIHNodWZmbGUgPSBmdW5jdGlvbiBzaHVmZmxlKGEpIHtcbiAgcmV0dXJuIGEuc29ydChmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIC41IC0gTWF0aC5yYW5kb20oKTtcbiAgfSk7XG59LFxuICAgIC8vIGFsdGVybmF0aXZlIHRoYXQncyBhIGJpdCBmYXN0ZXIgYW5kIG1vcmUgcmVsaWFibHkgZGl2ZXJzZSBidXQgYmlnZ2VyOiAgIGZvciAobGV0IGosIHYsIGkgPSBhLmxlbmd0aDsgaTsgaiA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGkpLCB2ID0gYVstLWldLCBhW2ldID0gYVtqXSwgYVtqXSA9IHYpOyByZXR1cm4gYTtcbi8vZm9yIGRpc3RyaWJ1dGluZyB2YWx1ZXMgYWNyb3NzIGFuIGFycmF5LiBDYW4gYWNjZXB0IGEgbnVtYmVyLCBhIGZ1bmN0aW9uIG9yIChtb3N0IGNvbW1vbmx5KSBhIGZ1bmN0aW9uIHdoaWNoIGNhbiBjb250YWluIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczoge2Jhc2UsIGFtb3VudCwgZnJvbSwgZWFzZSwgZ3JpZCwgYXhpcywgbGVuZ3RoLCBlYWNofS4gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgZXhwZWN0cyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6IGluZGV4LCB0YXJnZXQsIGFycmF5LiBSZWNvZ25pemVzIHRoZSBmb2xsb3dpbmdcbmRpc3RyaWJ1dGUgPSBmdW5jdGlvbiBkaXN0cmlidXRlKHYpIHtcbiAgaWYgKF9pc0Z1bmN0aW9uKHYpKSB7XG4gICAgcmV0dXJuIHY7XG4gIH1cblxuICB2YXIgdmFycyA9IF9pc09iamVjdCh2KSA/IHYgOiB7XG4gICAgZWFjaDogdlxuICB9LFxuICAgICAgLy9uOjEgaXMganVzdCB0byBpbmRpY2F0ZSB2IHdhcyBhIG51bWJlcjsgd2UgbGV2ZXJhZ2UgdGhhdCBsYXRlciB0byBzZXQgdiBhY2NvcmRpbmcgdG8gdGhlIGxlbmd0aCB3ZSBnZXQuIElmIGEgbnVtYmVyIGlzIHBhc3NlZCBpbiwgd2UgdHJlYXQgaXQgbGlrZSB0aGUgb2xkIHN0YWdn
1ZXIgdmFsdWUgd2hlcmUgMC4xLCBmb3IgZXhhbXBsZSwgd291bGQgbWVhbiB0aGF0IHRoaW5ncyB3b3VsZCBiZSBkaXN0cmlidXRlZCB3aXRoIDAuMSBiZXR3ZWVuIGVhY2ggZWxlbWVudCBpbiB0aGUgYXJyYXkgcmF0aGVyIHRoYW4gYSB0b3RhbCBcImFtb3VudFwiIHRoYXQncyBjaHVua2VkIG91dCBhbW9uZyB0aGVtIGFsbC5cbiAgZWFzZSA9IF9wYXJzZUVhc2UodmFycy5lYXNlKSxcbiAgICAgIGZyb20gPSB2YXJzLmZyb20gfHwgMCxcbiAgICAgIGJhc2UgPSBwYXJzZUZsb2F0KHZhcnMuYmFzZSkgfHwgMCxcbiAgICAgIGNhY2hlID0ge30sXG4gICAgICBpc0RlY2ltYWwgPSBmcm9tID4gMCAmJiBmcm9tIDwgMSxcbiAgICAgIHJhdGlvcyA9IGlzTmFOKGZyb20pIHx8IGlzRGVjaW1hbCxcbiAgICAgIGF4aXMgPSB2YXJzLmF4aXMsXG4gICAgICByYXRpb1ggPSBmcm9tLFxuICAgICAgcmF0aW9ZID0gZnJvbTtcblxuICBpZiAoX2lzU3RyaW5nKGZyb20pKSB7XG4gICAgcmF0aW9YID0gcmF0aW9ZID0ge1xuICAgICAgY2VudGVyOiAuNSxcbiAgICAgIGVkZ2VzOiAuNSxcbiAgICAgIGVuZDogMVxuICAgIH1bZnJvbV0gfHwgMDtcbiAgfSBlbHNlIGlmICghaXNEZWNpbWFsICYmIHJhdGlvcykge1xuICAgIHJhdGlvWCA9IGZyb21bMF07XG4gICAgcmF0aW9ZID0gZnJvbVsxXTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoaSwgdGFyZ2V0LCBhKSB7XG4gICAgdmFyIGwgPSAoYSB8fCB2YXJzKS5sZW5ndGgsXG4gICAgICAgIGRpc3RhbmNlcyA9IGNhY2hlW2xdLFxuICAgICAgICBvcmlnaW5YLFxuICAgICAgICBvcmlnaW5ZLFxuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgICBkLFxuICAgICAgICBqLFxuICAgICAgICBtYXgsXG4gICAgICAgIG1pbixcbiAgICAgICAgd3JhcEF0O1xuXG4gICAgaWYgKCFkaXN0YW5jZXMpIHtcbiAgICAgIHdyYXBBdCA9IHZhcnMuZ3JpZCA9PT0gXCJhdXRvXCIgPyAwIDogKHZhcnMuZ3JpZCB8fCBbMSwgX2JpZ051bV0pWzFdO1xuXG4gICAgICBpZiAoIXdyYXBBdCkge1xuICAgICAgICBtYXggPSAtX2JpZ051bTtcblxuICAgICAgICB3aGlsZSAobWF4IDwgKG1heCA9IGFbd3JhcEF0KytdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQpICYmIHdyYXBBdCA8IGwpIHt9XG5cbiAgICAgICAgd3JhcEF0IDwgbCAmJiB3cmFwQXQtLTtcbiAgICAgIH1cblxuICAgICAgZGlzdGFuY2VzID0gY2FjaGVbbF0gPSBbXTtcbiAgICAgIG9yaWdpblggPSByYXRpb3MgPyBNYXRoLm1pbih3cmFwQXQsIGwpICogcmF0aW9YIC0gLjUgOiBmcm9tICUgd3JhcEF0O1xuICAgICAgb3JpZ2luWSA9IHdyYXBBdCA9PT0gX2JpZ051bSA/IDAgOiByYXRpb3MgPyBsICogcmF0aW9ZIC8gd3JhcEF0IC0gLjUgOiBmcm9tIC8gd3JhcEF0IHwgMDtcbiAgICAgIG1heCA9IDA7XG4gICAgICBtaW4gPSBfYmlnTnVtO1xuXG4gICAgICBmb3IgKGogPSAwOyBqIDwgbDsgaisrKSB7XG4gICAgICAgIHggPSBqICUgd3JhcEF0IC0gb3JpZ2luWDtcbiAgICAgICAgeSA9IG9yaWdpblkgLSAoaiAvIHdyYXBBdCB8IDApO1xuICAgICAgICBkaXN0YW5jZXNbal0gPSBkID0gIWF4aXMgPyBfc3FydCh4ICogeCArIHkgKiB5KSA6IE1hdGguYWJzKGF4aXMgPT09IFwieVwiID8geSA6IHgpO1xuICAgICAgICBkID4gbWF4ICYmIChtYXggPSBkKTtcbiAgICAgICAgZCA8IG1pbiAmJiAobWluID0gZCk7XG4gICAgICB9XG5cbiAgICAgIGZyb20gPT09IFwicmFuZG9tXCIgJiYgc2h1ZmZsZShkaXN0YW5jZXMpO1xuICAgICAgZGlzdGFuY2VzLm1heCA9IG1heCAtIG1pbjtcbiAgICAgIGRpc3RhbmNlcy5taW4gPSBtaW47XG4gICAgICBkaXN0YW5jZXMudiA9IGwgPSAocGFyc2VGbG9hdCh2YXJzLmFtb3VudCkgfHwgcGFyc2VGbG9hdCh2YXJzLmVhY2gpICogKHdyYXBBdCA+IGwgPyBsIC0gMSA6ICFheGlzID8gTWF0aC5tYXgod3JhcEF0LCBsIC8gd3JhcEF0KSA6IGF4aXMgPT09IFwieVwiID8gbCAvIHdyYXBBdCA6IHdyYXBBdCkgfHwgMCkgKiAoZnJvbSA9PT0gXCJlZGdlc1wiID8gLTEgOiAxKTtcbiAgICAgIGRpc3RhbmNlcy5iID0gbCA8IDAgPyBiYXNlIC0gbCA6IGJhc2U7XG4gICAgICBkaXN0YW5jZXMudSA9IGdldFVuaXQodmFycy5hbW91bnQgfHwgdmFycy5lYWNoKSB8fCAwOyAvL3VuaXRcblxuICAgICAgZWFzZSA9IGVhc2UgJiYgbCA8IDAgPyBfaW52ZXJ0RWFzZShlYXNlKSA6IGVhc2U7XG4gICAgfVxuXG4gICAgbCA9IChkaXN0YW5jZXNbaV0gLSBkaXN0YW5jZXMubWluKSAvIGRpc3RhbmNlcy5tYXggfHwgMDtcbiAgICByZXR1cm4gX3JvdW5kUHJlY2lzZShkaXN0YW5jZXMuYiArIChlYXNlID8gZWFzZShsKSA6IGwpICogZGlzdGFuY2VzLnYpICsgZGlzdGFuY2VzLnU7IC8vcm91bmQgaW4gb3JkZXIgdG8gd29yayBhcm91bmQgZmxvYXRpbmcgcG9pbnQgZXJyb3JzXG4gIH07XG59LFxuICAgIF9yb3VuZE1vZGlmaWVyID0gZnVuY3Rpb24gX3JvdW5kTW9kaWZpZXIodikge1xuICAvL3Bhc3MgaW4gMC4xIGdldCBhIGZ1bmN0aW9uIHRoYXQnbGwgcm91bmQgdG8gdGhlIG5lYXJlc3QgdGVudGgsIG9yIDUgdG8gcm91bmQgdG8gdGhlIGNsb3Nlc3QgNSwgb3IgMC4wMDEgdG8gdGhlIGNsb3Nlc3QgMTAwMHRoLCBldGMuXG4gIHZhciBwID0gTWF0aC5wb3coMTAsICgodiArIFwiXCIpLnNwbGl0KFwiLlwiKVsxXSB8fCBcIlwiKS5sZW5ndGgpOyAvL3RvIGF2b2lkIGZsb2F0aW5nIHBvaW50IG1hdGggZXJyb3JzIChsaWtlIDI0ICogMC4xID09IDIuNDAwMDAwMDAwMDAwMDAwNCksIHdlIGNob3Agb2ZmIGF0IGEgc3BlY2lmaWMgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIChtdWNoIGZhc3RlciB0aGFuIHRvRml4ZWQoKSlcblxuICByZXR1cm4gZnVuY3Rpb24gKHJhdykge1xuICAgIHZhciBuID0gX3JvdW5kUHJlY2lzZShNYXRoLnJvdW5kKHBhcnNlRmxvYXQocmF3KSAvIHYpICogdiAqIHApO1xuXG4gICAgcmV0dXJuIChuIC0gbiAlIDEpIC8gcCArIChfaXNOdW1iZXIocmF3KSA/IDAgOiBnZXRVbml0KHJhdykpOyAvLyBuIC0gbiAlIDEgcmVwbGFjZXMgTWF0aC5mbG9vcigpIGluIG9yZGVyIHRvIGhhbmRsZSBuZWdhdGl2ZSB2YWx1ZXMgcHJvcGVybHkuIEZvciBleGFtcGxlLCBNYXRoLmZsb29yKC0xNTAuMDAwMDAwMDAwMDAwMDMpIGlzIDE1MS
1FcbiAgfTtcbn0sXG4gICAgc25hcCA9IGZ1bmN0aW9uIHNuYXAoc25hcFRvLCB2YWx1ZSkge1xuICB2YXIgaXNBcnJheSA9IF9pc0FycmF5KHNuYXBUbyksXG4gICAgICByYWRpdXMsXG4gICAgICBpczJEO1xuXG4gIGlmICghaXNBcnJheSAmJiBfaXNPYmplY3Qoc25hcFRvKSkge1xuICAgIHJhZGl1cyA9IGlzQXJyYXkgPSBzbmFwVG8ucmFkaXVzIHx8IF9iaWdOdW07XG5cbiAgICBpZiAoc25hcFRvLnZhbHVlcykge1xuICAgICAgc25hcFRvID0gdG9BcnJheShzbmFwVG8udmFsdWVzKTtcblxuICAgICAgaWYgKGlzMkQgPSAhX2lzTnVtYmVyKHNuYXBUb1swXSkpIHtcbiAgICAgICAgcmFkaXVzICo9IHJhZGl1czsgLy9wZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24gc28gd2UgZG9uJ3QgaGF2ZSB0byBNYXRoLnNxcnQoKSBpbiB0aGUgbG9vcC5cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc25hcFRvID0gX3JvdW5kTW9kaWZpZXIoc25hcFRvLmluY3JlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIF9jb25kaXRpb25hbFJldHVybih2YWx1ZSwgIWlzQXJyYXkgPyBfcm91bmRNb2RpZmllcihzbmFwVG8pIDogX2lzRnVuY3Rpb24oc25hcFRvKSA/IGZ1bmN0aW9uIChyYXcpIHtcbiAgICBpczJEID0gc25hcFRvKHJhdyk7XG4gICAgcmV0dXJuIE1hdGguYWJzKGlzMkQgLSByYXcpIDw9IHJhZGl1cyA/IGlzMkQgOiByYXc7XG4gIH0gOiBmdW5jdGlvbiAocmF3KSB7XG4gICAgdmFyIHggPSBwYXJzZUZsb2F0KGlzMkQgPyByYXcueCA6IHJhdyksXG4gICAgICAgIHkgPSBwYXJzZUZsb2F0KGlzMkQgPyByYXcueSA6IDApLFxuICAgICAgICBtaW4gPSBfYmlnTnVtLFxuICAgICAgICBjbG9zZXN0ID0gMCxcbiAgICAgICAgaSA9IHNuYXBUby5sZW5ndGgsXG4gICAgICAgIGR4LFxuICAgICAgICBkeTtcblxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGlmIChpczJEKSB7XG4gICAgICAgIGR4ID0gc25hcFRvW2ldLnggLSB4O1xuICAgICAgICBkeSA9IHNuYXBUb1tpXS55IC0geTtcbiAgICAgICAgZHggPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGR4ID0gTWF0aC5hYnMoc25hcFRvW2ldIC0geCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkeCA8IG1pbikge1xuICAgICAgICBtaW4gPSBkeDtcbiAgICAgICAgY2xvc2VzdCA9IGk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY2xvc2VzdCA9ICFyYWRpdXMgfHwgbWluIDw9IHJhZGl1cyA/IHNuYXBUb1tjbG9zZXN0XSA6IHJhdztcbiAgICByZXR1cm4gaXMyRCB8fCBjbG9zZXN0ID09PSByYXcgfHwgX2lzTnVtYmVyKHJhdykgPyBjbG9zZXN0IDogY2xvc2VzdCArIGdldFVuaXQocmF3KTtcbiAgfSk7XG59LFxuICAgIHJhbmRvbSA9IGZ1bmN0aW9uIHJhbmRvbShtaW4sIG1heCwgcm91bmRpbmdJbmNyZW1lbnQsIHJldHVybkZ1bmN0aW9uKSB7XG4gIHJldHVybiBfY29uZGl0aW9uYWxSZXR1cm4oX2lzQXJyYXkobWluKSA/ICFtYXggOiByb3VuZGluZ0luY3JlbWVudCA9PT0gdHJ1ZSA/ICEhKHJvdW5kaW5nSW5jcmVtZW50ID0gMCkgOiAhcmV0dXJuRnVuY3Rpb24sIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2lzQXJyYXkobWluKSA/IG1pblt+fihNYXRoLnJhbmRvbSgpICogbWluLmxlbmd0aCldIDogKHJvdW5kaW5nSW5jcmVtZW50ID0gcm91bmRpbmdJbmNyZW1lbnQgfHwgMWUtNSkgJiYgKHJldHVybkZ1bmN0aW9uID0gcm91bmRpbmdJbmNyZW1lbnQgPCAxID8gTWF0aC5wb3coMTAsIChyb3VuZGluZ0luY3JlbWVudCArIFwiXCIpLmxlbmd0aCAtIDIpIDogMSkgJiYgTWF0aC5mbG9vcihNYXRoLnJvdW5kKChtaW4gLSByb3VuZGluZ0luY3JlbWVudCAvIDIgKyBNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbiArIHJvdW5kaW5nSW5jcmVtZW50ICogLjk5KSkgLyByb3VuZGluZ0luY3JlbWVudCkgKiByb3VuZGluZ0luY3JlbWVudCAqIHJldHVybkZ1bmN0aW9uKSAvIHJldHVybkZ1bmN0aW9uO1xuICB9KTtcbn0sXG4gICAgcGlwZSA9IGZ1bmN0aW9uIHBpcGUoKSB7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBmdW5jdGlvbnMgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgZnVuY3Rpb25zW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBmdW5jdGlvbnMucmVkdWNlKGZ1bmN0aW9uICh2LCBmKSB7XG4gICAgICByZXR1cm4gZih2KTtcbiAgICB9LCB2YWx1ZSk7XG4gIH07XG59LFxuICAgIHVuaXRpemUgPSBmdW5jdGlvbiB1bml0aXplKGZ1bmMsIHVuaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBmdW5jKHBhcnNlRmxvYXQodmFsdWUpKSArICh1bml0IHx8IGdldFVuaXQodmFsdWUpKTtcbiAgfTtcbn0sXG4gICAgbm9ybWFsaXplID0gZnVuY3Rpb24gbm9ybWFsaXplKG1pbiwgbWF4LCB2YWx1ZSkge1xuICByZXR1cm4gbWFwUmFuZ2UobWluLCBtYXgsIDAsIDEsIHZhbHVlKTtcbn0sXG4gICAgX3dyYXBBcnJheSA9IGZ1bmN0aW9uIF93cmFwQXJyYXkoYSwgd3JhcHBlciwgdmFsdWUpIHtcbiAgcmV0dXJuIF9jb25kaXRpb25hbFJldHVybih2YWx1ZSwgZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgcmV0dXJuIGFbfn53cmFwcGVyKGluZGV4KV07XG4gIH0pO1xufSxcbiAgICB3cmFwID0gZnVuY3Rpb24gd3JhcChtaW4sIG1heCwgdmFsdWUpIHtcbiAgLy8gTk9URTogd3JhcCgpIENBTk5PVCBiZSBhbiBhcnJvdyBmdW5jdGlvbiEgQSB2ZXJ5IG9kZCBjb21waWxpbmcgYnVnIGNhdXNlcyBwcm9ibGVtcyAodW5yZWxhdGVkIHRvIEdTQVApLlxuICB2YXIgcmFuZ2UgPSBtYXggLSBtaW47XG4gIHJldHVybiBfaXNBcnJheShtaW4pID8gX3dyYXBBcnJheShtaW4sIHdyYXAoMCwgbWluLmxlbmd0aCksIG1heCkgOiBfY29uZGl0aW9uYWxSZXR1cm4odmFsdWUsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiAocmFuZ2UgKyAodmFsdWUgLSBtaW4pICUgcmFuZ2UpICUgcmFuZ2UgKyBtaW47XG4gIH0pO1xufSxcbiAgICB3cmFwWW95byA9IGZ1bmN0aW9uIHdyYXBZb3lvKG1pbiwgbWF4LCB2YWx1ZSkge1xuICB2YXIgcmFuZ2UgPSBtYXggLSBtaW4sXG4gICAgICB0b3RhbCA9IHJhbmdlICogMjtcbiAgcmV0dXJuIF9pc0FycmF5KG1pbikgPyBfd3JhcEFycmF5KG1pbiwgd3JhcFlveW8oMCwgbWluLmxlbmd0aCAtIDEpLCBtYXgpIDogX2NvbmRpdGlvbmFsUmV0dXJuKHZhbHVlLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB2YWx1ZSA9ICh0b3RhbCArICh2YWx1ZSAtIG1pbikgJSB0b3RhbCkgJSB0b3RhbCB8fCAwO1xuICAgIHJldHVybi
1BtaW4gKyAodmFsdWUgPiByYW5nZSA/IHRvdGFsIC0gdmFsdWUgOiB2YWx1ZSk7XG4gIH0pO1xufSxcbiAgICBfcmVwbGFjZVJhbmRvbSA9IGZ1bmN0aW9uIF9yZXBsYWNlUmFuZG9tKHZhbHVlKSB7XG4gIC8vcmVwbGFjZXMgYWxsIG9jY3VycmVuY2VzIG9mIHJhbmRvbSguLi4pIGluIGEgc3RyaW5nIHdpdGggdGhlIGNhbGN1bGF0ZWQgcmFuZG9tIHZhbHVlLiBjYW4gYmUgYSByYW5nZSBsaWtlIHJhbmRvbSgtMTAwLCAxMDAsIDUpIG9yIGFuIGFycmF5IGxpa2UgcmFuZG9tKFswLCAxMDAsIDUwMF0pXG4gIHZhciBwcmV2ID0gMCxcbiAgICAgIHMgPSBcIlwiLFxuICAgICAgaSxcbiAgICAgIG51bXMsXG4gICAgICBlbmQsXG4gICAgICBpc0FycmF5O1xuXG4gIHdoaWxlICh+KGkgPSB2YWx1ZS5pbmRleE9mKFwicmFuZG9tKFwiLCBwcmV2KSkpIHtcbiAgICBlbmQgPSB2YWx1ZS5pbmRleE9mKFwiKVwiLCBpKTtcbiAgICBpc0FycmF5ID0gdmFsdWUuY2hhckF0KGkgKyA3KSA9PT0gXCJbXCI7XG4gICAgbnVtcyA9IHZhbHVlLnN1YnN0cihpICsgNywgZW5kIC0gaSAtIDcpLm1hdGNoKGlzQXJyYXkgPyBfZGVsaW1pdGVkVmFsdWVFeHAgOiBfc3RyaWN0TnVtRXhwKTtcbiAgICBzICs9IHZhbHVlLnN1YnN0cihwcmV2LCBpIC0gcHJldikgKyByYW5kb20oaXNBcnJheSA/IG51bXMgOiArbnVtc1swXSwgaXNBcnJheSA/IDAgOiArbnVtc1sxXSwgK251bXNbMl0gfHwgMWUtNSk7XG4gICAgcHJldiA9IGVuZCArIDE7XG4gIH1cblxuICByZXR1cm4gcyArIHZhbHVlLnN1YnN0cihwcmV2LCB2YWx1ZS5sZW5ndGggLSBwcmV2KTtcbn0sXG4gICAgbWFwUmFuZ2UgPSBmdW5jdGlvbiBtYXBSYW5nZShpbk1pbiwgaW5NYXgsIG91dE1pbiwgb3V0TWF4LCB2YWx1ZSkge1xuICB2YXIgaW5SYW5nZSA9IGluTWF4IC0gaW5NaW4sXG4gICAgICBvdXRSYW5nZSA9IG91dE1heCAtIG91dE1pbjtcbiAgcmV0dXJuIF9jb25kaXRpb25hbFJldHVybih2YWx1ZSwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIG91dE1pbiArICgodmFsdWUgLSBpbk1pbikgLyBpblJhbmdlICogb3V0UmFuZ2UgfHwgMCk7XG4gIH0pO1xufSxcbiAgICBpbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uIGludGVycG9sYXRlKHN0YXJ0LCBlbmQsIHByb2dyZXNzLCBtdXRhdGUpIHtcbiAgdmFyIGZ1bmMgPSBpc05hTihzdGFydCArIGVuZCkgPyAwIDogZnVuY3Rpb24gKHApIHtcbiAgICByZXR1cm4gKDEgLSBwKSAqIHN0YXJ0ICsgcCAqIGVuZDtcbiAgfTtcblxuICBpZiAoIWZ1bmMpIHtcbiAgICB2YXIgaXNTdHJpbmcgPSBfaXNTdHJpbmcoc3RhcnQpLFxuICAgICAgICBtYXN0ZXIgPSB7fSxcbiAgICAgICAgcCxcbiAgICAgICAgaSxcbiAgICAgICAgaW50ZXJwb2xhdG9ycyxcbiAgICAgICAgbCxcbiAgICAgICAgaWw7XG5cbiAgICBwcm9ncmVzcyA9PT0gdHJ1ZSAmJiAobXV0YXRlID0gMSkgJiYgKHByb2dyZXNzID0gbnVsbCk7XG5cbiAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgIHN0YXJ0ID0ge1xuICAgICAgICBwOiBzdGFydFxuICAgICAgfTtcbiAgICAgIGVuZCA9IHtcbiAgICAgICAgcDogZW5kXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoX2lzQXJyYXkoc3RhcnQpICYmICFfaXNBcnJheShlbmQpKSB7XG4gICAgICBpbnRlcnBvbGF0b3JzID0gW107XG4gICAgICBsID0gc3RhcnQubGVuZ3RoO1xuICAgICAgaWwgPSBsIC0gMjtcblxuICAgICAgZm9yIChpID0gMTsgaSA8IGw7IGkrKykge1xuICAgICAgICBpbnRlcnBvbGF0b3JzLnB1c2goaW50ZXJwb2xhdGUoc3RhcnRbaSAtIDFdLCBzdGFydFtpXSkpOyAvL2J1aWxkIHRoZSBpbnRlcnBvbGF0b3JzIHVwIGZyb250IGFzIGEgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uIHNvIHRoYXQgd2hlbiB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkIG1hbnkgdGltZXMsIGl0IGNhbiBqdXN0IHJldXNlIHRoZW0uXG4gICAgICB9XG5cbiAgICAgIGwtLTtcblxuICAgICAgZnVuYyA9IGZ1bmN0aW9uIGZ1bmMocCkge1xuICAgICAgICBwICo9IGw7XG4gICAgICAgIHZhciBpID0gTWF0aC5taW4oaWwsIH5+cCk7XG4gICAgICAgIHJldHVybiBpbnRlcnBvbGF0b3JzW2ldKHAgLSBpKTtcbiAgICAgIH07XG5cbiAgICAgIHByb2dyZXNzID0gZW5kO1xuICAgIH0gZWxzZSBpZiAoIW11dGF0ZSkge1xuICAgICAgc3RhcnQgPSBfbWVyZ2UoX2lzQXJyYXkoc3RhcnQpID8gW10gOiB7fSwgc3RhcnQpO1xuICAgIH1cblxuICAgIGlmICghaW50ZXJwb2xhdG9ycykge1xuICAgICAgZm9yIChwIGluIGVuZCkge1xuICAgICAgICBfYWRkUHJvcFR3ZWVuLmNhbGwobWFzdGVyLCBzdGFydCwgcCwgXCJnZXRcIiwgZW5kW3BdKTtcbiAgICAgIH1cblxuICAgICAgZnVuYyA9IGZ1bmN0aW9uIGZ1bmMocCkge1xuICAgICAgICByZXR1cm4gX3JlbmRlclByb3BUd2VlbnMocCwgbWFzdGVyKSB8fCAoaXNTdHJpbmcgPyBzdGFydC5wIDogc3RhcnQpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gX2NvbmRpdGlvbmFsUmV0dXJuKHByb2dyZXNzLCBmdW5jKTtcbn0sXG4gICAgX2dldExhYmVsSW5EaXJlY3Rpb24gPSBmdW5jdGlvbiBfZ2V0TGFiZWxJbkRpcmVjdGlvbih0aW1lbGluZSwgZnJvbVRpbWUsIGJhY2t3YXJkKSB7XG4gIC8vdXNlZCBmb3IgbmV4dExhYmVsKCkgYW5kIHByZXZpb3VzTGFiZWwoKVxuICB2YXIgbGFiZWxzID0gdGltZWxpbmUubGFiZWxzLFxuICAgICAgbWluID0gX2JpZ051bSxcbiAgICAgIHAsXG4gICAgICBkaXN0YW5jZSxcbiAgICAgIGxhYmVsO1xuXG4gIGZvciAocCBpbiBsYWJlbHMpIHtcbiAgICBkaXN0YW5jZSA9IGxhYmVsc1twXSAtIGZyb21UaW1lO1xuXG4gICAgaWYgKGRpc3RhbmNlIDwgMCA9PT0gISFiYWNrd2FyZCAmJiBkaXN0YW5jZSAmJiBtaW4gPiAoZGlzdGFuY2UgPSBNYXRoLmFicyhkaXN0YW5jZSkpKSB7XG4gICAgICBsYWJlbCA9IHA7XG4gICAgICBtaW4gPSBkaXN0YW5jZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbGFiZWw7XG59LFxuICAgIF9jYWxsYmFjayA9IGZ1bmN0aW9uIF9jYWxsYmFjayhhbmltYXRpb24sIHR5cGUsIGV4ZWN1dGVMYXp5Rmlyc3QpIHtcbiAgdmFyIHYgPSBhbmltYXRpb24udmFycyxcbiAgICAgIGNhbGxiYWNrID0gdlt0eXBlXSxcbiAgICAgIHByZXZDb250ZXh0ID0gX2NvbnRleHQsXG4gICAgICBjb250ZXh0ID0gYW5pbWF0aW9uLl9jdHgsXG4gICAgICBwYXJhbXMsXG4gICAgICBzY29wZSxcbiAgICAgIHJlc3VsdDtcblxuICBpZiAoIWNhbGxiYWNrKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcGFyYW1zID0gdlt0eXBlICsgXCJQYXJhbXNcIl07XG4gIHNjb3BlID0gdi5jYWxsYmFja1Njb3BlIHx8IGFuaW1hdGlvbjtcbiAgZXhlY3V0ZUxhenlGaXJzdCAmJiBfbGF6eVR3ZWVucy5sZW5ndGggJiYgX2xhenlSZW5kZXIoKTsgLy9pbiBjYXNlIHJlbmRlcmluZyBjYXVzZWQgYW55IHR3ZWVucyB0byBsYXp5LWluaXQsIHdlIHNob3VsZCByZW5kZXIgdGhlbSBiZWNhdXNlIHR5cGljYWxseSB3aGVuIGEgdGltZWxpbmUgZmluaXNoZXMsIHVzZXJzIGV4cGVjdCB0aGluZ3MgdG8gaGF2ZSByZW5kZXJlZCBmdWxseS4gSW1hZ2luZSBhbiBvblVwZGF0ZSBvbiBhIHRpbWVsaW5lIHRoYXQgcmVwb3J0cy9jaGVja3MgdHdlZW5lZCB2YWx1ZXMuXG5cbiAgY29udGV4dCAmJiAoX2NvbnRleHQgPSBjb250ZXh0KTtcbiAgcmVzdWx0ID0gcGFyYW1zID8gY2FsbGJhY2suYXBwbHkoc2NvcGUsIH
1BhcmFtcykgOiBjYWxsYmFjay5jYWxsKHNjb3BlKTtcbiAgX2NvbnRleHQgPSBwcmV2Q29udGV4dDtcbiAgcmV0dXJuIHJlc3VsdDtcbn0sXG4gICAgX2ludGVycnVwdCA9IGZ1bmN0aW9uIF9pbnRlcnJ1cHQoYW5pbWF0aW9uKSB7XG4gIF9yZW1vdmVGcm9tUGFyZW50KGFuaW1hdGlvbik7XG5cbiAgYW5pbWF0aW9uLnNjcm9sbFRyaWdnZXIgJiYgYW5pbWF0aW9uLnNjcm9sbFRyaWdnZXIua2lsbCghIV9yZXZlcnRpbmcpO1xuICBhbmltYXRpb24ucHJvZ3Jlc3MoKSA8IDEgJiYgX2NhbGxiYWNrKGFuaW1hdGlvbiwgXCJvbkludGVycnVwdFwiKTtcbiAgcmV0dXJuIGFuaW1hdGlvbjtcbn0sXG4gICAgX3F1aWNrVHdlZW4sXG4gICAgX3JlZ2lzdGVyUGx1Z2luUXVldWUgPSBbXSxcbiAgICBfY3JlYXRlUGx1Z2luID0gZnVuY3Rpb24gX2NyZWF0ZVBsdWdpbihjb25maWcpIHtcbiAgaWYgKCFjb25maWcpIHJldHVybjtcbiAgY29uZmlnID0gIWNvbmZpZy5uYW1lICYmIGNvbmZpZ1tcImRlZmF1bHRcIl0gfHwgY29uZmlnOyAvLyBVTUQgcGFja2FnaW5nIHdyYXBzIHRoaW5ncyBvZGRseSwgc28gZm9yIGV4YW1wbGUgTW90aW9uUGF0aEhlbHBlciBiZWNvbWVzIHtNb3Rpb25QYXRoSGVscGVyOk1vdGlvblBhdGhIZWxwZXIsIGRlZmF1bHQ6TW90aW9uUGF0aEhlbHBlcn0uXG5cbiAgaWYgKF93aW5kb3dFeGlzdHMoKSB8fCBjb25maWcuaGVhZGxlc3MpIHtcbiAgICAvLyBlZGdlIGNhc2U6IHNvbWUgYnVpbGQgdG9vbHMgbWF5IHBhc3MgaW4gYSBudWxsL3VuZGVmaW5lZCB2YWx1ZVxuICAgIHZhciBuYW1lID0gY29uZmlnLm5hbWUsXG4gICAgICAgIGlzRnVuYyA9IF9pc0Z1bmN0aW9uKGNvbmZpZyksXG4gICAgICAgIFBsdWdpbiA9IG5hbWUgJiYgIWlzRnVuYyAmJiBjb25maWcuaW5pdCA/IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuX3Byb3BzID0gW107XG4gICAgfSA6IGNvbmZpZyxcbiAgICAgICAgLy9pbiBjYXNlIHNvbWVvbmUgcGFzc2VzIGluIGFuIG9iamVjdCB0aGF0J3Mgbm90IGEgcGx1Z2luLCBsaWtlIEN1c3RvbUVhc2VcbiAgICBpbnN0YW5jZURlZmF1bHRzID0ge1xuICAgICAgaW5pdDogX2VtcHR5RnVuYyxcbiAgICAgIHJlbmRlcjogX3JlbmRlclByb3BUd2VlbnMsXG4gICAgICBhZGQ6IF9hZGRQcm9wVHdlZW4sXG4gICAgICBraWxsOiBfa2lsbFByb3BUd2VlbnNPZixcbiAgICAgIG1vZGlmaWVyOiBfYWRkUGx1Z2luTW9kaWZpZXIsXG4gICAgICByYXdWYXJzOiAwXG4gICAgfSxcbiAgICAgICAgc3RhdGljcyA9IHtcbiAgICAgIHRhcmdldFRlc3Q6IDAsXG4gICAgICBnZXQ6IDAsXG4gICAgICBnZXRTZXR0ZXI6IF9nZXRTZXR0ZXIsXG4gICAgICBhbGlhc2VzOiB7fSxcbiAgICAgIHJlZ2lzdGVyOiAwXG4gICAgfTtcblxuICAgIF93YWtlKCk7XG5cbiAgICBpZiAoY29uZmlnICE9PSBQbHVnaW4pIHtcbiAgICAgIGlmIChfcGx1Z2luc1tuYW1lXSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIF9zZXREZWZhdWx0cyhQbHVnaW4sIF9zZXREZWZhdWx0cyhfY29weUV4Y2x1ZGluZyhjb25maWcsIGluc3RhbmNlRGVmYXVsdHMpLCBzdGF0aWNzKSk7IC8vc3RhdGljIG1ldGhvZHNcblxuXG4gICAgICBfbWVyZ2UoUGx1Z2luLnByb3RvdHlwZSwgX21lcmdlKGluc3RhbmNlRGVmYXVsdHMsIF9jb3B5RXhjbHVkaW5nKGNvbmZpZywgc3RhdGljcykpKTsgLy9pbnN0YW5jZSBtZXRob2RzXG5cblxuICAgICAgX3BsdWdpbnNbUGx1Z2luLnByb3AgPSBuYW1lXSA9IFBsdWdpbjtcblxuICAgICAgaWYgKGNvbmZpZy50YXJnZXRUZXN0KSB7XG4gICAgICAgIF9oYXJuZXNzUGx1Z2lucy5wdXNoKFBsdWdpbik7XG5cbiAgICAgICAgX3Jlc2VydmVkUHJvcHNbbmFtZV0gPSAxO1xuICAgICAgfVxuXG4gICAgICBuYW1lID0gKG5hbWUgPT09IFwiY3NzXCIgPyBcIkNTU1wiIDogbmFtZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIG5hbWUuc3Vic3RyKDEpKSArIFwiUGx1Z2luXCI7IC8vZm9yIHRoZSBnbG9iYWwgbmFtZS4gXCJtb3Rpb25QYXRoXCIgc2hvdWxkIGJlY29tZSBNb3Rpb25QYXRoUGx1Z2luXG4gICAgfVxuXG4gICAgX2FkZEdsb2JhbChuYW1lLCBQbHVnaW4pO1xuXG4gICAgY29uZmlnLnJlZ2lzdGVyICYmIGNvbmZpZy5yZWdpc3Rlcihnc2FwLCBQbHVnaW4sIFByb3BUd2Vlbik7XG4gIH0gZWxzZSB7XG4gICAgX3JlZ2lzdGVyUGx1Z2luUXVldWUucHVzaChjb25maWcpO1xuICB9XG59LFxuXG4vKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIENPTE9SU1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXzI1NSA9IDI1NSxcbiAgICBfY29sb3JMb29rdXAgPSB7XG4gIGFxdWE6IFswLCBfMjU1LCBfMjU1XSxcbiAgbGltZTogWzAsIF8yNTUsIDBdLFxuICBzaWx2ZXI6IFsxOTIsIDE5MiwgMTkyXSxcbiAgYmxhY2s6IFswLCAwLCAwXSxcbiAgbWFyb29uOiBbMTI4LCAwLCAwXSxcbiAgdGVhbDogWzAsIDEyOCwgMTI4XSxcbiAgYmx1ZTogWzAsIDAsIF8yNTVdLFxuICBuYXZ5OiBbMCwgMCwgMTI4XSxcbiAgd2hpdGU6IFtfMjU1LCBfMjU1LCBfMjU1XSxcbiAgb2xpdmU6IFsxMjgsIDEyOCwgMF0sXG4gIHllbGxvdzogW18yNTUsIF8yNTUsIDBdLFxuICBvcmFuZ2U6IFtfMjU1LCAxNjUsIDBdLFxuICBncmF5OiBbMTI4LCAxMjgsIDEyOF0sXG4gIHB1cnBsZTogWzEyOCwgMCwgMTI4XSxcbiAgZ3JlZW46IFswLCAxMjgsIDBdLFxuICByZWQ6IFtfMjU1LCAwLCAwXSxcbiAgcGluazogW18yNTUsIDE5MiwgMjAzXSxcbiAgY3lhbjogWzAsIF8yNTUsIF8yNTVdLFxuICB0cmFuc3BhcmVudDogW18yNTUsIF8yNTUsIF8yNTUsIDBdXG59LFxuICAgIC8vIHBvc3NpYmxlIGZ1dHVyZSBpZGVhIHRvIHJlcGxhY2UgdGhlIGhhcmQtY29kZWQgY29sb3IgbmFtZSB2YWx1ZXMgLSBwdXQgdGhpcyBpbiB0aGUgdGlja2VyLndha2UoKSB3aGVyZSB3ZSBzZXQgdGhlIF9kb2M6XG4vLyBsZXQgY3R4ID0gX2RvYy5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpLmdldENvbnRleHQoXCIyZFwiKTtcbi8vIF9mb3JFYWNoTmFtZShcImFxdWEsbGltZSxzaWx2ZXIsYmxhY2ssbWFyb29uLHRlYWwsYmx1ZSxuYXZ5LHdoaXRlLG9saXZlLHllbGxvdyxvcmFuZ2UsZ3JheSxwdXJwbGUsZ3JlZW4scmVkLHBpbmssY3lhblwiLCBjb2xvciA9PiB7Y3R4LmZpbGxTdHlsZSA9IGNvbG9yOyBfY29sb3JMb29rdXBbY29sb3JdID0gc3BsaXRDb2xvcihjdHguZmlsbFN0eWxlKX0pO1xuX2h1ZSA9IGZ1bmN0aW9uIF9odWUoaCwgbTEsIG0yKSB7XG4gIGggKz0gaCA8IDAgPyAxIDogaCA+IDEgPyAtMSA6IDA7XG4gIHJldHVybiAoaCAqIDYgPCAxID8gbTEgKyAobTIgLSBtMSkgKiBoICogNiA6IGggPCAuNSA/IG0yIDogaCAqIDMgPCAyID8gbTEgKyAobTIgLSBtMSkgKiAoMiAvIDMgLSBoKSAqIDYgOiBtMSkgKiBfMjU1ICsgLjUgfCAwO1xufSxcbiAgICBzcGxpdENvbG9yID0gZnVuY3Rpb24gc3BsaXRDb2xvcih2LCB0b0hTTCwgZm9yY2VBbHBoYSkge1xuICB2YXIgYSA9ICF2ID8gX2NvbG9yTG9va3VwLmJsYWNrIDogX2lzTnVtYmVyKHYpID8gW3YgPj4gMTYsIHYgPj4gOCAmIF8yNTUsIHYgJiBfMjU1XSA6
1IDAsXG4gICAgICByLFxuICAgICAgZyxcbiAgICAgIGIsXG4gICAgICBoLFxuICAgICAgcyxcbiAgICAgIGwsXG4gICAgICBtYXgsXG4gICAgICBtaW4sXG4gICAgICBkLFxuICAgICAgd2FzSFNMO1xuXG4gIGlmICghYSkge1xuICAgIGlmICh2LnN1YnN0cigtMSkgPT09IFwiLFwiKSB7XG4gICAgICAvL3NvbWV0aW1lcyBhIHRyYWlsaW5nIGNvbW1hIGlzIGluY2x1ZGVkIGFuZCB3ZSBzaG91bGQgY2hvcCBpdCBvZmYgKHR5cGljYWxseSBmcm9tIGEgY29tbWEtZGVsaW1pdGVkIGxpc3Qgb2YgdmFsdWVzIGxpa2UgYSB0ZXh0U2hhZG93OlwiMnB4IDJweCAycHggYmx1ZSwgNXB4IDVweCA1cHggcmdiKDI1NSwwLDApXCIgLSBpbiB0aGlzIGV4YW1wbGUgXCJibHVlLFwiIGhhcyBhIHRyYWlsaW5nIGNvbW1hLiBXZSBjb3VsZCBzdHJpcCBpdCBvdXQgaW5zaWRlIHBhcnNlQ29tcGxleCgpIGJ1dCB3ZSdkIG5lZWQgdG8gZG8gaXQgdG8gdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIHZhbHVlcyBwbHVzIGl0IHdvdWxkbid0IHByb3ZpZGUgcHJvdGVjdGlvbiBmcm9tIG90aGVyIHBvdGVudGlhbCBzY2VuYXJpb3MgbGlrZSBpZiB0aGUgdXNlciBwYXNzZXMgaW4gYSBzaW1pbGFyIHZhbHVlLlxuICAgICAgdiA9IHYuc3Vic3RyKDAsIHYubGVuZ3RoIC0gMSk7XG4gICAgfVxuXG4gICAgaWYgKF9jb2xvckxvb2t1cFt2XSkge1xuICAgICAgYSA9IF9jb2xvckxvb2t1cFt2XTtcbiAgICB9IGVsc2UgaWYgKHYuY2hhckF0KDApID09PSBcIiNcIikge1xuICAgICAgaWYgKHYubGVuZ3RoIDwgNikge1xuICAgICAgICAvL2ZvciBzaG9ydGhhbmQgbGlrZSAjOUYwIG9yICM5RjBGIChjb3VsZCBoYXZlIGFscGhhKVxuICAgICAgICByID0gdi5jaGFyQXQoMSk7XG4gICAgICAgIGcgPSB2LmNoYXJBdCgyKTtcbiAgICAgICAgYiA9IHYuY2hhckF0KDMpO1xuICAgICAgICB2ID0gXCIjXCIgKyByICsgciArIGcgKyBnICsgYiArIGIgKyAodi5sZW5ndGggPT09IDUgPyB2LmNoYXJBdCg0KSArIHYuY2hhckF0KDQpIDogXCJcIik7XG4gICAgICB9XG5cbiAgICAgIGlmICh2Lmxlbmd0aCA9PT0gOSkge1xuICAgICAgICAvLyBoZXggd2l0aCBhbHBoYSwgbGlrZSAjZmQ1ZTUzZmZcbiAgICAgICAgYSA9IHBhcnNlSW50KHYuc3Vic3RyKDEsIDYpLCAxNik7XG4gICAgICAgIHJldHVybiBbYSA+PiAxNiwgYSA+PiA4ICYgXzI1NSwgYSAmIF8yNTUsIHBhcnNlSW50KHYuc3Vic3RyKDcpLCAxNikgLyAyNTVdO1xuICAgICAgfVxuXG4gICAgICB2ID0gcGFyc2VJbnQodi5zdWJzdHIoMSksIDE2KTtcbiAgICAgIGEgPSBbdiA+PiAxNiwgdiA+PiA4ICYgXzI1NSwgdiAmIF8yNTVdO1xuICAgIH0gZWxzZSBpZiAodi5zdWJzdHIoMCwgMykgPT09IFwiaHNsXCIpIHtcbiAgICAgIGEgPSB3YXNIU0wgPSB2Lm1hdGNoKF9zdHJpY3ROdW1FeHApO1xuXG4gICAgICBpZiAoIXRvSFNMKSB7XG4gICAgICAgIGggPSArYVswXSAlIDM2MCAvIDM2MDtcbiAgICAgICAgcyA9ICthWzFdIC8gMTAwO1xuICAgICAgICBsID0gK2FbMl0gLyAxMDA7XG4gICAgICAgIGcgPSBsIDw9IC41ID8gbCAqIChzICsgMSkgOiBsICsgcyAtIGwgKiBzO1xuICAgICAgICByID0gbCAqIDIgLSBnO1xuICAgICAgICBhLmxlbmd0aCA+IDMgJiYgKGFbM10gKj0gMSk7IC8vY2FzdCBhcyBudW1iZXJcblxuICAgICAgICBhWzBdID0gX2h1ZShoICsgMSAvIDMsIHIsIGcpO1xuICAgICAgICBhWzFdID0gX2h1ZShoLCByLCBnKTtcbiAgICAgICAgYVsyXSA9IF9odWUoaCAtIDEgLyAzLCByLCBnKTtcbiAgICAgIH0gZWxzZSBpZiAofnYuaW5kZXhPZihcIj1cIikpIHtcbiAgICAgICAgLy9pZiByZWxhdGl2ZSB2YWx1ZXMgYXJlIGZvdW5kLCBqdXN0IHJldHVybiB0aGUgcmF3IHN0cmluZ3Mgd2l0aCB0aGUgcmVsYXRpdmUgcHJlZml4ZXMgaW4gcGxhY2UuXG4gICAgICAgIGEgPSB2Lm1hdGNoKF9udW1FeHApO1xuICAgICAgICBmb3JjZUFscGhhICYmIGEubGVuZ3RoIDwgNCAmJiAoYVszXSA9IDEpO1xuICAgICAgICByZXR1cm4gYTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYSA9IHYubWF0Y2goX3N0cmljdE51bUV4cCkgfHwgX2NvbG9yTG9va3VwLnRyYW5zcGFyZW50O1xuICAgIH1cblxuICAgIGEgPSBhLm1hcChOdW1iZXIpO1xuICB9XG5cbiAgaWYgKHRvSFNMICYmICF3YXNIU0wpIHtcbiAgICByID0gYVswXSAvIF8yNTU7XG4gICAgZyA9IGFbMV0gLyBfMjU1O1xuICAgIGIgPSBhWzJdIC8gXzI1NTtcbiAgICBtYXggPSBNYXRoLm1heChyLCBnLCBiKTtcbiAgICBtaW4gPSBNYXRoLm1pbihyLCBnLCBiKTtcbiAgICBsID0gKG1heCArIG1pbikgLyAyO1xuXG4gICAgaWYgKG1heCA9PT0gbWluKSB7XG4gICAgICBoID0gcyA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGQgPSBtYXggLSBtaW47XG4gICAgICBzID0gbCA+IDAuNSA/IGQgLyAoMiAtIG1heCAtIG1pbikgOiBkIC8gKG1heCArIG1pbik7XG4gICAgICBoID0gbWF4ID09PSByID8gKGcgLSBiKSAvIGQgKyAoZyA8IGIgPyA2IDogMCkgOiBtYXggPT09IGcgPyAoYiAtIHIpIC8gZCArIDIgOiAociAtIGcpIC8gZCArIDQ7XG4gICAgICBoICo9IDYwO1xuICAgIH1cblxuICAgIGFbMF0gPSB+fihoICsgLjUpO1xuICAgIGFbMV0gPSB+fihzICogMTAwICsgLjUpO1xuICAgIGFbMl0gPSB+fihsICogMTAwICsgLjUpO1xuICB9XG5cbiAgZm9yY2VBbHBoYSAmJiBhLmxlbmd0aCA8IDQgJiYgKGFbM10gPSAxKTtcbiAgcmV0dXJuIGE7XG59LFxuICAgIF9jb2xvck9yZGVyRGF0YSA9IGZ1bmN0aW9uIF9jb2xvck9yZGVyRGF0YSh2KSB7XG4gIC8vIHN0cmlwcyBvdXQgdGhlIGNvbG9ycyBmcm9tIHRoZSBzdHJpbmcsIGZpbmRzIGFsbCB0aGUgbnVtZXJpYyBzbG90cyAod2l0aCB1bml0cykgYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgdGhvc2UuIFRoZSBBcnJheSBhbHNvIGhhcyBhIFwiY1wiIHByb3BlcnR5IHdoaWNoIGlzIGFuIEFycmF5IG9mIHRoZSBpbmRleCB2YWx1ZXMgd2hlcmUgdGhlIGNvbG9ycyBiZWxvbmcuIFRoaXMgaXMgdG8gaGVscCB3b3JrIGFyb3VuZCBpc3N1ZXMgd2hlcmUgdGhlcmUncyBhIG1pcy1tYXRjaGVkIG9yZGVyIG9mIGNvbG9yL251bWVyaWMgZGF0YSBsaWtlIGRyb3Atc2hhZG93KCNmMDAgMHB4IDFweCAycHgpIGFuZCBkcm9wLXNoYWRvdygweCAxcHggMnB4ICNmMDApLiBUaGlzIGlzIGJhc2ljYWxseSBhIGhlbHBlciBmdW5jdGlvbiB1c2VkIGluIF9mb3JtYXRDb2xvcnMoKVxuICB2YXIgdmFsdWVzID0gW10sXG4gICAgICBjID0gW10sXG4gICAgICBpID0gLTE7XG4gIHYuc3BsaXQoX2NvbG9yRXhwKS5mb3JFYWNoKGZ1bmN0aW9uICh2KSB7XG4gICAgdmFyIGEgPSB2Lm1hdGNoKF9udW1XaXRoVW5pdEV4cCkgfHwgW107XG4gICAgdmFsdWVzLnB1c2guYXBwbHkodmFsdWVzLCBhKTtcbiAgICBjLnB1c2goaSArPSBhLmxlbmd0aCArIDEpO1xuICB9KTtcbiAgdmFsdWVzLmMgPSBjO1xuICByZXR1cm4gdmFsdWVzO1xufSxcbiAgICBfZm9ybWF0Q29sb3JzID0gZnVuY3Rpb24gX2Zvcm1hdENvbG9ycyhzLCB0b0hTTCwgb3JkZXJNYXRjaERhdGEpIHtcbiAgdmFyIHJlc3VsdCA9IFwiXCIsXG4gICAgICBjb2xvcnMgPSAocyArIHJlc3VsdCkubWF0Y2goX2NvbG9yRXhwKSxcbiAgICAgIHR5cGUgPSB0b0hTTCA/IFwiaHNsYShcIiA6IFwicmdiYShcIixcbiAgICAgIGkgPSAwLFxuICAgICAgYyxcbiAgICAgIHNoZWxsLFxuICAgICAgZCxcbiAgICAgIGw7XG5cbiAgaWYgKCFjb2xvcnMpIHtcbiAgICByZXR1cm4gcztcbiAgfVxuXG4gIGNvbG9ycyA9IGNvbG9ycy5tYXAoZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgcmV0dXJuIChjb2xvciA9IHNwbGl0Q29sb3IoY29sb3IsIHRvSFNMLCAxKSkgJiYgdHlwZSArICh0b0hTTCA/IGNvbG9yWzBdICsgXCIsXCIgKyBjb2xvclsxXSArIFwiJSxcIiArIGNvbG9yWzJdICsgXCIlLFwiICsgY29sb3JbM10gOiBjb2xvci5qb2luKFwiLFwiKSkgKyBcIilcIjtcbiAgfSk7XG5cbiAgaWYgKG9yZGVyTWF0Y2hEYXRhKSB7XG4gICAgZCA9IF9jb2xvck9yZGVyRGF0YShzKTtcbiAgICBjID0gb3JkZXJNYXRjaERhdGEuYztcblxuICAgIGlmIChjLmpvaW4ocmVzdWx0KSAhPT0gZC5jLmpvaW4ocmVzdWx0KSkge1xuICAgICAgc2hlbGwgPSBzLnJlcGxhY2UoX2NvbG9yRXhwLCBcIjFcIikuc3BsaXQoX251bVdpdGhVbml0RXhwKTtcbiAgICAgIGwgPSBzaGVsbC5sZW5ndGggLSAxO1xuXG4gICAgICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgICAgICByZXN1bHQgKz0gc2hlbGxbaV0gKyAofmMuaW5kZXhPZihpKSA/IGNvbG9ycy5zaGlmdCgpIHx8IHR5cGUgKyBcIjA
1sMCwwLDApXCIgOiAoZC5sZW5ndGggPyBkIDogY29sb3JzLmxlbmd0aCA/IGNvbG9ycyA6IG9yZGVyTWF0Y2hEYXRhKS5zaGlmdCgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoIXNoZWxsKSB7XG4gICAgc2hlbGwgPSBzLnNwbGl0KF9jb2xvckV4cCk7XG4gICAgbCA9IHNoZWxsLmxlbmd0aCAtIDE7XG5cbiAgICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgICAgcmVzdWx0ICs9IHNoZWxsW2ldICsgY29sb3JzW2ldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQgKyBzaGVsbFtsXTtcbn0sXG4gICAgX2NvbG9yRXhwID0gZnVuY3Rpb24gKCkge1xuICB2YXIgcyA9IFwiKD86XFxcXGIoPzooPzpyZ2J8cmdiYXxoc2x8aHNsYSlcXFxcKC4rP1xcXFwpKXxcXFxcQiMoPzpbMC05YS1mXXszLDR9KXsxLDJ9XFxcXGJcIixcbiAgICAgIC8vd2UnbGwgZHluYW1pY2FsbHkgYnVpbGQgdGhpcyBSZWd1bGFyIEV4cHJlc3Npb24gdG8gY29uc2VydmUgZmlsZSBzaXplLiBBZnRlciBidWlsZGluZyBpdCwgaXQgd2lsbCBiZSBhYmxlIHRvIGZpbmQgcmdiKCksIHJnYmEoKSwgIyAoaGV4YWRlY2ltYWwpLCBhbmQgbmFtZWQgY29sb3IgdmFsdWVzIGxpa2UgcmVkLCBibHVlLCBwdXJwbGUsIGV0Yy4sXG4gIHA7XG5cbiAgZm9yIChwIGluIF9jb2xvckxvb2t1cCkge1xuICAgIHMgKz0gXCJ8XCIgKyBwICsgXCJcXFxcYlwiO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBSZWdFeHAocyArIFwiKVwiLCBcImdpXCIpO1xufSgpLFxuICAgIF9oc2xFeHAgPSAvaHNsW2FdP1xcKC8sXG4gICAgX2NvbG9yU3RyaW5nRmlsdGVyID0gZnVuY3Rpb24gX2NvbG9yU3RyaW5nRmlsdGVyKGEpIHtcbiAgdmFyIGNvbWJpbmVkID0gYS5qb2luKFwiIFwiKSxcbiAgICAgIHRvSFNMO1xuICBfY29sb3JFeHAubGFzdEluZGV4ID0gMDtcblxuICBpZiAoX2NvbG9yRXhwLnRlc3QoY29tYmluZWQpKSB7XG4gICAgdG9IU0wgPSBfaHNsRXhwLnRlc3QoY29tYmluZWQpO1xuICAgIGFbMV0gPSBfZm9ybWF0Q29sb3JzKGFbMV0sIHRvSFNMKTtcbiAgICBhWzBdID0gX2Zvcm1hdENvbG9ycyhhWzBdLCB0b0hTTCwgX2NvbG9yT3JkZXJEYXRhKGFbMV0pKTsgLy8gbWFrZSBzdXJlIHRoZSBvcmRlciBvZiBudW1iZXJzL2NvbG9ycyBtYXRjaCB3aXRoIHRoZSBFTkQgdmFsdWUuXG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufSxcblxuLypcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBUSUNLRVJcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cbl90aWNrZXJBY3RpdmUsXG4gICAgX3RpY2tlciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9nZXRUaW1lID0gRGF0ZS5ub3csXG4gICAgICBfbGFnVGhyZXNob2xkID0gNTAwLFxuICAgICAgX2FkanVzdGVkTGFnID0gMzMsXG4gICAgICBfc3RhcnRUaW1lID0gX2dldFRpbWUoKSxcbiAgICAgIF9sYXN0VXBkYXRlID0gX3N0YXJ0VGltZSxcbiAgICAgIF9nYXAgPSAxMDAwIC8gMjQwLFxuICAgICAgX25leHRUaW1lID0gX2dhcCxcbiAgICAgIF9saXN0ZW5lcnMgPSBbXSxcbiAgICAgIF9pZCxcbiAgICAgIF9yZXEsXG4gICAgICBfcmFmLFxuICAgICAgX3NlbGYsXG4gICAgICBfZGVsdGEsXG4gICAgICBfaSxcbiAgICAgIF90aWNrID0gZnVuY3Rpb24gX3RpY2sodikge1xuICAgIHZhciBlbGFwc2VkID0gX2dldFRpbWUoKSAtIF9sYXN0VXBkYXRlLFxuICAgICAgICBtYW51YWwgPSB2ID09PSB0cnVlLFxuICAgICAgICBvdmVybGFwLFxuICAgICAgICBkaXNwYXRjaCxcbiAgICAgICAgdGltZSxcbiAgICAgICAgZnJhbWU7XG5cbiAgICAoZWxhcHNlZCA+IF9sYWdUaHJlc2hvbGQgfHwgZWxhcHNlZCA8IDApICYmIChfc3RhcnRUaW1lICs9IGVsYXBzZWQgLSBfYWRqdXN0ZWRMYWcpO1xuICAgIF9sYXN0VXBkYXRlICs9IGVsYXBzZWQ7XG4gICAgdGltZSA9IF9sYXN0VXBkYXRlIC0gX3N0YXJ0VGltZTtcbiAgICBvdmVybGFwID0gdGltZSAtIF9uZXh0VGltZTtcblxuICAgIGlmIChvdmVybGFwID4gMCB8fCBtYW51YWwpIHtcbiAgICAgIGZyYW1lID0gKytfc2VsZi5mcmFtZTtcbiAgICAgIF9kZWx0YSA9IHRpbWUgLSBfc2VsZi50aW1lICogMTAwMDtcbiAgICAgIF9zZWxmLnRpbWUgPSB0aW1lID0gdGltZSAvIDEwMDA7XG4gICAgICBfbmV4dFRpbWUgKz0gb3ZlcmxhcCArIChvdmVybGFwID49IF9nYXAgPyA0IDogX2dhcCAtIG92ZXJsYXApO1xuICAgICAgZGlzcGF0Y2ggPSAxO1xuICAgIH1cblxuICAgIG1hbnVhbCB8fCAoX2lkID0gX3JlcShfdGljaykpOyAvL21ha2Ugc3VyZSB0aGUgcmVxdWVzdCBpcyBtYWRlIGJlZm9yZSB3ZSBkaXNwYXRjaCB0aGUgXCJ0aWNrXCIgZXZlbnQgc28gdGhhdCB0aW1pbmcgaXMgbWFpbnRhaW5lZC4gT3RoZXJ3aXNlLCBpZiBwcm9jZXNzaW5nIHRoZSBcInRpY2tcIiByZXF1aXJlcyBhIGJ1bmNoIG9mIHRpbWUgKGxpa2UgMTVtcykgYW5kIHdlJ3JlIHVzaW5nIGEgc2V0VGltZW91dCgpIHRoYXQncyBiYXNlZCBvbiAxNi43bXMsIGl0J2QgdGVjaG5pY2FsbHkgdGFrZSAzMS43bXMgYmV0d2VlbiBmcmFtZXMgb3RoZXJ3aXNlLlxuXG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICBmb3IgKF9pID0gMDsgX2kgPCBfbGlzdGVuZXJzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAvLyB1c2UgX2kgYW5kIGNoZWNrIF9saXN0ZW5lcnMubGVuZ3RoIGluc3RlYWQgb2YgYSB2YXJpYWJsZSBiZWNhdXNlIGEgbGlzdGVuZXIgY291bGQgZ2V0IHJlbW92ZWQgZHVyaW5nIHRoZSBsb29wLCBhbmQgaWYgdGhhdCBoYXBwZW5zIHRvIGFuIGVsZW1lbnQgbGVzcyB0aGFuIHRoZSBjdXJyZW50IGluZGV4LCBpdCdkIHRocm93IHRoaW5ncyBvZmYgaW4gdGhlIGxvb3AuXG4gICAgICAgIF9saXN0ZW5lcnNbX2ldKHRpbWUsIF9kZWx0YSwgZnJhbWUsIHYpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBfc2VsZiA9IHtcbiAgICB0aW1lOiAwLFxuICAgIGZyYW1lOiAwLFxuICAgIHRpY2s6IGZ1bmN0aW9uIHRpY2soKSB7XG4gICAgICBfdGljayh0cnVlKTtcbiAgICB9LFxuICAgIGRlbHRhUmF0aW86IGZ1bmN0aW9uIGRlbHRhUmF0aW8oZnBzKSB7XG4gICAgICByZXR1cm4gX2RlbHRhIC8gKDEwMDAgLyAoZnBzIHx8IDYwKSk7XG4gICAgfSxcbiAgICB3YWtlOiBmdW5jdGlvbiB3YWtlKCkge1xuICAgICAgaWYgKF9jb3JlUmVhZHkpIHtcbiAgICAgICAgaWYgKCFfY29yZUluaXR0ZWQgJiYgX3dpbmRvd0V4aXN0cygpKSB7XG4gICAgICAgICAgX3dpbiA9IF9jb3JlSW5pdHRlZCA9IHdpbmRvdztcbiAgICAgICAgICBfZG9jID0gX3dpbi5kb2N1bWVudCB8fCB7fTtcbiAgICAgICAgICBfZ2xvYmFscy5nc2FwID0gZ3NhcDtcbiAgICAgICAgICAoX3dpbi5nc2FwVmVyc2lvbnMgfHwgKF93aW4uZ3NhcFZlcnNpb25zID0gW10pKS5wdXNoKGdzYXAudmVyc2lvbik7XG5cbiAgICAgICAgICBfaW5zdGFsbChfaW5zdGFsbFNjb3BlIHx8IF93aW4uR3JlZW5Tb2NrR2xvYmFscyB8fCAhX3dpbi5nc2FwICYmIF93aW4gfHwge30pO1xuXG4gICAgICAgICAgX3JlZ2lzdGVyUGx1Z2luUXVldWUuZm9yRWFjaChfY3JlYXRlUGx1Z2luKTtcbiAgICAgICAgfVxuXG4gICAgICAgIF9yYWYgPSB0eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lICE9PSBcInVuZGVmaW5lZFwiICYmIHJlcXVlc3RBbmltYXRpb25GcmFtZTtcbiAgICAgICAgX2lkICYmIF9zZWxmLnNsZWVwKCk7XG5cbiAgICAgICAgX3JlcSA9IF9yYWYgfHwgZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICByZXR1cm4gc2V0VGltZW91dChmLCBfbmV4dFRpbWUgLSBfc2VsZi50aW1lICogMTAwMCArIDEgfCAwKTtcbiAgICAgICAgfTtcblxuICAgICAgICBfdGlja2VyQWN0aXZlID0gMTtcblxuICAgICAgICBfdGljaygyKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIHNsZWVwOiBmdW5jdGlvbiBzbGVlcCgpIHtcbiAgICAgIChfcmFmID8gY2FuY2VsQW5pbWF0aW9uRnJhbWUgOiBjbGVhclRpbWVvdXQpKF9pZCk7XG4gICAgICBfdGlja2VyQWN0aXZlID0gMDtcbiAgICAgIF9yZXEgPSBfZW1wdHlGdW5jO1xuICAgIH0sXG4gICAgbGFnU21vb3RoaW5nOiBmdW5jdGlvbiBsYWdTbW9vdGhpbmcodGhyZXNob2xkLCBhZGp1c3RlZExhZykge1xuICAgICAgX2xhZ1RocmVzaG9sZCA9IHRocmVzaG9sZCB8fCBJbmZpbml0eTsgLy8gemVybyBzaG91bGQgYmUgaW50ZXJwcmV0ZWQgYXMgYmFzaWNhbGx5IHVubGltaXRlZFxuXG4gICAgICBfYWRqdXN0ZWRMYWcgPSBNYXRoLm1pbihhZGp1c3RlZExhZyB8fCAzMywgX2xhZ1RocmVzaG9sZCk7XG4gICAgfSxcbiAgICBmcHM6IGZ1bmN0aW9uIGZwcyhfZnBzKSB7XG4gICAgICBfZ2FwID0gMTAwMCAvIChfZnBzIHx8IDI0MCk7XG4gICAgICBfbmV4dFRpbWUgPSBfc2VsZi50aW1lICogMTAwMCArIF9nYXA7XG4gICAgfSxcbiAgICBhZGQ6IGZ1bmN0aW9uIGFkZChjYWxsYmFjaywgb25jZSwgcHJpb3JpdGl6ZSkge1xuICAgICAgdmFyIGZ1bmMgPSBvbmNlID8gZnVuY3Rpb24gKHQsIGQsIGYsIHYpIHtcbiAgICAgICAgY2FsbGJhY2sodCwgZCwgZiwgdik7XG5cbiAgICAgICAgX3NlbGYucmVtb3ZlKGZ1bmMpO1xuICAgICAgfSA6IGNhbGxiYWNrO1xuXG4gICAgICBfc2VsZi5yZW1vdmUoY2FsbGJhY2spO1xuXG4gICAgICBfbGlzdGVuZXJzW3ByaW9yaXRpemUgPyBcInVuc2hpZnRcIiA6IFwicHVzaFwiXShmdW5jKTtcblxuICAgICAgX3dha2UoKTtcblxuICAgICAgcmV0dXJuIGZ1bmM7XG4gICAgfSxcbiAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZShjYWxsYmFjaywgaSkge1xuICAgICAgfihpID0gX2xpc3RlbmVycy5pbmRleE9mKGNhbGxiYWNrKSkgJiYgX2xpc3RlbmVycy5zcGxpY2UoaSwgMSkgJiYgX2kgPj0gaSAmJi
1BfaS0tO1xuICAgIH0sXG4gICAgX2xpc3RlbmVyczogX2xpc3RlbmVyc1xuICB9O1xuICByZXR1cm4gX3NlbGY7XG59KCksXG4gICAgX3dha2UgPSBmdW5jdGlvbiBfd2FrZSgpIHtcbiAgcmV0dXJuICFfdGlja2VyQWN0aXZlICYmIF90aWNrZXIud2FrZSgpO1xufSxcbiAgICAvL2Fsc28gZW5zdXJlcyB0aGUgY29yZSBjbGFzc2VzIGFyZSBpbml0aWFsaXplZC5cblxuLypcbiogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKiBFQVNJTkdcbiogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKi9cbl9lYXNlTWFwID0ge30sXG4gICAgX2N1c3RvbUVhc2VFeHAgPSAvXltcXGQuXFwtTV1bXFxkLlxcLSxcXHNdLyxcbiAgICBfcXVvdGVzRXhwID0gL1tcIiddL2csXG4gICAgX3BhcnNlT2JqZWN0SW5TdHJpbmcgPSBmdW5jdGlvbiBfcGFyc2VPYmplY3RJblN0cmluZyh2YWx1ZSkge1xuICAvL3Rha2VzIGEgc3RyaW5nIGxpa2UgXCJ7d2lnZ2xlczoxMCwgdHlwZTphbnRpY2lwYXRlfSlcIiBhbmQgdHVybnMgaXQgaW50byBhIHJlYWwgb2JqZWN0LiBOb3RpY2UgaXQgZW5kcyBpbiBcIilcIiBhbmQgaW5jbHVkZXMgdGhlIHt9IHdyYXBwZXJzLiBUaGlzIGlzIGJlY2F1c2Ugd2Ugb25seSB1c2UgdGhpcyBmdW5jdGlvbiBmb3IgcGFyc2luZyBlYXNlIGNvbmZpZ3MgYW5kIHByaW9yaXRpemVkIG9wdGltaXphdGlvbiByYXRoZXIgdGhhbiByZXVzYWJpbGl0eS5cbiAgdmFyIG9iaiA9IHt9LFxuICAgICAgc3BsaXQgPSB2YWx1ZS5zdWJzdHIoMSwgdmFsdWUubGVuZ3RoIC0gMykuc3BsaXQoXCI6XCIpLFxuICAgICAga2V5ID0gc3BsaXRbMF0sXG4gICAgICBpID0gMSxcbiAgICAgIGwgPSBzcGxpdC5sZW5ndGgsXG4gICAgICBpbmRleCxcbiAgICAgIHZhbCxcbiAgICAgIHBhcnNlZFZhbDtcblxuICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgIHZhbCA9IHNwbGl0W2ldO1xuICAgIGluZGV4ID0gaSAhPT0gbCAtIDEgPyB2YWwubGFzdEluZGV4T2YoXCIsXCIpIDogdmFsLmxlbmd0aDtcbiAgICBwYXJzZWRWYWwgPSB2YWwuc3Vic3RyKDAsIGluZGV4KTtcbiAgICBvYmpba2V5XSA9IGlzTmFOKHBhcnNlZFZhbCkgPyBwYXJzZWRWYWwucmVwbGFjZShfcXVvdGVzRXhwLCBcIlwiKS50cmltKCkgOiArcGFyc2VkVmFsO1xuICAgIGtleSA9IHZhbC5zdWJzdHIoaW5kZXggKyAxKS50cmltKCk7XG4gIH1cblxuICByZXR1cm4gb2JqO1xufSxcbiAgICBfdmFsdWVJblBhcmVudGhlc2VzID0gZnVuY3Rpb24gX3ZhbHVlSW5QYXJlbnRoZXNlcyh2YWx1ZSkge1xuICB2YXIgb3BlbiA9IHZhbHVlLmluZGV4T2YoXCIoXCIpICsgMSxcbiAgICAgIGNsb3NlID0gdmFsdWUuaW5kZXhPZihcIilcIiksXG4gICAgICBuZXN0ZWQgPSB2YWx1ZS5pbmRleE9mKFwiKFwiLCBvcGVuKTtcbiAgcmV0dXJuIHZhbHVlLnN1YnN0cmluZyhvcGVuLCB+bmVzdGVkICYmIG5lc3RlZCA8IGNsb3NlID8gdmFsdWUuaW5kZXhPZihcIilcIiwgY2xvc2UgKyAxKSA6IGNsb3NlKTtcbn0sXG4gICAgX2NvbmZpZ0Vhc2VGcm9tU3RyaW5nID0gZnVuY3Rpb24gX2NvbmZpZ0Vhc2VGcm9tU3RyaW5nKG5hbWUpIHtcbiAgLy9uYW1lIGNhbiBiZSBhIHN0cmluZyBsaWtlIFwiZWxhc3RpYy5vdXQoMSwwLjUpXCIsIGFuZCBwYXNzIGluIF9lYXNlTWFwIGFzIG9iaiBhbmQgaXQnbGwgcGFyc2UgaXQgb3V0IGFuZCBjYWxsIHRoZSBhY3R1YWwgZnVuY3Rpb24gbGlrZSBfZWFzZU1hcC5FbGFzdGljLmVhc2VPdXQuY29uZmlnKDEsMC41KS4gSXQgd2lsbCBhbHNvIHBhcnNlIGN1c3RvbSBlYXNlIHN0cmluZ3MgYXMgbG9uZyBhcyBDdXN0b21FYXNlIGlzIGxvYWRlZCBhbmQgcmVnaXN0ZXJlZCAoaW50ZXJuYWxseSBhcyBfZWFzZU1hcC5fQ0UpLlxuICB2YXIgc3BsaXQgPSAobmFtZSArIFwiXCIpLnNwbGl0KFwiKFwiKSxcbiAgICAgIGVhc2UgPSBfZWFzZU1hcFtzcGxpdFswXV07XG4gIHJldHVybiBlYXNlICYmIHNwbGl0Lmxlbmd0aCA+IDEgJiYgZWFzZS5jb25maWcgPyBlYXNlLmNvbmZpZy5hcHBseShudWxsLCB+bmFtZS5pbmRleE9mKFwie1wiKSA/IFtfcGFyc2VPYmplY3RJblN0cmluZyhzcGxpdFsxXSldIDogX3ZhbHVlSW5QYXJlbnRoZXNlcyhuYW1lKS5zcGxpdChcIixcIikubWFwKF9udW1lcmljSWZQb3NzaWJsZSkpIDogX2Vhc2VNYXAuX0NFICYmIF9jdXN0b21FYXNlRXhwLnRlc3QobmFtZSkgPyBfZWFzZU1hcC5fQ0UoXCJcIiwgbmFtZSkgOiBlYXNlO1xufSxcbiAgICBfaW52ZXJ0RWFzZSA9IGZ1bmN0aW9uIF9pbnZlcnRFYXNlKGVhc2UpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChwKSB7XG4gICAgcmV0dXJuIDEgLSBlYXNlKDEgLSBwKTtcbiAgfTtcbn0sXG4gICAgLy8gYWxsb3cgeW95b0Vhc2UgdG8gYmUgc2V0IGluIGNoaWxkcmVuIGFuZCBoYXZlIHRob3NlIGFmZmVjdGVkIHdoZW4gdGhlIHBhcmVudC9hbmNlc3RvciB0aW1lbGluZSB5b3lvcy5cbl9wcm9wYWdhdGVZb3lvRWFzZSA9IGZ1bmN0aW9uIF9wcm9wYWdhdGVZb3lvRWFzZSh0aW1lbGluZSwgaXNZb3lvKSB7XG4gIHZhciBjaGlsZCA9IHRpbWVsaW5lLl9maXJzdCxcbiAgICAgIGVhc2U7XG5cbiAgd2hpbGUgKGNoaWxkKSB7XG4gICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgVGltZWxpbmUpIHtcbiAgICAgIF9wcm9wYWdhdGVZb3lvRWFzZShjaGlsZCwgaXNZb3lvKTtcbiAgICB9IGVsc2UgaWYgKGNoaWxkLnZhcnMueW95b0Vhc2UgJiYgKCFjaGlsZC5feW95byB8fCAhY2hpbGQuX3JlcGVhdCkgJiYgY2hpbGQuX3lveW8gIT09IGlzWW95bykge1xuICAgICAgaWYgKGNoaWxkLnRpbWVsaW5lKSB7XG4gICAgICAgIF9wcm9wYWdhdGVZb3lvRWFzZShjaGlsZC50aW1lbGluZSwgaXNZb3lvKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVhc2UgPSBjaGlsZC5fZWFzZTtcbiAgICAgICAgY2hpbGQuX2Vhc2UgPSBjaGlsZC5feUVhc2U7XG4gICAgICAgIGNoaWxkLl95RWFzZSA9IGVhc2U7XG4gICAgICAgIGNoaWxkLl95b3lvID0gaXNZb3lvO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNoaWxkID0gY2hpbGQuX25leHQ7XG4gIH1cbn0sXG4gICAgX3BhcnNlRWFzZSA9IGZ1bmN0aW9uIF9wYXJzZUVhc2UoZWFzZSwgZGVmYXVsdEVhc2UpIHtcbiAgcmV0dXJuICFlYXNlID8gZGVmYXVsdEVhc2UgOiAoX2lzRnVuY3Rpb24oZWFzZSkgPyBlYXNlIDogX2Vhc2VNYXBbZWFzZV0gfHwgX2NvbmZpZ0Vhc2VGcm9tU3RyaW5nKGVhc2UpKSB8fCBkZWZhdWx0RWFzZTtcbn0sXG4gICAgX2luc2VydEVhc2UgPSBmdW5jdGlvbiBfaW5zZXJ0RWFzZShuYW1lcywgZWFzZUluLCBlYXNlT3V0LCBlYXNlSW5PdXQpIHtcbiAgaWYgKGVhc2VPdXQgPT09IHZvaWQgMCkge1xuICAgIGVhc2VPdXQgPSBmdW5jdGlvbiBlYXNlT3V0KHApIHtcbiAgICAgIHJldHVybiAxIC0gZWFzZUluKDEgLSBwKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKGVhc2VJbk91dCA9PT0gdm9pZCAwKSB7XG4gICAgZWFzZUluT3V0ID0gZnVuY3Rpb24gZWFzZUluT3V0KHApIHtcbiAgICAgIHJldHVybi
1BwIDwgLjUgPyBlYXNlSW4ocCAqIDIpIC8gMiA6IDEgLSBlYXNlSW4oKDEgLSBwKSAqIDIpIC8gMjtcbiAgICB9O1xuICB9XG5cbiAgdmFyIGVhc2UgPSB7XG4gICAgZWFzZUluOiBlYXNlSW4sXG4gICAgZWFzZU91dDogZWFzZU91dCxcbiAgICBlYXNlSW5PdXQ6IGVhc2VJbk91dFxuICB9LFxuICAgICAgbG93ZXJjYXNlTmFtZTtcblxuICBfZm9yRWFjaE5hbWUobmFtZXMsIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgX2Vhc2VNYXBbbmFtZV0gPSBfZ2xvYmFsc1tuYW1lXSA9IGVhc2U7XG4gICAgX2Vhc2VNYXBbbG93ZXJjYXNlTmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKV0gPSBlYXNlT3V0O1xuXG4gICAgZm9yICh2YXIgcCBpbiBlYXNlKSB7XG4gICAgICBfZWFzZU1hcFtsb3dlcmNhc2VOYW1lICsgKHAgPT09IFwiZWFzZUluXCIgPyBcIi5pblwiIDogcCA9PT0gXCJlYXNlT3V0XCIgPyBcIi5vdXRcIiA6IFwiLmluT3V0XCIpXSA9IF9lYXNlTWFwW25hbWUgKyBcIi5cIiArIHBdID0gZWFzZVtwXTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBlYXNlO1xufSxcbiAgICBfZWFzZUluT3V0RnJvbU91dCA9IGZ1bmN0aW9uIF9lYXNlSW5PdXRGcm9tT3V0KGVhc2VPdXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChwKSB7XG4gICAgcmV0dXJuIHAgPCAuNSA/ICgxIC0gZWFzZU91dCgxIC0gcCAqIDIpKSAvIDIgOiAuNSArIGVhc2VPdXQoKHAgLSAuNSkgKiAyKSAvIDI7XG4gIH07XG59LFxuICAgIF9jb25maWdFbGFzdGljID0gZnVuY3Rpb24gX2NvbmZpZ0VsYXN0aWModHlwZSwgYW1wbGl0dWRlLCBwZXJpb2QpIHtcbiAgdmFyIHAxID0gYW1wbGl0dWRlID49IDEgPyBhbXBsaXR1ZGUgOiAxLFxuICAgICAgLy9ub3RlOiBpZiBhbXBsaXR1ZGUgaXMgPCAxLCB3ZSBzaW1wbHkgYWRqdXN0IHRoZSBwZXJpb2QgZm9yIGEgbW9yZSBuYXR1cmFsIGZlZWwuIE90aGVyd2lzZSB0aGUgbWF0aCBkb2Vzbid0IHdvcmsgcmlnaHQgYW5kIHRoZSBjdXJ2ZSBzdGFydHMgYXQgMS5cbiAgcDIgPSAocGVyaW9kIHx8ICh0eXBlID8gLjMgOiAuNDUpKSAvIChhbXBsaXR1ZGUgPCAxID8gYW1wbGl0dWRlIDogMSksXG4gICAgICBwMyA9IHAyIC8gXzJQSSAqIChNYXRoLmFzaW4oMSAvIHAxKSB8fCAwKSxcbiAgICAgIGVhc2VPdXQgPSBmdW5jdGlvbiBlYXNlT3V0KHApIHtcbiAgICByZXR1cm4gcCA9PT0gMSA/IDEgOiBwMSAqIE1hdGgucG93KDIsIC0xMCAqIHApICogX3NpbigocCAtIHAzKSAqIHAyKSArIDE7XG4gIH0sXG4gICAgICBlYXNlID0gdHlwZSA9PT0gXCJvdXRcIiA/IGVhc2VPdXQgOiB0eXBlID09PSBcImluXCIgPyBmdW5jdGlvbiAocCkge1xuICAgIHJldHVybiAxIC0gZWFzZU91dCgxIC0gcCk7XG4gIH0gOiBfZWFzZUluT3V0RnJvbU91dChlYXNlT3V0KTtcblxuICBwMiA9IF8yUEkgLyBwMjsgLy9wcmVjYWxjdWxhdGUgdG8gb3B0aW1pemVcblxuICBlYXNlLmNvbmZpZyA9IGZ1bmN0aW9uIChhbXBsaXR1ZGUsIHBlcmlvZCkge1xuICAgIHJldHVybiBfY29uZmlnRWxhc3RpYyh0eXBlLCBhbXBsaXR1ZGUsIHBlcmlvZCk7XG4gIH07XG5cbiAgcmV0dXJuIGVhc2U7XG59LFxuICAgIF9jb25maWdCYWNrID0gZnVuY3Rpb24gX2NvbmZpZ0JhY2sodHlwZSwgb3ZlcnNob290KSB7XG4gIGlmIChvdmVyc2hvb3QgPT09IHZvaWQgMCkge1xuICAgIG92ZXJzaG9vdCA9IDEuNzAxNTg7XG4gIH1cblxuICB2YXIgZWFzZU91dCA9IGZ1bmN0aW9uIGVhc2VPdXQocCkge1xuICAgIHJldHVybiBwID8gLS1wICogcCAqICgob3ZlcnNob290ICsgMSkgKiBwICsgb3ZlcnNob290KSArIDEgOiAwO1xuICB9LFxuICAgICAgZWFzZSA9IHR5cGUgPT09IFwib3V0XCIgPyBlYXNlT3V0IDogdHlwZSA9PT0gXCJpblwiID8gZnVuY3Rpb24gKHApIHtcbiAgICByZXR1cm4gMSAtIGVhc2VPdXQoMSAtIHApO1xuICB9IDogX2Vhc2VJbk91dEZyb21PdXQoZWFzZU91dCk7XG5cbiAgZWFzZS5jb25maWcgPSBmdW5jdGlvbiAob3ZlcnNob290KSB7XG4gICAgcmV0dXJuIF9jb25maWdCYWNrKHR5cGUsIG92ZXJzaG9vdCk7XG4gIH07XG5cbiAgcmV0dXJuIGVhc2U7XG59OyAvLyBhIGNoZWFwZXIgKGtiIGFuZCBjcHUpIGJ1dCBtb3JlIG1pbGQgd2F5IHRvIGdldCBhIHBhcmFtZXRlcml6ZWQgd2VpZ2h0ZWQgZWFzZSBieSBmZWVkaW5nIGluIGEgdmFsdWUgYmV0d2VlbiAtMSAoZWFzZUluKSBhbmQgMSAoZWFzZU91dCkgd2hlcmUgMCBpcyBsaW5lYXIuXG4vLyBfd2VpZ2h0ZWRFYXNlID0gcmF0aW8gPT4ge1xuLy8gXHRsZXQgeSA9IDAuNSArIHJhdGlvIC8gMjtcbi8vIFx0cmV0dXJuIHAgPT4gKDIgKiAoMSAtIHApICogcCAqIHkgKyBwICogcCk7XG4vLyB9LFxuLy8gYSBzdHJvbmdlciAoYnV0IG1vcmUgZXhwZW5zaXZlIGtiL2NwdSkgcGFyYW1ldGVyaXplZCB3ZWlnaHRlZCBlYXNlIHRoYXQgbGV0cyB5b3UgZmVlZCBpbiBhIHZhbHVlIGJldHdlZW4gLTEgKGVhc2VJbikgYW5kIDEgKGVhc2VPdXQpIHdoZXJlIDAgaXMgbGluZWFyLlxuLy8gX3dlaWdodGVkRWFzZVN0cm9uZyA9IHJhdGlvID0+IHtcbi8vIFx0cmF0aW8gPSAuNSArIHJhdGlvIC8gMjtcbi8vIFx0bGV0IG8gPSAxIC8gMyAqIChyYXRpbyA8IC41ID8gcmF0aW8gOiAxIC0gcmF0aW8pLFxuLy8gXHRcdGIgPSByYXRpbyAtIG8sXG4vLyBcdFx0YyA9IHJhdGlvICsgbztcbi8vIFx0cmV0dXJuIHAgPT4gcCA9PT0gMSA/IHAgOiAzICogYiAqICgxIC0gcCkgKiAoMSAtIHApICogcCArIDMgKiBjICogKDEgLSBwKSAqIHAgKiBwICsgcCAqIHAgKiBwO1xuLy8gfTtcblxuXG5fZm9yRWFjaE5hbWUoXCJMaW5lYXIsUXVhZCxDdWJpYyxRdWFydCxRdWludCxTdHJvbmdcIiwgZnVuY3Rpb24gKG5hbWUsIGkpIHtcbiAgdmFyIHBvd2VyID0gaSA8IDUgPyBpICsgMSA6IGk7XG5cbiAgX2luc2VydEVhc2UobmFtZSArIFwiLFBvd2VyXCIgKyAocG93ZXIgLSAxKSwgaSA/IGZ1bmN0aW9uIChwKSB7XG4gICAgcmV0dXJuIE1hdGgucG93KHAsIHBvd2VyKTtcbiAgfSA6IGZ1bmN0aW9uIChwKSB7XG4gICAgcmV0dXJuIHA7XG4gIH0sIGZ1bmN0aW9uIChwKSB7XG4gICAgcmV0dXJuIDEgLSBNYXRoLnBvdygxIC0gcCwgcG93ZXIpO1xuICB9LCBmdW5jdGlvbiAocCkge1xuICAgIHJldHVybi
1BwIDwgLjUgPyBNYXRoLnBvdyhwICogMiwgcG93ZXIpIC8gMiA6IDEgLSBNYXRoLnBvdygoMSAtIHApICogMiwgcG93ZXIpIC8gMjtcbiAgfSk7XG59KTtcblxuX2Vhc2VNYXAuTGluZWFyLmVhc2VOb25lID0gX2Vhc2VNYXAubm9uZSA9IF9lYXNlTWFwLkxpbmVhci5lYXNlSW47XG5cbl9pbnNlcnRFYXNlKFwiRWxhc3RpY1wiLCBfY29uZmlnRWxhc3RpYyhcImluXCIpLCBfY29uZmlnRWxhc3RpYyhcIm91dFwiKSwgX2NvbmZpZ0VsYXN0aWMoKSk7XG5cbihmdW5jdGlvbiAobiwgYykge1xuICB2YXIgbjEgPSAxIC8gYyxcbiAgICAgIG4yID0gMiAqIG4xLFxuICAgICAgbjMgPSAyLjUgKiBuMSxcbiAgICAgIGVhc2VPdXQgPSBmdW5jdGlvbiBlYXNlT3V0KHApIHtcbiAgICByZXR1cm4gcCA8IG4xID8gbiAqIHAgKiBwIDogcCA8IG4yID8gbiAqIE1hdGgucG93KHAgLSAxLjUgLyBjLCAyKSArIC43NSA6IHAgPCBuMyA/IG4gKiAocCAtPSAyLjI1IC8gYykgKiBwICsgLjkzNzUgOiBuICogTWF0aC5wb3cocCAtIDIuNjI1IC8gYywgMikgKyAuOTg0Mzc1O1xuICB9O1xuXG4gIF9pbnNlcnRFYXNlKFwiQm91bmNlXCIsIGZ1bmN0aW9uIChwKSB7XG4gICAgcmV0dXJuIDEgLSBlYXNlT3V0KDEgLSBwKTtcbiAgfSwgZWFzZU91dCk7XG59KSg3LjU2MjUsIDIuNzUpO1xuXG5faW5zZXJ0RWFzZShcIkV4cG9cIiwgZnVuY3Rpb24gKHApIHtcbiAgcmV0dXJuIHAgPyBNYXRoLnBvdygyLCAxMCAqIChwIC0gMSkpIDogMDtcbn0pO1xuXG5faW5zZXJ0RWFzZShcIkNpcmNcIiwgZnVuY3Rpb24gKHApIHtcbiAgcmV0dXJuIC0oX3NxcnQoMSAtIHAgKiBwKSAtIDEpO1xufSk7XG5cbl9pbnNlcnRFYXNlKFwiU2luZVwiLCBmdW5jdGlvbiAocCkge1xuICByZXR1cm4gcCA9PT0gMSA/IDEgOiAtX2NvcyhwICogX0hBTEZfUEkpICsgMTtcbn0pO1xuXG5faW5zZXJ0RWFzZShcIkJhY2tcIiwgX2NvbmZpZ0JhY2soXCJpblwiKSwgX2NvbmZpZ0JhY2soXCJvdXRcIiksIF9jb25maWdCYWNrKCkpO1xuXG5fZWFzZU1hcC5TdGVwcGVkRWFzZSA9IF9lYXNlTWFwLnN0ZXBzID0gX2dsb2JhbHMuU3RlcHBlZEVhc2UgPSB7XG4gIGNvbmZpZzogZnVuY3Rpb24gY29uZmlnKHN0ZXBzLCBpbW1lZGlhdGVTdGFydCkge1xuICAgIGlmIChzdGVwcyA9PT0gdm9pZCAwKSB7XG4gICAgICBzdGVwcyA9IDE7XG4gICAgfVxuXG4gICAgdmFyIHAxID0gMSAvIHN0ZXBzLFxuICAgICAgICBwMiA9IHN0ZXBzICsgKGltbWVkaWF0ZVN0YXJ0ID8gMCA6IDEpLFxuICAgICAgICBwMyA9IGltbWVkaWF0ZVN0YXJ0ID8gMSA6IDAsXG4gICAgICAgIG1heCA9IDEgLSBfdGlueU51bTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHApIHtcbiAgICAgIHJldHVybiAoKHAyICogX2NsYW1wKDAsIG1heCwgcCkgfCAwKSArIHAzKSAqIHAxO1xuICAgIH07XG4gIH1cbn07XG5fZGVmYXVsdHMuZWFzZSA9IF9lYXNlTWFwW1wicXVhZC5vdXRcIl07XG5cbl9mb3JFYWNoTmFtZShcIm9uQ29tcGxldGUsb25VcGRhdGUsb25TdGFydCxvblJlcGVhdCxvblJldmVyc2VDb21wbGV0ZSxvbkludGVycnVwdFwiLCBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gX2NhbGxiYWNrTmFtZXMgKz0gbmFtZSArIFwiLFwiICsgbmFtZSArIFwiUGFyYW1zLFwiO1xufSk7XG4vKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIENBQ0hFXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuZXhwb3J0IHZhciBHU0NhY2hlID0gZnVuY3Rpb24gR1NDYWNoZSh0YXJnZXQsIGhhcm5lc3MpIHtcbiAgdGhpcy5pZCA9IF9nc0lEKys7XG4gIHRhcmdldC5fZ3NhcCA9IHRoaXM7XG4gIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICB0aGlzLmhhcm5lc3MgPSBoYXJuZXNzO1xuICB0aGlzLmdldCA9IGhhcm5lc3MgPyBoYXJuZXNzLmdldCA6IF9nZXRQcm9wZXJ0eTtcbiAgdGhpcy5zZXQgPSBoYXJuZXNzID8gaGFybmVzcy5nZXRTZXR0ZXIgOiBfZ2V0U2V0dGVyO1xufTtcbi8qXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQU5JTUFUSU9OXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmV4cG9ydCB2YXIgQW5pbWF0aW9uID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gQW5pbWF0aW9uKHZhcnMpIHtcbiAgICB0aGlzLnZhcnMgPSB2YXJzO1xuICAgIHRoaXMuX2RlbGF5ID0gK3ZhcnMuZGVsYXkgfHwgMDtcblxuICAgIGlmICh0aGlzLl9yZXBlYXQgPSB2YXJzLnJlcGVhdCA9PT0gSW5maW5pdHkgPyAtMiA6IHZhcnMucmVwZWF0IHx8IDApIHtcbiAgICAgIC8vIFRPRE86IHJlcGVhdDogSW5maW5pdHkgb24gYSB0aW1lbGluZSdzIGNoaWxkcmVuIG11c3QgZmxhZyB0aGF0IHRpbWVsaW5lIGludGVybmFsbHkgYW5kIGFmZmVjdCBpdHMgdG90YWxEdXJhdGlvbiwgb3RoZXJ3aXNlIGl0J2xsIHN0b3AgaW4gdGhlIG5lZ2F0aXZlIGRpcmVjdGlvbiB3aGVuIHJlYWNoaW5nIHRoZSBzdGFydC5cbiAgICAgIHRoaXMuX3JEZWxheSA9IHZhcnMucmVwZWF0RGVsYXkgfHwgMDtcbiAgICAgIHRoaXMuX3lveW8gPSAhIXZhcnMueW95byB8fCAhIXZhcnMueW95b0Vhc2U7XG4gICAgfVxuXG4gICAgdGhpcy5fdHMgPSAxO1xuXG4gICAgX3NldER1cmF0aW9uKHRoaXMsICt2YXJzLmR1cmF0aW9uLCAxLCAxKTtcblxuICAgIHRoaXMuZGF0YSA9IHZhcnMuZGF0YTtcblxuICAgIGlmIChfY29udGV4dCkge1xuICAgICAgdGhpcy5fY3R4ID0gX2NvbnRleHQ7XG5cbiAgICAgIF9jb250ZXh0LmRhdGEucHVzaCh0aGlzKTtcbiAgICB9XG5cbiAgICBfdGlja2VyQWN0aXZlIHx8IF90aWNrZXIud2FrZSgpO1xuICB9XG5cbiAgdmFyIF9wcm90byA9IEFuaW1hdGlvbi5wcm90b3R5cGU7XG5cbiAgX3Byb3RvLmRlbGF5ID0gZnVuY3Rpb24gZGVsYXkodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgfHwgdmFsdWUgPT09IDApIHtcbiAgICAgIHRoaXMucGFyZW50ICYmIHRoaXMucGFyZW50LnNtb290aENoaWxkVGltaW5nICYmIHRoaXMuc3RhcnRUaW1lKHRoaXMuX3N0YXJ0ICsgdmFsdWUgLSB0aGlzLl9kZWxheSk7XG4gICAgICB0aGlzLl9kZWxheSA9IHZhbHVlO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2RlbGF5O1xuICB9O1xuXG4gIF9wcm90by5kdXJhdGlvbiA9IGZ1bmN0aW9uIGR1cmF0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLnRvdGFsRHVyYXRpb24odGhpcy5fcmVwZWF0ID4gMCA/IHZhbHVlICsgKHZhbHVlICsgdGhpcy5fckRlbGF5KSAqIHRoaXMuX3JlcGVhdCA6IHZhbHVlKSA6IHRoaXMudG90YWxEdXJhdGlvbigpICYmIHRoaXMuX2R1cjtcbiAgfTtcblxuICBfcHJvdG8udG90YWxEdXJhdGlvbiA9IGZ1bmN0aW9uIHRvdGFsRHVyYXRpb24odmFsdWUpIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybi
1B0aGlzLl90RHVyO1xuICAgIH1cblxuICAgIHRoaXMuX2RpcnR5ID0gMDtcbiAgICByZXR1cm4gX3NldER1cmF0aW9uKHRoaXMsIHRoaXMuX3JlcGVhdCA8IDAgPyB2YWx1ZSA6ICh2YWx1ZSAtIHRoaXMuX3JlcGVhdCAqIHRoaXMuX3JEZWxheSkgLyAodGhpcy5fcmVwZWF0ICsgMSkpO1xuICB9O1xuXG4gIF9wcm90by50b3RhbFRpbWUgPSBmdW5jdGlvbiB0b3RhbFRpbWUoX3RvdGFsVGltZSwgc3VwcHJlc3NFdmVudHMpIHtcbiAgICBfd2FrZSgpO1xuXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdFRpbWU7XG4gICAgfVxuXG4gICAgdmFyIHBhcmVudCA9IHRoaXMuX2RwO1xuXG4gICAgaWYgKHBhcmVudCAmJiBwYXJlbnQuc21vb3RoQ2hpbGRUaW1pbmcgJiYgdGhpcy5fdHMpIHtcbiAgICAgIF9hbGlnblBsYXloZWFkKHRoaXMsIF90b3RhbFRpbWUpO1xuXG4gICAgICAhcGFyZW50Ll9kcCB8fCBwYXJlbnQucGFyZW50IHx8IF9wb3N0QWRkQ2hlY2tzKHBhcmVudCwgdGhpcyk7IC8vIGVkZ2UgY2FzZTogaWYgdGhpcyBpcyBhIGNoaWxkIG9mIGEgdGltZWxpbmUgdGhhdCBhbHJlYWR5IGNvbXBsZXRlZCwgZm9yIGV4YW1wbGUsIHdlIG11c3QgcmUtYWN0aXZhdGUgdGhlIHBhcmVudC5cbiAgICAgIC8vaW4gY2FzZSBhbnkgb2YgdGhlIGFuY2VzdG9yIHRpbWVsaW5lcyBoYWQgY29tcGxldGVkIGJ1dCBzaG91bGQgbm93IGJlIGVuYWJsZWQsIHdlIHNob3VsZCByZXNldCB0aGVpciB0b3RhbFRpbWUoKSB3aGljaCB3aWxsIGFsc28gZW5zdXJlIHRoYXQgdGhleSdyZSBsaW5lZCB1cCBwcm9wZXJseSBhbmQgZW5hYmxlZC4gU2tpcCBmb3IgYW5pbWF0aW9ucyB0aGF0IGFyZSBvbiB0aGUgcm9vdCAod2FzdGVmdWwpLiBFeGFtcGxlOiBhIFRpbWVsaW5lTGl
10ZS5leHBvcnRSb290KCkgaXMgcGVyZm9ybWVkIHdoZW4gdGhlcmUncyBhIHBhdXNlZCB0d2VlbiBvbiB0aGUgcm9vdCwgdGhlIGV4cG9ydCB3aWxsIG5vdCBjb21wbGV0ZSB1bnRpbCB0aGF0IHR3ZWVuIGlzIHVucGF1c2VkLCBidXQgaW1hZ2luZSBhIGNoaWxkIGdldHMgcmVzdGFydGVkIGxhdGVyLCBhZnRlciBhbGwgW3VucGF1c2VkXSB0d2VlbnMgaGF2ZSBjb21wbGV0ZWQuIFRoZSBzdGFydCBvZiB0aGF0IGNoaWxkIHdvdWxkIGdldCBwdXNoZWQgb3V0LCBidXQgb25lIG9mIHRoZSBhbmNlc3RvcnMgbWF5IGhhdmUgY29tcGxldGVkLlxuXG4gICAgICB3aGlsZSAocGFyZW50ICYmIHBhcmVudC5wYXJlbnQpIHtcbiAgICAgICAgaWYgKHBhcmVudC5wYXJlbnQuX3RpbWUgIT09IHBhcmVudC5fc3RhcnQgKyAocGFyZW50Ll90cyA+PSAwID8gcGFyZW50Ll90VGltZSAvIHBhcmVudC5fdHMgOiAocGFyZW50LnRvdGFsRHVyYXRpb24oKSAtIHBhcmVudC5fdFRpbWUpIC8gLXBhcmVudC5fdHMpKSB7XG4gICAgICAgICAgcGFyZW50LnRvdGFsVGltZShwYXJlbnQuX3RUaW1lLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5wYXJlbnQgJiYgdGhpcy5fZHAuYXV0b1JlbW92ZUNoaWxkcmVuICYmICh0aGlzLl90cyA+IDAgJiYgX3RvdGFsVGltZSA8IHRoaXMuX3REdXIgfHwgdGhpcy5fdHMgPCAwICYmIF90b3RhbFRpbWUgPiAwIHx8ICF0aGlzLl90RHVyICYmICFfdG90YWxUaW1lKSkge1xuICAgICAgICAvL2lmIHRoZSBhbmltYXRpb24gZG9lc24ndCBoYXZlIGEgcGFyZW50LCBwdXQgaXQgYmFjayBpbnRvIGl0cyBsYXN0IHBhcmVudCAocmVjb3JkZWQgYXMgX2RwIGZvciBleGFjdGx5IGNhc2VzIGxpa2UgdGhpcykuIExpbWl0IHRvIHBhcmVudHMgd2l0aCBhdXRvUmVtb3ZlQ2hpbGRyZW4gKGxpa2UgZ2xvYmFsVGltZWxpbmUpIHNvIHRoYXQgaWYgdGhlIHVzZXIgbWFudWFsbHkgcmVtb3ZlcyBhbiBhbmltYXRpb24gZnJvbSBhIHRpbWVsaW5lIGFuZCB0aGVuIGFsdGVycyBpdHMgcGxheWhlYWQsIGl0IGRvZXNuJ3QgZ2V0IGFkZGVkIGJhY2sgaW4uXG4gICAgICAgIF9hZGRUb1RpbWVsaW5lKHRoaXMuX2RwLCB0aGlzLCB0aGlzLl9zdGFydCAtIHRoaXMuX2RlbGF5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5fdFRpbWUgIT09IF90b3RhbFRpbWUgfHwgIXRoaXMuX2R1ciAmJiAhc3VwcHJlc3NFdmVudHMgfHwgdGhpcy5faW5pdHRlZCAmJiBNYXRoLmFicyh0aGlzLl96VGltZSkgPT09IF90aW55TnVtIHx8ICFfdG90YWxUaW1lICYmICF0aGlzLl9pbml0dGVkICYmICh0aGlzLmFkZCB8fCB0aGlzLl9wdExvb2t1cCkpIHtcbiAgICAgIC8vIGNoZWNrIGZvciBfcHRMb29rdXAgb24gYSBUd2VlbiBpbnN0YW5jZSB0byBlbnN1cmUgaXQgaGFzIGFjdHVhbGx5IGZpbmlzaGVkIGJlaW5nIGluc3RhbnRpYXRlZCwgb3RoZXJ3aXNlIGlmIHRoaXMucmV2ZXJzZSgpIGdldHMgY2FsbGVkIGluIHRoZSBBbmltYXRpb24gY29uc3RydWN0b3IsIGl0IGNvdWxkIHRyaWdnZXIgYSByZW5kZXIoKSBoZXJlIGV2ZW4gdGhvdWdoIHRoZSBfdGFyZ2V0cyB3ZXJlbid0IHBvcHVsYXRlZCwgdGh1cyB3aGVuIF9pbml0KCkgaXMgY2FsbGVkIHRoZXJlIHdvbid0IGJlIGFueSBQcm9wVHdlZW5zIChpdCdsbCBhY3QgbGlrZSB0aGUgdHdlZW4gaXMgbm9uLWZ1bmN0aW9uYWwpXG4gICAgICB0aGlzLl90cyB8fCAodGhpcy5fcFRpbWUgPSBfdG90YWxUaW1lKTsgLy8gb3RoZXJ3aXNlLCBpZiBhbiBhbmltYXRpb24gaXMgcGF1c2VkLCB0aGVuIHRoZSBwbGF5aGVhZCBpcyBtb3ZlZCBiYWNrIHRvIHplcm8sIHRoZW4gcmVzdW1lZCwgaXQnZCByZXZlcnQgYmFjayB0byB0aGUgb3JpZ2luYWwgdGltZSBhdCB0aGUgcGF1c2VcbiAgICAgIC8vaWYgKCF0aGlzLl9sb2NrKSB7IC8vIGF2b2lkIGVuZGxlc3MgcmVjdXJzaW9uIChub3Qgc3VyZSB3ZSBuZWVkIHRoaXMgeWV0IG9yIGlmIGl0J3Mgd29ydGggdGhlIHBlcmZvcm1hbmNlIGhpdClcbiAgICAgIC8vICAgdGhpcy5fbG9jayA9IDE7XG5cbiAgICAgIF9sYXp5U2FmZVJlbmRlcih0aGlzLCBfdG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cyk7IC8vICAgdGhpcy5fbG9jayA9IDA7XG4gICAgICAvL31cblxuICAgI
1H1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIF9wcm90by50aW1lID0gZnVuY3Rpb24gdGltZSh2YWx1ZSwgc3VwcHJlc3NFdmVudHMpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHRoaXMudG90YWxUaW1lKE1hdGgubWluKHRoaXMudG90YWxEdXJhdGlvbigpLCB2YWx1ZSArIF9lbGFwc2VkQ3ljbGVEdXJhdGlvbih0aGlzKSkgJSAodGhpcy5fZHVyICsgdGhpcy5fckRlbGF5KSB8fCAodmFsdWUgPyB0aGlzLl9kdXIgOiAwKSwgc3VwcHJlc3NFdmVudHMpIDogdGhpcy5fdGltZTsgLy8gbm90ZTogaWYgdGhlIG1vZHVsdXMgcmVzdWx0cyBpbiAwLCB0aGUgcGxheWhlYWQgY291bGQgYmUgZXhhY3RseSBhdCB0aGUgZW5kIG9yIHRoZSBiZWdpbm5pbmcsIGFuZCB3ZSBhbHdheXMgZGVmZXIgdG8gdGhlIEVORCB3aXRoIGEgbm9uLXplcm8gdmFsdWUsIG90aGVyd2lzZSBpZiB5b3Ugc2V0IHRoZSB0aW1lKCkgdG8gdGhlIHZlcnkgZW5kIChkdXJhdGlvbigpKSwgaXQgd291bGQgcmVuZGVyIGF0IHRoZSBTVEFSVCFcbiAgfTtcblxuICBfcHJvdG8udG90YWxQcm9ncmVzcyA9IGZ1bmN0aW9uIHRvdGFsUHJvZ3Jlc3ModmFsdWUsIHN1cHByZXNzRXZlbnRzKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLnRvdGFsVGltZSh0aGlzLnRvdGFsRHVyYXRpb24oKSAqIHZhbHVlLCBzdXBwcmVzc0V2ZW50cykgOiB0aGlzLnRvdGFsRHVyYXRpb24oKSA/IE1hdGgubWluKDEsIHRoaXMuX3RUaW1lIC8gdGhpcy5fdER1cikgOiB0aGlzLnJhd1RpbWUoKSA+IDAgPyAxIDogMDtcbiAgfTtcblxuICBfcHJvdG8ucHJvZ3Jlc3MgPSBmdW5jdGlvbiBwcm9ncmVzcyh2YWx1ZSwgc3VwcHJlc3NFdmVudHMpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHRoaXMudG90YWxUaW1lKHRoaXMuZHVyYXRpb24oKSAqICh0aGlzLl95b3lvICYmICEodGhpcy5pdGVyYXRpb24oKSAmIDEpID8gMSAtIHZhbHVlIDogdmFsdWUpICsgX2VsYXBzZWRDeWNsZUR1cmF0aW9uKHRoaXMpLCBzdXBwcmVzc0V2ZW50cykgOiB0aGlzLmR1cmF0aW9uKCkgPyBNYXRoLm1pbigxLCB0aGlzLl90aW1lIC8gdGhpcy5fZHVyKSA6IHRoaXMucmF3VGltZSgpID4gMCA/IDEgOiAwO1xuICB9O1xuXG4gIF9wcm90by5pdGVyYXRpb24gPSBmdW5jdGlvbiBpdGVyYXRpb24odmFsdWUsIHN1cHByZXNzRXZlbnRzKSB7XG4gICAgdmFyIGN5Y2xlRHVyYXRpb24gPSB0aGlzLmR1cmF0aW9uKCkgKyB0aGlzLl9yRGVsYXk7XG5cbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHRoaXMudG90YWxUaW1lKHRoaXMuX3RpbWUgKyAodmFsdWUgLSAxKSAqIGN5Y2xlRHVyYXRpb24sIHN1cHByZXNzRXZlbnRzKSA6IHRoaXMuX3JlcGVhdCA/IF9hbmltYXRpb25DeWNsZSh0aGlzLl90VGltZSwgY3ljbGVEdXJhdGlvbikgKyAxIDogMTtcbiAgfSAvLyBwb3RlbnRpYWwgZnV0dXJlIGFkZGl0aW9uOlxuICAvLyBpc1BsYXlpbmdCYWNrd2FyZHMoKSB7XG4gIC8vIFx0bGV0IGFuaW1hdGlvbiA9IHRoaXMsXG4gIC8vIFx0XHRvcmllbnRhdGlvbiA9IDE7IC8vIDEgPSBmb3J3YXJkLCAtMSA9IGJhY2t3YXJkXG4gIC8vIFx0d2hpbGUgKGFuaW1hdGlvbikge1xuICAvLyBcdFx0b3JpZW50YXRpb24gKj0gYW5pbWF0aW9uLnJldmVyc2VkKCkgfHwgKGFuaW1hdGlvbi5yZXBlYXQoKSAmJiAhKGFuaW1hdGlvbi5pdGVyYXRpb24oKSAmIDEpKSA/IC0xIDogMTtcbiAgLy8gXHRcdGFuaW1hdGlvbiA9IGFuaW1hdGlvbi5wYXJlbnQ7XG4gIC8vIFx0fVxuICAvLyBcdHJldHVybiBvcmllbnRhdGlvbiA8IDA7XG4gIC8vIH1cbiAgO1xuXG4gIF9wcm90by50aW1lU2NhbGUgPSBmdW5jdGlvbiB0aW1lU2NhbGUodmFsdWUsIHN1cHByZXNzRXZlbnRzKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fcnRzID09PSAtX3RpbnlOdW0gP
1yAwIDogdGhpcy5fcnRzOyAvLyByZWNvcmRlZCB0aW1lU2NhbGUuIFNwZWNpYWwgY2FzZTogaWYgc29tZW9uZSBjYWxscyByZXZlcnNlKCkgb24gYW4gYW5pbWF0aW9uIHdpdGggdGltZVNjYWxlIG9mIDAsIHdlIGFzc2lnbiBpdCAtX3RpbnlOdW0gdG8gcmVtZW1iZXIgaXQncyByZXZlcnNlZC5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcnRzID09PSB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdmFyIHRUaW1lID0gdGhpcy5wYXJlbnQgJiYgdGhpcy5fdHMgPyBfcGFyZW50VG9DaGlsZFRvdGFsVGltZSh0aGlzLnBhcmVudC5fdGltZSwgdGhpcykgOiB0aGlzLl90VGltZTsgLy8gbWFrZSBzdXJlIHRvIGRvIHRoZSBwYXJlbnRUb0NoaWxkVG90YWxUaW1lKCkgQkVGT1JFIHNldHRpbmcgdGhlIG5ldyBfdHMgYmVjYXVzZSB0aGUgb2xkIG9uZSBtdXN0IGJlIHVzZWQgaW4gdGhhdCBjYWxjdWxhdGlvbi5cbiAgICAvLyBmdXR1cmUgYWRkaXRpb24/IFVwIHNpZGU6IGZhc3QgYW5kIG1pbmltYWwgZmlsZSBzaXplLiBEb3duIHNpZGU6IG9ubHkgd29ya3Mgb24gdGhpcyBhbmltYXRpb247IGlmIGEgdGltZWxpbmUgaXMgcmV2ZXJzZWQsIGZvciBleGFtcGxlLCBpdHMgY2hpbGRyZW5zJyBvblJldmVyc2Ugd291bGRuJ3QgZ2V0IGNhbGxlZC5cbiAgICAvLygrdmFsdWUgPCAwICYmIHRoaXMuX3J0cyA+PSAwKSAmJiBfY2FsbGJhY2sodGhpcywgXCJvblJldmVyc2VcIiwgdHJ1ZSk7XG4gICAgLy8gcHJpb3JpdGl6ZSByZW5kZXJpbmcgd2hlcmUgdGhlIHBhcmVudCdzIHBsYXloZWFkIGxpbmVzIHVwIGluc3RlYWQgb2YgdGhpcy5fdFRpbWUgYmVjYXVzZSB0aGVyZSBjb3VsZCBiZSBhIHR3ZWVuIHRoYXQncyBhbmltYXRpbmcgYW5vdGhlciB0d2VlbidzIHRpbWVTY2FsZSBpbiB0aGUgc2FtZSByZW5kZXJpbmcgbG9vcCAoc2FtZSBwYXJlbnQpLCB0aHVzIGlmIHRoZSB0aW1lU2NhbGUgdHdlZW4gcmVuZGVycyBmaXJzdCwgaXQgd291bGQgYWx0ZXIgX3N0YXJ0IEJFRk9SRSBfdFRpbWUgd2FzIHNldCBvbiB0aGF0IHRpY2sgKGluIHRoZSByZW5kZXJpbmcgbG9vcCksIGVmZmVjdGl2ZWx5IGZyZWV6aW5nIGl0IHVudGlsIHRoZSB0aW1lU2NhbGUgdHdlZW4gZmluaXNoZXMuXG5cbiAgICB0aGlzLl9ydHMgPSArdmFsdWUgfHwgMDtcbiAgICB0aGlzLl90cyA9IHRoaXMuX3BzIHx8IHZhbHVlID09PSAtX3RpbnlOdW0gP
1yAwIDogdGhpcy5fcnRzOyAvLyBfdHMgaXMgdGhlIGZ1bmN0aW9uYWwgdGltZVNjYWxlIHdoaWNoIHdvdWxkIGJlIDAgaWYgdGhlIGFuaW1hdGlvbiBpcyBwYXVzZWQuXG5cbiAgICB0aGlzLnRvdGFsVGltZShfY2xhbXAoLU1hdGguYWJzKHRoaXMuX2RlbGF5KSwgdGhpcy5fdER1ciwgdFRpbWUpLCBzdXBwcmVzc0V2ZW50cyAhPT0gZmFsc2UpO1xuXG4gICAgX3NldEVuZCh0aGlzKTsgLy8gaWYgcGFyZW50LnNtb290aENoaWxkVGltaW5nIHdhcyBmYWxzZSwgdGhlIGVuZCB0aW1lIGRpZG4ndCBnZXQgdXBkYXRlZCBpbiB0aGUgX2FsaWduUGxheWhlYWQoKSBtZXRob2QsIHNvIGRvIGl0IGhlcmUuXG5cblxuICAgIHJldHVybiBfcmVjYWNoZUFuY2VzdG9ycyh0aGlzKTtcbiAgfTtcblxuICBfcHJvdG8ucGF1c2VkID0gZnVuY3Rpb24gcGF1c2VkKHZhbHVlKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fcHM7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3BzICE9PSB2YWx1ZSkge1xuICAgICAgdGhpcy5fcHMgPSB2YWx1ZTtcblxuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX3BUaW1lID0gdGhpcy5fdFRpbWUgfHwgTWF0aC5tYXgoLXRoaXMuX2RlbGF5LCB0aGlzLnJhd1RpbWUoKSk7IC8vIGlmIHRoZSBwYXVzZSBvY2N1cnMgZHVyaW5nIHRoZSBkZWxheSBwaGFzZSwgbWFrZSBzdXJlIHRoYXQncyBmYWN0b3JlZCBpbiB3aGVuIHJlc3VtaW5nLlxuXG4gICAgICAgIHRoaXMuX3RzID0gdGhpcy5fYWN0ID0gMDsgLy8gX3RzIGlzIHRoZSBmdW5jdGlvbmFsIHRpbWVTY2FsZSwgc28gYSBwYXVzZWQgdHdlZW4gd291bGQgZWZmZWN0aXZlbHkgaGF2ZSBhIHRpbWVTY2FsZSBvZiAwLiBXZSByZWNvcmQgdGhlIFwicmVhbFwiIHRpbWVTY2FsZSBhcyBfcnRzIChyZWNvcmRlZCB0aW1lIHNjYWxlKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX3dha2UoKTtcblxuICAgICAgICB0aGlzLl90cyA9IHRoaXMuX3J0czsgLy9vbmx5IGRlZmVyIHRvIF9wVGltZSAocGF1c2VUaW1lKSBpZiB0VGltZSBpcyB6ZXJvLiBSZW1lbWJlciwgc29tZW9uZSBjb3VsZCBwYXVzZSgpIGFuIGFuaW1hdGlvbiwgdGhlbiBzY3J1YiB0aGUgcGxheWhlYWQgYW5kIHJlc3VtZSgpLiBJZiB0aGUgcGFyZW50IGRvZXNuJ3QgaGF2ZSBzbW9vdGhDaGlsZFRpbWluZywgd2UgcmVuZGVyIGF0IHRoZSByYXdUaW1lKCkgYmVjYXVzZSB0aGUgc3RhcnRUaW1lIHdvbid0IGdldCB1cGRhdGVkLlxuXG4gICAgICAgIHRoaXMudG90YWxUaW1lKHRoaXMucGFyZW50ICYmICF0aGlzLnBhcmVudC5zbW9vdGhDaGlsZFRpbWluZyA/IHRoaXMucmF3VGltZSgpIDogdGhpcy5fdFRpbWUgfHwgdGhpcy5fcFRpbWUsIHRoaXMucHJvZ3Jlc3MoKSA9PT0gMSAmJiBNYXRoLmFicyh0aGlzLl96VGltZSkgIT09IF90aW55TnVtICYmICh0aGlzLl90VGltZSAtPSBfdGlueU51bSkpOyAvLyBlZGdlIGNhc2U6IGFuaW1hdGlvbi5wcm9ncmVzcygxKS5wYXVzZSgpLnBsYXkoKSB3b3VsZG4ndCByZW5kZXIgYWdhaW4gYmVjYXVzZSB0aGUgcGxheWhlYWQgaXMgYWxyZWFkeSBhdCB0aGUgZW5kLCBidXQgdGhlIGNhbGwgdG8gdG90YWxUaW1lKCkgYmVsb3cgd2lsbCBhZGQgaXQgYmFjayB0byBpdHMgcGFyZW50Li4uYW5kIG5vdCByZW1vdmUgaXQgYWdhaW4gKHNpbmNlIHJlbW92aW5nIG9ubHkgaGFwcGVucyB1cG9uIHJlbmRlcmluZyBhdCBhIG5ldyB0aW1lKS4gT2Zmc2V0dGluZyB0aGUgX3RUaW1lIHNsaWdodGx5IGlzIGRvbmUgc2ltcGx5IHRvIGNhdXNlIHRoZSBmaW5hbCByZW5kZXIgaW4gdG90YWxUaW1lKCkgdGhhdCdsbCBwb3AgaXQgb2ZmIGl0cyB0aW1lbGluZSAoaWYgYXV0b1JlbW92ZUNoaWxkcmVuIGlzIHRydWUsIG9mIGNvdXJzZSkuIENoZWNrIHRvIG1ha2Ugc3VyZSBfelRpbWUgaXNuJ3QgLV90aW55TnVtIHRvIGF2b2lkIGFuIGVkZ2UgY2FzZSB3aGVyZSB0aGUgcGxheWhlYWQgaXMgcHVzaGVkIHRvIHRoZSBlbmQgYnV0IElOU0lERSBhIHR3ZWVuL2NhbGxiYWNrLCB0aGUgdGltZWxpbmUgaXRzZWxmIGlzIHBhdXNlZCB0aHVzIGhhbHRpbmcgcmVuZGVyaW5nIGFuZCBsZWF2aW5nIGEgZmV3IHVucmVuZGVyZWQuIFdoZW4gcmVzdW1pbmcsIGl0IHdvdWxkbid0IHJlbmRlciB0aG9zZSBvdGhlcndpc2UuXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgX3Byb3RvLnN0YXJ0VGltZSA9IGZ1bmN0aW9uIHN0YXJ0VGltZSh2YWx1ZSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB0aGlzLl9zdGFydCA9IHZhbHVlO1xuICAgICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50IHx8IHRoaXMuX2RwO1xuICAgICAgcGFyZW50ICYmIChwYXJlbnQuX3NvcnQgfHwgIXRoaXMucGFyZW50KSAmJiBfYWRkVG9UaW1lbGluZShwYXJlbnQsIHRoaXMsIHZhbHVlIC0gdGhpcy5fZGVsYXkpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3N0YXJ0O1xuICB9O1xuXG4gIF9wcm90by5lbmRUaW1lID0gZnVuY3Rpb24gZW5kVGltZShpbmNsdWRlUmVwZWF0cykge1xuICAgIHJldHVybiB0aGlzLl9zdGFydCArIChfaXNOb3RGYWxzZShpbmNsdWRlUmVwZWF0cykgPyB0aGlzLnRvdGFsRHVyYXRpb24oKSA6IHRoaXMuZHVyYXRpb24oKSkgLyBNYXRoLmFicyh0aGlzLl90cyB8fCAxKTtcbiAgfTtcblxuICBfcHJvdG8ucmF3VGltZSA9IGZ1bmN0aW9uIHJhd1RpbWUod3JhcFJlcGVhdHMpIHtcbiAgICB2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnQgfHwgdGhpcy5fZHA7IC8vIF9kcCA9IGRldGFjaGVkIHBhcmVudFxuXG4gICAgcmV0dXJuICFwYXJlbnQgPyB0aGlzLl90VGltZSA6IHdyYXBSZXBlYXRzICYmICghdGhpcy5fdHMgfHwgdGhpcy5fcmVwZWF0ICYmIHRoaXMuX3RpbWUgJiYgdGhpcy50b3RhbFByb2dyZXNzKCkgPCAxKSA/IHRoaXMuX3RUaW1lICUgKHRoaXMuX2R1ciArIHRoaXMuX3JEZWxheSkgOiAhdGhpcy5fdHMgPyB0aGlzLl90VGltZSA6IF9wYXJlbnRUb0NoaWxkVG90YWxUaW1lKHBhcmVudC5yYXdUaW1lKHdyYXBSZXBlYXRzKSwgdGhpcyk7XG4gIH07XG5cbiAgX3Byb3RvLnJldmVydCA9IGZ1bmN0aW9uIHJldmVydChjb25maWcpIHtcbiAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHtcbiAgICAgIGNvbmZpZyA9IF9yZXZlcnRDb25maWc7XG4gICAgfVxuXG4gICAgdmFyIHByZXZJc1JldmVydGluZyA9IF9yZXZlcnRpbmc7XG4gICAgX3JldmVydGluZyA9IGNvbmZpZztcblxuICAgIGlmICh0aGlzLl9pbml0dGVkIHx8IHRoaXMuX3N0YXJ0QXQpIHtcbiAgICAgIHRoaXMudGltZWxpbmUgJiYgdGhpcy50aW1lbGluZS5yZXZlcnQoY29uZmlnKTtcbiAgICAgIHRoaXMudG90YWxUaW1lKC0wLjAxLCBjb25maWcuc3VwcHJlc3NFdmVudHMpO1xuICAgIH1cblxuICAgI
1HRoaXMuZGF0YSAhPT0gXCJuZXN0ZWRcIiAmJiBjb25maWcua2lsbCAhPT0gZmFsc2UgJiYgdGhpcy5raWxsKCk7XG4gICAgX3JldmVydGluZyA9IHByZXZJc1JldmVydGluZztcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8uZ2xvYmFsVGltZSA9IGZ1bmN0aW9uIGdsb2JhbFRpbWUocmF3VGltZSkge1xuICAgIHZhciBhbmltYXRpb24gPSB0aGlzLFxuICAgICAgICB0aW1lID0gYXJndW1lbnRzLmxlbmd0aCA/IHJhd1RpbWUgOiBhbmltYXRpb24ucmF3VGltZSgpO1xuXG4gICAgd2hpbGUgKGFuaW1hdGlvbikge1xuICAgICAgdGltZSA9IGFuaW1hdGlvbi5fc3RhcnQgKyB0aW1lIC8gKE1hdGguYWJzKGFuaW1hdGlvbi5fdHMpIHx8IDEpO1xuICAgICAgYW5pbWF0aW9uID0gYW5pbWF0aW9uLl9kcDtcbiAgICB9XG5cbiAgICByZXR1cm4gIXRoaXMucGFyZW50ICYmIHRoaXMuX3NhdCA/IHRoaXMuX3NhdC5nbG9iYWxUaW1lKHJhd1RpbWUpIDogdGltZTsgLy8gdGhlIF9zdGFydEF0IHR3ZWVucyBmb3IgLmZyb21UbygpIGFuZCAuZnJvbSgpIHRoYXQgaGF2ZSBpbW1lZGlhdGVSZW5kZXIgc2hvdWxkIGFsd2F5cyBiZSBGSVJTVCBpbiB0aGUgdGltZWxpbmUgKGltcG9ydGFudCBmb3IgY29udGV4dC5yZXZlcnQoKSkuIFwiX3NhdFwiIHN0YW5kcyBmb3IgX3N0YXJ0QXRUd2VlbiwgcmVmZXJyaW5nIHRvIHRoZSBwYXJlbnQgdHdlZW4gdGhhdCBjcmVhdGVkIHRoZSBfc3RhcnRBdC4gV2UgbXVzdCBkaXNjZXJuIGlmIHRoYXQgdHdlZW4gaGFkIGltbWVkaWF0ZVJlbmRlciBzbyB0aGF0IHdlIGNhbiBrbm93IHdoZXRoZXIgb3Igbm90IHRvIHByaW9yaXRpemUgaXQgaW4gcmV2ZXJ0KCkuXG4gIH07XG5cbiAgX3Byb3RvLnJlcGVhdCA9IGZ1bmN0aW9uIHJlcGVhdCh2YWx1ZSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB0aGlzLl9yZXBlYXQgPSB2YWx1ZSA9PT0gSW5maW5pdHkgPyAtMiA6IHZhbHVlO1xuICAgICAgcmV0dXJuIF9vblVwZGF0ZVRvdGFsRHVyYXRpb24odGhpcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3JlcGVhdCA9PT0gLTIgPyBJbmZpbml0eSA6IHRoaXMuX3JlcGVhdDtcbiAgfTtcblxuICBfcHJvdG8ucmVwZWF0RGVsYXkgPSBmdW5jdGlvbiByZXBlYXREZWxheSh2YWx1ZSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB2Y
1XIgdGltZSA9IHRoaXMuX3RpbWU7XG4gICAgICB0aGlzLl9yRGVsYXkgPSB2YWx1ZTtcblxuICAgICAgX29uVXBkYXRlVG90YWxEdXJhdGlvbih0aGlzKTtcblxuICAgICAgcmV0dXJuIHRpbWUgPyB0aGlzLnRpbWUodGltZSkgOiB0aGlzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9yRGVsYXk7XG4gIH07XG5cbiAgX3Byb3RvLnlveW8gPSBmdW5jdGlvbiB5b3lvKHZhbHVlKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX3lveW8gPSB2YWx1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl95b3lvO1xuICB9O1xuXG4gIF9wcm90by5zZWVrID0gZnVuY3Rpb24gc2Vlayhwb3NpdGlvbiwgc3VwcHJlc3NFdmVudHMpIHtcbiAgICByZXR1cm4gdGhpcy50b3RhbFRpbWUoX3BhcnNlUG9zaXRpb24odGhpcywgcG9zaXRpb24pLCBfaXNOb3RGYWxzZShzdXBwcmVzc0V2ZW50cykpO1xuICB9O1xuXG4gIF9wcm90by5yZXN0YXJ0ID0gZnVuY3Rpb24gcmVzdGFydChpbmNsdWRlRGVsYXksIHN1cHByZXNzRXZlbnRzKSB7XG4gICAgcmV0dXJuIHRoaXMucGxheSgpLnRvdGFsVGltZShpbmNsdWRlRGVsYXkgPyAtdGhpcy5fZGVsYXkgOiAwLCBfaXNOb3RGYWxzZShzdXBwcmVzc0V2ZW50cykpO1xuICB9O1xuXG4gIF9wcm90by5wbGF5ID0gZnVuY3Rpb24gcGxheShmcm9tLCBzdXBwcmVzc0V2ZW50cykge1xuICAgIGZyb20gIT0gbnVsbCAmJiB0aGlzLnNlZWsoZnJvbSwgc3VwcHJlc3NFdmVudHMpO1xuICAgIHJldHVybiB0aGlzLnJldmVyc2VkKGZhbHNlKS5wYXVzZWQoZmFsc2UpO1xuICB9O1xuXG4gIF9wcm90by5yZXZlcnNlID0gZnVuY3Rpb24gcmV2ZXJzZShmcm9tLCBzdXBwcmVzc0V2ZW50cykge1xuICAgIGZyb20gIT0gbnVsbCAmJiB0aGlzLnNlZWsoZnJvbSB8fCB0aGlzLnRvdGFsRHVyYXRpb24oKSwgc3VwcHJlc3NFdmVudHMpO1xuICAgIHJldHVybiB0aGlzLnJldmVyc2VkKHRydWUpLnBhdXNlZChmYWxzZSk7XG4gIH07XG5cbiAgX3Byb3RvLnBhdXNlID0gZnVuY3Rpb24gcGF1c2UoYXRUaW1lLCBzdXBwcmVzc0V2ZW50cykge1xuICAgIGF0VGltZSAhPSBudWxsICYmIHRoaXMuc2VlayhhdFRpbWUsIHN1cHByZXNzRXZlbnRzKTtcbiAgICByZXR1cm4gdGhpcy5wYXVzZWQodHJ1ZSk7XG4gIH07XG5cbiAgX3Byb3RvLnJlc3VtZSA9IGZ1bmN0aW9uIHJlc3VtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wYXVzZWQoZmFsc2UpO1xuICB9O1xuXG4gIF9wcm90by5yZXZlcnNlZCA9IGZ1bmN0aW9uIHJldmVyc2VkKHZhbHVlKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICEhdmFsdWUgIT09IHRoaXMucmV2ZXJzZWQoKSAmJiB0aGlzLnRpbWVTY2FsZSgtdGhpcy5fcnRzIHx8ICh2YWx1ZSA/IC1fdGlueU51bSA6IDApKTsgLy8gaW4gY2FzZSB0aW1lU2NhbGUgaXMgemVybywgcmV2ZXJzaW5nIHdvdWxkIGhhdmUgbm8gZWZmZWN0IHNvIHdlIHVzZSBfdGlueU51bS5cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3J0cyA8IDA7XG4gIH07XG5cbiAgX3Byb3RvLmludmFsaWRhdGUgPSBmdW5jdGlvbiBpbnZhbGlkYXRlKCkge1xuICAgIHRoaXMuX2luaXR0ZWQgPSB0aGlzLl9hY3QgPSAwO1xuICAgIHRoaXMuX3pUaW1lID0gLV90aW55TnVtO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIF9wcm90by5pc0FjdGl2ZSA9IGZ1bmN0aW9uIGlzQWN0aXZlKCkge1xuICAgIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudCB8fCB0aGlzLl9kcCxcbiAgICAgICAgc3RhcnQgPSB0aGlzLl9zdGFydCxcbiAgICAgICAgcmF3VGltZTtcbiAgICByZXR1cm4gISEoIXBhcmVudCB8fCB0aGlzLl90cyAmJiB0aGlzLl9pbml0dGVkICYmIHBhcmVudC5pc0FjdGl2ZSgpICYmIChyYXdUaW1lID0gcGFyZW50LnJhd1RpbWUodHJ1ZSkpID49IHN0YXJ0ICYmIHJhd1RpbWUgPCB0aGlzLmVuZFRpbWUodHJ1ZSkgLSBfdGlueU51bSk7XG4gIH07XG5cbiAgX3Byb3RvLmV2ZW50Q2FsbGJhY2sgPSBmdW5jdGlvbiBldmVudENhbGxiYWNrKHR5cGUsIGNhbGxiYWNrLCBwYXJhbXMpIHtcbiAgICB2YXIgdmFycyA9IHRoaXMudmFycztcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgaWYgKCFjYWxsYmFjaykge1xuICAgICAgICBkZWxldGUgdmFyc1t0eXBlXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhcnNbdHlwZV0gPSBjYWxsYmFjaztcbiAgICAgICAgcGFyYW1zICYmICh2YXJzW3R5cGUgKyBcIlBhcmFtc1wiXSA9IHBhcmFtcyk7XG4gICAgICAgIHR5cGUgPT09IFwib25VcGRhdGVcIiAmJiAodGhpcy5fb25VcGRhdGUgPSBjYWxsYmFjayk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHJldHVybiB2YXJzW3R5cGVdO1xuICB9O1xuXG4gIF9wcm90by50aGVuID0gZnVuY3Rpb24gdGhlbihvbkZ1bGZpbGxlZCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgIHZhciBmID0gX2lzRnVuY3Rpb24ob25GdWxmaWxsZWQpID8gb25GdWxmaWxsZWQgOiBfcGFzc1Rocm91Z2gsXG4gICAgICAgICAgX3Jlc29sdmUgPSBmdW5jdGlvbiBfcmVzb2x2ZSgpIHtcbiAgICAgICAgdmFyIF90aGVuID0gc2VsZi50aGVuO1xuICAgICAgICBzZWxmLnRoZW4gPSBudWxsOyAvLyB0ZW1wb3JhcmlseSBudWxsIHRoZSB0aGVuKCkgbWV0aG9kIHRvIGF2b2lkIGFuIGluZmluaXRlIGxvb3AgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ3JlZW5zb2NrL0dTQVAvaXNzdWVzLzMyMilcblxuICAgICAgICBfaXNGdW5jdGlvbihmKSAmJiAoZiA9IGYoc2VsZikpICYmIChmLnRoZW4gfHwgZiA9PT0gc2VsZikgJiYgKHNlbGYudGhlbiA9IF90aGVuKTtcbiAgICAgICAgcmVzb2x2ZShmKTtcbiAgICAgICAgc2VsZi50aGVuID0gX3RoZW47XG4gICAgICB9O1xuXG4gICAgICBpZiAoc2VsZi5faW5pdHRlZCAmJiBzZWxmLnRvdGFsUHJvZ3Jlc3MoKSA9PT0gMSAmJiBzZWxmLl90cyA+PSAwIHx8ICFzZWxmLl90VGltZSAmJi
1BzZWxmLl90cyA8IDApIHtcbiAgICAgICAgX3Jlc29sdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGYuX3Byb20gPSBfcmVzb2x2ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICBfcHJvdG8ua2lsbCA9IGZ1bmN0aW9uIGtpbGwoKSB7XG4gICAgX2ludGVycnVwdCh0aGlzKTtcbiAgfTtcblxuICByZXR1cm4gQW5pbWF0aW9uO1xufSgpO1xuXG5fc2V0RGVmYXVsdHMoQW5pbWF0aW9uLnByb3RvdHlwZSwge1xuICBfdGltZTogMCxcbiAgX3N0YXJ0OiAwLFxuICBfZW5kOiAwLFxuICBfdFRpbWU6IDAsXG4gIF90RHVyOiAwLFxuICBfZGlydHk6IDAsXG4gIF9yZXBlYXQ6IDAsXG4gIF95b3lvOiBmYWxzZSxcbiAgcGFyZW50OiBudWxsLFxuICBfaW5pdHRlZDogZmFsc2UsXG4gIF9yRGVsYXk6IDAsXG4gIF90czogMSxcbiAgX2RwOiAwLFxuICByYXRpbzogMCxcbiAgX3pUaW1lOiAtX3RpbnlOdW0sXG4gIF9wcm9tOiAwLFxuICBfcHM6IGZhbHNlLFxuICBfcnRzOiAxXG59KTtcbi8qXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBUSU1FTElORVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuZXhwb3J0IHZhciBUaW1lbGluZSA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX0FuaW1hdGlvbikge1xuICBfaW5oZXJpdHNMb29zZShUaW1lbGluZSwgX0FuaW1hdGlvbik7XG5cbiAgZnVuY3Rpb24gVGltZWxpbmUodmFycywgcG9zaXRpb24pIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBpZiAodmFycyA9PT0gdm9pZCAwKSB7XG4gICAgICB2Y
1XJzID0ge307XG4gICAgfVxuXG4gICAgX3RoaXMgPSBfQW5pbWF0aW9uLmNhbGwodGhpcywgdmFycykgfHwgdGhpcztcbiAgICBfdGhpcy5sYWJlbHMgPSB7fTtcbiAgICBfdGhpcy5zbW9vdGhDaGlsZFRpbWluZyA9ICEhdmFycy5zbW9vdGhDaGlsZFRpbWluZztcbiAgICBfdGhpcy5hdXRvUmVtb3ZlQ2hpbGRyZW4gPSAhIXZhcnMuYXV0b1JlbW92ZUNoaWxkcmVuO1xuICAgIF90aGlzLl9zb3J0ID0gX2lzTm90RmFsc2UodmFycy5zb3J0Q2hpbGRyZW4pO1xuICAgIF9nbG9iYWxUaW1lbGluZSAmJiBfYWRkVG9UaW1lbGluZSh2YXJzLnBhcmVudCB8fCBfZ2xvYmFsVGltZWxpbmUsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBwb3NpdGlvbik7XG4gICAgdmFycy5yZXZlcnNlZCAmJiBfdGhpcy5yZXZlcnNlKCk7XG4gICAgdmFycy5wYXVzZWQgJiYgX3RoaXMucGF1c2VkKHRydWUpO1xuICAgIHZhcnMuc2Nyb2xsVHJpZ2dlciAmJiBfc2Nyb2xsVHJpZ2dlcihfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgdmFycy5zY3JvbGxUcmlnZ2VyKTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICB2YXIgX3Byb3RvMiA9IFRpbWVsaW5lLnByb3RvdHlwZTtcblxuICBfcHJvdG8yLnRvID0gZnVuY3Rpb24gdG8odGFyZ2V0cywgdmFycywgcG9zaXRpb24pIHtcbiAgICBfY3JlYXRlVHdlZW5UeXBlKDAsIGFyZ3VtZW50cywgdGhpcyk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLmZyb20gPSBmdW5jdGlvbiBmcm9tKHRhcmdldHMsIHZhcnMsIHBvc2l0aW9uKSB7XG4gICAgX2NyZWF0ZVR3ZWVuVHlwZSgxLCBhcmd1bWVudHMsIHRoaXMpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgX3Byb3RvMi5mcm9tVG8gPSBmdW5jdGlvbiBmcm9tVG8odGFyZ2V0cywgZnJvbVZhcnMsIHRvVmFycywgcG9zaXRpb24pIHtcbiAgICBfY3JlYXRlVHdlZW5UeXBlKDIsIGFyZ3VtZW50cywgdGhpcyk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLnNldCA9IGZ1bmN0aW9uIHNldCh0YXJnZXRzLCB2YXJzLCBwb3NpdGlvbikge1xuICAgIHZhcnMuZHVyYXRpb24gPSAwO1xuICAgIHZhcnMucGFyZW50ID0gdGhpcztcbiAgICBfaW5oZXJpdERlZmF1bHRzKHZhcnMpLnJlcGVhdERlbGF5IHx8ICh2YXJzLnJlcGVhdCA9IDApO1xuICAgIHZhcnMuaW1tZWRpYXRlUmVuZGVyID0gISF2YXJzLmltbWVkaWF0ZVJlbmRlcjtcbiAgICBuZXcgVHdlZW4odGFyZ2V0cywgdmFycywgX3BhcnNlUG9zaXRpb24odGhpcywgcG9zaXRpb24pLCAxKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLmNhbGwgPSBmdW5jdGlvbiBjYWxsKGNhbGxiYWNrLCBwYXJhbXMsIHBvc2l0aW9uKSB7XG4gICAgcmV0dXJuIF9hZGRUb1RpbWVsaW5lKHRoaXMsIFR3ZWVuLmRlbGF5ZWRDYWxsKDAsIGNhbGxiYWNrLCBwYXJhbXMpLCBwb3NpdGlvbik7XG4gIH0gLy9PTkxZIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5ISBNYXliZSBkZWxldGU/XG4gIDtcblxuICBfcHJvdG8yLnN0YWdnZXJUbyA9IGZ1bmN0aW9uIHN0YWdnZXJUbyh0YXJnZXRzLCBkdXJhdGlvbiwgdmFycywgc3RhZ2dlciwgcG9zaXRpb24sIG9uQ29tcGxldGVBbGwsIG9uQ29tcGxldGVBbGxQYXJhbXMpIHtcbiAgICB2YXJzLmR1cmF0aW9uID0gZHVyYXRpb247XG4gICAgdmFycy5zdGFnZ2VyID0gdmFycy5zdGFnZ2VyIHx8IHN0YWdnZXI7XG4gICAgdmFycy5vbkNvbXBsZXRlID0gb25Db21wbGV0ZUFsbDtcbiAgICB2YXJzLm9uQ29tcGxldGVQYXJhbXMgPSBvbkNvbXBsZXRlQWxsUGFyYW1zO1xuICAgIHZhcnMucGFyZW50ID0gdGhpcztcbiAgICBuZXcgVHdlZW4odGFyZ2V0cywgdmFycywgX3BhcnNlUG9zaXRpb24odGhpcywgcG9zaXRpb24pKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLnN0YWdnZXJGcm9tID0gZnVuY3Rpb24gc3RhZ2dlckZyb20odGFyZ2V0cywgZHVyYXRpb24sIHZhcnMsIHN0YWdnZXIsIHBvc2l0aW9uLCBvbkNvbXBsZXRlQWxsLCBvbkNvbXBsZXRlQWxsUGFyYW1zKSB7XG4gICAgdmFycy5ydW5CYWNrd2FyZHMgPSAxO1xuICAgIF9pbmhlcml0RGVmYXVsdHModmFycykuaW1tZWRpYXRlUmVuZGVyID0gX2lzTm90RmFsc2UodmFycy5pbW1lZGlhdGVSZW5kZXIpO1xuICAgIHJldHVybiB0aGlzLnN0YWdnZXJUbyh0YXJnZXRzLCBkdXJhdGlvbiwgdmFycywgc3RhZ2dlciwgcG9zaXRpb24sIG9uQ29tcGxldGVBbGwsIG9uQ29tcGxldGVBbGxQYXJhbXMpO1xuICB9O1xuXG4gIF9wcm90bzIuc3RhZ2dlckZyb21UbyA9IGZ1bmN0aW9uIHN0YWdnZXJGcm9tVG8odGFyZ2V0cywgZHVyYXRpb24sIGZyb21WYXJzLCB0b1ZhcnMsIHN0YWdnZXIsIHBvc2l0aW9uLCBvbkNvbXBsZXRlQWxsLCBvbkNvbXBsZXRlQWxsUGFyYW1zKSB7XG4gICAgdG9WYXJzLnN0YXJ0QXQgPSBmcm9tVmFycztcbiAgICBfaW5oZXJpdERlZmF1bHRzKHRvVmFycykuaW1tZWRpYXRlUmVuZGVyID0gX2lzTm90RmFsc2UodG9WYXJzLmltbWVkaWF0ZVJlbmRlcik7XG4gICAgcmV0dXJuIHRoaXMuc3RhZ2dlclRvKHRhcmdldHMsIGR1cmF0aW9uLCB0b1ZhcnMsIHN0YWdnZXIsIHBvc2l0aW9uLCBvbkNvbXBsZXRlQWxsLCBvbkNvbXBsZXRlQWxsUGFyYW1zKTtcbiAgfTtcblxuICBfcHJvdG8yLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcih0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSkge1xuICAgIHZhciBwcmV2VGltZSA9IHRoaXMuX3RpbWUsXG4gICAgICAgIHREdXIgPSB0aGlzLl9kaXJ0eSA/IHRoaXMudG90YWxEdXJhdGlvbigpIDogdGhpcy5fdER1cixcbiAgICAgICAgZHVyID0gdGhpcy5fZHVyLFxuICAgICAgICB0VGltZSA9IHRvdGFsVGltZSA8PSAwID8gMCA6IF9yb3VuZFByZWNpc2UodG90YWxUaW1lKSxcbiAgICAgICAgLy8gaWYgYSBwYXVzZWQgdGltZWxpbmUgaXMgcmVzdW1lZCAob3IgaXRzIF9zdGFydCBpcyB1cGRhdGVkIGZvciBhbm90aGVyIHJlYXNvbi4uLndoaWNoIHJvdW5kcyBpdCksIHRoYXQgY291bGQgcmVzdWx0IGluIHRoZSBwbGF5aGVhZCBzaGlmdGluZyBhICoqdGlueSoqIGFtb3VudCBhbmQgYS
1B6ZXJvLWR1cmF0aW9uIGNoaWxkIGF0IHRoYXQgc3BvdCBtYXkgZ2V0IHJlbmRlcmVkIGF0IGEgZGlmZmVyZW50IHJhdGlvLCBsaWtlIGl0cyB0b3RhbFRpbWUgaW4gcmVuZGVyKCkgbWF5IGJlIDFlLTE3IGluc3RlYWQgb2YgMCwgZm9yIGV4YW1wbGUuXG4gICAgY3Jvc3NpbmdTdGFydCA9IHRoaXMuX3pUaW1lIDwgMCAhPT0gdG90YWxUaW1lIDwgMCAmJiAodGhpcy5faW5pdHRlZCB8fCAhZHVyKSxcbiAgICAgICAgdGltZSxcbiAgICAgICAgY2hpbGQsXG4gICAgICAgIG5leHQsXG4gICAgICAgIGl0ZXJhdGlvbixcbiAgICAgICAgY3ljbGVEdXJhdGlvbixcbiAgICAgICAgcHJldlBhdXNlZCxcbiAgICAgICAgcGF1c2VUd2VlbixcbiAgICAgICAgdGltZVNjYWxlLFxuICAgICAgICBwcmV2U3RhcnQsXG4gICAgICAgIHByZXZJdGVyYXRpb24sXG4gICAgICAgIHlveW8sXG4gICAgICAgIGlzWW95bztcbiAgICB0aGlzICE9PSBfZ2xvYmFsVGltZWxpbmUgJiYgdFRpbWUgPiB0RHVyICYmIHRvdGFsVGltZSA+PSAwICYmICh0VGltZSA9IHREdXIpO1xuXG4gICAgaWYgKHRUaW1lICE9PSB0aGlzLl90VGltZSB8fCBmb3JjZSB8fCBjcm9zc2luZ1N0YXJ0KSB7XG4gICAgICBpZiAocHJldlRpbWUgIT09IHRoaXMuX3RpbWUgJiYgZHVyKSB7XG4gICAgICAgIC8vaWYgdG90YWxEdXJhdGlvbigpIGZpbmRzIGEgY2hpbGQgd2l0aCBhIG5lZ2F0aXZlIHN0YXJ0VGltZSBhbmQgc21vb3RoQ2hpbGRUaW1pbmcgaXMgdHJ1ZSwgdGhpbmdzIGdldCBzaGlmdGVkIGFyb3VuZCBpbnRlcm5hbGx5IHNvIHdlIG5lZWQgdG8gYWRqdXN0IHRoZSB0aW1lIGFjY29yZGluZ2x5LiBGb3IgZXhhbXBsZSwgaWYgYSB0d2VlbiBzdGFydHMgYXQgLTMwIHdlIG11c3Qgc2hpZnQgRVZFUllUSElORyBmb3J3YXJkIDMwIHNlY29uZHMgYW5kIG1vdmUgdGhpcyB0aW1lbGluZSdzIHN0YXJ0VGltZSBiYWNrd2FyZCBieSAzMCBzZWNvbmRzIHNvIHRoYXQgdGhpbmdzIGFsaWduIHdpdGggdGhlIHBsYXloZWFkIChubyBqdW1wKS5cbiAgICAgICAgdFRpbWUgKz0gdGhpcy5fdGltZSAtIHByZXZUaW1lO1xuICAgICAgICB0b3RhbFRpbWUgKz0gdGhpcy5fdGltZSAtIHByZXZUaW1lO1xuICAgICAgfVxuXG4gICAgICB0aW1lID0gdFRpbWU7XG4gICAgICBwcmV2U3RhcnQgPSB0aGlzLl9zdGFydDtcbiAgICAgIHRpbWVTY2FsZSA9IHRoaXMuX3RzO1xuICAgICAgcHJldlBhdXNlZCA9ICF0aW1lU2NhbGU7XG5cbiAgICAgIGlmIChjcm9zc2luZ1N0YXJ0KSB7XG4gICAgICAgIGR1ciB8fCAocHJldlRpbWUgPSB0aGlzLl96VGltZSk7IC8vd2hlbiB0aGUgcGxheWhlYWQgYXJyaXZlcyBhdCBFWEFDVExZIHRpbWUgMCAocmlnaHQgb24gdG9wKSBvZiBhIHplcm8tZHVyYXRpb24gdGltZWxpbmUsIHdlIG5lZWQgdG8gZGlzY2VybiBpZiBldmVudHMgYXJlIHN1cHByZXNzZWQgc28gdGhhdCB3aGVuIHRoZSBwbGF5aGVhZCBtb3ZlcyBhZ2FpbiAobmV4dCB0aW1lKSwgaXQnbGwgdHJpZ2dlciB0aGUgY2FsbGJhY2suIElmIGV2ZW50cyBhcmUgTk9UIHN1cHByZXNzZWQsIG9idmlvdXNseSB0aGUgY2FsbGJhY2sgd291bGQgYmUgdHJpZ2dlcmVkIGluIHRoaXMgcmVuZGVyLiBCYXNpY2FsbHksIHRoZSBjYWxsYmFjayBzaG91bGQgZmlyZSBlaXRoZXIgd2hlbiB0aGUgcGxheWhlYWQgQVJSSVZFUyBvciBMRUFWRVMgdGhpcyBleGFjdCBzcG90LCBub3QgYm90aC4gSW1hZ2luZSBkb2luZyBhIHRpbWVsaW5lLnNlZWsoMCkgYW5kIHRoZXJlJ3MgYSBjYWxsYmFjayB0aGF0IHNpdHMgYXQgMC4gU2luY2UgZXZlbnRzIGFyZSBzdXBwcmVzc2VkIG9uIHRoYXQgc2VlaygpIGJ5IGRlZmF1bHQsIG5vdGhpbmcgd2lsbCBmaXJlLCBidXQgd2hlbiB0aGUgcGxheWhlYWQgbW92ZXMgb2ZmIG9mIHRoYXQgcG9zaXRpb24sIHRoZSBjYWxsYmFjayBzaG91bGQgZmlyZS4gVGhpcyBiZWhhdmlvciBpcyB3aGF0IHBlb3BsZSBpbnR1aXRpdmVseSBleHBlY3QuXG5cbiAgICAgICAgKHRvdGFsVGltZSB8fCAhc3VwcHJlc3NFdmVudHMpICYmICh0aGlzLl96VGltZSA9IHRvdGFsVGltZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9yZXBlYXQpIHtcbiAgICAgICAgLy9hZGp1c3QgdGhlIHRpbWUgZm9yIHJlcGVhdHMgYW5kIHlveW9zXG4gICAgICAgIHlveW8gPSB0aGlzLl95b3lvO1xuICAgICAgICBjeWNsZUR1cmF0aW9uID0gZHVyICsgdGhpcy5fckRlbGF5O1xuXG4gICAgICAgIGlmICh0aGlzLl9yZXBlYXQgPCAtMSAmJiB0b3RhbFRpbWUgPCAwKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMudG90YWxUaW1lKGN5Y2xlRHVyYXRpb24gKiAxMDAgKyB0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aW1lID0gX3JvdW5kUHJlY2lzZSh0VGltZSAlIGN5Y2xlRHVyYXRpb24pOyAvL3JvdW5kIHRvIGF2b2lkIGZsb2F0aW5nIHBvaW50IGVycm9ycy4gKDQgJSAwLjggc2hvdWxkIGJlIDAgYnV0IHNvbWUgYnJvd3NlcnMgcmVwb3J0IGl0IGFzIDAuNzk5OTk5OTkhKVxuXG4gICAgICAgIGlmICh0VGltZSA9PT0gdER1cikge1xuICAgICAgICAgIC8vIHRoZSB0RHVyID09PSB0VGltZSBpcyBmb3IgZWRnZSBjYXNlcyB3aGVyZSB0aGVyZSdzIGEgbGVuZ3RoeSBkZWNpbWFsIG9uIHRoZSBkdXJhdGlvbiBhbmQgaXQgbWF5IHJlYWNoIHRoZSB2ZXJ5IGVuZCBidXQgdGhlIHRpbWUgaXMgcmVuZGVyZWQgYXMgbm90LXF1aXRlLXRoZXJlIChyZW1lbWJlciwgdER1ciBpcyByb3VuZGVkIHRvIDQgZGVjaW1hbHMgd2hlcmVhcyBkdXIgaXNuJ3QpXG4gICAgICAgICAgaXRlcmF0aW9uID0gdGhpcy5fcmVwZWF0O1xuICAgICAgICAgIHRpbWUgPSBkdXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlcmF0aW9uID0gfn4odFRpbWUgLyBjeWNsZUR1cmF0aW9uKTtcblxuICAgICAgICAgIGlmIChpdGVyYXRpb24gJiYgaXRlcmF0aW9uID09PSB0VGltZSAvIGN5Y2xlRHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRpbWUgPSBkdXI7XG4gICAgICAgICAgICBpdGVyYXRpb24tLTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aW1lID4gZHVyICYmICh0aW1lID0gZHVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgI
1HByZXZJdGVyYXRpb24gPSBfYW5pbWF0aW9uQ3ljbGUodGhpcy5fdFRpbWUsIGN5Y2xlRHVyYXRpb24pO1xuICAgICAgICAhcHJldlRpbWUgJiYgdGhpcy5fdFRpbWUgJiYgcHJldkl0ZXJhdGlvbiAhPT0gaXRlcmF0aW9uICYmIHRoaXMuX3RUaW1lIC0gcHJldkl0ZXJhdGlvbiAqIGN5Y2xlRHVyYXRpb24gLSB0aGlzLl9kdXIgPD0gMCAmJiAocHJldkl0ZXJhdGlvbiA9IGl0ZXJhdGlvbik7IC8vIGVkZ2UgY2FzZSAtIGlmIHNvbWVvbmUgZG9lcyBhZGRQYXVzZSgpIGF0IHRoZSB2ZXJ5IGJlZ2lubmluZyBvZiBhIHJlcGVhdGluZyB0aW1lbGluZSwgdGhhdCBwYXVzZSBpcyB0ZWNobmljYWxseSBhdCB0aGUgc2FtZSBzcG90IGFzIHRoZSBlbmQgd2hpY2ggY2F1c2VzIHRoaXMuX3RpbWUgdG8gZ2V0IHNldCB0byAwIHdoZW4gdGhlIHRvdGFsVGltZSB3b3VsZCBub3JtYWxseSBwbGFjZSB0aGUgcGxheWhlYWQgYXQgdGhlIGVuZC4gU2VlIGh0dHBzOi8vZ3NhcC5jb20vZm9ydW1zL3RvcGljLzIzODIzLWNsb3NpbmctbmF2LWFuaW1hdGlvbi1ub3Qtd29ya2luZy1vbi1pZS1hbmQtaXBob25lLTYtbWF5YmUtb3RoZXItb2xkZXItYnJvd3Nlci8/dGFiPWNvbW1lbnRzI2NvbW1lbnQtMTEzMDA1IGFsc28sIHRoaXMuX3RUaW1lIC0gcHJldkl0ZXJhdGlvbiAqIGN5Y2xlRHVyYXRpb24gLSB0aGlzLl9kdXIgPD0gMCBqdXN0IGNoZWNrcyB0byBtYWtlIHN1cmUgaXQgd2Fzbid0IHByZXZpb3VzbHkgaW4gdGhlIFwicmVwZWF0RGVsYXlcIiBwb3J0aW9uXG5cbiAgICAgICAgaWYgKHlveW8gJiYgaXRlcmF0aW9uICYgMSkge1xuICAgICAgICAgIHRpbWUgPSBkdXIgLSB0aW1lO1xuICAgICAgICAgIGlzWW95byA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgLypcbiAgICAgICAgbWFrZSBzdXJlIGNoaWxkcmVuIGF0IHRoZSBlbmQvYmVnaW5uaW5nIG9mIHRoZSB0aW1lbGluZSBhcmUgcmVuZGVyZWQgcHJvcGVybHkuIElmLCBmb3IgZXhhbXBsZSxcbiAgICAgICAgYSAzLXNlY29uZCBsb25nIHRpbWVsaW5lIHJlbmRlcmVkIGF0IDIuOSBzZWNvbmRzIHByZXZpb3VzbHksIGFuZCBub3cgcmVuZGVycyBhdCAzLjIgc2Vjb25kcyAod2hpY2hcbiAgICAgICAgd291bGQgZ2V0IHRyYW5zbGF0ZWQgdG8gMi44IHNlY29uZHMgaWYgdGhlIHRpbWVsaW5lIHlveW9zIG9yIDAuMiBzZWNvbmRzIGlmIGl0IGp1c3QgcmVwZWF0cyksIHRoZXJlXG4gICAgICAgIGNvdWxkIGJlIGEgY2FsbGJhY2sgb3IgYSBzaG9ydCB0d2VlbiB0aGF0J3MgYXQgMi45NSBvciAzIHNlY29uZHMgaW4gd2hpY2ggd291bGRuJ3QgcmVuZGVyLiBTb1xuICAgICAgICB3ZSBuZWVkIHRvIHB1c2ggdGhlIHRpbWVsaW5lIHRvIHRoZSBlbmQgKGFuZC9vciBiZWdpbm5pbmcgZGVwZW5kaW5nIG9uIGl0cyB5b3lvIHZhbHVlKS4gQWxzbyB3ZSBtdXN0XG4gICAgICAgIGVuc3VyZSB0aGF0IHplcm8tZHVyYXRpb24gdHdlZW5zIGF0IHRoZSB2ZXJ5IGJlZ2lubmluZyBvciBlbmQgb2YgdGhlIFRpbWVsaW5lIHdvcmsuXG4gICAgICAgICovXG5cblxuICAgICAgICBpZiAoaXRlcmF0aW9uICE9PSBwcmV2SXRlcmF0aW9uICYmICF0aGlzLl9sb2NrKSB7XG4gICAgICAgICAgdmFyIHJld2luZGluZyA9IHlveW8gJiYgcHJldkl0ZXJhdGlvbiAmIDEsXG4gICAgICAgICAgICAgIGRvZXNXcmFwID0gcmV3aW5kaW5nID09PSAoeW95byAmJiBpdGVyYXRpb24gJiAxKTtcbiAgICAgICAgICBpdGVyYXRpb24gPCBwcmV2SXRlcmF0aW9uICYmIChyZXdpbmRpbmcgPSAhcmV3aW5kaW5nKTtcbiAgICAgICAgICBwcmV2VGltZSA9IHJld2luZGluZyA/IDAgOiB0VGltZSAlIGR1ciA/IGR1ciA6IHRUaW1lOyAvLyBpZiB0aGUgcGxheWhlYWQgaXMgbGFuZGluZyBleGFjdGx5IGF0IHRoZSBlbmQgb2YgYW4gaXRlcmF0aW9uLCB1c2UgdGhhdCB0b3RhbFRpbWUgcmF0aGVyIHRoYW4gb25seSB0aGUgZHVyYXRpb24sIG90aGVyd2lzZSBpdCdsbCBza2lwIHRoZSAybmQgcmVuZGVyIHNpbmNlIGl0J3MgZWZmZWN0aXZlbHkgYXQgdGhlIHNhbWUgdGltZS5cblxuICAgICAgICAgIHRoaXMuX2xvY2sgPSAxO1xuICAgICAgICAgIHRoaXMucmVuZGVyKHByZXZUaW1lIHx8IChpc1lveW8gPyAwIDogX3JvdW5kUHJlY2lzZShpdGVyYXRpb24gKiBjeWNsZUR1cmF0aW9uKSksIHN1cHByZXNzRXZlbnRzLCAhZHVyKS5fbG9jayA9IDA7XG4gICAgICAgICAgdGhpcy5fdFRpbWUgPSB0VGltZTsgLy8gaWYgYSB1c2VyIGdldHMgdGhlIGl0ZXJhdGlvbigpIGluc2lkZSB0aGUgb25SZXBlYXQsIGZvciBleGFtcGxlLCBpdCBzaG91bGQgYmUgYWNjdXJhdGUuXG5cbiAgICAgICAgICAhc3VwcHJlc3NFdmVudHMgJiYgdGhpcy5wYXJlbnQgJiYgX2NhbGxiYWNrKHRoaXMsIFwib25SZXBlYXRcIik7XG4gICAgICAgICAgdGhpcy52YXJzLnJlcGVhdFJlZnJlc2ggJiYgIWlzWW95byAmJiAodGhpcy5pbnZhbGlkYXRlKCkuX2xvY2sgPSAxKTtcblxuICAgICAgICAgIGlmIChwcmV2VGltZSAmJiBwcmV2VGltZSAhPT0gdGhpcy5fdGltZSB8fCBwcmV2UGF1c2VkICE9PSAhdGhpcy5fdHMgfHwgdGhpcy52YXJzLm9uUmVwZWF0ICYmICF0aGlzLnBhcmVudCAmJiAhdGhpcy5fYWN0KSB7XG4gICAgICAgICAgICAvLyBpZiBwcmV2VGltZSBpcyAwIGFuZCB3ZSByZW5kZXIgYXQgdGhlIHZlcnkgZW5kLCBfdGltZSB3aWxsIGJlIHRoZSBlbmQsIHRodXMgd29uJ3QgbWF0Y2guIFNvIGluIHRoaXMgZWRnZSBjYXNlLCBwcmV2VGltZSB3b24ndCBtYXRjaCBfdGltZSBidXQgdGhhdCdzIG9rYXkuIElmIGl0IGdldHMga2lsbGVkIGluIHRoZSBvblJlcGVhdCwgZWplY3QgYXMgd2VsbC5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGR1ciA9IHRoaXMuX2R1cjsgLy8gaW4gY2FzZSB0aGUgZHVyYXRpb24gY2hhbmdlZCBpbiB0aGUgb25SZXBlYXRcblxuICAgICAgICAgIHREdXIgPSB0aGlzLl90RHVyO1xuXG4gICAgICAgICAgaWYgKGRvZXNXcmFwKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2NrID0gMjtcbiAgICAgICAgICAgIHByZXZUaW1lID0gcmV3aW5kaW5nID8gZHVyIDogLTAuMDAwMTtcbiAgICAgICAgICAgI
1HRoaXMucmVuZGVyKHByZXZUaW1lLCB0cnVlKTtcbiAgICAgICAgICAgIHRoaXMudmFycy5yZXBlYXRSZWZyZXNoICYmICFpc1lveW8gJiYgdGhpcy5pbnZhbGlkYXRlKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5fbG9jayA9IDA7XG5cbiAgICAgICAgICBpZiAoIXRoaXMuX3RzICYmICFwcmV2UGF1c2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICB9IC8vaW4gb3JkZXIgZm9yIHlveW9FYXNlIHRvIHdvcmsgcHJvcGVybHkgd2hlbiB0aGVyZSdzIGEgc3RhZ2dlciwgd2UgbXVzdCBzd2FwIG91dCB0aGUgZWFzZSBpbiBlYWNoIHN1Yi10d2Vlbi5cblxuXG4gICAgICAgICAgX3Byb3BhZ2F0ZVlveW9FYXNlKHRoaXMsIGlzWW95byk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX2hhc1BhdXNlICYmICF0aGlzLl9mb3JjaW5nICYmIHRoaXMuX2xvY2sgPCAyKSB7XG4gICAgICAgIHBhdXNlVHdlZW4gPSBfZmluZE5leHRQYXVzZVR3ZWVuKHRoaXMsIF9yb3VuZFByZWNpc2UocHJldlRpbWUpLCBfcm91bmRQcmVjaXNlKHRpbWUpKTtcblxuICAgICAgICBpZiAocGF1c2VUd2Vlbikge1xuICAgICAgICAgIHRUaW1lIC09IHRpbWUgLSAodGltZSA9IHBhdXNlVHdlZW4uX3N0YXJ0KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLl90VGltZSA9IHRUaW1lO1xuICAgICAgdGhpcy5fdGltZSA9IHRpbWU7XG4gICAgICB0aGlzLl9hY3QgPSAhdGltZVNjYWxlOyAvL2FzIGxvbmcgYXMgaXQncyBub3QgcGF1c2VkLCBmb3JjZSBpdCB0byBiZSBhY3RpdmUgc28gdGhhdCBpZiB0aGUgdXNlciByZW5kZXJzIGluZGVwZW5kZW50IG9mIHRoZSBwYXJlbnQgdGltZWxpbmUsIGl0J2xsIGJlIGZvcmNlZCB0byByZS1yZW5kZXIgb24gdGhlIG5leHQgdGljay5cblxuICAgICAgaWYgKCF0aGlzLl9pbml0dGVkKSB7XG4gICAgICAgIHRoaXMuX29uVXBkYXRlID0gdGhpcy52YXJzLm9uVXBkYXRlO1xuICAgICAgICB0aGlzLl9pbml0dGVkID0gMTtcbiAgICAgICAgdGhpcy5felRpbWUgPSB0b3RhbFRpbWU7XG4gICAgICAgIHByZXZUaW1lID0gMDsgLy8gdXBvbiBpbml0LCB0aGUgcGxheWhlYWQgc2hvdWxkIGFsd2F5cyBnbyBmb3J3YXJkOyBzb21lb25lIGNvdWxkIGludmFsaWRhdGUoKSBhIGNvbXBsZXRlZCB0aW1lbGluZSBhbmQgdGhlbiBpZiB0aGV5IHJlc3RhcnQoKSwgdGhhdCB3b3VsZCBtYWtlIGNoaWxkIHR3ZWVucyByZW5kZXIgaW4gcmV2ZXJzZSBvcmRlciB3aGljaCBjb3VsZCBsb2NrIGluIHRoZSB3cm9uZyBzdGFydGluZyB2YWx1ZXMgaWYgdGhleSBidWlsZCBvbiBlYWNoIG90aGVyLCBsaWtlIHRsLnRvKG9iaiwge3g6IDEwMH0pLnRvKG9iaiwge3g6IDB9KS5cbiAgICAgIH1cblxuICAgICAgaWYgKCFwcmV2VGltZSAmJiB0aW1lICYmICFzdXBwcmVzc0V2ZW50cyAmJiAhaXRlcmF0aW9uKSB7XG4gICAgICAgIF9jYWxsYmFjayh0aGlzLCBcIm9uU3RhcnRcIik7XG5cbiAgICAgICAgaWYgKHRoaXMuX3RUaW1lICE9PSB0VGltZSkge1xuICAgICAgICAgIC8vIGluIGNhc2UgdGhlIG9uU3RhcnQgdHJpZ2dlcmVkIGEgcmVuZGVyIGF0IGEgZGlmZmVyZW50IHNwb3QsIGVqZWN0LiBMaWtlIGlmIHNvbWVvbmUgZGlkIGFuaW1hdGlvbi5wYXVzZSgwLjUpIG9yIHNvbWV0aGluZyBpbnNpZGUgdGhlIG9uU3RhcnQuXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRpbWUgPj0gcHJldlRpbW
1UgJiYgdG90YWxUaW1lID49IDApIHtcbiAgICAgICAgY2hpbGQgPSB0aGlzLl9maXJzdDtcblxuICAgICAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgICAgICBuZXh0ID0gY2hpbGQuX25leHQ7XG5cbiAgICAgICAgICBpZiAoKGNoaWxkLl9hY3QgfHwgdGltZSA+PSBjaGlsZC5fc3RhcnQpICYmIGNoaWxkLl90cyAmJiBwYXVzZVR3ZWVuICE9PSBjaGlsZCkge1xuICAgICAgICAgICAgaWYgKGNoaWxkLnBhcmVudCAhPT0gdGhpcykge1xuICAgICAgICAgICAgICAvLyBhbiBleHRyZW1lIGVkZ2UgY2FzZSAtIHRoZSBjaGlsZCdzIHJlbmRlciBjb3VsZCBkbyBzb21ldGhpbmcgbGlrZSBraWxsKCkgdGhlIFwibmV4dFwiIG9uZSBpbiB0aGUgbGlua2VkIGxpc3QsIG9yIHJlcGFyZW50IGl0LiBJbiB0aGF0IGNhc2Ugd2UgbXVzdCByZS1pbml0aWF0ZSB0aGUgd2hvbGUgcmVuZGVyIHRvIGJlIHNhZmUuXG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlbmRlcih0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNoaWxkLnJlbmRlcihjaGlsZC5fdHMgPiAwID8gKHRpbWUgLSBjaGlsZC5fc3RhcnQpICogY2hpbGQuX3RzIDogKGNoaWxkLl9kaXJ0eSA/IGNoaWxkLnRvdGFsRHVyYXRpb24oKSA6IGNoaWxkLl90RHVyKSArICh0aW1lIC0gY2hpbGQuX3N0YXJ0KSAqIGNoaWxkLl90cywgc3VwcHJlc3NFdmVudHMsIGZvcmNlKTtcblxuICAgICAgICAgICAgaWYgKHRpbWUgIT09IHRoaXMuX3RpbWUgfHwgIXRoaXMuX3RzICYmICFwcmV2UGF1c2VkKSB7XG4gICAgICAgICAgICAgIC8vaW4gY2FzZSBhIHR3ZWVuIHBhdXNlcyBvciBzZWVrcyB0aGUgdGltZWxpbmUgd2hlbiByZW5kZXJpbmcsIGxpa2UgaW5zaWRlIG9mIGFuIG9uVXBkYXRlL29uQ29tcGxldGVcbiAgICAgICAgICAgICAgcGF1c2VUd2VlbiA9IDA7XG4gICAgICAgICAgICAgIG5leHQgJiYgKHRUaW1lICs9IHRoaXMuX3pUaW1lID0gLV90aW55TnVtKTsgLy8gaXQgZGlkbid0IGZpbmlzaCByZW5kZXJpbmcsIHNvIGZsYWcgelRpbWUgYXMgbmVnYXRpdmUgc28gdGhhdCBzbyB0aGF0IHRoZSBuZXh0IHRpbWUgcmVuZGVyKCkgaXMgY2FsbGVkIGl0J2xsIGJlIGZvcmNlZCAodG8gcmVuZGVyIGFueSByZW1haW5pbmcgY2hpbGRyZW4pXG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2hpbGQgPSBuZXh0O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGlsZCA9IHRoaXMuX2xhc3Q7XG4gICAgICAgIHZhciBhZGp1c3RlZFRpbWUgPSB0b3RhbFRpbWUgPCAwID8gdG90YWxUaW1lIDogdGltZTsgLy93aGVuIHRoZSBwbGF5aGVhZCBnb2VzIGJhY2t3YXJkIGJleW9uZCB0aGUgc3RhcnQgb2YgdGhpcyB0aW1lbGluZSwgd2UgbXVzdCBwYXNzIHRoYXQgaW5mb3JtYXRpb24gZG93biB0byB0aGUgY2hpbGQgYW5pbWF0aW9ucyBzbyB0aGF0IHplcm8tZHVyYXRpb24gdHdlZW5zIGtub3cgd2hldGhlciB0byByZW5kZXIgdGhlaXIgc3RhcnRpbmcgb3IgZW5kaW5nIHZhbHVlcy5cblxuICAgICAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgICAgICBuZXh0ID0gY2hpbGQuX3ByZXY7XG5cbiAgICAgICAgICBpZiAoKGNoaWxkLl9hY3QgfHwgYWRqdXN0ZWRUaW1lIDw9IGNoaWxkLl9lbmQpICYmIGNoaWxkLl90cyAmJiBwYXVzZVR3ZWVuICE9PSBjaGlsZCkge1xuICAgICAgICAgICAgaWYgKGNoaWxkLnBhcmVudCAhPT0gdGhpcykge1xuICAgICAgICAgICAgICAvLyBhbiBleHRyZW1lIGVkZ2UgY2FzZSAtIHRoZSBjaGlsZCdzIHJlbmRlciBjb3VsZCBkbyBzb21ldGhpbmcgbGlrZSBraWxsKCkgdGhlIFwibmV4dFwiIG9uZSBpbiB0aGUgbGlua2VkIGxpc3QsIG9yIHJlcGFyZW50IGl0LiBJbiB0aGF0IGNhc2Ugd2UgbXVzdCByZS1pbml0aWF0ZSB0aGUgd2hvbGUgcmVuZGVyIHRvIGJlIHNhZmUuXG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlbmRlcih0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNoaWxkLnJlbmRlcihjaGlsZC5fdHMgPiAwID8gKGFkanVzdGVkVGltZSAtIGNoaWxkLl9zdGFydCkgKiBjaGlsZC5fdHMgOiAoY2hpbGQuX2RpcnR5ID8gY2hpbGQudG90YWxEdXJhdGlvbigpIDogY2hpbGQuX3REdXIpICsgKGFkanVzdGVkVGltZSAtIGNoaWxkLl9zdGFydCkgKiBjaGlsZC5fdHMsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSB8fCBfcmV2ZXJ0aW5nICYmIChjaGlsZC5faW5pdHRlZCB8fCBjaGlsZC5fc3RhcnRBdCkpOyAvLyBpZiByZXZlcnRpbmcsIHdlIHNob3VsZCBhbHdheXMgZm9yY2UgcmVuZGVycyBvZiBpbml0dGVkIHR3ZWVucyAoYnV0IHJlbWVtYmVyIHRoYXQgLmZyb21UbygpIG9yIC5mcm9tKCkgbWF5IGhhdmUgYSBfc3RhcnRBdCBidXQgbm90IF9pbml0dGVkIHlldCkuIElmLCBmb3IgZXhhbXBsZSwgYSAuZnJvbVRvKCkgdHdlZW4gd2l0aCBhIHN0YWdnZXIgKHdoaWNoIGNyZWF0ZXMgYW4gaW50ZXJuYWwgdGltZWxpbmUpIGdldHMgcmV2ZXJ0ZWQgQkVGT1JFIHNvbWUgb2YgaXRzIGNoaWxkIHR3ZWVucyByZW5kZXIgZm9yIHRoZSBmaXJzdCB0aW1lLCBpdCBtYXkgbm90IHByb3Blcmx5IHRyaWdnZXIgdGhlbSB0byByZXZlcnQuXG5cbiAgICAgICAgICAgIGlmICh0aW1lICE9PSB0aGlzLl90aW1lIHx8ICF0aGlzLl90cyAmJiAhcHJldlBhdXNlZCkge1xuICAgICAgICAgICAgICAvL2luIGNhc2UgYSB0d2VlbiBwYXVzZXMgb3Igc2Vla3MgdGhlIHRpbWVsaW5lIHdoZW4gcmVuZGVyaW5nLCBsaWtlIGluc2lkZSBvZiBhbiBvblVwZGF0ZS9vbkNvbXBsZXRlXG4gICAgICAgICAgICAgIHBhdXNlVHdlZW4gPSAwO1xuICAgICAgICAgICAgICBuZXh0ICYmICh0VGltZSArPSB0aGlzLl96VGltZSA9IGFkanVzdGVkVGltZSA/IC1fdGlueU51bSA6IF90aW55TnVtKTsgLy8gaXQgZGlkbid0IGZpbmlzaCByZW5kZXJpbmcsIHNvIGFkanVzdCB6VGltZSBzbyB0aGF0IHNvIHRoYXQgdGhlIG5leHQgdGltZSByZW5kZXIoKSBpcyBjYWxsZWQgaXQnbGwgYmUgZm9yY2VkICh0byByZW5kZXIgYW55IHJlbWFpbmluZyBjaGlsZHJlbilcblxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgI
1H1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjaGlsZCA9IG5leHQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHBhdXNlVHdlZW4gJiYgIXN1cHByZXNzRXZlbnRzKSB7XG4gICAgICAgIHRoaXMucGF1c2UoKTtcbiAgICAgICAgcGF1c2VUd2Vlbi5yZW5kZXIodGltZSA+PSBwcmV2VGltZSA/IDAgOiAtX3RpbnlOdW0pLl96VGltZSA9IHRpbWUgPj0gcHJldlRpbWUgPyAxIDogLTE7XG5cbiAgICAgICAgaWYgKHRoaXMuX3RzKSB7XG4gICAgICAgICAgLy90aGUgY2FsbGJhY2sgcmVzdW1lZCBwbGF5YmFjayEgU28gc2luY2Ugd2UgbWF5IGhhdmUgaGVsZCBiYWNrIHRoZSBwbGF5aGVhZCBkdWUgdG8gd2hlcmUgdGhlIHBhdXNlIGlzIHBvc2l0aW9uZWQsIGdvIGFoZWFkIGFuZCBqdW1wIHRvIHdoZXJlIGl0J3MgU1VQUE9TRUQgdG8gYmUgKGlmIG5vIHBhdXNlIGhhcHBlbmVkKS5cbiAgICAgICAgICB0aGlzLl9zdGFydCA9IHByZXZTdGFydDsgLy9pZiB0aGUgcGF1c2Ugd2FzIGF0IGFuIGVhcmxpZXIgdGltZSBhbmQgdGhlIHVzZXIgcmVzdW1lZCBpbiB0aGUgY2FsbGJhY2ssIGl0IGNvdWxkIHJlcG9zaXRpb24gdGhlIHRpbWVsaW5lIChjaGFuZ2luZyBpdHMgc3RhcnRUaW1lKSwgdGhyb3dpbmcgdGhpbmdzIG9mZiBzbGlnaHRseSwgc28gd2UgbWFrZSBzdXJlIHRoZSBfc3RhcnQgZG9lc24ndCBzaGlmdC5cblxuICAgICAgICAgIF9zZXRFbmQodGhpcyk7XG5cbiAgICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXIodG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX29uVXBkYXRlICYmICFzdXBwcmVzc0V2ZW50cyAmJiBfY2FsbGJhY2sodGhpcywgXCJvblVwZGF0ZVwiLCB0cnVlKTtcbiAgICAgIGlmICh0VGltZSA9PT0gdER1ciAmJiB0aGlzLl90VGltZSA+PSB0aGlzLnRvdGFsRHVyYXRpb24oKSB8fCAhdFRpbWUgJiYgcHJldlRpbWUpIGlmIChwcmV2U3RhcnQgPT09IHRoaXMuX3N0YXJ0IHx8IE1hdGguYWJzKHRpbWVTY2FsZSkgIT09IE1hdGguYWJzKHRoaXMuX3RzKSkgaWYgKCF0aGlzLl9sb2NrKSB7XG4gICAgICAgIC8vIHJlbWVtYmVyLCBhIGNoaWxkJ3MgY2FsbGJhY2sgbWF5IGFsdGVyIHRoaXMgdGltZWxpbmUncyBwbGF5aGVhZCBvciB0aW1lU2NhbGUgd2hpY2ggaXMgd2h5IHdlIG5lZWQgdG8gYWRkIHNvbWUgb2YgdGhlc2UgY2hlY2tzLlxuICAgICAgICAodG90YWxUaW1lIHx8ICFkdXIpICYmICh0VGltZSA9PT0gdER1ciAmJiB0aGlzLl90cyA+IDAgfHwgIXRUaW1lICYmIHRoaXMuX3RzIDwgMCkgJiYgX3JlbW92ZUZyb21QYXJlbnQodGhpcywgMSk7IC8vIGRvbid0IHJlbW92ZSBpZiB0aGUgdGltZWxpbmUgaXMgcmV2ZXJzZWQgYW5kIHRoZSBwbGF5aGVhZCBpc24ndCBhdCAwLCBvdGhlcndpc2UgdGwucHJvZ3Jlc3MoMSkucmV2ZXJzZSgpIHdvbid0IHdvcmsuIE9ubHkgcmVtb3ZlIGlmIHRoZSBwbGF5aGVhZCBpcyBhdCB0aGUgZW5kIGFuZCB0aW1lU2NhbGUgaXMgcG9zaXRpdmUsIG9yIGlmIHRoZSBwbGF5aGVhZCBpcyBhdCAwIGFuZCB0aGUgdGltZVNjYWxlIGlzIG5lZ2F0aXZlLlxuXG4gICAgICAgIGlmICghc3VwcHJlc3NFdmVudHMgJiYgISh0b3RhbFRpbWUgPCAwICYmICFwcmV2VGltZSkgJiYgKHRUaW1lIHx8IHByZXZUaW1lIHx8ICF0RHVyKSkge1xuICAgICAgICAgIF9jYWxsYmFjayh0aGlzLCB0VGltZSA9PT0gdER1ciAmJiB0b3RhbFRpbWUgPj0gMCA/IFwib25Db21wbGV0ZVwiIDogXCJvblJldmVyc2VDb21wbGV0ZVwiLCB0cnVlKTtcblxuICAgICAgICAgIHRoaXMuX3Byb20gJiYgISh0VGltZSA8IHREdXIgJiYgdGhpcy50aW1lU2NhbGUoKSA+IDApICYmIHRoaXMuX3Byb20oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIF9wcm90bzIuYWRkID0gZnVuY3Rpb24gYWRkKGNoaWxkLCBwb3NpdGlvbikge1xuICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgX2lzTnVtYmVyKHBvc2l0aW9uKSB8fCAocG9zaXRpb24gPSBfcGFyc2VQb3NpdGlvbih0aGlzLCBwb3NpdGlvbiwgY2hpbGQpKTtcblxuICAgIGlmICghKGNoaWxkIGluc3RhbmNlb2YgQW5pbWF0aW9uKSkge1xuICAgICAgaWYgKF9pc0FycmF5KGNoaWxkKSkge1xuICAgICAgICBjaGlsZC5mb3JFYWNoKGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMyLmFkZChvYmosIHBvc2l0aW9uKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBpZiAoX2lzU3RyaW5nKGNoaWxkKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRMYWJlbChjaGlsZCwgcG9zaXRpb24pO1xuICAgICAgfVxuXG4gICAgICBpZiAoX2lzRnVuY3Rpb24oY2hpbGQpKSB7XG4gICAgICAgIGNoaWxkID0gVHdlZW4uZGVsYXllZENhbGwoMCwgY2hpbGQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMgIT09IGNoaWxkID8gX2FkZFRvVGltZWxpbmUodGhpcywgY2hpbGQsIHBvc2l0aW9uKSA6IHRoaXM7IC8vZG9uJ3QgYWxsb3cgYSB0aW1lbGluZSB0byBiZSBhZGRlZCB0byBpdHNlbGYgYXMgYSBjaGlsZCFcbiAgfTtcblxuICBfcHJvdG8yLmdldENoaWxkcmVuID0gZnVuY3Rpb24gZ2V0Q2hpbGRyZW4obmVzdGVkLCB0d2VlbnMsIHRpbWVsaW5lcywgaWdub3JlQmVmb3JlVGltZSkge1xuICAgIGlmIChuZXN0ZWQgPT09IHZvaWQgMCkge1xuICAgICAgbmVzdGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAodHdlZW5zID09PSB2b2lkIDApIHtcbiAgICAgIHR3ZWVucyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHRpbWVsaW5lcyA9PT0gdm9pZCAwKSB7XG4gICAgICB0aW1lbGluZXMgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChpZ25vcmVCZWZvcmVUaW1lID09PSB2b2lkIDApIHtcbiAgICAgIGlnbm9yZUJlZm9yZVRpbWUgPSAtX2JpZ051bTtcbiAgICB9XG5cbiAgICB2YXIgYSA9IFtdLFxuICAgICAgICBjaGlsZCA9IHRoaXMuX2ZpcnN0O1xuXG4gICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICBpZiAoY2hpbGQuX3N0YXJ0ID49IGlnbm9yZUJlZm9yZVRpbWUpIHtcbiAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgVHdlZW4pIHtcbiAgICAgICAgICB0d2VlbnMgJiYgYS5wdXNoKGNoaWxkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aW1lbGluZXMgJiYgYS5wdXNoKGNoaWxkKTtcbiAgICAgICAgICBuZXN0ZWQgJiYgYS5wdXNoLmFwcGx5KGEsIGNoaWxkLmdldENoaWxkcmVuKHRydWUsIHR3ZWVucywgdGltZWxpbmVzKSk7XG4gICAgICAgI
1H1cbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBjaGlsZC5fbmV4dDtcbiAgICB9XG5cbiAgICByZXR1cm4gYTtcbiAgfTtcblxuICBfcHJvdG8yLmdldEJ5SWQgPSBmdW5jdGlvbiBnZXRCeUlkKGlkKSB7XG4gICAgdmFyIGFuaW1hdGlvbnMgPSB0aGlzLmdldENoaWxkcmVuKDEsIDEsIDEpLFxuICAgICAgICBpID0gYW5pbWF0aW9ucy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBpZiAoYW5pbWF0aW9uc1tpXS52YXJzLmlkID09PSBpZCkge1xuICAgICAgICByZXR1cm4gYW5pbWF0aW9uc1tpXTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgX3Byb3RvMi5yZW1vdmUgPSBmdW5jdGlvbiByZW1vdmUoY2hpbGQpIHtcbiAgICBpZiAoX2lzU3RyaW5nKGNoaWxkKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlTGFiZWwoY2hpbGQpO1xuICAgIH1cblxuICAgIGlmIChfaXNGdW5jdGlvbihjaGlsZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmtpbGxUd2VlbnNPZihjaGlsZCk7XG4gICAgfVxuXG4gICAgX3JlbW92ZUxpbmtlZExpc3RJdGVtKHRoaXMsIGNoaWxkKTtcblxuICAgIGlmIChjaGlsZCA9PT0gdGhpcy5fcmVjZW50KSB7XG4gICAgICB0aGlzLl9yZWNlbnQgPSB0aGlzLl9sYXN0O1xuICAgIH1cblxuICAgIHJldHVybiBfdW5jYWNoZSh0aGlzKTtcbiAgfTtcblxuICBfcHJvdG8yLnRvdGFsVGltZSA9IGZ1bmN0aW9uIHRvdGFsVGltZShfdG90YWxUaW1lMiwgc3VwcHJlc3NFdmVudHMpIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aGlzLl90VGltZTtcbiAgICB9XG5cbiAgICB0aGlzLl9mb3JjaW5nID0gMTtcblxuICAgIGlmICghdGhpcy5fZHAgJiYgdGhpcy5fdHMpIHtcbiAgICAgIC8vc3BlY2lhbCBjYXNlIGZvciB0aGUgZ2xvYmFsIHRpbWVsaW5lIChvciBhbnkgb3RoZXIgdGhhdCBoYXMgbm8gcGFyZW50IG9yIGRldGFjaGVkIHBhcmVudCkuXG4gICAgICB0aGlzLl9zdGFydCA9IF9yb3VuZFByZWNpc2UoX3RpY2tlci50aW1lIC0gKHRoaXMuX3RzID4gMCA/IF90b3RhbFRpbWUyIC8gdGhpcy5fdHMgOiAodGhpcy50b3RhbER1cmF0aW9uKCkgLSBfdG90YWxUaW1lMikgLyAtdGhpcy5fdHMpKTtcbiAgICB9XG5cbiAgICBfQW5pbWF0aW9uLnByb3RvdHlwZS50b3RhbFRpbWUuY2FsbCh0aGlzLCBfdG90YWxUaW1lMiwgc3VwcHJlc3NFdmVudHMpO1xuXG4gICAgdGhpcy5fZm9yY2luZyA9IDA7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgX3Byb3RvMi5hZGRMYWJlbCA9IGZ1bmN0aW9uIGFkZExhYmVsKGxhYmVsLCBwb3NpdGlvbikge1xuICAgIHRoaXMubGFiZWxzW2xhYmVsXSA9IF9wYXJzZVBvc2l0aW9uKHRoaXMsIHBvc2l0aW9uKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLnJlbW92ZUxhYmVsID0gZnVuY3Rpb24gcmVtb3ZlTGFiZWwobGFiZWwpIHtcbiAgICBkZWxldGUgdGhpcy5sYWJlbHNbbGFiZWxdO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIF9wcm90bzIuYWRkUGF1c2UgPSBmdW5jdGlvbiBhZGRQYXVzZShwb3NpdGlvbiwgY2FsbGJhY2ssIHBhcmFtcykge1xuICAgIHZhciB0ID0gVHdlZW4uZGVsYXllZENhbGwoMCwgY2FsbGJhY2sgfHwgX2VtcHR5RnVuYywgcGFyYW1zKTtcbiAgICB0LmRhdGEgPSBcImlzUGF1c2VcIjtcbiAgICB0aGlzLl9oYXNQYXVzZSA9IDE7XG4gICAgcmV0dXJuIF9hZGRUb1RpbWVsaW5lKHRoaXMsIHQsIF9wYXJzZVBvc2l0aW9uKHRoaXMsIHBvc2l0aW9uKSk7XG4gIH07XG5cbiAgX3Byb3RvMi5yZW1vdmVQYXVzZSA9IGZ1bmN0aW9uIHJlbW92ZVBhdXNlKHBvc2l0aW9uKSB7XG4gICAgdmFyIGNoaWxkID0gdGhpcy5fZmlyc3Q7XG4gICAgcG9zaXRpb24gPSBfcGFyc2VQb3NpdGlvbih0aGlzLCBwb3NpdGlvbik7XG5cbiAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgIGlmIChjaGlsZC5fc3RhcnQgPT09IHBvc2l0aW9uICYmIGNoaWxkLmRhdGEgPT09IFwiaXNQYXVzZVwiKSB7XG4gICAgICAgIF9yZW1vdmVGcm9tUGFyZW50KGNoaWxkKTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBjaGlsZC5fbmV4dDtcbiAgICB9XG4gIH07XG5cbiAgX3Byb3RvMi5raWxsVHdlZW5zT2YgPSBmdW5jdGlvbiBraWxsVHdlZW5zT2YodGFyZ2V0cywgcHJvcHMsIG9ubHlBY3RpdmUpIHtcbiAgICB2YXIgdHdlZW5zID0gdGhpcy5nZXRUd2VlbnNPZih0YXJnZXRzLCBvbmx5QWN0aXZlKSxcbiAgICAgICAgaSA9IHR3ZWVucy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBfb3ZlcndyaXRpbmdUd2VlbiAhPT0gdHdlZW5zW2ldICYmIHR3ZWVuc1tpXS5raWxsKHRhcmdldHMsIHByb3BzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBfcHJvdG8yLmdldFR3ZWVuc09mID0gZnVuY3Rpb24gZ2V0VHdlZW5zT2YodGFyZ2V0cywgb25seUFjdGl2ZSkge1xuICAgIHZhciBhID0gW10sXG4gICAgICAgIHBhcnNlZFRhcmdldHMgPSB0b0FycmF5KHRhcmdldHMpLFxuICAgICAgICBjaGlsZCA9IHRoaXMuX2ZpcnN0LFxuICAgICAgICBpc0dsb2JhbFRpbWUgPSBfaXNOdW1iZXIob25seUFjdGl2ZSksXG4gICAgICAgIC8vIGEgbnVtYmVyIGlzIGludGVycHJldGVkIGFzIGEgZ2xvYmFsIHRpbWUuIElmIHRoZSBhbmltYXRpb24gc3BhbnNcbiAgICBjaGlsZHJlbjtcblxuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgVHdlZW4pIHtcbiAgICAgICAgaWYgKF9hcnJheUNvbnRhaW5zQW55KGNoaWxkLl90YXJnZXRzLCBwYXJzZWRUYXJnZXRzKSAmJiAoaXNHbG9iYWxUaW1lID8gKCFfb3ZlcndyaXRpbmdUd2VlbiB8fCBjaGlsZC5faW5pdHRlZCAmJiBjaGlsZC5fdHMpICYmIGNoaWxkLmdsb2JhbFRpbWUoMCkgPD0gb25seUFjdGl2ZSAmJiBjaGlsZC5nbG9iYWxUaW1lKGNoaWxkLnRvdGFsRHVyYXRpb24oKSkgPiBvbmx5QWN0aXZlIDogIW9ubHlBY3RpdmUgfHwgY2hpbGQuaXNBY3RpdmUoKSkpIHtcbiAgICAgICAgICAvLyBub3RlOiBpZiB0aGlzIGlzIGZvciBvdmVyd3JpdGluZywgaXQgc2hvdWxkIG9ubHkgYmUgZm9yIHR3ZWVucyB0aGF0IGFyZW4ndCBwYXVzZWQgYW5kIGFyZSBpbml0dGVkLlxuICAgICAgICAgIGEucHVzaChjaGlsZCk7XG4gICAgICAgI
1H1cbiAgICAgIH0gZWxzZSBpZiAoKGNoaWxkcmVuID0gY2hpbGQuZ2V0VHdlZW5zT2YocGFyc2VkVGFyZ2V0cywgb25seUFjdGl2ZSkpLmxlbmd0aCkge1xuICAgICAgICBhLnB1c2guYXBwbHkoYSwgY2hpbGRyZW4pO1xuICAgICAgfVxuXG4gICAgICBjaGlsZCA9IGNoaWxkLl9uZXh0O1xuICAgIH1cblxuICAgIHJldHVybiBhO1xuICB9IC8vIHBvdGVudGlhbCBmdXR1cmUgZmVhdHVyZSAtIHRhcmdldHMoKSBvbiB0aW1lbGluZXNcbiAgLy8gdGFyZ2V0cygpIHtcbiAgLy8gXHRsZXQgcmVzdWx0ID0gW107XG4gIC8vIFx0dGhpcy5nZXRDaGlsZHJlbih0cnVlLCB0cnVlLCBmYWxzZSkuZm9yRWFjaCh0ID0+IHJlc3VsdC5wdXNoKC4uLnQudGFyZ2V0cygpKSk7XG4gIC8vIFx0cmV0dXJuIHJlc3VsdC5maWx0ZXIoKHYsIGkpID0+IHJlc3VsdC5pbmRleE9mKHYpID09PSBpKTtcbiAgLy8gfVxuICA7XG5cbiAgX3Byb3RvMi50d2VlblRvID0gZnVuY3Rpb24gdHdlZW5Ubyhwb3NpdGlvbiwgdmFycykge1xuICAgIHZhcnMgPSB2YXJzIHx8IHt9O1xuXG4gICAgdmFyIHRsID0gdGhpcyxcbiAgICAgICAgZW5kVGltZSA9IF9wYXJzZVBvc2l0aW9uKHRsLCBwb3NpdGlvbiksXG4gICAgICAgIF92YXJzID0gdmFycyxcbiAgICAgICAgc3RhcnRBdCA9IF92YXJzLnN0YXJ0QXQsXG4gICAgICAgIF9vblN0YXJ0ID0gX3ZhcnMub25TdGFydCxcbiAgICAgICAgb25TdGFydFBhcmFtcyA9IF92YXJzLm9uU3RhcnRQYXJhbXMsXG4gICAgICAgIGltbWVkaWF0ZVJlbmRlciA9IF92YXJzLmltbWVkaWF0ZVJlbmRlcixcbiAgICAgICAgaW5pdHRlZCxcbiAgICAgICAgdHdlZW4gPSBUd2Vlbi50byh0bCwgX3NldERlZmF1bHRzKHtcbiAgICAgIGVhc2U6IHZhcnMuZWFzZSB8fCBcIm5vbmVcIixcbiAgICAgIGxhenk6IGZhbHNlLFxuICAgICAgaW1tZWRpYXRlUmVuZGVyOiBmYWxzZSxcbiAgICAgIHRpbWU6IGVuZFRpbWUsXG4gICAgICBvdmVyd3JpdGU6IFwiYXV0b1wiLFxuICAgICAgZHVyYXRpb246IHZhcnMuZHVyYXRpb24gfHwgTWF0aC5hYnMoKGVuZFRpbWUgLSAoc3RhcnRBdCAmJiBcInRpbWVcIiBpbiBzdGFydEF0ID8gc3RhcnRBdC50aW1lIDogdGwuX3RpbWUpKSAvIHRsLnRpbWVTY2FsZSgpKSB8fCBfdGlueU51bSxcbiAgICAgIG9uU3RhcnQ6IGZ1bmN0aW9uIG9uU3RhcnQoKSB7XG4gICAgICAgIHRsLnBhdXNlKCk7XG5cbiAgICAgICAgaWYgKCFpbml0dGVkKSB7XG4gICAgICAgICAgdmFyIGR1cmF0aW9uID0gdmFycy5kdXJhdGlvbiB8fCBNYXRoLmFicygoZW5kVGltZSAtIChzdGFydEF0ICYmIFwidGltZVwiIGluIHN0YXJ0QXQgPyBzdGFydEF0LnRpbWUgOiB0bC5fdGltZSkpIC8gdGwudGltZVNjYWxlKCkpO1xuICAgICAgICAgIHR3ZWVuLl9kdXIgIT09IGR1cmF0aW9uICYmIF9zZXREdXJhdGlvbih0d2VlbiwgZHVyYXRpb24sIDAsIDEpLnJlbmRlcih0d2Vlbi5fdGltZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICAgaW5pdHRlZCA9IDE7XG4gICAgICAgIH1cblxuICAgICAgICBfb25TdGFydCAmJiBfb25TdGFydC5hcHBseSh0d2Vlbiwgb25TdGFydFBhcmFtcyB8fCBbXSk7IC8vaW4gY2FzZSB0aGUgdXNlciBoYWQgYW4gb25TdGFydCBpbiB0aGUgdmFycyAtIHdlIGRvbid0IHdhbnQgdG8gb3ZlcndyaXRlIGl0LlxuICAgICAgfVxuICAgIH0sIHZhcnMpKTtcblxuICAgIHJldHVybiBpbW1lZGlhdGVSZW5kZXIgPyB0d2Vlbi5yZW5kZXIoMCkgOiB0d2VlbjtcbiAgfTtcblxuICBfcHJvdG8yLnR3ZWVuRnJvbVRvID0gZnVuY3Rpb24gdHdlZW5Gcm9tVG8oZnJvbVBvc2l0aW9uLCB0b1Bvc2l0aW9uLCB2YXJzKSB7XG4gICAgcmV0dXJuIHRoaXMudHdlZW5Ubyh0b1Bvc2l0aW9uLCBfc2V0RGVmYXVsdHMoe1xuICAgICAgc3RhcnRBdDoge1xuICAgICAgICB0aW1lOiBfcGFyc2VQb3NpdGlvbih0aGlzLCBmcm9tUG9zaXRpb24pXG4gICAgICB9XG4gICAgfSwgdmFycykpO1xuICB9O1xuXG4gIF9wcm90bzIucmVjZW50ID0gZnVuY3Rpb24gcmVjZW50KCkge1xuICAgIHJldHVybiB0aGlzLl9yZWNlbnQ7XG4gIH07XG5cbiAgX3Byb3RvMi5uZXh0TGFiZWwgPSBmdW5jdGlvbiBuZXh0TGFiZWwoYWZ0ZXJUaW1lKSB7XG4gICAgaWYgKGFmdGVyVGltZSA9PT0gdm9pZCAwKSB7XG4gICAgICBhZnRlclRpbWUgPSB0aGlzLl90aW1lO1xuICAgIH1cblxuICAgIHJldHVybiBfZ2V0TGFiZWxJbkRpcmVjdGlvbih0aGlzLCBfcGFyc2VQb3NpdGlvbih0aGlzLCBhZnRlclRpbWUpKTtcbiAgfTtcblxuICBfcHJvdG8yLnByZXZpb3VzTGFiZWwgPSBmdW5jdGlvbiBwcmV2aW91c0xhYmVsKGJlZm9yZVRpbWUpIHtcbiAgICBpZiAoYmVmb3JlVGltZSA9PT0gdm9pZCAwKSB7XG4gICAgICBiZWZvcmVUaW1lID0gdGhpcy5fdGltZTtcbiAgICB9XG5cbiAgICByZXR1cm4gX2dldExhYmVsSW5EaXJlY3Rpb24odGhpcywgX3BhcnNlUG9zaXRpb24odGhpcywgYmVmb3JlVGltZSksIDEpO1xuICB9O1xuXG4gIF9wcm90bzIuY3VycmVudExhYmVsID0gZnVuY3Rpb24gY3VycmVudExhYmVsKHZhbHVlKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLnNlZWsodmFsdWUsIHRydWUpIDogdGhpcy5wcmV2aW91c0xhYmVsKHRoaXMuX3RpbWUgKyBfdGlueU51bSk7XG4gIH07XG5cbiAgX3Byb3RvMi5zaGlmdENoaWxkcmVuID0gZnVuY3Rpb24gc2hpZnRDaGlsZHJlbihhbW91bnQsIGFkanVzdExhYmVscywgaWdub3JlQmVmb3JlVGltZSkge1xuICAgIGlmIChpZ25vcmVCZWZvcmVUaW1lID09PSB2b2lkIDApIHtcbiAgICAgIGlnbm9yZUJlZm9yZVRpbWUgPSAwO1xuICAgIH1cblxuICAgIHZhciBjaGlsZCA9IHRoaXMuX2ZpcnN0LFxuICAgICAgICBsYWJlbHMgPSB0aGlzLmxhYmVscyxcbiAgICAgICAgcDtcblxuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKGNoaWxkLl9zdGFydCA+PSBpZ25vcmVCZWZvcmVUaW1lKSB7XG4gICAgICAgIGNoaWxkLl9zdGFydCArPSBhbW91bnQ7XG4gICAgICAgIGNoaWxkLl9lbmQgKz0gYW1vdW50O1xuICAgICAgfVxuXG4gICAgICBjaGlsZCA9IGNoaWxkLl9uZXh0O1xuICAgIH1cblxuICAgIGlmIChhZGp1c3RMYWJlbHMpIHtcbiAgICAgIGZvciAocCBpbiBsYWJlbHMpIHtcbiAgICAgICAgaWYgKGxhYmVsc1twXSA+PSBpZ25vcmVCZWZvcmVUaW1lKSB7XG4gICAgICAgICAgbGFiZWxzW3BdICs9IGFtb3VudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgI
1HJldHVybiBfdW5jYWNoZSh0aGlzKTtcbiAgfTtcblxuICBfcHJvdG8yLmludmFsaWRhdGUgPSBmdW5jdGlvbiBpbnZhbGlkYXRlKHNvZnQpIHtcbiAgICB2YXIgY2hpbGQgPSB0aGlzLl9maXJzdDtcbiAgICB0aGlzLl9sb2NrID0gMDtcblxuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgY2hpbGQuaW52YWxpZGF0ZShzb2Z0KTtcbiAgICAgIGNoaWxkID0gY2hpbGQuX25leHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9BbmltYXRpb24ucHJvdG90eXBlLmludmFsaWRhdGUuY2FsbCh0aGlzLCBzb2Z0KTtcbiAgfTtcblxuICBfcHJvdG8yLmNsZWFyID0gZnVuY3Rpb24gY2xlYXIoaW5jbHVkZUxhYmVscykge1xuICAgIGlmIChpbmNsdWRlTGFiZWxzID09PSB2b2lkIDApIHtcbiAgICAgIGluY2x1ZGVMYWJlbHMgPSB0cnVlO1xuICAgIH1cblxuICAgIHZhciBjaGlsZCA9IHRoaXMuX2ZpcnN0LFxuICAgICAgICBuZXh0O1xuXG4gICAgd2hpbGUgKGNoaWxkKSB7XG4gICAgICBuZXh0ID0gY2hpbGQuX25leHQ7XG4gICAgICB0aGlzLnJlbW92ZShjaGlsZCk7XG4gICAgICBjaGlsZCA9IG5leHQ7XG4gICAgfVxuXG4gICAgdGhpcy5fZHAgJiYgKHRoaXMuX3RpbWUgPSB0aGlzLl90VGltZSA9IHRoaXMuX3BUaW1lID0gMCk7XG4gICAgaW5jbHVkZUxhYmVscyAmJiAodGhpcy5sYWJlbHMgPSB7fSk7XG4gICAgcmV0dXJuIF91bmNhY2hlKHRoaXMpO1xuICB9O1xuXG4gIF9wcm90bzIudG90YWxEdXJhdGlvbiA9IGZ1bmN0aW9uIHRvdGFsRHVyYXRpb24odmFsdWUpIHtcbiAgICB2YXIgbWF4ID0gMCxcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIGNoaWxkID0gc2VsZi5fbGFzdCxcbiAgICAgICAgcHJldlN0YXJ0ID0gX2JpZ051bSxcbiAgICAgICAgcHJldixcbiAgICAgICAgc3RhcnQsXG4gICAgICAgIHBhcmVudDtcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gc2VsZi50aW1lU2NhbGUoKHNlbGYuX3JlcGVhdCA8IDAgPyBzZWxmLmR1cmF0aW9uKCkgOiBzZWxmLnRvdGFsRHVyYXRpb24oKSkgLyAoc2VsZi5yZXZlcnNlZCgpID8gLXZhbHVlIDogdmFsdWUpKTtcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5fZGlydHkpIHtcbiAgICAgIHBhcmVudCA9IHNlbGYucGFyZW50O1xuXG4gICAgICB3aGlsZSAoY2hpbGQpIHtcbiAgICAgICAgcHJldiA9IGNoaWxkLl9wcmV2OyAvL3JlY29yZCBpdCBoZXJlIGluIGNhc2UgdGhlIHR3ZWVuIGNoYW5nZXMgcG9zaXRpb24gaW4gdGhlIHNlcXVlbmNlLi4uXG5cbiAgICAgICAgY2hpbGQuX2RpcnR5ICYmIGNoaWxkLnRvdGFsRHVyYXRpb24oKTsgLy9jb3VsZCBjaGFuZ2UgdGhlIHR3ZWVuLl9zdGFydFRpbWUsIHNvIG1ha2Ugc3VyZSB0aGUgYW5pbWF0aW9uJ3MgY2FjaGUgaXMgY2xlYW4gYmVmb3JlIGFuYWx5emluZyBpdC5cblxuICAgICAgICBzdGFydCA9IGNoaWxkLl9zdGFydDtcblxuICAgICAgICBpZiAoc3RhcnQgPiBwcmV2U3RhcnQgJiYgc2VsZi5fc29ydCAmJiBjaGlsZC5fdHMgJiYgIXNlbGYuX2xvY2spIHtcbiAgICAgICAgICAvL2luIGNhc2Ugb25lIG9mIHRoZSB0d2VlbnMgc2hpZnRlZCBvdXQgb2Ygb3JkZXIsIGl0IG5lZWRzIHRvIGJlIHJlLWluc2VydGVkIGludG8gdGhlIGNvcnJlY3QgcG9zaXRpb24gaW4gdGhlIHNlcXVlbmNlXG4gICAgICAgICAgc2VsZi5fbG9jayA9IDE7IC8vcHJldmVudCBlbmRsZXNzIHJlY3Vyc2l2ZSBjYWxscyAtIHRoZXJlIGFyZSBtZXRob2RzIHRoYXQgZ2V0IHRyaWdnZXJlZCB0aGF0IGNoZWNrIGR1cmF0aW9uL3RvdGFsRHVyYXRpb24gd2hlbiB3ZSBhZGQoKS5cblxuICAgICAgICAgIF9hZGRUb1RpbWVsaW5lKHNlbGYsIGNoaWxkLCBzdGFydCAtIGNoaWxkLl9kZWxheSwgMSkuX2xvY2sgPSAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByZXZTdGFydCA9IHN0YXJ0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0YXJ0IDwgMCAmJiBjaGlsZC5fdHMpIHtcbiAgICAgICAgICAvL2NoaWxkcmVuIGFyZW4ndCBhbGxvd2VkIHRvIGhhdmUgbmVnYXRpdmUgc3RhcnRUaW1lcyB1bmxlc3Mgc21vb3RoQ2hpbGRUaW1pbmcgaXMgdHJ1ZSwgc28gYWRqdXN0IGhlcmUgaWYgb25lIGlzIGZvdW5kLlxuICAgICAgICAgIG1heCAtPSBzdGFydDtcblxuICAgICAgICAgIGlmICghcGFyZW50ICYmICFzZWxmLl9kcCB8fCBwYXJlbnQgJiYgcGFyZW50LnNtb290aENoaWxkVGltaW5nKSB7XG4gICAgICAgICAgICBzZWxmLl9zdGFydCArPSBzdGFydCAvIHNlbGYuX3RzO1xuICAgICAgICAgICAgc2VsZi5fdGltZSAtPSBzdGFydDtcbiAgICAgICAgICAgIHNlbGYuX3RUaW1lIC09IHN0YXJ0O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHNlbGYuc2hpZnRDaGlsZHJlbigtc3RhcnQsIGZhbHNlLCAtMWU5OTkpO1xuICAgICAgICAgIHByZXZTdGFydCA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBjaGlsZC5fZW5kID4gbWF4ICYmIGNoaWxkLl90cyAmJiAobWF4ID0gY2hpbGQuX2VuZCk7XG4gICAgICAgIGNoaWxkID0gcHJldjtcbiAgICAgIH1cblxuICAgICAgX3NldER1cmF0aW9uKHNlbGYsIHNlbGYgPT09IF9nbG9iYWxUaW1lbGluZSAmJiBzZWxmLl90aW1lID4gbWF4ID8gc2VsZi5fdGltZSA6IG1heCwgMSwgMSk7XG5cbiAgICAgIHNlbGYuX2RpcnR5ID0gMDtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZi5fdER1cjtcbiAgfTtcblxuICBUaW1lbGluZS51cGRhdGVSb290ID0gZnVuY3Rpb24gdXBkYXRlUm9vdCh0aW1lKSB7XG4gICAgaWYgKF9nbG9iYWxUaW1lbGluZS5fdHMpIHtcbiAgICAgIF9sYXp5U2FmZVJlbmRlcihfZ2xvYmFsVGltZWxpbmUsIF9wYXJlbnRUb0NoaWxkVG90YWxUaW1lKHRpbWUsIF9nbG9iYWxUaW1lbGluZSkpO1xuXG4gICAgICBfbGFzdFJlbmRlcmVkRnJhbWUgPSBfdGlja2VyLmZyYW1lO1xuICAgIH1cblxuICAgIGlmIChfdGlja2VyLmZyYW1lID49IF9uZXh0R0NGcmFtZSkge1xuICAgICAgX25leHRHQ0ZyYW1lICs9IF9jb25maWcuYXV0b1NsZWVwIHx8IDEyMDtcbiAgICAgIHZhciBjaGlsZCA9IF9nbG9iYWxUaW1lbGluZS5fZmlyc3Q7XG4gICAgICBpZiAoIWNoaWxkIHx8ICFjaGlsZC5fdHMpIGlmIChfY29uZmlnLmF1dG9TbGVlcCAmJi
1BfdGlja2VyLl9saXN0ZW5lcnMubGVuZ3RoIDwgMikge1xuICAgICAgICB3aGlsZSAoY2hpbGQgJiYgIWNoaWxkLl90cykge1xuICAgICAgICAgIGNoaWxkID0gY2hpbGQuX25leHQ7XG4gICAgICAgIH1cblxuICAgICAgICBjaGlsZCB8fCBfdGlja2VyLnNsZWVwKCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBUaW1lbGluZTtcbn0oQW5pbWF0aW9uKTtcblxuX3NldERlZmF1bHRzKFRpbWVsaW5lLnByb3RvdHlwZSwge1xuICBfbG9jazogMCxcbiAgX2hhc1BhdXNlOiAwLFxuICBfZm9yY2luZzogMFxufSk7XG5cbnZhciBfYWRkQ29tcGxleFN0cmluZ1Byb3BUd2VlbiA9IGZ1bmN0aW9uIF9hZGRDb21wbGV4U3RyaW5nUHJvcFR3ZWVuKHRhcmdldCwgcHJvcCwgc3RhcnQsIGVuZCwgc2V0dGVyLCBzdHJpbmdGaWx0ZXIsIGZ1bmNQYXJhbSkge1xuICAvL25vdGU6IHdlIGNhbGwgX2FkZENvbXBsZXhTdHJpbmdQcm9wVHdlZW4uY2FsbCh0d2Vlbkluc3RhbmNlLi4uKSB0byBlbnN1cmUgdGhhdCBpdCdzIHNjb3BlZCBwcm9wZXJseS4gV2UgbWF5IGNhbGwgaXQgZnJvbSB3aXRoaW4gYSBwbHVnaW4gdG9vLCB0aHVzIFwidGhpc1wiIHdvdWxkIHJlZmVyIHRvIHRoZSBwbHVnaW4uXG4gIHZhciBwdCA9IG5ldyBQcm9wVHdlZW4odGhpcy5fcHQsIHRhcmdldCwgcHJvcCwgMCwgMSwgX3JlbmRlckNvbXBsZXhTdHJpbmcsIG51bGwsIHNldHRlciksXG4gICAgICBpbmRleCA9IDAsXG4gICAgICBtYXRjaEluZGV4ID0gMCxcbiAgICAgIHJlc3VsdCxcbiAgICAgIHN0YXJ0TnVtcyxcbiAgICAgIGNvbG9yLFxuICAgICAgZW5kTnVtLFxuICAgICAgY2h1bmssXG4gICAgICBzdGFydE51bSxcbiAgICAgIGhhc1JhbmRvbSxcbiAgICAgIGE7XG4gIHB0LmIgPSBzdGFydDtcbiAgcHQuZSA9IGVuZDtcbiAgc3RhcnQgKz0gXCJcIjsgLy9lbnN1cmUgdmFsdWVzIGFyZSBzdHJpbmdzXG5cbiAgZW5kICs9IFwiXCI7XG5cbiAgaWYgKGhhc1JhbmRvbSA9IH5lbmQuaW5kZXhPZihcInJhbmRvbShcIikpIHtcbiAgICBlbmQgPSBfcmVwbGFjZVJhbmRvbShlbmQpO1xuICB9XG5cbiAgaWYgKHN0cmluZ0ZpbHRlcikge1xuICAgIGEgPSBbc3RhcnQsIGVuZF07XG4gICAgc3RyaW5nRmlsdGVyKGEsIHRhcmdldCwgcHJvcCk7IC8vcGFzcyBhbiBhcnJheSB3aXRoIHRoZSBzdGFydGluZyBhbmQgZW5kaW5nIHZhbHVlcyBhbmQgbGV0IHRoZSBmaWx0ZXIgZG8gd2hhdGV2ZXIgaXQgbmVlZHMgdG8gdGhlIHZhbHVlcy5cblxuICAgIHN0YXJ0ID0gYVswXTtcbiAgICBlbmQgPSBhWzFdO1xuICB9XG5cbiAgc3RhcnROdW1zID0gc3RhcnQubWF0Y2goX2NvbXBsZXhTdHJpbmdOdW1FeHApIHx8IFtdO1xuXG4gIHdoaWxlIChyZXN1bHQgPSBfY29tcGxleFN0cmluZ051bUV4cC5leGVjKGVuZCkpIHtcbiAgICBlbmROdW0gPSByZXN1bHRbMF07XG4gICAgY2h1bmsgPSBlbmQuc3Vic3RyaW5nKGluZGV4LCByZXN1bHQuaW5kZXgpO1xuXG4gICAgaWYgKGNvbG9yKSB7XG4gICAgICBjb2xvciA9IChjb2xvciArIDEpICUgNTtcbiAgICB9IGVsc2UgaWYgKGNodW5rLnN1YnN0cigtNSkgPT09IFwicmdiYShcIikge1xuICAgICAgY29sb3IgPSAxO1xuICAgIH1cblxuICAgIGlmIChlbmROdW0gIT09IHN0YXJ0TnVtc1ttYXRjaEluZGV4KytdKSB7XG4gICAgICBzdGFydE51bSA9IHBhcnNlRmxvYXQoc3RhcnROdW1zW21hdGNoSW5kZXggLSAxXSkgfHwgMDsgLy90aGVzZSBuZXN0ZWQgUHJvcFR3ZWVucyBhcmUgaGFuZGxlZCBpbiBhIHNwZWNpYWwgd2F5IC0gd2UnbGwgbmV2ZXIgYWN0dWFsbHkgY2FsbCBhIHJlbmRlciBvciBzZXR0ZXIgbWV0aG9kIG9uIHRoZW0uIFdlJ2xsIGp1c3QgbG9vcCB0aHJvdWdoIHRoZW0gaW4gdGhlIHBhcmVudCBjb21wbGV4IHN0cmluZyBQcm9wVHdlZW4ncyByZW5kZXIgbWV0aG9kLlxuXG4gICAgICBwdC5fcHQgPSB7XG4gICAgICAgIF9uZXh0OiBwdC5fcHQsXG4gICAgICAgIHA6IGNodW5rIHx8IG1hdGNoSW5kZXggPT09IDEgPyBjaHVuayA6IFwiLFwiLFxuICAgICAgICAvL25vdGU6IFNWRyBzcGVjIGFsbG93cyBvbWlzc2lvbiBvZiBjb21tYS9zcGFjZSB3aGVuIGEgbmVnYXRpdmUgc2lnbiBpcyB3ZWRnZWQgYmV0d2VlbiB0d28gbnVtYmVycywgbGlrZSAyLjUtNS4zIGluc3RlYWQgb2YgMi41LC01LjMgYnV0IHdoZW4gdHdlZW5pbmcsIHRoZSBuZWdhdGl2ZSB2YWx1ZSBtYXkgc3dpdGNoIHRvIHBvc2l0aXZlLCBzbyB3ZSBpbnNlcnQgdGhlIGNvbW1hIGp1c3QgaW4gY2FzZS5cbiAgICAgICAgczogc3RhcnROdW0sXG4gICAgICAgIGM6IGVuZE51bS5jaGFyQXQoMSkgPT09IFwiPVwiID8gX3BhcnNlUmVsYXRpdmUoc3RhcnROdW0sIG
1VuZE51bSkgLSBzdGFydE51bSA6IHBhcnNlRmxvYXQoZW5kTnVtKSAtIHN0YXJ0TnVtLFxuICAgICAgICBtOiBjb2xvciAmJiBjb2xvciA8IDQgPyBNYXRoLnJvdW5kIDogMFxuICAgICAgfTtcbiAgICAgIGluZGV4ID0gX2NvbXBsZXhTdHJpbmdOdW1FeHAubGFzdEluZGV4O1xuICAgIH1cbiAgfVxuXG4gIHB0LmMgPSBpbmRleCA8IGVuZC5sZW5ndGggPyBlbmQuc3Vic3RyaW5nKGluZGV4LCBlbmQubGVuZ3RoKSA6IFwiXCI7IC8vd2UgdXNlIHRoZSBcImNcIiBvZiB0aGUgUHJvcFR3ZWVuIHRvIHN0b3JlIHRoZSBmaW5hbCBwYXJ0IG9mIHRoZSBzdHJpbmcgKGFmdGVyIHRoZSBsYXN0IG51bWJlcilcblxuICBwdC5mcCA9IGZ1bmNQYXJhbTtcblxuICBpZiAoX3JlbEV4cC50ZXN0KGVuZCkgfHwgaGFzUmFuZG9tKSB7XG4gICAgcHQuZSA9IDA7IC8vaWYgdGhlIGVuZCBzdHJpbmcgY29udGFpbnMgcmVsYXRpdmUgdmFsdWVzIG9yIGR5bmFtaWMgcmFuZG9tKC4uLikgdmFsdWVzLCBkZWxldGUgdGhlIGVuZCBpdCBzbyB0aGF0IG9uIHRoZSBmaW5hbCByZW5kZXIgd2UgZG9uJ3QgYWN0dWFsbHkgc2V0IGl0IHRvIHRoZSBzdHJpbmcgd2l0aCArPSBvciAtPSBjaGFyYWN0ZXJzIChmb3JjZXMgaXQgdG8gdXNlIHRoZSBjYWxjdWxhdGVkIHZhbHVlKS5cbiAgfVxuXG4gIHRoaXMuX3B0ID0gcHQ7IC8vc3RhcnQgdGhlIGxpbmtlZCBsaXN0IHdpdGggdGhpcyBuZXcgUHJvcFR3ZWVuLiBSZW1lbWJlciwgd2UgY2FsbCBfYWRkQ29tcGxleFN0cmluZ1Byb3BUd2Vlbi5jYWxsKHR3ZWVuSW5zdGFuY2UuLi4pIHRvIGVuc3VyZSB0aGF0IGl0J3Mgc2NvcGVkIHByb3Blcmx5LiBXZSBtYXkgY2FsbCBpdCBmcm9tIHdpdGhpbiBhIHBsdWdpbiB0b28sIHRodXMgXCJ0aGlzXCIgd291bGQgcmVmZXIgdG8gdGhlIHBsdWdpbi5cblxuICByZXR1cm4gcHQ7XG59LFxuICAgIF9hZGRQcm9wVHdlZW4gPSBmdW5jdGlvbiBfYWRkUHJvcFR3ZWVuKHRhcmdldCwgcHJvcCwgc3RhcnQsIGVuZCwgaW5kZXgsIHRhcmdldHMsIG1vZGlmaWVyLCBzdHJpbmdGaWx0ZXIsIGZ1bmNQYXJhbSwgb3B0aW9uYWwpIHtcbiAgX2lzRnVuY3Rpb24oZW5kKSAmJiAoZW5kID0gZW5kKGluZGV4IHx8IDAsIHRhcmdldCwgdGFyZ2V0cykpO1xuICB2YXIgY3VycmVudFZhbHVlID0gdGFyZ2V0W3Byb3BdLFxuICAgICAgcGFyc2VkU3RhcnQgPSBzdGFydCAhPT0gXCJnZXRcIiA/IHN0YXJ0IDogIV9pc0Z1bmN0aW9uKGN1cnJlbnRWYWx1ZSkgPyBjdXJyZW50VmFsdWUgOiBmdW5jUGFyYW0gPyB0YXJnZXRbcHJvcC5pbmRleE9mKFwic2V0XCIpIHx8ICFfaXNGdW5jdGlvbih0YXJnZXRbXCJnZXRcIiArIHByb3Auc3Vic3RyKDMpXSkgPyBwcm9wIDogXCJnZXRcIiArIHByb3Auc3Vic3RyKDMpXShmdW5jUGFyYW0pIDogdGFyZ2V0W3Byb3BdKCksXG4gICAgICBzZXR0ZXIgPSAhX2lzRnVuY3Rpb24oY3VycmVudFZhbHVlKSA/IF9zZXR0ZXJQbGFpbiA6IGZ1bmNQYXJhbSA/IF9zZXR0ZXJGdW5jV2l0aFBhcmFtIDogX3NldHRlckZ1bmMsXG4gICAgICBwdDtcblxuICBpZiAoX2lzU3RyaW5nKGVuZCkpIHtcbiAgICBpZiAofmVuZC5pbmRleE9mKFwicmFuZG9tKFwiKSkge1xuICAgICAgZW5kID0gX3JlcGxhY2VSYW5kb20oZW5kKTtcbiAgICB9XG5cbiAgICBpZiAoZW5kLmNoYXJBdCgxKSA9PT0gXCI9XCIpIHtcbiAgICAgIHB0ID0gX3BhcnNlUmVsYXRpdmUocGFyc2VkU3RhcnQsIGVuZCkgKyAoZ2V0VW5pdChwYXJzZWRTdGFydCkgfHwgMCk7XG5cbiAgICAgIGlmIChwdCB8fCBwdCA9PT0gMCkge1xuICAgICAgICAvLyB0byBhdm9pZCBpc05hTiwgbGlrZSBpZiBzb21lb25lIHBhc3NlcyBpbiBhIHZhbHVlIGxpa2UgXCIhPSB3aGF0ZXZlclwiXG4gICAgICAgIGVuZCA9IHB0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmICghb3B0aW9uYWwgfHwgcGFyc2VkU3RhcnQgIT09IGVuZCB8fCBfZm9yY2VBbGxQcm9wVHdlZW5zKSB7XG4gICAgaWYgKCFpc05hTihwYXJzZWRTdGFydCAqIGVuZCkgJiYgZW5kICE9PSBcIlwiKSB7XG4gICAgICAvLyBmdW4gZmFjdDogYW55IG51bWJlciBtdWx0aXBsaWVkIGJ5IFwiXCIgaXMgZXZhbHVhdGVkIGFzIHRoZSBudW1iZXIgMCFcbiAgICAgIHB0ID0gbmV3IFByb3BUd2Vlbih0aGlzLl9wdCwgdGFyZ2V0LCBwcm9wLCArcGFyc2VkU3RhcnQgfHwgMCwgZW5kIC0gKHBhcnNlZFN0YXJ0IHx8IDApLCB0eXBlb2YgY3VycmVudFZhbHVlID09PSBcImJvb2xlYW5cIiA/IF9yZW5kZXJCb29sZWFuIDogX3JlbmRlclBsYWluLCAwLCBzZXR0ZXIpO1xuICAgICAgZnVuY1BhcmFtICYmIChwdC5mcCA9IGZ1bmNQYXJhbSk7XG4gICAgICBtb2RpZmllciAmJiBwdC5tb2RpZmllcihtb2RpZmllciwgdGhpcywgdGFyZ2V0KTtcbiAgICAgIHJldHVybiB0aGlzLl9wdCA9IHB0O1xuICAgIH1cblxuICAgICFjdXJyZW50VmFsdWUgJiYgIShwcm9wIGluIHRhcmdldCkgJiYgX21pc3NpbmdQbHVnaW4ocHJvcCwgZW5kKTtcbiAgICByZXR1cm4gX2FkZENvbXBsZXhTdHJpbmdQcm9wVHdlZW4uY2FsbCh0aGlzLCB0YXJnZXQsIHByb3AsIHBhcnNlZFN0YXJ0LCBlbmQsIHNldHRlciwgc3RyaW5nRmlsdGVyIHx8IF9jb25maWcuc3RyaW5nRmlsdGVyLCBmdW5jUGFyYW0pO1xuICB9XG59LFxuICAgIC8vY3JlYXRlcyBhIGNvcHkgb2YgdGhlIHZhcnMgb2JqZWN0IGFuZCBwcm9jZXNzZXMgYW55IGZ1bmN0aW9uLWJhc2VkIHZhbHVlcyAocHV0dGluZyB0aGUgcmVzdWx0aW5nIHZhbHVlcyBkaXJlY3RseSBpbnRvIHRoZSBjb3B5KSBhcyB3ZWxsIGFzIHN0cmluZ3Mgd2l0aCBcInJhbmRvbSgpXCIgaW4gdGhlbS4gSXQgZG9lcyBOT1QgcHJvY2VzcyByZWxhdGl2ZSB2YWx1ZXMuXG5fcHJvY2Vzc1ZhcnMgPSBmdW5jdGlvbiBfcHJvY2Vzc1ZhcnModmFycywgaW5kZXgsIHRhcmdldCwgdGFyZ2V0cywgdHdlZW4pIHtcbiAgX2lzRnVuY3Rpb24odmFycykgJiYgKHZhcnMgPSBfcGFyc2VGdW5jT3JTdHJpbmcodmFycywgdHdlZW4sIGluZGV4LCB0YXJnZXQsIHRhcmdldHMpKTtcblxuICBpZiAoIV9pc09iamVjdCh2YXJzKSB8fCB2YXJzLnN0eWxlICYmIHZhcnMubm9kZVR5cGUgfHwgX2lzQXJyYXkodmFycykgfHwgX2lzVHlwZWRBcnJheSh2YXJzKSkge1xuICAgIHJldHVybi
1BfaXNTdHJpbmcodmFycykgPyBfcGFyc2VGdW5jT3JTdHJpbmcodmFycywgdHdlZW4sIGluZGV4LCB0YXJnZXQsIHRhcmdldHMpIDogdmFycztcbiAgfVxuXG4gIHZhciBjb3B5ID0ge30sXG4gICAgICBwO1xuXG4gIGZvciAocCBpbiB2YXJzKSB7XG4gICAgY29weVtwXSA9IF9wYXJzZUZ1bmNPclN0cmluZyh2YXJzW3BdLCB0d2VlbiwgaW5kZXgsIHRhcmdldCwgdGFyZ2V0cyk7XG4gIH1cblxuICByZXR1cm4gY29weTtcbn0sXG4gICAgX2NoZWNrUGx1Z2luID0gZnVuY3Rpb24gX2NoZWNrUGx1Z2luKHByb3BlcnR5LCB2YXJzLCB0d2VlbiwgaW5kZXgsIHRhcmdldCwgdGFyZ2V0cykge1xuICB2YXIgcGx1Z2luLCBwdCwgcHRMb29rdXAsIGk7XG5cbiAgaWYgKF9wbHVnaW5zW3Byb3BlcnR5XSAmJiAocGx1Z2luID0gbmV3IF9wbHVnaW5zW3Byb3BlcnR5XSgpKS5pbml0KHRhcmdldCwgcGx1Z2luLnJhd1ZhcnMgPyB2YXJzW3Byb3BlcnR5XSA6IF9wcm9jZXNzVmFycyh2YXJzW3Byb3BlcnR5XSwgaW5kZXgsIHRhcmdldCwgdGFyZ2V0cywgdHdlZW4pLCB0d2VlbiwgaW5kZXgsIHRhcmdldHMpICE9PSBmYWxzZSkge1xuICAgIHR3ZWVuLl9wdCA9IHB0ID0gbmV3IFByb3BUd2Vlbih0d2Vlbi5fcHQsIHRhcmdldCwgcHJvcGVydHksIDAsIDEsIHBsdWdpbi5yZW5kZXIsIHBsdWdpbiwgMCwgcGx1Z2luLnByaW9yaXR5KTtcblxuICAgIGlmICh0d2VlbiAhPT0gX3F1aWNrVHdlZW4pIHtcbiAgICAgIHB0TG9va3VwID0gdHdlZW4uX3B0TG9va3VwW3R3ZWVuLl90YXJnZXRzLmluZGV4T2YodGFyZ2V0KV07IC8vbm90ZTogd2UgY2FuJ3QgdXNlIHR3ZWVuLl9wdExvb2t1cFtpbmRleF0gYmVjYXVzZSBmb3Igc3RhZ2dlcmVkIHR3ZWVucywgdGhlIGluZGV4IGZyb20gdGhlIGZ1bGxUYXJnZXRzIGFycmF5IHdvbid0IG1hdGNoIHdoYXQgaXQgaXMgaW4gZWFjaCBpbmRpdmlkdWFsIHR3ZWVuIHRoYXQgc3Bhd25zIGZyb20gdGhlIHN0YWdnZXIuXG5cbiAgICAgIGkgPSBwbHVnaW4uX3Byb3BzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICBwdExvb2t1cFtwbHVnaW4uX3Byb3BzW2ldXSA9IHB0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwbHVnaW47XG59LFxuICAgIF9vdmVyd3JpdGluZ1R3ZWVuLFxuICAgIC8vc3RvcmUgYSByZWZlcmVuY2UgdGVtcG9yYXJpbHkgc28gd2UgY2FuIGF2b2lkIG92ZXJ3cml0aW5nIGl0c2VsZi5cbl9mb3JjZUFsbFByb3BUd2VlbnMsXG4gICAgX2luaXRUd2VlbiA9IGZ1bmN0aW9uIF9pbml0VHdlZW4odHdlZW4sIHRpbWUsIHRUaW1lKSB7XG4gIHZhciB2YXJzID0gdHdlZW4udmFycyxcbiAgICAgIGVhc2UgPSB2YXJzLmVhc2UsXG4gICAgICBzdGFydEF0ID0gdmFycy5zdGFydEF0LFxuICAgICAgaW1tZWRpYXRlUmVuZGVyID0gdmFycy5pbW1lZGlhdGVSZW5kZXIsXG4gICAgICBsYXp5ID0gdmFycy5sYXp5LFxuICAgICAgb25VcGRhdGUgPSB2YXJzLm9uVXBkYXRlLFxuICAgICAgcnVuQmFja3dhcmRzID0gdmFycy5ydW5CYWNrd2FyZHMsXG4gICAgICB5b3lvRWFzZSA9IHZhcnMueW95b0Vhc2UsXG4gICAgICBrZXlmcmFtZXMgPSB2YXJzLmtleWZyYW1lcyxcbiAgICAgIGF1dG9SZXZlcnQgPSB2YXJzLmF1dG9SZXZlcnQsXG4gICAgICBkdXIgPSB0d2Vlbi5fZHVyLFxuICAgICAgcHJldlN0YXJ0QXQgPSB0d2Vlbi5fc3RhcnRBdCxcbiAgICAgIHRhcmdldHMgPSB0d2Vlbi5fdGFyZ2V0cyxcbiAgICAgIHBhcmVudCA9IHR3ZWVuLnBhcmVudCxcbiAgICAgIGZ1bGxUYXJnZXRzID0gcGFyZW50ICYmIHBhcmVudC5kYXRhID09PSBcIm5lc3RlZFwiID8gcGFyZW50LnZhcnMudGFyZ2V0cyA6IHRhcmdldHMsXG4gICAgICBhdXRvT3ZlcndyaXRlID0gdHdlZW4uX292ZXJ3cml0ZSA9PT0gXCJhdXRvXCIgJiYgIV9zdXBwcmVzc092ZXJ3cml0ZXMsXG4gICAgICB0bCA9IHR3ZWVuLnRpbWVsaW5lLFxuICAgICAgY2xlYW5WYXJzLFxuICAgICAgaSxcbiAgICAgIHAsXG4gICAgICBwdCxcbiAgICAgIHRhcmdldCxcbiAgICAgIGhhc1ByaW9yaXR5LFxuICAgICAgZ3NEYXRhLFxuICAgICAgaGFybmVzcyxcbiAgICAgIHBsdWdpbixcbiAgICAgIHB0TG9va3VwLFxuICAgICAgaW5kZXgsXG4gICAgICBoYXJuZXNzVmFycyxcbiAgICAgIG92ZXJ3cml0dGVuO1xuICB0bCAmJiAoIWtleWZyYW1lcyB8fCAhZWFzZSkgJiYgKGVhc2UgPSBcIm5vbmVcIik7XG4gIHR3ZWVuLl9lYXNlID0gX3BhcnNlRWFzZShlYXNlLCBfZGVmYXVsdHMuZWFzZSk7XG4gIHR3ZWVuLl95RWFzZSA9IHlveW9FYXNlID8gX2ludmVydEVhc2UoX3BhcnNlRWFzZSh5b3lvRWFzZSA9PT0gdHJ1ZSA/IGVhc2UgOiB5b3lvRWFzZSwgX2RlZmF1bHRzLmVhc2UpKSA6IDA7XG5cbiAgaWYgKHlveW9FYXNlICYmIHR3ZWVuLl95b3lvICYmICF0d2Vlbi5fcmVwZWF0KSB7XG4gICAgLy90aGVyZSBtdXN0IGhhdmUgYmVlbiBhIHBhcmVudCB0aW1lbGluZSB3aXRoIHlveW86dHJ1ZSB0aGF0IGlzIGN1cnJlbnRseSBpbiBpdHMgeW95byBwaGFzZSwgc28gZmxpcCB0aGUgZWFzZXMuXG4gICAgeW95b0Vhc2UgPSB0d2Vlbi5feUVhc2U7XG4gICAgdHdlZW4uX3lFYXNlID0gdHdlZW4uX2Vhc2U7XG4gICAgdHdlZW4uX2Vhc2UgPSB5b3lvRWFzZTtcbiAgfVxuXG4gIHR3ZWVuLl9mcm9tID0gIXRsICYmICEhdmFycy5ydW5CYWNrd2FyZHM7IC8vbmVzdGVkIHRpbWVsaW5lcyBzaG91bGQgbmV2ZXIgcnVuIGJhY2t3YXJkcyAtIHRoZSBiYWNrd2FyZHMtbmVzcyBpcyBpbiB0aGUgY2hpbGQgdHdlZW5zLlxuXG4gIGlmICghdGwgfHwga2V5ZnJhbWVzICYmICF2YXJzLnN0YWdnZXIpIHtcbiAgICAvL2lmIHRoZXJlJ3MgYW4gaW50ZXJuYWwgdGltZWxpbmUsIHNraXAgYWxsIHRoZSBwYXJzaW5nIGJlY2F1c2Ugd2UgcGFzc2VkIHRoYXQgdGFzayBkb3duIHRoZSBjaGFpbi5cbiAgICBoYXJuZXNzID0gdGFyZ2V0c1swXSA/IF9nZXRDYWNoZSh0YXJnZXRzWzBdKS5oYXJuZXNzIDogMDtcbiAgICBoYXJuZXNzVmFycyA9IGhhcm5lc3MgJiYgdmFyc1toYXJuZXNzLnByb3BdOyAvL3NvbWVvbmUgbWF5IG5lZWQgdG8gc3BlY2lmeSBDU1Mtc3BlY2lmaWMgdmFsdWVzIEFORCBub24tQ1NTIHZhbHVlcywgbGlrZSBpZiB0aGUgZWxlbWVudCBoYXMgYW4gXCJ4XCIgcHJvcGVydHkgcGx1cyBpdCdzIGEgc3RhbmRhcmQgRE9NIGVsZW1lbnQuIFdlIGFsbG93IHBlb3BsZSB0byBkaXN0aW5ndWlzaCBieSB3cmFwcGluZyBwbHVnaW4tc3BlY2lmaWMgc3R1ZmYgaW4gYSBjc3M6e30gb2JqZWN0IGZvciBleGFtcGxlLlxuXG4gICAgY2xlYW5WYXJzID0gX2NvcHlFeGNsdWRpbmcodmFycywgX3Jlc2VydmVkUHJvcHMpO1xuXG4gICAgaWYgKHByZXZTdGFydEF0KSB7XG4gICAgICBwcmV2U3RhcnRBdC5felRpbWUgPCAwICYmIHByZXZTdGFydEF0LnByb2dyZXNzKDEpOyAvLyBpbiBjYXNlIGl0J3MgYSBsYXp5IHN0YXJ0QXQgdGhhdCBoYXNuJ3QgcmVuZGVyZWQgeWV0LlxuXG4gICAgICB0aW1lIDwgMCAmJiBydW5CYWNrd2FyZHMgJiYgaW1tZWRpYXRlUmVuZGVyICYmICFhdXRvUmV2ZXJ0ID8gcHJldlN0YXJ0QXQucmVuZGVyKC0xLCB0cnVlKSA6IHByZXZTdGFydEF0LnJldmVydChydW5CYWNrd2FyZHMgJiYgZHVyID8gX3JldmVydENvbmZpZ05vS2lsbCA6IF9zdGFydEF0UmV2ZXJ0Q29uZmlnKTsgLy8gaWYgaXQncyBhIFwic3RhcnRBdFwiIChub3QgXCJmcm9tKClcIiBvciBydW5CYWNrd2FyZHM6IHRydWUpLCB3ZSBvbmx5IG5lZWQgdG8gZG8gYSBzaGFsbG93IHJldmVydCAoa2VlcCB0cmFuc2Zvcm1zIGNhY2hlZCBpbiBDU1NQbHVnaW4pXG4gICAgICAvLyBkb24ndCBqdXN0IF9yZW1vdmVGcm9tUGFyZW50KHByZXZTdGFydEF0LnJlbmRlcigtMSwgdHJ1ZSkpIGJlY2F1c2UgdGhhdCdsbCBsZWF2ZSBpbmxpbmUgc3R5bGVzLiBXZSdyZSBjcmVhdGluZyBhIG5ldyBfc3RhcnRBdCBmb3IgXCJzdGFydEF0XCIgdHdlZW5zIHRoYXQgcmUtY2FwdHVyZSB0aGluZ3MgdG8gZW5zdXJlIHRoYXQgaWYgdGhlIHByZS10d2VlbiB2YWx1ZXMgY2hhbmdlZCBzaW5jZSB0aGUgdHdlZW4gd2FzIGNyZWF0ZWQsIHRoZXkncmUgcmVjb3JkZWQuXG5cbiAgICAgIHByZXZTdGFydEF0Ll9sYXp5ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoc3RhcnRBdCkge1xuICAgICAgX3JlbW92ZUZyb21QYXJlbnQodHdlZW4uX3N0YXJ0QXQgPSBUd2Vlbi5zZXQodGFyZ2V0cywgX3NldERlZmF1bHRzKHtcbiAgICAgICAgZGF0YTogXCJpc1N0YXJ0XCIsXG4gICAgICAgIG92ZXJ3cml0ZTogZmFsc2UsXG4gICAgICAgI
1HBhcmVudDogcGFyZW50LFxuICAgICAgICBpbW1lZGlhdGVSZW5kZXI6IHRydWUsXG4gICAgICAgIGxhenk6ICFwcmV2U3RhcnRBdCAmJiBfaXNOb3RGYWxzZShsYXp5KSxcbiAgICAgICAgc3RhcnRBdDogbnVsbCxcbiAgICAgICAgZGVsYXk6IDAsXG4gICAgICAgIG9uVXBkYXRlOiBvblVwZGF0ZSAmJiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIF9jYWxsYmFjayh0d2VlbiwgXCJvblVwZGF0ZVwiKTtcbiAgICAgICAgfSxcbiAgICAgICAgc3RhZ2dlcjogMFxuICAgICAgfSwgc3RhcnRBdCkpKTsgLy9jb3B5IHRoZSBwcm9wZXJ0aWVzL3ZhbHVlcyBpbnRvIGEgbmV3IG9iamVjdCB0byBhdm9pZCBjb2xsaXNpb25zLCBsaWtlIHZhciB0byA9IHt4OjB9LCBmcm9tID0ge3g6NTAwfTsgdGltZWxpbmUuZnJvbVRvKGUsIGZyb20sIHRvKS5mcm9tVG8oZSwgdG8sIGZyb20pO1xuXG5cbiAgICAgIHR3ZWVuLl9zdGFydEF0Ll9kcCA9IDA7IC8vIGRvbid0IGFsbG93IGl0IHRvIGdldCBwdXQgYmFjayBpbnRvIHJvb3QgdGltZWxpbmUhIExpa2Ugd2hlbiByZXZlcnQoKSBpcyBjYWxsZWQgYW5kIHRvdGFsVGltZSgpIGdldHMgc2V0LlxuXG4gICAgICB0d2Vlbi5fc3RhcnRBdC5fc2F0ID0gdHdlZW47IC8vIHVzZWQgaW4gZ2xvYmFsVGltZSgpLiBfc2F0IHN0YW5kcyBmb3IgX3N0YXJ0QXRUd2VlblxuXG4gICAgICB0aW1lIDwgMCAmJiAoX3JldmVydGluZyB8fCAhaW1tZWRpYXRlUmVuZGVyICYmICFhdXRvUmV2ZXJ0KSAmJiB0d2Vlbi5fc3RhcnRBdC5yZXZlcnQoX3JldmVydENvbmZpZ05vS2lsbCk7IC8vIHJhcmUgZWRnZSBjYXNlLCBsaWtlIGlmIGEgcmVuZGVyIGlzIGZvcmNlZCBpbiB0aGUgbmVnYXRpdmUgZGlyZWN0aW9uIG9mIGEgbm9uLWluaXR0ZWQgdHdlZW4uXG5cbiAgICAgIGlmIChpbW1lZGlhdGVSZW5kZXIpIHtcbiAgICAgICAgaWYgKGR1ciAmJiB0aW1lIDw9IDAgJiYgdFRpbWUgPD0gMCkge1xuICAgICAgICAgIC8vIGNoZWNrIHRUaW1lIGhlcmUgYmVjYXVzZSBpbiB0aGUgY2FzZSBvZiBhIHlveW8gdHdlZW4gd2hvc2UgcGxheWhlYWQgZ2V0cyBwdXNoZWQgdG8gdGhlIGVuZCBsaWtlIHR3ZWVuLnByb2dyZXNzKDEpLCB3ZSBzaG91bGQgYWxsb3cgaXQgdGhyb3VnaCBzbyB0aGF0IHRoZSBvbkNvbXBsZXRlIGdldHMgZmlyZWQgcHJvcGVybHkuXG4gICAgICAgICAgdGltZSAmJiAodHdlZW4uX3pUaW1lID0gdGltZSk7XG4gICAgICAgICAgcmV0dXJuOyAvL3dlIHNraXAgaW5pdGlhbGl6YXRpb24gaGVyZSBzbyB0aGF0IG92ZXJ3cml0aW5nIGRvZXNuJ3Qgb2NjdXIgdW50aWwgdGhlIHR3ZWVuIGFjdHVhbGx5IGJlZ2lucy4gT3RoZXJ3aXNlLCBpZiB5b3UgY3JlYXRlIHNldmVyYWwgaW1tZWRpYXRlUmVuZGVyOnRydWUgdHdlZW5zIG9mIHRoZSBzYW1lIHRhcmdldC9wcm9wZXJ0aWVzIHRvIGRyb3AgaW50byBhIFRpbWVsaW5lLCB0aGUgbGFzdCBvbmUgY3JlYXRlZCB3b3VsZCBvdmVyd3JpdGUgdGhlIGZpcnN0IG9uZXMgYmVjYXVzZSB0aGV5IGRpZG4ndCBnZXQgcGxhY2VkIGludG8gdGhlIHRpbWVsaW5lIHlldCBiZWZvcmUgdGhlIGZpcnN0IHJlbmRlciBvY2N1cnMgYW5kIGtpY2tzIGluIG92ZXJ3cml0aW5nLlxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChydW5CYWNrd2FyZHMgJiYgZHVyKSB7XG4gICAgICAvL2Zyb20oKSB0d2VlbnMgbXVzdCBiZSBoYW5kbGVkIHVuaXF1ZWx5OiB0aGVpciBiZWdpbm5pbmcgdmFsdWVzIG11c3QgYmUgcmVuZGVyZWQgYnV0IHdlIGRvbid0IHdhbnQgb3ZlcndyaXRpbmcgdG8gb2NjdXIgeWV0ICh3aGVuIHRpbWUgaXMgc3RpbGwgMCkuIFdhaXQgdW50aWwgdGhlIHR3ZWVuIGFjdHVhbGx5IGJlZ2lucyBiZWZvcmUgZG9pbmcgYWxsIHRoZSByb3V0aW5lcyBsaWtlIG92ZXJ3cml0aW5nLiBBdCB0aGF0IHRpbWUsIHdlIHNob3VsZCByZW5kZXIgYXQgdGhlIEVORCBvZiB0aGUgdHdlZW4gdG8gZW5zdXJlIHRoYXQgdGhpbmdzIGluaXRpYWxpemUgY29ycmVjdGx5IChyZW1lbWJlciwgZnJvbSgpIHR3ZWVucyBnbyBiYWNrd2FyZHMpXG4gICAgICBpZiAoIXByZXZTdGFydEF0KSB7XG4gICAgICAgIHRpbWUgJiYgKGltbWVkaWF0ZVJlbmRlciA9IGZhbHNlKTsgLy9pbiByYXJlIGNhc2VzIChsaWtlIGlmIGEgZnJvbSgpIHR3ZWVuIHJ1bnMgYW5kIHRoZW4gaXMgaW52YWxpZGF0ZSgpLWVkKSwgaW1tZWRpYXRlUmVuZGVyIGNvdWxkIGJlIHRydWUgYnV0IHRoZSBpbml0aWFsIGZvcmNlZC1yZW5kZXIgZ2V0cyBza2lwcGVkLCBzbyB0aGVyZSdzIG5vIG5lZWQgdG8gZm9yY2UgdGhlIHJlbmRlciBpbiB0aGlzIGNvbnRleHQgd2hlbiB0aGUgX3RpbWUgaXMgZ3JlYXRlciB0aGFuIDBcblxuICAgICAgICBwID0gX3NldERlZmF1bHRzKHtcbiAgICAgICAgICBvdmVyd3JpdGU6IGZhbHNlLFxuICAgICAgICAgIGRhdGE6IFwiaXNGcm9tU3RhcnRcIixcbiAgICAgICAgICAvL3dlIHRhZyB0aGUgdHdlZW4gd2l0aCBhcyBcImlzRnJvbVN0YXJ0XCIgc28gdGhhdCBpZiBbaW5zaWRlIGEgcGx1Z2luXSB3ZSBuZWVkIHRvIG9ubHkgZG8gc29tZXRoaW5nIGF0IHRoZSB2ZXJ5IEVORCBvZiBhIHR3ZWVuLCB3ZSBoYXZlIGEgd2F5IG9mIGlkZW50aWZ5aW5nIHRoaXMgdHdlZW4gYXMgbWVyZWx5IHRoZSBvbmUgdGhhdCdzIHNldHRpbmcgdGhlIGJlZ2lubmluZyB2YWx1ZXMgZm9yIGEgXCJmcm9tKClcIiB0d2Vlbi4gRm9yIGV4YW1wbGUsIGNsZWFyUHJvcHMgaW4gQ1NTUGx1Z2luIHNob3VsZCBvbmx5IGdldCBhcHBsaWVkIGF0IHRoZSB2ZXJ5IEVORCBvZiBhIHR3ZWVuIGFuZCB3aXRob3V0IHRoaXMgdGFnLCBmcm9tKC4uLntoZWlnaHQ6MTAwLCBjbGVhclByb3BzOlwiaGVpZ2h0XCIsIGRlbGF5OjF9KSB3b3VsZCB3aXBlIHRoZSBoZWlnaHQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdHdlZW4gYW5kIGFmdGVyIDEgc2Vjb25kLCBpdCdkIGtpY2sgYmFjayBpbi5cbiAgICAgICAgICBsYXp5OiBpbW1lZGlhdGVSZW5kZXIgJiYgIXByZXZTdGFydEF0ICYmIF9pc05vdEZhbHNlKGxhenkpLFxuICAgICAgICAgIGltbWVkaWF0ZVJlbmRlcjogaW1tZWRpYXRlUmVuZGVyLFxuICAgICAgICAgIC8vemVyby1kdXJhdGlvbiB0d2VlbnMgcmVuZGVyIGltbWVkaWF0ZWx5IGJ5IGRlZmF1bHQsIGJ1dCBpZiB3ZSdyZSBub3Qgc3BlY2lmaWNhbGx5IGluc3RydWN0ZWQgdG8gcmVuZGVyIHRoaXMgdHdlZW4gaW1tZWRpYXRlbHksIHdlIHNob3VsZCBza2lwIHRoaXMgYW5kIG1lcmVseSBfaW5pdCgpIHRvIHJlY29yZCB0aGUgc3RhcnRpbmcgdmFsdWVzIChyZW5kZXJpbmcgdGhlbSBpbW1lZGlhdGVseSB3b3VsZCBwdXNoIHRoZW0gdG8gY29tcGxldGlvbiB3aGljaCBpcyB3YXN0ZWZ1bCBpbiB0aGF0IGNhc2UgLSB3ZSdkIGhhdmUgdG8gcmVuZGVyKC0xKSBpbW1lZGlhdGVseSBhZnRlcilcbiAgICAgICAgICBzdGFnZ2VyOiAwLFxuICAgICAgICAgI
1HBhcmVudDogcGFyZW50IC8vZW5zdXJlcyB0aGF0IG5lc3RlZCB0d2VlbnMgdGhhdCBoYWQgYSBzdGFnZ2VyIGFyZSBoYW5kbGVkIHByb3Blcmx5LCBsaWtlIGdzYXAuZnJvbShcIi5jbGFzc1wiLCB7eTogZ3NhcC51dGlscy53cmFwKFstMTAwLDEwMF0pLCBzdGFnZ2VyOiAwLjV9KVxuXG4gICAgICAgIH0sIGNsZWFuVmFycyk7XG4gICAgICAgIGhhcm5lc3NWYXJzICYmIChwW2hhcm5lc3MucHJvcF0gPSBoYXJuZXNzVmFycyk7IC8vIGluIGNhc2Ugc29tZW9uZSBkb2VzIHNvbWV0aGluZyBsaWtlIC5mcm9tKC4uLiwge2Nzczp7fX0pXG5cbiAgICAgICAgX3JlbW92ZUZyb21QYXJlbnQodHdlZW4uX3N0YXJ0QXQgPSBUd2Vlbi5zZXQodGFyZ2V0cywgcCkpO1xuXG4gICAgICAgIHR3ZWVuLl9zdGFydEF0Ll9kcCA9IDA7IC8vIGRvbid0IGFsbG93IGl0IHRvIGdldCBwdXQgYmFjayBpbnRvIHJvb3QgdGltZWxpbmUhXG5cbiAgICAgICAgdHdlZW4uX3N0YXJ0QXQuX3NhdCA9IHR3ZWVuOyAvLyB1c2VkIGluIGdsb2JhbFRpbWUoKVxuXG4gICAgICAgIHRpbWUgPCAwICYmIChfcmV2ZXJ0aW5nID8gdHdlZW4uX3N0YXJ0QXQucmV2ZXJ0KF9yZXZlcnRDb25maWdOb0tpbGwpIDogdHdlZW4uX3N0YXJ0QXQucmVuZGVyKC0xLCB0cnVlKSk7XG4gICAgICAgIHR3ZWVuLl96VGltZSA9IHRpbWU7XG5cbiAgICAgICAgaWYgKCFpbW1lZGlhdGVSZW5kZXIpIHtcbiAgICAgICAgICBfaW5pdFR3ZWVuKHR3ZWVuLl9zdGFydEF0LCBfdGlueU51bSwgX3RpbnlOdW0pOyAvL2Vuc3VyZXMgdGhhdCB0aGUgaW5pdGlhbCB2YWx1ZXMgYXJlIHJlY29yZGVkXG5cbiAgICAgICAgfSBlbHNlIGlmICghdGltZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHR3ZWVuLl9wdCA9IHR3ZWVuLl9wdENhY2hlID0gMDtcbiAgICBsYXp5ID0gZHVyICYmIF9pc05vdEZhbHNlKGxhenkpIHx8IGxhenkgJiYgIWR1cjtcblxuICAgIGZvciAoaSA9IDA7IGkgPCB0YXJnZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0YXJnZXQgPSB0YXJnZXRzW2ldO1xuICAgICAgZ3NEYXRhID0gdGFyZ2V0Ll9nc2FwIHx8IF9oYXJuZXNzKHRhcmdldHMpW2ldLl9nc2FwO1xuICAgICAgdHdlZW4uX3B0TG9va3VwW2ldID0gcHRMb29rdXAgPSB7fTtcbiAgICAgIF9sYXp5TG9va3VwW2dzRGF0YS5pZF0gJiYgX2xhenlUd2VlbnMubGVuZ3RoICYmIF9sYXp5UmVuZGVyKCk7IC8vaWYgb3RoZXIgdHdlZW5zIG9mIHRoZSBzYW1lIHRhcmdldCBoYXZlIHJlY2VudGx5IGluaXR0ZWQgYnV0IGhhdmVuJ3QgcmVuZGVyZWQgeWV0LCB3ZSd2ZSBnb3QgdG8gZm9yY2UgdGhlIHJlbmRlciBzbyB0aGF0IHRoZSBzdGFydGluZyB2YWx1ZXMgYXJlIGNvcnJlY3QgKGltYWdpbmUgcG9wdWxhdGluZyBhIHRpbWVsaW5lIHdpdGggYSBidW5jaCBvZiBzZXF1ZW50aWFsIHR3ZWVucyBhbmQgdGhlbiBqdW1waW5nIHRvIHRoZSBlbmQpXG5cbiAgICAgIGluZGV4ID0gZnVsbFRhcmdldHMgPT09IHRhcmdldHMgPyBpIDogZnVsbFRhcmdldHMuaW5kZXhPZih0YXJnZXQpO1xuXG4gICAgICBpZiAoaGFybmVzcyAmJiAocGx1Z2luID0gbmV3IGhhcm5lc3MoKSkuaW5pdCh0YXJnZXQsIGhhcm5lc3NWYXJzIHx8IGNsZWFuVmFycywgdHdlZW4sIGluZGV4LCBmdWxsVGFyZ2V0cykgIT09IGZhbHNlKSB7XG4gICAgICAgIHR3ZWVuLl9wdCA9IHB0ID0gbmV3IFByb3BUd2Vlbih0d2Vlbi5fcHQsIHRhcmdldCwgcGx1Z2luLm5hbWUsIDAsIDEsIHBsdWdpbi5yZW5kZXIsIHBsdWdpbiwgMCwgcGx1Z2luLnByaW9yaXR5KTtcblxuICAgICAgICBwbHVnaW4uX3Byb3BzLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICBwdExvb2t1cFtuYW1lXSA9IHB0O1xuICAgICAgICB9KTtcblxuICAgICAgICBwbHVnaW4ucHJpb3JpdHkgJiYgKGhhc1ByaW9yaXR5ID0gMSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghaGFybmVzcyB8fCBoYXJuZXNzVmFycykge1xuICAgICAgICBmb3IgKHAgaW4gY2xlYW5WYXJzKSB7XG4gICAgICAgICAgaWYgKF9wbHVnaW5zW3BdICYmIChwbHVnaW4gPSBfY2hlY2tQbHVnaW4ocCwgY2xlYW5WYXJzLCB0d2VlbiwgaW5kZXgsIHRhcmdldCwgZnVsbFRhcmdldHMpKSkge1xuICAgICAgICAgICAgcGx1Z2luLnByaW9yaXR5ICYmIChoYXNQcmlvcml0eSA9IDEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwdExvb2t1cFtwXSA9IHB0ID0gX2FkZFByb3BUd2Vlbi5jYWxsKHR3ZWVuLCB0YXJnZXQsIHAsIFwiZ2V0XCIsIGNsZWFuVmFyc1twXSwgaW5kZXgsIGZ1bGxUYXJnZXRzLCAwLCB2YXJzLnN0cmluZ0ZpbHRlcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHR3ZWVuLl9vcCAmJiB0d2Vlbi5fb3BbaV0gJiYgdHdlZW4ua2lsbCh0YXJnZXQsIHR3ZWVuLl9vcFtpXSk7XG5cbiAgICAgIGlmIChhdXRvT3ZlcndyaXRlICYmIHR3ZWVuLl9wdCkge1xuICAgICAgICBfb3ZlcndyaXRpbmdUd2VlbiA9IHR3ZWVuO1xuXG4gICAgICAgIF9nbG9iYWxUaW1lbGluZS5raWxsVHdlZW5zT2YodGFyZ2V0LCBwdExvb2t1cCwgdHdlZW4uZ2xvYmFsVGltZSh0aW1lKSk7IC8vIG1ha2Ugc3VyZSB0aGUgb3ZlcndyaXRpbmcgZG9lc24ndCBvdmVyd3JpdGUgVEhJUyB0d2VlbiEhIVxuXG5cbiAgICAgICAgb3ZlcndyaXR0ZW4gPSAhdHdlZW4ucGFyZW50O1xuICAgICAgICBfb3ZlcndyaXRpbmdUd2VlbiA9IDA7XG4gICAgICB9XG5cbiAgICAgIHR3ZWVuLl9wdCAmJiBsYXp5ICYmIChfbGF6eUxvb2t1cFtnc0RhdGEuaWRdID0gMSk7XG4gICAgfVxuXG4gICAgaGFzUHJpb3JpdHkgJiYgX3NvcnRQcm9wVHdlZW5zQnlQcmlvcml0eSh0d2Vlbik7XG4gICAgdHdlZW4uX29uSW5pdCAmJiB0d2Vlbi5fb25Jbml0KHR3ZWVuKTsgLy9wbHVnaW5zIGxpa2UgUm91bmRQcm9wcyBtdXN0IHdhaXQgdW50aWwgQUxMIG9mIHRoZSBQcm9wVHdlZW5zIGFyZSBpbnN0YW50aWF0ZWQuIEluIHRoZSBwbHVnaW4ncyBpbml0KCkgZnVuY3Rpb24sIGl0IHNldHMgdGhlIF9vbkluaXQgb24gdGhlIHR3ZWVuIGluc3RhbmNlLiBNYXkgbm90IGJlIHByZXR0eS9pbnR1aXRpdmUsIGJ1dCBpdCdzIGZhc3QgYW5kIGtlZXBzIGZpbGUgc2l6ZSBkb3duLlxuICB9XG5cbiAgdHdlZW4uX29uVXBkYXRlID0gb25VcGRhdGU7XG4gIHR3ZWVuLl9pbml0dGVkID0gKCF0d2Vlbi5fb3AgfHwgdHdlZW4uX3B0KSAmJiAhb3ZlcndyaXR0ZW47IC8vIGlmIG92ZXJ3cml0dGVuUHJvcHMgcmVzdWx0ZWQgaW4gdGhlIGVudGlyZSB0d2VlbiBiZWluZyBraWxsZWQsIGRvIE5PVCBmbGFnIGl0IGFzIGluaXR0ZWQgb3IgZWxzZSBpdCBtYXkgcmVuZGVyIGZvciBvbmUgdGljay5cblxuICBrZXlmcmFtZXMgJiYgdGltZSA8PSAwICYmIHRsLnJlbmRlcihfYmlnTnVtLCB0cnVlLCB0cnVlKTsgLy8gaWYgdGhlcmUncyBhIDAlIGtleWZyYW1lLCBpdCdsbCByZW5kZXIgaW4gdGhlIFwiYmVmb3JlXCIg
1c3RhdGUgZm9yIGFueSBzdGFnZ2VyZWQvZGVsYXllZCBhbmltYXRpb25zIHRodXMgd2hlbiB0aGUgZm9sbG93aW5nIHR3ZWVuIGluaXRpYWxpemVzLCBpdCdsbCB1c2UgdGhlIFwiYmVmb3JlXCIgc3RhdGUgaW5zdGVhZCBvZiB0aGUgXCJhZnRlclwiIHN0YXRlIGFzIHRoZSBpbml0aWFsIHZhbHVlcy5cbn0sXG4gICAgX3VwZGF0ZVByb3BUd2VlbnMgPSBmdW5jdGlvbiBfdXBkYXRlUHJvcFR3ZWVucyh0d2VlbiwgcHJvcGVydHksIHZhbHVlLCBzdGFydCwgc3RhcnRJc1JlbGF0aXZlLCByYXRpbywgdGltZSwgc2tpcFJlY3Vyc2lvbikge1xuICB2YXIgcHRDYWNoZSA9ICh0d2Vlbi5fcHQgJiYgdHdlZW4uX3B0Q2FjaGUgfHwgKHR3ZWVuLl9wdENhY2hlID0ge30pKVtwcm9wZXJ0eV0sXG4gICAgICBwdCxcbiAgICAgIHJvb3RQVCxcbiAgICAgIGxvb2t1cCxcbiAgICAgIGk7XG5cbiAgaWYgKCFwdENhY2hlKSB7XG4gICAgcHRDYWNoZSA9IHR3ZWVuLl9wdENhY2hlW3Byb3BlcnR5XSA9IFtdO1xuICAgIGxvb2t1cCA9IHR3ZWVuLl9wdExvb2t1cDtcbiAgICBpID0gdHdlZW4uX3RhcmdldHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgcHQgPSBsb29rdXBbaV1bcHJvcGVydHldO1xuXG4gICAgICBpZiAocHQgJiYgcHQuZCAmJiBwdC5kLl9wdCkge1xuICAgICAgICAvLyBpdCdzIGEgcGx1Z2luLCBzbyBmaW5kIHRoZSBuZXN0ZWQgUHJvcFR3ZWVuXG4gICAgICAgIHB0ID0gcHQuZC5fcHQ7XG5cbiAgICAgICAgd2hpbGUgKHB0ICYmIHB0LnAgIT09IHByb3BlcnR5ICYmIHB0LmZwICE9PSBwcm9wZXJ0eSkge1xuICAgICAgICAgIC8vIFwiZnBcIiBpcyBmdW5jdGlvblBhcmFtIGZvciB0aGluZ3MgbGlrZSBzZXR0aW5nIENTUyB2YXJpYWJsZXMgd2hpY2ggcmVxdWlyZSAuc2V0UHJvcGVydHkoXCItLXZhci1uYW1lXCIsIHZhbHVlKVxuICAgICAgICAgIHB0ID0gcHQuX25leHQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFwdCkge1xuICAgICAgICAvLyB0aGVyZSBpcyBubyBQcm9wVHdlZW4gYXNzb2NpYXRlZCB3aXRoIHRoYXQgcHJvcGVydHksIHNvIHdlIG11c3QgRk9SQ0Ugb25lIHRvIGJlIGNyZWF0ZWQgYW5kIGRpdGNoIG91dCBvZiB0aGlzXG4gICAgICAgIC8vIGlmIHRoZSB0d2VlbiBoYXMgb3RoZXIgcHJvcGVydGllcyB0aGF0IGFscmVhZHkgcmVuZGVyZWQgYXQgbmV3IHBvc2l0aW9ucywgd2UnZCBub3JtYWxseSBoYXZlIHRvIHJld2luZCB0byBwdXQgdGhlbSBiYWNrIGxpa2UgdHdlZW4ucmVuZGVyKDAsIHRydWUpIGJlZm9yZSBmb3JjaW5nIGFuIF9pbml0VHdlZW4oKSwgYnV0IHRoYXQgY2FuIGNyZWF0ZSBhbm90aGVyIGVkZ2UgY2FzZSBsaWtlIHR3ZWVuaW5nIGEgdGltZWxpbmUncyBwcm9ncmVzcyB3b3VsZCB0cmlnZ2VyIG9uVXBkYXRlcyB0byBmaXJlIHdoaWNoIGNvdWxkIG1vdmUgb3RoZXIgdGhpbmdzIGFyb3VuZC4gSXQncyBiZXR0ZXIgdG8ganVzdCBpbmZvcm0gdXNlcnMgdGhhdCAucmVzZXRUbygpIHNob3VsZCBPTkxZIGJlIHVzZWQgZm9yIHR3ZWVucyB0aGF0IGFscmVhZHkgaGF2ZSB0aGF0IHByb3BlcnR5LiBGb3IgZXhhbXBsZSwgeW91IGNhbid0IGdzYXAudG8oLi4ueyB5OiAwIH0pIGFuZCB0aGVuIHR3ZWVuLnJlc3RUbyhcInhcIiwgMjAwKSBmb3IgZXhhbXBsZS5cbiAgICAgICAgX2ZvcmNlQWxsUHJvcFR3ZWVucyA9IDE7IC8vIG90aGVyd2lzZSwgd2hlbiB3ZSBfYWRkUHJvcFR3ZWVuKCkgYW5kIGl0IGZpbmRzIG5vIGNoYW5nZSBiZXR3ZWVuIHRoZSBzdGFydCBhbmQgZW5kIHZhbHVlcywgaXQgc2tpcHMgY3JlYXRpbmcgYSBQcm9wVHdlZW4gKGZvciBlZmZpY2llbmN5Li4ud2h5IHR3ZWVuIHdoZW4gdGhlcmUncyBubyBkaWZmZXJlbmNlPykgYnV0IGluIHRoaXMgY2FzZSB3ZSBORUVEIHRoYXQgUHJvcFR3ZWVuIGNyZWF0ZWQgc28gd2UgY2FuIGVkaXQgaXQuXG5cbiAgICAgICAgdHdlZW4udmFyc1twcm9wZXJ0eV0gPSBcIis9MFwiO1xuXG4gICAgICAgIF9pbml0VHdlZW4odHdlZW4sIHRpbWUpO1xuXG4gICAgICAgIF9mb3JjZUFsbFByb3BUd2VlbnMgPSAwO1xuICAgICAgICByZXR1cm4gc2tpcFJlY3Vyc2lvbiA/IF93YXJuKHByb3BlcnR5ICsgXCIgbm90IGVsaWdpYmxlIGZvciByZXNldFwiKSA6IDE7IC8vIGlmIHNvbWVvbmUgdHJpZXMgdG8gZG8gYSBxdWlja1RvKCkgb24gYSBzcGVjaWFsIHByb3BlcnR5IGxpa2UgYm9yZGVyUmFkaXVzIHdoaWNoIG11c3QgZ2V0IHNwbGl0IGludG8gNCBkaWZmZXJlbnQgcHJvcGVydGllcywgdGhhdCdzIG5vdCBlbGlnaWJsZSBmb3IgLnJlc2V0VG8oKS5cbiAgICAgIH1cblxuICAgICAgcHRDYWNoZS5wdXNoKHB0KTtcbiAgICB9XG4gIH1cblxuICBpID0gcHRDYWNoZS5sZW5ndGg7XG5cbiAgd2hpbGUgKGktLSkge1xuICAgIHJvb3RQVCA9IHB0Q2FjaGVbaV07XG4gICAgcHQgPSByb290UFQuX3B0IHx8IHJvb3RQVDsgLy8gY29tcGxleCB2YWx1ZXMgbWF5IGhhdmUgbmVzdGVkIFByb3BUd2VlbnMuIFdlIG9ubHkgYWNjb21tb2RhdGUgdGhlIEZJUlNUIHZhbHVlLlxuXG4gICAgcHQucyA9IChzdGFydCB8fCBzdGFydCA9PT0gMCkgJiYgIXN0YXJ0SXNSZWxhdGl2ZSA/IHN0YXJ0IDogcHQucyArIChzdGFydCB8fCAwKSArIHJhdGlvICogcHQuYztcbiAgICBwdC5jID0gdmFsdWUgLSBwdC5zO1xuICAgIHJvb3RQVC5lICYmIChyb290UFQuZSA9IF9yb3VuZCh2YWx1ZSkgKyBnZXRVbml0KHJvb3RQVC5lKSk7IC8vIG1haW5seSBmb3IgQ1NTUGx1Z2luIChlbmQgdmFsdWUpXG5cbiAgICByb290UFQuYiAmJiAocm9vdFBULmIgPSBwdC5zICsgZ2V0VW5pdChyb290UFQuYikpOyAvLyAoYmVnaW5uaW5nIHZhbHVlKVxuICB9XG59LFxuICAgIF9hZGRBbGlhc2VzVG9WYXJzID0gZnVuY3Rpb24gX2FkZEFsaWFzZXNUb1ZhcnModGFyZ2V0cywgdmFycykge1xuICB2YXIgaGFybmVzcyA9IHRhcmdldHNbMF0gPyBfZ2V0Q2FjaGUodGFyZ2V0c1swXSkuaGFybmVzcyA6IDAsXG4gICAgICBwcm9wZXJ0eUFsaWFzZXMgPSBoYXJuZXNzICYmIGhhcm5lc3MuYWxpYXNlcyxcbiAgICAgIGNvcHksXG4gICAgICBwLFxuICAgICAgaSxcbiAgICAgIGFsaWFzZXM7XG5cbiAgaWYgKCFwcm9wZXJ0eUFsaWFzZXMpIHtcbiAgICByZXR1cm4gdmFycztcbiAgfVxuXG4gIGNvcHkgPSBfbWVyZ2Uoe30sIHZhcnMpO1xuXG4gIGZvciAocCBpbiBwcm9wZXJ0eUFsaWFzZXMpIHtcbiAgICBpZiAocCBpbiBjb3B5KSB7XG4gICAgICBhbGlhc2VzID0gcHJvcGVydHlBbGlhc2VzW3BdLnNwbGl0KFwiLFwiKTtcbiAgICAgIGkgPSBhbGlhc2VzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICBjb3B5W2FsaWFzZXNbaV1dID0gY29weVtwXTtcbiAgICAgIH1cbiAgICB9XG4gI
1H1cblxuICByZXR1cm4gY29weTtcbn0sXG4gICAgLy8gcGFyc2VzIG11bHRpcGxlIGZvcm1hdHMsIGxpa2Uge1wiMCVcIjoge3g6IDEwMH0sIHtcIjUwJVwiOiB7eDogLTIwfX0gYW5kIHsgeDoge1wiMCVcIjogMTAwLCBcIjUwJVwiOiAtMjB9IH0sIGFuZCBhbiBcImVhc2VcIiBjYW4gYmUgc2V0IG9uIGFueSBvYmplY3QuIFdlIHBvcHVsYXRlIGFuIFwiYWxsUHJvcHNcIiBvYmplY3Qgd2l0aCBhbiBBcnJheSBmb3IgZWFjaCBwcm9wZXJ0eSwgbGlrZSB7eDogW3t9LCB7fV0sIHk6W3t9LCB7fV19IHdpdGggZGF0YSBmb3IgZWFjaCBwcm9wZXJ0eSB0d2Vlbi4gVGhlIG9iamVjdHMgaGF2ZSBhIFwidFwiICh0aW1lKSwgXCJ2XCIsICh2YWx1ZSksIGFuZCBcImVcIiAoZWFzZSkgcHJvcGVydHkuIFRoaXMgYWxsb3dzIHVzIHRvIHBpZWNlIHRvZ2V0aGVyIGEgdGltZWxpbmUgbGF0ZXIuXG5fcGFyc2VLZXlmcmFtZSA9IGZ1bmN0aW9uIF9wYXJzZUtleWZyYW1lKHByb3AsIG9iaiwgYWxsUHJvcHMsIGVhc2VFYWNoKSB7XG4gIHZhciBlYXNlID0gb2JqLmVhc2UgfHwgZWFzZUVhY2ggfHwgXCJwb3dlcjEuaW5PdXRcIixcbiAgICAgIHAsXG4gICAgICBhO1xuXG4gIGlmIChfaXNBcnJheShvYmopKSB7XG4gICAgYSA9IGFsbFByb3BzW3Byb3BdIHx8IChhbGxQcm9wc1twcm9wXSA9IFtdKTsgLy8gdCA9IHRpbWUgKG91dCBvZiAxMDApLCB2ID0gdmFsdWUsIGUgPSBlYXNlXG5cbiAgICBvYmouZm9yRWFjaChmdW5jdGlvbiAodmFsdWUsIGkpIHtcbiAgICAgIHJldHVybiBhLnB1c2goe1xuICAgICAgICB0OiBpIC8gKG9iai5sZW5ndGggLSAxKSAqIDEwMCxcbiAgICAgICAgdjogdmFsdWUsXG4gICAgICAgIGU6IGVhc2VcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGZvciAocCBpbiBvYmopIHtcbiAgICAgIGEgPSBhbGxQcm9wc1twXSB8fCAoYWxsUHJvcHNbcF0gPSBbXSk7XG4gICAgICBwID09PSBcImVhc2VcIiB8fCBhLnB1c2goe1xuICAgICAgICB0OiBwYXJzZUZsb2F0KHByb3ApLFxuICAgICAgICB2OiBvYmpbcF0sXG4gICAgICAgIGU6IGVhc2VcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufSxcbiAgICBfcGFyc2VGdW5jT3JTdHJpbmcgPSBmdW5jdGlvbiBfcGFyc2VGdW5jT3JTdHJpbmcodmFsdWUsIHR3ZWVuLCBpLCB0YXJnZXQsIHRhcmdldHMpIHtcbiAgcmV0dXJuIF9pc0Z1bmN0aW9uKHZhbHVlKSA/IHZhbHVlLmNhbGwodHdlZW4sIGksIHRhcmdldCwgdGFyZ2V0cykgOiBfaXNTdHJpbmcodmFsdWUpICYmIH52YWx1ZS5pbmRleE9mKFwicmFuZG9tKFwiKSA/IF9yZXBsYWNlUmFuZG9tKHZhbHVlKSA6IHZhbHVlO1xufSxcbiAgICBfc3RhZ2dlclR3ZWVuUHJvcHMgPSBfY2FsbGJhY2tOYW1lcyArIFwicmVwZWF0LHJlcGVhdERlbGF5LHlveW8scmVwZWF0UmVmcmVzaCx5b3lvRWFzZSxhdXRvUmV2ZXJ0XCIsXG4gICAgX3N0YWdnZXJQcm9wc1RvU2tpcCA9IHt9O1xuXG5fZm9yRWFjaE5hbWUoX3N0YWdnZXJUd2VlblByb3BzICsgXCIsaWQsc3RhZ2dlcixkZWxheSxkdXJhdGlvbixwYXVzZWQsc2Nyb2xsVHJpZ2dlclwiLCBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gX3N0YWdnZXJQcm9wc1RvU2tpcFtuYW1lXSA9IDE7XG59KTtcbi8qXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogVFdFRU5cbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuXG5leHBvcnQgdmFyIFR3ZWVuID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfQW5pbWF0aW9uMikge1xuICBfaW5oZXJpdHNMb29zZShUd2VlbiwgX0FuaW1hdGlvbjIpO1xuXG4gIGZ1bmN0aW9uIFR3ZWVuKHRhcmdldHMsIHZhcnMsIHBvc2l0aW9uLCBza2lwSW5oZXJpdCkge1xuICAgIHZhciBfdGhpczM7XG5cbiAgICBpZiAodHlwZW9mIHZhcnMgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHBvc2l0aW9uLmR1cmF0aW9uID0gdmFycztcbiAgICAgIHZhcnMgPSBwb3NpdGlvbjtcbiAgICAgIHBvc2l0aW9uID0gbnVsbDtcbiAgICB9XG5cbiAgICBfdGhpczMgPSBfQW5pbWF0aW9uMi5jYWxsKHRoaXMsIHNraXBJbmhlcml0ID8gdmFycyA6IF9pbmhlcml0RGVmYXVsdHModmFycykpIHx8IHRoaXM7XG4gICAgdmFyIF90aGlzMyR2YXJzID0gX3RoaXMzLnZhcnMsXG4gICAgICAgIGR1cmF0aW9uID0gX3RoaXMzJHZhcnMuZHVyYXRpb24sXG4gICAgICAgIGRlbGF5ID0gX3RoaXMzJHZhcnMuZGVsYXksXG4gICAgICAgIGltbWVkaWF0ZVJlbmRlciA9IF90aGlzMyR2YXJzLmltbWVkaWF0ZVJlbmRlcixcbiAgICAgICAgc3RhZ2dlciA9IF90aGlzMyR2YXJzLnN0YWdnZXIsXG4gICAgICAgIG92ZXJ3cml0ZSA9IF90aGlzMyR2YXJzLm92ZXJ3cml0ZSxcbiAgICAgICAga2V5ZnJhbWVzID0gX3RoaXMzJHZhcnMua2V5ZnJhbWVzLFxuICAgICAgICBkZWZhdWx0cyA9IF90aGlzMyR2YXJzLmRlZmF1bHRzLFxuICAgICAgICBzY3JvbGxUcmlnZ2VyID0gX3RoaXMzJHZhcnMuc2Nyb2xsVHJpZ2dlcixcbiAgICAgICAgeW95b0Vhc2UgPSBfdGhpczMkdmFycy55b3lvRWFzZSxcbiAgICAgICAgcGFyZW50ID0gdmFycy5wYXJlbnQgfHwgX2dsb2JhbFRpbWVsaW5lLFxuICAgICAgICBwYXJzZWRUYXJnZXRzID0gKF9pc0FycmF5KHRhcmdldHMpIHx8IF9pc1R5cGVkQXJyYXkodGFyZ2V0cykgPyBfaXNOdW1iZXIodGFyZ2V0c1swXSkgOiBcImxlbmd0aFwiIGluIHZhcnMpID8gW3RhcmdldHNdIDogdG9BcnJheSh0YXJnZXRzKSxcbiAgICAgICAgdGwsXG4gICAgICAgIGksXG4gICAgICAgIGNvcHksXG4gICAgICAgIGwsXG4gICAgICAgIHAsXG4gICAgICAgIGN1clRhcmdldCxcbiAgICAgICAgc3RhZ2dlckZ1bmMsXG4gICAgICAgIHN0YWdnZXJWYXJzVG9NZXJnZTtcbiAgICBfdGhpczMuX3RhcmdldHMgPSBwYXJzZWRUYXJnZXRzLmxlbmd0aCA/IF9oYXJuZXNzKHBhcnNlZFRhcmdldHMpIDogX3dhcm4oXCJHU0FQIHRhcmdldCBcIiArIHRhcmdldHMgKyBcIiBub3QgZm91bmQuIGh0dHBzOi8vZ3NhcC5jb21cIiwgIV9jb25maWcubnVsbFRhcmdldFdhcm4pIHx8IFtdO1xuICAgIF90aGlzMy5fcHRMb29rdXAgPSBbXTsgLy9Qcm9wVHdlZW4gbG9va3VwLiBBbiBhcnJheSBjb250YWluaW5nIGFuIG9iamVjdCBmb3IgZWFjaCB0YXJnZXQsIGhhdmluZyBrZXlzIGZvciBlYWNoIHR3ZWVuaW5nIHByb3BlcnR5XG5cbiAgICBfdGhpczMuX292ZXJ3cml0ZSA9IG92ZXJ3cml0ZTtcblxuICAgIGlmIChrZXlmcmFtZXMgfHwgc3RhZ2dlciB8fCBfaXNGdW5jT3JTdHJpbmc
1oZHVyYXRpb24pIHx8IF9pc0Z1bmNPclN0cmluZyhkZWxheSkpIHtcbiAgICAgIHZhcnMgPSBfdGhpczMudmFycztcbiAgICAgIHRsID0gX3RoaXMzLnRpbWVsaW5lID0gbmV3IFRpbWVsaW5lKHtcbiAgICAgICAgZGF0YTogXCJuZXN0ZWRcIixcbiAgICAgICAgZGVmYXVsdHM6IGRlZmF1bHRzIHx8IHt9LFxuICAgICAgICB0YXJnZXRzOiBwYXJlbnQgJiYgcGFyZW50LmRhdGEgPT09IFwibmVzdGVkXCIgPyBwYXJlbnQudmFycy50YXJnZXRzIDogcGFyc2VkVGFyZ2V0c1xuICAgICAgfSk7IC8vIHdlIG5lZWQgdG8gc3RvcmUgdGhlIHRhcmdldHMgYmVjYXVzZSBmb3Igc3RhZ2dlcnMgYW5kIGtleWZyYW1lcywgd2UgZW5kIHVwIGNyZWF0aW5nIGFuIGluZGl2aWR1YWwgdHdlZW4gZm9yIGVhY2ggYnV0IGZ1bmN0aW9uLWJhc2VkIHZhbHVlcyBuZWVkIHRvIGtub3cgdGhlIGluZGV4IGFuZCB0aGUgd2hvbGUgQXJyYXkgb2YgdGFyZ2V0cy5cblxuICAgICAgdGwua2lsbCgpO1xuICAgICAgdGwucGFyZW50ID0gdGwuX2RwID0gX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpczMpO1xuICAgICAgdGwuX3N0YXJ0ID0gMDtcblxuICAgICAgaWYgKHN0YWdnZXIgfHwgX2lzRnVuY09yU3RyaW5nKGR1cmF0aW9uKSB8fCBfaXNGdW5jT3JTdHJpbmcoZGVsYXkpKSB7XG4gICAgICAgIGwgPSBwYXJzZWRUYXJnZXRzLmxlbmd0aDtcbiAgICAgICAgc3RhZ2dlckZ1bmMgPSBzdGFnZ2VyICYmIGRpc3RyaWJ1dGUoc3RhZ2dlcik7XG5cbiAgICAgICAgaWYgKF9pc09iamVjdChzdGFnZ2VyKSkge1xuICAgICAgICAgIC8vdXNlcnMgY2FuIHBhc3MgaW4gY2FsbGJhY2tzIGxpa2Ugb25TdGFydC9vbkNvbXBsZXRlIGluIHRoZSBzdGFnZ2VyIG9iamVjdC4gVGhlc2Ugc2hvdWxkIGZpcmUgd2l0aCBlYWNoIGluZGl2aWR1YWwgdHdlZW4uXG4gICAgICAgICAgZm9yIChwIGluIHN0YWdnZXIpIHtcbiAgICAgICAgICAgIGlmICh+X3N0YWdnZXJUd2VlblByb3BzLmluZGV4T2YocCkpIHtcbiAgICAgICAgICAgICAgc3RhZ2dlclZhcnNUb01lcmdlIHx8IChzdGFnZ2VyVmFyc1RvTWVyZ2UgPSB7fSk7XG4gICAgICAgICAgICAgIHN0YWdnZXJWYXJzVG9NZXJnZVtwXSA9IHN0YWdnZXJbcF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgIGNvcHkgPSBfY29weUV4Y2x1ZGluZyh2YXJzLCBfc3RhZ2dlclByb3BzVG9Ta2lwKTtcbiAgICAgICAgICBjb3B5LnN0YWdnZXIgPSAwO1xuICAgICAgICAgIHlveW9FYXNlICYmIChjb3B5LnlveW9FYXNlID0geW95b0Vhc2UpO1xuICAgICAgICAgIHN0YWdnZXJWYXJzVG9NZXJnZSAmJiBfbWVyZ2UoY29weSwgc3RhZ2dlclZhcnNUb01lcmdlKTtcbiAgICAgICAgICBjdXJUYXJnZXQgPSBwYXJzZWRUYXJnZXRzW2ldOyAvL2Rvbid0IGp1c3QgY29weSBkdXJhdGlvbiBvciBkZWxheSBiZWNhdXNlIGlmIHRoZXkncmUgYSBzdHJpbmcgb3IgZnVuY3Rpb24sIHdlJ2QgZW5kIHVwIGluIGFuIGluZmluaXRlIGxvb3AgYmVjYXVzZSBfaXNGdW5jT3JTdHJpbmcoKSB3b3VsZCBldmFsdWF0ZSBhcyB0cnVlIGluIHRoZSBjaGlsZCB0d2VlbnMsIGVudGVyaW5nIHRoaXMgbG9vcCwgZXRjLiBTbyB3ZSBwYXJzZSB0aGUgdmFsdWUgc3RyYWlnaHQgZnJvbSB2YXJzIGFuZCBkZWZhdWx0IHRvIDAuXG5cbiAgICAgICAgICBjb3B5LmR1cmF0aW9uID0gK19wYXJzZUZ1bmNPclN0cmluZyhkdXJhdGlvbiwgX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpczMpLCBpLCBjdXJUYXJnZXQsIHBhcnNlZFRhcmdldHMpO1xuICAgICAgICAgIGNvcHkuZGVsYXkgPSAoK19wYXJzZUZ1bmNPclN0cmluZyhkZWxheSwgX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpczMpLCBpLCBjdXJUYXJnZXQsIHBhcnNlZFRhcmdldHMpIHx8IDApIC0gX3RoaXMzLl9kZWxheTtcblxuICAgICAgICAgIGlmICghc3RhZ2dlciAmJiBsID09PSAxICYmIGNvcHkuZGVsYXkpIHtcbiAgICAgICAgICAgIC8vIGlmIHNvbWVvbmUgZG9lcyBkZWxheTpcInJhbmRvbSgxLCA1KVwiLCByZXBlYXQ6LTEsIGZvciBleGFtcGxlLCB0aGUgZGVsYXkgc2hvdWxkbid0IGJlIGluc2lkZSB0aGUgcmVwZWF0LlxuICAgICAgICAgICAgX3RoaXMzLl9kZWxheSA9IGRlbGF5ID0gY29weS5kZWxheTtcbiAgICAgICAgICAgIF90aGlzMy5fc3RhcnQgKz0gZGVsYXk7XG4gICAgICAgICAgICBjb3B5LmRlbGF5ID0gMDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0bC50byhjdXJUYXJnZXQsIGNvcHksIHN0YWdnZXJGdW5jID8gc3RhZ2dlckZ1bmMoaSwgY3VyVGFyZ2V0LCBwYXJzZWRUYXJnZXRzKSA6IDApO1xuICAgICAgICAgIHRsLl9lYXNlID0gX2Vhc2VNYXAubm9uZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRsLmR1cmF0aW9uKCkgPyBkdXJhdGlvbiA9IGRlbGF5ID0gMCA6IF90aGlzMy50aW1lbGluZSA9IDA7IC8vIGlmIHRoZSB0aW1lbGluZSdzIGR1cmF0aW9uIGlzIDAsIHdlIGRvbid0IG5lZWQgYSB0aW1lbGluZSBpbnRlcm5hbGx5IVxuICAgICAgfSBlbHNlIGlmIChrZXlmcmFtZXMpIHtcbiAgICAgICAgX2luaGVyaXREZWZhdWx0cyhfc2V0RGVmYXVsdHModGwudmFycy5kZWZhdWx0cywge1xuICAgICAgICAgIGVhc2U6IFwibm9uZVwiXG4gICAgICAgIH0pKTtcblxuICAgICAgICB0bC5fZWFzZSA9IF9wYXJzZUVhc2Uoa2V5ZnJhbWVzLmVhc2UgfHwgdmFycy5lYXNlIHx8IFwibm9uZVwiKTtcbiAgICAgICAgdmFyIHRpbWUgPSAwLFxuICAgICAgICAgICAgYSxcbiAgICAgICAgICAgIGtmLFxuICAgICAgICAgICAgdjtcblxuICAgICAgICBpZiAoX2lzQXJyYXkoa2V5ZnJhbWVzKSkge1xuICAgICAgICAgIGtleWZyYW1lcy5mb3JFYWNoKGZ1bmN0aW9uIChmcmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRsLnRvKHBhcnNlZFRhcmdldHMsIGZyYW1lLCBcIj5cIik7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGwuZHVyYXRpb24oKTsgLy8gdG8gZW5zdXJlIHRsLl9kdXIgaXMgY2FjaGVkIGJlY2F1c2Ugd2UgdGFwIGludG8gaXQgZm9yIHBlcmZvcm1hbmNlIHB1cnBvc2VzIGluIHRoZSByZW5kZXIoKSBtZXRob2QuXG4gICAgICAgI
1H0gZWxzZSB7XG4gICAgICAgICAgY29weSA9IHt9O1xuXG4gICAgICAgICAgZm9yIChwIGluIGtleWZyYW1lcykge1xuICAgICAgICAgICAgcCA9PT0gXCJlYXNlXCIgfHwgcCA9PT0gXCJlYXNlRWFjaFwiIHx8IF9wYXJzZUtleWZyYW1lKHAsIGtleWZyYW1lc1twXSwgY29weSwga2V5ZnJhbWVzLmVhc2VFYWNoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKHAgaW4gY29weSkge1xuICAgICAgICAgICAgYSA9IGNvcHlbcF0uc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICByZXR1cm4gYS50IC0gYi50O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aW1lID0gMDtcblxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAga2YgPSBhW2ldO1xuICAgICAgICAgICAgICB2ID0ge1xuICAgICAgICAgICAgICAgIGVhc2U6IGtmLmUsXG4gICAgICAgICAgICAgICAgZHVyYXRpb246IChrZi50IC0gKGkgPyBhW2kgLSAxXS50IDogMCkpIC8gMTAwICogZHVyYXRpb25cbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgdltwXSA9IGtmLnY7XG4gICAgICAgICAgICAgIHRsLnRvKHBhcnNlZFRhcmdldHMsIHYsIHRpbWUpO1xuICAgICAgICAgICAgICB0aW1lICs9IHYuZHVyYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGwuZHVyYXRpb24oKSA8IGR1cmF0aW9uICYmIHRsLnRvKHt9LCB7XG4gICAgICAgICAgICBkdXJhdGlvbjogZHVyYXRpb24gLSB0bC5kdXJhdGlvbigpXG4gICAgICAgICAgfSk7IC8vIGluIGNhc2Uga2V5ZnJhbWVzIGRpZG4ndCBnbyB0byAxMDAlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZHVyYXRpb24gfHwgX3RoaXMzLmR1cmF0aW9uKGR1cmF0aW9uID0gdGwuZHVyYXRpb24oKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIF90aGlzMy50aW1lbGluZSA9IDA7IC8vc3BlZWQgb3B0aW1pemF0aW9uLCBmYXN0ZXIgbG9va3VwcyAobm8gZ29pbmcgdXAgdGhlIHByb3RvdHlwZSBjaGFpbilcbiAgICB9XG5cbiAgICBpZiAob3ZlcndyaXRlID09PSB0cnVlICYmICFfc3VwcHJlc3NPdmVyd3JpdGVzKSB7XG4gICAgICBfb3ZlcndyaXRpbmdUd2VlbiA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMzKTtcblxuICAgICAgX2dsb2JhbFRpbWVsaW5lLmtpbGxUd2VlbnNPZihwYXJzZWRUYXJnZXRzKTtcblxuICAgICAgX292ZXJ3cml0aW5nVHdlZW4gPSAwO1xuICAgIH1cblxuICAgIF9hZGRUb1RpbWVsaW5lKHBhcmVudCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpczMpLCBwb3NpdGlvbik7XG5cbiAgICB2YXJzLnJldmVyc2VkICYmIF90aGlzMy5yZXZlcnNlKCk7XG4gICAgdmFycy5wYXVzZWQgJiYgX3RoaXMzLnBhdXNlZCh0cnVlKTtcblxuICAgIGlmIChpbW1lZGlhdGVSZW5kZXIgfHwgIWR1cmF0aW9uICYmICFrZXlmcmFtZXMgJiYgX3RoaXMzLl9zdGFydCA9PT0gX3JvdW5kUHJlY2lzZShwYXJlbnQuX3RpbWUpICYmIF9pc05vdEZhbHNlKGltbWVkaWF0ZVJlbmRlcikgJiYgX2hhc05vUGF1c2VkQW5jZXN0b3JzKF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMzKSkgJiYgcGFyZW50LmRhdGEgIT09IFwibmVzdGVkXCIpIHtcbiAgICAgIF90aGlzMy5fdFRpbWUgPSAtX3RpbnlOdW07IC8vZm9yY2VzIGEgcmVuZGVyIHdpdGhvdXQgaGF2aW5nIHRvIHNldCB0aGUgcmVuZGVyKCkgXCJmb3JjZVwiIHBhcmFtZXRlciB0byB0cnVlIGJlY2F1c2Ugd2Ugd2FudCB0byBhbGxvdyBsYXp5aW5nIGJ5IGRlZmF1bHQgKHVzaW5nIHRoZSBcImZvcmNlXCIgcGFyYW1ldGVyIGFsd2F5cyBmb3JjZXMgYW4gaW1tZWRpYXRlIGZ1bGwgcmVuZGVyKVxuXG4gICAgICBfdGhpczMucmVuZGVyKE1hdGgubWF4KDAsIC1kZWxheSkgfHwgMCk7IC8vaW4gY2FzZSBkZWxheSBpcyBuZWdhdGl2ZVxuXG4gICAgfVxuXG4gICAgc2Nyb2xsVHJpZ2dlciAmJiBfc2Nyb2xsVHJpZ2dlcihfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzMyksIHNjcm9sbFRyaWdnZXIpO1xuICAgIHJldHVybiBfdGhpczM7XG4gIH1cblxuICB2YXIgX3Byb3RvMyA9IFR3ZWVuLnByb3RvdHlwZTtcblxuICBfcHJvdG8zLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcih0b3RhbFRpbWUsIHN1cHByZXNzRXZlbnRzLCBmb3JjZSkge1xuICAgIHZhciBwcmV2VGltZSA9IHRoaXMuX3RpbWUsXG4gICAgICAgIHREdXIgPSB0aGlzLl90RHVyLFxuICAgICAgICBkdXIgPSB0aGlzLl9kdXIsXG4gICAgICAgIGlzTmVnYXRpdmUgPSB0b3RhbFRpbWUgPCAwLFxuICAgICAgICB0VGltZSA9IHRvdGFsVGltZSA+IHREdXIgLSBfdGlueU51bSAmJiAhaXNOZWdhdGl2ZSA/IHREdXIgOiB0b3RhbFRpbWUgPCBfdGlueU51bSA/IDAgOiB0b3RhbFRpbWUsXG4gICAgICAgIHRpbWUsXG4gICAgICAgIHB0LFxuICAgICAgICBpdGVyYXRpb24sXG4gICAgICAgIGN5Y2xlRHVyYXRpb24sXG4gICAgICAgIHByZXZJdGVyYXRpb24sXG4gICAgICAgIGlzWW95byxcbiAgICAgICAgcmF0aW8sXG4gICAgICAgIHRpbWVsaW5lLFxuICAgICAgICB5b3lvRWFzZTtcblxuICAgIGlmICghZHVyKSB7XG4gICAgICBfcmVuZGVyWmVyb0R1cmF0aW9uVHdlZW4odGhpcywgdG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpO1xuICAgIH0gZWxzZSBpZiAodFRpbWUgIT09IHRoaXMuX3RUaW1lIHx8ICF0b3RhbFRpbWUgfHwgZm9yY2UgfHwgIXRoaXMuX2luaXR0ZWQgJiYgdGhpcy5fdFRpbWUgfHwgdGhpcy5fc3RhcnRBdCAmJiB0aGlzLl96VGltZSA8IDAgIT09IGlzTmVnYXRpdmUpIHtcbiAgICAgIC8vdGhpcyBzZW5zZXMgaWYgd2UncmUgY3Jvc3Npbmcgb3ZlciB0aGUgc3RhcnQgdGltZSwgaW4gd2hpY2ggY2FzZSB3ZSBtdXN0IHJlY29yZCBfelRpbWUgYW5kIGZvcmNlIHRoZSByZW5kZXIsIGJ1dCB3ZSBkbyBpdCBpbiB0aGlzIGxlbmd0aHkgY29uZGl0aW9uYWwgd2F5IGZvciBwZXJmb3JtYW5jZSByZWFzb25zICh1c3VhbGx5IHdlIGNhbiBza2lwIHRoZSBjYWxjdWxhdGlvbnMpOiB0aGlzLl9pbml0dGVkICYmICh0aGlzLl96VGltZSA8IDApICE9PSAodG90YWxUaW1lIDwgMClcbiAgICAgIHRpbWUgPSB0VGltZTtcbiAgICAgIHRpbWVsaW5lID0gdGhpcy50aW1lbGluZTtcblxuICAgICAgaWYgKHRoaXMuX3JlcGVhdCkge1xuICAgICAgICAvL2FkanVzdCB0aGUgdGltZSBmb3IgcmVwZWF0cyBhbmQgeW95b3NcbiAgICAgICAgY3ljbGVEdXJhdGlvbiA9IGR1ciArIH
1RoaXMuX3JEZWxheTtcblxuICAgICAgICBpZiAodGhpcy5fcmVwZWF0IDwgLTEgJiYgaXNOZWdhdGl2ZSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRvdGFsVGltZShjeWNsZUR1cmF0aW9uICogMTAwICsgdG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGltZSA9IF9yb3VuZFByZWNpc2UodFRpbWUgJSBjeWNsZUR1cmF0aW9uKTsgLy9yb3VuZCB0byBhdm9pZCBmbG9hdGluZyBwb2ludCBlcnJvcnMuICg0ICUgMC44IHNob3VsZCBiZSAwIGJ1dCBzb21lIGJyb3dzZXJzIHJlcG9ydCBpdCBhcyAwLjc5OTk5OTk5ISlcblxuICAgICAgICBpZiAodFRpbWUgPT09IHREdXIpIHtcbiAgICAgICAgICAvLyB0aGUgdER1ciA9PT0gdFRpbWUgaXMgZm9yIGVkZ2UgY2FzZXMgd2hlcmUgdGhlcmUncyBhIGxlbmd0aHkgZGVjaW1hbCBvbiB0aGUgZHVyYXRpb24gYW5kIGl0IG1heSByZWFjaCB0aGUgdmVyeSBlbmQgYnV0IHRoZSB0aW1lIGlzIHJlbmRlcmVkIGFzIG5vdC1xdWl0ZS10aGVyZSAocmVtZW1iZXIsIHREdXIgaXMgcm91bmRlZCB0byA0IGRlY2ltYWxzIHdoZXJlYXMgZHVyIGlzbid0KVxuICAgICAgICAgIGl0ZXJhdGlvbiA9IHRoaXMuX3JlcGVhdDtcbiAgICAgICAgICB0aW1lID0gZHVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZXJhdGlvbiA9IH5+KHRUaW1lIC8gY3ljbGVEdXJhdGlvbik7XG5cbiAgICAgICAgICBpZiAoaXRlcmF0aW9uICYmIGl0ZXJhdGlvbiA9PT0gX3JvdW5kUHJlY2lzZSh0VGltZSAvIGN5Y2xlRHVyYXRpb24pKSB7XG4gICAgICAgICAgICB0aW1lID0gZHVyO1xuICAgICAgICAgICAgaXRlcmF0aW9uLS07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGltZSA+IGR1ciAmJiAodGltZSA9IGR1cik7XG4gICAgICAgIH1cblxuICAgICAgICBpc1lveW8gPSB0aGlzLl95b3lvICYmIGl0ZXJhdGlvbiAmIDE7XG5cbiAgICAgICAgaWYgKGlzWW95bykge1xuICAgICAgICAgIHlveW9FYXNlID0gdGhpcy5feUVhc2U7XG4gICAgICAgICAgdGltZSA9IGR1ciAtIHRpbWU7XG4gICAgICAgIH1cblxuICAgICAgICBwcmV2SXRlcmF0aW9uID0gX2FuaW1hdGlvbkN5Y2xlKHRoaXMuX3RUaW1lLCBjeWNsZUR1cmF0aW9uKTtcblxuICAgICAgICBpZiAodGltZSA9PT0gcHJldlRpbWUgJiYgIWZvcmNlICYmIHRoaXMuX2luaXR0ZWQgJiYgaXRlcmF0aW9uID09PSBwcmV2SXRlcmF0aW9uKSB7XG4gICAgICAgICAgLy9jb3VsZCBiZSBkdXJpbmcgdGhlIHJlcGVhdERlbGF5IHBhcnQuIE5vIG5lZWQgdG8gcmVuZGVyIGFuZCBmaXJlIGNhbGxiYWNrcy5cbiAgICAgICAgICB0aGlzLl90VGltZSA9IHRUaW1lO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGl0ZXJhdGlvbiAhPT0gcHJldkl0ZXJhdGlvbikge1xuICAgICAgICAgIHRpbWVsaW5lICYmIHRoaXMuX3lFYXNlICYmIF9wcm9wYWdhdGVZb3lvRWFzZSh0aW1lbGluZSwgaXNZb3lvKTsgLy9yZXBlYXRSZWZyZXNoIGZ1bmN0aW9uYWxpdHlcblxuICAgICAgICAgIGlmICh0aGlzLnZhcnMucmVwZWF0UmVmcmVzaCAmJiAhaXNZb3lvICYmICF0aGlzLl9sb2NrICYmIHRoaXMuX3RpbWUgIT09IGN5Y2xlRHVyYXRpb24gJiYgdGhpcy5faW5pdHRlZCkge1xuICAgICAgICAgICAgLy8gdGhpcy5fdGltZSB3aWxsID09PSBjeWNsZUR1cmF0aW9uIHdoZW4gd2UgcmVuZGVyIGF0IEVYQUNUTFkgdGhlIGVuZCBvZiBhbiBpdGVyYXRpb24uIFdpdGhvdXQgdGhpcyBjb25kaXRpb24sIGl0J2Qgb2Z0ZW4gZG8gdGhlIHJlcGVhdFJlZnJlc2ggcmVuZGVyIFRXSUNFIChhZ2FpbiBvbiB0aGUgdmVyeSBuZXh0IHRpY2spLlxuICAgICAgICAgICAgdGhpcy5fbG9jayA9IGZvcmNlID0gMTsgLy9mb3JjZSwgb3RoZXJ3aXNlIGlmIGxhenkgaXMgdHJ1ZSwgdGhlIF9hdHRlbXB0SW5pdFR3ZWVuKCkgd2lsbCByZXR1cm4gYW5kIHdlJ2xsIGp1bXAgb3V0IGFuZCBnZXQgY2F1Z2h0IGJvdW5jaW5nIG9uIGVhY2ggdGljay5cblxuICAgICAgICAgICAgdGhpcy5yZW5kZXIoX3JvdW5kUHJlY2lzZShjeWNsZUR1cmF0aW9uICogaXRlcmF0aW9uKSwgdHJ1ZSkuaW52YWxpZGF0ZSgpLl9sb2NrID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLl9pbml0dGVkKSB7XG4gICAgICAgIGlmIChfYXR0ZW1wdEluaXRUd2Vlbih0aGlzLCBpc05lZ2F0aXZlID8gdG90YWxUaW1lIDogdGltZSwgZm9yY2UsIHN1cHByZXNzRXZlbnRzLCB0VGltZSkpIHtcbiAgICAgICAgICB0aGlzLl90VGltZSA9IDA7IC8vIGluIGNvbnN0cnVjdG9yIGlmIGltbWVkaWF0ZVJlbmRlciBpcyB0cnVlLCB3ZSBzZXQgX3RUaW1lIHRvIC1fdGlueU51bSB0byBoYXZlIHRoZSBwbGF5aGVhZCBjcm9zcyB0aGUgc3RhcnRpbmcgcG9pbnQgYnV0IHdlIGNhbid0IGxlYXZlIF90VGltZSBhcyBhIG5lZ2F0aXZlIG51bWJlci5cblxuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByZXZUaW1lICE9PSB0aGlzLl90aW1lICYmICEoZm9yY2UgJiYgdGhpcy52YXJzLnJlcGVhdFJlZnJlc2ggJiYgaXRlcmF0aW9uICE9PSBwcmV2SXRlcmF0aW9uKSkge1xuICAgICAgICAgIC8vIHJhcmUgZWRnZSBjYXNlIC0gZHVyaW5nIGluaXRpYWxpemF0aW9uLCBhbiBvblVwZGF0ZSBpbiB0aGUgX3N0YXJ0QXQgKC5mcm9tVG8oKSkgbWlnaHQgZm9yY2UgdGhpcyB0d2VlbiB0byByZW5kZXIgYXQgYSBkaWZmZXJlbnQgc3BvdCBpbiB3aGljaCBjYXNlIHdlIHNob3VsZCBkaXRjaCB0aGlzIHJlbmRlcigpIGNhbGwgc28gdGhhdCBpdCBkb2Vzbid0IHJldmVydCB0aGUgdmFsdWVzLiBCdXQgd2UgYWxzbyBkb24ndCB3YW50IHRvIGR1bXAgaWYgd2UncmUgZG9pbmcgYSByZXBlYXRSZWZyZXNoIHJlbmRlciFcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkdXIgIT09IHRoaXMuX2R1cikge1xuICAgICAgICAgIC8vIHdoaWxlIGluaXR0aW5nLCBhIHBsdWdpbiBsaWtlIEluZXJ0aWFQbHVnaW4gbWlnaHQgYWx0ZXIgdGhlIGR1cmF0aW9uLCBzbyByZXJ1biBmcm9tIHRoZSBzdGFydCB0byBlbnN1cmUgZXZlcnl0aGluZyByZW5kZXJzIGFzIGl0IHNob3VsZC5cbiAgICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXIodG90YWxUaW1lLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3RUaW1lID0gdFRpbWU7XG4gICAgICB0aGlzLl90
1aW1lID0gdGltZTtcblxuICAgICAgaWYgKCF0aGlzLl9hY3QgJiYgdGhpcy5fdHMpIHtcbiAgICAgICAgdGhpcy5fYWN0ID0gMTsgLy9hcyBsb25nIGFzIGl0J3Mgbm90IHBhdXNlZCwgZm9yY2UgaXQgdG8gYmUgYWN0aXZlIHNvIHRoYXQgaWYgdGhlIHVzZXIgcmVuZGVycyBpbmRlcGVuZGVudCBvZiB0aGUgcGFyZW50IHRpbWVsaW5lLCBpdCdsbCBiZSBmb3JjZWQgdG8gcmUtcmVuZGVyIG9uIHRoZSBuZXh0IHRpY2suXG5cbiAgICAgICAgdGhpcy5fbGF6eSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMucmF0aW8gPSByYXRpbyA9ICh5b3lvRWFzZSB8fCB0aGlzLl9lYXNlKSh0aW1lIC8gZHVyKTtcblxuICAgICAgaWYgKHRoaXMuX2Zyb20pIHtcbiAgICAgICAgdGhpcy5yYXRpbyA9IHJhdGlvID0gMSAtIHJhdGlvO1xuICAgICAgfVxuXG4gICAgICBpZiAodGltZSAmJiAhcHJldlRpbWUgJiYgIXN1cHByZXNzRXZlbnRzICYmICFpdGVyYXRpb24pIHtcbiAgICAgICAgX2NhbGxiYWNrKHRoaXMsIFwib25TdGFydFwiKTtcblxuICAgICAgICBpZiAodGhpcy5fdFRpbWUgIT09IHRUaW1lKSB7XG4gICAgICAgICAgLy8gaW4gY2FzZSB0aGUgb25TdGFydCB0cmlnZ2VyZWQgYSByZW5kZXIgYXQgYSBkaWZmZXJlbnQgc3BvdCwgZWplY3QuIExpa2UgaWYgc29tZW9uZSBkaWQgYW5pbWF0aW9uLnBhdXNlKDAuNSkgb3Igc29tZXRoaW5nIGluc2lkZSB0aGUgb25TdGFydC5cbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwdCA9IHRoaXMuX3B0O1xuXG4gICAgICB3aGlsZSAocHQpIHtcbiAgICAgICAgcHQucihyYXRpbywgcHQuZCk7XG4gICAgICAgIHB0ID0gcHQuX25leHQ7XG4gICAgICB9XG5cbiAgICAgIHRpbWVsaW5lICYmIHRpbWVsaW5lLnJlbmRlcih0b3RhbFRpbWUgPCAwID8gdG90YWxUaW1lIDogdGltZWxpbmUuX2R1ciAqIHRpbWVsaW5lLl9lYXNlKHRpbWUgLyB0aGlzLl9kdXIpLCBzdXBwcmVzc0V2ZW50cywgZm9yY2UpIHx8IHRoaXMuX3N0YXJ0QXQgJiYgKHRoaXMuX3pUaW1lID0gdG90YWxUaW1lKTtcblxuICAgICAgaWYgKHRoaXMuX29uVXBkYXRlICYmICFzdXBwcmVzc0V2ZW50cykge1xuICAgICAgICBpc05lZ2F0aXZlICYmIF9yZXdpbmRTdGFydEF0KHRoaXMsIHRvdGFsVGltZSwgc3VwcHJlc3NFdmVudHMsIGZvcmNlKTsgLy9ub3RlOiBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucywgd2UgdHVjayB0aGlzIGNvbmRpdGlvbmFsIGxvZ2ljIGluc2lkZSBsZXNzIHRyYXZlbGVkIGFyZWFzIChtb3N0IHR3ZWVucyBkb24ndCBoYXZlIGFuIG9uVXBkYXRlKS4gV2UnZCBqdXN0IGhhdmUgaXQgYXQgdGhlIGVuZCBiZWZvcmUgdGhlIG9uQ29tcGxldGUsIGJ1dCB0aGUgdmFsdWVzIHNob3VsZCBiZSB1cGRhdGVkIGJlZm9yZSBhbnkgb25VcGRhdGUgaXMgY2FsbGVkLCBzbyB3ZSBBTFNPIHB1dCBpdCBoZXJlIGFuZCB0aGVuIGlmIGl0J3Mgbm90IGNhbGxlZCwgd2UgZG8gc28gbGF0ZXIgbmVhciB0aGUgb25Db21wbGV0ZS5cblxuICAgICAgICBfY2FsbGJhY2sodGhpcywgXCJvblVwZGF0ZVwiKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fcmVwZWF0ICYmIGl0ZXJhdGlvbiAhPT0gcHJldkl0ZXJhdGlvbiAmJiB0aGlzLnZhcnMub25SZXBlYXQgJiYgIXN1cHByZXNzRXZlbnRzICYmIHRoaXMucGFyZW50ICYmIF9jYWxsYmFjayh0aGlzLCBcIm9uUmVwZWF0XCIpO1xuXG4gICAgICBpZiAoKHRUaW1lID09PSB0aGlzLl90RHVyIHx8ICF0VGltZSkgJiYgdGhpcy5fdFRpbWUgPT09IHRUaW1lKSB7XG4gICAgICAgIGlzTmVnYXRpdmUgJiYgIXRoaXMuX29uVXBkYXRlICYmIF9yZXdpbmRTdGFydEF0KHRoaXMsIHRvdGFsVGltZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgICh0b3RhbFRpbWUgfHwgIWR1cikgJiYgKHRUaW1lID09PSB0aGlzLl90RHVyICYmIHRoaXMuX3RzID4gMCB8fCAhdFRpbWUgJiYgdGhpcy5fdHMgPCAwKSAmJiBfcmVtb3ZlRnJvbVBhcmVudCh0aGlzLCAxKTsgLy8gZG9uJ3QgcmVtb3ZlIGlmIHdlJ3JlIHJlbmRlcmluZyBhdCBleGFjdGx5IGEgdGltZSBvZiAwLCBhcyB0aGVyZSBjb3VsZCBiZSBhdXRvUmV2ZXJ0IHZhbHVlcyB0aGF0IHNob3VsZCBnZXQgc2V0IG9uIHRoZSBuZXh0IHRpY2sgKGlmIHRoZSBwbGF5aGVhZCBnb2VzIGJhY2t3YXJkIGJleW9uZCB0aGUgc3RhcnRUaW1lLCBuZWdhdGl2ZSB0b3RhbFRpbWUpLiBEb24ndCByZW1vdmUgaWYgdGhlIHRpbWVsaW5lIGlzIHJldmVyc2VkIGFuZCB0aGUgcGxheWhlYWQgaXNuJ3QgYXQgMCwgb3RoZXJ3aXNlIHRsLnByb2dyZXNzKDEpLnJldmVyc2UoKSB3b24ndCB3b3JrLiBPbmx5IHJlbW92ZSBpZiB0aGUgcGxheWhlYWQgaXMgYXQgdGhlIGVuZCBhbmQgdGltZVNjYWxlIGlzIHBvc2l0aXZlLCBvciBpZiB0aGUgcGxheWhlYWQgaXMgYXQgMCBhbmQgdGhlIHRpbWVTY2FsZSBpcyBuZWdhdGl2ZS5cblxuICAgICAgICBpZiAoIXN1cHByZXNzRXZlbnRzICYmICEoaXNOZWdhdGl2ZSAmJiAhcHJldlRpbWUpICYmICh0VGltZSB8fCBwcmV2VGltZSB8fCBpc1lveW8pKSB7XG4gICAgICAgICAgLy8gaWYgcHJldlRpbWUgYW5kIHRUaW1lIGFyZSB6ZXJvLCB3ZSBzaG91bGRuJ3QgZmlyZSB0aGUgb25SZXZlcnNlQ29tcGxldGUuIFRoaXMgY291bGQgaGFwcGVuIGlmIHlvdSBnc2FwLnRvKC4uLiB7cGF1c2VkOnRydWV9KS5wbGF5KCk7XG4gICAgICAgICAgX2NhbGxiYWNrKHRoaXMsIHRUaW1lID09PSB0RHVyID8gXCJvbkNvbXBsZXRlXCIgOiBcIm9uUmV2ZXJzZUNvbXBsZXRlXCIsIHRydWUpO1xuXG4gICAgICAgICAgdGhpcy5fcHJvbSAmJiAhKHRUaW1lIDwgdER1ciAmJiB0aGlzLnRpbWVTY2FsZSgpID4gMCkgJiYgdGhpcy5fcHJvbSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgX3Byb3RvMy50YXJnZXRzID0gZnVuY3Rpb24gdGFyZ2V0cygpIHtcbiAgICByZXR1cm4gdGhpcy5fdGFyZ2V0cztcbiAgfTtcblxuICBfcHJvdG8zLmludmFsaWRhdGUgPSBmdW5jdGlvbiBpbnZhbGlkYXRlKHNvZnQpIHtcbiAgICAvLyBcInNvZnRcIiBnaXZlcyB1cyBhIHdheSB0byBjbGVhciBvdXQgZXZlcnl0aGluZyBFWENFUFQgdGhlIHJlY29yZGVkIHByZS1cImZyb21cIiBwb3J0aW9uIG9mIGZyb20oKSB0d2VlbnMuIE90aGVyd2lzZSwgZm9yIGV4YW1wbGUsIGlmIHlvdSB0d2Vlbi5wcm9ncmVzcygxKS5yZW5kZXIoMCwgdHJ1ZSB0cnVlKS5pbnZhbGlkYXRlKCksIHRoZSBcImZyb21cIiB2YWx1ZXMgd291bGQgcGVyc2lzdCBhbmQgdGhlbiBvbiB0aGUgbmV4dCByZW5kZXIsIHR
1oZSBmcm9tKCkgdHdlZW5zIHdvdWxkIGluaXRpYWxpemUgYW5kIHRoZSBjdXJyZW50IHZhbHVlIHdvdWxkIG1hdGNoIHRoZSBcImZyb21cIiB2YWx1ZXMsIHRodXMgYW5pbWF0ZSBmcm9tIHRoZSBzYW1lIHZhbHVlIHRvIHRoZSBzYW1lIHZhbHVlIChubyBhbmltYXRpb24pLiBXZSB0YXAgaW50byB0aGlzIGluIFNjcm9sbFRyaWdnZXIncyByZWZyZXNoKCkgd2hlcmUgd2UgbXVzdCBwdXNoIGEgdHdlZW4gdG8gY29tcGxldGlvbiBhbmQgdGhlbiBiYWNrIGFnYWluIGJ1dCBob25vciBpdHMgaW5pdCBzdGF0ZSBpbiBjYXNlIHRoZSB0d2VlbiBpcyBkZXBlbmRlbnQgb24gYW5vdGhlciB0d2VlbiBmdXJ0aGVyIHVwIG9uIHRoZSBwYWdlLlxuICAgICghc29mdCB8fCAhdGhpcy52YXJzLnJ1bkJhY2t3YXJkcykgJiYgKHRoaXMuX3N0YXJ0QXQgPSAwKTtcbiAgICB0aGlzLl9wdCA9IHRoaXMuX29wID0gdGhpcy5fb25VcGRhdGUgPSB0aGlzLl9sYXp5ID0gdGhpcy5yYXRpbyA9IDA7XG4gICAgdGhpcy5fcHRMb29rdXAgPSBbXTtcbiAgICB0aGlzLnRpbWVsaW5lICYmIHRoaXMudGltZWxpbmUuaW52YWxpZGF0ZShzb2Z0KTtcbiAgICByZXR1cm4gX0FuaW1hdGlvbjIucHJvdG90eXBlLmludmFsaWRhdGUuY2FsbCh0aGlzLCBzb2Z0KTtcbiAgfTtcblxuICBfcHJvdG8zLnJlc2V0VG8gPSBmdW5jdGlvbiByZXNldFRvKHByb3BlcnR5LCB2YWx1ZSwgc3RhcnQsIHN0YXJ0SXNSZWxhdGl2ZSwgc2tpcFJlY3Vyc2lvbikge1xuICAgIF90aWNrZXJBY3RpdmUgfHwgX3RpY2tlci53YWtlKCk7XG4gICAgdGhpcy5fdHMgfHwgdGhpcy5wbGF5KCk7XG4gICAgdmFyIHRpbWUgPSBNYXRoLm1pbih0aGlzLl9kdXIsICh0aGlzLl9kcC5fdGltZSAtIHRoaXMuX3N0YXJ0KSAqIHRoaXMuX3RzKSxcbiAgICAgICAgcmF0aW87XG4gICAgdGhpcy5faW5pdHRlZCB8fCBfaW5pdFR3ZWVuKHRoaXMsIHRpbWUpO1xuICAgIHJhdGlvID0gdGhpcy5fZWFzZSh0aW1lIC8gdGhpcy5fZHVyKTsgLy8gZG9uJ3QganVzdCBnZXQgdHdlZW4ucmF0aW8gYmVjYXVzZSBpdCBtYXkgbm90IGhhdmUgcmVuZGVyZWQgeWV0LlxuICAgIC8vIHBvc3NpYmxlIGZ1dHVyZSBhZGRpdGlvbiB0byBhbGxvdyBhbiBvYmplY3Qgd2l0aCBtdWx0aXBsZSB2YWx1ZXMgdG8gdXBkYXRlLCBsaWtlIHR3ZWVuLnJlc2V0VG8oe3g6IDEwMCwgeTogMjAwfSk7IEF0IHRoaXMgcG9pbnQsIGl0IGRvZXNuJ3Qgc2VlbSB3b3J0aCB0aGUgYWRkZWQga2IgZ2l2ZW4gdGhlIGZhY3QgdGhhdCBtb3N0IHVzZXJzIHdpbGwgbGlrZWx5IG9wdCBmb3IgdGhlIGNvbnZlbmllbnQgZ3NhcC5xdWlja1RvKCkgd2F5IG9mIGludGVyYWN0aW5nIHdpdGggdGhpcyBtZXRob2QuXG4gICAgLy8gaWYgKF9pc09iamVjdChwcm9wZXJ0eSkpIHsgLy8gcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uXG4gICAgLy8gXHRmb3IgKHAgaW4gcHJvcGVydHkpIHtcbiAgICAvLyBcdFx0aWYgKF91cGRhdGVQcm9wVHdlZW5zKHRoaXMsIHAsIHByb3BlcnR5W3BdLCB2YWx1ZSA/IHZhbHVlW3BdIDogbnVsbCwgc3RhcnQsIHJhdGlvLCB0aW1lKSkge1xuICAgIC8vIFx0XHRcdHJldHVybiB0aGlzLnJlc2V0VG8ocHJvcGVydHksIHZhbHVlLCBzdGFydCwgc3RhcnRJc1JlbGF0aXZlKTsgLy8gaWYgYSBQcm9wVHdlZW4gd2Fzbid0IGZvdW5kIGZvciB0aGUgcHJvcGVydHksIGl0J2xsIGdldCBmb3JjZWQgd2l0aCBhIHJlLWluaXRpYWxpemF0aW9uIHNvIHdlIG5lZWQgdG8ganVtcCBvdXQgYW5kIHN0YXJ0IG92ZXIgYWdhaW4uXG4gICAgLy8gXHRcdH1cbiAgICAvLyBcdH1cbiAgICAvLyB9IGVsc2Uge1xuXG4gICAgaWYgKF91cGRhdGVQcm9wVHdlZW5zKHRoaXMsIHByb3BlcnR5LCB2YWx1ZSwgc3RhcnQsIHN0YXJ0SXNSZWxhdGl2ZSwgcmF0aW8sIHRpbWUsIHNraXBSZWN1cnNpb24pKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXNldFRvKHByb3BlcnR5LCB2YWx1ZSwgc3RhcnQsIHN0YXJ0SXNSZWxhdGl2ZSwgMSk7IC8vIGlmIGEgUHJvcFR3ZWVuIHdhc24ndCBmb3VuZCBmb3IgdGhlIHByb3BlcnR5LCBpdCdsbCBnZXQgZm9yY2VkIHdpdGggYSByZS1pbml0aWFsaXphdGlvbiBzbyB3ZSBuZWVkIHRvIGp1bXAgb3V0IGFuZCBzdGFydCBvdmVyIGFnYWluLlxuICAgIH0gLy99XG5cblxuICAgIF9hbGlnblBsYXloZWFkKHRoaXMsIDApO1xuXG4gICAgdGhpcy5wYXJlbnQgfHwgX2FkZExpbmtlZExpc3RJdGVtKHRoaXMuX2RwLCB0aGlzLCBcIl9maXJzdFwiLCBcIl9sYXN0XCIsIHRoaXMuX2RwLl9zb3J0ID8gXCJfc3RhcnRcIiA6IDApO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcigwKTtcbiAgfTtcblxuICBfcHJvdG8zLmtpbGwgPSBmdW5jdGlvbiBraWxsKHRhcmdldHMsIHZhcnMpIHtcbiAgICBpZiAodmFycyA9PT0gdm9pZCAwKSB7XG4gICAgICB2Y
1XJzID0gXCJhbGxcIjtcbiAgICB9XG5cbiAgICBpZiAoIXRhcmdldHMgJiYgKCF2YXJzIHx8IHZhcnMgPT09IFwiYWxsXCIpKSB7XG4gICAgICB0aGlzLl9sYXp5ID0gdGhpcy5fcHQgPSAwO1xuICAgICAgcmV0dXJuIHRoaXMucGFyZW50ID8gX2ludGVycnVwdCh0aGlzKSA6IHRoaXM7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGltZWxpbmUpIHtcbiAgICAgIHZhciB0RHVyID0gdGhpcy50aW1lbGluZS50b3RhbER1cmF0aW9uKCk7XG4gICAgICB0aGlzLnRpbWVsaW5lLmtpbGxUd2VlbnNPZih0YXJnZXRzLCB2YXJzLCBfb3ZlcndyaXRpbmdUd2VlbiAmJiBfb3ZlcndyaXRpbmdUd2Vlbi52YXJzLm92ZXJ3cml0ZSAhPT0gdHJ1ZSkuX2ZpcnN0IHx8IF9pbnRlcnJ1cHQodGhpcyk7IC8vIGlmIG5vdGhpbmcgaXMgbGVmdCB0d2VlbmluZywgaW50ZXJydXB0LlxuXG4gICAgICB0aGlzLnBhcmVudCAmJiB0RHVyICE9PSB0aGlzLnRpbWVsaW5lLnRvdGFsRHVyYXRpb24oKSAmJiBfc2V0RHVyYXRpb24odGhpcywgdGhpcy5fZHVyICogdGhpcy50aW1lbGluZS5fdER1ciAvIHREdXIsIDAsIDEpOyAvLyBpZiBhIG5lc3RlZCB0d2VlbiBpcyBraWxsZWQgdGhhdCBjaGFuZ2VzIHRoZSBkdXJhdGlvbiwgaXQgc2hvdWxkIGFmZmVjdCB0aGlzIHR3ZWVuJ3MgZHVyYXRpb24uIFdlIG11c3QgdXNlIHRoZSByYXRpbywgdGhvdWdoLCBiZWNhdXNlIHNvbWV0aW1lcyB0aGUgaW50ZXJuYWwgdGltZWxpbmUgaXMgc3RyZXRjaGVkIGxpa2UgZm9yIGtleWZyYW1lcyB3aGVyZSB0aGV5IGRvbid0IGFsbCBhZGQgdXAgdG8gd2hhdGV2ZXIgdGhlIHBhcmVudCB0d2VlbidzIGR1cmF0aW9uIHdhcyBzZXQgdG8uXG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHZhciBwYXJzZWRUYXJnZXRzID0gdGhpcy5fdGFyZ2V0cyxcbiAgICAgICAga2lsbGluZ1RhcmdldHMgPSB0YXJnZXRzID8gdG9BcnJheSh0YXJnZXRzKSA6IHBhcnNlZFRhcmdldHMsXG4gICAgICAgIHByb3BUd2Vlbkxvb2t1cCA9IHRoaXMuX3B0TG9va3VwLFxuICAgICAgICBmaXJzdFBUID0gdGhpcy5fcHQsXG4gICAgICAgIG92ZXJ3cml0dGVuUHJvcHMsXG4gICAgICAgIGN1ckxvb2t1cCxcbiAgICAgICAgY3VyT3ZlcndyaXRlUHJvcHMsXG4gICAgICAgIHByb3BzLFxuICAgICAgICBwLFxuICAgICAgICBwdCxcbiAgICAgICAgaTtcblxuICAgIGlmICgoIXZhcnMgfHwgdmFycyA9PT0gXCJhbGxcIikgJiYgX2FycmF5c01hdGNoKHBhcnNlZFRhcmdldHMsIGtpbGxpbmdUYXJnZXRzKSkge1xuICAgICAgdmFycyA9PT0gXCJhbGxcIiAmJiAodGhpcy5fcHQgPSAwKTtcbiAgICAgIHJldHVybiBfaW50ZXJydXB0KHRoaXMpO1xuICAgIH1cblxuICAgIG92ZXJ3cml0dGVuUHJvcHMgPSB0aGlzLl9vcCA9IHRoaXMuX29wIHx8IFtdO1xuXG4gICAgaWYgKHZhcnMgIT09IFwiYWxsXCIpIHtcbiAgICAgIC8vc28gcGVvcGxlIGNhbiBwYXNzIGluIGEgY29tbWEtZGVsaW1pdGVkIGxpc3Qgb2YgcHJvcGVydHkgbmFtZXNcbiAgICAgIGlmIChfaXNTdHJpbmcodmFycykpIHtcbiAgICAgICAgcCA9IHt9O1xuXG4gICAgICAgIF9mb3JFYWNoTmFtZSh2YXJzLCBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgIHJldHVybiBwW25hbWVdID0gMTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFycyA9IHA7XG4gICAgICB9XG5cbiAgICAgIHZhcnMgPSBfYWRkQWxpYXNlc1RvVmFycyhwYXJzZWRUYXJnZXRzLCB2YXJzKTtcbiAgICB9XG5cbiAgICBpID0gcGFyc2VkVGFyZ2V0cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBpZiAofmtpbGxpbmdUYXJnZXRzLmluZGV4T2YocGFyc2VkVGFyZ2V0c1tpXSkpIHtcbiAgICAgICAgY3VyTG9va3VwID0gcHJvcFR3ZWVuTG9va3VwW2ldO1xuXG4gICAgICAgIGlmICh2YXJzID09PSBcImFsbFwiKSB7XG4gICAgICAgICAgb3ZlcndyaXR0ZW5Qcm9wc1tpXSA9IHZhcnM7XG4gICAgICAgICAgcHJvcHMgPSBjdXJMb29rdXA7XG4gICAgICAgICAgY3VyT3ZlcndyaXRlUHJvcHMgPSB7fTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJPdmVyd3JpdGVQcm9wcyA9IG92ZXJ3cml0dGVuUHJvcHNbaV0gPSBvdmVyd3JpdHRlblByb3BzW2ldIHx8IHt9O1xuICAgICAgICAgIHByb3BzID0gdmFycztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAocCBpbiBwcm9wcykge1xuICAgICAgICAgIHB0ID0gY3VyTG9va3VwICYmIGN1ckxvb2t1cFtwXTtcblxuICAgICAgICAgIGlmIChwdCkge1xuICAgICAgICAgICAgaWYgKCEoXCJraWxsXCIgaW4gcHQuZCkgfHwgcHQuZC5raWxsKHApID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgIF9yZW1vdmVMaW5rZWRMaXN0SXRlbSh0aGlzLCBwdCwgXCJfcHRcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlbGV0ZSBjdXJMb29rdXBbcF07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGN1ck92ZXJ3cml0ZVByb3BzICE9PSBcImFsbFwiKSB7XG4gICAgICAgICAgICBjdXJPdmVyd3JpdGVQcm9wc1twXSA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5faW5pdHRlZCAmJiAhdGhpcy5fcHQgJiYgZmlyc3RQVCAmJiBfaW50ZXJydXB0KHRoaXMpOyAvL2lmIGFsbCB0d2VlbmluZyBwcm9wZXJ0aWVzIGFyZSBraWxsZWQsIGtpbGwgdGhlIHR3ZWVuLiBXaXRob3V0IHRoaXMgbGluZSwgaWYgdGhlcmUncyBhIHR3ZWVuIHdpdGggbXVsdGlwbGUgdGFyZ2V0cyBhbmQgdGhlbiB5b3Uga2lsbFR3ZWVuc09mKCkgZWFjaCB0YXJnZXQgaW5kaXZpZHVhbGx5LCB0aGUgdHdlZW4gd291bGQgdGVjaG5pY2FsbHkgc3RpbGwgcmVtYWluIGFjdGl2ZSBhbmQgZmlyZSBpdHMgb25Db21wbGV0ZSBldmVuIHRob3VnaCB0aGVyZSBhcmVuJ3QgYW55IG1vcmUgcHJvcGVydGllcyB0d2VlbmluZy5cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIFR3ZWVuLnRvID0gZnVuY3Rpb24gdG8odGFyZ2V0cywgdmFycykge1xuICAgIHJldHVybiBuZXcgVHdlZW4odGFyZ2V0cywgdmFycywgYXJndW1lbnRzWzJdKTtcbiAgfTtcblxuICBUd2Vlbi5mcm9tID0gZnVuY3Rpb24gZnJvbSh0YXJnZXRzLCB2YXJzKSB7XG4gICAgcmV0dXJuIF9jcmVhdGVUd2VlblR5cGUoMSwgYXJndW1lbnRzKTtcbiAgfTtcblxuICBUd2Vlbi5kZWxheWVkQ2FsbCA9IGZ1bmN0aW9uIGRlbGF5ZWRDYWxsKGRlbGF5LCBjYWxsYmFjaywgcGFyYW1zLCBzY29wZSkge1xuICAgIHJldHVybi
1BuZXcgVHdlZW4oY2FsbGJhY2ssIDAsIHtcbiAgICAgIGltbWVkaWF0ZVJlbmRlcjogZmFsc2UsXG4gICAgICBsYXp5OiBmYWxzZSxcbiAgICAgIG92ZXJ3cml0ZTogZmFsc2UsXG4gICAgICBkZWxheTogZGVsYXksXG4gICAgICBvbkNvbXBsZXRlOiBjYWxsYmFjayxcbiAgICAgIG9uUmV2ZXJzZUNvbXBsZXRlOiBjYWxsYmFjayxcbiAgICAgIG9uQ29tcGxldGVQYXJhbXM6IHBhcmFtcyxcbiAgICAgIG9uUmV2ZXJzZUNvbXBsZXRlUGFyYW1zOiBwYXJhbXMsXG4gICAgICBjYWxsYmFja1Njb3BlOiBzY29wZVxuICAgIH0pOyAvLyB3ZSBtdXN0IHVzZSBvblJldmVyc2VDb21wbGV0ZSB0b28gZm9yIHRoaW5ncyBsaWtlIHRpbWVsaW5lLmFkZCgoKSA9PiB7Li4ufSkgd2hpY2ggc2hvdWxkIGJlIHRyaWdnZXJlZCBpbiBCT1RIIGRpcmVjdGlvbnMgKGZvcndhcmQgYW5kIHJldmVyc2UpXG4gIH07XG5cbiAgVHdlZW4uZnJvbVRvID0gZnVuY3Rpb24gZnJvbVRvKHRhcmdldHMsIGZyb21WYXJzLCB0b1ZhcnMpIHtcbiAgICByZXR1cm4gX2NyZWF0ZVR3ZWVuVHlwZSgyLCBhcmd1bWVudHMpO1xuICB9O1xuXG4gIFR3ZWVuLnNldCA9IGZ1bmN0aW9uIHNldCh0YXJnZXRzLCB2YXJzKSB7XG4gICAgdmFycy5kdXJhdGlvbiA9IDA7XG4gICAgdmFycy5yZXBlYXREZWxheSB8fCAodmFycy5yZXBlYXQgPSAwKTtcbiAgICByZXR1cm4gbmV3IFR3ZWVuKHRhcmdldHMsIHZhcnMpO1xuICB9O1xuXG4gIFR3ZWVuLmtpbGxUd2VlbnNPZiA9IGZ1bmN0aW9uIGtpbGxUd2VlbnNPZih0YXJnZXRzLCBwcm9wcywgb25seUFjdGl2ZSkge1xuICAgIHJldHVybiBfZ2xvYmFsVGltZWxpbmUua2lsbFR3ZWVuc09mKHRhcmdldHMsIHByb3BzLCBvbmx5QWN0aXZlKTtcbiAgfTtcblxuICByZXR1cm4gVHdlZW47XG59KEFuaW1hdGlvbik7XG5cbl9zZXREZWZhdWx0cyhUd2Vlbi5wcm90b3R5cGUsIHtcbiAgX3RhcmdldHM6IFtdLFxuICBfbGF6eTogMCxcbiAgX3N0YXJ0QXQ6IDAsXG4gIF9vcDogMCxcbiAgX29uSW5pdDogMFxufSk7IC8vYWRkIHRoZSBwZXJ0aW5lbnQgdGltZWxpbmUgbWV0aG9kcyB0byBUd2VlbiBpbnN0YW5jZXMgc28gdGhhdCB1c2VycyBjYW4gY2hhaW4gY29udmVuaWVudGx5IGFuZCBjcmVhdGUgYSB0aW1lbGluZSBhdXRvbWF0aWNhbGx5LiAocmVtb3ZlZCBkdWUgdG8gY29uY2VybnMgdGhhdCBpdCdkIHVsdGltYXRlbHkgYWRkIHRvIG1vcmUgY29uZnVzaW9uIGVzcGVjaWFsbHkgZm9yIGJlZ2lubmVycylcbi8vIF9mb3JFYWNoTmFtZShcInRvLGZyb20sZnJvbVRvLHNldCxjYWxsLGFkZCxhZGRMYWJlbCxhZGRQYXVzZVwiLCBuYW1lID0+IHtcbi8vIFx0VHdlZW4ucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oKSB7XG4vLyBcdFx0bGV0IHRsID0gbmV3IFRpbWVsaW5lKCk7XG4vLyBcdFx0cmV0dXJuIF9hZGRUb1RpbWVsaW5lKHRsLCB0aGlzKVtuYW1lXS5hcHBseSh0bCwgdG9BcnJheShhcmd1bWVudHMpKTtcbi8vIFx0fVxuLy8gfSk7XG4vL2ZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LiBMZXZlcmFnZSB0aGUgdGltZWxpbmUgY2FsbHMuXG5cblxuX2ZvckVhY2hOYW1lKFwic3RhZ2dlclRvLHN0YWdnZXJGcm9tLHN0YWdnZXJGcm9tVG9cIiwgZnVuY3Rpb24gKG5hbWUpIHtcbiAgVHdlZW5bbmFtZV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRsID0gbmV3IFRpbWVsaW5lKCksXG4gICAgICAgIHBhcmFtcyA9IF9zbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG5cbiAgICBwYXJhbXMuc3BsaWNlKG5hbWUgPT09IFwic3RhZ2dlckZyb21Ub1wiID8gNSA6IDQsIDAsIDApO1xuICAgIHJldHVybiB0bFtuYW1lXS5hcHBseSh0bCwgcGFyYW1zKTtcbiAgfTtcbn0pO1xuLypcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBQUk9QVFdFRU5cbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuXG52YXIgX3NldHRlclBsYWluID0gZnVuY3Rpb24gX3NldHRlclBsYWluKHRhcmdldCwgcHJvcGVydHksIHZhbHVlKSB7XG4gIHJldHVybiB0YXJnZXRbcHJvcGVydHldID0gdmFsdWU7XG59LFxuICAgIF9zZXR0ZXJGdW5jID0gZnVuY3Rpb24gX3NldHRlckZ1bmModGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgcmV0dXJuIHRhcmdldFtwcm9wZXJ0eV0odmFsdWUpO1xufSxcbiAgICBfc2V0dGVyRnVuY1dpdGhQYXJhbSA9IGZ1bmN0aW9uIF9zZXR0ZXJGdW5jV2l0aFBhcmFtKHRhcmdldCwgcHJvcGVydHksIHZhbHVlLCBkYXRhKSB7XG4gIHJldHVybiB0YXJnZXRbcHJvcGVydHldKGRhdGEuZnAsIHZhbHVlKTtcbn0sXG4gICAgX3NldHRlckF0dHJpYnV0ZSA9IGZ1bmN0aW9uIF9zZXR0ZXJBdHRyaWJ1dGUodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgcmV0dXJuIHRhcmdldC5zZXRBdHRyaWJ1dGUocHJvcGVydHksIHZhbHVlKTtcbn0sXG4gICAgX2dldFNldHRlciA9IGZ1bmN0aW9uIF9nZXRTZXR0ZXIodGFyZ2V0LCBwcm9wZXJ0eSkge1xuICByZXR1cm4gX2lzRnVuY3Rpb24odGFyZ2V0W3Byb3BlcnR5XSkgPyBfc2V0dGVyRnVuYyA6IF9pc1VuZGVmaW5lZCh0YXJnZXRbcHJvcGVydHldKSAmJiB0YXJnZXQuc2V0QXR0cmlidXRlID8gX3NldHRlckF0dHJpYnV0ZSA6IF9zZXR0ZXJQbGFpbjtcbn0sXG4gICAgX3JlbmRlclBsYWluID0gZnVuY3Rpb24gX3JlbmRlclBsYWluKHJhdGlvLCBkYXRhKSB7XG4gIHJldHVybiBkYXRhLnNldChkYXRhLnQsIGRhdGEucCwgTWF0aC5yb3VuZCgoZGF0YS5zICsgZGF0YS5jICogcmF0aW8pICogMTAwMDAwMCkgLyAxMDAwMDAwLCBkYXRhKTtcbn0sXG4gICAgX3JlbmRlckJvb2xlYW4gPSBmdW5jdGlvbiBfcmVuZGVyQm9vbGVhbihyYXRpbywgZGF0YSkge1xuICByZXR1cm4gZGF0YS5zZXQoZGF0YS50LCBkYXRhLnAsICEhKGRhdGEucyArIGRhdGEuYyAqIHJhdGlvKSwgZGF0YSk7XG59LFxuICAgIF9yZW5kZXJDb21wbGV4U3RyaW5nID0gZnVuY3Rpb24gX3JlbmRlckNvbXBsZXhTdHJpbmcocmF0aW8sIGRhdGEpIHtcbiAgdmFyIHB0ID0gZGF0YS5fcHQsXG4gICAgICBzID0gXCJcIjtcblxuICBpZiAoIXJhdGlvICYmIGRhdGEuYikge1xuICAgIC8vYiA9IGJlZ2lubmluZyBzdHJpbmdcbiAgICBzID0gZGF0YS5iO1xuICB9IGVsc2UgaWYgKHJhdGlvID09PSAxICYmIGRhdGEuZSkge1xuICAgIC8vZSA9IGVuZGluZyBzdHJpbmdcbiAgICBzID0gZGF0YS5lO1xuICB9IGVsc2Uge1xuICAgIHdoaWxlIChwdCkge1xuICAgICAgcyA9IHB0LnAgKyAocHQubSA/IHB0Lm0ocHQucyArIHB0LmMgKiByYXRpbykgOiBNYXRoLnJvdW5kKChwdC5zICsgcHQuYyAqIHJhdGlvKSAqIDEwMDAwKSAvIDEwMDAwKSArIHM7IC8vd2UgdXNlI
1HRoZSBcInBcIiBwcm9wZXJ0eSBmb3IgdGhlIHRleHQgaW5iZXR3ZWVuIChsaWtlIGEgc3VmZml4KS4gQW5kIGluIHRoZSBjb250ZXh0IG9mIGEgY29tcGxleCBzdHJpbmcsIHRoZSBtb2RpZmllciAobSkgaXMgdHlwaWNhbGx5IGp1c3QgTWF0aC5yb3VuZCgpLCBsaWtlIGZvciBSR0IgY29sb3JzLlxuXG4gICAgICBwdCA9IHB0Ll9uZXh0O1xuICAgIH1cblxuICAgIHMgKz0gZGF0YS5jOyAvL3dlIHVzZSB0aGUgXCJjXCIgb2YgdGhlIFByb3BUd2VlbiB0byBzdG9yZSB0aGUgZmluYWwgY2h1bmsgb2Ygbm9uLW51bWVyaWMgdGV4dC5cbiAgfVxuXG4gIGRhdGEuc2V0KGRhdGEudCwgZGF0YS5wLCBzLCBkYXRhKTtcbn0sXG4gICAgX3JlbmRlclByb3BUd2VlbnMgPSBmdW5jdGlvbiBfcmVuZGVyUHJvcFR3ZWVucyhyYXRpbywgZGF0YSkge1xuICB2YXIgcHQgPSBkYXRhLl9wdDtcblxuICB3aGlsZSAocHQpIHtcbiAgICBwdC5yKHJhdGlvLCBwdC5kKTtcbiAgICBwdCA9IHB0Ll9uZXh0O1xuICB9XG59LFxuICAgIF9hZGRQbHVnaW5Nb2RpZmllciA9IGZ1bmN0aW9uIF9hZGRQbHVnaW5Nb2RpZmllcihtb2RpZmllciwgdHdlZW4sIHRhcmdldCwgcHJvcGVydHkpIHtcbiAgdmFyIHB0ID0gdGhpcy5fcHQsXG4gICAgICBuZXh0O1xuXG4gIHdoaWxlIChwdCkge1xuICAgIG5leHQgPSBwdC5fbmV4dDtcbiAgICBwdC5wID09PSBwcm9wZXJ0eSAmJiBwdC5tb2RpZmllcihtb2RpZmllciwgdHdlZW4sIHRhcmdldCk7XG4gICAgcHQgPSBuZXh0O1xuICB9XG59LFxuICAgIF9raWxsUHJvcFR3ZWVuc09mID0gZnVuY3Rpb24gX2tpbGxQcm9wVHdlZW5zT2YocHJvcGVydHkpIHtcbiAgdmFyIHB0ID0gdGhpcy5fcHQsXG4gICAgICBoYXNOb25EZXBlbmRlbnRSZW1haW5pbmcsXG4gICAgICBuZXh0O1xuXG4gIHdoaWxlIChwdCkge1xuICAgIG5leHQgPSBwdC5fbmV4dDtcblxuICAgIGlmIChwdC5wID09PSBwcm9wZXJ0eSAmJiAhcHQub3AgfHwgcHQub3AgPT09IHByb3BlcnR5KSB7XG4gICAgICBfcmVtb3ZlTGlua2VkTGlzdEl0ZW0odGhpcywgcHQsIFwiX3B0XCIpO1xuICAgIH0gZWxzZSBpZiAoIXB0LmRlcCkge1xuICAgICAgaGFzTm9uRGVwZW5kZW50UmVtYWluaW5nID0gMTtcbiAgICB9XG5cbiAgICBwdCA9IG5leHQ7XG4gIH1cblxuICByZXR1cm4gIWhhc05vbkRlcGVuZGVudFJlbWFpbmluZztcbn0sXG4gICAgX3NldHRlcldpdGhNb2RpZmllciA9IGZ1bmN0aW9uIF9zZXR0ZXJXaXRoTW9kaWZpZXIodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUsIGRhdGEpIHtcbiAgZGF0YS5tU2V0KHRhcmdldCwgcHJvcGVydHksIGRhdGEubS5jYWxsKGRhdGEudHdlZW4sIHZhbHVlLCBkYXRhLm10KSwgZGF0YSk7XG59LFxuICAgIF9zb3J0UHJvcFR3ZWVuc0J5UHJpb3JpdHkgPSBmdW5jdGlvbiBfc29ydFByb3BUd2VlbnNCeVByaW9yaXR5KHBhcmVudCkge1xuICB2YXIgcHQgPSBwYXJlbnQuX3B0LFxuICAgICAgbmV4dCxcbiAgICAgIHB0MixcbiAgICAgIGZpcnN0LFxuICAgICAgbGFzdDsgLy9zb3J0cyB0aGUgUHJvcFR3ZWVuIGxpbmtlZCBsaXN0IGluIG9yZGVyIG9mIHByaW9yaXR5IGJlY2F1c2Ugc29tZSBwbHVnaW5zIG5lZWQgdG8gZG8gdGhlaXIgd29yayBhZnRlciBBTEwgb2YgdGhlIFByb3BUd2VlbnMgd2VyZSBjcmVhdGVkIChsaWtlIFJvdW5kUHJvcHNQbHVnaW4gYW5kIE1vZGlmaWVyc1BsdWdpbilcblxuICB3aGlsZSAocHQpIHtcbiAgICBuZXh0ID0gcHQuX25leHQ7XG4gICAgcHQyID0gZmlyc3Q7XG5cbiAgICB3aGlsZSAocHQyICYmIHB0Mi5wciA+IHB0LnByKSB7XG4gICAgICBwdDIgPSBwdDIuX25leHQ7XG4gICAgfVxuXG4gICAgaWYgKHB0Ll9wcmV2ID0gcHQyID8gcHQyLl9wcmV2IDogbGFzdCkge1xuICAgICAgcHQuX3ByZXYuX25leHQgPSBwdDtcbiAgICB9IGVsc2Uge1xuICAgICAgZmlyc3QgPSBwdDtcbiAgICB9XG5cbiAgICBpZiAocHQuX25leHQgPSBwdDIpIHtcbiAgICAgIHB0Mi5fcHJldiA9IHB0O1xuICAgIH0gZWxzZSB7XG4gICAgICBsYXN0ID0gcHQ7XG4gICAgfVxuXG4gICAgcHQgPSBuZXh0O1xuICB9XG5cbiAgcGFyZW50Ll9wdCA9IGZpcnN0O1xufTsgLy9Qcm9wVHdlZW4ga2V5OiB0ID0gdGFyZ2V0LCBwID0gcHJvcCwgciA9IHJlbmRlcmVyLCBkID0gZGF0YSwgcyA9IHN0YXJ0LCBjID0gY2hhbmdlLCBvcCA9IG92ZXJ3cml0ZVByb3BlcnR5IChPTkxZIHBvcHVsYXRlZCB3aGVuIGl0J3MgZGlmZmVyZW50IHRoYW4gcCksIHByID0gcHJpb3JpdHksIF9uZXh0L19wcmV2IGZvciB0aGUgbGlua2VkIGxpc3Qgc2libGluZ3MsIHNldCA9IHNldHRlciwgbSA9IG1vZGlmaWVyLCBtU2V0ID0gbW9kaWZpZXJTZXR0ZXIgKHRoZSBvcmlnaW5hbCBzZXR0ZXIsIGJlZm9yZSBhIG1vZGlmaWVyIHdhcyBhZGRlZClcblxuXG5leHBvcnQgdmFyIFByb3BUd2VlbiA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFByb3BUd2VlbihuZXh0LCB0YXJnZXQsIHByb3AsIHN0YXJ0LCBjaGFuZ2UsIHJlbmRlcmVyLCBkYXRhLCBzZXR0ZXIsIHByaW9yaXR5KSB7XG4gICAgdGhpcy50ID0gdGFyZ2V0O1xuICAgIHRoaXMucyA9IHN0YXJ0O1xuICAgIHRoaXMuYyA9IGNoYW5nZTtcbiAgICB0aGlzLnAgPSBwcm9wO1xuICAgIHRoaXMuciA9IHJlbmRlcmVyIHx8IF9yZW5kZXJQbGFpbjtcbiAgICB0aGlzLmQgPSBkYXRhIHx8IHRoaXM7XG4gICAgdGhpcy5zZXQgPSBzZXR0ZXIgfHwgX3NldHRlclBsYWluO1xuICAgIHRoaXMucHIgPSBwcmlvcml0eSB8fCAwO1xuICAgIHRoaXMuX25leHQgPSBuZXh0O1xuXG4gICAgaWYgKG5leHQpIHtcbiAgICAgIG5leHQuX3ByZXYgPSB0aGlzO1xuICAgIH1cbiAgfVxuXG4gIHZhciBfcHJvdG80ID0gUHJvcFR3ZWVuLnByb3RvdHlwZTtcblxuICBfcHJvdG80Lm1vZGlmaWVyID0gZnVuY3Rpb24gbW9kaWZpZXIoZnVuYywgdHdlZW4sIHRhcmdldCkge1xuICAgIHRoaXMubVNldCA9IHRoaXMubVNldCB8fCB0aGlzLnNldDsgLy9pbiBjYXNlIGl0IHdhcyBhbHJlYWR5IHNldCAoYSBQcm9wVHdlZW4gY2FuIG9ubHkgaGF2ZSBvbmUgbW9kaWZpZXIpXG5cbiAgICB0aGlzLnNldCA9IF9zZXR0ZXJXaXRoTW9kaWZpZXI7XG4gICAgdGhpcy5tID0gZnVuYztcbiAgICB0aGlzLm10ID0gdGFyZ2V0OyAvL21vZGlmaWVyIHRhcmdldFxuXG4gICAgdGhpcy50d2VlbiA9IHR3ZWVuO1xuICB9O1xuXG4gIHJldHVybi
1BQcm9wVHdlZW47XG59KCk7IC8vSW5pdGlhbGl6YXRpb24gdGFza3NcblxuX2ZvckVhY2hOYW1lKF9jYWxsYmFja05hbWVzICsgXCJwYXJlbnQsZHVyYXRpb24sZWFzZSxkZWxheSxvdmVyd3JpdGUscnVuQmFja3dhcmRzLHN0YXJ0QXQseW95byxpbW1lZGlhdGVSZW5kZXIscmVwZWF0LHJlcGVhdERlbGF5LGRhdGEscGF1c2VkLHJldmVyc2VkLGxhenksY2FsbGJhY2tTY29wZSxzdHJpbmdGaWx0ZXIsaWQseW95b0Vhc2Usc3RhZ2dlcixpbmhlcml0LHJlcGVhdFJlZnJlc2gsa2V5ZnJhbWVzLGF1dG9SZXZlcnQsc2Nyb2xsVHJpZ2dlclwiLCBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gX3Jlc2VydmVkUHJvcHNbbmFtZV0gPSAxO1xufSk7XG5cbl9nbG9iYWxzLlR3ZWVuTWF4ID0gX2dsb2JhbHMuVHdlZW5MaXRlID0gVHdlZW47XG5fZ2xvYmFscy5UaW1lbGluZUxpdGUgPSBfZ2xvYmFscy5UaW1lbGluZU1heCA9IFRpbWVsaW5lO1xuX2dsb2JhbFRpbWVsaW5lID0gbmV3IFRpbWVsaW5lKHtcbiAgc29ydENoaWxkcmVuOiBmYWxzZSxcbiAgZGVmYXVsdHM6IF9kZWZhdWx0cyxcbiAgYXV0b1JlbW92ZUNoaWxkcmVuOiB0cnVlLFxuICBpZDogXCJyb290XCIsXG4gIHNtb290aENoaWxkVGltaW5nOiB0cnVlXG59KTtcbl9jb25maWcuc3RyaW5nRmlsdGVyID0gX2NvbG9yU3RyaW5nRmlsdGVyO1xuXG52YXIgX21lZGlhID0gW10sXG4gICAgX2xpc3RlbmVycyA9IHt9LFxuICAgIF9lbXB0eUFycmF5ID0gW10sXG4gICAgX2xhc3RNZWRpYVRpbWUgPSAwLFxuICAgIF9jb250ZXh0SUQgPSAwLFxuICAgIF9kaXNwYXRjaCA9IGZ1bmN0aW9uIF9kaXNwYXRjaCh0eXBlKSB7XG4gIHJldHVybiAoX2xpc3RlbmVyc1t0eXBlXSB8fCBfZW1wdHlBcnJheSkubWFwKGZ1bmN0aW9uIChmKSB7XG4gICAgcmV0dXJuIGYoKTtcbiAgfSk7XG59LFxuICAgIF9vbk1lZGlhQ2hhbmdlID0gZnVuY3Rpb24gX29uTWVkaWFDaGFuZ2UoKSB7XG4gIHZhciB0aW1lID0gRGF0ZS5ub3coKSxcbiAgICAgIG1hdGNoZXMgPSBbXTtcblxuICBpZiAodGltZSAtIF9sYXN0TWVkaWFUaW1lID4gMikge1xuICAgIF9kaXNwYXRjaChcIm1hdGNoTWVkaWFJbml0XCIpO1xuXG4gICAgX21lZGlhLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgIHZhciBxdWVyaWVzID0gYy5xdWVyaWVzLFxuICAgICAgICAgIGNvbmRpdGlvbnMgPSBjLmNvbmRpdGlvbnMsXG4gICAgICAgICAgbWF0Y2gsXG4gICAgICAgICAgcCxcbiAgICAgICAgICBhbnlNYXRjaCxcbiAgICAgICAgICB0b2dnbGVkO1xuXG4gICAgICBmb3IgKHAgaW4gcXVlcmllcykge1xuICAgICAgICBtYXRjaCA9IF93aW4ubWF0Y2hNZWRpYShxdWVyaWVzW3BdKS5tYXRjaGVzOyAvLyBGaXJlZm94IGRvZXNuJ3QgdXBkYXRlIHRoZSBcIm1hdGNoZXNcIiBwcm9wZXJ0eSBvZiB0aGUgTWVkaWFRdWVyeUxpc3Qgb2JqZWN0IGNvcnJlY3RseSAtIGl0IG9ubHkgZG9lcyBzbyBhcyBpdCBjYWxscyBpdHMgY2hhbmdlIGhhbmRsZXIgLSBzbyB3ZSBtdXN0IHJlLWNyZWF0ZSBhIG1lZGlhIHF1ZXJ5IGhlcmUgdG8gZW5zdXJlIGl0J3MgYWNjdXJhdGUuXG5cbiAgICAgICAgbWF0Y2ggJiYgKGFueU1hdGNoID0gMSk7XG5cbiAgICAgICAgaWYgKG1hdGNoICE9PSBjb25kaXRpb25zW3BdKSB7XG4gICAgICAgICAgY29uZGl0aW9uc1twXSA9IG1hdGNoO1xuICAgICAgICAgIHRvZ2dsZWQgPSAxO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0b2dnbGVkKSB7XG4gICAgICAgIGMucmV2ZXJ0KCk7XG4gICAgICAgIGFueU1hdGNoICYmIG1hdGNoZXMucHVzaChjKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIF9kaXNwYXRjaChcIm1hdGNoTWVkaWFSZXZlcnRcIik7XG5cbiAgICBtYXRjaGVzLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgIHJldHVybiBjLm9uTWF0Y2goYywgZnVuY3Rpb24gKGZ1bmMpIHtcbiAgICAgICAgcmV0dXJuIGMuYWRkKG51bGwsIGZ1bmMpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgX2xhc3RNZWRpYVRpbWUgPSB0aW1lO1xuXG4gICAgX2Rpc3BhdGNoKFwibWF0Y2hNZWRpYVwiKTtcbiAgfVxufTtcblxudmFyIENvbnRleHQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBDb250ZXh0KGZ1bmMsIHNjb3BlKSB7XG4gICAgdGhpcy5zZWxlY3RvciA9IHNjb3BlICYmIHNlbGVjdG9yKHNjb3BlKTtcbiAgICB0aGlzLmRhdGEgPSBbXTtcbiAgICB0aGlzLl9yID0gW107IC8vIHJldHVybmVkL2NsZWFudXAgZnVuY3Rpb25zXG5cbiAgICB0aGlzLmlzUmV2ZXJ0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLmlkID0gX2NvbnRleHRJRCsrOyAvLyB0byB3b3JrIGFyb3VuZCBpc3N1ZXMgdGhhdCBmcmFtZXdvcmtzIGxpa2UgVnVlIGNhdXNlIGJ5IG1ha2luZyB0aGluZ3MgaW50byBQcm94aWVzIHdoaWNoIG1ha2UgaXQgaW1wb3NzaWJsZSB0byBkbyBzb21ldGhpbmcgbGlrZSBfbWVkaWEuaW5kZXhPZih0aGlzKSBiZWNhdXNlIFwidGhpc1wiIHdvdWxkIG5vIGxvbmdlciByZWZlciB0byB0aGUgQ29udGV4dCBpbnN0YW5jZSBpdHNlbGYgLSBpdCdkIHJlZmVyIHRvIGEgUHJveHkhIFdlIG5lZWRlZCBhIHdheSB0byBpZGVudGlmeSB0aGUgY29udGV4dCB1bmlxdWVseVxuXG4gICAgZnVuYyAmJiB0aGlzLmFkZChmdW5jKTtcbiAgfVxuXG4gIHZhciBfcHJvdG81ID0gQ29udGV4dC5wcm90b3R5cGU7XG5cbiAgX3Byb3RvNS5hZGQgPSBmdW5jdGlvbiBhZGQobmFtZSwgZnVuYywgc2NvcGUpIHtcbiAgICAvLyBwb3NzaWJsZSBmdXR1cmUgYWRkaXRpb24gaWYgd2UgbmVlZCB0aGUgYWJpbGl0eSB0byBhZGQoKSBhbiBhbmltYXRpb24gdG8gYSBjb250ZXh0IGFuZCBmb3Igd2hhdGV2ZXIgcmVhc29uIGNhbm5vdCBjcmVhdGUgdGhhdCBhbmltYXRpb24gaW5zaWRlIG9mIGEgY29udGV4dC5hZGQoKCkgPT4gey4uLn0pIGZ1bmN0aW9uLlxuICAgIC8vIGlmIChuYW1lICYmIF9pc0Z1bmN0aW9uKG5hbWUucmV2ZXJ0KSkge1xuICAgIC8vIFx0dGhpcy5kYXRhLnB1c2gobmFtZSk7XG4gICAgLy8gXHRyZXR1cm4gKG5hbWUuX2N0eCA9IHRoaXMpO1xuICAgIC8vIH1cbiAgICBpZiAoX2lzRnVuY3Rpb24obmFtZSkpIHtcbiAgICAgIHNjb3BlID0gZnVuYztcbiAgICAgIGZ1bmMgPSBuYW1lO1xuICAgICAgbmFtZSA9IF9pc0Z1bmN0aW9uO1xuICAgIH1cblxuICAgI
1HZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgZiA9IGZ1bmN0aW9uIGYoKSB7XG4gICAgICB2YXIgcHJldiA9IF9jb250ZXh0LFxuICAgICAgICAgIHByZXZTZWxlY3RvciA9IHNlbGYuc2VsZWN0b3IsXG4gICAgICAgICAgcmVzdWx0O1xuICAgICAgcHJldiAmJiBwcmV2ICE9PSBzZWxmICYmIHByZXYuZGF0YS5wdXNoKHNlbGYpO1xuICAgICAgc2NvcGUgJiYgKHNlbGYuc2VsZWN0b3IgPSBzZWxlY3RvcihzY29wZSkpO1xuICAgICAgX2NvbnRleHQgPSBzZWxmO1xuICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShzZWxmLCBhcmd1bWVudHMpO1xuICAgICAgX2lzRnVuY3Rpb24ocmVzdWx0KSAmJiBzZWxmLl9yLnB1c2gocmVzdWx0KTtcbiAgICAgIF9jb250ZXh0ID0gcHJldjtcbiAgICAgIHNlbGYuc2VsZWN0b3IgPSBwcmV2U2VsZWN0b3I7XG4gICAgICBzZWxmLmlzUmV2ZXJ0ZWQgPSBmYWxzZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIHNlbGYubGFzdCA9IGY7XG4gICAgcmV0dXJuIG5hbWUgPT09IF9pc0Z1bmN0aW9uID8gZihzZWxmLCBmdW5jdGlvbiAoZnVuYykge1xuICAgICAgcmV0dXJuIHNlbGYuYWRkKG51bGwsIGZ1bmMpO1xuICAgIH0pIDogbmFtZSA/IHNlbGZbbmFtZV0gPSBmIDogZjtcbiAgfTtcblxuICBfcHJvdG81Lmlnbm9yZSA9IGZ1bmN0aW9uIGlnbm9yZShmdW5jKSB7XG4gICAgdmFyIHByZXYgPSBfY29udGV4dDtcbiAgICBfY29udGV4dCA9IG51bGw7XG4gICAgZnVuYyh0aGlzKTtcbiAgICBfY29udGV4dCA9IHByZXY7XG4gIH07XG5cbiAgX3Byb3RvNS5nZXRUd2VlbnMgPSBmdW5jdGlvbiBnZXRUd2VlbnMoKSB7XG4gICAgdmFyIGEgPSBbXTtcbiAgICB0aGlzLmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZSkge1xuICAgICAgcmV0dXJuIGUgaW5zdGFuY2VvZiBDb250ZXh0ID8gYS5wdXNoLmFwcGx5KGEsIGUuZ2V0VHdlZW5zKCkpIDogZSBpbnN0YW5jZW9mIFR3ZWVuICYmICEoZS5wYXJlbnQgJiYgZS5wYXJlbnQuZGF0YSA9PT0gXCJuZXN0ZWRcIikgJiYgYS5wdXNoKGUpO1xuICAgIH0pO1xuICAgIHJldHVybiBhO1xuICB9O1xuXG4gIF9wcm90bzUuY2xlYXIgPSBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICB0aGlzLl9yLmxlbmd0aCA9IHRoaXMuZGF0YS5sZW5ndGggPSAwO1xuICB9O1xuXG4gIF9wcm90bzUua2lsbCA9IGZ1bmN0aW9uIGtpbGwocmV2ZXJ0LCBtYXRjaE1lZGlhKSB7XG4gICAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgICBpZiAocmV2ZXJ0KSB7XG4gICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2Y
1XIgdHdlZW5zID0gX3RoaXM0LmdldFR3ZWVucygpLFxuICAgICAgICAgICAgaSA9IF90aGlzNC5kYXRhLmxlbmd0aCxcbiAgICAgICAgICAgIHQ7XG5cbiAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgIC8vIEZsaXAgcGx1Z2luIHR3ZWVucyBhcmUgdmVyeSBkaWZmZXJlbnQgaW4gdGhhdCB0aGV5IHNob3VsZCBhY3R1YWxseSBiZSBwdXNoZWQgdG8gdGhlaXIgZW5kLiBUaGUgcGx1Z2luIHJlcGxhY2VzIHRoZSB0aW1lbGluZSdzIC5yZXZlcnQoKSBtZXRob2QgdG8gZG8gZXhhY3RseSB0aGF0LiBCdXQgd2UgYWxzbyBuZWVkIHRvIHJlbW92ZSBhbnkgb2YgdGhvc2UgbmVzdGVkIHR3ZWVucyBpbnNpZGUgdGhlIGZsaXAgdGltZWxpbmUgc28gdGhhdCB0aGV5IGRvbid0IGdldCBpbmRpdmlkdWFsbHkgcmV2ZXJ0ZWQuXG4gICAgICAgICAgdCA9IF90aGlzNC5kYXRhW2ldO1xuXG4gICAgICAgICAgaWYgKHQuZGF0YSA9PT0gXCJpc0ZsaXBcIikge1xuICAgICAgICAgICAgdC5yZXZlcnQoKTtcbiAgICAgICAgICAgIHQuZ2V0Q2hpbGRyZW4odHJ1ZSwgdHJ1ZSwgZmFsc2UpLmZvckVhY2goZnVuY3Rpb24gKHR3ZWVuKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0d2VlbnMuc3BsaWNlKHR3ZWVucy5pbmRleE9mKHR3ZWVuKSwgMSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gLy8gc2F2ZSBhcyBhbiBvYmplY3Qgc28gdGhhdCB3ZSBjYW4gY2FjaGUgdGhlIGdsb2JhbFRpbWUgZm9yIGVhY2ggdHdlZW4gdG8gb3B0aW1pemUgcGVyZm9ybWFuY2UgZHVyaW5nIHRoZSBzb3J0XG5cblxuICAgICAgICB0d2VlbnMubWFwKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGc6IHQuX2R1ciB8fCB0Ll9kZWxheSB8fCB0Ll9zYXQgJiYgIXQuX3NhdC52YXJzLmltbWVkaWF0ZVJlbmRlciA/IHQuZ2xvYmFsVGltZSgwKSA6IC1JbmZpbml0eSxcbiAgICAgICAgICAgIHQ6IHRcbiAgICAgICAgICB9O1xuICAgICAgICB9KS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgcmV0dXJuIGIuZyAtIGEuZyB8fCAtSW5maW5pdHk7XG4gICAgICAgIH0pLmZvckVhY2goZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgICByZXR1cm4gby50LnJldmVydChyZXZlcnQpO1xuICAgICAgICB9KTsgLy8gbm90ZTogYWxsIG9mIHRoZSBfc3RhcnRBdCB0d2VlbnMgc2hvdWxkIGJlIHJldmVydGVkIGluIHJldmVyc2Ugb3JkZXIgdGhhdCB0aGV5IHdlcmUgY3JlYXRlZCwgYW5kIHRoZXknbGwgYWxsIGhhdmUgdGhlIHNhbWUgZ2xvYmFsVGltZSAoLTEpIHNvIHRoZSBcIiB8fCAtMVwiIGluIHRoZSBzb3J0IGtlZXBzIHRoZSBvcmRlciBwcm9wZXJseS5cblxuICAgICAgICBpID0gX3RoaXM0LmRhdGEubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAvLyBtYWtlIHN1cmUgd2UgbG9vcCBiYWNrd2FyZHMgc28gdGhhdCwgZm9yIGV4YW1wbGUsIFNwbGl0VGV4dHMgdGhhdCB3ZXJlIGNyZWF0ZWQgbGF0ZXIgb24gdGhlIHNhbWUgZWxlbWVudCBnZXQgcmV2ZXJ0ZWQgZmlyc3RcbiAgICAgICAgICB0ID0gX3RoaXM0LmRhdGFbaV07XG5cbiAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIFRpbWVsaW5lKSB7XG4gICAgICAgICAgICBpZiAodC5kYXRhICE9PSBcIm5lc3RlZFwiKSB7XG4gICAgICAgICAgICAgIHQuc2Nyb2xsVHJpZ2dlciAmJiB0LnNjcm9sbFRyaWdnZXIucmV2ZXJ0KCk7XG4gICAgICAgICAgICAgIHQua2lsbCgpOyAvLyBkb24ndCByZXZlcnQoKSB0aGUgdGltZWxpbmUgYmVjYXVzZSB0aGF0J3MgZHVwbGljYXRpbmcgZWZmb3J0cyBzaW5jZSB3ZSBhbHJlYWR5IHJldmVydGVkIGFsbCB0aGUgdHdlZW5zXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICEodCBpbnN0YW5jZW9mIFR3ZWVuKSAmJiB0LnJldmVydCAmJiB0LnJldmVydChyZXZlcnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIF90aGlzNC5fci5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgcmV0dXJuIGYocmV2ZXJ0LCBfdGhpczQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBfdGhpczQuaXNSZXZlcnRlZCA9IHRydWU7XG4gICAgICB9KSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICByZXR1cm4gZS5raWxsICYmIGUua2lsbCgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5jbGVhcigpO1xuXG4gICAgaWYgKG1hdGNoTWVkaWEpIHtcbiAgICAgIHZhciBpID0gX21lZGlhLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAvLyBwcmV2aW91c2x5LCB3ZSBjaGVja2VkIF9tZWRpYS5pbmRleE9mKHRoaXMpLCBidXQgc29tZSBmcmFtZXdvcmtzIGxpa2UgVnVlIGVuZm9yY2UgUHJveHkgb2JqZWN0cyB0aGF0IG1ha2UgaXQgaW1wb3NzaWJsZSB0byBnZXQgdGhlIHByb3BlciByZXN1bHQgdGhhdCB3YXksIHNvIHdlIG11c3QgdXNlIGEgdW5pcXVlIElEIG51bWJlciBpbnN0ZWFkLlxuICAgICAgICBfbWVkaWFbaV0uaWQgPT09IHRoaXMuaWQgJiYgX21lZGlhLnNwbGljZShpLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgX3Byb3RvNS5yZXZlcnQgPSBmdW5jdGlvbiByZXZlcnQoY29uZmlnKSB7XG4gICAgdGhpcy5raWxsKGNvbmZpZyB8fCB7fSk7XG4gIH07XG5cbiAgcmV0dXJuIENvbnRleHQ7XG59KCk7XG5cbnZhciBNYXRjaE1lZGlhID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gTWF0Y2hNZWRpYShzY29wZSkge1xuICAgIHRoaXMuY29udGV4dHMgPSBbXTtcbiAgICB0aGlzLnNjb3BlID0gc2NvcGU7XG4gICAgX2NvbnRleHQgJiYgX2NvbnRleHQuZGF0YS5wdXNoKHRoaXMpO1xuICB9XG5cbiAgdmFyIF9wcm90bzYgPSBNYXRjaE1lZGlhLnByb3RvdHlwZTtcblxuICBfcHJvdG82LmFkZCA9IGZ1bmN0aW9uIGFkZChjb25kaXRpb25zLCBmdW5jLCBzY29wZSkge1xuICAgIF9pc09iamVjdChjb25kaXRpb25zKSB8fCAoY29uZGl0aW9ucyA9IHtcbiAgICAgIG1hdGNoZXM6IGNvbmRpdGlvbnNcbiAgICB9KTtcbiAgICB2YXIgY29udGV4dCA9IG5ldyBDb250ZXh0KDAsIHNjb3BlIHx8IHRoaXMuc2NvcGUpLFxuICAgICAgICBjb25kID0gY29udGV4dC5jb25kaXRpb25zID0ge30sXG4gICAgICAgIG1xLFxuICAgICAgICBwLFxuICAgICAgICBhY3RpdmU7XG4gICAgX2NvbnRleHQgJiYgIWNvbnRleHQuc2VsZWN0b3IgJiYgKGNvbnRleHQuc2VsZWN0b3IgPSBfY29udGV4dC5zZWxlY3Rvcik7IC8vIGluIGNhc2UgYSBjb250ZXh0IGlzIGNyZWF0ZWQgaW5zaWRlIGEgY29udGV4dC4gTGlrZSBhIGdzYXAubWF0Y2hNZWRpYSgpIHRoYXQncyBpbnNpZGUgYSBzY29wZWQgZ3NhcC5jb250ZXh0KClcblxuICAgI
1HRoaXMuY29udGV4dHMucHVzaChjb250ZXh0KTtcbiAgICBmdW5jID0gY29udGV4dC5hZGQoXCJvbk1hdGNoXCIsIGZ1bmMpO1xuICAgIGNvbnRleHQucXVlcmllcyA9IGNvbmRpdGlvbnM7XG5cbiAgICBmb3IgKHAgaW4gY29uZGl0aW9ucykge1xuICAgICAgaWYgKHAgPT09IFwiYWxsXCIpIHtcbiAgICAgICAgYWN0aXZlID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1xID0gX3dpbi5tYXRjaE1lZGlhKGNvbmRpdGlvbnNbcF0pO1xuXG4gICAgICAgIGlmIChtcSkge1xuICAgICAgICAgIF9tZWRpYS5pbmRleE9mKGNvbnRleHQpIDwgMCAmJiBfbWVkaWEucHVzaChjb250ZXh0KTtcbiAgICAgICAgICAoY29uZFtwXSA9IG1xLm1hdGNoZXMpICYmIChhY3RpdmUgPSAxKTtcbiAgICAgICAgICBtcS5hZGRMaXN0ZW5lciA/IG1xLmFkZExpc3RlbmVyKF9vbk1lZGlhQ2hhbmdlKSA6IG1xLmFkZEV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIiwgX29uTWVkaWFDaGFuZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgYWN0aXZlICYmIGZ1bmMoY29udGV4dCwgZnVuY3Rpb24gKGYpIHtcbiAgICAgIHJldHVybiBjb250ZXh0LmFkZChudWxsLCBmKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSAvLyByZWZyZXNoKCkge1xuICAvLyBcdGxldCB0aW1lID0gX2xhc3RNZWRpYVRpbWUsXG4gIC8vIFx0XHRtZWRpYSA9IF9tZWRpYTtcbiAgLy8gXHRfbGFzdE1lZGlhVGltZSA9IC0xO1xuICAvLyBcdF9tZWRpYSA9IHRoaXMuY29udGV4dHM7XG4gIC8vIFx0X29uTWVkaWFDaGFuZ2UoKTtcbiAgLy8gXHRfbGFzdE1lZGlhVGltZSA9IHRpbWU7XG4gIC8vIFx0X21lZGlhID0gbWVkaWE7XG4gIC8vIH1cbiAgO1xuXG4gIF9wcm90bzYucmV2ZXJ0ID0gZnVuY3Rpb24gcmV2ZXJ0KGNvbmZpZykge1xuICAgIHRoaXMua2lsbChjb25maWcgfHwge30pO1xuICB9O1xuXG4gIF9wcm90bzYua2lsbCA9IGZ1bmN0aW9uIGtpbGwocmV2ZXJ0KSB7XG4gICAgdGhpcy5jb250ZXh0cy5mb3JFYWNoKGZ1bmN0aW9uIChjKSB7XG4gICAgICByZXR1cm4gYy5raWxsKHJldmVydCwgdHJ1ZSk7XG4gICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIE1hdGNoTWVkaWE7XG59KCk7XG4vKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEdTQVBcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuXG52YXIgX2dzYXAgPSB7XG4gIHJlZ2lzdGVyUGx1Z2luOiBmdW5jdGlvbiByZWdpc3RlclBsdWdpbigpIHtcbiAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjIpLCBfa2V5MiA9IDA7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcbiAgICAgIGFyZ3NbX2tleTJdID0gYXJndW1lbnRzW19rZXkyXTtcbiAgICB9XG5cbiAgICBhcmdzLmZvckVhY2goZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgcmV0dXJuIF9jcmVhdGVQbHVnaW4oY29uZmlnKTtcbiAgICB9KTtcbiAgfSxcbiAgdGltZWxpbmU6IGZ1bmN0aW9uIHRpbWVsaW5lKHZhcnMpIHtcbiAgICByZXR1cm4gbmV3IFRpbWVsaW5lKHZhcnMpO1xuICB9LFxuICBnZXRUd2VlbnNPZjogZnVuY3Rpb24gZ2V0VHdlZW5zT2YodGFyZ2V0cywgb25seUFjdGl2ZSkge1xuICAgIHJldHVybiBfZ2xvYmFsVGltZWxpbmUuZ2V0VHdlZW5zT2YodGFyZ2V0cywgb25seUFjdGl2ZSk7XG4gIH0sXG4gIGdldFByb3BlcnR5OiBmdW5jdGlvbiBnZXRQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB1bml0LCB1bmNhY2hlKSB7XG4gICAgX2lzU3RyaW5nKHRhcmdldCkgJiYgKHRhcmdldCA9IHRvQXJyYXkodGFyZ2V0KVswXSk7IC8vaW4gY2FzZSBzZWxlY3RvciB0ZXh0IG9yIGFuIGFycmF5IGlzIHBhc3NlZCBpblxuXG4gICAgdmFyIGdldHRlciA9IF9nZXRDYWNoZSh0YXJnZXQgfHwge30pLmdldCxcbiAgICAgICAgZm9ybWF0ID0gdW5pdCA/IF9wYXNzVGhyb3VnaCA6IF9udW1lcmljSWZQb3NzaWJsZTtcblxuICAgIHVuaXQgPT09IFwibmF0aXZlXCIgJiYgKHVuaXQgPSBcIlwiKTtcbiAgICByZXR1cm4gIXRhcmdldCA/IHRhcmdldCA6ICFwcm9wZXJ0eSA/IGZ1bmN0aW9uIChwcm9wZXJ0eSwgdW5pdCwgdW5jYWNoZSkge1xuICAgICAgcmV0dXJuIGZvcm1hdCgoX3BsdWdpbnNbcHJvcGVydHldICYmIF9wbHVnaW5zW3Byb3BlcnR5XS5nZXQgfHwgZ2V0dGVyKSh0YXJnZXQsIHByb3BlcnR5LCB1bml0LCB1bmNhY2hlKSk7XG4gICAgfSA6IGZvcm1hdCgoX3BsdWdpbnNbcHJvcGVydHldICYmIF9wbHVnaW5zW3Byb3BlcnR5XS5nZXQgfHwgZ2V0dGVyKSh0YXJnZXQsIHByb3BlcnR5LCB1bml0LCB1bmNhY2hlKSk7XG4gIH0sXG4gIHF1aWNrU2V0dGVyOiBmdW5jdGlvbiBxdWlja1NldHRlcih0YXJnZXQsIHByb3BlcnR5LCB1bml0KSB7XG4gICAgdGFyZ2V0ID0gdG9BcnJheSh0YXJnZXQpO1xuXG4gICAgaWYgKHRhcmdldC5sZW5ndGggPiAxKSB7XG4gICAgICB2Y
1XIgc2V0dGVycyA9IHRhcmdldC5tYXAoZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgcmV0dXJuIGdzYXAucXVpY2tTZXR0ZXIodCwgcHJvcGVydHksIHVuaXQpO1xuICAgICAgfSksXG4gICAgICAgICAgbCA9IHNldHRlcnMubGVuZ3RoO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgaSA9IGw7XG5cbiAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgIHNldHRlcnNbaV0odmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIHRhcmdldCA9IHRhcmdldFswXSB8fCB7fTtcblxuICAgIHZhciBQbHVnaW4gPSBfcGx1Z2luc1twcm9wZXJ0eV0sXG4gICAgICAgIGNhY2hlID0gX2dldENhY2hlKHRhcmdldCksXG4gICAgICAgIHAgPSBjYWNoZS5oYXJuZXNzICYmIChjYWNoZS5oYXJuZXNzLmFsaWFzZXMgfHwge30pW3Byb3BlcnR5XSB8fCBwcm9wZXJ0eSxcbiAgICAgICAgLy8gaW4gY2FzZSBpdCdzIGFuIGFsaWFzLCBsaWtlIFwicm90YXRlXCIgZm9yIFwicm90YXRpb25cIi5cbiAgICBzZXR0ZXIgPSBQbHVnaW4gPyBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHZhciBwID0gbmV3IFBsdWdpbigpO1xuICAgICAgX3F1aWNrVHdlZW4uX3B0ID0gMDtcbiAgICAgIHAuaW5pdCh0YXJnZXQsIHVuaXQgPyB2YWx1ZSArIHVuaXQgOiB2YWx1ZSwgX3F1aWNrVHdlZW4sIDAsIFt0YXJnZXRdKTtcbiAgICAgIHAucmVuZGVyKDEsIHApO1xuICAgICAgX3F1aWNrVHdlZW4uX3B0ICYmIF9yZW5kZXJQcm9wVHdlZW5zKDEsIF9xdWlja1R3ZWVuKTtcbiAgICB9IDogY2FjaGUuc2V0KHRhcmdldCwgcCk7XG5cbiAgICByZXR1cm4gUGx1Z2luID8gc2V0dGVyIDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICByZXR1cm4gc2V0dGVyKHRhcmdldCwgcCwgdW5pdCA/IHZhbHVlICsgdW5pdCA6IHZhbHVlLCBjYWNoZSwgMSk7XG4gICAgfTtcbiAgfSxcbiAgcXVpY2tUbzogZnVuY3Rpb24gcXVpY2tUbyh0YXJnZXQsIHByb3BlcnR5LCB2YXJzKSB7XG4gICAgdmFyIF9tZXJnZTI7XG5cbiAgICB2YXIgdHdlZW4gPSBnc2FwLnRvKHRhcmdldCwgX21lcmdlKChfbWVyZ2UyID0ge30sIF9tZXJnZTJbcHJvcGVydHldID0gXCIrPTAuMVwiLCBfbWVyZ2UyLnBhdXNlZCA9IHRydWUsIF9tZXJnZTIpLCB2YXJzIHx8IHt9KSksXG4gICAgICAgIGZ1bmMgPSBmdW5jdGlvbiBmdW5jKHZhbHVlLCBzdGFydCwgc3RhcnRJc1JlbGF0aXZlKSB7XG4gICAgICByZXR1cm4gdHdlZW4ucmVzZXRUbyhwcm9wZXJ0eSwgdmFsdWUsIHN0YXJ0LCBzdGFydElzUmVsYXRpdmUpO1xuICAgIH07XG5cbiAgICBmdW5jLnR3ZWVuID0gdHdlZW47XG4gICAgcmV0dXJuIGZ1bmM7XG4gIH0sXG4gIGlzVHdlZW5pbmc6IGZ1bmN0aW9uIGlzVHdlZW5pbmcodGFyZ2V0cykge1xuICAgIHJldHVybiBfZ2xvYmFsVGltZWxpbmUuZ2V0VHdlZW5zT2YodGFyZ2V0cywgdHJ1ZSkubGVuZ3RoID4gMDtcbiAgfSxcbiAgZGVmYXVsdHM6IGZ1bmN0aW9uIGRlZmF1bHRzKHZhbHVlKSB7XG4gICAgdmFsdWUgJiYgdmFsdWUuZWFzZSAmJiAodmFsdWUuZWFzZSA9IF9wYXJzZUVhc2UodmFsdWUuZWFzZSwgX2RlZmF1bHRzLmVhc2UpKTtcbiAgICByZXR1cm4gX21lcmdlRGVlcChfZGVmYXVsdHMsIHZhbHVlIHx8IHt9KTtcbiAgfSxcbiAgY29uZmlnOiBmdW5jdGlvbiBjb25maWcodmFsdWUpIHtcbiAgICByZXR1cm4gX21lcmdlRGVlcChfY29uZmlnLCB2YWx1ZSB8fCB7fSk7XG4gIH0sXG4gIHJlZ2lzdGVyRWZmZWN0OiBmdW5jdGlvbiByZWdpc3RlckVmZmVjdChfcmVmMykge1xuICAgIHZhciBuYW1lID0gX3JlZjMubmFtZSxcbiAgICAgICAgZWZmZWN0ID0gX3JlZjMuZWZmZWN0LFxuICAgICAgICBwbHVnaW5zID0gX3JlZjMucGx1Z2lucyxcbiAgICAgICAgZGVmYXVsdHMgPSBfcmVmMy5kZWZhdWx0cyxcbiAgICAgICAgZXh0ZW5kVGltZWxpbmUgPSBfcmVmMy5leHRlbmRUaW1lbGluZTtcbiAgICAocGx1Z2lucyB8fCBcIlwiKS5zcGxpdChcIixcIikuZm9yRWFjaChmdW5jdGlvbiAocGx1Z2luTmFtZSkge1xuICAgICAgcmV0dXJuIHBsdWdpbk5hbWUgJiYgIV9wbHVnaW5zW3BsdWdpbk5hbWVdICYmICFfZ2xvYmFsc1twbHVnaW5OYW1lXSAmJiBfd2FybihuYW1lICsgXCIgZWZmZWN0IHJlcXVpcmVzIFwiICsgcGx1Z2luTmFtZSArIFwiIHBsdWdpbi5cIik7XG4gICAgfSk7XG5cbiAgICBfZWZmZWN0c1tuYW1lXSA9IGZ1bmN0aW9uICh0YXJnZXRzLCB2YXJzLCB0bCkge1xuICAgICAgcmV0dXJuIGVmZmVjdCh0b0FycmF5KHRhcmdldHMpLCBfc2V0RGVmYXVsdHModmFycyB8fCB7fSwgZGVmYXVsdHMpLCB0bCk7XG4gICAgfTtcblxuICAgIGlmIChleHRlbmRUaW1lbGluZSkge1xuICAgICAgVGltZWxpbmUucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24gKHRhcmdldHMsIHZhcnMsIHBvc2l0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZChfZWZmZWN0c1tuYW1lXSh0YXJnZXRzLCBfaXNPYmplY3QodmFycykgPyB2YXJzIDogKHBvc2l0aW9uID0gdmFycykgJiYge30sIHRoaXMpLCBwb3NpdGlvbik7XG4gICAgICB9O1xuICAgIH1cbiAgfSxcbiAgcmVnaXN0ZXJFYXNlOiBmdW5jdGlvbiByZWdpc3RlckVhc2UobmFtZSwgZWFzZSkge1xuICAgIF9lYXNlTWFwW25hbWVdID0gX3BhcnNlRWFzZShlYXNlKTtcbiAgfSxcbiAgcGFyc2VFYXNlOiBmdW5jdGlvbiBwYXJzZUVhc2UoZWFzZSwgZGVmYXVsdEVhc2UpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IF9wYXJzZUVhc2UoZWFzZSwgZGVmYXVsdEVhc2UpIDogX2Vhc2VNYXA7XG4gIH0sXG4gIGdldEJ5SWQ6IGZ1bmN0aW9uIGdldEJ5SWQoaWQpIHtcbiAgICByZXR1cm4gX2dsb2JhbFRpbWVsaW5lLmdldEJ5SWQoaWQpO1xuICB9LFxuICBleHBvcnRSb290OiBmdW5jdGlvbiBleHBvcnRSb290KHZhcnMsIGluY2x1ZGVEZWxheWVkQ2FsbHMpIHtcbiAgICBpZiAodmFycyA9PT0gdm9pZCAwKSB7XG4gICAgICB2Y
1XJzID0ge307XG4gICAgfVxuXG4gICAgdmFyIHRsID0gbmV3IFRpbWVsaW5lKHZhcnMpLFxuICAgICAgICBjaGlsZCxcbiAgICAgICAgbmV4dDtcbiAgICB0bC5zbW9vdGhDaGlsZFRpbWluZyA9IF9pc05vdEZhbHNlKHZhcnMuc21vb3RoQ2hpbGRUaW1pbmcpO1xuXG4gICAgX2dsb2JhbFRpbWVsaW5lLnJlbW92ZSh0bCk7XG5cbiAgICB0bC5fZHAgPSAwOyAvL290aGVyd2lzZSBpdCdsbCBnZXQgcmUtYWN0aXZhdGVkIHdoZW4gYWRkaW5nIGNoaWxkcmVuIGFuZCBiZSByZS1pbnRyb2R1Y2VkIGludG8gX2dsb2JhbFRpbWVsaW5lJ3MgbGlua2VkIGxpc3QgKHRoZW4gYWRkZWQgdG8gaXRzZWxmKS5cblxuICAgIHRsLl90aW1lID0gdGwuX3RUaW1lID0gX2dsb2JhbFRpbWVsaW5lLl90aW1lO1xuICAgIGNoaWxkID0gX2dsb2JhbFRpbWVsaW5lLl9maXJzdDtcblxuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgbmV4dCA9IGNoaWxkLl9uZXh0O1xuXG4gICAgICBpZiAoaW5jbHVkZURlbGF5ZWRDYWxscyB8fCAhKCFjaGlsZC5fZHVyICYmIGNoaWxkIGluc3RhbmNlb2YgVHdlZW4gJiYgY2hpbGQudmFycy5vbkNvbXBsZXRlID09PSBjaGlsZC5fdGFyZ2V0c1swXSkpIHtcbiAgICAgICAgX2FkZFRvVGltZWxpbmUodGwsIGNoaWxkLCBjaGlsZC5fc3RhcnQgLSBjaGlsZC5fZGVsYXkpO1xuICAgICAgfVxuXG4gICAgICBjaGlsZCA9IG5leHQ7XG4gICAgfVxuXG4gICAgX2FkZFRvVGltZWxpbmUoX2dsb2JhbFRpbWVsaW5lLCB0bCwgMCk7XG5cbiAgICByZXR1cm4gdGw7XG4gIH0sXG4gIGNvbnRleHQ6IGZ1bmN0aW9uIGNvbnRleHQoZnVuYywgc2NvcGUpIHtcbiAgICByZXR1cm4gZnVuYyA/IG5ldyBDb250ZXh0KGZ1bmMsIHNjb3BlKSA6IF9jb250ZXh0O1xuICB9LFxuICBtYXRjaE1lZGlhOiBmdW5jdGlvbiBtYXRjaE1lZGlhKHNjb3BlKSB7XG4gICAgcmV0dXJuIG5ldyBNYXRjaE1lZGlhKHNjb3BlKTtcbiAgfSxcbiAgbWF0Y2hNZWRpYVJlZnJlc2g6IGZ1bmN0aW9uIG1hdGNoTWVkaWFSZWZyZXNoKCkge1xuICAgIHJldHVybiBfbWVkaWEuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgdmFyIGNvbmQgPSBjLmNvbmRpdGlvbnMsXG4gICAgICAgICAgZm91bmQsXG4gICAgICAgICAgcDtcblxuICAgICAgZm9yIChwIGluIGNvbmQpIHtcbiAgICAgICAgaWYgKGNvbmRbcF0pIHtcbiAgICAgICAgICBjb25kW3BdID0gZmFsc2U7XG4gICAgICAgICAgZm91bmQgPSAxO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvdW5kICYmIGMucmV2ZXJ0KCk7XG4gICAgfSkgfHwgX29uTWVkaWFDaGFuZ2UoKTtcbiAgfSxcbiAgYWRkRXZlbnRMaXN0ZW5lcjogZnVuY3Rpb24gYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBjYWxsYmFjaykge1xuICAgIHZhciBhID0gX2xpc3RlbmVyc1t0eXBlXSB8fCAoX2xpc3RlbmVyc1t0eXBlXSA9IFtdKTtcbiAgICB+YS5pbmRleE9mKGNhbGxiYWNrKSB8fCBhLnB1c2goY2FsbGJhY2spO1xuICB9LFxuICByZW1vdmVFdmVudExpc3RlbmVyOiBmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGEgPSBfbGlzdGVuZXJzW3R5cGVdLFxuICAgICAgICBpID0gYSAmJiBhLmluZGV4T2YoY2FsbGJhY2spO1xuICAgIGkgPj0gMCAmJiBhLnNwbGljZShpLCAxKTtcbiAgfSxcbiAgdXRpbHM6IHtcbiAgICB3cmFwOiB3cmFwLFxuICAgIHdyYXBZb3lvOiB3cmFwWW95byxcbiAgICBkaXN0cmlidXRlOiBkaXN0cmlidXRlLFxuICAgIHJhbmRvbTogcmFuZG9tLFxuICAgIHNuYXA6IHNuYXAsXG4gICAgbm9ybWFsaXplOiBub3JtYWxpemUsXG4gICAgZ2V0VW5pdDogZ2V0VW5pdCxcbiAgICBjbGFtcDogY2xhbXAsXG4gICAgc3BsaXRDb2xvcjogc3BsaXRDb2xvcixcbiAgICB0b0FycmF5OiB0b0FycmF5LFxuICAgIHNlbGVjdG9yOiBzZWxlY3RvcixcbiAgICBtYXBSYW5nZTogbWFwUmFuZ2UsXG4gICAgcGlwZTogcGlwZSxcbiAgICB1bml0aXplOiB1bml0aXplLFxuICAgIGludGVycG9sYXRlOiBpbnRlcnBvbGF0ZSxcbiAgICBzaHVmZmxlOiBzaHVmZmxlXG4gIH0sXG4gIGluc3RhbGw6IF9pbnN0YWxsLFxuICBlZmZlY3RzOiBfZWZmZWN0cyxcbiAgdGlja2VyOiBfdGlja2VyLFxuICB1cGRhdGVSb290OiBUaW1lbGluZS51cGRhdGVSb290LFxuICBwbHVnaW5zOiBfcGx1Z2lucyxcbiAgZ2xvYmFsVGltZWxpbmU6IF9nbG9iYWxUaW1lbGluZSxcbiAgY29yZToge1xuICAgIFByb3BUd2VlbjogUHJvcFR3ZWVuLFxuICAgIGdsb2JhbHM6IF9hZGRHbG9iYWwsXG4gICAgVHdlZW46IFR3ZWVuLFxuICAgIFRpbWVsaW5lOiBUaW1lbGluZSxcbiAgICBBbmltYXRpb246IEFuaW1hdGlvbixcbiAgICBnZXRDYWNoZTogX2dldENhY2hlLFxuICAgIF9yZW1vdmVMaW5rZWRMaXN0SXRlbTogX3JlbW92ZUxpbmtlZExpc3RJdGVtLFxuICAgIHJldmVydGluZzogZnVuY3Rpb24gcmV2ZXJ0aW5nKCkge1xuICAgICAgcmV0dXJuIF9yZXZlcnRpbmc7XG4gICAgfSxcbiAgICBjb250ZXh0OiBmdW5jdGlvbiBjb250ZXh0KHRvQWRkKSB7XG4gICAgICBpZiAodG9BZGQgJiYgX2NvbnRleHQpIHtcbiAgICAgICAgX2NvbnRleHQuZGF0YS5wdXNoKHRvQWRkKTtcblxuICAgICAgICB0b0FkZC5fY3R4ID0gX2NvbnRleHQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBfY29udGV4dDtcbiAgICB9LFxuICAgIHN1cHByZXNzT3ZlcndyaXRlczogZnVuY3Rpb24gc3VwcHJlc3NPdmVyd3JpdGVzKHZhbHVlKSB7XG4gICAgICByZXR1cm4gX3N1cHByZXNzT3ZlcndyaXRlcyA9IHZhbHVlO1xuICAgIH1cbiAgfVxufTtcblxuX2ZvckVhY2hOYW1lKFwidG8sZnJvbSxmcm9tVG8sZGVsYXllZENhbGwsc2V0LGtpbGxUd2VlbnNPZlwiLCBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gX2dzYXBbbmFtZV0gPSBUd2VlbltuYW1lXTtcbn0pO1xuXG5fdGlja2VyLmFkZChUaW1lbGluZS51cGRhdGVSb290KTtcblxuX3F1aWNrVHdlZW4gPSBfZ3NhcC50byh7fSwge1xuICBkdXJhdGlvbjogMFxufSk7IC8vIC0tLS0gRVhUUkEgUExVR0lOUyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG52YXIgX2dldFBsdWdpblByb3BUd2VlbiA9IGZ1bmN0aW9uIF9nZXRQbHVnaW5Qcm9wVHdlZW4ocGx1Z2luLCBwcm9wKSB7XG4gIHZhciBwdCA9IHBsdWdpbi5fcHQ7XG5cbiAgd2hpbGUgKHB0ICYmIHB0LnAgIT09IHByb3AgJiYgcHQub3AgIT09IHByb3AgJiYgcHQuZnAgIT09IHByb3ApIHtcbiAgICBwdCA9IHB0Ll9uZXh0O1xuICB9XG5cbiAgcmV0dXJuIHB0O1xufSxcbiAgICBfYWRkTW9kaWZpZXJzID0gZnVuY3Rpb24gX2FkZE1vZGlmaWVycyh0d2VlbiwgbW9kaWZpZXJzKSB7XG4gIHZhciB0YXJnZXRzID0gdHdlZW4uX3RhcmdldHMsXG4gICAgICBwLFxuICAgICAgaSxcbiAgICAgIHB0O1xuXG4gIGZvciAocCBpbiBtb2RpZmllcnMpIHtcbiAgICBpID0gdGFyZ2V0cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBwdCA9IHR3ZWVuLl9wdExvb2t1cFtpXVtwXTtcblxuICAgICAgaWYgKHB0ICYmIChwdCA9IHB0LmQpKSB7XG4gICAgICAgIGlmIChwdC5fcHQpIHtcbiAgICAgICAgICAvLyBpcyBhIHBsdWdpblxuICAgICAgICAgI
1HB0ID0gX2dldFBsdWdpblByb3BUd2VlbihwdCwgcCk7XG4gICAgICAgIH1cblxuICAgICAgICBwdCAmJiBwdC5tb2RpZmllciAmJiBwdC5tb2RpZmllcihtb2RpZmllcnNbcF0sIHR3ZWVuLCB0YXJnZXRzW2ldLCBwKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn0sXG4gICAgX2J1aWxkTW9kaWZpZXJQbHVnaW4gPSBmdW5jdGlvbiBfYnVpbGRNb2RpZmllclBsdWdpbihuYW1lLCBtb2RpZmllcikge1xuICByZXR1cm4ge1xuICAgIG5hbWU6IG5hbWUsXG4gICAgcmF3VmFyczogMSxcbiAgICAvL2Rvbid0IHByZS1wcm9jZXNzIGZ1bmN0aW9uLWJhc2VkIHZhbHVlcyBvciBcInJhbmRvbSgpXCIgc3RyaW5ncy5cbiAgICBpbml0OiBmdW5jdGlvbiBpbml0KHRhcmdldCwgdmFycywgdHdlZW4pIHtcbiAgICAgIHR3ZWVuLl9vbkluaXQgPSBmdW5jdGlvbiAodHdlZW4pIHtcbiAgICAgICAgdmFyIHRlbXAsIHA7XG5cbiAgICAgICAgaWYgKF9pc1N0cmluZyh2YXJzKSkge1xuICAgICAgICAgIHRlbXAgPSB7fTtcblxuICAgICAgICAgIF9mb3JFYWNoTmFtZSh2YXJzLCBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRlbXBbbmFtZV0gPSAxO1xuICAgICAgICAgIH0pOyAvL2lmIHRoZSB1c2VyIHBhc3NlcyBpbiBhIGNvbW1hLWRlbGltaXRlZCBsaXN0IG9mIHByb3BlcnR5IG5hbWVzIHRvIHJvdW5kUHJvcHMsIGxpa2UgXCJ4LHlcIiwgd2Ugcm91bmQgdG8gd2hvbGUgbnVtYmVycy5cblxuXG4gICAgICAgICAgdmFycyA9IHRlbXA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobW9kaWZpZXIpIHtcbiAgICAgICAgICB0ZW1wID0ge307XG5cbiAgICAgICAgICBmb3IgKHAgaW4gdmFycykge1xuICAgICAgICAgICAgdGVtcFtwXSA9IG1vZGlmaWVyKHZhcnNbcF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhcnMgPSB0ZW1wO1xuICAgICAgICB9XG5cbiAgICAgICAgX2FkZE1vZGlmaWVycyh0d2VlbiwgdmFycyk7XG4gICAgICB9O1xuICAgIH1cbiAgfTtcbn07IC8vcmVnaXN0ZXIgY29yZSBwbHVnaW5zXG5cblxuZXhwb3J0IHZhciBnc2FwID0gX2dzYXAucmVnaXN0ZXJQbHVnaW4oe1xuICBuYW1lOiBcImF0dHJcIixcbiAgaW5pdDogZnVuY3Rpb24gaW5pdCh0YXJnZXQsIHZhcnMsIHR3ZWVuLCBpbmRleCwgdGFyZ2V0cykge1xuICAgIHZhciBwLCBwdCwgdjtcbiAgICB0aGlzLnR3ZWVuID0gdHdlZW47XG5cbiAgICBmb3IgKHAgaW4gdmFycykge1xuICAgICAgdiA9IHRhcmdldC5nZXRBdHRyaWJ1dGUocCkgfHwgXCJcIjtcbiAgICAgIHB0ID0gdGhpcy5hZGQodGFyZ2V0LCBcInNldEF0dHJpYnV0ZVwiLCAodiB8fCAwKSArIFwiXCIsIHZhcnNbcF0sIGluZGV4LCB0YXJnZXRzLCAwLCAwLCBwKTtcbiAgICAgIHB0Lm9wID0gcDtcbiAgICAgIHB0LmIgPSB2OyAvLyByZWNvcmQgdGhlIGJlZ2lubmluZyB2YWx1ZSBzbyB3ZSBjYW4gcmV2ZXJ0KClcblxuICAgICAgdGhpcy5fcHJvcHMucHVzaChwKTtcbiAgICB9XG4gIH0sXG4gIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKHJhdGlvLCBkYXRhKSB7XG4gICAgdmFyIHB0ID0gZGF0YS5fcHQ7XG5cbiAgICB3aGlsZSAocHQpIHtcbiAgICAgIF9yZXZlcnRpbmcgPyBwdC5zZXQocHQudCwgcHQucCwgcHQuYiwgcHQpIDogcHQucihyYXRpbywgcHQuZCk7IC8vIGlmIHJldmVydGluZywgZ28gYmFjayB0byB0aGUgb3JpZ2luYWwgKHB0LmIpXG5cbiAgICAgIHB0ID0gcHQuX25leHQ7XG4gICAgfVxuICB9XG59LCB7XG4gIG5hbWU6IFwiZW5kQXJyYXlcIixcbiAgaW5pdDogZnVuY3Rpb24gaW5pdCh0YXJnZXQsIHZhbHVlKSB7XG4gICAgdmFyIGkgPSB2YWx1ZS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICB0aGlzLmFkZCh0YXJnZXQsIGksIHRhcmdldFtpXSB8fCAwLCB2YWx1ZVtpXSwgMCwgMCwgMCwgMCwgMCwgMSk7XG4gICAgfVxuICB9XG59LCBfYnVpbGRNb2RpZmllclBsdWdpbihcInJvdW5kUHJvcHNcIiwgX3JvdW5kTW9kaWZpZXIpLCBfYnVpbGRNb2RpZmllclBsdWdpbihcIm1vZGlmaWVyc1wiKSwgX2J1aWxkTW9kaWZpZXJQbHVnaW4oXCJzbmFwXCIsIHNuYXApKSB8fCBfZ3NhcDsgLy90byBwcmV2ZW50IHRoZSBjb3JlIHBsdWdpbnMgZnJvbSBiZWluZyBkcm9wcGVkIHZpYSBhZ2dyZXNzaXZlIHRyZWUgc2hha2luZywgd2UgbXVzdCBpbmNsdWRlIHRoZW0gaW4gdGhlIHZhcmlhYmxlIGRlY2xhcmF0aW9uIGluIHRoaXMgd2F5LlxuXG5Ud2Vlbi52ZXJzaW9uID0gVGltZWxpbmUudmVyc2lvbiA9IGdzYXAudmVyc2lvbiA9I
1FwiMy4xMi41XCI7XG5fY29yZVJlYWR5ID0gMTtcbl93aW5kb3dFeGlzdHMoKSAmJiBfd2FrZSgpO1xudmFyIFBvd2VyMCA9IF9lYXNlTWFwLlBvd2VyMCxcbiAgICBQb3dlcjEgPSBfZWFzZU1hcC5Qb3dlcjEsXG4gICAgUG93ZXIyID0gX2Vhc2VNYXAuUG93ZXIyLFxuICAgIFBvd2VyMyA9IF9lYXNlTWFwLlBvd2VyMyxcbiAgICBQb3dlcjQgPSBfZWFzZU1hcC5Qb3dlcjQsXG4gICAgTGluZWFyID0gX2Vhc2VNYXAuTGluZWFyLFxuICAgIFF1YWQgPSBfZWFzZU1hcC5RdWFkLFxuICAgIEN1YmljID0gX2Vhc2VNYXAuQ3ViaWMsXG4gICAgUXVhcnQgPSBfZWFzZU1hcC5RdWFydCxcbiAgICBRdWludCA9IF9lYXNlTWFwLlF1aW50LFxuICAgIFN0cm9uZyA9IF9lYXNlTWFwLlN0cm9uZyxcbiAgICBFbGFzdGljID0gX2Vhc2VNYXAuRWxhc3RpYyxcbiAgICBCYWNrID0gX2Vhc2VNYXAuQmFjayxcbiAgICBTdGVwcGVkRWFzZSA9IF9lYXNlTWFwLlN0ZXBwZWRFYXNlLFxuICAgIEJvdW5jZSA9IF9lYXNlTWFwLkJvdW5jZSxcbiAgICBTaW5lID0gX2Vhc2VNYXAuU2luZSxcbiAgICBFeHBvID0gX2Vhc2VNYXAuRXhwbyxcbiAgICBDaXJjID0gX2Vhc2VNYXAuQ2lyYztcbmV4cG9ydCB7IFBvd2VyMCwgUG93ZXIxLCBQb3dlcjIsIFBvd2VyMywgUG93ZXI0LCBMaW5lYXIsIFF1YWQsIEN1YmljLCBRdWFydCwgUXVpbnQsIFN0cm9uZywgRWxhc3RpYywgQmFjaywgU3RlcHBlZEVhc2UsIEJvdW5jZSwgU2luZSwgRXhwbywgQ2lyYyB9O1xuZXhwb3J0IHsgVHdlZW4gYXMgVHdlZW5NYXgsIFR3ZWVuIGFzIFR3ZWVuTGl0ZSwgVGltZWxpbmUgYXMgVGltZWxpbmVNYXgsIFRpbWVsaW5lIGFzIFRpbWVsaW5lTGl
10ZSwgZ3NhcCBhcyBkZWZhdWx0LCB3cmFwLCB3cmFwWW95bywgZGlzdHJpYnV0ZSwgcmFuZG9tLCBzbmFwLCBub3JtYWxpemUsIGdldFVuaXQsIGNsYW1wLCBzcGxpdENvbG9yLCB0b0FycmF5LCBzZWxlY3RvciwgbWFwUmFuZ2UsIHBpcGUsIHVuaXRpemUsIGludGVycG9sYXRlLCBzaHVmZmxlIH07IC8vZXhwb3J0IHNvbWUgaW50ZXJuYWwgbWV0aG9kcy9vcm9qZWN0cyBmb3IgdXNlIGluIENTU1BsdWdpbiBzbyB0aGF0IHdlIGNhbiBleHRlcm5hbGl6ZSB0aGF0IGZpbGUgYW5kIGFsbG93IGN1c3RvbSBidWlsZHMgdGhhdCBleGNsdWRlIGl0LlxuXG5leHBvcnQgeyBfZ2V0UHJvcGVydHksIF9udW1FeHAsIF9udW1XaXRoVW5pdEV4cCwgX2lzU3RyaW5nLCBfaXNVbmRlZmluZWQsIF9yZW5kZXJDb21wbGV4U3RyaW5nLCBfcmVsRXhwLCBfc2V0RGVmYXVsdHMsIF9yZW1vdmVMaW5rZWRMaXN0SXRlbSwgX2ZvckVhY2hOYW1lLCBfc29ydFByb3BUd2VlbnNCeVByaW9yaXR5LCBfY29sb3JTdHJpbmdGaWx0ZXIsIF9yZXBsYWNlUmFuZG9tLCBfY2hlY2tQbHVnaW4sIF9wbHVnaW5zLCBfdGlja2VyLCBfY29uZmlnLCBfcm91bmRNb2RpZmllciwgX3JvdW5kLCBfbWlzc2luZ1BsdWdpbiwgX2dldFNldHRlciwgX2dldENhY2hlLCBfY29sb3JFeHAsIF9wYXJzZVJlbGF0aXZlIH07IiwiLyohXG4gKiBDU1NQbHVnaW4gMy4xMi41XG4gKiBodHRwczovL2dzYXAuY29tXG4gKlxuICogQ29weXJpZ2h0IDIwMDgtMjAyNCwgR3JlZW5Tb2NrLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogU3ViamVjdCB0byB0aGUgdGVybXMgYXQgaHR0cHM6Ly9nc2FwLmNvbS9zdGFuZGFyZC1saWNlbnNlIG9yIGZvclxuICogQ2x1YiBHU0FQIG1lbWJlcnMsIHRoZSBhZ3JlZW1lbnQgaXNzdWVkIHdpdGggdGhhdCBtZW1iZXJzaGlwLlxuICogQGF1dGhvcjogSmFjayBEb3lsZSwgamFja0BncmVlbnNvY2suY29tXG4qL1xuXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuaW1wb3J0IHsgZ3NhcCwgX2dldFByb3BlcnR5LCBfbnVtRXhwLCBfbnVtV2l0aFVuaXRFeHAsIGdldFVuaXQsIF9pc1N0cmluZywgX2lzVW5kZWZpbmVkLCBfcmVuZGVyQ29tcGxleFN0cmluZywgX3JlbEV4cCwgX2ZvckVhY2hOYW1lLCBfc29ydFByb3BUd2VlbnNCeVByaW9yaXR5LCBfY29sb3JTdHJpbmdGaWx0ZXIsIF9jaGVja1BsdWdpbiwgX3JlcGxhY2VSYW5kb20sIF9wbHVnaW5zLCBHU0NhY2hlLCBQcm9wVHdlZW4sIF9jb25maWcsIF90aWNrZXIsIF9yb3VuZCwgX21pc3NpbmdQbHVnaW4sIF9nZXRTZXR0ZXIsIF9nZXRDYWNoZSwgX2NvbG9yRXhwLCBfcGFyc2VSZWxhdGl2ZSwgX3NldERlZmF1bHRzLCBfcmVtb3ZlTGlua2VkTGlzdEl0ZW0gLy9mb3IgdGhlIGNvbW1lbnRlZC1vdXQgY2xhc3NOYW1lIGZlYXR1cmUuXG59IGZyb20gXCIuL2dzYXAtY29yZS5qc1wiO1xuXG52YXIgX3dpbixcbiAgICBfZG9jLFxuICAgIF9kb2NFbGVtZW50LFxuICAgIF9wbHVnaW5Jbml0dGVkLFxuICAgIF90ZW1wRGl2LFxuICAgIF90ZW1wRGl2U3R5bGVyLFxuICAgIF9yZWNlbnRTZXR0ZXJQbHVnaW4sXG4gICAgX3JldmVydGluZyxcbiAgICBfd2luZG93RXhpc3RzID0gZnVuY3Rpb24gX3dpbmRvd0V4aXN0cygpIHtcbiAgcmV0dXJuIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCI7XG59LFxuICAgIF90cmFuc2Zvcm1Qcm9wcyA9IHt9LFxuICAgIF9SQUQyREVHID0gMTgwIC8gTWF0aC5QSSxcbiAgICBfREVHMlJBRCA9IE1hdGguUEkgLyAxODAsXG4gICAgX2F0YW4yID0gTWF0aC5hdGFuMixcbiAgICBfYmlnTnVtID0gMWU4LFxuICAgIF9jYXBzRXhwID0gLyhbQS1aXSkvZyxcbiAgICBfaG9yaXpvbnRhbEV4cCA9IC8obGVmdHxyaWdodHx3aWR0aHxtYXJnaW58cGFkZGluZ3x4KS9pLFxuICAgIF9jb21wbGV4RXhwID0gL1tcXHMsXFwoXVxcUy8sXG4gICAgX3Byb3BlcnR5QWxpYXNlcyA9IHtcbiAgYXV0b0FscGhhOiBcIm9wYWNpdHksdmlzaWJpbGl0eVwiLFxuICBzY2FsZTogXCJzY2FsZVgsc2NhbGVZXCIsXG4gIGFscGhhOiBcIm9wYWNpdHlcIlxufSxcbiAgICBfcmVuZGVyQ1NTUHJvcCA9IGZ1bmN0aW9uIF9yZW5kZXJDU1NQcm9wKHJhdGlvLCBkYXRhKSB7XG4gIHJldHVybiBkYXRhLnNldChkYXRhLnQsIGRhdGEucCwgTWF0aC5yb3VuZCgoZGF0YS5zICsgZGF0YS5jICogcmF0aW8pICogMTAwMDApIC8gMTAwMDAgKyBkYXRhLnUsIGRhdGEpO1xufSxcbiAgICBfcmVuZGVyUHJvcFdpdGhFbmQgPSBmdW5jdGlvbiBfcmVuZGVyUHJvcFdpdGhFbmQocmF0aW8sIGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEuc2V0KGRhdGEudCwgZGF0YS5wLCByYXRpbyA9PT0gMSA/IGRhdGEuZSA6IE1hdGgucm91bmQoKGRhdGEucyArIGRhdGEuYyAqIHJhdGlvKSAqIDEwMDAwKSAvIDEwMDAwICsgZGF0YS51LCBkYXRhKTtcbn0sXG4gICAgX3JlbmRlckNTU1Byb3BXaXRoQmVnaW5uaW5nID0gZnVuY3Rpb24gX3JlbmRlckNTU1Byb3BXaXRoQmVnaW5uaW5nKHJhdGlvLCBkYXRhKSB7XG4gIHJldHVybiBkYXRhLnNldChkYXRhLnQsIGRhdGEucCwgcmF0aW8gPyBNYXRoLnJvdW5kKChkYXRhLnMgKyBkYXRhLmMgKiByYXRpbykgKiAxMDAwMCkgLyAxMDAwMCArIGRhdGEudSA6IGRhdGEuYiwgZGF0YSk7XG59LFxuICAgIC8vaWYgdW5pdHMgY2hhbmdlLCB3ZSBuZWVkIGEgd2F5IHRvIHJlbmRlciB0aGUgb3JpZ2luYWwgdW5pdC92YWx1ZSB3aGVuIHRoZSB0d2VlbiBnb2VzIGFsbCB0aGUgd2F5IGJhY2sgdG8gdGhlIGJlZ2lubmluZyAocmF0aW86MClcbl9yZW5kZXJSb3VuZGVkQ1NTUHJvcCA9IGZ1bmN0aW9uIF9yZW5kZXJSb3VuZGVkQ1NTUHJvcChyYXRpbywgZGF0YSkge1xuICB2YXIgdmFsdWUgPSBkYXRhLnMgKyBkYXRhLmMgKiByYXRpbztcbiAgZGF0YS5zZXQoZGF0YS50LCBkYXRhLnAsIH5+KHZhbHVlICsgKHZhbHVlIDwgMCA/IC0uNSA6IC41KSkgKyBkYXRhLnUsIGRhdGEpO1xufSxcbiAgICBfcmVuZGVyTm9uVHdlZW5pbmdWYWx1ZSA9IGZ1bmN0aW9uIF9yZW5kZXJOb25Ud2VlbmluZ1ZhbHVlKHJhdGlvLCBkYXRhKSB7XG4gIHJldHVybiBkYXRhLnNldChkYXRhLnQsIGRhdGEucCwgcmF0aW8gPyBkYXRhLmUgOiBkYXRhLmIsIGRhdGEpO1xufSxcbiAgICBfcmVuZGVyTm9uVHdlZW5pbmdWYWx1ZU9ubHlBdEVuZCA9IGZ1bmN0aW9uIF9yZW5kZXJOb25Ud2VlbmluZ1ZhbHVlT25seUF0RW5kKHJhdGlvLCBkYXRhKSB7XG4gIHJldHVybi
1BkYXRhLnNldChkYXRhLnQsIGRhdGEucCwgcmF0aW8gIT09IDEgPyBkYXRhLmIgOiBkYXRhLmUsIGRhdGEpO1xufSxcbiAgICBfc2V0dGVyQ1NTU3R5bGUgPSBmdW5jdGlvbiBfc2V0dGVyQ1NTU3R5bGUodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgcmV0dXJuIHRhcmdldC5zdHlsZVtwcm9wZXJ0eV0gPSB2YWx1ZTtcbn0sXG4gICAgX3NldHRlckNTU1Byb3AgPSBmdW5jdGlvbiBfc2V0dGVyQ1NTUHJvcCh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkge1xuICByZXR1cm4gdGFyZ2V0LnN0eWxlLnNldFByb3BlcnR5KHByb3BlcnR5LCB2YWx1ZSk7XG59LFxuICAgIF9zZXR0ZXJUcmFuc2Zvcm0gPSBmdW5jdGlvbiBfc2V0dGVyVHJhbnNmb3JtKHRhcmdldCwgcHJvcGVydHksIHZhbHVlKSB7XG4gIHJldHVybiB0YXJnZXQuX2dzYXBbcHJvcGVydHldID0gdmFsdWU7XG59LFxuICAgIF9zZXR0ZXJTY2FsZSA9IGZ1bmN0aW9uIF9zZXR0ZXJTY2FsZSh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkge1xuICByZXR1cm4gdGFyZ2V0Ll9nc2FwLnNjYWxlWCA9IHRhcmdldC5fZ3NhcC5zY2FsZVkgPSB2YWx1ZTtcbn0sXG4gICAgX3NldHRlclNjYWxlV2l0aFJlbmRlciA9IGZ1bmN0aW9uIF9zZXR0ZXJTY2FsZVdpdGhSZW5kZXIodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUsIGRhdGEsIHJhdGlvKSB7XG4gIHZhciBjYWNoZSA9IHRhcmdldC5fZ3NhcDtcbiAgY2FjaGUuc2NhbGVYID0gY2FjaGUuc2NhbGVZID0gdmFsdWU7XG4gIGNhY2hlLnJlbmRlclRyYW5zZm9ybShyYXRpbywgY2FjaGUpO1xufSxcbiAgICBfc2V0dGVyVHJhbnNmb3JtV2l0aFJlbmRlciA9IGZ1bmN0aW9uIF9zZXR0ZXJUcmFuc2Zvcm1XaXRoUmVuZGVyKHRhcmdldCwgcHJvcGVydHksIHZhbHVlLCBkYXRhLCByYXRpbykge1xuICB2YXIgY2FjaGUgPSB0YXJnZXQuX2dzYXA7XG4gIGNhY2hlW3Byb3BlcnR5XSA9IHZhbHVlO1xuICBjYWNoZS5yZW5kZXJUcmFuc2Zvcm0ocmF0aW8sIGNhY2hlKTtcbn0sXG4gICAgX3RyYW5zZm9ybVByb3AgPSBcInRyYW5zZm9ybVwiLFxuICAgIF90cmFuc2Zvcm1PcmlnaW5Qcm9wID0gX3RyYW5zZm9ybVByb3AgKyBcIk9yaWdpblwiLFxuICAgIF9zYXZlU3R5bGUgPSBmdW5jdGlvbiBfc2F2ZVN0eWxlKHByb3BlcnR5LCBpc05vdENTUykge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHZhciB0YXJnZXQgPSB0aGlzLnRhcmdldCxcbiAgICAgIHN0eWxlID0gdGFyZ2V0LnN0eWxlLFxuICAgICAgY2FjaGUgPSB0YXJnZXQuX2dzYXA7XG5cbiAgaWYgKHByb3BlcnR5IGluIF90cmFuc2Zvcm1Qcm9wcyAmJiBzdHlsZSkge1xuICAgIHRoaXMudGZtID0gdGhpcy50Zm0gfHwge307XG5cbiAgICBpZiAocHJvcGVydHkgIT09IFwidHJhbnNmb3JtXCIpIHtcbiAgICAgIHByb3BlcnR5ID0gX3Byb3BlcnR5QWxpYXNlc1twcm9wZXJ0eV0gfHwgcHJvcGVydHk7XG4gICAgICB+cHJvcGVydHkuaW5kZXhPZihcIixcIikgPyBwcm9wZXJ0eS5zcGxpdChcIixcIikuZm9yRWFjaChmdW5jdGlvbiAoYSkge1xuICAgICAgICByZXR1cm4gX3RoaXMudGZtW2FdID0gX2dldCh0YXJnZXQsIGEpO1xuICAgICAgfSkgOiB0aGlzLnRmbVtwcm9wZXJ0eV0gPSBjYWNoZS54ID8gY2FjaGVbcHJvcGVydHldIDogX2dldCh0YXJnZXQsIHByb3BlcnR5KTsgLy8gbm90ZTogc2NhbGUgd291bGQgbWFwIHRvIFwic2NhbGVYLHNjYWxlWVwiLCB0aHVzIHdlIGxvb3AgYW5kIGFwcGx5IHRoZW0gYm90aC5cblxuICAgICAgcHJvcGVydHkgPT09IF90cmFuc2Zvcm1PcmlnaW5Qcm9wICYmICh0aGlzLnRmbS56T3JpZ2luID0gY2FjaGUuek9yaWdpbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBfcHJvcGVydHlBbGlhc2VzLnRyYW5zZm9ybS5zcGxpdChcIixcIikuZm9yRWFjaChmdW5jdGlvbiAocCkge1xuICAgICAgICByZXR1cm4gX3NhdmVTdHlsZS5jYWxsKF90aGlzLCBwLCBpc05vdENTUyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wcm9wcy5pbmRleE9mKF90cmFuc2Zvcm1Qcm9wKSA+PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGNhY2hlLnN2Zykge1xuICAgICAgdGhpcy5zdmdvID0gdGFyZ2V0LmdldEF0dHJpYnV0ZShcImRhdGEtc3ZnLW9yaWdpblwiKTtcbiAgICAgIHRoaXMucHJvcHMucHVzaChfdHJhbnNmb3JtT3JpZ2luUHJvcCwgaXNOb3RDU1MsIFwiXCIpO1xuICAgIH1cblxuICAgIHByb3BlcnR5ID0gX3RyYW5zZm9ybVByb3A7XG4gIH1cblxuICAoc3R5bGUgfHwgaXNOb3RDU1MpICYmIHRoaXMucHJvcHMucHVzaChwcm9wZXJ0eSwgaXNOb3RDU1MsIHN0eWxlW3Byb3BlcnR5XSk7XG59LFxuICAgIF9yZW1vdmVJbmRlcGVuZGVudFRyYW5zZm9ybXMgPSBmdW5jdGlvbiBfcmVtb3ZlSW5kZXBlbmRlbnRUcmFuc2Zvcm1zKHN0eWxlKSB7XG4gIGlmIChzdHlsZS50cmFuc2xhdGUpIHtcbiAgICBzdHlsZS5yZW1vdmVQcm9wZXJ0eShcInRyYW5zbGF0ZVwiKTtcbiAgICBzdHlsZS5yZW1vdmVQcm9wZXJ0eShcInNjYWxlXCIpO1xuICAgIHN0eWxlLnJlbW92ZVByb3BlcnR5KFwicm90YXRlXCIpO1xuICB9XG59LFxuICAgIF9yZXZlcnRTdHlsZSA9IGZ1bmN0aW9uIF9yZXZlcnRTdHlsZSgpIHtcbiAgdmFyIHByb3BzID0gdGhpcy5wcm9wcyxcbiAgICAgIHRhcmdldCA9IHRoaXMudGFyZ2V0LFxuICAgICAgc3R5bGUgPSB0YXJnZXQuc3R5bGUsXG4gICAgICBjYWNoZSA9IHRhcmdldC5fZ3NhcCxcbiAgICAgIGksXG4gICAgICBwO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkgKz0gMykge1xuICAgIC8vIHN0b3JlZCBsaWtlIHRoaXM6IHByb3BlcnR5LCBpc05vdENTUywgdmFsdWVcbiAgICBwcm9wc1tpICsgMV0gPyB0YXJnZXRbcHJvcHNbaV1dID0gcHJvcHNbaSArIDJdIDogcHJvcHNbaSArIDJdID8gc3R5bGVbcHJvcHNbaV1dID0gcHJvcHNbaSArIDJdIDogc3R5bGUucmVtb3ZlUHJvcGVydHkocHJvcHNbaV0uc3Vic3RyKDAsIDIpID09PSBcIi0tXCIgPyBwcm9wc1tpXSA6IHByb3BzW2ldLnJlcGxhY2UoX2NhcHNFeHAsIFwiLSQxXCIpLnRvTG93ZXJDYXNlKCkpO1xuICB9XG5cbiAgaWYgKHRoaXMudGZtKSB7XG4gICAgZm9yIChwIGluIHRoaXMudGZtKSB7XG4gICAgICBjYWNoZVtwXSA9IHRoaXMudGZtW3BdO1xuICAgIH1cblxuICAgIGlmIChjYWNoZS5zdmcpIHtcbiAgICAgIGNhY2hlLnJlbmRlclRyYW5zZm9ybSgpO1xuICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShcImRhdGEtc3ZnLW9yaWdpblwiLCB0aGlzLnN2Z28gfHwgXCJcIik7XG4gICAgfVxuXG4gICAgaSA9IF9yZXZlcnRpbmcoKTtcblxuICAgIGlmICgoIWkgfHwgIWkuaXNTdGFydCkgJiYgIXN0eWxlW190cmFuc2Zvcm1Qcm9wXSkge1xuICAgICAgX3JlbW92ZUluZGVwZW5kZW50VHJhbnNmb3JtcyhzdHlsZSk7XG5cbiAgICAgIGlmIChjYWNoZS56T3JpZ2luICYmIHN0eWxlW190cmFuc2Zvcm1PcmlnaW5Qcm9wXSkge1xuICAgICAgICBzdHlsZVtfdHJhbnNmb3JtT3JpZ2luUHJvcF0gKz0gXCIgXCIgKyBjYWNoZS56T3JpZ2luICsgXCJweFwiOyAvLyBzaW5jZSB3ZSdyZSB1bmNhY2hpbmcsIHdlIG11c3QgcHV0IHRoZSB6T3JpZ2luIGJhY2sgaW50byB0aGUgdHJhbnNmb3JtT3JpZ2luIHNvIHRoYXQgd2UgY2FuIHB1bGwgaXQgb3V0IGFjY3VyYXRlbHkgd2hlbiB3ZSBwYXJzZSBhZ2Fpbi4gT3RoZXJ3aXNlLCB3ZSdkIGxvc2UgdGhlIHogcG9ydGlvbiBvZiB0aGUgb3JpZ2luIHNpbmNlIHdlIGV4dHJhY3QgaXQgdG8gcHJvdGVjdCBmcm9tIFNhZmFyaSBidWdzLlxuXG4gICAgICAgIGNhY2hlLnpP
1cmlnaW4gPSAwO1xuICAgICAgICBjYWNoZS5yZW5kZXJUcmFuc2Zvcm0oKTtcbiAgICAgIH1cblxuICAgICAgY2FjaGUudW5jYWNoZSA9IDE7IC8vIGlmIGl0J3MgYSBzdGFydEF0IHRoYXQncyBiZWluZyByZXZlcnRlZCBpbiB0aGUgX2luaXRUd2VlbigpIG9mIHRoZSBjb3JlLCB3ZSBkb24ndCBuZWVkIHRvIHVuY2FjaGUgdHJhbnNmb3Jtcy4gVGhpcyBpcyBwdXJlbHkgYSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24uXG4gICAgfVxuICB9XG59LFxuICAgIF9nZXRTdHlsZVNhdmVyID0gZnVuY3Rpb24gX2dldFN0eWxlU2F2ZXIodGFyZ2V0LCBwcm9wZXJ0aWVzKSB7XG4gIHZhciBzYXZlciA9IHtcbiAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICBwcm9wczogW10sXG4gICAgcmV2ZXJ0OiBfcmV2ZXJ0U3R5bGUsXG4gICAgc2F2ZTogX3NhdmVTdHlsZVxuICB9O1xuICB0YXJnZXQuX2dzYXAgfHwgZ3NhcC5jb3JlLmdldENhY2hlKHRhcmdldCk7IC8vIGp1c3QgbWFrZSBzdXJlIHRoZXJlJ3MgYSBfZ3NhcCBjYWNoZSBkZWZpbmVkIGJlY2F1c2Ugd2UgcmVhZCBmcm9tIGl0IGluIF9zYXZlU3R5bGUoKSBhbmQgaXQncyBtb3JlIGVmZmljaWVudCB0byBqdXN0IGNoZWNrIGl0IGhlcmUgb25jZS5cblxuICBwcm9wZXJ0aWVzICYmIHByb3BlcnRpZXMuc3BsaXQoXCIsXCIpLmZvckVhY2goZnVuY3Rpb24gKHApIHtcbiAgICByZXR1cm4gc2F2ZXIuc2F2ZShwKTtcbiAgfSk7XG4gIHJldHVybiBzYXZlcjtcbn0sXG4gICAgX3N1cHBvcnRzM0QsXG4gICAgX2NyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbiBfY3JlYXRlRWxlbWVudCh0eXBlLCBucykge1xuICB2YXIgZSA9IF9kb2MuY3JlYXRlRWxlbWVudE5TID8gX2RvYy5jcmVhdGVFbGVtZW50TlMoKG5zIHx8IFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiKS5yZXBsYWNlKC9eaHR0cHMvLCBcImh0dHBcIiksIHR5cGUpIDogX2RvYy5jcmVhdGVFbGVtZW50KHR5cGUpOyAvL3NvbWUgc2VydmVycyBzd2FwIGluIGh0dHBzIGZvciBodHRwIGluIHRoZSBuYW1lc3BhY2Ugd2hpY2ggY2FuIGJyZWFrIHRoaW5ncywgbWFraW5nIFwic3R5bGVcIiBpbmFjY2Vzc2libGUuXG5cbiAgcmV0dXJuIGUgJiYgZS5zdHlsZSA/IGUgOiBfZG9jLmNyZWF0ZUVsZW1lbnQodHlwZSk7IC8vc29tZSBlbnZpcm9ubWVudHMgd29uJ3QgYWxsb3cgYWNjZXNzIHRvIHRoZSBlbGVtZW50J3Mgc3R5bGUgd2hlbiBjcmVhdGVkIHdpdGggYSBuYW1lc3BhY2UgaW4gd2hpY2ggY2FzZSB3ZSBkZWZhdWx0IHRvIHRoZSBzdGFuZGFyZCBjcmVhdGVFbGVtZW50KCkgdG8gd29yayBhcm91bmQgdGhlIGlzc3VlLiBBbHNvIG5vdGUgdGhhdCB3aGVuIEdTQVAgaXMgZW1iZWRkZWQgZGlyZWN0bHkgaW5zaWRlIGFuIFNWRyBmaWxlLCBjcmVhdGVFbGVtZW50KCkgd29uJ3QgYWxsb3cgYWNjZXNzIHRvIHRoZSBzdHlsZSBvYmplY3QgaW4gRmlyZWZveCAoc2VlIGh0dHBzOi8vZ3NhcC5jb20vZm9ydW1zL3RvcGljLzIwMjE1LXByb2JsZW0tdXNpbmctdHdlZW5tYXgtaW4tc3RhbmRhbG9uZS1zZWxmLWNvbnRhaW5pbmctc3ZnLWZpbGUtZXJyLWNhbm5vdC1zZXQtcHJvcGVydHktY3NzdGV4dC1vZi11bmRlZmluZWQvKS5cbn0sXG4gICAgX2dldENvbXB1dGVkUHJvcGVydHkgPSBmdW5jdGlvbiBfZ2V0Q29tcHV0ZWRQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCBza2lwUHJlZml4RmFsbGJhY2spIHtcbiAgdmFyIGNzID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpO1xuICByZXR1cm4gY3NbcHJvcGVydHldIHx8IGNzLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHkucmVwbGFjZShfY2Fwc0V4cCwgXCItJDFcIikudG9Mb3dlckNhc2UoKSkgfHwgY3MuZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eSkgfHwgIXNraXBQcmVmaXhGYWxsYmFjayAmJiBfZ2V0Q29tcHV0ZWRQcm9wZXJ0eSh0YXJnZXQsIF9jaGVja1Byb3BQcmVmaXgocHJvcGVydHkpIHx8IHByb3BlcnR5LCAxKSB8fCBcIlwiOyAvL2NzcyB2YXJpYWJsZXMgbWF5IG5vdCBuZWVkIGNhcHMgc3dhcHBlZCBvdXQgZm9yIGRhc2hlcyBhbmQgbG93ZXJjYXNlLlxufSxcbiAgICBfcHJlZml4ZXMgPSBcIk8sTW96LG1zLE1zLFdlYmtpdFwiLnNwbGl0KFwiLFwiKSxcbiAgICBfY2hlY2tQcm9wUHJlZml4ID0gZnVuY3Rpb24gX2NoZWNrUHJvcFByZWZpeChwcm9wZXJ0eSwgZWxlbWVudCwgcHJlZmVyUHJlZml4KSB7XG4gIHZhciBlID0gZWxlbWVudCB8fCBfdGVtcERpdixcbiAgICAgIHMgPSBlLnN0eWxlLFxuICAgICAgaSA9IDU7XG5cbiAgaWYgKHByb3BlcnR5IGluIHMgJiYgIXByZWZlclByZWZpeCkge1xuICAgIHJldHVybiBwcm9wZXJ0eTtcbiAgfVxuXG4gIHByb3BlcnR5ID0gcHJvcGVydHkuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBwcm9wZXJ0eS5zdWJzdHIoMSk7XG5cbiAgd2hpbGUgKGktLSAmJiAhKF9wcmVmaXhlc1tpXSArIHByb3BlcnR5IGluIHMpKSB7fVxuXG4gIHJldHVybiBpIDwgMCA/IG51bGwgOiAoaSA9PT0gMyA/IFwibXNcIiA6IGkgPj0gMCA/IF9wcmVmaXhlc1tpXSA6IFwiXCIpICsgcHJvcGVydHk7XG59LFxuICAgIF9pbml0Q29yZSA9IGZ1bmN0aW9uIF9pbml0Q29yZSgpIHtcbiAgaWYgKF93aW5kb3dFeGlzdHMoKSAmJiB3aW5kb3cuZG9jdW1lbnQpIHtcbiAgICBfd2luID0gd2luZG93O1xuICAgIF9kb2MgPSBfd2luLmRvY3VtZW50O1xuICAgIF9kb2NFbGVtZW50ID0gX2RvYy5kb2N1bWVudEVsZW1lbnQ7XG4gICAgX3RlbXBEaXYgPSBfY3JlYXRlRWxlbWVudChcImRpdlwiKSB8fCB7XG4gICAgICBzdHlsZToge31cbiAgICB9O1xuICAgIF90ZW1wRGl2U3R5bGVyID0gX2NyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgX3RyYW5zZm9ybVByb3AgPSBfY2hlY2tQcm9wUHJlZml4KF90cmFuc2Zvcm1Qcm9wKTtcbiAgICBfdHJhbnNmb3JtT3JpZ2luUHJvcCA9IF90cmFuc2Zvcm1Qcm9wICsgXCJPcmlnaW5cIjtcbiAgICBfdGVtcERpdi5zdHlsZS5jc3NUZXh0ID0gXCJib3JkZXItd2lkdGg6MDtsaW5lLWhlaWdodDowO3Bvc2l0aW9uOmFic29sdXRlO3BhZGRpbmc6MFwiOyAvL21ha2Ugc3VyZSB0byBvdmVycmlkZSBjZXJ0YWluIHByb3BlcnRpZXMgdGhhdCBtY
1XkgY29udGFtaW5hdGUgbWVhc3VyZW1lbnRzLCBpbiBjYXNlIHRoZSB1c2VyIGhhcyBvdmVycmVhY2hpbmcgc3R5bGUgc2hlZXRzLlxuXG4gICAgX3N1cHBvcnRzM0QgPSAhIV9jaGVja1Byb3BQcmVmaXgoXCJwZXJzcGVjdGl2ZVwiKTtcbiAgICBfcmV2ZXJ0aW5nID0gZ3NhcC5jb3JlLnJldmVydGluZztcbiAgICBfcGx1Z2luSW5pdHRlZCA9IDE7XG4gIH1cbn0sXG4gICAgX2dldEJCb3hIYWNrID0gZnVuY3Rpb24gX2dldEJCb3hIYWNrKHN3YXBJZlBvc3NpYmxlKSB7XG4gIC8vd29ya3MgYXJvdW5kIGlzc3VlcyBpbiBzb21lIGJyb3dzZXJzIChsaWtlIEZpcmVmb3gpIHRoYXQgZG9uJ3QgY29ycmVjdGx5IHJlcG9ydCBnZXRCQm94KCkgb24gU1ZHIGVsZW1lbnRzIGluc2lkZSBhIDxkZWZzPiBlbGVtZW50IGFuZC9vciA8bWFzaz4uIFdlIHRyeSBjcmVhdGluZyBhbiBTVkcsIGFkZGluZyBpdCB0byB0aGUgZG9jdW1lbnRFbGVtZW50IGFuZCB0b3NzIHRoZSBlbGVtZW50IGluIHRoZXJlIHNvIHRoYXQgaXQncyBkZWZpbml0ZWx5IHBhcnQgb2YgdGhlIHJlbmRlcmluZyB0cmVlLCB0aGVuIGdyYWIgdGhlIGJib3ggYW5kIGlmIGl0IHdvcmtzLCB3ZSBhY3R1YWxseSBzd2FwIG91dCB0aGUgb3JpZ2luYWwgZ2V0QkJveCgpIG1ldGhvZCBmb3Igb3VyIG93biB0aGF0IGRvZXMgdGhlc2UgZXh0cmEgc3RlcHMgd2hlbmV2ZXIgZ2V0QkJveCBpcyBuZWVkZWQuIFRoaXMgaGVscHMgZW5zdXJlIHRoYXQgcGVyZm9ybWFuY2UgaXMgb3B0aW1hbCAob25seSBkbyBhbGwgdGhlc2UgZXh0cmEgc3RlcHMgd2hlbiBhYnNvbHV0ZWx5IG5lY2Vzc2FyeS4uLm1vc3QgZWxlbWVudHMgZG9uJ3QgbmVlZCBpdCkuXG4gIHZhciBzdmcgPSBfY3JlYXRlRWxlbWVudChcInN2Z1wiLCB0aGlzLm93bmVyU1ZHRWxlbWVudCAmJiB0aGlzLm93bmVyU1ZHRWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJ4bWxuc1wiKSB8fCBcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIpLFxuICAgICAgb2xkUGFyZW50ID0gdGhpcy5wYXJlbnROb2RlLFxuICAgICAgb2xkU2libGluZyA9IHRoaXMubmV4dFNpYmxpbmcsXG4gICAgICBvbGRDU1MgPSB0aGlzLnN0eWxlLmNzc1RleHQsXG4gICAgICBiYm94O1xuXG4gIF9kb2NFbGVtZW50LmFwcGVuZENoaWxkKHN2Zyk7XG5cbiAgc3ZnLmFwcGVuZENoaWxkKHRoaXMpO1xuICB0aGlzLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG5cbiAgaWYgKHN3YXBJZlBvc3NpYmxlKSB7XG4gICAgdHJ5IHtcbiAgICAgIGJib3ggPSB0aGlzLmdldEJCb3goKTtcbiAgICAgIHRoaXMuX2dzYXBCQm94ID0gdGhpcy5nZXRCQm94OyAvL3N0b3JlIHRoZSBvcmlnaW5hbFxuXG4gICAgICB0aGlzLmdldEJCb3ggPSBfZ2V0QkJveEhhY2s7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfSBlbHNlIGlmICh0aGlzLl9nc2FwQkJveCkge1xuICAgIGJib3ggPSB0aGlzLl9nc2FwQkJveCgpO1xuICB9XG5cbiAgaWYgKG9sZFBhcmVudCkge1xuICAgIGlmIChvbGRTaWJsaW5nKSB7XG4gICAgICBvbGRQYXJlbnQuaW5zZXJ0QmVmb3JlKHRoaXMsIG9sZFNpYmxpbmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvbGRQYXJlbnQuYXBwZW5kQ2hpbGQodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgX2RvY0VsZW1lbnQucmVtb3ZlQ2hpbGQoc3ZnKTtcblxuICB0aGlzLnN0eWxlLmNzc1RleHQgPSBvbGRDU1M7XG4gIHJldHVybiBiYm94O1xufSxcbiAgICBfZ2V0QXR0cmlidXRlRmFsbGJhY2tzID0gZnVuY3Rpb24gX2dldEF0dHJpYnV0ZUZhbGxiYWNrcyh0YXJnZXQsIGF0dHJpYnV0ZXNBcnJheSkge1xuICB2YXIgaSA9IGF0dHJpYnV0ZXNBcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKGktLSkge1xuICAgIGlmICh0YXJnZXQuaGFzQXR0cmlidXRlKGF0dHJpYnV0ZXNBcnJheVtpXSkpIHtcbiAgICAgIHJldHVybiB0YXJnZXQuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZXNBcnJheVtpXSk7XG4gICAgfVxuICB9XG59LFxuICAgIF9nZXRCQm94ID0gZnVuY3Rpb24gX2dldEJCb3godGFyZ2V0KSB7XG4gIHZhciBib3VuZHM7XG5cbiAgdHJ5IHtcbiAgICBib3VuZHMgPSB0YXJnZXQuZ2V0QkJveCgpOyAvL0ZpcmVmb3ggdGhyb3dzIGVycm9ycyBpZiB5b3UgdHJ5IGNhbGxpbmcgZ2V0QkJveCgpIG9uIGFuIFNWRyBlbGVtZW50IHRoYXQncyBub3QgcmVuZGVyZWQgKGxpa2UgaW4gYSA8c3ltYm9sPiBvciA8ZGVmcz4pLiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02MTIxMThcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBib3VuZHMgPSBfZ2V0QkJveEhhY2suY2FsbCh0YXJnZXQsIHRydWUpO1xuICB9XG5cbiAgYm91bmRzICYmIChib3VuZHMud2lkdGggfHwgYm91bmRzLmhlaWdodCkgfHwgdGFyZ2V0LmdldEJCb3ggPT09IF9nZXRCQm94SGFjayB8fCAoYm91bmRzID0gX2dldEJCb3hIYWNrLmNhbGwodGFyZ2V0LCB0cnVlKSk7IC8vc29tZSBicm93c2VycyAobGlrZSBGaXJlZm94KSBtaXNyZXBvcnQgdGhlIGJvdW5kcyBpZiB0aGUgZWxlbWVudCBoYXMgemVybyB3aWR0aCBhbmQgaGVpZ2h0IChpdCBqdXN0IGFzc3VtZXMgaXQncyBhdCB4OjAsIHk6MCksIHRodXMgd2UgbmVlZCB0byBtYW51YWxseSBncmFiIHRoZSBwb3NpdGlvbiBpbiB0aGF0IGNhc2UuXG5cbiAgcmV0dXJuIGJvdW5kcyAmJiAhYm91bmRzLndpZHRoICYmICFib3VuZHMueCAmJiAhYm91bmRzLnkgPyB7XG4gICAgeDogK19nZXRBdHRyaWJ1dGVGYWxsYmFja3ModGFyZ2V0LCBbXCJ4XCIsIFwiY3hcIiwgXCJ4MVwiXSkgfHwgMCxcbiAgICB5OiArX2dldEF0dHJpYnV0ZUZhbGxiYWNrcyh0YXJnZXQsIFtcInlcIiwgXCJjeVwiLCBcInkxXCJdKSB8fCAwLFxuICAgIHdpZHRoOiAwLFxuICAgIGhlaWdodDogMFxuICB9IDogYm91bmRzO1xufSxcbiAgICBfaXNTVkcgPSBmdW5jdGlvbiBfaXNTVkcoZSkge1xuICByZXR1cm4gISEoZS5nZXRDVE0gJiYgKCFlLnBhcmVudE5vZGUgfHwgZS5vd25lclNWR0VsZW1lbnQpICYmIF9nZXRCQm94KGUpKTtcbn0sXG4gICAgLy9yZXBvcnRzIGlmIHRoZSBlbGVtZW50IGlzIGFuIFNWRyBvbiB3aGljaCBnZXRCQm94KCkgYWN0dWFsbHkgd29ya3
1Ncbl9yZW1vdmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIF9yZW1vdmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5KSB7XG4gIGlmIChwcm9wZXJ0eSkge1xuICAgIHZhciBzdHlsZSA9IHRhcmdldC5zdHlsZSxcbiAgICAgICAgZmlyc3QyQ2hhcnM7XG5cbiAgICBpZiAocHJvcGVydHkgaW4gX3RyYW5zZm9ybVByb3BzICYmIHByb3BlcnR5ICE9PSBfdHJhbnNmb3JtT3JpZ2luUHJvcCkge1xuICAgICAgcHJvcGVydHkgPSBfdHJhbnNmb3JtUHJvcDtcbiAgICB9XG5cbiAgICBpZiAoc3R5bGUucmVtb3ZlUHJvcGVydHkpIHtcbiAgICAgIGZpcnN0MkNoYXJzID0gcHJvcGVydHkuc3Vic3RyKDAsIDIpO1xuXG4gICAgICBpZiAoZmlyc3QyQ2hhcnMgPT09IFwibXNcIiB8fCBwcm9wZXJ0eS5zdWJzdHIoMCwgNikgPT09IFwid2Via2l0XCIpIHtcbiAgICAgICAgLy9NaWNyb3NvZnQgYW5kIHNvbWUgV2Via2l0IGJyb3dzZXJzIGRvbid0IGNvbmZvcm0gdG8gdGhlIHN0YW5kYXJkIG9mIGNhcGl0YWxpemluZyB0aGUgZmlyc3QgcHJlZml4IGNoYXJhY3Rlciwgc28gd2UgYWRqdXN0IHNvIHRoYXQgd2hlbiB3ZSBwcmVmaXggdGhlIGNhcHMgd2l0aCBhIGRhc2gsIGl0J3MgY29ycmVjdCAob3RoZXJ3aXNlIGl0J2QgYmUgXCJtcy10cmFuc2Zvcm1cIiBpbnN0ZWFkIG9mIFwiLW1zLXRyYW5zZm9ybVwiIGZvciBJRTksIGZvciBleGFtcGxlKVxuICAgICAgICBwcm9wZXJ0eSA9IFwiLVwiICsgcHJvcGVydHk7XG4gICAgICB9XG5cbiAgICAgIHN0eWxlLnJlbW92ZVByb3BlcnR5KGZpcnN0MkNoYXJzID09PSBcIi0tXCIgPyBwcm9wZXJ0eSA6IHByb3BlcnR5LnJlcGxhY2UoX2NhcHNFeHAsIFwiLSQxXCIpLnRvTG93ZXJDYXNlKCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvL25vdGU6IG9sZCB2ZXJzaW9ucyBvZiBJRSB1c2UgXCJyZW1vdmVBdHRyaWJ1dGUoKVwiIGluc3RlYWQgb2YgXCJyZW1vdmVQcm9wZXJ0eSgpXCJcbiAgICAgIHN0eWxlLnJlbW92ZUF0dHJpYnV0ZShwcm9wZXJ0eSk7XG4gICAgfVxuICB9XG59LFxuICAgIF9hZGROb25Ud2VlbmluZ1BUID0gZnVuY3Rpb24gX2FkZE5vblR3ZWVuaW5nUFQocGx1Z2luLCB0YXJnZXQsIHByb3BlcnR5LCBiZWdpbm5pbmcsIGVuZCwgb25seVNldEF0RW5kKSB7XG4gIHZhciBwdCA9IG5ldyBQcm9wVHdlZW4ocGx1Z2luLl9wdCwgdGFyZ2V0LCBwcm9wZXJ0eSwgMCwgMSwgb25seVNldEF0RW5kID8gX3JlbmRlck5vblR3ZWVuaW5nVmFsdWVPbmx5QXRFbmQgOiBfcmVuZGVyTm9uVHdlZW5pbmdWYWx1ZSk7XG4gIHBsdWdpbi5fcHQgPSBwdDtcbiAgcHQuYiA9IGJlZ2lubmluZztcbiAgcHQuZSA9IGVuZDtcblxuICBwbHVnaW4uX3Byb3BzLnB1c2gocHJvcGVydHkpO1xuXG4gIHJldHVybiBwdDtcbn0sXG4gICAgX25vbkNvbnZlcnRpYmxlVW5pdHMgPSB7XG4gIGRlZzogMSxcbiAgcmFkOiAxLFxuICB0dXJuOiAxXG59LFxuICAgIF9ub25TdGFuZGFyZExheW91dHMgPSB7XG4gIGdyaWQ6IDEsXG4gIGZsZXg6IDFcbn0sXG4gICAgLy90YWtlcyBhIHNpbmdsZSB2YWx1ZSBsaWtlIDIwcHggYW5kIGNvbnZlcnRzIGl0IHRvIHRoZSB1bml0IHNwZWNpZmllZCwgbGlrZSBcIiVcIiwgcmV0dXJuaW5nIG9ubHkgdGhlIG51bWVyaWMgYW1vdW50LlxuX2NvbnZlcnRUb1VuaXQgPSBmdW5jdGlvbiBfY29udmVydFRvVW5pdCh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSwgdW5pdCkge1xuICB2YXIgY3VyVmFsdWUgPSBwYXJzZUZsb2F0KHZhbHVlKSB8fCAwLFxuICAgICAgY3VyVW5pdCA9ICh2YWx1ZSArIFwiXCIpLnRyaW0oKS5zdWJzdHIoKGN1clZhbHVlICsgXCJcIikubGVuZ3RoKSB8fCBcInB4XCIsXG4gICAgICAvLyBzb21lIGJyb3dzZXJzIGxlYXZlIGV4dHJhIHdoaXRlc3BhY2UgYXQgdGhlIGJlZ2lubmluZyBvZiBDU1MgdmFyaWFibGVzLCBoZW5jZSB0aGUgbmVlZCB0byB0cmltKClcbiAgc3R5bGUgPSBfdGVtcERpdi5zdHlsZSxcbiAgICAgIGhvcml6b250YWwgPSBfaG9yaXpvbnRhbEV4cC50ZXN0KHByb3BlcnR5KSxcbiAgICAgIGlzUm9vdFNWRyA9IHRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwic3ZnXCIsXG4gICAgICBtZWFzdXJlUHJvcGVydHkgPSAoaXNSb290U1ZHID8gXCJjbGllbnRcIiA6IFwib2Zmc2V0XCIpICsgKGhvcml6b250YWwgPyBcIldpZHRoXCIgOiBcIkhlaWdodFwiKSxcbiAgICAgIGFtb3VudCA9IDEwMCxcbiAgICAgIHRvUGl4ZWxzID0gdW5pdCA9PT0gXCJweFwiLFxuICAgICAgdG9QZXJjZW50ID0gdW5pdCA9PT0gXCIlXCIsXG4gICAgICBweCxcbiAgICAgIHBhcmVudCxcbiAgICAgIGNhY2hlLFxuICAgICAgaXNTVkc7XG5cbiAgaWYgKHVuaXQgPT09IGN1clVuaXQgfHwgIWN1clZhbHVlIHx8IF9ub25Db252ZXJ0aWJsZVVuaXRzW3VuaXRdIHx8IF9ub25Db252ZXJ0aWJsZVVuaXRzW2N1clVuaXRdKSB7XG4gICAgcmV0dXJuIGN1clZhbHVlO1xuICB9XG5cbiAgY3VyVW5pdCAhPT0gXCJweFwiICYmICF0b1BpeGVscyAmJiAoY3VyVmFsdWUgPSBfY29udmVydFRvVW5pdCh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSwgXCJweFwiKSk7XG4gIGlzU1ZHID0gdGFyZ2V0LmdldENUTSAmJiBfaXNTVkcodGFyZ2V0KTtcblxuICBpZiAoKHRvUGVyY2VudCB8fCBjdXJVbml0ID09PSBcIiVcIikgJiYgKF90cmFuc2Zvcm1Qcm9wc1twcm9wZXJ0eV0gfHwgfnByb3BlcnR5LmluZGV4T2YoXCJhZGl1c1wiKSkpIHtcbiAgICBweCA9IGlzU1ZHID8gdGFyZ2V0LmdldEJCb3goKVtob3Jpem9udGFsID8gXCJ3aWR0aFwiIDogXCJoZWlnaHRcIl0gOiB0YXJnZXRbbWVhc3VyZVByb3BlcnR5XTtcbiAgICByZXR1cm4gX3JvdW5kKHRvUGVyY2VudCA/IGN1clZhbHVlIC8gcHggKiBhbW91bnQgOiBjdXJWYWx1ZSAvIDEwMCAqIHB4KTtcbiAgfVxuXG4gIHN0eWxlW2hvcml6b250YWwgPyBcIndpZHRoXCIgOiBcImhlaWdodFwiXSA9IGFtb3VudCArICh0b1BpeGVscyA/IGN1clVuaXQgOiB1bml0KTtcbiAgcGFyZW50ID0gfnByb3BlcnR5LmluZGV4T2YoXCJhZGl1c1wiKSB8fCB1bml0ID09PSBcImVtXCIgJiYgdGFyZ2V0LmFwcGVuZENoaWxkICYmICFpc1Jvb3RTVkcgPyB0YXJnZXQgOiB0YXJnZXQucGFyZW50Tm9kZTtcblxuICBpZiAoaXNTVkcpIHtcbiAgICBwYXJlbnQgPSAodGFyZ2V0Lm93bmVyU1ZHRWxlbWVudCB8fCB7fSkucGFyZW50Tm9kZTtcbiAgfVxuXG4gIGlmICghcGFyZW50IHx8IHBhcmVudCA9PT0gX2RvYyB8fCAhcGFyZW50LmFwcGVuZENoaWxkKSB7XG4gICAgcGFyZW50ID0gX2RvYy5ib2R5O1xuICB9XG5cbiAgY2FjaGUgPSBwYXJlbnQuX2dzYXA7XG5cbiAgaWYgKGNhY2hlICYmIHRvUGVyY2VudCAmJiBjYWNoZS53aWR0aCAmJi
1Bob3Jpem9udGFsICYmIGNhY2hlLnRpbWUgPT09IF90aWNrZXIudGltZSAmJiAhY2FjaGUudW5jYWNoZSkge1xuICAgIHJldHVybiBfcm91bmQoY3VyVmFsdWUgLyBjYWNoZS53aWR0aCAqIGFtb3VudCk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRvUGVyY2VudCAmJiAocHJvcGVydHkgPT09IFwiaGVpZ2h0XCIgfHwgcHJvcGVydHkgPT09IFwid2lkdGhcIikpIHtcbiAgICAgIC8vIGlmIHdlJ3JlIGRlYWxpbmcgd2l0aCB3aWR0aC9oZWlnaHQgdGhhdCdzIGluc2lkZSBhIGNvbnRhaW5lciB3aXRoIHBhZGRpbmcgYW5kL29yIGl0J3MgYSBmbGV4Ym94L2dyaWQgY29udGFpbmVyLCB3ZSBtdXN0IGFwcGx5IGl0IHRvIHRoZSB0YXJnZXQgaXRzZWxmIHJhdGhlciB0aGFuIHRoZSBfdGVtcERpdiBpbiBvcmRlciB0byBlbnN1cmUgY29tcGxldGUgYWNjdXJhY3ksIGZhY3RvcmluZyBpbiB0aGUgcGFyZW50J3MgcGFkZGluZy5cbiAgICAgIHZhciB2ID0gdGFyZ2V0LnN0eWxlW3Byb3BlcnR5XTtcbiAgICAgIHRhcmdldC5zdHlsZVtwcm9wZXJ0eV0gPSBhbW91bnQgKyB1bml0O1xuICAgICAgcHggPSB0YXJnZXRbbWVhc3VyZVByb3BlcnR5XTtcbiAgICAgIHYgPyB0YXJnZXQuc3R5bGVbcHJvcGVydHldID0gdiA6IF9yZW1vdmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgKHRvUGVyY2VudCB8fCBjdXJVbml0ID09PSBcIiVcIikgJiYgIV9ub25TdGFuZGFyZExheW91dHNbX2dldENvbXB1dGVkUHJvcGVydHkocGFyZW50LCBcImRpc3BsYXlcIildICYmIChzdHlsZS5wb3NpdGlvbiA9IF9nZXRDb21wdXRlZFByb3BlcnR5KHRhcmdldCwgXCJwb3NpdGlvblwiKSk7XG4gICAgICBwYXJlbnQgPT09IHRhcmdldCAmJiAoc3R5bGUucG9zaXRpb24gPSBcInN0YXRpY1wiKTsgLy8gbGlrZSBmb3IgYm9yZGVyUmFkaXVzLCBpZiBpdCdzIGEgJSB3ZSBtdXN0IGhhdmUgaXQgcmVsYXRpdmUgdG8gdGhlIHRhcmdldCBpdHNlbGYgYnV0IHRoYXQgbWF5IG5vdCBoYXZlIHBvc2l0aW9uOiByZWxhdGl2ZSBvciBwb3NpdGlvbjogYWJzb2x1dGUgaW4gd2hpY2ggY2FzZSBpdCdkIGdvIHVwIHRoZSBjaGFpbiB1bnRpbCBpdCBmaW5kcyBpdHMgb2Zmc2V0UGFyZW50IChiYWQpLiBwb3NpdGlvbjogc3RhdGljIHByb3RlY3RzIGFnYWluc3QgdGhhdC5cblxuICAgICAgcGFyZW50LmFwcGVuZENoaWxkKF90ZW1wRGl2KTtcbiAgICAgIHB4ID0gX3RlbXBEaXZbbWVhc3VyZVByb3BlcnR5XTtcbiAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChfdGVtcERpdik7XG4gICAgICBzdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICB9XG5cbiAgICBpZiAoaG9yaXpvbnRhbCAmJiB0b1BlcmNlbnQpIHtcbiAgICAgIGNhY2hlID0gX2dldENhY2hlKHBhcmVudCk7XG4gICAgICBjYWNoZS50aW1lID0gX3RpY2tlci50aW1lO1xuICAgICAgY2FjaGUud2lkdGggPSBwYXJlbnRbbWVhc3VyZVByb3BlcnR5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gX3JvdW5kKHRvUGl4ZWxzID8gcHggKiBjdXJWYWx1ZSAvIGFtb3VudCA6IHB4ICYmIGN1clZhbHVlID8gYW1vdW50IC8gcHggKiBjdXJWYWx1ZSA6IDApO1xufSxcbiAgICBfZ2V0ID0gZnVuY3Rpb24gX2dldCh0YXJnZXQsIHByb3BlcnR5LCB1bml0LCB1bmNhY2hlKSB7XG4gIHZhciB2YWx1ZTtcbiAgX3BsdWdpbkluaXR0ZWQgfHwgX2luaXRDb3JlKCk7XG5cbiAgaWYgKHByb3BlcnR5IGluIF9wcm9wZXJ0eUFsaWFzZXMgJiYgcHJvcGVydHkgIT09IFwidHJhbnNmb3JtXCIpIHtcbiAgICBwcm9wZXJ0eSA9IF9wcm9wZXJ0eUFsaWFzZXNbcHJvcGVydHldO1xuXG4gICAgaWYgKH5wcm9wZXJ0eS5pbmRleE9mKFwiLFwiKSkge1xuICAgICAgcHJvcGVydHkgPSBwcm9wZXJ0eS5zcGxpdChcIixcIilbMF07XG4gICAgfVxuICB9XG5cbiAgaWYgKF90cmFuc2Zvcm1Qcm9wc1twcm9wZXJ0eV0gJiYgcHJvcGVydHkgIT09IFwidHJhbnNmb3JtXCIpIHtcbiAgICB2YWx1ZSA9IF9wYXJzZVRyYW5zZm9ybSh0YXJnZXQsIHVuY2FjaGUpO1xuICAgIHZhbHVlID0gcHJvcGVydHkgIT09IFwidHJhbnNmb3JtT3JpZ2luXCIgPyB2YWx1ZVtwcm9wZXJ0eV0gOiB2YWx1ZS5zdmcgPyB2YWx1ZS5vcmlnaW4gOiBfZmlyc3RUd29Pbmx5KF9nZXRDb21wdXRlZFByb3BlcnR5KHRhcmdldCwgX3RyYW5zZm9ybU9yaWdpblByb3ApKSArIFwiIFwiICsgdmFsdWUuek9yaWdpbiArIFwicHhcIjtcbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSA9IHRhcmdldC5zdHlsZVtwcm9wZXJ0eV07XG5cbiAgICBpZiAoIXZhbHVlIHx8IHZhbHVlID09PSBcImF1dG9cIiB8fCB1bmNhY2hlIHx8IH4odmFsdWUgKyBcIlwiKS5pbmRleE9mKFwiY2FsYyhcIikpIHtcbiAgICAgIHZhbHVlID0gX3NwZWNpYWxQcm9wc1twcm9wZXJ0eV0gJiYgX3NwZWNpYWxQcm9wc1twcm9wZXJ0eV0odGFyZ2V0LCBwcm9wZXJ0eSwgdW5pdCkgfHwgX2dldENvbXB1dGVkUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSkgfHwgX2dldFByb3BlcnR5KHRhcmdldCwgcHJvcGVydHkpIHx8IChwcm9wZXJ0eSA9PT0gXCJvcGFjaXR5XCIgPyAxIDogMCk7IC8vIG5vdGU6IHNvbWUgYnJvd3NlcnMsIGxpa2UgRmlyZWZveCwgZG9uJ3QgcmVwb3J0IGJvcmRlclJhZGl1cyBjb3JyZWN0bHkhIEluc3RlYWQsIGl0IG9ubHkgcmVwb3J0cyBldmVyeSBjb3JuZXIgbGlrZSAgYm9yZGVyVG9wTGVmdFJhZGl1c1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bml0ICYmICF+KHZhbHVlICsgXCJcIikudHJpbSgpLmluZGV4T2YoXCIgXCIpID8gX2NvbnZlcnRUb1VuaXQodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUsIHVuaXQpICsgdW5pdCA6IHZhbHVlO1xufSxcbiAgICBfdHdlZW5Db21wbGV4Q1NTU3RyaW5nID0gZnVuY3Rpb24gX3R3ZWVuQ29tcGxleENTU1N0cmluZyh0YXJnZXQsIHByb3AsIHN0YXJ0LCBlbmQpIHtcbiAgLy8gbm90ZTogd2UgY2FsbCBfdHdlZW5Db21wbGV4Q1NTU3RyaW5nLmNhbGwocGx1Z2luSW5zdGFuY2UuLi4pIHRvIGVuc3VyZSB0aGF0IGl0J3Mgc2NvcGVkIHByb3Blcmx5LiBXZSBtYXkgY2FsbCBpdCBmcm9tIHdpdGhpbiBhIHBsdWdpbiB0b28sIHRodXMgXCJ0aGlzXCIgd291bGQgcmVmZXIgdG8gdGhlIHBsdWdpbi5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA9PT0gXCJub25lXCIpIHtcbiAgICAvLyBzb21lIGJyb3dzZXJzIGxpa2UgU2FmYXJpIGFjdHVhbGx5IFBSRUZFUiB0aGUgcHJlZml4ZWQgcHJvcGVydHkgYW5kIG1pcy1yZXBvcnQgdGhlIHVucHJlZml4ZWQgdmFsdWUgbGlrZSBjbGlwUGF0aCAoQlVHKS4gSW4gb3RoZXIgd29yZHMsIGV2ZW4gdGhvdWdoIGNsaXBQYXRoIGV4aXN0cyBpbiB0aGUgc3R5bGUgKFwiY2xpcFBhdGhcIiBpbiB0YXJnZXQuc3R5bGUpIGFuZCBpdCdzIHNldCBpbiB0aGUgQ1NTIHByb3Blcmx5IChhbG9uZyB3aXRoIC13ZWJraXQtY2xpcC1wYXRoKSwgU2FmYXJpIHJlcG9ydHMgY2xpcFBhdGggYXMgXCJub25lXCIgd2hlcmVhcyBXZWJraXRDbGlwUGF0aCByZXBvcnRzIGFjY3VyYXRlbHkgbGlrZSBcImVsbGlwc2UoMTAwJSAwJSBhdCA1MCUgMCUpXCIsIHNvIGluIHRoaXMgY2FzZSB3ZSBtdXN0IFNXSVRDSCB0byB1c2luZyB0aGUgcHJlZml4ZWQgcHJvcGVydHkgaW5zdGVhZC4gU2VlIGh0dHBzOi8vZ3NhcC5jb20vZm9ydW1zL3RvcGljLzE4MzEwLWNsaXBwYXRoLWRvZXNudC13b3JrLW9uLWlvcy9cbiAgICB2YXIgcCA9IF9jaGVja1Byb3BQcmVmaXgocHJvcCwgdGFyZ2V0LCAxKSxcbiAgICAgICAgcyA9IHAgJiYgX2dldENvbXB1dGVkUHJvcGVydHkodGFyZ2V0LCBwLCAxKTtcblxuICAgIGlmIChzICYmIHMgIT09IHN0YXJ0KSB7XG4gICAgICBwcm9wID0gcDtcbiAgICAgIHN0YXJ0ID0gcztcbiAgICB9IGVsc2UgaWYgKHByb3AgPT09IFwiYm9yZGVyQ29sb3JcIikge1xuICAgICAgc3RhcnQgPSBfZ2V0Q29tcHV0ZWRQcm9wZXJ0eSh0YXJnZXQsIFwiYm9yZGVyVG9wQ29sb3JcIik7IC8vIEZpcmVmb3ggYnVnOiBhbHdheXMgcmVwb3J0cyBcImJvcmRlckNvbG9yXCIgYXMgXCJcIiwgc28gd2UgbXVzdCBmYWxsIGJhY2sgdG8gYm9yZGVyVG9wQ29sb3IuIFNlZSBodHRwczovL2dzYXAuY29tL2ZvcnVtcy90b3BpYy8yNDU4My1ob3ctdG8tcmV0dXJuLWNvbG9ycy10aGF0LW
1ktaGFkLWFmdGVyLXJldmVyc2UvXG4gICAgfVxuICB9XG5cbiAgdmFyIHB0ID0gbmV3IFByb3BUd2Vlbih0aGlzLl9wdCwgdGFyZ2V0LnN0eWxlLCBwcm9wLCAwLCAxLCBfcmVuZGVyQ29tcGxleFN0cmluZyksXG4gICAgICBpbmRleCA9IDAsXG4gICAgICBtYXRjaEluZGV4ID0gMCxcbiAgICAgIGEsXG4gICAgICByZXN1bHQsXG4gICAgICBzdGFydFZhbHVlcyxcbiAgICAgIHN0YXJ0TnVtLFxuICAgICAgY29sb3IsXG4gICAgICBzdGFydFZhbHVlLFxuICAgICAgZW5kVmFsdWUsXG4gICAgICBlbmROdW0sXG4gICAgICBjaHVuayxcbiAgICAgIGVuZFVuaXQsXG4gICAgICBzdGFydFVuaXQsXG4gICAgICBlbmRWYWx1ZXM7XG4gIHB0LmIgPSBzdGFydDtcbiAgcHQuZSA9IGVuZDtcbiAgc3RhcnQgKz0gXCJcIjsgLy8gZW5zdXJlIHZhbHVlcyBhcmUgc3RyaW5nc1xuXG4gIGVuZCArPSBcIlwiO1xuXG4gIGlmIChlbmQgPT09IFwiYXV0b1wiKSB7XG4gICAgc3RhcnRWYWx1ZSA9IHRhcmdldC5zdHlsZVtwcm9wXTtcbiAgICB0YXJnZXQuc3R5bGVbcHJvcF0gPSBlbmQ7XG4gICAgZW5kID0gX2dldENvbXB1dGVkUHJvcGVydHkodGFyZ2V0LCBwcm9wKSB8fCBlbmQ7XG4gICAgc3RhcnRWYWx1ZSA/IHRhcmdldC5zdHlsZVtwcm9wXSA9IHN0YXJ0VmFsdWUgOiBfcmVtb3ZlUHJvcGVydHkodGFyZ2V0LCBwcm9wKTtcbiAgfVxuXG4gIGEgPSBbc3RhcnQsIGVuZF07XG5cbiAgX2NvbG9yU3RyaW5nRmlsdGVyKGEpOyAvLyBwYXNzIGFuIGFycmF5IHdpdGggdGhlIHN0YXJ0aW5nIGFuZCBlbmRpbmcgdmFsdWVzIGFuZCBsZXQgdGhlIGZpbHRlciBkbyB3aGF0ZXZlciBpdCBuZWVkcyB0byB0aGUgdmFsdWVzLiBJZiBjb2xvcnMgYXJlIGZvdW5kLCBpdCByZXR1cm5zIHRydWUgYW5kIHRoZW4gd2UgbXVzdCBtYXRjaCB3aGVyZSB0aGUgY29sb3Igc2hvd3MgdXAgb3JkZXItd2lzZSBiZWNhdXNlIGZvciB0aGluZ3MgbGlrZSBib3hTaGFkb3csIHNvbWV0aW1lcyB0aGUgYnJvd3NlciBwcm92aWRlcyB0aGUgY29tcHV0ZWQgdmFsdWVzIHdpdGggdGhlIGNvbG9yIEZJUlNULCBidXQgdGhlIHVzZXIgcHJvdmlkZXMgaXQgd2l0aCB0aGUgY29sb3IgTEFTVCwgc28gZmxpcCB0aGVtIGlmIG5lY2Vzc2FyeS4gU2FtZSBmb3IgZHJvcC1zaGFkb3coKS5cblxuXG4gIHN0YXJ0ID0gYVswXTtcbiAgZW5kID0gYVsxXTtcbiAgc3RhcnRWYWx1ZXMgPSBzdGFydC5tYXRjaChfbnVtV2l0aFVuaXRFeHApIHx8IFtdO1xuICBlbmRWYWx1ZXMgPSBlbmQubWF0Y2goX251bVdpdGhVbml0RXhwKSB8fCBbXTtcblxuICBpZiAoZW5kVmFsdWVzLmxlbmd0aCkge1xuICAgIHdoaWxlIChyZXN1bHQgPSBfbnVtV2l0aFVuaXRFeHAuZXhlYyhlbmQpKSB7XG4gICAgICBlbmRWYWx1ZSA9IHJlc3VsdFswXTtcbiAgICAgIGNodW5rID0gZW5kLnN1YnN0cmluZyhpbmRleCwgcmVzdWx0LmluZGV4KTtcblxuICAgICAgaWYgKGNvbG9yKSB7XG4gICAgICAgIGNvbG9yID0gKGNvbG9yICsgMSkgJSA1O1xuICAgICAgfSBlbHNlIGlmIChjaHVuay5zdWJzdHIoLTUpID09PSBcInJnYmEoXCIgfHwgY2h1bmsuc3Vic3RyKC01KSA9PT0gXCJoc2xhKFwiKSB7XG4gICAgICAgIGNvbG9yID0gMTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVuZFZhbHVlICE9PSAoc3RhcnRWYWx1ZSA9IHN0YXJ0VmFsdWVzW21hdGNoSW5kZXgrK10gfHwgXCJcIikpIHtcbiAgICAgICAgc3RhcnROdW0gPSBwYXJzZUZsb2F0KHN0YXJ0VmFsdWUpIHx8IDA7XG4gICAgICAgIHN0YXJ0VW5pdCA9IHN0YXJ0VmFsdWUuc3Vic3RyKChzdGFydE51bSArIFwiXCIpLmxlbmd0aCk7XG4gICAgICAgIGVuZFZhbHVlLmNoYXJBdCgxKSA9PT0gXCI9XCIgJiYgKGVuZFZhbHVlID0gX3BhcnNlUmVsYXRpdmUoc3RhcnROdW0sIG
1VuZFZhbHVlKSArIHN0YXJ0VW5pdCk7XG4gICAgICAgIGVuZE51bSA9IHBhcnNlRmxvYXQoZW5kVmFsdWUpO1xuICAgICAgICBlbmRVbml0ID0gZW5kVmFsdWUuc3Vic3RyKChlbmROdW0gKyBcIlwiKS5sZW5ndGgpO1xuICAgICAgICBpbmRleCA9IF9udW1XaXRoVW5pdEV4cC5sYXN0SW5kZXggLSBlbmRVbml0Lmxlbmd0aDtcblxuICAgICAgICBpZiAoIWVuZFVuaXQpIHtcbiAgICAgICAgICAvL2lmIHNvbWV0aGluZyBsaWtlIFwicGVyc3BlY3RpdmU6MzAwXCIgaXMgcGFzc2VkIGluIGFuZCB3ZSBtdXN0IGFkZCBhIHVuaXQgdG8gdGhlIGVuZFxuICAgICAgICAgIGVuZFVuaXQgPSBlbmRVbml0IHx8IF9jb25maWcudW5pdHNbcHJvcF0gfHwgc3RhcnRVbml0O1xuXG4gICAgICAgICAgaWYgKGluZGV4ID09PSBlbmQubGVuZ3RoKSB7XG4gICAgICAgICAgICBlbmQgKz0gZW5kVW5pdDtcbiAgICAgICAgICAgIHB0LmUgKz0gZW5kVW5pdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhcnRVbml0ICE9PSBlbmRVbml0KSB7XG4gICAgICAgICAgc3RhcnROdW0gPSBfY29udmVydFRvVW5pdCh0YXJnZXQsIHByb3AsIHN0YXJ0VmFsdWUsIGVuZFVuaXQpIHx8IDA7XG4gICAgICAgIH0gLy8gdGhlc2UgbmVzdGVkIFByb3BUd2VlbnMgYXJlIGhhbmRsZWQgaW4gYSBzcGVjaWFsIHdheSAtIHdlJ2xsIG5ldmVyIGFjdHVhbGx5IGNhbGwgYSByZW5kZXIgb3Igc2V0dGVyIG1ldGhvZCBvbiB0aGVtLiBXZSdsbCBqdXN0IGxvb3AgdGhyb3VnaCB0aGVtIGluIHRoZSBwYXJlbnQgY29tcGxleCBzdHJpbmcgUHJvcFR3ZWVuJ3MgcmVuZGVyIG1ldGhvZC5cblxuXG4gICAgICAgIHB0Ll9wdCA9IHtcbiAgICAgICAgICBfbmV4dDogcHQuX3B0LFxuICAgICAgICAgIHA6IGNodW5rIHx8IG1hdGNoSW5kZXggPT09IDEgPyBjaHVuayA6IFwiLFwiLFxuICAgICAgICAgIC8vbm90ZTogU1ZHIHNwZWMgYWxsb3dzIG9taXNzaW9uIG9mIGNvbW1hL3NwYWNlIHdoZW4gYSBuZWdhdGl2ZSBzaWduIGlzIHdlZGdlZCBiZXR3ZWVuIHR3byBudW1iZXJzLCBsaWtlIDIuNS01LjMgaW5zdGVhZCBvZiAyLjUsLTUuMyBidXQgd2hlbiB0d2VlbmluZywgdGhlIG5lZ2F0aXZlIHZhbHVlIG1heSBzd2l0Y2ggdG8gcG9zaXRpdmUsIHNvIHdlIGluc2VydCB0aGUgY29tbWEganVzdCBpbiBjYXNlLlxuICAgICAgICAgIHM6IHN0YXJ0TnVtLFxuICAgICAgICAgIGM6IGVuZE51bSAtIHN0YXJ0TnVtLFxuICAgICAgICAgIG06IGNvbG9yICYmIGNvbG9yIDwgNCB8fCBwcm9wID09PSBcInpJbmRleFwiID8gTWF0aC5yb3VuZCA6IDBcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwdC5jID0gaW5kZXggPCBlbmQubGVuZ3RoID8gZW5kLnN1YnN0cmluZyhpbmRleCwgZW5kLmxlbmd0aCkgOiBcIlwiOyAvL3dlIHVzZSB0aGUgXCJjXCIgb2YgdGhlIFByb3BUd2VlbiB0byBzdG9yZSB0aGUgZmluYWwgcGFydCBvZiB0aGUgc3RyaW5nIChhZnRlciB0aGUgbGFzdCBudW1iZXIpXG4gIH0gZWxzZSB7XG4gICAgcHQuciA9IHByb3AgPT09IFwiZGlzcGxheVwiICYmIGVuZCA9PT0gXCJub25lXCIgPyBfcmVuZGVyTm9uVHdlZW5pbmdWYWx1ZU9ubHlBdEVuZCA6IF9yZW5kZXJOb25Ud2VlbmluZ1ZhbHVlO1xuICB9XG5cbiAgX3JlbEV4cC50ZXN0KGVuZCkgJiYgKHB0LmUgPSAwKTsgLy9pZiB0aGUgZW5kIHN0cmluZyBjb250YWlucyByZWxhdGl2ZSB2YWx1ZXMgb3IgZHluYW1pYyByYW5kb20oLi4uKSB2YWx1ZXMsIGRlbGV0ZSB0aGUgZW5kIGl0IHNvIHRoYXQgb24gdGhlIGZpbmFsIHJlbmRlciB3ZSBkb24ndCBhY3R1YWxseSBzZXQgaXQgdG8gdGhlIHN0cmluZyB3aXRoICs9IG9yIC09IGNoYXJhY3RlcnMgKGZvcmNlcyBpdCB0byB1c2UgdGhlIGNhbGN1bGF0ZWQgdmFsdWUpLlxuXG4gIHRoaXMuX3B0ID0gcHQ7IC8vc3RhcnQgdGhlIGxpbmtlZCBsaXN0IHdpdGggdGhpcyBuZXcgUHJvcFR3ZWVuLiBSZW1lbWJlciwgd2UgY2FsbCBfdHdlZW5Db21wbGV4Q1NTU3RyaW5nLmNhbGwocGx1Z2luSW5zdGFuY2UuLi4pIHRvIGVuc3VyZSB0aGF0IGl0J3Mgc2NvcGVkIHByb3Blcmx5LiBXZSBtYXkgY2FsbCBpdCBmcm9tIHdpdGhpbiBhbm90aGVyIHBsdWdpbiB0b28sIHRodXMgXCJ0aGlzXCIgd291bGQgcmVmZXIgdG8gdGhlIHBsdWdpbi5cblxuICByZXR1cm4gcHQ7XG59LFxuICAgIF9rZXl3b3JkVG9QZXJjZW50ID0ge1xuICB0b3A6IFwiMCVcIixcbiAgYm90dG9tOiBcIjEwMCVcIixcbiAgbGVmdDogXCIwJVwiLFxuICByaWdodDogXCIxMDAlXCIsXG4gIGNlbnRlcjogXCI1MCVcIlxufSxcbiAgICBfY29udmVydEtleXdvcmRzVG9QZXJjZW50YWdlcyA9IGZ1bmN0aW9uIF9jb252ZXJ0S2V5d29yZHNUb1BlcmNlbnRhZ2VzKHZhbHVlKSB7XG4gIHZhciBzcGxpdCA9IHZhbHVlLnNwbGl0KFwiIFwiKSxcbiAgICAgIHggPSBzcGxpdFswXSxcbiAgICAgIHkgPSBzcGxpdFsxXSB8fCBcIjUwJVwiO1xuXG4gIGlmICh4ID09PSBcInRvcFwiIHx8IHggPT09IFwiYm90dG9tXCIgfHwgeSA9PT0gXCJsZWZ0XCIgfHwgeSA9PT0gXCJyaWdodFwiKSB7XG4gICAgLy90aGUgdXNlciBwcm92aWRlZCB0aGVtIGluIHRoZSB3cm9uZyBvcmRlciwgc28gZmxpcCB0aGVtXG4gICAgdmFsdWUgPSB4O1xuICAgIHggPSB5O1xuICAgIHkgPSB2YWx1ZTtcbiAgfVxuXG4gIHNwbGl0WzBdID0gX2tleXdvcmRUb1BlcmNlbnRbeF0gfHwgeDtcbiAgc3BsaXRbMV0gPSBfa2V5d29yZFRvUGVyY2VudFt5XSB8fCB5O1xuICByZXR1cm4gc3BsaXQuam9pbihcIiBcIik7XG59LFxuICAgIF9yZW5kZXJDbGVhclByb3BzID0gZnVuY3Rpb24gX3JlbmRlckNsZWFyUHJvcHMocmF0aW8sIGRhdGEpIHtcbiAgaWYgKGRhdGEudHdlZW4gJiYgZGF0YS50d2Vlbi5fdGltZSA9PT0gZGF0YS50d2Vlbi5fZHVyKSB7XG4gICAgdmFyIHRhcmdldCA9IGRhdGEudCxcbiAgICAgICAgc3R5bGUgPSB0YXJnZXQuc3R5bGUsXG4gICAgICAgIHByb3BzID0gZGF0YS51LFxuICAgICAgICBjYWNoZSA9IHRhcmdldC5fZ3NhcCxcbiAgICAgICAgcHJvcCxcbiAgICAgICAgY2xlYXJUcmFuc2Zvcm1zLFxuICAgICAgICBpO1xuXG4gICAgaWYgKHByb3BzID09PSBcImFsbFwiIHx8IHByb3BzID09PSB0cnVlKSB7XG4gICAgICBzdHlsZS5jc3NUZXh0ID0gXCJcIjtcbiAgICAgIGNsZWFyVHJhbnNmb3JtcyA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb3BzID0gcHJvcHMuc3BsaXQoXCIsXCIpO1xuICAgICAgaSA9IHByb3BzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKC0taSA+IC0xKSB7XG4gICAgICAgI
1HByb3AgPSBwcm9wc1tpXTtcblxuICAgICAgICBpZiAoX3RyYW5zZm9ybVByb3BzW3Byb3BdKSB7XG4gICAgICAgICAgY2xlYXJUcmFuc2Zvcm1zID0gMTtcbiAgICAgICAgICBwcm9wID0gcHJvcCA9PT0gXCJ0cmFuc2Zvcm1PcmlnaW5cIiA/IF90cmFuc2Zvcm1PcmlnaW5Qcm9wIDogX3RyYW5zZm9ybVByb3A7XG4gICAgICAgIH1cblxuICAgICAgICBfcmVtb3ZlUHJvcGVydHkodGFyZ2V0LCBwcm9wKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2xlYXJUcmFuc2Zvcm1zKSB7XG4gICAgICBfcmVtb3ZlUHJvcGVydHkodGFyZ2V0LCBfdHJhbnNmb3JtUHJvcCk7XG5cbiAgICAgIGlmIChjYWNoZSkge1xuICAgICAgICBjYWNoZS5zdmcgJiYgdGFyZ2V0LnJlbW92ZUF0dHJpYnV0ZShcInRyYW5zZm9ybVwiKTtcblxuICAgICAgICBfcGFyc2VUcmFuc2Zvcm0odGFyZ2V0LCAxKTsgLy8gZm9yY2UgYWxsIHRoZSBjYWNoZWQgdmFsdWVzIGJhY2sgdG8gXCJub3JtYWxcIi9pZGVudGl0eSwgb3RoZXJ3aXNlIGlmIHRoZXJlJ3MgYW5vdGhlciB0d2VlbiB0aGF0J3MgYWxyZWFkeSBzZXQgdG8gcmVuZGVyIHRyYW5zZm9ybXMgb24gdGhpcyBlbGVtZW50LCBpdCBjb3VsZCBkaXNwbGF5IHRoZSB3cm9uZyB2YWx1ZXMuXG5cblxuICAgICAgICBjYWNoZS51bmNhY2hlID0gMTtcblxuICAgICAgICBfcmVtb3ZlSW5kZXBlbmRlbnRUcmFuc2Zvcm1zKHN0eWxlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn0sXG4gICAgLy8gbm90ZTogc3BlY2lhbFByb3BzIHNob3VsZCByZXR1cm4gMSBpZiAoYW5kIG9ubHkgaWYpIHRoZXkgaGF2ZSBhIG5vbi16ZXJvIHByaW9yaXR5LiBJdCBpbmRpY2F0ZXMgd2UgbmVlZCB0byBzb3J0IHRoZSBsaW5rZWQgbGlzdC5cbl9zcGVjaWFsUHJvcHMgPSB7XG4gIGNsZWFyUHJvcHM6IGZ1bmN0aW9uIGNsZWFyUHJvcHMocGx1Z2luLCB0YXJnZXQsIHByb3BlcnR5LCBlbmRWYWx1ZSwgdHdlZW4pIHtcbiAgICBpZiAodHdlZW4uZGF0YSAhPT0gXCJpc0Zyb21TdGFydFwiKSB7XG4gICAgICB2Y
1XIgcHQgPSBwbHVnaW4uX3B0ID0gbmV3IFByb3BUd2VlbihwbHVnaW4uX3B0LCB0YXJnZXQsIHByb3BlcnR5LCAwLCAwLCBfcmVuZGVyQ2xlYXJQcm9wcyk7XG4gICAgICBwdC51ID0gZW5kVmFsdWU7XG4gICAgICBwdC5wciA9IC0xMDtcbiAgICAgIHB0LnR3ZWVuID0gdHdlZW47XG5cbiAgICAgIHBsdWdpbi5fcHJvcHMucHVzaChwcm9wZXJ0eSk7XG5cbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuICAvKiBjbGFzc05hbWUgZmVhdHVyZSAoYWJvdXQgMC40a2IgZ3ppcHBlZCkuXG4gICwgY2xhc3NOYW1lKHBsdWdpbiwgdGFyZ2V0LCBwcm9wZXJ0eSwgZW5kVmFsdWUsIHR3ZWVuKSB7XG4gIFx0bGV0IF9yZW5kZXJDbGFzc05hbWUgPSAocmF0aW8sIGRhdGEpID0+IHtcbiAgXHRcdFx0ZGF0YS5jc3MucmVuZGVyKHJhdGlvLCBkYXRhLmNzcyk7XG4gIFx0XHRcdGlmICghcmF0aW8gfHwgcmF0aW8gPT09IDEpIHtcbiAgXHRcdFx0XHRsZXQgaW5saW5lID0gZGF0YS5ybXYsXG4gIFx0XHRcdFx0XHR0YXJnZXQgPSBkYXRhLnQsXG4gIFx0XHRcdFx0XHRwO1xuICBcdFx0XHRcdHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCByYXRpbyA/IGRhdGEuZSA6IGRhdGEuYik7XG4gIFx0XHRcdFx0Zm9yIChwIGluIGlubGluZSkge1xuICBcdFx0XHRcdFx0X3JlbW92ZVByb3BlcnR5KHRhcmdldCwgcCk7XG4gIFx0XHRcdFx0fVxuICBcdFx0XHR9XG4gIFx0XHR9LFxuICBcdFx0X2dldEFsbFN0eWxlcyA9ICh0YXJnZXQpID0+IHtcbiAgXHRcdFx0bGV0IHN0eWxlcyA9IHt9LFxuICBcdFx0XHRcdGNvbXB1dGVkID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpLFxuICBcdFx0XHRcdHA7XG4gIFx0XHRcdGZvciAocCBpbiBjb21wdXRlZCkge1xuICBcdFx0XHRcdGlmIChpc05hTihwKSAmJiBwICE9PSBcImNzc1RleHRcIiAmJiBwICE9PSBcImxlbmd0aFwiKSB7XG4gIFx0XHRcdFx0XHRzdHlsZXNbcF0gPSBjb21wdXRlZFtwXTtcbiAgXHRcdFx0XHR9XG4gIFx0XHRcdH1cbiAgXHRcdFx0X3NldERlZmF1bHRzKHN0eWxlcywgX3BhcnNlVHJhbnNmb3JtKHRhcmdldCwgMSkpO1xuICBcdFx0XHRyZXR1cm4gc3R5bGVzO1xuICBcdFx0fSxcbiAgXHRcdHN0YXJ0Q2xhc3NMaXN0ID0gdGFyZ2V0LmdldEF0dHJpYnV0ZShcImNsYXNzXCIpLFxuICBcdFx0c3R5bGUgPSB0YXJnZXQuc3R5bGUsXG4gIFx0XHRjc3NUZXh0ID0gc3R5bGUuY3NzVGV4dCxcbiAgXHRcdGNhY2hlID0gdGFyZ2V0Ll9nc2FwLFxuICBcdFx0Y2xhc3NQVCA9IGNhY2hlLmNsYXNzUFQsXG4gIFx0XHRpbmxpbmVUb1JlbW92ZUF0RW5kID0ge30sXG4gIFx0XHRkYXRhID0ge3Q6dGFyZ2V0LCBwbHVnaW46cGx1Z2luLCBybXY6aW5saW5lVG9SZW1vdmVBdEVuZCwgYjpzdGFydENsYXNzTGlzdCwgZTooZW5kVmFsdWUuY2hhckF0KDEpICE9PSBcIj1cIikgPyBlbmRWYWx1ZSA6IHN0YXJ0Q2xhc3NMaXN0LnJlcGxhY2UobmV3IFJlZ0V4cChcIig/OlxcXFxzfF4pXCIgKyBlbmRWYWx1ZS5zdWJzdHIoMikgKyBcIig/IVtcXFxcdy1dKVwiKSwgXCJcIikgKyAoKGVuZFZhbHVlLmNoYXJBdCgwKSA9PT0gXCIrXCIpID8gXCIgXCIgKyBlbmRWYWx1ZS5zdWJzdHIoMikgOiBcIlwiKX0sXG4gIFx0XHRjaGFuZ2luZ1ZhcnMgPSB7fSxcbiAgXHRcdHN0YXJ0VmFycyA9IF9nZXRBbGxTdHlsZXModGFyZ2V0KSxcbiAgXHRcdHRyYW5zZm9ybVJlbGF0ZWQgPSAvKHRyYW5zZm9ybXxwZXJzcGVjdGl2ZSkvaSxcbiAgXHRcdGVuZFZhcnMsIHA7XG4gIFx0aWYgKGNsYXNzUFQpIHtcbiAgXHRcdGNsYXNzUFQucigxLCBjbGFzc1BULmQpO1xuICBcdFx0X3JlbW92ZUxpbmtlZExpc3RJdGVtKGNsYXNzUFQuZC5wbHVnaW4sIGNsYXNzUFQsIFwiX3B0XCIpO1xuICBcdH1cbiAgXHR0YXJnZXQuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgZGF0YS5lKTtcbiAgXHRlbmRWYXJzID0gX2dldEFsbFN0eWxlcyh0YXJnZXQsIHRydWUpO1xuICBcdHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBzdGFydENsYXNzTGlzdCk7XG4gIFx0Zm9yIChwIGluIGVuZFZhcnMpIHtcbiAgXHRcdGlmIChlbmRWYXJzW3BdICE9PSBzdGFydFZhcnNbcF0gJiYgIXRyYW5zZm9ybVJlbGF0ZWQudGVzdChwKSkge1xuICBcdFx0XHRjaGFuZ2luZ1ZhcnNbcF0gPSBlbmRWYXJzW3BdO1xuICBcdFx0XHRpZiAoIXN0eWxlW3BdICYmIHN0eWxlW3BdICE9PSBcIjBcIikge1xuICBcdFx0XHRcdGlubGluZVRvUmVtb3ZlQXRFbmRbcF0gPSAxO1xuICBcdFx0XHR9XG4gIFx0XHR9XG4gIFx0fVxuICBcdGNhY2hlLmNsYXNzUFQgPSBwbHVnaW4uX3B0ID0gbmV3IFByb3BUd2VlbihwbHVnaW4uX3B0LCB0YXJnZXQsIFwiY2xhc3NOYW1lXCIsIDAsIDAsIF9yZW5kZXJDbGFzc05hbWUsIGRhdGEsIDAsIC0xMSk7XG4gIFx0aWYgKHN0eWxlLmNzc1RleHQgIT09IGNzc1RleHQpIHsgLy9vbmx5IGFwcGx5IGlmIHRoaW5ncyBjaGFuZ2UuIE90aGVyd2lzZSwgaW4gY2FzZXMgbGlrZSBhIGJhY2tncm91bmQtaW1hZ2UgdGhhdCdzIHB1bGxlZCBkeW5hbWljYWxseSwgaXQgY291bGQgY2F1c2UgYSByZWZyZXNoLiBTZWUgaHR0cHM6Ly9nc2FwLmNvbS9mb3J1bXMvdG9waWMvMjAzNjgtcG9zc2libGUtZ3NhcC1idWctc3dpdGNoaW5nLWNsYXNzbmFtZXMtaW4tY2hyb21lLy5cbiAgXHRcdHN0eWxlLmNzc1RleHQgPSBjc3NUZXh0OyAvL3dlIHJlY29yZGVkIGNzc1RleHQgYmVmb3JlIHdlIHN3YXBwZWQgY2xhc3NlcyBhbmQgcmFuIF9nZXRBbGxTdHlsZXMoKSBiZWNhdXNlIGluIGNhc2VzIHdoZW4gYSBjbGFzc05hbWUgdHdlZW4gaXMgb3ZlcndyaXR0ZW4sIHdlIHJlbW92ZSBhbGwgdGhlIHJlbGF0ZWQgdHdlZW5pbmcgcHJvcGVydGllcyBmcm9tIHRoYXQgY2xhc3MgY2hhbmdlIChvdGhlcndpc2UgY2xhc3Mtc3BlY2lmaWMgc3R1ZmYgY2FuJ3Qgb3ZlcnJpZGUgcHJvcGVydGllcyB3ZSd2ZSBkaXJlY3RseSBzZXQgb24gdGhlIHRhcmdldCdzIHN0eWxlIG9iamVjdCBkdWUgdG8gc3BlY2lmaWNpdHkpLlxuICBcdH1cbiAgXHRfcGFyc2VUcmFuc2Zvcm0odGFyZ2V0LCB0cnVlKTsgLy90byBjbGVhciB0aGUgY2FjaGluZyBvZiB0cmFuc2Zvcm1zXG4gIFx0ZGF0YS5jc3MgPSBuZXcgZ3NhcC5wbHVnaW5zLm
1NzcygpO1xuICBcdGRhdGEuY3NzLmluaXQodGFyZ2V0LCBjaGFuZ2luZ1ZhcnMsIHR3ZWVuKTtcbiAgXHRwbHVnaW4uX3Byb3BzLnB1c2goLi4uZGF0YS5jc3MuX3Byb3BzKTtcbiAgXHRyZXR1cm4gMTtcbiAgfVxuICAqL1xuXG59LFxuXG4vKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIFRSQU5TRk9STVNcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cbl9pZGVudGl0eTJETWF0cml4ID0gWzEsIDAsIDAsIDEsIDAsIDBdLFxuICAgIF9yb3RhdGlvbmFsUHJvcGVydGllcyA9IHt9LFxuICAgIF9pc051bGxUcmFuc2Zvcm0gPSBmdW5jdGlvbiBfaXNOdWxsVHJhbnNmb3JtKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gXCJtYXRyaXgoMSwgMCwgMCwgMSwgMCwgMClcIiB8fCB2YWx1ZSA9PT0gXCJub25lXCIgfHwgIXZhbHVlO1xufSxcbiAgICBfZ2V0Q29tcHV0ZWRUcmFuc2Zvcm1NYXRyaXhBc0FycmF5ID0gZnVuY3Rpb24gX2dldENvbXB1dGVkVHJhbnNmb3JtTWF0cml4QXNBcnJheSh0YXJnZXQpIHtcbiAgdmFyIG1hdHJpeFN0cmluZyA9IF9nZXRDb21wdXRlZFByb3BlcnR5KHRhcmdldCwgX3RyYW5zZm9ybVByb3ApO1xuXG4gIHJldHVybiBfaXNOdWxsVHJhbnNmb3JtKG1hdHJpeFN0cmluZykgPyBfaWRlbnRpdHkyRE1hdHJpeCA6IG1hdHJpeFN0cmluZy5zdWJzdHIoNykubWF0Y2goX251bUV4cCkubWFwKF9yb3VuZCk7XG59LFxuICAgIF9nZXRNYXRyaXggPSBmdW5jdGlvbiBfZ2V0TWF0cml4KHRhcmdldCwgZm9yY2UyRCkge1xuICB2YXIgY2FjaGUgPSB0YXJnZXQuX2dzYXAgfHwgX2dldENhY2hlKHRhcmdldCksXG4gICAgICBzdHlsZSA9IHRhcmdldC5zdHlsZSxcbiAgICAgIG1hdHJpeCA9IF9nZXRDb21wdXRlZFRyYW5zZm9ybU1hdHJpeEFzQXJyYXkodGFyZ2V0KSxcbiAgICAgIHBhcmVudCxcbiAgICAgIG5leHRTaWJsaW5nLFxuICAgICAgdGVtcCxcbiAgICAgIGFkZGVkVG9ET007XG5cbiAgaWYgKGNhY2hlLnN2ZyAmJiB0YXJnZXQuZ2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIpKSB7XG4gICAgdGVtcCA9IHRhcmdldC50cmFuc2Zvcm0uYmFzZVZhbC5jb25zb2xpZGF0ZSgpLm1hdHJpeDsgLy9lbnN1cmVzIHRoYXQgZXZlbiBjb21wbGV4IHZhbHVlcyBsaWtlIFwidHJhbnNsYXRlKDUwLDYwKSByb3RhdGUoMTM1LDAsMClcIiBhcmUgcGFyc2VkIGJlY2F1c2UgaXQgbWFzaGVzIGl0IGludG8gYSBtYXRyaXguXG5cbiAgICBtYXRyaXggPSBbdGVtcC5hLCB0ZW1wLmIsIHRlbXAuYywgdGVtcC5kLCB0ZW1wLmUsIHRlbXAuZl07XG4gICAgcmV0dXJuIG1hdHJpeC5qb2luKFwiLFwiKSA9PT0gXCIxLDAsMCwxLDAsMFwiID8gX2lkZW50aXR5MkRNYXRyaXggOiBtYXRyaXg7XG4gIH0gZWxzZSBpZiAobWF0cml4ID09PSBfaWRlbnRpdHkyRE1hdHJpeCAmJiAhdGFyZ2V0Lm9mZnNldFBhcmVudCAmJiB0YXJnZXQgIT09IF9kb2NFbGVtZW50ICYmICFjYWNoZS5zdmcpIHtcbiAgICAvL25vdGU6IGlmIG9mZnNldFBhcmVudCBpcyBudWxsLCB0aGF0IG1lYW5zIHRoZSBlbGVtZW50IGlzbid0IGluIHRoZSBub3JtYWwgZG9jdW1lbnQgZmxvdywgbGlrZSBpZiBpdCBoYXMgZGlzcGxheTpub25lIG9yIG9uZSBvZiBpdHMgYW5jZXN0b3JzIGhhcyBkaXNwbGF5Om5vbmUpLiBGaXJlZm94IHJldHVybnMgbnVsbCBmb3IgZ2V0Q29tcHV0ZWRTdHlsZSgpIGlmIHRoZSBlbGVtZW50IGlzIGluIGFuIGlmcmFtZSB0aGF0IGhhcyBkaXNwbGF5Om5vbmUuIGh0dHBzOi8vYnVnemlsbGEubW96
1aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTU0ODM5N1xuICAgIC8vYnJvd3NlcnMgZG9uJ3QgcmVwb3J0IHRyYW5zZm9ybXMgYWNjdXJhdGVseSB1bmxlc3MgdGhlIGVsZW1lbnQgaXMgaW4gdGhlIERPTSBhbmQgaGFzIGEgZGlzcGxheSB2YWx1ZSB0aGF0J3Mgbm90IFwibm9uZVwiLiBGaXJlZm94IGFuZCBNaWNyb3NvZnQgYnJvd3NlcnMgaGF2ZSBhIHBhcnRpYWwgYnVnIHdoZXJlIHRoZXknbGwgcmVwb3J0IHRyYW5zZm9ybXMgZXZlbiBpZiBkaXNwbGF5Om5vbmUgQlVUIG5vdCBhbnkgcGVyY2VudGFnZS1iYXNlZCB2YWx1ZXMgbGlrZSB0cmFuc2xhdGUoLTUwJSwgOHB4KSB3aWxsIGJlIHJlcG9ydGVkIGFzIGlmIGl0J3MgdHJhbnNsYXRlKDAsIDhweCkuXG4gICAgdGVtcCA9IHN0eWxlLmRpc3BsYXk7XG4gICAgc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjtcbiAgICBwYXJlbnQgPSB0YXJnZXQucGFyZW50Tm9kZTtcblxuICAgIGlmICghcGFyZW50IHx8ICF0YXJnZXQub2Zmc2V0UGFyZW50KSB7XG4gICAgICAvLyBub3RlOiBpbiAzLjMuMCB3ZSBzd2l0Y2hlZCB0YXJnZXQub2Zmc2V0UGFyZW50IHRvIF9kb2MuYm9keS5jb250YWlucyh0YXJnZXQpIHRvIGF2b2lkIFtzb21ldGltZXMgdW5uZWNlc3NhcnldIE11dGF0aW9uT2JzZXJ2ZXIgY2FsbHMgYnV0IHRoYXQgd2Fzbid0IGFkZXF1YXRlIGJlY2F1c2UgdGhlcmUgYXJlIGVkZ2UgY2FzZXMgd2hlcmUgbmVzdGVkIHBvc2l0aW9uOiBmaXhlZCBlbGVtZW50cyBuZWVkIHRvIGdldCByZXBhcmVudGVkIHRvIGFjY3VyYXRlbHkgc2Vuc2UgdHJhbnNmb3Jtcy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ncmVlbnNvY2svR1NBUC9pc3N1ZXMvMzg4IGFuZCBodHRwczovL2dpdGh1Yi5jb20vZ3JlZW5zb2NrL0dTQVAvaXNzdWVzLzM3NVxuICAgICAgYWRkZWRUb0RPTSA9IDE7IC8vZmxhZ1xuXG4gICAgICBuZXh0U2libGluZyA9IHRhcmdldC5uZXh0RWxlbWVudFNpYmxpbmc7XG5cbiAgICAgIF9kb2NFbGVtZW50LmFwcGVuZENoaWxkKHRhcmdldCk7IC8vd2UgbXVzdCBhZGQgaXQgdG8gdGhlIERPTSBpbiBvcmRlciB0byBnZXQgdmFsdWVzIHByb3Blcmx5XG5cbiAgICB9XG5cbiAgICBtYXRyaXggPSBfZ2V0Q29tcHV0ZWRUcmFuc2Zvcm1NYXRyaXhBc0FycmF5KHRhcmdldCk7XG4gICAgdGVtcCA/IHN0eWxlLmRpc3BsYXkgPSB0
1ZW1wIDogX3JlbW92ZVByb3BlcnR5KHRhcmdldCwgXCJkaXNwbGF5XCIpO1xuXG4gICAgaWYgKGFkZGVkVG9ET00pIHtcbiAgICAgIG5leHRTaWJsaW5nID8gcGFyZW50Lmluc2VydEJlZm9yZSh0YXJnZXQsIG5leHRTaWJsaW5nKSA6IHBhcmVudCA/IHBhcmVudC5hcHBlbmRDaGlsZCh0YXJnZXQpIDogX2RvY0VsZW1lbnQucmVtb3ZlQ2hpbGQodGFyZ2V0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZm9yY2UyRCAmJiBtYXRyaXgubGVuZ3RoID4gNiA/IFttYXRyaXhbMF0sIG1hdHJpeFsxXSwgbWF0cml4WzRdLCBtYXRyaXhbNV0sIG1hdHJpeFsxMl0sIG1hdHJpeFsxM11dIDogbWF0cml4O1xufSxcbiAgICBfYXBwbHlTVkdPcmlnaW4gPSBmdW5jdGlvbiBfYXBwbHlTVkdPcmlnaW4odGFyZ2V0LCBvcmlnaW4sIG9yaWdpbklzQWJzb2x1dGUsIHNtb290aCwgbWF0cml4QXJyYXksIHBsdWdpblRvQWRkUHJvcFR3ZWVuc1RvKSB7XG4gIHZhciBjYWNoZSA9IHRhcmdldC5fZ3NhcCxcbiAgICAgIG1hdHJpeCA9IG1hdHJpeEFycmF5IHx8IF9nZXRNYXRyaXgodGFyZ2V0LCB0cnVlKSxcbiAgICAgIHhPcmlnaW5PbGQgPSBjYWNoZS54T3JpZ2luIHx8IDAsXG4gICAgICB5T3JpZ2luT2xkID0gY2FjaGUueU9yaWdpbiB8fCAwLFxuICAgICAgeE9mZnNldE9sZCA9IGNhY2hlLnhPZmZzZXQgfHwgMCxcbiAgICAgIHlPZmZzZXRPbGQgPSBjYWNoZS55T2Zmc2V0IHx8IDAsXG4gICAgICBhID0gbWF0cml4WzBdLFxuICAgICAgYiA9IG1hdHJpeFsxXSxcbiAgICAgIGMgPSBtYXRyaXhbMl0sXG4gICAgICBkID0gbWF0cml4WzNdLFxuICAgICAgdHggPSBtYXRyaXhbNF0sXG4gICAgICB0eSA9IG1hdHJpeFs1XSxcbiAgICAgIG9yaWdpblNwbGl0ID0gb3JpZ2luLnNwbGl0KFwiIFwiKSxcbiAgICAgIHhPcmlnaW4gPSBwYXJzZUZsb2F0KG9yaWdpblNwbGl0WzBdKSB8fCAwLFxuICAgICAgeU9yaWdpbiA9IHBhcnNlRmxvYXQob3JpZ2luU3BsaXRbMV0pIHx8IDAsXG4gICAgICBib3VuZHMsXG4gICAgICBkZXRlcm1pbmFudCxcbiAgICAgIHgsXG4gICAgICB5O1xuXG4gIGlmICghb3JpZ2luSXNBYnNvbHV0ZSkge1xuICAgIGJvdW5kcyA9IF9nZXRCQm94KHRhcmdldCk7XG4gICAgeE9yaWdpbiA9IGJvdW5kcy54ICsgKH5vcmlnaW5TcGxpdFswXS5pbmRleE9mKFwiJVwiKSA/IHhPcmlnaW4gLyAxMDAgKiBib3VuZHMud2lkdGggOiB4T3JpZ2luKTtcbiAgICB5T3JpZ2luID0gYm91bmRzLnkgKyAofihvcmlnaW5TcGxpdFsxXSB8fCBvcmlnaW5TcGxpdFswXSkuaW5kZXhPZihcIiVcIikgPyB5T3JpZ2luIC8gMTAwICogYm91bmRzLmhlaWdodCA6IHlPcmlnaW4pOyAvLyBpZiAoIShcInhPcmlnaW5cIiBpbiBjYWNoZSkgJiYgKHhPcmlnaW4gfHwgeU9yaWdpbikpIHsgLy8gYWRkZWQgaW4gMy4xMi4zLCByZXZlcnRlZCBpbiAzLjEyLjQ7IHJlcXVpcmVzIG1vcmUgZXhwbG9yYXRpb25cbiAgICAvLyBcdHhPcmlnaW4gLT0gYm91bmRzLng7XG4gICAgLy8gXHR5T3JpZ2luIC09IGJvdW5kcy55O1xuICAgIC8vIH1cbiAgfSBlbHNlIGlmIChtYXRyaXggIT09IF9pZGVudGl0eTJETWF0cml4ICYmIChkZXRlcm1pbmFudCA9IGEgKiBkIC0gYiAqIGMpKSB7XG4gICAgLy9pZiBpdCdzIHplcm8gKGxpa2UgaWYgc2NhbGVYIGFuZCBzY2FsZVkgYXJlIHplcm8pLCBza2lwIGl0IHRvIGF2b2lkIGVycm9ycyB3aXRoIGRpdmlkaW5nIGJ5IHplcm8uXG4gICAgeCA9IHhPcmlnaW4gKiAoZCAvIGRldGVybWluYW50KSArIHlPcmlnaW4gKiAoLWMgLyBkZXRlcm1pbmFudCkgKyAoYyAqIHR5IC0gZCAqIHR4KSAvIGRldGVybWluYW50O1xuICAgIHkgPSB4T3JpZ2luICogKC1iIC8gZGV0ZXJtaW5hbnQpICsgeU9yaWdpbiAqIChhIC8gZGV0ZXJtaW5hbnQpIC0gKGEgKiB0eSAtIGIgKiB0eCkgLyBkZXRlcm1pbmFudDtcbiAgICB4T3JpZ2luID0geDtcbiAgICB5T3JpZ2luID0geTsgLy8gdGhlb3J5OiB3ZSBvbmx5IGhhZCB0byBkbyB0aGlzIGZvciBzbW9vdGhpbmcgYW5kIGl0IGFzc3VtZXMgdGhhdCB0aGUgcHJldmlvdXMgb25lIHdhcyBub3Qgb3JpZ2luSXNBYnNvbHV0ZS5cbiAgfVxuXG4gIGlmIChzbW9vdGggfHwgc21vb3RoICE9PSBmYWxzZSAmJiBjYWNoZS5zbW9vdGgpIHtcbiAgICB0eCA9IHhPcmlnaW4gLSB4T3JpZ2luT2xkO1xuICAgIHR5ID0geU9yaWdpbiAtIHlPcmlnaW5PbGQ7XG4gICAgY2FjaGUueE9mZnNldCA9IHhPZmZzZXRPbGQgKyAodHggKiBhICsgdHkgKiBjKSAtIHR4O1xuICAgIGNhY2hlLnlPZmZzZXQgPSB5T2Zmc2V0T2xkICsgKHR4ICogYiArIHR5ICogZCkgLSB0eTtcbiAgfSBlbHNlIHtcbiAgICBjYWNoZS54T2Zmc2V0ID0gY2FjaGUueU9mZnNldCA9IDA7XG4gIH1cblxuICBjYWNoZS54T3JpZ2luID0geE9yaWdpbjtcbiAgY2FjaGUueU9yaWdpbiA9IHlPcmlnaW47XG4gIGNhY2hlLnNtb290aCA9ICEhc21vb3RoO1xuICBjYWNoZS5vcmlnaW4gPSBvcmlnaW47XG4gIGNhY2hlLm9yaWdpbklzQWJzb2x1dGUgPSAhIW9yaWdpbklzQWJzb2x1dGU7XG4gIHRhcmdldC5zdHlsZVtfdHJhbnNmb3JtT3JpZ2luUHJvcF0gPSBcIjBweCAwcHhcIjsgLy9vdGhlcndpc2UsIGlmIHNvbWVvbmUgc2V0cyAgYW4gb3JpZ2luIHZpYSBDU1MsIGl0IHdpbGwgbGlrZWx5IGludGVyZmVyZSB3aXRoIHRoZSBTVkcgdHJhbnNmb3JtIGF0dHJpYnV0ZSBvbmVzIChiZWNhdXNlIHJlbWVtYmVyLCB3ZSdyZSBiYWtpbmcgdGhlIG9yaWdpbiBpbnRvIHRoZSBtYXRyaXgoKSB2YWx1ZSkuXG5cbiAgaWYgKHBsdWdpblRvQWRkUHJvcFR3ZWVuc1RvKSB7XG4gICAgX2FkZE5vblR3ZWVuaW5nUFQocGx1Z2luVG9BZGRQcm9wVHdlZW5zVG8sIGNhY2hlLCBcInhPcmlnaW5cIiwgeE9yaWdpbk9sZCwgeE9yaWdpbik7XG5cbiAgICBfYWRkTm9uVHdlZW5pbmdQVChwbHVnaW5Ub0FkZFByb3BUd2VlbnNUbywgY2FjaGUsIFwieU9yaWdpblwiLCB5T3JpZ2luT2xkLCB5T3JpZ2luKTtcblxuICAgIF9hZGROb25Ud2VlbmluZ1BUKHBsdWdpblRvQWRkUHJvcFR3ZWVuc1RvLCBjYWNoZSwgXCJ4T2Zmc2V0XCIsIHhPZmZzZXRPbGQsIGNhY2hlLnhPZmZzZXQpO1xuXG4gICAgX2FkZE5vblR3ZWVuaW5nUFQocGx1Z2luVG9BZGRQcm9wVHdlZW5zVG8sIGNhY2hlLCBcInlPZmZzZXRcIiwgeU9mZnNldE9sZCwgY2FjaGUueU9mZnNldCk7XG4gIH1cblxuICB0YXJnZXQuc2V0QXR0cmlidXRlKFwiZGF0YS1zdmctb3JpZ2luXCIsIHhPcmlnaW4gKyBcIiBcIiArIHlPcmlnaW4pO1xufSxcbiAgICBfcGFyc2VUcmFuc2Zvcm0gPSBmdW5jdGlvbiBfcGFyc2VUcmFuc2Zvcm0odGFyZ2V0LCB1bmNhY2hlKSB7XG4gIHZhciBjYWNoZSA9IHRhcmdldC5fZ3NhcCB8fCBuZXcgR1NDYWNoZSh0YXJnZXQpO1xuXG4gIGlmIChcInhcIiBpbiBjYWNoZSAmJiAhdW5jYWNoZSAmJiAhY2FjaGUudW5jYWNoZSkge1xuICAgIHJldHVybi
1BjYWNoZTtcbiAgfVxuXG4gIHZhciBzdHlsZSA9IHRhcmdldC5zdHlsZSxcbiAgICAgIGludmVydGVkU2NhbGVYID0gY2FjaGUuc2NhbGVYIDwgMCxcbiAgICAgIHB4ID0gXCJweFwiLFxuICAgICAgZGVnID0gXCJkZWdcIixcbiAgICAgIGNzID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpLFxuICAgICAgb3JpZ2luID0gX2dldENvbXB1dGVkUHJvcGVydHkodGFyZ2V0LCBfdHJhbnNmb3JtT3JpZ2luUHJvcCkgfHwgXCIwXCIsXG4gICAgICB4LFxuICAgICAgeSxcbiAgICAgIHosXG4gICAgICBzY2FsZVgsXG4gICAgICBzY2FsZVksXG4gICAgICByb3RhdGlvbixcbiAgICAgIHJvdGF0aW9uWCxcbiAgICAgIHJvdGF0aW9uWSxcbiAgICAgIHNrZXdYLFxuICAgICAgc2tld1ksXG4gICAgICBwZXJzcGVjdGl2ZSxcbiAgICAgIHhPcmlnaW4sXG4gICAgICB5T3JpZ2luLFxuICAgICAgbWF0cml4LFxuICAgICAgYW5nbGUsXG4gICAgICBjb3MsXG4gICAgICBzaW4sXG4gICAgICBhLFxuICAgICAgYixcbiAgICAgIGMsXG4gICAgICBkLFxuICAgICAgYTEyLFxuICAgICAgYTIyLFxuICAgICAgdDEsXG4gICAgICB0MixcbiAgICAgIHQzLFxuICAgICAgYTEzLFxuICAgICAgYTIzLFxuICAgICAgYTMzLFxuICAgICAgYTQyLFxuICAgICAgYTQzLFxuICAgICAgYTMyO1xuICB4ID0geSA9IHogPSByb3RhdGlvbiA9IHJvdGF0aW9uWCA9IHJvdGF0aW9uWSA9IHNrZXdYID0gc2tld1kgPSBwZXJzcGVjdGl2ZSA9IDA7XG4gIHNjYWxlWCA9IHNjYWxlWSA9IDE7XG4gIGNhY2hlLnN2ZyA9ICEhKHRhcmdldC5nZXRDVE0gJiYgX2lzU1ZHKHRhcmdldCkpO1xuXG4gIGlmIChjcy50cmFuc2xhdGUpIHtcbiAgICAvLyBhY2NvbW1vZGF0ZSBpbmRlcGVuZGVudCB0cmFuc2Zvcm1zIGJ5IGNvbWJpbmluZyB0aGVtIGludG8gbm9ybWFsIG9uZXMuXG4gICAgaWYgKGNzLnRyYW5zbGF0ZSAhPT0gXCJub25lXCIgfHwgY3Muc2NhbGUgIT09IFwibm9uZVwiIHx8IGNzLnJvdGF0ZSAhPT0gXCJub25lXCIpIHtcbiAgICAgIHN0eWxlW190cmFuc2Zvcm1Qcm9wXSA9IChjcy50cmFuc2xhdGUgIT09IFwibm9uZVwiID8gXCJ0cmFuc2xhdGUzZChcIiArIChjcy50cmFuc2xhdGUgKyBcIiAwIDBcIikuc3BsaXQoXCIgXCIpLnNsaWNlKDAsIDMpLmpvaW4oXCIsIFwiKSArIFwiKSBcIiA6IFwiXCIpICsgKGNzLnJvdGF0ZSAhPT0gXCJub25lXCIgPyBcInJvdGF0ZShcIiArIGNzLnJvdGF0ZSArIFwiKSBcIiA6IFwiXCIpICsgKGNzLnNjYWxlICE9PSBcIm5vbmVcIiA/IFwic2NhbGUoXCIgKyBjcy5zY2FsZS5zcGxpdChcIiBcIikuam9pbihcIixcIikgKyBcIikgXCIgOiBcIlwiKSArIChjc1tfdHJhbnNmb3JtUHJvcF0gIT09IFwibm9uZVwiID8gY3NbX3RyYW5zZm9ybVByb3BdIDogXCJcIik7XG4gICAgfVxuXG4gICAgc3R5bGUuc2NhbGUgPSBzdHlsZS5yb3RhdGUgPSBzdHlsZS50cmFuc2xhdGUgPSBcIm5vbmVcIjtcbiAgfVxuXG4gIG1hdHJpeCA9IF9nZXRNYXRyaXgodGFyZ2V0LCBjYWNoZS5zdmcpO1xuXG4gIGlmIChjYWNoZS5zdmcpIHtcbiAgICBpZiAoY2FjaGUudW5jYWNoZSkge1xuICAgICAgLy8gaWYgY2FjaGUudW5jYWNoZSBpcyB0cnVlIChhbmQgbWF5YmUgaWYgb3JpZ2luIGlzIDAsMCksIHdlIG5lZWQgdG8gc2V0IGVsZW1lbnQuc3R5bGUudHJhbnNmb3JtT3JpZ2luID0gKGNhY2hlLnhPcmlnaW4gLSBiYm94LngpICsgXCJweCBcIiArIChjYWNoZS55T3JpZ2luIC0gYmJveC55KSArIFwicHhcIi4gUHJldmlvdXNseSB3ZSBsZXQgdGhlIGRhdGEtc3ZnLW9yaWdpbiBzdGF5IGluc3RlYWQsIGJ1dCB3aGVuIGludHJvZHVjaW5nIHJldmVydCgpLCBpdCBjb21wbGljYXRlZCB0aGluZ3MuXG4gICAgICB0MiA9IHRhcmdldC5nZXRCQm94KCk7XG4gICAgICBvcmlnaW4gPSBjYWNoZS54T3JpZ2luIC0gdDIueCArIFwicHggXCIgKyAoY2FjaGUueU9yaWdpbiAtIHQyLnkpICsgXCJweFwiO1xuICAgICAgdDEgPSBcIlwiO1xuICAgIH0gZWxzZSB7XG4gICAgICB0MSA9ICF1bmNhY2hlICYmIHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXN2Zy1vcmlnaW5cIik7IC8vICBSZW1lbWJlciwgdG8gd29yayBhcm91bmQgYnJvd3NlciBpbmNvbnNpc3RlbmNpZXMgd2UgYWx3YXlzIGZvcmNlIFNWRyBlbGVtZW50cycgdHJhbnNmb3JtT3JpZ2luIHRvIDAsMCBhbmQgb2Zmc2V0IHRoZSB0cmFuc2xhdGlvbiBhY2NvcmRpbmdseS5cbiAgICB9XG5cbiAgICBfYXBwbHlTVkdPcmlnaW4odGFyZ2V0LCB0MSB8fCBvcmlnaW4sICEhdDEgfHwgY2FjaGUub3JpZ2luSXNBYnNvbHV0ZSwgY2FjaGUuc21vb3RoICE9PSBmYWxzZSwgbWF0cml4KTtcbiAgfVxuXG4gIHhPcmlnaW4gPSBjYWNoZS54T3JpZ2luIHx8IDA7XG4gIHlPcmlnaW4gPSBjYWNoZS55T3JpZ2luIHx8IDA7XG5cbiAgaWYgKG1hdHJpeCAhPT0gX2lkZW50aXR5MkRNYXRyaXgpIHtcbiAgICBhID0gbWF0cml4WzBdOyAvL2ExMVxuXG4gICAgYiA9IG1hdHJpeFsxXTsgLy9hMjFcblxuICAgIGMgPSBtYXRyaXhbMl07IC8vYTMxXG5cbiAgICBkID0gbWF0cml4WzNdOyAvL2E0MVxuXG4gICAgeCA9IGExMiA9IG1hdHJpeFs0XTtcbiAgICB5ID0gYTIyID0gbWF0cml4WzVdOyAvLzJEIG1hdHJpeFxuXG4gICAgaWYgKG1hdHJpeC5sZW5ndGggPT09IDYpIHtcbiAgICAgIHNjYWxlWCA9IE1hdGguc3FydChhICogYSArIGIgKiBiKTtcbiAgICAgIHNjYWxlWSA9IE1hdGguc3FydChkICogZCArIGMgKiBjKTtcbiAgICAgIHJvdGF0aW9uID0gYSB8fCBiID8gX2F0YW4yKGIsIGEpICogX1JBRDJERUcgOiAwOyAvL25vdGU6IGlmIHNjYWxlWCBpcyAwLCB3ZSBjYW5ub3QgYWNjdXJhdGVseSBtZWFzdXJlIHJvdGF0aW9uLiBTYW1lIGZvciBza2V3WCB3aXRoIGEgc2NhbGVZIG9mIDAuIFRoZXJlZm9yZSwgd2UgZGVmYXVsdCB0byB0aGUgcHJldmlvdXNseSByZWNvcmRlZCB2YWx1ZSAob3IgemVybyBpZiB0aGF0IGRvZXNuJ3QgZXhpc3QpLlxuXG4gICAgICBza2V3WCA9IGMgfHwgZCA/IF9hdGFuMihjLCBkKSAqIF9SQUQyREVHICsgcm90YXRpb24gOiAwO1xuICAgICAgc2tld1ggJiYgKHNjYWxlWSAqPSBNYXRoLmFicyhNYXRoLmNvcyhza2V3WCAqIF9ERUcyUkFEKSkpO1xuXG4gICAgICBpZiAoY2FjaGUuc3ZnKSB7XG4gICAgICAgI
1HggLT0geE9yaWdpbiAtICh4T3JpZ2luICogYSArIHlPcmlnaW4gKiBjKTtcbiAgICAgICAgeSAtPSB5T3JpZ2luIC0gKHhPcmlnaW4gKiBiICsgeU9yaWdpbiAqIGQpO1xuICAgICAgfSAvLzNEIG1hdHJpeFxuXG4gICAgfSBlbHNlIHtcbiAgICAgIGEzMiA9IG1hdHJpeFs2XTtcbiAgICAgIGE0MiA9IG1hdHJpeFs3XTtcbiAgICAgIGExMyA9IG1hdHJpeFs4XTtcbiAgICAgIGEyMyA9IG1hdHJpeFs5XTtcbiAgICAgIGEzMyA9IG1hdHJpeFsxMF07XG4gICAgICBhNDMgPSBtYXRyaXhbMTFdO1xuICAgICAgeCA9IG1hdHJpeFsxMl07XG4gICAgICB5ID0gbWF0cml4WzEzXTtcbiAgICAgIHogPSBtYXRyaXhbMTRdO1xuICAgICAgYW5nbGUgPSBfYXRhbjIoYTMyLCBhMzMpO1xuICAgICAgcm90YXRpb25YID0gYW5nbGUgKiBfUkFEMkRFRzsgLy9yb3RhdGlvblhcblxuICAgICAgaWYgKGFuZ2xlKSB7XG4gICAgICAgIGNvcyA9IE1hdGguY29zKC1hbmdsZSk7XG4gICAgICAgIHNpbiA9IE1hdGguc2luKC1hbmdsZSk7XG4gICAgICAgIHQxID0gYTEyICogY29zICsgYTEzICogc2luO1xuICAgICAgICB0MiA9IGEyMiAqIGNvcyArIGEyMyAqIHNpbjtcbiAgICAgICAgdDMgPSBhMzIgKiBjb3MgKyBhMzMgKiBzaW47XG4gICAgICAgIGExMyA9IGExMiAqIC1zaW4gKyBhMTMgKiBjb3M7XG4gICAgICAgIGEyMyA9IGEyMiAqIC1zaW4gKyBhMjMgKiBjb3M7XG4gICAgICAgIGEzMyA9IGEzMiAqIC1zaW4gKyBhMzMgKiBjb3M7XG4gICAgICAgIGE0MyA9IGE0MiAqIC1zaW4gKyBhNDMgKiBjb3M7XG4gICAgICAgIGExMiA9IHQxO1xuICAgICAgICBhMjIgPSB0MjtcbiAgICAgICAgYTMyID0gdDM7XG4gICAgICB9IC8vcm90YXRpb25ZXG5cblxuICAgICAgYW5nbGUgPSBfYXRhbjIoLWMsIGEzMyk7XG4gICAgICByb3RhdGlvblkgPSBhbmdsZSAqIF9SQUQyREVHO1xuXG4gICAgICBpZiAoYW5nbGUpIHtcbiAgICAgICAgY29zID0gTWF0aC5jb3MoLWFuZ2xlKTtcbiAgICAgICAgc2luID0gTWF0aC5zaW4oLWFuZ2xlKTtcbiAgICAgICAgdDEgPSBhICogY29zIC0gYTEzICogc2luO1xuICAgICAgICB0MiA9IGIgKiBjb3MgLSBhMjMgKiBzaW47XG4gICAgICAgIHQzID0gYyAqIGNvcyAtIGEzMyAqIHNpbjtcbiAgICAgICAgYTQzID0gZCAqIHNpbiArIGE0MyAqIGNvcztcbiAgICAgICAgYSA9IHQxO1xuICAgICAgICBiID0gdDI7XG4gICAgICAgIGMgPSB0MztcbiAgICAgIH0gLy9yb3RhdGlvblpcblxuXG4gICAgICBhbmdsZSA9IF9hdGFuMihiLCBhKTtcbiAgICAgIHJvdGF0aW9uID0gYW5nbGUgKiBfUkFEMkRFRztcblxuICAgICAgaWYgKGFuZ2xlKSB7XG4gICAgICAgIGNvcyA9IE1hdGguY29zKGFuZ2xlKTtcbiAgICAgICAgc2luID0gTWF0aC5zaW4oYW5nbGUpO1xuICAgICAgICB0MSA9IGEgKiBjb3MgKyBiICogc2luO1xuICAgICAgICB0MiA9IGExMiAqIGNvcyArIGEyMiAqIHNpbjtcbiAgICAgICAgYiA9IGIgKiBjb3MgLSBhICogc2luO1xuICAgICAgICBhMjIgPSBhMjIgKiBjb3MgLSBhMTIgKiBzaW47XG4gICAgICAgIGEgPSB0MTtcbiAgICAgICAgYTEyID0gdDI7XG4gICAgICB9XG5cbiAgICAgIGlmIChyb3RhdGlvblggJiYgTWF0aC5hYnMocm90YXRpb25YKSArIE1hdGguYWJzKHJvdGF0aW9uKSA+IDM1OS45KSB7XG4gICAgICAgIC8vd2hlbiByb3RhdGlvblkgaXMgc2V0LCBpdCB3aWxsIG9mdGVuIGJlIHBhcnNlZCBhcyAxODAgZGVncmVlcyBkaWZmZXJlbnQgdGhhbiBpdCBzaG91bGQgYmUsIGFuZCByb3RhdGlvblggYW5kIHJvdGF0aW9uIGJvdGggYmVpbmcgMTgwIChpdCBsb29rcyB0aGUgc2FtZSksIHNvIHdlIGFkanVzdCBmb3IgdGhhdCBoZXJlLlxuICAgICAgICByb3RhdGlvblggPSByb3RhdGlvbiA9IDA7XG4gICAgICAgIHJvdGF0aW9uWSA9IDE4MCAtIHJvdGF0aW9uWTtcbiAgICAgIH1cblxuICAgICAgc2NhbGVYID0gX3JvdW5kKE1hdGguc3FydChhICogYSArIGIgKiBiICsgYyAqIGMpKTtcbiAgICAgIHNjYWxlWSA9IF9yb3VuZChNYXRoLnNxcnQoYTIyICogYTIyICsgYTMyICogYTMyKSk7XG4gICAgICBhbmdsZSA9IF9hdGFuMihhMTIsIGEyMik7XG4gICAgICBza2V3WCA9IE1hdGguYWJzKGFuZ2xlKSA+IDAuMDAwMiA/IGFuZ2xlICogX1JBRDJERUcgOiAwO1xuICAgICAgcGVyc3BlY3RpdmUgPSBhNDMgPyAxIC8gKGE0MyA8IDAgPyAtYTQzIDogYTQzKSA6IDA7XG4gICAgfVxuXG4gICAgaWYgKGNhY2hlLnN2Zykge1xuICAgICAgLy9zZW5zZSBpZiB0aGVyZSBhcmUgQ1NTIHRyYW5zZm9ybXMgYXBwbGllZCBvbiBhbiBTVkcgZWxlbWVudCBpbiB3aGljaCBjYXNlIHdlIG11c3Qgb3ZlcndyaXRlIHRoZW0gd2hlbiByZW5kZXJpbmcuIFRoZSB0cmFuc2Zvcm0gYXR0cmlidXRlIGlzIG1vcmUgcmVsaWFibGUgY3Jvc3MtYnJvd3NlciwgYnV0IHdlIGNhbid0IGp1c3QgcmVtb3ZlIHRoZSBDU1Mgb25lcyBiZWNhdXNlIHRoZXkgbWF5IGJlIGFwcGxpZWQgaW4gYSBDU1MgcnVsZSBzb21ld2hlcmUgKG5vdCBqdXN0IGlubGluZSkuXG4gICAgICB0MSA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIik7XG4gICAgICBjYWNoZS5mb3JjZUNTUyA9IHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJcIikgfHwgIV9pc051bGxUcmFuc2Zvcm0oX2dldENvbXB1dGVkUHJvcGVydHkodGFyZ2V0LCBfdHJhbnNmb3JtUHJvcCkpO1xuICAgICAgdDEgJiYgdGFyZ2V0LnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCB0MSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKE1hdGguYWJzKHNrZXdYKSA+IDkwICYmIE1hdGguYWJzKHNrZXdYKSA8IDI3MCkge1xuICAgIGlmIChpbnZlcnRlZFNjYWxlWCkge1xuICAgICAgc2NhbGVYICo9IC0xO1xuICAgICAgc2tld1ggKz0gcm90YXRpb24gPD0gMCA/IDE4MCA6IC0xODA7XG4gICAgICByb3RhdGlvbiArPSByb3RhdGlvbiA8PSAwID8gMTgwIDogLTE4MDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NhbGVZICo9IC0xO1xuICAgICAgc2tld1ggKz0gc2tld1ggPD0gMCA/IDE4MCA6IC0xODA7XG4gICAgfVxuICB9XG5cbiAgdW5jYWNoZSA9IHVuY2FjaGUgfHwgY2FjaGUudW5jYWNoZTtcbiAgY2FjaGUueCA9IHggLSAoKGNhY2hlLnhQZXJjZW50ID0geCAmJiAoIXVuY2FjaGUgJiYgY2FjaGUueFBlcmNlbnQgfHwgKE1hdGgucm91bmQodGFyZ2V0Lm9mZnNldFdpZHRoIC8gMikgPT09IE1hdGgucm91bmQoLXgpID8gLTUwIDogMCkpKSA/IHRhcmdldC5vZmZzZXRXaWR0aCAqIGNhY2hlLnhQZXJjZW50IC8gMTAwIDogMCkgKyBweDtcbiAgY2FjaGUueSA9IHkgLSAoKGNhY2hlLnlQZXJjZW50ID0geSAmJiAoIXVuY2FjaGUgJiYgY2FjaGUueVBlcmNlbnQgfHwgKE1hdGgucm91bmQodGFyZ2V0Lm9mZnNldEhlaWdodCAvID
1IpID09PSBNYXRoLnJvdW5kKC15KSA/IC01MCA6IDApKSkgPyB0YXJnZXQub2Zmc2V0SGVpZ2h0ICogY2FjaGUueVBlcmNlbnQgLyAxMDAgOiAwKSArIHB4O1xuICBjYWNoZS56ID0geiArIHB4O1xuICBjYWNoZS5zY2FsZVggPSBfcm91bmQoc2NhbGVYKTtcbiAgY2FjaGUuc2NhbGVZID0gX3JvdW5kKHNjYWxlWSk7XG4gIGNhY2hlLnJvdGF0aW9uID0gX3JvdW5kKHJvdGF0aW9uKSArIGRlZztcbiAgY2FjaGUucm90YXRpb25YID0gX3JvdW5kKHJvdGF0aW9uWCkgKyBkZWc7XG4gIGNhY2hlLnJvdGF0aW9uWSA9IF9yb3VuZChyb3RhdGlvblkpICsgZGVnO1xuICBjYWNoZS5za2V3WCA9IHNrZXdYICsgZGVnO1xuICBjYWNoZS5za2V3WSA9IHNrZXdZICsgZGVnO1xuICBjYWNoZS50cmFuc2Zvcm1QZXJzcGVjdGl2ZSA9IHBlcnNwZWN0aXZlICsgcHg7XG5cbiAgaWYgKGNhY2hlLnpPcmlnaW4gPSBwYXJzZUZsb2F0KG9yaWdpbi5zcGxpdChcIiBcIilbMl0pIHx8ICF1bmNhY2hlICYmIGNhY2hlLnpPcmlnaW4gfHwgMCkge1xuICAgIHN0eWxlW190cmFuc2Zvcm1PcmlnaW5Qcm9wXSA9IF9maXJzdFR3b09ubHkob3JpZ2luKTtcbiAgfVxuXG4gIGNhY2hlLnhPZmZzZXQgPSBjYWNoZS55T2Zmc2V0ID0gMDtcbiAgY2FjaGUuZm9yY2UzRCA9IF9jb25maWcuZm9yY2UzRDtcbiAgY2FjaGUucmVuZGVyVHJhbnNmb3JtID0gY2FjaGUuc3ZnID8gX3JlbmRlclNWR1RyYW5zZm9ybXMgOiBfc3VwcG9ydHMzRCA/IF9yZW5kZXJDU1NUcmFuc2Zvcm1zIDogX3JlbmRlck5vbjNEVHJhbnNmb3JtcztcbiAgY2FjaGUudW5jYWNoZSA9IDA7XG4gIHJldHVybiBjYWNoZTtcbn0sXG4gICAgX2ZpcnN0VHdvT25seSA9IGZ1bmN0aW9uIF9maXJzdFR3b09ubHkodmFsdWUpIHtcbiAgcmV0dXJuICh2YWx1ZSA9IHZhbHVlLnNwbGl0KFwiIFwiKSlbMF0gKyBcIiBcIiArIHZhbHVlWzFdO1xufSxcbiAgICAvL2ZvciBoYW5kbGluZyB0cmFuc2Zvcm1PcmlnaW4gdmFsdWVzLCBzdHJpcHBpbmcgb3V0IHRoZSAzcmQgZGltZW5zaW9uXG5fYWRkUHhUcmFuc2xhdGUgPSBmdW5jdGlvbiBfYWRkUHhUcmFuc2xhdGUodGFyZ2V0LCBzdGFydCwgdmFsdWUpIHtcbiAgdmFyIHVuaXQgPSBnZXRVbml0KHN0YXJ0KTtcbiAgcmV0dXJuIF9yb3VuZChwYXJzZUZsb2F0KHN0YXJ0KSArIHBhcnNlRmxvYXQoX2NvbnZlcnRUb1VuaXQodGFyZ2V0LCBcInhcIiwgdmFsdWUgKyBcInB4XCIsIHVuaXQpKSkgKyB1bml0O1xufSxcbiAgICBfcmVuZGVyTm9uM0RUcmFuc2Zvcm1zID0gZnVuY3Rpb24gX3JlbmRlck5vbjNEVHJhbnNmb3JtcyhyYXRpbywgY2FjaGUpIHtcbiAgY2FjaGUueiA9IFwiMHB4XCI7XG4gIGNhY2hlLnJvdGF0aW9uWSA9IGNhY2hlLnJvdGF0aW9uWCA9IFwiMGRlZ1wiO1xuICBjYWNoZS5mb3JjZTNEID0gMDtcblxuICBfcmVuZGVyQ1NTVHJhbnNmb3JtcyhyYXRpbywgY2FjaGUpO1xufSxcbiAgICBfemVyb0RlZyA9IFwiMGRlZ1wiLFxuICAgIF96ZXJvUHggPSBcIjBweFwiLFxuICAgIF9lbmRQYXJlbnRoZXNpcyA9IFwiKSBcIixcbiAgICBfcmVuZGVyQ1NTVHJhbnNmb3JtcyA9IGZ1bmN0aW9uIF9yZW5kZXJDU1NUcmFuc2Zvcm1zKHJhdGlvLCBjYWNoZSkge1xuICB2YXIgX3JlZiA9IGNhY2hlIHx8IHRoaXMsXG4gICAgICB4UGVyY2VudCA9IF9yZWYueFBlcmNlbnQsXG4gICAgICB5UGVyY2VudCA9IF9yZWYueVBlcmNlbnQsXG4gICAgICB4ID0gX3JlZi54LFxuICAgICAgeSA9IF9yZWYueSxcbiAgICAgIHogPSBfcmVmLnosXG4gICAgICByb3RhdGlvbiA9IF9yZWYucm90YXRpb24sXG4gICAgICByb3RhdGlvblkgPSBfcmVmLnJvdGF0aW9uWSxcbiAgICAgIHJvdGF0aW9uWCA9IF9yZWYucm90YXRpb25YLFxuICAgICAgc2tld1ggPSBfcmVmLnNrZXdYLFxuICAgICAgc2tld1kgPSBfcmVmLnNrZXdZLFxuICAgICAgc2NhbGVYID0gX3JlZi5zY2FsZVgsXG4gICAgICBzY2FsZVkgPSBfcmVmLnNjYWxlWSxcbiAgICAgIHRyYW5zZm9ybVBlcnNwZWN0aXZlID0gX3JlZi50cmFuc2Zvcm1QZXJzcGVjdGl2ZSxcbiAgICAgIGZvcmNlM0QgPSBfcmVmLmZvcmNlM0QsXG4gICAgICB0YXJnZXQgPSBfcmVmLnRhcmdldCxcbiAgICAgIHpPcmlnaW4gPSBfcmVmLnpPcmlnaW4sXG4gICAgICB0cmFuc2Zvcm1zID0gXCJcIixcbiAgICAgIHVzZTNEID0gZm9yY2UzRCA9PT0gXCJhdXRvXCIgJiYgcmF0aW8gJiYgcmF0aW8gIT09IDEgfHwgZm9yY2UzRCA9PT0gdHJ1ZTsgLy8gU2FmYXJpIGhhcyBhIGJ1ZyB0aGF0IGNhdXNlcyBpdCBub3QgdG8gcmVuZGVyIDNEIHRyYW5zZm9ybS1vcmlnaW4gdmFsdWVzIHByb3Blcmx5LCBzbyB3ZSBmb3JjZSB0aGUgeiBvcmlnaW4gdG8gMCwgcmVjb3JkIGl0IGluIHRoZSBjYWNoZSwgYW5kIHRoZW4gZG8gdGhlIG1hdGggaGVyZSB0byBvZmZzZXQgdGhlIHRyYW5zbGF0ZSB2YWx1ZXMgYWNjb3JkaW5nbHkgKGJhc2ljYWxseSBkbyB0aGUgM0QgdHJhbnNmb3JtLW9yaWdpbiBwYXJ0IG1hbnVhbGx5KVxuXG5cbiAgaWYgKHpPcmlnaW4gJiYgKHJvdGF0aW9uWCAhPT0gX3plcm9EZWcgfHwgcm90YXRpb25ZICE9PSBfemVyb0RlZykpIHtcbiAgICB2YXIgYW5nbGUgPSBwYXJzZUZsb2F0KHJvdGF0aW9uWSkgKiBfREVHMlJBRCxcbiAgICAgICAgYTEzID0gTWF0aC5zaW4oYW5nbGUpLFxuICAgICAgICBhMzMgPSBNYXRoLmNvcyhhbmdsZSksXG4gICAgICAgIGNvcztcblxuICAgIGFuZ2xlID0gcGFyc2VGbG9hdChyb3RhdGlvblgpICogX0RFRzJSQUQ7XG4gICAgY29zID0gTWF0aC5jb3MoYW5nbGUpO1xuICAgIHggPSBfYWRkUHhUcmFuc2xhdGUodGFyZ2V0LCB4LCBhMTMgKiBjb3MgKiAtek9yaWdpbik7XG4gICAgeSA9IF9hZGRQeFRyYW5zbGF0ZSh0YXJnZXQsIHksIC1NYXRoLnNpbihhbmdsZSkgKiAtek9yaWdpbik7XG4gICAgeiA9IF9hZGRQeFRyYW5zbGF0ZSh0YXJnZXQsIHosIGEzMyAqIGNvcyAqIC16T3JpZ2luICsgek9yaWdpbik7XG4gIH1cblxuICBpZiAodHJhbnNmb3JtUGVyc3BlY3RpdmUgIT09IF96ZXJvUHgpIHtcbiAgICB0cmFuc2Zvcm1zICs9IFwicGVyc3BlY3RpdmUoXCIgKyB0cmFuc2Zvcm1QZXJzcGVjdGl2ZSArIF9lbmRQYXJlbnRoZXNpcztcbiAgfVxuXG4gIGlmICh4UGVyY2VudCB8fCB5UGVyY2VudCkge1xuICAgIHRyYW5zZm9ybXMgKz0gXCJ0cmFuc2xhdGUoXCIgKyB4UGVyY2VudCArIFwiJSwgXCIgKyB5UGVyY2VudCArIFwiJSkgXCI7XG4gIH1cblxuICBpZiAodXNlM0QgfHwgeCAhPT0gX3plcm9QeCB8fCB5ICE9PSBfemVyb1B4IHx8IHogIT09IF96ZXJvUHgpIHtcbiAgICB0cmFuc2Zvcm1zICs9IHogIT09IF96ZXJvUHggfHwgdXNlM0QgPyBcInRyYW5zbGF0ZTNkKFwiICsgeCArIFwiLCBcIiArIHkgKyBcIiwgXCIgKyB6ICsgXCIpIFwiIDogXCJ0cmFuc2xhdGUoXCIgKyB4ICsgXCIsIFwiICsgeSArIF9lbmRQYXJlbnRoZXNpcztcbiAgfVxuXG4gIGlmIChyb3RhdGlvbiAhPT0gX3plcm9EZWcpIHtcbiAgICB0cmFuc2Zvcm1zICs9IFwicm90YXRlKFwiICsgcm90YXRpb24gKyBfZW5kUGFyZW50aGVzaXM7XG4gIH1cblxuICBpZiAocm90YXRpb25ZICE9PSBfemVyb0RlZykge1xuICAgIHRyYW5zZm9ybXMgKz0gXCJyb3RhdGVZKFwiICsgcm90YXRpb25ZICsgX2VuZFBhcmVudGhlc2lzO1xuICB9XG5cbiAgaWYgKHJvdGF0aW9uWCAhPT0gX3plcm9EZWcpIHtcbiAgICB0cmFuc2Zvcm1zICs9IFwicm90YXRlWChcIiArIHJvdGF0aW9uWCArIF9lbmRQYXJlbnRoZXNpcztcbiAgfVxuXG4gIGlmIChza2V3WCAhPT0gX3plcm9EZWcgfHwgc2tld1kgIT09IF96ZXJvRGVnKSB7XG4gICAgdHJhbnNmb3JtcyArPSBcInNrZXcoXCIgKyBza2V3WCArIFwiLCBcIiArIHNrZXdZICsgX2VuZFBhcmVudGhlc2lzO1xuICB9XG5cbiAgaWYgKHNjYWxlWCAhPT0gMSB8fCBzY2FsZVkgIT09IDEpIHtcbiAgICB0cmFuc2Zvcm1zICs9IFwic2NhbGUoXCIgKyBzY2FsZVggKyBcIiwgXCIgKyBzY2FsZVkgKyBfZW5kUGFyZW50aGVzaXM7XG4gIH1cblxuICB0YXJnZXQuc3R5bGVbX3RyYW5zZm9ybVByb3BdID0gdHJhbnNmb3JtcyB8fCBcInRyYW5zbGF0ZSgwLCAwKVwiO1xufSxcbiAgICBfcmVuZGVyU1ZHVHJhbnNmb3JtcyA9IGZ1bmN0aW9uIF9yZW5kZXJTVkdUcmFuc2Zvcm1zKHJhdGlvLCBjYWNoZSkge1xuICB2YXIgX3JlZjIgPSBjYWNoZSB8fCB0aGlzLFxuICAgICAgeFBlcmNlbnQgPSBfcmVmMi54UGVyY2VudCxcbiAgICAgIHlQZXJjZW50ID0gX3JlZjIueVBlcmNlbnQsXG4gICAgICB4ID0gX3JlZjIueCxcbiAgICAgIHkgPSBfcmVmMi55LFxuICAgICAgcm90YXRpb24gPSBfcmVmMi5yb3RhdGlvbixcbiAgICAgIHNrZXdYID0gX3JlZjIuc2tld1gsXG4gICAgICBza2V3WSA9IF9yZWYyLnNrZXdZLFxuICAgICAgc2NhbGVYID0gX3JlZjIuc2NhbGVYLFxuICAgICAgc2NhbGVZID0gX3JlZjIuc2NhbGVZLFxuICAgICAgdGFyZ2V0ID0gX3JlZjIudGFyZ2V0LFxuICAgICAgeE9yaWdpbiA9IF9yZWYyLnhPcmlnaW4sXG4gICAgICB5T3Jp
1Z2luID0gX3JlZjIueU9yaWdpbixcbiAgICAgIHhPZmZzZXQgPSBfcmVmMi54T2Zmc2V0LFxuICAgICAgeU9mZnNldCA9IF9yZWYyLnlPZmZzZXQsXG4gICAgICBmb3JjZUNTUyA9IF9yZWYyLmZvcmNlQ1NTLFxuICAgICAgdHggPSBwYXJzZUZsb2F0KHgpLFxuICAgICAgdHkgPSBwYXJzZUZsb2F0KHkpLFxuICAgICAgYTExLFxuICAgICAgYTIxLFxuICAgICAgYTEyLFxuICAgICAgYTIyLFxuICAgICAgdGVtcDtcblxuICByb3RhdGlvbiA9IHBhcnNlRmxvYXQocm90YXRpb24pO1xuICBza2V3WCA9IHBhcnNlRmxvYXQoc2tld1gpO1xuICBza2V3WSA9IHBhcnNlRmxvYXQoc2tld1kpO1xuXG4gIGlmIChza2V3WSkge1xuICAgIC8vZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMsIHdlIGNvbWJpbmUgYWxsIHNrZXdpbmcgaW50byB0aGUgc2tld1ggYW5kIHJvdGF0aW9uIHZhbHVlcy4gUmVtZW1iZXIsIGEgc2tld1kgb2YgMTAgZGVncmVlcyBsb29rcyB0aGUgc2FtZSBhcyBhIHJvdGF0aW9uIG9mIDEwIGRlZ3JlZXMgcGx1cyBhIHNrZXdYIG9mIDEwIGRlZ3JlZXMuXG4gICAgc2tld1kgPSBwYXJzZUZsb2F0KHNrZXdZKTtcbiAgICBza2V3WCArPSBza2V3WTtcbiAgICByb3RhdGlvbiArPSBza2V3WTtcbiAgfVxuXG4gIGlmIChyb3RhdGlvbiB8fCBza2V3WCkge1xuICAgIHJvdGF0aW9uICo9IF9ERUcyUkFEO1xuICAgIHNrZXdYICo9IF9ERUcyUkFEO1xuICAgIGExMSA9IE1hdGguY29zKHJvdGF0aW9uKSAqIHNjYWxlWDtcbiAgICBhMjEgPSBNYXRoLnNpbihyb3RhdGlvbikgKiBzY2FsZVg7XG4gICAgYTEyID0gTWF0aC5zaW4ocm90YXRpb24gLSBza2V3WCkgKiAtc2NhbGVZO1xuICAgIGEyMiA9IE1hdGguY29zKHJvdGF0aW9uIC0gc2tld1gpICogc2NhbGVZO1xuXG4gICAgaWYgKHNrZXdYKSB7XG4gICAgICBza2V3WSAqPSBfREVHMlJBRDtcbiAgICAgIHRlbXAgPSBNYXRoLnRhbihza2V3WCAtIHNrZXdZKTtcbiAgICAgIHRlbXAgPSBNYXRoLnNxcnQoMSArIHRlbXAgKiB0ZW1wKTtcbiAgICAgIGExMiAqPSB0ZW1wO1xuICAgICAgYTIyICo9IHRlbXA7XG5cbiAgICAgIGlmIChza2V3WSkge1xuICAgICAgICB0ZW1wID0gTWF0aC50YW4oc2tld1kpO1xuICAgICAgICB0ZW1wID0gTWF0aC5zcXJ0KDEgKyB0ZW1wICogdGVtcCk7XG4gICAgICAgIGExMSAqPSB0ZW1wO1xuICAgICAgICBhMjEgKj0gdGVtcDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhMTEgPSBfcm91bmQoYTExKTtcbiAgICBhMjEgPSBfcm91bmQoYTIxKTtcbiAgICBhMTIgPSBfcm91bmQoYTEyKTtcbiAgICBhMjIgPSBfcm91bmQoYTIyKTtcbiAgfSBlbHNlIHtcbiAgICBhMTEgPSBzY2FsZVg7XG4gICAgYTIyID0gc2NhbGVZO1xuICAgIGEyMSA9IGExMiA9IDA7XG4gIH1cblxuICBpZiAodHggJiYgIX4oeCArIFwiXCIpLmluZGV4T2YoXCJweFwiKSB8fCB0eSAmJiAhfih5ICsgXCJcIikuaW5kZXhPZihcInB4XCIpKSB7XG4gICAgdHggPSBfY29udmVydFRvVW5pdCh0YXJnZXQsIFwieFwiLCB4LCBcInB4XCIpO1xuICAgIHR5ID0gX2NvbnZlcnRUb1VuaXQodGFyZ2V0LCBcInlcIiwgeSwgXCJweFwiKTtcbiAgfVxuXG4gIGlmICh4T3JpZ2luIHx8IHlPcmlnaW4gfHwgeE9mZnNldCB8fCB5T2Zmc2V0KSB7XG4gICAgdHggPSBfcm91bmQodHggKyB4T3JpZ2luIC0gKHhPcmlnaW4gKiBhMTEgKyB5T3JpZ2luICogYTEyKSArIHhPZmZzZXQpO1xuICAgIHR5ID0gX3JvdW5kKHR5ICsgeU9yaWdpbiAtICh4T3JpZ2luICogYTIxICsgeU9yaWdpbiAqIGEyMikgKyB5T2Zmc2V0KTtcbiAgfVxuXG4gIGlmICh4UGVyY2VudCB8fCB5UGVyY2VudCkge1xuICAgIC8vVGhlIFNWRyBzcGVjIGRvZXNuJ3Qgc3VwcG9ydCBwZXJjZW50YWdlLWJhc2VkIHRyYW5zbGF0aW9uIGluIHRoZSBcInRyYW5zZm9ybVwiIGF0dHJpYnV0ZSwgc28gd2UgbWVyZ2UgaXQgaW50byB0aGUgdHJhbnNsYXRpb24gdG8gc2ltdWxhdGUgaXQuXG4gICAgdGVtcCA9IHRhcmdldC5nZXRCQm94KCk7XG4gICAgdHggPSBfcm91bmQodHggKyB4UGVyY2VudCAvIDEwMCAqIHRlbXAud2lkdGgpO1xuICAgIHR5ID0gX3JvdW5kKHR5ICsgeVBlcmNlbnQgLyAxMDAgKiB0ZW1wLmhlaWdodCk7XG4gIH1cblxuICB0ZW1wID0gXCJtYXRyaXgoXCIgKyBhMTEgKyBcIixcIiArIGEyMSArIFwiLFwiICsgYTEyICsgXCIsXCIgKyBhMjIgKyBcIixcIiArIHR4ICsgXCIsXCIgKyB0eSArIFwiKVwiO1xuICB0YXJnZXQuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIHRlbXApO1xuICBmb3JjZUNTUyAmJiAodGFyZ2V0LnN0eWxlW190cmFuc2Zvcm1Qcm9wXSA9IHRlbXApOyAvL3NvbWUgYnJvd3NlcnMgcHJpb3JpdGl6ZSBDU1MgdHJhbnNmb3JtcyBvdmVyIHRoZSB0cmFuc2Zvcm0gYXR0cmlidXRlLiBXaGVuIHdlIHNlbnNlIHRoYXQgdGhlIHVzZXIgaGFzIENTUyB0cmFuc2Zvcm1zIGFwcGxpZWQsIHdlIG11c3Qgb3ZlcndyaXRlIHRoZW0gdGhpcyB3YXkgKG90aGVyd2lzZSBzb21lIGJyb3dzZXIgc2ltcGx5IHdvbid0IHJlbmRlciB0aGUgdHJhbnNmb3JtIGF0dHJpYnV0ZSBjaGFuZ2VzISlcbn0sXG4gICAgX2FkZFJvdGF0aW9uYWxQcm9wVHdlZW4gPSBmdW5jdGlvbiBfYWRkUm90YXRpb25hbFByb3BUd2VlbihwbHVnaW4sIHRhcmdldCwgcHJvcGVydHksIHN0YXJ0TnVtLCBlbmRWYWx1ZSkge1xuICB2YXIgY2FwID0gMzYwLFxuICAgICAgaXNTdHJpbmcgPSBfaXNTdHJpbmcoZW5kVmFsdWUpLFxuICAgICAgZW5kTnVtID0gcGFyc2VGbG9hdChlbmRWYWx1ZSkgKiAoaXNTdHJpbmcgJiYgfmVuZFZhbHVlLmluZGV4T2YoXCJyYWRcIikgPyBfUkFEMkRFRyA6IDEpLFxuICAgICAgY2hhbmdlID0gZW5kTnVtIC0gc3RhcnROdW0sXG4gICAgICBmaW5hbFZhbHVlID0gc3RhcnROdW0gKyBjaGFuZ2UgKyBcImRlZ1wiLFxuICAgICAgZGlyZWN0aW9uLFxuICAgICAgcHQ7XG5cbiAgaWYgKGlzU3RyaW5nKSB7XG4gICAgZGlyZWN0aW9uID0gZW5kVmFsdWUuc3BsaXQoXCJfXCIpWzFdO1xuXG4gICAgaWYgKGRpcmVjdGlvbiA9PT0gXCJzaG9ydFwiKSB7XG4gICAgICBjaGFuZ2UgJT0gY2FwO1xuXG4gICAgICBpZiAoY2hhbmdlICE9PSBjaGFuZ2UgJSAoY2FwIC8gMikpIHtcbiAgICAgICAgY2hhbmdlICs9IGNoYW5nZSA8IDAgPyBjYXAgOiAtY2FwO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkaXJlY3Rpb24gPT09IFwiY3dcIiAmJiBjaGFuZ2UgPCAwKSB7XG4gICAgICBjaGFuZ2UgPSAoY2hhbmdlICsgY2FwICogX2JpZ051bSkgJSBjYXAgLSB+fihjaGFuZ2UgLyBjYXApICogY2FwO1xuICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSBcImNjd1wiICYmIGNoYW5nZSA+IDApIHtcbiAgICAgIGNoYW5nZSA9IChjaGFuZ2UgLSBjYXAgKiBfYmlnTnVtKSAlIGNhcCAtIH5+KGNoYW5nZSAvIGNhcCkgKiBjYXA7XG4gICAgfVxuICB9XG5cbiAgcGx1Z2luLl9wdCA9IHB0ID0gbmV3IFByb3BUd2VlbihwbHVnaW4uX3B0LCB0YXJnZXQsIHByb3BlcnR5LCBzdGFydE51bSwgY2hhbmdlLCBfcmVuZGVyUHJvcFdpdGhFbmQpO1xuICBwdC5lID0gZmluYWxWYWx1ZTtcbiAgcHQudSA9IFwiZGVnXCI7XG5cbiAgcGx1Z2luLl9wcm9wcy5wdXNoKHByb3BlcnR5KTtcblxuICByZXR1cm4gcHQ7XG59LFxuICAgIF9hc3NpZ24gPSBmdW5jdGlvbiBfYXNzaWduKHRhcmdldCwgc291cmNlKSB7XG4gIC8vIEludGVybmV0IEV4cGxvcmVyIGRvZXNuJ3QgaGF2ZSBPYmplY3QuYXNzaWduKCksIHNvIHdlIHJlY3JlYXRlIGl0IGhlcmUuXG4gIGZvciAodmFyIHAgaW4gc291cmNlKSB7XG4gICAgdGFyZ2V0W3BdID0gc291cmNlW3BdO1xuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn0sXG4gICAgX2FkZFJhd1RyYW5zZm9ybVBUcyA9IGZ1bmN0aW9uIF9hZGRSYXdUcmFuc2Zvcm1QVHMocGx1Z2luLCB0cmFuc2Zvcm1zLCB0YXJnZXQpIHtcbiAgLy9mb3IgaGFuZGxpbmcgY2FzZXMgd2hlcmUgc29tZW9uZSBwYXNzZXMgaW4gYSB3aG9sZSB0cmFuc2Zvcm0gc3RyaW5nLCBsaWtlIHRyYW5zZm9ybTogXCJzY2FsZSgyLCAzKSByb3RhdGUoMjBkZWcpIHRyYW5zbGF0ZVkoMzBlbSlcIlxuICB2YXIgc3RhcnRDYWNoZSA9IF9hc3NpZ24oe30sIHRhcmdldC5fZ3NhcCksXG4gICAgICBleGNsdWRlID0gXCJwZXJzcGVjdGl2ZSxmb3JjZTNEL
1HRyYW5zZm9ybU9yaWdpbixzdmdPcmlnaW5cIixcbiAgICAgIHN0eWxlID0gdGFyZ2V0LnN0eWxlLFxuICAgICAgZW5kQ2FjaGUsXG4gICAgICBwLFxuICAgICAgc3RhcnRWYWx1ZSxcbiAgICAgIGVuZFZhbHVlLFxuICAgICAgc3RhcnROdW0sXG4gICAgICBlbmROdW0sXG4gICAgICBzdGFydFVuaXQsXG4gICAgICBlbmRVbml0O1xuXG4gIGlmIChzdGFydENhY2hlLnN2Zykge1xuICAgIHN0YXJ0VmFsdWUgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIpO1xuICAgIHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJcIik7XG4gICAgc3R5bGVbX3RyYW5zZm9ybVByb3BdID0gdHJhbnNmb3JtcztcbiAgICBlbmRDYWNoZSA9IF9wYXJzZVRyYW5zZm9ybSh0YXJnZXQsIDEpO1xuXG4gICAgX3JlbW92ZVByb3BlcnR5KHRhcmdldCwgX3RyYW5zZm9ybVByb3ApO1xuXG4gICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBzdGFydFZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICBzdGFydFZhbHVlID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpW190cmFuc2Zvcm1Qcm9wXTtcbiAgICBzdHlsZVtfdHJhbnNmb3JtUHJvcF0gPSB0cmFuc2Zvcm1zO1xuICAgIGVuZENhY2hlID0gX3BhcnNlVHJhbnNmb3JtKHRhcmdldCwgMSk7XG4gICAgc3R5bGVbX3RyYW5zZm9ybVByb3BdID0gc3RhcnRWYWx1ZTtcbiAgfVxuXG4gIGZvciAocCBpbiBfdHJhbnNmb3JtUHJvcHMpIHtcbiAgICBzdGFydFZhbHVlID0gc3RhcnRDYWNoZVtwXTtcbiAgICBlbmRWYWx1ZSA9IGVuZENhY2hlW3BdO1xuXG4gICAgaWYgKHN0YXJ0VmFsdWUgIT09IGVuZFZhbHVlICYmIGV4Y2x1ZGUuaW5kZXhPZihwKSA8IDApIHtcbiAgICAgIC8vdHdlZW5pbmcgdG8gbm8gcGVyc3BlY3RpdmUgZ2l2ZXMgdmVyeSB1bmludHVpdGl2ZSByZXN1bHRzIC0ganVzdCBrZWVwIHRoZSBzYW1lIHBlcnNwZWN0aXZlIGluIHRoYXQgY2FzZS5cbiAgICAgIHN0YXJ0VW5pdCA9IGdldFVuaXQoc3RhcnRWYWx1ZSk7XG4gICAgICBlbmRVbml0ID0gZ2V0VW5pdChlbmRWYWx1ZSk7XG4gICAgICBzdGFydE51bSA9IHN0YXJ0VW5pdCAhPT0gZW5kVW5pdCA/IF9jb252ZXJ0VG9Vbml0KHRhcmdldCwgcCwgc3RhcnRWYWx1ZSwgZW5kVW5pdCkgOiBwYXJzZUZsb2F0KHN0YXJ0VmFsdWUpO1xuICAgICAgZW5kTnVtID0gcGFyc2VGbG9hdChlbmRWYWx1ZSk7XG4gICAgICBwbHVnaW4uX3B0ID0gbmV3IFByb3BUd2VlbihwbHVnaW4uX3B0LCBlbmRDYWNoZSwgcCwgc3RhcnROdW0sIG
1VuZE51bSAtIHN0YXJ0TnVtLCBfcmVuZGVyQ1NTUHJvcCk7XG4gICAgICBwbHVnaW4uX3B0LnUgPSBlbmRVbml0IHx8IDA7XG5cbiAgICAgIHBsdWdpbi5fcHJvcHMucHVzaChwKTtcbiAgICB9XG4gIH1cblxuICBfYXNzaWduKGVuZENhY2hlLCBzdGFydENhY2hlKTtcbn07IC8vIGhhbmRsZSBzcGxpdHRpbmcgYXBhcnQgcGFkZGluZywgbWFyZ2luLCBib3JkZXJXaWR0aCwgYW5kIGJvcmRlclJhZGl1cyBpbnRvIHRoZWlyIDQgY29tcG9uZW50cy4gRmlyZWZveCwgZm9yIGV4YW1wbGUsIHdvbid0IHJlcG9ydCBib3JkZXJSYWRpdXMgY29ycmVjdGx5IC0gaXQgd2lsbCBvbmx5IGRvIGJvcmRlclRvcExlZnRSYWRpdXMgYW5kIHRoZSBvdGhlciBjb3JuZXJzLiBXZSBhbHNvIHdhbnQgdG8gaGFuZGxlIHBhZGRpbmdUb3AsIG1hcmdpbkxlZnQsIGJvcmRlclJpZ2h0V2lkdGgsIGV0Yy5cblxuXG5fZm9yRWFjaE5hbWUoXCJwYWRkaW5nLG1hcmdpbixXaWR0aCxSYWRpdXNcIiwgZnVuY3Rpb24gKG5hbWUsIGluZGV4KSB7XG4gIHZhciB0ID0gXCJUb3BcIixcbiAgICAgIHIgPSBcIlJpZ2h0XCIsXG4gICAgICBiID0gXCJCb3R0b21cIixcbiAgICAgIGwgPSBcIkxlZnRcIixcbiAgICAgIHByb3BzID0gKGluZGV4IDwgMyA/IFt0LCByLCBiLCBsXSA6IFt0ICsgbCwgdCArIHIsIGIgKyByLCBiICsgbF0pLm1hcChmdW5jdGlvbiAoc2lkZSkge1xuICAgIHJldHVybiBpbmRleCA8IDIgPyBuYW1lICsgc2lkZSA6IFwiYm9yZGVyXCIgKyBzaWRlICsgbmFtZTtcbiAgfSk7XG5cbiAgX3NwZWNpYWxQcm9wc1tpbmRleCA+IDEgPyBcImJvcmRlclwiICsgbmFtZSA6IG5hbWVdID0gZnVuY3Rpb24gKHBsdWdpbiwgdGFyZ2V0LCBwcm9wZXJ0eSwgZW5kVmFsdWUsIHR3ZWVuKSB7XG4gICAgdmFyIGEsIHZhcnM7XG5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDQpIHtcbiAgICAgIC8vIGdldHRlciwgcGFzc2VkIHRhcmdldCwgcHJvcGVydHksIGFuZCB1bml0IChmcm9tIF9nZXQoKSlcbiAgICAgIGEgPSBwcm9wcy5tYXAoZnVuY3Rpb24gKHByb3ApIHtcbiAgICAgICAgcmV0dXJuIF9nZXQocGx1Z2luLCBwcm9wLCBwcm9wZXJ0eSk7XG4gICAgICB9KTtcbiAgICAgIHZhcnMgPSBhLmpvaW4oXCIgXCIpO1xuICAgICAgcmV0dXJuIHZhcnMuc3BsaXQoYVswXSkubGVuZ3RoID09PSA1ID8gYVswXSA6IHZhcnM7XG4gICAgfVxuXG4gICAgYSA9IChlbmRWYWx1ZSArIFwiXCIpLnNwbGl0KFwiIFwiKTtcbiAgICB2YXJzID0ge307XG4gICAgcHJvcHMuZm9yRWFjaChmdW5jdGlvbiAocHJvcCwgaSkge1xuICAgICAgcmV0dXJuIHZhcnNbcHJvcF0gPSBhW2ldID0gYVtpXSB8fCBhWyhpIC0gMSkgLyAyIHwgMF07XG4gICAgfSk7XG4gICAgcGx1Z2luLmluaXQodGFyZ2V0LCB2YXJzLCB0d2Vlbik7XG4gIH07XG59KTtcblxuZXhwb3J0IHZhciBDU1NQbHVnaW4gPSB7XG4gIG5hbWU6IFwiY3NzXCIsXG4gIHJlZ2lzdGVyOiBfaW5pdENvcmUsXG4gIHRhcmdldFRlc3Q6IGZ1bmN0aW9uIHRhcmdldFRlc3QodGFyZ2V0KSB7XG4gICAgcmV0dXJuIHRhcmdldC5zdHlsZSAmJiB0YXJnZXQubm9kZVR5cGU7XG4gIH0sXG4gIGluaXQ6IGZ1bmN0aW9uIGluaXQodGFyZ2V0LCB2YXJzLCB0d2VlbiwgaW5kZXgsIHRhcmdldHMpIHtcbiAgICB2YXIgcHJvcHMgPSB0aGlzLl9wcm9wcyxcbiAgICAgICAgc3R5bGUgPSB0YXJnZXQuc3R5bGUsXG4gICAgICAgIHN0YXJ0QXQgPSB0d2Vlbi52YXJzLnN0YXJ0QXQsXG4gICAgICAgIHN0YXJ0VmFsdWUsXG4gICAgICAgIGVuZFZhbHVlLFxuICAgICAgICBlbmROdW0sXG4gICAgICAgIHN0YXJ0TnVtLFxuICAgICAgICB0eXBlLFxuICAgICAgICBzcGVjaWFsUHJvcCxcbiAgICAgICAgcCxcbiAgICAgICAgc3RhcnRVbml0LFxuICAgICAgICBlbmRVbml0LFxuICAgICAgICByZWxhdGl2ZSxcbiAgICAgICAgaXNUcmFuc2Zvcm1SZWxhdGVkLFxuICAgICAgICB0cmFuc2Zvcm1Qcm9wVHdlZW4sXG4gICAgICAgIGNhY2hlLFxuICAgICAgICBzbW9vdGgsXG4gICAgICAgIGhhc1ByaW9yaXR5LFxuICAgICAgICBpbmxpbmVQcm9wcztcbiAgICBfcGx1Z2luSW5pdHRlZCB8fCBfaW5pdENvcmUoKTsgLy8gd2UgbWF5IGNhbGwgaW5pdCgpIG11bHRpcGxlIHRpbWVzIG9uIHRoZSBzYW1lIHBsdWdpbiBpbnN0YW5jZSwgbGlrZSB3aGVuIGFkZGluZyBzcGVjaWFsIHByb3BlcnRpZXMsIHNvIG1ha2Ugc3VyZSB3ZSBkb24ndCBvdmVyd3JpdGUgdGhlIHJldmVydCBkYXRhIG9yIGlubGluZVByb3BzXG5cbiAgICB0aGlzLnN0eWxlcyA9IHRoaXMuc3R5bGVzIHx8IF9nZXRTdHlsZVNhdmVyKHRhcmdldCk7XG4gICAgaW5saW5lUHJvcHMgPSB0aGlzLnN0eWxlcy5wcm9wcztcbiAgICB0aGlzLnR3ZWVuID0gdHdlZW47XG5cbiAgICBmb3IgKHAgaW4gdmFycykge1xuICAgICAgaWYgKHAgPT09IFwiYXV0b1JvdW5kXCIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGVuZFZhbHVlID0gdmFyc1twXTtcblxuICAgICAgaWYgKF9wbHVnaW5zW3BdICYmIF9jaGVja1BsdWdpbihwLCB2YXJzLCB0d2VlbiwgaW5kZXgsIHRhcmdldCwgdGFyZ2V0cykpIHtcbiAgICAgICAgLy8gcGx1Z2luc1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdHlwZSA9IHR5cGVvZiBlbmRWYWx1ZTtcbiAgICAgIHNwZWNpYWxQcm9wID0gX3NwZWNpYWxQcm9wc1twXTtcblxuICAgICAgaWYgKHR5cGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBlbmRWYWx1ZSA9IGVuZFZhbHVlLmNhbGwodHdlZW4sIGluZGV4LCB0YXJnZXQsIHRhcmdldHMpO1xuICAgICAgICB0eXBlID0gdHlwZW9mIGVuZFZhbHVlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZSA9PT0gXCJzdHJpbmdcIiAmJiB+ZW5kVmFsdWUuaW5kZXhPZihcInJhbmRvbShcIikpIHtcbiAgICAgICAgZW5kVmFsdWUgPSBfcmVwbGFjZVJhbmRvbShlbmRWYWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzcGVjaWFsUHJvcCkge1xuICAgICAgICBzcGVjaWFsUHJvcCh0aGlzLCB0YXJnZXQsIHAsIGVuZFZhbHVlLCB0d2VlbikgJiYgKGhhc1ByaW9yaXR5ID0gMSk7XG4gICAgICB9IGVsc2UgaWYgKHAuc3Vic3RyKDAsIDIpID09PSBcIi0tXCIpIHtcbiAgICAgICAgLy9DU1MgdmFyaWFibGVcbiAgICAgICAgc3RhcnRWYWx1ZSA9IChnZXRDb21wdXRlZFN0eWxlKHRhcmdldCkuZ2V0UHJvcGVydHlWYWx1ZShwKSArIFwiXCIpLnRyaW0oKTtcbiAgICAgICAgZW5kVmFsdWUgKz0gXCJcIjtcbiAgICAgICAgX2NvbG9yRXhwLmxhc3RJbmRleCA9IDA7XG5cbiAgICAgICAgaWYgKCFfY29sb3JFeHAudGVzdChzdGFydFZhbHVlKSkge1xuICAgICAgICAgIC8vIGNvbG9ycyBkb24ndCBoYXZlIHVuaXRzXG4gICAgICAgICAgc3RhcnRVbml0ID0gZ2V0VW5pdChzdGFydFZhbHVlKTtcbiAgICAgICAgICBlbmRVbml0ID0gZ2V0VW5pdChlbmRWYWx1ZSk7XG4gICAgICAgI
1H1cblxuICAgICAgICBlbmRVbml0ID8gc3RhcnRVbml0ICE9PSBlbmRVbml0ICYmIChzdGFydFZhbHVlID0gX2NvbnZlcnRUb1VuaXQodGFyZ2V0LCBwLCBzdGFydFZhbHVlLCBlbmRVbml0KSArIGVuZFVuaXQpIDogc3RhcnRVbml0ICYmIChlbmRWYWx1ZSArPSBzdGFydFVuaXQpO1xuICAgICAgICB0aGlzLmFkZChzdHlsZSwgXCJzZXRQcm9wZXJ0eVwiLCBzdGFydFZhbHVlLCBlbmRWYWx1ZSwgaW5kZXgsIHRhcmdldHMsIDAsIDAsIHApO1xuICAgICAgICBwcm9wcy5wdXNoKHApO1xuICAgICAgICBpbmxpbmVQcm9wcy5wdXNoKHAsIDAsIHN0eWxlW3BdKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBpZiAoc3RhcnRBdCAmJiBwIGluIHN0YXJ0QXQpIHtcbiAgICAgICAgICAvLyBpbiBjYXNlIHNvbWVvbmUgaGFyZC1jb2RlcyBhIGNvbXBsZXggdmFsdWUgYXMgdGhlIHN0YXJ0LCBsaWtlIHRvcDogXCJjYWxjKDJ2aCAvIDIpXCIuIFdpdGhvdXQgdGhpcywgaXQnZCB1c2UgdGhlIGNvbXB1dGVkIHZhbHVlIChhbHdheXMgaW4gcHgpXG4gICAgICAgICAgc3RhcnRWYWx1ZSA9IHR5cGVvZiBzdGFydEF0W3BdID09PSBcImZ1bmN0aW9uXCIgPyBzdGFydEF0W3BdLmNhbGwodHdlZW4sIGluZGV4LCB0YXJnZXQsIHRhcmdldHMpIDogc3RhcnRBdFtwXTtcbiAgICAgICAgICBfaXNTdHJpbmcoc3RhcnRWYWx1ZSkgJiYgfnN0YXJ0VmFsdWUuaW5kZXhPZihcInJhbmRvbShcIikgJiYgKHN0YXJ0VmFsdWUgPSBfcmVwbGFjZVJhbmRvbShzdGFydFZhbHVlKSk7XG4gICAgICAgICAgZ2V0VW5pdChzdGFydFZhbHVlICsgXCJcIikgfHwgc3RhcnRWYWx1ZSA9PT0gXCJhdXRvXCIgfHwgKHN0YXJ0VmFsdWUgKz0gX2NvbmZpZy51bml0c1twXSB8fCBnZXRVbml0KF9nZXQodGFyZ2V0LCBwKSkgfHwgXCJcIik7IC8vIGZvciBjYXNlcyB3aGVuIHNvbWVvbmUgcGFzc2VzIGluIGEgdW5pdGxlc3MgdmFsdWUgbGlrZSB7eDogMTAwfTsgaWYgd2UgdHJ5IHNldHRpbmcgdHJhbnNsYXRlKDEwMCwgMHB4KSBpdCB3b24ndCB3b3JrLlxuXG4gICAgICAgICAgKHN0YXJ0VmFsdWUgKyBcIlwiKS5jaGFyQXQoMSkgPT09IFwiPVwiICYmIChzdGFydFZhbHVlID0gX2dldCh0YXJnZXQsIHApKTsgLy8gY2FuJ3Qgd29yayB3aXRoIHJlbGF0aXZlIHZhbHVlc1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXJ0VmFsdWUgPSBfZ2V0KHRhcmdldCwgcCk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGFydE51bSA9IHBhcnNlRmxvYXQoc3RhcnRWYWx1ZSk7XG4gICAgICAgIHJlbGF0aXZlID0gdHlwZSA9PT0gXCJzdHJpbmdcIiAmJiBlbmRWYWx1ZS5jaGFyQXQoMSkgPT09IFwiPVwiICYmIGVuZFZhbHVlLnN1YnN0cigwLCAyKTtcbiAgICAgICAgcmVsYXRpdmUgJiYgKGVuZFZhbHVlID0gZW5kVmFsdWUuc3Vic3RyKDIpKTtcbiAgICAgICAgZW5kTnVtID0gcGFyc2VGbG9hdChlbmRWYWx1ZSk7XG5cbiAgICAgICAgaWYgKHAgaW4gX3Byb3BlcnR5QWxpYXNlcykge1xuICAgICAgICAgIGlmIChwID09PSBcImF1dG9BbHBoYVwiKSB7XG4gICAgICAgICAgICAvL3NwZWNpYWwgY2FzZSB3aGVyZSB3ZSBjb250cm9sIHRoZSB2aXNpYmlsaXR5IGFsb25nIHdpdGggb3BhY2l0eS4gV2Ugc3RpbGwgYWxsb3cgdGhlIG9wYWNpdHkgdmFsdWUgdG8gcGFzcyB0aHJvdWdoIGFuZCBnZXQgdHdlZW5lZC5cbiAgICAgICAgICAgIGlmIChzdGFydE51bSA9PT0gMSAmJiBfZ2V0KHRhcmdldCwgXCJ2aXNpYmlsaXR5XCIpID09PSBcImhpZGRlblwiICYmIGVuZE51bSkge1xuICAgICAgICAgICAgICAvL2lmIHZpc2liaWxpdHkgaXMgaW5pdGlhbGx5IHNldCB0byBcImhpZGRlblwiLCB3ZSBzaG91bGQgaW50ZXJwcmV0IHRoYXQgYXMgaW50ZW50IHRvIG1ha2Ugb3BhY2l0eSAwIChhIGNvbnZlbmllbmNlKVxuICAgICAgICAgICAgICBzdGFydE51bSA9IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlubGluZVByb3BzLnB1c2goXCJ2aXNpYmlsaXR5XCIsIDAsIHN0eWxlLnZpc2liaWxpdHkpO1xuXG4gICAgICAgICAgICBfYWRkTm9uVHdlZW5pbmdQVCh0aGlzLCBzdHlsZSwgXCJ2aXNpYmlsaXR5XCIsIHN0YXJ0TnVtID8gXCJpbmhlcml0XCIgOiBcImhpZGRlblwiLCBlbmROdW0gPyBcImluaGVyaXRcIiA6IFwiaGlkZGVuXCIsICFlbmROdW0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwICE9PSBcInNjYWxlXCIgJiYgcCAhPT0gXCJ0cmFuc2Zvcm1cIikge1xuICAgICAgICAgICAgcCA9IF9wcm9wZXJ0eUFsaWFzZXNbcF07XG4gICAgICAgICAgICB+cC5pbmRleE9mKFwiLFwiKSAmJiAocCA9IHAuc3BsaXQoXCIsXCIpWzBdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpc1RyYW5zZm9ybVJlbGF0ZWQgPSBwIGluIF90cmFuc2Zvcm1Qcm9wczsgLy8tLS0gVFJBTlNGT1JNLVJFTEFURUQgLS0tXG5cbiAgICAgICAgaWYgKGlzVHJhbnNmb3JtUmVsYXRlZCkge1xuICAgICAgICAgIHRoaXMuc3R5bGVzLnNhdmUocCk7XG5cbiAgICAgICAgICBpZiAoIXRyYW5zZm9ybVByb3BUd2Vlbikge1xuICAgICAgICAgICAgY2FjaGUgPSB0YXJnZXQuX2dzYXA7XG4gICAgICAgICAgICBjYWNoZS5yZW5kZXJUcmFuc2Zvcm0gJiYgIXZhcnMucGFyc2VUcmFuc2Zvcm0gfHwgX3BhcnNlVHJhbnNmb3JtKHRhcmdldCwgdmFycy5wYXJzZVRyYW5zZm9ybSk7IC8vIGlmLCBmb3IgZXhhbXBsZSwgZ3NhcC5zZXQoLi4uIHt0cmFuc2Zvcm06XCJ0cmFuc2xhdGVYKDUwdncpXCJ9KSwgdGhlIF9nZXQoKSBjYWxsIGRvZXNuJ3QgcGFyc2UgdGhlIHRyYW5zZm9ybSwgdGh1cyBjYWNoZS5yZW5kZXJUcmFuc2Zvcm0gd29uJ3QgYmUgc2V0IHlldCBzbyBmb3JjZSB0aGUgcGFyc2luZyBvZiB0aGUgdHJhbnNmb3JtIGhlcmUuXG5cbiAgICAgICAgICAgIHNtb290aCA9IHZhcnMuc21vb3RoT3JpZ2luICE9PSBmYWxzZSAmJiBjYWNoZS5zbW9vdGg7XG4gICAgICAgICAgICB0cmFuc2Zvcm1Qcm9wVHdlZW4gPSB0aGlzLl9wdCA9IG5ldyBQcm9wVHdlZW4odGhpcy5fcHQsIHN0eWxlLCBfdHJhbnNmb3JtUHJvcCwgMCwgMSwgY2FjaGUucmVuZGVyVHJhbnNmb3JtLCBjYWNoZSwgMCwgLTEpOyAvL3RoZSBmaXJzdCB0aW1lIH
1Rocm91Z2gsIGNyZWF0ZSB0aGUgcmVuZGVyaW5nIFByb3BUd2VlbiBzbyB0aGF0IGl0IHJ1bnMgTEFTVCAoaW4gdGhlIGxpbmtlZCBsaXN0LCB3ZSBrZWVwIGFkZGluZyB0byB0aGUgYmVnaW5uaW5nKVxuXG4gICAgICAgICAgICB0cmFuc2Zvcm1Qcm9wVHdlZW4uZGVwID0gMTsgLy9mbGFnIGl0IGFzIGRlcGVuZGVudCBzbyB0aGF0IGlmIHRoaW5ncyBnZXQga2lsbGVkL292ZXJ3cml0dGVuIGFuZCB0aGlzIGlzIHRoZSBvbmx5IFByb3BUd2VlbiBsZWZ0LCB3ZSBjYW4gc2FmZWx5IGtpbGwgdGhlIHdob2xlIHR3ZWVuLlxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwID09PSBcInNjYWxlXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3B0ID0gbmV3IFByb3BUd2Vlbih0aGlzLl9wdCwgY2FjaGUsIFwic2NhbGVZXCIsIGNhY2hlLnNjYWxlWSwgKHJlbGF0aXZlID8gX3BhcnNlUmVsYXRpdmUoY2FjaGUuc2NhbGVZLCByZWxhdGl2ZSArIGVuZE51bSkgOiBlbmROdW0pIC0gY2FjaGUuc2NhbGVZIHx8IDAsIF9yZW5kZXJDU1NQcm9wKTtcbiAgICAgICAgICAgIHRoaXMuX3B0LnUgPSAwO1xuICAgICAgICAgICAgcHJvcHMucHVzaChcInNjYWxlWVwiLCBwKTtcbiAgICAgICAgICAgIHAgKz0gXCJYXCI7XG4gICAgICAgICAgfSBlbHNlIGlmIChwID09PSBcInRyYW5zZm9ybU9yaWdpblwiKSB7XG4gICAgICAgICAgICBpbmxpbmVQcm9wcy5wdXNoKF90cmFuc2Zvcm1PcmlnaW5Qcm9wLCAwLCBzdHlsZVtfdHJhbnNmb3JtT3JpZ2luUHJvcF0pO1xuICAgICAgICAgICAgZW5kVmFsdWUgPSBfY29udmVydEtleXdvcmRzVG9QZXJjZW50YWdlcyhlbmRWYWx1ZSk7IC8vaW4gY2FzZSBzb21ldGhpbmcgbGlrZSBcImxlZnQgdG9wXCIgb3IgXCJib3R0b20gcmlnaHRcIiBpcyBwYXNzZWQgaW4uIENvbnZlcnQgdG8gcGVyY2VudGFnZXMuXG5cbiAgICAgICAgICAgIGlmIChjYWNoZS5zdmcpIHtcbiAgICAgICAgICAgICAgX2FwcGx5U1ZHT3JpZ2luKHRhcmdldCwgZW5kVmFsdWUsIDAsIHNtb290aCwgMCwgdGhpcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBlbmRVbml0ID0gcGFyc2VGbG9hdChlbmRWYWx1ZS5zcGxpdChcIiBcIilbMl0pIHx8IDA7IC8vaGFuZGxlIHRoZSB6T3JpZ2luIHNlcGFyYXRlbHkhXG5cbiAgICAgICAgICAgICAgZW5kVW5pdCAhPT0gY2FjaGUuek9yaWdpbiAmJiBfYWRkTm9uVHdlZW5pbmdQVCh0aGlzLCBjYWNoZSwgXCJ6T3JpZ2luXCIsIGNhY2hlLnpPcmlnaW4sIGVuZFVuaXQpO1xuXG4gICAgICAgICAgICAgIF9hZGROb25Ud2VlbmluZ1BUKHRoaXMsIHN0eWxlLCBwLCBfZmlyc3RUd29Pbmx5KHN0YXJ0VmFsdWUpLCBfZmlyc3RUd29Pbmx5KGVuZFZhbHVlKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAocCA9PT0gXCJzdmdPcmlnaW5cIikge1xuICAgICAgICAgICAgX2FwcGx5U1ZHT3JpZ2luKHRhcmdldCwgZW5kVmFsdWUsIDEsIHNtb290aCwgMCwgdGhpcyk7XG5cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAocCBpbiBfcm90YXRpb25hbFByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIF9hZGRSb3RhdGlvbmFsUHJvcFR3ZWVuKHRoaXMsIGNhY2hlLCBwLCBzdGFydE51bSwgcmVsYXRpdmUgPyBfcGFyc2VSZWxhdGl2ZShzdGFydE51bSwgcmVsYXRpdmUgKyBlbmRWYWx1ZSkgOiBlbmRWYWx1ZSk7XG5cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAocCA9PT0gXCJzbW9vdGhPcmlnaW5cIikge1xuICAgICAgICAgICAgX2FkZE5vblR3ZWVuaW5nUFQodGhpcywgY2FjaGUsIFwic21vb3RoXCIsIGNhY2hlLnNtb290aCwgZW5kVmFsdWUpO1xuXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHAgPT09IFwiZm9yY2UzRFwiKSB7XG4gICAgICAgICAgICBjYWNoZVtwXSA9IGVuZFZhbHVlO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfSBlbHNlIGlmIChwID09PSBcInRyYW5zZm9ybVwiKSB7XG4gICAgICAgICAgICBfYWRkUmF3VHJhbnNmb3JtUFRzKHRoaXMsIGVuZFZhbHVlLCB0YXJnZXQpO1xuXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIShwIGluIHN0eWxlKSkge1xuICAgICAgICAgIHAgPSBfY2hlY2tQcm9wUHJlZml4KHApIHx8IHA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNUcmFuc2Zvcm1SZWxhdGVkIHx8IChlbmROdW0gfHwgZW5kTnVtID09PSAwKSAmJiAoc3RhcnROdW0gfHwgc3RhcnROdW0gPT09IDApICYmICFfY29tcGxleEV4cC50ZXN0KGVuZFZhbHVlKSAmJiBwIGluIHN0eWxlKSB7XG4gICAgICAgICAgc3RhcnRVbml0ID0gKHN0YXJ0VmFsdWUgKyBcIlwiKS5zdWJzdHIoKHN0YXJ0TnVtICsgXCJcIikubGVuZ3RoKTtcbiAgICAgICAgICBlbmROdW0gfHwgKGVuZE51bSA9IDApOyAvLyBwcm90ZWN0IGFnYWluc3QgTmFOXG5cbiAgICAgICAgICBlbmRVbml0ID0gZ2V0VW5pdChlbmRWYWx1ZSkgfHwgKHAgaW4gX2NvbmZpZy51bml0cyA/IF9jb25maWcudW5pdHNbcF0gOiBzdGFydFVuaXQpO1xuICAgICAgICAgIHN0YXJ0VW5pdCAhPT0gZW5kVW5pdCAmJiAoc3RhcnROdW0gPSBfY29udmVydFRvVW5pdCh0YXJnZXQsIHAsIHN0YXJ0VmFsdWUsIGVuZFVuaXQpKTtcbiAgICAgICAgICB0aGlzLl9wdCA9IG5ldyBQcm9wVHdlZW4odGhpcy5fcHQsIGlzVHJhbnNmb3JtUmVsYXRlZCA/IGNhY2hlIDogc3R5bGUsIHAsIHN0YXJ0TnVtLCAocmVsYXRpdmUgPyBfcGFyc2VSZWxhdGl2ZShzdGFydE51bSwgcmVsYXRpdmUgKyBlbmROdW0pIDogZW5kTnVtKSAtIHN0YXJ0TnVtLCAhaXNUcmFuc2Zvcm1SZWxhdGVkICYmIChlbmRVbml0ID09PSBcInB4XCIgfHwgcCA9PT0gXCJ6SW5kZXhcIikgJiYgdmFycy5hdXRvUm91bmQgIT09IGZhbHNlID8gX3JlbmRlclJvdW5kZWRDU1NQcm9wIDogX3JlbmRlckNTU1Byb3ApO1xuICAgICAgICAgIHRoaXMuX3B0LnUgPSBlbmRVbml0IHx8IDA7XG5cbiAgICAgICAgICBpZiAoc3RhcnRVbml0ICE9PSBlbmRVbml0ICYmIGVuZFVuaXQgIT09IFwiJVwiKSB7XG4gICAgICAgICAgICAvL3doZW4gdGhlIHR3ZWVuIGdvZXMgYWxsIHRoZSB3YXkgYmFjayB0byB0aGUgYmVnaW5uaW5nLCB3ZSBuZWVkIHRvIHJldmVydCBpdCB0byB0aGUgT0xEL09SSUdJTkFMIHZhbHVlICh3aXRoIHRob3NlIHVuaXRzKS4gV2UgcmVjb3JkIHRoYXQgYXMgYSBcImJcIiAoYmVnaW5uaW5nKSBwcm9wZXJ0eSBhbmQgcG9pbnQgdG8gYSByZW5kZXIgbWV0aG9kIHRoYXQgaGFuZGxlcyB0aGF0LiAocGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uKVxuICAgICAgICAgICAgdGhpcy5fcHQuYiA9IHN0YXJ0VmFsdWU7XG4gICAgICAgICAgICB0aGlzLl9wdC5yID0gX3JlbmRlckNTU1Byb3BXaXRoQmVnaW5uaW5nO1xuICAgICAgICAgI
1H1cbiAgICAgICAgfSBlbHNlIGlmICghKHAgaW4gc3R5bGUpKSB7XG4gICAgICAgICAgaWYgKHAgaW4gdGFyZ2V0KSB7XG4gICAgICAgICAgICAvL21heWJlIGl0J3Mgbm90IGEgc3R5bGUgLSBpdCBjb3VsZCBiZSBhIHByb3BlcnR5IGFkZGVkIGRpcmVjdGx5IHRvIGFuIGVsZW1lbnQgaW4gd2hpY2ggY2FzZSB3ZSdsbCB0cnkgdG8gYW5pbWF0ZSB0aGF0LlxuICAgICAgICAgICAgdGhpcy5hZGQodGFyZ2V0LCBwLCBzdGFydFZhbHVlIHx8IHRhcmdldFtwXSwgcmVsYXRpdmUgPyByZWxhdGl2ZSArIGVuZFZhbHVlIDogZW5kVmFsdWUsIGluZGV4LCB0YXJnZXRzKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHAgIT09IFwicGFyc2VUcmFuc2Zvcm1cIikge1xuICAgICAgICAgICAgX21pc3NpbmdQbHVnaW4ocCwgZW5kVmFsdWUpO1xuXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgX3R3ZWVuQ29tcGxleENTU1N0cmluZy5jYWxsKHRoaXMsIHRhcmdldCwgcCwgc3RhcnRWYWx1ZSwgcmVsYXRpdmUgPyByZWxhdGl2ZSArIGVuZFZhbHVlIDogZW5kVmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaXNUcmFuc2Zvcm1SZWxhdGVkIHx8IChwIGluIHN0eWxlID8gaW5saW5lUHJvcHMucHVzaChwLCAwLCBzdHlsZVtwXSkgOiBpbmxpbmVQcm9wcy5wdXNoKHAsIDEsIHN0YXJ0VmFsdWUgfHwgdGFyZ2V0W3BdKSk7XG4gICAgICAgIHByb3BzLnB1c2gocCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaGFzUHJpb3JpdHkgJiYgX3NvcnRQcm9wVHdlZW5zQnlQcmlvcml0eSh0aGlzKTtcbiAgfSxcbiAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIocmF0aW8sIGRhdGEpIHtcbiAgICBpZiAoZGF0YS50d2Vlbi5fdGltZSB8fCAhX3JldmVydGluZygpKSB7XG4gICAgICB2Y
1XIgcHQgPSBkYXRhLl9wdDtcblxuICAgICAgd2hpbGUgKHB0KSB7XG4gICAgICAgIHB0LnIocmF0aW8sIHB0LmQpO1xuICAgICAgICBwdCA9IHB0Ll9uZXh0O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBkYXRhLnN0eWxlcy5yZXZlcnQoKTtcbiAgICB9XG4gIH0sXG4gIGdldDogX2dldCxcbiAgYWxpYXNlczogX3Byb3BlcnR5QWxpYXNlcyxcbiAgZ2V0U2V0dGVyOiBmdW5jdGlvbiBnZXRTZXR0ZXIodGFyZ2V0LCBwcm9wZXJ0eSwgcGx1Z2luKSB7XG4gICAgLy9yZXR1cm5zIGEgc2V0dGVyIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyB0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSBhbmQgYXBwbGllcyBpdCBhY2NvcmRpbmdseS4gUmVtZW1iZXIsIHByb3BlcnRpZXMgbGlrZSBcInhcIiBhcmVuJ3QgYXMgc2ltcGxlIGFzIHRhcmdldC5zdHlsZS5wcm9wZXJ0eSA9IHZhbHVlIGJlY2F1c2UgdGhleSd2ZSBnb3QgdG8gYmUgYXBwbGllZCB0byBhIHByb3h5IG9iamVjdCBhbmQgdGhlbiBtZXJnZWQgaW50byBhIHRyYW5zZm9ybSBzdHJpbmcgaW4gYSByZW5kZXJlci5cbiAgICB2YXIgcCA9IF9wcm9wZXJ0eUFsaWFzZXNbcHJvcGVydHldO1xuICAgIHAgJiYgcC5pbmRleE9mKFwiLFwiKSA8IDAgJiYgKHByb3BlcnR5ID0gcCk7XG4gICAgcmV0dXJuIHByb3BlcnR5IGluIF90cmFuc2Zvcm1Qcm9wcyAmJiBwcm9wZXJ0eSAhPT0gX3RyYW5zZm9ybU9yaWdpblByb3AgJiYgKHRhcmdldC5fZ3NhcC54IHx8IF9nZXQodGFyZ2V0LCBcInhcIikpID8gcGx1Z2luICYmIF9yZWNlbnRTZXR0ZXJQbHVnaW4gPT09IHBsdWdpbiA/IHByb3BlcnR5ID09PSBcInNjYWxlXCIgPyBfc2V0dGVyU2NhbGUgOiBfc2V0dGVyVHJhbnNmb3JtIDogKF9yZWNlbnRTZXR0ZXJQbHVnaW4gPSBwbHVnaW4gfHwge30pICYmIChwcm9wZXJ0eSA9PT0gXCJzY2FsZVwiID8gX3NldHRlclNjYWxlV2l0aFJlbmRlciA6IF9zZXR0ZXJUcmFuc2Zvcm1XaXRoUmVuZGVyKSA6IHRhcmdldC5zdHlsZSAmJiAhX2lzVW5kZWZpbmVkKHRhcmdldC5zdHlsZVtwcm9wZXJ0eV0pID8gX3NldHRlckNTU1N0eWxlIDogfnByb3BlcnR5LmluZGV4T2YoXCItXCIpID8gX3NldHRlckNTU1Byb3AgOiBfZ2V0U2V0dGVyKHRhcmdldCwgcHJvcGVydHkpO1xuICB9LFxuICBjb3JlOiB7XG4gICAgX3JlbW92ZVByb3BlcnR5OiBfcmVtb3ZlUHJvcGVydHksXG4gICAgX2dldE1hdHJpeDogX2dldE1hdHJpeFxuICB9XG59O1xuZ3NhcC51dGlscy5jaGVja1ByZWZpeCA9IF9jaGVja1Byb3BQcmVmaXg7XG5nc2FwLmNvcmUuZ2V0U3R5bGVTYXZlciA9IF9nZXRTdHlsZVNhdmVyO1xuXG4oZnVuY3Rpb24gKHBvc2l0aW9uQW5kU2NhbGUsIHJvdGF0aW9uLCBvdGhlcnMsIGFsaWFzZXMpIHtcbiAgdmFyIGFsbCA9IF9mb3JFYWNoTmFtZShwb3NpdGlvbkFuZFNjYWxlICsgXCIsXCIgKyByb3RhdGlvbiArIFwiLFwiICsgb3RoZXJzLCBmdW5jdGlvbiAobmFtZSkge1xuICAgIF90cmFuc2Zvcm1Qcm9wc1tuYW1lXSA9IDE7XG4gIH0pO1xuXG4gIF9mb3JFYWNoTmFtZShyb3RhdGlvbiwgZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBfY29uZmlnLnVuaXRzW25hbWVdID0gXCJkZWdcIjtcbiAgICBfcm90YXRpb25hbFByb3BlcnRpZXNbbmFtZV0gPSAxO1xuICB9KTtcblxuICBfcHJvcGVydHlBbGlhc2VzW2FsbFsxM11dID0gcG9zaXRpb25BbmRTY2FsZSArIFwiLFwiICsgcm90YXRpb247XG5cbiAgX2ZvckVhY2hOYW1lKGFsaWFzZXMsIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdmFyIHNwbGl0ID0gbmFtZS5zcGxpdChcIjpcIik7XG4gICAgX3Byb3BlcnR5QWxpYXNlc1tzcGxpdFsxXV0gPSBhbGxbc3BsaXRbMF1dO1xuICB9KTtcbn0pKFwieCx5LHosc2NhbGUsc2NhbGVYLHNjYWxlWSx4UGVyY2VudCx5UGVyY2VudFwiLCBcInJvdGF0aW9uLHJvdGF0aW9uWCxyb3RhdGlvblksc2tld1gsc2tld1lcIiwgXCJ0cmFuc2Zvcm0sdHJhbnNmb3JtT3JpZ2luLHN2Z09yaWdpbixmb3JjZTNELHNtb290aE9yaWdpbix0cmFuc2Zvcm1QZXJzcGVjdGl2ZVwiLCBcIjA6dHJhbnNsYXRlWCwxOnRyYW5zbGF0ZVksMjp0cmFuc2xhdGVaLDg6cm90YXRlLDg6cm90YXRpb25aLDg6cm90YXRlWiw5OnJvdGF0ZVgsMTA6cm90YXRlWVwiKTtcblxuX2ZvckVhY2hOYW1lKFwieCx5LHosdG9wLHJpZ2h0LGJvdHRvbSxsZWZ0LHdpZHRoLGhlaWdodCxmb250U2l6ZSxwYWRkaW5nLG1hcmdpbixwZXJzcGVjdGl2ZVwiLCBmdW5jdGlvbiAobmFtZSkge1xuICBfY29uZmlnLnVuaXRzW25hbWVdID0gXCJweFwiO1xufSk7XG5cbmdzYXAucmVnaXN0ZXJQbHVnaW4oQ1NTUGx1Z2luKTtcbmV4cG9ydCB7IENTU1BsdWdpbiBhcyBkZWZhdWx0LCBfZ2V0QkJveCwgX2NyZWF0ZUVsZW1lbnQsIF9jaGVja1Byb3BQcmVmaXggYXMgY2hlY2tQcmVmaXggfTsiLCJpbXBvcnQgZ3NhcCBmcm9tIFwiLi9nc2FwLWNvcmUuanNcIjtcbmltcG9ydCBDU1NQbHVnaW4gZnJvbSBcIi4vQ1NTUGx1Z2luLmpzXCI7XG52YXIgZ3NhcFdpdGhDU1MgPSBnc2FwLnJlZ2lzdGVyUGx1Z2luKENTU1BsdWdpbikgfHwgZ3NhcCxcbiAgICAvLyB0byBwcm90ZWN0IGZyb20gdHJlZSBzaGFraW5nXG5Ud2Vlbk1heFdpdGhDU1MgPSBnc2FwV2l0aENTUy5jb3JlLlR3ZWVuO1xuZXhwb3J0IHsgZ3NhcFdpdGhDU1MgYXMgZ3NhcCwgZ3NhcFdpdGhDU1MgYXMgZGVmYXVsdCwgVHdlZW5NYXhXaXRoQ1NTIGFzIFR3ZWVuTWF4LCBDU1NQbHVnaW4gfTtcbmV4cG9ydCB7IFR3ZWVuTGl0ZSwgVGltZWxpbmVNYXgsIFRpbWVsaW5lTGl
10ZSwgUG93ZXIwLCBQb3dlcjEsIFBvd2VyMiwgUG93ZXIzLCBQb3dlcjQsIExpbmVhciwgUXVhZCwgQ3ViaWMsIFF1YXJ0LCBRdWludCwgU3Ryb25nLCBFbGFzdGljLCBCYWNrLCBTdGVwcGVkRWFzZSwgQm91bmNlLCBTaW5lLCBFeHBvLCBDaXJjLCB3cmFwLCB3cmFwWW95bywgZGlzdHJpYnV0ZSwgcmFuZG9tLCBzbmFwLCBub3JtYWxpemUsIGdldFVuaXQsIGNsYW1wLCBzcGxpdENvbG9yLCB0b0FycmF5LCBtYXBSYW5nZSwgcGlwZSwgdW5pdGl6ZSwgaW50ZXJwb2xhdGUsIHNodWZmbGUsIHNlbGVjdG9yIH0gZnJvbSBcIi4vZ3NhcC1jb3JlLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9DdXN0b21FYXNlLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9EcmFnZ2FibGUuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0NTU1J1bGVQbHVnaW4uanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0Vhc2VsUGx1Z2luLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9FYXNlUGFjay5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vRmxpcC5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vTW90aW9uUGF0aFBsdWdpbi5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vT2JzZXJ2ZXIuanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BpeGlQbHVnaW4uanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1Njcm9sbFRvUGx1Z2luLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TY3JvbGxUcmlnZ2VyLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9UZXh0UGx1Z2luLmpzXCI7IC8vQk9OVVMgRVhQT1JUU1xuLy8gZXhwb3J0ICogZnJvbSBcIi4vRHJhd1NWR1BsdWdpbi5qc1wiO1xuLy8gZXhwb3J0ICogZnJvbSBcIi4vUGh5c2ljczJEUGx1Z2luLmpzXCI7XG4vLyBleHBvcnQgKiBmcm9tIFwiLi9QaHlzaWNzUHJvcHNQbHVnaW4uanNcIjtcbi8vIGV4cG9ydCAqIGZyb20gXCIuL1NjcmFtYmxlVGV4dFBsdWdpbi5qc1wiO1xuLy8gZXhwb3J0ICogZnJvbSBcIi4vQ3VzdG9tQm91bmNlLmpzXCI7XG4vLyBleHBvcnQgKiBmcm9tIFwiLi9DdXN0b21XaWdnbGUuanNcIjtcbi8vIGV4cG9ydCAqIGZyb20gXCIuL0dTRGV2VG9vbHMuanNcIjtcbi8vIGV4cG9ydCAqIGZyb20gXCIuL0luZXJ0aWFQbHVnaW4uanNcIjtcbi8vIGV4cG9ydCAqIGZyb20gXCIuL01vcnBoU1ZHUGx1Z2luLmpzXCI7XG4vLyBleHBvcnQgKiBmcm9tIFwiLi9Nb3Rpb25QYXRoSGVscGVyLmpzXCI7XG4vLyBleHBvcnQgKiBmcm9tIFwiLi9TY3JvbGxTbW9vdGhlci5qc1wiO1xuLy8gZXhwb3J0ICogZnJvbSBcIi4vU3BsaXRUZXh0LmpzXCI7IiwiZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci
15jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfVxuXG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfVxuXG4vKiFcbiAqIE9ic2VydmVyIDMuMTIuNVxuICogaHR0cHM6Ly9nc2FwLmNvbVxuICpcbiAqIEBsaWNlbnNlIENvcHlyaWdodCAyMDA4LTIwMjQsIEdyZWVuU29jay4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFN1YmplY3QgdG8gdGhlIHRlcm1zIGF0IGh0dHBzOi8vZ3NhcC5jb20vc3RhbmRhcmQtbGljZW5zZSBvciBmb3JcbiAqIENsdWIgR1NBUCBtZW1iZXJzLCB0aGUgYWdyZWVtZW50IGlzc3VlZCB3aXRoIHRoYXQgbWVtYmVyc2hpcC5cbiAqIEBhdXRob3I6IEphY2sgRG95bGUsIGphY2tAZ3JlZW5zb2NrLmNvbVxuKi9cblxuLyogZXNsaW50LWRpc2FibGUgKi9cbnZhciBnc2FwLFxuICAgIF9jb3JlSW5pdHRlZCxcbiAgICBfY2xhbXAsXG4gICAgX3dpbixcbiAgICBfZG9jLFxuICAgIF9kb2NFbCxcbiAgICBfYm9keSxcbiAgICBfaXNUb3VjaCxcbiAgICBfcG9pbnRlclR5cGUsXG4gICAgU2Nyb2xsVHJpZ2dlcixcbiAgICBfcm9vdCxcbiAgICBfbm9ybWFsaXplcixcbiAgICBfZXZlbnRUeXBlcyxcbiAgICBfY29udGV4dCxcbiAgICBfZ2V0R1NBUCA9IGZ1bmN0aW9uIF9nZXRHU0FQKCkge1xuICByZXR1cm4gZ3NhcCB8fCB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIChnc2FwID0gd2luZG93LmdzYXApICYmIGdzYXAucmVnaXN0ZXJQbHVnaW4gJiYgZ3NhcDtcbn0sXG4gICAgX3N0YXJ0dXAgPSAxLFxuICAgIF9vYnNlcnZlcnMgPSBbXSxcbiAgICBfc2Nyb2xsZXJzID0gW10sXG4gICAgX3Byb3hpZXMgPSBbXSxcbiAgICBfZ2V0VGltZSA9IERhdGUubm93LFxuICAgIF9icmlkZ2UgPSBmdW5jdGlvbiBfYnJpZGdlKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZTtcbn0sXG4gICAgX2ludGVncmF0ZSA9IGZ1bmN0aW9uIF9pbnRlZ3JhdGUoKSB7XG4gIHZhciBjb3JlID0gU2Nyb2xsVHJpZ2dlci5jb3JlLFxuICAgICAgZGF0YSA9IGNvcmUuYnJpZGdlIHx8IHt9LFxuICAgICAgc2Nyb2xsZXJzID0gY29yZS5fc2Nyb2xsZXJzLFxuICAgICAgcHJveGllcyA9IGNvcmUuX3Byb3hpZXM7XG4gIHNjcm9sbGVycy5wdXNoLmFwcGx5KHNjcm9sbGVycywgX3Njcm9sbGVycyk7XG4gIHByb3hpZXMucHVzaC5hcHBseShwcm94aWVzLCBfcHJveGllcyk7XG4gIF9zY3JvbGxlcnMgPSBzY3JvbGxlcnM7XG4gIF9wcm94aWVzID0gcHJveGllcztcblxuICBfYnJpZGdlID0gZnVuY3Rpb24gX2JyaWRnZShuYW1lLCB2YWx1ZSkge1xuICAgIHJldHVybiBkYXRhW25hbWVdKHZhbHVlKTtcbiAgfTtcbn0sXG4gICAgX2dldFByb3h5UHJvcCA9IGZ1bmN0aW9uIF9nZXRQcm94eVByb3AoZWxlbWVudCwgcHJvcGVydHkpIHtcbiAgcmV0dXJuIH5fcHJveGllcy5pbmRleE9mKGVsZW1lbnQpICYmIF9wcm94aWVzW19wcm94aWVzLmluZGV4T2YoZWxlbWVudCkgKyAxXVtwcm9wZXJ0eV07XG59LFxuICAgIF9pc1ZpZXdwb3J0ID0gZnVuY3Rpb24gX2lzVmlld3BvcnQoZWwpIHtcbiAgcmV0dXJuICEhfl9yb290LmluZGV4T2YoZWwpO1xufSxcbiAgICBfYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBfYWRkTGlzdGVuZXIoZWxlbWVudCwgdHlwZSwgZnVuYywgcGFzc2l2ZSwgY2FwdHVyZSkge1xuICByZXR1cm4gZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGZ1bmMsIHtcbiAgICBwYXNzaXZlOiBwYXNzaXZlICE9PSBmYWxzZSxcbiAgICBjYXB0dXJlOiAhIWNhcHR1cmVcbiAgfSk7XG59LFxuICAgIF9yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIF9yZW1vdmVMaXN0ZW5lcihlbGVtZW50LCB0eXBlLCBmdW5jLCBjYXB0dXJlKSB7XG4gIHJldHVybiBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgZnVuYywgISFjYXB0dXJlKTtcbn0sXG4gICAgX3Njcm9sbExlZnQgPSBcInNjcm9sbExlZnRcIixcbiAgICBfc2Nyb2xsVG9wID0gXCJzY3JvbGxUb3BcIixcbiAgICBfb25TY3JvbGwgPSBmdW5jdGlvbiBfb25TY3JvbGwoKSB7XG4gIHJldHVybiBfbm9ybWFsaXplciAmJiBfbm9ybWFsaXplci5pc1ByZXNzZWQgfHwgX3Njcm9sbGVycy5jYWNoZSsrO1xufSxcbiAgICBfc2Nyb2xsQ2FjaGVGdW5jID0gZnVuY3Rpb24gX3Njcm9sbENhY2hlRnVuYyhmLCBkb05vdENhY2hlKSB7XG4gIHZhciBjYWNoaW5nRnVuYyA9IGZ1bmN0aW9uIGNhY2hpbmdGdW5jKHZhbHVlKSB7XG4gICAgLy8gc2luY2UgcmVhZGluZyB0aGUgc2Nyb2xsVG9wL3Njcm9sbExlZnQvcGFnZU9mZnNldFkvcGFnZU9mZnNldFggY2FuIHRyaWdnZXIgYSBsYXlvdXQsIHRoaXMgZnVuY3Rpb24gYWxsb3dzIHVzIHRvIGNhY2hlIHRoZSB2YWx1ZSBzbyBpdCBvbmx5IGdldHMgcmVhZCBmcmVzaCBhZnRlciBhIFwic2Nyb2xsXCIgZXZlbnQgZmlyZXMgKG9yIHdoaWxlIHdlJ3JlIHJlZnJlc2hpbmcgYmVjYXVzZSB0aGF0IGNhbiBsZW5ndGhlbiB0aGUgcGFnZSBhbmQgYWx0ZXIgdGhlIHNjcm9sbCBwb3NpdGlvbikuIHdoZW4gXCJzb2Z0XCIgaXMgdHJ1ZSwgdGhhdCBtZWFucyBkb24ndCBhY3R1YWxseSBzZXQgdGhlIHNjcm9sbCwgYnV0IGNhY2hlIHRoZSBuZXcgdmFsdWUgaW5zdGVhZCAodXNlZnVsIGluIFNjcm9sbFNtb290aGVyKVxuICAgIGlmICh2YWx1ZSB8fCB2YWx1ZSA9PT0gMCkge1xuICAgICAgX3N0YXJ0dXAgJiYgKF93aW4uaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9IFwibWFudWFsXCIpOyAvLyBvdGhlcndpc2UgdGhlIG5ldyBwb3NpdGlvbiB3aWxsIGdldCBvdmVyd3JpdHRlbiBieSB0aGUgYnJvd3NlciBvbmxvYWQuXG5cbiAgICAgIHZhciBpc05vcm1hbGl6aW5nID0gX25vcm1hbGl6ZXIgJiYgX25vcm1hbGl6ZXIuaXNQcmVzc2VkO1xuICAgICAgdmFsdWUgPSBjYWNoaW5nRnVuYy52ID0gTWF0aC5yb3VuZCh2YWx1ZSkgfHwgKF9ub3JtYWxpem
1VyICYmIF9ub3JtYWxpemVyLmlPUyA/IDEgOiAwKTsgLy9UT0RPOiBpT1MgQnVnOiBpZiB5b3UgYWxsb3cgaXQgdG8gZ28gdG8gMCwgU2FmYXJpIGNhbiBzdGFydCB0byByZXBvcnQgc3VwZXIgc3RyYW5nZSAod2lsZGx5IGluYWNjdXJhdGUpIHRvdWNoIHBvc2l0aW9ucyFcblxuICAgICAgZih2YWx1ZSk7XG4gICAgICBjYWNoaW5nRnVuYy5jYWNoZUlEID0gX3Njcm9sbGVycy5jYWNoZTtcbiAgICAgIGlzTm9ybWFsaXppbmcgJiYgX2JyaWRnZShcInNzXCIsIHZhbHVlKTsgLy8gc2V0IHNjcm9sbCAobm90aWZ5IFNjcm9sbFRyaWdnZXIgc28gaXQgY2FuIGRpc3BhdGNoIGEgXCJzY3JvbGxTdGFydFwiIGV2ZW50IGlmIG5lY2Vzc2FyeVxuICAgIH0gZWxzZSBpZiAoZG9Ob3RDYWNoZSB8fCBfc2Nyb2xsZXJzLmNhY2hlICE9PSBjYWNoaW5nRnVuYy5jYWNoZUlEIHx8IF9icmlkZ2UoXCJyZWZcIikpIHtcbiAgICAgIGNhY2hpbmdGdW5jLmNhY2hlSUQgPSBfc2Nyb2xsZXJzLmNhY2hlO1xuICAgICAgY2FjaGluZ0Z1bmMudiA9IGYoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2FjaGluZ0Z1bmMudiArIGNhY2hpbmdGdW5jLm9mZnNldDtcbiAgfTtcblxuICBjYWNoaW5nRnVuYy5vZmZzZXQgPSAwO1xuICByZXR1cm4gZiAmJiBjYWNoaW5nRnVuYztcbn0sXG4gICAgX2hvcml6b250YWwgPSB7XG4gIHM6IF9zY3JvbGxMZWZ0LFxuICBwOiBcImxlZnRcIixcbiAgcDI6IFwiTGVmdFwiLFxuICBvczogXCJyaWdodFwiLFxuICBvczI6IFwiUmlnaHRcIixcbiAgZDogXCJ3aWR0aFwiLFxuICBkMjogXCJXaWR0aFwiLFxuICBhOiBcInhcIixcbiAgc2M6IF9zY3JvbGxDYWNoZUZ1bmMoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyBfd2luLnNjcm9sbFRvKHZhbHVlLCBfdmVydGljYWwuc2MoKSkgOiBfd2luLnBhZ2VYT2Zmc2V0IHx8IF9kb2NbX3Njcm9sbExlZnRdIHx8IF9kb2NFbFtfc2Nyb2xsTGVmdF0gfHwgX2JvZHlbX3Njcm9sbExlZnRdIHx8IDA7XG4gIH0pXG59LFxuICAgIF92ZXJ0aWNhbCA9IHtcbiAgczogX3Njcm9sbFRvcCxcbiAgcDogXCJ0b3BcIixcbiAgcDI6IFwiVG9wXCIsXG4gIG9zOiBcImJvdHRvbVwiLFxuICBvczI6IFwiQm90dG9tXCIsXG4gIGQ6IFwiaGVpZ2h0XCIsXG4gIGQyOiBcIkhlaWdodFwiLFxuICBhOiBcInlcIixcbiAgb3A6IF9ob3Jpem9udGFsLFxuICBzYzogX3Njcm9sbENhY2hlRnVuYyhmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IF93aW4uc2Nyb2xsVG8oX2hvcml6b250YWwuc2MoKSwgdmFsdWUpIDogX3dpbi5wYWdlWU9mZnNldCB8fCBfZG9jW19zY3JvbGxUb3BdIHx8IF9kb2NFbFtfc2Nyb2xsVG9wXSB8fCBfYm9keVtfc2Nyb2xsVG9wXSB8fCAwO1xuICB9KVxufSxcbiAgICBfZ2V0VGFyZ2V0ID0gZnVuY3Rpb24gX2dldFRhcmdldCh0LCBzZWxmKSB7XG4gIHJldHVybiAoc2VsZiAmJiBzZWxmLl9jdHggJiYgc2VsZi5fY3R4LnNlbGVjdG9yIHx8IGdzYXAudXRpbHMudG9BcnJheSkodClbMF0gfHwgKHR5cGVvZiB0ID09PSBcInN0cmluZ1wiICYmIGdzYXAuY29uZmlnKCkubnVsbFRhcmdldFdhcm4gIT09IGZhbHNlID8gY29uc29sZS53YXJuKFwiRWxlbWVudCBub3QgZm91bmQ6XCIsIHQpIDogbnVsbCk7XG59LFxuICAgIF9nZXRTY3JvbGxGdW5jID0gZnVuY3Rpb24gX2dldFNjcm9sbEZ1bmMoZWxlbWVudCwgX3JlZikge1xuICB2YXIgcyA9IF9yZWYucyxcbiAgICAgIHNjID0gX3JlZi5zYztcbiAgLy8gd2Ugc3RvcmUgdGhlIHNjcm9sbGVyIGZ1bmN0aW9ucyBpbiBhbiBhbHRlcm5hdGluZyBzZXF1ZW5jZWQgQXJyYXkgbGlrZSBbZWxlbWVudCwgdmVydGljYWxTY3JvbGxGdW5jLCBob3Jpem9udGFsU2Nyb2xsRnVuYywgLi4uXSBzbyB0aGF0IHdlIGNhbiBtaW5pbWl6ZSBtZW1vcnksIG1heGltaXplIHBlcmZvcm1hbmNlLCBhbmQgd2UgYWxzbyByZWNvcmQgdGhlIGxhc3QgcG9zaXRpb24gYXMgYSBcIi5yZWNcIiBwcm9wZXJ0eSBpbiBvcmRlciB0byByZXZlcnQgdG8gdGhhdCBhZnRlciByZWZyZXNoaW5nIHRvIGVuc3VyZSB0aGluZ3MgZG9uJ3Qgc2hpZnQgYXJvdW5kLlxuICBfaXNWaWV3cG9ydChlbGVtZW50KSAmJiAoZWxlbWVudCA9IF9kb2Muc2Nyb2xsaW5nRWxlbWVudCB8fCBfZG9jRWwpO1xuXG4gIHZhciBpID0gX3Njcm9sbGVycy5pbmRleE9mKGVsZW1lbnQpLFxuICAgICAgb2Zmc2V0ID0gc2MgPT09IF92ZXJ0aWNhbC5zYyA/IDEgOiAyO1xuXG4gICF+aSAmJiAoaSA9IF9zY3JvbGxlcnMucHVzaChlbGVtZW50KSAtIDEpO1xuICBfc2Nyb2xsZXJzW2kgKyBvZmZzZXRdIHx8IF9hZGRMaXN0ZW5lcihlbGVtZW50LCBcInNjcm9sbFwiLCBfb25TY3JvbGwpOyAvLyBjbGVhciB0aGUgY2FjaGUgd2hlbiBhIHNjcm9sbCBvY2N1cnNcblxuICB2YXIgcHJldiA9IF9zY3JvbGxlcnNbaSArIG9mZnNldF0sXG4gICAgICBmdW5jID0gcHJldiB8fCAoX3Njcm9sbGVyc1tpICsgb2Zmc2V0XSA9IF9zY3JvbGxDYWNoZUZ1bmMoX2dldFByb3h5UHJvcChlbGVtZW50LCBzKSwgdHJ1ZSkgfHwgKF9pc1ZpZXdwb3J0KGVsZW1lbnQpID8gc2MgOiBfc2Nyb2xsQ2FjaGVGdW5jKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gZWxlbWVudFtzXSA9IHZhbHVlIDogZWxlbWVudFtzXTtcbiAgfSkpKTtcbiAgZnVuYy50YXJnZXQgPSBlbGVtZW50O1xuICBwcmV2IHx8IChmdW5jLnNtb290aCA9IGdzYXAuZ2V0UHJvcGVydHkoZWxlbWVudCwgXCJzY3JvbGxCZWhhdmlvclwiKSA9PT0gXCJzbW9vdGhcIik7IC8vIG9ubHkgc2V0IGl0IHRoZSBmaXJzdCB0aW1lIChkb24ndCByZXNldCBldmVyeSB0aW1lIGEgc2Nyb2xsRnVuYyBpcyByZXF1ZXN0ZWQgYmVjYXVzZSBwZXJoYXBzIGl0IGhhcHBlbnMgZHVyaW5nIGEgcmVmcmVzaCgpIHdoZW4gaXQncyBkaXNhYmxlZCBpbiBTY3JvbGxUcmlnZ2VyLlxuXG4gIHJldHVybiBmdW5jO1xufSxcbiAgICBfZ2V0VmVsb2NpdHlQcm9wID0gZnVuY3Rpb24gX2dldFZlbG9jaXR5UHJvcCh2YWx1ZSwgbWluVGltZVJlZnJlc2gsIHVzZURlbHRhKSB7XG4gIHZhciB2MSA9IHZhbHVlLFxuICAgICAgdjIgPSB2YWx1ZSxcbiAgICAgIHQxID0gX2dldFRpbWUoKSxcbiAgICAgIHQyID0gdDEsXG4gICAgICBtaW4gPSBtaW5UaW1l
1UmVmcmVzaCB8fCA1MCxcbiAgICAgIGRyb3BUb1plcm9UaW1lID0gTWF0aC5tYXgoNTAwLCBtaW4gKiAzKSxcbiAgICAgIHVwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZSh2YWx1ZSwgZm9yY2UpIHtcbiAgICB2YXIgdCA9IF9nZXRUaW1lKCk7XG5cbiAgICBpZiAoZm9yY2UgfHwgdCAtIHQxID4gbWluKSB7XG4gICAgICB2MiA9IHYxO1xuICAgICAgdjEgPSB2YWx1ZTtcbiAgICAgIHQyID0gdDE7XG4gICAgICB0MSA9IHQ7XG4gICAgfSBlbHNlIGlmICh1c2VEZWx0YSkge1xuICAgICAgdjEgKz0gdmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG5vdCB0b3RhbGx5IG5lY2Vzc2FyeSwgYnV0IG1ha2VzIGl0IGEgYml0IG1vcmUgYWNjdXJhdGUgYnkgYWRqdXN0aW5nIHRoZSB2MSB2YWx1ZSBhY2NvcmRpbmcgdG8gdGhlIG5ldyBzbG9wZS4gVGhpcyB3YXkgd2UncmUgbm90IGp1c3QgaWdub3JpbmcgdGhlIGluY29taW5nIGRhdGEuIFJlbW92aW5nIGZvciBub3cgYmVjYXVzZSBpdCBkb2Vzbid0IHNlZW0gdG8gbWFrZSBtdWNoIHByYWN0aWNhbCBkaWZmZXJlbmNlIGFuZCBpdCdzIHByb2JhYmx5IG5vdCB3b3J0aCB0aGUga2IuXG4gICAgICB2MSA9IHYyICsgKHZhbHVlIC0gdjIpIC8gKHQgLSB0MikgKiAodDEgLSB0Mik7XG4gICAgfVxuICB9LFxuICAgICAgcmVzZXQgPSBmdW5jdGlvbiByZXNldCgpIHtcbiAgICB2MiA9IHYxID0gdXNlRGVsdGEgPyAwIDogdjE7XG4gICAgdDIgPSB0MSA9IDA7XG4gIH0sXG4gICAgICBnZXRWZWxvY2l0eSA9IGZ1bmN0aW9uIGdldFZlbG9jaXR5KGxhdGVzdFZhbHVlKSB7XG4gICAgdmFyIHRPbGQgPSB0MixcbiAgICAgICAgdk9sZCA9IHYyLFxuICAgICAgICB0ID0gX2dldFRpbWUoKTtcblxuICAgIChsYXRlc3RWYWx1ZSB8fCBsYXRlc3RWYWx1ZSA9PT0gMCkgJiYgbGF0ZXN0VmFsdWUgIT09IHYxICYmIHVwZGF0ZShsYXRlc3RWYWx1ZSk7XG4gICAgcmV0dXJuIHQxID09PSB0MiB8fCB0IC0gdDIgPiBkcm9wVG9aZXJvVGltZSA/IDAgOiAodjEgKyAodXNlRGVsdGEgPyB2T2xkIDogLXZPbGQpKSAvICgodXNlRGVsdGEgPyB0IDogdDEpIC0gdE9sZCkgKiAxMDAwO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgdXBkYXRlOiB1cGRhdGUsXG4gICAgcmVzZXQ6IHJlc2V0LFxuICAgIGdldFZlbG9jaXR5OiBnZXRWZWxvY2l0eVxuICB9O1xufSxcbiAgICBfZ2V0RXZlbnQgPSBmdW5jdGlvbiBfZ2V0RXZlbnQoZSwgcHJldmVudERlZmF1bHQpIHtcbiAgcHJldmVudERlZmF1bHQgJiYgIWUuX2dzYXBBbGxvdyAmJiBlLnByZXZlbnREZWZhdWx0KCk7XG4gIHJldHVybiBlLmNoYW5nZWRUb3VjaGVzID8gZS5jaGFuZ2VkVG91Y2hlc1swXSA6IGU7XG59LFxuICAgIF9nZXRBYnNvbHV0ZU1heCA9IGZ1bmN0aW9uIF9nZXRBYnNvbHV0ZU1heChhKSB7XG4gIHZhciBtYXggPSBNYXRoLm1heC5hcHBseShNYXRoLCBhKSxcbiAgICAgIG1pbiA9IE1hdGgubWluLmFwcGx5KE1hdGgsIGEpO1xuICByZXR1cm4gTWF0aC5hYnMobWF4KSA+PSBNYXRoLmFicyhtaW4pID8gbWF4IDogbWluO1xufSxcbiAgICBfc2V0U2Nyb2xsVHJpZ2dlciA9IGZ1bmN0aW9uIF9zZXRTY3JvbGxUcmlnZ2VyKCkge1xuICBTY3JvbGxUcmlnZ2VyID0gZ3NhcC5jb3JlLmdsb2JhbHMoKS5TY3JvbGxUcmlnZ2VyO1xuICBTY3JvbGxUcmlnZ2VyICYmIFNjcm9sbFRyaWdnZXIuY29yZSAmJiBfaW50ZWdyYXRlKCk7XG59LFxuICAgIF9pbml0Q29yZSA9IGZ1bmN0aW9uIF9pbml0Q29yZShjb3JlKSB7XG4gIGdzYXAgPSBjb3JlIHx8IF9nZXRHU0FQKCk7XG5cbiAgaWYgKCFfY29yZUluaXR0ZWQgJiYgZ3NhcCAmJiB0eXBlb2YgZG9jdW1lbnQgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnQuYm9keSkge1xuICAgIF93aW4gPSB3aW5kb3c7XG4gICAgX2RvYyA9IGRvY3VtZW50O1xuICAgIF9kb2NFbCA9IF9kb2MuZG9jdW1lbnRFbGVtZW50O1xuICAgIF9ib2R5ID0gX2RvYy5ib2R5O1xuICAgIF9yb290ID0gW193aW4sIF9kb2MsIF9kb2NFbCwgX2JvZHldO1xuICAgIF9jbGFtcCA9IGdzYXAudXRpbHMuY2xhbXA7XG5cbiAgICBfY29udGV4dCA9IGdzYXAuY29yZS5jb250ZXh0IHx8IGZ1bmN0aW9uICgpIHt9O1xuXG4gICAgX3BvaW50ZXJUeXBlID0gXCJvbnBvaW50ZXJlbnRlclwiIGluIF9ib2R5ID8gXCJwb2ludGVyXCIgOiBcIm1vdXNlXCI7IC8vIGlzVG91Y2ggaXMgMCBpZiBubyB0b3VjaCwgMSBpZiBPTkxZIHRvdWNoLCBhbmQgMiBpZiBpdCBjYW4gYWNjb21tb2RhdGUgdG91Y2ggYnV0IGFsc28gb3RoZXIgdHlwZXMgbGlrZSBtb3VzZS9wb2ludGVyLlxuXG4gICAgX2lzVG91Y2ggPSBPYnNlcnZlci5pc1RvdWNoID0gX3dpbi5tYXRjaE1lZGlhICYmIF93aW4ubWF0Y2hNZWRpYShcIihob3Zlcjogbm9uZSksIChwb2ludGVyOiBjb2Fyc2UpXCIpLm1hdGNoZXMgPyAxIDogXCJvbnRvdWNoc3RhcnRcIiBpbiBfd2luIHx8IG5hdmlnYXRvci5tYXhUb3VjaFBvaW50cyA+IDAgfHwgbmF2aWdhdG9yLm1zTWF4VG91Y2hQb2ludHMgPiAwID8gMiA6IDA7XG4gICAgX2V2ZW50VHlwZXMgPSBPYnNlcnZlci5ldmVudFR5cGVzID0gKFwib250b3VjaHN0YXJ0XCIgaW4gX2RvY0VsID8gXCJ0b3VjaHN0YXJ0LHRvdWNobW92ZSx0b3VjaGNhbmNlbCx0b3VjaGVuZFwiIDogIShcIm9ucG9pbnRlcmRvd25cIiBpbiBfZG9jRWwpID8gXCJtb3VzZWRvd24sbW91c2Vtb3ZlLG1vdXNldXAsbW91c2V1cFwiIDogXCJwb2ludGVyZG93bixwb2ludGVybW92ZSxwb2ludGVyY2FuY2VsLHBvaW50ZXJ1cFwiKS5zcGxpdChcIixcIik7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gX3N0YXJ0dXAgPSAwO1xuICAgIH0sIDUwMCk7XG5cbiAgICBfc2V0U2Nyb2xsVHJpZ2dlcigpO1xuXG4gICAgX2NvcmVJbml0dGVkID0gMTtcbiAgfVxuXG4gIHJldHVybiBfY29yZUluaXR0ZWQ7XG59O1xuXG5faG9yaXpvbnRhbC5vcCA9IF92ZXJ0aWNhbDtcbl9zY3JvbGxlcnMuY2FjaGUgPSAwO1xuZXhwb3J0IHZhciBPYnNlcnZlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIE9ic2VydmVyKHZhcnMpIHtcbiAgICB0aGlzLmluaXQo
1dmFycyk7XG4gIH1cblxuICB2YXIgX3Byb3RvID0gT2JzZXJ2ZXIucHJvdG90eXBlO1xuXG4gIF9wcm90by5pbml0ID0gZnVuY3Rpb24gaW5pdCh2YXJzKSB7XG4gICAgX2NvcmVJbml0dGVkIHx8IF9pbml0Q29yZShnc2FwKSB8fCBjb25zb2xlLndhcm4oXCJQbGVhc2UgZ3NhcC5yZWdpc3RlclBsdWdpbihPYnNlcnZlcilcIik7XG4gICAgU2Nyb2xsVHJpZ2dlciB8fCBfc2V0U2Nyb2xsVHJpZ2dlcigpO1xuICAgIHZhciB0b2xlcmFuY2UgPSB2YXJzLnRvbGVyYW5jZSxcbiAgICAgICAgZHJhZ01pbmltdW0gPSB2YXJzLmRyYWdNaW5pbXVtLFxuICAgICAgICB0eXBlID0gdmFycy50eXBlLFxuICAgICAgICB0YXJnZXQgPSB2YXJzLnRhcmdldCxcbiAgICAgICAgbGluZUhlaWdodCA9IHZhcnMubGluZUhlaWdodCxcbiAgICAgICAgZGVib3VuY2UgPSB2YXJzLmRlYm91bmNlLFxuICAgICAgICBwcmV2ZW50RGVmYXVsdCA9IHZhcnMucHJldmVudERlZmF1bHQsXG4gICAgICAgIG9uU3RvcCA9IHZhcnMub25TdG9wLFxuICAgICAgICBvblN0b3BEZWxheSA9IHZhcnMub25TdG9wRGVsYXksXG4gICAgICAgIGlnbm9yZSA9IHZhcnMuaWdub3JlLFxuICAgICAgICB3aGVlbFNwZWVkID0gdmFycy53aGVlbFNwZWVkLFxuICAgICAgICBldmVudCA9IHZhcnMuZXZlbnQsXG4gICAgICAgIG9uRHJhZ1N0YXJ0ID0gdmFycy5vbkRyYWdTdGFydCxcbiAgICAgICAgb25EcmFnRW5kID0gdmFycy5vbkRyYWdFbmQsXG4gICAgICAgIG9uRHJhZyA9IHZhcnMub25EcmFnLFxuICAgICAgICBvblByZXNzID0gdmFycy5vblByZXNzLFxuICAgICAgICBvblJlbGVhc2UgPSB2YXJzLm9uUmVsZWFzZSxcbiAgICAgICAgb25SaWdodCA9IHZhcnMub25SaWdodCxcbiAgICAgICAgb25MZWZ0ID0gdmFycy5vbkxlZnQsXG4gICAgICAgIG9uVXAgPSB2YXJzLm9uVXAsXG4gICAgICAgIG9uRG93biA9IHZhcnMub25Eb3duLFxuICAgICAgICBvbkNoYW5nZVggPSB2YXJzLm9uQ2hhbmdlWCxcbiAgICAgICAgb25DaGFuZ2VZID0gdmFycy5vbkNoYW5nZVksXG4gICAgICAgIG9uQ2hhbmdlID0gdmFycy5vbkNoYW5nZSxcbiAgICAgICAgb25Ub2dnbGVYID0gdmFycy5vblRvZ2dsZVgsXG4gICAgICAgIG9uVG9nZ2xlWSA9IHZhcnMub25Ub2dnbGVZLFxuICAgICAgICBvbkhvdmVyID0gdmFycy5vbkhvdmVyLFxuICAgICAgICBvbkhvdmVyRW5kID0gdmFycy5vbkhvdmVyRW5kLFxuICAgICAgICBvbk1vdmUgPSB2YXJzLm9uTW92ZSxcbiAgICAgICAgaWdub3JlQ2hlY2sgPSB2YXJzLmlnbm9yZUNoZWNrLFxuICAgICAgICBpc05vcm1hbGl6ZXIgPSB2YXJzLmlzTm9ybWFsaXplcixcbiAgICAgICAgb25HZXN0dXJlU3RhcnQgPSB2YXJzLm9uR2VzdHVyZVN0YXJ0LFxuICAgICAgICBvbkdlc3R1cmVFbmQgPSB2YXJzLm9uR2VzdHVyZUVuZCxcbiAgICAgICAgb25XaGVlbCA9IHZhcnMub25XaGVlbCxcbiAgICAgICAgb25FbmFibGUgPSB2YXJzLm9uRW5hYmxlLFxuICAgICAgICBvbkRpc2FibGUgPSB2YXJzLm9uRGlzYWJsZSxcbiAgICAgICAgb25DbGljayA9IHZhcnMub25DbGljayxcbiAgICAgICAgc2Nyb2xsU3BlZWQgPSB2YXJzLnNjcm9sbFNwZWVkLFxuICAgICAgICBjYXB0dXJlID0gdmFycy5jYXB0dXJlLFxuICAgICAgICBhbGxvd0NsaWNrcyA9IHZhcnMuYWxsb3dDbGlja3MsXG4gICAgICAgIGxvY2tBeGlzID0gdmFycy5sb2NrQXhpcyxcbiAgICAgICAgb25Mb2NrQXhpcyA9IHZhcnMub25Mb2NrQXhpcztcbiAgICB0aGlzLnRhcmdldCA9IHRhcmdldCA9IF9nZXRUYXJnZXQodGFyZ2V0KSB8fCBfZG9jRWw7XG4gICAgdGhpcy52YXJzID0gdmFycztcbiAgICBpZ25vcmUgJiYgKGlnbm9yZSA9IGdzYXAudXRpbHMudG9BcnJheShpZ25vcmUpKTtcbiAgICB0b2xlcmFuY2UgPSB0b2xlcmFuY2UgfHwgMWUtOTtcbiAgICBkcmFnTWluaW11bSA9IGRyYWdNaW5pbXVtIHx8IDA7XG4gICAgd2hlZWxTcGVlZCA9IHdoZWVsU3BlZWQgfHwgMTtcbiAgICBzY3JvbGxTcGVlZCA9IHNjcm9sbFNwZWVkIHx8IDE7XG4gICAgdHlwZSA9IHR5cGUgfHwgXCJ3aGVlbCx0b3VjaCxwb2ludGVyXCI7XG4gICAgZGVib3VuY2UgPSBkZWJvdW5jZSAhPT0gZmFsc2U7XG4gICAgbGluZUhlaWdodCB8fCAobGluZUhlaWdodCA9IHBhcnNlRmxvYXQoX3dpbi5nZXRDb21wdXRlZFN0eWxlKF9ib2R5KS5saW5lSGVpZ2h0KSB8fCAyMik7IC8vIG5vdGU6IGJyb3dzZXIgbWF5IHJlcG9ydCBcIm5vcm1hbFwiLCBzbyBkZWZhdWx0IHRvIDIyLlxuXG4gICAgdmFyIGlkLFxuICAgICAgICBvblN0b3BEZWxheWVkQ2FsbCxcbiAgICAgICAgZHJhZ2dlZCxcbiAgICAgICAgbW92ZWQsXG4gICAgICAgIHdoZWVsZWQsXG4gICAgICAgIGxvY2tlZCxcbiAgICAgICAgYXhpcyxcbiAgICAgICAgc2VsZiA9IHRoaXMsXG4gICAgICAgIHByZXZEZWx0YVggPSAwLFxuICAgICAgICBwcmV2RGVsdGFZID0gMCxcbiAgICAgICAgcGFzc2l2ZSA9IHZhcnMucGFzc2l2ZSB8fCAhcHJldmVudERlZmF1bHQsXG4gICAgICAgIHNjcm9sbEZ1bmNYID0gX2dldFNjcm9sbEZ1bmModGFyZ2V0LCBfaG9yaXpvbnRhbCksXG4gICAgICAgIHNjcm9sbEZ1bmNZID0gX2dldFNjcm9sbEZ1bmModGFyZ2V0LCBfdmVydGljYWwpLFxuICAgICAgICBzY3JvbGxYID0gc2Nyb2xsRnVuY1goKSxcbiAgICAgICAgc2Nyb2xsWSA9IHNjcm9sbEZ1bmNZKCksXG4gICAgICAgIGxpbWl0VG9Ub3VjaCA9IH50eXBlLmluZGV4T2YoXCJ0b3VjaFwiKSAmJiAhfnR5cGUuaW5kZXhPZihcInBvaW50ZXJcIikgJiYgX2V2ZW50VHlwZXNbMF0gPT09IFwicG9pbnRlcmRvd25cIixcbiAgICAgICAgLy8gZm9yIGRldmljZXMgdGhhdCBhY2NvbW1vZGF0ZSBtb3VzZSBldmVudHMgYW5kIHRvdWNoIGV2ZW50cywgd2UgbmVlZCB0byBkaXN0aW5ndWlzaC5cbiAgICBpc1ZpZXdwb3J0ID0gX2lzVmlld3BvcnQodGFyZ2V0KSxcbiAgICAgICAgb3duZXJEb2MgPSB0YXJnZXQub3duZXJEb2N1bWVudCB8fCBfZG9jLFxuICAgICAgICBkZWx0YVggPSBbMCwgMCwgMF0sXG4gICAgICAgIC8vIHdoZWVsLCBzY3JvbGwsIHBvaW50ZXIvdG91Y2hcbiAgICBkZWx0YVkgPSBbMCwgMCwgMF0sXG4gICAgICAgIG9uQ2xpY2tUaW1lID0gMCxcbiAgICAgICAgY2xpY2tDYXB0dXJlID0gZnVuY3Rpb24gY2xpY2tDYXB0dXJlKCkge1xuICAgICAgcmV0dXJuIG9uQ2xpY2tUaW1lID0gX2dldFRpbWUoKTtcbiAgICB9LFxuICAgICAgICBfaWdub3JlQ2hlY2sgPSBmdW5jdGlvbiBfaWdub3JlQ2hlY2soZSwgaXNQb2ludGVyT3JUb3VjaCkge1xuICAgICAgcmV0dXJuIChzZWxmLmV2ZW50ID0gZSkgJiYgaWdub3JlICYmIH5pZ25vcmUuaW5kZXhPZihlLnRhcmdldCkgfHwgaXNQb2ludGVyT3JUb3VjaCAmJi
1BsaW1pdFRvVG91Y2ggJiYgZS5wb2ludGVyVHlwZSAhPT0gXCJ0b3VjaFwiIHx8IGlnbm9yZUNoZWNrICYmIGlnbm9yZUNoZWNrKGUsIGlzUG9pbnRlck9yVG91Y2gpO1xuICAgIH0sXG4gICAgICAgIG9uU3RvcEZ1bmMgPSBmdW5jdGlvbiBvblN0b3BGdW5jKCkge1xuICAgICAgc2VsZi5fdngucmVzZXQoKTtcblxuICAgICAgc2VsZi5fdnkucmVzZXQoKTtcblxuICAgICAgb25TdG9wRGVsYXllZENhbGwucGF1c2UoKTtcbiAgICAgIG9uU3RvcCAmJiBvblN0b3Aoc2VsZik7XG4gICAgfSxcbiAgICAgICAgdXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKCkge1xuICAgICAgdmFyIGR4ID0gc2VsZi5kZWx0YVggPSBfZ2V0QWJzb2x1dGVNYXgoZGVsdGFYKSxcbiAgICAgICAgICBkeSA9IHNlbGYuZGVsdGFZID0gX2dldEFic29sdXRlTWF4KGRlbHRhWSksXG4gICAgICAgICAgY2hhbmdlZFggPSBNYXRoLmFicyhkeCkgPj0gdG9sZXJhbmNlLFxuICAgICAgICAgIGNoYW5nZWRZID0gTWF0aC5hYnMoZHkpID49IHRvbGVyYW5jZTtcblxuICAgICAgb25DaGFuZ2UgJiYgKGNoYW5nZWRYIHx8IGNoYW5nZWRZKSAmJiBvbkNoYW5nZShzZWxmLCBkeCwgZHksIGRlbHRhWCwgZGVsdGFZKTsgLy8gaW4gU2Nyb2xsVHJpZ2dlci5ub3JtYWxpemVTY3JvbGwoKSwgd2UgbmVlZCB0byBrbm93IGlmIGl0IHdhcyB0b3VjaC9wb2ludGVyIHNvIHdlIG5lZWQgYWNjZXNzIHRvIHRoZSBkZWx0YVgvZGVsdGFZIEFycmF5cyBiZWZvcmUgd2UgY2xlYXIgdGhlbSBvdXQuXG5cbiAgICAgIGlmIChjaGFuZ2VkWCkge1xuICAgICAgICBvblJpZ2h0ICYmIHNlbGYuZGVsdGFYID4gMCAmJiBvblJpZ2h0KHNlbGYpO1xuICAgICAgICBvbkxlZnQgJiYgc2VsZi5kZWx0YVggPCAwICYmIG9uTGVmdChzZWxmKTtcbiAgICAgICAgb25DaGFuZ2VYICYmIG9uQ2hhbmdlWChzZWxmKTtcbiAgICAgICAgb25Ub2dnbGVYICYmIHNlbGYuZGVsdGFYIDwgMCAhPT0gcHJldkRlbHRhWCA8IDAgJiYgb25Ub2dnbGVYKHNlbGYpO1xuICAgICAgICBwcmV2RGVsdGFYID0gc2VsZi5kZWx0YVg7XG4gICAgICAgIGRlbHRhWFswXSA9IGRlbHRhWFsxXSA9IGRlbHRhWFsyXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFuZ2VkWSkge1xuICAgICAgICBvbkRvd24gJiYgc2VsZi5kZWx0YVkgPiAwICYmIG9uRG93bihzZWxmKTtcbiAgICAgICAgb25VcCAmJiBzZWxmLmRlbHRhWSA8IDAgJiYgb25VcChzZWxmKTtcbiAgICAgICAgb25DaGFuZ2VZICYmIG9uQ2hhbmdlWShzZWxmKTtcbiAgICAgICAgb25Ub2dnbGVZICYmIHNlbGYuZGVsdGFZIDwgMCAhPT0gcHJldkRlbHRhWSA8IDAgJiYgb25Ub2dnbGVZKHNlbGYpO1xuICAgICAgICBwcmV2RGVsdGFZID0gc2VsZi5kZWx0YVk7XG4gICAgICAgIGRlbHRhWVswXSA9IGRlbHRhWVsxXSA9IGRlbHRhWVsyXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb3ZlZCB8fCBkcmFnZ2VkKSB7XG4gICAgICAgIG9uTW92ZSAmJiBvbk1vdmUoc2VsZik7XG5cbiAgICAgICAgaWYgKGRyYWdnZWQpIHtcbiAgICAgICAgICBvbkRyYWcoc2VsZik7XG4gICAgICAgICAgZHJhZ2dlZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgbW92ZWQgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgbG9ja2VkICYmICEobG9ja2VkID0gZmFsc2UpICYmIG9uTG9ja0F4aXMgJiYgb25Mb2NrQXhpcyhzZWxmKTtcblxuICAgICAgaWYgKHdoZWVsZWQpIHtcbiAgICAgICAgb25XaGVlbChzZWxmKTtcbiAgICAgICAgd2hlZWxlZCA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZCA9IDA7XG4gICAgfSxcbiAgICAgICAgb25EZWx0YSA9IGZ1bmN0aW9uIG9uRGVsdGEoeCwgeSwgaW5kZXgpIHtcbiAgICAgIGRlbHRhWFtpbmRleF0gKz0geDtcbiAgICAgIGRlbHRhWVtpbmRleF0gKz0geTtcblxuICAgICAgc2VsZi5fdngudXBkYXRlKHgpO1xuXG4gICAgICBzZWxmLl92eS51cGRhdGUoeSk7XG5cbiAgICAgIGRlYm91bmNlID8gaWQgfHwgKGlkID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHVwZGF0ZSkpIDogdXBkYXRlKCk7XG4gICAgfSxcbiAgICAgICAgb25Ub3VjaE9yUG9pbnRlckRlbHRhID0gZnVuY3Rpb24gb25Ub3VjaE9yUG9pbnRlckRlbHRhKHgsIHkpIHtcbiAgICAgIGlmIChsb2NrQXhpcyAmJiAhYXhpcykge1xuICAgICAgICBzZWxmLmF4aXMgPSBheGlzID0gTWF0aC5hYnMoeCkgPiBNYXRoLmFicyh5KSA/IFwieFwiIDogXCJ5XCI7XG4gICAgICAgIGxvY2tlZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChheGlzICE9PSBcInlcIikge1xuICAgICAgICBkZWx0YVhbMl0gKz0geDtcblxuICAgICAgICBzZWxmLl92eC51cGRhdGUoeCwgdHJ1ZSk7IC8vIHVwZGF0ZSB0aGUgdmVsb2NpdHkgYXMgZnJlcXVlbnRseSBhcyBwb3NzaWJsZSBpbnN0ZWFkIG9mIGluIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gc28gdGhhdCB2ZXJ5IHF1aWNrIHRvdWNoLXNjcm9sbHMgKGZsaWNrcykgZmVlbCBuYXR1cmFsLiBJZiBpdCdzIHRoZSBtb3VzZS90b3VjaC9wb2ludGVyLCBmb3JjZSBpdCBzbyB0aGF0IHdlIGdldCBzbmFwcHkvYWNjdXJhdGUgbW9tZW50dW0gc2Nyb2xsLlxuXG4gICAgICB9XG5cbiAgICAgIGlmIChheGlzICE9PSBcInhcIikge1xuICAgICAgICBkZWx0YVlbMl0gKz0geTtcblxuICAgICAgICBzZWxmLl92eS51cGRhdGUoeSwgdHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIGRlYm91bmNlID8gaWQgfHwgKGlkID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHVwZGF0ZSkpIDogdXBkYXRlKCk7XG4gICAgfSxcbiAgICAgICAgX29uRHJhZyA9IGZ1bmN0aW9uIF9vbkRyYWcoZSkge1xuICAgICAgaWYgKF9pZ25vcmVDaGVjayhlLCAxKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGUgPSBfZ2V0RXZlbnQoZSwgcHJldmVudERlZmF1bHQpO1xuICAgICAgdmFyIHggPSBlLmNsaWVudFgsXG4gICAgICAgICAgeSA9IGUuY2xpZW50WSxcbiAgICAgICAgICBkeCA9IHggLSBzZWxmLngsXG4gICAgICAgICAgZHkgPSB5IC0gc2VsZi55LFxuICAgICAgICAgIGlzRHJhZ2dpbmcgPSBzZWxmLmlzRHJhZ2dpbmc7XG4gICAgICBzZWxmLnggPSB4O1xuICAgICAgc2VsZi55ID0geTtcblxuICAgICAgaWYgKGlzRHJhZ2dpbmcgfHwgTWF0aC5hYnMoc2VsZi5zdGFydFggLSB4KSA+PSBkcmFnTWluaW11bSB8fCBNYXRoLmFicyhzZWxmLnN0YXJ0WSAtIHkpID49IGRyYWdNaW5pbXVtKSB7XG4gICAgICAgIG9uRHJhZyAmJiAoZHJhZ2dlZCA9IHRydWUpO1xuICAgICAgICBpc0RyYWdnaW5nIH
1x8IChzZWxmLmlzRHJhZ2dpbmcgPSB0cnVlKTtcbiAgICAgICAgb25Ub3VjaE9yUG9pbnRlckRlbHRhKGR4LCBkeSk7XG4gICAgICAgIGlzRHJhZ2dpbmcgfHwgb25EcmFnU3RhcnQgJiYgb25EcmFnU3RhcnQoc2VsZik7XG4gICAgICB9XG4gICAgfSxcbiAgICAgICAgX29uUHJlc3MgPSBzZWxmLm9uUHJlc3MgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKF9pZ25vcmVDaGVjayhlLCAxKSB8fCBlICYmIGUuYnV0dG9uKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgc2VsZi5heGlzID0gYXhpcyA9IG51bGw7XG4gICAgICBvblN0b3BEZWxheWVkQ2FsbC5wYXVzZSgpO1xuICAgICAgc2VsZi5pc1ByZXNzZWQgPSB0cnVlO1xuICAgICAgZSA9IF9nZXRFdmVudChlKTsgLy8gbm90ZTogbWF5IG5lZWQgdG8gcHJldmVudERlZmF1bHQoPykgV29uJ3Qgc2lkZS1zY3JvbGwgb24gaU9TIFNhZmFyaSBpZiB3ZSBkbywgdGhvdWdoLlxuXG4gICAgICBwcmV2RGVsdGFYID0gcHJldkRlbHRhWSA9IDA7XG4gICAgICBzZWxmLnN0YXJ0WCA9IHNlbGYueCA9IGUuY2xpZW50WDtcbiAgICAgIHNlbGYuc3RhcnRZID0gc2VsZi55ID0gZS5jbGllbnRZO1xuXG4gICAgICBzZWxmLl92eC5yZXNldCgpOyAvLyBvdGhlcndpc2UgdGhlIHQyIG1heSBiZSBzdGFsZSBpZiB0aGUgdXNlciB0b3VjaGVzIGFuZCBmbGlja3Mgc3VwZXIgZmFzdCBhbmQgcmVsZWFzZXMgaW4gbGVzcyB0aGFuIDIgcmVxdWVzdEFuaW1hdGlvbkZyYW1lIHRpY2tzLCBjYXVzaW5nIHZlbG9jaXR5IHRvIGJlIDAuXG5cblxuICAgICAgc2VsZi5fdnkucmVzZXQoKTtcblxuICAgICAgX2FkZExpc3RlbmVyKGlzTm9ybWFsaXplciA/IHRhcmdldCA6IG93bmVyRG9jLCBfZXZlbnRUeXBlc1sxXSwgX29uRHJhZywgcGFzc2l2ZSwgdHJ1ZSk7XG5cbiAgICAgIHNlbGYuZGVsdGFYID0gc2VsZi5kZWx0YVkgPSAwO1xuICAgICAgb25QcmVzcyAmJiBvblByZXNzKHNlbGYpO1xuICAgIH0sXG4gICAgICAgIF9vblJlbGVhc2UgPSBzZWxmLm9uUmVsZWFzZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAoX2lnbm9yZUNoZWNrKGUsIDEpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgX3JlbW92ZUxpc3RlbmVyKGlzTm9ybWFsaXplciA/IHRhcmdldCA6IG93bmVyRG9jLCBfZXZlbnRUeXBlc1sxXSwgX29uRHJhZywgdHJ1ZSk7XG5cbiAgICAgIHZhciBpc1RyYWNraW5nRHJhZyA9ICFpc05hTihzZWxmLnkgLSBzZWxmLnN0YXJ0WSksXG4gICAgICAgICAgd2FzRHJhZ2dpbmcgPSBzZWxmLmlzRHJhZ2dpbmcsXG4gICAgICAgICAgaXNEcmFnTm90Q2xpY2sgPSB3YXNEcmFnZ2luZyAmJiAoTWF0aC5hYnMoc2VsZi54IC0gc2VsZi5zdGFydFgpID4gMyB8fCBNYXRoLmFicyhzZWxmLnkgLSBzZWxmLnN0YXJ0WSkgPiAzKSxcbiAgICAgICAgICAvLyBzb21lIHRvdWNoIGRldmljZXMgbmVlZCBzb21lIHdpZ2dsZSByb29tIGluIHRlcm1zIG9mIHNlbnNpbmcgY2xpY2tzIC0gdGhlIGZpbmdlciBtYXkgbW92ZSBhIGZldyBwaXhlbHMuXG4gICAgICBldmVudERhdGEgPSBfZ2V0RXZlbnQoZSk7XG5cbiAgICAgIGlmICghaXNEcmFnTm90Q2xpY2sgJiYgaXNUcmFja2luZ0RyYWcpIHtcbiAgICAgICAgc2VsZi5fdngucmVzZXQoKTtcblxuICAgICAgICBzZWxmLl92eS5yZXNldCgpOyAvL2lmIChwcmV2ZW50RGVmYXVsdCAmJiBhbGxvd0NsaWNrcyAmJiBzZWxmLmlzUHJlc3NlZCkgeyAvLyBjaGVjayBpc1ByZXNzZWQgYmVjYXVzZSBpbiBhIHJhcmUgZWRnZSBjYXNlLCB0aGUgaW5wdXRPYnNlcnZlciBpbiBTY3JvbGxUcmlnZ2VyIG1heSBzdG9wUHJvcGFnYXRpb24oKSBvbiB0aGUgcHJlc3MvZHJhZywgc28gdGhlIG9uUmVsZWFzZSBtYXkgZ2V0IGZpcmVkIHdpdGhvdXQgdGhlIG9uUHJlc3Mvb25EcmFnIGV2ZXIgZ2V0dGluZyBjYWxsZWQsIHRodXMgaXQgY291bGQgdHJpZ2dlciBhIGNsaWNrIHRvIG9jY3VyIG9uIGEgbGluayBhZnRlciBzY3JvbGwtZHJhZ2dpbmcgaXQuXG5cblxuICAgICAgICBpZiAocHJldmVudERlZmF1bHQgJiYgYWxsb3dDbGlja3MpIHtcbiAgICAgICAgICBnc2FwLmRlbGF5ZWRDYWxsKDAuMDgsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIHNvbWUgYnJvd3NlcnMgKGxpa2UgRmlyZWZveCkgd29uJ3QgdHJ1c3Qgc2NyaXB0LWdlbmVyYXRlZCBjbGlja3MsIHNvIGlmIHRoZSB1c2VyIHRyaWVzIHRvIGNsaWNrIG9uIGEgdmlkZW8gdG8gcGxheSBpdCwgZm9yIGV4YW1wbGUsIGl0IHNpbXBseSB3b24ndCB3b3JrLiBTaW5jZSBhIHJlZ3VsYXIgXCJjbGlja1wiIGV2ZW50IHdpbGwgbW9zdCBsaWtlbHkgYmUgZ2VuZXJhdGVkIGFueXdheSAob25lIHRoYXQgaGFzIGl0cyBpc1RydXN0ZWQgZmxhZyBzZXQgdG8gdHJ1ZSksIHdlIG11c3Qgc2xpZ2h0bHkgZGVsYXkgb3VyIHNjcmlwdC1nZW5lcmF0ZWQgY2xpY2sgc28gdGhhdCB0aGUgXCJyZWFsXCIvdHJ1c3RlZCBvbmUgaXMgcHJpb3JpdGl6ZWQuIFJlbWVtYmVyLCB3aGVuIHRoZXJlIGFyZSBkdXBsaWNhdGUgZXZlbnRzIGluIHF1aWNrIHN1Y2Nlc3Npb24sIHdlIHN1cHByZXNzIGFsbCBidXQgdGhlIGZpcnN0IG9uZS4gU29tZSBicm93c2VycyBkb24ndCBldmVuIHRyaWdnZXIgdGhlIFwicmVhbFwiIG9uZSBhdCBhbGwsIHNvIG91ciBzeW50aGV0aWMgb25lIGlzIGEgc2FmZXR5IHZhbHZlIHRoYXQgZW5zdXJlcyB0aGF0IG5vIG1hdHRlciB3aGF0LCBhIGNsaWNrIGV2ZW50IGRvZXMgZ2V0IGRpc3BhdGNoZWQuXG4gICAgICAgICAgICBpZiAoX2dldFRpbWUoKSAtIG9uQ2xpY2tUaW1lID4gMzAwICYmICFlLmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgICAgICAgICAgaWYgKGUudGFyZ2V0LmNsaWNrKSB7XG4gICAgICAgICAgICAgICAgLy9zb21lIGJyb3dzZXJzIChsaWtlIG1vYmlsZSBTYWZhcmkpIGRvbid0IHByb3Blcmx5IHRyaWdnZXIgdGhlIGNsaWNrIGV2ZW50XG4gICAgICAgICAgICAgICAgZS50YXJnZXQuY2xpY2soKTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChvd25lckRvYy5jcmVhdGVFdmVudCkge1xuICAgICAgICAgICAgICAgIHZhciBzeW50aGV0aWNFdmVudCA9IG93bmVyRG9jLmNyZWF0ZUV2ZW50KFwiTW91c2VFdmVudHNcIik7XG4gICAgICAgICAgICAgICAgc3ludGhldGljRXZlbnQuaW5p
1dE1vdXNlRXZlbnQoXCJjbGlja1wiLCB0cnVlLCB0cnVlLCBfd2luLCAxLCBldmVudERhdGEuc2NyZWVuWCwgZXZlbnREYXRhLnNjcmVlblksIGV2ZW50RGF0YS5jbGllbnRYLCBldmVudERhdGEuY2xpZW50WSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIDAsIG51bGwpO1xuICAgICAgICAgICAgICAgIGUudGFyZ2V0LmRpc3BhdGNoRXZlbnQoc3ludGhldGljRXZlbnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc2VsZi5pc0RyYWdnaW5nID0gc2VsZi5pc0dlc3R1cmluZyA9IHNlbGYuaXNQcmVzc2VkID0gZmFsc2U7XG4gICAgICBvblN0b3AgJiYgd2FzRHJhZ2dpbmcgJiYgIWlzTm9ybWFsaXplciAmJiBvblN0b3BEZWxheWVkQ2FsbC5yZXN0YXJ0KHRydWUpO1xuICAgICAgb25EcmFnRW5kICYmIHdhc0RyYWdnaW5nICYmIG9uRHJhZ0VuZChzZWxmKTtcbiAgICAgIG9uUmVsZWFzZSAmJiBvblJlbGVhc2Uoc2VsZiwgaXNEcmFnTm90Q2xpY2spO1xuICAgIH0sXG4gICAgICAgIF9vbkdlc3R1cmVTdGFydCA9IGZ1bmN0aW9uIF9vbkdlc3R1cmVTdGFydChlKSB7XG4gICAgICByZXR1cm4gZS50b3VjaGVzICYmIGUudG91Y2hlcy5sZW5ndGggPiAxICYmIChzZWxmLmlzR2VzdHVyaW5nID0gdHJ1ZSkgJiYgb25HZXN0dXJlU3RhcnQoZSwgc2VsZi5pc0RyYWdnaW5nKTtcbiAgICB9LFxuICAgICAgICBfb25HZXN0dXJlRW5kID0gZnVuY3Rpb24gX29uR2VzdHVyZUVuZCgpIHtcbiAgICAgIHJldHVybiAoc2VsZi5pc0dlc3R1cmluZyA9IGZhbHNlKSB8fCBvbkdlc3R1cmVFbmQoc2VsZik7XG4gICAgfSxcbiAgICAgICAgb25TY3JvbGwgPSBmdW5jdGlvbiBvblNjcm9sbChlKSB7XG4gICAgICBpZiAoX2lnbm9yZUNoZWNrKGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHggPSBzY3JvbGxGdW5jWCgpLFxuICAgICAgICAgIHkgPSBzY3JvbGxGdW5jWSgpO1xuICAgICAgb25EZWx0YSgoeCAtIHNjcm9sbFgpICogc2Nyb2xsU3BlZWQsICh5IC0gc2Nyb2xsWSkgKiBzY3JvbGxTcGVlZCwgMSk7XG4gICAgICBzY3JvbGxYID0geDtcbiAgICAgIHNjcm9sbFkgPSB5O1xuICAgICAgb25TdG9wICYmIG9uU3RvcERlbGF5ZWRDYWxsLnJlc3RhcnQodHJ1ZSk7XG4gICAgfSxcbiAgICAgICAgX29uV2hlZWwgPSBmdW5jdGlvbiBfb25XaGVlbChlKSB7XG4gICAgICBpZiAoX2lnbm9yZUNoZWNrKGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZSA9IF9nZXRFdmVudChlLCBwcmV2ZW50RGVmYXVsdCk7XG4gICAgICBvbldoZWVsICYmICh3aGVlbGVkID0gdHJ1ZSk7XG4gICAgICB2Y
1XIgbXVsdGlwbGllciA9IChlLmRlbHRhTW9kZSA9PT0gMSA/IGxpbmVIZWlnaHQgOiBlLmRlbHRhTW9kZSA9PT0gMiA/IF93aW4uaW5uZXJIZWlnaHQgOiAxKSAqIHdoZWVsU3BlZWQ7XG4gICAgICBvbkRlbHRhKGUuZGVsdGFYICogbXVsdGlwbGllciwgZS5kZWx0YVkgKiBtdWx0aXBsaWVyLCAwKTtcbiAgICAgIG9uU3RvcCAmJiAhaXNOb3JtYWxpemVyICYmIG9uU3RvcERlbGF5ZWRDYWxsLnJlc3RhcnQodHJ1ZSk7XG4gICAgfSxcbiAgICAgICAgX29uTW92ZSA9IGZ1bmN0aW9uIF9vbk1vdmUoZSkge1xuICAgICAgaWYgKF9pZ25vcmVDaGVjayhlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciB4ID0gZS5jbGllbnRYLFxuICAgICAgICAgIHkgPSBlLmNsaWVudFksXG4gICAgICAgICAgZHggPSB4IC0gc2VsZi54LFxuICAgICAgICAgIGR5ID0geSAtIHNlbGYueTtcbiAgICAgIHNlbGYueCA9IHg7XG4gICAgICBzZWxmLnkgPSB5O1xuICAgICAgbW92ZWQgPSB0cnVlO1xuICAgICAgb25TdG9wICYmIG9uU3RvcERlbGF5ZWRDYWxsLnJlc3RhcnQodHJ1ZSk7XG4gICAgICAoZHggfHwgZHkpICYmIG9uVG91Y2hPclBvaW50ZXJEZWx0YShkeCwgZHkpO1xuICAgIH0sXG4gICAgICAgIF9vbkhvdmVyID0gZnVuY3Rpb24gX29uSG92ZXIoZSkge1xuICAgICAgc2VsZi5ldmVudCA9IGU7XG4gICAgICBvbkhvdmVyKHNlbGYpO1xuICAgIH0sXG4gICAgICAgIF9vbkhvdmVyRW5kID0gZnVuY3Rpb24gX29uSG92ZXJFbmQoZSkge1xuICAgICAgc2VsZi5ldmVudCA9IGU7XG4gICAgICBvbkhvdmVyRW5kKHNlbGYpO1xuICAgIH0sXG4gICAgICAgIF9vbkNsaWNrID0gZnVuY3Rpb24gX29uQ2xpY2soZSkge1xuICAgICAgcmV0dXJuIF9pZ25vcmVDaGVjayhlKSB8fCBfZ2V0RXZlbnQoZSwgcHJldmVudERlZmF1bHQpICYmIG9uQ2xpY2soc2VsZik7XG4gICAgfTtcblxuICAgIG9uU3RvcERlbGF5ZWRDYWxsID0gc2VsZi5fZGMgPSBnc2FwLmRlbGF5ZWRDYWxsKG9uU3RvcERlbGF5IHx8IDAuMjUsIG9uU3RvcEZ1bmMpLnBhdXNlKCk7XG4gICAgc2VsZi5kZWx0YVggPSBzZWxmLmRlbHRhWSA9IDA7XG4gICAgc2VsZi5fdnggPSBfZ2V0VmVsb2NpdHlQcm9wKDAsIDUwLCB0cnVlKTtcbiAgICBzZWxmLl92eSA9IF9nZXRWZWxvY2l0eVByb3AoMCwgNTAsIHRydWUpO1xuICAgIHNlbGYuc2Nyb2xsWCA9IHNjcm9sbEZ1bmNYO1xuICAgIHNlbGYuc2Nyb2xsWSA9IHNjcm9sbEZ1bmNZO1xuICAgIHNlbGYuaXNEcmFnZ2luZyA9IHNlbGYuaXNHZXN0dXJpbmcgPSBzZWxmLmlzUHJlc3NlZCA9IGZhbHNlO1xuXG4gICAgX2NvbnRleHQodGhpcyk7XG5cbiAgICBzZWxmLmVuYWJsZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAoIXNlbGYuaXNFbmFibGVkKSB7XG4gICAgICAgIF9hZGRMaXN0ZW5lcihpc1ZpZXdwb3J0ID8gb3duZXJEb2MgOiB0YXJnZXQsIFwic2Nyb2xsXCIsIF9vblNjcm9sbCk7XG5cbiAgICAgICAgdHlwZS5pbmRleE9mKFwic2Nyb2xsXCIpID49IDAgJiYgX2FkZExpc3RlbmVyKGlzVmlld3BvcnQgPyBvd25lckRvYyA6IHRhcmdldCwgXCJzY3JvbGxcIiwgb25TY3JvbGwsIHBhc3NpdmUsIGNhcHR1cmUpO1xuICAgICAgICB0eXBlLmluZGV4T2YoXCJ3aGVlbFwiKSA+PSAwICYmIF9hZGRMaXN0ZW5lcih0YXJnZXQsIFwid2hlZWxcIiwgX29uV2hlZWwsIHBhc3NpdmUsIGNhcHR1cmUpO1xuXG4gICAgICAgIGlmICh0eXBlLmluZGV4T2YoXCJ0b3VjaFwiKSA+PSAwICYmIF9pc1RvdWNoIHx8IHR5cGUuaW5kZXhPZihcInBvaW50ZXJcIikgPj0gMCkge1xuICAgICAgICAgIF9hZGRMaXN0ZW5lcih0YXJnZXQsIF9ldmVudFR5cGVzWzBdLCBfb25QcmVzcywgcGFzc2l2ZSwgY2FwdHVyZSk7XG5cbiAgICAgICAgICBfYWRkTGlzdGVuZXIob3duZXJEb2MsIF9ldmVudFR5cGVzWzJdLCBfb25SZWxlYXNlKTtcblxuICAgICAgICAgIF9hZGRMaXN0ZW5lcihvd25lckRvYywgX2V2ZW50VHlwZXNbM10sIF9vblJlbGVhc2UpO1xuXG4gICAgICAgICAgYWxsb3dDbGlja3MgJiYgX2FkZExpc3RlbmVyKHRhcmdldCwgXCJjbGlja1wiLCBjbGlja0NhcHR1cmUsIHRydWUsIHRydWUpO1xuICAgICAgICAgIG9uQ2xpY2sgJiYgX2FkZExpc3RlbmVyKHRhcmdldCwgXCJjbGlja1wiLCBfb25DbGljayk7XG4gICAgICAgICAgb25HZXN0dXJlU3RhcnQgJiYgX2FkZExpc3RlbmVyKG93bmVyRG9jLCBcImdlc3R1cmVzdGFydFwiLCBfb25HZXN0dXJlU3RhcnQpO1xuICAgICAgICAgIG9uR2VzdHVyZUVuZCAmJiBfYWRkTGlzdGVuZXIob3duZXJEb2MsIFwiZ2VzdHVyZWVuZFwiLCBfb25HZXN0dXJlRW5kKTtcbiAgICAgICAgICBvbkhvdmVyICYmIF9hZGRMaXN0ZW5lcih0YXJnZXQsIF9wb2ludGVyVHlwZSArIFwiZW50ZXJcIiwgX29uSG92ZXIpO1xuICAgICAgICAgIG9uSG92ZXJFbmQgJiYgX2FkZExpc3RlbmVyKHRhcmdldCwgX3BvaW50ZXJUeXBlICsgXCJsZWF2ZVwiLCBfb25Ib3ZlckVuZCk7XG4gICAgICAgICAgb25Nb3ZlICYmIF9hZGRMaXN0ZW5lcih0YXJnZXQsIF9wb2ludGVyVHlwZSArIFwibW92ZVwiLCBfb25Nb3ZlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYuaXNFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgZSAmJiBlLnR5cGUgJiYgX29uUHJlc3MoZSk7XG4gICAgICAgIG9uRW5hYmxlICYmIG9uRW5hYmxlKHNlbGYpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc2VsZjtcbiAgICB9O1xuXG4gICAgc2VsZi5kaXNhYmxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHNlbGYuaXNFbmFibGVkKSB7XG4gICAgICAgIC8vIG9ubHkgcmVtb3ZlIHRoZSBfb25TY3JvbGwgbGlzdGVuZXIgaWYgdGhlcmUgYXJlbid0IGFueSBvdGhlcnMgdGhhdCByZWx5IG9uIHRoZSBmdW5jdGlvbmFsaXR5LlxuICAgICAgICBfb2JzZXJ2ZXJzLmZpbHRlcihmdW5jdGlvbiAobykge1xuICAgICAgICAgIHJldHVybiBvICE9PSBzZWxmICYmIF9pc1ZpZXdwb3J0KG8udGFyZ2V0KTtcbiAgICAgICAgfSkubGVuZ3RoIHx8IF9yZW1vdmVMaXN0ZW5lcihpc1ZpZXdwb3J0ID8gb3duZXJEb2MgOiB0YXJnZXQsIFwic2Nyb2xsXCIsIF9vblNjcm9sbCk7XG5cbiAgICAgICAgaWYgKHNlbGYuaXNQcmVzc2VkKSB7XG4gICAgICAgICAgc2VsZi5fdngucmVzZXQoKTtcblxuICAgICAgICAgI
1HNlbGYuX3Z5LnJlc2V0KCk7XG5cbiAgICAgICAgICBfcmVtb3ZlTGlzdGVuZXIoaXNOb3JtYWxpemVyID8gdGFyZ2V0IDogb3duZXJEb2MsIF9ldmVudFR5cGVzWzFdLCBfb25EcmFnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIF9yZW1vdmVMaXN0ZW5lcihpc1ZpZXdwb3J0ID8gb3duZXJEb2MgOiB0YXJnZXQsIFwic2Nyb2xsXCIsIG9uU2Nyb2xsLCBjYXB0dXJlKTtcblxuICAgICAgICBfcmVtb3ZlTGlzdGVuZXIodGFyZ2V0LCBcIndoZWVsXCIsIF9vbldoZWVsLCBjYXB0dXJlKTtcblxuICAgICAgICBfcmVtb3ZlTGlzdGVuZXIodGFyZ2V0LCBfZXZlbnRUeXBlc1swXSwgX29uUHJlc3MsIGNhcHR1cmUpO1xuXG4gICAgICAgIF9yZW1vdmVMaXN0ZW5lcihvd25lckRvYywgX2V2ZW50VHlwZXNbMl0sIF9vblJlbGVhc2UpO1xuXG4gICAgICAgIF9yZW1vdmVMaXN0ZW5lcihvd25lckRvYywgX2V2ZW50VHlwZXNbM10sIF9vblJlbGVhc2UpO1xuXG4gICAgICAgIF9yZW1vdmVMaXN0ZW5lcih0YXJnZXQsIFwiY2xpY2tcIiwgY2xpY2tDYXB0dXJlLCB0cnVlKTtcblxuICAgICAgICBfcmVtb3ZlTGlzdGVuZXIodGFyZ2V0LCBcImNsaWNrXCIsIF9vbkNsaWNrKTtcblxuICAgICAgICBfcmVtb3ZlTGlzdGVuZXIob3duZXJEb2MsIFwiZ2VzdHVyZXN0YXJ0XCIsIF9vbkdlc3R1cmVTdGFydCk7XG5cbiAgICAgICAgX3JlbW92ZUxpc3RlbmVyKG93bmVyRG9jLCBcImdlc3R1cmVlbmRcIiwgX29uR2VzdHVyZUVuZCk7XG5cbiAgICAgICAgX3JlbW92ZUxpc3RlbmVyKHRhcmdldCwgX3BvaW50ZXJUeXBlICsgXCJlbnRlclwiLCBfb25Ib3Zlcik7XG5cbiAgICAgICAgX3JlbW92ZUxpc3RlbmVyKHRhcmdldCwgX3BvaW50ZXJUeXBlICsgXCJsZWF2ZVwiLCBfb25Ib3ZlckVuZCk7XG5cbiAgICAgICAgX3JlbW92ZUxpc3RlbmVyKHRhcmdldCwgX3BvaW50ZXJUeXBlICsgXCJtb3ZlXCIsIF9vbk1vdmUpO1xuXG4gICAgICAgIHNlbGYuaXNFbmFibGVkID0gc2VsZi5pc1ByZXNzZWQgPSBzZWxmLmlzRHJhZ2dpbmcgPSBmYWxzZTtcbiAgICAgICAgb25EaXNhYmxlICYmIG9uRGlzYWJsZShzZWxmKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgc2VsZi5raWxsID0gc2VsZi5yZXZlcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBzZWxmLmRpc2FibGUoKTtcblxuICAgICAgdmFyIGkgPSBfb2JzZXJ2ZXJzLmluZGV4T2Yoc2VsZik7XG5cbiAgICAgIGkgPj0gMCAmJiBfb2JzZXJ2ZXJzLnNwbGljZShpLCAxKTtcbiAgICAgIF9ub3JtYWxpemVyID09PSBzZWxmICYmIChfbm9ybWFsaXplciA9IDApO1xuICAgIH07XG5cbiAgICBfb2JzZXJ2ZXJzLnB1c2goc2VsZik7XG5cbiAgICBpc05vcm1hbGl6ZXIgJiYgX2lzVmlld3BvcnQodGFyZ2V0KSAmJiAoX25vcm1hbGl6ZXIgPSBzZWxmKTtcbiAgICBzZWxmLmVuYWJsZShldmVudCk7XG4gIH07XG5cbiAgX2NyZWF0ZUNsYXNzKE9ic2VydmVyLCBbe1xuICAgIGtleTogXCJ2ZWxvY2l0eVhcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl92eC5nZXRWZWxvY2l0eSgpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ2ZWxvY2l0eVlcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl92eS5nZXRWZWxvY2l0eSgpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBPYnNlcnZlcjtcbn0oKTtcbk9ic2VydmVyLnZlcnNpb24gPSBcIjMuMTIuNVwiO1xuXG5PYnNlcnZlci5jcmVhdGUgPSBmdW5jdGlvbiAodmFycykge1xuICByZXR1cm4gbmV3IE9ic2VydmVyKHZhcnMpO1xufTtcblxuT2JzZXJ2ZXIucmVnaXN0ZXIgPSBfaW5pdENvcmU7XG5cbk9ic2VydmVyLmdldEFsbCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIF9vYnNlcnZlcnMuc2xpY2UoKTtcbn07XG5cbk9ic2VydmVyLmdldEJ5SWQgPSBmdW5jdGlvbiAoaWQpIHtcbiAgcmV0dXJuIF9vYnNlcnZlcnMuZmlsdGVyKGZ1bmN0aW9uIChvKSB7XG4gICAgcmV0dXJuIG8udmFycy5pZCA9PT0gaWQ7XG4gIH0pWzBdO1xufTtcblxuX2dldEdTQVAoKSAmJiBnc2FwLnJlZ2lzdGVyUGx1Z2luKE9ic2VydmVyKTtcbmV4cG9ydCB7IE9ic2VydmVyIGFzIGRlZmF1bHQsIF9pc1ZpZXdwb3J0LCBfc2Nyb2xsZXJzLCBfZ2V0U2Nyb2xsRnVuYywgX2dldFByb3h5UHJvcCwgX3Byb3hpZXMsIF9nZXRWZWxvY2l0eVByb3AsIF92ZXJ0aWNhbCwgX2hvcml6b250YWwsIF9nZXRUYXJnZXQgfTsiLCIvKiFcbiAqIFNjcm9sbFRyaWdnZXIgMy4xMi41XG4gKiBodHRwczovL2dzYXAuY29tXG4gKlxuICogQGxpY2Vuc2UgQ29weXJpZ2h0IDIwMDgtMjAyNCwgR3JlZW5Tb2NrLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogU3ViamVjdCB0byB0aGUgdGVybXMgYXQgaHR0cHM6Ly9nc2FwLmNvbS9zdGFuZGFyZC1saWNlbnNlIG9yIGZvclxuICogQ2x1YiBHU0FQIG1lbWJlcnMsIHRoZSBhZ3JlZW1lbnQgaXNzdWVkIHdpdGggdGhhdCBtZW1iZXJzaGlwLlxuICogQGF1dGhvcjogSmFjayBEb3lsZSwgamFja0BncmVlbnNvY2suY29tXG4qL1xuXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuaW1wb3J0IHsgT2JzZXJ2ZXIsIF9nZXRUYXJnZXQsIF92ZXJ0aWNhbCwgX2hvcml6b250YWwsIF9zY3JvbGxlcnMsIF9wcm94aWVzLCBfZ2V0U2Nyb2xsRnVuYywgX2dldFByb3h5UHJvcCwgX2dldFZlbG9jaXR5UHJvcCB9IGZyb20gXCIuL09ic2VydmVyLmpzXCI7XG5cbnZhciBnc2FwLFxuICAgIF9jb3JlSW5pdHRlZCxcbiAgICBfd2luLFxuICAgIF9kb2MsXG4gICAgX2RvY0VsLFxuICAgIF9ib2R5LFxuICAgIF9yb290LFxuICAgIF9yZXNpemVEZWxheSxcbiAgICBfdG9BcnJheSxcbiAgICBfY2xhbXAsXG4gICAgX3RpbWUyLFxuICAgIF9zeW5jSW50ZXJ2YWwsXG4gICAgX3JlZnJlc2hpbmcsXG4gICAgX3BvaW50ZXJJc0Rvd24sXG4gICAgX3RyYW5zZm9ybVByb3AsXG4gICAgX2ksXG4gICAgX3ByZXZXaWR0aCxcbiAgICBfcHJldkhlaWdodCxcbiAgICBfYXV0b1JlZnJlc2gsXG4gICAgX3NvcnQsXG4gICAgX3N1cHByZXNzT3ZlcndyaXRlcyxcbiAgICBfaWdub3JlUmVzaXplLFxuICAgIF9ub3JtYWxpem
1VyLFxuICAgIF9pZ25vcmVNb2JpbGVSZXNpemUsXG4gICAgX2Jhc2VTY3JlZW5IZWlnaHQsXG4gICAgX2Jhc2VTY3JlZW5XaWR0aCxcbiAgICBfZml4SU9TQnVnLFxuICAgIF9jb250ZXh0LFxuICAgIF9zY3JvbGxSZXN0b3JhdGlvbixcbiAgICBfZGl2MTAwdmgsXG4gICAgXzEwMHZoLFxuICAgIF9pc1JldmVydGVkLFxuICAgIF9jbGFtcGluZ01heCxcbiAgICBfbGltaXRDYWxsYmFja3MsXG4gICAgLy8gaWYgdHJ1ZSwgd2UnbGwgb25seSB0cmlnZ2VyIGNhbGxiYWNrcyBpZiB0aGUgYWN0aXZlIHN0YXRlIHRvZ2dsZXMsIHNvIGlmIHlvdSBzY3JvbGwgaW1tZWRpYXRlbHkgcGFzdCBib3RoIHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiBhIFNjcm9sbFRyaWdnZXIgKHRodXMgaW5hY3RpdmUgdG8gaW5hY3RpdmUpLCBuZWl0aGVyIGl0cyBvbkVudGVyIG5vciBvbkxlYXZlIHdpbGwgYmUgY2FsbGVkLiBUaGlzIGlzIHVzZWZ1bCBkdXJpbmcgc3RhcnR1cC5cbl9zdGFydHVwID0gMSxcbiAgICBfZ2V0VGltZSA9IERhdGUubm93LFxuICAgIF90aW1lMSA9IF9nZXRUaW1lKCksXG4gICAgX2xhc3RTY3JvbGxUaW1lID0gMCxcbiAgICBfZW5hYmxlZCA9IDAsXG4gICAgX3BhcnNlQ2xhbXAgPSBmdW5jdGlvbiBfcGFyc2VDbGFtcCh2YWx1ZSwgdHlwZSwgc2VsZikge1xuICB2YXIgY2xhbXAgPSBfaXNTdHJpbmcodmFsdWUpICYmICh2YWx1ZS5zdWJzdHIoMCwgNikgPT09IFwiY2xhbXAoXCIgfHwgdmFsdWUuaW5kZXhPZihcIm1heFwiKSA+IC0xKTtcbiAgc2VsZltcIl9cIiArIHR5cGUgKyBcIkNsYW1wXCJdID0gY2xhbXA7XG4gIHJldHVybiBjbGFtcCA/IHZhbHVlLnN1YnN0cig2LCB2YWx1ZS5sZW5ndGggLSA3KSA6IHZhbHVlO1xufSxcbiAgICBfa2VlcENsYW1wID0gZnVuY3Rpb24gX2tlZXBDbGFtcCh2YWx1ZSwgY2xhbXApIHtcbiAgcmV0dXJuIGNsYW1wICYmICghX2lzU3RyaW5nKHZhbHVlKSB8fCB2YWx1ZS5zdWJzdHIoMCwgNikgIT09IFwiY2xhbXAoXCIpID8gXCJjbGFtcChcIiArIHZhbHVlICsgXCIpXCIgOiB2YWx1ZTtcbn0sXG4gICAgX3JhZkJ1Z0ZpeCA9IGZ1bmN0aW9uIF9yYWZCdWdGaXgoKSB7XG4gIHJldHVybiBfZW5hYmxlZCAmJiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoX3JhZkJ1Z0ZpeCk7XG59LFxuICAgIC8vIGluIHNvbWUgYnJvd3NlcnMgKGxpa2UgRmlyZWZveCksIHNjcmVlbiByZXBhaW50cyB3ZXJlbid0IGNvbnNpc3RlbnQgdW5sZXNzIHdlIGhhZCBTT01FVEhJTkcgcXVldWVkIHVwIGluIHJlcXVlc3RBbmltYXRpb25GcmFtZSgpISBTbyB0aGlzIGp1c3QgY3JlYXRlcyBhIHN1cGVyIHNpbXBsZSBsb29wIHRvIGtlZXAgaXQgYWxpdmUgYW5kIHNtb290aCBvdXQgcmVwYWludHMuXG5fcG9pbnRlckRvd25IYW5kbGVyID0gZnVuY3Rpb24gX3BvaW50ZXJEb3duSGFuZGxlcigpIHtcbiAgcmV0dXJuIF9wb2ludGVySXNEb3duID0gMTtcbn0sXG4gICAgX3BvaW50ZXJVcEhhbmRsZXIgPSBmdW5jdGlvbiBfcG9pbnRlclVwSGFuZGxlcigpIHtcbiAgcmV0dXJuIF9wb2ludGVySXNEb3duID0gMDtcbn0sXG4gICAgX3Bhc3NUaHJvdWdoID0gZnVuY3Rpb24gX3Bhc3NUaHJvdWdoKHYpIHtcbiAgcmV0dXJuIHY7XG59LFxuICAgIF9yb3VuZCA9IGZ1bmN0aW9uIF9yb3VuZCh2YWx1ZSkge1xuICByZXR1cm4gTWF0aC5yb3VuZCh2YWx1ZSAqIDEwMDAwMCkgLyAxMDAwMDAgfHwgMDtcbn0sXG4gICAgX3dpbmRvd0V4aXN0cyA9IGZ1bmN0aW9uIF93aW5kb3dFeGlzdHMoKSB7XG4gIHJldHVybiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiO1xufSxcbiAgICBfZ2V0R1NBUCA9IGZ1bmN0aW9uIF9nZXRHU0FQKCkge1xuICByZXR1cm4gZ3NhcCB8fCBfd2luZG93RXhpc3RzKCkgJiYgKGdzYXAgPSB3aW5kb3cuZ3NhcCkgJiYgZ3NhcC5yZWdpc3RlclBsdWdpbiAmJiBnc2FwO1xufSxcbiAgICBfaXNWaWV3cG9ydCA9IGZ1bmN0aW9uIF9pc1ZpZXdwb3J0KGUpIHtcbiAgcmV0dXJuICEhfl9yb290LmluZGV4T2YoZSk7XG59LFxuICAgIF9nZXRWaWV3cG9ydERpbWVuc2lvbiA9IGZ1bmN0aW9uIF9nZXRWaWV3cG9ydERpbWVuc2lvbihkaW1lbnNpb25Qcm9wZXJ0eSkge1xuICByZXR1cm4gKGRpbWVuc2lvblByb3BlcnR5ID09PSBcIkhlaWdodFwiID8gXzEwMHZoIDogX3dpbltcImlubmVyXCIgKyBkaW1lbnNpb25Qcm9wZXJ0eV0pIHx8IF9kb2NFbFtcImNsaWVudFwiICsgZGltZW5zaW9uUHJvcGVydHldIHx8IF9ib2R5W1wiY2xpZW50XCIgKyBkaW1lbnNpb25Qcm9wZXJ0eV07XG59LFxuICAgIF9nZXRCb3VuZHNGdW5jID0gZnVuY3Rpb24gX2dldEJvdW5kc0Z1bmMoZWxlbWVudCkge1xuICByZXR1cm4gX2dldFByb3h5UHJvcChlbGVtZW50LCBcImdldEJvdW5kaW5nQ2xpZW50UmVjdFwiKSB8fCAoX2lzVmlld3BvcnQoZWxlbWVudCkgPyBmdW5jdGlvbiAoKSB7XG4gICAgX3dpbk9mZnNldHMud2lkdGggPSBfd2luLmlubmVyV2lkdGg7XG4gICAgX3dpbk9mZnNldHMuaGVpZ2h0ID0gXzEwMHZoO1xuICAgIHJldHVybiBfd2luT2Zmc2V0cztcbiAgfSA6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX2dldEJvdW5kcyhlbGVtZW50KTtcbiAgfSk7XG59LFxuICAgIF9nZXRTaXplRnVuYyA9IGZ1bmN0aW9uIF9nZXRTaXplRnVuYyhzY3JvbGxlciwgaXNWaWV3cG9ydCwgX3JlZikge1xuICB2YXIgZCA9IF9yZWYuZCxcbiAgICAgIGQyID0gX3JlZi5kMixcbiAgICAgIGEgPSBfcmVmLmE7XG4gIHJldHVybiAoYSA9IF9nZXRQcm94eVByb3Aoc2Nyb2xsZXIsIFwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0XCIpKSA/IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYSgpW2RdO1xuICB9IDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoaXNWaWV3cG9ydCA/IF9nZXRWaWV3cG9ydERpbWVuc2lvbihkMikgOiBzY3JvbGxlcltcImNsaWVudFwiICsgZDJdKSB8fCAwO1xuICB9O1xufSxcbiAgICBfZ2V0T2Zmc2V0c0Z1bmMgPSBmdW5jdGlvbiBfZ2V0T2Zmc2V0c0Z1bmMoZWxlbWVudCwgaXNWaWV3cG9ydCkge1xuICByZXR1cm4gIWlzVmlld3BvcnQgfHwgfl9wcm94aWVzLmluZGV4T2YoZWxlbWVudCkgPyBfZ2V0Qm91bmRzRnVuYyhlbGVtZW50KSA6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3dpbk9mZnNldHM7XG4gIH07XG59LFxuICAgIF9tYXhTY3JvbGwgP
1SBmdW5jdGlvbiBfbWF4U2Nyb2xsKGVsZW1lbnQsIF9yZWYyKSB7XG4gIHZhciBzID0gX3JlZjIucyxcbiAgICAgIGQyID0gX3JlZjIuZDIsXG4gICAgICBkID0gX3JlZjIuZCxcbiAgICAgIGEgPSBfcmVmMi5hO1xuICByZXR1cm4gTWF0aC5tYXgoMCwgKHMgPSBcInNjcm9sbFwiICsgZDIpICYmIChhID0gX2dldFByb3h5UHJvcChlbGVtZW50LCBzKSkgPyBhKCkgLSBfZ2V0Qm91bmRzRnVuYyhlbGVtZW50KSgpW2RdIDogX2lzVmlld3BvcnQoZWxlbWVudCkgPyAoX2RvY0VsW3NdIHx8IF9ib2R5W3NdKSAtIF9nZXRWaWV3cG9ydERpbWVuc2lvbihkMikgOiBlbGVtZW50W3NdIC0gZWxlbWVudFtcIm9mZnNldFwiICsgZDJdKTtcbn0sXG4gICAgX2l0ZXJhdGVBdXRvUmVmcmVzaCA9IGZ1bmN0aW9uIF9pdGVyYXRlQXV0b1JlZnJlc2goZnVuYywgZXZlbnRzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgX2F1dG9SZWZyZXNoLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgKCFldmVudHMgfHwgfmV2ZW50cy5pbmRleE9mKF9hdXRvUmVmcmVzaFtpICsgMV0pKSAmJiBmdW5jKF9hdXRvUmVmcmVzaFtpXSwgX2F1dG9SZWZyZXNoW2kgKyAxXSwgX2F1dG9SZWZyZXNoW2kgKyAyXSk7XG4gIH1cbn0sXG4gICAgX2lzU3RyaW5nID0gZnVuY3Rpb24gX2lzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCI7XG59LFxuICAgIF9pc0Z1bmN0aW9uID0gZnVuY3Rpb24gX2lzRnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiO1xufSxcbiAgICBfaXNOdW1iZXIgPSBmdW5jdGlvbiBfaXNOdW1iZXIodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIjtcbn0sXG4gICAgX2lzT2JqZWN0ID0gZnVuY3Rpb24gX2lzT2JqZWN0KHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCI7XG59LFxuICAgIF9lbmRBbmltYXRpb24gPSBmdW5jdGlvbiBfZW5kQW5pbWF0aW9uKGFuaW1hdGlvbiwgcmV2ZXJzZWQsIHBhdXNlKSB7XG4gIHJldHVybiBhbmltYXRpb24gJiYgYW5pbWF0aW9uLnByb2dyZXNzKHJldmVyc2VkID8gMCA6IDEpICYmIHBhdXNlICYmIGFuaW1hdGlvbi5wYXVzZSgpO1xufSxcbiAgICBfY2FsbGJhY2sgPSBmdW5jdGlvbiBfY2FsbGJhY2soc2VsZiwgZnVuYykge1xuICBpZiAoc2VsZi5lbmFibGVkKSB7XG4gICAgdmFyIHJlc3VsdCA9IHNlbGYuX2N0eCA/IHNlbGYuX2N0eC5hZGQoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGZ1bmMoc2VsZik7XG4gICAgfSkgOiBmdW5jKHNlbGYpO1xuICAgIHJlc3VsdCAmJiByZXN1bHQudG90YWxUaW1lICYmIChzZWxmLmNhbGxiYWNrQW5pbWF0aW9uID0gcmVzdWx0KTtcbiAgfVxufSxcbiAgICBfYWJzID0gTWF0aC5hYnMsXG4gICAgX2xlZnQgPSBcImxlZnRcIixcbiAgICBfdG9wID0gXCJ0b3BcIixcbiAgICBfcmlnaHQgPSBcInJpZ2h0XCIsXG4gICAgX2JvdHRvbSA9IFwiYm90dG9tXCIsXG4gICAgX3dpZHRoID0gXCJ3aWR0aFwiLFxuICAgIF9oZWlnaHQgPSBcImhlaWdodFwiLFxuICAgIF9SaWdodCA9IFwiUmlnaHRcIixcbiAgICBfTGVmdCA9IFwiTGVmdFwiLFxuICAgIF9Ub3AgPSBcIlRvcFwiLFxuICAgIF9Cb3R0b20gPSBcIkJvdHRvbVwiLFxuICAgIF9wYWRkaW5nID0gXCJwYWRkaW5nXCIsXG4gICAgX21hcmdpbiA9IFwibWFyZ2luXCIsXG4gICAgX1dpZHRoID0gXCJXaWR0aFwiLFxuICAgIF9IZWlnaHQgPSBcIkhlaWdodFwiLFxuICAgIF9weCA9IFwicHhcIixcbiAgICBfZ2V0Q29tcHV0ZWRTdHlsZSA9IGZ1bmN0aW9uIF9nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIF93aW4uZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbn0sXG4gICAgX21ha2VQb3NpdGlvbmFibGUgPSBmdW5jdGlvbiBfbWFrZVBvc2l0aW9uYWJsZShlbGVtZW50KSB7XG4gIC8vIGlmIHRoZSBlbGVtZW50IGFscmVhZHkgaGFzIHBvc2l0aW9uOiBhYnNvbHV0ZSBvciBmaXhlZCwgbGVhdmUgdGhhdCwgb3RoZXJ3aXNlIG1ha2UgaXQgcG9zaXRpb246IHJlbGF0aXZlXG4gIHZhciBwb3NpdGlvbiA9IF9nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLnBvc2l0aW9uO1xuXG4gIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSBwb3NpdGlvbiA9PT0gXCJhYnNvbHV0ZVwiIHx8IHBvc2l0aW9uID09PSBcImZpeGVkXCIgPyBwb3NpdGlvbiA6IFwicmVsYXRpdmVcIjtcbn0sXG4gICAgX3NldERlZmF1bHRzID0gZnVuY3Rpb24gX3NldERlZmF1bHRzKG9iaiwgZGVmYXVsdHMpIHtcbiAgZm9yICh2YXIgcCBpbiBkZWZhdWx0cykge1xuICAgIHAgaW4gb2JqIHx8IChvYmpbcF0gPSBkZWZhdWx0c1twXSk7XG4gIH1cblxuICByZXR1cm4gb2JqO1xufSxcbiAgICBfZ2V0Qm91bmRzID0gZnVuY3Rpb24gX2dldEJvdW5kcyhlbGVtZW50LCB3aXRob3V0VHJhbnNmb3Jtcykge1xuICB2YXIgdHdlZW4gPSB3aXRob3V0VHJhbnNmb3JtcyAmJiBfZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KVtfdHJhbnNmb3JtUHJvcF0gIT09IFwibWF0cml4KDEsIDAsIDAsIDEsIDAsIDApXCIgJiYgZ3NhcC50byhlbGVtZW50LCB7XG4gICAgeDogMCxcbiAgICB5OiAwLFxuICAgIHhQZXJjZW50OiAwLFxuICAgIHlQZXJjZW50OiAwLFxuICAgIHJvdGF0aW9uOiAwLFxuICAgIHJvdGF0aW9uWDogMCxcbiAgICByb3RhdGlvblk6IDAsXG4gICAgc2NhbGU6IDEsXG4gICAgc2tld1g6IDAsXG4gICAgc2tld1k6IDBcbiAgfSkucHJvZ3Jlc3MoMSksXG4gICAgICBib3VuZHMgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB0d2VlbiAmJiB0d2Vlbi5wcm9ncmVzcygwKS5raWxsKCk7XG4gIHJldHVybiBib3VuZHM7XG59LFxuICAgIF9nZXRTaXplID0gZnVuY3Rpb24gX2dldFNpemUoZWxlbWVudCwgX3JlZjMpIHtcbiAgdmFyIGQyID0gX3JlZjMuZDI7XG4gIHJldHVybiBlbGVtZW50W1wib2Zmc2V0XCIgKyBkMl0gfHwgZWxlbWVudFtcImNsaWVudFwiICsgZDJdIHx8IDA7XG59LFxuICAgIF9nZXRMYWJlbFJhdGlvQXJyYXkgPSBmdW5jdGlvbiBfZ2V0TGFiZWxSYXRpb0FycmF5KHRpbWVsaW5lKSB7XG4gIHZhciBhID0gW10sXG4gICAgICBsYWJlbHMgPSB0aW1lbGluZS5sYWJlbHMsXG4gICAgICBkdXJhdGlvbiA9IHRpbWVsaW5lLmR1cmF0aW9uKCksXG4gICAgICBwO1xuXG4gIGZvciAocCBpbiBsYWJlbHMpIHtcbiAgICBhLnB1c2gobGFiZWxzW3BdIC8gZHVyYXRpb24pO1xuICB9XG5cbiAgcmV0dXJuIGE7XG59LFxuICAgIF9nZXRDbG9zZXN0TGFiZWwgPSBmdW5jdGlvbiBfZ2V0Q2xvc2VzdExhYmVsKGFuaW1hdGlvbikge1xuICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIGdzYXAudXRpbHMuc25hcChfZ2V0TGFiZWxSYXRpb0FycmF5KGFuaW1hdGlvbiksIHZhbHVlKTtcbiAgfTtcbn0sXG4gICAgX3NuYXBEaXJlY3Rpb25hbCA9IGZ1bmN0aW9uIF9zbmFwRGlyZWN0aW9uYWwoc25hcEluY3JlbWVudE9yQXJyYXkpIHtcbiAgdmFyIHNuYXAgPSBnc2FwLnV0aWxzLnNuYXAoc25hcEluY3JlbWVudE9yQXJyYXkpLFxuICAgICAgYSA9IEFycmF5LmlzQXJyYXkoc25hcEluY3JlbWVudE9yQXJyYXkpICYmIHNuYXBJbmNyZW1lbnRPckFycmF5LnNsaWNlKDApLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gYSAtIGI7XG4gIH0pO1xuICByZXR1cm4gYSA/IGZ1bmN0aW9uICh2YWx1ZSwgZGlyZWN0aW9uLCB0aHJlc2hvbGQpIHtcbiAgICBpZiAodGhyZXNob2xkID09PSB2b2lkIDApIHtcbiAgICAgIHRocmVzaG9sZCA9IDFlLTM7XG4gICAgfVxuXG4gICAgdmFyIGk7XG5cbiAgICBpZiAoIWRpcmVjdGlvbikge1xuICAgICAgcmV0dXJuIHNuYXAodmFsdWUpO1xuICAgIH1cblxuICAgIGlmIChkaXJlY3Rpb24gPiAwKSB7XG4gICAgICB2YWx1ZSAtPSB0aHJlc2hvbGQ7IC8vIHRvIGF2b2lkIHJvdW5kaW5nIGVycm9ycy4gSWYgd2UncmUgdG9vIHN0cmljdCwgaXQgbWlnaHQgc25hcCBmb3J3YXJkLCB0aGVuIGltbWVkaWF0ZWx5IGFnYWluLCBhbmQgYWdhaW4uXG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChhW2ldID49IHZhbHVlKSB7XG4gICAgICAgICAgcmV0dXJuIGFbaV07XG4gICAgICAgI
1H1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGFbaSAtIDFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpID0gYS5sZW5ndGg7XG4gICAgICB2YWx1ZSArPSB0aHJlc2hvbGQ7XG5cbiAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgaWYgKGFbaV0gPD0gdmFsdWUpIHtcbiAgICAgICAgICByZXR1cm4gYVtpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhWzBdO1xuICB9IDogZnVuY3Rpb24gKHZhbHVlLCBkaXJlY3Rpb24sIHRocmVzaG9sZCkge1xuICAgIGlmICh0aHJlc2hvbGQgPT09IHZvaWQgMCkge1xuICAgICAgdGhyZXNob2xkID0gMWUtMztcbiAgICB9XG5cbiAgICB2YXIgc25hcHBlZCA9IHNuYXAodmFsdWUpO1xuICAgIHJldHVybiAhZGlyZWN0aW9uIHx8IE1hdGguYWJzKHNuYXBwZWQgLSB2YWx1ZSkgPCB0aHJlc2hvbGQgfHwgc25hcHBlZCAtIHZhbHVlIDwgMCA9PT0gZGlyZWN0aW9uIDwgMCA/IHNuYXBwZWQgOiBzbmFwKGRpcmVjdGlvbiA8IDAgPyB2YWx1ZSAtIHNuYXBJbmNyZW1lbnRPckFycmF5IDogdmFsdWUgKyBzbmFwSW5jcmVtZW50T3JBcnJheSk7XG4gIH07XG59LFxuICAgIF9nZXRMYWJlbEF0RGlyZWN0aW9uID0gZnVuY3Rpb24gX2dldExhYmVsQXREaXJlY3Rpb24odGltZWxpbmUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgc3QpIHtcbiAgICByZXR1cm4gX3NuYXBEaXJlY3Rpb25hbChfZ2V0TGFiZWxSYXRpb0FycmF5KHRpbWVsaW5lKSkodmFsdWUsIHN0LmRpcmVjdGlvbik7XG4gIH07XG59LFxuICAgIF9tdWx0aUxpc3RlbmVyID0gZnVuY3Rpb24gX211bHRpTGlzdGVuZXIoZnVuYywgZWxlbWVudCwgdHlwZXMsIGNhbGxiYWNrKSB7XG4gIHJldHVybiB0eXBlcy5zcGxpdChcIixcIikuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgIHJldHVybiBmdW5jKGVsZW1lbnQsIHR5cGUsIGNhbGxiYWNrKTtcbiAgfSk7XG59LFxuICAgIF9hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIF9hZGRMaXN0ZW5lcihlbGVtZW50LCB0eXBlLCBmdW5jLCBub25QYXNzaXZlLCBjYXB0dXJlKSB7XG4gIHJldHVybiBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZnVuYywge1xuICAgIHBhc3NpdmU6ICFub25QYXNzaXZlLFxuICAgIGNhcHR1cmU6ICEhY2FwdHVyZVxuICB9KTtcbn0sXG4gICAgX3JlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24gX3JlbW92ZUxpc3RlbmVyKGVsZW1lbnQsIHR5cGUsIGZ1bmMsIGNhcHR1cmUpIHtcbiAgcmV0dXJuIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBmdW5jLCAhIWNhcHR1cmUpO1xufSxcbiAgICBfd2hlZWxMaXN0ZW5lciA9IGZ1bmN0aW9uIF93aGVlbExpc3RlbmVyKGZ1bmMsIGVsLCBzY3JvbGxGdW5jKSB7XG4gIHNjcm9sbEZ1bmMgPSBzY3JvbGxGdW5jICYmIHNjcm9sbEZ1bmMud2hlZWxIYW5kbGVyO1xuXG4gIGlmIChzY3JvbGxGdW5jKSB7XG4gICAgZnVuYyhlbCwgXCJ3aGVlbFwiLCBzY3JvbGxGdW5jKTtcbiAgICBmdW5jKGVsLCBcInRvdWNobW92ZVwiLCBzY3JvbGxGdW5jKTtcbiAgfVxufSxcbiAgICBfbWFya2VyRGVmYXVsdHMgPSB7XG4gIHN0YXJ0Q29sb3I6IFwiZ3JlZW5cIixcbiAgZW5kQ29sb3I6IFwicmVkXCIsXG4gIGluZGVudDogMCxcbiAgZm9udFNpemU6IFwiMTZweFwiLFxuICBmb250V2VpZ2h0OiBcIm5vcm1hbFwiXG59LFxuICAgIF9kZWZhdWx0cyA9IHtcbiAgdG9nZ2xlQWN0aW9uczogXCJwbGF5XCIsXG4gIGFudGljaXBhdGVQaW46IDBcbn0sXG4gICAgX2tleXdvcmRzID0ge1xuICB0b3A6IDAsXG4gIGxlZnQ6IDAsXG4gIGNlbnRlcjogMC41LFxuICBib3R0b206IDEsXG4gIHJpZ2h0OiAxXG59LFxuICAgIF9vZmZzZXRUb1B4ID0gZnVuY3Rpb24gX29mZnNldFRvUHgodmFsdWUsIHNpemUpIHtcbiAgaWYgKF9pc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgZXFJbmRleCA9IHZhbHVlLmluZGV4T2YoXCI9XCIpLFxuICAgICAgICByZWxhdGl2ZSA9IH5lcUluZGV4ID8gKyh2YWx1ZS5jaGFyQXQoZXFJbmRleCAtIDEpICsgMSkgKiBwYXJzZU
1Zsb2F0KHZhbHVlLnN1YnN0cihlcUluZGV4ICsgMSkpIDogMDtcblxuICAgIGlmICh+ZXFJbmRleCkge1xuICAgICAgdmFsdWUuaW5kZXhPZihcIiVcIikgPiBlcUluZGV4ICYmIChyZWxhdGl2ZSAqPSBzaXplIC8gMTAwKTtcbiAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyKDAsIGVxSW5kZXggLSAxKTtcbiAgICB9XG5cbiAgICB2YWx1ZSA9IHJlbGF0aXZlICsgKHZhbHVlIGluIF9rZXl3b3JkcyA/IF9rZXl3b3Jkc1t2YWx1ZV0gKiBzaXplIDogfnZhbHVlLmluZGV4T2YoXCIlXCIpID8gcGFyc2VGbG9hdCh2YWx1ZSkgKiBzaXplIC8gMTAwIDogcGFyc2VGbG9hdCh2YWx1ZSkgfHwgMCk7XG4gIH1cblxuICByZXR1cm4gdmFsdWU7XG59LFxuICAgIF9jcmVhdGVNYXJrZXIgPSBmdW5jdGlvbiBfY3JlYXRlTWFya2VyKHR5cGUsIG5hbWUsIGNvbnRhaW5lciwgZGlyZWN0aW9uLCBfcmVmNCwgb2Zmc2V0LCBtYXRjaFdpZHRoRWwsIGNvbnRhaW5lckFuaW1hdGlvbikge1xuICB2YXIgc3RhcnRDb2xvciA9IF9yZWY0LnN0YXJ0Q29sb3IsXG4gICAgICBlbmRDb2xvciA9IF9yZWY0LmVuZENvbG9yLFxuICAgICAgZm9udFNpemUgPSBfcmVmNC5mb250U2l6ZSxcbiAgICAgIGluZGVudCA9IF9yZWY0LmluZGVudCxcbiAgICAgIGZvbnRXZWlnaHQgPSBfcmVmNC5mb250V2VpZ2h0O1xuXG4gIHZhciBlID0gX2RvYy5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLFxuICAgICAgdXNlRml4ZWRQb3NpdGlvbiA9IF9pc1ZpZXdwb3J0KGNvbnRhaW5lcikgfHwgX2dldFByb3h5UHJvcChjb250YWluZXIsIFwicGluVHlwZVwiKSA9PT0gXCJmaXhlZFwiLFxuICAgICAgaXNTY3JvbGxlciA9IHR5cGUuaW5kZXhPZihcInNjcm9sbGVyXCIpICE9PSAtMSxcbiAgICAgIHBhcmVudCA9IHVzZUZpeGVkUG9zaXRpb24gPyBfYm9keSA6IGNvbnRhaW5lcixcbiAgICAgIGlzU3RhcnQgPSB0eXBlLmluZGV4T2YoXCJzdGFydFwiKSAhPT0gLTEsXG4gICAgICBjb2xvciA9IGlzU3RhcnQgPyBzdGFydENvbG9yIDogZW5kQ29sb3IsXG4gICAgICBjc3MgPSBcImJvcmRlci1jb2xvcjpcIiArIGNvbG9yICsgXCI7Zm9udC1zaXplOlwiICsgZm9udFNpemUgKyBcIjtjb2xvcjpcIiArIGNvbG9yICsgXCI7Zm9udC13ZWlnaHQ6XCIgKyBmb250V2VpZ2h0ICsgXCI7cG9pbnRlci1ldmVudHM6bm9uZTt3aGl0ZS1zcGFjZTpub3dyYXA7Zm9udC1mYW1pbHk6c2Fucy1zZXJpZixBcmlhbDt6LWluZGV4OjEwMDA7cGFkZGluZzo0cHggOHB4O2JvcmRlci13aWR0aDowO2JvcmRlci1zdHlsZTpzb2xpZDtcIjtcblxuICBjc3MgKz0gXCJwb3NpdGlvbjpcIiArICgoaXNTY3JvbGxlciB8fCBjb250YWluZXJBbmltYXRpb24pICYmIHVzZUZpeGVkUG9zaXRpb24gPyBcImZpeGVkO1wiIDogXCJhYnNvbHV0ZTtcIik7XG4gIChpc1Njcm9sbGVyIHx8IGNvbnRhaW5lckFuaW1hdGlvbiB8fCAhdXNlRml4ZWRQb3NpdGlvbikgJiYgKGNzcyArPSAoZGlyZWN0aW9uID09PSBfdmVydGljYWwgPyBfcmlnaHQgOiBfYm90dG9tKSArIFwiOlwiICsgKG9mZnNldCArIHBhcnNlRmxvYXQoaW5kZW50KSkgKyBcInB4O1wiKTtcbiAgbWF0Y2hXaWR0aEVsICYmIChjc3MgKz0gXCJib3gtc2l6aW5nOmJvcmRlci1ib3g7dGV4dC1hbGlnbjpsZWZ0O3dpZHRoOlwiICsgbWF0Y2hXaWR0aEVsLm9mZnNldFdpZHRoICsgXCJweDtcIik7XG4gIGUuX2lzU3RhcnQgPSBpc1N0YXJ0O1xuICBlLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwiZ3NhcC1tYXJrZXItXCIgKyB0eXBlICsgKG5hbWUgPyBcIiBtYXJrZXItXCIgKyBuYW1lIDogXCJcIikpO1xuICBlLnN0eWxlLmNzc1RleHQgPSBjc3M7XG4gIGUuaW5uZXJUZXh0ID0gbmFtZSB8fCBuYW1lID09PSAwID8gdHlwZSArIFwiLVwiICsgbmFtZSA6IHR5cGU7XG4gIHBhcmVudC5jaGlsZHJlblswXSA/IHBhcmVudC5pbnNlcnRCZWZvcmUoZSwgcGFyZW50LmNoaWxkcmVuWzBdKSA6IHBhcmVudC5hcHBlbmRDaGlsZChlKTtcbiAgZS5fb2Zmc2V0ID0gZVtcIm9mZnNldFwiICsgZGlyZWN0aW9uLm9wLmQyXTtcblxuICBfcG9zaXRpb25NYXJrZXIoZSwgMCwgZGlyZWN0aW9uLCBpc1N0YXJ0KTtcblxuICByZXR1cm4gZTtcbn0sXG4gICAgX3Bvc2l0aW9uTWFya2VyID0gZnVuY3Rpb24gX3Bvc2l0aW9uTWFya2VyKG1hcmtlciwgc3RhcnQsIGRpcmVjdGlvbiwgZmxpcHBlZCkge1xuICB2YXIgdmFycyA9IHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCJcbiAgfSxcbiAgICAgIHNpZGUgPSBkaXJlY3Rpb25bZmxpcHBlZCA/IFwib3MyXCIgOiBcInAyXCJdLFxuICAgICAgb3Bwb3NpdGVTaWRlID0gZGlyZWN0aW9uW2ZsaXBwZWQgPyBcInAyXCIgOiBcIm9zMlwiXTtcbiAgbWFya2VyLl9pc0ZsaXBwZWQgPSBmbGlwcGVkO1xuICB2YXJzW2RpcmVjdGlvbi5hICsgXCJQZXJjZW50XCJdID0gZmxpcHBlZCA/IC0xMDAgOiAwO1xuICB2YXJzW2RpcmVjdGlvbi5hXSA9IGZsaXBwZWQgPyBcIjFweFwiIDogMDtcbiAgdmFyc1tcImJvcmRlclwiICsgc2lkZSArIF9XaWR0aF0gPSAxO1xuICB2YXJzW1wiYm9yZGVyXCIgKyBvcHBvc2l0ZVNpZGUgKyBfV2lkdGhdID0gMDtcbiAgdmFyc1tkaXJlY3Rpb24ucF0gPSBzdGFydCArIFwicHhcIjtcbiAgZ3NhcC5zZXQobWFya2VyLCB2YXJzKTtcbn0sXG4gICAgX3RyaWdnZXJzID0gW10sXG4gICAgX2lkcyA9IHt9LFxuICAgIF9yYWZJRCxcbiAgICBfc3luYyA9IGZ1bmN0aW9uIF9zeW5jKCkge1xuICByZXR1cm4gX2dldFRpbWUoKSAtIF9sYXN0U2Nyb2xsVGltZSA+IDM0ICYmIChfcmFmSUQgfHwgKF9yYWZJRCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShfdXBkYXRlQWxsKSkpO1xufSxcbiAgICBfb25TY3JvbGwgPSBmdW5jdGlvbiBfb25TY3JvbGwoKSB7XG4gIC8vIHByZXZpb3VzbHksIHdlIHRyaWVkIHRvIG9wdGltaXplIHBlcmZvcm1hbmNlIGJ5IGJhdGNoaW5nL2RlZmVycmluZyB0byB0aGUgbmV4dCByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKSwgYnV0IGRpc2NvdmVyZWQgdGhhdCBTYWZhcmkgaGFzIGEgZmV3IGJ1Z3MgdGhhdCBtYWtlIHRoaXMgdW53b3JrYWJsZSAoZXNwZWNpYWxseSBvbiBpT1MpLiBTZWUgaHR0cHM6Ly9jb2RlcGVuLmlvL0dyZWVuU29jay9wZW4vMTZjNDM1YjEyZWYwOWMzODEyNTIwNDgxOGU3YjQ1ZmM/ZWRpdG9ycz0wMDEwIGFuZCBodHRwczovL2NvZGVwZW4uaW8vR3JlZW5Tb2NrL3Blbi9Kak94WXBRLzNkZDY1Y2NlYzVhNjBmMWQ4NjJjMzU1ZDg0ZDE0NTYyP2VkaXRvcnM9MDAxMCBhbmQgaHR0cHM6Ly9jb2RlcGVuLmlvL0dyZWVuU29jay9wZW4vRXhiclBOYS8wODdjZWYxOTdkYzM1NDQ1YTA5NTFlODkzNWM0MTUwMz9lZGl0b3JzPTAw
1MTBcbiAgaWYgKCFfbm9ybWFsaXplciB8fCAhX25vcm1hbGl6ZXIuaXNQcmVzc2VkIHx8IF9ub3JtYWxpemVyLnN0YXJ0WCA+IF9ib2R5LmNsaWVudFdpZHRoKSB7XG4gICAgLy8gaWYgdGhlIHVzZXIgaXMgZHJhZ2dpbmcgdGhlIHNjcm9sbGJhciwgYWxsb3cgaXQuXG4gICAgX3Njcm9sbGVycy5jYWNoZSsrO1xuXG4gICAgaWYgKF9ub3JtYWxpemVyKSB7XG4gICAgICBfcmFmSUQgfHwgKF9yYWZJRCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShfdXBkYXRlQWxsKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIF91cGRhdGVBbGwoKTsgLy8gU2FmYXJpIGluIHBhcnRpY3VsYXIgKG9uIGRlc2t0b3ApIE5FRURTIHRoZSBpbW1lZGlhdGUgdXBkYXRlIHJhdGhlciB0aGFuIHdhaXRpbmcgZm9yIGEgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCkgd2hlcmVhcyBpT1Mgc2VlbXMgdG8gYmVuZWZpdCBmcm9tIHdhaXRpbmcgZm9yIHRoZSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKSB0aWNrLCBhdCBsZWFzdCB3aGVuIG5vcm1hbGl6aW5nLiBTZWUgaHR0cHM6Ly9jb2RlcGVuLmlvL0dyZWVuU29jay9wZW4vcUJZb3pxTz9lZGl0b3JzPTAxMTBcblxuICAgIH1cblxuICAgIF9sYXN0U2Nyb2xsVGltZSB8fCBfZGlzcGF0Y2goXCJzY3JvbGxTdGFydFwiKTtcbiAgICBfbGFzdFNjcm9sbFRpbWUgPSBfZ2V0VGltZSgpO1xuICB9XG59LFxuICAgIF9zZXRCYXNlRGltZW5zaW9ucyA9IGZ1bmN0aW9uIF9zZXRCYXNlRGltZW5zaW9ucygpIHtcbiAgX2Jhc2VTY3JlZW5XaWR0aCA9IF93aW4uaW5uZXJXaWR0aDtcbiAgX2Jhc2VTY3JlZW5IZWlnaHQgPSBfd2luLmlubmVySGVpZ2h0O1xufSxcbiAgICBfb25SZXNpemUgPSBmdW5jdGlvbiBfb25SZXNpemUoKSB7XG4gIF9zY3JvbGxlcnMuY2FjaGUrKztcbiAgIV9yZWZyZXNoaW5nICYmICFfaWdub3JlUmVzaXplICYmICFfZG9jLmZ1bGxzY3JlZW5FbGVtZW50ICYmICFfZG9jLndlYmtpdEZ1bGxzY3JlZW5FbGVtZW50ICYmICghX2lnbm9yZU1vYmlsZVJlc2l6ZSB8fCBfYmFzZVNjcmVlbldpZHRoICE9PSBfd2luLmlubmVyV2lkdGggfHwgTWF0aC5hYnMoX3dpbi5pbm5lckhlaWdodCAtIF9iYXNlU2NyZWVuSGVpZ2h0KSA+IF93aW4uaW5uZXJIZWlnaHQgKiAwLjI1KSAmJiBfcmVzaXplRGVsYXkucmVzdGFydCh0cnVlKTtcbn0sXG4gICAgLy8gaWdub3JlIHJlc2l6ZXMgdHJpZ2dlcmVkIGJ5IHJlZnJlc2goKVxuX2xpc3RlbmVycyA9IHt9LFxuICAgIF9lbXB0eUFycmF5ID0gW10sXG4gICAgX3NvZnRSZWZyZXNoID0gZnVuY3Rpb24gX3NvZnRSZWZyZXNoKCkge1xuICByZXR1cm4gX3JlbW92ZUxpc3RlbmVyKFNjcm9sbFRyaWdnZXIsIFwic2Nyb2xsRW5kXCIsIF9zb2Z0UmVmcmVzaCkgfHwgX3JlZnJlc2hBbGwodHJ1ZSk7XG59LFxuICAgIF9kaXNwYXRjaCA9IGZ1bmN0aW9uIF9kaXNwYXRjaCh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzW3R5cGVdICYmIF9saXN0ZW5lcnNbdHlwZV0ubWFwKGZ1bmN0aW9uIChmKSB7XG4gICAgcmV0dXJuIGYoKTtcbiAgfSkgfHwgX2VtcHR5QXJyYXk7XG59LFxuICAgIF9zYXZlZFN0eWxlcyA9IFtdLFxuICAgIC8vIHdoZW4gU2Nyb2xsVHJpZ2dlci5zYXZlU3R5bGVzKCkgaXMgY2FsbGVkLCB0aGUgaW5saW5lIHN0eWxlcyBhcmUgcmVjb3JkZWQgaW4gdGhpcyBBcnJheSBpbiBhIHNlcXVlbnRpYWwgZm9ybWF0IGxpa2UgW2VsZW1lbnQsIGNzc1RleHQsIGdzQ2FjaGUsIG1lZGlhXS4gVGhpcyBrZWVwcyBpdCB2ZXJ5IG1lbW9yeS1lZmZpY2llbnQgYW5kIGZhc3QgdG8gaXRlcmF0ZSB0aHJvdWdoLlxuX3JldmVydFJlY29yZGVkID0gZnVuY3Rpb24gX3JldmVydFJlY29yZGVkKG1lZGlhKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgX3NhdmVkU3R5bGVzLmxlbmd0aDsgaSArPSA1KSB7XG4gICAgaWYgKCFtZWRpYSB8fCBfc2F2ZWRTdHlsZXNbaSArIDRdICYmIF9zYXZlZFN0eWxlc1tpICsgNF0ucXVlcnkgPT09IG1lZGlhKSB7XG4gICAgICBfc2F2ZWRTdHlsZXNbaV0uc3R5bGUuY3NzVGV4dCA9IF9zYXZlZFN0eWxlc1tpICsgMV07XG4gICAgICBfc2F2ZWRTdHlsZXNbaV0uZ2V0QkJveCAmJiBfc2F2ZWRTdHlsZXNbaV0uc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIF9zYXZlZFN0eWxlc1tpICsgMl0gfHwgXCJcIik7XG4gICAgICBfc2F2ZWRTdHlsZXNbaSArIDNdLnVuY2FjaGUgPSAxO1xuICAgIH1cbiAgfVxufSxcbiAgICBfcmV2ZXJ0QWxsID0gZnVuY3Rpb24gX3JldmVydEFsbChraWxsLCBtZWRpYSkge1xuICB2YXIgdHJpZ2dlcjtcblxuICBmb3IgKF9pID0gMDsgX2kgPCBfdHJpZ2dlcnMubGVuZ3RoOyBfaSsrKSB7XG4gICAgdHJpZ2dlciA9IF90cmlnZ2Vyc1tfaV07XG5cbiAgICBpZiAodHJpZ2dlciAmJiAoIW1lZGlhIHx8IHRyaWdnZXIuX2N0eCA9PT0gbWVkaWEpKSB7XG4gICAgICBpZiAoa2lsbCkge1xuICAgICAgICB0cmlnZ2VyLmtpbGwoMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cmlnZ2VyLnJldmVydCh0cnVlLCB0cnVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfaXNSZXZlcnRlZCA9IHRydWU7XG4gIG1lZGlhICYmIF9yZXZlcnRSZWNvcmRlZChtZWRpYSk7XG4gIG1lZGlhIHx8IF9kaXNwYXRjaChcInJldmVydFwiKTtcbn0sXG4gICAgX2NsZWFyU2Nyb2xsTWVtb3J5ID0gZnVuY3Rpb24gX2NsZWFyU2Nyb2xsTWVtb3J5KHNjcm9sbFJlc3RvcmF0aW9uLCBmb3JjZSkge1xuICAvLyB6ZXJvLW91dCBhbGwgdGhlIHJlY29yZGVkIHNjcm9sbCBwb3NpdGlvbnMuIERvbid0IHVzZSBfdHJpZ2dlcnMgYmVjYXVzZSBpZiwgZm9yIGV4YW1wbGUsIC5tYXRjaE1lZGlhKCkgaXMgdXNlZCB0byBjcmVhdGUgc29tZSBTY3JvbGxUcmlnZ2VycyBhbmQgdGhlbiB0aGUgdXNlciByZXNpemVzIGFuZCBpdCByZW1vdmVzIEFMTCBTY3JvbGxUcmlnZ2VycywgYW5kIHR
1oZW4gZ28gYmFjayB0byBhIHNpemUgd2hlcmUgdGhlcmUgYXJlIFNjcm9sbFRyaWdnZXJzLCBpdCB3b3VsZCBoYXZlIGtlcHQgdGhlIHBvc2l0aW9uKHMpIHNhdmVkIGZyb20gdGhlIGluaXRpYWwgc3RhdGUuXG4gIF9zY3JvbGxlcnMuY2FjaGUrKztcbiAgKGZvcmNlIHx8ICFfcmVmcmVzaGluZ0FsbCkgJiYgX3Njcm9sbGVycy5mb3JFYWNoKGZ1bmN0aW9uIChvYmopIHtcbiAgICByZXR1cm4gX2lzRnVuY3Rpb24ob2JqKSAmJiBvYmouY2FjaGVJRCsrICYmIChvYmoucmVjID0gMCk7XG4gIH0pO1xuICBfaXNTdHJpbmcoc2Nyb2xsUmVzdG9yYXRpb24pICYmIChfd2luLmhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSBfc2Nyb2xsUmVzdG9yYXRpb24gPSBzY3JvbGxSZXN0b3JhdGlvbik7XG59LFxuICAgIF9yZWZyZXNoaW5nQWxsLFxuICAgIF9yZWZyZXNoSUQgPSAwLFxuICAgIF9xdWV1ZVJlZnJlc2hJRCxcbiAgICBfcXVldWVSZWZyZXNoQWxsID0gZnVuY3Rpb24gX3F1ZXVlUmVmcmVzaEFsbCgpIHtcbiAgLy8gd2UgZG9uJ3Qgd2FudCB0byBjYWxsIF9yZWZyZXNoQWxsKCkgZXZlcnkgdGltZSB3ZSBjcmVhdGUgYSBuZXcgU2Nyb2xsVHJpZ2dlciAoZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMpIC0gaXQncyBiZXR0ZXIgdG8gYmF0Y2ggdGhlbS4gU29tZSBmcmFtZXdvcmtzIGR5bmFtaWNhbGx5IGxvYWQgY29udGVudCBhbmQgd2UgY2FuJ3QgcmVseSBvbiB0aGUgd2luZG93J3MgXCJsb2FkXCIgb3IgXCJET01Db250ZW50TG9hZGVkXCIgZXZlbnRzIHRvIHRyaWdnZXIgaXQuXG4gIGlmIChfcXVldWVSZWZyZXNoSUQgIT09IF9yZWZyZXNoSUQpIHtcbiAgICB2YXIgaWQgPSBfcXVldWVSZWZyZXNoSUQgPSBfcmVmcmVzaElEO1xuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gaWQgPT09IF9yZWZyZXNoSUQgJiYgX3JlZnJlc2hBbGwodHJ1ZSk7XG4gICAgfSk7XG4gIH1cbn0sXG4gICAgX3JlZnJlc2gxMDB2aCA9IGZ1bmN0aW9uIF9yZWZyZXNoMTAwdmgoKSB7XG4gIF9ib2R5LmFwcGVuZENoaWxkKF9kaXYxMDB2aCk7XG5cbiAgXzEwMHZoID0gIV9ub3JtYWxpemVyICYmIF9kaXYxMDB2aC5vZmZzZXRIZWlnaHQgfHwgX3dpbi5pbm5lckhlaWdodDtcblxuICBfYm9keS5yZW1vdmVDaGlsZChfZGl2MTAwdmgpO1xufSxcbiAgICBfaGlkZUFsbE1hcmtlcnMgPSBmdW5jdGlvbiBfaGlkZUFsbE1hcmtlcnMoaGlkZSkge1xuICByZXR1cm4gX3RvQXJyYXkoXCIuZ3NhcC1tYXJrZXItc3RhcnQsIC5nc2FwLW1hcmtlci1lbmQsIC5nc2FwLW1hcmtlci1zY3JvbGxlci1zdGFydCwgLmdzYXAtbWFya2VyLXNjcm9sbGVyLWVuZFwiKS5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgIHJldHVybiBlbC5zdHlsZS5kaXNwbGF5ID0gaGlkZSA/IFwibm9uZVwiIDogXCJibG9ja1wiO1xuICB9KTtcbn0sXG4gICAgX3JlZnJlc2hBbGwgPSBmdW5jdGlvbiBfcmVmcmVzaEFsbChmb3JjZSwgc2tpcFJldmVydCkge1xuICBpZiAoX2xhc3RTY3JvbGxUaW1lICYmICFmb3JjZSAmJiAhX2lzUmV2ZXJ0ZWQpIHtcbiAgICBfYWRkTGlzdGVuZXIoU2Nyb2xsVHJpZ2dlciwgXCJzY3JvbGxFbmRcIiwgX3NvZnRSZWZyZXNoKTtcblxuICAgIHJldHVybjtcbiAgfVxuXG4gIF9yZWZyZXNoMTAwdmgoKTtcblxuICBfcmVmcmVzaGluZ0FsbCA9IFNjcm9sbFRyaWdnZXIuaXNSZWZyZXNoaW5nID0gdHJ1ZTtcblxuICBfc2Nyb2xsZXJzLmZvckVhY2goZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBfaXNGdW5jdGlvbihvYmopICYmICsrb2JqLmNhY2hlSUQgJiYgKG9iai5yZWMgPSBvYmooKSk7XG4gIH0pOyAvLyBmb3JjZSB0aGUgY2xlYXJpbmcgb2YgdGhlIGNhY2hlIGJlY2F1c2Ugc29tZSBicm93c2VycyB0YWtlIGEgbGl0dGxlIHdoaWxlIHRvIGRpc3BhdGNoIHRoZSBcInNjcm9sbFwiIGV2ZW50IGFuZCB0aGUgdXNlciBtYXkgaGF2ZSBjaGFuZ2VkIHRoZSBzY3JvbGwgcG9zaXRpb24gYW5kIHRoZW4gY2FsbGVkIFNjcm9sbFRyaWdnZXIucmVmcmVzaCgpIHJpZ2h0IGF3YXlcblxuXG4gIHZhciByZWZyZXNoSW5pdHMgPSBfZGlzcGF0Y2goXCJyZWZyZXNoSW5pdFwiKTtcblxuICBfc29ydCAmJiBTY3JvbGxUcmlnZ2VyLnNvcnQoKTtcbiAgc2tpcFJldmVydCB8fCBfcmV2ZXJ0QWxsKCk7XG5cbiAgX3Njcm9sbGVycy5mb3JFYWNoKGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAoX2lzRnVuY3Rpb24ob2JqKSkge1xuICAgICAgb2JqLnNtb290aCAmJiAob2JqLnRhcmdldC5zdHlsZS5zY3JvbGxCZWhhdmlvciA9IFwiYXV0b1wiKTsgLy8gc21vb3RoIHNjcm9sbGluZyBpbnRlcmZlcmVzXG5cbiAgICAgIG9iaigwKTtcbiAgICB9XG4gIH0pO1xuXG4gIF90cmlnZ2Vycy5zbGljZSgwKS5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgcmV0dXJuIHQucmVmcmVzaCgpO1xuICB9KTsgLy8gZG9uJ3QgbG9vcCB3aXRoIF9pIGJlY2F1c2UgZHVyaW5nIGEgcmVmcmVzaCgpIHNvbWVvbmUgY291bGQgY2FsbCBTY3JvbGxUcmlnZ2VyLnVwZGF0ZSgpIHdoaWNoIHdvdWxkIGl0ZXJhdGUgdGhyb3VnaCBfaSByZXN1bHRpbmcgaW4gYSBza2lwLlxuXG5cbiAgX2lzUmV2ZXJ0ZWQgPSBmYWxzZTtcblxuICBfdHJpZ2dlcnMuZm9yRWFjaChmdW5jdGlvbiAodCkge1xuICAgIC8vIG5lc3RlZCBwaW5zIChwaW5uZWRDb250YWluZXIpIHdpdGggcGluU3BhY2luZyBtYXkgZXhwYW5kIHRoZSBjb250YWluZXIsIHNvIHdlIG11c3QgYWNjb21tb2RhdGUgdGhhdCBoZXJlLlxuICAgIGlmICh0Ll9zdWJQaW5PZmZzZXQgJiYgdC5waW4pIHtcbiAgICAgIHZhciBwcm9wID0gdC52YXJzLmhvcml6b250YWwgPyBcIm9mZnNldFdpZHRoXCIgOiBcIm9mZnNldEhlaWdodFwiLFxuICAgICAgICAgIG9yaWdpbmFsID0gdC5waW5bcHJvcF07XG4gICAgICB0LnJldmVydCh0cnVlLCAxKTtcbiAgICAgIHQuYWRqdXN0UGluU3BhY2luZyh0LnBpbltwcm9wXSAtIG9yaWdpbmFsKTtcbiAgICAgIHQucmVmcmVzaCgpO1xuICAgIH1cbiAgfSk7XG5cbiAgX2NsYW1waW5nTWF4ID0gMTsgLy8gcGluU3BhY2luZyBtaWdodCBiZSBwcm9wcGluZyBhIHBhZ2Ugb3BlbiwgdGh1cyB3aGVuIHdlIC5zZXRQb3NpdGlvbnMoKSB0byBjbGFtcCBhIFNjcm9sbFRyaWdnZXIncyBlbmQgd2Ugc2hvdWxkIGxlYXZlIHRoZSBwaW5TcGFjaW5nIGFsb25lLiBUaGF0J3Mgd2hhdCB0aGlzIGZsYWcgaXMgZm9yLlxuXG4gIF9oaWRlQWxsTWFya2Vycyh0cnVlKTtcblxuICBfdHJpZ2dlcnMuZm9yRWFjaChmdW5jdGlvbiAodCkge1xuICAgIC8vIHRoZSBzY3JvbGxlcidzIG1heCBzY3JvbGwgcG9zaXRpb24gbWF5IGNoYW5nZSBhZnRlciBhbGwgdGhlIFNjcm9sbFRyaWdnZXJzIHJlZnJlc2hlZCAobGlrZSBwaW5uaW5nIGNvdWxkIHB1c2ggaXQgZG93biksIHNvIHdlIG5lZWQgdG8gbG9vcCBiYWNrIGFuZCBjb3JyZWN0IGFueSB3aXRoIGVuZDogXCJtYXhcIi4gU2FtZSBmb3IgYW55dGhpbmcgd2l0aCBhIGNsYW1wZWQgZW5kXG4gICAgdmFyIG1heCA9IF9tYXhTY3JvbGwodC5zY3JvbGxlciwgdC5fZGlyKSxcbiAgICAgICAgZW5kQ2xhbXAgPSB0LnZhcnMuZW5kID09PSBcIm1heFwiIHx8IHQuX2VuZENsYW1wICYmIHQuZW5kID4gbWF4LFxuICAgICAgICBzdGFydENsYW1wID0gdC5fc3RhcnRDbGFtcCAmJiB0LnN0YXJ0ID49IG1heDtcblxuICAgIChlbmRDbGFtcCB8fCBzdGFydENsYW1wKSAmJiB0LnNldFBvc2l0aW9ucyhzdGFydENsYW1wID8gbWF4IC0gMSA6IHQuc3RhcnQsIGVuZENsYW1wID8gTWF0aC5tYXgoc3RhcnRDbGFtcCA/IG1heCA6IHQuc3RhcnQgKyAxLCBtYXgpIDogdC5lbmQsIHRydWUpO1xuICB9KTtcblxuICBfaGlkZUFsbE1hcmtlcnMoZmFsc2UpO1xuXG4gIF9jbGFtcGluZ01heCA9IDA7XG4gIHJlZnJlc2hJbml0cy5mb3JFYWNoKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICByZXR1cm4gcmVzdWx0ICYmIHJlc3VsdC5yZW5kZXIgJiYgcmVzdWx0LnJlbmRlcigtMSk7XG4gIH0pOyAvLyBpZiB0aGUgb25S
1ZWZyZXNoSW5pdCgpIHJldHVybnMgYW4gYW5pbWF0aW9uICh0eXBpY2FsbHkgYSBnc2FwLnNldCgpKSwgcmV2ZXJ0IGl0LiBUaGlzIG1ha2VzIGl0IGVhc3kgdG8gcHV0IHRoaW5ncyBpbiBhIGNlcnRhaW4gc3BvdCBiZWZvcmUgcmVmcmVzaGluZyBmb3IgbWVhc3VyZW1lbnQgcHVycG9zZXMsIGFuZCB0aGVuIHB1dCB0aGluZ3MgYmFjay5cblxuICBfc2Nyb2xsZXJzLmZvckVhY2goZnVuY3Rpb24gKG9iaikge1xuICAgIGlmIChfaXNGdW5jdGlvbihvYmopKSB7XG4gICAgICBvYmouc21vb3RoICYmIHJlcXVlc3RBbmltYXRpb25GcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBvYmoudGFyZ2V0LnN0eWxlLnNjcm9sbEJlaGF2aW9yID0gXCJzbW9vdGhcIjtcbiAgICAgIH0pO1xuICAgICAgb2JqLnJlYyAmJiBvYmoob2JqLnJlYyk7XG4gICAgfVxuICB9KTtcblxuICBfY2xlYXJTY3JvbGxNZW1vcnkoX3Njcm9sbFJlc3RvcmF0aW9uLCAxKTtcblxuICBfcmVzaXplRGVsYXkucGF1c2UoKTtcblxuICBfcmVmcmVzaElEKys7XG4gIF9yZWZyZXNoaW5nQWxsID0gMjtcblxuICBfdXBkYXRlQWxsKDIpO1xuXG4gIF90cmlnZ2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgcmV0dXJuIF9pc0Z1bmN0aW9uKHQudmFycy5vblJlZnJlc2gpICYmIHQudmFycy5vblJlZnJlc2godCk7XG4gIH0pO1xuXG4gIF9yZWZyZXNoaW5nQWxsID0gU2Nyb2xsVHJpZ2dlci5pc1JlZnJlc2hpbmcgPSBmYWxzZTtcblxuICBfZGlzcGF0Y2goXCJyZWZyZXNoXCIpO1xufSxcbiAgICBfbGFzdFNjcm9sbCA9IDAsXG4gICAgX2RpcmVjdGlvbiA9IDEsXG4gICAgX3ByaW1hcnksXG4gICAgX3VwZGF0ZUFsbCA9IGZ1bmN0aW9uIF91cGRhdGVBbGwoZm9yY2UpIHtcbiAgaWYgKGZvcmNlID09PSAyIHx8ICFfcmVmcmVzaGluZ0FsbCAmJiAhX2lzUmV2ZXJ0ZWQpIHtcbiAgICAvLyBfaXNSZXZlcnRlZCBjb3VsZCBiZSB0cnVlIGlmLCBmb3IgZXhhbXBsZSwgYSBtYXRjaE1lZGlhKCkgaXMgaW4gdGhlIHByb2Nlc3Mgb2YgZXhlY3V0aW5nLiBXZSBkb24ndCB3YW50IHRvIHVwZGF0ZSBkdXJpbmcgdGhlIHRpbWUgZXZlcnl0aGluZyBpcyByZXZlcnRlZC5cbiAgICBTY3JvbGxUcmlnZ2VyLmlzVXBkYXRpbmcgPSB0cnVlO1xuICAgIF9wcmltYXJ5ICYmIF9wcmltYXJ5LnVwZGF0ZSgwKTsgLy8gU2Nyb2xsU21vb3RoZXIgdXNlcyByZWZyZXNoUHJpb3JpdHkgLTk5OTkgdG8gYmVjb21lIHRoZSBwcmltYXJ5IHRoYXQgZ2V0cyB1cGRhdGVkIGJlZm9yZSBhbGwgb3RoZXJzIGJlY2F1c2UgaXQgYWZmZWN0cyB0aGUgc2Nyb2xsIHBvc2l0aW9uLlxuXG4gICAgdmFyIGwgPSBfdHJpZ2dlcnMubGVuZ3RoLFxuICAgICAgICB0aW1lID0gX2dldFRpbWUoKSxcbiAgICAgICAgcmVjb3JkVmVsb2NpdHkgPSB0aW1lIC0gX3RpbWUxID49IDUwLFxuICAgICAgICBzY3JvbGwgPSBsICYmIF90cmlnZ2Vyc1swXS5zY3JvbGwoKTtcblxuICAgIF9kaXJlY3Rpb24gPSBfbGFzdFNjcm9sbCA+IHNjcm9sbCA/IC0xIDogMTtcbiAgICBfcmVmcmVzaGluZ0FsbCB8fCAoX2xhc3RTY3JvbGwgPSBzY3JvbGwpO1xuXG4gICAgaWYgKHJlY29yZFZlbG9jaXR5KSB7XG4gICAgICBpZiAoX2xhc3RTY3JvbGxUaW1lICYmICFfcG9pbnRlcklzRG93biAmJiB0aW1lIC0gX2xhc3RTY3JvbGxUaW1lID4gMjAwKSB7XG4gICAgICAgIF9sYXN0U2Nyb2xsVGltZSA9IDA7XG5cbiAgICAgICAgX2Rpc3BhdGNoKFwic2Nyb2xsRW5kXCIpO1xuICAgICAgfVxuXG4gICAgICBfdGltZTIgPSBfdGltZTE7XG4gICAgICBfdGltZTEgPSB0aW1lO1xuICAgIH1cblxuICAgIGlmIChfZGlyZWN0aW9uIDwgMCkge1xuICAgICAgX2kgPSBsO1xuXG4gICAgICB3aGlsZSAoX2ktLSA+IDApIHtcbiAgICAgICAgX3RyaWdnZXJzW19pXSAmJiBfdHJpZ2dlcnNbX2ldLnVwZGF0ZSgwLCByZWNvcmRWZWxvY2l0eSk7XG4gICAgICB9XG5cbiAgICAgIF9kaXJlY3Rpb24gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKF9pID0gMDsgX2kgPCBsOyBfaSsrKSB7XG4gICAgICAgIF90cmlnZ2Vyc1tfaV0gJiYgX3RyaWdnZXJzW19pXS51cGRhdGUoMCwgcmVjb3JkVmVsb2NpdHkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIFNjcm9sbFRyaWdnZXIuaXNVcGRhdGluZyA9IGZhbHNlO1xuICB9XG5cbiAgX3JhZklEID0gMDtcbn0sXG4gICAgX3Byb3BOYW1lc1RvQ29weSA9IFtfbGVmdCwgX3RvcCwgX2JvdHRvbSwgX3JpZ2h0LCBfbWFyZ2luICsgX0JvdHRvbSwgX21hcmdpbiArIF9SaWdodCwgX21hcmdpbiArIF9Ub3AsIF9tYXJnaW4gKyBfTGVmdCwgXCJkaXNwbGF5XCIsIFwiZmxleFNocmlua1wiLCBcImZsb2F0XCIsIFwiekluZGV4XCIsIFwiZ3JpZENvbHVtblN0YXJ0XCIsIFwiZ3JpZENvbHVtbkVuZFwiLCBcImdyaWRSb3dTdGFydFwiLCBcImdyaWRSb3dFbmRcIiwgXCJncmlkQXJlYVwiLCBcImp1c3RpZnlTZWxmXCIsIFwiYWxpZ25TZWxmXCIsIFwicGxhY2VTZWxmXCIsIFwib3JkZXJcIl0sXG4gICAgX3N0YXRlUHJvcHMgP
1SBfcHJvcE5hbWVzVG9Db3B5LmNvbmNhdChbX3dpZHRoLCBfaGVpZ2h0LCBcImJveFNpemluZ1wiLCBcIm1heFwiICsgX1dpZHRoLCBcIm1heFwiICsgX0hlaWdodCwgXCJwb3NpdGlvblwiLCBfbWFyZ2luLCBfcGFkZGluZywgX3BhZGRpbmcgKyBfVG9wLCBfcGFkZGluZyArIF9SaWdodCwgX3BhZGRpbmcgKyBfQm90dG9tLCBfcGFkZGluZyArIF9MZWZ0XSksXG4gICAgX3N3YXBQaW5PdXQgPSBmdW5jdGlvbiBfc3dhcFBpbk91dChwaW4sIHNwYWNlciwgc3RhdGUpIHtcbiAgX3NldFN0YXRlKHN0YXRlKTtcblxuICB2YXIgY2FjaGUgPSBwaW4uX2dzYXA7XG5cbiAgaWYgKGNhY2hlLnNwYWNlcklzTmF0aXZlKSB7XG4gICAgX3NldFN0YXRlKGNhY2hlLnNwYWNlclN0YXRlKTtcbiAgfSBlbHNlIGlmIChwaW4uX2dzYXAuc3dhcHBlZEluKSB7XG4gICAgdmFyIHBhcmVudCA9IHNwYWNlci5wYXJlbnROb2RlO1xuXG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShwaW4sIHNwYWNlcik7XG4gICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoc3BhY2VyKTtcbiAgICB9XG4gIH1cblxuICBwaW4uX2dzYXAuc3dhcHBlZEluID0gZmFsc2U7XG59LFxuICAgIF9zd2FwUGluSW4gPSBmdW5jdGlvbiBfc3dhcFBpbkluKHBpbiwgc3BhY2VyLCBjcywgc3BhY2VyU3RhdGUpIHtcbiAgaWYgKCFwaW4uX2dzYXAuc3dhcHBlZEluKSB7XG4gICAgdmFyIGkgPSBfcHJvcE5hbWVzVG9Db3B5Lmxlbmd0aCxcbiAgICAgICAgc3BhY2VyU3R5bGUgPSBzcGFjZXIuc3R5bGUsXG4gICAgICAgIHBpblN0eWxlID0gcGluLnN0eWxlLFxuICAgICAgICBwO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgcCA9IF9wcm9wTmFtZXNUb0NvcHlbaV07XG4gICAgICBzcGFjZXJTdHlsZVtwXSA9IGNzW3BdO1xuICAgIH1cblxuICAgIHNwYWNlclN0eWxlLnBvc2l0aW9uID0gY3MucG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIiA/IFwiYWJzb2x1dGVcIiA6IFwicmVsYXRpdmVcIjtcbiAgICBjcy5kaXNwbGF5ID09PSBcImlubGluZVwiICYmIChzcGFjZXJTdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIik7XG4gICAgcGluU3R5bGVbX2JvdHRvbV0gPSBwaW5TdHlsZVtfcmlnaHRdID0gXCJhdXRvXCI7XG4gICAgc3BhY2VyU3R5bGUuZmxleEJhc2lzID0gY3MuZmxleEJhc2lzIHx8IFwiYXV0b1wiO1xuICAgIHNwYWNlclN0eWxlLm92ZXJmbG93ID0gXCJ2aXNpYmxlXCI7XG4gICAgc3BhY2VyU3R5bGUuYm94U2l6aW5nID0gXCJib3JkZXItYm94XCI7XG4gICAgc3BhY2VyU3R5bGVbX3dpZHRoXSA9IF9nZXRTaXplKHBpbiwgX2hvcml6b250YWwpICsgX3B4O1xuICAgIHNwYWNlclN0eWxlW19oZWlnaHRdID0gX2dldFNpemUocGluLCBfdmVydGljYWwpICsgX3B4O1xuICAgIHNwYWNlclN0eWxlW19wYWRkaW5nXSA9IHBpblN0eWxlW19tYXJnaW5dID0gcGluU3R5bGVbX3RvcF0gPSBwaW5TdHlsZVtfbGVmdF0gPSBcIjBcIjtcblxuICAgIF9zZXRTdGF0ZShzcGFjZXJTdGF0ZSk7XG5cbiAgICBwaW5TdHlsZVtfd2lkdGhdID0gcGluU3R5bGVbXCJtYXhcIiArIF9XaWR0aF0gPSBjc1tfd2lkdGhdO1xuICAgIHBpblN0eWxlW19oZWlnaHRdID0gcGluU3R5bGVbXCJtYXhcIiArIF9IZWlnaHRdID0gY3NbX2hlaWdodF07XG4gICAgcGluU3R5bGVbX3BhZGRpbmddID0gY3NbX3BhZGRpbmddO1xuXG4gICAgaWYgKHBpbi5wYXJlbnROb2RlICE9PSBzcGFjZXIpIHtcbiAgICAgIHBpbi5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzcGFjZXIsIHBpbik7XG4gICAgICBzcGFjZXIuYXBwZW5kQ2hpbGQocGluKTtcbiAgICB9XG5cbiAgICBwaW4uX2dzYXAuc3dhcHBlZEluID0gdHJ1ZTtcbiAgfVxufSxcbiAgICBfY2Fwc0V4cCA9IC8oW0EtWl0pL2csXG4gICAgX3NldFN0YXRlID0gZnVuY3Rpb24gX3NldFN0YXRlKHN0YXRlKSB7XG4gIGlmIChzdGF0ZSkge1xuICAgIHZhciBzdHlsZSA9IHN0YXRlLnQuc3R5bGUsXG4gICAgICAgIGwgPSBzdGF0ZS5sZW5ndGgsXG4gICAgICAgIGkgPSAwLFxuICAgICAgICBwLFxuICAgICAgICB2YWx1ZTtcbiAgICAoc3RhdGUudC5fZ3NhcCB8fCBnc2FwLmNvcmUuZ2V0Q2FjaGUoc3RhdGUudCkpLnVuY2FjaGUgPSAxOyAvLyBvdGhlcndpc2UgdHJhbnNmb3JtcyBtYXkgYmUgb2ZmXG5cbiAgICBmb3IgKDsgaSA8IGw7IGkgKz0gMikge1xuICAgICAgdmFsdWUgPSBzdGF0ZVtpICsgMV07XG4gICAgICBwID0gc3RhdGVbaV07XG5cbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICBzdHlsZVtwXSA9IHZhbHVlO1xuICAgICAgfSBlbHNlIGlmIChzdHlsZVtwXSkge1xuICAgICAgICBzdHlsZS5yZW1vdmVQcm9wZXJ0eShwLnJlcGxhY2UoX2NhcHNFeHAsIFwiLSQxXCIpLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufSxcbiAgICBfZ2V0U3RhdGUgPSBmdW5jdGlvbiBfZ2V0U3RhdGUoZWxlbWVudCkge1xuICAvLyByZXR1cm5zIGFuIEFycmF5IHdpdGggYWx0ZXJuYXRpbmcgdmFsdWVzIGxpa2UgW3Byb3BlcnR5LCB2YWx1ZSwgcHJvcGVydHksIHZhbHVlXSBhbmQgYSBcInRcIiBwcm9wZXJ0eSBwb2ludGluZyB0byB0aGUgdGFyZ2V0IChlbGVtZW50KS4gTWFrZXMgaXQgZmFzdCBhbmQgY2hlYXAuXG4gIHZhciBsID0gX3N0YXRlUHJvcHMubGVuZ3RoLFxuICAgICAgc3R5bGUgPSBlbGVtZW50LnN0eWxlLFxuICAgICAgc3RhdGUgPSBbXSxcbiAgICAgIGkgPSAwO1xuXG4gIGZvciAoOyBpIDwgbDsgaSsrKSB7XG4gICAgc3RhdGUucHVzaChfc3RhdGVQcm9wc1tpXSwgc3R5bGVbX3N0YXRlUHJvcHNbaV1dKTtcbiAgfVxuXG4gIHN0YXRlLnQgPSBlbGVtZW50O1xuICByZXR1cm4gc3RhdGU7XG59LFxuICAgIF9jb3B5U3RhdGUgPSBmdW5jdGlvbiBfY29weVN0YXRl
1KHN0YXRlLCBvdmVycmlkZSwgb21pdE9mZnNldHMpIHtcbiAgdmFyIHJlc3VsdCA9IFtdLFxuICAgICAgbCA9IHN0YXRlLmxlbmd0aCxcbiAgICAgIGkgPSBvbWl0T2Zmc2V0cyA/IDggOiAwLFxuICAgICAgLy8gc2tpcCB0b3AsIGxlZnQsIHJpZ2h0LCBib3R0b20gaWYgb21pdE9mZnNldHMgaXMgdHJ1ZVxuICBwO1xuXG4gIGZvciAoOyBpIDwgbDsgaSArPSAyKSB7XG4gICAgcCA9IHN0YXRlW2ldO1xuICAgIHJlc3VsdC5wdXNoKHAsIHAgaW4gb3ZlcnJpZGUgPyBvdmVycmlkZVtwXSA6IHN0YXRlW2kgKyAxXSk7XG4gIH1cblxuICByZXN1bHQudCA9IHN0YXRlLnQ7XG4gIHJldHVybiByZXN1bHQ7XG59LFxuICAgIF93aW5PZmZzZXRzID0ge1xuICBsZWZ0OiAwLFxuICB0b3A6IDBcbn0sXG4gICAgLy8gLy8gcG90ZW50aWFsIGZ1dHVyZSBmZWF0dXJlICg/KSBBbGxvdyB1c2VycyB0byBjYWxjdWxhdGUgd2hlcmUgYSB0cmlnZ2VyIGhpdHMgKHNjcm9sbCBwb3NpdGlvbikgbGlrZSBnZXRTY3JvbGxQb3NpdGlvbihcIiNpZFwiLCBcInRvcCBib3R0b21cIilcbi8vIF9nZXRTY3JvbGxQb3NpdGlvbiA9ICh0cmlnZ2VyLCBwb3NpdGlvbiwge3Njcm9sbGVyLCBjb250YWluZXJBbmltYXRpb24sIGhvcml6b250YWx9KSA9PiB7XG4vLyBcdHNjcm9sbGVyID0gX2dldFRhcmdldChzY3JvbGxlciB8fCBfd2luKTtcbi8vIFx0bGV0IGRpcmVjdGlvbiA9IGhvcml6b250YWwgPyBfaG9yaXpvbnRhbCA6IF92ZXJ0aWNhbCxcbi8vIFx0XHRpc1ZpZXdwb3J0ID0gX2lzVmlld3BvcnQoc2Nyb2xsZXIpO1xuLy8gXHRfZ2V0U2l6ZUZ1bmMoc2Nyb2xsZXIsIGlzVmlld3BvcnQsIGRpcmVjdGlvbik7XG4vLyBcdHJldHVybiBfcGFyc2VQb3NpdGlvbihwb3NpdGlvbiwgX2dldFRhcmdldCh0cmlnZ2VyKSwgX2dldFNpemVGdW5jKHNjcm9sbGVyLCBpc1ZpZXdwb3J0LCBkaXJlY3Rpb24pKCksIGRpcmVjdGlvbiwgX2dldFNjcm9sbEZ1bmMoc2Nyb2xsZXIsIGRpcmVjdGlvbikoKSwgMCwgMCwgMCwgX2dldE9mZnNldHNGdW5jKHNjcm9sbGVyLCBpc1ZpZXdwb3J0KSgpLCBpc1ZpZXdwb3J0ID8gMCA6IHBhcnNlRmxvYXQoX2dldENvbXB1dGVkU3R5bGUoc2Nyb2xsZXIpW1wiYm9yZGVyXCIgKyBkaXJlY3Rpb24ucDIgKyBfV2lkdGhdKSB8fCAwLCAwLCBjb250YWluZXJBbmltYXRpb24gPyBjb250YWluZXJBbmltYXRpb24uZHVyYXRpb24oKSA6IF9tYXhTY3JvbGwoc2Nyb2xsZXIpLCBjb250YWluZXJBbmltYXRpb24pO1xuLy8gfSxcbl9wYXJzZVBvc2l0aW9uID0gZnVuY3Rpb24gX3BhcnNlUG9zaXRpb24odmFsdWUsIHRyaWdnZXIsIHNjcm9sbGVyU2l6ZSwgZGlyZWN0aW9uLCBzY3JvbGwsIG1hcmtlciwgbWFya2VyU2Nyb2xsZXIsIHNlbGYsIHNjcm9sbGVyQm91bmRzLCBib3JkZXJXaWR0aCwgdXNlRml4ZWRQb3NpdGlvbiwgc2Nyb2xsZXJNYXgsIGNvbnRhaW5lckFuaW1hdGlvbiwgY2xhbXBaZXJvUHJvcCkge1xuICBfaXNGdW5jdGlvbih2YWx1ZSkgJiYgKHZhbHVlID0gdmFsdWUoc2VsZikpO1xuXG4gIGlmIChfaXNTdHJpbmcodmFsdWUpICYmIHZhbHVlLnN1YnN0cigwLCAzKSA9PT0gXCJtYXhcIikge1xuICAgIHZhbHVlID0gc2Nyb2xsZXJNYXggKyAodmFsdWUuY2hhckF0KDQpID09PSBcIj1cIiA/IF9vZmZzZXRUb1B4KFwiMFwiICsgdmFsdWUuc3Vic3RyKDMpLCBzY3JvbGxlclNpemUpIDogMCk7XG4gIH1cblxuICB2YXIgdGltZSA9IGNvbnRhaW5lckFuaW1hdGlvbiA/IGNvbnRhaW5lckFuaW1hdGlvbi50aW1lKCkgOiAwLFxuICAgICAgcDEsXG4gICAgICBwMixcbiAgICAgIGVsZW1lbnQ7XG4gIGNvbnRhaW5lckFuaW1hdGlvbiAmJiBjb250YWluZXJBbmltYXRpb24uc2VlaygwKTtcbiAgaXNOYU4odmFsdWUpIHx8ICh2YWx1ZSA9ICt2YWx1ZSk7IC8vIGNvbnZlcnQgYSBzdHJpbmcgbnVtYmVyIGxpa2UgXCI0NVwiIHRvIGFuIGFjdHVhbCBudW1iZXJcblxuICBpZiAoIV9pc051bWJlcih2YWx1ZSkpIHtcbiAgICBfaXNGdW5jdGlvbih0cmlnZ2VyKSAmJiAodHJpZ2dlciA9IHRyaWdnZXIoc2VsZikpO1xuICAgIHZhciBvZmZzZXRzID0gKHZhbHVlIHx8IFwiMFwiKS5zcGxpdChcIiBcIiksXG4gICAgICAgIGJvdW5kcyxcbiAgICAgICAgbG9jYWxPZmZzZXQsXG4gICAgICAgIGdsb2JhbE9mZnNldCxcbiAgICAgICAgZGlzcGxheTtcbiAgICBlbGVtZW50ID0gX2dldFRhcmdldCh0cmlnZ2VyLCBzZWxmKSB8fCBfYm9keTtcbiAgICBib3VuZHMgPSBfZ2V0Qm91bmRzKGVsZW1lbnQpIHx8IHt9O1xuXG4gICAgaWYgKCghYm91bmRzIHx8ICFib3VuZHMubGVmdCAmJiAhYm91bmRzLnRvcCkgJiYgX2dldENvbXB1dGVkU3R5bGUoZWxlbWVudCkuZGlzcGxheSA9PT0gXCJub25lXCIpIHtcbiAgICAgIC8vIGlmIGRpc3BsYXkgaXMgXCJub25lXCIsIGl0IHdvbid0IHJlcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QoKSBwcm9wZXJseVxuICAgICAgZGlzcGxheSA9IGVsZW1lbnQuc3R5bGUuZGlzcGxheTtcbiAgICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjtcbiAgICAgIGJvdW5kcyA9IF9nZXRCb3VuZHMoZWxlbWVudCk7XG4gICAgICBkaXNwbGF5ID8gZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gZGlzcGxheSA6IGVsZW1lbnQuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJkaXNwbGF5XCIpO1xuICAgIH1cblxuICAgIGxvY2FsT2Zmc2V0ID0gX29mZnNldFRvUHgob2Zmc2V0c1swXSwgYm91bmRzW2RpcmVjdGlvbi5kXSk7XG4gICAgZ2xvYmFsT2Zmc2V0ID0gX29mZnNldFRvUHgob2Zmc2V0c1sxXSB8fCBcIjBcIiwgc2Nyb2xsZXJTaXplKTtcbiAgICB2YWx1ZSA9IGJvdW5kc1tkaXJlY3Rpb24ucF0gLSBzY3JvbGxlckJvdW5kc1tkaXJlY3Rpb24ucF0gLSBib3JkZXJXaWR0aCArIGxvY2FsT2Zmc2V0ICsgc2Nyb2xsIC0gZ2xvYmFsT2Zmc2V0O1xuICAgIG1hcmtlclNjcm9sbGVyICYmIF9wb3NpdGlvbk1hcmtlcihtYXJrZXJTY3JvbGxlciwgZ2xvYmFsT2Zmc2V0LCBkaXJlY3Rpb24sIHNjcm9sbGVyU2l6ZSAtIGdsb2JhbE9mZnNldCA8IDIwIHx8IG1hcmtlclNjcm9sbGVyLl9pc1N0YXJ0ICYmIGdsb2JhbE9mZnNldCA+IDIwKTtcbiAgICBzY3JvbGxlclNpemUgLT0gc2Nyb2xsZXJTaXplIC0gZ2xvYmFsT2Zmc2V0OyAvLyBhZGp1c3QgZm9yIHRoZSBtYXJrZXJcbiAgfSBlbHNlIHtcbiAgICBjb250YWluZXJBbmltYXRpb24gJiYgKHZhbHVlID0gZ3NhcC51dGlscy5tYXBSYW5nZShjb250YWluZXJBbmltYXRpb24uc2Nyb2xsVHJpZ2dlci5zdGFydCwgY29udGFpbmVyQW5pbWF0aW9uLnNjcm9sbFRyaWdnZXIuZW5kLCAwLCBzY3JvbGxlck1heCwgdmFsdWUpKTtcbiAgICBtYXJrZXJTY3JvbGxlciAmJiBfcG9zaXRpb25NYXJrZXIobWFya2VyU2Nyb2xsZXIsIHNjcm9sbGVyU2l6ZSwgZGlyZWN0aW9uLCB0cnVlKTtcbiAgfVxuXG4gIGlmIChjbGFtcFplcm9Qcm9wKSB7XG4gICAgc2VsZltjbGFtcFplcm9Qcm9wXSA9IHZhbHVlIHx8IC0wLjAwMTtcbiAgICB2YWx1ZSA8IDAgJiYgKHZhbHVlID0gMCk7XG4gIH1cblxuICBpZiAobWFya2VyKSB7XG4gICAgdmFyIHBvc2l0aW9uID0gdmFsdWUgKyBzY3JvbGxlclNpemUsXG4gICAgICAgIGlzU3RhcnQgPSBtYXJrZXIuX2lzU3RhcnQ7XG4gICAgcDEgPSBcInNjcm9sbFwiICsgZGlyZWN0aW9uLmQyO1xuXG4gICAgX3Bvc2l0aW9uTWFya2VyKG1hcmtlciwgcG9zaXRpb24sIGRpcmVjdGlvbiwgaXNTdGFydCAmJiBwb3NpdGlvbiA+IDIwIHx8ICFpc1N0YXJ0ICYmICh1c2VGaXhlZFBvc2l0aW9uID8gTWF0aC5tYXgoX2JvZHlbcDFdLCBfZG9jRWxbcDFdKSA6IG
11hcmtlci5wYXJlbnROb2RlW3AxXSkgPD0gcG9zaXRpb24gKyAxKTtcblxuICAgIGlmICh1c2VGaXhlZFBvc2l0aW9uKSB7XG4gICAgICBzY3JvbGxlckJvdW5kcyA9IF9nZXRCb3VuZHMobWFya2VyU2Nyb2xsZXIpO1xuICAgICAgdXNlRml4ZWRQb3NpdGlvbiAmJiAobWFya2VyLnN0eWxlW2RpcmVjdGlvbi5vcC5wXSA9IHNjcm9sbGVyQm91bmRzW2RpcmVjdGlvbi5vcC5wXSAtIGRpcmVjdGlvbi5vcC5tIC0gbWFya2VyLl9vZmZzZXQgKyBfcHgpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjb250YWluZXJBbmltYXRpb24gJiYgZWxlbWVudCkge1xuICAgIHAxID0gX2dldEJvdW5kcyhlbGVtZW50KTtcbiAgICBjb250YWluZXJBbmltYXRpb24uc2VlayhzY3JvbGxlck1heCk7XG4gICAgcDIgPSBfZ2V0Qm91bmRzKGVsZW1lbnQpO1xuICAgIGNvbnRhaW5lckFuaW1hdGlvbi5fY2FTY3JvbGxEaXN0ID0gcDFbZGlyZWN0aW9uLnBdIC0gcDJbZGlyZWN0aW9uLnBdO1xuICAgIHZhbHVlID0gdmFsdWUgLyBjb250YWluZXJBbmltYXRpb24uX2NhU2Nyb2xsRGlzdCAqIHNjcm9sbGVyTWF4O1xuICB9XG5cbiAgY29udGFpbmVyQW5pbWF0aW9uICYmIGNvbnRhaW5lckFuaW1hdGlvbi5zZWVrKHRpbWUpO1xuICByZXR1cm4gY29udGFpbmVyQW5pbWF0aW9uID8gdmFsdWUgOiBNYXRoLnJvdW5kKHZhbHVlKTtcbn0sXG4gICAgX3ByZWZpeEV4cCA9IC8od2Via2l0fG1venxsZW5ndGh8Y3NzVGV4dHxpbnNldCkvaSxcbiAgICBfcmVwYXJlbnQgPSBmdW5jdGlvbiBfcmVwYXJlbnQoZWxlbWVudCwgcGFyZW50LCB0b3AsIGxlZnQpIHtcbiAgaWYgKGVsZW1lbnQucGFyZW50Tm9kZSAhPT0gcGFyZW50KSB7XG4gICAgdmFyIHN0eWxlID0gZWxlbWVudC5zdHlsZSxcbiAgICAgICAgcCxcbiAgICAgICAgY3M7XG5cbiAgICBpZiAocGFyZW50ID09PSBfYm9keSkge1xuICAgICAgZWxlbWVudC5fc3RPcmlnID0gc3R5bGUuY3NzVGV4dDsgLy8gcmVjb3JkIG9yaWdpbmFsIGlubGluZSBzdHlsZXMgc28gd2UgY2FuIHJldmVydCB0aGVtIGxhdGVyXG5cbiAgICAgIGNzID0gX2dldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG5cbiAgICAgIGZvciAocCBpbiBjcykge1xuICAgICAgICAvLyBtdXN0IGNvcHkgYWxsIHJlbGV2YW50IHN0eWxlcyB0byBlbnN1cmUgdGhhdCBub3RoaW5nIGNoYW5nZXMgdmlzdWFsbHkgd2hlbiB3ZSByZXBhcmVudCB0byB0aGUgPGJvZHk+LiBTa2lwIHRoZSB2ZW5kb3IgcHJlZml4ZWQgb25lcy5cbiAgICAgICAgaWYgKCErcCAmJiAhX3ByZWZpeEV4cC50ZXN0KHApICYmIGNzW3BdICYmIHR5cGVvZiBzdHlsZVtwXSA9PT0gXCJzdHJpbmdcIiAmJiBwICE9PSBcIjBcIikge1xuICAgICAgICAgIHN0eWxlW3BdID0gY3NbcF07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3R5bGUudG9wID0gdG9wO1xuICAgICAgc3R5bGUubGVmdCA9IGxlZnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0eWxlLmNzc1RleHQgPSBlbGVtZW50Ll9zdE9yaWc7XG4gICAgfVxuXG4gICAgZ3NhcC5jb3JlLmdldENhY2hlKGVsZW1lbnQpLnVuY2FjaGUgPSAxO1xuICAgIHBhcmVudC5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgfVxufSxcbiAgICBfaW50ZXJydXB0aW9uVHJhY2tlciA9IGZ1bmN0aW9uIF9pbnRlcnJ1cHRpb25UcmFja2VyKGdldFZhbHVlRnVuYywgaW5pdGlhbFZhbHVlLCBvbkludGVycnVwdCkge1xuICB2YXIgbGFzdDEgPSBpbml0aWFsVmFsdWUsXG4gICAgICBsYXN0MiA9IGxhc3QxO1xuICByZXR1cm4gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBNYXRoLnJvdW5kKGdldFZhbHVlRnVuYygpKTsgLy8gcm91bmQgYmVjYXVzZSBpbiBzb21lIFt2ZXJ5IHVuY29tbW9uXSBXaW5kb3dzIGVudmlyb25tZW50cywgc2Nyb2xsIGNhbiBnZXQgcmVwb3J0ZWQgd2l0aCBkZWNpbWFscyBldmVuIHRob3VnaCBpdCB3YXMgc2V0IHdpdGhvdXQuXG5cbiAgICBpZiAoY3VycmVudCAhPT0gbGFzdDEgJiYgY3VycmVudCAhPT0gbGFzdDIgJiYgTWF0aC5hYnMoY3VycmVudCAtIGxhc3QxKSA+IDMgJiYgTWF0aC5hYnMoY3VycmVudCAtIGxhc3QyKSA+IDMpIHtcbiAgICAgIC8vIGlmIHRoZSB1c2VyIHNjcm9sbHMsIGtpbGwgdGhlIHR3ZWVuLiBpT1MgU2FmYXJpIGludGVybWl0dGVudGx5IG1pc3JlcG9ydHMgdGhlIHNjcm9sbCBwb3NpdGlvbiwgaXQgbWF5IGJlIHRoZSBtb3N0IHJlY2VudGx5LXNldCBvbmUgb3IgdGhlIG9uZSBiZWZvcmUgdGhhdCEgV2hlbiBTYWZhcmkgaXMgem9vbWVkIChDTUQtKyksIGl0IG9mdGVuIG1pc3JlcG9ydHMgYXMgMSBwaXhlbCBvZmYgdG9vISBTbyBpZiB3ZSBzZXQgdGhlIHNjcm9sbCBwb3NpdGlvbiB0byAxMjUsIGZvciBleGFtcGxlLCBpdCdsbCBhY3R1YWxseSByZXBvcnQgaXQgYXMgMTI0LlxuICAgICAgdmFsdWUgPSBjdXJyZW50O1xuICAgICAgb25JbnRlcnJ1cHQgJiYgb25JbnRlcnJ1cHQoKTtcbiAgICB9XG5cbiAgICBsYXN0MiA9IGxhc3QxO1xuICAgIGxhc3QxID0gdmFsdWU7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xufSxcbiAgICBfc2hpZnRNYXJrZXIgPSBmdW5jdGlvbiBfc2hpZnRNYXJrZXIobWFya2VyLCBkaXJlY3Rpb24sIHZhbHVlKSB7XG4gIHZhciB2YXJzID0ge307XG4gIHZhcnNbZGlyZWN0aW9uLnBdID0gXCIrPVwiICsgdmFsdWU7XG4gIGdzYXAuc2V0KG1hcmtlciwgdmFycyk7XG59LFxuICAgIC8vIF9tZXJnZUFuaW1hdGlvbnMgPSBhbmltYXRpb25zID0+IHtcbi8vIFx0bGV0IHRsID0gZ3NhcC50aW1lbGluZSh7c21vb3RoQ2hpbGRUaW1pbmc6IHRydWV9KS5zdGFydFRpbWUoTWF0aC5taW4oLi4uYW5pbWF0aW9ucy5tYXAoYSA9PiBhLmdsb2JhbFRpbWUoMCkpKSk7XG4vLyBcdGFuaW1hdGlvbnMuZm9yRWFjaChhID0+IHtsZXQgdGltZSA9IGEudG90YWxUaW1lKCk7IHRsLmFkZChhKTsgYS50b3RhbFRpbWUodGltZSk7IH0pO1xuLy8gXHR0bC5zbW9vdGhDaGlsZFRpbWluZyA9IGZhbHNlO1xuLy8gXHRyZXR1cm4gdGw7XG4vLyB9LFxuLy8gcmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgdG8gdHdlZW4gdGhlIHNjcm9sbCBwb3NpdGlvbiBpbiB0aGUgZGlyZWN0aW9uIHByb3ZpZGVkLCBhbmQgd2hlbiBkb2luZyBzbyBpdCdsbCBhZGQgYSAudHdlZW4gcHJvcGVydHkgdG8gdGhlIEZVTkNUSU9OIGl0c2VsZiwgYW5kIHJlbW92ZSBpdCB3aGVuIHRoZSB0d2VlbiBjb21wbGV0ZXMgb3IgZ2V0cyBraWxsZWQuIFRoaXMgZ2l2ZXMgdXMgYSB3YXkgdG8gaGF2ZSBtdWx0aXBsZSBTY3JvbGxUcmlnZ2VycyB1c2UgYSBjZW50cmFsIGZ1bmN0aW9uIGZvciBhbnkgZ2l2ZW4gc2Nyb2xsZXIgYW5kIHNlZSBpZiB0aGVyZSdzIGEgc2Nyb2xsIHR3ZWVuIHJ1bm5pbmcgKHdoaWNoIHdvdWxkIGFmZmVjdCBpZi9ob3cgdGhpbmdzIGdldCB1cGRhdGVkKVxuX2dldFR3ZWVuQ3JlYX
1RvciA9IGZ1bmN0aW9uIF9nZXRUd2VlbkNyZWF0b3Ioc2Nyb2xsZXIsIGRpcmVjdGlvbikge1xuICB2YXIgZ2V0U2Nyb2xsID0gX2dldFNjcm9sbEZ1bmMoc2Nyb2xsZXIsIGRpcmVjdGlvbiksXG4gICAgICBwcm9wID0gXCJfc2Nyb2xsXCIgKyBkaXJlY3Rpb24ucDIsXG4gICAgICAvLyBhZGQgYSB0d2VlbmFibGUgcHJvcGVydHkgdG8gdGhlIHNjcm9sbGVyIHRoYXQncyBhIGdldHRlci9zZXR0ZXIgZnVuY3Rpb24sIGxpa2UgX3Njcm9sbFRvcCBvciBfc2Nyb2xsTGVmdC4gVGhpcyB3YXksIGlmIHNvbWVvbmUgZG9lcyBnc2FwLmtpbGxUd2VlbnNPZihzY3JvbGxlcikgaXQnbGwga2lsbCB0aGUgc2Nyb2xsIHR3ZWVuLlxuICBnZXRUd2VlbiA9IGZ1bmN0aW9uIGdldFR3ZWVuKHNjcm9sbFRvLCB2YXJzLCBpbml0aWFsVmFsdWUsIGNoYW5nZTEsIGNoYW5nZTIpIHtcbiAgICB2YXIgdHdlZW4gPSBnZXRUd2Vlbi50d2VlbixcbiAgICAgICAgb25Db21wbGV0ZSA9IHZhcnMub25Db21wbGV0ZSxcbiAgICAgICAgbW9kaWZpZXJzID0ge307XG4gICAgaW5pdGlhbFZhbHVlID0gaW5pdGlhbFZhbHVlIHx8IGdldFNjcm9sbCgpO1xuXG4gICAgdmFyIGNoZWNrRm9ySW50ZXJydXB0aW9uID0gX2ludGVycnVwdGlvblRyYWNrZXIoZ2V0U2Nyb2xsLCBpbml0aWFsVmFsdWUsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHR3ZWVuLmtpbGwoKTtcbiAgICAgIGdldFR3ZWVuLnR3ZWVuID0gMDtcbiAgICB9KTtcblxuICAgIGNoYW5nZTIgPSBjaGFuZ2UxICYmIGNoYW5nZTIgfHwgMDsgLy8gaWYgY2hhbmdlMSBpcyAwLCB3ZSBzZXQgdGh
1hdCB0byB0aGUgZGlmZmVyZW5jZSBhbmQgaWdub3JlIGNoYW5nZTIuIE90aGVyd2lzZSwgdGhlcmUgd291bGQgYmUgYSBjb21wb3VuZCBlZmZlY3QuXG5cbiAgICBjaGFuZ2UxID0gY2hhbmdlMSB8fCBzY3JvbGxUbyAtIGluaXRpYWxWYWx1ZTtcbiAgICB0d2VlbiAmJiB0d2Vlbi5raWxsKCk7XG4gICAgdmFyc1twcm9wXSA9IHNjcm9sbFRvO1xuICAgIHZhcnMuaW5oZXJpdCA9IGZhbHNlO1xuICAgIHZhcnMubW9kaWZpZXJzID0gbW9kaWZpZXJzO1xuXG4gICAgbW9kaWZpZXJzW3Byb3BdID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGNoZWNrRm9ySW50ZXJydXB0aW9uKGluaXRpYWxWYWx1ZSArIGNoYW5nZTEgKiB0d2Vlbi5yYXRpbyArIGNoYW5nZTIgKiB0d2Vlbi5yYXRpbyAqIHR3ZWVuLnJhdGlvKTtcbiAgICB9O1xuXG4gICAgdmFycy5vblVwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIF9zY3JvbGxlcnMuY2FjaGUrKztcbiAgICAgIGdldFR3ZWVuLnR3ZWVuICYmIF91cGRhdGVBbGwoKTsgLy8gaWYgaXQgd2FzIGludGVycnVwdGVkL2tpbGxlZCwgbGlrZSBpbiBhIGNvbnRleHQucmV2ZXJ0KCksIGRvbid0IGZvcmNlIGFuIHVwZGF0ZUFsbCgpXG4gICAgfTtcblxuICAgIHZhcnMub25Db21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGdldFR3ZWVuLnR3ZWVuID0gMDtcbiAgICAgIG9uQ29tcGxldGUgJiYgb25Db21wbGV0ZS5jYWxsKHR3ZWVuKTtcbiAgICB9O1xuXG4gICAgdHdlZW4gPSBnZXRUd2Vlbi50d2VlbiA9IGdzYXAudG8oc2Nyb2xsZXIsIHZhcnMpO1xuICAgIHJldHVybiB0d2VlbjtcbiAgfTtcblxuICBzY3JvbGxlcltwcm9wXSA9IGdldFNjcm9sbDtcblxuICBnZXRTY3JvbGwud2hlZWxIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBnZXRUd2Vlbi50d2VlbiAmJiBnZXRUd2Vlbi50d2Vlbi5raWxsKCkgJiYgKGdldFR3ZWVuLnR3ZWVuID0gMCk7XG4gIH07XG5cbiAgX2FkZExpc3RlbmVyKHNjcm9sbGVyLCBcIndoZWVsXCIsIGdldFNjcm9sbC53aGVlbEhhbmRsZXIpOyAvLyBXaW5kb3dzIG1hY2hpbmVzIGhhbmRsZSBtb3VzZXdoZWVsIHNjcm9sbGluZyBpbiBjaHVua3MgKGxpa2UgXCIzIGxpbmVzIHBlciBzY3JvbGxcIikgbWVhbmluZyB0aGUgdHlwaWNhbCBzdHJhdGVneSBmb3IgY2FuY2VsbGluZyB0aGUgc2Nyb2xsIGlzbid0IGFzIHNlbnNpdGl2ZS4gSXQncyBtdWNoIG1vcmUgbGlrZWx5IHRvIG1hdGNoIG9uZSBvZiB0aGUgcHJldmlvdXMgMiBzY3JvbGwgZXZlbnQgcG9zaXRpb25zLiBTbyB3ZSBraWxsIGFueSBzbmFwcGluZyBhcyBzb29uIGFzIHRoZXJlJ3MgYSB3aGVlbCBldmVudC5cblxuXG4gIFNjcm9sbFRyaWdnZXIuaXNUb3VjaCAmJiBfYWRkTGlzdGVuZXIoc2Nyb2xsZXIsIFwidG91Y2htb3ZlXCIsIGdldFNjcm9sbC53aGVlbEhhbmRsZXIpO1xuICByZXR1cm4gZ2V0VHdlZW47XG59O1xuXG5leHBvcnQgdmFyIFNjcm9sbFRyaWdnZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTY3JvbGxUcmlnZ2VyKHZhcnMsIGFuaW1hdGlvbikge1xuICAgIF9jb3JlSW5pdHRlZCB8fCBTY3JvbGxUcmlnZ2VyLnJlZ2lzdGVyKGdzYXApIHx8IGNvbnNvbGUud2FybihcIlBsZWFzZSBnc2FwLnJlZ2lzdGVyUGx1Z2luKFNjcm9sbFRyaWdnZXIpXCIpO1xuXG4gICAgX2NvbnRleHQodGhpcyk7XG5cbiAgICB0aGlzLmluaXQodmFycywgYW5pbWF0aW9uKTtcbiAgfVxuXG4gIHZhciBfcHJvdG8gPSBTY3JvbGxUcmlnZ2VyLnByb3RvdHlwZTtcblxuICBfcHJvdG8uaW5pdCA9IGZ1bmN0aW9uIGluaXQodmFycywgYW5pbWF0aW9uKSB7XG4gICAgdGhpcy5wcm9ncmVzcyA9IHRoaXMuc3RhcnQgPSAwO1xuICAgIHRoaXMudmFycyAmJiB0aGlzLmtpbGwodHJ1ZSwgdHJ1ZSk7IC8vIGluIGNhc2UgaXQncyBiZWluZyBpbml0dGVkIGFnYWluXG5cbiAgICBpZiAoIV9lbmFibGVkKSB7XG4gICAgICB0aGlzLnVwZGF0ZSA9IHRoaXMucmVmcmVzaCA9IHRoaXMua2lsbCA9IF9wYXNzVGhyb3VnaDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXJzID0gX3NldERlZmF1bHRzKF9pc1N0cmluZyh2YXJzKSB8fCBfaXNOdW1iZXIodmFycykgfHwgdmFycy5ub2RlVHlwZSA/IHtcbiAgICAgIHRyaWdnZXI6IHZhcnNcbiAgICB9IDogdmFycywgX2RlZmF1bHRzKTtcblxuICAgIHZhciBfdmFycyA9IHZhcnMsXG4gICAgICAgIG9uVXBkYXRlID0gX3ZhcnMub25VcGRhdGUsXG4gICAgICAgIHRvZ2dsZUNsYXNzID0gX3ZhcnMudG9nZ2xlQ2xhc3MsXG4gICAgICAgIGlkID0gX3ZhcnMuaWQsXG4gICAgICAgIG9uVG9nZ2xlID0gX3ZhcnMub25Ub2dnbGUsXG4gICAgICAgIG9uUmVmcmVzaCA9IF92YXJzLm9uUmVmcmVzaCxcbiAgICAgICAgc2NydWIgPSBfdmFycy5zY3J1YixcbiAgICAgICAgdHJpZ2dlciA9IF92YXJzLnRyaWdnZXIsXG4gICAgICAgIHBpbiA9IF92YXJzLnBpbixcbiAgICAgICAgcGluU3BhY2luZyA9IF92YXJzLnBpblNwYWNpbmcsXG4gICAgICAgIGludmFsaWRhdGVPblJlZnJlc2ggPSBfdmFycy5pbnZhbGlkYXRlT25SZWZyZXNoLFxuICAgICAgICBhbnRpY2lwYXRlUGluID0gX3ZhcnMuYW50aWNpcGF0ZVBpbixcbiAgICAgICAgb25TY3J1YkNvbXBsZXRlID0gX3ZhcnMub25TY3J1YkNvbXBsZXRlLFxuICAgICAgICBvblNuYXBDb21wbGV0ZSA9IF92YXJzLm9uU25hcENvbXBsZXRlLFxuICAgICAgICBvbmNlID0gX3ZhcnMub25jZSxcbiAgICAgICAgc25hcCA9IF92YXJzLnNuYXAsXG4gICAgICAgIHBpblJlcGFyZW50ID0gX3ZhcnMucGluUmVwYXJlbnQsXG4gICAgICAgIHBpblNwYWNlciA9IF92YXJzLnBpblNwYWNlcixcbiAgICAgICAgY29udGFpbmVyQW5pbWF0aW9uID0gX3ZhcnMuY29udGFpbmVyQW5pbWF0aW9uLFxuICAgICAgICBmYXN0U2Nyb2xsRW5kID0gX3ZhcnMuZmFzdFNjcm9sbEVuZCxcbiAgICAgICAgcHJldmVudE92ZXJsYXBzID0gX3ZhcnMucHJldmVudE92ZXJsYXBzLFxuICAgICAgICBkaXJlY3Rpb24gPSB2YXJzLmhvcml6b250YWwgfHwgdmFycy5jb250YWluZXJBbmltYXRpb24gJiYgdmFycy5ob3Jpem9udGFsICE9PSBmYWxzZSA/IF9ob3Jpem9udGFsIDogX3ZlcnRpY2FsLFxuICAgICAgICBpc1RvZ2dsZSA9ICFzY3J1YiAmJiBzY3J1YiAhPT0gMCxcbiAgICAgICAgc2Nyb2xsZXIgPSBfZ2V0VGFyZ2V0KHZhcnMuc2Nyb2xsZXIgfHwgX3dpbiksXG4gICAgICAgI
1HNjcm9sbGVyQ2FjaGUgPSBnc2FwLmNvcmUuZ2V0Q2FjaGUoc2Nyb2xsZXIpLFxuICAgICAgICBpc1ZpZXdwb3J0ID0gX2lzVmlld3BvcnQoc2Nyb2xsZXIpLFxuICAgICAgICB1c2VGaXhlZFBvc2l0aW9uID0gKFwicGluVHlwZVwiIGluIHZhcnMgPyB2YXJzLnBpblR5cGUgOiBfZ2V0UHJveHlQcm9wKHNjcm9sbGVyLCBcInBpblR5cGVcIikgfHwgaXNWaWV3cG9ydCAmJiBcImZpeGVkXCIpID09PSBcImZpeGVkXCIsXG4gICAgICAgIGNhbGxiYWNrcyA9IFt2YXJzLm9uRW50ZXIsIHZhcnMub25MZWF2ZSwgdmFycy5vbkVudGVyQmFjaywgdmFycy5vbkxlYXZlQmFja10sXG4gICAgICAgIHRvZ2dsZUFjdGlvbnMgPSBpc1RvZ2dsZSAmJiB2YXJzLnRvZ2dsZUFjdGlvbnMuc3BsaXQoXCIgXCIpLFxuICAgICAgICBtYXJrZXJzID0gXCJtYXJrZXJzXCIgaW4gdmFycyA/IHZhcnMubWFya2VycyA6IF9kZWZhdWx0cy5tYXJrZXJzLFxuICAgICAgICBib3JkZXJXaWR0aCA9IGlzVmlld3BvcnQgPyAwIDogcGFyc2VGbG9hdChfZ2V0Q29tcHV0ZWRTdHlsZShzY3JvbGxlcilbXCJib3JkZXJcIiArIGRpcmVjdGlvbi5wMiArIF9XaWR0aF0pIHx8IDAsXG4gICAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgICBvblJlZnJlc2hJbml0ID0gdmFycy5vblJlZnJlc2hJbml0ICYmIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB2YXJzLm9uUmVmcmVzaEluaXQoc2VsZik7XG4gICAgfSxcbiAgICAgICAgZ2V0U2Nyb2xsZXJTaXplID0gX2dldFNpemVGdW5jKHNjcm9sbGVyLCBpc1ZpZXdwb3J0LCBkaXJlY3Rpb24pLFxuICAgICAgICBnZXRTY3JvbGxlck9mZnNldHMgPSBfZ2V0T2Zmc2V0c0Z1bmMoc2Nyb2xsZXIsIGlzVmlld3BvcnQpLFxuICAgICAgICBsYXN0U25hcCA9IDAsXG4gICAgICAgIGxhc3RSZWZyZXNoID0gMCxcbiAgICAgICAgcHJldlByb2dyZXNzID0gMCxcbiAgICAgICAgc2Nyb2xsRnVuYyA9IF9nZXRTY3JvbGxGdW5jKHNjcm9sbGVyLCBkaXJlY3Rpb24pLFxuICAgICAgICB0d2VlblRvLFxuICAgICAgICBwaW5DYWNoZSxcbiAgICAgICAgc25hcEZ1bmMsXG4gICAgICAgIHNjcm9sbDEsXG4gICAgICAgIHNjcm9sbDIsXG4gICAgICAgIHN0YXJ0LFxuICAgICAgICBlbmQsXG4gICAgICAgIG1hcmtlclN0YXJ0LFxuICAgICAgICBtYXJrZXJFbmQsXG4gICAgICAgIG1hcmtlclN0YXJ0VHJpZ2dlcixcbiAgICAgICAgbWFya2VyRW5kVHJpZ2dlcixcbiAgICAgICAgbWFya2VyVmFycyxcbiAgICAgICAgZXhlY3V0aW5nT25SZWZyZXNoLFxuICAgICAgICBjaGFuZ2UsXG4gICAgICAgIHBpbk9yaWdpbmFsU3RhdGUsXG4gICAgICAgIHBpbkFjdGl2ZVN0YXRlLFxuICAgICAgICBwaW5TdGF0ZSxcbiAgICAgICAgc3BhY2VyLFxuICAgICAgICBvZmZzZXQsXG4gICAgICAgIHBpbkdldHRlcixcbiAgICAgICAgcGluU2V0dGVyLFxuICAgICAgICBwaW5TdGFydCxcbiAgICAgICAgcGluQ2hhbmdlLFxuICAgICAgICBzcGFjaW5nU3RhcnQsXG4gICAgICAgIHNwYWNlclN0YXRlLFxuICAgICAgICBtYXJrZXJTdGFydFNldHRlcixcbiAgICAgICAgcGluTW92ZXMsXG4gICAgICAgIG1hcmtlckVuZFNldHRlcixcbiAgICAgICAgY3MsXG4gICAgICAgIHNuYXAxLFxuICAgICAgICBzbmFwMixcbiAgICAgICAgc2NydWJUd2VlbixcbiAgICAgICAgc2NydWJTbW9vdGgsXG4gICAgICAgIHNuYXBEdXJDbGFtcCxcbiAgICAgICAgc25hcERlbGF5ZWRDYWxsLFxuICAgICAgICBwcmV2U2Nyb2xsLFxuICAgICAgICBwcmV2QW5pbVByb2dyZXNzLFxuICAgICAgICBjYU1hcmtlclNldHRlcixcbiAgICAgICAgY3VzdG9tUmV2ZXJ0UmV0dXJuOyAvLyBmb3IgdGhlIHNha2Ugb2YgZWZmaWNpZW5jeSwgX3N0YXJ0Q2xhbXAvX2VuZENsYW1wIHNlcnZlIGxpa2UgYSB0cnV0aHkgdmFsdWUgaW5kaWNhdGluZyB0aGF0IGNsYW1waW5nIHdhcyBlbmFibGVkIG9uIHRoZSBzdGFydC9lbmQsIGFuZCBBTFNPIHN0b3JlIHRoZSBhY3R1YWwgcHJlLWNsYW1wZWQgbnVtZXJpYyB2YWx1ZS4gV2UgdGFwIGludG8gdGhhdCBpbiBTY3JvbGxTbW9vdGhlciBmb3Igc3BlZWQgZWZmZWN0cy4gU28gZm9yIGV4YW1wbGUsIGlmIHN0YXJ0PVwiY2xhbXAodG9wIGJvdHRvbSlcIiByZXN1bHRzIGluIGEgc3RhcnQgb2YgLTEwMCBuYXR1cmFsbHksIGl0IHdvdWxkIGdldCBjbGFtcGVkIHRvIDAgYnV0IC0xMDAgd291bGQgYmUgc3RvcmVkIGluIF9zdGFydENsYW1wLlxuXG5cbiAgICBzZWxmLl9zdGFydENsYW1wID0gc2VsZi5fZW5kQ2xhbXAgPSBmYWxzZTtcbiAgICBzZWxmLl9kaXIgPSBkaXJlY3Rpb247XG4gICAgYW50aWNpcGF0ZVBpbiAqPSA0NTtcbiAgICBzZWxmLnNjcm9sbGVyID0gc2Nyb2xsZXI7XG4gICAgc2VsZi5zY3JvbGwgPSBjb250YWluZXJBbmltYXRpb24gPyBjb250YWluZXJBbmltYXRpb24udGltZS5iaW5kKGNvbnRhaW5lckFuaW1hdGlvbikgOiBzY3JvbGxGdW5jO1xuICAgIHNjcm9sbDEgPSBzY3JvbGxGdW5jKCk7XG4gICAgc2VsZi52YXJzID0gdmFycztcbiAgICBhbmltYXRpb24gPSBhbmltYXRpb24gfHwgdmFycy5hbmltYXRpb247XG5cbiAgICBpZiAoXCJyZWZyZXNoUHJpb3JpdHlcIiBpbiB2YXJzKSB7XG4gICAgICBfc29ydCA9IDE7XG4gICAgICB2Y
1XJzLnJlZnJlc2hQcmlvcml0eSA9PT0gLTk5OTkgJiYgKF9wcmltYXJ5ID0gc2VsZik7IC8vIHVzZWQgYnkgU2Nyb2xsU21vb3RoZXJcbiAgICB9XG5cbiAgICBzY3JvbGxlckNhY2hlLnR3ZWVuU2Nyb2xsID0gc2Nyb2xsZXJDYWNoZS50d2VlblNjcm9sbCB8fCB7XG4gICAgICB0b3A6IF9nZXRUd2VlbkNyZWF0b3Ioc2Nyb2xsZXIsIF92ZXJ0aWNhbCksXG4gICAgICBsZWZ0OiBfZ2V0VHdlZW5DcmVhdG9yKHNjcm9sbGVyLCBfaG9yaXpvbnRhbClcbiAgICB9O1xuICAgIHNlbGYudHdlZW5UbyA9IHR3ZWVuVG8gPSBzY3JvbGxlckNhY2hlLnR3ZWVuU2Nyb2xsW2RpcmVjdGlvbi5wXTtcblxuICAgIHNlbGYuc2NydWJEdXJhdGlvbiA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgc2NydWJTbW9vdGggPSBfaXNOdW1iZXIodmFsdWUpICYmIHZhbHVlO1xuXG4gICAgICBpZiAoIXNjcnViU21vb3RoKSB7XG4gICAgICAgIHNjcnViVHdlZW4gJiYgc2NydWJUd2Vlbi5wcm9ncmVzcygxKS5raWxsKCk7XG4gICAgICAgIHNjcnViVHdlZW4gPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2NydWJUd2VlbiA/IHNjcnViVHdlZW4uZHVyYXRpb24odmFsdWUpIDogc2NydWJUd2VlbiA9IGdzYXAudG8oYW5pbWF0aW9uLCB7XG4gICAgICAgICAgZWFzZTogXCJleHBvXCIsXG4gICAgICAgICAgdG90YWxQcm9ncmVzczogXCIrPTBcIixcbiAgICAgICAgICBpbmhlcml0OiBmYWxzZSxcbiAgICAgICAgICBkdXJhdGlvbjogc2NydWJTbW9vdGgsXG4gICAgICAgICAgcGF1c2VkOiB0cnVlLFxuICAgICAgICAgIG9uQ29tcGxldGU6IGZ1bmN0aW9uIG9uQ29tcGxldGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gb25TY3J1YkNvbXBsZXRlICYmIG9uU2NydWJDb21wbGV0ZShzZWxmKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoYW5pbWF0aW9uKSB7XG4gICAgICBhbmltYXRpb24udmFycy5sYXp5ID0gZmFsc2U7XG4gICAgICBhbmltYXRpb24uX2luaXR0ZWQgJiYgIXNlbGYuaXNSZXZlcnRlZCB8fCBhbmltYXRpb24udmFycy5pbW1lZGlhdGVSZW5kZXIgIT09IGZhbHNlICYmIHZhcnMuaW1tZWRpYXRlUmVuZGVyICE9PSBmYWxzZSAmJiBhbmltYXRpb24uZHVyYXRpb24oKSAmJiBhbmltYXRpb24ucmVuZGVyKDAsIHRydWUsIHRydWUpOyAvLyBzcGVjaWFsIGNhc2U6IGlmIHRoaXMgU2Nyb2xsVHJpZ2dlciBnZXRzIHJlLWluaXR0ZWQsIGEgZnJvbSgpIHR3ZWVuIHdpdGggYSBzdGFnZ2VyIGNvdWxkIGdldCBpbml0dGVkIGluaXRpYWxseSBhbmQgdGhlbiByZXZlcnRlZCBvbiB0aGUgcmUtaW5pdCB3aGljaCBtZWFucyBpdCdsbCBuZWVkIHRvIGdldCByZW5kZXJlZCBhZ2FpbiBoZXJlIHRvIHByb3Blcmx5IGRpc3BsYXkgdGhpbmdzLiBPdGhlcndpc2UsIFNlZSBodHRwczovL2dzYXAuY29tL2ZvcnVtcy90b3BpYy8zNjc3Ny1zY3JvbGxzbW9vdGhlci1zcGxpdHRleHQtbmV4dGpzLyBhbmQgaHR0cHM6Ly9jb2RlcGVuLmlvL0dyZWVuU29jay9wZW4vZVlQeVBwZD9lZGl0b3JzPTAwMTBcblxuICAgICAgc2VsZi5hbmltYXRpb24gPSBhbmltYXRpb24ucGF1c2UoKTtcbiAgICAgIGFuaW1hdGlvbi5zY3JvbGxUcmlnZ2VyID0gc2VsZjtcbiAgICAgIHNlbGYuc2NydWJEdXJhdGlvbihzY3J1Yik7XG4gICAgICBzbmFwMSA9IDA7XG4gICAgICBpZCB8fCAoaWQgPSBhbmltYXRpb24udmFycy5pZCk7XG4gICAgfVxuXG4gICAgaWYgKHNuYXApIHtcbiAgICAgIC8vIFRPRE86IHBvdGVudGlhbCBpZGVhOiB1c2UgbGVnaXRpbWF0ZSBDU1Mgc2Nyb2xsIHNuYXBwaW5nIGJ5IHB1c2hpbmcgaW52aXNpYmxlIGVsZW1lbnRzIGludG8gdGhlIERPTSB0aGF0IHNlcnZlIGFzIHNuYXAgcG9zaXRpb25zLCBhbmQgdG9nZ2xlIHRoZSBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50LnN0eWxlLnNjcm9sbFNuYXBUeXBlIG9uVG9nZ2xlLiBTZWUgaHR0cHM6Ly9jb2RlcGVuLmlvL0dyZWVuU29jay9wZW4vSmpMcmdXTSBmb3IgYSBxdWljayBwcm9vZiBvZiBjb25jZXB0LlxuICAgICAgaWYgKCFfaXNPYmplY3Qoc25hcCkgfHwgc25hcC5wdXNoKSB7XG4gICAgICAgIHNuYXAgPSB7XG4gICAgICAgICAgc25hcFRvOiBzbmFwXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIFwic2Nyb2xsQmVoYXZpb3JcIiBpbiBfYm9keS5zdHlsZSAmJiBnc2FwLnNldChpc1ZpZXdwb3J0ID8gW19ib2R5LCBfZG9jRWxdIDogc2Nyb2xsZXIsIHtcbiAgICAgICAgc2Nyb2xsQmVoYXZpb3I6IFwiYXV0b1wiXG4gICAgICB9KTsgLy8gc21vb3RoIHNjcm9sbGluZyBkb2Vzbid0IHdvcmsgd2l0aCBzbmFwLlxuXG4gICAgICBfc2Nyb2xsZXJzLmZvckVhY2goZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgcmV0dXJuIF9pc0Z1bmN0aW9uKG8pICYmIG8udGFyZ2V0ID09PSAoaXNWaWV3cG9ydCA/IF9kb2Muc2Nyb2xsaW5nRWxlbWVudCB8fCBfZG9jRWwgOiBzY3JvbGxlcikgJiYgKG8uc21vb3RoID0gZmFsc2UpO1xuICAgICAgfSk7IC8vIG5vdGU6IHNldCBzbW9vdGggdG8gZmFsc2Ugb24gYm90aCB0aGUgdmVydGljYWwgYW5kIGhvcml6b250YWwgc2Nyb2xsIGdldHRlcnMvc2V0dGVyc1xuXG5cbiAgICAgIHNuYXBGdW5jID0gX2lzRnVuY3Rpb24oc25hcC5zbmFwVG8pID8gc25hcC5zbmFwVG8gOiBzbmFwLnNuYXBUbyA9PT0gXCJsYWJlbHNcIiA/IF9nZXRDbG9zZXN0TGFiZWwoYW5pbWF0aW9uKSA6IHNuYXAuc25hcFRvID09PSBcImxhYmVsc0RpcmVjdGlvbmFsXCIgPyBfZ2V0TGFiZWxBdERpcmVjdGlvbihhbmltYXRpb24pIDogc25hcC5kaXJlY3Rpb25hbCAhPT0gZmFsc2UgPyBmdW5jdGlvbiAodmFsdWUsIHN0KSB7XG4gICAgICAgIHJldHVybiBfc25hcERpcmVjdGlvbmFsKHNuYXAuc25hcFRvKSh2YWx1ZSwgX2dldFRpbWUoKSAtIGxhc3RSZWZyZXNoIDwgNTAwID8gMCA6IHN0LmRpcmVjdGlvbik7XG4gICAgICB9IDogZ3NhcC51dGlscy5zbmFwKHNuYXAuc25hcFRvKTtcbiAgICAgIHNuYXBEdXJDbGFtcCA9IHNuYXAuZHVyYXRpb24gfHwge1xuICAgICAgICBtaW46IDAuMSxcbiAgICAgICAgbWF4OiAyXG4gICAgICB9O1xuICAgICAgc25hcER1ckNsYW1wID0gX2lzT2JqZWN0KHNuYXBEdXJDbGFtcCkgPyBfY2xhbXAoc25hcER1ckNsYW1wLm1pbiwgc25hcER1ckNsYW1wLm1heCkgOiBfY2xhbXAoc25hcER1ckNsYW1wLCBzbmFwRHVyQ2xhbXApO1xuICAgICAgc25hcERlbGF5ZWRDYWxsID0gZ3NhcC5kZWxheWVkQ2FsbChzbmFwLmRlbGF5IHx8IHNjcnViU21vb3RoIC8gMiB8fCAwLjEsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNjcm9sbCA9IHNjcm9sbEZ1bmMoKSxcbiAgICAgICAgICAgI
1HJlZnJlc2hlZFJlY2VudGx5ID0gX2dldFRpbWUoKSAtIGxhc3RSZWZyZXNoIDwgNTAwLFxuICAgICAgICAgICAgdHdlZW4gPSB0d2VlblRvLnR3ZWVuO1xuXG4gICAgICAgIGlmICgocmVmcmVzaGVkUmVjZW50bHkgfHwgTWF0aC5hYnMoc2VsZi5nZXRWZWxvY2l0eSgpKSA8IDEwKSAmJiAhdHdlZW4gJiYgIV9wb2ludGVySXNEb3duICYmIGxhc3RTbmFwICE9PSBzY3JvbGwpIHtcbiAgICAgICAgICB2YXIgcHJvZ3Jlc3MgPSAoc2Nyb2xsIC0gc3RhcnQpIC8gY2hhbmdlLFxuICAgICAgICAgICAgICB0b3RhbFByb2dyZXNzID0gYW5pbWF0aW9uICYmICFpc1RvZ2dsZSA/IGFuaW1hdGlvbi50b3RhbFByb2dyZXNzKCkgOiBwcm9ncmVzcyxcbiAgICAgICAgICAgICAgdmVsb2NpdHkgPSByZWZyZXNoZWRSZWNlbnRseSA/IDAgOiAodG90YWxQcm9ncmVzcyAtIHNuYXAyKSAvIChfZ2V0VGltZSgpIC0gX3RpbWUyKSAqIDEwMDAgfHwgMCxcbiAgICAgICAgICAgICAgY2hhbmdlMSA9IGdzYXAudXRpbHMuY2xhbXAoLXByb2dyZXNzLCAxIC0gcHJvZ3Jlc3MsIF9hYnModmVsb2NpdHkgLyAyKSAqIHZlbG9jaXR5IC8gMC4xODUpLFxuICAgICAgICAgICAgICBuYXR1cmFsRW5kID0gcHJvZ3Jlc3MgKyAoc25hcC5pbmVydGlhID09PSBmYWxzZSA/IDAgOiBjaGFuZ2UxKSxcbiAgICAgICAgICAgICAgZW5kVmFsdWUsXG4gICAgICAgICAgICAgIGVuZFNjcm9sbCxcbiAgICAgICAgICAgICAgX3NuYXAgPSBzbmFwLFxuICAgICAgICAgICAgICBvblN0YXJ0ID0gX3NuYXAub25TdGFydCxcbiAgICAgICAgICAgICAgX29uSW50ZXJydXB0ID0gX3NuYXAub25JbnRlcnJ1cHQsXG4gICAgICAgICAgICAgIF9vbkNvbXBsZXRlID0gX3NuYXAub25Db21wbGV0ZTtcbiAgICAgICAgICBlbmRWYWx1ZSA9IHNuYXBGdW5jKG5hdHVyYWxFbmQsIHNlbGYpO1xuICAgICAgICAgIF9pc051bWJlcihlbmRWYWx1ZSkgfHwgKGVuZFZhbHVlID0gbmF0dXJhbEVuZCk7IC8vIGluIGNhc2UgdGhlIGZ1bmN0aW9uIGRpZG4ndCByZXR1cm4gYSBudW1iZXIsIGZhbGwgYmFjayB0byB1c2luZyB0aGUgbmF0dXJhbEVuZFxuXG4gICAgICAgICAgZW5kU2Nyb2xsID0gTWF0aC5yb3VuZChzdGFydCArIGVuZFZhbHVlICogY2hhbmdlKTtcblxuICAgICAgICAgIGlmIChzY3JvbGwgPD0gZW5kICYmIHNjcm9sbCA+PSBzdGFydCAmJiBlbmRTY3JvbGwgIT09IHNjcm9sbCkge1xuICAgICAgICAgICAgaWYgKHR3ZWVuICYmICF0d2Vlbi5faW5pdHRlZCAmJiB0d2Vlbi5kYXRhIDw9IF9hYnMoZW5kU2Nyb2xsIC0gc2Nyb2xsKSkge1xuICAgICAgICAgICAgICAvLyB0aGVyZSdzIGFuIG92ZXJsYXBwaW5nIHNuYXAhIFNvIHdlIG11c3QgZmlndXJlIG91dCB3aGljaCBvbmUgaXMgY2xvc2VyIGFuZCBsZXQgdGhhdCB0d2VlbiBsaXZlLlxuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzbmFwLmluZXJ0aWEgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIGNoYW5nZTEgPSBlbmRWYWx1ZSAtIHByb2dyZXNzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0d2VlblRvKGVuZFNjcm9sbCwge1xuICAgICAgICAgICAgICBkdXJhdGlvbjogc25hcER1ckNsYW1wKF9hYnMoTWF0aC5tYXgoX2FicyhuYXR1cmFsRW5kIC0gdG90YWxQcm9ncmVzcyksIF9hYnMoZW5kVmFsdWUgLSB0b3RhbFByb2dyZXNzKSkgKiAwLjE4NSAvIHZlbG9jaXR5IC8gMC4wNSB8fCAwKSksXG4gICAgICAgICAgICAgIGVhc2U6IHNuYXAuZWFzZSB8fCBcInBvd2VyM1wiLFxuICAgICAgICAgICAgICBkYXRhOiBfYWJzKGVuZFNjcm9sbCAtIHNjcm9sbCksXG4gICAgICAgICAgICAgIC8vIHJlY29yZCB0aGUgZGlzdGFuY2Ugc28gdGhhdCBpZiBhbm90aGVyIHNuYXAgdHdlZW4gb2NjdXJzIChjb25mbGljdCkgd2UgY2FuIHByaW9yaXRpemUgdGhlIGNsb3Nlc3Qgc25hcC5cbiAgICAgICAgICAgICAgb25JbnRlcnJ1cHQ6IGZ1bmN0aW9uIG9uSW50ZXJydXB0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzbmFwRGVsYXllZENhbGwucmVzdGFydCh0cnVlKSAmJiBfb25JbnRlcnJ1cHQgJiYgX29uSW50ZXJydXB0KHNlbGYpO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBvbkNvbXBsZXRlOiBmdW5jdGlvbiBvbkNvbXBsZXRlKCkge1xuICAgICAgICAgICAgICAgIHNlbGYudXBkYXRlKCk7XG4gICAgICAgICAgICAgICAgbGFzdFNuYXAgPSBzY3JvbGxGdW5jKCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoYW5pbWF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAvLyB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgc2Nyb2xsYmFyIGlzIGxpbWl0ZWQsIHNvIHdlIHNob3VsZCBjb3JyZWN0IHRoZSBzY3J1YmJlZCBhbmltYXRpb24ncyBwbGF5aGVhZCBhdCB0aGUgZW5kIHRvIG1hdGNoIEVYQUNUTFkgd2hlcmUgaXQgd2FzIHN1cHBvc2VkIHRvIHNuYXBcbiAgICAgICAgICAgICAgICAgIHNjcnViVHdlZW4gPyBzY3J1YlR3ZWVuLnJlc2V0VG8oXCJ0b3RhbFByb2dyZXNzXCIsIGVuZFZhbHVlLCBhbmltYXRpb24uX3RUaW1lIC8gYW5pbWF0aW9uLl90RHVyKSA6IGFuaW1hdGlvbi5wcm9ncmVzcyhlbmRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgc25hcDEgPSBzbmFwMiA9IGFuaW1hdGlvbiAmJiAhaXNUb2dnbGUgPyBhbmltYXRpb24udG90YWxQcm9ncmVzcygpIDogc2VsZi5wcm9ncmVzcztcbiAgICAgICAgICAgICAgICBvblNuYXBDb21wbGV0ZSAmJiBvblNuYXBDb21wbGV0ZShzZWxmKTtcbiAgICAgICAgICAgICAgICBfb25Db21wbGV0ZSAmJiBfb25Db21wbGV0ZShzZWxmKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgc2Nyb2xsLCBjaGFuZ2UxICogY2hhbmdlLCBlbmRTY3JvbGwgLSBzY3JvbGwgLSBjaGFuZ2UxICogY2hhbmdlKTtcbiAgICAgICAgICAgIG9uU3RhcnQgJiYgb25TdGFydChzZWxmLCB0d2VlblRvLnR3ZWVuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoc2VsZi5pc0FjdGl2ZSAmJiBsYXN0U25hcCAhPT0gc2Nyb2xsKSB7XG4gICAgICAgICAgc25hcERlbGF5ZWRDYWxsLnJlc3RhcnQodHJ1ZSk7XG4gICAgICAgI
1H1cbiAgICAgIH0pLnBhdXNlKCk7XG4gICAgfVxuXG4gICAgaWQgJiYgKF9pZHNbaWRdID0gc2VsZik7XG4gICAgdHJpZ2dlciA9IHNlbGYudHJpZ2dlciA9IF9nZXRUYXJnZXQodHJpZ2dlciB8fCBwaW4gIT09IHRydWUgJiYgcGluKTsgLy8gaWYgYSB0cmlnZ2VyIGhhcyBzb21lIGtpbmQgb2Ygc2Nyb2xsLXJlbGF0ZWQgZWZmZWN0IGFwcGxpZWQgdGhhdCBjb3VsZCBjb250YW1pbmF0ZSB0aGUgXCJ5XCIgb3IgXCJ4XCIgcG9zaXRpb24gKGxpa2UgYSBTY3JvbGxTbW9vdGhlciBlZmZlY3QpLCB3ZSBuZWVkZWQgYSB3YXkgdG8gdGVtcG9yYXJpbHkgcmV2ZXJ0IGl0LCBzbyB3ZSB1c2UgdGhlIHN0UmV2ZXJ0IHByb3BlcnR5IG9mIHRoZSBnc0NhY2hlLiBJdCBjYW4gcmV0dXJuIGFub3RoZXIgZnVuY3Rpb24gdGhhdCB3ZSdsbCBjYWxsIGF0IHRoZSBlbmQgc28gaXQgY2FuIHJldHVybiB0byBpdHMgbm9ybWFsIHN0YXRlLlxuXG4gICAgY3VzdG9tUmV2ZXJ0UmV0dXJuID0gdHJpZ2dlciAmJiB0cmlnZ2VyLl9nc2FwICYmIHRyaWdnZXIuX2dzYXAuc3RSZXZlcnQ7XG4gICAgY3VzdG9tUmV2ZXJ0UmV0dXJuICYmIChjdXN0b21SZXZlcnRSZXR1cm4gPSBjdXN0b21SZXZlcnRSZXR1cm4oc2VsZikpO1xuICAgIHBpbiA9IHBpbiA9PT0gdHJ1ZSA/IHRyaWdnZXIgOiBfZ2V0VGFyZ2V0KHBpbik7XG4gICAgX2lzU3RyaW5nKHRvZ2dsZUNsYXNzKSAmJiAodG9nZ2xlQ2xhc3MgPSB7XG4gICAgICB0YXJnZXRzOiB0cmlnZ2VyLFxuICAgICAgY2xhc3NOYW1lOiB0b2dnbGVDbGFzc1xuICAgIH0pO1xuXG4gICAgaWYgKHBpbikge1xuICAgICAgcGluU3BhY2luZyA9PT0gZmFsc2UgfHwgcGluU3BhY2luZyA9PT0gX21hcmdpbiB8fCAocGluU3BhY2luZyA9ICFwaW5TcGFjaW5nICYmIHBpbi5wYXJlbnROb2RlICYmIHBpbi5wYXJlbnROb2RlLnN0eWxlICYmIF9nZXRDb21wdXRlZFN0eWxlKHBpbi5wYXJlbnROb2RlKS5kaXNwbGF5ID09PSBcImZsZXhcIiA/IGZhbHNlIDogX3BhZGRpbmcpOyAvLyBpZiB0aGUgcGFyZW50IGlzIGRpc3BsYXk6IGZsZXgsIGRvbid0IGFwcGx5IHBpblNwYWNpbmcgYnkgZGVmYXVsdC4gV2Ugc2hvdWxkIGNoZWNrIHRoYXQgcGluLnBhcmVudE5vZGUgaXMgYW4gZWxlbWVudCAobm90IHNoYWRvdyBkb20gd2luZG93KVxuXG4gICAgICBzZWxmLnBpbiA9IHBpbjtcbiAgICAgIHBpbkNhY2hlID0gZ3NhcC5jb3JlLmdldENhY2hlKHBpbik7XG5cbiAgICAgIGlmICghcGluQ2FjaGUuc3BhY2VyKSB7XG4gICAgICAgIC8vIHJlY29yZCB0aGUgc3BhY2VyIGFuZCBwaW5PcmlnaW5hbFN0YXRlIG9uIHRoZSBjYWNoZSBpbiBjYXNlIHNvbWVvbmUgdHJpZXMgcGlubmluZyB0aGUgc2FtZSBlbGVtZW50IHdpdGggTVVMVElQTEUgU2Nyb2xsVHJpZ2dlcnMgLSB3ZSBkb24ndCB3YW50IHRvIGhhdmUgbXVsdGlwbGUgc3BhY2VycyBvciByZWNvcmQgdGhlIFwib3JpZ2luYWxcIiBwaW4gc3RhdGUgYWZ0ZXIgaXQgaGFzIGFscmVhZHkgYmVlbiBhZmZlY3RlZCBieSBhbm90aGVyIFNjcm9sbFRyaWdnZXIuXG4gICAgICAgIGlmIChwaW5TcGFjZXIpIHtcbiAgICAgICAgICBwaW5TcGFjZXIgPSBfZ2V0VGFyZ2V0KHBpblNwYWNlcik7XG4gICAgICAgICAgcGluU3BhY2VyICYmICFwaW5TcGFjZXIubm9kZVR5cGUgJiYgKHBpblNwYWNlciA9IHBpblNwYWNlci5jdXJyZW50IHx8IHBpblNwYWNlci5uYXRpdmVFbGVtZW50KTsgLy8gZm9yIFJlYWN0ICYgQW5ndWxhclxuXG4gICAgICAgICAgcGluQ2FjaGUuc3BhY2VySXNOYXRpdmUgPSAhIXBpblNwYWNlcjtcbiAgICAgICAgICBwaW5TcGFjZXIgJiYgKHBpbkNhY2hlLnNwYWNlclN0YXRlID0gX2dldFN0YXRlKHBpblNwYWNlcikpO1xuICAgICAgICB9XG5cbiAgICAgICAgcGluQ2FjaGUuc3BhY2VyID0gc3BhY2VyID0gcGluU3BhY2VyIHx8IF9kb2MuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgc3BhY2VyLmNsYXNzTGlzdC5hZGQoXCJwaW4tc3BhY2VyXCIpO1xuICAgICAgICBpZCAmJiBzcGFjZXIuY2xhc3NMaXN0LmFkZChcInBpbi1zcGFjZXItXCIgKyBpZCk7XG4gICAgICAgIHBpbkNhY2hlLnBpblN0YXRlID0gcGluT3JpZ2luYWxTdGF0ZSA9IF9nZXRTdGF0ZShwaW4pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGluT3JpZ2luYWxTdGF0ZSA9IHBpbkNhY2hlLnBpblN0YXRlO1xuICAgICAgfVxuXG4gICAgICB2Y
1XJzLmZvcmNlM0QgIT09IGZhbHNlICYmIGdzYXAuc2V0KHBpbiwge1xuICAgICAgICBmb3JjZTNEOiB0cnVlXG4gICAgICB9KTtcbiAgICAgIHNlbGYuc3BhY2VyID0gc3BhY2VyID0gcGluQ2FjaGUuc3BhY2VyO1xuICAgICAgY3MgPSBfZ2V0Q29tcHV0ZWRTdHlsZShwaW4pO1xuICAgICAgc3BhY2luZ1N0YXJ0ID0gY3NbcGluU3BhY2luZyArIGRpcmVjdGlvbi5vczJdO1xuICAgICAgcGluR2V0dGVyID0gZ3NhcC5nZXRQcm9wZXJ0eShwaW4pO1xuICAgICAgcGluU2V0dGVyID0gZ3NhcC5xdWlja1NldHRlcihwaW4sIGRpcmVjdGlvbi5hLCBfcHgpOyAvLyBwaW4uZmlyc3RDaGlsZCAmJiAhX21heFNjcm9sbChwaW4sIGRpcmVjdGlvbikgJiYgKHBpbi5zdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCIpOyAvLyBwcm90ZWN0cyBmcm9tIGNvbGxhcHNpbmcgbWFyZ2lucywgYnV0IGNhbiBoYXZlIHVuaW50ZW5kZWQgY29uc2VxdWVuY2VzIGFzIGRlbW9uc3RyYXRlZCBoZXJlOiBodHRwczovL2NvZGVwZW4uaW8vR3JlZW5Tb2NrL3Blbi8xZTQyYzdhNzNiZmE0MDlkMmNmMWUxODRlN2E0MjQ4ZCBzbyBpdCB3YXMgcmVtb3ZlZCBpbiBmYXZvciBvZiBqdXN0IHRlbGxpbmcgcGVvcGxlIHRvIHNldCB1cCB0aGVpciBDU1MgdG8gYXZvaWQgdGhlIGNvbGxhcHNpbmcgbWFyZ2lucyAob3ZlcmZsb3c6IGhpZGRlbiB8IGF1dG8gaXMganVzdCBvbmUgb3B0aW9uLiBBbm90aGVyIGlzIGJvcmRlci10b3A6IDFweCBzb2xpZCB0cmFuc3BhcmVudCkuXG5cbiAgICAgIF9zd2FwUGluSW4ocGluLCBzcGFjZXIsIGNzKTtcblxuICAgICAgcGluU3RhdGUgPSBfZ2V0U3RhdGUocGluKTtcbiAgICB9XG5cbiAgICBpZiAobWFya2Vycykge1xuICAgICAgbWFya2VyVmFycyA9IF9pc09iamVjdChtYXJrZXJzKSA/IF9zZXREZWZhdWx0cyhtYXJrZXJzLCBfbWFya2VyRGVmYXVsdHMpIDogX21hcmtlckRlZmF1bHRzO1xuICAgICAgbWFya2VyU3RhcnRUcmlnZ2VyID0gX2NyZWF0ZU1hcmtlcihcInNjcm9sbGVyLXN0YXJ0XCIsIGlkLCBzY3JvbGxlciwgZGlyZWN0aW9uLCBtYXJrZXJWYXJzLCA
1wKTtcbiAgICAgIG1hcmtlckVuZFRyaWdnZXIgPSBfY3JlYXRlTWFya2VyKFwic2Nyb2xsZXItZW5kXCIsIGlkLCBzY3JvbGxlciwgZGlyZWN0aW9uLCBtYXJrZXJWYXJzLCAwLCBtYXJrZXJTdGFydFRyaWdnZXIpO1xuICAgICAgb2Zmc2V0ID0gbWFya2VyU3RhcnRUcmlnZ2VyW1wib2Zmc2V0XCIgKyBkaXJlY3Rpb24ub3AuZDJdO1xuXG4gICAgICB2YXIgY29udGVudCA9IF9nZXRUYXJnZXQoX2dldFByb3h5UHJvcChzY3JvbGxlciwgXCJjb250ZW50XCIpIHx8IHNjcm9sbGVyKTtcblxuICAgICAgbWFya2VyU3RhcnQgPSB0aGlzLm1hcmtlclN0YXJ0ID0gX2NyZWF0ZU1hcmtlcihcInN0YXJ0XCIsIGlkLCBjb250ZW50LCBkaXJlY3Rpb24sIG1hcmtlclZhcnMsIG9mZnNldCwgMCwgY29udGFpbmVyQW5pbWF0aW9uKTtcbiAgICAgIG1hcmtlckVuZCA9IHRoaXMubWFya2VyRW5kID0gX2NyZWF0ZU1hcmtlcihcImVuZFwiLCBpZCwgY29udGVudCwgZGlyZWN0aW9uLCBtYXJrZXJWYXJzLCBvZmZzZXQsIDAsIGNvbnRhaW5lckFuaW1hdGlvbik7XG4gICAgICBjb250YWluZXJBbmltYXRpb24gJiYgKGNhTWFya2VyU2V0dGVyID0gZ3NhcC5xdWlja1NldHRlcihbbWFya2VyU3RhcnQsIG1hcmtlckVuZF0sIGRpcmVjdGlvbi5hLCBfcHgpKTtcblxuICAgICAgaWYgKCF1c2VGaXhlZFBvc2l0aW9uICYmICEoX3Byb3hpZXMubGVuZ3RoICYmIF9nZXRQcm94eVByb3Aoc2Nyb2xsZXIsIFwiZml4ZWRNYXJrZXJzXCIpID09PSB0cnVlKSkge1xuICAgICAgICBfbWFrZVBvc2l0aW9uYWJsZShpc1ZpZXdwb3J0ID8gX2JvZHkgOiBzY3JvbGxlcik7XG5cbiAgICAgICAgZ3NhcC5zZXQoW21hcmtlclN0YXJ0VHJpZ2dlciwgbWFya2VyRW5kVHJpZ2dlcl0sIHtcbiAgICAgICAgICBmb3JjZTNEOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBtYXJrZXJTdGFydFNldHRlciA9IGdzYXAucXVpY2tTZXR0ZXIobWFya2VyU3RhcnRUcmlnZ2VyLCBkaXJlY3Rpb24uYSwgX3B4KTtcbiAgICAgICAgbWFya2VyRW5kU2V0dGVyID0gZ3NhcC5xdWlja1NldHRlcihtYXJrZXJFbmRUcmlnZ2VyLCBkaXJlY3Rpb24uYSwgX3B4KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29udGFpbmVyQW5pbWF0aW9uKSB7XG4gICAgICB2Y
1XIgb2xkT25VcGRhdGUgPSBjb250YWluZXJBbmltYXRpb24udmFycy5vblVwZGF0ZSxcbiAgICAgICAgICBvbGRQYXJhbXMgPSBjb250YWluZXJBbmltYXRpb24udmFycy5vblVwZGF0ZVBhcmFtcztcbiAgICAgIGNvbnRhaW5lckFuaW1hdGlvbi5ldmVudENhbGxiYWNrKFwib25VcGRhdGVcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnVwZGF0ZSgwLCAwLCAxKTtcbiAgICAgICAgb2xkT25VcGRhdGUgJiYgb2xkT25VcGRhdGUuYXBwbHkoY29udGFpbmVyQW5pbWF0aW9uLCBvbGRQYXJhbXMgfHwgW10pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2VsZi5wcmV2aW91cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBfdHJpZ2dlcnNbX3RyaWdnZXJzLmluZGV4T2Yoc2VsZikgLSAxXTtcbiAgICB9O1xuXG4gICAgc2VsZi5uZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90cmlnZ2Vyc1tfdHJpZ2dlcnMuaW5kZXhPZihzZWxmKSArIDFdO1xuICAgIH07XG5cbiAgICBzZWxmLnJldmVydCA9IGZ1bmN0aW9uIChyZXZlcnQsIHRlbXApIHtcbiAgICAgIGlmICghdGVtcCkge1xuICAgICAgICByZXR1cm4gc2VsZi5raWxsKHRydWUpO1xuICAgICAgfSAvLyBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIGdzYXAuY29udGV4dCgpIGFuZCBnc2FwLm1hdGNoTWVkaWEoKSB3aGljaCBjYWxsIHJldmVydCgpXG5cblxuICAgICAgdmFyIHIgPSByZXZlcnQgIT09IGZhbHNlIHx8ICFzZWxmLmVuYWJsZWQsXG4gICAgICAgICAgcHJldlJlZnJlc2hpbmcgPSBfcmVmcmVzaGluZztcblxuICAgICAgaWYgKHIgIT09IHNlbGYuaXNSZXZlcnRlZCkge1xuICAgICAgICBpZiAocikge1xuICAgICAgICAgIHByZXZTY3JvbGwgP
1SBNYXRoLm1heChzY3JvbGxGdW5jKCksIHNlbGYuc2Nyb2xsLnJlYyB8fCAwKTsgLy8gcmVjb3JkIHRoZSBzY3JvbGwgc28gd2UgY2FuIHJldmVydCBsYXRlciAocmVwb3NpdGlvbmluZy9waW5uaW5nIHRoaW5ncyBjYW4gYWZmZWN0IHNjcm9sbCBwb3NpdGlvbikuIEluIHRoZSBzdGF0aWMgcmVmcmVzaCgpIG1ldGhvZCwgd2UgZmlyc3QgcmVjb3JkIGFsbCB0aGUgc2Nyb2xsIHBvc2l0aW9ucyBhcyBhIHJlZmVyZW5jZS5cblxuICAgICAgICAgIHByZXZQcm9ncmVzcyA9IHNlbGYucHJvZ3Jlc3M7XG4gICAgICAgICAgcHJldkFuaW1Qcm9ncmVzcyA9IGFuaW1hdGlvbiAmJiBhbmltYXRpb24ucHJvZ3Jlc3MoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG1hcmtlclN0YXJ0ICYmIFttYXJrZXJTdGFydCwgbWFya2VyRW5kLCBtYXJrZXJTdGFydFRyaWdnZXIsIG1hcmtlckVuZFRyaWdnZXJdLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICByZXR1cm4gbS5zdHlsZS5kaXNwbGF5ID0gciA/IFwibm9uZVwiIDogXCJibG9ja1wiO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAocikge1xuICAgICAgICAgIF9yZWZyZXNoaW5nID0gc2VsZjtcbiAgICAgICAgICBzZWxmLnVwZGF0ZShyKTsgLy8gbWFrZSBzdXJlIHRoZSBwaW4gaXMgYmFjayBpbiBpdHMgb3JpZ2luYWwgcG9zaXRpb24gc28gdGhhdCBhbGwgdGhlIG1lYXN1cmVtZW50cyBhcmUgY29ycmVjdC4gZG8gdGhpcyBCRUZPUkUgc3dhcHBpbmcgdGhlIHBpbiBvdXRcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwaW4gJiYgKCFwaW5SZXBhcmVudCB8fCAhc2VsZi5pc0FjdGl2ZSkpIHtcbiAgICAgICAgICBpZiAocikge1xuICAgICAgICAgICAgX3N3YXBQaW5PdXQocGluLCBzcGFjZXIsIHBpbk9yaWdpbmFsU3RhdGUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBfc3dhcFBpbkluKHBpbiwgc3BhY2VyLCBfZ2V0Q29tcHV0ZWRTdHlsZShwaW4pLCBzcGFjZXJTdGF0ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgciB8fCBzZWxmLnVwZGF0ZShyKTsgLy8gd2hlbiB3ZSdyZSByZXN0b3JpbmcsIHRoZSB1cGRhdGUgc2hvdWxkIHJ1biBBRlRFUiBzd2FwcGluZyB0aGUgcGluIGludG8gaXRzIHBpbi1zcGFjZXIuXG5cbiAgICAgICAgX3JlZnJlc2hpbmcgPSBwcmV2UmVmcmVzaGluZzsgLy8gcmVzdG9yZS4gV2Ugc2V0IGl0IHRvIHRydWUgZHVyaW5nIHRoZSB1cGRhdGUoKSBzbyB0aGF0IHRoaW5ncyBmaXJlIHByb3Blcmx5IGluIHRoZXJlLlxuXG4gICAgICAgIHNlbGYuaXNSZXZlcnRlZCA9IHI7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHNlbGYucmVmcmVzaCA9IGZ1bmN0aW9uIChzb2Z0LCBmb3JjZSwgcG9zaXRpb24sIHBpbk9mZnNldCkge1xuICAgICAgLy8gcG9zaXRpb24gaXMgdHlwaWNhbGx5IG9ubHkgZGVmaW5lZCBpZiBpdCdzIGNvbWluZyBmcm9tIHNldFBvc2l0aW9ucygpIC0gaXQncyBhIHdheSB0byBza2lwIHRoZSBub3JtYWwgcGFyc2luZy4gcGluT2Zmc2V0IGlzIGFsc28gb25seSBmcm9tIHNldFBvc2l0aW9ucygpIGFuZCBpcyBtb3N0bHkgcmVsYXRlZCB0byBmYW5jeSBzdHVmZiB3ZSBuZWVkIHRvIGRvIGluIFNjcm9sbFNtb290aGVyIHdpdGggZWZmZWN0c1xuICAgICAgaWYgKChfcmVmcmVzaGluZyB8fCAhc2VsZi5lbmFibGVkKSAmJiAhZm9yY2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAocGluICYmIHNvZnQgJiYgX2xhc3RTY3JvbGxUaW1lKSB7XG4gICAgICAgIF9hZGRMaXN0ZW5lcihTY3JvbGxUcmlnZ2VyLCBcInNjcm9sbEVuZFwiLCBfc29mdFJlZnJlc2gpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgIV9yZWZyZXNoaW5nQWxsICYmIG9uUmVmcmVzaEluaXQgJiYgb25SZWZyZXNoSW5pdChzZWxmKTtcbiAgICAgIF9yZWZyZXNoaW5nID0gc2VsZjtcblxuICAgICAgaWYgKHR3ZWVuVG8udHdlZW4gJiYgIXBvc2l0aW9uKSB7XG4gICAgICAgIC8vIHdlIHNraXAgdGhpcyBpZiBhIHBvc2l0aW9uIGlzIHBhc3NlZCBpbiBiZWNhdXNlIHR5cGljYWxseSB0aGF0J3MgZnJvbSAuc2V0UG9zaXRpb25zKCkgYW5kIGl0J3MgYmVzdCB0byBhbGxvdyBpbi1wcm9ncmVzcyBzbmFwcGluZyB0byBjb250aW51ZS5cbiAgICAgICAgdHdlZW5Uby50d2Vlbi5raWxsKCk7XG4gICAgICAgIHR3ZWVuVG8udHdlZW4gPSAwO1xuICAgICAgfVxuXG4gICAgICBzY3J1YlR3ZWVuICYmIHNjcnViVHdlZW4ucGF1c2UoKTtcbiAgICAgIGludmFsaWRhdGVPblJlZnJlc2ggJiYgYW5pbWF0aW9uICYmIGFuaW1hdGlvbi5yZXZlcnQoe1xuICAgICAgICBraWxsOiBmYWxzZVxuICAgICAgfSkuaW52YWxpZGF0ZSgpO1xuICAgICAgc2VsZi5pc1JldmVydGVkIHx8IHNlbGYucmV2ZXJ0KHRydWUsIHRydWUpO1xuICAgICAgc2VsZi5fc3ViUGluT2Zmc2V0ID0gZmFsc2U7IC8vIHdlJ2xsIHNldCB0aGlzIHRvIHRydWUgaW4gdGhlIHN1Yi1waW5zIGlmIHdlIGZpbmQgYW55XG5cbiAgICAgIHZhciBzaXplID0gZ2V0U2Nyb2xsZXJTaXplKCksXG4gICAgICAgICAgc2Nyb2xsZXJCb3VuZHMgPSBnZXRTY3JvbGxlck9mZnNldHMoKSxcbiAgICAgICAgICBtYXggPSBjb250YWluZXJBbmltYXRpb24gPyBjb250YWluZXJBbmltYXRpb24uZHVyYXRpb24oKSA6IF9tYXhTY3JvbGwoc2Nyb2xsZXIsIGRpcmVjdGlvbiksXG4gICAgICAgICAgaXNGaXJzdFJlZnJlc2ggPSBjaGFuZ2UgPD0gMC4wMSxcbiAgICAgICAgICBvZmZzZXQgPSAwLFxuICAgICAgICAgIG90aGVyUGluT2Zmc2V0ID0gcGluT2Zmc2V0IHx8IDAsXG4gICAgICAgICAgcGFyc2VkRW5kID0gX2lzT2JqZWN0KHBvc2l0aW9uKSA/IHBvc2l0aW9uLmVuZCA6IHZhcnMuZW5kLFxuICAgICAgICAgIHBhcnNlZEVuZFRyaWdnZXIgPSB2YXJzLmVuZFRyaWdnZXIgfHwgdHJpZ2dlcixcbiAgICAgICAgICBwYXJzZWRTdGFydCA9IF9pc09iamVjdChwb3NpdGlvbikgPyBwb3NpdGlvbi5zdGFydCA6IHZhcnMuc3RhcnQgfHwgKHZhcnMuc3RhcnQgPT09IDAgfHwgIXRyaWdnZXIgPyAwIDogcGluID8gXCIwIDBcIiA6IFwiMCAxMDAlXCIpLFxuICAgICAgICAgI
1HBpbm5lZENvbnRhaW5lciA9IHNlbGYucGlubmVkQ29udGFpbmVyID0gdmFycy5waW5uZWRDb250YWluZXIgJiYgX2dldFRhcmdldCh2YXJzLnBpbm5lZENvbnRhaW5lciwgc2VsZiksXG4gICAgICAgICAgdHJpZ2dlckluZGV4ID0gdHJpZ2dlciAmJiBNYXRoLm1heCgwLCBfdHJpZ2dlcnMuaW5kZXhPZihzZWxmKSkgfHwgMCxcbiAgICAgICAgICBpID0gdHJpZ2dlckluZGV4LFxuICAgICAgICAgIGNzLFxuICAgICAgICAgIGJvdW5kcyxcbiAgICAgICAgICBzY3JvbGwsXG4gICAgICAgICAgaXNWZXJ0aWNhbCxcbiAgICAgICAgICBvdmVycmlkZSxcbiAgICAgICAgICBjdXJUcmlnZ2VyLFxuICAgICAgICAgIGN1clBpbixcbiAgICAgICAgICBvcHBvc2l0ZVNjcm9sbCxcbiAgICAgICAgICBpbml0dGVkLFxuICAgICAgICAgIHJldmVydGVkUGlucyxcbiAgICAgICAgICBmb3JjZWRPdmVyZmxvdyxcbiAgICAgICAgICBtYXJrZXJTdGFydE9mZnNldCxcbiAgICAgICAgICBtYXJrZXJFbmRPZmZzZXQ7XG5cbiAgICAgIGlmIChtYXJrZXJzICYmIF9pc09iamVjdChwb3NpdGlvbikpIHtcbiAgICAgICAgLy8gaWYgd2UgYWx0ZXIgdGhlIHN0YXJ0L2VuZCBwb3NpdGlvbnMgd2l0aCAuc2V0UG9zaXRpb25zKCksIGl0IGdlbmVyYWxseSBmZWVkcyBpbiBhYnNvbHV0ZSBOVU1CRVJTIHdoaWNoIGRvbid0IGNvbnZleSBpbmZvcm1hdGlvbiBhYm91dCB3aGVyZSB0byBsaW5lIHVwIHRoZSBtYXJrZXJzLCBzbyB0byBrZWVwIGl0IGludHVpdGl2ZSwgd2UgcmVjb3JkIGhvdyBmYXIgdGhlIHRyaWdnZXIgcG9zaXRpb25zIHNoaWZ0IGFmdGVyIGFwcGx5aW5nIHRoZSBuZXcgbnVtYmVycyBhbmQgdGhlbiBvZmZzZXQgYnkgdGhhdCBtdWNoIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb24uIFdlIGRvIHRoZSBzYW1lIHRvIHRoZSBhc3NvY2lhdGVkIHRyaWdnZXIgbWFya2VycyB0b28gb2YgY291cnNlLlxuICAgICAgICBtYXJrZXJTdGFydE9mZnNldCA9IGdzYXAuZ2V0UHJvcGVydHkobWFya2VyU3RhcnRUcmlnZ2VyLCBkaXJlY3Rpb24ucCk7XG4gICAgICAgIG1hcmtlckVuZE9mZnNldCA9IGdzYXAuZ2V0UHJvcGVydHkobWFya2VyRW5kVHJpZ2dlciwgZGlyZWN0aW9uLnApO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIC8vIHVzZXIgbWlnaHQgdHJ5IHRvIHBpbiB0aGUgc2FtZSBlbGVtZW50IG1vcmUgdGhhbiBvbmNlLCBzbyB3ZSBtdXN0IGZpbmQgYW55IHByaW9yIHRyaWdnZXJzIHdpdGggdGhlIHNhbWUgcGluLCByZXZlcnQgdGhlbSwgYW5kIGRldGVybWluZSBob3cgbG9uZyB0aGV5J3JlIHBpbm5pbmcgc28gdGhhdCB3ZSBjYW4gb2Zmc2V0IHRoaW5ncyBhcHByb3ByaWF0ZWx5LiBNYWtlIHN1cmUgd2UgcmV2ZXJ0IGZyb20gbGFzdCB0byBmaXJzdCBzbyB0aGF0IHRoaW5ncyBcInJld2luZFwiIHByb3Blcmx5LlxuICAgICAgICBjdXJUcmlnZ2VyID0gX3RyaWdnZXJzW2ldO1xuICAgICAgICBjdXJUcmlnZ2VyLmVuZCB8fCBjdXJUcmlnZ2VyLnJlZnJlc2goMCwgMSkgfHwgKF9yZWZyZXNoaW5nID0gc2VsZik7IC8vIGlmIGl0J3MgYSB0aW1lbGluZS1iYXNlZCB0cmlnZ2VyIHRoYXQgaGFzbid0IGJlZW4gZnVsbHkgaW5pdGlhbGl6ZWQgeWV0IGJlY2F1c2UgaXQncyB3YWl0aW5nIGZvciAxIHRpY2ssIGp1c3QgZm9yY2UgdGhlIHJlZnJlc2goKSBoZXJlLCBvdGhlcndpc2UgaWYgaXQgY29udGFpbnMgYSBwaW4gdGhhdCdzIHN1cHBvc2VkIHRvIGFmZmVjdCBvdGhlciBTY3JvbGxUcmlnZ2VycyBmdXJ0aGVyIGRvd24gdGhlIHBhZ2UsIHRoZXkgd29uJ3QgYmUgYWRqdXN0ZWQgcHJvcGVybHkuXG5cbiAgICAgICAgY3VyUGluID0gY3VyVHJpZ2dlci5waW47XG5cbiAgICAgICAgaWYgKGN1clBpbiAmJiAoY3VyUGluID09PSB0cmlnZ2VyIHx8IGN1clBpbiA9PT0gcGluIHx8IGN1clBpbiA9PT0gcGlubmVkQ29udGFpbmVyKSAmJiAhY3VyVHJpZ2dlci5pc1JldmVydGVkKSB7XG4gICAgICAgICAgcmV2ZXJ0ZWRQaW5zIHx8IChyZXZlcnRlZFBpbnMgPSBbXSk7XG4gICAgICAgICAgcmV2ZXJ0ZWRQaW5zLnVuc2hpZnQoY3VyVHJpZ2dlcik7IC8vIHdlJ2xsIHJldmVydCBmcm9tIGZpcnN0IHRvIGxhc3QgdG8gbWFrZSBzdXJlIHRoaW5ncyByZWFjaCB0aGVpciBlbmQgc3RhdGUgcHJvcGVybHlcblxuICAgICAgICAgIGN1clRyaWdnZXIucmV2ZXJ0KHRydWUsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGN1clRyaWdnZXIgIT09IF90cmlnZ2Vyc1tpXSkge1xuICAgICAgICAgIC8vIGluIGNhc2UgaXQgZ290IHJlbW92ZWQuXG4gICAgICAgICAgdHJpZ2dlckluZGV4LS07XG4gICAgICAgICAgaS0tO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIF9pc0Z1bmN0aW9uKHBhcnNlZFN0YXJ0KSAmJiAocGFyc2VkU3RhcnQgPSBwYXJzZWRTdGFydChzZWxmKSk7XG4gICAgICBwYXJzZWRTdGFydCA9IF9wYXJzZUNsYW1wKHBhcnNlZFN0YXJ0LCBcInN0YXJ0XCIsIHNlbGYpO1xuICAgICAgc3RhcnQgPSBfcGFyc2VQb3NpdGlvbihwYXJzZWRTdGFydCwgdHJpZ2dlciwgc2l6ZSwgZGlyZWN0aW9uLCBzY3JvbGxGdW5jKCksIG1hcmtlclN0YXJ0LCBtYXJrZXJTdGFydFRyaWdnZXIsIHNlbGYsIHNjcm9sbGVyQm91bmRzLCBib3JkZXJXaWR0aCwgdXNlRml4ZWRQb3NpdGlvbiwgbWF4LCBjb250YWluZXJBbmltYXRpb24sIHNlbGYuX3N0YXJ0Q2xhbXAgJiYgXCJfc3RhcnRDbGFtcFwiKSB8fCAocGluID8gLTAuMDAxIDogMCk7XG4gICAgICBfaXNGdW5jdGlvbihwYXJzZWRFbmQpICYmIChwYXJzZWRFbmQgPSBwYXJzZWRFbmQoc2VsZikpO1xuXG4gICAgICBpZiAoX2lzU3RyaW5nKHBhcnNlZEVuZCkgJiYgIXBhcnNlZEVuZC5pbmRleE9mKFwiKz1cIikpIHtcbiAgICAgICAgaWYgKH5wYXJzZWRFbmQuaW5kZXhPZihcIiBcIikpIHtcbiAgICAgICAgICBwYXJzZWRFbmQgPSAoX2lzU3RyaW5nKHBhcnNlZFN0YXJ0KSA/IHBhcnNlZFN0YXJ0LnNwbGl0KFwiIFwiKVswXSA6IFwiXCIpICsgcGFyc2VkRW5kO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9mZnNldCA9IF9vZmZzZXRUb1B4KHBhcnNlZEVuZC5zdWJzdHIoMiksIHNpemUpO1xuICAgICAgICAgI
1HBhcnNlZEVuZCA9IF9pc1N0cmluZyhwYXJzZWRTdGFydCkgPyBwYXJzZWRTdGFydCA6IChjb250YWluZXJBbmltYXRpb24gPyBnc2FwLnV0aWxzLm1hcFJhbmdlKDAsIGNvbnRhaW5lckFuaW1hdGlvbi5kdXJhdGlvbigpLCBjb250YWluZXJBbmltYXRpb24uc2Nyb2xsVHJpZ2dlci5zdGFydCwgY29udGFpbmVyQW5pbWF0aW9uLnNjcm9sbFRyaWdnZXIuZW5kLCBzdGFydCkgOiBzdGFydCkgKyBvZmZzZXQ7IC8vIF9wYXJzZVBvc2l0aW9uIHdvbid0IGZhY3RvciBpbiB0aGUgb2Zmc2V0IGlmIHRoZSBzdGFydCBpcyBhIG51bWJlciwgc28gZG8gaXQgaGVyZS5cblxuICAgICAgICAgIHBhcnNlZEVuZFRyaWdnZXIgPSB0cmlnZ2VyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHBhcnNlZEVuZCA9IF9wYXJzZUNsYW1wKHBhcnNlZEVuZCwgXCJlbmRcIiwgc2VsZik7XG4gICAgICBlbmQgPSBNYXRoLm1heChzdGFydCwgX3BhcnNlUG9zaXRpb24ocGFyc2VkRW5kIHx8IChwYXJzZWRFbmRUcmlnZ2VyID8gXCIxMDAlIDBcIiA6IG1heCksIHBhcnNlZEVuZFRyaWdnZXIsIHNpemUsIGRpcmVjdGlvbiwgc2Nyb2xsRnVuYygpICsgb2Zmc2V0LCBtYXJrZXJFbmQsIG1hcmtlckVuZFRyaWdnZXIsIHNlbGYsIHNjcm9sbGVyQm91bmRzLCBib3JkZXJXaWR0aCwgdXNlRml4ZWRQb3NpdGlvbiwgbWF4LCBjb250YWluZXJBbmltYXRpb24sIHNlbGYuX2VuZENsYW1wICYmIFwiX2VuZENsYW1wXCIpKSB8fCAtMC4wMDE7XG4gICAgICBvZmZzZXQgPSAwO1xuICAgICAgaSA9IHRyaWdnZXJJbmRleDtcblxuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICBjdXJUcmlnZ2VyID0gX3RyaWdnZXJzW2ldO1xuICAgICAgICBjdXJQaW4gPSBjdXJUcmlnZ2VyLnBpbjtcblxuICAgICAgICBpZiAoY3VyUGluICYmIGN1clRyaWdnZXIuc3RhcnQgLSBjdXJUcmlnZ2VyLl9waW5QdXNoIDw9IHN0YXJ0ICYmICFjb250YWluZXJBbmltYXRpb24gJiYgY3VyVHJpZ2dlci5lbmQgPiAwKSB7XG4gICAgICAgICAgY3MgPSBjdXJUcmlnZ2VyLmVuZCAtIChzZWxmLl9zdGFydENsYW1wID8gTWF0aC5tYXgoMCwgY3VyVHJpZ2dlci5zdGFydCkgOiBjdXJUcmlnZ2VyLnN0YXJ0KTtcblxuICAgICAgICAgIGlmICgoY3VyUGluID09PSB0cmlnZ2VyICYmIGN1clRyaWdnZXIuc3RhcnQgLSBjdXJUcmlnZ2VyLl9waW5QdXNoIDwgc3RhcnQgfHwgY3VyUGluID09PSBwaW5uZWRDb250YWluZXIpICYmIGlzTmFOKHBhcnNlZFN0YXJ0KSkge1xuICAgICAgICAgICAgLy8gbnVtZXJpYyBzdGFydCB2YWx1ZXMgc2hvdWxkbid0IGJlIG9mZnNldCBhdCBhbGwgLSB0cmVhdCB0aGVtIGFzIGFic29sdXRlXG4gICAgICAgICAgICBvZmZzZXQgKz0gY3MgKiAoMSAtIGN1clRyaWdnZXIucHJvZ3Jlc3MpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGN1clBpbiA9PT0gcGluICYmIChvdGhlclBpbk9mZnNldCArPSBjcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RhcnQgKz0gb2Zmc2V0O1xuICAgICAgZW5kICs9IG9mZnNldDtcbiAgICAgIHNlbGYuX3N0YXJ0Q2xhbXAgJiYgKHNlbGYuX3N0YXJ0Q2xhbXAgKz0gb2Zmc2V0KTtcblxuICAgICAgaWYgKHNlbGYuX2VuZENsYW1wICYmICFfcmVmcmVzaGluZ0FsbCkge1xuICAgICAgICBzZWxmLl9lbmRDbGFtcCA9IGVuZCB8fCAtMC4wMDE7XG4gICAgICAgIGVuZCA9IE1hdGgubWluKGVuZCwgX21heFNjcm9sbChzY3JvbGxlciwgZGlyZWN0aW9uKSk7XG4gICAgICB9XG5cbiAgICAgIGNoYW5nZSA9IGVuZCAtIHN0YXJ0IHx8IChzdGFydCAtPSAwLjAxKSAmJiAwLjAwMTtcblxuICAgICAgaWYgKGlzRmlyc3RSZWZyZXNoKSB7XG4gICAgICAgIC8vIG9uIHRoZSB2ZXJ5IGZpcnN0IHJlZnJlc2goKSwgdGhlIHByZXZQcm9ncmVzcyBjb3VsZG4ndCBoYXZlIGJlZW4gYWNjdXJhdGUgeWV0IGJlY2F1c2UgdGhlIHN0YXJ0L2VuZCB3ZXJlIG5ldmVyIGNhbGN1bGF0ZWQsIHNvIHdlIHNldCBpdCBoZXJlLiBCZWZvcmUgMy4xMS41LCBpdCBjb3VsZCBsZWFkIHRvIGFuIGluYWNjdXJhdGUgc2Nyb2xsIHBvc2l0aW9uIHJlc3RvcmF0aW9uIHdpdGggc25hcHBpbmcuXG4gICAgICAgIHByZXZQcm9ncmVzcyA9IGdzYXAudXRpbHMuY2xhbXAoMCwgMSwgZ3NhcC51dGlscy5ub3JtYWxpemUoc3RhcnQsIGVuZCwgcHJldlNjcm9sbCkpO1xuICAgICAgfVxuXG4gICAgICBzZWxmLl9waW5QdXNoID0gb3RoZXJQaW5PZmZzZXQ7XG5cbiAgICAgIGlmIChtYXJrZXJTdGFydCAmJiBvZmZzZXQpIHtcbiAgICAgICAgLy8gb2Zmc2V0IHRoZSBtYXJrZXJzIGlmIG5lY2Vzc2FyeVxuICAgICAgICBjcyA9IHt9O1xuICAgICAgICBjc1tkaXJlY3Rpb24uYV0gPSBcIis9XCIgKyBvZmZzZXQ7XG4gICAgICAgIHBpbm5lZENvbnRhaW5lciAmJiAoY3NbZGlyZWN0aW9uLnBdID0gXCItPVwiICsgc2Nyb2xsRnVuYygpKTtcbiAgICAgICAgZ3NhcC5zZXQoW21hcmtlclN0YXJ0LCBtYXJrZXJFbmRdLCBjcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwaW4gJiYgIShfY2xhbXBpbmdNYXggJiYgc2VsZi5lbmQgPj0gX21heFNjcm9sbChzY3JvbGxlciwgZGlyZWN0aW9uKSkpIHtcbiAgICAgICAgY3MgPSBfZ2V0Q29tcHV0ZWRTdHlsZShwaW4pO1xuICAgICAgICBpc1ZlcnRpY2FsID0gZGlyZWN0aW9uID09PSBfdmVydGljYWw7XG4gICAgICAgIHNjcm9sbCA9IHNjcm9sbEZ1bmMoKTsgLy8gcmVjYWxjdWxhdGUgYmVjYXVzZSB0aGUgdHJpZ2dlcnMgY2FuIGFmZmVjdCB0aGUgc2Nyb2xsXG5cbiAgICAgICAgcGluU3RhcnQgPSBwYXJzZUZsb2F0KHBpbkdldHRlcihkaXJlY3Rpb24uYSkpICsgb3RoZXJQaW5PZmZzZXQ7XG5cbiAgICAgICAgaWYgKCFtYXggJiYgZW5kID4gMSkge1xuICAgICAgICAgIC8vIG1ha2VzIHN1cmUgdGhlIHNjcm9sbGVyIGhhcyBhIHNjcm9sbGJhciwgb3RoZXJ3aXNlIGlmIHNvbWV0aGluZyBoYXMgd2lkdGg6IDEwMCUsIGZvciBleGFtcGxlLCBpdCB3b3VsZCBiZSB0b28gYmlnIChleGNsdWRlIHRoZSBzY3JvbGxiYXIpLiBTZWUgaHR0cHM6Ly9nc2FwLmNvbS9mb3J1bXMvdG9waWMvMjUxODItc2Nyb2xsdHJpZ2dlci13aWR0aC1vZi1wYWdlLWluY3JlYXNlLXdoZXJlLW1hcmtlcnMtYXJlLXNldC10by1mYWxzZS9cbiAgICAgICAgICBmb3JjZWRPdmVyZmxvdyA9IChpc1ZpZXdwb3J0ID8gX2RvYy5zY3JvbGxpbmdFbGVtZW50IHx8IF9kb2NFbCA6IHNjcm9sbGVyKS5zdHlsZTtcbiAgICAgICAgICBmb3JjZWRPdmVyZmxvdyA9IHtcbiAgICAgICAgICAgI
1HN0eWxlOiBmb3JjZWRPdmVyZmxvdyxcbiAgICAgICAgICAgIHZhbHVlOiBmb3JjZWRPdmVyZmxvd1tcIm92ZXJmbG93XCIgKyBkaXJlY3Rpb24uYS50b1VwcGVyQ2FzZSgpXVxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBpZiAoaXNWaWV3cG9ydCAmJiBfZ2V0Q29tcHV0ZWRTdHlsZShfYm9keSlbXCJvdmVyZmxvd1wiICsgZGlyZWN0aW9uLmEudG9VcHBlckNhc2UoKV0gIT09IFwic2Nyb2xsXCIpIHtcbiAgICAgICAgICAgIC8vIGF2b2lkIGFuIGV4dHJhIHNjcm9sbGJhciBpZiBCT1RIIDxodG1sPiBhbmQgPGJvZHk+IGhhdmUgb3ZlcmZsb3cgc2V0IHRvIFwic2Nyb2xsXCJcbiAgICAgICAgICAgIGZvcmNlZE92ZXJmbG93LnN0eWxlW1wib3ZlcmZsb3dcIiArIGRpcmVjdGlvbi5hLnRvVXBwZXJDYXNlKCldID0gXCJzY3JvbGxcIjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBfc3dhcFBpbkluKHBpbiwgc3BhY2VyLCBjcyk7XG5cbiAgICAgICAgcGluU3RhdGUgPSBfZ2V0U3RhdGUocGluKTsgLy8gdHJhbnNmb3JtcyB3aWxsIGludGVyZmVyZSB3aXRoIHRoZSB0b3AvbGVmdC9yaWdodC9ib3R0b20gcGxhY2VtZW50LCBzbyByZW1vdmUgdGhlbSB0ZW1wb3JhcmlseS4gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgZmFjdG9ycyBpbiB0cmFuc2Zvcm1zLlxuXG4gICAgICAgIGJvdW5kcyA9IF9nZXRCb3VuZHMocGluLCB0cnVlKTtcbiAgICAgICAgb3Bwb3NpdGVTY3JvbGwgPSB1c2VGaXhlZFBvc2l0aW9uICYmIF9nZXRTY3JvbGxGdW5jKHNjcm9sbGVyLCBpc1ZlcnRpY2FsID8gX2hvcml6b250YWwgOiBfdmVydGljYWwpKCk7XG5cbiAgICAgICAgaWYgKHBpblNwYWNpbmcpIHtcbiAgICAgICAgICBzcGFjZXJTdGF0ZSA9IFtwaW5TcGFjaW5nICsgZGlyZWN0aW9uLm9zMiwgY2hhbmdlICsgb3RoZXJQaW5PZmZzZXQgKyBfcHhdO1xuICAgICAgICAgIHNwYWNlclN0YXRlLnQgPSBzcGFjZXI7XG4gICAgICAgICAgaSA9IHBpblNwYWNpbmcgPT09IF9wYWRkaW5nID8gX2dldFNpemUocGluLCBkaXJlY3Rpb24pICsgY2hhbmdlICsgb3RoZXJQaW5PZmZzZXQgOiAwO1xuXG4gICAgICAgICAgaWYgKGkpIHtcbiAgICAgICAgICAgIHNwYWNlclN0YXRlLnB1c2goZGlyZWN0aW9uLmQsIGkgKyBfcHgpOyAvLyBmb3IgYm94LXNpemluZzogYm9yZGVyLWJveCAobXVzdCBpbmNsdWRlIHBhZGRpbmcpLlxuXG4gICAgICAgICAgICBzcGFjZXIuc3R5bGUuZmxleEJhc2lzICE9PSBcImF1dG9cIiAmJiAoc3BhY2VyLnN0eWxlLmZsZXhCYXNpcyA9IGkgKyBfcHgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIF9zZXRTdGF0ZShzcGFjZXJTdGF0ZSk7XG5cbiAgICAgICAgICBpZiAocGlubmVkQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAvLyBpbiBTY3JvbGxUcmlnZ2VyLnJlZnJlc2goKSwgd2UgbmVlZCB0byByZS1ldmFsdWF0ZSB0aGUgcGluQ29udGFpbmVyJ3Mgc2l6ZSBiZWNhdXNlIHRoaXMgcGluU3BhY2luZyBtYXkgc3RyZXRjaCBpdCBvdXQsIGJ1dCB3ZSBjYW4ndCBqdXN0IGFkZCB0aGUgZXhhY3QgZGlzdGFuY2UgYmVjYXVzZSBkZXBlbmRpbmcgb24gbGF5b3V0LCBpdCBtYXkgbm90IHB1c2ggdGhpbmdzIGRvd24gb3IgaXQgbWF5IG9ubHkgZG8gc28gcGFydGlhbGx5LlxuICAgICAgICAgICAgX3RyaWdnZXJzLmZvckVhY2goZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgICAgaWYgKHQucGluID09PSBwaW5uZWRDb250YWluZXIgJiYgdC52YXJzLnBpblNwYWNpbmcgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgdC5fc3ViUGluT2Zmc2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdXNlRml4ZWRQb3NpdGlvbiAmJiBzY3JvbGxGdW5jKHByZXZTY3JvbGwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGkgPSBfZ2V0U2l6ZShwaW4sIGRpcmVjdGlvbik7XG4gICAgICAgICAgaSAmJiBzcGFjZXIuc3R5bGUuZmxleEJhc2lzICE9PSBcImF1dG9cIiAmJiAoc3BhY2VyLnN0eWxlLmZsZXhCYXNpcyA9IGkgKyBfcHgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHVzZUZpeGVkUG9zaXRpb24pIHtcbiAgICAgICAgICBvdmVycmlkZSA9IHtcbiAgICAgICAgICAgIHRvcDogYm91bmRzLnRvcCArIChpc1ZlcnRpY2FsID8gc2Nyb2xsIC0gc3RhcnQgOiBvcHBvc2l0ZVNjcm9sbCkgKyBfcHgsXG4gICAgICAgICAgICBsZWZ0OiBib3VuZHMubGVmdCArIChpc1ZlcnRpY2FsID8gb3Bwb3NpdGVTY3JvbGwgOiBzY3JvbGwgLSBzdGFydCkgKyBfcHgsXG4gICAgICAgICAgICBib3hTaXppbmc6IFwiYm9yZGVyLWJveFwiLFxuICAgICAgICAgICAgcG9zaXRpb246IFwiZml4ZWRcIlxuICAgICAgICAgIH07XG4gICAgICAgICAgb3ZlcnJpZGVbX3dpZHRoXSA9IG92ZXJyaWRlW1wibWF4XCIgKyBfV2lkdGhdID0gTWF0aC5jZWlsKGJvdW5kcy53aWR0aCkgKyBfcHg7XG4gICAgICAgICAgb3ZlcnJpZGVbX2hlaWdodF0gPSBvdmVycmlkZVtcIm1heFwiICsgX0hlaWdodF0gPSBNYXRoLmNlaWwoYm91bmRzLmhlaWdodCkgKyBfcHg7XG4gICAgICAgICAgb3ZlcnJpZGVbX21hcmdpbl0gPSBvdmVycmlkZVtfbWFyZ2luICsgX1RvcF0gPSBvdmVycmlkZVtfbWFyZ2luICsgX1JpZ2h0XSA9IG92ZXJyaWRlW19tYXJnaW4gKyBfQm90dG9tXSA9IG92ZXJyaWRlW19tYXJnaW4gKyBfTGVmdF0gPSBcIjBcIjtcbiAgICAgICAgICBvdmVycmlkZVtfcGFkZGluZ10gPSBjc1tfcGFkZGluZ107XG4gICAgICAgICAgb3ZlcnJpZGVbX3BhZGRpbmcgKyBfVG9wXSA9IGNzW19wYWRkaW5nICsgX1RvcF07XG4gICAgICAgICAgb3ZlcnJpZGVbX3BhZGRpbmcgKyBfUmlnaHRdID0gY3NbX3BhZGRpbmcgKyBfUmlnaHRdO1xuICAgICAgICAgIG92ZXJyaWRlW19wYWRkaW5nICsgX0JvdHRvbV0gPSBjc1tfcGFkZGluZyArIF9Cb3R0b21dO1xuICAgICAgICAgIG92ZXJyaWRlW19wYWRkaW5nICsgX0xlZnRdID0gY3NbX3BhZGRpbmcgKyBfTGVmdF07XG4gICAgICAgICAgcGluQWN0aXZlU3RhdGUgPSBfY29weVN0YXRl
1KHBpbk9yaWdpbmFsU3RhdGUsIG92ZXJyaWRlLCBwaW5SZXBhcmVudCk7XG4gICAgICAgICAgX3JlZnJlc2hpbmdBbGwgJiYgc2Nyb2xsRnVuYygwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhbmltYXRpb24pIHtcbiAgICAgICAgICAvLyB0aGUgYW5pbWF0aW9uIG1pZ2h0IGJlIGFmZmVjdGluZyB0aGUgdHJhbnNmb3JtLCBzbyB3ZSBtdXN0IGp1bXAgdG8gdGhlIGVuZCwgY2hlY2sgdGhlIHZhbHVlLCBhbmQgY29tcGVuc2F0ZSBhY2NvcmRpbmdseS4gT3RoZXJ3aXNlLCB3aGVuIGl0IGJlY29tZXMgdW5waW5uZWQsIHRoZSBwaW5TZXR0ZXIoKSB3aWxsIGdldCBzZXQgdG8gYSB2YWx1ZSB0aGF0IGRvZXNuJ3QgaW5jbHVkZSB3aGF0ZXZlciB0aGUgYW5pbWF0aW9uIGRpZC5cbiAgICAgICAgICBpbml0dGVkID0gYW5pbWF0aW9uLl9pbml0dGVkOyAvLyBpZiBub3QsIHdlIG11c3QgaW52YWxpZGF0ZSgpIGFmdGVyIHRoaXMgc3RlcCwgb3RoZXJ3aXNlIGl0IGNvdWxkIGxvY2sgaW4gc3RhcnRpbmcgdmFsdWVzIHByZW1hdHVyZWx5LlxuXG4gICAgICAgICAgX3N1cHByZXNzT3ZlcndyaXRlcygxKTtcblxuICAgICAgICAgIGFuaW1hdGlvbi5yZW5kZXIoYW5pbWF0aW9uLmR1cmF0aW9uKCksIHRydWUsIHRydWUpO1xuICAgICAgICAgIHBpbkNoYW5nZSA9IHBpbkdldHRlcihkaXJlY3Rpb24uYSkgLSBwaW5TdGFydCArIGNoYW5nZSArIG90aGVyUGluT2Zmc2V0O1xuICAgICAgICAgIHBpbk1vdmVzID0gTWF0aC5hYnMoY2hhbmdlIC0gcGluQ2hhbmdlKSA+IDE7XG4gICAgICAgICAgdXNlRml4ZWRQb3NpdGlvbiAmJiBwaW5Nb3ZlcyAmJiBwaW5BY3RpdmVTdGF0ZS5zcGxpY2UocGluQWN0aXZlU3RhdGUubGVuZ3RoIC0gMiwgMik7IC8vIHRyYW5zZm9ybSBpcyB0aGUgbGFzdCBwcm9wZXJ0eS92YWx1ZSBzZXQgaW4gdGhlIHN0YXRlIEFycmF5LiBTaW5jZSB0aGUgYW5pbWF0aW9uIGlzIGNvbnRyb2xsaW5nIHRoYXQsIHdlIHNob3VsZCBvbWl0IGl0LlxuXG4gICAgICAgICAgYW5pbWF0aW9uLnJlbmRlcigwLCB0cnVlLCB0cnVlKTtcbiAgICAgICAgICBpbml0dGVkIHx8IGFuaW1hdGlvbi5pbnZhbGlkYXRlKHRydWUpO1xuICAgICAgICAgIGFuaW1hdGlvbi5wYXJlbnQgfHwgYW5pbWF0aW9uLnRvdGFsVGltZShhbmltYXRpb24udG90YWxUaW1lKCkpOyAvLyBpZiwgZm9yIGV4YW1wbGUsIGEgdG9nZ2xlQWN0aW9uIGNhbGxlZCBwbGF5KCkgYW5kIHRoZW4gcmVmcmVzaCgpIGhhcHBlbnMgYW5kIHdoZW4gd2UgcmVuZGVyKDEpIGFib3ZlLCBpdCB3b3VsZCBjYXVzZSB0aGUgYW5pbWF0aW9uIHRvIGNvbXBsZXRlIGFuZCBnZXQgcmVtb3ZlZCBmcm9tIGl0cyBwYXJlbnQsIHNvIHRoaXMgbWFrZXMgc3VyZSBpdCBnZXRzIHB1dCBiYWNrIGluLlxuXG4gICAgICAgICAgX3N1cHByZXNzT3ZlcndyaXRlcygwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwaW5DaGFuZ2UgPSBjaGFuZ2U7XG4gICAgICAgIH1cblxuICAgICAgICBmb3JjZWRPdmVyZmxvdyAmJiAoZm9yY2VkT3ZlcmZsb3cudmFsdWUgPyBmb3JjZWRPdmVyZmxvdy5zdHlsZVtcIm92ZXJmbG93XCIgKyBkaXJlY3Rpb24uYS50b1VwcGVyQ2FzZSgpXSA9IGZvcmNlZE92ZXJmbG93LnZhbHVlIDogZm9yY2VkT3ZlcmZsb3cuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJvdmVyZmxvdy1cIiArIGRpcmVjdGlvbi5hKSk7XG4gICAgICB9IGVsc2UgaWYgKHRyaWdnZXIgJiYgc2Nyb2xsRnVuYygpICYmICFjb250YWluZXJBbmltYXRpb24pIHtcbiAgICAgICAgLy8gaXQgbWF5IGJlIElOU0lERSBhIHBpbm5lZCBlbGVtZW50LCBzbyB3YWxrIHVwIHRoZSB0cmVlIGFuZCBsb29rIGZvciBhbnkgZWxlbWVudHMgd2l0aCBfcGluT2Zmc2V0IHRvIGNvbXBlbnNhdGUgYmVjYXVzZSBhbnl0aGluZyB3aXRoIHBpblNwYWNpbmcgdGhhdCdzIGFscmVhZHkgc2Nyb2xsZWQgd291bGQgdGhyb3cgb2ZmIHRoZSBtZWFzdXJlbWVudHMgaW4gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgYm91bmRzID0gdHJpZ2dlci5wYXJlbnROb2RlO1xuXG4gICAgICAgIHdoaWxlIChib3VuZHMgJiYgYm91bmRzICE9PSBfYm9keSkge1xuICAgICAgICAgIGlmIChib3VuZHMuX3Bpbk9mZnNldCkge1xuICAgICAgICAgICAgc3RhcnQgLT0gYm91bmRzLl9waW5PZmZzZXQ7XG4gICAgICAgICAgICBlbmQgLT0gYm91bmRzLl9waW5PZmZzZXQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYm91bmRzID0gYm91bmRzLnBhcmVudE5vZGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV2ZXJ0ZWRQaW5zICYmIHJldmVydGVkUGlucy5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiB0LnJldmVydChmYWxzZSwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICAgIHNlbGYuc3RhcnQgPSBzdGFydDtcbiAgICAgIHNlbGYuZW5kID0gZW5kO1xuICAgICAgc2Nyb2xsMSA9IHNjcm9sbDIgPSBfcmVmcmVzaGluZ0FsbCA/IHByZXZTY3JvbGwgOiBzY3JvbGxGdW5jKCk7IC8vIHJlc2V0IHZlbG9jaXR5XG5cbiAgICAgIGlmICghY29udGFpbmVyQW5pbWF0aW9uICYmICFfcmVmcmVzaGluZ0FsbCkge1xuICAgICAgICBzY3JvbGwxIDwgcHJldlNjcm9sbCAmJiBzY3JvbGxGdW5jKHByZXZTY3JvbGwpO1xuICAgICAgICBzZWxmLnNjcm9sbC5yZWMgPSAwO1xuICAgICAgfVxuXG4gICAgICBzZWxmLnJldmVydChmYWxzZSwgdHJ1ZSk7XG4gICAgICBsYXN0UmVmcmVzaCA9IF9nZXRUaW1lKCk7XG5cbiAgICAgIGlmIChzbmFwRGVsYXllZENhbGwpIHtcbiAgICAgICAgbGFzdFNuYXAgPSAtMTsgLy8ganVzdCBzbyBzbmFwcGluZyBnZXRzIHJlLWVuYWJsZWQsIGNsZWFyIG91dCBhbnkgcmVjb3JkZWQgbGFzdCB2YWx1ZVxuICAgICAgICAvLyBzZWxmLmlzQWN0aXZlICYmIHNjcm9sbEZ1bmMoc3RhcnQgKyBjaGFuZ2UgKiBwcmV2UHJvZ3Jlc3MpOyAvLyBwcmV2aW91c2x5IHRoaXMgbGluZSB3YXMgaGVyZSB0byBlbnN1cmUgdGhhdCB3aGVuIHNuYXBwaW5nIGtpY2tzIGluLCBpdCdzIGZyb20gdGhlIHByZXZpb3VzIHByb2dyZXNzIGJ1dCBpbiBzb21lIGNhc2VzIHRoYXQncyBub3QgZGVzaXJhYmxlLCBsaWtlIGFuIGFsbC1wYWdlIFNjcm9sbFRyaWdnZXIgd2hlbiBuZXcgY29udGVudCBnZXRzIGFkZGVkIHRvIHRoZSBwYWdlLCB0aGF0J2QgdG90YWxseSBjaGFuZ2UgdGhlIHByb2dyZXNzLlxuXG4gICAgICAgI
1HNuYXBEZWxheWVkQ2FsbC5yZXN0YXJ0KHRydWUpO1xuICAgICAgfVxuXG4gICAgICBfcmVmcmVzaGluZyA9IDA7XG4gICAgICBhbmltYXRpb24gJiYgaXNUb2dnbGUgJiYgKGFuaW1hdGlvbi5faW5pdHRlZCB8fCBwcmV2QW5pbVByb2dyZXNzKSAmJiBhbmltYXRpb24ucHJvZ3Jlc3MoKSAhPT0gcHJldkFuaW1Qcm9ncmVzcyAmJiBhbmltYXRpb24ucHJvZ3Jlc3MocHJldkFuaW1Qcm9ncmVzcyB8fCAwLCB0cnVlKS5yZW5kZXIoYW5pbWF0aW9uLnRpbWUoKSwgdHJ1ZSwgdHJ1ZSk7IC8vIG11c3QgZm9yY2UgYSByZS1yZW5kZXIgYmVjYXVzZSBpZiBzYXZlU3R5bGVzKCkgd2FzIHVzZWQgb24gdGhlIHRhcmdldChzKSwgdGhlIHN0eWxlcyBjb3VsZCBoYXZlIGJlZW4gd2lwZWQgb3V0IGR1cmluZyB0aGUgcmVmcmVzaCgpLlxuXG4gICAgICBpZiAoaXNGaXJzdFJlZnJlc2ggfHwgcHJldlByb2dyZXNzICE9PSBzZWxmLnByb2dyZXNzIHx8IGNvbnRhaW5lckFuaW1hdGlvbiB8fCBpbnZhbGlkYXRlT25SZWZyZXNoKSB7XG4gICAgICAgIC8vIGVuc3VyZXMgdGhhdCB0aGUgZGlyZWN0aW9uIGlzIHNldCBwcm9wZXJseSAod2hlbiByZWZyZXNoaW5nLCBwcm9ncmVzcyBpcyBzZXQgYmFjayB0byAwIGluaXRpYWxseSwgdGhlbiBiYWNrIGFnYWluIHRvIHdoZXJldmVyIGl0IG5lZWRzIHRvIGJlKSBhbmQgdGhhdCBjYWxsYmFja3MgYXJlIHRyaWdnZXJlZC5cbiAgICAgICAgYW5pbWF0aW9uICYmICFpc1RvZ2dsZSAmJiBhbmltYXRpb24udG90YWxQcm9ncmVzcyhjb250YWluZXJBbmltYXRpb24gJiYgc3RhcnQgPCAtMC4wMDEgJiYgIXByZXZQcm9ncmVzcyA/IGdzYXAudXRpbHMubm9ybWFsaXplKHN0YXJ0LCBlbmQsIDApIDogcHJldlByb2dyZXNzLCB0cnVlKTsgLy8gdG8gYXZvaWQgaXNzdWVzIHdoZXJlIGFuaW1hdGlvbiBjYWxsYmFja3MgbGlrZSBvblN0YXJ0IGFyZW4ndCB0cmlnZ2VyZWQuXG5cbiAgICAgICAgc2VsZi5wcm9ncmVzcyA9IGlzRmlyc3RSZWZyZXNoIHx8IChzY3JvbGwxIC0gc3RhcnQpIC8gY2hhbmdlID09PSBwcmV2UHJvZ3Jlc3MgPyAwIDogcHJldlByb2dyZXNzO1xuICAgICAgfVxuXG4gICAgICBwaW4gJiYgcGluU3BhY2luZyAmJiAoc3BhY2VyLl9waW5PZmZzZXQgPSBNYXRoLnJvdW5kKHNlbGYucHJvZ3Jlc3MgKiBwaW5DaGFuZ2UpKTtcbiAgICAgIHNjcnViVHdlZW4gJiYgc2NydWJUd2Vlbi5pbnZhbGlkYXRlKCk7XG5cbiAgICAgIGlmICghaXNOYU4obWFya2VyU3RhcnRPZmZzZXQpKSB7XG4gICAgICAgIC8vIG51bWJlcnMgd2VyZSBwYXNzZWQgaW4gZm9yIHRoZSBwb3NpdGlvbiB3aGljaCBhcmUgYWJzb2x1dGUsIHNvIGluc3RlYWQgb2YganVzdCBwdXR0aW5nIHRoZSBtYXJrZXJzIGF0IHRoZSB2ZXJ5IGJvdHRvbSBvZiB0aGUgdmlld3BvcnQsIHdlIGZpZ3VyZSBvdXQgaG93IGZhciB0aGV5IHNoaWZ0ZWQgZG93biAoaXQncyBzYWZlIHRvIGFzc3VtZSB0aGV5IHdlcmUgb3JpZ2luYWxseSBwb3NpdGlvbmVkIGluIGNsb3NlciByZWxhdGlvbiB0byB0aGUgdHJpZ2dlciBlbGVtZW50IHdpdGggdmFsdWVzIGxpa2UgXCJ0b3BcIiwgXCJjZW50ZXJcIiwgYSBwZXJjZW50YWdlIG9yIHdoYXRldmVyLCBzbyB3ZSBvZmZzZXQgdGhhdCBtdWNoIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb24gdG8gYmFzaWNhbGx5IHJldmVydCB0aGVtIHRvIHRoZSByZWxhdGl2ZSBwb3NpdGlvbiB0aHkgd2VyZSBhdCBwcmV2aW91c2x5LlxuICAgICAgICBtYXJrZXJTdGFydE9mZnNldCAtPSBnc2FwLmdldFByb3BlcnR5KG1hcmtlclN0YXJ0VHJpZ2dlciwgZGlyZWN0aW9uLnApO1xuICAgICAgICBtYXJrZXJFbmRPZmZzZXQgLT0gZ3NhcC5nZXRQcm9wZXJ0eShtYXJrZXJFbmRUcmlnZ2VyLCBkaXJlY3Rpb24ucCk7XG5cbiAgICAgICAgX3NoaWZ0TWFya2VyKG1hcmtlclN0YXJ0VHJpZ2dlciwgZGlyZWN0aW9uLCBtYXJrZXJTdGFydE9mZnNldCk7XG5cbiAgICAgICAgX3NoaWZ0TWFya2VyKG1hcmtlclN0YXJ0LCBkaXJlY3Rpb24sIG1hcmtlclN0YXJ0T2Zmc2V0IC0gKHBpbk9mZnNldCB8fCAwKSk7XG5cbiAgICAgICAgX3NoaWZ0TWFya2VyKG1hcmtlckVuZFRyaWdnZXIsIGRpcmVjdGlvbiwgbWFya2VyRW5kT2Zmc2V0KTtcblxuICAgICAgICBfc2hpZnRNYXJrZXIobWFya2VyRW5kLCBkaXJlY3Rpb24sIG1hcmtlckVuZE9mZnNldCAtIChwaW5PZmZzZXQgfHwgMCkpO1xuICAgICAgfVxuXG4gICAgICBpc0ZpcnN0UmVmcmVzaCAmJiAhX3JlZnJlc2hpbmdBbGwgJiYgc2VsZi51cGRhdGUoKTsgLy8gZWRnZSBjYXNlIC0gd2hlbiB5b3UgcmVsb2FkIGEgcGFnZSB3aGVuIGl0J3MgYWxyZWFkeSBzY3JvbGxlZCBkb3duLCBzb21lIGJyb3dzZXJzIGZpcmUgYSBcInNjcm9sbFwiIGV2ZW50IGJlZm9yZSBET01Db250ZW50TG9hZGVkLCB0cmlnZ2VyaW5nIGFuIHVwZGF0ZUFsbCgpLiBJZiB3ZSBkb24ndCB1cGRhdGUgdGhlIHNlbGYucHJvZ3Jlc3MgYXMgcGFydCBvZiByZWZyZXNoKCksIHRoZW4gd2hlbiBpdCBoYXBwZW5zIG5leHQsIGl0IG1heSByZWNvcmQgcHJldlByb2dyZXNzIGFzIDAgd2hlbiBpdCByZWFsbHkgc2hvdWxkbid0LCBwb3RlbnRpYWxseSBjYXVzaW5nIGEgY2FsbGJhY2sgaW4gYW4gYW5pbWF0aW9uIHRvIGZpcmUgYWdhaW4uXG5cbiAgICAgIGlmIChvblJlZnJlc2ggJiYgIV9yZWZyZXNoaW5nQWxsICYmICFleGVjdXRpbmdPblJlZnJlc2gpIHtcbiAgICAgICAgLy8gd2hlbiByZWZyZXNoaW5nIGFsbCwgd2UgZG8gZXh0cmEgd29yayB0byBjb3JyZWN0IHBpbm5lZENvbnRhaW5lciBzaXplcyBhbmQgZW5zdXJlIHRoaW5ncyBkb24ndCBleGNlZWQgdGhlIG1heFNjcm9sbCwgc28gd2Ugc2hvdWxkIGRvIGFsbCB0aGUgcmVmcmVzaGVzIGF0IHRoZSBlbmQgYWZ0ZXIgYWxsIHRoYXQgd29yayBzbyB0aGF0IHRoZSBzdGFydC9lbmQgdmFsdWVzIGFyZSBjb3JyZWN0ZWQuXG4gICAgICAgIGV4ZWN1dGluZ09uUmVmcmVzaCA9IHRydWU7XG4gICAgICAgIG9uUmVmcmVzaChzZWxmKTtcbiAgICAgICAgZXhlY3V0aW5nT25SZWZyZXNoID0gZmFsc2U7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHNlbGYuZ2V0VmVsb2NpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gKHNjcm9sbEZ1bmMoKSAtIHNjcm9sbDIpIC8gKF9nZXRUaW1lKCkgLSBfdGltZTIpICogMTAwMCB8fCAwO1xuICAgIH07XG5cbiAgICBzZWxmLmVuZEFuaW1hdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIF9lbmRBbmltYXRpb24oc2VsZi5jYWxsYmFja0FuaW1hdGlvbik7XG5cbiAgICAgIGlmIChhbmltYXRpb24pIHtcbiAgICAgICAgc2NydWJUd2VlbiA/IHNjcnViVHdlZW4ucHJvZ3Jlc3MoMSkgOiAhYW5pbWF0aW9uLnBhdXNlZCgpID8gX2VuZEFuaW1hdGlvbihhbmltYXRpb24sIGFuaW1hdGlvbi5yZXZlcnNlZCgpKSA6IGlzVG9nZ2xlIHx8IF9lbmRBbmltYXRpb24oYW5pbWF0aW9uLCBzZWxmLmRpcmVjdGlvbiA8IDAsIDEpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBzZWxmLmxhYmVsVG9TY3JvbGwgP
1SBmdW5jdGlvbiAobGFiZWwpIHtcbiAgICAgIHJldHVybiBhbmltYXRpb24gJiYgYW5pbWF0aW9uLmxhYmVscyAmJiAoc3RhcnQgfHwgc2VsZi5yZWZyZXNoKCkgfHwgc3RhcnQpICsgYW5pbWF0aW9uLmxhYmVsc1tsYWJlbF0gLyBhbmltYXRpb24uZHVyYXRpb24oKSAqIGNoYW5nZSB8fCAwO1xuICAgIH07XG5cbiAgICBzZWxmLmdldFRyYWlsaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgIHZhciBpID0gX3RyaWdnZXJzLmluZGV4T2Yoc2VsZiksXG4gICAgICAgICAgYSA9IHNlbGYuZGlyZWN0aW9uID4gMCA/IF90cmlnZ2Vycy5zbGljZSgwLCBpKS5yZXZlcnNlKCkgOiBfdHJpZ2dlcnMuc2xpY2UoaSArIDEpO1xuXG4gICAgICByZXR1cm4gKF9pc1N0cmluZyhuYW1lKSA/IGEuZmlsdGVyKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiB0LnZhcnMucHJldmVudE92ZXJsYXBzID09PSBuYW1lO1xuICAgICAgfSkgOiBhKS5maWx0ZXIoZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuZGlyZWN0aW9uID4gMCA/IHQuZW5kIDw9IHN0YXJ0IDogdC5zdGFydCA+PSBlbmQ7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgc2VsZi51cGRhdGUgPSBmdW5jdGlvbiAocmVzZXQsIHJlY29yZFZlbG9jaXR5LCBmb3JjZUZha2UpIHtcbiAgICAgIGlmIChjb250YWluZXJBbmltYXRpb24gJiYgIWZvcmNlRmFrZSAmJiAhcmVzZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2Nyb2xsID0gX3JlZnJlc2hpbmdBbGwgPT09IHRydWUgPyBwcmV2U2Nyb2xsIDogc2VsZi5zY3JvbGwoKSxcbiAgICAgICAgICBwID0gcmVzZXQgPyAwIDogKHNjcm9sbCAtIHN0YXJ0KSAvIGNoYW5nZSxcbiAgICAgICAgICBjbGlwcGVkID0gcCA8IDAgPyAwIDogcCA+IDEgPyAxIDogcCB8fCAwLFxuICAgICAgICAgIHByZXZQcm9ncmVzcyA9IHNlbGYucHJvZ3Jlc3MsXG4gICAgICAgICAgaXNBY3RpdmUsXG4gICAgICAgICAgd2FzQWN0aXZlLFxuICAgICAgICAgIHRvZ2dsZVN0YXRlLFxuICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICBzdGF0ZUNoYW5nZWQsXG4gICAgICAgICAgdG9nZ2xlZCxcbiAgICAgICAgICBpc0F0TWF4LFxuICAgICAgICAgIGlzVGFraW5nQWN0aW9uO1xuXG4gICAgICBpZiAocmVjb3JkVmVsb2NpdHkpIHtcbiAgICAgICAgc2Nyb2xsMiA9IHNjcm9sbDE7XG4gICAgICAgIHNjcm9sbDEgPSBjb250YWluZXJBbmltYXRpb24gPyBzY3JvbGxGdW5jKCkgOiBzY3JvbGw7XG5cbiAgICAgICAgaWYgKHNuYXApIHtcbiAgICAgICAgICBzbmFwMiA9IHNuYXAxO1xuICAgICAgICAgIHNuYXAxID0gYW5pbWF0aW9uICYmICFpc1RvZ2dsZSA/IGFuaW1hdGlvbi50b3RhbFByb2dyZXNzKCkgOiBjbGlwcGVkO1xuICAgICAgICB9XG4gICAgICB9IC8vIGFudGljaXBhdGUgdGhlIHBpbm5pbmcgYSBmZXcgdGlja3MgYWhlYWQgb2YgdGltZSBiYXNlZCBvbiB2ZWxvY2l0eSB0byBhdm9pZCBhIHZpc3VhbCBnbGl0Y2ggZHVlIHRvIHRoZSBmYWN0IHRoYXQgbW9zdCBicm93c2VycyBkbyBzY3JvbGxpbmcgb24gYSBzZXBhcmF0ZSB0aHJlYWQgKG5vdCBzeW5jZWQgd2l0aCByZXF1ZXN0QW5pbWF0aW9uRnJhbWUpLlxuXG5cbiAgICAgIGlmIChhbnRpY2lwYXRlUGluICYmIHBpbiAmJiAhX3JlZnJlc2hpbmcgJiYgIV9zdGFydHVwICYmIF9sYXN0U2Nyb2xsVGltZSkge1xuICAgICAgICBpZiAoIWNsaXBwZWQgJiYgc3RhcnQgPCBzY3JvbGwgKyAoc2Nyb2xsIC0gc2Nyb2xsMikgLyAoX2dldFRpbWUoKSAtIF90aW1lMikgKiBhbnRpY2lwYXRlUGluKSB7XG4gICAgICAgICAgY2xpcHBlZCA9IDAuMDAwMTtcbiAgICAgICAgfSBlbHNlIGlmIChjbGlwcGVkID09PSAxICYmIGVuZCA+IHNjcm9sbCArIChzY3JvbGwgLSBzY3JvbGwyKSAvIChfZ2V0VGltZSgpIC0gX3RpbWUyKSAqIGFudGljaXBhdGVQaW4pIHtcbiAgICAgICAgICBjbGlwcGVkID0gMC45OTk5O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjbGlwcGVkICE9PSBwcmV2UHJvZ3Jlc3MgJiYgc2VsZi5lbmFibGVkKSB7XG4gICAgICAgIGlzQWN0aXZlID0gc2VsZi5pc0FjdGl2ZSA9ICEhY2xpcHBlZCAmJiBjbGlwcGVkIDwgMTtcbiAgICAgICAgd2FzQWN0aXZlID0gISFwcmV2UHJvZ3Jlc3MgJiYgcHJldlByb2dyZXNzIDwgMTtcbiAgICAgICAgdG9nZ2xlZCA9IGlzQWN0aXZlICE9PSB3YXNBY3RpdmU7XG4gICAgICAgIHN0YXRlQ2hhbmdlZCA9IHRvZ2dsZWQgfHwgISFjbGlwcGVkICE9PSAhIXByZXZQcm9ncmVzczsgLy8gY291bGQgZ28gZnJvbSBzdGFydCBhbGwgdGhlIHdheSB0byBlbmQsIHRodXMgaXQgZGlkbid0IHRvZ2dsZSBidXQgaXQgZGlkIGNoYW5nZSBzdGF0ZSBpbiBhIHNlbnNlIChtYXkgbmVlZCB0byBmaXJlIGEgY2FsbGJhY2spXG5cbiAgICAgICAgc2VsZi5kaXJlY3Rpb24gPSBjbGlwcGVkID4gcHJldlByb2dyZXNzID8gMSA6IC0xO1xuICAgICAgICBzZWxmLnByb2dyZXNzID0gY2xpcHBlZDtcblxuICAgICAgICBpZiAoc3RhdGVDaGFuZ2VkICYmICFfcmVmcmVzaGluZykge1xuICAgICAgICAgIHRvZ2dsZVN0YXRlID0gY2xpcHBlZCAmJiAhcHJldlByb2dyZXNzID8gMCA6IGNsaXBwZWQgPT09IDEgPyAxIDogcHJldlByb2dyZXNzID09PSAxID8gMiA6IDM7IC8vIDAgPSBlbnRlciwgMSA9IGxlYXZlLCAyID0gZW50ZXJCYWNrLCAzID0gbGVhdmVCYWNrICh3ZSBwcmlvcml0aXplIHRoZSBGSVJTVCBlbmNvdW50ZXIsIHRodXMgaWYgeW91IHNjcm9sbCByZWFsbHkgZmFzdCBwYXN0IHRoZSBvbkVudGVyIGFuZCBvbkxlYXZlIGluIG9uZSB0aWNrLCBpdCdkIHByaW9yaXRpemUgb25FbnRlci5cblxuICAgICAgICAgIGlmIChpc1RvZ2dsZSkge1xuICAgICAgICAgICAgYWN0aW9uID0gIXRvZ2dsZWQgJiYgdG9nZ2xlQWN0aW9uc1t0b2dnbGVTdGF0ZSArIDFdICE9PSBcIm5vbmVcIiAmJiB0b2dnbGVBY3Rpb25zW3RvZ2dsZVN0YXRlICsgMV0gfHwgdG9nZ2xlQWN0aW9uc1t0b2dnbGVTdGF0ZV07IC8vIGlmIGl0IGRpZG4ndCB0b2dnbGUsIHRoYXQgbWVhbnMgaXQgc2hvdCByaWdodCBwYXN0IGFuZCBzaW5jZSB3ZSBwcmlvcml0aXplIH
1RoZSBcImVudGVyXCIgYWN0aW9uLCB3ZSBzaG91bGQgc3dpdGNoIHRvIHRoZSBcImxlYXZlXCIgaW4gdGhpcyBjYXNlIChidXQgb25seSBpZiBvbmUgaXMgZGVmaW5lZClcblxuICAgICAgICAgICAgaXNUYWtpbmdBY3Rpb24gPSBhbmltYXRpb24gJiYgKGFjdGlvbiA9PT0gXCJjb21wbGV0ZVwiIHx8IGFjdGlvbiA9PT0gXCJyZXNldFwiIHx8IGFjdGlvbiBpbiBhbmltYXRpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZlbnRPdmVybGFwcyAmJiAodG9nZ2xlZCB8fCBpc1Rha2luZ0FjdGlvbikgJiYgKGlzVGFraW5nQWN0aW9uIHx8IHNjcnViIHx8ICFhbmltYXRpb24pICYmIChfaXNGdW5jdGlvbihwcmV2ZW50T3ZlcmxhcHMpID8gcHJldmVudE92ZXJsYXBzKHNlbGYpIDogc2VsZi5nZXRUcmFpbGluZyhwcmV2ZW50T3ZlcmxhcHMpLmZvckVhY2goZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICByZXR1cm4gdC5lbmRBbmltYXRpb24oKTtcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGlmICghaXNUb2dnbGUpIHtcbiAgICAgICAgICBpZiAoc2NydWJUd2VlbiAmJiAhX3JlZnJlc2hpbmcgJiYgIV9zdGFydHVwKSB7XG4gICAgICAgICAgICBzY3J1YlR3ZWVuLl9kcC5fdGltZSAtIHNjcnViVHdlZW4uX3N0YXJ0ICE9PSBzY3J1YlR3ZWVuLl90aW1lICYmIHNjcnViVHdlZW4ucmVuZGVyKHNjcnViVHdlZW4uX2RwLl90aW1lIC0gc2NydWJUd2Vlbi5fc3RhcnQpOyAvLyBpZiB0aGVyZSdzIGEgc2NydWIgb24gYm90aCB0aGUgY29udGFpbmVyIGFuaW1hdGlvbiBhbmQgdGhpcyBvbmUgKG9yIGEgU2Nyb2xsU21vb3RoZXIpLCB0aGUgdXBkYXRlIG9yZGVyIHdvdWxkIGNhdXNlIHRoaXMgb25lIG5vdCB0byBoYXZlIHJlbmRlcmVkIHlldCwgc28gaXQgd291bGRuJ3QgbWFrZSBhbnkgcHJvZ3Jlc3MgYmVmb3JlIHdlIC5yZXN0YXJ0KCkgaXQgaGVhZGluZyB0b3dhcmQgdGhlIG5ldyBwcm9ncmVzcyBzbyBpdCdkIGFwcGVhciBzdHVjayB0aHVzIHdlIGZvcmNlIGEgcmVuZGVyIGhlcmUuXG5cbiAgICAgICAgICAgIGlmIChzY3J1YlR3ZWVuLnJlc2V0VG8pIHtcbiAgICAgICAgICAgICAgc2NydWJUd2Vlbi5yZXNldFRvKFwidG90YWxQcm9ncmVzc1wiLCBjbGlwcGVkLCBhbmltYXRpb24uX3RUaW1lIC8gYW5pbWF0aW9uLl90RHVyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIGxlZ2FjeSBzdXBwb3J0IChjb3VydGVzeSksIGJlZm9yZSAzLjEwLjBcbiAgICAgICAgICAgICAgc2NydWJUd2Vlbi52YXJzLnRvdGFsUHJvZ3Jlc3MgPSBjbGlwcGVkO1xuICAgICAgICAgICAgICBzY3J1YlR3ZWVuLmludmFsaWRhdGUoKS5yZXN0YXJ0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChhbmltYXRpb24pIHtcbiAgICAgICAgICAgIGFuaW1hdGlvbi50b3RhbFByb2dyZXNzKGNsaXBwZWQsICEhKF9yZWZyZXNoaW5nICYmIChsYXN0UmVmcmVzaCB8fCByZXNldCkpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGluKSB7XG4gICAgICAgICAgcmVzZXQgJiYgcGluU3BhY2luZyAmJiAoc3BhY2VyLnN0eWxlW3BpblNwYWNpbmcgKyBkaXJlY3Rpb24ub3MyXSA9IHNwYWNpbmdTdGFydCk7XG5cbiAgICAgICAgICBpZiAoIXVzZUZpeGVkUG9zaXRpb24pIHtcbiAgICAgICAgICAgIHBpblNldHRlcihfcm91bmQocGluU3RhcnQgKyBwaW5DaGFuZ2UgKiBjbGlwcGVkKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZUNoYW5nZWQpIHtcbiAgICAgICAgICAgIGlzQXRNYXggPSAhcmVzZXQgJiYgY2xpcHBlZCA+IHByZXZQcm9ncmVzcyAmJiBlbmQgKyAxID4gc2Nyb2xsICYmIHNjcm9sbCArIDEgPj0gX21heFNjcm9sbChzY3JvbGxlciwgZGlyZWN0aW9uKTsgLy8gaWYgaXQncyBhdCB0aGUgVkVSWSBlbmQgb2YgdGhlIHBhZ2UsIGRvbid0IHN3aXRjaCBhd2F5IGZyb20gcG9zaXRpb246IGZpeGVkIGJlY2F1c2UgaXQncyBwb2ludGxlc3MgYW5kIGl0IGNvdWxkIGNhdXNlIGEgYnJpZWYgZmxhc2ggd2hlbiB0aGUgdXNlciBzY3JvbGxzIGJhY2sgdXAgKHdoZW4gaXQgZ2V0cyBwaW5uZWQgYWdhaW4pXG5cbiAgICAgICAgICAgIGlmIChwaW5SZXBhcmVudCkge1xuICAgICAgICAgICAgICBpZiAoIXJlc2V0ICYmIChpc0FjdGl2ZSB8fCBpc0F0TWF4KSkge1xuICAgICAgICAgICAgICAgIHZhciBib3VuZHMgPSBfZ2V0Qm91bmRzKHBpbiwgdHJ1ZSksXG4gICAgICAgICAgICAgICAgICAgIF9vZmZzZXQgPSBzY3JvbGwgLSBzdGFydDtcblxuICAgICAgICAgICAgICAgIF9yZXBhcmVudChwaW4sIF9ib2R5LCBib3VuZHMudG9wICsgKGRpcmVjdGlvbiA9PT0gX3ZlcnRpY2FsID8gX29mZnNldCA6IDApICsgX3B4LCBib3VuZHMubGVmdCArIChkaXJlY3Rpb24gPT09IF92ZXJ0aWNhbCA/IDAgOiBfb2Zmc2V0KSArIF9weCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgX3JlcGFyZW50KHBpbiwgc3BhY2VyKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBfc2V0U3RhdGUoaXNBY3RpdmUgfHwgaXNBdE1heCA/IHBpbkFjdGl2ZVN0YXRlIDogcGluU3RhdGUpO1xuXG4gICAgICAgICAgICBwaW5Nb3ZlcyAmJiBjbGlwcGVkIDwgMSAmJiBpc0FjdGl2ZSB8fCBwaW5TZXR0ZXIocGluU3RhcnQgKyAoY2xpcHBlZCA9PT0gMSAmJiAhaXNBdE1heCA/IHBpbkNoYW5nZSA6IDApKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzbmFwICYmICF0d2VlblRvLnR3ZWVuICYmICFfcmVmcmVzaGluZyAmJiAhX3N0YXJ0dXAgJiYgc25hcERlbGF5ZWRDYWxsLnJlc3RhcnQodHJ1ZSk7XG4gICAgICAgIHRvZ2dsZUNsYXNzICYmICh0b2dnbGVkIHx8IG9uY2UgJiYgY2xpcHBlZCAmJiAoY2xpcHBlZCA8IDEgfHwgIV9saW1pdENhbGxiYWNrcykpICYmIF90b0FycmF5KHRvZ2dsZUNsYXNzLnRhcmdldHMpLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgcmV0dXJuIGVsLmNsYXNzTGlzdFtpc0FjdGl2ZSB8fCBvbmNlID8gXCJhZGRcIiA6IFwicmVtb3ZlXCJdKHRvZ2dsZUNsYXNzLmNsYXNzTmFtZSk7XG4gICAgICAgI
1H0pOyAvLyBjbGFzc2VzIGNvdWxkIGFmZmVjdCBwb3NpdGlvbmluZywgc28gZG8gaXQgZXZlbiBpZiByZXNldCBvciByZWZyZXNoaW5nIGlzIHRydWUuXG5cbiAgICAgICAgb25VcGRhdGUgJiYgIWlzVG9nZ2xlICYmICFyZXNldCAmJiBvblVwZGF0ZShzZWxmKTtcblxuICAgICAgICBpZiAoc3RhdGVDaGFuZ2VkICYmICFfcmVmcmVzaGluZykge1xuICAgICAgICAgIGlmIChpc1RvZ2dsZSkge1xuICAgICAgICAgICAgaWYgKGlzVGFraW5nQWN0aW9uKSB7XG4gICAgICAgICAgICAgIGlmIChhY3Rpb24gPT09IFwiY29tcGxldGVcIikge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5wYXVzZSgpLnRvdGFsUHJvZ3Jlc3MoMSk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoYWN0aW9uID09PSBcInJlc2V0XCIpIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb24ucmVzdGFydCh0cnVlKS5wYXVzZSgpO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PT0gXCJyZXN0YXJ0XCIpIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb24ucmVzdGFydCh0cnVlKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25bYWN0aW9uXSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG9uVXBkYXRlICYmIG9uVXBkYXRlKHNlbGYpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0b2dnbGVkIHx8ICFfbGltaXRDYWxsYmFja3MpIHtcbiAgICAgICAgICAgIC8vIG9uIHN0YXJ0dXAsIHRoZSBwYWdlIGNvdWxkIGJlIHNjcm9sbGVkIGFuZCB3ZSBkb24ndCB3YW50IHRvIGZpcmUgY2FsbGJhY2tzIHRoYXQgZGlkbid0IHRvZ2dsZS4gRm9yIGV4YW1wbGUgb25FbnRlciBzaG91bGRuJ3QgZmlyZSBpZiB0aGUgU2Nyb2xsVHJpZ2dlciBpc24ndCBhY3R1YWxseSBlbnRlcmVkLlxuICAgICAgICAgICAgb25Ub2dnbGUgJiYgdG9nZ2xlZCAmJiBfY2FsbGJhY2soc2VsZiwgb25Ub2dnbGUpO1xuICAgICAgICAgICAgY2FsbGJhY2tzW3RvZ2dsZVN0YXRlXSAmJiBfY2FsbGJhY2soc2VsZiwgY2FsbGJhY2tzW3RvZ2dsZVN0YXRlXSk7XG4gICAgICAgICAgICBvbmNlICYmIChjbGlwcGVkID09PSAxID8gc2VsZi5raWxsKGZhbHNlLCAxKSA6IGNhbGxiYWNrc1t0b2dnbGVTdGF0ZV0gPSAwKTsgLy8gYSBjYWxsYmFjayBzaG91bGRuJ3QgYmUgY2FsbGVkIGFnYWluIGlmIG9uY2UgaXMgdHJ1ZS5cblxuICAgICAgICAgICAgaWYgKCF0b2dnbGVkKSB7XG4gICAgICAgICAgICAgIC8vIGl0J3MgcG9zc2libGUgdG8gZ28gY29tcGxldGVseSBwYXN0LCBsaWtlIGZyb20gYmVmb3JlIHRoZSBzdGFydCB0byBhZnRlciB0aGUgZW5kIChvciB2aWNlLXZlcnNhKSBpbiB3aGljaCBjYXNlIEJPVEggY2FsbGJhY2tzIHNob3VsZCBiZSBmaXJlZCBpbiB0aGF0IG9yZGVyXG4gICAgICAgICAgICAgIHRvZ2dsZVN0YXRlID0gY2xpcHBlZCA9PT0gMSA/IDEgOiAzO1xuICAgICAgICAgICAgICBjYWxsYmFja3NbdG9nZ2xlU3RhdGVdICYmIF9jYWxsYmFjayhzZWxmLCBjYWxsYmFja3NbdG9nZ2xlU3RhdGVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZmFzdFNjcm9sbEVuZCAmJiAhaXNBY3RpdmUgJiYgTWF0aC5hYnMoc2VsZi5nZXRWZWxvY2l0eSgpKSA+IChfaXNOdW1iZXIoZmFzdFNjcm9sbEVuZCkgPyBmYXN0U2Nyb2xsRW5kIDogMjUwMCkpIHtcbiAgICAgICAgICAgIF9lbmRBbmltYXRpb24oc2VsZi5jYWxsYmFja0FuaW1hdGlvbik7XG5cbiAgICAgICAgICAgIHNjcnViVHdlZW4gPyBzY3J1YlR3ZWVuLnByb2dyZXNzKDEpIDogX2VuZEFuaW1hdGlvbihhbmltYXRpb24sIGFjdGlvbiA9PT0gXCJyZXZlcnNlXCIgPyAxIDogIWNsaXBwZWQsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc1RvZ2dsZSAmJiBvblVwZGF0ZSAmJiAhX3JlZnJlc2hpbmcpIHtcbiAgICAgICAgICBvblVwZGF0ZShzZWxmKTtcbiAgICAgICAgfVxuICAgICAgfSAvLyB1cGRhdGUgYWJzb2x1dGVseS1wb3NpdGlvbmVkIG1hcmtlcnMgKG9ubHkgaWYgdGhlIHNjcm9sbGVyIGlzbid0IHRoZSB2aWV3cG9ydClcblxuXG4gICAgICBpZiAobWFya2VyRW5kU2V0dGVyKSB7XG4gICAgICAgIHZhciBuID0gY29udGFpbmVyQW5pbWF0aW9uID8gc2Nyb2xsIC8gY29udGFpbmVyQW5pbWF0aW9uLmR1cmF0aW9uKCkgKiAoY29udGFpbmVyQW5pbWF0aW9uLl9jYVNjcm9sbERpc3QgfHwgMCkgOiBzY3JvbGw7XG4gICAgICAgIG1hcmtlclN0YXJ0U2V0dGVyKG4gKyAobWFya2VyU3RhcnRUcmlnZ2VyLl9pc0ZsaXBwZWQgPyAxIDogMCkpO1xuICAgICAgICBtYXJrZXJFbmRTZXR0ZXIobik7XG4gICAgICB9XG5cbiAgICAgIGNhTWFya2VyU2V0dGVyICYmIGNhTWFya2VyU2V0dGVyKC1zY3JvbGwgLyBjb250YWluZXJBbmltYXRpb24uZHVyYXRpb24oKSAqIChjb250YWluZXJBbmltYXRpb24uX2NhU2Nyb2xsRGlzdCB8fCAwKSk7XG4gICAgfTtcblxuICAgIHNlbGYuZW5hYmxlID0gZnVuY3Rpb24gKHJlc2V0LCByZWZyZXNoKSB7XG4gICAgICBpZiAoIXNlbGYuZW5hYmxlZCkge1xuICAgICAgICBzZWxmLmVuYWJsZWQgPSB0cnVlO1xuXG4gICAgICAgIF9hZGRMaXN0ZW5lcihzY3JvbGxlciwgXCJyZXNpemVcIiwgX29uUmVzaXplKTtcblxuICAgICAgICBpc1ZpZXdwb3J0IHx8IF9hZGRMaXN0ZW5lcihzY3JvbGxlciwgXCJzY3JvbGxcIiwgX29uU2Nyb2xsKTtcbiAgICAgICAgb25SZWZyZXNoSW5pdCAmJiBfYWRkTGlzdGVuZXIoU2Nyb2xsVHJpZ2dlciwgXCJyZWZyZXNoSW5pdFwiLCBvblJlZnJlc2hJbml0KTtcblxuICAgICAgICBpZiAocmVzZXQgIT09IGZhbHNlKSB7XG4gICAgICAgICAgc2VsZi5wcm9ncmVzcyA9IHByZXZQcm9ncmVzcyA9IDA7XG4gICAgICAgICAgc2Nyb2xsMSA9IHNjcm9sbDIgPSBsYXN0U25hcCA9IHNjcm9sbEZ1bmMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlZnJlc2ggIT09IGZhbHNlICYmIHNlbGYucmVmcmVzaCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBzZWxmLmdldFR3ZWVuID0gZnVuY3Rpb24gKHNuYXApIHtcbiAgICAgIHJldHVybi
1BzbmFwICYmIHR3ZWVuVG8gPyB0d2VlblRvLnR3ZWVuIDogc2NydWJUd2VlbjtcbiAgICB9O1xuXG4gICAgc2VsZi5zZXRQb3NpdGlvbnMgPSBmdW5jdGlvbiAobmV3U3RhcnQsIG5ld0VuZCwga2VlcENsYW1wLCBwaW5PZmZzZXQpIHtcbiAgICAgIC8vIGRvZXNuJ3QgcGVyc2lzdCBhZnRlciByZWZyZXNoKCkhIEludGVuZGVkIHRvIGJlIGEgd2F5IHRvIG92ZXJyaWRlIHZhbHVlcyB0aGF0IHdlcmUgc2V0IGR1cmluZyByZWZyZXNoKCksIGxpa2UgeW91IGNvdWxkIHNldCBpdCBpbiBvblJlZnJlc2goKVxuICAgICAgaWYgKGNvbnRhaW5lckFuaW1hdGlvbikge1xuICAgICAgICAvLyBjb252ZXJ0IHJhdGlvcyBpbnRvIHNjcm9sbCBwb3NpdGlvbnMuIFJlbWVtYmVyLCBzdGFydC9lbmQgdmFsdWVzIG9uIFNjcm9sbFRyaWdnZXJzIHRoYXQgaGF2ZSBhIGNvbnRhaW5lckFuaW1hdGlvbiByZWZlciB0byB0aGUgdGltZSAoaW4gc2Vjb25kcyksIE5PVCBzY3JvbGwgcG9zaXRpb25zLlxuICAgICAgICB2YXIgc3QgPSBjb250YWluZXJBbmltYXRpb24uc2Nyb2xsVHJpZ2dlcixcbiAgICAgICAgICAgIGR1cmF0aW9uID0gY29udGFpbmVyQW5pbWF0aW9uLmR1cmF0aW9uKCksXG4gICAgICAgICAgICBfY2hhbmdlID0gc3QuZW5kIC0gc3Quc3RhcnQ7XG5cbiAgICAgICAgbmV3U3RhcnQgPSBzdC5zdGFydCArIF9jaGFuZ2UgKiBuZXdTdGFydCAvIGR1cmF0aW9uO1xuICAgICAgICBuZXdFbmQgPSBzdC5zdGFydCArIF9jaGFuZ2UgKiBuZXdFbmQgLyBkdXJhdGlvbjtcbiAgICAgIH1cblxuICAgICAgc2VsZi5yZWZyZXNoKGZhbHNlLCBmYWxzZSwge1xuICAgICAgICBzdGFydDogX2tlZXBDbGFtcChuZXdTdGFydCwga2VlcENsYW1wICYmICEhc2VsZi5fc3RhcnRDbGFtcCksXG4gICAgICAgIGVuZDogX2tlZXBDbGFtcChuZXdFbmQsIGtlZXBDbGFtcCAmJiAhIXNlbGYuX2VuZENsYW1wKVxuICAgICAgfSwgcGluT2Zmc2V0KTtcbiAgICAgIHNlbGYudXBkYXRlKCk7XG4gICAgfTtcblxuICAgIHNlbGYuYWRqdXN0UGluU3BhY2luZyA9IGZ1bmN0aW9uIChhbW91bnQpIHtcbiAgICAgIGlmIChzcGFjZXJTdGF0ZSAmJiBhbW91bnQpIHtcbiAgICAgICAgdmFyIGkgPSBzcGFjZXJTdGF0ZS5pbmRleE9mKGRpcmVjdGlvbi5kKSArIDE7XG4gICAgICAgIHNwYWNlclN0YXRlW2ldID0gcGFyc2VGbG9hdChzcGFjZXJTdGF0ZVtpXSkgKyBhbW91bnQgKyBfcHg7XG4gICAgICAgIHNwYWNlclN0YXRlWzFdID0gcGFyc2VGbG9hdChzcGFjZXJTdGF0ZVsxXSkgKyBhbW91bnQgKyBfcHg7XG5cbiAgICAgICAgX3NldFN0YXRlKHNwYWNlclN0YXRlKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgc2VsZi5kaXNhYmxlID0gZnVuY3Rpb24gKHJlc2V0LCBhbGxvd0FuaW1hdGlvbikge1xuICAgICAgaWYgKHNlbGYuZW5hYmxlZCkge1xuICAgICAgICByZXNldCAhPT0gZmFsc2UgJiYgc2VsZi5yZXZlcnQodHJ1ZSwgdHJ1ZSk7XG4gICAgICAgIHNlbGYuZW5hYmxlZCA9IHNlbGYuaXNBY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgYWxsb3dBbmltYXRpb24gfHwgc2NydWJUd2VlbiAmJiBzY3J1YlR3ZWVuLnBhdXNlKCk7XG4gICAgICAgIHByZXZTY3JvbGwgP
1SAwO1xuICAgICAgICBwaW5DYWNoZSAmJiAocGluQ2FjaGUudW5jYWNoZSA9IDEpO1xuICAgICAgICBvblJlZnJlc2hJbml0ICYmIF9yZW1vdmVMaXN0ZW5lcihTY3JvbGxUcmlnZ2VyLCBcInJlZnJlc2hJbml0XCIsIG9uUmVmcmVzaEluaXQpO1xuXG4gICAgICAgIGlmIChzbmFwRGVsYXllZENhbGwpIHtcbiAgICAgICAgICBzbmFwRGVsYXllZENhbGwucGF1c2UoKTtcbiAgICAgICAgICB0d2VlblRvLnR3ZWVuICYmIHR3ZWVuVG8udHdlZW4ua2lsbCgpICYmICh0d2VlblRvLnR3ZWVuID0gMCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzVmlld3BvcnQpIHtcbiAgICAgICAgICB2YXIgaSA9IF90cmlnZ2Vycy5sZW5ndGg7XG5cbiAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAoX3RyaWdnZXJzW2ldLnNjcm9sbGVyID09PSBzY3JvbGxlciAmJiBfdHJpZ2dlcnNbaV0gIT09IHNlbGYpIHtcbiAgICAgICAgICAgICAgcmV0dXJuOyAvL2Rvbid0IHJlbW92ZSB0aGUgbGlzdGVuZXJzIGlmIHRoZXJlIGFyZSBzdGlsbCBvdGhlciB0cmlnZ2VycyByZWZlcmVuY2luZyBpdC5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBfcmVtb3ZlTGlzdGVuZXIoc2Nyb2xsZXIsIFwicmVzaXplXCIsIF9vblJlc2l6ZSk7XG5cbiAgICAgICAgICBpc1ZpZXdwb3J0IHx8IF9yZW1vdmVMaXN0ZW5lcihzY3JvbGxlciwgXCJzY3JvbGxcIiwgX29uU2Nyb2xsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBzZWxmLmtpbGwgPSBmdW5jdGlvbiAocmV2ZXJ0LCBhbGxvd0FuaW1hdGlvbikge1xuICAgICAgc2VsZi5kaXNhYmxlKHJldmVydCwgYWxsb3dBbmltYXRpb24pO1xuICAgICAgc2NydWJUd2VlbiAmJiAhYWxsb3dBbmltYXRpb24gJiYgc2NydWJUd2Vlbi5raWxsKCk7XG4gICAgICBpZCAmJiBkZWxldGUgX2lkc1tpZF07XG5cbiAgICAgIHZhciBpID0gX3RyaWdnZXJzLmluZGV4T2Yoc2VsZik7XG5cbiAgICAgIGkgPj0gMCAmJiBfdHJpZ2dlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgaSA9PT0gX2kgJiYgX2RpcmVjdGlvbiA+IDAgJiYgX2ktLTsgLy8gaWYgd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHJlZnJlc2goKSBvciB1cGRhdGUoKSwgc3BsaWNpbmcgd291bGQgY2F1c2Ugc2tpcHMgaW4gdGhlIGluZGV4LCBzbyBhZGp1c3QuLi5cbiAgICAgIC8vIGlmIG5vIG90aGVyIFNjcm9sbFRyaWdnZXIgaW5zdGFuY2VzIG9mIHRoZSBzYW1lIHNjcm9sbGVyIGFyZSBmb3VuZCwgd2lwZSBvdXQgYW55IHJlY29yZGVkIHNjcm9sbCBwb3NpdGlvbi4gT3RoZXJ3aXNlLCBpbiBhIHNpbmdsZSBwYWdlIGFwcGxpY2F0aW9uLCBmb3IgZXhhbXBsZSwgaXQgY291bGQgbWFpbnRhaW4gc2Nyb2xsIHBvc2l0aW9uIHdoZW4gaXQgcmVhbGx5IHNob3VsZG4ndC5cblxuICAgICAgaSA9IDA7XG5cbiAgICAgIF90cmlnZ2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHJldHVybiB0LnNjcm9sbGVyID09PSBzZWxmLnNjcm9sbGVyICYmIChpID0gMSk7XG4gICAgICB9KTtcblxuICAgICAgaSB8fCBfcmVmcmVzaGluZ0FsbCB8fCAoc2VsZi5zY3JvbGwucmVjID0gMCk7XG5cbiAgICAgIGlmIChhbmltYXRpb24pIHtcbiAgICAgICAgYW5pbWF0aW9uLnNjcm9sbFRyaWdnZXIgPSBudWxsO1xuICAgICAgICByZXZlcnQgJiYgYW5pbWF0aW9uLnJldmVydCh7XG4gICAgICAgICAga2lsbDogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGFsbG93QW5pbWF0aW9uIHx8IGFuaW1hdGlvbi5raWxsKCk7XG4gICAgICB9XG5cbiAgICAgIG1hcmtlclN0YXJ0ICYmIFttYXJrZXJTdGFydCwgbWFya2VyRW5kLCBtYXJrZXJTdGFydFRyaWdnZXIsIG1hcmtlckVuZFRyaWdnZXJdLmZvckVhY2goZnVuY3Rpb24gKG
10pIHtcbiAgICAgICAgcmV0dXJuIG0ucGFyZW50Tm9kZSAmJiBtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobSk7XG4gICAgICB9KTtcbiAgICAgIF9wcmltYXJ5ID09PSBzZWxmICYmIChfcHJpbWFyeSA9IDApO1xuXG4gICAgICBpZiAocGluKSB7XG4gICAgICAgIHBpbkNhY2hlICYmIChwaW5DYWNoZS51bmNhY2hlID0gMSk7XG4gICAgICAgIGkgPSAwO1xuXG4gICAgICAgIF90cmlnZ2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgcmV0dXJuIHQucGluID09PSBwaW4gJiYgaSsrO1xuICAgICAgICB9KTtcblxuICAgICAgICBpIHx8IChwaW5DYWNoZS5zcGFjZXIgPSAwKTsgLy8gaWYgdGhlcmUgYXJlbid0IGFueSBtb3JlIFNjcm9sbFRyaWdnZXJzIHdpdGggdGhlIHNhbWUgcGluLCByZW1vdmUgdGhlIHNwYWNlciwgb3RoZXJ3aXNlIGl0IGNvdWxkIGJlIGNvbnRhbWluYXRlZCB3aXRoIG9sZC9zdGFsZSB2YWx1ZXMgaWYgdGhlIHVzZXIgcmUtY3JlYXRlcyBhIFNjcm9sbFRyaWdnZXIgZm9yIHRoZSBzYW1lIGVsZW1lbnQuXG4gICAgICB9XG5cbiAgICAgIHZhcnMub25LaWxsICYmIHZhcnMub25LaWxsKHNlbGYpO1xuICAgIH07XG5cbiAgICBfdHJpZ2dlcnMucHVzaChzZWxmKTtcblxuICAgIHNlbGYuZW5hYmxlKGZhbHNlLCBmYWxzZSk7XG4gICAgY3VzdG9tUmV2ZXJ0UmV0dXJuICYmIGN1c3RvbVJldmVydFJldHVybihzZWxmKTtcblxuICAgIGlmIChhbmltYXRpb24gJiYgYW5pbWF0aW9uLmFkZCAmJiAhY2hhbmdlKSB7XG4gICAgICAvLyBpZiB0aGUgYW5pbWF0aW9uIGlzIGEgdGltZWxpbmUsIGl0IG1heSBub3QgaGF2ZSBiZWVuIHBvcHVsYXRlZCB5ZXQsIHNvIGl0IHdvdWxkbid0IHJlbmRlciBhdCB0aGUgcHJvcGVyIHBsYWNlIG9uIHRoZSBmaXJzdCByZWZyZXNoKCksIHRodXMgd2Ugc2hvdWxkIHNjaGVkdWxlIG9uZSBmb3IgdGhlIG5leHQgdGljay4gSWYgXCJjaGFuZ2VcIiBpcyBkZWZpbmVkLCB3ZSBrbm93IGl0IG11c3QgYmUgcmUtZW5hYmxpbmcsIHRodXMgd2UgY2FuIHJlZnJlc2goKSByaWdodCBhd2F5LlxuICAgICAgdmFyIHVwZGF0ZUZ1bmMgPSBzZWxmLnVwZGF0ZTsgLy8gc29tZSBicm93c2VycyBtYXkgZmlyZSBhIHNjcm9sbCBldmVudCBCRUZPUkUgYSB0aWNrIGVsYXBzZXMgYW5kL29yIHRoZSBET01Db250ZW50TG9hZGVkIGZpcmVzLiBTbyB0aGVyZSdzIGEgY2hhbmNlIHVwZGF0ZSgpIHdpbGwgYmUgY2FsbGVkIEJFRk9S
1RSBhIHJlZnJlc2goKSBoYXMgaGFwcGVuZWQgb24gYSBUaW1lbGluZS1hdHRhY2hlZCBTY3JvbGxUcmlnZ2VyIHdoaWNoIG1lYW5zIHRoZSBzdGFydC9lbmQgd29uJ3QgYmUgY2FsY3VsYXRlZCB5ZXQuIFdlIGRvbid0IHdhbnQgdG8gYWRkIGNvbmRpdGlvbmFsIGxvZ2ljIGluc2lkZSB0aGUgdXBkYXRlKCkgbWV0aG9kIChsaWtlIGNoZWNrIHRvIHNlZSBpZiBlbmQgaXMgZGVmaW5lZCBhbmQgaWYgbm90LCBmb3JjZSBhIHJlZnJlc2goKSkgYmVjYXVzZSB0aGF0J3MgYSBmdW5jdGlvbiB0aGF0IGdldHMgaGl0IGEgTE9UIChwZXJmb3JtYW5jZSkuIFNvIHdlIHN3YXAgb3V0IHRoZSByZWFsIHVwZGF0ZSgpIG1ldGhvZCBmb3IgdGhpcyBvbmUgdGhhdCdsbCByZS1hdHRhY2ggaXQgdGhlIGZpcnN0IHRpbWUgaXQgZ2V0cyBjYWxsZWQgYW5kIG9mIGNvdXJzZSBmb3JjZXMgYSByZWZyZXNoKCkuXG5cbiAgICAgIHNlbGYudXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnVwZGF0ZSA9IHVwZGF0ZUZ1bmM7XG4gICAgICAgIHN0YXJ0IHx8IGVuZCB8fCBzZWxmLnJlZnJlc2goKTtcbiAgICAgIH07XG5cbiAgICAgIGdzYXAuZGVsYXllZENhbGwoMC4wMSwgc2VsZi51cGRhdGUpO1xuICAgICAgY2hhbmdlID0gMC4wMTtcbiAgICAgIHN0YXJ0ID0gZW5kID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi5yZWZyZXNoKCk7XG4gICAgfVxuXG4gICAgcGluICYmIF9xdWV1ZVJlZnJlc2hBbGwoKTsgLy8gcGlubmluZyBjb3VsZCBhZmZlY3QgdGhlIHBvc2l0aW9ucyBvZiBvdGhlciB0aGluZ3MsIHNvIG1ha2Ugc3VyZSB3ZSBxdW
1V1ZSBhIGZ1bGwgcmVmcmVzaCgpXG4gIH07XG5cbiAgU2Nyb2xsVHJpZ2dlci5yZWdpc3RlciA9IGZ1bmN0aW9uIHJlZ2lzdGVyKGNvcmUpIHtcbiAgICBpZiAoIV9jb3JlSW5pdHRlZCkge1xuICAgICAgZ3NhcCA9IGNvcmUgfHwgX2dldEdTQVAoKTtcbiAgICAgIF93aW5kb3dFeGlzdHMoKSAmJiB3aW5kb3cuZG9jdW1lbnQgJiYgU2Nyb2xsVHJpZ2dlci5lbmFibGUoKTtcbiAgICAgIF9jb3JlSW5pdHRlZCA9IF9lbmFibGVkO1xuICAgIH1cblxuICAgIHJldHVybiBfY29yZUluaXR0ZWQ7XG4gIH07XG5cbiAgU2Nyb2xsVHJpZ2dlci5kZWZhdWx0cyA9IGZ1bmN0aW9uIGRlZmF1bHRzKGNvbmZpZykge1xuICAgIGlmIChjb25maWcpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gY29uZmlnKSB7XG4gICAgICAgIF9kZWZhdWx0c1twXSA9IGNvbmZpZ1twXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gX2RlZmF1bHRzO1xuICB9O1xuXG4gIFNjcm9sbFRyaWdnZXIuZGlzYWJsZSA9IGZ1bmN0aW9uIGRpc2FibGUocmVzZXQsIGtpbGwpIHtcbiAgICBfZW5hYmxlZCA9IDA7XG5cbiAgICBfdHJpZ2dlcnMuZm9yRWFjaChmdW5jdGlvbiAodHJpZ2dlcikge1xuICAgICAgcmV0dXJuIHRyaWdnZXJba2lsbCA/IFwia2lsbFwiIDogXCJkaXNhYmxlXCJdKHJlc2V0KTtcbiAgICB9KTtcblxuICAgIF9yZW1vdmVMaXN0ZW5lcihfd2luLCBcIndoZWVsXCIsIF9vblNjcm9sbCk7XG5cbiAgICBfcmVtb3ZlTGlzdGVuZXIoX2RvYywgXCJzY3JvbGxcIiwgX29uU2Nyb2xsKTtcblxuICAgIGNsZWFySW50ZXJ2YWwoX3N5bmNJbnRlcnZhbCk7XG5cbiAgICBfcmVtb3ZlTGlzdGVuZXIoX2RvYywgXCJ0b3VjaGNhbmNlbFwiLCBfcGFzc1Rocm91Z2gpO1xuXG4gICAgX3JlbW92ZUxpc3RlbmVyKF9ib2R5LCBcInRvdWNoc3RhcnRcIiwgX3Bhc3NUaHJvdWdoKTtcblxuICAgIF9tdWx0aUxpc3RlbmVyKF9yZW1vdmVMaXN0ZW5lciwgX2RvYywgXCJwb2ludGVyZG93bix0b3VjaHN0YXJ0LG1vdXNlZG93blwiLCBfcG9pbnRlckRvd25IYW5kbGVyKTtcblxuICAgIF9tdWx0aUxpc3RlbmVyKF9yZW1vdmVMaXN0ZW5lciwgX2RvYywgXCJwb2ludGVydXAsdG91Y2hlbmQsbW91c2V1cFwiLCBfcG9pbnRlclVwSGFuZGxlcik7XG5cbiAgICBfcmVzaXplRGVsYXkua2lsbCgpO1xuXG4gICAgX2l0ZXJhdGVBdXRvUmVmcmVzaChfcmVtb3ZlTGlzdGVuZXIpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfc2Nyb2xsZXJzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICBfd2hlZWxMaXN0ZW5lcihfcmVtb3ZlTGlzdGVuZXIsIF9zY3JvbGxlcnNbaV0sIF9zY3JvbGxlcnNbaSArIDFdKTtcblxuICAgICAgX3doZWVsTGlzdGVuZXIoX3JlbW92ZUxpc3RlbmVyLCBfc2Nyb2xsZXJzW2ldLCBfc2Nyb2xsZXJzW2kgKyAyXSk7XG4gICAgfVxuICB9O1xuXG4gIFNjcm9sbFRyaWdnZXIuZW5hYmxlID0gZnVuY3Rpb24gZW5hYmxlKCkge1xuICAgIF93aW4gPSB3aW5kb3c7XG4gICAgX2RvYyA9IGRvY3VtZW50O1xuICAgIF9kb2NFbCA9IF9kb2MuZG9jdW1lbnRFbGVtZW50O1xuICAgIF9ib2R5ID0gX2RvYy5ib2R5O1xuXG4gICAgaWYgKGdzYXApIHtcbiAgICAgIF90b0FycmF5ID0gZ3NhcC51dGlscy50b0FycmF5O1xuICAgICAgX2NsYW1wID0gZ3NhcC51dGlscy5jbGFtcDtcbiAgICAgIF9jb250ZXh0ID0gZ3NhcC5jb3JlLmNvbnRleHQgfHwgX3Bhc3NUaHJvdWdoO1xuICAgICAgX3N1cHByZXNzT3ZlcndyaXRlcyA9IGdzYXAuY29yZS5zdXBwcmVzc092ZXJ3cml0ZXMgfHwgX3Bhc3NUaHJvdWdoO1xuICAgICAgX3Njcm9sbFJlc3RvcmF0aW9uID0gX3dpbi5oaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uIHx8IFwiYXV0b1wiO1xuICAgICAgX2xhc3RTY3JvbGwgPSBfd2luLnBhZ2VZT2Zmc2V0O1xuICAgICAgZ3NhcC5jb3JlLmdsb2JhbHMoXCJTY3JvbGxUcmlnZ2VyXCIsIFNjcm9sbFRyaWdnZXIpOyAvLyBtdXN0IHJlZ2lzdGVyIHRoZSBnbG9iYWwgbWFudWFsbHkgYmVjYXVzZSBpbiBJbnRlcm5ldCBFeHBsb3JlciwgZnVuY3Rpb25zIChjbGFzc2VzKSBkb24ndCBoYXZlIGEgXCJuYW1lXCIgcHJvcGVydHkuXG5cbiAgICAgIGlmIChfYm9keSkge1xuICAgICAgICBfZW5hYmxlZCA9IDE7XG4gICAgICAgIF9kaXYxMDB2aCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7IC8vIHRvIHNvbHZlIG1vYmlsZSBicm93c2VyIGFkZHJlc3MgYmFyIHNob3cvaGlkZSByZXNpemluZywgd2Ugc2hvdWxkbid0IHJlbHkgb24gd2luZG93LmlubmVySGVpZ2h0LiBJbnN0ZWFkLCB1c2UgYSA8ZGl2PiB3aXRoIGl0cyBoZWlnaHQgc2V0IHRvIDEwMHZoIGFuZCBtZWFzdXJlIHRoYXQgc2luY2UgdGhhdCdzIHdoYXQgdGhlIHNjcm9sbGluZyBpcyBiYXNlZCBvbiBhbnl3YXkgYW5kIGl0J3Mgbm90IGFmZmVjdGVkIGJ5IGFkZHJlc3MgYmFyIHNob3dpbmcvaGlkaW5nLlxuXG4gICAgICAgIF9kaXYxMDB2aC5zdHlsZS5oZWlnaHQgPSBcIjEwMHZoXCI7XG4gICAgICAgIF9kaXYxMDB2aC5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblxuICAgICAgICBfcmVmcmVzaDEwMHZoKCk7XG5cbiAgICAgICAgX3JhZkJ1Z0ZpeCgpO1xuXG4gICAgICAgIE9ic2VydmVyLnJlZ2lzdGVyKGdzYXApOyAvLyBpc1RvdWNoIGlzIDAgaWYgbm8gdG91Y2gsIDEgaWYgT05MWSB0b3VjaCwgYW5kIDIgaWYgaXQgY2FuIGFjY29tbW9kYXRlIHRvdWNoIGJ1dCBhbHNvIG90aGVyIHR5cGVzIGxpa2UgbW91c2UvcG9pbnRlci5cblxuICAgICAgICBTY3JvbGxUcmlnZ2VyLmlzVG91Y2ggPSBPYnNlcnZlci5pc1RvdWNoO1xuICAgICAgICBfZml4SU9TQnVnID0gT2JzZXJ2ZXIuaXNUb3VjaCAmJiAvKGlQYWR8aVBob25lfGlQb2R8TWFjKS9nLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7IC8vIHNpbmNlIDIwMTcsIGlP
1UyBoYXMgaGFkIGEgYnVnIHRoYXQgY2F1c2VzIGV2ZW50LmNsaWVudFgvWSB0byBiZSBpbmFjY3VyYXRlIHdoZW4gYSBzY3JvbGwgb2NjdXJzLCB0aHVzIHdlIG11c3QgYWx0ZXJuYXRlIGlnbm9yaW5nIGV2ZXJ5IG90aGVyIHRvdWNobW92ZSBldmVudCB0byB3b3JrIGFyb3VuZCBpdC4gU2VlIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xODE5NTQgYW5kIGh0dHBzOi8vY29kZXBlbi5pby9HcmVlblNvY2svcGVuL0V4YnJQTmEvMDg3Y2VmMTk3ZGMzNTQ0NWEwOTUxZTg5MzVjNDE1MDNcblxuICAgICAgICBfaWdub3JlTW9iaWxlUmVzaXplID0gT2JzZXJ2ZXIuaXNUb3VjaCA9PT0gMTtcblxuICAgICAgICBfYWRkTGlzdGVuZXIoX3dpbiwgXCJ3aGVlbFwiLCBfb25TY3JvbGwpOyAvLyBtb3N0bHkgZm9yIDNyZCBwYXJ0eSBzbW9vdGggc2Nyb2xsaW5nIGxpYnJhcmllcy5cblxuXG4gICAgICAgIF9yb290ID0gW193aW4sIF9kb2MsIF9kb2NFbCwgX2JvZHldO1xuXG4gICAgICAgIGlmIChnc2FwLm1hdGNoTWVkaWEpIHtcbiAgICAgICAgICBTY3JvbGxUcmlnZ2VyLm1hdGNoTWVkaWEgPSBmdW5jdGlvbiAodmFycykge1xuICAgICAgICAgICAgdmFyIG1tID0gZ3NhcC5tYXRjaE1lZGlhKCksXG4gICAgICAgICAgICAgICAgcDtcblxuICAgICAgICAgICAgZm9yIChwIGluIHZhcnMpIHtcbiAgICAgICAgICAgICAgbW0uYWRkKHAsIHZhcnNbcF0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbW07XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGdzYXAuYWRkRXZlbnRMaXN0ZW5lcihcIm1hdGNoTWVkaWFJbml0XCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBfcmV2ZXJ0QWxsKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZ3NhcC5hZGRFdmVudExpc3RlbmVyKFwibWF0Y2hNZWRpYVJldmVydFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gX3JldmVydFJlY29yZGVkKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZ3NhcC5hZGRFdmVudExpc3RlbmVyKFwibWF0Y2hNZWRpYVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfcmVmcmVzaEFsbCgwLCAxKTtcblxuICAgICAgICAgICAgX2Rpc3BhdGNoKFwibWF0Y2hNZWRpYVwiKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBnc2FwLm1hdGNoTWVkaWEoXCIob3JpZW50YXRpb246IHBvcnRyYWl0KVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyB3aGVuIG9yaWVudGF0aW9uIGNoYW5nZXMsIHdlIHNob3VsZCB0YWtlIG5ldyBiYXNlIG1lYXN1cmVtZW50cyBmb3IgdGhlIGlnbm9yZU1vYmlsZVJlc2l6ZSBmZWF0dXJlLlxuICAgICAgICAgICAgX3NldEJhc2VEaW1lbnNpb25zKCk7XG5cbiAgICAgICAgICAgIHJldHVybiBfc2V0QmFzZURpbWVuc2lvbnM7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFwiUmVxdWlyZXMgR1NBUCAzLjExLjAgb3IgbGF0ZXJcIik7XG4gICAgICAgIH1cblxuICAgICAgICBfc2V0QmFzZURpbWVuc2lvbnMoKTtcblxuICAgICAgICBfYWRkTGlzdGVuZXIoX2RvYywgXCJzY3JvbGxcIiwgX29uU2Nyb2xsKTsgLy8gc29tZSBicm93c2VycyAobGlrZSBDaHJvbWUpLCB0aGUgd2luZG93IHN0b3BzIGRpc3BhdGNoaW5nIHNjcm9sbCBldmVudHMgb24gdGhlIHdpbmRvdyBpZiB5b3Ugc2Nyb2xsIHJlYWxseSBmYXN0LCBidXQgaXQncyBjb25zaXN0ZW50IG9uIHRoZSBkb2N1bWVudCFcblxuXG4gICAgICAgIHZhciBib2R5U3R5bGUgPSBfYm9keS5zdHlsZSxcbiAgICAgICAgICAgIGJvcmRlciA9IGJvZHlTdHlsZS5ib3JkZXJUb3BTdHlsZSxcbiAgICAgICAgICAgIEFuaW1hdGlvblByb3RvID0gZ3NhcC5jb3JlLkFuaW1hdGlvbi5wcm90b3R5cGUsXG4gICAgICAgICAgICBib3VuZHMsXG4gICAgICAgICAgICBpO1xuICAgICAgICBBbmltYXRpb25Qcm90by5yZXZlcnQgfHwgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFuaW1hdGlvblByb3RvLCBcInJldmVydFwiLCB7XG4gICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGltZSgtMC4wMSwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTsgLy8gb25seSBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgKEFuaW1hdGlvbi5yZXZlcnQoKSB3YXMgYWRkZWQgYWZ0ZXIgMy4xMC40KVxuXG4gICAgICAgIGJvZHlTdHlsZS5ib3JkZXJUb3BTdHlsZSA9IFwic29saWRcIjsgLy8gd29ya3MgYXJvdW5kIGFuIGlzc3VlIHdoZXJlIGEgbWFyZ2luIG9mIGEgY2hpbGQgZWxlbWVudCBjb3VsZCB0aHJvdyBvZmYgdGhlIGJvdW5kcyBvZiB0aGUgX2JvZHksIG1ha2luZyBpdCBzZWVtIGxpa2UgdGhlcmUncyBhIG1hcmdpbiB3aGVuIHRoZXJlIGFjdHVhbGx5IGlzbid0LiBUaGUgYm9yZGVyIGVuc3VyZXMgdGhhdCB0aGUgYm91bmRzIGFyZSBhY2N1cmF0ZS5cblxuICAgICAgICBib3VuZHMgPSBfZ2V0Qm91bmRzKF9ib2R5KTtcbiAgICAgICAgX3ZlcnRpY2FsLm0gPSBNYXRoLnJvdW5kKGJvdW5kcy50b3AgKyBfdmVydGljYWwuc2MoKSkgfHwgMDsgLy8gYWNjb21tb2RhdGUgdGhlIG9mZnNldCBvZiB0aGUgPGJvZHk+IGNhdXNlZCBieSBtYXJnaW5zIGFuZC9vciBwYWRkaW5nXG5cbiAgICAgICAgX2hvcml6b250YWwubSA9IE1hdGgucm91bmQoYm91bmRzLmxlZnQgKyBfaG9yaXpvbnRhbC5zYygpKSB8fCAwO1xuICAgICAgICBib3JkZXIgPyBib2R5U3R5bGUuYm9yZGVyVG9wU3R5bGUgPSBib3JkZXIgOiBib2R5U3R5bGUucmVtb3ZlUHJvcGVydHkoXCJib3JkZXItdG9wLXN0eWxlXCIpOyAvLyBUT0RPOiAoPykgbWF5YmUgbW92ZSB0byBsZXZlcmFnaW5nIHRoZSB2ZWxvY2l0eSBtZWNoYW5pc20gaW4gT2JzZXJ2ZXIgYW5kIHNraXAgaW50ZXJ2YWxzLlxuXG4gICAgICAgIF9zeW5jSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChfc3luYywgMjUwKTtcbiAgICAgICAgZ3NhcC5kZWxheWVkQ2FsbCgwLjUsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gX3N0YXJ0dXAgPSAwO1xuICAgICAgICB9KTtcblxuICAgICAgICBfYWRkTGlzdGVuZXIoX2RvYywgXCJ0b3VjaGNhbmNlbFwiLCBfcGFzc1Rocm91Z2gpOyAvLyBzb21lIG9sZGVyIEFuZHJvaWQgZGV2aWNlcyBpbnRlcm1pdHRlbnRseSBzdG9wIGRpc3BhdGNoaW5nIFwidG91Y2htb3ZlXCIgZXZlbnRzIGlmIHdlIGRvbid0IGxpc3RlbiBmb3IgXCJ0b3VjaGNhbmNlbFwiIG9uIHRoZSBkb2N1bWVudC5cblxuXG4gICAgICAgIF9hZGRMaXN0ZW5lcihfYm9keSwgXCJ0b3VjaHN0YXJ0XCIsIF9wYXNzVGhyb3VnaCk7IC8vd29ya3MgYXJvdW5kIFNhZmFyaSBidWc6IGh0dHBzOi8vZ3NhcC5jb20vZm9ydW1zL3RvcGljLzIxNDUwLWRyYWdnYWJsZS1pbi1pZnJhbWUtb24tbW9iaWxlLWlzLWJ1Z2d5L1xuXG5cbiAgICAgICAgX211bHRpTGlzdGVuZXIoX2FkZExpc3RlbmVyLCBfZG9jLCBcInBvaW50ZXJkb3duLHRvdWNoc3RhcnQsbW91c2Vkb3duXCIsIF9wb2ludGVyRG93bkhhbmRsZXIpO1xuXG4gICAgICAgIF9tdWx0aUxpc3RlbmVyKF9hZGRMaXN0ZW5lciwgX2RvYywgXCJwb2ludGVydXAsdG91Y2hlbmQsbW91c2V1cFwiLCBfcG9pbnRlclVwSGFuZGxlcik7XG5cbiAgICAgICAgX3RyYW5zZm9ybVByb3AgPSBnc2FwLnV0aWxzLmNoZWNrUHJlZml4KFwidHJhbnNmb3JtXCIpO1xuXG4gICAgICAgIF9zdGF0ZVByb3BzLnB1c2goX3RyYW5zZm9ybVByb3ApO1xuXG4gICAgICAgIF9jb3JlSW5pdHRlZCA9IF9nZXRUaW1lKCk7XG4gICAgICAgIF9yZXNpemVEZWxheSA9IGdzYXAuZGVsYXllZENhbGwoMC4yLCBfcmVmcmVzaEFsbCkucGF1c2UoKTtcbiAgICAgICAgX2F1dG9SZWZyZXNoID0gW19kb2MsIFwidmlzaWJpbGl0eWNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIHcgPSBfd2luLmlubmVyV2lkdGgsXG4gICAgICAgICAgICAgIGggPSBfd2luLmlubmVySGVpZ2h0O1xuXG4gICAgICAgICAgaWYgKF9kb2MuaGlkZGVuKSB7XG4gICAgICAgICAgICBfcHJldldpZHRoID0gdztcbiAgICAgICAgICAgIF9wcmV2SGVpZ2h0ID0gaDtcbiAgICAgICAgICB9IGVsc2UgaWYgKF9wcmV2V2lkdGggIT09IHcgfHwgX3ByZXZIZWlnaHQgIT09IGgpIHtcbiAgICAgICAgICAgIF9vblJlc2l6ZSgpO1xuICAgICAgICAgI
1H1cbiAgICAgICAgfSwgX2RvYywgXCJET01Db250ZW50TG9hZGVkXCIsIF9yZWZyZXNoQWxsLCBfd2luLCBcImxvYWRcIiwgX3JlZnJlc2hBbGwsIF93aW4sIFwicmVzaXplXCIsIF9vblJlc2l6ZV07XG5cbiAgICAgICAgX2l0ZXJhdGVBdXRvUmVmcmVzaChfYWRkTGlzdGVuZXIpO1xuXG4gICAgICAgIF90cmlnZ2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh0cmlnZ2VyKSB7XG4gICAgICAgICAgcmV0dXJuIHRyaWdnZXIuZW5hYmxlKDAsIDEpO1xuICAgICAgICB9KTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgX3Njcm9sbGVycy5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICAgIF93aGVlbExpc3RlbmVyKF9yZW1vdmVMaXN0ZW5lciwgX3Njcm9sbGVyc1tpXSwgX3Njcm9sbGVyc1tpICsgMV0pO1xuXG4gICAgICAgICAgX3doZWVsTGlzdGVuZXIoX3JlbW92ZUxpc3RlbmVyLCBfc2Nyb2xsZXJzW2ldLCBfc2Nyb2xsZXJzW2kgKyAyXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgU2Nyb2xsVHJpZ2dlci5jb25maWcgPSBmdW5jdGlvbiBjb25maWcodmFycykge1xuICAgIFwibGltaXRDYWxsYmFja3NcIiBpbiB2YXJzICYmIChfbGltaXRDYWxsYmFja3MgPSAhIXZhcnMubGltaXRDYWxsYmFja3MpO1xuICAgIHZhciBtcyA9IHZhcnMuc3luY0ludGVydmFsO1xuICAgIG1zICYmIGNsZWFySW50ZXJ2YWwoX3N5bmNJbnRlcnZhbCkgfHwgKF9zeW5jSW50ZXJ2YWwgPSBtcykgJiYgc2V0SW50ZXJ2YWwoX3N5bmMsIG1zKTtcbiAgICBcImlnbm9yZU1vYmlsZVJlc2l6ZVwiIGluIHZhcnMgJiYgKF9pZ25vcmVNb2JpbGVSZXNpemUgPSBTY3JvbGxUcmlnZ2VyLmlzVG91Y2ggPT09IDEgJiYgdmFycy5pZ25vcmVNb2JpbGVSZXNpemUpO1xuXG4gICAgaWYgKFwiYXV0b1JlZnJlc2hFdmVudHNcIiBpbiB2YXJzKSB7XG4gICAgICBfaXRlcmF0ZUF1dG9SZWZyZXNoKF9yZW1vdmVMaXN0ZW5lcikgfHwgX2l0ZXJhdGVBdXRvUmVmcmVzaChfYWRkTGlzdGVuZXIsIHZhcnMuYXV0b1JlZnJlc2hFdmVudHMgfHwgXCJub25lXCIpO1xuICAgICAgX2lnbm9yZVJlc2l6ZSA9ICh2YXJzLmF1dG9SZWZyZXNoRXZlbnRzICsgXCJcIikuaW5kZXhPZihcInJlc2l6ZVwiKSA9PT0gLTE7XG4gICAgfVxuICB9O1xuXG4gIFNjcm9sbFRyaWdnZXIuc2Nyb2xsZXJQcm94eSA9IGZ1bmN0aW9uIHNjcm9sbGVyUHJveHkodGFyZ2V0LCB2YXJzKSB7XG4gICAgdmFyIHQgPSBfZ2V0VGFyZ2V0KHRhcmdldCksXG4gICAgICAgIGkgPSBfc2Nyb2xsZXJzLmluZGV4T2YodCksXG4gICAgICAgIGlzVmlld3BvcnQgPSBfaXNWaWV3cG9ydCh0KTtcblxuICAgIGlmICh+aSkge1xuICAgICAgX3Njcm9sbGVycy5zcGxpY2UoaSwgaXNWaWV3cG9ydCA/IDYgOiAyKTtcbiAgICB9XG5cbiAgICBpZiAodmFycykge1xuICAgICAgaXNWaWV3cG9ydCA/IF9wcm94aWVzLnVuc2hpZnQoX3dpbiwgdmFycywgX2JvZHksIHZhcnMsIF9kb2NFbCwgdmFycykgOiBfcHJveGllcy51bnNoaWZ0KHQsIHZhcnMpO1xuICAgIH1cbiAgfTtcblxuICBTY3JvbGxUcmlnZ2VyLmNsZWFyTWF0Y2hNZWRpYSA9IGZ1bmN0aW9uIGNsZWFyTWF0Y2hNZWRpYShxdWVyeSkge1xuICAgIF90cmlnZ2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7XG4gICAgICByZXR1cm4gdC5fY3R4ICYmIHQuX2N0eC5xdWVyeSA9PT0gcXVlcnkgJiYgdC5fY3R4LmtpbGwodHJ1ZSwgdHJ1ZSk7XG4gICAgfSk7XG4gIH07XG5cbiAgU2Nyb2xsVHJpZ2dlci5pc0luVmlld3BvcnQgPSBmdW5jdGlvbiBpc0luVmlld3BvcnQoZWxlbWVudCwgcmF0aW8sIGhvcml6b250YWwpIHtcbiAgICB2YXIgYm91bmRzID0gKF9pc1N0cmluZyhlbGVtZW50KSA/IF9nZXRUYXJnZXQoZWxlbWVudCkgOiBlbGVtZW50KS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcbiAgICAgICAgb2Zmc2V0ID0gYm91bmRzW2hvcml6b250YWwgPyBfd2lkdGggOiBfaGVpZ2h0XSAqIHJhdGlvIHx8IDA7XG4gICAgcmV0dXJuIGhvcml6b250YWwgPyBib3VuZHMucmlnaHQgLSBvZmZzZXQgPiAwICYmIGJvdW5kcy5sZWZ0ICsgb2Zmc2V0IDwgX3dpbi5pbm5lcldpZHRoIDogYm91bmRzLmJvdHRvbSAtIG9mZnNldCA+IDAgJiYgYm91bmRzLnRvcCArIG9mZnNldCA8IF93aW4uaW5uZXJIZWlnaHQ7XG4gIH07XG5cbiAgU2Nyb2xsVHJpZ2dlci5wb3NpdGlvbkluVmlld3BvcnQgPSBmdW5jdGlvbiBwb3NpdGlvbkluVmlld3BvcnQoZWxlbWVudCwgcmVmZXJlbmNlUG9pbnQsIGhvcml6b250YWwpIHtcbiAgICBfaXNTdHJpbmcoZWxlbWVudCkgJiYgKGVsZW1lbnQgPSBfZ2V0VGFyZ2V0KGVsZW1lbnQpKTtcbiAgICB2YXIgYm91bmRzID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcbiAgICAgICAgc2l6ZSA9IGJvdW5kc1tob3Jpem9udGFsID8gX3dpZHRoIDogX2hlaWdodF0sXG4gICAgICAgIG9mZnNldCA9IHJlZmVyZW5jZVBvaW50ID09IG51bGwgPyBzaXplIC8gMiA6IHJlZmVyZW5jZVBvaW50IGluIF9rZXl3b3JkcyA/IF9rZXl3b3Jkc1tyZWZlcmVuY2VQb2ludF0gKiBzaXplIDogfnJlZmVyZW5jZVBvaW50LmluZGV4T2YoXCIlXCIpID8gcGFyc2VGbG9hdChyZWZlcmVuY2VQb2ludCkgKiBzaXplIC8gMTAwIDogcGFyc2VGbG9hdChyZWZlcmVuY2VQb2ludCkgfHwgMDtcbiAgICByZXR1cm4gaG9yaXpvbnRhbCA/IChib3VuZHMubGVmdCArIG9mZnNldCkgLyBfd2luLmlubmVyV2lkdGggOiAoYm91bmRzLnRvcCArIG9mZnNldCkgLyBfd2luLmlubmVySGVpZ2h0O1xuICB9O1xuXG4gIFNjcm9sbFRyaWdnZXIua2lsbEFsbCA9IGZ1bmN0aW9uIGtpbGxBbGwoYWxsb3dMaXN0ZW5lcnMpIHtcbiAgICBfdHJpZ2dlcnMuc2xpY2UoMCkuZm9yRWFjaChmdW5jdGlvbiAodCkge1xuICAgICAgcmV0dXJuIHQudmFycy5pZCAhPT0gXCJTY3JvbGxTbW9vdGhlclwiICYmIHQua2lsbCgpO1xuICAgIH0pO1xuXG4gICAgaWYgKGFsbG93TGlzdGVuZXJzICE9PSB0cnVlKSB7XG4gICAgICB2Y
1XIgbGlzdGVuZXJzID0gX2xpc3RlbmVycy5raWxsQWxsIHx8IFtdO1xuICAgICAgX2xpc3RlbmVycyA9IHt9O1xuICAgICAgbGlzdGVuZXJzLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgcmV0dXJuIGYoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gU2Nyb2xsVHJpZ2dlcjtcbn0oKTtcblNjcm9sbFRyaWdnZXIudmVyc2lvbiA9IFwiMy4xMi41XCI7XG5cblNjcm9sbFRyaWdnZXIuc2F2ZVN0eWxlcyA9IGZ1bmN0aW9uICh0YXJnZXRzKSB7XG4gIHJldHVybiB0YXJnZXRzID8gX3RvQXJyYXkodGFyZ2V0cykuZm9yRWFjaChmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgLy8gc2F2ZWQgc3R5bGVzIGFyZSByZWNvcmRlZCBpbiBhIGNvbnNlY3V0aXZlIGFsdGVybmF0aW5nIEFycmF5LCBsaWtlIFtlbGVtZW50LCBjc3NUZXh0LCB0cmFuc2Zvcm0gYXR0cmlidXRlLCBjYWNoZSwgbWF0Y2hNZWRpYSwgLi4uXVxuICAgIGlmICh0YXJnZXQgJiYgdGFyZ2V0LnN0eWxlKSB7XG4gICAgICB2YXIgaSA9IF9zYXZlZFN0eWxlcy5pbmRleE9mKHRhcmdldCk7XG5cbiAgICAgIGkgPj0gMCAmJiBfc2F2ZWRTdHlsZXMuc3BsaWNlKGksIDUpO1xuXG4gICAgICBfc2F2ZWRTdHlsZXMucHVzaCh0YXJnZXQsIHRhcmdldC5zdHlsZS5jc3NUZXh0LCB0YXJnZXQuZ2V0QkJveCAmJiB0YXJnZXQuZ2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIpLCBnc2FwLmNvcmUuZ2V0Q2FjaGUodGFyZ2V0KSwgX2NvbnRleHQoKSk7XG4gICAgfVxuICB9KSA6IF9zYXZlZFN0eWxlcztcbn07XG5cblNjcm9sbFRyaWdnZXIucmV2ZXJ0ID0gZnVuY3Rpb24gKHNvZnQsIG1lZGlhKSB7XG4gIHJldHVybiBfcmV2ZXJ0QWxsKCFzb2Z0LCBtZWRpYSk7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLmNyZWF0ZSA9IGZ1bmN0aW9uICh2YXJzLCBhbmltYXRpb24pIHtcbiAgcmV0dXJuIG5ldyBTY3JvbGxUcmlnZ2VyKHZhcnMsIGFuaW1hdGlvbik7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLnJlZnJlc2ggPSBmdW5jdGlvbiAoc2FmZSkge1xuICByZXR1cm4gc2FmZSA/IF9vblJlc2l6ZSgpIDogKF9jb3JlSW5pdHRlZCB8fCBTY3JvbGxUcmlnZ2VyLnJlZ2lzdGVyKCkpICYmIF9yZWZyZXNoQWxsKHRydWUpO1xufTtcblxuU2Nyb2xsVHJpZ2dlci51cGRhdGUgPSBmdW5jdGlvbiAoZm9yY2UpIHtcbiAgcmV0dXJuICsrX3Njcm9sbGVycy5jYWNoZSAmJiBfdXBkYXRlQWxsKGZvcmNlID09PSB0cnVlID8gMiA6IDApO1xufTtcblxuU2Nyb2xsVHJpZ2dlci5jbGVhclNjcm9sbE1lbW9yeSA9IF9jbGVhclNjcm9sbE1lbW9yeTtcblxuU2Nyb2xsVHJpZ2dlci5tYXhTY3JvbGwgPSBmdW5jdGlvbiAoZWxlbWVudCwgaG9yaXpvbnRhbCkge1xuICByZXR1cm4gX21heFNjcm9sbChlbGVtZW50LCBob3Jpem9udGFsID8gX2hvcml6b250YWwgOiBfdmVydGljYWwpO1xufTtcblxuU2Nyb2xsVHJpZ2dlci5nZXRTY3JvbGxGdW5jID0gZnVuY3Rpb24gKGVsZW1lbnQsIGhvcml6b250YWwpIHtcbiAgcmV0dXJuIF9nZXRTY3JvbGxGdW5jKF9nZXRUYXJnZXQoZWxlbWVudCksIGhvcml6b250YWwgPyBfaG9yaXpvbnRhbCA6IF92ZXJ0aWNhbCk7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLmdldEJ5SWQgPSBmdW5jdGlvbiAoaWQpIHtcbiAgcmV0dXJuIF9pZHNbaWRdO1xufTtcblxuU2Nyb2xsVHJpZ2dlci5nZXRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBfdHJpZ2dlcnMuZmlsdGVyKGZ1bmN0aW9uICh0KSB7XG4gICAgcmV0dXJuIHQudmFycy5pZCAhPT0gXCJTY3JvbGxTbW9vdGhlclwiO1xuICB9KTtcbn07IC8vIGl0J3MgY29tbW9uIGZvciBwZW9wbGUgdG8gU2Nyb2xsVHJpZ2dlci5nZXRBbGwodCA9PiB0LmtpbGwoKSkgb24gcGFnZSByb3V0ZXMsIGZvciBleGFtcGxlLCBhbmQgd2UgZG9uJ3Qgd2FudCBpdCB0byBydWluIHNtb290aCBzY3JvbGxpbmcgYnkga2lsbGluZyB0aGUgbWFpbiBTY3JvbGxTbW9vdGhlciBvbmUuXG5cblxuU2Nyb2xsVHJpZ2dlci5pc1Njcm9sbGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuICEhX2xhc3RTY3JvbGxUaW1lO1xufTtcblxuU2Nyb2xsVHJpZ2dlci5zbmFwRGlyZWN0aW9uYWwgPSBfc25hcERpcmVjdGlvbmFsO1xuXG5TY3JvbGxUcmlnZ2VyLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAodHlwZSwgY2FsbGJhY2spIHtcbiAgdmFyIGEgPSBfbGlzdGVuZXJzW3R5cGVdIHx8IChfbGlzdGVuZXJzW3R5cGVdID0gW10pO1xuICB+YS5pbmRleE9mKGNhbGxiYWNrKSB8fCBhLnB1c2goY2FsbGJhY2spO1xufTtcblxuU2Nyb2xsVHJpZ2dlci5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHR5cGUsIGNhbGxiYWNrKSB7XG4gIHZhciBhID0gX2xpc3RlbmVyc1t0eXBlXSxcbiAgICAgIGkgPSBhICYmIGEuaW5kZXhPZihjYWxsYmFjayk7XG4gIGkgPj0gMCAmJiBhLnNwbGljZShpLCAxKTtcbn07XG5cblNjcm9sbFRyaWdnZXIuYmF0Y2ggPSBmdW5jdGlvbiAodGFyZ2V0cywgdmFycykge1xuICB2YXIgcmVzdWx0ID0gW10sXG4gICAgICB2Y
1XJzQ29weSA9IHt9LFxuICAgICAgaW50ZXJ2YWwgPSB2YXJzLmludGVydmFsIHx8IDAuMDE2LFxuICAgICAgYmF0Y2hNYXggPSB2YXJzLmJhdGNoTWF4IHx8IDFlOSxcbiAgICAgIHByb3h5Q2FsbGJhY2sgPSBmdW5jdGlvbiBwcm94eUNhbGxiYWNrKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGVsZW1lbnRzID0gW10sXG4gICAgICAgIHRyaWdnZXJzID0gW10sXG4gICAgICAgIGRlbGF5ID0gZ3NhcC5kZWxheWVkQ2FsbChpbnRlcnZhbCwgZnVuY3Rpb24gKCkge1xuICAgICAgY2FsbGJhY2soZWxlbWVudHMsIHRyaWdnZXJzKTtcbiAgICAgIGVsZW1lbnRzID0gW107XG4gICAgICB0cmlnZ2VycyA9IFtdO1xuICAgIH0pLnBhdXNlKCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzZWxmKSB7XG4gICAgICBlbGVtZW50cy5sZW5ndGggfHwgZGVsYXkucmVzdGFydCh0cnVlKTtcbiAgICAgIGVsZW1lbnRzLnB1c2goc2VsZi50cmlnZ2VyKTtcbiAgICAgIHRyaWdnZXJzLnB1c2goc2VsZik7XG4gICAgICBiYXRjaE1heCA8PSBlbGVtZW50cy5sZW5ndGggJiYgZGVsYXkucHJvZ3Jlc3MoMSk7XG4gICAgfTtcbiAgfSxcbiAgICAgIHA7XG5cbiAgZm9yIChwIGluIHZhcnMpIHtcbiAgICB2YXJzQ29weVtwXSA9IHAuc3Vic3RyKDAsIDIpID09PSBcIm9uXCIgJiYgX2lzRnVuY3Rpb24odmFyc1twXSkgJiYgcCAhPT0gXCJvblJlZnJlc2hJbml0XCIgPyBwcm94eUNhbGxiYWNrKHAsIHZhcnNbcF0pIDogdmFyc1twXTtcbiAgfVxuXG4gIGlmIChfaXNGdW5jdGlvbihiYXRjaE1heCkpIHtcbiAgICBiYXRjaE1heCA9IGJhdGNoTWF4KCk7XG5cbiAgICBfYWRkTGlzdGVuZXIoU2Nyb2xsVHJpZ2dlciwgXCJyZWZyZXNoXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBiYXRjaE1heCA9IHZhcnMuYmF0Y2hNYXgoKTtcbiAgICB9KTtcbiAgfVxuXG4gIF90b0FycmF5KHRhcmdldHMpLmZvckVhY2goZnVuY3Rpb24gKHRhcmdldCkge1xuICAgIHZhciBjb25maWcgPSB7fTtcblxuICAgIGZvciAocCBpbiB2YXJzQ29weSkge1xuICAgICAgY29uZmlnW3BdID0gdmFyc0NvcHlbcF07XG4gICAgfVxuXG4gICAgY29uZmlnLnRyaWdnZXIgPSB0YXJnZXQ7XG4gICAgcmVzdWx0LnB1c2goU2Nyb2xsVHJpZ2dlci5jcmVhdGUoY29uZmlnKSk7XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHQ7XG59OyAvLyB0byByZWR1Y2UgZmlsZSBzaXplLiBjbGFtcHMgdGhlIHNjcm9sbCBhbmQgYWxzbyByZXR1cm5zIGEgZHVyYXRpb24gbXVsdGlwbGllciBzbyB0aGF0IGlmIHRoZSBzY3JvbGwgZ2V0cyBjaG9wcGVkIHNob3J0ZXIsIHRoZSBkdXJhdGlvbiBnZXRzIGN1cnRhaWxlZCBhcyB3ZWxsIChvdGhlcndpc2UgaWYgeW91J3JlIHZlcnkgY2xvc2UgdG8gdGhlIHRvcCBvZiB0aGUgcGFnZSwgZm9yIGV4YW1wbGUsIGFuZCBzd2lwZSB1cCByZWFsbHkgZmFzdCwgaXQnbGwgc3VkZGVubHkgc2xvdyBkb3duIGFuZCB0YWtlIGEgbG9uZyB0aW1lIHRvIHJlYWNoIHRoZSB0b3ApLlxuXG5cbnZhciBfY2xhbXBTY3JvbGxBbmRHZXREdXJhdGlvbk11bHRpcGxpZXIgPSBmdW5jdGlvbiBfY2xhbXBTY3JvbGxBbmRHZXREdXJhdGlvbk11bHRpcGxpZXIoc2Nyb2xsRnVuYywgY3VycmVudCwgZW5kLCBtYXgpIHtcbiAgY3VycmVudCA+IG1heCA/IHNjcm9sbEZ1bmMobWF4KSA6IGN1cnJlbnQgPCAwICYmIHNjcm9sbEZ1bmMoMCk7XG4gIHJldHVybiBlbmQgPiBtYXggPyAobWF4IC0gY3VycmVudCkgLyAoZW5kIC0gY3VycmVudCkgOiBlbmQgPCAwID8gY3VycmVudCAvIChjdXJyZW50IC0gZW5kKSA6IDE7XG59LFxuICAgIF9hbGxvd05hdGl2ZVBhbm5pbmcgPSBmdW5jdGlvbiBfYWxsb3dOYXRpdmVQYW5uaW5nKHRhcmdldCwgZGlyZWN0aW9uKSB7XG4gIGlmIChkaXJlY3Rpb24gPT09IHRydWUpIHtcbiAgICB0YXJnZXQuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJ0b3VjaC1hY3Rpb25cIik7XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0LnN0eWxlLnRvdWNoQWN0aW9uID0gZGlyZWN0aW9uID09PSB0cnVlID8gXCJhdXRvXCIgOiBkaXJlY3Rpb24gPyBcInBhbi1cIiArIGRpcmVjdGlvbiArIChPYnNlcnZlci5pc1RvdWNoID8gXCIgcGluY2gtem9vbVwiIDogXCJcIikgOiBcIm5vbmVcIjsgLy8gbm90ZTogRmlyZWZveCBkb2Vzbid0IHN1cHBvcnQgaXQgcGluY2gtem9vbSBwcm9wZXJseSwgYXQgbGVhc3QgaW4gYWRkaXRpb24gdG8gYSBwYW4teCBvciBwYW4teS5cbiAgfVxuXG4gIHRhcmdldCA9PT0gX2RvY0VsICYmIF9hbGxvd05hdGl2ZVBhbm5pbmcoX2JvZHksIGRpcmVjdGlvbik7XG59LFxuICAgIF9vdmVyZmxvdyA9IHtcbiAgYXV0bzogMSxcbiAgc2Nyb2xsOiAxXG59LFxuICAgIF9uZXN0ZWRTY3JvbGwgPSBmdW5jdGlvbiBfbmVzdGVkU2Nyb2xsKF9yZWY1KSB7XG4gIHZhciBldmVudCA9IF9yZWY1LmV2ZW50LFxuICAgICAgdGFyZ2V0ID0gX3JlZjUudGFyZ2V0LFxuICAgICAgYXhpcyA9IF9yZWY1LmF4aXM7XG5cbiAgdmFyIG5vZGUgPSAoZXZlbnQuY2hhbmdlZFRvdWNoZXMgPyBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSA6IGV2ZW50KS50YXJnZXQsXG4gICAgICBjYWNoZSA9IG5vZGUuX2dzYXAgfHwgZ3NhcC5jb3JlLmdldENhY2hlKG5vZGUpLFxuICAgICAgdGltZSA9IF9nZXRUaW1lKCksXG4gICAgICBjcztcblxuICBpZiAoIWNhY2hlLl9pc1Njcm9sbFQgfHwgdGltZSAtIGNhY2hlLl9pc1Njcm9sbFQgPiAyMDAwKSB7XG4gICAgLy8gY2FjaGUgZm9yIDIgc2Vjb25kcyB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLlxuICAgIHdoaWxlIChub2RlICYmIG5vZGUgIT09IF9ib2R5ICYmIChub2RlLnNjcm9sbEhlaWdodCA8PSBub2RlLmNsaWVudEhlaWdodCAmJiBub2RlLnNjcm9sbFdpZHR
1oIDw9IG5vZGUuY2xpZW50V2lkdGggfHwgIShfb3ZlcmZsb3dbKGNzID0gX2dldENvbXB1dGVkU3R5bGUobm9kZSkpLm92ZXJmbG93WV0gfHwgX292ZXJmbG93W2NzLm92ZXJmbG93WF0pKSkge1xuICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICB9XG5cbiAgICBjYWNoZS5faXNTY3JvbGwgPSBub2RlICYmIG5vZGUgIT09IHRhcmdldCAmJiAhX2lzVmlld3BvcnQobm9kZSkgJiYgKF9vdmVyZmxvd1soY3MgPSBfZ2V0Q29tcHV0ZWRTdHlsZShub2RlKSkub3ZlcmZsb3dZXSB8fCBfb3ZlcmZsb3dbY3Mub3ZlcmZsb3dYXSk7XG4gICAgY2FjaGUuX2lzU2Nyb2xsVCA9IHRpbWU7XG4gIH1cblxuICBpZiAoY2FjaGUuX2lzU2Nyb2xsIHx8IGF4aXMgPT09IFwieFwiKSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZXZlbnQuX2dzYXBBbGxvdyA9IHRydWU7XG4gIH1cbn0sXG4gICAgLy8gY2FwdHVyZSBldmVudHMgb24gc2Nyb2xsYWJsZSBlbGVtZW50cyBJTlNJREUgdGhlIDxib2R5PiBhbmQgYWxsb3cgdGhvc2UgYnkgY2FsbGluZyBzdG9wUHJvcGFnYXRpb24oKSB3aGVuIHdlIGZpbmQgYSBzY3JvbGxhYmxlIGFuY2VzdG9yXG5faW5wdXRPYnNlcnZlciA9IGZ1bmN0aW9uIF9pbnB1dE9ic2VydmVyKHRhcmdldCwgdHlwZSwgaW5wdXRzLCBuZXN0ZWQpIHtcbiAgcmV0dXJuIE9ic2VydmVyLmNyZWF0ZSh7XG4gICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgY2FwdHVyZTogdHJ1ZSxcbiAgICBkZWJvdW5jZTogZmFsc2UsXG4gICAgbG9ja0F4aXM6IHRydWUsXG4gICAgdHlwZTogdHlwZSxcbiAgICBvbldoZWVsOiBuZXN0ZWQgPSBuZXN0ZWQgJiYgX25lc3RlZFNjcm9sbCxcbiAgICBvblByZXNzOiBuZXN0ZWQsXG4gICAgb25EcmFnOiBuZXN0ZWQsXG4gICAgb25TY3JvbGw6IG5lc3RlZCxcbiAgICBvbkVuYWJsZTogZnVuY3Rpb24gb25FbmFibGUoKSB7XG4gICAgICByZXR1cm4gaW5wdXRzICYmIF9hZGRMaXN0ZW5lcihfZG9jLCBPYnNlcnZlci5ldmVudFR5cGVzWzBdLCBfY2FwdHVyZUlucHV0cywgZmFsc2UsIHRydWUpO1xuICAgIH0sXG4gICAgb25EaXNhYmxlOiBmdW5jdGlvbiBvbkRpc2FibGUoKSB7XG4gICAgICByZXR1cm4gX3JlbW92ZUxpc3RlbmVyKF9kb2MsIE9ic2VydmVyLmV2ZW50VHlwZXNbMF0sIF9jYXB0dXJlSW5wdXRzLCB0cnVlKTtcbiAgICB9XG4gIH0pO1xufSxcbiAgICBfaW5wdXRFeHAgPSAvKGlucHV0fGxhYmVsfHNlbGVjdHx0ZXh0YXJlYSkvaSxcbiAgICBfaW5wdXRJc0ZvY3VzZWQsXG4gICAgX2NhcHR1cmVJbnB1dHMgPSBmdW5jdGlvbiBfY2FwdHVyZUlucHV0cyhlKSB7XG4gIHZhciBpc0lucHV0ID0gX2lucHV0RXhwLnRlc3QoZS50YXJnZXQudGFnTmFtZSk7XG5cbiAgaWYgKGlzSW5wdXQgfHwgX2lucHV0SXNGb2N1c2VkKSB7XG4gICAgZS5fZ3NhcEFsbG93ID0gdHJ1ZTtcbiAgICBfaW5wdXRJc0ZvY3VzZWQgPSBpc0lucHV0O1xuICB9XG59LFxuICAgIF9nZXRTY3JvbGxOb3JtYWxpemVyID0gZnVuY3Rpb24gX2dldFNjcm9sbE5vcm1hbGl6ZXIodmFycykge1xuICBfaXNPYmplY3QodmFycykgfHwgKHZhcnMgPSB7fSk7XG4gIHZhcnMucHJldmVudERlZmF1bHQgPSB2YXJzLmlzTm9ybWFsaXplciA9IHZhcnMuYWxsb3dDbGlja3MgPSB0cnVlO1xuICB2YXJzLnR5cGUgfHwgKHZhcnMudHlwZSA9IFwid2hlZWwsdG91Y2hcIik7XG4gIHZhcnMuZGVib3VuY2UgPSAhIXZhcnMuZGVib3VuY2U7XG4gIHZhcnMuaWQgPSB2YXJzLmlkIHx8IFwibm9ybWFsaXplclwiO1xuXG4gIHZhciBfdmFyczIgPSB2YXJzLFxuICAgICAgbm9ybWFsaXplU2Nyb2xsWCA9IF92YXJzMi5ub3JtYWxpemVTY3JvbGxYLFxuICAgICAgbW9tZW50dW0gPSBfdmFyczIubW9tZW50dW0sXG4gICAgICBhbGxvd05lc3RlZFNjcm9sbCA9I
1F92YXJzMi5hbGxvd05lc3RlZFNjcm9sbCxcbiAgICAgIG9uUmVsZWFzZSA9IF92YXJzMi5vblJlbGVhc2UsXG4gICAgICBzZWxmLFxuICAgICAgbWF4WSxcbiAgICAgIHRhcmdldCA9IF9nZXRUYXJnZXQodmFycy50YXJnZXQpIHx8IF9kb2NFbCxcbiAgICAgIHNtb290aGVyID0gZ3NhcC5jb3JlLmdsb2JhbHMoKS5TY3JvbGxTbW9vdGhlcixcbiAgICAgIHNtb290aGVySW5zdGFuY2UgPSBzbW9vdGhlciAmJiBzbW9vdGhlci5nZXQoKSxcbiAgICAgIGNvbnRlbnQgPSBfZml4SU9TQnVnICYmICh2YXJzLmNvbnRlbnQgJiYgX2dldFRhcmdldCh2YXJzLmNvbnRlbnQpIHx8IHNtb290aGVySW5zdGFuY2UgJiYgdmFycy5jb250ZW50ICE9PSBmYWxzZSAmJiAhc21vb3RoZXJJbnN0YW5jZS5zbW9vdGgoKSAmJiBzbW9vdGhlckluc3RhbmNlLmNvbnRlbnQoKSksXG4gICAgICBzY3JvbGxGdW5jWSA9IF9nZXRTY3JvbGxGdW5jKHRhcmdldCwgX3ZlcnRpY2FsKSxcbiAgICAgIHNjcm9sbEZ1bmNYID0gX2dldFNjcm9sbEZ1bmModGFyZ2V0LCBfaG9yaXpvbnRhbCksXG4gICAgICBzY2FsZSA9IDEsXG4gICAgICBpbml0aWFsU2NhbGUgPSAoT2JzZXJ2ZXIuaXNUb3VjaCAmJiBfd2luLnZpc3VhbFZpZXdwb3J0ID8gX3dpbi52aXN1YWxWaWV3cG9ydC5zY2FsZSAqIF93aW4udmlzdWFsVmlld3BvcnQud2lkdGggOiBfd2luLm91dGVyV2lkdGgpIC8gX3dpbi5pbm5lcldpZHRoLFxuICAgICAgd2hlZWxSZWZyZXNoID0gMCxcbiAgICAgIHJlc29sdmVNb21lbnR1bUR1cmF0aW9uID0gX2lzRnVuY3Rpb24obW9tZW50dW0pID8gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBtb21lbnR1bShzZWxmKTtcbiAgfSA6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbW9tZW50dW0gfHwgMi44O1xuICB9LFxuICAgICAgbGFzdFJlZnJlc2hJRCxcbiAgICAgIHNraXBUb3VjaE1vdmUsXG4gICAgICBpbnB1dE9ic2VydmVyID0gX2lucHV0T2JzZXJ2ZXIodGFyZ2V0LCB2YXJzLnR5cGUsIHRydWUsIGFsbG93TmVzdGVkU2Nyb2xsKSxcbiAgICAgIHJlc3VtZVRvdWNoTW92ZSA9IGZ1bmN0aW9uIHJlc3VtZVRvdWNoTW92ZSgpIHtcbiAgICByZXR1cm4gc2tpcFRvdWNoTW92ZSA9IGZhbHNlO1xuICB9LFxuICAgICAgc2Nyb2xsQ2xhbXBYID0gX3Bhc3NUaHJvdWdoLFxuICAgICAgc2Nyb2xsQ2xhbXBZID0gX3Bhc3NUaHJvdWdoLFxuICAgICAgdXBkYXRlQ2xhbXBzID0gZnVuY3Rpb24gdXBkYXRlQ2xhbXBzKCkge1xuICAgIG1heFkgPSBfbWF4U2Nyb2xsKHRhcmdldCwgX3ZlcnRpY2FsKTtcbiAgICBzY3JvbGxDbGFtcFkgPSBfY2xhbXAoX2ZpeElPU0J1ZyA/IDEgOiAwLCBtYXhZKTtcbiAgICBub3JtYWxpemVTY3JvbGxYICYmIChzY3JvbGxDbGFtcFggPSBfY2xhbXAoMCwgX21heFNjcm9sbCh0YXJnZXQsIF9ob3Jpem9udGFsKSkpO1xuICAgIGxhc3RSZWZyZXNoSUQgPSBfcmVmcmVzaElEO1xuICB9LFxuICAgICAgcmVtb3ZlQ29udGVudE9mZnNldCA9IGZ1bmN0aW9uIHJlbW92ZUNvbnRlbnRPZmZzZXQoKSB7XG4gICAgY29udGVudC5fZ3NhcC55ID0gX3JvdW5kKHBhcnNlRmxvYXQoY29udGVudC5fZ3NhcC55KSArIHNjcm9sbEZ1bmNZLm9mZnNldCkgKyBcInB4XCI7XG4gICAgY29udGVudC5zdHlsZS50cmFuc2Zvcm0gPSBcIm1hdHJpeDNkKDEsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIFwiICsgcGFyc2VGbG9hdChjb250ZW50Ll9nc2FwLnkpICsgXCIsIDAsIDEpXCI7XG4gICAgc2Nyb2xsRnVuY1kub2Zmc2V0ID0gc2Nyb2xsRnVuY1kuY2FjaGVJRCA9IDA7XG4gIH0sXG4gICAgICBpZ25vcmVEcmFnID0gZnVuY3Rpb24gaWdub3JlRHJhZygpIHtcbiAgICBpZiAoc2tpcFRvdWNoTW92ZSkge1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHJlc3VtZVRvdWNoTW92ZSk7XG5cbiAgICAgIHZhciBvZmZzZXQgPSBfcm91bmQoc2VsZi5kZWx0YVkgLyAyKSxcbiAgICAgICAgICBzY3JvbGwgPSBzY3JvbGxDbGFtcFkoc2Nyb2xsRnVuY1kudiAtIG9mZnNldCk7XG5cbiAgICAgIGlmIChjb250ZW50ICYmIHNjcm9sbCAhPT0gc2Nyb2xsRnVuY1kudiArIHNjcm9sbEZ1bmNZLm9mZnNldCkge1xuICAgICAgICBzY3JvbGxGdW5jWS5vZmZzZXQgPSBzY3JvbGwgLSBzY3JvbGxGdW5jWS52O1xuXG4gICAgICAgIHZhciB5ID0gX3JvdW5kKChwYXJzZUZsb2F0KGNvbnRlbnQgJiYgY29udGVudC5fZ3NhcC55KSB8fCAwKSAtIHNjcm9sbEZ1bmNZLm9mZnNldCk7XG5cbiAgICAgICAgY29udGVudC5zdHlsZS50cmFuc2Zvcm0gPSBcIm1hdHJpeDNkKDEsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIFwiICsgeSArIFwiLCAwLCAxKVwiO1xuICAgICAgICBjb250ZW50Ll9nc2FwLnkgPSB5ICsgXCJweFwiO1xuICAgICAgICBzY3JvbGxGdW5jWS5jYWNoZUlEID0gX3Njcm9sbGVycy5jYWNoZTtcblxuICAgICAgICBfdXBkYXRlQWxsKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHNjcm9sbEZ1bmNZLm9mZnNldCAmJiByZW1vdmVDb250ZW50T2Zmc2V0KCk7XG4gICAgc2tpcFRvdWNoTW92ZSA9IHRydWU7XG4gIH0sXG4gICAgICB0d2VlbixcbiAgICAgIHN0YXJ0U2Nyb2xsWCxcbiAgICAgIHN0YXJ0U2Nyb2xsWSxcbiAgICAgIG9uU3RvcERlbGF5ZWRDYWxsLFxuICAgICAgb25SZXNpemUgPSBmdW5jdGlvbiBvblJlc2l6ZSgpIHtcbiAgICAvLyBpZiB0aGUgd2luZG93IHJlc2l6ZXMsIGxpa2Ugb24gYW4gaVBob25lIHdoaWNoIEFwcGxlIEZPUkNFUyB0aGUgYWRkcmVzcyBiYXIgdG8gc2hvdy9oaWRlIGV2ZW4gaWYgd2UgZXZlbnQucHJldmVudERlZmF1bHQoKSwgaXQgbWF5IGJlIHNjcm9sbGluZyB0b28gZmFyIG5vdyB0aGF0IHRoZSBhZGRyZXNzIGJhciBpcyBzaG93aW5nLCBzbyB3ZSBtdXN0IGR5bmFtaWNhbGx5IGFkanVzdCB0aGUgbW9tZW50dW0gdHdlZW4uXG4gICAgdXBkYXRlQ2xhbXBzKCk7XG5cbiAgICBpZiAodHdlZW4uaXNBY3RpdmUoKSAmJiB0d2Vlbi52YXJzLnNjcm9sbFkgPiBtYXhZKSB7XG4gICAgICBzY3JvbGxGdW5jWSgpID4gbWF4WSA/IHR3ZWVuLnByb2dyZXNzKDEpICYmIHNjcm9sbEZ1bmNZKG1heFkpIDogdHdlZW4ucmVzZXRUbyhcInNjcm9sbFlcIiwgbWF4WSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnRlbnQgJiYgZ3NhcC5zZXQoY29udGVudCwge1xuICAgIHk6IFwiKz0wXCJcbiAgfSk7IC8vIHRvIGVuc3VyZSB0aGVyZSdzIGEgY2FjaGUgKGVsZW1lbnQuX2dzYXApXG5cbiAgdmFycy5pZ25vcmVDaGVjayA9IGZ1bmN0aW9uIChlKSB7XG4gICAgcmV0dXJuIF9maXhJT1NCdWcgJiYgZS50eXBlID09PSBcInRvdWNobW92ZVwiICYmIGlnbm9yZURyYWcoZSkgfHwgc2NhbGUgPiAxLjA1ICYmIGUudHlwZSAhPT0gXCJ0b3VjaHN0YXJ0XCIgfHwgc2VsZi5pc0dlc3R1cmluZyB8fCBlLnRvdWNoZXMgJiYgZS50b3VjaGVzLmxlbmd0aCA+IDE7XG4gIH07XG5cbiAgdmFycy5vblByZXNzID0gZnVuY3Rpb24gKCkge1xuICAgIHNraXBUb3VjaE1vdmUgPSBmYWxzZTtcbiAgICB2YXIgcHJldlNjYWxlID0gc2NhbGU7XG4gICAgc2NhbGUgPSBfcm91bmQoKF93aW4udmlzdWFsVmlld3BvcnQgJiYgX3dpbi52aXN1YWxWaWV3cG9ydC5zY2FsZSB8fCAxKSAvIGluaXRpYWxTY2FsZSk7XG4gICAgdHdlZW4ucGF1c2UoKTtcbiAgICBwcmV2U2NhbGUgIT09IHNjYWxlICYmIF9hbGxvd05hdGl2ZVBhbm5pbmcodGFyZ2V0LCBzY2FsZSA+IDEuMDEgPyB0cnVlIDogbm9ybWFsaXplU2Nyb2xsWCA/IGZhbHNlIDogXCJ4XCIpO1xuICAgIHN0YXJ0U2Nyb2xsWCA9IHNjcm9sbEZ1bmNYKCk7XG4gICAgc3RhcnRTY3JvbGxZID0gc2Nyb2xsRnVuY1koKTtcbiAgICB1cGRhdGVDbGFtcHMoKTtcbiAgICBsYXN0UmVmcmVzaElEID0gX3JlZnJlc2hJRDtcbiAgfTtcblxuICB2Y
1XJzLm9uUmVsZWFzZSA9IHZhcnMub25HZXN0dXJlU3RhcnQgPSBmdW5jdGlvbiAoc2VsZiwgd2FzRHJhZ2dpbmcpIHtcbiAgICBzY3JvbGxGdW5jWS5vZmZzZXQgJiYgcmVtb3ZlQ29udGVudE9mZnNldCgpO1xuXG4gICAgaWYgKCF3YXNEcmFnZ2luZykge1xuICAgICAgb25TdG9wRGVsYXllZENhbGwucmVzdGFydCh0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3Njcm9sbGVycy5jYWNoZSsrOyAvLyBtYWtlIHN1cmUgd2UncmUgcHVsbGluZyB0aGUgbm9uLWNhY2hlZCB2YWx1ZVxuICAgICAgLy8gYWx0ZXJuYXRlIGFsZ29yaXRobTogZHVyWCA9IE1hdGgubWluKDYsIE1hdGguYWJzKHNlbGYudmVsb2NpdHlYIC8gODAwKSksXHRkdXIgPSBNYXRoLm1heChkdXJYLCBNYXRoLm1pbig2LCBNYXRoLmFicyhzZWxmLnZlbG9jaXR5WSAvIDgwMCkpKTsgZHVyID0gZHVyICogKDAuNCArICgxIC0gX3Bvd2VyNEluKGR1ciAvIDYpKSAqIDAuNikpICogKG1vbWVudHVtU3BlZWQgfHwgMSlcblxuICAgICAgdmFyIGR1ciA9IHJlc29sdmVNb21lbnR1bUR1cmF0aW9uKCksXG4gICAgICAgICAgY3VycmVudFNjcm9sbCxcbiAgICAgICAgICBlbmRTY3JvbGw7XG5cbiAgICAgIGlmIChub3JtYWxpemVTY3JvbGxYKSB7XG4gICAgICAgIGN1cnJlbnRTY3JvbGwgPSBzY3JvbGxGdW5jWCgpO1xuICAgICAgICBlbmRTY3JvbGwgPSBjdXJyZW50U2Nyb2xsICsgZHVyICogMC4wNSAqIC1zZWxmLnZlbG9jaXR5WCAvIDAuMjI3OyAvLyB0aGUgY29uc3RhbnQgLjIyNyBpcyBmcm9tIHBvd2VyNCgwLjA1KS4gdmVsb2NpdHkgaXMgaW52ZXJ0ZWQgYmVjYXVzZSBzY3JvbGxpbmcgZ29lcyBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uLlxuXG4gICAgICAgIGR1ciAqPSBfY2xhbXBTY3JvbGxBbmRHZXREdXJhdGlvbk11bHRpcGxpZXIoc2Nyb2xsRnVuY1gsIGN1cnJlbnRTY3JvbGwsIGVuZFNjcm9sbCwgX21heFNjcm9sbCh0YXJnZXQsIF9ob3Jpem9udGFsKSk7XG4gICAgICAgIHR3ZWVuLnZhcnMuc2Nyb2xsWCA9IHNjcm9sbENsYW1wWChlbmRTY3JvbGwpO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50U2Nyb2xsID0gc2Nyb2xsRnVuY1koKTtcbiAgICAgIGVuZFNjcm9sbCA9IGN1cnJlbnRTY3JvbGwgKyBkdXIgKiAwLjA1ICogLXNlbGYudmVsb2NpdHlZIC8gMC4yMjc7IC8vIHRoZSBjb25zdGFudCAuMjI3IGlzIGZyb20gcG93ZXI0KDAuMDUpXG5cbiAgICAgIGR1ciAqPSBfY2xhbXBTY3JvbGxBbmRHZXREdXJhdGlvbk11bHRpcGxpZXIoc2Nyb2xsRnVuY1ksIGN1cnJlbnRTY3JvbGwsIGVuZFNjcm9sbCwgX21heFNjcm9sbCh0YXJnZXQsIF92ZXJ0aWNhbCkpO1xuICAgICAgdHdlZW4udmFycy5zY3JvbGxZID0gc2Nyb2xsQ2xhbXBZKGVuZFNjcm9sbCk7XG4gICAgICB0d2Vlbi5pbnZhbGlkYXRlKCkuZHVyYXRpb24oZHVyKS5wbGF5KDAuMDEpO1xuXG4gICAgICBpZiAoX2ZpeElPU0J1ZyAmJiB0d2Vlbi52YXJzLnNjcm9sbFkgPj0gbWF4WSB8fCBjdXJyZW50U2Nyb2xsID49IG1heFkgLSAxKSB7XG4gICAgICAgIC8vIGlPUyBidWc6IGl0J2xsIHNob3cgdGhlIGFkZHJlc3MgYmFyIGJ1dCBOT1QgZmlyZSB0aGUgd2luZG93IFwicmVzaXplXCIgZXZlbnQgdW50aWwgdGhlIGFuaW1hdGlvbiBpcyBkb25lIGJ1dCB3ZSBtdXN0IHByb3RlY3QgYWdhaW5zdCBvdmVyc2hvb3Qgc28gd2UgbGV2ZXJhZ2UgYW4gb25VcGRhdGUgdG8gZG8gc28uXG4gICAgICAgIGdzYXAudG8oe30sIHtcbiAgICAgICAgICBvblVwZGF0ZTogb25SZXNpemUsXG4gICAgICAgICAgZHVyYXRpb246IGR1clxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBvblJlbGVhc2UgJiYgb25SZWxlYXNlKHNlbGYpO1xuICB9O1xuXG4gIHZhcnMub25XaGVlbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0d2Vlbi5fdHMgJiYgdHdlZW4ucGF1c2UoKTtcblxuICAgIGlmIChfZ2V0VGltZSgpIC0gd2hlZWxSZWZyZXNoID4gMTAwMCkge1xuICAgICAgLy8gYWZ0ZXIgMSBzZWNvbmQsIHJlZnJlc2ggdGhlIGNsYW1wcyBvdGhlcndpc2UgdGhhdCdsbCBvbmx5IGhhcHBlbiB3aGVuIFNjcm9sbFRyaWdnZXIucmVmcmVzaCgpIGlzIGNhbGxlZCBvciBmb3IgdG91Y2gtc2Nyb2xsaW5nLlxuICAgICAgbGFzdFJlZnJlc2hJRCA9IDA7XG4gICAgICB3aGVlbFJlZnJlc2ggPSBfZ2V0VGltZSgpO1xuICAgIH1cbiAgfTtcblxuICB2YXJzLm9uQ2hhbmdlID0gZnVuY3Rpb24gKHNlbGYsIGR4LCBkeSwgeEFycmF5LCB5QXJyYXkpIHtcbiAgICBfcmVmcmVzaElEICE9PSBsYXN0UmVmcmVzaElEICYmIHVwZGF0ZUNsYW1wcygpO1xuICAgIGR4ICYmIG5vcm1hbGl6ZVNjcm9sbFggJiYgc2Nyb2xsRnVuY1goc2Nyb2xsQ2xhbXBYKHhBcnJheVsyXSA9PT0gZHggPyBzdGFydFNjcm9sbFggKyAoc2VsZi5zdGFydFggLSBzZWxmLngpIDogc2Nyb2xsRnVuY1goKSArIGR4IC0geEFycmF5WzFdKSk7IC8vIGZvciBtb3JlIHByZWNpc2lvbiwgd2UgdHJhY2sgcG9pbnRlci90b3VjaCBtb3ZlbWVudCBmcm9tIHRoZSBzdGFydCwgb3RoZXJ3aXNlIGl0J2xsIGRyaWZ0LlxuXG4gICAgaWYgKGR5KSB7XG4gICAgICBzY3JvbGxGdW5jWS5vZmZzZXQgJiYgcmVtb3ZlQ29udGVudE9mZnNldCgpO1xuICAgICAgdmFyIGlzVG91Y2ggPSB5QXJyYXlbMl0gPT09IGR5LFxuICAgICAgICAgIHkgPSBpc1RvdWNoID8gc3RhcnRTY3JvbGxZICsgc2VsZi5zdGFydFkgLSBzZWxmLnkgOiBzY3JvbGxGdW5jWSgpICsgZHkgLSB5QXJyYXlbMV0sXG4gICAgICAgICAgeUNsYW1wZWQgPSBzY3JvbGxDbGFtcFkoeSk7XG4gICAgICBpc1RvdWNoICYmIHkgIT09IHlDbGFtcGVkICYmIChzdGFydFNjcm9sbFkgKz0geUNsYW1wZWQgLSB5KTtcbiAgICAgIHNjcm9sbEZ1bmNZKHlDbGFtcGVkKTtcbiAgICB9XG5cbiAgICAoZHkgfHwgZHgpICYmIF91cGRhdGVBbGwoKTtcbiAgfTtcblxuICB2YXJzLm9uRW5hYmxlID0gZnVuY3Rpb24gKCkge1xuICAgIF9hbGxvd05hdGl2ZVBhbm5pbmcodGFyZ2V0LCBub3JtYWxpemVTY3JvbGxYID8gZmFsc2UgOiBcInhcIik7XG5cbiAgICBTY3JvbGxUcmlnZ2VyLmFkZEV2ZW50TGlzdGVuZXIoXCJyZWZyZXNoXCIsIG9uUmVzaXplKTtcblxuICAgIF9hZGRMaXN0ZW5lcihfd2luLCBcInJlc2l6ZVwiLCBvblJlc2l6ZSk7XG5cbiAgICBpZiAoc2Nyb2xsRnVuY1kuc21vb3RoKSB7XG4gICAgICBzY3JvbGxGdW5jWS50YXJnZXQuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSBcImF1dG9cIjtcbiAgICAgIHNjcm9sbEZ1bmNZLnNtb290aCA9IHNjcm9sbEZ1bmNYLnNtb290aCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlucHV0T2JzZXJ2ZXIuZW5hYmxlKCk7XG4gIH07XG5cbiAgdmFycy5vbkRpc2FibGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgX2FsbG93TmF0aXZlUGFubmluZyh0YXJnZXQsIHRydWUpO1xuXG4gICAgX3JlbW92ZUxpc3RlbmVyKF93aW4sIFwicmVzaXplXCIsIG9uUmVzaXplKTtcblxuICAgIFNjcm9sbFRyaWdnZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInJlZnJlc2hcIiwgb25SZXNpemUpO1xuICAgIGlucHV0T2JzZXJ2ZXIua2lsbCgpO1xuICB9O1xuXG4gIHZhcnMubG9ja0F4aXMgPSB2YXJzLmxvY2tBeGlzICE9PSBmYWxzZTtcbiAgc2VsZiA9IG5ldyBPYnNlcnZlcih2YXJzKTtcbiAgc2VsZi5pT1MgPSBfZml4SU9TQnVnOyAvLyB1c2VkIGluIHRoZSBPYnNlcnZlciBnZXRDYWNoZWRTY3JvbGwoKSBmdW5jdGlvbiB0byB3b3JrIGFyb3VuZCBhbiBpT1MgYnVnIHRoYXQgd3JlYWtzIGhhdm9jIHdpdGggVG91Y2hFdmVudC5jbGllbnRZIGlmIHdlIGFsbG93IHNjcm9sbCB0byBnbyBhbGwgdGhlIHdheSBiYWNrIHRvIDAuXG5cbiAgX2ZpeElPU0J1ZyAmJiAhc2Nyb2xsRnVuY1koKSAmJiBzY3JvbGxGdW5jWSgxKTsgLy8gaU9TIGJ1ZyBjYXVzZXMgZXZlbnQuY2xpZW50WSB2YWx1ZXMgdG8gZnJlYWsgb3V0ICh3aWxkbHkgaW5hY2N1cmF0ZSkgaWYgdGhlIHNjcm9sbCBwb3NpdGlvbiBpcyBleGFjdGx5IDAuXG5cbiAgX2ZpeElPU0J1ZyAmJiBnc2FwLnRpY2tlci5hZGQoX3Bhc3NUaHJvdWdoKTsgLy8gcHJldmVudCB0aGUgdGlja2VyIGZyb20gc2xlZXBpbmdcblxuICBvblN0b3BEZWxheWVkQ2FsbCA9IHNlbGYuX2RjO1xuICB0d2VlbiA9IGdzYXAudG8oc2VsZiwge1xuICAgIGVhc2U6IFwicG93ZXI0XCIsXG4gICAgcGF1c2VkOiB0cnVlLFxuICAgIGluaGVyaXQ6IGZhbHNlLFxuICAgIHNjcm9sbFg6IG5vcm1hbGl6ZVNjcm9sbFggPyBcIis9MC4xXCIgOiBcIis9MFwiLFxuICAgIHNjcm9sbFk6IFwiKz0wLjFcIixcbiAgICBtb2RpZmllcnM6IHtcbiAgICAgIHNjcm9sbFk6IF9pbnRlcnJ1cHRpb25UcmFja2VyKHNjcm9sbEZ1bmNZLCBzY3JvbGxGdW5jWSgpLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgI
1HJldHVybiB0d2Vlbi5wYXVzZSgpO1xuICAgICAgfSlcbiAgICB9LFxuICAgIG9uVXBkYXRlOiBfdXBkYXRlQWxsLFxuICAgIG9uQ29tcGxldGU6IG9uU3RvcERlbGF5ZWRDYWxsLnZhcnMub25Db21wbGV0ZVxuICB9KTsgLy8gd2UgbmVlZCB0aGUgbW9kaWZpZXIgdG8gc2Vuc2UgaWYgdGhlIHNjcm9sbCBwb3NpdGlvbiBpcyBhbHRlcmVkIG91dHNpZGUgb2YgdGhlIG1vbWVudHVtIHR3ZWVuIChsaWtlIHdpdGggYSBzY3JvbGxUbyB0d2Vlbikgc28gd2UgY2FuIHBhdXNlKCkgaXQgdG8gcHJldmVudCBjb25mbGljdHMuXG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLnNvcnQgPSBmdW5jdGlvbiAoZnVuYykge1xuICByZXR1cm4gX3RyaWdnZXJzLnNvcnQoZnVuYyB8fCBmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiAoYS52YXJzLnJlZnJlc2hQcmlvcml0eSB8fCAwKSAqIC0xZTYgKyBhLnN0YXJ0IC0gKGIuc3RhcnQgKyAoYi52YXJzLnJlZnJlc2hQcmlvcml0eSB8fCAwKSAqIC0xZTYpO1xuICB9KTtcbn07XG5cblNjcm9sbFRyaWdnZXIub2JzZXJ2ZSA9IGZ1bmN0aW9uICh2YXJzKSB7XG4gIHJldHVybiBuZXcgT2JzZXJ2ZXIodmFycyk7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLm5vcm1hbGl6ZVNjcm9sbCA9IGZ1bmN0aW9uICh2YXJzKSB7XG4gIGlmICh0eXBlb2YgdmFycyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgIHJldHVybiBfbm9ybWFsaXplcjtcbiAgfVxuXG4gIGlmICh2YXJzID09PSB0cnVlICYmIF9ub3JtYWxpemVyKSB7XG4gICAgcmV0dXJuIF9ub3JtYWxpemVyLmVuYWJsZSgpO1xuICB9XG5cbiAgaWYgKHZhcnMgPT09IGZhbHNlKSB7XG4gICAgX25vcm1hbGl6ZXIgJiYgX25vcm1hbGl6ZXIua2lsbCgpO1xuICAgIF9ub3JtYWxpemVyID0gdmFycztcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbm9ybWFsaXplciA9IHZhcnMgaW5zdGFuY2VvZiBPYnNlcnZlciA/IHZhcnMgOiBfZ2V0U2Nyb2xsTm9ybWFsaXplcih2YXJzKTtcbiAgX25vcm1hbGl6ZXIgJiYgX25vcm1hbGl6ZXIudGFyZ2V0ID09PSBub3JtYWxpemVyLnRhcmdldCAmJiBfbm9ybWFsaXplci5raWxsKCk7XG4gIF9pc1ZpZXdwb3J0KG5vcm1hbGl6ZXIudGFyZ2V0KSAmJiAoX25vcm1hbGl6ZXIgPSBub3JtYWxpemVyKTtcbiAgcmV0dXJuIG5vcm1hbGl6ZXI7XG59O1xuXG5TY3JvbGxUcmlnZ2VyLmNvcmUgPSB7XG4gIC8vIHNtYWxsZXIgZmlsZSBzaXplIHdheSB0byBsZXZlcmFnZSBpbiBTY3JvbGxTbW9vdGhlciBhbmQgT2JzZXJ2ZXJcbiAgX2dldFZlbG9jaXR5UHJvcDogX2dldFZlbG9jaXR5UHJvcCxcbiAgX2lucHV0T2JzZXJ2ZXI6IF9pbnB1dE9ic2VydmVyLFxuICBfc2Nyb2xsZXJzOiBfc2Nyb2xsZXJzLFxuICBfcHJveGllczogX3Byb3hpZXMsXG4gIGJyaWRnZToge1xuICAgIC8vIHdoZW4gbm9ybWFsaXplU2Nyb2xsIHNldHMgdGhlIHNjcm9sbCBwb3NpdGlvbiAoc3MgPSBzZXRTY3JvbGwpXG4gICAgc3M6IGZ1bmN0aW9uIHNzKCkge1xuICAgICAgX2xhc3RTY3JvbGxUaW1lIHx8IF9kaXNwYXRjaChcInNjcm9sbFN0YXJ0XCIpO1xuICAgICAgX2xhc3RTY3JvbGxUaW1lID0gX2dldFRpbWUoKTtcbiAgICB9LFxuICAgIC8vIGEgd2F5IHRvIGdldCB0aGUgX3JlZnJlc2hpbmcgdmFsdWUgaW4gT2JzZXJ2ZXJcbiAgICByZWY6IGZ1bmN0aW9uIHJlZigpIHtcbiAgICAgIHJldHVybiBfcmVmcmVzaGluZztcbiAgICB9XG4gIH1cbn07XG5fZ2V0R1NBUCgpICYmIGdzYXAucmVnaXN0ZXJQbHVnaW4oU2Nyb2xsVHJpZ2dlcik7XG5leHBvcnQgeyBTY3JvbGxUcmlnZ2VyIGFzIGRlZmF1bHQgfTsiLCIvKiFcbiAqIENTU1J1bGVQbHVnaW4gMy4xMi41XG4gKiBodHRwczovL2dzYXAuY29tXG4gKlxuICogQGxpY2Vuc2UgQ29weXJpZ2h0IDIwMDgtMjAyNCwgR3JlZW5Tb2NrLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogU3ViamVjdCB0byB0aGUgdGVybXMgYXQgaHR0cHM6Ly9nc2FwLmNvbS9zdGFuZGFyZC1saWNlbnNlIG9yIGZvclxuICogQ2x1YiBHU0FQIG1lbWJlcnMsIHRoZSBhZ3JlZW1lbnQgaXNzdWVkIHdpdGggdGhhdCBtZW1iZXJzaGlwLlxuICogQGF1dGhvcjogSmFjayBEb3lsZSwgamFja0BncmVlbnNvY2suY29tXG4qL1xuXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xudmFyIGdzYXAsXG4gICAgX2NvcmVJbml0dGVkLFxuICAgIF93aW4sXG4gICAgX2RvYyxcbiAgICBDU1NQbHVnaW4sXG4gICAgX3dpbmRvd0V4aXN0cyA9IGZ1bmN0aW9uIF93aW5kb3dFeGlzdHMoKSB7XG4gIHJldHVybiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiO1xufSxcbiAgICBfZ2V0R1NBUCA9IGZ1bmN0aW9uIF9nZXRHU0FQKCkge1xuICByZXR1cm4gZ3NhcCB8fCBfd2luZG93RXhpc3RzKCkgJiYgKGdzYXAgPSB3aW5kb3cuZ3NhcCkgJiYgZ3NhcC5yZWdpc3RlclBsdWdpbiAmJiBnc2FwO1xufSxcbiAgICBfY2hlY2tSZWdpc3RlciA9IGZ1bmN0aW9uIF9jaGVja1JlZ2lzdGVyKCkge1xuICBpZiAoIV9jb3JlSW5pdHRlZCkge1xuICAgIF9pbml0Q29yZSgpO1xuXG4gICAgaWYgKCFDU1NQbHVnaW4pIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlBsZWFzZSBnc2FwLnJlZ2lzdGVyUGx1Z2luKENTU1BsdWdpbiwgQ1NTUnVsZVBsdWdpbilcIik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIF9jb3JlSW5pdHRlZDtcbn0sXG4gICAgX2luaXRDb3JlID0gZnVuY3Rpb24gX2luaXRDb3JlKGNvcmUpIHtcbiAgZ3NhcCA9IGNvcmUgfHwgX2dldEdTQVAoKTtcblxuICBpZiAoX3dpbmRvd0V4aXN0cygpKSB7XG4gICAgX3dpbiA9IHdpbmRvdztcbiAgICBfZG9jID0gZG9jdW1lbnQ7XG4gIH1cblxuICBpZiAoZ3NhcCkge1xuICAgIENTU1BsdWdpbiA9IGdzYXAucGx1Z2lucy5jc3M7XG5cbiAgICBpZiAoQ1NTUGx1Z2luKSB7XG4gICAgICBfY29yZUluaXR0ZWQgPSAxO1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IHZhciBDU1NSdWxlUGx1Z2luID0ge1xuICB2ZXJzaW9uOiBcIjMuMTIuNVwiLFxuICBuYW1lOiBcImNzc1J1bGVcIixcbiAgaW5pdDogZnVuY3Rpb24gaW5pdCh0YXJnZXQsIHZhbHVlLCB0d2VlbiwgaW5kZXgsIHRhcmdldHMpIHtcbiAgICBpZiAoIV9jaGVja1JlZ2lzdGVyKCkgfHwgdHlwZW9mIHRhcmdldC5jc3NUZXh0ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGRpdiA9IHRhcmdldC5fZ3NQcm94eSA9IHRhcmdldC5fZ3NQcm94eSB8fCBfZG9jLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgICB0aGlzLnNzID0gdGFyZ2V0O1xuICAgIHRoaXMuc3R5bGUgPSBkaXYuc3R5bGU7XG4gICAgZGl2LnN0eWxlLmNzc1RleHQgPSB0YXJnZXQuY3NzVGV4dDtcbiAgICBDU1NQbHVnaW4ucHJvdG90eXBlLmluaXQuY2FsbCh0aGlzLCBkaXYsIHZhbHVlLCB0d2VlbiwgaW5kZXgsIHRhcmdldHMpOyAvL3dlIGp1c3Qgb2ZmbG9hZCBhbGwgdGhlIHdvcmsgdG8gdGhlIHJlZ3VsYXIgQ1NTUGx1Z2luIGFuZCB0aGVuIGNvcHkgdGhlIGNzc1RleHQgYmFjayBvdmVyIHRvIHRoZSBydWxlIGluIHRoZSByZW5kZXIoKSBtZXRob2QuIFRoaXMgYWxsb3dzIHVzIHRvIGhhdmUgYWxsIG9mIHRoZSB1cGRhdGVzIHRvIENTU1BsdWdpbiBhdXRvbWF0aWNhbGx5IGZsb3cgdGhyb3VnaCB0byBDU1NSdWxlUGx1Z2luIGluc3RlYWQgb2YgaGF2aW5nIHRvIG1haW50YWluIGJvdGhcbiAgfSxcbiAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIocmF0aW8sIGRhdGEpIHtcbiAgICB2YXIgcHQgPSBkYXRhLl9wdCxcbiAgICAgICAgc3R5bGUgPSBkYXRhLnN0eWxlLF
1xuICAgICAgICBzcyA9IGRhdGEuc3MsXG4gICAgICAgIGk7XG5cbiAgICB3aGlsZSAocHQpIHtcbiAgICAgIHB0LnIocmF0aW8sIHB0LmQpO1xuICAgICAgcHQgPSBwdC5fbmV4dDtcbiAgICB9XG5cbiAgICBpID0gc3R5bGUubGVuZ3RoO1xuXG4gICAgd2hpbGUgKC0taSA+IC0xKSB7XG4gICAgICBzc1tzdHlsZVtpXV0gPSBzdHlsZVtzdHlsZVtpXV07XG4gICAgfVxuICB9LFxuICBnZXRSdWxlOiBmdW5jdGlvbiBnZXRSdWxlKHNlbGVjdG9yKSB7XG4gICAgX2NoZWNrUmVnaXN0ZXIoKTtcblxuICAgIHZhciBydWxlUHJvcCA9IF9kb2MuYWxsID8gXCJydWxlc1wiIDogXCJjc3NSdWxlc1wiLFxuICAgICAgICBzdHlsZVNoZWV0cyA9IF9kb2Muc3R5bGVTaGVldHMsXG4gICAgICAgIGkgPSBzdHlsZVNoZWV0cy5sZW5ndGgsXG4gICAgICAgIHBzZXVkbyA9IHNlbGVjdG9yLmNoYXJBdCgwKSA9PT0gXCI6XCIsXG4gICAgICAgIGosXG4gICAgICAgIGN1clNTLFxuICAgICAgICBjcyxcbiAgICAgICAgYTtcbiAgICBzZWxlY3RvciA9IChwc2V1ZG8gPyBcIlwiIDogXCIsXCIpICsgc2VsZWN0b3Iuc3BsaXQoXCI6OlwiKS5qb2luKFwiOlwiKS50b0xvd2VyQ2FzZSgpICsgXCIsXCI7IC8vbm90ZTogb2xkIHZlcnNpb25zIG9mIElFIHJlcG9ydCB0YWcgbmFtZSBzZWxlY3RvcnMgYXMgdXBwZXIgY2FzZSwgc28gd2UganVzdCBjaGFuZ2UgZXZlcnl0aGluZyB0byBsb3dlcmNhc2UuXG5cbiAgICBpZiAocHNldWRvKSB7XG4gICAgICBhID0gW107XG4gICAgfVxuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgLy9GaXJlZm94IG1heSB0aHJvdyBpbnNlY3VyZSBvcGVyYXRpb24gZXJyb3JzIHdoZW4gY3NzIGlzIGxvYWRlZCBmcm9tIG90aGVyIGRvbWFpbnMsIHNvIHRyeS9jYXRjaC5cbiAgICAgIHRyeSB7XG4gICAgICAgIGN1clNTID0gc3R5bGVTaGVldHNbaV1bcnVsZVByb3BdO1xuXG4gICAgICAgIGlmICghY3VyU1MpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGogPSBjdXJTUy5sZW5ndGg7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihlKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHdoaWxlICgtLWogPiAtMSkge1xuICAgICAgICBjcyA9IGN1clNTW2pdO1xuXG4gICAgICAgIGlmIChjcy5zZWxlY3RvclRleHQgJiYgKFwiLFwiICsgY3Muc2VsZWN0b3JUZXh0LnNwbGl0KFwiOjpcIikuam9pbihcIjpcIikudG9Mb3dlckNhc2UoKSArIFwiLFwiKS5pbmRleE9mKHNlbGVjdG9yKSAhPT0gLTEpIHtcbiAgICAgICAgICAvL25vdGU6IElFIGFkZHMgYW4gZXh0cmEgXCI6XCIgdG8gcHNldWRvIHNlbGVjdG9ycywgc28gLm15Q2xhc3M6YWZ0ZXIgYmVjb21lcyAubXlDbGFzczo6YWZ0ZXIsIHNvIHdlIG5lZWQgdG8gc3RyaXAgdGhlIGV4dHJhIG9uZSBvdXQuXG4gICAgICAgICAgaWYgKHBzZXVkbykge1xuICAgICAgICAgICAgYS5wdXNoKGNzLnN0eWxlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGNzLnN0eWxlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhO1xuICB9LFxuICByZWdpc3RlcjogX2luaXRDb3JlXG59O1xuX2dldEdTQVAoKSAmJiBnc2FwLnJlZ2lzdGVyUGx1Z2luKENTU1J1bGVQbHVnaW4pO1xuZXhwb3J0IHsgQ1NTUnVsZVBsdWdpbiBhcyBkZWZhdWx0IH07IiwiLyohXG4gKiBTY3JvbGxUb1BsdWdpbiAzLjEyLjVcbiAqIGh0dHBzOi8vZ3NhcC5jb21cbiAqXG4gKiBAbGljZW5zZSBDb3B5cmlnaHQgMjAwOC0yMDI0LCBHcmVlblNvY2suIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBhdCBodHRwczovL2dzYXAuY29tL3N0YW5kYXJkLWxpY2Vuc2Ugb3IgZm9yXG4gKiBDbHViIEdTQVAgbWVtYmVycywgdGhlIGFncmVlbWVudCBpc3N1ZWQgd2l0aCB0aGF0IG1lbWJlcnNoaXAuXG4gKiBAYXV0aG9yOiBKYWNrIERveWxlLCBqYWNrQGdyZWVuc29jay5jb21cbiovXG5cbi8qIGVzbGludC1kaXNhYmxlICovXG52YXIgZ3NhcCxcbiAgICBfY29yZUluaXR0ZWQsXG4gICAgX3dpbmRvdyxcbiAgICBfZG9jRWwsXG4gICAgX2JvZHksXG4gICAgX3RvQXJyYXksXG4gICAgX2NvbmZpZyxcbiAgICBTY3JvbGxUcmlnZ2VyLFxuICAgIF93aW5kb3dFeGlzdHMgPSBmdW5jdGlvbiBfd2luZG93RXhpc3RzKCkge1xuICByZXR1cm4gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIjtcbn0sXG4gICAgX2dldEdTQVAgPSBmdW5jdGlvbiBfZ2V0R1NBUCgpIHtcbiAgcmV0dXJuIGdzYXAgfHwgX3dpbmRvd0V4aXN0cygpICYmIChnc2FwID0gd2luZG93LmdzYXApICYmIGdzYXAucmVnaXN0ZXJQbHVnaW4gJiYgZ3NhcDtcbn0sXG4gICAgX2lzU3RyaW5nID0gZnVuY3Rpb24gX2lzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCI7XG59LFxuICAgIF9pc0Z1bmN0aW9uID0gZnVuY3Rpb24gX2lzRnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiO1xufSxcbiAgICBfbWF4ID0gZnVuY3Rpb24gX21heChlbGVtZW50LCBheGlzKSB7XG4gIHZhciBkaW0gPSBheGlzID09PSBcInhcIiA/IFwiV2lkdGhcIiA6IFwiSGVpZ2h0XCIsXG4gICAgICBzY3JvbGwgPSBcInNjcm9sbFwiICsgZGltLFxuICAgICAgY2xpZW50ID0gXCJjbGllbnRcIiArIGRpbTtcbiAgcmV0dXJuIGVsZW1lbnQgPT09IF93aW5kb3cgfHwgZWxlbWVudCA9PT0gX2RvY0VsIHx8IGVsZW1lbnQgPT09IF9ib2R5ID8gTWF0aC5tYXgoX2RvY0VsW3Njcm9sbF0sIF9ib2R5W3Njcm9sbF0pIC0gKF93aW5kb3dbXCJpbm5lclwiICsgZGltXSB8fCBfZG9jRWxbY2xpZW50XSB8fCBfYm9keVtjbGllbnRdKSA6IGVsZW1lbnRbc2Nyb2xsXSAtIGVsZW1lbnRbXCJvZmZzZXRcIiArIGRpbV07XG59LFxuICAgIF9idWlsZEdldHRlciA9IGZ1bmN0aW9uIF9idWlsZEdldHRlcihlLCBheGlzKSB7XG4gIC8vcGFzcyBpbiBhbiBlbGVtZW50IGFuZCBhbiBheGlzIChcInhcIiBvciBcInlcIikgYW5kIGl0J2xsIHJldHVybi
1BhIGdldHRlciBmdW5jdGlvbiBmb3IgdGhlIHNjcm9sbCBwb3NpdGlvbiBvZiB0aGF0IGVsZW1lbnQgKGxpa2Ugc2Nyb2xsVG9wIG9yIHNjcm9sbExlZnQsIGFsdGhvdWdoIGlmIHRoZSBlbGVtZW50IGlzIHRoZSB3aW5kb3csIGl0J2xsIHVzZSB0aGUgcGFnZVhPZmZzZXQvcGFnZVlPZmZzZXQgb3IgdGhlIGRvY3VtZW50RWxlbWVudCdzIHNjcm9sbFRvcC9zY3JvbGxMZWZ0IG9yIGRvY3VtZW50LmJvZHkncy4gQmFzaWNhbGx5IHRoaXMgc3RyZWFtbGluZXMgdGhpbmdzIGFuZCBtYWtlcyBhIHZlcnkgZmFzdCBnZXR0ZXIgYWNyb3NzIGJyb3dzZXJzLlxuICB2YXIgcCA9IFwic2Nyb2xsXCIgKyAoYXhpcyA9PT0gXCJ4XCIgPyBcIkxlZnRcIiA6IFwiVG9wXCIpO1xuXG4gIGlmIChlID09PSBfd2luZG93KSB7XG4gICAgaWYgKGUucGFnZVhPZmZzZXQgIT0gbnVsbCkge1xuICAgICAgcCA9IFwicGFnZVwiICsgYXhpcy50b1VwcGVyQ2FzZSgpICsgXCJPZmZzZXRcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgZSA9IF9kb2NFbFtwXSAhPSBudWxsID8gX2RvY0VsIDogX2JvZHk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZVtwXTtcbiAgfTtcbn0sXG4gICAgX2NsZWFuID0gZnVuY3Rpb24gX2NsZWFuKHZhbHVlLCBpbmRleCwgdGFyZ2V0LCB0YXJnZXRzKSB7XG4gIF9pc0Z1bmN0aW9uKHZhbHVlKSAmJiAodmFsdWUgPSB2YWx1ZShpbmRleCwgdGFyZ2V0LCB0YXJnZXRzKSk7XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIikge1xuICAgIHJldHVybiBfaXNTdHJpbmcodmFsdWUpICYmIHZhbHVlICE9PSBcIm1heFwiICYmIHZhbHVlLmNoYXJBdCgxKSAhPT0gXCI9XCIgPyB7XG4gICAgICB4OiB2YWx1ZSxcbiAgICAgIHk6IHZhbHVlXG4gICAgfSA6IHtcbiAgICAgIHk6IHZhbHVlXG4gICAgfTsgLy9pZiB3ZSBkb24ndCByZWNlaXZlIGFuIG9iamVjdCBhcyB0aGUgcGFyYW1ldGVyLCBhc3N1bWUgdGhlIHVzZXIgaW50ZW5kcyBcInlcIi5cbiAgfSBlbHNlIGlmICh2YWx1ZS5ub2RlVHlwZSkge1xuICAgIHJldHVybiB7XG4gICAgICB5OiB2YWx1ZSxcbiAgICAgIHg6IHZhbHVlXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgcmVzdWx0ID0ge30sXG4gICAgICAgIHA7XG5cbiAgICBmb3IgKHAgaW4gdmFsdWUpIHtcbiAgICAgIHJlc3VsdFtwXSA9IHAgIT09IFwib25BdXRvS2lsbFwiICYmIF9pc0Z1bmN0aW9uKHZhbHVlW3BdKSA/IHZhbHVlW3BdKGluZGV4LCB0YXJnZXQsIHRhcmdldHMpIDogdmFsdWVbcF07XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufSxcbiAgICBfZ2V0T2Zmc2V0ID0gZnVuY3Rpb24gX2dldE9mZnNldChlbGVtZW50LCBjb250YWluZXIpIHtcbiAgZWxlbWVudCA9IF90b0FycmF5KGVsZW1lbnQpWzBdO1xuXG4gIGlmICghZWxlbWVudCB8fCAhZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QpIHtcbiAgICByZXR1cm4gY29uc29sZS53YXJuKFwic2Nyb2xsVG8gdGFyZ2V0IGRvZXNuJ3QgZXhpc3QuIFVzaW5nIDBcIikgfHwge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9XG5cbiAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgaXNSb290ID0gIWNvbnRhaW5lciB8fCBjb250YWluZXIgPT09IF93aW5kb3cgfHwgY29udGFpbmVyID09PSBfYm9keSxcbiAgICAgIGNSZWN0ID0gaXNSb290ID8ge1xuICAgIHRvcDogX2RvY0VsLmNsaWVudFRvcCAtIChfd2luZG93LnBhZ2VZT2Zmc2V0IHx8IF9kb2NFbC5zY3JvbGxUb3AgfHwgX2JvZHkuc2Nyb2xsVG9wIHx8IDApLFxuICAgIGxlZnQ6IF9kb2NFbC5jbGllbnRMZWZ0IC0gKF93aW5kb3cucGFnZVhPZmZzZXQgfHwgX2RvY0VsLnNjcm9sbExlZnQgfHwgX2JvZHkuc2Nyb2xsTGVmdCB8fCAwKVxuICB9IDogY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgb2Zmc2V0cyA9IHtcbiAgICB4OiByZWN0LmxlZnQgLSBjUmVjdC5sZWZ0LFxuICAgIHk6IHJlY3QudG9wIC0gY1JlY3QudG9wXG4gIH07XG5cbiAgaWYgKCFpc1Jvb3QgJiYgY29udGFpbmVyKSB7XG4gICAgLy9vbmx5IGFkZCB0aGUgY3VycmVudCBzY3JvbGwgcG9zaXRpb24gaWYgaXQncyBub3QgdGhlIHdpbmRvdy9ib2R5LlxuICAgIG9mZnNldHMueCArPSBfYnVpbGRHZXR0ZXIoY29udGFpbmVyLCBcInhcIikoKTtcbiAgICBvZmZzZXRzLnkgKz0gX2J1aWxkR2V0dGVyKGNvbnRhaW5lciwgXCJ5XCIpKCk7XG4gIH1cblxuICByZXR1cm4gb2Zmc2V0cztcbn0sXG4gICAgX3BhcnNlVmFsID0gZnVuY3Rpb24gX3BhcnNlVmFsKHZhbHVlLCB0YXJnZXQsIGF4aXMsIGN1cnJlbnRWYWwsIG9mZnNldCkge1xuICByZXR1cm4gIWlzTmFOKHZhbHVlKSAmJiB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgPyBwYXJzZUZsb2F0KHZhbHVlKSAtIG9mZnNldCA6IF9pc1N0cmluZyh2YWx1ZSkgJiYgdmFsdWUuY2hhckF0KDEpID09PSBcIj1cIiA/IHBhcnNlRmxvYXQodmFsdWUuc3Vic3RyKDIpKSAqICh2YWx1ZS5jaGFyQXQoMCkgPT09IFwiLVwiID8gLTEgOiAxKSArIGN1cnJlbnRWYWwgLSBvZmZzZXQgOiB2YWx1ZSA9PT0gXCJtYXhcIiA/IF9tYXgodGFyZ2V0LCBheGlzKSAtIG9mZnNldCA6IE1hdGgubWluKF9tYXgodGFyZ2V0LCBheGlzKSwgX2dldE9mZnNldCh2YWx1ZSwgdGFyZ2V0KVtheGlzXSAtIG9mZnNldCk7XG59LFxuICAgIF9pbml0Q29yZSA9IGZ1bmN0aW9uIF9pbml0Q29yZSgpIHtcbiAgZ3NhcCA9IF9nZXRHU0FQKCk7XG5cbiAgaWYgKF93aW5kb3dFeGlzdHMoKSAmJiBnc2FwICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudC5ib2R5KSB7XG4gICAgX3dpbmRvdyA9IHdpbmRvdztcbiAgICBfYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gICAgX2RvY0VsID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgIF90b0FycmF5ID0gZ3NhcC51dGlscy50b0FycmF5O1xuICAgIGdzYXAuY29uZmlnKHtcbiAgICAgIGF1dG9LaWxsVGhyZXNob2xkOiA3XG4gICAgfSk7XG4gICAgX2NvbmZpZyA9IGdzYXAuY29uZmlnKCk7XG4gICAgX2NvcmVJbml0dGVkID0gMTtcbiAgfVxufTtcblxuZXhwb3J0IHZhciBTY3JvbGxUb1BsdWdpbiA9IHtcbiAgdmVyc2lvbjogXCIzLjEyLjVcIixcbiAgbmFtZTogXCJzY3JvbGxUb1wiLFxuICByYXdWYXJzOiAxLFxuICByZWdpc3RlcjogZnVuY3Rpb24gcmVnaXN0ZXIoY29yZSkge1xuICAgIGdzYXAgPSBjb3JlO1xuXG4gICAgX2luaXRDb3JlKCk7XG4gIH0sXG4gIGluaXQ6IGZ1bmN0aW9uIGluaXQodGFyZ2V0LCB2YWx1ZSwgdHdlZW4sIGluZGV4LCB0YXJnZXRzKSB7XG4gICAgX2NvcmVJbml0dGVkIHx8IF9pbml0Q29yZSgpO1xuICAgIHZhciBkYXRhID0gdGh
1pcyxcbiAgICAgICAgc25hcFR5cGUgPSBnc2FwLmdldFByb3BlcnR5KHRhcmdldCwgXCJzY3JvbGxTbmFwVHlwZVwiKTtcbiAgICBkYXRhLmlzV2luID0gdGFyZ2V0ID09PSBfd2luZG93O1xuICAgIGRhdGEudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIGRhdGEudHdlZW4gPSB0d2VlbjtcbiAgICB2YWx1ZSA9IF9jbGVhbih2YWx1ZSwgaW5kZXgsIHRhcmdldCwgdGFyZ2V0cyk7XG4gICAgZGF0YS52YXJzID0gdmFsdWU7XG4gICAgZGF0YS5hdXRvS2lsbCA9ICEhdmFsdWUuYXV0b0tpbGw7XG4gICAgZGF0YS5nZXRYID0gX2J1aWxkR2V0dGVyKHRhcmdldCwgXCJ4XCIpO1xuICAgIGRhdGEuZ2V0WSA9IF9idWlsZEdldHRlcih0YXJnZXQsIFwieVwiKTtcbiAgICBkYXRhLnggPSBkYXRhLnhQcmV2ID0gZGF0YS5nZXRYKCk7XG4gICAgZGF0YS55ID0gZGF0YS55UHJldiA9IGRhdGEuZ2V0WSgpO1xuICAgIFNjcm9sbFRyaWdnZXIgfHwgKFNjcm9sbFRyaWdnZXIgPSBnc2FwLmNvcmUuZ2xvYmFscygpLlNjcm9sbFRyaWdnZXIpO1xuICAgIGdzYXAuZ2V0UHJvcGVydHkodGFyZ2V0LCBcInNjcm9sbEJlaGF2aW9yXCIpID09PSBcInNtb290aFwiICYmIGdzYXAuc2V0KHRhcmdldCwge1xuICAgICAgc2Nyb2xsQmVoYXZpb3I6IFwiYXV0b1wiXG4gICAgfSk7XG5cbiAgICBpZiAoc25hcFR5cGUgJiYgc25hcFR5cGUgIT09IFwibm9uZVwiKSB7XG4gICAgICAvLyBkaXNhYmxlIHNjcm9sbCBzbmFwcGluZyB0byBhdm9pZCBzdHJhbmdlIGJlaGF2aW9yXG4gICAgICBkYXRhLnNuYXAgPSAxO1xuICAgICAgZGF0YS5zbmFwSW5saW5lID0gdGFyZ2V0LnN0eWxlLnNjcm9sbFNuYXBUeXBlO1xuICAgICAgdGFyZ2V0LnN0eWxlLnNjcm9sbFNuYXBUeXBlID0gXCJub25lXCI7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLnggIT0gbnVsbCkge1xuICAgICAgZGF0YS5hZGQoZGF0YSwgXCJ4XCIsIGRhdGEueCwgX3BhcnNlVmFsKHZhbHVlLngsIHRhcmdldCwgXCJ4XCIsIGRhdGEueCwgdmFsdWUub2Zmc2V0WCB8fCAwKSwgaW5kZXgsIHRhcmdldHMpO1xuXG4gICAgICBkYXRhLl9wcm9wcy5wdXNoKFwic2Nyb2xsVG9feFwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5za2lwWCA9IDE7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLnkgIT0gbnVsbCkge1xuICAgICAgZGF0YS5hZGQoZGF0YSwgXCJ5XCIsIGRhdGEueSwgX3BhcnNlVmFsKHZhbHVlLnksIHRhcmdldCwgXCJ5XCIsIGRhdGEueSwgdmFsdWUub2Zmc2V0WSB8fCAwKSwgaW5kZXgsIHRhcmdldHMpO1xuXG4gICAgICBkYXRhLl9wcm9wcy5wdXNoKFwic2Nyb2xsVG9feVwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YS5za2lwWSA9IDE7XG4gICAgfVxuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcihyYXRpbywgZGF0YSkge1xuICAgIHZhciBwdCA9IGRhdGEuX3B0LFxuICAgICAgICB0YXJnZXQgPSBkYXRhLnRhcmdldCxcbiAgICAgICAgdHdlZW4gPSBkYXRhLnR3ZWVuLFxuICAgICAgICBhdXRvS2lsbCA9IGRhdGEuYXV0b0tpbGwsXG4gICAgICAgIHhQcmV2ID0gZGF0YS54UHJldixcbiAgICAgICAgeVByZXYgPSBkYXRhLnlQcmV2LFxuICAgICAgICBpc1dpbiA9IGRhdGEuaXNXaW4sXG4gICAgICAgIHNuYXAgPSBkYXRhLnNuYXAsXG4gICAgICAgIHNuYXBJbmxpbmUgPSBkYXRhLnNuYXBJbmxpbmUsXG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICAgIHlEaWYsXG4gICAgICAgIHhEaWYsXG4gICAgICAgIHRocmVzaG9sZDtcblxuICAgIHdoaWxlIChwdCkge1xuICAgICAgcHQucihyYXRpbywgcHQuZCk7XG4gICAgICBwdCA9IHB0Ll9uZXh0O1xuICAgIH1cblxuICAgIHggPSBpc1dpbiB8fCAhZGF0YS5za2lwWCA/IGRhdGEuZ2V0WCgpIDogeFByZXY7XG4gICAgeSA9IGlzV2luIHx8ICFkYXRhLnNraXBZID8gZGF0YS5nZXRZKCkgOiB5UHJldjtcbiAgICB5RGlmID0geSAtIHlQcmV2O1xuICAgIHhEaWYgPSB4IC0geFByZXY7XG4gICAgdGhyZXNob2xkID0gX2NvbmZpZy5hdXRvS2lsbFRocmVzaG9sZDtcblxuICAgIGlmIChkYXRhLnggPCAwKSB7XG4gICAgICAvL2Nhbid0IHNjcm9sbCB0byBhIHBvc2l0aW9uIGxlc3MgdGhhbiAwISBNaWdodCBoYXBwZW4gaWYgc29tZW9uZSB1c2VzIGEgQmFjay5lYXNlT3V0IG9yIEVsYXN0aWMuZWFzZU91dCB3aGVuIHNjcm9sbGluZyBiYWNrIHRvIHRoZSB0b3Agb2YgdGhlIHBhZ2UgKGZvciBleGFtcGxlKVxuICAgICAgZGF0YS54ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS55IDwgMCkge1xuICAgICAgZGF0YS55ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoYXV0b0tpbGwpIHtcbiAgICAgIC8vbm90ZTogaU9TIGhhcyBhIGJ1ZyB0aGF0IHRocm93cyBvZmYgdGhlIHNjcm9sbCBieSBzZXZlcmFsIHBpeGVscywgc28gd2UgbmVlZCB0byBjaGVjayBpZiBpdCdzIHdpdGhpbiA3IHBpeGVscyBvZiB0aGUgcHJldmlvdXMgb25lIHRoYXQgd2Ugc2V0IGluc3RlYWQgb2YganVzdCBsb29raW5nIGZvciBhbiBleGFjdCBtYXRjaC5cbiAgICAgIGlmICghZGF0YS5za2lwWCAmJiAoeERpZiA+IHRocmVzaG9sZCB8fCB4RGlmIDwgLXRocmVzaG9sZCkgJiYgeCA8IF9tYXgodGFyZ2V0LCBcInhcIikpIHtcbiAgICAgICAgZGF0YS5za2lwWCA9IDE7IC8vaWYgdGhlIHVzZXIgc2Nyb2xscyBzZXBhcmF0ZWx5LCB3ZSBzaG91bGQgc3RvcCB0d2VlbmluZyFcbiAgICAgIH1cblxuICAgICAgaWYgKCFkYXRhLnNraXBZICYmICh5RGlmID4gdGhyZXNob2xkIHx8IHlEaWYgPCAtdGhyZXNob2xkKSAmJiB5IDwgX21heCh0YXJnZXQsIFwieVwiKSkge1xuICAgICAgICBkYXRhLnNraXBZID0gMTsgLy9pZiB0aGUgdXNlciBzY3JvbGxzIHNlcGFyYXRlbHksIHdlIHNob3VsZCBzdG9wIHR3ZWVuaW5nIVxuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YS5za2lwWCAmJiBkYXRhLnNraXBZKSB7XG4gICAgICAgIHR3ZWVuLmtpbGwoKTtcbiAgICAgICAgZGF0YS52YXJzLm9uQXV0b0tpbGwgJiYgZGF0YS52YXJzLm9uQXV0b0tpbGwuYXBwbHkodHdlZW4sIGRhdGEudmFycy5vbkF1dG9LaWxsUGFyYW1zIHx8IFtdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNXaW4pIHtcbiAgICAgIF93aW5kb3cuc2Nyb2xsVG8oIWRhdGEuc2tpcFggPyBkYXRhLnggOiB4LCAhZGF0YS5za2lwWSA/IGRhdGEueSA6IHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkYXRhLnNraXBZIHx8ICh0YXJnZXQuc2Nyb2xsVG9wID0gZGF0YS55KTtcbiAgICAgIGRhdGEuc2tpcFggfHwgKHRhcmdldC5zY3JvbGxMZWZ0ID0gZGF0YS54KTtcbiAgICB9XG5cbiAgICBpZiAoc25hcCAmJiAocmF0aW8gPT09IDEgfHwgcmF0aW8gPT09IDApKSB7XG4gICAgICB5ID0gdGFyZ2V0LnNjcm9sbFRvcDtcbiAgICAgIHggPSB0YXJnZXQuc2Nyb2xsTGVmdDtcbiAgICAgIHNuYXBJbmxpbmUgPyB0YXJnZXQuc3R5bGUuc2Nyb2xsU25hcFR5cGUgPSBzbmFwSW5saW5lIDogdGFyZ2V0LnN0eWxlLnJlbW92ZVByb3BlcnR5KFwic2Nyb2xsLXNuYXAtdHlwZVwiKTtcbiAgICAgIHRhcmdldC5zY3JvbGxUb3AgPSB5ICsgMTsgLy8gYnVnIGluIFNhZmFyaSBjYXVzZXMgdGhlIGVsZW1lbnQgdG8gdG90YWxseSByZXNldCBpdHMgc2Nyb2xsIHBvc2l0aW9uIHdoZW4gc2Nyb2xsLXNuYXAtdHlwZSBjaGFuZ2VzLCBzbyB3ZSBuZWVkIHRvIHNldCBpdCB0byBhIHNsaWdodGx5IGRpZmZlcmVudCB2YWx1ZSBhbmQgdGhlbiBiYWNrIGFnYWluIHRvIHdvcmsgYXJvdW5kIHRoaXMgYnVnLlxuXG4gICAgICB0YXJnZXQuc2Nyb2xsTGVmdCA9IHggKyAxO1xuICAgICAgdGFyZ2V0LnNjcm9sbFRvcCA9IHk7XG4gICAgICB0YXJnZXQuc2Nyb2xsTGVmdCA9IHg7XG4gICAgfVxuXG4gICAgZGF0YS54UHJldiA9IGRhdGEueDtcbiAgICBkYXRhLnlQcmV2ID0gZGF0YS55O1xuICAgIFNjcm9sbFRyaWdnZXIgJiYgU2Nyb2xsVHJpZ2dlci51cGRhdGUoKTtcbiAgfSxcbiAga2lsbDogZnVuY3Rpb24ga2lsbChwcm9wZXJ0eSkge1xuICAgIHZhciBib3RoID0gcHJvcGVydHkgPT09IFwic2Nyb2xsVG9cIixcbiAgICAgICAgaSA9IHRoaXMuX3Byb3BzLmluZGV4T2YocHJvcGVydHkpO1xuXG4gICAgaWYgKGJvdGggfHwgcHJvcGVydHkgPT09IFwic2Nyb2xsVG9feFwiKSB7XG4gICAgICB0aGlzLnNraXBYID0gMTtcbiAgICB9XG5cbiAgICBpZiAoYm90aCB8fCBwcm9wZXJ0eSA9PT0gXCJzY3JvbGxUb195XCIpIHtcbiAgICAgIHRoaXMuc2tpcFkgPSAxO1xuICAgIH1cblxuICAgIGkgPiAtMSAmJiB0aGlzLl9wcm9wcy5zcGxpY2UoaSwgMSk7XG4gICAgcmV0dXJuICF0aGlzLl9wcm9wcy5sZW5ndGg7XG4gIH1cbn07XG5TY3JvbGxUb1BsdWdpbi5tYXggPSBfbWF4O1xuU2Nyb2xsVG9QbHVnaW4uZ2V0T2Zmc2V0ID0gX2dldE9mZnNldDtcblNjcm9sbFRvUGx1Z2luLmJ1aWxkR2V0dGVyID0gX2J1aWxkR2V0dGVyO1xuX2dldEdTQVAoKSAmJiBnc2FwLnJlZ2lzdGVyUGx1Z2luKFNjcm9sbFRvUGx1Z2luKTtcbmV4cG9ydCB7
1IFNjcm9sbFRvUGx1Z2luIGFzIGRlZmF1bHQgfTsiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCAnLi4vc2Nzcy9idW5kbGUuc2Nzcyc7XG5pbXBvcnQgJ2Jvb3RzdHJhcC9qcy9kaXN0L2NvbGxhcHNlJztcbmltcG9ydCBTd2lwZXIgZnJvbSAnc3dpcGVyL2J1bmRsZSc7XG5pbXBvcnQgJ3N3aXBlci9zd2lwZXItYnVuZGxlLmNzcyc7XG5pbXBvcnQgbGlnaHRHYWxsZXJ5IGZyb20gJ2xpZ2h0Z2FsbGVyeSc7XG5pbXBvcnQgbGdab29tIGZyb20gJ2xpZ2h0Z2FsbGVyeS9wbHVnaW5zL3pvb20nO1xuaW1wb3J0ICdsaWdodGdhbGxlcnkvY3NzL2xpZ2h0Z2FsbGVyeS5jc3MnO1xuaW1wb3J0ICdsaWdodGdhbGxlcnkvY3NzL2xnLXpvb20uY3NzJztcbmltcG9ydCBMZW5pcyBmcm9tICdAc3R1ZGlvLWZyZWlnaHQvbGVuaXMnO1xuXG5pbXBvcnQgeyBnc2FwIH0gZnJvbSBcImdzYXAvYWxsXCI7XG5pbXBvcnQgeyBTY3JvbGxUcmlnZ2VyIH0gZnJvbSBcImdzYXAvU2Nyb2xsVHJpZ2dlclwiO1xuaW1wb3J0IHsgQ1NTUnVsZVBsdWdpbiB9IGZyb20gXCJnc2FwL0NTU1J1bGVQbHVnaW5cIjtcbmltcG9ydCB7IFNjcm9sbFRvUGx1Z2luIH0gZnJvbSBcImdzYXAvU2Nyb2xsVG9QbHVnaW5cIjtcblxudmFyIHN3aXBlcixzd2lwZXIyLHN3aXBlcjMsc3dpcGVyNCxzd2lwZXI1LHN3aXBlcjYsc3dpcGVyNyxzd2lwZXI4LCB0b3BiYXI7XG5sZXQgbW07XG5cbnZhciBpbWFnZXNMb2FkZWQgPSByZXF1aXJlKCdpbWFnZXNsb2FkZWQnKTtcblxuZ3NhcC5yZWdpc3RlclBsdWdpbihTY3JvbGxUcmlnZ2VyLCBTY3JvbGxUb1BsdWdpbiwgQ1NTUnVsZVBsdWdpbik7XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uKCkge1xuICAgIFxuICAgIGltYWdlc0xvYWRlZCggJ2JvZHknLCB7IGJhY2tncm91bmQ6IHRydWUgfSwgZnVuY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IG1lbnVUb2dnbGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubWVudS10b2dnbGUnKTtcbiAgICAgICAgY29uc3QgbWVudSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtZW51Q29tcGFyc2EnKTtcbiAgICAgICAgY29uc3QgYm9keSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKTtcbiAgICAgICAgY29uc3QgYmFja2dyb3VuZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiYWNrZ3JvdW5kJyk7XG4gICAgICAgIGNvbnN0IGNsb3NlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Nsb3NlTWVudScpO1xuICAgICAgICBjb25zdCBlbGVtZW50byA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5vbGRTdGFnaW9uZScpXG4gICAgICAgIFxuICAgICAgICBcblxuICAgICAgICBcbiAgICAgICAgY29uc3QgbGVuaXMgPSBuZXcgTGVuaXMoe1xuICAgICAgICAgICAgZHVyYXRpb246IDEuMixcbiAgICAgICAgICAgIGVhc2luZzogKHQpID0+ICh0ID09PSAxID8gMSA6IDEgLSBNYXRoLnBvdygyLCAtMTAgKiB0KSksXG4gICAgICAgICAgICBkaXJlY3Rpb246IFwidmVydGljYWxcIixcbiAgICAgICAgICAgIGdlc3R1cmVEaXJlY3Rpb246IFwidmVydGljYWxcIixcbiAgICAgICAgICAgIHNtb290aDogdHJ1ZSxcbiAgICAgICAgICAgIHNtb290aFRvdWNoOiBmYWxzZSxcbiAgICAgICAgICAgIHRvdWNoTXVsdGlwbGllcjogMixcbiAgICAgICAgfSk7XG5cbiAgICAgICAgXG4gICAgICAgIFxuICAgICAgICBmdW5jdGlvbiByYWYodGltZSkge1xuICAgICAgICAgICAgbGVuaXMucmFmKHRpbWUpO1xuICAgICAgICAgICAgbGVuaXMyLnJhZih0aW1lKTtcbiAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShyYWYpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmFmKTtcblxuICAgICAgICBpZigkKCcjbG9hZGluZycpLmxlbmd0aCl7XG4gICAgICAgIFNjcm9sbFRyaWdnZXIuY3JlYXRlKHtcblx0XHRcdHRyaWdnZXI6ICcjbG9hZGluZycsXG5cdFx0XHRzdGFydDogXCJ0b3AgODAlXCIsXG5cdFx0XHRvbmNlOiB0cnVlLFxuXHRcdFx0b25FbnRlcjogc2VsZiA9PiB7XG4gICAgICAgICAgICAgICAgdmFyIG5ld1VSTCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0ICsgXCIvYWpheC1uZXdzL1wiXG5cdFx0XHRcdCQuYWpheCh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiUE9TVFwiLFxuICAgICAgICAgICAgICAgICAgICB1cmw6IG5ld1VSTCxcbiAgICAgICAgICAgICAgICAgICAgY2FjaGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3Q6IDIxXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZVNlbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhID0galF1ZXJ5LnBhcnNlSlNPTihlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuXHRcdFx0fVxuXHRcdCAgfSk7XG4gICAgICAgIH1cblxuICAgIG1tID0gZ3NhcC5tYXRjaE1lZGlhKCk7XG5cbiAgICB2YXIgcGFydHMgPSB3aW5kb3cubG9jYXRpb24uc2VhcmNoLnN1YnN0cigxKS5zcGxpdChcIiZcIik7XG4gICAgdmFyICRfR0VUID0ge307XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2Y
1XIgdGVtcCA9IHBhcnRzW2ldLnNwbGl0KFwiPVwiKTtcbiAgICAgICAgJF9HRVRbZGVjb2RlVVJJQ29tcG9uZW50KHRlbXBbMF0pXSA9IGRlY29kZVVSSUNvbXBvbmVudCh0ZW1wWzFdKTtcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeVN0cmluZyA9IHdpbmRvdy5sb2NhdGlvbi5zZWFyY2g7XG4gICAgY29uc3QgdXJsUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhxdWVyeVN0cmluZyk7XG4gICAgY29uc3QgdHlwZSA9IHVybFBhcmFtcy5nZXQoJ3R5cGUnKVxuICAgIFxuICAgIGNoZWNrcmVzaXplKCk7ICAgIFxuICAgIFxuICAgIGlmKHR5cGUgPT0gJ21pY2hlbGluJyl7XG4gICAgICAgIHN3aXBlcjcgPSBuZXcgU3dpcGVyKFwiLmNTd2lwZXJcIiwge1xuICAgICAgICAgICAgZWZmZWN0OiAnZmFkZScsXG4gICAgICAgICAgICBhdXRvSGVpZ2h0OiB0cnVlLFxuICAgICAgICAgICAgaW5pdGlhbFNsaWRlOiAxLFxuICAgICAgICAgICAgZmFkZUVmZmVjdDoge1xuICAgICAgICAgICAgICAgIGNyb3NzRmFkZTogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHRvcGJhcjMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9wYmFyMyBhJyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b3BiYXIzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRvcGJhcjNbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgICAgIHN3aXBlcjcuc2xpZGVUbyhldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdocmVmJyksIDM1MCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnRhcmdldC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgICAgIHN3aXBlcjcub24oJ3NsaWRlQ2hhbmdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHRvcGJhcjMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgIG5vZGUuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgXG4gICAgICB9KTtcbiAgICB9ZWxzZSBpZih0eXBlID09ICd0ZWFtJyl7XG4gICAgICAgIHN3aXBlcjcgPSBuZXcgU3dpcGVyKFwiLmNTd2lwZXJcIiwge1xuICAgICAgICAgICAgZWZmZWN0OiAnZmFkZScsXG4gICAgICAgICAgICBhdXRvSGVpZ2h0OiB0cnVlLFxuICAgICAgICAgICAgaW5pdGlhbFNsaWRlOiAyLFxuICAgICAgICAgICAgZmFkZUVmZmVjdDoge1xuICAgICAgICAgICAgICAgIGNyb3NzRmFkZTogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHRvcGJhcjMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9wYmFyMyBhJyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b3BiYXIzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRvcGJhcjNbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgICAgIHN3aXBlcjcuc2xpZGVUbyhldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdocmVmJyksIDM1MCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnRhcmdldC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgICAgIHN3aXBlcjcub24oJ3NsaWRlQ2hhbmdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICB0b3BiYXIzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgbm9kZS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIFxuICAgICAgICAgIH0pO1xuICAgIH1lbHNle1xuICAgICAgICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2xpZGVDbGFzc2lmaWNhJykpe1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBzd2lwZXI3ID0gbmV3IFN3aXBlcihcIi5jU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBlZmZlY3Q6ICdmYWRlJyxcbiAgICAgICAgICAgICAgICBhdXRvSGVpZ2h0OiB0cnVlLFxuICAgICAgICAgICAgICAgIGZhZGVFZmZlY3Q6IHtcbiAgICAgICAgICAgICAgICAgICAgY3Jvc3NGYWRlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiAwLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2Y
1XIgdG9wYmFyMyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy50b3BiYXIzIGEnKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9wYmFyMy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHRvcGJhcjNbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpcGVyNy5zbGlkZVRvKGV2ZW50LnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSwgMzUwLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC50YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3dpcGVyNy5vbignc2xpZGVDaGFuZ2UnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0b3BiYXIzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBcbiAgICBsaWdodEdhbGxlcnkoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2N1c3RvbWl6ZS10aHVtYm5haWxzLWdhbGxlcnknKSwge1xuICAgICAgICAvLyBBZGQgYSBjdXN0b20gY2xhc3MgdG8gYXBwbHkgc3R5bGUgb25seSBmb3IgdGhlIHBhcnRpY3VsYXIgZ2FsbGVyeVxuICAgICAgICBhZGRDbGFzczogJ2xnLWN1c3RvbS10aHVtYm5haWxzJyxcbiAgICBcbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBzdGFydGluZyBhbmltYXRpb25zLlxuICAgICAgICAvLyBUaGlzIGNhbiBiZSBkb25lIGJ5IG92ZXJyaWRpbmcgQ1NTIGFzIHdlbGxcbiAgICAgICAgYXBwZW5kVGh1bWJuYWlsc1RvOiAnLmxnLW91dGVyJyxcbiAgICBcbiAgICAgICAgYW5pbWF0ZVRodW1iOiBmYWxzZSxcbiAgICAgICAgYWxsb3dNZWRpYU92ZXJsYXA6IHRydWUsXG4gICAgICAgIGRvd25sb2FkOiBmYWxzZVxuICAgIH0pO1xuICAgIGlmKCRfR0VUWydwaWxvdGEnXSl7XG4gICAgICAgIFxuICAgICAgICBcbiAgICAgICAgdmFyIGFjY29yZGlvbmxpc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjYWNjb3JkaW9uRXhhbXBsZSAuYWNjb3JkaW9uLWNvbGxhcHNlJyk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWNjb3JkaW9ubGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYWNjb3JkaW9ubGlzdFtpXS5jbGFzc0xpc3QucmVtb3ZlKCdzaG93Jyk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHZhciBxdWVzdG8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjJyskX0dFVFsncGlsb3RhJ10rJyAuYWNjb3JkaW9uLWNvbGxhcHNlJyk7XG4gICAgICAgIHF1ZXN0by5jbGFzc0xpc3QuYWRkKCdzaG93Jyk7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHZhciBwb3N5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignIycrJF9HRVRbJ3BpbG90YSddKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3AgLSA4MTtcbiAgICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCBwb3N5KTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgXG4gICAgfVxuICAgIGlmKCRfR0VUWydwYWMnXSl7XG4gICAgICAgIHZhciBwb3N5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BhY2NoZXR0aScpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAtIDgxO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgcG9zeSk7XG4gICAgICAgIH0sIDEwMCk7XG4gICAgfVxuICAgIGlmKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdnb3RvJykpe1xuICAgICAgICB2Y
1XIgZ290byA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdnb3RvJyk7XG4gICAgICAgIHZhciBwb3N5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BhY2NoZXR0aScpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAtIDgxO1xuICAgICAgICBnb3RvLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCBwb3N5KTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICB9XG4gICAgXG4gICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmxpZ2h0LWdhbGxlcnknKSl7XG4gICAgICAgIHZhciBnYWxsZXJ5UGlsb3RpID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmxpZ2h0LWdhbGxlcnknKTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBnYWxsZXJ5UGlsb3RpLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGxpZ2h0R2FsbGVyeShnYWxsZXJ5UGlsb3RpW2pdLCB7XG4gICAgICAgICAgICAgICAgLy8gQWRkIGEgY3VzdG9tIGNsYXNzIHRvIGFwcGx5IHN0eWxlIG9ubHkgZm9yIHRoZSBwYXJ0aWN1bGFyIGdhbGxlcnlcbiAgICAgICAgICAgICAgICBhZGRDbGFzczogJ2xnLWN1c3RvbS10aHVtYm5haWxzJyxcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgc3RhcnRpbmcgYW5pbWF0aW9ucy5cbiAgICAgICAgICAgICAgICAvLyBUaGlzIGNhbiBiZSBkb25lIGJ5IG92ZXJyaWRpbmcgQ1NTIGFzIHdlbGxcbiAgICAgICAgICAgICAgICBhcHBlbmRUaHVtYm5haWxzVG86ICcubGctb3V0ZXInLFxuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgYW5pbWF0ZVRodW1iOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBhbGxvd01lZGlhT3ZlcmxhcDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBkb3dubG9hZDogZmFsc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN3aXBlckdQID0gbmV3IFN3aXBlcihcIi5ncFN3aXBlclwiLCB7XG4gICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAzLFxuICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiA4LFxuICAgICAgICAgICAgZnJlZU1vZGU6IHRydWUsXG4gICAgICAgICAgICBzY3JvbGxiYXI6IHtcbiAgICAgICAgICAgICAgICBlbDogJy5zd2lwZXItc2Nyb2xsYmFyJyxcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGU6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgfVxuICAgIFxuICAgIFxuICAgICAgaWYoISFkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucmlnYSAuZGF0ZScpKXtcbiAgICAgICAgdmFyIHJpZ2hlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnJpZ2EgLmRhdGUnKTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCByaWdoZS5sZW5ndGg7ICsraikge1xuICAgICAgICAgICAgdmFyIHRleHQgPSByaWdoZVtqXS5pbm5lckhUTUw7XG4gICAgICAgICAgICB2Y
1XIgb2xkX2h0bWwgPSB0ZXh0LnNwbGl0KFwiIFwiKTtcbiAgICAgICAgICAgIHZhciBuZXdfaHRtbCA9IFwiXCI7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2xkX2h0bWwubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBuZXdfaHRtbCA9IG5ld19odG1sICsgXCIgPHNwYW4gY2xhc3M9J3RleHQtXCIraStcIic+XCIgKyBvbGRfaHRtbFtpXSArIFwiPC9zcGFuPlwiO1xuICAgICAgICAgICAgICAgIHJpZ2hlW2pdLmlubmVySFRNTCA9IG5ld19odG1sO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGxlbmlzMiA9IG5ldyBMZW5pcyh7XG4gICAgICAgICAgICB3cmFwcGVyOiBtZW51LFxuICAgICAgICAgICAgZHVyYXRpb246IDEuMixcbiAgICAgICAgICAgIGVhc2luZzogKHQpID0+ICh0ID09PSAxID8gMSA6IDEgLSBNYXRoLnBvdygyLCAtMTAgKiB0KSksXG4gICAgICAgICAgICBkaXJlY3Rpb246IFwidmVydGljYWxcIixcbiAgICAgICAgICAgIGdlc3R1cmVEaXJlY3Rpb246IFwidmVydGljYWxcIixcbiAgICAgICAgICAgIHNtb290aDogdHJ1ZSxcbiAgICAgICAgICAgIHNtb290aFRvdWNoOiBmYWxzZSxcbiAgICAgICAgICAgIHRvdWNoTXVsdGlwbGllcjogMixcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbWVudVRvZ2dsZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgYm9keS5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgIGdzYXAudG8obWVudSwge3JpZ2h0OiBcIjBweFwiLCBkdXJhdGlvbjogLjUsIGVhc2U6IFwiZXhwby5pbk91dFwiLCBvbkNvbXBsZXRlOmZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgICAgICAgIG1lbnUuY2xhc3NMaXN0LnRvZ2dsZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgIG1lbnVUb2dnbGUucXVlcnlTZWxlY3RvcignLmxpbmUtMScpLmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICBtZW51VG9nZ2xlLnF1ZXJ5U2VsZWN0b3IoJy5saW5lLTInKS5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnKTsgXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZighYmFja2dyb3VuZC5jbGFzc0xpc3QuY29udGFpbnMoJ2FjdGl2ZScpKXtcbiAgICAgICAgICAgICAgICBnc2FwLnRvKGJhY2tncm91bmQsIHtvcGFjaXR5Oi4yLCB2aXNpYmlsaXR5OlwidmlzaWJsZVwiLGRpc3BsYXk6XCJibG9ja1wiLCBkdXJhdGlvbjogLjUsIGVhc2U6IFwiZXhwby5pbk91dFwiLCBvbkNvbXBsZXRlOmZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgIGxlbmlzLnN0b3AoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9ZWxzZXtcbiAgICAgICAgICAgICAgICBnc2FwLnRvKGJhY2tncm91bmQsIHtvcGFjaXR5OjAsIHZpc2liaWxpdHk6XCJoaWRkZW5cIixkaXNwbGF5Olwibm9uZVwiLCBkdXJhdGlvbjogLjUsIGVhc2U6IFwiZXhwby5pbk91dFwiLCBvbkNvbXBsZXRlOmZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgIGxlbmlzLnN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgfX0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgIH0pO1xuICAgICAgICBjbG9zZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgYm9keS5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgIGdzYXAudG8obWVudSwge3JpZ2h0OiBcIi00ODBweFwiLCBkdXJhdGlvbjogLjUsIGVhc2U6IFwiZXhwby5pbk91dFwiLCBvbkNvbXBsZXRlOmZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgICAgICAgIG1lbnUuY2xhc3NMaXN0LnRvZ2dsZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgIG1lbnVUb2dnbGUucXVlcnlTZWxlY3RvcignLmxpbmUtMScpLmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICBtZW51VG9nZ2xlLnF1ZXJ5U2VsZWN0b3IoJy5saW5lLTInKS5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnKTsgXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZighYmFja2dyb3VuZC5jbGFzc0xpc3QuY29udGFpbnMoJ2FjdGl2ZScpKXtcbiAgICAgICAgICAgICAgICBnc2FwLnRvKGJhY2tncm91bmQsIHtvcGFjaXR5Oi4yLCB2aXNpYmlsaXR5OlwidmlzaWJsZVwiLGRpc3BsYXk6XCJibG9ja1wiLCBkdXJhdGlvbjogLjUsIGVhc2U6IFwiZXhwby5pbk91dFwiLCBvbkNvbXBsZXRlOmZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgIGxlbmlzLnN0b3AoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9ZWxzZXtcbiAgICAgICAgICAgICAgICBnc2FwLnRvKGJhY2tncm91bmQsIHtvcGFjaXR5OjAsIGR1cmF0aW9uOiAuNSwgZWFzZTogXCJleHBvLmluT3V0XCIsIG9uQ29tcGxldGU6ZnVuY3Rpb24oKXtcbiAgICAgICAgICAgICAgICAgICAgZ3NhcC5zZXQoYmFja2dyb3VuZCx7dmlzaWJpbGl0eTpcImhpZGRlblwiLGRpc3BsYXk6XCJub25lXCJ9KTtcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgbGVuaXMuc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9fSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBiYWNrZ3JvdW5kLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbn
1REZWZhdWx0KCk7XG4gICAgICAgICAgICBib2R5LmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgZ3NhcC50byhtZW51LCB7cmlnaHQ6IFwiLTQ4MHB4XCIsIGR1cmF0aW9uOiAuNSwgZWFzZTogXCJleHBvLmluT3V0XCIsIG9uQ29tcGxldGU6ZnVuY3Rpb24oKXtcbiAgICAgICAgICAgICAgICAgICAgbWVudS5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgbWVudVRvZ2dsZS5xdWVyeVNlbGVjdG9yKCcubGluZS0xJykuY2xhc3NMaXN0LnRvZ2dsZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgIG1lbnVUb2dnbGUucXVlcnlTZWxlY3RvcignLmxpbmUtMicpLmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScpOyBcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmKCFiYWNrZ3JvdW5kLmNsYXNzTGlzdC5jb250YWlucygnYWN0aXZlJykpe1xuICAgICAgICAgICAgICAgIGdzYXAudG8oYmFja2dyb3VuZCwge29wYWNpdHk6LjIsIHZpc2liaWxpdHk6XCJ2aXNpYmxlXCIsZGlzcGxheTpcImJsb2NrXCIsIGR1cmF0aW9uOiAuNSwgZWFzZTogXCJleHBvLmluT3V0XCIsIG9uQ29tcGxldGU6ZnVuY3Rpb24oKXtcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgbGVuaXMuc3RvcCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgIGdzYXAudG8oYmFja2dyb3VuZCwge29wYWNpdHk6MCwgZHVyYXRpb246IC41LCBlYXNlOiBcImV4cG8uaW5PdXRcIiwgb25Db21wbGV0ZTpmdW5jdGlvbigpe1xuICAgICAgICAgICAgICAgICAgICBnc2FwLnNldChiYWNrZ3JvdW5kLHt2aXNpYmlsaXR5OlwiaGlkZGVuXCIsZGlzcGxheTpcIm5vbmVcIn0pO1xuICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICBsZW5pcy5zdGFydCgpO1xuICAgICAgICAgICAgICAgIH19KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmKGVsZW1lbnRvKXtcbiAgICAgICAgICAgIGxldCBsaXN0YUFubmkgPSBbLi4uZWxlbWVudG8ucXVlcnlTZWxlY3RvckFsbCgnLm9sZFN0YWdpb25lIHVsIGxpIGEnKV07XG4gICAgICAgICAgICBsaXN0YUFubmkuZm9yRWFjaCggZWxlbSA9PiB7XG4gICAgICAgICAgICAgICAgZWxlbS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50ID0gWy4uLmVsZW1lbnRvLnF1ZXJ5U2VsZWN0b3JBbGwoJy5vbGRTdGFnaW9uZSB1bCBsaScpXTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudC5mb3JFYWNoKCBlbCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKCdjdXJyZW50Jyk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBlLnRhcmdldC5jbG9zZXN0KCdsaScpLmNsYXNzTGlzdC5hZGQoJ2N1cnJlbnQnKTtcbiAgICAgICAgICAgICAgICAgICAgaWYoZS50YXJnZXQuaW5uZXJIVE1MID09ICcyMDI2Jyl7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0ICsgXCIvY2xhc3NpZmljaGVcIjsgIFxuICAgICAgICAgICAgICAgICAgICB9ZWxzZXtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXdVUkwgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgKyBcIi8vXCIgKyB3aW5kb3cubG9jYXRpb24uaG9zdCArIFwiL3dwLWNvbnRlbnQvdGhlbWVzL3BjY2kyMDIzL2luY2x1ZGUvYWpheC1jbGFzc2lmaWNoZS5waHBcIjtcbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHVybDogbmV3VVJMLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5ubzogZS50YXJnZXQuaW5uZXJIVE1MXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlU2VuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi50b3BiYXIzXCIpLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5yaXN1bHRhdGlcIikuaW5uZXJIVE1MID0gJzxkaXYgaWQ9XCJjc3Nsb2FkLXdyYXBwZXJcIj48ZGl2IGNsYXNzPVwiY3NzbG9hZC1sb2FkZXJcIj48ZGl2IGNsYXNzPVwiY3NzbG9hZC1saW5lXCI+PC9kaXY+IDxkaXYgY2xhc3M9XCJjc3Nsb2FkLWxpbmVcIj48L2Rpdj48ZGl2IGNsYXNzPVwiY3NzbG9hZC1saW5lXCI+PC9kaXY+PGRpdiBjbGFzcz1cImNzc2xvYWQtbGluZVwiPjwvZGl2PjxkaXYgY2xhc3M9XCJjc3Nsb2FkLWxpbmVcIj48L2Rpdj48ZGl2IGNsYXNzPVwiY3NzbG9hZC1saW5lXCI+PC9kaXY+PGRpdiBjbGFzcz1cImNzc2xvYWQtc3VibGluZVwiPjwvZGl2PjxkaXYgY2xhc3M9XCJjc3Nsb2FkLXN1YmxpbmVcIj48L2Rpdj48ZGl2IGNsYXNzPVwiY3NzbG9hZC1zdWJsaW5lXCI+PC9kaXY+PGRpdiBjbGFzcz1cImNzc2xvYWQtc3VibGluZVwiPjwvZGl2PjxkaXYgY2xhc3M9XCJjc3Nsb2FkLXN1YmxpbmVcIj48L2Rpdj48ZGl2IGNsYXNzPVwiY3NzbG9hZC1sb2FkZXItY2lyY2xlLTFcIj48ZGl2IGNsYXNzPVwiY3NzbG9hZC1sb2FkZXItY2lyY2xlLTJcIj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPVwiY3NzbG9hZC1uZWVkbGVcIj48L2Rpdj48ZGl2IGNsYXNzPVwiY3NzbG9hZC1sb2FkaW5nXCI+bG9hZGluZzwvZGl2PjwvZGl2PjwvZGl2Pic7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpcGVyNy5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIucmlzdWx0YXRpXCIpLmlubmVySFRNTCA9ICcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgI
1HZhciBhID0galF1ZXJ5LnBhcnNlSlNPTihlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKmEubGlzdGEuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbG9yZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoaXRlbSA9PSAnYXNzb2x1dGEnKXsgdmFsb3JlID0gXCJBc3NvbHV0YVwifTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoaXRlbSA9PSAnbWljaGVsaW4nKXsgdmFsb3JlID0gXCJNaWNoZWxpbiBDdXBcIn07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGl0ZW0gPT0gJ3NpbHZlcicpeyB2YWxvcmUgPSBcIlNpbHZlclwifTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoaXRlbSA9PSAnY2xhc3NlJyl7IHZhbG9yZSA9IFwiQ2xhc3NlIE1ZJzA3XCJ9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihpdGVtID09ICd0ZWFtcycpeyB2YWxvcmUgPSBcIlRlYW1cIn07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGluZGV4ID09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIudG9wYmFyM1wiKS5pbm5lckhUTUwgKz0gXCI8YSBocmVmPSdcIiArIGluZGV4ICsgXCInIGNsYXNzPSdhY3RpdmUnPlwiICsgdmFsb3JlICsgXCI8L2E+XCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi50b3BiYXIzXCIpLmlubmVySFRNTCArPSBcIjxhIGhyZWY9J1wiICsgaW5kZXggKyBcIic+XCIgKyB2YWxvcmUgKyBcIjwvYT5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjY2xhc3NpZmljaGUgLmxhYmVsXCIpLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIucmlzdWx0YXRpXCIpLmlubmVySFRNTCArPSBhLmNsYXNzaWZpY2E7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpcGVyNyA9IG5ldyBTd2lwZXIoXCIuY1N3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdDogJ2ZhZGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRvSGVpZ2h0OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWRlRWZmZWN0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcm9zc0ZhZGU6IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0b3BiYXIzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnRvcGJhcjMgYScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9wYmFyMy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3BiYXIzW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2lwZXI3LnNsaWRlVG8oZXZlbnQudGFyZ2V0LmdldEF0dHJpYnV0ZSgnaHJlZicpLCAzNTAsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC50YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXBlcjcub24oJ3NsaWRlQ2hhbmdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcGJhcjMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIFxufSk7XG5cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwgY2hlY2tyZXNpemUpO1xuZnVuY3Rpb24gY2hlY2tyZXNpemUoKXtcbiAgICBtbSA9IGdzYXAubWF0Y2hNZWRpYSgpO1xuICAgIG1tLmFkZChcIihtaW4td2lkdGg6IDE2MDBweClcIiwgKCkgPT4ge1xuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubXlTd2lwZXInKSl7XG4gICAgICAgICAgICBpZihzd2lwZXIpe3N3aXBlci5kZXN0cm95KCk7fSBcbiAgICAgICAgICAgIHN3aXBlciA9IG5ldyBTd2lwZXIoXCIubXlTd2lwZXJcIiwge1xuICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDIuNCxcbiAgICAgICAgICAgICAgICBncmFiQ3Vyc29yOiB0cnVlLFxuICAgICAgICAgICAgICAgI
1HNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICB9XG4gICAgICAgIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5uZXdzU3dpcGVyJykpe1xuICAgICAgICAgICAgaWYoc3dpcGVyMyl7c3dpcGVyMy5kZXN0cm95KCk7fSBcbiAgICAgICAgICAgIHN3aXBlcjMgPSBuZXcgU3dpcGVyKFwiLm5ld3NTd2lwZXJcIiwge1xuICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDQsXG4gICAgICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiAzMixcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5hdmlnYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgbmV4dEVsOiBcIi5zd2lwZXItYnV0dG9uLW5leHRcIixcbiAgICAgICAgICAgICAgICAgICAgcHJldkVsOiBcIi5zd2lwZXItYnV0dG9uLXByZXZcIixcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY2FtcFN3aXBlcicpKXtcbiAgICAgICAgICAgIHZhciBsYWJlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jYW1wU3dpcGVyIC5hY3RpdmUnKS5nZXRBdHRyaWJ1dGUoJ2RhdGEtc3JjJyk7XG4gICAgICAgICAgICBpZihzd2lwZXI1KXtzd2lwZXI1LmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyNSA9IG5ldyBTd2lwZXIoXCIuY2FtcFN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogNSxcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDMyLFxuICAgICAgICAgICAgICAgIGluaXRpYWxTbGlkZTogbGFiZWwsXG4gICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBuYXZpZ2F0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgIG5leHRFbDogXCIuc3dpcGVyLWJ1dHRvbi1uZXh0XCIsXG4gICAgICAgICAgICAgICAgICAgIHByZXZFbDogXCIuc3dpcGVyLWJ1dHRvbi1wcmV2XCIsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmdhcmFTd2lwZXInKSl7XG4gICAgICAgICAgICBpZihzd2lwZXI2KXtzd2lwZXI2LmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyNiA9IG5ldyBTd2lwZXIoXCIuZ2FyYVN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMSxcbiAgICAgICAgICAgICAgICBhdXRvSGVpZ2h0OiB0cnVlLFxuICAgICAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDAsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgICAgICB2Y
1XIgdG9wYmFyMiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy50b3BiYXIyIGEnKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9wYmFyMi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHRvcGJhcjJbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpcGVyNi5zbGlkZVRvKGV2ZW50LnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSwgMzUwLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC50YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3dpcGVyNi5vbignc2xpZGVDaGFuZ2UnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICB0b3BiYXIyLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudGVhbVN3aXBlcicpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcjgpe3N3aXBlcjguZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXI4ID0gbmV3IFN3aXBlcihcIi50ZWFtU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiA1LFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBuYXZpZ2F0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgIG5leHRFbDogXCIuc3dpcGVyLWJ1dHRvbi1uZXh0XCIsXG4gICAgICAgICAgICAgICAgICAgIHByZXZFbDogXCIuc3dpcGVyLWJ1dHRvbi1wcmV2XCIsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNsYVN3aXBlcicpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcjIpe3N3aXBlcjIuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXIyID0gbmV3IFN3aXBlcihcIi5jbGFTd2lwZXJcIiwge1xuICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDIsXG4gICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRvcGJhciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy50b3BiYXIgYScpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b3BiYXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0b3BiYXJbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpcGVyMi5zbGlkZVRvKGV2ZW50LnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSwgMzUwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnRhcmdldC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzd2lwZXIyLm9uKCdzbGlkZUNoYW5nZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgdG9wYmFyLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGFydG5lclN3aXBlcicpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcjQpe3N3aXBlcjQuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXI0ID0gbmV3IFN3aXBlcihcIi5wYXJ0bmVyU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiA2LFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBhdXRvcGxheToge1xuICAgICAgICAgICAgICAgICAgICBkZWxheTogMjUwMCxcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZU9uSW50ZXJhY3Rpb246IGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICBtbS5hZGQoXCIobWluLXdpZHRoOiAxMjgwcHgpIGFuZCAobWF4LXdpZHRoOiAxNTk5cHgpXCIsICgpID0+IHtcbiAgICAgICBcbiAgICAgICAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NsaWRlR2FyZScpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcil7c3dpcGVyLmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyID0gbmV3IFN3aXBlcihcIi5teVN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMS44LFxuICAgICAgICAgICAgICAgIGdyYWJDdXJzb3I6IHRydWUsXG4gICAgICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiAzMixcbiAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbGlkZU5ld3MnKSl7XG4gICAgICAgICAgICBpZihzd2lwZXIzKXtzd2lwZXIzLmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyMyA9IG5ldyBTd2lwZXIoXCIubmV3c1N3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMyxcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDMyLFxuICAgICAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbmF2aWdhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICBuZXh0RWw6IFwiLnN3aXBlci1idXR0b24tbmV4dFwiLFxuICAgICAgICAgICAgICAgICAgICBwcmV2RWw6IFwiLnN3aXBlci1idXR0b24tcHJldlwiLFxuICAgICAgICAgICAgICAgI
1H1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jYW1wU3dpcGVyJykpe1xuICAgICAgICAgICAgdmFyIGxhYmVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNhbXBTd2lwZXIgLmFjdGl2ZScpLmdldEF0dHJpYnV0ZSgnZGF0YS1zcmMnKTtcbiAgICAgICAgICAgIGlmKHN3aXBlcjUpe3N3aXBlcjUuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXI1ID0gbmV3IFN3aXBlcihcIi5jYW1wU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAzLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgaW5pdGlhbFNsaWRlOiBsYWJlbCxcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5hdmlnYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgbmV4dEVsOiBcIi5zd2lwZXItYnV0dG9uLW5leHRcIixcbiAgICAgICAgICAgICAgICAgICAgcHJldkVsOiBcIi5zd2lwZXItYnV0dG9uLXByZXZcIixcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2xpZGVHYXJhJykpe1xuICAgICAgICAgICAgaWYoc3dpcGVyNil7c3dpcGVyNi5kZXN0cm95KCk7fSBcbiAgICAgICAgICAgIHN3aXBlcjYgPSBuZXcgU3dpcGVyKFwiLmdhcmFTd2lwZXJcIiwge1xuICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDEsXG4gICAgICAgICAgICAgICAgYXV0b0hlaWdodDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiAwLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2Y
1XIgdG9wYmFyMiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy50b3BiYXIyIGEnKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9wYmFyMi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHRvcGJhcjJbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpcGVyNi5zbGlkZVRvKGV2ZW50LnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSwgMzUwLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC50YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3dpcGVyNi5vbignc2xpZGVDaGFuZ2UnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICB0b3BiYXIyLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2xpZGVUZWFtcycpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcjgpe3N3aXBlcjguZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXI4ID0gbmV3IFN3aXBlcihcIi50ZWFtU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAzLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBuYXZpZ2F0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgIG5leHRFbDogXCIuc3dpcGVyLWJ1dHRvbi1uZXh0XCIsXG4gICAgICAgICAgICAgICAgICAgIHByZXZFbDogXCIuc3dpcGVyLWJ1dHRvbi1wcmV2XCIsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NsaWRlQ2xhc3NpZmljaGUnKSl7XG4gICAgICAgICAgICBpZihzd2lwZXIyKXtzd2lwZXIyLmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyMiA9IG5ldyBTd2lwZXIoXCIuY2xhU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAyLFxuICAgICAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDMyLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0b3BiYXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9wYmFyIGEnKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9wYmFyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdG9wYmFyW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXBlcjIuc2xpZGVUbyhldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdocmVmJyksIDM1MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC50YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3dpcGVyMi5vbignc2xpZGVDaGFuZ2UnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIHRvcGJhci5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBub2RlLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBhcnRuZXJTd2lwZXInKSl7XG4gICAgICAgICAgICBpZihzd2lwZXI0KXtzd2lwZXI0LmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyNCA9IG5ldyBTd2lwZXIoXCIucGFydG5lclN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogNixcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDMyLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgYXV0b3BsYXk6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVsYXk6IDI1MDAsXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVPbkludGVyYWN0aW9uOiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgXG4gICAgbW0uYWRkKFwiKG1heC13aWR0aDogMTI3OXB4KSBhbmQgKG1pbi13aWR0aDogNTMzcHgpIGFuZCAob3JpZW50YXRpb246IHBvcnRyYWl0KVwiLCAoKSA9PntcbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm15U3dpcGVyJykpe1xuICAgICAgICAgICAgaWYoc3dpcGVyKXtzd2lwZXIuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXIgPSBuZXcgU3dpcGVyKFwiLm15U3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgICAgICAgIGdyYWJDdXJzb3I6IHRydWUsXG4gICAgICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiAwLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNsYVN3aXBlcicpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcjIpe3N3aXBlcjIuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXIyID0gbmV3IFN3aXBlcihcIi5jbGFTd2lwZXJcIiwge1xuICAgICAgICAgICAgICAgI
1HNsaWRlc1BlclZpZXc6IDEsXG4gICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRvcGJhciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy50b3BiYXIgYScpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b3BiYXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0b3BiYXJbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpcGVyMi5zbGlkZVRvKGV2ZW50LnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSwgMzUwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnRhcmdldC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzd2lwZXIyLm9uKCdzbGlkZUNoYW5nZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgdG9wYmFyLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubmV3c1N3aXBlcicpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcjMpe3N3aXBlcjMuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXIzID0gbmV3IFN3aXBlcihcIi5uZXdzU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAyLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBuYXZpZ2F0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgIG5leHRFbDogXCIuc3dpcGVyLWJ1dHRvbi1uZXh0XCIsXG4gICAgICAgICAgICAgICAgICAgIHByZXZFbDogXCIuc3dpcGVyLWJ1dHRvbi1wcmV2XCIsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBhcnRuZXJTd2lwZXInKSl7XG4gICAgICAgICAgICBpZihzd2lwZXI0KXtzd2lwZXI0LmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyNCA9IG5ldyBTd2lwZXIoXCIucGFydG5lclN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMyxcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDMyLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgYXV0b3BsYXk6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVsYXk6IDI1MDAsXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVPbkludGVyYWN0aW9uOiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jYW1wU3dpcGVyJykpe1xuICAgICAgICAgICAgdmFyIGxhYmVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNhbXBTd2lwZXIgLmFjdGl2ZScpLmdldEF0dHJpYnV0ZSgnZGF0YS1zcmMnKTtcbiAgICAgICAgICAgIGlmKHN3aXBlcjUpe3N3aXBlcjUuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXI1ID0gbmV3IFN3aXBlcihcIi5jYW1wU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAyLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgaW5pdGlhbFNsaWRlOiBsYWJlbCxcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5hdmlnYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgbmV4dEVsOiBcIi5zd2lwZXItYnV0dG9uLW5leHRcIixcbiAgICAgICAgICAgICAgICAgICAgcHJldkVsOiBcIi5zd2lwZXItYnV0dG9uLXByZXZcIixcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZ2FyYVN3aXBlcicpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcjYpe3N3aXBlcjYuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXI2ID0gbmV3IFN3aXBlcihcIi5nYXJhU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgICAgICAgIGF1dG9IZWlnaHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIHRvcGJhcjIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9wYmFyMiBhJyk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvcGJhcjIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0b3BiYXIyW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXBlcjYuc2xpZGVUbyhldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdocmVmJyksIDM1MCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQudGFyZ2V0LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgI
1H1cbiAgICAgICAgICAgIHN3aXBlcjYub24oJ3NsaWRlQ2hhbmdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgdG9wYmFyMi5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBub2RlLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRlYW1Td2lwZXInKSl7XG4gICAgICAgICAgICBpZihzd2lwZXI4KXtzd2lwZXI4LmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyOCA9IG5ldyBTd2lwZXIoXCIudGVhbVN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMixcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDMyLFxuICAgICAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbmF2aWdhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICBuZXh0RWw6IFwiLnN3aXBlci1idXR0b24tbmV4dFwiLFxuICAgICAgICAgICAgICAgICAgICBwcmV2RWw6IFwiLnN3aXBlci1idXR0b24tcHJldlwiLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgbW0uYWRkKFwiKG1heC13aWR0aDogMTM2NnB4KSBhbmQgKG1pbi13aWR0aDogNTMzcHgpIGFuZCAob3JpZW50YXRpb246IGxhbmRzY2FwZSlcIiwgKCkgPT57XG4gICAgICAgIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5teVN3aXBlcicpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcil7c3dpcGVyLmRlc3Ryb3koKTt9XG4gICAgICAgICAgICBzd2lwZXIgPSBuZXcgU3dpcGVyKFwiLm15U3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLjUsXG4gICAgICAgICAgICAgICAgZ3JhYkN1cnNvcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDMyLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNsYVN3aXBlcicpKXtcbiAgICAgICAgICAgICAgICBpZihzd2lwZXIyKXtzd2lwZXIyLmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgICAgIHN3aXBlcjIgPSBuZXcgU3dpcGVyKFwiLmNsYVN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDEuNSxcbiAgICAgICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDMyLFxuICAgICAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0b3BiYXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9wYmFyIGEnKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9wYmFyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdG9wYmFyW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXBlcjIuc2xpZGVUbyhldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdocmVmJyksIDM1MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC50YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN3aXBlcjIub24oJ3NsaWRlQ2hhbmdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIHRvcGJhci5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5uZXdzU3dpcGVyJykpe1xuICAgICAgICAgICAgaWYoc3dpcGVyMyl7c3dpcGVyMy5kZXN0cm95KCk7fSBcbiAgICAgICAgICAgIHN3aXBlcjMgPSBuZXcgU3dpcGVyKFwiLm5ld3NTd2lwZXJcIiwge1xuICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDIsXG4gICAgICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiAzMixcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5hdmlnYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgbmV4dEVsOiBcIi5zd2lwZXItYnV0dG9uLW5leHRcIixcbiAgICAgICAgICAgICAgICAgICAgcHJldkVsOiBcIi5zd2lwZXItYnV0dG9uLXByZXZcIixcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGFydG5lclN3aXBlcicpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcjQpe3N3aXBlcjQuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXI0ID0gbmV3IFN3aXBlcihcIi5wYXJ0bmVyU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiA1LFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMzIsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBhdXRvcGxheToge1xuICAgICAgICAgICAgICAgICAgICBkZWxheTogMjUwMCxcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZU9uSW50ZXJhY3Rpb246IGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgI
1H1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNhbXBTd2lwZXInKSl7XG4gICAgICAgICAgICB2YXIgbGFiZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY2FtcFN3aXBlciAuYWN0aXZlJykuZ2V0QXR0cmlidXRlKCdkYXRhLXNyYycpO1xuICAgICAgICAgICAgaWYoc3dpcGVyNSl7c3dpcGVyNS5kZXN0cm95KCk7fSBcbiAgICAgICAgICAgIHN3aXBlcjUgPSBuZXcgU3dpcGVyKFwiLmNhbXBTd2lwZXJcIiwge1xuICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDIsXG4gICAgICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiAzMixcbiAgICAgICAgICAgICAgICBpbml0aWFsU2xpZGU6IGxhYmVsLFxuICAgICAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbmF2aWdhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICBuZXh0RWw6IFwiLnN3aXBlci1idXR0b24tbmV4dFwiLFxuICAgICAgICAgICAgICAgICAgICBwcmV2RWw6IFwiLnN3aXBlci1idXR0b24tcHJldlwiLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5nYXJhU3dpcGVyJykpe1xuICAgICAgICAgICAgICAgIGlmKHN3aXBlcjYpe3N3aXBlcjYuZGVzdHJveSgpO30gXG4gICAgICAgICAgICAgICAgc3dpcGVyNiA9IG5ldyBTd2lwZXIoXCIuZ2FyYVN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDEsXG4gICAgICAgICAgICAgICAgICAgIGF1dG9IZWlnaHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiAwLFxuICAgICAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB2Y
1XIgdG9wYmFyMiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy50b3BiYXIyIGEnKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvcGJhcjIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdG9wYmFyMltpXS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpcGVyNi5zbGlkZVRvKGV2ZW50LnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSwgMzUwLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQudGFyZ2V0LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzd2lwZXI2Lm9uKCdzbGlkZUNoYW5nZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgdG9wYmFyMi5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy50ZWFtU3dpcGVyJykpe1xuICAgICAgICAgICAgaWYoc3dpcGVyOCl7c3dpcGVyOC5kZXN0cm95KCk7fSBcbiAgICAgICAgICAgIHN3aXBlcjggPSBuZXcgU3dpcGVyKFwiLnRlYW1Td2lwZXJcIiwge1xuICAgICAgICAgICAgICAgIHNsaWRlc1BlclZpZXc6IDIsXG4gICAgICAgICAgICAgICAgc3BhY2VCZXR3ZWVuOiAzMixcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5hdmlnYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgbmV4dEVsOiBcIi5zd2lwZXItYnV0dG9uLW5leHRcIixcbiAgICAgICAgICAgICAgICAgICAgcHJldkVsOiBcIi5zd2lwZXItYnV0dG9uLXByZXZcIixcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgbW0uYWRkKFwiKG1heC13aWR0aDogNTMycHgpIGFuZCAobWluLXdpZHRoOiAwcHgpXCIsICgpID0+e1xuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubXlTd2lwZXInKSl7XG4gICAgICAgICAgICBpZihzd2lwZXIpe3N3aXBlci5kZXN0cm95KCk7fVxuICAgICAgICAgICAgc3dpcGVyID0gbmV3IFN3aXBlcihcIi5teVN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMSxcbiAgICAgICAgICAgICAgICBncmFiQ3Vyc29yOiB0cnVlLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMTYsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY2xhU3dpcGVyJykpe1xuICAgICAgICAgICAgICAgIGlmKHN3aXBlcjIpe3N3aXBlcjIuZGVzdHJveSgpO30gXG4gICAgICAgICAgICAgICAgc3dpcGVyMiA9IG5ldyBTd2lwZXIoXCIuY2xhU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMSxcbiAgICAgICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDE2LFxuICAgICAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0b3BiYXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9wYmFyIGEnKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9wYmFyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdG9wYmFyW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXBlcjIuc2xpZGVUbyhldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdocmVmJyksIDM1MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC50YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN3aXBlcjIub24oJ3NsaWRlQ2hhbmdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIHRvcGJhci5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5uZXdzU3dpcGVyJykpe1xuICAgICAgICAgIGlmKHN3aXBlcjMpe3N3aXBlcjMuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXIzID0gbmV3IFN3aXBlcihcIi5uZXdzU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMTYsXG4gICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBuYXZpZ2F0aW9uOiB7XG4gICAgICAgICAgICAgICAgICAgIG5leHRFbDogXCIuc3dpcGVyLWJ1dHRvbi1uZXh0XCIsXG4gICAgICAgICAgICAgICAgICAgIHByZXZFbDogXCIuc3dpcGVyLWJ1dHRvbi1wcmV2XCIsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgI
1H1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBhcnRuZXJTd2lwZXInKSl7XG4gICAgICAgICAgICBpZihzd2lwZXI0KXtzd2lwZXI0LmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyNCA9IG5ldyBTd2lwZXIoXCIucGFydG5lclN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMixcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDE2LFxuICAgICAgICAgICAgICAgIGZyZWVNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgYXV0b3BsYXk6IHtcbiAgICAgICAgICAgICAgICAgICAgZGVsYXk6IDI1MDAsXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVPbkludGVyYWN0aW9uOiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jYW1wU3dpcGVyJykpe1xuICAgICAgICAgICAgdmFyIGxhYmVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNhbXBTd2lwZXIgLmFjdGl2ZScpLmdldEF0dHJpYnV0ZSgnZGF0YS1zcmMnKTtcbiAgICAgICAgICAgIGlmKHN3aXBlcjUpe3N3aXBlcjUuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXI1ID0gbmV3IFN3aXBlcihcIi5jYW1wU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMTYsXG4gICAgICAgICAgICAgICAgaW5pdGlhbFNsaWRlOiBsYWJlbCxcbiAgICAgICAgICAgICAgICBhbGxvd1RvdWNoTW92ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZnJlZU1vZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG5hdmlnYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgbmV4dEVsOiBcIi5zd2lwZXItYnV0dG9uLW5leHRcIixcbiAgICAgICAgICAgICAgICAgICAgcHJldkVsOiBcIi5zd2lwZXItYnV0dG9uLXByZXZcIixcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZ2FyYVN3aXBlcicpKXtcbiAgICAgICAgICAgIGlmKHN3aXBlcjYpe3N3aXBlcjYuZGVzdHJveSgpO30gXG4gICAgICAgICAgICBzd2lwZXI2ID0gbmV3IFN3aXBlcihcIi5nYXJhU3dpcGVyXCIsIHtcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJWaWV3OiAxLFxuICAgICAgICAgICAgICAgIGF1dG9IZWlnaHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgYWxsb3dUb3VjaE1vdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNwYWNlQmV0d2VlbjogMCxcbiAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIHRvcGJhcjIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9wYmFyMiBhJyk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvcGJhcjIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0b3BiYXIyW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXBlcjYuc2xpZGVUbyhldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdocmVmJyksIDM1MCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQudGFyZ2V0LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN3aXBlcjYub24oJ3NsaWRlQ2hhbmdlJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgdG9wYmFyMi5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBub2RlLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRlYW1Td2lwZXInKSl7XG4gICAgICAgICAgICBpZihzd2lwZXI4KXtzd2lwZXI4LmRlc3Ryb3koKTt9IFxuICAgICAgICAgICAgc3dpcGVyOCA9IG5ldyBTd2lwZXIoXCIudGVhbVN3aXBlclwiLCB7XG4gICAgICAgICAgICAgICAgc2xpZGVzUGVyVmlldzogMSxcbiAgICAgICAgICAgICAgICBzcGFjZUJldHdlZW46IDE2LFxuICAgICAgICAgICAgICAgIGFsbG93VG91Y2hNb3ZlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBmcmVlTW9kZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgbmF2aWdhdGlvbjoge1xuICAgICAgICAgICAgICAgICAgICBuZXh0RWw6IFwiLnN3aXBlci1idXR0b24tbmV4dFwiLFxuICAgICAgICAgICAgICAgICAgICBwcmV2RWw6IFwiLnN3aXBlci1idXR0b24tcHJldlwiLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSlcbiAgICBcbn0iXSwibmFtZXMiOlsiX3RvQ29uc3VtYWJsZUFycmF5IiwiYXJyIiwiX2FycmF5V2l0aG91dEhvbGVzIiwiX2l0ZXJhYmxlVG9BcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsIl9ub25JdGVyYWJsZVNwcmVhZCIsIlR5cGVFcnJvciIsIm8iLCJtaW5MZW4iLCJfYXJyYXlMaWtlVG9BcnJheSIsIm4iLCJPYmplY3QiLCJwcm90b3R5cGUiLCJ0b1N0cmluZyIsImNhbGwiLCJzbGljZSIsImNvbnN0cnVjdG9yIiwibmFtZSIsIkFycmF5IiwiZnJvbSIsInRlc3QiLCJpdGVyIiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJpc0FycmF5IiwibGVuIiwibGVuZ3RoIiwiaSIsImFycjIiLCJTd2lwZXIiLCJsaWdodEdhbGxlcnkiLCJsZ1pvb20iLCJMZW5pcyIsImdzYXAiLCJTY3JvbGxUcmlnZ2VyIiwiQ1NTUnVsZVBsdWdpbiIsIlNjcm9sbFRvUGx1Z2luIiwic3dpcGVyIiwic3dpcGVyMiIsInN3aXBlcjMiLCJzd2lwZXI0Iiwic3dpcGVyNSIsInN3aXBlcjYiLCJzd2lwZXI3Iiwic3dpcGVyOCIsInRvcGJhciIsIm1tIiwiaW1hZ2VzTG9h
1ZGVkIiwicmVxdWlyZSIsInJlZ2lzdGVyUGx1Z2luIiwiZG9jdW1lbnQiLCJhZGRFdmVudExpc3RlbmVyIiwiYmFja2dyb3VuZCIsIm1lbnVUb2dnbGUiLCJxdWVyeVNlbGVjdG9yIiwibWVudSIsImdldEVsZW1lbnRCeUlkIiwiYm9keSIsImNsb3NlIiwiZWxlbWVudG8iLCJsZW5pcyIsImR1cmF0aW9uIiwiZWFzaW5nIiwidCIsIk1hdGgiLCJwb3ciLCJkaXJlY3Rpb24iLCJnZXN0dXJlRGlyZWN0aW9uIiwic21vb3RoIiwic21vb3RoVG91Y2giLCJ0b3VjaE11bHRpcGxpZXIiLCJyYWYiLCJ0aW1lIiwibGVuaXMyIiwicmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwiJCIsImNyZWF0ZSIsInRyaWdnZXIiLCJzdGFydCIsIm9uY2UiLCJvbkVudGVyIiwic2VsZiIsIm5ld1VSTCIsIndpbmRvdyIsImxvY2F0aW9uIiwicHJvdG9jb2wiLCJob3N0IiwiYWpheCIsInR5cGUiLCJ1cmwiLCJjYWNoZSIsImRhdGEiLCJsYXN0IiwiYmVmb3JlU2VuZCIsInN1Y2Nlc3MiLCJlIiwiYSIsImpRdWVyeSIsInBhcnNlSlNPTiIsIm1hdGNoTWVkaWEiLCJwYXJ0cyIsInNlYXJjaCIsInN1YnN0ciIsInNwbGl0IiwiJF9HRVQiLCJ0ZW1wIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwicXVlcnlTdHJpbmciLCJ1cmxQYXJhbXMiLCJVUkxTZWFyY2hQYXJhbXMiLCJnZXQiLCJjaGVja3Jlc2l6ZSIsImVmZmVjdCIsImF1dG9IZWlnaHQiLCJpbml0aWFsU2xpZGUiLCJmYWRlRWZmZWN0IiwiY3Jvc3NGYWRlIiwiYWxsb3dUb3VjaE1vdmUiLCJzcGFjZUJldHdlZW4iLCJmcmVlTW9kZSIsInRvcGJhcjMiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZXZlbnQiLCJzbGlkZVRvIiwidGFyZ2V0IiwiZ2V0QXR0cmlidXRlIiwiY2xhc3NMaXN0IiwiYWRkIiwicHJldmVudERlZmF1bHQiLCJvbiIsImZvckVhY2giLCJub2RlIiwicmVtb3ZlIiwiYWRkQ2xhc3MiLCJhcHBlbmRUaHVtYm5haWxzVG8iLCJhbmltYXRlVGh1bWIiLCJhbGxvd01lZGlhT3ZlcmxhcCIsImRvd25sb2FkIiwiYWNjb3JkaW9ubGlzdCIsInF1ZXN0byIsInNldFRpbWVvdXQiLCJwb3N5IiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0IiwidG9wIiwic2Nyb2xsVG8iLCJnb3RvIiwiZ2FsbGVyeVBpbG90aSIsImoiLCJzd2lwZXJHUCIsInNsaWRlc1BlclZpZXciLCJzY3JvbGxiYXIiLCJlbCIsImRyYWdnYWJsZSIsInJpZ2hlIiwidGV4dCIsImlubmVySFRNTCIsIm9sZF9odG1sIiwibmV3X2h0bWwiLCJ3cmFwcGVyIiwidG9nZ2xlIiwidG8iLCJyaWdodCIsImVhc2UiLCJvbkNvbXBsZXRlIiwiY29udGFpbnMiLCJvcGFjaXR5IiwidmlzaWJpbGl0eSIsImRpc3BsYXkiLCJzdG9wIiwic2V0IiwibGlzdGFBbm5pIiwiZWxlbSIsImN1cnJlbnQiLCJjbG9zZXN0IiwiaHJlZiIsImFubm8iLCJkZXN0cm95IiwiY2xhc3NpZmljYSIsImdyYWJDdXJzb3IiLCJsb29wIiwibmF2aWdhdGlvbiIsIm5leHRFbCIsInByZXZFbCIsImxhYmVsIiwidG9wYmFyMiIsImF1dG9wbGF5IiwiZGVsYXkiLCJkaXNhYmxlT25JbnRlcmFjdGlvbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///151\n")},11:function(module,__unused_webpack_exports,__webpack_require__){eval("/*!\n * Bootstrap base-component.js v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n(function (global, factory) {\n true ? module.exports = factory(__webpack_require__(269), __webpack_require__(956), __webpack_require__(105), __webpack_require__(35)) :\n 0;\n})(this, (function (Data, EventHandler, Config, index_js) { 'use strict';\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n /**\n * Constants\n */\n\n const VERSION = '5.3.3';\n\n /**\n * Class definition\n */\n\n class BaseComponent extends Config {\n constructor(element, config) {\n super();\n element = index_js.getElement(element);\n if (!element) {\n return;\n }\n this._element = element;\n this._config = this._getConfig(config);\n Data.set(this._element, this.constructor.DATA_KEY, this);\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY);\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null;\n }\n }\n _queueCallback(callback, element, isAnimated = true) {\n index_js.executeAfterTransition(callback, element, isAnimated);\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n\n // Static\n static getInstance(element) {\n return Data.get(index_js.getElement(element), this.DATA_KEY);\n }\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n }\n static get VERSION() {\n return VERSION;\n }\n static get DATA_KEY() {\n return `bs.${this.NAME}`;\n }\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`;\n }\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`;\n }\n }\n\n return BaseComponent;\n\n}));\n//# sourceMappingURL=base-component.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTEuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRSxLQUE0RCw0QkFBNEIsbUJBQU8sQ0FBQyxHQUFlLEdBQUcsbUJBQU8sQ0FBQyxHQUF3QixHQUFHLG1CQUFPLENBQUMsR0FBa0IsR0FBRyxtQkFBTyxDQUFDLEVBQWlCO0F
1BQzdNLEVBQUUsQ0FDeUs7QUFDM0ssQ0FBQywyREFBMkQ7O0FBRTVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQ7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLFVBQVU7QUFDN0I7QUFDQTtBQUNBLGlCQUFpQixjQUFjO0FBQy9CO0FBQ0E7QUFDQSxnQkFBZ0IsS0FBSyxFQUFFLGVBQWU7QUFDdEM7QUFDQTs7QUFFQTs7QUFFQSxDQUFDO0FBQ0QiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvYm9vdHN0cmFwL2pzL2Rpc3QvYmFzZS1jb21wb25lbnQuanM/MzAyZCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAgKiBCb290c3RyYXAgYmFzZS1jb21wb25lbnQuanMgdjUuMy4zIChodHRwczovL2dldGJvb3RzdHJhcC5jb20vKVxuICAqIENvcHlyaWdodCAyMDExLTIwMjQgVGhlIEJvb3RzdHJhcCBBdXRob3JzIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvZ3JhcGhzL2NvbnRyaWJ1dG9ycylcbiAgKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAgKi9cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKCcuL2RvbS9kYXRhLmpzJyksIHJlcXVpcmUoJy4vZG9tL2V2ZW50LWhhbmRsZXIuanMnKSwgcmVxdWlyZSgnLi91dGlsL2NvbmZpZy5qcycpLCByZXF1aXJlKCcuL3V0aWwvaW5kZXguanMnKSkgOlxuICB0eX
1Blb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWycuL2RvbS9kYXRhJywgJy4vZG9tL2V2ZW50LWhhbmRsZXInLCAnLi91dGlsL2NvbmZpZycsICcuL3V0aWwvaW5kZXgnXSwgZmFjdG9yeSkgOlxuICAoZ2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwuQmFzZUNvbXBvbmVudCA9IGZhY3RvcnkoZ2xvYmFsLkRhdGEsIGdsb2JhbC5FdmVudEhhbmRsZXIsIGdsb2JhbC5Db25maWcsIGdsb2JhbC5JbmRleCkpO1xufSkodGhpcywgKGZ1bmN0aW9uIChEYXRhLCBFdmVudEhhbmRsZXIsIENvbmZpZywgaW5kZXhfanMpIHsgJ3VzZSBzdHJpY3QnO1xuXG4gIC8qKlxuICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgKiBCb290c3RyYXAgYmFzZS1jb21wb25lbnQuanNcbiAgICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAqL1xuXG5cbiAgLyoqXG4gICAqIENvbnN0YW50c1xuICAgKi9cblxuICBjb25zdCBWRVJTSU9OID0gJzUuMy4zJztcblxuICAvKipcbiAgICogQ2xhc3MgZGVmaW5pdGlvblxuICAgKi9cblxuICBjbGFzcyBCYXNlQ29tcG9uZW50IGV4dGVuZHMgQ29uZmlnIHtcbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICAgIHN1cGVyKCk7XG4gICAgICBlbGVtZW50ID0gaW5kZXhfanMuZ2V0RWxlbWVudChlbGVtZW50KTtcbiAgICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgIHRoaXMuX2NvbmZpZyA9IHRoaXMuX2dldENvbmZpZyhjb25maWcpO1xuICAgICAgRGF0YS5zZXQodGhpcy5fZWxlbWVudCwgdGhpcy5jb25zdHJ1Y3Rvci5EQVRBX0tFWSwgdGhpcyk7XG4gICAgfVxuXG4gICAgLy8gUHVibGljXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgIERhdGEucmVtb3ZlKHRoaXMuX2VsZW1lbnQsIHRoaXMuY29uc3RydWN0b3IuREFUQV9LRVkpO1xuICAgICAgRXZlbnRIYW5kbGVyLm9mZih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLkVWRU5UX0tFWSk7XG4gICAgICBmb3IgKGNvbnN0IHByb3BlcnR5TmFtZSBvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0aGlzKSkge1xuICAgICAgICB0aGlzW3Byb3BlcnR5TmFtZV0gPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICBfcXVldWVDYWxsYmFjayhjYWxsYmFjaywgZWxlbWVudCwgaXNBbmltYXRlZCA9IHRydWUpIHtcbiAgICAgIGluZGV4X2pzLmV4ZWN1dGVBZnRlclRyYW5zaXRpb24oY2FsbGJhY2ssIGVsZW1lbnQsIGlzQW5pbWF0ZWQpO1xuICAgIH1cbiAgICBfZ2V0Q29uZmlnKGNvbmZpZykge1xuICAgICAgY29uZmlnID0gdGhpcy5fbWVyZ2VDb25maWdPYmooY29uZmlnLCB0aGlzLl9lbGVtZW50KTtcbiAgICAgIGNvbmZpZyA9IHRoaXMuX2NvbmZpZ0FmdGVyTWVyZ2UoY29uZmlnKTtcbiAgICAgIHRoaXMuX3R5cGVDaGVja0NvbmZpZyhjb25maWcpO1xuICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICB9XG5cbiAgICAvLyBTdGF0aWNcbiAgICBzdGF0aWMgZ2V0SW5zdGFuY2UoZWxlbWVudCkge1xuICAgICAgcmV0dXJuIERhdGEuZ2V0KGluZGV4X2pzLmdldEVsZW1lbnQoZWxlbWVudCksIHRoaXMuREFUQV9LRVkpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0T3JDcmVhdGVJbnN0YW5jZShlbGVtZW50LCBjb25maWcgPSB7fSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2UoZWxlbWVudCkgfHwgbmV3IHRoaXMoZWxlbWVudCwgdHlwZW9mIGNvbmZpZyA9PT0gJ29iamVjdCcgPyBjb25maWcgOiBudWxsKTtcbiAgICB9XG4gICAgc3RhdGljIGdldCBWRVJTSU9OKCkge1xuICAgICAgcmV0dXJuIFZFUlNJT047XG4gICAgfVxuICAgIHN0YXRpYyBnZXQgREFUQV9LRVkoKSB7XG4gICAgICByZXR1cm4gYGJzLiR7dGhpcy5OQU1FfWA7XG4gICAgfVxuICAgIHN0YXRpYyBnZXQgRVZFTlRfS0VZKCkge1xuICAgICAgcmV0dXJuIGAuJHt0aGlzLkRBVEFfS0VZfWA7XG4gICAgfVxuICAgIHN0YXRpYyBldmVudE5hbWUobmFtZSkge1xuICAgICAgcmV0dXJuIGAke25hbWV9JHt0aGlzLkVWRU5UX0tFWX1gO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBCYXNlQ29tcG9uZW50O1xuXG59KSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLWNvbXBvbmVudC5qcy5tYXBcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///11\n")},647:function(module,__unused_webpack_exports,__webpack_require__){eval("/*!\n * Bootstrap collapse.js v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n(function (global, factory) {\n true ? module.exports = factory(__webpack_require__(11), __webpack_require__(956), __webpack_require__(411), __webpack_require__(35)) :\n 0;\n})(this, (function (BaseComponent, EventHandler, SelectorEngine, index_js) { 'use strict';\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n /**\n * Constants\n */\n\n const NAME = 'collapse';\n const DATA_KEY = 'bs.collapse';\n const EVENT_KEY = `.${DATA_KEY}`;\n const DATA_API_KEY = '.data-api';\n const EVENT_SHOW = `show${EVENT_KEY}`;\n const EVENT_SHOWN = `shown${EVENT_KEY}`;\n const EVENT_HIDE = `hide${EVENT_KEY}`;\n const EVENT_HIDDEN = `hidden${EVENT_KEY}`;\n const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;\n const CLASS_NAME_SHOW = 'show';\n const CLASS_NAME_COLLAPSE = 'collapse';\n const CLASS_NAME_COLLAPSING = 'collapsing';\n const CLASS_NAME_COLLAPSED = 'collapsed';\n const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;\n const CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\n const WIDTH = 'width';\n const HEIGHT = 'height';\n const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';\n const SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"collapse\"]';
1\n const Default = {\n parent: null,\n toggle: true\n };\n const DefaultType = {\n parent: '(null|element)',\n toggle: 'boolean'\n };\n\n /**\n * Class definition\n */\n\n class Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isTransitioning = false;\n this._triggerArray = [];\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE);\n for (const elem of toggleList) {\n const selector = SelectorEngine.getSelectorFromElement(elem);\n const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem);\n }\n }\n this._initializeChildren();\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n }\n if (this._config.toggle) {\n this.toggle();\n }\n }\n\n // Getters\n static get Default() {\n return Default;\n }\n static get DefaultType() {\n return DefaultType;\n }\n static get NAME() {\n return NAME;\n }\n\n // Public\n toggle() {\n if (this._isShown()) {\n this.hide();\n } else {\n this.show();\n }\n }\n show() {\n if (this._isTransitioning || this._isShown()) {\n return;\n }\n let activeChildren = [];\n\n // find active children\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {\n toggle: false\n }));\n }\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW);\n if (startEvent.defaultPrevented) {\n return;\n }\n for (const activeInstance of activeChildren) {\n activeInstance.hide();\n }\n const dimension = this._getDimension();\n this._element.classList.remove(CLASS_NAME_COLLAPSE);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.style[dimension] = 0;\n this._addAriaAndCollapsedClass(this._triggerArray, true);\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);\n this._element.style[dimension] = '';\n EventHandler.trigger(this._element, EVENT_SHOWN);\n };\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n const scrollSize = `scroll${capitalizedDimension}`;\n this._queueCallback(complete, this._element, true);\n this._element.style[dimension] = `${this._element[scrollSize]}px`;\n }\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE);\n if (startEvent.defaultPrevented) {\n return;\n }\n const dimension = this._getDimension();\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n index_js.reflow(this._element);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);\n for (const trigger of this._triggerArray) {\n const element = SelectorEngine.getElementFromSelector(trigger);\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false);\n }\n }\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE);\n EventHandler.trigger(this._element, EVENT_HIDDEN);\n };\n this._element.style[dimension] = '';\n this._queueCallback(complete, this._element, true);\n }\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW);\n }\n\n // Private\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle); // Coerce string values\n config.parent = index_js.getElement(config.parent);\n return config;\n }\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n }\n _initializeChildren() {\n if (!this._config.parent) {\n return;\n }\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE);\n for (const element of children) {\n const selected = SelectorEngine.getElementFromSelector(element);\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected));\n }\n }\n }\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);\n // remove children if greater depth\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));\n }\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return;\n }\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);\n element.setAttribute('aria-expanded', isOpen);\n }\n }\n\n // Static\n static jQueryInterface(config) {\n const _config = {};\n if (typeof config === 'string' && /show|hide/.test(config)) {\
1n _config.toggle = false;\n }\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config);\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n }\n });\n }\n }\n\n /**\n * Data API implementation\n */\n\n EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n event.preventDefault();\n }\n for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {\n Collapse.getOrCreateInstance(element, {\n toggle: false\n }).toggle();\n }\n });\n\n /**\n * jQuery\n */\n\n index_js.defineJQueryPlugin(Collapse);\n\n return Collapse;\n\n}));\n//# sourceMappingURL=collapse.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQ3LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsS0FBNEQsNEJBQTRCLG1CQUFPLENBQUMsRUFBcUIsR0FBRyxtQkFBTyxDQUFDLEdBQXdCLEdBQUcsbUJBQU8sQ0FBQyxHQUEwQixHQUFHLG1CQUFPLENBQUMsRUFBaUI7QUFDM04sRUFBRSxDQUNxTDtBQUN2TCxDQUFDLDRFQUE0RTs7QUFFN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixTQUFTO0FBQ2pDO0FBQ0EsNEJBQTRCLFVBQVU7QUFDdEMsOEJBQThCLFVBQVU7QUFDeEMsNEJBQTRCLFVBQVU7QUFDdEMsZ0NBQWdDLFVBQVU7QUFDMUMsdUNBQXVDLFVBQVUsRUFBRSxhQUFhO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELHFCQUFxQixHQUFHLG9CQUFvQjtBQUM1RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MscUJBQXFCO0FBQ3ZEO0FBQ0EsMENBQTBDLDBCQUEwQjtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxpREFBaUQ7QUFDM0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhDQUE4QztBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9ELE9BQU87QUFDM0Q7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDO0FBQ0QiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvYm9vdHN0cmFwL2pzL2Rpc3QvY29sbGFwc2UuanM/ODEwZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAgKiBCb290c3RyYXAgY29sbGFwc2UuanMgdjUuMy4zIChodHRwczovL2dldGJvb3RzdHJhcC5jb20vKVxuICAqIENvcHlyaWdodCAyMDExLTIwMjQgVGhlIEJvb3RzdHJhcCBBdXRob3JzIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvZ3JhcGhzL2NvbnRyaWJ1dG9ycylcbiAgKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAgKi9cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKCcuL2Jhc2UtY29tcG9uZW50LmpzJyksIHJlcXVpcmUoJy4vZG9tL2V2ZW50LWhhbmRsZXIuanMnKSwgcmVxdWlyZSgnLi9kb20vc2VsZWN0b3ItZW5naW5lLmpzJyksIHJlcXVpcmUoJy4vdXRpbC9pbmRleC5qcycpKSA6XG4gIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJy4vYmFzZS1jb21wb25lbnQnLCAnLi9kb20vZXZlbnQtaGFuZGxlcicsICcu
1L2RvbS9zZWxlY3Rvci1lbmdpbmUnLCAnLi91dGlsL2luZGV4J10sIGZhY3RvcnkpIDpcbiAgKGdsb2JhbCA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiBnbG9iYWwgfHwgc2VsZiwgZ2xvYmFsLkNvbGxhcHNlID0gZmFjdG9yeShnbG9iYWwuQmFzZUNvbXBvbmVudCwgZ2xvYmFsLkV2ZW50SGFuZGxlciwgZ2xvYmFsLlNlbGVjdG9yRW5naW5lLCBnbG9iYWwuSW5kZXgpKTtcbn0pKHRoaXMsIChmdW5jdGlvbiAoQmFzZUNvbXBvbmVudCwgRXZlbnRIYW5kbGVyLCBTZWxlY3RvckVuZ2luZSwgaW5kZXhfanMpIHsgJ3VzZSBzdHJpY3QnO1xuXG4gIC8qKlxuICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgKiBCb290c3RyYXAgY29sbGFwc2UuanNcbiAgICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAqL1xuXG5cbiAgLyoqXG4gICAqIENvbnN0YW50c1xuICAgKi9cblxuICBjb25zdCBOQU1FID0gJ2NvbGxhcHNlJztcbiAgY29uc3QgREFUQV9LRVkgPSAnYnMuY29sbGFwc2UnO1xuICBjb25zdCBFVkVOVF9LRVkgPSBgLiR7REFUQV9LRVl9YDtcbiAgY29uc3QgREFUQV9BUElfS0VZID0gJy5kYXRhLWFwaSc7XG4gIGNvbnN0IEVWRU5UX1NIT1cgPSBgc2hvdyR7RVZFTlRfS0VZfWA7XG4gIGNvbnN0IEVWRU5UX1NIT1dOID0gYHNob3duJHtFVkVOVF9LRVl9YDtcbiAgY29uc3QgRVZFTlRfSElERSA9IGBoaWRlJHtFVkVOVF9LRVl9YDtcbiAgY29uc3QgRVZFTlRfSElEREVOID0gYGhpZGRlbiR7RVZFTlRfS0VZfWA7XG4gIGNvbnN0IEVWRU5UX0NMSUNLX0RBVEFfQVBJID0gYGNsaWNrJHtFVkVOVF9LRVl9JHtEQVRBX0FQSV9LRVl9YDtcbiAgY29uc3QgQ0xBU1NfTkFNRV9TSE9XID0gJ3Nob3cnO1xuICBjb25zdCBDTEFTU19OQU1FX0NPTExBUFNFID0gJ2NvbGxhcHNlJztcbiAgY29uc3QgQ0xBU1NfTkFNRV9DT0xMQVBTSU5HID0gJ2NvbGxhcHNpbmcnO1xuICBjb25zdCBDTEFTU19OQU1FX0NPTExBUFNFRCA9ICdjb2xsYXBzZWQnO1xuICBjb25zdCBDTEFTU19OQU1FX0RFRVBFUl9DSElMRFJFTiA9IGA6c2NvcGUgLiR7Q0xBU1NfTkFNRV9DT0xMQVBTRX0gLiR7Q0xBU1NfTkFNRV9DT0xMQVBTRX1gO1xuICBjb25zdCBDTEFTU19OQU1FX0hPUklaT05UQUwgPSAnY29sbGFwc2UtaG9yaXpvbnRhbCc7XG4gIGNvbnN0IFdJRFRIID0gJ3dpZHRoJztcbiAgY29uc3QgSEVJR0hUID0gJ2hlaWdodCc7XG4gIGNvbnN0IFNFTEVDVE9SX0FDVElWRVMgPSAnLmNvbGxhcHNlLnNob3csIC5jb2xsYXBzZS5jb2xsYXBzaW5nJztcbiAgY29uc3QgU0VMRUNUT1JfREFUQV9UT0dHTEUgPSAnW2RhdGEtYnMtdG9nZ2xlPVwiY29sbGFwc2VcIl0nO1xuICBjb25zdCBEZWZhdWx0ID0ge1xuICAgIHBhcmVudDogbnVsbCxcbiAgICB0b2dnbGU6IHRydWVcbiAgfTtcbiAgY29uc3QgRGVmYXVsdFR5cGUgPSB7XG4gICAgcGFyZW50OiAnKG51bGx8ZWxlbWVudCknLFxuICAgIHRvZ2dsZTogJ2Jvb2xlYW4nXG4gIH07XG5cbiAgLyoqXG4gICAqIENsYXNzIGRlZmluaXRpb25cbiAgICovXG5cbiAgY2xhc3MgQ29sbGFwc2UgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICAgIHN1cGVyKGVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICB0aGlzLl9pc1RyYW5zaXRpb25pbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuX3RyaWdnZXJBcnJheSA9IFtdO1xuICAgICAgY29uc3QgdG9nZ2xlTGlzdCA9IFNlbGVjdG9yRW5naW5lLmZpbmQoU0VMRUNUT1JfREFUQV9UT0dHTEUpO1xuICAgICAgZm9yIChjb25zdCBlbGVtIG9mIHRvZ2dsZUxpc3QpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0b3IgPSBTZWxlY3RvckVuZ2luZS5nZXRTZWxlY3RvckZyb21FbGVtZW50KGVsZW0pO1xuICAgICAgICBjb25zdCBmaWx0ZXJFbGVtZW50ID0gU2VsZWN0b3JFbmdpbmUuZmluZChzZWxlY3RvcikuZmlsdGVyKGZvdW5kRWxlbWVudCA9PiBmb3VuZEVsZW1lbnQgPT09IHRoaXMuX2VsZW1lbnQpO1xuICAgICAgICBpZiAoc2VsZWN0b3IgIT09IG51bGwgJiYgZmlsdGVyRWxlbWVudC5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLl90cmlnZ2VyQXJyYXkucHVzaChlbGVtKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5faW5pdGlhbGl6ZUNoaWxkcmVuKCk7XG4gICAgICBpZiAoIXRoaXMuX2NvbmZpZy5wYXJlbnQpIHtcbiAgICAgICAgdGhpcy5fYWRkQXJpYUFuZENvbGxhcHNlZENsYXNzKHRoaXMuX3RyaWdnZXJBcnJheSwgdGhpcy5faXNTaG93bigpKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9jb25maWcudG9nZ2xlKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gR2V0dGVyc1xuICAgIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICAgIHJldHVybiBEZWZhdWx0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgICAgcmV0dXJuIERlZmF1bHRUeXBlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgICByZXR1cm4gTkFNRTtcbiAgICB9XG5cbiAgICAvLyBQdWJsaWNcbiAgICB0b2dnbGUoKSB7XG4gICAgICBpZiAodGhpcy5faXNTaG93bigpKSB7XG4gICAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zaG93KCk7XG4gICAgICB9XG4gICAgfVxuICAgIHNob3coKSB7XG4gICAgICBpZiAodGhpcy5faXNUcmFuc2l0aW9uaW5nIHx8IHRoaXMuX2lzU2hvd24oKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsZXQgYWN0aXZlQ2hpbGRyZW4gPSBbXTtcblxuICAgICAgLy8gZmluZCBhY3RpdmUgY2hpbGRyZW5cbiAgICAgIGlmICh0aGlzLl9jb25maWcucGFyZW50KSB7XG4gICAgICAgIGFjdGl2ZUNoaWxkcmVuID0gdGhpcy5fZ2V0Rmlyc3RMZXZlbENoaWxkcmVuKFNFTEVDVE9SX0FDVElWRVMpLmZpbHRlcihlbGVtZW50ID0+IGVsZW1lbnQgIT09IHRoaXMuX2VsZW1lbnQpLm1hcChlbGVtZW50ID0+IENvbGxhcHNlLmdldE9yQ3JlYXRlSW5zdGFuY2UoZWxlbWVudCwge1xuICAgICAgICAgI
1HRvZ2dsZTogZmFsc2VcbiAgICAgICAgfSkpO1xuICAgICAgfVxuICAgICAgaWYgKGFjdGl2ZUNoaWxkcmVuLmxlbmd0aCAmJiBhY3RpdmVDaGlsZHJlblswXS5faXNUcmFuc2l0aW9uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXJ0RXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9TSE9XKTtcbiAgICAgIGlmIChzdGFydEV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBhY3RpdmVJbnN0YW5jZSBvZiBhY3RpdmVDaGlsZHJlbikge1xuICAgICAgICBhY3RpdmVJbnN0YW5jZS5oaWRlKCk7XG4gICAgICB9XG4gICAgICBjb25zdCBkaW1lbnNpb24gPSB0aGlzLl9nZXREaW1lbnNpb24oKTtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0NPTExBUFNFKTtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0NPTExBUFNJTkcpO1xuICAgICAgdGhpcy5fZWxlbWVudC5zdHlsZVtkaW1lbnNpb25dID0gMDtcbiAgICAgIHRoaXMuX2FkZEFyaWFBbmRDb2xsYXBzZWRDbGFzcyh0aGlzLl90cmlnZ2VyQXJyYXksIHRydWUpO1xuICAgICAgdGhpcy5faXNUcmFuc2l0aW9uaW5nID0gdHJ1ZTtcbiAgICAgIGNvbnN0IGNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgICB0aGlzLl9pc1RyYW5zaXRpb25pbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfQ09MTEFQU0lORyk7XG4gICAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0NPTExBUFNFLCBDTEFTU19OQU1FX1NIT1cpO1xuICAgICAgICB0aGlzLl9lbGVtZW50LnN0eWxlW2RpbWVuc2lvbl0gPSAnJztcbiAgICAgICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfU0hPV04pO1xuICAgICAgfTtcbiAgICAgIGNvbnN0IGNhcGl0YWxpemVkRGltZW5zaW9uID0gZGltZW5zaW9uWzBdLnRvVXBwZXJDYXNlKCkgKyBkaW1lbnNpb24uc2xpY2UoMSk7XG4gICAgICBjb25zdCBzY3JvbGxTaXplID0gYHNjcm9sbCR7Y2FwaXRhbGl6ZWREaW1lbnNpb259YDtcbiAgICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGUsIHRoaXMuX2VsZW1lbnQsIHRydWUpO1xuICAgICAgdGhpcy5fZWxlbWVudC5zdHlsZVtkaW1lbnNpb25dID0gYCR7dGhpcy5fZWxlbWVudFtzY3JvbGxTaXplXX1weGA7XG4gICAgfVxuICAgIGhpZGUoKSB7XG4gICAgICBpZiAodGhpcy5faXNUcmFuc2l0aW9uaW5nIHx8ICF0aGlzLl9pc1Nob3duKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhcnRFdmVudCA9IEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX0hJREUpO1xuICAgICAgaWYgKHN0YXJ0RXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBkaW1lbnNpb24gPSB0aGlzLl9nZXREaW1lbnNpb24oKTtcbiAgICAgIHRoaXMuX2VsZW1lbnQuc3R5bGVbZGltZW5zaW9uXSA9IGAke3RoaXMuX2VsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClbZGltZW5zaW9uXX1weGA7XG4gICAgICBpbmRleF9qcy5yZWZsb3codGhpcy5fZWxlbWVudCk7XG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9DT0xMQVBTSU5HKTtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0NPTExBUFNFLCBDTEFTU19OQU1FX1NIT1cpO1xuICAgICAgZm9yIChjb25zdCB0cmlnZ2VyIG9mIHRoaXMuX3RyaWdnZXJBcnJheSkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gU2VsZWN0b3JFbmdpbmUuZ2V0RWxlbWVudEZyb21TZWxlY3Rvcih0cmlnZ2VyKTtcbiAgICAgICAgaWYgKGVsZW1lbnQgJiYgIXRoaXMuX2lzU2hvd24oZWxlbWVudCkpIHtcbiAgICAgICAgICB0aGlzLl9hZGRBcmlhQW5kQ29sbGFwc2VkQ2xhc3MoW3RyaWdnZXJdLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuX2lzVHJhbnNpdGlvbmluZyA9IHRydWU7XG4gICAgICBjb25zdCBjb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5faXNUcmFuc2l0aW9uaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0NPTExBUFNJTkcpO1xuICAgICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9DT0xMQVBTRSk7XG4gICAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX0hJRERFTik7XG4gICAgICB9O1xuICAgICAgdGhpcy5fZWxlbWVudC5zdHlsZVtkaW1lbnNpb25dID0gJyc7XG4gICAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlLCB0aGlzLl9lbGVtZW50LCB0cnVlKTtcbiAgICB9XG4gICAgX2lzU2hvd24oZWxlbWVudCA9IHRoaXMuX2VsZW1lbnQpIHtcbiAgICAgIHJldHVybiBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX1NIT1cpO1xuICAgIH1cblxuICAgIC8vIFByaXZhdGVcbiAgICBfY29uZmlnQWZ0ZXJNZXJnZShjb25maWcpIHtcbiAgICAgIGNvbmZpZy50b2dnbGUgPSBCb29sZWFuKGNvbmZpZy50b2dnbGUpOyAvLyBDb2VyY2Ugc3RyaW5nIHZhbHVlc1xuICAgICAgY29uZmlnLnBhcmVudCA9IGluZGV4X2pzLmdldEVsZW1lbnQoY29uZmlnLnBhcmVudCk7XG4gICAgICByZXR1cm4gY29uZmlnO1xuICAgIH1cbiAgICBfZ2V0RGltZW5zaW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfSE9SSVpPTlRBTCkgPyBXSURUSCA6IEhFSUdIVDtcbiAgICB9XG4gICAgX2luaXRpYWxpemVDaGlsZHJlbigpIHtcbiAgICAgIGlmICghdGhpcy5fY29uZmlnLnBhcmVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuX2dldEZpcnN0TGV2ZWxDaGlsZHJlbihTRUxFQ1RPUl9EQVRBX1RPR0dMRSk7XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgY2hpbGRyZW4pIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWQgPSBTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKGVsZW1lbnQpO1xuICAgICAgICBpZiAoc2VsZWN0ZWQpIHtcbiAgICAgICAgICB0aGlzLl9hZGRBcmlhQW5kQ29sbGFwc2VkQ2xhc3MoW2VsZW1lbnRdLCB0aGlzLl9pc1Nob3duKHNlbGVjdGVkKSk7XG4gICAgICAgI
1H1cbiAgICAgIH1cbiAgICB9XG4gICAgX2dldEZpcnN0TGV2ZWxDaGlsZHJlbihzZWxlY3Rvcikge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSBTZWxlY3RvckVuZ2luZS5maW5kKENMQVNTX05BTUVfREVFUEVSX0NISUxEUkVOLCB0aGlzLl9jb25maWcucGFyZW50KTtcbiAgICAgIC8vIHJlbW92ZSBjaGlsZHJlbiBpZiBncmVhdGVyIGRlcHRoXG4gICAgICByZXR1cm4gU2VsZWN0b3JFbmdpbmUuZmluZChzZWxlY3RvciwgdGhpcy5fY29uZmlnLnBhcmVudCkuZmlsdGVyKGVsZW1lbnQgPT4gIWNoaWxkcmVuLmluY2x1ZGVzKGVsZW1lbnQpKTtcbiAgICB9XG4gICAgX2FkZEFyaWFBbmRDb2xsYXBzZWRDbGFzcyh0cmlnZ2VyQXJyYXksIGlzT3Blbikge1xuICAgICAgaWYgKCF0cmlnZ2VyQXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiB0cmlnZ2VyQXJyYXkpIHtcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKENMQVNTX05BTUVfQ09MTEFQU0VELCAhaXNPcGVuKTtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCBpc09wZW4pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFN0YXRpY1xuICAgIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgICBjb25zdCBfY29uZmlnID0ge307XG4gICAgICBpZiAodHlwZW9mIGNvbmZpZyA9PT0gJ3N0cmluZycgJiYgL3Nob3d8aGlkZS8udGVzdChjb25maWcpKSB7XG4gICAgICAgIF9jb25maWcudG9nZ2xlID0gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IENvbGxhcHNlLmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcywgX2NvbmZpZyk7XG4gICAgICAgIGlmICh0eXBlb2YgY29uZmlnID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGlmICh0eXBlb2YgZGF0YVtjb25maWddID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgTm8gbWV0aG9kIG5hbWVkIFwiJHtjb25maWd9XCJgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGF0YVtjb25maWddKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEYXRhIEFQSSBpbXBsZW1lbnRhdGlvblxuICAgKi9cblxuICBFdmVudEhhbmRsZXIub24oZG9jdW1lbnQsIEVWRU5UX0NMSUNLX0RBVEFfQVBJLCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSwgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gcHJldmVudERlZmF1bHQgb25seSBmb3IgPGE+IGVsZW1lbnRzICh3aGljaCBjaGFuZ2UgdGhlIFVSTCkgbm90IGluc2lkZSB0aGUgY29sbGFwc2libGUgZWxlbWVudFxuICAgIGlmIChldmVudC50YXJnZXQudGFnTmFtZSA9PT0gJ0EnIHx8IGV2ZW50LmRlbGVnYXRlVGFyZ2V0ICYmIGV2ZW50LmRlbGVnYXRlVGFyZ2V0LnRhZ05hbWUgPT09ICdBJykge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIFNlbGVjdG9yRW5naW5lLmdldE11bHRpcGxlRWxlbWVudHNGcm9tU2VsZWN0b3IodGhpcykpIHtcbiAgICAgIENvbGxhcHNlLmdldE9yQ3JlYXRlSW5zdGFuY2UoZWxlbWVudCwge1xuICAgICAgICB0b2dnbGU6IGZhbHNlXG4gICAgICB9KS50b2dnbGUoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBqUXVlcnlcbiAgICovXG5cbiAgaW5kZXhfanMuZGVmaW5lSlF1ZXJ5UGx1Z2luKENvbGxhcHNlKTtcblxuICByZXR1cm4gQ29sbGFwc2U7XG5cbn0pKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbGxhcHNlLmpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///647\n")},269:function(module){eval("/*!\n * Bootstrap data.js v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n(function (global, factory) {\n true ? module.exports = factory() :\n 0;\n})(this, (function () { 'use strict';\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n /**\n * Constants\n */\n\n const elementMap = new Map();\n const data = {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map());\n }\n const instanceMap = elementMap.get(element);\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n return;\n }\n instanceMap.set(key, instance);\n },\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null;\n }\n return null;\n },\n remove(element, key) {\n if (!elementMap.has(element)) {\n return;\n }\n const instanceMap = elementMap.get(element);\n instanceMap.delete(key);\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element);\n }\n }\n };\n\n return data;\n\n}));\n//# sourceMappingURL=data.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjY5LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsS0FBNEQ7QUFDOUQsRUFBRSxDQUNtRztBQUNyRyxDQUFDLHVCQUF1Qjs7QUFFeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFHQUFxRyxrQ0FBa0M7QUFDdkk7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDO0FBQ0QiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvYm9vdHN0cmFwL2pzL2Rpc3QvZG9tL2RhdGEuanM/NmVlMSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAgKiBCb290c3RyYXAgZGF0YS5qcyB2NS4zLjMgKGh0dHBzOi8vZ2V0Ym9vdHN0cmFwLmNvbS8pXG4gICogQ29weXJpZ2h0IDIwMTEtMjAyNCBUaGUgQm9vdHN0cmFwIEF1dGhvcnMgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ncmFwaHMvY29udHJpYnV0b3JzKVxuICAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICAqL1xuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuICB0eX
1Blb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuICAoZ2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwuRGF0YSA9IGZhY3RvcnkoKSk7XG59KSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cbiAgLyoqXG4gICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAqIEJvb3RzdHJhcCBkb20vZGF0YS5qc1xuICAgKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICovXG5cbiAgLyoqXG4gICAqIENvbnN0YW50c1xuICAgKi9cblxuICBjb25zdCBlbGVtZW50TWFwID0gbmV3IE1hcCgpO1xuICBjb25zdCBkYXRhID0ge1xuICAgIHNldChlbGVtZW50LCBrZXksIGluc3RhbmNlKSB7XG4gICAgICBpZiAoIWVsZW1lbnRNYXAuaGFzKGVsZW1lbnQpKSB7XG4gICAgICAgIGVsZW1lbnRNYXAuc2V0KGVsZW1lbnQsIG5ldyBNYXAoKSk7XG4gICAgICB9XG4gICAgICBjb25zdCBpbnN0YW5jZU1hcCA9IGVsZW1lbnRNYXAuZ2V0KGVsZW1lbnQpO1xuXG4gICAgICAvLyBtYWtlIGl0IGNsZWFyIHdlIG9ubHkgd2FudCBvbmUgaW5zdGFuY2UgcGVyIGVsZW1lbnRcbiAgICAgIC8vIGNhbiBiZSByZW1vdmVkIGxhdGVyIHdoZW4gbXVsdGlwbGUga2V5L2luc3RhbmNlcyBhcmUgZmluZSB0byBiZSB1c2VkXG4gICAgICBpZiAoIWluc3RhbmNlTWFwLmhhcyhrZXkpICYmIGluc3RhbmNlTWFwLnNpemUgIT09IDApIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgY29uc29sZS5lcnJvcihgQm9vdHN0cmFwIGRvZXNuJ3QgYWxsb3cgbW9yZSB0aGFuIG9uZSBpbnN0YW5jZSBwZXIgZWxlbWVudC4gQm91bmQgaW5zdGFuY2U6ICR7QXJyYXkuZnJvbShpbnN0YW5jZU1hcC5rZXlzKCkpWzBdfS5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaW5zdGFuY2VNYXAuc2V0KGtleSwgaW5zdGFuY2UpO1xuICAgIH0sXG4gICAgZ2V0KGVsZW1lbnQsIGtleSkge1xuICAgICAgaWYgKGVsZW1lbnRNYXAuaGFzKGVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybiBlbGVtZW50TWFwLmdldChlbGVtZW50KS5nZXQoa2V5KSB8fCBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICByZW1vdmUoZWxlbWVudCwga2V5KSB7XG4gICAgICBpZiAoIWVsZW1lbnRNYXAuaGFzKGVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGluc3RhbmNlTWFwID0gZWxlbWVudE1hcC5nZXQoZWxlbWVudCk7XG4gICAgICBpbnN0YW5jZU1hcC5kZWxldGUoa2V5KTtcblxuICAgICAgLy8gZnJlZSB1cCBlbGVtZW50IHJlZmVyZW5jZXMgaWYgdGhlcmUgYXJlIG5vIGluc3RhbmNlcyBsZWZ0IGZvciBhbiBlbGVtZW50XG4gICAgICBpZiAoaW5zdGFuY2VNYXAuc2l6ZSA9PT0gMCkge1xuICAgICAgICBlbGVtZW50TWFwLmRlbGV0ZShlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGRhdGE7XG5cbn0pKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGEuanMubWFwXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///269\n")},956:function(module,__unused_webpack_exports,__webpack_require__){eval("/*!\n * Bootstrap event-handler.js v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n(function (global, factory) {\n true ? module.exports = factory(__webpack_require__(35)) :\n 0;\n})(this, (function (index_js) { 'use strict';\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n /**\n * Constants\n */\n\n const namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\n const stripNameRegex = /\\..*/;\n const stripUidRegex = /::\\d+$/;\n const eventRegistry = {}; // Events storage\n let uidEvent = 1;\n const customEvents = {\n mouseenter: 'mouseover',\n mouseleave: 'mouseout'\n };\n const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);\n\n /**\n * Private methods\n */\n\n function makeEventUid(element, uid) {\n return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n }\n function getElementEvents(element) {\n const uid = makeEventUid(element);\n element.uidEvent = uid;\n eventRegistry[uid] = eventRegistry[uid] || {};\n return eventRegistry[uid];\n }\n function bootstrapHandler(element, fn) {\n return function handler(event) {\n hydrateObj(event, {\n delegateTarget: element\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, fn);\n }\n return fn.apply(element, [event]);\n };\n }\n function bootstrapDelegationHandler(element, selector, fn) {\n return function handler(event) {\n const domElements = element.querySelectorAll(selector);\n for (let {\n target\n } = event; target && target !== this; target = target.parentNode) {\n for (const domElement of domElements) {\n if (domElement !== target) {\n continue;\n }\n hydrateObj(event, {\n delegateTarget: target\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, selector, fn);\n }\n return fn.apply(target, [event]);\n }\n }\n };\n }\n function findHandler(events, callable, delegationSelector = null) {\n return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);\n }\n function normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n const isDelegated = typeof handler === 'string';\n // TODO: tooltip passes `false` instead of selector, so we need to check\n const callable = isDelegated ? delegationFunction : handler || delegationFunction;\n let typeEvent = getTypeEvent(originalTypeEvent);\n if (!nativeEvents.has(typeEvent)) {\n typeEvent = originalTypeEvent;\n }\n return [isDelegated, callable, typeEvent];\n }\n function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n\n // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n if (originalTypeEvent in customEvents) {\n const wrapFunction = fn => {\n return function (event) {\n if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n return fn.c
1all(this, event);\n }\n };\n };\n callable = wrapFunction(callable);\n }\n const events = getElementEvents(element);\n const handlers = events[typeEvent] || (events[typeEvent] = {});\n const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);\n if (previousFunction) {\n previousFunction.oneOff = previousFunction.oneOff && oneOff;\n return;\n }\n const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));\n const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);\n fn.delegationSelector = isDelegated ? handler : null;\n fn.callable = callable;\n fn.oneOff = oneOff;\n fn.uidEvent = uid;\n handlers[uid] = fn;\n element.addEventListener(typeEvent, fn, isDelegated);\n }\n function removeHandler(element, events, typeEvent, handler, delegationSelector) {\n const fn = findHandler(events[typeEvent], handler, delegationSelector);\n if (!fn) {\n return;\n }\n element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n delete events[typeEvent][fn.uidEvent];\n }\n function removeNamespacedHandlers(element, events, typeEvent, namespace) {\n const storeElementEvent = events[typeEvent] || {};\n for (const [handlerKey, event] of Object.entries(storeElementEvent)) {\n if (handlerKey.includes(namespace)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n }\n function getTypeEvent(event) {\n // allow to get the native events from namespaced events ('click.bs.button' --\x3e 'click')\n event = event.replace(stripNameRegex, '');\n return customEvents[event] || event;\n }\n const EventHandler = {\n on(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, false);\n },\n one(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, true);\n },\n off(element, originalTypeEvent, handler, delegationFunction) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n const inNamespace = typeEvent !== originalTypeEvent;\n const events = getElementEvents(element);\n const storeElementEvent = events[typeEvent] || {};\n const isNamespace = originalTypeEvent.startsWith('.');\n if (typeof callable !== 'undefined') {\n // Simplest case: handler is passed, remove that listener ONLY.\n if (!Object.keys(storeElementEvent).length) {\n return;\n }\n removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);\n return;\n }\n if (isNamespace) {\n for (const elementEvent of Object.keys(events)) {\n removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n }\n }\n for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {\n const handlerKey = keyHandlers.replace(stripUidRegex, '');\n if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n },\n trigger(element, event, args) {\n if (typeof event !== 'string' || !element) {\n return null;\n }\n const $ = index_js.getjQuery();\n const typeEvent = getTypeEvent(event);\n const inNamespace = event !== typeEvent;\n let jQueryEvent = null;\n let bubbles = true;\n let nativeDispatch = true;\n let defaultPrevented = false;\n if (inNamespace && $) {\n jQueryEvent = $.Event(event, args);\n $(element).trigger(jQueryEvent);\n bubbles = !jQueryEvent.isPropagationStopped();\n nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n defaultPrevented = jQueryEvent.isDefaultPrevented();\n }\n const evt = hydrateObj(new Event(event, {\n bubbles,\n cancelable: true\n }), args);\n if (defaultPrevented) {\n evt.preventDefault();\n }\n if (nativeDispatch) {\n element.dispatchEvent(evt);\n }\n if (evt.defaultPrevented && jQueryEvent) {\n jQueryEvent.preventDefault();\n }\n return evt;\n }\n };\n function hydrateObj(obj, meta = {}) {\n for (const [key, value] of Object.entries(meta)) {\n tr
1y {\n obj[key] = value;\n } catch (_unused) {\n Object.defineProperty(obj, key, {\n configurable: true,\n get() {\n return value;\n }\n });\n }\n }\n return obj;\n }\n\n return EventHandler;\n\n}));\n//# sourceMappingURL=event-handler.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU2LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsS0FBNEQsNEJBQTRCLG1CQUFPLENBQUMsRUFBa0I7QUFDcEgsRUFBRSxDQUN1SDtBQUN6SCxDQUFDLCtCQUErQjs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsSUFBSSxJQUFJLFdBQVc7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxTQUFTLDJCQUEyQjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRTtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDO0FBQ0QiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvYm9vdHN0cmFwL2pzL2Rpc3QvZG9tL2V2ZW50LWhhbmRsZXIuanM/NmE5NSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAgKiBCb290c3RyYXAgZXZlbnQtaGFuZGxlci5qcyB2NS4zLjMgKGh0dHBzOi8vZ2V0Ym9vdHN0cmFwLmNvbS8pXG4gICogQ29weXJpZ2h0IDIwMTEtMjAyNCBUaGUgQm9vdHN0cmFwIEF1dGhvcnMgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ncmFwaHMvY29udHJpYnV0b3JzKVxuICAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICAqL1xuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoJy4uL3V0aWwvaW5kZXguanMnKSkgOlxuICB0eX
1Blb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWycuLi91dGlsL2luZGV4J10sIGZhY3RvcnkpIDpcbiAgKGdsb2JhbCA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiBnbG9iYWwgfHwgc2VsZiwgZ2xvYmFsLkV2ZW50SGFuZGxlciA9IGZhY3RvcnkoZ2xvYmFsLkluZGV4KSk7XG59KSh0aGlzLCAoZnVuY3Rpb24gKGluZGV4X2pzKSB7ICd1c2Ugc3RyaWN0JztcblxuICAvKipcbiAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICogQm9vdHN0cmFwIGRvbS9ldmVudC1oYW5kbGVyLmpzXG4gICAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgKi9cblxuXG4gIC8qKlxuICAgKiBDb25zdGFudHNcbiAgICovXG5cbiAgY29uc3QgbmFtZXNwYWNlUmVnZXggPSAvW14uXSooPz1cXC4uKilcXC58LiovO1xuICBjb25zdCBzdHJpcE5hbWVSZWdleCA9IC9cXC4uKi87XG4gIGNvbnN0IHN0cmlwVWlkUmVnZXggPSAvOjpcXGQrJC87XG4gIGNvbnN0IGV2ZW50UmVnaXN0cnkgPSB7fTsgLy8gRXZlbnRzIHN0b3JhZ2VcbiAgbGV0IHVpZEV2ZW50ID0gMTtcbiAgY29uc3QgY3VzdG9tRXZlbnRzID0ge1xuICAgIG1vdXNlZW50ZXI6ICdtb3VzZW92ZXInLFxuICAgIG1vdXNlbGVhdmU6ICdtb3VzZW91dCdcbiAgfTtcbiAgY29uc3QgbmF0aXZlRXZlbnRzID0gbmV3IFNldChbJ2NsaWNrJywgJ2RibGNsaWNrJywgJ21vdXNldXAnLCAnbW91c2Vkb3duJywgJ2NvbnRleHRtZW51JywgJ21vdXNld2hlZWwnLCAnRE9NTW91c2VTY3JvbGwnLCAnbW91c2VvdmVyJywgJ21vdXNlb3V0JywgJ21vdXNlbW92ZScsICdzZWxlY3RzdGFydCcsICdzZWxlY3RlbmQnLCAna2V5ZG93bicsICdrZXlwcmVzcycsICdrZXl1cCcsICdvcmllbnRhdGlvbmNoYW5nZScsICd0b3VjaHN0YXJ0JywgJ3RvdWNobW92ZScsICd0b3VjaGVuZCcsICd0b3VjaGNhbmNlbCcsICdwb2ludGVyZG93bicsICdwb2ludGVybW92ZScsICdwb2ludGVydXAnLCAncG9pbnRlcmxlYXZlJywgJ3BvaW50ZXJjYW5jZWwnLCAnZ2VzdHVyZXN0YXJ0JywgJ2dlc3R1cmVjaGFuZ2UnLCAnZ2VzdHVyZWVuZCcsICdmb2N1cycsICdibHVyJywgJ2NoYW5nZScsICdyZXNldCcsICdzZWxlY3QnLCAnc3VibWl0JywgJ2ZvY3VzaW4nLCAnZm9jdXNvdXQnLCAnbG9hZCcsICd1bmxvYWQnLCAnYmVmb3JldW5sb2FkJywgJ3Jlc2l6ZScsICdtb3ZlJywgJ0RPTUNvbnRlbnRMb2FkZWQnLCAncmVhZHlzdGF0ZWNoYW5nZScsICdlcnJvcicsICdhYm9ydCcsICdzY3JvbGwnXSk7XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgbWV0aG9kc1xuICAgKi9cblxuICBmdW5jdGlvbiBtYWtlRXZlbnRVaWQoZWxlbWVudCwgdWlkKSB7XG4gICAgcmV0dXJuIHVpZCAmJiBgJHt1aWR9Ojoke3VpZEV2ZW50Kyt9YCB8fCBlbGVtZW50LnVpZEV2ZW50IHx8IHVpZEV2ZW50Kys7XG4gIH1cbiAgZnVuY3Rpb24gZ2V0RWxlbWVudEV2ZW50cyhlbGVtZW50KSB7XG4gICAgY29uc3QgdWlkID0gbWFrZUV2ZW50VWlkKGVsZW1lbnQpO1xuICAgIGVsZW1lbnQudWlkRXZlbnQgPSB1aWQ7XG4gICAgZXZlbnRSZWdpc3RyeVt1aWRdID0gZXZlbnRSZWdpc3RyeVt1aWRdIHx8IHt9O1xuICAgIHJldHVybiBldmVudFJlZ2lzdHJ5W3VpZF07XG4gIH1cbiAgZnVuY3Rpb24gYm9vdHN0cmFwSGFuZGxlcihlbGVtZW50LCBmbikge1xuICAgIHJldHVybiBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7XG4gICAgICBoeWRyYXRlT2JqKGV2ZW50LCB7XG4gICAgICAgIGRlbGVnYXRlVGFyZ2V0OiBlbGVtZW50XG4gICAgICB9KTtcbiAgICAgIGlmIChoYW5kbGVyLm9uZU9mZikge1xuICAgICAgICBFdmVudEhhbmRsZXIub2ZmKGVsZW1lbnQsIGV2ZW50LnR5cGUsIGZuKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmbi5hcHBseShlbGVtZW50LCBbZXZlbnRdKTtcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGJvb3RzdHJhcERlbGVnYXRpb25IYW5kbGVyKGVsZW1lbnQsIHNlbGVjdG9yLCBmbikge1xuICAgIHJldHVybiBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7XG4gICAgICBjb25zdCBkb21FbGVtZW50cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gICAgICBmb3IgKGxldCB7XG4gICAgICAgIHRhcmdldFxuICAgICAgfSA9IGV2ZW50OyB0YXJnZXQgJiYgdGFyZ2V0ICE9PSB0aGlzOyB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZSkge1xuICAgICAgICBmb3IgKGNvbnN0IGRvbUVsZW1lbnQgb2YgZG9tRWxlbWVudHMpIHtcbiAgICAgICAgICBpZiAoZG9tRWxlbWVudCAhPT0gdGFyZ2V0KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaHlkcmF0ZU9iaihldmVudCwge1xuICAgICAgICAgICAgZGVsZWdhdGVUYXJnZXQ6IHRhcmdldFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChoYW5kbGVyLm9uZU9mZikge1xuICAgICAgICAgICAgRXZlbnRIYW5kbGVyLm9mZihlbGVtZW50LCBldmVudC50eXBlLCBzZWxlY3RvciwgZm4pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm4uYXBwbHkodGFyZ2V0LCBbZXZlbnRdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZmluZEhhbmRsZXIoZXZlbnRzLCBjYWxsYWJsZSwgZGVsZWdhdGlvblNlbGVjdG9yID0gbnVsbCkge1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKGV2ZW50cykuZmluZChldmVudCA9PiBldmVudC5jYWxsYWJsZSA9PT0gY2FsbGFibGUgJiYgZXZlbnQuZGVsZWdhdGlvblNlbGVjdG9yID09PSBkZWxlZ2F0aW9uU2VsZWN0b3IpO1xuICB9XG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZVBhcmFtZXRlcnMob3JpZ2luYWxUeXBlRXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbikge1xuICAgIGNvbnN0IGlzRGVsZWdhdGVkID0gdHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnO1xuICAgIC8vIFRPRE86IHRvb2x0aXAgcGFzc2VzIGBmYWxzZWAgaW5zdGVhZCBvZiBzZWxlY3Rvciwgc28gd2UgbmVlZCB0byBjaGVja1xuICAgIGNvbnN0IGNhbGxhYmxlID0gaXNEZWxlZ2F0ZWQgPyBkZWxlZ2F0aW9uRnVuY3Rpb24gOiBoYW5kbGVyIHx8IGRlbGVnYXRpb25GdW5jdGlvbjtcbiAgICBsZXQgdHlwZUV2ZW50ID0gZ2V0VHlwZUV2ZW50KG9yaWdpbmFsVHlwZUV2ZW50KTtcbiAgICBpZiAoIW5hdGl2ZUV2ZW50cy5oYXModHlwZUV2ZW50KSkge1xuICAgICAgdHlwZUV2ZW50ID0gb3JpZ2luYWxUeXBlRXZlbnQ7XG4gICAgfVxuICAgIHJldHVybi
1BbaXNEZWxlZ2F0ZWQsIGNhbGxhYmxlLCB0eXBlRXZlbnRdO1xuICB9XG4gIGZ1bmN0aW9uIGFkZEhhbmRsZXIoZWxlbWVudCwgb3JpZ2luYWxUeXBlRXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbiwgb25lT2ZmKSB7XG4gICAgaWYgKHR5cGVvZiBvcmlnaW5hbFR5cGVFdmVudCAhPT0gJ3N0cmluZycgfHwgIWVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IFtpc0RlbGVnYXRlZCwgY2FsbGFibGUsIHR5cGVFdmVudF0gPSBub3JtYWxpemVQYXJhbWV0ZXJzKG9yaWdpbmFsVHlwZUV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24pO1xuXG4gICAgLy8gaW4gY2FzZSBvZiBtb3VzZWVudGVyIG9yIG1vdXNlbGVhdmUgd3JhcCB0aGUgaGFuZGxlciB3aXRoaW4gYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyBmb3IgaXRzIERPTSBwb3NpdGlvblxuICAgIC8vIHRoaXMgcHJldmVudHMgdGhlIGhhbmRsZXIgZnJvbSBiZWluZyBkaXNwYXRjaGVkIHRoZSBzYW1lIHdheSBhcyBtb3VzZW92ZXIgb3IgbW91c2VvdXQgZG9lc1xuICAgIGlmIChvcmlnaW5hbFR5cGVFdmVudCBpbiBjdXN0b21FdmVudHMpIHtcbiAgICAgIGNvbnN0IHdyYXBGdW5jdGlvbiA9IGZuID0+IHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIGlmICghZXZlbnQucmVsYXRlZFRhcmdldCB8fCBldmVudC5yZWxhdGVkVGFyZ2V0ICE9PSBldmVudC5kZWxlZ2F0ZVRhcmdldCAmJiAhZXZlbnQuZGVsZWdhdGVUYXJnZXQuY29udGFpbnMoZXZlbnQucmVsYXRlZFRhcmdldCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmbi5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9O1xuICAgICAgY2FsbGFibGUgPSB3cmFwRnVuY3Rpb24oY2FsbGFibGUpO1xuICAgIH1cbiAgICBjb25zdCBldmVudHMgPSBnZXRFbGVtZW50RXZlbnRzKGVsZW1lbnQpO1xuICAgIGNvbnN0IGhhbmRsZXJzID0gZXZlbnRzW3R5cGVFdmVudF0gfHwgKGV2ZW50c1t0eXBlRXZlbnRdID0ge30pO1xuICAgIGNvbnN0IHByZXZpb3VzRnVuY3Rpb24gPSBmaW5kSGFuZGxlcihoYW5kbGVycywgY2FsbGFibGUsIGlzRGVsZWdhdGVkID8gaGFuZGxlciA6IG51bGwpO1xuICAgIGlmIChwcmV2aW91c0Z1bmN0aW9uKSB7XG4gICAgICBwcmV2aW91c0Z1bmN0aW9uLm9uZU9mZiA9IHByZXZpb3VzRnVuY3Rpb24ub25lT2ZmICYmIG9uZU9mZjtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdWlkID0gbWFrZUV2ZW50VWlkKGNhbGxhYmxlLCBvcmlnaW5hbFR5cGVFdmVudC5yZXBsYWNlKG5hbWVzcGFjZVJlZ2V4LCAnJykpO1xuICAgIGNvbnN0IGZuID0gaXNEZWxlZ2F0ZWQgPyBib290c3RyYXBEZWxlZ2F0aW9uSGFuZGxlcihlbGVtZW50LCBoYW5kbGVyLCBjYWxsYWJsZSkgOiBib290c3RyYXBIYW5kbGVyKGVsZW1lbnQsIGNhbGxhYmxlKTtcbiAgICBmbi5kZWxlZ2F0aW9uU2VsZWN0b3IgPSBpc0RlbGVnYXRlZCA/IGhhbmRsZXIgOiBudWxsO1xuICAgIGZuLmNhbGxhYmxlID0gY2FsbGFibGU7XG4gICAgZm4ub25lT2ZmID0gb25lT2ZmO1xuICAgIGZuLnVpZEV2ZW50ID0gdWlkO1xuICAgIGhhbmRsZXJzW3VpZF0gPSBmbjtcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHlwZUV2ZW50LCBmbiwgaXNEZWxlZ2F0ZWQpO1xuICB9XG4gIGZ1bmN0aW9uIHJlbW92ZUhhbmRsZXIoZWxlbWVudCwgZXZlbnRzLCB0eXBlRXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25TZWxlY3Rvcikge1xuICAgIGNvbnN0IGZuID0gZmluZEhhbmRsZXIoZXZlbnRzW3R5cGVFdmVudF0sIGhhbmRsZXIsIGRlbGVnYXRpb25TZWxlY3Rvcik7XG4gICAgaWYgKCFmbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZUV2ZW50LCBmbiwgQm9vbGVhbihkZWxlZ2F0aW9uU2VsZWN0b3IpKTtcbiAgICBkZWxldGUgZXZlbnRzW3R5cGVFdmVudF1bZm4udWlkRXZlbnRdO1xuICB9XG4gIGZ1bmN0aW9uIHJlbW92ZU5hbWVzcGFjZWRIYW5kbGVycyhlbGVtZW50LCBldmVudHMsIHR5cGVFdmVudCwgbmFtZXNwYWNlKSB7XG4gICAgY29uc3Qgc3RvcmVFbGVtZW50RXZlbnQgPSBldmVudHNbdHlwZUV2ZW50XSB8fCB7fTtcbiAgICBmb3IgKGNvbnN0IFtoYW5kbGVyS2V5LCBldmVudF0gb2YgT2JqZWN0LmVud
1HJpZXMoc3RvcmVFbGVtZW50RXZlbnQpKSB7XG4gICAgICBpZiAoaGFuZGxlcktleS5pbmNsdWRlcyhuYW1lc3BhY2UpKSB7XG4gICAgICAgIHJlbW92ZUhhbmRsZXIoZWxlbWVudCwgZXZlbnRzLCB0eXBlRXZlbnQsIGV2ZW50LmNhbGxhYmxlLCBldmVudC5kZWxlZ2F0aW9uU2VsZWN0b3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBnZXRUeXBlRXZlbnQoZXZlbnQpIHtcbiAgICAvLyBhbGxvdyB0byBnZXQgdGhlIG5hdGl2ZSBldmVudHMgZnJvbSBuYW1lc3BhY2VkIGV2ZW50cyAoJ2NsaWNrLmJzLmJ1dHRvbicgLS0+ICdjbGljaycpXG4gICAgZXZlbnQgPSBldmVudC5yZXBsYWNlKHN0cmlwTmFtZVJlZ2V4LCAnJyk7XG4gICAgcmV0dXJuIGN1c3RvbUV2ZW50c1tldmVudF0gfHwgZXZlbnQ7XG4gIH1cbiAgY29uc3QgRXZlbnRIYW5kbGVyID0ge1xuICAgIG9uKGVsZW1lbnQsIGV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24pIHtcbiAgICAgIGFkZEhhbmRsZXIoZWxlbWVudCwgZXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbiwgZmFsc2UpO1xuICAgIH0sXG4gICAgb25lKGVsZW1lbnQsIGV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24pIHtcbiAgICAgIGFkZEhhbmRsZXIoZWxlbWVudCwgZXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbiwgdHJ1ZSk7XG4gICAgfSxcbiAgICBvZmYoZWxlbWVudCwgb3JpZ2luYWxUeXBlRXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbikge1xuICAgICAgaWYgKHR5cGVvZiBvcmlnaW5hbFR5cGVFdmVudCAhPT0gJ3N0cmluZycgfHwgIWVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgW2lzRGVsZWdhdGVkLCBjYWxsYWJsZSwgdHlwZUV2ZW50XSA9IG5vcm1hbGl6ZVBhcmFtZXRlcnMob3JpZ2luYWxUeXBlRXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbik7XG4gICAgICBjb25zdCBpbk5hbWVz
1cGFjZSA9IHR5cGVFdmVudCAhPT0gb3JpZ2luYWxUeXBlRXZlbnQ7XG4gICAgICBjb25zdCBldmVudHMgPSBnZXRFbGVtZW50RXZlbnRzKGVsZW1lbnQpO1xuICAgICAgY29uc3Qgc3RvcmVFbGVtZW50RXZlbnQgPSBldmVudHNbdHlwZUV2ZW50XSB8fCB7fTtcbiAgICAgIGNvbnN0IGlzTmFtZXNwYWNlID0gb3JpZ2luYWxUeXBlRXZlbnQuc3RhcnRzV2l0aCgnLicpO1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYWJsZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgLy8gU2ltcGxlc3QgY2FzZTogaGFuZGxlciBpcyBwYXNzZWQsIHJlbW92ZSB0aGF0IGxpc3RlbmVyIE9OTFkuXG4gICAgICAgIGlmICghT2JqZWN0LmtleXMoc3RvcmVFbGVtZW50RXZlbnQpLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICByZW1vdmVIYW5kbGVyKGVsZW1lbnQsIGV2ZW50cywgdHlwZUV2ZW50LCBjYWxsYWJsZSwgaXNEZWxlZ2F0ZWQgPyBoYW5kbGVyIDogbnVsbCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChpc05hbWVzcGFjZSkge1xuICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnRFdmVudCBvZiBPYmplY3Qua2V5cyhldmVudHMpKSB7XG4gICAgICAgICAgcmVtb3ZlTmFtZXNwYWNlZEhhbmRsZXJzKGVsZW1lbnQsIGV2ZW50cywgZWxlbWVudEV2ZW50LCBvcmlnaW5hbFR5cGVFdmVudC5zbGljZSgxKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgW2tleUhhbmRsZXJzLCBldmVudF0gb2YgT2JqZWN0LmVud
1HJpZXMoc3RvcmVFbGVtZW50RXZlbnQpKSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXJLZXkgPSBrZXlIYW5kbGVycy5yZXBsYWNlKHN0cmlwVWlkUmVnZXgsICcnKTtcbiAgICAgICAgaWYgKCFpbk5hbWVzcGFjZSB8fCBvcmlnaW5hbFR5cGVFdmVudC5pbmNsdWRlcyhoYW5kbGVyS2V5KSkge1xuICAgICAgICAgIHJlbW92ZUhhbmRsZXIoZWxlbWVudCwgZXZlbnRzLCB0eXBlRXZlbnQsIGV2ZW50LmNhbGxhYmxlLCBldmVudC5kZWxlZ2F0aW9uU2VsZWN0b3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICB0cmlnZ2VyKGVsZW1lbnQsIGV2ZW50LCBhcmdzKSB7XG4gICAgICBpZiAodHlwZW9mIGV2ZW50ICE9PSAnc3RyaW5nJyB8fCAhZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGNvbnN0ICQgPSBpbmRleF9qcy5nZXRqUXVlcnkoKTtcbiAgICAgIGNvbnN0IHR5cGVFdmVudCA9IGdldFR5cGVFdmVudChldmVudCk7XG4gICAgICBjb25zdCBpbk5hbWVzcGFjZSA9IGV2ZW50ICE9PSB0eXBlRXZlbnQ7XG4gICAgICBsZXQgalF1ZXJ5RXZlbnQgPSBudWxsO1xuICAgICAgbGV0IGJ1YmJsZXMgPSB0cnVlO1xuICAgICAgbGV0IG5hdGl2ZURpc3BhdGNoID0gdHJ1ZTtcbiAgICAgIGxldCBkZWZhdWx0UHJldmVudGVkID0gZmFsc2U7XG4gICAgICBpZiAoaW5OYW1lc3BhY2UgJiYgJCkge1xuICAgICAgICBqUXVlcnlFdmVudCA9ICQuRXZlbnQoZXZlbnQsIGFyZ3MpO1xuICAgICAgICAkKGVsZW1lbnQpLnRyaWdnZXIoalF1ZXJ5RXZlbnQpO1xuICAgICAgICBidWJibGVzID0gIWpRdWVyeUV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCk7XG4gICAgICAgIG5hdGl2ZURpc3BhdGNoID0gIWpRdWVyeUV2ZW50LmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKCk7XG4gICAgICAgIGRlZmF1bHRQcmV2ZW50ZWQgPSBqUXVlcnlFdmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGV2dCA9IGh5ZHJhdGVPYmoobmV3IEV2ZW50KGV2ZW50LCB7XG4gICAgICAgIGJ1YmJsZXMsXG4gICAgICAgIGNhbmNlbGFibG
1U6IHRydWVcbiAgICAgIH0pLCBhcmdzKTtcbiAgICAgIGlmIChkZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuICAgICAgaWYgKG5hdGl2ZURpc3BhdGNoKSB7XG4gICAgICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChldnQpO1xuICAgICAgfVxuICAgICAgaWYgKGV2dC5kZWZhdWx0UHJldmVudGVkICYmIGpRdWVyeUV2ZW50KSB7XG4gICAgICAgIGpRdWVyeUV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZXZ0O1xuICAgIH1cbiAgfTtcbiAgZnVuY3Rpb24gaHlkcmF0ZU9iaihvYmosIG1ldGEgPSB7fSkge1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG1ldGEpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBvYmpba2V5XSA9IHZhbHVlO1xuICAgICAgfSBjYXRjaCAoX3VudXNlZCkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgZ2V0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICByZXR1cm4gRXZlbnRIYW5kbGVyO1xuXG59KSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC1oYW5kbGVyLmpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///956\n")},333:function(module){eval("/*!\n * Bootstrap manipulator.js v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n(function (global, factory) {\n true ? module.exports = factory() :\n 0;\n})(this, (function () { 'use strict';\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n function normalizeData(value) {\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n if (value === Number(value).toString()) {\n return Number(value);\n }\n if (value === '' || value === 'null') {\n return null;\n }\n if (typeof value !== 'string') {\n return value;\n }\n try {\n return JSON.parse(decodeURIComponent(value));\n } catch (_unused) {\n return value;\n }\n }\n function normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n }\n const Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n },\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n },\n getDataAttributes(element) {\n if (!element) {\n return {};\n }\n const attributes = {};\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '');\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n attributes[pureKey] = normalizeData(element.dataset[key]);\n }\n return attributes;\n },\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n }\n };\n\n return Manipulator;\n\n}));\n//# sourceMappingURL=manipulator.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzMzLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsS0FBNEQ7QUFDOUQsRUFBRSxDQUMwRztBQUM1RyxDQUFDLHVCQUF1Qjs7QUFFeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QyxrQkFBa0I7QUFDOUQ7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHNCQUFzQjtBQUM1RCxLQUFLO0FBQ0w7QUFDQSx5Q0FBeUMsc0JBQXNCO0FBQy9ELEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSwyREFBMkQsc0JBQXNCO0FBQ2pGO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQztBQUNEIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL2Jvb3RzdHJhcC9qcy9kaXN0L2RvbS9tYW5pcHVsYXRvci5qcz8xMDllIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICAqIEJvb3RzdHJhcCBtYW5pcHVsYXRvci5qcyB2NS4zLjMgKGh0dHBzOi8vZ2V0Ym9vdHN0cmFwLmNvbS8pXG4gICogQ29weXJpZ2h0IDIwMTEtMjAyNCBUaGUgQm9vdHN0cmFwIEF1dGhvcnMgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ncmFwaHMvY29udHJpYnV0b3JzKVxuICAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICAqL1xuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuICB0eX
1Blb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuICAoZ2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwuTWFuaXB1bGF0b3IgPSBmYWN0b3J5KCkpO1xufSkodGhpcywgKGZ1bmN0aW9uICgpIHsgJ3VzZSBzdHJpY3QnO1xuXG4gIC8qKlxuICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgKiBCb290c3RyYXAgZG9tL21hbmlwdWxhdG9yLmpzXG4gICAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgKi9cblxuICBmdW5jdGlvbiBub3JtYWxpemVEYXRhKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09PSAndHJ1ZScpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT09ICdmYWxzZScpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHZhbHVlID09PSBOdW1iZXIodmFsdWUpLnRvU3RyaW5nKCkpIHtcbiAgICAgIHJldHVybiBOdW1iZXIodmFsdWUpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT09ICcnIHx8IHZhbHVlID09PSAnbnVsbCcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlKSk7XG4gICAgfSBjYXRjaCAoX3VudXNlZCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBub3JtYWxpemVEYXRhS2V5KGtleSkge1xuICAgIHJldHVybiBrZXkucmVwbGFjZSgvW0EtWl0vZywgY2hyID0+IGAtJHtjaHIudG9Mb3dlckNhc2UoKX1gKTtcbiAgfVxuICBjb25zdCBNYW5pcHVsYXRvciA9IHtcbiAgICBzZXREYXRhQXR0cmlidXRlKGVsZW1lbnQsIGtleSwgdmFsdWUpIHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGBkYXRhLWJzLSR7bm9ybWFsaXplRGF0YUtleShrZXkpfWAsIHZhbHVlKTtcbiAgICB9LFxuICAgIHJlbW92ZURhdGFBdHRyaWJ1dGUoZWxlbWVudCwga2V5KSB7XG4gICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShgZGF0YS1icy0ke25vcm1hbGl6ZURhdGFLZXkoa2V5KX1gKTtcbiAgICB9LFxuICAgIGdldERhdGFBdHRyaWJ1dGVzKGVsZW1lbnQpIHtcbiAgICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgICB9XG4gICAgICBjb25zdCBhdHRyaWJ1dGVzID0ge307XG4gICAgICBjb25zdCBic0tleXMgPSBPYmplY3Qua2V5cyhlbGVtZW50LmRhdGFzZXQpLmZpbHRlcihrZXkgPT4ga2V5LnN0YXJ0c1dpdGgoJ2JzJykgJiYgIWtleS5zdGFydHNXaXRoKCdic0NvbmZpZycpKTtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIGJzS2V5cykge1xuICAgICAgICBsZXQgcHVyZUtleSA9IGtleS5yZXBsYWNlKC9eYnMvLCAnJyk7XG4gICAgICAgIHB1cmVLZXkgPSBwdXJlS2V5LmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgcHVyZUtleS5zbGljZSgxLCBwdXJlS2V5Lmxlbmd0aCk7XG4gICAgICAgIGF0dHJpYnV0ZXNbcHVyZUtleV0gPSBub3JtYWxpemVEYXRhKGVsZW1lbnQuZGF0YXNldFtrZXldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgIH0sXG4gICAgZ2V0RGF0YUF0dHJpYnV0ZShlbGVtZW50LCBrZXkpIHtcbiAgICAgIHJldHVybiBub3JtYWxpemVEYXRhKGVsZW1lbnQuZ2V0QXR0cmlidXRlKGBkYXRhLWJzLSR7bm9ybWFsaXplRGF0YUtleShrZXkpfWApKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIE1hbmlwdWxhdG9yO1xuXG59KSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYW5pcHVsYXRvci5qcy5tYXBcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///333\n")},411:function(module,__unused_webpack_exports,__webpack_require__){eval("/*!\n * Bootstrap selector-engine.js v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n(function (global, factory) {\n true ? module.exports = factory(__webpack_require__(35)) :\n 0;\n})(this, (function (index_js) { 'use strict';\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n const getSelector = element => {\n let selector = element.getAttribute('data-bs-target');\n if (!selector || selector === '#') {\n let hrefAttribute = element.getAttribute('href');\n\n // The only valid content that could double as a selector are IDs or classes,\n // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n // `document.querySelector` will rightfully complain it is invali
1d.\n // See https://github.com/twbs/bootstrap/issues/32273\n if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {\n return null;\n }\n\n // Just in case some CMS puts out a full URL with the anchor appended\n if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n hrefAttribute = `#${hrefAttribute.split('#')[1]}`;\n }\n selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;\n }\n return selector ? selector.split(',').map(sel => index_js.parseSelector(sel)).join(',') : null;\n };\n const SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n },\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector);\n },\n children(element, selector) {\n return [].concat(...element.children).filter(child => child.matches(selector));\n },\n parents(element, selector) {\n const parents = [];\n let ancestor = element.parentNode.closest(selector);\n while (ancestor) {\n parents.push(ancestor);\n ancestor = ancestor.parentNode.closest(selector);\n }\n return parents;\n },\n prev(element, selector) {\n let previous = element.previousElementSibling;\n while (previous) {\n if (previous.matches(selector)) {\n return [previous];\n }\n previous = previous.previousElementSibling;\n }\n return [];\n },\n // TODO: this is now unused; remove later along with prev()\n next(element, selector) {\n let next = element.nextElementSibling;\n while (next) {\n if (next.matches(selector)) {\n return [next];\n }\n next = next.nextElementSibling;\n }\n return [];\n },\n focusableChildren(element) {\n const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',');\n return this.find(focusables, element).filter(el => !index_js.isDisabled(el) && index_js.isVisible(el));\n },\n getSelectorFromElement(element) {\n const selector = getSelector(element);\n if (selector) {\n return SelectorEngine.findOne(selector) ? selector : null;\n }\n return null;\n },\n getElementFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.findOne(selector) : null;\n },\n getMultipleElementsFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.find(selector) : [];\n }\n };\n\n return SelectorEngine;\n\n}));\n//# sourceMappingURL=selector-engine.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDExLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsS0FBNEQsNEJBQTRCLG1CQUFPLENBQUMsRUFBa0I7QUFDcEgsRUFBRSxDQUN5SDtBQUMzSCxDQUFDLCtCQUErQjs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0QkFBNEIsNEJBQTRCO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGlDQUFpQztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxnSkFBZ0osU0FBUztBQUN6SjtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQztBQUNEIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL2Jvb3RzdHJhcC9qcy9kaXN0L2RvbS9zZWxlY3Rvci1lbmdpbmUuanM/ODQ4ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAgKiBCb290c3RyYXAgc2VsZWN0b3ItZW5naW5lLmpzIHY1LjMuMyAoaHR0cHM6Ly9nZXRib290c3RyYXAuY29tLylcbiAgKiBDb3B5cmlnaHQgMjAxMS0yMDI0IFRoZSBCb290c3RyYXAgQXV0aG9ycyAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2dyYXBocy9jb250cmlidXRvcnMpXG4gICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gICovXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSgnLi4vdXRpbC9pbmRleC5qcycpKSA6XG4gIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJy4uL3V0aWwvaW5kZXgnXSwgZmFjdG9yeSkgOlxuICAoZ2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGh
1pcyA6IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwuU2VsZWN0b3JFbmdpbmUgPSBmYWN0b3J5KGdsb2JhbC5JbmRleCkpO1xufSkodGhpcywgKGZ1bmN0aW9uIChpbmRleF9qcykgeyAndXNlIHN0cmljdCc7XG5cbiAgLyoqXG4gICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAqIEJvb3RzdHJhcCBkb20vc2VsZWN0b3ItZW5naW5lLmpzXG4gICAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgKi9cblxuICBjb25zdCBnZXRTZWxlY3RvciA9IGVsZW1lbnQgPT4ge1xuICAgIGxldCBzZWxlY3RvciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWJzLXRhcmdldCcpO1xuICAgIGlmICghc2VsZWN0b3IgfHwgc2VsZWN0b3IgPT09ICcjJykge1xuICAgICAgbGV0IGhyZWZBdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnaHJlZicpO1xuXG4gICAgICAvLyBUaGUgb25seSB2YWxpZCBjb250ZW50IHRoYXQgY291bGQgZG91YmxlIGFzIGEgc2VsZWN0b3IgYXJlIElEcyBvciBjbGFzc2VzLFxuICAgICAgLy8gc28gZXZlcnl0aGluZyBzdGFydGluZyB3aXRoIGAjYCBvciBgLmAuIElmIGEgXCJyZWFsXCIgVVJMIGlzIHVzZWQgYXMgdGhlIHNlbGVjdG9yLFxuICAgICAgLy8gYGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JgIHdpbGwgcmlnaHRmdWxseSBjb21wbGFpbiBpdCBpcyBpbnZhbGlkLlxuICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9pc3N1ZXMvMzIyNzNcbiAgICAgIGlmICghaHJlZkF0dHJpYnV0ZSB8fCAhaHJlZkF0dHJpYnV0ZS5pbmNsdWRlcygnIycpICYmICFocmVmQXR0cmlidXRlLnN0YXJ0c1dpdGgoJy4nKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgLy8gSnVzdCBpbiBjYXNlIHNvbWUgQ01TIHB1dHMgb3V0IGEgZnVsbCBVUkwgd2l0aCB0aGUgYW5jaG9yIGFwcGVuZGVkXG4gICAgICBpZiAoaHJlZkF0dHJpYnV0ZS5pbmNsdWRlcygnIycpICYmICFocmVmQXR0cmlidXRlLnN0YXJ0c1dpdGgoJyMnKSkge1xuICAgICAgICBocmVmQXR0cmlidXRlID0gYCMke2hyZWZBdHRyaWJ1dGUuc3BsaXQoJyMnKVsxXX1gO1xuICAgICAgfVxuICAgICAgc2VsZWN0b3IgPSBocmVmQXR0cmlidXRlICYmIGhyZWZBdHRyaWJ1dGUgIT09ICcjJyA/IGhyZWZBdHRyaWJ1dGUudHJpbSgpIDogbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHNlbGVjdG9yID8gc2VsZWN0b3Iuc3BsaXQoJywnKS5tYXAoc2VsID0+IGluZGV4X2pzLnBhcnNlU2VsZWN0b3Ioc2VsKSkuam9pbignLCcpIDogbnVsbDtcbiAgfTtcbiAgY29uc3QgU2VsZWN0b3JFbmdpbmUgPSB7XG4gICAgZmluZChzZWxlY3RvciwgZWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgICAgcmV0dXJuIFtdLmNvbmNhdCguLi5FbGVtZW50LnByb3RvdHlwZS5xdWVyeVNlbGVjdG9yQWxsLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpKTtcbiAgICB9LFxuICAgIGZpbmRPbmUoc2VsZWN0b3IsIGVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBFbGVtZW50LnByb3RvdHlwZS5xdWVyeVNlbGVjdG9yLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpO1xuICAgIH0sXG4gICAgY2hpbGRyZW4oZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgICAgIHJldHVybiBbXS5jb25jYXQoLi4uZWxlbWVudC5jaGlsZHJlbikuZmlsdGVyKGNoaWxkID0+IGNoaWxkLm1hdGNoZXMoc2VsZWN0b3IpKTtcbiAgICB9LFxuICAgIHBhcmVudHMoZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgICAgIGNvbnN0IHBhcmVudHMgPSBbXTtcbiAgICAgIGxldCBhbmNlc3RvciA9IGVsZW1lbnQucGFyZW50Tm9kZS5jbG9zZXN0KHNlbGVjdG9yKTtcbiAgICAgIHdoaWxlIChhbmNlc3Rvcikge1xuICAgICAgICBwYXJlbnRzLnB1c2goYW5jZXN0b3IpO1xuICAgICAgICBhbmNlc3RvciA9IGFuY2VzdG9yLnBhcmVudE5vZGUuY2xvc2VzdChzZWxlY3Rvcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gcGFyZW50cztcbiAgICB9LFxuICAgIHByZXYoZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgICAgIGxldCBwcmV2aW91cyA9IGVsZW1lbnQucHJldmlvdXNFbGVtZW50U2libGluZztcbiAgICAgIHdoaWxlIChwcmV2aW91cykge1xuICAgICAgICBpZiAocHJldmlvdXMubWF0Y2hlcyhzZWxlY3RvcikpIHtcbiAgICAgICAgICByZXR1cm4gW3ByZXZpb3VzXTtcbiAgICAgICAgfVxuICAgICAgICBwcmV2aW91cyA9IHByZXZpb3VzLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG4gICAgICB9XG4gICAgICByZXR1cm4gW107XG4gICAgfSxcbiAgICAvLyBUT0RPOiB0aGlzIGlzIG5vdyB1bnVzZWQ7IHJlbW92ZSBsYXRlciBhbG9uZyB3aXRoIHByZXYoKVxuICAgIG5leHQoZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgICAgIGxldCBuZXh0ID0gZWxlbWVudC5uZXh0RWxlbWVudFNpYmxpbmc7XG4gICAgICB3aGlsZSAobmV4dCkge1xuICAgICAgICBpZiAobmV4dC5tYXRjaGVzKHNlbGVjdG9yKSkge1xuICAgICAgICAgIHJldHVybiBbbmV4dF07XG4gICAgICAgIH1cbiAgICAgICAgbmV4dCA9IG5leHQubmV4dEVsZW1lbnRTaWJsaW5nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtdO1xuICAgIH0sXG4gICAgZm9jdXNhYmxlQ2hpbGRyZW4oZWxlbWVudCkge1xuICAgICAgY29uc3QgZm9jdXNhYmxlcyA9IFsnYScsICdidXR0b24nLCAnaW5wdXQnLCAndGV4dGFyZWEnLCAnc2VsZWN0JywgJ2RldGFpbHMnLCAnW3RhYmluZGV4XScsICdbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSddLm1hcChzZWxlY3RvciA9PiBgJHtzZWxlY3Rvcn06bm90KFt0YWJpbmRleF49XCItXCJdKWApLmpvaW4oJywnKTtcbiAgICAgIHJldHVybiB0aGlzLmZpbmQoZm9jdXNhYmxlcywgZWxlbWVudCkuZmlsdGVyKGVsID0+ICFpbmRleF9qcy5pc0Rpc2FibGVkKGVsKSAmJiBpbmRleF9qcy5pc1Zpc2libGUoZWwpKTtcbiAgICB9LFxuICAgIGdldFNlbGVjdG9yRnJvbUVsZW1lbnQoZWxlbWVudCkge1xuICAgICAgY29uc3Qgc2VsZWN0b3IgPSBnZXRTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgIGlmIChzZWxlY3Rvcikge1xuICAgICAgICByZXR1cm4gU2VsZWN0b3JFbmdpbmUuZmluZE9uZShzZWxlY3RvcikgPyBzZWxlY3RvciA6IG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuICAgIGdldEVsZW1lbnRGcm9tU2VsZWN0b3IoZWxlbWVudCkge1xuICAgICAgY29uc3Qgc2VsZWN0b3IgPSBnZXRTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgIHJldHVybi
1BzZWxlY3RvciA/IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoc2VsZWN0b3IpIDogbnVsbDtcbiAgICB9LFxuICAgIGdldE11bHRpcGxlRWxlbWVudHNGcm9tU2VsZWN0b3IoZWxlbWVudCkge1xuICAgICAgY29uc3Qgc2VsZWN0b3IgPSBnZXRTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgIHJldHVybiBzZWxlY3RvciA/IFNlbGVjdG9yRW5naW5lLmZpbmQoc2VsZWN0b3IpIDogW107XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBTZWxlY3RvckVuZ2luZTtcblxufSkpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VsZWN0b3ItZW5naW5lLmpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///411\n")},105:function(module,__unused_webpack_exports,__webpack_require__){eval("/*!\n * Bootstrap config.js v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n(function (global, factory) {\n true ? module.exports = factory(__webpack_require__(333), __webpack_require__(35)) :\n 0;\n})(this, (function (Manipulator, index_js) { 'use strict';\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n /**\n * Class definition\n */\n\n class Config {\n // Getters\n static get Default() {\n return {};\n }\n static get DefaultType() {\n return {};\n }\n static get NAME() {\n throw new Error('You have to implement the static method \"NAME\", for each component!');\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n _configAfterMerge(config) {\n return config;\n }\n _mergeConfigObj(config, element) {\n const jsonConfig = index_js.isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse\n\n return {\n ...this.constructor.Default,\n ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n ...(index_js.isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n ...(typeof config === 'object' ? config : {})\n };\n }\n _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n for (const [property, expectedTypes] of Object.entries(configTypes)) {\n const value = config[property];\n const valueType = index_js.isElement(value) ? 'element' : index_js.toType(value);\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n }\n }\n }\n }\n\n return Config;\n\n}));\n//# sourceMappingURL=config.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTA1LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsS0FBNEQsNEJBQTRCLG1CQUFPLENBQUMsR0FBdUIsR0FBRyxtQkFBTyxDQUFDLEVBQVk7QUFDaEosRUFBRSxDQUNxSTtBQUN2SSxDQUFDLDRDQUE0Qzs7QUFFN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkdBQTZHOztBQUU3RztBQUNBO0FBQ0EsNERBQTREO0FBQzVELHFGQUFxRjtBQUNyRixvREFBb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsb0NBQW9DLFlBQVksU0FBUyxtQkFBbUIsVUFBVSx1QkFBdUIsY0FBYztBQUM1SjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDO0FBQ0QiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvYm9vdHN0cmFwL2pzL2Rpc3QvdXRpbC9jb25maWcuanM/MTI0MyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAgKiBCb290c3RyYXAgY29uZmlnLmpzIHY1LjMuMyAoaHR0cHM6Ly9nZXRib290c3RyYXAuY29tLylcbiAgKiBDb3B5cmlnaHQgMjAxMS0yMDI0IFRoZSBCb290c3RyYXAgQXV0aG9ycyAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2dyYXBocy9jb250cmlidXRvcnMpXG4gICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gICovXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSgnLi4vZG9tL2
11hbmlwdWxhdG9yLmpzJyksIHJlcXVpcmUoJy4vaW5kZXguanMnKSkgOlxuICB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoWycuLi9kb20vbWFuaXB1bGF0b3InLCAnLi9pbmRleCddLCBmYWN0b3J5KSA6XG4gIChnbG9iYWwgPSB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWxUaGlzIDogZ2xvYmFsIHx8IHNlbGYsIGdsb2JhbC5Db25maWcgPSBmYWN0b3J5KGdsb2JhbC5NYW5pcHVsYXRvciwgZ2xvYmFsLkluZGV4KSk7XG59KSh0aGlzLCAoZnVuY3Rpb24gKE1hbmlwdWxhdG9yLCBpbmRleF9qcykgeyAndXNlIHN0cmljdCc7XG5cbiAgLyoqXG4gICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAqIEJvb3RzdHJhcCB1dGlsL2NvbmZpZy5qc1xuICAgKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICovXG5cblxuICAvKipcbiAgICogQ2xhc3MgZGVmaW5pdGlvblxuICAgKi9cblxuICBjbGFzcyBDb25maWcge1xuICAgIC8vIEdldHRlcnNcbiAgICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIHN0YXRpYyBnZXQgRGVmYXVsdFR5cGUoKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGhhdmUgdG8gaW1wbGVtZW50IHRoZSBzdGF0aWMgbWV0aG9kIFwiTkFNRVwiLCBmb3IgZWFjaCBjb21wb25lbnQhJyk7XG4gICAgfVxuICAgIF9nZXRDb25maWcoY29uZmlnKSB7XG4gICAgICBjb25maWcgPSB0aGlzLl9tZXJnZUNvbmZpZ09iaihjb25maWcpO1xuICAgICAgY29uZmlnID0gdGhpcy5fY29uZmlnQWZ0ZXJNZXJnZShjb25maWcpO1xuICAgICAgdGhpcy5fdHlwZUNoZWNrQ29uZmlnKGNvbmZpZyk7XG4gICAgICByZXR1cm4gY29uZmlnO1xuICAgIH1cbiAgICBfY29uZmlnQWZ0ZXJNZXJnZShjb25maWcpIHtcbiAgICAgIHJldHVybiBjb25maWc7XG4gICAgfVxuICAgIF9tZXJnZUNvbmZpZ09iaihjb25maWcsIGVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IGpzb25Db25maWcgPSBpbmRleF9qcy5pc0VsZW1lbnQoZWxlbWVudCkgPyBNYW5pcHVsYXRvci5nZXREYXRhQXR0cmlidXRlKGVsZW1lbnQsICdjb25maWcnKSA6IHt9OyAvLyB0cnkgdG8gcGFyc2VcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4udGhpcy5jb25zdHJ1Y3Rvci5EZWZhdWx0LFxuICAgICAgICAuLi4odHlwZW9mIGpzb25Db25maWcgPT09ICdvYmplY3QnID8ganNvbkNvbmZpZyA6IHt9KSxcbiAgICAgICAgLi4uKGluZGV4X2pzLmlzRWxlbWVudChlbGVtZW50KSA/IE1hbmlwdWxhdG9yLmdldERhdGFBdHRyaWJ1dGVzKGVsZW1lbnQpIDoge30pLFxuICAgICAgICAuLi4odHlwZW9mIGNvbmZpZyA9PT0gJ29iamVjdCcgPyBjb25maWcgOiB7fSlcbiAgICAgIH07XG4gICAgfVxuICAgIF90eXBlQ2hlY2tDb25maWcoY29uZmlnLCBjb25maWdUeXBlcyA9IHRoaXMuY29uc3RydWN0b3IuRGVmYXVsdFR5cGUpIHtcbiAgICAgIGZvciAoY29uc3QgW3Byb3BlcnR5LCBleHBlY3RlZFR5cGVzXSBvZiBPYmplY3QuZW50cmllcyhjb25maWdUeXBlcykpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBjb25maWdbcHJvcGVydHldO1xuICAgICAgICBjb25zdCB2YWx1ZVR5cGUgPSBpbmRleF9qcy5pc0VsZW1lbnQodmFsdWUpID8gJ2VsZW1lbnQnIDogaW5kZXhfanMudG9UeXBlKHZhbHVlKTtcbiAgICAgICAgaWYgKCFuZXcgUmVnRXhwKGV4cGVjdGVkVHlwZXMpLnRlc3QodmFsdWVUeXBlKSkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FLnRvVXBwZXJDYXNlKCl9OiBPcHRpb24gXCIke3Byb3BlcnR5fVwiIHByb3ZpZGVkIHR5cGUgXCIke3ZhbHVlVHlwZX1cIiBidXQgZXhwZWN0ZWQgdHlwZSBcIiR7ZXhwZWN0ZWRUeXBlc31cIi5gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBDb25maWc7XG5cbn0pKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbmZpZy5qcy5tYXBcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///105\n")},35:function(__unused_webpack_module,exports){eval("/*!\n * Bootstrap index.js v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n(function (global, factory) {\n true ? factory(exports) :\n 0;\n})(this, (function (exports) { 'use strict';\n\n /**\n * --------------------------------------------------------------------------\n * Bootstrap util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n const MAX_UID = 1000000;\n const MILLISECONDS_MULTIPLIER = 1000;\n const TRANSITION_END = 'transitionend';\n\n /**\n * Properly escape IDs selectors to handle weird IDs\n * @param {string} selector\n * @returns {string}\n */\n const parseSelector = selector => {\n if (selector && window.CSS && window.CSS.escape) {\n // document.querySelector needs escaping to handle IDs (html5+) containing for instance /\n selector = selector.replace(/#([^\\s\"#']+)/g, (match, id) => `#${CSS.escape(id)}`);\n }\n return selector;\n };\n\n // Shout-out Angus Croll (https://goo.gl/pxwQGp)\n const toType = object => {\n if (object === null || object === undefined) {\n return `${object}`;\n }\n return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase();\n };\n\n /**\n * Public Util API\n */\n\n const getUID = prefix => {\n do {\n prefix += Math.floor(Math.random() * MAX_UID);\n } while (document.getElementById(prefix));\n return prefix;\n };\n const getTransitionDurationFromElement = element => {\n if (!element) {\n return 0;\n }\n\n // Get transition-duration of the element\n let {\n transitionDuration,\n transitionDelay\n } = window.getComputedStyle(element);\n const floatTransitionDuration = Number.parseFloat(transitionDuration);\n const floatTransitionDelay = Number.parseFloat(transitionDelay);\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0;\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0];\n transitionDelay = transitionDelay.split(',')[0];\n return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n };\n const triggerTransitionEnd = element => {\n element.dispatchEvent(new Event(TRANSITION_END));\n };\n const isElement = object => {\n if (!object || typeof object !== 'object') {\n return false;\n }\n if (typeof object.jquery !== 'undefined') {\n object = object[0];\n }\n return typeof object.nodeType !== 'undefined';\n };\n const getElement = object => {\n // it's a jQuery object or a node element\n if (isElement(object)) {\n return object.jquery ? object[0] : object;\n }\n if (typeof object === 'string' && object.length > 0) {\n return document.querySelector(parseSelector(object));\n }\n return null;\n };\n const isVisible = element => {\n if (!isElement(element) || element.getClientRects().length === 0) {\n return false;\n }\n const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
1\n // Handle `details` element as its content may falsie appear visible when it is closed\n const closedDetails = element.closest('details:not([open])');\n if (!closedDetails) {\n return elementIsVisible;\n }\n if (closedDetails !== element) {\n const summary = element.closest('summary');\n if (summary && summary.parentNode !== closedDetails) {\n return false;\n }\n if (summary === null) {\n return false;\n }\n }\n return elementIsVisible;\n };\n const isDisabled = element => {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return true;\n }\n if (element.classList.contains('disabled')) {\n return true;\n }\n if (typeof element.disabled !== 'undefined') {\n return element.disabled;\n }\n return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n };\n const findShadowRoot = element => {\n if (!document.documentElement.attachShadow) {\n return null;\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode();\n return root instanceof ShadowRoot ? root : null;\n }\n if (element instanceof ShadowRoot) {\n return element;\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null;\n }\n return findShadowRoot(element.parentNode);\n };\n const noop = () => {};\n\n /**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\n const reflow = element => {\n element.offsetHeight; // eslint-disable-line no-unused-expressions\n };\n const getjQuery = () => {\n if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n return window.jQuery;\n }\n return null;\n };\n const DOMContentLoadedCallbacks = [];\n const onDOMContentLoaded = callback => {\n if (document.readyState === 'loading') {\n // add listener on the first call when the document is in loading state\n if (!DOMContentLoadedCallbacks.length) {\n document.addEventListener('DOMContentLoaded', () => {\n for (const callback of DOMContentLoadedCallbacks) {\n callback();\n }\n });\n }\n DOMContentLoadedCallbacks.push(callback);\n } else {\n callback();\n }\n };\n const isRTL = () => document.documentElement.dir === 'rtl';\n const defineJQueryPlugin = plugin => {\n onDOMContentLoaded(() => {\n const $ = getjQuery();\n /* istanbul ignore if */\n if ($) {\n const name = plugin.NAME;\n const JQUERY_NO_CONFLICT = $.fn[name];\n $.fn[name] = plugin.jQueryInterface;\n $.fn[name].Constructor = plugin;\n $.fn[name].noConflict = () => {\n $.fn[name] = JQUERY_NO_CONFLICT;\n return plugin.jQueryInterface;\n };\n }\n });\n };\n const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {\n return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;\n };\n const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n if (!waitForTransition) {\n execute(callback);\n return;\n }\n const durationPadding = 5;\n const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n let called = false;\n const handler = ({\n target\n }) => {\n if (target !== transitionElement) {\n return;\n }\n called = true;\n transitionElement.removeEventListener(TRANSITION_END, handler);\n execute(callback);\n };\n transitionElement.addEventListener(TRANSITION_END, handler);\n setTimeout(() => {\n if (!called) {\n triggerTransitionEnd(transitionElement);\n }\n }, emulatedDuration);\n };\n\n /**\n * Return the previous/next element of a list.\n *\n * @param {array} list The list of elements\n * @param activeElement The active element\n * @param shouldGetNext Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\n const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) =>
1 {\n const listLength = list.length;\n let index = list.indexOf(activeElement);\n\n // if the element does not exist in the list return an element\n // depending on the direction and if cycle is allowed\n if (index === -1) {\n return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];\n }\n index += shouldGetNext ? 1 : -1;\n if (isCycleAllowed) {\n index = (index + listLength) % listLength;\n }\n return list[Math.max(0, Math.min(index, listLength - 1))];\n };\n\n exports.defineJQueryPlugin = defineJQueryPlugin;\n exports.execute = execute;\n exports.executeAfterTransition = executeAfterTransition;\n exports.findShadowRoot = findShadowRoot;\n exports.getElement = getElement;\n exports.getNextActiveElement = getNextActiveElement;\n exports.getTransitionDurationFromElement = getTransitionDurationFromElement;\n exports.getUID = getUID;\n exports.getjQuery = getjQuery;\n exports.isDisabled = isDisabled;\n exports.isElement = isElement;\n exports.isRTL = isRTL;\n exports.isVisible = isVisible;\n exports.noop = noop;\n exports.onDOMContentLoaded = onDOMContentLoaded;\n exports.parseSelector = parseSelector;\n exports.reflow = reflow;\n exports.toType = toType;\n exports.triggerTransitionEnd = triggerTransitionEnd;\n\n Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\n}));\n//# sourceMappingURL=index.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzUuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRSxLQUE0RDtBQUM5RCxFQUFFLENBQ3NHO0FBQ3hHLENBQUMsOEJBQThCOztBQUUvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckIsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0VBQXNFLGVBQWU7QUFDckY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixPQUFPO0FBQ3ZCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYSxhQUFhO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBLGNBQWMsY0FBYztBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHVEQUF1RCxpQkFBaUI7O0FBRXhFLENBQUM7QUFDRCIsInNvdXJjZXMiOlsid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9ib290c3RyYXAvanMvZGlzdC91dGlsL2luZGV4LmpzP2FhNTMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gICogQm9vdHN0cmFwIGluZGV4LmpzIHY1LjMuMyAoaHR0cHM6Ly9nZXRib290c3RyYXAuY29tLylcbiAgKiBDb3B5cmlnaHQgMjAxMS0yMDI0IFRoZSBCb290c3RyYXAgQXV0aG9ycyAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2dyYXBocy9jb250cmlidXRvcnMpXG4gICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gICovXG4oZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBmYWN0b3J5KGV4cG9ydHMpIDpcbiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKFsnZXhwb3J0cyddLCBmYWN0b3J5KSA6XG4gIChnbG9iYWwgP
1SB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWxUaGlzIDogZ2xvYmFsIHx8IHNlbGYsIGZhY3RvcnkoZ2xvYmFsLkluZGV4ID0ge30pKTtcbn0pKHRoaXMsIChmdW5jdGlvbiAoZXhwb3J0cykgeyAndXNlIHN0cmljdCc7XG5cbiAgLyoqXG4gICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAqIEJvb3RzdHJhcCB1dGlsL2luZGV4LmpzXG4gICAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgKi9cblxuICBjb25zdCBNQVhfVUlEID0gMTAwMDAwMDtcbiAgY29uc3QgTUlMTElTRUNPTkRTX01VTFRJUExJRVIgPSAxMDAwO1xuICBjb25zdCBUUkFOU0lUSU9OX0VORCA9ICd0cmFuc2l0aW9uZW5kJztcblxuICAvKipcbiAgICogUHJvcGVybHkgZXNjYXBlIElEcyBzZWxlY3RvcnMgdG8gaGFuZGxlIHdlaXJkIElEc1xuICAgKiBAcGFyYW0ge3N0cmluZ30gc2VsZWN0b3JcbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIGNvbnN0IHBhcnNlU2VsZWN0b3IgPSBzZWxlY3RvciA9PiB7XG4gICAgaWYgKHNlbGVjdG9yICYmIHdpbmRvdy5DU1MgJiYgd2luZG93LkNTUy5lc2NhcGUpIHtcbiAgICAgIC8vIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IgbmVlZHMgZXNjYXBpbmcgdG8gaGFuZGxlIElEcyAoaHRtbDUrKSBjb250YWluaW5nIGZvciBpbnN0YW5jZSAvXG4gICAgICBzZWxlY3RvciA9IHNlbGVjdG9yLnJlcGxhY2UoLyMoW15cXHNcIiMnXSspL2csIChtYXRjaCwgaWQpID0+IGAjJHtDU1MuZXNjYXBlKGlkKX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHNlbGVjdG9yO1xuICB9O1xuXG4gIC8vIFNob3V0LW91dCBBbmd1cyBDcm9sbCAoaHR0cHM6Ly9nb28uZ2wvcHh3UUdwKVxuICBjb25zdCB0b1R5cGUgPSBvYmplY3QgPT4ge1xuICAgIGlmIChvYmplY3QgPT09IG51bGwgfHwgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBgJHtvYmplY3R9YDtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpLm1hdGNoKC9cXHMoW2Etel0rKS9pKVsxXS50b0xvd2VyQ2FzZSgpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBQdWJsaWMgVXRpbCBBUElcbiAgICovXG5cbiAgY29uc3QgZ2V0VUlEID0gcHJlZml4ID0+IHtcbiAgICBkbyB7XG4gICAgICBwcmVmaXggKz0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogTUFYX1VJRCk7XG4gICAgfSB3aGlsZSAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocHJlZml4KSk7XG4gICAgcmV0dXJuIHByZWZpeDtcbiAgfTtcbiAgY29uc3QgZ2V0VHJhbnNpdGlvbkR1cmF0aW9uRnJvbUVsZW1lbnQgPSBlbGVtZW50ID0+IHtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIC8vIEdldCB0cmFuc2l0aW9uLWR1cmF0aW9uIG9mIHRoZSBlbGVtZW50XG4gICAgbGV0IHtcbiAgICAgIHRyYW5zaXRpb25EdXJhdGlvbixcbiAgICAgIHRyYW5zaXRpb25EZWxheVxuICAgIH0gPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgICBjb25zdCBmbG9hdFRyYW5zaXRpb25EdXJhdGlvbiA9IE51bWJlci5wYXJzZUZsb2F0KHRyYW5zaXRpb25EdXJhdGlvbik7XG4gICAgY29uc3QgZmxvYXRUcmFuc2l0aW9uRGVsYXkgPSBOdW1iZXIucGFyc2VGbG9hdCh0cmFuc2l0aW9uRGVsYXkpO1xuXG4gICAgLy8gUmV0dXJuIDAgaWYgZWxlbWVudCBvciB0cmFuc2l0aW9uIGR1cmF0aW9uIGlzIG5vdCBmb3VuZFxuICAgIGlmICghZmxvYXRUcmFuc2l0aW9uRHVyYXRpb24gJiYgIWZsb2F0VHJhbnNpdGlvbkRlbGF5KSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvLyBJZiBtdWx0aXBsZSBkdXJhdGlvbnMgYXJlIGRlZmluZWQsIHRha2UgdGhlIGZpcnN0XG4gICAgdHJhbnNpdGlvbkR1cmF0aW9uID0gdHJhbnNpdGlvbkR1cmF0aW9uLnNwbGl0KCcsJylbMF07XG4gICAgdHJhbnNpdGlvbkRlbGF5ID0gdHJhbnNpdGlvbkRlbGF5LnNwbGl0KCcsJylbMF07XG4gICAgcmV0dXJuIChOdW1iZXIucGFyc2VGbG9hdCh0cmFuc2l0aW9uRHVyYXRpb24pICsgTnVtYmVyLnBhcnNlRmxvYXQodHJhbnNpdGlvbkRlbGF5KSkgKiBNSUxMSVNFQ09ORFNfTVVMVElQTElFUjtcbiAgfTtcbiAgY29uc3QgdHJpZ2dlclRyYW5zaXRpb25FbmQgPSBlbGVtZW50ID0+IHtcbiAgICBlbGVtZW50LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFRSQU5TSVRJT05fRU5EKSk7XG4gIH07XG4gIGNvbnN0IGlzRWxlbWVudCA9IG9iamVjdCA9PiB7XG4gICAgaWYgKCFvYmplY3QgfHwgdHlwZW9mIG9iamVjdCAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmplY3QuanF1ZXJ5ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgb2JqZWN0ID0gb2JqZWN0WzBdO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZW9mIG9iamVjdC5ub2RlVHlwZSAhPT0gJ3VuZGVmaW5lZCc7XG4gIH07XG4gIGNvbnN0IGdldEVsZW1lbnQgPSBvYmplY3QgPT4ge1xuICAgIC8vIGl0J3MgYSBqUXVlcnkgb2JqZWN0IG9yIGEgbm9kZSBlbGVtZW50XG4gICAgaWYgKGlzRWxlbWVudChvYmplY3QpKSB7XG4gICAgICByZXR1cm4gb2JqZWN0LmpxdWVyeSA/IG9iamVjdFswXSA6IG9iamVjdDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihwYXJzZVNlbGVjdG9yKG9iamVjdCkpO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcbiAgY29uc3QgaXNWaXNpYmxlID0gZWxlbWVudCA9PiB7XG4gICAgaWYgKCFpc0VsZW1lbnQoZWxlbWVudCkgfHwgZWxlbWVudC5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBlbGVtZW50SXNWaXNpYmxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKCd2aXNpYmlsaXR5JykgPT09ICd2aXNpYmxlJztcbiAgICAvLyBIYW5kbGUgYGRldGFpbHNgIGVsZW1lbnQgYXMgaXRzIGNvbnRlbnQgbWF5IGZhbHNpZSBhcHBlYXIgdmlzaWJsZSB3aGVuIGl0IGlzIGNsb3NlZFxuICAgIGNvbnN0IGNsb3NlZERldGFpbHMgPSBlbGVtZW50LmNsb3Nlc3QoJ2RldGFpbHM6bm90KFtvcGVuXSknKTtcbiAgICBpZiAoIWNsb3NlZERldGFpbHMpIHtcbiAgICAgIHJldHVybi
1BlbGVtZW50SXNWaXNpYmxlO1xuICAgIH1cbiAgICBpZiAoY2xvc2VkRGV0YWlscyAhPT0gZWxlbWVudCkge1xuICAgICAgY29uc3Qgc3VtbWFyeSA9IGVsZW1lbnQuY2xvc2VzdCgnc3VtbWFyeScpO1xuICAgICAgaWYgKHN1bW1hcnkgJiYgc3VtbWFyeS5wYXJlbnROb2RlICE9PSBjbG9zZWREZXRhaWxzKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChzdW1tYXJ5ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGVsZW1lbnRJc1Zpc2libGU7XG4gIH07XG4gIGNvbnN0IGlzRGlzYWJsZWQgPSBlbGVtZW50ID0+IHtcbiAgICBpZiAoIWVsZW1lbnQgfHwgZWxlbWVudC5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2Rpc2FibGVkJykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGVsZW1lbnQuZGlzYWJsZWQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZWxlbWVudC5kaXNhYmxlZDtcbiAgICB9XG4gICAgcmV0dXJuIGVsZW1lbnQuaGFzQXR0cmlidXRlKCdkaXNhYmxlZCcpICYmIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkaXNhYmxlZCcpICE9PSAnZmFsc2UnO1xuICB9O1xuICBjb25zdCBmaW5kU2hhZG93Um9vdCA9IGVsZW1lbnQgPT4ge1xuICAgIGlmICghZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmF0dGFjaFNoYWRvdykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gQ2FuIGZpbmQgdGhlIHNoYWRvdyByb290IG90aGVyd2lzZSBpdCdsbCByZXR1cm4gdGhlIGRvY3VtZW50XG4gICAgaWYgKHR5cGVvZiBlbGVtZW50LmdldFJvb3ROb2RlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb25zdCByb290ID0gZWxlbWVudC5nZXRSb290Tm9kZSgpO1xuICAgICAgcmV0dXJuIHJvb3QgaW5zdGFuY2VvZiBTaGFkb3dSb290ID8gcm9vdCA6IG51bGw7XG4gICAgfVxuICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgU2hhZG93Um9vdCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLy8gd2hlbiB3ZSBkb24ndCBmaW5kIGEgc2hhZG93IHJvb3RcbiAgICBpZiAoIWVsZW1lbnQucGFyZW50Tm9kZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBmaW5kU2hhZG93Um9vdChlbGVtZW50LnBhcmVudE5vZGUpO1xuICB9O1xuICBjb25zdCBub29wID0gKCkgPT4ge307XG5cbiAgLyoqXG4gICAqIFRyaWNrIHRvIHJlc3RhcnQgYW4gZWxlbWVudCdzIGFuaW1hdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqIEByZXR1cm4gdm9pZFxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LmNoYXJpc3RoZW8uaW8vYmxvZy8yMDIxLzAyL3Jlc3RhcnQtYS1jc3MtYW5pbWF0aW9uLXdpdGgtamF2YXNjcmlwdC8jcmVzdGFydGluZy1hLWNzcy1hbmltYXRpb25cbiAgICovXG4gIGNvbnN0IHJlZmxvdyA9IGVsZW1lbnQgPT4ge1xuICAgIGVsZW1lbnQub2Zmc2V0SGVpZ2h0OyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuICB9O1xuICBjb25zdCBnZXRqUXVlcnkgPSAoKSA9PiB7XG4gICAgaWYgKHdpbmRvdy5qUXVlcnkgJiYgIWRvY3VtZW50LmJvZHkuaGFzQXR0cmlidXRlKCdkYXRhLWJzLW5vLWpxdWVyeScpKSB7XG4gICAgICByZXR1cm4gd2luZG93LmpRdWVyeTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG4gIGNvbnN0IERPTUNvbnRlbnRMb2FkZWRDYWxsYmFja3MgPSBbXTtcbiAgY29uc3Qgb25ET01Db250ZW50TG9hZGVkID0gY2FsbGJhY2sgPT4ge1xuICAgIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnbG9hZGluZycpIHtcbiAgICAgIC8vIGFkZCBsaXN0ZW5lciBvbiB0aGUgZmlyc3QgY2FsbCB3aGVuIHRoZSBkb2N1bWVudCBpcyBpbiBsb2FkaW5nIHN0YXRlXG4gICAgICBpZiAoIURPTUNvbnRlbnRMb2FkZWRDYWxsYmFja3MubGVuZ3RoKSB7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgZm9yIChjb25zdCBjYWxsYmFjayBvZiBET01Db250ZW50TG9hZGVkQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBET01Db250ZW50TG9hZGVkQ2FsbGJhY2tzLnB1c2goY2FsbGJhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgfTtcbiAgY29uc3QgaXNSVEwgPSAoKSA9PiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGlyID09PSAncnRsJztcbiAgY29uc3QgZGVmaW5lSlF1ZXJ5UGx1Z2luID0gcGx1Z2luID0+IHtcbiAgICBvbkRPTUNvbnRlbnRMb2FkZWQoKCkgPT4ge1xuICAgICAgY29uc3QgJCA9IGdldGpRdWVyeSgpO1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICBpZiAoJCkge1xuICAgICAgICBjb25zdCBuYW1lID0gcGx1Z2luLk5BTUU7XG4gICAgICAgIGNvbnN0IEpRVUVSWV9OT19DT05GTElDVCA9ICQuZm5bbmFtZV07XG4gICAgICAgICQuZm5bbmFtZV0gPSBwbHVnaW4ualF1ZXJ5SW50ZXJmYWNlO1xuICAgICAgICAkLmZuW25hbWVdLkNvbnN0cnVjdG9yID0gcGx1Z2luO1xuICAgICAgICAkLmZuW25hbWVdLm5vQ29uZmxpY3QgPSAoKSA9PiB7XG4gICAgICAgICAgJC5mbltuYW1lXSA9IEpRVUVSWV9OT19DT05GTElDVDtcbiAgICAgICAgICByZXR1cm4gcGx1Z2luLmpRdWVyeUludGVyZmFjZTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbiAgY29uc3QgZXhlY3V0ZSA9IChwb3NzaWJsZUNhbGxiYWNrLCBhcmdzID0gW10sIGRlZmF1bHRWYWx1ZSA9IHBvc3NpYmxlQ2FsbGJhY2spID0+IHtcbiAgICByZXR1cm4gdHlwZW9mIHBvc3NpYmxlQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicgPyBwb3NzaWJsZUNhbGxiYWNrKC4uLmFyZ3MpIDogZGVmYXVsdFZhbHVlO1xuICB9O1xuICBjb25zdCBleGVjdXRlQWZ0ZXJUcmFuc2l0aW9uID0gKGNhbGxiYWNrLCB0cmFuc2l0aW9uRWxlbWVudCwgd2FpdEZvclRyYW5zaXRpb24gPSB0cnVlKSA9PiB7XG4gICAgaWYgKCF3YWl
10Rm9yVHJhbnNpdGlvbikge1xuICAgICAgZXhlY3V0ZShjYWxsYmFjayk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGR1cmF0aW9uUGFkZGluZyA9IDU7XG4gICAgY29uc3QgZW11bGF0ZWREdXJhdGlvbiA9IGdldFRyYW5zaXRpb25EdXJhdGlvbkZyb21FbGVtZW50KHRyYW5zaXRpb25FbGVtZW50KSArIGR1cmF0aW9uUGFkZGluZztcbiAgICBsZXQgY2FsbGVkID0gZmFsc2U7XG4gICAgY29uc3QgaGFuZGxlciA9ICh7XG4gICAgICB0YXJnZXRcbiAgICB9KSA9PiB7XG4gICAgICBpZiAodGFyZ2V0ICE9PSB0cmFuc2l0aW9uRWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgdHJhbnNpdGlvbkVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihUUkFOU0lUSU9OX0VORCwgaGFuZGxlcik7XG4gICAgICBleGVjdXRlKGNhbGxiYWNrKTtcbiAgICB9O1xuICAgIHRyYW5zaXRpb25FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoVFJBTlNJVElPTl9FTkQsIGhhbmRsZXIpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgICAgdHJpZ2dlclRyYW5zaXRpb25FbmQodHJhbnNpdGlvbkVsZW1lbnQpO1xuICAgICAgfVxuICAgIH0sIGVtdWxhdGVkRHVyYXRpb24pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHByZXZpb3VzL25leHQgZWxlbWVudCBvZiBhIGxpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7YXJyYXl9IGxpc3QgICAgVGhlIGxpc3Qgb2YgZWxlbWVudHNcbiAgICogQHBhcmFtIGFjdGl2ZUVsZW1lbnQgICBUaGUgYWN0aXZlIGVsZW1lbnRcbiAgICogQHBhcmFtIHNob3VsZEdldE5leHQgICBDaG9vc2UgdG8gZ2V0IG5leHQgb3IgcHJldmlvdXMgZWxlbWVudFxuICAgKiBAcGFyYW0gaXNDeWNsZUFsbG93ZWRcbiAgICogQHJldHVybiB7RWxlbWVudHxlbGVtfSBUaGUgcHJvcGVyIGVsZW1lbnRcbiAgICovXG4gIGNvbnN0IGdldE5leHRBY3RpdmVFbGVtZW50ID0gKGxpc3QsIGFjdGl2ZUVsZW1lbnQsIHNob3VsZEdldE5leHQsIGlzQ3ljbGVBbGxvd2VkKSA9PiB7XG4gICAgY29uc3QgbGlzdExlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICAgIGxldCBpbmRleCA9IGxpc3QuaW5kZXhPZihhY3RpdmVFbGVtZW50KTtcblxuICAgIC8vIGlmIHRoZSBlbGVtZW50IGRvZXMgbm90IGV4aXN0IGluIHRoZSBsaXN0IHJldHVybiBhbiBlbGVtZW50XG4gICAgLy8gZGVwZW5kaW5nIG9uIHRoZSBkaXJlY3Rpb24gYW5kIGlmIGN5Y2xlIGlzIGFsbG93ZWRcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm4gIXNob3VsZEdldE5leHQgJiYgaXNDeWNsZUFsbG93ZWQgPyBsaXN0W2xpc3RMZW5ndGggLSAxXSA6IGxpc3RbMF07XG4gICAgfVxuICAgIGluZGV4ICs9IHNob3VsZEdldE5leHQgPyAxIDogLTE7XG4gICAgaWYgKGlzQ3ljbGVBbGxvd2VkKSB7XG4gICAgICBpbmRleCA9IChpbmRleCArIGxpc3RMZW5ndGgpICUgbGlzdExlbmd0aDtcbiAgICB9XG4gICAgcmV0dXJuIGxpc3RbTWF0aC5tYXgoMCwgTWF0aC5taW4oaW5kZXgsIGxpc3RMZW5ndGggLSAxKSldO1xuICB9O1xuXG4gIGV4cG9ydHMuZGVmaW5lSlF1ZXJ5UGx1Z2luID0gZGVmaW5lSlF1ZXJ5UGx1Z2luO1xuICBleHBvcnRzLmV4ZWN1dGUgPSBleGVjdXRlO1xuICBleHBvcnRzLmV4ZWN1dGVBZnRlclRyYW5zaXRpb24gPSBleGVjdXRlQWZ0ZXJUcmFuc2l0aW9uO1xuICBleHBvcnRzLmZpbmRTaGFkb3dSb290ID0gZmluZFNoYWRvd1Jvb3Q7XG4gIGV4cG9ydHMuZ2V0RWxlbWVudCA9IGdldEVsZW1lbnQ7XG4gIGV4cG9ydHMuZ2V0TmV4dEFjdGl2ZUVsZW1lbnQgPSBnZXROZXh0QWN0aXZlRWxlbWVudDtcbiAgZXhwb3J0cy5nZXRUcmFuc2l0aW9uRHVyYXRpb25Gcm9tRWxlbWVudCA9IGdldFRyYW5zaXRpb25EdXJhdGlvbkZyb21FbGVtZW50O1xuICBleHBvcnRzLmdldFVJRCA9IGdldFVJRDtcbiAgZXhwb3J0cy5nZXRqUXVlcnkgPSBnZXRqUXVlcnk7XG4gIGV4cG9ydHMuaXNEaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gIGV4cG9ydHMuaXNFbGVtZW50ID0gaXNFbGVtZW50O1xuICBleHBvcnRzLmlzUlRMID0gaXNSVEw7XG4gIGV4cG9ydHMuaXNWaXNpYmxlID0gaXNWaXNpYmxlO1xuICBleHBvcnRzLm5vb3AgPSBub29wO1xuICBleHBvcnRzLm9uRE9NQ29udGVudExvYWRlZCA9IG9uRE9NQ29udGVudExvYWRlZDtcbiAgZXhwb3J0cy5wYXJzZVNlbGVjdG9yID0gcGFyc2VTZWxlY3RvcjtcbiAgZXhwb3J0cy5yZWZsb3cgPSByZWZsb3c7XG4gIGV4cG9ydHMudG9UeXBlID0gdG9UeXBlO1xuICBleHBvcnRzLnRyaWdnZXJUcmFuc2l0aW9uRW5kID0gdHJpZ2dlclRyYW5zaXRpb25FbmQ7XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cbn0pKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///35\n")},137:function(module,exports,__webpack_require__){eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**\n * EvEmitter v1.1.0\n * Lil' event emitter\n * MIT License\n */\n\n/* jshint unused: true, undef: true, strict: true */\n\n( function( global, factory ) {\n // universal module definition\n /* jshint strict: false */ /* globals define, module, window */\n if ( true ) {\n // AMD - RequireJS\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( typeof window != 'undefined' ? window : this, function() {\n\n\"use strict\";\n\nfunction EvEmitter() {}\n\nvar proto = EvEmitter.prototype;\n\nproto.on = function( eventName, listener ) {\n if ( !eventName || !listener ) {\n return;\n }\n // set events hash\n var events = this._events = this._events || {};\n // set listeners array\n var listeners = events[ eventName ] = events[ eventName ] || [];\n // only add once\n if ( listeners.indexOf( listener ) == -1 ) {\n listeners.push( listener );\n }\n\n return this;\n};\n\nproto.once = function( eventName, listener ) {\n if ( !eventName || !listener ) {\n return;\n }\n // add event\n this.on( eventName, listener );\n // set once flag\n // set onceEvents hash\n var onceEvents = this._onceEvents = this._onceEvents || {};\n // set onceListeners object\n var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};\n // set flag\n onceListeners[ listener ] = true;\n\n return this;\n};\n\nproto.off = function( eventName, listener ) {\n var listeners = this._events && this._events[ eventName ];\n if ( !listeners || !listeners.length ) {\n return;\n }\n var index = listeners.indexOf( listener );\n if ( index != -1 ) {\n listeners.splice( index, 1 );\n }\n\n return this;\n};\n\nproto.emitEvent = function( eventName, args ) {\n var listeners = this._events && this._events[ eventName ];\n if ( !listeners || !listeners.length ) {\n return;\n }\n // copy over to avoid interference if .off() in listener\n listeners = listeners.slice(0);\n args = args || [];\n // once stuff\n var onceListeners = this._onceEvents && this._onceEvents[ eventName ];\n\n for ( var i=0; i < listeners.length; i++ ) {\n var listener = listeners[i]\n var isOnce = onceListeners && onceListeners[ listener ];\n if ( isOnce ) {\n // remove listener\n // remove before trigger to prevent recursion\n this.off( eventName, listener );\n // unset once flag\n delete onceListeners[ listener ];\n }\n // trigger listener\n listener.apply( this, args );\n }\n\n return this;\n};\n\nproto.allOff = function() {\n delete this._events;\n delete this._onceEvents;\n};\n\nreturn EvEmitter;\n\n}));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTM3LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTyxJQUF5QztBQUNoRDtBQUNBLElBQUksb0NBQVEsT0FBTztBQUFBO0FBQUE7QUFBQTtBQUFBLGtHQUFFO0FBQ3JCLElBQUksS0FBSyxFQU1OOztBQUVILENBQUM7O0FBRUQ7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsc0JBQXNCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9ib3N0cm9tLXdlYnBhY2svLi9ub2RlX21vZHVsZXMvZXYtZW1pdHRlci9ldi1lbWl0dGVyLmpzPzA5NDkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBFdkVtaXR0ZXIgdjEuMS4wXG4gKiBMaWwnIGV2ZW50IGVtaXR0ZXJcbiAqIE1JVCBMaWNlbnNlXG4gKi9cblxuLyoganNoaW50IHVudXNlZDogdHJ1ZSwgdW5kZWY6IHRydWUsIHN0cmljdDogdHJ1ZSAqL1xuXG4oIGZ1bmN0aW9uKCBnbG9iYWwsIGZhY3RvcnkgKSB7XG4gIC8vIHVuaXZlcnNhbCBtb2R1bGUgZGVmaW5pdGlvblxuICAvKiBqc2hpbnQgc3RyaWN0OiBmYWxzZSAqLyAvKiBnbG9iYWxzIGRlZmluZSwgbW9kdWxlLCB3aW5kb3cgKi9cbiAgaWYgKCB0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCApIHtcbiAgICAvLyBBTUQgLSBSZXF1aXJlSlNcbiAgICBkZWZpbmUoIGZhY3RvcnkgKTtcbiAgfSBlbHNlIGlmICggdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cyApIHtcbiAgICAvLyBDb21tb25KUyAtIEJyb3dzZXJpZnksIFdlYnBhY2tcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBCcm93c2VyIGdsb2JhbHNcbiAgICBnbG9iYWwuRXZFbWl0dGVyID0gZmFjdG9yeSgpO1xuICB9XG5cbn0oIHR5cGVvZiB3aW5kb3cgIT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzLCBmdW5jdGlvbigpIHtcblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbmZ1bmN0aW9uIEV2RW1pdHRlcigpIHt9XG5cbnZhciBwcm90byA9IEV2RW1pdHRlci5wcm90b3R5cGU7XG5cbnByb3RvLm9uID0gZnVuY3Rpb24oIGV2ZW50TmFtZSwgbGlzdGVuZXIgKSB7XG4gIGlmICggIWV2ZW50TmFtZSB8fCAhbGlzdGVuZXIgKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIHNldCBldmVudHMgaGFzaFxuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICAvLyBzZXQgbGlzdGVuZXJzIGFycmF5XG4gIHZhciBsaXN0ZW5lcnMgPSBldmVudHNbIGV2ZW50TmFtZSBdID0gZXZlbnRzWyBldmVudE5hbWUgXSB8fCBbXTtcbiAgLy8gb25seSBhZGQgb25jZVxuICBpZiAoIGxpc3RlbmVycy5pbmRleE9mKCBsaXN0ZW5lciApID09IC0xICkge1xuICAgIGxpc3RlbmVycy5wdXNoKCBsaXN0ZW5lciApO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5wcm90by5vbmNlID0gZnVuY3Rpb24oIGV2ZW50TmFtZSwgbGlzdGVuZXIgKSB7XG4gIGlmICggIWV2ZW50TmFtZSB8fCAhbGlzdGVuZXIgKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGFkZCBldmVudFxuICB0aGlzLm9uKCBldmVudE5hbWUsIGxpc3RlbmVyICk7XG4gIC8vIHNldCBvbmNlIGZsYWdcbiAgLy8gc2V0IG9uY2VFdmVudHMgaGFzaFxuICB2YXIgb25jZUV2ZW50cyA9IHRoaXMuX29uY2VFdmVudHMgPSB0aGlzLl9vbmNlRXZlbnRzIHx8IHt9O1xuICAvLyBzZXQgb25jZUxpc3RlbmVycyBvYmplY3RcbiAgdmFyIG9uY2VMaXN0ZW5lcnMgPSBvbmNlRXZlbnRzWyBldmVudE5hbWUgXSA9IG9uY2VFdmVudHNbIGV2ZW50TmFtZSBdIHx8IHt9O1xuICAvLyBzZXQgZmxhZ1xuICBvbmNlTGlzdGVuZXJzWyBsaXN0ZW5lciBdID0gdHJ1ZTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvLm9mZiA9IGZ1bmN0aW9uKCBldmVudE5hbWUsIGxpc3RlbmVyICkge1xuICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzICYmIHRoaXMuX2V2ZW50c1sgZXZlbnROYW1lIF07XG4gIGlmICggIWxpc3RlbmVycyB8fCAhbGlzdGVuZXJzLmxlbmd0aCApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGluZGV4ID0gbGlzdGVuZXJzLmluZGV4T2YoIGxpc3RlbmVyICk7XG4gIGlmICggaW5kZXggIT0gLTEgKSB7XG4gICAgbGlzdGVuZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcbiAgfVxuXG4gIHJldHVybi
1B0aGlzO1xufTtcblxucHJvdG8uZW1pdEV2ZW50ID0gZnVuY3Rpb24oIGV2ZW50TmFtZSwgYXJncyApIHtcbiAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50cyAmJiB0aGlzLl9ldmVudHNbIGV2ZW50TmFtZSBdO1xuICBpZiAoICFsaXN0ZW5lcnMgfHwgIWxpc3RlbmVycy5sZW5ndGggKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGNvcHkgb3ZlciB0byBhdm9pZCBpbnRlcmZlcmVuY2UgaWYgLm9mZigpIGluIGxpc3RlbmVyXG4gIGxpc3RlbmVycyA9IGxpc3RlbmVycy5zbGljZSgwKTtcbiAgYXJncyA9IGFyZ3MgfHwgW107XG4gIC8vIG9uY2Ugc3R1ZmZcbiAgdmFyIG9uY2VMaXN0ZW5lcnMgPSB0aGlzLl9vbmNlRXZlbnRzICYmIHRoaXMuX29uY2VFdmVudHNbIGV2ZW50TmFtZSBdO1xuXG4gIGZvciAoIHZhciBpPTA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpKysgKSB7XG4gICAgdmFyIGxpc3RlbmVyID0gbGlzdGVuZXJzW2ldXG4gICAgdmFyIGlzT25jZSA9IG9uY2VMaXN0ZW5lcnMgJiYgb25jZUxpc3RlbmVyc1sgbGlzdGVuZXIgXTtcbiAgICBpZiAoIGlzT25jZSApIHtcbiAgICAgIC8vIHJlbW92ZSBsaXN0ZW5lclxuICAgICAgLy8gcmVtb3ZlIGJlZm9yZSB0cmlnZ2VyIHRvIHByZXZlbnQgcmVjdXJzaW9uXG4gICAgICB0aGlzLm9mZiggZXZlbnROYW1lLCBsaXN0ZW5lciApO1xuICAgICAgLy8gdW5zZXQgb25jZSBmbGFnXG4gICAgICBkZWxldGUgb25jZUxpc3RlbmVyc1sgbGlzdGVuZXIgXTtcbiAgICB9XG4gICAgLy8gdHJpZ2dlciBsaXN0ZW5lclxuICAgIGxpc3RlbmVyLmFwcGx5KCB0aGlzLCBhcmdzICk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvLmFsbE9mZiA9IGZ1bmN0aW9uKCkge1xuICBkZWxldGUgdGhpcy5fZXZlbnRzO1xuICBkZWxldGUgdGhpcy5fb25jZUV2ZW50cztcbn07XG5cbnJldHVybiBFdkVtaXR0ZXI7XG5cbn0pKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///137\n")},943:function(module,exports,__webpack_require__){eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * imagesLoaded v4.1.4\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n\n( function( window, factory ) { 'use strict';\n // universal module definition\n\n /*global define: false, module: false, require: false */\n\n if ( true ) {\n // AMD\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [\n __webpack_require__(137)\n ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( EvEmitter ) {\n return factory( window, EvEmitter );\n }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n\n})( typeof window !== 'undefined' ? window : this,\n\n// -------------------------- factory -------------------------- //\n\nfunction factory( window, EvEmitter ) {\n\n'use strict';\n\nvar $ = window.jQuery;\nvar console = window.console;\n\n// -------------------------- helpers -------------------------- //\n\n// extend objects\nfunction extend( a, b ) {\n for ( var prop in b ) {\n a[ prop ] = b[ prop ];\n }\n return a;\n}\n\nvar arraySlice = Array.prototype.slice;\n\n// turn element or nodeList into an array\nfunction makeArray( obj ) {\n if ( Array.isArray( obj ) ) {\n // use object if already an array\n return obj;\n }\n\n var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';\n if ( isArrayLike ) {\n // convert nodeList to array\n return arraySlice.call( obj );\n }\n\n // array of single index\n return [ obj ];\n}\n\n// -------------------------- imagesLoaded -------------------------- //\n\n/**\n * @param {Array, Element, NodeList, String} elem\n * @param {Object or Function} options - if function, use as callback\n * @param {Function} onAlways - callback function\n */\nfunction ImagesLoaded( elem, options, onAlways ) {\n // coerce ImagesLoaded() without new, to be new ImagesLoaded()\n if ( !( this instanceof ImagesLoaded ) ) {\n return new ImagesLoaded( elem, options, onAlways );\n }\n // use elem as selector string\n var queryElem = elem;\n if ( typeof elem == 'string' ) {\n queryElem = document.querySelectorAll( elem );\n }\n // bail if bad element\n if ( !queryElem ) {\n console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );\n return;\n }\n\n this.elements = makeArray( queryElem );\n this.options = extend( {}, this.options );\n // shift arguments if no options set\n if ( typeof options == 'function' ) {\n onAlways = options;\n } else {\n extend( this.options, options );\n }\n\n if ( onAlways ) {\n this.on( 'always', onAlways );\n }\n\n this.getImages();\n\n if ( $ ) {\n // add jQuery Deferred object\n this.jqDeferred = new $.Deferred();\n }\n\n // HACK check async to allow time to bind listeners\n setTimeout( this.check.bind( this ) );\n}\n\nImagesLoaded.prototype = Object.create( EvEmitter.prototype );\n\nImagesLoaded.prototype.options = {};
1\n\nImagesLoaded.prototype.getImages = function() {\n this.images = [];\n\n // filter & find items if we have an item selector\n this.elements.forEach( this.addElementImages, this );\n};\n\n/**\n * @param {Node} element\n */\nImagesLoaded.prototype.addElementImages = function( elem ) {\n // filter siblings\n if ( elem.nodeName == 'IMG' ) {\n this.addImage( elem );\n }\n // get background image on element\n if ( this.options.background === true ) {\n this.addElementBackgroundImages( elem );\n }\n\n // find children\n // no non-element nodes, #143\n var nodeType = elem.nodeType;\n if ( !nodeType || !elementNodeTypes[ nodeType ] ) {\n return;\n }\n var childImgs = elem.querySelectorAll('img');\n // concat childElems to filterFound array\n for ( var i=0; i < childImgs.length; i++ ) {\n var img = childImgs[i];\n this.addImage( img );\n }\n\n // get child background images\n if ( typeof this.options.background == 'string' ) {\n var children = elem.querySelectorAll( this.options.background );\n for ( i=0; i < children.length; i++ ) {\n var child = children[i];\n this.addElementBackgroundImages( child );\n }\n }\n};\n\nvar elementNodeTypes = {\n 1: true,\n 9: true,\n 11: true\n};\n\nImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {\n var style = getComputedStyle( elem );\n if ( !style ) {\n // Firefox returns null if in a hidden iframe https://bugzil.la/548397\n return;\n }\n // get url inside url(\"...\")\n var reURL = /url\\((['\"])?(.*?)\\1\\)/gi;\n var matches = reURL.exec( style.backgroundImage );\n while ( matches !== null ) {\n var url = matches && matches[2];\n if ( url ) {\n this.addBackground( url, elem );\n }\n matches = reURL.exec( style.backgroundImage );\n }\n};\n\n/**\n * @param {Image} img\n */\nImagesLoaded.prototype.addImage = function( img ) {\n var loadingImage = new LoadingImage( img );\n this.images.push( loadingImage );\n};\n\nImagesLoaded.prototype.addBackground = function( url, elem ) {\n var background = new Background( url, elem );\n this.images.push( background );\n};\n\nImagesLoaded.prototype.check = function() {\n var _this = this;\n this.progressedCount = 0;\n this.hasAnyBroken = false;\n // complete if no images\n if ( !this.images.length ) {\n this.complete();\n return;\n }\n\n function onProgress( image, elem, message ) {\n // HACK - Chrome triggers event before object properties have changed. #83\n setTimeout( function() {\n _this.progress( image, elem, message );\n });\n }\n\n this.images.forEach( function( loadingImage ) {\n loadingImage.once( 'progress', onProgress );\n loadingImage.check();\n });\n};\n\nImagesLoaded.prototype.progress = function( image, elem, message ) {\n this.progressedCount++;\n this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;\n // progress event\n this.emitEvent( 'progress', [ this, image, elem ] );\n if ( this.jqDeferred && this.jqDeferred.notify ) {\n this.jqDeferred.notify( this, image );\n }\n // check if completed\n if ( this.progressedCount == this.images.length ) {\n this.complete();\n }\n\n if ( this.options.debug && console ) {\n console.log( 'progress: ' + message, image, elem );\n }\n};\n\nImagesLoaded.prototype.complete = function() {\n var eventName = this.hasAnyBroken ? 'fail' : 'done';\n this.isComplete = true;\n this.emitEvent( eventName, [ this ] );\n this.emitEvent( 'always', [ this ] );\n if ( this.jqDeferred ) {\n var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';\n this.jqDeferred[ jqMethod ]( this );\n }\n};\n\n// -------------------------- -------------------------- //\n\nfunction LoadingImage( img ) {\n this.img = img;\n}\n\nLoadingImage.prototype = Object.create( EvEmitter.prototype );\n\nLoadingImage.prototype.check = function() {\n // If complete is true and browser supports natural sizes,\n // try to check for image status manually.\n var isComplete = this.getIsImageComplete();\n if ( isComplete ) {\n // report based on naturalWidth\n this.confirm( this.img.naturalWi
1dth !== 0, 'naturalWidth' );\n return;\n }\n\n // If none of the checks above matched, simulate loading on detached element.\n this.proxyImage = new Image();\n this.proxyImage.addEventListener( 'load', this );\n this.proxyImage.addEventListener( 'error', this );\n // bind to image as well for Firefox. #191\n this.img.addEventListener( 'load', this );\n this.img.addEventListener( 'error', this );\n this.proxyImage.src = this.img.src;\n};\n\nLoadingImage.prototype.getIsImageComplete = function() {\n // check for non-zero, non-undefined naturalWidth\n // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671\n return this.img.complete && this.img.naturalWidth;\n};\n\nLoadingImage.prototype.confirm = function( isLoaded, message ) {\n this.isLoaded = isLoaded;\n this.emitEvent( 'progress', [ this, this.img, message ] );\n};\n\n// ----- events ----- //\n\n// trigger specified handler for event type\nLoadingImage.prototype.handleEvent = function( event ) {\n var method = 'on' + event.type;\n if ( this[ method ] ) {\n this[ method ]( event );\n }\n};\n\nLoadingImage.prototype.onload = function() {\n this.confirm( true, 'onload' );\n this.unbindEvents();\n};\n\nLoadingImage.prototype.onerror = function() {\n this.confirm( false, 'onerror' );\n this.unbindEvents();\n};\n\nLoadingImage.prototype.unbindEvents = function() {\n this.proxyImage.removeEventListener( 'load', this );\n this.proxyImage.removeEventListener( 'error', this );\n this.img.removeEventListener( 'load', this );\n this.img.removeEventListener( 'error', this );\n};\n\n// -------------------------- Background -------------------------- //\n\nfunction Background( url, element ) {\n this.url = url;\n this.element = element;\n this.img = new Image();\n}\n\n// inherit LoadingImage prototype\nBackground.prototype = Object.create( LoadingImage.prototype );\n\nBackground.prototype.check = function() {\n this.img.addEventListener( 'load', this );\n this.img.addEventListener( 'error', this );\n this.img.src = this.url;\n // check if image is already complete\n var isComplete = this.getIsImageComplete();\n if ( isComplete ) {\n this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );\n this.unbindEvents();\n }\n};\n\nBackground.prototype.unbindEvents = function() {\n this.img.removeEventListener( 'load', this );\n this.img.removeEventListener( 'error', this );\n};\n\nBackground.prototype.confirm = function( isLoaded, message ) {\n this.isLoaded = isLoaded;\n this.emitEvent( 'progress', [ this, this.element, message ] );\n};\n\n// -------------------------- jQuery -------------------------- //\n\nImagesLoaded.makeJQueryPlugin = function( jQuery ) {\n jQuery = jQuery || window.jQuery;\n if ( !jQuery ) {\n return;\n }\n // set local variable\n $ = jQuery;\n // $().imagesLoaded()\n $.fn.imagesLoaded = function( options, callback ) {\n var instance = new ImagesLoaded( this, options, callback );\n return instance.jqDeferred.promise( $(this) );\n };\n};\n// try making plugin\nImagesLoaded.makeJQueryPlugin();\n\n// -------------------------- -------------------------- //\n\nreturn ImagesLoaded;\n\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYm9zdHJvbS13ZWJwYWNrLy4vbm9kZV9tb2R1bGVzL2ltYWdlc2xvYWRlZC9pbWFnZXNsb2FkZWQuanM/YmQ3ZSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIGltYWdlc0xvYWRlZCB2NC4xLjRcbiAqIEphdmFTY3JpcHQgaXMgYWxsIGxpa2UgXCJZb3UgaW1hZ2VzIGFyZSBkb25lIHlldCBvciB3aGF0P1wiXG4gKiBNSVQgTGljZW5zZVxuICovXG5cbiggZnVuY3Rpb24oIHdpbmRvdywgZmFjdG9yeSApIHsgJ3VzZSBzdHJpY3QnO1xuICAvLyB1bml2ZXJzYWwgbW9kdWxlIGRlZmluaXRpb25cblxuICAvKmdsb2JhbCBkZWZpbmU6IGZhbHNlLCBtb2R1bGU6IGZhbHNlLCByZXF1aXJlOiBmYWxzZSAqL1xuXG4gIGlmICggdHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgKSB7XG4gICAgLy8gQU1EXG4gICAgZGVmaW5lKCBbXG4gICAgICAnZXYtZW1pdHRlci9ldi1lbWl0dGVyJ1xuICAgIF0sIGZ1bmN0aW9uKCBFdkVtaXR0ZXIgKSB7XG4gICAgICByZXR1cm4gZmFjdG9yeSggd2luZG93LCBFdkVtaXR0ZXIgKTtcbiAgICB9KTtcbiAgfSBlbHNlIGlmICggdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cyApIHtcbiAgICAvLyBDb21tb25KU1xuICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShcbiAgICAgIHdpbmRvdyxcbiAgICAgIHJlcXVpcmUoJ2V2LWVtaXR0ZXInKVxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgLy8gYnJvd3NlciBnbG9iYWxcbiAgICB3aW5kb3cuaW1hZ2VzTG9hZGVkID0gZmFjdG9yeShcbiAgICAgIHdpbmRvdyxcbiAgICAgIHdpbmRvdy5FdkVtaXR0ZXJcbiAgICApO1xuICB9XG5cbn0pKCB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMsXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICBmYWN0b3J5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIC8vXG5cbmZ1bmN0aW9uIGZ
1hY3RvcnkoIHdpbmRvdywgRXZFbWl0dGVyICkge1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciAkID0gd2luZG93LmpRdWVyeTtcbnZhciBjb25zb2xlID0gd2luZG93LmNvbnNvbGU7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy9cblxuLy8gZXh0ZW5kIG9iamVjdHNcbmZ1bmN0aW9uIGV4dGVuZCggYSwgYiApIHtcbiAgZm9yICggdmFyIHByb3AgaW4gYiApIHtcbiAgICBhWyBwcm9wIF0gPSBiWyBwcm9wIF07XG4gIH1cbiAgcmV0dXJuIGE7XG59XG5cbnZhciBhcnJheVNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG4vLyB0dXJuIGVsZW1lbnQgb3Igbm9kZUxpc3QgaW50byBhbiBhcnJheVxuZnVuY3Rpb24gbWFrZUFycmF5KCBvYmogKSB7XG4gIGlmICggQXJyYXkuaXNBcnJheSggb2JqICkgKSB7XG4gICAgLy8gdXNlIG9iamVjdCBpZiBhbHJlYWR5IGFuIGFycmF5XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHZhciBpc0FycmF5TGlrZSA9IHR5cGVvZiBvYmogPT0gJ29iamVjdCcgJiYgdHlwZW9mIG9iai5sZW5ndGggPT0gJ251bWJlcic7XG4gIGlmICggaXNBcnJheUxpa2UgKSB7XG4gICAgLy8gY29udmVydCBub2RlTGlzdCB0byBhcnJheVxuICAgIHJldHVybiBhcnJheVNsaWNlLmNhbGwoIG9iaiApO1xuICB9XG5cbiAgLy8gYXJyYXkgb2Ygc2luZ2xlIGluZGV4XG4gIHJldHVybiBbIG9iaiBdO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBpbWFnZXNMb2FkZWQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy9cblxuLyoqXG4gKiBAcGFyYW0ge0FycmF5LCBFbGVtZW50LCBOb2RlTGlzdCwgU3RyaW5nfSBlbGVtXG4gKiBAcGFyYW0ge09iamVjdCBvciBGdW5jdGlvbn0gb3B0aW9ucyAtIGlmIGZ1bmN0aW9uLCB1c2UgYXMgY2FsbGJhY2tcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9uQWx3YXlzIC0gY2FsbGJhY2sgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gSW1hZ2VzTG9h
1ZGVkKCBlbGVtLCBvcHRpb25zLCBvbkFsd2F5cyApIHtcbiAgLy8gY29lcmNlIEltYWdlc0xvYWRlZCgpIHdpdGhvdXQgbmV3LCB0byBiZSBuZXcgSW1hZ2VzTG9hZGVkKClcbiAgaWYgKCAhKCB0aGlzIGluc3RhbmNlb2YgSW1hZ2VzTG9hZGVkICkgKSB7XG4gICAgcmV0dXJuIG5ldyBJbWFnZXNMb2FkZWQoIGVsZW0sIG9wdGlvbnMsIG9uQWx3YXlzICk7XG4gIH1cbiAgLy8gdXNlIGVsZW0gYXMgc2VsZWN0b3Igc3RyaW5nXG4gIHZhciBxdWVyeUVsZW0gPSBlbGVtO1xuICBpZiAoIHR5cGVvZiBlbGVtID09ICdzdHJpbmcnICkge1xuICAgIHF1ZXJ5RWxlbSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIGVsZW0gKTtcbiAgfVxuICAvLyBiYWlsIGlmIGJhZCBlbGVtZW50XG4gIGlmICggIXF1ZXJ5RWxlbSApIHtcbiAgICBjb25zb2xlLmVycm9yKCAnQmFkIGVsZW1lbnQgZm9yIGltYWdlc0xvYWRlZCAnICsgKCBxdWVyeUVsZW0gfHwgZWxlbSApICk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5lbGVtZW50cyA9IG1ha2VBcnJheSggcXVlcnlFbGVtICk7XG4gIHRoaXMub3B0aW9ucyA9IGV4dGVuZCgge30sIHRoaXMub3B0aW9ucyApO1xuICAvLyBzaGlmdCBhcmd1bWVudHMgaWYgbm8gb3B0aW9ucyBzZXRcbiAgaWYgKCB0eXBlb2Ygb3B0aW9ucyA9PSAnZnVuY3Rpb24nICkge1xuICAgIG9uQWx3YXlzID0gb3B0aW9ucztcbiAgfSBlbHNlIHtcbiAgICBleHRlbmQoIHRoaXMub3B0aW9ucywgb3B0aW9ucyApO1xuICB9XG5cbiAgaWYgKCBvbkFsd2F5cyApIHtcbiAgICB0aGlzLm9uKCAnYWx3YXlzJywgb25BbHdheXMgKTtcbiAgfVxuXG4gIHRoaXMuZ2V0SW1hZ2VzKCk7XG5cbiAgaWYgKCAkICkge1xuICAgIC8vIGFkZCBqUXVlcnkgRGVmZXJyZWQgb2JqZWN0XG4gICAgdGhpcy5qcURlZmVycmVkID0gbmV3ICQuRGVmZXJyZWQoKTtcbiAgfVxuXG4gIC8vIEhBQ0sgY2hlY2sgYXN5bmMgdG8gYWxsb3cgdGltZSB0byBiaW5kIGxpc3RlbmVyc1xuICBzZXRUaW1lb3V0KCB0aGlzLmNoZWNrLmJpbmQoIHRoaXMgKSApO1xufVxuXG5JbWFnZXNMb2FkZWQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggRXZFbWl0dGVyLnByb3RvdHlwZSApO1xuXG5JbWFnZXNMb2FkZWQucHJvdG90eXBlLm9wdGlvbnMgPSB7fTtcblxuSW1hZ2VzTG9h
1ZGVkLnByb3RvdHlwZS5nZXRJbWFnZXMgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5pbWFnZXMgPSBbXTtcblxuICAvLyBmaWx0ZXIgJiBmaW5kIGl0ZW1zIGlmIHdlIGhhdmUgYW4gaXRlbSBzZWxlY3RvclxuICB0aGlzLmVsZW1lbnRzLmZvckVhY2goIHRoaXMuYWRkRWxlbWVudEltYWdlcywgdGhpcyApO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IGVsZW1lbnRcbiAqL1xuSW1hZ2VzTG9hZGVkLnByb3RvdHlwZS5hZGRFbGVtZW50SW1hZ2VzID0gZnVuY3Rpb24oIGVsZW0gKSB7XG4gIC8vIGZpbHRlciBzaWJsaW5nc1xuICBpZiAoIGVsZW0ubm9kZU5hbWUgPT0gJ0lNRycgKSB7XG4gICAgdGhpcy5hZGRJbWFnZSggZWxlbSApO1xuICB9XG4gIC8vIGdldCBiYWNrZ3JvdW5kIGltYWdlIG9uIGVsZW1lbnRcbiAgaWYgKCB0aGlzLm9wdGlvbnMuYmFja2dyb3VuZCA9PT0gdHJ1ZSApIHtcbiAgICB0aGlzLmFkZEVsZW1lbnRCYWNrZ3JvdW5kSW1hZ2VzKCBlbGVtICk7XG4gIH1cblxuICAvLyBmaW5kIGNoaWxkcmVuXG4gIC8vIG5vIG5vbi1lbGVtZW50IG5vZGVzLCAjMTQzXG4gIHZhciBub2RlVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG4gIGlmICggIW5vZGVUeXBlIHx8ICFlbGVtZW50Tm9kZVR5cGVzWyBub2RlVHlwZSBdICkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgY2hpbGRJbWdzID0gZWxlbS5xdWVyeVNlbGVjdG9yQWxsKCdpbWcnKTtcbiAgLy8gY29uY2F0IGNoaWxkRWxlbXMgdG8gZmlsdGVyRm91bmQgYXJyYXlcbiAgZm9yICggdmFyIGk9MDsgaSA8IGNoaWxkSW1ncy5sZW5ndGg7IGkrKyApIHtcbiAgICB2YXIgaW1nID0gY2hpbGRJbWdzW2ldO1xuICAgIHRoaXMuYWRkSW1hZ2UoIGltZyApO1xuICB9XG5cbiAgLy8gZ2V0IGNoaWxkIGJhY2tncm91bmQgaW1hZ2VzXG4gIGlmICggdHlwZW9mIHRoaXMub3B0aW9ucy5iYWNrZ3JvdW5kID09ICdzdHJpbmcnICkge1xuICAgIHZhciBjaGlsZHJlbiA9IGVsZW0ucXVlcnlTZWxlY3RvckFsbCggdGhpcy5vcHRpb25zLmJhY2tncm91bmQgKTtcbiAgICBmb3IgKCBpPTA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKyApIHtcbiAgICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW2ldO1xuICAgICAgdGhpcy5hZGRFbGVtZW50QmFja2dyb3VuZEltYWdlcyggY2hpbGQgKTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBlbGVtZW50Tm9kZVR5cGVzID0ge1xuICAxOiB0cnVlLFxuICA5OiB0cnVlLFxuICAxMTogdHJ1ZVxufTtcblxuSW1hZ2VzTG9h
1ZGVkLnByb3RvdHlwZS5hZGRFbGVtZW50QmFja2dyb3VuZEltYWdlcyA9IGZ1bmN0aW9uKCBlbGVtICkge1xuICB2YXIgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKCBlbGVtICk7XG4gIGlmICggIXN0eWxlICkge1xuICAgIC8vIEZpcmVmb3ggcmV0dXJucyBudWxsIGlmIGluIGEgaGlkZGVuIGlmcmFtZSBodHRwczovL2J1Z3ppbC5sYS81NDgzOTdcbiAgICByZXR1cm47XG4gIH1cbiAgLy8gZ2V0IHVybCBpbnNpZGUgdXJsKFwiLi4uXCIpXG4gIHZhciByZVVSTCA9IC91cmxcXCgoWydcIl0pPyguKj8pXFwxXFwpL2dpO1xuICB2YXIgbWF0Y2hlcyA9IHJlVVJMLmV4ZWMoIHN0eWxlLmJhY2tncm91bmRJbWFnZSApO1xuICB3aGlsZSAoIG1hdGNoZXMgIT09IG51bGwgKSB7XG4gICAgdmFyIHVybCA9IG1hdGNoZXMgJiYgbWF0Y2hlc1syXTtcbiAgICBpZiAoIHVybCApIHtcbiAgICAgIHRoaXMuYWRkQmFja2dyb3VuZCggdXJsLCBlbGVtICk7XG4gICAgfVxuICAgIG1hdGNoZXMgPSByZVVSTC5leGVjKCBzdHlsZS5iYWNrZ3JvdW5kSW1hZ2UgKTtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge0ltYWdlfSBpbWdcbiAqL1xuSW1hZ2VzTG9hZGVkLnByb3RvdHlwZS5hZGRJbWFnZSA9IGZ1bmN0aW9uKCBpbWcgKSB7XG4gIHZhciBsb2FkaW5nSW1hZ2UgPSBuZXcgTG9hZGluZ0ltYWdlKCBpbWcgKTtcbiAgdGhpcy5pbWFnZXMucHVzaCggbG9hZGluZ0ltYWdlICk7XG59O1xuXG5JbWFnZXNMb2FkZWQucHJvdG90eXBlLmFkZEJhY2tncm91bmQgPSBmdW5jdGlvbiggdXJsLCBlbGVtICkge1xuICB2YXIgYmFja2dyb3VuZCA9IG5ldyBCYWNrZ3JvdW5kKCB1cmwsIGVsZW0gKTtcbiAgdGhpcy5pbWFnZXMucHVzaCggYmFja2dyb3VuZCApO1xufTtcblxuSW1hZ2VzTG9h
1ZGVkLnByb3RvdHlwZS5jaGVjayA9IGZ1bmN0aW9uKCkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuICB0aGlzLnByb2dyZXNzZWRDb3VudCA9IDA7XG4gIHRoaXMuaGFzQW55QnJva2VuID0gZmFsc2U7XG4gIC8vIGNvbXBsZXRlIGlmIG5vIGltYWdlc1xuICBpZiAoICF0aGlzLmltYWdlcy5sZW5ndGggKSB7XG4gICAgdGhpcy5jb21wbGV0ZSgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MoIGltYWdlLCBlbGVtLCBtZXNzYWdlICkge1xuICAgIC8vIEhBQ0sgLSBDaHJvbWUgdHJpZ2dlcnMgZXZlbnQgYmVmb3JlIG9iamVjdCBwcm9wZXJ0aWVzIGhhdmUgY2hhbmdlZC4gIzgzXG4gICAgc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG4gICAgICBfdGhpcy5wcm9ncmVzcyggaW1hZ2UsIGVsZW0sIG1lc3NhZ2UgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHRoaXMuaW1hZ2VzLmZvckVhY2goIGZ1bmN0aW9uKCBsb2FkaW5nSW1hZ2UgKSB7XG4gICAgbG9hZGluZ0ltYWdlLm9uY2UoICdwcm9ncmVzcycsIG9uUHJvZ3Jlc3MgKTtcbiAgICBsb2FkaW5nSW1hZ2UuY2hlY2soKTtcbiAgfSk7XG59O1xuXG5JbWFnZXNMb2FkZWQucHJvdG90eXBlLnByb2dyZXNzID0gZnVuY3Rpb24oIGltYWdlLCBlbGVtLCBtZXNzYWdlICkge1xuICB0aGlzLnByb2dyZXNzZWRDb3VudCsrO1xuICB0aGlzLmhhc0FueUJyb2tlbiA9IHRoaXMuaGFzQW55QnJva2VuIHx8ICFpbWFnZS5pc0xvYWRlZDtcbiAgLy8gcHJvZ3Jlc3MgZXZlbnRcbiAgdGhpcy5lbWl0RXZlbnQoICdwcm9ncmVzcycsIFsgdGhpcywgaW1hZ2UsIGVsZW0gXSApO1xuICBpZiAoIHRoaXMuanFEZWZlcnJlZCAmJiB0aGlzLmpxRGVmZXJyZWQubm90aWZ5ICkge1xuICAgIHRoaXMuanFEZWZlcnJlZC5ub3RpZnkoIHRoaXMsIGltYWdlICk7XG4gIH1cbiAgLy8gY2hlY2sgaWYgY29tcGxldGVkXG4gIGlmICggdGhpcy5wcm9ncmVzc2VkQ291bnQgPT0gdGhpcy5pbWFnZXMubGVuZ3RoICkge1xuICAgIHRoaXMuY29tcGxldGUoKTtcbiAgfVxuXG4gIGlmICggdGhpcy5vcHRpb25zLmRlYnVnICYmIGNvbnNvbGUgKSB7XG4gICAgY29uc29sZS5sb2coICdwcm9ncmVzczogJyArIG1lc3NhZ2UsIGltYWdlLCBlbGVtICk7XG4gIH1cbn07XG5cbkltYWdlc0xvYWRlZC5wcm90b3R5cGUuY29tcGxldGUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGV2ZW50TmFtZSA9IHRoaXMuaGFzQW55QnJva2VuID8gJ2ZhaWwnIDogJ2RvbmUnO1xuICB0aGlzLmlzQ29tcGxldGUgPSB0cnVlO1xuICB0aGlzLmVtaXRFdmVudCggZXZlbnROYW1lLCBbIHRoaXMgXSApO1xuICB0aGlzLmVtaXRFdmVudCggJ2Fsd2F5cycsIFsgdGhpcyBdICk7XG4gIGlmICggdGhpcy5qcURlZmVycmVkICkge1xuICAgIHZhciBqcU1ldGhvZCA9IHRoaXMuaGFzQW55QnJva2VuID8gJ3JlamVjdCcgOiAncmVzb2x2ZSc7XG4gICAgdGhpcy5qcURlZmVycmVkWyBqcU1ldGhvZCBdKCB0aGlzICk7XG4gIH1cbn07XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAvL1xuXG5mdW5jdGlvbiBMb2FkaW5nSW1hZ2UoIGltZyApIHtcbiAgdGhpcy5pbWcgPSBpbWc7XG59XG5cbkxvYWRpbmdJbWFnZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBFdkVtaXR0ZXIucHJvdG90eXBlICk7XG5cbkxvYWRpbmdJbWFnZS5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbigpIHtcbiAgLy8gSWYgY29tcGxldGUgaXMgdHJ1ZSBhbmQgYnJvd3NlciBzdXBwb3J0cyBuYXR1cmFsIHNpemVzLFxuICAvLyB0cnkgdG8gY2hlY2sgZm9yIGltYWdlIHN0YXR1cyBtYW51YWxseS5cbiAgdmFyIGlzQ29tcGxldGUgPSB0aGlzLmdldElzSW1hZ2VDb21wbGV0ZSgpO1xuICBpZiAoIGlzQ29tcGxldGUgKSB7XG4gICAgLy8gcmVwb3J0IGJhc2VkIG9uIG5hdHVyYWxXaWR0aFxuICAgIHRoaXMuY29uZmlybSggdGhpcy5pbWcubmF0dXJhbFdpZHRoICE9PSAwLCAnbmF0dXJhbFdpZHRoJyApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIElmIG5vbmUgb2YgdGhlIGNoZWNrcyBhYm92ZSBtYXRjaGVkLCBzaW11bGF0ZSBsb2FkaW5nIG9uIGRldGFjaGVkIGVsZW1lbnQuXG4gIHRoaXMucHJveHlJbWFnZSA9IG5ldyBJbWFnZSgpO1xuICB0aGlzLnByb3h5SW1hZ2UuYWRkRXZlbnRMaXN0ZW5lciggJ2xvYWQnLCB0aGlzICk7XG4gIHRoaXMucHJveHlJbWFnZS5hZGRFdmVudExpc3RlbmVyKCAnZXJyb3InLCB0aGlzICk7XG4gIC8vIGJpbmQgdG8gaW1hZ2UgYXMgd2VsbCBmb3IgRmlyZWZveC4gIzE5MVxuICB0aGlzLmltZy5hZGRFdmVudExpc3RlbmVyKCAnbG9hZCcsIHRoaXMgKTtcbiAgdGhpcy5pbWcuYWRkRXZlbnRMaXN0ZW5lciggJ2Vycm9yJywgdGhpcyApO1xuICB0aGlzLnByb3h5SW1hZ2Uuc3JjID0gdGhpcy5pbWcuc3JjO1xufTtcblxuTG9hZGluZ0ltYWdlLnByb3RvdHlwZS5nZXRJc0ltYWdlQ29tcGxldGUgPSBmdW5jdGlvbigpIHtcbiAgLy8gY2hlY2sgZm9yIG5vbi16ZXJvLCBub24tdW5kZWZpbmVkIG5hdHVyYWxXaWR0aFxuICAvLyBmaXhlcyBTYWZhcmkrSW5maW5pdGVTY3JvbGwrTWFzb25yeSBidWcgaW5maW5pdGUtc2Nyb2xsIzY3MVxuICByZXR1cm4gdGhpcy5pbWcuY29tcGxldGUgJiYgdGhpcy5pbWcubmF0dXJhbFdpZHRoO1xufTtcblxuTG9hZGluZ0ltYWdlLnByb3RvdHlwZS5jb25maXJtID0gZnVuY3Rpb24oIGlzTG9hZGVkLCBtZXNzYWdlICkge1xuICB0aGlzLmlzTG9hZGVkID0gaXNMb2FkZWQ7XG4gIHRoaXMuZW1pdEV2ZW50KCAncHJvZ3Jlc3MnLCBbIHRoaXMsIHRoaXMuaW1nLCBtZXNzYWdlIF0gKTtcbn07XG5cbi8vIC0tLS0tIGV2ZW50cyAtLS0tLSAvL1xuXG4vLyB0cmlnZ2VyIHNwZWNpZmllZCBoYW5kbGVyIGZvciBldmVudCB0eXBlXG5Mb2FkaW5nSW1hZ2UucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24oIGV2ZW50ICkge1xuICB2YXIgbWV0aG9kID0gJ29uJyArIGV2ZW50LnR5cGU7XG4gIGlmICggdGhpc1sgbWV0aG9kIF0gKSB7XG4gICAgdGhpc1sgbWV0aG9kIF0oIGV2ZW50ICk7XG4gIH1cbn07XG5cbkxvYWRpbmdJbWFnZS5wcm90b3R5cGUub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuY29uZmlybSggdHJ1ZSwgJ29ubG9hZCcgKTtcbiAgdGhpcy51bmJpbmRF
1dmVudHMoKTtcbn07XG5cbkxvYWRpbmdJbWFnZS5wcm90b3R5cGUub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmNvbmZpcm0oIGZhbHNlLCAnb25lcnJvcicgKTtcbiAgdGhpcy51bmJpbmRFdmVudHMoKTtcbn07XG5cbkxvYWRpbmdJbWFnZS5wcm90b3R5cGUudW5iaW5kRXZlbnRzID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMucHJveHlJbWFnZS5yZW1vdmVFdmVudExpc3RlbmVyKCAnbG9hZCcsIHRoaXMgKTtcbiAgdGhpcy5wcm94eUltYWdlLnJlbW92ZUV2ZW50TGlzdGVuZXIoICdlcnJvcicsIHRoaXMgKTtcbiAgdGhpcy5pbWcucmVtb3ZlRXZlbnRMaXN0ZW5lciggJ2xvYWQnLCB0aGlzICk7XG4gIHRoaXMuaW1nLnJlbW92ZUV2ZW50TGlzdGVuZXIoICdlcnJvcicsIHRoaXMgKTtcbn07XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEJhY2tncm91bmQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy9cblxuZnVuY3Rpb24gQmFja2dyb3VuZCggdXJsLCBlbGVtZW50ICkge1xuICB0aGlzLnVybCA9IHVybDtcbiAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgdGhpcy5pbWcgPSBuZXcgSW1hZ2UoKTtcbn1cblxuLy8gaW5oZXJpdCBMb2FkaW5nSW1hZ2UgcHJvdG90eXBlXG5CYWNrZ3JvdW5kLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIExvYWRpbmdJbWFnZS5wcm90b3R5cGUgKTtcblxuQmFja2dyb3VuZC5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5pbWcuYWRkRXZlbnRMaXN0ZW5lciggJ2xvYWQnLCB0aGlzICk7XG4gIHRoaXMuaW1nLmFkZEV2ZW50TGlzdGVuZXIoICdlcnJvcicsIHRoaXMgKTtcbiAgdGhpcy5pbWcuc3JjID0gdGhpcy51cmw7XG4gIC8vIGNoZWNrIGlmIGltYWdlIGlzIGFscmVhZHkgY29tcGxldGVcbiAgdmFyIGlzQ29tcGxldGUgPSB0aGlzLmdldElzSW1hZ2VDb21wbGV0ZSgpO1xuICBpZiAoIGlzQ29tcGxldGUgKSB7XG4gICAgdGhpcy5jb25maXJtKCB0aGlzLmltZy5uYXR1cmFsV2lkdGggIT09IDAsICduYXR1cmFsV2lkdGgnICk7XG4gICAgdGhpcy51bmJpbmRFdmVudHMoKTtcbiAgfVxufTtcblxuQmFja2dyb3VuZC5wcm90b3R5cGUudW5iaW5kRXZlbnRzID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuaW1nLnJlbW92ZUV2ZW50TGlzdGVuZXIoICdsb2FkJywgdGhpcyApO1xuICB0aGlzLmltZy5yZW1vdmVFdmVudExpc3RlbmVyKCAnZXJyb3InLCB0aGlzICk7XG59O1xuXG5CYWNrZ3JvdW5kLnByb3RvdHlwZS5jb25maXJtID0gZnVuY3Rpb24oIGlzTG9hZGVkLCBtZXNzYWdlICkge1xuICB0aGlzLmlzTG9hZGVkID0gaXNMb2FkZWQ7XG4gIHRoaXMuZW1pdEV2ZW50KCAncHJvZ3Jlc3MnLCBbIHRoaXMsIHRoaXMuZWxlbWVudCwgbWVzc2FnZSBdICk7XG59O1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBqUXVlcnkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy9cblxuSW1hZ2VzTG9h
1ZGVkLm1ha2VKUXVlcnlQbHVnaW4gPSBmdW5jdGlvbiggalF1ZXJ5ICkge1xuICBqUXVlcnkgPSBqUXVlcnkgfHwgd2luZG93LmpRdWVyeTtcbiAgaWYgKCAhalF1ZXJ5ICkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBzZXQgbG9jYWwgdmFyaWFibGVcbiAgJCA9IGpRdWVyeTtcbiAgLy8gJCgpLmltYWdlc0xvYWRlZCgpXG4gICQuZm4uaW1hZ2VzTG9hZGVkID0gZnVuY3Rpb24oIG9wdGlvbnMsIGNhbGxiYWNrICkge1xuICAgIHZhciBpbnN0YW5jZSA9IG5ldyBJbWFnZXNMb2FkZWQoIHRoaXMsIG9wdGlvbnMsIGNhbGxiYWNrICk7XG4gICAgcmV0dXJuIGluc3RhbmNlLmpxRGVmZXJyZWQucHJvbWlzZSggJCh0aGlzKSApO1xuICB9O1xufTtcbi8vIHRyeSBtYWtpbmcgcGx1Z2luXG5JbWFnZXNMb2FkZWQubWFrZUpRdWVyeVBsdWdpbigpO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy9cblxucmV0dXJuIEltYWdlc0xvYWRlZDtcblxufSk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///943\n")},692:function(module,exports){eval('var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * jQuery JavaScript Library v3.7.1\n * https://jquery.com/\n *\n * Copyright OpenJS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2023-08-28T13:37Z\n */\n( function( global, factory ) {\n\n\t"use strict";\n\n\tif ( true && typeof module.exports === "object" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require("jquery")(window);\n\t\t// See ticket trac-14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( "jQuery requires a window with a document" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n"use strict";\n\nvar arr = [];\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar flat = arr.flat ? function( array ) {\n\treturn arr.flat.call( array );\n} : function( array ) {\n\treturn arr.concat.apply( [], array );\n};\n\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n\t\t// Support: Chrome <=57, Firefox <=52\n\t\t// In some browsers, typeof returns "function" for HTML <object> elements\n\t\t// (i.e., `typeof document.createElement( "object" ) === "function"`).\n\t\t// We don\'t want to classify *any* DOM node as a function.\n\t\t// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5\n\t\t// Plus for old WebKit, typeof returns "function" for HTML collections\n\t\t// (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)\n\t\treturn typeof obj === "function" && typeof obj.nodeType !== "number" &&\n\t\t\ttypeof obj.item !== "function";\n\t};\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\nvar document = window.document;\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( "script" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don\'t support the "nonce" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-
1attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + "";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === "object" || typeof obj === "function" ?\n\t\tclass2type[ toString.call( obj ) ] || "object" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar version = "3.7.1",\n\n\trhtmlSuffix = /HTML$/i,\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor \'enhanced\'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevOb
1ject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teven: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn ( i + 1 ) % 2;\n\t\t} ) );\n\t},\n\n\todd: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn i % 2;\n\t\t} ) );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array\'s method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === "boolean" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== "object" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === "__proto__" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we\'re merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don\'t bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: "jQuery" + ( version + Math.random() ).replace( /\\D/g, "" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== "[object Object]" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, "constructor" ) && proto.constructor;\n\t\treturn typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a provided context; falls back to the global one\n\t// if not specified.\n\tglobalEval: function( code, options, doc ) {\n\t\tDOMEval( code, { nonce: options && options.nonce }, doc );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\n\t// Retrieve the text value of an array of DOM nodes\n\ttext: function( elem ) {\n\t\tvar node,\n\t\t\tret = "",\n\t\t\ti = 0,\n\t\t\tnodeType = elem.nodeType;\n\n\t\tif ( !nodeType ) {\n\n\t\t\t// If no nodeType, this is expected to be an array\n\t\t\twhile ( ( node = elem[ i++ ] ) ) {\n\n\t\t\t\t// Do not traverse comment nodes\n\t\t\t\tret += jQuery.text( node );\n\t\t\t}\n\t\t}\n\t\tif ( nodeType === 1 || nodeType === 11 ) {\n\t\t\treturn elem.textContent;\n\t\t}\n\t\tif ( nodeType === 9 ) {\n\t\t\treturn elem.documentElement.textContent;\n\t\t}\n\t\tif ( nodeType === 3 || nodeType === 4 ) {\n\t\t\treturn elem.nodeValue;\n\t\t}\n\n\t\t// Do not include comment or processing instruction nodes\n\n\t\treturn ret;\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === "string" ?\n\t\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\tisXMLDoc: function( elem ) {\n\t\tvar namespace = elem && elem.namespaceURI,\n\t\t\tdocElem = elem && ( elem.ownerDocument || elem ).documentElement;\n\n\t\t// Assume HTML when documentElement doesn\'t yet exist, such as inside\n\t\t// document fragments.\n\t\treturn !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn flat( ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === "function" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),\n\tfunction( _i, name ) {\n\t\tclass2type[ "[object " + name + "]" ] = name.toLowerCase();\n\t} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn\'t used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && "length" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === "array" || length === 0 ||\n\t\ttypeof length === "number" && length > 0 && ( length - 1 ) in obj;\n}\n\n\nfunction nodeName( elem, name ) {\n\n\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n}\nvar pop = arr.pop;\n\n\nvar sort = arr.sort;\n\n\nvar splice = arr.splice;\n\n\nvar whitespace = "[\\\\x20\\\\t\\\\r\\\\n\\\\f]";\n\n\nvar rtrimCSS = new RegExp(\n\t"^" + whitespace + "+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)" + whitespace + "+$",\n\t"g"\n);\n\n\n\n\n// Note: an element does not contain itself\njQuery.contains = function( a, b ) {\n\tvar bup = b && b.parentNode;\n\n\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\n\t\t// Support: IE 9 - 11+\n\t\t// IE doesn\'t have `contains` on SVG.\n\t\ta.contains ?\n\t\t\ta.contains( bup )
1:\n\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t) );\n};\n\n\n\n\n// CSS string/identifier serialization\n// https://drafts.csswg.org/cssom/#common-serializing-idioms\nvar rcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\x80-\\uFFFF\\w-]/g;\n\nfunction fcssescape( ch, asCodePoint ) {\n\tif ( asCodePoint ) {\n\n\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\tif ( ch === "\\0" ) {\n\t\t\treturn "\\uFFFD";\n\t\t}\n\n\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\treturn ch.slice( 0, -1 ) + "\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";\n\t}\n\n\t// Other potentially-special ASCII characters get backslash-escaped\n\treturn "\\\\" + ch;\n}\n\njQuery.escapeSelector = function( sel ) {\n\treturn ( sel + "" ).replace( rcssescape, fcssescape );\n};\n\n\n\n\nvar preferredDoc = document,\n\tpushNative = push;\n\n( function() {\n\nvar i,\n\tExpr,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\tpush = pushNative,\n\n\t// Local document vars\n\tdocument,\n\tdocumentElement,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\tmatches,\n\n\t// Instance-specific data\n\texpando = jQuery.expando,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\tbooleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" +\n\t\t"loop|multiple|open|readonly|required|scoped",\n\n\t// Regular expressions\n\n\t// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n\tidentifier = "(?:\\\\\\\\[\\\\da-fA-F]{1,6}" + whitespace +\n\t\t"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+",\n\n\t// Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = "\\\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +\n\n\t\t// Operator (capture 2)\n\t\t"*([*^$|!~]?=)" + whitespace +\n\n\t\t// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"\n\t\t"*(?:\'((?:\\\\\\\\.|[^\\\\\\\\\'])*)\'|\\"((?:\\\\\\\\.|[^\\\\\\\\\\"])*)\\"|(" + identifier + "))|)" +\n\t\twhitespace + "*\\\\]",\n\n\tpseudos = ":(" + identifier + ")(?:\\\\((" +\n\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t"(\'((?:\\\\\\\\.|[^\\\\\\\\\'])*)\'|\\"((?:\\\\\\\\.|[^\\\\\\\\\\"])*)\\")|" +\n\n\t\t// 2. simple (capture 6)\n\t\t"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|" + attributes + ")*)|" +\n\n\t\t// 3. anything else (capture 2)\n\t\t".*" +\n\t\t")\\\\)|)",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + "+", "g" ),\n\n\trcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),\n\trleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" +\n\t\twhitespace + "*" ),\n\trdescend = new RegExp( whitespace + "|>" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( "^" + identifier + "$" ),\n\n\tmatchExpr = {\n\t\tID: new RegExp( "^#(" + identifier + ")" ),\n\t\tCLASS: new RegExp( "^\\\\.(" + identifier + ")" ),\n\t\tTAG: new RegExp( "^(" + identifier + "|[*])" ),\n\t\tATTR: new RegExp( "^" + attributes ),\n\t\tPSEUDO: new RegExp( "^" + pseudos ),\n\t\tCHILD: new RegExp(\n\t\t\t"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(" +\n\t\t\t\twhitespace + "*(even|odd|(([+-]|)(\\\\d*)n|)" + whitespace + "*(?:([+-]|)" +\n\t\t\t\twhitespace + "*(\\\\d+)|))" + whitespace + "*\\\\)|)", "i" ),\n\t\tbool: new RegExp( "^(?:" + booleans + ")$", "i" ),\n\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\tneedsContext: new RegExp( "^" + whitespace +\n\t\t\t"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(" + whitespace +\n\t\t\t"*((?:-\\\\d)?\\\\d*)" + whitespace + "*\\\\)|)(?=[^-]|$)", "i" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// https://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( "\\\\\\\\[\\\\da-fA-F]{1,6}" + whitespace +\n\t\t"?|\\\\\\\\([^\\\\r\\\\n\\\\f])", "g" ),\n\tfunescape = function( escape, nonHex ) {\n\t\tvar high = "0x" + escape.slice( 1 ) - 0x10000;\n\n\t\tif ( nonHex ) {\n\n\t\t\t// Strip the backslash prefix from a non-hex escape sequence\n\t\t\treturn nonHex;\n\t\t}\n\n\t\t// Replace a hexadecimal escape sequence with the encoded Unicode code point\n\t\t// Support: IE <=11+\n\t\t// For values outside the Basic Multilingual Plane (BMP), manually construct a\n\t\t// surrogate pair\n\t\treturn high < 0 ?\n\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\tString.fromCharCode( high >>
1 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes; see `setDocument`.\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Removing the function wrapper causes a "Permission Denied"\n\t// error in IE/Edge.\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && nodeName( elem, "fieldset" );\n\t\t},\n\t\t{ dir: "parentNode", next: "legend" }\n\t);\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t( arr = slice.call( preferredDoc.childNodes ) ),\n\t\tpreferredDoc.childNodes\n\t);\n\n\t// Support: Android <=4.0\n\t// Detect silently failing push.apply\n\t// eslint-disable-next-line no-unused-expressions\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = {\n\t\tapply: function( target, els ) {\n\t\t\tpushNative.apply( target, slice.call( els ) );\n\t\t},\n\t\tcall: function( target ) {\n\t\t\tpushNative.apply( target, slice.call( arguments, 1 ) );\n\t\t}\n\t};\n}\n\nfunction find( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== "string" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\t\tsetDocument( context );\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a "get*By*" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don\'t exist)\n\t\t\tif ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( ( m = match[ 1 ] ) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( ( elem = context.getElementById( m ) ) ) {\n\n\t\t\t\t\t\t\t// Support: IE 9 only\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tpush.call( results, elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE 9 only\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && ( elem = newContext.getElementById( m ) ) &&\n\t\t\t\t\t\t\tfind.contains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tpush.call( results, elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[ 2 ] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( !nonnativeSelectorCache[ selector + " " ] &&\n\t\t\t\t( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// The technique has to be used as well when a leading combinator is used\n\t\t\t\t// as such selectors are not recognized by querySelectorAll.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 &&\n\t\t\t\t\t( rdesce
1nd.test( selector ) || rleadingCombinator.test( selector ) ) ) {\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\n\t\t\t\t\t// We can use :scope instead of the ID hack if the browser\n\t\t\t\t\t// supports it & if we\'re not changing the context.\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a "Permission denied" error when\n\t\t\t\t\t// strict-comparing two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( newContext != context || !support.scope ) {\n\n\t\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\t\tif ( ( nid = context.getAttribute( "id" ) ) ) {\n\t\t\t\t\t\t\tnid = jQuery.escapeSelector( nid );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontext.setAttribute( "id", ( nid = expando ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +\n\t\t\t\t\t\t\ttoSelector( groups[ i ] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( "," );\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( "id" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrimCSS, "$1" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\n\t\t// Use (key + " ") to avoid collision with native prototype properties\n\t\t// (see https://github.com/jquery/sizzle/issues/157)\n\t\tif ( keys.push( key + " " ) > Expr.cacheLength ) {\n\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn ( cache[ key + " " ] = value );\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by jQuery selector module\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement( "fieldset" );\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch ( e ) {\n\t\treturn false;\n\t} finally {\n\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\treturn nodeName( elem, "input" ) && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\treturn ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) &&\n\t\t\telem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( "form" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t// https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a "form" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( "label" in elem ) {\n\t\t\t\t\tif ( "label" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11+\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can\'t be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn\'t\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( "label" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction( function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction( function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ ( j = matchIndexes[ i ] ) ] ) {\n\t\t\t\t\tseed[ j ] = !( matches[ j ] = seed[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Checks a node for validity as a jQuery selector context\n * @param {Element|Ob
1ject=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== "undefined" && context;\n}\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [node] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nfunction setDocument( node ) {\n\tvar subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocumentElement = document.documentElement;\n\tdocumentIsHTML = !jQuery.isXMLDoc( document );\n\n\t// Support: iOS 7 only, IE 9 - 11+\n\t// Older browsers didn\'t support unprefixed `matches`.\n\tmatches = documentElement.matches ||\n\t\tdocumentElement.webkitMatchesSelector ||\n\t\tdocumentElement.msMatchesSelector;\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Accessing iframe documents after unload throws "permission denied" errors\n\t// (see trac-13936).\n\t// Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`,\n\t// all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well.\n\tif ( documentElement.msMatchesSelector &&\n\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tpreferredDoc != document &&\n\t\t( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t\tsubWindow.addEventListener( "unload", unloadHandler );\n\t}\n\n\t// Support: IE <10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don\'t pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert( function( el ) {\n\t\tdocumentElement.appendChild( el ).id = jQuery.expando;\n\t\treturn !document.getElementsByName ||\n\t\t\t!document.getElementsByName( jQuery.expando ).length;\n\t} );\n\n\t// Support: IE 9 only\n\t// Check to see if it\'s possible to do matchesSelector\n\t// on a disconnected node.\n\tsupport.disconnectedMatch = assert( function( el ) {\n\t\treturn matches.call( el, "*" );\n\t} );\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// IE/Edge don\'t support the :scope pseudo-class.\n\tsupport.scope = assert( function() {\n\t\treturn document.querySelectorAll( ":scope" );\n\t} );\n\n\t// Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only\n\t// Make sure the `:has()` argument is parsed unforgivingly.\n\t// We include `*` in the test to detect buggy implementations that are\n\t// _selectively_ forgiving (specifically when the list includes at least\n\t// one valid selector).\n\t// Note that we treat complete lack of support for `:has()` as if it were\n\t// spec-compliant support, which is fine because use of `:has()` in such\n\t// environments will fail in the qSA path and fall back to jQuery traversal\n\t// anyway.\n\tsupport.cssHas = assert( function() {\n\t\ttry {\n\t\t\tdocument.querySelector( ":has(*,:jqfake)" );\n\t\t\treturn false;\n\t\t} catch ( e ) {\n\t\t\treturn true;\n\t\t}\n\t} );\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter.ID = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute( "id" ) === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find.ID = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== "undefined" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter.ID = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== "undefined" &&\n\t\t\t\t\telem.getAttributeNode( "id" );\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find.ID = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== "undefined" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tno
1de = elem.getAttributeNode( "id" );\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( ( elem = elems[ i++ ] ) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode( "id" );\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find.TAG = function( tag, context ) {\n\t\tif ( typeof context.getElementsByTagName !== "undefined" ) {\n\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t// DocumentFragment nodes don\'t have gEBTN\n\t\t} else {\n\t\t\treturn context.querySelectorAll( tag );\n\t\t}\n\t};\n\n\t// Class\n\tExpr.find.CLASS = function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\trbuggyQSA = [];\n\n\t// Build QSA regex\n\t// Regex strategy adopted from Diego Perini\n\tassert( function( el ) {\n\n\t\tvar input;\n\n\t\tdocumentElement.appendChild( el ).innerHTML =\n\t\t\t"<a id=\'" + expando + "\' href=\'\' disabled=\'disabled\'></a>" +\n\t\t\t"<select id=\'" + expando + "-\\r\\\\\' disabled=\'disabled\'>" +\n\t\t\t"<option selected=\'\'></option></select>";\n\n\t\t// Support: iOS <=7 - 8 only\n\t\t// Boolean attributes and "value" are not treated correctly in some XML documents\n\t\tif ( !el.querySelectorAll( "[selected]" ).length ) {\n\t\t\trbuggyQSA.push( "\\\\[" + whitespace + "*(?:value|" + booleans + ")" );\n\t\t}\n\n\t\t// Support: iOS <=7 - 8 only\n\t\tif ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {\n\t\t\trbuggyQSA.push( "~=" );\n\t\t}\n\n\t\t// Support: iOS 8 only\n\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\tif ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {\n\t\t\trbuggyQSA.push( ".#.+[+~]" );\n\t\t}\n\n\t\t// Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+\n\t\t// In some of the document kinds, these selectors wouldn\'t work natively.\n\t\t// This is probably OK but for backwards compatibility we want to maintain\n\t\t// handling them through jQuery traversal in jQuery 3.x.\n\t\tif ( !el.querySelectorAll( ":checked" ).length ) {\n\t\t\trbuggyQSA.push( ":checked" );\n\t\t}\n\n\t\t// Support: Windows 8 Native Apps\n\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\tinput = document.createElement( "input" );\n\t\tinput.setAttribute( "type", "hidden" );\n\t\tel.appendChild( input ).setAttribute( "name", "D" );\n\n\t\t// Support: IE 9 - 11+\n\t\t// IE\'s :disabled selector does not pick up the children of disabled fieldsets\n\t\t// Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+\n\t\t// In some of the document kinds, these selectors wouldn\'t work natively.\n\t\t// This is probably OK but for backwards compatibility we want to maintain\n\t\t// handling them through jQuery traversal in jQuery 3.x.\n\t\tdocumentElement.appendChild( el ).disabled = true;\n\t\tif ( el.querySelectorAll( ":disabled" ).length !== 2 ) {\n\t\t\trbuggyQSA.push( ":enabled", ":disabled" );\n\t\t}\n\n\t\t// Support: IE 11+, Edge 15 - 18+\n\t\t// IE 11/Edge don\'t find elements on a `[name=\'\']` query in some cases.\n\t\t// Adding a temporary attribute to the document before the selection works\n\t\t// around the issue.\n\t\t// Interestingly, IE 10 & older don\'t seem to have the issue.\n\t\tinput = document.createElement( "input" );\n\t\tinput.setAttribute( "name", "" );\n\t\tel.appendChild( input );\n\t\tif ( !el.querySelectorAll( "[name=\'\']" ).length ) {\n\t\t\trbuggyQSA.push( "\\\\[" + whitespace + "*name" + whitespace + "*=" +\n\t\t\t\twhitespace + "*(?:\'\'|\\"\\")" );\n\t\t}\n\t} );\n\n\tif ( !support.cssHas ) {\n\n\t\t// Support: Chrome 105 - 110+, Safari 15.4 - 16.3+\n\t\t// Our regular `try-catch` mechanism fails to detect natively-unsupported\n\t\t// pseudo-classe
1s inside `:has()` (such as `:has(:contains("Foo"))`)\n\t\t// in browsers that parse the `:has()` argument as a forgiving selector list.\n\t\t// https://drafts.csswg.org/selectors/#relational now requires the argument\n\t\t// to be parsed unforgivingly, but browsers have not yet fully adjusted.\n\t\trbuggyQSA.push( ":has" );\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = function( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tcompare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( a === document || a.ownerDocument == preferredDoc &&\n\t\t\t\tfind.contains( preferredDoc, a ) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( b === document || b.ownerDocument == preferredDoc &&\n\t\t\t\tfind.contains( preferredDoc, b ) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t};\n\n\treturn document;\n}\n\nfind.matches = function( expr, elements ) {\n\treturn find( expr, null, null, elements );\n};\n\nfind.matchesSelector = function( elem, expr ) {\n\tsetDocument( elem );\n\n\tif ( documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + " " ] &&\n\t\t( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9\'s matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn find( expr, document, null, [ elem ] ).length > 0;\n};\n\nfind.contains = function( context, elem ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( context.ownerDocument || context ) != document ) {\n\t\tsetDocument( context );\n\t}\n\treturn jQuery.contains( context, elem );\n};\n\n\nfind.attr = function( elem, name ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( elem.ownerDocument || elem ) != document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\n\t\t// Don\'t get fooled by Object.prototype properties (see trac-13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\tif ( val !== undefined ) {\n\t\treturn val;\n\t}\n\n\treturn elem.getAttribute( name );\n};\n\nfind.error = function( msg ) {\n\tthrow new Error( "Syntax error, unrecognized expression: " + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\njQuery.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\t//\n\t// Support: Android <=4.0+\n\t// Testing for detecting duplicates is unpredictable so instead assume we can\'t\n\t// depend on duplicate detection in all browsers without a stable sort.\n\thasDuplicate = !support.sortStable;\n\tsortInput = !support.sortStable && slice.call( results, 0 );\n\tsort.call( results, sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tsplice.call( results, duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};
1\n\njQuery.fn.uniqueSort = function() {\n\treturn this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) );\n};\n\nExpr = jQuery.expr = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t">": { dir: "parentNode", first: true },\n\t\t" ": { dir: "parentNode" },\n\t\t"+": { dir: "previousSibling", first: true },\n\t\t"~": { dir: "previousSibling" }\n\t},\n\n\tpreFilter: {\n\t\tATTR: function( match ) {\n\t\t\tmatch[ 1 ] = match[ 1 ].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" )\n\t\t\t\t.replace( runescape, funescape );\n\n\t\t\tif ( match[ 2 ] === "~=" ) {\n\t\t\t\tmatch[ 3 ] = " " + match[ 3 ] + " ";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\tCHILD: function( match ) {\n\n\t\t\t/* matches from matchExpr["CHILD"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[ 1 ] = match[ 1 ].toLowerCase();\n\n\t\t\tif ( match[ 1 ].slice( 0, 3 ) === "nth" ) {\n\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[ 3 ] ) {\n\t\t\t\t\tfind.error( match[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[ 4 ] = +( match[ 4 ] ?\n\t\t\t\t\tmatch[ 5 ] + ( match[ 6 ] || 1 ) :\n\t\t\t\t\t2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" )\n\t\t\t\t);\n\t\t\t\tmatch[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[ 3 ] ) {\n\t\t\t\tfind.error( match[ 0 ] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\tPSEUDO: function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[ 6 ] && match[ 2 ];\n\n\t\t\tif ( matchExpr.CHILD.test( match[ 0 ] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[ 3 ] ) {\n\t\t\t\tmatch[ 2 ] = match[ 4 ] || match[ 5 ] || "";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t( excess = tokenize( unquoted, true ) ) &&\n\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[ 0 ] = match[ 0 ].slice( 0, excess );\n\t\t\t\tmatch[ 2 ] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\tTAG: function( nodeNameSelector ) {\n\t\t\tvar expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === "*" ?\n\t\t\t\tfunction() {\n\t\t\t\t\treturn true;\n\t\t\t\t} :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn nodeName( elem, expectedNodeName );\n\t\t\t\t};\n\t\t},\n\n\t\tCLASS: function( className ) {\n\t\t\tvar pattern = classCache[ className + " " ];\n\n\t\t\treturn pattern ||\n\t\t\t\t( pattern = new RegExp( "(^|" + whitespace + ")" + className +\n\t\t\t\t\t"(" + whitespace + "|$)" ) ) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test(\n\t\t\t\t\t\ttypeof elem.className === "string" && elem.className ||\n\t\t\t\t\t\t\ttypeof elem.getAttribute !== "undefined" &&\n\t\t\t\t\t\t\t\telem.getAttribute( "class" ) ||\n\t\t\t\t\t\t\t""\n\t\t\t\t\t);\n\t\t\t\t} );\n\t\t},\n\n\t\tATTR: function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = find.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === "!=";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += "";\n\n\t\t\t\tif ( operator === "=" ) {\n\t\t\t\t\treturn result === check;\n\t\t\t\t}\n\t\t\t\tif ( operator === "!=" ) {\n\t\t\t\t\treturn result !== check;\n\t\t\t\t}\n\t\t\t\tif ( operator === "^=" ) {\n\t\t\t\t\treturn check && result.indexOf( check )
1=== 0;\n\t\t\t\t}\n\t\t\t\tif ( operator === "*=" ) {\n\t\t\t\t\treturn check && result.indexOf( check ) > -1;\n\t\t\t\t}\n\t\t\t\tif ( operator === "$=" ) {\n\t\t\t\t\treturn check && result.slice( -check.length ) === check;\n\t\t\t\t}\n\t\t\t\tif ( operator === "~=" ) {\n\t\t\t\t\treturn ( " " + result.replace( rwhitespace, " " ) + " " )\n\t\t\t\t\t\t.indexOf( check ) > -1;\n\t\t\t\t}\n\t\t\t\tif ( operator === "|=" ) {\n\t\t\t\t\treturn result === check || result.slice( 0, check.length + 1 ) === check + "-";\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t};\n\t\t},\n\n\t\tCHILD: function( type, what, _argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== "nth",\n\t\t\t\tforward = type.slice( -4 ) !== "last",\n\t\t\t\tofType = what === "of-type";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? "nextSibling" : "previousSibling",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( ( node = node[ dir ] ) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnodeName( node, name ) :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven\'t yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === "only" && !start && "nextSibling";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || ( parent[ expando ] = {} );\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\t\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnodeName( node, name ) :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( node[ expando ] = {} );\n\t\t\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\tPSEUDO: function( pseudo, argument ) {\n\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// https://www.w3.org/TR/selectors/#pseudo-classe
1s\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tfind.error( "unsupported pseudo: " + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as jQuery does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, "", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction( function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf.call( seed, matched[ i ] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\n\t\t// Potentially complex pseudos\n\t\tnot: markFunction( function( selector ) {\n\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrimCSS, "$1" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction( function( seed, matches, _context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\t\t\t\t\tseed[ i ] = !( matches[ i ] = elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} ) :\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tinput[ 0 ] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\n\t\t\t\t\t// Don\'t keep the element\n\t\t\t\t\t// (see https://github.com/jquery/sizzle/issues/299)\n\t\t\t\t\tinput[ 0 ] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t} ),\n\n\t\thas: markFunction( function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn find( selector, elem ).length > 0;\n\t\t\t};\n\t\t} ),\n\n\t\tcontains: markFunction( function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t} ),\n\n\t\t// "Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element\'s language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by "-".\n\t\t// The matching of C against the element\'s language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name."\n\t\t// https://www.w3.org/TR/selectors/#lang-pseudo\n\t\tlang: markFunction( function( lang ) {\n\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test( lang || "" ) ) {\n\t\t\t\tfind.error( "unsupported lang: " + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( ( elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t} ),\n\n\t\t// Miscellaneous\n\t\ttarget: function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\troot: function( elem ) {\n\t\t\treturn elem === documentElement;\n\t\t},\n\n\t\tfocus: function( elem ) {\n\t\t\treturn elem === safeActiveElement() &&\n\t\t\t\tdocument.hasFocus() &&\n\t\t\t\t!!( elem.type || elem.href || ~elem.tabIndex );\n\t\t},\n\n\t\t// Boolean properties\n\t\tenabled: createDisabledPseudo( false ),\n\t\tdisabled: createDisabledPseudo( true ),\n\n\t\tchecked: function( elem ) {\n\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#
1checked\n\t\t\treturn ( nodeName( elem, "input" ) && !!elem.checked ) ||\n\t\t\t\t( nodeName( elem, "option" ) && !!elem.selected );\n\t\t},\n\n\t\tselected: function( elem ) {\n\n\t\t\t// Support: IE <=11+\n\t\t\t// Accessing the selectedIndex property\n\t\t\t// forces the browser to treat the default option as\n\t\t\t// selected when in an optgroup.\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\t// eslint-disable-next-line no-unused-expressions\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\tempty: function( elem ) {\n\n\t\t\t// https://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t// but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\tparent: function( elem ) {\n\t\t\treturn !Expr.pseudos.empty( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\theader: function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\tinput: function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\tbutton: function( elem ) {\n\t\t\treturn nodeName( elem, "input" ) && elem.type === "button" ||\n\t\t\t\tno
1deName( elem, "button" );\n\t\t},\n\n\t\ttext: function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn nodeName( elem, "input" ) && elem.type === "text" &&\n\n\t\t\t\t// Support: IE <10 only\n\t\t\t\t// New HTML5 attribute values (e.g., "search") appear\n\t\t\t\t// with elem.type === "text"\n\t\t\t\t( ( attr = elem.getAttribute( "type" ) ) == null ||\n\t\t\t\t\tattr.toLowerCase() === "text" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\tfirst: createPositionalPseudo( function() {\n\t\t\treturn [ 0 ];\n\t\t} ),\n\n\t\tlast: createPositionalPseudo( function( _matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t} ),\n\n\t\teq: createPositionalPseudo( function( _matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t} ),\n\n\t\teven: createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\todd: createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\tlt: createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i;\n\n\t\t\tif ( argument < 0 ) {\n\t\t\t\ti = argument + length;\n\t\t\t} else if ( argument > length ) {\n\t\t\t\ti = length;\n\t\t\t} else {\n\t\t\t\ti = argument;\n\t\t\t}\n\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\tgt: createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} )\n\t}\n};\n\nExpr.pseudos.nth = Expr.pseudos.eq;\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\nfunction tokenize( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + " " ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || ( match = rcomma.exec( soFar ) ) ) {\n\t\t\tif ( match ) {\n\n\t\t\t\t// Don\'t consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[ 0 ].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( ( tokens = [] ) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( ( match = rleadingCombinator.exec( soFar ) ) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push( {\n\t\t\t\tvalue: matched,\n\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[ 0 ].replace( rtrimCSS, " " )\n\t\t\t} );\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||\n\t\t\t\t( match = preFilters[ type ]( match ) ) ) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push( {\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t} );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we\'re just parsing\n\t// Otherwise, throw an error or return tokens\n\tif ( parseOnly ) {\n\t\treturn soFar.length;\n\t}\n\n\treturn soFar ?\n\t\tfind.error( selector ) :\n\n\t\t// Cache the tokens\n\t\ttokenCache( selector, groups ).slice( 0 );\n}\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = "";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[ i ].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === "parentNode",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can\'t set arbitrary data on XML nodes, so they don\'t benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\n\t\t\t\t\t\tif ( skip && nodeName( elem, skip ) ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( ( oldCache = outerCache[ key ] ) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn ( newCache[ 2 ] = oldCache[ 2 ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we\'re done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[ i ]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[ 0 ];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tfind( selector, contexts[ i ], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ exp
1ando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction( function( seed, results, context, xml ) {\n\t\tvar temp, i, elem, matcherOut,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed ||\n\t\t\t\tmultipleContexts( selector || "*",\n\t\t\t\t\tcontext.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems;\n\n\t\tif ( matcher ) {\n\n\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter\n\t\t\t// or preexisting results,\n\t\t\tmatcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t[] :\n\n\t\t\t\t// ...otherwise use results directly\n\t\t\t\tresults;\n\n\t\t\t// Find primary matches\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t} else {\n\t\t\tmatcherOut = matcherIn;\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( ( elem = temp[ i ] ) ) {\n\t\t\t\t\tmatcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) ) {\n\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( ( matcherIn[ i ] = elem ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, ( matcherOut = [] ), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) &&\n\t\t\t\t\t\t( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) {\n\n\t\t\t\t\t\tseed[ temp ] = !( results[ temp ] = elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t} );\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[ 0 ].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[ " " ],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf.call( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tvar ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || (\n\t\t\t\t( checkContext = context ).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\n\t\t\t// Avoid hanging onto element\n\t\t\t// (see https://github.com/jquery/sizzle/issues/299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[ j ].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 )\n\t\t\t\t\t\t\t.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )\n\t\t\t\t\t).replace( rtrimCSS, "$1" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = "0",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find.TAG( "*", outermost ),\n\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\n\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\
1n\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\toutermostContext = context == document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: iOS <=7 - 9 only\n\t\t\t// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching\n\t\t\t// elements by id. (see trac-14142)\n\t\t\tfor ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n\t\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( !context && elem.ownerDocument != document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( ( matcher = elementMatchers[ j++ ] ) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml ) ) {\n\t\t\t\t\t\t\tpush.call( results, elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( ( elem = !matcher && elem ) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn\'t visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a "00" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( ( matcher = setMatchers[ j++ ] ) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !( unmatched[ i ] || setMatched[ i ] ) ) {\n\t\t\t\t\t\t\t\tsetMatched[ i ] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tjQuery.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\nfunction compile( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + " " ];\n\n\tif ( !cached ) {\n\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[ i ] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector,\n\t\t\tmatcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n}\n\n/**\n * A low-level selection function that works with jQuery\'s compiled\n * selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n * selector function built with jQuery selector compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nfunction select( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === "function" && selector,\n\t\tmatch = !seed && tokenize( ( selector = compiled.selector || selector ) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[ 0 ] = match[ 0 ].slice( 0 );\n\t\tif ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&\n\t\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {\n\n\t\t\tcontext = ( Expr.find.ID(\n\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\tcontext\n\t\t\t) || [] )[ 0 ];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;
1\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr.needsContext.test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[ i ];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ ( type = token.type ) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( ( find = Expr.find[ type ] ) ) {\n\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( ( seed = find(\n\t\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[ 0 ].type ) &&\n\t\t\t\t\t\ttestContext( context.parentNode ) || context\n\t\t\t\t) ) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n}\n\n// One-time assignments\n\n// Support: Android <=4.0 - 4.1+\n// Sort stability\nsupport.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Android <=4.0 - 4.1+\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert( function( el ) {\n\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;\n} );\n\njQuery.find = find;\n\n// Deprecated\njQuery.expr[ ":" ] = jQuery.expr.pseudos;\njQuery.unique = jQuery.uniqueSort;\n\n// These have always been private, but they used to be documented as part of\n
1// Sizzle so let\'s maintain them for now for backwards compatibility purposes.\nfind.compile = compile;\nfind.select = select;\nfind.setDocument = setDocument;\nfind.tokenize = tokenize;\n\nfind.escape = jQuery.escapeSelector;\nfind.getText = jQuery.text;\nfind.isXML = jQuery.isXMLDoc;\nfind.selectors = jQuery.expr;\nfind.support = jQuery.support;\nfind.uniqueSort = jQuery.uniqueSort;\n\n\t/* eslint-enable */\n\n} )();\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== "string" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = ":not(" + expr + ")";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== "string" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $("p:first").is("p:last") won\'t return true for a doc with two "p".\n\t\t\ttypeof selector === "string" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521)\n\t// Strict HTML recognition (trac-11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(""), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// s
1o migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === "string" ) {\n\t\t\tif ( selector[ 0 ] === "<" &&\n\t\t\t\tselector[ selector.length - 1 ] === ">" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== "string" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there\'s no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don\'t pass non-elements to jQuery#find\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === "string" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\
1n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, "parentNode" );\n\t},\n\tparentsUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, "parentNode", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, "nextSibling" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, "previousSibling" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, "nextSibling" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, "previousSibling" );\n\t},\n\tnextUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, "nextSibling", until );\n\t},\n\tprevUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, "previousSibling", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( elem.contentDocument != null &&\n\n\t\t\t// Support: IE 11+\n\t\t\t// <object> elements with no `data` attribute has an object\n\t\t\t// `contentDocument` with a `null` prototype.\n\t\t\tgetProto( elem.contentDocument ) ) {\n\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don\'t support it.\n\t\tif ( nodeName( elem, "template" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== "Until" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === "string" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * "fired" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest "memorized"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === "string" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\
1n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn\'t re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we\'re done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we\'re done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = "";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== "string" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = "";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = "";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\
1n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn\'t unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ "notify", "progress", jQuery.Callbacks( "memory" ),\n\t\t\t\t\tjQuery.Callbacks( "memory" ), 2 ],\n\t\t\t\t[ "resolve", "done", jQuery.Callbacks( "once memory" ),\n\t\t\t\t\tjQuery.Callbacks( "once memory" ), 0, "resolved" ],\n\t\t\t\t[ "reject", "fail", jQuery.Callbacks( "once memory" ),\n\t\t\t\t\tjQuery.Callbacks( "once memory" ), 1, "rejected" ]\n\t\t\t],\n\t\t\tstate = "pending",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t"catch": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( _i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + "With" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( "Thenable self
1-resolution" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === "object" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === "function" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.error );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the error, in case of exception\n\t\t\t\t\t\t\t\t// since it\'s otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getErrorHook ) {\n\t\t\t\t\t\t\t\t\tprocess.error = jQuery.Deferred.getErrorHook();\n\n\t\t\t\t\t\t\t\t// The deprecated alias of the above. While the name suggests\n\t\t\t\t\t\t\t\t// returning the stack, not an error instance, jQuery just passes\n\t\t\t\t\t\t\t\t// it directly to `console.warn` so both will work; an instance\n\t\t\t\t\t\t\t\t// just better cooperates with source maps.\n\t\t\t\t\t\t\t\t} else if ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.error = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\
1n\n\t\t\t\t\t\t// state = "resolved" (i.e., fulfilled)\n\t\t\t\t\t\t// state = "rejected"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + "With" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the primary Deferred\n\t\t\tprimary = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tprimary.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( primary.state() === "pending" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn primary.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );\n\t\t}\n\n\t\treturn primary.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\n// If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error\n// captured before the async barrier to get the original error cause\n// which may otherwise be hidden.\njQuery.Deferred.exceptionHook = function( error, asyncError ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( "jQuery.Deferred exception: " + error.message,\n\t\t\terror.stack, asyncError );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See trac-6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we\'re already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}
1\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( "DOMContentLoaded", completed );\n\twindow.removeEventListener( "load", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals "interactive" too soon\nif ( document.readyState === "complete" ||\n\t( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( "DOMContentLoaded", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( "load", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it\'s a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === "object" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, _key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\t\tvalue :\n\t\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( _all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (trac-9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t// - Node\n\t// - Node.ELEMENT_NODE\n\t// - Node.DOCUMENT_NODE\n\t// - Object\n\t// - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;
1\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see trac-8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === "string" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t// 1. No key was specified\n\t\t// 2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the "read" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t// 1. The entire cache object\n\t\t// 2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === "string" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t// 1. An object of properties\n\t\t// 2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the "set" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there\'s no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];
1\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module\'s maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support "private" and "user" data.\n//\t4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === "true" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === "false" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === "null" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn\'t change the string\n\tif ( data === +data + "" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === "string" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn\'t changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (trac-14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( "data-" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, "hasDataAttrs", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === "object" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to "discover" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn\'t exist.\n\t\t\t\treturn;\n\t\t\t}
1\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || "fx" ) + "queue";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || "fx";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === "inprogress" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === "fx" ) {\n\t\t\t\tqueue.unshift( "inprogress" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + "queueHooks";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( "once memory" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + "queue", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== "string" ) {\n\t\t\tdata = type;\n\t\t\ttype = "fx";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === "fx" && queue[ 0 ] !== "inprogress" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || "fx", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== "string" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || "fx";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + "queueHooks" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );\n\n\nvar cssExpand = [ "Top", "Right", "Bottom", "Left" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions supp
1ort `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === "none" ||\n\t\t\telem.style.display === "" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, "display" ) === "none";\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, "" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finis
1h if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, "display" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === "none" ) {\n\t\tdisplay = "block";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === "none" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, "display" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = "";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== "none" ) {\n\t\t\t\tvalues[ index ] = "none";\n\n\t\t\t\t// Remember what we\'re overwriting\n\t\t\t\tdataPriv.set( elem, "display", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === "boolean" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( "div" ) ),\n\t\tinput = document.createElement( "input" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (trac-11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (trac-14901)\n\tinput.setAttribute( "type", "radio" );\n\tinput.setAttribute( "checked", "checked" );\n\tinput.setAttribute( "name", "t" );\n\n\tdiv.appendChild( input );
1\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn\'t clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = "<textarea>x</textarea>";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces <option> tags with their contents when inserted outside of\n\t// the select element.\n\tdiv.innerHTML = "<option></option>";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (trac-13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, "<table>", "</table>" ],\n\tcol: [ 2, "<table><colgroup>", "</colgroup></table>" ],\n\ttr: [ 2, "<table><tbody>", "</tbody></table>" ],\n\ttd: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],\n\n\t_default: [ 0, "", "" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, "<select multiple=\'multiple\'>", "</select>" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (trac-15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== "undefined" ) {\n\t\tret = context.getElementsByTagName( tag || "*" );\n\n\t} else if ( typeof context.querySelectorAll !== "undefined" ) {\n\t\tret = context.querySelectorAll( tag || "*" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t"globalEval",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], "globalEval" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === "object" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t}
1 else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( "div" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (trac-12392)\n\t\t\t\ttmp.textContent = "";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = "";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), "script" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || "" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar rtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === "object" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== "string" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === "string" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards\' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element\'s event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || "" ).match( rnothtmlwhite ) || [ "" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( "." )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we\'re the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element\'s handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}
1\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || "" ).match( rnothtmlwhite ) || [ "" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( "(^|\\\\.)" + namespaces.join( "\\\\.(?:.*\\\\.|)" ) + "(\\\\.|$)" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === "**" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it\'s no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, "handle events" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\tdataPriv.get( this, "events" ) || Object.create( null )\n\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event\'s.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rn
1amespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === "click" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don\'t check non-elements (trac-13208)\n\t\t\t\t// Don\'t process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don\'t conflict with Object.prototype properties (trac-13203)\n\t\t\t\t\t\tsel = handleObj.selector + " ";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, "input" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, "click", ... )\n\t\t\t\t\tleverageNative( el, "click", true );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, "input" ) ) {\n\n\t\t\t\t\tleverageNative( el, "click" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we\'re currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, "input" ) &&\n\t\t\t\t\tdataPriv.get( target, "click" ) ||\n\t\t\t\t\tno
1deName( target, "a" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn\'t alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, isSetup ) {\n\n\t// Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !isSetup ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\tif ( !saved ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tdataPriv.set( this, type, false );\n\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering\n\t\t\t\t// the native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, jQuery.event.trigger(\n\t\t\t\t\tsaved[ 0 ],\n\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\tthis\n\t\t\t\t) );\n\n\t\t\t\t// Abort handling of the native event by all jQuery handlers while allowing\n\t\t\t\t// native handlers on the same element to run. On target, this is achieved\n\t\t\t\t// by stopping immediate propagation just on the jQuery event. However,\n\t\t\t\t// the native event is re-wrapped by a jQuery one on each level of the\n\t\t\t\t// propagation so the only way to stop it for jQuery is to stop it for\n\t\t\t\t// everyone via native `stopPropagation()`. This is not a problem for\n\t\t\t\t// focus/blur which don\'t bubble, but it does also stop click on checkboxes\n\t\t\t\t// and radios. We accept this limitation.\n\t\t\t\tevent.stopPropagation();\n\t\t\t\tevent.isImmediatePropagationStopped = returnTrue;\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This "if" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the \'new\' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (trac-504, trac-13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn\'t have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\
1n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t"char": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\twhich: true\n}, jQuery.event.addProp );\n\njQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {\n\n\tfunction focusMappedHandler( nativeEvent ) {\n\t\tif ( document.documentMode ) {\n\n\t\t\t// Support: IE 11+\n\t\t\t// Attach a single focusin/focusout handler on the document while someone wants\n\t\t\t// focus/blur. This is because the former are synchronous in IE while the latter\n\t\t\t// are async. In other browsers, all those handlers are invoked synchronously.\n\n\t\t\t// `handle` from private data would already wrap the event, but we need\n\t\t\t// to change the `type` here.\n\t\t\tvar handle = dataPriv.get( this, "handle" ),\n\t\t\t\tevent = jQuery.event.fix( nativeEvent );\n\t\t\tevent.type = nativeEvent.type === "focusin" ? "focus" : "blur";\n\t\t\tevent.isSimulated = true;\n\n\t\t\t// First, handle focusin/focusout\n\t\t\thandle( nativeEvent );\n\n\t\t\t// ...then, handle focus/blur\n\t\t\t//\n\t\t\t// focus/blur don\'t bubble while focusin/focusout do; simulate the former by only\n\t\t\t// invoking the handler at the lower level.\n\t\t\tif ( event.target === event.currentTarget ) {\n\n\t\t\t\t// The setup part calls `leverageNative`, which, in turn, calls\n\t\t\t\t// `jQuery.event.add`, so event handle will already have been set\n\t\t\t\t// by this point.\n\t\t\t\thandle( event );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// For non-IE browsers, attach a single capturing handler on the document\n\t\t\t// while someone wants focusin/focusout.\n\t\t\tjQuery.event.simulate( delegateType, nativeEvent.target,\n\t\t\t\tjQuery.event.fix( nativeEvent ) );\n\t\t}\n\t}\n\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\tvar attaches;\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, "focus", ... )\n\t\t\t// dataPriv.set( this, "blur", ... )\n\t\t\tleverageNative( this, type, true );\n\n\t\t\tif ( document.documentMode ) {\n\n\t\t\t\t// Support: IE 9 - 11+\n\t\t\t\t// We use the same native handler for focusin & focus (and focusout & blur)\n\t\t\t\t// so we need to coordinate setup & teardown parts between those events.\n\t\t\t\t// Use `delegateType` as the key as `type` is already used by `leverageNative`.\n\t\t\t\tattaches = dataPriv.get( this, delegateType );\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tthis.addEventListener( delegateType, focusMappedHandler );\n\t\t\t\t}\n\t\t\t\tdataPriv.set( this, delegateType, ( attaches || 0 ) + 1 );\n\t\t\t} else {\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}
1,\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tvar attaches;\n\n\t\t\tif ( document.documentMode ) {\n\t\t\t\tattaches = dataPriv.get( this, delegateType ) - 1;\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tthis.removeEventListener( delegateType, focusMappedHandler );\n\t\t\t\t\tdataPriv.remove( this, delegateType );\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.set( this, delegateType, attaches );\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Return false to indicate standard teardown should be applied\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\t// Suppress native focus or blur if we\'re currently inside\n\t\t// a leveraged native-event stack\n\t\t_default: function( event ) {\n\t\t\treturn dataPriv.get( event.target, type );\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n\n\t// Support: Firefox <=44\n\t// Firefox doesn\'t have focus(in | out) events\n\t// Related t
1icket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n\t//\n\t// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n\t// focus(in | out) events fire after focus & blur events,\n\t// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n\t// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\n\t//\n\t// Support: IE 9 - 11+\n\t// To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch,\n\t// attach a single handler for both events in IE.\n\tjQuery.event.special[ delegateType ] = {\n\t\tsetup: function() {\n\n\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\tdataHolder = document.documentMode ? this : doc,\n\t\t\t\tattaches = dataPriv.get( dataHolder, delegateType );\n\n\t\t\t// Support: IE 9 - 11+\n\t\t\t// We use the same native handler for focusin & focus (and focusout & blur)\n\t\t\t// so we need to coordinate setup & teardown parts between those events.\n\t\t\t// Use `delegateType` as the key as `type` is already used by `leverageNative`.\n\t\t\tif ( !attaches ) {\n\t\t\t\tif ( document.documentMode ) {\n\t\t\t\t\tthis.addEventListener( delegateType, focusMappedHandler );\n\t\t\t\t} else {\n\t\t\t\t\tdoc.addEventListener( type, focusMappedHandler, true );\n\t\t\t\t}\n\t\t\t}\n\t\t\tdataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 );\n\t\t},\n\t\tteardown: function() {\n\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\tdataHolder = document.documentMode ? this : doc,\n\t\t\t\tattaches = dataPriv.get( dataHolder, delegateType ) - 1;\n\n\t\t\tif ( !attaches ) {\n\t\t\t\tif ( document.documentMode ) {\n\t\t\t\t\tthis.removeEventListener( delegateType, focusMappedHandler );\n\t\t\t\t} else {\n\t\t\t\t\tdoc.removeEventListener( type, focusMappedHandler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( dataHolder, delegateType );\n\t\t\t} else {\n\t\t\t\tdataPriv.set( dataHolder, delegateType, attaches );\n\t\t\t}\n\t\t}\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: "mouseover",\n\tmouseleave: "mouseout",\n\tpointerenter: "pointerover",\n\tpointerleave: "pointerout"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event ) dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + "." + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === "object" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === "function" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}
1\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked="checked" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\n\trcleanScript = /^\\s*<!\\[CDATA\\[|\\]\\]>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, "table" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {\n\n\t\treturn jQuery( elem ).children( "tbody" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( "type" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, "handle events" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === "input" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === "input" || nodeName === "textarea" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can\'t cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === "string" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, "script" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (trac-8070).\n\t\t\tfor ( ; i < l;
1 i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, "script" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Re-enable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || "" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, "globalEval" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won\'t run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( "nonce" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Unwrap a CDATA section containing script contents. This shouldn\'t be\n\t\t\t\t\t\t\t// needed as in XML documents they\'re already not visible when\n\t\t\t\t\t\t\t// inspecting element contents and in HTML documents they have no\n\t\t\t\t\t\t\t// meaning but we\'re preserving that logic for backwards compatibility.\n\t\t\t\t\t\t\t// This will be removed completely in 4.0. See gh-4904.\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, "script" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew jQuery#find here for performance reasons:\n\t\t\t// https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, "script" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, "script" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove\'s overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\
1n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = "";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === "string" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: "append",\n\tprependTo: "prepend",\n\tinsertBefore: "before",\n\tinsertAfter: "after",\n\treplaceAll: "replaceWith"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );\n\nvar rcustomProp = /^--/;\n\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
1\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they\'re executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = "position:absolute;left:-11111px;width:60px;" +\n\t\t\t"margin-top:1px;padding:0;border:0";\n\t\tdiv.style.cssText =\n\t\t\t"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +\n\t\t\t"margin:auto;border:1px;padding:1px;" +\n\t\t\t"width:60%;top:1%";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== "1%";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn\'t\n\t\tdiv.style.right = "60%";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don\'t get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = "absolute";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn\'t be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( "div" ),\n\t\tdiv = document.createElement( "div" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (trac-8908)\n\tdiv.style.backgroundClip = "content-box";\n\tdiv.cloneNode( true ).style.backgroundClip = "";\n\tsupport.clearCloneStyle = div.style.backgroundClip === "content-box";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\t//\n\t\t// Support: Firefox 70+\n\t\t// Only Firefox includes border widths\n\t\t// in computed dimensions. (gh-4529)\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( "table" );\n\t\t\t\ttr = document.createElement( "tr" );\n\t\t\t\ttrChild = document.createElement( "div" );\n\n\t\t\t\ttable.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";\n\t\t\t\ttr.style.cssText = "box-sizing:content-box;border:1px solid";\n\n\t\t\t\t// Support: Chrome 86+\n\t\t\t\t// Height set through cssText does not get applied.\n\t\t\t\t// Computed height then comes back as 0.\n\t\t\t\ttr.style.height = "1px";\n\t\t\t\ttrChild.style.height = "9px";\n\n\t\t\t\t// Support: Android 8 Chrome 86+\n\t\t\t\t// In our bodyBackgroun
1d.html iframe,\n\t\t\t\t// display for all div elements is set to "inline",\n\t\t\t\t// which causes a problem only in Android 8 Chrome 86.\n\t\t\t\t// Ensuring the div is `display: block`\n\t\t\t\t// gets around this issue.\n\t\t\t\ttrChild.style.display = "block";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderTopWidth, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\t\tisCustomProp = rcustomProp.test( name ),\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t// .css(\'filter\') (IE 9 only, trac-12537)\n\t// .css(\'--customProperty) (gh-3144)\n\tif ( computed ) {\n\n\t\t// Support: IE <=9 - 11+\n\t\t// IE only supports `"float"` in `getPropertyValue`; in computed styles\n\t\t// it\'s only available as `"cssFloat"`. We no longer modify properties\n\t\t// sent to `.css()` apart from camelCasing, so we need to check both.\n\t\t// Normally, this would create difference in behavior: if\n\t\t// `getPropertyValue` returns an empty string, the value returned\n\t\t// by `.css()` would be `undefined`. This is usually the case for\n\t\t// disconnected elements. However, in IE even disconnected elements\n\t\t// with no styles return `"none"` for `getPropertyValue( "float" )`\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( isCustomProp && ret ) {\n\n\t\t\t// Support: Firefox 105+, Chrome <=105+\n\t\t\t// Spec requires trimming whitespace for custom properties (gh-4926).\n\t\t\t// Firefox only trims leading whitespace. Chrome just collapses\n\t\t\t// both leading & trailing whitespace to a single space.\n\t\t\t//\n\t\t\t// Fall back to `undefined` if empty string returned.\n\t\t\t// This collapses a missing definition with property defined\n\t\t\t// and set to an empty string but there\'s no standard API\n\t\t\t// allowing us to differentiate them without a performance penalty\n\t\t\t// and returning `undefined` aligns with older jQuery.\n\t\t\t//\n\t\t\t// rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED\n\t\t\t// as whitespace while CSS does not, but this is not a problem\n\t\t\t// because CSS preprocessing replaces them with U+000A LINE FEED\n\t\t\t// (which *is* CSS whitespace)\n\t\t\t// https://www.w3.org/TR/css-syntax-3/#input-preprocessing\n\t\t\tret = ret.replace( rtrimCSS, "$1" ) || undefined;\n\t\t}\n\n\t\tif ( ret === "" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the "awesome hack by Dean Edwards"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + "" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we\'ll check on the first run if it\'s really needed.\n\treturn {\n\t\tget: function() {\
1n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it\'s not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ "Webkit", "Moz", "ms" ],\n\temptyStyle = document.createElement( "div" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except "table", "table-cell", or "table-caption"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\tcssShow = { position: "absolute", visibility: "hidden", display: "block" },\n\tcssNormalTransform = {\n\t\tletterSpacing: "0",\n\t\tfontWeight: "400"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined "subtract", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === "width" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0,\n\t\tmarginDelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? "border" : "content" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\t// Count margin delta separately to only add it after scroll gutter adjustment.\n\t\t// This is needed to make negative margins work with `outerHeight( true )` (gh-3982).\n\t\tif ( box === "margin" ) {\n\t\t\tmarginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we\'re seeking "padding" or "border" or "margin"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );\n\n\t\t\t// For "border" or "margin", add border\n\t\t\tif ( box !== "padding" ) {\n\t\t\t\tdelta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we\'re seeking "content" or\n\t\t// "padding" or "margin"\n\t\t} else {\n\n\t\t\t// For "content", subtract padding\n\t\t\tif ( box === "content" ) {\n\t\t\t\tdelta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For "content" or "padding", subtract border\n\t\t\tif ( box !== "margin" ) {\n\t\t\t\tdelta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can\'t determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta + marginDelta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it\'s needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, "boxSizing", false, styles ) === "border-box",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = "auto";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\
1n\t\t// Interestingly, in some cases IE 9 doesn\'t suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is "auto"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === "auto" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize "" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element\'s box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? "border" : "content" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + "px";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, "opacity" );\n\t\t\t\t\treturn ret === "" ? "1" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don\'t automatically add "px" to these possibly-unitless properties\n\tcssNumber: {\n\t\tanimationIterationCount: true,\n\t\taspectRatio: true,\n\t\tborderImageSlice: true,\n\t\tcolumnCount: true,\n\t\tflexGrow: true,\n\t\tflexShrink: true,\n\t\tfontWeight: true,\n\t\tgridArea: true,\n\t\tgridColumn: true,\n\t\tgridColumnEnd: true,\n\t\tgridColumnStart: true,\n\t\tgridRow: true,\n\t\tgridRowEnd: true,\n\t\tgridRowStart: true,\n\t\tlineHeight: true,\n\t\topacity: true,\n\t\torder: true,\n\t\torphans: true,\n\t\tscale: true,\n\t\twidows: true,\n\t\tzIndex: true,\n\t\tzoom: true,\n\n\t\t// SVG-related\n\t\tfillOpacity: true,\n\t\tfloodOpacity: true,\n\t\tstopOpacity: true,\n\t\tstrokeMiterlimit: true,\n\t\tstrokeOpacity: true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don\'t set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we\'re working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we\'re working with the right name. We don\'t\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we\'re setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert "+=" or "-=" to relative numbers (trac-7345)\n\t\t\tif ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug trac-9237\n\t\t\t\ttype = "number";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren\'t set (trac-7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// "px" to a few hardcoded values.\
1n\t\t\tif ( type === "number" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone\'s values\n\t\t\tif ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {\n\t\t\t\tstyle[ name ] = "inherit";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( "set" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && "get" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we\'re working with the right name. We don\'t\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && "get" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert "normal" to computed value\n\t\tif ( val === "normal" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === "" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ "height", "width" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, "display" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t} ) :\n\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === "absolute",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, "boxSizing", false, styles ) === "border-box",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, "border", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || "px" ) !== "px" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, "marginLeft" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }
1, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t) + "px";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: "",\n\tpadding: "",\n\tborder: "Width"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === "string" ? value.split( " " ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== "margin" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as "10px" are parsed to Float;\n\t\t\t// complex values such as "rotate(1rad)" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, "" );\n\n\t\t\t// Empty strings, null, undefined and "auto" are converted to 0.\n\t\t\treturn !result || result === "auto" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};
1\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: "swing"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ "margin" + which ] = attrs[ "padding" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We\'re done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = "width" in props || "height" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, "fxshow" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, "fx" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, "fx" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === "toggle";\n\t\t\tif ( value === ( hidden ? "hide" : "show" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a "show" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict "overflow" and "display" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, "dis
1play" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, "display" );\n\t\tif ( display === "none" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, "display" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, "float" ) === "none" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === "none" ? "" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = "inline-block";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = "hidden";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( "hidden" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` "reverses"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a "hide" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, "fxshow" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && "expand" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won\'t overwrite existing keys.\n\t\t\t// Reusing \'index\' because we have the correct "name"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don\'t match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won\'t allow us to use `1
1- ( 0.5 || 0 )` (trac-12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there\'s more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t"*": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ "*" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== "number" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> "fx"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = "fx";\n\t}
1\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won\'t be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, "finish" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\n\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== "string" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || "fx", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + "queueHooks",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn\'t forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || "fx";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + "queue" ],\n\t\t\t\thooks = data[ type + "queueHooks" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === "boolean" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( "show" ),\n\tslideUp: genFx( "hide" ),\n\tslideToggle: genFx( "toggle" ),\n\tfadeIn: { opacity: "show" },\n\tfadeOut: { opacity: "hide" },\n\tfadeToggle: { opacity: "toggle" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];
1\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || "fx";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( "input" ),\n\t\tselect = document.createElement( "select" ),\n\t\topt = select.appendChild( document.createElement( "option" ) );\n\n\tinput.type = "checkbox";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be "on"\n\tsupport.checkOn = input.value !== "";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( "input" );\n\tinput.value = "t";\n\tinput.type = "radio";\n\tsupport.radioValue = input.value === "t";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don\'t get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === "undefined" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && "set" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + "" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === "radio" &&\n\t\t\t\t\tnodeName( elem, "input" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( "type", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\
1n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don\'t get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && "set" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn\'t always return the\n\t\t\t\t// correct value when it hasn\'t been explicitly set\n\t\t\t\t// Use proper attribute retrieval (trac-12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, "tabindex" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t"for": "htmlFor",\n\t\t"class": "className"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule "no-unused-expressions" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: "off" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: "off" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t"tabIndex",\n\t"readOnly",\n\t"maxLength",\n\t"cellSpacing",\n\t"cellPadding",\n\t"rowSpan",\n\t"colSpan",\n\t"useMap",\n\t"frameBorder",\n\t"contentEditable"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( " " );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( "class" ) || "";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === "string" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classNames, cur, curValue, className, i, finalValue;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclassNames = classesToArray( value );\n\n\t\tif ( classNames.length ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tcurValue = getClass( this );\n\t\t\t\tcur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tfor ( i = 0; i < classNames.length; i++ ) {\n\t\t\t\t\t\tclassName = classNames[ i ];\n\t\t\t\t\t\tif ( cur.indexOf( " " + className + " " ) < 0 ) {\n\t\t\t\t\t\t\tcur += className + " ";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\tthis.setAttribute( "class", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classNames, cur, curValue, className, i, finalValue;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( "class", "" );\n\t\t}\n\n\t\tclassNames = classesToArray( value );\n\n\t\tif ( classNames.length ) {\n\t\t\treturn this.each( function() {\
1n\t\t\t\tcurValue = getClass( this );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tfor ( i = 0; i < classNames.length; i++ ) {\n\t\t\t\t\t\tclassName = classNames[ i ];\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( " " + className + " " ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( " " + className + " ", " " );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\tthis.setAttribute( "class", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar classNames, className, i, self,\n\t\t\ttype = typeof value,\n\t\t\tisValidValue = type === "string" || Array.isArray( value );\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\tif ( typeof stateVal === "boolean" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tclassNames = classesToArray( value );\n\n\t\treturn this.each( function() {\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\tself = jQuery( this );\n\n\t\t\t\tfor ( i = 0; i < classNames.length; i++ ) {\n\t\t\t\t\tclassName = classNames[ i ];\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === "boolean" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, "__className__", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we\'re passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( "class",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\t"" :\n\t\t\t\t\t\t\tdataPriv.get( this, "__className__" ) || ""\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = " " + selector + " ";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t"get" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, "value" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === "string" ) {\n\t\t\t\t\treturn ret.replace( rreturn, "" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? "" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as "";
1 convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = "";\n\n\t\t\t} else if ( typeof val === "number" ) {\n\t\t\t\tval += "";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? "" : value + "";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, "value" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (trac-14686, trac-14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === "select-one",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn\'t update selected after form reset (trac-2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don\'t return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, "optgroup" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don\'t need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ "radio", "checkbox" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( "value" ) === null ? "on" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, parserErrorElem;\n\tif ( !data || typeof data !== "string" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );\n\t} catch ( e ) {}\n\n\tparserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];\n\tif ( !xml || parserErrorElem ) {\n\t\tjQuery.error( "Invalid XML: " + (\n\t\t\tparserErrorElem ?\n\t\t\t\tjQuery.map( parserErrorElem.childNodes, function( el ) {\n\t\t\t\t\treturn el.textContent;\n\t\t\t\t} ).join( "\\n" ) :\n\t\t\t\tdata\n\t\t) );\n\t}\n\treturn xml;\n};\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, "type" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don\'t do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we\'re not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( "." ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( "." );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}
1\n\t\tontype = type.indexOf( ":" ) < 0 && "on" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === "object" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( "." );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( "(^|\\\\.)" + namespaces.join( "\\\\.(?:.*\\\\.|)" ) + "(\\\\.|$)" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (trac-9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, "handle" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don\'t do default actions on window, that\'s where global variables be (trac-6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don\'t re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\
1n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === "object" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + "=" +\n\t\t\t\tencodeURIComponent( value == null ? "" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn "";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the "old" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( "&" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for "elements" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, "elements" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} ).filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( ":disabled" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( ":disabled" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} ).map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, "\\r\\n" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, "\\r\\n" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// trac-7653, trac-8125, trac-8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t * - BEFORE asking for a transport\n\t * - AFTER param seri
1alization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol "*" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to "*" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol "*" can be used\n\t * 3) selection will start with transport dataType and THEN go to "*" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression\n\tallTypes = "*/".concat( "*" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( "a" );\n\noriginAnchor.href = location.href;\n\n// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to "*"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== "string" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = "*";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === "+" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || "*";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === "string" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );\n}\n\n// A special extend for ajax options\n// that takes "flat" options (not to be deep extended)\n// Fixes trac-9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === "*" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );\n\t\t}\n\t}\n\n\t// Check if we\'re dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t}
1 else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There\'s only work to do if current dataType is non-auto\n\t\t\tif ( current === "*" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== "*" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + " " + current ] || converters[ "* " + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( " " );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + " " + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ "* " + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: "parsererror",\n\t\t\t\t\t\t\t\terror: conv ? e : "No conversion from " + prev + " to " + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: "success", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: "GET",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: "application/x-www-form-urlencoded; charset=UTF-8",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: fal
1se,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t"*": allTypes,\n\t\t\ttext: "text/plain",\n\t\t\thtml: "text/html",\n\t\t\txml: "application/xml, text/xml",\n\t\t\tjson: "application/json, text/javascript"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: "responseXML",\n\t\t\ttext: "responseText",\n\t\t\tjson: "responseJSON"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall "*") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t"* text": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t"text html": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t"text json": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t"text xml": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn\'t be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn\'t be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === "object" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( "once memory" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = "canceled",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + " " ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + " " ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( ", " );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\
1n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (trac-10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + "" )\n\t\t\t.replace( rprotocol, location.protocol + "//" );\n\n\t\t// Alias method option to type as per ticket trac-12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];\n\n\t\t// A cross-domain request is in order when the origin doesn\'t match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( "a" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor\'s host property isn\'t correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + "//" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== "string" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don\'t fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( "ajaxStart" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we\'re toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, "" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === "string" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cac
1heURL ) ? "&" : "?" ) + s.data;\n\n\t\t\t\t// trac-9682: remove data so that it\'s not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, "$1" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change \'%20\' to \'+\' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, "+" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( "Content-Type", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t"Accept",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :\n\t\t\t\ts.accepts[ "*" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = "abort";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, "No Transport" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( "timeout" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || "";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script but not if jsonp\n\t\t\tif ( !isSuccess &&\n\t\t\t\tjQuery.inArray( "script", s.dataTypes ) > -1 &&\n\t\t\t\tjQuery.inArray( "json", s.dataTypes ) < 0 ) {\n\t\t\t\ts.converters[ "text script" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( "Last-Modified" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( "etag" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === "HEAD" ) {\n\t\t\t\t\tstatusText = "nocontent";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = "notmodified";\n\n\t\t\t\t// If we have data, let\'s convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = "error";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + "";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( "ajaxStop" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, "json" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, "script" );\n\t}\n} );\n\njQuery.each( [ "get", "post" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === "content-type" ) {\n\t\t\ts.contentType = s.headers[ i ] || "";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (trac-11264)\n\t\ttype: "GET",\n\t\tdataType: "script",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t"text script": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}
1\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( "body" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// trac-1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won\'t change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {\n\t\t\t\t\theaders[ "X-Requested-With" ] = "XMLHttpRequest";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === "abort" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === "error" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== "number" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, "error" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see trac-8605, trac-14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || "text" ) !== "text" ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== "string" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t}
1 else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( "abort" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// trac-14683: Only rethrow if this hasn\'t been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: "text/javascript, application/javascript, " +\n\t\t\t"application/ecmascript, application/x-ecmascript"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t"text script": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache\'s special case and crossDomain\njQuery.ajaxPrefilter( "script", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = "GET";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( "script", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( "<script>" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( "load error", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === "error" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: "callback",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t"url" :\n\t\t\ttypeof s.data === "string" &&\n\t\t\t\t( s.contentType || "" )\n\t\t\t\t\t.indexOf( "application/x-www-form-urlencoded" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && "data"\n\t\t);\n\n\t// Handle iff the expected data type is "jsonp" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ "script json" ]
1= function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + " was not called" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = "json";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn\'t exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn\'t screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn "script";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( "" ).body;\n\tbody.innerHTML = "<form></form><form></form>";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument "data" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== "string" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === "boolean" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( "" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document\'s URL (gh-2965)\n\t\t\tbase = context.createElement( "base" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( " " );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it\'s a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it\'s the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === "object" ) {\n\t\ttype = "POST";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If "type" variable is undefined, then "GET" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || "GET",\n\t\t\tdataType: "html",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE \'Permission Denied\' errors\n\t\t\t\tjQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets "data", "status", "jqXHR"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets "jqXHR", "status", "error"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\
1n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, "position" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === "static" ) {\n\t\t\telem.style.position = "relative";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, "top" );\n\t\tcurCSSLeft = jQuery.css( elem, "left" );\n\t\tcalculatePosition = ( position === "absolute" || position === "fixed" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( "using" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element\'s border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element\'s margin box to its offset parent\'s padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, "position" ) === "fixed" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, "position" ) === "static" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.
1nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t// documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {\n\tvar top = "pageYOffset" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ "top", "left" ], function( _i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + "px" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: "height", Width: "width" }, function( name, type ) {\n\tjQuery.each( {\n\t\tpadding: "inner" + name,\n\t\tcontent: type,\n\t\t"": "outer" + name\n\t}, function( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( "outer" ) === 0 ?\n\t\t\t\t\t\telem[ "inner" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ "client" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ "scroll" + name ], doc[ "scroll" + name ],\n\t\t\t\t\t\telem.body[ "offset" + name ], doc[ "offset" + name ],\n\t\t\t\t\t\tdoc[ "client" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( [\n\t"ajaxStart",\n\t"ajaxStop",\n\t"ajaxComplete",\n\t"ajaxError",\n\t"ajaxSuccess",\n\t"ajaxSend"\n], function( _i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, "**" ) :\n\t\t\tthis.off( types, selector || "**", fn );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this\n\t\t\t.on( "mouseenter", fnOver )\n\t\t\t.on( "mouseleave", fnOut || fnOver );\n\t}\n} );\n\njQuery.each(\n\t( "blur focus focusin focusout resize scroll click dblclick " +\n\t"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +\n\t"change select submit keydown keypress keyup contextmenu" ).split( " " ),\n\tfunction( _i, name ) {\n\n\t\t// Handle event binding\n\t\tjQuery.fn[ name ] = function( data, fn ) {\n\t\t\treturn arguments.length > 0 ?\n\t\t\t\tthis.on( name, null, data, fn ) :\n\t\t\t\tthis.trigger( name );\n\t\t};\n\t}\n);\n\n\n\n\n// Support: Android <=4.0 only\n// Make sure we trim BOM and NBSP\n// Require that the "whitespace run" starts from a non-whitespace\n// to avoid O(N^2) behavior when the engine would try matching "\\s+$" at each space position.\nvar rtrim = /^[\\s\\uFEFF\\xA0]+|([^\\s\\uFEFF\\xA0])[\\s\\uFEFF\\xA0]+$/g;\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n
1// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === "string" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === "number" || type === "string" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives ("")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals ("0x...")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\njQuery.trim = function( text ) {\n\treturn text == null ?\n\t\t"" :\n\t\t( text + "" ).replace( rtrim, "$1" );\n};\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( true ) {\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {\n\t\treturn jQuery;\n\t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (trac-13566)\nif ( typeof noGlobal === "undefined" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjkyLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsTUFBTSxLQUEwQjs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOzs7QUFHQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7QUFHQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0F
1BRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTLFlBQVk7O0FBRXJCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRixvQkFBb0I7O0FBRXBCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGLDhDQUE4QztBQUM5QztBQUNBO0FBQ0EsbUJBQW1CLGlDQUFpQztBQUNwRCxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsWUFBWTtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOzs7QUFHRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxVQUFVLFNBQVM7QUFDbkI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVLFlBQVk7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFlBQVk7QUFDdkI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTs7O0FBR0E7OztBQUdBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBOztBQUVBO0FBQ0Esa0NBQWtDLElBQUk7QUFDdEM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLDJCQUEyQjtBQUMzQjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLDBDQUEwQyxJQUFJO0FBQzlDO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEd
1BQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QztBQUN4QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLDBCQUEwQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QU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7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxXQUFXO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLGVBQWU7O0FBRWYsU0FBUzs7QUFFVDtBQUNBLFNBQVMsZ0NBQWdDO0FBQ3pDLFNBQVMsbUJBQW1CO0FBQzVCLFNBQVMscUNBQXFDO0FBQzlDLFNBQVM7QUFDVCxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTixHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxrRUFBa0U7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsUUFBUTs7QUFFUjtBQUNBO0FBQ0EsK0RBQStEO0FBQy9EO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQSxrRUFBa0UsVUFBVTtBQUM1RSx1Q0FBdUMsMkJBQTJCO0FBQ2xFO0FBQ0EsaUNBQWlDLE1BQU07QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQSxXQUFXLFlBQVk7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0EsV0FBVyxZQUFZO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBLFdBQVcsY0FBYztBQUN6QjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLGFBQWEsdUVBQXVFO0FBQ3BGO0FBQ0E7QUFDQSxhQUFhLDRCQUE0QjtBQUN6QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLFNBQVM7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsNkRBQTZEOztBQUU3RDtBQUNBO0FBQ0EsUUFBUTtBQUNSOztBQUVBO0FBQ0E7QUFDQSxRQUFROztBQUVSO0FBQ0E7O0FBRUEsb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUyxTQUFTO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTLFNBQVM7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEd
1BQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKLFNBQVMsU0FBUztBQUNsQjtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFlBQVksU0FBUztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0JBQWtCLGlEQUFpRDtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrREFBa0Q7QUFDbEQ7QUFDQSxXQUFXLDRDQUE0QztBQUN2RDtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxpQkFBaUI7QUFDNUI7QUFDQSxXQUFXLFNBQVM7QUFDcEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBLFNBQVMsR0FBRztBQUNaO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBOztBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUEsZUFBZSxTQUFTO0FBQ3hCO0FBQ0E7O0FBRUE7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLE1BQU07QUFDTjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsMkJBQTJCLHdCQUF3Qjs7QUFFbkQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0F
1BRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0EsMkNBQTJDO0FBQzNDLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUI7O0FBRW5CO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsY0FBYztBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSLE9BQU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHlDQUF5QyxxQ0FBcUM7QUFDOUUscUNBQXFDLHNDQUFzQztBQUMzRSxxQ0FBcUMscUNBQXFDO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsUUFBUTtBQUNSO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxZQUFZOztBQUVaO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFdBQVc7O0FBRVg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw0REFBNEQ7QUFDNUQ7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07O0FBRU47QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFDQUFxQztBQUNyQyxzQ0FBc0M7QUFDdEMscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0F
1BRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7Ozs7QUFLQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQSxXQUFXLFNBQVM7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdCQUF3QixhQUFhO0FBQ3JDLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLFNBQVM7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxFQUFFOzs7QUFHRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7OztBQUdBOztBQUVBOzs7O0FBSUE7QUFDQTtBQUNBLEdBQUc7QUFDSCxlQUFlOztBQUVmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTLGdCQUFnQjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxFQUFFO0FBQ0Y7O0FBRUE7O0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7OztBQUdGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxHQUFHO0FBQ0g7O0FBRUEsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVMsT0FBTztBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0Esc0JBQXNCOztBQUV0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUyxPQUFPO0FBQ2hCOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxXQUFXOztBQUVYOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsNENBQTRDO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGdFQUFnRTtBQUNoRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFdBQVcsY0FBYzs7QUFFekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixtQkFBbUI7QUFDckM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQix1Q0FBdUM7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHVEQUF1RDtBQUMvRTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsSUFBSTtBQUNKLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEd
1BQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTSwrQ0FBK0M7QUFDckQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx1Q0FBdUM7QUFDdkM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsZUFBZSxvQ0FBb0M7O0FBRW5EO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHlEQUF5RDtBQUN6RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLEVBQUU7OztBQUdGOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEMsT0FBTztBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4Qjs7QUFFOUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU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FDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDZDQUE2QyxjQUFjO0FBQzNELCtDQUErQzs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFOzs7QUFHRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHVEQUF1RDtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLDhEQUE4RDtBQUMzRTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVMsT0FBTzs7QUFFaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0F
1BRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBLElBQUk7O0FBRUo7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGVBQWU7QUFDbEM7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7O0FBRUEsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsWUFBWSxTQUFTO0FBQ3JCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOzs7QUFHRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7O0FBRVo7QUFDQT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tBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7Ozs7QUFLRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7Ozs7O0FBS0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBa0IsdUJBQXVCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBa0IsdUJBQXVCO0FBQ3pDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsdUJBQXVCO0FBQ3hDOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEVBQUU7O0FBRUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOzs7OztBQUtGOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEsa0NBQWtDO0FBQ2xDO0FBQ0E7O0FBRUEsS0FBSztBQUNMOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBLFlBQVksU0FBUztBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7Ozs7QUFLRjtBQUNBOztBQUVBLGNBQWM7O0FBRWQ7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBOztBQUVBOztBQUVBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRDQUE0QztBQUM1Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsS0FBSztBQUNoQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxFQUFFOztBQUVGOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUosR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQT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s7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQjs7QUFFM0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQzs7QUFFbEM7QUFDQSxzQkFBc0I7QUFDdEIsMkJBQTJCOztBQUUzQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLEtB
1QUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFROztBQUVSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RDtBQUN2RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUk7QUFDSixFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSixFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUEsb0RBQW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSx1QkFBdUI7QUFDbkMsWUFBWSx3QkFBd0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7Ozs7O0FBS0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0F
1BRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEMsY0FBYyx1Q0FBdUM7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7Ozs7QUFLRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7Ozs7O0FBS0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsSUFBSTtBQUNKOztBQUVBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EscURBQXFEO0FBQ3JEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQjs7QUFFcEI7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBLEVBQUU7O0FBRUY7QUFDQSxlQUFlLHFEQUFxRDtBQUNwRTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOzs7QUFHRjtBQUNBLGVBQWUsa0NBQWtDO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsR0FBRztBQUNILEVBQUU7OztBQUdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOzs7OztBQUtGOztBQUVBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0F
1BRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLLElBQTBDO0FBQy9DLENBQUMsaUNBQWtCLEVBQUUsbUNBQUU7QUFDdkI7QUFDQSxFQUFFO0FBQUEsa0dBQUU7QUFDSjs7Ozs7QUFLQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0EsRUFBRSIsInNvdXJjZXMiOlsid2VicGFjazovL2Jvc3Ryb20td2VicGFjay8uL25vZGVfbW9kdWxlcy9qcXVlcnkvZGlzdC9qcXVlcnkuanM/MTE1NyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjMuNy4xXG4gKiBodHRwczovL2pxdWVyeS5jb20vXG4gKlxuICogQ29weXJpZ2h0IE9wZW5KUyBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cHM6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcbiAqXG4gKiBEYXRlOiAyMDIzLTA4LTI4VDEzOjM3WlxuICovXG4oIGZ1bmN0aW9uKCBnbG9iYWwsIGZhY3RvcnkgKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cblx0aWYgKCB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdC8vIEZvciBDb21tb25KUyBhbmQgQ29tbW9uSlMtbGlrZSBlbnZpcm9ubWVudHMgd2hlcmUgYSBwcm9wZXIgYHdpbmRvd2Bcblx0XHQvLyBpcyBwcmVzZW50LCBleGVjdXRlIHRoZSBmYWN0b3J5IGFuZCBnZXQgalF1ZXJ5LlxuXHRcdC8vIEZvciBlbnZpcm9ubWVudHMgdGhhdCBkbyBub3QgaGF2ZSBhIGB3aW5kb3dgIHdpdGggYSBgZG9jdW1lbnRgXG5cdFx0Ly8gKHN1Y2ggYXMgTm9kZS5qcyksIGV4cG9zZSBhIGZhY3RvcnkgYXMgbW9kdWxlLmV4cG9ydHMuXG5cdFx0Ly8gVGhpcyBhY2NlbnR1YXRlcyB0aGUgbmVlZCBmb3IgdGhlIGNyZWF0aW9uIG9mIGEgcmVhbCBgd2luZG93YC5cblx0XHQvLyBlLmcuIHZhciBqUXVlcnkgPSByZXF1aXJlKFwianF1ZXJ5XCIpKHdpbmRvdyk7XG5cdFx0Ly8gU2VlIHRpY2tldCB0cmFjLTE0NTQ5IGZvciBtb3JlIGluZm8uXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBnbG9iYWwuZG9jdW1lbnQgP1xuXHRcdFx0ZmFjdG9yeSggZ2xvYmFsLCB0cnVlICkgOlxuXHRcdFx0ZnVuY3Rpb24oIHcgKSB7XG5cdFx0XHRcdGlmICggIXcuZG9jdW1lbnQgKSB7XG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCBcImpRdWVyeSByZXF1aXJlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnRcIiApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBmYWN0b3J5KCB3ICk7XG5cdFx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdGZhY3RvcnkoIGdsb2JhbCApO1xuXHR9XG5cbi8vIFBhc3MgdGhpcyBpZiB3aW5kb3cgaXMgbm90IGRlZmluZWQgeWV0XG59ICkoIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0aGlzLCBmdW5jdGlvbiggd2luZG93LCBub0dsb2JhbCApIHtcblxuLy8gRWRnZSA8PSAxMiAtIDEzKywgRmlyZWZveCA8PTE4IC0gNDUrLCBJRSAxMCAtIDExLCBTYWZhcmkgNS4xIC0gOSssIGlPUyA2IC0gOS4xXG4vLyB0aHJvdyBleGNlcHRpb25zIHdoZW4gbm9uLXN0cmljdCBjb2RlIChlLmcuLCBBU1AuTkVUIDQuNSkgYWNjZXNzZXMgc3RyaWN0IG1vZGVcbi8vIGFyZ3VtZW50cy5jYWxsZWUuY2FsbGVyICh0cmFjLTEzMzM1KS4gQnV0IGFzIG9mIGpRdWVyeSAzLjAgKDIwMTYpLCBzdHJpY3QgbW9kZSBzaG91bGQgYmUgY29tbW9uXG4vLyBlbm91Z2ggdGhhdCBhbGwgc3VjaCBhdHRlbXB0cyBhcmUgZ3VhcmRlZCBpbiBhIHRyeSBibG9jay5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgYXJyID0gW107XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcblxudmFyIHNsaWNlID0gYXJyLnNsaWNlO1xuXG52YXIgZmxhdCA9IGFyci5mbGF0ID8gZnVuY3Rpb24oIGFycmF5ICkge1xuXHRyZXR1cm4gYXJyLmZsYXQuY2FsbCggYXJyYXkgKTtcbn0gOiBmdW5jdGlvbiggYXJyYXkgKSB7XG5cdHJldHVybiBhcnIuY29uY2F0LmFwcGx5KCBbXSwgYXJyYXkgKTtcbn07XG5cblxudmFyIHB1c2ggPSBhcnIucHVzaDtcblxudmFyIGluZGV4T2YgPSBhcnIuaW5kZXhPZjtcblxudmFyIGNsYXNzMnR5cGUgPSB7fTtcblxudmFyIHRvU3RyaW5nID0gY2xhc3MydHlwZS50b1N0cmluZztcblxudmFyIGhhc093biA9IGNsYXNzMnR5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBmblRvU3RyaW5nID0gaGFzT3duLnRvU3RyaW5nO1xuXG52YXIgT2JqZWN0RnVuY3Rpb25TdHJpbmcgPSBmblRvU3RyaW5nLmNhbGwoIE9iamVjdCApO1xuXG52YXIgc3VwcG9ydCA9IHt9O1xuXG52YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIGlzRnVuY3Rpb24oIG9iaiApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTU3LCBGaXJlZm94IDw9NTJcblx0XHQvLyBJbiBzb21lIGJyb3dzZXJzLCB0eXBlb2YgcmV0dXJucyBcImZ1bmN0aW9uXCIgZm9yIEhUTUwgPG9iamVjdD4gZWxlbWVudHNcblx0XHQvLyAoaS5lLiwgYHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9iamVjdFwiICkgPT09IFwiZnVuY3Rpb25cImApLlxuXHRcdC8vIFdlIGRvbid0IHdhbnQgdG8gY2xhc3NpZnkgKmFueSogRE9NIG5vZGUgYXMgYSBmdW5jdGlvbi5cblx0XHQvLyBTdXBwb3J0OiBRdFdlYiA8PTMuOC41LCBXZWJLaXQgPD01MzQuMzQsIHdraHRtbHRvcGRmIHRvb2wgPD0wLjEyLjVcblx0XHQvLyBQbHVzIGZvciBvbGQgV2ViS2l0LCB0eXBlb2YgcmV0dXJucyBcImZ1bmN0aW9uXCIgZm9yIEhUTUwgY29sbGVjdGlvbnNcblx0XHQvLyAoZS5nLiwgYHR5cGVvZiBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImRpdlwiKSA9PT0gXCJmdW5jdGlvblwiYCkuIChnaC00NzU2KVxuXHRcdHJldHVybi
1B0eXBlb2Ygb2JqID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIG9iai5ub2RlVHlwZSAhPT0gXCJudW1iZXJcIiAmJlxuXHRcdFx0dHlwZW9mIG9iai5pdGVtICE9PSBcImZ1bmN0aW9uXCI7XG5cdH07XG5cblxudmFyIGlzV2luZG93ID0gZnVuY3Rpb24gaXNXaW5kb3coIG9iaiApIHtcblx0XHRyZXR1cm4gb2JqICE9IG51bGwgJiYgb2JqID09PSBvYmoud2luZG93O1xuXHR9O1xuXG5cbnZhciBkb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudDtcblxuXG5cblx0dmFyIHByZXNlcnZlZFNjcmlwdEF0dHJpYnV0ZXMgPSB7XG5cdFx0dHlwZTogdHJ1ZSxcblx0XHRzcmM6IHRydWUsXG5cdFx0bm9uY2U6IHRydWUsXG5cdFx0bm9Nb2R1bGU6IHRydWVcblx0fTtcblxuXHRmdW5jdGlvbiBET01FdmFsKCBjb2RlLCBub2RlLCBkb2MgKSB7XG5cdFx0ZG9jID0gZG9jIHx8IGRvY3VtZW50O1xuXG5cdFx0dmFyIGksIHZhbCxcblx0XHRcdHNjcmlwdCA9IGRvYy5jcmVhdGVFbGVtZW50KCBcInNjcmlwdFwiICk7XG5cblx0XHRzY3JpcHQudGV4dCA9IGNvZGU7XG5cdFx0aWYgKCBub2RlICkge1xuXHRcdFx0Zm9yICggaSBpbiBwcmVzZXJ2ZWRTY3JpcHRBdHRyaWJ1dGVzICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggNjQrLCBFZGdlIDE4K1xuXHRcdFx0XHQvLyBTb21lIGJyb3dzZXJzIGRvbid0IHN1cHBvcnQgdGhlIFwibm9uY2VcIiBwcm9wZXJ0eSBvbiBzY3JpcHRzLlxuXHRcdFx0XHQvLyBPbiB0aGUgb3RoZXIgaGFuZCwganVzdCB1c2luZyBgZ2V0QXR0cmlidXRlYCBpcyBub3QgZW5vdWdoIGFzXG5cdFx0XHRcdC8vIHRoZSBgbm9uY2VgIGF0dHJpYnV0ZSBpcyByZXNldCB0byBhbiBlbXB0eSBzdHJpbmcgd2hlbmV2ZXIgaXRcblx0XHRcdFx0Ly8gYmVjb21lcyBicm93c2luZy1jb250ZXh0IGNvbm5lY3RlZC5cblx0XHRcdFx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS93aGF0d2cvaHRtbC9pc3N1ZXMvMjM2OVxuXHRcdFx0XHQvLyBTZWUgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jbm9uY2UtYXR0cmlidXRlc1xuXHRcdFx0XHQvLyBUaGUgYG5vZGUuZ2V0QXR0cmlidXRlYCBjaGVjayB3YXMgYWRkZWQgZm9yIHRoZSBzYWtlIG9mXG5cdFx0XHRcdC8vIGBqUXVlcnkuZ2xvYmFsRXZhbGAgc28gdGhhdCBpdCBjYW4gZmFrZSBhIG5vbmNlLWNvbnRhaW5pbmcgbm9kZVxuXHRcdFx0XHQvLyB2aWEgYW4gb2JqZWN0LlxuXHRcdFx0XHR2YWwgPSBub2RlWyBpIF0gfHwgbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoIGkgKTtcblx0XHRcdFx0aWYgKCB2YWwgKSB7XG5cdFx0XHRcdFx0c2NyaXB0LnNldEF0dHJpYnV0ZSggaSwgdmFsICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0ZG9jLmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdCApLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHNjcmlwdCApO1xuXHR9XG5cblxuZnVuY3Rpb24gdG9UeXBlKCBvYmogKSB7XG5cdGlmICggb2JqID09IG51bGwgKSB7XG5cdFx0cmV0dXJuIG9iaiArIFwiXCI7XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9Mi4zIG9ubHkgKGZ1bmN0aW9uaXNoIFJlZ0V4cClcblx0cmV0dXJuIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIG9iaiA9PT0gXCJmdW5jdGlvblwiID9cblx0XHRjbGFzczJ0eXBlWyB0b1N0cmluZy5jYWxsKCBvYmogKSBdIHx8IFwib2JqZWN0XCIgOlxuXHRcdHR5cGVvZiBvYmo7XG59XG4vKiBnbG9iYWwgU3ltYm9sICovXG4vLyBEZWZpbmluZyB0aGlzIGdsb2JhbCBpbiAuZXNsaW50cmMuanNvbiB3b3VsZCBjcmVhdGUgYSBkYW5nZXIgb2YgdXNpbmcgdGhlIGdsb2JhbFxuLy8gdW5ndWFyZGVkIGluIGFub3RoZXIgcGxhY2UsIGl0IHNlZW1zIHNhZmVyIHRvIGRlZmluZSBnbG9iYWwgb25seSBmb3IgdGhpcyBtb2R1bGVcblxuXG5cbnZhciB2ZXJzaW9uID0gXCIzLjcuMVwiLFxuXG5cdHJodG1sU3VmZml4ID0gL0hUTUwkL2ksXG5cblx0Ly8gRGVmaW5lIGEgbG9jYWwgY29weSBvZiBqUXVlcnlcblx0alF1ZXJ5ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkge1xuXG5cdFx0Ly8gVGhlIGpRdWVyeSBvYmplY3QgaXMgYWN0dWFsbHkganVzdCB0aGUgaW5pdCBjb25zdHJ1Y3RvciAnZW5oYW5jZWQnXG5cdFx0Ly8gTmVlZCBpbml0IGlmIGpRdWVyeSBpcyBjYWxsZWQgKGp1c3QgYWxsb3cgZXJyb3IgdG8gYmUgdGhyb3duIGlmIG5vdCBpbmNsdWRlZClcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5mbi5pbml0KCBzZWxlY3RvciwgY29udGV4dCApO1xuXHR9O1xuXG5qUXVlcnkuZm4gPSBqUXVlcnkucHJvdG90eXBlID0ge1xuXG5cdC8vIFRoZSBjdXJyZW50IHZlcnNpb24gb2YgalF1ZXJ5IGJlaW5nIHVzZWRcblx0anF1ZXJ5OiB2ZXJzaW9uLFxuXG5cdGNvbnN0cnVjdG9yOiBqUXVlcnksXG5cblx0Ly8gVGhlIGRlZmF1bHQgbGVuZ3RoIG9mIGEgalF1ZXJ5IG9iamVjdCBpcyAwXG5cdGxlbmd0aDogMCxcblxuXHR0b0FycmF5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2xpY2UuY2FsbCggdGhpcyApO1xuXHR9LFxuXG5cdC8vIEdldCB0aGUgTnRoIGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgZWxlbWVudCBzZXQgT1Jcblx0Ly8gR2V0IHRoZSB3aG9sZSBtYXRjaGVkIGVsZW1lbnQgc2V0IGFzIGEgY2xlYW4gYXJyYXlcblx0Z2V0OiBmdW5jdGlvbiggbnVtICkge1xuXG5cdFx0Ly8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgaW4gYSBjbGVhbiBhcnJheVxuXHRcdGlmICggbnVtID09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gc2xpY2UuY2FsbCggdGhpcyApO1xuXHRcdH1cblxuXHRcdC8vIFJldHVybiBqdXN0IHRoZSBvbmUgZWxlbWVudCBmcm9tIHRoZSBzZXRcblx0XHRyZXR1cm4gbnVtIDwgMCA/IHRoaXNbIG51bSArIHRoaXMubGVuZ3RoIF0gOiB0aGlzWyBudW0gXTtcblx0fSxcblxuXHQvLyBUYWtlIGFuIGFycmF5IG9mIGVsZW1lbnRzIGFuZCBwdXNoIGl0IG9udG8gdGhlIHN0YWNrXG5cdC8vIChyZXR1cm5pbmcgdGhlIG5ldyBtYXRjaGVkIGVsZW1lbnQgc2V0KVxuXHRwdXNoU3RhY2s6IGZ1bmN0aW9uKCBlbGVtcyApIHtcblxuXHRcdC8vIEJ1aWxkIGEgbmV3IGpRdWVyeSBtYXRjaGVkIGVsZW1lbnQgc2V0XG5cdFx0dmFyIHJldCA9IGpRdWVyeS5tZXJnZSggdGhpcy5jb25zdHJ1Y3RvcigpLCBlbGVtcyApO1xuXG5cdFx0Ly8gQWRkIHRoZSBvbGQgb2JqZWN0IG9udG8gdGhlIHN0YWNrIChhcyBhIHJlZmVyZW5jZSlcblx0XHRyZXQucHJldk9iamVjdCA9IHRoaXM7XG5cblx0XHQvLyBSZXR1cm4gdGhlIG5ld2x5LWZvcm1lZCBlbGVtZW50IHNldFxuXHRcdHJldHVybi
1ByZXQ7XG5cdH0sXG5cblx0Ly8gRXhlY3V0ZSBhIGNhbGxiYWNrIGZvciBldmVyeSBlbGVtZW50IGluIHRoZSBtYXRjaGVkIHNldC5cblx0ZWFjaDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBqUXVlcnkuZWFjaCggdGhpcywgY2FsbGJhY2sgKTtcblx0fSxcblxuXHRtYXA6IGZ1bmN0aW9uKCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeS5tYXAoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBpICkge1xuXHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwoIGVsZW0sIGksIGVsZW0gKTtcblx0XHR9ICkgKTtcblx0fSxcblxuXHRzbGljZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBzbGljZS5hcHBseSggdGhpcywgYXJndW1lbnRzICkgKTtcblx0fSxcblxuXHRmaXJzdDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZXEoIDAgKTtcblx0fSxcblxuXHRsYXN0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lcSggLTEgKTtcblx0fSxcblxuXHRldmVuOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeS5ncmVwKCB0aGlzLCBmdW5jdGlvbiggX2VsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gKCBpICsgMSApICUgMjtcblx0XHR9ICkgKTtcblx0fSxcblxuXHRvZGQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5LmdyZXAoIHRoaXMsIGZ1bmN0aW9uKCBfZWxlbSwgaSApIHtcblx0XHRcdHJldHVybiBpICUgMjtcblx0XHR9ICkgKTtcblx0fSxcblxuXHRlcTogZnVuY3Rpb24oIGkgKSB7XG5cdFx0dmFyIGxlbiA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0aiA9ICtpICsgKCBpIDwgMCA/IGxlbiA6IDAgKTtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGogPj0gMCAmJiBqIDwgbGVuID8gWyB0aGlzWyBqIF0gXSA6IFtdICk7XG5cdH0sXG5cblx0ZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wcmV2T2JqZWN0IHx8IHRoaXMuY29uc3RydWN0b3IoKTtcblx0fSxcblxuXHQvLyBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuXG5cdC8vIEJlaGF2ZXMgbGlrZSBhbiBBcnJheSdzIG1ldGhvZCwgbm90IGxpa2UgYSBqUXVlcnkgbWV0aG9kLlxuXHRwdXNoOiBwdXNoLFxuXHRzb3J0OiBhcnIuc29ydCxcblx0c3BsaWNlOiBhcnIuc3BsaWNlXG59O1xuXG5qUXVlcnkuZXh0ZW5kID0galF1ZXJ5LmZuLmV4dGVuZCA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgb3B0aW9ucywgbmFtZSwgc3JjLCBjb3B5LCBjb3B5SXNBcnJheSwgY2xvbmUsXG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWyAwIF0gfHwge30sXG5cdFx0aSA9IDEsXG5cdFx0bGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcblx0XHRkZWVwID0gZmFsc2U7XG5cblx0Ly8gSGFuZGxlIGEgZGVlcCBjb3B5IHNpdHVhdGlvblxuXHRpZiAoIHR5cGVvZiB0YXJnZXQgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdGRlZXAgPSB0YXJnZXQ7XG5cblx0XHQvLyBTa2lwIHRoZSBib29sZWFuIGFuZCB0aGUgdGFyZ2V0XG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWyBpIF0gfHwge307XG5cdFx0aSsrO1xuXHR9XG5cblx0Ly8gSGFuZGxlIGNhc2Ugd2hlbiB0YXJnZXQgaXMgYSBzdHJpbmcgb3Igc29tZXRoaW5nIChwb3NzaWJsZSBpbiBkZWVwIGNvcHkpXG5cdGlmICggdHlwZW9mIHRhcmdldCAhPT0gXCJvYmplY3RcIiAmJiAhaXNGdW5jdGlvbiggdGFyZ2V0ICkgKSB7XG5cdFx0dGFyZ2V0ID0ge307XG5cdH1cblxuXHQvLyBFeHRlbmQgalF1ZXJ5IGl0c2VsZiBpZiBvbmx5IG9uZSBhcmd1bWVudCBpcyBwYXNzZWRcblx0aWYgKCBpID09PSBsZW5ndGggKSB7XG5cdFx0dGFyZ2V0ID0gdGhpcztcblx0XHRpLS07XG5cdH1cblxuXHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblxuXHRcdC8vIE9ubHkgZGVhbCB3aXRoIG5vbi1udWxsL3VuZGVmaW5lZCB2YWx1ZXNcblx0XHRpZiAoICggb3B0aW9ucyA9IGFyZ3VtZW50c1sgaSBdICkgIT0gbnVsbCApIHtcblxuXHRcdFx0Ly8gRXh0ZW5kIHRoZSBiYXNlIG9iamVjdFxuXHRcdFx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdFx0XHRjb3B5ID0gb3B0aW9uc1sgbmFtZSBdO1xuXG5cdFx0XHRcdC8vIFByZXZlbnQgT2JqZWN0LnByb3RvdHlwZSBwb2xsdXRpb25cblx0XHRcdFx0Ly8gUHJldmVudCBuZXZlci1lbmRpbmcgbG9vcFxuXHRcdFx0XHRpZiAoIG5hbWUgPT09IFwiX19wcm90b19fXCIgfHwgdGFyZ2V0ID09PSBjb3B5ICkge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmVjdXJzZSBpZiB3ZSdyZSBtZXJnaW5nIHBsYWluIG9iamVjdHMgb3IgYXJyYXlzXG5cdFx0XHRcdGlmICggZGVlcCAmJiBjb3B5ICYmICggalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGNvcHkgKSB8fFxuXHRcdFx0XHRcdCggY29weUlzQXJyYXkgPSBBcnJheS5pc0FycmF5KCBjb3B5ICkgKSApICkge1xuXHRcdFx0XHRcdHNyYyA9IHRhcmdldFsgbmFtZSBdO1xuXG5cdFx0XHRcdFx0Ly8gRW5zdXJlIHByb3BlciB0eXBlIGZvciB0aGUgc291cmNlIHZhbHVlXG5cdFx0XHRcdFx0aWYgKCBjb3B5SXNBcnJheSAmJiAhQXJyYXkuaXNBcnJheSggc3JjICkgKSB7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IFtdO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoICFjb3B5SXNBcnJheSAmJiAhalF1ZXJ5LmlzUGxhaW5PYmplY3QoIHNyYyApICkge1xuXHRcdFx0XHRcdFx0Y2xvbmUgPSB7fTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y2xvbmUgPSBzcmM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvcHlJc0FycmF5ID0gZmFsc2U7XG5cblx0XHRcdFx0XHQvLyBOZXZlciBtb3ZlIG9yaWdpbmFsIG9iamVjdHMsIGNsb25lIHRoZW1cblx0XHRcdFx0XHR0YXJnZXRbIG5hbWUgXSA9IGpRdWVyeS5leHRlbmQoIGRlZXAsIGNsb25lLCBjb3B5ICk7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgYnJpbmcgaW4gdW5kZWZpbmVkIHZhbHVlc1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBjb3B5ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0dGFyZ2V0WyBuYW1lIF0gPSBjb3B5O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBtb2RpZmllZCBvYmplY3Rcblx0cmV0dXJuIHRhcmdldDtcbn07XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHQvLyBVbmlxdWUgZm9yIGVhY2ggY29we
1SBvZiBqUXVlcnkgb24gdGhlIHBhZ2Vcblx0ZXhwYW5kbzogXCJqUXVlcnlcIiArICggdmVyc2lvbiArIE1hdGgucmFuZG9tKCkgKS5yZXBsYWNlKCAvXFxEL2csIFwiXCIgKSxcblxuXHQvLyBBc3N1bWUgalF1ZXJ5IGlzIHJlYWR5IHdpdGhvdXQgdGhlIHJlYWR5IG1vZHVsZVxuXHRpc1JlYWR5OiB0cnVlLFxuXG5cdGVycm9yOiBmdW5jdGlvbiggbXNnICkge1xuXHRcdHRocm93IG5ldyBFcnJvciggbXNnICk7XG5cdH0sXG5cblx0bm9vcDogZnVuY3Rpb24oKSB7fSxcblxuXHRpc1BsYWluT2JqZWN0OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHZhciBwcm90bywgQ3RvcjtcblxuXHRcdC8vIERldGVjdCBvYnZpb3VzIG5lZ2F0aXZlc1xuXHRcdC8vIFVzZSB0b1N0cmluZyBpbnN0ZWFkIG9mIGpRdWVyeS50eXBlIHRvIGNhdGNoIGhvc3Qgb2JqZWN0c1xuXHRcdGlmICggIW9iaiB8fCB0b1N0cmluZy5jYWxsKCBvYmogKSAhPT0gXCJbb2JqZWN0IE9iamVjdF1cIiApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRwcm90byA9IGdldFByb3RvKCBvYmogKTtcblxuXHRcdC8vIE9iamVjdHMgd2l0aCBubyBwcm90b3R5cGUgKGUuZy4sIGBPYmplY3QuY3JlYXRlKCBudWxsIClgKSBhcmUgcGxhaW5cblx0XHRpZiAoICFwcm90byApIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIE9iamVjdHMgd2l0aCBwcm90b3R5cGUgYXJlIHBsYWluIGlmZiB0aGV5IHdlcmUgY29uc3RydWN0ZWQgYnkgYSBnbG9iYWwgT2JqZWN0IGZ1bmN0aW9uXG5cdFx0Q3RvciA9IGhhc093bi5jYWxsKCBwcm90bywgXCJjb25zdHJ1Y3RvclwiICkgJiYgcHJvdG8uY29uc3RydWN0b3I7XG5cdFx0cmV0dXJuIHR5cGVvZiBDdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgZm5Ub1N0cmluZy5jYWxsKCBDdG9yICkgPT09IE9iamVjdEZ1bmN0aW9uU3RyaW5nO1xuXHR9LFxuXG5cdGlzRW1wdHlPYmplY3Q6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0dmFyIG5hbWU7XG5cblx0XHRmb3IgKCBuYW1lIGluIG9iaiApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cblx0Ly8gRXZhbHVhdGVzIGEgc2NyaXB0IGluIGEgcHJvdmlkZWQgY29udGV4dDsgZmFsbHMgYmFjayB0byB0aGUgZ2xvYmFsIG9uZVxuXHQvLyBpZiBub3Qgc3BlY2lmaWVkLlxuXHRnbG9iYWxFdmFsOiBmdW5jdGlvbiggY29kZSwgb3B0aW9ucywgZG9jICkge1xuXHRcdERPTUV2YWwoIGNvZGUsIHsgbm9uY2U6IG9wdGlvbnMgJiYgb3B0aW9ucy5ub25jZSB9LCBkb2MgKTtcblx0fSxcblxuXHRlYWNoOiBmdW5jdGlvbiggb2JqLCBjYWxsYmFjayApIHtcblx0XHR2YXIgbGVuZ3RoLCBpID0gMDtcblxuXHRcdGlmICggaXNBcnJheUxpa2UoIG9iaiApICkge1xuXHRcdFx0bGVuZ3RoID0gb2JqLmxlbmd0aDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrLmNhbGwoIG9ialsgaSBdLCBpLCBvYmpbIGkgXSApID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3IgKCBpIGluIG9iaiApIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gb2JqO1xuXHR9LFxuXG5cblx0Ly8gUmV0cmlldmUgdGhlIHRleHQgdmFsdWUgb2YgYW4gYXJyYXkgb2YgRE9NIG5vZGVzXG5cdHRleHQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBub2RlLFxuXHRcdFx0cmV0ID0gXCJcIixcblx0XHRcdGkgPSAwLFxuXHRcdFx0bm9kZVR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0aWYgKCAhbm9kZVR5cGUgKSB7XG5cblx0XHRcdC8vIElmIG5vIG5vZGVUeXBlLCB0aGlzIGlzIGV4cGVjdGVkIHRvIGJlIGFuIGFycmF5XG5cdFx0XHR3aGlsZSAoICggbm9kZSA9IGVsZW1bIGkrKyBdICkgKSB7XG5cblx0XHRcdFx0Ly8gRG8gbm90IHRyYXZlcnNlIGNvbW1lbnQgbm9kZXNcblx0XHRcdFx0cmV0ICs9IGpRdWVyeS50ZXh0KCBub2RlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICggbm9kZVR5cGUgPT09IDEgfHwgbm9kZVR5cGUgPT09IDExICkge1xuXHRcdFx0cmV0dXJuIGVsZW0udGV4dENvbnRlbnQ7XG5cdFx0fVxuXHRcdGlmICggbm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kb2N1bWVudEVsZW1lbnQudGV4dENvbnRlbnQ7XG5cdFx0fVxuXHRcdGlmICggbm9kZVR5cGUgPT09IDMgfHwgbm9kZVR5cGUgPT09IDQgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlVmFsdWU7XG5cdFx0fVxuXG5cdFx0Ly8gRG8gbm90IGluY2x1ZGUgY29tbWVudCBvciBwcm9jZXNzaW5nIGluc3RydWN0aW9uIG5vZGVzXG5cblx0XHRyZXR1cm4gcmV0O1xuXHR9LFxuXG5cdC8vIHJlc3VsdHMgaXMgZm9yIGludGVybmFsIHVzYWdlIG9ubHlcblx0bWFrZUFycmF5OiBmdW5jdGlvbiggYXJyLCByZXN1bHRzICkge1xuXHRcdHZhciByZXQgPSByZXN1bHRzIHx8IFtdO1xuXG5cdFx0aWYgKCBhcnIgIT0gbnVsbCApIHtcblx0XHRcdGlmICggaXNBcnJheUxpa2UoIE9iamVjdCggYXJyICkgKSApIHtcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCByZXQsXG5cdFx0XHRcdFx0dHlwZW9mIGFyciA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdFx0XHRbIGFyciBdIDogYXJyXG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmNhbGwoIHJldCwgYXJyICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHRpbkFycmF5OiBmdW5jdGlvbiggZWxlbSwgYXJyLCBpICkge1xuXHRcdHJldHVybiBhcnIgPT0gbnVsbCA/IC0xIDogaW5kZXhPZi5jYWxsKCBhcnIsIGVsZW0sIGkgKTtcblx0fSxcblxuXHRpc1hNTERvYzogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIG5hbWVzcGFjZSA9IGVsZW0gJiYgZWxlbS5uYW1lc3BhY2VVUkksXG5cdFx0XHRkb2NFbGVtID0gZWxlbSAmJiAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkuZG9jdW1lbnRFbGVtZW50O1xuXG5cdFx0Ly8gQXNzdW1lIEhUTUwgd2hlbiBkb2N1bWVudEVsZW1lbnQgZG9lc24ndCB5ZXQgZXhpc3QsIHN1Y2ggYXMgaW5zaWRlXG5cdFx0Ly8gZG9jdW1lbnQgZnJhZ21lbn
1RzLlxuXHRcdHJldHVybiAhcmh0bWxTdWZmaXgudGVzdCggbmFtZXNwYWNlIHx8IGRvY0VsZW0gJiYgZG9jRWxlbS5ub2RlTmFtZSB8fCBcIkhUTUxcIiApO1xuXHR9LFxuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seVxuXHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdG1lcmdlOiBmdW5jdGlvbiggZmlyc3QsIHNlY29uZCApIHtcblx0XHR2YXIgbGVuID0gK3NlY29uZC5sZW5ndGgsXG5cdFx0XHRqID0gMCxcblx0XHRcdGkgPSBmaXJzdC5sZW5ndGg7XG5cblx0XHRmb3IgKCA7IGogPCBsZW47IGorKyApIHtcblx0XHRcdGZpcnN0WyBpKysgXSA9IHNlY29uZFsgaiBdO1xuXHRcdH1cblxuXHRcdGZpcnN0Lmxlbmd0aCA9IGk7XG5cblx0XHRyZXR1cm4gZmlyc3Q7XG5cdH0sXG5cblx0Z3JlcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgaW52ZXJ0ICkge1xuXHRcdHZhciBjYWxsYmFja0ludmVyc2UsXG5cdFx0XHRtYXRjaGVzID0gW10sXG5cdFx0XHRpID0gMCxcblx0XHRcdGxlbmd0aCA9IGVsZW1zLmxlbmd0aCxcblx0XHRcdGNhbGxiYWNrRXhwZWN0ID0gIWludmVydDtcblxuXHRcdC8vIEdvIHRocm91Z2ggdGhlIGFycmF5LCBvbmx5IHNhdmluZyB0aGUgaXRlbXNcblx0XHQvLyB0aGF0IHBhc3MgdGhlIHZhbGlkYXRvciBmdW5jdGlvblxuXHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0Y2FsbGJhY2tJbnZlcnNlID0gIWNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpICk7XG5cdFx0XHRpZiAoIGNhbGxiYWNrSW52ZXJzZSAhPT0gY2FsbGJhY2tFeHBlY3QgKSB7XG5cdFx0XHRcdG1hdGNoZXMucHVzaCggZWxlbXNbIGkgXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBtYXRjaGVzO1xuXHR9LFxuXG5cdC8vIGFyZyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxuXHRtYXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGFyZyApIHtcblx0XHR2YXIgbGVuZ3RoLCB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0cmV0ID0gW107XG5cblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgdHJhbnNsYXRpbmcgZWFjaCBvZiB0aGUgaXRlbXMgdG8gdGhlaXIgbmV3IHZhbHVlc1xuXHRcdGlmICggaXNBcnJheUxpa2UoIGVsZW1zICkgKSB7XG5cdFx0XHRsZW5ndGggPSBlbGVtcy5sZW5ndGg7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjayggZWxlbXNbIGkgXSwgaSwgYXJnICk7XG5cblx0XHRcdFx0aWYgKCB2YWx1ZSAhPSBudWxsICkge1xuXHRcdFx0XHRcdHJldC5wdXNoKCB2YWx1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBHbyB0aHJvdWdoIGV2ZXJ5IGtleSBvbiB0aGUgb2JqZWN0LFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3IgKCBpIGluIGVsZW1zICkge1xuXHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTtcblxuXHRcdFx0XHRpZiAoIHZhbHVlICE9IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0LnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBGbGF0dGVuIGFueSBuZXN0ZWQgYXJyYXlzXG5cdFx0cmV0dXJuIGZsYXQoIHJldCApO1xuXHR9LFxuXG5cdC8vIEEgZ2xvYmFsIEdVSUQgY291bnRlciBmb3Igb2JqZWN0c1xuXHRndWlkOiAxLFxuXG5cdC8vIGpRdWVyeS5zdXBwb3J0IGlzIG5vdCB1c2VkIGluIENvcmUgYnV0IG90aGVyIHByb2plY3RzIGF0dGFjaCB0aGVpclxuXHQvLyBwcm9wZXJ0aWVzIHRvIGl0IHNvIGl0IG5lZWRzIHRvIGV4aXN0LlxuXHRzdXBwb3J0OiBzdXBwb3J0XG59ICk7XG5cbmlmICggdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICkge1xuXHRqUXVlcnkuZm5bIFN5bWJvbC5pdGVyYXRvciBdID0gYXJyWyBTeW1ib2wuaXRlcmF0b3IgXTtcbn1cblxuLy8gUG9wdWxhdGUgdGhlIGNsYXNzMnR5cGUgbWFwXG5qUXVlcnkuZWFjaCggXCJCb29sZWFuIE51bWJlciBTdHJpbmcgRnVuY3Rpb24gQXJyYXkgRGF0ZSBSZWdFeHAgT2JqZWN0IEVycm9yIFN5bWJvbFwiLnNwbGl0KCBcIiBcIiApLFxuXHRmdW5jdGlvbiggX2ksIG5hbWUgKSB7XG5cdFx0Y2xhc3MydHlwZVsgXCJbb2JqZWN0IFwiICsgbmFtZSArIFwiXVwiIF0gPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cdH0gKTtcblxuZnVuY3Rpb24gaXNBcnJheUxpa2UoIG9iaiApIHtcblxuXHQvLyBTdXBwb3J0OiByZWFsIGlPUyA4LjIgb25seSAobm90IHJlcHJvZHVjaWJsZSBpbiBzaW11bGF0b3IpXG5cdC8vIGBpbmAgY2hlY2sgdXNlZCB0byBwcmV2ZW50IEpJVCBlcnJvciAoZ2gtMjE0NSlcblx0Ly8gaGFzT3duIGlzbid0IHVzZWQgaGVyZSBkdWUgdG8gZmFsc2UgbmVnYXRpdmVzXG5cdC8vIHJlZ2FyZGluZyBOb2RlbGlzdCBsZW5ndGggaW4gSUVcblx0dmFyIGxlbmd0aCA9ICEhb2JqICYmIFwibGVuZ3RoXCIgaW4gb2JqICYmIG9iai5sZW5ndGgsXG5cdFx0dHlwZSA9IHRvVHlwZSggb2JqICk7XG5cblx0aWYgKCBpc0Z1bmN0aW9uKCBvYmogKSB8fCBpc1dpbmRvdyggb2JqICkgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0cmV0dXJuIHR5cGUgPT09IFwiYXJyYXlcIiB8fCBsZW5ndGggPT09IDAgfHxcblx0XHR0eXBlb2YgbGVuZ3RoID09PSBcIm51bWJlclwiICYmIGxlbmd0aCA+IDAgJiYgKCBsZW5ndGggLSAxICkgaW4gb2JqO1xufVxuXG5cbmZ1bmN0aW9uIG5vZGVOYW1lKCBlbGVtLCBuYW1lICkge1xuXG5cdHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXG59XG52YXIgcG9wID0gYXJyLnBvcDtcblxuXG52YXIgc29ydCA9IGFyci5zb3J0O1xuXG5cbnZhciBzcGxpY2UgPSBhcnIuc3BsaWNlO1xuXG5cbnZhciB3aGl0ZXNwYWNlID0gXCJbXFxcXHgyMFxcXFx0XFxcXHJcXFxcblxcXFxmXVwiO1xuXG5cbnZhciBydHJpbUNTUyA9IG5ldyBSZWdFeHAoXG5cdFwiXlwiICsgd2hpdGVzcGFjZSArIFwiK3woKD86XnxbXlxcXFxcXFxcXSkoPzpcXFxcXFxcXC4pKilcIiArIH
1doaXRlc3BhY2UgKyBcIiskXCIsXG5cdFwiZ1wiXG4pO1xuXG5cblxuXG4vLyBOb3RlOiBhbiBlbGVtZW50IGRvZXMgbm90IGNvbnRhaW4gaXRzZWxmXG5qUXVlcnkuY29udGFpbnMgPSBmdW5jdGlvbiggYSwgYiApIHtcblx0dmFyIGJ1cCA9IGIgJiYgYi5wYXJlbnROb2RlO1xuXG5cdHJldHVybiBhID09PSBidXAgfHwgISEoIGJ1cCAmJiBidXAubm9kZVR5cGUgPT09IDEgJiYgKFxuXG5cdFx0Ly8gU3VwcG9ydDogSUUgOSAtIDExK1xuXHRcdC8vIElFIGRvZXNuJ3QgaGF2ZSBgY29udGFpbnNgIG9uIFNWRy5cblx0XHRhLmNvbnRhaW5zID9cblx0XHRcdGEuY29udGFpbnMoIGJ1cCApIDpcblx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gJiYgYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYnVwICkgJiAxNlxuXHQpICk7XG59O1xuXG5cblxuXG4vLyBDU1Mgc3RyaW5nL2lkZW50aWZpZXIgc2VyaWFsaXphdGlvblxuLy8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNjb21tb24tc2VyaWFsaXppbmctaWRpb21zXG52YXIgcmNzc2VzY2FwZSA9IC8oW1xcMC1cXHgxZlxceDdmXXxeLT9cXGQpfF4tJHxbXlxceDgwLVxcdUZGRkZcXHctXS9nO1xuXG5mdW5jdGlvbiBmY3NzZXNjYXBlKCBjaCwgYXNDb2RlUG9pbnQgKSB7XG5cdGlmICggYXNDb2RlUG9pbnQgKSB7XG5cblx0XHQvLyBVKzAwMDAgTlVMTCBiZWNvbWVzIFUrRkZGRCBSRVBMQUNFTUVOVCBDSEFSQUNURVJcblx0XHRpZiAoIGNoID09PSBcIlxcMFwiICkge1xuXHRcdFx0cmV0dXJuIFwiXFx1RkZGRFwiO1xuXHRcdH1cblxuXHRcdC8vIENvbnRyb2wgY2hhcmFjdGVycyBhbmQgKGRlcGVuZGVudCB1cG9uIHBvc2l0aW9uKSBudW1iZXJzIGdldCBlc2NhcGVkIGFzIGNvZGUgcG9pbnRzXG5cdFx0cmV0dXJuIGNoLnNsaWNlKCAwLCAtMSApICsgXCJcXFxcXCIgKyBjaC5jaGFyQ29kZUF0KCBjaC5sZW5ndGggLSAxICkudG9TdHJpbmcoIDE2ICkgKyBcIiBcIjtcblx0fVxuXG5cdC8vIE90aGVyIHBvdGVudGlhbGx5LXNwZWNpYWwgQVNDSUkgY2hhcmFjdGVycyBnZXQgYmFja3NsYXNoLWVzY2FwZWRcblx0cmV0dXJuIFwiXFxcXFwiICsgY2g7XG59XG5cbmpRdWVyeS5lc2NhcGVTZWxlY3RvciA9IGZ1bmN0aW9uKCBzZWwgKSB7XG5cdHJldHVybiAoIHNlbCArIFwiXCIgKS5yZXBsYWNlKCByY3NzZXNjYXBlLCBmY3NzZXNjYXBlICk7XG59O1xuXG5cblxuXG52YXIgcHJlZmVycmVkRG9jID0gZG9jdW1lbnQsXG5cdHB1c2hOYXRpdmUgPSBwdXNoO1xuXG4oIGZ1bmN0aW9uKCkge1xuXG52YXIgaSxcblx0RXhwcixcblx0b3V0ZXJtb3N0Q29udGV4dCxcblx0c29ydElucHV0LFxuXHRoYXNEdXBsaWNhdGUsXG5cdHB1c2ggPSBwdXNoTmF0aXZlLFxuXG5cdC8vIExvY2FsIGRvY3VtZW50IHZhcnNcblx0ZG9jdW1lbnQsXG5cdGRvY3VtZW50RWxlbWVudCxcblx0ZG9jdW1lbnRJc0hUTUwsXG5cdHJidWdneVFTQSxcblx0bWF0Y2hlcyxcblxuXHQvLyBJbnN0YW5jZS1zcGVjaWZpYyBkYXRhXG5cdGV4cGFuZG8gPSBqUXVlcnkuZXhwYW5kbyxcblx0ZGlycnVucyA9IDAsXG5cdGRvbmUgPSAwLFxuXHRjbGFzc0NhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0dG9rZW5DYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdGNvbXBpbGVyQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRub25uYXRpdmVTZWxlY3RvckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0c29ydE9yZGVyID0gZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH0sXG5cblx0Ym9vbGVhbnMgPSBcImNoZWNrZWR8c2VsZWN0ZWR8YXN5bmN8YXV0b2ZvY3VzfGF1dG9wbGF5fGNvbnRyb2xzfGRlZmVyfGRpc2FibGVkfGhpZGRlbnxpc21hcHxcIiArXG5cdFx0XCJsb29wfG11bHRpcGxlfG9wZW58cmVhZG9ubHl8cmVxdWlyZWR8c2NvcGVkXCIsXG5cblx0Ly8gUmVndWxhciBleHByZXNzaW9uc1xuXG5cdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9jc3Mtc3ludGF4LTMvI2lkZW50LXRva2VuLWRpYWdyYW1cblx0aWRlbnRpZmllciA9IFwiKD86XFxcXFxcXFxbXFxcXGRhLWZBLUZdezEsNn1cIiArIHdoaXRlc3BhY2UgK1xuXHRcdFwiP3xcXFxcXFxcXFteXFxcXHJcXFxcblxcXFxmXXxbXF
1xcXHctXXxbXlxcMC1cXFxceDdmXSkrXCIsXG5cblx0Ly8gQXR0cmlidXRlIHNlbGVjdG9yczogaHR0cHM6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jYXR0cmlidXRlLXNlbGVjdG9yc1xuXHRhdHRyaWJ1dGVzID0gXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKihcIiArIGlkZW50aWZpZXIgKyBcIikoPzpcIiArIHdoaXRlc3BhY2UgK1xuXG5cdFx0Ly8gT3BlcmF0b3IgKGNhcHR1cmUgMilcblx0XHRcIiooWypeJHwhfl0/PSlcIiArIHdoaXRlc3BhY2UgK1xuXG5cdFx0Ly8gXCJBdHRyaWJ1dGUgdmFsdWVzIG11c3QgYmUgQ1NTIGlkZW50aWZpZXJzIFtjYXB0dXJlIDVdIG9yIHN0cmluZ3MgW2NhcHR1cmUgMyBvciBjYXB0dXJlIDRdXCJcblx0XHRcIiooPzonKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcJ10pKiknfFxcXCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFxcXFwiXSkqKVxcXCJ8KFwiICsgaWRlbnRpZmllciArIFwiKSl8KVwiICtcblx0XHR3aGl0ZXNwYWNlICsgXCIqXFxcXF1cIixcblxuXHRwc2V1ZG9zID0gXCI6KFwiICsgaWRlbnRpZmllciArIFwiKSg/OlxcXFwoKFwiICtcblxuXHRcdC8vIFRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHNlbGVjdG9ycyBuZWVkaW5nIHRva2VuaXplIGluIHRoZSBwcmVGaWx0ZXIsIHByZWZlciBhcmd1bWVudHM6XG5cdFx0Ly8gMS4gcXVvdGVkIChjYXB0dXJlIDM7IGNhcHR1cmUgNCBvciBjYXB0dXJlIDUpXG5cdFx0XCIoJygoPzpcXFxcXFxcXC58W15cXFxcXFxcXCddKSopJ3xcXFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcXFxcIl0pKilcXFwiKXxcIiArXG5cblx0XHQvLyAyLiBzaW1wbGUgKGNhcHR1cmUgNilcblx0XHRcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXCgpW1xcXFxdXXxcIiArIGF0dHJpYnV0ZXMgKyBcIikqKXxcIiArXG5cblx0XHQvLyAzLiBhbnl0aGluZyBlbHNlIChjYXB0dXJlIDIpXG5cdFx0XCIuKlwiICtcblx0XHRcIilcXFxcKXwpXCIsXG5cblx0Ly8gTGVhZGluZyBhbmQgbm9uLWVzY2FwZWQgdHJhaWxpbmcgd2hpdGVzcGFjZSwgY2FwdHVyaW5nIHNvbWUgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVycyBwcmVjZWRpbmcgdGhlIGxhdHRlclxuXHRyd2hpdGVzcGFjZSA9IG5ldyBSZWdFeHAoIHdoaXRlc3BhY2UgKyBcIitcIiwgXCJnXCIgKSxcblxuXHRyY29tbWEgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiosXCIgKyB3aGl0ZXNwYWNlICsgXCIqXCIgKSxcblx0cmxlYWRpbmdDb21iaW5hdG9yID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFs+K35dfFwiICsgd2hpdGVzcGFjZSArIFwiKVwiICtcblx0XHR3aGl0ZXNwYWNlICsgXCIqXCIgKSxcblx0cmRlc2NlbmQgPSBuZXcgUmVnRXhwKCB3aGl0ZXNwYWNlICsgXCJ8PlwiICksXG5cblx0cnBzZXVkbyA9IG5ldyBSZWdFeHAoIHBzZXVkb3MgKSxcblx0cmlkZW50aWZpZXIgPSBuZXcgUmVnRXhwKCBcIl5cIiArIGlkZW50aWZpZXIgKyBcIiRcIiApLFxuXG5cdG1hdGNoRXhwciA9IHtcblx0XHRJRDogbmV3IFJlZ0V4cCggXCJeIyhcIiArIGlkZW50aWZpZXIgKyBcIilcIiApLFxuXHRcdENMQVNTOiBuZXcgUmVnRXhwKCBcIl5cXFxcLihcIiArIGlkZW50aWZpZXIgKyBcIilcIiApLFxuXHRcdFRBRzogbmV3IFJlZ0V4cCggXCJeKFwiICsgaWRlbnRpZmllciArIFwifFsqXSlcIiApLFxuXHRcdEFUVFI6IG5ldyBSZWdFeHAoIFwiXlwiICsgYXR0cmlidXRlcyApLFxuXHRcdFBTRVVETzogbmV3IFJlZ0V4cCggXCJeXCIgKyBwc2V1ZG9zICksXG5cdFx0Q0hJTEQ6IG5ldyBSZWdFeHAoXG5cdFx0XHRcIl46KG9ubHl8Zmlyc3R8bGFzdHxudGh8bnRoLWxhc3QpLShjaGlsZHxvZi10eXBlKSg/OlxcXFwoXCIgK1xuXHRcdFx0XHR3aGl0ZXNwYWNlICsgXCIqKGV2ZW58b2RkfCgoWystXXwpKFxcXFxkKilufClcIiArIHdoaXRlc3BhY2UgKyBcIiooPzooWystXXwpXCIgK1xuXHRcdFx0XHR3aGl0ZXNwYWNlICsgXCIqKFxcXFxkKyl8KSlcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpXCIsIFwiaVwiICksXG5cdFx0Ym9vbDogbmV3IFJlZ0V4cCggXCJeKD86XCIgKyBib29sZWFucyArIFwiKSRcIiwgXCJpXCIgKSxcblxuXHRcdC8vIEZvciB1c2UgaW4gbGlicmFyaWVzIGltcGxlbWVudGluZyAuaXMoKVxuXHRcdC8vIFdlIHVzZSB0aGlzIGZvciBQT1MgbWF0Y2hpbmcgaW4gYHNlbGVjdGBcblx0XHRuZWVkc0NvbnRleHQ6IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArXG5cdFx0XHRcIipbPit+XXw6KGV2ZW58b2RkfGVxfGd0fGx0fG50aHxmaXJzdHxsYXN0KSg/OlxcXFwoXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFwiKigoPzotXFxcXGQpP1xcXFxkKilcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpKD89W14tXXwkKVwiLCBcImlcIiApXG5cdH0sXG5cblx0cmlucHV0cyA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksXG5cdHJoZWFkZXIgPSAvXmhcXGQkL2ksXG5cblx0Ly8gRWFzaWx5LXBhcnNlYWJsZS9yZXRyaWV2YWJsZSBJRCBvciBUQUcgb3IgQ0xBU1Mgc2VsZWN0b3JzXG5cdHJxdWlja0V4cHIgPSAvXig/OiMoW1xcdy1dKyl8KFxcdyspfFxcLihbXFx3LV0rKSkkLyxcblxuXHRyc2libGluZyA9IC9bK35dLyxcblxuXHQvLyBDU1MgZXNjYXBlc1xuXHQvLyBodHRwczovL3d3dy53My5vcmcvVFIvQ1NTMjEvc3luZGF0YS5odG1sI2VzY2FwZWQtY2hhcmFjdGVyc1xuXHRydW5lc2NhcGUgPSBuZXcgUmVnRXhwKCBcIlxcXFxcXFxcW1xcXFxkYS1mQS1GXXsxLDZ9XCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcIj98XFxcXFxcXFwoW15cXFxcclxcXFxuXFxcXGZdKVwiLCBcImdcIiApLFxuXHRmdW5lc2NhcGUgPSBmdW5jdGlvbiggZXNjYXBlLCBub25IZXggKSB7XG5cdFx0dmFyIGhpZ2ggPSBcIjB4XCIgKyBlc2NhcGUuc2xpY2UoIDEgKSAtIDB4MTAwMDA7XG5cblx0XHRpZiAoIG5vbkhleCApIHtcblxuXHRcdFx0Ly8gU3RyaXAgdGhlIGJhY2tzbGFzaCBwcmVmaXggZnJvbSBhIG5vbi1oZXggZXNjYXBlIHNlcXVlbmNlXG5cdFx0XHRyZXR1cm4gbm9uSGV4O1xuXHRcdH1cblxuXHRcdC8vIFJlcGxhY2UgYSBoZXhhZGVjaW1hbCBlc2NhcGUgc2VxdWVuY2Ugd2l0aCB0aGUgZW5jb2RlZCBVbmljb2RlIGNvZGUgcG9pbnRcblx0XHQvLyBTdXBwb3J0OiBJRSA8PTExK1xuXHRcdC8vIEZvciB2YWx1ZXMgb3V0c2lkZSB0aGUgQmFzaWMgTXVsdGlsaW5ndWFsIFBsYW5lIChCTVApLCBtYW51YWxseSBjb25zdHJ1Y3QgYVxuXHRcdC8vIHN1cnJvZ2F0ZSBwYWlyXG5cdFx0cmV0dXJuIGhpZ2ggPCAwID9cblx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggKyAweDEwMDAwICkgOlxuXHRcdFx0U3RyaW5nLmZyb21DaGFyQ29kZSggaGlnaCA+PiAxMCB8IDB4RDgwMCwgaGlnaCAmIDB4M0ZGIHwgMHhEQzAwICk7XG5cdH0sXG5cblx0Ly8gVXNlZCBmb3IgaWZyYW1lczsgc2VlIGBzZXREb2N1bWVudGAuXG5cdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSssIEVkZ2UgMTIgLSAxOCtcblx0Ly8gUmVtb3ZpbmcgdGhlIGZ1bmN0aW9uIHdyYXBwZXIgY2F1c2VzIGEgXCJQZXJtaXNzaW9uIERlbmllZFwiXG5cdC8vIGVycm9yIGluIElFL0VkZ2UuXG5cdHVubG9hZEhhbmRsZXIgPSBmdW5jdGlvbigpIHtcblx0XHRzZXREb2N1bWVudCgpO1xuXHR9LFxuXG5cdGluRGlzYWJsZWRGaWVsZHNldCA9IGFkZENvbWJpbmF0b3IoXG5cdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gdHJ1ZSAmJiBub2RlTmFtZSggZWxlbSwgXCJmaWVsZHNldFwiICk7XG5cdFx0fSxcblx0XHR7IGRpcjogXCJwYXJlbnROb2RlXCIsIG5leHQ6IFwibGVnZW5kXCIgfVxuXHQpO1xuXG4vLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuLy8gQWNjZXNzaW5nIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgY2FuIHRocm93IHVuZXhwZWN0ZWRseVxuLy8gaH
1R0cHM6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzkzXG5mdW5jdGlvbiBzYWZlQWN0aXZlRWxlbWVudCgpIHtcblx0dHJ5IHtcblx0XHRyZXR1cm4gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcblx0fSBjYXRjaCAoIGVyciApIHsgfVxufVxuXG4vLyBPcHRpbWl6ZSBmb3IgcHVzaC5hcHBseSggXywgTm9kZUxpc3QgKVxudHJ5IHtcblx0cHVzaC5hcHBseShcblx0XHQoIGFyciA9IHNsaWNlLmNhbGwoIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzICkgKSxcblx0XHRwcmVmZXJyZWREb2MuY2hpbGROb2Rlc1xuXHQpO1xuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjBcblx0Ly8gRGV0ZWN0IHNpbGVudGx5IGZhaWxpbmcgcHVzaC5hcHBseVxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG5cdGFyclsgcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMubGVuZ3RoIF0ubm9kZVR5cGU7XG59IGNhdGNoICggZSApIHtcblx0cHVzaCA9IHtcblx0XHRhcHBseTogZnVuY3Rpb24oIHRhcmdldCwgZWxzICkge1xuXHRcdFx0cHVzaE5hdGl2ZS5hcHBseSggdGFyZ2V0LCBzbGljZS5jYWxsKCBlbHMgKSApO1xuXHRcdH0sXG5cdFx0Y2FsbDogZnVuY3Rpb24oIHRhcmdldCApIHtcblx0XHRcdHB1c2hOYXRpdmUuYXBwbHkoIHRhcmdldCwgc2xpY2UuY2FsbCggYXJndW1lbnRzLCAxICkgKTtcblx0XHR9XG5cdH07XG59XG5cbmZ1bmN0aW9uIGZpbmQoIHNlbGVjdG9yLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICkge1xuXHR2YXIgbSwgaSwgZWxlbSwgbmlkLCBtYXRjaCwgZ3JvdXBzLCBuZXdTZWxlY3Rvcixcblx0XHRuZXdDb250ZXh0ID0gY29udGV4dCAmJiBjb250ZXh0Lm93bmVyRG9jdW1lbnQsXG5cblx0XHQvLyBub2RlVHlwZSBkZWZhdWx0cyB0byA5LCBzaW5jZSBjb250ZXh0IGRlZmF1bHRzIHRvIGRvY3VtZW50XG5cdFx0bm9kZVR5cGUgPSBjb250ZXh0ID8gY29udGV4dC5ub2RlVHlwZSA6IDk7XG5cblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XG5cblx0Ly8gUmV0dXJuIGVhcmx5IGZyb20gY2FsbHMgd2l0aCBpbnZhbGlkIHNlbGVjdG9yIG9yIGNvbnRleHRcblx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09IFwic3RyaW5nXCIgfHwgIXNlbGVjdG9yIHx8XG5cdFx0bm9kZVR5cGUgIT09IDEgJiYgbm9kZVR5cGUgIT09IDkgJiYgbm9kZVR5cGUgIT09IDExICkge1xuXG5cdFx0cmV0dXJuIHJlc3VsdHM7XG5cdH1cblxuXHQvLyBUcnkgdG8gc2hvcnRjdXQgZmluZCBvcGVyYXRpb25zIChhcyBvcHBvc2VkIHRvIGZpbHRlcnMpIGluIEhUTUwgZG9jdW1lbnRzXG5cdGlmICggIXNlZWQgKSB7XG5cdFx0c2V0RG9jdW1lbnQoIGNvbnRleHQgKTtcblx0XHRjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcblxuXHRcdGlmICggZG9jdW1lbnRJc0hUTUwgKSB7XG5cblx0XHRcdC8vIElmIHRoZSBzZWxlY3RvciBpcyBzdWZmaWNpZW50bHkgc2ltcGxlLCB0cnkgdXNpbmcgYSBcImdldCpCeSpcIiBET00gbWV0aG9kXG5cdFx0XHQvLyAoZXhjZXB0aW5nIERvY3VtZW50RnJhZ21lbnQgY29udGV4dCwgd2hlcmUgdGhlIG1ldGhvZHMgZG9uJ3QgZXhpc3QpXG5cdFx0XHRpZiAoIG5vZGVUeXBlICE9PSAxMSAmJiAoIG1hdGNoID0gcnF1aWNrRXhwci5leGVjKCBzZWxlY3RvciApICkgKSB7XG5cblx0XHRcdFx0Ly8gSUQgc2VsZWN0b3Jcblx0XHRcdFx0aWYgKCAoIG0gPSBtYXRjaFsgMSBdICkgKSB7XG5cblx0XHRcdFx0XHQvLyBEb2N1bWVudCBjb250ZXh0XG5cdFx0XHRcdFx0aWYgKCBub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRcdGlmICggKCBlbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggbSApICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgOSBvbmx5XG5cdFx0XHRcdFx0XHRcdC8vIGdldEVsZW1lbnRCeUlkIGNhbiBtYXRjaCBlbGVtZW50cyBieSBuYW1lIGluc3RlYWQgb2YgSURcblx0XHRcdFx0XHRcdFx0aWYgKCBlbGVtLmlkID09PSBtICkge1xuXHRcdFx0XHRcdFx0XHRcdHB1c2guY2FsbCggcmVzdWx0cywgZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIEVsZW1lbnQgY29udGV4dFxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDkgb25seVxuXHRcdFx0XHRcdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgY2FuIG1hdGNoIGVsZW1lbnRzIGJ5IG5hbWUgaW5zdGVhZCBvZiBJRFxuXHRcdFx0XHRcdFx0aWYgKCBuZXdDb250ZXh0ICYmICggZWxlbSA9IG5ld0NvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSApICYmXG5cdFx0XHRcdFx0XHRcdGZpbmQuY29udGFpbnMoIGNvbnRleHQsIGVsZW0gKSAmJlxuXHRcdFx0XHRcdFx0XHRlbGVtLmlkID09PSBtICkge1xuXG5cdFx0XHRcdFx0XHRcdHB1c2guY2FsbCggcmVzdWx0cywgZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gVHlwZSBzZWxlY3RvclxuXHRcdFx0XHR9IGVsc2UgaWYgKCBtYXRjaFsgMiBdICkge1xuXHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHNlbGVjdG9yICkgKTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0XHQvLyBDbGFzcyBzZWxlY3RvclxuXHRcdFx0XHR9IGVsc2UgaWYgKCAoIG0gPSBtYXRjaFsgMyBdICkgJiYgY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICkge1xuXHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggbSApICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gVGFrZSBhZHZhbnRhZ2Ugb2YgcXVlcnlTZWxlY3RvckFsbFxuXHRcdFx0aWYgKCAhbm9ubmF0aXZlU2VsZWN0b3JDYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdICYmXG5cdFx0XHRcdCggIXJidWdneVFTQSB8fCAhcmJ1Z2d5UVNBLnRlc3QoIHNlbGVjdG9yICkgKSApIHtcblxuXHRcdFx0XHRuZXdTZWxlY3RvciA9IHNlbGVjdG9yO1xuXHRcdFx0XHRuZXdDb250ZXh0ID0gY29udGV4dDtcblxuXHRcdFx0XHQvLyBxU0EgY29uc2lkZXJzIGVsZW1lbnRzIG91dHNpZGUgYSBzY29waW5nIHJvb3Qgd2hlbiBldmFsdWF0aW5nIGNoaWxkIG9yXG5cdFx0XHRcdC8vIGRlc2NlbmRhbnQgY29tYmluYXRvcnMsIHd
1oaWNoIGlzIG5vdCB3aGF0IHdlIHdhbnQuXG5cdFx0XHRcdC8vIEluIHN1Y2ggY2FzZXMsIHdlIHdvcmsgYXJvdW5kIHRoZSBiZWhhdmlvciBieSBwcmVmaXhpbmcgZXZlcnkgc2VsZWN0b3IgaW4gdGhlXG5cdFx0XHRcdC8vIGxpc3Qgd2l0aCBhbiBJRCBzZWxlY3RvciByZWZlcmVuY2luZyB0aGUgc2NvcGUgY29udGV4dC5cblx0XHRcdFx0Ly8gVGhlIHRlY2huaXF1ZSBoYXMgdG8gYmUgdXNlZCBhcyB3ZWxsIHdoZW4gYSBsZWFkaW5nIGNvbWJpbmF0b3IgaXMgdXNlZFxuXHRcdFx0XHQvLyBhcyBzdWNoIHNlbGVjdG9ycyBhcmUgbm90IHJlY29nbml6ZWQgYnkgcXVlcnlTZWxlY3RvckFsbC5cblx0XHRcdFx0Ly8gVGhhbmtzIHRvIEFuZHJldyBEdXBvbnQgZm9yIHRoaXMgdGVjaG5pcXVlLlxuXHRcdFx0XHRpZiAoIG5vZGVUeXBlID09PSAxICYmXG5cdFx0XHRcdFx0KCByZGVzY2VuZC50ZXN0KCBzZWxlY3RvciApIHx8IHJsZWFkaW5nQ29tYmluYXRvci50ZXN0KCBzZWxlY3RvciApICkgKSB7XG5cblx0XHRcdFx0XHQvLyBFeHBhbmQgY29udGV4dCBmb3Igc2libGluZyBzZWxlY3RvcnNcblx0XHRcdFx0XHRuZXdDb250ZXh0ID0gcnNpYmxpbmcudGVzdCggc2VsZWN0b3IgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHxcblx0XHRcdFx0XHRcdGNvbnRleHQ7XG5cblx0XHRcdFx0XHQvLyBXZSBjYW4gdXNlIDpzY29wZSBpbnN0ZWFkIG9mIHRoZSBJRCBoYWNrIGlmIHRoZSBicm93c2VyXG5cdFx0XHRcdFx0Ly8gc3VwcG9ydHMgaXQgJiBpZiB3ZSdyZSBub3QgY2hhbmdpbmcgdGhlIGNvbnRleHQuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0XHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlblxuXHRcdFx0XHRcdC8vIHN0cmljdC1jb21wYXJpbmcgdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRcdFx0XHRpZiAoIG5ld0NvbnRleHQgIT0gY29udGV4dCB8fCAhc3VwcG9ydC5zY29wZSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gQ2FwdHVyZSB0aGUgY29udGV4dCBJRCwgc2V0dGluZyBpdCBmaXJzdCBpZiBuZWNlc3Nhcnlcblx0XHRcdFx0XHRcdGlmICggKCBuaWQgPSBjb250ZXh0LmdldEF0dHJpYnV0ZSggXCJpZFwiICkgKSApIHtcblx0XHRcdFx0XHRcdFx0bmlkID0galF1ZXJ5LmVzY2FwZVNlbGVjdG9yKCBuaWQgKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGNvbnRleHQuc2V0QXR0cmlidXRlKCBcImlkXCIsICggbmlkID0gZXhwYW5kbyApICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gUHJlZml4IGV2ZXJ5IHNlbGVjdG9yIGluIHRoZSBsaXN0XG5cdFx0XHRcdFx0Z3JvdXBzID0gdG9rZW5pemUoIHNlbGVjdG9yICk7XG5cdFx0XHRcdFx0aSA9IGdyb3Vwcy5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRncm91cHNbIGkgXSA9ICggbmlkID8gXCIjXCIgKyBuaWQgOiBcIjpzY29wZVwiICkgKyBcIiBcIiArXG5cdFx0XHRcdFx0XHRcdHRvU2VsZWN0b3IoIGdyb3Vwc1sgaSBdICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdG5ld1NlbGVjdG9yID0gZ3JvdXBzLmpvaW4oIFwiLFwiICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsXG5cdFx0XHRcdFx0XHRuZXdDb250ZXh0LnF1
1ZXJ5U2VsZWN0b3JBbGwoIG5ld1NlbGVjdG9yIClcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHR9IGNhdGNoICggcXNhRXJyb3IgKSB7XG5cdFx0XHRcdFx0bm9ubmF0aXZlU2VsZWN0b3JDYWNoZSggc2VsZWN0b3IsIHRydWUgKTtcblx0XHRcdFx0fSBmaW5hbGx5IHtcblx0XHRcdFx0XHRpZiAoIG5pZCA9PT0gZXhwYW5kbyApIHtcblx0XHRcdFx0XHRcdGNvbnRleHQucmVtb3ZlQXR0cmlidXRlKCBcImlkXCIgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBBbGwgb3RoZXJzXG5cdHJldHVybiBzZWxlY3QoIHNlbGVjdG9yLnJlcGxhY2UoIHJ0cmltQ1NTLCBcIiQxXCIgKSwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApO1xufVxuXG4vKipcbiAqIENyZWF0ZSBrZXktdmFsdWUgY2FjaGVzIG9mIGxpbWl0ZWQgc2l6ZVxuICogQHJldHVybnMge2Z1bmN0aW9uKHN0cmluZywgb2JqZWN0KX0gUmV0dXJucyB0aGUgT2JqZWN0IGRhdGEgYWZ0ZXIgc3RvcmluZyBpdCBvbiBpdHNlbGYgd2l0aFxuICpcdHByb3BlcnR5IG5hbWUgdGhlIChzcGFjZS1zdWZmaXhlZCkgc3RyaW5nIGFuZCAoaWYgdGhlIGNhY2hlIGlzIGxhcmdlciB0aGFuIEV4cHIuY2FjaGVMZW5ndGgpXG4gKlx0ZGVsZXRpbmcgdGhlIG9sZGVzdCBlbnRyeVxuICovXG5mdW5jdGlvbiBjcmVhdGVDYWNoZSgpIHtcblx0dmFyIGtleXMgPSBbXTtcblxuXHRmdW5jdGlvbiBjYWNoZSgga2V5LCB2YWx1ZSApIHtcblxuXHRcdC8vIFVzZSAoa2V5ICsgXCIgXCIpIHRvIGF2b2lkIGNvbGxpc2lvbiB3aXRoIG5hdGl2ZSBwcm90b3R5cGUgcHJvcGVydGllc1xuXHRcdC8vIChzZWUgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9zaXp6bGUvaXNzdWVzLzE1Nylcblx0XHRpZiAoIGtleXMucHVzaCgga2V5ICsgXCIgXCIgKSA+IEV4cHIuY2FjaGVMZW5ndGggKSB7XG5cblx0XHRcdC8vIE9ubHkga2VlcCB0aGUgbW9zdCByZWNlbnQgZW50cmllc1xuXHRcdFx0ZGVsZXRlIGNhY2hlWyBrZXlzLnNoaWZ0KCkgXTtcblx0XHR9XG5cdFx0cmV0dXJuICggY2FjaGVbIGtleSArIFwiIFwiIF0gPSB2YWx1ZSApO1xuXHR9XG5cdHJldHVybiBjYWNoZTtcbn1cblxuLyoqXG4gKiBNYXJrIGEgZnVuY3Rpb24gZm9yIHNwZWNpYWwgdXNlIGJ5IGpRdWVyeSBzZWxlY3RvciBtb2R1bGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBtYXJrXG4gKi9cbmZ1bmN0aW9uIG1hcmtGdW5jdGlvbiggZm4gKSB7XG5cdGZuWyBleHBhbmRvIF0gPSB0cnVlO1xuXHRyZXR1cm4gZm47XG59XG5cbi8qKlxuICogU3VwcG9ydCB0ZXN0aW5nIHVzaW5nIGFuIGVsZW1lbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFBhc3NlZCB0aGUgY3JlYXRlZCBlbGVtZW50IGFuZCByZXR1cm5zIGEgYm9vbGVhbiByZXN1bHRcbiAqL1xuZnVuY3Rpb24gYXNzZXJ0KCBmbiApIHtcblx0dmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJmaWVsZHNldFwiICk7XG5cblx0dHJ5IHtcblx0XHRyZXR1cm4gISFmbiggZWwgKTtcblx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9IGZpbmFsbHkge1xuXG5cdFx0Ly8gUmVtb3ZlIGZyb20gaXRzIHBhcmVudCBieSBkZWZhdWx0XG5cdFx0aWYgKCBlbC5wYXJlbnROb2RlICkge1xuXHRcdFx0ZWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggZWwgKTtcblx0XHR9XG5cblx0XHQvLyByZWxlYXNlIG1lbW9yeSBpbiBJRVxuXHRcdGVsID0gbnVsbDtcblx0fVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgaW5wdXQgdHlwZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlucHV0UHNldWRvKCB0eXBlICkge1xuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIG5vZGVOYW1lKCBlbGVtLCBcImlucHV0XCIgKSAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBidXR0b25zXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICovXG5mdW5jdGlvbiBjcmVhdGVCdXR0b25Qc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gKCBub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgfHwgbm9kZU5hbWUoIGVsZW0sIFwiYnV0dG9uXCIgKSApICYmXG5cdFx0XHRlbGVtLnR5cGUgPT09IHR5cGU7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciA6ZW5hYmxlZC86ZGlzYWJsZWRcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZGlzYWJsZWQgdHJ1ZSBmb3IgOmRpc2FibGVkOyBmYWxzZSBmb3IgOmVuYWJsZWRcbiAqL1xuZnVuY3Rpb24gY3JlYXRlRGlzYWJsZWRQc2V1ZG8oIGRpc2FibGVkICkge1xuXG5cdC8vIEtub3duIDpkaXNhYmxlZCBmYWxzZSBwb3NpdGl2ZXM6IGZpZWxkc2V0W2Rpc2FibGVkXSA+IGxlZ2VuZDpudGgtb2YtdHlwZShuKzIpIDpjYW4tZGlzYWJsZVxuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHQvLyBPbmx5IGNlcnRhaW4gZWxlbWVudHMgY2FuIG1hdGNoIDplbmFibGVkIG9yIDpkaXNhYmxlZFxuXHRcdC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3NjcmlwdGluZy5odG1sI3NlbGVjdG9yLWVuYWJsZWRcblx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zY3JpcHRpbmcuaHRtbCNzZWxlY3Rvci1kaXNhYmxlZFxuXHRcdGlmICggXCJmb3JtXCIgaW4gZWxlbSApIHtcblxuXHRcdFx0Ly8gQ2hlY2sgZm9yIGluaGVyaXRlZCBkaXNhYmxlZG5lc3Mgb24gcmVsZXZhbnQgbm9uLWRpc2FibGVkIGVsZW1lbnRzOlxuXHRcdFx0Ly8gKiBsaXN0ZWQgZm9ybS1hc3NvY2lhdGVkIGVsZW1lbnRzIGluIGEgZGlzYWJsZWQgZmllbGRzZXRcblx0XHRcdC8vICAgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZm9ybXMuaHRtbCNjYXRlZ29yeS1saXN0ZWRcblx0XHRcdC8vICAgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZm9ybXMuaHRtbCNjb25jZXB0LWZlLWRpc2FibGVkXG5cdFx0XHQvLyAqIG9wdGlvbiBlbGVtZW50cyBpbiBhIGRpc2FibGVkIG9wdGdyb3VwXG5cdFx0XHQvLyAgIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Zvcm1zLmh0bWwjY29uY2VwdC1vcHRpb24tZGlzYWJsZWRcblx0XHRcdC8vIEFsbCBzdWNoIGVsZW1lbnRzIGhhdmUgYSBcImZvcm1cIiBwcm9wZXJ0eS5cblx0XHRcdGlmICggZWxlbS5wYXJlbnROb2RlICYmIGVsZW0uZGlzYWJsZWQgPT09IGZhbHNlICkge1xuXG5cdFx0XHRcdC8vIE9wdGlvbiBlbGVtZW50cyBkZWZlciB0byBhIHBhcmVudCBvcHRncm91cCBpZiBwcmVzZW50XG5cdFx0XHRcdGlmICggXCJsYWJlbFwiIGluIGVsZW0gKSB7XG5cdFx0XHRcdFx0aWYgKCBcImxhYmVsXCIgaW4gZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVsZW0ucGFyZW50Tm9kZS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHJldHVybi
1BlbGVtLmRpc2FibGVkID09PSBkaXNhYmxlZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA2IC0gMTErXG5cdFx0XHRcdC8vIFVzZSB0aGUgaXNEaXNhYmxlZCBzaG9ydGN1dCBwcm9wZXJ0eSB0byBjaGVjayBmb3IgZGlzYWJsZWQgZmllbGRzZXQgYW5jZXN0b3JzXG5cdFx0XHRcdHJldHVybiBlbGVtLmlzRGlzYWJsZWQgPT09IGRpc2FibGVkIHx8XG5cblx0XHRcdFx0XHQvLyBXaGVyZSB0aGVyZSBpcyBubyBpc0Rpc2FibGVkLCBjaGVjayBtYW51YWxseVxuXHRcdFx0XHRcdGVsZW0uaXNEaXNhYmxlZCAhPT0gIWRpc2FibGVkICYmXG5cdFx0XHRcdFx0XHRpbkRpc2FibGVkRmllbGRzZXQoIGVsZW0gKSA9PT0gZGlzYWJsZWQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBkaXNhYmxlZDtcblxuXHRcdC8vIFRyeSB0byB3aW5ub3cgb3V0IGVsZW1lbnRzIHRoYXQgY2FuJ3QgYmUgZGlzYWJsZWQgYmVmb3JlIHRydXN0aW5nIHRoZSBkaXNhYmxlZCBwcm9wZXJ0eS5cblx0XHQvLyBTb21lIHZpY3RpbXMgZ2V0IGNhdWdodCBpbiBvdXIgbmV0IChsYWJlbCwgbGVnZW5kLCBtZW51LCB0cmFjayksIGJ1dCBpdCBzaG91bGRuJ3Rcblx0XHQvLyBldmVuIGV4aXN0IG9uIHRoZW0sIGxldCBhbG9uZSBoYXZlIGEgYm9vbGVhbiB2YWx1ZS5cblx0XHR9IGVsc2UgaWYgKCBcImxhYmVsXCIgaW4gZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBkaXNhYmxlZDtcblx0XHR9XG5cblx0XHQvLyBSZW1haW5pbmcgZWxlbWVudHMgYXJlIG5laXRoZXIgOmVuYWJsZWQgbm9yIDpkaXNhYmxlZFxuXHRcdHJldHVybiBmYWxzZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIHBvc2l0aW9uYWxzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICovXG5mdW5jdGlvbiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmbiApIHtcblx0cmV0dXJuIG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGFyZ3VtZW50ICkge1xuXHRcdGFyZ3VtZW50ID0gK2FyZ3VtZW50O1xuXHRcdHJldHVybiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWVkLCBtYXRjaGVzICkge1xuXHRcdFx0dmFyIGosXG5cdFx0XHRcdG1hdGNoSW5kZXhlcyA9IGZuKCBbXSwgc2VlZC5sZW5ndGgsIGFyZ3VtZW50ICksXG5cdFx0XHRcdGkgPSBtYXRjaEluZGV4ZXMubGVuZ3RoO1xuXG5cdFx0XHQvLyBNYXRjaCBlbGVtZW50cyBmb3VuZCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4ZXNcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRpZiAoIHNlZWRbICggaiA9IG1hdGNoSW5kZXhlc1sgaSBdICkgXSApIHtcblx0XHRcdFx0XHRzZWVkWyBqIF0gPSAhKCBtYXRjaGVzWyBqIF0gPSBzZWVkWyBqIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSApO1xufVxuXG4vKipcbiAqIENoZWNrcyBhIG5vZGUgZm9yIHZhbGlkaXR5IGFzIGEgalF1ZXJ5IHNlbGVjdG9yIGNvbnRleHRcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3Q9fSBjb250ZXh0XG4gKiBAcmV0dXJucyB7RWxlbWVudHxPYmplY3R8Qm9vbGVhbn0gVGhlIGlucHV0IG5vZGUgaWYgYWNjZXB0YWJsZSwgb3RoZXJ3aXNlIGEgZmFsc3kgdmFsdWVcbiAqL1xuZnVuY3Rpb24gdGVzdENvbnRleHQoIGNvbnRleHQgKSB7XG5cdHJldHVybiBjb250ZXh0ICYmIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBcInVuZGVmaW5lZFwiICYmIGNvbnRleHQ7XG59XG5cbi8qKlxuICogU2V0cyBkb2N1bWVudC1yZWxhdGVkIHZhcmlhYmxlcyBvbmNlIGJhc2VkIG9uIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0fSBbbm9kZV0gQW4gZWxlbWVudCBvciBkb2N1bWVudCBvYmplY3QgdG8gdXNlIHRvIHNldCB0aGUgZG9jdW1lbnRcbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGN1cnJlbnQgZG9jdW1lbnRcbiAqL1xuZnVuY3Rpb24gc2V0RG9jdW1lbnQoIG5vZGUgKSB7XG5cdHZhciBzdWJXaW5kb3csXG5cdFx0ZG9jID0gbm9kZSA/IG5vZGUub3duZXJEb2N1bWVudCB8fCBub2RlIDogcHJlZmVycmVkRG9jO1xuXG5cdC8vIFJldHVybiBlYXJseSBpZiBkb2MgaXMgaW52YWxpZCBvciBhbHJlYWR5IHNlbGVjdGVkXG5cdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdGlmICggZG9jID09IGRvY3VtZW50IHx8IGRvYy5ub2RlVHlwZSAhPT0gOSB8fCAhZG9jLmRvY3VtZW50RWxlbWVudCApIHtcblx0XHRyZXR1cm4gZG9jdW1lbnQ7XG5cdH1cblxuXHQvLyBVcGRhdGUgZ2xvYmFsIHZhcmlhYmxlc1xuXHRkb2N1bWVudCA9IGRvYztcblx0ZG9jdW1lbnRFbGVtZW50ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXHRkb2N1bWVudElzSFRNTCA9ICFqUXVlcnkuaXNYTUxEb2MoIGRvY3VtZW50ICk7XG5cblx0Ly8gU3VwcG9ydDogaU9TIDcgb25seSwgSUUgOSAtIDExK1xuXHQvLyBPbGRlciBicm93c2VycyBkaWRuJ3Qgc3VwcG9ydCB1bnByZWZpeGVkIGBtYXRjaGVzYC5cblx0bWF0Y2hlcyA9IGRvY3VtZW50RWxlbWVudC5tYXRjaGVzIHx8XG5cdFx0ZG9jdW1lbnRFbGVtZW50LndlYmtpdE1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY3VtZW50RWxlbWVudC5tc01hdGNoZXNTZWxlY3RvcjtcblxuXHQvLyBTdXBwb3J0OiBJRSA5IC0gMTErLCBFZGdlIDEyIC0gMTgrXG5cdC8vIEFjY2Vzc2luZyBpZnJhbWUgZG9jdW1lbnRzIGFmdGVyIHVubG9hZCB0aHJvd3MgXCJwZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yc1xuXHQvLyAoc2VlIHRyYWMtMTM5MzYpLlxuXHQvLyBMaW1pdCB0aGUgZml4IHRvIElFICYgRWRnZSBMZWdhY3k7IGRlc3BpdGUgRWRnZSAxNSsgaW1wbGVtZW50aW5nIGBtYXRjaGVzYCxcblx0Ly8gYWxsIElFIDkrIGFuZCBFZGdlIExlZ2FjeSB2ZXJzaW9ucyBpbXBsZW1lbnQgYG1zTWF0Y2hlc1NlbGVjdG9yYCBhcyB3ZWxsLlxuXHRpZiAoIGRvY3VtZW50RWxlbWVudC5t
1c01hdGNoZXNTZWxlY3RvciAmJlxuXG5cdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRwcmVmZXJyZWREb2MgIT0gZG9jdW1lbnQgJiZcblx0XHQoIHN1YldpbmRvdyA9IGRvY3VtZW50LmRlZmF1bHRWaWV3ICkgJiYgc3ViV2luZG93LnRvcCAhPT0gc3ViV2luZG93ICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgOSAtIDExKywgRWRnZSAxMiAtIDE4K1xuXHRcdHN1YldpbmRvdy5hZGRFdmVudExpc3RlbmVyKCBcInVubG9hZFwiLCB1bmxvYWRIYW5kbGVyICk7XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBJRSA8MTBcblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudEJ5SWQgcmV0dXJucyBlbGVtZW50cyBieSBuYW1lXG5cdC8vIFRoZSBicm9rZW4gZ2V0RWxlbWVudEJ5SWQgbWV0aG9kcyBkb24ndCBwaWNrIHVwIHByb2dyYW1tYXRpY2FsbHktc2V0IG5hbWVzLFxuXHQvLyBzbyB1c2UgYSByb3VuZGFib3V0IGdldEVsZW1lbnRzQnlOYW1lIHRlc3Rcblx0c3VwcG9ydC5nZXRCeUlkID0gYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdFx0ZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKCBlbCApLmlkID0galF1ZXJ5LmV4cGFuZG87XG5cdFx0cmV0dXJuICFkb2N1bWVudC5nZXRFbGVtZW50c0J5TmFtZSB8fFxuXHRcdFx0IWRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lKCBqUXVlcnkuZXhwYW5kbyApLmxlbmd0aDtcblx0fSApO1xuXG5cdC8vIFN1cHBvcnQ6IElFIDkgb25seVxuXHQvLyBDaGVjayB0byBzZWUgaWYgaXQncyBwb3NzaWJsZSB0byBkbyBtYXRjaGVzU2VsZWN0b3Jcblx0Ly8gb24gYSBkaXNjb25uZWN0ZWQgbm9kZS5cblx0c3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCA9IGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXHRcdHJldHVybiBtYXRjaGVzLmNhbGwoIGVsLCBcIipcIiApO1xuXHR9ICk7XG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExKywgRWRnZSAxMiAtIDE4K1xuXHQvLyBJRS9FZGdlIGRvbid0IHN1cHBvcnQgdGhlIDpzY29wZSBwc2V1ZG8tY2xhc3MuXG5cdHN1cHBvcnQuc2NvcGUgPSBhc3NlcnQoIGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCBcIjpzY29wZVwiICk7XG5cdH0gKTtcblxuXHQvLyBTdXBwb3J0OiBDaHJvbWUgMTA1IC0gMTExIG9ubHksIFNhZmFyaSAxNS40IC0gMTYuMyBvbmx5XG5cdC8vIE1ha2Ugc3VyZSB0aGUgYDpoYXMoKWAgYXJndW1lbnQgaXMgcGFyc2VkIHVuZm9yZ2l2aW5nbHkuXG5cdC8vIFdlIGluY2x1ZGUgYCpgIGluIHRoZSB0ZXN0IHRvIGRldGVjdCBidWdneSBpbXBsZW1lbnRhdGlvbnMgdGhhdCBhcmVcblx0Ly8gX3NlbGVjdGl2ZWx5XyBmb3JnaXZpbmcgKHNwZWNpZmljYWxseSB3aGVuIHRoZSBsaXN0IGluY2x1ZGVzIGF0IGxlYXN0XG5cdC8vIG9uZSB2YWxpZCBzZWxlY3RvcikuXG5cdC8vIE5vdGUgdGhhdCB3ZSB0cmVhdCBjb21wbGV0ZSBsYWNrIG9mIHN1cHBvcnQgZm9yIGA6aGFzKClgIGFzIGlmIGl0IHdlcmVcblx0Ly8gc3BlYy1jb21wbGlhbnQgc3VwcG9ydCwgd2hpY2ggaXMgZmluZSBiZWNhdXNlIHVzZSBvZiBgOmhhcygpYCBpbiBzdWNoXG5cdC8vIGVudmlyb25tZW50cyB3aWxsIGZhaWwgaW4gdGhlIHFTQSBwYXRoIGFuZCBmYWxsIGJhY2sgdG8galF1ZXJ5IHRyYXZlcnNhbFxuXHQvLyBhbnl3YXkuXG5cdHN1cHBvcnQuY3NzSGFzID0gYXNzZXJ0KCBmdW5jdGlvbigpIHtcblx0XHR0cnkge1xuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvciggXCI6aGFzKCosOmpxZmFrZSlcIiApO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHR9ICk7XG5cblx0Ly8gSUQgZmlsdGVyIGFuZCBmaW5kXG5cdGlmICggc3VwcG9ydC5nZXRCeUlkICkge1xuXHRcdEV4cHIuZmlsdGVyLklEID0gZnVuY3Rpb24oIGlkICkge1xuXHRcdFx0dmFyIGF0dHJJZCA9IGlkLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggXCJpZFwiICkgPT09IGF0dHJJZDtcblx0XHRcdH07XG5cdFx0fTtcblx0XHRFeHByLmZpbmQuSUQgPSBmdW5jdGlvbiggaWQsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSBcInVuZGVmaW5lZFwiICYmIGRvY3VtZW50SXNIVE1MICkge1xuXHRcdFx0XHR2YXIgZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIGlkICk7XG5cdFx0XHRcdHJldHVybiBlbGVtID8gWyBlbGVtIF0gOiBbXTtcblx0XHRcdH1cblx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdEV4cHIuZmlsdGVyLklEID0gIGZ1bmN0aW9uKCBpZCApIHtcblx0XHRcdHZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgbm9kZSA9IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZU5vZGUgIT09IFwidW5kZWZpbmVkXCIgJiZcblx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIFwiaWRcIiApO1xuXHRcdFx0XHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlID09PSBhdHRySWQ7XG5cdFx0XHR9O1xuXHRcdH07XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA2IC0gNyBvbmx5XG5cdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgaXMgbm90IHJlbGlhYmxlIGFzIGEgZmluZCBzaG9ydGN1dFxuXHRcdEV4cHIuZmluZC5JRCA9IGZ1bmN0aW9uKCBpZCwgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRcdHZhciBub2RlLCBpLCBlbGVtcyxcblx0XHRcdFx0XHRlbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTtcblxuXHRcdFx0XHRpZiAoIGVsZW0gKSB7XG5cblx0XHRcdFx0XHQvLyBWZXJpZnkgdGhlIGl
1kIGF0dHJpYnV0ZVxuXHRcdFx0XHRcdG5vZGUgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIFwiaWRcIiApO1xuXHRcdFx0XHRcdGlmICggbm9kZSAmJiBub2RlLnZhbHVlID09PSBpZCApIHtcblx0XHRcdFx0XHRcdHJldHVybiBbIGVsZW0gXTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBGYWxsIGJhY2sgb24gZ2V0RWxlbWVudHNCeU5hbWVcblx0XHRcdFx0XHRlbGVtcyA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeU5hbWUoIGlkICk7XG5cdFx0XHRcdFx0aSA9IDA7XG5cdFx0XHRcdFx0d2hpbGUgKCAoIGVsZW0gPSBlbGVtc1sgaSsrIF0gKSApIHtcblx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIFwiaWRcIiApO1xuXHRcdFx0XHRcdFx0aWYgKCBub2RlICYmIG5vZGUudmFsdWUgPT09IGlkICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gWyBlbGVtIF07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIFtdO1xuXHRcdFx0fVxuXHRcdH07XG5cdH1cblxuXHQvLyBUYWdcblx0RXhwci5maW5kLlRBRyA9IGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XG5cdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRcdHJldHVybiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgKTtcblxuXHRcdC8vIERvY3VtZW50RnJhZ21lbnQgbm9kZXMgZG9uJ3QgaGF2ZSBnRUJUTlxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCB0YWcgKTtcblx0XHR9XG5cdH07XG5cblx0Ly8gQ2xhc3Ncblx0RXhwci5maW5kLkNMQVNTID0gZnVuY3Rpb24oIGNsYXNzTmFtZSwgY29udGV4dCApIHtcblx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBjbGFzc05hbWUgKTtcblx0XHR9XG5cdH07XG5cblx0LyogUVNBL21hdGNoZXNTZWxlY3RvclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gUVNBIGFuZCBtYXRjaGVzU2VsZWN0b3Igc3VwcG9ydFxuXG5cdHJidWdneVFTQSA9IFtdO1xuXG5cdC8vIEJ1aWxkIFFTQSByZWdleFxuXHQvLyBSZWdleCBzdHJhdGVneSBhZG9wdGVkIGZyb20gRGllZ28gUGVyaW5pXG5cdGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXG5cdFx0dmFyIGlucHV0O1xuXG5cdFx0ZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKCBlbCApLmlubmVySFRNTCA9XG5cdFx0XHRcIjxhIGlkPSdcIiArIGV4cGFuZG8gKyBcIicgaHJlZj0nJyBkaXNhYmxlZD0nZGlzYWJsZWQnPjwvYT5cIiArXG5cdFx0XHRcIjxzZWxlY3QgaWQ9J1wiICsgZXhwYW5kbyArIFwiLVxcclxcXFwnIGRpc2FibGVkPSdkaXNhYmxlZCc+XCIgK1xuXHRcdFx0XCI8b3B0aW9uIHNlbGVjdGVkPScnPjwvb3B0aW9uPjwvc2VsZWN0PlwiO1xuXG5cdFx0Ly8gU3VwcG9ydDogaU9TIDw9NyAtIDggb25seVxuXHRcdC8vIEJvb2xlYW4gYXR0cmlidXRlcyBhbmQgXCJ2YWx1ZVwiIGFyZSBub3QgdHJlYXRlZCBjb3JyZWN0bHkgaW4gc29tZSBYTUwgZG9jdW1lbnRzXG5cdFx0aWYgKCAhZWwucXVlcnlTZWxlY3RvckFsbCggXCJbc2VsZWN0ZWRdXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKig/OnZhbHVlfFwiICsgYm9vbGVhbnMgKyBcIilcIiApO1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IGlPUyA8PTcgLSA4IG9ubHlcblx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIltpZH49XCIgKyBleHBhbmRvICsgXCItXVwiICkubGVuZ3RoICkge1xuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwifj1cIiApO1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IGlPUyA4IG9ubHlcblx0XHQvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM2ODUxXG5cdFx0Ly8gSW4tcGFnZSBgc2VsZWN0b3IjaWQgc2libGluZy1jb21iaW5hdG9yIHNlbGVjdG9yYCBmYWlsc1xuXHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiYSNcIiArIGV4cGFuZG8gKyBcIisqXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRyYnVnZ3lRU0EucHVzaCggXCIuIy4rWyt+XVwiICk7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogQ2hyb21lIDw9MTA1KywgRmlyZWZveCA8PTEwNCssIFNhZmFyaSA8PTE1LjQrXG5cdFx0Ly8gSW4gc29tZSBvZiB0aGUgZG9jdW1lbnQga2luZHMsIHRoZXNlIHNlbGVjdG9ycyB3b3VsZG4ndCB3b3JrIG5hdGl2ZWx5LlxuXHRcdC8vIFRoaXMgaXMgcHJvYmFibHkgT0sgYnV0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSB3ZSB3YW50IHRvIG1haW50YWluXG5cdFx0Ly8gaGFuZGxpbmcgdGhlbSB0aHJvdWdoIGpRdWVyeSB0cmF2ZXJzYWwgaW4galF1ZXJ5IDMueC5cblx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIjpjaGVja2VkXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRyYnVnZ3lRU0EucHVzaCggXCI6Y2hlY2tlZFwiICk7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogV2luZG93cyA4IE5hdGl2ZSBBcHBzXG5cdFx0Ly8gVGhlIHR5cGUgYW5kIG5hbWUgYXR0cmlidXRlcyBhcmUgcmVzdHJpY3RlZCBkdXJpbmcgLmlubmVySFRNTCBhc3NpZ25tZW50XG5cdFx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcblx0XHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCBcImhpZGRlblwiICk7XG5cdFx0ZWwuYXBwZW5kQ2hpbGQoIGlucHV0ICkuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJEXCIgKTtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgLSAxMStcblx0XHQvLyBJRSdzIDpkaXNhYmxlZCBzZWxlY3RvciBkb2VzIG5vdCBwaWNrIHVwIHRoZSBjaGlsZHJlbiBvZiBkaXNhYmxlZCBmaWVsZHNldHNcblx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0xMDUrLCBGaXJlZm94IDw9MTA0KywgU2FmYXJpIDw9MTUuNCtcblx0XHQvLyBJbiBzb21lIG9mIHRoZSBkb2N1bWVudCBraW5kcywgdGhlc2Ugc2VsZWN0b3JzIHdvdWxkbid0IHdvcmsgbmF0aXZlbHkuXG5cdFx0Ly8gVGhpcyBpcyBwcm9iYWJseSBPSyBidXQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHdlIHdhbnQgdG8gbWFpbnRhaW5cblx0XHQvLyBoYW5kbGluZyB0aGVtIHRocm91Z2ggalF1ZXJ5IHRyYXZlcnNhbCBpbiBqUXVlcnkgMy54LlxuXHRcdGRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZCggZWwgKS5kaXNhYmxlZCA9IHRydWU7XG5cdFx0aWYgKCBlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIjpkaXNhYmxlZFwiICkubGVuZ3RoICE9PSAyICkge1xuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiOmVuYWJsZWRcIiwgXCI6ZGlzYWJsZWRcIiApO1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNSAtIDE4K1xuXHRcdC8vIElFIDExL0VkZ2UgZG9uJ3QgZmluZCBlbGVtZW50cyBvbiBhIGBbbmFtZT0nJ11gIHF1ZXJ5IGluIHNvbWUgY2FzZXMuXG5cdFx0Ly8gQWRkaW5nIGEgdGVtcG9yYXJ5IGF0dHJpYnV0ZSB0byB0aGUgZG9jdW1lbnQgYmVmb3JlIHRoZSBzZWxlY3Rpb24gd29ya3Ncblx0XHQvLyBhcm91bmQgdGhlIGlzc3VlLlxuXHRcdC8vIEludGVyZXN0aW5nbHksIElFIDEwICYgb2xkZXIgZG9uJ3Qgc2VlbSB0byBoYXZlIHRoZSBpc3N1ZS5cblx0XHRpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApO1xuXHRcdGlucHV0LnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwiXCIgKTtcblx0XHRlbC5hcHBlbmRDaGlsZCggaW5wdXQgKTtcblx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIltuYW1lPScnXVwiICkubGVuZ3RoICkge1xuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiXFxcXFt
1cIiArIHdoaXRlc3BhY2UgKyBcIipuYW1lXCIgKyB3aGl0ZXNwYWNlICsgXCIqPVwiICtcblx0XHRcdFx0d2hpdGVzcGFjZSArIFwiKig/OicnfFxcXCJcXFwiKVwiICk7XG5cdFx0fVxuXHR9ICk7XG5cblx0aWYgKCAhc3VwcG9ydC5jc3NIYXMgKSB7XG5cblx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgMTA1IC0gMTEwKywgU2FmYXJpIDE1LjQgLSAxNi4zK1xuXHRcdC8vIE91ciByZWd1bGFyIGB0cnktY2F0Y2hgIG1lY2hhbmlzbSBmYWlscyB0byBkZXRlY3QgbmF0aXZlbHktdW5zdXBwb3J0ZWRcblx0XHQvLyBwc2V1ZG8tY2xhc3NlcyBpbnNpZGUgYDpoYXMoKWAgKHN1Y2ggYXMgYDpoYXMoOmNvbnRhaW5zKFwiRm9vXCIpKWApXG5cdFx0Ly8gaW4gYnJvd3NlcnMgdGhhdCBwYXJzZSB0aGUgYDpoYXMoKWAgYXJndW1lbnQgYXMgYSBmb3JnaXZpbmcgc2VsZWN0b3IgbGlzdC5cblx0XHQvLyBodHRwczovL2RyYWZ0cy5jc3N3Zy5vcmcvc2VsZWN0b3JzLyNyZWxhdGlvbmFsIG5vdyByZXF1aXJlcyB0aGUgYXJndW1lbnRcblx0XHQvLyB0byBiZSBwYXJzZWQgdW5mb3JnaXZpbmdseSwgYnV0IGJyb3dzZXJzIGhhdmUgbm90IHlldCBmdWxseSBhZGp1c3RlZC5cblx0XHRyYnVnZ3lRU0EucHVzaCggXCI6aGFzXCIgKTtcblx0fVxuXG5cdHJidWdneVFTQSA9IHJidWdneVFTQS5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5UVNBLmpvaW4oIFwifFwiICkgKTtcblxuXHQvKiBTb3J0aW5nXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBEb2N1bWVudCBvcmRlciBzb3J0aW5nXG5cdHNvcnRPcmRlciA9IGZ1bmN0aW9uKCBhLCBiICkge1xuXG5cdFx0Ly8gRmxhZyBmb3IgZHVwbGljYXRlIHJlbW92YWxcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0Ly8gU29ydCBvbiBtZXRob2QgZXhpc3RlbmNlIGlmIG9ubHkgb25lIGlucHV0IGhhcyBjb21wYXJlRG9jdW1lbnRQb3NpdGlvblxuXHRcdHZhciBjb21wYXJlID0gIWEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gLSAhYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbjtcblx0XHRpZiAoIGNvbXBhcmUgKSB7XG5cdFx0XHRyZXR1cm4gY29tcGFyZTtcblx0XHR9XG5cblx0XHQvLyBDYWxjdWxhdGUgcG9zaXRpb24gaWYgYm90aCBpbnB1dHMgYmVsb25nIHRvIHRoZSBzYW1lIGRvY3VtZW50XG5cdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRjb21wYXJlID0gKCBhLm93bmVyRG9jdW1lbnQgfHwgYSApID09ICggYi5vd25lckRvY3VtZW50IHx8IGIgKSA/XG5cdFx0XHRhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBiICkgOlxuXG5cdFx0XHQvLyBPdGhlcndpc2Ugd2Uga25vdyB0aGV5IGFyZSBkaXNjb25uZWN0ZWRcblx0XHRcdDE7XG5cblx0XHQvLyBEaXNjb25uZWN0ZWQgbm9kZXNcblx0XHRpZiAoIGNvbXBhcmUgJiAxIHx8XG5cdFx0XHQoICFzdXBwb3J0LnNvcnREZXRhY2hlZCAmJiBiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBhICkgPT09IGNvbXBhcmUgKSApIHtcblxuXHRcdFx0Ly8gQ2hvb3NlIHRoZSBmaXJzdCBlbGVtZW50IHRoYXQgaXMgcmVsYXRlZCB0byBvdXIgcHJlZmVycmVkIGRvY3VtZW50XG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0aWYgKCBhID09PSBkb2N1bWVudCB8fCBhLm93bmVyRG9jdW1lbnQgPT0gcHJlZmVycmVkRG9jICYmXG5cdFx0XHRcdGZpbmQuY29udGFpbnMoIHByZWZlcnJlZERvYywgYSApICkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdFx0XHRpZiAoIGIgPT09IGRvY3VtZW50IHx8IGIub3duZXJEb2N1bWVudCA9PSBwcmVmZXJyZWREb2MgJiZcblx0XHRcdFx0ZmluZC5jb250YWlucyggcHJlZmVycmVkRG9jLCBiICkgKSB7XG5cdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBNYWludGFpbiBvcmlnaW5hbCBvcmRlclxuXHRcdFx0cmV0dXJuIHNvcnRJbnB1dCA/XG5cdFx0XHRcdCggaW5kZXhPZi5jYWxsKCBzb3J0SW5wdXQsIGEgKSAtIGluZGV4T2YuY2FsbCggc29ydElucHV0LCBiICkgKSA6XG5cdFx0XHRcdDA7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNvbXBhcmUgJiA0ID8gLTEgOiAxO1xuXHR9O1xuXG5cdHJldHVybiBkb2N1bWVudDtcbn1cblxuZmluZC5tYXRjaGVzID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1lbnRzICkge1xuXHRyZXR1cm4gZmluZCggZXhwciwgbnVsbCwgbnVsbCwgZWxlbWVudHMgKTtcbn07XG5cbmZpbmQubWF0Y2hlc1NlbGVjdG9yID0gZnVuY3Rpb24oIGVsZW0sIGV4cHIgKSB7XG5cdHNldERvY3VtZW50KCBlbGVtICk7XG5cblx0aWYgKCBkb2N1bWVudElzSFRNTCAmJlxuXHRcdCFub25uYXRpdmVTZWxlY3RvckNhY2hlWyBleHByICsgXCIgXCIgXSAmJlxuXHRcdCggIXJidWdneVFTQSB8fCAhcmJ1Z2d5UVNBLnRlc3QoIGV4cHIgKSApICkge1xuXG5cdFx0dHJ5IHtcblx0XHRcdHZhciByZXQgPSBtYXRjaGVzLmNhbGwoIGVsZW0sIGV4cHIgKTtcblxuXHRcdFx0Ly8gSUUgOSdzIG1hdGNoZXNTZWxlY3RvciByZXR1cm5zIGZhbHNlIG9uIGRpc2Nvbm5lY3RlZCBub2Rlc1xuXHRcdFx0aWYgKCByZXQgfHwgc3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCB8fFxuXG5cdFx0XHRcdFx0Ly8gQXMgd2VsbCwgZGlzY29ubmVjdGVkIG5vZGVzIGFyZSBzYWlkIHRvIGJlIGluIGEgZG9jdW1lbnRcblx0XHRcdFx0XHQvLyBmcmFnbWVudCBpbiBJRSA5XG5cdFx0XHRcdFx0ZWxlbS5kb2N1bWVudCAmJiBlbGVtLmRvY3VtZW50Lm5vZGVUeXBlICE9PSAxMSApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdG5vbm5hdGl2ZVNlbGVjdG9yQ2FjaGUoIGV4cHIsIHRydWUgKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZmluZCggZXhwciwgZG9jdW1lbnQsIG51bGwsIFsgZWxlbSBdICkubGVuZ3RoID4gMDtcbn07XG5cbmZpbmQuY29udGFpbnMgPSBmdW5jdGlvbiggY29udGV4dCwgZWxlbSApIHtcblxuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0aWYgKCAoIGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0ICkgIT0gZG9jdW1lbnQgKSB7XG5cdFx0c2V0RG9jdW1lbnQoIGNvbnRleHQgKTtcblx0fVxuXHRyZXR1cm4galF1ZXJ5LmNvbnRhaW5zKCBjb250ZXh0LCBlbGVtICk7XG59O1xuXG5cbmZpbmQuYXR0ciA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXG5cdC8vIFNldCBkb2N1bWVudCB2Y
1XJzIGlmIG5lZWRlZFxuXHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRpZiAoICggZWxlbS5vd25lckRvY3VtZW50IHx8IGVsZW0gKSAhPSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggZWxlbSApO1xuXHR9XG5cblx0dmFyIGZuID0gRXhwci5hdHRySGFuZGxlWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSxcblxuXHRcdC8vIERvbid0IGdldCBmb29sZWQgYnkgT2JqZWN0LnByb3RvdHlwZSBwcm9wZXJ0aWVzIChzZWUgdHJhYy0xMzgwNylcblx0XHR2YWwgPSBmbiAmJiBoYXNPd24uY2FsbCggRXhwci5hdHRySGFuZGxlLCBuYW1lLnRvTG93ZXJDYXNlKCkgKSA/XG5cdFx0XHRmbiggZWxlbSwgbmFtZSwgIWRvY3VtZW50SXNIVE1MICkgOlxuXHRcdFx0dW5kZWZpbmVkO1xuXG5cdGlmICggdmFsICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0cmV0dXJuIHZhbDtcblx0fVxuXG5cdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApO1xufTtcblxuZmluZC5lcnJvciA9IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdHRocm93IG5ldyBFcnJvciggXCJTeW50YXggZXJyb3IsIHVucmVjb2duaXplZCBleHByZXNzaW9uOiBcIiArIG1zZyApO1xufTtcblxuLyoqXG4gKiBEb2N1bWVudCBzb3J0aW5nIGFuZCByZW1vdmluZyBkdXBsaWNhdGVzXG4gKiBAcGFyYW0ge0FycmF5TGlrZX0gcmVzdWx0c1xuICovXG5qUXVlcnkudW5pcXVlU29ydCA9IGZ1bmN0aW9uKCByZXN1bHRzICkge1xuXHR2YXIgZWxlbSxcblx0XHRkdXBsaWNhdGVzID0gW10sXG5cdFx0aiA9IDAsXG5cdFx0aSA9IDA7XG5cblx0Ly8gVW5sZXNzIHdlICprbm93KiB3ZSBjYW4gZGV0ZWN0IGR1cGxpY2F0ZXMsIGFzc3VtZSB0aGVpciBwcmVzZW5jZVxuXHQvL1xuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wK1xuXHQvLyBUZXN0aW5nIGZvciBkZXRlY3RpbmcgZHVwbGljYXRlcyBpcyB1bnByZWRpY3RhYmxlIHNvIGluc3RlYWQgYXNzdW1lIHdlIGNhbid0XG5cdC8vIGRlcGVuZCBvbiBkdXBsaWNhdGUgZGV0ZWN0aW9uIGluIGFsbCBicm93c2VycyB3aXRob3V0IGEgc3RhYmxlIHNvcnQuXG5cdGhhc0R1cGxpY2F0ZSA9ICFzdXBwb3J0LnNvcnRTdGFibGU7XG5cdHNvcnRJbnB1dCA9ICFzdXBwb3J0LnNvcnRTdGFibGUgJiYgc2xpY2UuY2FsbCggcmVzdWx0cywgMCApO1xuXHRzb3J0LmNhbGwoIHJlc3VsdHMsIHNvcnRPcmRlciApO1xuXG5cdGlmICggaGFzRHVwbGljYXRlICkge1xuXHRcdHdoaWxlICggKCBlbGVtID0gcmVzdWx0c1sgaSsrIF0gKSApIHtcblx0XHRcdGlmICggZWxlbSA9PT0gcmVzdWx0c1sgaSBdICkge1xuXHRcdFx0XHRqID0gZHVwbGljYXRlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0c3BsaWNlLmNhbGwoIHJlc3VsdHMsIGR1cGxpY2F0ZXNbIGogXSwgMSApO1xuXHRcdH1cblx0fVxuXG5cdC8vIENsZWFyIGlucHV0IGFmdGVyIHNvcnRpbmcgdG8gcmVsZWFzZSBvYmplY3RzXG5cdC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L3NpenpsZS9wdWxsLzIyNVxuXHRzb3J0SW5wdXQgPSBudWxsO1xuXG5cdHJldHVybiByZXN1bHRzO1xufTtcblxualF1ZXJ5LmZuLnVuaXF1ZVNvcnQgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkudW5pcXVlU29ydCggc2xpY2UuYXBwbHkoIHRoaXMgKSApICk7XG59O1xuXG5FeHByID0galF1ZXJ5LmV4cHIgPSB7XG5cblx0Ly8gQ2FuIGJlIGFkanVzdGVkIGJ5IHRoZSB1c2VyXG5cdGNhY2hlTGVuZ3RoOiA1MCxcblxuXHRjcmVhdGVQc2V1ZG86IG1hcmtGdW5jdGlvbixcblxuXHRtYXRjaDogbWF0Y2hFeHByLFxuXG5cdGF0dHJIYW5kbGU6IHt9LFxuXG5cdGZpbmQ6IHt9LFxuXG5cdHJlbGF0aXZlOiB7XG5cdFx0XCI+XCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiwgZmlyc3Q6IHRydWUgfSxcblx0XHRcIiBcIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiIH0sXG5cdFx0XCIrXCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiLCBmaXJzdDogdHJ1ZSB9LFxuXHRcdFwiflwiOiB7IGRpcjogXCJwcmV2aW91c1NpYmxpbmdcIiB9XG5cdH0sXG5cblx0cHJlRmlsdGVyOiB7XG5cdFx0QVRUUjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0bWF0Y2hbIDEgXSA9IG1hdGNoWyAxIF0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0Ly8gTW92ZSB0aGUgZ2l2ZW4gdmFsdWUgdG8gbWF0Y2hbM10gd2hldGhlciBxdW90ZWQgb3IgdW5xdW90ZWRcblx0XHRcdG1hdGNoWyAzIF0gPSAoIG1hdGNoWyAzIF0gfHwgbWF0Y2hbIDQgXSB8fCBtYXRjaFsgNSBdIHx8IFwiXCIgKVxuXHRcdFx0XHQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsgMiBdID09PSBcIn49XCIgKSB7XG5cdFx0XHRcdG1hdGNoWyAzIF0gPSBcIiBcIiArIG1hdGNoWyAzIF0gKyBcIiBcIjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7XG5cdFx0fSxcblxuXHRcdENISUxEOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cblx0XHRcdC8qIG1hdGNoZXMgZnJvbSBtYXRjaEV4cHJbXCJDSElMRFwiXVxuXHRcdFx0XHQxIHR5cGUgKG9ubHl8bnRofC4uLilcblx0XHRcdFx0MiB3aGF0IChjaGlsZHxvZi10eXBlKVxuXHRcdFx0XHQzIGFyZ3VtZW50IChldmVufG9kZHxcXGQqfFxcZCpuKFsrLV1cXGQrKT98Li4uKVxuXHRcdFx0XHQ0IHhuLWNvbXBvbmVudCBvZiB4bit5IGFyZ3VtZW50IChbKy1dP1xcZCpufClcblx0XHRcdFx0NSBzaWduIG9mIHhuLWNvbXBvbmVudFxuXHRcdFx0XHQ2IHggb2YgeG4tY29tcG9uZW50XG5cdFx0XHRcdDcgc2lnbiBvZiB5LWNvbXBvbmVudFxuXHRcdFx0XHQ4IHkgb2YgeS1jb21wb25lbnRcblx0XHRcdCovXG5cdFx0XHRtYXRjaFsgMSBdID0gbWF0Y2hbIDEgXS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0XHRpZiAoIG1hdGNoWyAxIF0uc2xpY2UoIDAsIDMgKSA9PT0gXCJudGhcIiApIHtcblxuXHRcdFx0XHQvLyBudGgtKiByZXF1aXJlcyBhcmd1bWVudFxuXHRcdFx0XHRpZiAoICFtYXRjaFsgMyBdICkge1xuXHRcdFx0XHRcdGZpbmQuZXJyb3IoIG1hdGNoWyAwIF0gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIG51bWVyaWMgeCBhbmQgeSBwYXJhbWV0ZXJzIGZvciBFeHByLmZpbHRlci5DSElMRFxuXHRcdFx0XHQvLyByZW1lbWJlciB0aGF0IGZhbHNlL3RydWUgY2FzdCByZXNwZWN0aXZlbHkgdG8gMC8xXG5cdFx0XHRcdG1hdGNoWyA0IF0gPSArKCBtYXRjaFsgNCBdID9cblx0XHRcdFx0XHRtYXRjaFsgNSBdICsgKCBtYXRjaFsgNiBdIHx8IDEgKSA6XG5cdFx0XHRcdFx0MiAqICggbWF0Y2hbIDMgXSA9PT0gXCJldmVuXCIgfHwgbWF0Y2hbIDMgXSA9PT0gXCJvZGRcIiApXG5cdFx0XHRcdCk7XG5cdFx0XHRcdG1hdGNoWyA1IF0gPSArKCAoIG1hdGNoWyA3IF0gKyBtYXRjaFsgOCBdICkgfHwgbWF0Y2hbIDMgXSA9PT0gXCJvZGRcIiApO1xuXG5cdFx0XHQvLyBvdGhlciB0eXBlcyBwcm9oaWJpdCBhcmd1bWVudHNcblx0XHRcdH0gZWxzZSBpZiAoIG1hdGNoWyAzIF0gKSB7XG5cdFx0XHRcdGZpbmQuZXJyb3IoIG1hdGNoWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoO1xuXHRcdH0sXG5cblx0XHRQU0VVRE86IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdHZhciBleGNlc3MsXG5cdFx0XHRcdHVucXVvdGVkID0gIW1hdGNoWyA2IF0gJiYgbWF0Y2hbIDIgXTtcblxuXHRcdFx0aWYgKCBtY
1XRjaEV4cHIuQ0hJTEQudGVzdCggbWF0Y2hbIDAgXSApICkge1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWNjZXB0IHF1b3RlZCBhcmd1bWVudHMgYXMtaXNcblx0XHRcdGlmICggbWF0Y2hbIDMgXSApIHtcblx0XHRcdFx0bWF0Y2hbIDIgXSA9IG1hdGNoWyA0IF0gfHwgbWF0Y2hbIDUgXSB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTdHJpcCBleGNlc3MgY2hhcmFjdGVycyBmcm9tIHVucXVvdGVkIGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggdW5xdW90ZWQgJiYgcnBzZXVkby50ZXN0KCB1bnF1b3RlZCApICYmXG5cblx0XHRcdFx0Ly8gR2V0IGV4Y2VzcyBmcm9tIHRva2VuaXplIChyZWN1cnNpdmVseSlcblx0XHRcdFx0KCBleGNlc3MgPSB0b2tlbml6ZSggdW5xdW90ZWQsIHRydWUgKSApICYmXG5cblx0XHRcdFx0Ly8gYWR2YW5jZSB0byB0aGUgbmV4dCBjbG9zaW5nIHBhcmVudGhlc2lzXG5cdFx0XHRcdCggZXhjZXNzID0gdW5xdW90ZWQuaW5kZXhPZiggXCIpXCIsIHVucXVvdGVkLmxlbmd0aCAtIGV4Y2VzcyApIC0gdW5xdW90ZWQubGVuZ3RoICkgKSB7XG5cblx0XHRcdFx0Ly8gZXhjZXNzIGlzIGEgbmVnYXRpdmUgaW5kZXhcblx0XHRcdFx0bWF0Y2hbIDAgXSA9IG1hdGNoWyAwIF0uc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0XHRtYXRjaFsgMiBdID0gdW5xdW90ZWQuc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXR1cm4gb25seSBjYXB0dXJlcyBuZWVkZWQgYnkgdGhlIHBzZXVkbyBmaWx0ZXIgbWV0aG9kICh0eXBlIGFuZCBhcmd1bWVudClcblx0XHRcdHJldHVybiBtYXRjaC5zbGljZSggMCwgMyApO1xuXHRcdH1cblx0fSxcblxuXHRmaWx0ZXI6IHtcblxuXHRcdFRBRzogZnVuY3Rpb24oIG5vZGVOYW1lU2VsZWN0b3IgKSB7XG5cdFx0XHR2YXIgZXhwZWN0ZWROb2RlTmFtZSA9IG5vZGVOYW1lU2VsZWN0b3IucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5vZGVOYW1lU2VsZWN0b3IgPT09IFwiKlwiID9cblx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH0gOlxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gbm9kZU5hbWUoIGVsZW0sIGV4cGVjdGVkTm9kZU5hbWUgKTtcblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0Q0xBU1M6IGZ1bmN0aW9uKCBjbGFzc05hbWUgKSB7XG5cdFx0XHR2YXIgcGF0dGVybiA9IGNsYXNzQ2FjaGVbIGNsYXNzTmFtZSArIFwiIFwiIF07XG5cblx0XHRcdHJldHVybiBwYXR0ZXJuIHx8XG5cdFx0XHRcdCggcGF0dGVybiA9IG5ldyBSZWdFeHAoIFwiKF58XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyBjbGFzc05hbWUgK1xuXHRcdFx0XHRcdFwiKFwiICsgd2hpdGVzcGFjZSArIFwifCQpXCIgKSApICYmXG5cdFx0XHRcdGNsYXNzQ2FjaGUoIGNsYXNzTmFtZSwgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhdHRlcm4udGVzdChcblx0XHRcdFx0XHRcdHR5cGVvZiBlbGVtLmNsYXNzTmFtZSA9PT0gXCJzdHJpbmdcIiAmJiBlbGVtLmNsYXNzTmFtZSB8fFxuXHRcdFx0XHRcdFx0XHR0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgIT09IFwidW5kZWZpbmVkXCIgJiZcblx0XHRcdFx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHxcblx0XHRcdFx0XHRcdFx0XCJcIlxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH0gKTtcblx0XHR9LFxuXG5cdFx0QVRUUjogZnVuY3Rpb24oIG5hbWUsIG9wZXJhdG9yLCBjaGVjayApIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHJlc3VsdCA9IGZpbmQuYXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0XHRcdGlmICggcmVzdWx0ID09IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIiE9XCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCAhb3BlcmF0b3IgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXN1bHQgKz0gXCJcIjtcblxuXHRcdFx0XHRpZiAoIG9wZXJhdG9yID09PSBcIj1cIiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0ID09PSBjaGVjaztcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIG9wZXJhdG9yID09PSBcIiE9XCIgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdCAhPT0gY2hlY2s7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBvcGVyYXRvciA9PT0gXCJePVwiICkge1xuXHRcdFx0XHRcdHJldHVybiBjaGVjayAmJiByZXN1bHQuaW5kZXhPZiggY2hlY2sgKSA9PT0gMDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIG9wZXJhdG9yID09PSBcIio9XCIgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID4gLTE7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBvcGVyYXRvciA9PT0gXCIkPVwiICkge1xuXHRcdFx0XHRcdHJldHVybiBjaGVjayAmJiByZXN1bHQuc2xpY2UoIC1jaGVjay5sZW5ndGggKSA9PT0gY2hlY2s7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBvcGVyYXRvciA9PT0gXCJ+PVwiICkge1xuXHRcdFx0XHRcdHJldHVybiAoIFwiIFwiICsgcmVzdWx0LnJlcGxhY2UoIHJ3aGl0ZXNwYWNlLCBcIiBcIiApICsgXCIgXCIgKVxuXHRcdFx0XHRcdFx0LmluZGV4T2YoIGNoZWNrICkgPiAtMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIG9wZXJhdG9yID09PSBcInw9XCIgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdCA9PT0gY2hlY2sgfHwgcmVzdWx0LnNsaWNlKCAwLCBjaGVjay5sZW5ndGggKyAxICkgPT09IGNoZWNrICsgXCItXCI7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRDSElMRDogZnVuY3Rpb24oIHR5cGUsIHdoYXQsIF9hcmd1bWVudCwgZmlyc3QsIGxhc3QgKSB7XG5cdFx0XHR2YXIgc2ltcGxlID0gdHlwZS5zbGljZSggMCwgMyApICE9PSBcIm50aFwiLFxuXHRcdFx0XHRmb3J3YXJkID0gdHlwZS5zbGljZSggLTQgKSAhPT0gXCJsYXN0XCIsXG5cdFx0XHRcdG9mVHlwZSA9IHdoYXQgPT09IFwib2YtdHlwZVwiO1xuXG5cdFx0XHRyZXR1cm4gZmlyc3QgPT09IDEgJiYgbGFzdCA9PT0gMCA/XG5cblx0XHRcdFx0Ly8gU2hvcnRjdXQgZm9yIDpudGgtKihuKVxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gISFlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRcdH0gOlxuXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBfY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdHZhciBjYWNoZSwgb3V0ZXJDYWNoZSwgbm9kZSwgbm9kZUluZGV4LCBzdGFydCxcblx0XHRcdFx0XHRcdGRpciA9IHNpbXBsZSAhPT0gZm9yd2FyZCA/IFwibmV4dFNpYmxpbmdcIiA6IFwicHJldmlvdXNTaWJsaW5nXCIsXG5cdFx0XHRcdFx0XHRwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGUsXG5cdFx0XHRcdFx0XHRuYW1lID0gb2ZUeXBlICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxcblx0XHRcdFx0XHRcdHVzZUNhY2hlID0gIXhtbCAmJiAhb2ZUeXBlLFxuXHRcdFx0XHRcdFx0ZGlmZiA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0aWYgKCBwYXJlbnQgKSB7XG5cblx0XHRcdFx0XHRcdC8vIDooZmlyc3R8bGFzdHxvbmx5KS0oY2hpbGR8b2YtdHlwZSlcblx0XHRcdFx0XHRcdGlmICggc2ltcGxlICkge1xuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIGRpciApIHtcblx0XHRcdFx0XHRcdFx0XHRub2RlID0gZWxlbTtcblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoICggbm9kZSA9IG5vZGVbIGRpciBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG9mVHlwZSA/XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGVOYW1lKCBub2RlLCBuYW1lICkgOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRub2RlLm5vZGVUeXBlID09PSAxICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybi
1BmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBSZXZlcnNlIGRpcmVjdGlvbiBmb3IgOm9ubHktKiAoaWYgd2UgaGF2ZW4ndCB5ZXQgZG9uZSBzbylcblx0XHRcdFx0XHRcdFx0XHRzdGFydCA9IGRpciA9IHR5cGUgPT09IFwib25seVwiICYmICFzdGFydCAmJiBcIm5leHRTaWJsaW5nXCI7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHN0YXJ0ID0gWyBmb3J3YXJkID8gcGFyZW50LmZpcnN0Q2hpbGQgOiBwYXJlbnQubGFzdENoaWxkIF07XG5cblx0XHRcdFx0XHRcdC8vIG5vbi14bWwgOm50aC1jaGlsZCguLi4pIHN0b3JlcyBjYWNoZSBkYXRhIG9uIGBwYXJlbnRgXG5cdFx0XHRcdFx0XHRpZiAoIGZvcndhcmQgJiYgdXNlQ2FjaGUgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU2VlayBgZWxlbWAgZnJvbSBhIHByZXZpb3VzbHktY2FjaGVkIGluZGV4XG5cdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBwYXJlbnRbIGV4cGFuZG8gXSB8fCAoIHBhcmVudFsgZXhwYW5kbyBdID0ge30gKTtcblx0XHRcdFx0XHRcdFx0Y2FjaGUgPSBvdXRlckNhY2hlWyB0eXBlIF0gfHwgW107XG5cdFx0XHRcdFx0XHRcdG5vZGVJbmRleCA9IGNhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgY2FjaGVbIDEgXTtcblx0XHRcdFx0XHRcdFx0ZGlmZiA9IG5vZGVJbmRleCAmJiBjYWNoZVsgMiBdO1xuXHRcdFx0XHRcdFx0XHRub2RlID0gbm9kZUluZGV4ICYmIHBhcmVudC5jaGlsZE5vZGVzWyBub2RlSW5kZXggXTtcblxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoICggbm9kZSA9ICsrbm9kZUluZGV4ICYmIG5vZGUgJiYgbm9kZVsgZGlyIF0gfHxcblxuXHRcdFx0XHRcdFx0XHRcdC8vIEZhbGxiYWNrIHRvIHNlZWtpbmcgYGVsZW1gIGZyb20gdGhlIHN0YXJ0XG5cdFx0XHRcdFx0XHRcdFx0KCBkaWZmID0gbm9kZUluZGV4ID0gMCApIHx8IHN0YXJ0LnBvcCgpICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBXaGVuIGZvdW5kLCBjYWNoZSBpbmRleGVzIG9uIGBwYXJlbnRgIGFuZCBicmVha1xuXHRcdFx0XHRcdFx0XHRcdGlmICggbm9kZS5ub2RlVHlwZSA9PT0gMSAmJiArK2RpZmYgJiYgbm9kZSA9PT0gZWxlbSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGVbIHR5cGUgXSA9IFsgZGlycnVucywgbm9kZUluZGV4LCBkaWZmIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBVc2UgcHJldmlvdXNseS1jYWNoZWQgZWxlbWVudCBpbmRleCBpZiBhdmFpbGFibGVcblx0XHRcdFx0XHRcdFx0aWYgKCB1c2VDYWNoZSApIHtcblx0XHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gZWxlbVsgZXhwYW5kbyBdIHx8ICggZWxlbVsgZXhwYW5kbyBdID0ge30gKTtcblx0XHRcdFx0XHRcdFx0XHRjYWNoZSA9IG91dGVyQ2FjaGVbIHR5cGUgXSB8fCBbXTtcblx0XHRcdFx0XHRcdFx0XHRub2RlSW5kZXggPSBjYWNoZVsgMCBdID09PSBkaXJydW5zICYmIGNhY2hlWyAxIF07XG5cdFx0XHRcdFx0XHRcdFx0ZGlmZiA9IG5vZGVJbmRleDtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdC8vIHhtbCA6bnRoLWNoaWxkKC4uLilcblx0XHRcdFx0XHRcdFx0Ly8gb3IgOm50aC1sYXN0LWNoaWxkKC4uLikgb3IgOm50aCgtbGFzdCk/LW9mLXR5cGUoLi4uKVxuXHRcdFx0XHRcdFx0XHRpZiAoIGRpZmYgPT09IGZhbHNlICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gVXNlIHRoZSBzYW1lIGxvb3AgYXMgYWJvdmUgdG8gc2VlayBgZWxlbWAgZnJvbSB0aGUgc3RhcnRcblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoICggbm9kZSA9ICsrbm9kZUluZGV4ICYmIG5vZGUgJiYgbm9kZVsgZGlyIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRcdCggZGlmZiA9IG5vZGVJbmRleCA9IDAgKSB8fCBzdGFydC5wb3AoKSApICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoICggb2ZUeXBlID9cblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZU5hbWUoIG5vZGUsIG5hbWUgKSA6XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZVR5cGUgPT09IDEgKSAmJlxuXHRcdFx0XHRcdFx0XHRcdFx0XHQrK2RpZmYgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gQ2FjaGUgdGhlIGluZGV4IG9mIGVhY2ggZW5jb3VudGVyZWQgZWxlbWVudFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIHVzZUNhY2hlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCggbm9kZVsgZXhwYW5kbyBdID0ge30gKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIGRpZmYgXTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggbm9kZSA9PT0gZWxlbSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBJbmNvcnBvcmF0ZSB0aGUgb2Zmc2V0LCB0aGVuIGNoZWNrIGFnYWluc3QgY3ljbGUgc2l6ZVxuXHRcdFx0XHRcdFx0ZGlmZiAtPSBsYXN0O1xuXHRcdFx0XHRcdFx0cmV0dXJuIGRpZmYgPT09IGZpcnN0IHx8ICggZGlmZiAlIGZpcnN0ID09PSAwICYmIGRpZmYgLyBmaXJzdCA+PSAwICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRQU0VVRE86IGZ1bmN0aW9uKCBwc2V1ZG8sIGFyZ3VtZW50ICkge1xuXG5cdFx0XHQvLyBwc2V1ZG8tY2xhc3MgbmFtZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmVcblx0XHRcdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI3BzZXVkby1jbGFzc2VzXG5cdFx0XHQvLyBQcmlvcml0aXplIGJ5IGNhc2Ugc2Vuc2l0aXZpdHkgaW4gY2FzZSBjdXN0b20gcHNldWRvcyBhcmUgYWRkZWQgd2l0aCB1cHBlcmNhc2UgbGV0dGVyc1xuXHRcdFx0Ly8gUmVtZW1iZXIgdGhhdCBzZXRGaWx0ZXJzIGluaGVyaXRzIGZyb20gcHNldWRvc1xuXHRcdFx0dmFyIGFyZ3MsXG5cdFx0XHRcdGZuID0gRXhwci5wc2V1ZG9zWyBwc2V1ZG8gXSB8fCBFeHByLnNldEZpbHRlcnNbIHBzZXVkby50b0xvd2VyQ2FzZSgpIF0gfHxcblx0XHRcdFx0XHRmaW5kLmVycm9yKCBcInVuc3VwcG9ydGVkIHBzZXVkbzogXCIgKyBwc2V1ZG8gKTtcblxuXHRcdFx0Ly8gVGhlIHVzZXIgbWF5IHVzZSBjcmVhdGVQc2V1ZG8gdG8gaW5kaWNhdGUgdGhhdFxuXHRcdFx0Ly8gYXJndW1lbnRzIGFyZSBuZWVkZWQgdG8gY3JlYXRlIHRoZSBmaWx0ZXIgZnVuY3Rpb25cblx0XHRcdC8vIGp1c3QgYXMgalF1ZXJ5IGRvZXNcblx0XHRcdGlmICggZm5bIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0cmV0dXJuIGZuKCBhcmd1bWVudCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBCdXQgbWFpbnRhaW4gc3VwcG9ydCBmb3Igb2xkIHNpZ25hdHVyZXNcblx0XHRcdGlmICggZm4ubGVuZ3RoID4gMSApIHtcblx0XHRcdFx0YXJncyA9IFsgcHNldWRvLCBwc2V1ZG8sIFwiXCIsIGFyZ3VtZW50IF07XG5cdFx0XHRcdHJldHVybi
1BFeHByLnNldEZpbHRlcnMuaGFzT3duUHJvcGVydHkoIHBzZXVkby50b0xvd2VyQ2FzZSgpICkgP1xuXHRcdFx0XHRcdG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7XG5cdFx0XHRcdFx0XHR2YXIgaWR4LFxuXHRcdFx0XHRcdFx0XHRtYXRjaGVkID0gZm4oIHNlZWQsIGFyZ3VtZW50ICksXG5cdFx0XHRcdFx0XHRcdGkgPSBtYXRjaGVkLmxlbmd0aDtcblx0XHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0XHRpZHggPSBpbmRleE9mLmNhbGwoIHNlZWQsIG1hdGNoZWRbIGkgXSApO1xuXHRcdFx0XHRcdFx0XHRzZWVkWyBpZHggXSA9ICEoIG1hdGNoZXNbIGlkeCBdID0gbWF0Y2hlZFsgaSBdICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSApIDpcblx0XHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRcdHJldHVybiBmbiggZWxlbSwgMCwgYXJncyApO1xuXHRcdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBmbjtcblx0XHR9XG5cdH0sXG5cblx0cHNldWRvczoge1xuXG5cdFx0Ly8gUG90ZW50aWFsbHkgY29tcGxleCBwc2V1ZG9zXG5cdFx0bm90OiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblxuXHRcdFx0Ly8gVHJpbSB0aGUgc2VsZWN0b3IgcGFzc2VkIHRvIGNvbXBpbGVcblx0XHRcdC8vIHRvIGF2b2lkIHRyZWF0aW5nIGxlYWRpbmcgYW5kIHRyYWlsaW5nXG5cdFx0XHQvLyBzcGFjZXMgYXMgY29tYmluYXRvcnNcblx0XHRcdHZhciBpbnB1dCA9IFtdLFxuXHRcdFx0XHRyZXN1bHRzID0gW10sXG5cdFx0XHRcdG1hdGNoZXIgPSBjb21waWxlKCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbUNTUywgXCIkMVwiICkgKTtcblxuXHRcdFx0cmV0dXJuIG1hdGNoZXJbIGV4cGFuZG8gXSA/XG5cdFx0XHRcdG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMsIF9jb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0dmFyIGVsZW0sXG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQgPSBtYXRjaGVyKCBzZWVkLCBudWxsLCB4bWwsIFtdICksXG5cdFx0XHRcdFx0XHRpID0gc2VlZC5sZW5ndGg7XG5cblx0XHRcdFx0XHQvLyBNYXRjaCBlbGVtZW50cyB1bm1hdGNoZWQgYnkgYG1hdGNoZXJgXG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZWxlbSA9IHVubWF0Y2hlZFsgaSBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdHNlZWRbIGkgXSA9ICEoIG1hdGNoZXNbIGkgXSA9IGVsZW0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gKSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBfY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdGlucHV0WyAwIF0gPSBlbGVtO1xuXHRcdFx0XHRcdG1hdGNoZXIoIGlucHV0LCBudWxsLCB4bWwsIHJlc3VsdHMgKTtcblxuXHRcdFx0XHRcdC8vIERvbid0IGtlZXAgdGhlIGVsZW1lbnRcblx0XHRcdFx0XHQvLyAoc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvc2l6emxlL2lzc3Vlcy8yOTkpXG5cdFx0XHRcdFx0aW5wdXRbIDAgXSA9IG51bGw7XG5cdFx0XHRcdFx0cmV0dXJuICFyZXN1bHRzLnBvcCgpO1xuXHRcdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdGhhczogbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiBmaW5kKCBzZWxlY3RvciwgZWxlbSApLmxlbmd0aCA+IDA7XG5cdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdGNvbnRhaW5zOiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRcdFx0dGV4dCA9IHRleHQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuICggZWxlbS50ZXh0Q29udGVudCB8fCBqUXVlcnkudGV4dCggZWxlbSApICkuaW5kZXhPZiggdGV4dCApID4gLTE7XG5cdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdC8vIFwiV2hldGhlciBhbiBlbGVtZW50IGlzIHJlcHJlc2VudGVkIGJ5IGEgOmxhbmcoKSBzZWxlY3RvclxuXHRcdC8vIGlzIGJhc2VkIHNvbGVseSBvbiB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlXG5cdFx0Ly8gYmVpbmcgZXF1YWwgdG8gdGhlIGlkZW50aWZpZXIgQyxcblx0XHQvLyBvciBiZWdpbm5pbmcgd2l0aCB0aGUgaWRlbnRpZmllciBDIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IFwiLVwiLlxuXHRcdC8vIFRoZSBtYXRjaGluZyBvZiBDIGFnYWluc3QgdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZSBpcyBwZXJmb3JtZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LlxuXHRcdC8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuXCJcblx0XHQvLyBodHRwczovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNsYW5nLXBzZXVkb1xuXHRcdGxhbmc6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGxhbmcgKSB7XG5cblx0XHRcdC8vIGxhbmcgdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGlkZW50aWZpZXJcblx0XHRcdGlmICggIXJpZGVudGlmaWVyLnRlc3QoIGxhbmcgfHwgXCJcIiApICkge1xuXHRcdFx0XHRmaW5kLmVycm9yKCBcInVuc3VwcG9ydGVkIGxhbmc6IFwiICsgbGFuZyApO1xuXHRcdFx0fVxuXHRcdFx0bGFuZyA9IGxhbmcucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgZWxlbUxhbmc7XG5cdFx0XHRcdGRvIHtcblx0XHRcdFx0XHRpZiAoICggZWxlbUxhbmcgPSBkb2N1bWVudElzSFRNTCA/XG5cdFx0XHRcdFx0XHRlbGVtLmxhbmcgOlxuXHRcdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoIFwieG1sOmxhbmdcIiApIHx8IGVsZW0uZ2V0QXR0cmlidXRlKCBcImxhbmdcIiApICkgKSB7XG5cblx0XHRcdFx0XHRcdGVsZW1MYW5nID0gZWxlbUxhbmcudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtTGFuZyA9PT0gbGFuZyB8fCBlbGVtTGFuZy5pbmRleE9mKCBsYW5nICsgXCItXCIgKSA9PT0gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gd2hpbGUgKCAoIGVsZW0gPSBlbGVtLnBhcmVudE5vZGUgKSAmJiBlbGVtLm5vZGVUeXBlID09PSAxICk7XG5cdFx0XHRcdHJldHVybi
1BmYWxzZTtcblx0XHRcdH07XG5cdFx0fSApLFxuXG5cdFx0Ly8gTWlzY2VsbGFuZW91c1xuXHRcdHRhcmdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbiAmJiB3aW5kb3cubG9jYXRpb24uaGFzaDtcblx0XHRcdHJldHVybiBoYXNoICYmIGhhc2guc2xpY2UoIDEgKSA9PT0gZWxlbS5pZDtcblx0XHR9LFxuXG5cdFx0cm9vdDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jdW1lbnRFbGVtZW50O1xuXHRcdH0sXG5cblx0XHRmb2N1czogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gc2FmZUFjdGl2ZUVsZW1lbnQoKSAmJlxuXHRcdFx0XHRkb2N1bWVudC5oYXNGb2N1cygpICYmXG5cdFx0XHRcdCEhKCBlbGVtLnR5cGUgfHwgZWxlbS5ocmVmIHx8IH5lbGVtLnRhYkluZGV4ICk7XG5cdFx0fSxcblxuXHRcdC8vIEJvb2xlYW4gcHJvcGVydGllc1xuXHRcdGVuYWJsZWQ6IGNyZWF0ZURpc2FibGVkUHNldWRvKCBmYWxzZSApLFxuXHRcdGRpc2FibGVkOiBjcmVhdGVEaXNhYmxlZFBzZXVkbyggdHJ1ZSApLFxuXG5cdFx0Y2hlY2tlZDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdC8vIEluIENTUzMsIDpjaGVja2VkIHNob3VsZCByZXR1cm4gYm90aCBjaGVja2VkIGFuZCBzZWxlY3RlZCBlbGVtZW50c1xuXHRcdFx0Ly8gaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHRyZXR1cm4gKCBub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgJiYgISFlbGVtLmNoZWNrZWQgKSB8fFxuXHRcdFx0XHQoIG5vZGVOYW1lKCBlbGVtLCBcIm9wdGlvblwiICkgJiYgISFlbGVtLnNlbGVjdGVkICk7XG5cdFx0fSxcblxuXHRcdHNlbGVjdGVkOiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgPD0xMStcblx0XHRcdC8vIEFjY2Vzc2luZyB0aGUgc2VsZWN0ZWRJbmRleCBwcm9wZXJ0eVxuXHRcdFx0Ly8gZm9yY2VzIHRoZSBicm93c2VyIHRvIHRyZWF0IHRoZSBkZWZhdWx0IG9wdGlvbiBhc1xuXHRcdFx0Ly8gc2VsZWN0ZWQgd2hlbiBpbiBhbiBvcHRncm91cC5cblx0XHRcdGlmICggZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0Ly8gQ29udGVudHNcblx0XHRlbXB0eTogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2VtcHR5LXBzZXVkb1xuXHRcdFx0Ly8gOmVtcHR5IGlzIG5lZ2F0ZWQgYnkgZWxlbWVudCAoMSkgb3IgY29udGVudCBub2RlcyAodGV4dDogMzsgY2RhdGE6IDQ7IGVudGl0eSByZWY6IDUpLFxuXHRcdFx0Ly8gICBidXQgbm90IGJ5IG90aGVycyAoY29tbWVudDogODsgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbjogNzsgZXRjLilcblx0XHRcdC8vIG5vZGVUeXBlIDwgNiB3b3JrcyBiZWNhdXNlIGF0dHJpYnV0ZXMgKDIpIGRvIG5vdCBhcHBlYXIgYXMgY2hpbGRyZW5cblx0XHRcdGZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkge1xuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPCA2ICkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdHBhcmVudDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gIUV4cHIucHNldWRvcy5lbXB0eSggZWxlbSApO1xuXHRcdH0sXG5cblx0XHQvLyBFbGVtZW50L2lucHV0IHR5cGVzXG5cdFx0aGVhZGVyOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiByaGVhZGVyLnRlc3QoIGVsZW0ubm9kZU5hbWUgKTtcblx0XHR9LFxuXG5cdFx0aW5wdXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRidXR0b246IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIG5vZGVOYW1lKCBlbGVtLCBcImlucHV0XCIgKSAmJiBlbGVtLnR5cGUgPT09IFwiYnV0dG9uXCIgfHxcblx0XHRcdFx0bm9kZU5hbWUoIGVsZW0sIFwiYnV0dG9uXCIgKTtcblx0XHR9LFxuXG5cdFx0dGV4dDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgYXR0cjtcblx0XHRcdHJldHVybiBub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgJiYgZWxlbS50eXBlID09PSBcInRleHRcIiAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDwxMCBvbmx5XG5cdFx0XHRcdC8vIE5ldyBIVE1MNSBhdHRyaWJ1dGUgdmFsdWVzIChlLmcuLCBcInNlYXJjaFwiKSBhcHBlYXJcblx0XHRcdFx0Ly8gd2l0aCBlbGVtLnR5cGUgPT09IFwidGV4dFwiXG5cdFx0XHRcdCggKCBhdHRyID0gZWxlbS5nZXRBdHRyaWJ1dGUoIFwidHlwZVwiICkgKSA9PSBudWxsIHx8XG5cdFx0XHRcdFx0YXR0ci50b0xvd2VyQ2FzZSgpID09PSBcInRleHRcIiApO1xuXHRcdH0sXG5cblx0XHQvLyBQb3NpdGlvbi1pbi1jb2xsZWN0aW9uXG5cdFx0Zmlyc3Q6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIFsgMCBdO1xuXHRcdH0gKSxcblxuXHRcdGxhc3Q6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBfbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gWyBsZW5ndGggLSAxIF07XG5cdFx0fSApLFxuXG5cdFx0ZXE6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBfbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xuXHRcdFx0cmV0dXJuIFsgYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudCBdO1xuXHRcdH0gKSxcblxuXHRcdGV2ZW46IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHZhciBpID0gMDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9ICksXG5cblx0XHRvZGQ6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHZhciBpID0gMTtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9ICksXG5cblx0XHRsdDogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpO1xuXG5cdFx0XHRpZiAoIGFyZ3VtZW50IDwgMCApIHtcblx0XHRcdFx0aSA9IGFyZ3VtZW50ICsgbGVuZ3RoO1xuXHRcdFx0fSBlbHNlIGlmICggYXJndW1lbnQgPiBsZW5ndGggKSB7XG5cdFx0XHRcdGkgPSBsZW5ndGg7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpID0gYXJndW1lbnQ7XG5cdFx0XHR9XG5cblx0XHRcdGZvciAoIDsgLS1pID49IDA7ICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9ICksXG5cblx0XHRndDogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybi
1BtYXRjaEluZGV4ZXM7XG5cdFx0fSApXG5cdH1cbn07XG5cbkV4cHIucHNldWRvcy5udGggPSBFeHByLnBzZXVkb3MuZXE7XG5cbi8vIEFkZCBidXR0b24vaW5wdXQgdHlwZSBwc2V1ZG9zXG5mb3IgKCBpIGluIHsgcmFkaW86IHRydWUsIGNoZWNrYm94OiB0cnVlLCBmaWxlOiB0cnVlLCBwYXNzd29yZDogdHJ1ZSwgaW1hZ2U6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApO1xufVxuZm9yICggaSBpbiB7IHN1Ym1pdDogdHJ1ZSwgcmVzZXQ6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVCdXR0b25Qc2V1ZG8oIGkgKTtcbn1cblxuLy8gRWFzeSBBUEkgZm9yIGNyZWF0aW5nIG5ldyBzZXRGaWx0ZXJzXG5mdW5jdGlvbiBzZXRGaWx0ZXJzKCkge31cbnNldEZpbHRlcnMucHJvdG90eXBlID0gRXhwci5maWx0ZXJzID0gRXhwci5wc2V1ZG9zO1xuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcblxuZnVuY3Rpb24gdG9rZW5pemUoIHNlbGVjdG9yLCBwYXJzZU9ubHkgKSB7XG5cdHZhciBtYXRjaGVkLCBtYXRjaCwgdG9rZW5zLCB0eXBlLFxuXHRcdHNvRmFyLCBncm91cHMsIHByZUZpbHRlcnMsXG5cdFx0Y2FjaGVkID0gdG9rZW5DYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdO1xuXG5cdGlmICggY2FjaGVkICkge1xuXHRcdHJldHVybiBwYXJzZU9ubHkgPyAwIDogY2FjaGVkLnNsaWNlKCAwICk7XG5cdH1cblxuXHRzb0ZhciA9IHNlbGVjdG9yO1xuXHRncm91cHMgPSBbXTtcblx0cHJlRmlsdGVycyA9IEV4cHIucHJlRmlsdGVyO1xuXG5cdHdoaWxlICggc29GYXIgKSB7XG5cblx0XHQvLyBDb21tYSBhbmQgZmlyc3QgcnVuXG5cdFx0aWYgKCAhbWF0Y2hlZCB8fCAoIG1hdGNoID0gcmNvbW1hLmV4ZWMoIHNvRmFyICkgKSApIHtcblx0XHRcdGlmICggbWF0Y2ggKSB7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgY29uc3VtZSB0cmFpbGluZyBjb21tYXMgYXMgdmFsaWRcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hbIDAgXS5sZW5ndGggKSB8fCBzb0Zhcjtcblx0XHRcdH1cblx0XHRcdGdyb3Vwcy5wdXNoKCAoIHRva2VucyA9IFtdICkgKTtcblx0XHR9XG5cblx0XHRtYXRjaGVkID0gZmFsc2U7XG5cblx0XHQvLyBDb21iaW5hdG9yc1xuXHRcdGlmICggKCBtYXRjaCA9IHJsZWFkaW5nQ29tYmluYXRvci5leGVjKCBzb0ZhciApICkgKSB7XG5cdFx0XHRtYXRjaGVkID0gbWF0Y2guc2hpZnQoKTtcblx0XHRcdHRva2Vucy5wdXNoKCB7XG5cdFx0XHRcdHZhbHVlOiBtYXRjaGVkLFxuXG5cdFx0XHRcdC8vIENhc3QgZGVzY2VuZGFudCBjb21iaW5hdG9ycyB0byBzcGFjZVxuXHRcdFx0XHR0eXBlOiBtYXRjaFsgMCBdLnJlcGxhY2UoIHJ0cmltQ1NTLCBcIiBcIiApXG5cdFx0XHR9ICk7XG5cdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZpbHRlcnNcblx0XHRmb3IgKCB0eXBlIGluIEV4cHIuZmlsdGVyICkge1xuXHRcdFx0aWYgKCAoIG1hdGNoID0gbWF0Y2hFeHByWyB0eXBlIF0uZXhlYyggc29GYXIgKSApICYmICggIXByZUZpbHRlcnNbIHR5cGUgXSB8fFxuXHRcdFx0XHQoIG1hdGNoID0gcHJlRmlsdGVyc1sgdHlwZSBdKCBtYXRjaCApICkgKSApIHtcblx0XHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHRcdHRva2Vucy5wdXNoKCB7XG5cdFx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cdFx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0XHRtYXRjaGVzOiBtYXRjaFxuXHRcdFx0XHR9ICk7XG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoZWQubGVuZ3RoICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCAhbWF0Y2hlZCApIHtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXG5cdC8vIFJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBpbnZhbGlkIGV4Y2Vzc1xuXHQvLyBpZiB3ZSdyZSBqdXN0IHBhcnNpbmdcblx0Ly8gT3RoZXJ3aXNlLCB0aHJvdyBhbiBlcnJvciBvciByZXR1cm4gdG9rZW5zXG5cdGlmICggcGFyc2VPbmx5ICkge1xuXHRcdHJldHVybiBzb0Zhci5sZW5ndGg7XG5cdH1cblxuXHRyZXR1cm4gc29GYXIgP1xuXHRcdGZpbmQuZXJyb3IoIHNlbGVjdG9yICkgOlxuXG5cdFx0Ly8gQ2FjaGUgdGhlIHRva2Vuc1xuXHRcdHRva2VuQ2FjaGUoIHNlbGVjdG9yLCBncm91cHMgKS5zbGljZSggMCApO1xufVxuXG5mdW5jdGlvbiB0b1NlbGVjdG9yKCB0b2tlbnMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdHNlbGVjdG9yID0gXCJcIjtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0c2VsZWN0b3IgKz0gdG9rZW5zWyBpIF0udmFsdWU7XG5cdH1cblx0cmV0dXJuIHNlbGVjdG9yO1xufVxuXG5mdW5jdGlvbiBhZGRDb21iaW5hdG9yKCBtYXRjaGVyLCBjb21iaW5hdG9yLCBiYXNlICkge1xuXHR2YXIgZGlyID0gY29tYmluYXRvci5kaXIsXG5cdFx0c2tpcCA9IGNvbWJpbmF0b3IubmV4dCxcblx0XHRrZXkgPSBza2lwIHx8IGRpcixcblx0XHRjaGVja05vbkVsZW1lbnRzID0gYmFzZSAmJiBrZXkgPT09IFwicGFyZW50Tm9kZVwiLFxuXHRcdGRvbmVOYW1lID0gZG9uZSsrO1xuXG5cdHJldHVybiBjb21iaW5hdG9yLmZpcnN0ID9cblxuXHRcdC8vIENoZWNrIGFnYWluc3QgY2xvc2VzdCBhbmNlc3Rvci9wcmVjZWRpbmcgZWxlbWVudFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR3aGlsZSAoICggZWxlbSA9IGVsZW1bIGRpciBdICkgKSB7XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdHJldHVybiBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0gOlxuXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBhbGwgYW5jZXN0b3IvcHJlY2VkaW5nIGVsZW1lbnRzXG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBvbGRDYWNoZSwgb3V0ZXJDYWNoZSxcblx0XHRcdFx0bmV3Q2FjaGUgPSBbIGRpcnJ1bnMsIGRvbmVOYW1lIF07XG5cblx0XHRcdC8vIFdlIGNhbid0IHNldCBhcmJpdHJhcnkgZGF0YSBvbiBYTUwgbm9kZXMsIHNvIHRoZXkgZG9uJ3QgYmVuZWZpdCBmcm9tIGNvbWJpbmF0b3IgY2FjaGluZ1xuXHRcdFx0aWYgKCB4bWwgKSB7XG5cdFx0XHRcdHdoaWxlICggKCBlbGVtID0gZWxlbVsgZGlyIF0gKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybi
1B0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0d2hpbGUgKCAoIGVsZW0gPSBlbGVtWyBkaXIgXSApICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IGVsZW1bIGV4cGFuZG8gXSB8fCAoIGVsZW1bIGV4cGFuZG8gXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdGlmICggc2tpcCAmJiBub2RlTmFtZSggZWxlbSwgc2tpcCApICkge1xuXHRcdFx0XHRcdFx0XHRlbGVtID0gZWxlbVsgZGlyIF0gfHwgZWxlbTtcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoICggb2xkQ2FjaGUgPSBvdXRlckNhY2hlWyBrZXkgXSApICYmXG5cdFx0XHRcdFx0XHRcdG9sZENhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgb2xkQ2FjaGVbIDEgXSA9PT0gZG9uZU5hbWUgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQXNzaWduIHRvIG5ld0NhY2hlIHNvIHJlc3VsdHMgYmFjay1wcm9wYWdhdGUgdG8gcHJldmlvdXMgZWxlbWVudHNcblx0XHRcdFx0XHRcdFx0cmV0dXJuICggbmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0gKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gUmV1c2UgbmV3Y2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50c1xuXHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlWyBrZXkgXSA9IG5ld0NhY2hlO1xuXG5cdFx0XHRcdFx0XHRcdC8vIEEgbWF0Y2ggbWVhbnMgd2UncmUgZG9uZTsgYSBmYWlsIG1lYW5zIHdlIGhhdmUgdG8ga2VlcCBjaGVja2luZ1xuXHRcdFx0XHRcdFx0XHRpZiAoICggbmV3Q2FjaGVbIDIgXSA9IG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9O1xufVxuXG5mdW5jdGlvbiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSB7XG5cdHJldHVybiBtYXRjaGVycy5sZW5ndGggPiAxID9cblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIGkgPSBtYXRjaGVycy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAhbWF0Y2hlcnNbIGkgXSggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9IDpcblx0XHRtYXRjaGVyc1sgMCBdO1xufVxuXG5mdW5jdGlvbiBtdWx0aXBsZUNvbnRleHRzKCBzZWxlY3RvciwgY29udGV4dHMsIHJlc3VsdHMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSBjb250ZXh0cy5sZW5ndGg7XG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdGZpbmQoIHNlbGVjdG9yLCBjb250ZXh0c1sgaSBdLCByZXN1bHRzICk7XG5cdH1cblx0cmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIGNvbmRlbnNlKCB1bm1hdGNoZWQsIG1hcCwgZmlsdGVyLCBjb250ZXh0LCB4bWwgKSB7XG5cdHZhciBlbGVtLFxuXHRcdG5ld1VubWF0Y2hlZCA9IFtdLFxuXHRcdGkgPSAwLFxuXHRcdGxlbiA9IHVubWF0Y2hlZC5sZW5ndGgsXG5cdFx0bWFwcGVkID0gbWFwICE9IG51bGw7XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAoIGVsZW0gPSB1bm1hdGNoZWRbIGkgXSApICkge1xuXHRcdFx0aWYgKCAhZmlsdGVyIHx8IGZpbHRlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdG5ld1VubWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdGlmICggbWFwcGVkICkge1xuXHRcdFx0XHRcdG1hcC5wdXNoKCBpICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gbmV3VW5tYXRjaGVkO1xufVxuXG5mdW5jdGlvbiBzZXRNYXRjaGVyKCBwcmVGaWx0ZXIsIHNlbGVjdG9yLCBtYXRjaGVyLCBwb3N0RmlsdGVyLCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKSB7XG5cdGlmICggcG9zdEZpbHRlciAmJiAhcG9zdEZpbHRlclsgZXhwYW5kbyBdICkge1xuXHRcdHBvc3RGaWx0ZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmlsdGVyICk7XG5cdH1cblx0aWYgKCBwb3N0RmluZGVyICYmICFwb3N0RmluZGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0cG9zdEZpbmRlciA9IHNldE1hdGNoZXIoIHBvc3RGaW5kZXIsIHBvc3RTZWxlY3RvciApO1xuXHR9XG5cdHJldHVybiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWVkLCByZXN1bHRzLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0dmFyIHRlbXAsIGksIGVsZW0sIG1hdGNoZXJPdXQsXG5cdFx0XHRwcmVNYXAgPSBbXSxcblx0XHRcdHBvc3RNYXAgPSBbXSxcblx0XHRcdHByZWV4aXN0aW5nID0gcmVzdWx0cy5sZW5ndGgsXG5cblx0XHRcdC8vIEdldCBpbml0aWFsIGVsZW1lbnRzIGZyb20gc2VlZCBvciBjb250ZXh0XG5cdFx0XHRlbGVtcyA9IHNlZWQgfHxcblx0XHRcdFx0bXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IgfHwgXCIqXCIsXG5cdFx0XHRcdFx0Y29udGV4dC5ub2RlVHlwZSA/IFsgY29udGV4dCBdIDogY29udGV4dCwgW10gKSxcblxuXHRcdFx0Ly8gUHJlZmlsdGVyIHRvIGdldCBtYXRjaGVyIGlucHV0LCBwcmVzZXJ2aW5nIGEgbWFwIGZvciBzZWVkLXJlc3VsdHMgc3luY2hyb25pemF0aW9uXG5cdFx0XHRtYXRjaGVySW4gPSBwcmVGaWx0ZXIgJiYgKCBzZWVkIHx8ICFzZWxlY3RvciApID9cblx0XHRcdFx0Y29uZGVuc2UoIGVsZW1zLCBwcmVNYXAsIHByZUZpbHRlciwgY29udGV4dCwgeG1sICkgOlxuXHRcdFx0XHRlbGVtcztcblxuXHRcdGlmICggbWF0Y2hlciApIHtcblxuXHRcdFx0Ly8gSWYgd2UgaGF2ZSBhIHBvc3RGaW5kZXIsIG9yIGZpbHRlcmVkIHNlZWQsIG9yIG5vbi1zZWVkIHBvc3RGaWx0ZXJcblx0XHRcdC8vIG9yIHByZWV4aXN0aW5nIHJlc3VsdHMsXG5cdFx0XHRtYXRjaGVyT3V0ID0gcG9zdEZpbmRlciB8fCAoIHNlZWQgPyBwcmVGaWx0ZXIgOiBwcmVleGlzdGluZyB8fCBwb3N0RmlsdGVyICkgP1xuXG5cdFx0XHRcdC8vIC4uLmludGVybWVkaWF0ZSBwcm9jZXNzaW5nIGlzIG5lY2Vzc2FyeVxuXHRcdFx0XHRbXSA6XG5cblx0XHRcdFx0Ly8gLi4ub3RoZXJ3aXNlI
1HVzZSByZXN1bHRzIGRpcmVjdGx5XG5cdFx0XHRcdHJlc3VsdHM7XG5cblx0XHRcdC8vIEZpbmQgcHJpbWFyeSBtYXRjaGVzXG5cdFx0XHRtYXRjaGVyKCBtYXRjaGVySW4sIG1hdGNoZXJPdXQsIGNvbnRleHQsIHhtbCApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyT3V0ID0gbWF0Y2hlckluO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHBvc3RGaWx0ZXJcblx0XHRpZiAoIHBvc3RGaWx0ZXIgKSB7XG5cdFx0XHR0ZW1wID0gY29uZGVuc2UoIG1hdGNoZXJPdXQsIHBvc3RNYXAgKTtcblx0XHRcdHBvc3RGaWx0ZXIoIHRlbXAsIFtdLCBjb250ZXh0LCB4bWwgKTtcblxuXHRcdFx0Ly8gVW4tbWF0Y2ggZmFpbGluZyBlbGVtZW50cyBieSBtb3ZpbmcgdGhlbSBiYWNrIHRvIG1hdGNoZXJJblxuXHRcdFx0aSA9IHRlbXAubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggKCBlbGVtID0gdGVtcFsgaSBdICkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlck91dFsgcG9zdE1hcFsgaSBdIF0gPSAhKCBtYXRjaGVySW5bIHBvc3RNYXBbIGkgXSBdID0gZWxlbSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWVkICkge1xuXHRcdFx0aWYgKCBwb3N0RmluZGVyIHx8IHByZUZpbHRlciApIHtcblx0XHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xuXG5cdFx0XHRcdFx0Ly8gR2V0IHRoZSBmaW5hbCBtYXRjaGVyT3V0IGJ5IGNvbmRlbnNpbmcgdGhpcyBpbnRlcm1lZGlhdGUgaW50byBwb3N0RmluZGVyIGNvbnRleHRzXG5cdFx0XHRcdFx0dGVtcCA9IFtdO1xuXHRcdFx0XHRcdGkgPSBtYXRjaGVyT3V0Lmxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGlmICggKCBlbGVtID0gbWF0Y2hlck91dFsgaSBdICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gUmVzdG9yZSBtYXRjaGVySW4gc2luY2UgZWxlbSBpcyBub3QgeWV0IGEgZmluYWwgbWF0Y2hcblx0XHRcdFx0XHRcdFx0dGVtcC5wdXNoKCAoIG1hdGNoZXJJblsgaSBdID0gZWxlbSApICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHBvc3RGaW5kZXIoIG51bGwsICggbWF0Y2hlck91dCA9IFtdICksIHRlbXAsIHhtbCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gTW92ZSBtYXRjaGVkIGVsZW1lbnRzIGZyb20gc2VlZCB0byByZXN1bHRzIHRvIGtlZXAgdGhlbSBzeW5jaHJvbml6ZWRcblx0XHRcdFx0aSA9IG1hdGNoZXJPdXQubGVuZ3RoO1xuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRpZiAoICggZWxlbSA9IG1hdGNoZXJPdXRbIGkgXSApICYmXG5cdFx0XHRcdFx0XHQoIHRlbXAgPSBwb3N0RmluZGVyID8gaW5kZXhPZi5jYWxsKCBzZWVkLCBlbGVtICkgOiBwcmVNYXBbIGkgXSApID4gLTEgKSB7XG5cblx0XHRcdFx0XHRcdHNlZWRbIHRlbXAgXSA9ICEoIHJlc3VsdHNbIHRlbXAgXSA9IGVsZW0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEFkZCBlbGVtZW50cyB0byByZXN1bHRzLCB0aHJvdWdoIHBvc3RGaW5kZXIgaWYgZGVmaW5lZFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyT3V0ID0gY29uZGVuc2UoXG5cdFx0XHRcdG1hdGNoZXJPdXQgPT09IHJlc3VsdHMgP1xuXHRcdFx0XHRcdG1hdGNoZXJPdXQuc3BsaWNlKCBwcmVleGlzdGluZywgbWF0Y2hlck91dC5sZW5ndGggKSA6XG5cdFx0XHRcdFx0bWF0Y2hlck91dFxuXHRcdFx0KTtcblx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgcmVzdWx0cywgbWF0Y2hlck91dCwgeG1sICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBtYXRjaGVyT3V0ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMgKSB7XG5cdHZhciBjaGVja0NvbnRleHQsIG1hdGNoZXIsIGosXG5cdFx0bGVuID0gdG9rZW5zLmxlbmd0aCxcblx0XHRsZWFkaW5nUmVsYXRpdmUgPSBFeHByLnJlbGF0aXZlWyB0b2tlbnNbIDAgXS50eXBlIF0sXG5cdFx0aW1wbGljaXRSZWxhdGl2ZSA9IGxlYWRpbmdSZWxhdGl2ZSB8fCBFeHByLnJlbGF0aXZlWyBcIiBcIiBdLFxuXHRcdGkgPSBsZWFkaW5nUmVsYXRpdmUgPyAxIDogMCxcblxuXHRcdC8vIFRoZSBmb3VuZGF0aW9uYWwgbWF0Y2hlciBlbnN1cmVzIHRoYXQgZWxlbWVudHMgYXJlIHJlYWNoYWJsZSBmcm9tIHRvcC1sZXZlbCBjb250ZXh0KHMpXG5cdFx0bWF0Y2hDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gY2hlY2tDb250ZXh0O1xuXHRcdH0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSxcblx0XHRtYXRjaEFueUNvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGNoZWNrQ29udGV4dCwgZWxlbSApID4gLTE7XG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxuXHRcdG1hdGNoZXJzID0gWyBmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0dmFyIHJldCA9ICggIWxlYWRpbmdSZWxhdGl2ZSAmJiAoIHhtbCB8fCBjb250ZXh0ICE9IG91dGVybW9zdENvbnRleHQgKSApIHx8IChcblx0XHRcdFx0KCBjaGVja0NvbnRleHQgPSBjb250ZXh0ICkubm9kZVR5cGUgP1xuXHRcdFx0XHRcdG1hdGNoQ29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgOlxuXHRcdFx0XHRcdG1hdGNoQW55Q29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgKTtcblxuXHRcdFx0Ly8gQXZvaWQgaGFuZ2luZyBvbnRvIGVsZW1lbnRcblx0XHRcdC8vIChzZWUgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9zaXp6bGUvaXNzdWVzLzI5OSlcblx0XHRcdGNoZWNrQ29udGV4dCA9IG51bGw7XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH0gXTtcblxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRpZiAoICggbWF0Y2hlciA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1sgaSBdLnR5cGUgXSApICkge1xuXHRcdFx0bWF0Y2hlcnMgPSBbIGFkZENvbWJpbmF0b3IoIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLCBtYXRjaGVyICkgXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWF0Y2hlciA9IEV4cHIuZmlsdGVyWyB0b2tlbnNbIGkgXS50eXBlIF0uYXBwbHkoIG51bGwsIHRva2Vuc1sgaSBdLm1hdGNoZXMgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIHNwZWNpYWwgdXBvbiBzZWVpbmcgYSBwb3NpdGlvbmFsIG1hdGNoZXJcblx0XHRcdGlmICggbWF0Y2hlclsgZXhwYW5kbyBdICkge1xuXG5cdFx0XHRcdC8vIEZpbmQgdGhlIG5leHQgcmVsYXRpdmUgb3BlcmF0b3IgKGlmIGFueSkgZm9yIHByb3BlciBoYW5kbGluZ1xuXHRcdFx0XHRqID0gKytpO1xuXHRcdFx0XHRmb3IgKCA7IGogPCBsZW47IGorKyApIHtcblx0XHRcdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbIHRva2Vuc1sgaiBdLnR5cGUgXSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gc2V0TWF0Y2hlcihcblx0XHRcdFx0XHRpID4gMSAmJiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSxcblx0XHRcdFx0XHRpID4gMSAmJiB0b1NlbGVjdG9yKFxuXG5cdFx0XHRcdFx0XHQvLyBJZiB0aGUgcHJlY2VkaW5nIHRva2VuIHdhcyBhIGRlc2NlbmRhbnQgY29tYmluYXRvciwgaW5zZXJ0IGFuIGltcGxpY2l0IGFueS1lbGVtZW50IGAqYFxuXHRcdFx0XHRcdFx0dG9rZW5zLnNsaWNlKCAwLCBpIC0gMSApXG5cdFx0XHRcdFx0XHRcdC5jb25jYXQoIHsgdmFsdWU6IHRva2Vuc1sgaSAtIDIgXS50eXBlID09PSBcIiBcIiA/IFwiKlwiIDogXCJcIiB9IClcblx0XHRcdFx0XHQpLnJlcGxhY2UoIHJ0cmltQ1NTLCBcIiQxXCIgKSxcblx0XHRcdFx0XHRtYXRjaGVyLFxuXHRcdFx0XHRcdGkgPCBqICYmIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMuc2xpY2UoIGksIGogKSApLFxuXHRcdFx0XHRcdGogPCBsZW4gJiYgbWF0Y2hlckZyb21Ub2tlbnMoICggdG9rZW5zID0gdG9rZW5zLnNsaWNlKCBqICkgKSApLFxuXHRcdFx0XHRcdGogPCBsZW4gJiYgdG9TZWxlY3RvciggdG9rZW5zIClcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHRcdG1hdGNoZXJzLnB1c2goIG1hdGNoZXIgKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApIHtcblx0dmFyIGJ5U2V0ID0gc2V0TWF0Y2hlcnMubGVuZ3RoID4gMCxcblx0XHRieUVsZW1lbnQgPSBlbGVtZW50TWF0Y2hlcnMubGVuZ3RoID4gMCxcblx0XHRzdXBlck1hdGNoZXIgPSBmdW5jdGlvbiggc2VlZCwgY29udGV4dCwgeG1sLCByZXN1bHRzLCBvdXRlcm1vc3QgKSB7XG5cdFx0XHR2YXIgZWxlbSwgaiwgbWF0Y2hlcixcblx0XHRcdFx0bWF0Y2hlZENvdW50ID0gMCxcblx0XHRcdFx0aSA9IFwiMFwiLFxuXHRcdFx0XHR1bm1hdGNoZWQgPSBzZWVkICYmIFtdLFxuXHRcdFx0XHRzZXRNYXRjaGVkID0gW10sXG5cdFx0XHRcdGNvbnRleHRCYWNrdXAgPSBvdXRlcm1vc3RDb250ZXh0LFxuXG5cdFx0XHRcdC8vIFdlIG11c3QgYWx3YXlzIGhhdmUgZWl0aGVyIHNlZWQgZWxlbWVudHMgb3Igb3V0ZXJtb3N0IGNvbnRleHRcblx0XHRcdFx0ZWxlbXMgPSBzZWVkIHx8IGJ5RWxlbWVudCAmJiBFeHByLmZpbmQuVEFHKCBcIipcIiwgb3V0ZXJtb3N0ICksXG5cblx0XHRcdFx0Ly8gVXNlIGludGVnZXIgZGlycnVucyBpZmYgdGhpcyBpcyB0aGUgb3V0ZXJtb3N0IG1hdGNoZXJcblx0XHRcdFx0ZGlycnVuc1VuaXF1ZSA9ICggZGlycnVucyArPSBjb250ZXh0QmFja3VwID09IG51bGwgPyAxIDogTWF0aC5yYW5kb20oKSB8fCAwLjEgKSxcblx0XHRcdFx0bGVuID0gZWxlbXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHRcdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dCA9PSBkb2N1bWVudCB8fCBjb250ZXh0IHx8IG91dGVybW9zdDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIGVsZW1lbnRzIHBhc3NpbmcgZWxlbWVudE1hdGNoZXJzIGRpcmVjdGx5IHRvIHJlc3VsdHNcblx0XHRcdC8vIFN1cHBvcnQ6IGlPUyA8PTcgLSA5IG9ubHlcblx0XHRcdC8vIFRvbGVyYXRlIE5vZGVMaXN0IH
1Byb3BlcnRpZXMgKElFOiBcImxlbmd0aFwiOyBTYWZhcmk6IDxudW1iZXI+KSBtYXRjaGluZ1xuXHRcdFx0Ly8gZWxlbWVudHMgYnkgaWQuIChzZWUgdHJhYy0xNDE0Milcblx0XHRcdGZvciAoIDsgaSAhPT0gbGVuICYmICggZWxlbSA9IGVsZW1zWyBpIF0gKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggYnlFbGVtZW50ICYmIGVsZW0gKSB7XG5cdFx0XHRcdFx0aiA9IDA7XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdFx0XHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0XHRcdFx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0XHRcdGlmICggIWNvbnRleHQgJiYgZWxlbS5vd25lckRvY3VtZW50ICE9IGRvY3VtZW50ICkge1xuXHRcdFx0XHRcdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblx0XHRcdFx0XHRcdHhtbCA9ICFkb2N1bWVudElzSFRNTDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0d2hpbGUgKCAoIG1hdGNoZXIgPSBlbGVtZW50TWF0Y2hlcnNbIGorKyBdICkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQgfHwgZG9jdW1lbnQsIHhtbCApICkge1xuXHRcdFx0XHRcdFx0XHRwdXNoLmNhbGwoIHJlc3VsdHMsIGVsZW0gKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRcdFx0ZGlycnVucyA9IGRpcnJ1bnNVbmlxdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gVHJhY2sgdW5tYXRjaGVkIGVsZW1lbnRzIGZvciBzZXQgZmlsdGVyc1xuXHRcdFx0XHRpZiAoIGJ5U2V0ICkge1xuXG5cdFx0XHRcdFx0Ly8gVGhleSB3aWxsIGhhdmUgZ29uZSB0aHJvdWdoIGFsbCBwb3NzaWJsZSBtYXRjaGVyc1xuXHRcdFx0XHRcdGlmICggKCBlbGVtID0gIW1hdGNoZXIgJiYgZWxlbSApICkge1xuXHRcdFx0XHRcdFx0bWF0Y2hlZENvdW50LS07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gTGVuZ3RoZW4gdGhlIGFycmF5IGZvciBldmVyeSBlbGVtZW50LCBtYXRjaGVkIG9yIG5vdFxuXHRcdFx0XHRcdGlmICggc2VlZCApIHtcblx0XHRcdFx0XHRcdHVubWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIGBpYCBpcyBub3cgdGhlIGNvdW50IG9mIGVsZW1lbnRzIHZpc2l0ZWQgYWJvdmUsIGFuZCBhZGRpbmcgaXQgdG8gYG1hdGNoZWRDb3VudGBcblx0XHRcdC8vIG1ha2VzIHRoZSBsYXR0ZXIgbm9ubmVnYXRpdmUuXG5cdFx0XHRtYXRjaGVkQ291bnQgKz0gaTtcblxuXHRcdFx0Ly8gQXBwbHkgc2V0IGZpbHRlcnMgdG8gdW5tYXRjaGVkIGVsZW1lbnRzXG5cdFx0XHQvLyBOT1RFOiBUaGlzIGNhbiBiZSBza2lwcGVkIGlmIHRoZXJlIGFyZSBubyB1bm1hdGNoZWQgZWxlbWVudHMgKGkuZS4sIGBtYXRjaGVkQ291bnRgXG5cdFx0XHQvLyBlcXVhbHMgYGlgKSwgdW5sZXNzIHdlIGRpZG4ndCB2aXNpdCBfYW55XyBlbGVtZW50cyBpbiB0aGUgYWJvdmUgbG9vcCBiZWNhdXNlIHdlIGhhdmVcblx0XHRcdC8vIG5vIGVsZW1lbnQgbWF0Y2hlcnMgYW5kIG5vIHNlZWQuXG5cdFx0XHQvLyBJbmNyZW1lbnRpbmcgYW4gaW5pdGlhbGx5LXN0cmluZyBcIjBcIiBgaWAgYWxsb3dzIGBpYCB0byByZW1haW4gYSBzdHJpbmcgb25seSBpbiB0aGF0XG5cdFx0XHQvLyBjYXNlLCB3aGljaCB3aWxsIHJlc3VsdCBpbiBhIFwiMDBcIiBgbWF0Y2hlZENvdW50YCB0aGF0IGRpZmZlcnMgZnJvbSBgaWAgYnV0IGlzIGFsc29cblx0XHRcdC8vIG51bWVyaWNhbGx5IHplcm8uXG5cdFx0XHRpZiAoIGJ5U2V0ICYmIGkgIT09IG1hdGNoZWRDb3VudCApIHtcblx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdHdoaWxlICggKCBtYXRjaGVyID0gc2V0TWF0Y2hlcnNbIGorKyBdICkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlciggdW5tYXRjaGVkLCBzZXRNYXRjaGVkLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggc2VlZCApIHtcblxuXHRcdFx0XHRcdC8vIFJlaW50ZWdyYXRlIGVsZW1lbnQgbWF0Y2hlcyB0byBlbGltaW5hdGUgdGhlIG5lZWQgZm9yIHNvcnRpbmdcblx0XHRcdFx0XHRpZiAoIG1hdGNoZWRDb3VudCA+IDAgKSB7XG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCAhKCB1bm1hdGNoZWRbIGkgXSB8fCBzZXRNYXRjaGVkWyBpIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHRzZXRNYXRjaGVkWyBpIF0gPSBwb3AuY2FsbCggcmVzdWx0cyApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gRGlzY2FyZCBpbmRleCBwbGFjZWhvbGRlciB2YWx1ZXMgdG8gZ2V0IG9ubHkgYWN0dWFsIG1hdGNoZXNcblx0XHRcdFx0XHRzZXRNYXRjaGVkID0gY29uZGVuc2UoIHNldE1hdGNoZWQgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFkZCBtYXRjaGVzIHRvIHJlc3VsdHNcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2V0TWF0Y2hlZCApO1xuXG5cdFx0XHRcdC8vIFNlZWRsZXNzIHNldCBtYXRjaGVzIHN1Y2NlZWRpbmcgbXVsdGlwbGUgc3VjY2Vzc2Z1bCBtYXRjaGVycyBzdGlwdWxhdGUgc29ydGluZ1xuXHRcdFx0XHRpZiAoIG91dGVybW9zdCAmJiAhc2VlZCAmJiBzZXRNYXRjaGVkLmxlbmd0aCA+IDAgJiZcblx0XHRcdFx0XHQoIG1hdGNoZWRDb3VudCArIHNldE1hdGNoZXJzLmxlbmd0aCApID4gMSApIHtcblxuXHRcdFx0XHRcdGpRdWVyeS51bmlxdWVTb3J0KCByZXN1bHRzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gT3ZlcnJpZGUgbWFuaXB1bGF0aW9uIG9mIGdsb2JhbHMgYnkgbmVzdGVkIG1hdGNoZXJzXG5cdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0ZGlycnVucyA9IGRpcnJ1bnNVbmlxdWU7XG5cdFx0XHRcdG91dGVybW9zdENvbnRleHQgPSBjb250ZXh0QmFja3VwO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdW5tYXRjaGVkO1xuXHRcdH07XG5cblx0cmV0dXJuIGJ5U2V0ID9cblx0XHRtYXJrRnVuY3Rpb24oIHN1cGVyTWF0Y2hlciApIDpcblx0XHRzdXBlck1hdGNoZXI7XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGUoIHNlbGVjdG9yLCBtYXRjaCAvKiBJbnRlcm5hbCBVc2UgT25seSAqLyApIHtcblx0dmFyIGksXG5cdFx0c2V0TWF0Y2hlcnMgPSBbXSxcblx0XHRlbGVtZW50TWF0Y2hlcnMgPSBbXSxcblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCAhY2FjaGVkICkge1xuXG5cdFx0Ly8gR2VuZXJhdGUgYSBmdW5jdGlvbiBvZiByZWN1cnNpdmUgZnVuY3Rpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gY2hlY2sgZWFjaCBlbGVtZW50XG5cdFx0aWYgKCAhbWF0Y2ggKSB7XG5cdFx0XHRtYXRjaCA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXHRcdH1cblx0XHRpID0gbWF0Y2gubGVuZ3RoO1xuXHRcdHd
1oaWxlICggaS0tICkge1xuXHRcdFx0Y2FjaGVkID0gbWF0Y2hlckZyb21Ub2tlbnMoIG1hdGNoWyBpIF0gKTtcblx0XHRcdGlmICggY2FjaGVkWyBleHBhbmRvIF0gKSB7XG5cdFx0XHRcdHNldE1hdGNoZXJzLnB1c2goIGNhY2hlZCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbWVudE1hdGNoZXJzLnB1c2goIGNhY2hlZCApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENhY2hlIHRoZSBjb21waWxlZCBmdW5jdGlvblxuXHRcdGNhY2hlZCA9IGNvbXBpbGVyQ2FjaGUoIHNlbGVjdG9yLFxuXHRcdFx0bWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkgKTtcblxuXHRcdC8vIFNhdmUgc2VsZWN0b3IgYW5kIHRva2VuaXphdGlvblxuXHRcdGNhY2hlZC5zZWxlY3RvciA9IHNlbGVjdG9yO1xuXHR9XG5cdHJldHVybiBjYWNoZWQ7XG59XG5cbi8qKlxuICogQSBsb3ctbGV2ZWwgc2VsZWN0aW9uIGZ1bmN0aW9uIHRoYXQgd29ya3Mgd2l0aCBqUXVlcnkncyBjb21waWxlZFxuICogIHNlbGVjdG9yIGZ1bmN0aW9uc1xuICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHNlbGVjdG9yIEEgc2VsZWN0b3Igb3IgYSBwcmUtY29tcGlsZWRcbiAqICBzZWxlY3RvciBmdW5jdGlvbiBidWlsdCB3aXRoIGpRdWVyeSBzZWxlY3RvciBjb21waWxlXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGNvbnRleHRcbiAqIEBwYXJhbSB7QXJyYXl9IFtyZXN1bHRzXVxuICogQHBhcmFtIHtBcnJheX0gW3NlZWRdIEEgc2V0IG9mIGVsZW1lbnRzIHRvIG1hdGNoIGFnYWluc3RcbiAqL1xuZnVuY3Rpb24gc2VsZWN0KCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcblx0dmFyIGksIHRva2VucywgdG9rZW4sIHR5cGUsIGZpbmQsXG5cdFx0Y29tcGlsZWQgPSB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiAmJiBzZWxlY3Rvcixcblx0XHRtYXRjaCA9ICFzZWVkICYmIHRva2VuaXplKCAoIHNlbGVjdG9yID0gY29tcGlsZWQuc2VsZWN0b3IgfHwgc2VsZWN0b3IgKSApO1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFRyeSB0byBtaW5pbWl6ZSBvcGVyYXRpb25zIGlmIHRoZXJlIGlzIG9ubHkgb25lIHNlbGVjdG9yIGluIHRoZSBsaXN0IGFuZCBubyBzZWVkXG5cdC8vICh0aGUgbGF0dGVyIG9mIHdoaWNoIGd1YXJhbnRlZXMgdXMgY29udGV4dClcblx0aWYgKCBtY
1XRjaC5sZW5ndGggPT09IDEgKSB7XG5cblx0XHQvLyBSZWR1Y2UgY29udGV4dCBpZiB0aGUgbGVhZGluZyBjb21wb3VuZCBzZWxlY3RvciBpcyBhbiBJRFxuXHRcdHRva2VucyA9IG1hdGNoWyAwIF0gPSBtYXRjaFsgMCBdLnNsaWNlKCAwICk7XG5cdFx0aWYgKCB0b2tlbnMubGVuZ3RoID4gMiAmJiAoIHRva2VuID0gdG9rZW5zWyAwIF0gKS50eXBlID09PSBcIklEXCIgJiZcblx0XHRcdFx0Y29udGV4dC5ub2RlVHlwZSA9PT0gOSAmJiBkb2N1bWVudElzSFRNTCAmJiBFeHByLnJlbGF0aXZlWyB0b2tlbnNbIDEgXS50eXBlIF0gKSB7XG5cblx0XHRcdGNvbnRleHQgPSAoIEV4cHIuZmluZC5JRChcblx0XHRcdFx0dG9rZW4ubWF0Y2hlc1sgMCBdLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICksXG5cdFx0XHRcdGNvbnRleHRcblx0XHRcdCkgfHwgW10gKVsgMCBdO1xuXHRcdFx0aWYgKCAhY29udGV4dCApIHtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cblx0XHRcdC8vIFByZWNvbXBpbGVkIG1hdGNoZXJzIHdpbGwgc3RpbGwgdmVyaWZ5IGFuY2VzdHJ5LCBzbyBzdGVwIHVwIGEgbGV2ZWxcblx0XHRcdH0gZWxzZSBpZiAoIGNvbXBpbGVkICkge1xuXHRcdFx0XHRjb250ZXh0ID0gY29udGV4dC5wYXJlbnROb2RlO1xuXHRcdFx0fVxuXG5cdFx0XHRzZWxlY3RvciA9IHNlbGVjdG9yLnNsaWNlKCB0b2tlbnMuc2hpZnQoKS52YWx1ZS5sZW5ndGggKTtcblx0XHR9XG5cblx0XHQvLyBGZXRjaCBhIHNlZWQgc2V0IGZvciByaWdodC10by1sZWZ0IG1hdGNoaW5nXG5cdFx0aSA9IG1hdGNoRXhwci5uZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSA/IDAgOiB0b2tlbnMubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0dG9rZW4gPSB0b2tlbnNbIGkgXTtcblxuXHRcdFx0Ly8gQWJvcnQgaWYgd2UgaGl0IGEgY29tYmluYXRvclxuXHRcdFx0aWYgKCBFeHByLnJlbGF0aXZlWyAoIHR5cGUgPSB0b2tlbi50eXBlICkgXSApIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoICggZmluZCA9IEV4cHIuZmluZFsgdHlwZSBdICkgKSB7XG5cblx0XHRcdFx0Ly8gU2VhcmNoLCBleHBhbmRpbmcgY29udGV4dCBmb3IgbGVhZGluZyBzaWJsaW5nIGNvbWJpbmF0b3JzXG5cdFx0XHRcdGlmICggKCBzZWVkID0gZmluZChcblx0XHRcdFx0XHR0b2tlbi5tYXRjaGVzWyAwIF0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKSxcblx0XHRcdFx0XHRyc2libGluZy50ZXN0KCB0b2tlbnNbIDAgXS50eXBlICkgJiZcblx0XHRcdFx0XHRcdHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0XG5cdFx0XHRcdCkgKSApIHtcblxuXHRcdFx0XHRcdC8vIElmIHNlZWQgaXMgZW1wdHkgb3Igbm8gdG9rZW5zIHJlbWFpbiwgd2UgY2FuIHJldHVybiBlYXJseVxuXHRcdFx0XHRcdHRva2Vucy5zcGxpY2UoIGksIDEgKTtcblx0XHRcdFx0XHRzZWxlY3RvciA9IHNlZWQubGVuZ3RoICYmIHRvU2VsZWN0b3IoIHRva2VucyApO1xuXHRcdFx0XHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2VlZCApO1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBDb21waWxlIGFuZCBleGVjdXRlIGEgZmlsdGVyaW5nIGZ1bmN0aW9uIGlmIG9uZSBpcyBub3QgcHJvdmlkZWRcblx0Ly8gUHJvdmlkZSBgbWF0Y2hgIHRvIGF2b2lkIHJldG9rZW5pemF0aW9uIGlmIHdlIG1vZGlmaWVkIHRoZSBzZWxlY3RvciBhYm92ZVxuXHQoIGNvbXBpbGVkIHx8IGNvbXBpbGUoIHNlbGVjdG9yLCBtYXRjaCApICkoXG5cdFx0c2VlZCxcblx0XHRjb250ZXh0LFxuXHRcdCFkb2N1bWVudElzSFRNTCxcblx0XHRyZXN1bHRzLFxuXHRcdCFjb250ZXh0IHx8IHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcblx0KTtcblx0cmV0dXJuIHJlc3VsdHM7XG59XG5cbi8vIE9uZS10aW1lIGFzc2lnbm1lbnRzXG5cbi8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgLSA0LjErXG4vLyBTb3J0IHN0YWJpbGl0eVxuc3VwcG9ydC5zb3J0U3RhYmxlID0gZXhwYW5kby5zcGxpdCggXCJcIiApLnNvcnQoIHNvcnRPcmRlciApLmpvaW4oIFwiXCIgKSA9PT0gZXhwYW5kbztcblxuLy8gSW5pdGlhbGl6ZSBhZ2FpbnN0IHRoZSBkZWZhdWx0IGRvY3VtZW50XG5zZXREb2N1bWVudCgpO1xuXG4vLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIC0gNC4xK1xuLy8gRGV0YWNoZWQgbm9kZXMgY29uZm91bmRpbmdseSBmb2xsb3cgKmVhY2ggb3RoZXIqXG5zdXBwb3J0LnNvcnREZXRhY2hlZCA9IGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXG5cdC8vIFNob3VsZCByZXR1cm4gMSwgYnV0IHJldHVybnMgNCAoZm9sbG93aW5nKVxuXHRyZXR1cm4gZWwuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZmllbGRzZXRcIiApICkgJiAxO1xufSApO1xuXG5qUXVlcnkuZmluZCA9IGZpbmQ7XG5cbi8vIERlcHJlY2F0ZWRcbmpRdWVyeS5leHByWyBcIjpcIiBdID0galF1ZXJ5LmV4cHIucHNldWRvcztcbmpRdWVyeS51bmlxdWUgPSBqUXVlcnkudW5pcXVlU29ydDtcblxuLy8gVGhlc2UgaGF2ZSBhbHdheXMgYmVlbiBwcml2YXRlLCBidXQgdGhleSB1c2VkIHRvIGJlIGRvY3VtZW50ZWQgYXMgcGFydCBvZlxuLy8gU2l6emxlIHNvIGxldCdzIG1haW50YWluIHRoZW0gZm9yIG5vdyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgcHVycG9zZXMuXG5maW5kLmNvbXBpbGUgPSBjb21waWxlO1xuZmluZC5zZWxlY3QgPSBzZWxlY3Q7XG5maW5kLnNldERvY3VtZW50ID0gc2V0RG9jdW1lbnQ7XG5maW5kLnRva2VuaXplID0gdG9rZW5pemU7XG5cbmZpbmQuZXNjYXBlID0galF1ZXJ5LmVzY2FwZVNlbGVjdG9yO1xuZmluZC5nZXRUZXh0ID0galF1ZXJ5LnRleHQ7XG5maW5kLmlzWE1MID0galF1ZXJ5LmlzWE1MRG9jO1xuZmluZC5zZWxlY3RvcnMgPSBqUXVlcnkuZXhwcjtcbmZpbmQuc3VwcG9ydCA9IGpRdWVyeS5zdXBwb3J0O1xuZmluZC51bmlxdWVTb3J0ID0galF1ZXJ5LnVuaXF1ZVNvcnQ7XG5cblx0LyogZXNsaW50LWVuYWJsZSAqL1xuXG59ICkoKTtcblxuXG52YXIgZGlyID0gZnVuY3Rpb24oIGVsZW0sIGRpciwgdW50aWwgKSB7XG5cdHZhciBtYXRjaGVkID0gW10sXG5cdFx0dHJ1bmNhdGUgPSB1bnRpbCAhPT0gdW5kZWZpbmVkO1xuXG5cdHdoaWxlICggKCBlbGVtID0gZWxlbVsgZGlyIF0gKSAmJiBlbGVtLm5vZGVUeXBlICE9PSA5ICkge1xuXHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdGlmICggdHJ1bmNhdGUgJiYgalF1ZXJ5KCBlbGVtICkuaXMoIHVudGlsICkgKSB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0bWF0Y2hlZC5wdXNoKCBlbGVtICk7XG5cdFx0fVxuXHR9XG5cdHJldHVybi
1BtYXRjaGVkO1xufTtcblxuXG52YXIgc2libGluZ3MgPSBmdW5jdGlvbiggbiwgZWxlbSApIHtcblx0dmFyIG1hdGNoZWQgPSBbXTtcblxuXHRmb3IgKCA7IG47IG4gPSBuLm5leHRTaWJsaW5nICkge1xuXHRcdGlmICggbi5ub2RlVHlwZSA9PT0gMSAmJiBuICE9PSBlbGVtICkge1xuXHRcdFx0bWF0Y2hlZC5wdXNoKCBuICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG1hdGNoZWQ7XG59O1xuXG5cbnZhciBybmVlZHNDb250ZXh0ID0galF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0O1xuXG52YXIgcnNpbmdsZVRhZyA9ICggL148KFthLXpdW15cXC9cXDA+OlxceDIwXFx0XFxyXFxuXFxmXSopW1xceDIwXFx0XFxyXFxuXFxmXSpcXC8/Pig/OjxcXC9cXDE+fCkkL2kgKTtcblxuXG5cbi8vIEltcGxlbWVudCB0aGUgaWRlbnRpY2FsIGZ1bmN0aW9uYWxpdHkgZm9yIGZpbHRlciBhbmQgbm90XG5mdW5jdGlvbiB3aW5ub3coIGVsZW1lbnRzLCBxdWFsaWZpZXIsIG5vdCApIHtcblx0aWYgKCBpc0Z1bmN0aW9uKCBxdWFsaWZpZXIgKSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSwgaSApIHtcblx0XHRcdHJldHVybiAhIXF1YWxpZmllci5jYWxsKCBlbGVtLCBpLCBlbGVtICkgIT09IG5vdDtcblx0XHR9ICk7XG5cdH1cblxuXHQvLyBTaW5nbGUgZWxlbWVudFxuXHRpZiAoIHF1YWxpZmllci5ub2RlVHlwZSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiAoIGVsZW0gPT09IHF1YWxpZmllciApICE9PSBub3Q7XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gQXJyYXlsaWtlIG9mIGVsZW1lbnRzIChqUXVlcnksIGFyZ3VtZW50cywgQXJyYXkpXG5cdGlmICggdHlwZW9mIHF1YWxpZmllciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiAoIGluZGV4T2YuY2FsbCggcXVhbGlmaWVyLCBlbGVtICkgPiAtMSApICE9PSBub3Q7XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gRmlsdGVyZWQgZGlyZWN0bHkgZm9yIGJvdGggc2ltcGxlIGFuZCBjb21wbGV4IHNlbGVjdG9yc1xuXHRyZXR1cm4galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cywgbm90ICk7XG59XG5cbmpRdWVyeS5maWx0ZXIgPSBmdW5jdGlvbiggZXhwciwgZWxlbXMsIG5vdCApIHtcblx0dmFyIGVsZW0gPSBlbGVtc1sgMCBdO1xuXG5cdGlmICggbm90ICkge1xuXHRcdGV4cHIgPSBcIjpub3QoXCIgKyBleHByICsgXCIpXCI7XG5cdH1cblxuXHRpZiAoIGVsZW1zLmxlbmd0aCA9PT0gMSAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdHJldHVybiBqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGVsZW0sIGV4cHIgKSA/IFsgZWxlbSBdIDogW107XG5cdH1cblxuXHRyZXR1cm4galF1ZXJ5LmZpbmQubWF0Y2hlcyggZXhwciwgalF1ZXJ5LmdyZXAoIGVsZW1zLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gMTtcblx0fSApICk7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGZpbmQ6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR2YXIgaSwgcmV0LFxuXHRcdFx0bGVuID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRzZWxmID0gdGhpcztcblxuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkoIHNlbGVjdG9yICkuZmlsdGVyKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggc2VsZlsgaSBdLCB0aGlzICkgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gKSApO1xuXHRcdH1cblxuXHRcdHJldCA9IHRoaXMucHVzaFN0YWNrKCBbXSApO1xuXG5cdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGpRdWVyeS5maW5kKCBzZWxlY3Rvciwgc2VsZlsgaSBdLCByZXQgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbGVuID4gMSA/IGpRdWVyeS51bmlxdWVTb3J0KCByZXQgKSA6IHJldDtcblx0fSxcblx0ZmlsdGVyOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3coIHRoaXMsIHNlbGVjdG9yIHx8IFtdLCBmYWxzZSApICk7XG5cdH0sXG5cdG5vdDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggd2lubm93KCB0aGlzLCBzZWxlY3RvciB8fCBbXSwgdHJ1ZSApICk7XG5cdH0sXG5cdGlzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuICEhd2lubm93KFxuXHRcdFx0dGhpcyxcblxuXHRcdFx0Ly8gSWYgdGhpcyBpcyBhIHBvc2l0aW9uYWwvcmVsYXRpdmUgc2VsZWN0b3IsIGNoZWNrIG1lbWJlcnNoaXAgaW4gdGhlIHJldHVybmVkIHNldFxuXHRcdFx0Ly8gc28gJChcInA6Zmlyc3RcIikuaXMoXCJwOmxhc3RcIikgd29uJ3QgcmV0dXJuIHRydWUgZm9yIGEgZG9jIHdpdGggdHdvIFwicFwiLlxuXHRcdFx0dHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICYmIHJuZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSA/XG5cdFx0XHRcdGpRdWVyeSggc2VsZWN0b3IgKSA6XG5cdFx0XHRcdHNlbGVjdG9yIHx8IFtdLFxuXHRcdFx0ZmFsc2Vcblx0XHQpLmxlbmd0aDtcblx0fVxufSApO1xuXG5cbi8vIEluaXRpYWxpemUgYSBqUXVlcnkgb2JqZWN0XG5cblxuLy8gQSBjZW50cmFsIHJlZmVyZW5jZSB0byB0aGUgcm9vdCBqUXVlcnkoZG9jdW1lbnQpXG52YXIgcm9vdGpRdWVyeSxcblxuXHQvLyBBIHNpbXBsZSB3YXkgdG8gY2hlY2sgZm9yIEhUTUwgc3RyaW5nc1xuXHQvLyBQcmlvcml0aXplICNpZCBvdmVyIDx0YWc+IHRvIGF2b2lkIFhTUyB2aWEgbG9jYXRpb24uaGFzaCAodHJhYy05NTIxKVxuXHQvLyBTdHJpY3QgSFRNTCByZWNvZ25pdGlvbiAodHJhYy0xMTI5MDogbXVzdCBzdGFydCB3aXRoIDwpXG5cdC8vIFNob3J0Y3V0IHNpbXBsZSA
1jaWQgY2FzZSBmb3Igc3BlZWRcblx0cnF1aWNrRXhwciA9IC9eKD86XFxzKig8W1xcd1xcV10rPilbXj5dKnwjKFtcXHctXSspKSQvLFxuXG5cdGluaXQgPSBqUXVlcnkuZm4uaW5pdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCwgcm9vdCApIHtcblx0XHR2YXIgbWF0Y2gsIGVsZW07XG5cblx0XHQvLyBIQU5ETEU6ICQoXCJcIiksICQobnVsbCksICQodW5kZWZpbmVkKSwgJChmYWxzZSlcblx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdC8vIE1ldGhvZCBpbml0KCkgYWNjZXB0cyBhbiBhbHRlcm5hdGUgcm9vdGpRdWVyeVxuXHRcdC8vIHNvIG1pZ3JhdGUgY2FuIHN1cHBvcnQgalF1ZXJ5LnN1YiAoZ2gtMjEwMSlcblx0XHRyb290ID0gcm9vdCB8fCByb290alF1ZXJ5O1xuXG5cdFx0Ly8gSGFuZGxlIEhUTUwgc3RyaW5nc1xuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0aWYgKCBzZWxlY3RvclsgMCBdID09PSBcIjxcIiAmJlxuXHRcdFx0XHRzZWxlY3Rvclsgc2VsZWN0b3IubGVuZ3RoIC0gMSBdID09PSBcIj5cIiAmJlxuXHRcdFx0XHRzZWxlY3Rvci5sZW5ndGggPj0gMyApIHtcblxuXHRcdFx0XHQvLyBBc3N1bWUgdGhhdCBzdHJpbmdzIHRoYXQgc3RhcnQgYW5kIGVuZCB3aXRoIDw+IGFyZSBIVE1MIGFuZCBza2lwIHRoZSByZWdleCBjaGVja1xuXHRcdFx0XHRtYXRjaCA9IFsgbnVsbCwgc2VsZWN0b3IsIG51bGwgXTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1hdGNoIGh0bWwgb3IgbWFrZSBzdXJlIG5vIGNvbnRleHQgaXMgc3BlY2lmaWVkIGZvciAjaWRcblx0XHRcdGlmICggbWF0Y2ggJiYgKCBtYXRjaFsgMSBdIHx8ICFjb250ZXh0ICkgKSB7XG5cblx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwpIC0+ICQoYXJyYXkpXG5cdFx0XHRcdGlmICggbWF0Y2hbIDEgXSApIHtcblx0XHRcdFx0XHRjb250ZXh0ID0gY29udGV4dCBpbnN0YW5jZW9mIGpRdWVyeSA/IGNvbnRleHRbIDAgXSA6IGNvbnRleHQ7XG5cblx0XHRcdFx0XHQvLyBPcHRpb24gdG8gcnVuIHNjcmlwdHMgaXMgdHJ1ZSBmb3IgYmFjay1jb21wYXRcblx0XHRcdFx0XHQvLyBJbnRlbnRpb25hbGx5IGxldCB0aGUgZXJyb3IgYmUgdGhyb3duIGlmIHBhcnNlSFRNTCBpcyBub3QgcHJlc2VudFxuXHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcywgalF1ZXJ5LnBhcnNlSFRNTChcblx0XHRcdFx0XHRcdG1hdGNoWyAxIF0sXG5cdFx0XHRcdFx0XHRjb250ZXh0ICYmIGNvbnRleHQubm9kZVR5cGUgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IGRvY3VtZW50LFxuXHRcdFx0XHRcdFx0dHJ1ZVxuXHRcdFx0XHRcdCkgKTtcblxuXHRcdFx0XHRcdC8vIEhBTkRMRTogJChodG1sLCBwcm9wcylcblx0XHRcdFx0XHRpZiAoIHJzaW5nbGVUYWcudGVzdCggbWF0Y2hbIDEgXSApICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBjb250ZXh0ICkgKSB7XG5cdFx0XHRcdFx0XHRmb3IgKCBtYXRjaCBpbiBjb250ZXh0ICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFByb3BlcnRpZXMgb2YgY29udGV4dCBhcmUgY2FsbGVkIGFzIG1ldGhvZHMgaWYgcG9zc2libGVcblx0XHRcdFx0XHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCB0aGlzWyBtYXRjaCBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpc1sgbWF0Y2ggXSggY29udGV4dFsgbWF0Y2ggXSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIC4uLmFuZCBvdGhlcndpc2Ugc2V0IGFzIGF0dHJpYnV0ZXNcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmF0dHIoIG1hdGNoLCBjb250ZXh0WyBtYXRjaCBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoI2lkKVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggbWF0Y2hbIDIgXSApO1xuXG5cdFx0XHRcdFx0aWYgKCBlbGVtICkge1xuXG5cdFx0XHRcdFx0XHQvLyBJbmplY3QgdGhlIGVsZW1lbnQgZGlyZWN0bHkgaW50byB0aGUgalF1ZXJ5IG9iamVjdFxuXHRcdFx0XHRcdFx0dGhpc1sgMCBdID0gZWxlbTtcblx0XHRcdFx0XHRcdHRoaXMubGVuZ3RoID0gMTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gSEFORExFOiAkKGV4cHIsICQoLi4uKSlcblx0XHRcdH0gZWxzZSBpZiAoICFjb250ZXh0IHx8IGNvbnRleHQuanF1ZXJ5ICkge1xuXHRcdFx0XHRyZXR1cm4gKCBjb250ZXh0IHx8IHJvb3QgKS5maW5kKCBzZWxlY3RvciApO1xuXG5cdFx0XHQvLyBIQU5ETEU6ICQoZXhwciwgY29udGV4dClcblx0XHRcdC8vICh3aGljaCBpcyBqdXN0IGVxdWl2YWxlbnQgdG86ICQoY29udGV4dCkuZmluZChleHByKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IoIGNvbnRleHQgKS5maW5kKCBzZWxlY3RvciApO1xuXHRcdFx0fVxuXG5cdFx0Ly8gSEFORExFOiAkKERPTUVsZW1lbnQpXG5cdFx0fSBlbHNlIGlmICggc2VsZWN0b3Iubm9kZVR5cGUgKSB7XG5cdFx0XHR0aGlzWyAwIF0gPSBzZWxlY3Rvcjtcblx0XHRcdHRoaXMubGVuZ3RoID0gMTtcblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0Ly8gSEFORExFOiAkKGZ1bmN0aW9uKVxuXHRcdC8vIFNob3J0Y3V0IGZvciBkb2N1bWVudCByZWFkeVxuXHRcdH0gZWxzZSBpZiAoIGlzRnVuY3Rpb24oIHNlbGVjdG9yICkgKSB7XG5cdFx0XHRyZXR1cm4gcm9vdC5yZWFkeSAhPT0gdW5kZWZpbmVkID9cblx0XHRcdFx0cm9vdC5yZWFkeSggc2VsZWN0b3IgKSA6XG5cblx0XHRcdFx0Ly8gRXhlY3V0ZSBpbW1lZGlhdGVseSBpZiByZWFkeSBpcyBub3QgcHJlc2VudFxuXHRcdFx0XHRzZWxlY3RvciggalF1ZXJ5ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpRdWVyeS5tYWtlQXJyYXkoIHNlbGVjdG9yLCB0aGlzICk7XG5cdH07XG5cbi8vIEdpdmUgdGhlIGluaXQgZnVuY3Rpb24gdGhlIGpRdWVyeSBwcm90b3R5cGUgZm9yIGxhdGVyIGluc3RhbnRpYXRpb25cbmluaXQucHJvdG90eXBlID0galF1ZXJ5LmZuO1xuXG4vLyBJbml0aWFsaXplIGNlbnRyYWwgcmVmZXJlbmNlXG5yb290alF1ZXJ5ID0galF1ZXJ5KCBkb2N1bWVudCApO1xuXG5cbnZhciBycGFyZW50c3ByZXYgPSAvXig/OnBhcmVudHN8cHJldig/OlVudGlsfEFsbCkpLyxcblxuXHQvLyBNZXRob2RzIGd1YXJhbnRlZWQgdG8gcHJvZHVjZSBhIHVuaXF1ZSBzZXQgd2hlbiBzdGFydGluZyBmcm9tIGEgdW5pcXVlIHNldFxuXHRndWFyYW50ZWVkVW5pcXVlID0ge1xuXHRcdGNoaWxkcmVuOiB0cnVlLFxuXHRcdGNvbnRlbn
1RzOiB0cnVlLFxuXHRcdG5leHQ6IHRydWUsXG5cdFx0cHJldjogdHJ1ZVxuXHR9O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGhhczogZnVuY3Rpb24oIHRhcmdldCApIHtcblx0XHR2YXIgdGFyZ2V0cyA9IGpRdWVyeSggdGFyZ2V0LCB0aGlzICksXG5cdFx0XHRsID0gdGFyZ2V0cy5sZW5ndGg7XG5cblx0XHRyZXR1cm4gdGhpcy5maWx0ZXIoIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGkgPSAwO1xuXHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggdGhpcywgdGFyZ2V0c1sgaSBdICkgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0Y2xvc2VzdDogZnVuY3Rpb24oIHNlbGVjdG9ycywgY29udGV4dCApIHtcblx0XHR2YXIgY3VyLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRtYXRjaGVkID0gW10sXG5cdFx0XHR0YXJnZXRzID0gdHlwZW9mIHNlbGVjdG9ycyAhPT0gXCJzdHJpbmdcIiAmJiBqUXVlcnkoIHNlbGVjdG9ycyApO1xuXG5cdFx0Ly8gUG9zaXRpb25hbCBzZWxlY3RvcnMgbmV2ZXIgbWF0Y2gsIHNpbmNlIHRoZXJlJ3Mgbm8gX3NlbGVjdGlvbl8gY29udGV4dFxuXHRcdGlmICggIXJuZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3JzICkgKSB7XG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdGZvciAoIGN1ciA9IHRoaXNbIGkgXTsgY3VyICYmIGN1ciAhPT0gY29udGV4dDsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7XG5cblx0XHRcdFx0XHQvLyBBbHdheXMgc2tpcCBkb2N1bWVudCBmcmFnbWVudHNcblx0XHRcdFx0XHRpZiAoIGN1ci5ub2RlVHlwZSA8IDExICYmICggdGFyZ2V0cyA/XG5cdFx0XHRcdFx0XHR0YXJnZXRzLmluZGV4KCBjdXIgKSA+IC0xIDpcblxuXHRcdFx0XHRcdFx0Ly8gRG9uJ3QgcGFzcyBub24tZWxlbWVudHMgdG8galF1ZXJ5I2ZpbmRcblx0XHRcdFx0XHRcdGN1ci5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGN1ciwgc2VsZWN0b3JzICkgKSApIHtcblxuXHRcdFx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZC5sZW5ndGggPiAxID8galF1ZXJ5LnVuaXF1ZVNvcnQoIG1hdGNoZWQgKSA6IG1hdGNoZWQgKTtcblx0fSxcblxuXHQvLyBEZXRlcm1pbmUgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgd2l0aGluIHRoZSBzZXRcblx0aW5kZXg6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gTm8gYXJndW1lbnQsIHJldHVybiBpbmRleCBpbiBwYXJlbnRcblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuICggdGhpc1sgMCBdICYmIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xuXHRcdH1cblxuXHRcdC8vIEluZGV4IGluIHNlbGVjdG9yXG5cdFx0aWYgKCB0eXBlb2YgZWxlbSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGpRdWVyeSggZWxlbSApLCB0aGlzWyAwIF0gKTtcblx0XHR9XG5cblx0XHQvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnRcblx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLFxuXG5cdFx0XHQvLyBJZiBpdCByZWNlaXZlcyBhIGpRdWVyeSBvYmplY3QsIHRoZSBmaXJzdCBlbGVtZW50IGlzIHVzZWRcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbVxuXHRcdCk7XG5cdH0sXG5cblx0YWRkOiBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKFxuXHRcdFx0alF1ZXJ5LnVuaXF1ZVNvcnQoXG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcy5nZXQoKSwgalF1ZXJ5KCBzZWxlY3RvciwgY29udGV4dCApIClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXG5cdGFkZEJhY2s6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5hZGQoIHNlbGVjdG9yID09IG51bGwgP1xuXHRcdFx0dGhpcy5wcmV2T2JqZWN0IDogdGhpcy5wcmV2T2JqZWN0LmZpbHRlciggc2VsZWN0b3IgKVxuXHRcdCk7XG5cdH1cbn0gKTtcblxuZnVuY3Rpb24gc2libGluZyggY3VyLCBkaXIgKSB7XG5cdHdoaWxlICggKCBjdXIgPSBjdXJbIGRpciBdICkgJiYgY3VyLm5vZGVUeXBlICE9PSAxICkge31cblx0cmV0dXJuIGN1cjtcbn1cblxualF1ZXJ5LmVhY2goIHtcblx0cGFyZW50OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlICE9PSAxMSA/IHBhcmVudCA6IG51bGw7XG5cdH0sXG5cdHBhcmVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiICk7XG5cdH0sXG5cdHBhcmVudHNVbnRpbDogZnVuY3Rpb24oIGVsZW0sIF9pLCB1bnRpbCApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcInBhcmVudE5vZGVcIiwgdW50aWwgKTtcblx0fSxcblx0bmV4dDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIHNpYmxpbmcoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xuXHR9LFxuXHRwcmV2OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIgKTtcblx0fSxcblx0cHJldkFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBfaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJuZXh0U2libGluZ1wiLCB1bnRpbCApO1xuXHR9LFxuXHRwcmV2VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBfaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0c2libGluZ3M6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybi
1BzaWJsaW5ncyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7XG5cdH0sXG5cdGNoaWxkcmVuOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZ3MoIGVsZW0uZmlyc3RDaGlsZCApO1xuXHR9LFxuXHRjb250ZW50czogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0aWYgKCBlbGVtLmNvbnRlbnREb2N1bWVudCAhPSBudWxsICYmXG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExK1xuXHRcdFx0Ly8gPG9iamVjdD4gZWxlbWVudHMgd2l0aCBubyBgZGF0YWAgYXR0cmlidXRlIGhhcyBhbiBvYmplY3Rcblx0XHRcdC8vIGBjb250ZW50RG9jdW1lbnRgIHdpdGggYSBgbnVsbGAgcHJvdG90eXBlLlxuXHRcdFx0Z2V0UHJvdG8oIGVsZW0uY29udGVudERvY3VtZW50ICkgKSB7XG5cblx0XHRcdHJldHVybiBlbGVtLmNvbnRlbnREb2N1bWVudDtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTEgb25seSwgaU9TIDcgb25seSwgQW5kcm9pZCBCcm93c2VyIDw9NC4zIG9ubHlcblx0XHQvLyBUcmVhdCB0aGUgdGVtcGxhdGUgZWxlbWVudCBhcyBhIHJlZ3VsYXIgb25lIGluIGJyb3dzZXJzIHRoYXRcblx0XHQvLyBkb24ndCBzdXBwb3J0IGl0LlxuXHRcdGlmICggbm9kZU5hbWUoIGVsZW0sIFwidGVtcGxhdGVcIiApICkge1xuXHRcdFx0ZWxlbSA9IGVsZW0uY29udGVudCB8fCBlbGVtO1xuXHRcdH1cblxuXHRcdHJldHVybiBqUXVlcnkubWVyZ2UoIFtdLCBlbGVtLmNoaWxkTm9kZXMgKTtcblx0fVxufSwgZnVuY3Rpb24oIG5hbWUsIGZuICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCB1bnRpbCwgc2VsZWN0b3IgKSB7XG5cdFx0dmFyIG1hdGNoZWQgPSBqUXVlcnkubWFwKCB0aGlzLCBmbiwgdW50aWwgKTtcblxuXHRcdGlmICggbmFtZS5zbGljZSggLTUgKSAhPT0gXCJVbnRpbFwiICkge1xuXHRcdFx0c2VsZWN0b3IgPSB1bnRpbDtcblx0XHR9XG5cblx0XHRpZiAoIHNlbGVjdG9yICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdG1hdGNoZWQgPSBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgbWF0Y2hlZCApO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy5sZW5ndGggPiAxICkge1xuXG5cdFx0XHQvLyBSZW1vdmUgZHVwbGljYXRlc1xuXHRcdFx0aWYgKCAhZ3VhcmFudGVlZFVuaXF1ZVsgbmFtZSBdICkge1xuXHRcdFx0XHRqUXVlcnkudW5pcXVlU29ydCggbWF0Y2hlZCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXZlcnNlIG9yZGVyIGZvciBwYXJlbnRzKiBhbmQgcHJldi1kZXJpdmF0aXZlc1xuXHRcdFx0aWYgKCBycGFyZW50c3ByZXYudGVzdCggbmFtZSApICkge1xuXHRcdFx0XHRtYXRjaGVkLnJldmVyc2UoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIG1hdGNoZWQgKTtcblx0fTtcbn0gKTtcbnZhciBybm90aHRtbHdoaXRlID0gKCAvW15cXHgyMFxcdFxcclxcblxcZl0rL2cgKTtcblxuXG5cbi8vIENvbnZlcnQgU3RyaW5nLWZvcm1hdHRlZCBvcHRpb25zIGludG8gT2JqZWN0LWZvcm1hdHRlZCBvbmVzXG5mdW5jdGlvbiBjcmVhdGVPcHRpb25zKCBvcHRpb25zICkge1xuXHR2YXIgb2JqZWN0ID0ge307XG5cdGpRdWVyeS5lYWNoKCBvcHRpb25zLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW10sIGZ1bmN0aW9uKCBfLCBmbGFnICkge1xuXHRcdG9iamVjdFsgZmxhZyBdID0gdHJ1ZTtcblx0fSApO1xuXHRyZXR1cm4gb2JqZWN0O1xufVxuXG4vKlxuICogQ3JlYXRlIGEgY2FsbGJhY2sgbGlzdCB1c2luZyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gKlxuICpcdG9wdGlvbnM6IGFuIG9wdGlvbmFsIGxpc3Qgb2Ygc3BhY2Utc2VwYXJhdGVkIG9wdGlvbnMgdGhhdCB3aWxsIGNoYW5nZSBob3dcbiAqXHRcdFx0dGhlIGNhbGxiYWNrIGxpc3QgYmVoYXZlcyBvciBhIG1vcmUgdHJhZGl0aW9uYWwgb3B0aW9uIG9iamVjdFxuICpcbiAqIEJ5IGRlZmF1bHQgYSBjYWxsYmFjayBsaXN0IHdpbGwgYWN0IGxpa2UgYW4gZXZlbnQgY2FsbGJhY2sgbGlzdCBhbmQgY2FuIGJlXG4gKiBcImZpcmVkXCIgbXVsdGlwbGUgdGltZXMuXG4gKlxuICogUG9zc2libGUgb3B0aW9uczpcbiAqXG4gKlx0b25jZTpcdFx0XHR3aWxsIGVuc3VyZSB0aGUgY2FsbGJhY2sgbGlzdCBjYW4gb25seSBiZSBmaXJlZCBvbmNlIChsaWtlIGEgRGVmZXJyZWQpXG4gKlxuICpcdG1lbW9yeTpcdFx0XHR3aWxsIGtlZXAgdHJhY2sgb2YgcHJldmlvdXMgdmFsdWVzIGFuZCB3aWxsIGNhbGwgYW55IGNhbGxiYWNrIGFkZGVkXG4gKlx0XHRcdFx0XHRhZnRlciB0aGUgbGlzdCBoYXMgYmVlbiBmaXJlZCByaWdodCBhd2F5IHdpdGggdGhlIGxhdGVzdCBcIm1lbW9yaXplZFwiXG4gKlx0XHRcdFx0XHR2YWx1ZXMgKGxpa2UgYSBEZWZlcnJlZClcbiAqXG4gKlx0dW5pcXVlOlx0XHRcdHdpbGwgZW5zdXJlIGEgY2FsbGJhY2sgY2FuIG9ubHkgYmUgYWRkZWQgb25jZSAobm8gZHVwbGljYXRlIGluIHRoZSBsaXN0KVxuICpcbiAqXHRzdG9wT25GYWxzZTpcdGludGVycnVwdCBjYWxsaW5ncyB3aGVuIGEgY2FsbGJhY2sgcmV0dXJucyBmYWxzZVxuICpcbiAqL1xualF1ZXJ5LkNhbGxiYWNrcyA9IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXG5cdC8vIENvbnZlcnQgb3B0aW9ucyBmcm9tIFN0cmluZy1mb3JtYXR0ZWQgdG8gT2JqZWN0LWZvcm1hdHRlZCBpZiBuZWVkZWRcblx0Ly8gKHdlIGNoZWNrIGluIGNhY2hlIGZpcnN0KVxuXHRvcHRpb25zID0gdHlwZW9mIG9wdGlvbnMgPT09IFwic3RyaW5nXCIgP1xuXHRcdGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSA6XG5cdFx0alF1ZXJ5LmV4dGVuZCgge30sIG9wdGlvbnMgKTtcblxuXHR2YXIgLy8gRmxhZyB0byBrbm93IGlmIGxpc3QgaXMgY3VycmVudGx5IGZpcmluZ1xuXHRcdGZpcmluZyxcblxuXHRcdC8vIExhc3QgZmlyZSB2YWx1ZSBmb3Igbm9uLWZvcmdldHRhYmxlIGxpc3RzXG5cdFx0bWVtb3J5LFxuXG5cdFx0Ly8gRmxhZyB0byBrbm93IGlmIGxpc3Qgd2FzIGFscmVhZHkgZmlyZWRcblx0XHRmaXJlZCxcblxuXHRcdC8vIEZsYWcgdG8gcHJldmVudCBmaXJpbmdcblx0XHRsb2NrZWQsXG5cblx0XHQvLyBBY3R1YWwgY2FsbGJhY2sgbGlzdFxuXHRcdGxpc3QgPSBbXSxcblxuXHRcdC8vIFF1ZXVlIG9mIGV4ZWN1dGlvbiBkYXRhIGZvciByZXBlYXRhYmxlIGxpc3RzXG5cdFx0cXVldWUgPSBbXSxcblxuXHRcdC8vIEluZGV4IG9mIGN1cnJlbnRseSBmaXJpbmcgY2FsbGJhY2sgKG1vZGlmaWVkIGJ5IGFkZC9yZW1vdmUgYXMgbmVlZGVkKVxuXHRcdGZpcmluZ0luZGV4ID0gLTEsXG5cblx0XHQvLyBGaXJlIGNhbGxiYWNrc1xuXHRcdGZpcmUgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gRW5mb3JjZSBzaW5nbGUtZmlyaW5nXG5cdFx0XHRsb2NrZWQgPSBsb2NrZWQgfHwgb3B0aW9ucy5vbmNlO1xuXG5cdFx0XHQvLyBFeGVjdXRlIGNhbGxiYWNrcyBmb3IgYWxsIHBlbmRpbmcgZXhlY3V0aW9ucyxcblx0XHRcdC8vIHJlc3BlY3RpbmcgZmlyaW5nSW5kZXggb3ZlcnJpZGVzIGFuZCBydW50aW1lIGNoYW5nZXNcblx0XHRcdGZpcmVkID0gZmlyaW5nID0gdHJ1ZTtcblx0XHRcdGZvciAoIDsgcXVldWUubGVuZ3RoOyBmaXJpbmdJbmRleCA9IC0xICkge1xuXHRcdFx0XHRtZW1vcnkgPSBxdWV1ZS5zaGlmdCgpO1xuXHRcdFx0XHR3aGlsZSAoICsrZmlyaW5nSW5kZXggPCBsaXN0Lmxlbmd0aCApIHtcblxuXHRcdFx0XHRcdC8vIFJ1biBjYWxsYmFjayBhbmQgY2hlY2sgZm9yIGVhcmx5IHRlcm1pbmF0aW9uXG5cdFx0XHRcdFx0aWYgKCBsaXN0WyBmaXJpbmdJbmRleCBdLmFwcGx5KCBtZW1vcnlbIDAgXSwgbWVtb3J5WyAxIF0gKSA9PT0gZmFsc2UgJiZcblx0XHRcdFx0XHRcdG9wdGlvbnMuc3RvcE9uRmFsc2UgKSB7XG5cblx0XHRcdFx0XHRcdC8vIEp1bXAgdG8gZW5kIGFuZCBmb3JnZXQgdGhlIGRhdGEgc28gLmFkZCBkb2Vzbid0IHJlLWZpcmVcblx0XHRcdFx0XHRcdGZpcmluZ0luZGV4ID0gbGlzdC5sZW5ndGg7XG5cdFx0XHRcdFx0XHRtZW1vcnkgPSBmYWxzZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gRm9yZ2V0IHRoZSBkYXRhIGlmIHdlJ3JlIGRvbmUgd2l0aCBpdFxuXHRcdFx0aWYgKCAhb3B0aW9ucy5tZW1vcnkgKSB7XG5cdFx0XHRcdG1lbW9yeSA9IGZ
1hbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHRmaXJpbmcgPSBmYWxzZTtcblxuXHRcdFx0Ly8gQ2xlYW4gdXAgaWYgd2UncmUgZG9uZSBmaXJpbmcgZm9yIGdvb2Rcblx0XHRcdGlmICggbG9ja2VkICkge1xuXG5cdFx0XHRcdC8vIEtlZXAgYW4gZW1wdHkgbGlzdCBpZiB3ZSBoYXZlIGRhdGEgZm9yIGZ1dHVyZSBhZGQgY2FsbHNcblx0XHRcdFx0aWYgKCBtZW1vcnkgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IFtdO1xuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSwgdGhpcyBvYmplY3QgaXMgc3BlbnRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRsaXN0ID0gXCJcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvLyBBY3R1YWwgQ2FsbGJhY2tzIG9iamVjdFxuXHRcdHNlbGYgPSB7XG5cblx0XHRcdC8vIEFkZCBhIGNhbGxiYWNrIG9yIGEgY29sbGVjdGlvbiBvZiBjYWxsYmFja3MgdG8gdGhlIGxpc3Rcblx0XHRcdGFkZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblxuXHRcdFx0XHRcdC8vIElmIHdlIGhhdmUgbWVtb3J5IGZyb20gYSBwYXN0IHJ1biwgd2Ugc2hvdWxkIGZpcmUgYWZ0ZXIgYWRkaW5nXG5cdFx0XHRcdFx0aWYgKCBtZW1vcnkgJiYgIWZpcmluZyApIHtcblx0XHRcdFx0XHRcdGZpcmluZ0luZGV4ID0gbGlzdC5sZW5ndGggLSAxO1xuXHRcdFx0XHRcdFx0cXVldWUucHVzaCggbWVtb3J5ICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0KCBmdW5jdGlvbiBhZGQoIGFyZ3MgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJncywgZnVuY3Rpb24oIF8sIGFyZyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCBhcmcgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoICFvcHRpb25zLnVuaXF1ZSB8fCAhc2VsZi5oYXMoIGFyZyApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0bGlzdC5wdXNoKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGFyZyAmJiBhcmcubGVuZ3RoICYmIHRvVHlwZSggYXJnICkgIT09IFwic3RyaW5nXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBJbnNwZWN0IHJlY3Vyc2l2ZWx5XG5cdFx0XHRcdFx0XHRcdFx0YWRkKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdH0gKSggYXJndW1lbnRzICk7XG5cblx0XHRcdFx0XHRpZiAoIG1lbW9yeSAmJiAhZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIFJlbW92ZSBhIGNhbGxiYWNrIGZyb20gdGhlIGxpc3Rcblx0XHRcdHJlbW92ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5lYWNoKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0dmFyIGluZGV4O1xuXHRcdFx0XHRcdHdoaWxlICggKCBpbmRleCA9IGpRdWVyeS5pbkFycmF5KCBhcmcsIGxpc3QsIGluZGV4ICkgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0bGlzdC5zcGxpY2UoIGluZGV4LCAxICk7XG5cblx0XHRcdFx0XHRcdC8vIEhhbmRsZSBmaXJpbmcgaW5kZXhlc1xuXHRcdFx0XHRcdFx0aWYgKCBpbmRleCA8PSBmaXJpbmdJbmRleCApIHtcblx0XHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXgtLTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBDaGVjayBpZiBhIGdpdmVuIGNhbGxiYWNrIGlzIGluIHRoZSBsaXN0LlxuXHRcdFx0Ly8gSWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4sIHJldHVybiB3aGV0aGVyIG9yIG5vdCBsaXN0IGhhcyBjYWxsYmFja3MgYXR0YWNoZWQuXG5cdFx0XHRoYXM6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0cmV0dXJuIGZuID9cblx0XHRcdFx0XHRqUXVlcnkuaW5BcnJheSggZm4sIGxpc3QgKSA+IC0xIDpcblx0XHRcdFx0XHRsaXN0Lmxlbmd0aCA+IDA7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBSZW1vdmUgYWxsIGNhbGxiYWNrcyBmcm9tIHRoZSBsaXN0XG5cdFx0XHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0XHRsaXN0ID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBEaXNhYmxlIC5maXJlIGFuZCAuYWRkXG5cdFx0XHQvLyBBYm9ydCBhbnkgY3VycmVudC9wZW5kaW5nIGV4ZWN1dGlvbnNcblx0XHRcdC8vIENsZWFyIGFsbCBjYWxsYmFja3MgYW5kIHZhbHVlc1xuXHRcdFx0ZGlzYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxvY2tlZCA9IHF1ZXVlID0gW107XG5cdFx0XHRcdGxpc3QgPSBtZW1vcnkgPSBcIlwiO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHRkaXNhYmxlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhbGlzdDtcblx0XHRcdH0sXG5cblx0XHRcdC8vIERpc2FibGUgLmZpcmVcblx0XHRcdC8vIEFsc28gZGlzYWJsZSAuYWRkIHVubGVzcyB3ZSBoYXZlIG1lbW9yeSAoc2luY2UgaXQgd291bGQgaGF2ZSBubyBlZmZlY3QpXG5cdFx0XHQvLyBBYm9ydCBhbnkgcGVuZGluZyBleGVjdXRpb25zXG5cdFx0XHRsb2NrOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0bG9ja2VkID0gcXVldWUgPSBbXTtcblx0XHRcdFx0aWYgKCAhbWVtb3J5ICYmICFmaXJpbmcgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IG1lbW9yeSA9IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0bG9ja2VkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICEhbG9ja2VkO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gQ2FsbCBhbGwgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGNvbnRleHQgYW5kIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZVdpdGg6IGZ1bmN0aW9uKCBjb250ZXh0LCBhcmdzICkge1xuXHRcdFx0XHRpZiAoICFsb2NrZWQgKSB7XG5cdFx0XHRcdFx0YXJncyA9IGFyZ3MgfHwgW107XG5cdFx0XHRcdFx0YXJncyA9IFsgY29udGV4dCwgYXJncy5zbGljZSA/IGFyZ3Muc2xpY2UoKSA6IGFyZ3MgXTtcblx0XHRcdFx0XHRxdWV1ZS5wdXNoKCBhcmdzICk7XG5cdFx0XHRcdFx0aWYgKCAhZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIENhbGwgYWxsIHRoZSBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzXG5cdFx0XHRmaXJlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0c2VsZi5maXJlV2l0aCggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdHJldHVybi
1B0aGlzO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gVG8ga25vdyBpZiB0aGUgY2FsbGJhY2tzIGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZCBhdCBsZWFzdCBvbmNlXG5cdFx0XHRmaXJlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhIWZpcmVkO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0cmV0dXJuIHNlbGY7XG59O1xuXG5cbmZ1bmN0aW9uIElkZW50aXR5KCB2ICkge1xuXHRyZXR1cm4gdjtcbn1cbmZ1bmN0aW9uIFRocm93ZXIoIGV4ICkge1xuXHR0aHJvdyBleDtcbn1cblxuZnVuY3Rpb24gYWRvcHRWYWx1ZSggdmFsdWUsIHJlc29sdmUsIHJlamVjdCwgbm9WYWx1ZSApIHtcblx0dmFyIG1ldGhvZDtcblxuXHR0cnkge1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIHByb21pc2UgYXNwZWN0IGZpcnN0IHRvIHByaXZpbGVnZSBzeW5jaHJvbm91cyBiZWhhdmlvclxuXHRcdGlmICggdmFsdWUgJiYgaXNGdW5jdGlvbiggKCBtZXRob2QgPSB2YWx1ZS5wcm9taXNlICkgKSApIHtcblx0XHRcdG1ldGhvZC5jYWxsKCB2YWx1ZSApLmRvbmUoIHJlc29sdmUgKS5mYWlsKCByZWplY3QgKTtcblxuXHRcdC8vIE90aGVyIHRoZW5hYmxlc1xuXHRcdH0gZWxzZSBpZiAoIHZhbHVlICYmIGlzRnVuY3Rpb24oICggbWV0aG9kID0gdmFsdWUudGhlbiApICkgKSB7XG5cdFx0XHRtZXRob2QuY2FsbCggdmFsdWUsIHJlc29sdmUsIHJlamVjdCApO1xuXG5cdFx0Ly8gT3RoZXIgbm9uLXRoZW5hYmxlc1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIENvbnRyb2wgYHJlc29sdmVgIGFyZ3VtZW50cyBieSBsZXR0aW5nIEFycmF5I3NsaWNlIGNhc3QgYm9vbGVhbiBgbm9WYWx1ZWAgdG8gaW50ZWdlcjpcblx0XHRcdC8vICogZmFsc2U6IFsgdmFsdWUg
1XS5zbGljZSggMCApID0+IHJlc29sdmUoIHZhbHVlIClcblx0XHRcdC8vICogdHJ1ZTogWyB2YWx1ZSBdLnNsaWNlKCAxICkgPT4gcmVzb2x2ZSgpXG5cdFx0XHRyZXNvbHZlLmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXS5zbGljZSggbm9WYWx1ZSApICk7XG5cdFx0fVxuXG5cdC8vIEZvciBQcm9taXNlcy9BKywgY29udmVydCBleGNlcHRpb25zIGludG8gcmVqZWN0aW9uc1xuXHQvLyBTaW5jZSBqUXVlcnkud2hlbiBkb2Vzbid0IHVud3JhcCB0aGVuYWJsZXMsIHdlIGNhbiBza2lwIHRoZSBleHRyYSBjaGVja3MgYXBwZWFyaW5nIGluXG5cdC8vIERlZmVycmVkI3RoZW4gdG8gY29uZGl0aW9uYWxseSBzdXBwcmVzcyByZWplY3Rpb24uXG5cdH0gY2F0Y2ggKCB2YWx1ZSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIG9ubHlcblx0XHQvLyBTdHJpY3QgbW9kZSBmdW5jdGlvbnMgaW52b2tlZCB3aXRob3V0IC5jYWxsLy5hcHBseSBnZXQgZ2xvYmFsLW9iamVjdCBjb250ZXh0XG5cdFx0cmVqZWN0LmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXSApO1xuXHR9XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHREZWZlcnJlZDogZnVuY3Rpb24oIGZ1bmMgKSB7XG5cdFx0dmFyIHR1cGxlcyA9IFtcblxuXHRcdFx0XHQvLyBhY3Rpb24sIGFkZCBsaXN0ZW5lciwgY2FsbGJhY2tzLFxuXHRcdFx0XHQvLyAuLi4gLnRoZW4gaGFuZGxlcnMsIGFyZ3VtZW50IGluZGV4LCBbZmluYWwgc3RhdGVdXG5cdFx0XHRcdFsgXCJub3RpZnlcIiwgXCJwcm9ncmVzc1wiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm1lbW9yeVwiICksXG5cdFx0XHRcdFx0alF1ZXJ5LkNhbGxiYWNrcyggXCJtZW1vcnlcIiApLCAyIF0sXG5cdFx0XHRcdFsgXCJyZXNvbHZlXCIsIFwiZG9uZVwiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSxcblx0XHRcdFx0XHRqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSwgMCwgXCJyZXNvbHZlZFwiIF0sXG5cdFx0XHRcdFsgXCJyZWplY3RcIiwgXCJmYWlsXCIsIGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLFxuXHRcdFx0XHRcdGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLCAxLCBcInJlamVjdGVkXCIgXVxuXHRcdFx0XSxcblx0XHRcdHN0YXRlID0gXCJwZW5kaW5nXCIsXG5cdFx0XHRwcm9taXNlID0ge1xuXHRcdFx0XHRzdGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRhbHdheXM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGRlZmVycmVkLmRvbmUoIGFyZ3VtZW50cyApLmZhaWwoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRcImNhdGNoXCI6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcHJvbWlzZS50aGVuKCBudWxsLCBmbiApO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIEtlZXAgcGlwZSBmb3IgYmFjay1jb21wYXRcblx0XHRcdFx0cGlwZTogZnVuY3Rpb24oIC8qIGZuRG9uZSwgZm5GYWlsLCBmblByb2dyZXNzICovICkge1xuXHRcdFx0XHRcdHZhciBmbnMgPSBhcmd1bWVudHM7XG5cblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggX2ksIHR1cGxlICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIE1hcCB0dXBsZXMgKHByb2dyZXNzLCBkb25lLCBmYWlsKSB0byBhcmd1bWVudHMgKGRvbmUsIGZhaWwsIHByb2dyZXNzKVxuXHRcdFx0XHRcdFx0XHR2YXIgZm4gPSBpc0Z1bmN0aW9uKCBmbnNbIHR1cGxlWyA0IF0gXSApICYmIGZuc1sgdHVwbGVbIDQgXSBdO1xuXG5cdFx0XHRcdFx0XHRcdC8vIGRlZmVycmVkLnByb2dyZXNzKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLm5vdGlmeSB9KVxuXHRcdFx0XHRcdFx0XHQvLyBkZWZlcnJlZC5kb25lKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLnJlc29sdmUgfSlcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWQuZmFpbChmdW5jdGlvbigpIHsgYmluZCB0byBuZXdEZWZlciBvciBuZXdEZWZlci5yZWplY3QgfSlcblx0XHRcdFx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAxIF0gXSggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkID0gZm4gJiYgZm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdFx0XHRcdGlmICggcmV0dXJuZWQgJiYgaXNGdW5jdGlvbiggcmV0dXJuZWQucHJvbWlzZSApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQucHJvbWlzZSgpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5wcm9ncmVzcyggbmV3RGVmZXIubm90aWZ5IClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmRvbmUoIG5ld0RlZmVyLnJlc29sdmUgKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuZmFpbCggbmV3RGVmZXIucmVqZWN0ICk7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXShcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcyxcblx0XHRcdFx0XHRcdFx0XHRcdFx0Zm4gPyBbIHJldHVybmVkIF0gOiBhcmd1bWVudHNcblx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRmbnMgPSBudWxsO1xuXHRcdFx0XHRcdH0gKS5wcm9taXNlKCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRoZW46IGZ1bmN0aW9uKCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgb25Qcm9ncmVzcyApIHtcblx0XHRcdFx0XHR2YXIgbWF4RGVwdGggPSAwO1xuXHRcdFx0XHRcdGZ1bmN0aW9uIHJlc29sdmUoIGRlcHRoLCBkZWZlcnJlZCwgaGFuZGxlciwgc3BlY2lhbCApIHtcblx0XHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0dmFyIHRoYXQgPSB0aGlzLFxuXHRcdFx0XHRcdFx0XHRcdGFyZ3MgPSBhcmd1bWVudHMsXG5cdFx0XHRcdFx0XHRcdFx0bWlnaHRUaHJvdyA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkLCB0aGVuO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4zLjMuM1xuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTlcblx0XHRcdFx0XHRcdFx0XHRcdC8vIElnbm9yZSBkb3VibGUtcmVzb2x1dGlvbiBhdHRlbXB0c1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBkZXB0aCA8IG1heERlcHRoICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkID0gaGFuZGxlci5hcHBseSggdGhhdCwgYXJncyApO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4xXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC00OFxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCByZXR1cm5lZCA9PT0gZGVmZXJyZWQucHJvbWlzZSgpICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCBcIlRoZW5hYmxlIHNlbGYtcmVzb2x1dGlvblwiICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb25zIDIuMy4zLjEsIDMuNVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTRcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTc1XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXRyaWV2ZSBgdGhlbmAgb25seSBvbmNlXG5cdFx0XHRcdFx0XHRcdFx0XHR0aG
1VuID0gcmV0dXJuZWQgJiZcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy40XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTY0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgY2hlY2sgb2JqZWN0cyBhbmQgZnVuY3Rpb25zIGZvciB0aGVuYWJpbGl0eVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQoIHR5cGVvZiByZXR1cm5lZCA9PT0gXCJvYmplY3RcIiB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiByZXR1cm5lZCA9PT0gXCJmdW5jdGlvblwiICkgJiZcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQudGhlbjtcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSGFuZGxlIGEgcmV0dXJuZWQgdGhlbmFibGVcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggaXNGdW5jdGlvbiggdGhlbiApICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFNwZWNpYWwgcHJvY2Vzc29ycyAobm90aWZ5KSBqdXN0IHdhaXQgZm9yIHJlc29sdXRpb25cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoZW4uY2FsbChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBJZGVudGl0eSwgc3BlY2lhbCApLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBUaHJvd2VyLCBzcGVjaWFsIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE5vcm1hbCBwcm9jZXNzb3JzIChyZXNvbHZlKSBhbHNvIGhvb2sgaW50byBwcm9ncmVzc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIGRpc3JlZ2FyZCBvbGRlciByZXNvbHV0aW9uIHZhbHVlc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1heERlcHRoKys7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGVuLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5lZCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgSWRlbnRpdHksIHNwZWNpYWwgKSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgVGhyb3dlciwgc3BlY2lhbCApLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBJZGVudGl0eSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBIYW5kbGUgYWxsIG90aGVyIHJldHVybmVkIHZhbHVlc1xuXHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBPbmx5IHN1YnN0aXR1dGUgaGFuZGxlcnMgcGFzcyBvbiBjb250ZXh0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGFuZCBtdWx0aXBsZSB2YWx1ZXMgKG5vbi1zcGVjIGJlaGF2aW9yKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIGhhbmRsZXIgIT09IElkZW50aXR5ICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoYXQgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YXJncyA9IFsgcmV0dXJuZWQgXTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFByb2Nlc3MgdGhlIHZhbHVlKHMpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIERlZmF1bHQgcHJvY2VzcyBpcyByZXNvbHZlXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCggc3BlY2lhbCB8fCBkZWZlcnJlZC5yZXNvbHZlV2l0aCApKCB0aGF0LCBhcmdzICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fSxcblxuXHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgbm9ybWFsIHByb2Nlc3NvcnMgKHJlc29sdmUpIGNhdGNoIGFuZCByZWplY3QgZXhjZXB0aW9uc1xuXHRcdFx0XHRcdFx0XHRcdHByb2Nlc3MgPSBzcGVjaWFsID9cblx0XHRcdFx0XHRcdFx0XHRcdG1pZ2h0VGhyb3cgOlxuXHRcdFx0XHRcdFx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWlnaHRUaHJvdygpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9IGNhdGNoICggZSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LkRlZmVycmVkLmV4Y2VwdGlvbkhvb2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayggZSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cHJvY2Vzcy5lcnJvciApO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb24gMi4zLjMuMy40LjFcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC02MVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIElnbm9yZSBwb3N0LXJlc29sdXRpb24gZXhjZXB0aW9uc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggZGVwdGggKyAxID49IG1heERlcHRoICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBPbmx5IHN1YnN0aXR1dGUgaGFuZGxlcnMgcGFzcyBvbiBjb250ZXh0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBhbmQgbXVsdGlwbGUgdmFsdWVzIChub24tc3BlYyBiZWhhdmlvcilcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggaGFuZGxlciAhPT0gVGhyb3dlciApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhhdCA9IHVuZGVmaW5lZDtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0YXJncyA9IFsgZSBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCB0aGF0LCBhcmdzICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHR9O1xuXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb24gMi4zLjMuMy4xXG5cdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTU3XG5cdFx0XHRcdFx0XHRcdC8vIFJlLXJlc29sdmUgcHJvbWlzZXMgaW1tZWRpYXRlbHkgdG8gZG9kZ2UgZmFsc2UgcmVqZWN0aW9uIGZyb21cblx0XHRcdFx0XHRcdFx0Ly8gc3Vic2VxdWVudCBlcnJvcnNcblx0XHRcdFx0XHRcdFx0aWYgKCBkZXB0aCApIHtcblx0XHRcdFx0XHRcdFx0XHRwcm9jZXNzKCk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBDYWxsIGFuIG9wdGlvbmFsIGhvb2sgdG8gcmVjb3JkIHRoZSBlcnJvciwgaW4gY2FzZSBvZiBleGNlcHRpb25cblx0XHRcdFx0XHRcdFx0XHQvLyBzaW5jZSBpdCdzIG90aGVyd2lzZSBsb3N0IHdoZW4gZXhlY3V0aW9uIGdvZXMgYXN5bmNcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5EZWZlcnJlZC5nZXRFcnJvckhvb2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRwcm9jZXNzLmVycm9yID0galF1ZXJ5LkRlZmVycmVkLmdldEVycm9ySG9vaygpO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gVGhlIGRlcHJlY2F0ZWQgYWxpYXMgb2YgdGhlIGFib3ZlLiBXaGlsZSB0aGUgbmFtZSBzdWdnZXN0c1xuXHRcdFx0XHRcdFx0XHRcdC8vIHJldHVybmluZyB0aGUgc3RhY2ssIG5vdCBhbiBlcnJvciBpbnN0YW5jZSwgalF1ZXJ5IGp1c3QgcGFzc2VzXG5cdFx0XHRcdFx0XHRcdFx0Ly8gaXQgZGlyZWN0bHkgdG8gYGNvbnNvbGUud2FybmAgc28gYm90aCB3aWxsIHdvcms7IGFuIGluc3RhbmNlXG5cdFx0XHRcdFx0XHRcdFx0Ly8ganVzdCBiZXR0ZXIgY29vcGVyYXRlcyB3aXRoIHNvdXJjZSBtYXBzLlxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGpRdWVyeS5EZWZlcnJlZC5nZXRTdGFja0hvb2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRwcm9jZXNzLmVycm9yID0galF1ZXJ5LkRlZmVycmVkLmdldFN0YWNrSG9vaygpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR3aW5kb3cuc2V0VGltZW91dCggcHJvY2VzcyApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybi
1BqUXVlcnkuRGVmZXJyZWQoIGZ1bmN0aW9uKCBuZXdEZWZlciApIHtcblxuXHRcdFx0XHRcdFx0Ly8gcHJvZ3Jlc3NfaGFuZGxlcnMuYWRkKCAuLi4gKVxuXHRcdFx0XHRcdFx0dHVwbGVzWyAwIF1bIDMgXS5hZGQoXG5cdFx0XHRcdFx0XHRcdHJlc29sdmUoXG5cdFx0XHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlcixcblx0XHRcdFx0XHRcdFx0XHRpc0Z1bmN0aW9uKCBvblByb2dyZXNzICkgP1xuXHRcdFx0XHRcdFx0XHRcdFx0b25Qcm9ncmVzcyA6XG5cdFx0XHRcdFx0XHRcdFx0XHRJZGVudGl0eSxcblx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlci5ub3RpZnlXaXRoXG5cdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdC8vIGZ1bGZpbGxlZF9oYW5kbGVycy5hZGQoIC4uLiApXG5cdFx0XHRcdFx0XHR0dXBsZXNbIDEgXVsgMyBdLmFkZChcblx0XHRcdFx0XHRcdFx0cmVzb2x2ZShcblx0XHRcdFx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyLFxuXHRcdFx0XHRcdFx0XHRcdGlzRnVuY3Rpb24oIG9uRnVsZmlsbGVkICkgP1xuXHRcdFx0XHRcdFx0XHRcdFx0b25GdWxmaWxsZWQgOlxuXHRcdFx0XHRcdFx0XHRcdFx0SWRlbnRpdHlcblx0XHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdFx0Ly8gcmVqZWN0ZWRfaGFuZGxlcnMuYWRkKCAuLi4gKVxuXHRcdFx0XHRcdFx0dHVwbGVzWyAyIF1bIDMgXS5hZGQoXG5cdFx0XHRcdFx0XHRcdHJlc29sdmUoXG5cdFx0XHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlcixcblx0XHRcdFx0XHRcdFx0XHRpc0Z1bmN0aW9uKCBvblJlamVjdGVkICkgP1xuXHRcdFx0XHRcdFx0XHRcdFx0b25SZWplY3RlZCA6XG5cdFx0XHRcdFx0XHRcdFx0XHRUaHJvd2VyXG5cdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fSApLnByb21pc2UoKTtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBHZXQgYSBwcm9taXNlIGZvciB0aGlzIGRlZmVycmVkXG5cdFx0XHRcdC8vIElmIG9iaiBpcyBwcm92aWRlZCwgdGhlIHByb21pc2UgYXNwZWN0IGlzIGFkZGVkIHRvIHRoZSBvYmplY3Rcblx0XHRcdFx0cHJvbWlzZTogZnVuY3Rpb24oIG9iaiApIHtcblx0XHRcdFx0XHRyZXR1cm4gb2JqICE9IG51bGwgPyBqUXVlcnkuZXh0ZW5kKCBvYmosIHByb21pc2UgKSA6IHByb21pc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRkZWZlcnJlZCA9IHt9O1xuXG5cdFx0Ly8gQWRkIGxpc3Qtc3BlY2lmaWMgbWV0aG9kc1xuXHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcblx0XHRcdHZhciBsaXN0ID0gdHVwbGVbIDIgXSxcblx0XHRcdFx0c3RhdGVTdHJpbmcgPSB0dXBsZVsgNSBdO1xuXG5cdFx0XHQvLyBwcm9taXNlLnByb2dyZXNzID0gbGlzdC5hZGRcblx0XHRcdC8vIHByb21pc2UuZG9uZSA9IGxpc3QuYWRkXG5cdFx0XHQvLyBwcm9taXNlLmZhaWwgPSBsaXN0LmFkZFxuXHRcdFx0cHJvbWlzZVsgdHVwbGVbIDEgXSBdID0gbGlzdC5hZGQ7XG5cblx0XHRcdC8vIEhhbmRsZSBzdGF0ZVxuXHRcdFx0aWYgKCBzdGF0ZVN0cmluZyApIHtcblx0XHRcdFx0bGlzdC5hZGQoXG5cdFx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0XHRcdC8vIHN0YXRlID0gXCJyZXNvbHZlZFwiIChpLmUuLCBmdWxmaWxsZWQpXG5cdFx0XHRcdFx0XHQvLyBzdGF0ZSA9IFwicmVqZWN0ZWRcIlxuXHRcdFx0XHRcdFx0c3RhdGUgPSBzdGF0ZVN0cmluZztcblx0XHRcdFx0XHR9LFxuXG5cdFx0XHRcdFx0Ly8gcmVqZWN0ZWRfY2FsbGJhY2tzLmRpc2FibGVcblx0XHRcdFx0XHQvLyBmdWxmaWxsZWRfY2FsbGJhY2tzLmRpc2FibGVcblx0XHRcdFx0XHR0dXBsZXNbIDMgLSBpIF1bIDIgXS5kaXNhYmxlLFxuXG5cdFx0XHRcdFx0Ly8gcmVqZWN0ZWRfaGFuZGxlcnMuZGlzYWJsZVxuXHRcdFx0XHRcdC8vIGZ1bGZpbGxlZF9oYW5kbGVycy5kaXNhYmxlXG5cdFx0XHRcdFx0dHVwbGVzWyAzIC0gaSBdWyAzIF0uZGlzYWJsZSxcblxuXHRcdFx0XHRcdC8vIHByb2dyZXNzX2NhbGxiYWNrcy5sb2NrXG5cdFx0XHRcdFx0dHVwbGVzWyAwIF1bIDIgXS5sb2NrLFxuXG5cdFx0XHRcdFx0Ly8gcHJvZ3Jlc3NfaGFuZGxlcnMubG9ja1xuXHRcdFx0XHRcdHR1cGxlc1sgMCBdWyAzIF0ubG9ja1xuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBwcm9ncmVzc19oYW5kbGVycy5maXJlXG5cdFx0XHQvLyBmdWxmaWxsZWRfaGFuZGxlcnMuZmlyZVxuXHRcdFx0Ly8gcmVqZWN0ZWRfaGFuZGxlcnMuZmlyZVxuXHRcdFx0bGlzdC5hZGQoIHR1cGxlWyAzIF0uZmlyZSApO1xuXG5cdFx0XHQvLyBkZWZlcnJlZC5ub3RpZnkgPSBmdW5jdGlvbigpIHsgZGVmZXJyZWQubm90aWZ5V2l0aCguLi4pIH1cblx0XHRcdC8vIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbigpIHsgZGVmZXJyZWQucmVzb2x2ZVdpdGgoLi4uKSB9XG5cdFx0XHQvLyBkZWZlcnJlZC5yZWplY3QgPSBmdW5jdGlvbigpIHsgZGVmZXJyZWQucmVqZWN0V2l0aCguLi4pIH1cblx0XHRcdGRlZmVycmVkWyB0dXBsZVsgMCBdIF0gPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdKCB0aGlzID09PSBkZWZlcnJlZCA/IHVuZGVmaW5lZCA6IHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH07XG5cblx0XHRcdC8vIGRlZmVycmVkLm5vdGlmeVdpdGggPSBsaXN0LmZpcmVXaXRoXG5cdFx0XHQvLyBkZWZlcnJlZC5yZXNvbHZlV2l0aCA9IGxpc3QuZmlyZVdpdGhcblx0XHRcdC8vIGRlZmVycmVkLnJlamVjdFdpdGggPSBsaXN0LmZpcmVXaXRoXG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbIDAgXSArIFwiV2l0aFwiIF0gPSBsaXN0LmZpcmVXaXRoO1xuXHRcdH0gKTtcblxuXHRcdC8vIE1ha2UgdGhlIGRlZmVycmVkIGEgcHJvbWlzZVxuXHRcdHByb21pc2UucHJvbWlzZSggZGVmZXJyZWQgKTtcblxuXHRcdC8vIENhbGwgZ2l2ZW4gZnVuYyBpZiBhbnlcblx0XHRpZiAoIGZ1bmMgKSB7XG5cdFx0XHRmdW5jLmNhbGwoIGRlZmVycmVkLCBkZWZlcnJlZCApO1xuXHRcdH1cblxuXHRcdC8vIEFsbCBkb25lIVxuXHRcdHJldHVybi
1BkZWZlcnJlZDtcblx0fSxcblxuXHQvLyBEZWZlcnJlZCBoZWxwZXJcblx0d2hlbjogZnVuY3Rpb24oIHNpbmdsZVZhbHVlICkge1xuXHRcdHZhclxuXG5cdFx0XHQvLyBjb3VudCBvZiB1bmNvbXBsZXRlZCBzdWJvcmRpbmF0ZXNcblx0XHRcdHJlbWFpbmluZyA9IGFyZ3VtZW50cy5sZW5ndGgsXG5cblx0XHRcdC8vIGNvdW50IG9mIHVucHJvY2Vzc2VkIGFyZ3VtZW50c1xuXHRcdFx0aSA9IHJlbWFpbmluZyxcblxuXHRcdFx0Ly8gc3Vib3JkaW5hdGUgZnVsZmlsbG1lbnQgZGF0YVxuXHRcdFx0cmVzb2x2ZUNvbnRleHRzID0gQXJyYXkoIGkgKSxcblx0XHRcdHJlc29sdmVWYWx1ZXMgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSxcblxuXHRcdFx0Ly8gdGhlIHByaW1hcnkgRGVmZXJyZWRcblx0XHRcdHByaW1hcnkgPSBqUXVlcnkuRGVmZXJyZWQoKSxcblxuXHRcdFx0Ly8gc3Vib3JkaW5hdGUgY2FsbGJhY2sgZmFjdG9yeVxuXHRcdFx0dXBkYXRlRnVuYyA9IGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0XHRcdHJlc29sdmVDb250ZXh0c1sgaSBdID0gdGhpcztcblx0XHRcdFx0XHRyZXNvbHZlVmFsdWVzWyBpIF0gPSBhcmd1bWVudHMubGVuZ3RoID4gMSA/IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApIDogdmFsdWU7XG5cdFx0XHRcdFx0aWYgKCAhKCAtLXJlbWFpbmluZyApICkge1xuXHRcdFx0XHRcdFx0cHJpbWFyeS5yZXNvbHZlV2l0aCggcmVzb2x2ZUNvbnRleHRzLCByZXNvbHZlVmFsdWVzICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdFx0fTtcblxuXHRcdC8vIFNpbmdsZS0gYW5kIGVtcHR5IGFyZ3VtZW50cyBhcmUgYWRvcHRlZCBsaWtlIFByb21pc2UucmVzb2x2ZVxuXHRcdGlmICggcmVtYWluaW5nIDw9IDEgKSB7XG5cdFx0XHRhZG9wdFZhbHVlKCBzaW5nbGVWYWx1ZSwgcHJpbWFyeS5kb25lKCB1cGRhdGVGdW5jKCBpICkgKS5yZXNvbHZlLCBwcmltYXJ5LnJlamVjdCxcblx0XHRcdFx0IXJlbWFpbmluZyApO1xuXG5cdFx0XHQvLyBVc2UgLnRoZW4oKSB0byB1bndyYXAgc2Vjb25kYXJ5IHRoZW5hYmxlcyAoY2YuIGdoLTMwMDApXG5cdFx0XHRpZiAoIHByaW1hcnkuc3RhdGUoKSA9PT0gXCJwZW5kaW5nXCIgfHxcblx0XHRcdFx0aXNGdW5jdGlvbiggcmVzb2x2ZVZhbHVlc1sgaSBdICYmIHJlc29sdmVWYWx1ZXNbIGkgXS50aGVuICkgKSB7XG5cblx0XHRcdFx0cmV0dXJuIHByaW1hcnkudGhlbigpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE11bHRpcGxlIGFyZ3VtZW50cyBhcmUgYWdncmVnYXRlZCBsaWtlIFByb21pc2UuYWxsIGFycmF5IGVsZW1lbnRzXG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRhZG9wdFZhbHVlKCByZXNvbHZlVmFsdWVzWyBpIF0sIHVwZGF0ZUZ1bmMoIGkgKSwgcHJpbWFyeS5yZWplY3QgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gcHJpbWFyeS5wcm9taXNlKCk7XG5cdH1cbn0gKTtcblxuXG4vLyBUaGVzZSB1c3VhbGx5IGluZGljYXRlIGEgcHJvZ3JhbW1lciBtaXN0YWtlIGR1cmluZyBkZXZlbG9wbWVudCxcbi8vIHdhcm4gYWJvdXQgdGhlbSBBU0FQIHJhdGhlciB0aGFuIHN3YWxsb3dpbmcgdGhlbSBieSBkZWZhdWx0LlxudmFyIHJlcnJvck5hbWVzID0gL14oRXZhbHxJbnRlcm5hbHxSYW5nZXxSZWZlcmVuY2V8U3ludGF4fFR5cGV8VVJJKUVycm9yJC87XG5cbi8vIElmIGBqUXVlcnkuRGVmZXJyZWQuZ2V0RXJyb3JIb29rYCBpcyBkZWZpbmVkLCBgYXN5bmNFcnJvcmAgaXMgYW4gZXJyb3Jcbi8vIGNhcHR1cmVkIGJlZm9yZSB0aGUgYXN5bmMgYmFycmllciB0byBnZXQgdGhlIG9yaWdpbmFsIGVycm9yIGNhdXNlXG4vLyB3aGljaCBtYXkgb3RoZXJ3aXNlIGJlIGhpZGRlbi5cbmpRdWVyeS5EZWZlcnJlZC5leGNlcHRpb25Ib29rID0gZnVuY3Rpb24oIGVycm9yLCBhc3luY0Vycm9yICkge1xuXG5cdC8vIFN1cHBvcnQ6IElFIDggLSA5IG9ubHlcblx0Ly8gQ29uc29sZSBleGlzdHMgd2hlbiBkZXYgdG9vbHMgYXJlIG9wZW4sIHdoaWNoIGNhbiBoYXBwZW4gYXQgYW55IHRpbWVcblx0aWYgKCB3aW5kb3cuY29uc29sZSAmJiB3aW5kb3cuY29uc29sZS53YXJuICYmIGVycm9yICYmIHJlcnJvck5hbWVzLnRlc3QoIGVycm9yLm5hbWUgKSApIHtcblx0XHR3aW5kb3cuY29uc29sZS53YXJuKCBcImpRdWVyeS5EZWZlcnJlZCBleGNlcHRpb246IFwiICsgZXJyb3IubWVzc2FnZSxcblx0XHRcdGVycm9yLnN0YWNrLCBhc3luY0Vycm9yICk7XG5cdH1cbn07XG5cblxuXG5cbmpRdWVyeS5yZWFkeUV4Y2VwdGlvbiA9IGZ1bmN0aW9uKCBlcnJvciApIHtcblx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdHRocm93IGVycm9yO1xuXHR9ICk7XG59O1xuXG5cblxuXG4vLyBUaGUgZGVmZXJyZWQgdXNlZCBvbiBET00gcmVhZHlcbnZhciByZWFkeUxpc3QgPSBqUXVlcnkuRGVmZXJyZWQoKTtcblxualF1ZXJ5LmZuLnJlYWR5ID0gZnVuY3Rpb24oIGZuICkge1xuXG5cdHJlYWR5TGlzdFxuXHRcdC50aGVuKCBmbiApXG5cblx0XHQvLyBXcmFwIGpRdWVyeS5yZWFkeUV4Y2VwdGlvbiBpbiBhIGZ1bmN0aW9uIHNvIHRoYXQgdGhlIGxvb2t1cFxuXHRcdC8vIGhhcHBlbnMgYXQgdGhlIHRpbWUgb2YgZXJyb3IgaGFuZGxpbmcgaW5zdGVhZCBvZiBjYWxsYmFja1xuXHRcdC8vIHJlZ2lzdHJhdGlvbi5cblx0XHQuY2F0Y2goIGZ1bmN0aW9uKCBlcnJvciApIHtcblx0XHRcdGpRdWVyeS5yZWFkeUV4Y2VwdGlvbiggZXJyb3IgKTtcblx0XHR9ICk7XG5cblx0cmV0dXJuIHRoaXM7XG59O1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cblx0Ly8gSXMgdGhlIERPTSByZWFkeSB0byBiZSB1c2VkPyBTZXQgdG8gdHJ1ZSBvbmNlIGl0IG9jY3Vycy5cblx0aXNSZWFkeTogZmFsc2UsXG5cblx0Ly8gQSBjb3VudGVyIHRvIHRyYWNrIGhvdyBtYW55IGl0ZW1zIHRvIHdhaXQgZm9yIGJlZm9yZVxuXHQvLyB0aGUgcmVhZHkgZXZlbnQgZmlyZXMuIFNlZSB0cmFjLTY3ODFcblx0cmVhZHlXYWl0OiAxLFxuXG5cdC8vIEhhbmRsZSB3aGVuIHRoZSBET00gaXMgcmVhZHlcblx0cmVhZHk6IGZ1bmN0aW9uKCB3YWl0ICkge1xuXG5cdFx0Ly8gQWJvcnQgaWYgdGhlcmUgYXJlIHBlbmRpbmcgaG9sZHMgb3Igd2UncmUgYWxyZWFkeSByZWFkeVxuXHRcdGlmICggd2FpdCA9PT0gdHJ1ZSA/IC0talF1ZXJ5LnJlYWR5V2Fp
1dCA6IGpRdWVyeS5pc1JlYWR5ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFJlbWVtYmVyIHRoYXQgdGhlIERPTSBpcyByZWFkeVxuXHRcdGpRdWVyeS5pc1JlYWR5ID0gdHJ1ZTtcblxuXHRcdC8vIElmIGEgbm9ybWFsIERPTSBSZWFkeSBldmVudCBmaXJlZCwgZGVjcmVtZW50LCBhbmQgd2FpdCBpZiBuZWVkIGJlXG5cdFx0aWYgKCB3YWl0ICE9PSB0cnVlICYmIC0talF1ZXJ5LnJlYWR5V2FpdCA+IDAgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gSWYgdGhlcmUgYXJlIGZ1bmN0aW9ucyBib3VuZCwgdG8gZXhlY3V0ZVxuXHRcdHJlYWR5TGlzdC5yZXNvbHZlV2l0aCggZG9jdW1lbnQsIFsgalF1ZXJ5IF0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkucmVhZHkudGhlbiA9IHJlYWR5TGlzdC50aGVuO1xuXG4vLyBUaGUgcmVhZHkgZXZlbnQgaGFuZGxlciBhbmQgc2VsZiBjbGVhbnVwIG1ldGhvZFxuZnVuY3Rpb24gY29tcGxldGVkKCkge1xuXHRkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgY29tcGxldGVkICk7XG5cdHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCBcImxvYWRcIiwgY29tcGxldGVkICk7XG5cdGpRdWVyeS5yZWFkeSgpO1xufVxuXG4vLyBDYXRjaCBjYXNlcyB3aGVyZSAkKGRvY3VtZW50KS5yZWFkeSgpIGlzIGNhbGxlZFxuLy8gYWZ0ZXIgdGhlIGJyb3dzZXIgZXZlbnQgaGFzIGFscmVhZHkgb2NjdXJyZWQuXG4vLyBTdXBwb3J0OiBJRSA8PTkgLSAxMCBvbmx5XG4vLyBPbGRlciBJRSBzb21ldGltZXMgc2lnbmFscyBcImludGVyYWN0aXZlXCIgdG9vIHNvb25cbmlmICggZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gXCJjb21wbGV0ZVwiIHx8XG5cdCggZG9jdW1lbnQucmVhZHlTdGF0ZSAhPT0gXCJsb2FkaW5nXCIgJiYgIWRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kb1Njcm9sbCApICkge1xuXG5cdC8vIEhhbmRsZSBpdCBhc3luY2hyb25vdXNseSB0byBhbGxvdyBzY3JpcHRzIHRoZSBvcHBvcnR1bml0eSB0byBkZWxheSByZWFkeVxuXHR3aW5kb3cuc2V0VGltZW91dCggalF1ZXJ5LnJlYWR5ICk7XG5cbn0gZWxzZSB7XG5cblx0Ly8gVXNlIHRoZSBoYW5keSBldmVudCBjYWxsYmFja1xuXHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgY29tcGxldGVkICk7XG5cblx0Ly8gQSBmYWxsYmFjayB0byB3aW5kb3cub25sb2FkLCB0aGF0IHdpbGwgYWx3YXlzIHdvcmtcblx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQgKTtcbn1cblxuXG5cblxuLy8gTXVsdGlmdW5jdGlvbmFsIG1ldGhvZCB0byBnZXQgYW5kIHNldCB2YWx1ZXMgb2YgYSBjb2xsZWN0aW9uXG4vLyBUaGUgdmFsdWUvcyBjYW4gb3B0aW9uYWxseSBiZSBleGVjdXRlZCBpZiBpdCdzIGEgZnVuY3Rpb25cbnZhciBhY2Nlc3MgPSBmdW5jdGlvbiggZWxlbXMsIGZuLCBrZXksIHZhbHVlLCBjaGFpbmFibGUsIGVtcHR5R2V0LCByYXcgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSBlbGVtcy5sZW5ndGgsXG5cdFx0YnVsayA9IGtleSA9PSBudWxsO1xuXG5cdC8vIFNldHMgbWFueSB2YWx1ZXNcblx0aWYgKCB0b1R5cGUoIGtleSApID09PSBcIm9iamVjdFwiICkge1xuXHRcdGNoYWluYWJsZSA9IHRydWU7XG5cdFx0Zm9yICggaSBpbiBrZXkgKSB7XG5cdFx0XHRhY2Nlc3MoIGVsZW1zLCBmbiwgaSwga2V5WyBpIF0sIHRydWUsIGVtcHR5R2V0LCByYXcgKTtcblx0XHR9XG5cblx0Ly8gU2V0cyBvbmUgdmFsdWVcblx0fSBlbHNlIGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRjaGFpbmFibGUgPSB0cnVlO1xuXG5cdFx0aWYgKCAhaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJhdyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKCBidWxrICkge1xuXG5cdFx0XHQvLyBCdWxrIG9wZXJhdGlvbnMgcnVuIGFnYWluc3QgdGhlIGVudGlyZSBzZXRcblx0XHRcdGlmICggcmF3ICkge1xuXHRcdFx0XHRmbi5jYWxsKCBlbGVtcywgdmFsdWUgKTtcblx0XHRcdFx0Zm4gPSBudWxsO1xuXG5cdFx0XHQvLyAuLi5leGNlcHQgd2hlbiBleGVjdXRpbmcgZnVuY3Rpb24gdmFsdWVzXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRidWxrID0gZm47XG5cdFx0XHRcdGZuID0gZnVuY3Rpb24oIGVsZW0sIF9rZXksIHZhbHVlICkge1xuXHRcdFx0XHRcdHJldHVybiBidWxrLmNhbGwoIGpRdWVyeSggZWxlbSApLCB2YWx1ZSApO1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggZm4gKSB7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0Zm4oXG5cdFx0XHRcdFx0ZWxlbXNbIGkgXSwga2V5LCByYXcgP1xuXHRcdFx0XHRcdFx0dmFsdWUgOlxuXHRcdFx0XHRcdFx0dmFsdWUuY2FsbCggZWxlbXNbIGkgXSwgaSwgZm4oIGVsZW1zWyBpIF0sIGtleSApIClcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRpZiAoIGNoYWluYWJsZSApIHtcblx0XHRyZXR1cm4gZWxlbXM7XG5cdH1cblxuXHQvLyBHZXRzXG5cdGlmICggYnVsayApIHtcblx0XHRyZXR1cm4gZm4uY2FsbCggZWxlbXMgKTtcblx0fVxuXG5cdHJldHVybiBsZW4gPyBmb
1iggZWxlbXNbIDAgXSwga2V5ICkgOiBlbXB0eUdldDtcbn07XG5cblxuLy8gTWF0Y2hlcyBkYXNoZWQgc3RyaW5nIGZvciBjYW1lbGl6aW5nXG52YXIgcm1zUHJlZml4ID0gL14tbXMtLyxcblx0cmRhc2hBbHBoYSA9IC8tKFthLXpdKS9nO1xuXG4vLyBVc2VkIGJ5IGNhbWVsQ2FzZSBhcyBjYWxsYmFjayB0byByZXBsYWNlKClcbmZ1bmN0aW9uIGZjYW1lbENhc2UoIF9hbGwsIGxldHRlciApIHtcblx0cmV0dXJuIGxldHRlci50b1VwcGVyQ2FzZSgpO1xufVxuXG4vLyBDb252ZXJ0IGRhc2hlZCB0byBjYW1lbENhc2U7IHVzZWQgYnkgdGhlIGNzcyBhbmQgZGF0YSBtb2R1bGVzXG4vLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSwgRWRnZSAxMiAtIDE1XG4vLyBNaWNyb3NvZnQgZm9yZ290IHRvIGh1bXAgdGhlaXIgdmVuZG9yIHByZWZpeCAodHJhYy05NTcyKVxuZnVuY3Rpb24gY2FtZWxDYXNlKCBzdHJpbmcgKSB7XG5cdHJldHVybiBzdHJpbmcucmVwbGFjZSggcm1zUHJlZml4LCBcIm1zLVwiICkucmVwbGFjZSggcmRhc2hBbHBoYSwgZmNhbWVsQ2FzZSApO1xufVxudmFyIGFjY2VwdERhdGEgPSBmdW5jdGlvbiggb3duZXIgKSB7XG5cblx0Ly8gQWNjZXB0cyBvbmx5OlxuXHQvLyAgLSBOb2RlXG5cdC8vICAgIC0gTm9kZS5FTEVNRU5UX05PREVcblx0Ly8gICAgLSBOb2RlLkRPQ1VNRU5UX05PREVcblx0Ly8gIC0gT2JqZWN0XG5cdC8vICAgIC0gQW55XG5cdHJldHVybiBvd25lci5ub2RlVHlwZSA9PT0gMSB8fCBvd25lci5ub2RlVHlwZSA9PT0gOSB8fCAhKCArb3duZXIubm9kZVR5cGUgKTtcbn07XG5cblxuXG5cbmZ1bmN0aW9uIERhdGEoKSB7XG5cdHRoaXMuZXhwYW5kbyA9IGpRdWVyeS5leHBhbmRvICsgRGF0YS51aWQrKztcbn1cblxuRGF0YS51aWQgPSAxO1xuXG5EYXRhLnByb3RvdHlwZSA9IHtcblxuXHRjYWNoZTogZnVuY3Rpb24oIG93bmVyICkge1xuXG5cdFx0Ly8gQ2hlY2sgaWYgdGhlIG93bmVyIG9iamVjdCBhbHJlYWR5IGhhcyBhIGNhY2hlXG5cdFx0dmFyIHZhbHVlID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xuXG5cdFx0Ly8gSWYgbm90LCBjcmVhdGUgb25lXG5cdFx0aWYgKCAhdmFsdWUgKSB7XG5cdFx0XHR2YWx1ZSA9IHt9O1xuXG5cdFx0XHQvLyBXZSBjYW4gYWNjZXB0IGRhdGEgZm9yIG5vbi1lbGVtZW50IG5vZGVzIGluIG1vZGVybiBicm93c2Vycyxcblx0XHRcdC8vIGJ1dCB3ZSBzaG91bGQgbm90LCBzZWUgdHJhYy04MzM1LlxuXHRcdFx0Ly8gQWx3YXlzIHJldHVybiBhbiBlbXB0eSBvYmplY3QuXG5cdFx0XHRpZiAoIGFjY2VwdERhdGEoIG93bmVyICkgKSB7XG5cblx0XHRcdFx0Ly8gSWYgaXQgaXMgYSBub2RlIHVubGlrZWx5IHRvIGJlIHN0cmluZ2lmeS1lZCBvciBsb29wZWQgb3ZlclxuXHRcdFx0XHQvLyB1c2UgcGxhaW4gYXNzaWdubWVudFxuXHRcdFx0XHRpZiAoIG93bmVyLm5vZGVUeXBlICkge1xuXHRcdFx0XHRcdG93bmVyWyB0aGlzLmV4cGFuZG8gXSA9IHZhbHVlO1xuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBzZWN1cmUgaXQgaW4gYSBub24tZW51bWVyYWJsZSBwcm9wZXJ0eVxuXHRcdFx0XHQvLyBjb25maWd1cmFibGUgbXVzdCBiZSB0cnVlIHRvIGFsbG93IHRoZSBwcm9wZXJ0eSB0byBiZVxuXHRcdFx0XHQvLyBkZWxldGVkIHdoZW4gZGF0YSBpcyByZW1vdmVkXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCBvd25lciwgdGhpcy5leHBhbmRvLCB7XG5cdFx0XHRcdFx0XHR2YWx1ZTogdmFsdWUsXG5cdFx0XHRcdFx0XHRjb25maWd1cmFibGU6IHRydWVcblx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdmFsdWU7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24oIG93bmVyLCBkYXRhLCB2YWx1ZSApIHtcblx0XHR2YXIgcHJvcCxcblx0XHRcdGNhY2hlID0gdGhpcy5jYWNoZSggb3duZXIgKTtcblxuXHRcdC8vIEhhbmRsZTogWyBvd25lciwga2V5LCB2YWx1ZSBdIGFyZ3Ncblx0XHQvLyBBbHdheXMgdXNlIGNhbWVsQ2FzZSBrZXkgKGdoLTIyNTcpXG5cdFx0aWYgKCB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGNhY2hlWyBjYW1lbENhc2UoIGRhdGEgKSBdID0gdmFsdWU7XG5cblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIHsgcHJvcGVydGllcyB9IF0gYXJnc1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIENvcHkgdGhlIHByb3BlcnRpZXMgb25lLWJ5LW9uZSB0byB0aGUgY2FjaGUgb2JqZWN0XG5cdFx0XHRmb3IgKCBwcm9wIGluIGRhdGEgKSB7XG5cdFx0XHRcdGNhY2hlWyBjYW1lbENhc2UoIHByb3AgKSBdID0gZGF0YVsgcHJvcCBdO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gY2FjaGU7XG5cdH0sXG5cdGdldDogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7XG5cdFx0cmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHRoaXMuY2FjaGUoIG93bmVyICkgOlxuXG5cdFx0XHQvLyBBbHdheXMgdXNlIGNhbWVsQ2FzZSBrZXkgKGdoLTIyNTcpXG5cdFx0XHRvd25lclsgdGhpcy5leHBhbmRvIF0gJiYgb3duZXJbIHRoaXMuZXhwYW5kbyBdWyBjYW1lbENhc2UoIGtleSApIF07XG5cdH0sXG5cdGFjY2VzczogZnVuY3Rpb24oIG93bmVyLCBrZXksIHZhbHVlICkge1xuXG5cdFx0Ly8gSW4gY2FzZXMgd2hlcmUgZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBObyBrZXkgd2FzIHNwZWNpZmllZFxuXHRcdC8vICAgMi4gQSBzdHJpbmcga2V5IHdhcyBzcGVjaWZpZWQsIGJ1dCBubyB2YWx1ZSBwcm92aWRlZFxuXHRcdC8vXG5cdFx0Ly8gVGFrZSB0aGUgXCJyZWFkXCIgcGF0aCBhbmQgYWxsb3cgdGhlIGdldCBtZXRob2QgdG8gZGV0ZXJtaW5lXG5cdFx0Ly8gd2hpY2ggdmFsdWUgdG8gcmV0dXJuLCByZXNwZWN0aXZlbHkgZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBUaGUgZW50aXJlIGNhY2hlIG9iamVjdFxuXHRcdC8vICAgMi4gVGhlIGRhdGEgc3RvcmVkIGF0IHRoZSBrZXlcblx0XHQvL1xuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0KCAoIGtleSAmJiB0eXBlb2Yga2V5ID09PSBcInN0cmluZ1wiICkgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCApICkge1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5nZXQoIG93bmVyLCBrZXkgKTtcblx0XHR9XG5cblx0XHQvLyBXaGVuIHRoZSBrZXkgaXMgbm90IGEgc3RyaW5nLCBvciBib3RoIGEga2V5IGFuZCB2YWx1ZVxuXHRcdC8vIGFyZSBzcGVjaWZpZWQsIHNldCBvciBleHRlbmQgKGV4aXN0aW5nIG9iamVjdHMpIHdpdGggZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBBbiBvYmplY3Qgb2YgcHJvcGVydGllc1xuXHRcdC8vICAgMi4gQSBrZXkgYW5kIHZhbHVlXG5cdFx0Ly9cblx0XHR0aGlzLnNldCggb3duZXIsIGtleSwgdmFsdWUgKTtcblxuXHRcdC8vIFNpbmNlIHRoZSBcInNldFwiIHBhdGggY2FuIGhhdmUgdHdvIHBvc3NpYmxlIGVudHJ5IHBvaW50c1xuXHRcdC8vIHJldHVybi
1B0aGUgZXhwZWN0ZWQgZGF0YSBiYXNlZCBvbiB3aGljaCBwYXRoIHdhcyB0YWtlblsqXVxuXHRcdHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUgOiBrZXk7XG5cdH0sXG5cdHJlbW92ZTogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7XG5cdFx0dmFyIGksXG5cdFx0XHRjYWNoZSA9IG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcblxuXHRcdGlmICggY2FjaGUgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIGtleSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHQvLyBTdXBwb3J0IGFycmF5IG9yIHNwYWNlIHNlcGFyYXRlZCBzdHJpbmcgb2Yga2V5c1xuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCBrZXkgKSApIHtcblxuXHRcdFx0XHQvLyBJZiBrZXkgaXMgYW4gYXJyYXkgb2Yga2V5cy4uLlxuXHRcdFx0XHQvLyBXZSBhbHdheXMgc2V0IGNhbWVsQ2FzZSBrZXlzLCBzbyByZW1vdmUgdGhhdC5cblx0XHRcdFx0a2V5ID0ga2V5Lm1hcCggY2FtZWxDYXNlICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRrZXkgPSBjYW1lbENhc2UoIGtleSApO1xuXG5cdFx0XHRcdC8vIElmIGEga2V5IHdpdGggdGhlIHNwYWNlcyBleGlzdHMsIHVzZSBpdC5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCBjcmVhdGUgYW4gYXJyYXkgYnkgbWF0Y2hpbmcgbm9uLXdoaXRlc3BhY2Vcblx0XHRcdFx0a2V5ID0ga2V5IGluIGNhY2hlID9cblx0XHRcdFx0XHRbIGtleSBdIDpcblx0XHRcdFx0XHQoIGtleS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdICk7XG5cdFx0XHR9XG5cblx0XHRcdGkgPSBrZXkubGVuZ3RoO1xuXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0ZGVsZXRlIGNhY2hlWyBrZXlbIGkgXSBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSB0aGUgZXhwYW5kbyBpZiB0aGVyZSdzIG5vIG1vcmUgZGF0YVxuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgfHwgalF1ZXJ5LmlzRW1wdHlPYmplY3QoIGNhY2hlICkgKSB7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDVcblx0XHRcdC8vIFdlYmtpdCAmIEJsaW5rIHBlcmZvcm1hbmNlIHN1ZmZlcnMgd2hlbiBkZWxldGluZyBwcm9wZXJ0aWVzXG5cdFx0XHQvLyBmcm9tIERPTSBub2Rlcywgc28gc2V0IHRvIHVuZGVmaW5lZCBpbnN0ZWFkXG5cdFx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0zNzg2MDcgKGJ1ZyByZXN0cmljdGVkKVxuXHRcdFx0aWYgKCBvd25lci5ub2RlVHlwZSApIHtcblx0XHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVsZXRlIG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBvd25lciApIHtcblx0XHR2YXIgY2FjaGUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cdFx0cmV0dXJuIGNhY2hlICE9PSB1bmRlZmluZWQgJiYgIWpRdWVyeS5pc0VtcHR5T2JqZWN0KCBjYWNoZSApO1xuXHR9XG59O1xudmFyIGRhdGFQcml2ID0gbmV3IERhdGEoKTtcblxudmFyIGRhdGFVc2VyID0gbmV3IERhdGEoKTtcblxuXG5cbi8vXHRJbXBsZW1lbnRhdGlvbiBTdW1tYXJ5XG4vL1xuLy9cdDEuIEVuZm9yY2UgQVBJIHN1cmZhY2UgYW5kIHNlbWFudGljIGNvbXBhdGliaWxpdHkgd2l0aCAxLjkueCBicmFuY2hcbi8vXHQyLiBJbXByb3ZlIHRoZSBtb2R1bGUncyBtYWludGFpbmFiaWxpdHkgYnkgcmVkdWNpbmcgdGhlIHN0b3JhZ2Vcbi8vXHRcdHBhdGhzIHRvIGEgc2luZ2xlIG1lY2hhbmlzbS5cbi8vXHQzLiBVc2UgdGhlIHNhbWUgc2luZ2xlIG1lY2hhbmlzbSB0byBzdXBwb3J0IFwicHJpdmF0ZVwiIGFuZCBcInVzZXJcIiBkYXRhLlxuLy9cdDQuIF9OZXZlcl8gZXhwb3NlIFwicHJpdmF0ZVwiIGRhdGEgdG8gdXNlciBjb2RlIChUT0RPOiBEcm9wIF9kYXRhLCBfcmVtb3ZlRGF0YSlcbi8vXHQ1LiBBdm9pZCBleHBvc2luZyBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIG9uIHVzZXIgb2JqZWN0cyAoZWcuIGV4cGFuZG8gcHJvcGVydGllcylcbi8vXHQ2LiBQcm92aWRlIGEgY2xlYXIgcGF0aCBmb3IgaW1wbGVtZW50YXRpb24gdXBncmFkZSB0byBXZWFrTWFwIGluIDIwMTRcblxudmFyIHJicmFjZSA9IC9eKD86XFx7W1xcd1xcV10qXFx9fFxcW1tcXHdcXFddKlxcXSkkLyxcblx0cm11bHRpRGFzaCA9IC9bQS1aXS9nO1xuXG5mdW5jdGlvbiBnZXREYXRhKCBkYXRhICkge1xuXHRpZiAoIGRhdGEgPT09IFwidHJ1ZVwiICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0aWYgKCBkYXRhID09PSBcImZhbHNlXCIgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0aWYgKCBkYXRhID09PSBcIm51bGxcIiApIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIE9ubHkgY29udmVydCB0byBhIG51bWJlciBpZiBpdCBkb2Vzbid0IGNoYW5nZSB0aGUgc3RyaW5nXG5cdGlmICggZGF0YSA9PT0gK2RhdGEgKyBcIlwiICkge1xuXHRcdHJldHVybiArZGF0YTtcblx0fVxuXG5cdGlmICggcmJyYWNlLnRlc3QoIGRhdGEgKSApIHtcblx0XHRyZXR1cm4gSlNPTi5wYXJzZSggZGF0YSApO1xuXHR9XG5cblx0cmV0dXJuIGRhdGE7XG59XG5cbmZ1bmN0aW9uIGRhdGFBdHRyKCBlbGVtLCBrZXksIGRhdGEgKSB7XG5cdHZhciBuYW1lO1xuXG5cdC8vIElmIG5vdGhpbmcgd2FzIGZvdW5kIGludGVybmFsbHksIHRyeSB0byBmZXRjaCBhbnlcblx0Ly8gZGF0YSBmcm9tIHRoZSBIVE1MNSBkYXRhLSogYXR0cmlidXRlXG5cdGlmICggZGF0YSA9PT0gdW5kZWZpbmVkICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0bmFtZSA9IFwiZGF0YS1cIiArIGtleS5yZXBsYWNlKCBybXVsdGlEYXNoLCBcIi0kJlwiICkudG9Mb3dlckNhc2UoKTtcblx0XHRkYXRhID0gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKTtcblxuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRkYXRhID0gZ2V0RGF0YSggZGF0YSApO1xuXHRcdFx0fSBjYXRjaCAoIGUgKSB7fVxuXG5cdFx0XHQvLyBNYWtlIHN1cmUgd2Ug
1c2V0IHRoZSBkYXRhIHNvIGl0IGlzbid0IGNoYW5nZWQgbGF0ZXJcblx0XHRcdGRhdGFVc2VyLnNldCggZWxlbSwga2V5LCBkYXRhICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBkYXRhO1xufVxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkYXRhVXNlci5oYXNEYXRhKCBlbGVtICkgfHwgZGF0YVByaXYuaGFzRGF0YSggZWxlbSApO1xuXHR9LFxuXG5cdGRhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhVXNlci5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcblx0fSxcblxuXHRyZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRkYXRhVXNlci5yZW1vdmUoIGVsZW0sIG5hbWUgKTtcblx0fSxcblxuXHQvLyBUT0RPOiBOb3cgdGhhdCBhbGwgY2FsbHMgdG8gX2RhdGEgYW5kIF9yZW1vdmVEYXRhIGhhdmUgYmVlbiByZXBsYWNlZFxuXHQvLyB3aXRoIGRpcmVjdCBjYWxscyB0byBkYXRhUHJpdiBtZXRob2RzLCB0aGVzZSBjYW4gYmUgZGVwcmVjYXRlZC5cblx0X2RhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhUHJpdi5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcblx0fSxcblxuXHRfcmVtb3ZlRGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cdFx0ZGF0YVByaXYucmVtb3ZlKCBlbGVtLCBuYW1lICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRkYXRhOiBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHR2YXIgaSwgbmFtZSwgZGF0YSxcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXG5cdFx0XHRhdHRycyA9IGVsZW0gJiYgZWxlbS5hdHRyaWJ1dGVzO1xuXG5cdFx0Ly8gR2V0cyBhbGwgdmFsdWVzXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGlmICggdGhpcy5sZW5ndGggKSB7XG5cdFx0XHRcdGRhdGEgPSBkYXRhVXNlci5nZXQoIGVsZW0gKTtcblxuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgIWRhdGFQcml2LmdldCggZWxlbSwgXCJoYXNEYXRhQXR0cnNcIiApICkge1xuXHRcdFx0XHRcdGkgPSBhdHRycy5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDExIG9ubHlcblx0XHRcdFx0XHRcdC8vIFRoZSBhdHRycyBlbGVtZW50cyBjYW4gYmUgbnVsbCAodHJhYy0xNDg5NClcblx0XHRcdFx0XHRcdGlmICggYXR0cnNbIGkgXSApIHtcblx0XHRcdFx0XHRcdFx0bmFtZSA9IGF0dHJzWyBpIF0ubmFtZTtcblx0XHRcdFx0XHRcdFx0aWYgKCBuYW1lLmluZGV4T2YoIFwiZGF0YS1cIiApID09PSAwICkge1xuXHRcdFx0XHRcdFx0XHRcdG5hbWUgPSBjYW1lbENhc2UoIG5hbWUuc2xpY2UoIDUgKSApO1xuXHRcdFx0XHRcdFx0XHRcdGRhdGFBdHRyKCBlbGVtLCBuYW1lLCBkYXRhWyBuYW1lIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZGF0YTtcblx0XHR9XG5cblx0XHQvLyBTZXRzIG11bHRpcGxlIHZhbHVlc1xuXHRcdGlmICggdHlwZW9mIGtleSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhVXNlci5zZXQoIHRoaXMsIGtleSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBkYXRhO1xuXG5cdFx0XHQvLyBUaGUgY2FsbGluZyBqUXVlcnkgb2JqZWN0IChlbGVtZW50IG1hdGNoZXMpIGlzIG5vdCBlbXB0eVxuXHRcdFx0Ly8gKGFuZCB0aGVyZWZvcmUgaGFzIGFuIGVsZW1lbnQgYXBwZWFycyBhdCB0aGlzWyAwIF0pIGFuZCB0aGVcblx0XHRcdC8vIGB2YWx1ZWAgcGFyYW1ldGVyIHdhcyBub3QgdW5kZWZpbmVkLiBBbiBlbXB0eSBqUXVlcnkgb2JqZWN0XG5cdFx0XHQvLyB3aWxsIHJlc3VsdCBpbiBgdW5kZWZpbmVkYCBmb3IgZWxlbSA9IHRoaXNbIDAgXSB3aGljaCB3aWxsXG5cdFx0XHQvLyB0aHJvdyBhbiBleGNlcHRpb24gaWYgYW4gYXR0ZW1wdCB0byByZWFkIGEgZGF0YSBjYWNoZSBpcyBtYWRlLlxuXHRcdFx0aWYgKCBlbGVtICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBnZXQgZGF0YSBmcm9tIHRoZSBjYWNoZVxuXHRcdFx0XHQvLyBUaGUga2V5IHdpbGwgYWx3YXlzIGJlIGNhbWVsQ2FzZWQgaW4gRGF0YVxuXHRcdFx0XHRkYXRhID0gZGF0YVVzZXIuZ2V0KCBlbGVtLCBrZXkgKTtcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBdHRlbXB0IHRvIFwiZGlzY292ZXJcIiB0aGUgZGF0YSBpblxuXHRcdFx0XHQvLyBIVE1MNSBjdXN0b20gZGF0YS0qIGF0dHJzXG5cdFx0XHRcdGRhdGEgPSBkYXRhQXR0ciggZWxlbSwga2V5ICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gV2UgdHJpZWQgcmVhbGx5IGhhcmQsIGJ1dCB0aGUgZGF0YSBkb2Vzbid0IGV4aXN0LlxuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgZGF0YS4uLlxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBXZSBhbHdheXMgc3RvcmUgdGhlIGNhbWVsQ2FzZWQga2V5XG5cdFx0XHRcdGRhdGFVc2VyLnNldCggdGhpcywga2V5LCB2YWx1ZSApO1xuXHRcdFx0fSApO1xuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSwgbnVsbCwgdHJ1ZSApO1xuXHR9LFxuXG5cdHJlbW92ZURhdGE6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRkYXRhVXNlci5yZW1vdmUoIHRoaXMsIGtleSApO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5cbmpRdWVyeS5leHRlbmQoIHtcblx0cXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBx
1dWV1ZTtcblxuXHRcdGlmICggZWxlbSApIHtcblx0XHRcdHR5cGUgPSAoIHR5cGUgfHwgXCJmeFwiICkgKyBcInF1ZXVlXCI7XG5cdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmdldCggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHQvLyBTcGVlZCB1cCBkZXF1ZXVlIGJ5IGdldHRpbmcgb3V0IHF1aWNrbHkgaWYgdGhpcyBpcyBqdXN0IGEgbG9va3VwXG5cdFx0XHRpZiAoIGRhdGEgKSB7XG5cdFx0XHRcdGlmICggIXF1ZXVlIHx8IEFycmF5LmlzQXJyYXkoIGRhdGEgKSApIHtcblx0XHRcdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmFjY2VzcyggZWxlbSwgdHlwZSwgalF1ZXJ5Lm1ha2VBcnJheSggZGF0YSApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cXVldWUucHVzaCggZGF0YSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcXVldWUgfHwgW107XG5cdFx0fVxuXHR9LFxuXG5cdGRlcXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRcdHZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggZWxlbSwgdHlwZSApLFxuXHRcdFx0c3RhcnRMZW5ndGggPSBxdWV1ZS5sZW5ndGgsXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCksXG5cdFx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgdHlwZSApLFxuXHRcdFx0bmV4dCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggZWxlbSwgdHlwZSApO1xuXHRcdFx0fTtcblxuXHRcdC8vIElmIHRoZSBmeCBxdWV1ZSBpcyBkZXF1ZXVlZCwgYWx3YXlzIHJlbW92ZSB0aGUgcHJvZ3Jlc3Mgc2VudGluZWxcblx0XHRpZiAoIGZuID09PSBcImlucHJvZ3Jlc3NcIiApIHtcblx0XHRcdGZuID0gcXVldWUuc2hpZnQoKTtcblx0XHRcdHN0YXJ0TGVuZ3RoLS07XG5cdFx0fVxuXG5cdFx0aWYgKCBmbiApIHtcblxuXHRcdFx0Ly8gQWRkIGEgcHJvZ3Jlc3Mgc2VudGluZWwgdG8gcHJldmVudCB0aGUgZnggcXVldWUgZnJvbSBiZWluZ1xuXHRcdFx0Ly8gYXV0b21hdGljYWxseSBkZXF1ZXVlZFxuXHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgKSB7XG5cdFx0XHRcdHF1ZXVlLnVuc2hpZnQoIFwiaW5wcm9ncmVzc1wiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENsZWFyIHVwIHRoZSBsYXN0IHF1ZXVlIHN0b3AgZnVuY3Rpb25cblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xuXHRcdFx0Zm4uY2FsbCggZWxlbSwgbmV4dCwgaG9va3MgKTtcblx0XHR9XG5cblx0XHRpZiAoICFzdGFydExlbmd0aCAmJiBob29rcyApIHtcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gTm90IHB1YmxpYyAtIGdlbmVyYXRlIGEgcXVldWVIb29rcyBvYmplY3QsIG9yIHJldHVybiB0aGUgY3VycmVudCBvbmVcblx0X3F1ZXVlSG9va3M6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHZhciBrZXkgPSB0eXBlICsgXCJxdWV1ZUhvb2tzXCI7XG5cdFx0cmV0dXJuIGRhdGFQcml2LmdldCggZWxlbSwga2V5ICkgfHwgZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBrZXksIHtcblx0XHRcdGVtcHR5OiBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKS5hZGQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFsgdHlwZSArIFwicXVldWVcIiwga2V5IF0gKTtcblx0XHRcdH0gKVxuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHF1ZXVlOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgc2V0dGVyID0gMjtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRkYXRhID0gdHlwZTtcblx0XHRcdHR5cGUgPSBcImZ4XCI7XG5cdFx0XHRzZXR0ZXItLTtcblx0XHR9XG5cblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPCBzZXR0ZXIgKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LnF1ZXVlKCB0aGlzWyAwIF0sIHR5cGUgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHRoaXMgOlxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCB0aGlzLCB0eXBlLCBkYXRhICk7XG5cblx0XHRcdFx0Ly8gRW5zdXJlIGEgaG9va3MgZm9yIHRoaXMgcXVldWVcblx0XHRcdFx0alF1ZXJ5Ll9xdWV1ZUhvb2tzKCB0aGlzLCB0eXBlICk7XG5cblx0XHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgJiYgcXVldWVbIDAgXSAhPT0gXCJpbnByb2dyZXNzXCIgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHR9LFxuXHRkZXF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0fSApO1xuXHR9LFxuXHRjbGVhclF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSB8fCBcImZ4XCIsIFtdICk7XG5cdH0sXG5cblx0Ly8gR2V0IGEgcHJvbWlzZSByZXNvbHZlZCB3aGVuIHF1ZXVlcyBvZiBhIGNlcnRhaW4gdHlwZVxuXHQvLyBhcmUgZW1wdGllZCAoZnggaXMgdGhlIHR5cGUgYnkgZGVmYXVsdClcblx0cHJvbWlzZTogZnVuY3Rpb24oIHR5cGUsIG9iaiApIHtcblx0XHR2YXIgdG1wLFxuXHRcdFx0Y291bnQgPSAxLFxuXHRcdFx0ZGVmZXIgPSBqUXVlcnkuRGVmZXJyZWQoKSxcblx0XHRcdGVsZW1lbnRzID0gdGhpcyxcblx0XHRcdGkgPSB0aGlzLmxlbmd0aCxcblx0XHRcdHJlc29sdmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhKCAtLWNvdW50ICkgKSB7XG5cdFx0XHRcdFx0ZGVmZXIucmVzb2x2ZVdpdGgoIGVsZW1lbnRzLCBbIGVsZW1lbnRzIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRvYmogPSB0eXBlO1xuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHR0bXAgPSBkYXRhUHJpdi5nZXQoIGVsZW1lbnRzWyBpIF0sIHR5cGUgKyBcInF1ZXVlSG9va3NcIiApO1xuXHRcdFx0aWYgKCB0bXAgJiYgdG1wLmVtcHR5ICkge1xuXHRcdFx0XHRjb3VudCsrO1xuXHRcdFx0XHR0bXAuZW1wdHkuYWRkKCByZXNvbHZlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJlc29sdmUoKTtcblx0XHRyZXR1cm4gZGVmZXIucHJvbWlzZSggb2JqICk7XG5cdH1cbn0gKTtcbnZhciBwbnVtID0gKCAvWystXT8oPzpcXGQqXFwufClcXGQrKD86W2VFXVsrLV0/XFxkK3wpLyApLnNvdXJjZTtcblxudmFyIHJjc3NOdW0gPSBuZXcgUmVnRXhwKCBcIl4oPzooWystXSk9fCkoXCIgKyBwbnVtICsgXCIpKFthLXolXSopJFwiLCBcImlcIiApO1xuXG5cbnZhciBjc3NFeHBhbmQgPSBbIFwiVG9wXCIsIFwiUmlnaHRcIiwgXCJCb3R0b21cIiwgXCJMZWZ0XCIgXTtcblxudmFyIGRvY3VtZW50RWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuXG5cblx0dmFyIGlzQXR0YWNoZWQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybi
1BqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApO1xuXHRcdH0sXG5cdFx0Y29tcG9zZWQgPSB7IGNvbXBvc2VkOiB0cnVlIH07XG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExKywgRWRnZSAxMiAtIDE4KywgaU9TIDEwLjAgLSAxMC4yIG9ubHlcblx0Ly8gQ2hlY2sgYXR0YWNobWVudCBhY3Jvc3Mgc2hhZG93IERPTSBib3VuZGFyaWVzIHdoZW4gcG9zc2libGUgKGdoLTM1MDQpXG5cdC8vIFN1cHBvcnQ6IGlPUyAxMC4wLTEwLjIgb25seVxuXHQvLyBFYXJseSBpT1MgMTAgdmVyc2lvbnMgc3VwcG9ydCBgYXR0YWNoU2hhZG93YCBidXQgbm90IGBnZXRSb290Tm9kZWAsXG5cdC8vIGxlYWRpbmcgdG8gZXJyb3JzLiBXZSBuZWVkIHRvIGNoZWNrIGZvciBgZ2V0Um9vdE5vZGVgLlxuXHRpZiAoIGRvY3VtZW50RWxlbWVudC5nZXRSb290Tm9kZSApIHtcblx0XHRpc0F0dGFjaGVkID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKSB8fFxuXHRcdFx0XHRlbGVtLmdldFJvb3ROb2RlKCBjb21wb3NlZCApID09PSBlbGVtLm93bmVyRG9jdW1lbnQ7XG5cdFx0fTtcblx0fVxudmFyIGlzSGlkZGVuV2l0aGluVHJlZSA9IGZ1bmN0aW9uKCBlbGVtLCBlbCApIHtcblxuXHRcdC8vIGlzSGlkZGVuV2l0aGluVHJlZSBtaWdodCBiZSBjYWxsZWQgZnJvbSBqUXVlcnkjZmlsdGVyIGZ1bmN0aW9uO1xuXHRcdC8vIGluIHRoYXQgY2FzZSwgZWxlbWVudCB3aWxsIGJlIHNlY29uZCBhcmd1bWVudFxuXHRcdGVsZW0gPSBlbCB8fCBlbGVtO1xuXG5cdFx0Ly8gSW5saW5lIHN0eWxlIHRydW1wcyBhbGxcblx0XHRyZXR1cm4gZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIm5vbmVcIiB8fFxuXHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmXG5cblx0XHRcdC8vIE90aGVyd2lzZSwgY2hlY2sgY29tcHV0ZWQgc3R5bGVcblx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD00MyAtIDQ1XG5cdFx0XHQvLyBEaXNjb25uZWN0ZWQgZWxlbWVudHMgY2FuIGhhdmUgY29tcHV0ZWQgZGlzcGxheTogbm9uZSwgc28gZmlyc3QgY29uZmlybSB0aGF0IGVsZW0gaXNcblx0XHRcdC8vIGluIHRoZSBkb2N1bWVudC5cblx0XHRcdGlzQXR0YWNoZWQoIGVsZW0gKSAmJlxuXG5cdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApID09PSBcIm5vbmVcIjtcblx0fTtcblxuXG5cbmZ1bmN0aW9uIGFkanVzdENTUyggZWxlbSwgcHJvcCwgdmFsdWVQYXJ0cywgdHdlZW4gKSB7XG5cdHZhciBhZGp1c3RlZCwgc2NhbGUsXG5cdFx0bWF4SXRlcmF0aW9ucyA9IDIwLFxuXHRcdGN1cnJlbnRWYWx1ZSA9IHR3ZWVuID9cblx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gdHdlZW4uY3VyKCk7XG5cdFx0XHR9IDpcblx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4galF1ZXJ5LmNzcyggZWxlbSwgcHJvcCwgXCJcIiApO1xuXHRcdFx0fSxcblx0XHRpbml0aWFsID0gY3VycmVudFZhbHVlKCksXG5cdFx0dW5pdCA9IHZhbHVlUGFydHMgJiYgdmFsdWVQYXJ0c1sgMyBdIHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApLFxuXG5cdFx0Ly8gU3RhcnRpbmcgdmFsdWUgY29tcHV0YXRpb24gaXMgcmVxdWlyZWQgZm9yIHBvdGVudGlhbCB1bml0IG1pc21hdGNoZXNcblx0XHRpbml0aWFsSW5Vbml0ID0gZWxlbS5ub2RlVHlwZSAmJlxuXHRcdFx0KCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gfHwgdW5pdCAhPT0gXCJweFwiICYmICtpbml0aWFsICkgJiZcblx0XHRcdHJjc3NOdW0uZXhlYyggalF1ZXJ5LmNzcyggZWxlbSwgcHJvcCApICk7XG5cblx0aWYgKCBpbml0aWFsSW5Vbml0ICYmIGluaXRpYWxJblVuaXRbIDMgXSAhPT0gdW5pdCApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD01NFxuXHRcdC8vIEhhbHZlIHRoZSBpdGVyYXRpb24gdGFyZ2V0IHZhbHVlIHRvIHByZXZlbnQgaW50ZXJmZXJlbmNlIGZyb20gQ1NTIHVwcGVyIGJvdW5kcyAoZ2gtMjE0NClcblx0XHRpbml0aWFsID0gaW5pdGlhbCAvIDI7XG5cblx0XHQvLyBUcnVzdCB1bml0cyByZXBvcnRlZCBieSBqUXVlcnkuY3NzXG5cdFx0dW5pdCA9IHVuaXQgfHwgaW5pdGlhbEluVW5pdFsgMyBdO1xuXG5cdFx0Ly8gSXRlcmF0aXZlbHkgYXBwcm94aW1hdGUgZnJvbSBhIG5vbnplcm8gc3RhcnRpbmcgcG9pbnRcblx0XHRpbml0aWFsSW5Vbml0ID0gK2luaXRpYWwgfHwgMTtcblxuXHRcdHdoaWxlICggbWF4SXRlcmF0aW9ucy0tICkge1xuXG5cdFx0XHQvLyBFdmFsdWF0ZSBhbmQgdXBkYXRlIG91ciBiZXN0IGd1ZXNzIChkb3VibGluZyBndWVzc2VzIHRoYXQgemVybyBvdXQpLlxuXHRcdFx0Ly8gRmluaXNoIGlmIHRoZSBzY2FsZSBlcXVhbHMgb3IgY3Jvc3NlcyAxIChtYWtpbmcgdGhlIG9sZCpuZXcgcHJvZHVjdCBub24tcG9zaXRpdmUpLlxuXHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBpbml0aWFsSW5Vbml0ICsgdW5pdCApO1xuXHRcdFx0aWYgKCAoIDEgLSBzY2FsZSApICogKCAxIC0gKCBzY2FsZSA9IGN1cnJlbnRWYWx1ZSgpIC8gaW5pdGlhbCB8fCAwLjUgKSApIDw9IDAgKSB7XG5cdFx0XHRcdG1heEl0ZXJhdGlvbnMgPSAwO1xuXHRcdFx0fVxuXHRcdFx0aW5pdGlhbEluVW5pdCA9IGluaXRpYWxJblVuaXQgLyBzY2FsZTtcblxuXHRcdH1cblxuXHRcdGluaXRpYWxJblVuaXQgPSBpbml0aWFsSW5Vbml0ICogMjtcblx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AsIGluaXRpYWxJblVuaXQgKyB1bml0ICk7XG5cblx0XHQvLyBNYWtlIHN1cmUgd2UgdXBkYXRlIHRoZSB0d2VlbiBwcm9wZXJ0aWVzIGxhdGVyIG9uXG5cdFx0dmFsdWVQYXJ0cyA9IHZhbHVlUGFydHMgfHwgW107XG5cdH1cblxuXHRpZiAoIHZhbHVlUGFydHMgKSB7XG5cdFx0aW5pdGlhbEluVW5pdCA9ICtpbml0aWFsSW5Vbml0IHx8ICtpbml0aWFsIHx8IDA7XG5cblx0XHQvLyBBcHBseSByZWxhdGl2ZSBvZmZzZXQgKCs9Ly09KSBpZiBzcGVjaWZpZWRcblx0XHRhZGp1c3RlZCA9IHZhbHVlUGFydHNbIDEgXSA/XG5cdFx0XHRpbml0aWFsSW5Vbml0ICsgKCB2YWx1ZVBhcnRzWyAxIF0gKyAxICkgKiB2YWx1ZVBhcnRzWyAyIF0gOlxuXHRcdFx0K3ZhbHVlUGFydHNbIDIgXTtcblx0XHRpZiAoIHR3ZWVuICkge1xuXHRcdFx0dHdlZW4udW5pdCA9IHVuaXQ7XG5cdFx0XHR0d2Vlbi5zdGFydCA9IGluaXRpYWxJblVuaXQ7XG5cdFx0XHR0d2Vlbi5lbmQgPSBhZGp1c3RlZDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGFkanVzdGVkO1xufVxuXG5cbnZhciBkZWZhdWx0RGlzcGxheU1hcCA9IHt9O1xuXG5mdW5jdGlvbiBnZXREZWZhdWx0RGlzcGxheSggZWxlbSApIHtcblx0dmFyIHRlbXAsXG5cdFx0ZG9jID0gZWxlbS5vd25lckRvY3VtZW50LFxuXHRcdG5vZGVOYW1lID0gZWxlbS5ub2RlTmFtZSxcblx0XHRkaXNwbGF5ID0gZGVmYXVsdERpc3BsYXlNYXBbIG5vZGVOYW1lIF07XG5cblx0aWYgKCBkaXNwbGF5ICkge1xuXHRcdHJldHVybi
1BkaXNwbGF5O1xuXHR9XG5cblx0dGVtcCA9IGRvYy5ib2R5LmFwcGVuZENoaWxkKCBkb2MuY3JlYXRlRWxlbWVudCggbm9kZU5hbWUgKSApO1xuXHRkaXNwbGF5ID0galF1ZXJ5LmNzcyggdGVtcCwgXCJkaXNwbGF5XCIgKTtcblxuXHR0ZW1wLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHRlbXAgKTtcblxuXHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdGRpc3BsYXkgPSBcImJsb2NrXCI7XG5cdH1cblx0ZGVmYXVsdERpc3BsYXlNYXBbIG5vZGVOYW1lIF0gPSBkaXNwbGF5O1xuXG5cdHJldHVybiBkaXNwbGF5O1xufVxuXG5mdW5jdGlvbiBzaG93SGlkZSggZWxlbWVudHMsIHNob3cgKSB7XG5cdHZhciBkaXNwbGF5LCBlbGVtLFxuXHRcdHZhbHVlcyA9IFtdLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7XG5cblx0Ly8gRGV0ZXJtaW5lIG5ldyBkaXNwbGF5IHZhbHVlIGZvciBlbGVtZW50cyB0aGF0IG5lZWQgdG8gY2hhbmdlXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXHRcdGlmICggIWVsZW0uc3R5bGUgKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHRkaXNwbGF5ID0gZWxlbS5zdHlsZS5kaXNwbGF5O1xuXHRcdGlmICggc2hvdyApIHtcblxuXHRcdFx0Ly8gU2luY2Ugd2UgZm9yY2UgdmlzaWJpbGl0eSB1cG9uIGNhc2NhZGUtaGlkZGVuIGVsZW1lbnRzLCBhbiBpbW1lZGlhdGUgKGFuZCBzbG93KVxuXHRcdFx0Ly8gY2hlY2sgaXMgcmVxdWlyZWQgaW4gdGhpcyBmaXJzdCBsb29wIHVubGVzcyB3ZSBoYXZlIGEgbm9uZW1wdHkgZGlzcGxheSB2YWx1ZSAoZWl0aGVyXG5cdFx0XHQvLyBpbmxpbmUgb3IgYWJvdXQtdG8tYmUtcmVzdG9yZWQpXG5cdFx0XHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBkYXRhUHJpdi5nZXQoIGVsZW0sIFwiZGlzcGxheVwiICkgfHwgbnVsbDtcblx0XHRcdFx0aWYgKCAhdmFsdWVzWyBpbmRleCBdICkge1xuXHRcdFx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmICggZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmIGlzSGlkZGVuV2l0aGluVHJlZSggZWxlbSApICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBnZXREZWZhdWx0RGlzcGxheSggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIGRpc3BsYXkgIT09IFwibm9uZVwiICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBcIm5vbmVcIjtcblxuXHRcdFx0XHQvLyBSZW1lbWJlciB3aGF0IHdlJ3JlIG92ZXJ3cml0aW5nXG5cdFx0XHRcdGRhdGFQcml2LnNldCggZWxlbSwgXCJkaXNwbGF5XCIsIGRpc3BsYXkgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBTZXQgdGhlIGRpc3BsYXkgb2YgdGhlIGVsZW1lbnRzIGluIGEgc2Vjb25kIGxvb3AgdG8gYXZvaWQgY29uc3RhbnQgcmVmbG93XG5cdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0aWYgKCB2YWx1ZXNbIGluZGV4IF0gIT0gbnVsbCApIHtcblx0XHRcdGVsZW1lbnRzWyBpbmRleCBdLnN0eWxlLmRpc3BsYXkgPSB2YWx1ZXNbIGluZGV4IF07XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnRzO1xufVxuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHNob3c6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcywgdHJ1ZSApO1xuXHR9LFxuXHRoaWRlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2hvd0hpZGUoIHRoaXMgKTtcblx0fSxcblx0dG9nZ2xlOiBmdW5jdGlvbiggc3RhdGUgKSB7XG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGUgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0cmV0dXJuIHN0YXRlID8gdGhpcy5zaG93KCkgOiB0aGlzLmhpZGUoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggaXNIaWRkZW5XaXRoaW5UcmVlKCB0aGlzICkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnNob3coKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmhpZGUoKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH1cbn0gKTtcbnZhciByY2hlY2thYmxlVHlwZSA9ICggL14oPzpjaGVja2JveHxyYWRpbykkL2kgKTtcblxudmFyIHJ0YWdOYW1lID0gKCAvPChbYS16XVteXFwvXFwwPlxceDIwXFx0XFxyXFxuXFxmXSopL2kgKTtcblxudmFyIHJzY3JpcHRUeXBlID0gKCAvXiR8Xm1vZHVsZSR8XFwvKD86amF2YXxlY21hKXNjcmlwdC9pICk7XG5cblxuXG4oIGZ1bmN0aW9uKCkge1xuXHR2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG5cdFx0ZGl2ID0gZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApLFxuXHRcdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAgLSA0LjMgb25seVxuXHQvLyBDaGVjayBzdGF0ZSBsb3N0IGlmIHRoZSBuYW1lIGlzIHNldCAodHJhYy0xMTIxNylcblx0Ly8gU3VwcG9ydDogV2luZG93cyBXZWIgQXBwcyAoV1dBKVxuXHQvLyBgbmFtZWAgYW5kIGB0eXBlYCBtdXN0IHVzZSAuc2V0QXR0cmlidXRlIGZvciBXV0EgKHRyYWMtMTQ
15MDEpXG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwicmFkaW9cIiApO1xuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwiY2hlY2tlZFwiLCBcImNoZWNrZWRcIiApO1xuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwibmFtZVwiLCBcInRcIiApO1xuXG5cdGRpdi5hcHBlbmRDaGlsZCggaW5wdXQgKTtcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4xIG9ubHlcblx0Ly8gT2xkZXIgV2ViS2l0IGRvZXNuJ3QgY2xvbmUgY2hlY2tlZCBzdGF0ZSBjb3JyZWN0bHkgaW4gZnJhZ21lbnRzXG5cdHN1cHBvcnQuY2hlY2tDbG9uZSA9IGRpdi5jbG9uZU5vZGUoIHRydWUgKS5jbG9uZU5vZGUoIHRydWUgKS5sYXN0Q2hpbGQuY2hlY2tlZDtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHlcblx0Ly8gTWFrZSBzdXJlIHRleHRhcmVhIChhbmQgY2hlY2tib3gpIGRlZmF1bHRWYWx1ZSBpcyBwcm9wZXJseSBjbG9uZWRcblx0ZGl2LmlubmVySFRNTCA9IFwiPHRleHRhcmVhPng8L3RleHRhcmVhPlwiO1xuXHRzdXBwb3J0Lm5vQ2xvbmVDaGVja2VkID0gISFkaXYuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmRlZmF1bHRWYWx1ZTtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHQvLyBJRSA8PTkgcmVwbGFjZXMgPG9wdGlvbj4gdGFncyB3aXRoIHRoZWlyIGNvbnRlbnRzIHdoZW4gaW5zZXJ0ZWQgb3V0c2lkZSBvZlxuXHQvLyB0aGUgc2VsZWN0IGVsZW1lbnQuXG5cdGRpdi5pbm5lckhUTUwgPSBcIjxvcHRpb24+PC9vcHRpb24+XCI7XG5cdHN1cHBvcnQub3B0aW9uID0gISFkaXYubGFzdENoaWxkO1xufSApKCk7XG5cblxuLy8gV2UgaGF2ZSB0byBjbG9zZSB0aGVzZSB0YWdzIHRvIHN1cHBvcnQgWEhUTUwgKHRyYWMtMTMyMDApXG52YXIgd3JhcE1hcCA9IHtcblxuXHQvLyBYSFRNTCBwYXJzZXJzIGRvIG5vdCBtYWdpY2FsbHkgaW5zZXJ0IGVsZW1lbnRzIGluIHRoZVxuXHQvLyBzYW1lIHdheSB0aGF0IHRhZyBzb3VwIHBhcnNlcnMgZG8uIFNvIHdlIGNhbm5vdCBzaG9ydGVuXG5cdC8vIHRoaXMgYnkgb21pdHRpbmcgPHRib2R5PiBvciBvdGhlciByZXF1aXJlZCBlbGVtZW50cy5cblx0dGhlYWQ6IFsgMSwgXCI8dGFibGU+XCIsIFwiPC90YWJsZT5cIiBdLFxuXHRjb2w6IFsgMiwgXCI8dGFibGU+PGNvbGdyb3VwPlwiLCBcIjwvY29sZ3JvdXA+PC90YWJsZT5cIiBdLFxuXHR0cjogWyAyLCBcIjx0YWJsZT48dGJvZHk+XCIsIFwiPC90Ym9keT48L3RhYmxlPlwiIF0sXG5cdHRkOiBbIDMsIFwiPHRhYmxlPjx0Ym9keT48dHI+XCIsIFwiPC90cj48L3Rib2R5PjwvdGFibGU+XCIgXSxcblxuXHRfZGVmYXVsdDogWyAwLCBcIlwiLCBcIlwiIF1cbn07XG5cbndyYXBNYXAudGJvZHkgPSB3cmFwTWFwLnRmb290ID0gd3JhcE1hcC5jb2xncm91cCA9IHdyYXBNYXAuY2FwdGlvbiA9IHdyYXBNYXAudGhlYWQ7XG53cmFwTWFwLnRoID0gd3JhcE1hcC50ZDtcblxuLy8gU3VwcG9ydDogSUUgPD05IG9ubHlcbmlmICggIXN1cHBvcnQub3B0aW9uICkge1xuXHR3cmFwTWFwLm9wdGdyb3VwID0gd3JhcE1hcC5vcHRpb24gPSBbIDEsIFwiPHNlbGVjdCBtdWx0aXBsZT0nbXVsdGlwbGUnPlwiLCBcIjwvc2VsZWN0PlwiIF07XG59XG5cblxuZnVuY3Rpb24gZ2V0QWxsKCBjb250ZXh0LCB0YWcgKSB7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHQvLyBVc2UgdHlwZW9mIHRvIGF2b2lkIHplcm8tYXJndW1lbnQgbWV0aG9kIGludm9jYXRpb24gb24gaG9zdCBvYmplY3RzICh0cmFjLTE1MTUxKVxuXHR2YXIgcmV0O1xuXG5cdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgKSB7XG5cdFx0cmV0ID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnIHx8IFwiKlwiICk7XG5cblx0fSBlbHNlIGlmICggdHlwZW9mIGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCAhPT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRyZXQgPSBjb250ZXh0LnF1
1ZXJ5U2VsZWN0b3JBbGwoIHRhZyB8fCBcIipcIiApO1xuXG5cdH0gZWxzZSB7XG5cdFx0cmV0ID0gW107XG5cdH1cblxuXHRpZiAoIHRhZyA9PT0gdW5kZWZpbmVkIHx8IHRhZyAmJiBub2RlTmFtZSggY29udGV4dCwgdGFnICkgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5tZXJnZSggWyBjb250ZXh0IF0sIHJldCApO1xuXHR9XG5cblx0cmV0dXJuIHJldDtcbn1cblxuXG4vLyBNYXJrIHNjcmlwdHMgYXMgaGF2aW5nIGFscmVhZHkgYmVlbiBldmFsdWF0ZWRcbmZ1bmN0aW9uIHNldEdsb2JhbEV2YWwoIGVsZW1zLCByZWZFbGVtZW50cyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGwgPSBlbGVtcy5sZW5ndGg7XG5cblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdGRhdGFQcml2LnNldChcblx0XHRcdGVsZW1zWyBpIF0sXG5cdFx0XHRcImdsb2JhbEV2YWxcIixcblx0XHRcdCFyZWZFbGVtZW50cyB8fCBkYXRhUHJpdi5nZXQoIHJlZkVsZW1lbnRzWyBpIF0sIFwiZ2xvYmFsRXZhbFwiIClcblx0XHQpO1xuXHR9XG59XG5cblxudmFyIHJodG1sID0gLzx8JiM/XFx3KzsvO1xuXG5mdW5jdGlvbiBidWlsZEZyYWdtZW50KCBlbGVtcywgY29udGV4dCwgc2NyaXB0cywgc2VsZWN0aW9uLCBpZ25vcmVkICkge1xuXHR2YXIgZWxlbSwgdG1wLCB0YWcsIHdyYXAsIGF0dGFjaGVkLCBqLFxuXHRcdGZyYWdtZW50ID0gY29udGV4dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG5cdFx0bm9kZXMgPSBbXSxcblx0XHRpID0gMCxcblx0XHRsID0gZWxlbXMubGVuZ3RoO1xuXG5cdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRlbGVtID0gZWxlbXNbIGkgXTtcblxuXHRcdGlmICggZWxlbSB8fCBlbGVtID09PSAwICkge1xuXG5cdFx0XHQvLyBBZGQgbm9kZXMgZGlyZWN0bHlcblx0XHRcdGlmICggdG9UeXBlKCBlbGVtICkgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdFx0XHRcdC8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgZWxlbS5ub2RlVHlwZSA/IFsgZWxlbSBdIDogZWxlbSApO1xuXG5cdFx0XHQvLyBDb252ZXJ0IG5vbi1odG1sIGludG8gYSB0ZXh0IG5vZGVcblx0XHRcdH0gZWxzZSBpZiAoICFyaHRtbC50ZXN0KCBlbGVtICkgKSB7XG5cdFx0XHRcdG5vZGVzLnB1c2goIGNvbnRleHQuY3JlYXRlVGV4dE5vZGUoIGVsZW0gKSApO1xuXG5cdFx0XHQvLyBDb252ZXJ0IGh0bWwgaW50byBET00gbm9kZXNcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRtcCA9IHRtcCB8fCBmcmFnbWVudC5hcHBlbmRDaGlsZCggY29udGV4dC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKTtcblxuXHRcdFx0XHQvLyBEZXNlcmlhbGl6ZSBhIHN0YW5kYXJkIHJlcHJlc2VudGF0aW9uXG5cdFx0XHRcdHRhZyA9ICggcnRhZ05hbWUuZXhlYyggZWxlbSApIHx8IFsgXCJcIiwgXCJcIiBdIClbIDEgXS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHR3cmFwID0gd3JhcE1hcFsgdGFnIF0gfHwgd3JhcE1hcC5fZGVmYXVsdDtcblx0XHRcdFx0dG1wLmlubmVySFRNTCA9IHdyYXBbIDEgXSArIGpRdWVyeS5odG1sUHJlZmlsdGVyKCBlbGVtICkgKyB3cmFwWyAyIF07XG5cblx0XHRcdFx0Ly8gRGVzY2VuZCB0aHJvdWdoIHdyYXBwZXJzIHRvIH
1RoZSByaWdodCBjb250ZW50XG5cdFx0XHRcdGogPSB3cmFwWyAwIF07XG5cdFx0XHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0XHRcdHRtcCA9IHRtcC5sYXN0Q2hpbGQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIG5vZGVzLCB0bXAuY2hpbGROb2RlcyApO1xuXG5cdFx0XHRcdC8vIFJlbWVtYmVyIHRoZSB0b3AtbGV2ZWwgY29udGFpbmVyXG5cdFx0XHRcdHRtcCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG5cblx0XHRcdFx0Ly8gRW5zdXJlIHRoZSBjcmVhdGVkIG5vZGVzIGFyZSBvcnBoYW5lZCAodHJhYy0xMjM5Milcblx0XHRcdFx0dG1wLnRleHRDb250ZW50ID0gXCJcIjtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBSZW1vdmUgd3JhcHBlciBmcm9tIGZyYWdtZW50XG5cdGZyYWdtZW50LnRleHRDb250ZW50ID0gXCJcIjtcblxuXHRpID0gMDtcblx0d2hpbGUgKCAoIGVsZW0gPSBub2Rlc1sgaSsrIF0gKSApIHtcblxuXHRcdC8vIFNraXAgZWxlbWVudHMgYWxyZWFkeSBpbiB0aGUgY29udGV4dCBjb2xsZWN0aW9uICh0cmFjLTQwODcpXG5cdFx0aWYgKCBzZWxlY3Rpb24gJiYgalF1ZXJ5LmluQXJyYXkoIGVsZW0sIHNlbGVjdGlvbiApID4gLTEgKSB7XG5cdFx0XHRpZiAoIGlnbm9yZWQgKSB7XG5cdFx0XHRcdGlnbm9yZWQucHVzaCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdFx0Y29udGludWU7XG5cdFx0fVxuXG5cdFx0YXR0YWNoZWQgPSBpc0F0dGFjaGVkKCBlbGVtICk7XG5cblx0XHQvLyBBcHBlbmQgdG8gZnJhZ21lbnRcblx0XHR0bXAgPSBnZXRBbGwoIGZyYWdtZW50LmFwcGVuZENoaWxkKCBlbGVtICksIFwic2NyaXB0XCIgKTtcblxuXHRcdC8vIFByZXNlcnZlIHNjcmlwdCBldmFsdWF0aW9uIGhpc3Rvcnlcblx0XHRpZiAoIGF0dGFjaGVkICkge1xuXHRcdFx0c2V0R2xvYmFsRXZhbCggdG1wICk7XG5cdFx0fVxuXG5cdFx0Ly8gQ2FwdHVyZSBleGVjdXRhYmxlc1xuXHRcdGlmICggc2NyaXB0cyApIHtcblx0XHRcdGogPSAwO1xuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0bXBbIGorKyBdICkgKSB7XG5cdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggZWxlbS50eXBlIHx8IFwiXCIgKSApIHtcblx0XHRcdFx0XHRzY3JpcHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBmcmFnbWVudDtcbn1cblxuXG52YXIgcnR5cGVuYW1lc3BhY2UgPSAvXihbXi5dKikoPzpcXC4oLispfCkvO1xuXG5mdW5jdGlvbiByZXR1cm5UcnVlKCkge1xuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmV0dXJuRmFsc2UoKSB7XG5cdHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gb24oIGVsZW0sIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIG9uZSApIHtcblx0dmFyIG9yaWdGbiwgdHlwZTtcblxuXHQvLyBUeXBlcyBjYW4gYmUgYSBtYXAgb2YgdHlwZXMvaGFuZGxlcnNcblx0aWYgKCB0eXBlb2YgdHlwZXMgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHQvLyAoIHR5cGVzLU9iamVjdCwgc2VsZWN0b3IsIGRhdGEgKVxuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzLU9iamVjdCwgZGF0YSApXG5cdFx0XHRkYXRhID0gZGF0YSB8fCBzZWxlY3Rvcjtcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0b24oIGVsZW0sIHR5cGUsIHNlbGVjdG9yLCBkYXRhLCB0eXBlc1sgdHlwZSBdLCBvbmUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIGVsZW07XG5cdH1cblxuXHRpZiAoIGRhdGEgPT0gbnVsbCAmJiBmbiA9PSBudWxsICkge1xuXG5cdFx0Ly8gKCB0eXBlcywgZm4gKVxuXHRcdGZuID0gc2VsZWN0b3I7XG5cdFx0ZGF0YSA9IHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHR9IGVsc2UgaWYgKCBmbiA9PSBudWxsICkge1xuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzLCBzZWxlY3RvciwgZm4gKVxuXHRcdFx0Zm4gPSBkYXRhO1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyAoIHR5cGVzLCBkYXRhLCBmbiApXG5cdFx0XHRmbiA9IGRhdGE7XG5cdFx0XHRkYXRhID0gc2VsZWN0b3I7XG5cdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblx0aWYgKCBmbiA9PT0gZmFsc2UgKSB7XG5cdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0fSBlbHNlIGlmICggIWZuICkge1xuXHRcdHJldHVybiBlbGVtO1xuXHR9XG5cblx0aWYgKCBvbmUgPT09IDEgKSB7XG5cdFx0b3JpZ0ZuID0gZm47XG5cdFx0Zm4gPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cblx0XHRcdC8vIENhbiB1c2UgYW4gZW1wdHkgc2V0LCBzaW5jZSBldmVudCBjb250YWlucyB0aGUgaW5mb1xuXHRcdFx0alF1ZXJ5KCkub2ZmKCBldmVudCApO1xuXHRcdFx0cmV0dXJuIG9yaWdGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fTtcblxuXHRcdC8vIFVzZSBzYW1lIGd1aWQgc28gY2FsbGVyIGNhbiByZW1vdmUgdXNpbmcgb3JpZ0ZuXG5cdFx0Zm4uZ3VpZCA9IG9yaWdGbi5ndWlkIHx8ICggb3JpZ0ZuLmd1aWQgPSBqUXVlcnkuZ3VpZCsrICk7XG5cdH1cblx0cmV0dXJuIGVsZW0uZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0alF1ZXJ5LmV2ZW50LmFkZCggdGhpcywgdHlwZXMsIGZuLCBkYXRhLCBzZWxlY3RvciApO1xuXHR9ICk7XG59XG5cbi8qXG4gKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBtYW5hZ2luZyBldmVudHMgLS0gbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuXG4gKiBQcm9wcyB0byBEZWFuIEVkd2FyZHMnIGFkZEV2ZW50IGxpYnJhcnkgZm9yIG1hbnkgb2YgdGhlIGlkZWFzLlxuICovXG5qUXVlcnkuZXZlbnQgPSB7XG5cblx0Z2xvYmFsOiB7fSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlcywgaGFuZGxlciwgZGF0YSwgc2VsZWN0b3IgKSB7XG5cblx0XHR2YXIgaGFuZGxlT2JqSW4sIGV2ZW50SGFuZGxlLCB0bXAsXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcblx0XHRcdHNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSxcblx0XHRcdGVsZW1EYXRhID0gZGF0YVByaXYuZ2V0KCBlbGVtICk7XG5cblx0XHQvLyBPbmx5IGF0dGFjaCBldmVudHMgdG8gb2JqZWN0cyB0aGF0IGFjY2VwdCBkYXRhXG5cdFx0aWYgKCAhYWNjZXB0RGF0YSggZWxlbSApICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhbiBvYmplY3Qgb2YgY3VzdG9tIGRhdGEgaW4gbGlldSBvZiB0aGUgaGFuZGxlclxuXHRcdGlmICggaGFuZGxlci5oYW5kbGVyICkge1xuXHRcdFx0aGFuZGxlT2JqSW4gPSBoYW5kbGVyO1xuXHRcdFx0aGFuZGxlciA9IGhhbmRsZU9iakluLmhhbmRsZXI7XG5cdFx0XHRzZWxlY3RvciA9IGhhbmRsZU9iakluLnNlbGVjdG9yO1xuXHRcdH1cblxuXHRcdC8vIEVuc3VyZSB0aGF0IGludmFsaWQgc2VsZWN0b3JzIHRocm93IGV4Y2VwdGlvbnMgYXQgYXR0YWNoIHRpbWVcblx0XHQvLyBFdmFsdWF0ZSBhZ2FpbnN0IGRvY3VtZW50RWxlbWVudCBpbiBjYXNlIGVsZW0gaXMgYSBub24tZWxlbWVudCBub2RlIChlLmcuLCBkb2N1bWVudClcblx0XHRpZiAoIHNlbGVjdG9yICkge1xuXHRcdFx0alF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKCBkb2N1bWVudEVsZW1lbnQsIHNlbGVjdG9yICk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgdGhlIGhhbmRsZXIgaGFzIGEgdW5pcXVlIElELCB1c2VkIHRvIGZpbmQvcmVtb3ZlIGl0IGxhdGVyXG5cdFx0aWYgKCAhaGFuZGxlci5ndWlkICkge1xuXHRcdFx0aGFuZGxlci5ndWlkID0galF1ZXJ5Lmd1aWQrKztcblx0XHR9XG5cblx0XHQvLyBJbml0IHRoZSBlbGVtZW50J3MgZXZlbnQgc3RydWN0dXJlIGFuZCBtYWluIGh
1hbmRsZXIsIGlmIHRoaXMgaXMgdGhlIGZpcnN0XG5cdFx0aWYgKCAhKCBldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgKSApIHtcblx0XHRcdGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyA9IE9iamVjdC5jcmVhdGUoIG51bGwgKTtcblx0XHR9XG5cdFx0aWYgKCAhKCBldmVudEhhbmRsZSA9IGVsZW1EYXRhLmhhbmRsZSApICkge1xuXHRcdFx0ZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgPSBmdW5jdGlvbiggZSApIHtcblxuXHRcdFx0XHQvLyBEaXNjYXJkIHRoZSBzZWNvbmQgZXZlbnQgb2YgYSBqUXVlcnkuZXZlbnQudHJpZ2dlcigpIGFuZFxuXHRcdFx0XHQvLyB3aGVuIGFuIGV2ZW50IGlzIGNhbGxlZCBhZnRlciBhIHBhZ2UgaGFzIHVubG9hZGVkXG5cdFx0XHRcdHJldHVybiB0eXBlb2YgalF1ZXJ5ICE9PSBcInVuZGVmaW5lZFwiICYmIGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgIT09IGUudHlwZSA/XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmRpc3BhdGNoLmFwcGx5KCBlbGVtLCBhcmd1bWVudHMgKSA6IHVuZGVmaW5lZDtcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gSGFuZGxlIG11bHRpcGxlIGV2ZW50cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZVxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbIHQgXSApIHx8IFtdO1xuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWyAxIF07XG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbID
1IgXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBUaGVyZSAqbXVzdCogYmUgYSB0eXBlLCBubyBhdHRhY2hpbmcgbmFtZXNwYWNlLW9ubHkgaGFuZGxlcnNcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiBldmVudCBjaGFuZ2VzIGl0cyB0eXBlLCB1c2UgdGhlIHNwZWNpYWwgZXZlbnQgaGFuZGxlcnMgZm9yIHRoZSBjaGFuZ2VkIHR5cGVcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXG5cdFx0XHQvLyBJZiBzZWxlY3RvciBkZWZpbmVkLCBkZXRlcm1pbmUgc3BlY2lhbCBldmVudCBhcGkgdHlwZSwgb3RoZXJ3aXNlIGdpdmVuIHR5cGVcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblxuXHRcdFx0Ly8gVXBkYXRlIHNwZWNpYWwgYmFzZWQgb24gbmV3bHkgcmVzZXQgdHlwZVxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cblx0XHRcdC8vIGhhbmRsZU9iaiBpcyBwYXNzZWQgdG8gYWxsIGV2ZW50IGhhbmRsZXJzXG5cdFx0XHRoYW5kbGVPYmogPSBqUXVlcnkuZXh0ZW5kKCB7XG5cdFx0XHRcdHR5cGU6IHR5cGUsXG5cdFx0XHRcdG9yaWdUeXBlOiBvcmlnVHlwZSxcblx0XHRcdFx0ZGF0YTogZGF0YSxcblx0XHRcdFx0aGFuZGxlcjogaGFuZGxlcixcblx0XHRcdFx0Z3VpZDogaGFuZGxlci5ndWlkLFxuXHRcdFx0XHRzZWxlY3Rvcjogc2VsZWN0b3IsXG5cdFx0XHRcdG5lZWRzQ29udGV4dDogc2VsZWN0b3IgJiYgalF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9yICksXG5cdFx0XHRcdG5hbWVzcGFjZTogbmFtZXNwYWNlcy5qb2luKCBcIi5cIiApXG5cdFx0XHR9LCBoYW5kbGVPYmpJbiApO1xuXG5cdFx0XHQvLyBJbml0IHRoZSBldmVudCBoYW5kbGVyIHF1ZXVlIGlmIHdlJ3JlIHRoZSBmaXJzdFxuXHRcdFx0aWYgKCAhKCBoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdICkgKSB7XG5cdFx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gPSBbXTtcblx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudCA9IDA7XG5cblx0XHRcdFx0Ly8gT25seSB1c2UgYWRkRXZlbnRMaXN0ZW5lciBpZiB0aGUgc3BlY2lhbCBldmVudHMgaGFuZGxlciByZXR1cm5zIGZhbHNlXG5cdFx0XHRcdGlmICggIXNwZWNpYWwuc2V0dXAgfHxcblx0XHRcdFx0XHRzcGVjaWFsLnNldHVwLmNhbGwoIGVsZW0sIGRhdGEsIG5hbWVzcGFjZXMsIGV2ZW50SGFuZGxlICkgPT09IGZhbHNlICkge1xuXG5cdFx0XHRcdFx0aWYgKCBlbGVtLmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGV2ZW50SGFuZGxlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggc3BlY2lhbC5hZGQgKSB7XG5cdFx0XHRcdHNwZWNpYWwuYWRkLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xuXG5cdFx0XHRcdGlmICggIWhhbmRsZU9iai5oYW5kbGVyLmd1aWQgKSB7XG5cdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCA9IGhhbmRsZXIuZ3VpZDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgdG8gdGhlIGVsZW1lbnQncyBoYW5kbGVyIGxpc3QsIGRlbGVnYXRlcyBpbiBmcm9udFxuXHRcdFx0aWYgKCBzZWxlY3RvciApIHtcblx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50KyssIDAsIGhhbmRsZU9iaiApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aGFuZGxlcnMucHVzaCggaGFuZGxlT2JqICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEtlZXAgdHJhY2sgb2Ygd2hpY2ggZXZlbnRzIGhhdmUgZXZlciBiZWVuIHVzZWQsIGZvciBldmVudCBvcHRpbWl6YXRpb25cblx0XHRcdGpRdWVyeS5ldmVudC5nbG9iYWxbIHR5cGUgXSA9IHRydWU7XG5cdFx0fVxuXG5cdH0sXG5cblx0Ly8gRGV0YWNoIGFuIGV2ZW50IG9yIHNldCBvZiBldmVudHMgZnJvbSBhbiBlbGVtZW50XG5cdHJlbW92ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBzZWxlY3RvciwgbWFwcGVkVHlwZXMgKSB7XG5cblx0XHR2YXIgaiwgb3JpZ0NvdW50LCB0bXAsXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcblx0XHRcdHNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSxcblx0XHRcdGVsZW1EYXRhID0gZGF0YVByaXYuaGFzRGF0YSggZWxlbSApICYmIGRhdGFQcml2LmdldCggZWxlbSApO1xuXG5cdFx0aWYgKCAhZWxlbURhdGEgfHwgISggZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gT25jZSBmb3IgZWFjaCB0eXBlLm5hbWVzcGFjZSBpbiB0eXBlczsgdHlwZSBtYXkgYmUgb21pdHRlZFxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbIHQgXSApIHx8IFtdO1xuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWyAxIF07XG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbID
1IgXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBVbmJpbmQgYWxsIGV2ZW50cyAob24gdGhpcyBuYW1lc3BhY2UsIGlmIHByb3ZpZGVkKSBmb3IgdGhlIGVsZW1lbnRcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGZvciAoIHR5cGUgaW4gZXZlbnRzICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIGVsZW0sIHR5cGUgKyB0eXBlc1sgdCBdLCBoYW5kbGVyLCBzZWxlY3RvciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gfHwgW107XG5cdFx0XHR0bXAgPSB0bXBbIDIgXSAmJlxuXHRcdFx0XHRuZXcgUmVnRXhwKCBcIihefFxcXFwuKVwiICsgbmFtZXNwYWNlcy5qb2luKCBcIlxcXFwuKD86LipcXFxcLnwpXCIgKSArIFwiKFxcXFwufCQpXCIgKTtcblxuXHRcdFx0Ly8gUmVtb3ZlIG1hdGNoaW5nIGV2ZW50c1xuXHRcdFx0b3JpZ0NvdW50ID0gaiA9IGhhbmRsZXJzLmxlbmd0aDtcblx0XHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0XHRoYW5kbGVPYmogPSBoYW5kbGVyc1sgaiBdO1xuXG5cdFx0XHRcdGlmICggKCBtYXBwZWRUeXBlcyB8fCBvcmlnVHlwZSA9PT0gaGFuZGxlT2JqLm9yaWdUeXBlICkgJiZcblx0XHRcdFx0XHQoICFoYW5kbGVyIHx8IGhhbmRsZXIuZ3VpZCA9PT0gaGFuZGxlT2JqLmd1aWQgKSAmJlxuXHRcdFx0XHRcdCggIXRtcCB8fCB0bXAudGVzdCggaGFuZGxlT2JqLm5hbWVzcGFjZSApICkgJiZcblx0XHRcdFx0XHQoICFzZWxlY3RvciB8fCBzZWxlY3RvciA9PT0gaGFuZGxlT2JqLnNlbGVjdG9yIHx8XG5cdFx0XHRcdFx0XHRzZWxlY3RvciA9PT0gXCIqKlwiICYmIGhhbmRsZU9iai5zZWxlY3RvciApICkge1xuXHRcdFx0XHRcdGhhbmRsZXJzLnNwbGljZSggaiwgMSApO1xuXG5cdFx0XHRcdFx0aWYgKCBoYW5kbGVPYmouc2VsZWN0b3IgKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVycy5kZWxlZ2F0ZUNvdW50LS07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggc3BlY2lhbC5yZW1vdmUgKSB7XG5cdFx0XHRcdFx0XHRzcGVjaWFsLnJlbW92ZS5jYWxsKCBlbGVtLCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gUmVtb3ZlIGdlbmVyaWMgZXZlbnQgaGFuZGxlciBpZiB3ZSByZW1vdmVkIHNvbWV0aGluZyBhbmQgbm8gbW9yZSBoYW5kbGVycyBleGlzdFxuXHRcdFx0Ly8gKGF2b2lkcyBwb3RlbnRpYWwgZm9yIGVuZGxlc3MgcmVjdXJzaW9uIGR1cmluZyByZW1vdmFsIG9mIHNwZWNpYWwgZXZlbnQgaGFuZGxlcnMpXG5cdFx0XHRpZiAoIG9yaWdDb3VudCAmJiAhaGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0XHRpZiAoICFzcGVjaWFsLnRlYXJkb3duIHx8XG5cdFx0XHRcdFx0c3BlY2lhbC50ZWFyZG93bi5jYWxsKCBlbGVtLCBuYW1lc3BhY2VzLCBlbGVtRGF0YS5oYW5kbGUgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGVsZW1EYXRhLmhhbmRsZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGVsZXRlIGV2ZW50c1sgdHlwZSBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSBkYXRhIGFuZCB0aGUgZXhwYW5kbyBpZiBpdCdzIG5vIGxvbmdlciB1c2VkXG5cdFx0aWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggZXZlbnRzICkgKSB7XG5cdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFwiaGFuZGxlIGV2ZW50c1wiICk7XG5cdFx0fVxuXHR9LFxuXG5cdGRpc3BhdGNoOiBmdW5jdGlvbiggbmF0aXZlRXZlbnQgKSB7XG5cblx0XHR2YXIgaSwgaiwgcmV0LCBtYXRjaGVkLCBoYW5kbGVPYmosIGhhbmRsZXJRdWV1ZSxcblx0XHRcdGFyZ3MgPSBuZXcgQXJyYXkoIGFyZ3VtZW50cy5sZW5ndGggKSxcblxuXHRcdFx0Ly8gTWFrZSBhIHdyaXRhYmxlIGpRdWVyeS5FdmVudCBmcm9tIHRoZSBuYXRpdmUgZXZlbnQgb2JqZWN0XG5cdFx0XHRldmVudCA9IGpRdWVyeS5ldmVudC5maXgoIG5hdGl2ZUV2ZW50ICksXG5cblx0XHRcdGhhbmRsZXJzID0gKFxuXHRcdFx0XHRkYXRhUHJpdi5nZXQoIHRoaXMsIFwiZXZlbnRzXCIgKSB8fCBPYmplY3QuY3JlYXRlKCBudWxsIClcblx0XHRcdClbIGV2ZW50LnR5cGUgXSB8fCBbXSxcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgZXZlbnQudHlwZSBdIHx8IHt9O1xuXG5cdFx0Ly8gVXNlIHRoZSBmaXgtZWQgalF1ZXJ5LkV2ZW50IHJhdGhlciB0aGFuIHRoZSAocmVhZC1vbmx5KSBuYXRpdmUgZXZlbnRcblx0XHRhcmdzWyAwIF0gPSBldmVudDtcblxuXHRcdGZvciAoIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrICkge1xuXHRcdFx0YXJnc1sgaSBdID0gYXJndW1lbnRzWyBpIF07XG5cdFx0fVxuXG5cdFx0ZXZlbnQuZGVsZWdhdGVUYXJnZXQgPSB0aGlzO1xuXG5cdFx0Ly8gQ2FsbCB0aGUgcHJlRGlzcGF0Y2ggaG9vayBmb3IgdGhlIG1hcHBlZCB0eXBlLCBhbmQgbGV0IGl0IGJhaWwgaWYgZGVzaXJlZFxuXHRcdGlmICggc3BlY2lhbC5wcmVEaXNwYXRjaCAmJiBzcGVjaWFsLnByZURpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICkgPT09IGZhbHNlICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIERldGVybWluZSBoYW5kbGVyc1xuXHRcdGhhbmRsZXJRdWV1ZSA9IGpRdWVyeS5ldmVudC5oYW5kbGVycy5jYWxsKCB0aGlzLCBldmVudCwgaGFuZGxlcnMgKTtcblxuXHRcdC8vIFJ1biBkZWxlZ2F0ZXMgZmlyc3Q7IHRoZXkgbWF5IHdhbnQgdG8gc3RvcCBwcm9wYWdhdGlvbiBiZW5lYXRoIHVzXG5cdFx0aSA9IDA7XG5cdFx0d2hpbGUgKCAoIG1hdGNoZWQgPSBoYW5kbGVyUXVldWVbIGkrKyBdICkgJiYgIWV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cdFx0XHRldmVudC5jdXJyZW50VGFyZ2V0ID0gbWF0Y2hlZC5lbGVtO1xuXG5cdFx0XHRqID0gMDtcblx0XHRcdHdoaWxlICggKCBoYW5kbGVPYmogPSBtYXRjaGVkLmhhbmRsZXJzWyBqKysgXSApICYmXG5cdFx0XHRcdCFldmVudC5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXG5cdFx0XHRcdC8vIElmIHRoZSBldmVudCBpcyBuYW1lc3BhY2VkLCB0aGVuIGVhY2ggaGFuZGxlciBpcyBvbmx5IGludm9rZWQgaWYgaXQgaXNcblx0XHRcdFx0Ly8gc3BlY2lhbGx5IHVuaXZlcnNhbCBvciBpdHMgbmFtZXNwYWNlcyBhcmUgYSBzdXBlcnNldCBvZiB0aGUgZXZlbnQncy5cblx0XHRcdFx0aWYgKCAhZXZlbnQucm5hbWVzcGFjZSB8fCBoYW5kbGVPYmoubmFtZXNwYWNlID09PSBmYWxzZSB8fFxuXHRcdFx0XHRcdGV2ZW50LnJuYW1lc3BhY2UudGVzdCggaGFuZGxlT2JqLm5hbWVzcGFjZSApICkge1xuXG5cdFx0XHRcdFx0ZXZlbnQuaGFuZGxlT2JqID0gaGFuZGxlT2JqO1xuXHRcdFx0XHRcdGV2ZW50LmRhdGEgPSBoYW5kbGVPYmouZGF0YTtcblxuXHRcdFx0XHRcdHJldCA9ICggKCBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgaGFuZGxlT2JqLm9yaWdUeXBlIF0gfHwge30gKS5oYW5kbGUgfHxcblx0XHRcdFx0XHRcdGhhbmRsZU9iai5oYW5kbGVyICkuYXBwbHkoIG1hdGNoZWQuZWxlbSwgYXJncyApO1xuXG5cdFx0XHRcdFx0aWYgKCByZXQgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdGlmICggKCBldmVudC5yZXN1bHQgPSByZXQgKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRcdGV2ZW50LnByZXZlbn
1REZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENhbGwgdGhlIHBvc3REaXNwYXRjaCBob29rIGZvciB0aGUgbWFwcGVkIHR5cGVcblx0XHRpZiAoIHNwZWNpYWwucG9zdERpc3BhdGNoICkge1xuXHRcdFx0c3BlY2lhbC5wb3N0RGlzcGF0Y2guY2FsbCggdGhpcywgZXZlbnQgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xuXHR9LFxuXG5cdGhhbmRsZXJzOiBmdW5jdGlvbiggZXZlbnQsIGhhbmRsZXJzICkge1xuXHRcdHZhciBpLCBoYW5kbGVPYmosIHNlbCwgbWF0Y2hlZEhhbmRsZXJzLCBtYXRjaGVkU2VsZWN0b3JzLFxuXHRcdFx0aGFuZGxlclF1ZXVlID0gW10sXG5cdFx0XHRkZWxlZ2F0ZUNvdW50ID0gaGFuZGxlcnMuZGVsZWdhdGVDb3VudCxcblx0XHRcdGN1ciA9IGV2ZW50LnRhcmdldDtcblxuXHRcdC8vIEZpbmQgZGVsZWdhdGUgaGFuZGxlcnNcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgJiZcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05XG5cdFx0XHQvLyBCbGFjay1ob2xlIFNWRyA8dXNlPiBpbnN0YW5jZSB0cmVlcyAodHJhYy0xMzE4MClcblx0XHRcdGN1ci5ub2RlVHlwZSAmJlxuXG5cdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDw9NDJcblx0XHRcdC8vIFN1cHByZXNzIHNwZWMtdmlvbGF0aW5nIGNsaWNrcyBpbmRpY2F0aW5nIGEgbm9uLXByaW1hcnkgcG9pbnRlciBidXR0b24gKHRyYWMtMzg2MSlcblx0XHRcdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvI2V2ZW50LXR5cGUtY2xpY2tcblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExIG9ubHlcblx0XHRcdC8vIC4uLmJ1dCBub3QgYXJyb3cga2V5IFwiY2xpY2tzXCIgb2YgcmFkaW8gaW5wdXRzLCB3aGljaCBjYW4gaGF2ZSBgYnV0dG9uYCAtMSAoZ2gtMjM0Mylcblx0XHRcdCEoIGV2ZW50LnR5cGUgPT09IFwiY2xpY2tcIiAmJiBldmVudC5idXR0b24gPj0gMSApICkge1xuXG5cdFx0XHRmb3IgKCA7IGN1ciAhPT0gdGhpczsgY3VyID0gY3VyLnBhcmVudE5vZGUgfHwgdGhpcyApIHtcblxuXHRcdFx0XHQvLyBEb24ndCBjaGVjayBub24tZWxlbWVudHMgKHRyYWMtMTMyMDgpXG5cdFx0XHRcdC8vIERvbid0IHByb2Nlc3MgY2xpY2tzIG9uIGRpc2FibGVkIGVsZW1lbnRzICh0cmFjLTY5MTEsIHRyYWMtODE2NSwgdHJhYy0xMTM4MiwgdHJhYy0xMTc2NClcblx0XHRcdFx0aWYgKCBjdXIubm9kZVR5cGUgPT09IDEgJiYgISggZXZlbnQudHlwZSA9PT0gXCJjbGlja1wiICYmIGN1ci5kaXNhYmxlZCA9PT0gdHJ1ZSApICkge1xuXHRcdFx0XHRcdG1hdGNoZWRIYW5kbGVycyA9IFtdO1xuXHRcdFx0XHRcdG1hdGNoZWRTZWxlY3RvcnMgPSB7fTtcblx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGRlbGVnYXRlQ291bnQ7IGkrKyApIHtcblx0XHRcdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBpIF07XG5cblx0XHRcdFx0XHRcdC8vIERvbid0IGNvbmZsaWN0IHdpdGggT2JqZWN0LnByb3RvdHlwZSBwcm9wZXJ0aWVzICh0cmFjLTEzMjAzKVxuXHRcdFx0XHRcdFx0c2VsID0gaGFuZGxlT2JqLnNlbGVjdG9yICsgXCIgXCI7XG5cblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlZFNlbGVjdG9yc1sgc2VsIF0gPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlZFNlbGVjdG9yc1sgc2VsIF0gPSBoYW5kbGVPYmoubmVlZHNDb250ZXh0ID9cblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkoIHNlbCwgdGhpcyApLmluZGV4KCBjdXIgKSA+IC0xIDpcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZCggc2VsLCB0aGlzLCBudWxsLCBbIGN1ciBdICkubGVuZ3RoO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVkU2VsZWN0b3JzWyBzZWwgXSApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlZEhhbmRsZXJzLnB1c2goIGhhbmRsZU9iaiApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIG1hdGNoZWRIYW5kbGVycy5sZW5ndGggKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVyUXVldWUucHVzaCggeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBtYXRjaGVkSGFuZGxlcnMgfSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEFkZCB0aGUgcmVtYWluaW5nIC
1hkaXJlY3RseS1ib3VuZCkgaGFuZGxlcnNcblx0XHRjdXIgPSB0aGlzO1xuXHRcdGlmICggZGVsZWdhdGVDb3VudCA8IGhhbmRsZXJzLmxlbmd0aCApIHtcblx0XHRcdGhhbmRsZXJRdWV1ZS5wdXNoKCB7IGVsZW06IGN1ciwgaGFuZGxlcnM6IGhhbmRsZXJzLnNsaWNlKCBkZWxlZ2F0ZUNvdW50ICkgfSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBoYW5kbGVyUXVldWU7XG5cdH0sXG5cblx0YWRkUHJvcDogZnVuY3Rpb24oIG5hbWUsIGhvb2sgKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCBqUXVlcnkuRXZlbnQucHJvdG90eXBlLCBuYW1lLCB7XG5cdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXG5cdFx0XHRnZXQ6IGlzRnVuY3Rpb24oIGhvb2sgKSA/XG5cdFx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlmICggdGhpcy5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGhvb2soIHRoaXMub3JpZ2luYWxFdmVudCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlmICggdGhpcy5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRoaXMub3JpZ2luYWxFdmVudFsgbmFtZSBdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSxcblxuXHRcdFx0c2V0OiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggdGhpcywgbmFtZSwge1xuXHRcdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXHRcdFx0XHRcdHdyaXRhYmxlOiB0cnVlLFxuXHRcdFx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdGZpeDogZnVuY3Rpb24oIG9yaWdpbmFsRXZlbnQgKSB7XG5cdFx0cmV0dXJuIG9yaWdpbmFsRXZlbnRbIGpRdWVyeS5leHBhbmRvIF0gP1xuXHRcdFx0b3JpZ2luYWxFdmVudCA6XG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCBvcmlnaW5hbEV2ZW50ICk7XG5cdH0sXG5cblx0c3BlY2lhbDoge1xuXHRcdGxvYWQ6IHtcblxuXHRcdFx0Ly8gUHJldmVudCB0cmlnZ2VyZWQgaW1hZ2UubG9hZCBldmVudHMgZnJvbSBidWJibGluZyB0byB3aW5kb3cubG9hZFxuXHRcdFx0bm9CdWJibGU6IHRydWVcblx0XHR9LFxuXHRcdGNsaWNrOiB7XG5cblx0XHRcdC8vIFV0aWxpemUgbmF0aXZlIGV2ZW50IHRvIGVuc3VyZSBjb3JyZWN0IHN0YXRlIGZvciBjaGVja2FibGUgaW5wdXRzXG5cdFx0XHRzZXR1cDogZnVuY3Rpb24oIGRhdGEgKSB7XG5cblx0XHRcdFx0Ly8gRm9yIG11dHVhbCBjb21wcmVzc2liaWxpdHkgd2l0aCBfZGVmYXVsdCwgcmVwbGFjZSBgdGhpc2AgYWNjZXNzIHdpdGggYSBsb2NhbCB2YXIuXG5cdFx0XHRcdC8vIGB8fCBkYXRhYCBpcyBkZWFkIGNvZGUgbWVhbnQgb25seSB0byBwcmVzZXJ2ZSB0aGUgdmFyaWFibGUgdGhyb3VnaCBtaW5pZmljYXRpb24uXG5cdFx0XHRcdHZhciBlbCA9IHRoaXMgfHwgZGF0YTtcblxuXHRcdFx0XHQvLyBDbGFpbSB0aGUgZmlyc3QgaGFuZGxlclxuXHRcdFx0XHRpZiAoIHJjaGVja2FibGVUeXBlLnRlc3QoIGVsLnR5cGUgKSAmJlxuXHRcdFx0XHRcdGVsLmNsaWNrICYmIG5vZGVOYW1lKCBlbCwgXCJpbnB1dFwiICkgKSB7XG5cblx0XHRcdFx0XHQvLyBkYXRhUHJpdi5zZXQoIGVsLCBcImNsaWNrXCIsIC4uLiApXG5cdFx0XHRcdFx0bGV2ZXJhZ2VOYXRpdmUoIGVsLCBcImNsaWNrXCIsIHRydWUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFJldHVybiBmYWxzZSB0byBhbGxvdyBub3JtYWwgcHJvY2Vzc2luZyBpbiB0aGUgY2FsbGVyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0sXG5cdFx0XHR0cmlnZ2VyOiBmdW5jdGlvbiggZGF0YSApIHtcblxuXHRcdFx0XHQvLyBGb3IgbXV0dWFsIGNvbXByZXNzaWJpbGl0eSB3aXRoIF9kZWZhdWx0LCByZXBsYWNlIGB0aGlzYCBhY2Nlc3Mgd2l0aCBhIGxvY2FsIHZhci5cblx0XHRcdFx0Ly8gYHx8IGRhdGFgIGlzIGRlYWQgY29kZSBtZWFudCBvbmx5IHRvIHByZXNlcnZlIHRoZSB2YXJpYWJsZSB0aHJvdWdoIG1pbmlmaWNhdGlvbi5cblx0XHRcdFx0dmFyIGVsID0gdGhpcyB8fCBkYXRhO1xuXG5cdFx0XHRcdC8vIEZvcmNlIHNldHVwIGJlZm9yZSB0cmlnZ2VyaW5nIGEgY2xpY2tcblx0XHRcdFx0aWYgKCByY2hlY2thYmxlVHlwZS50ZXN0KCBlbC50eXBlICkgJiZcblx0XHRcdFx0XHRlbC5jbGljayAmJiBub2RlTmFtZSggZWwsIFwiaW5wdXRcIiApICkge1xuXG5cdFx0XHRcdFx0bGV2ZXJhZ2VOYXRpdmUoIGVsLCBcImNsaWNrXCIgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFJldHVybiBub24tZmFsc2UgdG8gYWxsb3cgbm9ybWFsIGV2ZW50LXBhdGggcHJvcGFnYXRpb25cblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBGb3IgY3Jvc3MtYnJvd3NlciBjb25zaXN0ZW5jeSwgc3VwcHJlc3MgbmF0aXZlIC5jbGljaygpIG9uIGxpbmtzXG5cdFx0XHQvLyBBbHNvIHByZXZlbnQgaXQgaWYgd2UncmUgY3VycmVudGx5IGluc2lkZSBhIGxldmVyYWdlZCBuYXRpdmUtZXZlbnQgc3RhY2tcblx0XHRcdF9kZWZhdWx0OiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdHZhciB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG5cdFx0XHRcdHJldHVybiByY2hlY2thYmxlVHlwZS50ZXN0KCB0YXJnZXQudHlwZSApICYmXG5cdFx0XHRcdFx0dGFyZ2V0LmNsaWNrICYmIG5vZGVOYW1lKCB0YXJnZXQsIFwiaW5wdXRcIiApICYmXG5cdFx0XHRcdFx0ZGF0YVByaXYuZ2V0KCB0YXJnZXQsIFwiY2xpY2tcIiApIHx8XG5cdFx0XHRcdFx0bm9kZU5hbWUoIHRhcmdldCwgXCJhXCIgKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0YmVmb3JldW5sb2FkOiB7XG5cdFx0XHRwb3N0RGlzcGF0Y2g6IGZ1bmN0aW9uKCBldmVudCApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDIwK1xuXHRcdFx0XHQvLyBGaXJlZm94IGRvZXNuJ3QgYWxlcnQgaWYgdGhlIHJldHVyblZhbHVlIGZpZWxkIGlzIG5vdCBzZXQuXG5cdFx0XHRcdGlmICggZXZlbnQucmVzdWx0ICE9PSB1bmRlZmluZWQgJiYgZXZlbnQub3JpZ2luYWxFdmVudCApIHtcblx0XHRcdFx0XHRldmVudC5vcmlnaW5hbEV2ZW50LnJldHVyblZhbHVlID0gZXZlbnQucmVzdWx0O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59O1xuXG4vLyBFbnN1cmUgdGhlIHByZXNlbmNlIG9mIGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgaGFuZGxlcyBtYW51YWxseS10cmlnZ2VyZWRcbi8vIHN5bnRoZXRpYyBldmVudHMgYnkgaW50ZXJydXB0aW5nIHByb2dyZXNzIHVudGlsIHJlaW52b2tlZCBpbiByZXNwb25zZSB0b1xuLy8gKm5hdGl2ZSogZXZlbnRzIHRoYXQgaXQgZmlyZXMgZGlyZWN0bHksIGVuc3VyaW5nIHRoYXQgc3RhdGUgY2hhbmdlcyBoYXZlXG4vLyBhbHJlYWR5IG9jY3VycmVkIGJlZm9yZSBvdGhlciBsaXN0ZW5lcnMgYXJlIGludm9rZWQuXG5mdW5jdGlvbiBsZXZlcmFnZU5hdGl2ZSggZWwsIHR5cGUsIGlzU2V0dXAgKSB7XG5cblx0Ly8gTWlzc2luZyBgaXNTZXR1cGAgaW5kaWNhdGVzIGEgdHJpZ2dlciBjYWxsLCB3aGljaCBtdXN0IGZvcmNlIHNldHVwIHRocm91Z2ggalF1ZXJ5LmV2ZW50LmFkZFxuXHRpZiAoICFpc1NldHVwICkge1xuXHRcdGlmICggZGF0YVByaXYuZ2V0KCBlbCwgdHlwZSApID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuYWRkKCBlbCwgdHlwZSwgcmV0dXJuVHJ1ZSApO1xuXHRcdH1cblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBSZWdpc3RlciB0aGUgY29udHJvbGxlciBhcyBhIHNwZWNpYWwgdW5pdmVyc2FsIGhhbmRsZXIgZm9yIGFsbCBldmVudCBuYW1lc3BhY2VzXG5cdGRhdGFQcml2LnNldCggZWwsIHR5cGUsIGZhbHNlICk7XG5cdGpRdWVyeS5ldmVudC5hZGQoIGVsLCB0eX
1BlLCB7XG5cdFx0bmFtZXNwYWNlOiBmYWxzZSxcblx0XHRoYW5kbGVyOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHR2YXIgcmVzdWx0LFxuXHRcdFx0XHRzYXZlZCA9IGRhdGFQcml2LmdldCggdGhpcywgdHlwZSApO1xuXG5cdFx0XHRpZiAoICggZXZlbnQuaXNUcmlnZ2VyICYgMSApICYmIHRoaXNbIHR5cGUgXSApIHtcblxuXHRcdFx0XHQvLyBJbnRlcnJ1cHQgcHJvY2Vzc2luZyBvZiB0aGUgb3V0ZXIgc3ludGhldGljIC50cmlnZ2VyKCllZCBldmVudFxuXHRcdFx0XHRpZiAoICFzYXZlZCApIHtcblxuXHRcdFx0XHRcdC8vIFN0b3JlIGFyZ3VtZW50cyBmb3IgdXNlIHdoZW4gaGFuZGxpbmcgdGhlIGlubmVyIG5hdGl2ZSBldmVudFxuXHRcdFx0XHRcdC8vIFRoZXJlIHdpbGwgYWx3YXlzIGJlIGF0IGxlYXN0IG9uZSBhcmd1bWVudCAoYW4gZXZlbnQgb2JqZWN0KSwgc28gdGhpcyBhcnJheVxuXHRcdFx0XHRcdC8vIHdpbGwgbm90IGJlIGNvbmZ1c2VkIHdpdGggYSBsZWZ0b3ZlciBjYXB0dXJlIG9iamVjdC5cblx0XHRcdFx0XHRzYXZlZCA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdGRhdGFQcml2LnNldCggdGhpcywgdHlwZSwgc2F2ZWQgKTtcblxuXHRcdFx0XHRcdC8vIFRyaWdnZXIgdGhlIG5hdGl2ZSBldmVudCBhbmQgY2FwdHVyZSBpdHMgcmVzdWx0XG5cdFx0XHRcdFx0dGhpc1sgdHlwZSBdKCk7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZGF0YVByaXYuZ2V0KCB0aGlzLCB0eXBlICk7XG5cdFx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCB0eXBlLCBmYWxzZSApO1xuXG5cdFx0XHRcdFx0aWYgKCBzYXZlZCAhPT0gcmVzdWx0ICkge1xuXG5cdFx0XHRcdFx0XHQvLyBDYW5jZWwgdGhlIG91dGVyIHN5bnRoZXRpYyBldmVudFxuXHRcdFx0XHRcdFx0ZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBJZiB0aGlzIGlzIGFuIGlubmVyIHN5bnRoZXRpYyBldmVudCBmb3IgYW4gZXZlbnQgd2l0aCBhIGJ1YmJsaW5nIHN1cnJvZ2F0ZVxuXHRcdFx0XHQvLyAoZm9jdXMgb3IgYmx1ciksIGFzc3VtZSB0aGF0IHRoZSBzdXJyb2dhdGUgYWxyZWFkeSBwcm9wYWdhdGVkIGZyb20gdHJpZ2dlcmluZ1xuXHRcdFx0XHQvLyB0aGUgbmF0aXZlIGV2ZW50IGFuZCBwcmV2ZW50IHRoYXQgZnJvbSBoYXBwZW5pbmcgYWdhaW4gaGVyZS5cblx0XHRcdFx0Ly8gVGhpcyB0ZWNobmljYWxseSBnZXRzIHRoZSBvcmRlcmluZyB3cm9uZyB3LnIudC4gdG8gYC50cmlnZ2VyKClgIChpbiB3aGljaCB0aGVcblx0XHRcdFx0Ly8gYnViYmxpbmcgc3Vycm9nYXRlIHByb3BhZ2F0ZXMgKmFmdGVyKiB0aGUgbm9uLWJ1YmJsaW5nIGJhc2UpLCBidXQgdGhhdCBzZWVtc1xuXHRcdFx0XHQvLyBsZXNzIGJhZCB0aGFuIGR1cGxpY2F0aW9uLlxuXHRcdFx0XHR9IGVsc2UgaWYgKCAoIGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge30gKS5kZWxlZ2F0ZVR5cGUgKSB7XG5cdFx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgdGhpcyBpcyBhIG5hdGl2ZSBldmVudCB0cmlnZ2VyZWQgYWJvdmUsIGV2ZXJ5dGhpbmcgaXMgbm93IGluIG9yZGVyXG5cdFx0XHQvLyBGaXJlIGFuIGlubmVyIHN5bnRoZXRpYyBldmVudCB3aXRoIHRoZSBvcmlnaW5hbCBhcmd1bWVudHNcblx0XHRcdH0gZWxzZSBpZiAoIHNhdmVkICkge1xuXG5cdFx0XHRcdC8vIC4uLmFuZCBjYXB0dXJlIHRoZSByZXN1bHRcblx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCB0eXBlLCBqUXVlcnkuZXZlbnQudHJpZ2dlcihcblx0XHRcdFx0XHRzYXZlZFsgMCBdLFxuXHRcdFx0XHRcdHNhdmVkLnNsaWNlKCAxICksXG5cdFx0XHRcdFx0dGhpc1xuXHRcdFx0XHQpICk7XG5cblx0XHRcdFx0Ly8gQWJvcnQgaGFuZGxpbmcgb2YgdGhlIG5hdGl2ZSBldmVudCBieSBhbGwgalF1ZXJ5IGhhbmRsZXJzIHdoaWxlIGFsbG93aW5nXG5cdFx0XHRcdC8vIG5hdGl2ZSBoYW5kbGVycyBvbiB0aGUgc2FtZSBlbGVtZW50IHRvIHJ1bi4gT24gdGFyZ2V0LCB0aGlzIGlzIGFjaGlldmVkXG5cdFx0XHRcdC8vIGJ5IHN0b3BwaW5nIGltbWVkaWF0ZSBwcm9wYWdhdGlvbiBqdXN0IG9uIHRoZSBqUXVlcnkgZXZlbnQuIEhvd2V2ZXIsXG5cdFx0XHRcdC8vIHRoZSBuYXRpdmUgZXZlbnQgaXMgcmUtd3JhcHBlZCBieSBhIGpRdWVyeSBvbmUgb24gZWFjaCBsZXZlbCBvZiB0aGVcblx0XHRcdFx0Ly8gcHJvcGFnYXRpb24gc28gdGhlIG9ubHkgd2F5IHRvIHN0b3AgaXQgZm9yIGpRdWVyeSBpcyB0byBzdG9wIGl0IGZvclxuXHRcdFx0XHQvLyBldmVyeW9uZSB2aWEgbmF0aXZlIGBzdG9wUHJvcGFnYXRpb24oKWAuIFRoaXMgaXMgbm90IGEgcHJvYmxlbSBmb3Jcblx0XHRcdFx0Ly8gZm9jdXMvYmx1ciB3aGljaCBkb24ndCBidWJibGUsIGJ1dCBpdCBkb2VzIGFsc28gc3RvcCBjbGljayBvbiBjaGVja2JveGVzXG5cdFx0XHRcdC8vIGFuZCByYWRpb3MuIFdlIGFjY2VwdCB0aGlzIGxpbWl0YXRpb24uXG5cdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRldmVudC5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59XG5cbmpRdWVyeS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBoYW5kbGUgKSB7XG5cblx0Ly8gVGhpcyBcImlmXCIgaXMgbmVlZGVkIGZvciBwbGFpbiBvYmplY3RzXG5cdGlmICggZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyICkge1xuXHRcdGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgaGFuZGxlICk7XG5cdH1cbn07XG5cbmpRdWVyeS5FdmVudCA9IGZ1bmN0aW9uKCBzcmMsIHByb3BzICkge1xuXG5cdC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCB0aGUgJ25ldycga2V5d29yZFxuXHRpZiAoICEoIHRoaXMgaW5zdGFuY2VvZiBqUXVlcnkuRXZlbnQgKSApIHtcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5FdmVudCggc3JjLCBwcm9wcyApO1xuXHR9XG5cblx0Ly8gRXZlbnQgb2JqZWN0XG5cdGlmICggc3JjICYmIHNyYy50eX
1BlICkge1xuXHRcdHRoaXMub3JpZ2luYWxFdmVudCA9IHNyYztcblx0XHR0aGlzLnR5cGUgPSBzcmMudHlwZTtcblxuXHRcdC8vIEV2ZW50cyBidWJibGluZyB1cCB0aGUgZG9jdW1lbnQgbWF5IGhhdmUgYmVlbiBtYXJrZWQgYXMgcHJldmVudGVkXG5cdFx0Ly8gYnkgYSBoYW5kbGVyIGxvd2VyIGRvd24gdGhlIHRyZWU7IHJlZmxlY3QgdGhlIGNvcnJlY3QgdmFsdWUuXG5cdFx0dGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSBzcmMuZGVmYXVsdFByZXZlbnRlZCB8fFxuXHRcdFx0XHRzcmMuZGVmYXVsdFByZXZlbnRlZCA9PT0gdW5kZWZpbmVkICYmXG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTIuMyBvbmx5XG5cdFx0XHRcdHNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0cmV0dXJuVHJ1ZSA6XG5cdFx0XHRyZXR1cm5GYWxzZTtcblxuXHRcdC8vIENyZWF0ZSB0YXJnZXQgcHJvcGVydGllc1xuXHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA8PTYgLSA3IG9ubHlcblx0XHQvLyBUYXJnZXQgc2hvdWxkIG5vdCBiZSBhIHRleHQgbm9kZSAodHJhYy01MDQsIHRyYWMtMTMxNDMpXG5cdFx0dGhpcy50YXJnZXQgPSAoIHNyYy50YXJnZXQgJiYgc3JjLnRhcmdldC5ub2RlVHlwZSA9PT0gMyApID9cblx0XHRcdHNyYy50YXJnZXQucGFyZW50Tm9kZSA6XG5cdFx0XHRzcmMudGFyZ2V0O1xuXG5cdFx0dGhpcy5jdXJyZW50VGFyZ2V0ID0gc3JjLmN1cnJlbnRUYXJnZXQ7XG5cdFx0dGhpcy5yZWxhdGVkVGFyZ2V0ID0gc3JjLnJlbGF0ZWRUYXJnZXQ7XG5cblx0Ly8gRXZlbnQgdHlwZVxuXHR9IGVsc2Uge1xuXHRcdHRoaXMudHlwZSA9IHNyYztcblx0fVxuXG5cdC8vIFB1dCBleHBsaWNpdGx5IHByb3ZpZGVkIHByb3BlcnRpZXMgb250byB0aGUgZXZlbnQgb2JqZWN0XG5cdGlmICggcHJvcHMgKSB7XG5cdFx0alF1ZXJ5LmV4dGVuZCggdGhpcywgcHJvcHMgKTtcblx0fVxuXG5cdC8vIENyZWF0ZSBhIHRpbWVzdGFtcCBpZiBpbmNvbWluZyBldmVudCBkb2Vzbid0IGhhdmUgb25lXG5cdHRoaXMudGltZVN0YW1wID0gc3JjICYmIHNyYy50aW1lU3RhbXAgfHwgRGF0ZS5ub3coKTtcblxuXHQvLyBNYXJrIGl0IGFzIGZpeGVkXG5cdHRoaXNbIGpRdWVyeS5leHBhbmRvIF0gPSB0cnVlO1xufTtcblxuLy8galF1ZXJ5LkV2ZW50IGlzIGJhc2VkIG9uIERPTTMgRXZlbnRzIGFzIHNwZWNpZmllZCBieSB0aGUgRUNNQVNjcmlwdCBMYW5ndWFnZSBCaW5kaW5nXG4vLyBodHRwczovL3d3dy53My5vcmcvVFIvMjAwMy9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAwMzAzMzEvZWNtYS1zY3JpcHQtYmluZGluZy5odG1sXG5qUXVlcnkuRXZlbnQucHJvdG90eXBlID0ge1xuXHRjb25zdHJ1Y3RvcjogalF1ZXJ5LkV2ZW50LFxuXHRpc0RlZmF1bHRQcmV2ZW50ZWQ6IHJldHVybkZhbHNlLFxuXHRpc1Byb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cdGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSxcblx0aXNTaW11bGF0ZWQ6IGZhbHNlLFxuXG5cdHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcblxuXHRcdHRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gcmV0dXJuVHJ1ZTtcblxuXHRcdGlmICggZSAmJiAhdGhpcy5pc1NpbXVsYXRlZCApIHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdH0sXG5cdHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gcmV0dXJuVHJ1ZTtcblxuXHRcdGlmICggZSAmJiAhdGhpcy5pc1NpbXVsYXRlZCApIHtcblx0XHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdH1cblxuXHRcdHRoaXMuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdH1cbn07XG5cbi8vIEluY2x1ZGVzIGFsbCBjb21tb24gZXZlbnQgcHJvcHMgaW5jbHVkaW5nIEtleUV2ZW50IGFuZCBNb3VzZUV2ZW50IHNwZWNpZmljIHByb3BzXG5qUXVlcnkuZWFjaCgge1xuXHRhbHRLZXk6IHRydWUsXG5cdGJ1YmJsZXM6IHRydWUsXG5cdGNhbmNlbGFibG
1U6IHRydWUsXG5cdGNoYW5nZWRUb3VjaGVzOiB0cnVlLFxuXHRjdHJsS2V5OiB0cnVlLFxuXHRkZXRhaWw6IHRydWUsXG5cdGV2ZW50UGhhc2U6IHRydWUsXG5cdG1ldGFLZXk6IHRydWUsXG5cdHBhZ2VYOiB0cnVlLFxuXHRwYWdlWTogdHJ1ZSxcblx0c2hpZnRLZXk6IHRydWUsXG5cdHZpZXc6IHRydWUsXG5cdFwiY2hhclwiOiB0cnVlLFxuXHRjb2RlOiB0cnVlLFxuXHRjaGFyQ29kZTogdHJ1ZSxcblx0a2V5OiB0cnVlLFxuXHRrZXlDb2RlOiB0cnVlLFxuXHRidXR0b246IHRydWUsXG5cdGJ1dHRvbnM6IHRydWUsXG5cdGNsaWVudFg6IHRydWUsXG5cdGNsaWVudFk6IHRydWUsXG5cdG9mZnNldFg6IHRydWUsXG5cdG9mZnNldFk6IHRydWUsXG5cdHBvaW50ZXJJZDogdHJ1ZSxcblx0cG9pbnRlclR5cGU6IHRydWUsXG5cdHNjcmVlblg6IHRydWUsXG5cdHNjcmVlblk6IHRydWUsXG5cdHRhcmdldFRvdWNoZXM6IHRydWUsXG5cdHRvRWxlbWVudDogdHJ1ZSxcblx0dG91Y2hlczogdHJ1ZSxcblx0d2hpY2g6IHRydWVcbn0sIGpRdWVyeS5ldmVudC5hZGRQcm9wICk7XG5cbmpRdWVyeS5lYWNoKCB7IGZvY3VzOiBcImZvY3VzaW5cIiwgYmx1cjogXCJmb2N1c291dFwiIH0sIGZ1bmN0aW9uKCB0eXBlLCBkZWxlZ2F0ZVR5cGUgKSB7XG5cblx0ZnVuY3Rpb24gZm9jdXNNYXBwZWRIYW5kbGVyKCBuYXRpdmVFdmVudCApIHtcblx0XHRpZiAoIGRvY3VtZW50LmRvY3VtZW50TW9kZSApIHtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErXG5cdFx0XHQvLyBBdHRhY2ggYSBzaW5nbGUgZm9jdXNpbi9mb2N1c291dCBoYW5kbGVyIG9uIHRoZSBkb2N1bWVudCB3aGlsZSBzb21lb25lIHdhbnRzXG5cdFx0XHQvLyBmb2N1cy9ibHVyLiBUaGlzIGlzIGJlY2F1c2UgdGhlIGZvcm1lciBhcmUgc3luY2hyb25vdXMgaW4gSUUgd2hpbGUgdGhlIGxhdHRlclxuXHRcdFx0Ly8gYXJlIGFzeW5jLiBJbiBvdGhlciBicm93c2VycywgYWxsIHRob3NlIGhhbmRsZXJzIGFyZSBpbnZva2VkIHN5bmNocm9ub3VzbHkuXG5cblx0XHRcdC8vIGBoYW5kbGVgIGZyb20gcHJpdmF0ZSBkYXRhIHdvdWxkIGFscmVhZHkgd3JhcCB0aGUgZXZlbnQsIGJ1dCB3ZSBuZWVkXG5cdFx0XHQvLyB0byBjaGFuZ2UgdGhlIGB0eXBlYCBoZXJlLlxuXHRcdFx0dmFyIGhhbmRsZSA9IGRhdGFQcml2LmdldCggdGhpcywgXCJoYW5kbGVcIiApLFxuXHRcdFx0XHRldmVudCA9IGpRdWVyeS5ldmVudC5maXgoIG5hdGl2ZUV2ZW50ICk7XG5cdFx0XHRldmVudC50eXBlID0gbmF0aXZlRXZlbnQudHlwZSA9PT0gXCJmb2N1c2luXCIgPyBcImZvY3VzXCIgOiBcImJsdXJcIjtcblx0XHRcdGV2ZW50LmlzU2ltdWxhdGVkID0gdHJ1ZTtcblxuXHRcdFx0Ly8gRmlyc3QsIGhhbmRsZSBmb2N1c2luL2ZvY3Vzb3V0XG5cdFx0XHRoYW5kbGUoIG5hdGl2ZUV2ZW50ICk7XG5cblx0XHRcdC8vIC4uLnRoZW4sIGhhbmRsZSBmb2N1cy9ibHVyXG5cdFx0XHQvL1xuXHRcdFx0Ly8gZm9jdXMvYmx1ciBkb24ndCBidWJibGUgd2hpbGUgZm9jdXNpbi9mb2N1c291dCBkbzsgc2ltdWxhdGUgdGhlIGZvcm1lciBieSBvbmx5XG5cdFx0XHQvLyBpbnZva2luZyB0aGUgaGFuZGxlciBhdCB0aGUgbG93ZXIgbGV2ZWwuXG5cdFx0XHRpZiAoIGV2ZW50LnRhcmdldCA9PT0gZXZlbnQuY3VycmVudFRhcmdldCApIHtcblxuXHRcdFx0XHQvLyBUaGUgc2V0dXAgcGFydCBjYWxscyBgbGV2ZXJhZ2VOYXRpdmVgLCB3aGljaCwgaW4gdHVybiwgY2FsbHNcblx0XHRcdFx0Ly8gYGpRdWVyeS5ldmVudC5hZGRgLCBzbyBldmVudCBoYW5kbGUgd2lsbCBhbHJlYWR5IGhhdmUgYmVlbiBzZXRcblx0XHRcdFx0Ly8gYnkgdGhpcyBwb2ludC5cblx0XHRcdFx0aGFuZGxlKCBldmVudCApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIEZvciBub24tSUUgYnJvd3NlcnMsIGF0dGFjaCBhIHNpbmdsZSBjYXB0dXJpbmcgaGFuZGxlciBvbiB0aGUgZG9jdW1lbnRcblx0XHRcdC8vIHdoaWxlIHNvbWVvbmUgd2FudHMgZm9jdXNpbi9mb2N1c291dC5cblx0XHRcdGpRdWVyeS5ldmVudC5zaW11bGF0ZSggZGVsZWdhdGVUeXBlLCBuYXRpdmVFdmVudC50YXJnZXQsXG5cdFx0XHRcdGpRdWVyeS5ldmVudC5maXgoIG5hdGl2ZUV2ZW50ICkgKTtcblx0XHR9XG5cdH1cblxuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdID0ge1xuXG5cdFx0Ly8gVXRpbGl6ZSBuYXRpdmUgZXZlbnQgaWYgcG9zc2libGUgc28gYmx1ci9mb2N1cyBzZXF1ZW5jZSBpcyBjb3JyZWN0XG5cdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHR2YXIgYXR0YWNoZXM7XG5cblx0XHRcdC8vIENsYWltIHRoZSBmaXJzdCBoYW5kbGVyXG5cdFx0XHQvLyBkYXRhUHJpdi5zZXQoIHRoaXMsIFwiZm9jdXNcIiwgLi4uIClcblx0XHRcdC8vIGRhdGFQcml2LnNldCggdGhpcywgXCJibHVyXCIsIC4uLiApXG5cdFx0XHRsZXZlcmFnZU5hdGl2ZSggdGhpcywgdHlwZSwgdHJ1ZSApO1xuXG5cdFx0XHRpZiAoIGRvY3VtZW50LmRvY3VtZW50TW9kZSApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTErXG5cdFx0XHRcdC8vIFdlIHVzZSB0aGUgc2FtZSBuYXRpdmUgaGFuZGxlciBmb3IgZm9jdXNpbiAmIGZvY3VzIChhbmQgZm9jdXNvdXQgJiBibHVyKVxuXHRcdFx0XHQvLyBzbyB3ZSBuZWVkIHRvIGNvb3JkaW5hdGUgc2V0dXAgJiB0ZWFyZG93biBwYXJ0cyBiZXR3ZWVuIHRob3NlIGV2ZW50cy5cblx0XHRcdFx0Ly8gVXNlIGBkZWxlZ2F0ZVR5cGVgIGFzIHRoZSBrZXkgYXMgYHR5cGVgIGlzIGFscmVhZHkgdXNlZCBieSBgbGV2ZXJhZ2VOYXRpdmVgLlxuXHRcdFx0XHRhdHRhY2hlcyA9IGRhdGFQcml2LmdldCggdGhpcywgZGVsZWdhdGVUeXBlICk7XG5cdFx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRcdHRoaXMuYWRkRXZlbnRMaXN0ZW5lciggZGVsZWdhdGVUeXBlLCBmb2N1c01hcHBlZEhhbmRsZXIgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkYXRhUHJpdi5zZXQoIHRoaXMsIGRlbGVnYXRlVHlwZSwgKCBhdHRhY2hlcyB8fCAwICkgKyAxICk7XG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIFJldHVybi
1BmYWxzZSB0byBhbGxvdyBub3JtYWwgcHJvY2Vzc2luZyBpbiB0aGUgY2FsbGVyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBGb3JjZSBzZXR1cCBiZWZvcmUgdHJpZ2dlclxuXHRcdFx0bGV2ZXJhZ2VOYXRpdmUoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIG5vbi1mYWxzZSB0byBhbGxvdyBub3JtYWwgZXZlbnQtcGF0aCBwcm9wYWdhdGlvblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdHRlYXJkb3duOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBhdHRhY2hlcztcblxuXHRcdFx0aWYgKCBkb2N1bWVudC5kb2N1bWVudE1vZGUgKSB7XG5cdFx0XHRcdGF0dGFjaGVzID0gZGF0YVByaXYuZ2V0KCB0aGlzLCBkZWxlZ2F0ZVR5cGUgKSAtIDE7XG5cdFx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRcdHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lciggZGVsZWdhdGVUeXBlLCBmb2N1c01hcHBlZEhhbmRsZXIgKTtcblx0XHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIHRoaXMsIGRlbGVnYXRlVHlwZSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGRhdGFQcml2LnNldCggdGhpcywgZGVsZWdhdGVUeXBlLCBhdHRhY2hlcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIFJldHVybiBmYWxzZSB0byBpbmRpY2F0ZSBzdGFuZGFyZCB0ZWFyZG93biBzaG91bGQgYmUgYXBwbGllZFxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdC8vIFN1cHByZXNzIG5hdGl2ZSBmb2N1cyBvciBibHVyIGlmIHdlJ3JlIGN1cnJlbnRseSBpbnNpZGVcblx0XHQvLyBhIGxldmVyYWdlZCBuYXRpdmUtZXZlbnQgc3RhY2tcblx0XHRfZGVmYXVsdDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0cmV0dXJuIGRhdGFQcml2LmdldCggZXZlbnQudGFyZ2V0LCB0eXBlICk7XG5cdFx0fSxcblxuXHRcdGRlbGVnYXRlVHlwZTogZGVsZWdhdGVUeXBlXG5cdH07XG5cblx0Ly8gU3VwcG9ydDogRmlyZWZveCA8PTQ0XG5cdC8vIEZpcmVmb3ggZG9lc24ndCBoYXZlIGZvY3VzKGluIHwgb3V0KSBldmVudHNcblx0Ly8gUmVsYXRlZCB0aWNrZXQgLSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02ODc3ODdcblx0Ly9cblx0Ly8gU3VwcG9ydDogQ2hyb21lIDw9NDggLSA0OSwgU2FmYXJpIDw9OS4wIC0gOS4xXG5cdC8vIGZvY3VzKGluIHwgb3V0KSBldmVudHMgZmlyZSBhZnRlciBmb2N1cyAmIGJsdXIgZXZlbnRzLFxuXHQvLyB3aGljaCBpcyBzcGVjIHZpb2xhdGlvbiAtIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy8jZXZlbnRzLWZvY3VzZXZlbnQtZXZlbnQtb3JkZXJcblx0Ly8gUmVsYXRlZCB0aWNrZXQgLSBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NDk4NTdcblx0Ly9cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExK1xuXHQvLyBUbyBwcmVzZXJ2ZSByZWxhdGl2ZSBmb2N1c2luL2ZvY3VzICYgZm9jdXNvdXQvYmx1ciBldmVudCBvcmRlciBndWFyYW50ZWVkIG9uIHRoZSAzLnggYnJhbmNoLFxuXHQvLyBhdHRhY2ggYSBzaW5nbGUgaGFuZGxlciBmb3IgYm90aCBldmVudHMgaW4gSUUuXG5cdGpRdWVyeS5ldmVudC5zcGVjaWFsWyBkZWxlZ2F0ZVR5cGUgXSA9IHtcblx0XHRzZXR1cDogZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIEhhbmRsZTogcmVndWxhciBub2RlcyAodmlhIGB0aGlzLm93bmVyRG9jdW1lbnRgKSwgd2luZG93XG5cdFx0XHQvLyAodmlhIGB0aGlzLmRvY3VtZW50YCkgJiBkb2N1bWVudCAodmlhIGB0aGlzYCkuXG5cdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMuZG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0ZGF0YUhvbGRlciA9IGRvY3VtZW50LmRvY3VtZW50TW9kZSA/IHRoaXMgOiBkb2MsXG5cdFx0XHRcdGF0dGFjaGVzID0gZGF0YVByaXYuZ2V0KCBkYXRhSG9sZGVyLCBkZWxlZ2F0ZVR5cGUgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgOSAtIDExK1xuXHRcdFx0Ly8gV2UgdXNlIHRoZSBzYW1lIG5hdGl2ZSBoYW5kbGVyIGZvciBmb2N1c2luICYgZm9jdXMgKGFuZCBmb2N1c291dCAmIGJsdXIpXG5cdFx0XHQvLyBzbyB3ZSBuZWVkIHRvIGNvb3JkaW5hdGUgc2V0dXAgJiB0ZWFyZG93biBwYXJ0cyBiZXR3ZWVuIHRob3NlIGV2ZW50cy5cblx0XHRcdC8vIFVzZSBgZGVsZWdhdGVUeXBlYCBhcyB0aGUga2V5IGFzIGB0eXBlYCBpcyBhbHJlYWR5IHVzZWQgYnkgYGxldmVyYWdlTmF0aXZlYC5cblx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRpZiAoIGRvY3VtZW50LmRvY3VtZW50TW9kZSApIHtcblx0XHRcdFx0XHR0aGlzLmFkZEV2ZW50TGlzdGVuZXIoIGRlbGVnYXRlVHlwZSwgZm9jdXNNYXBwZWRIYW5kbGVyICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZG9jLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGZvY3VzTWFwcGVkSGFuZGxlciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRkYXRhUHJpdi5zZXQoIGRhdGFIb2xkZXIsIGRlbGVnYXRlVHlwZSwgKCBhdHRhY2hlcyB8fCAwICkgKyAxICk7XG5cdFx0fSxcblx0XHR0ZWFyZG93bjogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMuZG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0ZGF0YUhvbGRlciA9IGRvY3VtZW50LmRvY3VtZW50TW9kZSA/IHRoaXMgOiBkb2MsXG5cdFx0XHRcdGF0dGFjaGVzID0gZGF0YVByaXYuZ2V0KCBkYXRhSG9sZGVyLCBkZWxlZ2F0ZVR5cGUgKSAtIDE7XG5cblx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRpZiAoIGRvY3VtZW50LmRvY3VtZW50TW9kZSApIHtcblx0XHRcdFx0XHR0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoIGRlbGVnYXRlVHlwZSwgZm9jdXNNYXBwZWRIYW5kbGVyICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoIHR5cGUsIGZvY3VzTWFwcGVkSGFuZGxlciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGRhdGFQcml2LnJlbW92ZSggZGF0YUhvbGRlciwgZGVsZWdhdGVUeXBlICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkYXRhUHJpdi5zZXQoIGRhdGFIb2xkZXIsIGRlbGVnYXRlVHlwZSwgYXR0YWNoZXMgKTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG59ICk7XG5cbi8vIENyZWF0ZSBtb3VzZWVudGVyL2xlYXZlIGV2ZW50cyB1c2luZyBtb3VzZW92ZXIvb3V0IGFuZCBldmVudC10aW1lIGNoZWNrc1xuLy8gc28gdGhhdCBldmVudCBkZWxlZ2F0aW9uIHdvcmtzIGluIGpRdWVyeS5cbi8vIERvIHRoZSBzYW1lIGZvciBwb2ludGVyZW50ZXIvcG9pbnRlcmxlYXZlIGFuZCBwb2ludGVyb3Zlci9wb2ludGVyb3V0XG4vL1xuLy8gU3VwcG9ydDogU2FmYXJpIDcgb25seVxuLy8gU2FmYXJpIHNlbmRzIG1vdXNlZW50ZXIgdG9vIG9mdGVuOyBzZWU6XG4vLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NzAyNThcbi8vIGZvciB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGJ1ZyAoaXQgZXhpc3RlZCBpbiBvbGRlciBDaHJvbWUgdmVyc2lvbnMgYXMgd2VsbCkuXG5qUXVlcnkuZWFjaCgge1xuXHRtb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLFxuXHRtb3VzZWxlYXZlOiBcIm1vdXNlb3V0XCIsXG5cdHBvaW50ZXJlbnRlcjogXCJwb2ludGVyb3ZlclwiLFxuXHRwb2ludGVybGVhdmU6IFwicG9pbnRlcm91dFwiXG59LCBmdW5jdGlvbiggb3JpZywgZml4ICkge1xuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgb3JpZyBdID0ge1xuXHRcdGRlbGVnYXRlVHlwZTogZml4LFxuXHRcdGJpbmRUeXBlOiBmaXgsXG5cblx0XHRoYW5kbGU6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHZhciByZXQsXG5cdFx0XHRcdHRhcmdldCA9IHRoaXMsXG5cdFx0XHRcdHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0LFxuXHRcdFx0XHRoYW5kbGVPYmogPSBldmVudC5oYW5kbGVPYmo7XG5cblx0XHRcdC8vIEZvciBtb3VzZWVudGVyL2xlYXZlIGNhbGwgdGhlIGhhbmRsZXIgaWYgcmVsYXRlZCBpcyBvdXRzaWRlIHRoZSB0YXJnZXQuXG5cdFx0XHQvLyBOQjogTm8gcmVsYXRlZF
1RhcmdldCBpZiB0aGUgbW91c2UgbGVmdC9lbnRlcmVkIHRoZSBicm93c2VyIHdpbmRvd1xuXHRcdFx0aWYgKCAhcmVsYXRlZCB8fCAoIHJlbGF0ZWQgIT09IHRhcmdldCAmJiAhalF1ZXJ5LmNvbnRhaW5zKCB0YXJnZXQsIHJlbGF0ZWQgKSApICkge1xuXHRcdFx0XHRldmVudC50eXBlID0gaGFuZGxlT2JqLm9yaWdUeXBlO1xuXHRcdFx0XHRyZXQgPSBoYW5kbGVPYmouaGFuZGxlci5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdGV2ZW50LnR5cGUgPSBmaXg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH1cblx0fTtcbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdG9uOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gb24oIHRoaXMsIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKTtcblx0fSxcblx0b25lOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gb24oIHRoaXMsIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIDEgKTtcblx0fSxcblx0b2ZmOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBmbiApIHtcblx0XHR2YXIgaGFuZGxlT2JqLCB0eXBlO1xuXHRcdGlmICggdHlwZXMgJiYgdHlwZXMucHJldmVudERlZmF1bHQgJiYgdHlwZXMuaGFuZGxlT2JqICkge1xuXG5cdFx0XHQvLyAoIGV2ZW50ICkgIGRpc3BhdGNoZWQgalF1ZXJ5LkV2ZW50XG5cdFx0XHRoYW5kbGVPYmogPSB0eXBlcy5oYW5kbGVPYmo7XG5cdFx0XHRqUXVlcnkoIHR5cGVzLmRlbGVnYXRlVGFyZ2V0ICkub2ZmKFxuXHRcdFx0XHRoYW5kbGVPYmoubmFtZXNwYWNlID9cblx0XHRcdFx0XHRoYW5kbGVPYmoub3JpZ1R5cGUgKyBcIi5cIiArIGhhbmRsZU9iai5uYW1lc3BhY2UgOlxuXHRcdFx0XHRcdGhhbmRsZU9iai5vcmlnVHlwZSxcblx0XHRcdFx0aGFuZGxlT2JqLnNlbGVjdG9yLFxuXHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlclxuXHRcdFx0KTtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdFx0Ly8gKCB0eXBlcy1vYmplY3QgWywgc2VsZWN0b3JdIClcblx0XHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XG5cdFx0XHRcdHRoaXMub2ZmKCB0eXBlLCBzZWxlY3RvciwgdHlwZXNbIHR5cGUgXSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXHRcdGlmICggc2VsZWN0b3IgPT09IGZhbHNlIHx8IHR5cGVvZiBzZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzIFssIGZuXSApXG5cdFx0XHRmbiA9IHNlbGVjdG9yO1xuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICggZm4gPT09IGZhbHNlICkge1xuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCB0eXBlcywgZm4sIHNlbGVjdG9yICk7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cblxudmFyXG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMCAtIDExLCBFZGdlIDEyIC0gMTMgb25seVxuXHQvLyBJbiBJRS9FZGdlIHVzaW5nIHJlZ2V4IGdyb3VwcyBoZXJlIGNhdXNlcyBzZXZlcmUgc2xvd2Rvd25zLlxuXHQvLyBTZWUgaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vSUUvZmVlZGJhY2svZGV0YWlscy8xNzM2NTEyL1xuXHRybm9Jbm5lcmh0bWwgPSAvPHNjcmlwdHw8c3R5bGV8PGxpbmsvaSxcblxuXHQvLyBjaGVja2VkPVwiY2hlY2tlZFwiIG9yIGNoZWNrZWRcblx0cmNoZWNrZWQgPSAvY2hlY2tlZFxccyooPzpbXj1dfD1cXHMqLmNoZWNrZWQuKS9pLFxuXG5cdHJjbGVhblNjcmlwdCA9IC9eXFxzKjwhXFxbQ0RBVEFcXFt8XFxdXFxdPlxccyokL2c7XG5cbi8vIFByZWZlciBhIHRib2R5IG92ZXIgaXRzIHBhcmVudCB0YWJsZSBmb3IgY29udGFpbmluZyBuZXcgcm93c1xuZnVuY3Rpb24gbWFuaXB1bGF0aW9uVGFyZ2V0KCBlbGVtLCBjb250ZW50ICkge1xuXHRpZiAoIG5vZGVOYW1lKCBlbGVtLCBcInRhYmxlXCIgKSAmJlxuXHRcdG5vZGVOYW1lKCBjb250ZW50Lm5vZGVUeXBlICE9PSAxMSA/IGNvbnRlbnQgOiBjb250ZW50LmZpcnN0Q2hpbGQsIFwidHJcIiApICkge1xuXG5cdFx0cmV0dXJuIGpRdWVyeSggZWxlbSApLmNoaWxkcmVuKCBcInRib2R5XCIgKVsgMCBdIHx8IGVsZW07XG5cdH1cblxuXHRyZXR1cm4gZWxlbTtcbn1cblxuLy8gUmVwbGFjZS9yZXN0b3JlIHRoZSB0eXBlIGF0dHJpYnV0ZSBvZiBzY3JpcHQgZWxlbWVudHMgZm9yIHNhZmUgRE9NIG1hbmlwdWxhdGlvblxuZnVuY3Rpb24gZGlzYWJsZVNjcmlwdCggZWxlbSApIHtcblx0ZWxlbS50eXBlID0gKCBlbGVtLmdldEF0dHJpYnV0ZSggXCJ0eXBlXCIgKSAhPT0gbnVsbCApICsgXCIvXCIgKyBlbGVtLnR5cGU7XG5cdHJldHVybiBlbGVtO1xufVxuZnVuY3Rpb24gcmVzdG9yZVNjcmlwdCggZWxlbSApIHtcblx0aWYgKCAoIGVsZW0udHlwZSB8fCBcIlwiICkuc2xpY2UoIDAsIDUgKSA9PT0gXCJ0cnVlL1wiICkge1xuXHRcdGVsZW0udHlwZSA9IGVsZW0udHlwZS5zbGljZSggNSApO1xuXHR9IGVsc2Uge1xuXHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBcInR5cGVcIiApO1xuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmZ1bmN0aW9uIGNsb25lQ29weUV2ZW50KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBpLCBsLCB0eXBlLCBwZGF0YU9sZCwgdWRhdGFPbGQsIHVkYXRhQ3VyLCBldmVudHM7XG5cblx0aWYgKCBkZXN0Lm5vZGVUeXBlICE9PSAxICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIDEuIENvcHkgcHJpdmF0ZSBkYXRhOiBldmVudHMsIGhhbmRsZXJzLCBldGMuXG5cdGlmICggZGF0YVByaXYuaGFzRGF0YSggc3JjICkgKSB7XG5cdFx0cGRhdGFPbGQgPSBkYXRhUHJpdi5nZXQoIHNyYyApO1xuXHRcdGV2ZW50cyA9IHBkYXRhT2xkLmV2ZW50cztcblxuXHRcdGlmICggZXZlbnRzICkge1xuXHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBkZXN0LCBcImhhbmRsZSBldmVudHNcIiApO1xuXG5cdFx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcblx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBldmVudHNbIHR5cGUgXS5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggZGVzdCwgdHlwZSwgZXZlbnRzWyB0eXBlIF1bIGkgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gMi4gQ29weSB1c2VyIGRhdGFcblx0aWYgKCBkYXRhVXNlci5oYXNEYXRhKCBzcmMgKSApIHtcblx0XHR1ZGF0YU9sZCA9IGRhdGFVc2VyLmFjY2Vzcyggc3JjICk7XG5cdFx0dWRhdGFDdXIgPSBqUXVlcnkuZXh0ZW5kKCB7fSwgdWRhdGFPbGQgKTtcblxuXHRcdGRhdGFVc2VyLnNldCggZGVzdCwgdWRhdGFDdXIgKTtcblx0fVxufVxuXG4vLyBGaXggSUUgYnVncywgc2VlIHN1cHBvcnQgdGVzdHNcbmZ1bmN0aW9uIGZpeElucHV0KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBub2RlTmFtZSA9IGRlc3Qubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuXHQvLyBGYWlscyB0byBwZXJzaXN0IHRoZSBjaGVja2VkIHN0YXRlIG9mIGEgY2xvbmVkIGNoZWNrYm94IG9yIHJhZGlvIGJ1dHRvbi5cblx0aWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmIHJjaGVja2FibGVUeXBlLnRlc3QoIHNyYy50eX
1BlICkgKSB7XG5cdFx0ZGVzdC5jaGVja2VkID0gc3JjLmNoZWNrZWQ7XG5cblx0Ly8gRmFpbHMgdG8gcmV0dXJuIHRoZSBzZWxlY3RlZCBvcHRpb24gdG8gdGhlIGRlZmF1bHQgc2VsZWN0ZWQgc3RhdGUgd2hlbiBjbG9uaW5nIG9wdGlvbnNcblx0fSBlbHNlIGlmICggbm9kZU5hbWUgPT09IFwiaW5wdXRcIiB8fCBub2RlTmFtZSA9PT0gXCJ0ZXh0YXJlYVwiICkge1xuXHRcdGRlc3QuZGVmYXVsdFZhbHVlID0gc3JjLmRlZmF1bHRWYWx1ZTtcblx0fVxufVxuXG5mdW5jdGlvbiBkb21NYW5pcCggY29sbGVjdGlvbiwgYXJncywgY2FsbGJhY2ssIGlnbm9yZWQgKSB7XG5cblx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRhcmdzID0gZmxhdCggYXJncyApO1xuXG5cdHZhciBmcmFnbWVudCwgZmlyc3QsIHNjcmlwdHMsIGhhc1NjcmlwdHMsIG5vZGUsIGRvYyxcblx0XHRpID0gMCxcblx0XHRsID0gY29sbGVjdGlvbi5sZW5ndGgsXG5cdFx0aU5vQ2xvbmUgPSBsIC0gMSxcblx0XHR2YWx1ZSA9IGFyZ3NbIDAgXSxcblx0XHR2YWx1ZUlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdC8vIFdlIGNhbid0IGNsb25lTm9kZSBmcmFnbWVudHMgdGhhdCBjb250YWluIGNoZWNrZWQsIGluIFdlYktpdFxuXHRpZiAoIHZhbHVlSXNGdW5jdGlvbiB8fFxuXHRcdFx0KCBsID4gMSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0IXN1cHBvcnQuY2hlY2tDbG9uZSAmJiByY2hlY2tlZC50ZXN0KCB2YWx1ZSApICkgKSB7XG5cdFx0cmV0dXJuIGNvbGxlY3Rpb24uZWFjaCggZnVuY3Rpb24oIGluZGV4ICkge1xuXHRcdFx0dmFyIHNlbGYgPSBjb2xsZWN0aW9uLmVxKCBpbmRleCApO1xuXHRcdFx0aWYgKCB2YWx1ZUlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdGFyZ3NbIDAgXSA9IHZhbHVlLmNhbGwoIHRoaXMsIGluZGV4LCBzZWxmLmh0bWwoKSApO1xuXHRcdFx0fVxuXHRcdFx0ZG9tTWFuaXAoIHNlbGYsIGFyZ3MsIGNhbGxiYWNrLCBpZ25vcmVkICk7XG5cdFx0fSApO1xuXHR9XG5cblx0aWYgKCBsICkge1xuXHRcdGZyYWdtZW50ID0gYnVpbGRGcmFnbWVudCggYXJncywgY29sbGVjdGlvblsgMCBdLm93bmVyRG9jdW1lbnQsIGZhbHNlLCBjb2xsZWN0aW9uLCBpZ25vcmVkICk7XG5cdFx0Zmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkO1xuXG5cdFx0aWYgKCBmcmFnbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSApIHtcblx0XHRcdGZyYWdtZW50ID0gZmlyc3Q7XG5cdFx0fVxuXG5cdFx0Ly8gUmVxdWlyZSBlaXRoZXIgbmV3IGNvbnRlbnQgb3IgYW4gaW50ZXJlc3QgaW4gaWdub3JlZCBlbGVtZW50cyB0byBpbnZva2UgdGhlIGNhbGxiYWNrXG5cdFx0aWYgKCBmaXJzdCB8fCBpZ25vcmVkICkge1xuXHRcdFx0c2NyaXB0cyA9IGpRdWVyeS5tYXAoIGdldEFsbCggZnJhZ21lbnQsIFwic2NyaXB0XCIgKSwgZGlzYWJsZVNjcmlwdCApO1xuXHRcdFx0aGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoO1xuXG5cdFx0XHQvLyBVc2UgdGhlIG9yaWdpbmFsIGZyYWdtZW50IGZvciB0aGUgbGFzdCBpdGVtXG5cdFx0XHQvLyBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXBcblx0XHRcdC8vIGJlaW5nIGVtcHRpZWQgaW5jb3JyZWN0bHkgaW4gY2VydGFpbiBzaXR1YXRpb25zICh0cmFjLTgwNzApLlxuXHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRub2RlID0gZnJhZ21lbnQ7XG5cblx0XHRcdFx0aWYgKCBpICE9PSBpTm9DbG9uZSApIHtcblx0XHRcdFx0XHRub2RlID0galF1ZXJ5LmNsb25lKCBub2RlLCB0cnVlLCB0cnVlICk7XG5cblx0XHRcdFx0XHQvLyBLZWVwIHJlZmVyZW5jZXMgdG8gY2xvbmVkIHNjcmlwdHMgZm9yIGxhdGVyIHJlc3RvcmF0aW9uXG5cdFx0XHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0XHRcdFx0XHRcdC8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0XHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggc2NyaXB0cywgZ2V0QWxsKCBub2RlLCBcInNjcmlwdFwiICkgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjYWxsYmFjay5jYWxsKCBjb2xsZWN0aW9uWyBpIF0sIG5vZGUsIGkgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xuXHRcdFx0XHRkb2MgPSBzY3JpcHRzWyBzY3JpcHRzLmxlbmd0aCAtIDEgXS5vd25lckRvY3VtZW50O1xuXG5cdFx0XHRcdC8vIFJlLWVuYWJsZSBzY3JpcHRzXG5cdFx0XHRcdGpRdWVyeS5tYXAoIHNjcmlwdHMsIHJlc3RvcmVTY3JpcHQgKTtcblxuXHRcdFx0XHQvLyBFdmFsdWF0ZSBleGVjdXRhYmxlIHNjcmlwdHMgb24gZmlyc3QgZG9jdW1lbnQgaW5zZXJ0aW9uXG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgaGFzU2NyaXB0czsgaSsrICkge1xuXHRcdFx0XHRcdG5vZGUgPSBzY3JpcHRzWyBpIF07XG5cdFx0XHRcdFx0aWYgKCByc2NyaXB0VHlwZS50ZXN0KCBub2RlLnR5cGUgfHwgXCJcIiApICYmXG5cdFx0XHRcdFx0XHQhZGF0YVByaXYuYWNjZXNzKCBub2RlLCBcImdsb2JhbEV2YWxcIiApICYmXG5cdFx0XHRcdFx0XHRqUXVlcnkuY29udGFpbnMoIGRvYywgbm9kZSApICkge1xuXG5cdFx0XHRcdFx0XHRpZiAoIG5vZGUuc3JjICYmICggbm9kZS50eXBlIHx8IFwiXCIgKS50b0xvd2VyQ2FzZSgpICAhPT0gXCJtb2R1bGVcIiApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBPcHRpb25hbCBBSkFYIGRlcGVuZGVuY3ksIGJ1dCB3b24ndCBydW4gc2NyaXB0cyBpZiBub3QgcHJlc2VudFxuXHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5fZXZhbFVybCAmJiAhbm9kZS5ub01vZHVsZSApIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuX2V2YWxVcmwoIG5vZGUuc3JjLCB7XG5cdFx0XHRcdFx0XHRcdFx0XHRub25jZTogbm9kZS5ub25jZSB8fCBub2RlLmdldEF0dHJpYnV0ZSggXCJub25jZVwiIClcblx0XHRcdFx0XHRcdFx0XHR9LCBkb2MgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBVbndyYXAgYSBDREFUQSBzZWN0aW9uIGNvbnRhaW5pbmcgc2NyaXB0IGNvbnRlbn
1RzLiBUaGlzIHNob3VsZG4ndCBiZVxuXHRcdFx0XHRcdFx0XHQvLyBuZWVkZWQgYXMgaW4gWE1MIGRvY3VtZW50cyB0aGV5J3JlIGFscmVhZHkgbm90IHZpc2libGUgd2hlblxuXHRcdFx0XHRcdFx0XHQvLyBpbnNwZWN0aW5nIGVsZW1lbnQgY29udGVudHMgYW5kIGluIEhUTUwgZG9jdW1lbnRzIHRoZXkgaGF2ZSBub1xuXHRcdFx0XHRcdFx0XHQvLyBtZWFuaW5nIGJ1dCB3ZSdyZSBwcmVzZXJ2aW5nIHRoYXQgbG9naWMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuXHRcdFx0XHRcdFx0XHQvLyBUaGlzIHdpbGwgYmUgcmVtb3ZlZCBjb21wbGV0ZWx5IGluIDQuMC4gU2VlIGdoLTQ5MDQuXG5cdFx0XHRcdFx0XHRcdERPTUV2YWwoIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICksIG5vZGUsIGRvYyApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBjb2xsZWN0aW9uO1xufVxuXG5mdW5jdGlvbiByZW1vdmUoIGVsZW0sIHNlbGVjdG9yLCBrZWVwRGF0YSApIHtcblx0dmFyIG5vZGUsXG5cdFx0bm9kZXMgPSBzZWxlY3RvciA/IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCBlbGVtICkgOiBlbGVtLFxuXHRcdGkgPSAwO1xuXG5cdGZvciAoIDsgKCBub2RlID0gbm9kZXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcblx0XHRpZiAoICFrZWVwRGF0YSAmJiBub2RlLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBub2RlICkgKTtcblx0XHR9XG5cblx0XHRpZiAoIG5vZGUucGFyZW50Tm9kZSApIHtcblx0XHRcdGlmICgga2VlcERhdGEgJiYgaXNBdHRhY2hlZCggbm9kZSApICkge1xuXHRcdFx0XHRzZXRHbG9iYWxFdmFsKCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0fVxuXHRcdFx0bm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBub2RlICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0aHRtbFByZWZpbHRlcjogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0cmV0dXJuIGh0bWw7XG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uKCBlbGVtLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHR2YXIgaSwgbCwgc3JjRWxlbWVudHMsIGRlc3RFbGVtZW50cyxcblx0XHRcdGNsb25lID0gZWxlbS5jbG9uZU5vZGUoIHRydWUgKSxcblx0XHRcdGluUGFnZSA9IGlzQXR0YWNoZWQoIGVsZW0gKTtcblxuXHRcdC8vIEZpeCBJRSBjbG9uaW5nIGlzc3Vlc1xuXHRcdGlmICggIXN1cHBvcnQubm9DbG9uZUNoZWNrZWQgJiYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGVsZW0ubm9kZVR5cGUgPT09IDExICkgJiZcblx0XHRcdFx0IWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXG5cdFx0XHQvLyBXZSBlc2NoZXcgalF1ZXJ5I2ZpbmQgaGVyZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29uczpcblx0XHRcdC8vIGh0dHBzOi8vanNwZXJmLmNvbS9nZXRhbGwtdnMtc2l6emxlLzJcblx0XHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUgKTtcblx0XHRcdHNyY0VsZW1lbnRzID0gZ2V0QWxsKCBlbGVtICk7XG5cblx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRmaXhJbnB1dCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDb3B5IHRoZSBldmVudHMgZnJvbSB0aGUgb3JpZ2luYWwgdG8gdGhlIGNsb25lXG5cdFx0aWYgKCBkYXRhQW5kRXZlbnRzICkge1xuXHRcdFx0aWYgKCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHRcdFx0c3JjRWxlbWVudHMgPSBzcmNFbGVtZW50cyB8fCBnZXRBbGwoIGVsZW0gKTtcblx0XHRcdFx0ZGVzdEVsZW1lbnRzID0gZGVzdEVsZW1lbnRzIHx8IGdldEFsbCggY2xvbmUgKTtcblxuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IHNyY0VsZW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRjbG9uZUNvcHlFdmVudCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIGVsZW0sIGNsb25lICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUHJlc2VydmUgc2NyaXB0IGV2YWx1YXRpb24gaGlzdG9yeVxuXHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUsIFwic2NyaXB0XCIgKTtcblx0XHRpZiAoIGRlc3RFbGVtZW50cy5sZW5ndGggPiAwICkge1xuXHRcdFx0c2V0R2xvYmFsRXZhbCggZGVzdEVsZW1lbnRzLCAhaW5QYWdlICYmIGdldEFsbCggZWxlbSwgXCJzY3JpcHRcIiApICk7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIHRoZSBjbG9uZWQgc2V0XG5cdFx0cmV0dXJuIGNsb25lO1xuXHR9LFxuXG5cdGNsZWFuRGF0YTogZnVuY3Rpb24oIGVsZW1zICkge1xuXHRcdHZhciBkYXRhLCBlbGVtLCB0eXBlLFxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7ICggZWxlbSA9IGVsZW1zWyBpIF0gKSAhPT0gdW5kZWZpbmVkOyBpKysgKSB7XG5cdFx0XHRpZiAoIGFjY2VwdERhdGEoIGVsZW0gKSApIHtcblx0XHRcdFx0aWYgKCAoIGRhdGEgPSBlbGVtWyBkYXRhUHJpdi5leHBhbmRvIF0gKSApIHtcblx0XHRcdFx0XHRpZiAoIGRhdGEuZXZlbnRzICkge1xuXHRcdFx0XHRcdFx0Zm9yICggdHlwZSBpbiBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsWyB0eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIFRoaXMgaXMgYSBzaG9ydGN1dCB0byBhdm9pZCBqUXVlcnkuZXZlbnQucmVtb3ZlJ3Mgb3ZlcmhlYWRcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGRhdGEuaGFuZGxlICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0zNSAtIDQ1K1xuXHRcdFx0XHRcdC8vIEFzc2lnbiB1bmRlZmluZWQgaW5zdGVhZCBvZiB1c2luZyBkZWxldGUsIHNlZSBEYXRhI3JlbW92ZVxuXHRcdFx0XHRcdGVsZW1bIGRhdGFQcml2LmV4cGFuZG8gXSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIGVsZW1bIGRhdGFVc2VyLmV4cGFuZG8gXSApIHtcblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDUrXG5cdFx0XHRcdFx0Ly8gQXNzaWduIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIHVzaW5nIGRlbGV0ZSwgc2VlIERhdGEjcmVtb3ZlXG5cdFx0XHRcdFx0ZWxlbVsgZGF0YVVzZXIuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0ZGV0YWNoOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHJlbW92ZSggdGhpcywgc2VsZWN0b3IsIHRydWUgKTtcblx0fSxcblxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gcmVtb3ZlKCB0aGlzLCBzZWxlY3RvciApO1xuXHR9LFxuXG5cdHRleHQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS50ZXh0KCB0aGlzICkgOlxuXHRcdFx0XHR0aGlzLmVtcHR5KCkuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRleHRDb250ZW50ID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fSxcblxuXHRhcHBlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybi
1Bkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XG5cdFx0XHRcdHRhcmdldC5hcHBlbmRDaGlsZCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRwcmVwZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0YXJnZXQuZmlyc3RDaGlsZCApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRiZWZvcmU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdGFmdGVyOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0dGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcy5uZXh0U2libGluZyApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGVsZW0sXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKCBlbGVtID0gdGhpc1sgaSBdICkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXG5cdFx0XHRcdC8vIFByZXZlbnQgbWVtb3J5IGxlYWtzXG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggZWxlbSwgZmFsc2UgKSApO1xuXG5cdFx0XHRcdC8vIFJlbW92ZSBhbnkgcmVtYWluaW5nIG5vZGVzXG5cdFx0XHRcdGVsZW0udGV4dENvbnRlbnQgPSBcIlwiO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiggZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0ZGF0YUFuZEV2ZW50cyA9IGRhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGZhbHNlIDogZGF0YUFuZEV2ZW50cztcblx0XHRkZWVwRGF0YUFuZEV2ZW50cyA9IGRlZXBEYXRhQW5kRXZlbnRzID09IG51bGwgPyBkYXRhQW5kRXZlbnRzIDogZGVlcERhdGFBbmRFdmVudHM7XG5cblx0XHRyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5jbG9uZSggdGhpcywgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKTtcblx0XHR9ICk7XG5cdH0sXG5cblx0aHRtbDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBlbGVtID0gdGhpc1sgMCBdIHx8IHt9LFxuXHRcdFx0XHRpID0gMCxcblx0XHRcdFx0bCA9IHRoaXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIHZhbHVlID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uaW5uZXJIVE1MO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZWUgaWYgd2UgY2FuIHRha2UgYSBzaG9ydGN1dCBhbmQganVzdCB1c2UgaW5uZXJIVE1MXG5cdFx0XHRpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAhcm5vSW5uZXJodG1sLnRlc3QoIHZhbHVlICkgJiZcblx0XHRcdFx0IXdyYXBNYXBbICggcnRhZ05hbWUuZXhlYyggdmFsdWUgKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKSBdICkge1xuXG5cdFx0XHRcdHZhbHVlID0galF1ZXJ5Lmh0bWxQcmVmaWx0ZXIoIHZhbHVlICk7XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRlbGVtID0gdGhpc1sgaSBdIHx8IHt9O1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgZWxlbWVudCBub2RlcyBhbmQgcHJldmVudCBtZW1vcnkgbGVha3Ncblx0XHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cdFx0XHRcdFx0XHRcdGVsZW0uaW5uZXJIVE1MID0gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZWxlbSA9IDA7XG5cblx0XHRcdFx0Ly8gSWYgdXNpbmcgaW5uZXJIVE1MIHRocm93cyBhbiBleGNlcHRpb24sIHVzZSB0aGUgZmFsbGJhY2sgbWV0aG9kXG5cdFx0XHRcdH0gY2F0Y2ggKCBlICkge31cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHR0aGlzLmVtcHR5KCkuYXBwZW5kKCB2YWx1ZSApO1xuXHRcdFx0fVxuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoICk7XG5cdH0sXG5cblx0cmVwbGFjZVdpdGg6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBpZ25vcmVkID0gW107XG5cblx0XHQvLyBNYWtlIHRoZSBjaGFuZ2VzLCByZXBsYWNpbmcgZWFjaCBub24taWdub3JlZCBjb250ZXh0IGVsZW1lbnQgd2l0aCB0aGUgbmV3IGNvbnRlbnRcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlO1xuXG5cdFx0XHRpZiAoIGpRdWVyeS5pbkFycmF5KCB0aGlzLCBpZ25vcmVkICkgPCAwICkge1xuXHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIHRoaXMgKSApO1xuXHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblx0XHRcdFx0XHRwYXJlbnQucmVwbGFjZUNoaWxkKCBlbGVtLCB0aGlzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEZvcmNlIGNhbGxiYWNrIGludm9jYXRpb25cblx0XHR9LCBpZ25vcmVkICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIHtcblx0YXBwZW5kVG86IFwiYXBwZW5kXCIsXG5cdHByZXBlbmRUbzogXCJwcmVwZW5kXCIsXG5cdGluc2VydEJlZm9yZTogXCJiZWZvcmVcIixcblx0aW5zZXJ0QWZ0ZXI6IFwiYWZ0ZXJcIixcblx0cmVwbGFjZUFsbDogXCJyZXBsYWNlV2l0aFwiXG59LCBmdW5jdGlvbiggbmFtZSwgb3JpZ2luYWwgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBlbGVtcyxcblx0XHRcdHJldCA9IFtdLFxuXHRcdFx0aW5zZXJ0ID0galF1ZXJ5KCBzZWxlY3RvciApLFxuXHRcdFx0bGFzdCA9IGluc2VydC5sZW5ndGggLSAxLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7IGkgPD0gbGFzdDsgaSsrICkge1xuXHRcdFx0ZWxlbXMgPSBpID09PSBsYXN0ID8gdGhpcyA6IHRoaXMuY2xvbmUoIHRydWUgKTtcblx0XHRcdGpRdWVyeSggaW5zZXJ0WyBpIF0gKVsgb3JpZ2luYWwgXSggZWxlbXMgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdFx0XHQvLyAuZ2V0KCkgYmVjYXVzZSBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdFx0XHRwdXNoLmFwcGx5KCByZXQsIGVsZW1zLmdldCgpICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTtcblx0fTtcbn0gKTtcbnZhciBybnVtbm9ucHggPSBuZXcgUmVnRXhwKCBcIl4oXCIgKyBwbnVtICsgXCIpKD8hcHgpW2EteiVdKyRcIiwgXCJpXCIgKTtcblxudmFyIHJjdXN0b21Qcm9wID0gL14tLS87XG5cblxudmFyIGdldFN0eWxlcyA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5LCBGaXJlZm94IDw9MzAgKHRyYWMtMTUwOTgsIHRyYWMtMTQxNTApXG5cdFx0Ly8gSUUgdGhyb3dzIG9uIGVsZW1lbnRzIGNyZWF0ZWQgaW4gcG9wdXBzXG5cdFx0Ly8gRkYgbWVhbndoaWxlIHRocm93cyBvbiBmcmFtZSBlbGVtZW50cyB0aHJvdWdoIFwiZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZVwiXG5cdFx0dmFyIHZpZXcgPSBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXc7XG5cblx0XHRpZiAoICF2aWV3IHx8ICF2aWV3Lm9wZW5lciApIHtcblx0XHRcdHZpZXcgPSB3aW5kb3c7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHZpZXcuZ2V0Q29tcHV0ZWRTdHlsZSggZWxlbSApO1xuXHR9O1xuXG52YXIgc3dhcCA9IGZ1bmN0aW9uKCBlbGVtLCBvcHRpb25zLCBjYWxsYmFjayApIHtcblx0dmFyIHJldCwgbmFtZSxcblx0XHRvbGQgPSB7fTtcblxuXHQvLyBSZW1lbWJlciB0aGUgb2xkIHZhbHVlcywgYW5kIGluc2VydCB0aGUgbmV3IG9uZXNcblx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdG9sZFsgbmFtZSBdID0gZWxlbS5zdHlsZVsgbmFtZSBdO1xuXHRcdGVsZW0uc3R5bGVbIG5hbWUgXSA9IG9wdGlvbnNbIG5hbWUgXTtcblx0fVxuXG5cdHJldCA9IGNhbGxiYWNrLmNhbGwoIGVsZW0gKTtcblxuXHQvLyBSZX
1ZlcnQgdGhlIG9sZCB2YWx1ZXNcblx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdGVsZW0uc3R5bGVbIG5hbWUgXSA9IG9sZFsgbmFtZSBdO1xuXHR9XG5cblx0cmV0dXJuIHJldDtcbn07XG5cblxudmFyIHJib3hTdHlsZSA9IG5ldyBSZWdFeHAoIGNzc0V4cGFuZC5qb2luKCBcInxcIiApLCBcImlcIiApO1xuXG5cblxuKCBmdW5jdGlvbigpIHtcblxuXHQvLyBFeGVjdXRpbmcgYm90aCBwaXhlbFBvc2l0aW9uICYgYm94U2l6aW5nUmVsaWFibGUgdGVzdHMgcmVxdWlyZSBvbmx5IG9uZSBsYXlvdXRcblx0Ly8gc28gdGhleSdyZSBleGVjdXRlZCBhdCB0aGUgc2FtZSB0aW1lIHRvIHNhdmUgdGhlIHNlY29uZCBjb21wdXRhdGlvbi5cblx0ZnVuY3Rpb24gY29tcHV0ZVN0eWxlVGVzdHMoKSB7XG5cblx0XHQvLyBUaGlzIGlzIGEgc2luZ2xldG9uLCB3ZSBuZWVkIHRvIGV4ZWN1dGUgaXQgb25seSBvbmNlXG5cdFx0aWYgKCAhZGl2ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnRhaW5lci5zdHlsZS5jc3NUZXh0ID0gXCJwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0Oi0xMTExMXB4O3dpZHRoOjYwcHg7XCIgK1xuXHRcdFx0XCJtYXJnaW4tdG9wOjFweDtwYWRkaW5nOjA7Ym9yZGVyOjBcIjtcblx0XHRkaXYuc3R5bGUuY3NzVGV4dCA9XG5cdFx0XHRcInBvc2l0aW9uOnJlbGF0aXZlO2Rpc3BsYXk6YmxvY2s7Ym94LXNpemluZzpib3JkZXItYm94O292ZXJmbG93OnNjcm9sbDtcIiArXG5cdFx0XHRcIm1hcmdpbjphdXRvO2JvcmRlcjoxcHg7cGFkZGluZzoxcHg7XCIgK1xuXHRcdFx0XCJ3aWR0aDo2MCU7dG9wOjElXCI7XG5cdFx0ZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKCBjb250YWluZXIgKS5hcHBlbmRDaGlsZCggZGl2ICk7XG5cblx0XHR2YXIgZGl2U3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggZGl2ICk7XG5cdFx0cGl4ZWxQb3NpdGlvblZhbCA9IGRpdlN0eWxlLnRvcCAhPT0gXCIxJVwiO1xuXG5cdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAgLSA0LjMgb25seSwgRmlyZWZveCA8PTMgLSA0NFxuXHRcdHJlbGlhYmxlTWFyZ2luTGVmdFZhbCA9IHJvdW5kUGl4ZWxNZWFzdXJlcyggZGl2U3R5bGUubWFyZ2luTGVmdCApID09PSAxMjtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIC0gNC4zIG9ubHksIFNhZmFyaSA8PTkuMSAtIDEwLjEsIGlPUyA8PTcuMCAtIDkuM1xuXHRcdC8vIFNvbWUgc3R5bGVzIGNvbWUgYmFjayB3aXRoIHBlcmNlbnRhZ2UgdmFsdWVzLCBldmVuIHRob3VnaCB0aGV5IHNob3VsZG4ndFxuXHRcdGRpdi5zdHlsZS5yaWdodCA9IFwiNjAlXCI7XG5cdFx0cGl4ZWxCb3hTdHlsZXNWYWwgPSByb3VuZFBpeGVsTWVhc3VyZXMoIGRpdlN0eWxlLnJpZ2h0ICkgPT09IDM2O1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgOSAtIDExIG9ubHlcblx0XHQvLyBEZXRlY3QgbWlzcmVwb3J0aW5nIG9mIGNvbnRlbnQgZGltZW5zaW9ucyBmb3IgYm94LXNpemluZzpib3JkZXItYm94IGVsZW1lbnRzXG5cdFx0Ym94U2l6aW5nUmVsaWFibGVWYWwgPSByb3VuZFBpeGVsTWVhc3VyZXMoIGRpdlN0eWxlLndpZHRoICkgPT09IDM2O1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgOSBvbmx5XG5cdFx0Ly8gRGV0ZWN0IG92ZXJmbG93OnNjcm9sbCBzY3Jld2luZXNzIChnaC0zNjk5KVxuXHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTY0XG5cdFx0Ly8gRG9uJ3QgZ2V0IHRyaWNrZWQgd2hlbiB6b29tIGFmZmVjdHMgb2Zmc2V0V2lkdGggKGdoLTQwMjkpXG5cdFx0ZGl2LnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuXHRcdHNjcm9sbGJveFNpemVWYWwgPSByb3VuZFBpeGVsTWVhc3VyZXMoIGRpdi5vZmZzZXRXaWR0aCAvIDMgKSA9PT0gMTI7XG5cblx0XHRkb2N1bWVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoIGNvbnRhaW5lciApO1xuXG5cdFx0Ly8gTnVsbGlmeSB0aGUgZGl2IHNvIGl0IHdvdWxkbid0IGJlIHN0b3JlZCBpbiB0aGUgbWVtb3J5IGFuZFxuXHRcdC8vIGl0IHdpbGwgYWxzbyBiZSBhIHNpZ24gdGhhdCBjaGVja3MgYWxyZWFkeSBwZXJmb3JtZWRcblx0XHRkaXYgPSBudWxsO1xuXHR9XG5cblx0ZnVuY3Rpb24gcm91bmRQaXhlbE1lYXN1cmVzKCBtZWFzdXJlICkge1xuXHRcdHJldHVybiBNYXRoLnJvdW5kKCBwYXJzZUZsb2F0KCBtZWFzdXJlICkgKTtcblx0fVxuXG5cdHZhciBwaXhlbFBvc2l0aW9uVmFsLCBib3hTaXppbmdSZWxpYWJsZVZhbCwgc2Nyb2xsYm94U2l6ZVZhbCwgcGl4ZWxCb3hTdHlsZXNWYWwsXG5cdFx0cmVsaWFibGVUckRpbWVuc2lvbnNWYWwsIHJlbGlhYmxlTWFyZ2luTGVmdFZhbCxcblx0XHRjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICksXG5cdFx0ZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApO1xuXG5cdC8vIEZpbmlzaCBlYXJseSBpbiBsaW1pdGVkIChub24tYnJvd3NlcikgZW52aXJvbm1lbnRzXG5cdGlmICggIWRpdi5zdHlsZSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSBvbmx5XG5cdC8vIFN0eWxlIG9mIGNsb25lZCBlbGVtZW50IGFmZmVjdHMgc291cmNlIGVsZW1lbnQgY2xvbmVkICh0cmFjLTg5MDgpXG5cdGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9IFwiY29udGVudC1ib3hcIjtcblx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJcIjtcblx0c3VwcG9ydC5jbGVhckNsb25lU3R5bGUgPSBkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPT09IFwiY29udGVudC1ib3hcIjtcblxuXHRqUXVlcnkuZXh0ZW5kKCBzdXBwb3J0LCB7XG5cdFx0Ym94U2l6aW5nUmVsaWFibGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybiBib3hTaXppbmdSZWxpYWJsZVZhbDtcblx0XHR9LFxuXHRcdHBpeGVsQm94U3R5bGVzOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gcGl4ZWxCb3hTdHlsZXNWYWw7XG5cdFx0fSxcblx0XHRwaXhlbFBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gcGl4ZWxQb3NpdGlvblZhbDtcblx0XHR9LFxuXHRcdHJlbGlhYmxlTWFyZ2luTGVmdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xuXHRcdFx0cmV0dXJuIHJlbGlhYmxlTWFyZ2luTGVmdFZhbDtcblx0XHR9LFxuXHRcdHNjcm9sbGJveFNpemU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybi
1BzY3JvbGxib3hTaXplVmFsO1xuXHRcdH0sXG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTErLCBFZGdlIDE1IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBtaXNyZXBvcnQgYGdldENvbXB1dGVkU3R5bGVgIG9mIHRhYmxlIHJvd3Mgd2l0aCB3aWR0aC9oZWlnaHRcblx0XHQvLyBzZXQgaW4gQ1NTIHdoaWxlIGBvZmZzZXQqYCBwcm9wZXJ0aWVzIHJlcG9ydCBjb3JyZWN0IHZhbHVlcy5cblx0XHQvLyBCZWhhdmlvciBpbiBJRSA5IGlzIG1vcmUgc3VidGxlIHRoYW4gaW4gbmV3ZXIgdmVyc2lvbnMgJiBpdCBwYXNzZXNcblx0XHQvLyBzb21lIHZlcnNpb25zIG9mIHRoaXMgdGVzdDsgbWFrZSBzdXJlIG5vdCB0byBtYWtlIGl0IHBhc3MgdGhlcmUhXG5cdFx0Ly9cblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDcwK1xuXHRcdC8vIE9ubHkgRmlyZWZveCBpbmNsdWRlcyBib3JkZXIgd2lkdGhzXG5cdFx0Ly8gaW4gY29tcHV0ZWQgZGltZW5zaW9ucy4gKGdoLTQ1MjkpXG5cdFx0cmVsaWFibGVUckRpbWVuc2lvbnM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHRhYmxlLCB0ciwgdHJDaGlsZCwgdHJTdHlsZTtcblx0XHRcdGlmICggcmVsaWFibGVUckRpbWVuc2lvbnNWYWwgPT0gbnVsbCApIHtcblx0XHRcdFx0dGFibGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInRhYmxlXCIgKTtcblx0XHRcdFx0dHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInRyXCIgKTtcblx0XHRcdFx0dHJDaGlsZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHRcdFx0XHR0YWJsZS5zdHlsZS5jc3NUZXh0ID0gXCJwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0Oi0xMTExMXB4O2JvcmRlci1jb2xsYXBzZTpzZXBhcmF0ZVwiO1xuXHRcdFx0XHR0ci5zdHlsZS5jc3NUZXh0ID0gXCJib3gtc2l6aW5nOmNvbnRlbnQtYm94O2JvcmRlcjoxcHggc29saWRcIjtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgODYrXG5cdFx0XHRcdC8vIEhlaWdodCBzZXQgdGhyb3VnaCBjc3NUZXh0IGRvZXMgbm90IGdldCBhcHBsaWVkLlxuXHRcdFx0XHQvLyBDb21wdXRlZCBoZWlnaHQgdGhlbiBjb21lcyBiYWNrIGFzIDAuXG5cdFx0XHRcdHRyLnN0eWxlLmhlaWdodCA9IFwiMXB4XCI7XG5cdFx0XHRcdHRyQ2hpbGQuc3R5bGUuaGVpZ2h0ID0gXCI5cHhcIjtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDggQ2hyb21lIDg2K1xuXHRcdFx0XHQvLyBJbiBvdXIgYm9keUJhY2tncm91bmQuaHRtbCBpZnJhbWUsXG5cdFx0XHRcdC8vIGRpc3BsYXkgZm9yIGFsbCBkaXYgZWxlbWVudHMgaXMgc2V0IHRvIFwiaW5saW5lXCIsXG5cdFx0XHRcdC8vIHdoaWNoIGNhdXNlcyBhIHByb2JsZW0gb25seSBpbiBBbmRyb2lkIDggQ2hyb21lIDg2LlxuXHRcdFx0XHQvLyBFbnN1cmluZyB0aGUgZGl2IGlzIGBkaXNwbGF5OiBibG9ja2Bcblx0XHRcdFx0Ly8gZ2V0cyBhcm91bmQgdGhpcyBpc3N1ZS5cblx0XHRcdFx0dHJDaGlsZC5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuXG5cdFx0XHRcdGRvY3VtZW50RWxlbWVudFxuXHRcdFx0XHRcdC5hcHBlbmRDaGlsZCggdGFibGUgKVxuXHRcdFx0XHRcdC5hcHBlbmRDaGlsZCggdHIgKVxuXHRcdFx0XHRcdC5hcHBlbmRDaGlsZCggdHJDaGlsZCApO1xuXG5cdFx0XHRcdHRyU3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggdHIgKTtcblx0XHRcdFx0cmVsaWFibGVUckRpbWVuc2lvbnNWYWwgPSAoIHBhcnNlSW50KCB0clN0eWxlLmhlaWdodCwgMTAgKSArXG5cdFx0XHRcdFx0cGFyc2VJbnQoIHRyU3R5bGUuYm9yZGVyVG9wV2lkdGgsIDEwICkgK1xuXHRcdFx0XHRcdHBhcnNlSW50KCB0clN0eWxlLmJvcmRlckJvdHRvbVdpZHRoLCAxMCApICkgPT09IHRyLm9mZnNldEhlaWdodDtcblxuXHRcdFx0XHRkb2N1bWVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoIHRhYmxlICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVsaWFibGVUckRpbWVuc2lvbnNWYWw7XG5cdFx0fVxuXHR9ICk7XG59ICkoKTtcblxuXG5mdW5jdGlvbiBjdXJDU1MoIGVsZW0sIG5hbWUsIGNvbXB1dGVkICkge1xuXHR2YXIgd2lkdGgsIG1pbldpZHRoLCBtYXhXaWR0aCwgcmV0LFxuXHRcdGlzQ3VzdG9tUHJvcCA9IHJjdXN0b21Qcm9wLnRlc3QoIG5hbWUgKSxcblxuXHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggNTErXG5cdFx0Ly8gUmV0cmlldmluZyBzdHlsZSBiZWZvcmUgY29tcHV0ZWQgc29tZWhvd1xuXHRcdC8vIGZpeGVzIGFuIGlzc3VlIHdpdGggZ2V0dGluZyB3cm9uZyB2YWx1ZXNcblx0XHQvLyBvbiBkZXRhY2hlZCBlbGVtZW50c1xuXHRcdHN0eWxlID0gZWxlbS5zdHlsZTtcblxuXHRjb21wdXRlZCA9IGNvbXB1dGVkIHx8IGdldFN0eWxlcyggZWxlbSApO1xuXG5cdC8vIGdldFByb3BlcnR5VmFsdWUgaXMgbmVlZGVkIGZvcjpcblx0Ly8gICAuY3NzKCdmaWx0ZXInKSAoSUUgOSBvbmx5LCB0cmFjLTEyNTM3KVxuXHQvLyAgIC5jc3MoJy0tY3VzdG9tUHJvcGVydHkpIChnaC0zMTQ0KVxuXHRpZiAoIGNvbXB1dGVkICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTErXG5cdFx0Ly8gSUUgb25seSBzdXBwb3J0cyBgXCJmbG9hdFwiYCBpbiBgZ2V0UHJvcGVydHlWYWx1ZWA7IGluIGNvbXB1dGVkIHN0eWxlc1xuXHRcdC8vIGl0J3Mgb25seSBhdmFpbGFibGUgYXMgYFwiY3NzRmxvYXRcImAuIFdlIG5vIGxvbmdlciBtb2RpZnkgcHJvcGVydGllc1xuXHRcdC8vIHNlbnQgdG8gYC5jc3MoKWAgYXBhcnQgZnJvbSBjYW1lbENhc2luZywgc28gd2UgbmVlZCB0byBjaGVjayBib3RoLlxuXHRcdC8vIE5vcm1hbGx5LCB0aGlzIHdvdWxkIGNyZWF0ZSBkaWZmZXJlbmNlIGluIGJlaGF2aW9yOiBpZlxuXHRcdC8vIGBnZXRQcm9wZXJ0eVZhbHVlYCByZXR1cm5zIGFuIGVtcHR5IHN0cmluZywgdGhlIHZhbHVlIHJldHVybmVkXG5cdFx0Ly8gYnkgYC5jc3MoKWAgd291bGQgYmUgYHVuZGVmaW5lZGAuIFRoaXMgaXMgdXN1YWxseSB0aGUgY2FzZSBmb3Jcblx0XHQvLyBkaXNjb25uZWN0ZWQgZWxlbWVudHMuIEhvd2V2ZXIsIGluIElFIGV2ZW4gZGlzY29ubmVjdGVkIGVsZW1lbnRzXG5cdFx0Ly8gd2l0aCBubyBzdHlsZXMgcmV0dXJuIGBcIm5vbmVcImAgZm9yIGBnZXRQcm9wZXJ0eVZhbHVlKCBcImZsb2F0XCIgKWBcblx0XHRyZXQgPSBjb21wdXRlZC5nZXRQcm9wZXJ0eVZhbHVlKCBuYW1lICkgfHwgY29tcHV0ZWRbIG5hbWUgXTtcblxuXHRcdGlmICggaXNDdXN0b21Qcm9wICYmIHJldCApIHtcblxuXHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCAxMDUrLCBDaHJvbWUgPD0xMDUrXG5cdFx0XHQvLyBTcGVjIHJlcXVpcmVzIHRyaW1taW5nIHdoaXRlc3BhY2UgZm9yIGN1c3RvbSBwcm9wZXJ0aWVzIChnaC00OTI2KS5cblx0XHRcdC8vIEZpcmVmb3ggb25seSB0cmltcyBsZWFkaW5nIHdoaXRlc3BhY2UuIENocm9tZSBqdXN0IGNvbGxhcHNlc1xuXHRcdFx0Ly8gYm90aCBsZWFkaW5nICYgdHJhaWxpbmcgd2hpdGVzcGFjZSB0byBhIHNpbmdsZSBzcGFjZS5cblx0XHRcdC8vXG5cdFx0XHQvLyBGYWxsIGJhY2sgdG8gYHVuZGVmaW5lZGAgaWYgZW1wdHkgc3RyaW5nIHJldHVybmVkLlxuXHRcdFx0Ly8gVGhpcyBjb2xsYXBzZXMgYSBtaXNzaW5nIGRlZmluaXRpb24gd2l0aCBwcm9wZXJ0eSBkZWZpbmVkXG5cdFx0XHQvLyBhbmQgc2V0IHRvIGFuIGVtcHR5IHN0cmluZyBidXQgdGhlcmUncyBubyBzdGFuZGFyZCBBUElcblx0XHRcdC8vIGFsbG93aW5nIHVzIHRvIGRpZmZlcmVudGlhdGUgdGhlbSB3aXRob3V0IGEgcGVyZm9ybWFuY2UgcGVuYWx0eVxuXHRcdFx0Ly8gYW5kIHJldHVybmluZyBgdW5kZWZpbmVkYCBhbGlnbnMgd2l0aCBvbGRlciBqUXVlcnkuXG5cdFx0XHQvL1xuXHRcdFx0Ly8gcnRyaW1DU1MgdHJlYXRzIFUrMDAwRCBDQVJSSUFHRSBSRVRVUk4gYW5kIFUrMDAwQyBGT1JNIEZFRURcblx0XHRcdC8vIGFzIHdoaXRlc3BhY2Ugd2hpbGUgQ1NTIGRvZXMgbm90LCBidXQgdGhpcyBpcyBub3QgYSBwcm9ibGVtXG5cdFx0XHQvLyBiZWNhdXNlIENTUyBwcmVwcm9jZXNzaW5nIHJlcGxhY2VzIHRoZW0gd2l0aCBVKzAwMEEgTElORSBGRUVEXG5cdFx0XHQvLyAod2hpY2ggKmlzKiBDU1Mgd2hpdGVzcGFjZSlcblx0XHRcdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9jc3Mtc3ludGF4LTMvI2lucHV0LXByZXByb2Nlc3Npbmdcblx0XHRcdHJldCA9IHJldC5yZXBsYWNlKCBydHJpbUNTUywgXCIkMVwiICkgfHwgdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdGlmICggcmV0ID09PSBcIlwiICYmICFpc0F0dGFjaGVkKCBlbGVtICkgKSB7XG5cdFx0XHRyZXQgPSBqUXVlcnkuc3R5bGUoIGVsZW0sIG5hbW
1UgKTtcblx0XHR9XG5cblx0XHQvLyBBIHRyaWJ1dGUgdG8gdGhlIFwiYXdlc29tZSBoYWNrIGJ5IERlYW4gRWR3YXJkc1wiXG5cdFx0Ly8gQW5kcm9pZCBCcm93c2VyIHJldHVybnMgcGVyY2VudGFnZSBmb3Igc29tZSB2YWx1ZXMsXG5cdFx0Ly8gYnV0IHdpZHRoIHNlZW1zIHRvIGJlIHJlbGlhYmx5IHBpeGVscy5cblx0XHQvLyBUaGlzIGlzIGFnYWluc3QgdGhlIENTU09NIGRyYWZ0IHNwZWM6XG5cdFx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNyZXNvbHZlZC12YWx1ZXNcblx0XHRpZiAoICFzdXBwb3J0LnBpeGVsQm94U3R5bGVzKCkgJiYgcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJib3hTdHlsZS50ZXN0KCBuYW1lICkgKSB7XG5cblx0XHRcdC8vIFJlbWVtYmVyIHRoZSBvcmlnaW5hbCB2YWx1ZXNcblx0XHRcdHdpZHRoID0gc3R5bGUud2lkdGg7XG5cdFx0XHRtaW5XaWR0aCA9IHN0eWxlLm1pbldpZHRoO1xuXHRcdFx0bWF4V2lkdGggPSBzdHlsZS5tYXhXaWR0aDtcblxuXHRcdFx0Ly8gUHV0IGluIHRoZSBuZXcgdmFsdWVzIHRvIGdldCBhIGNvbXB1dGVkIHZhbHVlIG91dFxuXHRcdFx0c3R5bGUubWluV2lkdGggPSBzdHlsZS5tYXhXaWR0aCA9IHN0eWxlLndpZHRoID0gcmV0O1xuXHRcdFx0cmV0ID0gY29tcHV0ZWQud2lkdGg7XG5cblx0XHRcdC8vIFJldmVydCB0aGUgY2hhbmdlZCB2YWx1ZXNcblx0XHRcdHN0eWxlLndpZHRoID0gd2lkdGg7XG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IG1pbldpZHRoO1xuXHRcdFx0c3R5bGUubWF4V2lkdGggPSBtYXhXaWR0aDtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcmV0ICE9PSB1bmRlZmluZWQgP1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHRcdC8vIElFIHJldHVybnMgekluZGV4IHZhbHVlIGFzIGFuIGludGVnZXIuXG5cdFx0cmV0ICsgXCJcIiA6XG5cdFx0cmV0O1xufVxuXG5cbmZ1bmN0aW9uIGFkZEdldEhvb2tJZiggY29uZGl0aW9uRm4sIGhvb2tGbiApIHtcblxuXHQvLyBEZWZpbmUgdGhlIGhvb2ssIHdlJ2xsIGNoZWNrIG9uIHRoZSBmaXJzdCBydW4gaWYgaXQncyByZWFsbHkgbmVlZGVkLlxuXHRyZXR1cm4ge1xuXHRcdGdldDogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGNvbmRpdGlvbkZuKCkgKSB7XG5cblx0XHRcdFx0Ly8gSG9vayBub3QgbmVlZGVkIChvciBpdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgaXQgZHVlXG5cdFx0XHRcdC8vIHRvIG1pc3NpbmcgZGVwZW5kZW5jeSksIHJlbW92ZSBpdC5cblx0XHRcdFx0ZGVsZXRlIHRoaXMuZ2V0O1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIEhvb2sgbmVlZGVkOyByZWRlZmluZSBpdCBzbyB0aGF0IHRoZSBzdXBwb3J0IHRlc3QgaXMgbm90IGV4ZWN1dGVkIGFnYWluLlxuXHRcdFx0cmV0dXJuICggdGhpcy5nZXQgPSBob29rRm4gKS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fVxuXHR9O1xufVxuXG5cbnZhciBjc3NQcmVmaXhlcyA9IFsgXCJXZWJraXRcIiwgXCJNb3pcIiwgXCJtc1wiIF0sXG5cdGVtcHR5U3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkuc3R5bGUsXG5cdHZlbmRvclByb3BzID0ge307XG5cbi8vIFJldHVybiBhIHZlbmRvci1wcmVmaXhlZCBwcm9wZXJ0eSBvciB1bmRlZmluZWRcbmZ1bmN0aW9uIHZlbmRvclByb3BOYW1lKCBuYW1lICkge1xuXG5cdC8vIENoZWNrIGZvciB2ZW5kb3IgcHJlZml4ZWQgbmFtZXNcblx0dmFyIGNhcE5hbWUgPSBuYW1lWyAwIF0udG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoIDEgKSxcblx0XHRpID0gY3NzUHJlZml4ZXMubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdG5hbWUgPSBjc3NQcmVmaXhlc1sgaSBdICsgY2FwTmFtZTtcblx0XHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRcdHJldHVybiBuYW1lO1xuXHRcdH1cblx0fVxufVxuXG4vLyBSZXR1cm4gYSBwb3RlbnRpYWxseS1tYXBwZWQgalF1ZXJ5LmNzc1Byb3BzIG9yIHZlbmRvciBwcmVmaXhlZCBwcm9wZXJ0eVxuZnVuY3Rpb24gZmluYWxQcm9wTmFtZSggbmFtZSApIHtcblx0dmFyIGZpbmFsID0galF1ZXJ5LmNzc1Byb3BzWyBuYW1lIF0gfHwgdmVuZG9yUHJvcHNbIG5hbWUgXTtcblxuXHRpZiAoIGZpbmFsICkge1xuXHRcdHJldHVybiBmaW5hbDtcblx0fVxuXHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRyZXR1cm4gbmFtZTtcblx0fVxuXHRyZXR1cm4gdmVuZG9yUHJvcHNbIG5hbWUgXSA9IHZlbmRvclByb3BOYW1lKCBuYW1lICkgfHwgbmFtZTtcbn1cblxuXG52YXJcblxuXHQvLyBTd2FwcGFibGUgaWYgZGlzcGxheSBpcyBub25lIG9yIHN0YXJ0cyB3aXRoIHRhYmxlXG5cdC8vIGV4Y2VwdCBcInRhYmxlXCIsIFwidGFibGUtY2VsbFwiLCBvciBcInRhYmxlLWNhcHRpb25cIlxuXHQvLyBTZWUgaGVyZSBmb3IgZGlzcGxheSB2YWx1ZXM6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvQ1NTL2Rpc3BsYXlcblx0cmRpc3BsYXlzd2FwID0gL14obm9uZXx0YWJsZSg/IS1jW2VhXSkuKykvLFxuXHRjc3NTaG93ID0geyBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLCB2aXNpYmlsaXR5OiBcImhpZGRlblwiLCBkaXNwbGF5OiBcImJsb2NrXCIgfSxcblx0Y3NzTm9ybWFsVHJhbnNmb3JtID0ge1xuXHRcdGxldHRlclNwYWNpbmc6IFwiMFwiLFxuXHRcdGZvbnRXZWlnaHQ6IFwiNDAwXCJcblx0fTtcblxuZnVuY3Rpb24gc2V0UG9zaXRpdmVOdW1iZXIoIF9lbGVtLCB2YWx1ZSwgc3VidHJhY3QgKSB7XG5cblx0Ly8gQW55IHJlbGF0aXZlICgrLy0pIHZhbHVlcyBoYXZlIGFscmVhZHkgYmVlblxuXHQvLyBub3JtYWxpemVkIGF0IHRoaXMgcG9pbnRcblx0dmFyIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICk7XG5cdHJldHVybiBtYXRjaGVzID9cblxuXHRcdC8vIEd1YXJkIGFnYWluc3QgdW5kZWZpbmVkIFwic3VidHJhY3RcIiwgZS5nLiwgd2hlbiB1c2VkIGFzIGluIGNzc0hvb2tzXG5cdFx0TWF0aC5tYXgoIDAsIG1hdGNoZXNbIDIgXSAtICggc3VidHJhY3QgfHwgMCApICkgKyAoIG1hdGNoZXNbIDMgXSB8fCBcInB4XCIgKSA6XG5cdFx0dmFsdWU7XG59XG5cbmZ1bmN0aW9uIGJveE1vZGVsQWRqdXN0bWVudCggZWxlbSwgZGltZW5zaW9uLCBib3gsIGlzQm9yZGVyQm94LCBzdHlsZXMsIGNvbXB1dGVkVmFsICkge1xuXHR2YXIgaSA9IGRpbWVuc2lvbiA9PT0gXCJ3aWR0aFwiID8gMSA6IDAsXG5cdFx0ZXh0cmEgP
1SAwLFxuXHRcdGRlbHRhID0gMCxcblx0XHRtYXJnaW5EZWx0YSA9IDA7XG5cblx0Ly8gQWRqdXN0bWVudCBtYXkgbm90IGJlIG5lY2Vzc2FyeVxuXHRpZiAoIGJveCA9PT0gKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApICkge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cblx0Zm9yICggOyBpIDwgNDsgaSArPSAyICkge1xuXG5cdFx0Ly8gQm90aCBib3ggbW9kZWxzIGV4Y2x1ZGUgbWFyZ2luXG5cdFx0Ly8gQ291bnQgbWFyZ2luIGRlbHRhIHNlcGFyYXRlbHkgdG8gb25seSBhZGQgaXQgYWZ0ZXIgc2Nyb2xsIGd1dHRlciBhZGp1c3RtZW50LlxuXHRcdC8vIFRoaXMgaXMgbmVlZGVkIHRvIG1ha2UgbmVnYXRpdmUgbWFyZ2lucyB3b3JrIHdpdGggYG91dGVySGVpZ2h0KCB0cnVlIClgIChnaC0zOTgyKS5cblx0XHRpZiAoIGJveCA9PT0gXCJtYXJnaW5cIiApIHtcblx0XHRcdG1hcmdpbkRlbHRhICs9IGpRdWVyeS5jc3MoIGVsZW0sIGJveCArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHR9XG5cblx0XHQvLyBJZiB3ZSBnZXQgaGVyZSB3aXRoIGEgY29udGVudC1ib3gsIHdlJ3JlIHNlZWtpbmcgXCJwYWRkaW5nXCIgb3IgXCJib3JkZXJcIiBvciBcIm1hcmdpblwiXG5cdFx0aWYgKCAhaXNCb3JkZXJCb3ggKSB7XG5cblx0XHRcdC8vIEFkZCBwYWRkaW5nXG5cdFx0XHRkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblxuXHRcdFx0Ly8gRm9yIFwiYm9yZGVyXCIgb3IgXCJtYXJnaW5cIiwgYWRkIGJvcmRlclxuXHRcdFx0aWYgKCBib3ggIT09IFwicGFkZGluZ1wiICkge1xuXHRcdFx0XHRkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXG5cdFx0XHQvLyBCdXQgc3RpbGwga2VlcCB0cmFjayBvZiBpdCBvdGhlcndpc2Vcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGV4dHJhICs9IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm9yZGVyXCIgKyBjc3NFeHBhbmRbIGkgXSArIFwiV2lkdGhcIiwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cblx0XHQvLyBJZiB3ZSBnZXQgaGVyZSB3aXRoIGEgYm9yZGVyLWJveCAoY29udGVudCArIHBhZGRpbmcgKyBib3JkZXIpLCB3ZSdyZSBzZWVraW5nIFwiY29udGVudFwiIG9yXG5cdFx0Ly8gXCJwYWRkaW5nXCIgb3IgXCJtYXJnaW5cIlxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIEZvciBcImNvbnRlbnRcIiwgc3VidHJhY3QgcGFkZGluZ1xuXHRcdFx0aWYgKCBib3ggPT09IFwiY29udGVudFwiICkge1xuXHRcdFx0XHRkZWx0YSAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRm9yIFwiY29udGVudFwiIG9yIFwicGFkZGluZ1wiLCBzdWJ0cmFjdCBib3JkZXJcblx0XHRcdGlmICggYm94ICE9PSBcIm1hcmdpblwiICkge1xuXHRcdFx0XHRkZWx0YSAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIEFjY291bnQgZm9yIHBvc2l0aXZlIGNvbnRlbnQtYm94IHNjcm9sbCBndXR0ZXIgd2hlbiByZXF1ZXN0ZWQgYnkgcHJvdmlkaW5nIGNvbXB1dGVkVmFsXG5cdGlmICggIWlzQm9yZGVyQm94ICYmIGNvbXB1dGVkVmFsID49IDAgKSB7XG5cblx0XHQvLyBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgaXMgYSByb3VuZGVkIHN1bSBvZiBjb250ZW50LCBwYWRkaW5nLCBzY3JvbGwgZ3V0dGVyLCBhbmQgYm9yZGVyXG5cdFx0Ly8gQXNzdW1pbmcgaW50ZWdlciBzY3JvbGwgZ3V0dGVyLCBzdWJ0cmFjdCB0aGUgcmVzdCBhbmQgcm91bmQgZG93blxuXHRcdGRlbHRhICs9IE1hdGgubWF4KCAwLCBNYXRoLmNlaWwoXG5cdFx0XHRlbGVtWyBcIm9mZnNldFwiICsgZGltZW5zaW9uWyAwIF0udG9VcHBlckNhc2UoKSArIGRpbWVuc2lvbi5zbGljZSggMSApIF0gLVxuXHRcdFx0Y29tcHV0ZWRWYWwgLVxuXHRcdFx0ZGVsdGEgLVxuXHRcdFx0ZXh0cmEgLVxuXHRcdFx0MC41XG5cblx0XHQvLyBJZiBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgaXMgdW5rbm93biwgdGhlbiB3ZSBjYW4ndCBkZXRlcm1pbmUgY29udGVudC1ib3ggc2Nyb2xsIGd1dHRlclxuXHRcdC8vIFVzZSBhbiBleHBsaWNpdCB6ZXJvIHRvIGF2b2lkIE5hTiAoZ2gtMzk2NClcblx0XHQpICkgfHwgMDtcblx0fVxuXG5cdHJldHVybiBkZWx0YSArIG1hcmdpbkRlbHRhO1xufVxuXG5mdW5jdGlvbiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBkaW1lbnNpb24sIGV4dHJhICkge1xuXG5cdC8vIFN0YXJ0IHdpdGggY29tcHV0ZWQgc3R5bGVcblx0dmFyIHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApLFxuXG5cdFx0Ly8gVG8gYXZvaWQgZm9yY2luZyBhIHJlZmxvdywgb25seSBmZXRjaCBib3hTaXppbmcgaWYgd2UgbmVlZCBpdCAoZ2gtNDMyMikuXG5cdFx0Ly8gRmFrZSBjb250ZW50LWJveCB1bnRpbCB3ZSBrbm93IGl0J3MgbmVlZGVkIHRvIGtub3cgdGhlIHRydWUgdmFsdWUuXG5cdFx0Ym94U2l6aW5nTmVlZGVkID0gIXN1cHBvcnQuYm94U2l6aW5nUmVsaWFibGUoKSB8fCBleHRyYSxcblx0XHRpc0JvcmRlckJveCA9IGJveFNpemluZ05lZWRlZCAmJlxuXHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIixcblx0XHR2YWx1ZUlzQm9yZGVyQm94ID0gaXNCb3JkZXJCb3gsXG5cblx0XHR2YWwgPSBjdXJDU1MoIGVsZW0sIGRpbWVuc2lvbiwgc3R5bGVzICksXG5cdFx0b2Zmc2V0UHJvcCA9IFwib2Zmc2V0XCIgKyBkaW1lbnNpb25bIDAgXS50b1VwcGVyQ2FzZSgpICsgZGltZW5zaW9uLnNsaWNlKCAxICk7XG5cblx0Ly8gU3VwcG9ydDogRmlyZWZveCA8PTU0XG5cdC8vIFJldHVybiBhIGNvbmZvdW5kaW5nIG5vbi1waXhlbCB2YWx1ZSBvciBmZWlnbiBpZ25vcmFuY2UsIGFzIGFwcHJvcHJpYXRlLlxuXHRpZiAoIHJudW1ub25weC50ZXN0KCB2YWwgKSApIHtcblx0XHRpZiAoICFleHRyYSApIHtcblx0XHRcdHJldHVybi
1B2YWw7XG5cdFx0fVxuXHRcdHZhbCA9IFwiYXV0b1wiO1xuXHR9XG5cblxuXHQvLyBTdXBwb3J0OiBJRSA5IC0gMTEgb25seVxuXHQvLyBVc2Ugb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IGZvciB3aGVuIGJveCBzaXppbmcgaXMgdW5yZWxpYWJsZS5cblx0Ly8gSW4gdGhvc2UgY2FzZXMsIHRoZSBjb21wdXRlZCB2YWx1ZSBjYW4gYmUgdHJ1c3RlZCB0byBiZSBib3JkZXItYm94LlxuXHRpZiAoICggIXN1cHBvcnQuYm94U2l6aW5nUmVsaWFibGUoKSAmJiBpc0JvcmRlckJveCB8fFxuXG5cdFx0Ly8gU3VwcG9ydDogSUUgMTAgLSAxMSssIEVkZ2UgMTUgLSAxOCtcblx0XHQvLyBJRS9FZGdlIG1pc3JlcG9ydCBgZ2V0Q29tcHV0ZWRTdHlsZWAgb2YgdGFibGUgcm93cyB3aXRoIHdpZHRoL2hlaWdodFxuXHRcdC8vIHNldCBpbiBDU1Mgd2hpbGUgYG9mZnNldCpgIHByb3BlcnRpZXMgcmVwb3J0IGNvcnJlY3QgdmFsdWVzLlxuXHRcdC8vIEludGVyZXN0aW5nbHksIGluIHNvbWUgY2FzZXMgSUUgOSBkb2Vzbid0IHN1ZmZlciBmcm9tIHRoaXMgaXNzdWUuXG5cdFx0IXN1cHBvcnQucmVsaWFibGVUckRpbWVuc2lvbnMoKSAmJiBub2RlTmFtZSggZWxlbSwgXCJ0clwiICkgfHxcblxuXHRcdC8vIEZhbGwgYmFjayB0byBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgd2hlbiB2YWx1ZSBpcyBcImF1dG9cIlxuXHRcdC8vIFRoaXMgaGFwcGVucyBmb3IgaW5saW5lIGVsZW1lbnRzIHdpdGggbm8gZXhwbGljaXQgc2V0dGluZyAoZ2gtMzU3MSlcblx0XHR2YWwgPT09IFwiYXV0b1wiIHx8XG5cblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4xIC0gNC4zIG9ubHlcblx0XHQvLyBBbHNvIHVzZSBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgZm9yIG1pc3JlcG9ydGVkIGlubGluZSBkaW1lbnNpb25zIChnaC0zNjAyKVxuXHRcdCFwYXJzZUZsb2F0KCB2YWwgKSAmJiBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImlubGluZVwiICkgJiZcblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGUgZWxlbWVudCBpcyB2aXNpYmxlICYgY29ubmVjdGVkXG5cdFx0ZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCApIHtcblxuXHRcdGlzQm9yZGVyQm94ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIjtcblxuXHRcdC8vIFdoZXJlIGF2YWlsYWJsZSwgb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IGFwcHJveGltYXRlIGJvcmRlciBib3ggZGltZW5zaW9ucy5cblx0XHQvLyBXaGVyZSBub3QgYXZhaWxhYmxlIChlLmcuLCBTVkcpLCBhc3N1bWUgdW5yZWxpYWJsZSBib3gtc2l6aW5nIGFuZCBpbnRlcnByZXQgdGhlXG5cdFx0Ly8gcmV0cmlldmVkIHZhbHVlIGFzIGEgY29udGVudCBib3ggZGltZW5zaW9uLlxuXHRcdHZhbHVlSXNCb3JkZXJCb3ggPSBvZmZzZXRQcm9wIGluIGVsZW07XG5cdFx0aWYgKCB2YWx1ZUlzQm9yZGVyQm94ICkge1xuXHRcdFx0dmFsID0gZWxlbVsgb2Zmc2V0UHJvcCBdO1xuXHRcdH1cblx0fVxuXG5cdC8vIE5vcm1hbGl6ZSBcIlwiIGFuZCBhdXRvXG5cdHZhbCA9IHBhcnNlRmxvYXQoIHZhbCApIHx8IDA7XG5cblx0Ly8gQWRqdXN0IGZvciB0aGUgZWxlbWVudCdzIGJveCBtb2RlbFxuXHRyZXR1cm4gKCB2YWwgK1xuXHRcdGJveE1vZGVsQWRqdXN0bWVudChcblx0XHRcdGVsZW0sXG5cdFx0XHRkaW1lbnNpb24sXG5cdFx0XHRleHRyYSB8fCAoIGlzQm9yZGVyQm94ID8gXCJib3JkZXJcIiA6IFwiY29udGVudFwiICksXG5cdFx0XHR2YWx1ZUlzQm9yZGVyQm94LFxuXHRcdFx0c3R5bGVzLFxuXG5cdFx0XHQvLyBQcm92aWRlIHRoZSBjdXJyZW50IGNvbXB1dGVkIHNpemUgdG8gcmVxdWVzdCBzY3JvbGwgZ3V0dGVyIGNhbGN1bGF0aW9uIChnaC0zNTg5KVxuXHRcdFx0dmFsXG5cdFx0KVxuXHQpICsgXCJweFwiO1xufVxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cblx0Ly8gQWRkIGluIHN0eWxlIHByb3BlcnR5IGhvb2tzIGZvciBvdmVycmlkaW5nIHRoZSBkZWZhdWx0XG5cdC8vIGJlaGF2aW9yIG9mIGdldHRpbmcgYW5kIHNldHRpbmcgYSBzdHlsZSBwcm9wZXJ0eVxuXHRjc3NIb29rczoge1xuXHRcdG9wYWNpdHk6IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkge1xuXHRcdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXG5cdFx0XHRcdFx0Ly8gV2Ugc2hvdWxkIGFsd2F5cyBnZXQgYSBudW1iZXIgYmFjayBmcm9tIG9wYWNpdHlcblx0XHRcdFx0XHR2YXIgcmV0ID0gY3VyQ1NTKCBlbGVtLCBcIm9wYWNpdHlcIiApO1xuXHRcdFx0XHRcdHJldHVybiByZXQgPT09IFwiXCIgPyBcIjFcIiA6IHJldDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvLyBEb24ndCBhdXRvbWF0aWNhbGx5IGFkZCBcInB4XCIgdG8gdGhlc2UgcG9zc2libHktdW5pdGxlc3MgcHJvcGVydGllc1xuXHRjc3NOdW1iZXI6IHtcblx0XHRhbmltYXRpb25JdGVyYXRpb25Db3VudDogdHJ1ZSxcblx0XHRhc3BlY3RSYXRpbzogdHJ1ZSxcblx0XHRib3JkZXJJbWFnZVNsaWNlOiB0cnVlLFxuXHRcdGNvbHVtbkNvdW50OiB0cnVlLFxuXHRcdGZsZXhHcm93OiB0cnVlLFxuXHRcdGZsZXhTaHJpbms6IHRydWUsXG5cdFx0Zm9udFdlaWdodDogdHJ1ZSxcblx0XHRncmlkQXJlYTogdHJ1ZSxcblx0XHRncmlkQ29sdW1uOiB0cnVlLFxuXHRcdGdyaWRDb2x1bW5FbmQ6IHRydWUsXG5cdFx0Z3JpZENvbHVtblN0YXJ0OiB0cnVlLFxuXHRcdGdyaWRSb3c6IHRydWUsXG5cdFx0Z3JpZFJvd0VuZDogdHJ1ZSxcblx0XHRncmlkUm93U3RhcnQ6IHRydWUsXG5cdFx0bGluZUhlaWdodDogdHJ1ZSxcblx0XHRvcGFjaXR5OiB0cnVlLFxuXHRcdG9yZGVyOiB0cnVlLFxuXHRcdG9ycGhhbnM6IHRydWUsXG5cdFx0c2NhbGU6IHRydWUsXG5cdFx0d2lkb3dzOiB0cnVlLFxuXHRcdHpJbmRleDogdHJ1ZSxcblx0XHR6b29tOiB0cnVlLFxuXG5cdFx0Ly8gU1ZHLXJlbGF0ZWRcblx0XHRmaWxsT3BhY2l0eTogdHJ1ZSxcblx0XHRmbG9vZE9wYWNpdHk6IHRydWUsXG5cdFx0c3RvcE9wYWNpdHk6IHRydWUsXG5cdFx0c3Ryb2tlTWl0ZXJsaW1pdDogdHJ1ZSxcblx0XHRzdHJva2VPcGFjaXR5OiB0cnVlXG5cdH0sXG5cblx0Ly8gQWRkIGluIHByb3BlcnRpZXMgd2hvc2UgbmFtZXMgeW91IHdpc2ggdG8gZml4IGJlZm9yZVxuXHQvLyBzZXR0aW5nIG9yIGdldHRpbmcgdGhlIHZhbHVlXG5cdGNzc1Byb3BzOiB7fSxcblxuXHQvLyBHZXQgYW5kIHNldCB0aGUgc3R5bGUgcHJvcGVydHkgb24gYSBET00gTm9kZVxuXHRzdHlsZTogZnVuY3Rpb24oIGVsZW0sIG5hbW
1UsIHZhbHVlLCBleHRyYSApIHtcblxuXHRcdC8vIERvbid0IHNldCBzdHlsZXMgb24gdGV4dCBhbmQgY29tbWVudCBub2Rlc1xuXHRcdGlmICggIWVsZW0gfHwgZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4IHx8ICFlbGVtLnN0eWxlICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZVxuXHRcdHZhciByZXQsIHR5cGUsIGhvb2tzLFxuXHRcdFx0b3JpZ05hbWUgPSBjYW1lbENhc2UoIG5hbWUgKSxcblx0XHRcdGlzQ3VzdG9tUHJvcCA9IHJjdXN0b21Qcm9wLnRlc3QoIG5hbWUgKSxcblx0XHRcdHN0eWxlID0gZWxlbS5zdHlsZTtcblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZS4gV2UgZG9uJ3Rcblx0XHQvLyB3YW50IHRvIHF1ZXJ5IHRoZSB2YWx1ZSBpZiBpdCBpcyBhIENTUyBjdXN0b20gcHJvcGVydHlcblx0XHQvLyBzaW5jZSB0aGV5IGFyZSB1c2VyLWRlZmluZWQuXG5cdFx0aWYgKCAhaXNDdXN0b21Qcm9wICkge1xuXHRcdFx0bmFtZSA9IGZpbmFsUHJvcE5hbWUoIG9yaWdOYW1lICk7XG5cdFx0fVxuXG5cdFx0Ly8gR2V0cyBob29rIGZvciB0aGUgcHJlZml4ZWQgdmVyc2lvbiwgdGhlbiB1bnByZWZpeGVkIHZlcnNpb25cblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdIHx8IGpRdWVyeS5jc3NIb29rc1sgb3JpZ05hbWUgXTtcblxuXHRcdC8vIENoZWNrIGlmIHdlJ3JlIHNldHRpbmcgYSB2YWx1ZVxuXHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHR5cGUgPSB0eXBlb2YgdmFsdWU7XG5cblx0XHRcdC8vIENvbnZlcnQgXCIrPVwiIG9yIFwiLT1cIiB0byByZWxhdGl2ZSBudW1iZXJzICh0cmFjLTczNDUpXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwic3RyaW5nXCIgJiYgKCByZXQgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICkgKSAmJiByZXRbIDEgXSApIHtcblx0XHRcdFx0dmFsdWUgPSBhZGp1c3RDU1MoIGVsZW0sIG5hbWUsIHJldCApO1xuXG5cdFx0XHRcdC8vIEZpeGVzIGJ1ZyB0cmFjLTkyMzdcblx0XHRcdFx0dHlwZSA9IFwibnVtYmVyXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG51bGwgYW5kIE5hTiB2YWx1ZXMgYXJlbid0IHNldCAodHJhYy03MTE2KVxuXHRcdFx0aWYgKCB2YWx1ZSA9PSBudWxsIHx8IHZhbHVlICE9PSB2YWx1ZSApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiBhIG51bWJlciB3YXMgcGFzc2VkIGluLCBhZGQgdGhlIHVuaXQgKGV4Y2VwdCBmb3IgY2VydGFpbiBDU1MgcHJvcGVydGllcylcblx0XHRcdC8vIFRoZSBpc0N1c3RvbVByb3AgY2hlY2sgY2FuIGJlIHJlbW92ZWQgaW4galF1ZXJ5IDQuMCB3aGVuIHdlIG9ubHkgYXV0by1hcHBlbmRcblx0XHRcdC8vIFwicHhcIiB0byBhIGZldyBoYXJkY29kZWQgdmFsdWVzLlxuXHRcdFx0aWYgKCB0eXBlID09PSBcIm51bWJlclwiICYmICFpc0N1c3RvbVByb3AgKSB7XG5cdFx0XHRcdHZhbHVlICs9IHJldCAmJiByZXRbIDMgXSB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIG9yaWdOYW1lIF0gPyBcIlwiIDogXCJweFwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGJhY2tncm91bmQtKiBwcm9wcyBhZmZlY3Qgb3JpZ2luYWwgY2xvbmUncyB2YWx1ZXNcblx0XHRcdGlmICggIXN1cHBvcnQuY2xlYXJDbG9uZVN0eWxlICYmIHZhbHVlID09PSBcIlwiICYmIG5hbWUuaW5kZXhPZiggXCJiYWNrZ3JvdW5kXCIgKSA9PT0gMCApIHtcblx0XHRcdFx0c3R5bGVbIG5hbWUgXSA9IFwiaW5oZXJpdFwiO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkLCB1c2UgdGhhdCB2YWx1ZSwgb3RoZXJ3aXNlIGp1c3Qgc2V0IHRoZSBzcGVjaWZpZWQgdmFsdWVcblx0XHRcdGlmICggIWhvb2tzIHx8ICEoIFwic2V0XCIgaW4gaG9va3MgKSB8fFxuXHRcdFx0XHQoIHZhbHVlID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0aWYgKCBpc0N1c3RvbVByb3AgKSB7XG5cdFx0XHRcdFx0c3R5bGUuc2V0UHJvcGVydHkoIG5hbWUsIHZhbHVlICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c3R5bGVbIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgbm9uLWNvbXB1dGVkIHZhbHVlIGZyb20gdGhlcmVcblx0XHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJlxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLmdldCggZWxlbSwgZmFsc2UsIGV4dHJhICkgKSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE90aGVyd2lzZSBqdXN0IGdldCB0aGUgdmFsdWUgZnJvbSB0aGUgc3R5bGUgb2JqZWN0XG5cdFx0XHRyZXR1cm4gc3R5bGVbIG5hbWUgXTtcblx0XHR9XG5cdH0sXG5cblx0Y3NzOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZXh0cmEsIHN0eWxlcyApIHtcblx0XHR2YXIgdmFsLCBudW0sIGhvb2tzLFxuXHRcdFx0b3JpZ05hbWUgPSBjYW1lbENhc2UoIG5hbWUgKSxcblx0XHRcdGlzQ3VzdG9tUHJvcCA9IHJjdXN0b21Qcm9wLnRlc3QoIG5hbWUgKTtcblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZS4gV2UgZG9uJ3Rcblx0XHQvLyB3YW50IHRvIG1vZGlmeSB0aGUgdmFsdWUgaWYgaXQgaXMgYSBDU1MgY3VzdG9tIHByb3BlcnR5XG5cdFx0Ly8gc2luY2UgdGhleSBhcmUgdXNlci1kZWZpbmVkLlxuXHRcdGlmICggIWlzQ3VzdG9tUHJvcCApIHtcblx0XHRcdG5hbWUgPSBmaW5hbFByb3BOYW1lKCBvcmlnTmFtZSApO1xuXHRcdH1cblxuXHRcdC8vIFRyeSBwcmVmaXhlZCBuYW1lIGZvbGxvd2VkIGJ5IHRoZSB1bnByZWZpeGVkIG5hbWVcblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdIHx8IGpRdWVyeS5jc3NIb29rc1sgb3JpZ05hbWUgXTtcblxuXHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQgZ2V0IHRoZSBjb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXG5cdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICkge1xuXHRcdFx0dmFsID0gaG9va3MuZ2V0KCBlbGVtLCB0cnVlLCBleHRyYSApO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyd2lzZSwgaWYgYSB3YXkgdG8gZ2V0IHRoZSBjb21wdXRlZCB2YWx1ZSBleGlzdHMsIHVzZSB0aGF0XG5cdFx0aWYgKCB2YWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHZhbCA9IGN1ckNTUyggZWxlbSwgbmFtZSwgc3R5bGVzICk7XG5cdFx0fVxuXG5cdFx0Ly8gQ29udmVydCBcIm5vcm1hbFwiIHRvIGNvbXB1dGVkIHZhbHVlXG5cdFx0aWYgKCB2YWwgPT09IFwibm9ybWFsXCIgJiYgbmFtZSBpbiBjc3NOb3JtYWxUcmFuc2Zvcm0gKSB7XG5cdFx0XHR2YWwgPSBjc3NOb3JtYWxUcmFuc2Zvcm1bIG5hbWUgXTtcblx0XHR9XG5cblx0XHQvLyBNYWtlIG51bWVyaWMgaWYgZm9yY2VkIG9yIGEgcXVhbGlmaWVyIHdhcyBwcm92aWRlZCBhbmQgdmFsIGxvb2tzIG51bWVyaWNcblx0XHRpZiAoIGV4dHJhID09PSBcIlwiIHx8IGV4dHJhICkge1xuXHRcdFx0bnVtID0gcGFyc2VGbG9hdCggdmFsICk7XG5cdFx0XHRyZXR1cm4gZXh0cmEgPT09IHRydWUgfHwgaXNGaW5pdGUoIG51bSApID8gbnVtIHx8IDAgOiB2YWw7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHZhbDtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCggWyBcImhlaWdodFwiLCBcIndpZHRoXCIgXSwgZnVuY3Rpb24oIF9pLCBkaW1lbnNpb24gKSB7XG5cdGpRdWVyeS5jc3NIb29rc1sgZGltZW5zaW9uIF0gPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQsIGV4dHJhICkge1xuXHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblxuXHRcdFx0XHQvLyBDZXJ0YWluIGVsZW1lbnRzIGNhbiBoYXZlIGRpbWVuc2lvbiBpbmZvIGlmIHdlIGludmlzaWJse
1SBzaG93IHRoZW1cblx0XHRcdFx0Ly8gYnV0IGl0IG11c3QgaGF2ZSBhIGN1cnJlbnQgZGlzcGxheSBzdHlsZSB0aGF0IHdvdWxkIGJlbmVmaXRcblx0XHRcdFx0cmV0dXJuIHJkaXNwbGF5c3dhcC50ZXN0KCBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApICkgJiZcblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA4K1xuXHRcdFx0XHRcdC8vIFRhYmxlIGNvbHVtbnMgaW4gU2FmYXJpIGhhdmUgbm9uLXplcm8gb2Zmc2V0V2lkdGggJiB6ZXJvXG5cdFx0XHRcdFx0Ly8gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGggdW5sZXNzIGRpc3BsYXkgaXMgY2hhbmdlZC5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHlcblx0XHRcdFx0XHQvLyBSdW5uaW5nIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBvbiBhIGRpc2Nvbm5lY3RlZCBub2RlXG5cdFx0XHRcdFx0Ly8gaW4gSUUgdGhyb3dzIGFuIGVycm9yLlxuXHRcdFx0XHRcdCggIWVsZW0uZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggfHwgIWVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGggKSA/XG5cdFx0XHRcdFx0c3dhcCggZWxlbSwgY3NzU2hvdywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZ2V0V2lkdGhPckhlaWdodCggZWxlbSwgZGltZW5zaW9uLCBleHRyYSApO1xuXHRcdFx0XHRcdH0gKSA6XG5cdFx0XHRcdFx0Z2V0V2lkdGhPckhlaWdodCggZWxlbSwgZGltZW5zaW9uLCBleHRyYSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSB7XG5cdFx0XHR2YXIgbWF0Y2hlcyxcblx0XHRcdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICksXG5cblx0XHRcdFx0Ly8gT25seSByZWFkIHN0eWxlcy5wb3NpdGlvbiBpZiB0aGUgdGVzdCBoYXMgYSBjaGFuY2UgdG8gZmFpbFxuXHRcdFx0XHQvLyB0byBhdm9pZCBmb3JjaW5nIGEgcmVmbG93LlxuXHRcdFx0XHRzY3JvbGxib3hTaXplQnVnZ3kgPSAhc3VwcG9ydC5zY3JvbGxib3hTaXplKCkgJiZcblx0XHRcdFx0XHRzdHlsZXMucG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIixcblxuXHRcdFx0XHQvLyBUbyBhdm9pZCBmb3JjaW5nIGEgcmVmbG93LCBvbmx5IGZldGNoIGJveFNpemluZyBpZiB3ZSBuZWVkIGl0IChnaC0zOTkxKVxuXHRcdFx0XHRib3hTaXppbmdOZWVkZWQgPSBzY3JvbGxib3hTaXplQnVnZ3kgfHwgZXh0cmEsXG5cdFx0XHRcdGlzQm9yZGVyQm94ID0gYm94U2l6aW5nTmVlZGVkICYmXG5cdFx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIixcblx0XHRcdFx0c3VidHJhY3QgPSBleHRyYSA/XG5cdFx0XHRcdFx0Ym94TW9kZWxBZGp1c3RtZW50KFxuXHRcdFx0XHRcdFx0ZWxlbSxcblx0XHRcdFx0XHRcdGRpbWVuc2lvbixcblx0XHRcdFx0XHRcdGV4dHJhLFxuXHRcdFx0XHRcdFx0aXNCb3JkZXJCb3gsXG5cdFx0XHRcdFx0XHRzdHlsZXNcblx0XHRcdFx0XHQpIDpcblx0XHRcdFx0XHQwO1xuXG5cdFx0XHQvLyBBY2NvdW50IGZvciB1bnJlbGlhYmxlIGJvcmRlci1ib3ggZGltZW5zaW9ucyBieSBjb21wYXJpbmcgb2Zmc2V0KiB0byBjb21wdXRlZCBhbmRcblx0XHRcdC8vIGZha2luZyBhIGNvbnRlbnQtYm94IHRvIGdldCBib3JkZXIgYW5kIHBhZGRpbmcgKGdoLTM2OTkpXG5cdFx0XHRpZiAoIGlzQm9yZGVyQm94ICYmIHNjcm9sbGJveFNpemVCdWdneSApIHtcblx0XHRcdFx0c3VidHJhY3QgLT0gTWF0aC5jZWlsKFxuXHRcdFx0XHRcdGVsZW1bIFwib2Zmc2V0XCIgKyBkaW1lbnNpb25bIDAgXS50b1VwcGVyQ2FzZSgpICsgZGltZW5zaW9uLnNsaWNlKCAxICkgXSAtXG5cdFx0XHRcdFx0cGFyc2VGbG9hdCggc3R5bGVzWyBkaW1lbnNpb24gXSApIC1cblx0XHRcdFx0XHRib3hNb2RlbEFkanVzdG1lbnQoIGVsZW0sIGRpbWVuc2lvbiwgXCJib3JkZXJcIiwgZmFsc2UsIHN0eWxlcyApIC1cblx0XHRcdFx0XHQwLjVcblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udmVydCB0byBwaXhlbHMgaWYgdmFsdWUgYWRqdXN0bWVudCBpcyBuZWVkZWRcblx0XHRcdGlmICggc3VidHJhY3QgJiYgKCBtYXRjaGVzID0gcmNzc051bS5leGVjKCB2YWx1ZSApICkgJiZcblx0XHRcdFx0KCBtYXRjaGVzWyAzIF0gfHwgXCJweFwiICkgIT09IFwicHhcIiApIHtcblxuXHRcdFx0XHRlbGVtLnN0eWxlWyBkaW1lbnNpb24gXSA9IHZhbHVlO1xuXHRcdFx0XHR2YWx1ZSA9IGpRdWVyeS5jc3MoIGVsZW0sIGRpbWVuc2lvbiApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBzdWJ0cmFjdCApO1xuXHRcdH1cblx0fTtcbn0gKTtcblxualF1ZXJ5LmNzc0hvb2tzLm1hcmdpbkxlZnQgPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucmVsaWFibGVNYXJnaW5MZWZ0LFxuXHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdHJldHVybiAoIHBhcnNlRmxvYXQoIGN1ckNTUyggZWxlbSwgXCJtYXJnaW5MZWZ0XCIgKSApIHx8XG5cdFx0XHRcdGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCAtXG5cdFx0XHRcdFx0c3dhcCggZWxlbSwgeyBtYXJnaW5MZWZ0OiAwIH0sIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdDtcblx0XHRcdFx0XHR9IClcblx0XHRcdCkgKyBcInB4XCI7XG5cdFx0fVxuXHR9XG4pO1xuXG4vLyBUaGVzZSBob29rcyBhcmUgdXNlZCBieSBhbmltYXRlIHRvIGV4cGFuZCBwcm9wZXJ0aWVzXG5qUXVlcnkuZWFjaCgge1xuXHRtYXJnaW46IFwiXCIsXG5cdHBhZGRpbmc6IFwiXCIsXG5cdGJvcmRlcjogXCJXaWR0aFwiXG59LCBmdW5jdGlvbiggcHJlZml4LCBzdWZmaXggKSB7XG5cdGpRdWVyeS5jc3NIb29rc1sgcHJlZml4ICsgc3VmZml4IF0gPSB7XG5cdFx0ZXhwYW5kOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHR2YXIgaSA9IDAsXG5cdFx0XHRcdGV4cGFuZGVkID0ge30sXG5cblx0XHRcdFx0Ly8gQXNzdW1lcyBhIHNpbmdsZSBudW1iZXIgaWYgbm90IGEgc3RyaW5nXG5cdFx0XHRcdHBhcnRzID0gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gdmFsdWUuc3BsaXQoIFwiIFwiICkgOiBbIHZhbHVlIF07XG5cblx0XHRcdGZvciAoIDsgaSA8IDQ7IGkrKyApIHtcblx0XHRcdFx0ZXhwYW5kZWRbIHByZWZpeCArIGNz
1c0V4cGFuZFsgaSBdICsgc3VmZml4IF0gPVxuXHRcdFx0XHRcdHBhcnRzWyBpIF0gfHwgcGFydHNbIGkgLSAyIF0gfHwgcGFydHNbIDAgXTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGV4cGFuZGVkO1xuXHRcdH1cblx0fTtcblxuXHRpZiAoIHByZWZpeCAhPT0gXCJtYXJnaW5cIiApIHtcblx0XHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdLnNldCA9IHNldFBvc2l0aXZlTnVtYmVyO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0Y3NzOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdFx0dmFyIHN0eWxlcywgbGVuLFxuXHRcdFx0XHRtYXAgPSB7fSxcblx0XHRcdFx0aSA9IDA7XG5cblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSggbmFtZSApICkge1xuXHRcdFx0XHRzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKTtcblx0XHRcdFx0bGVuID0gbmFtZS5sZW5ndGg7XG5cblx0XHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdFx0bWFwWyBuYW1lWyBpIF0gXSA9IGpRdWVyeS5jc3MoIGVsZW0sIG5hbWVbIGkgXSwgZmFsc2UsIHN0eWxlcyApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIG1hcDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIG5hbWUsIHZhbHVlICkgOlxuXHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBuYW1lICk7XG5cdFx0fSwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XG5cdH1cbn0gKTtcblxuXG5mdW5jdGlvbiBUd2VlbiggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcgKSB7XG5cdHJldHVybiBuZXcgVHdlZW4ucHJvdG90eXBlLmluaXQoIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nICk7XG59XG5qUXVlcnkuVHdlZW4gPSBUd2VlbjtcblxuVHdlZW4ucHJvdG90eXBlID0ge1xuXHRjb25zdHJ1Y3RvcjogVHdlZW4sXG5cdGluaXQ6IGZ1bmN0aW9uKCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZywgdW5pdCApIHtcblx0XHR0aGlzLmVsZW0gPSBlbGVtO1xuXHRcdHRoaXMucHJvcCA9IHByb3A7XG5cdFx0dGhpcy5lYXNpbmcgPSBlYXNpbmcgfHwgalF1ZXJ5LmVhc2luZy5fZGVmYXVsdDtcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXHRcdHRoaXMuc3RhcnQgPSB0aGlzLm5vdyA9IHRoaXMuY3VyKCk7XG5cdFx0dGhpcy5lbmQgPSBlbmQ7XG5cdFx0dGhpcy51bml0ID0gdW5pdCB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/IFwiXCIgOiBcInB4XCIgKTtcblx0fSxcblx0Y3VyOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgaG9va3MgPSBUd2Vlbi5wcm9wSG9va3NbIHRoaXMucHJvcCBdO1xuXG5cdFx0cmV0dXJuIGhvb2tzICYmIGhvb2tzLmdldCA/XG5cdFx0XHRob29rcy5nZXQoIHRoaXMgKSA6XG5cdFx0XHRUd2Vlbi5wcm9wSG9va3MuX2RlZmF1bHQuZ2V0KCB0aGlzICk7XG5cdH0sXG5cdHJ1bjogZnVuY3Rpb24oIHBlcmNlbnQgKSB7XG5cdFx0dmFyIGVhc2VkLFxuXHRcdFx0aG9va3MgPSBUd2Vlbi5wcm9wSG9va3NbIHRoaXMucHJvcCBdO1xuXG5cdFx0aWYgKCB0aGlzLm9wdGlvbnMuZHVyYXRpb24gKSB7XG5cdFx0XHR0aGlzLnBvcyA9IGVhc2VkID0galF1ZXJ5LmVhc2luZ1sgdGhpcy5lYXNpbmcgXShcblx0XHRcdFx0cGVyY2VudCwgdGhpcy5vcHRpb25zLmR1cmF0aW9uICogcGVyY2VudCwgMCwgMSwgdGhpcy5vcHRpb25zLmR1cmF0aW9uXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnBvcyA9IGVhc2VkID0gcGVyY2VudDtcblx0XHR9XG5cdFx0dGhpcy5ub3cgPSAoIHRoaXMuZW5kIC0gdGhpcy5zdGFydCApICogZWFzZWQgKyB0aGlzLnN0YXJ0O1xuXG5cdFx0aWYgKCB0aGlzLm9wdGlvbnMuc3RlcCApIHtcblx0XHRcdHRoaXMub3B0aW9ucy5zdGVwLmNhbGwoIHRoaXMuZWxlbSwgdGhpcy5ub3csIHRoaXMgKTtcblx0XHR9XG5cblx0XHRpZiAoIGhvb2tzICYmIGhvb2tzLnNldCApIHtcblx0XHRcdGhvb2tzLnNldCggdGhpcyApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRUd2Vlbi5wcm9wSG9va3MuX2RlZmF1bHQuc2V0KCB0aGlzICk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG59O1xuXG5Ud2Vlbi5wcm90b3R5cGUuaW5pdC5wcm90b3R5cGUgPSBUd2Vlbi5wcm90b3R5cGU7XG5cblR3ZWVuLnByb3BIb29rcyA9IHtcblx0X2RlZmF1bHQ6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcblx0XHRcdHZhciByZXN1bHQ7XG5cblx0XHRcdC8vIFVzZSBhIHByb3BlcnR5IG9uIHRoZSBlbGVtZW50IGRpcmVjdGx5IHdoZW4gaXQgaXMgbm90IGEgRE9NIGVsZW1lbnQsXG5cdFx0XHQvLyBvciB3aGVuIHRoZXJlIGlzIG5vIG1hdGNoaW5nIHN0eWxlIHByb3BlcnR5IHRoYXQgZXhpc3RzLlxuXHRcdFx0aWYgKCB0d2Vlbi5lbGVtLm5vZGVUeXBlICE9PSAxIHx8XG5cdFx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSAhPSBudWxsICYmIHR3ZWVuLmVsZW0uc3R5bGVbIHR3ZWVuLnByb3AgXSA9PSBudWxsICkge1xuXHRcdFx0XHRyZXR1cm4gdHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBQYXNzaW5nIGFuIGVtcHR5IHN0cmluZyBhcyBhIDNyZCBwYXJhbWV0ZXIgdG8gLmNzcyB3aWxsIGF1dG9tYXRpY2FsbHlcblx0XHRcdC8vIGF0dGVtcHQgYSBwYXJzZUZsb2F0IGFuZCBmYWxsYmFjayB0byBhIHN0cmluZyBpZiB0aGUgcGFyc2UgZmFpbHMuXG5cdFx0XHQvLyBTaW1wbGUgdmFsdWVzIHN1Y2ggYXMgXCIxMHB4XCIgYXJlIHBhcnNlZCB0byBGbG9hdDtcblx0XHRcdC8vIGNvbXBsZXggdmFsdWVzIHN1Y2ggYXMgXCJyb3RhdGUoMXJhZClcIiBhcmUgcmV0dXJuZWQgYXMtaXMuXG5cdFx0XHRyZXN1bHQgPSBqUXVlcnkuY3NzKCB0d2Vlbi5lbGVtLCB0d2Vlbi5wcm9wLCBcIlwiICk7XG5cblx0XHRcdC8vIEVtcHR5IHN0cmluZ3MsIG51bGwsIHVuZGVmaW5lZCBhbmQgXCJhdXRvXCIgYXJlIGNvbnZlcnRlZCB0byAwLlxuXHRcdFx0cmV0dXJuICFyZXN1bHQgfHwgcmVzdWx0ID09PSBcImF1dG9cIiA/IDAgOiByZXN1bHQ7XG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcblxuXHRcdFx0Ly8gVXNlIHN0ZXAgaG9vayBmb3IgYmFjayBjb21wYXQuXG5cdFx0XHQvLyBVc2UgY3NzSG9vayBpZiBpdHMgdGhlcmUuXG5cdFx0XHQvLyBVc2UgLnN0eWxlIGlmIGF2YWlsYWJsZSBhbmQgdXNlIHBsYWluIHByb3BlcnRpZXMgd2hlcmUgYXZhaWxhYmxlLlxuXHRcdFx0aWYgKCBqUXVlcnkuZnguc3RlcFsgdHdlZW4ucHJv
1cCBdICkge1xuXHRcdFx0XHRqUXVlcnkuZnguc3RlcFsgdHdlZW4ucHJvcCBdKCB0d2VlbiApO1xuXHRcdFx0fSBlbHNlIGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAoXG5cdFx0XHRcdGpRdWVyeS5jc3NIb29rc1sgdHdlZW4ucHJvcCBdIHx8XG5cdFx0XHRcdFx0dHdlZW4uZWxlbS5zdHlsZVsgZmluYWxQcm9wTmFtZSggdHdlZW4ucHJvcCApIF0gIT0gbnVsbCApICkge1xuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIHR3ZWVuLm5vdyArIHR3ZWVuLnVuaXQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbi8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG4vLyBQYW5pYyBiYXNlZCBhcHByb2FjaCB0byBzZXR0aW5nIHRoaW5ncyBvbiBkaXNjb25uZWN0ZWQgbm9kZXNcblR3ZWVuLnByb3BIb29rcy5zY3JvbGxUb3AgPSBUd2Vlbi5wcm9wSG9va3Muc2Nyb2xsTGVmdCA9IHtcblx0c2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cdFx0aWYgKCB0d2Vlbi5lbGVtLm5vZGVUeXBlICYmIHR3ZWVuLmVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdztcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5lYXNpbmcgPSB7XG5cdGxpbmVhcjogZnVuY3Rpb24oIHAgKSB7XG5cdFx0cmV0dXJuIHA7XG5cdH0sXG5cdHN3aW5nOiBmdW5jdGlvbiggcCApIHtcblx0XHRyZXR1cm4gMC41IC0gTWF0aC5jb3MoIHAgKiBNYXRoLlBJICkgLyAyO1xuXHR9LFxuXHRfZGVmYXVsdDogXCJzd2luZ1wiXG59O1xuXG5qUXVlcnkuZnggPSBUd2Vlbi5wcm90b3R5cGUuaW5pdDtcblxuLy8gQmFjayBjb21wYXQgPDEuOCBleHRlbnNpb24gcG9pbnRcbmpRdWVyeS5meC5zdGVwID0ge307XG5cblxuXG5cbnZhclxuXHRmeE5vdywgaW5Qcm9ncmVzcyxcblx0cmZ4dHlwZXMgPSAvXig/OnRvZ2dsZXxzaG93fGhpZGUpJC8sXG5cdHJydW4gPSAvcXVldWVIb29rcyQvO1xuXG5mdW5jdGlvbiBzY2hlZHVsZSgpIHtcblx0aWYgKCBpblByb2dyZXNzICkge1xuXHRcdGlmICggZG9jdW1lbnQuaGlkZGVuID09PSBmYWxzZSAmJiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lICkge1xuXHRcdFx0d2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSggc2NoZWR1bGUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0d2luZG93LnNldFRpbWVvdXQoIHNjaGVkdWxlLCBqUXVlcnkuZnguaW50ZXJ2YWwgKTtcblx0XHR9XG5cblx0XHRqUXVlcnkuZngudGljaygpO1xuXHR9XG59XG5cbi8vIEFuaW1hdGlvbnMgY3JlYXRlZCBzeW5jaHJvbm91c2x5IHdpbGwgcnVuIHN5bmNocm9ub3VzbHlcbmZ1bmN0aW9uIGNyZWF0ZUZ4Tm93KCkge1xuXHR3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0ZnhOb3cgPSB1bmRlZmluZWQ7XG5cdH0gKTtcblx0cmV0dXJuICggZnhOb3cgPSBEYXRlLm5vdygpICk7XG59XG5cbi8vIEdlbmVyYXRlIHBhcmFtZXRlcnMgdG8gY3JlYXRlIGEgc3RhbmRhcmQgYW5pbWF0aW9uXG5mdW5jdGlvbiBnZW5GeCggdHlwZSwgaW5jbHVkZVdpZHRoICkge1xuXHR2YXIgd2hpY2gsXG5cdFx0aSA9IDAsXG5cdFx0YXR0cnMgPSB7IGhlaWdodDogdHlwZSB9O1xuXG5cdC8vIElmIHdlIGluY2x1ZGUgd2lkdGgsIHN0ZXAgdmFsdWUgaXMgMSB0byBkbyBhbGwgY3NzRXhwYW5kIHZhbHVlcyxcblx0Ly8gb3RoZXJ3aXNlIHN0ZXAgdmFsdWUgaXMgMiB0byBza2lwIG92ZXIgTGVmdCBhbmQgUmlnaHRcblx0aW5jbHVkZVdpZHRoID0gaW5jbHVkZVdpZHRoID8gMSA6IDA7XG5cdGZvciAoIDsgaSA8IDQ7IGkgKz0gMiAtIGluY2x1ZGVXaWR0aCApIHtcblx0XHR3aGljaCA9IGNzc0V4cGFuZFsgaSBdO1xuXHRcdGF0dHJzWyBcIm1hcmdpblwiICsgd2hpY2ggXSA9IGF0dHJzWyBcInBhZGRpbmdcIiArIHdoaWNoIF0gPSB0eXBlO1xuXHR9XG5cblx0aWYgKCBpbmNsdWRlV2lkdGggKSB7XG5cdFx0YXR0cnMub3BhY2l0eSA9IGF0dHJzLndpZHRoID0gdHlwZTtcblx0fVxuXG5cdHJldHVybiBhdHRycztcbn1cblxuZnVuY3Rpb24gY3JlYXRlVHdlZW4oIHZhbHVlLCBwcm9wLCBhbmltYXRpb24gKSB7XG5cdHZhciB0d2Vlbixcblx0XHRjb2xsZWN0aW9uID0gKCBBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSB8fCBbXSApLmNvbmNhdCggQW5pbWF0aW9uLnR3ZWVuZXJzWyBcIipcIiBdICksXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xuXHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdGlmICggKCB0d2VlbiA9IGNvbGxlY3Rpb25bIGluZGV4IF0uY2FsbCggYW5pbWF0aW9uLCBwcm9wLCB2YWx1ZSApICkgKSB7XG5cblx0XHRcdC8vIFdlJ3JlIGRvbmUgd2l0aCB0aGlzIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gdHdlZW47XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRQcmVmaWx0ZXIoIGVsZW0sIHByb3BzLCBvcHRzICkge1xuXHR2YXIgcHJvcCwgdmFsdWUsIHRvZ2dsZSwgaG9va3MsIG9sZGZpcmUsIHByb3BUd2VlbiwgcmVzdG9yZURpc3BsYXksIGRpc3BsYXksXG5cdFx0aXNCb3ggPSBcIndpZHRoXCIgaW4gcHJvcHMgfHwgXCJoZWlnaHRcIiBpbiBwcm9wcyxcblx0XHRhbmltID0gdGhpcyxcblx0XHRvcmlnID0ge30sXG5cdFx0c3R5bGUgPSBlbGVtLnN0eWxlLFxuXHRcdGhpZGRlbiA9IGVsZW0ubm9kZVR5cGUgJiYgaXNIaWRkZW5XaXRoaW5UcmVlKCBlbGVtICksXG5cdFx0ZGF0YVNob3cgPSBkYXRhUHJpdi5nZXQoIGVsZW0sIFwiZnhzaG93XCIgKTtcblxuXHQvLyBRdWV1ZS1za2lwcGluZyBhbmltYXRpb25zIGhpamFjayB0aGUgZnggaG9va3Ncblx0aWYgKCAhb3B0cy5xdWV1ZSApIHtcblx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgXCJmeFwiICk7XG5cdFx0aWYgKCBob29rcy51bnF1ZXVlZCA9PSBudWxsICkge1xuXHRcdFx0aG9va3MudW5xdWV1ZWQgPSAwO1xuXHRcdFx0b2xkZmlyZSA9IGhvb2tzLmVtcHR5LmZpcmU7XG5cdFx0XHRob29rcy5lbXB0eS5maXJlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggIWhvb2tzLnVucXVldWVkICkge1xuXHRcdFx0XHRcdG9sZGZpcmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHR9XG5cdFx0aG9va3MudW5xdWV1ZWQrKztcblxuXHRcdGFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gRW5zdXJlIHRoZSBjb21wbGV0ZSBoYW5kbGVyIGlzIGNhbGxlZCBiZWZvcmUgdGhpcyBjb21wbGV0ZXNcblx0XHRcdGFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0aG9va3MudW5xdWV1ZWQtLTtcblx0XHRcdFx0aWYgKCAhalF1ZXJ5LnF1ZXVlKCBlbGVtLCBcImZ4XCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdFx0aG9va3MuZW1wdHkuZmlyZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gRGV0ZWN0IHNob3cvaGlkZSBhbmltYXRpb25zXG5cdGZvciAoIHByb3AgaW4gcHJvcHMgKSB7XG5cdFx0dmFsdWUgPSBwcm9wc1sgcHJvcCBdO1xuXHRcdGlmICggcmZ4dHlwZXMudGVzdCggdmFsdWUgKSApIHtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgcHJvcCBdO1xuXHRcdFx0dG9nZ2xlID0gdG9nZ2xlIHx8IHZhbHVlID09PSBcInRvZ2dsZVwiO1xuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gKCBoaWRkZW4gPyBcImhpZGVcIiA6IFwic2hvd1wiICkgKSB7XG5cblx0XHRcdFx0Ly8gUHJldGVuZCB0byBiZSBoaWRkZW4gaWYgdGhpcyBpcyBh
1IFwic2hvd1wiIGFuZFxuXHRcdFx0XHQvLyB0aGVyZSBpcyBzdGlsbCBkYXRhIGZyb20gYSBzdG9wcGVkIHNob3cvaGlkZVxuXHRcdFx0XHRpZiAoIHZhbHVlID09PSBcInNob3dcIiAmJiBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0aGlkZGVuID0gdHJ1ZTtcblxuXHRcdFx0XHQvLyBJZ25vcmUgYWxsIG90aGVyIG5vLW9wIHNob3cvaGlkZSBkYXRhXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdG9yaWdbIHByb3AgXSA9IGRhdGFTaG93ICYmIGRhdGFTaG93WyBwcm9wIF0gfHwgalF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gQmFpbCBvdXQgaWYgdGhpcyBpcyBhIG5vLW9wIGxpa2UgLmhpZGUoKS5oaWRlKClcblx0cHJvcFR3ZWVuID0gIWpRdWVyeS5pc0VtcHR5T2JqZWN0KCBwcm9wcyApO1xuXHRpZiAoICFwcm9wVHdlZW4gJiYgalF1ZXJ5LmlzRW1wdHlPYmplY3QoIG9yaWcgKSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBSZXN0cmljdCBcIm92ZXJmbG93XCIgYW5kIFwiZGlzcGxheVwiIHN0eWxlcyBkdXJpbmcgYm94IGFuaW1hdGlvbnNcblx0aWYgKCBpc0JveCAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEsIEVkZ2UgMTIgLSAxNVxuXHRcdC8vIFJlY29yZCBhbGwgMyBvdmVyZmxvdyBhdHRyaWJ1dGVzIGJlY2F1c2UgSUUgZG9lcyBub3QgaW5mZXIgdGhlIHNob3J0aGFuZFxuXHRcdC8vIGZyb20gaWRlbnRpY2FsbHktdmFsdWVkIG92ZXJmbG93WCBhbmQgb3ZlcmZsb3dZIGFuZCBFZGdlIGp1c3QgbWlycm9yc1xuXHRcdC8vIHRoZSBvdmVyZmxvd1ggdmFsdWUgdGhlcmUuXG5cdFx0b3B0cy5vdmVyZmxvdyA9IFsgc3R5bGUub3ZlcmZsb3csIHN0eWxlLm92ZXJmbG93WCwgc3R5bGUub3ZlcmZsb3dZIF07XG5cblx0XHQvLyBJZGVudGlmeSBhIGRpc3BsYXkgdHlwZSwgcHJlZmVycmluZyBvbGQgc2hvdy9oaWRlIGRhdGEgb3ZlciB0aGUgQ1NTIGNhc2NhZGVcblx0XHRyZXN0b3JlRGlzcGxheSA9IGRhdGFTaG93ICYmIGRhdGFTaG93LmRpc3BsYXk7XG5cdFx0aWYgKCByZXN0b3JlRGlzcGxheSA9PSBudWxsICkge1xuXHRcdFx0cmVzdG9yZURpc3BsYXkgPSBkYXRhUHJpdi5nZXQoIGVsZW0sIFwiZGlzcGxheVwiICk7XG5cdFx0fVxuXHRcdGRpc3BsYXkgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApO1xuXHRcdGlmICggZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XG5cdFx0XHRpZiAoIHJlc3RvcmVEaXNwbGF5ICkge1xuXHRcdFx0XHRkaXNwbGF5ID0gcmVzdG9yZURpc3BsYXk7XG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIEdldCBub25lbXB0eSB2YWx1ZShzKSBieSB0ZW1wb3JhcmlseSBmb3JjaW5nIHZpc2liaWxpdHlcblx0XHRcdFx0c2hvd0hpZGUoIFsgZWxlbSBdLCB0cnVlICk7XG5cdFx0XHRcdHJlc3RvcmVEaXNwbGF5ID0gZWxlbS5zdHlsZS5kaXNwbGF5IHx8IHJlc3RvcmVEaXNwbGF5O1xuXHRcdFx0XHRkaXNwbGF5ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKTtcblx0XHRcdFx0c2hvd0hpZGUoIFsgZWxlbSBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQW5pbWF0ZSBpbmxpbmUgZWxlbWVudHMgYXMgaW5saW5lLWJsb2NrXG5cdFx0aWYgKCBkaXNwbGF5ID09PSBcImlubGluZVwiIHx8IGRpc3BsYXkgPT09IFwiaW5saW5lLWJsb2NrXCIgJiYgcmVzdG9yZURpc3BsYXkgIT0gbnVsbCApIHtcblx0XHRcdGlmICggalF1ZXJ5LmNzcyggZWxlbSwgXCJmbG9hdFwiICkgPT09IFwibm9uZVwiICkge1xuXG5cdFx0XHRcdC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIGRpc3BsYXkgdmFsdWUgYXQgdGhlIGVuZCBvZiBwdXJlIHNob3cvaGlkZSBhbmltYXRpb25zXG5cdFx0XHRcdGlmICggIXByb3BUd2VlbiApIHtcblx0XHRcdFx0XHRhbmltLmRvbmUoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0c3R5bGUuZGlzcGxheSA9IHJlc3RvcmVEaXNwbGF5O1xuXHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHRpZiAoIHJlc3RvcmVEaXNwbGF5ID09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRkaXNwbGF5ID0gc3R5bGUuZGlzcGxheTtcblx0XHRcdFx0XHRcdHJlc3RvcmVEaXNwbGF5ID0gZGlzcGxheSA9PT0gXCJub25lXCIgPyBcIlwiIDogZGlzcGxheTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0c3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCI7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0aWYgKCBvcHRzLm92ZXJmbG93ICkge1xuXHRcdHN0eWxlLm92ZXJmbG93ID0gXCJoaWRkZW5cIjtcblx0XHRhbmltLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cdFx0XHRzdHlsZS5vdmVyZmxvdyA9IG9wdHMub3ZlcmZsb3dbIDAgXTtcblx0XHRcdHN0eWxlLm92ZXJmbG93WCA9IG9wdHMub3ZlcmZsb3dbIDEgXTtcblx0XHRcdHN0eWxlLm92ZXJmbG93WSA9IG9wdHMub3ZlcmZsb3dbIDIgXTtcblx0XHR9ICk7XG5cdH1cblxuXHQvLyBJbXBsZW1lbnQgc2hvdy9oaWRlIGFuaW1hdGlvbnNcblx0cHJvcFR3ZWVuID0gZmFsc2U7XG5cdGZvciAoIHByb3AgaW4gb3JpZyApIHtcblxuXHRcdC8vIEdlbmVyYWwgc2hvdy9oaWRlIHNldHVwIGZvciB0aGlzIGVsZW1lbnQgYW5pbWF0aW9uXG5cdFx0aWYgKCAhcHJvcFR3ZWVuICkge1xuXHRcdFx0aWYgKCBkYXRhU2hvdyApIHtcblx0XHRcdFx0aWYgKCBcImhpZGRlblwiIGluIGRhdGFTaG93ICkge1xuXHRcdFx0XHRcdGhpZGRlbiA9IGRhdGFTaG93LmhpZGRlbjtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGF0YVNob3cgPSBkYXRhUHJpdi5hY2Nlc3MoIGVsZW0sIFwiZnhzaG93XCIsIHsgZGlzcGxheTogcmVzdG9yZURpc3BsYXkgfSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdG9yZSBoaWRkZW4vdmlzaWJsZSBmb3IgdG9nZ2xlIHNvIGAuc3RvcCgpLnRvZ2dsZSgpYCBcInJldmVyc2VzXCJcblx0XHRcdGlmICggdG9nZ2xlICkge1xuXHRcdFx0XHRkYXRhU2hvdy5oaWRkZW4gPSAhaGlkZGVuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTaG93IGVsZW1lbnRzIGJlZm9yZSBhbmltYXRpbmcgdGhlbV
1xuXHRcdFx0aWYgKCBoaWRkZW4gKSB7XG5cdFx0XHRcdHNob3dIaWRlKCBbIGVsZW0gXSwgdHJ1ZSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBuby1sb29wLWZ1bmMgKi9cblxuXHRcdFx0YW5pbS5kb25lKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvKiBlc2xpbnQtZW5hYmxlIG5vLWxvb3AtZnVuYyAqL1xuXG5cdFx0XHRcdC8vIFRoZSBmaW5hbCBzdGVwIG9mIGEgXCJoaWRlXCIgYW5pbWF0aW9uIGlzIGFjdHVhbGx5IGhpZGluZyB0aGUgZWxlbWVudFxuXHRcdFx0XHRpZiAoICFoaWRkZW4gKSB7XG5cdFx0XHRcdFx0c2hvd0hpZGUoIFsgZWxlbSBdICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBlbGVtLCBcImZ4c2hvd1wiICk7XG5cdFx0XHRcdGZvciAoIHByb3AgaW4gb3JpZyApIHtcblx0XHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AsIG9yaWdbIHByb3AgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0Ly8gUGVyLXByb3BlcnR5IHNldHVwXG5cdFx0cHJvcFR3ZWVuID0gY3JlYXRlVHdlZW4oIGhpZGRlbiA/IGRhdGFTaG93WyBwcm9wIF0gOiAwLCBwcm9wLCBhbmltICk7XG5cdFx0aWYgKCAhKCBwcm9wIGluIGRhdGFTaG93ICkgKSB7XG5cdFx0XHRkYXRhU2hvd1sgcHJvcCBdID0gcHJvcFR3ZWVuLnN0YXJ0O1xuXHRcdFx0aWYgKCBoaWRkZW4gKSB7XG5cdFx0XHRcdHByb3BUd2Vlbi5lbmQgPSBwcm9wVHdlZW4uc3RhcnQ7XG5cdFx0XHRcdHByb3BUd2Vlbi5zdGFydCA9IDA7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIHByb3BGaWx0ZXIoIHByb3BzLCBzcGVjaWFsRWFzaW5nICkge1xuXHR2YXIgaW5kZXgsIG5hbWUsIGVhc2luZywgdmFsdWUsIGhvb2tzO1xuXG5cdC8vIGNhbWVsQ2FzZSwgc3BlY2lhbEVhc2luZyBhbmQgZXhwYW5kIGNzc0hvb2sgcGFzc1xuXHRmb3IgKCBpbmRleCBpbiBwcm9wcyApIHtcblx0XHRuYW1lID0gY2FtZWxDYXNlKCBpbmRleCApO1xuXHRcdGVhc2luZyA9IHNwZWNpYWxFYXNpbmdbIG5hbWUgXTtcblx0XHR2YWx1ZSA9IHByb3BzWyBpbmRleCBdO1xuXHRcdGlmICggQXJyYXkuaXNBcnJheSggdmFsdWUgKSApIHtcblx0XHRcdGVhc2luZyA9IHZhbHVlWyAxIF07XG5cdFx0XHR2YWx1ZSA9IHByb3BzWyBpbmRleCBdID0gdmFsdWVbIDAgXTtcblx0XHR9XG5cblx0XHRpZiAoIGluZGV4ICE9PSBuYW1lICkge1xuXHRcdFx0cHJvcHNbIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBpbmRleCBdO1xuXHRcdH1cblxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF07XG5cdFx0aWYgKCBob29rcyAmJiBcImV4cGFuZFwiIGluIGhvb2tzICkge1xuXHRcdFx0dmFsdWUgPSBob29rcy5leHBhbmQoIHZhbHVlICk7XG5cdFx0XHRkZWxldGUgcHJvcHNbIG5hbWUgXTtcblxuXHRcdFx0Ly8gTm90IHF1aXRlICQuZXh0ZW5kLCB0aGlzIHdvbid0IG92ZXJ3cml0ZSBleGlzdGluZyBrZXlzLlxuXHRcdFx0Ly8gUmV1c2luZyAnaW5kZXgnIGJlY2F1c2Ugd2UgaGF2ZSB0aGUgY29ycmVjdCBcIm5hbWVcIlxuXHRcdFx0Zm9yICggaW5kZXggaW4gdmFsdWUgKSB7XG5cdFx0XHRcdGlmICggISggaW5kZXggaW4gcHJvcHMgKSApIHtcblx0XHRcdFx0XHRwcm9wc1sgaW5kZXggXSA9IHZhbHVlWyBpbmRleCBdO1xuXHRcdFx0XHRcdHNwZWNpYWxFYXNpbmdbIGluZGV4IF0gPSBlYXNpbmc7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0c3BlY2lhbEVhc2luZ1sgbmFtZSBdID0gZWFzaW5nO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBBbmltYXRpb24oIGVsZW0sIHByb3BlcnRpZXMsIG9wdGlvbnMgKSB7XG5cdHZhciByZXN1bHQsXG5cdFx0c3RvcHBlZCxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gQW5pbWF0aW9uLnByZWZpbHRlcnMubGVuZ3RoLFxuXHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCkuYWx3YXlzKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gRG9uJ3QgbWF0Y2ggZWxlbSBpbiB0aGUgOmFuaW1hdGVkIHNlbGVjdG9yXG5cdFx0XHRkZWxldGUgdGljay5lbGVtO1xuXHRcdH0gKSxcblx0XHR0aWNrID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdHZhciBjdXJyZW50VGltZSA9IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXG5cdFx0XHRcdHJlbWFpbmluZyA9IE1hdGgubWF4KCAwLCBhbmltYXRpb24uc3RhcnRUaW1lICsgYW5pbWF0aW9uLmR1cmF0aW9uIC0gY3VycmVudFRpbWUgKSxcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuMyBvbmx5XG5cdFx0XHRcdC8vIEFyY2hhaWMgY3Jhc2ggYnVnIHdvbid0IGFsbG93IHVzIHRvIHVzZSBgMSAtICggMC41IHx8IDAgKWAgKHRyYWMtMTI0OTcpXG5cdFx0XHRcdHRlbXAgPSByZW1haW5pbmcgLyBhbmltYXRpb24uZHVyYXRpb24gfHwgMCxcblx0XHRcdFx0cGVyY2VudCA9IDEgLSB0ZW1wLFxuXHRcdFx0XHRpbmRleCA9IDAsXG5cdFx0XHRcdGxlbmd0aCA9IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoO1xuXG5cdFx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggcGVyY2VudCApO1xuXHRcdFx0fVxuXG5cdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgcGVyY2VudCwgcmVtYWluaW5nIF0gKTtcblxuXHRcdFx0Ly8gSWYgdGhlcmUncyBtb3JlIHRvIGRvLCB5aWVsZFxuXHRcdFx0aWYgKCBwZXJjZW50IDwgMSAmJiBsZW5ndGggKSB7XG5cdFx0XHRcdHJldHVybiByZW1haW5pbmc7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIHRoaXMgd2FzIGFuIGVtcHR5IGFuaW1hdGlvbiwgc3ludGhlc2l6ZSBhIGZpbmFsIHByb2dyZXNzIG5vdGlmaWNhdGlvblxuXHRcdFx0aWYgKCAhbGVuZ3RoICkge1xuXHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlc29sdmUgdGhlIGFuaW1hdGlvbiBhbmQgcmVwb3J0IGl0cyBjb25jbHVzaW9uXG5cdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24gXSApO
11xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0sXG5cdFx0YW5pbWF0aW9uID0gZGVmZXJyZWQucHJvbWlzZSgge1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdHByb3BzOiBqUXVlcnkuZXh0ZW5kKCB7fSwgcHJvcGVydGllcyApLFxuXHRcdFx0b3B0czogalF1ZXJ5LmV4dGVuZCggdHJ1ZSwge1xuXHRcdFx0XHRzcGVjaWFsRWFzaW5nOiB7fSxcblx0XHRcdFx0ZWFzaW5nOiBqUXVlcnkuZWFzaW5nLl9kZWZhdWx0XG5cdFx0XHR9LCBvcHRpb25zICksXG5cdFx0XHRvcmlnaW5hbFByb3BlcnRpZXM6IHByb3BlcnRpZXMsXG5cdFx0XHRvcmlnaW5hbE9wdGlvbnM6IG9wdGlvbnMsXG5cdFx0XHRzdGFydFRpbWU6IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXG5cdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbixcblx0XHRcdHR3ZWVuczogW10sXG5cdFx0XHRjcmVhdGVUd2VlbjogZnVuY3Rpb24oIHByb3AsIGVuZCApIHtcblx0XHRcdFx0dmFyIHR3ZWVuID0galF1ZXJ5LlR3ZWVuKCBlbGVtLCBhbmltYXRpb24ub3B0cywgcHJvcCwgZW5kLFxuXHRcdFx0XHRcdGFuaW1hdGlvbi5vcHRzLnNwZWNpYWxFYXNpbmdbIHByb3AgXSB8fCBhbmltYXRpb24ub3B0cy5lYXNpbmcgKTtcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVucy5wdXNoKCB0d2VlbiApO1xuXHRcdFx0XHRyZXR1cm4gdHdlZW47XG5cdFx0XHR9LFxuXHRcdFx0c3RvcDogZnVuY3Rpb24oIGdvdG9FbmQgKSB7XG5cdFx0XHRcdHZhciBpbmRleCA9IDAsXG5cblx0XHRcdFx0XHQvLyBJZiB3ZSBhcmUgZ29pbmcgdG8gdGhlIGVuZCwgd2Ugd2FudCB0byBydW4gYWxsIHRoZSB0d2VlbnNcblx0XHRcdFx0XHQvLyBvdGhlcndpc2Ugd2Ugc2tpcCB0aGlzIHBhcnRcblx0XHRcdFx0XHRsZW5ndGggPSBnb3RvRW5kID8gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGggOiAwO1xuXHRcdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdFx0c3RvcHBlZCA9IHRydWU7XG5cdFx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVuc1sgaW5kZXggXS5ydW4oIDEgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFJlc29sdmUgd2hlbiB3ZSBwbGF5ZWQgdGhlIGxhc3QgZnJhbWU7IG90aGVyd2lzZSwgcmVqZWN0XG5cdFx0XHRcdGlmICggZ290b0VuZCApIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7XG5cdFx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBnb3RvRW5kIF0gKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9XG5cdFx0fSApLFxuXHRcdHByb3BzID0gYW5pbWF0aW9uLnByb3BzO1xuXG5cdHByb3BGaWx0ZXIoIHByb3BzLCBhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nICk7XG5cblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRyZXN1bHQgPSBBbmltYXRpb24ucHJlZmlsdGVyc1sgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIGVsZW0sIHByb3BzLCBhbmltYXRpb24ub3B0cyApO1xuXHRcdGlmICggcmVzdWx0ICkge1xuXHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCByZXN1bHQuc3RvcCApICkge1xuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIGFuaW1hdGlvbi5lbGVtLCBhbmltYXRpb24ub3B0cy5xdWV1ZSApLnN0b3AgPVxuXHRcdFx0XHRcdHJlc3VsdC5zdG9wLmJpbmQoIHJlc3VsdCApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdH1cblxuXHRqUXVlcnkubWFwKCBwcm9wcywgY3JlYXRlVHdlZW4sIGFuaW1hdGlvbiApO1xuXG5cdGlmICggaXNGdW5jdGlvbiggYW5pbWF0aW9uLm9wdHMuc3RhcnQgKSApIHtcblx0XHRhbmltYXRpb24ub3B0cy5zdGFydC5jYWxsKCBlbGVtLCBhbmltYXRpb24gKTtcblx0fVxuXG5cdC8vIEF0dGFjaCBjYWxsYmFja3MgZnJvbSBvcHRpb25zXG5cdGFuaW1hdGlvblxuXHRcdC5wcm9ncmVzcyggYW5pbWF0aW9uLm9wdHMucHJvZ3Jlc3MgKVxuXHRcdC5kb25lKCBhbmltYXRpb24ub3B0cy5kb25lLCBhbmltYXRpb24ub3B0cy5jb21wbGV0ZSApXG5cdFx0LmZhaWwoIGFuaW1hdGlvbi5vcHRzLmZhaWwgKVxuXHRcdC5hbHdheXMoIGFuaW1hdGlvbi5vcHRzLmFsd2F5cyApO1xuXG5cdGpRdWVyeS5meC50aW1lcihcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aWNrLCB7XG5cdFx0XHRlbGVtOiBlbGVtLFxuXHRcdFx0YW5pbTogYW5pbWF0aW9uLFxuXHRcdFx0cXVldWU6IGFuaW1hdGlvbi5vcHRzLnF1ZXVlXG5cdFx0fSApXG5cdCk7XG5cblx0cmV0dXJuIGFuaW1hdGlvbjtcbn1cblxualF1ZXJ5LkFuaW1hdGlvbiA9IGpRdWVyeS5leHRlbmQoIEFuaW1hdGlvbiwge1xuXG5cdHR3ZWVuZXJzOiB7XG5cdFx0XCIqXCI6IFsgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkge1xuXHRcdFx0dmFyIHR3ZWVuID0gdGhpcy5jcmVhdGVUd2VlbiggcHJvcCwgdmFsdWUgKTtcblx0XHRcdGFkanVzdENTUyggdHdlZW4uZWxlbSwgcHJvcCwgcmNzc051bS5leGVjKCB2YWx1ZSApLCB0d2VlbiApO1xuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH0gXVxuXHR9LFxuXG5cdHR3ZWVuZXI6IGZ1bmN0aW9uKCBwcm9wcywgY2FsbGJhY2sgKSB7XG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBwcm9wcyApICkge1xuXHRcdFx0Y2FsbGJhY2sgPSBwcm9wcztcblx0XHRcdHByb3BzID0gWyBcIipcIiBdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcm9wcyA9IHByb3BzLm1hdGNoKCBybm90aHRtbHdoaXRlICk7XG5cdFx0fVxuXG5cdFx0dmFyIHByb3AsXG5cdFx0XHRpbmRleCA9IDAsXG5cdFx0XHRsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cblx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0cHJvcCA9IHByb3BzWyBpbmRleCBdO1xuXHRcdFx0QW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gPSBBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSB8fCBbXTtcblx0XHRcdEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9LFxuXG5cdHByZWZpbHRlcnM6IFsgZGVmYXVsdFByZWZpbHRlciBdLFxuXG5cdHByZWZpbHRlcjogZnVuY3Rpb24oIGNhbGxiYWNrLCBwcmVwZW5kICkge1xuXHRcdGlmICggcHJlcGVuZCApIHtcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnB1c2goIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9XG59ICk7XG5cbmpRdWVyeS5zcGVlZCA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBmbiApIHtcblx0dmFyIG9wdCA9IHNwZWVkICYmIHR5cGVvZiBzcGVlZCA9PT0gXCJvYmplY3RcIiA/IGpRdWVyeS5leHRlbmQoIHt9LCBzcGVlZCApIDoge1xuXHRcdGNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8XG5cdFx0XHRpc0Z1bmN0aW9uKCBzcGVlZCApICYmIHNwZWVkLFxuXHRcdGR1cmF0aW9uOiBzcGVlZCxcblx0XHRlYXNpbmc6IGZuICYmIGVhc2luZyB8fCBlYXNpbmcgJiYgIWlzRnVuY3Rpb24oIGVhc2luZyApICYmIGVhc2luZ1xuXHR9O1xuXG5cdC8vIEdvIHRvIHRoZSBlbmQgc3RhdGUgaWYgZnggYXJlIG9mZlxuXHRpZiAoIGpRdWVyeS5meC5vZmYgKSB7XG5cdFx0b3B0LmR1cmF0aW9uID0gMDtcblxuXHR9IGVsc2Uge1xuXHRcdGlmICggdHlwZW9mIG9wdC5kdXJhdGlvbiAhPT0gXCJudW1iZXJcIiApIHtcblx0XHRcdGlmICggb3B0LmR1cmF0aW9uIGluIGpRdWVyeS5meC5zcGVlZHMgKSB7XG5cdFx0XHRcdG9wdC5kdXJhdGlvbiA9IGpRdWVyeS5meC5zcGVlZHNbIG9wdC5kdXJhdGlvbiBdO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvcHQuZHVyYXRpb24gPSBqUXVlcnkuZnguc3BlZWRzLl9kZWZhdWx0O
11xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIE5vcm1hbGl6ZSBvcHQucXVldWUgLSB0cnVlL3VuZGVmaW5lZC9udWxsIC0+IFwiZnhcIlxuXHRpZiAoIG9wdC5xdWV1ZSA9PSBudWxsIHx8IG9wdC5xdWV1ZSA9PT0gdHJ1ZSApIHtcblx0XHRvcHQucXVldWUgPSBcImZ4XCI7XG5cdH1cblxuXHQvLyBRdWV1ZWluZ1xuXHRvcHQub2xkID0gb3B0LmNvbXBsZXRlO1xuXG5cdG9wdC5jb21wbGV0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggaXNGdW5jdGlvbiggb3B0Lm9sZCApICkge1xuXHRcdFx0b3B0Lm9sZC5jYWxsKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBvcHQucXVldWUgKSB7XG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgb3B0LnF1ZXVlICk7XG5cdFx0fVxuXHR9O1xuXG5cdHJldHVybiBvcHQ7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGZhZGVUbzogZnVuY3Rpb24oIHNwZWVkLCB0bywgZWFzaW5nLCBjYWxsYmFjayApIHtcblxuXHRcdC8vIFNob3cgYW55IGhpZGRlbiBlbGVtZW50cyBhZnRlciBzZXR0aW5nIG9wYWNpdHkgdG8gMFxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggaXNIaWRkZW5XaXRoaW5UcmVlICkuY3NzKCBcIm9wYWNpdHlcIiwgMCApLnNob3coKVxuXG5cdFx0XHQvLyBBbmltYXRlIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWRcblx0XHRcdC5lbmQoKS5hbmltYXRlKCB7IG9wYWNpdHk6IHRvIH0sIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XG5cdH0sXG5cdGFuaW1hdGU6IGZ1bmN0aW9uKCBwcm9wLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHR2YXIgZW1wdHkgPSBqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcCApLFxuXHRcdFx0b3B0YWxsID0galF1ZXJ5LnNwZWVkKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApLFxuXHRcdFx0ZG9BbmltYXRpb24gPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBPcGVyYXRlIG9uIGEgY29weSBvZiBwcm9wIHNvIHBlci1wcm9wZXJ0eSBlYXNpbmcgd29uJ3QgYmUgbG9zdFxuXHRcdFx0XHR2YXIgYW5pbSA9IEFuaW1hdGlvbiggdGhpcywgalF1ZXJ5LmV4dGVuZCgge30sIHByb3AgKSwgb3B0YWxsICk7XG5cblx0XHRcdFx0Ly8gRW1wdHkgYW5pbWF0aW9ucywgb3IgZmluaXNoaW5nIHJlc29sdmVzIGltbWVkaWF0ZWx5XG5cdFx0XHRcdGlmICggZW1wdHkgfHwgZGF0YVByaXYuZ2V0KCB0aGlzLCBcImZpbmlzaFwiICkgKSB7XG5cdFx0XHRcdFx0YW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRkb0FuaW1hdGlvbi5maW5pc2ggPSBkb0FuaW1hdGlvbjtcblxuXHRcdHJldHVybiBlbXB0eSB8fCBvcHRhbGwucXVldWUgPT09IGZhbHNlID9cblx0XHRcdHRoaXMuZWFjaCggZG9BbmltYXRpb24gKSA6XG5cdFx0XHR0aGlzLnF1ZXVlKCBvcHRhbGwucXVldWUsIGRvQW5pbWF0aW9uICk7XG5cdH0sXG5cdHN0b3A6IGZ1bmN0aW9uKCB0eXBlLCBjbGVhclF1ZXVlLCBnb3RvRW5kICkge1xuXHRcdHZhciBzdG9wUXVldWUgPSBmdW5jdGlvbiggaG9va3MgKSB7XG5cdFx0XHR2YXIgc3RvcCA9IGhvb2tzLnN0b3A7XG5cdFx0XHRkZWxldGUgaG9va3Muc3RvcDtcblx0XHRcdHN0b3AoIGdvdG9FbmQgKTtcblx0XHR9O1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGdvdG9FbmQgPSBjbGVhclF1ZXVlO1xuXHRcdFx0Y2xlYXJRdWV1ZSA9IHR5cGU7XG5cdFx0XHR0eXBlID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoIGNsZWFyUXVldWUgKSB7XG5cdFx0XHR0aGlzLnF1ZXVlKCB0eXBlIHx8IFwiZnhcIiwgW10gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkZXF1ZXVlID0gdHJ1ZSxcblx0XHRcdFx0aW5kZXggPSB0eXBlICE9IG51bGwgJiYgdHlwZSArIFwicXVldWVIb29rc1wiLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRkYXRhID0gZGF0YVByaXYuZ2V0KCB0aGlzICk7XG5cblx0XHRcdGlmICggaW5kZXggKSB7XG5cdFx0XHRcdGlmICggZGF0YVsgaW5kZXggXSAmJiBkYXRhWyBpbmRleCBdLnN0b3AgKSB7XG5cdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoIGluZGV4IGluIGRhdGEgKSB7XG5cdFx0XHRcdFx0aWYgKCBkYXRhWyBpbmRleCBdICYmIGRhdGFbIGluZGV4IF0uc3RvcCAmJiBycnVuLnRlc3QoIGluZGV4ICkgKSB7XG5cdFx0XHRcdFx0XHRzdG9wUXVldWUoIGRhdGFbIGluZGV4IF0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaW5kZXggPSB0aW1lcnMubGVuZ3RoOyBpbmRleC0tOyApIHtcblx0XHRcdFx0aWYgKCB0aW1lcnNbIGluZGV4IF0uZWxlbSA9PT0gdGhpcyAmJlxuXHRcdFx0XHRcdCggdHlwZSA9PSBudWxsIHx8IHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApICkge1xuXG5cdFx0XHRcdFx0dGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggZ290b0VuZCApO1xuXHRcdFx0XHRcdGRlcXVldWUgPSBmYWxzZTtcblx0XHRcdFx0XHR0aW1lcnMuc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXJ0IHRoZSBuZXh0IGluIHRoZSBxdWV1ZSBpZiB0aGUgbGFzdCBzdGVwIHdhc24ndCBmb3JjZWQuXG5cdFx0XHQvLyBUaW1lcnMgY3VycmVudGx5IHdpbGwgY2FsbCB0aGVpciBjb21wbGV0ZSBjYWxsYmFja3MsIHdoaWNoXG5cdFx0XHQvLyB3aWxsIGRlcXVldWUgYnV0IG9ubHkgaWYgdGhleSB3ZXJlIGdvdG9FbmQuXG5cdFx0XHRpZiAoIGRlcXVldWUgfHwgIWdvdG9FbmQgKSB7XG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXHRmaW5pc2g6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdGlmICggdHlwZSAhPT0gZmFsc2UgKSB7XG5cdFx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGluZGV4LFxuXHRcdFx0XHRkYXRhID0gZGF0YVByaXYuZ2V0KCB0aGlzICksXG5cdFx0XHRcdHF1ZXVlID0gZGF0YVsgdHlwZSArIFwicXVldWVcIiBdLFxuXHRcdFx0XHRob29rcyA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlSG9va3NcIiBdLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRsZW5ndGggPSBxdWV1ZSA/IHF1ZXVlLmxlbmd0aCA6IDA7XG5cblx0XHRcdC8vIEVuYWJsZSBmaW5pc2hpbmcgZmxhZyBvbiBwcml2YXRlIGRhdGFcblx0XHRcdGRhdGEuZmluaXNoID0gdHJ1ZTtcblxuXHRcdFx0Ly8gRW1wdHkgdGhlI
1HF1ZXVlIGZpcnN0XG5cdFx0XHRqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIFtdICk7XG5cblx0XHRcdGlmICggaG9va3MgJiYgaG9va3Muc3RvcCApIHtcblx0XHRcdFx0aG9va3Muc3RvcC5jYWxsKCB0aGlzLCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIExvb2sgZm9yIGFueSBhY3RpdmUgYW5pbWF0aW9ucywgYW5kIGZpbmlzaCB0aGVtXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xuXHRcdFx0XHRpZiAoIHRpbWVyc1sgaW5kZXggXS5lbGVtID09PSB0aGlzICYmIHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApIHtcblx0XHRcdFx0XHR0aW1lcnNbIGluZGV4IF0uYW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBMb29rIGZvciBhbnkgYW5pbWF0aW9ucyBpbiB0aGUgb2xkIHF1ZXVlIGFuZCBmaW5pc2ggdGhlbVxuXHRcdFx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0aWYgKCBxdWV1ZVsgaW5kZXggXSAmJiBxdWV1ZVsgaW5kZXggXS5maW5pc2ggKSB7XG5cdFx0XHRcdFx0cXVldWVbIGluZGV4IF0uZmluaXNoLmNhbGwoIHRoaXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBUdXJuIG9mZiBmaW5pc2hpbmcgZmxhZ1xuXHRcdFx0ZGVsZXRlIGRhdGEuZmluaXNoO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCggWyBcInRvZ2dsZVwiLCBcInNob3dcIiwgXCJoaWRlXCIgXSwgZnVuY3Rpb24oIF9pLCBuYW1lICkge1xuXHR2YXIgY3NzRm4gPSBqUXVlcnkuZm5bIG5hbWUgXTtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHNwZWVkID09IG51bGwgfHwgdHlwZW9mIHNwZWVkID09PSBcImJvb2xlYW5cIiA/XG5cdFx0XHRjc3NGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICkgOlxuXHRcdFx0dGhpcy5hbmltYXRlKCBnZW5GeCggbmFtZSwgdHJ1ZSApLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSApO1xuXG4vLyBHZW5lcmF0ZSBzaG9ydGN1dHMgZm9yIGN1c3RvbSBhbmltYXRpb25zXG5qUXVlcnkuZWFjaCgge1xuXHRzbGlkZURvd246IGdlbkZ4KCBcInNob3dcIiApLFxuXHRzbGlkZVVwOiBnZW5GeCggXCJoaWRlXCIgKSxcblx0c2xpZGVUb2dnbGU6IGdlbkZ4KCBcInRvZ2dsZVwiICksXG5cdGZhZGVJbjogeyBvcGFjaXR5OiBcInNob3dcIiB9LFxuXHRmYWRlT3V0OiB7IG9wYWNpdHk6IFwiaGlkZVwiIH0sXG5cdGZhZGVUb2dnbGU6IHsgb3BhY2l0eTogXCJ0b2dnbGVcIiB9XG59LCBmdW5jdGlvbiggbmFtZSwgcHJvcHMgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLmFuaW1hdGUoIHByb3BzLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSApO1xuXG5qUXVlcnkudGltZXJzID0gW107XG5qUXVlcnkuZngudGljayA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgdGltZXIsXG5cdFx0aSA9IDAsXG5cdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycztcblxuXHRmeE5vdyA9IERhdGUubm93KCk7XG5cblx0Zm9yICggOyBpIDwgdGltZXJzLmxlbmd0aDsgaSsrICkge1xuXHRcdHRpbWVyID0gdGltZXJzWyBpIF07XG5cblx0XHQvLyBSdW4gdGhlIHRpbWVyIGFuZCBzYWZlbHkgcmVtb3ZlIGl0IHdoZW4gZG9uZSAoYWxsb3dpbmcgZm9yIGV4dGVybmFsIHJlbW92YWwpXG5cdFx0aWYgKCAhdGltZXIoKSAmJiB0aW1lcnNbIGkgXSA9PT0gdGltZXIgKSB7XG5cdFx0XHR0aW1lcnMuc3BsaWNlKCBpLS0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoICF0aW1lcnMubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5meC5zdG9wKCk7XG5cdH1cblx0ZnhOb3cgPSB1bmRlZmluZWQ7XG59O1xuXG5qUXVlcnkuZngudGltZXIgPSBmdW5jdGlvbiggdGltZXIgKSB7XG5cdGpRdWVyeS50aW1lcnMucHVzaCggdGltZXIgKTtcblx0alF1ZXJ5LmZ4LnN0YXJ0KCk7XG59O1xuXG5qUXVlcnkuZnguaW50ZXJ2YWwgPSAxMztcbmpRdWVyeS5meC5zdGFydCA9IGZ1bmN0aW9uKCkge1xuXHRpZiAoIGluUHJvZ3Jlc3MgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aW5Qcm9ncmVzcyA9IHRydWU7XG5cdHNjaGVkdWxlKCk7XG59O1xuXG5qUXVlcnkuZnguc3RvcCA9IGZ1bmN0aW9uKCkge1xuXHRpblByb2dyZXNzID0gbnVsbDtcbn07XG5cbmpRdWVyeS5meC5zcGVlZHMgPSB7XG5cdHNsb3c6IDYwMCxcblx0ZmFzdDogMjAwLFxuXG5cdC8vIERlZmF1bHQgc3BlZWRcblx0X2RlZmF1bHQ6IDQwMFxufTtcblxuXG4vLyBCYXNlZCBvZmYgb2YgdGhlIHBsdWdpbiBieSBDbGludCBIZWxmZXJzLCB3aXRoIHBlcm1pc3Npb24uXG5qUXVlcnkuZm4uZGVsYXkgPSBmdW5jdGlvbiggdGltZSwgdHlwZSApIHtcblx0dGltZSA9IGpRdWVyeS5meCA/IGpRdWVyeS5meC5zcGVlZHNbIHRpbWUgXSB8fCB0aW1lIDogdGltZTtcblx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdHJldHVybiB0aGlzLnF1ZXVlKCB0eXBlLCBmdW5jdGlvbiggbmV4dCwgaG9va3MgKSB7XG5cdFx0dmFyIHRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCggbmV4dCwgdGltZSApO1xuXHRcdGhvb2tzLnN0b3AgPSBmdW5jdGlvbigpIHtcblx0XHRcdHdpbmRvdy5jbGVhclRpbWVvdXQoIHRpbWVvdXQgKTtcblx0XHR9O1xuXHR9ICk7XG59O1xuXG5cbiggZnVuY3Rpb24oKSB7XG5cdHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApLFxuXHRcdHNlbGVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwic2VsZWN0XCIgKSxcblx0XHRvcHQgPSBzZWxlY3QuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwib3B0aW9uXCIgKSApO1xuXG5cdGlucHV0LnR5cGUgPSBcImNoZWNrYm94XCI7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMyBvbmx5XG5cdC8vIERlZmF1bHQgdmFsdWUgZm9yIGEgY2hlY2tib3ggc2hvdWxkIGJlIFwib25cIlxuXHRzdXBwb3J0LmNoZWNrT24gPSBpbnB1dC52YWx1ZSAhPT0gXCJcIjtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHlcblx0Ly8gTXVzdCBhY2Nlc3Mgc2VsZWN0ZWRJbmRleCB0byBtYWtlIGRlZmF1bHQgb3B0aW9ucyBzZWxlY3Rcblx0c3VwcG9ydC5vcHRTZWxlY3RlZCA9IG9wdC5zZWxlY3RlZDtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHlcblx0Ly8gQW4gaW5wdXQgbG9zZXMgaXRzIHZhbHVlIGFmdGVyIGJlY29taW5nIGEgcmFkaW9cblx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcblx0aW5wdXQudmFsdWUgPSBcInRcIjtcblx0aW5wdXQudHlwZSA9IFwicmFkaW9cIjtcblx0c3VwcG9ydC5yYWRpb1ZhbHVlID0gaW5wdXQudmFsdWUgPT09IFwidFwiO1xufSApKCk7XG5cblxudmFyIGJvb2xIb29rLF
1xuXHRhdHRySGFuZGxlID0galF1ZXJ5LmV4cHIuYXR0ckhhbmRsZTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRhdHRyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LmF0dHIsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBuYW1lICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIHRoaXMsIG5hbWUgKTtcblx0XHR9ICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmV4dGVuZCgge1xuXHRhdHRyOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0dmFyIHJldCwgaG9va3MsXG5cdFx0XHRuVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0XHQvLyBEb24ndCBnZXQvc2V0IGF0dHJpYnV0ZXMgb24gdGV4dCwgY29tbWVudCBhbmQgYXR0cmlidXRlIG5vZGVzXG5cdFx0aWYgKCBuVHlwZSA9PT0gMyB8fCBuVHlwZSA9PT0gOCB8fCBuVHlwZSA9PT0gMiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBGYWxsYmFjayB0byBwcm9wIHdoZW4gYXR0cmlidXRlcyBhcmUgbm90IHN1cHBvcnRlZFxuXHRcdGlmICggdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlID09PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5wcm9wKCBlbGVtLCBuYW1lLCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdC8vIEF0dHJpYnV0ZSBob29rcyBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgbG93ZXJjYXNlIHZlcnNpb25cblx0XHQvLyBHcmFiIG5lY2Vzc2FyeSBob29rIGlmIG9uZSBpcyBkZWZpbmVkXG5cdFx0aWYgKCBuVHlwZSAhPT0gMSB8fCAhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICkgKSB7XG5cdFx0XHRob29rcyA9IGpRdWVyeS5hdHRySG9va3NbIG5hbWUudG9Mb3dlckNhc2UoKSBdIHx8XG5cdFx0XHRcdCggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC50ZXN0KCBuYW1lICkgPyBib29sSG9vayA6IHVuZGVmaW5lZCApO1xuXHRcdH1cblxuXHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGlmICggdmFsdWUgPT09IG51bGwgKSB7XG5cdFx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCBlbGVtLCBuYW1lICk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBob29rcyAmJiBcInNldFwiIGluIGhvb2tzICYmXG5cdFx0XHRcdCggcmV0ID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgbmFtZSApICkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblxuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIHZhbHVlICsgXCJcIiApO1xuXHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdH1cblxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAoIHJldCA9IGhvb2tzLmdldCggZWxlbSwgbmFtZSApICkgIT09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH1cblxuXHRcdHJldCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIG5hbWUgKTtcblxuXHRcdC8vIE5vbi1leGlzdGVudCBhdHRyaWJ1dGVzIHJldHVybiBudWxsLCB3ZSBub3JtYWxpemUgdG8gdW5kZWZpbmVkXG5cdFx0cmV0dXJuIHJldCA9PSBudWxsID8gdW5kZWZpbmVkIDogcmV0O1xuXHR9LFxuXG5cdGF0dHJIb29rczoge1xuXHRcdHR5cGU6IHtcblx0XHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0XHRpZiAoICFzdXBwb3J0LnJhZGlvVmFsdWUgJiYgdmFsdWUgPT09IFwicmFkaW9cIiAmJlxuXHRcdFx0XHRcdG5vZGVOYW1lKCBlbGVtLCBcImlucHV0XCIgKSApIHtcblx0XHRcdFx0XHR2YXIgdmFsID0gZWxlbS52YWx1ZTtcblx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIHZhbHVlICk7XG5cdFx0XHRcdFx0aWYgKCB2YWwgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnZhbHVlID0gdmFsO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0cmVtb3ZlQXR0cjogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdHZhciBuYW1lLFxuXHRcdFx0aSA9IDAsXG5cblx0XHRcdC8vIEF0dHJpYnV0ZSBuYW1lcyBjYW4gY29udGFpbiBub24tSFRNTCB3aGl0ZXNwYWNlIGNoYXJhY3RlcnNcblx0XHRcdC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI2F0dHJpYnV0ZXMtMlxuXHRcdFx0YXR0ck5hbWVzID0gdmFsdWUgJiYgdmFsdWUubWF0Y2goIHJub3RodG1sd2hpdGUgKTtcblxuXHRcdGlmICggYXR0ck5hbWVzICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHR3aGlsZSAoICggbmFtZSA9IGF0dHJOYW1lc1sgaSsrIF0gKSApIHtcblx0XHRcdFx0ZWxlbS5yZW1vdmVBdHRyaWJ1dGUoIG5hbWUgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0gKTtcblxuLy8gSG9va3MgZm9yIGJvb2xlYW4gYXR0cmlidXRlc1xuYm9vbEhvb2sgPSB7XG5cdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlLCBuYW1lICkge1xuXHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXG5cdFx0XHQvLyBSZW1vdmUgYm9vbGVhbiBhdHRyaWJ1dGVzIHdoZW4gc2V0IHRvIGZhbHNlXG5cdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggbmFtZSwgbmFtZSApO1xuXHRcdH1cblx0XHRyZXR1cm4gbmFtZTtcblx0fVxufTtcblxualF1ZXJ5LmVhY2goIGpRdWVyeS5leHByLm1hdGNoLmJvb2wuc291cmNlLm1hdGNoKCAvXFx3Ky9nICksIGZ1bmN0aW9uKCBfaSwgbmFtZSApIHtcblx0dmFyIGdldHRlciA9IGF0dHJIYW5kbGVbIG5hbWUgXSB8fCBqUXVlcnkuZmluZC5hdHRyO1xuXG5cdGF0dHJIYW5kbGVbIG5hbWUgXSA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHR2YXIgcmV0LCBoYW5kbGUsXG5cdFx0XHRsb3dlcmNhc2VOYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0aWYgKCAhaXNYTUwgKSB7XG5cblx0XHRcdC8vIEF2b2lkIGFuIGluZmluaXRlIGxvb3AgYnkgdGVtcG9yYXJpbHkgcmVtb3ZpbmcgdGhpcyBmdW5jdGlvbiBmcm9tIHRoZSBnZXR0ZXJcblx0XHRcdGhhbmRsZSA9IGF0dHJIYW5kbGVbIGxvd2VyY2FzZU5hbWUgXTtcblx0XHRcdGF0dHJIYW5kbGVbIGxvd2VyY2FzZU5hbWUgXSA9IHJldDtcblx0XHRcdHJldCA9IGdldHRlciggZWxlbSwgbmFtZSwgaXNYTUwgKSAhPSBudWxsID9cblx0XHRcdFx0bG93ZXJjYXNlTmFtZSA6XG5cdFx0XHRcdG51bGw7XG5cdFx0XHRhdHRySGFuZGxlWyBsb3dlcmNhc2VOYW1lIF0gPSBoYW5kbGU7XG5cdFx0fVxuXHRcdHJldHVybi
1ByZXQ7XG5cdH07XG59ICk7XG5cblxuXG5cbnZhciByZm9jdXNhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxcblx0cmNsaWNrYWJsZSA9IC9eKD86YXxhcmVhKSQvaTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRwcm9wOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LnByb3AsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9LFxuXG5cdHJlbW92ZVByb3A6IGZ1bmN0aW9uKCBuYW1lICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGVsZXRlIHRoaXNbIGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZSBdO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdHByb3A6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHR2YXIgcmV0LCBob29rcyxcblx0XHRcdG5UeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRcdC8vIERvbid0IGdldC9zZXQgcHJvcGVydGllcyBvbiB0ZXh0LCBjb21tZW50IGFuZCBhdHRyaWJ1dGUgbm9kZXNcblx0XHRpZiAoIG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXG5cdFx0XHQvLyBGaXggbmFtZSBhbmQgYXR0YWNoIGhvb2tzXG5cdFx0XHRuYW1lID0galF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lO1xuXHRcdFx0aG9va3MgPSBqUXVlcnkucHJvcEhvb2tzWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0aWYgKCBob29rcyAmJiBcInNldFwiIGluIGhvb2tzICYmXG5cdFx0XHRcdCggcmV0ID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgbmFtZSApICkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuICggZWxlbVsgbmFtZSBdID0gdmFsdWUgKTtcblx0XHR9XG5cblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKCByZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSApICE9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cblx0XHRyZXR1cm4gZWxlbVsgbmFtZSBdO1xuXHR9LFxuXG5cdHByb3BIb29rczoge1xuXHRcdHRhYkluZGV4OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExIG9ubHlcblx0XHRcdFx0Ly8gZWxlbS50YWJJbmRleCBkb2Vzbid0IGFsd2F5cyByZXR1cm4gdGhlXG5cdFx0XHRcdC8vIGNvcnJlY3QgdmFsdWUgd2hlbiBpdCBoYXNuJ3QgYmVlbiBleHBsaWNpdGx5IHNldFxuXHRcdFx0XHQvLyBVc2UgcHJvcGVyIGF0dHJpYnV0ZSByZXRyaWV2YWwgKHRyYWMtMTIwNzIpXG5cdFx0XHRcdHZhciB0YWJpbmRleCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIFwidGFiaW5kZXhcIiApO1xuXG5cdFx0XHRcdGlmICggdGFiaW5kZXggKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhcnNlSW50KCB0YWJpbmRleCwgMTAgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRyZm9jdXNhYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSB8fFxuXHRcdFx0XHRcdHJjbGlja2FibGUudGVzdCggZWxlbS5ub2RlTmFtZSApICYmXG5cdFx0XHRcdFx0ZWxlbS5ocmVmXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRwcm9wRml4OiB7XG5cdFx0XCJmb3JcIjogXCJodG1sRm9yXCIsXG5cdFx0XCJjbGFzc1wiOiBcImNsYXNzTmFtZVwiXG5cdH1cbn0gKTtcblxuLy8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG4vLyBBY2Nlc3NpbmcgdGhlIHNlbGVjdGVkSW5kZXggcHJvcGVydHlcbi8vIGZvcmNlcyB0aGUgYnJvd3NlciB0byByZXNwZWN0IHNldHRpbmcgc2VsZWN0ZWRcbi8vIG9uIHRoZSBvcHRpb25cbi8vIFRoZSBnZXR0ZXIgZW5zdXJlcyBhIGRlZmF1bHQgb3B0aW9uIGlzIHNlbGVjdGVkXG4vLyB3aGVuIGluIGFuIG9wdGdyb3VwXG4vLyBlc2xpbnQgcnVsZSBcIm5vLXVudXNlZC1leHByZXNzaW9uc1wiIGlzIGRpc2FibGVkIGZvciB0aGlzIGNvZGVcbi8vIHNpbmNlIGl0IGNvbnNpZGVycyBzdWNoIGFjY2Vzc2lvbnMgbm9vcFxuaWYgKCAhc3VwcG9ydC5vcHRTZWxlY3RlZCApIHtcblx0alF1ZXJ5LnByb3BIb29rcy5zZWxlY3RlZCA9IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHQvKiBlc2xpbnQgbm8tdW51c2VkLWV4cHJlc3Npb25zOiBcIm9mZlwiICovXG5cblx0XHRcdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRpZiAoIHBhcmVudCAmJiBwYXJlbnQucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0LyogZXNsaW50IG5vLXVudXNlZC1leHByZXNzaW9uczogXCJvZmZcIiAqL1xuXG5cdFx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdFx0aWYgKCBwYXJlbnQgKSB7XG5cdFx0XHRcdHBhcmVudC5zZWxlY3RlZEluZGV4O1xuXG5cdFx0XHRcdGlmICggcGFyZW50LnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fTtcbn1cblxualF1ZXJ5LmVhY2goIFtcblx0XCJ0YWJJbmRleFwiLFxuXHRcInJlYWRPbmx5XCIsXG5cdFwibWF4TGVuZ3RoXCIsXG5cdFwiY2VsbFNwYWNpbmdcIixcblx0XCJjZWxsUGFkZGluZ1wiLFxuXHRcInJvd1NwYW5cIixcblx0XCJjb2xTcGFuXCIsXG5cdFwidXNlTWFwXCIsXG5cdFwiZnJhbWVCb3JkZXJcIixcblx0XCJjb250ZW50RWRpdGFibGVcIlxuXSwgZnVuY3Rpb24oKSB7XG5cdGpRdWVyeS5wcm9wRml4WyB0aGlzLnRvTG93ZXJDYXNlKCkgXSA9IHRoaXM7XG59ICk7XG5cblxuXG5cblx0Ly8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2UgYWNjb3JkaW5nIHRvIEhUTUwgc3BlY1xuXHQvLyBodHRwczovL2luZnJhLnNwZWMud2hhdHdnLm9yZy8jc3RyaXAtYW5kLWNvbGxhcHNlLWFzY2lpLXdoaXRlc3BhY2Vcblx0ZnVuY3Rpb24gc3RyaXBBbmRDb2xsYXBzZSggdmFsdWUgKSB7XG5cdFx0dmFyIHRva2VucyA9IHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW107XG5cdFx0cmV0dXJuIHRva2Vucy5qb2luKCBcIiBcIiApO1xuXHR9XG5cblxuZnVuY3Rpb24gZ2V0Q2xhc3MoIGVsZW0gKSB7XG5cdHJldHVybi
1BlbGVtLmdldEF0dHJpYnV0ZSAmJiBlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHwgXCJcIjtcbn1cblxuZnVuY3Rpb24gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICkge1xuXHRpZiAoIEFycmF5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9XG5cdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiB2YWx1ZS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdO1xuXHR9XG5cdHJldHVybiBbXTtcbn1cblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRhZGRDbGFzczogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBjbGFzc05hbWVzLCBjdXIsIGN1clZhbHVlLCBjbGFzc05hbWUsIGksIGZpbmFsVmFsdWU7XG5cblx0XHRpZiAoIGlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaiApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuYWRkQ2xhc3MoIHZhbHVlLmNhbGwoIHRoaXMsIGosIGdldENsYXNzKCB0aGlzICkgKSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdGNsYXNzTmFtZXMgPSBjbGFzc2VzVG9BcnJheSggdmFsdWUgKTtcblxuXHRcdGlmICggY2xhc3NOYW1lcy5sZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0Y3VyVmFsdWUgPSBnZXRDbGFzcyggdGhpcyApO1xuXHRcdFx0XHRjdXIgPSB0aGlzLm5vZGVUeXBlID09PSAxICYmICggXCIgXCIgKyBzdHJpcEFuZENvbGxhcHNlKCBjdXJWYWx1ZSApICsgXCIgXCIgKTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGNsYXNzTmFtZXMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRjbGFzc05hbWUgPSBjbGFzc05hbWVzWyBpIF07XG5cdFx0XHRcdFx0XHRpZiAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXNzTmFtZSArIFwiIFwiICkgPCAwICkge1xuXHRcdFx0XHRcdFx0XHRjdXIgKz0gY2xhc3NOYW1lICsgXCIgXCI7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gT25seSBhc3NpZ24gaWYgZGlmZmVyZW50IHRvIGF2b2lkIHVubmVlZGVkIHJlbmRlcmluZy5cblx0XHRcdFx0XHRmaW5hbFZhbHVlID0gc3RyaXBBbmRDb2xsYXBzZSggY3VyICk7XG5cdFx0XHRcdFx0aWYgKCBjdXJWYWx1ZSAhPT0gZmluYWxWYWx1ZSApIHtcblx0XHRcdFx0XHRcdHRoaXMuc2V0QXR0cmlidXRlKCBcImNsYXNzXCIsIGZpbmFsVmFsdWUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRyZW1vdmVDbGFzczogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBjbGFzc05hbWVzLCBjdXIsIGN1clZhbHVlLCBjbGFzc05hbWUsIGksIGZpbmFsVmFsdWU7XG5cblx0XHRpZiAoIGlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaiApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkucmVtb3ZlQ2xhc3MoIHZhbHVlLmNhbGwoIHRoaXMsIGosIGdldENsYXNzKCB0aGlzICkgKSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdGlmICggIWFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5hdHRyKCBcImNsYXNzXCIsIFwiXCIgKTtcblx0XHR9XG5cblx0XHRjbGFzc05hbWVzID0gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICk7XG5cblx0XHRpZiAoIGNsYXNzTmFtZXMubGVuZ3RoICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGN1clZhbHVlID0gZ2V0Q2xhc3MoIHRoaXMgKTtcblxuXHRcdFx0XHQvLyBUaGlzIGV4cHJlc3Npb24gaXMgaGVyZSBmb3IgYmV0dGVyIGNvbXByZXNzaWJpbGl0eSAoc2VlIGFkZENsYXNzKVxuXHRcdFx0XHRjdXIgPSB0aGlzLm5vZGVUeXBlID09PSAxICYmICggXCIgXCIgKyBzdHJpcEFuZENvbGxhcHNlKCBjdXJWYWx1ZSApICsgXCIgXCIgKTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGNsYXNzTmFtZXMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRjbGFzc05hbWUgPSBjbGFzc05hbWVzWyBpIF07XG5cblx0XHRcdFx0XHRcdC8vIFJlbW92ZSAqYWxsKiBpbnN0YW5jZXNcblx0XHRcdFx0XHRcdHdoaWxlICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhc3NOYW1lICsgXCIgXCIgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0XHRjdXIgPSBjdXIucmVwbGFjZSggXCIgXCIgKyBjbGFzc05hbWUgKyBcIiBcIiwgXCIgXCIgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBPbmx5IGFzc2lnbiBpZiBkaWZmZXJlbnQgdG8gYXZvaWQgdW5uZWVkZWQgcmVuZGVyaW5nLlxuXHRcdFx0XHRcdGZpbmFsVmFsdWUgPSBzdHJpcEFuZENvbGxhcHNlKCBjdXIgKTtcblx0XHRcdFx0XHRpZiAoIGN1clZhbHVlICE9PSBmaW5hbFZhbHVlICkge1xuXHRcdFx0XHRcdFx0dGhpcy5zZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIiwgZmluYWxWYWx1ZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHRvZ2dsZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUsIHN0YXRlVmFsICkge1xuXHRcdHZhciBjbGFzc05hbWVzLCBjbGFzc05hbWUsIGksIHNlbGYsXG5cdFx0XHR0eXBlID0gdHlwZW9mIHZhbHVlLFxuXHRcdFx0aXNWYWxpZFZhbHVlID0gdHlwZSA9PT0gXCJzdHJpbmdcIiB8fCBBcnJheS5pc0FycmF5KCB2YWx1ZSApO1xuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnRvZ2dsZUNsYXNzKFxuXHRcdFx0XHRcdHZhbHVlLmNhbGwoIHRoaXMsIGksIGdldENsYXNzKCB0aGlzICksIHN0YXRlVmFsICksXG5cdFx0XHRcdFx0c3RhdGVWYWxcblx0XHRcdFx0KTtcblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRpZiAoIHR5cGVvZiBzdGF0ZVZhbCA9PT0gXCJib29sZWFuXCIgJiYgaXNWYWxpZFZhbHVlICkge1xuXHRcdFx0cmV0dXJuIHN0YXRlVmFsID8gdGhpcy5hZGRDbGFzcyggdmFsdWUgKSA6IHRoaXMucmVtb3ZlQ2xhc3MoIHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0Y2xhc3NOYW1lcyA9IGNsYXNzZXNUb0FycmF5KCB2YWx1ZSApO1xuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGlzVmFsaWRWYWx1ZSApIHtcblxuXHRcdFx0XHQvLyBUb2dnbGUgaW5kaXZpZHVhbCBjbGFzcyBuYW1lc1xuXHRcdFx0XHRzZWxmID0galF1ZXJ5KCB0aGlzICk7XG5cblx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBjbGFzc05hbWVzLmxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdGNsYXNzTmFtZSA9IGNsYXNzTmFtZXNbIG
1kgXTtcblxuXHRcdFx0XHRcdC8vIENoZWNrIGVhY2ggY2xhc3NOYW1lIGdpdmVuLCBzcGFjZSBzZXBhcmF0ZWQgbGlzdFxuXHRcdFx0XHRcdGlmICggc2VsZi5oYXNDbGFzcyggY2xhc3NOYW1lICkgKSB7XG5cdFx0XHRcdFx0XHRzZWxmLnJlbW92ZUNsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c2VsZi5hZGRDbGFzcyggY2xhc3NOYW1lICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdC8vIFRvZ2dsZSB3aG9sZSBjbGFzcyBuYW1lXG5cdFx0XHR9IGVsc2UgaWYgKCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGUgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0XHRjbGFzc05hbWUgPSBnZXRDbGFzcyggdGhpcyApO1xuXHRcdFx0XHRpZiAoIGNsYXNzTmFtZSApIHtcblxuXHRcdFx0XHRcdC8vIFN0b3JlIGNsYXNzTmFtZSBpZiBzZXRcblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiLCBjbGFzc05hbWUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIElmIHRoZSBlbGVtZW50IGhhcyBhIGNsYXNzIG5hbWUgb3IgaWYgd2UncmUgcGFzc2VkIGBmYWxzZWAsXG5cdFx0XHRcdC8vIHRoZW4gcmVtb3ZlIHRoZSB3aG9sZSBjbGFzc25hbWUgKGlmIHRoZXJlIHdhcyBvbmUsIHRoZSBhYm92ZSBzYXZlZCBpdCkuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBicmluZyBiYWNrIHdoYXRldmVyIHdhcyBwcmV2aW91c2x5IHNhdmVkIChpZiBhbnl0aGluZyksXG5cdFx0XHRcdC8vIGZhbGxpbmcgYmFjayB0byB0aGUgZW1wdHkgc3RyaW5nIGlmIG5vdGhpbmcgd2FzIHN0b3JlZC5cblx0XHRcdFx0aWYgKCB0aGlzLnNldEF0dHJpYnV0ZSApIHtcblx0XHRcdFx0XHR0aGlzLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lIHx8IHZhbHVlID09PSBmYWxzZSA/XG5cdFx0XHRcdFx0XHRcdFwiXCIgOlxuXHRcdFx0XHRcdFx0XHRkYXRhUHJpdi5nZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiICkgfHwgXCJcIlxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0aGFzQ2xhc3M6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR2YXIgY2xhc3NOYW1lLCBlbGVtLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRjbGFzc05hbWUgPSBcIiBcIiArIHNlbGVjdG9yICsgXCIgXCI7XG5cdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xuXHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmXG5cdFx0XHRcdCggXCIgXCIgKyBzdHJpcEFuZENvbGxhcHNlKCBnZXRDbGFzcyggZWxlbSApICkgKyBcIiBcIiApLmluZGV4T2YoIGNsYXNzTmFtZSApID4gLTEgKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufSApO1xuXG5cblxuXG52YXIgcnJldHVybiA9IC9cXHIvZztcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHR2YWw6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgaG9va3MsIHJldCwgdmFsdWVJc0Z1bmN0aW9uLFxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXTtcblxuXHRcdGlmICggIWFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyBlbGVtLnR5cGUgXSB8fFxuXHRcdFx0XHRcdGpRdWVyeS52YWxIb29rc1sgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIF07XG5cblx0XHRcdFx0aWYgKCBob29rcyAmJlxuXHRcdFx0XHRcdFwiZ2V0XCIgaW4gaG9va3MgJiZcblx0XHRcdFx0XHQoIHJldCA9IGhvb2tzLmdldCggZWxlbSwgXCJ2YWx1ZVwiICkgKSAhPT0gdW5kZWZpbmVkXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXQgPSBlbGVtLnZhbHVlO1xuXG5cdFx0XHRcdC8vIEhhbmRsZSBtb3N0IGNvbW1vbiBzdHJpbmcgY2FzZXNcblx0XHRcdFx0aWYgKCB0eXBlb2YgcmV0ID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0XHRcdHJldHVybiByZXQucmVwbGFjZSggcnJldHVybiwgXCJcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gSGFuZGxlIGNhc2VzIHdoZXJlIHZhbHVlIGlzIG51bGwvdW5kZWYgb3IgbnVtYmVyXG5cdFx0XHRcdHJldHVybiByZXQgPT0gbnVsbCA/IFwiXCIgOiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YWx1ZUlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHR2YXIgdmFsO1xuXG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgIT09IDEgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCB2YWx1ZUlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdHZhbCA9IHZhbHVlLmNhbGwoIHRoaXMsIGksIGpRdWVyeSggdGhpcyApLnZhbCgpICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVHJlYXQgbnVsbC91bmRlZmluZWQgYXMgXCJcIjsgY29udmVydCBudW1iZXJzIHRvIHN0cmluZ1xuXHRcdFx0aWYgKCB2YWwgPT0gbnVsbCApIHtcblx0XHRcdFx0dmFsID0gXCJcIjtcblxuXHRcdFx0fSBlbHNlIGlmICggdHlwZW9mIHZhbCA9PT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0dmFsICs9IFwiXCI7XG5cblx0XHRcdH0gZWxzZSBpZiAoIEFycmF5LmlzQXJyYXkoIHZhbCApICkge1xuXHRcdFx0XHR2YWwgPSBqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSArIFwiXCI7XG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblxuXHRcdFx0aG9va3MgPSBqUXVlcnkudmFsSG9va3NbIHRoaXMudHlwZSBdIHx8IGpRdWVyeS52YWxIb29rc1sgdGhpcy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIF07XG5cblx0XHRcdC8vIElmIHNldCByZXR1cm5zIHVuZGVmaW5lZCwgZmFsbCBiYWNrIHRvIG5vcm1hbCBzZXR0aW5nXG5cdFx0XHRpZiAoICFob29rcyB8fCAhKCBcInNldFwiIGluIGhvb2tzICkgfHwgaG9va3Muc2V0KCB0aGlzLCB2YWwsIFwidmFsdWVcIiApID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHRoaXMudmFsdWUgPSB2YWw7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0dmFsSG9va3M6IHtcblx0XHRvcHRpb246IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdFx0dmFyIHZhbCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIFwidmFsdWVcIiApO1xuXHRcdFx0XHRyZXR1cm4gdmFsICE9IG51bGwgP1xuXHRcdFx0XHRcdHZhbCA6XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTEwIC0gMTEgb25seVxuXHRcdFx0XHRcdC8vIG9wdGlvbi50ZXh0IHRocm93cyBleGNlcHRpb25zICh0cmFjLTE0Njg2LCB0cmFjLTE0ODU4KVxuXHRcdFx0XHRcdC8vIFN0cmlwIGFuZCBjb2xsYXBzZSB3aGl0ZXNwYWNlXG5cdFx0XHRcdFx0Ly8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jc3RyaXAtYW5kLWNvbGxhcHNlLXdoaXRlc3BhY2Vcblx0XHRcdFx0XHRzdHJpcEFuZENvbGxhcHNlKCBqUXVlcnkudGV4dCggZWxlbSApICk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRzZWxlY3Q6IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciB2YWx1ZSwgb3B0aW9uLCBpLFxuXHRcdFx0XHRcdG9wdGlvbnMgPSBlbGVtLm9wdGlvbnMsXG5cdFx0XHRcdFx0aW5kZXggPSBlbGVtLnNlbGVjdGVkSW5kZXgsXG5cdFx0XHRcdFx0b25lID0gZWxlbS50eXBlID09PSBcInNlbGVjdC1vbmVcIixcblx0XHRcdFx0XHR2YWx1ZXMgPSBvbmUgPyBudWxsIDogW10sXG5cdFx0XHRcdFx0bWF4ID0gb25lID8gaW5kZXggKyAxIDogb3B0aW9ucy5sZW5ndGg7XG5cblx0XHRcdFx0aWYgKCBpbmRleCA8IDAgKSB7XG5cdFx0XHRcdFx0aSA9IG1heDtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGkgPSBvbmUgPyBpbmRleCA6IDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBMb29wIHRocm91Z2ggYWxsIHRoZSBzZWxlY3RlZCBvcHRpb25zXG5cdFx0XHRcdGZvciAoIDsgaSA8IG1heDsgaSsrICkge1xuXHRcdFx0XHRcdG9wdGlvbiA9IG9wdGlvbnNbIGkgXTtcblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG5cdFx0XHRcdFx0Ly8gSUU4LTkgZG9lc24ndCB1cGRhdGUgc2VsZWN0ZWQgYWZ0ZXIgZm9ybSByZXNldCAodHJhYy0yNTUxKVxuXHRcdFx0XHRcdGlmICggKCBvcHRpb24uc2VsZWN0ZWQgfHwgaSA9PT0gaW5kZXggKSAmJlxuXG5cdFx0XHRcdFx0XHRcdC8vIERvbid0IHJldHVybi
1BvcHRpb25zIHRoYXQgYXJlIGRpc2FibGVkIG9yIGluIGEgZGlzYWJsZWQgb3B0Z3JvdXBcblx0XHRcdFx0XHRcdFx0IW9wdGlvbi5kaXNhYmxlZCAmJlxuXHRcdFx0XHRcdFx0XHQoICFvcHRpb24ucGFyZW50Tm9kZS5kaXNhYmxlZCB8fFxuXHRcdFx0XHRcdFx0XHRcdCFub2RlTmFtZSggb3B0aW9uLnBhcmVudE5vZGUsIFwib3B0Z3JvdXBcIiApICkgKSB7XG5cblx0XHRcdFx0XHRcdC8vIEdldCB0aGUgc3BlY2lmaWMgdmFsdWUgZm9yIHRoZSBvcHRpb25cblx0XHRcdFx0XHRcdHZhbHVlID0galF1ZXJ5KCBvcHRpb24gKS52YWwoKTtcblxuXHRcdFx0XHRcdFx0Ly8gV2UgZG9uJ3QgbmVlZCBhbiBhcnJheSBmb3Igb25lIHNlbGVjdHNcblx0XHRcdFx0XHRcdGlmICggb25lICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIE11bHRpLVNlbGVjdHMgcmV0dXJuIGFuIGFycmF5XG5cdFx0XHRcdFx0XHR2YWx1ZXMucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdmFsdWVzO1xuXHRcdFx0fSxcblxuXHRcdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0XHRcdHZhciBvcHRpb25TZXQsIG9wdGlvbixcblx0XHRcdFx0XHRvcHRpb25zID0gZWxlbS5vcHRpb25zLFxuXHRcdFx0XHRcdHZhbHVlcyA9IGpRdWVyeS5tYWtlQXJyYXkoIHZhbHVlICksXG5cdFx0XHRcdFx0aSA9IG9wdGlvbnMubGVuZ3RoO1xuXG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdG9wdGlvbiA9IG9wdGlvbnNbIGkgXTtcblxuXHRcdFx0XHRcdC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbmQtYXNzaWduICovXG5cblx0XHRcdFx0XHRpZiAoIG9wdGlvbi5zZWxlY3RlZCA9XG5cdFx0XHRcdFx0XHRqUXVlcnkuaW5BcnJheSggalF1ZXJ5LnZhbEhvb2tzLm9wdGlvbi5nZXQoIG9wdGlvbiApLCB2YWx1ZXMgKSA+IC0xXG5cdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRvcHRpb25TZXQgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8qIGVzbGludC1lbmFibGUgbm8tY29uZC1hc3NpZ24gKi9cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEZvcmNlIGJyb3dzZXJzIHRvIGJlaGF2ZSBjb25zaXN0ZW50bHkgd2hlbiBub24tbWF0Y2hpbmcgdmFsdWUgaXMgc2V0XG5cdFx0XHRcdGlmICggIW9wdGlvblNldCApIHtcblx0XHRcdFx0XHRlbGVtLnNlbGVjdGVkSW5kZXggPSAtMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdmFsdWVzO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufSApO1xuXG4vLyBSYWRpb3MgYW5kIGNoZWNrYm94ZXMgZ2V0dGVyL3NldHRlclxualF1ZXJ5LmVhY2goIFsgXCJyYWRpb1wiLCBcImNoZWNrYm94XCIgXSwgZnVuY3Rpb24oKSB7XG5cdGpRdWVyeS52YWxIb29rc1sgdGhpcyBdID0ge1xuXHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCB2YWx1ZSApICkge1xuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLmNoZWNrZWQgPSBqUXVlcnkuaW5BcnJheSggalF1ZXJ5KCBlbGVtICkudmFsKCksIHZhbHVlICkgPiAtMSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0aWYgKCAhc3VwcG9ydC5jaGVja09uICkge1xuXHRcdGpRdWVyeS52YWxIb29rc1sgdGhpcyBdLmdldCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCBcInZhbHVlXCIgKSA9PT0gbnVsbCA/IFwib25cIiA6IGVsZW0udmFsdWU7XG5cdFx0fTtcblx0fVxufSApO1xuXG5cblxuXG4vLyBSZXR1cm4galF1ZXJ5IGZvciBhdHRyaWJ1dGVzLW9ubHkgaW5jbHVzaW9uXG52YXIgbG9jYXRpb24gPSB3aW5kb3cubG9jYXRpb247XG5cbnZhciBub25jZSA9IHsgZ3VpZDogRGF0ZS5ub3coKSB9O1xuXG52YXIgcnF1ZXJ5ID0gKCAvXFw/LyApO1xuXG5cblxuLy8gQ3Jvc3MtYnJvd3NlciB4bWwgcGFyc2luZ1xualF1ZXJ5LnBhcnNlWE1MID0gZnVuY3Rpb24oIGRhdGEgKSB7XG5cdHZhciB4bWwsIHBhcnNlckVycm9yRWxlbTtcblx0aWYgKCAhZGF0YSB8fCB0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5XG5cdC8vIElFIHRocm93cyBvbiBwYXJzZUZyb21TdHJpbmcgd2l0aCBpbnZhbGlkIGlucHV0LlxuXHR0cnkge1xuXHRcdHhtbCA9ICggbmV3IHdpbmRvdy5ET01QYXJzZXIoKSApLnBhcnNlRnJvbVN0cmluZyggZGF0YSwgXCJ0ZXh0L3htbFwiICk7XG5cdH0gY2F0Y2ggKCBlICkge31cblxuXHRwYXJzZXJFcnJvckVsZW0gPSB4bWwgJiYgeG1sLmdldEVsZW1lbnRzQnlUYWdOYW1lKCBcInBhcnNlcmVycm9yXCIgKVsgMCBdO1xuXHRpZiAoICF4bWwgfHwgcGFyc2VyRXJyb3JFbGVtICkge1xuXHRcdGpRdWVyeS5lcnJvciggXCJJbnZhbGlkIFhNTDogXCIgKyAoXG5cdFx0XHRwYXJzZXJFcnJvckVsZW0gP1xuXHRcdFx0XHRqUXVlcnkubWFwKCBwYXJzZXJFcnJvckVsZW0uY2hpbGROb2RlcywgZnVuY3Rpb24oIGVsICkge1xuXHRcdFx0XHRcdHJldHVybiBlbC50ZXh0Q29udGVudDtcblx0XHRcdFx0fSApLmpvaW4oIFwiXFxuXCIgKSA6XG5cdFx0XHRcdGRhdGFcblx0XHQpICk7XG5cdH1cblx0cmV0dXJuIHhtbDtcbn07XG5cblxudmFyIHJmb2N1c01vcnBoID0gL14oPzpmb2N1c2luZm9jdXN8Zm9jdXNvdXRibHVyKSQvLFxuXHRzdG9wUHJvcGFnYXRpb25DYWxsYmFjayA9IGZ1bmN0aW9uKCBlICkge1xuXHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdH07XG5cbmpRdWVyeS5leHRlbmQoIGpRdWVyeS5ldmVudCwge1xuXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCBldmVudCwgZGF0YSwgZWxlbSwgb25seUhhbmRsZXJzICkge1xuXG5cdFx0dmFyIGksIGN1ciwgdG1wLCBidWJibGVUeXBlLCBvbnR5cGUsIGhhbmRsZSwgc3BlY2lhbCwgbGFzdEVsZW1lbnQsXG5cdFx0XHRldmVudFBhdGggPSBbIGVsZW0gfHwgZG9jdW1lbnQgXSxcblx0XHRcdHR5cGUgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwidHlwZVwiICkgPyBldmVudC50eXBlIDogZXZlbnQsXG5cdFx0XHRuYW1lc3BhY2VzID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcIm5hbWVzcGFjZVwiICkgPyBldmVudC5uYW1lc3BhY2Uuc3BsaXQoIFwiLlwiICkgOiBbXTtcblxuXHRcdGN1ciA9IGxhc3RFbGVtZW50ID0gdG1wID0gZWxlbSA9IGVsZW0gfHwgZG9jdW1lbnQ7XG5cblx0XHQvLyBEb24ndCBkbyBldmVudHMgb24gdGV4dCBhbmQgY29tbWVudCBub2Rlc1xuXHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGZvY3VzL2JsdXIgbW9ycGhzIHRvIGZvY3VzaW4vb3V0OyBlbnN1cmUgd2UncmUgbm90IGZpcmluZyB0aGVtIHJpZ2h0IG5vd1xuXHRcdGlmICggcmZvY3VzTW9ycGgudGVzdCggdHlwZSArIGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgKSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIHR5cGUuaW5kZXhPZiggXCIuXCIgKSA+IC0xICkge1xuXG5cdFx0XHQvLyBOYW1lc3BhY2VkIHRyaWdnZXI7IGNyZWF0ZSBhIHJlZ2V4cCB0byBtYXRjaCBldmVudCB0eX
1BlIGluIGhhbmRsZSgpXG5cdFx0XHRuYW1lc3BhY2VzID0gdHlwZS5zcGxpdCggXCIuXCIgKTtcblx0XHRcdHR5cGUgPSBuYW1lc3BhY2VzLnNoaWZ0KCk7XG5cdFx0XHRuYW1lc3BhY2VzLnNvcnQoKTtcblx0XHR9XG5cdFx0b250eXBlID0gdHlwZS5pbmRleE9mKCBcIjpcIiApIDwgMCAmJiBcIm9uXCIgKyB0eXBlO1xuXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGEgalF1ZXJ5LkV2ZW50IG9iamVjdCwgT2JqZWN0LCBvciBqdXN0IGFuIGV2ZW50IHR5cGUgc3RyaW5nXG5cdFx0ZXZlbnQgPSBldmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XG5cdFx0XHRldmVudCA6XG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCB0eXBlLCB0eXBlb2YgZXZlbnQgPT09IFwib2JqZWN0XCIgJiYgZXZlbnQgKTtcblxuXHRcdC8vIFRyaWdnZXIgYml0bWFzazogJiAxIGZvciBuYXRpdmUgaGFuZGxlcnM7ICYgMiBmb3IgalF1ZXJ5IChhbHdheXMgdHJ1ZSlcblx0XHRldmVudC5pc1RyaWdnZXIgPSBvbmx5SGFuZGxlcnMgPyAyIDogMztcblx0XHRldmVudC5uYW1lc3BhY2UgPSBuYW1lc3BhY2VzLmpvaW4oIFwiLlwiICk7XG5cdFx0ZXZlbnQucm5hbWVzcGFjZSA9IGV2ZW50Lm5hbWVzcGFjZSA/XG5cdFx0XHRuZXcgUmVnRXhwKCBcIihefFxcXFwuKVwiICsgbmFtZXNwYWNlcy5qb2luKCBcIlxcXFwuKD86LipcXFxcLnwpXCIgKSArIFwiKFxcXFwufCQpXCIgKSA6XG5cdFx0XHRudWxsO1xuXG5cdFx0Ly8gQ2xlYW4gdXAgdGhlIGV2ZW50IGluIGNhc2UgaXQgaXMgYmVpbmcgcmV1c2VkXG5cdFx0ZXZlbnQucmVzdWx0ID0gdW5kZWZpbmVkO1xuXHRcdGlmICggIWV2ZW50LnRhcmdldCApIHtcblx0XHRcdGV2ZW50LnRhcmdldCA9IGVsZW07XG5cdFx0fVxuXG5cdFx0Ly8gQ2xvbmUgYW55IGluY29taW5nIGRhdGEgYW5kIHByZXBlbmQgdGhlIGV2ZW50LCBjcmVhdGluZyB0aGUgaGFuZGxlciBhcmcgbGlzdFxuXHRcdGRhdGEgPSBkYXRhID09IG51bGwgP1xuXHRcdFx0WyBldmVudCBdIDpcblx0XHRcdGpRdWVyeS5tYWtlQXJyYXkoIGRhdGEsIFsgZXZlbnQgXSApO1xuXG5cdFx0Ly8gQWxsb3cgc3BlY2lhbCBldmVudHMgdG8gZHJhdyBvdXRzaWRlIHRoZSBsaW5lc1xuXHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiBzcGVjaWFsLnRyaWdnZXIgJiYgc3BlY2lhbC50cmlnZ2VyLmFwcGx5KCBlbGVtLCBkYXRhICkgPT09IGZhbHNlICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIERldGVybWluZSBldmVudCBwcm9wYWdhdGlvbiBwYXRoIGluIGFkdmFuY2UsIHBlciBXM0MgZXZlbnRzIHNwZWMgKHRyYWMtOTk1MSlcblx0XHQvLyBCdWJibGUgdXAgdG8gZG9jdW1lbnQsIHRoZW4gdG8gd2luZG93OyB3YXRjaCBmb3IgYSBnbG9iYWwgb3duZXJEb2N1bWVudCB2YXIgKHRyYWMtOTcyNClcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgIXNwZWNpYWwubm9CdWJibGUgJiYgIWlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdGJ1YmJsZVR5cGUgPSBzcGVjaWFsLmRlbGVnYXRlVHlwZSB8fCB0eXBlO1xuXHRcdFx0aWYgKCAhcmZvY3VzTW9ycGgudGVzdCggYnViYmxlVHlwZSArIHR5cGUgKSApIHtcblx0XHRcdFx0Y3VyID0gY3VyLnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cdFx0XHRmb3IgKCA7IGN1cjsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGV2ZW50UGF0aC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0dG1wID0gY3VyO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPbmx5IGFkZCB3aW5kb3cgaWYgd2UgZ290IHRvIGRvY3VtZW50IChlLmcuLCBub3QgcGxhaW4gb2JqIG9yIGRldGFjaGVkIERPTSlcblx0XHRcdGlmICggdG1wID09PSAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudCApICkge1xuXHRcdFx0XHRldmVudFBhdGgucHVzaCggdG1wLmRlZmF1bHRWaWV3IHx8IHRtcC5wYXJlbnRXaW5kb3cgfHwgd2luZG93ICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRmlyZSBoYW5kbGVycyBvbiB0aGUgZXZlbnQgcGF0aFxuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKCBjdXIgPSBldmVudFBhdGhbIGkrKyBdICkgJiYgIWV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cdFx0XHRsYXN0RWxlbWVudCA9IGN1cjtcblx0XHRcdGV2ZW50LnR5cGUgPSBpID4gMSA/XG5cdFx0XHRcdGJ1YmJsZVR5cGUgOlxuXHRcdFx0XHRzcGVjaWFsLmJpbmRUeXBlIHx8IHR5cGU7XG5cblx0XHRcdC8vIGpRdWVyeSBoYW5kbGVyXG5cdFx0XHRoYW5kbGUgPSAoIGRhdGFQcml2LmdldCggY3VyLCBcImV2ZW50c1wiICkgfHwgT2JqZWN0LmNyZWF0ZSggbnVsbCApIClbIGV2ZW50LnR5cGUgXSAmJlxuXHRcdFx0XHRkYXRhUHJpdi5nZXQoIGN1ciwgXCJoYW5kbGVcIiApO1xuXHRcdFx0aWYgKCBoYW5kbGUgKSB7XG5cdFx0XHRcdGhhbmRsZS5hcHBseSggY3VyLCBkYXRhICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE5hdGl2ZSBoYW5kbGVyXG5cdFx0XHRoYW5kbGUgPSBvbnR5cGUgJiYgY3VyWyBvbnR5cGUgXTtcblx0XHRcdGlmICggaGFuZGxlICYmIGhhbmRsZS5hcHBseSAmJiBhY2NlcHREYXRhKCBjdXIgKSApIHtcblx0XHRcdFx0ZXZlbnQucmVzdWx0ID0gaGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTtcblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0ZXZlbnQudHlwZSA9IHR5cGU7XG5cblx0XHQvLyBJZiBub2JvZHkgcHJldmVudGVkIHRoZSBkZWZhdWx0IGFjdGlvbiwgZG8gaXQgbm93XG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmICFldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApIHtcblxuXHRcdFx0aWYgKCAoICFzcGVjaWFsLl9kZWZhdWx0IHx8XG5cdFx0XHRcdHNwZWNpYWwuX2RlZmF1bHQuYXBwbHkoIGV2ZW50UGF0aC5wb3AoKSwgZGF0YSApID09PSBmYWxzZSApICYmXG5cdFx0XHRcdGFjY2VwdERhdGEoIGVsZW0gKSApIHtcblxuXHRcdFx0XHQvLyBDYWxsIGEgbmF0aXZlIERPTSBtZXRob2Qgb24gdGhlIHRhcmdldCB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGV2ZW50LlxuXHRcdFx0XHQvLyBEb24ndCBkbyBkZWZhdWx0IGFjdGlvbnMgb24gd2luZG93LCB0aGF0J3Mgd2hlcmUgZ2xvYmFsIHZhcmlhYmxlcyBiZSAodHJhYy02MTcwKVxuXHRcdFx0XHRpZiAoIG9udHlwZSAmJiBpc0Z1bmN0aW9uKCBlbGVtWyB0eXBlIF0gKSAmJiAhaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0XHRcdC8vIERvbid0IHJlLXRyaWdnZXIgYW4gb25GT08gZXZlbnQgd2hlbiB3ZSBjYWxsIGl0cyBGT08oKSBtZXRob2Rcblx0XHRcdFx0XHR0bXAgPSBlbGVtWyBvbnR5cGUgXTtcblxuXHRcdFx0XHRcdGlmICggdG1wICkge1xuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSBudWxsO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFByZXZlbnQgcmUtdHJpZ2dlcmluZyBvZiB0aGUgc2FtZSBldmVudCwgc2luY2Ugd2UgYWxyZWFkeSBidWJibGVkIGl0IGFib3ZlXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHR5cGU7XG5cblx0XHRcdFx0XHRpZiAoIGV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cdFx0XHRcdFx0XHRsYXN0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCB0eXBlLCBzdG9wUHJvcGFnYXRpb25DYWxsYmFjayApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGVsZW1bIHR5cGUgXSgpO1xuXG5cdFx0XHRcdFx0aWYgKCBldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0XHRcdFx0bGFzdEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgc3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRcdFx0aWYgKCB0bXAgKSB7XG5cdFx0XHRcdFx0XHRlbGVtWyBvbnR5cGUgXSA9IHRtcDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xuXHR9LFxuXG5cdC8vIFBpZ2d5YmFjayBvbiBhIGRvbm9yIGV2ZW50IHRvIHNpbXVsYXRlIGEgZGlmZmVyZW50IG9uZVxuXHQvLyBVc2VkIG9ubHkgZm9yIGBmb2N1cyhpbiB8IG91dClgIGV2ZW50c1xuXHRzaW11bGF0ZTogZnVuY3Rpb24oIHR5cGUsIGVsZW0sIGV2ZW50ICkge1xuXHRcdHZhciBlID0galF1ZXJ5LmV4dGVuZChcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoKSxcblx0XHRcdGV2ZW50LFxuXHRcdFx0e1xuXHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRpc1NpbXVsYXRlZDogdHJ1ZVxuXHRcdFx0fVxuXHRcdCk7XG5cblx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggZSwgbnVsbCwgZWxlbSApO1xuXHR9XG5cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHJldHVybi
1B0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIHRoaXMgKTtcblx0XHR9ICk7XG5cdH0sXG5cdHRyaWdnZXJIYW5kbGVyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgZWxlbSA9IHRoaXNbIDAgXTtcblx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIGVsZW0sIHRydWUgKTtcblx0XHR9XG5cdH1cbn0gKTtcblxuXG52YXJcblx0cmJyYWNrZXQgPSAvXFxbXFxdJC8sXG5cdHJDUkxGID0gL1xccj9cXG4vZyxcblx0cnN1Ym1pdHRlclR5cGVzID0gL14oPzpzdWJtaXR8YnV0dG9ufGltYWdlfHJlc2V0fGZpbGUpJC9pLFxuXHRyc3VibWl0dGFibGUgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxrZXlnZW4pL2k7XG5cbmZ1bmN0aW9uIGJ1aWxkUGFyYW1zKCBwcmVmaXgsIG9iaiwgdHJhZGl0aW9uYWwsIGFkZCApIHtcblx0dmFyIG5hbWU7XG5cblx0aWYgKCBBcnJheS5pc0FycmF5KCBvYmogKSApIHtcblxuXHRcdC8vIFNlcmlhbGl6ZSBhcnJheSBpdGVtLlxuXHRcdGpRdWVyeS5lYWNoKCBvYmosIGZ1bmN0aW9uKCBpLCB2ICkge1xuXHRcdFx0aWYgKCB0cmFkaXRpb25hbCB8fCByYnJhY2tldC50ZXN0KCBwcmVmaXggKSApIHtcblxuXHRcdFx0XHQvLyBUcmVhdCBlYWNoIGFycmF5IGl0ZW0gYXMgYSBzY2FsYXIuXG5cdFx0XHRcdGFkZCggcHJlZml4LCB2ICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gSXRlbSBpcyBub24tc2NhbGFyIChhcnJheSBvciBvYmplY3QpLCBlbmNvZGUgaXRzIG51bWVyaWMgaW5kZXguXG5cdFx0XHRcdGJ1aWxkUGFyYW1zKFxuXHRcdFx0XHRcdHByZWZpeCArIFwiW1wiICsgKCB0eXBlb2YgdiA9PT0gXCJvYmplY3RcIiAmJiB2ICE9IG51bGwgPyBpIDogXCJcIiApICsgXCJdXCIsXG5cdFx0XHRcdFx0dixcblx0XHRcdFx0XHR0cmFkaXRpb25hbCxcblx0XHRcdFx0XHRhZGRcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9ICk7XG5cblx0fSBlbHNlIGlmICggIXRyYWRpdGlvbmFsICYmIHRvVHlwZSggb2JqICkgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHQvLyBTZXJpYWxpemUgb2JqZWN0IGl0ZW0uXG5cdFx0Zm9yICggbmFtZSBpbiBvYmogKSB7XG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4ICsgXCJbXCIgKyBuYW1lICsgXCJdXCIsIG9ialsgbmFtZSBdLCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0fVxuXG5cdH0gZWxzZSB7XG5cblx0XHQvLyBTZXJpYWxpemUgc2NhbGFyIGl0ZW0uXG5cdFx0YWRkKCBwcmVmaXgsIG9iaiApO1xuXHR9XG59XG5cbi8vIFNlcmlhbGl6ZSBhbiBhcnJheSBvZiBmb3JtIGVsZW1lbnRzIG9yIGEgc2V0IG9mXG4vLyBrZXkvdmFsdWVzIGludG8gYSBxdWVyeSBzdHJpbmdcbmpRdWVyeS5wYXJhbSA9IGZ1bmN0aW9uKCBhLCB0cmFkaXRpb25hbCApIHtcblx0dmFyIHByZWZpeCxcblx0XHRzID0gW10sXG5cdFx0YWRkID0gZnVuY3Rpb24oIGtleSwgdmFsdWVPckZ1bmN0aW9uICkge1xuXG5cdFx0XHQvLyBJZiB2YWx1ZSBpcyBhIGZ1bmN0aW9uLCBpbnZva2UgaXQgYW5kIHVzZSBpdHMgcmV0dXJuIHZhbHVlXG5cdFx0XHR2YXIgdmFsdWUgPSBpc0Z1bmN0aW9uKCB2YWx1ZU9yRnVuY3Rpb24gKSA/XG5cdFx0XHRcdHZhbHVlT3JGdW5jdGlvbigpIDpcblx0XHRcdFx0dmFsdWVPckZ1bmN0aW9uO1xuXG5cdFx0XHRzWyBzLmxlbmd0aCBdID0gZW5jb2RlVVJJQ29tcG9uZW50KCBrZXkgKSArIFwiPVwiICtcblx0XHRcdFx0ZW5jb2RlVVJJQ29tcG9uZW50KCB2YWx1ZSA9PSBudWxsID8gXCJcIiA6IHZhbHVlICk7XG5cdFx0fTtcblxuXHRpZiAoIGEgPT0gbnVsbCApIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXG5cdC8vIElmIGFuIGFycmF5IHdhcyBwYXNzZWQgaW4sIGFzc3VtZSB0aGF0IGl0IGlzIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMuXG5cdGlmICggQXJyYXkuaXNBcnJheSggYSApIHx8ICggYS5qcXVlcnkgJiYgIWpRdWVyeS5pc1BsYWluT2JqZWN0KCBhICkgKSApIHtcblxuXHRcdC8vIFNlcmlhbGl6ZSB0aGUgZm9ybSBlbGVtZW50c1xuXHRcdGpRdWVyeS5lYWNoKCBhLCBmdW5jdGlvbigpIHtcblx0XHRcdGFkZCggdGhpcy5uYW1lLCB0aGlzLnZhbHVlICk7XG5cdFx0fSApO1xuXG5cdH0gZWxzZSB7XG5cblx0XHQvLyBJZiB0cmFkaXRpb25hbCwgZW5jb2RlIHRoZSBcIm9sZFwiIHdheSAodGhlIHdheSAxLjMuMiBvciBvbGRlclxuXHRcdC8vIGRpZCBpdCksIG90aGVyd2lzZSBlbmNvZGUgcGFyYW1zIHJlY3Vyc2l2ZWx5LlxuXHRcdGZvciAoIHByZWZpeCBpbiBhICkge1xuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCwgYVsgcHJlZml4IF0sIHRyYWRpdGlvbmFsLCBhZGQgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIHJlc3VsdGluZyBzZXJpYWxpemF0aW9uXG5cdHJldHVybiBzLmpvaW4oIFwiJlwiICk7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHNlcmlhbGl6ZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5wYXJhbSggdGhpcy5zZXJpYWxpemVBcnJheSgpICk7XG5cdH0sXG5cdHNlcmlhbGl6ZUFycmF5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBDYW4gYWRkIHByb3BIb29rIGZvciBcImVsZW1lbnRzXCIgdG8gZmlsdGVyIG9yIGFkZCBmb3JtIGVsZW1lbnRzXG5cdFx0XHR2YXIgZWxlbWVudHMgPSBqUXVlcnkucHJvcCggdGhpcywgXCJlbGVtZW50c1wiICk7XG5cdFx0XHRyZXR1cm4gZWxlbWVudHMgPyBqUXVlcnkubWFrZUFycmF5KCBlbGVtZW50cyApIDogdGhpcztcblx0XHR9ICkuZmlsdGVyKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciB0eXBlID0gdGhpcy50eXBlO1xuXG5cdFx0XHQvLyBVc2UgLmlzKCBcIjpkaXNhYmxlZFwiICkgc28gdGhhdCBmaWVsZHNldFtkaXNhYmxlZF0gd29ya3Ncblx0XHRcdHJldHVybiB0aGlzLm5hbWUgJiYgIWpRdWVyeSggdGhpcyApLmlzKCBcIjpkaXNhYmxlZFwiICkgJiZcblx0XHRcdFx0cnN1Ym1pdHRhYmxlLnRlc3QoIHRoaXMubm9kZU5hbWUgKSAmJiAhcnN1Ym1pdHRlclR5cGVzLnRlc3QoIHR5cGUgKSAmJlxuXHRcdFx0XHQoIHRoaXMuY2hlY2tlZCB8fCAhcmNoZWNrYWJsZVR5cGUudGVzdCggdHlwZSApICk7XG5cdFx0fSApLm1hcCggZnVuY3Rpb24oIF9pLCBlbGVtICkge1xuXHRcdFx0dmFyIHZhbCA9IGpRdWVyeSggdGhpcyApLnZhbCgpO1xuXG5cdFx0XHRpZiAoIHZhbCA9PSBudWxsICkge1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF
15KCB2YWwgKSApIHtcblx0XHRcdFx0cmV0dXJuIGpRdWVyeS5tYXAoIHZhbCwgZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdFx0XHRyZXR1cm4geyBuYW1lOiBlbGVtLm5hbWUsIHZhbHVlOiB2YWwucmVwbGFjZSggckNSTEYsIFwiXFxyXFxuXCIgKSB9O1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XG5cdFx0fSApLmdldCgpO1xuXHR9XG59ICk7XG5cblxudmFyXG5cdHIyMCA9IC8lMjAvZyxcblx0cmhhc2ggPSAvIy4qJC8sXG5cdHJhbnRpQ2FjaGUgPSAvKFs/Jl0pXz1bXiZdKi8sXG5cdHJoZWFkZXJzID0gL14oLio/KTpbIFxcdF0qKFteXFxyXFxuXSopJC9tZyxcblxuXHQvLyB0cmFjLTc2NTMsIHRyYWMtODEyNSwgdHJhYy04MTUyOiBsb2NhbCBwcm90b2NvbCBkZXRlY3Rpb25cblx0cmxvY2FsUHJvdG9jb2wgPSAvXig/OmFib3V0fGFwcHxhcHAtc3RvcmFnZXwuKy1leHRlbnNpb258ZmlsZXxyZXN8d2lkZ2V0KTokLyxcblx0cm5vQ29udGVudCA9IC9eKD86R0VUfEhFQUQpJC8sXG5cdHJwcm90b2NvbCA9IC9eXFwvXFwvLyxcblxuXHQvKiBQcmVmaWx0ZXJzXG5cdCAqIDEpIFRoZXkgYXJlIHVzZWZ1bCB0byBpbnRyb2R1Y2UgY3VzdG9tIGRhdGFUeXBlcyAoc2VlIGFqYXgvanNvbnAuanMgZm9yIGFuIGV4YW1wbGUpXG5cdCAqIDIpIFRoZXNlIGFyZSBjYWxsZWQ6XG5cdCAqICAgIC0gQkVGT1JFIGFza2luZyBmb3IgYSB0cmFuc3BvcnRcblx0ICogICAgLSBBRlRFUiBwYXJhbSBzZXJpYWxpemF0aW9uIChzLmRhdGEgaXMgYSBzdHJpbmcgaWYgcy5wcm9jZXNzRGF0YSBpcyB0cnVlKVxuXHQgKiAzKSBrZXkgaXMgdGhlIGRhdGFUeXBlXG5cdCAqIDQpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcblx0ICogNSkgZXhlY3V0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gY29udGludWUgZG93biB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHByZWZpbHRlcnMgPSB7fSxcblxuXHQvKiBUcmFuc3BvcnRzIGJpbmRpbmdzXG5cdCAqIDEpIGtleSBpcyB0aGUgZGF0YVR5cGVcblx0ICogMikgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxuXHQgKiAzKSBzZWxlY3Rpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBnbyB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHRyYW5zcG9ydHMgPSB7fSxcblxuXHQvLyBBdm9pZCBjb21tZW50LXByb2xvZyBjaGFyIHNlcXVlbmNlICh0cmFjLTEwMDk4KTsgbXVzdCBhcHBlYXNlIGxpbnQgYW5kIGV2YWRlIGNvbXByZXNzaW9uXG5cdGFsbFR5cGVzID0gXCIqL1wiLmNvbmNhdCggXCIqXCIgKSxcblxuXHQvLyBBbmNob3IgdGFnIGZvciBwYXJzaW5nIHRoZSBkb2N1bWVudCBvcmlnaW5cblx0b3JpZ2luQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJhXCIgKTtcblxub3JpZ2luQW5jaG9yLmhyZWYgPSBsb2NhdGlvbi5ocmVmO1xuXG4vLyBCYXNlIFwiY29uc3RydWN0b3JcIiBmb3IgalF1ZXJ5LmFqYXhQcmVmaWx0ZXIgYW5kIGpRdWVyeS5hamF4VHJhbnNwb3J0XG5mdW5jdGlvbiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSApIHtcblxuXHQvLyBkYXRhVHlwZUV4cHJlc3Npb24gaXMgb3B0aW9uYWwgYW5kIGRlZmF1bHRzIHRvIFwiKlwiXG5cdHJldHVybiBmdW5jdGlvbiggZGF0YVR5cGVFeHByZXNzaW9uLCBmdW5jICkge1xuXG5cdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVFeHByZXNzaW9uICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0ZnVuYyA9IGRhdGFUeXBlRXhwcmVzc2lvbjtcblx0XHRcdGRhdGFUeXBlRXhwcmVzc2lvbiA9IFwiKlwiO1xuXHRcdH1cblxuXHRcdHZhciBkYXRhVHlwZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0ZGF0YVR5cGVzID0gZGF0YVR5cGVFeHByZXNzaW9uLnRvTG93ZXJDYXNlKCkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbXTtcblxuXHRcdGlmICggaXNGdW5jdGlvbiggZnVuYyApICkge1xuXG5cdFx0XHQvLyBGb3IgZWFjaCBkYXRhVHlwZSBpbiB0aGUgZGF0YVR5cGVFeHByZXNzaW9uXG5cdFx0XHR3aGlsZSAoICggZGF0YVR5cGUgPSBkYXRhVHlwZXNbIGkrKyBdICkgKSB7XG5cblx0XHRcdFx0Ly8gUHJlcGVuZCBpZiByZXF1ZXN0ZWRcblx0XHRcdFx0aWYgKCBkYXRhVHlwZVsgMCBdID09PSBcIitcIiApIHtcblx0XHRcdFx0XHRkYXRhVHlwZSA9IGRhdGFUeXBlLnNsaWNlKCAxICkgfHwgXCIqXCI7XG5cdFx0XHRcdFx0KCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gPSBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10gKS51bnNoaWZ0KCBmdW5jICk7XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdCggc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdICkucHVzaCggZnVuYyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xufVxuXG4vLyBCYXNlIGluc3BlY3Rpb24gZnVuY3Rpb24gZm9yIHByZWZpbHRlcnMgYW5kIHRyYW5zcG9ydHNcbmZ1bmN0aW9uIGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBzdHJ1Y3R1cmUsIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKSB7XG5cblx0dmFyIGluc3BlY3RlZCA9IHt9LFxuXHRcdHNlZWtpbmdUcmFuc3BvcnQgPSAoIHN0cnVjdHVyZSA9PT0gdHJhbnNwb3J0cyApO1xuXG5cdGZ1bmN0aW9uIGluc3BlY3QoIGRhdGFUeXBlICkge1xuXHRcdHZhciBzZWxlY3RlZDtcblx0XHRpbnNwZWN0ZWRbIGRhdGFUeXBlIF0gPSB0cnVlO1xuXHRcdGpRdWVyeS5lYWNoKCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10sIGZ1bmN0aW9uKCBfLCBwcmVmaWx0ZXJPckZhY3RvcnkgKSB7XG5cdFx0XHR2YXIgZGF0YVR5cGVPclRyYW5zcG9ydCA9IHByZWZpbHRlck9yRmFjdG9yeSggb3B0aW9ucywgb3JpZ2luYWxPcHRpb25zLCBqcVhIUiApO1xuXHRcdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVPclRyYW5zcG9ydCA9PT0gXCJzdHJpbmdcIiAmJlxuXHRcdFx0XHQhc2Vla2luZ1RyYW5zcG9ydCAmJiAhaW5zcGVjdGVkWyBkYXRhV
1HlwZU9yVHJhbnNwb3J0IF0gKSB7XG5cblx0XHRcdFx0b3B0aW9ucy5kYXRhVHlwZXMudW5zaGlmdCggZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0XHRpbnNwZWN0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0gZWxzZSBpZiAoIHNlZWtpbmdUcmFuc3BvcnQgKSB7XG5cdFx0XHRcdHJldHVybiAhKCBzZWxlY3RlZCA9IGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdFx0cmV0dXJuIHNlbGVjdGVkO1xuXHR9XG5cblx0cmV0dXJuIGluc3BlY3QoIG9wdGlvbnMuZGF0YVR5cGVzWyAwIF0gKSB8fCAhaW5zcGVjdGVkWyBcIipcIiBdICYmIGluc3BlY3QoIFwiKlwiICk7XG59XG5cbi8vIEEgc3BlY2lhbCBleHRlbmQgZm9yIGFqYXggb3B0aW9uc1xuLy8gdGhhdCB0YWtlcyBcImZsYXRcIiBvcHRpb25zIChub3QgdG8gYmUgZGVlcCBleHRlbmRlZClcbi8vIEZpeGVzIHRyYWMtOTg4N1xuZnVuY3Rpb24gYWpheEV4dGVuZCggdGFyZ2V0LCBzcmMgKSB7XG5cdHZhciBrZXksIGRlZXAsXG5cdFx0ZmxhdE9wdGlvbnMgPSBqUXVlcnkuYWpheFNldHRpbmdzLmZsYXRPcHRpb25zIHx8IHt9O1xuXG5cdGZvciAoIGtleSBpbiBzcmMgKSB7XG5cdFx0aWYgKCBzcmNbIGtleSBdICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHQoIGZsYXRPcHRpb25zWyBrZXkgXSA/IHRhcmdldCA6ICggZGVlcCB8fCAoIGRlZXAgPSB7fSApICkgKVsga2V5IF0gPSBzcmNbIGtleSBdO1xuXHRcdH1cblx0fVxuXHRpZiAoIGRlZXAgKSB7XG5cdFx0alF1ZXJ5LmV4dGVuZCggdHJ1ZSwgdGFyZ2V0LCBkZWVwICk7XG5cdH1cblxuXHRyZXR1cm4gdGFyZ2V0O1xufVxuXG4vKiBIYW5kbGVzIHJlc3BvbnNlcyB0byBhbiBhamF4IHJlcXVlc3Q6XG4gKiAtIGZpbmRzIHRoZSByaWdodCBkYXRhVHlwZSAobWVkaWF0ZXMgYmV0d2VlbiBjb250ZW50LXR5cGUgYW5kIGV4cGVjdGVkIGRhdGFUeXBlKVxuICogLSByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHJlc3BvbnNlXG4gKi9cbmZ1bmN0aW9uIGFqYXhIYW5kbGVSZXNwb25zZXMoIHMsIGpxWEhSLCByZXNwb25zZXMgKSB7XG5cblx0dmFyIGN0LCB0eXBlLCBmaW5hbERhdGFUeXBlLCBmaXJzdERhdGFUeXBlLFxuXHRcdGNvbnRlbnRzID0gcy5jb250ZW50cyxcblx0XHRkYXRhVHlwZXMgPSBzLmRhdGFUeXBlcztcblxuXHQvLyBSZW1vdmUgYXV0byBkYXRhVHlwZSBhbmQgZ2V0IGNvbnRlbnQtdHlwZSBpbiB0aGUgcHJvY2Vzc1xuXHR3aGlsZSAoIGRhdGFUeXBlc1sgMCBdID09PSBcIipcIiApIHtcblx0XHRkYXRhVHlwZXMuc2hpZnQoKTtcblx0XHRpZiAoIGN0ID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRjdCA9IHMubWltZVR5cGUgfHwganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoIFwiQ29udGVudC1UeXBlXCIgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDaGVjayBpZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBrbm93biBjb250ZW50LXR5cGVcblx0aWYgKCBjdCApIHtcblx0XHRmb3IgKCB0eXBlIGluIGNvbnRlbnRzICkge1xuXHRcdFx0aWYgKCBjb250ZW50c1sgdHlwZSBdICYmIGNvbnRlbnRzWyB0eXBlIF0udGVzdCggY3QgKSApIHtcblx0XHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIHR5cGUgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2hlY2sgdG8gc2VlIGlmIHdlIGhhdmUgYSByZXNwb25zZSBmb3IgdGhlIGV4cGVjdGVkIGRhdGFUeXBlXG5cdGlmICggZGF0YVR5cGVzWyAwIF0gaW4gcmVzcG9uc2VzICkge1xuXHRcdGZpbmFsRGF0YVR5cGUgPSBkYXRhVHlwZXNbIDAgXTtcblx0fSBlbHNlIHtcblxuXHRcdC8vIFRyeSBjb252ZXJ0aWJsZSBkYXRhVHlwZXNcblx0XHRmb3IgKCB0eXBlIGluIHJlc3BvbnNlcyApIHtcblx0XHRcdGlmICggIWRhdGFUeXBlc1sgMCBdIHx8IHMuY29udmVydGVyc1sgdHlwZSArIFwiIFwiICsgZGF0YVR5cGVzWyAwIF0gXSApIHtcblx0XHRcdFx0ZmluYWxEYXRhVHlwZSA9IHR5cGU7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCAhZmlyc3REYXRhVHlwZSApIHtcblx0XHRcdFx0Zmlyc3REYXRhVHlwZSA9IHR5cGU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gT3IganVzdCB1c2UgZmlyc3Qgb25lXG5cdFx0ZmluYWxEYXRhVHlwZSA9IGZpbmFsRGF0YVR5cGUgfHwgZmlyc3REYXRhVHlwZTtcblx0fVxuXG5cdC8vIElmIHdlIGZvdW5kIGEgZGF0YVR5cGVcblx0Ly8gV2UgYWRkIHRoZSBkYXRhVHlwZSB0byB0aGUgbGlzdCBpZiBuZWVkZWRcblx0Ly8gYW5kIHJldHVybiB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxuXHRpZiAoIGZpbmFsRGF0YVR5cGUgKSB7XG5cdFx0aWYgKCBmaW5hbERhdGFUeXBlICE9PSBkYXRhVHlwZXNbIDAgXSApIHtcblx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCBmaW5hbERhdGFUeXBlICk7XG5cdFx0fVxuXHRcdHJldHVybiByZXNwb25zZXNbIGZpbmFsRGF0YVR5cGUgXTtcblx0fVxufVxuXG4vKiBDaGFpbiBjb252ZXJzaW9ucyBnaXZlbiB0aGUgcmVxdWVzdCBhbmQgdGhlIG9yaWdpbmFsIHJlc3BvbnNlXG4gKiBBbHNvIHNldHMgdGhlIHJlc3BvbnNlWFhYIGZpZWxkcyBvbiB0aGUganFYSFIgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gYWpheENvbnZlcnQoIHMsIHJlc3BvbnNlLCBqcVhIUiwgaXNTdWNjZXNzICkge1xuXHR2YXIgY29udjIsIGN1cnJlbnQsIGNvbnYsIHRtcCwgcHJldixcblx0XHRjb252ZXJ0ZXJzID0ge30sXG5cblx0XHQvLyBXb3JrIHdpdGggYSBjb3B5IG9mIGRhdGFUeXBlcyBpbiBjYXNlIHdlIG5lZWQgdG8gbW9kaWZ5IGl0IGZvciBjb252ZXJzaW9uXG5cdFx0ZGF0YVR5cGVzID0gcy5kYXRhVHlwZXMuc2xpY2UoKTtcblxuXHQvLyBDcmVhdGUgY29udmVydGVycyBtYXAgd2l0aCBsb3dlcmNhc2VkIGtleXNcblx0aWYgKCBkYXRhVHlwZXNbIDEgXSApIHtcblx0XHRmb3IgKCBjb252IGluIHMuY29udmVydGVycyApIHtcblx0XHRcdGNvbnZlcnRlcnNbIGNvbnYudG9Mb3dlckNhc2UoKSBdID0gcy5jb252ZXJ0ZXJzWyBjb252IF07XG5cdFx0fVxuXHR9XG5cblx0Y3VycmVudCA9IGRhdGFUeXBlcy5zaGlmdCgpO1xuXG5cdC8vIENvbnZlcnQgdG8gZWFjaCBzZXF1ZW50aWFsIGRhdGFUeXBlXG5cdHdoaWxlICggY3VycmVudCApIHtcblxuXHRcdGlmICggcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdICkge1xuXHRcdFx0anFYSFJbIHMucmVzcG9uc2VGaWVsZHNbIGN1cnJlbnQgXSBdID0gcmVzcG9uc2U7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgdGhlIGRhdGFGaWx0ZXIgaWYgcHJvdmlkZWRcblx0XHRpZiAoICFwcmV2ICYmIGlzU3VjY2VzcyAmJiBzLmRhdGFGaWx0ZXIgKSB7XG5cdFx0XHRyZXNwb25zZSA9IHMuZGF0YUZpbHRlciggcmVzcG9uc2UsIHMuZGF0YVR5cGUgKTtcblx0XHR9XG5cblx0XHRwcmV2ID0gY3VycmVudDtcblx0XHRjdXJyZW50ID0gZGF0YVR5cGVzLnNoaWZ0KCk7XG5cblx0XHRpZiAoIGN1cnJlbnQgKSB7XG5cblx0XHRcdC8vIFRoZXJlJ3Mgb25seSB3b3JrIHRvIGRvIGlmIGN1cnJlbnQgZGF0YVR5cGUgaXMgbm9uLWF1dG9cblx0XHRcdGlmICggY3VycmVudCA9PT0gXCIqXCIgKSB7XG5cblx0XHRcdFx0Y3VycmVudCA9IHByZXY7XG5cblx0XHRcdC8vIENvbnZlcnQgcmVzcG9uc2UgaWYgcHJldiBkYXRhVHlwZSBpcyBub24tYXV0byBhbmQgZGlmZmVycyBmcm9tIGN1cnJlbnRcblx0XHRcdH0gZWxzZSBpZiAoIHByZXYgIT09IFwiKlwiICYmIHByZXYgIT09IGN1cnJlbnQgKSB7XG5cblx0XHRcdFx0Ly8gU2VlayBhIGRpcmVjdCBjb252ZXJ0ZXJcblx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIHByZXYgKyBcIiBcIiArIGN1cnJlbnQgXSB8fCBjb252ZXJ0ZXJzWyBcIiogXCIgKyBjdXJyZW50IF07XG5cblx0XHRcdFx0Ly8gSWYgbm9uZSBmb3VuZCwgc2VlayBhIHBhaXJcblx0XHRcdFx0aWYgKCAhY29udiApIHtcblx0XHRcdFx0XHRmb3IgKCBjb252MiBpbiBjb252ZXJ0ZXJzICkge1xuXG5cdFx0XHRcdFx0XHQvLyBJZiBjb252MiBvdXRwdXRzIGN1cnJlbnRcblx0XHRcdFx0XHRcdHRtcCA9IGNvbnYyLnNwbGl0KCBcIiBcIiApO1xuXHRcdFx0XHRcdFx0aWYgKCB0bXBbIDEgXSA9PT0gY3VycmVudCApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBJZiBwcmV2IGNhbiBiZSBjb252ZXJ0ZWQgdG8gYWNjZXB0ZWQgaW5wdXRcblx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIHByZXYgKyBcIiBcIiArIHRtcFsgMCBdIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRjb252ZXJ0ZXJzWyBcIiogXCIgKyB0bXBbIDAgXSBdO1xuXHRcdFx0XHRcdFx0XHRpZiAoIGNvbnYgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBDb25kZW5zZSBlcXVpdmFsZW5jZSBjb252ZXJ0ZXJzXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBjb252ID09PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIGNvbnYyIF07XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBPdGhlcndpc2UsIGluc2VydCB0aGUgaW50ZXJtZWRpYXRlIGRhdGFUeXBlXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggY29udmVydGVyc1sgY29udjIgXSAhPT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGN1cnJlbnQgPSB0bXBbIDAgXTtcblx0XHRcdFx0XHRcdFx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCB0bXBbIDEgXSApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFwcGx5IGNvbnZlcnRlciAoaWYgbm90IGFuIGVxdWl2YWxlbmNlKVxuXHRcdFx0XHRpZiAoIGNvbnYgIT09IHRydWUgKSB7XG5cblx0XHRcdFx0XHQvLyBVbmxlc3MgZXJyb3JzIGFyZSBhbGxvd2VkIHRvIGJ1YmJsZSwgY2F0Y2ggYW5kIHJldHVybi
1B0aGVtXG5cdFx0XHRcdFx0aWYgKCBjb252ICYmIHMudGhyb3dzICkge1xuXHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7XG5cdFx0XHRcdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0XHRzdGF0ZTogXCJwYXJzZXJlcnJvclwiLFxuXHRcdFx0XHRcdFx0XHRcdGVycm9yOiBjb252ID8gZSA6IFwiTm8gY29udmVyc2lvbiBmcm9tIFwiICsgcHJldiArIFwiIHRvIFwiICsgY3VycmVudFxuXHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB7IHN0YXRlOiBcInN1Y2Nlc3NcIiwgZGF0YTogcmVzcG9uc2UgfTtcbn1cblxualF1ZXJ5LmV4dGVuZCgge1xuXG5cdC8vIENvdW50ZXIgZm9yIGhvbGRpbmcgdGhlIG51bWJlciBvZiBhY3RpdmUgcXVlcmllc1xuXHRhY3RpdmU6IDAsXG5cblx0Ly8gTGFzdC1Nb2RpZmllZCBoZWFkZXIgY2FjaGUgZm9yIG5leHQgcmVxdWVzdFxuXHRsYXN0TW9kaWZpZWQ6IHt9LFxuXHRldGFnOiB7fSxcblxuXHRhamF4U2V0dGluZ3M6IHtcblx0XHR1cmw6IGxvY2F0aW9uLmhyZWYsXG5cdFx0dHlwZTogXCJHRVRcIixcblx0XHRpc0xvY2FsOiBybG9jYWxQcm90b2NvbC50ZXN0KCBsb2NhdGlvbi5wcm90b2NvbCApLFxuXHRcdGdsb2JhbDogdHJ1ZSxcblx0XHRwcm9jZXNzRGF0YTogdHJ1ZSxcblx0XHRhc3luYzogdHJ1ZSxcblx0XHRjb250ZW50VHlwZTogXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLThcIixcblxuXHRcdC8qXG5cdFx0dGltZW91dDogMCxcblx0XHRkYXRhOiBudWxsLFxuXHRcdGRhdGFUeXBlOiBudWxsLFxuXHRcdHVzZXJuYW1lOiBudWxsLFxuXHRcdHBhc3N3b3JkOiBudWxsLFxuXHRcdGNhY2hlOiBudWxsLFxuXHRcdHRocm93czogZmFsc2UsXG5cdFx0dHJhZGl0aW9uYWw6IGZhbHNlLFxuXHRcdGhlYWRlcnM6IHt9LFxuXHRcdCovXG5cblx0XHRhY2NlcHRzOiB7XG5cdFx0XHRcIipcIjogYWxsVHlwZXMsXG5cdFx0XHR0ZXh0OiBcInRleHQvcGxhaW5cIixcblx0XHRcdGh0bWw6IFwidGV4dC9odG1sXCIsXG5cdFx0XHR4bWw6IFwiYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbFwiLFxuXHRcdFx0anNvbjogXCJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHRcIlxuXHRcdH0sXG5cblx0XHRjb250ZW50czoge1xuXHRcdFx0eG1sOiAvXFxieG1sXFxiLyxcblx0XHRcdGh0bWw6IC9cXGJodG1sLyxcblx0XHRcdGpzb246IC9cXGJqc29uXFxiL1xuXHRcdH0sXG5cblx0XHRyZXNwb25zZUZpZWxkczoge1xuXHRcdFx0eG1sOiBcInJlc3BvbnNlWE1MXCIsXG5cdFx0XHR0ZXh0OiBcInJlc3BvbnNlVGV4dFwiLFxuXHRcdFx0anNvbjogXCJyZXNwb25zZUpTT05cIlxuXHRcdH0sXG5cblx0XHQvLyBEYXRhIGNvbnZlcnRlcnNcblx0XHQvLyBLZXlzIHNlcGFyYXRlIHNvdXJjZSAob3IgY2F0Y2hhbGwgXCIqXCIpIGFuZCBkZXN0aW5hdGlvbiB0eXBlcyB3aXRoIGEgc2luZ2xlIHNwYWNlXG5cdFx0Y29udmVydGVyczoge1xuXG5cdFx0XHQvLyBDb252ZXJ0IGFueXRoaW5nIHRvIHRleHRcblx0XHRcdFwiKiB0ZXh0XCI6IFN0cmluZyxcblxuXHRcdFx0Ly8gVGV4dCB0byBodG1sICh0cnVlID0gbm8gdHJhbnNmb3JtYXRpb24pXG5cdFx0XHRcInRleHQgaHRtbFwiOiB0cnVlLFxuXG5cdFx0XHQvLyBFdmFsdWF0ZSB0ZXh0IGFzIGEganNvbiBleHByZXNzaW9uXG5cdFx0XHRcInRleHQganNvblwiOiBKU09OLnBhcnNlLFxuXG5cdFx0XHQvLyBQYXJzZSB0ZXh0IGFzIHhtbFxuXHRcdFx0XCJ0ZXh0IHhtbFwiOiBqUXVlcnkucGFyc2VYTUxcblx0XHR9LFxuXG5cdFx0Ly8gRm9yIG9wdGlvbnMgdGhhdCBzaG91bGRuJ3QgYmUgZGVlcCBleHRlbmRlZDpcblx0XHQvLyB5b3UgY2FuIGFkZCB5b3VyIG93biBjdXN0b20gb3B0aW9ucyBoZXJlIGlmXG5cdFx0Ly8gYW5kIHdoZW4geW91IGNyZWF0ZSBvbmUgdGhhdCBzaG91bGRuJ3QgYmVcblx0XHQvLyBkZWVwIGV4dGVuZGVkIChzZWUgYWpheEV4dGVuZClcblx0XHRmbGF0T3B0aW9uczoge1xuXHRcdFx0dXJsOiB0cnVlLFxuXHRcdFx0Y29udGV4dDogdHJ1ZVxuXHRcdH1cblx0fSxcblxuXHQvLyBDcmVhdGVzIGEgZnVsbCBmbGVkZ2VkIHNldHRpbmdzIG9iamVjdCBpbnRvIHRhcmdldFxuXHQvLyB3aXRoIGJvdGggYWpheFNldHRpbmdzIGFuZCBzZXR0aW5ncyBmaWVsZHMuXG5cdC8vIElmIHRhcmdldCBpcyBvbWl0dGVkLCB3cml0ZXMgaW50byBhamF4U2V0dGluZ3MuXG5cdGFqYXhTZXR1cDogZnVuY3Rpb24oIHRhcmdldCwgc2V0dGluZ3MgKSB7XG5cdFx0cmV0dXJuIHNldHRpbmdzID9cblxuXHRcdFx0Ly8gQnVpbGRpbmcgYSBzZXR0aW5ncyBvYmplY3Rcblx0XHRcdGFqYXhFeHRlbmQoIGFqYXhFeHRlbmQoIHRhcmdldCwgalF1ZXJ5LmFqYXhTZXR0aW5ncyApLCBzZXR0aW5ncyApIDpcblxuXHRcdFx0Ly8gRXh0ZW5kaW5nIGFqYXhTZXR0aW5nc1xuXHRcdFx0YWpheEV4dGVuZCggalF1ZXJ5LmFqYXhTZXR0aW5ncywgdGFyZ2V0ICk7XG5cdH0sXG5cblx0YWpheFByZWZpbHRlcjogYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBwcmVmaWx0ZXJzICksXG5cdGFqYXhUcmFuc3BvcnQ6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cyApLFxuXG5cdC8vIE1haW4gbWV0aG9kXG5cdGFqYXg6IGZ1bmN0aW9uKCB1cmwsIG9wdGlvbnMgKSB7XG5cblx0XHQvLyBJZiB1cmwgaXMgYW4gb2JqZWN0LCBzaW11bGF0ZSBwcmUtMS41IHNpZ25hdHVyZVxuXHRcdGlmICggdHlwZW9mIHVybCA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdG9wdGlvbnMgPSB1cmw7XG5cdFx0XHR1cmwgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gRm9yY2Ugb3B0aW9ucyB0byBiZSBhbiBvYmplY3Rcblx0XHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuXHRcdHZhciB0cmFuc3BvcnQsXG5cblx0XHRcdC8vIFVSTCB3aXRob3V0IGFudGktY2FjaGUgcGFyYW1cblx0XHRcdGNhY2hlVVJMLFxuXG5cdFx0XHQvLyBSZXNwb25zZSBoZWFkZXJzXG5cdFx0XHRyZXNwb25zZUhlYWRlcnNTdHJpbmcsXG5cdFx0XHRyZXNwb25zZUhlYWRlcnMsXG5cblx0XHRcdC8vIHRpbWVvdXQgaGFuZGxlXG5cdFx0XHR0aW1lb3V0VGltZXIsXG5cblx0XHRcdC8vIFVybCBjbGVhbnVwIHZhclxuXHRcdFx0dXJsQW5jaG9yLFxuXG5cdFx0XHQvLyBSZXF1ZXN0IHN0YXRlIChiZWNvbWVzIGZhbHNlIHVwb24gc2VuZCBhbmQgdHJ1ZSB1cG9uIGNvbXBsZXRpb24pXG5cdFx0XHRjb21wbGV0ZWQsXG5cblx0XHRcdC8vIFRvIGtub3cgaWYgZ2xvYmFsIGV2ZW50cyBhcmUgdG8gYmUgZGlzcGF0Y2hlZFxuXHRcdFx0ZmlyZUdsb2JhbHMsXG5cblx0XHRcdC8vIExvb3AgdmFyaWFibGVcblx0XHRcdGksXG5cblx0XHRcdC8vIHVuY2FjaGVkIHBhcnQgb2YgdGhlIHVybFxuXHRcdFx0dW5jYWNoZWQsXG5cblx0XHRcdC8vIENyZWF0ZSB0aGUgZmluYWwgb3B0aW9ucyBvYmplY3Rcblx0XHRcdHMgPSBqUXVlcnkuYWpheFNldHVwKCB7fSwgb3B0aW9ucyApLFxuXG5cdFx0XHQvLyBDYWxsYmFja3MgY29udGV4dFxuXHRcdFx0Y2FsbGJhY2tDb250ZXh0ID0gcy5jb250ZXh0IHx8IHMsXG5cblx0XHRcdC8vIENvbnRleHQgZm9yIGdsb2JhbCBldmVudHMgaXMgY2FsbGJhY2tDb250ZXh0IGlmIGl0IGlzIGEgRE9NIG5vZGUgb3IgalF1ZXJ5IGNvbGxlY3Rpb25cblx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dCA9IHMuY29udGV4dCAmJlxuXHRcdFx0XHQoIGNhbGxiYWNrQ29udGV4dC5ub2RlVHlwZSB8fCBjYWxsYmFja0NvbnRleHQuanF1ZXJ5ICkgP1xuXHRcdFx0XHRqUXVlcnkoIGNhbGxiYWNrQ29udGV4dCApIDpcblx0XHRcdFx0alF1ZXJ5LmV2ZW50LFxuXG5cdFx0XHQvLyBEZWZlcnJlZHNcblx0XHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCksXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkID0galF1ZXJ5LkNhbGxiYWNrcyggXCJvbmNlIG1lbW9yeVwiICksXG5cblx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRzdGF0dXNDb2RlID0gcy5zdGF0dXNDb2RlIHx8IHt9LFxuXG5cdFx0XHQvLyBIZWFkZXJzICh0aGV5IGFyZSBzZW50IGFsbCBhdCBvbmNlKVxuXHRcdFx0cmVxdWVzdEhlYWRlcnMgPSB7fSxcblx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXMgPSB7fSxcblxuXHRcdFx0Ly8gRGVmYXVsdCBhYm9ydCBtZXNzYWdlXG5cdFx0XHRzdHJBYm9ydCA9IFwiY2FuY2VsZWRcIixcblxuXHRcdFx0Ly8gRmFrZSB4aHJcblx0XHRcdGpxWEhSID0ge1xuXHRcdFx0XHRyZWFkeVN0YXRlOiAwLFxuXG5cdFx0XHRcdC8vIEJ1aWxkcyBoZWFkZXJzIGhhc2h0YWJsZSBpZiBuZWVkZWRcblx0XHRcdFx0Z2V0UmVzcG9uc2VIZWFkZXI6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0XHRcdFx0dmFyIG1hdGNoO1xuXHRcdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRcdFx0aWYgKCAhcmVzcG9uc2VIZWFkZXJzICkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnMgPSB7fTtcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG1hdGNoID0gcmhlYWRlcnMuZXhlYyggcmVzcG9uc2VIZWFkZXJzU3RyaW5nICkgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnNbIG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKSArIFwiIFwiIF0gPVxuXHRcdFx0XHRcdFx0XHRcdFx0KCByZXNwb25zZUhlYWRlcnNbIG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKSArIFwiIFwiIF0gfHwgW10gKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuY29uY2F0KCBtYXRjaFsgMiBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdG1hdGNoID0gcmVzcG9uc2VIZWFkZXJzWyBrZXkudG9Mb3dlckNhc2UoKSArIFwiIFwiIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybi
1BtYXRjaCA9PSBudWxsID8gbnVsbCA6IG1hdGNoLmpvaW4oIFwiLCBcIiApO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIFJhdyBzdHJpbmdcblx0XHRcdFx0Z2V0QWxsUmVzcG9uc2VIZWFkZXJzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29tcGxldGVkID8gcmVzcG9uc2VIZWFkZXJzU3RyaW5nIDogbnVsbDtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBDYWNoZXMgdGhlIGhlYWRlclxuXHRcdFx0XHRzZXRSZXF1ZXN0SGVhZGVyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHRcdFx0aWYgKCBjb21wbGV0ZWQgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRcdG5hbWUgPSByZXF1ZXN0SGVhZGVyc05hbWVzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSA9XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXNbIG5hbWUudG9Mb3dlckNhc2UoKSBdIHx8IG5hbWU7XG5cdFx0XHRcdFx0XHRyZXF1ZXN0SGVhZGVyc1sgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIE92ZXJyaWRlcyByZXNwb25zZSBjb250ZW50LXR5cGUgaGVhZGVyXG5cdFx0XHRcdG92ZXJyaWRlTWltZVR5cGU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdFx0XHRcdGlmICggY29tcGxldGVkID09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRzLm1pbWVUeXBlID0gdHlwZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdFx0c3RhdHVzQ29kZTogZnVuY3Rpb24oIG1hcCApIHtcblx0XHRcdFx0XHR2YXIgY29kZTtcblx0XHRcdFx0XHRpZiAoIG1hcCApIHtcblx0XHRcdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEV4ZWN1dGUgdGhlIGFwcHJvcHJpYXRlIGNhbGxiYWNrc1xuXHRcdFx0XHRcdFx0XHRqcVhIUi5hbHdheXMoIG1hcFsganFYSFIuc3RhdHVzIF0gKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gTGF6eS1hZGQgdGhlIG5ldyBjYWxsYmFja3MgaW4gYSB3YXkgdGhhdCBwcmVzZXJ2ZXMgb2xkIG9uZXNcblx0XHRcdFx0XHRcdFx0Zm9yICggY29kZSBpbiBtYXAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c3RhdHVzQ29kZVsgY29kZSBdID0gWyBzdGF0dXNDb2RlWyBjb2RlIF0sIG1hcFsgY29kZSBdIF07XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gQ2FuY2VsIHRoZSByZXF1ZXN0XG5cdFx0XHRcdGFib3J0OiBmdW5jdGlvbiggc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHR2YXIgZmluYWxUZXh0ID0gc3RhdHVzVGV4dCB8fCBzdHJBYm9ydDtcblx0XHRcdFx0XHRpZiAoIHRyYW5zcG9ydCApIHtcblx0XHRcdFx0XHRcdHRyYW5zcG9ydC5hYm9ydCggZmluYWxUZXh0ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRvbmUoIDAsIGZpbmFsVGV4dCApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0Ly8gQXR0YWNoIGRlZmVycmVkc1xuXHRcdGRlZmVycmVkLnByb21pc2UoIGpxWEhSICk7XG5cblx0XHQvLyBBZGQgcHJvdG9jb2wgaWYgbm90IHByb3ZpZGVkIChwcmVmaWx0ZXJzIG1pZ2h0IGV4cGVjdCBpdClcblx0XHQvLyBIYW5kbGUgZmFsc3kgdXJsIGluIHRoZSBzZXR0aW5ncyBvYmplY3QgKHRyYWMtMTAwOTM6IGNvbnNpc3RlbmN5IHdpdGggb2xkIHNpZ25hdHVyZSlcblx0XHQvLyBXZSBhbHNvIHVzZSB0aGUgdXJsIHBhcmFtZXRlciBpZiBhdmFpbGFibGVcblx0XHRzLnVybCA9ICggKCB1cmwgfHwgcy51cmwgfHwgbG9jYXRpb24uaHJlZiApICsgXCJcIiApXG5cdFx0XHQucmVwbGFjZSggcnByb3RvY29sLCBsb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiApO1xuXG5cdFx0Ly8gQWxpYXMgbWV0aG9kIG9wdGlvbiB0byB0eXBlIGFzIHBlciB0aWNrZXQgdHJhYy0xMjAwNFxuXHRcdHMudHlwZSA9IG9wdGlvbnMubWV0aG9kIHx8IG9wdGlvbnMudHlwZSB8fCBzLm1ldGhvZCB8fCBzLnR5cGU7XG5cblx0XHQvLyBFeHRyYWN0IGRhdGFUeXBlcyBsaXN0XG5cdFx0cy5kYXRhVHlwZXMgPSAoIHMuZGF0YVR5cGUgfHwgXCIqXCIgKS50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgWyBcIlwiIF07XG5cblx0XHQvLyBBIGNyb3NzLWRvbWFpbiByZXF1ZXN0IGlzIGluIG9yZGVyIHdoZW4gdGhlIG9yaWdpbiBkb2Vzbid0IG1hdGNoIHRoZSBjdXJyZW50IG9yaWdpbi5cblx0XHRpZiAoIHMuY3Jvc3NEb21haW4gPT0gbnVsbCApIHtcblx0XHRcdHVybEFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiYVwiICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OCAtIDExLCBFZGdlIDEyIC0gMTVcblx0XHRcdC8vIElFIHRocm93cyBleGNlcHRpb24gb24gYWNjZXNzaW5nIHRoZSBocmVmIHByb3BlcnR5IGlmIHVybCBpcyBtYWxmb3JtZWQsXG5cdFx0XHQvLyBlLmcuIGh0dHA6Ly9leGFtcGxlLmNvbTo4MHgvXG5cdFx0XHR0cnkge1xuXHRcdFx0XHR1cmxBbmNob3IuaHJlZiA9IHMudXJsO1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OCAtIDExIG9ubHlcblx0XHRcdFx0Ly8gQW5jaG9yJ3MgaG9zdCBwcm9wZXJ0eSBpc24ndCBjb3JyZWN0bHkgc2V0IHdoZW4gcy51cmwgaXMgcmVsYXRpdmVcblx0XHRcdFx0dXJsQW5jaG9yLmhyZWYgPSB1cmxBbmNob3IuaHJlZjtcblx0XHRcdFx0cy5jcm9zc0RvbWFpbiA9IG9yaWdpbkFuY2hvci5wcm90b2NvbCArIFwiLy9cIiArIG9yaWdpbkFuY2hvci5ob3N0ICE9PVxuXHRcdFx0XHRcdHVybEFuY2hvci5wcm90b2NvbCArIFwiLy9cIiArIHVybEFuY2hvci5ob3N0O1xuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cblx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgYW4gZXJyb3IgcGFyc2luZyB0aGUgVVJMLCBhc3N1bWUgaXQgaXMgY3Jvc3NEb21haW4sXG5cdFx0XHRcdC8vIGl0IGNhbiBiZSByZWplY3RlZCBieSB0aGUgdHJhbnNwb3J0IGlmIGl0IGlzIGludmFsaWRcblx0XHRcdFx0cy5jcm9zc0RvbWFpbiA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ29udmVydCBkYXRhIGlmIG5vdCBhbHJlYWR5IGEgc3RyaW5nXG5cdFx0aWYgKCBzLmRhdGEgJiYgcy5wcm9jZXNzRGF0YSAmJiB0eXBlb2Ygcy5kYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0cy5kYXRhID0galF1ZXJ5LnBhcmFtKCBzLmRhdGEsIHMudHJhZGl0aW9uYWwgKTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSBwcmVmaWx0ZXJzXG5cdFx0aW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMsIHMsIG9wdGlvbnMsIGpxWEhSICk7XG5cblx0XHQvLyBJZiByZXF1ZXN0IHdhcyBhYm9ydGVkIGluc2lkZSBhIHByZWZpbHRlciwgc3RvcCB0aGVyZVxuXHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0cmV0dXJuIGpxWEhSO
11xuXHRcdH1cblxuXHRcdC8vIFdlIGNhbiBmaXJlIGdsb2JhbCBldmVudHMgYXMgb2Ygbm93IGlmIGFza2VkIHRvXG5cdFx0Ly8gRG9uJ3QgZmlyZSBldmVudHMgaWYgalF1ZXJ5LmV2ZW50IGlzIHVuZGVmaW5lZCBpbiBhbiBBTUQtdXNhZ2Ugc2NlbmFyaW8gKHRyYWMtMTUxMTgpXG5cdFx0ZmlyZUdsb2JhbHMgPSBqUXVlcnkuZXZlbnQgJiYgcy5nbG9iYWw7XG5cblx0XHQvLyBXYXRjaCBmb3IgYSBuZXcgc2V0IG9mIHJlcXVlc3RzXG5cdFx0aWYgKCBmaXJlR2xvYmFscyAmJiBqUXVlcnkuYWN0aXZlKysgPT09IDAgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggXCJhamF4U3RhcnRcIiApO1xuXHRcdH1cblxuXHRcdC8vIFVwcGVyY2FzZSB0aGUgdHlwZVxuXHRcdHMudHlwZSA9IHMudHlwZS50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0Ly8gRGV0ZXJtaW5lIGlmIHJlcXVlc3QgaGFzIGNvbnRlbnRcblx0XHRzLmhhc0NvbnRlbnQgPSAhcm5vQ29udGVudC50ZXN0KCBzLnR5cGUgKTtcblxuXHRcdC8vIFNhdmUgdGhlIFVSTCBpbiBjYXNlIHdlJ3JlIHRveWluZyB3aXRoIHRoZSBJZi1Nb2RpZmllZC1TaW5jZVxuXHRcdC8vIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciBsYXRlciBvblxuXHRcdC8vIFJlbW92ZSBoYXNoIHRvIHNpbXBsaWZ5IHVybCBtYW5pcHVsYXRpb25cblx0XHRjYWNoZVVSTCA9IHMudXJsLnJlcGxhY2UoIHJoYXNoLCBcIlwiICk7XG5cblx0XHQvLyBNb3JlIG9wdGlvbnMgaGFuZGxpbmcgZm9yIHJlcXVlc3RzIHdpdGggbm8gY29udGVudFxuXHRcdGlmICggIXMuaGFzQ29udGVudCApIHtcblxuXHRcdFx0Ly8gUmVtZW1iZXIgdGhlIGhhc2ggc28gd2UgY2FuIHB1dCBpdCBiYWNrXG5cdFx0XHR1bmNhY2hlZCA9IHMudXJsLnNsaWNlKCBjYWNoZVVSTC5sZW5ndGggKTtcblxuXHRcdFx0Ly8gSWYgZGF0YSBpcyBhdmFpbGFibGUgYW5kIHNob3VsZCBiZSBwcm9jZXNzZWQsIGFwcGVuZCBkYXRhIHRvIHVybFxuXHRcdFx0aWYgKCBzLmRhdGEgJiYgKCBzLnByb2Nlc3NEYXRhIHx8IHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgKSApIHtcblx0XHRcdFx0Y2FjaGVVUkwgKz0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuZGF0YTtcblxuXHRcdFx0XHQvLyB0cmFjLTk2ODI6IHJlbW92ZSBkYXRhIHNvIHRoYXQgaXQncyBub3QgdXNlZCBpbiBhbiBldmVudHVhbCByZXRyeVxuXHRcdFx0XHRkZWxldGUgcy5kYXRhO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgb3IgdXBkYXRlIGFudGktY2FjaGUgcGFyYW0gaWYgbmVlZGVkXG5cdFx0XHRpZiAoIHMuY2FjaGUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRjYWNoZVVSTCA9IGNhY2hlVVJMLnJlcGxhY2UoIHJhbnRpQ2FjaGUsIFwiJDFcIiApO1xuXHRcdFx0XHR1bmNhY2hlZCA9ICggcnF1ZXJ5LnRlc3QoIGNhY2hlVVJMICkgPyBcIiZcIiA6IFwiP1wiICkgKyBcIl89XCIgKyAoIG5vbmNlLmd1aWQrKyApICtcblx0XHRcdFx0XHR1bmNhY2hlZDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUHV0IGhhc2ggYW5kIGFudGktY2FjaGUgb24gdGhlIFVSTCB0aGF0IHdpbGwgYmUgcmVxdWVzdGVkIChnaC0xNzMyKVxuXHRcdFx0cy51cmwgPSBjYWNoZVVSTCArIHVuY2FjaGVkO1xuXG5cdFx0Ly8gQ2hhbmdlICclMjAnIHRvICcrJyBpZiB0aGlzIGlzIGVuY29kZWQgZm9ybSBib2R5IGNvbnRlbnQgKGdoLTI2NTgpXG5cdFx0fSBlbHNlIGlmICggcy5kYXRhICYmIHMucHJvY2Vzc0RhdGEgJiZcblx0XHRcdCggcy5jb250ZW50VHlwZSB8fCBcIlwiICkuaW5kZXhPZiggXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIiApID09PSAwICkge1xuXHRcdFx0cy5kYXRhID0gcy5kYXRhLnJlcGxhY2UoIHIyMCwgXCIrXCIgKTtcblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxuXHRcdGlmICggcy5pZk1vZGlmaWVkICkge1xuXHRcdFx0aWYgKCBqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdICkge1xuXHRcdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIklmLU1vZGlmaWVkLVNpbmNlXCIsIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKTtcblx0XHRcdH1cblx0XHRcdGlmICggalF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gKSB7XG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTm9uZS1NYXRjaFwiLCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgY29ycmVjdCBoZWFkZXIsIGlmIGRhdGEgaXMgYmVpbmcgc2VudFxuXHRcdGlmICggcy5kYXRhICYmIHMuaGFzQ29udGVudCAmJiBzLmNvbnRlbnRUeXBlICE9PSBmYWxzZSB8fCBvcHRpb25zLmNvbnRlbnRUeXBlICkge1xuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJDb250ZW50LVR5cGVcIiwgcy5jb250ZW50VHlwZSApO1xuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgQWNjZXB0cyBoZWFkZXIgZm9yIHRoZSBzZXJ2ZXIsIGRlcGVuZGluZyBvbiB0aGUgZGF0YVR5cGVcblx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKFxuXHRcdFx0XCJBY2NlcHRcIixcblx0XHRcdHMuZGF0YVR5cGVzWyAwIF0gJiYgcy5hY2NlcHRzWyBzLmRhdGFUeXBlc1sgMCBdIF0gP1xuXHRcdFx0XHRzLmFjY2VwdHNbIHMuZGF0YVR5cGVzWyAwIF0gXSArXG5cdFx0XHRcdFx0KCBzLmRhdGFUeXBlc1sgMCBdICE9PSBcIipcIiA/IFwiLCBcIiArIGFsbFR5cGVzICsgXCI7IHE9MC4wMVwiIDogXCJcIiApIDpcblx0XHRcdFx0cy5hY2NlcHRzWyBcIipcIiBdXG5cdFx0KTtcblxuXHRcdC8vIENoZWNrIGZvciBoZWFkZXJzIG9wdGlvblxuXHRcdGZvciAoIGkgaW4gcy5oZWFkZXJzICkge1xuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggaSwgcy5oZWFkZXJzWyBpIF0gKTtcblx0XHR9XG5cblx0XHQvLyBBbGxvdyBjdXN0b20gaGVhZGVycy9taW1ldHlwZXMgYW5kIGVhcmx5IGFib3J0XG5cdFx0aWYgKCBzLmJlZm9yZVNlbmQgJiZcblx0XHRcdCggcy5iZWZvcmVTZW5kLmNhbGwoIGNhbGxiYWNrQ29udGV4dCwganFYSFIsIHMgKSA9PT0gZmFsc2UgfHwgY29tcGxldGVkICkgKSB7XG5cblx0XHRcdC8vIEFib3J0IGlmIG5vdCBkb25lIGFscmVhZHkgYW5kIHJldHVyblxuXHRcdFx0cmV0dXJuIGpxWEhSLmFib3J0KCk7XG5cdFx0fVxuXG5cdFx0Ly8gQWJvcnRpbmcgaXMgbm8gbG9uZ2VyIGEgY2FuY2VsbGF0aW9uXG5cdFx0c3RyQWJvcnQgPSBcImFib3J0XCI7XG5cblx0XHQvLyBJbnN0YWxsIGNhbGxiYWNrcyBvbiBkZWZlcnJlZHNcblx0XHRjb21wbGV0ZURlZmVycmVkLmFkZCggcy5jb21wbGV0ZSApO1xuXHRcdGpxWEhSLmRvbmUoIHMuc3VjY2VzcyApO1xuXHRcdGpxWEhSLmZhaWwoIHMuZXJyb3IgKTtcblxuXHRcdC8vIEdldCB0cmFuc3BvcnRcblx0XHR0cmFuc3BvcnQgPSBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cywgcywgb3B0aW9ucywganFYSFIgKTtcblxuXHRcdC8vIElmIG5vIHRyYW5zcG9ydCwgd2UgYXV0by1hYm9ydFxuXHRcdGlmICggIXRyYW5zcG9ydCApIHtcblx0XHRcdGRvbmUoIC0xLCBcIk5vIFRyYW5zcG9ydFwiICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpxWEhSLnJlYWR5U3RhdGUgPSAxO1xuXG5cdFx0XHQvLyBTZW5kIGdsb2JhbCBldmVudFxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIFwiYWpheFNlbmRcIiwgWyBqcVhIUiwgcyBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIHJlcXVlc3Qgd2FzIGFib3J0ZWQgaW5zaWRlIGFqYXhTZW5kLCBzdG9wIHRoZXJlXG5cdFx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdFx0cmV0dXJuIGpxWEhSO
11xuXHRcdFx0fVxuXG5cdFx0XHQvLyBUaW1lb3V0XG5cdFx0XHRpZiAoIHMuYXN5bmMgJiYgcy50aW1lb3V0ID4gMCApIHtcblx0XHRcdFx0dGltZW91dFRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGpxWEhSLmFib3J0KCBcInRpbWVvdXRcIiApO1xuXHRcdFx0XHR9LCBzLnRpbWVvdXQgKTtcblx0XHRcdH1cblxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Y29tcGxldGVkID0gZmFsc2U7XG5cdFx0XHRcdHRyYW5zcG9ydC5zZW5kKCByZXF1ZXN0SGVhZGVycywgZG9uZSApO1xuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cblx0XHRcdFx0Ly8gUmV0aHJvdyBwb3N0LWNvbXBsZXRpb24gZXhjZXB0aW9uc1xuXHRcdFx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdFx0XHR0aHJvdyBlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUHJvcGFnYXRlIG90aGVycyBhcyByZXN1bHRzXG5cdFx0XHRcdGRvbmUoIC0xLCBlICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbGJhY2sgZm9yIHdoZW4gZXZlcnl0aGluZyBpcyBkb25lXG5cdFx0ZnVuY3Rpb24gZG9uZSggc3RhdHVzLCBuYXRpdmVTdGF0dXNUZXh0LCByZXNwb25zZXMsIGhlYWRlcnMgKSB7XG5cdFx0XHR2YXIgaXNTdWNjZXNzLCBzdWNjZXNzLCBlcnJvciwgcmVzcG9uc2UsIG1vZGlmaWVkLFxuXHRcdFx0XHRzdGF0dXNUZXh0ID0gbmF0aXZlU3RhdHVzVGV4dDtcblxuXHRcdFx0Ly8gSWdub3JlIHJlcGVhdCBpbnZvY2F0aW9uc1xuXHRcdFx0aWYgKCBjb21wbGV0ZWQgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Y29tcGxldGVkID0gdHJ1ZTtcblxuXHRcdFx0Ly8gQ2xlYXIgdGltZW91dCBpZiBpdCBleGlzdHNcblx0XHRcdGlmICggdGltZW91dFRpbWVyICkge1xuXHRcdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0VGltZXIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRGVyZWZlcmVuY2UgdHJhbnNwb3J0IGZvciBlYXJseSBnYXJiYWdlIGNvbGxlY3Rpb25cblx0XHRcdC8vIChubyBtYXR0ZXIgaG93IGxvbmcgdGhlIGpxWEhSIG9iamVjdCB3aWxsIGJlIHVzZWQpXG5cdFx0XHR0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG5cblx0XHRcdC8vIENhY2hlIHJlc3BvbnNlIGhlYWRlcnNcblx0XHRcdHJlc3BvbnNlSGVhZGVyc1N0cmluZyA9IGhlYWRlcnMgfHwgXCJcIjtcblxuXHRcdFx0Ly8gU2V0IHJlYWR5U3RhdGVcblx0XHRcdGpxWEhSLnJlYWR5U3RhdGUgPSBzdGF0dXMgPiAwID8gNCA6IDA7XG5cblx0XHRcdC8vIERldGVybWluZSBpZiBzdWNjZXNzZnVsXG5cdFx0XHRpc1N1Y2Nlc3MgPSBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMCB8fCBzdGF0dXMgPT09IDMwNDtcblxuXHRcdFx0Ly8gR2V0IHJlc3BvbnNlIGRhdGFcblx0XHRcdGlmICggcmVzcG9uc2VzICkge1xuXHRcdFx0XHRyZXNwb25zZSA9IGFqYXhIYW5kbGVSZXNwb25zZXMoIHMsIGpxWEhSLCByZXNwb25zZXMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVXNlIGEgbm9vcCBjb252ZXJ0ZXIgZm9yIG1pc3Npbmcgc2NyaXB0IGJ1dCBub3QgaWYganNvbnBcblx0XHRcdGlmICggIWlzU3VjY2VzcyAmJlxuXHRcdFx0XHRqUXVlcnkuaW5BcnJheSggXCJzY3JpcHRcIiwgcy5kYXRhVHlwZXMgKSA+IC0xICYmXG5cdFx0XHRcdGpRdWVyeS5pbkFycmF5KCBcImpzb25cIiwgcy5kYXRhVHlwZXMgKSA8IDAgKSB7XG5cdFx0XHRcdHMuY29udmVydGVyc1sgXCJ0ZXh0IHNjcmlwdFwiIF0gPSBmdW5jdGlvbigpIHt9O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb252ZXJ0IG5vIG1hdHRlciB3aGF0ICh0aGF0IHdheSByZXNwb25zZVhYWCBmaWVsZHMgYXJlIGFsd2F5cyBzZXQpXG5cdFx0XHRyZXNwb25zZSA9IGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApO1xuXG5cdFx0XHQvLyBJZiBzdWNjZXNzZnVsLCBoYW5kbGUgdHlwZSBjaGFpbmluZ1xuXHRcdFx0aWYgKCBpc1N1Y2Nlc3MgKSB7XG5cblx0XHRcdFx0Ly8gU2V0IHRoZSBJZi1Nb2RpZmllZC1TaW5jZSBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIsIGlmIGluIGlmTW9kaWZpZWQgbW9kZS5cblx0XHRcdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlciggXCJMYXN0LU1vZGlmaWVkXCIgKTtcblx0XHRcdFx0XHRpZiAoIG1vZGlmaWVkICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSA9IG1vZGlmaWVkO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcImV0YWdcIiApO1xuXHRcdFx0XHRcdGlmICggbW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSA9IG1vZGlmaWVkO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGlmIG5vIGNvbnRlbnRcblx0XHRcdFx0aWYgKCBzdGF0dXMgPT09IDIwNCB8fCBzLnR5cGUgPT09IFwiSEVBRFwiICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcIm5vY29udGVudFwiO1xuXG5cdFx0XHRcdC8vIGlmIG5vdCBtb2RpZmllZFxuXHRcdFx0XHR9IGVsc2UgaWYgKCBzdGF0dXMgPT09IDMwNCApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJub3Rtb2RpZmllZFwiO1xuXG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgZGF0YSwgbGV0J3MgY29udmVydCBpdFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSByZXNwb25zZS5zdGF0ZTtcblx0XHRcdFx0XHRzdWNjZXNzID0gcmVzcG9uc2UuZGF0YTtcblx0XHRcdFx0XHRlcnJvciA9IHJlc3BvbnNlLmVycm9yO1xuXHRcdFx0XHRcdGlzU3VjY2VzcyA9ICFlcnJvcjtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBFeHRyYWN0IGVycm9yIGZyb20gc3RhdHVzVGV4dCBhbmQgbm9ybWFsaXplIGZvciBub24tYWJvcnRzXG5cdFx0XHRcdGVycm9yID0gc3RhdHVzVGV4dDtcblx0XHRcdFx0aWYgKCBzdGF0dXMgfHwgIXN0YXR1c1RleHQgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwiZXJyb3JcIjtcblx0XHRcdFx0XHRpZiAoIHN0YXR1cyA8IDAgKSB7XG5cdFx0XHRcdFx0XHRzdGF0dXMgPSAwO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgZGF0YSBmb3IgdGhlIGZha2UgeGhyIG9iamVjdFxuXHRcdFx0anFYSFIuc3RhdHVzID0gc3RhdHVzO1xuXHRcdFx0anFYSFIuc3RhdHVzVGV4dCA9ICggbmF0aXZlU3RhdHVzVGV4dCB8fCBzdGF0dXNUZXh0ICkgKyBcIlwiO1xuXG5cdFx0XHQvLyBTdWNjZXNzL0Vycm9yXG5cdFx0XHRpZiAoIGlzU3VjY2VzcyApIHtcblx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBzdWNjZXNzLCBzdGF0dXNUZXh0LCBqcVhIUiBdICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsganFYSFIsIHN0YXR1c1RleHQsIGVycm9yIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3Rh
1dHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdGpxWEhSLnN0YXR1c0NvZGUoIHN0YXR1c0NvZGUgKTtcblx0XHRcdHN0YXR1c0NvZGUgPSB1bmRlZmluZWQ7XG5cblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBpc1N1Y2Nlc3MgPyBcImFqYXhTdWNjZXNzXCIgOiBcImFqYXhFcnJvclwiLFxuXHRcdFx0XHRcdFsganFYSFIsIHMsIGlzU3VjY2VzcyA/IHN1Y2Nlc3MgOiBlcnJvciBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbXBsZXRlXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkLmZpcmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsganFYSFIsIHN0YXR1c1RleHQgXSApO1xuXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggXCJhamF4Q29tcGxldGVcIiwgWyBqcVhIUiwgcyBdICk7XG5cblx0XHRcdFx0Ly8gSGFuZGxlIHRoZSBnbG9iYWwgQUpBWCBjb3VudGVyXG5cdFx0XHRcdGlmICggISggLS1qUXVlcnkuYWN0aXZlICkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIFwiYWpheFN0b3BcIiApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpxWEhSO1xuXHR9LFxuXG5cdGdldEpTT046IGZ1bmN0aW9uKCB1cmwsIGRhdGEsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIGRhdGEsIGNhbGxiYWNrLCBcImpzb25cIiApO1xuXHR9LFxuXG5cdGdldFNjcmlwdDogZnVuY3Rpb24oIHVybCwgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5nZXQoIHVybCwgdW5kZWZpbmVkLCBjYWxsYmFjaywgXCJzY3JpcHRcIiApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5lYWNoKCBbIFwiZ2V0XCIsIFwicG9zdFwiIF0sIGZ1bmN0aW9uKCBfaSwgbWV0aG9kICkge1xuXHRqUXVlcnlbIG1ldGhvZCBdID0gZnVuY3Rpb24oIHVybCwgZGF0YSwgY2FsbGJhY2ssIHR5cGUgKSB7XG5cblx0XHQvLyBTaGlmdCBhcmd1bWVudHMgaWYgZGF0YSBhcmd1bWVudCB3YXMgb21pdHRlZFxuXHRcdGlmICggaXNGdW5jdGlvbiggZGF0YSApICkge1xuXHRcdFx0dHlwZSA9IHR5cGUgfHwgY2FsbGJhY2s7XG5cdFx0XHRjYWxsYmFjayA9IGRhdGE7XG5cdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdC8vIFRoZSB1cmwgY2FuIGJlIGFuIG9wdGlvbnMgb2JqZWN0ICh3aGljaCB0aGVuIG11c3QgaGF2ZSAudXJsKVxuXHRcdHJldHVybiBqUXVlcnkuYWpheCggalF1ZXJ5LmV4dGVuZCgge1xuXHRcdFx0dXJsOiB1cmwsXG5cdFx0XHR0eXBlOiBtZXRob2QsXG5cdFx0XHRkYXRhVHlwZTogdHlwZSxcblx0XHRcdGRhdGE6IGRhdGEsXG5cdFx0XHRzdWNjZXNzOiBjYWxsYmFja1xuXHRcdH0sIGpRdWVyeS5pc1BsYWluT2JqZWN0KCB1cmwgKSAmJiB1cmwgKSApO1xuXHR9O1xufSApO1xuXG5qUXVlcnkuYWpheFByZWZpbHRlciggZnVuY3Rpb24oIHMgKSB7XG5cdHZhciBpO1xuXHRmb3IgKCBpIGluIHMuaGVhZGVycyApIHtcblx0XHRpZiAoIGkudG9Mb3dlckNhc2UoKSA9PT0gXCJjb250ZW50LXR5cGVcIiApIHtcblx0XHRcdHMuY29udGVudFR5cGUgPSBzLmhlYWRlcnNbIGkgXSB8fCBcIlwiO1xuXHRcdH1cblx0fVxufSApO1xuXG5cbmpRdWVyeS5fZXZhbFVybCA9IGZ1bmN0aW9uKCB1cmwsIG9wdGlvbnMsIGRvYyApIHtcblx0cmV0dXJuIGpRdWVyeS5hamF4KCB7XG5cdFx0dXJsOiB1cmwsXG5cblx0XHQvLyBNYWtlIHRoaXMgZXhwbGljaXQsIHNpbmNlIHVzZXIgY2FuIG92ZXJyaWRlIHRoaXMgdGhyb3VnaCBhamF4U2V0dXAgKHRyYWMtMTEyNjQpXG5cdFx0dHlwZTogXCJHRVRcIixcblx0XHRkYXRhVHlwZTogXCJzY3JpcHRcIixcblx0XHRjYWNoZTogdHJ1ZSxcblx0XHRhc3luYzogZmFsc2UsXG5cdFx0Z2xvYmFsOiBmYWxzZSxcblxuXHRcdC8vIE9ubHkgZXZhbHVhdGUgdGhlIHJlc3BvbnNlIGlmIGl0IGlzIHN1Y2Nlc3NmdWwgKGdoLTQxMjYpXG5cdFx0Ly8gZGF0YUZpbHRlciBpcyBub3QgaW52b2tlZCBmb3IgZmFpbHVyZSByZXNwb25zZXMsIHNvIHVzaW5nIGl0IGluc3RlYWRcblx0XHQvLyBvZiB0aGUgZGVmYXVsdCBjb252ZXJ0ZXIgaXMga2x1ZGd5IGJ1dCBpdCB3b3Jrcy5cblx0XHRjb252ZXJ0ZXJzOiB7XG5cdFx0XHRcInRleHQgc2NyaXB0XCI6IGZ1bmN0aW9uKCkge31cblx0XHR9LFxuXHRcdGRhdGFGaWx0ZXI6IGZ1bmN0aW9uKCByZXNwb25zZSApIHtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCByZXNwb25zZSwgb3B0aW9ucywgZG9jICk7XG5cdFx0fVxuXHR9ICk7XG59O1xuXG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0d3JhcEFsbDogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0dmFyIHdyYXA7XG5cblx0XHRpZiAoIHRoaXNbIDAgXSApIHtcblx0XHRcdGlmICggaXNGdW5jdGlvbiggaHRtbCApICkge1xuXHRcdFx0XHRodG1sID0gaHRtbC5jYWxsKCB0aGlzWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVGhlIGVsZW1lbnRzIHRvIHdyYXAgdGhlIHRhcmdldCBhcm91bmRcblx0XHRcdHdyYXAgPSBqUXVlcnkoIGh0bWwsIHRoaXNbIDAgXS5vd25lckRvY3VtZW50ICkuZXEoIDAgKS5jbG9uZSggdHJ1ZSApO1xuXG5cdFx0XHRpZiAoIHRoaXNbIDAgXS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR3cmFwLmluc2VydEJlZm9yZSggdGhpc1sgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHdyYXAubWFwKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGVsZW0gPSB0aGlzO1xuXG5cdFx0XHRcdHdoaWxlICggZWxlbS5maXJzdEVsZW1lbnRDaGlsZCApIHtcblx0XHRcdFx0XHRlbGVtID0gZWxlbS5maXJzdEVsZW1lbnRDaGlsZDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBlbGVtO1xuXHRcdFx0fSApLmFwcGVuZCggdGhpcyApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHdyYXBJbm5lcjogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcElubmVyKCBodG1sLmNhbGwoIHRoaXMsIGkgKSApO
11xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHNlbGYgPSBqUXVlcnkoIHRoaXMgKSxcblx0XHRcdFx0Y29udGVudHMgPSBzZWxmLmNvbnRlbnRzKCk7XG5cblx0XHRcdGlmICggY29udGVudHMubGVuZ3RoICkge1xuXHRcdFx0XHRjb250ZW50cy53cmFwQWxsKCBodG1sICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNlbGYuYXBwZW5kKCBodG1sICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdHdyYXA6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciBodG1sSXNGdW5jdGlvbiA9IGlzRnVuY3Rpb24oIGh0bWwgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaHRtbElzRnVuY3Rpb24gPyBodG1sLmNhbGwoIHRoaXMsIGkgKSA6IGh0bWwgKTtcblx0XHR9ICk7XG5cdH0sXG5cblx0dW53cmFwOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dGhpcy5wYXJlbnQoIHNlbGVjdG9yICkubm90KCBcImJvZHlcIiApLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5KCB0aGlzICkucmVwbGFjZVdpdGgoIHRoaXMuY2hpbGROb2RlcyApO1xuXHRcdH0gKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxufSApO1xuXG5cbmpRdWVyeS5leHByLnBzZXVkb3MuaGlkZGVuID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiAhalF1ZXJ5LmV4cHIucHNldWRvcy52aXNpYmxlKCBlbGVtICk7XG59O1xualF1ZXJ5LmV4cHIucHNldWRvcy52aXNpYmxlID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiAhISggZWxlbS5vZmZzZXRXaWR0aCB8fCBlbGVtLm9mZnNldEhlaWdodCB8fCBlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoICk7XG59O1xuXG5cblxuXG5qUXVlcnkuYWpheFNldHRpbmdzLnhociA9IGZ1bmN0aW9uKCkge1xuXHR0cnkge1xuXHRcdHJldHVybiBuZXcgd2luZG93LlhNTEh0dHBSZXF1
1ZXN0KCk7XG5cdH0gY2F0Y2ggKCBlICkge31cbn07XG5cbnZhciB4aHJTdWNjZXNzU3RhdHVzID0ge1xuXG5cdFx0Ly8gRmlsZSBwcm90b2NvbCBhbHdheXMgeWllbGRzIHN0YXR1cyBjb2RlIDAsIGFzc3VtZSAyMDBcblx0XHQwOiAyMDAsXG5cblx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdC8vIHRyYWMtMTQ1MDogc29tZXRpbWVzIElFIHJldHVybnMgMTIyMyB3aGVuIGl0IHNob3VsZCBiZSAyMDRcblx0XHQxMjIzOiAyMDRcblx0fSxcblx0eGhyU3VwcG9ydGVkID0galF1ZXJ5LmFqYXhTZXR0aW5ncy54aHIoKTtcblxuc3VwcG9ydC5jb3JzID0gISF4aHJTdXBwb3J0ZWQgJiYgKCBcIndpdGhDcmVkZW50aWFsc1wiIGluIHhoclN1cHBvcnRlZCApO1xuc3VwcG9ydC5hamF4ID0geGhyU3VwcG9ydGVkID0gISF4aHJTdXBwb3J0ZWQ7XG5cbmpRdWVyeS5hamF4VHJhbnNwb3J0KCBmdW5jdGlvbiggb3B0aW9ucyApIHtcblx0dmFyIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrO1xuXG5cdC8vIENyb3NzIGRvbWFpbiBvbmx5IGFsbG93ZWQgaWYgc3VwcG9ydGVkIHRocm91Z2ggWE1MSHR0cFJlcXVlc3Rcblx0aWYgKCBzdXBwb3J0LmNvcnMgfHwgeGhyU3VwcG9ydGVkICYmICFvcHRpb25zLmNyb3NzRG9tYWluICkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW5kOiBmdW5jdGlvbiggaGVhZGVycywgY29tcGxldGUgKSB7XG5cdFx0XHRcdHZhciBpLFxuXHRcdFx0XHRcdHhociA9IG9wdGlvbnMueGhyKCk7XG5cblx0XHRcdFx0eGhyLm9wZW4oXG5cdFx0XHRcdFx0b3B0aW9ucy50eXBlLFxuXHRcdFx0XHRcdG9wdGlvbnMudXJsLFxuXHRcdFx0XHRcdG9wdGlvbnMuYXN5bmMsXG5cdFx0XHRcdFx0b3B0aW9ucy51c2VybmFtZSxcblx0XHRcdFx0XHRvcHRpb25zLnBhc3N3b3JkXG5cdFx0XHRcdCk7XG5cblx0XHRcdFx0Ly8gQXBwbHkgY3VzdG9tIGZpZWxkcyBpZiBwcm92aWRlZFxuXHRcdFx0XHRpZiAoIG9wdGlvbnMueGhyRmllbGRzICkge1xuXHRcdFx0XHRcdGZvciAoIGkgaW4gb3B0aW9ucy54aHJGaWVsZHMgKSB7XG5cdFx0XHRcdFx0XHR4aHJbIGkgXSA9IG9wdGlvbnMueGhyRmllbGRzWyBpIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gT3ZlcnJpZGUgbWltZSB0eXBlIGlmIG5lZWRlZFxuXHRcdFx0XHRpZiAoIG9wdGlvbnMubWltZVR5cGUgJiYgeGhyLm92ZXJyaWRlTWltZVR5cGUgKSB7XG5cdFx0XHRcdFx0eGhyLm92ZXJyaWRlTWltZVR5cGUoIG9wdGlvbnMubWltZVR5cGUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFgtUmVxdWVzdGVkLVdpdGggaGVhZGVyXG5cdFx0XHRcdC8vIEZvciBjcm9zcy1kb21haW4gcmVxdWVzdHMsIHNlZWluZyBhcyBjb25kaXRpb25zIGZvciBhIHByZWZsaWdodCBhcmVcblx0XHRcdFx0Ly8gYWtpbiB0byBhIGppZ3NhdyBwdXp6bGUsIHdlIHNpbXBseSBuZXZlciBzZXQgaXQgdG8gYmUgc3VyZS5cblx0XHRcdFx0Ly8gKGl0IGNhbiBhbHdheXMgYmUgc2V0IG9uIGEgcGVyLXJlcXVlc3QgYmFzaXMgb3IgZXZlbiB1c2luZyBhamF4U2V0dXApXG5cdFx0XHRcdC8vIEZvciBzYW1lLWRvbWFpbiByZXF1ZXN0cywgd29uJ3QgY2hhbmdlIGhlYWRlciBpZiBhbHJlYWR5IHByb3ZpZGVkLlxuXHRcdFx0XHRpZiAoICFvcHRpb25zLmNyb3NzRG9tYWluICYmICFoZWFkZXJzWyBcIlgtUmVxdWVzdGVkLVdpdGhcIiBdICkge1xuXHRcdFx0XHRcdGhlYWRlcnNbIFwiWC1SZXF1ZXN0ZWQtV2l0aFwiIF0gPSBcIlhNTEh0dHBSZXF1
1ZXN0XCI7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTZXQgaGVhZGVyc1xuXHRcdFx0XHRmb3IgKCBpIGluIGhlYWRlcnMgKSB7XG5cdFx0XHRcdFx0eGhyLnNldFJlcXVlc3RIZWFkZXIoIGksIGhlYWRlcnNbIGkgXSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQ2FsbGJhY2tcblx0XHRcdFx0Y2FsbGJhY2sgPSBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdFx0XHRjYWxsYmFjayA9IGVycm9yQ2FsbGJhY2sgPSB4aHIub25sb2FkID1cblx0XHRcdFx0XHRcdFx0XHR4aHIub25lcnJvciA9IHhoci5vbmFib3J0ID0geGhyLm9udGltZW91dCA9XG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiYWJvcnRcIiApIHtcblx0XHRcdFx0XHRcdFx0XHR4aHIuYWJvcnQoKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggdHlwZSA9PT0gXCJlcnJvclwiICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0XHRcdFx0XHRcdFx0XHQvLyBPbiBhIG1hbnVhbCBuYXRpdmUgYWJvcnQsIElFOSB0aHJvd3Ncblx0XHRcdFx0XHRcdFx0XHQvLyBlcnJvcnMgb24gYW55IHByb3BlcnR5IGFjY2VzcyB0aGF0IGlzIG5vdCByZWFkeVN0YXRlXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlb2YgeGhyLnN0YXR1cyAhPT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbXBsZXRlKCAwLCBcImVycm9yXCIgKTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gRmlsZTogcHJvdG9jb2wgYWx3YXlzIHlpZWxkcyBzdGF0dXMgMDsgc2VlIHRyYWMtODYwNSwgdHJhYy0xNDIwN1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dFxuXHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHJTdWNjZXNzU3RhdHVzWyB4aHIuc3RhdHVzIF0gfHwgeGhyLnN0YXR1cyxcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXNUZXh0LFxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSUU5IGhhcyBubyBYSFIyIGJ1dCB0aHJvd3Mgb24gYmluYXJ5ICh0cmFjLTExNDI2KVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gRm9yIFhIUjIgbm9uLXRleHQsIGxldCB0aGUgY2FsbGVyIGhhbmRsZSBpdCAoZ2gtMjQ5OClcblx0XHRcdFx0XHRcdFx0XHRcdCggeGhyLnJlc3BvbnNlVHlwZSB8fCBcInRleHRcIiApICE9PSBcInRleHRcIiAgfHxcblx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiB4aHIucmVzcG9uc2VUZXh0ICE9PSBcInN0cmluZ1wiID9cblx0XHRcdFx0XHRcdFx0XHRcdFx0eyBiaW5hcnk6IHhoci5yZXNwb25zZSB9IDpcblx0XHRcdFx0XHRcdFx0XHRcdFx0eyB0ZXh0OiB4aHIucmVzcG9uc2VUZXh0IH0sXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKClcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fTtcblxuXHRcdFx0XHQvLyBMaXN0ZW4gdG8gZXZlbnRzXG5cdFx0XHRcdHhoci5vbmxvYWQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHRlcnJvckNhbGxiYWNrID0geGhyLm9uZXJyb3IgPSB4aHIub250aW1lb3V0ID0gY2FsbGJhY2soIFwiZXJyb3JcIiApO
11xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDkgb25seVxuXHRcdFx0XHQvLyBVc2Ugb25yZWFkeXN0YXRlY2hhbmdlIHRvIHJlcGxhY2Ugb25hYm9ydFxuXHRcdFx0XHQvLyB0byBoYW5kbGUgdW5jYXVnaHQgYWJvcnRzXG5cdFx0XHRcdGlmICggeGhyLm9uYWJvcnQgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHR4aHIub25hYm9ydCA9IGVycm9yQ2FsbGJhY2s7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0eGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdFx0XHQvLyBDaGVjayByZWFkeVN0YXRlIGJlZm9yZSB0aW1lb3V0IGFzIGl0IGNoYW5nZXNcblx0XHRcdFx0XHRcdGlmICggeGhyLnJlYWR5U3RhdGUgPT09IDQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQWxsb3cgb25lcnJvciB0byBiZSBjYWxsZWQgZmlyc3QsXG5cdFx0XHRcdFx0XHRcdC8vIGJ1dCB0aGF0IHdpbGwgbm90IGhhbmRsZSBhIG5hdGl2ZSBhYm9ydFxuXHRcdFx0XHRcdFx0XHQvLyBBbHNvLCBzYXZlIGVycm9yQ2FsbGJhY2sgdG8gYSB2YXJpYWJsZVxuXHRcdFx0XHRcdFx0XHQvLyBhcyB4aHIub25lcnJvciBjYW5ub3QgYmUgYWNjZXNzZWRcblx0XHRcdFx0XHRcdFx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRlcnJvckNhbGxiYWNrKCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIENyZWF0ZSB0aGUgYWJvcnQgY2FsbGJhY2tcblx0XHRcdFx0Y2FsbGJhY2sgPSBjYWxsYmFjayggXCJhYm9ydFwiICk7XG5cblx0XHRcdFx0dHJ5IHtcblxuXHRcdFx0XHRcdC8vIERvIHNlbmQgdGhlI
1HJlcXVlc3QgKHRoaXMgbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbilcblx0XHRcdFx0XHR4aHIuc2VuZCggb3B0aW9ucy5oYXNDb250ZW50ICYmIG9wdGlvbnMuZGF0YSB8fCBudWxsICk7XG5cdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXG5cdFx0XHRcdFx0Ly8gdHJhYy0xNDY4MzogT25seSByZXRocm93IGlmIHRoaXMgaGFzbid0IGJlZW4gbm90aWZpZWQgYXMgYW4gZXJyb3IgeWV0XG5cdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRcdHRocm93IGU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXG5cdFx0XHRhYm9ydDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdH1cbn0gKTtcblxuXG5cblxuLy8gUHJldmVudCBhdXRvLWV4ZWN1dGlvbiBvZiBzY3JpcHRzIHdoZW4gbm8gZXhwbGljaXQgZGF0YVR5cGUgd2FzIHByb3ZpZGVkIChTZWUgZ2gtMjQzMilcbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBmdW5jdGlvbiggcyApIHtcblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xuXHRcdHMuY29udGVudHMuc2NyaXB0ID0gZmFsc2U7XG5cdH1cbn0gKTtcblxuLy8gSW5zdGFsbCBzY3JpcHQgZGF0YVR5cGVcbmpRdWVyeS5hamF4U2V0dXAoIHtcblx0YWNjZXB0czoge1xuXHRcdHNjcmlwdDogXCJ0ZXh0L2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2phdmFzY3JpcHQsIFwiICtcblx0XHRcdFwiYXBwbGljYXRpb24vZWNtYXNjcmlwdCwgYXBwbGljYXRpb24veC1lY21hc2NyaXB0XCJcblx0fSxcblx0Y29udGVudHM6IHtcblx0XHRzY3JpcHQ6IC9cXGIoPzpqYXZhfGVjbWEpc2NyaXB0XFxiL1xuXHR9LFxuXHRjb252ZXJ0ZXJzOiB7XG5cdFx0XCJ0ZXh0IHNjcmlwdFwiOiBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCB0ZXh0ICk7XG5cdFx0XHRyZXR1cm4gdGV4dDtcblx0XHR9XG5cdH1cbn0gKTtcblxuLy8gSGFuZGxlIGNhY2hlJ3Mgc3BlY2lhbCBjYXNlIGFuZCBjcm9zc0RvbWFpblxualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwic2NyaXB0XCIsIGZ1bmN0aW9uKCBzICkge1xuXHRpZiAoIHMuY2FjaGUgPT09IHVuZGVmaW5lZCApIHtcblx0XHRzLmNhY2hlID0gZmFsc2U7XG5cdH1cblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xuXHRcdHMudHlwZSA9IFwiR0VUXCI7XG5cdH1cbn0gKTtcblxuLy8gQmluZCBzY3JpcHQgdGFnIGhhY2sgdHJhbnNwb3J0XG5qUXVlcnkuYWpheFRyYW5zcG9ydCggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XG5cblx0Ly8gVGhpcyB0cmFuc3BvcnQgb25seSBkZWFscyB3aXRoIGNyb3NzIGRvbWFpbiBvciBmb3JjZWQtYnktYXR0cnMgcmVxdWVzdHNcblx0aWYgKCBzLmNyb3NzRG9tYWluIHx8IHMuc2NyaXB0QXR0cnMgKSB7XG5cdFx0dmFyIHNjcmlwdCwgY2FsbGJhY2s7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBfLCBjb21wbGV0ZSApIHtcblx0XHRcdFx0c2NyaXB0ID0galF1ZXJ5KCBcIjxzY3JpcHQ+XCIgKVxuXHRcdFx0XHRcdC5hdHRyKCBzLnNjcmlwdEF0dHJzIHx8IHt9IClcblx0XHRcdFx0XHQucHJvcCggeyBjaGFyc2V0OiBzLnNjcmlwdENoYXJzZXQsIHNyYzogcy51cmwgfSApXG5cdFx0XHRcdFx0Lm9uKCBcImxvYWQgZXJyb3JcIiwgY2FsbGJhY2sgPSBmdW5jdGlvbiggZXZ0ICkge1xuXHRcdFx0XHRcdFx0c2NyaXB0LnJlbW92ZSgpO1xuXHRcdFx0XHRcdFx0Y2FsbGJhY2sgPSBudWxsO1xuXHRcdFx0XHRcdFx0aWYgKCBldnQgKSB7XG5cdFx0XHRcdFx0XHRcdGNvbXBsZXRlKCBldnQudHlwZSA9PT0gXCJlcnJvclwiID8gNDA0IDogMjAwLCBldnQudHlwZSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHQvLyBVc2UgbmF0aXZlIERPTSBtYW5pcHVsYXRpb24gdG8gYXZvaWQgb3VyIGRvbU1hbmlwIEFKQVggdHJpY2tlcnlcblx0XHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCggc2NyaXB0WyAwIF0gKTtcblx0XHRcdH0sXG5cdFx0XHRhYm9ydDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdH1cbn0gKTtcblxuXG5cblxudmFyIG9sZENhbGxiYWNrcyA9IFtdLFxuXHRyanNvbnAgPSAvKD0pXFw/KD89JnwkKXxcXD9cXD8vO1xuXG4vLyBEZWZhdWx0IGpzb25wIHNldHRpbmdzXG5qUXVlcnkuYWpheFNldHVwKCB7XG5cdGpzb25wOiBcImNhbGxiYWNrXCIsXG5cdGpzb25wQ2FsbGJhY2s6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBjYWxsYmFjayA9IG9sZENhbGxiYWNrcy5wb3AoKSB8fCAoIGpRdWVyeS5leHBhbmRvICsgXCJfXCIgKyAoIG5vbmNlLmd1aWQrKyApICk7XG5cdFx0dGhpc1sgY2FsbGJhY2sgXSA9IHRydWU7XG5cdFx0cmV0dXJuIGNhbGxiYWNrO1xuXHR9XG59ICk7XG5cbi8vIERldGVjdCwgbm9ybWFsaXplIG9wdGlvbnMgYW5kIGluc3RhbGwgY2FsbGJhY2tzIGZvciBqc29ucCByZXF1ZXN0c1xualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwianNvbiBqc29ucFwiLCBmdW5jdGlvbiggcywgb3JpZ2luYWxTZXR0aW5ncywganFYSFIgKSB7XG5cblx0dmFyIGNhbGxiYWNrTmFtZSwgb3ZlcndyaXR0ZW4sIHJlc3BvbnNlQ29udGFpbmVyLFxuXHRcdGpzb25Qcm9wID0gcy5qc29ucCAhPT0gZmFsc2UgJiYgKCByanNvbnAudGVzdCggcy51cmwgKSA/XG5cdFx0XHRcInVybFwiIDpcblx0XHRcdHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0KCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKVxuXHRcdFx0XHRcdC5pbmRleE9mKCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiICkgPT09IDAgJiZcblx0XHRcdFx0cmpzb25wLnRlc3QoIHMuZGF0YSApICYmIFwiZGF0YVwiXG5cdFx0KTtcblxuXHQvLyBIYW5kbGUgaWZmIHRoZSBleHBlY3RlZCBkYXRhIHR5cGUgaXMgXCJqc29ucFwiIG9yIHdlIGhhdmUgYSBwYXJhbWV0ZXIgdG8gc2V0XG5cdGlmICgganNvblByb3AgfHwgcy5kYXRhV
1HlwZXNbIDAgXSA9PT0gXCJqc29ucFwiICkge1xuXG5cdFx0Ly8gR2V0IGNhbGxiYWNrIG5hbWUsIHJlbWVtYmVyaW5nIHByZWV4aXN0aW5nIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCBpdFxuXHRcdGNhbGxiYWNrTmFtZSA9IHMuanNvbnBDYWxsYmFjayA9IGlzRnVuY3Rpb24oIHMuanNvbnBDYWxsYmFjayApID9cblx0XHRcdHMuanNvbnBDYWxsYmFjaygpIDpcblx0XHRcdHMuanNvbnBDYWxsYmFjaztcblxuXHRcdC8vIEluc2VydCBjYWxsYmFjayBpbnRvIHVybCBvciBmb3JtIGRhdGFcblx0XHRpZiAoIGpzb25Qcm9wICkge1xuXHRcdFx0c1sganNvblByb3AgXSA9IHNbIGpzb25Qcm9wIF0ucmVwbGFjZSggcmpzb25wLCBcIiQxXCIgKyBjYWxsYmFja05hbWUgKTtcblx0XHR9IGVsc2UgaWYgKCBzLmpzb25wICE9PSBmYWxzZSApIHtcblx0XHRcdHMudXJsICs9ICggcnF1ZXJ5LnRlc3QoIHMudXJsICkgPyBcIiZcIiA6IFwiP1wiICkgKyBzLmpzb25wICsgXCI9XCIgKyBjYWxsYmFja05hbWU7XG5cdFx0fVxuXG5cdFx0Ly8gVXNlIGRhdGEgY29udmVydGVyIHRvIHJldHJpZXZlIGpzb24gYWZ0ZXIgc2NyaXB0IGV4ZWN1dGlvblxuXHRcdHMuY29udmVydGVyc1sgXCJzY3JpcHQganNvblwiIF0gPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggIXJlc3BvbnNlQ29udGFpbmVyICkge1xuXHRcdFx0XHRqUXVlcnkuZXJyb3IoIGNhbGxiYWNrTmFtZSArIFwiIHdhcyBub3QgY2FsbGVkXCIgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXNwb25zZUNvbnRhaW5lclsgMCBdO1xuXHRcdH07XG5cblx0XHQvLyBGb3JjZSBqc29uIGRhdGFUeXBlXG5cdFx0cy5kYXRhVHlwZXNbIDAgXSA9IFwianNvblwiO1xuXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja1xuXHRcdG92ZXJ3cml0dGVuID0gd2luZG93WyBjYWxsYmFja05hbWUgXTtcblx0XHR3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IGFyZ3VtZW50cztcblx0XHR9O1xuXG5cdFx0Ly8gQ2xlYW4tdXAgZnVuY3Rpb24gKGZpcmVzIGFmdGVyIGNvbnZlcnRlcnMpXG5cdFx0anFYSFIuYWx3YXlzKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gSWYgcHJldmlvdXMgdmFsdWUgZGlkbid0IGV4aXN0IC0gcmVtb3ZlIGl0XG5cdFx0XHRpZiAoIG92ZXJ3cml0dGVuID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdGpRdWVyeSggd2luZG93ICkucmVtb3ZlUHJvcCggY2FsbGJhY2tOYW1lICk7XG5cblx0XHRcdC8vIE90aGVyd2lzZSByZXN0b3JlIHByZWV4aXN0aW5nIHZhbHVlXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gb3ZlcndyaXR0ZW47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNhdmUgYmFjayBhcyBmcmVlXG5cdFx0XHRpZiAoIHNbIGNhbGxiYWNrTmFtZSBdICkge1xuXG5cdFx0XHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHJlLXVzaW5nIHRoZSBvcHRpb25zIGRvZXNuJ3Qgc2NyZXcgdGhpbmdzIGFyb3VuZFxuXHRcdFx0XHRzLmpzb25wQ2FsbGJhY2sgPSBvcmlnaW5hbFNldHRpbmdzLmpzb25wQ2FsbGJhY2s7XG5cblx0XHRcdFx0Ly8gU2F2ZSB0aGUgY2FsbGJhY2sgbmFtZSBmb3IgZnV0dXJlIHVzZVxuXHRcdFx0XHRvbGRDYWxsYmFja3MucHVzaCggY2FsbGJhY2tOYW1lICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENhbGwgaWYgaXQgd2FzIGEgZnVuY3Rpb24gYW5kIHdlIGhhdmUgYSByZXNwb25zZVxuXHRcdFx0aWYgKCByZXNwb25zZUNvbnRhaW5lciAmJiBpc0Z1bmN0aW9uKCBvdmVyd3JpdHRlbiApICkge1xuXHRcdFx0XHRvdmVyd3JpdHRlbiggcmVzcG9uc2VDb250YWluZXJbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IG92ZXJ3cml0dGVuID0gdW5kZWZpbmVkO1xuXHRcdH0gKTtcblxuXHRcdC8vIERlbGVnYXRlIHRvIHNjcmlwdFxuXHRcdHJldHVybiBcInNjcmlwdFwiO1xuXHR9XG59ICk7XG5cblxuXG5cbi8vIFN1cHBvcnQ6IFNhZmFyaSA4IG9ubHlcbi8vIEluIFNhZmFyaSA4IGRvY3VtZW50cyBjcmVhdGVkIHZpYSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnRcbi8vIGNvbGxhcHNlIHNpYmxpbmcgZm9ybXM6IHRoZSBzZWNvbmQgb25lIGJlY29tZXMgYSBjaGlsZCBvZiB0aGUgZmlyc3Qgb25lLlxuLy8gQmVjYXVzZSBvZiB0aGF0LCB0aGlzIHNlY3VyaXR5IG1lYXN1cmUgaGFzIHRvIGJlIGRpc2FibGVkIGluIFNhZmFyaSA4LlxuLy8gaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTEzNzMzN1xuc3VwcG9ydC5jcmVhdGVIVE1MRG9jdW1lbnQgPSAoIGZ1bmN0aW9uKCkge1xuXHR2YXIgYm9keSA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCggXCJcIiApLmJvZHk7XG5cdGJvZHkuaW5uZXJIVE1MID0gXCI8Zm9ybT48L2Zvcm0+PGZvcm0+PC9mb3JtPlwiO1xuXHRyZXR1cm4gYm9keS5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMjtcbn0gKSgpO1xuXG5cbi8vIEFyZ3VtZW50IFwiZGF0YVwiIHNob3VsZCBiZSBzdHJpbmcgb2YgaHRtbFxuLy8gY29udGV4dCAob3B0aW9uYWwpOiBJZiBzcGVjaWZpZWQsIHRoZSBmcmFnbWVudCB3aWxsIGJlIGNyZWF0ZWQgaW4gdGhpcyBjb250ZXh0LFxuLy8gZGVmYXVsdHMgdG8gZG9jdW1lbnRcbi8vIGtlZXBTY3JpcHRzIChvcHRpb25hbCk6IElmIHRydWUsIHdpbGwgaW5jbHVkZSBzY3JpcHRzIHBhc3NlZCBpbiB0aGUgaHRtbCBzdHJpbmdcbmpRdWVyeS5wYXJzZUhUTUwgPSBmdW5jdGlvbiggZGF0YSwgY29udGV4dCwga2VlcFNjcmlwdHMgKSB7XG5cdGlmICggdHlwZW9mIGRhdGEgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIFtdO1xuXHR9XG5cdGlmICggdHlwZW9mIGNvbnRleHQgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdGtlZXBTY3JpcHRzID0gY29udGV4dDtcblx0XHRjb250ZXh0ID0gZmFsc2U7XG5cdH1cblxuXHR2YXIgYmFzZSwgcGFyc2VkLCBzY3JpcHRzO1xuXG5cdGlmICggIWNvbnRleHQgKSB7XG5cblx0XHQvLyBTdG9wIHNjcmlwdHMgb3IgaW5saW5lIGV2ZW50IGhhbmRsZXJzIGZyb20gYmVpbmcgZXhlY3V0ZWQgaW1tZWRpYXRlbHlcblx0XHQvLyBieSB1c2luZyBkb2N1bWVudC5pbXBsZW1lbnRhdGlvblxuXHRcdGlmICggc3VwcG9ydC5jcmVhdGVIVE1MRG9jdW1lbnQgKSB7XG5cdFx0XHRjb250ZXh0ID0gZG9jdW1lbnQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCBcIlwiICk7XG5cblx0XHRcdC8vIFNldCB0aGUgYmFzZSBocmVmIGZvciB0aGUgY3JlYXRlZCBkb2N1bWVudFxuXHRcdFx0Ly8gc28gYW55IHBhcnNlZCBlbGVtZW50cyB3aXRoIFVSTHNcblx0XHRcdC8vIGFyZSBiYXNlZCBvbiB0aGUgZG9jdW1lbnQncyBVUkwgKGdoLTI5NjUpXG5cdFx0XHRiYXNlID0gY29udGV4dC5jcmVhdGVFbGVtZW50KCBcImJhc2VcIiApO1xuXHRcdFx0YmFzZS5ocmVmID0gZG9jdW1lbnQubG9jYXRpb24uaHJlZjtcblx0XHRcdGNvbnRleHQuaGVhZC5hcHBlbmRDaGlsZCggYmFzZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb250ZXh0ID0gZG9jdW1lbnQ7XG5cdFx0fVxuXHR9XG5cblx0cGFyc2VkID0gcnNpbmdsZVRhZy5leGVjKCBkYXRhICk7XG5cdHNjcmlwdHMgPSAha2
1VlcFNjcmlwdHMgJiYgW107XG5cblx0Ly8gU2luZ2xlIHRhZ1xuXHRpZiAoIHBhcnNlZCApIHtcblx0XHRyZXR1cm4gWyBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoIHBhcnNlZFsgMSBdICkgXTtcblx0fVxuXG5cdHBhcnNlZCA9IGJ1aWxkRnJhZ21lbnQoIFsgZGF0YSBdLCBjb250ZXh0LCBzY3JpcHRzICk7XG5cblx0aWYgKCBzY3JpcHRzICYmIHNjcmlwdHMubGVuZ3RoICkge1xuXHRcdGpRdWVyeSggc2NyaXB0cyApLnJlbW92ZSgpO1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeS5tZXJnZSggW10sIHBhcnNlZC5jaGlsZE5vZGVzICk7XG59O1xuXG5cbi8qKlxuICogTG9hZCBhIHVybCBpbnRvIGEgcGFnZVxuICovXG5qUXVlcnkuZm4ubG9hZCA9IGZ1bmN0aW9uKCB1cmwsIHBhcmFtcywgY2FsbGJhY2sgKSB7XG5cdHZhciBzZWxlY3RvciwgdHlwZSwgcmVzcG9uc2UsXG5cdFx0c2VsZiA9IHRoaXMsXG5cdFx0b2ZmID0gdXJsLmluZGV4T2YoIFwiIFwiICk7XG5cblx0aWYgKCBvZmYgPiAtMSApIHtcblx0XHRzZWxlY3RvciA9IHN0cmlwQW5kQ29sbGFwc2UoIHVybC5zbGljZSggb2ZmICkgKTtcblx0XHR1cmwgPSB1cmwuc2xpY2UoIDAsIG9mZiApO1xuXHR9XG5cblx0Ly8gSWYgaXQncyBhIGZ1bmN0aW9uXG5cdGlmICggaXNGdW5jdGlvbiggcGFyYW1zICkgKSB7XG5cblx0XHQvLyBXZSBhc3N1bWUgdGhhdCBpdCdzIHRoZSBjYWxsYmFja1xuXHRcdGNhbGxiYWNrID0gcGFyYW1zO1xuXHRcdHBhcmFtcyA9IHVuZGVmaW5lZDtcblxuXHQvLyBPdGhlcndpc2UsIGJ1aWxkIGEgcGFyYW0gc3RyaW5nXG5cdH0gZWxzZSBpZiAoIHBhcmFtcyAmJiB0eXBlb2YgcGFyYW1zID09PSBcIm9iamVjdFwiICkge1xuXHRcdHR5cGUgPSBcIlBPU1RcIjtcblx0fVxuXG5cdC8vIElmIHdlIGhhdmUgZWxlbWVudHMgdG8gbW9kaWZ5LCBtYWtlIHRoZSByZXF1ZXN0XG5cdGlmICggc2VsZi5sZW5ndGggPiAwICkge1xuXHRcdGpRdWVyeS5hamF4KCB7XG5cdFx0XHR1cmw6IHVybCxcblxuXHRcdFx0Ly8gSWYgXCJ0eXBlXCIgdmFyaWFibGUgaXMgdW5kZWZpbmVkLCB0aGVuIFwiR0VUXCIgbWV0aG9kIHdpbGwgYmUgdXNlZC5cblx0XHRcdC8vIE1ha2UgdmFsdWUgb2YgdGhpcyBmaWVsZCBleHBsaWNpdCBzaW5jZVxuXHRcdFx0Ly8gdXNlciBjYW4gb3ZlcnJpZGUgaXQgdGhyb3VnaCBhamF4U2V0dXAgbWV0aG9kXG5cdFx0XHR0eXBlOiB0eXBlIHx8IFwiR0VUXCIsXG5cdFx0XHRkYXRhVHlwZTogXCJodG1sXCIsXG5cdFx0XHRkYXRhOiBwYXJhbXNcblx0XHR9ICkuZG9uZSggZnVuY3Rpb24oIHJlc3BvbnNlVGV4dCApIHtcblxuXHRcdFx0Ly8gU2F2ZSByZXNwb25zZSBmb3IgdXNlIGluIGNvbXBsZXRlIGNhbGxiYWNrXG5cdFx0XHRyZXNwb25zZSA9IGFyZ3VtZW50cztcblxuXHRcdFx0c2VsZi5odG1sKCBzZWxlY3RvciA/XG5cblx0XHRcdFx0Ly8gSWYgYSBzZWxlY3RvciB3YXMgc3BlY2lmaWVkLCBsb2NhdGUgdGhlIHJpZ2h0IGVsZW1lbnRzIGluIGEgZHVtbXkgZGl2XG5cdFx0XHRcdC8vIEV4Y2x1ZGUgc2NyaXB0cyB0byBhdm9pZCBJRSAnUGVybWlzc2lvbiBEZW5pZWQnIGVycm9yc1xuXHRcdFx0XHRqUXVlcnkoIFwiPGRpdj5cIiApLmFwcGVuZCggalF1ZXJ5LnBhcnNlSFRNTCggcmVzcG9uc2VUZXh0ICkgKS5maW5kKCBzZWxlY3RvciApIDpcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UgdXNlIHRoZSBmdWxsIHJlc3VsdFxuXHRcdFx0XHRyZXNwb25zZVRleHQgKTtcblxuXHRcdC8vIElmIHRoZSByZXF1ZXN0IHN1Y2NlZWRzLCB0aGlzIGZ1bmN0aW9uIGdldHMgXCJkYXRhXCIsIFwic3RhdHVzXCIsIFwianFYSFJcIlxuXHRcdC8vIGJ1dCB0aGV5IGFyZSBpZ25vcmVkIGJlY2F1c2UgcmVzcG9uc2Ugd2FzIHNldCBhYm92ZS5cblx0XHQvLyBJZiBpdCBmYWlscywgdGhpcyBmdW5jdGlvbiBnZXRzIFwianFYSFJcIiwgXCJzdGF0dXNcIiwgXCJlcnJvclwiXG5cdFx0fSApLmFsd2F5cyggY2FsbGJhY2sgJiYgZnVuY3Rpb24oIGpxWEhSLCBzdGF0dXMgKSB7XG5cdFx0XHRzZWxmLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRjYWxsYmFjay5hcHBseSggdGhpcywgcmVzcG9uc2UgfHwgWyBqcVhIUi5yZXNwb25zZVRleHQsIHN0YXR1cywganFYSFIgXSApO1xuXHRcdFx0fSApO1xuXHRcdH0gKTtcblx0fVxuXG5cdHJldHVybiB0aGlzO1xufTtcblxuXG5cblxualF1ZXJ5LmV4cHIucHNldWRvcy5hbmltYXRlZCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRyZXR1cm4galF1ZXJ5LmdyZXAoIGpRdWVyeS50aW1lcnMsIGZ1bmN0aW9uKCBmbiApIHtcblx0XHRyZXR1cm4gZWxlbSA9PT0gZm4uZWxlbTtcblx0fSApLmxlbmd0aDtcbn07XG5cblxuXG5cbmpRdWVyeS5vZmZzZXQgPSB7XG5cdHNldE9mZnNldDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGkgKSB7XG5cdFx0dmFyIGN1clBvc2l0aW9uLCBjdXJMZWZ0LCBjdXJDU1NUb3AsIGN1clRvcCwgY3VyT2Zmc2V0LCBjdXJDU1NMZWZ0LCBjYWxjdWxhdGVQb3NpdGlvbixcblx0XHRcdHBvc2l0aW9uID0galF1ZXJ5LmNzcyggZWxlbSwgXCJwb3NpdGlvblwiICksXG5cdFx0XHRjdXJFbGVtID0galF1ZXJ5KCBlbGVtICksXG5cdFx0XHRwcm9wcyA9IHt9O1xuXG5cdFx0Ly8gU2V0IHBvc2l0aW9uIGZpcnN0LCBpbi1jYXNlIHRvcC9sZWZ0IGFyZSBzZXQgZXZlbiBvbiBzdGF0aWMgZWxlbVxuXHRcdGlmICggcG9zaXRpb24gPT09IFwic3RhdGljXCIgKSB7XG5cdFx0XHRlbGVtLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuXHRcdH1cblxuXHRcdGN1ck9mZnNldCA9IGN1ckVsZW0ub2Zmc2V0KCk7XG5cdFx0Y3VyQ1NTVG9wID0galF1ZXJ5LmNzcyggZWxlbSwgXCJ0b3BcIiApO1xuXHRcdGN1ckNTU0xlZnQgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImxlZnRcIiApO1xuXHRcdGNhbGN1bGF0ZVBvc2l0aW9uID0gKCBwb3NpdGlvbiA9PT0gXCJhYnNvbHV0ZVwiIHx8IHBvc2l0aW9uID09PSBcImZpeGVkXCIgKSAmJlxuXHRcdFx0KCBjdXJDU1NUb3AgKyBjdXJDU1NMZWZ0ICkuaW5kZXhPZiggXCJhdXRvXCIgKSA+IC0xO1xuXG5cdFx0Ly8gTmVlZCB0byBiZSBhYmxlIHRvIGNhbGN1bGF0ZSBwb3NpdGlvbiBpZiBlaXRoZXJcblx0XHQvLyB0b3Agb3IgbGVmdCBpcyBhdXRvIGFuZCBwb3NpdGlvbiBpcyBlaXRoZXIgYWJzb2x1dGUgb3IgZml4ZWRcblx0XHRpZiAoIGNhbGN1bGF0ZVBvc2l0aW9uICkge1xuXHRcdFx0Y3VyUG9zaXRpb24gPSBjdXJFbGVtLnBvc2l0aW9uKCk7XG5cdFx0XHRjdXJUb3AgPSBjdXJQb3NpdGlvbi50b3A7XG5cdFx0XHRjdXJMZWZ0ID0gY3VyUG9zaXRpb24ubGVmdDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdXJUb3AgPSBwYXJzZU
1Zsb2F0KCBjdXJDU1NUb3AgKSB8fCAwO1xuXHRcdFx0Y3VyTGVmdCA9IHBhcnNlRmxvYXQoIGN1ckNTU0xlZnQgKSB8fCAwO1xuXHRcdH1cblxuXHRcdGlmICggaXNGdW5jdGlvbiggb3B0aW9ucyApICkge1xuXG5cdFx0XHQvLyBVc2UgalF1ZXJ5LmV4dGVuZCBoZXJlIHRvIGFsbG93IG1vZGlmaWNhdGlvbiBvZiBjb29yZGluYXRlcyBhcmd1bWVudCAoZ2gtMTg0OClcblx0XHRcdG9wdGlvbnMgPSBvcHRpb25zLmNhbGwoIGVsZW0sIGksIGpRdWVyeS5leHRlbmQoIHt9LCBjdXJPZmZzZXQgKSApO1xuXHRcdH1cblxuXHRcdGlmICggb3B0aW9ucy50b3AgIT0gbnVsbCApIHtcblx0XHRcdHByb3BzLnRvcCA9ICggb3B0aW9ucy50b3AgLSBjdXJPZmZzZXQudG9wICkgKyBjdXJUb3A7XG5cdFx0fVxuXHRcdGlmICggb3B0aW9ucy5sZWZ0ICE9IG51bGwgKSB7XG5cdFx0XHRwcm9wcy5sZWZ0ID0gKCBvcHRpb25zLmxlZnQgLSBjdXJPZmZzZXQubGVmdCApICsgY3VyTGVmdDtcblx0XHR9XG5cblx0XHRpZiAoIFwidXNpbmdcIiBpbiBvcHRpb25zICkge1xuXHRcdFx0b3B0aW9ucy51c2luZy5jYWxsKCBlbGVtLCBwcm9wcyApO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1ckVsZW0uY3NzKCBwcm9wcyApO1xuXHRcdH1cblx0fVxufTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdC8vIG9mZnNldCgpIHJlbGF0ZXMgYW4gZWxlbWVudCdzIGJvcmRlciBib3ggdG8gdGhlIGRvY3VtZW50IG9yaWdpblxuXHRvZmZzZXQ6IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXG5cdFx0Ly8gUHJlc2VydmUgY2hhaW5pbmcgZm9yIHNldHRlclxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiBvcHRpb25zID09PSB1bmRlZmluZWQgP1xuXHRcdFx0XHR0aGlzIDpcblx0XHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0XHRqUXVlcnkub2Zmc2V0LnNldE9mZnNldCggdGhpcywgb3B0aW9ucywgaSApO1xuXHRcdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0dmFyIHJlY3QsIHdpbixcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XG5cblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFJldHVybiB6ZXJvcyBmb3IgZGlzY29ubmVjdGVkIGFuZCBoaWRkZW4gKGRpc3BsYXk6IG5vbmUpIGVsZW1lbnRzIChnaC0yMzEwKVxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuXHRcdC8vIFJ1bm5pbmcgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG9uIGFcblx0XHQvLyBkaXNjb25uZWN0ZWQgbm9kZSBpbiBJRSB0aHJvd3MgYW4gZXJyb3Jcblx0XHRpZiAoICFlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoICkge1xuXHRcdFx0cmV0dXJuIHsgdG9wOiAwLCBsZWZ0OiAwIH07XG5cdFx0fVxuXG5cdFx0Ly8gR2V0IGRvY3VtZW50LXJlbGF0aXZlIHBvc2l0aW9uIGJ5IGFkZGluZyB2aWV3cG9ydCBzY3JvbGwgdG8gdmlld3BvcnQtcmVsYXRpdmUgZ0JDUlxuXHRcdHJlY3QgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdHdpbiA9IGVsZW0ub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlldztcblx0XHRyZXR1cm4ge1xuXHRcdFx0dG9wOiByZWN0LnRvcCArIHdpbi5wYWdlWU9mZnNldCxcblx0XHRcdGxlZnQ6IHJlY3QubGVmdCArIHdpbi5wYWdlWE9mZnNldFxuXHRcdH07XG5cdH0sXG5cblx0Ly8gcG9zaXRpb24oKSByZWxhdGVzIGFuIGVsZW1lbnQncyBtYXJnaW4gYm94IHRvIGl0cyBvZmZzZXQgcGFyZW50J3MgcGFkZGluZyBib3hcblx0Ly8gVGhpcyBjb3JyZXNwb25kcyB0byB0aGUgYmVoYXZpb3Igb2YgQ1NTIGFic29sdXRlIHBvc2l0aW9uaW5nXG5cdHBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRpZiAoICF0aGlzWyAwIF0gKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIG9mZnNldFBhcmVudCwgb2Zmc2V0LCBkb2MsXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdLFxuXHRcdFx0cGFyZW50T2Zmc2V0ID0geyB0b3A6IDAsIGxlZnQ6IDAgfTtcblxuXHRcdC8vIHBvc2l0aW9uOmZpeGVkIGVsZW1lbnRzIGFyZSBvZmZzZXQgZnJvbSB0aGUgdmlld3BvcnQsIHdoaWNoIGl0c2VsZiBhbHdheXMgaGFzIHplcm8gb2Zmc2V0XG5cdFx0aWYgKCBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSA9PT0gXCJmaXhlZFwiICkge1xuXG5cdFx0XHQvLyBBc3N1bWUgcG9zaXRpb246Zml4ZWQgaW1wbGllcyBhdmFpbGFiaWxpdHkgb2YgZ2V0Qm91bmRpbmdDbGllbnRSZWN0XG5cdFx0XHRvZmZzZXQgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdG9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG5cblx0XHRcdC8vIEFjY291bnQgZm9yIHRoZSAqcmVhbCogb2Zmc2V0IHBhcmVudCwgd2hpY2ggY2FuIGJlIHRoZSBkb2N1bWVudCBvciBpdHMgcm9vdCBlbGVtZW50XG5cdFx0XHQvLyB3aGVuIGEgc3RhdGljYWxseSBwb3NpdGlvbmVkIGVsZW1lbnQgaXMgaWRlbnRpZmllZFxuXHRcdFx0ZG9jID0gZWxlbS5vd25lckRvY3VtZW50O1xuXHRcdFx0b2Zmc2V0UGFyZW50ID0gZWxlbS5vZmZzZXRQYXJlbnQgfHwgZG9jLmRvY3VtZW50RWxlbWVudDtcblx0XHRcdHdoaWxlICggb2Zmc2V0UGFyZW50ICYmXG5cdFx0XHRcdCggb2Zmc2V0UGFyZW50ID09PSBkb2MuYm9keSB8fCBvZmZzZXRQYXJlbnQgPT09IGRvYy5kb2N1bWVudEVsZW1lbnQgKSAmJlxuXHRcdFx0XHRqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnQsIFwicG9zaXRpb25cIiApID09PSBcInN0YXRpY1wiICkge1xuXG5cdFx0XHRcdG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudC5wYXJlbnROb2RlO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBvZmZzZXRQYXJlbnQgJiYgb2Zmc2V0UGFyZW50ICE9PSBlbGVtICYmIG9mZnNldFBhcmVudC5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdFx0XHQvLyBJbmNvcnBvcmF0ZSBib3JkZXJzIGludG8gaXRzIG9mZnNldCwgc2luY2UgdGhleSBhcmUgb3V0c2lkZSBpdHMgY29udGVudCBvcmlnaW5cblx0XHRcdFx0cGFyZW50T2Zmc2V0ID0galF1ZXJ5KCBvZmZzZXRQYXJlbnQgKS5vZmZzZXQoKTtcblx0XHRcdFx0cGFyZW50T2Zmc2V0LnRvcCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnQsIFwiYm9yZGVyVG9wV2lkdGhcIiwgdHJ1ZSApO1xuXHRcdFx0XHRwYXJlbnRPZmZzZXQubGVmdCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnQsIFwiYm9yZGVyTGVmdFdpZHRoXCIsIHRydWUgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTdWJ0cmFjdCBwYXJlbnQgb2Zmc2V0cyBhbmQgZWxlbWVudCBtYXJnaW5zXG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogb2Zmc2V0LnRvcCAtIHBhcmVudE9mZnNldC50b3AgLSBqUXVlcnkuY3NzKCBlbGVtLCBcIm1hcmdpblRvcFwiLCB0cnVlICksXG5cdFx0XHRsZWZ0OiBvZmZzZXQubGVmdCAtIHBhcmVudE9mZnNldC5sZWZ0IC0galF1ZXJ5LmNzcyggZWxlbSwgXCJtYXJnaW5MZWZ0XCIsIHRydWUgKVxuXHRcdH07XG5cdH0sXG5cblx0Ly8gVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gZG9jdW1lbnRFbGVtZW50IGluIHRoZSBmb2xsb3dpbmcgY2FzZXM6XG5cdC8vIDEpIEZvciB0aGUgZWxlbWVudCBpbnNpZGUgdGhlIGlmcmFtZSB3aXRob3V0IG9mZnNldFBhcmVudCwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm5cblx0Ly8gICAgZG9jdW1lbnRFbGVtZW50IG9mIHRoZSBwYXJlbnQgd2luZG93XG5cdC8vID
1IpIEZvciB0aGUgaGlkZGVuIG9yIGRldGFjaGVkIGVsZW1lbnRcblx0Ly8gMykgRm9yIGJvZHkgb3IgaHRtbCBlbGVtZW50LCBpLmUuIGluIGNhc2Ugb2YgdGhlIGh0bWwgbm9kZSAtIGl0IHdpbGwgcmV0dXJuIGl0c2VsZlxuXHQvL1xuXHQvLyBidXQgdGhvc2UgZXhjZXB0aW9ucyB3ZXJlIG5ldmVyIHByZXNlbnRlZCBhcyBhIHJlYWwgbGlmZSB1c2UtY2FzZXNcblx0Ly8gYW5kIG1pZ2h0IGJlIGNvbnNpZGVyZWQgYXMgbW9yZSBwcmVmZXJhYmxlIHJlc3VsdHMuXG5cdC8vXG5cdC8vIFRoaXMgbG9naWMsIGhvd2V2ZXIsIGlzIG5vdCBndWFyYW50ZWVkIGFuZCBjYW4gY2hhbmdlIGF0IGFueSBwb2ludCBpbiB0aGUgZnV0dXJlXG5cdG9mZnNldFBhcmVudDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFwKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudDtcblxuXHRcdFx0d2hpbGUgKCBvZmZzZXRQYXJlbnQgJiYgalF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcInBvc2l0aW9uXCIgKSA9PT0gXCJzdGF0aWNcIiApIHtcblx0XHRcdFx0b2Zmc2V0UGFyZW50ID0gb2Zmc2V0UGFyZW50Lm9mZnNldFBhcmVudDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG9mZnNldFBhcmVudCB8fCBkb2N1bWVudEVsZW1lbnQ7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbi8vIENyZWF0ZSBzY3JvbGxMZWZ0IGFuZCBzY3JvbGxUb3AgbWV0aG9kc1xualF1ZXJ5LmVhY2goIHsgc2Nyb2xsTGVmdDogXCJwYWdlWE9mZnNldFwiLCBzY3JvbGxUb3A6IFwicGFnZVlPZmZzZXRcIiB9LCBmdW5jdGlvbiggbWV0aG9kLCBwcm9wICkge1xuXHR2YXIgdG9wID0gXCJwYWdlWU9mZnNldFwiID09PSBwcm9wO1xuXG5cdGpRdWVyeS5mblsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBtZXRob2QsIHZhbCApIHtcblxuXHRcdFx0Ly8gQ29hbGVzY2UgZG9jdW1lbnRzIGFuZCB3aW5kb3dzXG5cdFx0XHR2YXIgd2luO1xuXHRcdFx0aWYgKCBpc1dpbmRvdyggZWxlbSApICkge1xuXHRcdFx0XHR3aW4gPSBlbGVtO1xuXHRcdFx0fSBlbHNlIGlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0d2luID0gZWxlbS5kZWZhdWx0Vmlldztcblx0XHRcdH1cblxuXHRcdFx0aWYgKCB2YWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHdpbiA/IHdpblsgcHJvcCBdIDogZWxlbVsgbWV0aG9kIF07XG5cdFx0XHR9XG5cblx0XHRcdGlmICggd2luICkge1xuXHRcdFx0XHR3aW4uc2Nyb2xsVG8oXG5cdFx0XHRcdFx0IXRvcCA/IHZhbCA6IHdpbi5wYWdlWE9mZnNldCxcblx0XHRcdFx0XHR0b3AgPyB2YWwgOiB3aW4ucGFnZVlPZmZzZXRcblx0XHRcdFx0KTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbVsgbWV0aG9kIF0gPSB2YWw7XG5cdFx0XHR9XG5cdFx0fSwgbWV0aG9kLCB2YWwsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fTtcbn0gKTtcblxuLy8gU3VwcG9ydDogU2FmYXJpIDw9NyAtIDkuMSwgQ2hyb21lIDw9MzcgLSA0OVxuLy8gQWRkIHRoZSB0b3AvbGVmdCBjc3NIb29rcyB1c2luZyBqUXVlcnkuZm4ucG9zaXRpb25cbi8vIFdlYmtpdCBidWc6IGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0yOTA4NFxuLy8gQmxpbmsgYnVnOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD01ODkzNDdcbi8vIGdldENvbXB1dGVkU3R5bGUgcmV0dXJucyBwZXJjZW50IHdoZW4gc3BlY2lmaWVkIGZvciB0b3AvbGVmdC9ib3R0b20vcmlnaHQ7XG4vLyByYXRoZXIgdGhhbiBtYWtlIHRoZSBjc3MgbW9kdWxlIGRlcGVuZCBvbiB0aGUgb2Zmc2V0IG1vZHVsZSwganVzdCBjaGVjayBmb3IgaXQgaGVyZVxualF1ZXJ5LmVhY2goIFsgXCJ0b3BcIiwgXCJsZWZ0XCIgXSwgZnVuY3Rpb24oIF9pLCBwcm9wICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIHByb3AgXSA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5waXhlbFBvc2l0aW9uLFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0XHRcdGNvbXB1dGVkID0gY3VyQ1NTKCBlbGVtLCBwcm9wICk7XG5cblx0XHRcdFx0Ly8gSWYgY3VyQ1NTIHJldHVybnMgcGVyY2VudGFnZSwgZmFsbGJhY2sgdG8gb2Zmc2V0XG5cdFx0XHRcdHJldHVybiBybnVtbm9ucHgudGVzdCggY29tcHV0ZWQgKSA/XG5cdFx0XHRcdFx0alF1ZXJ5KCBlbGVtICkucG9zaXRpb24oKVsgcHJvcCBdICsgXCJweFwiIDpcblx0XHRcdFx0XHRjb21wdXRlZDtcblx0XHRcdH1cblx0XHR9XG5cdCk7XG59ICk7XG5cblxuLy8gQ3JlYXRlIGlubmVySGVpZ2h0LCBpbm5lcldpZHRoLCBoZWlnaHQsIHdpZHRoLCBvdXRlckhlaWdodCBhbmQgb3V0ZXJXaWR0aCBtZXRob2RzXG5qUXVlcnkuZWFjaCggeyBIZWlnaHQ6IFwiaGVpZ2h0XCIsIFdpZHRoOiBcIndpZHRoXCIgfSwgZnVuY3Rpb24oIG5hbWUsIHR5cGUgKSB7XG5cdGpRdWVyeS5lYWNoKCB7XG5cdFx0cGFkZGluZzogXCJpbm5lclwiICsgbmFtZSxcblx0XHRjb250ZW50OiB0eXBlLFxuXHRcdFwiXCI6IFwib3V0ZXJcIiArIG5hbWVcblx0fSwgZnVuY3Rpb24oIGRlZmF1bHRFeHRyYSwgZnVuY05hbWUgKSB7XG5cblx0XHQvLyBNYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGhcblx0XHRqUXVlcnkuZm5bIGZ1bmNOYW1lIF0gPSBmdW5jdGlvbiggbWFyZ2luLCB2YWx1ZSApIHtcblx0XHRcdHZhciBjaGFpbmFibGUgPSBhcmd1bWVudHMubGVuZ3RoICYmICggZGVmYXVsdEV4dHJhIHx8IHR5cGVvZiBtYXJnaW4gIT09IFwiYm9vbGVhblwiICksXG5cdFx0XHRcdGV4dHJhID0gZGVmYXVsdEV4dHJhIHx8ICggbWFyZ2luID09PSB0cnVlIHx8IHZhbHVlID09PSB0cnVlID8gXCJtYXJnaW5cIiA6IFwiYm9yZGVyXCIgKTtcblxuXHRcdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIHR5cGUsIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgZG9jO1xuXG5cdFx0XHRcdGlmICggaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0XHRcdC8vICQoIHdpbmRvdyApLm91dGVyV2lkdGgvSGVpZ2h0IHJldHVybi
1B3L2ggaW5jbHVkaW5nIHNjcm9sbGJhcnMgKGdoLTE3MjkpXG5cdFx0XHRcdFx0cmV0dXJuIGZ1bmNOYW1lLmluZGV4T2YoIFwib3V0ZXJcIiApID09PSAwID9cblx0XHRcdFx0XHRcdGVsZW1bIFwiaW5uZXJcIiArIG5hbWUgXSA6XG5cdFx0XHRcdFx0XHRlbGVtLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFsgXCJjbGllbnRcIiArIG5hbWUgXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEdldCBkb2N1bWVudCB3aWR0aCBvciBoZWlnaHRcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdGRvYyA9IGVsZW0uZG9jdW1lbnRFbGVtZW50O1xuXG5cdFx0XHRcdFx0Ly8gRWl0aGVyIHNjcm9sbFtXaWR0aC9IZWlnaHRdIG9yIG9mZnNldFtXaWR0aC9IZWlnaHRdIG9yIGNsaWVudFtXaWR0aC9IZWlnaHRdLFxuXHRcdFx0XHRcdC8vIHdoaWNoZXZlciBpcyBncmVhdGVzdFxuXHRcdFx0XHRcdHJldHVybiBNYXRoLm1heChcblx0XHRcdFx0XHRcdGVsZW0uYm9keVsgXCJzY3JvbGxcIiArIG5hbWUgXSwgZG9jWyBcInNjcm9sbFwiICsgbmFtZSBdLFxuXHRcdFx0XHRcdFx0ZWxlbS5ib2R5WyBcIm9mZnNldFwiICsgbmFtZSBdLCBkb2NbIFwib2Zmc2V0XCIgKyBuYW1lIF0sXG5cdFx0XHRcdFx0XHRkb2NbIFwiY2xpZW50XCIgKyBuYW1lIF1cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgP1xuXG5cdFx0XHRcdFx0Ly8gR2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudCwgcmVxdWVzdGluZyBidXQgbm90IGZvcmNpbmcgcGFyc2VGbG9hdFxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIHR5cGUsIGV4dHJhICkgOlxuXG5cdFx0XHRcdFx0Ly8gU2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudFxuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgdHlwZSwgdmFsdWUsIGV4dHJhICk7XG5cdFx0XHR9LCB0eXBlLCBjaGFpbmFibGUgPyBtYXJnaW4gOiB1bmRlZmluZWQsIGNoYWluYWJsZSApO1xuXHRcdH07XG5cdH0gKTtcbn0gKTtcblxuXG5qUXVlcnkuZWFjaCggW1xuXHRcImFqYXhTdGFydFwiLFxuXHRcImFqYXhTdG9wXCIsXG5cdFwiYWpheENvbXBsZXRlXCIsXG5cdFwiYWpheEVycm9yXCIsXG5cdFwiYWpheFN1Y2Nlc3NcIixcblx0XCJhamF4U2VuZFwiXG5dLCBmdW5jdGlvbiggX2ksIHR5cGUgKSB7XG5cdGpRdWVyeS5mblsgdHlwZSBdID0gZnVuY3Rpb24oIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlLCBmbiApO1xuXHR9O1xufSApO1xuXG5cblxuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cblx0YmluZDogZnVuY3Rpb24oIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIG51bGwsIGRhdGEsIGZuICk7XG5cdH0sXG5cdHVuYmluZDogZnVuY3Rpb24oIHR5cGVzLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYoIHR5cGVzLCBudWxsLCBmbiApO1xuXHR9LFxuXG5cdGRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApO1xuXHR9LFxuXHR1bmRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBmbiApIHtcblxuXHRcdC8vICggbmFtZXNwYWNlICkgb3IgKCBzZWxlY3RvciwgdHlwZXMgWywgZm5dIClcblx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/XG5cdFx0XHR0aGlzLm9mZiggc2VsZWN0b3IsIFwiKipcIiApIDpcblx0XHRcdHRoaXMub2ZmKCB0eXBlcywgc2VsZWN0b3IgfHwgXCIqKlwiLCBmbiApO1xuXHR9LFxuXG5cdGhvdmVyOiBmdW5jdGlvbiggZm5PdmVyLCBmbk91dCApIHtcblx0XHRyZXR1cm4gdGhpc1xuXHRcdFx0Lm9uKCBcIm1vdXNlZW50ZXJcIiwgZm5PdmVyIClcblx0XHRcdC5vbiggXCJtb3VzZWxlYXZlXCIsIGZuT3V0IHx8IGZuT3ZlciApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5lYWNoKFxuXHQoIFwiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IHJlc2l6ZSBzY3JvbGwgY2xpY2sgZGJsY2xpY2sgXCIgK1xuXHRcIm1vdXNlZG93biBtb3VzZXVwIG1vdXNlbW92ZSBtb3VzZW92ZXIgbW91c2VvdXQgbW91c2VlbnRlciBtb3VzZWxlYXZlIFwiICtcblx0XCJjaGFuZ2Ugc2VsZWN0IHN1Ym1pdCBrZXlkb3duIGtleXByZXNzIGtleXVwIGNvbnRleHRtZW51XCIgKS5zcGxpdCggXCIgXCIgKSxcblx0ZnVuY3Rpb24oIF9pLCBuYW1lICkge1xuXG5cdFx0Ly8gSGFuZGxlIGV2ZW50IGJpbmRpbmdcblx0XHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBkYXRhLCBmbiApIHtcblx0XHRcdHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMCA/XG5cdFx0XHRcdHRoaXMub24oIG5hbWUsIG51bGwsIGRhdGEsIGZuICkgOlxuXHRcdFx0XHR0aGlzLnRyaWdnZXIoIG5hbWUgKTtcblx0XHR9O1xuXHR9XG4pO1xuXG5cblxuXG4vLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHlcbi8vIE1ha2Ugc3VyZSB3ZSB0cmltIEJPTSBhbmQgTkJTUFxuLy8gUmVxdWlyZSB0aGF0IHRoZSBcIndoaXRlc3BhY2UgcnVuXCIgc3RhcnRzIGZyb20gYSBub24td2hpdGVzcGFjZVxuLy8gdG8gYXZvaWQgTyhOXjIpIGJlaGF2aW9yIHdoZW4gdGhlIGVuZ2luZSB3b3VsZCB0cnkgbWF0Y2hpbmcgXCJcXHMrJFwiIGF0IGVhY2ggc3BhY2UgcG9zaXRpb24uXG52YXIgcnRyaW0gPSAvXltcXHNcXHVGRUZGXFx4QTBdK3woW15cXHNcXHVGRUZGXFx4QTBdKVtcXHNcXHVGRUZGXFx4QTBdKyQvZztcblxuLy8gQmluZCBhIGZ1bmN0aW9uIHRvIGEgY29udGV4dCwgb3B0aW9uYWxseSBwYXJ0aWFsbHkgYXBwbHlpbmcgYW55XG4vLyBhcmd1bWVudHMuXG4vLyBqUXVlcnkucHJveHkgaXMgZGVwcmVjYXRlZCB0byBwcm9tb3RlIHN0YW5kYXJkcyAoc3BlY2lmaWNhbGx5IEZ1bmN0aW9uI2JpbmQpXG4vLyBIb3dldmVyLCBpdCBpcyBub3Qgc2xhdGVkIGZvciByZW1vdmFsIGFueSB0aW1lIHNvb25cbmpRdWVyeS5wcm94eSA9IGZ1bmN0aW9uKCBmbiwgY29udGV4dCApIHtcblx0dmFyIHRtcCwgYXJncywgcHJveHk7XG5cblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHR0bXAgPSBmblsgY29udGV4dCBdO1xuXHRcdGNvbnRleHQgPSBmbjtcblx0XHRmbiA9IHRtcDtcblx0fVxuXG5cdC8vIFF1aWNrIGNoZWNrIHRvIGRldGVybWluZSBpZiB0YXJnZXQgaXMgY2FsbGFibGUsIGluIHRoZSBzcGVjXG5cdC8vIHRoaXMgdGhyb3dzIGEgVHlwZUVycm9yLCBidXQgd2Ugd2lsbCBqdXN0IHJldHVybi
1B1bmRlZmluZWQuXG5cdGlmICggIWlzRnVuY3Rpb24oIGZuICkgKSB7XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXG5cdC8vIFNpbXVsYXRlZCBiaW5kXG5cdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMsIDIgKTtcblx0cHJveHkgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZm4uYXBwbHkoIGNvbnRleHQgfHwgdGhpcywgYXJncy5jb25jYXQoIHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApICkgKTtcblx0fTtcblxuXHQvLyBTZXQgdGhlIGd1aWQgb2YgdW5pcXVlIGhhbmRsZXIgdG8gdGhlIHNhbWUgb2Ygb3JpZ2luYWwgaGFuZGxlciwgc28gaXQgY2FuIGJlIHJlbW92ZWRcblx0cHJveHkuZ3VpZCA9IGZuLmd1aWQgPSBmbi5ndWlkIHx8IGpRdWVyeS5ndWlkKys7XG5cblx0cmV0dXJuIHByb3h5O1xufTtcblxualF1ZXJ5LmhvbGRSZWFkeSA9IGZ1bmN0aW9uKCBob2xkICkge1xuXHRpZiAoIGhvbGQgKSB7XG5cdFx0alF1ZXJ5LnJlYWR5V2FpdCsrO1xuXHR9IGVsc2Uge1xuXHRcdGpRdWVyeS5yZWFkeSggdHJ1ZSApO1xuXHR9XG59O1xualF1ZXJ5LmlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xualF1ZXJ5LnBhcnNlSlNPTiA9IEpTT04ucGFyc2U7XG5qUXVlcnkubm9kZU5hbWUgPSBub2RlTmFtZTtcbmpRdWVyeS5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcbmpRdWVyeS5pc1dpbmRvdyA9IGlzV2luZG93O1xualF1ZXJ5LmNhbWVsQ2FzZSA9IGNhbWVsQ2FzZTtcbmpRdWVyeS50eXBlID0gdG9UeXBlO1xuXG5qUXVlcnkubm93ID0gRGF0ZS5ub3c7XG5cbmpRdWVyeS5pc051bWVyaWMgPSBmdW5jdGlvbiggb2JqICkge1xuXG5cdC8vIEFzIG9mIGpRdWVyeSAzLjAsIGlzTnVtZXJpYyBpcyBsaW1pdGVkIHRvXG5cdC8vIHN0cmluZ3MgYW5kIG51bWJlcnMgKHByaW1pdGl2ZXMgb3Igb2JqZWN0cylcblx0Ly8gdGhhdCBjYW4gYmUgY29lcmNlZCB0byBmaW5pdGUgbnVtYmVycyAoZ2gtMjY2Milcblx0dmFyIHR5cGUgPSBqUXVlcnkudHlwZSggb2JqICk7XG5cdHJldHVybiAoIHR5cGUgPT09IFwibnVtYmVyXCIgfHwgdHlwZSA9PT0gXCJzdHJpbmdcIiApICYmXG5cblx0XHQvLyBwYXJzZU
1Zsb2F0IE5hTnMgbnVtZXJpYy1jYXN0IGZhbHNlIHBvc2l0aXZlcyAoXCJcIilcblx0XHQvLyAuLi5idXQgbWlzaW50ZXJwcmV0cyBsZWFkaW5nLW51bWJlciBzdHJpbmdzLCBwYXJ0aWN1bGFybHkgaGV4IGxpdGVyYWxzIChcIjB4Li4uXCIpXG5cdFx0Ly8gc3VidHJhY3Rpb24gZm9yY2VzIGluZmluaXRpZXMgdG8gTmFOXG5cdFx0IWlzTmFOKCBvYmogLSBwYXJzZUZsb2F0KCBvYmogKSApO1xufTtcblxualF1ZXJ5LnRyaW0gPSBmdW5jdGlvbiggdGV4dCApIHtcblx0cmV0dXJuIHRleHQgPT0gbnVsbCA/XG5cdFx0XCJcIiA6XG5cdFx0KCB0ZXh0ICsgXCJcIiApLnJlcGxhY2UoIHJ0cmltLCBcIiQxXCIgKTtcbn07XG5cblxuXG4vLyBSZWdpc3RlciBhcyBhIG5hbWVkIEFNRCBtb2R1bGUsIHNpbmNlIGpRdWVyeSBjYW4gYmUgY29uY2F0ZW5hdGVkIHdpdGggb3RoZXJcbi8vIGZpbGVzIHRoYXQgbWF5IHVzZSBkZWZpbmUsIGJ1dCBub3QgdmlhIGEgcHJvcGVyIGNvbmNhdGVuYXRpb24gc2NyaXB0IHRoYXRcbi8vIHVuZGVyc3RhbmRzIGFub255bW91cyBBTUQgbW9kdWxlcy4gQSBuYW1lZCBBTUQgaXMgc2FmZXN0IGFuZCBtb3N0IHJvYnVzdFxuLy8gd2F5IHRvIHJlZ2lzdGVyLiBMb3dlcmNhc2UganF1ZXJ5IGlzIHVzZWQgYmVjYXVzZSBBTUQgbW9kdWxlIG5hbWVzIGFyZVxuLy8gZGVyaXZlZCBmcm9tIGZpbGUgbmFtZXMsIGFuZCBqUXVlcnkgaXMgbm9ybWFsbHkgZGVsaXZlcmVkIGluIGEgbG93ZXJjYXNlXG4vLyBmaWxlIG5hbWUuIERvIHRoaXMgYWZ0ZXIgY3JlYXRpbmcgdGhlIGdsb2JhbCBzbyB0aGF0IGlmIGFuIEFNRCBtb2R1bGUgd2FudHNcbi8vIHRvIGNhbGwgbm9Db25mbGljdCB0byBoaWRlIHRoaXMgdmVyc2lvbiBvZiBqUXVlcnksIGl0IHdpbGwgd29yay5cblxuLy8gTm90ZSB0aGF0IGZvciBtYXhpbXVtIHBvcnRhYmlsaXR5LCBsaWJyYXJpZXMgdGhhdCBhcmUgbm90IGpRdWVyeSBzaG91bGRcbi8vIGRlY2xhcmUgdGhlbXNlbHZlcyBhcyBhbm9ueW1vdXMgbW9kdWxlcywgYW5kIGF2b2lkIHNldHRpbmcgYSBnbG9iYWwgaWYgYW5cbi8vIEFNRCBsb2FkZXIgaXMgcHJlc2VudC4galF1ZXJ5IGlzIGEgc3BlY2lhbCBjYXNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlXG4vLyBodHRwczovL2dpdGh1Yi5jb20vanJidXJrZS9yZXF1aXJlanMvd2lraS9VcGRhdGluZy1leGlzdGluZy1saWJyYXJpZXMjd2lraS1hbm9uXG5cbmlmICggdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQgKSB7XG5cdGRlZmluZSggXCJqcXVlcnlcIiwgW10sIGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBqUXVlcnk7XG5cdH0gKTtcbn1cblxuXG5cblxudmFyXG5cblx0Ly8gTWFwIG92ZXIgalF1ZXJ5IGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF9qUXVlcnkgPSB3aW5kb3cualF1ZXJ5LFxuXG5cdC8vIE1hcCBvdmVyIHRoZSAkIGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF8kID0gd2luZG93LiQ7XG5cbmpRdWVyeS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oIGRlZXAgKSB7XG5cdGlmICggd2luZG93LiQgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cuJCA9IF8kO1xuXHR9XG5cblx0aWYgKCBkZWVwICYmIHdpbmRvdy5qUXVlcnkgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cualF1ZXJ5ID0gX2pRdWVyeTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnk7XG59O1xuXG4vLyBFeHBvc2UgalF1ZXJ5IGFuZCAkIGlkZW50aWZpZXJzLCBldmVuIGluIEFNRFxuLy8gKHRyYWMtNzEwMiNjb21tZW50OjEwLCBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L2pxdWVyeS9wdWxsLzU1Nylcbi8vIGFuZCBDb21tb25KUyBmb3IgYnJvd3NlciBlbXVsYXRvcnMgKHRyYWMtMTM1NjYpXG5pZiAoIHR5cGVvZiBub0dsb2JhbCA9PT0gXCJ1bmRlZmluZWRcIiApIHtcblx0d2luZG93LmpRdWVyeSA9IHdpbmRvdy4kID0galF1ZXJ5O1xufVxuXG5cblxuXG5yZXR1cm4galF1ZXJ5O1xufSApO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///692\n')}},__webpack_module_cache__={};function __webpack_require__(t){var n=__webpack_module_cache__[t];if(void 0!==n)return n.exports;var g=__webpack_module_cache__[t]={exports:{}};return __webpack_modules__[t].call(g.exports,g,g.exports,__webpack_require__),g.exports}var __webpack_exports__=__webpack_require__(151)})();
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.