gridstack 8.2.2 → 8.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/angular/projects/lib/package.json +1 -1
- package/angular/projects/lib/src/lib/base-widget.ts +1 -1
- package/angular/projects/lib/src/lib/gridstack-item.component.ts +1 -1
- package/angular/projects/lib/src/lib/gridstack.component.ts +1 -1
- package/angular/projects/lib/src/lib/gridstack.module.ts +1 -1
- package/dist/angular/esm2020/lib/base-widget.mjs +2 -2
- package/dist/angular/esm2020/lib/gridstack-item.component.mjs +2 -2
- package/dist/angular/esm2020/lib/gridstack.component.mjs +2 -2
- package/dist/angular/esm2020/lib/gridstack.module.mjs +2 -2
- package/dist/angular/fesm2015/gridstack-angular.mjs +4 -4
- package/dist/angular/fesm2015/gridstack-angular.mjs.map +1 -1
- package/dist/angular/fesm2020/gridstack-angular.mjs +4 -4
- package/dist/angular/fesm2020/gridstack-angular.mjs.map +1 -1
- package/dist/angular/lib/gridstack-item.component.d.ts +1 -1
- package/dist/angular/lib/gridstack.component.d.ts +1 -1
- package/dist/angular/package.json +1 -1
- package/dist/angular/src/base-widget.ts +1 -1
- package/dist/angular/src/gridstack-item.component.ts +1 -1
- package/dist/angular/src/gridstack.component.ts +1 -1
- package/dist/angular/src/gridstack.module.ts +1 -1
- package/dist/dd-base-impl.d.ts +1 -1
- package/dist/dd-base-impl.js +1 -1
- package/dist/dd-base-impl.js.map +1 -1
- package/dist/dd-draggable.d.ts +1 -1
- package/dist/dd-draggable.js +1 -1
- package/dist/dd-draggable.js.map +1 -1
- package/dist/dd-droppable.d.ts +1 -1
- package/dist/dd-droppable.js +1 -1
- package/dist/dd-droppable.js.map +1 -1
- package/dist/dd-element.d.ts +1 -1
- package/dist/dd-element.js +1 -1
- package/dist/dd-element.js.map +1 -1
- package/dist/dd-gridstack.d.ts +1 -1
- package/dist/dd-gridstack.js +1 -1
- package/dist/dd-gridstack.js.map +1 -1
- package/dist/dd-manager.d.ts +1 -1
- package/dist/dd-manager.js +1 -1
- package/dist/dd-manager.js.map +1 -1
- package/dist/dd-resizable-handle.d.ts +1 -1
- package/dist/dd-resizable-handle.js +1 -1
- package/dist/dd-resizable-handle.js.map +1 -1
- package/dist/dd-resizable.d.ts +1 -1
- package/dist/dd-resizable.js +1 -1
- package/dist/dd-resizable.js.map +1 -1
- package/dist/dd-touch.d.ts +1 -1
- package/dist/dd-touch.js +1 -1
- package/dist/dd-touch.js.map +1 -1
- package/dist/es5/dd-base-impl.d.ts +1 -1
- package/dist/es5/dd-base-impl.js +1 -1
- package/dist/es5/dd-base-impl.js.map +1 -1
- package/dist/es5/dd-draggable.d.ts +1 -1
- package/dist/es5/dd-draggable.js +1 -1
- package/dist/es5/dd-draggable.js.map +1 -1
- package/dist/es5/dd-droppable.d.ts +1 -1
- package/dist/es5/dd-droppable.js +1 -1
- package/dist/es5/dd-droppable.js.map +1 -1
- package/dist/es5/dd-element.d.ts +1 -1
- package/dist/es5/dd-element.js +1 -1
- package/dist/es5/dd-element.js.map +1 -1
- package/dist/es5/dd-gridstack.d.ts +1 -1
- package/dist/es5/dd-gridstack.js +1 -1
- package/dist/es5/dd-gridstack.js.map +1 -1
- package/dist/es5/dd-manager.d.ts +1 -1
- package/dist/es5/dd-manager.js +1 -1
- package/dist/es5/dd-manager.js.map +1 -1
- package/dist/es5/dd-resizable-handle.d.ts +1 -1
- package/dist/es5/dd-resizable-handle.js +1 -1
- package/dist/es5/dd-resizable-handle.js.map +1 -1
- package/dist/es5/dd-resizable.d.ts +1 -1
- package/dist/es5/dd-resizable.js +1 -1
- package/dist/es5/dd-resizable.js.map +1 -1
- package/dist/es5/dd-touch.d.ts +1 -1
- package/dist/es5/dd-touch.js +1 -1
- package/dist/es5/dd-touch.js.map +1 -1
- package/dist/es5/gridstack-all.js +3 -1
- package/dist/es5/gridstack-all.js.LICENSE.txt +1 -1
- package/dist/es5/gridstack-all.js.map +1 -1
- package/dist/es5/gridstack-engine.d.ts +9 -8
- package/dist/es5/gridstack-engine.js +115 -73
- package/dist/es5/gridstack-engine.js.map +1 -1
- package/dist/es5/gridstack-poly.js +1 -1
- package/dist/es5/gridstack.d.ts +11 -5
- package/dist/es5/gridstack.js +15 -7
- package/dist/es5/gridstack.js.map +1 -1
- package/dist/es5/types.d.ts +11 -4
- package/dist/es5/types.js +1 -1
- package/dist/es5/types.js.map +1 -1
- package/dist/es5/utils.d.ts +2 -2
- package/dist/es5/utils.js +2 -1
- package/dist/es5/utils.js.map +1 -1
- package/dist/gridstack-all.js +3 -1
- package/dist/gridstack-all.js.LICENSE.txt +1 -1
- package/dist/gridstack-all.js.map +1 -1
- package/dist/gridstack-engine.d.ts +9 -8
- package/dist/gridstack-engine.js +110 -73
- package/dist/gridstack-engine.js.map +1 -1
- package/dist/gridstack.css +1 -1
- package/dist/gridstack.d.ts +11 -5
- package/dist/gridstack.js +13 -7
- package/dist/gridstack.js.map +1 -1
- package/dist/src/gridstack.scss +1 -1
- package/dist/types.d.ts +11 -4
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +2 -2
- package/dist/utils.js.map +1 -1
- package/doc/CHANGES.md +6 -2
- package/doc/README.md +16 -7
- package/package.json +1 -1
package/dist/gridstack-all.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
!function(Q,B){"object"==typeof exports&&"object"==typeof module?module.exports=B():"function"==typeof define&&define.amd?define([],B):"object"==typeof exports?exports.GridStack=B():Q.GridStack=B()}(self,(()=>(()=>{"use strict";var __webpack_modules__={944:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval("\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"GridStack\": () => (/* binding */ GridStack)\n});\n\n// UNUSED EXPORTS: DDGridStack, GridStackEngine, Utils, dragInDefaultOptions, gridDefaults, obsolete, obsoleteAttr, obsoleteOpts, obsoleteOptsDel\n\n;// CONCATENATED MODULE: ./src/utils.ts\n/**\n * utils.ts 8.2.2\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n/** checks for obsolete method names */\n// eslint-disable-next-line\nfunction obsolete(self, f, oldName, newName, rev) {\n let wrapper = (...args) => {\n console.warn('gridstack.js: Function `' + oldName + '` is deprecated in ' + rev + ' and has been replaced ' +\n 'with `' + newName + '`. It will be **removed** in a future release');\n return f.apply(self, args);\n };\n wrapper.prototype = f.prototype;\n return wrapper;\n}\n/** checks for obsolete grid options (can be used for any fields, but msg is about options) */\nfunction obsoleteOpts(opts, oldName, newName, rev) {\n if (opts[oldName] !== undefined) {\n opts[newName] = opts[oldName];\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + ' and has been replaced with `' +\n newName + '`. It will be **removed** in a future release');\n }\n}\n/** checks for obsolete grid options which are gone */\nfunction obsoleteOptsDel(opts, oldName, rev, info) {\n if (opts[oldName] !== undefined) {\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + info);\n }\n}\n/** checks for obsolete Jquery element attributes */\nfunction obsoleteAttr(el, oldName, newName, rev) {\n let oldAttr = el.getAttribute(oldName);\n if (oldAttr !== null) {\n el.setAttribute(newName, oldAttr);\n console.warn('gridstack.js: attribute `' + oldName + '`=' + oldAttr + ' is deprecated on this object in ' + rev + ' and has been replaced with `' +\n newName + '`. It will be **removed** in a future release');\n }\n}\n/**\n * Utility methods\n */\nclass Utils {\n /** convert a potential selector into actual list of html elements. optional root which defaults to document (for shadow dom) */\n static getElements(els, root = document) {\n if (typeof els === 'string') {\n const doc = ('getElementById' in root) ? root : undefined;\n // Note: very common for people use to id='1,2,3' which is only legal as HTML5 id, but not CSS selectors\n // so if we start with a number, assume it's an id and just return that one item...\n // see https://github.com/gridstack/gridstack.js/issues/2234#issuecomment-1523796562\n if (doc && !isNaN(+els[0])) { // start with digit\n const el = doc.getElementById(els);\n return el ? [el] : [];\n }\n let list = root.querySelectorAll(els);\n if (!list.length && els[0] !== '.' && els[0] !== '#') {\n list = root.querySelectorAll('.' + els);\n if (!list.length) {\n list = root.querySelectorAll('#' + els);\n }\n }\n return Array.from(list);\n }\n return [els];\n }\n /** convert a potential selector into actual single element. optional root which defaults to document (for shadow dom) */\n static getElement(els, root = document) {\n if (typeof els === 'string') {\n const doc = ('getElementById' in root) ? root : undefined;\n if (!els.length)\n return null;\n if (doc && els[0] === '#') {\n return doc.getElementById(els.substring(1));\n }\n if (els[0] === '#' || els[0] === '.' || els[0] === '[') {\n return root.querySelector(els);\n }\n // if we start with a digit, assume it's an id (error calling querySelector('#1')) as class are not valid CSS\n if (doc && !isNaN(+els[0])) { // start with digit\n return doc.getElementById(els);\n }\n // finally try string, then id, then class\n let el = root.querySelector(els);\n if (doc && !el) {\n el = doc.getElementById(els);\n }\n if (!el) {\n el = root.querySelector('.' + els);\n }\n return el;\n }\n return els;\n }\n /** returns true if a and b overlap */\n static isIntercepted(a, b) {\n return !(a.y >= b.y + b.h || a.y + a.h <= b.y || a.x + a.w <= b.x || a.x >= b.x + b.w);\n }\n /** returns true if a and b touch edges or corners */\n static isTouching(a, b) {\n return Utils.isIntercepted(a, { x: b.x - 0.5, y: b.y - 0.5, w: b.w + 1, h: b.h + 1 });\n }\n /** returns the area a and b overlap */\n static areaIntercept(a, b) {\n let x0 = (a.x > b.x) ? a.x : b.x;\n let x1 = (a.x + a.w < b.x + b.w) ? a.x + a.w : b.x + b.w;\n if (x1 <= x0)\n return 0; // no overlap\n let y0 = (a.y > b.y) ? a.y : b.y;\n let y1 = (a.y + a.h < b.y + b.h) ? a.y + a.h : b.y + b.h;\n if (y1 <= y0)\n return 0; // no overlap\n return (x1 - x0) * (y1 - y0);\n }\n /** returns the area */\n static area(a) {\n return a.w * a.h;\n }\n /**\n * Sorts array of nodes\n * @param nodes array to sort\n * @param dir 1 for asc, -1 for desc (optional)\n * @param width width of the grid. If undefined the width will be calculated automatically (optional).\n **/\n static sort(nodes, dir, column) {\n column = column || nodes.reduce((col, n) => Math.max(n.x + n.w, col), 0) || 12;\n if (dir === -1)\n return nodes.sort((a, b) => (b.x + b.y * column) - (a.x + a.y * column));\n else\n return nodes.sort((b, a) => (b.x + b.y * column) - (a.x + a.y * column));\n }\n /**\n * creates a style sheet with style id under given parent\n * @param id will set the 'gs-style-id' attribute to that id\n * @param parent to insert the stylesheet as first child,\n * if none supplied it will be appended to the document head instead.\n */\n static createStylesheet(id, parent, options) {\n let style = document.createElement('style');\n const nonce = options?.nonce;\n if (nonce)\n style.nonce = nonce;\n style.setAttribute('type', 'text/css');\n style.setAttribute('gs-style-id', id);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (style.styleSheet) { // TODO: only CSSImportRule have that and different beast ??\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n style.styleSheet.cssText = '';\n }\n else {\n style.appendChild(document.createTextNode('')); // WebKit hack\n }\n if (!parent) {\n // default to head\n parent = document.getElementsByTagName('head')[0];\n parent.appendChild(style);\n }\n else {\n parent.insertBefore(style, parent.firstChild);\n }\n return style.sheet;\n }\n /** removed the given stylesheet id */\n static removeStylesheet(id) {\n let el = document.querySelector('STYLE[gs-style-id=' + id + ']');\n if (el && el.parentNode)\n el.remove();\n }\n /** inserts a CSS rule */\n static addCSSRule(sheet, selector, rules) {\n if (typeof sheet.addRule === 'function') {\n sheet.addRule(selector, rules);\n }\n else if (typeof sheet.insertRule === 'function') {\n sheet.insertRule(`${selector}{${rules}}`);\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static toBool(v) {\n if (typeof v === 'boolean') {\n return v;\n }\n if (typeof v === 'string') {\n v = v.toLowerCase();\n return !(v === '' || v === 'no' || v === 'false' || v === '0');\n }\n return Boolean(v);\n }\n static toNumber(value) {\n return (value === null || value.length === 0) ? undefined : Number(value);\n }\n static parseHeight(val) {\n let h;\n let unit = 'px';\n if (typeof val === 'string') {\n let match = val.match(/^(-[0-9]+\\.[0-9]+|[0-9]*\\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/);\n if (!match) {\n throw new Error('Invalid height');\n }\n unit = match[2] || 'px';\n h = parseFloat(match[1]);\n }\n else {\n h = val;\n }\n return { h, unit };\n }\n /** copies unset fields in target to use the given default sources values */\n // eslint-disable-next-line\n static defaults(target, ...sources) {\n sources.forEach(source => {\n for (const key in source) {\n if (!source.hasOwnProperty(key))\n return;\n if (target[key] === null || target[key] === undefined) {\n target[key] = source[key];\n }\n else if (typeof source[key] === 'object' && typeof target[key] === 'object') {\n // property is an object, recursively add it's field over... #1373\n this.defaults(target[key], source[key]);\n }\n }\n });\n return target;\n }\n /** given 2 objects return true if they have the same values. Checks for Object {} having same fields and values (just 1 level down) */\n static same(a, b) {\n if (typeof a !== 'object')\n return a == b;\n if (typeof a !== typeof b)\n return false;\n // else we have object, check just 1 level deep for being same things...\n if (Object.keys(a).length !== Object.keys(b).length)\n return false;\n for (const key in a) {\n if (a[key] !== b[key])\n return false;\n }\n return true;\n }\n /** copies over b size & position (GridStackPosition), and optionally min/max as well */\n static copyPos(a, b, doMinMax = false) {\n if (b.x !== undefined)\n a.x = b.x;\n if (b.y !== undefined)\n a.y = b.y;\n if (b.w !== undefined)\n a.w = b.w;\n if (b.h !== undefined)\n a.h = b.h;\n if (doMinMax) {\n if (b.minW)\n a.minW = b.minW;\n if (b.minH)\n a.minH = b.minH;\n if (b.maxW)\n a.maxW = b.maxW;\n if (b.maxH)\n a.maxH = b.maxH;\n }\n return a;\n }\n /** true if a and b has same size & position */\n static samePos(a, b) {\n return a && b && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;\n }\n /** given a node, makes sure it's min/max are valid */\n static sanitizeMinMax(node) {\n // remove 0, undefine, null\n if (!node.minW) {\n delete node.minW;\n }\n if (!node.minH) {\n delete node.minH;\n }\n if (!node.maxW) {\n delete node.maxW;\n }\n if (!node.maxH) {\n delete node.maxH;\n }\n }\n /** removes field from the first object if same as the second objects (like diffing) and internal '_' for saving */\n static removeInternalAndSame(a, b) {\n if (typeof a !== 'object' || typeof b !== 'object')\n return;\n for (let key in a) {\n let val = a[key];\n if (key[0] === '_' || val === b[key]) {\n delete a[key];\n }\n else if (val && typeof val === 'object' && b[key] !== undefined) {\n for (let i in val) {\n if (val[i] === b[key][i] || i[0] === '_') {\n delete val[i];\n }\n }\n if (!Object.keys(val).length) {\n delete a[key];\n }\n }\n }\n }\n /** removes internal fields '_' and default values for saving */\n static removeInternalForSave(n, removeEl = true) {\n for (let key in n) {\n if (key[0] === '_' || n[key] === null || n[key] === undefined)\n delete n[key];\n }\n delete n.grid;\n if (removeEl)\n delete n.el;\n // delete default values (will be re-created on read)\n if (!n.autoPosition)\n delete n.autoPosition;\n if (!n.noResize)\n delete n.noResize;\n if (!n.noMove)\n delete n.noMove;\n if (!n.locked)\n delete n.locked;\n if (n.w === 1 || n.w === n.minW)\n delete n.w;\n if (n.h === 1 || n.h === n.minH)\n delete n.h;\n }\n /** return the closest parent (or itself) matching the given class */\n static closestUpByClass(el, name) {\n while (el) {\n if (el.classList.contains(name))\n return el;\n el = el.parentElement;\n }\n return null;\n }\n /** delay calling the given function for given delay, preventing new calls from happening while waiting */\n static throttle(func, delay) {\n let isWaiting = false;\n return (...args) => {\n if (!isWaiting) {\n isWaiting = true;\n setTimeout(() => { func(...args); isWaiting = false; }, delay);\n }\n };\n }\n static removePositioningStyles(el) {\n let style = el.style;\n if (style.position) {\n style.removeProperty('position');\n }\n if (style.left) {\n style.removeProperty('left');\n }\n if (style.top) {\n style.removeProperty('top');\n }\n if (style.width) {\n style.removeProperty('width');\n }\n if (style.height) {\n style.removeProperty('height');\n }\n }\n /** @internal returns the passed element if scrollable, else the closest parent that will, up to the entire document scrolling element */\n static getScrollElement(el) {\n if (!el)\n return document.scrollingElement || document.documentElement; // IE support\n const style = getComputedStyle(el);\n const overflowRegex = /(auto|scroll)/;\n if (overflowRegex.test(style.overflow + style.overflowY)) {\n return el;\n }\n else {\n return this.getScrollElement(el.parentElement);\n }\n }\n /** @internal */\n static updateScrollPosition(el, position, distance) {\n // is widget in view?\n let rect = el.getBoundingClientRect();\n let innerHeightOrClientHeight = (window.innerHeight || document.documentElement.clientHeight);\n if (rect.top < 0 ||\n rect.bottom > innerHeightOrClientHeight) {\n // set scrollTop of first parent that scrolls\n // if parent is larger than el, set as low as possible\n // to get entire widget on screen\n let offsetDiffDown = rect.bottom - innerHeightOrClientHeight;\n let offsetDiffUp = rect.top;\n let scrollEl = this.getScrollElement(el);\n if (scrollEl !== null) {\n let prevScroll = scrollEl.scrollTop;\n if (rect.top < 0 && distance < 0) {\n // moving up\n if (el.offsetHeight > innerHeightOrClientHeight) {\n scrollEl.scrollTop += distance;\n }\n else {\n scrollEl.scrollTop += Math.abs(offsetDiffUp) > Math.abs(distance) ? distance : offsetDiffUp;\n }\n }\n else if (distance > 0) {\n // moving down\n if (el.offsetHeight > innerHeightOrClientHeight) {\n scrollEl.scrollTop += distance;\n }\n else {\n scrollEl.scrollTop += offsetDiffDown > distance ? distance : offsetDiffDown;\n }\n }\n // move widget y by amount scrolled\n position.top += scrollEl.scrollTop - prevScroll;\n }\n }\n }\n /**\n * @internal Function used to scroll the page.\n *\n * @param event `MouseEvent` that triggers the resize\n * @param el `HTMLElement` that's being resized\n * @param distance Distance from the V edges to start scrolling\n */\n static updateScrollResize(event, el, distance) {\n const scrollEl = this.getScrollElement(el);\n const height = scrollEl.clientHeight;\n // #1727 event.clientY is relative to viewport, so must compare this against position of scrollEl getBoundingClientRect().top\n // #1745 Special situation if scrollEl is document 'html': here browser spec states that\n // clientHeight is height of viewport, but getBoundingClientRect() is rectangle of html element;\n // this discrepancy arises because in reality scrollbar is attached to viewport, not html element itself.\n const offsetTop = (scrollEl === this.getScrollElement()) ? 0 : scrollEl.getBoundingClientRect().top;\n const pointerPosY = event.clientY - offsetTop;\n const top = pointerPosY < distance;\n const bottom = pointerPosY > height - distance;\n if (top) {\n // This also can be done with a timeout to keep scrolling while the mouse is\n // in the scrolling zone. (will have smoother behavior)\n scrollEl.scrollBy({ behavior: 'smooth', top: pointerPosY - distance });\n }\n else if (bottom) {\n scrollEl.scrollBy({ behavior: 'smooth', top: distance - (height - pointerPosY) });\n }\n }\n /** single level clone, returning a new object with same top fields. This will share sub objects and arrays */\n static clone(obj) {\n if (obj === null || obj === undefined || typeof (obj) !== 'object') {\n return obj;\n }\n // return Object.assign({}, obj);\n if (obj instanceof Array) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return [...obj];\n }\n return { ...obj };\n }\n /**\n * Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY.\n * Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies.\n */\n static cloneDeep(obj) {\n // list of fields we will skip during cloneDeep (nested objects, other internal)\n const skipFields = ['parentGrid', 'el', 'grid', 'subGrid', 'engine'];\n // return JSON.parse(JSON.stringify(obj)); // doesn't work with date format ?\n const ret = Utils.clone(obj);\n for (const key in ret) {\n // NOTE: we don't support function/circular dependencies so skip those properties for now...\n if (ret.hasOwnProperty(key) && typeof (ret[key]) === 'object' && key.substring(0, 2) !== '__' && !skipFields.find(k => k === key)) {\n ret[key] = Utils.cloneDeep(obj[key]);\n }\n }\n return ret;\n }\n /** deep clone the given HTML node, removing teh unique id field */\n static cloneNode(el) {\n const node = el.cloneNode(true);\n node.removeAttribute('id');\n return node;\n }\n static appendTo(el, parent) {\n let parentNode;\n if (typeof parent === 'string') {\n parentNode = Utils.getElement(parent);\n }\n else {\n parentNode = parent;\n }\n if (parentNode) {\n parentNode.appendChild(el);\n }\n }\n // public static setPositionRelative(el: HTMLElement): void {\n // if (!(/^(?:r|a|f)/).test(window.getComputedStyle(el).position)) {\n // el.style.position = \"relative\";\n // }\n // }\n static addElStyles(el, styles) {\n if (styles instanceof Object) {\n for (const s in styles) {\n if (styles.hasOwnProperty(s)) {\n if (Array.isArray(styles[s])) {\n // support fallback value\n styles[s].forEach(val => {\n el.style[s] = val;\n });\n }\n else {\n el.style[s] = styles[s];\n }\n }\n }\n }\n }\n static initEvent(e, info) {\n const evt = { type: info.type };\n const obj = {\n button: 0,\n which: 0,\n buttons: 1,\n bubbles: true,\n cancelable: true,\n target: info.target ? info.target : e.target\n };\n // don't check for `instanceof DragEvent` as Safari use MouseEvent #1540\n if (e.dataTransfer) {\n evt['dataTransfer'] = e.dataTransfer; // workaround 'readonly' field.\n }\n ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].forEach(p => evt[p] = e[p]); // keys\n ['pageX', 'pageY', 'clientX', 'clientY', 'screenX', 'screenY'].forEach(p => evt[p] = e[p]); // point info\n return { ...evt, ...obj };\n }\n /** copies the MouseEvent properties and sends it as another event to the given target */\n static simulateMouseEvent(e, simulatedType, target) {\n const simulatedEvent = document.createEvent('MouseEvents');\n simulatedEvent.initMouseEvent(simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n e.screenX, // screenX\n e.screenY, // screenY\n e.clientX, // clientX\n e.clientY, // clientY\n e.ctrlKey, // ctrlKey\n e.altKey, // altKey\n e.shiftKey, // shiftKey\n e.metaKey, // metaKey\n 0, // button\n e.target // relatedTarget\n );\n (target || e.target).dispatchEvent(simulatedEvent);\n }\n}\n\n;// CONCATENATED MODULE: ./src/gridstack-engine.ts\n/**\n * gridstack-engine.ts 8.2.2\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\n/**\n * Defines the GridStack engine that does most no DOM grid manipulation.\n * See GridStack methods and vars for descriptions.\n *\n * NOTE: values should not be modified directly - call the main GridStack API instead\n */\nclass GridStackEngine {\n constructor(opts = {}) {\n this.addedNodes = [];\n this.removedNodes = [];\n this.column = opts.column || 12;\n this.maxRow = opts.maxRow;\n this._float = opts.float;\n this.nodes = opts.nodes || [];\n this.onChange = opts.onChange;\n }\n batchUpdate(flag = true) {\n if (!!this.batchMode === flag)\n return this;\n this.batchMode = flag;\n if (flag) {\n this._prevFloat = this._float;\n this._float = true; // let things go anywhere for now... will restore and possibly reposition later\n this.saveInitial(); // since begin update (which is called multiple times) won't do this\n }\n else {\n this._float = this._prevFloat;\n delete this._prevFloat;\n this._packNodes()._notify();\n }\n return this;\n }\n // use entire row for hitting area (will use bottom reverse sorted first) if we not actively moving DOWN and didn't already skip\n _useEntireRowArea(node, nn) {\n return (!this.float || this.batchMode && !this._prevFloat) && !this._hasLocked && (!node._moving || node._skipDown || nn.y <= node.y);\n }\n /** @internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found.\n * return true if we moved. */\n _fixCollisions(node, nn = node, collide, opt = {}) {\n this.sortNodes(-1); // from last to first, so recursive collision move items in the right order\n collide = collide || this.collide(node, nn); // REAL area collide for swap and skip if none...\n if (!collide)\n return false;\n // swap check: if we're actively moving in gravity mode, see if we collide with an object the same size\n if (node._moving && !opt.nested && !this.float) {\n if (this.swap(node, collide))\n return true;\n }\n // during while() collisions MAKE SURE to check entire row so larger items don't leap frog small ones (push them all down starting last in grid)\n let area = nn;\n if (this._useEntireRowArea(node, nn)) {\n area = { x: 0, w: this.column, y: nn.y, h: nn.h };\n collide = this.collide(node, area, opt.skip); // force new hit\n }\n let didMove = false;\n let newOpt = { nested: true, pack: false };\n while (collide = collide || this.collide(node, area, opt.skip)) { // could collide with more than 1 item... so repeat for each\n let moved;\n // if colliding with a locked item OR moving down with top gravity (and collide could move up) -> skip past the collide,\n // but remember that skip down so we only do this once (and push others otherwise).\n if (collide.locked || node._moving && !node._skipDown && nn.y > node.y && !this.float &&\n // can take space we had, or before where we're going\n (!this.collide(collide, { ...collide, y: node.y }, node) || !this.collide(collide, { ...collide, y: nn.y - collide.h }, node))) {\n node._skipDown = (node._skipDown || nn.y > node.y);\n moved = this.moveNode(node, { ...nn, y: collide.y + collide.h, ...newOpt });\n if (collide.locked && moved) {\n Utils.copyPos(nn, node); // moving after lock become our new desired location\n }\n else if (!collide.locked && moved && opt.pack) {\n // we moved after and will pack: do it now and keep the original drop location, but past the old collide to see what else we might push way\n this._packNodes();\n nn.y = collide.y + collide.h;\n Utils.copyPos(node, nn);\n }\n didMove = didMove || moved;\n }\n else {\n // move collide down *after* where we will be, ignoring where we are now (don't collide with us)\n moved = this.moveNode(collide, { ...collide, y: nn.y + nn.h, skip: node, ...newOpt });\n }\n if (!moved) {\n return didMove;\n } // break inf loop if we couldn't move after all (ex: maxRow, fixed)\n collide = undefined;\n }\n return didMove;\n }\n /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */\n collide(skip, area = skip, skip2) {\n const skipId = skip._id;\n const skip2Id = skip2?._id;\n return this.nodes.find(n => n._id !== skipId && n._id !== skip2Id && Utils.isIntercepted(n, area));\n }\n collideAll(skip, area = skip, skip2) {\n const skipId = skip._id;\n const skip2Id = skip2?._id;\n return this.nodes.filter(n => n._id !== skipId && n._id !== skip2Id && Utils.isIntercepted(n, area));\n }\n /** does a pixel coverage collision based on where we started, returning the node that has the most coverage that is >50% mid line */\n directionCollideCoverage(node, o, collides) {\n if (!o.rect || !node._rect)\n return;\n let r0 = node._rect; // where started\n let r = { ...o.rect }; // where we are\n // update dragged rect to show where it's coming from (above or below, etc...)\n if (r.y > r0.y) {\n r.h += r.y - r0.y;\n r.y = r0.y;\n }\n else {\n r.h += r0.y - r.y;\n }\n if (r.x > r0.x) {\n r.w += r.x - r0.x;\n r.x = r0.x;\n }\n else {\n r.w += r0.x - r.x;\n }\n let collide;\n collides.forEach(n => {\n if (n.locked || !n._rect)\n return;\n let r2 = n._rect; // overlapping target\n let yOver = Number.MAX_VALUE, xOver = Number.MAX_VALUE, overMax = 0.5; // need >50%\n // depending on which side we started from, compute the overlap % of coverage\n // (ex: from above/below we only compute the max horizontal line coverage)\n if (r0.y < r2.y) { // from above\n yOver = ((r.y + r.h) - r2.y) / r2.h;\n }\n else if (r0.y + r0.h > r2.y + r2.h) { // from below\n yOver = ((r2.y + r2.h) - r.y) / r2.h;\n }\n if (r0.x < r2.x) { // from the left\n xOver = ((r.x + r.w) - r2.x) / r2.w;\n }\n else if (r0.x + r0.w > r2.x + r2.w) { // from the right\n xOver = ((r2.x + r2.w) - r.x) / r2.w;\n }\n let over = Math.min(xOver, yOver);\n if (over > overMax) {\n overMax = over;\n collide = n;\n }\n });\n o.collide = collide; // save it so we don't have to find it again\n return collide;\n }\n /** does a pixel coverage returning the node that has the most coverage by area */\n /*\n protected collideCoverage(r: GridStackPosition, collides: GridStackNode[]): {collide: GridStackNode, over: number} {\n let collide: GridStackNode;\n let overMax = 0;\n collides.forEach(n => {\n if (n.locked || !n._rect) return;\n let over = Utils.areaIntercept(r, n._rect);\n if (over > overMax) {\n overMax = over;\n collide = n;\n }\n });\n return {collide, over: overMax};\n }\n */\n /** called to cache the nodes pixel rectangles used for collision detection during drag */\n cacheRects(w, h, top, right, bottom, left) {\n this.nodes.forEach(n => n._rect = {\n y: n.y * h + top,\n x: n.x * w + left,\n w: n.w * w - left - right,\n h: n.h * h - top - bottom\n });\n return this;\n }\n /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */\n swap(a, b) {\n if (!b || b.locked || !a || a.locked)\n return false;\n function _doSwap() {\n let x = b.x, y = b.y;\n b.x = a.x;\n b.y = a.y; // b -> a position\n if (a.h != b.h) {\n a.x = x;\n a.y = b.y + b.h; // a -> goes after b\n }\n else if (a.w != b.w) {\n a.x = b.x + b.w;\n a.y = y; // a -> goes after b\n }\n else {\n a.x = x;\n a.y = y; // a -> old b position\n }\n a._dirty = b._dirty = true;\n return true;\n }\n let touching; // remember if we called it (vs undefined)\n // same size and same row or column, and touching\n if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) && (touching = Utils.isTouching(a, b)))\n return _doSwap();\n if (touching === false)\n return; // IFF ran test and fail, bail out\n // check for taking same columns (but different height) and touching\n if (a.w === b.w && a.x === b.x && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.y < a.y) {\n let t = a;\n a = b;\n b = t;\n } // swap a <-> b vars so a is first\n return _doSwap();\n }\n if (touching === false)\n return;\n // check if taking same row (but different width) and touching\n if (a.h === b.h && a.y === b.y && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.x < a.x) {\n let t = a;\n a = b;\n b = t;\n } // swap a <-> b vars so a is first\n return _doSwap();\n }\n return false;\n }\n isAreaEmpty(x, y, w, h) {\n let nn = { x: x || 0, y: y || 0, w: w || 1, h: h || 1 };\n return !this.collide(nn);\n }\n /** re-layout grid items to reclaim any empty space */\n compact() {\n if (this.nodes.length === 0)\n return this;\n this.batchUpdate()\n .sortNodes();\n let copyNodes = this.nodes;\n this.nodes = []; // pretend we have no nodes to conflict layout to start with...\n copyNodes.forEach(node => {\n if (!node.locked) {\n node.autoPosition = true;\n }\n this.addNode(node, false); // 'false' for add event trigger\n node._dirty = true; // will force attr update\n });\n return this.batchUpdate(false);\n }\n /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */\n set float(val) {\n if (this._float === val)\n return;\n this._float = val || false;\n if (!val) {\n this._packNodes()._notify();\n }\n }\n /** float getter method */\n get float() { return this._float || false; }\n /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */\n sortNodes(dir) {\n this.nodes = Utils.sort(this.nodes, dir, this.column);\n return this;\n }\n /** @internal called to top gravity pack the items back OR revert back to original Y positions when floating */\n _packNodes() {\n if (this.batchMode) {\n return this;\n }\n this.sortNodes(); // first to last\n if (this.float) {\n // restore original Y pos\n this.nodes.forEach(n => {\n if (n._updating || n._orig === undefined || n.y === n._orig.y)\n return;\n let newY = n.y;\n while (newY > n._orig.y) {\n --newY;\n let collide = this.collide(n, { x: n.x, y: newY, w: n.w, h: n.h });\n if (!collide) {\n n._dirty = true;\n n.y = newY;\n }\n }\n });\n }\n else {\n // top gravity pack\n this.nodes.forEach((n, i) => {\n if (n.locked)\n return;\n while (n.y > 0) {\n let newY = i === 0 ? 0 : n.y - 1;\n let canBeMoved = i === 0 || !this.collide(n, { x: n.x, y: newY, w: n.w, h: n.h });\n if (!canBeMoved)\n break;\n // Note: must be dirty (from last position) for GridStack::OnChange CB to update positions\n // and move items back. The user 'change' CB should detect changes from the original\n // starting position instead.\n n._dirty = (n.y !== newY);\n n.y = newY;\n }\n });\n }\n return this;\n }\n /**\n * given a random node, makes sure it's coordinates/values are valid in the current grid\n * @param node to adjust\n * @param resizing if out of bound, resize down or move into the grid to fit ?\n */\n prepareNode(node, resizing) {\n node = node || {};\n node._id = node._id ?? GridStackEngine._idSeq++;\n // if we're missing position, have the grid position us automatically (before we set them to 0,0)\n if (node.x === undefined || node.y === undefined || node.x === null || node.y === null) {\n node.autoPosition = true;\n }\n // assign defaults for missing required fields\n let defaults = { x: 0, y: 0, w: 1, h: 1 };\n Utils.defaults(node, defaults);\n if (!node.autoPosition) {\n delete node.autoPosition;\n }\n if (!node.noResize) {\n delete node.noResize;\n }\n if (!node.noMove) {\n delete node.noMove;\n }\n Utils.sanitizeMinMax(node);\n // check for NaN (in case messed up strings were passed. can't do parseInt() || defaults.x above as 0 is valid #)\n if (typeof node.x == 'string') {\n node.x = Number(node.x);\n }\n if (typeof node.y == 'string') {\n node.y = Number(node.y);\n }\n if (typeof node.w == 'string') {\n node.w = Number(node.w);\n }\n if (typeof node.h == 'string') {\n node.h = Number(node.h);\n }\n if (isNaN(node.x)) {\n node.x = defaults.x;\n node.autoPosition = true;\n }\n if (isNaN(node.y)) {\n node.y = defaults.y;\n node.autoPosition = true;\n }\n if (isNaN(node.w)) {\n node.w = defaults.w;\n }\n if (isNaN(node.h)) {\n node.h = defaults.h;\n }\n return this.nodeBoundFix(node, resizing);\n }\n /** part2 of preparing a node to fit inside our grid - checks for x,y,w from grid dimensions */\n nodeBoundFix(node, resizing) {\n let before = node._orig || Utils.copyPos({}, node);\n if (node.maxW) {\n node.w = Math.min(node.w, node.maxW);\n }\n if (node.maxH) {\n node.h = Math.min(node.h, node.maxH);\n }\n if (node.minW && node.minW <= this.column) {\n node.w = Math.max(node.w, node.minW);\n }\n if (node.minH) {\n node.h = Math.max(node.h, node.minH);\n }\n // if user loaded a larger than allowed widget for current # of columns (or force 1 column mode),\n // remember it's position & width so we can restore back (1 -> 12 column) #1655 #1985\n // IFF we're not in the middle of column resizing!\n const saveOrig = this.column === 1 || node.x + node.w > this.column;\n if (saveOrig && this.column < 12 && !this._inColumnResize && node._id && this.findCacheLayout(node, 12) === -1) {\n let copy = { ...node }; // need _id + positions\n if (copy.autoPosition) {\n delete copy.x;\n delete copy.y;\n }\n else\n copy.x = Math.min(11, copy.x);\n copy.w = Math.min(12, copy.w);\n this.cacheOneLayout(copy, 12);\n }\n if (node.w > this.column) {\n node.w = this.column;\n }\n else if (node.w < 1) {\n node.w = 1;\n }\n if (this.maxRow && node.h > this.maxRow) {\n node.h = this.maxRow;\n }\n else if (node.h < 1) {\n node.h = 1;\n }\n if (node.x < 0) {\n node.x = 0;\n }\n if (node.y < 0) {\n node.y = 0;\n }\n if (node.x + node.w > this.column) {\n if (resizing) {\n node.w = this.column - node.x;\n }\n else {\n node.x = this.column - node.w;\n }\n }\n if (this.maxRow && node.y + node.h > this.maxRow) {\n if (resizing) {\n node.h = this.maxRow - node.y;\n }\n else {\n node.y = this.maxRow - node.h;\n }\n }\n if (!Utils.samePos(node, before)) {\n node._dirty = true;\n }\n return node;\n }\n /** returns a list of modified nodes from their original values */\n getDirtyNodes(verify) {\n // compare original x,y,w,h instead as _dirty can be a temporary state\n if (verify) {\n return this.nodes.filter(n => n._dirty && !Utils.samePos(n, n._orig));\n }\n return this.nodes.filter(n => n._dirty);\n }\n /** @internal call this to call onChange callback with dirty nodes so DOM can be updated */\n _notify(removedNodes) {\n if (this.batchMode || !this.onChange)\n return this;\n let dirtyNodes = (removedNodes || []).concat(this.getDirtyNodes());\n this.onChange(dirtyNodes);\n return this;\n }\n /** @internal remove dirty and last tried info */\n cleanNodes() {\n if (this.batchMode)\n return this;\n this.nodes.forEach(n => {\n delete n._dirty;\n delete n._lastTried;\n });\n return this;\n }\n /** @internal called to save initial position/size to track real dirty state.\n * Note: should be called right after we call change event (so next API is can detect changes)\n * as well as right before we start move/resize/enter (so we can restore items to prev values) */\n saveInitial() {\n this.nodes.forEach(n => {\n n._orig = Utils.copyPos({}, n);\n delete n._dirty;\n });\n this._hasLocked = this.nodes.some(n => n.locked);\n return this;\n }\n /** @internal restore all the nodes back to initial values (called when we leave) */\n restoreInitial() {\n this.nodes.forEach(n => {\n if (Utils.samePos(n, n._orig))\n return;\n Utils.copyPos(n, n._orig);\n n._dirty = true;\n });\n this._notify();\n return this;\n }\n /** find the first available empty spot for the given node width/height, updating the x,y attributes. return true if found.\n * optionally you can pass your own existing node list and column count, otherwise defaults to that engine data.\n */\n findEmptyPosition(node, nodeList = this.nodes, column = this.column) {\n nodeList = Utils.sort(nodeList, -1, column);\n let found = false;\n for (let i = 0; !found; ++i) {\n let x = i % column;\n let y = Math.floor(i / column);\n if (x + node.w > column) {\n continue;\n }\n let box = { x, y, w: node.w, h: node.h };\n if (!nodeList.find(n => Utils.isIntercepted(box, n))) {\n node.x = x;\n node.y = y;\n delete node.autoPosition;\n found = true;\n }\n }\n return found;\n }\n /** call to add the given node to our list, fixing collision and re-packing */\n addNode(node, triggerAddEvent = false) {\n let dup = this.nodes.find(n => n._id === node._id);\n if (dup)\n return dup; // prevent inserting twice! return it instead.\n // skip prepareNode if we're in middle of column resize (not new) but do check for bounds!\n node = this._inColumnResize ? this.nodeBoundFix(node) : this.prepareNode(node);\n delete node._temporaryRemoved;\n delete node._removeDOM;\n if (node.autoPosition && this.findEmptyPosition(node)) {\n delete node.autoPosition; // found our slot\n }\n this.nodes.push(node);\n if (triggerAddEvent) {\n this.addedNodes.push(node);\n }\n this._fixCollisions(node);\n if (!this.batchMode) {\n this._packNodes()._notify();\n }\n return node;\n }\n removeNode(node, removeDOM = true, triggerEvent = false) {\n if (!this.nodes.find(n => n._id === node._id)) {\n // TEST console.log(`Error: GridStackEngine.removeNode() node._id=${node._id} not found!`)\n return this;\n }\n if (triggerEvent) { // we wait until final drop to manually track removed items (rather than during drag)\n this.removedNodes.push(node);\n }\n if (removeDOM)\n node._removeDOM = true; // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n // don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times.\n this.nodes = this.nodes.filter(n => n._id !== node._id);\n return this._packNodes()\n ._notify([node]);\n }\n removeAll(removeDOM = true) {\n delete this._layouts;\n if (!this.nodes.length)\n return this;\n removeDOM && this.nodes.forEach(n => n._removeDOM = true); // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n this.removedNodes = this.nodes;\n this.nodes = [];\n return this._notify(this.removedNodes);\n }\n /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move.\n * In more complicated cases (maxRow) it will attempt at moving the item and fixing\n * others in a clone first, then apply those changes if still within specs. */\n moveNodeCheck(node, o) {\n // if (node.locked) return false;\n if (!this.changedPosConstrain(node, o))\n return false;\n o.pack = true;\n // simpler case: move item directly...\n if (!this.maxRow) {\n return this.moveNode(node, o);\n }\n // complex case: create a clone with NO maxRow (will check for out of bounds at the end)\n let clonedNode;\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => {\n if (n._id === node._id) {\n clonedNode = { ...n };\n return clonedNode;\n }\n return { ...n };\n })\n });\n if (!clonedNode)\n return false;\n // check if we're covering 50% collision and could move\n let canMove = clone.moveNode(clonedNode, o) && clone.getRow() <= this.maxRow;\n // else check if we can force a swap (float=true, or different shapes) on non-resize\n if (!canMove && !o.resizing && o.collide) {\n let collide = o.collide.el.gridstackNode; // find the source node the clone collided with at 50%\n if (this.swap(node, collide)) { // swaps and mark dirty\n this._notify();\n return true;\n }\n }\n if (!canMove)\n return false;\n // if clone was able to move, copy those mods over to us now instead of caller trying to do this all over!\n // Note: we can't use the list directly as elements and other parts point to actual node, so copy content\n clone.nodes.filter(n => n._dirty).forEach(c => {\n let n = this.nodes.find(a => a._id === c._id);\n if (!n)\n return;\n Utils.copyPos(n, c);\n n._dirty = true;\n });\n this._notify();\n return true;\n }\n /** return true if can fit in grid height constrain only (always true if no maxRow) */\n willItFit(node) {\n delete node._willFitPos;\n if (!this.maxRow)\n return true;\n // create a clone with NO maxRow and check if still within size\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => { return { ...n }; })\n });\n let n = { ...node }; // clone node so we don't mod any settings on it but have full autoPosition and min/max as well! #1687\n this.cleanupNode(n);\n delete n.el;\n delete n._id;\n delete n.content;\n delete n.grid;\n clone.addNode(n);\n if (clone.getRow() <= this.maxRow) {\n node._willFitPos = Utils.copyPos({}, n);\n return true;\n }\n return false;\n }\n /** true if x,y or w,h are different after clamping to min/max */\n changedPosConstrain(node, p) {\n // first make sure w,h are set for caller\n p.w = p.w || node.w;\n p.h = p.h || node.h;\n if (node.x !== p.x || node.y !== p.y)\n return true;\n // check constrained w,h\n if (node.maxW) {\n p.w = Math.min(p.w, node.maxW);\n }\n if (node.maxH) {\n p.h = Math.min(p.h, node.maxH);\n }\n if (node.minW) {\n p.w = Math.max(p.w, node.minW);\n }\n if (node.minH) {\n p.h = Math.max(p.h, node.minH);\n }\n return (node.w !== p.w || node.h !== p.h);\n }\n /** return true if the passed in node was actually moved (checks for no-op and locked) */\n moveNode(node, o) {\n if (!node || /*node.locked ||*/ !o)\n return false;\n let wasUndefinedPack;\n if (o.pack === undefined) {\n wasUndefinedPack = o.pack = true;\n }\n // constrain the passed in values and check if we're still changing our node\n if (typeof o.x !== 'number') {\n o.x = node.x;\n }\n if (typeof o.y !== 'number') {\n o.y = node.y;\n }\n if (typeof o.w !== 'number') {\n o.w = node.w;\n }\n if (typeof o.h !== 'number') {\n o.h = node.h;\n }\n let resizing = (node.w !== o.w || node.h !== o.h);\n let nn = Utils.copyPos({}, node, true); // get min/max out first, then opt positions next\n Utils.copyPos(nn, o);\n nn = this.nodeBoundFix(nn, resizing);\n Utils.copyPos(o, nn);\n if (Utils.samePos(node, o))\n return false;\n let prevPos = Utils.copyPos({}, node);\n // check if we will need to fix collision at our new location\n let collides = this.collideAll(node, nn, o.skip);\n let needToMove = true;\n if (collides.length) {\n let activeDrag = node._moving && !o.nested;\n // check to make sure we actually collided over 50% surface area while dragging\n let collide = activeDrag ? this.directionCollideCoverage(node, o, collides) : collides[0];\n // if we're enabling creation of sub-grids on the fly, see if we're covering 80% of either one, if we didn't already do that\n if (activeDrag && collide && node.grid?.opts?.subGridDynamic && !node.grid._isTemp) {\n let over = Utils.areaIntercept(o.rect, collide._rect);\n let a1 = Utils.area(o.rect);\n let a2 = Utils.area(collide._rect);\n let perc = over / (a1 < a2 ? a1 : a2);\n if (perc > .8) {\n collide.grid.makeSubGrid(collide.el, undefined, node);\n collide = undefined;\n }\n }\n if (collide) {\n needToMove = !this._fixCollisions(node, nn, collide, o); // check if already moved...\n }\n else {\n needToMove = false; // we didn't cover >50% for a move, skip...\n if (wasUndefinedPack)\n delete o.pack;\n }\n }\n // now move (to the original ask vs the collision version which might differ) and repack things\n if (needToMove) {\n node._dirty = true;\n Utils.copyPos(node, nn);\n }\n if (o.pack) {\n this._packNodes()\n ._notify();\n }\n return !Utils.samePos(node, prevPos); // pack might have moved things back\n }\n getRow() {\n return this.nodes.reduce((row, n) => Math.max(row, n.y + n.h), 0);\n }\n beginUpdate(node) {\n if (!node._updating) {\n node._updating = true;\n delete node._skipDown;\n if (!this.batchMode)\n this.saveInitial();\n }\n return this;\n }\n endUpdate() {\n let n = this.nodes.find(n => n._updating);\n if (n) {\n delete n._updating;\n delete n._skipDown;\n }\n return this;\n }\n /** saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode) so we don't loose orig layout,\n * returning a list of widgets for serialization */\n save(saveElement = true, saveCB) {\n // use the highest layout for any saved info so we can have full detail on reload #1849\n let len = this._layouts?.length;\n let layout = len && this.column !== (len - 1) ? this._layouts[len - 1] : null;\n let list = [];\n this.sortNodes();\n this.nodes.forEach(n => {\n let wl = layout?.find(l => l._id === n._id);\n let w = { ...n };\n // use layout info instead if set\n if (wl) {\n w.x = wl.x;\n w.y = wl.y;\n w.w = wl.w;\n }\n Utils.removeInternalForSave(w, !saveElement);\n if (saveCB)\n saveCB(n, w);\n list.push(w);\n });\n return list;\n }\n /** @internal called whenever a node is added or moved - updates the cached layouts */\n layoutsNodesChange(nodes) {\n if (!this._layouts || this._inColumnResize)\n return this;\n // remove smaller layouts - we will re-generate those on the fly... larger ones need to update\n this._layouts.forEach((layout, column) => {\n if (!layout || column === this.column)\n return this;\n if (column < this.column) {\n this._layouts[column] = undefined;\n }\n else {\n // we save the original x,y,w (h isn't cached) to see what actually changed to propagate better.\n // NOTE: we don't need to check against out of bound scaling/moving as that will be done when using those cache values. #1785\n let ratio = column / this.column;\n nodes.forEach(node => {\n if (!node._orig)\n return; // didn't change (newly added ?)\n let n = layout.find(l => l._id === node._id);\n if (!n)\n return; // no cache for new nodes. Will use those values.\n // Y changed, push down same amount\n // TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode)\n if (node.y !== node._orig.y) {\n n.y += (node.y - node._orig.y);\n }\n // X changed, scale from new position\n if (node.x !== node._orig.x) {\n n.x = Math.round(node.x * ratio);\n }\n // width changed, scale from new width\n if (node.w !== node._orig.w) {\n n.w = Math.round(node.w * ratio);\n }\n // ...height always carries over from cache\n });\n }\n });\n return this;\n }\n /**\n * @internal Called to scale the widget width & position up/down based on the column change.\n * Note we store previous layouts (especially original ones) to make it possible to go\n * from say 12 -> 1 -> 12 and get back to where we were.\n *\n * @param prevColumn previous number of columns\n * @param column new column number\n * @param nodes different sorted list (ex: DOM order) instead of current list\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\n */\n updateNodeWidths(prevColumn, column, nodes, layout = 'moveScale') {\n if (!this.nodes.length || !column || prevColumn === column)\n return this;\n // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data\n this.cacheLayout(this.nodes, prevColumn);\n this.batchUpdate(); // do this EARLY as it will call saveInitial() so we can detect where we started for _dirty and collision\n let newNodes = [];\n // if we're going to 1 column and using DOM order rather than default sorting, then generate that layout\n let domOrder = false;\n if (column === 1 && nodes?.length) {\n domOrder = true;\n let top = 0;\n nodes.forEach(n => {\n n.x = 0;\n n.w = 1;\n n.y = Math.max(n.y, top);\n top = n.y + n.h;\n });\n newNodes = nodes;\n nodes = [];\n }\n else {\n nodes = Utils.sort(this.nodes, -1, prevColumn); // current column reverse sorting so we can insert last to front (limit collision)\n }\n // see if we have cached previous layout IFF we are going up in size (restore) otherwise always\n // generate next size down from where we are (looks more natural as you gradually size down).\n let cacheNodes = [];\n if (column > prevColumn) {\n cacheNodes = this._layouts[column] || [];\n // ...if not, start with the largest layout (if not already there) as down-scaling is more accurate\n // by pretending we came from that larger column by assigning those values as starting point\n let lastIndex = this._layouts.length - 1;\n if (!cacheNodes.length && prevColumn !== lastIndex && this._layouts[lastIndex]?.length) {\n prevColumn = lastIndex;\n this._layouts[lastIndex].forEach(cacheNode => {\n let n = nodes.find(n => n._id === cacheNode._id);\n if (n) {\n // still current, use cache info positions\n n.x = cacheNode.x;\n n.y = cacheNode.y;\n n.w = cacheNode.w;\n }\n });\n }\n }\n // if we found cache re-use those nodes that are still current\n cacheNodes.forEach(cacheNode => {\n let j = nodes.findIndex(n => n._id === cacheNode._id);\n if (j !== -1) {\n // still current, use cache info positions\n if (cacheNode.autoPosition || isNaN(cacheNode.x) || isNaN(cacheNode.y)) {\n this.findEmptyPosition(cacheNode, newNodes);\n }\n if (!cacheNode.autoPosition) {\n nodes[j].x = cacheNode.x;\n nodes[j].y = cacheNode.y;\n nodes[j].w = cacheNode.w;\n newNodes.push(nodes[j]);\n }\n nodes.splice(j, 1);\n }\n });\n // ...and add any extra non-cached ones\n if (nodes.length) {\n if (typeof layout === 'function') {\n layout(column, prevColumn, newNodes, nodes);\n }\n else if (!domOrder) {\n let ratio = column / prevColumn;\n let move = (layout === 'move' || layout === 'moveScale');\n let scale = (layout === 'scale' || layout === 'moveScale');\n nodes.forEach(node => {\n // NOTE: x + w could be outside of the grid, but addNode() below will handle that\n node.x = (column === 1 ? 0 : (move ? Math.round(node.x * ratio) : Math.min(node.x, column - 1)));\n node.w = ((column === 1 || prevColumn === 1) ? 1 :\n scale ? (Math.round(node.w * ratio) || 1) : (Math.min(node.w, column)));\n newNodes.push(node);\n });\n nodes = [];\n }\n }\n // finally re-layout them in reverse order (to get correct placement)\n if (!domOrder)\n newNodes = Utils.sort(newNodes, -1, column);\n this._inColumnResize = true; // prevent cache update\n this.nodes = []; // pretend we have no nodes to start with (add() will use same structures) to simplify layout\n newNodes.forEach(node => {\n this.addNode(node, false); // 'false' for add event trigger\n delete node._orig; // make sure the commit doesn't try to restore things back to original\n });\n this.batchUpdate(false);\n delete this._inColumnResize;\n return this;\n }\n /**\n * call to cache the given layout internally to the given location so we can restore back when column changes size\n * @param nodes list of nodes\n * @param column corresponding column index to save it under\n * @param clear if true, will force other caches to be removed (default false)\n */\n cacheLayout(nodes, column, clear = false) {\n let copy = [];\n nodes.forEach((n, i) => {\n n._id = n._id ?? GridStackEngine._idSeq++; // make sure we have an id in case this is new layout, else re-use id already set\n copy[i] = { x: n.x, y: n.y, w: n.w, _id: n._id }; // only thing we change is x,y,w and id to find it back\n });\n this._layouts = clear ? [] : this._layouts || []; // use array to find larger quick\n this._layouts[column] = copy;\n return this;\n }\n /**\n * call to cache the given node layout internally to the given location so we can restore back when column changes size\n * @param node single node to cache\n * @param column corresponding column index to save it under\n */\n cacheOneLayout(n, column) {\n n._id = n._id ?? GridStackEngine._idSeq++;\n let l = { x: n.x, y: n.y, w: n.w, _id: n._id };\n if (n.autoPosition) {\n delete l.x;\n delete l.y;\n l.autoPosition = true;\n }\n this._layouts = this._layouts || [];\n this._layouts[column] = this._layouts[column] || [];\n let index = this.findCacheLayout(n, column);\n if (index === -1)\n this._layouts[column].push(l);\n else\n this._layouts[column][index] = l;\n return this;\n }\n findCacheLayout(n, column) {\n return this._layouts?.[column]?.findIndex(l => l._id === n._id) ?? -1;\n }\n /** called to remove all internal values but the _id */\n cleanupNode(node) {\n for (let prop in node) {\n if (prop[0] === '_' && prop !== '_id')\n delete node[prop];\n }\n return this;\n }\n}\n/** @internal unique global internal _id counter */\nGridStackEngine._idSeq = 0;\n\n\n;// CONCATENATED MODULE: ./src/types.ts\n/**\n * types.ts 8.2.2\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n// default values for grid options - used during init and when saving out\nconst gridDefaults = {\n alwaysShowResizeHandle: 'mobile',\n animate: true,\n auto: true,\n cellHeight: 'auto',\n cellHeightThrottle: 100,\n cellHeightUnit: 'px',\n column: 12,\n draggable: { handle: '.grid-stack-item-content', appendTo: 'body', scroll: true },\n handle: '.grid-stack-item-content',\n itemClass: 'grid-stack-item',\n margin: 10,\n marginUnit: 'px',\n maxRow: 0,\n minRow: 0,\n oneColumnSize: 768,\n placeholderClass: 'grid-stack-placeholder',\n placeholderText: '',\n removableOptions: { accept: '.grid-stack-item' },\n resizable: { handles: 'se' },\n rtl: 'auto',\n // **** same as not being set ****\n // disableDrag: false,\n // disableOneColumnMode: false,\n // disableResize: false,\n // float: false,\n // handleClass: null,\n // oneColumnModeDomSort: false,\n // removable: false,\n // staticGrid: false,\n // styleInHead: false,\n};\n/** default dragIn options */\nconst dragInDefaultOptions = {\n handle: '.grid-stack-item-content',\n appendTo: 'body',\n // revert: 'invalid',\n // scroll: false,\n};\n\n;// CONCATENATED MODULE: ./src/dd-manager.ts\n/**\n * dd-manager.ts 8.2.2\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n/**\n * globals that are shared across Drag & Drop instances\n */\nclass DDManager {\n}\n\n;// CONCATENATED MODULE: ./src/dd-touch.ts\n/**\n * touch.ts 8.2.2\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\n/**\n * Detect touch support - Windows Surface devices and other touch devices\n * should we use this instead ? (what we had for always showing resize handles)\n * /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\n */\nconst isTouch = typeof window !== 'undefined' && typeof document !== 'undefined' &&\n ('ontouchstart' in document\n || 'ontouchstart' in window\n // || !!window.TouchEvent // true on Windows 10 Chrome desktop so don't use this\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n || (window.DocumentTouch && document instanceof window.DocumentTouch)\n || navigator.maxTouchPoints > 0\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n || navigator.msMaxTouchPoints > 0);\n// interface TouchCoord {x: number, y: number};\nclass DDTouch {\n}\n/**\n* Get the x,y position of a touch event\n*/\n// function getTouchCoords(e: TouchEvent): TouchCoord {\n// return {\n// x: e.changedTouches[0].pageX,\n// y: e.changedTouches[0].pageY\n// };\n// }\n/**\n * Simulate a mouse event based on a corresponding touch event\n * @param {Object} e A touch event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulateMouseEvent(e, simulatedType) {\n // Ignore multi-touch events\n if (e.touches.length > 1)\n return;\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable)\n e.preventDefault();\n const touch = e.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents');\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n touch.screenX, // screenX\n touch.screenY, // screenY\n touch.clientX, // clientX\n touch.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n/**\n * Simulate a mouse event based on a corresponding Pointer event\n * @param {Object} e A pointer event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulatePointerMouseEvent(e, simulatedType) {\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable)\n e.preventDefault();\n const simulatedEvent = document.createEvent('MouseEvents');\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n e.screenX, // screenX\n e.screenY, // screenY\n e.clientX, // clientX\n e.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n/**\n * Handle the touchstart events\n * @param {Object} e The widget element's touchstart event\n */\nfunction touchstart(e) {\n // Ignore the event if another widget is already being handled\n if (DDTouch.touchHandled)\n return;\n DDTouch.touchHandled = true;\n // Simulate the mouse events\n // simulateMouseEvent(e, 'mouseover');\n // simulateMouseEvent(e, 'mousemove');\n simulateMouseEvent(e, 'mousedown');\n}\n/**\n * Handle the touchmove events\n * @param {Object} e The document's touchmove event\n */\nfunction touchmove(e) {\n // Ignore event if not handled by us\n if (!DDTouch.touchHandled)\n return;\n simulateMouseEvent(e, 'mousemove');\n}\n/**\n * Handle the touchend events\n * @param {Object} e The document's touchend event\n */\nfunction touchend(e) {\n // Ignore event if not handled\n if (!DDTouch.touchHandled)\n return;\n // cancel delayed leave event when we release on ourself which happens BEFORE we get this!\n if (DDTouch.pointerLeaveTimeout) {\n window.clearTimeout(DDTouch.pointerLeaveTimeout);\n delete DDTouch.pointerLeaveTimeout;\n }\n const wasDragging = !!DDManager.dragElement;\n // Simulate the mouseup event\n simulateMouseEvent(e, 'mouseup');\n // simulateMouseEvent(event, 'mouseout');\n // If the touch interaction did not move, it should trigger a click\n if (!wasDragging) {\n simulateMouseEvent(e, 'click');\n }\n // Unset the flag to allow other widgets to inherit the touch event\n DDTouch.touchHandled = false;\n}\n/**\n * Note we don't get touchenter/touchleave (which are deprecated)\n * see https://stackoverflow.com/questions/27908339/js-touch-equivalent-for-mouseenter\n * so instead of PointerEvent to still get enter/leave and send the matching mouse event.\n */\nfunction pointerdown(e) {\n // console.log(\"pointer down\")\n e.target.releasePointerCapture(e.pointerId); // <- Important!\n}\nfunction pointerenter(e) {\n // ignore the initial one we get on pointerdown on ourself\n if (!DDManager.dragElement) {\n // console.log('pointerenter ignored');\n return;\n }\n // console.log('pointerenter');\n simulatePointerMouseEvent(e, 'mouseenter');\n}\nfunction pointerleave(e) {\n // ignore the leave on ourself we get before releasing the mouse over ourself\n // by delaying sending the event and having the up event cancel us\n if (!DDManager.dragElement) {\n // console.log('pointerleave ignored');\n return;\n }\n DDTouch.pointerLeaveTimeout = window.setTimeout(() => {\n delete DDTouch.pointerLeaveTimeout;\n // console.log('pointerleave delayed');\n simulatePointerMouseEvent(e, 'mouseleave');\n }, 10);\n}\n\n;// CONCATENATED MODULE: ./src/dd-resizable-handle.ts\n/**\n * dd-resizable-handle.ts 8.2.2\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nclass DDResizableHandle {\n constructor(host, direction, option) {\n /** @internal true after we've moved enough pixels to start a resize */\n this.moving = false;\n this.host = host;\n this.dir = direction;\n this.option = option;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n this._init();\n }\n /** @internal */\n _init() {\n const el = document.createElement('div');\n el.classList.add('ui-resizable-handle');\n el.classList.add(`${DDResizableHandle.prefix}${this.dir}`);\n el.style.zIndex = '100';\n el.style.userSelect = 'none';\n this.el = el;\n this.host.appendChild(this.el);\n this.el.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.addEventListener('touchstart', touchstart);\n this.el.addEventListener('pointerdown', pointerdown);\n // this.el.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n return this;\n }\n /** call this when resize handle needs to be removed and cleaned up */\n destroy() {\n if (this.moving)\n this._mouseUp(this.mouseDownEvent);\n this.el.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.removeEventListener('touchstart', touchstart);\n this.el.removeEventListener('pointerdown', pointerdown);\n }\n this.host.removeChild(this.el);\n delete this.el;\n delete this.host;\n return this;\n }\n /** @internal called on mouse down on us: capture move on the entire document (mouse might not stay on us) until we release the mouse */\n _mouseDown(e) {\n this.mouseDownEvent = e;\n document.addEventListener('mousemove', this._mouseMove, true); // capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.addEventListener('touchmove', touchmove);\n this.el.addEventListener('touchend', touchend);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n /** @internal */\n _mouseMove(e) {\n let s = this.mouseDownEvent;\n if (this.moving) {\n this._triggerEvent('move', e);\n }\n else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 2) {\n // don't start unless we've moved at least 3 pixels\n this.moving = true;\n this._triggerEvent('start', this.mouseDownEvent);\n this._triggerEvent('move', e);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n /** @internal */\n _mouseUp(e) {\n if (this.moving) {\n this._triggerEvent('stop', e);\n }\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.removeEventListener('touchmove', touchmove);\n this.el.removeEventListener('touchend', touchend);\n }\n delete this.moving;\n delete this.mouseDownEvent;\n e.stopPropagation();\n e.preventDefault();\n }\n /** @internal */\n _triggerEvent(name, event) {\n if (this.option[name])\n this.option[name](event);\n return this;\n }\n}\n/** @internal */\nDDResizableHandle.prefix = 'ui-resizable-';\n\n\n;// CONCATENATED MODULE: ./src/dd-base-impl.ts\n/**\n * dd-base-impl.ts 8.2.2\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\nclass DDBaseImplement {\n constructor() {\n /** @internal */\n this._eventRegister = {};\n }\n /** returns the enable state, but you have to call enable()/disable() to change (as other things need to happen) */\n get disabled() { return this._disabled; }\n on(event, callback) {\n this._eventRegister[event] = callback;\n }\n off(event) {\n delete this._eventRegister[event];\n }\n enable() {\n this._disabled = false;\n }\n disable() {\n this._disabled = true;\n }\n destroy() {\n delete this._eventRegister;\n }\n triggerEvent(eventName, event) {\n if (!this.disabled && this._eventRegister && this._eventRegister[eventName])\n return this._eventRegister[eventName](event);\n }\n}\n\n;// CONCATENATED MODULE: ./src/dd-resizable.ts\n/**\n * dd-resizable.ts 8.2.2\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\n\n\n\nclass DDResizable extends DDBaseImplement {\n constructor(el, opts = {}) {\n super();\n /** @internal */\n this._ui = () => {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const newRect = {\n width: this.originalRect.width,\n height: this.originalRect.height + this.scrolled,\n left: this.originalRect.left,\n top: this.originalRect.top - this.scrolled\n };\n const rect = this.temporalRect || newRect;\n return {\n position: {\n left: rect.left - containmentRect.left,\n top: rect.top - containmentRect.top\n },\n size: {\n width: rect.width,\n height: rect.height\n }\n /* Gridstack ONLY needs position set above... keep around in case.\n element: [this.el], // The object representing the element to be resized\n helper: [], // TODO: not support yet - The object representing the helper that's being resized\n originalElement: [this.el],// we don't wrap here, so simplify as this.el //The object representing the original element before it is wrapped\n originalPosition: { // The position represented as { left, top } before the resizable is resized\n left: this.originalRect.left - containmentRect.left,\n top: this.originalRect.top - containmentRect.top\n },\n originalSize: { // The size represented as { width, height } before the resizable is resized\n width: this.originalRect.width,\n height: this.originalRect.height\n }\n */\n };\n };\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseOver = this._mouseOver.bind(this);\n this._mouseOut = this._mouseOut.bind(this);\n this.enable();\n this._setupAutoHide(this.option.autoHide);\n this._setupHandlers();\n }\n on(event, callback) {\n super.on(event, callback);\n }\n off(event) {\n super.off(event);\n }\n enable() {\n super.enable();\n this.el.classList.remove('ui-resizable-disabled');\n this._setupAutoHide(this.option.autoHide);\n }\n disable() {\n super.disable();\n this.el.classList.add('ui-resizable-disabled');\n this._setupAutoHide(false);\n }\n destroy() {\n this._removeHandlers();\n this._setupAutoHide(false);\n delete this.el;\n super.destroy();\n }\n updateOption(opts) {\n let updateHandles = (opts.handles && opts.handles !== this.option.handles);\n let updateAutoHide = (opts.autoHide && opts.autoHide !== this.option.autoHide);\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n if (updateHandles) {\n this._removeHandlers();\n this._setupHandlers();\n }\n if (updateAutoHide) {\n this._setupAutoHide(this.option.autoHide);\n }\n return this;\n }\n /** @internal turns auto hide on/off */\n _setupAutoHide(auto) {\n if (auto) {\n this.el.classList.add('ui-resizable-autohide');\n // use mouseover and not mouseenter to get better performance and track for nested cases\n this.el.addEventListener('mouseover', this._mouseOver);\n this.el.addEventListener('mouseout', this._mouseOut);\n }\n else {\n this.el.classList.remove('ui-resizable-autohide');\n this.el.removeEventListener('mouseover', this._mouseOver);\n this.el.removeEventListener('mouseout', this._mouseOut);\n if (DDManager.overResizeElement === this) {\n delete DDManager.overResizeElement;\n }\n }\n return this;\n }\n /** @internal */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _mouseOver(e) {\n // console.log(`${count++} pre-enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n // already over a child, ignore. Ideally we just call e.stopPropagation() but see https://github.com/gridstack/gridstack.js/issues/2018\n if (DDManager.overResizeElement || DDManager.dragElement)\n return;\n DDManager.overResizeElement = this;\n // console.log(`${count++} enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.remove('ui-resizable-autohide');\n }\n /** @internal */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _mouseOut(e) {\n // console.log(`${count++} pre-leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n if (DDManager.overResizeElement !== this)\n return;\n delete DDManager.overResizeElement;\n // console.log(`${count++} leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.add('ui-resizable-autohide');\n }\n /** @internal */\n _setupHandlers() {\n let handlerDirection = this.option.handles || 'e,s,se';\n if (handlerDirection === 'all') {\n handlerDirection = 'n,e,s,w,se,sw,ne,nw';\n }\n this.handlers = handlerDirection.split(',')\n .map(dir => dir.trim())\n .map(dir => new DDResizableHandle(this.el, dir, {\n start: (event) => {\n this._resizeStart(event);\n },\n stop: (event) => {\n this._resizeStop(event);\n },\n move: (event) => {\n this._resizing(event, dir);\n }\n }));\n return this;\n }\n /** @internal */\n _resizeStart(event) {\n this.originalRect = this.el.getBoundingClientRect();\n this.scrollEl = Utils.getScrollElement(this.el);\n this.scrollY = this.scrollEl.scrollTop;\n this.scrolled = 0;\n this.startEvent = event;\n this._setupHelper();\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resizestart', target: this.el });\n if (this.option.start) {\n this.option.start(ev, this._ui());\n }\n this.el.classList.add('ui-resizable-resizing');\n this.triggerEvent('resizestart', ev);\n return this;\n }\n /** @internal */\n _resizing(event, dir) {\n this.scrolled = this.scrollEl.scrollTop - this.scrollY;\n this.temporalRect = this._getChange(event, dir);\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resize', target: this.el });\n if (this.option.resize) {\n this.option.resize(ev, this._ui());\n }\n this.triggerEvent('resize', ev);\n return this;\n }\n /** @internal */\n _resizeStop(event) {\n const ev = Utils.initEvent(event, { type: 'resizestop', target: this.el });\n if (this.option.stop) {\n this.option.stop(ev); // Note: ui() not used by gridstack so don't pass\n }\n this.el.classList.remove('ui-resizable-resizing');\n this.triggerEvent('resizestop', ev);\n this._cleanHelper();\n delete this.startEvent;\n delete this.originalRect;\n delete this.temporalRect;\n delete this.scrollY;\n delete this.scrolled;\n return this;\n }\n /** @internal */\n _setupHelper() {\n this.elOriginStyleVal = DDResizable._originStyleProp.map(prop => this.el.style[prop]);\n this.parentOriginStylePosition = this.el.parentElement.style.position;\n if (window.getComputedStyle(this.el.parentElement).position.match(/static/)) {\n this.el.parentElement.style.position = 'relative';\n }\n this.el.style.position = 'absolute';\n this.el.style.opacity = '0.8';\n return this;\n }\n /** @internal */\n _cleanHelper() {\n DDResizable._originStyleProp.forEach((prop, i) => {\n this.el.style[prop] = this.elOriginStyleVal[i] || null;\n });\n this.el.parentElement.style.position = this.parentOriginStylePosition || null;\n return this;\n }\n /** @internal */\n _getChange(event, dir) {\n const oEvent = this.startEvent;\n const newRect = {\n width: this.originalRect.width,\n height: this.originalRect.height + this.scrolled,\n left: this.originalRect.left,\n top: this.originalRect.top - this.scrolled\n };\n const offsetX = event.clientX - oEvent.clientX;\n const offsetY = event.clientY - oEvent.clientY;\n if (dir.indexOf('e') > -1) {\n newRect.width += offsetX;\n }\n else if (dir.indexOf('w') > -1) {\n newRect.width -= offsetX;\n newRect.left += offsetX;\n }\n if (dir.indexOf('s') > -1) {\n newRect.height += offsetY;\n }\n else if (dir.indexOf('n') > -1) {\n newRect.height -= offsetY;\n newRect.top += offsetY;\n }\n const constrain = this._constrainSize(newRect.width, newRect.height);\n if (Math.round(newRect.width) !== Math.round(constrain.width)) { // round to ignore slight round-off errors\n if (dir.indexOf('w') > -1) {\n newRect.left += newRect.width - constrain.width;\n }\n newRect.width = constrain.width;\n }\n if (Math.round(newRect.height) !== Math.round(constrain.height)) {\n if (dir.indexOf('n') > -1) {\n newRect.top += newRect.height - constrain.height;\n }\n newRect.height = constrain.height;\n }\n return newRect;\n }\n /** @internal constrain the size to the set min/max values */\n _constrainSize(oWidth, oHeight) {\n const maxWidth = this.option.maxWidth || Number.MAX_SAFE_INTEGER;\n const minWidth = this.option.minWidth || oWidth;\n const maxHeight = this.option.maxHeight || Number.MAX_SAFE_INTEGER;\n const minHeight = this.option.minHeight || oHeight;\n const width = Math.min(maxWidth, Math.max(minWidth, oWidth));\n const height = Math.min(maxHeight, Math.max(minHeight, oHeight));\n return { width, height };\n }\n /** @internal */\n _applyChange() {\n let containmentRect = { left: 0, top: 0, width: 0, height: 0 };\n if (this.el.style.position === 'absolute') {\n const containmentEl = this.el.parentElement;\n const { left, top } = containmentEl.getBoundingClientRect();\n containmentRect = { left, top, width: 0, height: 0 };\n }\n if (!this.temporalRect)\n return this;\n Object.keys(this.temporalRect).forEach(key => {\n const value = this.temporalRect[key];\n this.el.style[key] = value - containmentRect[key] + 'px';\n });\n return this;\n }\n /** @internal */\n _removeHandlers() {\n this.handlers.forEach(handle => handle.destroy());\n delete this.handlers;\n return this;\n }\n}\n/** @internal */\nDDResizable._originStyleProp = ['width', 'height', 'position', 'left', 'top', 'opacity', 'zIndex'];\n\n\n;// CONCATENATED MODULE: ./src/dd-draggable.ts\n/**\n * dd-draggable.ts 8.2.2\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\n\n\n\n// make sure we are not clicking on known object that handles mouseDown\nconst skipMouseDown = 'input,textarea,button,select,option,[contenteditable=\"true\"],.ui-resizable-handle';\n// let count = 0; // TEST\nclass DDDraggable extends DDBaseImplement {\n constructor(el, option = {}) {\n super();\n this.el = el;\n this.option = option;\n // get the element that is actually supposed to be dragged by\n let handleName = option.handle.substring(1);\n this.dragEl = el.classList.contains(handleName) ? el : el.querySelector(option.handle) || el;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n this.enable();\n }\n on(event, callback) {\n super.on(event, callback);\n }\n off(event) {\n super.off(event);\n }\n enable() {\n if (this.disabled === false)\n return;\n super.enable();\n this.dragEl.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.addEventListener('touchstart', touchstart);\n this.dragEl.addEventListener('pointerdown', pointerdown);\n // this.dragEl.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n this.el.classList.remove('ui-draggable-disabled');\n }\n disable(forDestroy = false) {\n if (this.disabled === true)\n return;\n super.disable();\n this.dragEl.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.removeEventListener('touchstart', touchstart);\n this.dragEl.removeEventListener('pointerdown', pointerdown);\n }\n if (!forDestroy)\n this.el.classList.add('ui-draggable-disabled');\n }\n destroy() {\n if (this.dragTimeout)\n window.clearTimeout(this.dragTimeout);\n delete this.dragTimeout;\n if (this.dragging)\n this._mouseUp(this.mouseDownEvent);\n this.disable(true);\n delete this.el;\n delete this.helper;\n delete this.option;\n super.destroy();\n }\n updateOption(opts) {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n return this;\n }\n /** @internal call when mouse goes down before a dragstart happens */\n _mouseDown(e) {\n // don't let more than one widget handle mouseStart\n if (DDManager.mouseHandled)\n return;\n if (e.button !== 0)\n return true; // only left click\n // make sure we are not clicking on known object that handles mouseDown, or ones supplied by the user\n if (e.target.closest(skipMouseDown))\n return true;\n if (this.option.cancel) {\n if (e.target.closest(this.option.cancel))\n return true;\n }\n // REMOVE: why would we get the event if it wasn't for us or child ?\n // make sure we are clicking on a drag handle or child of it...\n // Note: we don't need to check that's handle is an immediate child, as mouseHandled will prevent parents from also handling it (lowest wins)\n // let className = this.option.handle.substring(1);\n // let el = e.target as HTMLElement;\n // while (el && !el.classList.contains(className)) { el = el.parentElement; }\n // if (!el) return;\n this.mouseDownEvent = e;\n delete this.dragging;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n // document handler so we can continue receiving moves as the item is 'fixed' position, and capture=true so WE get a first crack\n document.addEventListener('mousemove', this._mouseMove, true); // true=capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.addEventListener('touchmove', touchmove);\n this.dragEl.addEventListener('touchend', touchend);\n }\n e.preventDefault();\n // preventDefault() prevents blur event which occurs just after mousedown event.\n // if an editable content has focus, then blur must be call\n if (document.activeElement)\n document.activeElement.blur();\n DDManager.mouseHandled = true;\n return true;\n }\n /** @internal method to call actual drag event */\n _callDrag(e) {\n if (!this.dragging)\n return;\n const ev = Utils.initEvent(e, { target: this.el, type: 'drag' });\n if (this.option.drag) {\n this.option.drag(ev, this.ui());\n }\n this.triggerEvent('drag', ev);\n }\n /** @internal called when the main page (after successful mousedown) receives a move event to drag the item around the screen */\n _mouseMove(e) {\n // console.log(`${count++} move ${e.x},${e.y}`)\n let s = this.mouseDownEvent;\n if (this.dragging) {\n this._dragFollow(e);\n // delay actual grid handling drag until we pause for a while if set\n if (DDManager.pauseDrag) {\n const pause = Number.isInteger(DDManager.pauseDrag) ? DDManager.pauseDrag : 100;\n if (this.dragTimeout)\n window.clearTimeout(this.dragTimeout);\n this.dragTimeout = window.setTimeout(() => this._callDrag(e), pause);\n }\n else {\n this._callDrag(e);\n }\n }\n else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 3) {\n /**\n * don't start unless we've moved at least 3 pixels\n */\n this.dragging = true;\n DDManager.dragElement = this;\n // if we're dragging an actual grid item, set the current drop as the grid (to detect enter/leave)\n let grid = this.el.gridstackNode?.grid;\n if (grid) {\n DDManager.dropElement = grid.el.ddElement.ddDroppable;\n }\n else {\n delete DDManager.dropElement;\n }\n this.helper = this._createHelper(e);\n this._setupHelperContainmentStyle();\n this.dragOffset = this._getDragOffset(e, this.el, this.helperContainment);\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstart' });\n this._setupHelperStyle(e);\n if (this.option.start) {\n this.option.start(ev, this.ui());\n }\n this.triggerEvent('dragstart', ev);\n }\n e.preventDefault(); // needed otherwise we get text sweep text selection as we drag around\n return true;\n }\n /** @internal call when the mouse gets released to drop the item at current location */\n _mouseUp(e) {\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.removeEventListener('touchmove', touchmove, true);\n this.dragEl.removeEventListener('touchend', touchend, true);\n }\n if (this.dragging) {\n delete this.dragging;\n // reset the drop target if dragging over ourself (already parented, just moving during stop callback below)\n if (DDManager.dropElement?.el === this.el.parentElement) {\n delete DDManager.dropElement;\n }\n this.helperContainment.style.position = this.parentOriginStylePosition || null;\n if (this.helper === this.el) {\n this._removeHelperStyle();\n }\n else {\n this.helper.remove();\n }\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstop' });\n if (this.option.stop) {\n this.option.stop(ev); // NOTE: destroy() will be called when removing item, so expect NULL ptr after!\n }\n this.triggerEvent('dragstop', ev);\n // call the droppable method to receive the item\n if (DDManager.dropElement) {\n DDManager.dropElement.drop(e);\n }\n }\n delete this.helper;\n delete this.mouseDownEvent;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n delete DDManager.mouseHandled;\n e.preventDefault();\n }\n /** @internal create a clone copy (or user defined method) of the original drag item if set */\n _createHelper(event) {\n let helper = this.el;\n if (typeof this.option.helper === 'function') {\n helper = this.option.helper(event);\n }\n else if (this.option.helper === 'clone') {\n helper = Utils.cloneNode(this.el);\n }\n if (!document.body.contains(helper)) {\n Utils.appendTo(helper, this.option.appendTo === 'parent' ? this.el.parentElement : this.option.appendTo);\n }\n if (helper === this.el) {\n this.dragElementOriginStyle = DDDraggable.originStyleProp.map(prop => this.el.style[prop]);\n }\n return helper;\n }\n /** @internal set the fix position of the dragged item */\n _setupHelperStyle(e) {\n this.helper.classList.add('ui-draggable-dragging');\n // TODO: set all at once with style.cssText += ... ? https://stackoverflow.com/questions/3968593\n const style = this.helper.style;\n style.pointerEvents = 'none'; // needed for over items to get enter/leave\n // style.cursor = 'move'; // TODO: can't set with pointerEvents=none ! (done in CSS as well)\n style.width = this.dragOffset.width + 'px';\n style.height = this.dragOffset.height + 'px';\n style.willChange = 'left, top';\n style.position = 'fixed'; // let us drag between grids by not clipping as parent .grid-stack is position: 'relative'\n this._dragFollow(e); // now position it\n style.transition = 'none'; // show up instantly\n setTimeout(() => {\n if (this.helper) {\n style.transition = null; // recover animation\n }\n }, 0);\n return this;\n }\n /** @internal restore back the original style before dragging */\n _removeHelperStyle() {\n this.helper.classList.remove('ui-draggable-dragging');\n let node = this.helper?.gridstackNode;\n // don't bother restoring styles if we're gonna remove anyway...\n if (!node?._isAboutToRemove && this.dragElementOriginStyle) {\n let helper = this.helper;\n // don't animate, otherwise we animate offseted when switching back to 'absolute' from 'fixed'.\n // TODO: this also removes resizing animation which doesn't have this issue, but others.\n // Ideally both would animate ('move' would immediately restore 'absolute' and adjust coordinate to match,\n // then trigger a delay (repaint) to restore to final dest with animate) but then we need to make sure 'resizestop'\n // is called AFTER 'transitionend' event is received (see https://github.com/gridstack/gridstack.js/issues/2033)\n let transition = this.dragElementOriginStyle['transition'] || null;\n helper.style.transition = this.dragElementOriginStyle['transition'] = 'none'; // can't be NULL #1973\n DDDraggable.originStyleProp.forEach(prop => helper.style[prop] = this.dragElementOriginStyle[prop] || null);\n setTimeout(() => helper.style.transition = transition, 50); // recover animation from saved vars after a pause (0 isn't enough #1973)\n }\n delete this.dragElementOriginStyle;\n return this;\n }\n /** @internal updates the top/left position to follow the mouse */\n _dragFollow(e) {\n let containmentRect = { left: 0, top: 0 };\n // if (this.helper.style.position === 'absolute') { // we use 'fixed'\n // const { left, top } = this.helperContainment.getBoundingClientRect();\n // containmentRect = { left, top };\n // }\n const style = this.helper.style;\n const offset = this.dragOffset;\n style.left = e.clientX + offset.offsetLeft - containmentRect.left + 'px';\n style.top = e.clientY + offset.offsetTop - containmentRect.top + 'px';\n }\n /** @internal */\n _setupHelperContainmentStyle() {\n this.helperContainment = this.helper.parentElement;\n if (this.helper.style.position !== 'fixed') {\n this.parentOriginStylePosition = this.helperContainment.style.position;\n if (window.getComputedStyle(this.helperContainment).position.match(/static/)) {\n this.helperContainment.style.position = 'relative';\n }\n }\n return this;\n }\n /** @internal */\n _getDragOffset(event, el, parent) {\n // in case ancestor has transform/perspective css properties that change the viewpoint\n let xformOffsetX = 0;\n let xformOffsetY = 0;\n if (parent) {\n const testEl = document.createElement('div');\n Utils.addElStyles(testEl, {\n opacity: '0',\n position: 'fixed',\n top: 0 + 'px',\n left: 0 + 'px',\n width: '1px',\n height: '1px',\n zIndex: '-999999',\n });\n parent.appendChild(testEl);\n const testElPosition = testEl.getBoundingClientRect();\n parent.removeChild(testEl);\n xformOffsetX = testElPosition.left;\n xformOffsetY = testElPosition.top;\n // TODO: scale ?\n }\n const targetOffset = el.getBoundingClientRect();\n return {\n left: targetOffset.left,\n top: targetOffset.top,\n offsetLeft: -event.clientX + targetOffset.left - xformOffsetX,\n offsetTop: -event.clientY + targetOffset.top - xformOffsetY,\n width: targetOffset.width,\n height: targetOffset.height\n };\n }\n /** @internal TODO: set to public as called by DDDroppable! */\n ui() {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const offset = this.helper.getBoundingClientRect();\n return {\n position: {\n top: offset.top - containmentRect.top,\n left: offset.left - containmentRect.left\n }\n /* not used by GridStack for now...\n helper: [this.helper], //The object arr representing the helper that's being dragged.\n offset: { top: offset.top, left: offset.left } // Current offset position of the helper as { top, left } object.\n */\n };\n }\n}\n/** @internal properties we change during dragging, and restore back */\nDDDraggable.originStyleProp = ['transition', 'pointerEvents', 'position', 'left', 'top', 'minWidth', 'willChange'];\n\n\n;// CONCATENATED MODULE: ./src/dd-droppable.ts\n/**\n * dd-droppable.ts 8.2.2\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\n\n\n\n// let count = 0; // TEST\nclass DDDroppable extends DDBaseImplement {\n constructor(el, opts = {}) {\n super();\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseEnter = this._mouseEnter.bind(this);\n this._mouseLeave = this._mouseLeave.bind(this);\n this.enable();\n this._setupAccept();\n }\n on(event, callback) {\n super.on(event, callback);\n }\n off(event) {\n super.off(event);\n }\n enable() {\n if (this.disabled === false)\n return;\n super.enable();\n this.el.classList.add('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n this.el.addEventListener('mouseenter', this._mouseEnter);\n this.el.addEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.addEventListener('pointerenter', pointerenter);\n this.el.addEventListener('pointerleave', pointerleave);\n }\n }\n disable(forDestroy = false) {\n if (this.disabled === true)\n return;\n super.disable();\n this.el.classList.remove('ui-droppable');\n if (!forDestroy)\n this.el.classList.add('ui-droppable-disabled');\n this.el.removeEventListener('mouseenter', this._mouseEnter);\n this.el.removeEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.removeEventListener('pointerenter', pointerenter);\n this.el.removeEventListener('pointerleave', pointerleave);\n }\n }\n destroy() {\n this.disable(true);\n this.el.classList.remove('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n super.destroy();\n }\n updateOption(opts) {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n this._setupAccept();\n return this;\n }\n /** @internal called when the cursor enters our area - prepare for a possible drop and track leaving */\n _mouseEnter(e) {\n // console.log(`${count++} Enter ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement)\n return;\n if (!this._canDrop(DDManager.dragElement.el))\n return;\n e.preventDefault();\n e.stopPropagation();\n // make sure when we enter this, that the last one gets a leave FIRST to correctly cleanup as we don't always do\n if (DDManager.dropElement && DDManager.dropElement !== this) {\n DDManager.dropElement._mouseLeave(e);\n }\n DDManager.dropElement = this;\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropover' });\n if (this.option.over) {\n this.option.over(ev, this._ui(DDManager.dragElement));\n }\n this.triggerEvent('dropover', ev);\n this.el.classList.add('ui-droppable-over');\n // console.log('tracking'); // TEST\n }\n /** @internal called when the item is leaving our area, stop tracking if we had moving item */\n _mouseLeave(e) {\n // console.log(`${count++} Leave ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement || DDManager.dropElement !== this)\n return;\n e.preventDefault();\n e.stopPropagation();\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropout' });\n if (this.option.out) {\n this.option.out(ev, this._ui(DDManager.dragElement));\n }\n this.triggerEvent('dropout', ev);\n if (DDManager.dropElement === this) {\n delete DDManager.dropElement;\n // console.log('not tracking'); // TEST\n // if we're still over a parent droppable, send it an enter as we don't get one from leaving nested children\n let parentDrop;\n let parent = this.el.parentElement;\n while (!parentDrop && parent) {\n parentDrop = parent.ddElement?.ddDroppable;\n parent = parent.parentElement;\n }\n if (parentDrop) {\n parentDrop._mouseEnter(e);\n }\n }\n }\n /** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */\n drop(e) {\n e.preventDefault();\n const ev = Utils.initEvent(e, { target: this.el, type: 'drop' });\n if (this.option.drop) {\n this.option.drop(ev, this._ui(DDManager.dragElement));\n }\n this.triggerEvent('drop', ev);\n }\n /** @internal true if element matches the string/method accept option */\n _canDrop(el) {\n return el && (!this.accept || this.accept(el));\n }\n /** @internal */\n _setupAccept() {\n if (!this.option.accept)\n return this;\n if (typeof this.option.accept === 'string') {\n this.accept = (el) => el.matches(this.option.accept);\n }\n else {\n this.accept = this.option.accept;\n }\n return this;\n }\n /** @internal */\n _ui(drag) {\n return {\n draggable: drag.el,\n ...drag.ui()\n };\n }\n}\n\n;// CONCATENATED MODULE: ./src/dd-element.ts\n/**\n * dd-elements.ts 8.2.2\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\n\n\nclass DDElement {\n static init(el) {\n if (!el.ddElement) {\n el.ddElement = new DDElement(el);\n }\n return el.ddElement;\n }\n constructor(el) {\n this.el = el;\n }\n on(eventName, callback) {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.on(eventName, callback);\n }\n else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.on(eventName, callback);\n }\n else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.on(eventName, callback);\n }\n return this;\n }\n off(eventName) {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.off(eventName);\n }\n else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.off(eventName);\n }\n else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.off(eventName);\n }\n return this;\n }\n setupDraggable(opts) {\n if (!this.ddDraggable) {\n this.ddDraggable = new DDDraggable(this.el, opts);\n }\n else {\n this.ddDraggable.updateOption(opts);\n }\n return this;\n }\n cleanDraggable() {\n if (this.ddDraggable) {\n this.ddDraggable.destroy();\n delete this.ddDraggable;\n }\n return this;\n }\n setupResizable(opts) {\n if (!this.ddResizable) {\n this.ddResizable = new DDResizable(this.el, opts);\n }\n else {\n this.ddResizable.updateOption(opts);\n }\n return this;\n }\n cleanResizable() {\n if (this.ddResizable) {\n this.ddResizable.destroy();\n delete this.ddResizable;\n }\n return this;\n }\n setupDroppable(opts) {\n if (!this.ddDroppable) {\n this.ddDroppable = new DDDroppable(this.el, opts);\n }\n else {\n this.ddDroppable.updateOption(opts);\n }\n return this;\n }\n cleanDroppable() {\n if (this.ddDroppable) {\n this.ddDroppable.destroy();\n delete this.ddDroppable;\n }\n return this;\n }\n}\n\n;// CONCATENATED MODULE: ./src/dd-gridstack.ts\n/**\n * dd-gridstack.ts 8.2.2\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\n\n\n// let count = 0; // TEST\n/**\n * HTML Native Mouse and Touch Events Drag and Drop functionality.\n */\nclass DDGridStack {\n resizable(el, opts, key, value) {\n this._getDDElements(el).forEach(dEl => {\n if (opts === 'disable' || opts === 'enable') {\n dEl.ddResizable && dEl.ddResizable[opts](); // can't create DD as it requires options for setupResizable()\n }\n else if (opts === 'destroy') {\n dEl.ddResizable && dEl.cleanResizable();\n }\n else if (opts === 'option') {\n dEl.setupResizable({ [key]: value });\n }\n else {\n const grid = dEl.el.gridstackNode.grid;\n let handles = dEl.el.getAttribute('gs-resize-handles') ? dEl.el.getAttribute('gs-resize-handles') : grid.opts.resizable.handles;\n let autoHide = !grid.opts.alwaysShowResizeHandle;\n dEl.setupResizable({\n ...grid.opts.resizable,\n ...{ handles, autoHide },\n ...{\n start: opts.start,\n stop: opts.stop,\n resize: opts.resize\n }\n });\n }\n });\n return this;\n }\n draggable(el, opts, key, value) {\n this._getDDElements(el).forEach(dEl => {\n if (opts === 'disable' || opts === 'enable') {\n dEl.ddDraggable && dEl.ddDraggable[opts](); // can't create DD as it requires options for setupDraggable()\n }\n else if (opts === 'destroy') {\n dEl.ddDraggable && dEl.cleanDraggable();\n }\n else if (opts === 'option') {\n dEl.setupDraggable({ [key]: value });\n }\n else {\n const grid = dEl.el.gridstackNode.grid;\n dEl.setupDraggable({\n ...grid.opts.draggable,\n ...{\n // containment: (grid.parentGridItem && !grid.opts.dragOut) ? grid.el.parentElement : (grid.opts.draggable.containment || null),\n start: opts.start,\n stop: opts.stop,\n drag: opts.drag\n }\n });\n }\n });\n return this;\n }\n dragIn(el, opts) {\n this._getDDElements(el).forEach(dEl => dEl.setupDraggable(opts));\n return this;\n }\n droppable(el, opts, key, value) {\n if (typeof opts.accept === 'function' && !opts._accept) {\n opts._accept = opts.accept;\n opts.accept = (el) => opts._accept(el);\n }\n this._getDDElements(el).forEach(dEl => {\n if (opts === 'disable' || opts === 'enable') {\n dEl.ddDroppable && dEl.ddDroppable[opts]();\n }\n else if (opts === 'destroy') {\n if (dEl.ddDroppable) { // error to call destroy if not there\n dEl.cleanDroppable();\n }\n }\n else if (opts === 'option') {\n dEl.setupDroppable({ [key]: value });\n }\n else {\n dEl.setupDroppable(opts);\n }\n });\n return this;\n }\n /** true if element is droppable */\n isDroppable(el) {\n return !!(el && el.ddElement && el.ddElement.ddDroppable && !el.ddElement.ddDroppable.disabled);\n }\n /** true if element is draggable */\n isDraggable(el) {\n return !!(el && el.ddElement && el.ddElement.ddDraggable && !el.ddElement.ddDraggable.disabled);\n }\n /** true if element is draggable */\n isResizable(el) {\n return !!(el && el.ddElement && el.ddElement.ddResizable && !el.ddElement.ddResizable.disabled);\n }\n on(el, name, callback) {\n this._getDDElements(el).forEach(dEl => dEl.on(name, (event) => {\n callback(event, DDManager.dragElement ? DDManager.dragElement.el : event.target, DDManager.dragElement ? DDManager.dragElement.helper : null);\n }));\n return this;\n }\n off(el, name) {\n this._getDDElements(el).forEach(dEl => dEl.off(name));\n return this;\n }\n /** @internal returns a list of DD elements, creating them on the fly by default */\n _getDDElements(els, create = true) {\n let hosts = Utils.getElements(els);\n if (!hosts.length)\n return [];\n let list = hosts.map(e => e.ddElement || (create ? DDElement.init(e) : null));\n if (!create) {\n list.filter(d => d);\n } // remove nulls\n return list;\n }\n}\n\n;// CONCATENATED MODULE: ./src/gridstack.ts\n/*!\n * GridStack 8.2.2\n * https://gridstackjs.com/\n *\n * Copyright (c) 2021-2022 Alain Dumesny\n * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE\n */\n\n\n\n/*\n * and include D&D by default\n * TODO: while we could generate a gridstack-static.js at smaller size - saves about 31k (41k -> 72k)\n * I don't know how to generate the DD only code at the remaining 31k to delay load as code depends on Gridstack.ts\n * also it caused loading issues in prod - see https://github.com/gridstack/gridstack.js/issues/2039\n */\n\n\n\n/** global instance */\nconst dd = new DDGridStack;\n// export all dependent file as well to make it easier for users to just import the main file\n\n\n\n\n/**\n * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid.\n * Note: your grid elements MUST have the following classes for the CSS layout to work:\n * @example\n * <div class=\"grid-stack\">\n * <div class=\"grid-stack-item\">\n * <div class=\"grid-stack-item-content\">Item 1</div>\n * </div>\n * </div>\n */\nclass GridStack {\n /**\n * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will\n * simply return the existing instance (ignore any passed options). There is also an initAll() version that support\n * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.\n * @param options grid options (optional)\n * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector)\n *\n * @example\n * let grid = GridStack.init();\n *\n * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later\n * let grid = document.querySelector('.grid-stack').gridstack;\n */\n static init(options = {}, elOrString = '.grid-stack') {\n let el = GridStack.getGridElement(elOrString);\n if (!el) {\n if (typeof elOrString === 'string') {\n console.error('GridStack.initAll() no grid was found with selector \"' + elOrString + '\" - element missing or wrong selector ?' +\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\n }\n else {\n console.error('GridStack.init() no grid element was passed.');\n }\n return null;\n }\n if (!el.gridstack) {\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\n }\n return el.gridstack;\n }\n /**\n * Will initialize a list of elements (given a selector) and return an array of grids.\n * @param options grid options (optional)\n * @param selector elements selector to convert to grids (default to '.grid-stack' class selector)\n *\n * @example\n * let grids = GridStack.initAll();\n * grids.forEach(...)\n */\n static initAll(options = {}, selector = '.grid-stack') {\n let grids = [];\n GridStack.getGridElements(selector).forEach(el => {\n if (!el.gridstack) {\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\n }\n grids.push(el.gridstack);\n });\n if (grids.length === 0) {\n console.error('GridStack.initAll() no grid was found with selector \"' + selector + '\" - element missing or wrong selector ?' +\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\n }\n return grids;\n }\n /**\n * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then\n * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from\n * JSON serialized data, including options.\n * @param parent HTML element parent to the grid\n * @param opt grids options used to initialize the grid, and list of children\n */\n static addGrid(parent, opt = {}) {\n if (!parent)\n return null;\n let el = parent;\n if (el.gridstack) {\n // already a grid - set option and load data\n const grid = el.gridstack;\n if (opt)\n grid.opts = { ...grid.opts, ...opt };\n if (opt.children !== undefined)\n grid.load(opt.children);\n return grid;\n }\n // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead\n const parentIsGrid = parent.classList.contains('grid-stack');\n if (!parentIsGrid || GridStack.addRemoveCB) {\n if (GridStack.addRemoveCB) {\n el = GridStack.addRemoveCB(parent, opt, true, true);\n }\n else {\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\n doc.body.innerHTML = `<div class=\"grid-stack ${opt.class || ''}\"></div>`;\n el = doc.body.children[0];\n parent.appendChild(el);\n }\n }\n // create grid class and load any children\n let grid = GridStack.init(opt, el);\n return grid;\n }\n /** call this method to register your engine instead of the default one.\n * See instead `GridStackOptions.engineClass` if you only need to\n * replace just one instance.\n */\n static registerEngine(engineClass) {\n GridStack.engineClass = engineClass;\n }\n /** @internal create placeholder DIV as needed */\n get placeholder() {\n if (!this._placeholder) {\n let placeholderChild = document.createElement('div'); // child so padding match item-content\n placeholderChild.className = 'placeholder-content';\n if (this.opts.placeholderText) {\n placeholderChild.innerHTML = this.opts.placeholderText;\n }\n this._placeholder = document.createElement('div');\n this._placeholder.classList.add(this.opts.placeholderClass, gridDefaults.itemClass, this.opts.itemClass);\n this.placeholder.appendChild(placeholderChild);\n }\n return this._placeholder;\n }\n /**\n * Construct a grid item from the given element and options\n * @param el\n * @param opts\n */\n constructor(el, opts = {}) {\n /** @internal */\n this._gsEventHandler = {};\n /** @internal extra row added when dragging at the bottom of the grid */\n this._extraDragRow = 0;\n this.el = el; // exposed HTML element to the user\n opts = opts || {}; // handles null/undefined/0\n if (!el.classList.contains('grid-stack')) {\n this.el.classList.add('grid-stack');\n }\n // if row property exists, replace minRow and maxRow instead\n if (opts.row) {\n opts.minRow = opts.maxRow = opts.row;\n delete opts.row;\n }\n let rowAttr = Utils.toNumber(el.getAttribute('gs-row'));\n // flag only valid in sub-grids (handled by parent, not here)\n if (opts.column === 'auto') {\n delete opts.column;\n }\n // save original setting so we can restore on save\n if (opts.alwaysShowResizeHandle !== undefined) {\n opts._alwaysShowResizeHandle = opts.alwaysShowResizeHandle;\n }\n // elements DOM attributes override any passed options (like CSS style) - merge the two together\n let defaults = { ...Utils.cloneDeep(gridDefaults),\n column: Utils.toNumber(el.getAttribute('gs-column')) || gridDefaults.column,\n minRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-min-row')) || gridDefaults.minRow,\n maxRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-max-row')) || gridDefaults.maxRow,\n staticGrid: Utils.toBool(el.getAttribute('gs-static')) || gridDefaults.staticGrid,\n draggable: {\n handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || gridDefaults.draggable.handle,\n },\n removableOptions: {\n accept: opts.itemClass ? '.' + opts.itemClass : gridDefaults.removableOptions.accept,\n },\n };\n if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead\n defaults.animate = Utils.toBool(el.getAttribute('gs-animate'));\n }\n this.opts = Utils.defaults(opts, defaults);\n opts = null; // make sure we use this.opts instead\n this._initMargin(); // part of settings defaults...\n // Now check if we're loading into 1 column mode FIRST so we don't do un-necessary work (like cellHeight = width / 12 then go 1 column)\n if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) {\n this._prevColumn = this.getColumn();\n this.opts.column = 1;\n }\n if (this.opts.rtl === 'auto') {\n this.opts.rtl = (el.style.direction === 'rtl');\n }\n if (this.opts.rtl) {\n this.el.classList.add('grid-stack-rtl');\n }\n // check if we're been nested, and if so update our style and keep pointer around (used during save)\n let parentGridItem = Utils.closestUpByClass(this.el, gridDefaults.itemClass)?.gridstackNode;\n if (parentGridItem) {\n parentGridItem.subGrid = this;\n this.parentGridItem = parentGridItem;\n this.el.classList.add('grid-stack-nested');\n parentGridItem.el.classList.add('grid-stack-sub-grid');\n }\n this._isAutoCellHeight = (this.opts.cellHeight === 'auto');\n if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') {\n // make the cell content square initially (will use resize/column event to keep it square)\n this.cellHeight(undefined, false);\n }\n else {\n // append unit if any are set\n if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== gridDefaults.cellHeightUnit) {\n this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit;\n delete this.opts.cellHeightUnit;\n }\n this.cellHeight(this.opts.cellHeight, false);\n }\n // see if we need to adjust auto-hide\n if (this.opts.alwaysShowResizeHandle === 'mobile') {\n this.opts.alwaysShowResizeHandle = isTouch;\n }\n this._styleSheetClass = 'gs-id-' + GridStackEngine._idSeq++;\n this.el.classList.add(this._styleSheetClass);\n this._setStaticClass();\n let engineClass = this.opts.engineClass || GridStack.engineClass || GridStackEngine;\n this.engine = new engineClass({\n column: this.getColumn(),\n float: this.opts.float,\n maxRow: this.opts.maxRow,\n onChange: (cbNodes) => {\n let maxH = 0;\n this.engine.nodes.forEach(n => { maxH = Math.max(maxH, n.y + n.h); });\n cbNodes.forEach(n => {\n let el = n.el;\n if (!el)\n return;\n if (n._removeDOM) {\n if (el)\n el.remove();\n delete n._removeDOM;\n }\n else {\n this._writePosAttr(el, n);\n }\n });\n this._updateStyles(false, maxH); // false = don't recreate, just append if need be\n }\n });\n if (this.opts.auto) {\n this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check...\n this.getGridItems().forEach(el => this._prepareElement(el));\n this.batchUpdate(false);\n }\n // load any passed in children as well, which overrides any DOM layout done above\n if (this.opts.children) {\n let children = this.opts.children;\n delete this.opts.children;\n if (children.length)\n this.load(children); // don't load empty\n }\n this.setAnimation(this.opts.animate);\n this._updateStyles();\n this.el.classList.add('gs-' + this.opts.column);\n // dynamic grids require pausing during drag to detect over to nest vs push\n if (this.opts.subGridDynamic && !DDManager.pauseDrag)\n DDManager.pauseDrag = true;\n if (this.opts.draggable?.pause !== undefined)\n DDManager.pauseDrag = this.opts.draggable.pause;\n this._setupRemoveDrop();\n this._setupAcceptWidget();\n this._updateWindowResizeEvent();\n }\n /**\n * add a new widget and returns it.\n *\n * Widget will be always placed even if result height is more than actual grid height.\n * You need to use `willItFit()` before calling addWidget for additional check.\n * See also `makeWidget()`.\n *\n * @example\n * let grid = GridStack.init();\n * grid.addWidget({w: 3, content: 'hello'});\n * grid.addWidget('<div class=\"grid-stack-item\"><div class=\"grid-stack-item-content\">hello</div></div>', {w: 3});\n *\n * @param el GridStackWidget (which can have content string as well), html element, or string definition to add\n * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget\n */\n addWidget(els, options) {\n function isGridStackWidget(w) {\n return w.el !== undefined || w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false;\n }\n let el;\n let node;\n if (typeof els === 'string') {\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\n doc.body.innerHTML = els;\n el = doc.body.children[0];\n }\n else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) {\n node = options = els;\n if (node?.el) {\n el = node.el; // re-use element stored in the node\n }\n else if (GridStack.addRemoveCB) {\n el = GridStack.addRemoveCB(this.el, options, true, false);\n }\n else {\n let content = options?.content || '';\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\n doc.body.innerHTML = `<div class=\"grid-stack-item ${this.opts.itemClass || ''}\"><div class=\"grid-stack-item-content\">${content}</div></div>`;\n el = doc.body.children[0];\n }\n }\n else {\n el = els;\n }\n if (!el)\n return;\n // if the caller ended up initializing the widget in addRemoveCB, or we stared with one already, skip the rest\n node = el.gridstackNode;\n if (node && el.parentElement === this.el && this.engine.nodes.find(n => n._id === node._id))\n return el;\n // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos\n // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz') before adding the node.\n // So make sure we load any DOM attributes that are not specified in passed in options (which override)\n let domAttr = this._readAttr(el);\n options = Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it\n Utils.defaults(options, domAttr);\n node = this.engine.prepareNode(options);\n this._writeAttr(el, options);\n if (this._insertNotAppend) {\n this.el.prepend(el);\n }\n else {\n this.el.appendChild(el);\n }\n this.makeWidget(el, options);\n return el;\n }\n /**\n * Convert an existing gridItem element into a sub-grid with the given (optional) options, else inherit them\n * from the parent's subGrid options.\n * @param el gridItem element to convert\n * @param ops (optional) sub-grid options, else default to node, then parent settings, else defaults\n * @param nodeToAdd (optional) node to add to the newly created sub grid (used when dragging over existing regular item)\n * @returns newly created grid\n */\n makeSubGrid(el, ops, nodeToAdd, saveContent = true) {\n let node = el.gridstackNode;\n if (!node) {\n node = this.makeWidget(el).gridstackNode;\n }\n if (node.subGrid?.el)\n return node.subGrid; // already done\n // find the template subGrid stored on a parent as fallback...\n let subGridTemplate; // eslint-disable-next-line @typescript-eslint/no-this-alias\n let grid = this;\n while (grid && !subGridTemplate) {\n subGridTemplate = grid.opts?.subGridOpts;\n grid = grid.parentGridItem?.grid;\n }\n //... and set the create options\n ops = Utils.cloneDeep({ ...(subGridTemplate || {}), children: undefined, ...(ops || node.subGridOpts) });\n node.subGridOpts = ops;\n // if column special case it set, remember that flag and set default\n let autoColumn;\n if (ops.column === 'auto') {\n autoColumn = true;\n ops.column = Math.max(node.w || 1, nodeToAdd?.w || 1);\n ops.disableOneColumnMode = true; // driven by parent\n }\n // if we're converting an existing full item, move over the content to be the first sub item in the new grid\n let content = node.el.querySelector('.grid-stack-item-content');\n let newItem;\n let newItemOpt;\n if (saveContent) {\n this._removeDD(node.el); // remove D&D since it's set on content div\n newItemOpt = { ...node, x: 0, y: 0 };\n Utils.removeInternalForSave(newItemOpt);\n delete newItemOpt.subGridOpts;\n if (node.content) {\n newItemOpt.content = node.content;\n delete node.content;\n }\n if (GridStack.addRemoveCB) {\n newItem = GridStack.addRemoveCB(this.el, newItemOpt, true, false);\n }\n else {\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\n doc.body.innerHTML = `<div class=\"grid-stack-item\"></div>`;\n newItem = doc.body.children[0];\n newItem.appendChild(content);\n doc.body.innerHTML = `<div class=\"grid-stack-item-content\"></div>`;\n content = doc.body.children[0];\n node.el.appendChild(content);\n }\n this._prepareDragDropByNode(node); // ... and restore original D&D\n }\n // if we're adding an additional item, make the container large enough to have them both\n if (nodeToAdd) {\n let w = autoColumn ? ops.column : node.w;\n let h = node.h + nodeToAdd.h;\n let style = node.el.style;\n style.transition = 'none'; // show up instantly so we don't see scrollbar with nodeToAdd\n this.update(node.el, { w, h });\n setTimeout(() => style.transition = null); // recover animation\n }\n let subGrid = node.subGrid = GridStack.addGrid(content, ops);\n if (nodeToAdd?._moving)\n subGrid._isTemp = true; // prevent re-nesting as we add over\n if (autoColumn)\n subGrid._autoColumn = true;\n // add the original content back as a child of hte newly created grid\n if (saveContent) {\n subGrid.addWidget(newItem, newItemOpt);\n }\n // now add any additional node\n if (nodeToAdd) {\n if (nodeToAdd._moving) {\n // create an artificial event even for the just created grid to receive this item\n window.setTimeout(() => Utils.simulateMouseEvent(nodeToAdd._event, 'mouseenter', subGrid.el), 0);\n }\n else {\n subGrid.addWidget(node.el, node);\n }\n }\n return subGrid;\n }\n /**\n * called when an item was converted into a nested grid to accommodate a dragged over item, but then item leaves - return back\n * to the original grid-item. Also called to remove empty sub-grids when last item is dragged out (since re-creating is simple)\n */\n removeAsSubGrid(nodeThatRemoved) {\n let pGrid = this.parentGridItem?.grid;\n if (!pGrid)\n return;\n pGrid.batchUpdate();\n pGrid.removeWidget(this.parentGridItem.el, true, true);\n this.engine.nodes.forEach(n => {\n // migrate any children over and offsetting by our location\n n.x += this.parentGridItem.x;\n n.y += this.parentGridItem.y;\n pGrid.addWidget(n.el, n);\n });\n pGrid.batchUpdate(false);\n if (this.parentGridItem)\n delete this.parentGridItem.subGrid;\n delete this.parentGridItem;\n // create an artificial event for the original grid now that this one is gone (got a leave, but won't get enter)\n if (nodeThatRemoved) {\n window.setTimeout(() => Utils.simulateMouseEvent(nodeThatRemoved._event, 'mouseenter', pGrid.el), 0);\n }\n }\n /**\n * saves the current layout returning a list of widgets for serialization which might include any nested grids.\n * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will\n * be removed.\n * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid()\n * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.\n * @param saveCB callback for each node -> widget, so application can insert additional data to be saved into the widget data structure.\n * @returns list of widgets or full grid option, including .children list of widgets\n */\n save(saveContent = true, saveGridOpt = false, saveCB = GridStack.saveCB) {\n // return copied GridStackWidget (with optionally .el) we can modify at will...\n let list = this.engine.save(saveContent, saveCB);\n // check for HTML content and nested grids\n list.forEach(n => {\n if (saveContent && n.el && !n.subGrid && !saveCB) { // sub-grid are saved differently, not plain content\n let sub = n.el.querySelector('.grid-stack-item-content');\n n.content = sub ? sub.innerHTML : undefined;\n if (!n.content)\n delete n.content;\n }\n else {\n if (!saveContent && !saveCB) {\n delete n.content;\n }\n // check for nested grid\n if (n.subGrid?.el) {\n const listOrOpt = n.subGrid.save(saveContent, saveGridOpt, saveCB);\n n.subGridOpts = (saveGridOpt ? listOrOpt : { children: listOrOpt });\n delete n.subGrid;\n }\n }\n delete n.el;\n });\n // check if save entire grid options (needed for recursive) + children...\n if (saveGridOpt) {\n let o = Utils.cloneDeep(this.opts);\n // delete default values that will be recreated on launch\n if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) {\n o.margin = o.marginTop;\n delete o.marginTop;\n delete o.marginRight;\n delete o.marginBottom;\n delete o.marginLeft;\n }\n if (o.rtl === (this.el.style.direction === 'rtl')) {\n o.rtl = 'auto';\n }\n if (this._isAutoCellHeight) {\n o.cellHeight = 'auto';\n }\n if (this._autoColumn) {\n o.column = 'auto';\n delete o.disableOneColumnMode;\n }\n const origShow = o._alwaysShowResizeHandle;\n delete o._alwaysShowResizeHandle;\n if (origShow !== undefined) {\n o.alwaysShowResizeHandle = origShow;\n }\n else {\n delete o.alwaysShowResizeHandle;\n }\n Utils.removeInternalAndSame(o, gridDefaults);\n o.children = list;\n return o;\n }\n return list;\n }\n /**\n * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.\n *\n * @param layout list of widgets definition to update/create\n * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving\n * the user control of insertion.\n *\n * @example\n * see http://gridstackjs.com/demo/serialization.html\n **/\n load(layout, addRemove = GridStack.addRemoveCB || true) {\n let items = GridStack.Utils.sort([...layout], -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort\n this._insertNotAppend = true; // since create in reverse order...\n // if we're loading a layout into for example 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save\n // the original wanted layout so we can scale back up correctly #1471\n if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(n => (n.x + n.w) > this.opts.column)) {\n this._ignoreLayoutsNodeChange = true; // skip layout update\n this.engine.cacheLayout(items, this._prevColumn, true);\n }\n // if given a different callback, temporally set it as global option so creating will use it\n const prevCB = GridStack.addRemoveCB;\n if (typeof (addRemove) === 'function')\n GridStack.addRemoveCB = addRemove;\n let removed = [];\n this.batchUpdate();\n // see if any items are missing from new layout and need to be removed first\n if (addRemove) {\n let copyNodes = [...this.engine.nodes]; // don't loop through array you modify\n copyNodes.forEach(n => {\n let item = items.find(w => n.id === w.id);\n if (!item) {\n if (GridStack.addRemoveCB)\n GridStack.addRemoveCB(this.el, n, false, false);\n removed.push(n); // batch keep track\n this.removeWidget(n.el, true, false);\n }\n });\n }\n // now add/update the widgets\n items.forEach(w => {\n let item = (w.id !== undefined) ? this.engine.nodes.find(n => n.id === w.id) : undefined;\n if (item) {\n this.update(item.el, w);\n if (w.subGridOpts?.children) { // update any sub grid as well\n let sub = item.el.querySelector('.grid-stack');\n if (sub && sub.gridstack) {\n sub.gridstack.load(w.subGridOpts.children); // TODO: support updating grid options ?\n this._insertNotAppend = true; // got reset by above call\n }\n }\n }\n else if (addRemove) {\n this.addWidget(w);\n }\n });\n this.engine.removedNodes = removed;\n this.batchUpdate(false);\n // after commit, clear that flag\n delete this._ignoreLayoutsNodeChange;\n delete this._insertNotAppend;\n prevCB ? GridStack.addRemoveCB = prevCB : delete GridStack.addRemoveCB;\n return this;\n }\n /**\n * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient)\n * and get a single event callback. You will see no changes until `batchUpdate(false)` is called.\n */\n batchUpdate(flag = true) {\n this.engine.batchUpdate(flag);\n if (!flag) {\n this._triggerRemoveEvent();\n this._triggerAddEvent();\n this._triggerChangeEvent();\n }\n return this;\n }\n /**\n * Gets current cell height.\n */\n getCellHeight(forcePixel = false) {\n if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' &&\n (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) {\n return this.opts.cellHeight;\n }\n // else get first cell height\n let el = this.el.querySelector('.' + this.opts.itemClass);\n if (el) {\n let height = Utils.toNumber(el.getAttribute('gs-h')) || 1; // since we don't write 1 anymore\n return Math.round(el.offsetHeight / height);\n }\n // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain)\n let rows = parseInt(this.el.getAttribute('gs-current-row'));\n return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight;\n }\n /**\n * Update current cell height - see `GridStackOptions.cellHeight` for format.\n * This method rebuilds an internal CSS style sheet.\n * Note: You can expect performance issues if call this method too often.\n *\n * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin),\n * if pass 0 the CSS will be generated by the application instead.\n * @param update (Optional) if false, styles will not be updated\n *\n * @example\n * grid.cellHeight(100); // same as 100px\n * grid.cellHeight('70px');\n * grid.cellHeight(grid.cellWidth() * 1.2);\n */\n cellHeight(val, update = true) {\n // if not called internally, check if we're changing mode\n if (update && val !== undefined) {\n if (this._isAutoCellHeight !== (val === 'auto')) {\n this._isAutoCellHeight = (val === 'auto');\n this._updateWindowResizeEvent();\n }\n }\n if (val === 'initial' || val === 'auto') {\n val = undefined;\n }\n // make item content be square\n if (val === undefined) {\n let marginDiff = -this.opts.marginRight - this.opts.marginLeft\n + this.opts.marginTop + this.opts.marginBottom;\n val = this.cellWidth() + marginDiff;\n }\n let data = Utils.parseHeight(val);\n if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) {\n return this;\n }\n this.opts.cellHeightUnit = data.unit;\n this.opts.cellHeight = data.h;\n if (update) {\n this._updateStyles(true); // true = force re-create for current # of rows\n }\n return this;\n }\n /** Gets current cell width. */\n cellWidth() {\n return this._widthOrContainer() / this.getColumn();\n }\n /** return our expected width (or parent) for 1 column check */\n _widthOrContainer() {\n // use `offsetWidth` or `clientWidth` (no scrollbar) ?\n // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\n return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);\n }\n /** re-layout grid items to reclaim any empty space */\n compact() {\n this.engine.compact();\n this._triggerChangeEvent();\n return this;\n }\n /**\n * set the number of columns in the grid. Will update existing widgets to conform to new number of columns,\n * as well as cache the original layout so you can revert back to previous positions without loss.\n * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],\n * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)\n * @param column - Integer > 0 (default 12).\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\n */\n column(column, layout = 'moveScale') {\n if (column < 1 || this.opts.column === column)\n return this;\n let oldColumn = this.getColumn();\n // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on)\n // then remember the original columns so we can restore.\n if (column === 1) {\n this._prevColumn = oldColumn;\n }\n else {\n delete this._prevColumn;\n }\n this.el.classList.remove('gs-' + oldColumn);\n this.el.classList.add('gs-' + column);\n this.opts.column = this.engine.column = column;\n // update the items now - see if the dom order nodes should be passed instead (else default to current list)\n let domNodes;\n if (column === 1 && this.opts.oneColumnModeDomSort) {\n domNodes = [];\n this.getGridItems().forEach(el => {\n if (el.gridstackNode) {\n domNodes.push(el.gridstackNode);\n }\n });\n if (!domNodes.length) {\n domNodes = undefined;\n }\n }\n this.engine.updateNodeWidths(oldColumn, column, domNodes, layout);\n if (this._isAutoCellHeight)\n this.cellHeight();\n // and trigger our event last...\n this._ignoreLayoutsNodeChange = true; // skip layout update\n this._triggerChangeEvent();\n delete this._ignoreLayoutsNodeChange;\n return this;\n }\n /**\n * get the number of columns in the grid (default 12)\n */\n getColumn() {\n return this.opts.column;\n }\n /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */\n getGridItems() {\n return Array.from(this.el.children)\n .filter((el) => el.matches('.' + this.opts.itemClass) && !el.matches('.' + this.opts.placeholderClass));\n }\n /**\n * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members.\n * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`).\n */\n destroy(removeDOM = true) {\n if (!this.el)\n return; // prevent multiple calls\n this.offAll();\n this._updateWindowResizeEvent(true);\n this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away)\n this.setAnimation(false);\n if (!removeDOM) {\n this.removeAll(removeDOM);\n this.el.classList.remove(this._styleSheetClass);\n this.el.removeAttribute('gs-current-row');\n }\n else {\n this.el.parentNode.removeChild(this.el);\n }\n this._removeStylesheet();\n if (this.parentGridItem)\n delete this.parentGridItem.subGrid;\n delete this.parentGridItem;\n delete this.opts;\n delete this._placeholder;\n delete this.engine;\n delete this.el.gridstack; // remove circular dependency that would prevent a freeing\n delete this.el;\n return this;\n }\n /**\n * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html)\n */\n float(val) {\n if (this.opts.float !== val) {\n this.opts.float = this.engine.float = val;\n this._triggerChangeEvent();\n }\n return this;\n }\n /**\n * get the current float mode\n */\n getFloat() {\n return this.engine.float;\n }\n /**\n * Get the position of the cell under a pixel on screen.\n * @param position the position of the pixel to resolve in\n * absolute coordinates, as an object with top and left properties\n * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false).\n * Useful when grid is within `position: relative` element\n *\n * Returns an object with properties `x` and `y` i.e. the column and row in the grid.\n */\n getCellFromPixel(position, useDocRelative = false) {\n let box = this.el.getBoundingClientRect();\n // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`)\n let containerPos;\n if (useDocRelative) {\n containerPos = { top: box.top + document.documentElement.scrollTop, left: box.left };\n // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`)\n }\n else {\n containerPos = { top: this.el.offsetTop, left: this.el.offsetLeft };\n // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`)\n }\n let relativeLeft = position.left - containerPos.left;\n let relativeTop = position.top - containerPos.top;\n let columnWidth = (box.width / this.getColumn());\n let rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row')));\n return { x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight) };\n }\n /** returns the current number of rows, which will be at least `minRow` if set */\n getRow() {\n return Math.max(this.engine.getRow(), this.opts.minRow);\n }\n /**\n * Checks if specified area is empty.\n * @param x the position x.\n * @param y the position y.\n * @param w the width of to check\n * @param h the height of to check\n */\n isAreaEmpty(x, y, w, h) {\n return this.engine.isAreaEmpty(x, y, w, h);\n }\n /**\n * If you add elements to your grid by hand (or have some framework creating DOM), you have to tell gridstack afterwards to make them widgets.\n * If you want gridstack to add the elements for you, use `addWidget()` instead.\n * Makes the given element a widget and returns it.\n * @param els widget or single selector to convert.\n * @param options widget definition to use instead of reading attributes or using default sizing values\n *\n * @example\n * let grid = GridStack.init();\n * grid.el.appendChild('<div id=\"1\" gs-w=\"3\"></div>');\n * grid.el.appendChild('<div id=\"2\"></div>');\n * grid.makeWidget('1');\n * grid.makeWidget('2', {w:2, content: 'hello'});\n */\n makeWidget(els, options) {\n let el = GridStack.getElement(els);\n this._prepareElement(el, true, options);\n this._updateContainerHeight();\n // see if there is a sub-grid to create\n const node = el.gridstackNode;\n if (node.subGridOpts) {\n this.makeSubGrid(el, node.subGridOpts, undefined, false); // node.subGrid will be used as option in method, no need to pass\n }\n // if we're adding an item into 1 column (_prevColumn is set only when going to 1) make sure\n // we don't override the larger 12 column layout that was already saved. #1985\n if (this._prevColumn && this.opts.column === 1) {\n this._ignoreLayoutsNodeChange = true;\n }\n this._triggerAddEvent();\n this._triggerChangeEvent();\n delete this._ignoreLayoutsNodeChange;\n return el;\n }\n /**\n * Event handler that extracts our CustomEvent data out automatically for receiving custom\n * notifications (see doc for supported events)\n * @param name of the event (see possible values) or list of names space separated\n * @param callback function called with event and optional second/third param\n * (see README documentation for each signature).\n *\n * @example\n * grid.on('added', function(e, items) { log('added ', items)} );\n * or\n * grid.on('added removed change', function(e, items) { log(e.type, items)} );\n *\n * Note: in some cases it is the same as calling native handler and parsing the event.\n * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} );\n *\n */\n on(name, callback) {\n // check for array of names being passed instead\n if (name.indexOf(' ') !== -1) {\n let names = name.split(' ');\n names.forEach(name => this.on(name, callback));\n return this;\n }\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\n // native CustomEvent handlers - cash the generic handlers so we can easily remove\n let noData = (name === 'enable' || name === 'disable');\n if (noData) {\n this._gsEventHandler[name] = (event) => callback(event);\n }\n else {\n this._gsEventHandler[name] = (event) => callback(event, event.detail);\n }\n this.el.addEventListener(name, this._gsEventHandler[name]);\n }\n else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') {\n // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself.\n // do same for start event to make it easier...\n this._gsEventHandler[name] = callback;\n }\n else {\n console.log('GridStack.on(' + name + ') event not supported, but you can still use $(\".grid-stack\").on(...) while jquery-ui is still used internally.');\n }\n return this;\n }\n /**\n * unsubscribe from the 'on' event below\n * @param name of the event (see possible values)\n */\n off(name) {\n // check for array of names being passed instead\n if (name.indexOf(' ') !== -1) {\n let names = name.split(' ');\n names.forEach(name => this.off(name));\n return this;\n }\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\n // remove native CustomEvent handlers\n if (this._gsEventHandler[name]) {\n this.el.removeEventListener(name, this._gsEventHandler[name]);\n }\n }\n delete this._gsEventHandler[name];\n return this;\n }\n /** remove all event handlers */\n offAll() {\n Object.keys(this._gsEventHandler).forEach(key => this.off(key));\n return this;\n }\n /**\n * Removes widget from the grid.\n * @param el widget or selector to modify\n * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true).\n * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).\n */\n removeWidget(els, removeDOM = true, triggerEvent = true) {\n GridStack.getElements(els).forEach(el => {\n if (el.parentElement && el.parentElement !== this.el)\n return; // not our child!\n let node = el.gridstackNode;\n // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272\n if (!node) {\n node = this.engine.nodes.find(n => el === n.el);\n }\n if (!node)\n return;\n if (GridStack.addRemoveCB) {\n GridStack.addRemoveCB(this.el, node, false, false);\n }\n // remove our DOM data (circular link) and drag&drop permanently\n delete el.gridstackNode;\n this._removeDD(el);\n this.engine.removeNode(node, removeDOM, triggerEvent);\n if (removeDOM && el.parentElement) {\n el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM\n }\n });\n if (triggerEvent) {\n this._triggerRemoveEvent();\n this._triggerChangeEvent();\n }\n return this;\n }\n /**\n * Removes all widgets from the grid.\n * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`).\n */\n removeAll(removeDOM = true) {\n // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently\n this.engine.nodes.forEach(n => {\n delete n.el.gridstackNode;\n this._removeDD(n.el);\n });\n this.engine.removeAll(removeDOM);\n this._triggerRemoveEvent();\n return this;\n }\n /**\n * Toggle the grid animation state. Toggles the `grid-stack-animate` class.\n * @param doAnimate if true the grid will animate.\n */\n setAnimation(doAnimate) {\n if (doAnimate) {\n this.el.classList.add('grid-stack-animate');\n }\n else {\n this.el.classList.remove('grid-stack-animate');\n }\n return this;\n }\n /**\n * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.\n * Also toggle the grid-stack-static class.\n * @param val if true the grid become static.\n * @param updateClass true (default) if css class gets updated\n * @param recurse true (default) if sub-grids also get updated\n */\n setStatic(val, updateClass = true, recurse = true) {\n if (!!this.opts.staticGrid === val)\n return this;\n val ? this.opts.staticGrid = true : delete this.opts.staticGrid;\n this._setupRemoveDrop();\n this._setupAcceptWidget();\n this.engine.nodes.forEach(n => {\n this._prepareDragDropByNode(n); // either delete or init Drag&drop\n if (n.subGrid && recurse)\n n.subGrid.setStatic(val, updateClass, recurse);\n });\n if (updateClass) {\n this._setStaticClass();\n }\n return this;\n }\n /**\n * Updates widget position/size and other info. Note: if you need to call this on all nodes, use load() instead which will update what changed.\n * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted)\n * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated.\n */\n update(els, opt) {\n // support legacy call for now ?\n if (arguments.length > 2) {\n console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon');\n // eslint-disable-next-line prefer-rest-params\n let a = arguments, i = 1;\n opt = { x: a[i++], y: a[i++], w: a[i++], h: a[i++] };\n return this.update(els, opt);\n }\n GridStack.getElements(els).forEach(el => {\n if (!el || !el.gridstackNode)\n return;\n let n = el.gridstackNode;\n let w = Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items\n delete w.autoPosition;\n // move/resize widget if anything changed\n let keys = ['x', 'y', 'w', 'h'];\n let m;\n if (keys.some(k => w[k] !== undefined && w[k] !== n[k])) {\n m = {};\n keys.forEach(k => {\n m[k] = (w[k] !== undefined) ? w[k] : n[k];\n delete w[k];\n });\n }\n // for a move as well IFF there is any min/max fields set\n if (!m && (w.minW || w.minH || w.maxW || w.maxH)) {\n m = {}; // will use node position but validate values\n }\n // check for content changing\n if (w.content) {\n let sub = el.querySelector('.grid-stack-item-content');\n if (sub && sub.innerHTML !== w.content) {\n sub.innerHTML = w.content;\n }\n delete w.content;\n }\n // any remaining fields are assigned, but check for dragging changes, resize constrain\n let changed = false;\n let ddChanged = false;\n for (const key in w) {\n if (key[0] !== '_' && n[key] !== w[key]) {\n n[key] = w[key];\n changed = true;\n ddChanged = ddChanged || (!this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked'));\n }\n }\n Utils.sanitizeMinMax(n);\n // finally move the widget\n if (m) {\n this.engine.cleanNodes()\n .beginUpdate(n)\n .moveNode(n, m);\n this._updateContainerHeight();\n this._triggerChangeEvent();\n this.engine.endUpdate();\n }\n if (changed) { // move will only update x,y,w,h so update the rest too\n this._writeAttr(el, n);\n }\n if (ddChanged) {\n this._prepareDragDropByNode(n);\n }\n });\n return this;\n }\n /**\n * Updates the margins which will set all 4 sides at once - see `GridStackOptions.margin` for format options (CSS string format of 1,2,4 values or single number).\n * @param value margin value\n */\n margin(value) {\n let isMultiValue = (typeof value === 'string' && value.split(' ').length > 1);\n // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle)\n if (!isMultiValue) {\n let data = Utils.parseHeight(value);\n if (this.opts.marginUnit === data.unit && this.opts.margin === data.h)\n return;\n }\n // re-use existing margin handling\n this.opts.margin = value;\n this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined;\n this._initMargin();\n this._updateStyles(true); // true = force re-create\n return this;\n }\n /** returns current margin number value (undefined if 4 sides don't match) */\n getMargin() { return this.opts.margin; }\n /**\n * Returns true if the height of the grid will be less than the vertical\n * constraint. Always returns true if grid doesn't have height constraint.\n * @param node contains x,y,w,h,auto-position options\n *\n * @example\n * if (grid.willItFit(newWidget)) {\n * grid.addWidget(newWidget);\n * } else {\n * alert('Not enough free space to place the widget');\n * }\n */\n willItFit(node) {\n // support legacy call for now\n if (arguments.length > 1) {\n console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon');\n // eslint-disable-next-line prefer-rest-params\n let a = arguments, i = 0, w = { x: a[i++], y: a[i++], w: a[i++], h: a[i++], autoPosition: a[i++] };\n return this.willItFit(w);\n }\n return this.engine.willItFit(node);\n }\n /** @internal */\n _triggerChangeEvent() {\n if (this.engine.batchMode)\n return this;\n let elements = this.engine.getDirtyNodes(true); // verify they really changed\n if (elements && elements.length) {\n if (!this._ignoreLayoutsNodeChange) {\n this.engine.layoutsNodesChange(elements);\n }\n this._triggerEvent('change', elements);\n }\n this.engine.saveInitial(); // we called, now reset initial values & dirty flags\n return this;\n }\n /** @internal */\n _triggerAddEvent() {\n if (this.engine.batchMode)\n return this;\n if (this.engine.addedNodes?.length) {\n if (!this._ignoreLayoutsNodeChange) {\n this.engine.layoutsNodesChange(this.engine.addedNodes);\n }\n // prevent added nodes from also triggering 'change' event (which is called next)\n this.engine.addedNodes.forEach(n => { delete n._dirty; });\n this._triggerEvent('added', this.engine.addedNodes);\n this.engine.addedNodes = [];\n }\n return this;\n }\n /** @internal */\n _triggerRemoveEvent() {\n if (this.engine.batchMode)\n return this;\n if (this.engine.removedNodes?.length) {\n this._triggerEvent('removed', this.engine.removedNodes);\n this.engine.removedNodes = [];\n }\n return this;\n }\n /** @internal */\n _triggerEvent(type, data) {\n let event = data ? new CustomEvent(type, { bubbles: false, detail: data }) : new Event(type);\n this.el.dispatchEvent(event);\n return this;\n }\n /** @internal called to delete the current dynamic style sheet used for our layout */\n _removeStylesheet() {\n if (this._styles) {\n Utils.removeStylesheet(this._styleSheetClass);\n delete this._styles;\n }\n return this;\n }\n /** @internal updated/create the CSS styles for row based layout and initial margin setting */\n _updateStyles(forceUpdate = false, maxH) {\n // call to delete existing one if we change cellHeight / margin\n if (forceUpdate) {\n this._removeStylesheet();\n }\n if (!maxH)\n maxH = this.getRow();\n this._updateContainerHeight();\n // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??\n if (this.opts.cellHeight === 0) {\n return this;\n }\n let cellHeight = this.opts.cellHeight;\n let cellHeightUnit = this.opts.cellHeightUnit;\n let prefix = `.${this._styleSheetClass} > .${this.opts.itemClass}`;\n // create one as needed\n if (!this._styles) {\n // insert style to parent (instead of 'head' by default) to support WebComponent\n let styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode;\n this._styles = Utils.createStylesheet(this._styleSheetClass, styleLocation, {\n nonce: this.opts.nonce,\n });\n if (!this._styles)\n return this;\n this._styles._max = 0;\n // these are done once only\n Utils.addCSSRule(this._styles, prefix, `height: ${cellHeight}${cellHeightUnit}`);\n // content margins\n let top = this.opts.marginTop + this.opts.marginUnit;\n let bottom = this.opts.marginBottom + this.opts.marginUnit;\n let right = this.opts.marginRight + this.opts.marginUnit;\n let left = this.opts.marginLeft + this.opts.marginUnit;\n let content = `${prefix} > .grid-stack-item-content`;\n let placeholder = `.${this._styleSheetClass} > .grid-stack-placeholder > .placeholder-content`;\n Utils.addCSSRule(this._styles, content, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\n Utils.addCSSRule(this._styles, placeholder, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\n // resize handles offset (to match margin)\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-ne`, `right: ${right}`);\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-e`, `right: ${right}`);\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-se`, `right: ${right}; bottom: ${bottom}`);\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-nw`, `left: ${left}`);\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-w`, `left: ${left}`);\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-sw`, `left: ${left}; bottom: ${bottom}`);\n }\n // now update the height specific fields\n maxH = maxH || this._styles._max;\n if (maxH > this._styles._max) {\n let getHeight = (rows) => (cellHeight * rows) + cellHeightUnit;\n for (let i = this._styles._max + 1; i <= maxH; i++) { // start at 1\n Utils.addCSSRule(this._styles, `${prefix}[gs-y=\"${i}\"]`, `top: ${getHeight(i)}`);\n Utils.addCSSRule(this._styles, `${prefix}[gs-h=\"${i + 1}\"]`, `height: ${getHeight(i + 1)}`); // start at 2\n }\n this._styles._max = maxH;\n }\n return this;\n }\n /** @internal */\n _updateContainerHeight() {\n if (!this.engine || this.engine.batchMode)\n return this;\n let row = this.getRow() + this._extraDragRow; // checks for minRow already\n // check for css min height\n // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary\n // rows as the CSS will make us bigger than our set height if needed... not sure why we had this.\n // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']);\n // if (cssMinHeight > 0) {\n // let minRow = Math.round(cssMinHeight / this.getCellHeight(true));\n // if (row < minRow) {\n // row = minRow;\n // }\n // }\n this.el.setAttribute('gs-current-row', String(row));\n if (row === 0) {\n this.el.style.removeProperty('min-height');\n return this;\n }\n let cellHeight = this.opts.cellHeight;\n let unit = this.opts.cellHeightUnit;\n if (!cellHeight)\n return this;\n this.el.style.minHeight = row * cellHeight + unit;\n return this;\n }\n /** @internal */\n _prepareElement(el, triggerAddEvent = false, node) {\n el.classList.add(this.opts.itemClass);\n node = node || this._readAttr(el);\n el.gridstackNode = node;\n node.el = el;\n node.grid = this;\n let copy = { ...node };\n node = this.engine.addNode(node, triggerAddEvent);\n // write node attr back in case there was collision or we have to fix bad values during addNode()\n if (!Utils.same(node, copy)) {\n this._writeAttr(el, node);\n }\n this._prepareDragDropByNode(node);\n return this;\n }\n /** @internal call to write position x,y,w,h attributes back to element */\n _writePosAttr(el, n) {\n if (n.x !== undefined && n.x !== null) {\n el.setAttribute('gs-x', String(n.x));\n }\n if (n.y !== undefined && n.y !== null) {\n el.setAttribute('gs-y', String(n.y));\n }\n n.w > 1 ? el.setAttribute('gs-w', String(n.w)) : el.removeAttribute('gs-w');\n n.h > 1 ? el.setAttribute('gs-h', String(n.h)) : el.removeAttribute('gs-h');\n return this;\n }\n /** @internal call to write any default attributes back to element */\n _writeAttr(el, node) {\n if (!node)\n return this;\n this._writePosAttr(el, node);\n let attrs /*: GridStackWidget but strings */ = {\n autoPosition: 'gs-auto-position',\n noResize: 'gs-no-resize',\n noMove: 'gs-no-move',\n locked: 'gs-locked',\n id: 'gs-id',\n };\n for (const key in attrs) {\n if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway\n el.setAttribute(attrs[key], String(node[key]));\n }\n else {\n el.removeAttribute(attrs[key]);\n }\n }\n return this;\n }\n /** @internal call to read any default attributes from element */\n _readAttr(el, clearDefaultAttr = true) {\n let n = {};\n n.x = Utils.toNumber(el.getAttribute('gs-x'));\n n.y = Utils.toNumber(el.getAttribute('gs-y'));\n n.w = Utils.toNumber(el.getAttribute('gs-w'));\n n.h = Utils.toNumber(el.getAttribute('gs-h'));\n n.autoPosition = Utils.toBool(el.getAttribute('gs-auto-position'));\n n.noResize = Utils.toBool(el.getAttribute('gs-no-resize'));\n n.noMove = Utils.toBool(el.getAttribute('gs-no-move'));\n n.locked = Utils.toBool(el.getAttribute('gs-locked'));\n n.id = el.getAttribute('gs-id');\n // read but never written out\n n.maxW = Utils.toNumber(el.getAttribute('gs-max-w'));\n n.minW = Utils.toNumber(el.getAttribute('gs-min-w'));\n n.maxH = Utils.toNumber(el.getAttribute('gs-max-h'));\n n.minH = Utils.toNumber(el.getAttribute('gs-min-h'));\n // v8.x optimization to reduce un-needed attr that don't render or are default CSS\n if (clearDefaultAttr) {\n if (n.w === 1)\n el.removeAttribute('gs-w');\n if (n.h === 1)\n el.removeAttribute('gs-h');\n if (n.maxW)\n el.removeAttribute('gs-max-w');\n if (n.minW)\n el.removeAttribute('gs-min-w');\n if (n.maxH)\n el.removeAttribute('gs-max-h');\n if (n.minH)\n el.removeAttribute('gs-min-h');\n }\n // remove any key not found (null or false which is default)\n for (const key in n) {\n if (!n.hasOwnProperty(key))\n return;\n if (!n[key] && n[key] !== 0) { // 0 can be valid value (x,y only really)\n delete n[key];\n }\n }\n return n;\n }\n /** @internal */\n _setStaticClass() {\n let classes = ['grid-stack-static'];\n if (this.opts.staticGrid) {\n this.el.classList.add(...classes);\n this.el.setAttribute('gs-static', 'true');\n }\n else {\n this.el.classList.remove(...classes);\n this.el.removeAttribute('gs-static');\n }\n return this;\n }\n /**\n * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off\n * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square)\n */\n onParentResize() {\n if (!this.el || !this.el.clientWidth)\n return; // return if we're gone or no size yet (will get called again)\n let changedColumn = false;\n // see if we're nested and take our column count from our parent....\n if (this._autoColumn && this.parentGridItem) {\n if (this.opts.column !== this.parentGridItem.w) {\n changedColumn = true;\n this.column(this.parentGridItem.w, 'none');\n }\n }\n else {\n // else check for 1 column in/out behavior\n let oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize;\n if ((this.opts.column === 1) !== oneColumn) {\n changedColumn = true;\n if (this.opts.animate) {\n this.setAnimation(false);\n } // 1 <-> 12 is too radical, turn off animation\n this.column(oneColumn ? 1 : this._prevColumn);\n if (this.opts.animate) {\n this.setAnimation(true);\n }\n }\n }\n // make the cells content square again\n if (this._isAutoCellHeight) {\n if (!changedColumn && this.opts.cellHeightThrottle) {\n if (!this._cellHeightThrottle) {\n this._cellHeightThrottle = Utils.throttle(() => this.cellHeight(), this.opts.cellHeightThrottle);\n }\n this._cellHeightThrottle();\n }\n else {\n // immediate update if we've changed column count or have no threshold\n this.cellHeight();\n }\n }\n // finally update any nested grids\n this.engine.nodes.forEach(n => {\n if (n.subGrid)\n n.subGrid.onParentResize();\n });\n return this;\n }\n /** add or remove the window size event handler */\n _updateWindowResizeEvent(forceRemove = false) {\n // only add event if we're not nested (parent will call us) and we're auto sizing cells or supporting oneColumn (i.e. doing work)\n const workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.parentGridItem;\n if (!forceRemove && workTodo && !this._windowResizeBind) {\n this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later\n window.addEventListener('resize', this._windowResizeBind);\n }\n else if ((forceRemove || !workTodo) && this._windowResizeBind) {\n window.removeEventListener('resize', this._windowResizeBind);\n delete this._windowResizeBind; // remove link to us so we can free\n }\n return this;\n }\n /** @internal convert a potential selector into actual element */\n static getElement(els = '.grid-stack-item') { return Utils.getElement(els); }\n /** @internal */\n static getElements(els = '.grid-stack-item') { return Utils.getElements(els); }\n /** @internal */\n static getGridElement(els) { return GridStack.getElement(els); }\n /** @internal */\n static getGridElements(els) { return Utils.getElements(els); }\n /** @internal initialize margin top/bottom/left/right and units */\n _initMargin() {\n let data;\n let margin = 0;\n // support passing multiple values like CSS (ex: '5px 10px 0 20px')\n let margins = [];\n if (typeof this.opts.margin === 'string') {\n margins = this.opts.margin.split(' ');\n }\n if (margins.length === 2) { // top/bot, left/right like CSS\n this.opts.marginTop = this.opts.marginBottom = margins[0];\n this.opts.marginLeft = this.opts.marginRight = margins[1];\n }\n else if (margins.length === 4) { // Clockwise like CSS\n this.opts.marginTop = margins[0];\n this.opts.marginRight = margins[1];\n this.opts.marginBottom = margins[2];\n this.opts.marginLeft = margins[3];\n }\n else {\n data = Utils.parseHeight(this.opts.margin);\n this.opts.marginUnit = data.unit;\n margin = this.opts.margin = data.h;\n }\n // see if top/bottom/left/right need to be set as well\n if (this.opts.marginTop === undefined) {\n this.opts.marginTop = margin;\n }\n else {\n data = Utils.parseHeight(this.opts.marginTop);\n this.opts.marginTop = data.h;\n delete this.opts.margin;\n }\n if (this.opts.marginBottom === undefined) {\n this.opts.marginBottom = margin;\n }\n else {\n data = Utils.parseHeight(this.opts.marginBottom);\n this.opts.marginBottom = data.h;\n delete this.opts.margin;\n }\n if (this.opts.marginRight === undefined) {\n this.opts.marginRight = margin;\n }\n else {\n data = Utils.parseHeight(this.opts.marginRight);\n this.opts.marginRight = data.h;\n delete this.opts.margin;\n }\n if (this.opts.marginLeft === undefined) {\n this.opts.marginLeft = margin;\n }\n else {\n data = Utils.parseHeight(this.opts.marginLeft);\n this.opts.marginLeft = data.h;\n delete this.opts.margin;\n }\n this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead...\n if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) {\n this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin()\n }\n return this;\n }\n /* ===========================================================================================\n * drag&drop methods that used to be stubbed out and implemented in dd-gridstack.ts\n * but caused loading issues in prod - see https://github.com/gridstack/gridstack.js/issues/2039\n * ===========================================================================================\n */\n /** get the global (but static to this code) DD implementation */\n static getDD() {\n return dd;\n }\n /**\n * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.\n * Called during GridStack.init() as options, but can also be called directly (last param are used) in case the toolbar\n * is dynamically create and needs to be set later.\n * @param dragIn string selector (ex: '.sidebar .grid-stack-item') or list of dom elements\n * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'}\n * @param root optional root which defaults to document (for shadow dom pas the parent HTMLDocument)\n **/\n static setupDragIn(dragIn, dragInOptions, root = document) {\n if (dragInOptions?.pause !== undefined) {\n DDManager.pauseDrag = dragInOptions.pause;\n }\n dragInOptions = { ...dragInDefaultOptions, ...(dragInOptions || {}) };\n let els = (typeof dragIn === 'string') ? Utils.getElements(dragIn, root) : dragIn;\n if (els.length)\n els?.forEach(el => {\n if (!dd.isDraggable(el))\n dd.dragIn(el, dragInOptions);\n });\n }\n /**\n * Enables/Disables dragging by the user of specific grid element. If you want all items, and have it affect future items, use enableMove() instead. No-op for static grids.\n * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead.\n * @param els widget or selector to modify.\n * @param val if true widget will be draggable, assuming the parent grid isn't noMove or static.\n */\n movable(els, val) {\n if (this.opts.staticGrid)\n return this; // can't move a static grid!\n GridStack.getElements(els).forEach(el => {\n let n = el.gridstackNode;\n if (!n)\n return;\n val ? delete n.noMove : n.noMove = true;\n this._prepareDragDropByNode(n); // init DD if need be, and adjust\n });\n return this;\n }\n /**\n * Enables/Disables user resizing of specific grid element. If you want all items, and have it affect future items, use enableResize() instead. No-op for static grids.\n * @param els widget or selector to modify\n * @param val if true widget will be resizable, assuming the parent grid isn't noResize or static.\n */\n resizable(els, val) {\n if (this.opts.staticGrid)\n return this; // can't resize a static grid!\n GridStack.getElements(els).forEach(el => {\n let n = el.gridstackNode;\n if (!n)\n return;\n val ? delete n.noResize : n.noResize = true;\n this._prepareDragDropByNode(n); // init DD if need be, and adjust\n });\n return this;\n }\n /**\n * Temporarily disables widgets moving/resizing.\n * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.\n * Note: no-op for static grid\n * This is a shortcut for:\n * @example\n * grid.enableMove(false);\n * grid.enableResize(false);\n * @param recurse true (default) if sub-grids also get updated\n */\n disable(recurse = true) {\n if (this.opts.staticGrid)\n return;\n this.enableMove(false, recurse);\n this.enableResize(false, recurse);\n this._triggerEvent('disable');\n return this;\n }\n /**\n * Re-enables widgets moving/resizing - see disable().\n * Note: no-op for static grid.\n * This is a shortcut for:\n * @example\n * grid.enableMove(true);\n * grid.enableResize(true);\n * @param recurse true (default) if sub-grids also get updated\n */\n enable(recurse = true) {\n if (this.opts.staticGrid)\n return;\n this.enableMove(true, recurse);\n this.enableResize(true, recurse);\n this._triggerEvent('enable');\n return this;\n }\n /**\n * Enables/disables widget moving. No-op for static grids, and locally defined items still overrule\n * @param recurse true (default) if sub-grids also get updated\n */\n enableMove(doEnable, recurse = true) {\n if (this.opts.staticGrid)\n return this; // can't move a static grid!\n doEnable ? delete this.opts.disableDrag : this.opts.disableDrag = true; // FIRST before we update children as grid overrides #1658\n this.engine.nodes.forEach(n => {\n this._prepareDragDropByNode(n);\n if (n.subGrid && recurse)\n n.subGrid.enableMove(doEnable, recurse);\n });\n return this;\n }\n /**\n * Enables/disables widget resizing. No-op for static grids.\n * @param recurse true (default) if sub-grids also get updated\n */\n enableResize(doEnable, recurse = true) {\n if (this.opts.staticGrid)\n return this; // can't size a static grid!\n doEnable ? delete this.opts.disableResize : this.opts.disableResize = true; // FIRST before we update children as grid overrides #1658\n this.engine.nodes.forEach(n => {\n this._prepareDragDropByNode(n);\n if (n.subGrid && recurse)\n n.subGrid.enableResize(doEnable, recurse);\n });\n return this;\n }\n /** @internal removes any drag&drop present (called during destroy) */\n _removeDD(el) {\n dd.draggable(el, 'destroy').resizable(el, 'destroy');\n if (el.gridstackNode) {\n delete el.gridstackNode._initDD; // reset our DD init flag\n }\n delete el.ddElement;\n return this;\n }\n /** @internal called to add drag over to support widgets being added externally */\n _setupAcceptWidget() {\n // check if we need to disable things\n if (this.opts.staticGrid || (!this.opts.acceptWidgets && !this.opts.removable)) {\n dd.droppable(this.el, 'destroy');\n return this;\n }\n // vars shared across all methods\n let cellHeight, cellWidth;\n let onDrag = (event, el, helper) => {\n let node = el.gridstackNode;\n if (!node)\n return;\n helper = helper || el;\n let parent = this.el.getBoundingClientRect();\n let { top, left } = helper.getBoundingClientRect();\n left -= parent.left;\n top -= parent.top;\n let ui = { position: { top, left } };\n if (node._temporaryRemoved) {\n node.x = Math.max(0, Math.round(left / cellWidth));\n node.y = Math.max(0, Math.round(top / cellHeight));\n delete node.autoPosition;\n this.engine.nodeBoundFix(node);\n // don't accept *initial* location if doesn't fit #1419 (locked drop region, or can't grow), but maybe try if it will go somewhere\n if (!this.engine.willItFit(node)) {\n node.autoPosition = true; // ignore x,y and try for any slot...\n if (!this.engine.willItFit(node)) {\n dd.off(el, 'drag'); // stop calling us\n return; // full grid or can't grow\n }\n if (node._willFitPos) {\n // use the auto position instead #1687\n Utils.copyPos(node, node._willFitPos);\n delete node._willFitPos;\n }\n }\n // re-use the existing node dragging method\n this._onStartMoving(helper, event, ui, node, cellWidth, cellHeight);\n }\n else {\n // re-use the existing node dragging that does so much of the collision detection\n this._dragOrResize(helper, event, ui, node, cellWidth, cellHeight);\n }\n };\n dd.droppable(this.el, {\n accept: (el) => {\n let node = el.gridstackNode;\n // set accept drop to true on ourself (which we ignore) so we don't get \"can't drop\" icon in HTML5 mode while moving\n if (node?.grid === this)\n return true;\n if (!this.opts.acceptWidgets)\n return false;\n // check for accept method or class matching\n let canAccept = true;\n if (typeof this.opts.acceptWidgets === 'function') {\n canAccept = this.opts.acceptWidgets(el);\n }\n else {\n let selector = (this.opts.acceptWidgets === true ? '.grid-stack-item' : this.opts.acceptWidgets);\n canAccept = el.matches(selector);\n }\n // finally check to make sure we actually have space left #1571\n if (canAccept && node && this.opts.maxRow) {\n let n = { w: node.w, h: node.h, minW: node.minW, minH: node.minH }; // only width/height matters and autoPosition\n canAccept = this.engine.willItFit(n);\n }\n return canAccept;\n }\n })\n /**\n * entering our grid area\n */\n .on(this.el, 'dropover', (event, el, helper) => {\n // console.log(`over ${this.el.gridstack.opts.id} ${count++}`); // TEST\n let node = el.gridstackNode;\n // ignore drop enter on ourself (unless we temporarily removed) which happens on a simple drag of our item\n if (node?.grid === this && !node._temporaryRemoved) {\n // delete node._added; // reset this to track placeholder again in case we were over other grid #1484 (dropout doesn't always clear)\n return false; // prevent parent from receiving msg (which may be a grid as well)\n }\n // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now\n if (node?.grid && node.grid !== this && !node._temporaryRemoved) {\n // console.log('dropover without leave'); // TEST\n let otherGrid = node.grid;\n otherGrid._leave(el, helper);\n }\n // cache cell dimensions (which don't change), position can animate if we removed an item in otherGrid that affects us...\n cellWidth = this.cellWidth();\n cellHeight = this.getCellHeight(true);\n // load any element attributes if we don't have a node\n if (!node) {\n node = this._readAttr(el, false); // don't wipe external (e.g. drag toolbar) attr #2354\n }\n if (!node.grid) {\n node._isExternal = true;\n el.gridstackNode = node;\n }\n // calculate the grid size based on element outer size\n helper = helper || el;\n let w = node.w || Math.round(helper.offsetWidth / cellWidth) || 1;\n let h = node.h || Math.round(helper.offsetHeight / cellHeight) || 1;\n // if the item came from another grid, make a copy and save the original info in case we go back there\n if (node.grid && node.grid !== this) {\n // copy the node original values (min/max/id/etc...) but override width/height/other flags which are this grid specific\n // console.log('dropover cloning node'); // TEST\n if (!el._gridstackNodeOrig)\n el._gridstackNodeOrig = node; // shouldn't have multiple nested!\n el.gridstackNode = node = { ...node, w, h, grid: this };\n this.engine.cleanupNode(node)\n .nodeBoundFix(node);\n // restore some internal fields we need after clearing them all\n node._initDD =\n node._isExternal = // DOM needs to be re-parented on a drop\n node._temporaryRemoved = true; // so it can be inserted onDrag below\n }\n else {\n node.w = w;\n node.h = h;\n node._temporaryRemoved = true; // so we can insert it\n }\n // clear any marked for complete removal (Note: don't check _isAboutToRemove as that is cleared above - just do it)\n this._itemRemoving(node.el, false);\n dd.on(el, 'drag', onDrag);\n // make sure this is called at least once when going fast #1578\n onDrag(event, el, helper);\n return false; // prevent parent from receiving msg (which may be a grid as well)\n })\n /**\n * Leaving our grid area...\n */\n .on(this.el, 'dropout', (event, el, helper) => {\n // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST\n let node = el.gridstackNode;\n if (!node)\n return false;\n // fix #1578 when dragging fast, we might get leave after other grid gets enter (which calls us to clean)\n // so skip this one if we're not the active grid really..\n if (!node.grid || node.grid === this) {\n this._leave(el, helper);\n // if we were created as temporary nested grid, go back to before state\n if (this._isTemp) {\n this.removeAsSubGrid(node);\n }\n }\n return false; // prevent parent from receiving msg (which may be grid as well)\n })\n /**\n * end - releasing the mouse\n */\n .on(this.el, 'drop', (event, el, helper) => {\n let node = el.gridstackNode;\n // ignore drop on ourself from ourself that didn't come from the outside - dragend will handle the simple move instead\n if (node?.grid === this && !node._isExternal)\n return false;\n let wasAdded = !!this.placeholder.parentElement; // skip items not actually added to us because of constrains, but do cleanup #1419\n this.placeholder.remove();\n // notify previous grid of removal\n // console.log('drop delete _gridstackNodeOrig') // TEST\n let origNode = el._gridstackNodeOrig;\n delete el._gridstackNodeOrig;\n if (wasAdded && origNode?.grid && origNode.grid !== this) {\n let oGrid = origNode.grid;\n oGrid.engine.removedNodes.push(origNode);\n oGrid._triggerRemoveEvent()._triggerChangeEvent();\n // if it's an empty sub-grid that got auto-created, nuke it\n if (oGrid.parentGridItem && !oGrid.engine.nodes.length && oGrid.opts.subGridDynamic) {\n oGrid.removeAsSubGrid();\n }\n }\n if (!node)\n return false;\n // use existing placeholder node as it's already in our list with drop location\n if (wasAdded) {\n this.engine.cleanupNode(node); // removes all internal _xyz values\n node.grid = this;\n }\n dd.off(el, 'drag');\n // if we made a copy ('helper' which is temp) of the original node then insert a copy, else we move the original node (#1102)\n // as the helper will be nuked by jquery-ui otherwise. TODO: update old code path\n if (helper !== el) {\n helper.remove();\n el.gridstackNode = origNode; // original item (left behind) is re-stored to pre dragging as the node now has drop info\n if (wasAdded) {\n el = el.cloneNode(true);\n }\n }\n else {\n el.remove(); // reduce flicker as we change depth here, and size further down\n this._removeDD(el);\n }\n if (!wasAdded)\n return false;\n el.gridstackNode = node;\n node.el = el;\n let subGrid = node.subGrid?.el?.gridstack; // set when actual sub-grid present\n // @ts-ignore\n Utils.copyPos(node, this._readAttr(this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578\n Utils.removePositioningStyles(el); // @ts-ignore\n this._writeAttr(el, node);\n el.classList.add(gridDefaults.itemClass, this.opts.itemClass);\n this.el.appendChild(el); // @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only)\n if (subGrid) {\n subGrid.parentGridItem = node;\n if (!subGrid.opts.styleInHead)\n subGrid._updateStyles(true); // re-create sub-grid styles now that we've moved\n }\n this._updateContainerHeight();\n this.engine.addedNodes.push(node); // @ts-ignore\n this._triggerAddEvent(); // @ts-ignore\n this._triggerChangeEvent();\n this.engine.endUpdate();\n if (this._gsEventHandler['dropped']) {\n this._gsEventHandler['dropped']({ ...event, type: 'dropped' }, origNode && origNode.grid ? origNode : undefined, node);\n }\n // wait till we return out of the drag callback to set the new drag&resize handler or they may get messed up\n window.setTimeout(() => {\n // IFF we are still there (some application will use as placeholder and insert their real widget instead and better call makeWidget())\n if (node.el && node.el.parentElement) {\n this._prepareDragDropByNode(node);\n }\n else {\n this.engine.removeNode(node);\n }\n delete node.grid._isTemp;\n });\n return false; // prevent parent from receiving msg (which may be grid as well)\n });\n return this;\n }\n /** @internal mark item for removal */\n _itemRemoving(el, remove) {\n let node = el ? el.gridstackNode : undefined;\n if (!node || !node.grid)\n return;\n remove ? node._isAboutToRemove = true : delete node._isAboutToRemove;\n remove ? el.classList.add('grid-stack-item-removing') : el.classList.remove('grid-stack-item-removing');\n }\n /** @internal called to setup a trash drop zone if the user specifies it */\n _setupRemoveDrop() {\n if (!this.opts.staticGrid && typeof this.opts.removable === 'string') {\n let trashEl = document.querySelector(this.opts.removable);\n if (!trashEl)\n return this;\n // only register ONE drop-over/dropout callback for the 'trash', and it will\n // update the passed in item and parent grid because the 'trash' is a shared resource anyway,\n // and Native DD only has 1 event CB (having a list and technically a per grid removableOptions complicates things greatly)\n if (!dd.isDroppable(trashEl)) {\n dd.droppable(trashEl, this.opts.removableOptions)\n .on(trashEl, 'dropover', (event, el) => this._itemRemoving(el, true))\n .on(trashEl, 'dropout', (event, el) => this._itemRemoving(el, false));\n }\n }\n return this;\n }\n /** @internal prepares the element for drag&drop **/\n _prepareDragDropByNode(node) {\n let el = node.el;\n const noMove = node.noMove || this.opts.disableDrag;\n const noResize = node.noResize || this.opts.disableResize;\n // check for disabled grid first\n if (this.opts.staticGrid || (noMove && noResize)) {\n if (node._initDD) {\n this._removeDD(el); // nukes everything instead of just disable, will add some styles back next\n delete node._initDD;\n }\n el.classList.add('ui-draggable-disabled', 'ui-resizable-disabled'); // add styles one might depend on #1435\n return this;\n }\n if (!node._initDD) {\n // variables used/cashed between the 3 start/move/end methods, in addition to node passed above\n let cellWidth;\n let cellHeight;\n /** called when item starts moving/resizing */\n let onStartMoving = (event, ui) => {\n // trigger any 'dragstart' / 'resizestart' manually\n if (this._gsEventHandler[event.type]) {\n this._gsEventHandler[event.type](event, event.target);\n }\n cellWidth = this.cellWidth();\n cellHeight = this.getCellHeight(true); // force pixels for calculations\n this._onStartMoving(el, event, ui, node, cellWidth, cellHeight);\n };\n /** called when item is being dragged/resized */\n let dragOrResize = (event, ui) => {\n this._dragOrResize(el, event, ui, node, cellWidth, cellHeight);\n };\n /** called when the item stops moving/resizing */\n let onEndMoving = (event) => {\n this.placeholder.remove();\n delete node._moving;\n delete node._event;\n delete node._lastTried;\n // if the item has moved to another grid, we're done here\n let target = event.target;\n if (!target.gridstackNode || target.gridstackNode.grid !== this)\n return;\n node.el = target;\n if (node._isAboutToRemove) {\n let gridToNotify = el.gridstackNode.grid;\n if (gridToNotify._gsEventHandler[event.type]) {\n gridToNotify._gsEventHandler[event.type](event, target);\n }\n this._removeDD(el);\n gridToNotify.engine.removedNodes.push(node);\n gridToNotify._triggerRemoveEvent();\n // break circular links and remove DOM\n delete el.gridstackNode;\n delete node.el;\n el.remove();\n }\n else {\n Utils.removePositioningStyles(target);\n if (node._temporaryRemoved) {\n // got removed - restore item back to before dragging position\n Utils.copyPos(node, node._orig); // @ts-ignore\n this._writePosAttr(target, node);\n this.engine.addNode(node);\n }\n else {\n // move to new placeholder location\n this._writePosAttr(target, node);\n }\n if (this._gsEventHandler[event.type]) {\n this._gsEventHandler[event.type](event, target);\n }\n }\n // @ts-ignore\n this._extraDragRow = 0; // @ts-ignore\n this._updateContainerHeight(); // @ts-ignore\n this._triggerChangeEvent();\n this.engine.endUpdate();\n };\n dd.draggable(el, {\n start: onStartMoving,\n stop: onEndMoving,\n drag: dragOrResize\n }).resizable(el, {\n start: onStartMoving,\n stop: onEndMoving,\n resize: dragOrResize\n });\n node._initDD = true; // we've set DD support now\n }\n // finally fine tune move vs resize by disabling any part...\n dd.draggable(el, noMove ? 'disable' : 'enable')\n .resizable(el, noResize ? 'disable' : 'enable');\n return this;\n }\n /** @internal handles actual drag/resize start **/\n _onStartMoving(el, event, ui, node, cellWidth, cellHeight) {\n this.engine.cleanNodes()\n .beginUpdate(node);\n // @ts-ignore\n this._writePosAttr(this.placeholder, node);\n this.el.appendChild(this.placeholder);\n // console.log('_onStartMoving placeholder') // TEST\n node.el = this.placeholder;\n node._lastUiPosition = ui.position;\n node._prevYPix = ui.position.top;\n node._moving = (event.type === 'dragstart'); // 'dropover' are not initially moving so they can go exactly where they enter (will push stuff out of the way)\n delete node._lastTried;\n if (event.type === 'dropover' && node._temporaryRemoved) {\n // console.log('engine.addNode x=' + node.x); // TEST\n this.engine.addNode(node); // will add, fix collisions, update attr and clear _temporaryRemoved\n node._moving = true; // AFTER, mark as moving object (wanted fix location before)\n }\n // set the min/max resize info\n this.engine.cacheRects(cellWidth, cellHeight, this.opts.marginTop, this.opts.marginRight, this.opts.marginBottom, this.opts.marginLeft);\n if (event.type === 'resizestart') {\n dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minW || 1))\n .resizable(el, 'option', 'minHeight', cellHeight * (node.minH || 1));\n if (node.maxW) {\n dd.resizable(el, 'option', 'maxWidth', cellWidth * node.maxW);\n }\n if (node.maxH) {\n dd.resizable(el, 'option', 'maxHeight', cellHeight * node.maxH);\n }\n }\n }\n /** @internal handles actual drag/resize **/\n _dragOrResize(el, event, ui, node, cellWidth, cellHeight) {\n let p = { ...node._orig }; // could be undefined (_isExternal) which is ok (drag only set x,y and w,h will default to node value)\n let resizing;\n let mLeft = this.opts.marginLeft, mRight = this.opts.marginRight, mTop = this.opts.marginTop, mBottom = this.opts.marginBottom;\n // if margins (which are used to pass mid point by) are large relative to cell height/width, reduce them down #1855\n let mHeight = Math.round(cellHeight * 0.1), mWidth = Math.round(cellWidth * 0.1);\n mLeft = Math.min(mLeft, mWidth);\n mRight = Math.min(mRight, mWidth);\n mTop = Math.min(mTop, mHeight);\n mBottom = Math.min(mBottom, mHeight);\n if (event.type === 'drag') {\n if (node._temporaryRemoved)\n return; // handled by dropover\n let distance = ui.position.top - node._prevYPix;\n node._prevYPix = ui.position.top;\n if (this.opts.draggable.scroll !== false) {\n Utils.updateScrollPosition(el, ui.position, distance);\n }\n // get new position taking into account the margin in the direction we are moving! (need to pass mid point by margin)\n let left = ui.position.left + (ui.position.left > node._lastUiPosition.left ? -mRight : mLeft);\n let top = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -mBottom : mTop);\n p.x = Math.round(left / cellWidth);\n p.y = Math.round(top / cellHeight);\n // @ts-ignore// if we're at the bottom hitting something else, grow the grid so cursor doesn't leave when trying to place below others\n let prev = this._extraDragRow;\n if (this.engine.collide(node, p)) {\n let row = this.getRow();\n let extra = Math.max(0, (p.y + node.h) - row);\n if (this.opts.maxRow && row + extra > this.opts.maxRow) {\n extra = Math.max(0, this.opts.maxRow - row);\n } // @ts-ignore\n this._extraDragRow = extra; // @ts-ignore\n }\n else\n this._extraDragRow = 0; // @ts-ignore\n if (this._extraDragRow !== prev)\n this._updateContainerHeight();\n if (node.x === p.x && node.y === p.y)\n return; // skip same\n // DON'T skip one we tried as we might have failed because of coverage <50% before\n // if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return;\n }\n else if (event.type === 'resize') {\n if (p.x < 0)\n return;\n // Scrolling page if needed\n Utils.updateScrollResize(event, el, cellHeight);\n // get new size\n p.w = Math.round((ui.size.width - mLeft) / cellWidth);\n p.h = Math.round((ui.size.height - mTop) / cellHeight);\n if (node.w === p.w && node.h === p.h)\n return;\n if (node._lastTried && node._lastTried.w === p.w && node._lastTried.h === p.h)\n return; // skip one we tried (but failed)\n // if we size on left/top side this might move us, so get possible new position as well\n let left = ui.position.left + mLeft;\n let top = ui.position.top + mTop;\n p.x = Math.round(left / cellWidth);\n p.y = Math.round(top / cellHeight);\n resizing = true;\n }\n node._event = event;\n node._lastTried = p; // set as last tried (will nuke if we go there)\n let rect = {\n x: ui.position.left + mLeft,\n y: ui.position.top + mTop,\n w: (ui.size ? ui.size.width : node.w * cellWidth) - mLeft - mRight,\n h: (ui.size ? ui.size.height : node.h * cellHeight) - mTop - mBottom\n };\n if (this.engine.moveNodeCheck(node, { ...p, cellWidth, cellHeight, rect, resizing })) {\n node._lastUiPosition = ui.position;\n this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft);\n delete node._skipDown;\n if (resizing && node.subGrid)\n node.subGrid.onParentResize();\n this._extraDragRow = 0; // @ts-ignore\n this._updateContainerHeight();\n let target = event.target; // @ts-ignore\n this._writePosAttr(target, node);\n if (this._gsEventHandler[event.type]) {\n this._gsEventHandler[event.type](event, target);\n }\n }\n }\n /** @internal called when item leaving our area by either cursor dropout event\n * or shape is outside our boundaries. remove it from us, and mark temporary if this was\n * our item to start with else restore prev node values from prev grid it came from.\n **/\n _leave(el, helper) {\n let node = el.gridstackNode;\n if (!node)\n return;\n dd.off(el, 'drag'); // no need to track while being outside\n // this gets called when cursor leaves and shape is outside, so only do this once\n if (node._temporaryRemoved)\n return;\n node._temporaryRemoved = true;\n this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue\n node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged\n if (this.opts.removable === true) { // boolean vs a class string\n // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so\n this._itemRemoving(el, true);\n }\n // finally if item originally came from another grid, but left us, restore things back to prev info\n if (el._gridstackNodeOrig) {\n // console.log('leave delete _gridstackNodeOrig') // TEST\n el.gridstackNode = el._gridstackNodeOrig;\n delete el._gridstackNodeOrig;\n }\n else if (node._isExternal) {\n // item came from outside (like a toolbar) so nuke any node info\n delete node.el;\n delete el.gridstackNode;\n // and restore all nodes back to original\n this.engine.restoreInitial();\n }\n }\n // legacy method removed\n commit() { obsolete(this, this.batchUpdate(false), 'commit', 'batchUpdate', '5.2'); return this; }\n}\n/** scoping so users can call GridStack.Utils.sort() for example */\nGridStack.Utils = Utils;\n/** scoping so users can call new GridStack.Engine(12) for example */\nGridStack.Engine = GridStackEngine;\nGridStack.GDRev = '8.2.2';\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ0LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBOzs7R0FHRztBQVNILHVDQUF1QztBQUN2QywyQkFBMkI7QUFDcEIsU0FBUyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxPQUFlLEVBQUUsT0FBZSxFQUFFLEdBQVc7SUFDN0UsSUFBSSxPQUFPLEdBQUcsQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFO1FBQ3hCLE9BQU8sQ0FBQyxJQUFJLENBQUMsMEJBQTBCLEdBQUcsT0FBTyxHQUFHLHFCQUFxQixHQUFHLEdBQUcsR0FBRyx5QkFBeUI7WUFDM0csUUFBUSxHQUFHLE9BQU8sR0FBRywrQ0FBK0MsQ0FBQyxDQUFDO1FBQ3RFLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUNELE9BQU8sQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNoQyxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBRUQsOEZBQThGO0FBQ3ZGLFNBQVMsWUFBWSxDQUFDLElBQXNCLEVBQUUsT0FBZSxFQUFFLE9BQWUsRUFBRSxHQUFXO0lBQ2hHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFNBQVMsRUFBRTtRQUMvQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlCLE9BQU8sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsT0FBTyxHQUFHLHFCQUFxQixHQUFHLEdBQUcsR0FBRywrQkFBK0I7WUFDN0csT0FBTyxHQUFHLCtDQUErQyxDQUFDLENBQUM7S0FDOUQ7QUFDSCxDQUFDO0FBRUQsc0RBQXNEO0FBQy9DLFNBQVMsZUFBZSxDQUFDLElBQXNCLEVBQUUsT0FBZSxFQUFFLEdBQVcsRUFBRSxJQUFZO0lBQ2hHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFNBQVMsRUFBRTtRQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLHdCQUF3QixHQUFHLE9BQU8sR0FBRyxxQkFBcUIsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUM7S0FDdkY7QUFDSCxDQUFDO0FBRUQsb0RBQW9EO0FBQzdDLFNBQVMsWUFBWSxDQUFDLEVBQWUsRUFBRSxPQUFlLEVBQUUsT0FBZSxFQUFFLEdBQVc7SUFDekYsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN2QyxJQUFJLE9BQU8sS0FBSyxJQUFJLEVBQUU7UUFDcEIsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDbEMsT0FBTyxDQUFDLElBQUksQ0FBQywyQkFBMkIsR0FBRyxPQUFPLEdBQUcsSUFBSSxHQUFHLE9BQU8sR0FBRyxtQ0FBbUMsR0FBRyxHQUFHLEdBQUcsK0JBQStCO1lBQy9JLE9BQU8sR0FBRywrQ0FBK0MsQ0FBQyxDQUFDO0tBQzlEO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0ksTUFBTSxLQUFLO0lBRWhCLGdJQUFnSTtJQUNoSSxNQUFNLENBQUMsV0FBVyxDQUFDLEdBQXFCLEVBQUUsT0FBK0IsUUFBUTtRQUMvRSxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtZQUMzQixNQUFNLEdBQUcsR0FBRyxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFnQixDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFFdEUsd0dBQXdHO1lBQ3hHLG1GQUFtRjtZQUNuRixvRkFBb0Y7WUFDcEYsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLG1CQUFtQjtnQkFDL0MsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDbkMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUN2QjtZQUVELElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7Z0JBQ3BELElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO2dCQUN4QyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtvQkFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7aUJBQUU7YUFDOUQ7WUFDRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFrQixDQUFDO1NBQzFDO1FBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsQ0FBQztJQUVELHlIQUF5SDtJQUN6SCxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQXFCLEVBQUUsT0FBK0IsUUFBUTtRQUM5RSxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtZQUMzQixNQUFNLEdBQUcsR0FBRyxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFnQixDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDdEUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBQzdCLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7Z0JBQ3pCLE9BQU8sR0FBRyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDN0M7WUFDRCxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFO2dCQUN0RCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDaEM7WUFFRCw2R0FBNkc7WUFDN0csSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLG1CQUFtQjtnQkFDL0MsT0FBTyxHQUFHLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ2hDO1lBRUQsMENBQTBDO1lBQzFDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakMsSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUU7Z0JBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDO2FBQUU7WUFDaEQsSUFBSSxDQUFDLEVBQUUsRUFBRTtnQkFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO2FBQUU7WUFDL0MsT0FBTyxFQUFpQixDQUFDO1NBQzFCO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsc0NBQXNDO0lBQ3RDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBb0IsRUFBRSxDQUFvQjtRQUM3RCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pGLENBQUM7SUFFRCxxREFBcUQ7SUFDckQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFvQixFQUFFLENBQW9CO1FBQzFELE9BQU8sS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQUUsRUFBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBQyxDQUFDLEVBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRUQsdUNBQXVDO0lBQ3ZDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBb0IsRUFBRSxDQUFvQjtRQUM3RCxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqRCxJQUFJLEVBQUUsSUFBSSxFQUFFO1lBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxhQUFhO1FBQ3JDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pELElBQUksRUFBRSxJQUFJLEVBQUU7WUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLGFBQWE7UUFDckMsT0FBTyxDQUFDLEVBQUUsR0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBQyxFQUFFLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQsdUJBQXVCO0lBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBb0I7UUFDOUIsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkIsQ0FBQztJQUVEOzs7OztRQUtJO0lBQ0osTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFzQixFQUFFLEdBQVksRUFBRSxNQUFlO1FBQy9ELE1BQU0sR0FBRyxNQUFNLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMvRSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDWixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDOztZQUV2RSxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQzNFLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFVLEVBQUUsTUFBb0IsRUFBRSxPQUE0QjtRQUNwRixJQUFJLEtBQUssR0FBcUIsUUFBUSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5RCxNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsS0FBSztRQUM1QixJQUFJLEtBQUs7WUFBRSxLQUFLLENBQUMsS0FBSyxHQUFHLEtBQUs7UUFDOUIsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDdkMsS0FBSyxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDdEMsOERBQThEO1FBQzlELElBQUssS0FBYSxDQUFDLFVBQVUsRUFBRSxFQUFFLDREQUE0RDtZQUMzRiw4REFBOEQ7WUFDN0QsS0FBYSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1NBQ3hDO2FBQU07WUFDTCxLQUFLLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWM7U0FDL0Q7UUFDRCxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ1gsa0JBQWtCO1lBQ2xCLE1BQU0sR0FBRyxRQUFRLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUMzQjthQUFNO1lBQ0wsTUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1NBQy9DO1FBQ0QsT0FBTyxLQUFLLENBQUMsS0FBc0IsQ0FBQztJQUN0QyxDQUFDO0lBRUQsc0NBQXNDO0lBQ3RDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFVO1FBQ2hDLElBQUksRUFBRSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsb0JBQW9CLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ2pFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxVQUFVO1lBQUUsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3ZDLENBQUM7SUFFRCx5QkFBeUI7SUFDekIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFvQixFQUFFLFFBQWdCLEVBQUUsS0FBYTtRQUNyRSxJQUFJLE9BQU8sS0FBSyxDQUFDLE9BQU8sS0FBSyxVQUFVLEVBQUU7WUFDdkMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDaEM7YUFBTSxJQUFJLE9BQU8sS0FBSyxDQUFDLFVBQVUsS0FBSyxVQUFVLEVBQUU7WUFDakQsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLFFBQVEsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1NBQzNDO0lBQ0gsQ0FBQztJQUVELDhEQUE4RDtJQUM5RCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQVU7UUFDdEIsSUFBSSxPQUFPLENBQUMsS0FBSyxTQUFTLEVBQUU7WUFDMUIsT0FBTyxDQUFDLENBQUM7U0FDVjtRQUNELElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxFQUFFO1lBQ3pCLENBQUMsR0FBRyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDcEIsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxPQUFPLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1NBQ2hFO1FBQ0QsT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEIsQ0FBQztJQUVELE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBb0I7UUFDbEMsT0FBTyxDQUFDLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVELE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBbUI7UUFDcEMsSUFBSSxDQUFTLENBQUM7UUFDZCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUM7UUFDaEIsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUU7WUFDM0IsSUFBSSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyx1RUFBdUUsQ0FBQyxDQUFDO1lBQy9GLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ1YsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2FBQ25DO1lBQ0QsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7WUFDeEIsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMxQjthQUFNO1lBQ0wsQ0FBQyxHQUFHLEdBQUcsQ0FBQztTQUNUO1FBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsNEVBQTRFO0lBQzVFLDJCQUEyQjtJQUMzQixNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxHQUFHLE9BQU87UUFFaEMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUN2QixLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sRUFBRTtnQkFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDO29CQUFFLE9BQU87Z0JBQ3hDLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssU0FBUyxFQUFFO29CQUNyRCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2lCQUMzQjtxQkFBTSxJQUFJLE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVEsSUFBSSxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxRQUFRLEVBQUU7b0JBQzdFLGtFQUFrRTtvQkFDbEUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7aUJBQ3pDO2FBQ0Y7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRCx1SUFBdUk7SUFDdkksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFVLEVBQUUsQ0FBVTtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVE7WUFBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsSUFBSSxPQUFPLENBQUMsS0FBSyxPQUFPLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN4Qyx3RUFBd0U7UUFDeEUsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU07WUFBRSxPQUFPLEtBQUssQ0FBQztRQUNsRSxLQUFLLE1BQU0sR0FBRyxJQUFJLENBQUMsRUFBRTtZQUNuQixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1NBQ3JDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsd0ZBQXdGO0lBQ3hGLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBa0IsRUFBRSxDQUFrQixFQUFFLFFBQVEsR0FBRyxLQUFLO1FBQ3JFLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTO1lBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTO1lBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTO1lBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTO1lBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLElBQUksUUFBUSxFQUFFO1lBQ1osSUFBSSxDQUFDLENBQUMsSUFBSTtnQkFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDNUIsSUFBSSxDQUFDLENBQUMsSUFBSTtnQkFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDNUIsSUFBSSxDQUFDLENBQUMsSUFBSTtnQkFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDNUIsSUFBSSxDQUFDLENBQUMsSUFBSTtnQkFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7U0FDN0I7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRCwrQ0FBK0M7SUFDL0MsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFvQixFQUFFLENBQW9CO1FBQ3ZELE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVELHNEQUFzRDtJQUN0RCxNQUFNLENBQUMsY0FBYyxDQUFDLElBQW1CO1FBQ3ZDLDJCQUEyQjtRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtZQUFFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztTQUFFO1FBQ3JDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQUUsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDO1NBQUU7UUFDckMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFBRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7U0FBRTtRQUNyQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtZQUFFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztTQUFFO0lBQ3ZDLENBQUM7SUFFRCxtSEFBbUg7SUFDbkgsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQVUsRUFBRSxDQUFVO1FBQ2pELElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVE7WUFBRSxPQUFPO1FBQzNELEtBQUssSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFO1lBQ2pCLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNqQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDcEMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDO2FBQ2Q7aUJBQU0sSUFBSSxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLEVBQUU7Z0JBQ2pFLEtBQUssSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFO29CQUNqQixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRTt3QkFBRSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUM7cUJBQUU7aUJBQzVEO2dCQUNELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRTtvQkFBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUM7aUJBQUU7YUFDaEQ7U0FDRjtJQUNILENBQUM7SUFFRCxnRUFBZ0U7SUFDaEUsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQWdCLEVBQUUsUUFBUSxHQUFHLElBQUk7UUFDNUQsS0FBSyxJQUFJLEdBQUcsSUFBSSxDQUFDLEVBQUU7WUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssU0FBUztnQkFBRyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUFFO1FBQ3JHLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNkLElBQUksUUFBUTtZQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMxQixxREFBcUQ7UUFDckQsSUFBSSxDQUFDLENBQUMsQ0FBQyxZQUFZO1lBQUUsT0FBTyxDQUFDLENBQUMsWUFBWSxDQUFDO1FBQzNDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUTtZQUFFLE9BQU8sQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUNuQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU07WUFBRSxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDL0IsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNO1lBQUUsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQy9CLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSTtZQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUk7WUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELHFFQUFxRTtJQUNyRSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsRUFBZSxFQUFFLElBQVk7UUFDbkQsT0FBTyxFQUFFLEVBQUU7WUFDVCxJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztnQkFBRSxPQUFPLEVBQUUsQ0FBQztZQUMzQyxFQUFFLEdBQUcsRUFBRSxDQUFDLGFBQWE7U0FDdEI7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCwwR0FBMEc7SUFDMUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFnQixFQUFFLEtBQWE7UUFDN0MsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLE9BQU8sQ0FBQyxHQUFHLElBQUksRUFBRSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQ2QsU0FBUyxHQUFHLElBQUksQ0FBQztnQkFDakIsVUFBVSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQzthQUNoRTtRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLHVCQUF1QixDQUFDLEVBQWU7UUFDNUMsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQztRQUNyQixJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUU7WUFDbEIsS0FBSyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUNsQztRQUNELElBQUksS0FBSyxDQUFDLElBQUksRUFBRTtZQUNkLEtBQUssQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDOUI7UUFDRCxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDYixLQUFLLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzdCO1FBQ0QsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO1lBQ2YsS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUMvQjtRQUNELElBQUksS0FBSyxDQUFDLE1BQU0sRUFBRTtZQUNoQixLQUFLLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1NBQ2hDO0lBQ0gsQ0FBQztJQUVELHlJQUF5STtJQUN6SSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsRUFBZ0I7UUFDdEMsSUFBSSxDQUFDLEVBQUU7WUFBRSxPQUFPLFFBQVEsQ0FBQyxnQkFBK0IsSUFBSSxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUMsYUFBYTtRQUNuRyxNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNuQyxNQUFNLGFBQWEsR0FBRyxlQUFlLENBQUM7UUFFdEMsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQ3hELE9BQU8sRUFBRSxDQUFDO1NBQ1g7YUFBTTtZQUNMLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQztTQUNoRDtJQUNILENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsTUFBTSxDQUFDLG9CQUFvQixDQUFDLEVBQWUsRUFBRSxRQUF1QixFQUFFLFFBQWdCO1FBQ3BGLHFCQUFxQjtRQUNyQixJQUFJLElBQUksR0FBRyxFQUFFLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUN0QyxJQUFJLHlCQUF5QixHQUFHLENBQUMsTUFBTSxDQUFDLFdBQVcsSUFBSSxRQUFRLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzlGLElBQUksSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyx5QkFBeUIsRUFDdkM7WUFDQSw2Q0FBNkM7WUFDN0Msc0RBQXNEO1lBQ3RELGlDQUFpQztZQUNqQyxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLHlCQUF5QixDQUFDO1lBQzdELElBQUksWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7WUFDNUIsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3pDLElBQUksUUFBUSxLQUFLLElBQUksRUFBRTtnQkFDckIsSUFBSSxVQUFVLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQztnQkFDcEMsSUFBSSxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxFQUFFO29CQUNoQyxZQUFZO29CQUNaLElBQUksRUFBRSxDQUFDLFlBQVksR0FBRyx5QkFBeUIsRUFBRTt3QkFDL0MsUUFBUSxDQUFDLFNBQVMsSUFBSSxRQUFRLENBQUM7cUJBQ2hDO3lCQUFNO3dCQUNMLFFBQVEsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQztxQkFDN0Y7aUJBQ0Y7cUJBQU0sSUFBSSxRQUFRLEdBQUcsQ0FBQyxFQUFFO29CQUN2QixjQUFjO29CQUNkLElBQUksRUFBRSxDQUFDLFlBQVksR0FBRyx5QkFBeUIsRUFBRTt3QkFDL0MsUUFBUSxDQUFDLFNBQVMsSUFBSSxRQUFRLENBQUM7cUJBQ2hDO3lCQUFNO3dCQUNMLFFBQVEsQ0FBQyxTQUFTLElBQUksY0FBYyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUM7cUJBQzdFO2lCQUNGO2dCQUNELG1DQUFtQztnQkFDbkMsUUFBUSxDQUFDLEdBQUcsSUFBSSxRQUFRLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQzthQUNqRDtTQUNGO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFpQixFQUFFLEVBQWUsRUFBRSxRQUFnQjtRQUM1RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0MsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQztRQUNyQyw2SEFBNkg7UUFDN0gsd0ZBQXdGO1FBQ3hGLGdHQUFnRztRQUNoRyx5R0FBeUc7UUFDekcsTUFBTSxTQUFTLEdBQUcsQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxHQUFHLENBQUM7UUFDcEcsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUM7UUFDOUMsTUFBTSxHQUFHLEdBQUcsV0FBVyxHQUFHLFFBQVEsQ0FBQztRQUNuQyxNQUFNLE1BQU0sR0FBRyxXQUFXLEdBQUcsTUFBTSxHQUFHLFFBQVEsQ0FBQztRQUUvQyxJQUFJLEdBQUcsRUFBRTtZQUNQLDRFQUE0RTtZQUM1RSx1REFBdUQ7WUFDdkQsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLFdBQVcsR0FBRyxRQUFRLEVBQUMsQ0FBQyxDQUFDO1NBQ3ZFO2FBQU0sSUFBSSxNQUFNLEVBQUU7WUFDakIsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLFFBQVEsR0FBRyxDQUFDLE1BQU0sR0FBRyxXQUFXLENBQUMsRUFBQyxDQUFDLENBQUM7U0FDbEY7SUFDSCxDQUFDO0lBRUQsOEdBQThHO0lBQzlHLE1BQU0sQ0FBQyxLQUFLLENBQUksR0FBTTtRQUNwQixJQUFJLEdBQUcsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLFNBQVMsSUFBSSxPQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssUUFBUSxFQUFFO1lBQ2pFLE9BQU8sR0FBRyxDQUFDO1NBQ1o7UUFDRCxpQ0FBaUM7UUFDakMsSUFBSSxHQUFHLFlBQVksS0FBSyxFQUFFO1lBQ3hCLDhEQUE4RDtZQUM5RCxPQUFPLENBQUMsR0FBRyxHQUFHLENBQVEsQ0FBQztTQUN4QjtRQUNELE9BQU8sRUFBQyxHQUFHLEdBQUcsRUFBQyxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxNQUFNLENBQUMsU0FBUyxDQUFJLEdBQU07UUFDeEIsZ0ZBQWdGO1FBQ2hGLE1BQU0sVUFBVSxHQUFHLENBQUMsWUFBWSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JFLDZFQUE2RTtRQUM3RSxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdCLEtBQUssTUFBTSxHQUFHLElBQUksR0FBRyxFQUFFO1lBQ3JCLDRGQUE0RjtZQUM1RixJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksT0FBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLFFBQVEsSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFO2dCQUNoSSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzthQUN0QztTQUNGO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsbUVBQW1FO0lBQzVELE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBZTtRQUNyQyxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBZ0IsQ0FBQztRQUMvQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVNLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBZSxFQUFFLE1BQTRCO1FBQ2xFLElBQUksVUFBdUIsQ0FBQztRQUM1QixJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRTtZQUM5QixVQUFVLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN2QzthQUFNO1lBQ0wsVUFBVSxHQUFHLE1BQU0sQ0FBQztTQUNyQjtRQUNELElBQUksVUFBVSxFQUFFO1lBQ2QsVUFBVSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUM1QjtJQUNILENBQUM7SUFFRCw2REFBNkQ7SUFDN0Qsc0VBQXNFO0lBQ3RFLHNDQUFzQztJQUN0QyxNQUFNO0lBQ04sSUFBSTtJQUVHLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBZSxFQUFFLE1BQTZDO1FBQ3RGLElBQUksTUFBTSxZQUFZLE1BQU0sRUFBRTtZQUM1QixLQUFLLE1BQU0sQ0FBQyxJQUFJLE1BQU0sRUFBRTtnQkFDdEIsSUFBSSxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUM1QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7d0JBQzVCLHlCQUF5Qjt3QkFDeEIsTUFBTSxDQUFDLENBQUMsQ0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTs0QkFDcEMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7d0JBQ3BCLENBQUMsQ0FBQyxDQUFDO3FCQUNKO3lCQUFNO3dCQUNMLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO3FCQUN6QjtpQkFDRjthQUNGO1NBQ0Y7SUFDSCxDQUFDO0lBRU0sTUFBTSxDQUFDLFNBQVMsQ0FBSSxDQUF5QixFQUFFLElBQTRDO1FBQ2hHLE1BQU0sR0FBRyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoQyxNQUFNLEdBQUcsR0FBRztZQUNWLE1BQU0sRUFBRSxDQUFDO1lBQ1QsS0FBSyxFQUFFLENBQUM7WUFDUixPQUFPLEVBQUUsQ0FBQztZQUNWLE9BQU8sRUFBRSxJQUFJO1lBQ2IsVUFBVSxFQUFFLElBQUk7WUFDaEIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNO1NBQzdDLENBQUM7UUFDRix3RUFBd0U7UUFDeEUsSUFBSyxDQUFlLENBQUMsWUFBWSxFQUFFO1lBQ2pDLEdBQUcsQ0FBQyxjQUFjLENBQUMsR0FBSSxDQUFlLENBQUMsWUFBWSxDQUFDLENBQUMsK0JBQStCO1NBQ3JGO1FBQ0QsQ0FBQyxRQUFRLEVBQUMsU0FBUyxFQUFDLFNBQVMsRUFBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPO1FBQzlFLENBQUMsT0FBTyxFQUFDLE9BQU8sRUFBQyxTQUFTLEVBQUMsU0FBUyxFQUFDLFNBQVMsRUFBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhO1FBQ3BHLE9BQU8sRUFBQyxHQUFHLEdBQUcsRUFBRSxHQUFHLEdBQUcsRUFBaUIsQ0FBQztJQUMxQyxDQUFDO0lBRUQseUZBQXlGO0lBQ2xGLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFhLEVBQUUsYUFBcUIsRUFBRSxNQUFvQjtRQUN6RixNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzNELGNBQWMsQ0FBQyxjQUFjLENBQzNCLGFBQWEsRUFBRSxPQUFPO1FBQ3RCLElBQUksRUFBVSxVQUFVO1FBQ3hCLElBQUksRUFBVSxhQUFhO1FBQzNCLE1BQU0sRUFBUSxPQUFPO1FBQ3JCLENBQUMsRUFBYSxTQUFTO1FBQ3ZCLENBQUMsQ0FBQyxPQUFPLEVBQUssVUFBVTtRQUN4QixDQUFDLENBQUMsT0FBTyxFQUFLLFVBQVU7UUFDeEIsQ0FBQyxDQUFDLE9BQU8sRUFBSyxVQUFVO1FBQ3hCLENBQUMsQ0FBQyxPQUFPLEVBQUssVUFBVTtRQUN4QixDQUFDLENBQUMsT0FBTyxFQUFLLFVBQVU7UUFDeEIsQ0FBQyxDQUFDLE1BQU0sRUFBTSxTQUFTO1FBQ3ZCLENBQUMsQ0FBQyxRQUFRLEVBQUksV0FBVztRQUN6QixDQUFDLENBQUMsT0FBTyxFQUFLLFVBQVU7UUFDeEIsQ0FBQyxFQUFhLFNBQVM7UUFDdkIsQ0FBQyxDQUFDLE1BQU0sQ0FBTSxnQkFBZ0I7U0FDL0IsQ0FBQztRQUNGLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDckQsQ0FBQztDQWNGOzs7QUMxaUJEOzs7R0FHRztBQUU2QjtBQWVoQzs7Ozs7R0FLRztBQUNILE1BQWEsZUFBZTtJQXNCMUIsWUFBbUIsT0FBK0IsRUFBRTtRQWxCN0MsZUFBVSxHQUFvQixFQUFFLENBQUM7UUFDakMsaUJBQVksR0FBb0IsRUFBRSxDQUFDO1FBa0J4QyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDaEMsQ0FBQztJQUVNLFdBQVcsQ0FBQyxJQUFJLEdBQUcsSUFBSTtRQUM1QixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxLQUFLLElBQUk7WUFBRSxPQUFPLElBQUksQ0FBQztRQUMzQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLElBQUksRUFBRTtZQUNSLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUM5QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxDQUFDLCtFQUErRTtZQUNuRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxvRUFBb0U7U0FDekY7YUFBTTtZQUNMLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUM5QixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDdkIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQzdCO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsZ0lBQWdJO0lBQ3RILGlCQUFpQixDQUFDLElBQW1CLEVBQUUsRUFBcUI7UUFDcEUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hJLENBQUM7SUFFRDtrQ0FDOEI7SUFDcEIsY0FBYyxDQUFDLElBQW1CLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRSxPQUF1QixFQUFFLE1BQXlCLEVBQUU7UUFDM0csSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsMkVBQTJFO1FBRS9GLE9BQU8sR0FBRyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxpREFBaUQ7UUFDOUYsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLEtBQUssQ0FBQztRQUUzQix1R0FBdUc7UUFDdkcsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDOUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7Z0JBQUUsT0FBTyxJQUFJLENBQUM7U0FDM0M7UUFFRCxnSkFBZ0o7UUFDaEosSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2QsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxFQUFFO1lBQ3BDLElBQUksR0FBRyxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQztZQUNoRCxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLGdCQUFnQjtTQUMvRDtRQUVELElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLE1BQU0sR0FBc0IsRUFBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUMsQ0FBQztRQUM1RCxPQUFPLE9BQU8sR0FBRyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLDREQUE0RDtZQUM1SCxJQUFJLEtBQWMsQ0FBQztZQUNuQix3SEFBd0g7WUFDeEgsbUZBQW1GO1lBQ25GLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSztnQkFDbkYscURBQXFEO2dCQUNyRCxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBQyxHQUFHLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBQyxHQUFHLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxFQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRTtnQkFDNUgsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ25ELEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUMsQ0FBQyxDQUFDO2dCQUMxRSxJQUFJLE9BQU8sQ0FBQyxNQUFNLElBQUksS0FBSyxFQUFFO29CQUMzQixhQUFhLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsb0RBQW9EO2lCQUM5RTtxQkFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxLQUFLLElBQUksR0FBRyxDQUFDLElBQUksRUFBRTtvQkFDL0MsMklBQTJJO29CQUMzSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7b0JBQ2xCLEVBQUUsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDO29CQUM3QixhQUFhLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2lCQUN6QjtnQkFDRCxPQUFPLEdBQUcsT0FBTyxJQUFJLEtBQUssQ0FBQzthQUM1QjtpQkFBTTtnQkFDTCxnR0FBZ0c7Z0JBQ2hHLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxFQUFDLEdBQUcsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sRUFBQyxDQUFDLENBQUM7YUFDckY7WUFDRCxJQUFJLENBQUMsS0FBSyxFQUFFO2dCQUFFLE9BQU8sT0FBTyxDQUFDO2FBQUUsQ0FBQyxtRUFBbUU7WUFDbkcsT0FBTyxHQUFHLFNBQVMsQ0FBQztTQUNyQjtRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRCxnSUFBZ0k7SUFDekgsT0FBTyxDQUFDLElBQW1CLEVBQUUsSUFBSSxHQUFHLElBQUksRUFBRSxLQUFxQjtRQUNwRSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQ3hCLE1BQU0sT0FBTyxHQUFHLEtBQUssRUFBRSxHQUFHLENBQUM7UUFDM0IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssTUFBTSxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssT0FBTyxJQUFJLG1CQUFtQixDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3JHLENBQUM7SUFDTSxVQUFVLENBQUMsSUFBbUIsRUFBRSxJQUFJLEdBQUcsSUFBSSxFQUFFLEtBQXFCO1FBQ3ZFLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDeEIsTUFBTSxPQUFPLEdBQUcsS0FBSyxFQUFFLEdBQUcsQ0FBQztRQUMzQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxNQUFNLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxPQUFPLElBQUksbUJBQW1CLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDdkcsQ0FBQztJQUVELHFJQUFxSTtJQUMzSCx3QkFBd0IsQ0FBQyxJQUFtQixFQUFFLENBQW9CLEVBQUUsUUFBeUI7UUFDckcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU87UUFDbkMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLGdCQUFnQjtRQUNyQyxJQUFJLENBQUMsR0FBRyxFQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBQyxDQUFDLENBQUMsZUFBZTtRQUVwQyw4RUFBOEU7UUFDOUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUU7WUFDZCxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNsQixDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDWjthQUFNO1lBQ0wsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDbkI7UUFDRCxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRTtZQUNkLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2xCLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUNaO2FBQU07WUFDTCxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNuQjtRQUVELElBQUksT0FBc0IsQ0FBQztRQUMzQixRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ25CLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLO2dCQUFFLE9BQU87WUFDakMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLHFCQUFxQjtZQUN2QyxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsU0FBUyxFQUFFLEtBQUssR0FBRyxNQUFNLENBQUMsU0FBUyxFQUFFLE9BQU8sR0FBRyxHQUFHLENBQUMsQ0FBQyxZQUFZO1lBQ25GLDZFQUE2RTtZQUM3RSwwRUFBMEU7WUFDMUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxhQUFhO2dCQUM5QixLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ3JDO2lCQUFNLElBQUksRUFBRSxDQUFDLENBQUMsR0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEdBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLGFBQWE7Z0JBQy9DLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDdEM7WUFDRCxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLGdCQUFnQjtnQkFDakMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUNyQztpQkFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxpQkFBaUI7Z0JBQ25ELEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDdEM7WUFDRCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxJQUFJLElBQUksR0FBRyxPQUFPLEVBQUU7Z0JBQ2xCLE9BQU8sR0FBRyxJQUFJLENBQUM7Z0JBQ2YsT0FBTyxHQUFHLENBQUMsQ0FBQzthQUNiO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxDQUFDLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxDQUFDLDRDQUE0QztRQUNqRSxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsa0ZBQWtGO0lBQ2xGOzs7Ozs7Ozs7Ozs7OztNQWNFO0lBRUYsMEZBQTBGO0lBQ25GLFVBQVUsQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFFLEdBQVcsRUFBRSxLQUFhLEVBQUUsTUFBYyxFQUFFLElBQVk7UUFFOUYsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDckIsQ0FBQyxDQUFDLEtBQUssR0FBRztZQUNSLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHO1lBQ2hCLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJO1lBQ2pCLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsS0FBSztZQUN6QixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLE1BQU07U0FDMUIsQ0FDRixDQUFDO1FBQ0YsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsd0hBQXdIO0lBQ2pILElBQUksQ0FBQyxDQUFnQixFQUFFLENBQWdCO1FBQzVDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRW5ELFNBQVMsT0FBTztZQUNkLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckIsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsa0JBQWtCO1lBQ3hDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNkLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CO2FBQy9DO2lCQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNyQixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjthQUMvQztpQkFBTTtnQkFDTCxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLHNCQUFzQjthQUN6QztZQUNELENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7WUFDM0IsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsSUFBSSxRQUFpQixDQUFDLENBQUMsMENBQTBDO1FBRWpFLGlEQUFpRDtRQUNqRCxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ25HLE9BQU8sT0FBTyxFQUFFLENBQUM7UUFDbkIsSUFBSSxRQUFRLEtBQUssS0FBSztZQUFFLE9BQU8sQ0FBQyxrQ0FBa0M7UUFFbEUsb0VBQW9FO1FBQ3BFLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ25GLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7YUFBRSxDQUFDLGtDQUFrQztZQUM5RSxPQUFPLE9BQU8sRUFBRSxDQUFDO1NBQ2xCO1FBQ0QsSUFBSSxRQUFRLEtBQUssS0FBSztZQUFFLE9BQU87UUFFL0IsOERBQThEO1FBQzlELElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ25GLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7YUFBRSxDQUFDLGtDQUFrQztZQUM5RSxPQUFPLE9BQU8sRUFBRSxDQUFDO1NBQ2xCO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU0sV0FBVyxDQUFDLENBQVMsRUFBRSxDQUFTLEVBQUUsQ0FBUyxFQUFFLENBQVM7UUFDM0QsSUFBSSxFQUFFLEdBQWtCLEVBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUMsQ0FBQztRQUNyRSxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQsc0RBQXNEO0lBQy9DLE9BQU87UUFDWixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUN6QyxJQUFJLENBQUMsV0FBVyxFQUFFO2FBQ2YsU0FBUyxFQUFFLENBQUM7UUFDZixJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQzNCLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsK0RBQStEO1FBQ2hGLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ2hCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO2FBQzFCO1lBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxnQ0FBZ0M7WUFDM0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsQ0FBQyx5QkFBeUI7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELCtHQUErRztJQUMvRyxJQUFXLEtBQUssQ0FBQyxHQUFZO1FBQzNCLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxHQUFHO1lBQUUsT0FBTztRQUNoQyxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxLQUFLLENBQUM7UUFDM0IsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNSLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUM3QjtJQUNILENBQUM7SUFFRCwwQkFBMEI7SUFDMUIsSUFBVyxLQUFLLEtBQWMsT0FBTyxJQUFJLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFNUQsK0dBQStHO0lBQ3hHLFNBQVMsQ0FBQyxHQUFZO1FBQzNCLElBQUksQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0RCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCwrR0FBK0c7SUFDckcsVUFBVTtRQUNsQixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFBRSxPQUFPLElBQUksQ0FBQztTQUFFO1FBQ3BDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLGdCQUFnQjtRQUVsQyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDZCx5QkFBeUI7WUFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3JCLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFBRSxPQUFPO2dCQUN0RSxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNmLE9BQU8sSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO29CQUN2QixFQUFFLElBQUksQ0FBQztvQkFDUCxJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDO29CQUNqRSxJQUFJLENBQUMsT0FBTyxFQUFFO3dCQUNaLENBQUMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO3dCQUNoQixDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztxQkFDWjtpQkFDRjtZQUNILENBQUMsQ0FBQyxDQUFDO1NBQ0o7YUFBTTtZQUNMLG1CQUFtQjtZQUNuQixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDMUIsSUFBSSxDQUFDLENBQUMsTUFBTTtvQkFBRSxPQUFPO2dCQUNyQixPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUNkLElBQUksSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ2pDLElBQUksVUFBVSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDO29CQUNoRixJQUFJLENBQUMsVUFBVTt3QkFBRSxNQUFNO29CQUN2QiwwRkFBMEY7b0JBQzFGLG9GQUFvRjtvQkFDcEYsNkJBQTZCO29CQUM3QixDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQztvQkFDMUIsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7aUJBQ1o7WUFDSCxDQUFDLENBQUMsQ0FBQztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLFdBQVcsQ0FBQyxJQUFtQixFQUFFLFFBQWtCO1FBQ3hELElBQUksR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsSUFBSSxlQUFlLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFaEQsaUdBQWlHO1FBQ2pHLElBQUksSUFBSSxDQUFDLENBQUMsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLENBQUMsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUU7WUFDdEYsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDMUI7UUFFRCw4Q0FBOEM7UUFDOUMsSUFBSSxRQUFRLEdBQWtCLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDO1FBQ3hELGNBQWMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFBRSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7U0FBRTtRQUNyRCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUFFLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztTQUFFO1FBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQUUsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO1NBQUU7UUFDekMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFM0IsaUhBQWlIO1FBQ2pILElBQUksT0FBTyxJQUFJLENBQUMsQ0FBQyxJQUFJLFFBQVEsRUFBRTtZQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUFFO1FBQzNELElBQUksT0FBTyxJQUFJLENBQUMsQ0FBQyxJQUFJLFFBQVEsRUFBRTtZQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUFFO1FBQzNELElBQUksT0FBTyxJQUFJLENBQUMsQ0FBQyxJQUFJLFFBQVEsRUFBRTtZQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUFFO1FBQzNELElBQUksT0FBTyxJQUFJLENBQUMsQ0FBQyxJQUFJLFFBQVEsRUFBRTtZQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUFFO1FBQzNELElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUFDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1NBQUU7UUFDckUsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FBRTtRQUNyRSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7U0FBRTtRQUMzQyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7U0FBRTtRQUUzQyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFD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QUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxlQUFlLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDMUMsSUFBSSxDQUFDLEdBQWtCLEVBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUM7UUFDM0QsSUFBSSxDQUFDLENBQUMsWUFBWSxFQUFFO1lBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQUMsQ0FBQyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FBRTtRQUN0RSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDcEQsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDNUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxDQUFDO1lBQ2QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7O1lBRTlCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVTLGVBQWUsQ0FBQyxDQUFnQixFQUFFLE1BQWM7UUFDeEQsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7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QUM5QjthQUFNLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUMzQixnRUFBZ0U7WUFDaEUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2YsT0FBTyxFQUFFLENBQUMsYUFBYSxDQUFDO1lBQ3hCLHlDQUF5QztZQUN6QyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQzlCO0lBQ0gsQ0FBQztJQUVELHdCQUF3QjtJQUNqQixNQUFNLEtBQWdCLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDOztBQXJsRXBILG1FQUFtRTtBQUNyRCxlQUFLLEdBQUcsS0FBSyxDQUFDO0FBRTVCLHFFQUFxRTtBQUN2RCxnQkFBTSxHQUFHLGVBQWUsQ0FBQztBQXk3Q2hDLGVBQUssR0FBRyxPQUFPLENBQUM7QUFqakRIIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vR3JpZFN0YWNrLy4vc3JjL3V0aWxzLnRzPzdkZGEiLCJ3ZWJwYWNrOi8vR3JpZFN0YWNrLy4vc3JjL2dyaWRzdGFjay1lbmdpbmUudHM/MDcwZSIsIndlYnBhY2s6Ly9HcmlkU3RhY2svLi9zcmMvdHlwZXMudHM/YTc2ZCIsIndlYnBhY2s6Ly9HcmlkU3RhY2svLi9zcmMvZGQtbWFuYWdlci50cz8zZmUyIiwid2VicGFjazovL0dyaWRTdGFjay8uL3NyYy9kZC10b3VjaC50cz8wY2M5Iiwid2VicGFjazovL0dyaWRTdGFjay8uL3NyYy9kZC1yZXNpemFibGUtaGFuZGxlLnRzP2YzZTUiLCJ3ZWJwYWNrOi8vR3JpZFN0YWNrLy4vc3JjL2RkLWJhc2UtaW1wbC50cz9kN2M5Iiwid2VicGFjazovL0dyaWRTdGFjay8uL3NyYy9kZC1yZXNpemFibGUudHM/NDI0NCIsIndlYnBhY2s6Ly9HcmlkU3RhY2svLi9zcmMvZGQtZHJhZ2dhYmxlLnRzP2YzNjUiLCJ3ZWJwYWNrOi8vR3JpZFN0YWNrLy4vc3JjL2RkLWRyb3BwYWJsZS50cz9mZDVhIiwid2VicGFjazovL0dyaWRTdGFjay8uL3NyYy9kZC1lbGVtZW50LnRzPzA1OTYiLCJ3ZWJwYWNrOi8vR3JpZFN0YWNrLy4vc3JjL2RkLWdyaWRzdGFjay50cz8yYzMyIiwid2VicGFjazovL0dyaWRTdGFjay8uL3NyYy9ncmlkc3RhY2sudHM/YTZhOCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogdXRpbHMudHMgOC4yLjJcclxuICogQ29weXJpZ2h0IChjKSAyMDIxIEFsYWluIER1bWVzbnkgLSBzZWUgR3JpZFN0YWNrIHJvb3QgbGljZW5zZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IEdyaWRTdGFja0VsZW1lbnQsIEdyaWRTdGFja05vZGUsIEdyaWRTdGFja09wdGlvbnMsIG51bWJlck9yU3RyaW5nLCBHcmlkU3RhY2tQb3NpdGlvbiwgR3JpZFN0YWNrV2lkZ2V0IH0gZnJvbSAnLi90eXBlcyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEhlaWdodERhdGEge1xyXG4gIGg6IG51bWJlcjtcclxuICB1bml0OiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKiBjaGVja3MgZm9yIG9ic29sZXRlIG1ldGhvZCBuYW1lcyAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuZXhwb3J0IGZ1bmN0aW9uIG9ic29sZXRlKHNlbGYsIGYsIG9sZE5hbWU6IHN0cmluZywgbmV3TmFtZTogc3RyaW5nLCByZXY6IHN0cmluZyk6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55IHtcclxuICBsZXQgd3JhcHBlciA9ICguLi5hcmdzKSA9PiB7XHJcbiAgICBjb25zb2xlLndhcm4oJ2dyaWRzdGFjay5qczogRnVuY3Rpb24gYCcgKyBvbGROYW1lICsgJ2AgaXMgZGVwcmVjYXRlZCBpbiAnICsgcmV2ICsgJyBhbmQgaGFzIGJlZW4gcmVwbGFjZWQgJyArXHJcbiAgICAnd2l0aCBgJyArIG5ld05hbWUgKyAnYC4gSXQgd2lsbCBiZSAqKnJlbW92ZWQqKiBpbiBhIGZ1dHVyZSByZWxlYXNlJyk7XHJcbiAgICByZXR1cm4gZi5hcHBseShzZWxmLCBhcmdzKTtcclxuICB9XHJcbiAgd3JhcHBlci5wcm90b3R5cGUgPSBmLnByb3RvdHlwZTtcclxuICByZXR1cm4gd3JhcHBlcjtcclxufVxyXG5cclxuLyoqIGNoZWNrcyBmb3Igb2Jzb2xldGUgZ3JpZCBvcHRpb25zIChjYW4gYmUgdXNlZCBmb3IgYW55IGZpZWxkcywgYnV0IG1zZyBpcyBhYm91dCBvcHRpb25zKSAqL1xyXG5leHBvcnQgZnVuY3Rpb24gb2Jzb2xldGVPcHRzKG9wdHM6IEdyaWRTdGFja09wdGlvbnMsIG9sZE5hbWU6IHN0cmluZywgbmV3TmFtZTogc3RyaW5nLCByZXY6IHN0cmluZyk6IHZvaWQge1xyXG4gIGlmIChvcHRzW29sZE5hbWVdICE9PSB1bmRlZmluZWQpIHtcclxuICAgIG9wdHNbbmV3TmFtZV0gPSBvcHRzW29sZE5hbWVdO1xyXG4gICAgY29uc29sZS53YXJuKCdncmlkc3RhY2suanM6IE9wdGlvbiBgJyArIG9sZE5hbWUgKyAnYCBpcyBkZXByZWNhdGVkIGluICcgKyByZXYgKyAnIGFuZCBoYXMgYmVlbiByZXBsYWNlZCB3aXRoIGAnICtcclxuICAgICAgbmV3TmFtZSArICdgLiBJdCB3aWxsIGJlICoqcmVtb3ZlZCoqIGluIGEgZnV0dXJlIHJlbGVhc2UnKTtcclxuICB9XHJcbn1cclxuXHJcbi8qKiBjaGVja3MgZm9yIG9ic29sZXRlIGdyaWQgb3B0aW9ucyB3aGljaCBhcmUgZ29uZSAqL1xyXG5leHBvcnQgZnVuY3Rpb24gb2Jzb2xldGVPcHRzRGVsKG9wdHM6IEdyaWRTdGFja09wdGlvbnMsIG9sZE5hbWU6IHN0cmluZywgcmV2OiBzdHJpbmcsIGluZm86IHN0cmluZyk6IHZvaWQge1xyXG4gIGlmIChvcHRzW29sZE5hbWVdICE9PSB1bmRlZmluZWQpIHtcclxuICAgIGNvbnNvbGUud2FybignZ3JpZHN0YWNrLmpzOiBPcHRpb24gYCcgKyBvbGROYW1lICsgJ2AgaXMgZGVwcmVjYXRlZCBpbiAnICsgcmV2ICsgaW5mbyk7XHJcbiAgfVxyXG59XHJcblxyXG4vKiogY2hlY2tzIGZvciBvYnNvbGV0ZSBKcXVlcnkgZWxlbWVudCBhdHRyaWJ1dGVzICovXHJcbmV4cG9ydCBmdW5jdGlvbiBvYnNvbGV0ZUF0dHIoZWw6IEhUTUxFbGVtZW50LCBvbGROYW1lOiBzdHJpbmcsIG5ld05hbWU6IHN0cmluZywgcmV2OiBzdHJpbmcpOiB2b2lkIHtcclxuICBsZXQgb2xkQXR0ciA9IGVsLmdldEF0dHJpYnV0ZShvbGROYW1lKTtcclxuICBpZiAob2xkQXR0ciAhPT0gbnVsbCkge1xyXG4gICAgZWwuc2V0QXR0cmlidXRlKG5ld05hbWUsIG9sZEF0dHIpO1xyXG4gICAgY29uc29sZS53YXJuKCdncmlkc3RhY2suanM6IGF0dHJpYnV0ZSBgJyArIG9sZE5hbWUgKyAnYD0nICsgb2xkQXR0ciArICcgaXMgZGVwcmVjYXRlZCBvbiB0aGlzIG9iamVjdCBpbiAnICsgcmV2ICsgJyBhbmQgaGFzIGJlZW4gcmVwbGFjZWQgd2l0aCBgJyArXHJcbiAgICAgIG5ld05hbWUgKyAnYC4gSXQgd2lsbCBiZSAqKnJlbW92ZWQqKiBpbiBhIGZ1dHVyZSByZWxlYXNlJyk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogVXRpbGl0eSBtZXRob2RzXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgVXRpbHMge1xyXG5cclxuICAvKiogY29udmVydCBhIHBvdGVudGlhbCBzZWxlY3RvciBpbnRvIGFjdHVhbCBsaXN0IG9mIGh0bWwgZWxlbWVudHMuIG9wdGlvbmFsIHJvb3Qgd2hpY2ggZGVmYXVsdHMgdG8gZG9jdW1lbnQgKGZvciBzaGFkb3cgZG9tKSAqL1xyXG4gIHN0YXRpYyBnZXRFbGVtZW50cyhlbHM6IEdyaWRTdGFja0VsZW1lbnQsIHJvb3Q6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgPSBkb2N1bWVudCk6IEhUTUxFbGVtZW50W10ge1xyXG4gICAgaWYgKHR5cGVvZiBlbHMgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIGNvbnN0IGRvYyA9ICgnZ2V0RWxlbWVudEJ5SWQnIGluIHJvb3QpID8gcm9vdCBhcyBEb2N1bWVudCA6IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIC8vIE5vdGU6IHZlcnkgY29tbW9uIGZvciBwZW9wbGUgdXNlIHRvIGlkPScxLDIsMycgd2hpY2ggaXMgb25seSBsZWdhbCBhcyBIVE1MNSBpZCwgYnV0IG5vdCBDU1Mgc2VsZWN0b3JzXHJcbiAgICAgIC8vIHNvIGlmIHdlIHN0YXJ0IHdpdGggYSBudW1iZXIsIGFzc3VtZSBpdCdzIGFuIGlkIGFuZCBqdXN0IHJldHVybiB0aGF0IG9uZSBpdGVtLi4uXHJcbiAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ3JpZHN0YWNrL2dyaWRzdGFjay5qcy9pc3N1ZXMvMjIzNCNpc3N1ZWNvbW1lbnQtMTUyMzc5NjU2MlxyXG4gICAgICBpZiAoZG9jICYmICFpc05hTigrZWxzWzBdKSkgeyAvLyBzdGFydCB3aXRoIGRpZ2l0XHJcbiAgICAgICAgY29uc3QgZWwgPSBkb2MuZ2V0RWxlbWVudEJ5SWQoZWxzKTtcclxuICAgICAgICByZXR1cm4gZWwgPyBbZWxdIDogW107XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGxldCBsaXN0ID0gcm9vdC5xdWVyeVNlbGVjdG9yQWxsKGVscyk7XHJcbiAgICAgIGlmICghbGlzdC5sZW5ndGggJiYgZWxzWzBdICE9PSAnLicgJiYgZWxzWzBdICE9PSAnIycpIHtcclxuICAgICAgICBsaXN0ID0gcm9vdC5xdWVyeVNlbGVjdG9yQWxsKCcuJyArIGVscyk7XHJcbiAgICAgICAgaWYgKCFsaXN0Lmxlbmd0aCkgeyBsaXN0ID0gcm9vdC5xdWVyeVNlbGVjdG9yQWxsKCcjJyArIGVscykgfVxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBBcnJheS5mcm9tKGxpc3QpIGFzIEhUTUxFbGVtZW50W107XHJcbiAgICB9XHJcbiAgICByZXR1cm4gW2Vsc107XHJcbiAgfVxyXG5cclxuICAvKiogY29udmVydCBhIHBvdGVudGlhbCBzZWxlY3RvciBpbnRvIGFjdHVhbCBzaW5nbGUgZWxlbWVudC4gb3B0aW9uYWwgcm9vdCB3aGljaCBkZWZhdWx0cyB0byBkb2N1bWVudCAoZm9yIHNoYWRvdyBkb20pICovXHJcbiAgc3RhdGljIGdldEVsZW1lbnQoZWxzOiBHcmlkU3RhY2tFbGVtZW50LCByb290OiBIVE1MRWxlbWVudCB8IERvY3VtZW50ID0gZG9jdW1lbnQpOiBIVE1MRWxlbWVudCB7XHJcbiAgICBpZiAodHlwZW9mIGVscyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgY29uc3QgZG9jID0gKCdnZXRFbGVtZW50QnlJZCcgaW4gcm9vdCkgPyByb290IGFzIERvY3VtZW50IDogdW5kZWZpbmVkO1xyXG4gICAgICBpZiAoIWVscy5sZW5ndGgpIHJldHVybiBudWxsO1xyXG4gICAgICBpZiAoZG9jICYmIGVsc1swXSA9PT0gJyMnKSB7XHJcbiAgICAgICAgcmV0dXJuIGRvYy5nZXRFbGVtZW50QnlJZChlbHMuc3Vic3RyaW5nKDEpKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoZWxzWzBdID09PSAnIycgfHwgZWxzWzBdID09PSAnLicgfHwgZWxzWzBdID09PSAnWycpIHtcclxuICAgICAgICByZXR1cm4gcm9vdC5xdWVyeVNlbGVjdG9yKGVscyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIGlmIHdlIHN0YXJ0IHdpdGggYSBkaWdpdCwgYXNzdW1lIGl0J3MgYW4gaWQgKGVycm9yIGNhbGxpbmcgcXVlcnlTZWxlY3RvcignIzEnKSkgYXMgY2xhc3MgYXJlIG5vdCB2YWxpZCBDU1NcclxuICAgICAgaWYgKGRvYyAmJiAhaXNOYU4oK2Vsc1swXSkpIHsgLy8gc3RhcnQgd2l0aCBkaWdpdFxyXG4gICAgICAgIHJldHVybiBkb2MuZ2V0RWxlbWVudEJ5SWQoZWxzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gZmluYWxseSB0cnkgc3RyaW5nLCB0aGVuIGlkLCB0aGVuIGNsYXNzXHJcbiAgICAgIGxldCBlbCA9IHJvb3QucXVlcnlTZWxlY3RvcihlbHMpO1xyXG4gICAgICBpZiAoZG9jICYmICFlbCkgeyBlbCA9IGRvYy5nZXRFbGVtZW50QnlJZChlbHMpIH1cclxuICAgICAgaWYgKCFlbCkgeyBlbCA9IHJvb3QucXVlcnlTZWxlY3RvcignLicgKyBlbHMpIH1cclxuICAgICAgcmV0dXJuIGVsIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGVscztcclxuICB9XHJcblxyXG4gIC8qKiByZXR1cm5zIHRydWUgaWYgYSBhbmQgYiBvdmVybGFwICovXHJcbiAgc3RhdGljIGlzSW50ZXJjZXB0ZWQoYTogR3JpZFN0YWNrUG9zaXRpb24sIGI6IEdyaWRTdGFja1Bvc2l0aW9uKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gIShhLnkgPj0gYi55ICsgYi5oIHx8IGEueSArIGEuaCA8PSBiLnkgfHwgYS54ICsgYS53IDw9IGIueCB8fCBhLnggPj0gYi54ICsgYi53KTtcclxuICB9XHJcblxyXG4gIC8qKiByZXR1cm5zIHRydWUgaWYgYSBhbmQgYiB0b3VjaCBlZGdlcyBvciBjb3JuZXJzICovXHJcbiAgc3RhdGljIGlzVG91Y2hpbmcoYTogR3JpZFN0YWNrUG9zaXRpb24sIGI6IEdyaWRTdGFja1Bvc2l0aW9uKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gVXRpbHMuaXNJbnRlcmNlcHRlZChhLCB7eDogYi54LTAuNSwgeTogYi55LTAuNSwgdzogYi53KzEsIGg6IGIuaCsxfSlcclxuICB9XHJcblxyXG4gIC8qKiByZXR1cm5zIHRoZSBhcmVhIGEgYW5kIGIgb3ZlcmxhcCAqL1xyXG4gIHN0YXRpYyBhcmVhSW50ZXJjZXB0KGE6IEdyaWRTdGFja1Bvc2l0aW9uLCBiOiBHcmlkU3RhY2tQb3NpdGlvbik6IG51bWJlciB7XHJcbiAgICBsZXQgeDAgPSAoYS54ID4gYi54KSA/IGEueCA6IGIueDtcclxuICAgIGxldCB4MSA9IChhLngrYS53IDwgYi54K2IudykgPyBhLngrYS53IDogYi54K2IudztcclxuICAgIGlmICh4MSA8PSB4MCkgcmV0dXJuIDA7IC8vIG5vIG92ZXJsYXBcclxuICAgIGxldCB5MCA9IChhLnkgPiBiLnkpID8gYS55IDogYi55O1xyXG4gICAgbGV0IHkxID0gKGEueSthLmggPCBiLnkrYi5oKSA/IGEueSthLmggOiBiLnkrYi5oO1xyXG4gICAgaWYgKHkxIDw9IHkwKSByZXR1cm4gMDsgLy8gbm8gb3ZlcmxhcFxyXG4gICAgcmV0dXJuICh4MS14MCkgKiAoeTEteTApO1xyXG4gIH1cclxuXHJcbiAgLyoqIHJldHVybnMgdGhlIGFyZWEgKi9cclxuICBzdGF0aWMgYXJlYShhOiBHcmlkU3RhY2tQb3NpdGlvbik6IG51bWJlciB7XHJcbiAgICByZXR1cm4gYS53ICogYS5oO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU29ydHMgYXJyYXkgb2Ygbm9kZXNcclxuICAgKiBAcGFyYW0gbm9kZXMgYXJyYXkgdG8gc29ydFxyXG4gICAqIEBwYXJhbSBkaXIgMSBmb3IgYXNjLCAtMSBmb3IgZGVzYyAob3B0aW9uYWwpXHJcbiAgICogQHBhcmFtIHdpZHRoIHdpZHRoIG9mIHRoZSBncmlkLiBJZiB1bmRlZmluZWQgdGhlIHdpZHRoIHdpbGwgYmUgY2FsY3VsYXRlZCBhdXRvbWF0aWNhbGx5IChvcHRpb25hbCkuXHJcbiAgICoqL1xyXG4gIHN0YXRpYyBzb3J0KG5vZGVzOiBHcmlkU3RhY2tOb2RlW10sIGRpcj86IC0xIHwgMSwgY29sdW1uPzogbnVtYmVyKTogR3JpZFN0YWNrTm9kZVtdIHtcclxuICAgIGNvbHVtbiA9IGNvbHVtbiB8fCBub2Rlcy5yZWR1Y2UoKGNvbCwgbikgPT4gTWF0aC5tYXgobi54ICsgbi53LCBjb2wpLCAwKSB8fCAxMjtcclxuICAgIGlmIChkaXIgPT09IC0xKVxyXG4gICAgICByZXR1cm4gbm9kZXMuc29ydCgoYSwgYikgPT4gKGIueCArIGIueSAqIGNvbHVtbiktKGEueCArIGEueSAqIGNvbHVtbikpO1xyXG4gICAgZWxzZVxyXG4gICAgICByZXR1cm4gbm9kZXMuc29ydCgoYiwgYSkgPT4gKGIueCArIGIueSAqIGNvbHVtbiktKGEueCArIGEueSAqIGNvbHVtbikpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogY3JlYXRlcyBhIHN0eWxlIHNoZWV0IHdpdGggc3R5bGUgaWQgdW5kZXIgZ2l2ZW4gcGFyZW50XHJcbiAgICogQHBhcmFtIGlkIHdpbGwgc2V0IHRoZSAnZ3Mtc3R5bGUtaWQnIGF0dHJpYnV0ZSB0byB0aGF0IGlkXHJcbiAgICogQHBhcmFtIHBhcmVudCB0byBpbnNlcnQgdGhlIHN0eWxlc2hlZXQgYXMgZmlyc3QgY2hpbGQsXHJcbiAgICogaWYgbm9uZSBzdXBwbGllZCBpdCB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoZSBkb2N1bWVudCBoZWFkIGluc3RlYWQuXHJcbiAgICovXHJcbiAgc3RhdGljIGNyZWF0ZVN0eWxlc2hlZXQoaWQ6IHN0cmluZywgcGFyZW50PzogSFRNTEVsZW1lbnQsIG9wdGlvbnM/OiB7IG5vbmNlPzogc3RyaW5nIH0pOiBDU1NTdHlsZVNoZWV0IHtcclxuICAgIGxldCBzdHlsZTogSFRNTFN0eWxlRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XHJcbiAgICBjb25zdCBub25jZSA9IG9wdGlvbnM/Lm5vbmNlXHJcbiAgICBpZiAobm9uY2UpIHN0eWxlLm5vbmNlID0gbm9uY2VcclxuICAgIHN0eWxlLnNldEF0dHJpYnV0ZSgndHlwZScsICd0ZXh0L2NzcycpO1xyXG4gICAgc3R5bGUuc2V0QXR0cmlidXRlKCdncy1zdHlsZS1pZCcsIGlkKTtcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XHJcbiAgICBpZiAoKHN0eWxlIGFzIGFueSkuc3R5bGVTaGVldCkgeyAvLyBUT0RPOiBvbmx5IENTU0ltcG9ydFJ1bGUgaGF2ZSB0aGF0IGFuZCBkaWZmZXJlbnQgYmVhc3QgPz9cclxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcclxuICAgICAgKHN0eWxlIGFzIGFueSkuc3R5bGVTaGVldC5jc3NUZXh0ID0gJyc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzdHlsZS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJykpOyAvLyBXZWJLaXQgaGFja1xyXG4gICAgfVxyXG4gICAgaWYgKCFwYXJlbnQpIHtcclxuICAgICAgLy8gZGVmYXVsdCB0byBoZWFkXHJcbiAgICAgIHBhcmVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF07XHJcbiAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChzdHlsZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHN0eWxlLCBwYXJlbnQuZmlyc3RDaGlsZCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gc3R5bGUuc2hlZXQgYXMgQ1NTU3R5bGVTaGVldDtcclxuICB9XHJcblxyXG4gIC8qKiByZW1vdmVkIHRoZSBnaXZlbiBzdHlsZXNoZWV0IGlkICovXHJcbiAgc3RhdGljIHJlbW92ZVN0eWxlc2hlZXQoaWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgbGV0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignU1RZTEVbZ3Mtc3R5bGUtaWQ9JyArIGlkICsgJ10nKTtcclxuICAgIGlmIChlbCAmJiBlbC5wYXJlbnROb2RlKSBlbC5yZW1vdmUoKTtcclxuICB9XHJcblxyXG4gIC8qKiBpbnNlcnRzIGEgQ1NTIHJ1bGUgKi9cclxuICBzdGF0aWMgYWRkQ1NTUnVsZShzaGVldDogQ1NTU3R5bGVTaGVldCwgc2VsZWN0b3I6IHN0cmluZywgcnVsZXM6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKHR5cGVvZiBzaGVldC5hZGRSdWxlID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIHNoZWV0LmFkZFJ1bGUoc2VsZWN0b3IsIHJ1bGVzKTtcclxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNoZWV0Lmluc2VydFJ1bGUgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgc2hlZXQuaW5zZXJ0UnVsZShgJHtzZWxlY3Rvcn17JHtydWxlc319YCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxyXG4gIHN0YXRpYyB0b0Jvb2wodjogdW5rbm93bik6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHR5cGVvZiB2ID09PSAnYm9vbGVhbicpIHtcclxuICAgICAgcmV0dXJuIHY7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIHYgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIHYgPSB2LnRvTG93ZXJDYXNlKCk7XHJcbiAgICAgIHJldHVybiAhKHYgPT09ICcnIHx8IHYgPT09ICdubycgfHwgdiA9PT0gJ2ZhbHNlJyB8fCB2ID09PSAnMCcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIEJvb2xlYW4odik7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgdG9OdW1iZXIodmFsdWU6IG51bGwgfCBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZS5sZW5ndGggPT09IDApID8gdW5kZWZpbmVkIDogTnVtYmVyKHZhbHVlKTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBwYXJzZUhlaWdodCh2YWw6IG51bWJlck9yU3RyaW5nKTogSGVpZ2h0RGF0YSB7XHJcbiAgICBsZXQgaDogbnVtYmVyO1xyXG4gICAgbGV0IHVuaXQgPSAncHgnO1xyXG4gICAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIGxldCBtYXRjaCA9IHZhbC5tYXRjaCgvXigtWzAtOV0rXFwuWzAtOV0rfFswLTldKlxcLlswLTldK3wtWzAtOV0rfFswLTldKykocHh8ZW18cmVtfHZofHZ3fCUpPyQvKTtcclxuICAgICAgaWYgKCFtYXRjaCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZWlnaHQnKTtcclxuICAgICAgfVxyXG4gICAgICB1bml0ID0gbWF0Y2hbMl0gfHwgJ3B4JztcclxuICAgICAgaCA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaCA9IHZhbDtcclxuICAgIH1cclxuICAgIHJldHVybiB7IGgsIHVuaXQgfTtcclxuICB9XHJcblxyXG4gIC8qKiBjb3BpZXMgdW5zZXQgZmllbGRzIGluIHRhcmdldCB0byB1c2UgdGhlIGdpdmVuIGRlZmF1bHQgc291cmNlcyB2YWx1ZXMgKi9cclxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcclxuICBzdGF0aWMgZGVmYXVsdHModGFyZ2V0LCAuLi5zb3VyY2VzKToge30ge1xyXG5cclxuICAgIHNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xyXG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBzb3VyY2UpIHtcclxuICAgICAgICBpZiAoIXNvdXJjZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSByZXR1cm47XHJcbiAgICAgICAgaWYgKHRhcmdldFtrZXldID09PSBudWxsIHx8IHRhcmdldFtrZXldID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XHJcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygc291cmNlW2tleV0gPT09ICdvYmplY3QnICYmIHR5cGVvZiB0YXJnZXRba2V5XSA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgIC8vIHByb3BlcnR5IGlzIGFuIG9iamVjdCwgcmVjdXJzaXZlbHkgYWRkIGl0J3MgZmllbGQgb3Zlci4uLiAjMTM3M1xyXG4gICAgICAgICAgdGhpcy5kZWZhdWx0cyh0YXJnZXRba2V5XSwgc291cmNlW2tleV0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHRhcmdldDtcclxuICB9XHJcblxyXG4gIC8qKiBnaXZlbiAyIG9iamVjdHMgcmV0dXJuIHRydWUgaWYgdGhleSBoYXZlIHRoZSBzYW1lIHZhbHVlcy4gQ2hlY2tzIGZvciBPYmplY3Qge30gaGF2aW5nIHNhbWUgZmllbGRzIGFuZCB2YWx1ZXMgKGp1c3QgMSBsZXZlbCBkb3duKSAqL1xyXG4gIHN0YXRpYyBzYW1lKGE6IHVua25vd24sIGI6IHVua25vd24pOiBib29sZWFuIHtcclxuICAgIGlmICh0eXBlb2YgYSAhPT0gJ29iamVjdCcpICByZXR1cm4gYSA9PSBiO1xyXG4gICAgaWYgKHR5cGVvZiBhICE9PSB0eXBlb2YgYikgcmV0dXJuIGZhbHNlO1xyXG4gICAgLy8gZWxzZSB3ZSBoYXZlIG9iamVjdCwgY2hlY2sganVzdCAxIGxldmVsIGRlZXAgZm9yIGJlaW5nIHNhbWUgdGhpbmdzLi4uXHJcbiAgICBpZiAoT2JqZWN0LmtleXMoYSkubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhiKS5sZW5ndGgpIHJldHVybiBmYWxzZTtcclxuICAgIGZvciAoY29uc3Qga2V5IGluIGEpIHtcclxuICAgICAgaWYgKGFba2V5XSAhPT0gYltrZXldKSByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIC8qKiBjb3BpZXMgb3ZlciBiIHNpemUgJiBwb3NpdGlvbiAoR3JpZFN0YWNrUG9zaXRpb24pLCBhbmQgb3B0aW9uYWxseSBtaW4vbWF4IGFzIHdlbGwgKi9cclxuICBzdGF0aWMgY29weVBvcyhhOiBHcmlkU3RhY2tXaWRnZXQsIGI6IEdyaWRTdGFja1dpZGdldCwgZG9NaW5NYXggPSBmYWxzZSk6IEdyaWRTdGFja1dpZGdldCB7XHJcbiAgICBpZiAoYi54ICE9PSB1bmRlZmluZWQpIGEueCA9IGIueDtcclxuICAgIGlmIChiLnkgIT09IHVuZGVmaW5lZCkgYS55ID0gYi55O1xyXG4gICAgaWYgKGIudyAhPT0gdW5kZWZpbmVkKSBhLncgPSBiLnc7XHJcbiAgICBpZiAoYi5oICE9PSB1bmRlZmluZWQpIGEuaCA9IGIuaDtcclxuICAgIGlmIChkb01pbk1heCkge1xyXG4gICAgICBpZiAoYi5taW5XKSBhLm1pblcgPSBiLm1pblc7XHJcbiAgICAgIGlmIChiLm1pbkgpIGEubWluSCA9IGIubWluSDtcclxuICAgICAgaWYgKGIubWF4VykgYS5tYXhXID0gYi5tYXhXO1xyXG4gICAgICBpZiAoYi5tYXhIKSBhLm1heEggPSBiLm1heEg7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYTtcclxuICB9XHJcblxyXG4gIC8qKiB0cnVlIGlmIGEgYW5kIGIgaGFzIHNhbWUgc2l6ZSAmIHBvc2l0aW9uICovXHJcbiAgc3RhdGljIHNhbWVQb3MoYTogR3JpZFN0YWNrUG9zaXRpb24sIGI6IEdyaWRTdGFja1Bvc2l0aW9uKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gYSAmJiBiICYmIGEueCA9PT0gYi54ICYmIGEueSA9PT0gYi55ICYmIGEudyA9PT0gYi53ICYmIGEuaCA9PT0gYi5oO1xyXG4gIH1cclxuXHJcbiAgLyoqIGdpdmVuIGEgbm9kZSwgbWFrZXMgc3VyZSBpdCdzIG1pbi9tYXggYXJlIHZhbGlkICovXHJcbiAgc3RhdGljIHNhbml0aXplTWluTWF4KG5vZGU6IEdyaWRTdGFja05vZGUpIHtcclxuICAgIC8vIHJlbW92ZSAwLCB1bmRlZmluZSwgbnVsbFxyXG4gICAgaWYgKCFub2RlLm1pblcpIHsgZGVsZXRlIG5vZGUubWluVzsgfVxyXG4gICAgaWYgKCFub2RlLm1pbkgpIHsgZGVsZXRlIG5vZGUubWluSDsgfVxyXG4gICAgaWYgKCFub2RlLm1heFcpIHsgZGVsZXRlIG5vZGUubWF4VzsgfVxyXG4gICAgaWYgKCFub2RlLm1heEgpIHsgZGVsZXRlIG5vZGUubWF4SDsgfVxyXG4gIH1cclxuXHJcbiAgLyoqIHJlbW92ZXMgZmllbGQgZnJvbSB0aGUgZmlyc3Qgb2JqZWN0IGlmIHNhbWUgYXMgdGhlIHNlY29uZCBvYmplY3RzIChsaWtlIGRpZmZpbmcpIGFuZCBpbnRlcm5hbCAnXycgZm9yIHNhdmluZyAqL1xyXG4gIHN0YXRpYyByZW1vdmVJbnRlcm5hbEFuZFNhbWUoYTogdW5rbm93biwgYjogdW5rbm93bik6dm9pZCB7XHJcbiAgICBpZiAodHlwZW9mIGEgIT09ICdvYmplY3QnIHx8IHR5cGVvZiBiICE9PSAnb2JqZWN0JykgcmV0dXJuO1xyXG4gICAgZm9yIChsZXQga2V5IGluIGEpIHtcclxuICAgICAgbGV0IHZhbCA9IGFba2V5XTtcclxuICAgICAgaWYgKGtleVswXSA9PT0gJ18nIHx8IHZhbCA9PT0gYltrZXldKSB7XHJcbiAgICAgICAgZGVsZXRlIGFba2V5XVxyXG4gICAgICB9IGVsc2UgaWYgKHZhbCAmJiB0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiBiW2tleV0gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGZvciAobGV0IGkgaW4gdmFsKSB7XHJcbiAgICAgICAgICBpZiAodmFsW2ldID09PSBiW2tleV1baV0gfHwgaVswXSA9PT0gJ18nKSB7IGRlbGV0ZSB2YWxbaV0gfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIU9iamVjdC5rZXlzKHZhbCkubGVuZ3RoKSB7IGRlbGV0ZSBhW2tleV0gfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogcmVtb3ZlcyBpbnRlcm5hbCBmaWVsZHMgJ18nIGFuZCBkZWZhdWx0IHZhbHVlcyBmb3Igc2F2aW5nICovXHJcbiAgc3RhdGljIHJlbW92ZUludGVybmFsRm9yU2F2ZShuOiBHcmlkU3RhY2tOb2RlLCByZW1vdmVFbCA9IHRydWUpOiB2b2lkIHtcclxuICAgIGZvciAobGV0IGtleSBpbiBuKSB7IGlmIChrZXlbMF0gPT09ICdfJyB8fCBuW2tleV0gPT09IG51bGwgfHwgbltrZXldID09PSB1bmRlZmluZWQgKSBkZWxldGUgbltrZXldOyB9XHJcbiAgICBkZWxldGUgbi5ncmlkO1xyXG4gICAgaWYgKHJlbW92ZUVsKSBkZWxldGUgbi5lbDtcclxuICAgIC8vIGRlbGV0ZSBkZWZhdWx0IHZhbHVlcyAod2lsbCBiZSByZS1jcmVhdGVkIG9uIHJlYWQpXHJcbiAgICBpZiAoIW4uYXV0b1Bvc2l0aW9uKSBkZWxldGUgbi5hdXRvUG9zaXRpb247XHJcbiAgICBpZiAoIW4ubm9SZXNpemUpIGRlbGV0ZSBuLm5vUmVzaXplO1xyXG4gICAgaWYgKCFuLm5vTW92ZSkgZGVsZXRlIG4ubm9Nb3ZlO1xyXG4gICAgaWYgKCFuLmxvY2tlZCkgZGVsZXRlIG4ubG9ja2VkO1xyXG4gICAgaWYgKG4udyA9PT0gMSB8fCBuLncgPT09IG4ubWluVykgZGVsZXRlIG4udztcclxuICAgIGlmIChuLmggPT09IDEgfHwgbi5oID09PSBuLm1pbkgpIGRlbGV0ZSBuLmg7XHJcbiAgfVxyXG5cclxuICAvKiogcmV0dXJuIHRoZSBjbG9zZXN0IHBhcmVudCAob3IgaXRzZWxmKSBtYXRjaGluZyB0aGUgZ2l2ZW4gY2xhc3MgKi9cclxuICBzdGF0aWMgY2xvc2VzdFVwQnlDbGFzcyhlbDogSFRNTEVsZW1lbnQsIG5hbWU6IHN0cmluZyk6IEhUTUxFbGVtZW50IHtcclxuICAgIHdoaWxlIChlbCkge1xyXG4gICAgICBpZiAoZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpKSByZXR1cm4gZWw7XHJcbiAgICAgIGVsID0gZWwucGFyZW50RWxlbWVudFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICAvKiogZGVsYXkgY2FsbGluZyB0aGUgZ2l2ZW4gZnVuY3Rpb24gZm9yIGdpdmVuIGRlbGF5LCBwcmV2ZW50aW5nIG5ldyBjYWxscyBmcm9tIGhhcHBlbmluZyB3aGlsZSB3YWl0aW5nICovXHJcbiAgc3RhdGljIHRocm90dGxlKGZ1bmM6ICgpID0+IHZvaWQsIGRlbGF5OiBudW1iZXIpOiAoKSA9PiB2b2lkIHtcclxuICAgIGxldCBpc1dhaXRpbmcgPSBmYWxzZTtcclxuICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xyXG4gICAgICBpZiAoIWlzV2FpdGluZykge1xyXG4gICAgICAgIGlzV2FpdGluZyA9IHRydWU7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IGZ1bmMoLi4uYXJncyk7IGlzV2FpdGluZyA9IGZhbHNlOyB9LCBkZWxheSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHN0YXRpYyByZW1vdmVQb3NpdGlvbmluZ1N0eWxlcyhlbDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcclxuICAgIGxldCBzdHlsZSA9IGVsLnN0eWxlO1xyXG4gICAgaWYgKHN0eWxlLnBvc2l0aW9uKSB7XHJcbiAgICAgIHN0eWxlLnJlbW92ZVByb3BlcnR5KCdwb3NpdGlvbicpO1xyXG4gICAgfVxyXG4gICAgaWYgKHN0eWxlLmxlZnQpIHtcclxuICAgICAgc3R5bGUucmVtb3ZlUHJvcGVydHkoJ2xlZnQnKTtcclxuICAgIH1cclxuICAgIGlmIChzdHlsZS50b3ApIHtcclxuICAgICAgc3R5bGUucmVtb3ZlUHJvcGVydHkoJ3RvcCcpO1xyXG4gICAgfVxyXG4gICAgaWYgKHN0eWxlLndpZHRoKSB7XHJcbiAgICAgIHN0eWxlLnJlbW92ZVByb3BlcnR5KCd3aWR0aCcpO1xyXG4gICAgfVxyXG4gICAgaWYgKHN0eWxlLmhlaWdodCkge1xyXG4gICAgICBzdHlsZS5yZW1vdmVQcm9wZXJ0eSgnaGVpZ2h0Jyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogQGludGVybmFsIHJldHVybnMgdGhlIHBhc3NlZCBlbGVtZW50IGlmIHNjcm9sbGFibGUsIGVsc2UgdGhlIGNsb3Nlc3QgcGFyZW50IHRoYXQgd2lsbCwgdXAgdG8gdGhlIGVudGlyZSBkb2N1bWVudCBzY3JvbGxpbmcgZWxlbWVudCAqL1xyXG4gIHN0YXRpYyBnZXRTY3JvbGxFbGVtZW50KGVsPzogSFRNTEVsZW1lbnQpOiBIVE1MRWxlbWVudCB7XHJcbiAgICBpZiAoIWVsKSByZXR1cm4gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudCBhcyBIVE1MRWxlbWVudCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7IC8vIElFIHN1cHBvcnRcclxuICAgIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbCk7XHJcbiAgICBjb25zdCBvdmVyZmxvd1JlZ2V4ID0gLyhhdXRvfHNjcm9sbCkvO1xyXG5cclxuICAgIGlmIChvdmVyZmxvd1JlZ2V4LnRlc3Qoc3R5bGUub3ZlcmZsb3cgKyBzdHlsZS5vdmVyZmxvd1kpKSB7XHJcbiAgICAgIHJldHVybiBlbDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmdldFNjcm9sbEVsZW1lbnQoZWwucGFyZW50RWxlbWVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogQGludGVybmFsICovXHJcbiAgc3RhdGljIHVwZGF0ZVNjcm9sbFBvc2l0aW9uKGVsOiBIVE1MRWxlbWVudCwgcG9zaXRpb246IHt0b3A6IG51bWJlcn0sIGRpc3RhbmNlOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIC8vIGlzIHdpZGdldCBpbiB2aWV3P1xyXG4gICAgbGV0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGxldCBpbm5lckhlaWdodE9yQ2xpZW50SGVpZ2h0ID0gKHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KTtcclxuICAgIGlmIChyZWN0LnRvcCA8IDAgfHxcclxuICAgICAgcmVjdC5ib3R0b20gPiBpbm5lckhlaWdodE9yQ2xpZW50SGVpZ2h0XHJcbiAgICApIHtcclxuICAgICAgLy8gc2V0IHNjcm9sbFRvcCBvZiBmaXJzdCBwYXJlbnQgdGhhdCBzY3JvbGxzXHJcbiAgICAgIC8vIGlmIHBhcmVudCBpcyBsYXJnZXIgdGhhbiBlbCwgc2V0IGFzIGxvdyBhcyBwb3NzaWJsZVxyXG4gICAgICAvLyB0byBnZXQgZW50aXJlIHdpZGdldCBvbiBzY3JlZW5cclxuICAgICAgbGV0IG9mZnNldERpZmZEb3duID0gcmVjdC5ib3R0b20gLSBpbm5lckhlaWdodE9yQ2xpZW50SGVpZ2h0O1xyXG4gICAgICBsZXQgb2Zmc2V0RGlmZlVwID0gcmVjdC50b3A7XHJcbiAgICAgIGxldCBzY3JvbGxFbCA9IHRoaXMuZ2V0U2Nyb2xsRWxlbWVudChlbCk7XHJcbiAgICAgIGlmIChzY3JvbGxFbCAhPT0gbnVsbCkge1xyXG4gICAgICAgIGxldCBwcmV2U2Nyb2xsID0gc2Nyb2xsRWwuc2Nyb2xsVG9wO1xyXG4gICAgICAgIGlmIChyZWN0LnRvcCA8IDAgJiYgZGlzdGFuY2UgPCAwKSB7XHJcbiAgICAgICAgICAvLyBtb3ZpbmcgdXBcclxuICAgICAgICAgIGlmIChlbC5vZmZzZXRIZWlnaHQgPiBpbm5lckhlaWdodE9yQ2xpZW50SGVpZ2h0KSB7XHJcbiAgICAgICAgICAgIHNjcm9sbEVsLnNjcm9sbFRvcCArPSBkaXN0YW5jZTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHNjcm9sbEVsLnNjcm9sbFRvcCArPSBNYXRoLmFicyhvZmZzZXREaWZmVXApID4gTWF0aC5hYnMoZGlzdGFuY2UpID8gZGlzdGFuY2UgOiBvZmZzZXREaWZmVXA7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChkaXN0YW5jZSA+IDApIHtcclxuICAgICAgICAgIC8vIG1vdmluZyBkb3duXHJcbiAgICAgICAgICBpZiAoZWwub2Zmc2V0SGVpZ2h0ID4gaW5uZXJIZWlnaHRPckNsaWVudEhlaWdodCkge1xyXG4gICAgICAgICAgICBzY3JvbGxFbC5zY3JvbGxUb3AgKz0gZGlzdGFuY2U7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBzY3JvbGxFbC5zY3JvbGxUb3AgKz0gb2Zmc2V0RGlmZkRvd24gPiBkaXN0YW5jZSA/IGRpc3RhbmNlIDogb2Zmc2V0RGlmZkRvd247XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIG1vdmUgd2lkZ2V0IHkgYnkgYW1vdW50IHNjcm9sbGVkXHJcbiAgICAgICAgcG9zaXRpb24udG9wICs9IHNjcm9sbEVsLnNjcm9sbFRvcCAtIHByZXZTY3JvbGw7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBpbnRlcm5hbCBGdW5jdGlvbiB1c2VkIHRvIHNjcm9sbCB0aGUgcGFnZS5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBldmVudCBgTW91c2VFdmVudGAgdGhhdCB0cmlnZ2VycyB0aGUgcmVzaXplXHJcbiAgICogQHBhcmFtIGVsIGBIVE1MRWxlbWVudGAgdGhhdCdzIGJlaW5nIHJlc2l6ZWRcclxuICAgKiBAcGFyYW0gZGlzdGFuY2UgRGlzdGFuY2UgZnJvbSB0aGUgViBlZGdlcyB0byBzdGFydCBzY3JvbGxpbmdcclxuICAgKi9cclxuICBzdGF0aWMgdXBkYXRlU2Nyb2xsUmVzaXplKGV2ZW50OiBNb3VzZUV2ZW50LCBlbDogSFRNTEVsZW1lbnQsIGRpc3RhbmNlOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGNvbnN0IHNjcm9sbEVsID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KGVsKTtcclxuICAgIGNvbnN0IGhlaWdodCA9IHNjcm9sbEVsLmNsaWVudEhlaWdodDtcclxuICAgIC8vICMxNzI3IGV2ZW50LmNsaWVudFkgaXMgcmVsYXRpdmUgdG8gdmlld3BvcnQsIHNvIG11c3QgY29tcGFyZSB0aGlzIGFnYWluc3QgcG9zaXRpb24gb2Ygc2Nyb2xsRWwgZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wXHJcbiAgICAvLyAjMTc0NSBTcGVjaWFsIHNpdHVhdGlvbiBpZiBzY3JvbGxFbCBpcyBkb2N1bWVudCAnaHRtbCc6IGhlcmUgYnJvd3NlciBzcGVjIHN0YXRlcyB0aGF0XHJcbiAgICAvLyBjbGllbnRIZWlnaHQgaXMgaGVpZ2h0IG9mIHZpZXdwb3J0LCBidXQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgaXMgcmVjdGFuZ2xlIG9mIGh0bWwgZWxlbWVudDtcclxuICAgIC8vIHRoaXMgZGlzY3JlcGFuY3kgYXJpc2VzIGJlY2F1c2UgaW4gcmVhbGl0eSBzY3JvbGxiYXIgaXMgYXR0YWNoZWQgdG8gdmlld3BvcnQsIG5vdCBodG1sIGVsZW1lbnQgaXRzZWxmLlxyXG4gICAgY29uc3Qgb2Zmc2V0VG9wID0gKHNjcm9sbEVsID09PSB0aGlzLmdldFNjcm9sbEVsZW1lbnQoKSkgPyAwIDogc2Nyb2xsRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wO1xyXG4gICAgY29uc3QgcG9pbnRlclBvc1kgPSBldmVudC5jbGllbnRZIC0gb2Zmc2V0VG9wO1xyXG4gICAgY29uc3QgdG9wID0gcG9pbnRlclBvc1kgPCBkaXN0YW5jZTtcclxuICAgIGNvbnN0IGJvdHRvbSA9IHBvaW50ZXJQb3NZID4gaGVpZ2h0IC0gZGlzdGFuY2U7XHJcblxyXG4gICAgaWYgKHRvcCkge1xyXG4gICAgICAvLyBUaGlzIGFsc28gY2FuIGJlIGRvbmUgd2l0aCBhIHRpbWVvdXQgdG8ga2VlcCBzY3JvbGxpbmcgd2hpbGUgdGhlIG1vdXNlIGlzXHJcbiAgICAgIC8vIGluIHRoZSBzY3JvbGxpbmcgem9uZS4gKHdpbGwgaGF2ZSBzbW9vdGhlciBiZWhhdmlvcilcclxuICAgICAgc2Nyb2xsRWwuc2Nyb2xsQnkoeyBiZWhhdmlvcjogJ3Ntb290aCcsIHRvcDogcG9pbnRlclBvc1kgLSBkaXN0YW5jZX0pO1xyXG4gICAgfSBlbHNlIGlmIChib3R0b20pIHtcclxuICAgICAgc2Nyb2xsRWwuc2Nyb2xsQnkoeyBiZWhhdmlvcjogJ3Ntb290aCcsIHRvcDogZGlzdGFuY2UgLSAoaGVpZ2h0IC0gcG9pbnRlclBvc1kpfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogc2luZ2xlIGxldmVsIGNsb25lLCByZXR1cm5pbmcgYSBuZXcgb2JqZWN0IHdpdGggc2FtZSB0b3AgZmllbGRzLiBUaGlzIHdpbGwgc2hhcmUgc3ViIG9iamVjdHMgYW5kIGFycmF5cyAqL1xyXG4gIHN0YXRpYyBjbG9uZTxUPihvYmo6IFQpOiBUIHtcclxuICAgIGlmIChvYmogPT09IG51bGwgfHwgb2JqID09PSB1bmRlZmluZWQgfHwgdHlwZW9mKG9iaikgIT09ICdvYmplY3QnKSB7XHJcbiAgICAgIHJldHVybiBvYmo7XHJcbiAgICB9XHJcbiAgICAvLyByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgb2JqKTtcclxuICAgIGlmIChvYmogaW5zdGFuY2VvZiBBcnJheSkge1xyXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxyXG4gICAgICByZXR1cm4gWy4uLm9ial0gYXMgYW55O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHsuLi5vYmp9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVjdXJzaXZlIGNsb25lIHZlcnNpb24gdGhhdCByZXR1cm5zIGEgZnVsbCBjb3B5LCBjaGVja2luZyBmb3IgbmVzdGVkIG9iamVjdHMgYW5kIGFycmF5cyBPTkxZLlxyXG4gICAqIE5vdGU6IHRoaXMgd2lsbCB1c2UgYXMtaXMgYW55IGtleSBzdGFydGluZyB3aXRoIGRvdWJsZSBfXyAoYW5kIG5vdCBjb3B5IGluc2lkZSkgc29tZSBsaWIgaGF2ZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMuXHJcbiAgICovXHJcbiAgc3RhdGljIGNsb25lRGVlcDxUPihvYmo6IFQpOiBUIHtcclxuICAgIC8vIGxpc3Qgb2YgZmllbGRzIHdlIHdpbGwgc2tpcCBkdXJpbmcgY2xvbmVEZWVwIChuZXN0ZWQgb2JqZWN0cywgb3RoZXIgaW50ZXJuYWwpXHJcbiAgICBjb25zdCBza2lwRmllbGRzID0gWydwYXJlbnRHcmlkJywgJ2VsJywgJ2dyaWQnLCAnc3ViR3JpZCcsICdlbmdpbmUnXTtcclxuICAgIC8vIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpOyAvLyBkb2Vzbid0IHdvcmsgd2l0aCBkYXRlIGZvcm1hdCA/XHJcbiAgICBjb25zdCByZXQgPSBVdGlscy5jbG9uZShvYmopO1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gcmV0KSB7XHJcbiAgICAgIC8vIE5PVEU6IHdlIGRvbid0IHN1cHBvcnQgZnVuY3Rpb24vY2lyY3VsYXIgZGVwZW5kZW5jaWVzIHNvIHNraXAgdGhvc2UgcHJvcGVydGllcyBmb3Igbm93Li4uXHJcbiAgICAgIGlmIChyZXQuaGFzT3duUHJvcGVydHkoa2V5KSAmJiB0eXBlb2YocmV0W2tleV0pID09PSAnb2JqZWN0JyAmJiBrZXkuc3Vic3RyaW5nKDAsIDIpICE9PSAnX18nICYmICFza2lwRmllbGRzLmZpbmQoayA9PiBrID09PSBrZXkpKSB7XHJcbiAgICAgICAgcmV0W2tleV0gPSBVdGlscy5jbG9uZURlZXAob2JqW2tleV0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmV0O1xyXG4gIH1cclxuXHJcbiAgLyoqIGRlZXAgY2xvbmUgdGhlIGdpdmVuIEhUTUwgbm9kZSwgcmVtb3ZpbmcgdGVoIHVuaXF1ZSBpZCBmaWVsZCAqL1xyXG4gIHB1YmxpYyBzdGF0aWMgY2xvbmVOb2RlKGVsOiBIVE1MRWxlbWVudCk6IEhUTUxFbGVtZW50IHtcclxuICAgIGNvbnN0IG5vZGUgPSBlbC5jbG9uZU5vZGUodHJ1ZSkgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZSgnaWQnKTtcclxuICAgIHJldHVybiBub2RlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHN0YXRpYyBhcHBlbmRUbyhlbDogSFRNTEVsZW1lbnQsIHBhcmVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQpOiB2b2lkIHtcclxuICAgIGxldCBwYXJlbnROb2RlOiBIVE1MRWxlbWVudDtcclxuICAgIGlmICh0eXBlb2YgcGFyZW50ID09PSAnc3RyaW5nJykge1xyXG4gICAgICBwYXJlbnROb2RlID0gVXRpbHMuZ2V0RWxlbWVudChwYXJlbnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcGFyZW50Tm9kZSA9IHBhcmVudDtcclxuICAgIH1cclxuICAgIGlmIChwYXJlbnROb2RlKSB7XHJcbiAgICAgIHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoZWwpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gcHVibGljIHN0YXRpYyBzZXRQb3NpdGlvblJlbGF0aXZlKGVsOiBIVE1MRWxlbWVudCk6IHZvaWQge1xyXG4gIC8vICAgaWYgKCEoL14oPzpyfGF8ZikvKS50ZXN0KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKS5wb3NpdGlvbikpIHtcclxuICAvLyAgICAgZWwuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XHJcbiAgLy8gICB9XHJcbiAgLy8gfVxyXG5cclxuICBwdWJsaWMgc3RhdGljIGFkZEVsU3R5bGVzKGVsOiBIVE1MRWxlbWVudCwgc3R5bGVzOiB7IFtwcm9wOiBzdHJpbmddOiBzdHJpbmcgfCBzdHJpbmdbXSB9KTogdm9pZCB7XHJcbiAgICBpZiAoc3R5bGVzIGluc3RhbmNlb2YgT2JqZWN0KSB7XHJcbiAgICAgIGZvciAoY29uc3QgcyBpbiBzdHlsZXMpIHtcclxuICAgICAgICBpZiAoc3R5bGVzLmhhc093blByb3BlcnR5KHMpKSB7XHJcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShzdHlsZXNbc10pKSB7XHJcbiAgICAgICAgICAgIC8vIHN1cHBvcnQgZmFsbGJhY2sgdmFsdWVcclxuICAgICAgICAgICAgKHN0eWxlc1tzXSBhcyBzdHJpbmdbXSkuZm9yRWFjaCh2YWwgPT4ge1xyXG4gICAgICAgICAgICAgIGVsLnN0eWxlW3NdID0gdmFsO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGVsLnN0eWxlW3NdID0gc3R5bGVzW3NdO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIHN0YXRpYyBpbml0RXZlbnQ8VD4oZTogRHJhZ0V2ZW50IHwgTW91c2VFdmVudCwgaW5mbzogeyB0eXBlOiBzdHJpbmc7IHRhcmdldD86IEV2ZW50VGFyZ2V0IH0pOiBUIHtcclxuICAgIGNvbnN0IGV2dCA9IHsgdHlwZTogaW5mby50eXBlIH07XHJcbiAgICBjb25zdCBvYmogPSB7XHJcbiAgICAgIGJ1dHRvbjogMCxcclxuICAgICAgd2hpY2g6IDAsXHJcbiAgICAgIGJ1dHRvbnM6IDEsXHJcbiAgICAgIGJ1YmJsZXM6IHRydWUsXHJcbiAgICAgIGNhbmNlbGFibGU6IHRydWUsXHJcbiAgICAgIHRhcmdldDogaW5mby50YXJnZXQgPyBpbmZvLnRhcmdldCA6IGUudGFyZ2V0XHJcbiAgICB9O1xyXG4gICAgLy8gZG9uJ3QgY2hlY2sgZm9yIGBpbnN0YW5jZW9mIERyYWdFdmVudGAgYXMgU2FmYXJpIHVzZSBNb3VzZUV2ZW50ICMxNTQwXHJcbiAgICBpZiAoKGUgYXMgRHJhZ0V2ZW50KS5kYXRhVHJhbnNmZXIpIHtcclxuICAgICAgZXZ0WydkYXRhVHJhbnNmZXInXSA9IChlIGFzIERyYWdFdmVudCkuZGF0YVRyYW5zZmVyOyAvLyB3b3JrYXJvdW5kICdyZWFkb25seScgZmllbGQuXHJcbiAgICB9XHJcbiAgICBbJ2FsdEtleScsJ2N0cmxLZXknLCdtZXRhS2V5Jywnc2hpZnRLZXknXS5mb3JFYWNoKHAgPT4gZXZ0W3BdID0gZVtwXSk7IC8vIGtleXNcclxuICAgIFsncGFnZVgnLCdwYWdlWScsJ2NsaWVudFgnLCdjbGllbnRZJywnc2NyZWVuWCcsJ3NjcmVlblknXS5mb3JFYWNoKHAgPT4gZXZ0W3BdID0gZVtwXSk7IC8vIHBvaW50IGluZm9cclxuICAgIHJldHVybiB7Li4uZXZ0LCAuLi5vYmp9IGFzIHVua25vd24gYXMgVDtcclxuICB9XHJcblxyXG4gIC8qKiBjb3BpZXMgdGhlIE1vdXNlRXZlbnQgcHJvcGVydGllcyBhbmQgc2VuZHMgaXQgYXMgYW5vdGhlciBldmVudCB0byB0aGUgZ2l2ZW4gdGFyZ2V0ICovXHJcbiAgcHVibGljIHN0YXRpYyBzaW11bGF0ZU1vdXNlRXZlbnQoZTogTW91c2VFdmVudCwgc2ltdWxhdGVkVHlwZTogc3RyaW5nLCB0YXJnZXQ/OiBFdmVudFRhcmdldCk6IHZvaWQge1xyXG4gICAgY29uc3Qgc2ltdWxhdGVkRXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnTW91c2VFdmVudHMnKTtcclxuICAgIHNpbXVsYXRlZEV2ZW50LmluaXRNb3VzZUV2ZW50KFxyXG4gICAgICBzaW11bGF0ZWRUeXBlLCAvLyB0eXBlXHJcbiAgICAgIHRydWUsICAgICAgICAgLy8gYnViYmxlc1xyXG4gICAgICB0cnVlLCAgICAgICAgIC8vIGNhbmNlbGFibGVcclxuICAgICAgd2luZG93LCAgICAgICAvLyB2aWV3XHJcbiAgICAgIDEsICAgICAgICAgICAgLy8gZGV0YWlsXHJcbiAgICAgIGUuc2NyZWVuWCwgICAgLy8gc2NyZWVuWFxyXG4gICAgICBlLnNjcmVlblksICAgIC8vIHNjcmVlbllcclxuICAgICAgZS5jbGllbnRYLCAgICAvLyBjbGllbnRYXHJcbiAgICAgIGUuY2xpZW50WSwgICAgLy8gY2xpZW50WVxyXG4gICAgICBlLmN0cmxLZXksICAgIC8vIGN0cmxLZXlcclxuICAgICAgZS5hbHRLZXksICAgICAvLyBhbHRLZXlcclxuICAgICAgZS5zaGlmdEtleSwgICAvLyBzaGlmdEtleVxyXG4gICAgICBlLm1ldGFLZXksICAgIC8vIG1ldGFLZXlcclxuICAgICAgMCwgICAgICAgICAgICAvLyBidXR0b25cclxuICAgICAgZS50YXJnZXQgICAgICAvLyByZWxhdGVkVGFyZ2V0XHJcbiAgICApO1xyXG4gICAgKHRhcmdldCB8fCBlLnRhcmdldCkuZGlzcGF0Y2hFdmVudChzaW11bGF0ZWRFdmVudCk7XHJcbiAgfVxyXG5cclxuICAvKiogcmV0dXJucyB0cnVlIGlmIGV2ZW50IGlzIGluc2lkZSB0aGUgZ2l2ZW4gZWxlbWVudCByZWN0YW5nbGUgKi9cclxuICAvLyBOb3RlOiBTYWZhcmkgTWFjIGhhcyBudWxsIGV2ZW50LnJlbGF0ZWRUYXJnZXQgd2hpY2ggY2F1c2VzICMxNjg0IHNvIGNoZWNrIGlmIERyYWdFdmVudCBpcyBpbnNpZGUgdGhlIGNvb3JkaW5hdGVzIGluc3RlYWRcclxuICAvLyAgICB0aGlzLmVsLmNvbnRhaW5zKGV2ZW50LnJlbGF0ZWRUYXJnZXQgYXMgSFRNTEVsZW1lbnQpXHJcbiAgLy8gcHVibGljIHN0YXRpYyBpbnNpZGUoZTogTW91c2VFdmVudCwgZWw6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XHJcbiAgLy8gICAvLyBzcmNFbGVtZW50LCB0b0VsZW1lbnQsIHRhcmdldDogYWxsIHNldCB0byBwbGFjZWhvbGRlciB3aGVuIGxlYXZpbmcgc2ltcGxlIGdyaWQsIHNvIHdlIGNhbid0IHVzZSB0aGF0IChDaHJvbWUpXHJcbiAgLy8gICBsZXQgdGFyZ2V0OiBIVE1MRWxlbWVudCA9IGUucmVsYXRlZFRhcmdldCB8fCAoZSBhcyBhbnkpLmZyb21FbGVtZW50O1xyXG4gIC8vICAgaWYgKCF0YXJnZXQpIHtcclxuICAvLyAgICAgY29uc3QgeyBib3R0b20sIGxlZnQsIHJpZ2h0LCB0b3AgfSA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gIC8vICAgICByZXR1cm4gKGUueCA8IHJpZ2h0ICYmIGUueCA+IGxlZnQgJiYgZS55IDwgYm90dG9tICYmIGUueSA+IHRvcCk7XHJcbiAgLy8gICB9XHJcbiAgLy8gICByZXR1cm4gZWwuY29udGFpbnModGFyZ2V0KTtcclxuICAvLyB9XHJcbn1cclxuIiwiLyoqXG4gKiBncmlkc3RhY2stZW5naW5lLnRzIDguMi4yXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjEtMjAyMiBBbGFpbiBEdW1lc255IC0gc2VlIEdyaWRTdGFjayByb290IGxpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgeyBVdGlscyB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgR3JpZFN0YWNrTm9kZSwgQ29sdW1uT3B0aW9ucywgR3JpZFN0YWNrUG9zaXRpb24sIEdyaWRTdGFja01vdmVPcHRzLCBTYXZlRmNuIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKiBjYWxsYmFjayB0byB1cGRhdGUgdGhlIERPTSBhdHRyaWJ1dGVzIHNpbmNlIHRoaXMgY2xhc3MgaXMgZ2VuZXJpYyAobm8gSFRNTCBvciBvdGhlciBpbmZvKSBmb3IgaXRlbXMgdGhhdCBjaGFuZ2VkIC0gc2VlIF9ub3RpZnkoKSAqL1xudHlwZSBPbkNoYW5nZUNCID0gKG5vZGVzOiBHcmlkU3RhY2tOb2RlW10pID0+IHZvaWQ7XG5cbi8qKiBvcHRpb25zIHVzZWQgZHVyaW5nIGNyZWF0aW9uIC0gc2ltaWxhciB0byBHcmlkU3RhY2tPcHRpb25zICovXG5leHBvcnQgaW50ZXJmYWNlIEdyaWRTdGFja0VuZ2luZU9wdGlvbnMge1xuICBjb2x1bW4/OiBudW1iZXI7XG4gIG1heFJvdz86IG51bWJlcjtcbiAgZmxvYXQ/OiBib29sZWFuO1xuICBub2Rlcz86IEdyaWRTdGFja05vZGVbXTtcbiAgb25DaGFuZ2U/OiBPbkNoYW5nZUNCO1xufVxuXG4vKipcbiAqIERlZmluZXMgdGhlIEdyaWRTdGFjayBlbmdpbmUgdGhhdCBkb2VzIG1vc3Qgbm8gRE9NIGdyaWQgbWFuaXB1bGF0aW9uLlxuICogU2VlIEdyaWRTdGFjayBtZXRob2RzIGFuZCB2YXJzIGZvciBkZXNjcmlwdGlvbnMuXG4gKlxuICogTk9URTogdmFsdWVzIHNob3VsZCBub3QgYmUgbW9kaWZpZWQgZGlyZWN0bHkgLSBjYWxsIHRoZSBtYWluIEdyaWRTdGFjayBBUEkgaW5zdGVhZFxuICovXG5leHBvcnQgY2xhc3MgR3JpZFN0YWNrRW5naW5lIHtcbiAgcHVibGljIGNvbHVtbjogbnVtYmVyO1xuICBwdWJsaWMgbWF4Um93OiBudW1iZXI7XG4gIHB1YmxpYyBub2RlczogR3JpZFN0YWNrTm9kZVtdO1xuICBwdWJsaWMgYWRkZWROb2RlczogR3JpZFN0YWNrTm9kZVtdID0gW107XG4gIHB1YmxpYyByZW1vdmVkTm9kZXM6IEdyaWRTdGFja05vZGVbXSA9IFtdO1xuICBwdWJsaWMgYmF0Y2hNb2RlOiBib29sZWFuO1xuICAvKiogQGludGVybmFsIGNhbGxiYWNrIHRvIHVwZGF0ZSB0aGUgRE9NIGF0dHJpYnV0ZXMgKi9cbiAgcHJvdGVjdGVkIG9uQ2hhbmdlOiBPbkNoYW5nZUNCO1xuICAvKiogQGludGVybmFsICovXG4gIHByb3RlY3RlZCBfZmxvYXQ6IGJvb2xlYW47XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF9wcmV2RmxvYXQ6IGJvb2xlYW47XG4gIC8qKiBAaW50ZXJuYWwgY2FjaGVkIGxheW91dHMgb2YgZGlmZmVyZW5jZSBjb2x1bW4gY291bnQgc28gd2UgY2FuIHJlc3RvcmUgYmFjayAoZWcgMTIgLT4gMSAtPiAxMikgKi9cbiAgcHJvdGVjdGVkIF9sYXlvdXRzPzogR3JpZFN0YWNrTm9kZVtdW107IC8vIG1hcHMgY29sdW1uICMgdG8gYXJyYXkgb2YgdmFsdWVzIG5vZGVzXG4gIC8qKiBAaW50ZXJuYWwgdHJ1ZSB3aGlsZSB3ZSBhcmUgcmVzaXppbmcgd2lkZ2V0cyBkdXJpbmcgY29sdW1uIHJlc2l6ZSB0byBza2lwIGNlcnRhaW4gcGFydHMgKi9cbiAgcHJvdGVjdGVkIF9pbkNvbHVtblJlc2l6ZTogYm9vbGVhbjtcbiAgLyoqIEBpbnRlcm5hbCB0cnVlIGlmIHdlIGhhdmUgc29tZSBpdGVtcyBsb2NrZWQgKi9cbiAgcHJvdGVjdGVkIF9oYXNMb2NrZWQ6IGJvb2xlYW47XG4gIC8qKiBAaW50ZXJuYWwgdW5pcXVlIGdsb2JhbCBpbnRlcm5hbCBfaWQgY291bnRlciAqL1xuICBwdWJsaWMgc3RhdGljIF9pZFNlcSA9IDA7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdHM6IEdyaWRTdGFja0VuZ2luZU9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuY29sdW1uID0gb3B0cy5jb2x1bW4gfHwgMTI7XG4gICAgdGhpcy5tYXhSb3cgPSBvcHRzLm1heFJvdztcbiAgICB0aGlzLl9mbG9hdCA9IG9wdHMuZmxvYXQ7XG4gICAgdGhpcy5ub2RlcyA9IG9wdHMubm9kZXMgfHwgW107XG4gICAgdGhpcy5vbkNoYW5nZSA9IG9wdHMub25DaGFuZ2U7XG4gIH1cblxuICBwdWJsaWMgYmF0Y2hVcGRhdGUoZmxhZyA9IHRydWUpOiBHcmlkU3RhY2tFbmdpbmUge1xuICAgIGlmICghIXRoaXMuYmF0Y2hNb2RlID09PSBmbGFnKSByZXR1cm4gdGhpcztcbiAgICB0aGlzLmJhdGNoTW9kZSA9IGZsYWc7XG4gICAgaWYgKGZsYWcpIHtcbiAgICAgIHRoaXMuX3ByZXZGbG9hdCA9IHRoaXMuX2Zsb2F0O1xuICAgICAgdGhpcy5fZmxvYXQgPSB0cnVlOyAvLyBsZXQgdGhpbmdzIGdvIGFueXdoZXJlIGZvciBub3cuLi4gd2lsbCByZXN0b3JlIGFuZCBwb3NzaWJseSByZXBvc2l0aW9uIGxhdGVyXG4gICAgICB0aGlzLnNhdmVJbml0aWFsKCk7IC8vIHNpbmNlIGJlZ2luIHVwZGF0ZSAod2hpY2ggaXMgY2FsbGVkIG11bHRpcGxlIHRpbWVzKSB3b24ndCBkbyB0aGlzXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2Zsb2F0ID0gdGhpcy5fcHJldkZsb2F0O1xuICAgICAgZGVsZXRlIHRoaXMuX3ByZXZGbG9hdDtcbiAgICAgIHRoaXMuX3BhY2tOb2RlcygpLl9ub3RpZnkoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyB1c2UgZW50aXJlIHJvdyBmb3IgaGl0dGluZyBhcmVhICh3aWxsIHVzZSBib3R0b20gcmV2ZXJzZSBzb3J0ZWQgZmlyc3QpIGlmIHdlIG5vdCBhY3RpdmVseSBtb3ZpbmcgRE9XTiBhbmQgZGlkbid0IGFscmVhZHkgc2tpcFxuICBwcm90ZWN0ZWQgX3VzZUVudGlyZVJvd0FyZWEobm9kZTogR3JpZFN0YWNrTm9kZSwgbm46IEdyaWRTdGFja1Bvc2l0aW9uKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICghdGhpcy5mbG9hdCB8fCB0aGlzLmJhdGNoTW9kZSAmJiAhdGhpcy5fcHJldkZsb2F0KSAmJiAhdGhpcy5faGFzTG9ja2VkICYmICghbm9kZS5fbW92aW5nIHx8IG5vZGUuX3NraXBEb3duIHx8IG5uLnkgPD0gbm9kZS55KTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgZml4IGNvbGxpc2lvbiBvbiBnaXZlbiAnbm9kZScsIGdvaW5nIHRvIGdpdmVuIG5ldyBsb2NhdGlvbiAnbm4nLCB3aXRoIG9wdGlvbmFsICdjb2xsaWRlJyBub2RlIGFscmVhZHkgZm91bmQuXG4gICAqIHJldHVybiB0cnVlIGlmIHdlIG1vdmVkLiAqL1xuICBwcm90ZWN0ZWQgX2ZpeENvbGxpc2lvbnMobm9kZTogR3JpZFN0YWNrTm9kZSwgbm4gPSBub2RlLCBjb2xsaWRlPzogR3JpZFN0YWNrTm9kZSwgb3B0OiBHcmlkU3RhY2tNb3ZlT3B0cyA9IHt9KTogYm9vbGVhbiB7XG4gICAgdGhpcy5zb3J0Tm9kZXMoLTEpOyAvLyBmcm9tIGxhc3QgdG8gZmlyc3QsIHNvIHJlY3Vyc2l2ZSBjb2xsaXNpb24gbW92ZSBpdGVtcyBpbiB0aGUgcmlnaHQgb3JkZXJcblxuICAgIGNvbGxpZGUgPSBjb2xsaWRlIHx8IHRoaXMuY29sbGlkZShub2RlLCBubik7IC8vIFJFQUwgYXJlYSBjb2xsaWRlIGZvciBzd2FwIGFuZCBza2lwIGlmIG5vbmUuLi5cbiAgICBpZiAoIWNvbGxpZGUpIHJldHVybiBmYWxzZTtcblxuICAgIC8vIHN3YXAgY2hlY2s6IGlmIHdlJ3JlIGFjdGl2ZWx5IG1vdmluZyBpbiBncmF2aXR5IG1vZGUsIHNlZSBpZiB3ZSBjb2xsaWRlIHdpdGggYW4gb2JqZWN0IHRoZSBzYW1lIHNpemVcbiAgICBpZiAobm9kZS5fbW92aW5nICYmICFvcHQubmVzdGVkICYmICF0aGlzLmZsb2F0KSB7XG4gICAgICBpZiAodGhpcy5zd2FwKG5vZGUsIGNvbGxpZGUpKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBkdXJpbmcgd2hpbGUoKSBjb2xsaXNpb25zIE1BS0UgU1VSRSB0byBjaGVjayBlbnRpcmUgcm93IHNvIGxhcmdlciBpdGVtcyBkb24ndCBsZWFwIGZyb2cgc21hbGwgb25lcyAocHVzaCB0aGVtIGFsbCBkb3duIHN0YXJ0aW5nIGxhc3QgaW4gZ3JpZClcbiAgICBsZXQgYXJlYSA9IG5uO1xuICAgIGlmICh0aGlzLl91c2VFbnRpcmVSb3dBcmVhKG5vZGUsIG5uKSkge1xuICAgICAgYXJlYSA9IHt4OiAwLCB3OiB0aGlzLmNvbHVtbiwgeTogbm4ueSwgaDogbm4uaH07XG4gICAgICBjb2xsaWRlID0gdGhpcy5jb2xsaWRlKG5vZGUsIGFyZWEsIG9wdC5za2lwKTsgLy8gZm9yY2UgbmV3IGhpdFxuICAgIH1cblxuICAgIGxldCBkaWRNb3ZlID0gZmFsc2U7XG4gICAgbGV0IG5ld09wdDogR3JpZFN0YWNrTW92ZU9wdHMgPSB7bmVzdGVkOiB0cnVlLCBwYWNrOiBmYWxzZX07XG4gICAgd2hpbGUgKGNvbGxpZGUgPSBjb2xsaWRlIHx8IHRoaXMuY29sbGlkZShub2RlLCBhcmVhLCBvcHQuc2tpcCkpIHsgLy8gY291bGQgY29sbGlkZSB3aXRoIG1vcmUgdGhhbiAxIGl0ZW0uLi4gc28gcmVwZWF0IGZvciBlYWNoXG4gICAgICBsZXQgbW92ZWQ6IGJvb2xlYW47XG4gICAgICAvLyBpZiBjb2xsaWRpbmcgd2l0aCBhIGxvY2tlZCBpdGVtIE9SIG1vdmluZyBkb3duIHdpdGggdG9wIGdyYXZpdHkgKGFuZCBjb2xsaWRlIGNvdWxkIG1vdmUgdXApIC0+IHNraXAgcGFzdCB0aGUgY29sbGlkZSxcbiAgICAgIC8vIGJ1dCByZW1lbWJlciB0aGF0IHNraXAgZG93biBzbyB3ZSBvbmx5IGRvIHRoaXMgb25jZSAoYW5kIHB1c2ggb3RoZXJzIG90aGVyd2lzZSkuXG4gICAgICBpZiAoY29sbGlkZS5sb2NrZWQgfHwgbm9kZS5fbW92aW5nICYmICFub2RlLl9za2lwRG93biAmJiBubi55ID4gbm9kZS55ICYmICF0aGlzLmZsb2F0ICYmXG4gICAgICAgIC8vIGNhbiB0YWtlIHNwYWNlIHdlIGhhZCwgb3IgYmVmb3JlIHdoZXJlIHdlJ3JlIGdvaW5nXG4gICAgICAgICghdGhpcy5jb2xsaWRlKGNvbGxpZGUsIHsuLi5jb2xsaWRlLCB5OiBub2RlLnl9LCBub2RlKSB8fCAhdGhpcy5jb2xsaWRlKGNvbGxpZGUsIHsuLi5jb2xsaWRlLCB5OiBubi55IC0gY29sbGlkZS5ofSwgbm9kZSkpKSB7XG4gICAgICAgIG5vZGUuX3NraXBEb3duID0gKG5vZGUuX3NraXBEb3duIHx8IG5uLnkgPiBub2RlLnkpO1xuICAgICAgICBtb3ZlZCA9IHRoaXMubW92ZU5vZGUobm9kZSwgey4uLm5uLCB5OiBjb2xsaWRlLnkgKyBjb2xsaWRlLmgsIC4uLm5ld09wdH0pO1xuICAgICAgICBpZiAoY29sbGlkZS5sb2NrZWQgJiYgbW92ZWQpIHtcbiAgICAgICAgICBVdGlscy5jb3B5UG9zKG5uLCBub2RlKTsgLy8gbW92aW5nIGFmdGVyIGxvY2sgYmVjb21lIG91ciBuZXcgZGVzaXJlZCBsb2NhdGlvblxuICAgICAgICB9IGVsc2UgaWYgKCFjb2xsaWRlLmxvY2tlZCAmJiBtb3ZlZCAmJiBvcHQucGFjaykge1xuICAgICAgICAgIC8vIHdlIG1vdmVkIGFmdGVyIGFuZCB3aWxsIHBhY2s6IGRvIGl0IG5vdyBhbmQga2VlcCB0aGUgb3JpZ2luYWwgZHJvcCBsb2NhdGlvbiwgYnV0IHBhc3QgdGhlIG9sZCBjb2xsaWRlIHRvIHNlZSB3aGF0IGVsc2Ugd2UgbWlnaHQgcHVzaCB3YXlcbiAgICAgICAgICB0aGlzLl9wYWNrTm9kZXMoKTtcbiAgICAgICAgICBubi55ID0gY29sbGlkZS55ICsgY29sbGlkZS5oO1xuICAgICAgICAgIFV0aWxzLmNvcHlQb3Mobm9kZSwgbm4pO1xuICAgICAgICB9XG4gICAgICAgIGRpZE1vdmUgPSBkaWRNb3ZlIHx8IG1vdmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gbW92ZSBjb2xsaWRlIGRvd24gKmFmdGVyKiB3aGVyZSB3ZSB3aWxsIGJlLCBpZ25vcmluZyB3aGVyZSB3ZSBhcmUgbm93IChkb24ndCBjb2xsaWRlIHdpdGggdXMpXG4gICAgICAgIG1vdmVkID0gdGhpcy5tb3ZlTm9kZShjb2xsaWRlLCB7Li4uY29sbGlkZSwgeTogbm4ueSArIG5uLmgsIHNraXA6IG5vZGUsIC4uLm5ld09wdH0pO1xuICAgICAgfVxuICAgICAgaWYgKCFtb3ZlZCkgeyByZXR1cm4gZGlkTW92ZTsgfSAvLyBicmVhayBpbmYgbG9vcCBpZiB3ZSBjb3VsZG4ndCBtb3ZlIGFmdGVyIGFsbCAoZXg6IG1heFJvdywgZml4ZWQpXG4gICAgICBjb2xsaWRlID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gZGlkTW92ZTtcbiAgfVxuXG4gIC8qKiByZXR1cm4gdGhlIG5vZGVzIHRoYXQgaW50ZXJjZXB0IHRoZSBnaXZlbiBub2RlLiBPcHRpb25hbGx5IGEgZGlmZmVyZW50IGFyZWEgY2FuIGJlIHVzZWQsIGFzIHdlbGwgYXMgYSBzZWNvbmQgbm9kZSB0byBza2lwICovXG4gIHB1YmxpYyBjb2xsaWRlKHNraXA6IEdyaWRTdGFja05vZGUsIGFyZWEgPSBza2lwLCBza2lwMj86IEdyaWRTdGFja05vZGUpOiBHcmlkU3RhY2tOb2RlIHtcbiAgICBjb25zdCBza2lwSWQgPSBza2lwLl9pZDtcbiAgICBjb25zdCBza2lwMklkID0gc2tpcDI/Ll9pZDtcbiAgICByZXR1cm4gdGhpcy5ub2Rlcy5maW5kKG4gPT4gbi5faWQgIT09IHNraXBJZCAmJiBuLl9pZCAhPT0gc2tpcDJJZCAmJiBVdGlscy5pc0ludGVyY2VwdGVkKG4sIGFyZWEpKTtcbiAgfVxuICBwdWJsaWMgY29sbGlkZUFsbChza2lwOiBHcmlkU3RhY2tOb2RlLCBhcmVhID0gc2tpcCwgc2tpcDI/OiBHcmlkU3RhY2tOb2RlKTogR3JpZFN0YWNrTm9kZVtdIHtcbiAgICBjb25zdCBza2lwSWQgPSBza2lwLl9pZDtcbiAgICBjb25zdCBza2lwMklkID0gc2tpcDI/Ll9pZDtcbiAgICByZXR1cm4gdGhpcy5ub2Rlcy5maWx0ZXIobiA9PiBuLl9pZCAhPT0gc2tpcElkICYmIG4uX2lkICE9PSBza2lwMklkICYmIFV0aWxzLmlzSW50ZXJjZXB0ZWQobiwgYXJlYSkpO1xuICB9XG5cbiAgLyoqIGRvZXMgYSBwaXhlbCBjb3ZlcmFnZSBjb2xsaXNpb24gYmFzZWQgb24gd2hlcmUgd2Ugc3RhcnRlZCwgcmV0dXJuaW5nIHRoZSBub2RlIHRoYXQgaGFzIHRoZSBtb3N0IGNvdmVyYWdlIHRoYXQgaXMgPjUwJSBtaWQgbGluZSAqL1xuICBwcm90ZWN0ZWQgZGlyZWN0aW9uQ29sbGlkZUNvdmVyYWdlKG5vZGU6IEdyaWRTdGFja05vZGUsIG86IEdyaWRTdGFja01vdmVPcHRzLCBjb2xsaWRlczogR3JpZFN0YWNrTm9kZVtdKTogR3JpZFN0YWNrTm9kZSB7XG4gICAgaWYgKCFvLnJlY3QgfHwgIW5vZGUuX3JlY3QpIHJldHVybjtcbiAgICBsZXQgcjAgPSBub2RlLl9yZWN0OyAvLyB3aGVyZSBzdGFydGVkXG4gICAgbGV0IHIgPSB7Li4uby5yZWN0fTsgLy8gd2hlcmUgd2UgYXJlXG5cbiAgICAvLyB1cGRhdGUgZHJhZ2dlZCByZWN0IHRvIHNob3cgd2hlcmUgaXQncyBjb21pbmcgZnJvbSAoYWJvdmUgb3IgYmVsb3csIGV0Yy4uLilcbiAgICBpZiAoci55ID4gcjAueSkge1xuICAgICAgci5oICs9IHIueSAtIHIwLnk7XG4gICAgICByLnkgPSByMC55O1xuICAgIH0gZWxzZSB7XG4gICAgICByLmggKz0gcjAueSAtIHIueTtcbiAgICB9XG4gICAgaWYgKHIueCA+IHIwLngpIHtcbiAgICAgIHIudyArPSByLnggLSByMC54O1xuICAgICAgci54ID0gcjAueDtcbiAgICB9IGVsc2Uge1xuICAgICAgci53ICs9IHIwLnggLSByLng7XG4gICAgfVxuXG4gICAgbGV0IGNvbGxpZGU6IEdyaWRTdGFja05vZGU7XG4gICAgY29sbGlkZXMuZm9yRWFjaChuID0+IHtcbiAgICAgIGlmIChuLmxvY2tlZCB8fCAhbi5fcmVjdCkgcmV0dXJuO1xuICAgICAgbGV0IHIyID0gbi5fcmVjdDsgLy8gb3ZlcmxhcHBpbmcgdGFyZ2V0XG4gICAgICBsZXQgeU92ZXIgPSBOdW1iZXIuTUFYX1ZBTFVFLCB4T3ZlciA9IE51bWJlci5NQVhfVkFMVUUsIG92ZXJNYXggPSAwLjU7IC8vIG5lZWQgPjUwJVxuICAgICAgLy8gZGVwZW5kaW5nIG9uIHdoaWNoIHNpZGUgd2Ugc3RhcnRlZCBmcm9tLCBjb21wdXRlIHRoZSBvdmVybGFwICUgb2YgY292ZXJhZ2VcbiAgICAgIC8vIChleDogZnJvbSBhYm92ZS9iZWxvdyB3ZSBvbmx5IGNvbXB1dGUgdGhlIG1heCBob3Jpem9udGFsIGxpbmUgY292ZXJhZ2UpXG4gICAgICBpZiAocjAueSA8IHIyLnkpIHsgLy8gZnJvbSBhYm92ZVxuICAgICAgICB5T3ZlciA9ICgoci55ICsgci5oKSAtIHIyLnkpIC8gcjIuaDtcbiAgICAgIH0gZWxzZSBpZiAocjAueStyMC5oID4gcjIueStyMi5oKSB7IC8vIGZyb20gYmVsb3dcbiAgICAgICAgeU92ZXIgPSAoKHIyLnkgKyByMi5oKSAtIHIueSkgLyByMi5oO1xuICAgICAgfVxuICAgICAgaWYgKHIwLnggPCByMi54KSB7IC8vIGZyb20gdGhlIGxlZnRcbiAgICAgICAgeE92ZXIgPSAoKHIueCArIHIudykgLSByMi54KSAvIHIyLnc7XG4gICAgICB9IGVsc2UgaWYgKHIwLngrcjAudyA+IHIyLngrcjIudykgeyAvLyBmcm9tIHRoZSByaWdodFxuICAgICAgICB4T3ZlciA9ICgocjIueCArIHIyLncpIC0gci54KSAvIHIyLnc7XG4gICAgICB9XG4gICAgICBsZXQgb3ZlciA9IE1hdGgubWluKHhPdmVyLCB5T3Zlcik7XG4gICAgICBpZiAob3ZlciA+IG92ZXJNYXgpIHtcbiAgICAgICAgb3Zlck1heCA9IG92ZXI7XG4gICAgICAgIGNvbGxpZGUgPSBuO1xuICAgICAgfVxuICAgIH0pO1xuICAgIG8uY29sbGlkZSA9IGNvbGxpZGU7IC8vIHNhdmUgaXQgc28gd2UgZG9uJ3QgaGF2ZSB0byBmaW5kIGl0IGFnYWluXG4gICAgcmV0dXJuIGNvbGxpZGU7XG4gIH1cblxuICAvKiogZG9lcyBhIHBpeGVsIGNvdmVyYWdlIHJldHVybmluZyB0aGUgbm9kZSB0aGF0IGhhcyB0aGUgbW9zdCBjb3ZlcmFnZSBieSBhcmVhICovXG4gIC8qXG4gIHByb3RlY3RlZCBjb2xsaWRlQ292ZXJhZ2UocjogR3JpZFN0YWNrUG9zaXRpb24sIGNvbGxpZGVzOiBHcmlkU3RhY2tOb2RlW10pOiB7Y29sbGlkZTogR3JpZFN0YWNrTm9kZSwgb3ZlcjogbnVtYmVyfSB7XG4gICAgbGV0IGNvbGxpZGU6IEdyaWRTdGFja05vZGU7XG4gICAgbGV0IG92ZXJNYXggPSAwO1xuICAgIGNvbGxpZGVzLmZvckVhY2gobiA9PiB7XG4gICAgICBpZiAobi5sb2NrZWQgfHwgIW4uX3JlY3QpIHJldHVybjtcbiAgICAgIGxldCBvdmVyID0gVXRpbHMuYXJlYUludGVyY2VwdChyLCBuLl9yZWN0KTtcbiAgICAgIGlmIChvdmVyID4gb3Zlck1heCkge1xuICAgICAgICBvdmVyTWF4ID0gb3ZlcjtcbiAgICAgICAgY29sbGlkZSA9IG47XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHtjb2xsaWRlLCBvdmVyOiBvdmVyTWF4fTtcbiAgfVxuICAqL1xuXG4gIC8qKiBjYWxsZWQgdG8gY2FjaGUgdGhlIG5vZGVzIHBpeGVsIHJlY3RhbmdsZXMgdXNlZCBmb3IgY29sbGlzaW9uIGRldGVjdGlvbiBkdXJpbmcgZHJhZyAqL1xuICBwdWJsaWMgY2FjaGVSZWN0cyh3OiBudW1iZXIsIGg6IG51bWJlciwgdG9wOiBudW1iZXIsIHJpZ2h0OiBudW1iZXIsIGJvdHRvbTogbnVtYmVyLCBsZWZ0OiBudW1iZXIpOiBHcmlkU3RhY2tFbmdpbmVcbiAge1xuICAgIHRoaXMubm9kZXMuZm9yRWFjaChuID0+XG4gICAgICBuLl9yZWN0ID0ge1xuICAgICAgICB5OiBuLnkgKiBoICsgdG9wLFxuICAgICAgICB4OiBuLnggKiB3ICsgbGVmdCxcbiAgICAgICAgdzogbi53ICogdyAtIGxlZnQgLSByaWdodCxcbiAgICAgICAgaDogbi5oICogaCAtIHRvcCAtIGJvdHRvbVxuICAgICAgfVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogY2FsbGVkIHRvIHBvc3NpYmx5IHN3YXAgYmV0d2VlbiAyIG5vZGVzIChzYW1lIHNpemUgb3IgY29sdW1uLCBub3QgbG9ja2VkLCB0b3VjaGluZyksIHJldHVybmluZyB0cnVlIGlmIHN1Y2Nlc3NmdWwgKi9cbiAgcHVibGljIHN3YXAoYTogR3JpZFN0YWNrTm9kZSwgYjogR3JpZFN0YWNrTm9kZSk6IGJvb2xlYW4ge1xuICAgIGlmICghYiB8fCBiLmxvY2tlZCB8fCAhYSB8fCBhLmxvY2tlZCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgZnVuY3Rpb24gX2RvU3dhcCgpOiB0cnVlIHsgLy8gYXNzdW1lcyBhIGlzIGJlZm9yZSBiIElGRiB0aGV5IGhhdmUgZGlmZmVyZW50IGhlaWdodCAocHV0IGFmdGVyIHJhdGhlciB0aGFuIGV4YWN0IHN3YXApXG4gICAgICBsZXQgeCA9IGIueCwgeSA9IGIueTtcbiAgICAgIGIueCA9IGEueDsgYi55ID0gYS55OyAvLyBiIC0+IGEgcG9zaXRpb25cbiAgICAgIGlmIChhLmggIT0gYi5oKSB7XG4gICAgICAgIGEueCA9IHg7IGEueSA9IGIueSArIGIuaDsgLy8gYSAtPiBnb2VzIGFmdGVyIGJcbiAgICAgIH0gZWxzZSBpZiAoYS53ICE9IGIudykge1xuICAgICAgICBhLnggPSBiLnggKyBiLnc7IGEueSA9IHk7IC8vIGEgLT4gZ29lcyBhZnRlciBiXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhLnggPSB4OyBhLnkgPSB5OyAvLyBhIC0+IG9sZCBiIHBvc2l0aW9uXG4gICAgICB9XG4gICAgICBhLl9kaXJ0eSA9IGIuX2RpcnR5ID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBsZXQgdG91Y2hpbmc6IGJvb2xlYW47IC8vIHJlbWVtYmVyIGlmIHdlIGNhbGxlZCBpdCAodnMgdW5kZWZpbmVkKVxuXG4gICAgLy8gc2FtZSBzaXplIGFuZCBzYW1lIHJvdyBvciBjb2x1bW4sIGFuZCB0b3VjaGluZ1xuICAgIGlmIChhLncgPT09IGIudyAmJiBhLmggPT09IGIuaCAmJiAoYS54ID09PSBiLnggfHwgYS55ID09PSBiLnkpICYmICh0b3VjaGluZyA9IFV0aWxzLmlzVG91Y2hpbmcoYSwgYikpKVxuICAgICAgcmV0dXJuIF9kb1N3YXAoKTtcbiAgICBpZiAodG91Y2hpbmcgPT09IGZhbHNlKSByZXR1cm47IC8vIElGRiByYW4gdGVzdCBhbmQgZmFpbCwgYmFpbCBvdXRcblxuICAgIC8vIGNoZWNrIGZvciB0YWtpbmcgc2FtZSBjb2x1bW5zIChidXQgZGlmZmVyZW50IGhlaWdodCkgYW5kIHRvdWNoaW5nXG4gICAgaWYgKGEudyA9PT0gYi53ICYmIGEueCA9PT0gYi54ICYmICh0b3VjaGluZyB8fCAodG91Y2hpbmcgPSBVdGlscy5pc1RvdWNoaW5nKGEsIGIpKSkpIHtcbiAgICAgIGlmIChiLnkgPCBhLnkpIHsgbGV0IHQgPSBhOyBhID0gYjsgYiA9IHQ7IH0gLy8gc3dhcCBhIDwtPiBiIHZhcnMgc28gYSBpcyBmaXJzdFxuICAgICAgcmV0dXJuIF9kb1N3YXAoKTtcbiAgICB9XG4gICAgaWYgKHRvdWNoaW5nID09PSBmYWxzZSkgcmV0dXJuO1xuXG4gICAgLy8gY2hlY2sgaWYgdGFraW5nIHNhbWUgcm93IChidXQgZGlmZmVyZW50IHdpZHRoKSBhbmQgdG91Y2hpbmdcbiAgICBpZiAoYS5oID09PSBiLmggJiYgYS55ID09PSBiLnkgJiYgKHRvdWNoaW5nIHx8ICh0b3VjaGluZyA9IFV0aWxzLmlzVG91Y2hpbmcoYSwgYikpKSkge1xuICAgICAgaWYgKGIueCA8IGEueCkgeyBsZXQgdCA9IGE7IGEgPSBiOyBiID0gdDsgfSAvLyBzd2FwIGEgPC0+IGIgdmFycyBzbyBhIGlzIGZpcnN0XG4gICAgICByZXR1cm4gX2RvU3dhcCgpO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwdWJsaWMgaXNBcmVhRW1wdHkoeDogbnVtYmVyLCB5OiBudW1iZXIsIHc6IG51bWJlciwgaDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgbGV0IG5uOiBHcmlkU3RhY2tOb2RlID0ge3g6IHggfHwgMCwgeTogeSB8fCAwLCB3OiB3IHx8IDEsIGg6IGggfHwgMX07XG4gICAgcmV0dXJuICF0aGlzLmNvbGxpZGUobm4pO1xuICB9XG5cbiAgLyoqIHJlLWxheW91dCBncmlkIGl0ZW1zIHRvIHJlY2xhaW0gYW55IGVtcHR5IHNwYWNlICovXG4gIHB1YmxpYyBjb21wYWN0KCk6IEdyaWRTdGFja0VuZ2luZSB7XG4gICAgaWYgKHRoaXMubm9kZXMubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcztcbiAgICB0aGlzLmJhdGNoVXBkYXRlKClcbiAgICAgIC5zb3J0Tm9kZXMoKTtcbiAgICBsZXQgY29weU5vZGVzID0gdGhpcy5ub2RlcztcbiAgICB0aGlzLm5vZGVzID0gW107IC8vIHByZXRlbmQgd2UgaGF2ZSBubyBub2RlcyB0byBjb25mbGljdCBsYXlvdXQgdG8gc3RhcnQgd2l0aC4uLlxuICAgIGNvcHlOb2Rlcy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgaWYgKCFub2RlLmxvY2tlZCkge1xuICAgICAgICBub2RlLmF1dG9Qb3NpdGlvbiA9IHRydWU7XG4gICAgICB9XG4gICAgICB0aGlzLmFkZE5vZGUobm9kZSwgZmFsc2UpOyAvLyAnZmFsc2UnIGZvciBhZGQgZXZlbnQgdHJpZ2dlclxuICAgICAgbm9kZS5fZGlydHkgPSB0cnVlOyAvLyB3aWxsIGZvcmNlIGF0dHIgdXBkYXRlXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuYmF0Y2hVcGRhdGUoZmFsc2UpO1xuICB9XG5cbiAgLyoqIGVuYWJsZS9kaXNhYmxlIGZsb2F0aW5nIHdpZGdldHMgKGRlZmF1bHQ6IGBmYWxzZWApIFNlZSBbZXhhbXBsZV0oaHR0cDovL2dyaWRzdGFja2pzLmNvbS9kZW1vL2Zsb2F0Lmh0bWwpICovXG4gIHB1YmxpYyBzZXQgZmxvYXQodmFsOiBib29sZWFuKSB7XG4gICAgaWYgKHRoaXMuX2Zsb2F0ID09PSB2YWwpIHJldHVybjtcbiAgICB0aGlzLl9mbG9hdCA9IHZhbCB8fCBmYWxzZTtcbiAgICBpZiAoIXZhbCkge1xuICAgICAgdGhpcy5fcGFja05vZGVzKCkuX25vdGlmeSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBmbG9hdCBnZXR0ZXIgbWV0aG9kICovXG4gIHB1YmxpYyBnZXQgZmxvYXQoKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLl9mbG9hdCB8fCBmYWxzZTsgfVxuXG4gIC8qKiBzb3J0IHRoZSBub2RlcyBhcnJheSBmcm9tIGZpcnN0IHRvIGxhc3QsIG9yIHJldmVyc2UuIENhbGxlZCBkdXJpbmcgY29sbGlzaW9uL3BsYWNlbWVudCB0byBmb3JjZSBhbiBvcmRlciAqL1xuICBwdWJsaWMgc29ydE5vZGVzKGRpcj86IC0xIHwgMSk6IEdyaWRTdGFja0VuZ2luZSB7XG4gICAgdGhpcy5ub2RlcyA9IFV0aWxzLnNvcnQodGhpcy5ub2RlcywgZGlyLCB0aGlzLmNvbHVtbik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogQGludGVybmFsIGNhbGxlZCB0byB0b3AgZ3Jhdml0eSBwYWNrIHRoZSBpdGVtcyBiYWNrIE9SIHJldmVydCBiYWNrIHRvIG9yaWdpbmFsIFkgcG9zaXRpb25zIHdoZW4gZmxvYXRpbmcgKi9cbiAgcHJvdGVjdGVkIF9wYWNrTm9kZXMoKTogR3JpZFN0YWNrRW5naW5lIHtcbiAgICBpZiAodGhpcy5iYXRjaE1vZGUpIHsgcmV0dXJuIHRoaXM7IH1cbiAgICB0aGlzLnNvcnROb2RlcygpOyAvLyBmaXJzdCB0byBsYXN0XG5cbiAgICBpZiAodGhpcy5mbG9hdCkge1xuICAgICAgLy8gcmVzdG9yZSBvcmlnaW5hbCBZIHBvc1xuICAgICAgdGhpcy5ub2Rlcy5mb3JFYWNoKG4gPT4ge1xuICAgICAgICBpZiAobi5fdXBkYXRpbmcgfHwgbi5fb3JpZyA9PT0gdW5kZWZpbmVkIHx8IG4ueSA9PT0gbi5fb3JpZy55KSByZXR1cm47XG4gICAgICAgIGxldCBuZXdZID0gbi55O1xuICAgICAgICB3aGlsZSAobmV3WSA+IG4uX29yaWcueSkge1xuICAgICAgICAgIC0tbmV3WTtcbiAgICAgICAgICBsZXQgY29sbGlkZSA9IHRoaXMuY29sbGlkZShuLCB7eDogbi54LCB5OiBuZXdZLCB3OiBuLncsIGg6IG4uaH0pO1xuICAgICAgICAgIGlmICghY29sbGlkZSkge1xuICAgICAgICAgICAgbi5fZGlydHkgPSB0cnVlO1xuICAgICAgICAgICAgbi55ID0gbmV3WTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyB0b3AgZ3Jhdml0eSBwYWNrXG4gICAgICB0aGlzLm5vZGVzLmZvckVhY2goKG4sIGkpID0+IHtcbiAgICAgICAgaWYgKG4ubG9ja2VkKSByZXR1cm47XG4gICAgICAgIHdoaWxlIChuLnkgPiAwKSB7XG4gICAgICAgICAgbGV0IG5ld1kgPSBpID09PSAwID8gMCA6IG4ueSAtIDE7XG4gICAgICAgICAgbGV0IGNhbkJlTW92ZWQgPSBpID09PSAwIHx8ICF0aGlzLmNvbGxpZGUobiwge3g6IG4ueCwgeTogbmV3WSwgdzogbi53LCBoOiBuLmh9KTtcbiAgICAgICAgICBpZiAoIWNhbkJlTW92ZWQpIGJyZWFrO1xuICAgICAgICAgIC8vIE5vdGU6IG11c3QgYmUgZGlydHkgKGZyb20gbGFzdCBwb3NpdGlvbikgZm9yIEdyaWRTdGFjazo6T25DaGFuZ2UgQ0IgdG8gdXBkYXRlIHBvc2l0aW9uc1xuICAgICAgICAgIC8vIGFuZCBtb3ZlIGl0ZW1zIGJhY2suIFRoZSB1c2VyICdjaGFuZ2UnIENCIHNob3VsZCBkZXRlY3QgY2hhbmdlcyBmcm9tIHRoZSBvcmlnaW5hbFxuICAgICAgICAgIC8vIHN0YXJ0aW5nIHBvc2l0aW9uIGluc3RlYWQuXG4gICAgICAgICAgbi5fZGlydHkgPSAobi55ICE9PSBuZXdZKTtcbiAgICAgICAgICBuLnkgPSBuZXdZO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogZ2l2ZW4gYSByYW5kb20gbm9kZSwgbWFrZXMgc3VyZSBpdCdzIGNvb3JkaW5hdGVzL3ZhbHVlcyBhcmUgdmFsaWQgaW4gdGhlIGN1cnJlbnQgZ3JpZFxuICAgKiBAcGFyYW0gbm9kZSB0byBhZGp1c3RcbiAgICogQHBhcmFtIHJlc2l6aW5nIGlmIG91dCBvZiBib3VuZCwgcmVzaXplIGRvd24gb3IgbW92ZSBpbnRvIHRoZSBncmlkIHRvIGZpdCA/XG4gICAqL1xuICBwdWJsaWMgcHJlcGFyZU5vZGUobm9kZTogR3JpZFN0YWNrTm9kZSwgcmVzaXppbmc/OiBib29sZWFuKTogR3JpZFN0YWNrTm9kZSB7XG4gICAgbm9kZSA9IG5vZGUgfHwge307XG4gICAgbm9kZS5faWQgPSBub2RlLl9pZCA/PyBHcmlkU3RhY2tFbmdpbmUuX2lkU2VxKys7XG5cbiAgICAvLyBpZiB3ZSdyZSBtaXNzaW5nIHBvc2l0aW9uLCBoYXZlIHRoZSBncmlkIHBvc2l0aW9uIHVzIGF1dG9tYXRpY2FsbHkgKGJlZm9yZSB3ZSBzZXQgdGhlbSB0byAwLDApXG4gICAgaWYgKG5vZGUueCA9PT0gdW5kZWZpbmVkIHx8IG5vZGUueSA9PT0gdW5kZWZpbmVkIHx8IG5vZGUueCA9PT0gbnVsbCB8fCBub2RlLnkgPT09IG51bGwpIHtcbiAgICAgIG5vZGUuYXV0b1Bvc2l0aW9uID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpZ24gZGVmYXVsdHMgZm9yIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzXG4gICAgbGV0IGRlZmF1bHRzOiBHcmlkU3RhY2tOb2RlID0geyB4OiAwLCB5OiAwLCB3OiAxLCBoOiAxfTtcbiAgICBVdGlscy5kZWZhdWx0cyhub2RlLCBkZWZhdWx0cyk7XG5cbiAgICBpZiAoIW5vZGUuYXV0b1Bvc2l0aW9uKSB7IGRlbGV0ZSBub2RlLmF1dG9Qb3NpdGlvbjsgfVxuICAgIGlmICghbm9kZS5ub1Jlc2l6ZSkgeyBkZWxldGUgbm9kZS5ub1Jlc2l6ZTsgfVxuICAgIGlmICghbm9kZS5ub01vdmUpIHsgZGVsZXRlIG5vZGUubm9Nb3ZlOyB9XG4gICAgVXRpbHMuc2FuaXRpemVNaW5NYXgobm9kZSk7XG5cbiAgICAvLyBjaGVjayBmb3IgTmFOIChpbiBjYXNlIG1lc3NlZCB1cCBzdHJpbmdzIHdlcmUgcGFzc2VkLiBjYW4ndCBkbyBwYXJzZUludCgpIHx8IGRlZmF1bHRzLnggYWJvdmUgYXMgMCBpcyB2YWxpZCAjKVxuICAgIGlmICh0eXBlb2Ygbm9kZS54ID09ICdzdHJpbmcnKSB7IG5vZGUueCA9IE51bWJlcihub2RlLngpOyB9XG4gICAgaWYgKHR5cGVvZiBub2RlLnkgPT0gJ3N0cmluZycpIHsgbm9kZS55ID0gTnVtYmVyKG5vZGUueSk7IH1cbiAgICBpZiAodHlwZW9mIG5vZGUudyA9PSAnc3RyaW5nJykgeyBub2RlLncgPSBOdW1iZXIobm9kZS53KTsgfVxuICAgIGlmICh0eXBlb2Ygbm9kZS5oID09ICdzdHJpbmcnKSB7IG5vZGUuaCA9IE51bWJlcihub2RlLmgpOyB9XG4gICAgaWYgKGlzTmFOKG5vZGUueCkpIHsgbm9kZS54ID0gZGVmYXVsdHMueDsgbm9kZS5hdXRvUG9zaXRpb24gPSB0cnVlOyB9XG4gICAgaWYgKGlzTmFOKG5vZGUueSkpIHsgbm9kZS55ID0gZGVmYXVsdHMueTsgbm9kZS5hdXRvUG9zaXRpb24gPSB0cnVlOyB9XG4gICAgaWYgKGlzTmFOKG5vZGUudykpIHsgbm9kZS53ID0gZGVmYXVsdHMudzsgfVxuICAgIGlmIChpc05hTihub2RlLmgpKSB7IG5vZGUuaCA9IGRlZmF1bHRzLmg7IH1cblxuICAgIHJldHVybiB0aGlzLm5vZGVCb3VuZEZpeChub2RlLCByZXNpemluZyk7XG4gIH1cblxuICAvKiogcGFydDIgb2YgcHJlcGFyaW5nIGEgbm9kZSB0byBmaXQgaW5zaWRlIG91ciBncmlkIC0gY2hlY2tzIGZvciB4LHksdyBmcm9tIGdyaWQgZGltZW5zaW9ucyAqL1xuICBwdWJsaWMgbm9kZUJvdW5kRml4KG5vZGU6IEdyaWRTdGFja05vZGUsIHJlc2l6aW5nPzogYm9vbGVhbik6IEdyaWRTdGFja05vZGUge1xuXG4gICAgbGV0IGJlZm9yZSA9IG5vZGUuX29yaWcgfHwgVXRpbHMuY29weVBvcyh7fSwgbm9kZSk7XG5cbiAgICBpZiAobm9kZS5tYXhXKSB7IG5vZGUudyA9IE1hdGgubWluKG5vZGUudywgbm9kZS5tYXhXKTsgfVxuICAgIGlmIChub2RlLm1heEgpIHsgbm9kZS5oID0gTWF0aC5taW4obm9kZS5oLCBub2RlLm1heEgpOyB9XG4gICAgaWYgKG5vZGUubWluVyAmJiBub2RlLm1pblcgPD0gdGhpcy5jb2x1bW4pIHsgbm9kZS53ID0gTWF0aC5tYXgobm9kZS53LCBub2RlLm1pblcpOyB9XG4gICAgaWYgKG5vZGUubWluSCkgeyBub2RlLmggPSBNYXRoLm1heChub2RlLmgsIG5vZGUubWluSCk7IH1cblxuICAgIC8vIGlmIHVzZXIgbG9hZGVkIGEgbGFyZ2VyIHRoYW4gYWxsb3dlZCB3aWRnZXQgZm9yIGN1cnJlbnQgIyBvZiBjb2x1bW5zIChvciBmb3JjZSAxIGNvbHVtbiBtb2RlKSxcbiAgICAvLyByZW1lbWJlciBpdCdzIHBvc2l0aW9uICYgd2lkdGggc28gd2UgY2FuIHJlc3RvcmUgYmFjayAoMSAtPiAxMiBjb2x1bW4pICMxNjU1ICMxOTg1XG4gICAgLy8gSUZGIHdlJ3JlIG5vdCBpbiB0aGUgbWlkZGxlIG9mIGNvbHVtbiByZXNpemluZyFcbiAgICBjb25zdCBzYXZlT3JpZyA9IHRoaXMuY29sdW1uID09PSAxIHx8IG5vZGUueCArIG5vZGUudyA+IHRoaXMuY29sdW1uO1xuICAgIGlmIChzYXZlT3JpZyAmJiB0aGlzLmNvbHVtbiA8IDEyICYmICF0aGlzLl9pbkNvbHVtblJlc2l6ZSAmJiBub2RlLl9pZCAmJiB0aGlzLmZpbmRDYWNoZUxheW91dChub2RlLCAxMikgPT09IC0xKSB7XG4gICAgICBsZXQgY29weSA9IHsuLi5ub2RlfTsgLy8gbmVlZCBfaWQgKyBwb3NpdGlvbnNcbiAgICAgIGlmIChjb3B5LmF1dG9Qb3NpdGlvbikgeyBkZWxldGUgY29weS54OyBkZWxldGUgY29weS55OyB9XG4gICAgICBlbHNlIGNvcHkueCA9IE1hdGgubWluKDExLCBjb3B5LngpO1xuICAgICAgY29weS53ID0gTWF0aC5taW4oMTIsIGNvcHkudyk7XG4gICAgICB0aGlzLmNhY2hlT25lTGF5b3V0KGNvcHksIDEyKTtcbiAgICB9XG5cbiAgICBpZiAobm9kZS53ID4gdGhpcy5jb2x1bW4pIHtcbiAgICAgIG5vZGUudyA9IHRoaXMuY29sdW1uO1xuICAgIH0gZWxzZSBpZiAobm9kZS53IDwgMSkge1xuICAgICAgbm9kZS53ID0gMTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tYXhSb3cgJiYgbm9kZS5oID4gdGhpcy5tYXhSb3cpIHtcbiAgICAgIG5vZGUuaCA9IHRoaXMubWF4Um93O1xuICAgIH0gZWxzZSBpZiAobm9kZS5oIDwgMSkge1xuICAgICAgbm9kZS5oID0gMTtcbiAgICB9XG5cbiAgICBpZiAobm9kZS54IDwgMCkge1xuICAgICAgbm9kZS54ID0gMDtcbiAgICB9XG4gICAgaWYgKG5vZGUueSA8IDApIHtcbiAgICAgIG5vZGUueSA9IDA7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUueCArIG5vZGUudyA+IHRoaXMuY29sdW1uKSB7XG4gICAgICBpZiAocmVzaXppbmcpIHtcbiAgICAgICAgbm9kZS53ID0gdGhpcy5jb2x1bW4gLSBub2RlLng7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub2RlLnggPSB0aGlzLmNvbHVtbiAtIG5vZGUudztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRoaXMubWF4Um93ICYmIG5vZGUueSArIG5vZGUuaCA+IHRoaXMubWF4Um93KSB7XG4gICAgICBpZiAocmVzaXppbmcpIHtcbiAgICAgICAgbm9kZS5oID0gdGhpcy5tYXhSb3cgLSBub2RlLnk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub2RlLnkgPSB0aGlzLm1heFJvdyAtIG5vZGUuaDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIVV0aWxzLnNhbWVQb3Mobm9kZSwgYmVmb3JlKSkge1xuICAgICAgbm9kZS5fZGlydHkgPSB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgLyoqIHJldHVybnMgYSBsaXN0IG9mIG1vZGlmaWVkIG5vZGVzIGZyb20gdGhlaXIgb3JpZ2luYWwgdmFsdWVzICovXG4gIHB1YmxpYyBnZXREaXJ0eU5vZGVzKHZlcmlmeT86IGJvb2xlYW4pOiBHcmlkU3RhY2tOb2RlW10ge1xuICAgIC8vIGNvbXBhcmUgb3JpZ2luYWwgeCx5LHcsaCBpbnN0ZWFkIGFzIF9kaXJ0eSBjYW4gYmUgYSB0ZW1wb3Jhcnkgc3RhdGVcbiAgICBpZiAodmVyaWZ5KSB7XG4gICAgICByZXR1cm4gdGhpcy5ub2Rlcy5maWx0ZXIobiA9PiBuLl9kaXJ0eSAmJiAhVXRpbHMuc2FtZVBvcyhuLCBuLl9vcmlnKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLm5vZGVzLmZpbHRlcihuID0+IG4uX2RpcnR5KTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgY2FsbCB0aGlzIHRvIGNhbGwgb25DaGFuZ2UgY2FsbGJhY2sgd2l0aCBkaXJ0eSBub2RlcyBzbyBET00gY2FuIGJlIHVwZGF0ZWQgKi9cbiAgcHJvdGVjdGVkIF9ub3RpZnkocmVtb3ZlZE5vZGVzPzogR3JpZFN0YWNrTm9kZVtdKTogR3JpZFN0YWNrRW5naW5lIHtcbiAgICBpZiAodGhpcy5iYXRjaE1vZGUgfHwgIXRoaXMub25DaGFuZ2UpIHJldHVybiB0aGlzO1xuICAgIGxldCBkaXJ0eU5vZGVzID0gKHJlbW92ZWROb2RlcyB8fCBbXSkuY29uY2F0KHRoaXMuZ2V0RGlydHlOb2RlcygpKTtcbiAgICB0aGlzLm9uQ2hhbmdlKGRpcnR5Tm9kZXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCByZW1vdmUgZGlydHkgYW5kIGxhc3QgdHJpZWQgaW5mbyAqL1xuICBwdWJsaWMgY2xlYW5Ob2RlcygpOiBHcmlkU3RhY2tFbmdpbmUge1xuICAgIGlmICh0aGlzLmJhdGNoTW9kZSkgcmV0dXJuIHRoaXM7XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKG4gPT4ge1xuICAgICAgZGVsZXRlIG4uX2RpcnR5O1xuICAgICAgZGVsZXRlIG4uX2xhc3RUcmllZDtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgY2FsbGVkIHRvIHNhdmUgaW5pdGlhbCBwb3NpdGlvbi9zaXplIHRvIHRyYWNrIHJlYWwgZGlydHkgc3RhdGUuXG4gICAqIE5vdGU6IHNob3VsZCBiZSBjYWxsZWQgcmlnaHQgYWZ0ZXIgd2UgY2FsbCBjaGFuZ2UgZXZlbnQgKHNvIG5leHQgQVBJIGlzIGNhbiBkZXRlY3QgY2hhbmdlcylcbiAgICogYXMgd2VsbCBhcyByaWdodCBiZWZvcmUgd2Ugc3RhcnQgbW92ZS9yZXNpemUvZW50ZXIgKHNvIHdlIGNhbiByZXN0b3JlIGl0ZW1zIHRvIHByZXYgdmFsdWVzKSAqL1xuICBwdWJsaWMgc2F2ZUluaXRpYWwoKTogR3JpZFN0YWNrRW5naW5lIHtcbiAgICB0aGlzLm5vZGVzLmZvckVhY2gobiA9PiB7XG4gICAgICBuLl9vcmlnID0gVXRpbHMuY29weVBvcyh7fSwgbik7XG4gICAgICBkZWxldGUgbi5fZGlydHk7XG4gICAgfSk7XG4gICAgdGhpcy5faGFzTG9ja2VkID0gdGhpcy5ub2Rlcy5zb21lKG4gPT4gbi5sb2NrZWQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCByZXN0b3JlIGFsbCB0aGUgbm9kZXMgYmFjayB0byBpbml0aWFsIHZhbHVlcyAoY2FsbGVkIHdoZW4gd2UgbGVhdmUpICovXG4gIHB1YmxpYyByZXN0b3JlSW5pdGlhbCgpOiBHcmlkU3RhY2tFbmdpbmUge1xuICAgIHRoaXMubm9kZXMuZm9yRWFjaChuID0+IHtcbiAgICAgIGlmIChVdGlscy5zYW1lUG9zKG4sIG4uX29yaWcpKSByZXR1cm47XG4gICAgICBVdGlscy5jb3B5UG9zKG4sIG4uX29yaWcpO1xuICAgICAgbi5fZGlydHkgPSB0cnVlO1xuICAgIH0pO1xuICAgIHRoaXMuX25vdGlmeSgpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIGZpbmQgdGhlIGZpcnN0IGF2YWlsYWJsZSBlbXB0eSBzcG90IGZvciB0aGUgZ2l2ZW4gbm9kZSB3aWR0aC9oZWlnaHQsIHVwZGF0aW5nIHRoZSB4LHkgYXR0cmlidXRlcy4gcmV0dXJuIHRydWUgaWYgZm91bmQuXG4gICAqIG9wdGlvbmFsbHkgeW91IGNhbiBwYXNzIHlvdXIgb3duIGV4aXN0aW5nIG5vZGUgbGlzdCBhbmQgY29sdW1uIGNvdW50LCBvdGhlcndpc2UgZGVmYXVsdHMgdG8gdGhhdCBlbmdpbmUgZGF0YS5cbiAgICovXG4gIHB1YmxpYyBmaW5kRW1wdHlQb3NpdGlvbihub2RlOiBHcmlkU3RhY2tOb2RlLCBub2RlTGlzdCA9IHRoaXMubm9kZXMsIGNvbHVtbiA9IHRoaXMuY29sdW1uKTogYm9vbGVhbiB7XG4gICAgbm9kZUxpc3QgPSBVdGlscy5zb3J0KG5vZGVMaXN0LCAtMSwgY29sdW1uKTtcbiAgICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgIWZvdW5kOyArK2kpIHtcbiAgICAgIGxldCB4ID0gaSAlIGNvbHVtbjtcbiAgICAgIGxldCB5ID0gTWF0aC5mbG9vcihpIC8gY29sdW1uKTtcbiAgICAgIGlmICh4ICsgbm9kZS53ID4gY29sdW1uKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbGV0IGJveCA9IHt4LCB5LCB3OiBub2RlLncsIGg6IG5vZGUuaH07XG4gICAgICBpZiAoIW5vZGVMaXN0LmZpbmQobiA9PiBVdGlscy5pc0ludGVyY2VwdGVkKGJveCwgbikpKSB7XG4gICAgICAgIG5vZGUueCA9IHg7XG4gICAgICAgIG5vZGUueSA9IHk7XG4gICAgICAgIGRlbGV0ZSBub2RlLmF1dG9Qb3NpdGlvbjtcbiAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZm91bmQ7XG4gIH1cblxuICAvKiogY2FsbCB0byBhZGQgdGhlIGdpdmVuIG5vZGUgdG8gb3VyIGxpc3QsIGZpeGluZyBjb2xsaXNpb24gYW5kIHJlLXBhY2tpbmcgKi9cbiAgcHVibGljIGFkZE5vZGUobm9kZTogR3JpZFN0YWNrTm9kZSwgdHJpZ2dlckFkZEV2ZW50ID0gZmFsc2UpOiBHcmlkU3RhY2tOb2RlIHtcbiAgICBsZXQgZHVwID0gdGhpcy5ub2Rlcy5maW5kKG4gPT4gbi5faWQgPT09IG5vZGUuX2lkKTtcbiAgICBpZiAoZHVwKSByZXR1cm4gZHVwOyAvLyBwcmV2ZW50IGluc2VydGluZyB0d2ljZSEgcmV0dXJuIGl0IGluc3RlYWQuXG5cbiAgICAvLyBza2lwIHByZXBhcmVOb2RlIGlmIHdlJ3JlIGluIG1pZGRsZSBvZiBjb2x1bW4gcmVzaXplIChub3QgbmV3KSBidXQgZG8gY2hlY2sgZm9yIGJvdW5kcyFcbiAgICBub2RlID0gdGhpcy5faW5Db2x1bW5SZXNpemUgPyB0aGlzLm5vZGVCb3VuZEZpeChub2RlKSA6IHRoaXMucHJlcGFyZU5vZGUobm9kZSk7XG4gICAgZGVsZXRlIG5vZGUuX3RlbXBvcmFyeVJlbW92ZWQ7XG4gICAgZGVsZXRlIG5vZGUuX3JlbW92ZURPTTtcblxuICAgIGlmIChub2RlLmF1dG9Qb3NpdGlvbiAmJiB0aGlzLmZpbmRFbXB0eVBvc2l0aW9uKG5vZGUpKSB7XG4gICAgICBkZWxldGUgbm9kZS5hdXRvUG9zaXRpb247IC8vIGZvdW5kIG91ciBzbG90XG4gICAgfVxuXG4gICAgdGhpcy5ub2Rlcy5wdXNoKG5vZGUpO1xuICAgIGlmICh0cmlnZ2VyQWRkRXZlbnQpIHsgdGhpcy5hZGRlZE5vZGVzLnB1c2gobm9kZSk7IH1cblxuICAgIHRoaXMuX2ZpeENvbGxpc2lvbnMobm9kZSk7XG4gICAgaWYgKCF0aGlzLmJhdGNoTW9kZSkgeyB0aGlzLl9wYWNrTm9kZXMoKS5fbm90aWZ5KCk7IH1cbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHB1YmxpYyByZW1vdmVOb2RlKG5vZGU6IEdyaWRTdGFja05vZGUsIHJlbW92ZURPTSA9IHRydWUsIHRyaWdnZXJFdmVudCA9IGZhbHNlKTogR3JpZFN0YWNrRW5naW5lIHtcbiAgICBpZiAoIXRoaXMubm9kZXMuZmluZChuID0+IG4uX2lkID09PSBub2RlLl9pZCkpIHtcbiAgICAgIC8vIFRFU1QgY29uc29sZS5sb2coYEVycm9yOiBHcmlkU3RhY2tFbmdpbmUucmVtb3ZlTm9kZSgpIG5vZGUuX2lkPSR7bm9kZS5faWR9IG5vdCBmb3VuZCFgKVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGlmICh0cmlnZ2VyRXZlbnQpIHsgLy8gd2Ugd2FpdCB1bnRpbCBmaW5hbCBkcm9wIHRvIG1hbnVhbGx5IHRyYWNrIHJlbW92ZWQgaXRlbXMgKHJhdGhlciB0aGFuIGR1cmluZyBkcmFnKVxuICAgICAgdGhpcy5yZW1vdmVkTm9kZXMucHVzaChub2RlKTtcbiAgICB9XG4gICAgaWYgKHJlbW92ZURPTSkgbm9kZS5fcmVtb3ZlRE9NID0gdHJ1ZTsgLy8gbGV0IENCIHJlbW92ZSBhY3R1YWwgSFRNTCAodXNlZCB0byBzZXQgX2lkIHRvIG51bGwsIGJ1dCB0aGVuIHdlIGxvb3NlIGxheW91dCBpbmZvKVxuICAgIC8vIGRvbid0IHVzZSAnZmFzdGVyJyAuc3BsaWNlKGZpbmRJbmRleCgpLDEpIGluIGNhc2Ugbm9kZSBpc24ndCBpbiBvdXIgbGlzdCwgb3IgaW4gbXVsdGlwbGUgdGltZXMuXG4gICAgdGhpcy5ub2RlcyA9IHRoaXMubm9kZXMuZmlsdGVyKG4gPT4gbi5faWQgIT09IG5vZGUuX2lkKTtcbiAgICByZXR1cm4gdGhpcy5fcGFja05vZGVzKClcbiAgICAgIC5fbm90aWZ5KFtub2RlXSk7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlQWxsKHJlbW92ZURPTSA9IHRydWUpOiBHcmlkU3RhY2tFbmdpbmUge1xuICAgIGRlbGV0ZSB0aGlzLl9sYXlvdXRzO1xuICAgIGlmICghdGhpcy5ub2Rlcy5sZW5ndGgpIHJldHVybiB0aGlzO1xuICAgIHJlbW92ZURPTSAmJiB0aGlzLm5vZGVzLmZvckVhY2gobiA9PiBuLl9yZW1vdmVET00gPSB0cnVlKTsgLy8gbGV0IENCIHJlbW92ZSBhY3R1YWwgSFRNTCAodXNlZCB0byBzZXQgX2lkIHRvIG51bGwsIGJ1dCB0aGVuIHdlIGxvb3NlIGxheW91dCBpbmZvKVxuICAgIHRoaXMucmVtb3ZlZE5vZGVzID0gdGhpcy5ub2RlcztcbiAgICB0aGlzLm5vZGVzID0gW107XG4gICAgcmV0dXJuIHRoaXMuX25vdGlmeSh0aGlzLnJlbW92ZWROb2Rlcyk7XG4gIH1cblxuICAvKiogY2hlY2tzIGlmIGl0ZW0gY2FuIGJlIG1vdmVkIChsYXlvdXQgY29uc3RyYWluKSB2cyBtb3ZlTm9kZSgpLCByZXR1cm5pbmcgdHJ1ZSBpZiB3YXMgYWJsZSB0byBtb3ZlLlxuICAgKiBJbiBtb3JlIGNvbXBsaWNhdGVkIGNhc2VzIChtYXhSb3cpIGl0IHdpbGwgYXR0ZW1wdCBhdCBtb3ZpbmcgdGhlIGl0ZW0gYW5kIGZpeGluZ1xuICAgKiBvdGhlcnMgaW4gYSBjbG9uZSBmaXJzdCwgdGhlbiBhcHBseSB0aG9zZSBjaGFuZ2VzIGlmIHN0aWxsIHdpdGhpbiBzcGVjcy4gKi9cbiAgcHVibGljIG1vdmVOb2RlQ2hlY2sobm9kZTogR3JpZFN0YWNrTm9kZSwgbzogR3JpZFN0YWNrTW92ZU9wdHMpOiBib29sZWFuIHtcbiAgICAvLyBpZiAobm9kZS5sb2NrZWQpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoIXRoaXMuY2hhbmdlZFBvc0NvbnN0cmFpbihub2RlLCBvKSkgcmV0dXJuIGZhbHNlO1xuICAgIG8ucGFjayA9IHRydWU7XG5cbiAgICAvLyBzaW1wbGVyIGNhc2U6IG1vdmUgaXRlbSBkaXJlY3RseS4uLlxuICAgIGlmICghdGhpcy5tYXhSb3cpIHtcbiAgICAgIHJldHVybiB0aGlzLm1vdmVOb2RlKG5vZGUsIG8pO1xuICAgIH1cblxuICAgIC8vIGNvbXBsZXggY2FzZTogY3JlYXRlIGEgY2xvbmUgd2l0aCBOTyBtYXhSb3cgKHdpbGwgY2hlY2sgZm9yIG91dCBvZiBib3VuZHMgYXQgdGhlIGVuZClcbiAgICBsZXQgY2xvbmVkTm9kZTogR3JpZFN0YWNrTm9kZTtcbiAgICBsZXQgY2xvbmUgPSBuZXcgR3JpZFN0YWNrRW5naW5lKHtcbiAgICAgIGNvbHVtbjogdGhpcy5jb2x1bW4sXG4gICAgICBmbG9hdDogdGhpcy5mbG9hdCxcbiAgICAgIG5vZGVzOiB0aGlzLm5vZGVzLm1hcChuID0+IHtcbiAgICAgICAgaWYgKG4uX2lkID09PSBub2RlLl9pZCkge1xuICAgICAgICAgIGNsb25lZE5vZGUgPSB7Li4ubn07XG4gICAgICAgICAgcmV0dXJuIGNsb25lZE5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsuLi5ufTtcbiAgICAgIH0pXG4gICAgfSk7XG4gICAgaWYgKCFjbG9uZWROb2RlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBjaGVjayBpZiB3ZSdyZSBjb3ZlcmluZyA1MCUgY29sbGlzaW9uIGFuZCBjb3VsZCBtb3ZlXG4gICAgbGV0IGNhbk1vdmUgPSBjbG9uZS5tb3ZlTm9kZShjbG9uZWROb2RlLCBvKSAmJiBjbG9uZS5nZXRSb3coKSA8PSB0aGlzLm1heFJvdztcbiAgICAvLyBlbHNlIGNoZWNrIGlmIHdlIGNhbiBmb3JjZSBhIHN3YXAgKGZsb2F0PXRydWUsIG9yIGRpZmZlcmVudCBzaGFwZXMpIG9uIG5vbi1yZXNpemVcbiAgICBpZiAoIWNhbk1vdmUgJiYgIW8ucmVzaXppbmcgJiYgby5jb2xsaWRlKSB7XG4gICAgICBsZXQgY29sbGlkZSA9IG8uY29sbGlkZS5lbC5ncmlkc3RhY2tOb2RlOyAvLyBmaW5kIHRoZSBzb3VyY2Ugbm9kZSB0aGUgY2xvbmUgY29sbGlkZWQgd2l0aCBhdCA1MCVcbiAgICAgIGlmICh0aGlzLnN3YXAobm9kZSwgY29sbGlkZSkpIHsgLy8gc3dhcHMgYW5kIG1hcmsgZGlydHlcbiAgICAgICAgdGhpcy5fbm90aWZ5KCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWNhbk1vdmUpIHJldHVybiBmYWxzZTtcblxuICAgIC8vIGlmIGNsb25lIHdhcyBhYmxlIHRvIG1vdmUsIGNvcHkgdGhvc2UgbW9kcyBvdmVyIHRvIHVzIG5vdyBpbnN0ZWFkIG9mIGNhbGxlciB0cnlpbmcgdG8gZG8gdGhpcyBhbGwgb3ZlciFcbiAgICAvLyBOb3RlOiB3ZSBjYW4ndCB1c2UgdGhlIGxpc3QgZGlyZWN0bHkgYXMgZWxlbWVudHMgYW5kIG90aGVyIHBhcnRzIHBvaW50IHRvIGFjdHVhbCBub2RlLCBzbyBjb3B5IGNvbnRlbnRcbiAgICBjbG9uZS5ub2Rlcy5maWx0ZXIobiA9PiBuLl9kaXJ0eSkuZm9yRWFjaChjID0+IHtcbiAgICAgIGxldCBuID0gdGhpcy5ub2Rlcy5maW5kKGEgPT4gYS5faWQgPT09IGMuX2lkKTtcbiAgICAgIGlmICghbikgcmV0dXJuO1xuICAgICAgVXRpbHMuY29weVBvcyhuLCBjKTtcbiAgICAgIG4uX2RpcnR5ID0gdHJ1ZTtcbiAgICB9KTtcbiAgICB0aGlzLl9ub3RpZnkoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiByZXR1cm4gdHJ1ZSBpZiBjYW4gZml0IGluIGdyaWQgaGVpZ2h0IGNvbnN0cmFpbiBvbmx5IChhbHdheXMgdHJ1ZSBpZiBubyBtYXhSb3cpICovXG4gIHB1YmxpYyB3aWxsSXRGaXQobm9kZTogR3JpZFN0YWNrTm9kZSk6IGJvb2xlYW4ge1xuICAgIGRlbGV0ZSBub2RlLl93aWxsRml0UG9zO1xuICAgIGlmICghdGhpcy5tYXhSb3cpIHJldHVybiB0cnVlO1xuICAgIC8vIGNyZWF0ZSBhIGNsb25lIHdpdGggTk8gbWF4Um93IGFuZCBjaGVjayBpZiBzdGlsbCB3aXRoaW4gc2l6ZVxuICAgIGxldCBjbG9uZSA9IG5ldyBHcmlkU3RhY2tFbmdpbmUoe1xuICAgICAgY29sdW1uOiB0aGlzLmNvbHVtbixcbiAgICAgIGZsb2F0OiB0aGlzLmZsb2F0LFxuICAgICAgbm9kZXM6IHRoaXMubm9kZXMubWFwKG4gPT4ge3JldHVybiB7Li4ubn19KVxuICAgIH0pO1xuICAgIGxldCBuID0gey4uLm5vZGV9OyAvLyBjbG9uZSBub2RlIHNvIHdlIGRvbid0IG1vZCBhbnkgc2V0dGluZ3Mgb24gaXQgYnV0IGhhdmUgZnVsbCBhdXRvUG9zaXRpb24gYW5kIG1pbi9tYXggYXMgd2VsbCEgIzE2ODdcbiAgICB0aGlzLmNsZWFudXBOb2RlKG4pO1xuICAgIGRlbGV0ZSBuLmVsOyBkZWxldGUgbi5faWQ7IGRlbGV0ZSBuLmNvbnRlbnQ7IGRlbGV0ZSBuLmdyaWQ7XG4gICAgY2xvbmUuYWRkTm9kZShuKTtcbiAgICBpZiAoY2xvbmUuZ2V0Um93KCkgPD0gdGhpcy5tYXhSb3cpIHtcbiAgICAgIG5vZGUuX3dpbGxGaXRQb3MgPSBVdGlscy5jb3B5UG9zKHt9LCBuKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKiogdHJ1ZSBpZiB4LHkgb3IgdyxoIGFyZSBkaWZmZXJlbnQgYWZ0ZXIgY2xhbXBpbmcgdG8gbWluL21heCAqL1xuICBwdWJsaWMgY2hhbmdlZFBvc0NvbnN0cmFpbihub2RlOiBHcmlkU3RhY2tOb2RlLCBwOiBHcmlkU3RhY2tQb3NpdGlvbik6IGJvb2xlYW4ge1xuICAgIC8vIGZpcnN0IG1ha2Ugc3VyZSB3LGggYXJlIHNldCBmb3IgY2FsbGVyXG4gICAgcC53ID0gcC53IHx8IG5vZGUudztcbiAgICBwLmggPSBwLmggfHwgbm9kZS5oO1xuICAgIGlmIChub2RlLnggIT09IHAueCB8fCBub2RlLnkgIT09IHAueSkgcmV0dXJuIHRydWU7XG4gICAgLy8gY2hlY2sgY29uc3RyYWluZWQgdyxoXG4gICAgaWYgKG5vZGUubWF4VykgeyBwLncgPSBNYXRoLm1pbihwLncsIG5vZGUubWF4Vyk7IH1cbiAgICBpZiAobm9kZS5tYXhIKSB7IHAuaCA9IE1hdGgubWluKHAuaCwgbm9kZS5tYXhIKTsgfVxuICAgIGlmIChub2RlLm1pblcpIHsgcC53ID0gTWF0aC5tYXgocC53LCBub2RlLm1pblcpOyB9XG4gICAgaWYgKG5vZGUubWluSCkgeyBwLmggPSBNYXRoLm1heChwLmgsIG5vZGUubWluSCk7IH1cbiAgICByZXR1cm4gKG5vZGUudyAhPT0gcC53IHx8IG5vZGUuaCAhPT0gcC5oKTtcbiAgfVxuXG4gIC8qKiByZXR1cm4gdHJ1ZSBpZiB0aGUgcGFzc2VkIGluIG5vZGUgd2FzIGFjdHVhbGx5IG1vdmVkIChjaGVja3MgZm9yIG5vLW9wIGFuZCBsb2NrZWQpICovXG4gIHB1YmxpYyBtb3ZlTm9kZShub2RlOiBHcmlkU3RhY2tOb2RlLCBvOiBHcmlkU3RhY2tNb3ZlT3B0cyk6IGJvb2xlYW4ge1xuICAgIGlmICghbm9kZSB8fCAvKm5vZGUubG9ja2VkIHx8Ki8gIW8pIHJldHVybiBmYWxzZTtcbiAgICBsZXQgd2FzVW5kZWZpbmVkUGFjazogYm9vbGVhbjtcbiAgICBpZiAoby5wYWNrID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHdhc1VuZGVmaW5lZFBhY2sgPSBvLnBhY2sgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIGNvbnN0cmFpbiB0aGUgcGFzc2VkIGluIHZhbHVlcyBhbmQgY2hlY2sgaWYgd2UncmUgc3RpbGwgY2hhbmdpbmcgb3VyIG5vZGVcbiAgICBpZiAodHlwZW9mIG8ueCAhPT0gJ251bWJlcicpIHsgby54ID0gbm9kZS54OyB9XG4gICAgaWYgKHR5cGVvZiBvLnkgIT09ICdudW1iZXInKSB7IG8ueSA9IG5vZGUueTsgfVxuICAgIGlmICh0eXBlb2Ygby53ICE9PSAnbnVtYmVyJykgeyBvLncgPSBub2RlLnc7IH1cbiAgICBpZiAodHlwZW9mIG8uaCAhPT0gJ251bWJlcicpIHsgby5oID0gbm9kZS5oOyB9XG4gICAgbGV0IHJlc2l6aW5nID0gKG5vZGUudyAhPT0gby53IHx8IG5vZGUuaCAhPT0gby5oKTtcbiAgICBsZXQgbm46IEdyaWRTdGFja05vZGUgPSBVdGlscy5jb3B5UG9zKHt9LCBub2RlLCB0cnVlKTsgLy8gZ2V0IG1pbi9tYXggb3V0IGZpcnN0LCB0aGVuIG9wdCBwb3NpdGlvbnMgbmV4dFxuICAgIFV0aWxzLmNvcHlQb3Mobm4sIG8pO1xuICAgIG5uID0gdGhpcy5ub2RlQm91bmRGaXgobm4sIHJlc2l6aW5nKTtcbiAgICBVdGlscy5jb3B5UG9zKG8sIG5uKTtcblxuICAgIGlmIChVdGlscy5zYW1lUG9zKG5vZGUsIG8pKSByZXR1cm4gZmFsc2U7XG4gICAgbGV0IHByZXZQb3M6IEdyaWRTdGFja1Bvc2l0aW9uID0gVXRpbHMuY29weVBvcyh7fSwgbm9kZSk7XG5cbiAgICAvLyBjaGVjayBpZiB3ZSB3aWxsIG5lZWQgdG8gZml4IGNvbGxpc2lvbiBhdCBvdXIgbmV3IGxvY2F0aW9uXG4gICAgbGV0IGNvbGxpZGVzID0gdGhpcy5jb2xsaWRlQWxsKG5vZGUsIG5uLCBvLnNraXApO1xuICAgIGxldCBuZWVkVG9Nb3ZlID0gdHJ1ZTtcbiAgICBpZiAoY29sbGlkZXMubGVuZ3RoKSB7XG4gICAgICBsZXQgYWN0aXZlRHJhZyA9IG5vZGUuX21vdmluZyAmJiAhby5uZXN0ZWQ7XG4gICAgICAvLyBjaGVjayB0byBtYWtlIHN1cmUgd2UgYWN0dWFsbHkgY29sbGlkZWQgb3ZlciA1MCUgc3VyZmFjZSBhcmVhIHdoaWxlIGRyYWdnaW5nXG4gICAgICBsZXQgY29sbGlkZSA9IGFjdGl2ZURyYWcgPyB0aGlzLmRpcmVjdGlvbkNvbGxpZGVDb3ZlcmFnZShub2RlLCBvLCBjb2xsaWRlcykgOiBjb2xsaWRlc1swXTtcbiAgICAgIC8vIGlmIHdlJ3JlIGVuYWJsaW5nIGNyZWF0aW9uIG9mIHN1Yi1ncmlkcyBvbiB0aGUgZmx5LCBzZWUgaWYgd2UncmUgY292ZXJpbmcgODAlIG9mIGVpdGhlciBvbmUsIGlmIHdlIGRpZG4ndCBhbHJlYWR5IGRvIHRoYXRcbiAgICAgIGlmIChhY3RpdmVEcmFnICYmIGNvbGxpZGUgJiYgbm9kZS5ncmlkPy5vcHRzPy5zdWJHcmlkRHluYW1pYyAmJiAhbm9kZS5ncmlkLl9pc1RlbXApIHtcbiAgICAgICAgbGV0IG92ZXIgPSBVdGlscy5hcmVhSW50ZXJjZXB0KG8ucmVjdCwgY29sbGlkZS5fcmVjdCk7XG4gICAgICAgIGxldCBhMSA9IFV0aWxzLmFyZWEoby5yZWN0KTtcbiAgICAgICAgbGV0IGEyID0gVXRpbHMuYXJlYShjb2xsaWRlLl9yZWN0KTtcbiAgICAgICAgbGV0IHBlcmMgPSBvdmVyIC8gKGExIDwgYTIgPyBhMSA6IGEyKTtcbiAgICAgICAgaWYgKHBlcmMgPiAuOCkge1xuICAgICAgICAgIGNvbGxpZGUuZ3JpZC5tYWtlU3ViR3JpZChjb2xsaWRlLmVsLCB1bmRlZmluZWQsIG5vZGUpO1xuICAgICAgICAgIGNvbGxpZGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNvbGxpZGUpIHtcbiAgICAgICAgbmVlZFRvTW92ZSA9ICF0aGlzLl9maXhDb2xsaXNpb25zKG5vZGUsIG5uLCBjb2xsaWRlLCBvKTsgLy8gY2hlY2sgaWYgYWxyZWFkeSBtb3ZlZC4uLlxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmVlZFRvTW92ZSA9IGZhbHNlOyAvLyB3ZSBkaWRuJ3QgY292ZXIgPjUwJSBmb3IgYSBtb3ZlLCBza2lwLi4uXG4gICAgICAgIGlmICh3YXNVbmRlZmluZWRQYWNrKSBkZWxldGUgby5wYWNrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIG5vdyBtb3ZlICh0byB0aGUgb3JpZ2luYWwgYXNrIHZzIHRoZSBjb2xsaXNpb24gdmVyc2lvbiB3aGljaCBtaWdodCBkaWZmZXIpIGFuZCByZXBhY2sgdGhpbmdzXG4gICAgaWYgKG5lZWRUb01vdmUpIHtcbiAgICAgIG5vZGUuX2RpcnR5ID0gdHJ1ZTtcbiAgICAgIFV0aWxzLmNvcHlQb3Mobm9kZSwgbm4pO1xuICAgIH1cbiAgICBpZiAoby5wYWNrKSB7XG4gICAgICB0aGlzLl9wYWNrTm9kZXMoKVxuICAgICAgICAuX25vdGlmeSgpO1xuICAgIH1cbiAgICByZXR1cm4gIVV0aWxzLnNhbWVQb3Mobm9kZSwgcHJldlBvcyk7IC8vIHBhY2sgbWlnaHQgaGF2ZSBtb3ZlZCB0aGluZ3MgYmFja1xuICB9XG5cbiAgcHVibGljIGdldFJvdygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm5vZGVzLnJlZHVjZSgocm93LCBuKSA9PiBNYXRoLm1heChyb3csIG4ueSArIG4uaCksIDApO1xuICB9XG5cbiAgcHVibGljIGJlZ2luVXBkYXRlKG5vZGU6IEdyaWRTdGFja05vZGUpOiBHcmlkU3RhY2tFbmdpbmUge1xuICAgIGlmICghbm9kZS5fdXBkYXRpbmcpIHtcbiAgICAgIG5vZGUuX3VwZGF0aW5nID0gdHJ1ZTtcbiAgICAgIGRlbGV0ZSBub2RlLl9za2lwRG93bjtcbiAgICAgIGlmICghdGhpcy5iYXRjaE1vZGUpIHRoaXMuc2F2ZUluaXRpYWwoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgZW5kVXBkYXRlKCk6IEdyaWRTdGFja0VuZ2luZSB7XG4gICAgbGV0IG4gPSB0aGlzLm5vZGVzLmZpbmQobiA9PiBuLl91cGRhdGluZyk7XG4gICAgaWYgKG4pIHtcbiAgICAgIGRlbGV0ZSBuLl91cGRhdGluZztcbiAgICAgIGRlbGV0ZSBuLl9za2lwRG93bjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogc2F2ZXMgYSBjb3B5IG9mIHRoZSBsYXJnZXN0IGNvbHVtbiBsYXlvdXQgKGVnIDEyIGV2ZW4gd2hlbiByZW5kZXJpbmcgb25lQ29sdW1uTW9kZSkgc28gd2UgZG9uJ3QgbG9vc2Ugb3JpZyBsYXlvdXQsXG4gICAqIHJldHVybmluZyBhIGxpc3Qgb2Ygd2lkZ2V0cyBmb3Igc2VyaWFsaXphdGlvbiAqL1xuICBwdWJsaWMgc2F2ZShzYXZlRWxlbWVudCA9IHRydWUsIHNhdmVDQj86IFNhdmVGY24pOiBHcmlkU3RhY2tOb2RlW10ge1xuICAgIC8vIHVzZSB0aGUgaGlnaGVzdCBsYXlvdXQgZm9yIGFueSBzYXZlZCBpbmZvIHNvIHdlIGNhbiBoYXZlIGZ1bGwgZGV0YWlsIG9uIHJlbG9hZCAjMTg0OVxuICAgIGxldCBsZW4gPSB0aGlzLl9sYXlvdXRzPy5sZW5ndGg7XG4gICAgbGV0IGxheW91dCA9IGxlbiAmJiB0aGlzLmNvbHVtbiAhPT0gKGxlbiAtIDEpID8gdGhpcy5fbGF5b3V0c1tsZW4gLSAxXSA6IG51bGw7XG4gICAgbGV0IGxpc3Q6IEdyaWRTdGFja05vZGVbXSA9IFtdO1xuICAgIHRoaXMuc29ydE5vZGVzKCk7XG4gICAgdGhpcy5ub2Rlcy5mb3JFYWNoKG4gPT4ge1xuICAgICAgbGV0IHdsID0gbGF5b3V0Py5maW5kKGwgPT4gbC5faWQgPT09IG4uX2lkKTtcbiAgICAgIGxldCB3OiBHcmlkU3RhY2tOb2RlID0gey4uLm59O1xuICAgICAgLy8gdXNlIGxheW91dCBpbmZvIGluc3RlYWQgaWYgc2V0XG4gICAgICBpZiAod2wpIHsgdy54ID0gd2wueDsgdy55ID0gd2wueTsgdy53ID0gd2wudzsgfVxuICAgICAgVXRpbHMucmVtb3ZlSW50ZXJuYWxGb3JTYXZlKHcsICFzYXZlRWxlbWVudCk7XG4gICAgICBpZiAoc2F2ZUNCKSBzYXZlQ0Iobiwgdyk7XG4gICAgICBsaXN0LnB1c2godyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGxpc3Q7XG4gIH1cblxuICAvKiogQGludGVybmFsIGNhbGxlZCB3aGVuZXZlciBhIG5vZGUgaXMgYWRkZWQgb3IgbW92ZWQgLSB1cGRhdGVzIHRoZSBjYWNoZWQgbGF5b3V0cyAqL1xuICBwdWJsaWMgbGF5b3V0c05vZGVzQ2hhbmdlKG5vZGVzOiBHcmlkU3RhY2tOb2RlW10pOiBHcmlkU3RhY2tFbmdpbmUge1xuICAgIGlmICghdGhpcy5fbGF5b3V0cyB8fCB0aGlzLl9pbkNvbHVtblJlc2l6ZSkgcmV0dXJuIHRoaXM7XG4gICAgLy8gcmVtb3ZlIHNtYWxsZXIgbGF5b3V0cyAtIHdlIHdpbGwgcmUtZ2VuZXJhdGUgdGhvc2Ugb24gdGhlIGZseS4uLiBsYXJnZXIgb25lcyBuZWVkIHRvIHVwZGF0ZVxuICAgIHRoaXMuX2xheW91dHMuZm9yRWFjaCgobGF5b3V0LCBjb2x1bW4pID0+IHtcbiAgICAgIGlmICghbGF5b3V0IHx8IGNvbHVtbiA9PT0gdGhpcy5jb2x1bW4pIHJldHVybiB0aGlzO1xuICAgICAgaWYgKGNvbHVtbiA8IHRoaXMuY29sdW1uKSB7XG4gICAgICAgIHRoaXMuX2xheW91dHNbY29sdW1uXSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvLyB3ZSBzYXZlIHRoZSBvcmlnaW5hbCB4LHksdyAoaCBpc24ndCBjYWNoZWQpIHRvIHNlZSB3aGF0IGFjdHVhbGx5IGNoYW5nZWQgdG8gcHJvcGFnYXRlIGJldHRlci5cbiAgICAgICAgLy8gTk9URTogd2UgZG9uJ3QgbmVlZCB0byBjaGVjayBhZ2FpbnN0IG91dCBvZiBib3VuZCBzY2FsaW5nL21vdmluZyBhcyB0aGF0IHdpbGwgYmUgZG9uZSB3aGVuIHVzaW5nIHRob3NlIGNhY2hlIHZhbHVlcy4gIzE3ODVcbiAgICAgICAgbGV0IHJhdGlvID0gY29sdW1uIC8gdGhpcy5jb2x1bW47XG4gICAgICAgIG5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgaWYgKCFub2RlLl9vcmlnKSByZXR1cm47IC8vIGRpZG4ndCBjaGFuZ2UgKG5ld2x5IGFkZGVkID8pXG4gICAgICAgICAgbGV0IG4gPSBsYXlvdXQuZmluZChsID0+IGwuX2lkID09PSBub2RlLl9pZCk7XG4gICAgICAgICAgaWYgKCFuKSByZXR1cm47IC8vIG5vIGNhY2hlIGZvciBuZXcgbm9kZXMuIFdpbGwgdXNlIHRob3NlIHZhbHVlcy5cbiAgICAgICAgICAvLyBZIGNoYW5nZWQsIHB1c2ggZG93biBzYW1lIGFtb3VudFxuICAgICAgICAgIC8vIFRPRE86IGRldGVjdCBkb2luZyBpdGVtICdzd2Fwcycgd2lsbCBoZWxwIGluc3RlYWQgb2YgbW92ZSAoZXNwZWNpYWxseSBpbiAxIGNvbHVtbiBtb2RlKVxuICAgICAgICAgIGlmIChub2RlLnkgIT09IG5vZGUuX29yaWcueSkge1xuICAgICAgICAgICAgbi55ICs9IChub2RlLnkgLSBub2RlLl9vcmlnLnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBYIGNoYW5nZWQsIHNjYWxlIGZyb20gbmV3IHBvc2l0aW9uXG4gICAgICAgICAgaWYgKG5vZGUueCAhPT0gbm9kZS5fb3JpZy54KSB7XG4gICAgICAgICAgICBuLnggPSBNYXRoLnJvdW5kKG5vZGUueCAqIHJhdGlvKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gd2lkdGggY2hhbmdlZCwgc2NhbGUgZnJvbSBuZXcgd2lkdGhcbiAgICAgICAgICBpZiAobm9kZS53ICE9PSBub2RlLl9vcmlnLncpIHtcbiAgICAgICAgICAgIG4udyA9IE1hdGgucm91bmQobm9kZS53ICogcmF0aW8pO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyAuLi5oZWlnaHQgYWx3YXlzIGNhcnJpZXMgb3ZlciBmcm9tIGNhY2hlXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbCBDYWxsZWQgdG8gc2NhbGUgdGhlIHdpZGdldCB3aWR0aCAmIHBvc2l0aW9uIHVwL2Rvd24gYmFzZWQgb24gdGhlIGNvbHVtbiBjaGFuZ2UuXG4gICAqIE5vdGUgd2Ugc3RvcmUgcHJldmlvdXMgbGF5b3V0cyAoZXNwZWNpYWxseSBvcmlnaW5hbCBvbmVzKSB0byBtYWtlIGl0IHBvc3NpYmxlIHRvIGdvXG4gICAqIGZyb20gc2F5IDEyIC0+IDEgLT4gMTIgYW5kIGdldCBiYWNrIHRvIHdoZXJlIHdlIHdlcmUuXG4gICAqXG4gICAqIEBwYXJhbSBwcmV2Q29sdW1uIHByZXZpb3VzIG51bWJlciBvZiBjb2x1bW5zXG4gICAqIEBwYXJhbSBjb2x1bW4gIG5ldyBjb2x1bW4gbnVtYmVyXG4gICAqIEBwYXJhbSBub2RlcyBkaWZmZXJlbnQgc29ydGVkIGxpc3QgKGV4OiBET00gb3JkZXIpIGluc3RlYWQgb2YgY3VycmVudCBsaXN0XG4gICAqIEBwYXJhbSBsYXlvdXQgc3BlY2lmeSB0aGUgdHlwZSBvZiByZS1sYXlvdXQgdGhhdCB3aWxsIGhhcHBlbiAocG9zaXRpb24sIHNpemUsIGV0Yy4uLikuXG4gICAqIE5vdGU6IGl0ZW1zIHdpbGwgbmV2ZXIgYmUgb3V0c2lkZSBvZiB0aGUgY3VycmVudCBjb2x1bW4gYm91bmRhcmllcy4gZGVmYXVsdCAobW92ZVNjYWxlKS4gSWdub3JlZCBmb3IgMSBjb2x1bW5cbiAgICovXG4gIHB1YmxpYyB1cGRhdGVOb2RlV2lkdGhzKHByZXZDb2x1bW46IG51bWJlciwgY29sdW1uOiBudW1iZXIsIG5vZGVzOiBHcmlkU3RhY2tOb2RlW10sIGxheW91dDogQ29sdW1uT3B0aW9ucyA9ICdtb3ZlU2NhbGUnKTogR3JpZFN0YWNrRW5naW5lIHtcbiAgICBpZiAoIXRoaXMubm9kZXMubGVuZ3RoIHx8ICFjb2x1bW4gfHwgcHJldkNvbHVtbiA9PT0gY29sdW1uKSByZXR1cm4gdGhpcztcblxuICAgIC8vIGNhY2hlIHRoZSBjdXJyZW50IGxheW91dCBpbiBjYXNlIHRoZXkgd2FudCB0byBnbyBiYWNrIChsaWtlIDEyIC0+IDEgLT4gMTIpIGFzIGl0IHJlcXVpcmVzIG9yaWdpbmFsIGRhdGFcbiAgICB0aGlzLmNhY2hlTGF5b3V0KHRoaXMubm9kZXMsIHByZXZDb2x1bW4pO1xuICAgIHRoaXMuYmF0Y2hVcGRhdGUoKTsgLy8gZG8gdGhpcyBFQVJMWSBhcyBpdCB3aWxsIGNhbGwgc2F2ZUluaXRpYWwoKSBzbyB3ZSBjYW4gZGV0ZWN0IHdoZXJlIHdlIHN0YXJ0ZWQgZm9yIF9kaXJ0eSBhbmQgY29sbGlzaW9uXG4gICAgbGV0IG5ld05vZGVzOiBHcmlkU3RhY2tOb2RlW10gPSBbXTtcblxuICAgIC8vIGlmIHdlJ3JlIGdvaW5nIHRvIDEgY29sdW1uIGFuZCB1c2luZyBET00gb3JkZXIgcmF0aGVyIHRoYW4gZGVmYXVsdCBzb3J0aW5nLCB0aGVuIGdlbmVyYXRlIHRoYXQgbGF5b3V0XG4gICAgbGV0IGRvbU9yZGVyID0gZmFsc2U7XG4gICAgaWYgKGNvbHVtbiA9PT0gMSAmJiBub2Rlcz8ubGVuZ3RoKSB7XG4gICAgICBkb21PcmRlciA9IHRydWU7XG4gICAgICBsZXQgdG9wID0gMDtcbiAgICAgIG5vZGVzLmZvckVhY2gobiA9PiB7XG4gICAgICAgIG4ueCA9IDA7XG4gICAgICAgIG4udyA9IDE7XG4gICAgICAgIG4ueSA9IE1hdGgubWF4KG4ueSwgdG9wKTtcbiAgICAgICAgdG9wID0gbi55ICsgbi5oO1xuICAgICAgfSk7XG4gICAgICBuZXdOb2RlcyA9IG5vZGVzO1xuICAgICAgbm9kZXMgPSBbXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZXMgPSBVdGlscy5zb3J0KHRoaXMubm9kZXMsIC0xLCBwcmV2Q29sdW1uKTsgLy8gY3VycmVudCBjb2x1bW4gcmV2ZXJzZSBzb3J0aW5nIHNvIHdlIGNhbiBpbnNlcnQgbGFzdCB0byBmcm9udCAobGltaXQgY29sbGlzaW9uKVxuICAgIH1cblxuICAgIC8vIHNlZSBpZiB3ZSBoYXZlIGNhY2hlZCBwcmV2aW91cyBsYXlvdXQgSUZGIHdlIGFyZSBnb2luZyB1cCBpbiBzaXplIChyZXN0b3JlKSBvdGhlcndpc2UgYWx3YXlzXG4gICAgLy8gZ2VuZXJhdGUgbmV4dCBzaXplIGRvd24gZnJvbSB3aGVyZSB3ZSBhcmUgKGxvb2tzIG1vcmUgbmF0dXJhbCBhcyB5b3UgZ3JhZHVhbGx5IHNpemUgZG93bikuXG4gICAgbGV0IGNhY2hlTm9kZXM6IEdyaWRTdGFja05vZGVbXSA9IFtdO1xuICAgIGlmIChjb2x1bW4gPiBwcmV2Q29sdW1uKSB7XG4gICAgICBjYWNoZU5vZGVzID0gdGhpcy5fbGF5b3V0c1tjb2x1bW5dIHx8IFtdO1xuICAgICAgLy8gLi4uaWYgbm90LCBzdGFydCB3aXRoIHRoZSBsYXJnZXN0IGxheW91dCAoaWYgbm90IGFscmVhZHkgdGhlcmUpIGFzIGRvd24tc2NhbGluZyBpcyBtb3JlIGFjY3VyYXRlXG4gICAgICAvLyBieSBwcmV0ZW5kaW5nIHdlIGNhbWUgZnJvbSB0aGF0IGxhcmdlciBjb2x1bW4gYnkgYXNzaWduaW5nIHRob3NlIHZhbHVlcyBhcyBzdGFydGluZyBwb2ludFxuICAgICAgbGV0IGxhc3RJbmRleCA9IHRoaXMuX2xheW91dHMubGVuZ3RoIC0gMTtcbiAgICAgIGlmICghY2FjaGVOb2Rlcy5sZW5ndGggJiYgcHJldkNvbHVtbiAhPT0gbGFzdEluZGV4ICYmIHRoaXMuX2xheW91dHNbbGFzdEluZGV4XT8ubGVuZ3RoKSB7XG4gICAgICAgIHByZXZDb2x1bW4gPSBsYXN0SW5kZXg7XG4gICAgICAgIHRoaXMuX2xheW91dHNbbGFzdEluZGV4XS5mb3JFYWNoKGNhY2hlTm9kZSA9PiB7XG4gICAgICAgICAgbGV0IG4gPSBub2Rlcy5maW5kKG4gPT4gbi5faWQgPT09IGNhY2hlTm9kZS5faWQpO1xuICAgICAgICAgIGlmIChuKSB7XG4gICAgICAgICAgICAvLyBzdGlsbCBjdXJyZW50LCB1c2UgY2FjaGUgaW5mbyBwb3NpdGlvbnNcbiAgICAgICAgICAgIG4ueCA9IGNhY2hlTm9kZS54O1xuICAgICAgICAgICAgbi55ID0gY2FjaGVOb2RlLnk7XG4gICAgICAgICAgICBuLncgPSBjYWNoZU5vZGUudztcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGlmIHdlIGZvdW5kIGNhY2hlIHJlLXVzZSB0aG9zZSBub2RlcyB0aGF0IGFyZSBzdGlsbCBjdXJyZW50XG4gICAgY2FjaGVOb2Rlcy5mb3JFYWNoKGNhY2hlTm9kZSA9PiB7XG4gICAgICBsZXQgaiA9IG5vZGVzLmZpbmRJbmRleChuID0+IG4uX2lkID09PSBjYWNoZU5vZGUuX2lkKTtcbiAgICAgIGlmIChqICE9PSAtMSkge1xuICAgICAgICAvLyBzdGlsbCBjdXJyZW50LCB1c2UgY2FjaGUgaW5mbyBwb3NpdGlvbnNcbiAgICAgICAgaWYgKGNhY2hlTm9kZS5hdXRvUG9zaXRpb24gfHwgaXNOYU4oY2FjaGVOb2RlLngpIHx8IGlzTmFOKGNhY2hlTm9kZS55KSkge1xuICAgICAgICAgIHRoaXMuZmluZEVtcHR5UG9zaXRpb24oY2FjaGVOb2RlLCBuZXdOb2Rlcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjYWNoZU5vZGUuYXV0b1Bvc2l0aW9uKSB7XG4gICAgICAgICAgbm9kZXNbal0ueCA9IGNhY2hlTm9kZS54O1xuICAgICAgICAgIG5vZGVzW2pdLnkgPSBjYWNoZU5vZGUueTtcbiAgICAgICAgICBub2Rlc1tqXS53ID0gY2FjaGVOb2RlLnc7XG4gICAgICAgICAgbmV3Tm9kZXMucHVzaChub2Rlc1tqXSk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZXMuc3BsaWNlKGosIDEpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8vIC4uLmFuZCBhZGQgYW55IGV4dHJhIG5vbi1jYWNoZWQgb25lc1xuICAgIGlmIChub2Rlcy5sZW5ndGgpIHtcbiAgICAgIGlmICh0eXBlb2YgbGF5b3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGxheW91dChjb2x1bW4sIHByZXZDb2x1bW4sIG5ld05vZGVzLCBub2Rlcyk7XG4gICAgICB9IGVsc2UgaWYgKCFkb21PcmRlcikge1xuICAgICAgICBsZXQgcmF0aW8gPSBjb2x1bW4gLyBwcmV2Q29sdW1uO1xuICAgICAgICBsZXQgbW92ZSA9IChsYXlvdXQgPT09ICdtb3ZlJyB8fCBsYXlvdXQgPT09ICdtb3ZlU2NhbGUnKTtcbiAgICAgICAgbGV0IHNjYWxlID0gKGxheW91dCA9PT0gJ3NjYWxlJyB8fCBsYXlvdXQgPT09ICdtb3ZlU2NhbGUnKTtcbiAgICAgICAgbm9kZXMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAvLyBOT1RFOiB4ICsgdyBjb3VsZCBiZSBvdXRzaWRlIG9mIHRoZSBncmlkLCBidXQgYWRkTm9kZSgpIGJlbG93IHdpbGwgaGFuZGxlIHRoYXRcbiAgICAgICAgICBub2RlLnggPSAoY29sdW1uID09PSAxID8gMCA6IChtb3ZlID8gTWF0aC5yb3VuZChub2RlLnggKiByYXRpbykgOiBNYXRoLm1pbihub2RlLngsIGNvbHVtbiAtIDEpKSk7XG4gICAgICAgICAgbm9kZS53ID0gKChjb2x1bW4gPT09IDEgfHwgcHJldkNvbHVtbiA9PT0gMSkgPyAxIDpcbiAgICAgICAgICAgIHNjYWxlID8gKE1hdGgucm91bmQobm9kZS53ICogcmF0aW8pIHx8IDEpIDogKE1hdGgubWluKG5vZGUudywgY29sdW1uKSkpO1xuICAgICAgICAgIG5ld05vZGVzLnB1c2gobm9kZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBub2RlcyA9IFtdO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGZpbmFsbHkgcmUtbGF5b3V0IHRoZW0gaW4gcmV2ZXJzZSBvcmRlciAodG8gZ2V0IGNvcnJlY3QgcGxhY2VtZW50KVxuICAgIGlmICghZG9tT3JkZXIpIG5ld05vZGVzID0gVXRpbHMuc29ydChuZXdOb2RlcywgLTEsIGNvbHVtbik7XG4gICAgdGhpcy5faW5Db2x1bW5SZXNpemUgPSB0cnVlOyAvLyBwcmV2ZW50IGNhY2hlIHVwZGF0ZVxuICAgIHRoaXMubm9kZXMgPSBbXTsgLy8gcHJldGVuZCB3ZSBoYXZlIG5vIG5vZGVzIHRvIHN0YXJ0IHdpdGggKGFkZCgpIHdpbGwgdXNlIHNhbWUgc3RydWN0dXJlcykgdG8gc2ltcGxpZnkgbGF5b3V0XG4gICAgbmV3Tm9kZXMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgIHRoaXMuYWRkTm9kZShub2RlLCBmYWxzZSk7IC8vICdmYWxzZScgZm9yIGFkZCBldmVudCB0cmlnZ2VyXG4gICAgICBkZWxldGUgbm9kZS5fb3JpZzsgLy8gbWFrZSBzdXJlIHRoZSBjb21taXQgZG9lc24ndCB0cnkgdG8gcmVzdG9yZSB0aGluZ3MgYmFjayB0byBvcmlnaW5hbFxuICAgIH0pO1xuICAgIHRoaXMuYmF0Y2hVcGRhdGUoZmFsc2UpO1xuICAgIGRlbGV0ZSB0aGlzLl9pbkNvbHVtblJlc2l6ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBjYWxsIHRvIGNhY2hlIHRoZSBnaXZlbiBsYXlvdXQgaW50ZXJuYWxseSB0byB0aGUgZ2l2ZW4gbG9jYXRpb24gc28gd2UgY2FuIHJlc3RvcmUgYmFjayB3aGVuIGNvbHVtbiBjaGFuZ2VzIHNpemVcbiAgICogQHBhcmFtIG5vZGVzIGxpc3Qgb2Ygbm9kZXNcbiAgICogQHBhcmFtIGNvbHVtbiBjb3JyZXNwb25kaW5nIGNvbHVtbiBpbmRleCB0byBzYXZlIGl0IHVuZGVyXG4gICAqIEBwYXJhbSBjbGVhciBpZiB0cnVlLCB3aWxsIGZvcmNlIG90aGVyIGNhY2hlcyB0byBiZSByZW1vdmVkIChkZWZhdWx0IGZhbHNlKVxuICAgKi9cbiAgcHVibGljIGNhY2hlTGF5b3V0KG5vZGVzOiBHcmlkU3RhY2tOb2RlW10sIGNvbHVtbjogbnVtYmVyLCBjbGVhciA9IGZhbHNlKTogR3JpZFN0YWNrRW5naW5lIHtcbiAgICBsZXQgY29weTogR3JpZFN0YWNrTm9kZVtdID0gW107XG4gICAgbm9kZXMuZm9yRWFjaCgobiwgaSkgPT4ge1xuICAgICAgbi5faWQgPSBuLl9pZCA/PyBHcmlkU3RhY2tFbmdpbmUuX2lkU2VxKys7IC8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGFuIGlkIGluIGNhc2UgdGhpcyBpcyBuZXcgbGF5b3V0LCBlbHNlIHJlLXVzZSBpZCBhbHJlYWR5IHNldFxuICAgICAgY29weVtpXSA9IHt4OiBuLngsIHk6IG4ueSwgdzogbi53LCBfaWQ6IG4uX2lkfSAvLyBvbmx5IHRoaW5nIHdlIGNoYW5nZSBpcyB4LHksdyBhbmQgaWQgdG8gZmluZCBpdCBiYWNrXG4gICAgfSk7XG4gICAgdGhpcy5fbGF5b3V0cyA9IGNsZWFyID8gW10gOiB0aGlzLl9sYXlvdXRzIHx8IFtdOyAvLyB1c2UgYXJyYXkgdG8gZmluZCBsYXJnZXIgcXVpY2tcbiAgICB0aGlzLl9sYXlvdXRzW2NvbHVtbl0gPSBjb3B5O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIGNhbGwgdG8gY2FjaGUgdGhlIGdpdmVuIG5vZGUgbGF5b3V0IGludGVybmFsbHkgdG8gdGhlIGdpdmVuIGxvY2F0aW9uIHNvIHdlIGNhbiByZXN0b3JlIGJhY2sgd2hlbiBjb2x1bW4gY2hhbmdlcyBzaXplXG4gICAqIEBwYXJhbSBub2RlIHNpbmdsZSBub2RlIHRvIGNhY2hlXG4gICAqIEBwYXJhbSBjb2x1bW4gY29ycmVzcG9uZGluZyBjb2x1bW4gaW5kZXggdG8gc2F2ZSBpdCB1bmRlclxuICAgKi9cbiAgcHVibGljIGNhY2hlT25lTGF5b3V0KG46IEdyaWRTdGFja05vZGUsIGNvbHVtbjogbnVtYmVyKTogR3JpZFN0YWNrRW5naW5lIHtcbiAgICBuLl9pZCA9IG4uX2lkID8/IEdyaWRTdGFja0VuZ2luZS5faWRTZXErKztcbiAgICBsZXQgbDogR3JpZFN0YWNrTm9kZSA9IHt4OiBuLngsIHk6IG4ueSwgdzogbi53LCBfaWQ6IG4uX2lkfVxuICAgIGlmIChuLmF1dG9Qb3NpdGlvbikgeyBkZWxldGUgbC54OyBkZWxldGUgbC55OyBsLmF1dG9Qb3NpdGlvbiA9IHRydWU7IH1cbiAgICB0aGlzLl9sYXlvdXRzID0gdGhpcy5fbGF5b3V0cyB8fCBbXTtcbiAgICB0aGlzLl9sYXlvdXRzW2NvbHVtbl0gPSB0aGlzLl9sYXlvdXRzW2NvbHVtbl0gfHwgW107XG4gICAgbGV0IGluZGV4ID0gdGhpcy5maW5kQ2FjaGVMYXlvdXQobiwgY29sdW1uKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKVxuICAgICAgdGhpcy5fbGF5b3V0c1tjb2x1bW5dLnB1c2gobCk7XG4gICAgZWxzZVxuICAgICAgdGhpcy5fbGF5b3V0c1tjb2x1bW5dW2luZGV4XSA9IGw7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwcm90ZWN0ZWQgZmluZENhY2hlTGF5b3V0KG46IEdyaWRTdGFja05vZGUsIGNvbHVtbjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fbGF5b3V0cz8uW2NvbHVtbl0/LmZpbmRJbmRleChsID0+IGwuX2lkID09PSBuLl9pZCkgPz8gLTE7XG4gIH1cblxuXG4gIC8qKiBjYWxsZWQgdG8gcmVtb3ZlIGFsbCBpbnRlcm5hbCB2YWx1ZXMgYnV0IHRoZSBfaWQgKi9cbiAgcHVibGljIGNsZWFudXBOb2RlKG5vZGU6IEdyaWRTdGFja05vZGUpOiBHcmlkU3RhY2tFbmdpbmUge1xuICAgIGZvciAobGV0IHByb3AgaW4gbm9kZSkge1xuICAgICAgaWYgKHByb3BbMF0gPT09ICdfJyAmJiBwcm9wICE9PSAnX2lkJykgZGVsZXRlIG5vZGVbcHJvcF07XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG4iLCIvKipcclxuICogdHlwZXMudHMgOC4yLjJcclxuICogQ29weXJpZ2h0IChjKSAyMDIxIEFsYWluIER1bWVzbnkgLSBzZWUgR3JpZFN0YWNrIHJvb3QgbGljZW5zZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IEdyaWRTdGFjayB9IGZyb20gJy4vZ3JpZHN0YWNrJztcclxuaW1wb3J0IHsgR3JpZFN0YWNrRW5naW5lIH0gZnJvbSAnLi9ncmlkc3RhY2stZW5naW5lJztcclxuXHJcbi8vIGRlZmF1bHQgdmFsdWVzIGZvciBncmlkIG9wdGlvbnMgLSB1c2VkIGR1cmluZyBpbml0IGFuZCB3aGVuIHNhdmluZyBvdXRcclxuZXhwb3J0IGNvbnN0IGdyaWREZWZhdWx0czogR3JpZFN0YWNrT3B0aW9ucyA9IHtcclxuICBhbHdheXNTaG93UmVzaXplSGFuZGxlOiAnbW9iaWxlJyxcclxuICBhbmltYXRlOiB0cnVlLFxyXG4gIGF1dG86IHRydWUsXHJcbiAgY2VsbEhlaWdodDogJ2F1dG8nLFxyXG4gIGNlbGxIZWlnaHRUaHJvdHRsZTogMTAwLFxyXG4gIGNlbGxIZWlnaHRVbml0OiAncHgnLFxyXG4gIGNvbHVtbjogMTIsXHJcbiAgZHJhZ2dhYmxlOiB7IGhhbmRsZTogJy5ncmlkLXN0YWNrLWl0ZW0tY29udGVudCcsIGFwcGVuZFRvOiAnYm9keScsIHNjcm9sbDogdHJ1ZSB9LFxyXG4gIGhhbmRsZTogJy5ncmlkLXN0YWNrLWl0ZW0tY29udGVudCcsXHJcbiAgaXRlbUNsYXNzOiAnZ3JpZC1zdGFjay1pdGVtJyxcclxuICBtYXJnaW46IDEwLFxyXG4gIG1hcmdpblVuaXQ6ICdweCcsXHJcbiAgbWF4Um93OiAwLFxyXG4gIG1pblJvdzogMCxcclxuICBvbmVDb2x1bW5TaXplOiA3NjgsXHJcbiAgcGxhY2Vob2xkZXJDbGFzczogJ2dyaWQtc3RhY2stcGxhY2Vob2xkZXInLFxyXG4gIHBsYWNlaG9sZGVyVGV4dDogJycsXHJcbiAgcmVtb3ZhYmxlT3B0aW9uczogeyBhY2NlcHQ6ICcuZ3JpZC1zdGFjay1pdGVtJyB9LFxyXG4gIHJlc2l6YWJsZTogeyBoYW5kbGVzOiAnc2UnIH0sXHJcbiAgcnRsOiAnYXV0bycsXHJcblxyXG4gIC8vICoqKiogc2FtZSBhcyBub3QgYmVpbmcgc2V0ICoqKipcclxuICAvLyBkaXNhYmxlRHJhZzogZmFsc2UsXHJcbiAgLy8gZGlzYWJsZU9uZUNvbHVtbk1vZGU6IGZhbHNlLFxyXG4gIC8vIGRpc2FibGVSZXNpemU6IGZhbHNlLFxyXG4gIC8vIGZsb2F0OiBmYWxzZSxcclxuICAvLyBoYW5kbGVDbGFzczogbnVsbCxcclxuICAvLyBvbmVDb2x1bW5Nb2RlRG9tU29ydDogZmFsc2UsXHJcbiAgLy8gcmVtb3ZhYmxlOiBmYWxzZSxcclxuICAvLyBzdGF0aWNHcmlkOiBmYWxzZSxcclxuICAvLyBzdHlsZUluSGVhZDogZmFsc2UsXHJcbn07XHJcblxyXG4vKiogZGVmYXVsdCBkcmFnSW4gb3B0aW9ucyAqL1xyXG5leHBvcnQgY29uc3QgZHJhZ0luRGVmYXVsdE9wdGlvbnM6IERERHJhZ0luT3B0ID0ge1xyXG4gIGhhbmRsZTogJy5ncmlkLXN0YWNrLWl0ZW0tY29udGVudCcsXHJcbiAgYXBwZW5kVG86ICdib2R5JyxcclxuICAvLyByZXZlcnQ6ICdpbnZhbGlkJyxcclxuICAvLyBzY3JvbGw6IGZhbHNlLFxyXG59O1xyXG5cclxuLyoqIGRpZmZlcmVudCBsYXlvdXQgb3B0aW9ucyB3aGVuIGNoYW5naW5nICMgb2YgY29sdW1ucyxcclxuICogaW5jbHVkaW5nIGEgY3VzdG9tIGZ1bmN0aW9uIHRoYXQgdGFrZXMgbmV3L29sZCBjb2x1bW4gY291bnQsIGFuZCBhcnJheSBvZiBuZXcvb2xkIHBvc2l0aW9uc1xyXG4gKiBOb3RlOiBuZXcgbGlzdCBtYXkgYmUgcGFydGlhbGx5IGFscmVhZHkgZmlsbGVkIGlmIHdlIGhhdmUgYSBjYWNoZSBvZiB0aGUgbGF5b3V0IGF0IHRoYXQgc2l6ZSBhbmQgbmV3IGl0ZW1zIHdlcmUgYWRkZWQgbGF0ZXIuXHJcbiAqL1xyXG5leHBvcnQgdHlwZSBDb2x1bW5PcHRpb25zID0gJ21vdmVTY2FsZScgfCAnbW92ZScgfCAnc2NhbGUnIHwgJ25vbmUnIHxcclxuICAoKGNvbHVtbjogbnVtYmVyLCBvbGRDb2x1bW46IG51bWJlciwgbm9kZXM6IEdyaWRTdGFja05vZGVbXSwgb2xkTm9kZXM6IEdyaWRTdGFja05vZGVbXSkgPT4gdm9pZCk7XHJcblxyXG5leHBvcnQgdHlwZSBudW1iZXJPclN0cmluZyA9IG51bWJlciB8IHN0cmluZztcclxuZXhwb3J0IGludGVyZmFjZSBHcmlkSXRlbUhUTUxFbGVtZW50IGV4dGVuZHMgSFRNTEVsZW1lbnQge1xyXG4gIC8qKiBwb2ludGVyIHRvIGdyaWQgbm9kZSBpbnN0YW5jZSAqL1xyXG4gIGdyaWRzdGFja05vZGU/OiBHcmlkU3RhY2tOb2RlO1xyXG4gIC8qKiBAaW50ZXJuYWwgKi9cclxuICBfZ3JpZHN0YWNrTm9kZU9yaWc/OiBHcmlkU3RhY2tOb2RlO1xyXG59XHJcblxyXG5leHBvcnQgdHlwZSBHcmlkU3RhY2tFbGVtZW50ID0gc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCBHcmlkSXRlbUhUTUxFbGVtZW50O1xyXG5cclxuLyoqIHNwZWNpZmljIGFuZCBnZW5lcmFsIGV2ZW50IGhhbmRsZXJzIGZvciB0aGUgLm9uKCkgbWV0aG9kICovXHJcbmV4cG9ydCB0eXBlIEdyaWRTdGFja0V2ZW50SGFuZGxlciA9IChldmVudDogRXZlbnQpID0+IHZvaWQ7XHJcbmV4cG9ydCB0eXBlIEdyaWRTdGFja0VsZW1lbnRIYW5kbGVyID0gKGV2ZW50OiBFdmVudCwgZWw6IEdyaWRJdGVtSFRNTEVsZW1lbnQpID0+IHZvaWQ7XHJcbmV4cG9ydCB0eXBlIEdyaWRTdGFja05vZGVzSGFuZGxlciA9IChldmVudDogRXZlbnQsIG5vZGVzOiBHcmlkU3RhY2tOb2RlW10pID0+IHZvaWQ7XHJcbmV4cG9ydCB0eXBlIEdyaWRTdGFja0Ryb3BwZWRIYW5kbGVyID0gKGV2ZW50OiBFdmVudCwgcHJldmlvdXNOb2RlOiBHcmlkU3RhY2tOb2RlLCBuZXdOb2RlOiBHcmlkU3RhY2tOb2RlKSA9PiB2b2lkO1xyXG5leHBvcnQgdHlwZSBHcmlkU3RhY2tFdmVudEhhbmRsZXJDYWxsYmFjayA9IEdyaWRTdGFja0V2ZW50SGFuZGxlciB8IEdyaWRTdGFja0VsZW1lbnRIYW5kbGVyIHwgR3JpZFN0YWNrTm9kZXNIYW5kbGVyIHwgR3JpZFN0YWNrRHJvcHBlZEhhbmRsZXI7XHJcblxyXG4vKiogb3B0aW9uYWwgZnVuY3Rpb24gY2FsbGVkIGR1cmluZyBsb2FkKCkgdG8gY2FsbGJhY2sgdGhlIHVzZXIgb24gbmV3IGFkZGVkL3JlbW92ZSBncmlkIGl0ZW1zIHwgZ3JpZHMgKi9cclxuZXhwb3J0IHR5cGUgQWRkUmVtb3ZlRmNuID0gKHBhcmVudDogSFRNTEVsZW1lbnQsIHc6IEdyaWRTdGFja1dpZGdldCwgYWRkOiBib29sZWFuLCBncmlkOiBib29sZWFuKSA9PiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZDtcclxuXHJcbi8qKiBvcHRpb25hbCBmdW5jdGlvbiBjYWxsZWQgZHVyaW5nIHNhdmUoKSB0byBsZXQgdGhlIGNhbGxlciBhZGQgYWRkaXRpb25hbCBjdXN0b20gZGF0YSB0byB0aGUgR3JpZFN0YWNrV2lkZ2V0IHN0cnVjdHVyZSB0aGF0IHdpbGwgZ2V0IHJldHVybmVkICovXHJcbmV4cG9ydCB0eXBlIFNhdmVGY24gPSAobm9kZTogR3JpZFN0YWNrTm9kZSwgdzogR3JpZFN0YWNrV2lkZ2V0KSA9PiB2b2lkO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBEZWZpbmVzIHRoZSBvcHRpb25zIGZvciBhIEdyaWRcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgR3JpZFN0YWNrT3B0aW9ucyB7XHJcbiAgLyoqXHJcbiAgICogYWNjZXB0IHdpZGdldHMgZHJhZ2dlZCBmcm9tIG90aGVyIGdyaWRzIG9yIGZyb20gb3V0c2lkZSAoZGVmYXVsdDogYGZhbHNlYCkuIENhbiBiZTpcclxuICAgKiBgdHJ1ZWAgKHVzZXMgYCcuZ3JpZC1zdGFjay1pdGVtJ2AgY2xhc3MgZmlsdGVyKSBvciBgZmFsc2VgLFxyXG4gICAqIHN0cmluZyBmb3IgZXhwbGljaXQgY2xhc3MgbmFtZSxcclxuICAgKiBmdW5jdGlvbiByZXR1cm5pbmcgYSBib29sZWFuLiBTZWUgW2V4YW1wbGVdKGh0dHA6Ly9ncmlkc3RhY2suZ2l0aHViLmlvL2dyaWRzdGFjay5qcy9kZW1vL3R3by5odG1sKVxyXG4gICAqL1xyXG4gIGFjY2VwdFdpZGdldHM/OiBib29sZWFuIHwgc3RyaW5nIHwgKChlbGVtZW50OiBFbGVtZW50KSA9PiBib29sZWFuKTtcclxuXHJcbiAgLyoqIHBvc3NpYmxlIHZhbHVlcyAoZGVmYXVsdDogYG1vYmlsZWApIC0gZG9lcyBub3QgYXBwbHkgdG8gbm9uLXJlc2l6YWJsZSB3aWRnZXRzXHJcbiAgICAqIGBmYWxzZWAgdGhlIHJlc2l6aW5nIGhhbmRsZXMgYXJlIG9ubHkgc2hvd24gd2hpbGUgaG92ZXJpbmcgb3ZlciBhIHdpZGdldFxyXG4gICAgKiBgdHJ1ZWAgdGhlIHJlc2l6aW5nIGhhbmRsZXMgYXJlIGFsd2F5cyBzaG93blxyXG4gICAgKiAnbW9iaWxlJyBpZiBydW5uaW5nIG9uIGEgbW9iaWxlIGRldmljZSwgZGVmYXVsdCB0byBgdHJ1ZWAgKHNpbmNlIHRoZXJlIGlzIG5vIGhvdmVyaW5nIHBlciBzYXkpLCBlbHNlIGBmYWxzZWAuXHJcbiAgICBTZWUgW2V4YW1wbGVdKGh0dHA6Ly9ncmlkc3RhY2suZ2l0aHViLmlvL2dyaWRzdGFjay5qcy9kZW1vL21vYmlsZS5odG1sKSAqL1xyXG4gIGFsd2F5c1Nob3dSZXNpemVIYW5kbGU/OiB0cnVlIHwgZmFsc2UgfCAnbW9iaWxlJztcclxuXHJcbiAgLyoqIHR1cm5zIGFuaW1hdGlvbiBvbiAoZGVmYXVsdD86IHRydWUpICovXHJcbiAgYW5pbWF0ZT86IGJvb2xlYW47XHJcblxyXG4gIC8qKiBpZiBmYWxzZSBncmlkc3RhY2sgd2lsbCBub3QgaW5pdGlhbGl6ZSBleGlzdGluZyBpdGVtcyAoZGVmYXVsdD86IHRydWUpICovXHJcbiAgYXV0bz86IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIG9uZSBjZWxsIGhlaWdodCAoZGVmYXVsdD86ICdhdXRvJykuIENhbiBiZTpcclxuICAgKiAgYW4gaW50ZWdlciAocHgpXHJcbiAgICogIGEgc3RyaW5nIChleDogJzEwMHB4JywgJzEwZW0nLCAnMTByZW0nKS4gTm90ZTogJSBkb2Vzbid0IHJpZ2h0IC0gc2VlIGRlbW8vY2VsbC1oZWlnaHQuaHRtbFxyXG4gICAqICAwLCBpbiB3aGljaCBjYXNlIHRoZSBsaWJyYXJ5IHdpbGwgbm90IGdlbmVyYXRlIHN0eWxlcyBmb3Igcm93cy4gRXZlcnl0aGluZyBtdXN0IGJlIGRlZmluZWQgaW4geW91ciBvd24gQ1NTIGZpbGVzLlxyXG4gICAqICAnYXV0bycgLSBoZWlnaHQgd2lsbCBiZSBjYWxjdWxhdGVkIGZvciBzcXVhcmUgY2VsbHMgKHdpZHRoIC8gY29sdW1uKSBhbmQgdXBkYXRlZCBsaXZlIGFzIHlvdSByZXNpemUgdGhlIHdpbmRvdyAtIGFsc28gc2VlIGBjZWxsSGVpZ2h0VGhyb3R0bGVgXHJcbiAgICogICdpbml0aWFsJyAtIHNpbWlsYXIgdG8gJ2F1dG8nIChzdGFydCBhdCBzcXVhcmUgY2VsbHMpIGJ1dCBzdGF5IHRoYXQgc2l6ZSBkdXJpbmcgd2luZG93IHJlc2l6aW5nLlxyXG4gICAqL1xyXG4gIGNlbGxIZWlnaHQ/OiBudW1iZXJPclN0cmluZztcclxuXHJcbiAgLyoqIHRocm90dGxlIHRpbWUgZGVsYXkgKGluIG1zKSB1c2VkIHdoZW4gY2VsbEhlaWdodD0nYXV0bycgdG8gaW1wcm92ZSBwZXJmb3JtYW5jZSB2cyB1c2FiaWxpdHkgKGRlZmF1bHQ/OiAxMDApLlxyXG4gICAqIEEgdmFsdWUgb2YgMCB3aWxsIG1ha2UgaXQgaW5zdGFudCBhdCBhIGNvc3Qgb2YgcmUtY3JlYXRpbmcgdGhlIENTUyBmaWxlIGF0IGV2ZXIgd2luZG93IHJlc2l6ZSBldmVudCFcclxuICAgKiAqL1xyXG4gIGNlbGxIZWlnaHRUaHJvdHRsZT86IG51bWJlcjtcclxuXHJcbiAgLyoqIChpbnRlcm5hbCkgdW5pdCBmb3IgY2VsbEhlaWdodCAoZGVmYXVsdD8gJ3B4Jykgd2hpY2ggaXMgc2V0IHdoZW4gYSBzdHJpbmcgY2VsbEhlaWdodCB3aXRoIGEgdW5pdCBpcyBwYXNzZWQgKGV4OiAnMTByZW0nKSAqL1xyXG4gIGNlbGxIZWlnaHRVbml0Pzogc3RyaW5nO1xyXG5cclxuICAvKiogbGlzdCBvZiBjaGlsZHJlbiBpdGVtIHRvIGNyZWF0ZSB3aGVuIGNhbGxpbmcgbG9hZCgpIG9yIGFkZEdyaWQoKSAqL1xyXG4gIGNoaWxkcmVuPzogR3JpZFN0YWNrV2lkZ2V0W107XHJcblxyXG4gIC8qKiBudW1iZXIgb2YgY29sdW1ucyAoZGVmYXVsdD86IDEyKS4gTm90ZTogSUYgeW91IGNoYW5nZSB0aGlzLCBDU1MgYWxzbyBoYXZlIHRvIGNoYW5nZS4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ncmlkc3RhY2svZ3JpZHN0YWNrLmpzI2NoYW5nZS1ncmlkLWNvbHVtbnMuXHJcbiAgICogTm90ZTogZm9yIG5lc3RlZCBncmlkcywgaXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlICdhdXRvJyB3aGljaCB3aWxsIGFsd2F5cyBtYXRjaCB0aGUgY29udGFpbmVyIGdyaWQtaXRlbSBjdXJyZW50IHdpZHRoIChpbiBjb2x1bW4pIHRvIGtlZXAgaW5zaWRlIGFuZCBvdXRzaWRlXHJcbiAgICogaXRlbXMgYWx3YXlzIHRvIHNhbWUuIGZsYWcgaXMgbm90IHN1cHBvcnRlZCBmb3IgcmVndWxhciBub24tbmVzdGVkIGdyaWRzLlxyXG4gICAqL1xyXG4gIGNvbHVtbj86IG51bWJlciB8ICdhdXRvJztcclxuXHJcbiAgLyoqIGFkZGl0aW9uYWwgY2xhc3Mgb24gdG9wIG9mICcuZ3JpZC1zdGFjaycgKHdoaWNoIGlzIHJlcXVpcmVkIGZvciBvdXIgQ1NTKSB0byBkaWZmZXJlbnRpYXRlIHRoaXMgaW5zdGFuY2UuXHJcbiAgTm90ZTogb25seSB1c2VkIGJ5IGFkZEdyaWQoKSwgZWxzZSB5b3VyIGVsZW1lbnQgc2hvdWxkIGhhdmUgdGhlIG5lZWRlZCBjbGFzcyAqL1xyXG4gIGNsYXNzPzogc3RyaW5nO1xyXG5cclxuICAvKiogZGlzYWxsb3dzIGRyYWdnaW5nIG9mIHdpZGdldHMgKGRlZmF1bHQ/OiBmYWxzZSkgKi9cclxuICBkaXNhYmxlRHJhZz86IGJvb2xlYW47XHJcblxyXG4gIC8qKiBkaXNhYmxlcyB0aGUgb25Db2x1bW5Nb2RlIHdoZW4gdGhlIGdyaWQgd2lkdGggaXMgbGVzcyB0aGFuIG9uZUNvbHVtblNpemUgKGRlZmF1bHQ/OiBmYWxzZSkgKi9cclxuICBkaXNhYmxlT25lQ29sdW1uTW9kZT86IGJvb2xlYW47XHJcblxyXG4gIC8qKiBkaXNhbGxvd3MgcmVzaXppbmcgb2Ygd2lkZ2V0cyAoZGVmYXVsdD86IGZhbHNlKS4gKi9cclxuICBkaXNhYmxlUmVzaXplPzogYm9vbGVhbjtcclxuXHJcbiAgLyoqIGFsbG93cyB0byBvdmVycmlkZSBVSSBkcmFnZ2FibGUgb3B0aW9ucy4gKGRlZmF1bHQ/OiB7IGhhbmRsZT86ICcuZ3JpZC1zdGFjay1pdGVtLWNvbnRlbnQnLCBhcHBlbmRUbz86ICdib2R5JyB9KSAqL1xyXG4gIGRyYWdnYWJsZT86IERERHJhZ09wdDtcclxuXHJcbiAgLyoqIGxldCB1c2VyIGRyYWcgbmVzdGVkIGdyaWQgaXRlbXMgb3V0IG9mIGEgcGFyZW50IG9yIG5vdCAoZGVmYXVsdCB0cnVlIC0gbm90IHN1cHBvcnRlZCB5ZXQpICovXHJcbiAgLy9kcmFnT3V0PzogYm9vbGVhbjtcclxuXHJcbiAgLyoqIHRoZSB0eXBlIG9mIGVuZ2luZSB0byBjcmVhdGUgKHNvIHlvdSBjYW4gc3ViY2xhc3MpIGRlZmF1bHQgdG8gR3JpZFN0YWNrRW5naW5lICovXHJcbiAgZW5naW5lQ2xhc3M/OiB0eXBlb2YgR3JpZFN0YWNrRW5naW5lO1xyXG5cclxuICAvKiogZW5hYmxlIGZsb2F0aW5nIHdpZGdldHMgKGRlZmF1bHQ/OiBmYWxzZSkgU2VlIGV4YW1wbGUgKGh0dHA6Ly9ncmlkc3RhY2suZ2l0aHViLmlvL2dyaWRzdGFjay5qcy9kZW1vL2Zsb2F0Lmh0bWwpICovXHJcbiAgZmxvYXQ/OiBib29sZWFuO1xyXG5cclxuICAvKiogZHJhZ2dhYmxlIGhhbmRsZSBzZWxlY3RvciAoZGVmYXVsdD86ICcuZ3JpZC1zdGFjay1pdGVtLWNvbnRlbnQnKSAqL1xyXG4gIGhhbmRsZT86IHN0cmluZztcclxuXHJcbiAgLyoqIGRyYWdnYWJsZSBoYW5kbGUgY2xhc3MgKGUuZy4gJ2dyaWQtc3RhY2staXRlbS1jb250ZW50JykuIElmIHNldCAnaGFuZGxlJyBpcyBpZ25vcmVkIChkZWZhdWx0PzogbnVsbCkgKi9cclxuICBoYW5kbGVDbGFzcz86IHN0cmluZztcclxuXHJcbiAgLyoqIGFkZGl0aW9uYWwgd2lkZ2V0IGNsYXNzIChkZWZhdWx0PzogJ2dyaWQtc3RhY2staXRlbScpICovXHJcbiAgaXRlbUNsYXNzPzogc3RyaW5nO1xyXG5cclxuICAvKipcclxuICAgKiBnYXAgYmV0d2VlbiBncmlkIGl0ZW0gYW5kIGNvbnRlbnQgKGRlZmF1bHQ/OiAxMCkuIFRoaXMgd2lsbCBzZXQgYWxsIDQgc2lkZXMgYW5kIHN1cHBvcnQgdGhlIENTUyBmb3JtYXRzIGJlbG93XHJcbiAgICogIGFuIGludGVnZXIgKHB4KVxyXG4gICAqICBhIHN0cmluZyB3aXRoIHBvc3NpYmxlIHVuaXRzIChleDogJzJlbScsICcyMHB4JywgJzJyZW0nKVxyXG4gICAqICBzdHJpbmcgd2l0aCBzcGFjZSBzZXBhcmF0ZWQgdmFsdWVzIChleDogJzVweCAxMHB4IDAgMjBweCcgZm9yIGFsbCA0IHNpZGVzLCBvciAnNWVtIDEwZW0nIGZvciB0b3AvYm90dG9tIGFuZCBsZWZ0L3JpZ2h0IHBhaXJzIGxpa2UgQ1NTKS5cclxuICAgKiBOb3RlOiBhbGwgc2lkZXMgbXVzdCBoYXZlIHNhbWUgdW5pdHMgKGxhc3Qgb25lIHdpbnMsIGRlZmF1bHQgcHgpXHJcbiAgICovXHJcbiAgbWFyZ2luPzogbnVtYmVyT3JTdHJpbmc7XHJcblxyXG4gIC8qKiBPTEQgd2F5IHRvIG9wdGlvbmFsbHkgc2V0IGVhY2ggc2lkZSAtIHVzZSBtYXJnaW46ICc1cHggMTBweCAwIDIwcHgnIGluc3RlYWQuIFVzZWQgaW50ZXJuYWxseSB0byBzdG9yZSBlYWNoIHNpZGUuICovXHJcbiAgbWFyZ2luVG9wPzogbnVtYmVyT3JTdHJpbmc7XHJcbiAgbWFyZ2luUmlnaHQ/OiBudW1iZXJPclN0cmluZztcclxuICBtYXJnaW5Cb3R0b20/OiBudW1iZXJPclN0cmluZztcclxuICBtYXJnaW5MZWZ0PzogbnVtYmVyT3JTdHJpbmc7XHJcblxyXG4gIC8qKiAoaW50ZXJuYWwpIHVuaXQgZm9yIG1hcmdpbiAoZGVmYXVsdD8gJ3B4Jykgc2V0IHdoZW4gYG1hcmdpbmAgaXMgc2V0IGFzIHN0cmluZyB3aXRoIHVuaXQgKGV4OiAycmVtJykgKi9cclxuICBtYXJnaW5Vbml0Pzogc3RyaW5nO1xyXG5cclxuICAvKiogbWF4aW11bSByb3dzIGFtb3VudC4gRGVmYXVsdD8gaXMgMCB3aGljaCBtZWFucyBubyBtYXhpbXVtIHJvd3MgKi9cclxuICBtYXhSb3c/OiBudW1iZXI7XHJcblxyXG4gIC8qKiBtaW5pbXVtIHJvd3MgYW1vdW50LiBEZWZhdWx0IGlzIGAwYC4gWW91IGNhbiBhbHNvIGRvIHRoaXMgd2l0aCBgbWluLWhlaWdodGAgQ1NTIGF0dHJpYnV0ZVxyXG4gICAqIG9uIHRoZSBncmlkIGRpdiBpbiBwaXhlbHMsIHdoaWNoIHdpbGwgcm91bmQgdG8gdGhlIGNsb3Nlc3Qgcm93LlxyXG4gICAqL1xyXG4gIG1pblJvdz86IG51bWJlcjtcclxuXHJcbiAgLyoqIElmIHlvdSBhcmUgdXNpbmcgYSBub25jZS1iYXNlZCBDb250ZW50IFNlY3VyaXR5IFBvbGljeSwgcGFzcyB5b3VyIG5vbmNlIGhlcmUgYW5kXHJcbiAgICogR3JpZFN0YWNrIHdpbGwgYWRkIGl0IHRvIHRoZSA8c3R5bGU+IGVsZW1lbnRzIGl0IGNyZWF0ZXMuICovXHJcbiAgbm9uY2U/OiBzdHJpbmc7XHJcblxyXG4gIC8qKiBtaW5pbWFsIHdpZHRoIGJlZm9yZSBncmlkIHdpbGwgYmUgc2hvd24gaW4gb25lIGNvbHVtbiBtb2RlIChkZWZhdWx0PzogNzY4KSAqL1xyXG4gIG9uZUNvbHVtblNpemU/OiBudW1iZXI7XHJcblxyXG4gIC8qKlxyXG4gICAqIHNldCB0byB0cnVlIGlmIHlvdSB3YW50IG9uZUNvbHVtbk1vZGUgdG8gdXNlIHRoZSBET00gb3JkZXIgYW5kIGlnbm9yZSB4LHkgZnJvbSBub3JtYWwgbXVsdGkgY29sdW1uXHJcbiAgICogbGF5b3V0cyBkdXJpbmcgc29ydGluZy4gVGhpcyBlbmFibGVzIHlvdSB0byBoYXZlIGN1c3RvbSAxIGNvbHVtbiBsYXlvdXQgdGhhdCBkaWZmZXIgZnJvbSB0aGUgcmVzdC4gKGRlZmF1bHQ/OiBmYWxzZSlcclxuICAgKi9cclxuICBvbmVDb2x1bW5Nb2RlRG9tU29ydD86IGJvb2xlYW47XHJcblxyXG4gIC8qKiBjbGFzcyBmb3IgcGxhY2Vob2xkZXIgKGRlZmF1bHQ/OiAnZ3JpZC1zdGFjay1wbGFjZWhvbGRlcicpICovXHJcbiAgcGxhY2Vob2xkZXJDbGFzcz86IHN0cmluZztcclxuXHJcbiAgLyoqIHBsYWNlaG9sZGVyIGRlZmF1bHQgY29udGVudCAoZGVmYXVsdD86ICcnKSAqL1xyXG4gIHBsYWNlaG9sZGVyVGV4dD86IHN0cmluZztcclxuXHJcbiAgLyoqIGFsbG93cyB0byBvdmVycmlkZSBVSSByZXNpemFibGUgb3B0aW9ucy4gKGRlZmF1bHQ/OiB7IGhhbmRsZXM6ICdzZScgfSkgKi9cclxuICByZXNpemFibGU/OiBERFJlc2l6ZU9wdDtcclxuXHJcbiAgLyoqXHJcbiAgICogaWYgdHJ1ZSB3aWRnZXRzIGNvdWxkIGJlIHJlbW92ZWQgYnkgZHJhZ2dpbmcgb3V0c2lkZSBvZiB0aGUgZ3JpZC4gSXQgY291bGQgYWxzbyBiZSBhIHNlbGVjdG9yIHN0cmluZyAoZXg6IFwiLnRyYXNoXCIpLFxyXG4gICAqIGluIHRoaXMgY2FzZSB3aWRnZXRzIHdpbGwgYmUgcmVtb3ZlZCBieSBkcm9wcGluZyB0aGVtIHRoZXJlIChkZWZhdWx0PzogZmFsc2UpXHJcbiAgICogU2VlIGV4YW1wbGUgKGh0dHA6Ly9ncmlkc3RhY2suZ2l0aHViLmlvL2dyaWRzdGFjay5qcy9kZW1vL3R3by5odG1sKVxyXG4gICAqL1xyXG4gIHJlbW92YWJsZT86IGJvb2xlYW4gfCBzdHJpbmc7XHJcblxyXG4gIC8qKiBhbGxvd3MgdG8gb3ZlcnJpZGUgVUkgcmVtb3ZhYmxlIG9wdGlvbnMuIChkZWZhdWx0PzogeyBhY2NlcHQ6ICcuZ3JpZC1zdGFjay1pdGVtJyB9KSAqL1xyXG4gIHJlbW92YWJsZU9wdGlvbnM/OiBERFJlbW92ZU9wdDtcclxuXHJcbiAgLyoqIGZpeCBncmlkIG51bWJlciBvZiByb3dzLiBUaGlzIGlzIGEgc2hvcnRjdXQgb2Ygd3JpdGluZyBgbWluUm93Ok4sIG1heFJvdzpOYC4gKGRlZmF1bHQgYDBgIG5vIGNvbnN0cmFpbikgKi9cclxuICByb3c/OiBudW1iZXI7XHJcblxyXG4gIC8qKlxyXG4gICAqIGlmIHRydWUgdHVybnMgZ3JpZCB0byBSVEwuIFBvc3NpYmxlIHZhbHVlcyBhcmUgdHJ1ZSwgZmFsc2UsICdhdXRvJyAoZGVmYXVsdD86ICdhdXRvJylcclxuICAgKiBTZWUgW2V4YW1wbGVdKGh0dHA6Ly9ncmlkc3RhY2suZ2l0aHViLmlvL2dyaWRzdGFjay5qcy9kZW1vL3J0bC5odG1sKVxyXG4gICAqL1xyXG4gIHJ0bD86IGJvb2xlYW4gfCAnYXV0byc7XHJcblxyXG4gIC8qKlxyXG4gICAqIG1ha2VzIGdyaWQgc3RhdGljIChkZWZhdWx0PzogZmFsc2UpLiBJZiBgdHJ1ZWAgd2lkZ2V0cyBhcmUgbm90IG1vdmFibGUvcmVzaXphYmxlLlxyXG4gICAqIFlvdSBkb24ndCBldmVuIG5lZWQgZHJhZ2dhYmxlL3Jlc2l6YWJsZS4gQSBDU1MgY2xhc3NcclxuICAgKiAnZ3JpZC1zdGFjay1zdGF0aWMnIGlzIGFsc28gYWRkZWQgdG8gdGhlIGVsZW1lbnQuXHJcbiAgICovXHJcbiAgc3RhdGljR3JpZD86IGJvb2xlYW47XHJcblxyXG4gIC8qKiBpZiBgdHJ1ZWAgd2lsbCBhZGQgc3R5bGUgZWxlbWVudCB0byBgPGhlYWQ+YCBvdGhlcndpc2Ugd2lsbCBhZGQgaXQgdG8gZWxlbWVudCdzIHBhcmVudCBub2RlIChkZWZhdWx0IGBmYWxzZWApLiAqL1xyXG4gIHN0eWxlSW5IZWFkPzogYm9vbGVhbjtcclxuXHJcbiAgLyoqIGxpc3Qgb2YgZGlmZmVyZW5jZXMgaW4gb3B0aW9ucyBmb3IgYXV0b21hdGljYWxseSBjcmVhdGVkIHN1Yi1ncmlkcyB1bmRlciB1cyAoaW5zaWRlIG91ciBncmlkLWl0ZW1zKSAqL1xyXG4gIHN1YkdyaWRPcHRzPzogR3JpZFN0YWNrT3B0aW9ucztcclxuXHJcbiAgLyoqIGVuYWJsZS9kaXNhYmxlIHRoZSBjcmVhdGlvbiBvZiBzdWItZ3JpZHMgb24gdGhlIGZseSBieSBkcmFnZ2luZyBpdGVtcyBjb21wbGV0ZWx5XHJcbiAgICogb3ZlciBvdGhlcnMgKG5lc3QpIHZzIHBhcnRpYWxseSAocHVzaCkuIEZvcmNlcyBgREREcmFnT3B0LnBhdXNlPXRydWVgIHRvIGFjY29tcGxpc2ggdGhhdC4gKi9cclxuICBzdWJHcmlkRHluYW1pYz86IGJvb2xlYW47XHJcbn1cclxuXHJcbi8qKiBvcHRpb25zIHVzZWQgZHVyaW5nIEdyaWRTdGFja0VuZ2luZS5tb3ZlTm9kZSgpICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgR3JpZFN0YWNrTW92ZU9wdHMgZXh0ZW5kcyBHcmlkU3RhY2tQb3NpdGlvbiB7XHJcbiAgLyoqIG5vZGUgdG8gc2tpcCBjb2xsaXNpb24gKi9cclxuICBza2lwPzogR3JpZFN0YWNrTm9kZTtcclxuICAvKiogZG8gd2UgcGFjayAoZGVmYXVsdCB0cnVlKSAqL1xyXG4gIHBhY2s/OiBib29sZWFuO1xyXG4gIC8qKiB0cnVlIGlmIHdlIGFyZSBjYWxsaW5nIHRoaXMgcmVjdXJzaXZlbHkgdG8gcHJldmVudCBzaW1wbGUgc3dhcCBvciBjb3ZlcmFnZSBjb2xsaXNpb24gLSBkZWZhdWx0IGZhbHNlKi9cclxuICBuZXN0ZWQ/OiBib29sZWFuO1xyXG4gIC8qKiB2YXJzIHRvIGNhbGN1bGF0ZSBvdGhlciBjZWxscyBjb29yZGluYXRlcyAqL1xyXG4gIGNlbGxXaWR0aD86IG51bWJlcjtcclxuICBjZWxsSGVpZ2h0PzogbnVtYmVyO1xyXG4gIG1hcmdpblRvcD86IG51bWJlcjtcclxuICBtYXJnaW5Cb3R0b20/OiBudW1iZXI7XHJcbiAgbWFyZ2luTGVmdD86IG51bWJlcjtcclxuICBtYXJnaW5SaWdodD86IG51bWJlcjtcclxuICAvKiogcG9zaXRpb24gaW4gcGl4ZWxzIG9mIHRoZSBjdXJyZW50bHkgZHJhZ2dlZCBpdGVtcyAoZm9yIG92ZXJsYXAgY2hlY2spICovXHJcbiAgcmVjdD86IEdyaWRTdGFja1Bvc2l0aW9uO1xyXG4gIC8qKiB0cnVlIGlmIHdlJ3JlIGxpdmUgcmVzaXppbmcgKi9cclxuICByZXNpemluZz86IGJvb2xlYW47XHJcbiAgLyoqIGJlc3Qgbm9kZSAobW9zdCBjb3ZlcmFnZSkgd2UgY29sbGllZCB3aXRoICovXHJcbiAgY29sbGlkZT86IEdyaWRTdGFja05vZGU7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgR3JpZFN0YWNrUG9zaXRpb24ge1xyXG4gIC8qKiB3aWRnZXQgcG9zaXRpb24geCAoZGVmYXVsdD86IDApICovXHJcbiAgeD86IG51bWJlcjtcclxuICAvKiogd2lkZ2V0IHBvc2l0aW9uIHkgKGRlZmF1bHQ/OiAwKSAqL1xyXG4gIHk/OiBudW1iZXI7XHJcbiAgLyoqIHdpZGdldCBkaW1lbnNpb24gd2lkdGggKGRlZmF1bHQ/OiAxKSAqL1xyXG4gIHc/OiBudW1iZXI7XHJcbiAgLyoqIHdpZGdldCBkaW1lbnNpb24gaGVpZ2h0IChkZWZhdWx0PzogMSkgKi9cclxuICBoPzogbnVtYmVyO1xyXG59XHJcblxyXG4vKipcclxuICogR3JpZFN0YWNrIFdpZGdldCBjcmVhdGlvbiBvcHRpb25zXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEdyaWRTdGFja1dpZGdldCBleHRlbmRzIEdyaWRTdGFja1Bvc2l0aW9uIHtcclxuICAvKiogaWYgdHJ1ZSB0aGVuIHgsIHkgcGFyYW1ldGVycyB3aWxsIGJlIGlnbm9yZWQgYW5kIHdpZGdldCB3aWxsIGJlIHBsYWNlcyBvbiB0aGUgZmlyc3QgYXZhaWxhYmxlIHBvc2l0aW9uIChkZWZhdWx0PzogZmFsc2UpICovXHJcbiAgYXV0b1Bvc2l0aW9uPzogYm9vbGVhbjtcclxuICAvKiogbWluaW11bSB3aWR0aCBhbGxvd2VkIGR1cmluZyByZXNpemUvY3JlYXRpb24gKGRlZmF1bHQ/OiB1bmRlZmluZWQgPSB1bi1jb25zdHJhaW5lZCkgKi9cclxuICBtaW5XPzogbnVtYmVyO1xyXG4gIC8qKiBtYXhpbXVtIHdpZHRoIGFsbG93ZWQgZHVyaW5nIHJlc2l6ZS9jcmVhdGlvbiAoZGVmYXVsdD86IHVuZGVmaW5lZCA9IHVuLWNvbnN0cmFpbmVkKSAqL1xyXG4gIG1heFc/OiBudW1iZXI7XHJcbiAgLyoqIG1pbmltdW0gaGVpZ2h0IGFsbG93ZWQgZHVyaW5nIHJlc2l6ZS9jcmVhdGlvbiAoZGVmYXVsdD86IHVuZGVmaW5lZCA9IHVuLWNvbnN0cmFpbmVkKSAqL1xyXG4gIG1pbkg/OiBudW1iZXI7XHJcbiAgLyoqIG1heGltdW0gaGVpZ2h0IGFsbG93ZWQgZHVyaW5nIHJlc2l6ZS9jcmVhdGlvbiAoZGVmYXVsdD86IHVuZGVmaW5lZCA9IHVuLWNvbnN0cmFpbmVkKSAqL1xyXG4gIG1heEg/OiBudW1iZXI7XHJcbiAgLyoqIHByZXZlbnQgcmVzaXppbmcgKGRlZmF1bHQ/OiB1bmRlZmluZWQgPSB1bi1jb25zdHJhaW5lZCkgKi9cclxuICBub1Jlc2l6ZT86IGJvb2xlYW47XHJcbiAgLyoqIHByZXZlbnRzIG1vdmluZyAoZGVmYXVsdD86IHVuZGVmaW5lZCA9IHVuLWNvbnN0cmFpbmVkKSAqL1xyXG4gIG5vTW92ZT86IGJvb2xlYW47XHJcbiAgLyoqIHByZXZlbnRzIGJlaW5nIG1vdmVkIGJ5IG90aGVycyBkdXJpbmcgdGhlaXIgKGRlZmF1bHQ/OiB1bmRlZmluZWQgPSB1bi1jb25zdHJhaW5lZCkgKi9cclxuICBsb2NrZWQ/OiBib29sZWFuO1xyXG4gIC8qKiB2YWx1ZSBmb3IgYGdzLWlkYCBzdG9yZWQgb24gdGhlIHdpZGdldCAoZGVmYXVsdD86IHVuZGVmaW5lZCkgKi9cclxuICBpZD86IHN0cmluZztcclxuICAvKiogaHRtbCB0byBhcHBlbmQgaW5zaWRlIGFzIGNvbnRlbnQgKi9cclxuICBjb250ZW50Pzogc3RyaW5nO1xyXG4gIC8qKiBvcHRpb25hbCBuZXN0ZWQgZ3JpZCBvcHRpb25zIGFuZCBsaXN0IG9mIGNoaWxkcmVuLCB3aGljaCB0aGVuIHR1cm5zIGludG8gYWN0dWFsIGluc3RhbmNlIGF0IHJ1bnRpbWUgdG8gZ2V0IG9wdGlvbnMgZnJvbSAqL1xyXG4gIHN1YkdyaWRPcHRzPzogR3JpZFN0YWNrT3B0aW9ucztcclxufVxyXG5cclxuLyoqIERyYWcmRHJvcCByZXNpemUgb3B0aW9ucyAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEREUmVzaXplT3B0IHtcclxuICAvKiogZG8gcmVzaXplIGhhbmRsZSBoaWRlIGJ5IGRlZmF1bHQgdW50aWwgbW91c2Ugb3ZlciA/IC0gZGVmYXVsdDogdHJ1ZSBvbiBkZXNrdG9wLCBmYWxzZSBvbiBtb2JpbGUqL1xyXG4gIGF1dG9IaWRlPzogYm9vbGVhbjtcclxuICAvKipcclxuICAgKiBzaWRlcyB3aGVyZSB5b3UgY2FuIHJlc2l6ZSBmcm9tIChleDogJ2UsIHNlLCBzLCBzdywgdycpIC0gZGVmYXVsdCAnc2UnIChzb3V0aC1lYXN0KVxyXG4gICAqIE5vdGU6IGl0IGlzIG5vdCByZWNvbW1lbmRlZCB0byByZXNpemUgZnJvbSB0aGUgdG9wIHNpZGVzIGFzIHdlaXJkIHNpZGUgZWZmZWN0IG1heSBvY2N1ci5cclxuICAqL1xyXG4gIGhhbmRsZXM/OiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKiBEcmFnJkRyb3AgcmVtb3ZlIG9wdGlvbnMgKi9cclxuZXhwb3J0IGludGVyZmFjZSBERFJlbW92ZU9wdCB7XHJcbiAgLyoqIGNsYXNzIHRoYXQgY2FuIGJlIHJlbW92ZWQgKGRlZmF1bHQ/OiAnLicgKyBvcHRzLml0ZW1DbGFzcykgKi9cclxuICBhY2NlcHQ/OiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKiBEcmFnJkRyb3AgZHJhZ2dpbmcgb3B0aW9ucyAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIERERHJhZ09wdCB7XHJcbiAgLyoqIGNsYXNzIHNlbGVjdG9yIG9mIGl0ZW1zIHRoYXQgY2FuIGJlIGRyYWdnZWQuIGRlZmF1bHQgdG8gJy5ncmlkLXN0YWNrLWl0ZW0tY29udGVudCcgKi9cclxuICBoYW5kbGU/OiBzdHJpbmc7XHJcbiAgLyoqIGRlZmF1bHQgdG8gJ2JvZHknICovXHJcbiAgYXBwZW5kVG8/OiBzdHJpbmc7XHJcbiAgLyoqIGlmIHNldCAodHJ1ZSB8IG1zZWMpLCBkcmFnZ2luZyBwbGFjZW1lbnQgKGNvbGxpc2lvbikgd2lsbCBvbmx5IGhhcHBlbiBhZnRlciBhIHBhdXNlIGJ5IHRoZSB1c2VyLiBOb3RlOiB0aGlzIGlzIEdsb2JhbCAqL1xyXG4gIHBhdXNlPzogYm9vbGVhbiB8IG51bWJlcjtcclxuICAvKiogZGVmYXVsdCB0byBgdHJ1ZWAgKi9cclxuICBzY3JvbGw/OiBib29sZWFuO1xyXG4gIC8qKiBwcmV2ZW50cyBkcmFnZ2luZyBmcm9tIHN0YXJ0aW5nIG9uIHNwZWNpZmllZCBlbGVtZW50cywgbGlzdGVkIGFzIGNvbW1hIHNlcGFyYXRlZCBzZWxlY3RvcnMgKGVnOiAnLm5vLWRyYWcnKS4gZGVmYXVsdCBidWlsdCBpbiBpcyAnaW5wdXQsdGV4dGFyZWEsYnV0dG9uLHNlbGVjdCxvcHRpb24nICovXHJcbiAgY2FuY2VsPzogc3RyaW5nO1xyXG59XHJcbmV4cG9ydCBpbnRlcmZhY2UgREREcmFnSW5PcHQgZXh0ZW5kcyBERERyYWdPcHQge1xyXG4gIC8qKiBoZWxwZXIgZnVuY3Rpb24gd2hlbiBkcm9wcGluZzogJ2Nsb25lJyBvciB5b3VyIG93biBtZXRob2QgKi9cclxuICBoZWxwZXI/OiAnY2xvbmUnIHwgKChldmVudDogRXZlbnQpID0+IEhUTUxFbGVtZW50KTtcclxuICAvKiogdXNlZCB3aGVuIGRyYWdnaW5nIGl0ZW0gZnJvbSB0aGUgb3V0c2lkZSwgYW5kIGNhbmNlbGluZyAoZXg6ICdpbnZhbGlkJyBvciB5b3VyIG93biBtZXRob2QpKi9cclxuICAvLyByZXZlcnQ/OiBzdHJpbmcgfCAoKGV2ZW50OiBFdmVudCkgPT4gSFRNTEVsZW1lbnQpO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFNpemUge1xyXG4gIHdpZHRoOiBudW1iZXI7XHJcbiAgaGVpZ2h0OiBudW1iZXI7XHJcbn1cclxuZXhwb3J0IGludGVyZmFjZSBQb3NpdGlvbiB7XHJcbiAgdG9wOiBudW1iZXI7XHJcbiAgbGVmdDogbnVtYmVyO1xyXG59XHJcbmV4cG9ydCBpbnRlcmZhY2UgUmVjdCBleHRlbmRzIFNpemUsIFBvc2l0aW9uIHt9XHJcblxyXG4vKiogZGF0YSB0aGF0IGlzIHBhc3NlZCBkdXJpbmcgZHJhZyBhbmQgcmVzaXppbmcgY2FsbGJhY2tzICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRERVSURhdGEge1xyXG4gIHBvc2l0aW9uPzogUG9zaXRpb247XHJcbiAgc2l6ZT86IFNpemU7XHJcbiAgZHJhZ2dhYmxlPzogSFRNTEVsZW1lbnQ7XHJcbiAgLyogZmllbGRzIG5vdCB1c2VkIGJ5IEdyaWRTdGFjayBidXQgc2VudCBieSBqcSA/IGxlYXZlIGluIGNhc2Ugd2UgZ28gYmFjayB0byB0aGVtLi4uXHJcbiAgb3JpZ2luYWxQb3NpdGlvbj8gOiBQb3NpdGlvbjtcclxuICBvZmZzZXQ/OiBQb3NpdGlvbjtcclxuICBvcmlnaW5hbFNpemU/OiBTaXplO1xyXG4gIGVsZW1lbnQ/OiBIVE1MRWxlbWVudFtdO1xyXG4gIGhlbHBlcj86IEhUTUxFbGVtZW50W107XHJcbiAgb3JpZ2luYWxFbGVtZW50PzogSFRNTEVsZW1lbnRbXTtcclxuICAqL1xyXG59XHJcblxyXG4vKipcclxuICogaW50ZXJuYWwgZGVzY3JpcHRpb25zIGRlc2NyaWJpbmcgdGhlIGl0ZW1zIGluIHRoZSBncmlkXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEdyaWRTdGFja05vZGUgZXh0ZW5kcyBHcmlkU3RhY2tXaWRnZXQge1xyXG4gIC8qKiBwb2ludGVyIGJhY2sgdG8gSFRNTCBlbGVtZW50ICovXHJcbiAgZWw/OiBHcmlkSXRlbUhUTUxFbGVtZW50O1xyXG4gIC8qKiBwb2ludGVyIGJhY2sgdG8gcGFyZW50IEdyaWQgaW5zdGFuY2UgKi9cclxuICBncmlkPzogR3JpZFN0YWNrO1xyXG4gIC8qKiBhY3R1YWwgc3ViLWdyaWQgaW5zdGFuY2UgKi9cclxuICBzdWJHcmlkPzogR3JpZFN0YWNrO1xyXG4gIC8qKiBAaW50ZXJuYWwgaW50ZXJuYWwgaWQgdXNlZCB0byBtYXRjaCB3aGVuIGNsb25pbmcgZW5naW5lcyBvciBzYXZpbmcgY29sdW1uIGxheW91dHMgKi9cclxuICBfaWQ/OiBudW1iZXI7XHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIF9kaXJ0eT86IGJvb2xlYW47XHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIF91cGRhdGluZz86IGJvb2xlYW47XHJcbiAgLyoqIEBpbnRlcm5hbCB0cnVlIHdoZW4gb3ZlciB0cmFzaC9hbm90aGVyIGdyaWQgc28gd2UgZG9uJ3QgYm90aGVyIHJlbW92aW5nIGRyYWcgQ1NTIHN0eWxlIHRoYXQgd291bGQgYW5pbWF0ZSBiYWNrIHRvIG9sZCBwb3NpdGlvbiAqL1xyXG4gIF9pc0Fib3V0VG9SZW1vdmU/OiBib29sZWFuO1xyXG4gIC8qKiBAaW50ZXJuYWwgdHJ1ZSBpZiBpdGVtIGNhbWUgZnJvbSBvdXRzaWRlIG9mIHRoZSBncmlkIC0+IGFjdHVhbCBpdGVtIG5lZWQgdG8gYmUgbW92ZWQgb3ZlciAqL1xyXG4gIF9pc0V4dGVybmFsPzogYm9vbGVhbjtcclxuICAvKiogQGludGVybmFsIE1vdXNlIGV2ZW50IHRoYXQncyBjYXVzaW5nIG1vdmluZ3xyZXNpemluZyAqL1xyXG4gIF9ldmVudD86IE1vdXNlRXZlbnQ7XHJcbiAgLyoqIEBpbnRlcm5hbCBtb3ZpbmcgdnMgcmVzaXppbmcgKi9cclxuICBfbW92aW5nPzogYm9vbGVhbjtcclxuICAvKiogQGludGVybmFsIHRydWUgaWYgd2UganVtcGVkIGRvd24gcGFzdCBpdGVtIGJlbG93IChvbmUgdGltZSBqdW1wIHNvIHdlIGRvbid0IGhhdmUgdG8gdG90YWxseSBwYXNzIGl0KSAqL1xyXG4gIF9za2lwRG93bj86IGJvb2xlYW47XHJcbiAgLyoqIEBpbnRlcm5hbCBvcmlnaW5hbCB2YWx1ZXMgYmVmb3JlIGEgZHJhZy9zaXplICovXHJcbiAgX29yaWc/OiBHcmlkU3RhY2tQb3NpdGlvbjtcclxuICAvKiogQGludGVybmFsIHBvc2l0aW9uIGluIHBpeGVscyB1c2VkIGR1cmluZyBjb2xsaXNpb24gY2hlY2sgICovXHJcbiAgX3JlY3Q/OiBHcmlkU3RhY2tQb3NpdGlvbjtcclxuICAvKiogQGludGVybmFsIHRvcC9sZWZ0IHBpeGVsIGxvY2F0aW9uIGJlZm9yZSBhIGRyYWcgc28gd2UgY2FuIGRldGVjdCBkaXJlY3Rpb24gb2YgbW92ZSBmcm9tIGxhc3QgcG9zaXRpb24qL1xyXG4gIF9sYXN0VWlQb3NpdGlvbj86IFBvc2l0aW9uO1xyXG4gIC8qKiBAaW50ZXJuYWwgc2V0IG9uIHRoZSBpdGVtIGJlaW5nIGRyYWdnZWQvcmVzaXplZCByZW1lbWJlciB0aGUgbGFzdCBwb3NpdGlvbnMgd2UndmUgdHJpZWQgKGJ1dCBmYWlsZWQpIHNvIHdlIGRvbid0IHRyeSBhZ2FpbiBkdXJpbmcgZHJhZy9yZXNpemUgKi9cclxuICBfbGFzdFRyaWVkPzogR3JpZFN0YWNrUG9zaXRpb247XHJcbiAgLyoqIEBpbnRlcm5hbCBwb3NpdGlvbiB3aWxsSXRGaXQoKSB3aWxsIHVzZSB0byBwb3NpdGlvbiB0aGUgaXRlbSAqL1xyXG4gIF93aWxsRml0UG9zPzogR3JpZFN0YWNrUG9zaXRpb247XHJcbiAgLyoqIEBpbnRlcm5hbCBsYXN0IGRyYWcgWSBwaXhlbCBwb3NpdGlvbiB1c2VkIHRvIGluY3JlbWVudGFsbHkgdXBkYXRlIFYgc2Nyb2xsIGJhciAqL1xyXG4gIF9wcmV2WVBpeD86IG51bWJlcjtcclxuICAvKiogQGludGVybmFsIHRydWUgaWYgd2UndmUgcmVtb3ZlIHRoZSBpdGVtIGZyb20gb3Vyc2VsZiAoZHJhZ2dpbmcgb3V0KSBidXQgbWlnaHQgcmV2ZXJ0IGl0IGJhY2sgKHJlbGVhc2Ugb24gbm90aGluZyAtPiBnb2VzIGJhY2spICovXHJcbiAgX3RlbXBvcmFyeVJlbW92ZWQ/OiBib29sZWFuO1xyXG4gIC8qKiBAaW50ZXJuYWwgdHJ1ZSBpZiB3ZSBzaG91bGQgcmVtb3ZlIERPTSBlbGVtZW50IG9uIF9ub3RpZnkoKSByYXRoZXIgdGhhbiBjbGVhcmluZyBfaWQgKG9sZCB3YXkpICovXHJcbiAgX3JlbW92ZURPTT86IGJvb2xlYW47XHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIF9pbml0REQ/OiBib29sZWFuO1xyXG59XHJcbiIsIi8qKlxuICogZGQtbWFuYWdlci50cyA4LjIuMlxuICogQ29weXJpZ2h0IChjKSAyMDIxIEFsYWluIER1bWVzbnkgLSBzZWUgR3JpZFN0YWNrIHJvb3QgbGljZW5zZVxuICovXG5cbmltcG9ydCB7IERERHJhZ2dhYmxlIH0gZnJvbSAnLi9kZC1kcmFnZ2FibGUnO1xuaW1wb3J0IHsgREREcm9wcGFibGUgfSBmcm9tICcuL2RkLWRyb3BwYWJsZSc7XG5pbXBvcnQgeyBERFJlc2l6YWJsZSB9IGZyb20gJy4vZGQtcmVzaXphYmxlJztcblxuLyoqXG4gKiBnbG9iYWxzIHRoYXQgYXJlIHNoYXJlZCBhY3Jvc3MgRHJhZyAmIERyb3AgaW5zdGFuY2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBERE1hbmFnZXIge1xuICAvKiogaWYgc2V0ICh0cnVlIHwgaW4gbXNlYyksIGRyYWdnaW5nIHBsYWNlbWVudCAoY29sbGlzaW9uKSB3aWxsIG9ubHkgaGFwcGVuIGFmdGVyIGEgcGF1c2UgYnkgdGhlIHVzZXIqL1xuICBwdWJsaWMgc3RhdGljIHBhdXNlRHJhZzogYm9vbGVhbiB8IG51bWJlcjtcblxuICAvKiogdHJ1ZSBpZiBhIG1vdXNlIGRvd24gZXZlbnQgd2FzIGhhbmRsZWQgKi9cbiAgcHVibGljIHN0YXRpYyBtb3VzZUhhbmRsZWQ6IGJvb2xlYW47XG5cbiAgLyoqIGl0ZW0gYmVpbmcgZHJhZ2dlZCAqL1xuICBwdWJsaWMgc3RhdGljIGRyYWdFbGVtZW50OiBERERyYWdnYWJsZTtcblxuICAvKiogaXRlbSB3ZSBhcmUgY3VycmVudGx5IG92ZXIgYXMgZHJvcCB0YXJnZXQgKi9cbiAgcHVibGljIHN0YXRpYyBkcm9wRWxlbWVudDogREREcm9wcGFibGU7XG5cbiAgLyoqIGN1cnJlbnQgaXRlbSB3ZSdyZSBvdmVyIGZvciByZXNpemluZyBwdXJwb3NlIChpZ25vcmUgbmVzdGVkIGdyaWQgcmVzaXplIGhhbmRsZXMpICovXG4gIHB1YmxpYyBzdGF0aWMgb3ZlclJlc2l6ZUVsZW1lbnQ6IEREUmVzaXphYmxlO1xuXG59XG4iLCIvKipcbiAqIHRvdWNoLnRzIDguMi4yXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjEgQWxhaW4gRHVtZXNueSAtIHNlZSBHcmlkU3RhY2sgcm9vdCBsaWNlbnNlXG4gKi9cblxuaW1wb3J0IHsgRERNYW5hZ2VyIH0gZnJvbSAnLi9kZC1tYW5hZ2VyJztcblxuLyoqXG4gKiBEZXRlY3QgdG91Y2ggc3VwcG9ydCAtIFdpbmRvd3MgU3VyZmFjZSBkZXZpY2VzIGFuZCBvdGhlciB0b3VjaCBkZXZpY2VzXG4gKiBzaG91bGQgd2UgdXNlIHRoaXMgaW5zdGVhZCA/ICh3aGF0IHdlIGhhZCBmb3IgYWx3YXlzIHNob3dpbmcgcmVzaXplIGhhbmRsZXMpXG4gKiAvQW5kcm9pZHx3ZWJPU3xpUGhvbmV8aVBhZHxpUG9kfEJsYWNrQmVycnl8SUVNb2JpbGV8T3BlcmEgTWluaS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudClcbiAqL1xuZXhwb3J0IGNvbnN0IGlzVG91Y2g6IGJvb2xlYW4gPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmXG4oICdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50XG4gIHx8ICdvbnRvdWNoc3RhcnQnIGluIHdpbmRvd1xuICAvLyB8fCAhIXdpbmRvdy5Ub3VjaEV2ZW50IC8vIHRydWUgb24gV2luZG93cyAxMCBDaHJvbWUgZGVza3RvcCBzbyBkb24ndCB1c2UgdGhpc1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICB8fCAoKHdpbmRvdyBhcyBhbnkpLkRvY3VtZW50VG91Y2ggJiYgZG9jdW1lbnQgaW5zdGFuY2VvZiAod2luZG93IGFzIGFueSkuRG9jdW1lbnRUb3VjaClcbiAgfHwgbmF2aWdhdG9yLm1heFRvdWNoUG9pbnRzID4gMFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICB8fCAobmF2aWdhdG9yIGFzIGFueSkubXNNYXhUb3VjaFBvaW50cyA+IDBcbik7XG5cbi8vIGludGVyZmFjZSBUb3VjaENvb3JkIHt4OiBudW1iZXIsIHk6IG51bWJlcn07XG5cbmNsYXNzIEREVG91Y2gge1xuICBwdWJsaWMgc3RhdGljIHRvdWNoSGFuZGxlZDogYm9vbGVhbjtcbiAgcHVibGljIHN0YXRpYyBwb2ludGVyTGVhdmVUaW1lb3V0OiBudW1iZXI7XG59XG5cbi8qKlxuKiBHZXQgdGhlIHgseSBwb3NpdGlvbiBvZiBhIHRvdWNoIGV2ZW50XG4qL1xuLy8gZnVuY3Rpb24gZ2V0VG91Y2hDb29yZHMoZTogVG91Y2hFdmVudCk6IFRvdWNoQ29vcmQge1xuLy8gICByZXR1cm4ge1xuLy8gICAgIHg6IGUuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVgsXG4vLyAgICAgeTogZS5jaGFuZ2VkVG91Y2hlc1swXS5wYWdlWVxuLy8gICB9O1xuLy8gfVxuXG4vKipcbiAqIFNpbXVsYXRlIGEgbW91c2UgZXZlbnQgYmFzZWQgb24gYSBjb3JyZXNwb25kaW5nIHRvdWNoIGV2ZW50XG4gKiBAcGFyYW0ge09iamVjdH0gZSBBIHRvdWNoIGV2ZW50XG4gKiBAcGFyYW0ge1N0cmluZ30gc2ltdWxhdGVkVHlwZSBUaGUgY29ycmVzcG9uZGluZyBtb3VzZSBldmVudFxuICovXG5mdW5jdGlvbiBzaW11bGF0ZU1vdXNlRXZlbnQoZTogVG91Y2hFdmVudCwgc2ltdWxhdGVkVHlwZTogc3RyaW5nKSB7XG5cbiAgLy8gSWdub3JlIG11bHRpLXRvdWNoIGV2ZW50c1xuICBpZiAoZS50b3VjaGVzLmxlbmd0aCA+IDEpIHJldHVybjtcblxuICAvLyBQcmV2ZW50IFwiSWdub3JlZCBhdHRlbXB0IHRvIGNhbmNlbCBhIHRvdWNobW92ZSBldmVudCB3aXRoIGNhbmNlbGFibGU9ZmFsc2VcIiBlcnJvcnNcbiAgaWYgKGUuY2FuY2VsYWJsZSkgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gIGNvbnN0IHRvdWNoID0gZS5jaGFuZ2VkVG91Y2hlc1swXSwgc2ltdWxhdGVkRXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnTW91c2VFdmVudHMnKTtcblxuICAvLyBJbml0aWFsaXplIHRoZSBzaW11bGF0ZWQgbW91c2UgZXZlbnQgdXNpbmcgdGhlIHRvdWNoIGV2ZW50J3MgY29vcmRpbmF0ZXNcbiAgc2ltdWxhdGVkRXZlbnQuaW5pdE1vdXNlRXZlbnQoXG4gICAgc2ltdWxhdGVkVHlwZSwgICAgLy8gdHlwZVxuICAgIHRydWUsICAgICAgICAgICAgIC8vIGJ1YmJsZXNcbiAgICB0cnVlLCAgICAgICAgICAgICAvLyBjYW5jZWxhYmxlXG4gICAgd2luZG93LCAgICAgICAgICAgLy8gdmlld1xuICAgIDEsICAgICAgICAgICAgICAgIC8vIGRldGFpbFxuICAgIHRvdWNoLnNjcmVlblgsICAgIC8vIHNjcmVlblhcbiAgICB0b3VjaC5zY3JlZW5ZLCAgICAvLyBzY3JlZW5ZXG4gICAgdG91Y2guY2xpZW50WCwgICAgLy8gY2xpZW50WFxuICAgIHRvdWNoLmNsaWVudFksICAgIC8vIGNsaWVudFlcbiAgICBmYWxzZSwgICAgICAgICAgICAvLyBjdHJsS2V5XG4gICAgZmFsc2UsICAgICAgICAgICAgLy8gYWx0S2V5XG4gICAgZmFsc2UsICAgICAgICAgICAgLy8gc2hpZnRLZXlcbiAgICBmYWxzZSwgICAgICAgICAgICAvLyBtZXRhS2V5XG4gICAgMCwgICAgICAgICAgICAgICAgLy8gYnV0dG9uXG4gICAgbnVsbCAgICAgICAgICAgICAgLy8gcmVsYXRlZFRhcmdldFxuICApO1xuXG4gIC8vIERpc3BhdGNoIHRoZSBzaW11bGF0ZWQgZXZlbnQgdG8gdGhlIHRhcmdldCBlbGVtZW50XG4gIGUudGFyZ2V0LmRpc3BhdGNoRXZlbnQoc2ltdWxhdGVkRXZlbnQpO1xufVxuXG4vKipcbiAqIFNpbXVsYXRlIGEgbW91c2UgZXZlbnQgYmFzZWQgb24gYSBjb3JyZXNwb25kaW5nIFBvaW50ZXIgZXZlbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBlIEEgcG9pbnRlciBldmVudFxuICogQHBhcmFtIHtTdHJpbmd9IHNpbXVsYXRlZFR5cGUgVGhlIGNvcnJlc3BvbmRpbmcgbW91c2UgZXZlbnRcbiAqL1xuZnVuY3Rpb24gc2ltdWxhdGVQb2ludGVyTW91c2VFdmVudChlOiBQb2ludGVyRXZlbnQsIHNpbXVsYXRlZFR5cGU6IHN0cmluZykge1xuXG4gIC8vIFByZXZlbnQgXCJJZ25vcmVkIGF0dGVtcHQgdG8gY2FuY2VsIGEgdG91Y2htb3ZlIGV2ZW50IHdpdGggY2FuY2VsYWJsZT1mYWxzZVwiIGVycm9yc1xuICBpZiAoZS5jYW5jZWxhYmxlKSBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgY29uc3Qgc2ltdWxhdGVkRXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnTW91c2VFdmVudHMnKTtcblxuICAvLyBJbml0aWFsaXplIHRoZSBzaW11bGF0ZWQgbW91c2UgZXZlbnQgdXNpbmcgdGhlIHRvdWNoIGV2ZW50J3MgY29vcmRpbmF0ZXNcbiAgc2ltdWxhdGVkRXZlbnQuaW5pdE1vdXNlRXZlbnQoXG4gICAgc2ltdWxhdGVkVHlwZSwgICAgLy8gdHlwZVxuICAgIHRydWUsICAgICAgICAgICAgIC8vIGJ1YmJsZXNcbiAgICB0cnVlLCAgICAgICAgICAgICAvLyBjYW5jZWxhYmxlXG4gICAgd2luZG93LCAgICAgICAgICAgLy8gdmlld1xuICAgIDEsICAgICAgICAgICAgICAgIC8vIGRldGFpbFxuICAgIGUuc2NyZWVuWCwgICAgLy8gc2NyZWVuWFxuICAgIGUuc2NyZWVuWSwgICAgLy8gc2NyZWVuWVxuICAgIGUuY2xpZW50WCwgICAgLy8gY2xpZW50WFxuICAgIGUuY2xpZW50WSwgICAgLy8gY2xpZW50WVxuICAgIGZhbHNlLCAgICAgICAgICAgIC8vIGN0cmxLZXlcbiAgICBmYWxzZSwgICAgICAgICAgICAvLyBhbHRLZXlcbiAgICBmYWxzZSwgICAgICAgICAgICAvLyBzaGlmdEtleVxuICAgIGZhbHNlLCAgICAgICAgICAgIC8vIG1ldGFLZXlcbiAgICAwLCAgICAgICAgICAgICAgICAvLyBidXR0b25cbiAgICBudWxsICAgICAgICAgICAgICAvLyByZWxhdGVkVGFyZ2V0XG4gICk7XG5cbiAgLy8gRGlzcGF0Y2ggdGhlIHNpbXVsYXRlZCBldmVudCB0byB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgZS50YXJnZXQuZGlzcGF0Y2hFdmVudChzaW11bGF0ZWRFdmVudCk7XG59XG5cblxuLyoqXG4gKiBIYW5kbGUgdGhlIHRvdWNoc3RhcnQgZXZlbnRzXG4gKiBAcGFyYW0ge09iamVjdH0gZSBUaGUgd2lkZ2V0IGVsZW1lbnQncyB0b3VjaHN0YXJ0IGV2ZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b3VjaHN0YXJ0KGU6IFRvdWNoRXZlbnQpOiB2b2lkIHtcbiAgLy8gSWdub3JlIHRoZSBldmVudCBpZiBhbm90aGVyIHdpZGdldCBpcyBhbHJlYWR5IGJlaW5nIGhhbmRsZWRcbiAgaWYgKEREVG91Y2gudG91Y2hIYW5kbGVkKSByZXR1cm47XG4gIEREVG91Y2gudG91Y2hIYW5kbGVkID0gdHJ1ZTtcblxuICAvLyBTaW11bGF0ZSB0aGUgbW91c2UgZXZlbnRzXG4gIC8vIHNpbXVsYXRlTW91c2VFdmVudChlLCAnbW91c2VvdmVyJyk7XG4gIC8vIHNpbXVsYXRlTW91c2VFdmVudChlLCAnbW91c2Vtb3ZlJyk7XG4gIHNpbXVsYXRlTW91c2VFdmVudChlLCAnbW91c2Vkb3duJyk7XG59XG5cbi8qKlxuICogSGFuZGxlIHRoZSB0b3VjaG1vdmUgZXZlbnRzXG4gKiBAcGFyYW0ge09iamVjdH0gZSBUaGUgZG9jdW1lbnQncyB0b3VjaG1vdmUgZXZlbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvdWNobW92ZShlOiBUb3VjaEV2ZW50KTogdm9pZCB7XG4gIC8vIElnbm9yZSBldmVudCBpZiBub3QgaGFuZGxlZCBieSB1c1xuICBpZiAoIUREVG91Y2gudG91Y2hIYW5kbGVkKSByZXR1cm47XG5cbiAgc2ltdWxhdGVNb3VzZUV2ZW50KGUsICdtb3VzZW1vdmUnKTtcbn1cblxuLyoqXG4gKiBIYW5kbGUgdGhlIHRvdWNoZW5kIGV2ZW50c1xuICogQHBhcmFtIHtPYmplY3R9IGUgVGhlIGRvY3VtZW50J3MgdG91Y2hlbmQgZXZlbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvdWNoZW5kKGU6IFRvdWNoRXZlbnQpOiB2b2lkIHtcblxuICAvLyBJZ25vcmUgZXZlbnQgaWYgbm90IGhhbmRsZWRcbiAgaWYgKCFERFRvdWNoLnRvdWNoSGFuZGxlZCkgcmV0dXJuO1xuXG4gIC8vIGNhbmNlbCBkZWxheWVkIGxlYXZlIGV2ZW50IHdoZW4gd2UgcmVsZWFzZSBvbiBvdXJzZWxmIHdoaWNoIGhhcHBlbnMgQkVGT1JFIHdlIGdldCB0aGlzIVxuICBpZiAoRERUb3VjaC5wb2ludGVyTGVhdmVUaW1lb3V0KSB7XG4gICAgd2luZG93LmNsZWFyVGltZW91dChERFRvdWNoLnBvaW50ZXJMZWF2ZVRpbWVvdXQpO1xuICAgIGRlbGV0ZSBERFRvdWNoLnBvaW50ZXJMZWF2ZVRpbWVvdXQ7XG4gIH1cblxuICBjb25zdCB3YXNEcmFnZ2luZyA9ICEhRERNYW5hZ2VyLmRyYWdFbGVtZW50O1xuXG4gIC8vIFNpbXVsYXRlIHRoZSBtb3VzZXVwIGV2ZW50XG4gIHNpbXVsYXRlTW91c2VFdmVudChlLCAnbW91c2V1cCcpO1xuICAvLyBzaW11bGF0ZU1vdXNlRXZlbnQoZXZlbnQsICdtb3VzZW91dCcpO1xuXG4gIC8vIElmIHRoZSB0b3VjaCBpbnRlcmFjdGlvbiBkaWQgbm90IG1vdmUsIGl0IHNob3VsZCB0cmlnZ2VyIGEgY2xpY2tcbiAgaWYgKCF3YXNEcmFnZ2luZykge1xuICAgIHNpbXVsYXRlTW91c2VFdmVudChlLCAnY2xpY2snKTtcbiAgfVxuXG4gIC8vIFVuc2V0IHRoZSBmbGFnIHRvIGFsbG93IG90aGVyIHdpZGdldHMgdG8gaW5oZXJpdCB0aGUgdG91Y2ggZXZlbnRcbiAgRERUb3VjaC50b3VjaEhhbmRsZWQgPSBmYWxzZTtcbn1cblxuLyoqXG4gKiBOb3RlIHdlIGRvbid0IGdldCB0b3VjaGVudGVyL3RvdWNobGVhdmUgKHdoaWNoIGFyZSBkZXByZWNhdGVkKVxuICogc2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI3OTA4MzM5L2pzLXRvdWNoLWVxdWl2YWxlbnQtZm9yLW1vdXNlZW50ZXJcbiAqIHNvIGluc3RlYWQgb2YgUG9pbnRlckV2ZW50IHRvIHN0aWxsIGdldCBlbnRlci9sZWF2ZSBhbmQgc2VuZCB0aGUgbWF0Y2hpbmcgbW91c2UgZXZlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb2ludGVyZG93bihlOiBQb2ludGVyRXZlbnQpOiB2b2lkIHtcbiAgLy8gY29uc29sZS5sb2coXCJwb2ludGVyIGRvd25cIilcbiAgKGUudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpIC8vIDwtIEltcG9ydGFudCFcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBvaW50ZXJlbnRlcihlOiBQb2ludGVyRXZlbnQpOiB2b2lkIHtcbiAgLy8gaWdub3JlIHRoZSBpbml0aWFsIG9uZSB3ZSBnZXQgb24gcG9pbnRlcmRvd24gb24gb3Vyc2VsZlxuICBpZiAoIURETWFuYWdlci5kcmFnRWxlbWVudCkge1xuICAgIC8vIGNvbnNvbGUubG9nKCdwb2ludGVyZW50ZXIgaWdub3JlZCcpO1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBjb25zb2xlLmxvZygncG9pbnRlcmVudGVyJyk7XG4gIHNpbXVsYXRlUG9pbnRlck1vdXNlRXZlbnQoZSwgJ21vdXNlZW50ZXInKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBvaW50ZXJsZWF2ZShlOiBQb2ludGVyRXZlbnQpOiB2b2lkIHtcbiAgLy8gaWdub3JlIHRoZSBsZWF2ZSBvbiBvdXJzZWxmIHdlIGdldCBiZWZvcmUgcmVsZWFzaW5nIHRoZSBtb3VzZSBvdmVyIG91cnNlbGZcbiAgLy8gYnkgZGVsYXlpbmcgc2VuZGluZyB0aGUgZXZlbnQgYW5kIGhhdmluZyB0aGUgdXAgZXZlbnQgY2FuY2VsIHVzXG4gIGlmICghRERNYW5hZ2VyLmRyYWdFbGVtZW50KSB7XG4gICAgLy8gY29uc29sZS5sb2coJ3BvaW50ZXJsZWF2ZSBpZ25vcmVkJyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIEREVG91Y2gucG9pbnRlckxlYXZlVGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICBkZWxldGUgRERUb3VjaC5wb2ludGVyTGVhdmVUaW1lb3V0O1xuICAgIC8vIGNvbnNvbGUubG9nKCdwb2ludGVybGVhdmUgZGVsYXllZCcpO1xuICAgIHNpbXVsYXRlUG9pbnRlck1vdXNlRXZlbnQoZSwgJ21vdXNlbGVhdmUnKTtcbiAgfSwgMTApO1xufVxuXG4iLCIvKipcbiAqIGRkLXJlc2l6YWJsZS1oYW5kbGUudHMgOC4yLjJcbiAqIENvcHlyaWdodCAoYykgMjAyMS0yMDIyIEFsYWluIER1bWVzbnkgLSBzZWUgR3JpZFN0YWNrIHJvb3QgbGljZW5zZVxuICovXG5cbmltcG9ydCB7IGlzVG91Y2gsIHBvaW50ZXJkb3duLCB0b3VjaGVuZCwgdG91Y2htb3ZlLCB0b3VjaHN0YXJ0IH0gZnJvbSAnLi9kZC10b3VjaCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRERSZXNpemFibGVIYW5kbGVPcHQge1xuICBzdGFydD86IChldmVudCkgPT4gdm9pZDtcbiAgbW92ZT86IChldmVudCkgPT4gdm9pZDtcbiAgc3RvcD86IChldmVudCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGNsYXNzIEREUmVzaXphYmxlSGFuZGxlIHtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgZWw6IEhUTUxFbGVtZW50O1xuICAvKiogQGludGVybmFsICovXG4gIHByb3RlY3RlZCBob3N0OiBIVE1MRWxlbWVudDtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgb3B0aW9uOiBERFJlc2l6YWJsZUhhbmRsZU9wdDtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgZGlyOiBzdHJpbmc7XG4gIC8qKiBAaW50ZXJuYWwgdHJ1ZSBhZnRlciB3ZSd2ZSBtb3ZlZCBlbm91Z2ggcGl4ZWxzIHRvIHN0YXJ0IGEgcmVzaXplICovXG4gIHByb3RlY3RlZCBtb3ZpbmcgPSBmYWxzZTtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgbW91c2VEb3duRXZlbnQ6IE1vdXNlRXZlbnQ7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIHN0YXRpYyBwcmVmaXggPSAndWktcmVzaXphYmxlLSc7XG5cbiAgY29uc3RydWN0b3IoaG9zdDogSFRNTEVsZW1lbnQsIGRpcmVjdGlvbjogc3RyaW5nLCBvcHRpb246IEREUmVzaXphYmxlSGFuZGxlT3B0KSB7XG4gICAgdGhpcy5ob3N0ID0gaG9zdDtcbiAgICB0aGlzLmRpciA9IGRpcmVjdGlvbjtcbiAgICB0aGlzLm9wdGlvbiA9IG9wdGlvbjtcbiAgICAvLyBjcmVhdGUgdmFyIGV2ZW50IGJpbmRpbmcgc28gd2UgY2FuIGVhc2lseSByZW1vdmUgYW5kIHN0aWxsIGxvb2sgbGlrZSBUUyBtZXRob2RzICh1bmxpa2UgYW5vbnltb3VzIGZ1bmN0aW9ucylcbiAgICB0aGlzLl9tb3VzZURvd24gPSB0aGlzLl9tb3VzZURvd24uYmluZCh0aGlzKTtcbiAgICB0aGlzLl9tb3VzZU1vdmUgPSB0aGlzLl9tb3VzZU1vdmUuYmluZCh0aGlzKTtcbiAgICB0aGlzLl9tb3VzZVVwID0gdGhpcy5fbW91c2VVcC5iaW5kKHRoaXMpO1xuXG4gICAgdGhpcy5faW5pdCgpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgX2luaXQoKTogRERSZXNpemFibGVIYW5kbGUge1xuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZWwuY2xhc3NMaXN0LmFkZCgndWktcmVzaXphYmxlLWhhbmRsZScpO1xuICAgIGVsLmNsYXNzTGlzdC5hZGQoYCR7RERSZXNpemFibGVIYW5kbGUucHJlZml4fSR7dGhpcy5kaXJ9YCk7XG4gICAgZWwuc3R5bGUuekluZGV4ID0gJzEwMCc7XG4gICAgZWwuc3R5bGUudXNlclNlbGVjdCA9ICdub25lJztcbiAgICB0aGlzLmVsID0gZWw7XG4gICAgdGhpcy5ob3N0LmFwcGVuZENoaWxkKHRoaXMuZWwpO1xuICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5fbW91c2VEb3duKTtcbiAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdG91Y2hzdGFydCk7XG4gICAgICB0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgcG9pbnRlcmRvd24pO1xuICAgICAgLy8gdGhpcy5lbC5zdHlsZS50b3VjaEFjdGlvbiA9ICdub25lJzsgLy8gbm90IG5lZWRlZCB1bmxpa2UgcG9pbnRlcmRvd24gZG9jIGNvbW1lbnRcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogY2FsbCB0aGlzIHdoZW4gcmVzaXplIGhhbmRsZSBuZWVkcyB0byBiZSByZW1vdmVkIGFuZCBjbGVhbmVkIHVwICovXG4gIHB1YmxpYyBkZXN0cm95KCk6IEREUmVzaXphYmxlSGFuZGxlIHtcbiAgICBpZiAodGhpcy5tb3ZpbmcpIHRoaXMuX21vdXNlVXAodGhpcy5tb3VzZURvd25FdmVudCk7XG4gICAgdGhpcy5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLl9tb3VzZURvd24pO1xuICAgIGlmIChpc1RvdWNoKSB7XG4gICAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0b3VjaHN0YXJ0KTtcbiAgICAgIHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBwb2ludGVyZG93bik7XG4gICAgfVxuICAgIHRoaXMuaG9zdC5yZW1vdmVDaGlsZCh0aGlzLmVsKTtcbiAgICBkZWxldGUgdGhpcy5lbDtcbiAgICBkZWxldGUgdGhpcy5ob3N0O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCBjYWxsZWQgb24gbW91c2UgZG93biBvbiB1czogY2FwdHVyZSBtb3ZlIG9uIHRoZSBlbnRpcmUgZG9jdW1lbnQgKG1vdXNlIG1pZ2h0IG5vdCBzdGF5IG9uIHVzKSB1bnRpbCB3ZSByZWxlYXNlIHRoZSBtb3VzZSAqL1xuICBwcm90ZWN0ZWQgX21vdXNlRG93bihlOiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5tb3VzZURvd25FdmVudCA9IGU7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5fbW91c2VNb3ZlLCB0cnVlKTsgLy8gY2FwdHVyZSwgbm90IGJ1YmJsZVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLl9tb3VzZVVwLCB0cnVlKTtcbiAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0b3VjaG1vdmUpO1xuICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRvdWNoZW5kKTtcbiAgICB9XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIHByb3RlY3RlZCBfbW91c2VNb3ZlKGU6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBsZXQgcyA9IHRoaXMubW91c2VEb3duRXZlbnQ7XG4gICAgaWYgKHRoaXMubW92aW5nKSB7XG4gICAgICB0aGlzLl90cmlnZ2VyRXZlbnQoJ21vdmUnLCBlKTtcbiAgICB9IGVsc2UgaWYgKE1hdGguYWJzKGUueCAtIHMueCkgKyBNYXRoLmFicyhlLnkgLSBzLnkpID4gMikge1xuICAgICAgLy8gZG9uJ3Qgc3RhcnQgdW5sZXNzIHdlJ3ZlIG1vdmVkIGF0IGxlYXN0IDMgcGl4ZWxzXG4gICAgICB0aGlzLm1vdmluZyA9IHRydWU7XG4gICAgICB0aGlzLl90cmlnZ2VyRXZlbnQoJ3N0YXJ0JywgdGhpcy5tb3VzZURvd25FdmVudCk7XG4gICAgICB0aGlzLl90cmlnZ2VyRXZlbnQoJ21vdmUnLCBlKTtcbiAgICB9XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIHByb3RlY3RlZCBfbW91c2VVcChlOiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMubW92aW5nKSB7XG4gICAgICB0aGlzLl90cmlnZ2VyRXZlbnQoJ3N0b3AnLCBlKTtcbiAgICB9XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5fbW91c2VNb3ZlLCB0cnVlKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5fbW91c2VVcCwgdHJ1ZSk7XG4gICAgaWYgKGlzVG91Y2gpIHtcbiAgICAgIHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgdG91Y2htb3ZlKTtcbiAgICAgIHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0b3VjaGVuZCk7XG4gICAgfVxuICAgIGRlbGV0ZSB0aGlzLm1vdmluZztcbiAgICBkZWxldGUgdGhpcy5tb3VzZURvd25FdmVudDtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF90cmlnZ2VyRXZlbnQobmFtZTogc3RyaW5nLCBldmVudDogTW91c2VFdmVudCk6IEREUmVzaXphYmxlSGFuZGxlIHtcbiAgICBpZiAodGhpcy5vcHRpb25bbmFtZV0pIHRoaXMub3B0aW9uW25hbWVdKGV2ZW50KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuIiwiLyoqXG4gKiBkZC1iYXNlLWltcGwudHMgOC4yLjJcbiAqIENvcHlyaWdodCAoYykgMjAyMS0yMDIyIEFsYWluIER1bWVzbnkgLSBzZWUgR3JpZFN0YWNrIHJvb3QgbGljZW5zZVxuICovXG5cbmV4cG9ydCB0eXBlIEV2ZW50Q2FsbGJhY2sgPSAoZXZlbnQ6IEV2ZW50KSA9PiBib29sZWFufHZvaWQ7XG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRERCYXNlSW1wbGVtZW50IHtcbiAgLyoqIHJldHVybnMgdGhlIGVuYWJsZSBzdGF0ZSwgYnV0IHlvdSBoYXZlIHRvIGNhbGwgZW5hYmxlKCkvZGlzYWJsZSgpIHRvIGNoYW5nZSAoYXMgb3RoZXIgdGhpbmdzIG5lZWQgdG8gaGFwcGVuKSAqL1xuICBwdWJsaWMgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4gICB7IHJldHVybiB0aGlzLl9kaXNhYmxlZDsgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF9kaXNhYmxlZDogYm9vbGVhbjsgLy8gaW5pdGlhbCBzdGF0ZSB0byBkaWZmZXJlbnRpYXRlIGZyb20gZmFsc2VcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgX2V2ZW50UmVnaXN0ZXI6IHtcbiAgICBbZXZlbnROYW1lOiBzdHJpbmddOiBFdmVudENhbGxiYWNrO1xuICB9ID0ge307XG5cbiAgcHVibGljIG9uKGV2ZW50OiBzdHJpbmcsIGNhbGxiYWNrOiBFdmVudENhbGxiYWNrKTogdm9pZCB7XG4gICAgdGhpcy5fZXZlbnRSZWdpc3RlcltldmVudF0gPSBjYWxsYmFjaztcbiAgfVxuXG4gIHB1YmxpYyBvZmYoZXZlbnQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGRlbGV0ZSB0aGlzLl9ldmVudFJlZ2lzdGVyW2V2ZW50XTtcbiAgfVxuXG4gIHB1YmxpYyBlbmFibGUoKTogdm9pZCB7XG4gICAgdGhpcy5fZGlzYWJsZWQgPSBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNhYmxlKCk6IHZvaWQge1xuICAgIHRoaXMuX2Rpc2FibGVkID0gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBkZXN0cm95KCk6IHZvaWQge1xuICAgIGRlbGV0ZSB0aGlzLl9ldmVudFJlZ2lzdGVyO1xuICB9XG5cbiAgcHVibGljIHRyaWdnZXJFdmVudChldmVudE5hbWU6IHN0cmluZywgZXZlbnQ6IEV2ZW50KTogYm9vbGVhbnx2b2lkIHtcbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQgJiYgdGhpcy5fZXZlbnRSZWdpc3RlciAmJiB0aGlzLl9ldmVudFJlZ2lzdGVyW2V2ZW50TmFtZV0pXG4gICAgICByZXR1cm4gdGhpcy5fZXZlbnRSZWdpc3RlcltldmVudE5hbWVdKGV2ZW50KTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEhUTUxFbGVtZW50RXh0ZW5kT3B0PFQ+IHtcbiAgZWw6IEhUTUxFbGVtZW50O1xuICBvcHRpb246IFQ7XG4gIHVwZGF0ZU9wdGlvbihUKTogRERCYXNlSW1wbGVtZW50O1xufVxuIiwiLyoqXG4gKiBkZC1yZXNpemFibGUudHMgOC4yLjJcbiAqIENvcHlyaWdodCAoYykgMjAyMS0yMDIyIEFsYWluIER1bWVzbnkgLSBzZWUgR3JpZFN0YWNrIHJvb3QgbGljZW5zZVxuICovXG5cbmltcG9ydCB7IEREUmVzaXphYmxlSGFuZGxlIH0gZnJvbSAnLi9kZC1yZXNpemFibGUtaGFuZGxlJztcbmltcG9ydCB7IEREQmFzZUltcGxlbWVudCwgSFRNTEVsZW1lbnRFeHRlbmRPcHQgfSBmcm9tICcuL2RkLWJhc2UtaW1wbCc7XG5pbXBvcnQgeyBVdGlscyB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgRERVSURhdGEsIFJlY3QsIFNpemUgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IERETWFuYWdlciB9IGZyb20gJy4vZGQtbWFuYWdlcic7XG5cbi8vIGltcG9ydCB7IEdyaWRJdGVtSFRNTEVsZW1lbnQgfSBmcm9tICcuL3R5cGVzJzsgbGV0IGNvdW50ID0gMDsgLy8gVEVTVFxuXG4vLyBUT0RPOiBtZXJnZSB3aXRoIERERHJhZ09wdFxuZXhwb3J0IGludGVyZmFjZSBERFJlc2l6YWJsZU9wdCB7XG4gIGF1dG9IaWRlPzogYm9vbGVhbjtcbiAgaGFuZGxlcz86IHN0cmluZztcbiAgbWF4SGVpZ2h0PzogbnVtYmVyO1xuICBtYXhXaWR0aD86IG51bWJlcjtcbiAgbWluSGVpZ2h0PzogbnVtYmVyO1xuICBtaW5XaWR0aD86IG51bWJlcjtcbiAgc3RhcnQ/OiAoZXZlbnQ6IEV2ZW50LCB1aTogRERVSURhdGEpID0+IHZvaWQ7XG4gIHN0b3A/OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xuICByZXNpemU/OiAoZXZlbnQ6IEV2ZW50LCB1aTogRERVSURhdGEpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBERFJlc2l6YWJsZSBleHRlbmRzIEREQmFzZUltcGxlbWVudCBpbXBsZW1lbnRzIEhUTUxFbGVtZW50RXh0ZW5kT3B0PEREUmVzaXphYmxlT3B0PiB7XG5cbiAgLy8gaGF2ZSB0byBiZSBwdWJsaWMgZWxzZSBjb21wbGFpbnMgZm9yIEhUTUxFbGVtZW50RXh0ZW5kT3B0ID9cbiAgcHVibGljIGVsOiBIVE1MRWxlbWVudDtcbiAgcHVibGljIG9wdGlvbjogRERSZXNpemFibGVPcHQ7XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgaGFuZGxlcnM6IEREUmVzaXphYmxlSGFuZGxlW107XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIG9yaWdpbmFsUmVjdDogUmVjdDtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgdGVtcG9yYWxSZWN0OiBSZWN0O1xuICAvKiogQGludGVybmFsICovXG4gIHByb3RlY3RlZCBzY3JvbGxZOiBudW1iZXI7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIHNjcm9sbGVkOiBudW1iZXI7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIHNjcm9sbEVsOiBIVE1MRWxlbWVudDtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgc3RhcnRFdmVudDogTW91c2VFdmVudDtcbiAgLyoqIEBpbnRlcm5hbCB2YWx1ZSBzYXZlZCBpbiB0aGUgc2FtZSBvcmRlciBhcyBfb3JpZ2luU3R5bGVQcm9wW10gKi9cbiAgcHJvdGVjdGVkIGVsT3JpZ2luU3R5bGVWYWw6IHN0cmluZ1tdO1xuICAvKiogQGludGVybmFsICovXG4gIHByb3RlY3RlZCBwYXJlbnRPcmlnaW5TdHlsZVBvc2l0aW9uOiBzdHJpbmc7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIHN0YXRpYyBfb3JpZ2luU3R5bGVQcm9wID0gWyd3aWR0aCcsICdoZWlnaHQnLCAncG9zaXRpb24nLCAnbGVmdCcsICd0b3AnLCAnb3BhY2l0eScsICd6SW5kZXgnXTtcblxuICBjb25zdHJ1Y3RvcihlbDogSFRNTEVsZW1lbnQsIG9wdHM6IEREUmVzaXphYmxlT3B0ID0ge30pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICB0aGlzLm9wdGlvbiA9IG9wdHM7XG4gICAgLy8gY3JlYXRlIHZhciBldmVudCBiaW5kaW5nIHNvIHdlIGNhbiBlYXNpbHkgcmVtb3ZlIGFuZCBzdGlsbCBsb29rIGxpa2UgVFMgbWV0aG9kcyAodW5saWtlIGFub255bW91cyBmdW5jdGlvbnMpXG4gICAgdGhpcy5fbW91c2VPdmVyID0gdGhpcy5fbW91c2VPdmVyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fbW91c2VPdXQgPSB0aGlzLl9tb3VzZU91dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuZW5hYmxlKCk7XG4gICAgdGhpcy5fc2V0dXBBdXRvSGlkZSh0aGlzLm9wdGlvbi5hdXRvSGlkZSk7XG4gICAgdGhpcy5fc2V0dXBIYW5kbGVycygpO1xuICB9XG5cbiAgcHVibGljIG9uKGV2ZW50OiAncmVzaXplc3RhcnQnIHwgJ3Jlc2l6ZScgfCAncmVzaXplc3RvcCcsIGNhbGxiYWNrOiAoZXZlbnQ6IERyYWdFdmVudCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHN1cGVyLm9uKGV2ZW50LCBjYWxsYmFjayk7XG4gIH1cblxuICBwdWJsaWMgb2ZmKGV2ZW50OiAncmVzaXplc3RhcnQnIHwgJ3Jlc2l6ZScgfCAncmVzaXplc3RvcCcpOiB2b2lkIHtcbiAgICBzdXBlci5vZmYoZXZlbnQpO1xuICB9XG5cbiAgcHVibGljIGVuYWJsZSgpOiB2b2lkIHtcbiAgICBzdXBlci5lbmFibGUoKTtcbiAgICB0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoJ3VpLXJlc2l6YWJsZS1kaXNhYmxlZCcpO1xuICAgIHRoaXMuX3NldHVwQXV0b0hpZGUodGhpcy5vcHRpb24uYXV0b0hpZGUpO1xuICB9XG5cbiAgcHVibGljIGRpc2FibGUoKTogdm9pZCB7XG4gICAgc3VwZXIuZGlzYWJsZSgpO1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0LmFkZCgndWktcmVzaXphYmxlLWRpc2FibGVkJyk7XG4gICAgdGhpcy5fc2V0dXBBdXRvSGlkZShmYWxzZSk7XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9yZW1vdmVIYW5kbGVycygpO1xuICAgIHRoaXMuX3NldHVwQXV0b0hpZGUoZmFsc2UpO1xuICAgIGRlbGV0ZSB0aGlzLmVsO1xuICAgIHN1cGVyLmRlc3Ryb3koKTtcbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVPcHRpb24ob3B0czogRERSZXNpemFibGVPcHQpOiBERFJlc2l6YWJsZSB7XG4gICAgbGV0IHVwZGF0ZUhhbmRsZXMgPSAob3B0cy5oYW5kbGVzICYmIG9wdHMuaGFuZGxlcyAhPT0gdGhpcy5vcHRpb24uaGFuZGxlcyk7XG4gICAgbGV0IHVwZGF0ZUF1dG9IaWRlID0gKG9wdHMuYXV0b0hpZGUgJiYgb3B0cy5hdXRvSGlkZSAhPT0gdGhpcy5vcHRpb24uYXV0b0hpZGUpO1xuICAgIE9iamVjdC5rZXlzKG9wdHMpLmZvckVhY2goa2V5ID0+IHRoaXMub3B0aW9uW2tleV0gPSBvcHRzW2tleV0pO1xuICAgIGlmICh1cGRhdGVIYW5kbGVzKSB7XG4gICAgICB0aGlzLl9yZW1vdmVIYW5kbGVycygpO1xuICAgICAgdGhpcy5fc2V0dXBIYW5kbGVycygpO1xuICAgIH1cbiAgICBpZiAodXBkYXRlQXV0b0hpZGUpIHtcbiAgICAgIHRoaXMuX3NldHVwQXV0b0hpZGUodGhpcy5vcHRpb24uYXV0b0hpZGUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgdHVybnMgYXV0byBoaWRlIG9uL29mZiAqL1xuICBwcm90ZWN0ZWQgX3NldHVwQXV0b0hpZGUoYXV0bzogYm9vbGVhbik6IEREUmVzaXphYmxlIHtcbiAgICBpZiAoYXV0bykge1xuICAgICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKCd1aS1yZXNpemFibGUtYXV0b2hpZGUnKTtcbiAgICAgIC8vIHVzZSBtb3VzZW92ZXIgYW5kIG5vdCBtb3VzZWVudGVyIHRvIGdldCBiZXR0ZXIgcGVyZm9ybWFuY2UgYW5kIHRyYWNrIGZvciBuZXN0ZWQgY2FzZXNcbiAgICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgdGhpcy5fbW91c2VPdmVyKTtcbiAgICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCB0aGlzLl9tb3VzZU91dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZSgndWktcmVzaXphYmxlLWF1dG9oaWRlJyk7XG4gICAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsIHRoaXMuX21vdXNlT3Zlcik7XG4gICAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlb3V0JywgdGhpcy5fbW91c2VPdXQpO1xuICAgICAgaWYgKERETWFuYWdlci5vdmVyUmVzaXplRWxlbWVudCA9PT0gdGhpcykge1xuICAgICAgICBkZWxldGUgRERNYW5hZ2VyLm92ZXJSZXNpemVFbGVtZW50O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBwcm90ZWN0ZWQgX21vdXNlT3ZlcihlOiBFdmVudCk6IHZvaWQge1xuICAgIC8vIGNvbnNvbGUubG9nKGAke2NvdW50Kyt9IHByZS1lbnRlciAkeyh0aGlzLmVsIGFzIEdyaWRJdGVtSFRNTEVsZW1lbnQpLmdyaWRzdGFja05vZGUuX2lkfWApXG4gICAgLy8gYWxyZWFkeSBvdmVyIGEgY2hpbGQsIGlnbm9yZS4gSWRlYWxseSB3ZSBqdXN0IGNhbGwgZS5zdG9wUHJvcGFnYXRpb24oKSBidXQgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ncmlkc3RhY2svZ3JpZHN0YWNrLmpzL2lzc3Vlcy8yMDE4XG4gICAgaWYgKERETWFuYWdlci5vdmVyUmVzaXplRWxlbWVudCB8fCBERE1hbmFnZXIuZHJhZ0VsZW1lbnQpIHJldHVybjtcbiAgICBERE1hbmFnZXIub3ZlclJlc2l6ZUVsZW1lbnQgPSB0aGlzO1xuICAgIC8vIGNvbnNvbGUubG9nKGAke2NvdW50Kyt9IGVudGVyICR7KHRoaXMuZWwgYXMgR3JpZEl0ZW1IVE1MRWxlbWVudCkuZ3JpZHN0YWNrTm9kZS5faWR9YClcbiAgICB0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoJ3VpLXJlc2l6YWJsZS1hdXRvaGlkZScpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIHByb3RlY3RlZCBfbW91c2VPdXQoZTogRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBjb25zb2xlLmxvZyhgJHtjb3VudCsrfSBwcmUtbGVhdmUgJHsodGhpcy5lbCBhcyBHcmlkSXRlbUhUTUxFbGVtZW50KS5ncmlkc3RhY2tOb2RlLl9pZH1gKVxuICAgIGlmIChERE1hbmFnZXIub3ZlclJlc2l6ZUVsZW1lbnQgIT09IHRoaXMpIHJldHVybjtcbiAgICBkZWxldGUgRERNYW5hZ2VyLm92ZXJSZXNpemVFbGVtZW50O1xuICAgIC8vIGNvbnNvbGUubG9nKGAke2NvdW50Kyt9IGxlYXZlICR7KHRoaXMuZWwgYXMgR3JpZEl0ZW1IVE1MRWxlbWVudCkuZ3JpZHN0YWNrTm9kZS5faWR9YClcbiAgICB0aGlzLmVsLmNsYXNzTGlzdC5hZGQoJ3VpLXJlc2l6YWJsZS1hdXRvaGlkZScpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgX3NldHVwSGFuZGxlcnMoKTogRERSZXNpemFibGUge1xuICAgIGxldCBoYW5kbGVyRGlyZWN0aW9uID0gdGhpcy5vcHRpb24uaGFuZGxlcyB8fCAnZSxzLHNlJztcbiAgICBpZiAoaGFuZGxlckRpcmVjdGlvbiA9PT0gJ2FsbCcpIHtcbiAgICAgIGhhbmRsZXJEaXJlY3Rpb24gPSAnbixlLHMsdyxzZSxzdyxuZSxudyc7XG4gICAgfVxuICAgIHRoaXMuaGFuZGxlcnMgPSBoYW5kbGVyRGlyZWN0aW9uLnNwbGl0KCcsJylcbiAgICAgIC5tYXAoZGlyID0+IGRpci50cmltKCkpXG4gICAgICAubWFwKGRpciA9PiBuZXcgRERSZXNpemFibGVIYW5kbGUodGhpcy5lbCwgZGlyLCB7XG4gICAgICAgIHN0YXJ0OiAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgICB0aGlzLl9yZXNpemVTdGFydChldmVudCk7XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3A6IChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgICAgICAgIHRoaXMuX3Jlc2l6ZVN0b3AoZXZlbnQpO1xuICAgICAgICB9LFxuICAgICAgICBtb3ZlOiAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgICB0aGlzLl9yZXNpemluZyhldmVudCwgZGlyKTtcbiAgICAgICAgfVxuICAgICAgfSkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgX3Jlc2l6ZVN0YXJ0KGV2ZW50OiBNb3VzZUV2ZW50KTogRERSZXNpemFibGUge1xuICAgIHRoaXMub3JpZ2luYWxSZWN0ID0gdGhpcy5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB0aGlzLnNjcm9sbEVsID0gVXRpbHMuZ2V0U2Nyb2xsRWxlbWVudCh0aGlzLmVsKTtcbiAgICB0aGlzLnNjcm9sbFkgPSB0aGlzLnNjcm9sbEVsLnNjcm9sbFRvcDtcbiAgICB0aGlzLnNjcm9sbGVkID0gMDtcbiAgICB0aGlzLnN0YXJ0RXZlbnQgPSBldmVudDtcbiAgICB0aGlzLl9zZXR1cEhlbHBlcigpO1xuICAgIHRoaXMuX2FwcGx5Q2hhbmdlKCk7XG4gICAgY29uc3QgZXYgPSBVdGlscy5pbml0RXZlbnQ8TW91c2VFdmVudD4oZXZlbnQsIHsgdHlwZTogJ3Jlc2l6ZXN0YXJ0JywgdGFyZ2V0OiB0aGlzLmVsIH0pO1xuICAgIGlmICh0aGlzLm9wdGlvbi5zdGFydCkge1xuICAgICAgdGhpcy5vcHRpb24uc3RhcnQoZXYsIHRoaXMuX3VpKCkpO1xuICAgIH1cbiAgICB0aGlzLmVsLmNsYXNzTGlzdC5hZGQoJ3VpLXJlc2l6YWJsZS1yZXNpemluZycpO1xuICAgIHRoaXMudHJpZ2dlckV2ZW50KCdyZXNpemVzdGFydCcsIGV2KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF9yZXNpemluZyhldmVudDogTW91c2VFdmVudCwgZGlyOiBzdHJpbmcpOiBERFJlc2l6YWJsZSB7XG4gICAgdGhpcy5zY3JvbGxlZCA9IHRoaXMuc2Nyb2xsRWwuc2Nyb2xsVG9wIC0gdGhpcy5zY3JvbGxZO1xuICAgIHRoaXMudGVtcG9yYWxSZWN0ID0gdGhpcy5fZ2V0Q2hhbmdlKGV2ZW50LCBkaXIpO1xuICAgIHRoaXMuX2FwcGx5Q2hhbmdlKCk7XG4gICAgY29uc3QgZXYgPSBVdGlscy5pbml0RXZlbnQ8TW91c2VFdmVudD4oZXZlbnQsIHsgdHlwZTogJ3Jlc2l6ZScsIHRhcmdldDogdGhpcy5lbCB9KTtcbiAgICBpZiAodGhpcy5vcHRpb24ucmVzaXplKSB7XG4gICAgICB0aGlzLm9wdGlvbi5yZXNpemUoZXYsIHRoaXMuX3VpKCkpO1xuICAgIH1cbiAgICB0aGlzLnRyaWdnZXJFdmVudCgncmVzaXplJywgZXYpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgX3Jlc2l6ZVN0b3AoZXZlbnQ6IE1vdXNlRXZlbnQpOiBERFJlc2l6YWJsZSB7XG4gICAgY29uc3QgZXYgPSBVdGlscy5pbml0RXZlbnQ8TW91c2VFdmVudD4oZXZlbnQsIHsgdHlwZTogJ3Jlc2l6ZXN0b3AnLCB0YXJnZXQ6IHRoaXMuZWwgfSk7XG4gICAgaWYgKHRoaXMub3B0aW9uLnN0b3ApIHtcbiAgICAgIHRoaXMub3B0aW9uLnN0b3AoZXYpOyAvLyBOb3RlOiB1aSgpIG5vdCB1c2VkIGJ5IGdyaWRzdGFjayBzbyBkb24ndCBwYXNzXG4gICAgfVxuICAgIHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZSgndWktcmVzaXphYmxlLXJlc2l6aW5nJyk7XG4gICAgdGhpcy50cmlnZ2VyRXZlbnQoJ3Jlc2l6ZXN0b3AnLCBldik7XG4gICAgdGhpcy5fY2xlYW5IZWxwZXIoKTtcbiAgICBkZWxldGUgdGhpcy5zdGFydEV2ZW50O1xuICAgIGRlbGV0ZSB0aGlzLm9yaWdpbmFsUmVjdDtcbiAgICBkZWxldGUgdGhpcy50ZW1wb3JhbFJlY3Q7XG4gICAgZGVsZXRlIHRoaXMuc2Nyb2xsWTtcbiAgICBkZWxldGUgdGhpcy5zY3JvbGxlZDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF9zZXR1cEhlbHBlcigpOiBERFJlc2l6YWJsZSB7XG4gICAgdGhpcy5lbE9yaWdpblN0eWxlVmFsID0gRERSZXNpemFibGUuX29yaWdpblN0eWxlUHJvcC5tYXAocHJvcCA9PiB0aGlzLmVsLnN0eWxlW3Byb3BdKTtcbiAgICB0aGlzLnBhcmVudE9yaWdpblN0eWxlUG9zaXRpb24gPSB0aGlzLmVsLnBhcmVudEVsZW1lbnQuc3R5bGUucG9zaXRpb247XG4gICAgaWYgKHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWwucGFyZW50RWxlbWVudCkucG9zaXRpb24ubWF0Y2goL3N0YXRpYy8pKSB7XG4gICAgICB0aGlzLmVsLnBhcmVudEVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgIH1cbiAgICB0aGlzLmVsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICB0aGlzLmVsLnN0eWxlLm9wYWNpdHkgPSAnMC44JztcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF9jbGVhbkhlbHBlcigpOiBERFJlc2l6YWJsZSB7XG4gICAgRERSZXNpemFibGUuX29yaWdpblN0eWxlUHJvcC5mb3JFYWNoKChwcm9wLCBpKSA9PiB7XG4gICAgICB0aGlzLmVsLnN0eWxlW3Byb3BdID0gdGhpcy5lbE9yaWdpblN0eWxlVmFsW2ldIHx8IG51bGw7XG4gICAgfSk7XG4gICAgdGhpcy5lbC5wYXJlbnRFbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gdGhpcy5wYXJlbnRPcmlnaW5TdHlsZVBvc2l0aW9uIHx8IG51bGw7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIHByb3RlY3RlZCBfZ2V0Q2hhbmdlKGV2ZW50OiBNb3VzZUV2ZW50LCBkaXI6IHN0cmluZyk6IFJlY3Qge1xuICAgIGNvbnN0IG9FdmVudCA9IHRoaXMuc3RhcnRFdmVudDtcbiAgICBjb25zdCBuZXdSZWN0ID0geyAvLyBOb3RlOiBvcmlnaW5hbFJlY3QgaXMgYSBjb21wbGV4IG9iamVjdCwgbm90IGEgc2ltcGxlIFJlY3QsIHNvIGNvcHkgb3V0LlxuICAgICAgd2lkdGg6IHRoaXMub3JpZ2luYWxSZWN0LndpZHRoLFxuICAgICAgaGVpZ2h0OiB0aGlzLm9yaWdpbmFsUmVjdC5oZWlnaHQgKyB0aGlzLnNjcm9sbGVkLFxuICAgICAgbGVmdDogdGhpcy5vcmlnaW5hbFJlY3QubGVmdCxcbiAgICAgIHRvcDogdGhpcy5vcmlnaW5hbFJlY3QudG9wIC0gdGhpcy5zY3JvbGxlZFxuICAgIH07XG5cbiAgICBjb25zdCBvZmZzZXRYID0gZXZlbnQuY2xpZW50WCAtIG9FdmVudC5jbGllbnRYO1xuICAgIGNvbnN0IG9mZnNldFkgPSBldmVudC5jbGllbnRZIC0gb0V2ZW50LmNsaWVudFk7XG5cbiAgICBpZiAoZGlyLmluZGV4T2YoJ2UnKSA+IC0xKSB7XG4gICAgICBuZXdSZWN0LndpZHRoICs9IG9mZnNldFg7XG4gICAgfSBlbHNlIGlmIChkaXIuaW5kZXhPZigndycpID4gLTEpIHtcbiAgICAgIG5ld1JlY3Qud2lkdGggLT0gb2Zmc2V0WDtcbiAgICAgIG5ld1JlY3QubGVmdCArPSBvZmZzZXRYO1xuICAgIH1cbiAgICBpZiAoZGlyLmluZGV4T2YoJ3MnKSA+IC0xKSB7XG4gICAgICBuZXdSZWN0LmhlaWdodCArPSBvZmZzZXRZO1xuICAgIH0gZWxzZSBpZiAoZGlyLmluZGV4T2YoJ24nKSA+IC0xKSB7XG4gICAgICBuZXdSZWN0LmhlaWdodCAtPSBvZmZzZXRZO1xuICAgICAgbmV3UmVjdC50b3AgKz0gb2Zmc2V0WVxuICAgIH1cbiAgICBjb25zdCBjb25zdHJhaW4gPSB0aGlzLl9jb25zdHJhaW5TaXplKG5ld1JlY3Qud2lkdGgsIG5ld1JlY3QuaGVpZ2h0KTtcbiAgICBpZiAoTWF0aC5yb3VuZChuZXdSZWN0LndpZHRoKSAhPT0gTWF0aC5yb3VuZChjb25zdHJhaW4ud2lkdGgpKSB7IC8vIHJvdW5kIHRvIGlnbm9yZSBzbGlnaHQgcm91bmQtb2ZmIGVycm9yc1xuICAgICAgaWYgKGRpci5pbmRleE9mKCd3JykgPiAtMSkge1xuICAgICAgICBuZXdSZWN0LmxlZnQgKz0gbmV3UmVjdC53aWR0aCAtIGNvbnN0cmFpbi53aWR0aDtcbiAgICAgIH1cbiAgICAgIG5ld1JlY3Qud2lkdGggPSBjb25zdHJhaW4ud2lkdGg7XG4gICAgfVxuICAgIGlmIChNYXRoLnJvdW5kKG5ld1JlY3QuaGVpZ2h0KSAhPT0gTWF0aC5yb3VuZChjb25zdHJhaW4uaGVpZ2h0KSkge1xuICAgICAgaWYgKGRpci5pbmRleE9mKCduJykgPiAtMSkge1xuICAgICAgICBuZXdSZWN0LnRvcCArPSBuZXdSZWN0LmhlaWdodCAtIGNvbnN0cmFpbi5oZWlnaHQ7XG4gICAgICB9XG4gICAgICBuZXdSZWN0LmhlaWdodCA9IGNvbnN0cmFpbi5oZWlnaHQ7XG4gICAgfVxuICAgIHJldHVybiBuZXdSZWN0O1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCBjb25zdHJhaW4gdGhlIHNpemUgdG8gdGhlIHNldCBtaW4vbWF4IHZhbHVlcyAqL1xuICBwcm90ZWN0ZWQgX2NvbnN0cmFpblNpemUob1dpZHRoOiBudW1iZXIsIG9IZWlnaHQ6IG51bWJlcik6IFNpemUge1xuICAgIGNvbnN0IG1heFdpZHRoID0gdGhpcy5vcHRpb24ubWF4V2lkdGggfHwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI7XG4gICAgY29uc3QgbWluV2lkdGggPSB0aGlzLm9wdGlvbi5taW5XaWR0aCB8fCBvV2lkdGg7XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gdGhpcy5vcHRpb24ubWF4SGVpZ2h0IHx8IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSO1xuICAgIGNvbnN0IG1pbkhlaWdodCA9IHRoaXMub3B0aW9uLm1pbkhlaWdodCB8fCBvSGVpZ2h0O1xuICAgIGNvbnN0IHdpZHRoID0gTWF0aC5taW4obWF4V2lkdGgsIE1hdGgubWF4KG1pbldpZHRoLCBvV2lkdGgpKTtcbiAgICBjb25zdCBoZWlnaHQgPSBNYXRoLm1pbihtYXhIZWlnaHQsIE1hdGgubWF4KG1pbkhlaWdodCwgb0hlaWdodCkpO1xuICAgIHJldHVybiB7IHdpZHRoLCBoZWlnaHQgfTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF9hcHBseUNoYW5nZSgpOiBERFJlc2l6YWJsZSB7XG4gICAgbGV0IGNvbnRhaW5tZW50UmVjdCA9IHsgbGVmdDogMCwgdG9wOiAwLCB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XG4gICAgaWYgKHRoaXMuZWwuc3R5bGUucG9zaXRpb24gPT09ICdhYnNvbHV0ZScpIHtcbiAgICAgIGNvbnN0IGNvbnRhaW5tZW50RWwgPSB0aGlzLmVsLnBhcmVudEVsZW1lbnQ7XG4gICAgICBjb25zdCB7IGxlZnQsIHRvcCB9ID0gY29udGFpbm1lbnRFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnRhaW5tZW50UmVjdCA9IHsgbGVmdCwgdG9wLCB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XG4gICAgfVxuICAgIGlmICghdGhpcy50ZW1wb3JhbFJlY3QpIHJldHVybiB0aGlzO1xuICAgIE9iamVjdC5rZXlzKHRoaXMudGVtcG9yYWxSZWN0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMudGVtcG9yYWxSZWN0W2tleV07XG4gICAgICB0aGlzLmVsLnN0eWxlW2tleV0gPSB2YWx1ZSAtIGNvbnRhaW5tZW50UmVjdFtrZXldICsgJ3B4JztcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF9yZW1vdmVIYW5kbGVycygpOiBERFJlc2l6YWJsZSB7XG4gICAgdGhpcy5oYW5kbGVycy5mb3JFYWNoKGhhbmRsZSA9PiBoYW5kbGUuZGVzdHJveSgpKTtcbiAgICBkZWxldGUgdGhpcy5oYW5kbGVycztcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF91aSA9ICgpOiBERFVJRGF0YSA9PiB7XG4gICAgY29uc3QgY29udGFpbm1lbnRFbCA9IHRoaXMuZWwucGFyZW50RWxlbWVudDtcbiAgICBjb25zdCBjb250YWlubWVudFJlY3QgPSBjb250YWlubWVudEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IG5ld1JlY3QgPSB7IC8vIE5vdGU6IG9yaWdpbmFsUmVjdCBpcyBhIGNvbXBsZXggb2JqZWN0LCBub3QgYSBzaW1wbGUgUmVjdCwgc28gY29weSBvdXQuXG4gICAgICB3aWR0aDogdGhpcy5vcmlnaW5hbFJlY3Qud2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMub3JpZ2luYWxSZWN0LmhlaWdodCArIHRoaXMuc2Nyb2xsZWQsXG4gICAgICBsZWZ0OiB0aGlzLm9yaWdpbmFsUmVjdC5sZWZ0LFxuICAgICAgdG9wOiB0aGlzLm9yaWdpbmFsUmVjdC50b3AgLSB0aGlzLnNjcm9sbGVkXG4gICAgfTtcbiAgICBjb25zdCByZWN0ID0gdGhpcy50ZW1wb3JhbFJlY3QgfHwgbmV3UmVjdDtcbiAgICByZXR1cm4ge1xuICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgbGVmdDogcmVjdC5sZWZ0IC0gY29udGFpbm1lbnRSZWN0LmxlZnQsXG4gICAgICAgIHRvcDogcmVjdC50b3AgLSBjb250YWlubWVudFJlY3QudG9wXG4gICAgICB9LFxuICAgICAgc2l6ZToge1xuICAgICAgICB3aWR0aDogcmVjdC53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiByZWN0LmhlaWdodFxuICAgICAgfVxuICAgICAgLyogR3JpZHN0YWNrIE9OTFkgbmVlZHMgcG9zaXRpb24gc2V0IGFib3ZlLi4uIGtlZXAgYXJvdW5kIGluIGNhc2UuXG4gICAgICBlbGVtZW50OiBbdGhpcy5lbF0sIC8vIFRoZSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBlbGVtZW50IHRvIGJlIHJlc2l6ZWRcbiAgICAgIGhlbHBlcjogW10sIC8vIFRPRE86IG5vdCBzdXBwb3J0IHlldCAtIFRoZSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBoZWxwZXIgdGhhdCdzIGJlaW5nIHJlc2l6ZWRcbiAgICAgIG9yaWdpbmFsRWxlbWVudDogW3RoaXMuZWxdLC8vIHdlIGRvbid0IHdyYXAgaGVyZSwgc28gc2ltcGxpZnkgYXMgdGhpcy5lbCAvL1RoZSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBvcmlnaW5hbCBlbGVtZW50IGJlZm9yZSBpdCBpcyB3cmFwcGVkXG4gICAgICBvcmlnaW5hbFBvc2l0aW9uOiB7IC8vIFRoZSBwb3NpdGlvbiByZXByZXNlbnRlZCBhcyB7IGxlZnQsIHRvcCB9IGJlZm9yZSB0aGUgcmVzaXphYmxlIGlzIHJlc2l6ZWRcbiAgICAgICAgbGVmdDogdGhpcy5vcmlnaW5hbFJlY3QubGVmdCAtIGNvbnRhaW5tZW50UmVjdC5sZWZ0LFxuICAgICAgICB0b3A6IHRoaXMub3JpZ2luYWxSZWN0LnRvcCAtIGNvbnRhaW5tZW50UmVjdC50b3BcbiAgICAgIH0sXG4gICAgICBvcmlnaW5hbFNpemU6IHsgLy8gVGhlIHNpemUgcmVwcmVzZW50ZWQgYXMgeyB3aWR0aCwgaGVpZ2h0IH0gYmVmb3JlIHRoZSByZXNpemFibGUgaXMgcmVzaXplZFxuICAgICAgICB3aWR0aDogdGhpcy5vcmlnaW5hbFJlY3Qud2lkdGgsXG4gICAgICAgIGhlaWdodDogdGhpcy5vcmlnaW5hbFJlY3QuaGVpZ2h0XG4gICAgICB9XG4gICAgICAqL1xuICAgIH07XG4gIH1cbn1cbiIsIi8qKlxuICogZGQtZHJhZ2dhYmxlLnRzIDguMi4yXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjEtMjAyMiBBbGFpbiBEdW1lc255IC0gc2VlIEdyaWRTdGFjayByb290IGxpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgeyBERE1hbmFnZXIgfSBmcm9tICcuL2RkLW1hbmFnZXInO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IEREQmFzZUltcGxlbWVudCwgSFRNTEVsZW1lbnRFeHRlbmRPcHQgfSBmcm9tICcuL2RkLWJhc2UtaW1wbCc7XG5pbXBvcnQgeyBHcmlkSXRlbUhUTUxFbGVtZW50LCBERFVJRGF0YSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgRERFbGVtZW50SG9zdCB9IGZyb20gJy4vZGQtZWxlbWVudCc7XG5pbXBvcnQgeyBpc1RvdWNoLCB0b3VjaGVuZCwgdG91Y2htb3ZlLCB0b3VjaHN0YXJ0LCBwb2ludGVyZG93biB9IGZyb20gJy4vZGQtdG91Y2gnO1xuXG4vLyBUT0RPOiBtZXJnZSB3aXRoIERERHJhZ09wdCA/XG5leHBvcnQgaW50ZXJmYWNlIERERHJhZ2dhYmxlT3B0IHtcbiAgYXBwZW5kVG8/OiBzdHJpbmcgfCBIVE1MRWxlbWVudDtcbiAgaGFuZGxlPzogc3RyaW5nO1xuICBoZWxwZXI/OiAnY2xvbmUnIHwgSFRNTEVsZW1lbnQgfCAoKGV2ZW50OiBFdmVudCkgPT4gSFRNTEVsZW1lbnQpO1xuICBjYW5jZWw/OiBzdHJpbmc7XG4gIC8vIGNvbnRhaW5tZW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQ7IC8vIFRPRE86IG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiAgLy8gcmV2ZXJ0Pzogc3RyaW5nIHwgYm9vbGVhbiB8IHVua25vd247IC8vIFRPRE86IG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiAgLy8gc2Nyb2xsPzogYm9vbGVhbjtcbiAgc3RhcnQ/OiAoZXZlbnQ6IEV2ZW50LCB1aTogRERVSURhdGEpID0+IHZvaWQ7XG4gIHN0b3A/OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xuICBkcmFnPzogKGV2ZW50OiBFdmVudCwgdWk6IEREVUlEYXRhKSA9PiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgRHJhZ09mZnNldCB7XG4gIGxlZnQ6IG51bWJlcjtcbiAgdG9wOiBudW1iZXI7XG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICBvZmZzZXRMZWZ0OiBudW1iZXI7XG4gIG9mZnNldFRvcDogbnVtYmVyO1xufVxuXG50eXBlIERERHJhZ0V2ZW50ID0gJ2RyYWcnIHwgJ2RyYWdzdGFydCcgfCAnZHJhZ3N0b3AnO1xuXG4vLyBtYWtlIHN1cmUgd2UgYXJlIG5vdCBjbGlja2luZyBvbiBrbm93biBvYmplY3QgdGhhdCBoYW5kbGVzIG1vdXNlRG93blxuY29uc3Qgc2tpcE1vdXNlRG93biA9ICdpbnB1dCx0ZXh0YXJlYSxidXR0b24sc2VsZWN0LG9wdGlvbixbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSwudWktcmVzaXphYmxlLWhhbmRsZSc7XG5cbi8vIGxldCBjb3VudCA9IDA7IC8vIFRFU1RcblxuZXhwb3J0IGNsYXNzIERERHJhZ2dhYmxlIGV4dGVuZHMgRERCYXNlSW1wbGVtZW50IGltcGxlbWVudHMgSFRNTEVsZW1lbnRFeHRlbmRPcHQ8REREcmFnZ2FibGVPcHQ+IHtcbiAgcHVibGljIGVsOiBIVE1MRWxlbWVudDtcbiAgcHVibGljIG9wdGlvbjogREREcmFnZ2FibGVPcHQ7XG4gIHB1YmxpYyBoZWxwZXI6IEhUTUxFbGVtZW50OyAvLyB1c2VkIGJ5IEdyaWRTdGFja0RETmF0aXZlXG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgbW91c2VEb3duRXZlbnQ6IE1vdXNlRXZlbnQ7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIGRyYWdPZmZzZXQ6IERyYWdPZmZzZXQ7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIGRyYWdFbGVtZW50T3JpZ2luU3R5bGU6IEFycmF5PHN0cmluZz47XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIGRyYWdFbDogSFRNTEVsZW1lbnQ7XG4gIC8qKiBAaW50ZXJuYWwgdHJ1ZSB3aGlsZSB3ZSBhcmUgZHJhZ2dpbmcgYW4gaXRlbSBhcm91bmQgKi9cbiAgcHJvdGVjdGVkIGRyYWdnaW5nOiBib29sZWFuO1xuICAvKiogQGludGVybmFsICovXG4gIHByb3RlY3RlZCBwYXJlbnRPcmlnaW5TdHlsZVBvc2l0aW9uOiBzdHJpbmc7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIGhlbHBlckNvbnRhaW5tZW50OiBIVE1MRWxlbWVudDtcbiAgLyoqIEBpbnRlcm5hbCBwcm9wZXJ0aWVzIHdlIGNoYW5nZSBkdXJpbmcgZHJhZ2dpbmcsIGFuZCByZXN0b3JlIGJhY2sgKi9cbiAgcHJvdGVjdGVkIHN0YXRpYyBvcmlnaW5TdHlsZVByb3AgPSBbJ3RyYW5zaXRpb24nLCAncG9pbnRlckV2ZW50cycsICdwb3NpdGlvbicsICdsZWZ0JywgJ3RvcCcsICdtaW5XaWR0aCcsICd3aWxsQ2hhbmdlJ107XG4gIC8qKiBAaW50ZXJuYWwgcGF1c2UgYmVmb3JlIHdlIGNhbGwgdGhlIGFjdHVhbCBkcmFnIGhpdCBjb2xsaXNpb24gY29kZSAqL1xuICBwcm90ZWN0ZWQgZHJhZ1RpbWVvdXQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihlbDogSFRNTEVsZW1lbnQsIG9wdGlvbjogREREcmFnZ2FibGVPcHQgPSB7fSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5lbCA9IGVsO1xuICAgIHRoaXMub3B0aW9uID0gb3B0aW9uO1xuXG4gICAgLy8gZ2V0IHRoZSBlbGVtZW50IHRoYXQgaXMgYWN0dWFsbHkgc3VwcG9zZWQgdG8gYmUgZHJhZ2dlZCBieVxuICAgIGxldCBoYW5kbGVOYW1lID0gb3B0aW9uLmhhbmRsZS5zdWJzdHJpbmcoMSk7XG4gICAgdGhpcy5kcmFnRWwgPSBlbC5jbGFzc0xpc3QuY29udGFpbnMoaGFuZGxlTmFtZSkgPyBlbCA6IGVsLnF1ZXJ5U2VsZWN0b3Iob3B0aW9uLmhhbmRsZSkgfHwgZWw7XG4gICAgLy8gY3JlYXRlIHZhciBldmVudCBiaW5kaW5nIHNvIHdlIGNhbiBlYXNpbHkgcmVtb3ZlIGFuZCBzdGlsbCBsb29rIGxpa2UgVFMgbWV0aG9kcyAodW5saWtlIGFub255bW91cyBmdW5jdGlvbnMpXG4gICAgdGhpcy5fbW91c2VEb3duID0gdGhpcy5fbW91c2VEb3duLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fbW91c2VNb3ZlID0gdGhpcy5fbW91c2VNb3ZlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fbW91c2VVcCA9IHRoaXMuX21vdXNlVXAuYmluZCh0aGlzKTtcbiAgICB0aGlzLmVuYWJsZSgpO1xuICB9XG5cbiAgcHVibGljIG9uKGV2ZW50OiBERERyYWdFdmVudCwgY2FsbGJhY2s6IChldmVudDogRHJhZ0V2ZW50KSA9PiB2b2lkKTogdm9pZCB7XG4gICAgc3VwZXIub24oZXZlbnQsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHB1YmxpYyBvZmYoZXZlbnQ6IERERHJhZ0V2ZW50KTogdm9pZCB7XG4gICAgc3VwZXIub2ZmKGV2ZW50KTtcbiAgfVxuXG4gIHB1YmxpYyBlbmFibGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQgPT09IGZhbHNlKSByZXR1cm47XG4gICAgc3VwZXIuZW5hYmxlKCk7XG4gICAgdGhpcy5kcmFnRWwuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5fbW91c2VEb3duKTtcbiAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgdGhpcy5kcmFnRWwuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRvdWNoc3RhcnQpO1xuICAgICAgdGhpcy5kcmFnRWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCBwb2ludGVyZG93bik7XG4gICAgICAvLyB0aGlzLmRyYWdFbC5zdHlsZS50b3VjaEFjdGlvbiA9ICdub25lJzsgLy8gbm90IG5lZWRlZCB1bmxpa2UgcG9pbnRlcmRvd24gZG9jIGNvbW1lbnRcbiAgICB9XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKCd1aS1kcmFnZ2FibGUtZGlzYWJsZWQnKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNhYmxlKGZvckRlc3Ryb3kgPSBmYWxzZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkID09PSB0cnVlKSByZXR1cm47XG4gICAgc3VwZXIuZGlzYWJsZSgpO1xuICAgIHRoaXMuZHJhZ0VsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMuX21vdXNlRG93bik7XG4gICAgaWYgKGlzVG91Y2gpIHtcbiAgICAgIHRoaXMuZHJhZ0VsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0b3VjaHN0YXJ0KTtcbiAgICAgIHRoaXMuZHJhZ0VsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgcG9pbnRlcmRvd24pO1xuICAgIH1cbiAgICBpZiAoIWZvckRlc3Ryb3kpIHRoaXMuZWwuY2xhc3NMaXN0LmFkZCgndWktZHJhZ2dhYmxlLWRpc2FibGVkJyk7XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kcmFnVGltZW91dCkgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLmRyYWdUaW1lb3V0KTtcbiAgICBkZWxldGUgdGhpcy5kcmFnVGltZW91dDtcbiAgICBpZiAodGhpcy5kcmFnZ2luZykgdGhpcy5fbW91c2VVcCh0aGlzLm1vdXNlRG93bkV2ZW50KTtcbiAgICB0aGlzLmRpc2FibGUodHJ1ZSk7XG4gICAgZGVsZXRlIHRoaXMuZWw7XG4gICAgZGVsZXRlIHRoaXMuaGVscGVyO1xuICAgIGRlbGV0ZSB0aGlzLm9wdGlvbjtcbiAgICBzdXBlci5kZXN0cm95KCk7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlT3B0aW9uKG9wdHM6IERERHJhZ2dhYmxlT3B0KTogREREcmFnZ2FibGUge1xuICAgIE9iamVjdC5rZXlzKG9wdHMpLmZvckVhY2goa2V5ID0+IHRoaXMub3B0aW9uW2tleV0gPSBvcHRzW2tleV0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCBjYWxsIHdoZW4gbW91c2UgZ29lcyBkb3duIGJlZm9yZSBhIGRyYWdzdGFydCBoYXBwZW5zICovXG4gIHByb3RlY3RlZCBfbW91c2VEb3duKGU6IE1vdXNlRXZlbnQpOiBib29sZWFuIHtcbiAgICAvLyBkb24ndCBsZXQgbW9yZSB0aGFuIG9uZSB3aWRnZXQgaGFuZGxlIG1vdXNlU3RhcnRcbiAgICBpZiAoRERNYW5hZ2VyLm1vdXNlSGFuZGxlZCkgcmV0dXJuO1xuICAgIGlmIChlLmJ1dHRvbiAhPT0gMCkgcmV0dXJuIHRydWU7IC8vIG9ubHkgbGVmdCBjbGlja1xuXG4gICAgLy8gbWFrZSBzdXJlIHdlIGFyZSBub3QgY2xpY2tpbmcgb24ga25vd24gb2JqZWN0IHRoYXQgaGFuZGxlcyBtb3VzZURvd24sIG9yIG9uZXMgc3VwcGxpZWQgYnkgdGhlIHVzZXJcbiAgICBpZiAoKGUudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KHNraXBNb3VzZURvd24pKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAodGhpcy5vcHRpb24uY2FuY2VsKSB7XG4gICAgICBpZiAoKGUudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KHRoaXMub3B0aW9uLmNhbmNlbCkpIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIFJFTU9WRTogd2h5IHdvdWxkIHdlIGdldCB0aGUgZXZlbnQgaWYgaXQgd2Fzbid0IGZvciB1cyBvciBjaGlsZCA/XG4gICAgLy8gbWFrZSBzdXJlIHdlIGFyZSBjbGlja2luZyBvbiBhIGRyYWcgaGFuZGxlIG9yIGNoaWxkIG9mIGl0Li4uXG4gICAgLy8gTm90ZTogd2UgZG9uJ3QgbmVlZCB0byBjaGVjayB0aGF0J3MgaGFuZGxlIGlzIGFuIGltbWVkaWF0ZSBjaGlsZCwgYXMgbW91c2VIYW5kbGVkIHdpbGwgcHJldmVudCBwYXJlbnRzIGZyb20gYWxzbyBoYW5kbGluZyBpdCAobG93ZXN0IHdpbnMpXG4gICAgLy8gbGV0IGNsYXNzTmFtZSA9IHRoaXMub3B0aW9uLmhhbmRsZS5zdWJzdHJpbmcoMSk7XG4gICAgLy8gbGV0IGVsID0gZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgLy8gd2hpbGUgKGVsICYmICFlbC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSkgeyBlbCA9IGVsLnBhcmVudEVsZW1lbnQ7IH1cbiAgICAvLyBpZiAoIWVsKSByZXR1cm47XG5cbiAgICB0aGlzLm1vdXNlRG93bkV2ZW50ID0gZTtcbiAgICBkZWxldGUgdGhpcy5kcmFnZ2luZztcbiAgICBkZWxldGUgRERNYW5hZ2VyLmRyYWdFbGVtZW50O1xuICAgIGRlbGV0ZSBERE1hbmFnZXIuZHJvcEVsZW1lbnQ7XG4gICAgLy8gZG9jdW1lbnQgaGFuZGxlciBzbyB3ZSBjYW4gY29udGludWUgcmVjZWl2aW5nIG1vdmVzIGFzIHRoZSBpdGVtIGlzICdmaXhlZCcgcG9zaXRpb24sIGFuZCBjYXB0dXJlPXRydWUgc28gV0UgZ2V0IGEgZmlyc3QgY3JhY2tcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLl9tb3VzZU1vdmUsIHRydWUpOyAvLyB0cnVlPWNhcHR1cmUsIG5vdCBidWJibGVcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5fbW91c2VVcCwgdHJ1ZSk7XG4gICAgaWYgKGlzVG91Y2gpIHtcbiAgICAgIHRoaXMuZHJhZ0VsLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRvdWNobW92ZSk7XG4gICAgICB0aGlzLmRyYWdFbC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRvdWNoZW5kKTtcbiAgICB9XG5cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgLy8gcHJldmVudERlZmF1bHQoKSBwcmV2ZW50cyBibHVyIGV2ZW50IHdoaWNoIG9jY3VycyBqdXN0IGFmdGVyIG1vdXNlZG93biBldmVudC5cbiAgICAvLyBpZiBhbiBlZGl0YWJsZSBjb250ZW50IGhhcyBmb2N1cywgdGhlbiBibHVyIG11c3QgYmUgY2FsbFxuICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50KSAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCkuYmx1cigpO1xuXG4gICAgRERNYW5hZ2VyLm1vdXNlSGFuZGxlZCA9IHRydWU7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogQGludGVybmFsIG1ldGhvZCB0byBjYWxsIGFjdHVhbCBkcmFnIGV2ZW50ICovXG4gIHByb3RlY3RlZCBfY2FsbERyYWcoZTogRHJhZ0V2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmRyYWdnaW5nKSByZXR1cm47XG4gICAgY29uc3QgZXYgPSBVdGlscy5pbml0RXZlbnQ8RHJhZ0V2ZW50PihlLCB7IHRhcmdldDogdGhpcy5lbCwgdHlwZTogJ2RyYWcnIH0pO1xuICAgIGlmICh0aGlzLm9wdGlvbi5kcmFnKSB7XG4gICAgICB0aGlzLm9wdGlvbi5kcmFnKGV2LCB0aGlzLnVpKCkpO1xuICAgIH1cbiAgICB0aGlzLnRyaWdnZXJFdmVudCgnZHJhZycsIGV2KTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgY2FsbGVkIHdoZW4gdGhlIG1haW4gcGFnZSAoYWZ0ZXIgc3VjY2Vzc2Z1bCBtb3VzZWRvd24pIHJlY2VpdmVzIGEgbW92ZSBldmVudCB0byBkcmFnIHRoZSBpdGVtIGFyb3VuZCB0aGUgc2NyZWVuICovXG4gIHByb3RlY3RlZCBfbW91c2VNb3ZlKGU6IERyYWdFdmVudCk6IGJvb2xlYW4ge1xuICAgIC8vIGNvbnNvbGUubG9nKGAke2NvdW50Kyt9IG1vdmUgJHtlLnh9LCR7ZS55fWApXG4gICAgbGV0IHMgPSB0aGlzLm1vdXNlRG93bkV2ZW50O1xuXG4gICAgaWYgKHRoaXMuZHJhZ2dpbmcpIHtcbiAgICAgIHRoaXMuX2RyYWdGb2xsb3coZSk7XG4gICAgICAvLyBkZWxheSBhY3R1YWwgZ3JpZCBoYW5kbGluZyBkcmFnIHVudGlsIHdlIHBhdXNlIGZvciBhIHdoaWxlIGlmIHNldFxuICAgICAgaWYgKERETWFuYWdlci5wYXVzZURyYWcpIHtcbiAgICAgICAgY29uc3QgcGF1c2UgPSBOdW1iZXIuaXNJbnRlZ2VyKERETWFuYWdlci5wYXVzZURyYWcpID8gRERNYW5hZ2VyLnBhdXNlRHJhZyBhcyBudW1iZXIgOiAxMDA7XG4gICAgICAgIGlmICh0aGlzLmRyYWdUaW1lb3V0KSB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuZHJhZ1RpbWVvdXQpO1xuICAgICAgICB0aGlzLmRyYWdUaW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4gdGhpcy5fY2FsbERyYWcoZSksIHBhdXNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2NhbGxEcmFnKGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoTWF0aC5hYnMoZS54IC0gcy54KSArIE1hdGguYWJzKGUueSAtIHMueSkgPiAzKSB7XG4gICAgICAvKipcbiAgICAgICAqIGRvbid0IHN0YXJ0IHVubGVzcyB3ZSd2ZSBtb3ZlZCBhdCBsZWFzdCAzIHBpeGVsc1xuICAgICAgICovXG4gICAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgICAgIERETWFuYWdlci5kcmFnRWxlbWVudCA9IHRoaXM7XG4gICAgICAvLyBpZiB3ZSdyZSBkcmFnZ2luZyBhbiBhY3R1YWwgZ3JpZCBpdGVtLCBzZXQgdGhlIGN1cnJlbnQgZHJvcCBhcyB0aGUgZ3JpZCAodG8gZGV0ZWN0IGVudGVyL2xlYXZlKVxuICAgICAgbGV0IGdyaWQgPSAodGhpcy5lbCBhcyBHcmlkSXRlbUhUTUxFbGVtZW50KS5ncmlkc3RhY2tOb2RlPy5ncmlkO1xuICAgICAgaWYgKGdyaWQpIHtcbiAgICAgICAgRERNYW5hZ2VyLmRyb3BFbGVtZW50ID0gKGdyaWQuZWwgYXMgRERFbGVtZW50SG9zdCkuZGRFbGVtZW50LmRkRHJvcHBhYmxlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIERETWFuYWdlci5kcm9wRWxlbWVudDtcbiAgICAgIH1cbiAgICAgIHRoaXMuaGVscGVyID0gdGhpcy5fY3JlYXRlSGVscGVyKGUpO1xuICAgICAgdGhpcy5fc2V0dXBIZWxwZXJDb250YWlubWVudFN0eWxlKCk7XG4gICAgICB0aGlzLmRyYWdPZmZzZXQgPSB0aGlzLl9nZXREcmFnT2Zmc2V0KGUsIHRoaXMuZWwsIHRoaXMuaGVscGVyQ29udGFpbm1lbnQpO1xuICAgICAgY29uc3QgZXYgPSBVdGlscy5pbml0RXZlbnQ8RHJhZ0V2ZW50PihlLCB7IHRhcmdldDogdGhpcy5lbCwgdHlwZTogJ2RyYWdzdGFydCcgfSk7XG5cbiAgICAgIHRoaXMuX3NldHVwSGVscGVyU3R5bGUoZSk7XG4gICAgICBpZiAodGhpcy5vcHRpb24uc3RhcnQpIHtcbiAgICAgICAgdGhpcy5vcHRpb24uc3RhcnQoZXYsIHRoaXMudWkoKSk7XG4gICAgICB9XG4gICAgICB0aGlzLnRyaWdnZXJFdmVudCgnZHJhZ3N0YXJ0JywgZXYpO1xuICAgIH1cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7IC8vIG5lZWRlZCBvdGhlcndpc2Ugd2UgZ2V0IHRleHQgc3dlZXAgdGV4dCBzZWxlY3Rpb24gYXMgd2UgZHJhZyBhcm91bmRcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgY2FsbCB3aGVuIHRoZSBtb3VzZSBnZXRzIHJlbGVhc2VkIHRvIGRyb3AgdGhlIGl0ZW0gYXQgY3VycmVudCBsb2NhdGlvbiAqL1xuICBwcm90ZWN0ZWQgX21vdXNlVXAoZTogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMuX21vdXNlTW92ZSwgdHJ1ZSk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuX21vdXNlVXAsIHRydWUpO1xuICAgIGlmIChpc1RvdWNoKSB7XG4gICAgICB0aGlzLmRyYWdFbC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0b3VjaG1vdmUsIHRydWUpO1xuICAgICAgdGhpcy5kcmFnRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0b3VjaGVuZCwgdHJ1ZSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmRyYWdnaW5nKSB7XG4gICAgICBkZWxldGUgdGhpcy5kcmFnZ2luZztcblxuICAgICAgLy8gcmVzZXQgdGhlIGRyb3AgdGFyZ2V0IGlmIGRyYWdnaW5nIG92ZXIgb3Vyc2VsZiAoYWxyZWFkeSBwYXJlbnRlZCwganVzdCBtb3ZpbmcgZHVyaW5nIHN0b3AgY2FsbGJhY2sgYmVsb3cpXG4gICAgICBpZiAoRERNYW5hZ2VyLmRyb3BFbGVtZW50Py5lbCA9PT0gdGhpcy5lbC5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgIGRlbGV0ZSBERE1hbmFnZXIuZHJvcEVsZW1lbnQ7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuaGVscGVyQ29udGFpbm1lbnQuc3R5bGUucG9zaXRpb24gPSB0aGlzLnBhcmVudE9yaWdpblN0eWxlUG9zaXRpb24gfHwgbnVsbDtcbiAgICAgIGlmICh0aGlzLmhlbHBlciA9PT0gdGhpcy5lbCkge1xuICAgICAgICB0aGlzLl9yZW1vdmVIZWxwZXJTdHlsZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5oZWxwZXIucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgICBjb25zdCBldiA9IFV0aWxzLmluaXRFdmVudDxEcmFnRXZlbnQ+KGUsIHsgdGFyZ2V0OiB0aGlzLmVsLCB0eXBlOiAnZHJhZ3N0b3AnIH0pO1xuICAgICAgaWYgKHRoaXMub3B0aW9uLnN0b3ApIHtcbiAgICAgICAgdGhpcy5vcHRpb24uc3RvcChldik7IC8vIE5PVEU6IGRlc3Ryb3koKSB3aWxsIGJlIGNhbGxlZCB3aGVuIHJlbW92aW5nIGl0ZW0sIHNvIGV4cGVjdCBOVUxMIHB0ciBhZnRlciFcbiAgICAgIH1cbiAgICAgIHRoaXMudHJpZ2dlckV2ZW50KCdkcmFnc3RvcCcsIGV2KTtcblxuICAgICAgLy8gY2FsbCB0aGUgZHJvcHBhYmxlIG1ldGhvZCB0byByZWNlaXZlIHRoZSBpdGVtXG4gICAgICBpZiAoRERNYW5hZ2VyLmRyb3BFbGVtZW50KSB7XG4gICAgICAgIERETWFuYWdlci5kcm9wRWxlbWVudC5kcm9wKGUpO1xuICAgICAgfVxuICAgIH1cbiAgICBkZWxldGUgdGhpcy5oZWxwZXI7XG4gICAgZGVsZXRlIHRoaXMubW91c2VEb3duRXZlbnQ7XG4gICAgZGVsZXRlIERETWFuYWdlci5kcmFnRWxlbWVudDtcbiAgICBkZWxldGUgRERNYW5hZ2VyLmRyb3BFbGVtZW50O1xuICAgIGRlbGV0ZSBERE1hbmFnZXIubW91c2VIYW5kbGVkO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgY3JlYXRlIGEgY2xvbmUgY29weSAob3IgdXNlciBkZWZpbmVkIG1ldGhvZCkgb2YgdGhlIG9yaWdpbmFsIGRyYWcgaXRlbSBpZiBzZXQgKi9cbiAgcHJvdGVjdGVkIF9jcmVhdGVIZWxwZXIoZXZlbnQ6IERyYWdFdmVudCk6IEhUTUxFbGVtZW50IHtcbiAgICBsZXQgaGVscGVyID0gdGhpcy5lbDtcbiAgICBpZiAodHlwZW9mIHRoaXMub3B0aW9uLmhlbHBlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaGVscGVyID0gdGhpcy5vcHRpb24uaGVscGVyKGV2ZW50KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uLmhlbHBlciA9PT0gJ2Nsb25lJykge1xuICAgICAgaGVscGVyID0gVXRpbHMuY2xvbmVOb2RlKHRoaXMuZWwpO1xuICAgIH1cbiAgICBpZiAoIWRvY3VtZW50LmJvZHkuY29udGFpbnMoaGVscGVyKSkge1xuICAgICAgVXRpbHMuYXBwZW5kVG8oaGVscGVyLCB0aGlzLm9wdGlvbi5hcHBlbmRUbyA9PT0gJ3BhcmVudCcgPyB0aGlzLmVsLnBhcmVudEVsZW1lbnQgOiB0aGlzLm9wdGlvbi5hcHBlbmRUbyk7XG4gICAgfVxuICAgIGlmIChoZWxwZXIgPT09IHRoaXMuZWwpIHtcbiAgICAgIHRoaXMuZHJhZ0VsZW1lbnRPcmlnaW5TdHlsZSA9IERERHJhZ2dhYmxlLm9yaWdpblN0eWxlUHJvcC5tYXAocHJvcCA9PiB0aGlzLmVsLnN0eWxlW3Byb3BdKTtcbiAgICB9XG4gICAgcmV0dXJuIGhlbHBlcjtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgc2V0IHRoZSBmaXggcG9zaXRpb24gb2YgdGhlIGRyYWdnZWQgaXRlbSAqL1xuICBwcm90ZWN0ZWQgX3NldHVwSGVscGVyU3R5bGUoZTogRHJhZ0V2ZW50KTogREREcmFnZ2FibGUge1xuICAgIHRoaXMuaGVscGVyLmNsYXNzTGlzdC5hZGQoJ3VpLWRyYWdnYWJsZS1kcmFnZ2luZycpO1xuICAgIC8vIFRPRE86IHNldCBhbGwgYXQgb25jZSB3aXRoIHN0eWxlLmNzc1RleHQgKz0gLi4uID8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzk2ODU5M1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5oZWxwZXIuc3R5bGU7XG4gICAgc3R5bGUucG9pbnRlckV2ZW50cyA9ICdub25lJzsgLy8gbmVlZGVkIGZvciBvdmVyIGl0ZW1zIHRvIGdldCBlbnRlci9sZWF2ZVxuICAgIC8vIHN0eWxlLmN1cnNvciA9ICdtb3ZlJzsgLy8gIFRPRE86IGNhbid0IHNldCB3aXRoIHBvaW50ZXJFdmVudHM9bm9uZSAhIChkb25lIGluIENTUyBhcyB3ZWxsKVxuICAgIHN0eWxlLndpZHRoID0gdGhpcy5kcmFnT2Zmc2V0LndpZHRoICsgJ3B4JztcbiAgICBzdHlsZS5oZWlnaHQgPSB0aGlzLmRyYWdPZmZzZXQuaGVpZ2h0ICsgJ3B4JztcbiAgICBzdHlsZS53aWxsQ2hhbmdlID0gJ2xlZnQsIHRvcCc7XG4gICAgc3R5bGUucG9zaXRpb24gPSAnZml4ZWQnOyAvLyBsZXQgdXMgZHJhZyBiZXR3ZWVuIGdyaWRzIGJ5IG5vdCBjbGlwcGluZyBhcyBwYXJlbnQgLmdyaWQtc3RhY2sgaXMgcG9zaXRpb246ICdyZWxhdGl2ZSdcbiAgICB0aGlzLl9kcmFnRm9sbG93KGUpOyAvLyBub3cgcG9zaXRpb24gaXRcbiAgICBzdHlsZS50cmFuc2l0aW9uID0gJ25vbmUnOyAvLyBzaG93IHVwIGluc3RhbnRseVxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaGVscGVyKSB7XG4gICAgICAgIHN0eWxlLnRyYW5zaXRpb24gPSBudWxsOyAvLyByZWNvdmVyIGFuaW1hdGlvblxuICAgICAgfVxuICAgIH0sIDApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCByZXN0b3JlIGJhY2sgdGhlIG9yaWdpbmFsIHN0eWxlIGJlZm9yZSBkcmFnZ2luZyAqL1xuICBwcm90ZWN0ZWQgX3JlbW92ZUhlbHBlclN0eWxlKCk6IERERHJhZ2dhYmxlIHtcbiAgICB0aGlzLmhlbHBlci5jbGFzc0xpc3QucmVtb3ZlKCd1aS1kcmFnZ2FibGUtZHJhZ2dpbmcnKTtcbiAgICBsZXQgbm9kZSA9ICh0aGlzLmhlbHBlciBhcyBHcmlkSXRlbUhUTUxFbGVtZW50KT8uZ3JpZHN0YWNrTm9kZTtcbiAgICAvLyBkb24ndCBib3RoZXIgcmVzdG9yaW5nIHN0eWxlcyBpZiB3ZSdyZSBnb25uYSByZW1vdmUgYW55d2F5Li4uXG4gICAgaWYgKCFub2RlPy5faXNBYm91dFRvUmVtb3ZlICYmIHRoaXMuZHJhZ0VsZW1lbnRPcmlnaW5TdHlsZSkge1xuICAgICAgbGV0IGhlbHBlciA9IHRoaXMuaGVscGVyO1xuICAgICAgLy8gZG9uJ3QgYW5pbWF0ZSwgb3RoZXJ3aXNlIHdlIGFuaW1hdGUgb2Zmc2V0ZWQgd2hlbiBzd2l0Y2hpbmcgYmFjayB0byAnYWJzb2x1dGUnIGZyb20gJ2ZpeGVkJy5cbiAgICAgIC8vIFRPRE86IHRoaXMgYWxzbyByZW1vdmVzIHJlc2l6aW5nIGFuaW1hdGlvbiB3aGljaCBkb2Vzbid0IGhhdmUgdGhpcyBpc3N1ZSwgYnV0IG90aGVycy5cbiAgICAgIC8vIElkZWFsbHkgYm90aCB3b3VsZCBhbmltYXRlICgnbW92ZScgd291bGQgaW1tZWRpYXRlbHkgcmVzdG9yZSAnYWJzb2x1dGUnIGFuZCBhZGp1c3QgY29vcmRpbmF0ZSB0byBtYXRjaCxcbiAgICAgIC8vIHRoZW4gdHJpZ2dlciBhIGRlbGF5IChyZXBhaW50KSB0byByZXN0b3JlIHRvIGZpbmFsIGRlc3Qgd2l0aCBhbmltYXRlKSBidXQgdGhlbiB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSAncmVzaXplc3RvcCdcbiAgICAgIC8vIGlzIGNhbGxlZCBBRlRFUiAndHJhbnNpdGlvbmVuZCcgZXZlbnQgaXMgcmVjZWl2ZWQgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ3JpZHN0YWNrL2dyaWRzdGFjay5qcy9pc3N1ZXMvMjAzMylcbiAgICAgIGxldCB0cmFuc2l0aW9uID0gdGhpcy5kcmFnRWxlbWVudE9yaWdpblN0eWxlWyd0cmFuc2l0aW9uJ10gfHwgbnVsbDtcbiAgICAgIGhlbHBlci5zdHlsZS50cmFuc2l0aW9uID0gdGhpcy5kcmFnRWxlbWVudE9yaWdpblN0eWxlWyd0cmFuc2l0aW9uJ10gPSAnbm9uZSc7IC8vIGNhbid0IGJlIE5VTEwgIzE5NzNcbiAgICAgIERERHJhZ2dhYmxlLm9yaWdpblN0eWxlUHJvcC5mb3JFYWNoKHByb3AgPT4gaGVscGVyLnN0eWxlW3Byb3BdID0gdGhpcy5kcmFnRWxlbWVudE9yaWdpblN0eWxlW3Byb3BdIHx8IG51bGwpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiBoZWxwZXIuc3R5bGUudHJhbnNpdGlvbiA9IHRyYW5zaXRpb24sIDUwKTsgLy8gcmVjb3ZlciBhbmltYXRpb24gZnJvbSBzYXZlZCB2YXJzIGFmdGVyIGEgcGF1c2UgKDAgaXNuJ3QgZW5vdWdoICMxOTczKVxuICAgIH1cbiAgICBkZWxldGUgdGhpcy5kcmFnRWxlbWVudE9yaWdpblN0eWxlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCB1cGRhdGVzIHRoZSB0b3AvbGVmdCBwb3NpdGlvbiB0byBmb2xsb3cgdGhlIG1vdXNlICovXG4gIHByb3RlY3RlZCBfZHJhZ0ZvbGxvdyhlOiBEcmFnRXZlbnQpOiB2b2lkIHtcbiAgICBsZXQgY29udGFpbm1lbnRSZWN0ID0geyBsZWZ0OiAwLCB0b3A6IDAgfTtcbiAgICAvLyBpZiAodGhpcy5oZWxwZXIuc3R5bGUucG9zaXRpb24gPT09ICdhYnNvbHV0ZScpIHsgLy8gd2UgdXNlICdmaXhlZCdcbiAgICAvLyAgIGNvbnN0IHsgbGVmdCwgdG9wIH0gPSB0aGlzLmhlbHBlckNvbnRhaW5tZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIC8vICAgY29udGFpbm1lbnRSZWN0ID0geyBsZWZ0LCB0b3AgfTtcbiAgICAvLyB9XG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLmhlbHBlci5zdHlsZTtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmRyYWdPZmZzZXQ7XG4gICAgc3R5bGUubGVmdCA9IGUuY2xpZW50WCArIG9mZnNldC5vZmZzZXRMZWZ0IC0gY29udGFpbm1lbnRSZWN0LmxlZnQgKyAncHgnO1xuICAgIHN0eWxlLnRvcCA9IGUuY2xpZW50WSArIG9mZnNldC5vZmZzZXRUb3AgLSBjb250YWlubWVudFJlY3QudG9wICsgJ3B4JztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF9zZXR1cEhlbHBlckNvbnRhaW5tZW50U3R5bGUoKTogREREcmFnZ2FibGUge1xuICAgIHRoaXMuaGVscGVyQ29udGFpbm1lbnQgPSB0aGlzLmhlbHBlci5wYXJlbnRFbGVtZW50O1xuICAgIGlmICh0aGlzLmhlbHBlci5zdHlsZS5wb3NpdGlvbiAhPT0gJ2ZpeGVkJykge1xuICAgICAgdGhpcy5wYXJlbnRPcmlnaW5TdHlsZVBvc2l0aW9uID0gdGhpcy5oZWxwZXJDb250YWlubWVudC5zdHlsZS5wb3NpdGlvbjtcbiAgICAgIGlmICh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmhlbHBlckNvbnRhaW5tZW50KS5wb3NpdGlvbi5tYXRjaCgvc3RhdGljLykpIHtcbiAgICAgICAgdGhpcy5oZWxwZXJDb250YWlubWVudC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgX2dldERyYWdPZmZzZXQoZXZlbnQ6IERyYWdFdmVudCwgZWw6IEhUTUxFbGVtZW50LCBwYXJlbnQ6IEhUTUxFbGVtZW50KTogRHJhZ09mZnNldCB7XG5cbiAgICAvLyBpbiBjYXNlIGFuY2VzdG9yIGhhcyB0cmFuc2Zvcm0vcGVyc3BlY3RpdmUgY3NzIHByb3BlcnRpZXMgdGhhdCBjaGFuZ2UgdGhlIHZpZXdwb2ludFxuICAgIGxldCB4Zm9ybU9mZnNldFggPSAwO1xuICAgIGxldCB4Zm9ybU9mZnNldFkgPSAwO1xuICAgIGlmIChwYXJlbnQpIHtcbiAgICAgIGNvbnN0IHRlc3RFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgVXRpbHMuYWRkRWxTdHlsZXModGVzdEVsLCB7XG4gICAgICAgIG9wYWNpdHk6ICcwJyxcbiAgICAgICAgcG9zaXRpb246ICdmaXhlZCcsXG4gICAgICAgIHRvcDogMCArICdweCcsXG4gICAgICAgIGxlZnQ6IDAgKyAncHgnLFxuICAgICAgICB3aWR0aDogJzFweCcsXG4gICAgICAgIGhlaWdodDogJzFweCcsXG4gICAgICAgIHpJbmRleDogJy05OTk5OTknLFxuICAgICAgfSk7XG4gICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQodGVzdEVsKTtcbiAgICAgIGNvbnN0IHRlc3RFbFBvc2l0aW9uID0gdGVzdEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHRlc3RFbCk7XG4gICAgICB4Zm9ybU9mZnNldFggPSB0ZXN0RWxQb3NpdGlvbi5sZWZ0O1xuICAgICAgeGZvcm1PZmZzZXRZID0gdGVzdEVsUG9zaXRpb24udG9wO1xuICAgICAgLy8gVE9ETzogc2NhbGUgP1xuICAgIH1cblxuICAgIGNvbnN0IHRhcmdldE9mZnNldCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiB7XG4gICAgICBsZWZ0OiB0YXJnZXRPZmZzZXQubGVmdCxcbiAgICAgIHRvcDogdGFyZ2V0T2Zmc2V0LnRvcCxcbiAgICAgIG9mZnNldExlZnQ6IC0gZXZlbnQuY2xpZW50WCArIHRhcmdldE9mZnNldC5sZWZ0IC0geGZvcm1PZmZzZXRYLFxuICAgICAgb2Zmc2V0VG9wOiAtIGV2ZW50LmNsaWVudFkgKyB0YXJnZXRPZmZzZXQudG9wIC0geGZvcm1PZmZzZXRZLFxuICAgICAgd2lkdGg6IHRhcmdldE9mZnNldC53aWR0aCxcbiAgICAgIGhlaWdodDogdGFyZ2V0T2Zmc2V0LmhlaWdodFxuICAgIH07XG4gIH1cblxuICAvKiogQGludGVybmFsIFRPRE86IHNldCB0byBwdWJsaWMgYXMgY2FsbGVkIGJ5IERERHJvcHBhYmxlISAqL1xuICBwdWJsaWMgdWkoKTogRERVSURhdGEge1xuICAgIGNvbnN0IGNvbnRhaW5tZW50RWwgPSB0aGlzLmVsLnBhcmVudEVsZW1lbnQ7XG4gICAgY29uc3QgY29udGFpbm1lbnRSZWN0ID0gY29udGFpbm1lbnRFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmhlbHBlci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICByZXR1cm4ge1xuICAgICAgcG9zaXRpb246IHsgLy9DdXJyZW50IENTUyBwb3NpdGlvbiBvZiB0aGUgaGVscGVyIGFzIHsgdG9wLCBsZWZ0IH0gb2JqZWN0XG4gICAgICAgIHRvcDogb2Zmc2V0LnRvcCAtIGNvbnRhaW5tZW50UmVjdC50b3AsXG4gICAgICAgIGxlZnQ6IG9mZnNldC5sZWZ0IC0gY29udGFpbm1lbnRSZWN0LmxlZnRcbiAgICAgIH1cbiAgICAgIC8qIG5vdCB1c2VkIGJ5IEdyaWRTdGFjayBmb3Igbm93Li4uXG4gICAgICBoZWxwZXI6IFt0aGlzLmhlbHBlcl0sIC8vVGhlIG9iamVjdCBhcnIgcmVwcmVzZW50aW5nIHRoZSBoZWxwZXIgdGhhdCdzIGJlaW5nIGRyYWdnZWQuXG4gICAgICBvZmZzZXQ6IHsgdG9wOiBvZmZzZXQudG9wLCBsZWZ0OiBvZmZzZXQubGVmdCB9IC8vIEN1cnJlbnQgb2Zmc2V0IHBvc2l0aW9uIG9mIHRoZSBoZWxwZXIgYXMgeyB0b3AsIGxlZnQgfSBvYmplY3QuXG4gICAgICAqL1xuICAgIH07XG4gIH1cbn1cbiIsIi8qKlxuICogZGQtZHJvcHBhYmxlLnRzIDguMi4yXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjEtMjAyMiBBbGFpbiBEdW1lc255IC0gc2VlIEdyaWRTdGFjayByb290IGxpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgeyBERERyYWdnYWJsZSB9IGZyb20gJy4vZGQtZHJhZ2dhYmxlJztcbmltcG9ydCB7IERETWFuYWdlciB9IGZyb20gJy4vZGQtbWFuYWdlcic7XG5pbXBvcnQgeyBEREJhc2VJbXBsZW1lbnQsIEhUTUxFbGVtZW50RXh0ZW5kT3B0IH0gZnJvbSAnLi9kZC1iYXNlLWltcGwnO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IERERWxlbWVudEhvc3QgfSBmcm9tICcuL2RkLWVsZW1lbnQnO1xuaW1wb3J0IHsgaXNUb3VjaCwgcG9pbnRlcmVudGVyLCBwb2ludGVybGVhdmUgfSBmcm9tICcuL2RkLXRvdWNoJztcbmltcG9ydCB7IEREVUlEYXRhIH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgREREcm9wcGFibGVPcHQge1xuICBhY2NlcHQ/OiBzdHJpbmcgfCAoKGVsOiBIVE1MRWxlbWVudCkgPT4gYm9vbGVhbik7XG4gIGRyb3A/OiAoZXZlbnQ6IERyYWdFdmVudCwgdWk6IEREVUlEYXRhKSA9PiB2b2lkO1xuICBvdmVyPzogKGV2ZW50OiBEcmFnRXZlbnQsIHVpOiBERFVJRGF0YSkgPT4gdm9pZDtcbiAgb3V0PzogKGV2ZW50OiBEcmFnRXZlbnQsIHVpOiBERFVJRGF0YSkgPT4gdm9pZDtcbn1cblxuLy8gbGV0IGNvdW50ID0gMDsgLy8gVEVTVFxuXG5leHBvcnQgY2xhc3MgREREcm9wcGFibGUgZXh0ZW5kcyBEREJhc2VJbXBsZW1lbnQgaW1wbGVtZW50cyBIVE1MRWxlbWVudEV4dGVuZE9wdDxERERyb3BwYWJsZU9wdD4ge1xuXG4gIHB1YmxpYyBhY2NlcHQ6IChlbDogSFRNTEVsZW1lbnQpID0+IGJvb2xlYW47XG4gIHB1YmxpYyBlbDogSFRNTEVsZW1lbnQ7XG4gIHB1YmxpYyBvcHRpb246IERERHJvcHBhYmxlT3B0O1xuXG4gIGNvbnN0cnVjdG9yKGVsOiBIVE1MRWxlbWVudCwgb3B0czogREREcm9wcGFibGVPcHQgPSB7fSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5lbCA9IGVsO1xuICAgIHRoaXMub3B0aW9uID0gb3B0cztcbiAgICAvLyBjcmVhdGUgdmFyIGV2ZW50IGJpbmRpbmcgc28gd2UgY2FuIGVhc2lseSByZW1vdmUgYW5kIHN0aWxsIGxvb2sgbGlrZSBUUyBtZXRob2RzICh1bmxpa2UgYW5vbnltb3VzIGZ1bmN0aW9ucylcbiAgICB0aGlzLl9tb3VzZUVudGVyID0gdGhpcy5fbW91c2VFbnRlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX21vdXNlTGVhdmUgPSB0aGlzLl9tb3VzZUxlYXZlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5lbmFibGUoKTtcbiAgICB0aGlzLl9zZXR1cEFjY2VwdCgpO1xuICB9XG5cbiAgcHVibGljIG9uKGV2ZW50OiAnZHJvcCcgfCAnZHJvcG92ZXInIHwgJ2Ryb3BvdXQnLCBjYWxsYmFjazogKGV2ZW50OiBEcmFnRXZlbnQpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBzdXBlci5vbihldmVudCwgY2FsbGJhY2spO1xuICB9XG5cbiAgcHVibGljIG9mZihldmVudDogJ2Ryb3AnIHwgJ2Ryb3BvdmVyJyB8ICdkcm9wb3V0Jyk6IHZvaWQge1xuICAgIHN1cGVyLm9mZihldmVudCk7XG4gIH1cblxuICBwdWJsaWMgZW5hYmxlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkID09PSBmYWxzZSkgcmV0dXJuO1xuICAgIHN1cGVyLmVuYWJsZSgpO1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0LmFkZCgndWktZHJvcHBhYmxlJyk7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKCd1aS1kcm9wcGFibGUtZGlzYWJsZWQnKTtcbiAgICB0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCB0aGlzLl9tb3VzZUVudGVyKTtcbiAgICB0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCB0aGlzLl9tb3VzZUxlYXZlKTtcbiAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyZW50ZXInLCBwb2ludGVyZW50ZXIpO1xuICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybGVhdmUnLCBwb2ludGVybGVhdmUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBkaXNhYmxlKGZvckRlc3Ryb3kgPSBmYWxzZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkID09PSB0cnVlKSByZXR1cm47XG4gICAgc3VwZXIuZGlzYWJsZSgpO1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZSgndWktZHJvcHBhYmxlJyk7XG4gICAgaWYgKCFmb3JEZXN0cm95KSB0aGlzLmVsLmNsYXNzTGlzdC5hZGQoJ3VpLWRyb3BwYWJsZS1kaXNhYmxlZCcpO1xuICAgIHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIHRoaXMuX21vdXNlRW50ZXIpO1xuICAgIHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIHRoaXMuX21vdXNlTGVhdmUpO1xuICAgIGlmIChpc1RvdWNoKSB7XG4gICAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJlbnRlcicsIHBvaW50ZXJlbnRlcik7XG4gICAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJsZWF2ZScsIHBvaW50ZXJsZWF2ZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlKHRydWUpO1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZSgndWktZHJvcHBhYmxlJyk7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKCd1aS1kcm9wcGFibGUtZGlzYWJsZWQnKTtcbiAgICBzdXBlci5kZXN0cm95KCk7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlT3B0aW9uKG9wdHM6IERERHJvcHBhYmxlT3B0KTogREREcm9wcGFibGUge1xuICAgIE9iamVjdC5rZXlzKG9wdHMpLmZvckVhY2goa2V5ID0+IHRoaXMub3B0aW9uW2tleV0gPSBvcHRzW2tleV0pO1xuICAgIHRoaXMuX3NldHVwQWNjZXB0KCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogQGludGVybmFsIGNhbGxlZCB3aGVuIHRoZSBjdXJzb3IgZW50ZXJzIG91ciBhcmVhIC0gcHJlcGFyZSBmb3IgYSBwb3NzaWJsZSBkcm9wIGFuZCB0cmFjayBsZWF2aW5nICovXG4gIHByb3RlY3RlZCBfbW91c2VFbnRlcihlOiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgLy8gY29uc29sZS5sb2coYCR7Y291bnQrK30gRW50ZXIgJHt0aGlzLmVsLmlkIHx8ICh0aGlzLmVsIGFzIEdyaWRIVE1MRWxlbWVudCkuZ3JpZHN0YWNrLm9wdHMuaWR9YCk7IC8vIFRFU1RcbiAgICBpZiAoIURETWFuYWdlci5kcmFnRWxlbWVudCkgcmV0dXJuO1xuICAgIGlmICghdGhpcy5fY2FuRHJvcChERE1hbmFnZXIuZHJhZ0VsZW1lbnQuZWwpKSByZXR1cm47XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAvLyBtYWtlIHN1cmUgd2hlbiB3ZSBlbnRlciB0aGlzLCB0aGF0IHRoZSBsYXN0IG9uZSBnZXRzIGEgbGVhdmUgRklSU1QgdG8gY29ycmVjdGx5IGNsZWFudXAgYXMgd2UgZG9uJ3QgYWx3YXlzIGRvXG4gICAgaWYgKERETWFuYWdlci5kcm9wRWxlbWVudCAmJiBERE1hbmFnZXIuZHJvcEVsZW1lbnQgIT09IHRoaXMpIHtcbiAgICAgIERETWFuYWdlci5kcm9wRWxlbWVudC5fbW91c2VMZWF2ZShlIGFzIERyYWdFdmVudCk7XG4gICAgfVxuICAgIERETWFuYWdlci5kcm9wRWxlbWVudCA9IHRoaXM7XG5cbiAgICBjb25zdCBldiA9IFV0aWxzLmluaXRFdmVudDxEcmFnRXZlbnQ+KGUsIHsgdGFyZ2V0OiB0aGlzLmVsLCB0eXBlOiAnZHJvcG92ZXInIH0pO1xuICAgIGlmICh0aGlzLm9wdGlvbi5vdmVyKSB7XG4gICAgICB0aGlzLm9wdGlvbi5vdmVyKGV2LCB0aGlzLl91aShERE1hbmFnZXIuZHJhZ0VsZW1lbnQpKVxuICAgIH1cbiAgICB0aGlzLnRyaWdnZXJFdmVudCgnZHJvcG92ZXInLCBldik7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKCd1aS1kcm9wcGFibGUtb3ZlcicpO1xuICAgIC8vIGNvbnNvbGUubG9nKCd0cmFja2luZycpOyAvLyBURVNUXG4gIH1cblxuICAvKiogQGludGVybmFsIGNhbGxlZCB3aGVuIHRoZSBpdGVtIGlzIGxlYXZpbmcgb3VyIGFyZWEsIHN0b3AgdHJhY2tpbmcgaWYgd2UgaGFkIG1vdmluZyBpdGVtICovXG4gIHByb3RlY3RlZCBfbW91c2VMZWF2ZShlOiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgLy8gY29uc29sZS5sb2coYCR7Y291bnQrK30gTGVhdmUgJHt0aGlzLmVsLmlkIHx8ICh0aGlzLmVsIGFzIEdyaWRIVE1MRWxlbWVudCkuZ3JpZHN0YWNrLm9wdHMuaWR9YCk7IC8vIFRFU1RcbiAgICBpZiAoIURETWFuYWdlci5kcmFnRWxlbWVudCB8fCBERE1hbmFnZXIuZHJvcEVsZW1lbnQgIT09IHRoaXMpIHJldHVybjtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIGNvbnN0IGV2ID0gVXRpbHMuaW5pdEV2ZW50PERyYWdFdmVudD4oZSwgeyB0YXJnZXQ6IHRoaXMuZWwsIHR5cGU6ICdkcm9wb3V0JyB9KTtcbiAgICBpZiAodGhpcy5vcHRpb24ub3V0KSB7XG4gICAgICB0aGlzLm9wdGlvbi5vdXQoZXYsIHRoaXMuX3VpKERETWFuYWdlci5kcmFnRWxlbWVudCkpXG4gICAgfVxuICAgIHRoaXMudHJpZ2dlckV2ZW50KCdkcm9wb3V0JywgZXYpO1xuXG4gICAgaWYgKERETWFuYWdlci5kcm9wRWxlbWVudCA9PT0gdGhpcykge1xuICAgICAgZGVsZXRlIERETWFuYWdlci5kcm9wRWxlbWVudDtcbiAgICAgIC8vIGNvbnNvbGUubG9nKCdub3QgdHJhY2tpbmcnKTsgLy8gVEVTVFxuXG4gICAgICAvLyBpZiB3ZSdyZSBzdGlsbCBvdmVyIGEgcGFyZW50IGRyb3BwYWJsZSwgc2VuZCBpdCBhbiBlbnRlciBhcyB3ZSBkb24ndCBnZXQgb25lIGZyb20gbGVhdmluZyBuZXN0ZWQgY2hpbGRyZW5cbiAgICAgIGxldCBwYXJlbnREcm9wOiBERERyb3BwYWJsZTtcbiAgICAgIGxldCBwYXJlbnQ6IERERWxlbWVudEhvc3QgPSB0aGlzLmVsLnBhcmVudEVsZW1lbnQ7XG4gICAgICB3aGlsZSAoIXBhcmVudERyb3AgJiYgcGFyZW50KSB7XG4gICAgICAgIHBhcmVudERyb3AgPSBwYXJlbnQuZGRFbGVtZW50Py5kZERyb3BwYWJsZTtcbiAgICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudEVsZW1lbnQ7XG4gICAgICB9XG4gICAgICBpZiAocGFyZW50RHJvcCkge1xuICAgICAgICBwYXJlbnREcm9wLl9tb3VzZUVudGVyKGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKiBpdGVtIGlzIGJlaW5nIGRyb3BwZWQgb24gdXMgLSBjYWxsZWQgYnkgdGhlIGRyYWcgbW91c2V1cCBoYW5kbGVyIC0gdGhpcyBjYWxscyB0aGUgY2xpZW50IGRyb3AgZXZlbnQgKi9cbiAgcHVibGljIGRyb3AoZTogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBldiA9IFV0aWxzLmluaXRFdmVudDxEcmFnRXZlbnQ+KGUsIHsgdGFyZ2V0OiB0aGlzLmVsLCB0eXBlOiAnZHJvcCcgfSk7XG4gICAgaWYgKHRoaXMub3B0aW9uLmRyb3ApIHtcbiAgICAgIHRoaXMub3B0aW9uLmRyb3AoZXYsIHRoaXMuX3VpKERETWFuYWdlci5kcmFnRWxlbWVudCkpXG4gICAgfVxuICAgIHRoaXMudHJpZ2dlckV2ZW50KCdkcm9wJywgZXYpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCB0cnVlIGlmIGVsZW1lbnQgbWF0Y2hlcyB0aGUgc3RyaW5nL21ldGhvZCBhY2NlcHQgb3B0aW9uICovXG4gIHByb3RlY3RlZCBfY2FuRHJvcChlbDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZWwgJiYgKCF0aGlzLmFjY2VwdCB8fCB0aGlzLmFjY2VwdChlbCkpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgX3NldHVwQWNjZXB0KCk6IERERHJvcHBhYmxlIHtcbiAgICBpZiAoIXRoaXMub3B0aW9uLmFjY2VwdCkgcmV0dXJuIHRoaXM7XG4gICAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbi5hY2NlcHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLmFjY2VwdCA9IChlbDogSFRNTEVsZW1lbnQpID0+IGVsLm1hdGNoZXModGhpcy5vcHRpb24uYWNjZXB0IGFzIHN0cmluZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWNjZXB0ID0gdGhpcy5vcHRpb24uYWNjZXB0O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIF91aShkcmFnOiBERERyYWdnYWJsZSk6IEREVUlEYXRhIHtcbiAgICByZXR1cm4ge1xuICAgICAgZHJhZ2dhYmxlOiBkcmFnLmVsLFxuICAgICAgLi4uZHJhZy51aSgpXG4gICAgfTtcbiAgfVxufVxuXG4iLCIvKipcbiAqIGRkLWVsZW1lbnRzLnRzIDguMi4yXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjEgQWxhaW4gRHVtZXNueSAtIHNlZSBHcmlkU3RhY2sgcm9vdCBsaWNlbnNlXG4gKi9cblxuaW1wb3J0IHsgRERSZXNpemFibGUsIEREUmVzaXphYmxlT3B0IH0gZnJvbSAnLi9kZC1yZXNpemFibGUnO1xuaW1wb3J0IHsgR3JpZEl0ZW1IVE1MRWxlbWVudCB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgREREcmFnZ2FibGUsIERERHJhZ2dhYmxlT3B0IH0gZnJvbSAnLi9kZC1kcmFnZ2FibGUnO1xuaW1wb3J0IHsgREREcm9wcGFibGUsIERERHJvcHBhYmxlT3B0IH0gZnJvbSAnLi9kZC1kcm9wcGFibGUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIERERWxlbWVudEhvc3QgZXh0ZW5kcyBHcmlkSXRlbUhUTUxFbGVtZW50IHtcbiAgZGRFbGVtZW50PzogRERFbGVtZW50O1xufVxuXG5leHBvcnQgY2xhc3MgRERFbGVtZW50IHtcblxuICBzdGF0aWMgaW5pdChlbDogRERFbGVtZW50SG9zdCk6IERERWxlbWVudCB7XG4gICAgaWYgKCFlbC5kZEVsZW1lbnQpIHsgZWwuZGRFbGVtZW50ID0gbmV3IERERWxlbWVudChlbCk7IH1cbiAgICByZXR1cm4gZWwuZGRFbGVtZW50O1xuICB9XG5cbiAgcHVibGljIGVsOiBEREVsZW1lbnRIb3N0O1xuICBwdWJsaWMgZGREcmFnZ2FibGU/OiBERERyYWdnYWJsZTtcbiAgcHVibGljIGRkRHJvcHBhYmxlPzogREREcm9wcGFibGU7XG4gIHB1YmxpYyBkZFJlc2l6YWJsZT86IEREUmVzaXphYmxlO1xuXG4gIGNvbnN0cnVjdG9yKGVsOiBEREVsZW1lbnRIb3N0KSB7XG4gICAgdGhpcy5lbCA9IGVsO1xuICB9XG5cbiAgcHVibGljIG9uKGV2ZW50TmFtZTogc3RyaW5nLCBjYWxsYmFjazogKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB2b2lkKTogRERFbGVtZW50IHtcbiAgICBpZiAodGhpcy5kZERyYWdnYWJsZSAmJiBbJ2RyYWcnLCAnZHJhZ3N0YXJ0JywgJ2RyYWdzdG9wJ10uaW5kZXhPZihldmVudE5hbWUpID4gLTEpIHtcbiAgICAgIHRoaXMuZGREcmFnZ2FibGUub24oZXZlbnROYW1lIGFzICdkcmFnJyB8ICdkcmFnc3RhcnQnIHwgJ2RyYWdzdG9wJywgY2FsbGJhY2spO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kZERyb3BwYWJsZSAmJiBbJ2Ryb3AnLCAnZHJvcG92ZXInLCAnZHJvcG91dCddLmluZGV4T2YoZXZlbnROYW1lKSA+IC0xKSB7XG4gICAgICB0aGlzLmRkRHJvcHBhYmxlLm9uKGV2ZW50TmFtZSBhcyAnZHJvcCcgfCAnZHJvcG92ZXInIHwgJ2Ryb3BvdXQnLCBjYWxsYmFjayk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmRkUmVzaXphYmxlICYmIFsncmVzaXplc3RhcnQnLCAncmVzaXplJywgJ3Jlc2l6ZXN0b3AnXS5pbmRleE9mKGV2ZW50TmFtZSkgPiAtMSkge1xuICAgICAgdGhpcy5kZFJlc2l6YWJsZS5vbihldmVudE5hbWUgYXMgJ3Jlc2l6ZXN0YXJ0JyB8ICdyZXNpemUnIHwgJ3Jlc2l6ZXN0b3AnLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIG9mZihldmVudE5hbWU6IHN0cmluZyk6IERERWxlbWVudCB7XG4gICAgaWYgKHRoaXMuZGREcmFnZ2FibGUgJiYgWydkcmFnJywgJ2RyYWdzdGFydCcsICdkcmFnc3RvcCddLmluZGV4T2YoZXZlbnROYW1lKSA+IC0xKSB7XG4gICAgICB0aGlzLmRkRHJhZ2dhYmxlLm9mZihldmVudE5hbWUgYXMgJ2RyYWcnIHwgJ2RyYWdzdGFydCcgfCAnZHJhZ3N0b3AnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZGREcm9wcGFibGUgJiYgWydkcm9wJywgJ2Ryb3BvdmVyJywgJ2Ryb3BvdXQnXS5pbmRleE9mKGV2ZW50TmFtZSkgPiAtMSkge1xuICAgICAgdGhpcy5kZERyb3BwYWJsZS5vZmYoZXZlbnROYW1lIGFzICdkcm9wJyB8ICdkcm9wb3ZlcicgfCAnZHJvcG91dCcpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kZFJlc2l6YWJsZSAmJiBbJ3Jlc2l6ZXN0YXJ0JywgJ3Jlc2l6ZScsICdyZXNpemVzdG9wJ10uaW5kZXhPZihldmVudE5hbWUpID4gLTEpIHtcbiAgICAgIHRoaXMuZGRSZXNpemFibGUub2ZmKGV2ZW50TmFtZSBhcyAncmVzaXplc3RhcnQnIHwgJ3Jlc2l6ZScgfCAncmVzaXplc3RvcCcpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyBzZXR1cERyYWdnYWJsZShvcHRzOiBERERyYWdnYWJsZU9wdCk6IERERWxlbWVudCB7XG4gICAgaWYgKCF0aGlzLmRkRHJhZ2dhYmxlKSB7XG4gICAgICB0aGlzLmRkRHJhZ2dhYmxlID0gbmV3IERERHJhZ2dhYmxlKHRoaXMuZWwsIG9wdHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRkRHJhZ2dhYmxlLnVwZGF0ZU9wdGlvbihvcHRzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgY2xlYW5EcmFnZ2FibGUoKTogRERFbGVtZW50IHtcbiAgICBpZiAodGhpcy5kZERyYWdnYWJsZSkge1xuICAgICAgdGhpcy5kZERyYWdnYWJsZS5kZXN0cm95KCk7XG4gICAgICBkZWxldGUgdGhpcy5kZERyYWdnYWJsZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgc2V0dXBSZXNpemFibGUob3B0czogRERSZXNpemFibGVPcHQpOiBEREVsZW1lbnQge1xuICAgIGlmICghdGhpcy5kZFJlc2l6YWJsZSkge1xuICAgICAgdGhpcy5kZFJlc2l6YWJsZSA9IG5ldyBERFJlc2l6YWJsZSh0aGlzLmVsLCBvcHRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZFJlc2l6YWJsZS51cGRhdGVPcHRpb24ob3B0cyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGNsZWFuUmVzaXphYmxlKCk6IERERWxlbWVudCB7XG4gICAgaWYgKHRoaXMuZGRSZXNpemFibGUpIHtcbiAgICAgIHRoaXMuZGRSZXNpemFibGUuZGVzdHJveSgpO1xuICAgICAgZGVsZXRlIHRoaXMuZGRSZXNpemFibGU7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIHNldHVwRHJvcHBhYmxlKG9wdHM6IERERHJvcHBhYmxlT3B0KTogRERFbGVtZW50IHtcbiAgICBpZiAoIXRoaXMuZGREcm9wcGFibGUpIHtcbiAgICAgIHRoaXMuZGREcm9wcGFibGUgPSBuZXcgREREcm9wcGFibGUodGhpcy5lbCwgb3B0cyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGREcm9wcGFibGUudXBkYXRlT3B0aW9uKG9wdHMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyBjbGVhbkRyb3BwYWJsZSgpOiBEREVsZW1lbnQge1xuICAgIGlmICh0aGlzLmRkRHJvcHBhYmxlKSB7XG4gICAgICB0aGlzLmRkRHJvcHBhYmxlLmRlc3Ryb3koKTtcbiAgICAgIGRlbGV0ZSB0aGlzLmRkRHJvcHBhYmxlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuIiwiLyoqXHJcbiAqIGRkLWdyaWRzdGFjay50cyA4LjIuMlxyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjEgQWxhaW4gRHVtZXNueSAtIHNlZSBHcmlkU3RhY2sgcm9vdCBsaWNlbnNlXHJcbiAqL1xyXG5cclxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzICovXHJcbmltcG9ydCB7IEdyaWRJdGVtSFRNTEVsZW1lbnQsIEdyaWRTdGFja0VsZW1lbnQsIERERHJhZ0luT3B0IH0gZnJvbSAnLi90eXBlcyc7XHJcbmltcG9ydCB7IFV0aWxzIH0gZnJvbSAnLi91dGlscyc7XHJcbmltcG9ydCB7IERETWFuYWdlciB9IGZyb20gJy4vZGQtbWFuYWdlcic7XHJcbmltcG9ydCB7IERERWxlbWVudCwgRERFbGVtZW50SG9zdCB9IGZyb20gJy4vZGQtZWxlbWVudCc7XHJcblxyXG4vKiogRHJhZyZEcm9wIGRyb3Agb3B0aW9ucyAqL1xyXG5leHBvcnQgdHlwZSBERERyb3BPcHQgPSB7XHJcbiAgLyoqIGZ1bmN0aW9uIG9yIGNsYXNzIHR5cGUgdGhhdCB0aGlzIGdyaWQgd2lsbCBhY2NlcHQgYXMgZHJvcHBlZCBpdGVtcyAoc2VlIEdyaWRTdGFja09wdGlvbnMuYWNjZXB0V2lkZ2V0cykgKi9cclxuICBhY2NlcHQ/OiAoZWw6IEdyaWRJdGVtSFRNTEVsZW1lbnQpID0+IGJvb2xlYW47XHJcbn1cclxuXHJcbi8qKiBkcmFnJmRyb3Agb3B0aW9ucyBjdXJyZW50bHkgY2FsbGVkIGZyb20gdGhlIG1haW4gY29kZSwgYnV0IG90aGVycyBjYW4gYmUgcGFzc2VkIGluIGdyaWQgb3B0aW9ucyAqL1xyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxyXG5leHBvcnQgdHlwZSBERE9wdHMgPSAnZW5hYmxlJyB8ICdkaXNhYmxlJyB8ICdkZXN0cm95JyB8ICdvcHRpb24nIHwgc3RyaW5nIHwgYW55O1xyXG5leHBvcnQgdHlwZSBEREtleSA9ICdtaW5XaWR0aCcgfCAnbWluSGVpZ2h0JyB8ICdtYXhXaWR0aCcgfCAnbWF4SGVpZ2h0JztcclxuZXhwb3J0IHR5cGUgRERWYWx1ZSA9IG51bWJlciB8IHN0cmluZztcclxuXHJcbi8qKiBkcmFnJmRyb3AgZXZlbnRzIGNhbGxiYWNrcyAqL1xyXG5leHBvcnQgdHlwZSBERENhbGxiYWNrID0gKGV2ZW50OiBFdmVudCwgYXJnMjogR3JpZEl0ZW1IVE1MRWxlbWVudCwgaGVscGVyPzogR3JpZEl0ZW1IVE1MRWxlbWVudCkgPT4gdm9pZDtcclxuXHJcbi8vIGxldCBjb3VudCA9IDA7IC8vIFRFU1RcclxuXHJcbi8qKlxyXG4gKiBIVE1MIE5hdGl2ZSBNb3VzZSBhbmQgVG91Y2ggRXZlbnRzIERyYWcgYW5kIERyb3AgZnVuY3Rpb25hbGl0eS5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBEREdyaWRTdGFjayB7XHJcblxyXG4gIHB1YmxpYyByZXNpemFibGUoZWw6IEdyaWRJdGVtSFRNTEVsZW1lbnQsIG9wdHM6IERET3B0cywga2V5PzogRERLZXksIHZhbHVlPzogRERWYWx1ZSk6IERER3JpZFN0YWNrIHtcclxuICAgIHRoaXMuX2dldERERWxlbWVudHMoZWwpLmZvckVhY2goZEVsID0+IHtcclxuICAgICAgaWYgKG9wdHMgPT09ICdkaXNhYmxlJyB8fCBvcHRzID09PSAnZW5hYmxlJykge1xyXG4gICAgICAgIGRFbC5kZFJlc2l6YWJsZSAmJiBkRWwuZGRSZXNpemFibGVbb3B0c10oKTsgLy8gY2FuJ3QgY3JlYXRlIEREIGFzIGl0IHJlcXVpcmVzIG9wdGlvbnMgZm9yIHNldHVwUmVzaXphYmxlKClcclxuICAgICAgfSBlbHNlIGlmIChvcHRzID09PSAnZGVzdHJveScpIHtcclxuICAgICAgICBkRWwuZGRSZXNpemFibGUgJiYgZEVsLmNsZWFuUmVzaXphYmxlKCk7XHJcbiAgICAgIH0gZWxzZSBpZiAob3B0cyA9PT0gJ29wdGlvbicpIHtcclxuICAgICAgICBkRWwuc2V0dXBSZXNpemFibGUoeyBba2V5XTogdmFsdWUgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgZ3JpZCA9IGRFbC5lbC5ncmlkc3RhY2tOb2RlLmdyaWQ7XHJcbiAgICAgICAgbGV0IGhhbmRsZXMgPSBkRWwuZWwuZ2V0QXR0cmlidXRlKCdncy1yZXNpemUtaGFuZGxlcycpID8gZEVsLmVsLmdldEF0dHJpYnV0ZSgnZ3MtcmVzaXplLWhhbmRsZXMnKSA6IGdyaWQub3B0cy5yZXNpemFibGUuaGFuZGxlcztcclxuICAgICAgICBsZXQgYXV0b0hpZGUgPSAhZ3JpZC5vcHRzLmFsd2F5c1Nob3dSZXNpemVIYW5kbGU7XHJcbiAgICAgICAgZEVsLnNldHVwUmVzaXphYmxlKHtcclxuICAgICAgICAgIC4uLmdyaWQub3B0cy5yZXNpemFibGUsXHJcbiAgICAgICAgICAuLi57IGhhbmRsZXMsIGF1dG9IaWRlIH0sXHJcbiAgICAgICAgICAuLi57XHJcbiAgICAgICAgICAgIHN0YXJ0OiBvcHRzLnN0YXJ0LFxyXG4gICAgICAgICAgICBzdG9wOiBvcHRzLnN0b3AsXHJcbiAgICAgICAgICAgIHJlc2l6ZTogb3B0cy5yZXNpemVcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHB1YmxpYyBkcmFnZ2FibGUoZWw6IEdyaWRJdGVtSFRNTEVsZW1lbnQsIG9wdHM6IERET3B0cywga2V5PzogRERLZXksIHZhbHVlPzogRERWYWx1ZSk6IERER3JpZFN0YWNrIHtcclxuICAgIHRoaXMuX2dldERERWxlbWVudHMoZWwpLmZvckVhY2goZEVsID0+IHtcclxuICAgICAgaWYgKG9wdHMgPT09ICdkaXNhYmxlJyB8fCBvcHRzID09PSAnZW5hYmxlJykge1xyXG4gICAgICAgIGRFbC5kZERyYWdnYWJsZSAmJiBkRWwuZGREcmFnZ2FibGVbb3B0c10oKTsgLy8gY2FuJ3QgY3JlYXRlIEREIGFzIGl0IHJlcXVpcmVzIG9wdGlvbnMgZm9yIHNldHVwRHJhZ2dhYmxlKClcclxuICAgICAgfSBlbHNlIGlmIChvcHRzID09PSAnZGVzdHJveScpIHtcclxuICAgICAgICBkRWwuZGREcmFnZ2FibGUgJiYgZEVsLmNsZWFuRHJhZ2dhYmxlKCk7XHJcbiAgICAgIH0gZWxzZSBpZiAob3B0cyA9PT0gJ29wdGlvbicpIHtcclxuICAgICAgICBkRWwuc2V0dXBEcmFnZ2FibGUoeyBba2V5XTogdmFsdWUgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgZ3JpZCA9IGRFbC5lbC5ncmlkc3RhY2tOb2RlLmdyaWQ7XHJcbiAgICAgICAgZEVsLnNldHVwRHJhZ2dhYmxlKHtcclxuICAgICAgICAgIC4uLmdyaWQub3B0cy5kcmFnZ2FibGUsXHJcbiAgICAgICAgICAuLi57XHJcbiAgICAgICAgICAgIC8vIGNvbnRhaW5tZW50OiAoZ3JpZC5wYXJlbnRHcmlkSXRlbSAmJiAhZ3JpZC5vcHRzLmRyYWdPdXQpID8gZ3JpZC5lbC5wYXJlbnRFbGVtZW50IDogKGdyaWQub3B0cy5kcmFnZ2FibGUuY29udGFpbm1lbnQgfHwgbnVsbCksXHJcbiAgICAgICAgICAgIHN0YXJ0OiBvcHRzLnN0YXJ0LFxyXG4gICAgICAgICAgICBzdG9wOiBvcHRzLnN0b3AsXHJcbiAgICAgICAgICAgIGRyYWc6IG9wdHMuZHJhZ1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGRyYWdJbihlbDogR3JpZFN0YWNrRWxlbWVudCwgb3B0czogREREcmFnSW5PcHQpOiBEREdyaWRTdGFjayB7XHJcbiAgICB0aGlzLl9nZXREREVsZW1lbnRzKGVsKS5mb3JFYWNoKGRFbCA9PiBkRWwuc2V0dXBEcmFnZ2FibGUob3B0cykpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZHJvcHBhYmxlKGVsOiBHcmlkSXRlbUhUTUxFbGVtZW50LCBvcHRzOiBERE9wdHMgfCBERERyb3BPcHQsIGtleT86IERES2V5LCB2YWx1ZT86IEREVmFsdWUpOiBEREdyaWRTdGFjayB7XHJcbiAgICBpZiAodHlwZW9mIG9wdHMuYWNjZXB0ID09PSAnZnVuY3Rpb24nICYmICFvcHRzLl9hY2NlcHQpIHtcclxuICAgICAgb3B0cy5fYWNjZXB0ID0gb3B0cy5hY2NlcHQ7XHJcbiAgICAgIG9wdHMuYWNjZXB0ID0gKGVsKSA9PiBvcHRzLl9hY2NlcHQoZWwpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fZ2V0RERFbGVtZW50cyhlbCkuZm9yRWFjaChkRWwgPT4ge1xyXG4gICAgICBpZiAob3B0cyA9PT0gJ2Rpc2FibGUnIHx8IG9wdHMgPT09ICdlbmFibGUnKSB7XHJcbiAgICAgICAgZEVsLmRkRHJvcHBhYmxlICYmIGRFbC5kZERyb3BwYWJsZVtvcHRzXSgpO1xyXG4gICAgICB9IGVsc2UgaWYgKG9wdHMgPT09ICdkZXN0cm95Jykge1xyXG4gICAgICAgIGlmIChkRWwuZGREcm9wcGFibGUpIHsgLy8gZXJyb3IgdG8gY2FsbCBkZXN0cm95IGlmIG5vdCB0aGVyZVxyXG4gICAgICAgICAgZEVsLmNsZWFuRHJvcHBhYmxlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2UgaWYgKG9wdHMgPT09ICdvcHRpb24nKSB7XHJcbiAgICAgICAgZEVsLnNldHVwRHJvcHBhYmxlKHsgW2tleV06IHZhbHVlIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGRFbC5zZXR1cERyb3BwYWJsZShvcHRzKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiB0cnVlIGlmIGVsZW1lbnQgaXMgZHJvcHBhYmxlICovXHJcbiAgcHVibGljIGlzRHJvcHBhYmxlKGVsOiBEREVsZW1lbnRIb3N0KTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gISEoZWwgJiYgZWwuZGRFbGVtZW50ICYmIGVsLmRkRWxlbWVudC5kZERyb3BwYWJsZSAmJiAhZWwuZGRFbGVtZW50LmRkRHJvcHBhYmxlLmRpc2FibGVkKTtcclxuICB9XHJcblxyXG4gIC8qKiB0cnVlIGlmIGVsZW1lbnQgaXMgZHJhZ2dhYmxlICovXHJcbiAgcHVibGljIGlzRHJhZ2dhYmxlKGVsOiBEREVsZW1lbnRIb3N0KTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gISEoZWwgJiYgZWwuZGRFbGVtZW50ICYmIGVsLmRkRWxlbWVudC5kZERyYWdnYWJsZSAmJiAhZWwuZGRFbGVtZW50LmRkRHJhZ2dhYmxlLmRpc2FibGVkKTtcclxuICB9XHJcblxyXG4gIC8qKiB0cnVlIGlmIGVsZW1lbnQgaXMgZHJhZ2dhYmxlICovXHJcbiAgcHVibGljIGlzUmVzaXphYmxlKGVsOiBEREVsZW1lbnRIb3N0KTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gISEoZWwgJiYgZWwuZGRFbGVtZW50ICYmIGVsLmRkRWxlbWVudC5kZFJlc2l6YWJsZSAmJiAhZWwuZGRFbGVtZW50LmRkUmVzaXphYmxlLmRpc2FibGVkKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbihlbDogR3JpZEl0ZW1IVE1MRWxlbWVudCwgbmFtZTogc3RyaW5nLCBjYWxsYmFjazogRERDYWxsYmFjayk6IERER3JpZFN0YWNrIHtcclxuICAgIHRoaXMuX2dldERERWxlbWVudHMoZWwpLmZvckVhY2goZEVsID0+XHJcbiAgICAgIGRFbC5vbihuYW1lLCAoZXZlbnQ6IEV2ZW50KSA9PiB7XHJcbiAgICAgICAgY2FsbGJhY2soXHJcbiAgICAgICAgICBldmVudCxcclxuICAgICAgICAgIERETWFuYWdlci5kcmFnRWxlbWVudCA/IERETWFuYWdlci5kcmFnRWxlbWVudC5lbCA6IGV2ZW50LnRhcmdldCBhcyBHcmlkSXRlbUhUTUxFbGVtZW50LFxyXG4gICAgICAgICAgRERNYW5hZ2VyLmRyYWdFbGVtZW50ID8gRERNYW5hZ2VyLmRyYWdFbGVtZW50LmhlbHBlciA6IG51bGwpXHJcbiAgICAgIH0pXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb2ZmKGVsOiBHcmlkSXRlbUhUTUxFbGVtZW50LCBuYW1lOiBzdHJpbmcpOiBEREdyaWRTdGFjayB7XHJcbiAgICB0aGlzLl9nZXREREVsZW1lbnRzKGVsKS5mb3JFYWNoKGRFbCA9PiBkRWwub2ZmKG5hbWUpKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCByZXR1cm5zIGEgbGlzdCBvZiBERCBlbGVtZW50cywgY3JlYXRpbmcgdGhlbSBvbiB0aGUgZmx5IGJ5IGRlZmF1bHQgKi9cclxuICBwcm90ZWN0ZWQgX2dldERERWxlbWVudHMoZWxzOiBHcmlkU3RhY2tFbGVtZW50LCBjcmVhdGUgPSB0cnVlKTogRERFbGVtZW50W10ge1xyXG4gICAgbGV0IGhvc3RzID0gVXRpbHMuZ2V0RWxlbWVudHMoZWxzKSBhcyBEREVsZW1lbnRIb3N0W107XHJcbiAgICBpZiAoIWhvc3RzLmxlbmd0aCkgcmV0dXJuIFtdO1xyXG4gICAgbGV0IGxpc3QgPSBob3N0cy5tYXAoZSA9PiBlLmRkRWxlbWVudCB8fCAoY3JlYXRlID8gRERFbGVtZW50LmluaXQoZSkgOiBudWxsKSk7XHJcbiAgICBpZiAoIWNyZWF0ZSkgeyBsaXN0LmZpbHRlcihkID0+IGQpOyB9IC8vIHJlbW92ZSBudWxsc1xyXG4gICAgcmV0dXJuIGxpc3Q7XHJcbiAgfVxyXG59XHJcbiIsIi8qIVxyXG4gKiBHcmlkU3RhY2sgOC4yLjJcclxuICogaHR0cHM6Ly9ncmlkc3RhY2tqcy5jb20vXHJcbiAqXHJcbiAqIENvcHlyaWdodCAoYykgMjAyMS0yMDIyIEFsYWluIER1bWVzbnlcclxuICogc2VlIHJvb3QgbGljZW5zZSBodHRwczovL2dpdGh1Yi5jb20vZ3JpZHN0YWNrL2dyaWRzdGFjay5qcy90cmVlL21hc3Rlci9MSUNFTlNFXHJcbiAqL1xyXG5pbXBvcnQgeyBHcmlkU3RhY2tFbmdpbmUgfSBmcm9tICcuL2dyaWRzdGFjay1lbmdpbmUnO1xyXG5pbXBvcnQgeyBVdGlscywgSGVpZ2h0RGF0YSwgb2Jzb2xldGUgfSBmcm9tICcuL3V0aWxzJztcclxuaW1wb3J0IHsgZ3JpZERlZmF1bHRzLCBDb2x1bW5PcHRpb25zLCBHcmlkSXRlbUhUTUxFbGVtZW50LCBHcmlkU3RhY2tFbGVtZW50LCBHcmlkU3RhY2tFdmVudEhhbmRsZXJDYWxsYmFjayxcclxuICBHcmlkU3RhY2tOb2RlLCBHcmlkU3RhY2tXaWRnZXQsIG51bWJlck9yU3RyaW5nLCBERFVJRGF0YSwgREREcmFnSW5PcHQsIEdyaWRTdGFja1Bvc2l0aW9uLCBHcmlkU3RhY2tPcHRpb25zLFxyXG4gIGRyYWdJbkRlZmF1bHRPcHRpb25zLCBHcmlkU3RhY2tFdmVudEhhbmRsZXIsIEdyaWRTdGFja05vZGVzSGFuZGxlciwgQWRkUmVtb3ZlRmNuLCBTYXZlRmNuIH0gZnJvbSAnLi90eXBlcyc7XHJcblxyXG4vKlxyXG4gKiBhbmQgaW5jbHVkZSBEJkQgYnkgZGVmYXVsdFxyXG4gKiBUT0RPOiB3aGlsZSB3ZSBjb3VsZCBnZW5lcmF0ZSBhIGdyaWRzdGFjay1zdGF0aWMuanMgYXQgc21hbGxlciBzaXplIC0gc2F2ZXMgYWJvdXQgMzFrICg0MWsgLT4gNzJrKVxyXG4gKiBJIGRvbid0IGtub3cgaG93IHRvIGdlbmVyYXRlIHRoZSBERCBvbmx5IGNvZGUgYXQgdGhlIHJlbWFpbmluZyAzMWsgdG8gZGVsYXkgbG9hZCBhcyBjb2RlIGRlcGVuZHMgb24gR3JpZHN0YWNrLnRzXHJcbiAqIGFsc28gaXQgY2F1c2VkIGxvYWRpbmcgaXNzdWVzIGluIHByb2QgLSBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2dyaWRzdGFjay9ncmlkc3RhY2suanMvaXNzdWVzLzIwMzlcclxuICovXHJcbmltcG9ydCB7IERER3JpZFN0YWNrIH0gZnJvbSAnLi9kZC1ncmlkc3RhY2snO1xyXG5pbXBvcnQgeyBpc1RvdWNoIH0gZnJvbSAnLi9kZC10b3VjaCc7XHJcbmltcG9ydCB7IERETWFuYWdlciB9IGZyb20gJy4vZGQtbWFuYWdlcic7XHJcbmltcG9ydCB7IERERWxlbWVudEhvc3QgfSBmcm9tICcuL2RkLWVsZW1lbnQnO1xyXG4vKiogZ2xvYmFsIGluc3RhbmNlICovXHJcbmNvbnN0IGRkID0gbmV3IERER3JpZFN0YWNrO1xyXG5cclxuLy8gZXhwb3J0IGFsbCBkZXBlbmRlbnQgZmlsZSBhcyB3ZWxsIHRvIG1ha2UgaXQgZWFzaWVyIGZvciB1c2VycyB0byBqdXN0IGltcG9ydCB0aGUgbWFpbiBmaWxlXHJcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMnO1xyXG5leHBvcnQgKiBmcm9tICcuL3V0aWxzJztcclxuZXhwb3J0ICogZnJvbSAnLi9ncmlkc3RhY2stZW5naW5lJztcclxuZXhwb3J0ICogZnJvbSAnLi9kZC1ncmlkc3RhY2snO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBHcmlkSFRNTEVsZW1lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XHJcbiAgZ3JpZHN0YWNrPzogR3JpZFN0YWNrOyAvLyBncmlkJ3MgcGFyZW50IERPTSBlbGVtZW50IHBvaW50cyBiYWNrIHRvIGdyaWQgY2xhc3NcclxufVxyXG4vKiogbGlzdCBvZiBwb3NzaWJsZSBldmVudHMsIG9yIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIHRoZW0gKi9cclxuZXhwb3J0IHR5cGUgR3JpZFN0YWNrRXZlbnQgPSAnYWRkZWQnIHwgJ2NoYW5nZScgfCAnZGlzYWJsZScgfCAnZHJhZycgfCAnZHJhZ3N0YXJ0JyB8ICdkcmFnc3RvcCcgfCAnZHJvcHBlZCcgfFxyXG4gICdlbmFibGUnIHwgJ3JlbW92ZWQnIHwgJ3Jlc2l6ZScgfCAncmVzaXplc3RhcnQnIHwgJ3Jlc2l6ZXN0b3AnIHwgc3RyaW5nO1xyXG5cclxuLyoqIERlZmluZXMgdGhlIGNvb3JkaW5hdGVzIG9mIGFuIG9iamVjdCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIE1vdXNlUG9zaXRpb24ge1xyXG4gIHRvcDogbnVtYmVyO1xyXG4gIGxlZnQ6IG51bWJlcjtcclxufVxyXG5cclxuLyoqIERlZmluZXMgdGhlIHBvc2l0aW9uIG9mIGEgY2VsbCBpbnNpZGUgdGhlIGdyaWQqL1xyXG5leHBvcnQgaW50ZXJmYWNlIENlbGxQb3NpdGlvbiB7XHJcbiAgeDogbnVtYmVyO1xyXG4gIHk6IG51bWJlcjtcclxufVxyXG5cclxuaW50ZXJmYWNlIEdyaWRDU1NTdHlsZVNoZWV0IGV4dGVuZHMgQ1NTU3R5bGVTaGVldCB7XHJcbiAgX21heD86IG51bWJlcjsgLy8gaW50ZXJuYWwgdHJhY2tlciBvZiB0aGUgbWF4ICMgb2Ygcm93cyB3ZSBjcmVhdGVkXHJcbn1cclxuXHJcbi8vIGV4dGVuZCB3aXRoIGludGVybmFsIGZpZWxkcyB3ZSBuZWVkIC0gVE9ETzogbW92ZSBvdGhlciBpdGVtcyBpbiBoZXJlXHJcbmludGVyZmFjZSBJbnRlcm5hbEdyaWRTdGFja09wdGlvbnMgZXh0ZW5kcyBHcmlkU3RhY2tPcHRpb25zIHtcclxuICBfYWx3YXlzU2hvd1Jlc2l6ZUhhbmRsZT86IHRydWUgfCBmYWxzZSB8ICdtb2JpbGUnOyAvLyBzbyB3ZSBjYW4gcmVzdG9yZSBmb3Igc2F2ZVxyXG59XHJcblxyXG4vKipcclxuICogTWFpbiBncmlkc3RhY2sgY2xhc3MgLSB5b3Ugd2lsbCBuZWVkIHRvIGNhbGwgYEdyaWRTdGFjay5pbml0KClgIGZpcnN0IHRvIGluaXRpYWxpemUgeW91ciBncmlkLlxyXG4gKiBOb3RlOiB5b3VyIGdyaWQgZWxlbWVudHMgTVVTVCBoYXZlIHRoZSBmb2xsb3dpbmcgY2xhc3NlcyBmb3IgdGhlIENTUyBsYXlvdXQgdG8gd29yazpcclxuICogQGV4YW1wbGVcclxuICogPGRpdiBjbGFzcz1cImdyaWQtc3RhY2tcIj5cclxuICogICA8ZGl2IGNsYXNzPVwiZ3JpZC1zdGFjay1pdGVtXCI+XHJcbiAqICAgICA8ZGl2IGNsYXNzPVwiZ3JpZC1zdGFjay1pdGVtLWNvbnRlbnRcIj5JdGVtIDE8L2Rpdj5cclxuICogICA8L2Rpdj5cclxuICogPC9kaXY+XHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgR3JpZFN0YWNrIHtcclxuXHJcbiAgLyoqXHJcbiAgICogaW5pdGlhbGl6aW5nIHRoZSBIVE1MIGVsZW1lbnQsIG9yIHNlbGVjdG9yIHN0cmluZywgaW50byBhIGdyaWQgd2lsbCByZXR1cm4gdGhlIGdyaWQuIENhbGxpbmcgaXQgYWdhaW4gd2lsbFxyXG4gICAqIHNpbXBseSByZXR1cm4gdGhlIGV4aXN0aW5nIGluc3RhbmNlIChpZ25vcmUgYW55IHBhc3NlZCBvcHRpb25zKS4gVGhlcmUgaXMgYWxzbyBhbiBpbml0QWxsKCkgdmVyc2lvbiB0aGF0IHN1cHBvcnRcclxuICAgKiBtdWx0aXBsZSBncmlkcyBpbml0aWFsaXphdGlvbiBhdCBvbmNlLiBPciB5b3UgY2FuIHVzZSBhZGRHcmlkKCkgdG8gY3JlYXRlIHRoZSBlbnRpcmUgZ3JpZCBmcm9tIEpTT04uXHJcbiAgICogQHBhcmFtIG9wdGlvbnMgZ3JpZCBvcHRpb25zIChvcHRpb25hbClcclxuICAgKiBAcGFyYW0gZWxPclN0cmluZyBlbGVtZW50IG9yIENTUyBzZWxlY3RvciAoZmlyc3Qgb25lIHVzZWQpIHRvIGNvbnZlcnQgdG8gYSBncmlkIChkZWZhdWx0IHRvICcuZ3JpZC1zdGFjaycgY2xhc3Mgc2VsZWN0b3IpXHJcbiAgICpcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqIGxldCBncmlkID0gR3JpZFN0YWNrLmluaXQoKTtcclxuICAgKlxyXG4gICAqIE5vdGU6IHRoZSBIVE1MRWxlbWVudCAob2YgdHlwZSBHcmlkSFRNTEVsZW1lbnQpIHdpbGwgc3RvcmUgYSBgZ3JpZHN0YWNrOiBHcmlkU3RhY2tgIHZhbHVlIHRoYXQgY2FuIGJlIHJldHJpZXZlIGxhdGVyXHJcbiAgICogbGV0IGdyaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZ3JpZC1zdGFjaycpLmdyaWRzdGFjaztcclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIGluaXQob3B0aW9uczogR3JpZFN0YWNrT3B0aW9ucyA9IHt9LCBlbE9yU3RyaW5nOiBHcmlkU3RhY2tFbGVtZW50ID0gJy5ncmlkLXN0YWNrJyk6IEdyaWRTdGFjayB7XHJcbiAgICBsZXQgZWwgPSBHcmlkU3RhY2suZ2V0R3JpZEVsZW1lbnQoZWxPclN0cmluZyk7XHJcbiAgICBpZiAoIWVsKSB7XHJcbiAgICAgIGlmICh0eXBlb2YgZWxPclN0cmluZyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdHcmlkU3RhY2suaW5pdEFsbCgpIG5vIGdyaWQgd2FzIGZvdW5kIHdpdGggc2VsZWN0b3IgXCInICsgZWxPclN0cmluZyArICdcIiAtIGVsZW1lbnQgbWlzc2luZyBvciB3cm9uZyBzZWxlY3RvciA/JyArXHJcbiAgICAgICAgJ1xcbk5vdGU6IFwiLmdyaWQtc3RhY2tcIiBpcyByZXF1aXJlZCBmb3IgcHJvcGVyIENTUyBzdHlsaW5nIGFuZCBkcmFnL2Ryb3AsIGFuZCBpcyB0aGUgZGVmYXVsdCBzZWxlY3Rvci4nKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKCdHcmlkU3RhY2suaW5pdCgpIG5vIGdyaWQgZWxlbWVudCB3YXMgcGFzc2VkLicpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgaWYgKCFlbC5ncmlkc3RhY2spIHtcclxuICAgICAgZWwuZ3JpZHN0YWNrID0gbmV3IEdyaWRTdGFjayhlbCwgVXRpbHMuY2xvbmVEZWVwKG9wdGlvbnMpKTtcclxuICAgIH1cclxuICAgIHJldHVybiBlbC5ncmlkc3RhY2tcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFdpbGwgaW5pdGlhbGl6ZSBhIGxpc3Qgb2YgZWxlbWVudHMgKGdpdmVuIGEgc2VsZWN0b3IpIGFuZCByZXR1cm4gYW4gYXJyYXkgb2YgZ3JpZHMuXHJcbiAgICogQHBhcmFtIG9wdGlvbnMgZ3JpZCBvcHRpb25zIChvcHRpb25hbClcclxuICAgKiBAcGFyYW0gc2VsZWN0b3IgZWxlbWVudHMgc2VsZWN0b3IgdG8gY29udmVydCB0byBncmlkcyAoZGVmYXVsdCB0byAnLmdyaWQtc3RhY2snIGNsYXNzIHNlbGVjdG9yKVxyXG4gICAqXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiBsZXQgZ3JpZHMgPSBHcmlkU3RhY2suaW5pdEFsbCgpO1xyXG4gICAqIGdyaWRzLmZvckVhY2goLi4uKVxyXG4gICAqL1xyXG4gIHB1YmxpYyBzdGF0aWMgaW5pdEFsbChvcHRpb25zOiBHcmlkU3RhY2tPcHRpb25zID0ge30sIHNlbGVjdG9yID0gJy5ncmlkLXN0YWNrJyk6IEdyaWRTdGFja1tdIHtcclxuICAgIGxldCBncmlkczogR3JpZFN0YWNrW10gPSBbXTtcclxuICAgIEdyaWRTdGFjay5nZXRHcmlkRWxlbWVudHMoc2VsZWN0b3IpLmZvckVhY2goZWwgPT4ge1xyXG4gICAgICBpZiAoIWVsLmdyaWRzdGFjaykge1xyXG4gICAgICAgIGVsLmdyaWRzdGFjayA9IG5ldyBHcmlkU3RhY2soZWwsIFV0aWxzLmNsb25lRGVlcChvcHRpb25zKSk7XHJcbiAgICAgIH1cclxuICAgICAgZ3JpZHMucHVzaChlbC5ncmlkc3RhY2spO1xyXG4gICAgfSk7XHJcbiAgICBpZiAoZ3JpZHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0dyaWRTdGFjay5pbml0QWxsKCkgbm8gZ3JpZCB3YXMgZm91bmQgd2l0aCBzZWxlY3RvciBcIicgKyBzZWxlY3RvciArICdcIiAtIGVsZW1lbnQgbWlzc2luZyBvciB3cm9uZyBzZWxlY3RvciA/JyArXHJcbiAgICAgICdcXG5Ob3RlOiBcIi5ncmlkLXN0YWNrXCIgaXMgcmVxdWlyZWQgZm9yIHByb3BlciBDU1Mgc3R5bGluZyBhbmQgZHJhZy9kcm9wLCBhbmQgaXMgdGhlIGRlZmF1bHQgc2VsZWN0b3IuJyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZ3JpZHM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBjYWxsIHRvIGNyZWF0ZSBhIGdyaWQgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucywgaW5jbHVkaW5nIGxvYWRpbmcgYW55IGNoaWxkcmVuIGZyb20gSlNPTiBzdHJ1Y3R1cmUuIFRoaXMgd2lsbCBjYWxsIEdyaWRTdGFjay5pbml0KCksIHRoZW5cclxuICAgKiBncmlkLmxvYWQoKSBvbiBhbnkgcGFzc2VkIGNoaWxkcmVuIChyZWN1cnNpdmVseSkuIEdyZWF0IGFsdGVybmF0aXZlIHRvIGNhbGxpbmcgaW5pdCgpIGlmIHlvdSB3YW50IGVudGlyZSBncmlkIHRvIGNvbWUgZnJvbVxyXG4gICAqIEpTT04gc2VyaWFsaXplZCBkYXRhLCBpbmNsdWRpbmcgb3B0aW9ucy5cclxuICAgKiBAcGFyYW0gcGFyZW50IEhUTUwgZWxlbWVudCBwYXJlbnQgdG8gdGhlIGdyaWRcclxuICAgKiBAcGFyYW0gb3B0IGdyaWRzIG9wdGlvbnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBncmlkLCBhbmQgbGlzdCBvZiBjaGlsZHJlblxyXG4gICAqL1xyXG4gIHB1YmxpYyBzdGF0aWMgYWRkR3JpZChwYXJlbnQ6IEhUTUxFbGVtZW50LCBvcHQ6IEdyaWRTdGFja09wdGlvbnMgPSB7fSk6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAoIXBhcmVudCkgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgbGV0IGVsID0gcGFyZW50IGFzIEdyaWRIVE1MRWxlbWVudDtcclxuICAgIGlmIChlbC5ncmlkc3RhY2spIHtcclxuICAgICAgLy8gYWxyZWFkeSBhIGdyaWQgLSBzZXQgb3B0aW9uIGFuZCBsb2FkIGRhdGFcclxuICAgICAgY29uc3QgZ3JpZCA9IGVsLmdyaWRzdGFjaztcclxuICAgICAgaWYgKG9wdCkgZ3JpZC5vcHRzID0gey4uLmdyaWQub3B0cywgLi4ub3B0fTtcclxuICAgICAgaWYgKG9wdC5jaGlsZHJlbiAhPT0gdW5kZWZpbmVkKSBncmlkLmxvYWQob3B0LmNoaWxkcmVuKTtcclxuICAgICAgcmV0dXJuIGdyaWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gY3JlYXRlIHRoZSBncmlkIGVsZW1lbnQsIGJ1dCBjaGVjayBpZiB0aGUgcGFzc2VkICdwYXJlbnQnIGFscmVhZHkgaGFzIGdyaWQgc3R5bGluZyBhbmQgc2hvdWxkIGJlIHVzZWQgaW5zdGVhZFxyXG4gICAgY29uc3QgcGFyZW50SXNHcmlkID0gcGFyZW50LmNsYXNzTGlzdC5jb250YWlucygnZ3JpZC1zdGFjaycpO1xyXG4gICAgaWYgKCFwYXJlbnRJc0dyaWQgfHwgR3JpZFN0YWNrLmFkZFJlbW92ZUNCKSB7XHJcbiAgICAgIGlmIChHcmlkU3RhY2suYWRkUmVtb3ZlQ0IpIHtcclxuICAgICAgICBlbCA9IEdyaWRTdGFjay5hZGRSZW1vdmVDQihwYXJlbnQsIG9wdCwgdHJ1ZSwgdHJ1ZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbGV0IGRvYyA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgnJyk7IC8vIElFIG5lZWRzIGEgcGFyYW1cclxuICAgICAgICBkb2MuYm9keS5pbm5lckhUTUwgPSBgPGRpdiBjbGFzcz1cImdyaWQtc3RhY2sgJHtvcHQuY2xhc3MgfHwgJyd9XCI+PC9kaXY+YDtcclxuICAgICAgICBlbCA9IGRvYy5ib2R5LmNoaWxkcmVuWzBdIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChlbCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBjcmVhdGUgZ3JpZCBjbGFzcyBhbmQgbG9hZCBhbnkgY2hpbGRyZW5cclxuICAgIGxldCBncmlkID0gR3JpZFN0YWNrLmluaXQob3B0LCBlbCk7XHJcbiAgICByZXR1cm4gZ3JpZDtcclxuICB9XHJcblxyXG4gIC8qKiBjYWxsIHRoaXMgbWV0aG9kIHRvIHJlZ2lzdGVyIHlvdXIgZW5naW5lIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb25lLlxyXG4gICAqIFNlZSBpbnN0ZWFkIGBHcmlkU3RhY2tPcHRpb25zLmVuZ2luZUNsYXNzYCBpZiB5b3Ugb25seSBuZWVkIHRvXHJcbiAgICogcmVwbGFjZSBqdXN0IG9uZSBpbnN0YW5jZS5cclxuICAgKi9cclxuICBzdGF0aWMgcmVnaXN0ZXJFbmdpbmUoZW5naW5lQ2xhc3M6IHR5cGVvZiBHcmlkU3RhY2tFbmdpbmUpOiB2b2lkIHtcclxuICAgIEdyaWRTdGFjay5lbmdpbmVDbGFzcyA9IGVuZ2luZUNsYXNzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogY2FsbGJhY2sgbWV0aG9kIHVzZSB3aGVuIG5ldyBpdGVtc3xncmlkcyBuZWVkcyB0byBiZSBjcmVhdGVkIG9yIGRlbGV0ZWQsIGluc3RlYWQgb2YgdGhlIGRlZmF1bHRcclxuICAgKiBpdGVtOiA8ZGl2IGNsYXNzPVwiZ3JpZC1zdGFjay1pdGVtXCI+PGRpdiBjbGFzcz1cImdyaWQtc3RhY2staXRlbS1jb250ZW50XCI+dy5jb250ZW50PC9kaXY+PC9kaXY+XHJcbiAgICogZ3JpZDogPGRpdiBjbGFzcz1cImdyaWQtc3RhY2tcIj5ncmlkIGNvbnRlbnQuLi48L2Rpdj5cclxuICAgKiBhZGQgPSB0cnVlOiB0aGUgcmV0dXJuZWQgRE9NIGVsZW1lbnQgd2lsbCB0aGVuIGJlIGNvbnZlcnRlZCB0byBhIEdyaWRJdGVtSFRNTEVsZW1lbnQgdXNpbmcgbWFrZVdpZGdldCgpfEdyaWRTdGFjazppbml0KCkuXHJcbiAgICogYWRkID0gZmFsc2U6IHRoZSBpdGVtIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIERPTSAoaWYgbm90IGFscmVhZHkgZG9uZSlcclxuICAgKiBncmlkID0gdHJ1ZXxmYWxzZSBmb3IgZ3JpZCB2cyBncmlkLWl0ZW1zXHJcbiAgICovXHJcbiAgcHVibGljIHN0YXRpYyBhZGRSZW1vdmVDQj86IEFkZFJlbW92ZUZjbjtcclxuXHJcbiAgLyoqXHJcbiAgICogY2FsbGJhY2sgZHVyaW5nIHNhdmluZyB0byBhcHBsaWNhdGlvbiBjYW4gaW5qZWN0IGV4dHJhIGRhdGEgZm9yIGVhY2ggd2lkZ2V0LCBvbiB0b3Agb2YgdGhlIGdyaWQgbGF5b3V0IHByb3BlcnRpZXNcclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIHNhdmVDQj86IFNhdmVGY247XHJcblxyXG4gIC8qKiBzY29waW5nIHNvIHVzZXJzIGNhbiBjYWxsIEdyaWRTdGFjay5VdGlscy5zb3J0KCkgZm9yIGV4YW1wbGUgKi9cclxuICBwdWJsaWMgc3RhdGljIFV0aWxzID0gVXRpbHM7XHJcblxyXG4gIC8qKiBzY29waW5nIHNvIHVzZXJzIGNhbiBjYWxsIG5ldyBHcmlkU3RhY2suRW5naW5lKDEyKSBmb3IgZXhhbXBsZSAqL1xyXG4gIHB1YmxpYyBzdGF0aWMgRW5naW5lID0gR3JpZFN0YWNrRW5naW5lO1xyXG5cclxuICAvKiogdGhlIEhUTUwgZWxlbWVudCB0aWVkIHRvIHRoaXMgZ3JpZCBhZnRlciBpdCdzIGJlZW4gaW5pdGlhbGl6ZWQgKi9cclxuICBwdWJsaWMgZWw6IEdyaWRIVE1MRWxlbWVudDtcclxuXHJcbiAgLyoqIGVuZ2luZSB1c2VkIHRvIGltcGxlbWVudCBub24gRE9NIGdyaWQgZnVuY3Rpb25hbGl0eSAqL1xyXG4gIHB1YmxpYyBlbmdpbmU6IEdyaWRTdGFja0VuZ2luZTtcclxuXHJcbiAgLyoqIGdyaWQgb3B0aW9ucyAtIHB1YmxpYyBmb3IgY2xhc3NlcyB0byBhY2Nlc3MsIGJ1dCB1c2UgbWV0aG9kcyB0byBtb2RpZnkhICovXHJcbiAgcHVibGljIG9wdHM6IEdyaWRTdGFja09wdGlvbnM7XHJcblxyXG4gIC8qKiBwb2ludCB0byBhIHBhcmVudCBncmlkIGl0ZW0gaWYgd2UncmUgbmVzdGVkIChpbnNpZGUgYSBncmlkLWl0ZW0gaW4gYmV0d2VlbiAyIEdyaWRzKSAqL1xyXG4gIHB1YmxpYyBwYXJlbnRHcmlkSXRlbT86IEdyaWRTdGFja05vZGU7XHJcblxyXG4gIHByb3RlY3RlZCBzdGF0aWMgZW5naW5lQ2xhc3M6IHR5cGVvZiBHcmlkU3RhY2tFbmdpbmU7XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgdW5pcXVlIGNsYXNzIG5hbWUgZm9yIG91ciBnZW5lcmF0ZWQgQ1NTIHN0eWxlIHNoZWV0ICovXHJcbiAgcHJvdGVjdGVkIF9zdHlsZVNoZWV0Q2xhc3M/OiBzdHJpbmc7XHJcbiAgLyoqIEBpbnRlcm5hbCB0cnVlIGlmIHdlIGdvdCBjcmVhdGVkIGJ5IGRyYWcgb3ZlciBnZXN0dXJlLCBzbyB3ZSBjYW4gcmVtb3ZlZCBvbiBkcmFnIG91dCAodGVtcG9yYXJ5KSAqL1xyXG4gIHB1YmxpYyBfaXNUZW1wPzogYm9vbGVhbjtcclxuXHJcbiAgLyoqIEBpbnRlcm5hbCBjcmVhdGUgcGxhY2Vob2xkZXIgRElWIGFzIG5lZWRlZCAqL1xyXG4gIHB1YmxpYyBnZXQgcGxhY2Vob2xkZXIoKTogSFRNTEVsZW1lbnQge1xyXG4gICAgaWYgKCF0aGlzLl9wbGFjZWhvbGRlcikge1xyXG4gICAgICBsZXQgcGxhY2Vob2xkZXJDaGlsZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOyAvLyBjaGlsZCBzbyBwYWRkaW5nIG1hdGNoIGl0ZW0tY29udGVudFxyXG4gICAgICBwbGFjZWhvbGRlckNoaWxkLmNsYXNzTmFtZSA9ICdwbGFjZWhvbGRlci1jb250ZW50JztcclxuICAgICAgaWYgKHRoaXMub3B0cy5wbGFjZWhvbGRlclRleHQpIHtcclxuICAgICAgICBwbGFjZWhvbGRlckNoaWxkLmlubmVySFRNTCA9IHRoaXMub3B0cy5wbGFjZWhvbGRlclRleHQ7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5fcGxhY2Vob2xkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgdGhpcy5fcGxhY2Vob2xkZXIuY2xhc3NMaXN0LmFkZCh0aGlzLm9wdHMucGxhY2Vob2xkZXJDbGFzcywgZ3JpZERlZmF1bHRzLml0ZW1DbGFzcywgdGhpcy5vcHRzLml0ZW1DbGFzcyk7XHJcbiAgICAgIHRoaXMucGxhY2Vob2xkZXIuYXBwZW5kQ2hpbGQocGxhY2Vob2xkZXJDaGlsZCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5fcGxhY2Vob2xkZXI7XHJcbiAgfVxyXG4gIC8qKiBAaW50ZXJuYWwgKi9cclxuICBwcm90ZWN0ZWQgX3BsYWNlaG9sZGVyOiBIVE1MRWxlbWVudDtcclxuICAvKiogQGludGVybmFsICovXHJcbiAgcHJvdGVjdGVkIF9wcmV2Q29sdW1uOiBudW1iZXI7XHJcbiAgLyoqIEBpbnRlcm5hbCBwcmV2ZW50IGNhY2hlZCBsYXlvdXRzIGZyb20gYmVpbmcgdXBkYXRlZCB3aGVuIGxvYWRpbmcgaW50byBzbWFsbCBjb2x1bW4gbGF5b3V0cyAqL1xyXG4gIHByb3RlY3RlZCBfaWdub3JlTGF5b3V0c05vZGVDaGFuZ2U6IGJvb2xlYW47XHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIHB1YmxpYyBfZ3NFdmVudEhhbmRsZXIgPSB7fTtcclxuICAvKiogQGludGVybmFsICovXHJcbiAgcHJvdGVjdGVkIF9zdHlsZXM6IEdyaWRDU1NTdHlsZVNoZWV0O1xyXG4gIC8qKiBAaW50ZXJuYWwgZmxhZyB0byBrZWVwIGNlbGxzIHNxdWFyZSBkdXJpbmcgcmVzaXplICovXHJcbiAgcHJvdGVjdGVkIF9pc0F1dG9DZWxsSGVpZ2h0OiBib29sZWFuO1xyXG4gIC8qKiBAaW50ZXJuYWwgdHJhY2sgZXZlbnQgYmluZGluZyB0byB3aW5kb3cgcmVzaXplIHNvIHdlIGNhbiByZW1vdmUgKi9cclxuICBwcm90ZWN0ZWQgX3dpbmRvd1Jlc2l6ZUJpbmQ6ICgpID0+IHZvaWQ7XHJcbiAgLyoqIEBpbnRlcm5hbCBsaW1pdCBhdXRvIGNlbGwgcmVzaXppbmcgbWV0aG9kICovXHJcbiAgcHJvdGVjdGVkIF9jZWxsSGVpZ2h0VGhyb3R0bGU6ICgpID0+IHZvaWQ7XHJcbiAgLyoqIEBpbnRlcm5hbCB0cnVlIHdoZW4gbG9hZGluZyBpdGVtcyB0byBpbnNlcnQgZmlyc3QgcmF0aGVyIHRoYW4gYXBwZW5kICovXHJcbiAgcHJvdGVjdGVkIF9pbnNlcnROb3RBcHBlbmQ6IGJvb2xlYW47XHJcbiAgLyoqIEBpbnRlcm5hbCBleHRyYSByb3cgYWRkZWQgd2hlbiBkcmFnZ2luZyBhdCB0aGUgYm90dG9tIG9mIHRoZSBncmlkICovXHJcbiAgcHJvdGVjdGVkIF9leHRyYURyYWdSb3cgPSAwO1xyXG4gIC8qKiBAaW50ZXJuYWwgdHJ1ZSBpZiBuZXN0ZWQgZ3JpZCBzaG91bGQgZ2V0IGNvbHVtbiBjb3VudCBmcm9tIG91ciB3aWR0aCAqL1xyXG4gIHByb3RlY3RlZCBfYXV0b0NvbHVtbj86IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbnN0cnVjdCBhIGdyaWQgaXRlbSBmcm9tIHRoZSBnaXZlbiBlbGVtZW50IGFuZCBvcHRpb25zXHJcbiAgICogQHBhcmFtIGVsXHJcbiAgICogQHBhcmFtIG9wdHNcclxuICAgKi9cclxuICBwdWJsaWMgY29uc3RydWN0b3IoZWw6IEdyaWRIVE1MRWxlbWVudCwgb3B0czogR3JpZFN0YWNrT3B0aW9ucyA9IHt9KSB7XHJcbiAgICB0aGlzLmVsID0gZWw7IC8vIGV4cG9zZWQgSFRNTCBlbGVtZW50IHRvIHRoZSB1c2VyXHJcbiAgICBvcHRzID0gb3B0cyB8fCB7fTsgLy8gaGFuZGxlcyBudWxsL3VuZGVmaW5lZC8wXHJcblxyXG4gICAgaWYgKCFlbC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyaWQtc3RhY2snKSkge1xyXG4gICAgICB0aGlzLmVsLmNsYXNzTGlzdC5hZGQoJ2dyaWQtc3RhY2snKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBpZiByb3cgcHJvcGVydHkgZXhpc3RzLCByZXBsYWNlIG1pblJvdyBhbmQgbWF4Um93IGluc3RlYWRcclxuICAgIGlmIChvcHRzLnJvdykge1xyXG4gICAgICBvcHRzLm1pblJvdyA9IG9wdHMubWF4Um93ID0gb3B0cy5yb3c7XHJcbiAgICAgIGRlbGV0ZSBvcHRzLnJvdztcclxuICAgIH1cclxuICAgIGxldCByb3dBdHRyID0gVXRpbHMudG9OdW1iZXIoZWwuZ2V0QXR0cmlidXRlKCdncy1yb3cnKSk7XHJcblxyXG4gICAgLy8gZmxhZyBvbmx5IHZhbGlkIGluIHN1Yi1ncmlkcyAoaGFuZGxlZCBieSBwYXJlbnQsIG5vdCBoZXJlKVxyXG4gICAgaWYgKG9wdHMuY29sdW1uID09PSAnYXV0bycpIHtcclxuICAgICAgZGVsZXRlIG9wdHMuY29sdW1uO1xyXG4gICAgfVxyXG4gICAgLy8gc2F2ZSBvcmlnaW5hbCBzZXR0aW5nIHNvIHdlIGNhbiByZXN0b3JlIG9uIHNhdmVcclxuICAgIGlmIChvcHRzLmFsd2F5c1Nob3dSZXNpemVIYW5kbGUgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAob3B0cyBhcyBJbnRlcm5hbEdyaWRTdGFja09wdGlvbnMpLl9hbHdheXNTaG93UmVzaXplSGFuZGxlID0gb3B0cy5hbHdheXNTaG93UmVzaXplSGFuZGxlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGVsZW1lbnRzIERPTSBhdHRyaWJ1dGVzIG92ZXJyaWRlIGFueSBwYXNzZWQgb3B0aW9ucyAobGlrZSBDU1Mgc3R5bGUpIC0gbWVyZ2UgdGhlIHR3byB0b2dldGhlclxyXG4gICAgbGV0IGRlZmF1bHRzOiBHcmlkU3RhY2tPcHRpb25zID0gey4uLlV0aWxzLmNsb25lRGVlcChncmlkRGVmYXVsdHMpLFxyXG4gICAgICBjb2x1bW46IFV0aWxzLnRvTnVtYmVyKGVsLmdldEF0dHJpYnV0ZSgnZ3MtY29sdW1uJykpIHx8IGdyaWREZWZhdWx0cy5jb2x1bW4sXHJcbiAgICAgIG1pblJvdzogcm93QXR0ciA/IHJvd0F0dHIgOiBVdGlscy50b051bWJlcihlbC5nZXRBdHRyaWJ1dGUoJ2dzLW1pbi1yb3cnKSkgfHwgZ3JpZERlZmF1bHRzLm1pblJvdyxcclxuICAgICAgbWF4Um93OiByb3dBdHRyID8gcm93QXR0ciA6IFV0aWxzLnRvTnVtYmVyKGVsLmdldEF0dHJpYnV0ZSgnZ3MtbWF4LXJvdycpKSB8fCBncmlkRGVmYXVsdHMubWF4Um93LFxyXG4gICAgICBzdGF0aWNHcmlkOiBVdGlscy50b0Jvb2woZWwuZ2V0QXR0cmlidXRlKCdncy1zdGF0aWMnKSkgfHwgZ3JpZERlZmF1bHRzLnN0YXRpY0dyaWQsXHJcbiAgICAgIGRyYWdnYWJsZToge1xyXG4gICAgICAgIGhhbmRsZTogKG9wdHMuaGFuZGxlQ2xhc3MgPyAnLicgKyBvcHRzLmhhbmRsZUNsYXNzIDogKG9wdHMuaGFuZGxlID8gb3B0cy5oYW5kbGUgOiAnJykpIHx8IGdyaWREZWZhdWx0cy5kcmFnZ2FibGUuaGFuZGxlLFxyXG4gICAgICB9LFxyXG4gICAgICByZW1vdmFibGVPcHRpb25zOiB7XHJcbiAgICAgICAgYWNjZXB0OiBvcHRzLml0ZW1DbGFzcyA/ICcuJyArIG9wdHMuaXRlbUNsYXNzIDogZ3JpZERlZmF1bHRzLnJlbW92YWJsZU9wdGlvbnMuYWNjZXB0LFxyXG4gICAgICB9LFxyXG4gICAgfTtcclxuICAgIGlmIChlbC5nZXRBdHRyaWJ1dGUoJ2dzLWFuaW1hdGUnKSkgeyAvLyBkZWZhdWx0IHRvIHRydWUsIGJ1dCBpZiBzZXQgdG8gZmFsc2UgdXNlIHRoYXQgaW5zdGVhZFxyXG4gICAgICBkZWZhdWx0cy5hbmltYXRlID0gVXRpbHMudG9Cb29sKGVsLmdldEF0dHJpYnV0ZSgnZ3MtYW5pbWF0ZScpKVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMub3B0cyA9IFV0aWxzLmRlZmF1bHRzKG9wdHMsIGRlZmF1bHRzKTtcclxuICAgIG9wdHMgPSBudWxsOyAvLyBtYWtlIHN1cmUgd2UgdXNlIHRoaXMub3B0cyBpbnN0ZWFkXHJcbiAgICB0aGlzLl9pbml0TWFyZ2luKCk7IC8vIHBhcnQgb2Ygc2V0dGluZ3MgZGVmYXVsdHMuLi5cclxuXHJcbiAgICAvLyBOb3cgY2hlY2sgaWYgd2UncmUgbG9hZGluZyBpbnRvIDEgY29sdW1uIG1vZGUgRklSU1Qgc28gd2UgZG9uJ3QgZG8gdW4tbmVjZXNzYXJ5IHdvcmsgKGxpa2UgY2VsbEhlaWdodCA9IHdpZHRoIC8gMTIgdGhlbiBnbyAxIGNvbHVtbilcclxuICAgIGlmICh0aGlzLm9wdHMuY29sdW1uICE9PSAxICYmICF0aGlzLm9wdHMuZGlzYWJsZU9uZUNvbHVtbk1vZGUgJiYgdGhpcy5fd2lkdGhPckNvbnRhaW5lcigpIDw9IHRoaXMub3B0cy5vbmVDb2x1bW5TaXplKSB7XHJcbiAgICAgIHRoaXMuX3ByZXZDb2x1bW4gPSB0aGlzLmdldENvbHVtbigpO1xyXG4gICAgICB0aGlzLm9wdHMuY29sdW1uID0gMTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5vcHRzLnJ0bCA9PT0gJ2F1dG8nKSB7XHJcbiAgICAgIHRoaXMub3B0cy5ydGwgPSAoZWwuc3R5bGUuZGlyZWN0aW9uID09PSAncnRsJyk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5vcHRzLnJ0bCkge1xyXG4gICAgICB0aGlzLmVsLmNsYXNzTGlzdC5hZGQoJ2dyaWQtc3RhY2stcnRsJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gY2hlY2sgaWYgd2UncmUgYmVlbiBuZXN0ZWQsIGFuZCBpZiBzbyB1cGRhdGUgb3VyIHN0eWxlIGFuZCBrZWVwIHBvaW50ZXIgYXJvdW5kICh1c2VkIGR1cmluZyBzYXZlKVxyXG4gICAgbGV0IHBhcmVudEdyaWRJdGVtID0gKFV0aWxzLmNsb3Nlc3RVcEJ5Q2xhc3ModGhpcy5lbCwgZ3JpZERlZmF1bHRzLml0ZW1DbGFzcykgYXMgR3JpZEl0ZW1IVE1MRWxlbWVudCk/LmdyaWRzdGFja05vZGU7XHJcbiAgICBpZiAocGFyZW50R3JpZEl0ZW0pIHtcclxuICAgICAgcGFyZW50R3JpZEl0ZW0uc3ViR3JpZCA9IHRoaXM7XHJcbiAgICAgIHRoaXMucGFyZW50R3JpZEl0ZW0gPSBwYXJlbnRHcmlkSXRlbTtcclxuICAgICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKCdncmlkLXN0YWNrLW5lc3RlZCcpO1xyXG4gICAgICBwYXJlbnRHcmlkSXRlbS5lbC5jbGFzc0xpc3QuYWRkKCdncmlkLXN0YWNrLXN1Yi1ncmlkJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5faXNBdXRvQ2VsbEhlaWdodCA9ICh0aGlzLm9wdHMuY2VsbEhlaWdodCA9PT0gJ2F1dG8nKTtcclxuICAgIGlmICh0aGlzLl9pc0F1dG9DZWxsSGVpZ2h0IHx8IHRoaXMub3B0cy5jZWxsSGVpZ2h0ID09PSAnaW5pdGlhbCcpIHtcclxuICAgICAgLy8gbWFrZSB0aGUgY2VsbCBjb250ZW50IHNxdWFyZSBpbml0aWFsbHkgKHdpbGwgdXNlIHJlc2l6ZS9jb2x1bW4gZXZlbnQgdG8ga2VlcCBpdCBzcXVhcmUpXHJcbiAgICAgIHRoaXMuY2VsbEhlaWdodCh1bmRlZmluZWQsIGZhbHNlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIGFwcGVuZCB1bml0IGlmIGFueSBhcmUgc2V0XHJcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5vcHRzLmNlbGxIZWlnaHQgPT0gJ251bWJlcicgJiYgdGhpcy5vcHRzLmNlbGxIZWlnaHRVbml0ICYmIHRoaXMub3B0cy5jZWxsSGVpZ2h0VW5pdCAhPT0gZ3JpZERlZmF1bHRzLmNlbGxIZWlnaHRVbml0KSB7XHJcbiAgICAgICAgdGhpcy5vcHRzLmNlbGxIZWlnaHQgPSB0aGlzLm9wdHMuY2VsbEhlaWdodCArIHRoaXMub3B0cy5jZWxsSGVpZ2h0VW5pdDtcclxuICAgICAgICBkZWxldGUgdGhpcy5vcHRzLmNlbGxIZWlnaHRVbml0O1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuY2VsbEhlaWdodCh0aGlzLm9wdHMuY2VsbEhlaWdodCwgZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHNlZSBpZiB3ZSBuZWVkIHRvIGFkanVzdCBhdXRvLWhpZGVcclxuICAgIGlmICh0aGlzLm9wdHMuYWx3YXlzU2hvd1Jlc2l6ZUhhbmRsZSA9PT0gJ21vYmlsZScpIHtcclxuICAgICAgdGhpcy5vcHRzLmFsd2F5c1Nob3dSZXNpemVIYW5kbGUgPSBpc1RvdWNoO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3N0eWxlU2hlZXRDbGFzcyA9ICdncy1pZC0nICsgR3JpZFN0YWNrRW5naW5lLl9pZFNlcSsrO1xyXG4gICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKHRoaXMuX3N0eWxlU2hlZXRDbGFzcyk7XHJcblxyXG4gICAgdGhpcy5fc2V0U3RhdGljQ2xhc3MoKTtcclxuXHJcbiAgICBsZXQgZW5naW5lQ2xhc3MgPSB0aGlzLm9wdHMuZW5naW5lQ2xhc3MgfHwgR3JpZFN0YWNrLmVuZ2luZUNsYXNzIHx8IEdyaWRTdGFja0VuZ2luZTtcclxuICAgIHRoaXMuZW5naW5lID0gbmV3IGVuZ2luZUNsYXNzKHtcclxuICAgICAgY29sdW1uOiB0aGlzLmdldENvbHVtbigpLFxyXG4gICAgICBmbG9hdDogdGhpcy5vcHRzLmZsb2F0LFxyXG4gICAgICBtYXhSb3c6IHRoaXMub3B0cy5tYXhSb3csXHJcbiAgICAgIG9uQ2hhbmdlOiAoY2JOb2RlcykgPT4ge1xyXG4gICAgICAgIGxldCBtYXhIID0gMDtcclxuICAgICAgICB0aGlzLmVuZ2luZS5ub2Rlcy5mb3JFYWNoKG4gPT4geyBtYXhIID0gTWF0aC5tYXgobWF4SCwgbi55ICsgbi5oKSB9KTtcclxuICAgICAgICBjYk5vZGVzLmZvckVhY2gobiA9PiB7XHJcbiAgICAgICAgICBsZXQgZWwgPSBuLmVsO1xyXG4gICAgICAgICAgaWYgKCFlbCkgcmV0dXJuO1xyXG4gICAgICAgICAgaWYgKG4uX3JlbW92ZURPTSkge1xyXG4gICAgICAgICAgICBpZiAoZWwpIGVsLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICBkZWxldGUgbi5fcmVtb3ZlRE9NO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fd3JpdGVQb3NBdHRyKGVsLCBuKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLl91cGRhdGVTdHlsZXMoZmFsc2UsIG1heEgpOyAvLyBmYWxzZSA9IGRvbid0IHJlY3JlYXRlLCBqdXN0IGFwcGVuZCBpZiBuZWVkIGJlXHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdHMuYXV0bykge1xyXG4gICAgICB0aGlzLmJhdGNoVXBkYXRlKCk7IC8vIHByZXZlbnQgaW4gYmV0d2VlbiByZS1sYXlvdXQgIzE1MzUgVE9ETzogdGhpcyBvbmx5IHNldCBmbG9hdD10cnVlLCBuZWVkIHRvIHByZXZlbnQgY29sbGlzaW9uIGNoZWNrLi4uXHJcbiAgICAgIHRoaXMuZ2V0R3JpZEl0ZW1zKCkuZm9yRWFjaChlbCA9PiB0aGlzLl9wcmVwYXJlRWxlbWVudChlbCkpO1xyXG4gICAgICB0aGlzLmJhdGNoVXBkYXRlKGZhbHNlKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBsb2FkIGFueSBwYXNzZWQgaW4gY2hpbGRyZW4gYXMgd2VsbCwgd2hpY2ggb3ZlcnJpZGVzIGFueSBET00gbGF5b3V0IGRvbmUgYWJvdmVcclxuICAgIGlmICh0aGlzLm9wdHMuY2hpbGRyZW4pIHtcclxuICAgICAgbGV0IGNoaWxkcmVuID0gdGhpcy5vcHRzLmNoaWxkcmVuO1xyXG4gICAgICBkZWxldGUgdGhpcy5vcHRzLmNoaWxkcmVuO1xyXG4gICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoKSB0aGlzLmxvYWQoY2hpbGRyZW4pOyAvLyBkb24ndCBsb2FkIGVtcHR5XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5zZXRBbmltYXRpb24odGhpcy5vcHRzLmFuaW1hdGUpO1xyXG5cclxuICAgIHRoaXMuX3VwZGF0ZVN0eWxlcygpO1xyXG4gICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKCdncy0nICsgdGhpcy5vcHRzLmNvbHVtbik7XHJcblxyXG4gICAgLy8gZHluYW1pYyBncmlkcyByZXF1aXJlIHBhdXNpbmcgZHVyaW5nIGRyYWcgdG8gZGV0ZWN0IG92ZXIgdG8gbmVzdCB2cyBwdXNoXHJcbiAgICBpZiAodGhpcy5vcHRzLnN1YkdyaWREeW5hbWljICYmICFERE1hbmFnZXIucGF1c2VEcmFnKSBERE1hbmFnZXIucGF1c2VEcmFnID0gdHJ1ZTtcclxuICAgIGlmICh0aGlzLm9wdHMuZHJhZ2dhYmxlPy5wYXVzZSAhPT0gdW5kZWZpbmVkKSBERE1hbmFnZXIucGF1c2VEcmFnID0gdGhpcy5vcHRzLmRyYWdnYWJsZS5wYXVzZTtcclxuXHJcbiAgICB0aGlzLl9zZXR1cFJlbW92ZURyb3AoKTtcclxuICAgIHRoaXMuX3NldHVwQWNjZXB0V2lkZ2V0KCk7XHJcbiAgICB0aGlzLl91cGRhdGVXaW5kb3dSZXNpemVFdmVudCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogYWRkIGEgbmV3IHdpZGdldCBhbmQgcmV0dXJucyBpdC5cclxuICAgKlxyXG4gICAqIFdpZGdldCB3aWxsIGJlIGFsd2F5cyBwbGFjZWQgZXZlbiBpZiByZXN1bHQgaGVpZ2h0IGlzIG1vcmUgdGhhbiBhY3R1YWwgZ3JpZCBoZWlnaHQuXHJcbiAgICogWW91IG5lZWQgdG8gdXNlIGB3aWxsSXRGaXQoKWAgYmVmb3JlIGNhbGxpbmcgYWRkV2lkZ2V0IGZvciBhZGRpdGlvbmFsIGNoZWNrLlxyXG4gICAqIFNlZSBhbHNvIGBtYWtlV2lkZ2V0KClgLlxyXG4gICAqXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiBsZXQgZ3JpZCA9IEdyaWRTdGFjay5pbml0KCk7XHJcbiAgICogZ3JpZC5hZGRXaWRnZXQoe3c6IDMsIGNvbnRlbnQ6ICdoZWxsbyd9KTtcclxuICAgKiBncmlkLmFkZFdpZGdldCgnPGRpdiBjbGFzcz1cImdyaWQtc3RhY2staXRlbVwiPjxkaXYgY2xhc3M9XCJncmlkLXN0YWNrLWl0ZW0tY29udGVudFwiPmhlbGxvPC9kaXY+PC9kaXY+Jywge3c6IDN9KTtcclxuICAgKlxyXG4gICAqIEBwYXJhbSBlbCAgR3JpZFN0YWNrV2lkZ2V0ICh3aGljaCBjYW4gaGF2ZSBjb250ZW50IHN0cmluZyBhcyB3ZWxsKSwgaHRtbCBlbGVtZW50LCBvciBzdHJpbmcgZGVmaW5pdGlvbiB0byBhZGRcclxuICAgKiBAcGFyYW0gb3B0aW9ucyB3aWRnZXQgcG9zaXRpb24vc2l6ZSBvcHRpb25zIChvcHRpb25hbCwgYW5kIGlnbm9yZSBpZiBmaXJzdCBwYXJhbSBpcyBhbHJlYWR5IG9wdGlvbikgLSBzZWUgR3JpZFN0YWNrV2lkZ2V0XHJcbiAgICovXHJcbiAgcHVibGljIGFkZFdpZGdldChlbHM/OiBHcmlkU3RhY2tXaWRnZXQgfCBHcmlkU3RhY2tFbGVtZW50LCBvcHRpb25zPzogR3JpZFN0YWNrV2lkZ2V0KTogR3JpZEl0ZW1IVE1MRWxlbWVudCB7XHJcbiAgICBmdW5jdGlvbiBpc0dyaWRTdGFja1dpZGdldCh3OiBHcmlkU3RhY2tOb2RlKTogdyBpcyBHcmlkU3RhY2tOb2RlIHsgLy8gaHR0cHM6Ly9tZWRpdW0uY29tL292cnNlYS9jaGVja2luZy10aGUtdHlwZS1vZi1hbi1vYmplY3QtaW4tdHlwZXNjcmlwdC10aGUtdHlwZS1ndWFyZHMtMjRkOThkOTExOWIwXHJcbiAgICAgIHJldHVybiB3LmVsICE9PSB1bmRlZmluZWQgfHwgdy54ICE9PSB1bmRlZmluZWQgfHwgdy55ICE9PSB1bmRlZmluZWQgfHwgdy53ICE9PSB1bmRlZmluZWQgfHwgdy5oICE9PSB1bmRlZmluZWQgfHwgdy5jb250ZW50ICE9PSB1bmRlZmluZWQgPyB0cnVlIDogZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGVsOiBHcmlkSXRlbUhUTUxFbGVtZW50O1xyXG4gICAgbGV0IG5vZGU6IEdyaWRTdGFja05vZGU7XHJcbiAgICBpZiAodHlwZW9mIGVscyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgbGV0IGRvYyA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgnJyk7IC8vIElFIG5lZWRzIGEgcGFyYW1cclxuICAgICAgZG9jLmJvZHkuaW5uZXJIVE1MID0gZWxzO1xyXG4gICAgICBlbCA9IGRvYy5ib2R5LmNoaWxkcmVuWzBdIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiYgaXNHcmlkU3RhY2tXaWRnZXQoZWxzKSkge1xyXG4gICAgICBub2RlID0gb3B0aW9ucyA9IGVscztcclxuICAgICAgaWYgKG5vZGU/LmVsKSB7XHJcbiAgICAgICAgZWwgPSBub2RlLmVsOyAvLyByZS11c2UgZWxlbWVudCBzdG9yZWQgaW4gdGhlIG5vZGVcclxuICAgICAgfSBlbHNlIGlmIChHcmlkU3RhY2suYWRkUmVtb3ZlQ0IpIHtcclxuICAgICAgICBlbCA9IEdyaWRTdGFjay5hZGRSZW1vdmVDQih0aGlzLmVsLCBvcHRpb25zLCB0cnVlLCBmYWxzZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbGV0IGNvbnRlbnQgPSBvcHRpb25zPy5jb250ZW50IHx8ICcnO1xyXG4gICAgICAgIGxldCBkb2MgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoJycpOyAvLyBJRSBuZWVkcyBhIHBhcmFtXHJcbiAgICAgICAgZG9jLmJvZHkuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9XCJncmlkLXN0YWNrLWl0ZW0gJHt0aGlzLm9wdHMuaXRlbUNsYXNzIHx8ICcnfVwiPjxkaXYgY2xhc3M9XCJncmlkLXN0YWNrLWl0ZW0tY29udGVudFwiPiR7Y29udGVudH08L2Rpdj48L2Rpdj5gO1xyXG4gICAgICAgIGVsID0gZG9jLmJvZHkuY2hpbGRyZW5bMF0gYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGVsID0gZWxzIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghZWwpIHJldHVybjtcclxuXHJcbiAgICAvLyBpZiB0aGUgY2FsbGVyIGVuZGVkIHVwIGluaXRpYWxpemluZyB0aGUgd2lkZ2V0IGluIGFkZFJlbW92ZUNCLCBvciB3ZSBzdGFyZWQgd2l0aCBvbmUgYWxyZWFkeSwgc2tpcCB0aGUgcmVzdFxyXG4gICAgbm9kZSA9IGVsLmdyaWRzdGFja05vZGU7XHJcbiAgICBpZiAobm9kZSAmJiBlbC5wYXJlbnRFbGVtZW50ID09PSB0aGlzLmVsICYmIHRoaXMuZW5naW5lLm5vZGVzLmZpbmQobiA9PiBuLl9pZCA9PT0gbm9kZS5faWQpKSByZXR1cm4gZWw7XHJcblxyXG4gICAgLy8gVGVtcHRpbmcgdG8gaW5pdGlhbGl6ZSB0aGUgcGFzc2VkIGluIG9wdCB3aXRoIGRlZmF1bHQgYW5kIHZhbGlkIHZhbHVlcywgYnV0IHRoaXMgYnJlYWsga25vY2tvdXQgZGVtb3NcclxuICAgIC8vIGFzIHRoZSBhY3R1YWwgdmFsdWUgYXJlIGZpbGxlZCBpbiB3aGVuIF9wcmVwYXJlRWxlbWVudCgpIGNhbGxzIGVsLmdldEF0dHJpYnV0ZSgnZ3MteHl6JykgYmVmb3JlIGFkZGluZyB0aGUgbm9kZS5cclxuICAgIC8vIFNvIG1ha2Ugc3VyZSB3ZSBsb2FkIGFueSBET00gYXR0cmlidXRlcyB0aGF0IGFyZSBub3Qgc3BlY2lmaWVkIGluIHBhc3NlZCBpbiBvcHRpb25zICh3aGljaCBvdmVycmlkZSlcclxuICAgIGxldCBkb21BdHRyID0gdGhpcy5fcmVhZEF0dHIoZWwpO1xyXG4gICAgb3B0aW9ucyA9IFV0aWxzLmNsb25lRGVlcChvcHRpb25zKSB8fCB7fTsgIC8vIG1ha2UgYSBjb3B5IGJlZm9yZSB3ZSBtb2RpZnkgaW4gY2FzZSBjYWxsZXIgcmUtdXNlcyBpdFxyXG4gICAgVXRpbHMuZGVmYXVsdHMob3B0aW9ucywgZG9tQXR0cik7XHJcbiAgICBub2RlID0gdGhpcy5lbmdpbmUucHJlcGFyZU5vZGUob3B0aW9ucyk7XHJcbiAgICB0aGlzLl93cml0ZUF0dHIoZWwsIG9wdGlvbnMpO1xyXG5cclxuICAgIGlmICh0aGlzLl9pbnNlcnROb3RBcHBlbmQpIHtcclxuICAgICAgdGhpcy5lbC5wcmVwZW5kKGVsKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZWwuYXBwZW5kQ2hpbGQoZWwpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMubWFrZVdpZGdldChlbCwgb3B0aW9ucyk7XHJcblxyXG4gICAgcmV0dXJuIGVsO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29udmVydCBhbiBleGlzdGluZyBncmlkSXRlbSBlbGVtZW50IGludG8gYSBzdWItZ3JpZCB3aXRoIHRoZSBnaXZlbiAob3B0aW9uYWwpIG9wdGlvbnMsIGVsc2UgaW5oZXJpdCB0aGVtXHJcbiAgICogZnJvbSB0aGUgcGFyZW50J3Mgc3ViR3JpZCBvcHRpb25zLlxyXG4gICAqIEBwYXJhbSBlbCBncmlkSXRlbSBlbGVtZW50IHRvIGNvbnZlcnRcclxuICAgKiBAcGFyYW0gb3BzIChvcHRpb25hbCkgc3ViLWdyaWQgb3B0aW9ucywgZWxzZSBkZWZhdWx0IHRvIG5vZGUsIHRoZW4gcGFyZW50IHNldHRpbmdzLCBlbHNlIGRlZmF1bHRzXHJcbiAgICogQHBhcmFtIG5vZGVUb0FkZCAob3B0aW9uYWwpIG5vZGUgdG8gYWRkIHRvIHRoZSBuZXdseSBjcmVhdGVkIHN1YiBncmlkICh1c2VkIHdoZW4gZHJhZ2dpbmcgb3ZlciBleGlzdGluZyByZWd1bGFyIGl0ZW0pXHJcbiAgICogQHJldHVybnMgbmV3bHkgY3JlYXRlZCBncmlkXHJcbiAgICovXHJcbiAgcHVibGljIG1ha2VTdWJHcmlkKGVsOiBHcmlkSXRlbUhUTUxFbGVtZW50LCBvcHM/OiBHcmlkU3RhY2tPcHRpb25zLCBub2RlVG9BZGQ/OiBHcmlkU3RhY2tOb2RlLCBzYXZlQ29udGVudCA9IHRydWUpOiBHcmlkU3RhY2sge1xyXG4gICAgbGV0IG5vZGUgPSBlbC5ncmlkc3RhY2tOb2RlO1xyXG4gICAgaWYgKCFub2RlKSB7XHJcbiAgICAgIG5vZGUgPSB0aGlzLm1ha2VXaWRnZXQoZWwpLmdyaWRzdGFja05vZGU7XHJcbiAgICB9XHJcbiAgICBpZiAobm9kZS5zdWJHcmlkPy5lbCkgcmV0dXJuIG5vZGUuc3ViR3JpZDsgLy8gYWxyZWFkeSBkb25lXHJcblxyXG4gICAgLy8gZmluZCB0aGUgdGVtcGxhdGUgc3ViR3JpZCBzdG9yZWQgb24gYSBwYXJlbnQgYXMgZmFsbGJhY2suLi5cclxuICAgIGxldCBzdWJHcmlkVGVtcGxhdGU6IEdyaWRTdGFja09wdGlvbnM7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xyXG4gICAgbGV0IGdyaWQ6IEdyaWRTdGFjayA9IHRoaXM7XHJcbiAgICB3aGlsZSAoZ3JpZCAmJiAhc3ViR3JpZFRlbXBsYXRlKSB7XHJcbiAgICAgIHN1YkdyaWRUZW1wbGF0ZSA9IGdyaWQub3B0cz8uc3ViR3JpZE9wdHM7XHJcbiAgICAgIGdyaWQgPSBncmlkLnBhcmVudEdyaWRJdGVtPy5ncmlkO1xyXG4gICAgfVxyXG4gICAgLy8uLi4gYW5kIHNldCB0aGUgY3JlYXRlIG9wdGlvbnNcclxuICAgIG9wcyA9IFV0aWxzLmNsb25lRGVlcCh7Li4uKHN1YkdyaWRUZW1wbGF0ZSB8fCB7fSksIGNoaWxkcmVuOiB1bmRlZmluZWQsIC4uLihvcHMgfHwgbm9kZS5zdWJHcmlkT3B0cyl9KTtcclxuICAgIG5vZGUuc3ViR3JpZE9wdHMgPSBvcHM7XHJcblxyXG4gICAgLy8gaWYgY29sdW1uIHNwZWNpYWwgY2FzZSBpdCBzZXQsIHJlbWVtYmVyIHRoYXQgZmxhZyBhbmQgc2V0IGRlZmF1bHRcclxuICAgIGxldCBhdXRvQ29sdW1uOiBib29sZWFuO1xyXG4gICAgaWYgKG9wcy5jb2x1bW4gPT09ICdhdXRvJykge1xyXG4gICAgICBhdXRvQ29sdW1uID0gdHJ1ZTtcclxuICAgICAgb3BzLmNvbHVtbiA9IE1hdGgubWF4KG5vZGUudyB8fCAxLCBub2RlVG9BZGQ/LncgfHwgMSk7XHJcbiAgICAgIG9wcy5kaXNhYmxlT25lQ29sdW1uTW9kZSA9IHRydWU7IC8vIGRyaXZlbiBieSBwYXJlbnRcclxuICAgIH1cclxuXHJcbiAgICAvLyBpZiB3ZSdyZSBjb252ZXJ0aW5nIGFuIGV4aXN0aW5nIGZ1bGwgaXRlbSwgbW92ZSBvdmVyIHRoZSBjb250ZW50IHRvIGJlIHRoZSBmaXJzdCBzdWIgaXRlbSBpbiB0aGUgbmV3IGdyaWRcclxuICAgIGxldCBjb250ZW50ID0gbm9kZS5lbC5xdWVyeVNlbGVjdG9yKCcuZ3JpZC1zdGFjay1pdGVtLWNvbnRlbnQnKSBhcyBIVE1MRWxlbWVudDtcclxuICAgIGxldCBuZXdJdGVtOiBIVE1MRWxlbWVudDtcclxuICAgIGxldCBuZXdJdGVtT3B0OiBHcmlkU3RhY2tOb2RlO1xyXG4gICAgaWYgKHNhdmVDb250ZW50KSB7XHJcbiAgICAgIHRoaXMuX3JlbW92ZUREKG5vZGUuZWwpOyAvLyByZW1vdmUgRCZEIHNpbmNlIGl0J3Mgc2V0IG9uIGNvbnRlbnQgZGl2XHJcbiAgICAgIG5ld0l0ZW1PcHQgPSB7Li4ubm9kZSwgeDowLCB5OjB9O1xyXG4gICAgICBVdGlscy5yZW1vdmVJbnRlcm5hbEZvclNhdmUobmV3SXRlbU9wdCk7XHJcbiAgICAgIGRlbGV0ZSBuZXdJdGVtT3B0LnN1YkdyaWRPcHRzO1xyXG4gICAgICBpZiAobm9kZS5jb250ZW50KSB7XHJcbiAgICAgICAgbmV3SXRlbU9wdC5jb250ZW50ID0gbm9kZS5jb250ZW50O1xyXG4gICAgICAgIGRlbGV0ZSBub2RlLmNvbnRlbnQ7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKEdyaWRTdGFjay5hZGRSZW1vdmVDQikge1xyXG4gICAgICAgIG5ld0l0ZW0gPSBHcmlkU3RhY2suYWRkUmVtb3ZlQ0IodGhpcy5lbCwgbmV3SXRlbU9wdCwgdHJ1ZSwgZmFsc2UpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGxldCBkb2MgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoJycpOyAvLyBJRSBuZWVkcyBhIHBhcmFtXHJcbiAgICAgICAgZG9jLmJvZHkuaW5uZXJIVE1MID0gYDxkaXYgY2xhc3M9XCJncmlkLXN0YWNrLWl0ZW1cIj48L2Rpdj5gO1xyXG4gICAgICAgIG5ld0l0ZW0gPSBkb2MuYm9keS5jaGlsZHJlblswXSBhcyBIVE1MRWxlbWVudDtcclxuICAgICAgICBuZXdJdGVtLmFwcGVuZENoaWxkKGNvbnRlbnQpO1xyXG4gICAgICAgIGRvYy5ib2R5LmlubmVySFRNTCA9IGA8ZGl2IGNsYXNzPVwiZ3JpZC1zdGFjay1pdGVtLWNvbnRlbnRcIj48L2Rpdj5gO1xyXG4gICAgICAgIGNvbnRlbnQgPSBkb2MuYm9keS5jaGlsZHJlblswXSBhcyBIVE1MRWxlbWVudDtcclxuICAgICAgICBub2RlLmVsLmFwcGVuZENoaWxkKGNvbnRlbnQpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuX3ByZXBhcmVEcmFnRHJvcEJ5Tm9kZShub2RlKTsgLy8gLi4uIGFuZCByZXN0b3JlIG9yaWdpbmFsIEQmRFxyXG4gICAgfVxyXG5cclxuICAgIC8vIGlmIHdlJ3JlIGFkZGluZyBhbiBhZGRpdGlvbmFsIGl0ZW0sIG1ha2UgdGhlIGNvbnRhaW5lciBsYXJnZSBlbm91Z2ggdG8gaGF2ZSB0aGVtIGJvdGhcclxuICAgIGlmIChub2RlVG9BZGQpIHtcclxuICAgICAgbGV0IHcgPSBhdXRvQ29sdW1uID8gb3BzLmNvbHVtbiA6IG5vZGUudztcclxuICAgICAgbGV0IGggPSBub2RlLmggKyBub2RlVG9BZGQuaDtcclxuICAgICAgbGV0IHN0eWxlID0gbm9kZS5lbC5zdHlsZTtcclxuICAgICAgc3R5bGUudHJhbnNpdGlvbiA9ICdub25lJzsgLy8gc2hvdyB1cCBpbnN0YW50bHkgc28gd2UgZG9uJ3Qgc2VlIHNjcm9sbGJhciB3aXRoIG5vZGVUb0FkZFxyXG4gICAgICB0aGlzLnVwZGF0ZShub2RlLmVsLCB7dywgaH0pO1xyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+ICBzdHlsZS50cmFuc2l0aW9uID0gbnVsbCk7IC8vIHJlY292ZXIgYW5pbWF0aW9uXHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHN1YkdyaWQgPSBub2RlLnN1YkdyaWQgPSBHcmlkU3RhY2suYWRkR3JpZChjb250ZW50LCBvcHMpO1xyXG4gICAgaWYgKG5vZGVUb0FkZD8uX21vdmluZykgc3ViR3JpZC5faXNUZW1wID0gdHJ1ZTsgLy8gcHJldmVudCByZS1uZXN0aW5nIGFzIHdlIGFkZCBvdmVyXHJcbiAgICBpZiAoYXV0b0NvbHVtbikgc3ViR3JpZC5fYXV0b0NvbHVtbiA9IHRydWU7XHJcblxyXG4gICAgLy8gYWRkIHRoZSBvcmlnaW5hbCBjb250ZW50IGJhY2sgYXMgYSBjaGlsZCBvZiBodGUgbmV3bHkgY3JlYXRlZCBncmlkXHJcbiAgICBpZiAoc2F2ZUNvbnRlbnQpIHtcclxuICAgICAgc3ViR3JpZC5hZGRXaWRnZXQobmV3SXRlbSwgbmV3SXRlbU9wdCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gbm93IGFkZCBhbnkgYWRkaXRpb25hbCBub2RlXHJcbiAgICBpZiAobm9kZVRvQWRkKSB7XHJcbiAgICAgIGlmIChub2RlVG9BZGQuX21vdmluZykge1xyXG4gICAgICAgIC8vIGNyZWF0ZSBhbiBhcnRpZmljaWFsIGV2ZW50IGV2ZW4gZm9yIHRoZSBqdXN0IGNyZWF0ZWQgZ3JpZCB0byByZWNlaXZlIHRoaXMgaXRlbVxyXG4gICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IFV0aWxzLnNpbXVsYXRlTW91c2VFdmVudChub2RlVG9BZGQuX2V2ZW50LCAnbW91c2VlbnRlcicsIHN1YkdyaWQuZWwpLCAwKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzdWJHcmlkLmFkZFdpZGdldChub2RlLmVsLCBub2RlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN1YkdyaWQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBjYWxsZWQgd2hlbiBhbiBpdGVtIHdhcyBjb252ZXJ0ZWQgaW50byBhIG5lc3RlZCBncmlkIHRvIGFjY29tbW9kYXRlIGEgZHJhZ2dlZCBvdmVyIGl0ZW0sIGJ1dCB0aGVuIGl0ZW0gbGVhdmVzIC0gcmV0dXJuIGJhY2tcclxuICAgKiB0byB0aGUgb3JpZ2luYWwgZ3JpZC1pdGVtLiBBbHNvIGNhbGxlZCB0byByZW1vdmUgZW1wdHkgc3ViLWdyaWRzIHdoZW4gbGFzdCBpdGVtIGlzIGRyYWdnZWQgb3V0IChzaW5jZSByZS1jcmVhdGluZyBpcyBzaW1wbGUpXHJcbiAgICovXHJcbiAgcHVibGljIHJlbW92ZUFzU3ViR3JpZChub2RlVGhhdFJlbW92ZWQ/OiBHcmlkU3RhY2tOb2RlKTogdm9pZCB7XHJcbiAgICBsZXQgcEdyaWQgPSB0aGlzLnBhcmVudEdyaWRJdGVtPy5ncmlkO1xyXG4gICAgaWYgKCFwR3JpZCkgcmV0dXJuO1xyXG5cclxuICAgIHBHcmlkLmJhdGNoVXBkYXRlKCk7XHJcbiAgICBwR3JpZC5yZW1vdmVXaWRnZXQodGhpcy5wYXJlbnRHcmlkSXRlbS5lbCwgdHJ1ZSwgdHJ1ZSk7XHJcbiAgICB0aGlzLmVuZ2luZS5ub2Rlcy5mb3JFYWNoKG4gPT4ge1xyXG4gICAgICAvLyBtaWdyYXRlIGFueSBjaGlsZHJlbiBvdmVyIGFuZCBvZmZzZXR0aW5nIGJ5IG91ciBsb2NhdGlvblxyXG4gICAgICBuLnggKz0gdGhpcy5wYXJlbnRHcmlkSXRlbS54O1xyXG4gICAgICBuLnkgKz0gdGhpcy5wYXJlbnRHcmlkSXRlbS55O1xyXG4gICAgICBwR3JpZC5hZGRXaWRnZXQobi5lbCwgbik7XHJcbiAgICB9KTtcclxuICAgIHBHcmlkLmJhdGNoVXBkYXRlKGZhbHNlKTtcclxuICAgIGlmICh0aGlzLnBhcmVudEdyaWRJdGVtKSBkZWxldGUgdGhpcy5wYXJlbnRHcmlkSXRlbS5zdWJHcmlkO1xyXG4gICAgZGVsZXRlIHRoaXMucGFyZW50R3JpZEl0ZW07XHJcblxyXG4gICAgLy8gY3JlYXRlIGFuIGFydGlmaWNpYWwgZXZlbnQgZm9yIHRoZSBvcmlnaW5hbCBncmlkIG5vdyB0aGF0IHRoaXMgb25lIGlzIGdvbmUgKGdvdCBhIGxlYXZlLCBidXQgd29uJ3QgZ2V0IGVudGVyKVxyXG4gICAgaWYgKG5vZGVUaGF0UmVtb3ZlZCkge1xyXG4gICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiBVdGlscy5zaW11bGF0ZU1vdXNlRXZlbnQobm9kZVRoYXRSZW1vdmVkLl9ldmVudCwgJ21vdXNlZW50ZXInLCBwR3JpZC5lbCksIDApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogc2F2ZXMgdGhlIGN1cnJlbnQgbGF5b3V0IHJldHVybmluZyBhIGxpc3Qgb2Ygd2lkZ2V0cyBmb3Igc2VyaWFsaXphdGlvbiB3aGljaCBtaWdodCBpbmNsdWRlIGFueSBuZXN0ZWQgZ3JpZHMuXHJcbiAgICogQHBhcmFtIHNhdmVDb250ZW50IGlmIHRydWUgKGRlZmF1bHQpIHRoZSBsYXRlc3QgaHRtbCBpbnNpZGUgLmdyaWQtc3RhY2stY29udGVudCB3aWxsIGJlIHNhdmVkIHRvIEdyaWRTdGFja1dpZGdldC5jb250ZW50IGZpZWxkLCBlbHNlIGl0IHdpbGxcclxuICAgKiBiZSByZW1vdmVkLlxyXG4gICAqIEBwYXJhbSBzYXZlR3JpZE9wdCBpZiB0cnVlIChkZWZhdWx0IGZhbHNlKSwgc2F2ZSB0aGUgZ3JpZCBvcHRpb25zIGl0c2VsZiwgc28geW91IGNhbiBjYWxsIHRoZSBuZXcgR3JpZFN0YWNrLmFkZEdyaWQoKVxyXG4gICAqIHRvIHJlY3JlYXRlIGV2ZXJ5dGhpbmcgZnJvbSBzY3JhdGNoLiBHcmlkU3RhY2tPcHRpb25zLmNoaWxkcmVuIHdvdWxkIHRoZW4gY29udGFpbiB0aGUgd2lkZ2V0IGxpc3QgaW5zdGVhZC5cclxuICAgKiBAcGFyYW0gc2F2ZUNCIGNhbGxiYWNrIGZvciBlYWNoIG5vZGUgLT4gd2lkZ2V0LCBzbyBhcHBsaWNhdGlvbiBjYW4gaW5zZXJ0IGFkZGl0aW9uYWwgZGF0YSB0byBiZSBzYXZlZCBpbnRvIHRoZSB3aWRnZXQgZGF0YSBzdHJ1Y3R1cmUuXHJcbiAgICogQHJldHVybnMgbGlzdCBvZiB3aWRnZXRzIG9yIGZ1bGwgZ3JpZCBvcHRpb24sIGluY2x1ZGluZyAuY2hpbGRyZW4gbGlzdCBvZiB3aWRnZXRzXHJcbiAgICovXHJcbiAgcHVibGljIHNhdmUoc2F2ZUNvbnRlbnQgPSB0cnVlLCBzYXZlR3JpZE9wdCA9IGZhbHNlLCBzYXZlQ0IgPSBHcmlkU3RhY2suc2F2ZUNCKTogR3JpZFN0YWNrV2lkZ2V0W10gfCBHcmlkU3RhY2tPcHRpb25zIHtcclxuICAgIC8vIHJldHVybiBjb3BpZWQgR3JpZFN0YWNrV2lkZ2V0ICh3aXRoIG9wdGlvbmFsbHkgLmVsKSB3ZSBjYW4gbW9kaWZ5IGF0IHdpbGwuLi5cclxuICAgIGxldCBsaXN0ID0gdGhpcy5lbmdpbmUuc2F2ZShzYXZlQ29udGVudCwgc2F2ZUNCKTtcclxuXHJcbiAgICAvLyBjaGVjayBmb3IgSFRNTCBjb250ZW50IGFuZCBuZXN0ZWQgZ3JpZHNcclxuICAgIGxpc3QuZm9yRWFjaChuID0+IHtcclxuICAgICAgaWYgKHNhdmVDb250ZW50ICYmIG4uZWwgJiYgIW4uc3ViR3JpZCAmJiAhc2F2ZUNCKSB7IC8vIHN1Yi1ncmlkIGFyZSBzYXZlZCBkaWZmZXJlbnRseSwgbm90IHBsYWluIGNvbnRlbnRcclxuICAgICAgICBsZXQgc3ViID0gbi5lbC5xdWVyeVNlbGVjdG9yKCcuZ3JpZC1zdGFjay1pdGVtLWNvbnRlbnQnKTtcclxuICAgICAgICBuLmNvbnRlbnQgPSBzdWIgPyBzdWIuaW5uZXJIVE1MIDogdW5kZWZpbmVkO1xyXG4gICAgICAgIGlmICghbi5jb250ZW50KSBkZWxldGUgbi5jb250ZW50O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICghc2F2ZUNvbnRlbnQgJiYgIXNhdmVDQikgeyBkZWxldGUgbi5jb250ZW50OyB9XHJcbiAgICAgICAgLy8gY2hlY2sgZm9yIG5lc3RlZCBncmlkXHJcbiAgICAgICAgaWYgKG4uc3ViR3JpZD8uZWwpIHtcclxuICAgICAgICAgIGNvbnN0IGxpc3RPck9wdCA9IG4uc3ViR3JpZC5zYXZlKHNhdmVDb250ZW50LCBzYXZlR3JpZE9wdCwgc2F2ZUNCKTtcclxuICAgICAgICAgIG4uc3ViR3JpZE9wdHMgPSAoc2F2ZUdyaWRPcHQgPyBsaXN0T3JPcHQgOiB7Y2hpbGRyZW46IGxpc3RPck9wdH0pIGFzIEdyaWRTdGFja09wdGlvbnM7XHJcbiAgICAgICAgICBkZWxldGUgbi5zdWJHcmlkO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBkZWxldGUgbi5lbDtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIGNoZWNrIGlmIHNhdmUgZW50aXJlIGdyaWQgb3B0aW9ucyAobmVlZGVkIGZvciByZWN1cnNpdmUpICsgY2hpbGRyZW4uLi5cclxuICAgIGlmIChzYXZlR3JpZE9wdCkge1xyXG4gICAgICBsZXQgbzogSW50ZXJuYWxHcmlkU3RhY2tPcHRpb25zID0gVXRpbHMuY2xvbmVEZWVwKHRoaXMub3B0cyk7XHJcbiAgICAgIC8vIGRlbGV0ZSBkZWZhdWx0IHZhbHVlcyB0aGF0IHdpbGwgYmUgcmVjcmVhdGVkIG9uIGxhdW5jaFxyXG4gICAgICBpZiAoby5tYXJnaW5Cb3R0b20gPT09IG8ubWFyZ2luVG9wICYmIG8ubWFyZ2luUmlnaHQgPT09IG8ubWFyZ2luTGVmdCAmJiBvLm1hcmdpblRvcCA9PT0gby5tYXJnaW5SaWdodCkge1xyXG4gICAgICAgIG8ubWFyZ2luID0gby5tYXJnaW5Ub3A7XHJcbiAgICAgICAgZGVsZXRlIG8ubWFyZ2luVG9wOyBkZWxldGUgby5tYXJnaW5SaWdodDsgZGVsZXRlIG8ubWFyZ2luQm90dG9tOyBkZWxldGUgby5tYXJnaW5MZWZ0O1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChvLnJ0bCA9PT0gKHRoaXMuZWwuc3R5bGUuZGlyZWN0aW9uID09PSAncnRsJykpIHsgby5ydGwgPSAnYXV0bycgfVxyXG4gICAgICBpZiAodGhpcy5faXNBdXRvQ2VsbEhlaWdodCkge1xyXG4gICAgICAgIG8uY2VsbEhlaWdodCA9ICdhdXRvJ1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLl9hdXRvQ29sdW1uKSB7XHJcbiAgICAgICAgby5jb2x1bW4gPSAnYXV0byc7XHJcbiAgICAgICAgZGVsZXRlIG8uZGlzYWJsZU9uZUNvbHVtbk1vZGU7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3Qgb3JpZ1Nob3cgPSBvLl9hbHdheXNTaG93UmVzaXplSGFuZGxlO1xyXG4gICAgICBkZWxldGUgby5fYWx3YXlzU2hvd1Jlc2l6ZUhhbmRsZTtcclxuICAgICAgaWYgKG9yaWdTaG93ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICBvLmFsd2F5c1Nob3dSZXNpemVIYW5kbGUgPSBvcmlnU2hvdztcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBkZWxldGUgby5hbHdheXNTaG93UmVzaXplSGFuZGxlO1xyXG4gICAgICB9XHJcbiAgICAgIFV0aWxzLnJlbW92ZUludGVybmFsQW5kU2FtZShvLCBncmlkRGVmYXVsdHMpO1xyXG4gICAgICBvLmNoaWxkcmVuID0gbGlzdDtcclxuICAgICAgcmV0dXJuIG87XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGxpc3Q7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBsb2FkIHRoZSB3aWRnZXRzIGZyb20gYSBsaXN0LiBUaGlzIHdpbGwgY2FsbCB1cGRhdGUoKSBvbiBlYWNoIChtYXRjaGluZyBieSBpZCkgb3IgYWRkL3JlbW92ZSB3aWRnZXRzIHRoYXQgYXJlIG5vdCB0aGVyZS5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBsYXlvdXQgbGlzdCBvZiB3aWRnZXRzIGRlZmluaXRpb24gdG8gdXBkYXRlL2NyZWF0ZVxyXG4gICAqIEBwYXJhbSBhZGRBbmRSZW1vdmUgYm9vbGVhbiAoZGVmYXVsdCB0cnVlKSBvciBjYWxsYmFjayBtZXRob2QgY2FuIGJlIHBhc3NlZCB0byBjb250cm9sIGlmIGFuZCBob3cgbWlzc2luZyB3aWRnZXRzIGNhbiBiZSBhZGRlZC9yZW1vdmVkLCBnaXZpbmdcclxuICAgKiB0aGUgdXNlciBjb250cm9sIG9mIGluc2VydGlvbi5cclxuICAgKlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogc2VlIGh0dHA6Ly9ncmlkc3RhY2tqcy5jb20vZGVtby9zZXJpYWxpemF0aW9uLmh0bWxcclxuICAgKiovXHJcbiAgcHVibGljIGxvYWQobGF5b3V0OiBHcmlkU3RhY2tXaWRnZXRbXSwgYWRkUmVtb3ZlOiBib29sZWFuIHwgQWRkUmVtb3ZlRmNuID0gR3JpZFN0YWNrLmFkZFJlbW92ZUNCIHx8IHRydWUpOiBHcmlkU3RhY2sge1xyXG4gICAgbGV0IGl0ZW1zID0gR3JpZFN0YWNrLlV0aWxzLnNvcnQoWy4uLmxheW91dF0sIC0xLCB0aGlzLl9wcmV2Q29sdW1uIHx8IHRoaXMuZ2V0Q29sdW1uKCkpOyAvLyBtYWtlIGNvcHkgYmVmb3JlIHdlIG1vZC9zb3J0XHJcbiAgICB0aGlzLl9pbnNlcnROb3RBcHBlbmQgPSB0cnVlOyAvLyBzaW5jZSBjcmVhdGUgaW4gcmV2ZXJzZSBvcmRlci4uLlxyXG5cclxuICAgIC8vIGlmIHdlJ3JlIGxvYWRpbmcgYSBsYXlvdXQgaW50byBmb3IgZXhhbXBsZSAxIGNvbHVtbiAoX3ByZXZDb2x1bW4gaXMgc2V0IG9ubHkgd2hlbiBnb2luZyB0byAxKSBhbmQgaXRlbXMgZG9uJ3QgZml0LCBtYWtlIHN1cmUgdG8gc2F2ZVxyXG4gICAgLy8gdGhlIG9yaWdpbmFsIHdhbnRlZCBsYXlvdXQgc28gd2UgY2FuIHNjYWxlIGJhY2sgdXAgY29ycmVjdGx5ICMxNDcxXHJcbiAgICBpZiAodGhpcy5fcHJldkNvbHVtbiAmJiB0aGlzLl9wcmV2Q29sdW1uICE9PSB0aGlzLm9wdHMuY29sdW1uICYmIGl0ZW1zLnNvbWUobiA9PiAobi54ICsgbi53KSA+ICh0aGlzLm9wdHMuY29sdW1uIGFzIG51bWJlcikpKSB7XHJcbiAgICAgIHRoaXMuX2lnbm9yZUxheW91dHNOb2RlQ2hhbmdlID0gdHJ1ZTsgLy8gc2tpcCBsYXlvdXQgdXBkYXRlXHJcbiAgICAgIHRoaXMuZW5naW5lLmNhY2hlTGF5b3V0KGl0ZW1zLCB0aGlzLl9wcmV2Q29sdW1uLCB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBpZiBnaXZlbiBhIGRpZmZlcmVudCBjYWxsYmFjaywgdGVtcG9yYWxseSBzZXQgaXQgYXMgZ2xvYmFsIG9wdGlvbiBzbyBjcmVhdGluZyB3aWxsIHVzZSBpdFxyXG4gICAgY29uc3QgcHJldkNCID0gR3JpZFN0YWNrLmFkZFJlbW92ZUNCO1xyXG4gICAgaWYgKHR5cGVvZihhZGRSZW1vdmUpID09PSAnZnVuY3Rpb24nKSBHcmlkU3RhY2suYWRkUmVtb3ZlQ0IgPSBhZGRSZW1vdmUgYXMgQWRkUmVtb3ZlRmNuO1xyXG5cclxuICAgIGxldCByZW1vdmVkOiBHcmlkU3RhY2tOb2RlW10gPSBbXTtcclxuICAgIHRoaXMuYmF0Y2hVcGRhdGUoKTtcclxuXHJcbiAgICAvLyBzZWUgaWYgYW55IGl0ZW1zIGFyZSBtaXNzaW5nIGZyb20gbmV3IGxheW91dCBhbmQgbmVlZCB0byBiZSByZW1vdmVkIGZpcnN0XHJcbiAgICBpZiAoYWRkUmVtb3ZlKSB7XHJcbiAgICAgIGxldCBjb3B5Tm9kZXMgPSBbLi4udGhpcy5lbmdpbmUubm9kZXNdOyAvLyBkb24ndCBsb29wIHRocm91Z2ggYXJyYXkgeW91IG1vZGlmeVxyXG4gICAgICBjb3B5Tm9kZXMuZm9yRWFjaChuID0+IHtcclxuICAgICAgICBsZXQgaXRlbSA9IGl0ZW1zLmZpbmQodyA9PiBuLmlkID09PSB3LmlkKTtcclxuICAgICAgICBpZiAoIWl0ZW0pIHtcclxuICAgICAgICAgIGlmIChHcmlkU3RhY2suYWRkUmVtb3ZlQ0IpXHJcbiAgICAgICAgICAgIEdyaWRTdGFjay5hZGRSZW1vdmVDQih0aGlzLmVsLCBuLCBmYWxzZSwgZmFsc2UpO1xyXG4gICAgICAgICAgcmVtb3ZlZC5wdXNoKG4pOyAvLyBiYXRjaCBrZWVwIHRyYWNrXHJcbiAgICAgICAgICB0aGlzLnJlbW92ZVdpZGdldChuLmVsLCB0cnVlLCBmYWxzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBub3cgYWRkL3VwZGF0ZSB0aGUgd2lkZ2V0c1xyXG4gICAgaXRlbXMuZm9yRWFjaCh3ID0+IHtcclxuICAgICAgbGV0IGl0ZW0gPSAody5pZCAhPT0gdW5kZWZpbmVkKSA/IHRoaXMuZW5naW5lLm5vZGVzLmZpbmQobiA9PiBuLmlkID09PSB3LmlkKSA6IHVuZGVmaW5lZDtcclxuICAgICAgaWYgKGl0ZW0pIHtcclxuICAgICAgICB0aGlzLnVwZGF0ZShpdGVtLmVsLCB3KTtcclxuICAgICAgICBpZiAody5zdWJHcmlkT3B0cz8uY2hpbGRyZW4pIHsgLy8gdXBkYXRlIGFueSBzdWIgZ3JpZCBhcyB3ZWxsXHJcbiAgICAgICAgICBsZXQgc3ViID0gaXRlbS5lbC5xdWVyeVNlbGVjdG9yKCcuZ3JpZC1zdGFjaycpIGFzIEdyaWRIVE1MRWxlbWVudDtcclxuICAgICAgICAgIGlmIChzdWIgJiYgc3ViLmdyaWRzdGFjaykge1xyXG4gICAgICAgICAgICBzdWIuZ3JpZHN0YWNrLmxvYWQody5zdWJHcmlkT3B0cy5jaGlsZHJlbik7IC8vIFRPRE86IHN1cHBvcnQgdXBkYXRpbmcgZ3JpZCBvcHRpb25zID9cclxuICAgICAgICAgICAgdGhpcy5faW5zZXJ0Tm90QXBwZW5kID0gdHJ1ZTsgLy8gZ290IHJlc2V0IGJ5IGFib3ZlIGNhbGxcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSBpZiAoYWRkUmVtb3ZlKSB7XHJcbiAgICAgICAgdGhpcy5hZGRXaWRnZXQodyk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZW5naW5lLnJlbW92ZWROb2RlcyA9IHJlbW92ZWQ7XHJcbiAgICB0aGlzLmJhdGNoVXBkYXRlKGZhbHNlKTtcclxuXHJcbiAgICAvLyBhZnRlciBjb21taXQsIGNsZWFyIHRoYXQgZmxhZ1xyXG4gICAgZGVsZXRlIHRoaXMuX2lnbm9yZUxheW91dHNOb2RlQ2hhbmdlO1xyXG4gICAgZGVsZXRlIHRoaXMuX2luc2VydE5vdEFwcGVuZDtcclxuICAgIHByZXZDQiA/IEdyaWRTdGFjay5hZGRSZW1vdmVDQiA9IHByZXZDQiA6IGRlbGV0ZSBHcmlkU3RhY2suYWRkUmVtb3ZlQ0I7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHVzZSBiZWZvcmUgY2FsbGluZyBhIGJ1bmNoIG9mIGBhZGRXaWRnZXQoKWAgdG8gcHJldmVudCB1bi1uZWNlc3NhcnkgcmVsYXlvdXRzIGluIGJldHdlZW4gKG1vcmUgZWZmaWNpZW50KVxyXG4gICAqIGFuZCBnZXQgYSBzaW5nbGUgZXZlbnQgY2FsbGJhY2suIFlvdSB3aWxsIHNlZSBubyBjaGFuZ2VzIHVudGlsIGBiYXRjaFVwZGF0ZShmYWxzZSlgIGlzIGNhbGxlZC5cclxuICAgKi9cclxuICBwdWJsaWMgYmF0Y2hVcGRhdGUoZmxhZyA9IHRydWUpOiBHcmlkU3RhY2sge1xyXG4gICAgdGhpcy5lbmdpbmUuYmF0Y2hVcGRhdGUoZmxhZyk7XHJcbiAgICBpZiAoIWZsYWcpIHtcclxuICAgICAgdGhpcy5fdHJpZ2dlclJlbW92ZUV2ZW50KCk7XHJcbiAgICAgIHRoaXMuX3RyaWdnZXJBZGRFdmVudCgpO1xyXG4gICAgICB0aGlzLl90cmlnZ2VyQ2hhbmdlRXZlbnQoKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyBjdXJyZW50IGNlbGwgaGVpZ2h0LlxyXG4gICAqL1xyXG4gIHB1YmxpYyBnZXRDZWxsSGVpZ2h0KGZvcmNlUGl4ZWwgPSBmYWxzZSk6IG51bWJlciB7XHJcbiAgICBpZiAodGhpcy5vcHRzLmNlbGxIZWlnaHQgJiYgdGhpcy5vcHRzLmNlbGxIZWlnaHQgIT09ICdhdXRvJyAmJlxyXG4gICAgICAgKCFmb3JjZVBpeGVsIHx8ICF0aGlzLm9wdHMuY2VsbEhlaWdodFVuaXQgfHwgdGhpcy5vcHRzLmNlbGxIZWlnaHRVbml0ID09PSAncHgnKSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5vcHRzLmNlbGxIZWlnaHQgYXMgbnVtYmVyO1xyXG4gICAgfVxyXG4gICAgLy8gZWxzZSBnZXQgZmlyc3QgY2VsbCBoZWlnaHRcclxuICAgIGxldCBlbCA9IHRoaXMuZWwucXVlcnlTZWxlY3RvcignLicgKyB0aGlzLm9wdHMuaXRlbUNsYXNzKSBhcyBIVE1MRWxlbWVudDtcclxuICAgIGlmIChlbCkge1xyXG4gICAgICBsZXQgaGVpZ2h0ID0gVXRpbHMudG9OdW1iZXIoZWwuZ2V0QXR0cmlidXRlKCdncy1oJykpIHx8IDE7IC8vIHNpbmNlIHdlIGRvbid0IHdyaXRlIDEgYW55bW9yZVxyXG4gICAgICByZXR1cm4gTWF0aC5yb3VuZChlbC5vZmZzZXRIZWlnaHQgLyBoZWlnaHQpO1xyXG4gICAgfVxyXG4gICAgLy8gZWxzZSBkbyBlbnRpcmUgZ3JpZCBhbmQgIyBvZiByb3dzIChidXQgZG9lc24ndCB3b3JrIGlmIG1pbi1oZWlnaHQgaXMgdGhlIGFjdHVhbCBjb25zdHJhaW4pXHJcbiAgICBsZXQgcm93cyA9IHBhcnNlSW50KHRoaXMuZWwuZ2V0QXR0cmlidXRlKCdncy1jdXJyZW50LXJvdycpKTtcclxuICAgIHJldHVybiByb3dzID8gTWF0aC5yb3VuZCh0aGlzLmVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodCAvIHJvd3MpIDogdGhpcy5vcHRzLmNlbGxIZWlnaHQgYXMgbnVtYmVyO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXBkYXRlIGN1cnJlbnQgY2VsbCBoZWlnaHQgLSBzZWUgYEdyaWRTdGFja09wdGlvbnMuY2VsbEhlaWdodGAgZm9yIGZvcm1hdC5cclxuICAgKiBUaGlzIG1ldGhvZCByZWJ1aWxkcyBhbiBpbnRlcm5hbCBDU1Mgc3R5bGUgc2hlZXQuXHJcbiAgICogTm90ZTogWW91IGNhbiBleHBlY3QgcGVyZm9ybWFuY2UgaXNzdWVzIGlmIGNhbGwgdGhpcyBtZXRob2QgdG9vIG9mdGVuLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHZhbCB0aGUgY2VsbCBoZWlnaHQuIElmIG5vdCBwYXNzZWQgKHVuZGVmaW5lZCksIGNlbGxzIGNvbnRlbnQgd2lsbCBiZSBtYWRlIHNxdWFyZSAobWF0Y2ggd2lkdGggbWludXMgbWFyZ2luKSxcclxuICAgKiBpZiBwYXNzIDAgdGhlIENTUyB3aWxsIGJlIGdlbmVyYXRlZCBieSB0aGUgYXBwbGljYXRpb24gaW5zdGVhZC5cclxuICAgKiBAcGFyYW0gdXBkYXRlIChPcHRpb25hbCkgaWYgZmFsc2UsIHN0eWxlcyB3aWxsIG5vdCBiZSB1cGRhdGVkXHJcbiAgICpcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqIGdyaWQuY2VsbEhlaWdodCgxMDApOyAvLyBzYW1lIGFzIDEwMHB4XHJcbiAgICogZ3JpZC5jZWxsSGVpZ2h0KCc3MHB4Jyk7XHJcbiAgICogZ3JpZC5jZWxsSGVpZ2h0KGdyaWQuY2VsbFdpZHRoKCkgKiAxLjIpO1xyXG4gICAqL1xyXG4gIHB1YmxpYyBjZWxsSGVpZ2h0KHZhbD86IG51bWJlck9yU3RyaW5nLCB1cGRhdGUgPSB0cnVlKTogR3JpZFN0YWNrIHtcclxuXHJcbiAgICAvLyBpZiBub3QgY2FsbGVkIGludGVybmFsbHksIGNoZWNrIGlmIHdlJ3JlIGNoYW5naW5nIG1vZGVcclxuICAgIGlmICh1cGRhdGUgJiYgdmFsICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgaWYgKHRoaXMuX2lzQXV0b0NlbGxIZWlnaHQgIT09ICh2YWwgPT09ICdhdXRvJykpIHtcclxuICAgICAgICB0aGlzLl9pc0F1dG9DZWxsSGVpZ2h0ID0gKHZhbCA9PT0gJ2F1dG8nKTtcclxuICAgICAgICB0aGlzLl91cGRhdGVXaW5kb3dSZXNpemVFdmVudCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodmFsID09PSAnaW5pdGlhbCcgfHwgdmFsID09PSAnYXV0bycpIHsgdmFsID0gdW5kZWZpbmVkOyB9XHJcblxyXG4gICAgLy8gbWFrZSBpdGVtIGNvbnRlbnQgYmUgc3F1YXJlXHJcbiAgICBpZiAodmFsID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgbGV0IG1hcmdpbkRpZmYgPSAtICh0aGlzLm9wdHMubWFyZ2luUmlnaHQgYXMgbnVtYmVyKSAtICh0aGlzLm9wdHMubWFyZ2luTGVmdCBhcyBudW1iZXIpXHJcbiAgICAgICAgKyAodGhpcy5vcHRzLm1hcmdpblRvcCBhcyBudW1iZXIpICsgKHRoaXMub3B0cy5tYXJnaW5Cb3R0b20gYXMgbnVtYmVyKTtcclxuICAgICAgdmFsID0gdGhpcy5jZWxsV2lkdGgoKSArIG1hcmdpbkRpZmY7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGRhdGEgPSBVdGlscy5wYXJzZUhlaWdodCh2YWwpO1xyXG4gICAgaWYgKHRoaXMub3B0cy5jZWxsSGVpZ2h0VW5pdCA9PT0gZGF0YS51bml0ICYmIHRoaXMub3B0cy5jZWxsSGVpZ2h0ID09PSBkYXRhLmgpIHtcclxuICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcbiAgICB0aGlzLm9wdHMuY2VsbEhlaWdodFVuaXQgPSBkYXRhLnVuaXQ7XHJcbiAgICB0aGlzLm9wdHMuY2VsbEhlaWdodCA9IGRhdGEuaDtcclxuXHJcbiAgICBpZiAodXBkYXRlKSB7XHJcbiAgICAgIHRoaXMuX3VwZGF0ZVN0eWxlcyh0cnVlKTsgLy8gdHJ1ZSA9IGZvcmNlIHJlLWNyZWF0ZSBmb3IgY3VycmVudCAjIG9mIHJvd3NcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIEdldHMgY3VycmVudCBjZWxsIHdpZHRoLiAqL1xyXG4gIHB1YmxpYyBjZWxsV2lkdGgoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLl93aWR0aE9yQ29udGFpbmVyKCkgLyB0aGlzLmdldENvbHVtbigpO1xyXG4gIH1cclxuICAvKiogcmV0dXJuIG91ciBleHBlY3RlZCB3aWR0aCAob3IgcGFyZW50KSBmb3IgMSBjb2x1bW4gY2hlY2sgKi9cclxuICBwcm90ZWN0ZWQgX3dpZHRoT3JDb250YWluZXIoKTogbnVtYmVyIHtcclxuICAgIC8vIHVzZSBgb2Zmc2V0V2lkdGhgIG9yIGBjbGllbnRXaWR0aGAgKG5vIHNjcm9sbGJhcikgP1xyXG4gICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjEwNjQxMDEvdW5kZXJzdGFuZGluZy1vZmZzZXR3aWR0aC1jbGllbnR3aWR0aC1zY3JvbGx3aWR0aC1hbmQtaGVpZ2h0LXJlc3BlY3RpdmVseVxyXG4gICAgcmV0dXJuICh0aGlzLmVsLmNsaWVudFdpZHRoIHx8IHRoaXMuZWwucGFyZW50RWxlbWVudC5jbGllbnRXaWR0aCB8fCB3aW5kb3cuaW5uZXJXaWR0aCk7XHJcbiAgfVxyXG5cclxuICAvKiogcmUtbGF5b3V0IGdyaWQgaXRlbXMgdG8gcmVjbGFpbSBhbnkgZW1wdHkgc3BhY2UgKi9cclxuICBwdWJsaWMgY29tcGFjdCgpOiBHcmlkU3RhY2sge1xyXG4gICAgdGhpcy5lbmdpbmUuY29tcGFjdCgpO1xyXG4gICAgdGhpcy5fdHJpZ2dlckNoYW5nZUV2ZW50KCk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHNldCB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gdGhlIGdyaWQuIFdpbGwgdXBkYXRlIGV4aXN0aW5nIHdpZGdldHMgdG8gY29uZm9ybSB0byBuZXcgbnVtYmVyIG9mIGNvbHVtbnMsXHJcbiAgICogYXMgd2VsbCBhcyBjYWNoZSB0aGUgb3JpZ2luYWwgbGF5b3V0IHNvIHlvdSBjYW4gcmV2ZXJ0IGJhY2sgdG8gcHJldmlvdXMgcG9zaXRpb25zIHdpdGhvdXQgbG9zcy5cclxuICAgKiBSZXF1aXJlcyBgZ3JpZHN0YWNrLWV4dHJhLmNzc2Agb3IgYGdyaWRzdGFjay1leHRyYS5taW4uY3NzYCBmb3IgWzItMTFdLFxyXG4gICAqIGVsc2UgeW91IHdpbGwgbmVlZCB0byBnZW5lcmF0ZSBjb3JyZWN0IENTUyAoc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ncmlkc3RhY2svZ3JpZHN0YWNrLmpzI2NoYW5nZS1ncmlkLWNvbHVtbnMpXHJcbiAgICogQHBhcmFtIGNvbHVtbiAtIEludGVnZXIgPiAwIChkZWZhdWx0IDEyKS5cclxuICAgKiBAcGFyYW0gbGF5b3V0IHNwZWNpZnkgdGhlIHR5cGUgb2YgcmUtbGF5b3V0IHRoYXQgd2lsbCBoYXBwZW4gKHBvc2l0aW9uLCBzaXplLCBldGMuLi4pLlxyXG4gICAqIE5vdGU6IGl0ZW1zIHdpbGwgbmV2ZXIgYmUgb3V0c2lkZSBvZiB0aGUgY3VycmVudCBjb2x1bW4gYm91bmRhcmllcy4gZGVmYXVsdCAobW92ZVNjYWxlKS4gSWdub3JlZCBmb3IgMSBjb2x1bW5cclxuICAgKi9cclxuICBwdWJsaWMgY29sdW1uKGNvbHVtbjogbnVtYmVyLCBsYXlvdXQ6IENvbHVtbk9wdGlvbnMgPSAnbW92ZVNjYWxlJyk6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAoY29sdW1uIDwgMSB8fCB0aGlzLm9wdHMuY29sdW1uID09PSBjb2x1bW4pIHJldHVybiB0aGlzO1xyXG4gICAgbGV0IG9sZENvbHVtbiA9IHRoaXMuZ2V0Q29sdW1uKCk7XHJcblxyXG4gICAgLy8gaWYgd2UgZ28gaW50byAxIGNvbHVtbiBtb2RlICh3aGljaCBoYXBwZW5zIGlmIHdlJ3JlIHNpemVkIGxlc3MgdGhhbiBtaW5XIHVubGVzcyBkaXNhYmxlT25lQ29sdW1uTW9kZSBpcyBvbilcclxuICAgIC8vIHRoZW4gcmVtZW1iZXIgdGhlIG9yaWdpbmFsIGNvbHVtbnMgc28gd2UgY2FuIHJlc3RvcmUuXHJcbiAgICBpZiAoY29sdW1uID09PSAxKSB7XHJcbiAgICAgIHRoaXMuX3ByZXZDb2x1bW4gPSBvbGRDb2x1bW47XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBkZWxldGUgdGhpcy5fcHJldkNvbHVtbjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoJ2dzLScgKyBvbGRDb2x1bW4pO1xyXG4gICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKCdncy0nICsgY29sdW1uKTtcclxuICAgIHRoaXMub3B0cy5jb2x1bW4gPSB0aGlzLmVuZ2luZS5jb2x1bW4gPSBjb2x1bW47XHJcblxyXG4gICAgLy8gdXBkYXRlIHRoZSBpdGVtcyBub3cgLSBzZWUgaWYgdGhlIGRvbSBvcmRlciBub2RlcyBzaG91bGQgYmUgcGFzc2VkIGluc3RlYWQgKGVsc2UgZGVmYXVsdCB0byBjdXJyZW50IGxpc3QpXHJcbiAgICBsZXQgZG9tTm9kZXM6IEdyaWRTdGFja05vZGVbXTtcclxuICAgIGlmIChjb2x1bW4gPT09IDEgJiYgdGhpcy5vcHRzLm9uZUNvbHVtbk1vZGVEb21Tb3J0KSB7XHJcbiAgICAgIGRvbU5vZGVzID0gW107XHJcbiAgICAgIHRoaXMuZ2V0R3JpZEl0ZW1zKCkuZm9yRWFjaChlbCA9PiB7IC8vIGdldCBkb20gZWxlbWVudHMgaW4gb3JkZXJcclxuICAgICAgICBpZiAoZWwuZ3JpZHN0YWNrTm9kZSkgeyBkb21Ob2Rlcy5wdXNoKGVsLmdyaWRzdGFja05vZGUpOyB9XHJcbiAgICAgIH0pO1xyXG4gICAgICBpZiAoIWRvbU5vZGVzLmxlbmd0aCkgeyBkb21Ob2RlcyA9IHVuZGVmaW5lZDsgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5lbmdpbmUudXBkYXRlTm9kZVdpZHRocyhvbGRDb2x1bW4sIGNvbHVtbiwgZG9tTm9kZXMsIGxheW91dCk7XHJcbiAgICBpZiAodGhpcy5faXNBdXRvQ2VsbEhlaWdodCkgdGhpcy5jZWxsSGVpZ2h0KCk7XHJcblxyXG4gICAgLy8gYW5kIHRyaWdnZXIgb3VyIGV2ZW50IGxhc3QuLi5cclxuICAgIHRoaXMuX2lnbm9yZUxheW91dHNOb2RlQ2hhbmdlID0gdHJ1ZTsgLy8gc2tpcCBsYXlvdXQgdXBkYXRlXHJcbiAgICB0aGlzLl90cmlnZ2VyQ2hhbmdlRXZlbnQoKTtcclxuICAgIGRlbGV0ZSB0aGlzLl9pZ25vcmVMYXlvdXRzTm9kZUNoYW5nZTtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGdldCB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gdGhlIGdyaWQgKGRlZmF1bHQgMTIpXHJcbiAgICovXHJcbiAgcHVibGljIGdldENvbHVtbigpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMub3B0cy5jb2x1bW4gYXMgbnVtYmVyO1xyXG4gIH1cclxuXHJcbiAgLyoqIHJldHVybnMgYW4gYXJyYXkgb2YgZ3JpZCBIVE1MIGVsZW1lbnRzIChubyBwbGFjZWhvbGRlcikgLSB1c2VkIHRvIGl0ZXJhdGUgdGhyb3VnaCBvdXIgY2hpbGRyZW4gaW4gRE9NIG9yZGVyICovXHJcbiAgcHVibGljIGdldEdyaWRJdGVtcygpOiBHcmlkSXRlbUhUTUxFbGVtZW50W10ge1xyXG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5lbC5jaGlsZHJlbilcclxuICAgICAgLmZpbHRlcigoZWw6IEhUTUxFbGVtZW50KSA9PiBlbC5tYXRjaGVzKCcuJyArIHRoaXMub3B0cy5pdGVtQ2xhc3MpICYmICFlbC5tYXRjaGVzKCcuJyArIHRoaXMub3B0cy5wbGFjZWhvbGRlckNsYXNzKSkgYXMgR3JpZEl0ZW1IVE1MRWxlbWVudFtdO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVzdHJveXMgYSBncmlkIGluc3RhbmNlLiBETyBOT1QgQ0FMTCBhbnkgbWV0aG9kcyBvciBhY2Nlc3MgYW55IHZhcnMgYWZ0ZXIgdGhpcyBhcyBpdCB3aWxsIGZyZWUgdXAgbWVtYmVycy5cclxuICAgKiBAcGFyYW0gcmVtb3ZlRE9NIGlmIGBmYWxzZWAgZ3JpZCBhbmQgaXRlbXMgSFRNTCBlbGVtZW50cyB3aWxsIG5vdCBiZSByZW1vdmVkIGZyb20gdGhlIERPTSAoT3B0aW9uYWwuIERlZmF1bHQgYHRydWVgKS5cclxuICAgKi9cclxuICBwdWJsaWMgZGVzdHJveShyZW1vdmVET00gPSB0cnVlKTogR3JpZFN0YWNrIHtcclxuICAgIGlmICghdGhpcy5lbCkgcmV0dXJuOyAvLyBwcmV2ZW50IG11bHRpcGxlIGNhbGxzXHJcbiAgICB0aGlzLm9mZkFsbCgpO1xyXG4gICAgdGhpcy5fdXBkYXRlV2luZG93UmVzaXplRXZlbnQodHJ1ZSk7XHJcbiAgICB0aGlzLnNldFN0YXRpYyh0cnVlLCBmYWxzZSk7IC8vIHBlcm1hbmVudGx5IHJlbW92ZXMgREQgYnV0IGRvbid0IHNldCBDU1MgY2xhc3MgKHdlJ3JlIGdvaW5nIGF3YXkpXHJcbiAgICB0aGlzLnNldEFuaW1hdGlvbihmYWxzZSk7XHJcbiAgICBpZiAoIXJlbW92ZURPTSkge1xyXG4gICAgICB0aGlzLnJlbW92ZUFsbChyZW1vdmVET00pO1xyXG4gICAgICB0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUodGhpcy5fc3R5bGVTaGVldENsYXNzKTtcclxuICAgICAgdGhpcy5lbC5yZW1vdmVBdHRyaWJ1dGUoJ2dzLWN1cnJlbnQtcm93Jyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5lbCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9yZW1vdmVTdHlsZXNoZWV0KCk7XHJcbiAgICBpZiAodGhpcy5wYXJlbnRHcmlkSXRlbSkgZGVsZXRlIHRoaXMucGFyZW50R3JpZEl0ZW0uc3ViR3JpZDtcclxuICAgIGRlbGV0ZSB0aGlzLnBhcmVudEdyaWRJdGVtO1xyXG4gICAgZGVsZXRlIHRoaXMub3B0cztcclxuICAgIGRlbGV0ZSB0aGlzLl9wbGFjZWhvbGRlcjtcclxuICAgIGRlbGV0ZSB0aGlzLmVuZ2luZTtcclxuICAgIGRlbGV0ZSB0aGlzLmVsLmdyaWRzdGFjazsgLy8gcmVtb3ZlIGNpcmN1bGFyIGRlcGVuZGVuY3kgdGhhdCB3b3VsZCBwcmV2ZW50IGEgZnJlZWluZ1xyXG4gICAgZGVsZXRlIHRoaXMuZWw7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGVuYWJsZS9kaXNhYmxlIGZsb2F0aW5nIHdpZGdldHMgKGRlZmF1bHQ6IGBmYWxzZWApIFNlZSBbZXhhbXBsZV0oaHR0cDovL2dyaWRzdGFja2pzLmNvbS9kZW1vL2Zsb2F0Lmh0bWwpXHJcbiAgICovXHJcbiAgcHVibGljIGZsb2F0KHZhbDogYm9vbGVhbik6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAodGhpcy5vcHRzLmZsb2F0ICE9PSB2YWwpIHtcclxuICAgICAgdGhpcy5vcHRzLmZsb2F0ID0gdGhpcy5lbmdpbmUuZmxvYXQgPSB2YWw7XHJcbiAgICAgIHRoaXMuX3RyaWdnZXJDaGFuZ2VFdmVudCgpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBnZXQgdGhlIGN1cnJlbnQgZmxvYXQgbW9kZVxyXG4gICAqL1xyXG4gIHB1YmxpYyBnZXRGbG9hdCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmVuZ2luZS5mbG9hdDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgcG9zaXRpb24gb2YgdGhlIGNlbGwgdW5kZXIgYSBwaXhlbCBvbiBzY3JlZW4uXHJcbiAgICogQHBhcmFtIHBvc2l0aW9uIHRoZSBwb3NpdGlvbiBvZiB0aGUgcGl4ZWwgdG8gcmVzb2x2ZSBpblxyXG4gICAqIGFic29sdXRlIGNvb3JkaW5hdGVzLCBhcyBhbiBvYmplY3Qgd2l0aCB0b3AgYW5kIGxlZnQgcHJvcGVydGllc1xyXG4gICAqIEBwYXJhbSB1c2VEb2NSZWxhdGl2ZSBpZiB0cnVlLCB2YWx1ZSB3aWxsIGJlIGJhc2VkIG9uIGRvY3VtZW50IHBvc2l0aW9uIHZzIHBhcmVudCBwb3NpdGlvbiAoT3B0aW9uYWwuIERlZmF1bHQgZmFsc2UpLlxyXG4gICAqIFVzZWZ1bCB3aGVuIGdyaWQgaXMgd2l0aGluIGBwb3NpdGlvbjogcmVsYXRpdmVgIGVsZW1lbnRcclxuICAgKlxyXG4gICAqIFJldHVybnMgYW4gb2JqZWN0IHdpdGggcHJvcGVydGllcyBgeGAgYW5kIGB5YCBpLmUuIHRoZSBjb2x1bW4gYW5kIHJvdyBpbiB0aGUgZ3JpZC5cclxuICAgKi9cclxuICBwdWJsaWMgZ2V0Q2VsbEZyb21QaXhlbChwb3NpdGlvbjogTW91c2VQb3NpdGlvbiwgdXNlRG9jUmVsYXRpdmUgPSBmYWxzZSk6IENlbGxQb3NpdGlvbiB7XHJcbiAgICBsZXQgYm94ID0gdGhpcy5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIC8vIGNvbnNvbGUubG9nKGBnZXRCb3VuZGluZ0NsaWVudFJlY3QgbGVmdDogJHtib3gubGVmdH0gdG9wOiAke2JveC50b3B9IHc6ICR7Ym94Lnd9IGg6ICR7Ym94Lmh9YClcclxuICAgIGxldCBjb250YWluZXJQb3M6IHt0b3A6IG51bWJlciwgbGVmdDogbnVtYmVyfTtcclxuICAgIGlmICh1c2VEb2NSZWxhdGl2ZSkge1xyXG4gICAgICBjb250YWluZXJQb3MgPSB7dG9wOiBib3gudG9wICsgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCwgbGVmdDogYm94LmxlZnR9O1xyXG4gICAgICAvLyBjb25zb2xlLmxvZyhgZ2V0Q2VsbEZyb21QaXhlbCBzY3JvbGxUb3A6ICR7ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcH1gKVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29udGFpbmVyUG9zID0ge3RvcDogdGhpcy5lbC5vZmZzZXRUb3AsIGxlZnQ6IHRoaXMuZWwub2Zmc2V0TGVmdH1cclxuICAgICAgLy8gY29uc29sZS5sb2coYGdldENlbGxGcm9tUGl4ZWwgb2Zmc2V0VG9wOiAke2NvbnRhaW5lclBvcy5sZWZ0fSBvZmZzZXRMZWZ0OiAke2NvbnRhaW5lclBvcy50b3B9YClcclxuICAgIH1cclxuICAgIGxldCByZWxhdGl2ZUxlZnQgPSBwb3NpdGlvbi5sZWZ0IC0gY29udGFpbmVyUG9zLmxlZnQ7XHJcbiAgICBsZXQgcmVsYXRpdmVUb3AgPSBwb3NpdGlvbi50b3AgLSBjb250YWluZXJQb3MudG9wO1xyXG5cclxuICAgIGxldCBjb2x1bW5XaWR0aCA9IChib3gud2lkdGggLyB0aGlzLmdldENvbHVtbigpKTtcclxuICAgIGxldCByb3dIZWlnaHQgPSAoYm94LmhlaWdodCAvIHBhcnNlSW50KHRoaXMuZWwuZ2V0QXR0cmlidXRlKCdncy1jdXJyZW50LXJvdycpKSk7XHJcblxyXG4gICAgcmV0dXJuIHt4OiBNYXRoLmZsb29yKHJlbGF0aXZlTGVmdCAvIGNvbHVtbldpZHRoKSwgeTogTWF0aC5mbG9vcihyZWxhdGl2ZVRvcCAvIHJvd0hlaWdodCl9O1xyXG4gIH1cclxuXHJcbiAgLyoqIHJldHVybnMgdGhlIGN1cnJlbnQgbnVtYmVyIG9mIHJvd3MsIHdoaWNoIHdpbGwgYmUgYXQgbGVhc3QgYG1pblJvd2AgaWYgc2V0ICovXHJcbiAgcHVibGljIGdldFJvdygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIE1hdGgubWF4KHRoaXMuZW5naW5lLmdldFJvdygpLCB0aGlzLm9wdHMubWluUm93KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyBpZiBzcGVjaWZpZWQgYXJlYSBpcyBlbXB0eS5cclxuICAgKiBAcGFyYW0geCB0aGUgcG9zaXRpb24geC5cclxuICAgKiBAcGFyYW0geSB0aGUgcG9zaXRpb24geS5cclxuICAgKiBAcGFyYW0gdyB0aGUgd2lkdGggb2YgdG8gY2hlY2tcclxuICAgKiBAcGFyYW0gaCB0aGUgaGVpZ2h0IG9mIHRvIGNoZWNrXHJcbiAgICovXHJcbiAgcHVibGljIGlzQXJlYUVtcHR5KHg6IG51bWJlciwgeTogbnVtYmVyLCB3OiBudW1iZXIsIGg6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZW5naW5lLmlzQXJlYUVtcHR5KHgsIHksIHcsIGgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSWYgeW91IGFkZCBlbGVtZW50cyB0byB5b3VyIGdyaWQgYnkgaGFuZCAob3IgaGF2ZSBzb21lIGZyYW1ld29yayBjcmVhdGluZyBET00pLCB5b3UgaGF2ZSB0byB0ZWxsIGdyaWRzdGFjayBhZnRlcndhcmRzIHRvIG1ha2UgdGhlbSB3aWRnZXRzLlxyXG4gICAqIElmIHlvdSB3YW50IGdyaWRzdGFjayB0byBhZGQgdGhlIGVsZW1lbnRzIGZvciB5b3UsIHVzZSBgYWRkV2lkZ2V0KClgIGluc3RlYWQuXHJcbiAgICogTWFrZXMgdGhlIGdpdmVuIGVsZW1lbnQgYSB3aWRnZXQgYW5kIHJldHVybnMgaXQuXHJcbiAgICogQHBhcmFtIGVscyB3aWRnZXQgb3Igc2luZ2xlIHNlbGVjdG9yIHRvIGNvbnZlcnQuXHJcbiAgICogQHBhcmFtIG9wdGlvbnMgd2lkZ2V0IGRlZmluaXRpb24gdG8gdXNlIGluc3RlYWQgb2YgcmVhZGluZyBhdHRyaWJ1dGVzIG9yIHVzaW5nIGRlZmF1bHQgc2l6aW5nIHZhbHVlc1xyXG4gICAqXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiBsZXQgZ3JpZCA9IEdyaWRTdGFjay5pbml0KCk7XHJcbiAgICogZ3JpZC5lbC5hcHBlbmRDaGlsZCgnPGRpdiBpZD1cIjFcIiBncy13PVwiM1wiPjwvZGl2PicpO1xyXG4gICAqIGdyaWQuZWwuYXBwZW5kQ2hpbGQoJzxkaXYgaWQ9XCIyXCI+PC9kaXY+Jyk7XHJcbiAgICogZ3JpZC5tYWtlV2lkZ2V0KCcxJyk7XHJcbiAgICogZ3JpZC5tYWtlV2lkZ2V0KCcyJywge3c6MiwgY29udGVudDogJ2hlbGxvJ30pO1xyXG4gICAqL1xyXG4gIHB1YmxpYyBtYWtlV2lkZ2V0KGVsczogR3JpZFN0YWNrRWxlbWVudCwgb3B0aW9ucz86IEdyaWRTdGFja1dpZGdldCk6IEdyaWRJdGVtSFRNTEVsZW1lbnQge1xyXG4gICAgbGV0IGVsID0gR3JpZFN0YWNrLmdldEVsZW1lbnQoZWxzKTtcclxuICAgIHRoaXMuX3ByZXBhcmVFbGVtZW50KGVsLCB0cnVlLCBvcHRpb25zKTtcclxuICAgIHRoaXMuX3VwZGF0ZUNvbnRhaW5lckhlaWdodCgpO1xyXG5cclxuICAgIC8vIHNlZSBpZiB0aGVyZSBpcyBhIHN1Yi1ncmlkIHRvIGNyZWF0ZVxyXG4gICAgY29uc3Qgbm9kZSA9IGVsLmdyaWRzdGFja05vZGU7XHJcbiAgICBpZiAobm9kZS5zdWJHcmlkT3B0cykge1xyXG4gICAgICB0aGlzLm1ha2VTdWJHcmlkKGVsLCBub2RlLnN1YkdyaWRPcHRzLCB1bmRlZmluZWQsIGZhbHNlKTsgLy8gbm9kZS5zdWJHcmlkIHdpbGwgYmUgdXNlZCBhcyBvcHRpb24gaW4gbWV0aG9kLCBubyBuZWVkIHRvIHBhc3NcclxuICAgIH1cclxuXHJcbiAgICAvLyBpZiB3ZSdyZSBhZGRpbmcgYW4gaXRlbSBpbnRvIDEgY29sdW1uIChfcHJldkNvbHVtbiBpcyBzZXQgb25seSB3aGVuIGdvaW5nIHRvIDEpIG1ha2Ugc3VyZVxyXG4gICAgLy8gd2UgZG9uJ3Qgb3ZlcnJpZGUgdGhlIGxhcmdlciAxMiBjb2x1bW4gbGF5b3V0IHRoYXQgd2FzIGFscmVhZHkgc2F2ZWQuICMxOTg1XHJcbiAgICBpZiAodGhpcy5fcHJldkNvbHVtbiAmJiB0aGlzLm9wdHMuY29sdW1uID09PSAxKSB7XHJcbiAgICAgIHRoaXMuX2lnbm9yZUxheW91dHNOb2RlQ2hhbmdlID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHRoaXMuX3RyaWdnZXJBZGRFdmVudCgpO1xyXG4gICAgdGhpcy5fdHJpZ2dlckNoYW5nZUV2ZW50KCk7XHJcbiAgICBkZWxldGUgdGhpcy5faWdub3JlTGF5b3V0c05vZGVDaGFuZ2U7XHJcblxyXG4gICAgcmV0dXJuIGVsO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXZlbnQgaGFuZGxlciB0aGF0IGV4dHJhY3RzIG91ciBDdXN0b21FdmVudCBkYXRhIG91dCBhdXRvbWF0aWNhbGx5IGZvciByZWNlaXZpbmcgY3VzdG9tXHJcbiAgICogbm90aWZpY2F0aW9ucyAoc2VlIGRvYyBmb3Igc3VwcG9ydGVkIGV2ZW50cylcclxuICAgKiBAcGFyYW0gbmFtZSBvZiB0aGUgZXZlbnQgKHNlZSBwb3NzaWJsZSB2YWx1ZXMpIG9yIGxpc3Qgb2YgbmFtZXMgc3BhY2Ugc2VwYXJhdGVkXHJcbiAgICogQHBhcmFtIGNhbGxiYWNrIGZ1bmN0aW9uIGNhbGxlZCB3aXRoIGV2ZW50IGFuZCBvcHRpb25hbCBzZWNvbmQvdGhpcmQgcGFyYW1cclxuICAgKiAoc2VlIFJFQURNRSBkb2N1bWVudGF0aW9uIGZvciBlYWNoIHNpZ25hdHVyZSkuXHJcbiAgICpcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqIGdyaWQub24oJ2FkZGVkJywgZnVuY3Rpb24oZSwgaXRlbXMpIHsgbG9nKCdhZGRlZCAnLCBpdGVtcyl9ICk7XHJcbiAgICogb3JcclxuICAgKiBncmlkLm9uKCdhZGRlZCByZW1vdmVkIGNoYW5nZScsIGZ1bmN0aW9uKGUsIGl0ZW1zKSB7IGxvZyhlLnR5cGUsIGl0ZW1zKX0gKTtcclxuICAgKlxyXG4gICAqIE5vdGU6IGluIHNvbWUgY2FzZXMgaXQgaXMgdGhlIHNhbWUgYXMgY2FsbGluZyBuYXRpdmUgaGFuZGxlciBhbmQgcGFyc2luZyB0aGUgZXZlbnQuXHJcbiAgICogZ3JpZC5lbC5hZGRFdmVudExpc3RlbmVyKCdhZGRlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7IGxvZygnYWRkZWQgJywgZXZlbnQuZGV0YWlsKX0gKTtcclxuICAgKlxyXG4gICAqL1xyXG4gIHB1YmxpYyBvbihuYW1lOiBHcmlkU3RhY2tFdmVudCwgY2FsbGJhY2s6IEdyaWRTdGFja0V2ZW50SGFuZGxlckNhbGxiYWNrKTogR3JpZFN0YWNrIHtcclxuICAgIC8vIGNoZWNrIGZvciBhcnJheSBvZiBuYW1lcyBiZWluZyBwYXNzZWQgaW5zdGVhZFxyXG4gICAgaWYgKG5hbWUuaW5kZXhPZignICcpICE9PSAtMSkge1xyXG4gICAgICBsZXQgbmFtZXMgPSBuYW1lLnNwbGl0KCcgJykgYXMgR3JpZFN0YWNrRXZlbnRbXTtcclxuICAgICAgbmFtZXMuZm9yRWFjaChuYW1lID0+IHRoaXMub24obmFtZSwgY2FsbGJhY2spKTtcclxuICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG5hbWUgPT09ICdjaGFuZ2UnIHx8IG5hbWUgPT09ICdhZGRlZCcgfHwgbmFtZSA9PT0gJ3JlbW92ZWQnIHx8IG5hbWUgPT09ICdlbmFibGUnIHx8IG5hbWUgPT09ICdkaXNhYmxlJykge1xyXG4gICAgICAvLyBuYXRpdmUgQ3VzdG9tRXZlbnQgaGFuZGxlcnMgLSBjYXNoIHRoZSBnZW5lcmljIGhhbmRsZXJzIHNvIHdlIGNhbiBlYXNpbHkgcmVtb3ZlXHJcbiAgICAgIGxldCBub0RhdGEgPSAobmFtZSA9PT0gJ2VuYWJsZScgfHwgbmFtZSA9PT0gJ2Rpc2FibGUnKTtcclxuICAgICAgaWYgKG5vRGF0YSkge1xyXG4gICAgICAgIHRoaXMuX2dzRXZlbnRIYW5kbGVyW25hbWVdID0gKGV2ZW50OiBFdmVudCkgPT4gKGNhbGxiYWNrIGFzIEdyaWRTdGFja0V2ZW50SGFuZGxlcikoZXZlbnQpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuX2dzRXZlbnRIYW5kbGVyW25hbWVdID0gKGV2ZW50OiBDdXN0b21FdmVudCkgPT4gKGNhbGxiYWNrIGFzIEdyaWRTdGFja05vZGVzSGFuZGxlcikoZXZlbnQsIGV2ZW50LmRldGFpbCk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKG5hbWUsIHRoaXMuX2dzRXZlbnRIYW5kbGVyW25hbWVdKTtcclxuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ2RyYWcnIHx8IG5hbWUgPT09ICdkcmFnc3RhcnQnIHx8IG5hbWUgPT09ICdkcmFnc3RvcCcgfHwgbmFtZSA9PT0gJ3Jlc2l6ZXN0YXJ0JyB8fCBuYW1lID09PSAncmVzaXplJyB8fCBuYW1lID09PSAncmVzaXplc3RvcCcgfHwgbmFtZSA9PT0gJ2Ryb3BwZWQnKSB7XHJcbiAgICAgIC8vIGRyYWcmZHJvcCBzdG9wIGV2ZW50cyBORUVEIHRvIGJlIGNhbGwgdGhlbSBBRlRFUiB3ZSB1cGRhdGUgbm9kZSBhdHRyaWJ1dGVzIHNvIGhhbmRsZSB0aGVtIG91cnNlbGYuXHJcbiAgICAgIC8vIGRvIHNhbWUgZm9yIHN0YXJ0IGV2ZW50IHRvIG1ha2UgaXQgZWFzaWVyLi4uXHJcbiAgICAgIHRoaXMuX2dzRXZlbnRIYW5kbGVyW25hbWVdID0gY2FsbGJhY2s7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zb2xlLmxvZygnR3JpZFN0YWNrLm9uKCcgKyBuYW1lICsgJykgZXZlbnQgbm90IHN1cHBvcnRlZCwgYnV0IHlvdSBjYW4gc3RpbGwgdXNlICQoXCIuZ3JpZC1zdGFja1wiKS5vbiguLi4pIHdoaWxlIGpxdWVyeS11aSBpcyBzdGlsbCB1c2VkIGludGVybmFsbHkuJyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHVuc3Vic2NyaWJlIGZyb20gdGhlICdvbicgZXZlbnQgYmVsb3dcclxuICAgKiBAcGFyYW0gbmFtZSBvZiB0aGUgZXZlbnQgKHNlZSBwb3NzaWJsZSB2YWx1ZXMpXHJcbiAgICovXHJcbiAgcHVibGljIG9mZihuYW1lOiBHcmlkU3RhY2tFdmVudCk6IEdyaWRTdGFjayB7XHJcbiAgICAvLyBjaGVjayBmb3IgYXJyYXkgb2YgbmFtZXMgYmVpbmcgcGFzc2VkIGluc3RlYWRcclxuICAgIGlmIChuYW1lLmluZGV4T2YoJyAnKSAhPT0gLTEpIHtcclxuICAgICAgbGV0IG5hbWVzID0gbmFtZS5zcGxpdCgnICcpIGFzIEdyaWRTdGFja0V2ZW50W107XHJcbiAgICAgIG5hbWVzLmZvckVhY2gobmFtZSA9PiB0aGlzLm9mZihuYW1lKSk7XHJcbiAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChuYW1lID09PSAnY2hhbmdlJyB8fCBuYW1lID09PSAnYWRkZWQnIHx8IG5hbWUgPT09ICdyZW1vdmVkJyB8fCBuYW1lID09PSAnZW5hYmxlJyB8fCBuYW1lID09PSAnZGlzYWJsZScpIHtcclxuICAgICAgLy8gcmVtb3ZlIG5hdGl2ZSBDdXN0b21FdmVudCBoYW5kbGVyc1xyXG4gICAgICBpZiAodGhpcy5fZ3NFdmVudEhhbmRsZXJbbmFtZV0pIHtcclxuICAgICAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgdGhpcy5fZ3NFdmVudEhhbmRsZXJbbmFtZV0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBkZWxldGUgdGhpcy5fZ3NFdmVudEhhbmRsZXJbbmFtZV07XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKiogcmVtb3ZlIGFsbCBldmVudCBoYW5kbGVycyAqL1xyXG4gIHB1YmxpYyBvZmZBbGwoKTogR3JpZFN0YWNrIHtcclxuICAgIE9iamVjdC5rZXlzKHRoaXMuX2dzRXZlbnRIYW5kbGVyKS5mb3JFYWNoKGtleSA9PiB0aGlzLm9mZihrZXkpKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVtb3ZlcyB3aWRnZXQgZnJvbSB0aGUgZ3JpZC5cclxuICAgKiBAcGFyYW0gZWwgIHdpZGdldCBvciBzZWxlY3RvciB0byBtb2RpZnlcclxuICAgKiBAcGFyYW0gcmVtb3ZlRE9NIGlmIGBmYWxzZWAgRE9NIGVsZW1lbnQgd29uJ3QgYmUgcmVtb3ZlZCBmcm9tIHRoZSB0cmVlIChEZWZhdWx0PyB0cnVlKS5cclxuICAgKiBAcGFyYW0gdHJpZ2dlckV2ZW50IGlmIGBmYWxzZWAgKHF1aWV0IG1vZGUpIGVsZW1lbnQgd2lsbCBub3QgYmUgYWRkZWQgdG8gcmVtb3ZlZCBsaXN0IGFuZCBubyAncmVtb3ZlZCcgY2FsbGJhY2tzIHdpbGwgYmUgY2FsbGVkIChEZWZhdWx0PyB0cnVlKS5cclxuICAgKi9cclxuICBwdWJsaWMgcmVtb3ZlV2lkZ2V0KGVsczogR3JpZFN0YWNrRWxlbWVudCwgcmVtb3ZlRE9NID0gdHJ1ZSwgdHJpZ2dlckV2ZW50ID0gdHJ1ZSk6IEdyaWRTdGFjayB7XHJcbiAgICBHcmlkU3RhY2suZ2V0RWxlbWVudHMoZWxzKS5mb3JFYWNoKGVsID0+IHtcclxuICAgICAgaWYgKGVsLnBhcmVudEVsZW1lbnQgJiYgZWwucGFyZW50RWxlbWVudCAhPT0gdGhpcy5lbCkgcmV0dXJuOyAvLyBub3Qgb3VyIGNoaWxkIVxyXG4gICAgICBsZXQgbm9kZSA9IGVsLmdyaWRzdGFja05vZGU7XHJcbiAgICAgIC8vIEZvciBNZXRlb3Igc3VwcG9ydDogaHR0cHM6Ly9naXRodWIuY29tL2dyaWRzdGFjay9ncmlkc3RhY2suanMvcHVsbC8yNzJcclxuICAgICAgaWYgKCFub2RlKSB7XHJcbiAgICAgICAgbm9kZSA9IHRoaXMuZW5naW5lLm5vZGVzLmZpbmQobiA9PiBlbCA9PT0gbi5lbCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCFub2RlKSByZXR1cm47XHJcblxyXG4gICAgICBpZiAoR3JpZFN0YWNrLmFkZFJlbW92ZUNCKSB7XHJcbiAgICAgICAgR3JpZFN0YWNrLmFkZFJlbW92ZUNCKHRoaXMuZWwsIG5vZGUsIGZhbHNlLCBmYWxzZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHJlbW92ZSBvdXIgRE9NIGRhdGEgKGNpcmN1bGFyIGxpbmspIGFuZCBkcmFnJmRyb3AgcGVybWFuZW50bHlcclxuICAgICAgZGVsZXRlIGVsLmdyaWRzdGFja05vZGU7XHJcbiAgICAgIHRoaXMuX3JlbW92ZUREKGVsKTtcclxuXHJcbiAgICAgIHRoaXMuZW5naW5lLnJlbW92ZU5vZGUobm9kZSwgcmVtb3ZlRE9NLCB0cmlnZ2VyRXZlbnQpO1xyXG5cclxuICAgICAgaWYgKHJlbW92ZURPTSAmJiBlbC5wYXJlbnRFbGVtZW50KSB7XHJcbiAgICAgICAgZWwucmVtb3ZlKCk7IC8vIGluIGJhdGNoIG1vZGUgZW5naW5lLnJlbW92ZU5vZGUgZG9lc24ndCBjYWxsIGJhY2sgdG8gcmVtb3ZlIERPTVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIGlmICh0cmlnZ2VyRXZlbnQpIHtcclxuICAgICAgdGhpcy5fdHJpZ2dlclJlbW92ZUV2ZW50KCk7XHJcbiAgICAgIHRoaXMuX3RyaWdnZXJDaGFuZ2VFdmVudCgpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZW1vdmVzIGFsbCB3aWRnZXRzIGZyb20gdGhlIGdyaWQuXHJcbiAgICogQHBhcmFtIHJlbW92ZURPTSBpZiBgZmFsc2VgIERPTSBlbGVtZW50cyB3b24ndCBiZSByZW1vdmVkIGZyb20gdGhlIHRyZWUgKERlZmF1bHQ/IGB0cnVlYCkuXHJcbiAgICovXHJcbiAgcHVibGljIHJlbW92ZUFsbChyZW1vdmVET00gPSB0cnVlKTogR3JpZFN0YWNrIHtcclxuICAgIC8vIGFsd2F5cyByZW1vdmUgb3VyIERPTSBkYXRhIChjaXJjdWxhciBsaW5rKSBiZWZvcmUgbGlzdCBnZXRzIGVtcHRpZWQgYW5kIGRyYWcmZHJvcCBwZXJtYW5lbnRseVxyXG4gICAgdGhpcy5lbmdpbmUubm9kZXMuZm9yRWFjaChuID0+IHtcclxuICAgICAgZGVsZXRlIG4uZWwuZ3JpZHN0YWNrTm9kZTtcclxuICAgICAgdGhpcy5fcmVtb3ZlREQobi5lbCk7XHJcbiAgICB9KTtcclxuICAgIHRoaXMuZW5naW5lLnJlbW92ZUFsbChyZW1vdmVET00pO1xyXG4gICAgdGhpcy5fdHJpZ2dlclJlbW92ZUV2ZW50KCk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvZ2dsZSB0aGUgZ3JpZCBhbmltYXRpb24gc3RhdGUuICBUb2dnbGVzIHRoZSBgZ3JpZC1zdGFjay1hbmltYXRlYCBjbGFzcy5cclxuICAgKiBAcGFyYW0gZG9BbmltYXRlIGlmIHRydWUgdGhlIGdyaWQgd2lsbCBhbmltYXRlLlxyXG4gICAqL1xyXG4gIHB1YmxpYyBzZXRBbmltYXRpb24oZG9BbmltYXRlOiBib29sZWFuKTogR3JpZFN0YWNrIHtcclxuICAgIGlmIChkb0FuaW1hdGUpIHtcclxuICAgICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKCdncmlkLXN0YWNrLWFuaW1hdGUnKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZSgnZ3JpZC1zdGFjay1hbmltYXRlJyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvZ2dsZSB0aGUgZ3JpZCBzdGF0aWMgc3RhdGUsIHdoaWNoIHBlcm1hbmVudGx5IHJlbW92ZXMvYWRkIERyYWcmRHJvcCBzdXBwb3J0LCB1bmxpa2UgZGlzYWJsZSgpL2VuYWJsZSgpIHRoYXQganVzdCB0dXJucyBpdCBvZmYvb24uXHJcbiAgICogQWxzbyB0b2dnbGUgdGhlIGdyaWQtc3RhY2stc3RhdGljIGNsYXNzLlxyXG4gICAqIEBwYXJhbSB2YWwgaWYgdHJ1ZSB0aGUgZ3JpZCBiZWNvbWUgc3RhdGljLlxyXG4gICAqIEBwYXJhbSB1cGRhdGVDbGFzcyB0cnVlIChkZWZhdWx0KSBpZiBjc3MgY2xhc3MgZ2V0cyB1cGRhdGVkXHJcbiAgICogQHBhcmFtIHJlY3Vyc2UgdHJ1ZSAoZGVmYXVsdCkgaWYgc3ViLWdyaWRzIGFsc28gZ2V0IHVwZGF0ZWRcclxuICAgKi9cclxuICBwdWJsaWMgc2V0U3RhdGljKHZhbDogYm9vbGVhbiwgdXBkYXRlQ2xhc3MgPSB0cnVlLCByZWN1cnNlID0gdHJ1ZSk6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAoISF0aGlzLm9wdHMuc3RhdGljR3JpZCA9PT0gdmFsKSByZXR1cm4gdGhpcztcclxuICAgIHZhbCA/IHRoaXMub3B0cy5zdGF0aWNHcmlkID0gdHJ1ZSA6IGRlbGV0ZSB0aGlzLm9wdHMuc3RhdGljR3JpZDtcclxuICAgIHRoaXMuX3NldHVwUmVtb3ZlRHJvcCgpO1xyXG4gICAgdGhpcy5fc2V0dXBBY2NlcHRXaWRnZXQoKTtcclxuICAgIHRoaXMuZW5naW5lLm5vZGVzLmZvckVhY2gobiA9PiB7XHJcbiAgICAgIHRoaXMuX3ByZXBhcmVEcmFnRHJvcEJ5Tm9kZShuKTsgLy8gZWl0aGVyIGRlbGV0ZSBvciBpbml0IERyYWcmZHJvcFxyXG4gICAgICBpZiAobi5zdWJHcmlkICYmIHJlY3Vyc2UpIG4uc3ViR3JpZC5zZXRTdGF0aWModmFsLCB1cGRhdGVDbGFzcywgcmVjdXJzZSk7XHJcbiAgICB9KTtcclxuICAgIGlmICh1cGRhdGVDbGFzcykgeyB0aGlzLl9zZXRTdGF0aWNDbGFzcygpOyB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFVwZGF0ZXMgd2lkZ2V0IHBvc2l0aW9uL3NpemUgYW5kIG90aGVyIGluZm8uIE5vdGU6IGlmIHlvdSBuZWVkIHRvIGNhbGwgdGhpcyBvbiBhbGwgbm9kZXMsIHVzZSBsb2FkKCkgaW5zdGVhZCB3aGljaCB3aWxsIHVwZGF0ZSB3aGF0IGNoYW5nZWQuXHJcbiAgICogQHBhcmFtIGVscyAgd2lkZ2V0IG9yIHNlbGVjdG9yIG9mIG9iamVjdHMgdG8gbW9kaWZ5IChub3RlOiBzZXR0aW5nIHRoZSBzYW1lIHgseSBmb3IgbXVsdGlwbGUgaXRlbXMgd2lsbCBiZSBpbmRldGVybWluaXN0aWMgYW5kIGxpa2VseSB1bndhbnRlZClcclxuICAgKiBAcGFyYW0gb3B0IG5ldyB3aWRnZXQgb3B0aW9ucyAoeCx5LHcsaCwgZXRjLi4pLiBPbmx5IHRob3NlIHNldCB3aWxsIGJlIHVwZGF0ZWQuXHJcbiAgICovXHJcbiAgcHVibGljIHVwZGF0ZShlbHM6IEdyaWRTdGFja0VsZW1lbnQsIG9wdDogR3JpZFN0YWNrV2lkZ2V0KTogR3JpZFN0YWNrIHtcclxuXHJcbiAgICAvLyBzdXBwb3J0IGxlZ2FjeSBjYWxsIGZvciBub3cgP1xyXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7XHJcbiAgICAgIGNvbnNvbGUud2FybignZ3JpZHN0YWNrLnRzOiBgdXBkYXRlKGVsLCB4LCB5LCB3LCBoKWAgaXMgZGVwcmVjYXRlZC4gVXNlIGB1cGRhdGUoZWwsIHt4LCB3LCBjb250ZW50LCAuLi59KWAuIEl0IHdpbGwgYmUgcmVtb3ZlZCBzb29uJyk7XHJcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItcmVzdC1wYXJhbXNcclxuICAgICAgbGV0IGEgPSBhcmd1bWVudHMsIGkgPSAxO1xyXG4gICAgICBvcHQgPSB7IHg6YVtpKytdLCB5OmFbaSsrXSwgdzphW2krK10sIGg6YVtpKytdIH07XHJcbiAgICAgIHJldHVybiB0aGlzLnVwZGF0ZShlbHMsIG9wdCk7XHJcbiAgICB9XHJcblxyXG4gICAgR3JpZFN0YWNrLmdldEVsZW1lbnRzKGVscykuZm9yRWFjaChlbCA9PiB7XHJcbiAgICAgIGlmICghZWwgfHwgIWVsLmdyaWRzdGFja05vZGUpIHJldHVybjtcclxuICAgICAgbGV0IG4gPSBlbC5ncmlkc3RhY2tOb2RlO1xyXG4gICAgICBsZXQgdyA9IFV0aWxzLmNsb25lRGVlcChvcHQpOyAvLyBtYWtlIGEgY29weSB3ZSBjYW4gbW9kaWZ5IGluIGNhc2UgdGhleSByZS11c2UgaXQgb3IgbXVsdGlwbGUgaXRlbXNcclxuICAgICAgZGVsZXRlIHcuYXV0b1Bvc2l0aW9uO1xyXG5cclxuICAgICAgLy8gbW92ZS9yZXNpemUgd2lkZ2V0IGlmIGFueXRoaW5nIGNoYW5nZWRcclxuICAgICAgbGV0IGtleXMgPSBbJ3gnLCAneScsICd3JywgJ2gnXTtcclxuICAgICAgbGV0IG06IEdyaWRTdGFja1dpZGdldDtcclxuICAgICAgaWYgKGtleXMuc29tZShrID0+IHdba10gIT09IHVuZGVmaW5lZCAmJiB3W2tdICE9PSBuW2tdKSkge1xyXG4gICAgICAgIG0gPSB7fTtcclxuICAgICAgICBrZXlzLmZvckVhY2goayA9PiB7XHJcbiAgICAgICAgICBtW2tdID0gKHdba10gIT09IHVuZGVmaW5lZCkgPyB3W2tdIDogbltrXTtcclxuICAgICAgICAgIGRlbGV0ZSB3W2tdO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICAgIC8vIGZvciBhIG1vdmUgYXMgd2VsbCBJRkYgdGhlcmUgaXMgYW55IG1pbi9tYXggZmllbGRzIHNldFxyXG4gICAgICBpZiAoIW0gJiYgKHcubWluVyB8fCB3Lm1pbkggfHwgdy5tYXhXIHx8IHcubWF4SCkpIHtcclxuICAgICAgICBtID0ge307IC8vIHdpbGwgdXNlIG5vZGUgcG9zaXRpb24gYnV0IHZhbGlkYXRlIHZhbHVlc1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBjaGVjayBmb3IgY29udGVudCBjaGFuZ2luZ1xyXG4gICAgICBpZiAody5jb250ZW50KSB7XHJcbiAgICAgICAgbGV0IHN1YiA9IGVsLnF1ZXJ5U2VsZWN0b3IoJy5ncmlkLXN0YWNrLWl0ZW0tY29udGVudCcpO1xyXG4gICAgICAgIGlmIChzdWIgJiYgc3ViLmlubmVySFRNTCAhPT0gdy5jb250ZW50KSB7XHJcbiAgICAgICAgICBzdWIuaW5uZXJIVE1MID0gdy5jb250ZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICBkZWxldGUgdy5jb250ZW50O1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBhbnkgcmVtYWluaW5nIGZpZWxkcyBhcmUgYXNzaWduZWQsIGJ1dCBjaGVjayBmb3IgZHJhZ2dpbmcgY2hhbmdlcywgcmVzaXplIGNvbnN0cmFpblxyXG4gICAgICBsZXQgY2hhbmdlZCA9IGZhbHNlO1xyXG4gICAgICBsZXQgZGRDaGFuZ2VkID0gZmFsc2U7XHJcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHcpIHtcclxuICAgICAgICBpZiAoa2V5WzBdICE9PSAnXycgJiYgbltrZXldICE9PSB3W2tleV0pIHtcclxuICAgICAgICAgIG5ba2V5XSA9IHdba2V5XTtcclxuICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xyXG4gICAgICAgICAgZGRDaGFuZ2VkID0gZGRDaGFuZ2VkIHx8ICghdGhpcy5vcHRzLnN0YXRpY0dyaWQgJiYgKGtleSA9PT0gJ25vUmVzaXplJyB8fCBrZXkgPT09ICdub01vdmUnIHx8IGtleSA9PT0gJ2xvY2tlZCcpKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgVXRpbHMuc2FuaXRpemVNaW5NYXgobik7XHJcblxyXG4gICAgICAvLyBmaW5hbGx5IG1vdmUgdGhlIHdpZGdldFxyXG4gICAgICBpZiAobSkge1xyXG4gICAgICAgIHRoaXMuZW5naW5lLmNsZWFuTm9kZXMoKVxyXG4gICAgICAgICAgLmJlZ2luVXBkYXRlKG4pXHJcbiAgICAgICAgICAubW92ZU5vZGUobiwgbSk7XHJcbiAgICAgICAgdGhpcy5fdXBkYXRlQ29udGFpbmVySGVpZ2h0KCk7XHJcbiAgICAgICAgdGhpcy5fdHJpZ2dlckNoYW5nZUV2ZW50KCk7XHJcbiAgICAgICAgdGhpcy5lbmdpbmUuZW5kVXBkYXRlKCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGNoYW5nZWQpIHsgLy8gbW92ZSB3aWxsIG9ubHkgdXBkYXRlIHgseSx3LGggc28gdXBkYXRlIHRoZSByZXN0IHRvb1xyXG4gICAgICAgIHRoaXMuX3dyaXRlQXR0cihlbCwgbik7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGRkQ2hhbmdlZCkge1xyXG4gICAgICAgIHRoaXMuX3ByZXBhcmVEcmFnRHJvcEJ5Tm9kZShuKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFVwZGF0ZXMgdGhlIG1hcmdpbnMgd2hpY2ggd2lsbCBzZXQgYWxsIDQgc2lkZXMgYXQgb25jZSAtIHNlZSBgR3JpZFN0YWNrT3B0aW9ucy5tYXJnaW5gIGZvciBmb3JtYXQgb3B0aW9ucyAoQ1NTIHN0cmluZyBmb3JtYXQgb2YgMSwyLDQgdmFsdWVzIG9yIHNpbmdsZSBudW1iZXIpLlxyXG4gICAqIEBwYXJhbSB2YWx1ZSBtYXJnaW4gdmFsdWVcclxuICAgKi9cclxuICBwdWJsaWMgbWFyZ2luKHZhbHVlOiBudW1iZXJPclN0cmluZyk6IEdyaWRTdGFjayB7XHJcbiAgICBsZXQgaXNNdWx0aVZhbHVlID0gKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUuc3BsaXQoJyAnKS5sZW5ndGggPiAxKTtcclxuICAgIC8vIGNoZWNrIGlmIHdlIGNhbiBza2lwIHJlLWNyZWF0aW5nIG91ciBDU1MgZmlsZS4uLiB3b24ndCBjaGVjayBpZiBtdWx0aSB2YWx1ZXMgKHRvbyBtdWNoIGhhc3NsZSlcclxuICAgIGlmICghaXNNdWx0aVZhbHVlKSB7XHJcbiAgICAgIGxldCBkYXRhID0gVXRpbHMucGFyc2VIZWlnaHQodmFsdWUpO1xyXG4gICAgICBpZiAodGhpcy5vcHRzLm1hcmdpblVuaXQgPT09IGRhdGEudW5pdCAmJiB0aGlzLm9wdHMubWFyZ2luID09PSBkYXRhLmgpIHJldHVybjtcclxuICAgIH1cclxuICAgIC8vIHJlLXVzZSBleGlzdGluZyBtYXJnaW4gaGFuZGxpbmdcclxuICAgIHRoaXMub3B0cy5tYXJnaW4gPSB2YWx1ZTtcclxuICAgIHRoaXMub3B0cy5tYXJnaW5Ub3AgPSB0aGlzLm9wdHMubWFyZ2luQm90dG9tID0gdGhpcy5vcHRzLm1hcmdpbkxlZnQgPSB0aGlzLm9wdHMubWFyZ2luUmlnaHQgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLl9pbml0TWFyZ2luKCk7XHJcblxyXG4gICAgdGhpcy5fdXBkYXRlU3R5bGVzKHRydWUpOyAvLyB0cnVlID0gZm9yY2UgcmUtY3JlYXRlXHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKiogcmV0dXJucyBjdXJyZW50IG1hcmdpbiBudW1iZXIgdmFsdWUgKHVuZGVmaW5lZCBpZiA0IHNpZGVzIGRvbid0IG1hdGNoKSAqL1xyXG4gIHB1YmxpYyBnZXRNYXJnaW4oKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMub3B0cy5tYXJnaW4gYXMgbnVtYmVyOyB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgaGVpZ2h0IG9mIHRoZSBncmlkIHdpbGwgYmUgbGVzcyB0aGFuIHRoZSB2ZXJ0aWNhbFxyXG4gICAqIGNvbnN0cmFpbnQuIEFsd2F5cyByZXR1cm5zIHRydWUgaWYgZ3JpZCBkb2Vzbid0IGhhdmUgaGVpZ2h0IGNvbnN0cmFpbnQuXHJcbiAgICogQHBhcmFtIG5vZGUgY29udGFpbnMgeCx5LHcsaCxhdXRvLXBvc2l0aW9uIG9wdGlvbnNcclxuICAgKlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogaWYgKGdyaWQud2lsbEl0Rml0KG5ld1dpZGdldCkpIHtcclxuICAgKiAgIGdyaWQuYWRkV2lkZ2V0KG5ld1dpZGdldCk7XHJcbiAgICogfSBlbHNlIHtcclxuICAgKiAgIGFsZXJ0KCdOb3QgZW5vdWdoIGZyZWUgc3BhY2UgdG8gcGxhY2UgdGhlIHdpZGdldCcpO1xyXG4gICAqIH1cclxuICAgKi9cclxuICBwdWJsaWMgd2lsbEl0Rml0KG5vZGU6IEdyaWRTdGFja1dpZGdldCk6IGJvb2xlYW4ge1xyXG4gICAgLy8gc3VwcG9ydCBsZWdhY3kgY2FsbCBmb3Igbm93XHJcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgY29uc29sZS53YXJuKCdncmlkc3RhY2sudHM6IGB3aWxsSXRGaXQoeCx5LHcsaCxhdXRvUG9zaXRpb24pYCBpcyBkZXByZWNhdGVkLiBVc2UgYHdpbGxJdEZpdCh7eCwgeSwuLi59KWAuIEl0IHdpbGwgYmUgcmVtb3ZlZCBzb29uJyk7XHJcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItcmVzdC1wYXJhbXNcclxuICAgICAgbGV0IGEgPSBhcmd1bWVudHMsIGkgPSAwLFxyXG4gICAgICAgIHc6IEdyaWRTdGFja1dpZGdldCA9IHsgeDphW2krK10sIHk6YVtpKytdLCB3OmFbaSsrXSwgaDphW2krK10sIGF1dG9Qb3NpdGlvbjphW2krK10gfTtcclxuICAgICAgcmV0dXJuIHRoaXMud2lsbEl0Rml0KHcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuZW5naW5lLndpbGxJdEZpdChub2RlKTtcclxuICB9XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgKi9cclxuICBwcm90ZWN0ZWQgX3RyaWdnZXJDaGFuZ2VFdmVudCgpOiBHcmlkU3RhY2sge1xyXG4gICAgaWYgKHRoaXMuZW5naW5lLmJhdGNoTW9kZSkgcmV0dXJuIHRoaXM7XHJcbiAgICBsZXQgZWxlbWVudHMgPSB0aGlzLmVuZ2luZS5nZXREaXJ0eU5vZGVzKHRydWUpOyAvLyB2ZXJpZnkgdGhleSByZWFsbHkgY2hhbmdlZFxyXG4gICAgaWYgKGVsZW1lbnRzICYmIGVsZW1lbnRzLmxlbmd0aCkge1xyXG4gICAgICBpZiAoIXRoaXMuX2lnbm9yZUxheW91dHNOb2RlQ2hhbmdlKSB7XHJcbiAgICAgICAgdGhpcy5lbmdpbmUubGF5b3V0c05vZGVzQ2hhbmdlKGVsZW1lbnRzKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLl90cmlnZ2VyRXZlbnQoJ2NoYW5nZScsIGVsZW1lbnRzKTtcclxuICAgIH1cclxuICAgIHRoaXMuZW5naW5lLnNhdmVJbml0aWFsKCk7IC8vIHdlIGNhbGxlZCwgbm93IHJlc2V0IGluaXRpYWwgdmFsdWVzICYgZGlydHkgZmxhZ3NcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIHByb3RlY3RlZCBfdHJpZ2dlckFkZEV2ZW50KCk6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAodGhpcy5lbmdpbmUuYmF0Y2hNb2RlKSByZXR1cm4gdGhpcztcclxuICAgIGlmICh0aGlzLmVuZ2luZS5hZGRlZE5vZGVzPy5sZW5ndGgpIHtcclxuICAgICAgaWYgKCF0aGlzLl9pZ25vcmVMYXlvdXRzTm9kZUNoYW5nZSkge1xyXG4gICAgICAgIHRoaXMuZW5naW5lLmxheW91dHNOb2Rlc0NoYW5nZSh0aGlzLmVuZ2luZS5hZGRlZE5vZGVzKTtcclxuICAgICAgfVxyXG4gICAgICAvLyBwcmV2ZW50IGFkZGVkIG5vZGVzIGZyb20gYWxzbyB0cmlnZ2VyaW5nICdjaGFuZ2UnIGV2ZW50ICh3aGljaCBpcyBjYWxsZWQgbmV4dClcclxuICAgICAgdGhpcy5lbmdpbmUuYWRkZWROb2Rlcy5mb3JFYWNoKG4gPT4geyBkZWxldGUgbi5fZGlydHk7IH0pO1xyXG4gICAgICB0aGlzLl90cmlnZ2VyRXZlbnQoJ2FkZGVkJywgdGhpcy5lbmdpbmUuYWRkZWROb2Rlcyk7XHJcbiAgICAgIHRoaXMuZW5naW5lLmFkZGVkTm9kZXMgPSBbXTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIHB1YmxpYyBfdHJpZ2dlclJlbW92ZUV2ZW50KCk6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAodGhpcy5lbmdpbmUuYmF0Y2hNb2RlKSByZXR1cm4gdGhpcztcclxuICAgIGlmICh0aGlzLmVuZ2luZS5yZW1vdmVkTm9kZXM/Lmxlbmd0aCkge1xyXG4gICAgICB0aGlzLl90cmlnZ2VyRXZlbnQoJ3JlbW92ZWQnLCB0aGlzLmVuZ2luZS5yZW1vdmVkTm9kZXMpO1xyXG4gICAgICB0aGlzLmVuZ2luZS5yZW1vdmVkTm9kZXMgPSBbXTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIHByb3RlY3RlZCBfdHJpZ2dlckV2ZW50KHR5cGU6IHN0cmluZywgZGF0YT86IEdyaWRTdGFja05vZGVbXSk6IEdyaWRTdGFjayB7XHJcbiAgICBsZXQgZXZlbnQgPSBkYXRhID8gbmV3IEN1c3RvbUV2ZW50KHR5cGUsIHtidWJibGVzOiBmYWxzZSwgZGV0YWlsOiBkYXRhfSkgOiBuZXcgRXZlbnQodHlwZSk7XHJcbiAgICB0aGlzLmVsLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKiogQGludGVybmFsIGNhbGxlZCB0byBkZWxldGUgdGhlIGN1cnJlbnQgZHluYW1pYyBzdHlsZSBzaGVldCB1c2VkIGZvciBvdXIgbGF5b3V0ICovXHJcbiAgcHJvdGVjdGVkIF9yZW1vdmVTdHlsZXNoZWV0KCk6IEdyaWRTdGFjayB7XHJcblxyXG4gICAgaWYgKHRoaXMuX3N0eWxlcykge1xyXG4gICAgICBVdGlscy5yZW1vdmVTdHlsZXNoZWV0KHRoaXMuX3N0eWxlU2hlZXRDbGFzcyk7XHJcbiAgICAgIGRlbGV0ZSB0aGlzLl9zdHlsZXM7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgdXBkYXRlZC9jcmVhdGUgdGhlIENTUyBzdHlsZXMgZm9yIHJvdyBiYXNlZCBsYXlvdXQgYW5kIGluaXRpYWwgbWFyZ2luIHNldHRpbmcgKi9cclxuICBwcm90ZWN0ZWQgX3VwZGF0ZVN0eWxlcyhmb3JjZVVwZGF0ZSA9IGZhbHNlLCBtYXhIPzogbnVtYmVyKTogR3JpZFN0YWNrIHtcclxuICAgIC8vIGNhbGwgdG8gZGVsZXRlIGV4aXN0aW5nIG9uZSBpZiB3ZSBjaGFuZ2UgY2VsbEhlaWdodCAvIG1hcmdpblxyXG4gICAgaWYgKGZvcmNlVXBkYXRlKSB7XHJcbiAgICAgIHRoaXMuX3JlbW92ZVN0eWxlc2hlZXQoKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIW1heEgpIG1heEggPSB0aGlzLmdldFJvdygpO1xyXG4gICAgdGhpcy5fdXBkYXRlQ29udGFpbmVySGVpZ2h0KCk7XHJcblxyXG4gICAgLy8gaWYgdXNlciBpcyB0ZWxsaW5nIHVzIHRoZXkgd2lsbCBoYW5kbGUgdGhlIENTUyB0aGVtc2VsdmVzIGJ5IHNldHRpbmcgaGVpZ2h0cyB0byAwLiBEbyB3ZSBuZWVkIHRoaXMgb3B0cyByZWFsbHkgPz9cclxuICAgIGlmICh0aGlzLm9wdHMuY2VsbEhlaWdodCA9PT0gMCkge1xyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBsZXQgY2VsbEhlaWdodCA9IHRoaXMub3B0cy5jZWxsSGVpZ2h0IGFzIG51bWJlcjtcclxuICAgIGxldCBjZWxsSGVpZ2h0VW5pdCA9IHRoaXMub3B0cy5jZWxsSGVpZ2h0VW5pdDtcclxuICAgIGxldCBwcmVmaXggPSBgLiR7dGhpcy5fc3R5bGVTaGVldENsYXNzfSA+IC4ke3RoaXMub3B0cy5pdGVtQ2xhc3N9YDtcclxuXHJcbiAgICAvLyBjcmVhdGUgb25lIGFzIG5lZWRlZFxyXG4gICAgaWYgKCF0aGlzLl9zdHlsZXMpIHtcclxuICAgICAgLy8gaW5zZXJ0IHN0eWxlIHRvIHBhcmVudCAoaW5zdGVhZCBvZiAnaGVhZCcgYnkgZGVmYXVsdCkgdG8gc3VwcG9ydCBXZWJDb21wb25lbnRcclxuICAgICAgbGV0IHN0eWxlTG9jYXRpb24gPSB0aGlzLm9wdHMuc3R5bGVJbkhlYWQgPyB1bmRlZmluZWQgOiB0aGlzLmVsLnBhcmVudE5vZGUgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgIHRoaXMuX3N0eWxlcyA9IFV0aWxzLmNyZWF0ZVN0eWxlc2hlZXQodGhpcy5fc3R5bGVTaGVldENsYXNzLCBzdHlsZUxvY2F0aW9uLCB7XHJcbiAgICAgICAgbm9uY2U6IHRoaXMub3B0cy5ub25jZSxcclxuICAgICAgfSk7XHJcbiAgICAgIGlmICghdGhpcy5fc3R5bGVzKSByZXR1cm4gdGhpcztcclxuICAgICAgdGhpcy5fc3R5bGVzLl9tYXggPSAwO1xyXG5cclxuICAgICAgLy8gdGhlc2UgYXJlIGRvbmUgb25jZSBvbmx5XHJcbiAgICAgIFV0aWxzLmFkZENTU1J1bGUodGhpcy5fc3R5bGVzLCBwcmVmaXgsIGBoZWlnaHQ6ICR7Y2VsbEhlaWdodH0ke2NlbGxIZWlnaHRVbml0fWApO1xyXG4gICAgICAvLyBjb250ZW50IG1hcmdpbnNcclxuICAgICAgbGV0IHRvcDogc3RyaW5nID0gdGhpcy5vcHRzLm1hcmdpblRvcCArIHRoaXMub3B0cy5tYXJnaW5Vbml0O1xyXG4gICAgICBsZXQgYm90dG9tOiBzdHJpbmcgPSB0aGlzLm9wdHMubWFyZ2luQm90dG9tICsgdGhpcy5vcHRzLm1hcmdpblVuaXQ7XHJcbiAgICAgIGxldCByaWdodDogc3RyaW5nID0gdGhpcy5vcHRzLm1hcmdpblJpZ2h0ICsgdGhpcy5vcHRzLm1hcmdpblVuaXQ7XHJcbiAgICAgIGxldCBsZWZ0OiBzdHJpbmcgPSB0aGlzLm9wdHMubWFyZ2luTGVmdCArIHRoaXMub3B0cy5tYXJnaW5Vbml0O1xyXG4gICAgICBsZXQgY29udGVudCA9IGAke3ByZWZpeH0gPiAuZ3JpZC1zdGFjay1pdGVtLWNvbnRlbnRgO1xyXG4gICAgICBsZXQgcGxhY2Vob2xkZXIgPSBgLiR7dGhpcy5fc3R5bGVTaGVldENsYXNzfSA+IC5ncmlkLXN0YWNrLXBsYWNlaG9sZGVyID4gLnBsYWNlaG9sZGVyLWNvbnRlbnRgO1xyXG4gICAgICBVdGlscy5hZGRDU1NSdWxlKHRoaXMuX3N0eWxlcywgY29udGVudCwgYHRvcDogJHt0b3B9OyByaWdodDogJHtyaWdodH07IGJvdHRvbTogJHtib3R0b219OyBsZWZ0OiAke2xlZnR9O2ApO1xyXG4gICAgICBVdGlscy5hZGRDU1NSdWxlKHRoaXMuX3N0eWxlcywgcGxhY2Vob2xkZXIsIGB0b3A6ICR7dG9wfTsgcmlnaHQ6ICR7cmlnaHR9OyBib3R0b206ICR7Ym90dG9tfTsgbGVmdDogJHtsZWZ0fTtgKTtcclxuICAgICAgLy8gcmVzaXplIGhhbmRsZXMgb2Zmc2V0ICh0byBtYXRjaCBtYXJnaW4pXHJcbiAgICAgIFV0aWxzLmFkZENTU1J1bGUodGhpcy5fc3R5bGVzLCBgJHtwcmVmaXh9ID4gLnVpLXJlc2l6YWJsZS1uZWAsIGByaWdodDogJHtyaWdodH1gKTtcclxuICAgICAgVXRpbHMuYWRkQ1NTUnVsZSh0aGlzLl9zdHlsZXMsIGAke3ByZWZpeH0gPiAudWktcmVzaXphYmxlLWVgLCBgcmlnaHQ6ICR7cmlnaHR9YCk7XHJcbiAgICAgIFV0aWxzLmFkZENTU1J1bGUodGhpcy5fc3R5bGVzLCBgJHtwcmVmaXh9ID4gLnVpLXJlc2l6YWJsZS1zZWAsIGByaWdodDogJHtyaWdodH07IGJvdHRvbTogJHtib3R0b219YCk7XHJcbiAgICAgIFV0aWxzLmFkZENTU1J1bGUodGhpcy5fc3R5bGVzLCBgJHtwcmVmaXh9ID4gLnVpLXJlc2l6YWJsZS1ud2AsIGBsZWZ0OiAke2xlZnR9YCk7XHJcbiAgICAgIFV0aWxzLmFkZENTU1J1bGUodGhpcy5fc3R5bGVzLCBgJHtwcmVmaXh9ID4gLnVpLXJlc2l6YWJsZS13YCwgYGxlZnQ6ICR7bGVmdH1gKTtcclxuICAgICAgVXRpbHMuYWRkQ1NTUnVsZSh0aGlzLl9zdHlsZXMsIGAke3ByZWZpeH0gPiAudWktcmVzaXphYmxlLXN3YCwgYGxlZnQ6ICR7bGVmdH07IGJvdHRvbTogJHtib3R0b219YCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gbm93IHVwZGF0ZSB0aGUgaGVpZ2h0IHNwZWNpZmljIGZpZWxkc1xyXG4gICAgbWF4SCA9IG1heEggfHwgdGhpcy5fc3R5bGVzLl9tYXg7XHJcbiAgICBpZiAobWF4SCA+IHRoaXMuX3N0eWxlcy5fbWF4KSB7XHJcbiAgICAgIGxldCBnZXRIZWlnaHQgPSAocm93czogbnVtYmVyKTogc3RyaW5nID0+IChjZWxsSGVpZ2h0ICogcm93cykgKyBjZWxsSGVpZ2h0VW5pdDtcclxuICAgICAgZm9yIChsZXQgaSA9IHRoaXMuX3N0eWxlcy5fbWF4ICsgMTsgaSA8PSBtYXhIOyBpKyspIHsgLy8gc3RhcnQgYXQgMVxyXG4gICAgICAgIFV0aWxzLmFkZENTU1J1bGUodGhpcy5fc3R5bGVzLCBgJHtwcmVmaXh9W2dzLXk9XCIke2l9XCJdYCwgYHRvcDogJHtnZXRIZWlnaHQoaSl9YCk7XHJcbiAgICAgICAgVXRpbHMuYWRkQ1NTUnVsZSh0aGlzLl9zdHlsZXMsIGAke3ByZWZpeH1bZ3MtaD1cIiR7aSsxfVwiXWAsIGBoZWlnaHQ6ICR7Z2V0SGVpZ2h0KGkrMSl9YCk7IC8vIHN0YXJ0IGF0IDJcclxuICAgICAgfVxyXG4gICAgICB0aGlzLl9zdHlsZXMuX21heCA9IG1heEg7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgKi9cclxuICBwcm90ZWN0ZWQgX3VwZGF0ZUNvbnRhaW5lckhlaWdodCgpOiBHcmlkU3RhY2sge1xyXG4gICAgaWYgKCF0aGlzLmVuZ2luZSB8fCB0aGlzLmVuZ2luZS5iYXRjaE1vZGUpIHJldHVybiB0aGlzO1xyXG4gICAgbGV0IHJvdyA9IHRoaXMuZ2V0Um93KCkgKyB0aGlzLl9leHRyYURyYWdSb3c7IC8vIGNoZWNrcyBmb3IgbWluUm93IGFscmVhZHlcclxuICAgIC8vIGNoZWNrIGZvciBjc3MgbWluIGhlaWdodFxyXG4gICAgLy8gTm90ZTogd2UgZG9uJ3QgaGFuZGxlICUscmVtIGNvcnJlY3RseSBzbyBjb21tZW50IG91dCwgYmVzaWRlIHdlIGRvbid0IG5lZWQgbmVlZCB0byBjcmVhdGUgdW4tbmVjZXNzYXJ5XHJcbiAgICAvLyByb3dzIGFzIHRoZSBDU1Mgd2lsbCBtYWtlIHVzIGJpZ2dlciB0aGFuIG91ciBzZXQgaGVpZ2h0IGlmIG5lZWRlZC4uLiBub3Qgc3VyZSB3aHkgd2UgaGFkIHRoaXMuXHJcbiAgICAvLyBsZXQgY3NzTWluSGVpZ2h0ID0gcGFyc2VJbnQoZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmVsKVsnbWluLWhlaWdodCddKTtcclxuICAgIC8vIGlmIChjc3NNaW5IZWlnaHQgPiAwKSB7XHJcbiAgICAvLyAgIGxldCBtaW5Sb3cgPSBNYXRoLnJvdW5kKGNzc01pbkhlaWdodCAvIHRoaXMuZ2V0Q2VsbEhlaWdodCh0cnVlKSk7XHJcbiAgICAvLyAgIGlmIChyb3cgPCBtaW5Sb3cpIHtcclxuICAgIC8vICAgICByb3cgPSBtaW5Sb3c7XHJcbiAgICAvLyAgIH1cclxuICAgIC8vIH1cclxuICAgIHRoaXMuZWwuc2V0QXR0cmlidXRlKCdncy1jdXJyZW50LXJvdycsIFN0cmluZyhyb3cpKTtcclxuICAgIGlmIChyb3cgPT09IDApIHtcclxuICAgICAgdGhpcy5lbC5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgnbWluLWhlaWdodCcpO1xyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuICAgIGxldCBjZWxsSGVpZ2h0ID0gdGhpcy5vcHRzLmNlbGxIZWlnaHQgYXMgbnVtYmVyO1xyXG4gICAgbGV0IHVuaXQgPSB0aGlzLm9wdHMuY2VsbEhlaWdodFVuaXQ7XHJcbiAgICBpZiAoIWNlbGxIZWlnaHQpIHJldHVybiB0aGlzO1xyXG4gICAgdGhpcy5lbC5zdHlsZS5taW5IZWlnaHQgPSByb3cgKiBjZWxsSGVpZ2h0ICsgdW5pdDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIHByb3RlY3RlZCBfcHJlcGFyZUVsZW1lbnQoZWw6IEdyaWRJdGVtSFRNTEVsZW1lbnQsIHRyaWdnZXJBZGRFdmVudCA9IGZhbHNlLCBub2RlPzogR3JpZFN0YWNrTm9kZSk6IEdyaWRTdGFjayB7XHJcbiAgICBlbC5jbGFzc0xpc3QuYWRkKHRoaXMub3B0cy5pdGVtQ2xhc3MpO1xyXG4gICAgbm9kZSA9IG5vZGUgfHwgdGhpcy5fcmVhZEF0dHIoZWwpO1xyXG4gICAgZWwuZ3JpZHN0YWNrTm9kZSA9IG5vZGU7XHJcbiAgICBub2RlLmVsID0gZWw7XHJcbiAgICBub2RlLmdyaWQgPSB0aGlzO1xyXG4gICAgbGV0IGNvcHkgPSB7Li4ubm9kZX07XHJcbiAgICBub2RlID0gdGhpcy5lbmdpbmUuYWRkTm9kZShub2RlLCB0cmlnZ2VyQWRkRXZlbnQpO1xyXG4gICAgLy8gd3JpdGUgbm9kZSBhdHRyIGJhY2sgaW4gY2FzZSB0aGVyZSB3YXMgY29sbGlzaW9uIG9yIHdlIGhhdmUgdG8gZml4IGJhZCB2YWx1ZXMgZHVyaW5nIGFkZE5vZGUoKVxyXG4gICAgaWYgKCFVdGlscy5zYW1lKG5vZGUsIGNvcHkpKSB7XHJcbiAgICAgIHRoaXMuX3dyaXRlQXR0cihlbCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9wcmVwYXJlRHJhZ0Ryb3BCeU5vZGUobm9kZSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgY2FsbCB0byB3cml0ZSBwb3NpdGlvbiB4LHksdyxoIGF0dHJpYnV0ZXMgYmFjayB0byBlbGVtZW50ICovXHJcbiAgcHJvdGVjdGVkIF93cml0ZVBvc0F0dHIoZWw6IEhUTUxFbGVtZW50LCBuOiBHcmlkU3RhY2tQb3NpdGlvbik6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAobi54ICE9PSB1bmRlZmluZWQgJiYgbi54ICE9PSBudWxsKSB7IGVsLnNldEF0dHJpYnV0ZSgnZ3MteCcsIFN0cmluZyhuLngpKTsgfVxyXG4gICAgaWYgKG4ueSAhPT0gdW5kZWZpbmVkICYmIG4ueSAhPT0gbnVsbCkgeyBlbC5zZXRBdHRyaWJ1dGUoJ2dzLXknLCBTdHJpbmcobi55KSk7IH1cclxuICAgIG4udyA+IDEgPyBlbC5zZXRBdHRyaWJ1dGUoJ2dzLXcnLCBTdHJpbmcobi53KSkgOiBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2dzLXcnKTtcclxuICAgIG4uaCA+IDEgPyBlbC5zZXRBdHRyaWJ1dGUoJ2dzLWgnLCBTdHJpbmcobi5oKSkgOiBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2dzLWgnKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCBjYWxsIHRvIHdyaXRlIGFueSBkZWZhdWx0IGF0dHJpYnV0ZXMgYmFjayB0byBlbGVtZW50ICovXHJcbiAgcHJvdGVjdGVkIF93cml0ZUF0dHIoZWw6IEhUTUxFbGVtZW50LCBub2RlOiBHcmlkU3RhY2tXaWRnZXQpOiBHcmlkU3RhY2sge1xyXG4gICAgaWYgKCFub2RlKSByZXR1cm4gdGhpcztcclxuICAgIHRoaXMuX3dyaXRlUG9zQXR0cihlbCwgbm9kZSk7XHJcblxyXG4gICAgbGV0IGF0dHJzIC8qOiBHcmlkU3RhY2tXaWRnZXQgYnV0IHN0cmluZ3MgKi8gPSB7IC8vIHJlbWFpbmluZyBhdHRyaWJ1dGVzXHJcbiAgICAgIGF1dG9Qb3NpdGlvbjogJ2dzLWF1dG8tcG9zaXRpb24nLFxyXG4gICAgICBub1Jlc2l6ZTogJ2dzLW5vLXJlc2l6ZScsXHJcbiAgICAgIG5vTW92ZTogJ2dzLW5vLW1vdmUnLFxyXG4gICAgICBsb2NrZWQ6ICdncy1sb2NrZWQnLFxyXG4gICAgICBpZDogJ2dzLWlkJyxcclxuICAgIH07XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBhdHRycykge1xyXG4gICAgICBpZiAobm9kZVtrZXldKSB7IC8vIDAgaXMgdmFsaWQgZm9yIHgseSBvbmx5IGJ1dCBkb25lIGFib3ZlIGFscmVhZHkgYW5kIG5vdCBpbiBsaXN0IGFueXdheVxyXG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShhdHRyc1trZXldLCBTdHJpbmcobm9kZVtrZXldKSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKGF0dHJzW2tleV0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgY2FsbCB0byByZWFkIGFueSBkZWZhdWx0IGF0dHJpYnV0ZXMgZnJvbSBlbGVtZW50ICovXHJcbiAgcHJvdGVjdGVkIF9yZWFkQXR0cihlbDogSFRNTEVsZW1lbnQsIGNsZWFyRGVmYXVsdEF0dHIgPSB0cnVlKTogR3JpZFN0YWNrV2lkZ2V0IHtcclxuICAgIGxldCBuOiBHcmlkU3RhY2tOb2RlID0ge307XHJcbiAgICBuLnggPSBVdGlscy50b051bWJlcihlbC5nZXRBdHRyaWJ1dGUoJ2dzLXgnKSk7XHJcbiAgICBuLnkgPSBVdGlscy50b051bWJlcihlbC5nZXRBdHRyaWJ1dGUoJ2dzLXknKSk7XHJcbiAgICBuLncgPSBVdGlscy50b051bWJlcihlbC5nZXRBdHRyaWJ1dGUoJ2dzLXcnKSk7XHJcbiAgICBuLmggPSBVdGlscy50b051bWJlcihlbC5nZXRBdHRyaWJ1dGUoJ2dzLWgnKSk7XHJcbiAgICBuLmF1dG9Qb3NpdGlvbiA9IFV0aWxzLnRvQm9vbChlbC5nZXRBdHRyaWJ1dGUoJ2dzLWF1dG8tcG9zaXRpb24nKSk7XHJcbiAgICBuLm5vUmVzaXplID0gVXRpbHMudG9Cb29sKGVsLmdldEF0dHJpYnV0ZSgnZ3Mtbm8tcmVzaXplJykpO1xyXG4gICAgbi5ub01vdmUgPSBVdGlscy50b0Jvb2woZWwuZ2V0QXR0cmlidXRlKCdncy1uby1tb3ZlJykpO1xyXG4gICAgbi5sb2NrZWQgPSBVdGlscy50b0Jvb2woZWwuZ2V0QXR0cmlidXRlKCdncy1sb2NrZWQnKSk7XHJcbiAgICBuLmlkID0gZWwuZ2V0QXR0cmlidXRlKCdncy1pZCcpO1xyXG5cclxuICAgIC8vIHJlYWQgYnV0IG5ldmVyIHdyaXR0ZW4gb3V0XHJcbiAgICBuLm1heFcgPSBVdGlscy50b051bWJlcihlbC5nZXRBdHRyaWJ1dGUoJ2dzLW1heC13JykpO1xyXG4gICAgbi5taW5XID0gVXRpbHMudG9OdW1iZXIoZWwuZ2V0QXR0cmlidXRlKCdncy1taW4tdycpKTtcclxuICAgIG4ubWF4SCA9IFV0aWxzLnRvTnVtYmVyKGVsLmdldEF0dHJpYnV0ZSgnZ3MtbWF4LWgnKSk7XHJcbiAgICBuLm1pbkggPSBVdGlscy50b051bWJlcihlbC5nZXRBdHRyaWJ1dGUoJ2dzLW1pbi1oJykpO1xyXG5cclxuICAgIC8vIHY4Lnggb3B0aW1pemF0aW9uIHRvIHJlZHVjZSB1bi1uZWVkZWQgYXR0ciB0aGF0IGRvbid0IHJlbmRlciBvciBhcmUgZGVmYXVsdCBDU1NcclxuICAgIGlmIChjbGVhckRlZmF1bHRBdHRyKSB7XHJcbiAgICAgIGlmIChuLncgPT09IDEpIGVsLnJlbW92ZUF0dHJpYnV0ZSgnZ3MtdycpO1xyXG4gICAgICBpZiAobi5oID09PSAxKSBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2dzLWgnKTtcclxuICAgICAgaWYgKG4ubWF4VykgZWwucmVtb3ZlQXR0cmlidXRlKCdncy1tYXgtdycpO1xyXG4gICAgICBpZiAobi5taW5XKSBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2dzLW1pbi13Jyk7XHJcbiAgICAgIGlmIChuLm1heEgpIGVsLnJlbW92ZUF0dHJpYnV0ZSgnZ3MtbWF4LWgnKTtcclxuICAgICAgaWYgKG4ubWluSCkgZWwucmVtb3ZlQXR0cmlidXRlKCdncy1taW4taCcpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJlbW92ZSBhbnkga2V5IG5vdCBmb3VuZCAobnVsbCBvciBmYWxzZSB3aGljaCBpcyBkZWZhdWx0KVxyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gbikge1xyXG4gICAgICBpZiAoIW4uaGFzT3duUHJvcGVydHkoa2V5KSkgcmV0dXJuO1xyXG4gICAgICBpZiAoIW5ba2V5XSAmJiBuW2tleV0gIT09IDApIHsgLy8gMCBjYW4gYmUgdmFsaWQgdmFsdWUgKHgseSBvbmx5IHJlYWxseSlcclxuICAgICAgICBkZWxldGUgbltrZXldO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG47XHJcbiAgfVxyXG5cclxuICAvKiogQGludGVybmFsICovXHJcbiAgcHJvdGVjdGVkIF9zZXRTdGF0aWNDbGFzcygpOiBHcmlkU3RhY2sge1xyXG4gICAgbGV0IGNsYXNzZXMgPSBbJ2dyaWQtc3RhY2stc3RhdGljJ107XHJcblxyXG4gICAgaWYgKHRoaXMub3B0cy5zdGF0aWNHcmlkKSB7XHJcbiAgICAgIHRoaXMuZWwuY2xhc3NMaXN0LmFkZCguLi5jbGFzc2VzKTtcclxuICAgICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoJ2dzLXN0YXRpYycsICd0cnVlJyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoLi4uY2xhc3Nlcyk7XHJcbiAgICAgIHRoaXMuZWwucmVtb3ZlQXR0cmlidXRlKCdncy1zdGF0aWMnKTtcclxuXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGNhbGxlZCB3aGVuIHdlIGFyZSBiZWluZyByZXNpemVkIGJ5IHRoZSB3aW5kb3cgLSBjaGVjayBpZiB0aGUgb25lIENvbHVtbiBNb2RlIG5lZWRzIHRvIGJlIHR1cm5lZCBvbi9vZmZcclxuICAgKiBhbmQgcmVtZW1iZXIgdGhlIHByZXYgY29sdW1ucyB3ZSB1c2VkLCBvciBnZXQgb3VyIGNvdW50IGZyb20gcGFyZW50LCBhcyB3ZWxsIGFzIGNoZWNrIGZvciBhdXRvIGNlbGwgaGVpZ2h0IChzcXVhcmUpXHJcbiAgICovXHJcbiAgcHVibGljIG9uUGFyZW50UmVzaXplKCk6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAoIXRoaXMuZWwgfHwgIXRoaXMuZWwuY2xpZW50V2lkdGgpIHJldHVybjsgLy8gcmV0dXJuIGlmIHdlJ3JlIGdvbmUgb3Igbm8gc2l6ZSB5ZXQgKHdpbGwgZ2V0IGNhbGxlZCBhZ2FpbilcclxuICAgIGxldCBjaGFuZ2VkQ29sdW1uID0gZmFsc2U7XHJcblxyXG4gICAgLy8gc2VlIGlmIHdlJ3JlIG5lc3RlZCBhbmQgdGFrZSBvdXIgY29sdW1uIGNvdW50IGZyb20gb3VyIHBhcmVudC4uLi5cclxuICAgIGlmICh0aGlzLl9hdXRvQ29sdW1uICYmIHRoaXMucGFyZW50R3JpZEl0ZW0pIHtcclxuICAgICAgaWYgKHRoaXMub3B0cy5jb2x1bW4gIT09IHRoaXMucGFyZW50R3JpZEl0ZW0udykge1xyXG4gICAgICAgIGNoYW5nZWRDb2x1bW4gPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuY29sdW1uKHRoaXMucGFyZW50R3JpZEl0ZW0udywgJ25vbmUnKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gZWxzZSBjaGVjayBmb3IgMSBjb2x1bW4gaW4vb3V0IGJlaGF2aW9yXHJcbiAgICAgIGxldCBvbmVDb2x1bW4gPSAhdGhpcy5vcHRzLmRpc2FibGVPbmVDb2x1bW5Nb2RlICYmIHRoaXMuZWwuY2xpZW50V2lkdGggPD0gdGhpcy5vcHRzLm9uZUNvbHVtblNpemU7XHJcbiAgICAgIGlmICgodGhpcy5vcHRzLmNvbHVtbiA9PT0gMSkgIT09IG9uZUNvbHVtbikge1xyXG4gICAgICAgIGNoYW5nZWRDb2x1bW4gPSB0cnVlO1xyXG4gICAgICAgIGlmICh0aGlzLm9wdHMuYW5pbWF0ZSkgeyB0aGlzLnNldEFuaW1hdGlvbihmYWxzZSk7IH0gLy8gMSA8LT4gMTIgaXMgdG9vIHJhZGljYWwsIHR1cm4gb2ZmIGFuaW1hdGlvblxyXG4gICAgICAgIHRoaXMuY29sdW1uKG9uZUNvbHVtbiA/IDEgOiB0aGlzLl9wcmV2Q29sdW1uKTtcclxuICAgICAgICBpZiAodGhpcy5vcHRzLmFuaW1hdGUpIHsgdGhpcy5zZXRBbmltYXRpb24odHJ1ZSk7IH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIG1ha2UgdGhlIGNlbGxzIGNvbnRlbnQgc3F1YXJlIGFnYWluXHJcbiAgICBpZiAodGhpcy5faXNBdXRvQ2VsbEhlaWdodCkge1xyXG4gICAgICBpZiAoIWNoYW5nZWRDb2x1bW4gJiYgdGhpcy5vcHRzLmNlbGxIZWlnaHRUaHJvdHRsZSkge1xyXG4gICAgICAgIGlmICghdGhpcy5fY2VsbEhlaWdodFRocm90dGxlKSB7XHJcbiAgICAgICAgICB0aGlzLl9jZWxsSGVpZ2h0VGhyb3R0bGUgPSBVdGlscy50aHJvdHRsZSgoKSA9PiB0aGlzLmNlbGxIZWlnaHQoKSwgdGhpcy5vcHRzLmNlbGxIZWlnaHRUaHJvdHRsZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX2NlbGxIZWlnaHRUaHJvdHRsZSgpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIGltbWVkaWF0ZSB1cGRhdGUgaWYgd2UndmUgY2hhbmdlZCBjb2x1bW4gY291bnQgb3IgaGF2ZSBubyB0aHJlc2hvbGRcclxuICAgICAgICB0aGlzLmNlbGxIZWlnaHQoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIGZpbmFsbHkgdXBkYXRlIGFueSBuZXN0ZWQgZ3JpZHNcclxuICAgIHRoaXMuZW5naW5lLm5vZGVzLmZvckVhY2gobiA9PiB7XHJcbiAgICAgIGlmIChuLnN1YkdyaWQpIG4uc3ViR3JpZC5vblBhcmVudFJlc2l6ZSgpXHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBhZGQgb3IgcmVtb3ZlIHRoZSB3aW5kb3cgc2l6ZSBldmVudCBoYW5kbGVyICovXHJcbiAgcHJvdGVjdGVkIF91cGRhdGVXaW5kb3dSZXNpemVFdmVudChmb3JjZVJlbW92ZSA9IGZhbHNlKTogR3JpZFN0YWNrIHtcclxuICAgIC8vIG9ubHkgYWRkIGV2ZW50IGlmIHdlJ3JlIG5vdCBuZXN0ZWQgKHBhcmVudCB3aWxsIGNhbGwgdXMpIGFuZCB3ZSdyZSBhdXRvIHNpemluZyBjZWxscyBvciBzdXBwb3J0aW5nIG9uZUNvbHVtbiAoaS5lLiBkb2luZyB3b3JrKVxyXG4gICAgY29uc3Qgd29ya1RvZG8gPSAodGhpcy5faXNBdXRvQ2VsbEhlaWdodCB8fCAhdGhpcy5vcHRzLmRpc2FibGVPbmVDb2x1bW5Nb2RlKSAmJiAhdGhpcy5wYXJlbnRHcmlkSXRlbTtcclxuXHJcbiAgICBpZiAoIWZvcmNlUmVtb3ZlICYmIHdvcmtUb2RvICYmICF0aGlzLl93aW5kb3dSZXNpemVCaW5kKSB7XHJcbiAgICAgIHRoaXMuX3dpbmRvd1Jlc2l6ZUJpbmQgPSB0aGlzLm9uUGFyZW50UmVzaXplLmJpbmQodGhpcyk7IC8vIHNvIHdlIGNhbiBwcm9wZXJseSByZW1vdmUgbGF0ZXJcclxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMuX3dpbmRvd1Jlc2l6ZUJpbmQpO1xyXG4gICAgfSBlbHNlIGlmICgoZm9yY2VSZW1vdmUgfHwgIXdvcmtUb2RvKSAmJiB0aGlzLl93aW5kb3dSZXNpemVCaW5kKSB7XHJcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLl93aW5kb3dSZXNpemVCaW5kKTtcclxuICAgICAgZGVsZXRlIHRoaXMuX3dpbmRvd1Jlc2l6ZUJpbmQ7IC8vIHJlbW92ZSBsaW5rIHRvIHVzIHNvIHdlIGNhbiBmcmVlXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKiogQGludGVybmFsIGNvbnZlcnQgYSBwb3RlbnRpYWwgc2VsZWN0b3IgaW50byBhY3R1YWwgZWxlbWVudCAqL1xyXG4gIHB1YmxpYyBzdGF0aWMgZ2V0RWxlbWVudChlbHM6IEdyaWRTdGFja0VsZW1lbnQgPSAnLmdyaWQtc3RhY2staXRlbScpOiBHcmlkSXRlbUhUTUxFbGVtZW50IHsgcmV0dXJuIFV0aWxzLmdldEVsZW1lbnQoZWxzKSB9XHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIHB1YmxpYyBzdGF0aWMgZ2V0RWxlbWVudHMoZWxzOiBHcmlkU3RhY2tFbGVtZW50ID0gJy5ncmlkLXN0YWNrLWl0ZW0nKTogR3JpZEl0ZW1IVE1MRWxlbWVudFtdIHsgcmV0dXJuIFV0aWxzLmdldEVsZW1lbnRzKGVscykgfVxyXG4gIC8qKiBAaW50ZXJuYWwgKi9cclxuICBwdWJsaWMgc3RhdGljIGdldEdyaWRFbGVtZW50KGVsczogR3JpZFN0YWNrRWxlbWVudCk6IEdyaWRIVE1MRWxlbWVudCB7IHJldHVybiBHcmlkU3RhY2suZ2V0RWxlbWVudChlbHMpIH1cclxuICAvKiogQGludGVybmFsICovXHJcbiAgcHVibGljIHN0YXRpYyBnZXRHcmlkRWxlbWVudHMoZWxzOiBzdHJpbmcpOiBHcmlkSFRNTEVsZW1lbnRbXSB7IHJldHVybiBVdGlscy5nZXRFbGVtZW50cyhlbHMpIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCBpbml0aWFsaXplIG1hcmdpbiB0b3AvYm90dG9tL2xlZnQvcmlnaHQgYW5kIHVuaXRzICovXHJcbiAgcHJvdGVjdGVkIF9pbml0TWFyZ2luKCk6IEdyaWRTdGFjayB7XHJcblxyXG4gICAgbGV0IGRhdGE6IEhlaWdodERhdGE7XHJcbiAgICBsZXQgbWFyZ2luID0gMDtcclxuXHJcbiAgICAvLyBzdXBwb3J0IHBhc3NpbmcgbXVsdGlwbGUgdmFsdWVzIGxpa2UgQ1NTIChleDogJzVweCAxMHB4IDAgMjBweCcpXHJcbiAgICBsZXQgbWFyZ2luczogc3RyaW5nW10gPSBbXTtcclxuICAgIGlmICh0eXBlb2YgdGhpcy5vcHRzLm1hcmdpbiA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgbWFyZ2lucyA9IHRoaXMub3B0cy5tYXJnaW4uc3BsaXQoJyAnKVxyXG4gICAgfVxyXG4gICAgaWYgKG1hcmdpbnMubGVuZ3RoID09PSAyKSB7IC8vIHRvcC9ib3QsIGxlZnQvcmlnaHQgbGlrZSBDU1NcclxuICAgICAgdGhpcy5vcHRzLm1hcmdpblRvcCA9IHRoaXMub3B0cy5tYXJnaW5Cb3R0b20gPSBtYXJnaW5zWzBdO1xyXG4gICAgICB0aGlzLm9wdHMubWFyZ2luTGVmdCA9IHRoaXMub3B0cy5tYXJnaW5SaWdodCA9IG1hcmdpbnNbMV07XHJcbiAgICB9IGVsc2UgaWYgKG1hcmdpbnMubGVuZ3RoID09PSA0KSB7IC8vIENsb2Nrd2lzZSBsaWtlIENTU1xyXG4gICAgICB0aGlzLm9wdHMubWFyZ2luVG9wID0gbWFyZ2luc1swXTtcclxuICAgICAgdGhpcy5vcHRzLm1hcmdpblJpZ2h0ID0gbWFyZ2luc1sxXTtcclxuICAgICAgdGhpcy5vcHRzLm1hcmdpbkJvdHRvbSA9IG1hcmdpbnNbMl07XHJcbiAgICAgIHRoaXMub3B0cy5tYXJnaW5MZWZ0ID0gbWFyZ2luc1szXTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGRhdGEgPSBVdGlscy5wYXJzZUhlaWdodCh0aGlzLm9wdHMubWFyZ2luKTtcclxuICAgICAgdGhpcy5vcHRzLm1hcmdpblVuaXQgPSBkYXRhLnVuaXQ7XHJcbiAgICAgIG1hcmdpbiA9IHRoaXMub3B0cy5tYXJnaW4gPSBkYXRhLmg7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gc2VlIGlmIHRvcC9ib3R0b20vbGVmdC9yaWdodCBuZWVkIHRvIGJlIHNldCBhcyB3ZWxsXHJcbiAgICBpZiAodGhpcy5vcHRzLm1hcmdpblRvcCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHRoaXMub3B0cy5tYXJnaW5Ub3AgPSBtYXJnaW47XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBkYXRhID0gVXRpbHMucGFyc2VIZWlnaHQodGhpcy5vcHRzLm1hcmdpblRvcCk7XHJcbiAgICAgIHRoaXMub3B0cy5tYXJnaW5Ub3AgPSBkYXRhLmg7XHJcbiAgICAgIGRlbGV0ZSB0aGlzLm9wdHMubWFyZ2luO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLm9wdHMubWFyZ2luQm90dG9tID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgdGhpcy5vcHRzLm1hcmdpbkJvdHRvbSA9IG1hcmdpbjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGRhdGEgPSBVdGlscy5wYXJzZUhlaWdodCh0aGlzLm9wdHMubWFyZ2luQm90dG9tKTtcclxuICAgICAgdGhpcy5vcHRzLm1hcmdpbkJvdHRvbSA9IGRhdGEuaDtcclxuICAgICAgZGVsZXRlIHRoaXMub3B0cy5tYXJnaW47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0cy5tYXJnaW5SaWdodCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHRoaXMub3B0cy5tYXJnaW5SaWdodCA9IG1hcmdpbjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGRhdGEgPSBVdGlscy5wYXJzZUhlaWdodCh0aGlzLm9wdHMubWFyZ2luUmlnaHQpO1xyXG4gICAgICB0aGlzLm9wdHMubWFyZ2luUmlnaHQgPSBkYXRhLmg7XHJcbiAgICAgIGRlbGV0ZSB0aGlzLm9wdHMubWFyZ2luO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLm9wdHMubWFyZ2luTGVmdCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHRoaXMub3B0cy5tYXJnaW5MZWZ0ID0gbWFyZ2luO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZGF0YSA9IFV0aWxzLnBhcnNlSGVpZ2h0KHRoaXMub3B0cy5tYXJnaW5MZWZ0KTtcclxuICAgICAgdGhpcy5vcHRzLm1hcmdpbkxlZnQgPSBkYXRhLmg7XHJcbiAgICAgIGRlbGV0ZSB0aGlzLm9wdHMubWFyZ2luO1xyXG4gICAgfVxyXG4gICAgdGhpcy5vcHRzLm1hcmdpblVuaXQgPSBkYXRhLnVuaXQ7IC8vIGluIGNhc2Ugc2lkZSB3ZXJlIHNwZWxsZWQgb3V0LCB1c2UgdGhvc2UgdW5pdHMgaW5zdGVhZC4uLlxyXG4gICAgaWYgKHRoaXMub3B0cy5tYXJnaW5Ub3AgPT09IHRoaXMub3B0cy5tYXJnaW5Cb3R0b20gJiYgdGhpcy5vcHRzLm1hcmdpbkxlZnQgPT09IHRoaXMub3B0cy5tYXJnaW5SaWdodCAmJiB0aGlzLm9wdHMubWFyZ2luVG9wID09PSB0aGlzLm9wdHMubWFyZ2luUmlnaHQpIHtcclxuICAgICAgdGhpcy5vcHRzLm1hcmdpbiA9IHRoaXMub3B0cy5tYXJnaW5Ub3A7IC8vIG1ha2VzIGl0IGVhc2llciB0byBjaGVjayBmb3Igbm8tb3BzIGluIHNldE1hcmdpbigpXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHN0YXRpYyBHRFJldiA9ICc4LjIuMic7XHJcblxyXG4gIC8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAgKiBkcmFnJmRyb3AgbWV0aG9kcyB0aGF0IHVzZWQgdG8gYmUgc3R1YmJlZCBvdXQgYW5kIGltcGxlbWVudGVkIGluIGRkLWdyaWRzdGFjay50c1xyXG4gICAqIGJ1dCBjYXVzZWQgbG9hZGluZyBpc3N1ZXMgaW4gcHJvZCAtIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ3JpZHN0YWNrL2dyaWRzdGFjay5qcy9pc3N1ZXMvMjAzOVxyXG4gICAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAgKi9cclxuXHJcbiAgLyoqIGdldCB0aGUgZ2xvYmFsIChidXQgc3RhdGljIHRvIHRoaXMgY29kZSkgREQgaW1wbGVtZW50YXRpb24gKi9cclxuICBwdWJsaWMgc3RhdGljIGdldEREKCk6IERER3JpZFN0YWNrIHtcclxuICAgIHJldHVybiBkZDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGNhbGwgdG8gc2V0dXAgZHJhZ2dpbmcgaW4gZnJvbSB0aGUgb3V0c2lkZSAoc2F5IHRvb2xiYXIpLCBieSBzcGVjaWZ5aW5nIHRoZSBjbGFzcyBzZWxlY3Rpb24gYW5kIG9wdGlvbnMuXHJcbiAgICogQ2FsbGVkIGR1cmluZyBHcmlkU3RhY2suaW5pdCgpIGFzIG9wdGlvbnMsIGJ1dCBjYW4gYWxzbyBiZSBjYWxsZWQgZGlyZWN0bHkgKGxhc3QgcGFyYW0gYXJlIHVzZWQpIGluIGNhc2UgdGhlIHRvb2xiYXJcclxuICAgKiBpcyBkeW5hbWljYWxseSBjcmVhdGUgYW5kIG5lZWRzIHRvIGJlIHNldCBsYXRlci5cclxuICAgKiBAcGFyYW0gZHJhZ0luIHN0cmluZyBzZWxlY3RvciAoZXg6ICcuc2lkZWJhciAuZ3JpZC1zdGFjay1pdGVtJykgb3IgbGlzdCBvZiBkb20gZWxlbWVudHNcclxuICAgKiBAcGFyYW0gZHJhZ0luT3B0aW9ucyBvcHRpb25zIC0gc2VlIERERHJhZ0luT3B0LiAoZGVmYXVsdDoge2hhbmRsZTogJy5ncmlkLXN0YWNrLWl0ZW0tY29udGVudCcsIGFwcGVuZFRvOiAnYm9keSd9XHJcbiAgICogQHBhcmFtIHJvb3Qgb3B0aW9uYWwgcm9vdCB3aGljaCBkZWZhdWx0cyB0byBkb2N1bWVudCAoZm9yIHNoYWRvdyBkb20gcGFzIHRoZSBwYXJlbnQgSFRNTERvY3VtZW50KVxyXG4gICAqKi9cclxuICBwdWJsaWMgc3RhdGljIHNldHVwRHJhZ0luKGRyYWdJbj86IHN0cmluZyB8IEhUTUxFbGVtZW50W10sIGRyYWdJbk9wdGlvbnM/OiBERERyYWdJbk9wdCwgcm9vdDogSFRNTEVsZW1lbnQgfCBEb2N1bWVudCA9IGRvY3VtZW50KTogdm9pZCB7XHJcbiAgICBpZiAoZHJhZ0luT3B0aW9ucz8ucGF1c2UgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICBERE1hbmFnZXIucGF1c2VEcmFnID0gZHJhZ0luT3B0aW9ucy5wYXVzZTtcclxuICAgIH1cclxuXHJcbiAgICBkcmFnSW5PcHRpb25zID0gey4uLmRyYWdJbkRlZmF1bHRPcHRpb25zLCAuLi4oZHJhZ0luT3B0aW9ucyB8fCB7fSl9O1xyXG4gICAgbGV0IGVsczogSFRNTEVsZW1lbnRbXSA9ICh0eXBlb2YgZHJhZ0luID09PSAnc3RyaW5nJykgPyBVdGlscy5nZXRFbGVtZW50cyhkcmFnSW4sIHJvb3QpIDogZHJhZ0luO1xyXG4gICAgaWYgKGVscy5sZW5ndGgpIGVscz8uZm9yRWFjaChlbCA9PiB7XHJcbiAgICAgIGlmICghZGQuaXNEcmFnZ2FibGUoZWwpKSBkZC5kcmFnSW4oZWwsIGRyYWdJbk9wdGlvbnMpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFbmFibGVzL0Rpc2FibGVzIGRyYWdnaW5nIGJ5IHRoZSB1c2VyIG9mIHNwZWNpZmljIGdyaWQgZWxlbWVudC4gSWYgeW91IHdhbnQgYWxsIGl0ZW1zLCBhbmQgaGF2ZSBpdCBhZmZlY3QgZnV0dXJlIGl0ZW1zLCB1c2UgZW5hYmxlTW92ZSgpIGluc3RlYWQuIE5vLW9wIGZvciBzdGF0aWMgZ3JpZHMuXHJcbiAgICogSUYgeW91IGFyZSBsb29raW5nIHRvIHByZXZlbnQgYW4gaXRlbSBmcm9tIG1vdmluZyAoZHVlIHRvIGJlaW5nIHB1c2hlZCBhcm91bmQgYnkgYW5vdGhlciBkdXJpbmcgY29sbGlzaW9uKSB1c2UgbG9ja2VkIHByb3BlcnR5IGluc3RlYWQuXHJcbiAgICogQHBhcmFtIGVscyB3aWRnZXQgb3Igc2VsZWN0b3IgdG8gbW9kaWZ5LlxyXG4gICAqIEBwYXJhbSB2YWwgaWYgdHJ1ZSB3aWRnZXQgd2lsbCBiZSBkcmFnZ2FibGUsIGFzc3VtaW5nIHRoZSBwYXJlbnQgZ3JpZCBpc24ndCBub01vdmUgb3Igc3RhdGljLlxyXG4gICAqL1xyXG4gIHB1YmxpYyBtb3ZhYmxlKGVsczogR3JpZFN0YWNrRWxlbWVudCwgdmFsOiBib29sZWFuKTogR3JpZFN0YWNrIHtcclxuICAgIGlmICh0aGlzLm9wdHMuc3RhdGljR3JpZCkgcmV0dXJuIHRoaXM7IC8vIGNhbid0IG1vdmUgYSBzdGF0aWMgZ3JpZCFcclxuICAgIEdyaWRTdGFjay5nZXRFbGVtZW50cyhlbHMpLmZvckVhY2goZWwgPT4ge1xyXG4gICAgICBsZXQgbiA9IGVsLmdyaWRzdGFja05vZGU7XHJcbiAgICAgIGlmICghbikgcmV0dXJuO1xyXG4gICAgICB2YWwgPyBkZWxldGUgbi5ub01vdmUgOiBuLm5vTW92ZSA9IHRydWU7XHJcbiAgICAgIHRoaXMuX3ByZXBhcmVEcmFnRHJvcEJ5Tm9kZShuKTsgLy8gaW5pdCBERCBpZiBuZWVkIGJlLCBhbmQgYWRqdXN0XHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRW5hYmxlcy9EaXNhYmxlcyB1c2VyIHJlc2l6aW5nIG9mIHNwZWNpZmljIGdyaWQgZWxlbWVudC4gSWYgeW91IHdhbnQgYWxsIGl0ZW1zLCBhbmQgaGF2ZSBpdCBhZmZlY3QgZnV0dXJlIGl0ZW1zLCB1c2UgZW5hYmxlUmVzaXplKCkgaW5zdGVhZC4gTm8tb3AgZm9yIHN0YXRpYyBncmlkcy5cclxuICAgKiBAcGFyYW0gZWxzICB3aWRnZXQgb3Igc2VsZWN0b3IgdG8gbW9kaWZ5XHJcbiAgICogQHBhcmFtIHZhbCAgaWYgdHJ1ZSB3aWRnZXQgd2lsbCBiZSByZXNpemFibGUsIGFzc3VtaW5nIHRoZSBwYXJlbnQgZ3JpZCBpc24ndCBub1Jlc2l6ZSBvciBzdGF0aWMuXHJcbiAgICovXHJcbiAgcHVibGljIHJlc2l6YWJsZShlbHM6IEdyaWRTdGFja0VsZW1lbnQsIHZhbDogYm9vbGVhbik6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAodGhpcy5vcHRzLnN0YXRpY0dyaWQpIHJldHVybiB0aGlzOyAvLyBjYW4ndCByZXNpemUgYSBzdGF0aWMgZ3JpZCFcclxuICAgIEdyaWRTdGFjay5nZXRFbGVtZW50cyhlbHMpLmZvckVhY2goZWwgPT4ge1xyXG4gICAgICBsZXQgbiA9IGVsLmdyaWRzdGFja05vZGU7XHJcbiAgICAgIGlmICghbikgcmV0dXJuO1xyXG4gICAgICB2YWwgPyBkZWxldGUgbi5ub1Jlc2l6ZSA6IG4ubm9SZXNpemUgPSB0cnVlO1xyXG4gICAgICB0aGlzLl9wcmVwYXJlRHJhZ0Ryb3BCeU5vZGUobik7IC8vIGluaXQgREQgaWYgbmVlZCBiZSwgYW5kIGFkanVzdFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRlbXBvcmFyaWx5IGRpc2FibGVzIHdpZGdldHMgbW92aW5nL3Jlc2l6aW5nLlxyXG4gICAqIElmIHlvdSB3YW50IGEgbW9yZSBwZXJtYW5lbnQgd2F5ICh3aGljaCBmcmVlemVzIHVwIHJlc291cmNlcykgdXNlIGBzZXRTdGF0aWModHJ1ZSlgIGluc3RlYWQuXHJcbiAgICogTm90ZTogbm8tb3AgZm9yIHN0YXRpYyBncmlkXHJcbiAgICogVGhpcyBpcyBhIHNob3J0Y3V0IGZvcjpcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqICBncmlkLmVuYWJsZU1vdmUoZmFsc2UpO1xyXG4gICAqICBncmlkLmVuYWJsZVJlc2l6ZShmYWxzZSk7XHJcbiAgICogQHBhcmFtIHJlY3Vyc2UgdHJ1ZSAoZGVmYXVsdCkgaWYgc3ViLWdyaWRzIGFsc28gZ2V0IHVwZGF0ZWRcclxuICAgKi9cclxuICBwdWJsaWMgZGlzYWJsZShyZWN1cnNlID0gdHJ1ZSk6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAodGhpcy5vcHRzLnN0YXRpY0dyaWQpIHJldHVybjtcclxuICAgIHRoaXMuZW5hYmxlTW92ZShmYWxzZSwgcmVjdXJzZSk7XHJcbiAgICB0aGlzLmVuYWJsZVJlc2l6ZShmYWxzZSwgcmVjdXJzZSk7XHJcbiAgICB0aGlzLl90cmlnZ2VyRXZlbnQoJ2Rpc2FibGUnKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBSZS1lbmFibGVzIHdpZGdldHMgbW92aW5nL3Jlc2l6aW5nIC0gc2VlIGRpc2FibGUoKS5cclxuICAgKiBOb3RlOiBuby1vcCBmb3Igc3RhdGljIGdyaWQuXHJcbiAgICogVGhpcyBpcyBhIHNob3J0Y3V0IGZvcjpcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqICBncmlkLmVuYWJsZU1vdmUodHJ1ZSk7XHJcbiAgICogIGdyaWQuZW5hYmxlUmVzaXplKHRydWUpO1xyXG4gICAqIEBwYXJhbSByZWN1cnNlIHRydWUgKGRlZmF1bHQpIGlmIHN1Yi1ncmlkcyBhbHNvIGdldCB1cGRhdGVkXHJcbiAgICovXHJcbiAgcHVibGljIGVuYWJsZShyZWN1cnNlID0gdHJ1ZSk6IEdyaWRTdGFjayB7XHJcbiAgICBpZiAodGhpcy5vcHRzLnN0YXRpY0dyaWQpIHJldHVybjtcclxuICAgIHRoaXMuZW5hYmxlTW92ZSh0cnVlLCByZWN1cnNlKTtcclxuICAgIHRoaXMuZW5hYmxlUmVzaXplKHRydWUsIHJlY3Vyc2UpO1xyXG4gICAgdGhpcy5fdHJpZ2dlckV2ZW50KCdlbmFibGUnKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRW5hYmxlcy9kaXNhYmxlcyB3aWRnZXQgbW92aW5nLiBOby1vcCBmb3Igc3RhdGljIGdyaWRzLCBhbmQgbG9jYWxseSBkZWZpbmVkIGl0ZW1zIHN0aWxsIG92ZXJydWxlXHJcbiAgICogQHBhcmFtIHJlY3Vyc2UgdHJ1ZSAoZGVmYXVsdCkgaWYgc3ViLWdyaWRzIGFsc28gZ2V0IHVwZGF0ZWRcclxuICAgKi9cclxuICBwdWJsaWMgZW5hYmxlTW92ZShkb0VuYWJsZTogYm9vbGVhbiwgcmVjdXJzZSA9IHRydWUpOiBHcmlkU3RhY2sge1xyXG4gICAgaWYgKHRoaXMub3B0cy5zdGF0aWNHcmlkKSByZXR1cm4gdGhpczsgLy8gY2FuJ3QgbW92ZSBhIHN0YXRpYyBncmlkIVxyXG4gICAgZG9FbmFibGUgPyBkZWxldGUgdGhpcy5vcHRzLmRpc2FibGVEcmFnIDogdGhpcy5vcHRzLmRpc2FibGVEcmFnID0gdHJ1ZTsgLy8gRklSU1QgYmVmb3JlIHdlIHVwZGF0ZSBjaGlsZHJlbiBhcyBncmlkIG92ZXJyaWRlcyAjMTY1OFxyXG4gICAgdGhpcy5lbmdpbmUubm9kZXMuZm9yRWFjaChuID0+IHtcclxuICAgICAgdGhpcy5fcHJlcGFyZURyYWdEcm9wQnlOb2RlKG4pO1xyXG4gICAgICBpZiAobi5zdWJHcmlkICYmIHJlY3Vyc2UpIG4uc3ViR3JpZC5lbmFibGVNb3ZlKGRvRW5hYmxlLCByZWN1cnNlKTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFbmFibGVzL2Rpc2FibGVzIHdpZGdldCByZXNpemluZy4gTm8tb3AgZm9yIHN0YXRpYyBncmlkcy5cclxuICAgKiBAcGFyYW0gcmVjdXJzZSB0cnVlIChkZWZhdWx0KSBpZiBzdWItZ3JpZHMgYWxzbyBnZXQgdXBkYXRlZFxyXG4gICAqL1xyXG4gIHB1YmxpYyBlbmFibGVSZXNpemUoZG9FbmFibGU6IGJvb2xlYW4sIHJlY3Vyc2UgPSB0cnVlKTogR3JpZFN0YWNrIHtcclxuICAgIGlmICh0aGlzLm9wdHMuc3RhdGljR3JpZCkgcmV0dXJuIHRoaXM7IC8vIGNhbid0IHNpemUgYSBzdGF0aWMgZ3JpZCFcclxuICAgIGRvRW5hYmxlID8gZGVsZXRlIHRoaXMub3B0cy5kaXNhYmxlUmVzaXplIDogdGhpcy5vcHRzLmRpc2FibGVSZXNpemUgPSB0cnVlOyAvLyBGSVJTVCBiZWZvcmUgd2UgdXBkYXRlIGNoaWxkcmVuIGFzIGdyaWQgb3ZlcnJpZGVzICMxNjU4XHJcbiAgICB0aGlzLmVuZ2luZS5ub2Rlcy5mb3JFYWNoKG4gPT4ge1xyXG4gICAgICB0aGlzLl9wcmVwYXJlRHJhZ0Ryb3BCeU5vZGUobik7XHJcbiAgICAgIGlmIChuLnN1YkdyaWQgJiYgcmVjdXJzZSkgbi5zdWJHcmlkLmVuYWJsZVJlc2l6ZShkb0VuYWJsZSwgcmVjdXJzZSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCByZW1vdmVzIGFueSBkcmFnJmRyb3AgcHJlc2VudCAoY2FsbGVkIGR1cmluZyBkZXN0cm95KSAqL1xyXG4gIHByb3RlY3RlZCBfcmVtb3ZlREQoZWw6IERERWxlbWVudEhvc3QpOiBHcmlkU3RhY2sge1xyXG4gICAgZGQuZHJhZ2dhYmxlKGVsLCAnZGVzdHJveScpLnJlc2l6YWJsZShlbCwgJ2Rlc3Ryb3knKTtcclxuICAgIGlmIChlbC5ncmlkc3RhY2tOb2RlKSB7XHJcbiAgICAgIGRlbGV0ZSBlbC5ncmlkc3RhY2tOb2RlLl9pbml0REQ7IC8vIHJlc2V0IG91ciBERCBpbml0IGZsYWdcclxuICAgIH1cclxuICAgIGRlbGV0ZSBlbC5kZEVsZW1lbnQ7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgY2FsbGVkIHRvIGFkZCBkcmFnIG92ZXIgdG8gc3VwcG9ydCB3aWRnZXRzIGJlaW5nIGFkZGVkIGV4dGVybmFsbHkgKi9cclxuICBwcm90ZWN0ZWQgX3NldHVwQWNjZXB0V2lkZ2V0KCk6IEdyaWRTdGFjayB7XHJcblxyXG4gICAgLy8gY2hlY2sgaWYgd2UgbmVlZCB0byBkaXNhYmxlIHRoaW5nc1xyXG4gICAgaWYgKHRoaXMub3B0cy5zdGF0aWNHcmlkIHx8ICghdGhpcy5vcHRzLmFjY2VwdFdpZGdldHMgJiYgIXRoaXMub3B0cy5yZW1vdmFibGUpKSB7XHJcbiAgICAgIGRkLmRyb3BwYWJsZSh0aGlzLmVsLCAnZGVzdHJveScpO1xyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICAvLyB2YXJzIHNoYXJlZCBhY3Jvc3MgYWxsIG1ldGhvZHNcclxuICAgIGxldCBjZWxsSGVpZ2h0OiBudW1iZXIsIGNlbGxXaWR0aDogbnVtYmVyO1xyXG5cclxuICAgIGxldCBvbkRyYWcgPSAoZXZlbnQ6IERyYWdFdmVudCwgZWw6IEdyaWRJdGVtSFRNTEVsZW1lbnQsIGhlbHBlcjogR3JpZEl0ZW1IVE1MRWxlbWVudCkgPT4ge1xyXG4gICAgICBsZXQgbm9kZSA9IGVsLmdyaWRzdGFja05vZGU7XHJcbiAgICAgIGlmICghbm9kZSkgcmV0dXJuO1xyXG5cclxuICAgICAgaGVscGVyID0gaGVscGVyIHx8IGVsO1xyXG4gICAgICBsZXQgcGFyZW50ID0gdGhpcy5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgbGV0IHt0b3AsIGxlZnR9ID0gaGVscGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBsZWZ0IC09IHBhcmVudC5sZWZ0O1xyXG4gICAgICB0b3AgLT0gcGFyZW50LnRvcDtcclxuICAgICAgbGV0IHVpOiBERFVJRGF0YSA9IHtwb3NpdGlvbjoge3RvcCwgbGVmdH19O1xyXG5cclxuICAgICAgaWYgKG5vZGUuX3RlbXBvcmFyeVJlbW92ZWQpIHtcclxuICAgICAgICBub2RlLnggPSBNYXRoLm1heCgwLCBNYXRoLnJvdW5kKGxlZnQgLyBjZWxsV2lkdGgpKTtcclxuICAgICAgICBub2RlLnkgPSBNYXRoLm1heCgwLCBNYXRoLnJvdW5kKHRvcCAvIGNlbGxIZWlnaHQpKTtcclxuICAgICAgICBkZWxldGUgbm9kZS5hdXRvUG9zaXRpb247XHJcbiAgICAgICAgdGhpcy5lbmdpbmUubm9kZUJvdW5kRml4KG5vZGUpO1xyXG5cclxuICAgICAgICAvLyBkb24ndCBhY2NlcHQgKmluaXRpYWwqIGxvY2F0aW9uIGlmIGRvZXNuJ3QgZml0ICMxNDE5IChsb2NrZWQgZHJvcCByZWdpb24sIG9yIGNhbid0IGdyb3cpLCBidXQgbWF5YmUgdHJ5IGlmIGl0IHdpbGwgZ28gc29tZXdoZXJlXHJcbiAgICAgICAgaWYgKCF0aGlzLmVuZ2luZS53aWxsSXRGaXQobm9kZSkpIHtcclxuICAgICAgICAgIG5vZGUuYXV0b1Bvc2l0aW9uID0gdHJ1ZTsgLy8gaWdub3JlIHgseSBhbmQgdHJ5IGZvciBhbnkgc2xvdC4uLlxyXG4gICAgICAgICAgaWYgKCF0aGlzLmVuZ2luZS53aWxsSXRGaXQobm9kZSkpIHtcclxuICAgICAgICAgICAgZGQub2ZmKGVsLCAnZHJhZycpOyAvLyBzdG9wIGNhbGxpbmcgdXNcclxuICAgICAgICAgICAgcmV0dXJuOyAvLyBmdWxsIGdyaWQgb3IgY2FuJ3QgZ3Jvd1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKG5vZGUuX3dpbGxGaXRQb3MpIHtcclxuICAgICAgICAgICAgLy8gdXNlIHRoZSBhdXRvIHBvc2l0aW9uIGluc3RlYWQgIzE2ODdcclxuICAgICAgICAgICAgVXRpbHMuY29weVBvcyhub2RlLCBub2RlLl93aWxsRml0UG9zKTtcclxuICAgICAgICAgICAgZGVsZXRlIG5vZGUuX3dpbGxGaXRQb3M7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyByZS11c2UgdGhlIGV4aXN0aW5nIG5vZGUgZHJhZ2dpbmcgbWV0aG9kXHJcbiAgICAgICAgdGhpcy5fb25TdGFydE1vdmluZyhoZWxwZXIsIGV2ZW50LCB1aSwgbm9kZSwgY2VsbFdpZHRoLCBjZWxsSGVpZ2h0KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyByZS11c2UgdGhlIGV4aXN0aW5nIG5vZGUgZHJhZ2dpbmcgdGhhdCBkb2VzIHNvIG11Y2ggb2YgdGhlIGNvbGxpc2lvbiBkZXRlY3Rpb25cclxuICAgICAgICB0aGlzLl9kcmFnT3JSZXNpemUoaGVscGVyLCBldmVudCwgdWksIG5vZGUsIGNlbGxXaWR0aCwgY2VsbEhlaWdodCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBkZC5kcm9wcGFibGUodGhpcy5lbCwge1xyXG4gICAgICBhY2NlcHQ6IChlbDogR3JpZEl0ZW1IVE1MRWxlbWVudCkgPT4ge1xyXG4gICAgICAgIGxldCBub2RlOiBHcmlkU3RhY2tOb2RlID0gZWwuZ3JpZHN0YWNrTm9kZTtcclxuICAgICAgICAvLyBzZXQgYWNjZXB0IGRyb3AgdG8gdHJ1ZSBvbiBvdXJzZWxmICh3aGljaCB3ZSBpZ25vcmUpIHNvIHdlIGRvbid0IGdldCBcImNhbid0IGRyb3BcIiBpY29uIGluIEhUTUw1IG1vZGUgd2hpbGUgbW92aW5nXHJcbiAgICAgICAgaWYgKG5vZGU/LmdyaWQgPT09IHRoaXMpIHJldHVybiB0cnVlO1xyXG4gICAgICAgIGlmICghdGhpcy5vcHRzLmFjY2VwdFdpZGdldHMpIHJldHVybiBmYWxzZTtcclxuICAgICAgICAvLyBjaGVjayBmb3IgYWNjZXB0IG1ldGhvZCBvciBjbGFzcyBtYXRjaGluZ1xyXG4gICAgICAgIGxldCBjYW5BY2NlcHQgPSB0cnVlO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5vcHRzLmFjY2VwdFdpZGdldHMgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgIGNhbkFjY2VwdCA9IHRoaXMub3B0cy5hY2NlcHRXaWRnZXRzKGVsKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgbGV0IHNlbGVjdG9yID0gKHRoaXMub3B0cy5hY2NlcHRXaWRnZXRzID09PSB0cnVlID8gJy5ncmlkLXN0YWNrLWl0ZW0nIDogdGhpcy5vcHRzLmFjY2VwdFdpZGdldHMgYXMgc3RyaW5nKTtcclxuICAgICAgICAgIGNhbkFjY2VwdCA9IGVsLm1hdGNoZXMoc2VsZWN0b3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBmaW5hbGx5IGNoZWNrIHRvIG1ha2Ugc3VyZSB3ZSBhY3R1YWxseSBoYXZlIHNwYWNlIGxlZnQgIzE1NzFcclxuICAgICAgICBpZiAoY2FuQWNjZXB0ICYmIG5vZGUgJiYgdGhpcy5vcHRzLm1heFJvdykge1xyXG4gICAgICAgICAgbGV0IG4gPSB7dzogbm9kZS53LCBoOiBub2RlLmgsIG1pblc6IG5vZGUubWluVywgbWluSDogbm9kZS5taW5IfTsgLy8gb25seSB3aWR0aC9oZWlnaHQgbWF0dGVycyBhbmQgYXV0b1Bvc2l0aW9uXHJcbiAgICAgICAgICBjYW5BY2NlcHQgPSB0aGlzLmVuZ2luZS53aWxsSXRGaXQobik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjYW5BY2NlcHQ7XHJcbiAgICAgIH1cclxuICAgIH0pXHJcbiAgICAvKipcclxuICAgICAqIGVudGVyaW5nIG91ciBncmlkIGFyZWFcclxuICAgICAqL1xyXG4gICAgICAub24odGhpcy5lbCwgJ2Ryb3BvdmVyJywgKGV2ZW50OiBFdmVudCwgZWw6IEdyaWRJdGVtSFRNTEVsZW1lbnQsIGhlbHBlcjogR3JpZEl0ZW1IVE1MRWxlbWVudCkgPT4ge1xyXG4gICAgICAvLyBjb25zb2xlLmxvZyhgb3ZlciAke3RoaXMuZWwuZ3JpZHN0YWNrLm9wdHMuaWR9ICR7Y291bnQrK31gKTsgLy8gVEVTVFxyXG4gICAgICAgIGxldCBub2RlID0gZWwuZ3JpZHN0YWNrTm9kZTtcclxuICAgICAgICAvLyBpZ25vcmUgZHJvcCBlbnRlciBvbiBvdXJzZWxmICh1bmxlc3Mgd2UgdGVtcG9yYXJpbHkgcmVtb3ZlZCkgd2hpY2ggaGFwcGVucyBvbiBhIHNpbXBsZSBkcmFnIG9mIG91ciBpdGVtXHJcbiAgICAgICAgaWYgKG5vZGU/LmdyaWQgPT09IHRoaXMgJiYgIW5vZGUuX3RlbXBvcmFyeVJlbW92ZWQpIHtcclxuICAgICAgICAvLyBkZWxldGUgbm9kZS5fYWRkZWQ7IC8vIHJlc2V0IHRoaXMgdG8gdHJhY2sgcGxhY2Vob2xkZXIgYWdhaW4gaW4gY2FzZSB3ZSB3ZXJlIG92ZXIgb3RoZXIgZ3JpZCAjMTQ4NCAoZHJvcG91dCBkb2Vzbid0IGFsd2F5cyBjbGVhcilcclxuICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gcHJldmVudCBwYXJlbnQgZnJvbSByZWNlaXZpbmcgbXNnICh3aGljaCBtYXkgYmUgYSBncmlkIGFzIHdlbGwpXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBmaXggIzE1Nzggd2hlbiBkcmFnZ2luZyBmYXN0LCB3ZSBtYXkgbm90IGdldCBhIGxlYXZlIG9uIHRoZSBwcmV2aW91cyBncmlkIHNvIGZvcmNlIG9uZSBub3dcclxuICAgICAgICBpZiAobm9kZT8uZ3JpZCAmJiBub2RlLmdyaWQgIT09IHRoaXMgJiYgIW5vZGUuX3RlbXBvcmFyeVJlbW92ZWQpIHtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZygnZHJvcG92ZXIgd2l0aG91dCBsZWF2ZScpOyAvLyBURVNUXHJcbiAgICAgICAgICBsZXQgb3RoZXJHcmlkID0gbm9kZS5ncmlkO1xyXG4gICAgICAgICAgb3RoZXJHcmlkLl9sZWF2ZShlbCwgaGVscGVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGNhY2hlIGNlbGwgZGltZW5zaW9ucyAod2hpY2ggZG9uJ3QgY2hhbmdlKSwgcG9zaXRpb24gY2FuIGFuaW1hdGUgaWYgd2UgcmVtb3ZlZCBhbiBpdGVtIGluIG90aGVyR3JpZCB0aGF0IGFmZmVjdHMgdXMuLi5cclxuICAgICAgICBjZWxsV2lkdGggPSB0aGlzLmNlbGxXaWR0aCgpO1xyXG4gICAgICAgIGNlbGxIZWlnaHQgPSB0aGlzLmdldENlbGxIZWlnaHQodHJ1ZSk7XHJcblxyXG4gICAgICAgIC8vIGxvYWQgYW55IGVsZW1lbnQgYXR0cmlidXRlcyBpZiB3ZSBkb24ndCBoYXZlIGEgbm9kZVxyXG4gICAgICAgIGlmICghbm9kZSkge1xyXG4gICAgICAgICAgbm9kZSA9IHRoaXMuX3JlYWRBdHRyKGVsLCBmYWxzZSk7IC8vIGRvbid0IHdpcGUgZXh0ZXJuYWwgKGUuZy4gZHJhZyB0b29sYmFyKSBhdHRyICMyMzU0XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghbm9kZS5ncmlkKSB7XHJcbiAgICAgICAgICBub2RlLl9pc0V4dGVybmFsID0gdHJ1ZTtcclxuICAgICAgICAgIGVsLmdyaWRzdGFja05vZGUgPSBub2RlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBncmlkIHNpemUgYmFzZWQgb24gZWxlbWVudCBvdXRlciBzaXplXHJcbiAgICAgICAgaGVscGVyID0gaGVscGVyIHx8IGVsO1xyXG4gICAgICAgIGxldCB3ID0gbm9kZS53IHx8IE1hdGgucm91bmQoaGVscGVyLm9mZnNldFdpZHRoIC8gY2VsbFdpZHRoKSB8fCAxO1xyXG4gICAgICAgIGxldCBoID0gbm9kZS5oIHx8IE1hdGgucm91bmQoaGVscGVyLm9mZnNldEhlaWdodCAvIGNlbGxIZWlnaHQpIHx8IDE7XHJcblxyXG4gICAgICAgIC8vIGlmIHRoZSBpdGVtIGNhbWUgZnJvbSBhbm90aGVyIGdyaWQsIG1ha2UgYSBjb3B5IGFuZCBzYXZlIHRoZSBvcmlnaW5hbCBpbmZvIGluIGNhc2Ugd2UgZ28gYmFjayB0aGVyZVxyXG4gICAgICAgIGlmIChub2RlLmdyaWQgJiYgbm9kZS5ncmlkICE9PSB0aGlzKSB7XHJcbiAgICAgICAgLy8gY29weSB0aGUgbm9kZSBvcmlnaW5hbCB2YWx1ZXMgKG1pbi9tYXgvaWQvZXRjLi4uKSBidXQgb3ZlcnJpZGUgd2lkdGgvaGVpZ2h0L290aGVyIGZsYWdzIHdoaWNoIGFyZSB0aGlzIGdyaWQgc3BlY2lmaWNcclxuICAgICAgICAvLyBjb25zb2xlLmxvZygnZHJvcG92ZXIgY2xvbmluZyBub2RlJyk7IC8vIFRFU1RcclxuICAgICAgICAgIGlmICghZWwuX2dyaWRzdGFja05vZGVPcmlnKSBlbC5fZ3JpZHN0YWNrTm9kZU9yaWcgPSBub2RlOyAvLyBzaG91bGRuJ3QgaGF2ZSBtdWx0aXBsZSBuZXN0ZWQhXHJcbiAgICAgICAgICBlbC5ncmlkc3RhY2tOb2RlID0gbm9kZSA9IHsuLi5ub2RlLCB3LCBoLCBncmlkOiB0aGlzfTtcclxuICAgICAgICAgIHRoaXMuZW5naW5lLmNsZWFudXBOb2RlKG5vZGUpXHJcbiAgICAgICAgICAgIC5ub2RlQm91bmRGaXgobm9kZSk7XHJcbiAgICAgICAgICAvLyByZXN0b3JlIHNvbWUgaW50ZXJuYWwgZmllbGRzIHdlIG5lZWQgYWZ0ZXIgY2xlYXJpbmcgdGhlbSBhbGxcclxuICAgICAgICAgIG5vZGUuX2luaXRERCA9XHJcbiAgICAgICAgbm9kZS5faXNFeHRlcm5hbCA9ICAvLyBET00gbmVlZHMgdG8gYmUgcmUtcGFyZW50ZWQgb24gYSBkcm9wXHJcbiAgICAgICAgbm9kZS5fdGVtcG9yYXJ5UmVtb3ZlZCA9IHRydWU7IC8vIHNvIGl0IGNhbiBiZSBpbnNlcnRlZCBvbkRyYWcgYmVsb3dcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgbm9kZS53ID0gdzsgbm9kZS5oID0gaDtcclxuICAgICAgICAgIG5vZGUuX3RlbXBvcmFyeVJlbW92ZWQgPSB0cnVlOyAvLyBzbyB3ZSBjYW4gaW5zZXJ0IGl0XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBjbGVhciBhbnkgbWFya2VkIGZvciBjb21wbGV0ZSByZW1vdmFsIChOb3RlOiBkb24ndCBjaGVjayBfaXNBYm91dFRvUmVtb3ZlIGFzIHRoYXQgaXMgY2xlYXJlZCBhYm92ZSAtIGp1c3QgZG8gaXQpXHJcbiAgICAgICAgdGhpcy5faXRlbVJlbW92aW5nKG5vZGUuZWwsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgZGQub24oZWwsICdkcmFnJywgb25EcmFnKTtcclxuICAgICAgICAvLyBtYWtlIHN1cmUgdGhpcyBpcyBjYWxsZWQgYXQgbGVhc3Qgb25jZSB3aGVuIGdvaW5nIGZhc3QgIzE1NzhcclxuICAgICAgICBvbkRyYWcoZXZlbnQgYXMgRHJhZ0V2ZW50LCBlbCwgaGVscGVyKTtcclxuICAgICAgICByZXR1cm4gZmFsc2U7IC8vIHByZXZlbnQgcGFyZW50IGZyb20gcmVjZWl2aW5nIG1zZyAod2hpY2ggbWF5IGJlIGEgZ3JpZCBhcyB3ZWxsKVxyXG4gICAgICB9KVxyXG4gICAgLyoqXHJcbiAgICAgKiBMZWF2aW5nIG91ciBncmlkIGFyZWEuLi5cclxuICAgICAqL1xyXG4gICAgICAub24odGhpcy5lbCwgJ2Ryb3BvdXQnLCAoZXZlbnQsIGVsOiBHcmlkSXRlbUhUTUxFbGVtZW50LCBoZWxwZXI6IEdyaWRJdGVtSFRNTEVsZW1lbnQpID0+IHtcclxuICAgICAgLy8gY29uc29sZS5sb2coYG91dCAke3RoaXMuZWwuZ3JpZHN0YWNrLm9wdHMuaWR9ICR7Y291bnQrK31gKTsgLy8gVEVTVFxyXG4gICAgICAgIGxldCBub2RlID0gZWwuZ3JpZHN0YWNrTm9kZTtcclxuICAgICAgICBpZiAoIW5vZGUpIHJldHVybiBmYWxzZTtcclxuICAgICAgICAvLyBmaXggIzE1Nzggd2hlbiBkcmFnZ2luZyBmYXN0LCB3ZSBtaWdodCBnZXQgbGVhdmUgYWZ0ZXIgb3RoZXIgZ3JpZCBnZXRzIGVudGVyICh3aGljaCBjYWxscyB1cyB0byBjbGVhbilcclxuICAgICAgICAvLyBzbyBza2lwIHRoaXMgb25lIGlmIHdlJ3JlIG5vdCB0aGUgYWN0aXZlIGdyaWQgcmVhbGx5Li5cclxuICAgICAgICBpZiAoIW5vZGUuZ3JpZCB8fCBub2RlLmdyaWQgPT09IHRoaXMpIHtcclxuICAgICAgICAgIHRoaXMuX2xlYXZlKGVsLCBoZWxwZXIpO1xyXG4gICAgICAgICAgLy8gaWYgd2Ugd2VyZSBjcmVhdGVkIGFzIHRlbXBvcmFyeSBuZXN0ZWQgZ3JpZCwgZ28gYmFjayB0byBiZWZvcmUgc3RhdGVcclxuICAgICAgICAgIGlmICh0aGlzLl9pc1RlbXApIHtcclxuICAgICAgICAgICAgdGhpcy5yZW1vdmVBc1N1YkdyaWQobm9kZSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTsgLy8gcHJldmVudCBwYXJlbnQgZnJvbSByZWNlaXZpbmcgbXNnICh3aGljaCBtYXkgYmUgZ3JpZCBhcyB3ZWxsKVxyXG4gICAgICB9KVxyXG4gICAgLyoqXHJcbiAgICAgKiBlbmQgLSByZWxlYXNpbmcgdGhlIG1vdXNlXHJcbiAgICAgKi9cclxuICAgICAgLm9uKHRoaXMuZWwsICdkcm9wJywgKGV2ZW50LCBlbDogR3JpZEl0ZW1IVE1MRWxlbWVudCwgaGVscGVyOiBHcmlkSXRlbUhUTUxFbGVtZW50KSA9PiB7XHJcbiAgICAgICAgbGV0IG5vZGUgPSBlbC5ncmlkc3RhY2tOb2RlO1xyXG4gICAgICAgIC8vIGlnbm9yZSBkcm9wIG9uIG91cnNlbGYgZnJvbSBvdXJzZWxmIHRoYXQgZGlkbid0IGNvbWUgZnJvbSB0aGUgb3V0c2lkZSAtIGRyYWdlbmQgd2lsbCBoYW5kbGUgdGhlIHNpbXBsZSBtb3ZlIGluc3RlYWRcclxuICAgICAgICBpZiAobm9kZT8uZ3JpZCA9PT0gdGhpcyAmJiAhbm9kZS5faXNFeHRlcm5hbCkgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgICAgICBsZXQgd2FzQWRkZWQgPSAhIXRoaXMucGxhY2Vob2xkZXIucGFyZW50RWxlbWVudDsgLy8gc2tpcCBpdGVtcyBub3QgYWN0dWFsbHkgYWRkZWQgdG8gdXMgYmVjYXVzZSBvZiBjb25zdHJhaW5zLCBidXQgZG8gY2xlYW51cCAjMTQxOVxyXG4gICAgICAgIHRoaXMucGxhY2Vob2xkZXIucmVtb3ZlKCk7XHJcblxyXG4gICAgICAgIC8vIG5vdGlmeSBwcmV2aW91cyBncmlkIG9mIHJlbW92YWxcclxuICAgICAgICAvLyBjb25zb2xlLmxvZygnZHJvcCBkZWxldGUgX2dyaWRzdGFja05vZGVPcmlnJykgLy8gVEVTVFxyXG4gICAgICAgIGxldCBvcmlnTm9kZSA9IGVsLl9ncmlkc3RhY2tOb2RlT3JpZztcclxuICAgICAgICBkZWxldGUgZWwuX2dyaWRzdGFja05vZGVPcmlnO1xyXG4gICAgICAgIGlmICh3YXNBZGRlZCAmJiBvcmlnTm9kZT8uZ3JpZCAmJiBvcmlnTm9kZS5ncmlkICE9PSB0aGlzKSB7XHJcbiAgICAgICAgICBsZXQgb0dyaWQgPSBvcmlnTm9kZS5ncmlkO1xyXG4gICAgICAgICAgb0dyaWQuZW5naW5lLnJlbW92ZWROb2Rlcy5wdXNoKG9yaWdOb2RlKTtcclxuICAgICAgICAgIG9HcmlkLl90cmlnZ2VyUmVtb3ZlRXZlbnQoKS5fdHJpZ2dlckNoYW5nZUV2ZW50KCk7XHJcbiAgICAgICAgICAvLyBpZiBpdCdzIGFuIGVtcHR5IHN1Yi1ncmlkIHRoYXQgZ290IGF1dG8tY3JlYXRlZCwgbnVrZSBpdFxyXG4gICAgICAgICAgaWYgKG9HcmlkLnBhcmVudEdyaWRJdGVtICYmICFvR3JpZC5lbmdpbmUubm9kZXMubGVuZ3RoICYmIG9HcmlkLm9wdHMuc3ViR3JpZER5bmFtaWMpIHtcclxuICAgICAgICAgICAgb0dyaWQucmVtb3ZlQXNTdWJHcmlkKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIW5vZGUpIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gdXNlIGV4aXN0aW5nIHBsYWNlaG9sZGVyIG5vZGUgYXMgaXQncyBhbHJlYWR5IGluIG91ciBsaXN0IHdpdGggZHJvcCBsb2NhdGlvblxyXG4gICAgICAgIGlmICh3YXNBZGRlZCkge1xyXG4gICAgICAgICAgdGhpcy5lbmdpbmUuY2xlYW51cE5vZGUobm9kZSk7IC8vIHJlbW92ZXMgYWxsIGludGVybmFsIF94eXogdmFsdWVzXHJcbiAgICAgICAgICBub2RlLmdyaWQgPSB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBkZC5vZmYoZWwsICdkcmFnJyk7XHJcbiAgICAgICAgLy8gaWYgd2UgbWFkZSBhIGNvcHkgKCdoZWxwZXInIHdoaWNoIGlzIHRlbXApIG9mIHRoZSBvcmlnaW5hbCBub2RlIHRoZW4gaW5zZXJ0IGEgY29weSwgZWxzZSB3ZSBtb3ZlIHRoZSBvcmlnaW5hbCBub2RlICgjMTEwMilcclxuICAgICAgICAvLyBhcyB0aGUgaGVscGVyIHdpbGwgYmUgbnVrZWQgYnkganF1ZXJ5LXVpIG90aGVyd2lzZS4gVE9ETzogdXBkYXRlIG9sZCBjb2RlIHBhdGhcclxuICAgICAgICBpZiAoaGVscGVyICE9PSBlbCkge1xyXG4gICAgICAgICAgaGVscGVyLnJlbW92ZSgpO1xyXG4gICAgICAgICAgZWwuZ3JpZHN0YWNrTm9kZSA9IG9yaWdOb2RlOyAvLyBvcmlnaW5hbCBpdGVtIChsZWZ0IGJlaGluZCkgaXMgcmUtc3RvcmVkIHRvIHByZSBkcmFnZ2luZyBhcyB0aGUgbm9kZSBub3cgaGFzIGRyb3AgaW5mb1xyXG4gICAgICAgICAgaWYgKHdhc0FkZGVkKSB7XHJcbiAgICAgICAgICAgIGVsID0gZWwuY2xvbmVOb2RlKHRydWUpIGFzIEdyaWRJdGVtSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGVsLnJlbW92ZSgpOyAvLyByZWR1Y2UgZmxpY2tlciBhcyB3ZSBjaGFuZ2UgZGVwdGggaGVyZSwgYW5kIHNpemUgZnVydGhlciBkb3duXHJcbiAgICAgICAgICB0aGlzLl9yZW1vdmVERChlbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghd2FzQWRkZWQpIHJldHVybiBmYWxzZTtcclxuICAgICAgICBlbC5ncmlkc3RhY2tOb2RlID0gbm9kZTtcclxuICAgICAgICBub2RlLmVsID0gZWw7XHJcbiAgICAgICAgbGV0IHN1YkdyaWQgPSBub2RlLnN1YkdyaWQ/LmVsPy5ncmlkc3RhY2s7IC8vIHNldCB3aGVuIGFjdHVhbCBzdWItZ3JpZCBwcmVzZW50XHJcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgICAgIFV0aWxzLmNvcHlQb3Mobm9kZSwgdGhpcy5fcmVhZEF0dHIodGhpcy5wbGFjZWhvbGRlcikpOyAvLyBwbGFjZWhvbGRlciB2YWx1ZXMgYXMgbW92aW5nIFZFUlkgZmFzdCBjYW4gdGhyb3cgdGhpbmdzIG9mZiAjMTU3OFxyXG4gICAgICAgIFV0aWxzLnJlbW92ZVBvc2l0aW9uaW5nU3R5bGVzKGVsKTsvLyBAdHMtaWdub3JlXHJcbiAgICAgICAgdGhpcy5fd3JpdGVBdHRyKGVsLCBub2RlKTtcclxuICAgICAgICBlbC5jbGFzc0xpc3QuYWRkKGdyaWREZWZhdWx0cy5pdGVtQ2xhc3MsIHRoaXMub3B0cy5pdGVtQ2xhc3MpO1xyXG4gICAgICAgIHRoaXMuZWwuYXBwZW5kQ2hpbGQoZWwpOy8vIEB0cy1pZ25vcmUgLy8gVE9ETzogbm93IHdvdWxkIGJlIGlkZWFsIHRpbWUgdG8gX3JlbW92ZUhlbHBlclN0eWxlKCkgb3ZlcnJpZGluZyBmbG9hdGluZyBzdHlsZXMgKG5hdGl2ZSBvbmx5KVxyXG4gICAgICAgIGlmIChzdWJHcmlkKSB7XHJcbiAgICAgICAgICBzdWJHcmlkLnBhcmVudEdyaWRJdGVtID0gbm9kZTtcclxuICAgICAgICAgIGlmICghc3ViR3JpZC5vcHRzLnN0eWxlSW5IZWFkKSBzdWJHcmlkLl91cGRhdGVTdHlsZXModHJ1ZSk7IC8vIHJlLWNyZWF0ZSBzdWItZ3JpZCBzdHlsZXMgbm93IHRoYXQgd2UndmUgbW92ZWRcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fdXBkYXRlQ29udGFpbmVySGVpZ2h0KCk7XHJcbiAgICAgICAgdGhpcy5lbmdpbmUuYWRkZWROb2Rlcy5wdXNoKG5vZGUpOy8vIEB0cy1pZ25vcmVcclxuICAgICAgICB0aGlzLl90cmlnZ2VyQWRkRXZlbnQoKTsvLyBAdHMtaWdub3JlXHJcbiAgICAgICAgdGhpcy5fdHJpZ2dlckNoYW5nZUV2ZW50KCk7XHJcblxyXG4gICAgICAgIHRoaXMuZW5naW5lLmVuZFVwZGF0ZSgpO1xyXG4gICAgICAgIGlmICh0aGlzLl9nc0V2ZW50SGFuZGxlclsnZHJvcHBlZCddKSB7XHJcbiAgICAgICAgICB0aGlzLl9nc0V2ZW50SGFuZGxlclsnZHJvcHBlZCddKHsuLi5ldmVudCwgdHlwZTogJ2Ryb3BwZWQnfSwgb3JpZ05vZGUgJiYgb3JpZ05vZGUuZ3JpZCA/IG9yaWdOb2RlIDogdW5kZWZpbmVkLCBub2RlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHdhaXQgdGlsbCB3ZSByZXR1cm4gb3V0IG9mIHRoZSBkcmFnIGNhbGxiYWNrIHRvIHNldCB0aGUgbmV3IGRyYWcmcmVzaXplIGhhbmRsZXIgb3IgdGhleSBtYXkgZ2V0IG1lc3NlZCB1cFxyXG4gICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgIC8vIElGRiB3ZSBhcmUgc3RpbGwgdGhlcmUgKHNvbWUgYXBwbGljYXRpb24gd2lsbCB1c2UgYXMgcGxhY2Vob2xkZXIgYW5kIGluc2VydCB0aGVpciByZWFsIHdpZGdldCBpbnN0ZWFkIGFuZCBiZXR0ZXIgY2FsbCBtYWtlV2lkZ2V0KCkpXHJcbiAgICAgICAgICBpZiAobm9kZS5lbCAmJiBub2RlLmVsLnBhcmVudEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5fcHJlcGFyZURyYWdEcm9wQnlOb2RlKG5vZGUpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5lbmdpbmUucmVtb3ZlTm9kZShub2RlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGRlbGV0ZSBub2RlLmdyaWQuX2lzVGVtcDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBwcmV2ZW50IHBhcmVudCBmcm9tIHJlY2VpdmluZyBtc2cgKHdoaWNoIG1heSBiZSBncmlkIGFzIHdlbGwpXHJcbiAgICAgIH0pO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKiogQGludGVybmFsIG1hcmsgaXRlbSBmb3IgcmVtb3ZhbCAqL1xyXG4gIHByaXZhdGUgX2l0ZW1SZW1vdmluZyhlbDogR3JpZEl0ZW1IVE1MRWxlbWVudCwgcmVtb3ZlOiBib29sZWFuKSB7XHJcbiAgICBsZXQgbm9kZSA9IGVsID8gZWwuZ3JpZHN0YWNrTm9kZSA6IHVuZGVmaW5lZDtcclxuICAgIGlmICghbm9kZSB8fCAhbm9kZS5ncmlkKSByZXR1cm47XHJcbiAgICByZW1vdmUgPyBub2RlLl9pc0Fib3V0VG9SZW1vdmUgPSB0cnVlIDogZGVsZXRlIG5vZGUuX2lzQWJvdXRUb1JlbW92ZTtcclxuICAgIHJlbW92ZSA/IGVsLmNsYXNzTGlzdC5hZGQoJ2dyaWQtc3RhY2staXRlbS1yZW1vdmluZycpIDogZWwuY2xhc3NMaXN0LnJlbW92ZSgnZ3JpZC1zdGFjay1pdGVtLXJlbW92aW5nJyk7XHJcbiAgfVxyXG5cclxuICAvKiogQGludGVybmFsIGNhbGxlZCB0byBzZXR1cCBhIHRyYXNoIGRyb3Agem9uZSBpZiB0aGUgdXNlciBzcGVjaWZpZXMgaXQgKi9cclxuICBwcm90ZWN0ZWQgX3NldHVwUmVtb3ZlRHJvcCgpOiBHcmlkU3RhY2sge1xyXG4gICAgaWYgKCF0aGlzLm9wdHMuc3RhdGljR3JpZCAmJiB0eXBlb2YgdGhpcy5vcHRzLnJlbW92YWJsZSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgbGV0IHRyYXNoRWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMub3B0cy5yZW1vdmFibGUpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICBpZiAoIXRyYXNoRWwpIHJldHVybiB0aGlzO1xyXG4gICAgICAvLyBvbmx5IHJlZ2lzdGVyIE9ORSBkcm9wLW92ZXIvZHJvcG91dCBjYWxsYmFjayBmb3IgdGhlICd0cmFzaCcsIGFuZCBpdCB3aWxsXHJcbiAgICAgIC8vIHVwZGF0ZSB0aGUgcGFzc2VkIGluIGl0ZW0gYW5kIHBhcmVudCBncmlkIGJlY2F1c2UgdGhlICd0cmFzaCcgaXMgYSBzaGFyZWQgcmVzb3VyY2UgYW55d2F5LFxyXG4gICAgICAvLyBhbmQgTmF0aXZlIEREIG9ubHkgaGFzIDEgZXZlbnQgQ0IgKGhhdmluZyBhIGxpc3QgYW5kIHRlY2huaWNhbGx5IGEgcGVyIGdyaWQgcmVtb3ZhYmxlT3B0aW9ucyBjb21wbGljYXRlcyB0aGluZ3MgZ3JlYXRseSlcclxuICAgICAgaWYgKCFkZC5pc0Ryb3BwYWJsZSh0cmFzaEVsKSkge1xyXG4gICAgICAgIGRkLmRyb3BwYWJsZSh0cmFzaEVsLCB0aGlzLm9wdHMucmVtb3ZhYmxlT3B0aW9ucylcclxuICAgICAgICAgIC5vbih0cmFzaEVsLCAnZHJvcG92ZXInLCAoZXZlbnQsIGVsKSA9PiB0aGlzLl9pdGVtUmVtb3ZpbmcoZWwsIHRydWUpKVxyXG4gICAgICAgICAgLm9uKHRyYXNoRWwsICdkcm9wb3V0JywgIChldmVudCwgZWwpID0+IHRoaXMuX2l0ZW1SZW1vdmluZyhlbCwgZmFsc2UpKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKiogQGludGVybmFsIHByZXBhcmVzIHRoZSBlbGVtZW50IGZvciBkcmFnJmRyb3AgKiovXHJcbiAgcHJvdGVjdGVkIF9wcmVwYXJlRHJhZ0Ryb3BCeU5vZGUobm9kZTogR3JpZFN0YWNrTm9kZSk6IEdyaWRTdGFjayB7XHJcbiAgICBsZXQgZWwgPSBub2RlLmVsO1xyXG4gICAgY29uc3Qgbm9Nb3ZlID0gbm9kZS5ub01vdmUgfHwgdGhpcy5vcHRzLmRpc2FibGVEcmFnO1xyXG4gICAgY29uc3Qgbm9SZXNpemUgPSBub2RlLm5vUmVzaXplIHx8IHRoaXMub3B0cy5kaXNhYmxlUmVzaXplO1xyXG5cclxuICAgIC8vIGNoZWNrIGZvciBkaXNhYmxlZCBncmlkIGZpcnN0XHJcbiAgICBpZiAodGhpcy5vcHRzLnN0YXRpY0dyaWQgfHwgKG5vTW92ZSAmJiBub1Jlc2l6ZSkpIHtcclxuICAgICAgaWYgKG5vZGUuX2luaXRERCkge1xyXG4gICAgICAgIHRoaXMuX3JlbW92ZUREKGVsKTsgLy8gbnVrZXMgZXZlcnl0aGluZyBpbnN0ZWFkIG9mIGp1c3QgZGlzYWJsZSwgd2lsbCBhZGQgc29tZSBzdHlsZXMgYmFjayBuZXh0XHJcbiAgICAgICAgZGVsZXRlIG5vZGUuX2luaXRERDtcclxuICAgICAgfVxyXG4gICAgICBlbC5jbGFzc0xpc3QuYWRkKCd1aS1kcmFnZ2FibGUtZGlzYWJsZWQnLCAndWktcmVzaXphYmxlLWRpc2FibGVkJyk7IC8vIGFkZCBzdHlsZXMgb25lIG1pZ2h0IGRlcGVuZCBvbiAjMTQzNVxyXG4gICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIW5vZGUuX2luaXRERCkge1xyXG4gICAgICAvLyB2YXJpYWJsZXMgdXNlZC9jYXNoZWQgYmV0d2VlbiB0aGUgMyBzdGFydC9tb3ZlL2VuZCBtZXRob2RzLCBpbiBhZGRpdGlvbiB0byBub2RlIHBhc3NlZCBhYm92ZVxyXG4gICAgICBsZXQgY2VsbFdpZHRoOiBudW1iZXI7XHJcbiAgICAgIGxldCBjZWxsSGVpZ2h0OiBudW1iZXI7XHJcblxyXG4gICAgICAvKiogY2FsbGVkIHdoZW4gaXRlbSBzdGFydHMgbW92aW5nL3Jlc2l6aW5nICovXHJcbiAgICAgIGxldCBvblN0YXJ0TW92aW5nID0gKGV2ZW50OiBFdmVudCwgdWk6IEREVUlEYXRhKSA9PiB7XHJcbiAgICAgICAgLy8gdHJpZ2dlciBhbnkgJ2RyYWdzdGFydCcgLyAncmVzaXplc3RhcnQnIG1hbnVhbGx5XHJcbiAgICAgICAgaWYgKHRoaXMuX2dzRXZlbnRIYW5kbGVyW2V2ZW50LnR5cGVdKSB7XHJcbiAgICAgICAgICB0aGlzLl9nc0V2ZW50SGFuZGxlcltldmVudC50eXBlXShldmVudCwgZXZlbnQudGFyZ2V0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2VsbFdpZHRoID0gdGhpcy5jZWxsV2lkdGgoKTtcclxuICAgICAgICBjZWxsSGVpZ2h0ID0gdGhpcy5nZXRDZWxsSGVpZ2h0KHRydWUpOyAvLyBmb3JjZSBwaXhlbHMgZm9yIGNhbGN1bGF0aW9uc1xyXG5cclxuICAgICAgICB0aGlzLl9vblN0YXJ0TW92aW5nKGVsLCBldmVudCwgdWksIG5vZGUsIGNlbGxXaWR0aCwgY2VsbEhlaWdodCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8qKiBjYWxsZWQgd2hlbiBpdGVtIGlzIGJlaW5nIGRyYWdnZWQvcmVzaXplZCAqL1xyXG4gICAgICBsZXQgZHJhZ09yUmVzaXplID0gKGV2ZW50OiBNb3VzZUV2ZW50LCB1aTogRERVSURhdGEpID0+IHtcclxuICAgICAgICB0aGlzLl9kcmFnT3JSZXNpemUoZWwsIGV2ZW50LCB1aSwgbm9kZSwgY2VsbFdpZHRoLCBjZWxsSGVpZ2h0KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLyoqIGNhbGxlZCB3aGVuIHRoZSBpdGVtIHN0b3BzIG1vdmluZy9yZXNpemluZyAqL1xyXG4gICAgICBsZXQgb25FbmRNb3ZpbmcgPSAoZXZlbnQ6IEV2ZW50KSA9PiB7XHJcbiAgICAgICAgdGhpcy5wbGFjZWhvbGRlci5yZW1vdmUoKTtcclxuICAgICAgICBkZWxldGUgbm9kZS5fbW92aW5nO1xyXG4gICAgICAgIGRlbGV0ZSBub2RlLl9ldmVudDtcclxuICAgICAgICBkZWxldGUgbm9kZS5fbGFzdFRyaWVkO1xyXG5cclxuICAgICAgICAvLyBpZiB0aGUgaXRlbSBoYXMgbW92ZWQgdG8gYW5vdGhlciBncmlkLCB3ZSdyZSBkb25lIGhlcmVcclxuICAgICAgICBsZXQgdGFyZ2V0OiBHcmlkSXRlbUhUTUxFbGVtZW50ID0gZXZlbnQudGFyZ2V0IGFzIEdyaWRJdGVtSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgaWYgKCF0YXJnZXQuZ3JpZHN0YWNrTm9kZSB8fCB0YXJnZXQuZ3JpZHN0YWNrTm9kZS5ncmlkICE9PSB0aGlzKSByZXR1cm47XHJcblxyXG4gICAgICAgIG5vZGUuZWwgPSB0YXJnZXQ7XHJcblxyXG4gICAgICAgIGlmIChub2RlLl9pc0Fib3V0VG9SZW1vdmUpIHtcclxuICAgICAgICAgIGxldCBncmlkVG9Ob3RpZnkgPSBlbC5ncmlkc3RhY2tOb2RlLmdyaWQ7XHJcbiAgICAgICAgICBpZiAoZ3JpZFRvTm90aWZ5Ll9nc0V2ZW50SGFuZGxlcltldmVudC50eXBlXSkge1xyXG4gICAgICAgICAgICBncmlkVG9Ob3RpZnkuX2dzRXZlbnRIYW5kbGVyW2V2ZW50LnR5cGVdKGV2ZW50LCB0YXJnZXQpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgdGhpcy5fcmVtb3ZlREQoZWwpO1xyXG4gICAgICAgICAgZ3JpZFRvTm90aWZ5LmVuZ2luZS5yZW1vdmVkTm9kZXMucHVzaChub2RlKTtcclxuICAgICAgICAgIGdyaWRUb05vdGlmeS5fdHJpZ2dlclJlbW92ZUV2ZW50KCk7XHJcbiAgICAgICAgICAvLyBicmVhayBjaXJjdWxhciBsaW5rcyBhbmQgcmVtb3ZlIERPTVxyXG4gICAgICAgICAgZGVsZXRlIGVsLmdyaWRzdGFja05vZGU7XHJcbiAgICAgICAgICBkZWxldGUgbm9kZS5lbDtcclxuICAgICAgICAgIGVsLnJlbW92ZSgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBVdGlscy5yZW1vdmVQb3NpdGlvbmluZ1N0eWxlcyh0YXJnZXQpO1xyXG4gICAgICAgICAgaWYgKG5vZGUuX3RlbXBvcmFyeVJlbW92ZWQpIHtcclxuICAgICAgICAgICAgLy8gZ290IHJlbW92ZWQgLSByZXN0b3JlIGl0ZW0gYmFjayB0byBiZWZvcmUgZHJhZ2dpbmcgcG9zaXRpb25cclxuICAgICAgICAgICAgVXRpbHMuY29weVBvcyhub2RlLCBub2RlLl9vcmlnKTsvLyBAdHMtaWdub3JlXHJcbiAgICAgICAgICAgIHRoaXMuX3dyaXRlUG9zQXR0cih0YXJnZXQsIG5vZGUpO1xyXG4gICAgICAgICAgICB0aGlzLmVuZ2luZS5hZGROb2RlKG5vZGUpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gbW92ZSB0byBuZXcgcGxhY2Vob2xkZXIgbG9jYXRpb25cclxuICAgICAgICAgICAgdGhpcy5fd3JpdGVQb3NBdHRyKHRhcmdldCwgbm9kZSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAodGhpcy5fZ3NFdmVudEhhbmRsZXJbZXZlbnQudHlwZV0pIHtcclxuICAgICAgICAgICAgdGhpcy5fZ3NFdmVudEhhbmRsZXJbZXZlbnQudHlwZV0oZXZlbnQsIHRhcmdldCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcclxuICAgICAgICB0aGlzLl9leHRyYURyYWdSb3cgPSAwOy8vIEB0cy1pZ25vcmVcclxuICAgICAgICB0aGlzLl91cGRhdGVDb250YWluZXJIZWlnaHQoKTsvLyBAdHMtaWdub3JlXHJcbiAgICAgICAgdGhpcy5fdHJpZ2dlckNoYW5nZUV2ZW50KCk7XHJcblxyXG4gICAgICAgIHRoaXMuZW5naW5lLmVuZFVwZGF0ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBkZC5kcmFnZ2FibGUoZWwsIHtcclxuICAgICAgICBzdGFydDogb25TdGFydE1vdmluZyxcclxuICAgICAgICBzdG9wOiBvbkVuZE1vdmluZyxcclxuICAgICAgICBkcmFnOiBkcmFnT3JSZXNpemVcclxuICAgICAgfSkucmVzaXphYmxlKGVsLCB7XHJcbiAgICAgICAgc3RhcnQ6IG9uU3RhcnRNb3ZpbmcsXHJcbiAgICAgICAgc3RvcDogb25FbmRNb3ZpbmcsXHJcbiAgICAgICAgcmVzaXplOiBkcmFnT3JSZXNpemVcclxuICAgICAgfSk7XHJcbiAgICAgIG5vZGUuX2luaXRERCA9IHRydWU7IC8vIHdlJ3ZlIHNldCBERCBzdXBwb3J0IG5vd1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGZpbmFsbHkgZmluZSB0dW5lIG1vdmUgdnMgcmVzaXplIGJ5IGRpc2FibGluZyBhbnkgcGFydC4uLlxyXG4gICAgZGQuZHJhZ2dhYmxlKGVsLCBub01vdmUgPyAnZGlzYWJsZScgOiAnZW5hYmxlJylcclxuICAgICAgLnJlc2l6YWJsZShlbCwgbm9SZXNpemUgPyAnZGlzYWJsZScgOiAnZW5hYmxlJyk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKiogQGludGVybmFsIGhhbmRsZXMgYWN0dWFsIGRyYWcvcmVzaXplIHN0YXJ0ICoqL1xyXG4gIHByb3RlY3RlZCBfb25TdGFydE1vdmluZyhlbDogR3JpZEl0ZW1IVE1MRWxlbWVudCwgZXZlbnQ6IEV2ZW50LCB1aTogRERVSURhdGEsIG5vZGU6IEdyaWRTdGFja05vZGUsIGNlbGxXaWR0aDogbnVtYmVyLCBjZWxsSGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIHRoaXMuZW5naW5lLmNsZWFuTm9kZXMoKVxyXG4gICAgICAuYmVnaW5VcGRhdGUobm9kZSk7XHJcbiAgICAvLyBAdHMtaWdub3JlXHJcbiAgICB0aGlzLl93cml0ZVBvc0F0dHIodGhpcy5wbGFjZWhvbGRlciwgbm9kZSlcclxuICAgIHRoaXMuZWwuYXBwZW5kQ2hpbGQodGhpcy5wbGFjZWhvbGRlcik7XHJcbiAgICAvLyBjb25zb2xlLmxvZygnX29uU3RhcnRNb3ZpbmcgcGxhY2Vob2xkZXInKSAvLyBURVNUXHJcblxyXG4gICAgbm9kZS5lbCA9IHRoaXMucGxhY2Vob2xkZXI7XHJcbiAgICBub2RlLl9sYXN0VWlQb3NpdGlvbiA9IHVpLnBvc2l0aW9uO1xyXG4gICAgbm9kZS5fcHJldllQaXggPSB1aS5wb3NpdGlvbi50b3A7XHJcbiAgICBub2RlLl9tb3ZpbmcgPSAoZXZlbnQudHlwZSA9PT0gJ2RyYWdzdGFydCcpOyAvLyAnZHJvcG92ZXInIGFyZSBub3QgaW5pdGlhbGx5IG1vdmluZyBzbyB0aGV5IGNhbiBnbyBleGFjdGx5IHdoZXJlIHRoZXkgZW50ZXIgKHdpbGwgcHVzaCBzdHVmZiBvdXQgb2YgdGhlIHdheSlcclxuICAgIGRlbGV0ZSBub2RlLl9sYXN0VHJpZWQ7XHJcblxyXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09ICdkcm9wb3ZlcicgJiYgbm9kZS5fdGVtcG9yYXJ5UmVtb3ZlZCkge1xyXG4gICAgICAvLyBjb25zb2xlLmxvZygnZW5naW5lLmFkZE5vZGUgeD0nICsgbm9kZS54KTsgLy8gVEVTVFxyXG4gICAgICB0aGlzLmVuZ2luZS5hZGROb2RlKG5vZGUpOyAvLyB3aWxsIGFkZCwgZml4IGNvbGxpc2lvbnMsIHVwZGF0ZSBhdHRyIGFuZCBjbGVhciBfdGVtcG9yYXJ5UmVtb3ZlZFxyXG4gICAgICBub2RlLl9tb3ZpbmcgPSB0cnVlOyAvLyBBRlRFUiwgbWFyayBhcyBtb3Zpbmcgb2JqZWN0ICh3YW50ZWQgZml4IGxvY2F0aW9uIGJlZm9yZSlcclxuICAgIH1cclxuXHJcbiAgICAvLyBzZXQgdGhlIG1pbi9tYXggcmVzaXplIGluZm9cclxuICAgIHRoaXMuZW5naW5lLmNhY2hlUmVjdHMoY2VsbFdpZHRoLCBjZWxsSGVpZ2h0LCB0aGlzLm9wdHMubWFyZ2luVG9wIGFzIG51bWJlciwgdGhpcy5vcHRzLm1hcmdpblJpZ2h0IGFzIG51bWJlciwgdGhpcy5vcHRzLm1hcmdpbkJvdHRvbSBhcyBudW1iZXIsIHRoaXMub3B0cy5tYXJnaW5MZWZ0IGFzIG51bWJlcik7XHJcbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ3Jlc2l6ZXN0YXJ0Jykge1xyXG4gICAgICBkZC5yZXNpemFibGUoZWwsICdvcHRpb24nLCAnbWluV2lkdGgnLCBjZWxsV2lkdGggKiAobm9kZS5taW5XIHx8IDEpKVxyXG4gICAgICAgIC5yZXNpemFibGUoZWwsICdvcHRpb24nLCAnbWluSGVpZ2h0JywgY2VsbEhlaWdodCAqIChub2RlLm1pbkggfHwgMSkpO1xyXG4gICAgICBpZiAobm9kZS5tYXhXKSB7IGRkLnJlc2l6YWJsZShlbCwgJ29wdGlvbicsICdtYXhXaWR0aCcsIGNlbGxXaWR0aCAqIG5vZGUubWF4Vyk7IH1cclxuICAgICAgaWYgKG5vZGUubWF4SCkgeyBkZC5yZXNpemFibGUoZWwsICdvcHRpb24nLCAnbWF4SGVpZ2h0JywgY2VsbEhlaWdodCAqIG5vZGUubWF4SCk7IH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgaGFuZGxlcyBhY3R1YWwgZHJhZy9yZXNpemUgKiovXHJcbiAgcHJvdGVjdGVkIF9kcmFnT3JSZXNpemUoZWw6IEdyaWRJdGVtSFRNTEVsZW1lbnQsIGV2ZW50OiBNb3VzZUV2ZW50LCB1aTogRERVSURhdGEsIG5vZGU6IEdyaWRTdGFja05vZGUsIGNlbGxXaWR0aDogbnVtYmVyLCBjZWxsSGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGxldCBwID0gey4uLm5vZGUuX29yaWd9OyAvLyBjb3VsZCBiZSB1bmRlZmluZWQgKF9pc0V4dGVybmFsKSB3aGljaCBpcyBvayAoZHJhZyBvbmx5IHNldCB4LHkgYW5kIHcsaCB3aWxsIGRlZmF1bHQgdG8gbm9kZSB2YWx1ZSlcclxuICAgIGxldCByZXNpemluZzogYm9vbGVhbjtcclxuICAgIGxldCBtTGVmdCA9IHRoaXMub3B0cy5tYXJnaW5MZWZ0IGFzIG51bWJlcixcclxuICAgICAgbVJpZ2h0ID0gdGhpcy5vcHRzLm1hcmdpblJpZ2h0IGFzIG51bWJlcixcclxuICAgICAgbVRvcCA9IHRoaXMub3B0cy5tYXJnaW5Ub3AgYXMgbnVtYmVyLFxyXG4gICAgICBtQm90dG9tID0gdGhpcy5vcHRzLm1hcmdpbkJvdHRvbSBhcyBudW1iZXI7XHJcblxyXG4gICAgLy8gaWYgbWFyZ2lucyAod2hpY2ggYXJlIHVzZWQgdG8gcGFzcyBtaWQgcG9pbnQgYnkpIGFyZSBsYXJnZSByZWxhdGl2ZSB0byBjZWxsIGhlaWdodC93aWR0aCwgcmVkdWNlIHRoZW0gZG93biAjMTg1NVxyXG4gICAgbGV0IG1IZWlnaHQgPSBNYXRoLnJvdW5kKGNlbGxIZWlnaHQgKiAwLjEpLFxyXG4gICAgICBtV2lkdGggPSBNYXRoLnJvdW5kKGNlbGxXaWR0aCAqIDAuMSk7XHJcbiAgICBtTGVmdCA9IE1hdGgubWluKG1MZWZ0LCBtV2lkdGgpO1xyXG4gICAgbVJpZ2h0ID0gTWF0aC5taW4obVJpZ2h0LCBtV2lkdGgpO1xyXG4gICAgbVRvcCA9IE1hdGgubWluKG1Ub3AsIG1IZWlnaHQpO1xyXG4gICAgbUJvdHRvbSA9IE1hdGgubWluKG1Cb3R0b20sIG1IZWlnaHQpO1xyXG5cclxuICAgIGlmIChldmVudC50eXBlID09PSAnZHJhZycpIHtcclxuICAgICAgaWYgKG5vZGUuX3RlbXBvcmFyeVJlbW92ZWQpIHJldHVybjsgLy8gaGFuZGxlZCBieSBkcm9wb3ZlclxyXG4gICAgICBsZXQgZGlzdGFuY2UgPSB1aS5wb3NpdGlvbi50b3AgLSBub2RlLl9wcmV2WVBpeDtcclxuICAgICAgbm9kZS5fcHJldllQaXggPSB1aS5wb3NpdGlvbi50b3A7XHJcbiAgICAgIGlmICh0aGlzLm9wdHMuZHJhZ2dhYmxlLnNjcm9sbCAhPT0gZmFsc2UpIHtcclxuICAgICAgICBVdGlscy51cGRhdGVTY3JvbGxQb3NpdGlvbihlbCwgdWkucG9zaXRpb24sIGRpc3RhbmNlKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gZ2V0IG5ldyBwb3NpdGlvbiB0YWtpbmcgaW50byBhY2NvdW50IHRoZSBtYXJnaW4gaW4gdGhlIGRpcmVjdGlvbiB3ZSBhcmUgbW92aW5nISAobmVlZCB0byBwYXNzIG1pZCBwb2ludCBieSBtYXJnaW4pXHJcbiAgICAgIGxldCBsZWZ0ID0gdWkucG9zaXRpb24ubGVmdCArICh1aS5wb3NpdGlvbi5sZWZ0ID4gbm9kZS5fbGFzdFVpUG9zaXRpb24ubGVmdCAgPyAtbVJpZ2h0IDogbUxlZnQpO1xyXG4gICAgICBsZXQgdG9wID0gdWkucG9zaXRpb24udG9wICsgKHVpLnBvc2l0aW9uLnRvcCA+IG5vZGUuX2xhc3RVaVBvc2l0aW9uLnRvcCAgPyAtbUJvdHRvbSA6IG1Ub3ApO1xyXG4gICAgICBwLnggPSBNYXRoLnJvdW5kKGxlZnQgLyBjZWxsV2lkdGgpO1xyXG4gICAgICBwLnkgPSBNYXRoLnJvdW5kKHRvcCAvIGNlbGxIZWlnaHQpO1xyXG5cclxuICAgICAgLy8gQHRzLWlnbm9yZS8vIGlmIHdlJ3JlIGF0IHRoZSBib3R0b20gaGl0dGluZyBzb21ldGhpbmcgZWxzZSwgZ3JvdyB0aGUgZ3JpZCBzbyBjdXJzb3IgZG9lc24ndCBsZWF2ZSB3aGVuIHRyeWluZyB0byBwbGFjZSBiZWxvdyBvdGhlcnNcclxuICAgICAgbGV0IHByZXYgPSB0aGlzLl9leHRyYURyYWdSb3c7XHJcbiAgICAgIGlmICh0aGlzLmVuZ2luZS5jb2xsaWRlKG5vZGUsIHApKSB7XHJcbiAgICAgICAgbGV0IHJvdyA9IHRoaXMuZ2V0Um93KCk7XHJcbiAgICAgICAgbGV0IGV4dHJhID0gTWF0aC5tYXgoMCwgKHAueSArIG5vZGUuaCkgLSByb3cpO1xyXG4gICAgICAgIGlmICh0aGlzLm9wdHMubWF4Um93ICYmIHJvdyArIGV4dHJhID4gdGhpcy5vcHRzLm1heFJvdykge1xyXG4gICAgICAgICAgZXh0cmEgPSBNYXRoLm1heCgwLCB0aGlzLm9wdHMubWF4Um93IC0gcm93KTtcclxuICAgICAgICB9Ly8gQHRzLWlnbm9yZVxyXG4gICAgICAgIHRoaXMuX2V4dHJhRHJhZ1JvdyA9IGV4dHJhOy8vIEB0cy1pZ25vcmVcclxuICAgICAgfSBlbHNlIHRoaXMuX2V4dHJhRHJhZ1JvdyA9IDA7Ly8gQHRzLWlnbm9yZVxyXG4gICAgICBpZiAodGhpcy5fZXh0cmFEcmFnUm93ICE9PSBwcmV2KSB0aGlzLl91cGRhdGVDb250YWluZXJIZWlnaHQoKTtcclxuXHJcbiAgICAgIGlmIChub2RlLnggPT09IHAueCAmJiBub2RlLnkgPT09IHAueSkgcmV0dXJuOyAvLyBza2lwIHNhbWVcclxuICAgICAgLy8gRE9OJ1Qgc2tpcCBvbmUgd2UgdHJpZWQgYXMgd2UgbWlnaHQgaGF2ZSBmYWlsZWQgYmVjYXVzZSBvZiBjb3ZlcmFnZSA8NTAlIGJlZm9yZVxyXG4gICAgICAvLyBpZiAobm9kZS5fbGFzdFRyaWVkICYmIG5vZGUuX2xhc3RUcmllZC54ID09PSB4ICYmIG5vZGUuX2xhc3RUcmllZC55ID09PSB5KSByZXR1cm47XHJcbiAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09ICdyZXNpemUnKSAge1xyXG4gICAgICBpZiAocC54IDwgMCkgcmV0dXJuO1xyXG4gICAgICAvLyBTY3JvbGxpbmcgcGFnZSBpZiBuZWVkZWRcclxuICAgICAgVXRpbHMudXBkYXRlU2Nyb2xsUmVzaXplKGV2ZW50LCBlbCwgY2VsbEhlaWdodCk7XHJcblxyXG4gICAgICAvLyBnZXQgbmV3IHNpemVcclxuICAgICAgcC53ID0gTWF0aC5yb3VuZCgodWkuc2l6ZS53aWR0aCAtIG1MZWZ0KSAvIGNlbGxXaWR0aCk7XHJcbiAgICAgIHAuaCA9IE1hdGgucm91bmQoKHVpLnNpemUuaGVpZ2h0IC0gbVRvcCkgLyBjZWxsSGVpZ2h0KTtcclxuICAgICAgaWYgKG5vZGUudyA9PT0gcC53ICYmIG5vZGUuaCA9PT0gcC5oKSByZXR1cm47XHJcbiAgICAgIGlmIChub2RlLl9sYXN0VHJpZWQgJiYgbm9kZS5fbGFzdFRyaWVkLncgPT09IHAudyAmJiBub2RlLl9sYXN0VHJpZWQuaCA9PT0gcC5oKSByZXR1cm47IC8vIHNraXAgb25lIHdlIHRyaWVkIChidXQgZmFpbGVkKVxyXG5cclxuICAgICAgLy8gaWYgd2Ugc2l6ZSBvbiBsZWZ0L3RvcCBzaWRlIHRoaXMgbWlnaHQgbW92ZSB1cywgc28gZ2V0IHBvc3NpYmxlIG5ldyBwb3NpdGlvbiBhcyB3ZWxsXHJcbiAgICAgIGxldCBsZWZ0ID0gdWkucG9zaXRpb24ubGVmdCArIG1MZWZ0O1xyXG4gICAgICBsZXQgdG9wID0gdWkucG9zaXRpb24udG9wICsgbVRvcDtcclxuICAgICAgcC54ID0gTWF0aC5yb3VuZChsZWZ0IC8gY2VsbFdpZHRoKTtcclxuICAgICAgcC55ID0gTWF0aC5yb3VuZCh0b3AgLyBjZWxsSGVpZ2h0KTtcclxuXHJcbiAgICAgIHJlc2l6aW5nID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBub2RlLl9ldmVudCA9IGV2ZW50O1xyXG4gICAgbm9kZS5fbGFzdFRyaWVkID0gcDsgLy8gc2V0IGFzIGxhc3QgdHJpZWQgKHdpbGwgbnVrZSBpZiB3ZSBnbyB0aGVyZSlcclxuICAgIGxldCByZWN0OiBHcmlkU3RhY2tQb3NpdGlvbiA9IHsgLy8gc2NyZWVuIHBpeCBvZiB0aGUgZHJhZ2dlZCBib3hcclxuICAgICAgeDogdWkucG9zaXRpb24ubGVmdCArIG1MZWZ0LFxyXG4gICAgICB5OiB1aS5wb3NpdGlvbi50b3AgKyBtVG9wLFxyXG4gICAgICB3OiAodWkuc2l6ZSA/IHVpLnNpemUud2lkdGggOiBub2RlLncgKiBjZWxsV2lkdGgpIC0gbUxlZnQgLSBtUmlnaHQsXHJcbiAgICAgIGg6ICh1aS5zaXplID8gdWkuc2l6ZS5oZWlnaHQgOiBub2RlLmggKiBjZWxsSGVpZ2h0KSAtIG1Ub3AgLSBtQm90dG9tXHJcbiAgICB9O1xyXG4gICAgaWYgKHRoaXMuZW5naW5lLm1vdmVOb2RlQ2hlY2sobm9kZSwgey4uLnAsIGNlbGxXaWR0aCwgY2VsbEhlaWdodCwgcmVjdCwgcmVzaXppbmd9KSkge1xyXG4gICAgICBub2RlLl9sYXN0VWlQb3NpdGlvbiA9IHVpLnBvc2l0aW9uO1xyXG4gICAgICB0aGlzLmVuZ2luZS5jYWNoZVJlY3RzKGNlbGxXaWR0aCwgY2VsbEhlaWdodCwgbVRvcCwgbVJpZ2h0LCBtQm90dG9tLCBtTGVmdCk7XHJcbiAgICAgIGRlbGV0ZSBub2RlLl9za2lwRG93bjtcclxuICAgICAgaWYgKHJlc2l6aW5nICYmIG5vZGUuc3ViR3JpZCkgbm9kZS5zdWJHcmlkLm9uUGFyZW50UmVzaXplKCk7XHJcbiAgICAgIHRoaXMuX2V4dHJhRHJhZ1JvdyA9IDA7Ly8gQHRzLWlnbm9yZVxyXG4gICAgICB0aGlzLl91cGRhdGVDb250YWluZXJIZWlnaHQoKTtcclxuXHJcbiAgICAgIGxldCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgR3JpZEl0ZW1IVE1MRWxlbWVudDsvLyBAdHMtaWdub3JlXHJcbiAgICAgIHRoaXMuX3dyaXRlUG9zQXR0cih0YXJnZXQsIG5vZGUpO1xyXG4gICAgICBpZiAodGhpcy5fZ3NFdmVudEhhbmRsZXJbZXZlbnQudHlwZV0pIHtcclxuICAgICAgICB0aGlzLl9nc0V2ZW50SGFuZGxlcltldmVudC50eXBlXShldmVudCwgdGFyZ2V0KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCBjYWxsZWQgd2hlbiBpdGVtIGxlYXZpbmcgb3VyIGFyZWEgYnkgZWl0aGVyIGN1cnNvciBkcm9wb3V0IGV2ZW50XHJcbiAgICogb3Igc2hhcGUgaXMgb3V0c2lkZSBvdXIgYm91bmRhcmllcy4gcmVtb3ZlIGl0IGZyb20gdXMsIGFuZCBtYXJrIHRlbXBvcmFyeSBpZiB0aGlzIHdhc1xyXG4gICAqIG91ciBpdGVtIHRvIHN0YXJ0IHdpdGggZWxzZSByZXN0b3JlIHByZXYgbm9kZSB2YWx1ZXMgZnJvbSBwcmV2IGdyaWQgaXQgY2FtZSBmcm9tLlxyXG4gICAqKi9cclxuICBwcm90ZWN0ZWQgX2xlYXZlKGVsOiBHcmlkSXRlbUhUTUxFbGVtZW50LCBoZWxwZXI/OiBHcmlkSXRlbUhUTUxFbGVtZW50KTogdm9pZCB7XHJcbiAgICBsZXQgbm9kZSA9IGVsLmdyaWRzdGFja05vZGU7XHJcbiAgICBpZiAoIW5vZGUpIHJldHVybjtcclxuXHJcbiAgICBkZC5vZmYoZWwsICdkcmFnJyk7IC8vIG5vIG5lZWQgdG8gdHJhY2sgd2hpbGUgYmVpbmcgb3V0c2lkZVxyXG5cclxuICAgIC8vIHRoaXMgZ2V0cyBjYWxsZWQgd2hlbiBjdXJzb3IgbGVhdmVzIGFuZCBzaGFwZSBpcyBvdXRzaWRlLCBzbyBvbmx5IGRvIHRoaXMgb25jZVxyXG4gICAgaWYgKG5vZGUuX3RlbXBvcmFyeVJlbW92ZWQpIHJldHVybjtcclxuICAgIG5vZGUuX3RlbXBvcmFyeVJlbW92ZWQgPSB0cnVlO1xyXG5cclxuICAgIHRoaXMuZW5naW5lLnJlbW92ZU5vZGUobm9kZSk7IC8vIHJlbW92ZSBwbGFjZWhvbGRlciBhcyB3ZWxsLCBvdGhlcndpc2UgaXQncyBhIHNpZ24gbm9kZSBpcyBub3QgaW4gb3VyIGxpc3QsIHdoaWNoIGlzIGEgYmlnZ2VyIGlzc3VlXHJcbiAgICBub2RlLmVsID0gbm9kZS5faXNFeHRlcm5hbCAmJiBoZWxwZXIgPyBoZWxwZXIgOiBlbDsgLy8gcG9pbnQgYmFjayB0byByZWFsIGl0ZW0gYmVpbmcgZHJhZ2dlZFxyXG5cclxuICAgIGlmICh0aGlzLm9wdHMucmVtb3ZhYmxlID09PSB0cnVlKSB7IC8vIGJvb2xlYW4gdnMgYSBjbGFzcyBzdHJpbmdcclxuICAgICAgLy8gaXRlbSBsZWF2aW5nIHVzIGFuZCB3ZSBhcmUgc3VwcG9zZWQgdG8gcmVtb3ZlIG9uIGxlYXZlIChubyBuZWVkIHRvIGRyYWcgb250byB0cmFzaCkgbWFyayBpdCBzb1xyXG4gICAgICB0aGlzLl9pdGVtUmVtb3ZpbmcoZWwsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGZpbmFsbHkgaWYgaXRlbSBvcmlnaW5hbGx5IGNhbWUgZnJvbSBhbm90aGVyIGdyaWQsIGJ1dCBsZWZ0IHVzLCByZXN0b3JlIHRoaW5ncyBiYWNrIHRvIHByZXYgaW5mb1xyXG4gICAgaWYgKGVsLl9ncmlkc3RhY2tOb2RlT3JpZykge1xyXG4gICAgICAvLyBjb25zb2xlLmxvZygnbGVhdmUgZGVsZXRlIF9ncmlkc3RhY2tOb2RlT3JpZycpIC8vIFRFU1RcclxuICAgICAgZWwuZ3JpZHN0YWNrTm9kZSA9IGVsLl9ncmlkc3RhY2tOb2RlT3JpZztcclxuICAgICAgZGVsZXRlIGVsLl9ncmlkc3RhY2tOb2RlT3JpZztcclxuICAgIH0gZWxzZSBpZiAobm9kZS5faXNFeHRlcm5hbCkge1xyXG4gICAgICAvLyBpdGVtIGNhbWUgZnJvbSBvdXRzaWRlIChsaWtlIGEgdG9vbGJhcikgc28gbnVrZSBhbnkgbm9kZSBpbmZvXHJcbiAgICAgIGRlbGV0ZSBub2RlLmVsO1xyXG4gICAgICBkZWxldGUgZWwuZ3JpZHN0YWNrTm9kZTtcclxuICAgICAgLy8gYW5kIHJlc3RvcmUgYWxsIG5vZGVzIGJhY2sgdG8gb3JpZ2luYWxcclxuICAgICAgdGhpcy5lbmdpbmUucmVzdG9yZUluaXRpYWwoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIGxlZ2FjeSBtZXRob2QgcmVtb3ZlZFxyXG4gIHB1YmxpYyBjb21taXQoKTogR3JpZFN0YWNrIHsgb2Jzb2xldGUodGhpcywgdGhpcy5iYXRjaFVwZGF0ZShmYWxzZSksICdjb21taXQnLCAnYmF0Y2hVcGRhdGUnLCAnNS4yJyk7IHJldHVybiB0aGlzOyB9XHJcbn1cclxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///944\n")}},__webpack_require__={d:(Q,B)=>{for(var U in B)__webpack_require__.o(B,U)&&!__webpack_require__.o(Q,U)&&Object.defineProperty(Q,U,{enumerable:!0,get:B[U]})},o:(Q,B)=>Object.prototype.hasOwnProperty.call(Q,B)},__webpack_exports__={};return __webpack_modules__[944](0,__webpack_exports__,__webpack_require__),__webpack_exports__=__webpack_exports__.GridStack,__webpack_exports__})()));
|
|
1
|
+
/*! For license information please see gridstack-all.js.LICENSE.txt */
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.GridStack=t():e.GridStack=t()}(self,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var s in i)e.o(i,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:i[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{GridStack:()=>R});class i{static getElements(e,t=document){if("string"==typeof e){const i="getElementById"in t?t:void 0;if(i&&!isNaN(+e[0])){const t=i.getElementById(e);return t?[t]:[]}let s=t.querySelectorAll(e);return s.length||"."===e[0]||"#"===e[0]||(s=t.querySelectorAll("."+e),s.length||(s=t.querySelectorAll("#"+e))),Array.from(s)}return[e]}static getElement(e,t=document){if("string"==typeof e){const i="getElementById"in t?t:void 0;if(!e.length)return null;if(i&&"#"===e[0])return i.getElementById(e.substring(1));if("#"===e[0]||"."===e[0]||"["===e[0])return t.querySelector(e);if(i&&!isNaN(+e[0]))return i.getElementById(e);let s=t.querySelector(e);return i&&!s&&(s=i.getElementById(e)),s||(s=t.querySelector("."+e)),s}return e}static isIntercepted(e,t){return!(e.y>=t.y+t.h||e.y+e.h<=t.y||e.x+e.w<=t.x||e.x>=t.x+t.w)}static isTouching(e,t){return i.isIntercepted(e,{x:t.x-.5,y:t.y-.5,w:t.w+1,h:t.h+1})}static areaIntercept(e,t){let i=e.x>t.x?e.x:t.x,s=e.x+e.w<t.x+t.w?e.x+e.w:t.x+t.w;if(s<=i)return 0;let o=e.y>t.y?e.y:t.y,n=e.y+e.h<t.y+t.h?e.y+e.h:t.y+t.h;return n<=o?0:(s-i)*(n-o)}static area(e){return e.w*e.h}static sort(e,t=1,i){return i=i||e.reduce(((e,t)=>Math.max(t.x+t.w,e)),0)||12,-1===t?e.sort(((e,t)=>t.x+t.y*i-(e.x+e.y*i))):e.sort(((e,t)=>e.x+e.y*i-(t.x+t.y*i)))}static createStylesheet(e,t,i){let s=document.createElement("style");const o=i?.nonce;return o&&(s.nonce=o),s.setAttribute("type","text/css"),s.setAttribute("gs-style-id",e),s.styleSheet?s.styleSheet.cssText="":s.appendChild(document.createTextNode("")),t?t.insertBefore(s,t.firstChild):(t=document.getElementsByTagName("head")[0]).appendChild(s),s.sheet}static removeStylesheet(e){let t=document.querySelector("STYLE[gs-style-id="+e+"]");t&&t.parentNode&&t.remove()}static addCSSRule(e,t,i){"function"==typeof e.addRule?e.addRule(t,i):"function"==typeof e.insertRule&&e.insertRule(`${t}{${i}}`)}static toBool(e){return"boolean"==typeof e?e:"string"==typeof e?!(""===(e=e.toLowerCase())||"no"===e||"false"===e||"0"===e):Boolean(e)}static toNumber(e){return null===e||0===e.length?void 0:Number(e)}static parseHeight(e){let t,i="px";if("string"==typeof e){let s=e.match(/^(-[0-9]+\.[0-9]+|[0-9]*\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/);if(!s)throw new Error("Invalid height");i=s[2]||"px",t=parseFloat(s[1])}else t=e;return{h:t,unit:i}}static defaults(e,...t){return t.forEach((t=>{for(const i in t){if(!t.hasOwnProperty(i))return;null===e[i]||void 0===e[i]?e[i]=t[i]:"object"==typeof t[i]&&"object"==typeof e[i]&&this.defaults(e[i],t[i])}})),e}static same(e,t){if("object"!=typeof e)return e==t;if(typeof e!=typeof t)return!1;if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const i in e)if(e[i]!==t[i])return!1;return!0}static copyPos(e,t,i=!1){return void 0!==t.x&&(e.x=t.x),void 0!==t.y&&(e.y=t.y),void 0!==t.w&&(e.w=t.w),void 0!==t.h&&(e.h=t.h),i&&(t.minW&&(e.minW=t.minW),t.minH&&(e.minH=t.minH),t.maxW&&(e.maxW=t.maxW),t.maxH&&(e.maxH=t.maxH)),e}static samePos(e,t){return e&&t&&e.x===t.x&&e.y===t.y&&e.w===t.w&&e.h===t.h}static sanitizeMinMax(e){e.minW||delete e.minW,e.minH||delete e.minH,e.maxW||delete e.maxW,e.maxH||delete e.maxH}static removeInternalAndSame(e,t){if("object"==typeof e&&"object"==typeof t)for(let i in e){let s=e[i];if("_"===i[0]||s===t[i])delete e[i];else if(s&&"object"==typeof s&&void 0!==t[i]){for(let e in s)s[e]!==t[i][e]&&"_"!==e[0]||delete s[e];Object.keys(s).length||delete e[i]}}}static removeInternalForSave(e,t=!0){for(let t in e)"_"!==t[0]&&null!==e[t]&&void 0!==e[t]||delete e[t];delete e.grid,t&&delete e.el,e.autoPosition||delete e.autoPosition,e.noResize||delete e.noResize,e.noMove||delete e.noMove,e.locked||delete e.locked,1!==e.w&&e.w!==e.minW||delete e.w,1!==e.h&&e.h!==e.minH||delete e.h}static closestUpByClass(e,t){for(;e;){if(e.classList.contains(t))return e;e=e.parentElement}return null}static throttle(e,t){let i=!1;return(...s)=>{i||(i=!0,setTimeout((()=>{e(...s),i=!1}),t))}}static removePositioningStyles(e){let t=e.style;t.position&&t.removeProperty("position"),t.left&&t.removeProperty("left"),t.top&&t.removeProperty("top"),t.width&&t.removeProperty("width"),t.height&&t.removeProperty("height")}static getScrollElement(e){if(!e)return document.scrollingElement||document.documentElement;const t=getComputedStyle(e);return/(auto|scroll)/.test(t.overflow+t.overflowY)?e:this.getScrollElement(e.parentElement)}static updateScrollPosition(e,t,i){let s=e.getBoundingClientRect(),o=window.innerHeight||document.documentElement.clientHeight;if(s.top<0||s.bottom>o){let n=s.bottom-o,r=s.top,l=this.getScrollElement(e);if(null!==l){let h=l.scrollTop;s.top<0&&i<0?e.offsetHeight>o?l.scrollTop+=i:l.scrollTop+=Math.abs(r)>Math.abs(i)?i:r:i>0&&(e.offsetHeight>o?l.scrollTop+=i:l.scrollTop+=n>i?i:n),t.top+=l.scrollTop-h}}}static updateScrollResize(e,t,i){const s=this.getScrollElement(t),o=s.clientHeight,n=s===this.getScrollElement()?0:s.getBoundingClientRect().top,r=e.clientY-n,l=r>o-i;r<i?s.scrollBy({behavior:"smooth",top:r-i}):l&&s.scrollBy({behavior:"smooth",top:i-(o-r)})}static clone(e){return null==e||"object"!=typeof e?e:e instanceof Array?[...e]:{...e}}static cloneDeep(e){const t=["parentGrid","el","grid","subGrid","engine"],s=i.clone(e);for(const o in s)s.hasOwnProperty(o)&&"object"==typeof s[o]&&"__"!==o.substring(0,2)&&!t.find((e=>e===o))&&(s[o]=i.cloneDeep(e[o]));return s}static cloneNode(e){const t=e.cloneNode(!0);return t.removeAttribute("id"),t}static appendTo(e,t){let s;s="string"==typeof t?i.getElement(t):t,s&&s.appendChild(e)}static addElStyles(e,t){if(t instanceof Object)for(const i in t)t.hasOwnProperty(i)&&(Array.isArray(t[i])?t[i].forEach((t=>{e.style[i]=t})):e.style[i]=t[i])}static initEvent(e,t){const i={type:t.type},s={button:0,which:0,buttons:1,bubbles:!0,cancelable:!0,target:t.target?t.target:e.target};return e.dataTransfer&&(i.dataTransfer=e.dataTransfer),["altKey","ctrlKey","metaKey","shiftKey"].forEach((t=>i[t]=e[t])),["pageX","pageY","clientX","clientY","screenX","screenY"].forEach((t=>i[t]=e[t])),{...i,...s}}static simulateMouseEvent(e,t,i){const s=document.createEvent("MouseEvents");s.initMouseEvent(t,!0,!0,window,1,e.screenX,e.screenY,e.clientX,e.clientY,e.ctrlKey,e.altKey,e.shiftKey,e.metaKey,0,e.target),(i||e.target).dispatchEvent(s)}}class s{constructor(e={}){this.addedNodes=[],this.removedNodes=[],this.column=e.column||12,this.maxRow=e.maxRow,this._float=e.float,this.nodes=e.nodes||[],this.onChange=e.onChange}batchUpdate(e=!0,t=!0){return!!this.batchMode===e||(this.batchMode=e,e?(this._prevFloat=this._float,this._float=!0,this.saveInitial()):(this._float=this._prevFloat,delete this._prevFloat,t&&this._packNodes(),this._notify())),this}_useEntireRowArea(e,t){return(!this.float||this.batchMode&&!this._prevFloat)&&!this._hasLocked&&(!e._moving||e._skipDown||t.y<=e.y)}_fixCollisions(e,t=e,s,o={}){if(this.sortNodes(-1),!(s=s||this.collide(e,t)))return!1;if(e._moving&&!o.nested&&!this.float&&this.swap(e,s))return!0;let n=t;this._useEntireRowArea(e,t)&&(n={x:0,w:this.column,y:t.y,h:t.h},s=this.collide(e,n,o.skip));let r=!1,l={nested:!0,pack:!1};for(;s=s||this.collide(e,n,o.skip);){let n;if(s.locked||e._moving&&!e._skipDown&&t.y>e.y&&!this.float&&(!this.collide(s,{...s,y:e.y},e)||!this.collide(s,{...s,y:t.y-s.h},e))?(e._skipDown=e._skipDown||t.y>e.y,n=this.moveNode(e,{...t,y:s.y+s.h,...l}),s.locked&&n?i.copyPos(t,e):!s.locked&&n&&o.pack&&(this._packNodes(),t.y=s.y+s.h,i.copyPos(e,t)),r=r||n):n=this.moveNode(s,{...s,y:t.y+t.h,skip:e,...l}),!n)return r;s=void 0}return r}collide(e,t=e,s){const o=e._id,n=s?._id;return this.nodes.find((e=>e._id!==o&&e._id!==n&&i.isIntercepted(e,t)))}collideAll(e,t=e,s){const o=e._id,n=s?._id;return this.nodes.filter((e=>e._id!==o&&e._id!==n&&i.isIntercepted(e,t)))}directionCollideCoverage(e,t,i){if(!t.rect||!e._rect)return;let s,o=e._rect,n={...t.rect};return n.y>o.y?(n.h+=n.y-o.y,n.y=o.y):n.h+=o.y-n.y,n.x>o.x?(n.w+=n.x-o.x,n.x=o.x):n.w+=o.x-n.x,i.forEach((e=>{if(e.locked||!e._rect)return;let t=e._rect,i=Number.MAX_VALUE,r=Number.MAX_VALUE,l=.5;o.y<t.y?i=(n.y+n.h-t.y)/t.h:o.y+o.h>t.y+t.h&&(i=(t.y+t.h-n.y)/t.h),o.x<t.x?r=(n.x+n.w-t.x)/t.w:o.x+o.w>t.x+t.w&&(r=(t.x+t.w-n.x)/t.w);let h=Math.min(r,i);h>l&&(l=h,s=e)})),t.collide=s,s}cacheRects(e,t,i,s,o,n){return this.nodes.forEach((r=>r._rect={y:r.y*t+i,x:r.x*e+n,w:r.w*e-n-s,h:r.h*t-i-o})),this}swap(e,t){if(!t||t.locked||!e||e.locked)return!1;function s(){let i=t.x,s=t.y;return t.x=e.x,t.y=e.y,e.h!=t.h?(e.x=i,e.y=t.y+t.h):e.w!=t.w?(e.x=t.x+t.w,e.y=s):(e.x=i,e.y=s),e._dirty=t._dirty=!0,!0}let o;if(e.w===t.w&&e.h===t.h&&(e.x===t.x||e.y===t.y)&&(o=i.isTouching(e,t)))return s();if(!1!==o){if(e.w===t.w&&e.x===t.x&&(o||(o=i.isTouching(e,t)))){if(t.y<e.y){let i=e;e=t,t=i}return s()}if(!1!==o){if(e.h===t.h&&e.y===t.y&&(o||(o=i.isTouching(e,t)))){if(t.x<e.x){let i=e;e=t,t=i}return s()}return!1}}}isAreaEmpty(e,t,i,s){let o={x:e||0,y:t||0,w:i||1,h:s||1};return!this.collide(o)}compact(e="compact",t=!0){if(0===this.nodes.length)return this;t&&this.sortNodes();const i=this.batchMode;i||this.batchUpdate();const s=this._inColumnResize;s||(this._inColumnResize=!0);let o=this.nodes;return this.nodes=[],o.forEach(((t,i,s)=>{let o;t.locked||(t.autoPosition=!0,"list"===e&&i&&(o=s[i-1])),this.addNode(t,!1,o)})),s||delete this._inColumnResize,i||this.batchUpdate(!1),this}set float(e){this._float!==e&&(this._float=e||!1,e||this._packNodes()._notify())}get float(){return this._float||!1}sortNodes(e=1,t=this.column){return this.nodes=i.sort(this.nodes,e,t),this}_packNodes(){return this.batchMode||(this.sortNodes(),this.float?this.nodes.forEach((e=>{if(e._updating||void 0===e._orig||e.y===e._orig.y)return;let t=e.y;for(;t>e._orig.y;)--t,this.collide(e,{x:e.x,y:t,w:e.w,h:e.h})||(e._dirty=!0,e.y=t)})):this.nodes.forEach(((e,t)=>{if(!e.locked)for(;e.y>0;){let i=0===t?0:e.y-1;if(0!==t&&this.collide(e,{x:e.x,y:i,w:e.w,h:e.h}))break;e._dirty=e.y!==i,e.y=i}}))),this}prepareNode(e,t){(e=e||{})._id=e._id??s._idSeq++,void 0!==e.x&&void 0!==e.y&&null!==e.x&&null!==e.y||(e.autoPosition=!0);let o={x:0,y:0,w:1,h:1};return i.defaults(e,o),e.autoPosition||delete e.autoPosition,e.noResize||delete e.noResize,e.noMove||delete e.noMove,i.sanitizeMinMax(e),"string"==typeof e.x&&(e.x=Number(e.x)),"string"==typeof e.y&&(e.y=Number(e.y)),"string"==typeof e.w&&(e.w=Number(e.w)),"string"==typeof e.h&&(e.h=Number(e.h)),isNaN(e.x)&&(e.x=o.x,e.autoPosition=!0),isNaN(e.y)&&(e.y=o.y,e.autoPosition=!0),isNaN(e.w)&&(e.w=o.w),isNaN(e.h)&&(e.h=o.h),this.nodeBoundFix(e,t)}nodeBoundFix(e,t){let s=e._orig||i.copyPos({},e);if(e.maxW&&(e.w=Math.min(e.w,e.maxW)),e.maxH&&(e.h=Math.min(e.h,e.maxH)),e.minW&&e.minW<=this.column&&(e.w=Math.max(e.w,e.minW)),e.minH&&(e.h=Math.max(e.h,e.minH)),(1===this.column||e.x+e.w>this.column)&&this.column<12&&!this._inColumnResize&&e._id&&-1===this.findCacheLayout(e,12)){let t={...e};t.autoPosition?(delete t.x,delete t.y):t.x=Math.min(11,t.x),t.w=Math.min(12,t.w),this.cacheOneLayout(t,12)}return e.w>this.column?e.w=this.column:e.w<1&&(e.w=1),this.maxRow&&e.h>this.maxRow?e.h=this.maxRow:e.h<1&&(e.h=1),e.x<0&&(e.x=0),e.y<0&&(e.y=0),e.x+e.w>this.column&&(t?e.w=this.column-e.x:e.x=this.column-e.w),this.maxRow&&e.y+e.h>this.maxRow&&(t?e.h=this.maxRow-e.y:e.y=this.maxRow-e.h),i.samePos(e,s)||(e._dirty=!0),e}getDirtyNodes(e){return e?this.nodes.filter((e=>e._dirty&&!i.samePos(e,e._orig))):this.nodes.filter((e=>e._dirty))}_notify(e){if(this.batchMode||!this.onChange)return this;let t=(e||[]).concat(this.getDirtyNodes());return this.onChange(t),this}cleanNodes(){return this.batchMode||this.nodes.forEach((e=>{delete e._dirty,delete e._lastTried})),this}saveInitial(){return this.nodes.forEach((e=>{e._orig=i.copyPos({},e),delete e._dirty})),this._hasLocked=this.nodes.some((e=>e.locked)),this}restoreInitial(){return this.nodes.forEach((e=>{i.samePos(e,e._orig)||(i.copyPos(e,e._orig),e._dirty=!0)})),this._notify(),this}findEmptyPosition(e,t=this.nodes,s=this.column,o){let n=!1;for(let r=o?o.y*s+(o.x+o.w):0;!n;++r){let o=r%s,l=Math.floor(r/s);if(o+e.w>s)continue;let h={x:o,y:l,w:e.w,h:e.h};t.find((e=>i.isIntercepted(h,e)))||(e.x===o&&e.y===l||(e._dirty=!0),e.x=o,e.y=l,delete e.autoPosition,n=!0)}return n}addNode(e,t=!1,i){let s;return this.nodes.find((t=>t._id===e._id))||(delete(e=this._inColumnResize?this.nodeBoundFix(e):this.prepareNode(e))._temporaryRemoved,delete e._removeDOM,e.autoPosition&&this.findEmptyPosition(e,this.nodes,this.column,i)&&(delete e.autoPosition,s=!0),this.nodes.push(e),t&&this.addedNodes.push(e),s||this._fixCollisions(e),this.batchMode||this._packNodes()._notify(),e)}removeNode(e,t=!0,i=!1){return this.nodes.find((t=>t._id===e._id))?(i&&this.removedNodes.push(e),t&&(e._removeDOM=!0),this.nodes=this.nodes.filter((t=>t._id!==e._id)),this._packNodes()._notify([e])):this}removeAll(e=!0){return delete this._layouts,this.nodes.length?(e&&this.nodes.forEach((e=>e._removeDOM=!0)),this.removedNodes=this.nodes,this.nodes=[],this._notify(this.removedNodes)):this}moveNodeCheck(e,t){if(!this.changedPosConstrain(e,t))return!1;if(t.pack=!0,!this.maxRow)return this.moveNode(e,t);let o,n=new s({column:this.column,float:this.float,nodes:this.nodes.map((t=>t._id===e._id?(o={...t},o):{...t}))});if(!o)return!1;let r=n.moveNode(o,t)&&n.getRow()<=this.maxRow;if(!r&&!t.resizing&&t.collide){let i=t.collide.el.gridstackNode;if(this.swap(e,i))return this._notify(),!0}return!!r&&(n.nodes.filter((e=>e._dirty)).forEach((e=>{let t=this.nodes.find((t=>t._id===e._id));t&&(i.copyPos(t,e),t._dirty=!0)})),this._notify(),!0)}willItFit(e){if(delete e._willFitPos,!this.maxRow)return!0;let t=new s({column:this.column,float:this.float,nodes:this.nodes.map((e=>({...e})))}),o={...e};return this.cleanupNode(o),delete o.el,delete o._id,delete o.content,delete o.grid,t.addNode(o),t.getRow()<=this.maxRow&&(e._willFitPos=i.copyPos({},o),!0)}changedPosConstrain(e,t){return t.w=t.w||e.w,t.h=t.h||e.h,e.x!==t.x||e.y!==t.y||(e.maxW&&(t.w=Math.min(t.w,e.maxW)),e.maxH&&(t.h=Math.min(t.h,e.maxH)),e.minW&&(t.w=Math.max(t.w,e.minW)),e.minH&&(t.h=Math.max(t.h,e.minH)),e.w!==t.w||e.h!==t.h)}moveNode(e,t){if(!e||!t)return!1;let s;void 0===t.pack&&(s=t.pack=!0),"number"!=typeof t.x&&(t.x=e.x),"number"!=typeof t.y&&(t.y=e.y),"number"!=typeof t.w&&(t.w=e.w),"number"!=typeof t.h&&(t.h=e.h);let o=e.w!==t.w||e.h!==t.h,n=i.copyPos({},e,!0);if(i.copyPos(n,t),n=this.nodeBoundFix(n,o),i.copyPos(t,n),i.samePos(e,t))return!1;let r=i.copyPos({},e),l=this.collideAll(e,n,t.skip),h=!0;if(l.length){let o=e._moving&&!t.nested,r=o?this.directionCollideCoverage(e,t,l):l[0];if(o&&r&&e.grid?.opts?.subGridDynamic&&!e.grid._isTemp){let s=i.areaIntercept(t.rect,r._rect),o=i.area(t.rect),n=i.area(r._rect);s/(o<n?o:n)>.8&&(r.grid.makeSubGrid(r.el,void 0,e),r=void 0)}r?h=!this._fixCollisions(e,n,r,t):(h=!1,s&&delete t.pack)}return h&&(e._dirty=!0,i.copyPos(e,n)),t.pack&&this._packNodes()._notify(),!i.samePos(e,r)}getRow(){return this.nodes.reduce(((e,t)=>Math.max(e,t.y+t.h)),0)}beginUpdate(e){return e._updating||(e._updating=!0,delete e._skipDown,this.batchMode||this.saveInitial()),this}endUpdate(){let e=this.nodes.find((e=>e._updating));return e&&(delete e._updating,delete e._skipDown),this}save(e=!0,t){let s=this._layouts?.length,o=s&&this.column!==s-1?this._layouts[s-1]:null,n=[];return this.sortNodes(),this.nodes.forEach((s=>{let r=o?.find((e=>e._id===s._id)),l={...s};r&&(l.x=r.x,l.y=r.y,l.w=r.w),i.removeInternalForSave(l,!e),t&&t(s,l),n.push(l)})),n}layoutsNodesChange(e){return!this._layouts||this._inColumnResize||this._layouts.forEach(((t,i)=>{if(!t||i===this.column)return this;if(i<this.column)this._layouts[i]=void 0;else{let s=i/this.column;e.forEach((e=>{if(!e._orig)return;let i=t.find((t=>t._id===e._id));i&&(e.y!==e._orig.y&&(i.y+=e.y-e._orig.y),e.x!==e._orig.x&&(i.x=Math.round(e.x*s)),e.w!==e._orig.w&&(i.w=Math.round(e.w*s)))}))}})),this}columnChanged(e,t,s,o="moveScale"){if(!this.nodes.length||!t||e===t)return this;const n="compact"===o||"list"===o;n&&this.sortNodes(1,e),t<e&&this.cacheLayout(this.nodes,e),this.batchUpdate();let r=[],l=!1;if(1===t&&s?.length){l=!0;let e=0;s.forEach((t=>{t.x=0,t.w=1,t.y=Math.max(t.y,e),e=t.y+t.h})),r=s,s=[]}else s=n?this.nodes:i.sort(this.nodes,-1,e);if(t>e&&this._layouts){const i=this._layouts[t]||[];let o=this._layouts.length-1;!i.length&&e!==o&&this._layouts[o]?.length&&(e=o,this._layouts[o].forEach((e=>{let t=s.find((t=>t._id===e._id));t&&(n||(t.x=e.x,t.y=e.y),t.w=e.w)}))),i.forEach((e=>{let t=s.findIndex((t=>t._id===e._id));if(-1!==t){if(n)return void(s[t].w=e.w);(e.autoPosition||isNaN(e.x)||isNaN(e.y))&&this.findEmptyPosition(e,r),e.autoPosition||(s[t].x=e.x,s[t].y=e.y,s[t].w=e.w,r.push(s[t])),s.splice(t,1)}}))}if(n)this.compact(o,!1);else{if(s.length)if("function"==typeof o)o(t,e,r,s);else if(!l){let i=n||"none"===o?1:t/e,l="move"===o||"moveScale"===o,h="scale"===o||"moveScale"===o;s.forEach((s=>{s.x=1===t?0:l?Math.round(s.x*i):Math.min(s.x,t-1),s.w=1===t||1===e?1:h?Math.round(s.w*i)||1:Math.min(s.w,t),r.push(s)})),s=[]}l||(r=i.sort(r,-1,t)),this._inColumnResize=!0,this.nodes=[],r.forEach((e=>{this.addNode(e,!1),delete e._orig}))}return this.nodes.forEach((e=>delete e._orig)),this.batchUpdate(!1,!n),delete this._inColumnResize,this}cacheLayout(e,t,i=!1){let o=[];return e.forEach(((e,t)=>{e._id=e._id??s._idSeq++,o[t]={x:e.x,y:e.y,w:e.w,_id:e._id}})),this._layouts=i?[]:this._layouts||[],this._layouts[t]=o,this}cacheOneLayout(e,t){e._id=e._id??s._idSeq++;let i={x:e.x,y:e.y,w:e.w,_id:e._id};e.autoPosition&&(delete i.x,delete i.y,i.autoPosition=!0),this._layouts=this._layouts||[],this._layouts[t]=this._layouts[t]||[];let o=this.findCacheLayout(e,t);return-1===o?this._layouts[t].push(i):this._layouts[t][o]=i,this}findCacheLayout(e,t){return this._layouts?.[t]?.findIndex((t=>t._id===e._id))??-1}cleanupNode(e){for(let t in e)"_"===t[0]&&"_id"!==t&&delete e[t];return this}}s._idSeq=0;const o={alwaysShowResizeHandle:"mobile",animate:!0,auto:!0,cellHeight:"auto",cellHeightThrottle:100,cellHeightUnit:"px",column:12,draggable:{handle:".grid-stack-item-content",appendTo:"body",scroll:!0},handle:".grid-stack-item-content",itemClass:"grid-stack-item",margin:10,marginUnit:"px",maxRow:0,minRow:0,oneColumnSize:768,placeholderClass:"grid-stack-placeholder",placeholderText:"",removableOptions:{accept:".grid-stack-item"},resizable:{handles:"se"},rtl:"auto"},n={handle:".grid-stack-item-content",appendTo:"body"};class r{}const l="undefined"!=typeof window&&"undefined"!=typeof document&&("ontouchstart"in document||"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0);class h{}function a(e,t){if(e.touches.length>1)return;e.cancelable&&e.preventDefault();const i=e.changedTouches[0],s=document.createEvent("MouseEvents");s.initMouseEvent(t,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),e.target.dispatchEvent(s)}function d(e,t){e.cancelable&&e.preventDefault();const i=document.createEvent("MouseEvents");i.initMouseEvent(t,!0,!0,window,1,e.screenX,e.screenY,e.clientX,e.clientY,!1,!1,!1,!1,0,null),e.target.dispatchEvent(i)}function p(e){h.touchHandled||(h.touchHandled=!0,a(e,"mousedown"))}function g(e){h.touchHandled&&a(e,"mousemove")}function u(e){if(!h.touchHandled)return;h.pointerLeaveTimeout&&(window.clearTimeout(h.pointerLeaveTimeout),delete h.pointerLeaveTimeout);const t=!!r.dragElement;a(e,"mouseup"),t||a(e,"click"),h.touchHandled=!1}function c(e){e.target.releasePointerCapture(e.pointerId)}function m(e){r.dragElement&&d(e,"mouseenter")}function _(e){r.dragElement&&(h.pointerLeaveTimeout=window.setTimeout((()=>{delete h.pointerLeaveTimeout,d(e,"mouseleave")}),10))}class v{constructor(e,t,i){this.moving=!1,this.host=e,this.dir=t,this.option=i,this._mouseDown=this._mouseDown.bind(this),this._mouseMove=this._mouseMove.bind(this),this._mouseUp=this._mouseUp.bind(this),this._init()}_init(){const e=document.createElement("div");return e.classList.add("ui-resizable-handle"),e.classList.add(`${v.prefix}${this.dir}`),e.style.zIndex="100",e.style.userSelect="none",this.el=e,this.host.appendChild(this.el),this.el.addEventListener("mousedown",this._mouseDown),l&&(this.el.addEventListener("touchstart",p),this.el.addEventListener("pointerdown",c)),this}destroy(){return this.moving&&this._mouseUp(this.mouseDownEvent),this.el.removeEventListener("mousedown",this._mouseDown),l&&(this.el.removeEventListener("touchstart",p),this.el.removeEventListener("pointerdown",c)),this.host.removeChild(this.el),delete this.el,delete this.host,this}_mouseDown(e){this.mouseDownEvent=e,document.addEventListener("mousemove",this._mouseMove,!0),document.addEventListener("mouseup",this._mouseUp,!0),l&&(this.el.addEventListener("touchmove",g),this.el.addEventListener("touchend",u)),e.stopPropagation(),e.preventDefault()}_mouseMove(e){let t=this.mouseDownEvent;this.moving?this._triggerEvent("move",e):Math.abs(e.x-t.x)+Math.abs(e.y-t.y)>2&&(this.moving=!0,this._triggerEvent("start",this.mouseDownEvent),this._triggerEvent("move",e)),e.stopPropagation(),e.preventDefault()}_mouseUp(e){this.moving&&this._triggerEvent("stop",e),document.removeEventListener("mousemove",this._mouseMove,!0),document.removeEventListener("mouseup",this._mouseUp,!0),l&&(this.el.removeEventListener("touchmove",g),this.el.removeEventListener("touchend",u)),delete this.moving,delete this.mouseDownEvent,e.stopPropagation(),e.preventDefault()}_triggerEvent(e,t){return this.option[e]&&this.option[e](t),this}}v.prefix="ui-resizable-";class f{constructor(){this._eventRegister={}}get disabled(){return this._disabled}on(e,t){this._eventRegister[e]=t}off(e){delete this._eventRegister[e]}enable(){this._disabled=!1}disable(){this._disabled=!0}destroy(){delete this._eventRegister}triggerEvent(e,t){if(!this.disabled&&this._eventRegister&&this._eventRegister[e])return this._eventRegister[e](t)}}class y extends f{constructor(e,t={}){super(),this._ui=()=>{const e=this.el.parentElement.getBoundingClientRect(),t={width:this.originalRect.width,height:this.originalRect.height+this.scrolled,left:this.originalRect.left,top:this.originalRect.top-this.scrolled},i=this.temporalRect||t;return{position:{left:i.left-e.left,top:i.top-e.top},size:{width:i.width,height:i.height}}},this.el=e,this.option=t,this._mouseOver=this._mouseOver.bind(this),this._mouseOut=this._mouseOut.bind(this),this.enable(),this._setupAutoHide(this.option.autoHide),this._setupHandlers()}on(e,t){super.on(e,t)}off(e){super.off(e)}enable(){super.enable(),this.el.classList.remove("ui-resizable-disabled"),this._setupAutoHide(this.option.autoHide)}disable(){super.disable(),this.el.classList.add("ui-resizable-disabled"),this._setupAutoHide(!1)}destroy(){this._removeHandlers(),this._setupAutoHide(!1),delete this.el,super.destroy()}updateOption(e){let t=e.handles&&e.handles!==this.option.handles,i=e.autoHide&&e.autoHide!==this.option.autoHide;return Object.keys(e).forEach((t=>this.option[t]=e[t])),t&&(this._removeHandlers(),this._setupHandlers()),i&&this._setupAutoHide(this.option.autoHide),this}_setupAutoHide(e){return e?(this.el.classList.add("ui-resizable-autohide"),this.el.addEventListener("mouseover",this._mouseOver),this.el.addEventListener("mouseout",this._mouseOut)):(this.el.classList.remove("ui-resizable-autohide"),this.el.removeEventListener("mouseover",this._mouseOver),this.el.removeEventListener("mouseout",this._mouseOut),r.overResizeElement===this&&delete r.overResizeElement),this}_mouseOver(e){r.overResizeElement||r.dragElement||(r.overResizeElement=this,this.el.classList.remove("ui-resizable-autohide"))}_mouseOut(e){r.overResizeElement===this&&(delete r.overResizeElement,this.el.classList.add("ui-resizable-autohide"))}_setupHandlers(){let e=this.option.handles||"e,s,se";return"all"===e&&(e="n,e,s,w,se,sw,ne,nw"),this.handlers=e.split(",").map((e=>e.trim())).map((e=>new v(this.el,e,{start:e=>{this._resizeStart(e)},stop:e=>{this._resizeStop(e)},move:t=>{this._resizing(t,e)}}))),this}_resizeStart(e){this.originalRect=this.el.getBoundingClientRect(),this.scrollEl=i.getScrollElement(this.el),this.scrollY=this.scrollEl.scrollTop,this.scrolled=0,this.startEvent=e,this._setupHelper(),this._applyChange();const t=i.initEvent(e,{type:"resizestart",target:this.el});return this.option.start&&this.option.start(t,this._ui()),this.el.classList.add("ui-resizable-resizing"),this.triggerEvent("resizestart",t),this}_resizing(e,t){this.scrolled=this.scrollEl.scrollTop-this.scrollY,this.temporalRect=this._getChange(e,t),this._applyChange();const s=i.initEvent(e,{type:"resize",target:this.el});return this.option.resize&&this.option.resize(s,this._ui()),this.triggerEvent("resize",s),this}_resizeStop(e){const t=i.initEvent(e,{type:"resizestop",target:this.el});return this.option.stop&&this.option.stop(t),this.el.classList.remove("ui-resizable-resizing"),this.triggerEvent("resizestop",t),this._cleanHelper(),delete this.startEvent,delete this.originalRect,delete this.temporalRect,delete this.scrollY,delete this.scrolled,this}_setupHelper(){return this.elOriginStyleVal=y._originStyleProp.map((e=>this.el.style[e])),this.parentOriginStylePosition=this.el.parentElement.style.position,window.getComputedStyle(this.el.parentElement).position.match(/static/)&&(this.el.parentElement.style.position="relative"),this.el.style.position="absolute",this.el.style.opacity="0.8",this}_cleanHelper(){return y._originStyleProp.forEach(((e,t)=>{this.el.style[e]=this.elOriginStyleVal[t]||null})),this.el.parentElement.style.position=this.parentOriginStylePosition||null,this}_getChange(e,t){const i=this.startEvent,s={width:this.originalRect.width,height:this.originalRect.height+this.scrolled,left:this.originalRect.left,top:this.originalRect.top-this.scrolled},o=e.clientX-i.clientX,n=e.clientY-i.clientY;t.indexOf("e")>-1?s.width+=o:t.indexOf("w")>-1&&(s.width-=o,s.left+=o),t.indexOf("s")>-1?s.height+=n:t.indexOf("n")>-1&&(s.height-=n,s.top+=n);const r=this._constrainSize(s.width,s.height);return Math.round(s.width)!==Math.round(r.width)&&(t.indexOf("w")>-1&&(s.left+=s.width-r.width),s.width=r.width),Math.round(s.height)!==Math.round(r.height)&&(t.indexOf("n")>-1&&(s.top+=s.height-r.height),s.height=r.height),s}_constrainSize(e,t){const i=this.option.maxWidth||Number.MAX_SAFE_INTEGER,s=this.option.minWidth||e,o=this.option.maxHeight||Number.MAX_SAFE_INTEGER,n=this.option.minHeight||t;return{width:Math.min(i,Math.max(s,e)),height:Math.min(o,Math.max(n,t))}}_applyChange(){let e={left:0,top:0,width:0,height:0};if("absolute"===this.el.style.position){const t=this.el.parentElement,{left:i,top:s}=t.getBoundingClientRect();e={left:i,top:s,width:0,height:0}}return this.temporalRect?(Object.keys(this.temporalRect).forEach((t=>{const i=this.temporalRect[t];this.el.style[t]=i-e[t]+"px"})),this):this}_removeHandlers(){return this.handlers.forEach((e=>e.destroy())),delete this.handlers,this}}y._originStyleProp=["width","height","position","left","top","opacity","zIndex"];class b extends f{constructor(e,t={}){super(),this.el=e,this.option=t;let i=t.handle.substring(1);this.dragEl=e.classList.contains(i)?e:e.querySelector(t.handle)||e,this._mouseDown=this._mouseDown.bind(this),this._mouseMove=this._mouseMove.bind(this),this._mouseUp=this._mouseUp.bind(this),this.enable()}on(e,t){super.on(e,t)}off(e){super.off(e)}enable(){!1!==this.disabled&&(super.enable(),this.dragEl.addEventListener("mousedown",this._mouseDown),l&&(this.dragEl.addEventListener("touchstart",p),this.dragEl.addEventListener("pointerdown",c)),this.el.classList.remove("ui-draggable-disabled"))}disable(e=!1){!0!==this.disabled&&(super.disable(),this.dragEl.removeEventListener("mousedown",this._mouseDown),l&&(this.dragEl.removeEventListener("touchstart",p),this.dragEl.removeEventListener("pointerdown",c)),e||this.el.classList.add("ui-draggable-disabled"))}destroy(){this.dragTimeout&&window.clearTimeout(this.dragTimeout),delete this.dragTimeout,this.dragging&&this._mouseUp(this.mouseDownEvent),this.disable(!0),delete this.el,delete this.helper,delete this.option,super.destroy()}updateOption(e){return Object.keys(e).forEach((t=>this.option[t]=e[t])),this}_mouseDown(e){if(!r.mouseHandled)return 0!==e.button||e.target.closest('input,textarea,button,select,option,[contenteditable="true"],.ui-resizable-handle')||this.option.cancel&&e.target.closest(this.option.cancel)||(this.mouseDownEvent=e,delete this.dragging,delete r.dragElement,delete r.dropElement,document.addEventListener("mousemove",this._mouseMove,!0),document.addEventListener("mouseup",this._mouseUp,!0),l&&(this.dragEl.addEventListener("touchmove",g),this.dragEl.addEventListener("touchend",u)),e.preventDefault(),document.activeElement&&document.activeElement.blur(),r.mouseHandled=!0),!0}_callDrag(e){if(!this.dragging)return;const t=i.initEvent(e,{target:this.el,type:"drag"});this.option.drag&&this.option.drag(t,this.ui()),this.triggerEvent("drag",t)}_mouseMove(e){let t=this.mouseDownEvent;if(this.dragging)if(this._dragFollow(e),r.pauseDrag){const t=Number.isInteger(r.pauseDrag)?r.pauseDrag:100;this.dragTimeout&&window.clearTimeout(this.dragTimeout),this.dragTimeout=window.setTimeout((()=>this._callDrag(e)),t)}else this._callDrag(e);else if(Math.abs(e.x-t.x)+Math.abs(e.y-t.y)>3){this.dragging=!0,r.dragElement=this;let t=this.el.gridstackNode?.grid;t?r.dropElement=t.el.ddElement.ddDroppable:delete r.dropElement,this.helper=this._createHelper(e),this._setupHelperContainmentStyle(),this.dragOffset=this._getDragOffset(e,this.el,this.helperContainment);const s=i.initEvent(e,{target:this.el,type:"dragstart"});this._setupHelperStyle(e),this.option.start&&this.option.start(s,this.ui()),this.triggerEvent("dragstart",s)}return e.preventDefault(),!0}_mouseUp(e){if(document.removeEventListener("mousemove",this._mouseMove,!0),document.removeEventListener("mouseup",this._mouseUp,!0),l&&(this.dragEl.removeEventListener("touchmove",g,!0),this.dragEl.removeEventListener("touchend",u,!0)),this.dragging){delete this.dragging,r.dropElement?.el===this.el.parentElement&&delete r.dropElement,this.helperContainment.style.position=this.parentOriginStylePosition||null,this.helper===this.el?this._removeHelperStyle():this.helper.remove();const t=i.initEvent(e,{target:this.el,type:"dragstop"});this.option.stop&&this.option.stop(t),this.triggerEvent("dragstop",t),r.dropElement&&r.dropElement.drop(e)}delete this.helper,delete this.mouseDownEvent,delete r.dragElement,delete r.dropElement,delete r.mouseHandled,e.preventDefault()}_createHelper(e){let t=this.el;return"function"==typeof this.option.helper?t=this.option.helper(e):"clone"===this.option.helper&&(t=i.cloneNode(this.el)),document.body.contains(t)||i.appendTo(t,"parent"===this.option.appendTo?this.el.parentElement:this.option.appendTo),t===this.el&&(this.dragElementOriginStyle=b.originStyleProp.map((e=>this.el.style[e]))),t}_setupHelperStyle(e){this.helper.classList.add("ui-draggable-dragging");const t=this.helper.style;return t.pointerEvents="none",t.width=this.dragOffset.width+"px",t.height=this.dragOffset.height+"px",t.willChange="left, top",t.position="fixed",this._dragFollow(e),t.transition="none",setTimeout((()=>{this.helper&&(t.transition=null)}),0),this}_removeHelperStyle(){this.helper.classList.remove("ui-draggable-dragging");let e=this.helper?.gridstackNode;if(!e?._isAboutToRemove&&this.dragElementOriginStyle){let e=this.helper,t=this.dragElementOriginStyle.transition||null;e.style.transition=this.dragElementOriginStyle.transition="none",b.originStyleProp.forEach((t=>e.style[t]=this.dragElementOriginStyle[t]||null)),setTimeout((()=>e.style.transition=t),50)}return delete this.dragElementOriginStyle,this}_dragFollow(e){const t=this.helper.style,i=this.dragOffset;t.left=e.clientX+i.offsetLeft-0+"px",t.top=e.clientY+i.offsetTop-0+"px"}_setupHelperContainmentStyle(){return this.helperContainment=this.helper.parentElement,"fixed"!==this.helper.style.position&&(this.parentOriginStylePosition=this.helperContainment.style.position,window.getComputedStyle(this.helperContainment).position.match(/static/)&&(this.helperContainment.style.position="relative")),this}_getDragOffset(e,t,s){let o=0,n=0;if(s){const e=document.createElement("div");i.addElStyles(e,{opacity:"0",position:"fixed",top:"0px",left:"0px",width:"1px",height:"1px",zIndex:"-999999"}),s.appendChild(e);const t=e.getBoundingClientRect();s.removeChild(e),o=t.left,n=t.top}const r=t.getBoundingClientRect();return{left:r.left,top:r.top,offsetLeft:-e.clientX+r.left-o,offsetTop:-e.clientY+r.top-n,width:r.width,height:r.height}}ui(){const e=this.el.parentElement.getBoundingClientRect(),t=this.helper.getBoundingClientRect();return{position:{top:t.top-e.top,left:t.left-e.left}}}}b.originStyleProp=["transition","pointerEvents","position","left","top","minWidth","willChange"];class w extends f{constructor(e,t={}){super(),this.el=e,this.option=t,this._mouseEnter=this._mouseEnter.bind(this),this._mouseLeave=this._mouseLeave.bind(this),this.enable(),this._setupAccept()}on(e,t){super.on(e,t)}off(e){super.off(e)}enable(){!1!==this.disabled&&(super.enable(),this.el.classList.add("ui-droppable"),this.el.classList.remove("ui-droppable-disabled"),this.el.addEventListener("mouseenter",this._mouseEnter),this.el.addEventListener("mouseleave",this._mouseLeave),l&&(this.el.addEventListener("pointerenter",m),this.el.addEventListener("pointerleave",_)))}disable(e=!1){!0!==this.disabled&&(super.disable(),this.el.classList.remove("ui-droppable"),e||this.el.classList.add("ui-droppable-disabled"),this.el.removeEventListener("mouseenter",this._mouseEnter),this.el.removeEventListener("mouseleave",this._mouseLeave),l&&(this.el.removeEventListener("pointerenter",m),this.el.removeEventListener("pointerleave",_)))}destroy(){this.disable(!0),this.el.classList.remove("ui-droppable"),this.el.classList.remove("ui-droppable-disabled"),super.destroy()}updateOption(e){return Object.keys(e).forEach((t=>this.option[t]=e[t])),this._setupAccept(),this}_mouseEnter(e){if(!r.dragElement)return;if(!this._canDrop(r.dragElement.el))return;e.preventDefault(),e.stopPropagation(),r.dropElement&&r.dropElement!==this&&r.dropElement._mouseLeave(e),r.dropElement=this;const t=i.initEvent(e,{target:this.el,type:"dropover"});this.option.over&&this.option.over(t,this._ui(r.dragElement)),this.triggerEvent("dropover",t),this.el.classList.add("ui-droppable-over")}_mouseLeave(e){if(!r.dragElement||r.dropElement!==this)return;e.preventDefault(),e.stopPropagation();const t=i.initEvent(e,{target:this.el,type:"dropout"});if(this.option.out&&this.option.out(t,this._ui(r.dragElement)),this.triggerEvent("dropout",t),r.dropElement===this){let t;delete r.dropElement;let i=this.el.parentElement;for(;!t&&i;)t=i.ddElement?.ddDroppable,i=i.parentElement;t&&t._mouseEnter(e)}}drop(e){e.preventDefault();const t=i.initEvent(e,{target:this.el,type:"drop"});this.option.drop&&this.option.drop(t,this._ui(r.dragElement)),this.triggerEvent("drop",t)}_canDrop(e){return e&&(!this.accept||this.accept(e))}_setupAccept(){return this.option.accept?("string"==typeof this.option.accept?this.accept=e=>e.matches(this.option.accept):this.accept=this.option.accept,this):this}_ui(e){return{draggable:e.el,...e.ui()}}}class E{static init(e){return e.ddElement||(e.ddElement=new E(e)),e.ddElement}constructor(e){this.el=e}on(e,t){return this.ddDraggable&&["drag","dragstart","dragstop"].indexOf(e)>-1?this.ddDraggable.on(e,t):this.ddDroppable&&["drop","dropover","dropout"].indexOf(e)>-1?this.ddDroppable.on(e,t):this.ddResizable&&["resizestart","resize","resizestop"].indexOf(e)>-1&&this.ddResizable.on(e,t),this}off(e){return this.ddDraggable&&["drag","dragstart","dragstop"].indexOf(e)>-1?this.ddDraggable.off(e):this.ddDroppable&&["drop","dropover","dropout"].indexOf(e)>-1?this.ddDroppable.off(e):this.ddResizable&&["resizestart","resize","resizestop"].indexOf(e)>-1&&this.ddResizable.off(e),this}setupDraggable(e){return this.ddDraggable?this.ddDraggable.updateOption(e):this.ddDraggable=new b(this.el,e),this}cleanDraggable(){return this.ddDraggable&&(this.ddDraggable.destroy(),delete this.ddDraggable),this}setupResizable(e){return this.ddResizable?this.ddResizable.updateOption(e):this.ddResizable=new y(this.el,e),this}cleanResizable(){return this.ddResizable&&(this.ddResizable.destroy(),delete this.ddResizable),this}setupDroppable(e){return this.ddDroppable?this.ddDroppable.updateOption(e):this.ddDroppable=new w(this.el,e),this}cleanDroppable(){return this.ddDroppable&&(this.ddDroppable.destroy(),delete this.ddDroppable),this}}const x=new class{resizable(e,t,i,s){return this._getDDElements(e).forEach((e=>{if("disable"===t||"enable"===t)e.ddResizable&&e.ddResizable[t]();else if("destroy"===t)e.ddResizable&&e.cleanResizable();else if("option"===t)e.setupResizable({[i]:s});else{const i=e.el.gridstackNode.grid;let s=e.el.getAttribute("gs-resize-handles")?e.el.getAttribute("gs-resize-handles"):i.opts.resizable.handles,o=!i.opts.alwaysShowResizeHandle;e.setupResizable({...i.opts.resizable,handles:s,autoHide:o,start:t.start,stop:t.stop,resize:t.resize})}})),this}draggable(e,t,i,s){return this._getDDElements(e).forEach((e=>{if("disable"===t||"enable"===t)e.ddDraggable&&e.ddDraggable[t]();else if("destroy"===t)e.ddDraggable&&e.cleanDraggable();else if("option"===t)e.setupDraggable({[i]:s});else{const i=e.el.gridstackNode.grid;e.setupDraggable({...i.opts.draggable,start:t.start,stop:t.stop,drag:t.drag})}})),this}dragIn(e,t){return this._getDDElements(e).forEach((e=>e.setupDraggable(t))),this}droppable(e,t,i,s){return"function"!=typeof t.accept||t._accept||(t._accept=t.accept,t.accept=e=>t._accept(e)),this._getDDElements(e).forEach((e=>{"disable"===t||"enable"===t?e.ddDroppable&&e.ddDroppable[t]():"destroy"===t?e.ddDroppable&&e.cleanDroppable():"option"===t?e.setupDroppable({[i]:s}):e.setupDroppable(t)})),this}isDroppable(e){return!(!(e&&e.ddElement&&e.ddElement.ddDroppable)||e.ddElement.ddDroppable.disabled)}isDraggable(e){return!(!(e&&e.ddElement&&e.ddElement.ddDraggable)||e.ddElement.ddDraggable.disabled)}isResizable(e){return!(!(e&&e.ddElement&&e.ddElement.ddResizable)||e.ddElement.ddResizable.disabled)}on(e,t,i){return this._getDDElements(e).forEach((e=>e.on(t,(e=>{i(e,r.dragElement?r.dragElement.el:e.target,r.dragElement?r.dragElement.helper:null)})))),this}off(e,t){return this._getDDElements(e).forEach((e=>e.off(t))),this}_getDDElements(e,t=!0){let s=i.getElements(e);if(!s.length)return[];let o=s.map((e=>e.ddElement||(t?E.init(e):null)));return t||o.filter((e=>e)),o}};class R{static init(e={},t=".grid-stack"){let s=R.getGridElement(t);return s?(s.gridstack||(s.gridstack=new R(s,i.cloneDeep(e))),s.gridstack):("string"==typeof t?console.error('GridStack.initAll() no grid was found with selector "'+t+'" - element missing or wrong selector ?\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.'):console.error("GridStack.init() no grid element was passed."),null)}static initAll(e={},t=".grid-stack"){let s=[];return R.getGridElements(t).forEach((t=>{t.gridstack||(t.gridstack=new R(t,i.cloneDeep(e))),s.push(t.gridstack)})),0===s.length&&console.error('GridStack.initAll() no grid was found with selector "'+t+'" - element missing or wrong selector ?\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.'),s}static addGrid(e,t={}){if(!e)return null;let i=e;if(i.gridstack){const e=i.gridstack;return t&&(e.opts={...e.opts,...t}),void 0!==t.children&&e.load(t.children),e}if(!e.classList.contains("grid-stack")||R.addRemoveCB)if(R.addRemoveCB)i=R.addRemoveCB(e,t,!0,!0);else{let s=document.implementation.createHTMLDocument("");s.body.innerHTML=`<div class="grid-stack ${t.class||""}"></div>`,i=s.body.children[0],e.appendChild(i)}return R.init(t,i)}static registerEngine(e){R.engineClass=e}get placeholder(){if(!this._placeholder){let e=document.createElement("div");e.className="placeholder-content",this.opts.placeholderText&&(e.innerHTML=this.opts.placeholderText),this._placeholder=document.createElement("div"),this._placeholder.classList.add(this.opts.placeholderClass,o.itemClass,this.opts.itemClass),this.placeholder.appendChild(e)}return this._placeholder}constructor(e,t={}){this._gsEventHandler={},this._extraDragRow=0,this.el=e,t=t||{},e.classList.contains("grid-stack")||this.el.classList.add("grid-stack"),t.row&&(t.minRow=t.maxRow=t.row,delete t.row);let n=i.toNumber(e.getAttribute("gs-row"));"auto"===t.column&&delete t.column,void 0!==t.alwaysShowResizeHandle&&(t._alwaysShowResizeHandle=t.alwaysShowResizeHandle);let h={...i.cloneDeep(o),column:i.toNumber(e.getAttribute("gs-column"))||o.column,minRow:n||i.toNumber(e.getAttribute("gs-min-row"))||o.minRow,maxRow:n||i.toNumber(e.getAttribute("gs-max-row"))||o.maxRow,staticGrid:i.toBool(e.getAttribute("gs-static"))||o.staticGrid,draggable:{handle:(t.handleClass?"."+t.handleClass:t.handle?t.handle:"")||o.draggable.handle},removableOptions:{accept:t.itemClass?"."+t.itemClass:o.removableOptions.accept}};e.getAttribute("gs-animate")&&(h.animate=i.toBool(e.getAttribute("gs-animate"))),this.opts=i.defaults(t,h),t=null,this._initMargin(),1!==this.opts.column&&!this.opts.disableOneColumnMode&&this._widthOrContainer()<=this.opts.oneColumnSize&&(this._prevColumn=this.getColumn(),this.opts.column=1),"auto"===this.opts.rtl&&(this.opts.rtl="rtl"===e.style.direction),this.opts.rtl&&this.el.classList.add("grid-stack-rtl");let a=i.closestUpByClass(this.el,o.itemClass)?.gridstackNode;a&&(a.subGrid=this,this.parentGridItem=a,this.el.classList.add("grid-stack-nested"),a.el.classList.add("grid-stack-sub-grid")),this._isAutoCellHeight="auto"===this.opts.cellHeight,this._isAutoCellHeight||"initial"===this.opts.cellHeight?this.cellHeight(void 0,!1):("number"==typeof this.opts.cellHeight&&this.opts.cellHeightUnit&&this.opts.cellHeightUnit!==o.cellHeightUnit&&(this.opts.cellHeight=this.opts.cellHeight+this.opts.cellHeightUnit,delete this.opts.cellHeightUnit),this.cellHeight(this.opts.cellHeight,!1)),"mobile"===this.opts.alwaysShowResizeHandle&&(this.opts.alwaysShowResizeHandle=l),this._styleSheetClass="gs-id-"+s._idSeq++,this.el.classList.add(this._styleSheetClass),this._setStaticClass();let d=this.opts.engineClass||R.engineClass||s;if(this.engine=new d({column:this.getColumn(),float:this.opts.float,maxRow:this.opts.maxRow,onChange:e=>{let t=0;this.engine.nodes.forEach((e=>{t=Math.max(t,e.y+e.h)})),e.forEach((e=>{let t=e.el;t&&(e._removeDOM?(t&&t.remove(),delete e._removeDOM):this._writePosAttr(t,e))})),this._updateStyles(!1,t)}}),this.opts.auto&&(this.batchUpdate(),this.getGridItems().forEach((e=>this._prepareElement(e))),this.batchUpdate(!1)),this.opts.children){let e=this.opts.children;delete this.opts.children,e.length&&this.load(e)}this.setAnimation(this.opts.animate),this._updateStyles(),this.el.classList.add("gs-"+this.opts.column),this.opts.subGridDynamic&&!r.pauseDrag&&(r.pauseDrag=!0),void 0!==this.opts.draggable?.pause&&(r.pauseDrag=this.opts.draggable.pause),this._setupRemoveDrop(),this._setupAcceptWidget(),this._updateWindowResizeEvent()}addWidget(e,t){let s,o;if("string"==typeof e){let t=document.implementation.createHTMLDocument("");t.body.innerHTML=e,s=t.body.children[0]}else if(0===arguments.length||1===arguments.length&&(void 0!==(n=e).el||void 0!==n.x||void 0!==n.y||void 0!==n.w||void 0!==n.h||void 0!==n.content))if(o=t=e,o?.el)s=o.el;else if(R.addRemoveCB)s=R.addRemoveCB(this.el,t,!0,!1);else{let e=t?.content||"",i=document.implementation.createHTMLDocument("");i.body.innerHTML=`<div class="grid-stack-item ${this.opts.itemClass||""}"><div class="grid-stack-item-content">${e}</div></div>`,s=i.body.children[0]}else s=e;var n;if(!s)return;if(o=s.gridstackNode,o&&s.parentElement===this.el&&this.engine.nodes.find((e=>e._id===o._id)))return s;let r=this._readAttr(s);return t=i.cloneDeep(t)||{},i.defaults(t,r),o=this.engine.prepareNode(t),this._writeAttr(s,t),this._insertNotAppend?this.el.prepend(s):this.el.appendChild(s),this.makeWidget(s,t),s}makeSubGrid(e,t,s,o=!0){let n,r=e.gridstackNode;if(r||(r=this.makeWidget(e).gridstackNode),r.subGrid?.el)return r.subGrid;let l,h=this;for(;h&&!n;)n=h.opts?.subGridOpts,h=h.parentGridItem?.grid;t=i.cloneDeep({...n||{},children:void 0,...t||r.subGridOpts}),r.subGridOpts=t,"auto"===t.column&&(l=!0,t.column=Math.max(r.w||1,s?.w||1),t.disableOneColumnMode=!0);let a,d,p=r.el.querySelector(".grid-stack-item-content");if(o){if(this._removeDD(r.el),d={...r,x:0,y:0},i.removeInternalForSave(d),delete d.subGridOpts,r.content&&(d.content=r.content,delete r.content),R.addRemoveCB)a=R.addRemoveCB(this.el,d,!0,!1);else{let e=document.implementation.createHTMLDocument("");e.body.innerHTML='<div class="grid-stack-item"></div>',a=e.body.children[0],a.appendChild(p),e.body.innerHTML='<div class="grid-stack-item-content"></div>',p=e.body.children[0],r.el.appendChild(p)}this._prepareDragDropByNode(r)}if(s){let e=l?t.column:r.w,i=r.h+s.h,o=r.el.style;o.transition="none",this.update(r.el,{w:e,h:i}),setTimeout((()=>o.transition=null))}let g=r.subGrid=R.addGrid(p,t);return s?._moving&&(g._isTemp=!0),l&&(g._autoColumn=!0),o&&g.addWidget(a,d),s&&(s._moving?window.setTimeout((()=>i.simulateMouseEvent(s._event,"mouseenter",g.el)),0):g.addWidget(r.el,r)),g}removeAsSubGrid(e){let t=this.parentGridItem?.grid;t&&(t.batchUpdate(),t.removeWidget(this.parentGridItem.el,!0,!0),this.engine.nodes.forEach((e=>{e.x+=this.parentGridItem.x,e.y+=this.parentGridItem.y,t.addWidget(e.el,e)})),t.batchUpdate(!1),this.parentGridItem&&delete this.parentGridItem.subGrid,delete this.parentGridItem,e&&window.setTimeout((()=>i.simulateMouseEvent(e._event,"mouseenter",t.el)),0))}save(e=!0,t=!1,s=R.saveCB){let n=this.engine.save(e,s);if(n.forEach((i=>{if(e&&i.el&&!i.subGrid&&!s){let e=i.el.querySelector(".grid-stack-item-content");i.content=e?e.innerHTML:void 0,i.content||delete i.content}else if(e||s||delete i.content,i.subGrid?.el){const o=i.subGrid.save(e,t,s);i.subGridOpts=t?o:{children:o},delete i.subGrid}delete i.el})),t){let e=i.cloneDeep(this.opts);e.marginBottom===e.marginTop&&e.marginRight===e.marginLeft&&e.marginTop===e.marginRight&&(e.margin=e.marginTop,delete e.marginTop,delete e.marginRight,delete e.marginBottom,delete e.marginLeft),e.rtl===("rtl"===this.el.style.direction)&&(e.rtl="auto"),this._isAutoCellHeight&&(e.cellHeight="auto"),this._autoColumn&&(e.column="auto",delete e.disableOneColumnMode);const t=e._alwaysShowResizeHandle;return delete e._alwaysShowResizeHandle,void 0!==t?e.alwaysShowResizeHandle=t:delete e.alwaysShowResizeHandle,i.removeInternalAndSame(e,o),e.children=n,e}return n}load(e,t=R.addRemoveCB||!0){let i=R.Utils.sort([...e],-1,this._prevColumn||this.getColumn());this._insertNotAppend=!0,this._prevColumn&&this._prevColumn!==this.opts.column&&i.some((e=>e.x+e.w>this.opts.column))&&(this._ignoreLayoutsNodeChange=!0,this.engine.cacheLayout(i,this._prevColumn,!0));const s=R.addRemoveCB;"function"==typeof t&&(R.addRemoveCB=t);let o=[];return this.batchUpdate(),t&&[...this.engine.nodes].forEach((e=>{i.find((t=>e.id===t.id))||(R.addRemoveCB&&R.addRemoveCB(this.el,e,!1,!1),o.push(e),this.removeWidget(e.el,!0,!1))})),i.forEach((e=>{let i=void 0!==e.id?this.engine.nodes.find((t=>t.id===e.id)):void 0;if(i){if(this.update(i.el,e),e.subGridOpts?.children){let t=i.el.querySelector(".grid-stack");t&&t.gridstack&&(t.gridstack.load(e.subGridOpts.children),this._insertNotAppend=!0)}}else t&&this.addWidget(e)})),this.engine.removedNodes=o,this.batchUpdate(!1),delete this._ignoreLayoutsNodeChange,delete this._insertNotAppend,s?R.addRemoveCB=s:delete R.addRemoveCB,this}batchUpdate(e=!0){return this.engine.batchUpdate(e),e||(this._triggerRemoveEvent(),this._triggerAddEvent(),this._triggerChangeEvent()),this}getCellHeight(e=!1){if(this.opts.cellHeight&&"auto"!==this.opts.cellHeight&&(!e||!this.opts.cellHeightUnit||"px"===this.opts.cellHeightUnit))return this.opts.cellHeight;let t=this.el.querySelector("."+this.opts.itemClass);if(t){let e=i.toNumber(t.getAttribute("gs-h"))||1;return Math.round(t.offsetHeight/e)}let s=parseInt(this.el.getAttribute("gs-current-row"));return s?Math.round(this.el.getBoundingClientRect().height/s):this.opts.cellHeight}cellHeight(e,t=!0){if(t&&void 0!==e&&this._isAutoCellHeight!==("auto"===e)&&(this._isAutoCellHeight="auto"===e,this._updateWindowResizeEvent()),"initial"!==e&&"auto"!==e||(e=void 0),void 0===e){let t=-this.opts.marginRight-this.opts.marginLeft+this.opts.marginTop+this.opts.marginBottom;e=this.cellWidth()+t}let s=i.parseHeight(e);return this.opts.cellHeightUnit===s.unit&&this.opts.cellHeight===s.h||(this.opts.cellHeightUnit=s.unit,this.opts.cellHeight=s.h,t&&this._updateStyles(!0)),this}cellWidth(){return this._widthOrContainer()/this.getColumn()}_widthOrContainer(){return this.el.clientWidth||this.el.parentElement.clientWidth||window.innerWidth}compact(e="compact",t=!0){return this.engine.compact(e,t),this._triggerChangeEvent(),this}column(e,t="moveScale"){if(e<1||this.opts.column===e)return this;let i,s=this.getColumn();return 1===e?this._prevColumn=s:delete this._prevColumn,this.el.classList.remove("gs-"+s),this.el.classList.add("gs-"+e),this.opts.column=this.engine.column=e,1===e&&this.opts.oneColumnModeDomSort&&(i=[],this.getGridItems().forEach((e=>{e.gridstackNode&&i.push(e.gridstackNode)})),i.length||(i=void 0)),this.engine.columnChanged(s,e,i,t),this._isAutoCellHeight&&this.cellHeight(),this._ignoreLayoutsNodeChange=!0,this._triggerChangeEvent(),delete this._ignoreLayoutsNodeChange,this}getColumn(){return this.opts.column}getGridItems(){return Array.from(this.el.children).filter((e=>e.matches("."+this.opts.itemClass)&&!e.matches("."+this.opts.placeholderClass)))}destroy(e=!0){if(this.el)return this.offAll(),this._updateWindowResizeEvent(!0),this.setStatic(!0,!1),this.setAnimation(!1),e?this.el.parentNode.removeChild(this.el):(this.removeAll(e),this.el.classList.remove(this._styleSheetClass),this.el.removeAttribute("gs-current-row")),this._removeStylesheet(),this.parentGridItem&&delete this.parentGridItem.subGrid,delete this.parentGridItem,delete this.opts,delete this._placeholder,delete this.engine,delete this.el.gridstack,delete this.el,this}float(e){return this.opts.float!==e&&(this.opts.float=this.engine.float=e,this._triggerChangeEvent()),this}getFloat(){return this.engine.float}getCellFromPixel(e,t=!1){let i,s=this.el.getBoundingClientRect();i=t?{top:s.top+document.documentElement.scrollTop,left:s.left}:{top:this.el.offsetTop,left:this.el.offsetLeft};let o=e.left-i.left,n=e.top-i.top,r=s.width/this.getColumn(),l=s.height/parseInt(this.el.getAttribute("gs-current-row"));return{x:Math.floor(o/r),y:Math.floor(n/l)}}getRow(){return Math.max(this.engine.getRow(),this.opts.minRow)}isAreaEmpty(e,t,i,s){return this.engine.isAreaEmpty(e,t,i,s)}makeWidget(e,t){let i=R.getElement(e);this._prepareElement(i,!0,t),this._updateContainerHeight();const s=i.gridstackNode;return s.subGridOpts&&this.makeSubGrid(i,s.subGridOpts,void 0,!1),this._prevColumn&&1===this.opts.column&&(this._ignoreLayoutsNodeChange=!0),this._triggerAddEvent(),this._triggerChangeEvent(),delete this._ignoreLayoutsNodeChange,i}on(e,t){if(-1!==e.indexOf(" "))return e.split(" ").forEach((e=>this.on(e,t))),this;if("change"===e||"added"===e||"removed"===e||"enable"===e||"disable"===e){let i="enable"===e||"disable"===e;this._gsEventHandler[e]=i?e=>t(e):e=>t(e,e.detail),this.el.addEventListener(e,this._gsEventHandler[e])}else"drag"===e||"dragstart"===e||"dragstop"===e||"resizestart"===e||"resize"===e||"resizestop"===e||"dropped"===e?this._gsEventHandler[e]=t:console.log("GridStack.on("+e+') event not supported, but you can still use $(".grid-stack").on(...) while jquery-ui is still used internally.');return this}off(e){return-1!==e.indexOf(" ")?(e.split(" ").forEach((e=>this.off(e))),this):("change"!==e&&"added"!==e&&"removed"!==e&&"enable"!==e&&"disable"!==e||this._gsEventHandler[e]&&this.el.removeEventListener(e,this._gsEventHandler[e]),delete this._gsEventHandler[e],this)}offAll(){return Object.keys(this._gsEventHandler).forEach((e=>this.off(e))),this}removeWidget(e,t=!0,i=!0){return R.getElements(e).forEach((e=>{if(e.parentElement&&e.parentElement!==this.el)return;let s=e.gridstackNode;s||(s=this.engine.nodes.find((t=>e===t.el))),s&&(R.addRemoveCB&&R.addRemoveCB(this.el,s,!1,!1),delete e.gridstackNode,this._removeDD(e),this.engine.removeNode(s,t,i),t&&e.parentElement&&e.remove())})),i&&(this._triggerRemoveEvent(),this._triggerChangeEvent()),this}removeAll(e=!0){return this.engine.nodes.forEach((e=>{delete e.el.gridstackNode,this._removeDD(e.el)})),this.engine.removeAll(e),this._triggerRemoveEvent(),this}setAnimation(e){return e?this.el.classList.add("grid-stack-animate"):this.el.classList.remove("grid-stack-animate"),this}setStatic(e,t=!0,i=!0){return!!this.opts.staticGrid===e||(e?this.opts.staticGrid=!0:delete this.opts.staticGrid,this._setupRemoveDrop(),this._setupAcceptWidget(),this.engine.nodes.forEach((s=>{this._prepareDragDropByNode(s),s.subGrid&&i&&s.subGrid.setStatic(e,t,i)})),t&&this._setStaticClass()),this}update(e,t){if(arguments.length>2){console.warn("gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon");let i=arguments,s=1;return t={x:i[s++],y:i[s++],w:i[s++],h:i[s++]},this.update(e,t)}return R.getElements(e).forEach((e=>{if(!e||!e.gridstackNode)return;let s=e.gridstackNode,o=i.cloneDeep(t);delete o.autoPosition;let n,r=["x","y","w","h"];if(r.some((e=>void 0!==o[e]&&o[e]!==s[e]))&&(n={},r.forEach((e=>{n[e]=void 0!==o[e]?o[e]:s[e],delete o[e]}))),!n&&(o.minW||o.minH||o.maxW||o.maxH)&&(n={}),o.content){let t=e.querySelector(".grid-stack-item-content");t&&t.innerHTML!==o.content&&(t.innerHTML=o.content),delete o.content}let l=!1,h=!1;for(const e in o)"_"!==e[0]&&s[e]!==o[e]&&(s[e]=o[e],l=!0,h=h||!this.opts.staticGrid&&("noResize"===e||"noMove"===e||"locked"===e));i.sanitizeMinMax(s),n&&(this.engine.cleanNodes().beginUpdate(s).moveNode(s,n),this._updateContainerHeight(),this._triggerChangeEvent(),this.engine.endUpdate()),l&&this._writeAttr(e,s),h&&this._prepareDragDropByNode(s)})),this}margin(e){if(!("string"==typeof e&&e.split(" ").length>1)){let t=i.parseHeight(e);if(this.opts.marginUnit===t.unit&&this.opts.margin===t.h)return}return this.opts.margin=e,this.opts.marginTop=this.opts.marginBottom=this.opts.marginLeft=this.opts.marginRight=void 0,this._initMargin(),this._updateStyles(!0),this}getMargin(){return this.opts.margin}willItFit(e){if(arguments.length>1){console.warn("gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon");let e=arguments,t=0,i={x:e[t++],y:e[t++],w:e[t++],h:e[t++],autoPosition:e[t++]};return this.willItFit(i)}return this.engine.willItFit(e)}_triggerChangeEvent(){if(this.engine.batchMode)return this;let e=this.engine.getDirtyNodes(!0);return e&&e.length&&(this._ignoreLayoutsNodeChange||this.engine.layoutsNodesChange(e),this._triggerEvent("change",e)),this.engine.saveInitial(),this}_triggerAddEvent(){return this.engine.batchMode||this.engine.addedNodes?.length&&(this._ignoreLayoutsNodeChange||this.engine.layoutsNodesChange(this.engine.addedNodes),this.engine.addedNodes.forEach((e=>{delete e._dirty})),this._triggerEvent("added",this.engine.addedNodes),this.engine.addedNodes=[]),this}_triggerRemoveEvent(){return this.engine.batchMode||this.engine.removedNodes?.length&&(this._triggerEvent("removed",this.engine.removedNodes),this.engine.removedNodes=[]),this}_triggerEvent(e,t){let i=t?new CustomEvent(e,{bubbles:!1,detail:t}):new Event(e);return this.el.dispatchEvent(i),this}_removeStylesheet(){return this._styles&&(i.removeStylesheet(this._styleSheetClass),delete this._styles),this}_updateStyles(e=!1,t){if(e&&this._removeStylesheet(),t||(t=this.getRow()),this._updateContainerHeight(),0===this.opts.cellHeight)return this;let s=this.opts.cellHeight,o=this.opts.cellHeightUnit,n=`.${this._styleSheetClass} > .${this.opts.itemClass}`;if(!this._styles){let e=this.opts.styleInHead?void 0:this.el.parentNode;if(this._styles=i.createStylesheet(this._styleSheetClass,e,{nonce:this.opts.nonce}),!this._styles)return this;this._styles._max=0,i.addCSSRule(this._styles,n,`height: ${s}${o}`);let t=this.opts.marginTop+this.opts.marginUnit,r=this.opts.marginBottom+this.opts.marginUnit,l=this.opts.marginRight+this.opts.marginUnit,h=this.opts.marginLeft+this.opts.marginUnit,a=`${n} > .grid-stack-item-content`,d=`.${this._styleSheetClass} > .grid-stack-placeholder > .placeholder-content`;i.addCSSRule(this._styles,a,`top: ${t}; right: ${l}; bottom: ${r}; left: ${h};`),i.addCSSRule(this._styles,d,`top: ${t}; right: ${l}; bottom: ${r}; left: ${h};`),i.addCSSRule(this._styles,`${n} > .ui-resizable-ne`,`right: ${l}`),i.addCSSRule(this._styles,`${n} > .ui-resizable-e`,`right: ${l}`),i.addCSSRule(this._styles,`${n} > .ui-resizable-se`,`right: ${l}; bottom: ${r}`),i.addCSSRule(this._styles,`${n} > .ui-resizable-nw`,`left: ${h}`),i.addCSSRule(this._styles,`${n} > .ui-resizable-w`,`left: ${h}`),i.addCSSRule(this._styles,`${n} > .ui-resizable-sw`,`left: ${h}; bottom: ${r}`)}if((t=t||this._styles._max)>this._styles._max){let e=e=>s*e+o;for(let s=this._styles._max+1;s<=t;s++)i.addCSSRule(this._styles,`${n}[gs-y="${s}"]`,`top: ${e(s)}`),i.addCSSRule(this._styles,`${n}[gs-h="${s+1}"]`,`height: ${e(s+1)}`);this._styles._max=t}return this}_updateContainerHeight(){if(!this.engine||this.engine.batchMode)return this;let e=this.getRow()+this._extraDragRow;if(this.el.setAttribute("gs-current-row",String(e)),0===e)return this.el.style.removeProperty("min-height"),this;let t=this.opts.cellHeight,i=this.opts.cellHeightUnit;return t?(this.el.style.minHeight=e*t+i,this):this}_prepareElement(e,t=!1,s){e.classList.add(this.opts.itemClass),s=s||this._readAttr(e),e.gridstackNode=s,s.el=e,s.grid=this;let o={...s};return s=this.engine.addNode(s,t),i.same(s,o)||this._writeAttr(e,s),this._prepareDragDropByNode(s),this}_writePosAttr(e,t){return void 0!==t.x&&null!==t.x&&e.setAttribute("gs-x",String(t.x)),void 0!==t.y&&null!==t.y&&e.setAttribute("gs-y",String(t.y)),t.w>1?e.setAttribute("gs-w",String(t.w)):e.removeAttribute("gs-w"),t.h>1?e.setAttribute("gs-h",String(t.h)):e.removeAttribute("gs-h"),this}_writeAttr(e,t){if(!t)return this;this._writePosAttr(e,t);let i={autoPosition:"gs-auto-position",noResize:"gs-no-resize",noMove:"gs-no-move",locked:"gs-locked",id:"gs-id"};for(const s in i)t[s]?e.setAttribute(i[s],String(t[s])):e.removeAttribute(i[s]);return this}_readAttr(e,t=!0){let s={};s.x=i.toNumber(e.getAttribute("gs-x")),s.y=i.toNumber(e.getAttribute("gs-y")),s.w=i.toNumber(e.getAttribute("gs-w")),s.h=i.toNumber(e.getAttribute("gs-h")),s.autoPosition=i.toBool(e.getAttribute("gs-auto-position")),s.noResize=i.toBool(e.getAttribute("gs-no-resize")),s.noMove=i.toBool(e.getAttribute("gs-no-move")),s.locked=i.toBool(e.getAttribute("gs-locked")),s.id=e.getAttribute("gs-id"),s.maxW=i.toNumber(e.getAttribute("gs-max-w")),s.minW=i.toNumber(e.getAttribute("gs-min-w")),s.maxH=i.toNumber(e.getAttribute("gs-max-h")),s.minH=i.toNumber(e.getAttribute("gs-min-h")),t&&(1===s.w&&e.removeAttribute("gs-w"),1===s.h&&e.removeAttribute("gs-h"),s.maxW&&e.removeAttribute("gs-max-w"),s.minW&&e.removeAttribute("gs-min-w"),s.maxH&&e.removeAttribute("gs-max-h"),s.minH&&e.removeAttribute("gs-min-h"));for(const e in s){if(!s.hasOwnProperty(e))return;s[e]||0===s[e]||delete s[e]}return s}_setStaticClass(){let e=["grid-stack-static"];return this.opts.staticGrid?(this.el.classList.add(...e),this.el.setAttribute("gs-static","true")):(this.el.classList.remove(...e),this.el.removeAttribute("gs-static")),this}onParentResize(){if(!this.el||!this.el.clientWidth)return;let e=!1;if(this._autoColumn&&this.parentGridItem)this.opts.column!==this.parentGridItem.w&&(e=!0,this.column(this.parentGridItem.w,"none"));else{let t=!this.opts.disableOneColumnMode&&this.el.clientWidth<=this.opts.oneColumnSize;1===this.opts.column!==t&&(e=!0,this.opts.animate&&this.setAnimation(!1),this.column(t?1:this._prevColumn),this.opts.animate&&this.setAnimation(!0))}return this._isAutoCellHeight&&(!e&&this.opts.cellHeightThrottle?(this._cellHeightThrottle||(this._cellHeightThrottle=i.throttle((()=>this.cellHeight()),this.opts.cellHeightThrottle)),this._cellHeightThrottle()):this.cellHeight()),this.engine.nodes.forEach((e=>{e.subGrid&&e.subGrid.onParentResize()})),this}_updateWindowResizeEvent(e=!1){const t=(this._isAutoCellHeight||!this.opts.disableOneColumnMode)&&!this.parentGridItem;return e||!t||this._windowResizeBind?!e&&t||!this._windowResizeBind||(window.removeEventListener("resize",this._windowResizeBind),delete this._windowResizeBind):(this._windowResizeBind=this.onParentResize.bind(this),window.addEventListener("resize",this._windowResizeBind)),this}static getElement(e=".grid-stack-item"){return i.getElement(e)}static getElements(e=".grid-stack-item"){return i.getElements(e)}static getGridElement(e){return R.getElement(e)}static getGridElements(e){return i.getElements(e)}_initMargin(){let e,t=0,s=[];return"string"==typeof this.opts.margin&&(s=this.opts.margin.split(" ")),2===s.length?(this.opts.marginTop=this.opts.marginBottom=s[0],this.opts.marginLeft=this.opts.marginRight=s[1]):4===s.length?(this.opts.marginTop=s[0],this.opts.marginRight=s[1],this.opts.marginBottom=s[2],this.opts.marginLeft=s[3]):(e=i.parseHeight(this.opts.margin),this.opts.marginUnit=e.unit,t=this.opts.margin=e.h),void 0===this.opts.marginTop?this.opts.marginTop=t:(e=i.parseHeight(this.opts.marginTop),this.opts.marginTop=e.h,delete this.opts.margin),void 0===this.opts.marginBottom?this.opts.marginBottom=t:(e=i.parseHeight(this.opts.marginBottom),this.opts.marginBottom=e.h,delete this.opts.margin),void 0===this.opts.marginRight?this.opts.marginRight=t:(e=i.parseHeight(this.opts.marginRight),this.opts.marginRight=e.h,delete this.opts.margin),void 0===this.opts.marginLeft?this.opts.marginLeft=t:(e=i.parseHeight(this.opts.marginLeft),this.opts.marginLeft=e.h,delete this.opts.margin),this.opts.marginUnit=e.unit,this.opts.marginTop===this.opts.marginBottom&&this.opts.marginLeft===this.opts.marginRight&&this.opts.marginTop===this.opts.marginRight&&(this.opts.margin=this.opts.marginTop),this}static getDD(){return x}static setupDragIn(e,t,s=document){void 0!==t?.pause&&(r.pauseDrag=t.pause),t={...n,...t||{}};let o="string"==typeof e?i.getElements(e,s):e;o.length&&o?.forEach((e=>{x.isDraggable(e)||x.dragIn(e,t)}))}movable(e,t){return this.opts.staticGrid||R.getElements(e).forEach((e=>{let i=e.gridstackNode;i&&(t?delete i.noMove:i.noMove=!0,this._prepareDragDropByNode(i))})),this}resizable(e,t){return this.opts.staticGrid||R.getElements(e).forEach((e=>{let i=e.gridstackNode;i&&(t?delete i.noResize:i.noResize=!0,this._prepareDragDropByNode(i))})),this}disable(e=!0){if(!this.opts.staticGrid)return this.enableMove(!1,e),this.enableResize(!1,e),this._triggerEvent("disable"),this}enable(e=!0){if(!this.opts.staticGrid)return this.enableMove(!0,e),this.enableResize(!0,e),this._triggerEvent("enable"),this}enableMove(e,t=!0){return this.opts.staticGrid||(e?delete this.opts.disableDrag:this.opts.disableDrag=!0,this.engine.nodes.forEach((i=>{this._prepareDragDropByNode(i),i.subGrid&&t&&i.subGrid.enableMove(e,t)}))),this}enableResize(e,t=!0){return this.opts.staticGrid||(e?delete this.opts.disableResize:this.opts.disableResize=!0,this.engine.nodes.forEach((i=>{this._prepareDragDropByNode(i),i.subGrid&&t&&i.subGrid.enableResize(e,t)}))),this}_removeDD(e){return x.draggable(e,"destroy").resizable(e,"destroy"),e.gridstackNode&&delete e.gridstackNode._initDD,delete e.ddElement,this}_setupAcceptWidget(){if(this.opts.staticGrid||!this.opts.acceptWidgets&&!this.opts.removable)return x.droppable(this.el,"destroy"),this;let e,t,s=(s,o,n)=>{let r=o.gridstackNode;if(!r)return;n=n||o;let l=this.el.getBoundingClientRect(),{top:h,left:a}=n.getBoundingClientRect();a-=l.left,h-=l.top;let d={position:{top:h,left:a}};if(r._temporaryRemoved){if(r.x=Math.max(0,Math.round(a/t)),r.y=Math.max(0,Math.round(h/e)),delete r.autoPosition,this.engine.nodeBoundFix(r),!this.engine.willItFit(r)){if(r.autoPosition=!0,!this.engine.willItFit(r))return void x.off(o,"drag");r._willFitPos&&(i.copyPos(r,r._willFitPos),delete r._willFitPos)}this._onStartMoving(n,s,d,r,t,e)}else this._dragOrResize(n,s,d,r,t,e)};return x.droppable(this.el,{accept:e=>{let t=e.gridstackNode;if(t?.grid===this)return!0;if(!this.opts.acceptWidgets)return!1;let i=!0;if("function"==typeof this.opts.acceptWidgets)i=this.opts.acceptWidgets(e);else{let t=!0===this.opts.acceptWidgets?".grid-stack-item":this.opts.acceptWidgets;i=e.matches(t)}if(i&&t&&this.opts.maxRow){let e={w:t.w,h:t.h,minW:t.minW,minH:t.minH};i=this.engine.willItFit(e)}return i}}).on(this.el,"dropover",((i,o,n)=>{let r=o.gridstackNode;if(r?.grid===this&&!r._temporaryRemoved)return!1;r?.grid&&r.grid!==this&&!r._temporaryRemoved&&r.grid._leave(o,n),t=this.cellWidth(),e=this.getCellHeight(!0),r||(r=this._readAttr(o,!1)),r.grid||(r._isExternal=!0,o.gridstackNode=r),n=n||o;let l=r.w||Math.round(n.offsetWidth/t)||1,h=r.h||Math.round(n.offsetHeight/e)||1;return r.grid&&r.grid!==this?(o._gridstackNodeOrig||(o._gridstackNodeOrig=r),o.gridstackNode=r={...r,w:l,h,grid:this},this.engine.cleanupNode(r).nodeBoundFix(r),r._initDD=r._isExternal=r._temporaryRemoved=!0):(r.w=l,r.h=h,r._temporaryRemoved=!0),this._itemRemoving(r.el,!1),x.on(o,"drag",s),s(i,o,n),!1})).on(this.el,"dropout",((e,t,i)=>{let s=t.gridstackNode;return!!s&&(s.grid&&s.grid!==this||(this._leave(t,i),this._isTemp&&this.removeAsSubGrid(s)),!1)})).on(this.el,"drop",((e,t,s)=>{let n=t.gridstackNode;if(n?.grid===this&&!n._isExternal)return!1;let r=!!this.placeholder.parentElement;this.placeholder.remove();let l=t._gridstackNodeOrig;if(delete t._gridstackNodeOrig,r&&l?.grid&&l.grid!==this){let e=l.grid;e.engine.removedNodes.push(l),e._triggerRemoveEvent()._triggerChangeEvent(),e.parentGridItem&&!e.engine.nodes.length&&e.opts.subGridDynamic&&e.removeAsSubGrid()}if(!n)return!1;if(r&&(this.engine.cleanupNode(n),n.grid=this),x.off(t,"drag"),s!==t?(s.remove(),t.gridstackNode=l,r&&(t=t.cloneNode(!0))):(t.remove(),this._removeDD(t)),!r)return!1;t.gridstackNode=n,n.el=t;let h=n.subGrid?.el?.gridstack;return i.copyPos(n,this._readAttr(this.placeholder)),i.removePositioningStyles(t),this._writeAttr(t,n),t.classList.add(o.itemClass,this.opts.itemClass),this.el.appendChild(t),h&&(h.parentGridItem=n,h.opts.styleInHead||h._updateStyles(!0)),this._updateContainerHeight(),this.engine.addedNodes.push(n),this._triggerAddEvent(),this._triggerChangeEvent(),this.engine.endUpdate(),this._gsEventHandler.dropped&&this._gsEventHandler.dropped({...e,type:"dropped"},l&&l.grid?l:void 0,n),window.setTimeout((()=>{n.el&&n.el.parentElement?this._prepareDragDropByNode(n):this.engine.removeNode(n),delete n.grid._isTemp})),!1})),this}_itemRemoving(e,t){let i=e?e.gridstackNode:void 0;i&&i.grid&&(t?i._isAboutToRemove=!0:delete i._isAboutToRemove,t?e.classList.add("grid-stack-item-removing"):e.classList.remove("grid-stack-item-removing"))}_setupRemoveDrop(){if(!this.opts.staticGrid&&"string"==typeof this.opts.removable){let e=document.querySelector(this.opts.removable);if(!e)return this;x.isDroppable(e)||x.droppable(e,this.opts.removableOptions).on(e,"dropover",((e,t)=>this._itemRemoving(t,!0))).on(e,"dropout",((e,t)=>this._itemRemoving(t,!1)))}return this}_prepareDragDropByNode(e){let t=e.el;const s=e.noMove||this.opts.disableDrag,o=e.noResize||this.opts.disableResize;if(this.opts.staticGrid||s&&o)return e._initDD&&(this._removeDD(t),delete e._initDD),t.classList.add("ui-draggable-disabled","ui-resizable-disabled"),this;if(!e._initDD){let s,o,n=(i,n)=>{this._gsEventHandler[i.type]&&this._gsEventHandler[i.type](i,i.target),s=this.cellWidth(),o=this.getCellHeight(!0),this._onStartMoving(t,i,n,e,s,o)},r=(i,n)=>{this._dragOrResize(t,i,n,e,s,o)},l=s=>{this.placeholder.remove(),delete e._moving,delete e._event,delete e._lastTried;let o=s.target;if(o.gridstackNode&&o.gridstackNode.grid===this){if(e.el=o,e._isAboutToRemove){let i=t.gridstackNode.grid;i._gsEventHandler[s.type]&&i._gsEventHandler[s.type](s,o),this._removeDD(t),i.engine.removedNodes.push(e),i._triggerRemoveEvent(),delete t.gridstackNode,delete e.el,t.remove()}else i.removePositioningStyles(o),e._temporaryRemoved?(i.copyPos(e,e._orig),this._writePosAttr(o,e),this.engine.addNode(e)):this._writePosAttr(o,e),this._gsEventHandler[s.type]&&this._gsEventHandler[s.type](s,o);this._extraDragRow=0,this._updateContainerHeight(),this._triggerChangeEvent(),this.engine.endUpdate()}};x.draggable(t,{start:n,stop:l,drag:r}).resizable(t,{start:n,stop:l,resize:r}),e._initDD=!0}return x.draggable(t,s?"disable":"enable").resizable(t,o?"disable":"enable"),this}_onStartMoving(e,t,i,s,o,n){this.engine.cleanNodes().beginUpdate(s),this._writePosAttr(this.placeholder,s),this.el.appendChild(this.placeholder),s.el=this.placeholder,s._lastUiPosition=i.position,s._prevYPix=i.position.top,s._moving="dragstart"===t.type,delete s._lastTried,"dropover"===t.type&&s._temporaryRemoved&&(this.engine.addNode(s),s._moving=!0),this.engine.cacheRects(o,n,this.opts.marginTop,this.opts.marginRight,this.opts.marginBottom,this.opts.marginLeft),"resizestart"===t.type&&(x.resizable(e,"option","minWidth",o*(s.minW||1)).resizable(e,"option","minHeight",n*(s.minH||1)),s.maxW&&x.resizable(e,"option","maxWidth",o*s.maxW),s.maxH&&x.resizable(e,"option","maxHeight",n*s.maxH))}_dragOrResize(e,t,s,o,n,r){let l,h={...o._orig},a=this.opts.marginLeft,d=this.opts.marginRight,p=this.opts.marginTop,g=this.opts.marginBottom,u=Math.round(.1*r),c=Math.round(.1*n);if(a=Math.min(a,c),d=Math.min(d,c),p=Math.min(p,u),g=Math.min(g,u),"drag"===t.type){if(o._temporaryRemoved)return;let t=s.position.top-o._prevYPix;o._prevYPix=s.position.top,!1!==this.opts.draggable.scroll&&i.updateScrollPosition(e,s.position,t);let l=s.position.left+(s.position.left>o._lastUiPosition.left?-d:a),u=s.position.top+(s.position.top>o._lastUiPosition.top?-g:p);h.x=Math.round(l/n),h.y=Math.round(u/r);let c=this._extraDragRow;if(this.engine.collide(o,h)){let e=this.getRow(),t=Math.max(0,h.y+o.h-e);this.opts.maxRow&&e+t>this.opts.maxRow&&(t=Math.max(0,this.opts.maxRow-e)),this._extraDragRow=t}else this._extraDragRow=0;if(this._extraDragRow!==c&&this._updateContainerHeight(),o.x===h.x&&o.y===h.y)return}else if("resize"===t.type){if(h.x<0)return;if(i.updateScrollResize(t,e,r),h.w=Math.round((s.size.width-a)/n),h.h=Math.round((s.size.height-p)/r),o.w===h.w&&o.h===h.h)return;if(o._lastTried&&o._lastTried.w===h.w&&o._lastTried.h===h.h)return;let d=s.position.left+a,g=s.position.top+p;h.x=Math.round(d/n),h.y=Math.round(g/r),l=!0}o._event=t,o._lastTried=h;let m={x:s.position.left+a,y:s.position.top+p,w:(s.size?s.size.width:o.w*n)-a-d,h:(s.size?s.size.height:o.h*r)-p-g};if(this.engine.moveNodeCheck(o,{...h,cellWidth:n,cellHeight:r,rect:m,resizing:l})){o._lastUiPosition=s.position,this.engine.cacheRects(n,r,p,d,g,a),delete o._skipDown,l&&o.subGrid&&o.subGrid.onParentResize(),this._extraDragRow=0,this._updateContainerHeight();let e=t.target;this._writePosAttr(e,o),this._gsEventHandler[t.type]&&this._gsEventHandler[t.type](t,e)}}_leave(e,t){let i=e.gridstackNode;i&&(x.off(e,"drag"),i._temporaryRemoved||(i._temporaryRemoved=!0,this.engine.removeNode(i),i.el=i._isExternal&&t?t:e,!0===this.opts.removable&&this._itemRemoving(e,!0),e._gridstackNodeOrig?(e.gridstackNode=e._gridstackNodeOrig,delete e._gridstackNodeOrig):i._isExternal&&(delete i.el,delete e.gridstackNode,this.engine.restoreInitial())))}commit(){return this.batchUpdate(!1).prototype,this}}return R.Utils=i,R.Engine=s,R.GDRev="8.3.0",t.GridStack})()));
|
|
3
|
+
//# sourceMappingURL=gridstack-all.js.map
|