25 lines
750 KiB
JavaScript
25 lines
750 KiB
JavaScript
"use strict";
|
|
/*
|
|
* ATTENTION: An "eval-source-map" devtool has been used.
|
|
* This devtool is neither made for production nor for readable output files.
|
|
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
|
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
|
* or disable the default devtool with "devtool: false".
|
|
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
|
*/
|
|
exports.id = "vendor-chunks/canvg";
|
|
exports.ids = ["vendor-chunks/canvg"];
|
|
exports.modules = {
|
|
|
|
/***/ "(ssr)/./node_modules/canvg/lib/index.cjs":
|
|
/*!******************************************!*\
|
|
!*** ./node_modules/canvg/lib/index.cjs ***!
|
|
\******************************************/
|
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
|
|
eval("\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\n__webpack_require__(/*! core-js/modules/es.object.to-string.js */ \"(ssr)/./node_modules/core-js/modules/es.object.to-string.js\");\n__webpack_require__(/*! core-js/modules/es.promise.js */ \"(ssr)/./node_modules/core-js/modules/es.promise.js\");\n__webpack_require__(/*! core-js/modules/es.reflect.delete-property.js */ \"(ssr)/./node_modules/core-js/modules/es.reflect.delete-property.js\");\nvar _regeneratorRuntime = __webpack_require__(/*! @babel/runtime/regenerator */ \"(ssr)/./node_modules/@babel/runtime/regenerator/index.js\");\nvar _asyncToGenerator = __webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ \"(ssr)/./node_modules/@babel/runtime/helpers/asyncToGenerator.js\");\n__webpack_require__(/*! core-js/modules/es.array.map.js */ \"(ssr)/./node_modules/core-js/modules/es.array.map.js\");\n__webpack_require__(/*! core-js/modules/es.parse-float.js */ \"(ssr)/./node_modules/core-js/modules/es.parse-float.js\");\n__webpack_require__(/*! core-js/modules/es.regexp.exec.js */ \"(ssr)/./node_modules/core-js/modules/es.regexp.exec.js\");\n__webpack_require__(/*! core-js/modules/es.string.match.js */ \"(ssr)/./node_modules/core-js/modules/es.string.match.js\");\n__webpack_require__(/*! core-js/modules/es.string.replace.js */ \"(ssr)/./node_modules/core-js/modules/es.string.replace.js\");\n__webpack_require__(/*! core-js/modules/es.string.starts-with.js */ \"(ssr)/./node_modules/core-js/modules/es.string.starts-with.js\");\n__webpack_require__(/*! core-js/modules/es.array.join.js */ \"(ssr)/./node_modules/core-js/modules/es.array.join.js\");\nvar _slicedToArray = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ \"(ssr)/./node_modules/@babel/runtime/helpers/slicedToArray.js\");\nvar _defineProperty = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ \"(ssr)/./node_modules/@babel/runtime/helpers/defineProperty.js\");\nvar _classCallCheck = __webpack_require__(/*! @babel/runtime/helpers/classCallCheck */ \"(ssr)/./node_modules/@babel/runtime/helpers/classCallCheck.js\");\nvar _createClass = __webpack_require__(/*! @babel/runtime/helpers/createClass */ \"(ssr)/./node_modules/@babel/runtime/helpers/createClass.js\");\n__webpack_require__(/*! core-js/modules/es.array.concat.js */ \"(ssr)/./node_modules/core-js/modules/es.array.concat.js\");\n__webpack_require__(/*! core-js/modules/es.array.every.js */ \"(ssr)/./node_modules/core-js/modules/es.array.every.js\");\n__webpack_require__(/*! core-js/modules/es.array.reduce.js */ \"(ssr)/./node_modules/core-js/modules/es.array.reduce.js\");\n__webpack_require__(/*! core-js/modules/es.string.ends-with.js */ \"(ssr)/./node_modules/core-js/modules/es.string.ends-with.js\");\n__webpack_require__(/*! core-js/modules/es.string.split.js */ \"(ssr)/./node_modules/core-js/modules/es.string.split.js\");\nvar requestAnimationFrame = __webpack_require__(/*! raf */ \"(ssr)/./node_modules/raf/index.js\");\n__webpack_require__(/*! core-js/modules/es.function.name.js */ \"(ssr)/./node_modules/core-js/modules/es.function.name.js\");\n__webpack_require__(/*! core-js/modules/es.string.trim.js */ \"(ssr)/./node_modules/core-js/modules/es.string.trim.js\");\nvar RGBColor = __webpack_require__(/*! rgbcolor */ \"(ssr)/./node_modules/rgbcolor/index.js\");\n__webpack_require__(/*! core-js/modules/es.array.for-each.js */ \"(ssr)/./node_modules/core-js/modules/es.array.for-each.js\");\n__webpack_require__(/*! core-js/modules/web.dom-collections.for-each.js */ \"(ssr)/./node_modules/core-js/modules/web.dom-collections.for-each.js\");\nvar _inherits = __webpack_require__(/*! @babel/runtime/helpers/inherits */ \"(ssr)/./node_modules/@babel/runtime/helpers/inherits.js\");\nvar _possibleConstructorReturn = __webpack_require__(/*! @babel/runtime/helpers/possibleConstructorReturn */ \"(ssr)/./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js\");\nvar _getPrototypeOf = __webpack_require__(/*! @babel/runtime/helpers/getPrototypeOf */ \"(ssr)/./node_modules/@babel/runtime/helpers/getPrototypeOf.js\");\n__webpack_require__(/*! core-js/modules/es.array.from.js */ \"(ssr)/./node_modules/core-js/modules/es.array.from.js\");\n__webpack_require__(/*! core-js/modules/es.array.includes.js */ \"(ssr)/./node_modules/core-js/modules/es.array.includes.js\");\n__webpack_require__(/*! core-js/modules/es.array.index-of.js */ \"(ssr)/./node_modules/core-js/modules/es.array.index-of.js\");\n__webpack_require__(/*! core-js/modules/es.array.some.js */ \"(ssr)/./node_modules/core-js/modules/es.array.some.js\");\n__webpack_require__(/*! core-js/modules/es.string.includes.js */ \"(ssr)/./node_modules/core-js/modules/es.string.includes.js\");\n__webpack_require__(/*! core-js/modules/es.string.iterator.js */ \"(ssr)/./node_modules/core-js/modules/es.string.iterator.js\");\nvar _toConsumableArray = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ \"(ssr)/./node_modules/@babel/runtime/helpers/toConsumableArray.js\");\n__webpack_require__(/*! core-js/modules/es.array.reverse.js */ \"(ssr)/./node_modules/core-js/modules/es.array.reverse.js\");\n__webpack_require__(/*! core-js/modules/es.number.constructor.js */ \"(ssr)/./node_modules/core-js/modules/es.number.constructor.js\");\nvar _get = __webpack_require__(/*! @babel/runtime/helpers/get */ \"(ssr)/./node_modules/@babel/runtime/helpers/get.js\");\n__webpack_require__(/*! core-js/modules/es.array.fill.js */ \"(ssr)/./node_modules/core-js/modules/es.array.fill.js\");\nvar svgPathdata = __webpack_require__(/*! svg-pathdata */ \"(ssr)/./node_modules/svg-pathdata/lib/SVGPathData.cjs\");\n__webpack_require__(/*! core-js/modules/es.regexp.to-string.js */ \"(ssr)/./node_modules/core-js/modules/es.regexp.to-string.js\");\nvar _assertThisInitialized = __webpack_require__(/*! @babel/runtime/helpers/assertThisInitialized */ \"(ssr)/./node_modules/@babel/runtime/helpers/assertThisInitialized.js\");\n__webpack_require__(/*! core-js/modules/es.array.iterator.js */ \"(ssr)/./node_modules/core-js/modules/es.array.iterator.js\");\n__webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"(ssr)/./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n__webpack_require__(/*! core-js/modules/es.map.js */ \"(ssr)/./node_modules/core-js/modules/es.map.js\");\n__webpack_require__(/*! core-js/modules/es.reflect.apply.js */ \"(ssr)/./node_modules/core-js/modules/es.reflect.apply.js\");\n__webpack_require__(/*! core-js/modules/es.reflect.get-prototype-of.js */ \"(ssr)/./node_modules/core-js/modules/es.reflect.get-prototype-of.js\");\nvar stackblurCanvas = __webpack_require__(/*! stackblur-canvas */ \"(ssr)/./node_modules/stackblur-canvas/dist/stackblur-es.js\");\n\nfunction _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }\n\nvar _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime);\nvar _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator);\nvar _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray);\nvar _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);\nvar _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck);\nvar _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass);\nvar requestAnimationFrame__default = /*#__PURE__*/_interopDefaultLegacy(requestAnimationFrame);\nvar RGBColor__default = /*#__PURE__*/_interopDefaultLegacy(RGBColor);\nvar _inherits__default = /*#__PURE__*/_interopDefaultLegacy(_inherits);\nvar _possibleConstructorReturn__default = /*#__PURE__*/_interopDefaultLegacy(_possibleConstructorReturn);\nvar _getPrototypeOf__default = /*#__PURE__*/_interopDefaultLegacy(_getPrototypeOf);\nvar _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);\nvar _get__default = /*#__PURE__*/_interopDefaultLegacy(_get);\nvar _assertThisInitialized__default = /*#__PURE__*/_interopDefaultLegacy(_assertThisInitialized);\n\n/**\r\n * Options preset for `OffscreenCanvas`.\r\n * @param config - Preset requirements.\r\n * @param config.DOMParser - XML/HTML parser from string into DOM Document.\r\n * @returns Preset object.\r\n */\nfunction offscreen() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n DOMParserFallback = _ref.DOMParser;\n\n var preset = {\n window: null,\n ignoreAnimation: true,\n ignoreMouse: true,\n DOMParser: DOMParserFallback,\n createCanvas: function createCanvas(width, height) {\n return new OffscreenCanvas(width, height);\n },\n createImage: function createImage(url) {\n return _asyncToGenerator__default[\"default\"]( /*#__PURE__*/_regeneratorRuntime__default[\"default\"].mark(function _callee() {\n var response, blob, img;\n return _regeneratorRuntime__default[\"default\"].wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _context.next = 2;\n return fetch(url);\n\n case 2:\n response = _context.sent;\n _context.next = 5;\n return response.blob();\n\n case 5:\n blob = _context.sent;\n _context.next = 8;\n return createImageBitmap(blob);\n\n case 8:\n img = _context.sent;\n return _context.abrupt(\"return\", img);\n\n case 10:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee);\n }))();\n }\n };\n\n if (typeof DOMParser !== 'undefined' || typeof DOMParserFallback === 'undefined') {\n Reflect.deleteProperty(preset, 'DOMParser');\n }\n\n return preset;\n}\n\n/**\r\n * Options preset for `node-canvas`.\r\n * @param config - Preset requirements.\r\n * @param config.DOMParser - XML/HTML parser from string into DOM Document.\r\n * @param config.canvas - `node-canvas` exports.\r\n * @param config.fetch - WHATWG-compatible `fetch` function.\r\n * @returns Preset object.\r\n */\nfunction node(_ref) {\n var DOMParser = _ref.DOMParser,\n canvas = _ref.canvas,\n fetch = _ref.fetch;\n return {\n window: null,\n ignoreAnimation: true,\n ignoreMouse: true,\n DOMParser: DOMParser,\n fetch: fetch,\n createCanvas: canvas.createCanvas,\n createImage: canvas.loadImage\n };\n}\n\nvar index = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\toffscreen: offscreen,\n\tnode: node\n});\n\n/**\r\n * HTML-safe compress white-spaces.\r\n * @param str - String to compress.\r\n * @returns String.\r\n */\nfunction compressSpaces(str) {\n return str.replace(/(?!\\u3000)\\s+/gm, ' ');\n}\n/**\r\n * HTML-safe left trim.\r\n * @param str - String to trim.\r\n * @returns String.\r\n */\n\nfunction trimLeft(str) {\n return str.replace(/^[\\n \\t]+/, '');\n}\n/**\r\n * HTML-safe right trim.\r\n * @param str - String to trim.\r\n * @returns String.\r\n */\n\nfunction trimRight(str) {\n return str.replace(/[\\n \\t]+$/, '');\n}\n/**\r\n * String to numbers array.\r\n * @param str - Numbers string.\r\n * @returns Numbers array.\r\n */\n\nfunction toNumbers(str) {\n var matches = (str || '').match(/-?(\\d+(?:\\.\\d*(?:[eE][+-]?\\d+)?)?|\\.\\d+)(?=\\D|$)/gm) || [];\n return matches.map(parseFloat);\n} // Microsoft Edge fix\n\nvar allUppercase = /^[A-Z-]+$/;\n/**\r\n * Normalize attribute name.\r\n * @param name - Attribute name.\r\n * @returns Normalized attribute name.\r\n */\n\nfunction normalizeAttributeName(name) {\n if (allUppercase.test(name)) {\n return name.toLowerCase();\n }\n\n return name;\n}\n/**\r\n * Parse external URL.\r\n * @param url - CSS url string.\r\n * @returns Parsed URL.\r\n */\n\nfunction parseExternalUrl(url) {\n // single quotes [2]\n // v double quotes [3]\n // v v no quotes [4]\n // v v v\n var urlMatch = /url\\(('([^']+)'|\"([^\"]+)\"|([^'\")]+))\\)/.exec(url) || [];\n return urlMatch[2] || urlMatch[3] || urlMatch[4];\n}\n/**\r\n * Transform floats to integers in rgb colors.\r\n * @param color - Color to normalize.\r\n * @returns Normalized color.\r\n */\n\nfunction normalizeColor(color) {\n if (!color.startsWith('rgb')) {\n return color;\n }\n\n var rgbParts = 3;\n var normalizedColor = color.replace(/\\d+(\\.\\d+)?/g, function (num, isFloat) {\n return rgbParts-- && isFloat ? String(Math.round(parseFloat(num))) : num;\n });\n return normalizedColor;\n}\n\n// slightly modified version of https://github.com/keeganstreet/specificity/blob/master/specificity.js\nvar attributeRegex = /(\\[[^\\]]+\\])/g;\nvar idRegex = /(#[^\\s+>~.[:]+)/g;\nvar classRegex = /(\\.[^\\s+>~.[:]+)/g;\nvar pseudoElementRegex = /(::[^\\s+>~.[:]+|:first-line|:first-letter|:before|:after)/gi;\nvar pseudoClassWithBracketsRegex = /(:[\\w-]+\\([^)]*\\))/gi;\nvar pseudoClassRegex = /(:[^\\s+>~.[:]+)/g;\nvar elementRegex = /([^\\s+>~.[:]+)/g;\n\nfunction findSelectorMatch(selector, regex) {\n var matches = regex.exec(selector);\n\n if (!matches) {\n return [selector, 0];\n }\n\n return [selector.replace(regex, ' '), matches.length];\n}\n/**\r\n * Measure selector specificity.\r\n * @param selector - Selector to measure.\r\n * @returns Specificity.\r\n */\n\n\nfunction getSelectorSpecificity(selector) {\n var specificity = [0, 0, 0];\n var currentSelector = selector.replace(/:not\\(([^)]*)\\)/g, ' $1 ').replace(/{[\\s\\S]*/gm, ' ');\n var delta = 0;\n\n var _findSelectorMatch = findSelectorMatch(currentSelector, attributeRegex);\n\n var _findSelectorMatch2 = _slicedToArray__default[\"default\"](_findSelectorMatch, 2);\n\n currentSelector = _findSelectorMatch2[0];\n delta = _findSelectorMatch2[1];\n specificity[1] += delta;\n\n var _findSelectorMatch3 = findSelectorMatch(currentSelector, idRegex);\n\n var _findSelectorMatch4 = _slicedToArray__default[\"default\"](_findSelectorMatch3, 2);\n\n currentSelector = _findSelectorMatch4[0];\n delta = _findSelectorMatch4[1];\n specificity[0] += delta;\n\n var _findSelectorMatch5 = findSelectorMatch(currentSelector, classRegex);\n\n var _findSelectorMatch6 = _slicedToArray__default[\"default\"](_findSelectorMatch5, 2);\n\n currentSelector = _findSelectorMatch6[0];\n delta = _findSelectorMatch6[1];\n specificity[1] += delta;\n\n var _findSelectorMatch7 = findSelectorMatch(currentSelector, pseudoElementRegex);\n\n var _findSelectorMatch8 = _slicedToArray__default[\"default\"](_findSelectorMatch7, 2);\n\n currentSelector = _findSelectorMatch8[0];\n delta = _findSelectorMatch8[1];\n specificity[2] += delta;\n\n var _findSelectorMatch9 = findSelectorMatch(currentSelector, pseudoClassWithBracketsRegex);\n\n var _findSelectorMatch10 = _slicedToArray__default[\"default\"](_findSelectorMatch9, 2);\n\n currentSelector = _findSelectorMatch10[0];\n delta = _findSelectorMatch10[1];\n specificity[1] += delta;\n\n var _findSelectorMatch11 = findSelectorMatch(currentSelector, pseudoClassRegex);\n\n var _findSelectorMatch12 = _slicedToArray__default[\"default\"](_findSelectorMatch11, 2);\n\n currentSelector = _findSelectorMatch12[0];\n delta = _findSelectorMatch12[1];\n specificity[1] += delta;\n currentSelector = currentSelector.replace(/[*\\s+>~]/g, ' ').replace(/[#.]/g, ' ');\n\n var _findSelectorMatch13 = findSelectorMatch(currentSelector, elementRegex);\n\n var _findSelectorMatch14 = _slicedToArray__default[\"default\"](_findSelectorMatch13, 2);\n\n currentSelector = _findSelectorMatch14[0];\n delta = _findSelectorMatch14[1];\n // lgtm [js/useless-assignment-to-local]\n specificity[2] += delta;\n return specificity.join('');\n}\n\nvar PSEUDO_ZERO = .00000001;\n/**\r\n * Vector magnitude.\r\n * @param v\r\n * @returns Number result.\r\n */\n\nfunction vectorMagnitude(v) {\n return Math.sqrt(Math.pow(v[0], 2) + Math.pow(v[1], 2));\n}\n/**\r\n * Ratio between two vectors.\r\n * @param u\r\n * @param v\r\n * @returns Number result.\r\n */\n\nfunction vectorsRatio(u, v) {\n return (u[0] * v[0] + u[1] * v[1]) / (vectorMagnitude(u) * vectorMagnitude(v));\n}\n/**\r\n * Angle between two vectors.\r\n * @param u\r\n * @param v\r\n * @returns Number result.\r\n */\n\nfunction vectorsAngle(u, v) {\n return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vectorsRatio(u, v));\n}\nfunction CB1(t) {\n return t * t * t;\n}\nfunction CB2(t) {\n return 3 * t * t * (1 - t);\n}\nfunction CB3(t) {\n return 3 * t * (1 - t) * (1 - t);\n}\nfunction CB4(t) {\n return (1 - t) * (1 - t) * (1 - t);\n}\nfunction QB1(t) {\n return t * t;\n}\nfunction QB2(t) {\n return 2 * t * (1 - t);\n}\nfunction QB3(t) {\n return (1 - t) * (1 - t);\n}\n\nvar Property = /*#__PURE__*/function () {\n function Property(document, name, value) {\n _classCallCheck__default[\"default\"](this, Property);\n\n this.document = document;\n this.name = name;\n this.value = value;\n this.isNormalizedColor = false;\n }\n\n _createClass__default[\"default\"](Property, [{\n key: \"split\",\n value: function split() {\n var separator = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ' ';\n var document = this.document,\n name = this.name;\n return compressSpaces(this.getString()).trim().split(separator).map(function (value) {\n return new Property(document, name, value);\n });\n }\n }, {\n key: \"hasValue\",\n value: function hasValue(zeroIsValue) {\n var value = this.value;\n return value !== null && value !== '' && (zeroIsValue || value !== 0) && typeof value !== 'undefined';\n }\n }, {\n key: \"isString\",\n value: function isString(regexp) {\n var value = this.value;\n var result = typeof value === 'string';\n\n if (!result || !regexp) {\n return result;\n }\n\n return regexp.test(value);\n }\n }, {\n key: \"isUrlDefinition\",\n value: function isUrlDefinition() {\n return this.isString(/^url\\(/);\n }\n }, {\n key: \"isPixels\",\n value: function isPixels() {\n if (!this.hasValue()) {\n return false;\n }\n\n var asString = this.getString();\n\n switch (true) {\n case asString.endsWith('px'):\n case /^[0-9]+$/.test(asString):\n return true;\n\n default:\n return false;\n }\n }\n }, {\n key: \"setValue\",\n value: function setValue(value) {\n this.value = value;\n return this;\n }\n }, {\n key: \"getValue\",\n value: function getValue(def) {\n if (typeof def === 'undefined' || this.hasValue()) {\n return this.value;\n }\n\n return def;\n }\n }, {\n key: \"getNumber\",\n value: function getNumber(def) {\n if (!this.hasValue()) {\n if (typeof def === 'undefined') {\n return 0;\n }\n\n return parseFloat(def);\n }\n\n var value = this.value;\n var n = parseFloat(value);\n\n if (this.isString(/%$/)) {\n n /= 100.0;\n }\n\n return n;\n }\n }, {\n key: \"getString\",\n value: function getString(def) {\n if (typeof def === 'undefined' || this.hasValue()) {\n return typeof this.value === 'undefined' ? '' : String(this.value);\n }\n\n return String(def);\n }\n }, {\n key: \"getColor\",\n value: function getColor(def) {\n var color = this.getString(def);\n\n if (this.isNormalizedColor) {\n return color;\n }\n\n this.isNormalizedColor = true;\n color = normalizeColor(color);\n this.value = color;\n return color;\n }\n }, {\n key: \"getDpi\",\n value: function getDpi() {\n return 96.0; // TODO: compute?\n }\n }, {\n key: \"getRem\",\n value: function getRem() {\n return this.document.rootEmSize;\n }\n }, {\n key: \"getEm\",\n value: function getEm() {\n return this.document.emSize;\n }\n }, {\n key: \"getUnits\",\n value: function getUnits() {\n return this.getString().replace(/[0-9.-]/g, '');\n }\n }, {\n key: \"getPixels\",\n value: function getPixels(axisOrIsFontSize) {\n var processPercent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n if (!this.hasValue()) {\n return 0;\n }\n\n var _ref = typeof axisOrIsFontSize === 'boolean' ? [undefined, axisOrIsFontSize] : [axisOrIsFontSize],\n _ref2 = _slicedToArray__default[\"default\"](_ref, 2),\n axis = _ref2[0],\n isFontSize = _ref2[1];\n\n var viewPort = this.document.screen.viewPort;\n\n switch (true) {\n case this.isString(/vmin$/):\n return this.getNumber() / 100.0 * Math.min(viewPort.computeSize('x'), viewPort.computeSize('y'));\n\n case this.isString(/vmax$/):\n return this.getNumber() / 100.0 * Math.max(viewPort.computeSize('x'), viewPort.computeSize('y'));\n\n case this.isString(/vw$/):\n return this.getNumber() / 100.0 * viewPort.computeSize('x');\n\n case this.isString(/vh$/):\n return this.getNumber() / 100.0 * viewPort.computeSize('y');\n\n case this.isString(/rem$/):\n return this.getNumber() * this.getRem();\n\n case this.isString(/em$/):\n return this.getNumber() * this.getEm();\n\n case this.isString(/ex$/):\n return this.getNumber() * this.getEm() / 2.0;\n\n case this.isString(/px$/):\n return this.getNumber();\n\n case this.isString(/pt$/):\n return this.getNumber() * this.getDpi() * (1.0 / 72.0);\n\n case this.isString(/pc$/):\n return this.getNumber() * 15;\n\n case this.isString(/cm$/):\n return this.getNumber() * this.getDpi() / 2.54;\n\n case this.isString(/mm$/):\n return this.getNumber() * this.getDpi() / 25.4;\n\n case this.isString(/in$/):\n return this.getNumber() * this.getDpi();\n\n case this.isString(/%$/) && isFontSize:\n return this.getNumber() * this.getEm();\n\n case this.isString(/%$/):\n return this.getNumber() * viewPort.computeSize(axis);\n\n default:\n {\n var n = this.getNumber();\n\n if (processPercent && n < 1.0) {\n return n * viewPort.computeSize(axis);\n }\n\n return n;\n }\n }\n }\n }, {\n key: \"getMilliseconds\",\n value: function getMilliseconds() {\n if (!this.hasValue()) {\n return 0;\n }\n\n if (this.isString(/ms$/)) {\n return this.getNumber();\n }\n\n return this.getNumber() * 1000;\n }\n }, {\n key: \"getRadians\",\n value: function getRadians() {\n if (!this.hasValue()) {\n return 0;\n }\n\n switch (true) {\n case this.isString(/deg$/):\n return this.getNumber() * (Math.PI / 180.0);\n\n case this.isString(/grad$/):\n return this.getNumber() * (Math.PI / 200.0);\n\n case this.isString(/rad$/):\n return this.getNumber();\n\n default:\n return this.getNumber() * (Math.PI / 180.0);\n }\n }\n }, {\n key: \"getDefinition\",\n value: function getDefinition() {\n var asString = this.getString();\n var name = /#([^)'\"]+)/.exec(asString);\n\n if (name) {\n name = name[1];\n }\n\n if (!name) {\n name = asString;\n }\n\n return this.document.definitions[name];\n }\n }, {\n key: \"getFillStyleDefinition\",\n value: function getFillStyleDefinition(element, opacity) {\n var def = this.getDefinition();\n\n if (!def) {\n return null;\n } // gradient\n\n\n if (typeof def.createGradient === 'function') {\n return def.createGradient(this.document.ctx, element, opacity);\n } // pattern\n\n\n if (typeof def.createPattern === 'function') {\n if (def.getHrefAttribute().hasValue()) {\n var patternTransform = def.getAttribute('patternTransform');\n def = def.getHrefAttribute().getDefinition();\n\n if (patternTransform.hasValue()) {\n def.getAttribute('patternTransform', true).setValue(patternTransform.value);\n }\n }\n\n return def.createPattern(this.document.ctx, element, opacity);\n }\n\n return null;\n }\n }, {\n key: \"getTextBaseline\",\n value: function getTextBaseline() {\n if (!this.hasValue()) {\n return null;\n }\n\n return Property.textBaselineMapping[this.getString()];\n }\n }, {\n key: \"addOpacity\",\n value: function addOpacity(opacity) {\n var value = this.getColor();\n var len = value.length;\n var commas = 0; // Simulate old RGBColor version, which can't parse rgba.\n\n for (var i = 0; i < len; i++) {\n if (value[i] === ',') {\n commas++;\n }\n\n if (commas === 3) {\n break;\n }\n }\n\n if (opacity.hasValue() && this.isString() && commas !== 3) {\n var color = new RGBColor__default[\"default\"](value);\n\n if (color.ok) {\n color.alpha = opacity.getNumber();\n value = color.toRGBA();\n }\n }\n\n return new Property(this.document, this.name, value);\n }\n }], [{\n key: \"empty\",\n value: function empty(document) {\n return new Property(document, 'EMPTY', '');\n }\n }]);\n\n return Property;\n}();\nProperty.textBaselineMapping = {\n 'baseline': 'alphabetic',\n 'before-edge': 'top',\n 'text-before-edge': 'top',\n 'middle': 'middle',\n 'central': 'middle',\n 'after-edge': 'bottom',\n 'text-after-edge': 'bottom',\n 'ideographic': 'ideographic',\n 'alphabetic': 'alphabetic',\n 'hanging': 'hanging',\n 'mathematical': 'alphabetic'\n};\n\nvar ViewPort = /*#__PURE__*/function () {\n function ViewPort() {\n _classCallCheck__default[\"default\"](this, ViewPort);\n\n this.viewPorts = [];\n }\n\n _createClass__default[\"default\"](ViewPort, [{\n key: \"clear\",\n value: function clear() {\n this.viewPorts = [];\n }\n }, {\n key: \"setCurrent\",\n value: function setCurrent(width, height) {\n this.viewPorts.push({\n width: width,\n height: height\n });\n }\n }, {\n key: \"removeCurrent\",\n value: function removeCurrent() {\n this.viewPorts.pop();\n }\n }, {\n key: \"getCurrent\",\n value: function getCurrent() {\n var viewPorts = this.viewPorts;\n return viewPorts[viewPorts.length - 1];\n }\n }, {\n key: \"computeSize\",\n value: function computeSize(d) {\n if (typeof d === 'number') {\n return d;\n }\n\n if (d === 'x') {\n return this.width;\n }\n\n if (d === 'y') {\n return this.height;\n }\n\n return Math.sqrt(Math.pow(this.width, 2) + Math.pow(this.height, 2)) / Math.sqrt(2);\n }\n }, {\n key: \"width\",\n get: function get() {\n return this.getCurrent().width;\n }\n }, {\n key: \"height\",\n get: function get() {\n return this.getCurrent().height;\n }\n }]);\n\n return ViewPort;\n}();\n\nvar Point = /*#__PURE__*/function () {\n function Point(x, y) {\n _classCallCheck__default[\"default\"](this, Point);\n\n this.x = x;\n this.y = y;\n }\n\n _createClass__default[\"default\"](Point, [{\n key: \"angleTo\",\n value: function angleTo(point) {\n return Math.atan2(point.y - this.y, point.x - this.x);\n }\n }, {\n key: \"applyTransform\",\n value: function applyTransform(transform) {\n var x = this.x,\n y = this.y;\n var xp = x * transform[0] + y * transform[2] + transform[4];\n var yp = x * transform[1] + y * transform[3] + transform[5];\n this.x = xp;\n this.y = yp;\n }\n }], [{\n key: \"parse\",\n value: function parse(point) {\n var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n\n var _toNumbers = toNumbers(point),\n _toNumbers2 = _slicedToArray__default[\"default\"](_toNumbers, 2),\n _toNumbers2$ = _toNumbers2[0],\n x = _toNumbers2$ === void 0 ? defaultValue : _toNumbers2$,\n _toNumbers2$2 = _toNumbers2[1],\n y = _toNumbers2$2 === void 0 ? defaultValue : _toNumbers2$2;\n\n return new Point(x, y);\n }\n }, {\n key: \"parseScale\",\n value: function parseScale(scale) {\n var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n\n var _toNumbers3 = toNumbers(scale),\n _toNumbers4 = _slicedToArray__default[\"default\"](_toNumbers3, 2),\n _toNumbers4$ = _toNumbers4[0],\n x = _toNumbers4$ === void 0 ? defaultValue : _toNumbers4$,\n _toNumbers4$2 = _toNumbers4[1],\n y = _toNumbers4$2 === void 0 ? x : _toNumbers4$2;\n\n return new Point(x, y);\n }\n }, {\n key: \"parsePath\",\n value: function parsePath(path) {\n var points = toNumbers(path);\n var len = points.length;\n var pathPoints = [];\n\n for (var i = 0; i < len; i += 2) {\n pathPoints.push(new Point(points[i], points[i + 1]));\n }\n\n return pathPoints;\n }\n }]);\n\n return Point;\n}();\n\nvar Mouse = /*#__PURE__*/function () {\n function Mouse(screen) {\n _classCallCheck__default[\"default\"](this, Mouse);\n\n this.screen = screen;\n this.working = false;\n this.events = [];\n this.eventElements = []; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\n this.onClick = this.onClick.bind(this); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\n this.onMouseMove = this.onMouseMove.bind(this);\n }\n\n _createClass__default[\"default\"](Mouse, [{\n key: \"isWorking\",\n value: function isWorking() {\n return this.working;\n }\n }, {\n key: \"start\",\n value: function start() {\n if (this.working) {\n return;\n }\n\n var screen = this.screen,\n onClick = this.onClick,\n onMouseMove = this.onMouseMove;\n var canvas = screen.ctx.canvas;\n canvas.onclick = onClick;\n canvas.onmousemove = onMouseMove;\n this.working = true;\n }\n }, {\n key: \"stop\",\n value: function stop() {\n if (!this.working) {\n return;\n }\n\n var canvas = this.screen.ctx.canvas;\n this.working = false;\n canvas.onclick = null;\n canvas.onmousemove = null;\n }\n }, {\n key: \"hasEvents\",\n value: function hasEvents() {\n return this.working && this.events.length > 0;\n }\n }, {\n key: \"runEvents\",\n value: function runEvents() {\n if (!this.working) {\n return;\n }\n\n var document = this.screen,\n events = this.events,\n eventElements = this.eventElements;\n var style = document.ctx.canvas.style;\n\n if (style) {\n style.cursor = '';\n }\n\n events.forEach(function (_ref, i) {\n var run = _ref.run;\n var element = eventElements[i];\n\n while (element) {\n run(element);\n element = element.parent;\n }\n }); // done running, clear\n\n this.events = [];\n this.eventElements = [];\n }\n }, {\n key: \"checkPath\",\n value: function checkPath(element, ctx) {\n if (!this.working || !ctx) {\n return;\n }\n\n var events = this.events,\n eventElements = this.eventElements;\n events.forEach(function (_ref2, i) {\n var x = _ref2.x,\n y = _ref2.y;\n\n if (!eventElements[i] && ctx.isPointInPath && ctx.isPointInPath(x, y)) {\n eventElements[i] = element;\n }\n });\n }\n }, {\n key: \"checkBoundingBox\",\n value: function checkBoundingBox(element, boundingBox) {\n if (!this.working || !boundingBox) {\n return;\n }\n\n var events = this.events,\n eventElements = this.eventElements;\n events.forEach(function (_ref3, i) {\n var x = _ref3.x,\n y = _ref3.y;\n\n if (!eventElements[i] && boundingBox.isPointInBox(x, y)) {\n eventElements[i] = element;\n }\n });\n }\n }, {\n key: \"mapXY\",\n value: function mapXY(x, y) {\n var _this$screen = this.screen,\n window = _this$screen.window,\n ctx = _this$screen.ctx;\n var point = new Point(x, y);\n var element = ctx.canvas;\n\n while (element) {\n point.x -= element.offsetLeft;\n point.y -= element.offsetTop;\n element = element.offsetParent;\n }\n\n if (window.scrollX) {\n point.x += window.scrollX;\n }\n\n if (window.scrollY) {\n point.y += window.scrollY;\n }\n\n return point;\n }\n }, {\n key: \"onClick\",\n value: function onClick(event) {\n var _this$mapXY = this.mapXY(event.clientX, event.clientY),\n x = _this$mapXY.x,\n y = _this$mapXY.y;\n\n this.events.push({\n type: 'onclick',\n x: x,\n y: y,\n run: function run(eventTarget) {\n if (eventTarget.onClick) {\n eventTarget.onClick();\n }\n }\n });\n }\n }, {\n key: \"onMouseMove\",\n value: function onMouseMove(event) {\n var _this$mapXY2 = this.mapXY(event.clientX, event.clientY),\n x = _this$mapXY2.x,\n y = _this$mapXY2.y;\n\n this.events.push({\n type: 'onmousemove',\n x: x,\n y: y,\n run: function run(eventTarget) {\n if (eventTarget.onMouseMove) {\n eventTarget.onMouseMove();\n }\n }\n });\n }\n }]);\n\n return Mouse;\n}();\n\nvar defaultWindow = typeof window !== 'undefined' ? window : null;\nvar defaultFetch$1 = typeof fetch !== 'undefined' ? fetch.bind(undefined) // `fetch` depends on context: `someObject.fetch(...)` will throw error.\n: null;\n\nvar Screen = /*#__PURE__*/function () {\n function Screen(ctx) {\n var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n _ref$fetch = _ref.fetch,\n fetch = _ref$fetch === void 0 ? defaultFetch$1 : _ref$fetch,\n _ref$window = _ref.window,\n window = _ref$window === void 0 ? defaultWindow : _ref$window;\n\n _classCallCheck__default[\"default\"](this, Screen);\n\n this.ctx = ctx;\n this.FRAMERATE = 30;\n this.MAX_VIRTUAL_PIXELS = 30000;\n this.CLIENT_WIDTH = 800;\n this.CLIENT_HEIGHT = 600;\n this.viewPort = new ViewPort();\n this.mouse = new Mouse(this);\n this.animations = [];\n this.waits = [];\n this.frameDuration = 0;\n this.isReadyLock = false;\n this.isFirstRender = true;\n this.intervalId = null;\n this.window = window;\n this.fetch = fetch;\n }\n\n _createClass__default[\"default\"](Screen, [{\n key: \"wait\",\n value: function wait(checker) {\n this.waits.push(checker);\n }\n }, {\n key: \"ready\",\n value: function ready() {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n if (!this.readyPromise) {\n return Promise.resolve();\n }\n\n return this.readyPromise;\n }\n }, {\n key: \"isReady\",\n value: function isReady() {\n if (this.isReadyLock) {\n return true;\n }\n\n var isReadyLock = this.waits.every(function (_) {\n return _();\n });\n\n if (isReadyLock) {\n this.waits = [];\n\n if (this.resolveReady) {\n this.resolveReady();\n }\n }\n\n this.isReadyLock = isReadyLock;\n return isReadyLock;\n }\n }, {\n key: \"setDefaults\",\n value: function setDefaults(ctx) {\n // initial values and defaults\n ctx.strokeStyle = 'rgba(0,0,0,0)';\n ctx.lineCap = 'butt';\n ctx.lineJoin = 'miter';\n ctx.miterLimit = 4;\n }\n }, {\n key: \"setViewBox\",\n value: function setViewBox(_ref2) {\n var document = _ref2.document,\n ctx = _ref2.ctx,\n aspectRatio = _ref2.aspectRatio,\n width = _ref2.width,\n desiredWidth = _ref2.desiredWidth,\n height = _ref2.height,\n desiredHeight = _ref2.desiredHeight,\n _ref2$minX = _ref2.minX,\n minX = _ref2$minX === void 0 ? 0 : _ref2$minX,\n _ref2$minY = _ref2.minY,\n minY = _ref2$minY === void 0 ? 0 : _ref2$minY,\n refX = _ref2.refX,\n refY = _ref2.refY,\n _ref2$clip = _ref2.clip,\n clip = _ref2$clip === void 0 ? false : _ref2$clip,\n _ref2$clipX = _ref2.clipX,\n clipX = _ref2$clipX === void 0 ? 0 : _ref2$clipX,\n _ref2$clipY = _ref2.clipY,\n clipY = _ref2$clipY === void 0 ? 0 : _ref2$clipY;\n // aspect ratio - http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute\n var cleanAspectRatio = compressSpaces(aspectRatio).replace(/^defer\\s/, ''); // ignore defer\n\n var _cleanAspectRatio$spl = cleanAspectRatio.split(' '),\n _cleanAspectRatio$spl2 = _slicedToArray__default[\"default\"](_cleanAspectRatio$spl, 2),\n aspectRatioAlign = _cleanAspectRatio$spl2[0],\n aspectRatioMeetOrSlice = _cleanAspectRatio$spl2[1];\n\n var align = aspectRatioAlign || 'xMidYMid';\n var meetOrSlice = aspectRatioMeetOrSlice || 'meet'; // calculate scale\n\n var scaleX = width / desiredWidth;\n var scaleY = height / desiredHeight;\n var scaleMin = Math.min(scaleX, scaleY);\n var scaleMax = Math.max(scaleX, scaleY);\n var finalDesiredWidth = desiredWidth;\n var finalDesiredHeight = desiredHeight;\n\n if (meetOrSlice === 'meet') {\n finalDesiredWidth *= scaleMin;\n finalDesiredHeight *= scaleMin;\n }\n\n if (meetOrSlice === 'slice') {\n finalDesiredWidth *= scaleMax;\n finalDesiredHeight *= scaleMax;\n }\n\n var refXProp = new Property(document, 'refX', refX);\n var refYProp = new Property(document, 'refY', refY);\n var hasRefs = refXProp.hasValue() && refYProp.hasValue();\n\n if (hasRefs) {\n ctx.translate(-scaleMin * refXProp.getPixels('x'), -scaleMin * refYProp.getPixels('y'));\n }\n\n if (clip) {\n var scaledClipX = scaleMin * clipX;\n var scaledClipY = scaleMin * clipY;\n ctx.beginPath();\n ctx.moveTo(scaledClipX, scaledClipY);\n ctx.lineTo(width, scaledClipY);\n ctx.lineTo(width, height);\n ctx.lineTo(scaledClipX, height);\n ctx.closePath();\n ctx.clip();\n }\n\n if (!hasRefs) {\n var isMeetMinY = meetOrSlice === 'meet' && scaleMin === scaleY;\n var isSliceMaxY = meetOrSlice === 'slice' && scaleMax === scaleY;\n var isMeetMinX = meetOrSlice === 'meet' && scaleMin === scaleX;\n var isSliceMaxX = meetOrSlice === 'slice' && scaleMax === scaleX;\n\n if (align.startsWith('xMid') && (isMeetMinY || isSliceMaxY)) {\n ctx.translate(width / 2.0 - finalDesiredWidth / 2.0, 0);\n }\n\n if (align.endsWith('YMid') && (isMeetMinX || isSliceMaxX)) {\n ctx.translate(0, height / 2.0 - finalDesiredHeight / 2.0);\n }\n\n if (align.startsWith('xMax') && (isMeetMinY || isSliceMaxY)) {\n ctx.translate(width - finalDesiredWidth, 0);\n }\n\n if (align.endsWith('YMax') && (isMeetMinX || isSliceMaxX)) {\n ctx.translate(0, height - finalDesiredHeight);\n }\n } // scale\n\n\n switch (true) {\n case align === 'none':\n ctx.scale(scaleX, scaleY);\n break;\n\n case meetOrSlice === 'meet':\n ctx.scale(scaleMin, scaleMin);\n break;\n\n case meetOrSlice === 'slice':\n ctx.scale(scaleMax, scaleMax);\n break;\n } // translate\n\n\n ctx.translate(-minX, -minY);\n }\n }, {\n key: \"start\",\n value: function start(element) {\n var _this = this;\n\n var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n _ref3$enableRedraw = _ref3.enableRedraw,\n enableRedraw = _ref3$enableRedraw === void 0 ? false : _ref3$enableRedraw,\n _ref3$ignoreMouse = _ref3.ignoreMouse,\n ignoreMouse = _ref3$ignoreMouse === void 0 ? false : _ref3$ignoreMouse,\n _ref3$ignoreAnimation = _ref3.ignoreAnimation,\n ignoreAnimation = _ref3$ignoreAnimation === void 0 ? false : _ref3$ignoreAnimation,\n _ref3$ignoreDimension = _ref3.ignoreDimensions,\n ignoreDimensions = _ref3$ignoreDimension === void 0 ? false : _ref3$ignoreDimension,\n _ref3$ignoreClear = _ref3.ignoreClear,\n ignoreClear = _ref3$ignoreClear === void 0 ? false : _ref3$ignoreClear,\n forceRedraw = _ref3.forceRedraw,\n scaleWidth = _ref3.scaleWidth,\n scaleHeight = _ref3.scaleHeight,\n offsetX = _ref3.offsetX,\n offsetY = _ref3.offsetY;\n\n var FRAMERATE = this.FRAMERATE,\n mouse = this.mouse;\n var frameDuration = 1000 / FRAMERATE;\n this.frameDuration = frameDuration;\n this.readyPromise = new Promise(function (resolve) {\n _this.resolveReady = resolve;\n });\n\n if (this.isReady()) {\n this.render(element, ignoreDimensions, ignoreClear, scaleWidth, scaleHeight, offsetX, offsetY);\n }\n\n if (!enableRedraw) {\n return;\n }\n\n var now = Date.now();\n var then = now;\n var delta = 0;\n\n var tick = function tick() {\n now = Date.now();\n delta = now - then;\n\n if (delta >= frameDuration) {\n then = now - delta % frameDuration;\n\n if (_this.shouldUpdate(ignoreAnimation, forceRedraw)) {\n _this.render(element, ignoreDimensions, ignoreClear, scaleWidth, scaleHeight, offsetX, offsetY);\n\n mouse.runEvents();\n }\n }\n\n _this.intervalId = requestAnimationFrame__default[\"default\"](tick);\n };\n\n if (!ignoreMouse) {\n mouse.start();\n }\n\n this.intervalId = requestAnimationFrame__default[\"default\"](tick);\n }\n }, {\n key: \"stop\",\n value: function stop() {\n if (this.intervalId) {\n requestAnimationFrame__default[\"default\"].cancel(this.intervalId);\n this.intervalId = null;\n }\n\n this.mouse.stop();\n }\n }, {\n key: \"shouldUpdate\",\n value: function shouldUpdate(ignoreAnimation, forceRedraw) {\n // need update from animations?\n if (!ignoreAnimation) {\n var frameDuration = this.frameDuration;\n var shouldUpdate = this.animations.reduce(function (shouldUpdate, animation) {\n return animation.update(frameDuration) || shouldUpdate;\n }, false);\n\n if (shouldUpdate) {\n return true;\n }\n } // need update from redraw?\n\n\n if (typeof forceRedraw === 'function' && forceRedraw()) {\n return true;\n }\n\n if (!this.isReadyLock && this.isReady()) {\n return true;\n } // need update from mouse events?\n\n\n if (this.mouse.hasEvents()) {\n return true;\n }\n\n return false;\n }\n }, {\n key: \"render\",\n value: function render(element, ignoreDimensions, ignoreClear, scaleWidth, scaleHeight, offsetX, offsetY) {\n var CLIENT_WIDTH = this.CLIENT_WIDTH,\n CLIENT_HEIGHT = this.CLIENT_HEIGHT,\n viewPort = this.viewPort,\n ctx = this.ctx,\n isFirstRender = this.isFirstRender;\n var canvas = ctx.canvas;\n viewPort.clear();\n\n if (canvas.width && canvas.height) {\n viewPort.setCurrent(canvas.width, canvas.height);\n } else {\n viewPort.setCurrent(CLIENT_WIDTH, CLIENT_HEIGHT);\n }\n\n var widthStyle = element.getStyle('width');\n var heightStyle = element.getStyle('height');\n\n if (!ignoreDimensions && (isFirstRender || typeof scaleWidth !== 'number' && typeof scaleHeight !== 'number')) {\n // set canvas size\n if (widthStyle.hasValue()) {\n canvas.width = widthStyle.getPixels('x');\n\n if (canvas.style) {\n canvas.style.width = \"\".concat(canvas.width, \"px\");\n }\n }\n\n if (heightStyle.hasValue()) {\n canvas.height = heightStyle.getPixels('y');\n\n if (canvas.style) {\n canvas.style.height = \"\".concat(canvas.height, \"px\");\n }\n }\n }\n\n var cWidth = canvas.clientWidth || canvas.width;\n var cHeight = canvas.clientHeight || canvas.height;\n\n if (ignoreDimensions && widthStyle.hasValue() && heightStyle.hasValue()) {\n cWidth = widthStyle.getPixels('x');\n cHeight = heightStyle.getPixels('y');\n }\n\n viewPort.setCurrent(cWidth, cHeight);\n\n if (typeof offsetX === 'number') {\n element.getAttribute('x', true).setValue(offsetX);\n }\n\n if (typeof offsetY === 'number') {\n element.getAttribute('y', true).setValue(offsetY);\n }\n\n if (typeof scaleWidth === 'number' || typeof scaleHeight === 'number') {\n var viewBox = toNumbers(element.getAttribute('viewBox').getString());\n var xRatio = 0;\n var yRatio = 0;\n\n if (typeof scaleWidth === 'number') {\n var _widthStyle = element.getStyle('width');\n\n if (_widthStyle.hasValue()) {\n xRatio = _widthStyle.getPixels('x') / scaleWidth;\n } else if (!isNaN(viewBox[2])) {\n xRatio = viewBox[2] / scaleWidth;\n }\n }\n\n if (typeof scaleHeight === 'number') {\n var _heightStyle = element.getStyle('height');\n\n if (_heightStyle.hasValue()) {\n yRatio = _heightStyle.getPixels('y') / scaleHeight;\n } else if (!isNaN(viewBox[3])) {\n yRatio = viewBox[3] / scaleHeight;\n }\n }\n\n if (!xRatio) {\n xRatio = yRatio;\n }\n\n if (!yRatio) {\n yRatio = xRatio;\n }\n\n element.getAttribute('width', true).setValue(scaleWidth);\n element.getAttribute('height', true).setValue(scaleHeight);\n var transformStyle = element.getStyle('transform', true, true);\n transformStyle.setValue(\"\".concat(transformStyle.getString(), \" scale(\").concat(1.0 / xRatio, \", \").concat(1.0 / yRatio, \")\"));\n } // clear and render\n\n\n if (!ignoreClear) {\n ctx.clearRect(0, 0, cWidth, cHeight);\n }\n\n element.render(ctx);\n\n if (isFirstRender) {\n this.isFirstRender = false;\n }\n }\n }]);\n\n return Screen;\n}();\nScreen.defaultWindow = defaultWindow;\nScreen.defaultFetch = defaultFetch$1;\n\nvar defaultFetch = Screen.defaultFetch;\nvar DefaultDOMParser = typeof DOMParser !== 'undefined' ? DOMParser : null;\n\nvar Parser = /*#__PURE__*/function () {\n function Parser() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n _ref$fetch = _ref.fetch,\n fetch = _ref$fetch === void 0 ? defaultFetch : _ref$fetch,\n _ref$DOMParser = _ref.DOMParser,\n DOMParser = _ref$DOMParser === void 0 ? DefaultDOMParser : _ref$DOMParser;\n\n _classCallCheck__default[\"default\"](this, Parser);\n\n this.fetch = fetch;\n this.DOMParser = DOMParser;\n }\n\n _createClass__default[\"default\"](Parser, [{\n key: \"parse\",\n value: function () {\n var _parse = _asyncToGenerator__default[\"default\"]( /*#__PURE__*/_regeneratorRuntime__default[\"default\"].mark(function _callee(resource) {\n return _regeneratorRuntime__default[\"default\"].wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n if (!resource.startsWith('<')) {\n _context.next = 2;\n break;\n }\n\n return _context.abrupt(\"return\", this.parseFromString(resource));\n\n case 2:\n return _context.abrupt(\"return\", this.load(resource));\n\n case 3:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function parse(_x) {\n return _parse.apply(this, arguments);\n }\n\n return parse;\n }()\n }, {\n key: \"parseFromString\",\n value: function parseFromString(xml) {\n var parser = new this.DOMParser();\n\n try {\n return this.checkDocument(parser.parseFromString(xml, 'image/svg+xml'));\n } catch (err) {\n return this.checkDocument(parser.parseFromString(xml, 'text/xml'));\n }\n }\n }, {\n key: \"checkDocument\",\n value: function checkDocument(document) {\n var parserError = document.getElementsByTagName('parsererror')[0];\n\n if (parserError) {\n throw new Error(parserError.textContent);\n }\n\n return document;\n }\n }, {\n key: \"load\",\n value: function () {\n var _load = _asyncToGenerator__default[\"default\"]( /*#__PURE__*/_regeneratorRuntime__default[\"default\"].mark(function _callee2(url) {\n var response, xml;\n return _regeneratorRuntime__default[\"default\"].wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _context2.next = 2;\n return this.fetch(url);\n\n case 2:\n response = _context2.sent;\n _context2.next = 5;\n return response.text();\n\n case 5:\n xml = _context2.sent;\n return _context2.abrupt(\"return\", this.parseFromString(xml));\n\n case 7:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function load(_x2) {\n return _load.apply(this, arguments);\n }\n\n return load;\n }()\n }]);\n\n return Parser;\n}();\n\nvar Translate = /*#__PURE__*/function () {\n function Translate(_, point) {\n _classCallCheck__default[\"default\"](this, Translate);\n\n this.type = 'translate';\n this.point = null;\n this.point = Point.parse(point);\n }\n\n _createClass__default[\"default\"](Translate, [{\n key: \"apply\",\n value: function apply(ctx) {\n var _this$point = this.point,\n x = _this$point.x,\n y = _this$point.y;\n ctx.translate(x || 0.0, y || 0.0);\n }\n }, {\n key: \"unapply\",\n value: function unapply(ctx) {\n var _this$point2 = this.point,\n x = _this$point2.x,\n y = _this$point2.y;\n ctx.translate(-1.0 * x || 0.0, -1.0 * y || 0.0);\n }\n }, {\n key: \"applyToPoint\",\n value: function applyToPoint(point) {\n var _this$point3 = this.point,\n x = _this$point3.x,\n y = _this$point3.y;\n point.applyTransform([1, 0, 0, 1, x || 0.0, y || 0.0]);\n }\n }]);\n\n return Translate;\n}();\n\nvar Rotate = /*#__PURE__*/function () {\n function Rotate(document, rotate, transformOrigin) {\n _classCallCheck__default[\"default\"](this, Rotate);\n\n this.type = 'rotate';\n this.angle = null;\n this.originX = null;\n this.originY = null;\n this.cx = 0;\n this.cy = 0;\n var numbers = toNumbers(rotate);\n this.angle = new Property(document, 'angle', numbers[0]);\n this.originX = transformOrigin[0];\n this.originY = transformOrigin[1];\n this.cx = numbers[1] || 0;\n this.cy = numbers[2] || 0;\n }\n\n _createClass__default[\"default\"](Rotate, [{\n key: \"apply\",\n value: function apply(ctx) {\n var cx = this.cx,\n cy = this.cy,\n originX = this.originX,\n originY = this.originY,\n angle = this.angle;\n var tx = cx + originX.getPixels('x');\n var ty = cy + originY.getPixels('y');\n ctx.translate(tx, ty);\n ctx.rotate(angle.getRadians());\n ctx.translate(-tx, -ty);\n }\n }, {\n key: \"unapply\",\n value: function unapply(ctx) {\n var cx = this.cx,\n cy = this.cy,\n originX = this.originX,\n originY = this.originY,\n angle = this.angle;\n var tx = cx + originX.getPixels('x');\n var ty = cy + originY.getPixels('y');\n ctx.translate(tx, ty);\n ctx.rotate(-1.0 * angle.getRadians());\n ctx.translate(-tx, -ty);\n }\n }, {\n key: \"applyToPoint\",\n value: function applyToPoint(point) {\n var cx = this.cx,\n cy = this.cy,\n angle = this.angle;\n var rad = angle.getRadians();\n point.applyTransform([1, 0, 0, 1, cx || 0.0, cy || 0.0 // this.p.y\n ]);\n point.applyTransform([Math.cos(rad), Math.sin(rad), -Math.sin(rad), Math.cos(rad), 0, 0]);\n point.applyTransform([1, 0, 0, 1, -cx || 0.0, -cy || 0.0 // -this.p.y\n ]);\n }\n }]);\n\n return Rotate;\n}();\n\nvar Scale = /*#__PURE__*/function () {\n function Scale(_, scale, transformOrigin) {\n _classCallCheck__default[\"default\"](this, Scale);\n\n this.type = 'scale';\n this.scale = null;\n this.originX = null;\n this.originY = null;\n var scaleSize = Point.parseScale(scale); // Workaround for node-canvas\n\n if (scaleSize.x === 0 || scaleSize.y === 0) {\n scaleSize.x = PSEUDO_ZERO;\n scaleSize.y = PSEUDO_ZERO;\n }\n\n this.scale = scaleSize;\n this.originX = transformOrigin[0];\n this.originY = transformOrigin[1];\n }\n\n _createClass__default[\"default\"](Scale, [{\n key: \"apply\",\n value: function apply(ctx) {\n var _this$scale = this.scale,\n x = _this$scale.x,\n y = _this$scale.y,\n originX = this.originX,\n originY = this.originY;\n var tx = originX.getPixels('x');\n var ty = originY.getPixels('y');\n ctx.translate(tx, ty);\n ctx.scale(x, y || x);\n ctx.translate(-tx, -ty);\n }\n }, {\n key: \"unapply\",\n value: function unapply(ctx) {\n var _this$scale2 = this.scale,\n x = _this$scale2.x,\n y = _this$scale2.y,\n originX = this.originX,\n originY = this.originY;\n var tx = originX.getPixels('x');\n var ty = originY.getPixels('y');\n ctx.translate(tx, ty);\n ctx.scale(1.0 / x, 1.0 / y || x);\n ctx.translate(-tx, -ty);\n }\n }, {\n key: \"applyToPoint\",\n value: function applyToPoint(point) {\n var _this$scale3 = this.scale,\n x = _this$scale3.x,\n y = _this$scale3.y;\n point.applyTransform([x || 0.0, 0, 0, y || 0.0, 0, 0]);\n }\n }]);\n\n return Scale;\n}();\n\nvar Matrix = /*#__PURE__*/function () {\n function Matrix(_, matrix, transformOrigin) {\n _classCallCheck__default[\"default\"](this, Matrix);\n\n this.type = 'matrix';\n this.matrix = [];\n this.originX = null;\n this.originY = null;\n this.matrix = toNumbers(matrix);\n this.originX = transformOrigin[0];\n this.originY = transformOrigin[1];\n }\n\n _createClass__default[\"default\"](Matrix, [{\n key: \"apply\",\n value: function apply(ctx) {\n var originX = this.originX,\n originY = this.originY,\n matrix = this.matrix;\n var tx = originX.getPixels('x');\n var ty = originY.getPixels('y');\n ctx.translate(tx, ty);\n ctx.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);\n ctx.translate(-tx, -ty);\n }\n }, {\n key: \"unapply\",\n value: function unapply(ctx) {\n var originX = this.originX,\n originY = this.originY,\n matrix = this.matrix;\n var a = matrix[0];\n var b = matrix[2];\n var c = matrix[4];\n var d = matrix[1];\n var e = matrix[3];\n var f = matrix[5];\n var g = 0.0;\n var h = 0.0;\n var i = 1.0;\n var det = 1 / (a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g));\n var tx = originX.getPixels('x');\n var ty = originY.getPixels('y');\n ctx.translate(tx, ty);\n ctx.transform(det * (e * i - f * h), det * (f * g - d * i), det * (c * h - b * i), det * (a * i - c * g), det * (b * f - c * e), det * (c * d - a * f));\n ctx.translate(-tx, -ty);\n }\n }, {\n key: \"applyToPoint\",\n value: function applyToPoint(point) {\n point.applyTransform(this.matrix);\n }\n }]);\n\n return Matrix;\n}();\n\nfunction _createSuper$M(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$M(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$M() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar Skew = /*#__PURE__*/function (_Matrix) {\n _inherits__default[\"default\"](Skew, _Matrix);\n\n var _super = _createSuper$M(Skew);\n\n function Skew(document, skew, transformOrigin) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, Skew);\n\n _this = _super.call(this, document, skew, transformOrigin);\n _this.type = 'skew';\n _this.angle = null;\n _this.angle = new Property(document, 'angle', skew);\n return _this;\n }\n\n return Skew;\n}(Matrix);\n\nfunction _createSuper$L(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$L(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$L() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar SkewX = /*#__PURE__*/function (_Skew) {\n _inherits__default[\"default\"](SkewX, _Skew);\n\n var _super = _createSuper$L(SkewX);\n\n function SkewX(document, skew, transformOrigin) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, SkewX);\n\n _this = _super.call(this, document, skew, transformOrigin);\n _this.type = 'skewX';\n _this.matrix = [1, 0, Math.tan(_this.angle.getRadians()), 1, 0, 0];\n return _this;\n }\n\n return SkewX;\n}(Skew);\n\nfunction _createSuper$K(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$K(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$K() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar SkewY = /*#__PURE__*/function (_Skew) {\n _inherits__default[\"default\"](SkewY, _Skew);\n\n var _super = _createSuper$K(SkewY);\n\n function SkewY(document, skew, transformOrigin) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, SkewY);\n\n _this = _super.call(this, document, skew, transformOrigin);\n _this.type = 'skewY';\n _this.matrix = [1, Math.tan(_this.angle.getRadians()), 0, 1, 0, 0];\n return _this;\n }\n\n return SkewY;\n}(Skew);\n\nfunction parseTransforms(transform) {\n return compressSpaces(transform).trim().replace(/\\)([a-zA-Z])/g, ') $1').replace(/\\)(\\s?,\\s?)/g, ') ').split(/\\s(?=[a-z])/);\n}\n\nfunction parseTransform(transform) {\n var _transform$split = transform.split('('),\n _transform$split2 = _slicedToArray__default[\"default\"](_transform$split, 2),\n type = _transform$split2[0],\n value = _transform$split2[1];\n\n return [type.trim(), value.trim().replace(')', '')];\n}\n\nvar Transform = /*#__PURE__*/function () {\n function Transform(document, transform, transformOrigin) {\n var _this = this;\n\n _classCallCheck__default[\"default\"](this, Transform);\n\n this.document = document;\n this.transforms = [];\n var data = parseTransforms(transform);\n data.forEach(function (transform) {\n if (transform === 'none') {\n return;\n }\n\n var _parseTransform = parseTransform(transform),\n _parseTransform2 = _slicedToArray__default[\"default\"](_parseTransform, 2),\n type = _parseTransform2[0],\n value = _parseTransform2[1];\n\n var TransformType = Transform.transformTypes[type];\n\n if (typeof TransformType !== 'undefined') {\n _this.transforms.push(new TransformType(_this.document, value, transformOrigin));\n }\n });\n }\n\n _createClass__default[\"default\"](Transform, [{\n key: \"apply\",\n value: function apply(ctx) {\n var transforms = this.transforms;\n var len = transforms.length;\n\n for (var i = 0; i < len; i++) {\n transforms[i].apply(ctx);\n }\n }\n }, {\n key: \"unapply\",\n value: function unapply(ctx) {\n var transforms = this.transforms;\n var len = transforms.length;\n\n for (var i = len - 1; i >= 0; i--) {\n transforms[i].unapply(ctx);\n }\n } // TODO: applyToPoint unused ... remove?\n\n }, {\n key: \"applyToPoint\",\n value: function applyToPoint(point) {\n var transforms = this.transforms;\n var len = transforms.length;\n\n for (var i = 0; i < len; i++) {\n transforms[i].applyToPoint(point);\n }\n }\n }], [{\n key: \"fromElement\",\n value: function fromElement(document, element) {\n var transformStyle = element.getStyle('transform', false, true);\n\n var _element$getStyle$spl = element.getStyle('transform-origin', false, true).split(),\n _element$getStyle$spl2 = _slicedToArray__default[\"default\"](_element$getStyle$spl, 2),\n transformOriginXProperty = _element$getStyle$spl2[0],\n _element$getStyle$spl3 = _element$getStyle$spl2[1],\n transformOriginYProperty = _element$getStyle$spl3 === void 0 ? transformOriginXProperty : _element$getStyle$spl3;\n\n var transformOrigin = [transformOriginXProperty, transformOriginYProperty];\n\n if (transformStyle.hasValue()) {\n return new Transform(document, transformStyle.getString(), transformOrigin);\n }\n\n return null;\n }\n }]);\n\n return Transform;\n}();\nTransform.transformTypes = {\n translate: Translate,\n rotate: Rotate,\n scale: Scale,\n matrix: Matrix,\n skewX: SkewX,\n skewY: SkewY\n};\n\nvar Element = /*#__PURE__*/function () {\n function Element(document, node) {\n var _this = this;\n\n var captureTextNodes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n _classCallCheck__default[\"default\"](this, Element);\n\n this.document = document;\n this.node = node;\n this.captureTextNodes = captureTextNodes;\n this.attributes = Object.create(null);\n this.styles = Object.create(null);\n this.stylesSpecificity = Object.create(null);\n this.animationFrozen = false;\n this.animationFrozenValue = '';\n this.parent = null;\n this.children = [];\n\n if (!node || node.nodeType !== 1) {\n // ELEMENT_NODE\n return;\n } // add attributes\n\n\n Array.from(node.attributes).forEach(function (attribute) {\n var nodeName = normalizeAttributeName(attribute.nodeName);\n _this.attributes[nodeName] = new Property(document, nodeName, attribute.value);\n });\n this.addStylesFromStyleDefinition(); // add inline styles\n\n if (this.getAttribute('style').hasValue()) {\n var styles = this.getAttribute('style').getString().split(';').map(function (_) {\n return _.trim();\n });\n styles.forEach(function (style) {\n if (!style) {\n return;\n }\n\n var _style$split$map = style.split(':').map(function (_) {\n return _.trim();\n }),\n _style$split$map2 = _slicedToArray__default[\"default\"](_style$split$map, 2),\n name = _style$split$map2[0],\n value = _style$split$map2[1];\n\n _this.styles[name] = new Property(document, name, value);\n });\n }\n\n var definitions = document.definitions;\n var id = this.getAttribute('id'); // add id\n\n if (id.hasValue()) {\n if (!definitions[id.getString()]) {\n definitions[id.getString()] = this;\n }\n }\n\n Array.from(node.childNodes).forEach(function (childNode) {\n if (childNode.nodeType === 1) {\n _this.addChild(childNode); // ELEMENT_NODE\n\n } else if (captureTextNodes && (childNode.nodeType === 3 || childNode.nodeType === 4)) {\n var textNode = document.createTextNode(childNode);\n\n if (textNode.getText().length > 0) {\n _this.addChild(textNode); // TEXT_NODE\n\n }\n }\n });\n }\n\n _createClass__default[\"default\"](Element, [{\n key: \"getAttribute\",\n value: function getAttribute(name) {\n var createIfNotExists = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n var attr = this.attributes[name];\n\n if (!attr && createIfNotExists) {\n var _attr = new Property(this.document, name, '');\n\n this.attributes[name] = _attr;\n return _attr;\n }\n\n return attr || Property.empty(this.document);\n }\n }, {\n key: \"getHrefAttribute\",\n value: function getHrefAttribute() {\n for (var key in this.attributes) {\n if (key === 'href' || key.endsWith(':href')) {\n return this.attributes[key];\n }\n }\n\n return Property.empty(this.document);\n }\n }, {\n key: \"getStyle\",\n value: function getStyle(name) {\n var createIfNotExists = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n var skipAncestors = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n var style = this.styles[name];\n\n if (style) {\n return style;\n }\n\n var attr = this.getAttribute(name);\n\n if (attr !== null && attr !== void 0 && attr.hasValue()) {\n this.styles[name] = attr; // move up to me to cache\n\n return attr;\n }\n\n if (!skipAncestors) {\n var parent = this.parent;\n\n if (parent) {\n var parentStyle = parent.getStyle(name);\n\n if (parentStyle !== null && parentStyle !== void 0 && parentStyle.hasValue()) {\n return parentStyle;\n }\n }\n }\n\n if (createIfNotExists) {\n var _style = new Property(this.document, name, '');\n\n this.styles[name] = _style;\n return _style;\n }\n\n return style || Property.empty(this.document);\n }\n }, {\n key: \"render\",\n value: function render(ctx) {\n // don't render display=none\n // don't render visibility=hidden\n if (this.getStyle('display').getString() === 'none' || this.getStyle('visibility').getString() === 'hidden') {\n return;\n }\n\n ctx.save();\n\n if (this.getStyle('mask').hasValue()) {\n // mask\n var mask = this.getStyle('mask').getDefinition();\n\n if (mask) {\n this.applyEffects(ctx);\n mask.apply(ctx, this);\n }\n } else if (this.getStyle('filter').getValue('none') !== 'none') {\n // filter\n var filter = this.getStyle('filter').getDefinition();\n\n if (filter) {\n this.applyEffects(ctx);\n filter.apply(ctx, this);\n }\n } else {\n this.setContext(ctx);\n this.renderChildren(ctx);\n this.clearContext(ctx);\n }\n\n ctx.restore();\n }\n }, {\n key: \"setContext\",\n value: function setContext(_) {// NO RENDER\n }\n }, {\n key: \"applyEffects\",\n value: function applyEffects(ctx) {\n // transform\n var transform = Transform.fromElement(this.document, this);\n\n if (transform) {\n transform.apply(ctx);\n } // clip\n\n\n var clipPathStyleProp = this.getStyle('clip-path', false, true);\n\n if (clipPathStyleProp.hasValue()) {\n var clip = clipPathStyleProp.getDefinition();\n\n if (clip) {\n clip.apply(ctx);\n }\n }\n }\n }, {\n key: \"clearContext\",\n value: function clearContext(_) {// NO RENDER\n }\n }, {\n key: \"renderChildren\",\n value: function renderChildren(ctx) {\n this.children.forEach(function (child) {\n child.render(ctx);\n });\n }\n }, {\n key: \"addChild\",\n value: function addChild(childNode) {\n var child = childNode instanceof Element ? childNode : this.document.createElement(childNode);\n child.parent = this;\n\n if (!Element.ignoreChildTypes.includes(child.type)) {\n this.children.push(child);\n }\n }\n }, {\n key: \"matchesSelector\",\n value: function matchesSelector(selector) {\n var _node$getAttribute;\n\n var node = this.node;\n\n if (typeof node.matches === 'function') {\n return node.matches(selector);\n }\n\n var styleClasses = (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, 'class');\n\n if (!styleClasses || styleClasses === '') {\n return false;\n }\n\n return styleClasses.split(' ').some(function (styleClass) {\n return \".\".concat(styleClass) === selector;\n });\n }\n }, {\n key: \"addStylesFromStyleDefinition\",\n value: function addStylesFromStyleDefinition() {\n var _this$document = this.document,\n styles = _this$document.styles,\n stylesSpecificity = _this$document.stylesSpecificity;\n\n for (var selector in styles) {\n if (!selector.startsWith('@') && this.matchesSelector(selector)) {\n var style = styles[selector];\n var specificity = stylesSpecificity[selector];\n\n if (style) {\n for (var name in style) {\n var existingSpecificity = this.stylesSpecificity[name];\n\n if (typeof existingSpecificity === 'undefined') {\n existingSpecificity = '000';\n }\n\n if (specificity >= existingSpecificity) {\n this.styles[name] = style[name];\n this.stylesSpecificity[name] = specificity;\n }\n }\n }\n }\n }\n }\n }, {\n key: \"removeStyles\",\n value: function removeStyles(element, ignoreStyles) {\n var toRestore = ignoreStyles.reduce(function (toRestore, name) {\n var styleProp = element.getStyle(name);\n\n if (!styleProp.hasValue()) {\n return toRestore;\n }\n\n var value = styleProp.getString();\n styleProp.setValue('');\n return [].concat(_toConsumableArray__default[\"default\"](toRestore), [[name, value]]);\n }, []);\n return toRestore;\n }\n }, {\n key: \"restoreStyles\",\n value: function restoreStyles(element, styles) {\n styles.forEach(function (_ref) {\n var _ref2 = _slicedToArray__default[\"default\"](_ref, 2),\n name = _ref2[0],\n value = _ref2[1];\n\n element.getStyle(name, true).setValue(value);\n });\n }\n }, {\n key: \"isFirstChild\",\n value: function isFirstChild() {\n var _this$parent;\n\n return ((_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.children.indexOf(this)) === 0;\n }\n }]);\n\n return Element;\n}();\nElement.ignoreChildTypes = ['title'];\n\nfunction _createSuper$J(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$J(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$J() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar UnknownElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](UnknownElement, _Element);\n\n var _super = _createSuper$J(UnknownElement);\n\n function UnknownElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, UnknownElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n\n return _this;\n }\n\n return UnknownElement;\n}(Element);\n\nfunction wrapFontFamily(fontFamily) {\n var trimmed = fontFamily.trim();\n return /^('|\")/.test(trimmed) ? trimmed : \"\\\"\".concat(trimmed, \"\\\"\");\n}\n\nfunction prepareFontFamily(fontFamily) {\n return typeof process === 'undefined' ? fontFamily : fontFamily.trim().split(',').map(wrapFontFamily).join(',');\n}\n/**\r\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-style\r\n * @param fontStyle\r\n * @returns CSS font style.\r\n */\n\n\nfunction prepareFontStyle(fontStyle) {\n if (!fontStyle) {\n return '';\n }\n\n var targetFontStyle = fontStyle.trim().toLowerCase();\n\n switch (targetFontStyle) {\n case 'normal':\n case 'italic':\n case 'oblique':\n case 'inherit':\n case 'initial':\n case 'unset':\n return targetFontStyle;\n\n default:\n if (/^oblique\\s+(-|)\\d+deg$/.test(targetFontStyle)) {\n return targetFontStyle;\n }\n\n return '';\n }\n}\n/**\r\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight\r\n * @param fontWeight\r\n * @returns CSS font weight.\r\n */\n\n\nfunction prepareFontWeight(fontWeight) {\n if (!fontWeight) {\n return '';\n }\n\n var targetFontWeight = fontWeight.trim().toLowerCase();\n\n switch (targetFontWeight) {\n case 'normal':\n case 'bold':\n case 'lighter':\n case 'bolder':\n case 'inherit':\n case 'initial':\n case 'unset':\n return targetFontWeight;\n\n default:\n if (/^[\\d.]+$/.test(targetFontWeight)) {\n return targetFontWeight;\n }\n\n return '';\n }\n}\n\nvar Font = /*#__PURE__*/function () {\n function Font(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) {\n _classCallCheck__default[\"default\"](this, Font);\n\n var inheritFont = inherit ? typeof inherit === 'string' ? Font.parse(inherit) : inherit : {};\n this.fontFamily = fontFamily || inheritFont.fontFamily;\n this.fontSize = fontSize || inheritFont.fontSize;\n this.fontStyle = fontStyle || inheritFont.fontStyle;\n this.fontWeight = fontWeight || inheritFont.fontWeight;\n this.fontVariant = fontVariant || inheritFont.fontVariant;\n }\n\n _createClass__default[\"default\"](Font, [{\n key: \"toString\",\n value: function toString() {\n return [prepareFontStyle(this.fontStyle), this.fontVariant, prepareFontWeight(this.fontWeight), this.fontSize, // Wrap fontFamily only on nodejs and only for canvas.ctx\n prepareFontFamily(this.fontFamily)].join(' ').trim();\n }\n }], [{\n key: \"parse\",\n value: function parse() {\n var font = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n var inherit = arguments.length > 1 ? arguments[1] : undefined;\n var fontStyle = '';\n var fontVariant = '';\n var fontWeight = '';\n var fontSize = '';\n var fontFamily = '';\n var parts = compressSpaces(font).trim().split(' ');\n var set = {\n fontSize: false,\n fontStyle: false,\n fontWeight: false,\n fontVariant: false\n };\n parts.forEach(function (part) {\n switch (true) {\n case !set.fontStyle && Font.styles.includes(part):\n if (part !== 'inherit') {\n fontStyle = part;\n }\n\n set.fontStyle = true;\n break;\n\n case !set.fontVariant && Font.variants.includes(part):\n if (part !== 'inherit') {\n fontVariant = part;\n }\n\n set.fontStyle = true;\n set.fontVariant = true;\n break;\n\n case !set.fontWeight && Font.weights.includes(part):\n if (part !== 'inherit') {\n fontWeight = part;\n }\n\n set.fontStyle = true;\n set.fontVariant = true;\n set.fontWeight = true;\n break;\n\n case !set.fontSize:\n if (part !== 'inherit') {\n var _part$split = part.split('/');\n\n var _part$split2 = _slicedToArray__default[\"default\"](_part$split, 1);\n\n fontSize = _part$split2[0];\n }\n\n set.fontStyle = true;\n set.fontVariant = true;\n set.fontWeight = true;\n set.fontSize = true;\n break;\n\n default:\n if (part !== 'inherit') {\n fontFamily += part;\n }\n\n }\n });\n return new Font(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit);\n }\n }]);\n\n return Font;\n}();\nFont.styles = 'normal|italic|oblique|inherit';\nFont.variants = 'normal|small-caps|inherit';\nFont.weights = 'normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900|inherit';\n\nvar BoundingBox = /*#__PURE__*/function () {\n function BoundingBox() {\n var x1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Number.NaN;\n var y1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Number.NaN;\n var x2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Number.NaN;\n var y2 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : Number.NaN;\n\n _classCallCheck__default[\"default\"](this, BoundingBox);\n\n this.x1 = x1;\n this.y1 = y1;\n this.x2 = x2;\n this.y2 = y2;\n this.addPoint(x1, y1);\n this.addPoint(x2, y2);\n }\n\n _createClass__default[\"default\"](BoundingBox, [{\n key: \"addPoint\",\n value: function addPoint(x, y) {\n if (typeof x !== 'undefined') {\n if (isNaN(this.x1) || isNaN(this.x2)) {\n this.x1 = x;\n this.x2 = x;\n }\n\n if (x < this.x1) {\n this.x1 = x;\n }\n\n if (x > this.x2) {\n this.x2 = x;\n }\n }\n\n if (typeof y !== 'undefined') {\n if (isNaN(this.y1) || isNaN(this.y2)) {\n this.y1 = y;\n this.y2 = y;\n }\n\n if (y < this.y1) {\n this.y1 = y;\n }\n\n if (y > this.y2) {\n this.y2 = y;\n }\n }\n }\n }, {\n key: \"addX\",\n value: function addX(x) {\n this.addPoint(x, null);\n }\n }, {\n key: \"addY\",\n value: function addY(y) {\n this.addPoint(null, y);\n }\n }, {\n key: \"addBoundingBox\",\n value: function addBoundingBox(boundingBox) {\n if (!boundingBox) {\n return;\n }\n\n var x1 = boundingBox.x1,\n y1 = boundingBox.y1,\n x2 = boundingBox.x2,\n y2 = boundingBox.y2;\n this.addPoint(x1, y1);\n this.addPoint(x2, y2);\n }\n }, {\n key: \"sumCubic\",\n value: function sumCubic(t, p0, p1, p2, p3) {\n return Math.pow(1 - t, 3) * p0 + 3 * Math.pow(1 - t, 2) * t * p1 + 3 * (1 - t) * Math.pow(t, 2) * p2 + Math.pow(t, 3) * p3;\n }\n }, {\n key: \"bezierCurveAdd\",\n value: function bezierCurveAdd(forX, p0, p1, p2, p3) {\n var b = 6 * p0 - 12 * p1 + 6 * p2;\n var a = -3 * p0 + 9 * p1 - 9 * p2 + 3 * p3;\n var c = 3 * p1 - 3 * p0;\n\n if (a === 0) {\n if (b === 0) {\n return;\n }\n\n var t = -c / b;\n\n if (0 < t && t < 1) {\n if (forX) {\n this.addX(this.sumCubic(t, p0, p1, p2, p3));\n } else {\n this.addY(this.sumCubic(t, p0, p1, p2, p3));\n }\n }\n\n return;\n }\n\n var b2ac = Math.pow(b, 2) - 4 * c * a;\n\n if (b2ac < 0) {\n return;\n }\n\n var t1 = (-b + Math.sqrt(b2ac)) / (2 * a);\n\n if (0 < t1 && t1 < 1) {\n if (forX) {\n this.addX(this.sumCubic(t1, p0, p1, p2, p3));\n } else {\n this.addY(this.sumCubic(t1, p0, p1, p2, p3));\n }\n }\n\n var t2 = (-b - Math.sqrt(b2ac)) / (2 * a);\n\n if (0 < t2 && t2 < 1) {\n if (forX) {\n this.addX(this.sumCubic(t2, p0, p1, p2, p3));\n } else {\n this.addY(this.sumCubic(t2, p0, p1, p2, p3));\n }\n }\n } // from http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html\n\n }, {\n key: \"addBezierCurve\",\n value: function addBezierCurve(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) {\n this.addPoint(p0x, p0y);\n this.addPoint(p3x, p3y);\n this.bezierCurveAdd(true, p0x, p1x, p2x, p3x);\n this.bezierCurveAdd(false, p0y, p1y, p2y, p3y);\n }\n }, {\n key: \"addQuadraticCurve\",\n value: function addQuadraticCurve(p0x, p0y, p1x, p1y, p2x, p2y) {\n var cp1x = p0x + 2 / 3 * (p1x - p0x); // CP1 = QP0 + 2/3 *(QP1-QP0)\n\n var cp1y = p0y + 2 / 3 * (p1y - p0y); // CP1 = QP0 + 2/3 *(QP1-QP0)\n\n var cp2x = cp1x + 1 / 3 * (p2x - p0x); // CP2 = CP1 + 1/3 *(QP2-QP0)\n\n var cp2y = cp1y + 1 / 3 * (p2y - p0y); // CP2 = CP1 + 1/3 *(QP2-QP0)\n\n this.addBezierCurve(p0x, p0y, cp1x, cp2x, cp1y, cp2y, p2x, p2y);\n }\n }, {\n key: \"isPointInBox\",\n value: function isPointInBox(x, y) {\n var x1 = this.x1,\n y1 = this.y1,\n x2 = this.x2,\n y2 = this.y2;\n return x1 <= x && x <= x2 && y1 <= y && y <= y2;\n }\n }, {\n key: \"x\",\n get: function get() {\n return this.x1;\n }\n }, {\n key: \"y\",\n get: function get() {\n return this.y1;\n }\n }, {\n key: \"width\",\n get: function get() {\n return this.x2 - this.x1;\n }\n }, {\n key: \"height\",\n get: function get() {\n return this.y2 - this.y1;\n }\n }]);\n\n return BoundingBox;\n}();\n\nfunction _createSuper$I(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$I(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$I() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar PathParser = /*#__PURE__*/function (_SVGPathData) {\n _inherits__default[\"default\"](PathParser, _SVGPathData);\n\n var _super = _createSuper$I(PathParser);\n\n function PathParser(path) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, PathParser);\n\n _this = _super.call(this, path // Fix spaces after signs.\n .replace(/([+\\-.])\\s+/gm, '$1') // Remove invalid part.\n .replace(/[^MmZzLlHhVvCcSsQqTtAae\\d\\s.,+-].*/g, ''));\n _this.control = null;\n _this.start = null;\n _this.current = null;\n _this.command = null;\n _this.commands = _this.commands;\n _this.i = -1;\n _this.previousCommand = null;\n _this.points = [];\n _this.angles = [];\n return _this;\n }\n\n _createClass__default[\"default\"](PathParser, [{\n key: \"reset\",\n value: function reset() {\n this.i = -1;\n this.command = null;\n this.previousCommand = null;\n this.start = new Point(0, 0);\n this.control = new Point(0, 0);\n this.current = new Point(0, 0);\n this.points = [];\n this.angles = [];\n }\n }, {\n key: \"isEnd\",\n value: function isEnd() {\n var i = this.i,\n commands = this.commands;\n return i >= commands.length - 1;\n }\n }, {\n key: \"next\",\n value: function next() {\n var command = this.commands[++this.i];\n this.previousCommand = this.command;\n this.command = command;\n return command;\n }\n }, {\n key: \"getPoint\",\n value: function getPoint() {\n var xProp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'x';\n var yProp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'y';\n var point = new Point(this.command[xProp], this.command[yProp]);\n return this.makeAbsolute(point);\n }\n }, {\n key: \"getAsControlPoint\",\n value: function getAsControlPoint(xProp, yProp) {\n var point = this.getPoint(xProp, yProp);\n this.control = point;\n return point;\n }\n }, {\n key: \"getAsCurrentPoint\",\n value: function getAsCurrentPoint(xProp, yProp) {\n var point = this.getPoint(xProp, yProp);\n this.current = point;\n return point;\n }\n }, {\n key: \"getReflectedControlPoint\",\n value: function getReflectedControlPoint() {\n var previousCommand = this.previousCommand.type;\n\n if (previousCommand !== svgPathdata.SVGPathData.CURVE_TO && previousCommand !== svgPathdata.SVGPathData.SMOOTH_CURVE_TO && previousCommand !== svgPathdata.SVGPathData.QUAD_TO && previousCommand !== svgPathdata.SVGPathData.SMOOTH_QUAD_TO) {\n return this.current;\n } // reflect point\n\n\n var _this$current = this.current,\n cx = _this$current.x,\n cy = _this$current.y,\n _this$control = this.control,\n ox = _this$control.x,\n oy = _this$control.y;\n var point = new Point(2 * cx - ox, 2 * cy - oy);\n return point;\n }\n }, {\n key: \"makeAbsolute\",\n value: function makeAbsolute(point) {\n if (this.command.relative) {\n var _this$current2 = this.current,\n x = _this$current2.x,\n y = _this$current2.y;\n point.x += x;\n point.y += y;\n }\n\n return point;\n }\n }, {\n key: \"addMarker\",\n value: function addMarker(point, from, priorTo) {\n var points = this.points,\n angles = this.angles; // if the last angle isn't filled in because we didn't have this point yet ...\n\n if (priorTo && angles.length > 0 && !angles[angles.length - 1]) {\n angles[angles.length - 1] = points[points.length - 1].angleTo(priorTo);\n }\n\n this.addMarkerAngle(point, from ? from.angleTo(point) : null);\n }\n }, {\n key: \"addMarkerAngle\",\n value: function addMarkerAngle(point, angle) {\n this.points.push(point);\n this.angles.push(angle);\n }\n }, {\n key: \"getMarkerPoints\",\n value: function getMarkerPoints() {\n return this.points;\n }\n }, {\n key: \"getMarkerAngles\",\n value: function getMarkerAngles() {\n var angles = this.angles;\n var len = angles.length;\n\n for (var i = 0; i < len; i++) {\n if (!angles[i]) {\n for (var j = i + 1; j < len; j++) {\n if (angles[j]) {\n angles[i] = angles[j];\n break;\n }\n }\n }\n }\n\n return angles;\n }\n }]);\n\n return PathParser;\n}(svgPathdata.SVGPathData);\n\nfunction _createSuper$H(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$H(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$H() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar RenderedElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](RenderedElement, _Element);\n\n var _super = _createSuper$H(RenderedElement);\n\n function RenderedElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, RenderedElement);\n\n _this = _super.apply(this, arguments);\n _this.modifiedEmSizeStack = false;\n return _this;\n }\n\n _createClass__default[\"default\"](RenderedElement, [{\n key: \"calculateOpacity\",\n value: function calculateOpacity() {\n var opacity = 1.0; // eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n\n var element = this;\n\n while (element) {\n var opacityStyle = element.getStyle('opacity', false, true); // no ancestors on style call\n\n if (opacityStyle.hasValue(true)) {\n opacity *= opacityStyle.getNumber();\n }\n\n element = element.parent;\n }\n\n return opacity;\n }\n }, {\n key: \"setContext\",\n value: function setContext(ctx) {\n var fromMeasure = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n if (!fromMeasure) {\n // causes stack overflow when measuring text with gradients\n // fill\n var fillStyleProp = this.getStyle('fill');\n var fillOpacityStyleProp = this.getStyle('fill-opacity');\n var strokeStyleProp = this.getStyle('stroke');\n var strokeOpacityProp = this.getStyle('stroke-opacity');\n\n if (fillStyleProp.isUrlDefinition()) {\n var fillStyle = fillStyleProp.getFillStyleDefinition(this, fillOpacityStyleProp);\n\n if (fillStyle) {\n ctx.fillStyle = fillStyle;\n }\n } else if (fillStyleProp.hasValue()) {\n if (fillStyleProp.getString() === 'currentColor') {\n fillStyleProp.setValue(this.getStyle('color').getColor());\n }\n\n var _fillStyle = fillStyleProp.getColor();\n\n if (_fillStyle !== 'inherit') {\n ctx.fillStyle = _fillStyle === 'none' ? 'rgba(0,0,0,0)' : _fillStyle;\n }\n }\n\n if (fillOpacityStyleProp.hasValue()) {\n var _fillStyle2 = new Property(this.document, 'fill', ctx.fillStyle).addOpacity(fillOpacityStyleProp).getColor();\n\n ctx.fillStyle = _fillStyle2;\n } // stroke\n\n\n if (strokeStyleProp.isUrlDefinition()) {\n var strokeStyle = strokeStyleProp.getFillStyleDefinition(this, strokeOpacityProp);\n\n if (strokeStyle) {\n ctx.strokeStyle = strokeStyle;\n }\n } else if (strokeStyleProp.hasValue()) {\n if (strokeStyleProp.getString() === 'currentColor') {\n strokeStyleProp.setValue(this.getStyle('color').getColor());\n }\n\n var _strokeStyle = strokeStyleProp.getString();\n\n if (_strokeStyle !== 'inherit') {\n ctx.strokeStyle = _strokeStyle === 'none' ? 'rgba(0,0,0,0)' : _strokeStyle;\n }\n }\n\n if (strokeOpacityProp.hasValue()) {\n var _strokeStyle2 = new Property(this.document, 'stroke', ctx.strokeStyle).addOpacity(strokeOpacityProp).getString();\n\n ctx.strokeStyle = _strokeStyle2;\n }\n\n var strokeWidthStyleProp = this.getStyle('stroke-width');\n\n if (strokeWidthStyleProp.hasValue()) {\n var newLineWidth = strokeWidthStyleProp.getPixels();\n ctx.lineWidth = !newLineWidth ? PSEUDO_ZERO // browsers don't respect 0 (or node-canvas? :-)\n : newLineWidth;\n }\n\n var strokeLinecapStyleProp = this.getStyle('stroke-linecap');\n var strokeLinejoinStyleProp = this.getStyle('stroke-linejoin');\n var strokeMiterlimitProp = this.getStyle('stroke-miterlimit'); // NEED TEST\n // const pointOrderStyleProp = this.getStyle('paint-order');\n\n var strokeDasharrayStyleProp = this.getStyle('stroke-dasharray');\n var strokeDashoffsetProp = this.getStyle('stroke-dashoffset');\n\n if (strokeLinecapStyleProp.hasValue()) {\n ctx.lineCap = strokeLinecapStyleProp.getString();\n }\n\n if (strokeLinejoinStyleProp.hasValue()) {\n ctx.lineJoin = strokeLinejoinStyleProp.getString();\n }\n\n if (strokeMiterlimitProp.hasValue()) {\n ctx.miterLimit = strokeMiterlimitProp.getNumber();\n } // NEED TEST\n // if (pointOrderStyleProp.hasValue()) {\n // \t// ?\n // \tctx.paintOrder = pointOrderStyleProp.getValue();\n // }\n\n\n if (strokeDasharrayStyleProp.hasValue() && strokeDasharrayStyleProp.getString() !== 'none') {\n var gaps = toNumbers(strokeDasharrayStyleProp.getString());\n\n if (typeof ctx.setLineDash !== 'undefined') {\n ctx.setLineDash(gaps);\n } else // @ts-expect-error Handle browser prefix.\n if (typeof ctx.webkitLineDash !== 'undefined') {\n // @ts-expect-error Handle browser prefix.\n ctx.webkitLineDash = gaps;\n } else // @ts-expect-error Handle browser prefix.\n if (typeof ctx.mozDash !== 'undefined' && !(gaps.length === 1 && gaps[0] === 0)) {\n // @ts-expect-error Handle browser prefix.\n ctx.mozDash = gaps;\n }\n\n var offset = strokeDashoffsetProp.getPixels();\n\n if (typeof ctx.lineDashOffset !== 'undefined') {\n ctx.lineDashOffset = offset;\n } else // @ts-expect-error Handle browser prefix.\n if (typeof ctx.webkitLineDashOffset !== 'undefined') {\n // @ts-expect-error Handle browser prefix.\n ctx.webkitLineDashOffset = offset;\n } else // @ts-expect-error Handle browser prefix.\n if (typeof ctx.mozDashOffset !== 'undefined') {\n // @ts-expect-error Handle browser prefix.\n ctx.mozDashOffset = offset;\n }\n }\n } // font\n\n\n this.modifiedEmSizeStack = false;\n\n if (typeof ctx.font !== 'undefined') {\n var fontStyleProp = this.getStyle('font');\n var fontStyleStyleProp = this.getStyle('font-style');\n var fontVariantStyleProp = this.getStyle('font-variant');\n var fontWeightStyleProp = this.getStyle('font-weight');\n var fontSizeStyleProp = this.getStyle('font-size');\n var fontFamilyStyleProp = this.getStyle('font-family');\n var font = new Font(fontStyleStyleProp.getString(), fontVariantStyleProp.getString(), fontWeightStyleProp.getString(), fontSizeStyleProp.hasValue() ? \"\".concat(fontSizeStyleProp.getPixels(true), \"px\") : '', fontFamilyStyleProp.getString(), Font.parse(fontStyleProp.getString(), ctx.font));\n fontStyleStyleProp.setValue(font.fontStyle);\n fontVariantStyleProp.setValue(font.fontVariant);\n fontWeightStyleProp.setValue(font.fontWeight);\n fontSizeStyleProp.setValue(font.fontSize);\n fontFamilyStyleProp.setValue(font.fontFamily);\n ctx.font = font.toString();\n\n if (fontSizeStyleProp.isPixels()) {\n this.document.emSize = fontSizeStyleProp.getPixels();\n this.modifiedEmSizeStack = true;\n }\n }\n\n if (!fromMeasure) {\n // effects\n this.applyEffects(ctx); // opacity\n\n ctx.globalAlpha = this.calculateOpacity();\n }\n }\n }, {\n key: \"clearContext\",\n value: function clearContext(ctx) {\n _get__default[\"default\"](_getPrototypeOf__default[\"default\"](RenderedElement.prototype), \"clearContext\", this).call(this, ctx);\n\n if (this.modifiedEmSizeStack) {\n this.document.popEmSize();\n }\n }\n }]);\n\n return RenderedElement;\n}(Element);\n\nfunction _createSuper$G(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$G(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$G() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar PathElement = /*#__PURE__*/function (_RenderedElement) {\n _inherits__default[\"default\"](PathElement, _RenderedElement);\n\n var _super = _createSuper$G(PathElement);\n\n function PathElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, PathElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'path';\n _this.pathParser = null;\n _this.pathParser = new PathParser(_this.getAttribute('d').getString());\n return _this;\n }\n\n _createClass__default[\"default\"](PathElement, [{\n key: \"path\",\n value: function path(ctx) {\n var pathParser = this.pathParser;\n var boundingBox = new BoundingBox();\n pathParser.reset();\n\n if (ctx) {\n ctx.beginPath();\n }\n\n while (!pathParser.isEnd()) {\n switch (pathParser.next().type) {\n case PathParser.MOVE_TO:\n this.pathM(ctx, boundingBox);\n break;\n\n case PathParser.LINE_TO:\n this.pathL(ctx, boundingBox);\n break;\n\n case PathParser.HORIZ_LINE_TO:\n this.pathH(ctx, boundingBox);\n break;\n\n case PathParser.VERT_LINE_TO:\n this.pathV(ctx, boundingBox);\n break;\n\n case PathParser.CURVE_TO:\n this.pathC(ctx, boundingBox);\n break;\n\n case PathParser.SMOOTH_CURVE_TO:\n this.pathS(ctx, boundingBox);\n break;\n\n case PathParser.QUAD_TO:\n this.pathQ(ctx, boundingBox);\n break;\n\n case PathParser.SMOOTH_QUAD_TO:\n this.pathT(ctx, boundingBox);\n break;\n\n case PathParser.ARC:\n this.pathA(ctx, boundingBox);\n break;\n\n case PathParser.CLOSE_PATH:\n this.pathZ(ctx, boundingBox);\n break;\n }\n }\n\n return boundingBox;\n }\n }, {\n key: \"getBoundingBox\",\n value: function getBoundingBox(_) {\n return this.path();\n }\n }, {\n key: \"getMarkers\",\n value: function getMarkers() {\n var pathParser = this.pathParser;\n var points = pathParser.getMarkerPoints();\n var angles = pathParser.getMarkerAngles();\n var markers = points.map(function (point, i) {\n return [point, angles[i]];\n });\n return markers;\n }\n }, {\n key: \"renderChildren\",\n value: function renderChildren(ctx) {\n this.path(ctx);\n this.document.screen.mouse.checkPath(this, ctx);\n var fillRuleStyleProp = this.getStyle('fill-rule');\n\n if (ctx.fillStyle !== '') {\n if (fillRuleStyleProp.getString('inherit') !== 'inherit') {\n ctx.fill(fillRuleStyleProp.getString());\n } else {\n ctx.fill();\n }\n }\n\n if (ctx.strokeStyle !== '') {\n if (this.getAttribute('vector-effect').getString() === 'non-scaling-stroke') {\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.stroke();\n ctx.restore();\n } else {\n ctx.stroke();\n }\n }\n\n var markers = this.getMarkers();\n\n if (markers) {\n var markersLastIndex = markers.length - 1;\n var markerStartStyleProp = this.getStyle('marker-start');\n var markerMidStyleProp = this.getStyle('marker-mid');\n var markerEndStyleProp = this.getStyle('marker-end');\n\n if (markerStartStyleProp.isUrlDefinition()) {\n var marker = markerStartStyleProp.getDefinition();\n\n var _markers$ = _slicedToArray__default[\"default\"](markers[0], 2),\n point = _markers$[0],\n angle = _markers$[1];\n\n marker.render(ctx, point, angle);\n }\n\n if (markerMidStyleProp.isUrlDefinition()) {\n var _marker = markerMidStyleProp.getDefinition();\n\n for (var i = 1; i < markersLastIndex; i++) {\n var _markers$i = _slicedToArray__default[\"default\"](markers[i], 2),\n _point = _markers$i[0],\n _angle = _markers$i[1];\n\n _marker.render(ctx, _point, _angle);\n }\n }\n\n if (markerEndStyleProp.isUrlDefinition()) {\n var _marker2 = markerEndStyleProp.getDefinition();\n\n var _markers$markersLastI = _slicedToArray__default[\"default\"](markers[markersLastIndex], 2),\n _point2 = _markers$markersLastI[0],\n _angle2 = _markers$markersLastI[1];\n\n _marker2.render(ctx, _point2, _angle2);\n }\n }\n }\n }, {\n key: \"pathM\",\n value: function pathM(ctx, boundingBox) {\n var pathParser = this.pathParser;\n\n var _PathElement$pathM = PathElement.pathM(pathParser),\n point = _PathElement$pathM.point;\n\n var x = point.x,\n y = point.y;\n pathParser.addMarker(point);\n boundingBox.addPoint(x, y);\n\n if (ctx) {\n ctx.moveTo(x, y);\n }\n }\n }, {\n key: \"pathL\",\n value: function pathL(ctx, boundingBox) {\n var pathParser = this.pathParser;\n\n var _PathElement$pathL = PathElement.pathL(pathParser),\n current = _PathElement$pathL.current,\n point = _PathElement$pathL.point;\n\n var x = point.x,\n y = point.y;\n pathParser.addMarker(point, current);\n boundingBox.addPoint(x, y);\n\n if (ctx) {\n ctx.lineTo(x, y);\n }\n }\n }, {\n key: \"pathH\",\n value: function pathH(ctx, boundingBox) {\n var pathParser = this.pathParser;\n\n var _PathElement$pathH = PathElement.pathH(pathParser),\n current = _PathElement$pathH.current,\n point = _PathElement$pathH.point;\n\n var x = point.x,\n y = point.y;\n pathParser.addMarker(point, current);\n boundingBox.addPoint(x, y);\n\n if (ctx) {\n ctx.lineTo(x, y);\n }\n }\n }, {\n key: \"pathV\",\n value: function pathV(ctx, boundingBox) {\n var pathParser = this.pathParser;\n\n var _PathElement$pathV = PathElement.pathV(pathParser),\n current = _PathElement$pathV.current,\n point = _PathElement$pathV.point;\n\n var x = point.x,\n y = point.y;\n pathParser.addMarker(point, current);\n boundingBox.addPoint(x, y);\n\n if (ctx) {\n ctx.lineTo(x, y);\n }\n }\n }, {\n key: \"pathC\",\n value: function pathC(ctx, boundingBox) {\n var pathParser = this.pathParser;\n\n var _PathElement$pathC = PathElement.pathC(pathParser),\n current = _PathElement$pathC.current,\n point = _PathElement$pathC.point,\n controlPoint = _PathElement$pathC.controlPoint,\n currentPoint = _PathElement$pathC.currentPoint;\n\n pathParser.addMarker(currentPoint, controlPoint, point);\n boundingBox.addBezierCurve(current.x, current.y, point.x, point.y, controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n\n if (ctx) {\n ctx.bezierCurveTo(point.x, point.y, controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n }\n }\n }, {\n key: \"pathS\",\n value: function pathS(ctx, boundingBox) {\n var pathParser = this.pathParser;\n\n var _PathElement$pathS = PathElement.pathS(pathParser),\n current = _PathElement$pathS.current,\n point = _PathElement$pathS.point,\n controlPoint = _PathElement$pathS.controlPoint,\n currentPoint = _PathElement$pathS.currentPoint;\n\n pathParser.addMarker(currentPoint, controlPoint, point);\n boundingBox.addBezierCurve(current.x, current.y, point.x, point.y, controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n\n if (ctx) {\n ctx.bezierCurveTo(point.x, point.y, controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n }\n }\n }, {\n key: \"pathQ\",\n value: function pathQ(ctx, boundingBox) {\n var pathParser = this.pathParser;\n\n var _PathElement$pathQ = PathElement.pathQ(pathParser),\n current = _PathElement$pathQ.current,\n controlPoint = _PathElement$pathQ.controlPoint,\n currentPoint = _PathElement$pathQ.currentPoint;\n\n pathParser.addMarker(currentPoint, controlPoint, controlPoint);\n boundingBox.addQuadraticCurve(current.x, current.y, controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n\n if (ctx) {\n ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n }\n }\n }, {\n key: \"pathT\",\n value: function pathT(ctx, boundingBox) {\n var pathParser = this.pathParser;\n\n var _PathElement$pathT = PathElement.pathT(pathParser),\n current = _PathElement$pathT.current,\n controlPoint = _PathElement$pathT.controlPoint,\n currentPoint = _PathElement$pathT.currentPoint;\n\n pathParser.addMarker(currentPoint, controlPoint, controlPoint);\n boundingBox.addQuadraticCurve(current.x, current.y, controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n\n if (ctx) {\n ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n }\n }\n }, {\n key: \"pathA\",\n value: function pathA(ctx, boundingBox) {\n var pathParser = this.pathParser;\n\n var _PathElement$pathA = PathElement.pathA(pathParser),\n currentPoint = _PathElement$pathA.currentPoint,\n rX = _PathElement$pathA.rX,\n rY = _PathElement$pathA.rY,\n sweepFlag = _PathElement$pathA.sweepFlag,\n xAxisRotation = _PathElement$pathA.xAxisRotation,\n centp = _PathElement$pathA.centp,\n a1 = _PathElement$pathA.a1,\n ad = _PathElement$pathA.ad; // for markers\n\n\n var dir = 1 - sweepFlag ? 1.0 : -1.0;\n var ah = a1 + dir * (ad / 2.0);\n var halfWay = new Point(centp.x + rX * Math.cos(ah), centp.y + rY * Math.sin(ah));\n pathParser.addMarkerAngle(halfWay, ah - dir * Math.PI / 2);\n pathParser.addMarkerAngle(currentPoint, ah - dir * Math.PI);\n boundingBox.addPoint(currentPoint.x, currentPoint.y); // TODO: this is too naive, make it better\n\n if (ctx && !isNaN(a1) && !isNaN(ad)) {\n var r = rX > rY ? rX : rY;\n var sx = rX > rY ? 1 : rX / rY;\n var sy = rX > rY ? rY / rX : 1;\n ctx.translate(centp.x, centp.y);\n ctx.rotate(xAxisRotation);\n ctx.scale(sx, sy);\n ctx.arc(0, 0, r, a1, a1 + ad, Boolean(1 - sweepFlag));\n ctx.scale(1 / sx, 1 / sy);\n ctx.rotate(-xAxisRotation);\n ctx.translate(-centp.x, -centp.y);\n }\n }\n }, {\n key: \"pathZ\",\n value: function pathZ(ctx, boundingBox) {\n PathElement.pathZ(this.pathParser);\n\n if (ctx) {\n // only close path if it is not a straight line\n if (boundingBox.x1 !== boundingBox.x2 && boundingBox.y1 !== boundingBox.y2) {\n ctx.closePath();\n }\n }\n }\n }], [{\n key: \"pathM\",\n value: function pathM(pathParser) {\n var point = pathParser.getAsCurrentPoint();\n pathParser.start = pathParser.current;\n return {\n point: point\n };\n }\n }, {\n key: \"pathL\",\n value: function pathL(pathParser) {\n var current = pathParser.current;\n var point = pathParser.getAsCurrentPoint();\n return {\n current: current,\n point: point\n };\n }\n }, {\n key: \"pathH\",\n value: function pathH(pathParser) {\n var current = pathParser.current,\n command = pathParser.command;\n var point = new Point((command.relative ? current.x : 0) + command.x, current.y);\n pathParser.current = point;\n return {\n current: current,\n point: point\n };\n }\n }, {\n key: \"pathV\",\n value: function pathV(pathParser) {\n var current = pathParser.current,\n command = pathParser.command;\n var point = new Point(current.x, (command.relative ? current.y : 0) + command.y);\n pathParser.current = point;\n return {\n current: current,\n point: point\n };\n }\n }, {\n key: \"pathC\",\n value: function pathC(pathParser) {\n var current = pathParser.current;\n var point = pathParser.getPoint('x1', 'y1');\n var controlPoint = pathParser.getAsControlPoint('x2', 'y2');\n var currentPoint = pathParser.getAsCurrentPoint();\n return {\n current: current,\n point: point,\n controlPoint: controlPoint,\n currentPoint: currentPoint\n };\n }\n }, {\n key: \"pathS\",\n value: function pathS(pathParser) {\n var current = pathParser.current;\n var point = pathParser.getReflectedControlPoint();\n var controlPoint = pathParser.getAsControlPoint('x2', 'y2');\n var currentPoint = pathParser.getAsCurrentPoint();\n return {\n current: current,\n point: point,\n controlPoint: controlPoint,\n currentPoint: currentPoint\n };\n }\n }, {\n key: \"pathQ\",\n value: function pathQ(pathParser) {\n var current = pathParser.current;\n var controlPoint = pathParser.getAsControlPoint('x1', 'y1');\n var currentPoint = pathParser.getAsCurrentPoint();\n return {\n current: current,\n controlPoint: controlPoint,\n currentPoint: currentPoint\n };\n }\n }, {\n key: \"pathT\",\n value: function pathT(pathParser) {\n var current = pathParser.current;\n var controlPoint = pathParser.getReflectedControlPoint();\n pathParser.control = controlPoint;\n var currentPoint = pathParser.getAsCurrentPoint();\n return {\n current: current,\n controlPoint: controlPoint,\n currentPoint: currentPoint\n };\n }\n }, {\n key: \"pathA\",\n value: function pathA(pathParser) {\n var current = pathParser.current,\n command = pathParser.command;\n var rX = command.rX,\n rY = command.rY,\n xRot = command.xRot,\n lArcFlag = command.lArcFlag,\n sweepFlag = command.sweepFlag;\n var xAxisRotation = xRot * (Math.PI / 180.0);\n var currentPoint = pathParser.getAsCurrentPoint(); // Conversion from endpoint to center parameterization\n // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes\n // x1', y1'\n\n var currp = new Point(Math.cos(xAxisRotation) * (current.x - currentPoint.x) / 2.0 + Math.sin(xAxisRotation) * (current.y - currentPoint.y) / 2.0, -Math.sin(xAxisRotation) * (current.x - currentPoint.x) / 2.0 + Math.cos(xAxisRotation) * (current.y - currentPoint.y) / 2.0); // adjust radii\n\n var l = Math.pow(currp.x, 2) / Math.pow(rX, 2) + Math.pow(currp.y, 2) / Math.pow(rY, 2);\n\n if (l > 1) {\n rX *= Math.sqrt(l);\n rY *= Math.sqrt(l);\n } // cx', cy'\n\n\n var s = (lArcFlag === sweepFlag ? -1 : 1) * Math.sqrt((Math.pow(rX, 2) * Math.pow(rY, 2) - Math.pow(rX, 2) * Math.pow(currp.y, 2) - Math.pow(rY, 2) * Math.pow(currp.x, 2)) / (Math.pow(rX, 2) * Math.pow(currp.y, 2) + Math.pow(rY, 2) * Math.pow(currp.x, 2)));\n\n if (isNaN(s)) {\n s = 0;\n }\n\n var cpp = new Point(s * rX * currp.y / rY, s * -rY * currp.x / rX); // cx, cy\n\n var centp = new Point((current.x + currentPoint.x) / 2.0 + Math.cos(xAxisRotation) * cpp.x - Math.sin(xAxisRotation) * cpp.y, (current.y + currentPoint.y) / 2.0 + Math.sin(xAxisRotation) * cpp.x + Math.cos(xAxisRotation) * cpp.y); // initial angle\n\n var a1 = vectorsAngle([1, 0], [(currp.x - cpp.x) / rX, (currp.y - cpp.y) / rY]); // θ1\n // angle delta\n\n var u = [(currp.x - cpp.x) / rX, (currp.y - cpp.y) / rY];\n var v = [(-currp.x - cpp.x) / rX, (-currp.y - cpp.y) / rY];\n var ad = vectorsAngle(u, v); // Δθ\n\n if (vectorsRatio(u, v) <= -1) {\n ad = Math.PI;\n }\n\n if (vectorsRatio(u, v) >= 1) {\n ad = 0;\n }\n\n return {\n currentPoint: currentPoint,\n rX: rX,\n rY: rY,\n sweepFlag: sweepFlag,\n xAxisRotation: xAxisRotation,\n centp: centp,\n a1: a1,\n ad: ad\n };\n }\n }, {\n key: \"pathZ\",\n value: function pathZ(pathParser) {\n pathParser.current = pathParser.start;\n }\n }]);\n\n return PathElement;\n}(RenderedElement);\n\nfunction _createSuper$F(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$F(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$F() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar GlyphElement = /*#__PURE__*/function (_PathElement) {\n _inherits__default[\"default\"](GlyphElement, _PathElement);\n\n var _super = _createSuper$F(GlyphElement);\n\n function GlyphElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, GlyphElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'glyph';\n _this.horizAdvX = _this.getAttribute('horiz-adv-x').getNumber();\n _this.unicode = _this.getAttribute('unicode').getString();\n _this.arabicForm = _this.getAttribute('arabic-form').getString();\n return _this;\n }\n\n return GlyphElement;\n}(PathElement);\n\nfunction _createSuper$E(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$E(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$E() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar TextElement = /*#__PURE__*/function (_RenderedElement) {\n _inherits__default[\"default\"](TextElement, _RenderedElement);\n\n var _super = _createSuper$E(TextElement);\n\n function TextElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, TextElement);\n\n _this = _super.call(this, document, node, (this instanceof TextElement ? this.constructor : void 0) === TextElement ? true : captureTextNodes);\n _this.type = 'text';\n _this.x = 0;\n _this.y = 0;\n _this.measureCache = -1;\n return _this;\n }\n\n _createClass__default[\"default\"](TextElement, [{\n key: \"setContext\",\n value: function setContext(ctx) {\n var fromMeasure = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n _get__default[\"default\"](_getPrototypeOf__default[\"default\"](TextElement.prototype), \"setContext\", this).call(this, ctx, fromMeasure);\n\n var textBaseline = this.getStyle('dominant-baseline').getTextBaseline() || this.getStyle('alignment-baseline').getTextBaseline();\n\n if (textBaseline) {\n ctx.textBaseline = textBaseline;\n }\n }\n }, {\n key: \"initializeCoordinates\",\n value: function initializeCoordinates() {\n this.x = 0;\n this.y = 0;\n this.leafTexts = [];\n this.textChunkStart = 0;\n this.minX = Number.POSITIVE_INFINITY;\n this.maxX = Number.NEGATIVE_INFINITY;\n }\n }, {\n key: \"getBoundingBox\",\n value: function getBoundingBox(ctx) {\n var _this2 = this;\n\n if (this.type !== 'text') {\n return this.getTElementBoundingBox(ctx);\n } // first, calculate child positions\n\n\n this.initializeCoordinates();\n this.adjustChildCoordinatesRecursive(ctx);\n var boundingBox = null; // then calculate bounding box\n\n this.children.forEach(function (_, i) {\n var childBoundingBox = _this2.getChildBoundingBox(ctx, _this2, _this2, i);\n\n if (!boundingBox) {\n boundingBox = childBoundingBox;\n } else {\n boundingBox.addBoundingBox(childBoundingBox);\n }\n });\n return boundingBox;\n }\n }, {\n key: \"getFontSize\",\n value: function getFontSize() {\n var document = this.document,\n parent = this.parent;\n var inheritFontSize = Font.parse(document.ctx.font).fontSize;\n var fontSize = parent.getStyle('font-size').getNumber(inheritFontSize);\n return fontSize;\n }\n }, {\n key: \"getTElementBoundingBox\",\n value: function getTElementBoundingBox(ctx) {\n var fontSize = this.getFontSize();\n return new BoundingBox(this.x, this.y - fontSize, this.x + this.measureText(ctx), this.y);\n }\n }, {\n key: \"getGlyph\",\n value: function getGlyph(font, text, i) {\n var char = text[i];\n var glyph = null;\n\n if (font.isArabic) {\n var len = text.length;\n var prevChar = text[i - 1];\n var nextChar = text[i + 1];\n var arabicForm = 'isolated';\n\n if ((i === 0 || prevChar === ' ') && i < len - 1 && nextChar !== ' ') {\n arabicForm = 'terminal';\n }\n\n if (i > 0 && prevChar !== ' ' && i < len - 1 && nextChar !== ' ') {\n arabicForm = 'medial';\n }\n\n if (i > 0 && prevChar !== ' ' && (i === len - 1 || nextChar === ' ')) {\n arabicForm = 'initial';\n }\n\n if (typeof font.glyphs[char] !== 'undefined') {\n // NEED TEST\n var maybeGlyph = font.glyphs[char];\n glyph = maybeGlyph instanceof GlyphElement ? maybeGlyph : maybeGlyph[arabicForm];\n }\n } else {\n glyph = font.glyphs[char];\n }\n\n if (!glyph) {\n glyph = font.missingGlyph;\n }\n\n return glyph;\n }\n }, {\n key: \"getText\",\n value: function getText() {\n return '';\n }\n }, {\n key: \"getTextFromNode\",\n value: function getTextFromNode(node) {\n var textNode = node || this.node;\n var childNodes = Array.from(textNode.parentNode.childNodes);\n var index = childNodes.indexOf(textNode);\n var lastIndex = childNodes.length - 1;\n var text = compressSpaces( // textNode.value\n // || textNode.text\n textNode.textContent || '');\n\n if (index === 0) {\n text = trimLeft(text);\n }\n\n if (index === lastIndex) {\n text = trimRight(text);\n }\n\n return text;\n }\n }, {\n key: \"renderChildren\",\n value: function renderChildren(ctx) {\n var _this3 = this;\n\n if (this.type !== 'text') {\n this.renderTElementChildren(ctx);\n return;\n } // first, calculate child positions\n\n\n this.initializeCoordinates();\n this.adjustChildCoordinatesRecursive(ctx); // then render\n\n this.children.forEach(function (_, i) {\n _this3.renderChild(ctx, _this3, _this3, i);\n });\n var mouse = this.document.screen.mouse; // Do not calc bounding box if mouse is not working.\n\n if (mouse.isWorking()) {\n mouse.checkBoundingBox(this, this.getBoundingBox(ctx));\n }\n }\n }, {\n key: \"renderTElementChildren\",\n value: function renderTElementChildren(ctx) {\n var document = this.document,\n parent = this.parent;\n var renderText = this.getText();\n var customFont = parent.getStyle('font-family').getDefinition();\n\n if (customFont) {\n var unitsPerEm = customFont.fontFace.unitsPerEm;\n var ctxFont = Font.parse(document.ctx.font);\n var fontSize = parent.getStyle('font-size').getNumber(ctxFont.fontSize);\n var fontStyle = parent.getStyle('font-style').getString(ctxFont.fontStyle);\n var scale = fontSize / unitsPerEm;\n var text = customFont.isRTL ? renderText.split('').reverse().join('') : renderText;\n var dx = toNumbers(parent.getAttribute('dx').getString());\n var len = text.length;\n\n for (var i = 0; i < len; i++) {\n var glyph = this.getGlyph(customFont, text, i);\n ctx.translate(this.x, this.y);\n ctx.scale(scale, -scale);\n var lw = ctx.lineWidth;\n ctx.lineWidth = ctx.lineWidth * unitsPerEm / fontSize;\n\n if (fontStyle === 'italic') {\n ctx.transform(1, 0, .4, 1, 0, 0);\n }\n\n glyph.render(ctx);\n\n if (fontStyle === 'italic') {\n ctx.transform(1, 0, -.4, 1, 0, 0);\n }\n\n ctx.lineWidth = lw;\n ctx.scale(1 / scale, -1 / scale);\n ctx.translate(-this.x, -this.y);\n this.x += fontSize * (glyph.horizAdvX || customFont.horizAdvX) / unitsPerEm;\n\n if (typeof dx[i] !== 'undefined' && !isNaN(dx[i])) {\n this.x += dx[i];\n }\n }\n\n return;\n }\n\n var x = this.x,\n y = this.y; // NEED TEST\n // if (ctx.paintOrder === 'stroke') {\n // \tif (ctx.strokeStyle) {\n // \t\tctx.strokeText(renderText, x, y);\n // \t}\n // \tif (ctx.fillStyle) {\n // \t\tctx.fillText(renderText, x, y);\n // \t}\n // } else {\n\n if (ctx.fillStyle) {\n ctx.fillText(renderText, x, y);\n }\n\n if (ctx.strokeStyle) {\n ctx.strokeText(renderText, x, y);\n } // }\n\n }\n }, {\n key: \"applyAnchoring\",\n value: function applyAnchoring() {\n if (this.textChunkStart >= this.leafTexts.length) {\n return;\n } // This is basically the \"Apply anchoring\" part of https://www.w3.org/TR/SVG2/text.html#TextLayoutAlgorithm.\n // The difference is that we apply the anchoring as soon as a chunk is finished. This saves some extra looping.\n // Vertical text is not supported.\n\n\n var firstElement = this.leafTexts[this.textChunkStart];\n var textAnchor = firstElement.getStyle('text-anchor').getString('start');\n var isRTL = false; // we treat RTL like LTR\n\n var shift = 0;\n\n if (textAnchor === 'start' && !isRTL || textAnchor === 'end' && isRTL) {\n shift = firstElement.x - this.minX;\n } else if (textAnchor === 'end' && !isRTL || textAnchor === 'start' && isRTL) {\n shift = firstElement.x - this.maxX;\n } else {\n shift = firstElement.x - (this.minX + this.maxX) / 2;\n }\n\n for (var i = this.textChunkStart; i < this.leafTexts.length; i++) {\n this.leafTexts[i].x += shift;\n } // start new chunk\n\n\n this.minX = Number.POSITIVE_INFINITY;\n this.maxX = Number.NEGATIVE_INFINITY;\n this.textChunkStart = this.leafTexts.length;\n }\n }, {\n key: \"adjustChildCoordinatesRecursive\",\n value: function adjustChildCoordinatesRecursive(ctx) {\n var _this4 = this;\n\n this.children.forEach(function (_, i) {\n _this4.adjustChildCoordinatesRecursiveCore(ctx, _this4, _this4, i);\n });\n this.applyAnchoring();\n }\n }, {\n key: \"adjustChildCoordinatesRecursiveCore\",\n value: function adjustChildCoordinatesRecursiveCore(ctx, textParent, parent, i) {\n var child = parent.children[i];\n\n if (child.children.length > 0) {\n child.children.forEach(function (_, i) {\n textParent.adjustChildCoordinatesRecursiveCore(ctx, textParent, child, i);\n });\n } else {\n // only leafs are relevant\n this.adjustChildCoordinates(ctx, textParent, parent, i);\n }\n }\n }, {\n key: \"adjustChildCoordinates\",\n value: function adjustChildCoordinates(ctx, textParent, parent, i) {\n var child = parent.children[i];\n\n if (typeof child.measureText !== 'function') {\n return child;\n }\n\n ctx.save();\n child.setContext(ctx, true);\n var xAttr = child.getAttribute('x');\n var yAttr = child.getAttribute('y');\n var dxAttr = child.getAttribute('dx');\n var dyAttr = child.getAttribute('dy');\n var customFont = child.getStyle('font-family').getDefinition();\n var isRTL = Boolean(customFont) && customFont.isRTL;\n\n if (i === 0) {\n // First children inherit attributes from parent(s). Positional attributes\n // are only inherited from a parent to it's first child.\n if (!xAttr.hasValue()) {\n xAttr.setValue(child.getInheritedAttribute('x'));\n }\n\n if (!yAttr.hasValue()) {\n yAttr.setValue(child.getInheritedAttribute('y'));\n }\n\n if (!dxAttr.hasValue()) {\n dxAttr.setValue(child.getInheritedAttribute('dx'));\n }\n\n if (!dyAttr.hasValue()) {\n dyAttr.setValue(child.getInheritedAttribute('dy'));\n }\n }\n\n var width = child.measureText(ctx);\n\n if (isRTL) {\n textParent.x -= width;\n }\n\n if (xAttr.hasValue()) {\n // an \"x\" attribute marks the start of a new chunk\n textParent.applyAnchoring();\n child.x = xAttr.getPixels('x');\n\n if (dxAttr.hasValue()) {\n child.x += dxAttr.getPixels('x');\n }\n } else {\n if (dxAttr.hasValue()) {\n textParent.x += dxAttr.getPixels('x');\n }\n\n child.x = textParent.x;\n }\n\n textParent.x = child.x;\n\n if (!isRTL) {\n textParent.x += width;\n }\n\n if (yAttr.hasValue()) {\n child.y = yAttr.getPixels('y');\n\n if (dyAttr.hasValue()) {\n child.y += dyAttr.getPixels('y');\n }\n } else {\n if (dyAttr.hasValue()) {\n textParent.y += dyAttr.getPixels('y');\n }\n\n child.y = textParent.y;\n }\n\n textParent.y = child.y; // update the current chunk and it's bounds\n\n textParent.leafTexts.push(child);\n textParent.minX = Math.min(textParent.minX, child.x, child.x + width);\n textParent.maxX = Math.max(textParent.maxX, child.x, child.x + width);\n child.clearContext(ctx);\n ctx.restore();\n return child;\n }\n }, {\n key: \"getChildBoundingBox\",\n value: function getChildBoundingBox(ctx, textParent, parent, i) {\n var child = parent.children[i]; // not a text node?\n\n if (typeof child.getBoundingBox !== 'function') {\n return null;\n }\n\n var boundingBox = child.getBoundingBox(ctx);\n\n if (!boundingBox) {\n return null;\n }\n\n child.children.forEach(function (_, i) {\n var childBoundingBox = textParent.getChildBoundingBox(ctx, textParent, child, i);\n boundingBox.addBoundingBox(childBoundingBox);\n });\n return boundingBox;\n }\n }, {\n key: \"renderChild\",\n value: function renderChild(ctx, textParent, parent, i) {\n var child = parent.children[i];\n child.render(ctx);\n child.children.forEach(function (_, i) {\n textParent.renderChild(ctx, textParent, child, i);\n });\n }\n }, {\n key: \"measureText\",\n value: function measureText(ctx) {\n var measureCache = this.measureCache;\n\n if (~measureCache) {\n return measureCache;\n }\n\n var renderText = this.getText();\n var measure = this.measureTargetText(ctx, renderText);\n this.measureCache = measure;\n return measure;\n }\n }, {\n key: \"measureTargetText\",\n value: function measureTargetText(ctx, targetText) {\n if (!targetText.length) {\n return 0;\n }\n\n var parent = this.parent;\n var customFont = parent.getStyle('font-family').getDefinition();\n\n if (customFont) {\n var fontSize = this.getFontSize();\n var text = customFont.isRTL ? targetText.split('').reverse().join('') : targetText;\n var dx = toNumbers(parent.getAttribute('dx').getString());\n var len = text.length;\n var _measure = 0;\n\n for (var i = 0; i < len; i++) {\n var glyph = this.getGlyph(customFont, text, i);\n _measure += (glyph.horizAdvX || customFont.horizAdvX) * fontSize / customFont.fontFace.unitsPerEm;\n\n if (typeof dx[i] !== 'undefined' && !isNaN(dx[i])) {\n _measure += dx[i];\n }\n }\n\n return _measure;\n }\n\n if (!ctx.measureText) {\n return targetText.length * 10;\n }\n\n ctx.save();\n this.setContext(ctx, true);\n\n var _ctx$measureText = ctx.measureText(targetText),\n measure = _ctx$measureText.width;\n\n this.clearContext(ctx);\n ctx.restore();\n return measure;\n }\n /**\r\n * Inherits positional attributes from {@link TextElement} parent(s). Attributes\r\n * are only inherited from a parent to its first child.\r\n * @param name - The attribute name.\r\n * @returns The attribute value or null.\r\n */\n\n }, {\n key: \"getInheritedAttribute\",\n value: function getInheritedAttribute(name) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias,consistent-this\n var current = this;\n\n while (current instanceof TextElement && current.isFirstChild()) {\n var parentAttr = current.parent.getAttribute(name);\n\n if (parentAttr.hasValue(true)) {\n return parentAttr.getValue('0');\n }\n\n current = current.parent;\n }\n\n return null;\n }\n }]);\n\n return TextElement;\n}(RenderedElement);\n\nfunction _createSuper$D(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$D(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$D() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar TSpanElement = /*#__PURE__*/function (_TextElement) {\n _inherits__default[\"default\"](TSpanElement, _TextElement);\n\n var _super = _createSuper$D(TSpanElement);\n\n function TSpanElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, TSpanElement);\n\n _this = _super.call(this, document, node, (this instanceof TSpanElement ? this.constructor : void 0) === TSpanElement ? true : captureTextNodes);\n _this.type = 'tspan'; // if this node has children, then they own the text\n\n _this.text = _this.children.length > 0 ? '' : _this.getTextFromNode();\n return _this;\n }\n\n _createClass__default[\"default\"](TSpanElement, [{\n key: \"getText\",\n value: function getText() {\n return this.text;\n }\n }]);\n\n return TSpanElement;\n}(TextElement);\n\nfunction _createSuper$C(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$C(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$C() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar TextNode = /*#__PURE__*/function (_TSpanElement) {\n _inherits__default[\"default\"](TextNode, _TSpanElement);\n\n var _super = _createSuper$C(TextNode);\n\n function TextNode() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, TextNode);\n\n _this = _super.apply(this, arguments);\n _this.type = 'textNode';\n return _this;\n }\n\n return TextNode;\n}(TSpanElement);\n\nfunction _createSuper$B(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$B(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$B() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar SVGElement = /*#__PURE__*/function (_RenderedElement) {\n _inherits__default[\"default\"](SVGElement, _RenderedElement);\n\n var _super = _createSuper$B(SVGElement);\n\n function SVGElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, SVGElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'svg';\n _this.root = false;\n return _this;\n }\n\n _createClass__default[\"default\"](SVGElement, [{\n key: \"setContext\",\n value: function setContext(ctx) {\n var _this$node$parentNode;\n\n var document = this.document;\n var screen = document.screen,\n window = document.window;\n var canvas = ctx.canvas;\n screen.setDefaults(ctx);\n\n if (canvas.style && typeof ctx.font !== 'undefined' && window && typeof window.getComputedStyle !== 'undefined') {\n ctx.font = window.getComputedStyle(canvas).getPropertyValue('font');\n var fontSizeProp = new Property(document, 'fontSize', Font.parse(ctx.font).fontSize);\n\n if (fontSizeProp.hasValue()) {\n document.rootEmSize = fontSizeProp.getPixels('y');\n document.emSize = document.rootEmSize;\n }\n } // create new view port\n\n\n if (!this.getAttribute('x').hasValue()) {\n this.getAttribute('x', true).setValue(0);\n }\n\n if (!this.getAttribute('y').hasValue()) {\n this.getAttribute('y', true).setValue(0);\n }\n\n var _screen$viewPort = screen.viewPort,\n width = _screen$viewPort.width,\n height = _screen$viewPort.height;\n\n if (!this.getStyle('width').hasValue()) {\n this.getStyle('width', true).setValue('100%');\n }\n\n if (!this.getStyle('height').hasValue()) {\n this.getStyle('height', true).setValue('100%');\n }\n\n if (!this.getStyle('color').hasValue()) {\n this.getStyle('color', true).setValue('black');\n }\n\n var refXAttr = this.getAttribute('refX');\n var refYAttr = this.getAttribute('refY');\n var viewBoxAttr = this.getAttribute('viewBox');\n var viewBox = viewBoxAttr.hasValue() ? toNumbers(viewBoxAttr.getString()) : null;\n var clip = !this.root && this.getStyle('overflow').getValue('hidden') !== 'visible';\n var minX = 0;\n var minY = 0;\n var clipX = 0;\n var clipY = 0;\n\n if (viewBox) {\n minX = viewBox[0];\n minY = viewBox[1];\n }\n\n if (!this.root) {\n width = this.getStyle('width').getPixels('x');\n height = this.getStyle('height').getPixels('y');\n\n if (this.type === 'marker') {\n clipX = minX;\n clipY = minY;\n minX = 0;\n minY = 0;\n }\n }\n\n screen.viewPort.setCurrent(width, height); // Default value of transform-origin is center only for root SVG elements\n // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform-origin\n\n if (this.node // is not temporary SVGElement\n && (!this.parent || ((_this$node$parentNode = this.node.parentNode) === null || _this$node$parentNode === void 0 ? void 0 : _this$node$parentNode.nodeName) === 'foreignObject') && this.getStyle('transform', false, true).hasValue() && !this.getStyle('transform-origin', false, true).hasValue()) {\n this.getStyle('transform-origin', true, true).setValue('50% 50%');\n }\n\n _get__default[\"default\"](_getPrototypeOf__default[\"default\"](SVGElement.prototype), \"setContext\", this).call(this, ctx);\n\n ctx.translate(this.getAttribute('x').getPixels('x'), this.getAttribute('y').getPixels('y'));\n\n if (viewBox) {\n width = viewBox[2];\n height = viewBox[3];\n }\n\n document.setViewBox({\n ctx: ctx,\n aspectRatio: this.getAttribute('preserveAspectRatio').getString(),\n width: screen.viewPort.width,\n desiredWidth: width,\n height: screen.viewPort.height,\n desiredHeight: height,\n minX: minX,\n minY: minY,\n refX: refXAttr.getValue(),\n refY: refYAttr.getValue(),\n clip: clip,\n clipX: clipX,\n clipY: clipY\n });\n\n if (viewBox) {\n screen.viewPort.removeCurrent();\n screen.viewPort.setCurrent(width, height);\n }\n }\n }, {\n key: \"clearContext\",\n value: function clearContext(ctx) {\n _get__default[\"default\"](_getPrototypeOf__default[\"default\"](SVGElement.prototype), \"clearContext\", this).call(this, ctx);\n\n this.document.screen.viewPort.removeCurrent();\n }\n /**\r\n * Resize SVG to fit in given size.\r\n * @param width\r\n * @param height\r\n * @param preserveAspectRatio\r\n */\n\n }, {\n key: \"resize\",\n value: function resize(width) {\n var height = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : width;\n var preserveAspectRatio = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n var widthAttr = this.getAttribute('width', true);\n var heightAttr = this.getAttribute('height', true);\n var viewBoxAttr = this.getAttribute('viewBox');\n var styleAttr = this.getAttribute('style');\n var originWidth = widthAttr.getNumber(0);\n var originHeight = heightAttr.getNumber(0);\n\n if (preserveAspectRatio) {\n if (typeof preserveAspectRatio === 'string') {\n this.getAttribute('preserveAspectRatio', true).setValue(preserveAspectRatio);\n } else {\n var preserveAspectRatioAttr = this.getAttribute('preserveAspectRatio');\n\n if (preserveAspectRatioAttr.hasValue()) {\n preserveAspectRatioAttr.setValue(preserveAspectRatioAttr.getString().replace(/^\\s*(\\S.*\\S)\\s*$/, '$1'));\n }\n }\n }\n\n widthAttr.setValue(width);\n heightAttr.setValue(height);\n\n if (!viewBoxAttr.hasValue()) {\n viewBoxAttr.setValue(\"0 0 \".concat(originWidth || width, \" \").concat(originHeight || height));\n }\n\n if (styleAttr.hasValue()) {\n var widthStyle = this.getStyle('width');\n var heightStyle = this.getStyle('height');\n\n if (widthStyle.hasValue()) {\n widthStyle.setValue(\"\".concat(width, \"px\"));\n }\n\n if (heightStyle.hasValue()) {\n heightStyle.setValue(\"\".concat(height, \"px\"));\n }\n }\n }\n }]);\n\n return SVGElement;\n}(RenderedElement);\n\nfunction _createSuper$A(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$A(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$A() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar RectElement = /*#__PURE__*/function (_PathElement) {\n _inherits__default[\"default\"](RectElement, _PathElement);\n\n var _super = _createSuper$A(RectElement);\n\n function RectElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, RectElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'rect';\n return _this;\n }\n\n _createClass__default[\"default\"](RectElement, [{\n key: \"path\",\n value: function path(ctx) {\n var x = this.getAttribute('x').getPixels('x');\n var y = this.getAttribute('y').getPixels('y');\n var width = this.getStyle('width', false, true).getPixels('x');\n var height = this.getStyle('height', false, true).getPixels('y');\n var rxAttr = this.getAttribute('rx');\n var ryAttr = this.getAttribute('ry');\n var rx = rxAttr.getPixels('x');\n var ry = ryAttr.getPixels('y');\n\n if (rxAttr.hasValue() && !ryAttr.hasValue()) {\n ry = rx;\n }\n\n if (ryAttr.hasValue() && !rxAttr.hasValue()) {\n rx = ry;\n }\n\n rx = Math.min(rx, width / 2.0);\n ry = Math.min(ry, height / 2.0);\n\n if (ctx) {\n var KAPPA = 4 * ((Math.sqrt(2) - 1) / 3);\n ctx.beginPath(); // always start the path so we don't fill prior paths\n\n if (height > 0 && width > 0) {\n ctx.moveTo(x + rx, y);\n ctx.lineTo(x + width - rx, y);\n ctx.bezierCurveTo(x + width - rx + KAPPA * rx, y, x + width, y + ry - KAPPA * ry, x + width, y + ry);\n ctx.lineTo(x + width, y + height - ry);\n ctx.bezierCurveTo(x + width, y + height - ry + KAPPA * ry, x + width - rx + KAPPA * rx, y + height, x + width - rx, y + height);\n ctx.lineTo(x + rx, y + height);\n ctx.bezierCurveTo(x + rx - KAPPA * rx, y + height, x, y + height - ry + KAPPA * ry, x, y + height - ry);\n ctx.lineTo(x, y + ry);\n ctx.bezierCurveTo(x, y + ry - KAPPA * ry, x + rx - KAPPA * rx, y, x + rx, y);\n ctx.closePath();\n }\n }\n\n return new BoundingBox(x, y, x + width, y + height);\n }\n }, {\n key: \"getMarkers\",\n value: function getMarkers() {\n return null;\n }\n }]);\n\n return RectElement;\n}(PathElement);\n\nfunction _createSuper$z(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$z(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$z() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar CircleElement = /*#__PURE__*/function (_PathElement) {\n _inherits__default[\"default\"](CircleElement, _PathElement);\n\n var _super = _createSuper$z(CircleElement);\n\n function CircleElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, CircleElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'circle';\n return _this;\n }\n\n _createClass__default[\"default\"](CircleElement, [{\n key: \"path\",\n value: function path(ctx) {\n var cx = this.getAttribute('cx').getPixels('x');\n var cy = this.getAttribute('cy').getPixels('y');\n var r = this.getAttribute('r').getPixels();\n\n if (ctx && r > 0) {\n ctx.beginPath();\n ctx.arc(cx, cy, r, 0, Math.PI * 2, false);\n ctx.closePath();\n }\n\n return new BoundingBox(cx - r, cy - r, cx + r, cy + r);\n }\n }, {\n key: \"getMarkers\",\n value: function getMarkers() {\n return null;\n }\n }]);\n\n return CircleElement;\n}(PathElement);\n\nfunction _createSuper$y(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$y(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$y() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar EllipseElement = /*#__PURE__*/function (_PathElement) {\n _inherits__default[\"default\"](EllipseElement, _PathElement);\n\n var _super = _createSuper$y(EllipseElement);\n\n function EllipseElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, EllipseElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'ellipse';\n return _this;\n }\n\n _createClass__default[\"default\"](EllipseElement, [{\n key: \"path\",\n value: function path(ctx) {\n var KAPPA = 4 * ((Math.sqrt(2) - 1) / 3);\n var rx = this.getAttribute('rx').getPixels('x');\n var ry = this.getAttribute('ry').getPixels('y');\n var cx = this.getAttribute('cx').getPixels('x');\n var cy = this.getAttribute('cy').getPixels('y');\n\n if (ctx && rx > 0 && ry > 0) {\n ctx.beginPath();\n ctx.moveTo(cx + rx, cy);\n ctx.bezierCurveTo(cx + rx, cy + KAPPA * ry, cx + KAPPA * rx, cy + ry, cx, cy + ry);\n ctx.bezierCurveTo(cx - KAPPA * rx, cy + ry, cx - rx, cy + KAPPA * ry, cx - rx, cy);\n ctx.bezierCurveTo(cx - rx, cy - KAPPA * ry, cx - KAPPA * rx, cy - ry, cx, cy - ry);\n ctx.bezierCurveTo(cx + KAPPA * rx, cy - ry, cx + rx, cy - KAPPA * ry, cx + rx, cy);\n ctx.closePath();\n }\n\n return new BoundingBox(cx - rx, cy - ry, cx + rx, cy + ry);\n }\n }, {\n key: \"getMarkers\",\n value: function getMarkers() {\n return null;\n }\n }]);\n\n return EllipseElement;\n}(PathElement);\n\nfunction _createSuper$x(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$x(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$x() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar LineElement = /*#__PURE__*/function (_PathElement) {\n _inherits__default[\"default\"](LineElement, _PathElement);\n\n var _super = _createSuper$x(LineElement);\n\n function LineElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, LineElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'line';\n return _this;\n }\n\n _createClass__default[\"default\"](LineElement, [{\n key: \"getPoints\",\n value: function getPoints() {\n return [new Point(this.getAttribute('x1').getPixels('x'), this.getAttribute('y1').getPixels('y')), new Point(this.getAttribute('x2').getPixels('x'), this.getAttribute('y2').getPixels('y'))];\n }\n }, {\n key: \"path\",\n value: function path(ctx) {\n var _this$getPoints = this.getPoints(),\n _this$getPoints2 = _slicedToArray__default[\"default\"](_this$getPoints, 2),\n _this$getPoints2$ = _this$getPoints2[0],\n x0 = _this$getPoints2$.x,\n y0 = _this$getPoints2$.y,\n _this$getPoints2$2 = _this$getPoints2[1],\n x1 = _this$getPoints2$2.x,\n y1 = _this$getPoints2$2.y;\n\n if (ctx) {\n ctx.beginPath();\n ctx.moveTo(x0, y0);\n ctx.lineTo(x1, y1);\n }\n\n return new BoundingBox(x0, y0, x1, y1);\n }\n }, {\n key: \"getMarkers\",\n value: function getMarkers() {\n var _this$getPoints3 = this.getPoints(),\n _this$getPoints4 = _slicedToArray__default[\"default\"](_this$getPoints3, 2),\n p0 = _this$getPoints4[0],\n p1 = _this$getPoints4[1];\n\n var a = p0.angleTo(p1);\n return [[p0, a], [p1, a]];\n }\n }]);\n\n return LineElement;\n}(PathElement);\n\nfunction _createSuper$w(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$w(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$w() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar PolylineElement = /*#__PURE__*/function (_PathElement) {\n _inherits__default[\"default\"](PolylineElement, _PathElement);\n\n var _super = _createSuper$w(PolylineElement);\n\n function PolylineElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, PolylineElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'polyline';\n _this.points = [];\n _this.points = Point.parsePath(_this.getAttribute('points').getString());\n return _this;\n }\n\n _createClass__default[\"default\"](PolylineElement, [{\n key: \"path\",\n value: function path(ctx) {\n var points = this.points;\n\n var _points = _slicedToArray__default[\"default\"](points, 1),\n _points$ = _points[0],\n x0 = _points$.x,\n y0 = _points$.y;\n\n var boundingBox = new BoundingBox(x0, y0);\n\n if (ctx) {\n ctx.beginPath();\n ctx.moveTo(x0, y0);\n }\n\n points.forEach(function (_ref) {\n var x = _ref.x,\n y = _ref.y;\n boundingBox.addPoint(x, y);\n\n if (ctx) {\n ctx.lineTo(x, y);\n }\n });\n return boundingBox;\n }\n }, {\n key: \"getMarkers\",\n value: function getMarkers() {\n var points = this.points;\n var lastIndex = points.length - 1;\n var markers = [];\n points.forEach(function (point, i) {\n if (i === lastIndex) {\n return;\n }\n\n markers.push([point, point.angleTo(points[i + 1])]);\n });\n\n if (markers.length > 0) {\n markers.push([points[points.length - 1], markers[markers.length - 1][1]]);\n }\n\n return markers;\n }\n }]);\n\n return PolylineElement;\n}(PathElement);\n\nfunction _createSuper$v(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$v(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$v() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar PolygonElement = /*#__PURE__*/function (_PolylineElement) {\n _inherits__default[\"default\"](PolygonElement, _PolylineElement);\n\n var _super = _createSuper$v(PolygonElement);\n\n function PolygonElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, PolygonElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'polygon';\n return _this;\n }\n\n _createClass__default[\"default\"](PolygonElement, [{\n key: \"path\",\n value: function path(ctx) {\n var boundingBox = _get__default[\"default\"](_getPrototypeOf__default[\"default\"](PolygonElement.prototype), \"path\", this).call(this, ctx);\n\n var _this$points = _slicedToArray__default[\"default\"](this.points, 1),\n _this$points$ = _this$points[0],\n x = _this$points$.x,\n y = _this$points$.y;\n\n if (ctx) {\n ctx.lineTo(x, y);\n ctx.closePath();\n }\n\n return boundingBox;\n }\n }]);\n\n return PolygonElement;\n}(PolylineElement);\n\nfunction _createSuper$u(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$u(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$u() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar PatternElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](PatternElement, _Element);\n\n var _super = _createSuper$u(PatternElement);\n\n function PatternElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, PatternElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'pattern';\n return _this;\n }\n\n _createClass__default[\"default\"](PatternElement, [{\n key: \"createPattern\",\n value: function createPattern(ctx, _, parentOpacityProp) {\n var width = this.getStyle('width').getPixels('x', true);\n var height = this.getStyle('height').getPixels('y', true); // render me using a temporary svg element\n\n var patternSvg = new SVGElement(this.document, null);\n patternSvg.attributes.viewBox = new Property(this.document, 'viewBox', this.getAttribute('viewBox').getValue());\n patternSvg.attributes.width = new Property(this.document, 'width', \"\".concat(width, \"px\"));\n patternSvg.attributes.height = new Property(this.document, 'height', \"\".concat(height, \"px\"));\n patternSvg.attributes.transform = new Property(this.document, 'transform', this.getAttribute('patternTransform').getValue());\n patternSvg.children = this.children;\n var patternCanvas = this.document.createCanvas(width, height);\n var patternCtx = patternCanvas.getContext('2d');\n var xAttr = this.getAttribute('x');\n var yAttr = this.getAttribute('y');\n\n if (xAttr.hasValue() && yAttr.hasValue()) {\n patternCtx.translate(xAttr.getPixels('x', true), yAttr.getPixels('y', true));\n }\n\n if (parentOpacityProp.hasValue()) {\n this.styles['fill-opacity'] = parentOpacityProp;\n } else {\n Reflect.deleteProperty(this.styles, 'fill-opacity');\n } // render 3x3 grid so when we transform there's no white space on edges\n\n\n for (var x = -1; x <= 1; x++) {\n for (var y = -1; y <= 1; y++) {\n patternCtx.save();\n patternSvg.attributes.x = new Property(this.document, 'x', x * patternCanvas.width);\n patternSvg.attributes.y = new Property(this.document, 'y', y * patternCanvas.height);\n patternSvg.render(patternCtx);\n patternCtx.restore();\n }\n }\n\n var pattern = ctx.createPattern(patternCanvas, 'repeat');\n return pattern;\n }\n }]);\n\n return PatternElement;\n}(Element);\n\nfunction _createSuper$t(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$t(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$t() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar MarkerElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](MarkerElement, _Element);\n\n var _super = _createSuper$t(MarkerElement);\n\n function MarkerElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, MarkerElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'marker';\n return _this;\n }\n\n _createClass__default[\"default\"](MarkerElement, [{\n key: \"render\",\n value: function render(ctx, point, angle) {\n if (!point) {\n return;\n }\n\n var x = point.x,\n y = point.y;\n var orient = this.getAttribute('orient').getString('auto');\n var markerUnits = this.getAttribute('markerUnits').getString('strokeWidth');\n ctx.translate(x, y);\n\n if (orient === 'auto') {\n ctx.rotate(angle);\n }\n\n if (markerUnits === 'strokeWidth') {\n ctx.scale(ctx.lineWidth, ctx.lineWidth);\n }\n\n ctx.save(); // render me using a temporary svg element\n\n var markerSvg = new SVGElement(this.document, null);\n markerSvg.type = this.type;\n markerSvg.attributes.viewBox = new Property(this.document, 'viewBox', this.getAttribute('viewBox').getValue());\n markerSvg.attributes.refX = new Property(this.document, 'refX', this.getAttribute('refX').getValue());\n markerSvg.attributes.refY = new Property(this.document, 'refY', this.getAttribute('refY').getValue());\n markerSvg.attributes.width = new Property(this.document, 'width', this.getAttribute('markerWidth').getValue());\n markerSvg.attributes.height = new Property(this.document, 'height', this.getAttribute('markerHeight').getValue());\n markerSvg.attributes.overflow = new Property(this.document, 'overflow', this.getAttribute('overflow').getValue());\n markerSvg.attributes.fill = new Property(this.document, 'fill', this.getAttribute('fill').getColor('black'));\n markerSvg.attributes.stroke = new Property(this.document, 'stroke', this.getAttribute('stroke').getValue('none'));\n markerSvg.children = this.children;\n markerSvg.render(ctx);\n ctx.restore();\n\n if (markerUnits === 'strokeWidth') {\n ctx.scale(1 / ctx.lineWidth, 1 / ctx.lineWidth);\n }\n\n if (orient === 'auto') {\n ctx.rotate(-angle);\n }\n\n ctx.translate(-x, -y);\n }\n }]);\n\n return MarkerElement;\n}(Element);\n\nfunction _createSuper$s(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$s(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$s() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar DefsElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](DefsElement, _Element);\n\n var _super = _createSuper$s(DefsElement);\n\n function DefsElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, DefsElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'defs';\n return _this;\n }\n\n _createClass__default[\"default\"](DefsElement, [{\n key: \"render\",\n value: function render() {// NOOP\n }\n }]);\n\n return DefsElement;\n}(Element);\n\nfunction _createSuper$r(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$r(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$r() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar GElement = /*#__PURE__*/function (_RenderedElement) {\n _inherits__default[\"default\"](GElement, _RenderedElement);\n\n var _super = _createSuper$r(GElement);\n\n function GElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, GElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'g';\n return _this;\n }\n\n _createClass__default[\"default\"](GElement, [{\n key: \"getBoundingBox\",\n value: function getBoundingBox(ctx) {\n var boundingBox = new BoundingBox();\n this.children.forEach(function (child) {\n boundingBox.addBoundingBox(child.getBoundingBox(ctx));\n });\n return boundingBox;\n }\n }]);\n\n return GElement;\n}(RenderedElement);\n\nfunction _createSuper$q(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$q(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$q() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar GradientElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](GradientElement, _Element);\n\n var _super = _createSuper$q(GradientElement);\n\n function GradientElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, GradientElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.attributesToInherit = ['gradientUnits'];\n _this.stops = [];\n\n var _assertThisInitialize = _assertThisInitialized__default[\"default\"](_this),\n stops = _assertThisInitialize.stops,\n children = _assertThisInitialize.children;\n\n children.forEach(function (child) {\n if (child.type === 'stop') {\n stops.push(child);\n }\n });\n return _this;\n }\n\n _createClass__default[\"default\"](GradientElement, [{\n key: \"getGradientUnits\",\n value: function getGradientUnits() {\n return this.getAttribute('gradientUnits').getString('objectBoundingBox');\n }\n }, {\n key: \"createGradient\",\n value: function createGradient(ctx, element, parentOpacityProp) {\n var _this2 = this;\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n var stopsContainer = this;\n\n if (this.getHrefAttribute().hasValue()) {\n stopsContainer = this.getHrefAttribute().getDefinition();\n this.inheritStopContainer(stopsContainer);\n }\n\n var _stopsContainer = stopsContainer,\n stops = _stopsContainer.stops;\n var gradient = this.getGradient(ctx, element);\n\n if (!gradient) {\n return this.addParentOpacity(parentOpacityProp, stops[stops.length - 1].color);\n }\n\n stops.forEach(function (stop) {\n gradient.addColorStop(stop.offset, _this2.addParentOpacity(parentOpacityProp, stop.color));\n });\n\n if (this.getAttribute('gradientTransform').hasValue()) {\n // render as transformed pattern on temporary canvas\n var document = this.document;\n var _document$screen = document.screen,\n MAX_VIRTUAL_PIXELS = _document$screen.MAX_VIRTUAL_PIXELS,\n viewPort = _document$screen.viewPort;\n\n var _viewPort$viewPorts = _slicedToArray__default[\"default\"](viewPort.viewPorts, 1),\n rootView = _viewPort$viewPorts[0];\n\n var rect = new RectElement(document, null);\n rect.attributes.x = new Property(document, 'x', -MAX_VIRTUAL_PIXELS / 3.0);\n rect.attributes.y = new Property(document, 'y', -MAX_VIRTUAL_PIXELS / 3.0);\n rect.attributes.width = new Property(document, 'width', MAX_VIRTUAL_PIXELS);\n rect.attributes.height = new Property(document, 'height', MAX_VIRTUAL_PIXELS);\n var group = new GElement(document, null);\n group.attributes.transform = new Property(document, 'transform', this.getAttribute('gradientTransform').getValue());\n group.children = [rect];\n var patternSvg = new SVGElement(document, null);\n patternSvg.attributes.x = new Property(document, 'x', 0);\n patternSvg.attributes.y = new Property(document, 'y', 0);\n patternSvg.attributes.width = new Property(document, 'width', rootView.width);\n patternSvg.attributes.height = new Property(document, 'height', rootView.height);\n patternSvg.children = [group];\n var patternCanvas = document.createCanvas(rootView.width, rootView.height);\n var patternCtx = patternCanvas.getContext('2d');\n patternCtx.fillStyle = gradient;\n patternSvg.render(patternCtx);\n return patternCtx.createPattern(patternCanvas, 'no-repeat');\n }\n\n return gradient;\n }\n }, {\n key: \"inheritStopContainer\",\n value: function inheritStopContainer(stopsContainer) {\n var _this3 = this;\n\n this.attributesToInherit.forEach(function (attributeToInherit) {\n if (!_this3.getAttribute(attributeToInherit).hasValue() && stopsContainer.getAttribute(attributeToInherit).hasValue()) {\n _this3.getAttribute(attributeToInherit, true).setValue(stopsContainer.getAttribute(attributeToInherit).getValue());\n }\n });\n }\n }, {\n key: \"addParentOpacity\",\n value: function addParentOpacity(parentOpacityProp, color) {\n if (parentOpacityProp.hasValue()) {\n var colorProp = new Property(this.document, 'color', color);\n return colorProp.addOpacity(parentOpacityProp).getColor();\n }\n\n return color;\n }\n }]);\n\n return GradientElement;\n}(Element);\n\nfunction _createSuper$p(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$p(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$p() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar LinearGradientElement = /*#__PURE__*/function (_GradientElement) {\n _inherits__default[\"default\"](LinearGradientElement, _GradientElement);\n\n var _super = _createSuper$p(LinearGradientElement);\n\n function LinearGradientElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, LinearGradientElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'linearGradient';\n\n _this.attributesToInherit.push('x1', 'y1', 'x2', 'y2');\n\n return _this;\n }\n\n _createClass__default[\"default\"](LinearGradientElement, [{\n key: \"getGradient\",\n value: function getGradient(ctx, element) {\n var isBoundingBoxUnits = this.getGradientUnits() === 'objectBoundingBox';\n var boundingBox = isBoundingBoxUnits ? element.getBoundingBox(ctx) : null;\n\n if (isBoundingBoxUnits && !boundingBox) {\n return null;\n }\n\n if (!this.getAttribute('x1').hasValue() && !this.getAttribute('y1').hasValue() && !this.getAttribute('x2').hasValue() && !this.getAttribute('y2').hasValue()) {\n this.getAttribute('x1', true).setValue(0);\n this.getAttribute('y1', true).setValue(0);\n this.getAttribute('x2', true).setValue(1);\n this.getAttribute('y2', true).setValue(0);\n }\n\n var x1 = isBoundingBoxUnits ? boundingBox.x + boundingBox.width * this.getAttribute('x1').getNumber() : this.getAttribute('x1').getPixels('x');\n var y1 = isBoundingBoxUnits ? boundingBox.y + boundingBox.height * this.getAttribute('y1').getNumber() : this.getAttribute('y1').getPixels('y');\n var x2 = isBoundingBoxUnits ? boundingBox.x + boundingBox.width * this.getAttribute('x2').getNumber() : this.getAttribute('x2').getPixels('x');\n var y2 = isBoundingBoxUnits ? boundingBox.y + boundingBox.height * this.getAttribute('y2').getNumber() : this.getAttribute('y2').getPixels('y');\n\n if (x1 === x2 && y1 === y2) {\n return null;\n }\n\n return ctx.createLinearGradient(x1, y1, x2, y2);\n }\n }]);\n\n return LinearGradientElement;\n}(GradientElement);\n\nfunction _createSuper$o(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$o(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$o() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar RadialGradientElement = /*#__PURE__*/function (_GradientElement) {\n _inherits__default[\"default\"](RadialGradientElement, _GradientElement);\n\n var _super = _createSuper$o(RadialGradientElement);\n\n function RadialGradientElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, RadialGradientElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'radialGradient';\n\n _this.attributesToInherit.push('cx', 'cy', 'r', 'fx', 'fy', 'fr');\n\n return _this;\n }\n\n _createClass__default[\"default\"](RadialGradientElement, [{\n key: \"getGradient\",\n value: function getGradient(ctx, element) {\n var isBoundingBoxUnits = this.getGradientUnits() === 'objectBoundingBox';\n var boundingBox = element.getBoundingBox(ctx);\n\n if (isBoundingBoxUnits && !boundingBox) {\n return null;\n }\n\n if (!this.getAttribute('cx').hasValue()) {\n this.getAttribute('cx', true).setValue('50%');\n }\n\n if (!this.getAttribute('cy').hasValue()) {\n this.getAttribute('cy', true).setValue('50%');\n }\n\n if (!this.getAttribute('r').hasValue()) {\n this.getAttribute('r', true).setValue('50%');\n }\n\n var cx = isBoundingBoxUnits ? boundingBox.x + boundingBox.width * this.getAttribute('cx').getNumber() : this.getAttribute('cx').getPixels('x');\n var cy = isBoundingBoxUnits ? boundingBox.y + boundingBox.height * this.getAttribute('cy').getNumber() : this.getAttribute('cy').getPixels('y');\n var fx = cx;\n var fy = cy;\n\n if (this.getAttribute('fx').hasValue()) {\n fx = isBoundingBoxUnits ? boundingBox.x + boundingBox.width * this.getAttribute('fx').getNumber() : this.getAttribute('fx').getPixels('x');\n }\n\n if (this.getAttribute('fy').hasValue()) {\n fy = isBoundingBoxUnits ? boundingBox.y + boundingBox.height * this.getAttribute('fy').getNumber() : this.getAttribute('fy').getPixels('y');\n }\n\n var r = isBoundingBoxUnits ? (boundingBox.width + boundingBox.height) / 2.0 * this.getAttribute('r').getNumber() : this.getAttribute('r').getPixels();\n var fr = this.getAttribute('fr').getPixels();\n return ctx.createRadialGradient(fx, fy, fr, cx, cy, r);\n }\n }]);\n\n return RadialGradientElement;\n}(GradientElement);\n\nfunction _createSuper$n(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$n(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$n() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar StopElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](StopElement, _Element);\n\n var _super = _createSuper$n(StopElement);\n\n function StopElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, StopElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'stop';\n var offset = Math.max(0, Math.min(1, _this.getAttribute('offset').getNumber()));\n\n var stopOpacity = _this.getStyle('stop-opacity');\n\n var stopColor = _this.getStyle('stop-color', true);\n\n if (stopColor.getString() === '') {\n stopColor.setValue('#000');\n }\n\n if (stopOpacity.hasValue()) {\n stopColor = stopColor.addOpacity(stopOpacity);\n }\n\n _this.offset = offset;\n _this.color = stopColor.getColor();\n return _this;\n }\n\n return StopElement;\n}(Element);\n\nfunction _createSuper$m(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$m(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$m() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar AnimateElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](AnimateElement, _Element);\n\n var _super = _createSuper$m(AnimateElement);\n\n function AnimateElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, AnimateElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'animate';\n _this.duration = 0;\n _this.initialValue = null;\n _this.initialUnits = '';\n _this.removed = false;\n _this.frozen = false;\n document.screen.animations.push(_assertThisInitialized__default[\"default\"](_this));\n _this.begin = _this.getAttribute('begin').getMilliseconds();\n _this.maxDuration = _this.begin + _this.getAttribute('dur').getMilliseconds();\n _this.from = _this.getAttribute('from');\n _this.to = _this.getAttribute('to');\n _this.values = new Property(document, 'values', null);\n\n var valuesAttr = _this.getAttribute('values');\n\n if (valuesAttr.hasValue()) {\n _this.values.setValue(valuesAttr.getString().split(';'));\n }\n\n return _this;\n }\n\n _createClass__default[\"default\"](AnimateElement, [{\n key: \"getProperty\",\n value: function getProperty() {\n var attributeType = this.getAttribute('attributeType').getString();\n var attributeName = this.getAttribute('attributeName').getString();\n\n if (attributeType === 'CSS') {\n return this.parent.getStyle(attributeName, true);\n }\n\n return this.parent.getAttribute(attributeName, true);\n }\n }, {\n key: \"calcValue\",\n value: function calcValue() {\n var initialUnits = this.initialUnits;\n\n var _this$getProgress = this.getProgress(),\n progress = _this$getProgress.progress,\n from = _this$getProgress.from,\n to = _this$getProgress.to; // tween value linearly\n\n\n var newValue = from.getNumber() + (to.getNumber() - from.getNumber()) * progress;\n\n if (initialUnits === '%') {\n newValue *= 100.0; // numValue() returns 0-1 whereas properties are 0-100\n }\n\n return \"\".concat(newValue).concat(initialUnits);\n }\n }, {\n key: \"update\",\n value: function update(delta) {\n var parent = this.parent;\n var prop = this.getProperty(); // set initial value\n\n if (!this.initialValue) {\n this.initialValue = prop.getString();\n this.initialUnits = prop.getUnits();\n } // if we're past the end time\n\n\n if (this.duration > this.maxDuration) {\n var fill = this.getAttribute('fill').getString('remove'); // loop for indefinitely repeating animations\n\n if (this.getAttribute('repeatCount').getString() === 'indefinite' || this.getAttribute('repeatDur').getString() === 'indefinite') {\n this.duration = 0;\n } else if (fill === 'freeze' && !this.frozen) {\n this.frozen = true;\n parent.animationFrozen = true;\n parent.animationFrozenValue = prop.getString();\n } else if (fill === 'remove' && !this.removed) {\n this.removed = true;\n prop.setValue(parent.animationFrozen ? parent.animationFrozenValue : this.initialValue);\n return true;\n }\n\n return false;\n }\n\n this.duration += delta; // if we're past the begin time\n\n var updated = false;\n\n if (this.begin < this.duration) {\n var newValue = this.calcValue(); // tween\n\n var typeAttr = this.getAttribute('type');\n\n if (typeAttr.hasValue()) {\n // for transform, etc.\n var type = typeAttr.getString();\n newValue = \"\".concat(type, \"(\").concat(newValue, \")\");\n }\n\n prop.setValue(newValue);\n updated = true;\n }\n\n return updated;\n }\n }, {\n key: \"getProgress\",\n value: function getProgress() {\n var document = this.document,\n values = this.values;\n var result = {\n progress: (this.duration - this.begin) / (this.maxDuration - this.begin)\n };\n\n if (values.hasValue()) {\n var p = result.progress * (values.getValue().length - 1);\n var lb = Math.floor(p);\n var ub = Math.ceil(p);\n result.from = new Property(document, 'from', parseFloat(values.getValue()[lb]));\n result.to = new Property(document, 'to', parseFloat(values.getValue()[ub]));\n result.progress = (p - lb) / (ub - lb);\n } else {\n result.from = this.from;\n result.to = this.to;\n }\n\n return result;\n }\n }]);\n\n return AnimateElement;\n}(Element);\n\nfunction _createSuper$l(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$l(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$l() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar AnimateColorElement = /*#__PURE__*/function (_AnimateElement) {\n _inherits__default[\"default\"](AnimateColorElement, _AnimateElement);\n\n var _super = _createSuper$l(AnimateColorElement);\n\n function AnimateColorElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, AnimateColorElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'animateColor';\n return _this;\n }\n\n _createClass__default[\"default\"](AnimateColorElement, [{\n key: \"calcValue\",\n value: function calcValue() {\n var _this$getProgress = this.getProgress(),\n progress = _this$getProgress.progress,\n from = _this$getProgress.from,\n to = _this$getProgress.to;\n\n var colorFrom = new RGBColor__default[\"default\"](from.getColor());\n var colorTo = new RGBColor__default[\"default\"](to.getColor());\n\n if (colorFrom.ok && colorTo.ok) {\n // tween color linearly\n var r = colorFrom.r + (colorTo.r - colorFrom.r) * progress;\n var g = colorFrom.g + (colorTo.g - colorFrom.g) * progress;\n var b = colorFrom.b + (colorTo.b - colorFrom.b) * progress; // ? alpha\n\n return \"rgb(\".concat(Math.floor(r), \", \").concat(Math.floor(g), \", \").concat(Math.floor(b), \")\");\n }\n\n return this.getAttribute('from').getColor();\n }\n }]);\n\n return AnimateColorElement;\n}(AnimateElement);\n\nfunction _createSuper$k(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$k(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$k() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar AnimateTransformElement = /*#__PURE__*/function (_AnimateElement) {\n _inherits__default[\"default\"](AnimateTransformElement, _AnimateElement);\n\n var _super = _createSuper$k(AnimateTransformElement);\n\n function AnimateTransformElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, AnimateTransformElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'animateTransform';\n return _this;\n }\n\n _createClass__default[\"default\"](AnimateTransformElement, [{\n key: \"calcValue\",\n value: function calcValue() {\n var _this$getProgress = this.getProgress(),\n progress = _this$getProgress.progress,\n from = _this$getProgress.from,\n to = _this$getProgress.to; // tween value linearly\n\n\n var transformFrom = toNumbers(from.getString());\n var transformTo = toNumbers(to.getString());\n var newValue = transformFrom.map(function (from, i) {\n var to = transformTo[i];\n return from + (to - from) * progress;\n }).join(' ');\n return newValue;\n }\n }]);\n\n return AnimateTransformElement;\n}(AnimateElement);\n\nfunction _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== \"undefined\" && o[Symbol.iterator] || o[\"@@iterator\"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray$1(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen); }\n\nfunction _arrayLikeToArray$1(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _createSuper$j(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$j(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$j() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar FontElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](FontElement, _Element);\n\n var _super = _createSuper$j(FontElement);\n\n function FontElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, FontElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'font';\n _this.glyphs = Object.create(null);\n _this.horizAdvX = _this.getAttribute('horiz-adv-x').getNumber();\n var definitions = document.definitions;\n\n var _assertThisInitialize = _assertThisInitialized__default[\"default\"](_this),\n children = _assertThisInitialize.children;\n\n var _iterator = _createForOfIteratorHelper$1(children),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var child = _step.value;\n\n switch (child.type) {\n case 'font-face':\n {\n _this.fontFace = child;\n var fontFamilyStyle = child.getStyle('font-family');\n\n if (fontFamilyStyle.hasValue()) {\n definitions[fontFamilyStyle.getString()] = _assertThisInitialized__default[\"default\"](_this);\n }\n\n break;\n }\n\n case 'missing-glyph':\n _this.missingGlyph = child;\n break;\n\n case 'glyph':\n {\n var glyph = child;\n\n if (glyph.arabicForm) {\n _this.isRTL = true;\n _this.isArabic = true;\n\n if (typeof _this.glyphs[glyph.unicode] === 'undefined') {\n _this.glyphs[glyph.unicode] = Object.create(null);\n }\n\n _this.glyphs[glyph.unicode][glyph.arabicForm] = glyph;\n } else {\n _this.glyphs[glyph.unicode] = glyph;\n }\n\n break;\n }\n\n default:\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n return _this;\n }\n\n _createClass__default[\"default\"](FontElement, [{\n key: \"render\",\n value: function render() {// NO RENDER\n }\n }]);\n\n return FontElement;\n}(Element);\n\nfunction _createSuper$i(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$i(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$i() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar FontFaceElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](FontFaceElement, _Element);\n\n var _super = _createSuper$i(FontFaceElement);\n\n function FontFaceElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, FontFaceElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'font-face';\n _this.ascent = _this.getAttribute('ascent').getNumber();\n _this.descent = _this.getAttribute('descent').getNumber();\n _this.unitsPerEm = _this.getAttribute('units-per-em').getNumber();\n return _this;\n }\n\n return FontFaceElement;\n}(Element);\n\nfunction _createSuper$h(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$h(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$h() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar MissingGlyphElement = /*#__PURE__*/function (_PathElement) {\n _inherits__default[\"default\"](MissingGlyphElement, _PathElement);\n\n var _super = _createSuper$h(MissingGlyphElement);\n\n function MissingGlyphElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, MissingGlyphElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'missing-glyph';\n _this.horizAdvX = 0;\n return _this;\n }\n\n return MissingGlyphElement;\n}(PathElement);\n\nfunction _createSuper$g(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$g(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$g() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar TRefElement = /*#__PURE__*/function (_TextElement) {\n _inherits__default[\"default\"](TRefElement, _TextElement);\n\n var _super = _createSuper$g(TRefElement);\n\n function TRefElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, TRefElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'tref';\n return _this;\n }\n\n _createClass__default[\"default\"](TRefElement, [{\n key: \"getText\",\n value: function getText() {\n var element = this.getHrefAttribute().getDefinition();\n\n if (element) {\n var firstChild = element.children[0];\n\n if (firstChild) {\n return firstChild.getText();\n }\n }\n\n return '';\n }\n }]);\n\n return TRefElement;\n}(TextElement);\n\nfunction _createSuper$f(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$f(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$f() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar AElement = /*#__PURE__*/function (_TextElement) {\n _inherits__default[\"default\"](AElement, _TextElement);\n\n var _super = _createSuper$f(AElement);\n\n function AElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, AElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'a';\n var childNodes = node.childNodes;\n var firstChild = childNodes[0];\n var hasText = childNodes.length > 0 && Array.from(childNodes).every(function (node) {\n return node.nodeType === 3;\n });\n _this.hasText = hasText;\n _this.text = hasText ? _this.getTextFromNode(firstChild) : '';\n return _this;\n }\n\n _createClass__default[\"default\"](AElement, [{\n key: \"getText\",\n value: function getText() {\n return this.text;\n }\n }, {\n key: \"renderChildren\",\n value: function renderChildren(ctx) {\n if (this.hasText) {\n // render as text element\n _get__default[\"default\"](_getPrototypeOf__default[\"default\"](AElement.prototype), \"renderChildren\", this).call(this, ctx);\n\n var document = this.document,\n x = this.x,\n y = this.y;\n var mouse = document.screen.mouse;\n var fontSize = new Property(document, 'fontSize', Font.parse(document.ctx.font).fontSize); // Do not calc bounding box if mouse is not working.\n\n if (mouse.isWorking()) {\n mouse.checkBoundingBox(this, new BoundingBox(x, y - fontSize.getPixels('y'), x + this.measureText(ctx), y));\n }\n } else if (this.children.length > 0) {\n // render as temporary group\n var g = new GElement(this.document, null);\n g.children = this.children;\n g.parent = this;\n g.render(ctx);\n }\n }\n }, {\n key: \"onClick\",\n value: function onClick() {\n var window = this.document.window;\n\n if (window) {\n window.open(this.getHrefAttribute().getString());\n }\n }\n }, {\n key: \"onMouseMove\",\n value: function onMouseMove() {\n var ctx = this.document.ctx;\n ctx.canvas.style.cursor = 'pointer';\n }\n }]);\n\n return AElement;\n}(TextElement);\n\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== \"undefined\" && o[Symbol.iterator] || o[\"@@iterator\"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction ownKeys$2(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$2(Object(source), true).forEach(function (key) { _defineProperty__default[\"default\"](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$2(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _createSuper$e(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$e(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$e() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar TextPathElement = /*#__PURE__*/function (_TextElement) {\n _inherits__default[\"default\"](TextPathElement, _TextElement);\n\n var _super = _createSuper$e(TextPathElement);\n\n function TextPathElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, TextPathElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'textPath';\n _this.textWidth = 0;\n _this.textHeight = 0;\n _this.pathLength = -1;\n _this.glyphInfo = null;\n _this.letterSpacingCache = [];\n _this.measuresCache = new Map([['', 0]]);\n\n var pathElement = _this.getHrefAttribute().getDefinition();\n\n _this.text = _this.getTextFromNode();\n _this.dataArray = _this.parsePathData(pathElement);\n return _this;\n }\n\n _createClass__default[\"default\"](TextPathElement, [{\n key: \"getText\",\n value: function getText() {\n return this.text;\n }\n }, {\n key: \"path\",\n value: function path(ctx) {\n var dataArray = this.dataArray;\n\n if (ctx) {\n ctx.beginPath();\n }\n\n dataArray.forEach(function (_ref) {\n var type = _ref.type,\n points = _ref.points;\n\n switch (type) {\n case PathParser.LINE_TO:\n if (ctx) {\n ctx.lineTo(points[0], points[1]);\n }\n\n break;\n\n case PathParser.MOVE_TO:\n if (ctx) {\n ctx.moveTo(points[0], points[1]);\n }\n\n break;\n\n case PathParser.CURVE_TO:\n if (ctx) {\n ctx.bezierCurveTo(points[0], points[1], points[2], points[3], points[4], points[5]);\n }\n\n break;\n\n case PathParser.QUAD_TO:\n if (ctx) {\n ctx.quadraticCurveTo(points[0], points[1], points[2], points[3]);\n }\n\n break;\n\n case PathParser.ARC:\n {\n var _points = _slicedToArray__default[\"default\"](points, 8),\n cx = _points[0],\n cy = _points[1],\n rx = _points[2],\n ry = _points[3],\n theta = _points[4],\n dTheta = _points[5],\n psi = _points[6],\n fs = _points[7];\n\n var r = rx > ry ? rx : ry;\n var scaleX = rx > ry ? 1 : rx / ry;\n var scaleY = rx > ry ? ry / rx : 1;\n\n if (ctx) {\n ctx.translate(cx, cy);\n ctx.rotate(psi);\n ctx.scale(scaleX, scaleY);\n ctx.arc(0, 0, r, theta, theta + dTheta, Boolean(1 - fs));\n ctx.scale(1 / scaleX, 1 / scaleY);\n ctx.rotate(-psi);\n ctx.translate(-cx, -cy);\n }\n\n break;\n }\n\n case PathParser.CLOSE_PATH:\n if (ctx) {\n ctx.closePath();\n }\n\n break;\n }\n });\n }\n }, {\n key: \"renderChildren\",\n value: function renderChildren(ctx) {\n this.setTextData(ctx);\n ctx.save();\n var textDecoration = this.parent.getStyle('text-decoration').getString();\n var fontSize = this.getFontSize();\n var glyphInfo = this.glyphInfo;\n var fill = ctx.fillStyle;\n\n if (textDecoration === 'underline') {\n ctx.beginPath();\n }\n\n glyphInfo.forEach(function (glyph, i) {\n var p0 = glyph.p0,\n p1 = glyph.p1,\n rotation = glyph.rotation,\n partialText = glyph.text;\n ctx.save();\n ctx.translate(p0.x, p0.y);\n ctx.rotate(rotation);\n\n if (ctx.fillStyle) {\n ctx.fillText(partialText, 0, 0);\n }\n\n if (ctx.strokeStyle) {\n ctx.strokeText(partialText, 0, 0);\n }\n\n ctx.restore();\n\n if (textDecoration === 'underline') {\n if (i === 0) {\n ctx.moveTo(p0.x, p0.y + fontSize / 8);\n }\n\n ctx.lineTo(p1.x, p1.y + fontSize / 5);\n } // // To assist with debugging visually, uncomment following\n //\n // ctx.beginPath();\n // if (i % 2)\n // \tctx.strokeStyle = 'red';\n // else\n // \tctx.strokeStyle = 'green';\n // ctx.moveTo(p0.x, p0.y);\n // ctx.lineTo(p1.x, p1.y);\n // ctx.stroke();\n // ctx.closePath();\n\n });\n\n if (textDecoration === 'underline') {\n ctx.lineWidth = fontSize / 20;\n ctx.strokeStyle = fill;\n ctx.stroke();\n ctx.closePath();\n }\n\n ctx.restore();\n }\n }, {\n key: \"getLetterSpacingAt\",\n value: function getLetterSpacingAt() {\n var idx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;\n return this.letterSpacingCache[idx] || 0;\n }\n }, {\n key: \"findSegmentToFitChar\",\n value: function findSegmentToFitChar(ctx, anchor, textFullWidth, fullPathWidth, spacesNumber, inputOffset, dy, c, charI) {\n var offset = inputOffset;\n var glyphWidth = this.measureText(ctx, c);\n\n if (c === ' ' && anchor === 'justify' && textFullWidth < fullPathWidth) {\n glyphWidth += (fullPathWidth - textFullWidth) / spacesNumber;\n }\n\n if (charI > -1) {\n offset += this.getLetterSpacingAt(charI);\n }\n\n var splineStep = this.textHeight / 20;\n var p0 = this.getEquidistantPointOnPath(offset, splineStep, 0);\n var p1 = this.getEquidistantPointOnPath(offset + glyphWidth, splineStep, 0);\n var segment = {\n p0: p0,\n p1: p1\n };\n var rotation = p0 && p1 ? Math.atan2(p1.y - p0.y, p1.x - p0.x) : 0;\n\n if (dy) {\n var dyX = Math.cos(Math.PI / 2 + rotation) * dy;\n var dyY = Math.cos(-rotation) * dy;\n segment.p0 = _objectSpread$2(_objectSpread$2({}, p0), {}, {\n x: p0.x + dyX,\n y: p0.y + dyY\n });\n segment.p1 = _objectSpread$2(_objectSpread$2({}, p1), {}, {\n x: p1.x + dyX,\n y: p1.y + dyY\n });\n }\n\n offset += glyphWidth;\n return {\n offset: offset,\n segment: segment,\n rotation: rotation\n };\n }\n }, {\n key: \"measureText\",\n value: function measureText(ctx, text) {\n var measuresCache = this.measuresCache;\n var targetText = text || this.getText();\n\n if (measuresCache.has(targetText)) {\n return measuresCache.get(targetText);\n }\n\n var measure = this.measureTargetText(ctx, targetText);\n measuresCache.set(targetText, measure);\n return measure;\n } // This method supposes what all custom fonts already loaded.\n // If some font will be loaded after this method call, <textPath> will not be rendered correctly.\n // You need to call this method manually to update glyphs cache.\n\n }, {\n key: \"setTextData\",\n value: function setTextData(ctx) {\n var _this2 = this;\n\n if (this.glyphInfo) {\n return;\n }\n\n var renderText = this.getText();\n var chars = renderText.split('');\n var spacesNumber = renderText.split(' ').length - 1;\n var dx = this.parent.getAttribute('dx').split().map(function (_) {\n return _.getPixels('x');\n });\n var dy = this.parent.getAttribute('dy').getPixels('y');\n var anchor = this.parent.getStyle('text-anchor').getString('start');\n var thisSpacing = this.getStyle('letter-spacing');\n var parentSpacing = this.parent.getStyle('letter-spacing');\n var letterSpacing = 0;\n\n if (!thisSpacing.hasValue() || thisSpacing.getValue() === 'inherit') {\n letterSpacing = parentSpacing.getPixels();\n } else if (thisSpacing.hasValue()) {\n if (thisSpacing.getValue() !== 'initial' && thisSpacing.getValue() !== 'unset') {\n letterSpacing = thisSpacing.getPixels();\n }\n } // fill letter-spacing cache\n\n\n var letterSpacingCache = [];\n var textLen = renderText.length;\n this.letterSpacingCache = letterSpacingCache;\n\n for (var i = 0; i < textLen; i++) {\n letterSpacingCache.push(typeof dx[i] !== 'undefined' ? dx[i] : letterSpacing);\n }\n\n var dxSum = letterSpacingCache.reduce(function (acc, cur, i) {\n return i === 0 ? 0 : acc + cur || 0;\n }, 0);\n var textWidth = this.measureText(ctx);\n var textFullWidth = Math.max(textWidth + dxSum, 0);\n this.textWidth = textWidth;\n this.textHeight = this.getFontSize();\n this.glyphInfo = [];\n var fullPathWidth = this.getPathLength();\n var startOffset = this.getStyle('startOffset').getNumber(0) * fullPathWidth;\n var offset = 0;\n\n if (anchor === 'middle' || anchor === 'center') {\n offset = -textFullWidth / 2;\n }\n\n if (anchor === 'end' || anchor === 'right') {\n offset = -textFullWidth;\n }\n\n offset += startOffset;\n chars.forEach(function (char, i) {\n // Find such segment what distance between p0 and p1 is approx. width of glyph\n var _this2$findSegmentToF = _this2.findSegmentToFitChar(ctx, anchor, textFullWidth, fullPathWidth, spacesNumber, offset, dy, char, i),\n nextOffset = _this2$findSegmentToF.offset,\n segment = _this2$findSegmentToF.segment,\n rotation = _this2$findSegmentToF.rotation;\n\n offset = nextOffset;\n\n if (!segment.p0 || !segment.p1) {\n return;\n } // const width = this.getLineLength(\n // \tsegment.p0.x,\n // \tsegment.p0.y,\n // \tsegment.p1.x,\n // \tsegment.p1.y\n // );\n // Note: Since glyphs are rendered one at a time, any kerning pair data built into the font will not be used.\n // Can foresee having a rough pair table built in that the developer can override as needed.\n // Or use \"dx\" attribute of the <text> node as a naive replacement\n // const kern = 0;\n // placeholder for future implementation\n // const midpoint = this.getPointOnLine(\n // \tkern + width / 2.0,\n // \tsegment.p0.x, segment.p0.y, segment.p1.x, segment.p1.y\n // );\n\n\n _this2.glyphInfo.push({\n // transposeX: midpoint.x,\n // transposeY: midpoint.y,\n text: chars[i],\n p0: segment.p0,\n p1: segment.p1,\n rotation: rotation\n });\n });\n }\n }, {\n key: \"parsePathData\",\n value: function parsePathData(path) {\n this.pathLength = -1; // reset path length\n\n if (!path) {\n return [];\n }\n\n var pathCommands = [];\n var pathParser = path.pathParser;\n pathParser.reset(); // convert l, H, h, V, and v to L\n\n while (!pathParser.isEnd()) {\n var current = pathParser.current;\n var startX = current ? current.x : 0;\n var startY = current ? current.y : 0;\n var command = pathParser.next();\n var nextCommandType = command.type;\n var points = [];\n\n switch (command.type) {\n case PathParser.MOVE_TO:\n this.pathM(pathParser, points);\n break;\n\n case PathParser.LINE_TO:\n nextCommandType = this.pathL(pathParser, points);\n break;\n\n case PathParser.HORIZ_LINE_TO:\n nextCommandType = this.pathH(pathParser, points);\n break;\n\n case PathParser.VERT_LINE_TO:\n nextCommandType = this.pathV(pathParser, points);\n break;\n\n case PathParser.CURVE_TO:\n this.pathC(pathParser, points);\n break;\n\n case PathParser.SMOOTH_CURVE_TO:\n nextCommandType = this.pathS(pathParser, points);\n break;\n\n case PathParser.QUAD_TO:\n this.pathQ(pathParser, points);\n break;\n\n case PathParser.SMOOTH_QUAD_TO:\n nextCommandType = this.pathT(pathParser, points);\n break;\n\n case PathParser.ARC:\n points = this.pathA(pathParser);\n break;\n\n case PathParser.CLOSE_PATH:\n PathElement.pathZ(pathParser);\n break;\n }\n\n if (command.type !== PathParser.CLOSE_PATH) {\n pathCommands.push({\n type: nextCommandType,\n points: points,\n start: {\n x: startX,\n y: startY\n },\n pathLength: this.calcLength(startX, startY, nextCommandType, points)\n });\n } else {\n pathCommands.push({\n type: PathParser.CLOSE_PATH,\n points: [],\n pathLength: 0\n });\n }\n }\n\n return pathCommands;\n }\n }, {\n key: \"pathM\",\n value: function pathM(pathParser, points) {\n var _PathElement$pathM$po = PathElement.pathM(pathParser).point,\n x = _PathElement$pathM$po.x,\n y = _PathElement$pathM$po.y;\n points.push(x, y);\n }\n }, {\n key: \"pathL\",\n value: function pathL(pathParser, points) {\n var _PathElement$pathL$po = PathElement.pathL(pathParser).point,\n x = _PathElement$pathL$po.x,\n y = _PathElement$pathL$po.y;\n points.push(x, y);\n return PathParser.LINE_TO;\n }\n }, {\n key: \"pathH\",\n value: function pathH(pathParser, points) {\n var _PathElement$pathH$po = PathElement.pathH(pathParser).point,\n x = _PathElement$pathH$po.x,\n y = _PathElement$pathH$po.y;\n points.push(x, y);\n return PathParser.LINE_TO;\n }\n }, {\n key: \"pathV\",\n value: function pathV(pathParser, points) {\n var _PathElement$pathV$po = PathElement.pathV(pathParser).point,\n x = _PathElement$pathV$po.x,\n y = _PathElement$pathV$po.y;\n points.push(x, y);\n return PathParser.LINE_TO;\n }\n }, {\n key: \"pathC\",\n value: function pathC(pathParser, points) {\n var _PathElement$pathC = PathElement.pathC(pathParser),\n point = _PathElement$pathC.point,\n controlPoint = _PathElement$pathC.controlPoint,\n currentPoint = _PathElement$pathC.currentPoint;\n\n points.push(point.x, point.y, controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n }\n }, {\n key: \"pathS\",\n value: function pathS(pathParser, points) {\n var _PathElement$pathS = PathElement.pathS(pathParser),\n point = _PathElement$pathS.point,\n controlPoint = _PathElement$pathS.controlPoint,\n currentPoint = _PathElement$pathS.currentPoint;\n\n points.push(point.x, point.y, controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n return PathParser.CURVE_TO;\n }\n }, {\n key: \"pathQ\",\n value: function pathQ(pathParser, points) {\n var _PathElement$pathQ = PathElement.pathQ(pathParser),\n controlPoint = _PathElement$pathQ.controlPoint,\n currentPoint = _PathElement$pathQ.currentPoint;\n\n points.push(controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n }\n }, {\n key: \"pathT\",\n value: function pathT(pathParser, points) {\n var _PathElement$pathT = PathElement.pathT(pathParser),\n controlPoint = _PathElement$pathT.controlPoint,\n currentPoint = _PathElement$pathT.currentPoint;\n\n points.push(controlPoint.x, controlPoint.y, currentPoint.x, currentPoint.y);\n return PathParser.QUAD_TO;\n }\n }, {\n key: \"pathA\",\n value: function pathA(pathParser) {\n var _PathElement$pathA = PathElement.pathA(pathParser),\n rX = _PathElement$pathA.rX,\n rY = _PathElement$pathA.rY,\n sweepFlag = _PathElement$pathA.sweepFlag,\n xAxisRotation = _PathElement$pathA.xAxisRotation,\n centp = _PathElement$pathA.centp,\n a1 = _PathElement$pathA.a1,\n ad = _PathElement$pathA.ad;\n\n if (sweepFlag === 0 && ad > 0) {\n ad -= 2 * Math.PI;\n }\n\n if (sweepFlag === 1 && ad < 0) {\n ad += 2 * Math.PI;\n }\n\n return [centp.x, centp.y, rX, rY, a1, ad, xAxisRotation, sweepFlag];\n }\n }, {\n key: \"calcLength\",\n value: function calcLength(x, y, commandType, points) {\n var len = 0;\n var p1 = null;\n var p2 = null;\n var t = 0;\n\n switch (commandType) {\n case PathParser.LINE_TO:\n return this.getLineLength(x, y, points[0], points[1]);\n\n case PathParser.CURVE_TO:\n // Approximates by breaking curve into 100 line segments\n len = 0.0;\n p1 = this.getPointOnCubicBezier(0, x, y, points[0], points[1], points[2], points[3], points[4], points[5]);\n\n for (t = 0.01; t <= 1; t += 0.01) {\n p2 = this.getPointOnCubicBezier(t, x, y, points[0], points[1], points[2], points[3], points[4], points[5]);\n len += this.getLineLength(p1.x, p1.y, p2.x, p2.y);\n p1 = p2;\n }\n\n return len;\n\n case PathParser.QUAD_TO:\n // Approximates by breaking curve into 100 line segments\n len = 0.0;\n p1 = this.getPointOnQuadraticBezier(0, x, y, points[0], points[1], points[2], points[3]);\n\n for (t = 0.01; t <= 1; t += 0.01) {\n p2 = this.getPointOnQuadraticBezier(t, x, y, points[0], points[1], points[2], points[3]);\n len += this.getLineLength(p1.x, p1.y, p2.x, p2.y);\n p1 = p2;\n }\n\n return len;\n\n case PathParser.ARC:\n {\n // Approximates by breaking curve into line segments\n len = 0.0;\n var start = points[4]; // 4 = theta\n\n var dTheta = points[5]; // 5 = dTheta\n\n var end = points[4] + dTheta;\n var inc = Math.PI / 180.0; // 1 degree resolution\n\n if (Math.abs(start - end) < inc) {\n inc = Math.abs(start - end);\n } // Note: for purpose of calculating arc length, not going to worry about rotating X-axis by angle psi\n\n\n p1 = this.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], start, 0);\n\n if (dTheta < 0) {\n // clockwise\n for (t = start - inc; t > end; t -= inc) {\n p2 = this.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], t, 0);\n len += this.getLineLength(p1.x, p1.y, p2.x, p2.y);\n p1 = p2;\n }\n } else {\n // counter-clockwise\n for (t = start + inc; t < end; t += inc) {\n p2 = this.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], t, 0);\n len += this.getLineLength(p1.x, p1.y, p2.x, p2.y);\n p1 = p2;\n }\n }\n\n p2 = this.getPointOnEllipticalArc(points[0], points[1], points[2], points[3], end, 0);\n len += this.getLineLength(p1.x, p1.y, p2.x, p2.y);\n return len;\n }\n }\n\n return 0;\n }\n }, {\n key: \"getPointOnLine\",\n value: function getPointOnLine(dist, p1x, p1y, p2x, p2y) {\n var fromX = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : p1x;\n var fromY = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : p1y;\n var m = (p2y - p1y) / (p2x - p1x + PSEUDO_ZERO);\n var run = Math.sqrt(dist * dist / (1 + m * m));\n\n if (p2x < p1x) {\n run *= -1;\n }\n\n var rise = m * run;\n var pt = null;\n\n if (p2x === p1x) {\n // vertical line\n pt = {\n x: fromX,\n y: fromY + rise\n };\n } else if ((fromY - p1y) / (fromX - p1x + PSEUDO_ZERO) === m) {\n pt = {\n x: fromX + run,\n y: fromY + rise\n };\n } else {\n var ix = 0;\n var iy = 0;\n var len = this.getLineLength(p1x, p1y, p2x, p2y);\n\n if (len < PSEUDO_ZERO) {\n return null;\n }\n\n var u = (fromX - p1x) * (p2x - p1x) + (fromY - p1y) * (p2y - p1y);\n u /= len * len;\n ix = p1x + u * (p2x - p1x);\n iy = p1y + u * (p2y - p1y);\n var pRise = this.getLineLength(fromX, fromY, ix, iy);\n var pRun = Math.sqrt(dist * dist - pRise * pRise);\n run = Math.sqrt(pRun * pRun / (1 + m * m));\n\n if (p2x < p1x) {\n run *= -1;\n }\n\n rise = m * run;\n pt = {\n x: ix + run,\n y: iy + rise\n };\n }\n\n return pt;\n }\n }, {\n key: \"getPointOnPath\",\n value: function getPointOnPath(distance) {\n var fullLen = this.getPathLength();\n var cumulativePathLength = 0;\n var p = null;\n\n if (distance < -0.00005 || distance - 0.00005 > fullLen) {\n return null;\n }\n\n var dataArray = this.dataArray;\n\n var _iterator = _createForOfIteratorHelper(dataArray),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var command = _step.value;\n\n if (command && (command.pathLength < 0.00005 || cumulativePathLength + command.pathLength + 0.00005 < distance)) {\n cumulativePathLength += command.pathLength;\n continue;\n }\n\n var delta = distance - cumulativePathLength;\n var currentT = 0;\n\n switch (command.type) {\n case PathParser.LINE_TO:\n p = this.getPointOnLine(delta, command.start.x, command.start.y, command.points[0], command.points[1], command.start.x, command.start.y);\n break;\n\n case PathParser.ARC:\n {\n var start = command.points[4]; // 4 = theta\n\n var dTheta = command.points[5]; // 5 = dTheta\n\n var end = command.points[4] + dTheta;\n currentT = start + delta / command.pathLength * dTheta;\n\n if (dTheta < 0 && currentT < end || dTheta >= 0 && currentT > end) {\n break;\n }\n\n p = this.getPointOnEllipticalArc(command.points[0], command.points[1], command.points[2], command.points[3], currentT, command.points[6]);\n break;\n }\n\n case PathParser.CURVE_TO:\n currentT = delta / command.pathLength;\n\n if (currentT > 1) {\n currentT = 1;\n }\n\n p = this.getPointOnCubicBezier(currentT, command.start.x, command.start.y, command.points[0], command.points[1], command.points[2], command.points[3], command.points[4], command.points[5]);\n break;\n\n case PathParser.QUAD_TO:\n currentT = delta / command.pathLength;\n\n if (currentT > 1) {\n currentT = 1;\n }\n\n p = this.getPointOnQuadraticBezier(currentT, command.start.x, command.start.y, command.points[0], command.points[1], command.points[2], command.points[3]);\n break;\n\n default:\n }\n\n if (p) {\n return p;\n }\n\n break;\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n return null;\n }\n }, {\n key: \"getLineLength\",\n value: function getLineLength(x1, y1, x2, y2) {\n return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n }\n }, {\n key: \"getPathLength\",\n value: function getPathLength() {\n if (this.pathLength === -1) {\n this.pathLength = this.dataArray.reduce(function (length, command) {\n return command.pathLength > 0 ? length + command.pathLength : length;\n }, 0);\n }\n\n return this.pathLength;\n }\n }, {\n key: \"getPointOnCubicBezier\",\n value: function getPointOnCubicBezier(pct, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) {\n var x = p4x * CB1(pct) + p3x * CB2(pct) + p2x * CB3(pct) + p1x * CB4(pct);\n var y = p4y * CB1(pct) + p3y * CB2(pct) + p2y * CB3(pct) + p1y * CB4(pct);\n return {\n x: x,\n y: y\n };\n }\n }, {\n key: \"getPointOnQuadraticBezier\",\n value: function getPointOnQuadraticBezier(pct, p1x, p1y, p2x, p2y, p3x, p3y) {\n var x = p3x * QB1(pct) + p2x * QB2(pct) + p1x * QB3(pct);\n var y = p3y * QB1(pct) + p2y * QB2(pct) + p1y * QB3(pct);\n return {\n x: x,\n y: y\n };\n }\n }, {\n key: \"getPointOnEllipticalArc\",\n value: function getPointOnEllipticalArc(cx, cy, rx, ry, theta, psi) {\n var cosPsi = Math.cos(psi);\n var sinPsi = Math.sin(psi);\n var pt = {\n x: rx * Math.cos(theta),\n y: ry * Math.sin(theta)\n };\n return {\n x: cx + (pt.x * cosPsi - pt.y * sinPsi),\n y: cy + (pt.x * sinPsi + pt.y * cosPsi)\n };\n } // TODO need some optimisations. possibly build cache only for curved segments?\n\n }, {\n key: \"buildEquidistantCache\",\n value: function buildEquidistantCache(inputStep, inputPrecision) {\n var fullLen = this.getPathLength();\n var precision = inputPrecision || 0.25; // accuracy vs performance\n\n var step = inputStep || fullLen / 100;\n\n if (!this.equidistantCache || this.equidistantCache.step !== step || this.equidistantCache.precision !== precision) {\n // Prepare cache\n this.equidistantCache = {\n step: step,\n precision: precision,\n points: []\n }; // Calculate points\n\n var s = 0;\n\n for (var l = 0; l <= fullLen; l += precision) {\n var p0 = this.getPointOnPath(l);\n var p1 = this.getPointOnPath(l + precision);\n\n if (!p0 || !p1) {\n continue;\n }\n\n s += this.getLineLength(p0.x, p0.y, p1.x, p1.y);\n\n if (s >= step) {\n this.equidistantCache.points.push({\n x: p0.x,\n y: p0.y,\n distance: l\n });\n s -= step;\n }\n }\n }\n }\n }, {\n key: \"getEquidistantPointOnPath\",\n value: function getEquidistantPointOnPath(targetDistance, step, precision) {\n this.buildEquidistantCache(step, precision);\n\n if (targetDistance < 0 || targetDistance - this.getPathLength() > 0.00005) {\n return null;\n }\n\n var idx = Math.round(targetDistance / this.getPathLength() * (this.equidistantCache.points.length - 1));\n return this.equidistantCache.points[idx] || null;\n }\n }]);\n\n return TextPathElement;\n}(TextElement);\n\nfunction _createSuper$d(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$d(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$d() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar dataUriRegex = /^\\s*data:(([^/,;]+\\/[^/,;]+)(?:;([^,;=]+=[^,;=]+))?)?(?:;(base64))?,(.*)$/i;\n\nvar ImageElement = /*#__PURE__*/function (_RenderedElement) {\n _inherits__default[\"default\"](ImageElement, _RenderedElement);\n\n var _super = _createSuper$d(ImageElement);\n\n function ImageElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, ImageElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'image';\n _this.loaded = false;\n\n var href = _this.getHrefAttribute().getString();\n\n if (!href) {\n return _possibleConstructorReturn__default[\"default\"](_this);\n }\n\n var isSvg = href.endsWith('.svg') || /^\\s*data:image\\/svg\\+xml/i.test(href);\n document.images.push(_assertThisInitialized__default[\"default\"](_this));\n\n if (!isSvg) {\n void _this.loadImage(href);\n } else {\n void _this.loadSvg(href);\n }\n\n _this.isSvg = isSvg;\n return _this;\n }\n\n _createClass__default[\"default\"](ImageElement, [{\n key: \"loadImage\",\n value: function () {\n var _loadImage = _asyncToGenerator__default[\"default\"]( /*#__PURE__*/_regeneratorRuntime__default[\"default\"].mark(function _callee(href) {\n var image;\n return _regeneratorRuntime__default[\"default\"].wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _context.prev = 0;\n _context.next = 3;\n return this.document.createImage(href);\n\n case 3:\n image = _context.sent;\n this.image = image;\n _context.next = 10;\n break;\n\n case 7:\n _context.prev = 7;\n _context.t0 = _context[\"catch\"](0);\n console.error(\"Error while loading image \\\"\".concat(href, \"\\\":\"), _context.t0);\n\n case 10:\n this.loaded = true;\n\n case 11:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, this, [[0, 7]]);\n }));\n\n function loadImage(_x) {\n return _loadImage.apply(this, arguments);\n }\n\n return loadImage;\n }()\n }, {\n key: \"loadSvg\",\n value: function () {\n var _loadSvg = _asyncToGenerator__default[\"default\"]( /*#__PURE__*/_regeneratorRuntime__default[\"default\"].mark(function _callee2(href) {\n var match, data, response, svg;\n return _regeneratorRuntime__default[\"default\"].wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n match = dataUriRegex.exec(href);\n\n if (!match) {\n _context2.next = 6;\n break;\n }\n\n data = match[5];\n\n if (match[4] === 'base64') {\n this.image = atob(data);\n } else {\n this.image = decodeURIComponent(data);\n }\n\n _context2.next = 19;\n break;\n\n case 6:\n _context2.prev = 6;\n _context2.next = 9;\n return this.document.fetch(href);\n\n case 9:\n response = _context2.sent;\n _context2.next = 12;\n return response.text();\n\n case 12:\n svg = _context2.sent;\n this.image = svg;\n _context2.next = 19;\n break;\n\n case 16:\n _context2.prev = 16;\n _context2.t0 = _context2[\"catch\"](6);\n console.error(\"Error while loading image \\\"\".concat(href, \"\\\":\"), _context2.t0);\n\n case 19:\n this.loaded = true;\n\n case 20:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _callee2, this, [[6, 16]]);\n }));\n\n function loadSvg(_x2) {\n return _loadSvg.apply(this, arguments);\n }\n\n return loadSvg;\n }()\n }, {\n key: \"renderChildren\",\n value: function renderChildren(ctx) {\n var document = this.document,\n image = this.image,\n loaded = this.loaded;\n var x = this.getAttribute('x').getPixels('x');\n var y = this.getAttribute('y').getPixels('y');\n var width = this.getStyle('width').getPixels('x');\n var height = this.getStyle('height').getPixels('y');\n\n if (!loaded || !image || !width || !height) {\n return;\n }\n\n ctx.save();\n ctx.translate(x, y);\n\n if (this.isSvg) {\n var subDocument = document.canvg.forkString(ctx, this.image, {\n ignoreMouse: true,\n ignoreAnimation: true,\n ignoreDimensions: true,\n ignoreClear: true,\n offsetX: 0,\n offsetY: 0,\n scaleWidth: width,\n scaleHeight: height\n });\n subDocument.document.documentElement.parent = this;\n void subDocument.render();\n } else {\n var _image = this.image;\n document.setViewBox({\n ctx: ctx,\n aspectRatio: this.getAttribute('preserveAspectRatio').getString(),\n width: width,\n desiredWidth: _image.width,\n height: height,\n desiredHeight: _image.height\n });\n\n if (this.loaded) {\n if (typeof _image.complete === 'undefined' || _image.complete) {\n ctx.drawImage(_image, 0, 0);\n }\n }\n }\n\n ctx.restore();\n }\n }, {\n key: \"getBoundingBox\",\n value: function getBoundingBox() {\n var x = this.getAttribute('x').getPixels('x');\n var y = this.getAttribute('y').getPixels('y');\n var width = this.getStyle('width').getPixels('x');\n var height = this.getStyle('height').getPixels('y');\n return new BoundingBox(x, y, x + width, y + height);\n }\n }]);\n\n return ImageElement;\n}(RenderedElement);\n\nfunction _createSuper$c(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$c(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$c() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar SymbolElement = /*#__PURE__*/function (_RenderedElement) {\n _inherits__default[\"default\"](SymbolElement, _RenderedElement);\n\n var _super = _createSuper$c(SymbolElement);\n\n function SymbolElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, SymbolElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'symbol';\n return _this;\n }\n\n _createClass__default[\"default\"](SymbolElement, [{\n key: \"render\",\n value: function render(_) {// NO RENDER\n }\n }]);\n\n return SymbolElement;\n}(RenderedElement);\n\nvar SVGFontLoader = /*#__PURE__*/function () {\n function SVGFontLoader(document) {\n _classCallCheck__default[\"default\"](this, SVGFontLoader);\n\n this.document = document;\n this.loaded = false;\n document.fonts.push(this);\n }\n\n _createClass__default[\"default\"](SVGFontLoader, [{\n key: \"load\",\n value: function () {\n var _load = _asyncToGenerator__default[\"default\"]( /*#__PURE__*/_regeneratorRuntime__default[\"default\"].mark(function _callee(fontFamily, url) {\n var document, svgDocument, fonts;\n return _regeneratorRuntime__default[\"default\"].wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _context.prev = 0;\n document = this.document;\n _context.next = 4;\n return document.canvg.parser.load(url);\n\n case 4:\n svgDocument = _context.sent;\n fonts = svgDocument.getElementsByTagName('font');\n Array.from(fonts).forEach(function (fontNode) {\n var font = document.createElement(fontNode);\n document.definitions[fontFamily] = font;\n });\n _context.next = 12;\n break;\n\n case 9:\n _context.prev = 9;\n _context.t0 = _context[\"catch\"](0);\n console.error(\"Error while loading font \\\"\".concat(url, \"\\\":\"), _context.t0);\n\n case 12:\n this.loaded = true;\n\n case 13:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, this, [[0, 9]]);\n }));\n\n function load(_x, _x2) {\n return _load.apply(this, arguments);\n }\n\n return load;\n }()\n }]);\n\n return SVGFontLoader;\n}();\n\nfunction _createSuper$b(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$b(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$b() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar StyleElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](StyleElement, _Element);\n\n var _super = _createSuper$b(StyleElement);\n\n function StyleElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, StyleElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'style';\n var css = compressSpaces(Array.from(node.childNodes) // NEED TEST\n .map(function (_) {\n return _.textContent;\n }).join('').replace(/(\\/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+\\/)|(^[\\s]*\\/\\/.*)/gm, '') // remove comments\n .replace(/@import.*;/g, '') // remove imports\n );\n var cssDefs = css.split('}');\n cssDefs.forEach(function (_) {\n var def = _.trim();\n\n if (!def) {\n return;\n }\n\n var cssParts = def.split('{');\n var cssClasses = cssParts[0].split(',');\n var cssProps = cssParts[1].split(';');\n cssClasses.forEach(function (_) {\n var cssClass = _.trim();\n\n if (!cssClass) {\n return;\n }\n\n var props = document.styles[cssClass] || {};\n cssProps.forEach(function (cssProp) {\n var prop = cssProp.indexOf(':');\n var name = cssProp.substr(0, prop).trim();\n var value = cssProp.substr(prop + 1, cssProp.length - prop).trim();\n\n if (name && value) {\n props[name] = new Property(document, name, value);\n }\n });\n document.styles[cssClass] = props;\n document.stylesSpecificity[cssClass] = getSelectorSpecificity(cssClass);\n\n if (cssClass === '@font-face') {\n // && !nodeEnv\n var fontFamily = props['font-family'].getString().replace(/\"|'/g, '');\n var srcs = props.src.getString().split(',');\n srcs.forEach(function (src) {\n if (src.indexOf('format(\"svg\")') > 0) {\n var url = parseExternalUrl(src);\n\n if (url) {\n void new SVGFontLoader(document).load(fontFamily, url);\n }\n }\n });\n }\n });\n });\n return _this;\n }\n\n return StyleElement;\n}(Element);\nStyleElement.parseExternalUrl = parseExternalUrl;\n\nfunction _createSuper$a(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$a(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$a() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar UseElement = /*#__PURE__*/function (_RenderedElement) {\n _inherits__default[\"default\"](UseElement, _RenderedElement);\n\n var _super = _createSuper$a(UseElement);\n\n function UseElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, UseElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'use';\n return _this;\n }\n\n _createClass__default[\"default\"](UseElement, [{\n key: \"setContext\",\n value: function setContext(ctx) {\n _get__default[\"default\"](_getPrototypeOf__default[\"default\"](UseElement.prototype), \"setContext\", this).call(this, ctx);\n\n var xAttr = this.getAttribute('x');\n var yAttr = this.getAttribute('y');\n\n if (xAttr.hasValue()) {\n ctx.translate(xAttr.getPixels('x'), 0);\n }\n\n if (yAttr.hasValue()) {\n ctx.translate(0, yAttr.getPixels('y'));\n }\n }\n }, {\n key: \"path\",\n value: function path(ctx) {\n var element = this.element;\n\n if (element) {\n element.path(ctx);\n }\n }\n }, {\n key: \"renderChildren\",\n value: function renderChildren(ctx) {\n var document = this.document,\n element = this.element;\n\n if (element) {\n var tempSvg = element;\n\n if (element.type === 'symbol') {\n // render me using a temporary svg element in symbol cases (http://www.w3.org/TR/SVG/struct.html#UseElement)\n tempSvg = new SVGElement(document, null);\n tempSvg.attributes.viewBox = new Property(document, 'viewBox', element.getAttribute('viewBox').getString());\n tempSvg.attributes.preserveAspectRatio = new Property(document, 'preserveAspectRatio', element.getAttribute('preserveAspectRatio').getString());\n tempSvg.attributes.overflow = new Property(document, 'overflow', element.getAttribute('overflow').getString());\n tempSvg.children = element.children; // element is still the parent of the children\n\n element.styles.opacity = new Property(document, 'opacity', this.calculateOpacity());\n }\n\n if (tempSvg.type === 'svg') {\n var widthStyle = this.getStyle('width', false, true);\n var heightStyle = this.getStyle('height', false, true); // if symbol or svg, inherit width/height from me\n\n if (widthStyle.hasValue()) {\n tempSvg.attributes.width = new Property(document, 'width', widthStyle.getString());\n }\n\n if (heightStyle.hasValue()) {\n tempSvg.attributes.height = new Property(document, 'height', heightStyle.getString());\n }\n }\n\n var oldParent = tempSvg.parent;\n tempSvg.parent = this;\n tempSvg.render(ctx);\n tempSvg.parent = oldParent;\n }\n }\n }, {\n key: \"getBoundingBox\",\n value: function getBoundingBox(ctx) {\n var element = this.element;\n\n if (element) {\n return element.getBoundingBox(ctx);\n }\n\n return null;\n }\n }, {\n key: \"elementTransform\",\n value: function elementTransform() {\n var document = this.document,\n element = this.element;\n return Transform.fromElement(document, element);\n }\n }, {\n key: \"element\",\n get: function get() {\n if (!this.cachedElement) {\n this.cachedElement = this.getHrefAttribute().getDefinition();\n }\n\n return this.cachedElement;\n }\n }]);\n\n return UseElement;\n}(RenderedElement);\n\nfunction _createSuper$9(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$9(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$9() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction imGet(img, x, y, width, _height, rgba) {\n return img[y * width * 4 + x * 4 + rgba];\n}\n\nfunction imSet(img, x, y, width, _height, rgba, val) {\n img[y * width * 4 + x * 4 + rgba] = val;\n}\n\nfunction m(matrix, i, v) {\n var mi = matrix[i];\n return mi * v;\n}\n\nfunction c(a, m1, m2, m3) {\n return m1 + Math.cos(a) * m2 + Math.sin(a) * m3;\n}\n\nvar FeColorMatrixElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](FeColorMatrixElement, _Element);\n\n var _super = _createSuper$9(FeColorMatrixElement);\n\n function FeColorMatrixElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, FeColorMatrixElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'feColorMatrix';\n var matrix = toNumbers(_this.getAttribute('values').getString());\n\n switch (_this.getAttribute('type').getString('matrix')) {\n // http://www.w3.org/TR/SVG/filters.html#feColorMatrixElement\n case 'saturate':\n {\n var s = matrix[0];\n /* eslint-disable array-element-newline */\n\n matrix = [0.213 + 0.787 * s, 0.715 - 0.715 * s, 0.072 - 0.072 * s, 0, 0, 0.213 - 0.213 * s, 0.715 + 0.285 * s, 0.072 - 0.072 * s, 0, 0, 0.213 - 0.213 * s, 0.715 - 0.715 * s, 0.072 + 0.928 * s, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1];\n /* eslint-enable array-element-newline */\n\n break;\n }\n\n case 'hueRotate':\n {\n var a = matrix[0] * Math.PI / 180.0;\n /* eslint-disable array-element-newline */\n\n matrix = [c(a, 0.213, 0.787, -0.213), c(a, 0.715, -0.715, -0.715), c(a, 0.072, -0.072, 0.928), 0, 0, c(a, 0.213, -0.213, 0.143), c(a, 0.715, 0.285, 0.140), c(a, 0.072, -0.072, -0.283), 0, 0, c(a, 0.213, -0.213, -0.787), c(a, 0.715, -0.715, 0.715), c(a, 0.072, 0.928, 0.072), 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1];\n /* eslint-enable array-element-newline */\n\n break;\n }\n\n case 'luminanceToAlpha':\n /* eslint-disable array-element-newline */\n matrix = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2125, 0.7154, 0.0721, 0, 0, 0, 0, 0, 0, 1];\n /* eslint-enable array-element-newline */\n\n break;\n }\n\n _this.matrix = matrix;\n _this.includeOpacity = _this.getAttribute('includeOpacity').hasValue();\n return _this;\n }\n\n _createClass__default[\"default\"](FeColorMatrixElement, [{\n key: \"apply\",\n value: function apply(ctx, _x, _y, width, height) {\n // assuming x==0 && y==0 for now\n var includeOpacity = this.includeOpacity,\n matrix = this.matrix;\n var srcData = ctx.getImageData(0, 0, width, height);\n\n for (var y = 0; y < height; y++) {\n for (var x = 0; x < width; x++) {\n var r = imGet(srcData.data, x, y, width, height, 0);\n var g = imGet(srcData.data, x, y, width, height, 1);\n var b = imGet(srcData.data, x, y, width, height, 2);\n var a = imGet(srcData.data, x, y, width, height, 3);\n var nr = m(matrix, 0, r) + m(matrix, 1, g) + m(matrix, 2, b) + m(matrix, 3, a) + m(matrix, 4, 1);\n var ng = m(matrix, 5, r) + m(matrix, 6, g) + m(matrix, 7, b) + m(matrix, 8, a) + m(matrix, 9, 1);\n var nb = m(matrix, 10, r) + m(matrix, 11, g) + m(matrix, 12, b) + m(matrix, 13, a) + m(matrix, 14, 1);\n var na = m(matrix, 15, r) + m(matrix, 16, g) + m(matrix, 17, b) + m(matrix, 18, a) + m(matrix, 19, 1);\n\n if (includeOpacity) {\n nr = 0;\n ng = 0;\n nb = 0;\n na *= a / 255;\n }\n\n imSet(srcData.data, x, y, width, height, 0, nr);\n imSet(srcData.data, x, y, width, height, 1, ng);\n imSet(srcData.data, x, y, width, height, 2, nb);\n imSet(srcData.data, x, y, width, height, 3, na);\n }\n }\n\n ctx.clearRect(0, 0, width, height);\n ctx.putImageData(srcData, 0, 0);\n }\n }]);\n\n return FeColorMatrixElement;\n}(Element);\n\nfunction _createSuper$8(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$8(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$8() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar MaskElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](MaskElement, _Element);\n\n var _super = _createSuper$8(MaskElement);\n\n function MaskElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, MaskElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'mask';\n return _this;\n }\n\n _createClass__default[\"default\"](MaskElement, [{\n key: \"apply\",\n value: function apply(ctx, element) {\n var document = this.document; // render as temp svg\n\n var x = this.getAttribute('x').getPixels('x');\n var y = this.getAttribute('y').getPixels('y');\n var width = this.getStyle('width').getPixels('x');\n var height = this.getStyle('height').getPixels('y');\n\n if (!width && !height) {\n var boundingBox = new BoundingBox();\n this.children.forEach(function (child) {\n boundingBox.addBoundingBox(child.getBoundingBox(ctx));\n });\n x = Math.floor(boundingBox.x1);\n y = Math.floor(boundingBox.y1);\n width = Math.floor(boundingBox.width);\n height = Math.floor(boundingBox.height);\n }\n\n var ignoredStyles = this.removeStyles(element, MaskElement.ignoreStyles);\n var maskCanvas = document.createCanvas(x + width, y + height);\n var maskCtx = maskCanvas.getContext('2d');\n document.screen.setDefaults(maskCtx);\n this.renderChildren(maskCtx); // convert mask to alpha with a fake node\n // TODO: refactor out apply from feColorMatrix\n\n new FeColorMatrixElement(document, {\n nodeType: 1,\n childNodes: [],\n attributes: [{\n nodeName: 'type',\n value: 'luminanceToAlpha'\n }, {\n nodeName: 'includeOpacity',\n value: 'true'\n }]\n }).apply(maskCtx, 0, 0, x + width, y + height);\n var tmpCanvas = document.createCanvas(x + width, y + height);\n var tmpCtx = tmpCanvas.getContext('2d');\n document.screen.setDefaults(tmpCtx);\n element.render(tmpCtx);\n tmpCtx.globalCompositeOperation = 'destination-in';\n tmpCtx.fillStyle = maskCtx.createPattern(maskCanvas, 'no-repeat');\n tmpCtx.fillRect(0, 0, x + width, y + height);\n ctx.fillStyle = tmpCtx.createPattern(tmpCanvas, 'no-repeat');\n ctx.fillRect(0, 0, x + width, y + height); // reassign mask\n\n this.restoreStyles(element, ignoredStyles);\n }\n }, {\n key: \"render\",\n value: function render(_) {// NO RENDER\n }\n }]);\n\n return MaskElement;\n}(Element);\nMaskElement.ignoreStyles = ['mask', 'transform', 'clip-path'];\n\nfunction _createSuper$7(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$7(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$7() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar noop = function noop() {// NOOP\n};\n\nvar ClipPathElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](ClipPathElement, _Element);\n\n var _super = _createSuper$7(ClipPathElement);\n\n function ClipPathElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, ClipPathElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'clipPath';\n return _this;\n }\n\n _createClass__default[\"default\"](ClipPathElement, [{\n key: \"apply\",\n value: function apply(ctx) {\n var document = this.document;\n var contextProto = Reflect.getPrototypeOf(ctx);\n var beginPath = ctx.beginPath,\n closePath = ctx.closePath;\n\n if (contextProto) {\n contextProto.beginPath = noop;\n contextProto.closePath = noop;\n }\n\n Reflect.apply(beginPath, ctx, []);\n this.children.forEach(function (child) {\n if (typeof child.path === 'undefined') {\n return;\n }\n\n var transform = typeof child.elementTransform !== 'undefined' ? child.elementTransform() : null; // handle <use />\n\n if (!transform) {\n transform = Transform.fromElement(document, child);\n }\n\n if (transform) {\n transform.apply(ctx);\n }\n\n child.path(ctx);\n\n if (contextProto) {\n contextProto.closePath = closePath;\n }\n\n if (transform) {\n transform.unapply(ctx);\n }\n });\n Reflect.apply(closePath, ctx, []);\n ctx.clip();\n\n if (contextProto) {\n contextProto.beginPath = beginPath;\n contextProto.closePath = closePath;\n }\n }\n }, {\n key: \"render\",\n value: function render(_) {// NO RENDER\n }\n }]);\n\n return ClipPathElement;\n}(Element);\n\nfunction _createSuper$6(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$6(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$6() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar FilterElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](FilterElement, _Element);\n\n var _super = _createSuper$6(FilterElement);\n\n function FilterElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, FilterElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'filter';\n return _this;\n }\n\n _createClass__default[\"default\"](FilterElement, [{\n key: \"apply\",\n value: function apply(ctx, element) {\n // render as temp svg\n var document = this.document,\n children = this.children;\n var boundingBox = element.getBoundingBox(ctx);\n\n if (!boundingBox) {\n return;\n }\n\n var px = 0;\n var py = 0;\n children.forEach(function (child) {\n var efd = child.extraFilterDistance || 0;\n px = Math.max(px, efd);\n py = Math.max(py, efd);\n });\n var width = Math.floor(boundingBox.width);\n var height = Math.floor(boundingBox.height);\n var tmpCanvasWidth = width + 2 * px;\n var tmpCanvasHeight = height + 2 * py;\n\n if (tmpCanvasWidth < 1 || tmpCanvasHeight < 1) {\n return;\n }\n\n var x = Math.floor(boundingBox.x);\n var y = Math.floor(boundingBox.y);\n var ignoredStyles = this.removeStyles(element, FilterElement.ignoreStyles);\n var tmpCanvas = document.createCanvas(tmpCanvasWidth, tmpCanvasHeight);\n var tmpCtx = tmpCanvas.getContext('2d');\n document.screen.setDefaults(tmpCtx);\n tmpCtx.translate(-x + px, -y + py);\n element.render(tmpCtx); // apply filters\n\n children.forEach(function (child) {\n if (typeof child.apply === 'function') {\n child.apply(tmpCtx, 0, 0, tmpCanvasWidth, tmpCanvasHeight);\n }\n }); // render on me\n\n ctx.drawImage(tmpCanvas, 0, 0, tmpCanvasWidth, tmpCanvasHeight, x - px, y - py, tmpCanvasWidth, tmpCanvasHeight);\n this.restoreStyles(element, ignoredStyles);\n }\n }, {\n key: \"render\",\n value: function render(_) {// NO RENDER\n }\n }]);\n\n return FilterElement;\n}(Element);\nFilterElement.ignoreStyles = ['filter', 'transform', 'clip-path'];\n\nfunction _createSuper$5(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$5(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$5() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar FeDropShadowElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](FeDropShadowElement, _Element);\n\n var _super = _createSuper$5(FeDropShadowElement);\n\n function FeDropShadowElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, FeDropShadowElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'feDropShadow';\n\n _this.addStylesFromStyleDefinition();\n\n return _this;\n }\n\n _createClass__default[\"default\"](FeDropShadowElement, [{\n key: \"apply\",\n value: function apply(_, _x, _y, _width, _height) {// TODO: implement\n }\n }]);\n\n return FeDropShadowElement;\n}(Element);\n\nfunction _createSuper$4(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$4(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$4() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar FeMorphologyElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](FeMorphologyElement, _Element);\n\n var _super = _createSuper$4(FeMorphologyElement);\n\n function FeMorphologyElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, FeMorphologyElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'feMorphology';\n return _this;\n }\n\n _createClass__default[\"default\"](FeMorphologyElement, [{\n key: \"apply\",\n value: function apply(_, _x, _y, _width, _height) {// TODO: implement\n }\n }]);\n\n return FeMorphologyElement;\n}(Element);\n\nfunction _createSuper$3(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$3(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$3() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar FeCompositeElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](FeCompositeElement, _Element);\n\n var _super = _createSuper$3(FeCompositeElement);\n\n function FeCompositeElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, FeCompositeElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'feComposite';\n return _this;\n }\n\n _createClass__default[\"default\"](FeCompositeElement, [{\n key: \"apply\",\n value: function apply(_, _x, _y, _width, _height) {// TODO: implement\n }\n }]);\n\n return FeCompositeElement;\n}(Element);\n\nfunction _createSuper$2(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$2(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$2() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar FeGaussianBlurElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](FeGaussianBlurElement, _Element);\n\n var _super = _createSuper$2(FeGaussianBlurElement);\n\n function FeGaussianBlurElement(document, node, captureTextNodes) {\n var _this;\n\n _classCallCheck__default[\"default\"](this, FeGaussianBlurElement);\n\n _this = _super.call(this, document, node, captureTextNodes);\n _this.type = 'feGaussianBlur';\n _this.blurRadius = Math.floor(_this.getAttribute('stdDeviation').getNumber());\n _this.extraFilterDistance = _this.blurRadius;\n return _this;\n }\n\n _createClass__default[\"default\"](FeGaussianBlurElement, [{\n key: \"apply\",\n value: function apply(ctx, x, y, width, height) {\n var document = this.document,\n blurRadius = this.blurRadius;\n var body = document.window ? document.window.document.body : null;\n var canvas = ctx.canvas; // StackBlur requires canvas be on document\n\n canvas.id = document.getUniqueId();\n\n if (body) {\n canvas.style.display = 'none';\n body.appendChild(canvas);\n }\n\n stackblurCanvas.canvasRGBA(canvas, x, y, width, height, blurRadius);\n\n if (body) {\n body.removeChild(canvas);\n }\n }\n }]);\n\n return FeGaussianBlurElement;\n}(Element);\n\nfunction _createSuper$1(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct$1() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar TitleElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](TitleElement, _Element);\n\n var _super = _createSuper$1(TitleElement);\n\n function TitleElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, TitleElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'title';\n return _this;\n }\n\n return TitleElement;\n}(Element);\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf__default[\"default\"](Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf__default[\"default\"](this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn__default[\"default\"](this, result); }; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\nvar DescElement = /*#__PURE__*/function (_Element) {\n _inherits__default[\"default\"](DescElement, _Element);\n\n var _super = _createSuper(DescElement);\n\n function DescElement() {\n var _this;\n\n _classCallCheck__default[\"default\"](this, DescElement);\n\n _this = _super.apply(this, arguments);\n _this.type = 'desc';\n return _this;\n }\n\n return DescElement;\n}(Element);\n\nvar elements = {\n 'svg': SVGElement,\n 'rect': RectElement,\n 'circle': CircleElement,\n 'ellipse': EllipseElement,\n 'line': LineElement,\n 'polyline': PolylineElement,\n 'polygon': PolygonElement,\n 'path': PathElement,\n 'pattern': PatternElement,\n 'marker': MarkerElement,\n 'defs': DefsElement,\n 'linearGradient': LinearGradientElement,\n 'radialGradient': RadialGradientElement,\n 'stop': StopElement,\n 'animate': AnimateElement,\n 'animateColor': AnimateColorElement,\n 'animateTransform': AnimateTransformElement,\n 'font': FontElement,\n 'font-face': FontFaceElement,\n 'missing-glyph': MissingGlyphElement,\n 'glyph': GlyphElement,\n 'text': TextElement,\n 'tspan': TSpanElement,\n 'tref': TRefElement,\n 'a': AElement,\n 'textPath': TextPathElement,\n 'image': ImageElement,\n 'g': GElement,\n 'symbol': SymbolElement,\n 'style': StyleElement,\n 'use': UseElement,\n 'mask': MaskElement,\n 'clipPath': ClipPathElement,\n 'filter': FilterElement,\n 'feDropShadow': FeDropShadowElement,\n 'feMorphology': FeMorphologyElement,\n 'feComposite': FeCompositeElement,\n 'feColorMatrix': FeColorMatrixElement,\n 'feGaussianBlur': FeGaussianBlurElement,\n 'title': TitleElement,\n 'desc': DescElement\n};\n\nfunction ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { _defineProperty__default[\"default\"](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction createCanvas(width, height) {\n var canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\nfunction createImage(_x) {\n return _createImage.apply(this, arguments);\n}\n\nfunction _createImage() {\n _createImage = _asyncToGenerator__default[\"default\"]( /*#__PURE__*/_regeneratorRuntime__default[\"default\"].mark(function _callee(src) {\n var anonymousCrossOrigin,\n image,\n _args = arguments;\n return _regeneratorRuntime__default[\"default\"].wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n anonymousCrossOrigin = _args.length > 1 && _args[1] !== undefined ? _args[1] : false;\n image = document.createElement('img');\n\n if (anonymousCrossOrigin) {\n image.crossOrigin = 'Anonymous';\n }\n\n return _context.abrupt(\"return\", new Promise(function (resolve, reject) {\n image.onload = function () {\n resolve(image);\n };\n\n image.onerror = function (_event, _source, _lineno, _colno, error) {\n reject(error);\n };\n\n image.src = src;\n }));\n\n case 4:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee);\n }));\n return _createImage.apply(this, arguments);\n}\n\nvar Document = /*#__PURE__*/function () {\n function Document(canvg) {\n var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n _ref$rootEmSize = _ref.rootEmSize,\n rootEmSize = _ref$rootEmSize === void 0 ? 12 : _ref$rootEmSize,\n _ref$emSize = _ref.emSize,\n emSize = _ref$emSize === void 0 ? 12 : _ref$emSize,\n _ref$createCanvas = _ref.createCanvas,\n createCanvas = _ref$createCanvas === void 0 ? Document.createCanvas : _ref$createCanvas,\n _ref$createImage = _ref.createImage,\n createImage = _ref$createImage === void 0 ? Document.createImage : _ref$createImage,\n anonymousCrossOrigin = _ref.anonymousCrossOrigin;\n\n _classCallCheck__default[\"default\"](this, Document);\n\n this.canvg = canvg;\n this.definitions = Object.create(null);\n this.styles = Object.create(null);\n this.stylesSpecificity = Object.create(null);\n this.images = [];\n this.fonts = [];\n this.emSizeStack = [];\n this.uniqueId = 0;\n this.screen = canvg.screen;\n this.rootEmSize = rootEmSize;\n this.emSize = emSize;\n this.createCanvas = createCanvas;\n this.createImage = this.bindCreateImage(createImage, anonymousCrossOrigin);\n this.screen.wait(this.isImagesLoaded.bind(this));\n this.screen.wait(this.isFontsLoaded.bind(this));\n }\n\n _createClass__default[\"default\"](Document, [{\n key: \"bindCreateImage\",\n value: function bindCreateImage(createImage, anonymousCrossOrigin) {\n if (typeof anonymousCrossOrigin === 'boolean') {\n return function (source, forceAnonymousCrossOrigin) {\n return createImage(source, typeof forceAnonymousCrossOrigin === 'boolean' ? forceAnonymousCrossOrigin : anonymousCrossOrigin);\n };\n }\n\n return createImage;\n }\n }, {\n key: \"popEmSize\",\n value: function popEmSize() {\n var emSizeStack = this.emSizeStack;\n emSizeStack.pop();\n }\n }, {\n key: \"getUniqueId\",\n value: function getUniqueId() {\n return \"canvg\".concat(++this.uniqueId);\n }\n }, {\n key: \"isImagesLoaded\",\n value: function isImagesLoaded() {\n return this.images.every(function (_) {\n return _.loaded;\n });\n }\n }, {\n key: \"isFontsLoaded\",\n value: function isFontsLoaded() {\n return this.fonts.every(function (_) {\n return _.loaded;\n });\n }\n }, {\n key: \"createDocumentElement\",\n value: function createDocumentElement(document) {\n var documentElement = this.createElement(document.documentElement);\n documentElement.root = true;\n documentElement.addStylesFromStyleDefinition();\n this.documentElement = documentElement;\n return documentElement;\n }\n }, {\n key: \"createElement\",\n value: function createElement(node) {\n var elementType = node.nodeName.replace(/^[^:]+:/, '');\n var ElementType = Document.elementTypes[elementType];\n\n if (typeof ElementType !== 'undefined') {\n return new ElementType(this, node);\n }\n\n return new UnknownElement(this, node);\n }\n }, {\n key: \"createTextNode\",\n value: function createTextNode(node) {\n return new TextNode(this, node);\n }\n }, {\n key: \"setViewBox\",\n value: function setViewBox(config) {\n this.screen.setViewBox(_objectSpread$1({\n document: this\n }, config));\n }\n }, {\n key: \"window\",\n get: function get() {\n return this.screen.window;\n }\n }, {\n key: \"fetch\",\n get: function get() {\n return this.screen.fetch;\n }\n }, {\n key: \"ctx\",\n get: function get() {\n return this.screen.ctx;\n }\n }, {\n key: \"emSize\",\n get: function get() {\n var emSizeStack = this.emSizeStack;\n return emSizeStack[emSizeStack.length - 1];\n },\n set: function set(value) {\n var emSizeStack = this.emSizeStack;\n emSizeStack.push(value);\n }\n }]);\n\n return Document;\n}();\nDocument.createCanvas = createCanvas;\nDocument.createImage = createImage;\nDocument.elementTypes = elements;\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty__default[\"default\"](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n/**\r\n * SVG renderer on canvas.\r\n */\n\nvar Canvg = /*#__PURE__*/function () {\n /**\r\n * Main constructor.\r\n * @param ctx - Rendering context.\r\n * @param svg - SVG Document.\r\n * @param options - Rendering options.\r\n */\n function Canvg(ctx, svg) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n _classCallCheck__default[\"default\"](this, Canvg);\n\n this.parser = new Parser(options);\n this.screen = new Screen(ctx, options);\n this.options = options;\n var document = new Document(this, options);\n var documentElement = document.createDocumentElement(svg);\n this.document = document;\n this.documentElement = documentElement;\n }\n /**\r\n * Create Canvg instance from SVG source string or URL.\r\n * @param ctx - Rendering context.\r\n * @param svg - SVG source string or URL.\r\n * @param options - Rendering options.\r\n * @returns Canvg instance.\r\n */\n\n\n _createClass__default[\"default\"](Canvg, [{\n key: \"fork\",\n\n /**\r\n * Create new Canvg instance with inherited options.\r\n * @param ctx - Rendering context.\r\n * @param svg - SVG source string or URL.\r\n * @param options - Rendering options.\r\n * @returns Canvg instance.\r\n */\n value: function fork(ctx, svg) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n return Canvg.from(ctx, svg, _objectSpread(_objectSpread({}, this.options), options));\n }\n /**\r\n * Create new Canvg instance with inherited options.\r\n * @param ctx - Rendering context.\r\n * @param svg - SVG source string.\r\n * @param options - Rendering options.\r\n * @returns Canvg instance.\r\n */\n\n }, {\n key: \"forkString\",\n value: function forkString(ctx, svg) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n return Canvg.fromString(ctx, svg, _objectSpread(_objectSpread({}, this.options), options));\n }\n /**\r\n * Document is ready promise.\r\n * @returns Ready promise.\r\n */\n\n }, {\n key: \"ready\",\n value: function ready() {\n return this.screen.ready();\n }\n /**\r\n * Document is ready value.\r\n * @returns Is ready or not.\r\n */\n\n }, {\n key: \"isReady\",\n value: function isReady() {\n return this.screen.isReady();\n }\n /**\r\n * Render only first frame, ignoring animations and mouse.\r\n * @param options - Rendering options.\r\n */\n\n }, {\n key: \"render\",\n value: function () {\n var _render = _asyncToGenerator__default[\"default\"]( /*#__PURE__*/_regeneratorRuntime__default[\"default\"].mark(function _callee() {\n var options,\n _args = arguments;\n return _regeneratorRuntime__default[\"default\"].wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};\n this.start(_objectSpread({\n enableRedraw: true,\n ignoreAnimation: true,\n ignoreMouse: true\n }, options));\n _context.next = 4;\n return this.ready();\n\n case 4:\n this.stop();\n\n case 5:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function render() {\n return _render.apply(this, arguments);\n }\n\n return render;\n }()\n /**\r\n * Start rendering.\r\n * @param options - Render options.\r\n */\n\n }, {\n key: \"start\",\n value: function start() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var documentElement = this.documentElement,\n screen = this.screen,\n baseOptions = this.options;\n screen.start(documentElement, _objectSpread(_objectSpread({\n enableRedraw: true\n }, baseOptions), options));\n }\n /**\r\n * Stop rendering.\r\n */\n\n }, {\n key: \"stop\",\n value: function stop() {\n this.screen.stop();\n }\n /**\r\n * Resize SVG to fit in given size.\r\n * @param width\r\n * @param height\r\n * @param preserveAspectRatio\r\n */\n\n }, {\n key: \"resize\",\n value: function resize(width) {\n var height = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : width;\n var preserveAspectRatio = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n this.documentElement.resize(width, height, preserveAspectRatio);\n }\n }], [{\n key: \"from\",\n value: function () {\n var _from = _asyncToGenerator__default[\"default\"]( /*#__PURE__*/_regeneratorRuntime__default[\"default\"].mark(function _callee2(ctx, svg) {\n var options,\n parser,\n svgDocument,\n _args2 = arguments;\n return _regeneratorRuntime__default[\"default\"].wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n options = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : {};\n parser = new Parser(options);\n _context2.next = 4;\n return parser.parse(svg);\n\n case 4:\n svgDocument = _context2.sent;\n return _context2.abrupt(\"return\", new Canvg(ctx, svgDocument, options));\n\n case 6:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _callee2);\n }));\n\n function from(_x, _x2) {\n return _from.apply(this, arguments);\n }\n\n return from;\n }()\n /**\r\n * Create Canvg instance from SVG source string.\r\n * @param ctx - Rendering context.\r\n * @param svg - SVG source string.\r\n * @param options - Rendering options.\r\n * @returns Canvg instance.\r\n */\n\n }, {\n key: \"fromString\",\n value: function fromString(ctx, svg) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var parser = new Parser(options);\n var svgDocument = parser.parseFromString(svg);\n return new Canvg(ctx, svgDocument, options);\n }\n }]);\n\n return Canvg;\n}();\n\nexports.AElement = AElement;\nexports.AnimateColorElement = AnimateColorElement;\nexports.AnimateElement = AnimateElement;\nexports.AnimateTransformElement = AnimateTransformElement;\nexports.BoundingBox = BoundingBox;\nexports.CB1 = CB1;\nexports.CB2 = CB2;\nexports.CB3 = CB3;\nexports.CB4 = CB4;\nexports.Canvg = Canvg;\nexports.CircleElement = CircleElement;\nexports.ClipPathElement = ClipPathElement;\nexports.DefsElement = DefsElement;\nexports.DescElement = DescElement;\nexports.Document = Document;\nexports.Element = Element;\nexports.EllipseElement = EllipseElement;\nexports.FeColorMatrixElement = FeColorMatrixElement;\nexports.FeCompositeElement = FeCompositeElement;\nexports.FeDropShadowElement = FeDropShadowElement;\nexports.FeGaussianBlurElement = FeGaussianBlurElement;\nexports.FeMorphologyElement = FeMorphologyElement;\nexports.FilterElement = FilterElement;\nexports.Font = Font;\nexports.FontElement = FontElement;\nexports.FontFaceElement = FontFaceElement;\nexports.GElement = GElement;\nexports.GlyphElement = GlyphElement;\nexports.GradientElement = GradientElement;\nexports.ImageElement = ImageElement;\nexports.LineElement = LineElement;\nexports.LinearGradientElement = LinearGradientElement;\nexports.MarkerElement = MarkerElement;\nexports.MaskElement = MaskElement;\nexports.Matrix = Matrix;\nexports.MissingGlyphElement = MissingGlyphElement;\nexports.Mouse = Mouse;\nexports.PSEUDO_ZERO = PSEUDO_ZERO;\nexports.Parser = Parser;\nexports.PathElement = PathElement;\nexports.PathParser = PathParser;\nexports.PatternElement = PatternElement;\nexports.Point = Point;\nexports.PolygonElement = PolygonElement;\nexports.PolylineElement = PolylineElement;\nexports.Property = Property;\nexports.QB1 = QB1;\nexports.QB2 = QB2;\nexports.QB3 = QB3;\nexports.RadialGradientElement = RadialGradientElement;\nexports.RectElement = RectElement;\nexports.RenderedElement = RenderedElement;\nexports.Rotate = Rotate;\nexports.SVGElement = SVGElement;\nexports.SVGFontLoader = SVGFontLoader;\nexports.Scale = Scale;\nexports.Screen = Screen;\nexports.Skew = Skew;\nexports.SkewX = SkewX;\nexports.SkewY = SkewY;\nexports.StopElement = StopElement;\nexports.StyleElement = StyleElement;\nexports.SymbolElement = SymbolElement;\nexports.TRefElement = TRefElement;\nexports.TSpanElement = TSpanElement;\nexports.TextElement = TextElement;\nexports.TextPathElement = TextPathElement;\nexports.TitleElement = TitleElement;\nexports.Transform = Transform;\nexports.Translate = Translate;\nexports.UnknownElement = UnknownElement;\nexports.UseElement = UseElement;\nexports.ViewPort = ViewPort;\nexports.compressSpaces = compressSpaces;\nexports[\"default\"] = Canvg;\nexports.getSelectorSpecificity = getSelectorSpecificity;\nexports.normalizeAttributeName = normalizeAttributeName;\nexports.normalizeColor = normalizeColor;\nexports.parseExternalUrl = parseExternalUrl;\nexports.presets = index;\nexports.toNumbers = toNumbers;\nexports.trimLeft = trimLeft;\nexports.trimRight = trimRight;\nexports.vectorMagnitude = vectorMagnitude;\nexports.vectorsAngle = vectorsAngle;\nexports.vectorsRatio = vectorsRatio;\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsifQ==\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvY2FudmcvbGliL2luZGV4LmNqcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYiw4Q0FBNkMsRUFBRSxhQUFhLEVBQUM7O0FBRTdELG1CQUFPLENBQUMsMkdBQXdDO0FBQ2hELG1CQUFPLENBQUMseUZBQStCO0FBQ3ZDLG1CQUFPLENBQUMseUhBQStDO0FBQ3ZELDBCQUEwQixtQkFBTyxDQUFDLDRGQUE0QjtBQUM5RCx3QkFBd0IsbUJBQU8sQ0FBQyxnSEFBeUM7QUFDekUsbUJBQU8sQ0FBQyw2RkFBaUM7QUFDekMsbUJBQU8sQ0FBQyxpR0FBbUM7QUFDM0MsbUJBQU8sQ0FBQyxpR0FBbUM7QUFDM0MsbUJBQU8sQ0FBQyxtR0FBb0M7QUFDNUMsbUJBQU8sQ0FBQyx1R0FBc0M7QUFDOUMsbUJBQU8sQ0FBQywrR0FBMEM7QUFDbEQsbUJBQU8sQ0FBQywrRkFBa0M7QUFDMUMscUJBQXFCLG1CQUFPLENBQUMsMEdBQXNDO0FBQ25FLHNCQUFzQixtQkFBTyxDQUFDLDRHQUF1QztBQUNyRSxzQkFBc0IsbUJBQU8sQ0FBQyw0R0FBdUM7QUFDckUsbUJBQW1CLG1CQUFPLENBQUMsc0dBQW9DO0FBQy9ELG1CQUFPLENBQUMsbUdBQW9DO0FBQzVDLG1CQUFPLENBQUMsaUdBQW1DO0FBQzNDLG1CQUFPLENBQUMsbUdBQW9DO0FBQzVDLG1CQUFPLENBQUMsMkdBQXdDO0FBQ2hELG1CQUFPLENBQUMsbUdBQW9DO0FBQzVDLDRCQUE0QixtQkFBTyxDQUFDLDhDQUFLO0FBQ3pDLG1CQUFPLENBQUMscUdBQXFDO0FBQzdDLG1CQUFPLENBQUMsaUdBQW1DO0FBQzNDLGVBQWUsbUJBQU8sQ0FBQyx3REFBVTtBQUNqQyxtQkFBTyxDQUFDLHVHQUFzQztBQUM5QyxtQkFBTyxDQUFDLDZIQUFpRDtBQUN6RCxnQkFBZ0IsbUJBQU8sQ0FBQyxnR0FBaUM7QUFDekQsaUNBQWlDLG1CQUFPLENBQUMsa0lBQWtEO0FBQzNGLHNCQUFzQixtQkFBTyxDQUFDLDRHQUF1QztBQUNyRSxtQkFBTyxDQUFDLCtGQUFrQztBQUMxQyxtQkFBTyxDQUFDLHVHQUFzQztBQUM5QyxtQkFBTyxDQUFDLHVHQUFzQztBQUM5QyxtQkFBTyxDQUFDLCtGQUFrQztBQUMxQyxtQkFBTyxDQUFDLHlHQUF1QztBQUMvQyxtQkFBTyxDQUFDLHlHQUF1QztBQUMvQyx5QkFBeUIsbUJBQU8sQ0FBQyxrSEFBMEM7QUFDM0UsbUJBQU8sQ0FBQyxxR0FBcUM7QUFDN0MsbUJBQU8sQ0FBQywrR0FBMEM7QUFDbEQsV0FBVyxtQkFBTyxDQUFDLHNGQUE0QjtBQUMvQyxtQkFBTyxDQUFDLCtGQUFrQztBQUMxQyxrQkFBa0IsbUJBQU8sQ0FBQywyRUFBYztBQUN4QyxtQkFBTyxDQUFDLDJHQUF3QztBQUNoRCw2QkFBNkIsbUJBQU8sQ0FBQywwSEFBOEM7QUFDbkYsbUJBQU8sQ0FBQyx1R0FBc0M7QUFDOUMsbUJBQU8sQ0FBQyw2SEFBaUQ7QUFDekQsbUJBQU8sQ0FBQyxpRkFBMkI7QUFDbkMsbUJBQU8sQ0FBQyxxR0FBcUM7QUFDN0MsbUJBQU8sQ0FBQywySEFBZ0Q7QUFDeEQsc0JBQXNCLG1CQUFPLENBQUMsb0ZBQWtCOztBQUVoRCxxQ0FBcUMsNERBQTREOztBQUVqRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUZBQW1GO0FBQ25GOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQSxtRkFBbUY7QUFDbkY7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsbUJBQW1CO0FBQ25CO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFFBQVE7OztBQUdSO0FBQ0E7QUFDQSxRQUFROzs7QUFHUjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCOztBQUV0QixzQkFBc0IsU0FBUztBQUMvQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCLFNBQVM7QUFDL0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qjs7QUFFN0IsNENBQTRDOztBQUU1QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLEdBQUc7O0FBRVY7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUZBQXFGO0FBQ3JGO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0ZBQWtGOztBQUVsRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBEQUEwRDs7QUFFMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7OztBQUdSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFROzs7QUFHUjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQSx3RkFBd0Y7QUFDeEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0EsUUFBUTs7O0FBR1I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFROzs7QUFHUjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7OztBQUdSO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxRkFBcUY7QUFDckY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFD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Q0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE1BQU07O0FBRU4sR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSw0Q0FBNEM7O0FBRTVDLDRDQUE0Qzs7QUFFNUMsNkNBQTZDOztBQUU3Qyw2Q0FBNkM7O0FBRTdDO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDOztBQUVELG1DQUFtQywrREFBK0QseUNBQXlDLGtFQUFrRSxpQ0FBaUMsdUVBQXVFLDJEQUEyRCxPQUFPLHlDQUF5Qzs7QUFFaGEseUNBQXlDLHdFQUF3RSwwQ0FBMEMsOENBQThDLE1BQU0sNEVBQTRFLElBQUksZUFBZSxZQUFZOztBQUUxVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFROzs7QUFHUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNCQUFzQixTQUFTO0FBQy9CO0FBQ0EsOEJBQThCLFNBQVM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDOztBQUVELG1DQUFtQywrREFBK0QseUNBQXlDLGtFQUFrRSxpQ0FBaUMsdUVBQXVFLDJEQUEyRCxPQUFPLHlDQUF5Qzs7QUFFaGEseUNBQXlDLHdFQUF3RSwwQ0FBMEMsOENBQThDLE1BQU0sNEVBQTRFLElBQUksZUFBZSxZQUFZOztBQUUxVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUJBQXlCOztBQUV6Qjs7QUFFQTtBQUNBLHFFQUFxRTs7QUFFckU7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxVQUFVOzs7QUFHVjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVFQUF1RTtBQUN2RTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTs7O0FBR1I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnQ0FBZ0M7O0FBRWhDO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0EsQ0FBQzs7QUFFRCxtQ0FBbUMsK0RBQStELHlDQUF5QyxrRUFBa0UsaUNBQWlDLHVFQUF1RSwyREFBMkQsT0FBTyx5Q0FBeUM7O0FBRWhhLHlDQUF5Qyx3RUFBd0UsMENBQTBDLDhDQUE4QyxNQUFNLDRFQUE0RSxJQUFJLGVBQWUsWUFBWTs7QUFFMVQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSwwQkFBMEIsc0JBQXNCO0FBQ2hEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDOzs7QUFHdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RDs7QUFFNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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Q0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLDhCQUE4Qjs7QUFFOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLHNDQUFzQzs7QUFFdEM7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsd0JBQXdCLFNBQVM7QUFDakM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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TUFBTSw0RUFBNEUsSUFBSSxlQUFlLFlBQVk7O0FBRTFUO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RCxTQUFTO0FBQ2hFO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsdURBQXVELFNBQVM7QUFDaEU7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUEsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsUUFBUTs7O0FBR1I7QUFDQTtBQUNBOztBQUVBLHNCQUFzQixhQUFhO0FBQ25DO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxPQUFPO0FBQ1A7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwwQkFBMEI7O0FBRTFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQSxXQUFXO0FBQ1gsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsUUFBUTtBQUNqQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsUUFBUTtBQUNqQztBQUNBO0FB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LG9CQUFvQjtBQUNwQix1QkFBdUI7QUFDdkIsb0JBQW9CO0FBQ3BCLG1CQUFtQjtBQUNuQiw2QkFBNkI7QUFDN0IscUJBQXFCO0FBQ3JCLG1CQUFtQjtBQUNuQixjQUFjO0FBQ2QsMkJBQTJCO0FBQzNCLGFBQWE7QUFDYixtQkFBbUI7QUFDbkIsY0FBYztBQUNkLG1CQUFtQjtBQUNuQixrQkFBa0I7QUFDbEIsc0JBQXNCO0FBQ3RCLGFBQWE7QUFDYixzQkFBc0I7QUFDdEIsdUJBQXVCO0FBQ3ZCLGdCQUFnQjtBQUNoQixXQUFXO0FBQ1gsV0FBVztBQUNYLFdBQVc7QUFDWCw2QkFBNkI7QUFDN0IsbUJBQW1CO0FBQ25CLHVCQUF1QjtBQUN2QixjQUFjO0FBQ2Qsa0JBQWtCO0FBQ2xCLHFCQUFxQjtBQUNyQixhQUFhO0FBQ2IsY0FBYztBQUNkLFlBQVk7QUFDWixhQUFhO0FBQ2IsYUFBYTtBQUNiLG1CQUFtQjtBQUNuQixvQkFBb0I7QUFDcEIscUJBQXFCO0FBQ3JCLG1CQUFtQjtBQUNuQixvQkFBb0I7QUFDcEIsbUJBQW1CO0FBQ25CLHVCQUF1QjtBQUN2QixvQkFBb0I7QUFDcEIsaUJBQWlCO0FBQ2pCLGlCQUFpQjtBQUNqQixzQkFBc0I7QUFDdEIsa0JBQWtCO0FBQ2xCLGdCQUFnQjtBQUNoQixzQkFBc0I7QUFDdEIsa0JBQWtCO0FBQ2xCLDhCQUE4QjtBQUM5Qiw4QkFBOEI7QUFDOUIsc0JBQXNCO0FBQ3RCLHdCQUF3QjtBQUN4QixlQUFlO0FBQ2YsaUJBQWlCO0FBQ2pCLGdCQUFnQjtBQUNoQixpQkFBaUI7QUFDakIsdUJBQXVCO0FBQ3ZCLG9CQUFvQjtBQUNwQixvQkFBb0I7QUFDcEIsMkNBQTJDLGNBQWMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly92ZXJpZnlwYWNrLWZyb250ZW5kLy4vbm9kZV9tb2R1bGVzL2NhbnZnL2xpYi9pbmRleC5janM/NzcyZCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5vYmplY3QudG8tc3RyaW5nLmpzJyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXMucHJvbWlzZS5qcycpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLnJlZmxlY3QuZGVsZXRlLXByb3BlcnR5LmpzJyk7XG52YXIgX3JlZ2VuZXJhdG9yUnVudGltZSA9IHJlcXVpcmUoJ0BiYWJlbC9ydW50aW1lL3JlZ2VuZXJhdG9yJyk7XG52YXIgX2FzeW5jVG9HZW5lcmF0b3IgPSByZXF1aXJlKCdAYmFiZWwvcnVudGltZS9oZWxwZXJzL2FzeW5jVG9HZW5lcmF0b3InKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5hcnJheS5tYXAuanMnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5wYXJzZS1mbG9hdC5qcycpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5leGVjLmpzJyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLm1hdGNoLmpzJyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLnJlcGxhY2UuanMnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuc3RhcnRzLXdpdGguanMnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5hcnJheS5qb2luLmpzJyk7XG52YXIgX3NsaWNlZFRvQXJyYXkgPSByZXF1aXJlKCdAYmFiZWwvcnVudGltZS9oZWxwZXJzL3NsaWNlZFRvQXJyYXknKTtcbnZhciBfZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCdAYmFiZWwvcnVudGltZS9oZWxwZXJzL2RlZmluZVByb3BlcnR5Jyk7XG52YXIgX2NsYXNzQ2FsbENoZWNrID0gcmVxdWlyZSgnQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jbGFzc0NhbGxDaGVjaycpO1xudmFyIF9jcmVhdGVDbGFzcyA9IHJlcXVpcmUoJ0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvY3JlYXRlQ2xhc3MnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5hcnJheS5jb25jYXQuanMnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5hcnJheS5ldmVyeS5qcycpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LnJlZHVjZS5qcycpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5lbmRzLXdpdGguanMnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5zdHJpbmcuc3BsaXQuanMnKTtcbnZhciByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSByZXF1aXJlKCdyYWYnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5mdW5jdGlvbi5uYW1lLmpzJyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXMuc3RyaW5nLnRyaW0uanMnKTtcbnZhciBSR0JDb2xvciA9IHJlcXVpcmUoJ3JnYmNvbG9yJyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXMuYXJyYXkuZm9yLWVhY2guanMnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLWNvbGxlY3Rpb25zLmZvci1lYWNoLmpzJyk7XG52YXIgX2luaGVyaXRzID0gcmVxdWlyZSgnQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbmhlcml0cycpO1xudmFyIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuID0gcmVxdWlyZSgnQGJhYmVsL3J1bnRpbWUvaGVscGVycy9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuJyk7XG52YXIgX2dldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnQGJhYmVsL3J1bnRpbWUvaGVscGVycy9nZXRQcm90b3R5cGVPZicpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmZyb20uanMnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5hcnJheS5pbmNsdWRlcy5qcycpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmluZGV4LW9mLmpzJyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXMuYXJyYXkuc29tZS5qcycpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5pbmNsdWRlcy5qcycpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5pdGVyYXRvci5qcycpO1xudmFyIF90b0NvbnN1bWFibGVBcnJheSA9IHJlcXVpcmUoJ0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9Db25zdW1hYmxlQXJyYXknKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5hcnJheS5yZXZlcnNlLmpzJyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXMubnVtYmVyLmNvbnN0cnVjdG9yLmpzJyk7XG52YXIgX2dldCA9IHJlcXVpcmUoJ0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0Jyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXMuYXJyYXkuZmlsbC5qcycpO1xudmFyIHN2Z1BhdGhkYXRhID0gcmVxdWlyZSgnc3ZnLXBhdGhkYXRhJyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvZXMucmVnZXhwLnRvLXN0cmluZy5qcycpO1xudmFyIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQgPSByZXF1aXJlKCdAYmFiZWwvcnVudGltZS9oZWxwZXJzL2Fzc2VydFRoaXNJbml0aWFsaXplZCcpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5Lml0ZXJhdG9yLmpzJyk7XG5yZXF1aXJlKCdjb3JlLWpzL21vZHVsZXMvd2ViLmRvbS1jb2xsZWN0aW9ucy5pdGVyYXRvci5qcycpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLm1hcC5qcycpO1xucmVxdWlyZSgnY29yZS1qcy9tb2R1bGVzL2VzLnJlZmxlY3QuYXBwbHkuanMnKTtcbnJlcXVpcmUoJ2NvcmUtanMvbW9kdWxlcy9lcy5yZWZsZWN0LmdldC1wcm90b3R5cGUtb2YuanMnKTtcbnZhciBzdGFja2JsdXJDYW52YXMgPSByZXF1aXJlKCdzdGFja2JsdXItY2FudmFzJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wRGVmYXVsdExlZ2FjeSAoZSkgeyByZXR1cm4gZSAmJiB0eXBlb2YgZSA9PT0gJ29iamVjdCcgJiYgJ2RlZmF1bHQnIGluIGUgPyBlIDogeyAnZGVmYXVsdCc6IGUgfTsgfVxuXG52YXIgX3JlZ2VuZXJhdG9yUnVudGltZV9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koX3JlZ2VuZXJhdG9yUnVudGltZSk7XG52YXIgX2FzeW5jVG9HZW5lcmF0b3JfX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX2ludGVyb3BEZWZhdWx0TGVnYWN5KF9hc3luY1RvR2VuZXJhdG9yKTtcbnZhciBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koX3NsaWNlZFRvQXJyYXkpO1xudmFyIF9kZWZpbmVQcm9wZXJ0eV9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koX2RlZmluZVByb3BlcnR5KTtcbnZhciBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX2ludGVyb3BEZWZhdWx0TGVnYWN5KF9jbGFzc0NhbGxDaGVjayk7XG52YXIgX2NyZWF0ZUNsYXNzX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeShfY3JlYXRlQ2xhc3MpO1xudmFyIHJlcXVlc3RBbmltYXRpb25GcmFtZV9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3kocmVxdWVzdEFuaW1hdGlvbkZyYW1lKTtcbnZhciBSR0JDb2xvcl9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koUkdCQ29sb3IpO1xudmFyIF9pbmhlcml0c19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koX2luaGVyaXRzKTtcbnZhciBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4pO1xudmFyIF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koX2dldFByb3RvdHlwZU9mKTtcbnZhciBfdG9Db25zdW1hYmxlQXJyYXlfX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX2ludGVyb3BEZWZhdWx0TGVnYWN5KF90b0NvbnN1bWFibGVBcnJheSk7XG52YXIgX2dldF9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koX2dldCk7XG52YXIgX2Fzc2VydFRoaXNJbml0aWFsaXplZF9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koX2Fzc2VydFRoaXNJbml0aWFsaXplZCk7XG5cbi8qKlxyXG4gKiBPcHRpb25zIHByZXNldCBmb3IgYE9mZnNjcmVlbkNhbnZhc2AuXHJcbiAqIEBwYXJhbSBjb25maWcgLSBQcmVzZXQgcmVxdWlyZW1lbnRzLlxyXG4gKiBAcGFyYW0gY29uZmlnLkRPTVBhcnNlciAtIFhNTC9IVE1MIHBhcnNlciBmcm9tIHN0cmluZyBpbnRvIERPTSBEb2N1bWVudC5cclxuICogQHJldHVybnMgUHJlc2V0IG9iamVjdC5cclxuICovXG5mdW5jdGlvbiBvZmZzY3JlZW4oKSB7XG4gIHZhciBfcmVmID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB7fSxcbiAgICAgIERPTVBhcnNlckZhbGxiYWNrID0gX3JlZi5ET01QYXJzZXI7XG5cbiAgdmFyIHByZXNldCA9IHtcbiAgICB3aW5kb3c6IG51bGwsXG4gICAgaWdub3JlQW5pbWF0aW9uOiB0cnVlLFxuICAgIGlnbm9yZU1vdXNlOiB0cnVlLFxuICAgIERPTVBhcnNlcjogRE9NUGFyc2VyRmFsbGJhY2ssXG4gICAgY3JlYXRlQ2FudmFzOiBmdW5jdGlvbiBjcmVhdGVDYW52YXMod2lkdGgsIGhlaWdodCkge1xuICAgICAgcmV0dXJuIG5ldyBPZmZzY3JlZW5DYW52YXMod2lkdGgsIGhlaWdodCk7XG4gICAgfSxcbiAgICBjcmVhdGVJbWFnZTogZnVuY3Rpb24gY3JlYXRlSW1hZ2UodXJsKSB7XG4gICAgICByZXR1cm4gX2FzeW5jVG9HZW5lcmF0b3JfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKCAvKiNfX1BVUkVfXyovX3JlZ2VuZXJhdG9yUnVudGltZV9fZGVmYXVsdFtcImRlZmF1bHRcIl0ubWFyayhmdW5jdGlvbiBfY2FsbGVlKCkge1xuICAgICAgICB2YXIgcmVzcG9uc2UsIGJsb2IsIGltZztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvclJ1bnRpbWVfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLndyYXAoZnVuY3Rpb24gX2NhbGxlZSQoX2NvbnRleHQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZldGNoKHVybCk7XG5cbiAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gX2NvbnRleHQuc2VudDtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gNTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuYmxvYigpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgICBibG9iID0gX2NvbnRleHQuc2VudDtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gODtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoYmxvYik7XG5cbiAgICAgICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgICAgIGltZyA9IF9jb250ZXh0LnNlbnQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LmFicnVwdChcInJldHVyblwiLCBpbWcpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZSk7XG4gICAgICB9KSkoKTtcbiAgICB9XG4gIH07XG5cbiAgaWYgKHR5cGVvZiBET01QYXJzZXIgIT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiBET01QYXJzZXJGYWxsYmFjayA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KHByZXNldCwgJ0RPTVBhcnNlcicpO1xuICB9XG5cbiAgcmV0dXJuIHByZXNldDtcbn1cblxuLyoqXHJcbiAqIE9wdGlvbnMgcHJlc2V0IGZvciBgbm9kZS1jYW52YXNgLlxyXG4gKiBAcGFyYW0gY29uZmlnIC0gUHJlc2V0IHJlcXVpcmVtZW50cy5cclxuICogQHBhcmFtIGNvbmZpZy5ET01QYXJzZXIgLSBYTUwvSFRNTCBwYXJzZXIgZnJvbSBzdHJpbmcgaW50byBET00gRG9jdW1lbnQuXHJcbiAqIEBwYXJhbSBjb25maWcuY2FudmFzIC0gYG5vZGUtY2FudmFzYCBleHBvcnRzLlxyXG4gKiBAcGFyYW0gY29uZmlnLmZldGNoIC0gV0hBVFdHLWNvbXBhdGlibGUgYGZldGNoYCBmdW5jdGlvbi5cclxuICogQHJldHVybnMgUHJlc2V0IG9iamVjdC5cclxuICovXG5mdW5jdGlvbiBub2RlKF9yZWYpIHtcbiAgdmFyIERPTVBhcnNlciA9IF9yZWYuRE9NUGFyc2VyLFxuICAgICAgY2FudmFzID0gX3JlZi5jYW52YXMsXG4gICAgICBmZXRjaCA9IF9yZWYuZmV0Y2g7XG4gIHJldHVybiB7XG4gICAgd2luZG93OiBudWxsLFxuICAgIGlnbm9yZUFuaW1hdGlvbjogdHJ1ZSxcbiAgICBpZ25vcmVNb3VzZTogdHJ1ZSxcbiAgICBET01QYXJzZXI6IERPTVBhcnNlcixcbiAgICBmZXRjaDogZmV0Y2gsXG4gICAgY3JlYXRlQ2FudmFzOiBjYW52YXMuY3JlYXRlQ2FudmFzLFxuICAgIGNyZWF0ZUltYWdlOiBjYW52YXMubG9hZEltYWdlXG4gIH07XG59XG5cbnZhciBpbmRleCA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcblx0X19wcm90b19fOiBudWxsLFxuXHRvZmZzY3JlZW46IG9mZnNjcmVlbixcblx0bm9kZTogbm9kZVxufSk7XG5cbi8qKlxyXG4gKiBIVE1MLXNhZmUgY29tcHJlc3Mgd2hpdGUtc3BhY2VzLlxyXG4gKiBAcGFyYW0gc3RyIC0gU3RyaW5nIHRvIGNvbXByZXNzLlxyXG4gKiBAcmV0dXJucyBTdHJpbmcuXHJcbiAqL1xuZnVuY3Rpb24gY29tcHJlc3NTcGFjZXMoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvKD8hXFx1MzAwMClcXHMrL2dtLCAnICcpO1xufVxuLyoqXHJcbiAqIEhUTUwtc2FmZSBsZWZ0IHRyaW0uXHJcbiAqIEBwYXJhbSBzdHIgLSBTdHJpbmcgdG8gdHJpbS5cclxuICogQHJldHVybnMgU3RyaW5nLlxyXG4gKi9cblxuZnVuY3Rpb24gdHJpbUxlZnQoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvXltcXG4gXFx0XSsvLCAnJyk7XG59XG4vKipcclxuICogSFRNTC1zYWZlIHJpZ2h0IHRyaW0uXHJcbiAqIEBwYXJhbSBzdHIgLSBTdHJpbmcgdG8gdHJpbS5cclxuICogQHJldHVybnMgU3RyaW5nLlxyXG4gKi9cblxuZnVuY3Rpb24gdHJpbVJpZ2h0KHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL1tcXG4gXFx0XSskLywgJycpO1xufVxuLyoqXHJcbiAqIFN0cmluZyB0byBudW1iZXJzIGFycmF5LlxyXG4gKiBAcGFyYW0gc3RyIC0gTnVtYmVycyBzdHJpbmcuXHJcbiAqIEByZXR1cm5zIE51bWJlcnMgYXJyYXkuXHJcbiAqL1xuXG5mdW5jdGlvbiB0b051bWJlcnMoc3RyKSB7XG4gIHZhciBtYXRjaGVzID0gKHN0ciB8fCAnJykubWF0Y2goLy0/KFxcZCsoPzpcXC5cXGQqKD86W2VFXVsrLV0/XFxkKyk/KT98XFwuXFxkKykoPz1cXER8JCkvZ20pIHx8IFtdO1xuICByZXR1cm4gbWF0Y2hlcy5tYXAocGFyc2VGbG9hdCk7XG59IC8vIE1pY3Jvc29mdCBFZGdlIGZpeFxuXG52YXIgYWxsVXBwZXJjYXNlID0gL15bQS1aLV0rJC87XG4vKipcclxuICogTm9ybWFsaXplIGF0dHJpYnV0ZSBuYW1lLlxyXG4gKiBAcGFyYW0gbmFtZSAtIEF0dHJpYnV0ZSBuYW1lLlxyXG4gKiBAcmV0dXJucyBOb3JtYWxpemVkIGF0dHJpYnV0ZSBuYW1lLlxyXG4gKi9cblxuZnVuY3Rpb24gbm9ybWFsaXplQXR0cmlidXRlTmFtZShuYW1lKSB7XG4gIGlmIChhbGxVcHBlcmNhc2UudGVzdChuYW1lKSkge1xuICAgIHJldHVybiBuYW1lLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICByZXR1cm4gbmFtZTtcbn1cbi8qKlxyXG4gKiBQYXJzZSBleHRlcm5hbCBVUkwuXHJcbiAqIEBwYXJhbSB1cmwgLSBDU1MgdXJsIHN0cmluZy5cclxuICogQHJldHVybnMgUGFyc2VkIFVSTC5cclxuICovXG5cbmZ1bmN0aW9uIHBhcnNlRXh0ZXJuYWxVcmwodXJsKSB7XG4gIC8vICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZSBxdW90ZXMgWzJdXG4gIC8vICAgICAgICAgICAgICAgICAgICAgIHYgICAgICAgICBkb3VibGUgcXVvdGVzIFszXVxuICAvLyAgICAgICAgICAgICAgICAgICAgICB2ICAgICAgICAgdiAgICAgICAgIG5vIHF1b3RlcyBbNF1cbiAgLy8gICAgICAgICAgICAgICAgICAgICAgdiAgICAgICAgIHYgICAgICAgICB2XG4gIHZhciB1cmxNYXRjaCA9IC91cmxcXCgoJyhbXiddKyknfFwiKFteXCJdKylcInwoW14nXCIpXSspKVxcKS8uZXhlYyh1cmwpIHx8IFtdO1xuICByZXR1cm4gdXJsTWF0Y2hbMl0gfHwgdXJsTWF0Y2hbM10gfHwgdXJsTWF0Y2hbNF07XG59XG4vKipcclxuICogVHJhbnNmb3JtIGZsb2F0cyB0byBpbnRlZ2VycyBpbiByZ2IgY29sb3JzLlxyXG4gKiBAcGFyYW0gY29sb3IgLSBDb2xvciB0byBub3JtYWxpemUuXHJcbiAqIEByZXR1cm5zIE5vcm1hbGl6ZWQgY29sb3IuXHJcbiAqL1xuXG5mdW5jdGlvbiBub3JtYWxpemVDb2xvcihjb2xvcikge1xuICBpZiAoIWNvbG9yLnN0YXJ0c1dpdGgoJ3JnYicpKSB7XG4gICAgcmV0dXJuIGNvbG9yO1xuICB9XG5cbiAgdmFyIHJnYlBhcnRzID0gMztcbiAgdmFyIG5vcm1hbGl6ZWRDb2xvciA9IGNvbG9yLnJlcGxhY2UoL1xcZCsoXFwuXFxkKyk/L2csIGZ1bmN0aW9uIChudW0sIGlzRmxvYXQpIHtcbiAgICByZXR1cm4gcmdiUGFydHMtLSAmJiBpc0Zsb2F0ID8gU3RyaW5nKE1hdGgucm91bmQocGFyc2VGbG9hdChudW0pKSkgOiBudW07XG4gIH0pO1xuICByZXR1cm4gbm9ybWFsaXplZENvbG9yO1xufVxuXG4vLyBzbGlnaHRseSBtb2RpZmllZCB2ZXJzaW9uIG9mIGh0dHBzOi8vZ2l0aHViLmNvbS9rZWVnYW5zdHJlZXQvc3BlY2lmaWNpdHkvYmxvYi9tYXN0ZXIvc3BlY2lmaWNpdHkuanNcbnZhciBhdHRyaWJ1dGVSZWdleCA9IC8oXFxbW15cXF1dK1xcXSkvZztcbnZhciBpZFJlZ2V4ID0gLygjW15cXHMrPn4uWzpdKykvZztcbnZhciBjbGFzc1JlZ2V4ID0gLyhcXC5bXlxccys+fi5bOl0rKS9nO1xudmFyIHBzZXVkb0VsZW1lbnRSZWdleCA9IC8oOjpbXlxccys+fi5bOl0rfDpmaXJzdC1saW5lfDpmaXJzdC1sZXR0ZXJ8OmJlZm9yZXw6YWZ0ZXIpL2dpO1xudmFyIHBzZXVkb0NsYXNzV2l0aEJyYWNrZXRzUmVnZXggPSAvKDpbXFx3LV0rXFwoW14pXSpcXCkpL2dpO1xudmFyIHBzZXVkb0NsYXNzUmVnZXggPSAvKDpbXlxccys+fi5bOl0rKS9nO1xudmFyIGVsZW1lbnRSZWdleCA9IC8oW15cXHMrPn4uWzpdKykvZztcblxuZnVuY3Rpb24gZmluZFNlbGVjdG9yTWF0Y2goc2VsZWN0b3IsIHJlZ2V4KSB7XG4gIHZhciBtYXRjaGVzID0gcmVnZXguZXhlYyhzZWxlY3Rvcik7XG5cbiAgaWYgKCFtYXRjaGVzKSB7XG4gICAgcmV0dXJuIFtzZWxlY3RvciwgMF07XG4gIH1cblxuICByZXR1cm4gW3NlbGVjdG9yLnJlcGxhY2UocmVnZXgsICcgJyksIG1hdGNoZXMubGVuZ3RoXTtcbn1cbi8qKlxyXG4gKiBNZWFzdXJlIHNlbGVjdG9yIHNwZWNpZmljaXR5LlxyXG4gKiBAcGFyYW0gc2VsZWN0b3IgLSBTZWxlY3RvciB0byBtZWFzdXJlLlxyXG4gKiBAcmV0dXJucyBTcGVjaWZpY2l0eS5cclxuICovXG5cblxuZnVuY3Rpb24gZ2V0U2VsZWN0b3JTcGVjaWZpY2l0eShzZWxlY3Rvcikge1xuICB2YXIgc3BlY2lmaWNpdHkgPSBbMCwgMCwgMF07XG4gIHZhciBjdXJyZW50U2VsZWN0b3IgPSBzZWxlY3Rvci5yZXBsYWNlKC86bm90XFwoKFteKV0qKVxcKS9nLCAnICAgICAkMSAnKS5yZXBsYWNlKC97W1xcc1xcU10qL2dtLCAnICcpO1xuICB2YXIgZGVsdGEgPSAwO1xuXG4gIHZhciBfZmluZFNlbGVjdG9yTWF0Y2ggPSBmaW5kU2VsZWN0b3JNYXRjaChjdXJyZW50U2VsZWN0b3IsIGF0dHJpYnV0ZVJlZ2V4KTtcblxuICB2YXIgX2ZpbmRTZWxlY3Rvck1hdGNoMiA9IF9zbGljZWRUb0FycmF5X19kZWZhdWx0W1wiZGVmYXVsdFwiXShfZmluZFNlbGVjdG9yTWF0Y2gsIDIpO1xuXG4gIGN1cnJlbnRTZWxlY3RvciA9IF9maW5kU2VsZWN0b3JNYXRjaDJbMF07XG4gIGRlbHRhID0gX2ZpbmRTZWxlY3Rvck1hdGNoMlsxXTtcbiAgc3BlY2lmaWNpdHlbMV0gKz0gZGVsdGE7XG5cbiAgdmFyIF9maW5kU2VsZWN0b3JNYXRjaDMgPSBmaW5kU2VsZWN0b3JNYXRjaChjdXJyZW50U2VsZWN0b3IsIGlkUmVnZXgpO1xuXG4gIHZhciBfZmluZFNlbGVjdG9yTWF0Y2g0ID0gX3NsaWNlZFRvQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF9maW5kU2VsZWN0b3JNYXRjaDMsIDIpO1xuXG4gIGN1cnJlbnRTZWxlY3RvciA9IF9maW5kU2VsZWN0b3JNYXRjaDRbMF07XG4gIGRlbHRhID0gX2ZpbmRTZWxlY3Rvck1hdGNoNFsxXTtcbiAgc3BlY2lmaWNpdHlbMF0gKz0gZGVsdGE7XG5cbiAgdmFyIF9maW5kU2VsZWN0b3JNYXRjaDUgPSBmaW5kU2VsZWN0b3JNYXRjaChjdXJyZW50U2VsZWN0b3IsIGNsYXNzUmVnZXgpO1xuXG4gIHZhciBfZmluZFNlbGVjdG9yTWF0Y2g2ID0gX3NsaWNlZFRvQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF9maW5kU2VsZWN0b3JNYXRjaDUsIDIpO1xuXG4gIGN1cnJlbnRTZWxlY3RvciA9IF9maW5kU2VsZWN0b3JNYXRjaDZbMF07XG4gIGRlbHRhID0gX2ZpbmRTZWxlY3Rvck1hdGNoNlsxXTtcbiAgc3BlY2lmaWNpdHlbMV0gKz0gZGVsdGE7XG5cbiAgdmFyIF9maW5kU2VsZWN0b3JNYXRjaDcgPSBmaW5kU2VsZWN0b3JNYXRjaChjdXJyZW50U2VsZWN0b3IsIHBzZXVkb0VsZW1lbnRSZWdleCk7XG5cbiAgdmFyIF9maW5kU2VsZWN0b3JNYXRjaDggPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX2ZpbmRTZWxlY3Rvck1hdGNoNywgMik7XG5cbiAgY3VycmVudFNlbGVjdG9yID0gX2ZpbmRTZWxlY3Rvck1hdGNoOFswXTtcbiAgZGVsdGEgPSBfZmluZFNlbGVjdG9yTWF0Y2g4WzFdO1xuICBzcGVjaWZpY2l0eVsyXSArPSBkZWx0YTtcblxuICB2YXIgX2ZpbmRTZWxlY3Rvck1hdGNoOSA9IGZpbmRTZWxlY3Rvck1hdGNoKGN1cnJlbnRTZWxlY3RvciwgcHNldWRvQ2xhc3NXaXRoQnJhY2tldHNSZWdleCk7XG5cbiAgdmFyIF9maW5kU2VsZWN0b3JNYXRjaDEwID0gX3NsaWNlZFRvQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF9maW5kU2VsZWN0b3JNYXRjaDksIDIpO1xuXG4gIGN1cnJlbnRTZWxlY3RvciA9IF9maW5kU2VsZWN0b3JNYXRjaDEwWzBdO1xuICBkZWx0YSA9IF9maW5kU2VsZWN0b3JNYXRjaDEwWzFdO1xuICBzcGVjaWZpY2l0eVsxXSArPSBkZWx0YTtcblxuICB2YXIgX2ZpbmRTZWxlY3Rvck1hdGNoMTEgPSBmaW5kU2VsZWN0b3JNYXRjaChjdXJyZW50U2VsZWN0b3IsIHBzZXVkb0NsYXNzUmVnZXgpO1xuXG4gIHZhciBfZmluZFNlbGVjdG9yTWF0Y2gxMiA9IF9zbGljZWRUb0FycmF5X19kZWZhdWx0W1wiZGVmYXVsdFwiXShfZmluZFNlbGVjdG9yTWF0Y2gxMSwgMik7XG5cbiAgY3VycmVudFNlbGVjdG9yID0gX2ZpbmRTZWxlY3Rvck1hdGNoMTJbMF07XG4gIGRlbHRhID0gX2ZpbmRTZWxlY3Rvck1hdGNoMTJbMV07XG4gIHNwZWNpZmljaXR5WzFdICs9IGRlbHRhO1xuICBjdXJyZW50U2VsZWN0b3IgPSBjdXJyZW50U2VsZWN0b3IucmVwbGFjZSgvWypcXHMrPn5dL2csICcgJykucmVwbGFjZSgvWyMuXS9nLCAnICcpO1xuXG4gIHZhciBfZmluZFNlbGVjdG9yTWF0Y2gxMyA9IGZpbmRTZWxlY3Rvck1hdGNoKGN1cnJlbnRTZWxlY3RvciwgZWxlbWVudFJlZ2V4KTtcblxuICB2YXIgX2ZpbmRTZWxlY3Rvck1hdGNoMTQgPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX2ZpbmRTZWxlY3Rvck1hdGNoMTMsIDIpO1xuXG4gIGN1cnJlbnRTZWxlY3RvciA9IF9maW5kU2VsZWN0b3JNYXRjaDE0WzBdO1xuICBkZWx0YSA9IF9maW5kU2VsZWN0b3JNYXRjaDE0WzFdO1xuICAvLyBsZ3RtIFtqcy91c2VsZXNzLWFzc2lnbm1lbnQtdG8tbG9jYWxdXG4gIHNwZWNpZmljaXR5WzJdICs9IGRlbHRhO1xuICByZXR1cm4gc3BlY2lmaWNpdHkuam9pbignJyk7XG59XG5cbnZhciBQU0VVRE9fWkVSTyA9IC4wMDAwMDAwMTtcbi8qKlxyXG4gKiBWZWN0b3IgbWFnbml0dWRlLlxyXG4gKiBAcGFyYW0gdlxyXG4gKiBAcmV0dXJucyBOdW1iZXIgcmVzdWx0LlxyXG4gKi9cblxuZnVuY3Rpb24gdmVjdG9yTWFnbml0dWRlKHYpIHtcbiAgcmV0dXJuIE1hdGguc3FydChNYXRoLnBvdyh2WzBdLCAyKSArIE1hdGgucG93KHZbMV0sIDIpKTtcbn1cbi8qKlxyXG4gKiBSYXRpbyBiZXR3ZWVuIHR3byB2ZWN0b3JzLlxyXG4gKiBAcGFyYW0gdVxyXG4gKiBAcGFyYW0gdlxyXG4gKiBAcmV0dXJucyBOdW1iZXIgcmVzdWx0LlxyXG4gKi9cblxuZnVuY3Rpb24gdmVjdG9yc1JhdGlvKHUsIHYpIHtcbiAgcmV0dXJuICh1WzBdICogdlswXSArIHVbMV0gKiB2WzFdKSAvICh2ZWN0b3JNYWduaXR1ZGUodSkgKiB2ZWN0b3JNYWduaXR1ZGUodikpO1xufVxuLyoqXHJcbiAqIEFuZ2xlIGJldHdlZW4gdHdvIHZlY3RvcnMuXHJcbiAqIEBwYXJhbSB1XHJcbiAqIEBwYXJhbSB2XHJcbiAqIEByZXR1cm5zIE51bWJlciByZXN1bHQuXHJcbiAqL1xuXG5mdW5jdGlvbiB2ZWN0b3JzQW5nbGUodSwgdikge1xuICByZXR1cm4gKHVbMF0gKiB2WzFdIDwgdVsxXSAqIHZbMF0gPyAtMSA6IDEpICogTWF0aC5hY29zKHZlY3RvcnNSYXRpbyh1LCB2KSk7XG59XG5mdW5jdGlvbiBDQjEodCkge1xuICByZXR1cm4gdCAqIHQgKiB0O1xufVxuZnVuY3Rpb24gQ0IyKHQpIHtcbiAgcmV0dXJuIDMgKiB0ICogdCAqICgxIC0gdCk7XG59XG5mdW5jdGlvbiBDQjModCkge1xuICByZXR1cm4gMyAqIHQgKiAoMSAtIHQpICogKDEgLSB0KTtcbn1cbmZ1bmN0aW9uIENCNCh0KSB7XG4gIHJldHVybiAoMSAtIHQpICogKDEgLSB0KSAqICgxIC0gdCk7XG59XG5mdW5jdGlvbiBRQjEodCkge1xuICByZXR1cm4gdCAqIHQ7XG59XG5mdW5jdGlvbiBRQjIodCkge1xuICByZXR1cm4gMiAqIHQgKiAoMSAtIHQpO1xufVxuZnVuY3Rpb24gUUIzKHQpIHtcbiAgcmV0dXJuICgxIC0gdCkgKiAoMSAtIHQpO1xufVxuXG52YXIgUHJvcGVydHkgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBQcm9wZXJ0eShkb2N1bWVudCwgbmFtZSwgdmFsdWUpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFByb3BlcnR5KTtcblxuICAgIHRoaXMuZG9jdW1lbnQgPSBkb2N1bWVudDtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLmlzTm9ybWFsaXplZENvbG9yID0gZmFsc2U7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFByb3BlcnR5LCBbe1xuICAgIGtleTogXCJzcGxpdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzcGxpdCgpIHtcbiAgICAgIHZhciBzZXBhcmF0b3IgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6ICcgJztcbiAgICAgIHZhciBkb2N1bWVudCA9IHRoaXMuZG9jdW1lbnQsXG4gICAgICAgICAgbmFtZSA9IHRoaXMubmFtZTtcbiAgICAgIHJldHVybiBjb21wcmVzc1NwYWNlcyh0aGlzLmdldFN0cmluZygpKS50cmltKCkuc3BsaXQoc2VwYXJhdG9yKS5tYXAoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvcGVydHkoZG9jdW1lbnQsIG5hbWUsIHZhbHVlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJoYXNWYWx1ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBoYXNWYWx1ZSh6ZXJvSXNWYWx1ZSkge1xuICAgICAgdmFyIHZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICAgIHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gJycgJiYgKHplcm9Jc1ZhbHVlIHx8IHZhbHVlICE9PSAwKSAmJiB0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJpc1N0cmluZ1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBpc1N0cmluZyhyZWdleHApIHtcbiAgICAgIHZhciB2YWx1ZSA9IHRoaXMudmFsdWU7XG4gICAgICB2YXIgcmVzdWx0ID0gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJztcblxuICAgICAgaWYgKCFyZXN1bHQgfHwgIXJlZ2V4cCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVnZXhwLnRlc3QodmFsdWUpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJpc1VybERlZmluaXRpb25cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gaXNVcmxEZWZpbml0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaXNTdHJpbmcoL151cmxcXCgvKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiaXNQaXhlbHNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gaXNQaXhlbHMoKSB7XG4gICAgICBpZiAoIXRoaXMuaGFzVmFsdWUoKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHZhciBhc1N0cmluZyA9IHRoaXMuZ2V0U3RyaW5nKCk7XG5cbiAgICAgIHN3aXRjaCAodHJ1ZSkge1xuICAgICAgICBjYXNlIGFzU3RyaW5nLmVuZHNXaXRoKCdweCcpOlxuICAgICAgICBjYXNlIC9eWzAtOV0rJC8udGVzdChhc1N0cmluZyk6XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNldFZhbHVlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldFZhbHVlKHZhbHVlKSB7XG4gICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0VmFsdWVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0VmFsdWUoZGVmKSB7XG4gICAgICBpZiAodHlwZW9mIGRlZiA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZGVmO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXROdW1iZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0TnVtYmVyKGRlZikge1xuICAgICAgaWYgKCF0aGlzLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBkZWYgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdChkZWYpO1xuICAgICAgfVxuXG4gICAgICB2YXIgdmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgICAgdmFyIG4gPSBwYXJzZUZsb2F0KHZhbHVlKTtcblxuICAgICAgaWYgKHRoaXMuaXNTdHJpbmcoLyUkLykpIHtcbiAgICAgICAgbiAvPSAxMDAuMDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG47XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldFN0cmluZ1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRTdHJpbmcoZGVmKSB7XG4gICAgICBpZiAodHlwZW9mIGRlZiA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdGhpcy52YWx1ZSA9PT0gJ3VuZGVmaW5lZCcgPyAnJyA6IFN0cmluZyh0aGlzLnZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFN0cmluZyhkZWYpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRDb2xvclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRDb2xvcihkZWYpIHtcbiAgICAgIHZhciBjb2xvciA9IHRoaXMuZ2V0U3RyaW5nKGRlZik7XG5cbiAgICAgIGlmICh0aGlzLmlzTm9ybWFsaXplZENvbG9yKSB7XG4gICAgICAgIHJldHVybiBjb2xvcjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc05vcm1hbGl6ZWRDb2xvciA9IHRydWU7XG4gICAgICBjb2xvciA9IG5vcm1hbGl6ZUNvbG9yKGNvbG9yKTtcbiAgICAgIHRoaXMudmFsdWUgPSBjb2xvcjtcbiAgICAgIHJldHVybiBjb2xvcjtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0RHBpXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldERwaSgpIHtcbiAgICAgIHJldHVybiA5Ni4wOyAvLyBUT0RPOiBjb21wdXRlP1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRSZW1cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UmVtKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnQucm9vdEVtU2l6ZTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0RW1cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RW0oKSB7XG4gICAgICByZXR1cm4gdGhpcy5kb2N1bWVudC5lbVNpemU7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldFVuaXRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFVuaXRzKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RyaW5nKCkucmVwbGFjZSgvWzAtOS4tXS9nLCAnJyk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldFBpeGVsc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRQaXhlbHMoYXhpc09ySXNGb250U2l6ZSkge1xuICAgICAgdmFyIHByb2Nlc3NQZXJjZW50ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBmYWxzZTtcblxuICAgICAgaWYgKCF0aGlzLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG5cbiAgICAgIHZhciBfcmVmID0gdHlwZW9mIGF4aXNPcklzRm9udFNpemUgPT09ICdib29sZWFuJyA/IFt1bmRlZmluZWQsIGF4aXNPcklzRm9udFNpemVdIDogW2F4aXNPcklzRm9udFNpemVdLFxuICAgICAgICAgIF9yZWYyID0gX3NsaWNlZFRvQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF9yZWYsIDIpLFxuICAgICAgICAgIGF4aXMgPSBfcmVmMlswXSxcbiAgICAgICAgICBpc0ZvbnRTaXplID0gX3JlZjJbMV07XG5cbiAgICAgIHZhciB2aWV3UG9ydCA9IHRoaXMuZG9jdW1lbnQuc2NyZWVuLnZpZXdQb3J0O1xuXG4gICAgICBzd2l0Y2ggKHRydWUpIHtcbiAgICAgICAgY2FzZSB0aGlzLmlzU3RyaW5nKC92bWluJC8pOlxuICAgICAgICAgIHJldHVybiB0aGlzLmdldE51bWJlcigpIC8gMTAwLjAgKiBNYXRoLm1pbih2aWV3UG9ydC5jb21wdXRlU2l6ZSgneCcpLCB2aWV3UG9ydC5jb21wdXRlU2l6ZSgneScpKTtcblxuICAgICAgICBjYXNlIHRoaXMuaXNTdHJpbmcoL3ZtYXgkLyk6XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TnVtYmVyKCkgLyAxMDAuMCAqIE1hdGgubWF4KHZpZXdQb3J0LmNvbXB1dGVTaXplKCd4JyksIHZpZXdQb3J0LmNvbXB1dGVTaXplKCd5JykpO1xuXG4gICAgICAgIGNhc2UgdGhpcy5pc1N0cmluZygvdnckLyk6XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TnVtYmVyKCkgLyAxMDAuMCAqIHZpZXdQb3J0LmNvbXB1dGVTaXplKCd4Jyk7XG5cbiAgICAgICAgY2FzZSB0aGlzLmlzU3RyaW5nKC92aCQvKTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXROdW1iZXIoKSAvIDEwMC4wICogdmlld1BvcnQuY29tcHV0ZVNpemUoJ3knKTtcblxuICAgICAgICBjYXNlIHRoaXMuaXNTdHJpbmcoL3JlbSQvKTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXROdW1iZXIoKSAqIHRoaXMuZ2V0UmVtKCk7XG5cbiAgICAgICAgY2FzZSB0aGlzLmlzU3RyaW5nKC9lbSQvKTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXROdW1iZXIoKSAqIHRoaXMuZ2V0RW0oKTtcblxuICAgICAgICBjYXNlIHRoaXMuaXNTdHJpbmcoL2V4JC8pOlxuICAgICAgICAgIHJldHVybiB0aGlzLmdldE51bWJlcigpICogdGhpcy5nZXRFbSgpIC8gMi4wO1xuXG4gICAgICAgIGNhc2UgdGhpcy5pc1N0cmluZygvcHgkLyk6XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TnVtYmVyKCk7XG5cbiAgICAgICAgY2FzZSB0aGlzLmlzU3RyaW5nKC9wdCQvKTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXROdW1iZXIoKSAqIHRoaXMuZ2V0RHBpKCkgKiAoMS4wIC8gNzIuMCk7XG5cbiAgICAgICAgY2FzZSB0aGlzLmlzU3RyaW5nKC9wYyQvKTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXROdW1iZXIoKSAqIDE1O1xuXG4gICAgICAgIGNhc2UgdGhpcy5pc1N0cmluZygvY20kLyk6XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TnVtYmVyKCkgKiB0aGlzLmdldERwaSgpIC8gMi41NDtcblxuICAgICAgICBjYXNlIHRoaXMuaXNTdHJpbmcoL21tJC8pOlxuICAgICAgICAgIHJldHVybiB0aGlzLmdldE51bWJlcigpICogdGhpcy5nZXREcGkoKSAvIDI1LjQ7XG5cbiAgICAgICAgY2FzZSB0aGlzLmlzU3RyaW5nKC9pbiQvKTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXROdW1iZXIoKSAqIHRoaXMuZ2V0RHBpKCk7XG5cbiAgICAgICAgY2FzZSB0aGlzLmlzU3RyaW5nKC8lJC8pICYmIGlzRm9udFNpemU6XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TnVtYmVyKCkgKiB0aGlzLmdldEVtKCk7XG5cbiAgICAgICAgY2FzZSB0aGlzLmlzU3RyaW5nKC8lJC8pOlxuICAgICAgICAgIHJldHVybiB0aGlzLmdldE51bWJlcigpICogdmlld1BvcnQuY29tcHV0ZVNpemUoYXhpcyk7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgbiA9IHRoaXMuZ2V0TnVtYmVyKCk7XG5cbiAgICAgICAgICAgIGlmIChwcm9jZXNzUGVyY2VudCAmJiBuIDwgMS4wKSB7XG4gICAgICAgICAgICAgIHJldHVybiBuICogdmlld1BvcnQuY29tcHV0ZVNpemUoYXhpcyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBuO1xuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0TWlsbGlzZWNvbmRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldE1pbGxpc2Vjb25kcygpIHtcbiAgICAgIGlmICghdGhpcy5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5pc1N0cmluZygvbXMkLykpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TnVtYmVyKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmdldE51bWJlcigpICogMTAwMDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0UmFkaWFuc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRSYWRpYW5zKCkge1xuICAgICAgaWYgKCF0aGlzLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAodHJ1ZSkge1xuICAgICAgICBjYXNlIHRoaXMuaXNTdHJpbmcoL2RlZyQvKTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXROdW1iZXIoKSAqIChNYXRoLlBJIC8gMTgwLjApO1xuXG4gICAgICAgIGNhc2UgdGhpcy5pc1N0cmluZygvZ3JhZCQvKTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXROdW1iZXIoKSAqIChNYXRoLlBJIC8gMjAwLjApO1xuXG4gICAgICAgIGNhc2UgdGhpcy5pc1N0cmluZygvcmFkJC8pOlxuICAgICAgICAgIHJldHVybiB0aGlzLmdldE51bWJlcigpO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TnVtYmVyKCkgKiAoTWF0aC5QSSAvIDE4MC4wKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0RGVmaW5pdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXREZWZpbml0aW9uKCkge1xuICAgICAgdmFyIGFzU3RyaW5nID0gdGhpcy5nZXRTdHJpbmcoKTtcbiAgICAgIHZhciBuYW1lID0gLyMoW14pJ1wiXSspLy5leGVjKGFzU3RyaW5nKTtcblxuICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgbmFtZSA9IG5hbWVbMV07XG4gICAgICB9XG5cbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICBuYW1lID0gYXNTdHJpbmc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmRvY3VtZW50LmRlZmluaXRpb25zW25hbWVdO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRGaWxsU3R5bGVEZWZpbml0aW9uXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEZpbGxTdHlsZURlZmluaXRpb24oZWxlbWVudCwgb3BhY2l0eSkge1xuICAgICAgdmFyIGRlZiA9IHRoaXMuZ2V0RGVmaW5pdGlvbigpO1xuXG4gICAgICBpZiAoIWRlZikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0gLy8gZ3JhZGllbnRcblxuXG4gICAgICBpZiAodHlwZW9mIGRlZi5jcmVhdGVHcmFkaWVudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gZGVmLmNyZWF0ZUdyYWRpZW50KHRoaXMuZG9jdW1lbnQuY3R4LCBlbGVtZW50LCBvcGFjaXR5KTtcbiAgICAgIH0gLy8gcGF0dGVyblxuXG5cbiAgICAgIGlmICh0eXBlb2YgZGVmLmNyZWF0ZVBhdHRlcm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgaWYgKGRlZi5nZXRIcmVmQXR0cmlidXRlKCkuaGFzVmFsdWUoKSkge1xuICAgICAgICAgIHZhciBwYXR0ZXJuVHJhbnNmb3JtID0gZGVmLmdldEF0dHJpYnV0ZSgncGF0dGVyblRyYW5zZm9ybScpO1xuICAgICAgICAgIGRlZiA9IGRlZi5nZXRIcmVmQXR0cmlidXRlKCkuZ2V0RGVmaW5pdGlvbigpO1xuXG4gICAgICAgICAgaWYgKHBhdHRlcm5UcmFuc2Zvcm0uaGFzVmFsdWUoKSkge1xuICAgICAgICAgICAgZGVmLmdldEF0dHJpYnV0ZSgncGF0dGVyblRyYW5zZm9ybScsIHRydWUpLnNldFZhbHVlKHBhdHRlcm5UcmFuc2Zvcm0udmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkZWYuY3JlYXRlUGF0dGVybih0aGlzLmRvY3VtZW50LmN0eCwgZWxlbWVudCwgb3BhY2l0eSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRUZXh0QmFzZWxpbmVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0VGV4dEJhc2VsaW5lKCkge1xuICAgICAgaWYgKCF0aGlzLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBQcm9wZXJ0eS50ZXh0QmFzZWxpbmVNYXBwaW5nW3RoaXMuZ2V0U3RyaW5nKCldO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJhZGRPcGFjaXR5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFkZE9wYWNpdHkob3BhY2l0eSkge1xuICAgICAgdmFyIHZhbHVlID0gdGhpcy5nZXRDb2xvcigpO1xuICAgICAgdmFyIGxlbiA9IHZhbHVlLmxlbmd0aDtcbiAgICAgIHZhciBjb21tYXMgPSAwOyAvLyBTaW11bGF0ZSBvbGQgUkdCQ29sb3IgdmVyc2lvbiwgd2hpY2ggY2FuJ3QgcGFyc2UgcmdiYS5cblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAodmFsdWVbaV0gPT09ICcsJykge1xuICAgICAgICAgIGNvbW1hcysrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbW1hcyA9PT0gMykge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChvcGFjaXR5Lmhhc1ZhbHVlKCkgJiYgdGhpcy5pc1N0cmluZygpICYmIGNvbW1hcyAhPT0gMykge1xuICAgICAgICB2YXIgY29sb3IgPSBuZXcgUkdCQ29sb3JfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHZhbHVlKTtcblxuICAgICAgICBpZiAoY29sb3Iub2spIHtcbiAgICAgICAgICBjb2xvci5hbHBoYSA9IG9wYWNpdHkuZ2V0TnVtYmVyKCk7XG4gICAgICAgICAgdmFsdWUgPSBjb2xvci50b1JHQkEoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IFByb3BlcnR5KHRoaXMuZG9jdW1lbnQsIHRoaXMubmFtZSwgdmFsdWUpO1xuICAgIH1cbiAgfV0sIFt7XG4gICAga2V5OiBcImVtcHR5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGVtcHR5KGRvY3VtZW50KSB7XG4gICAgICByZXR1cm4gbmV3IFByb3BlcnR5KGRvY3VtZW50LCAnRU1QVFknLCAnJyk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFByb3BlcnR5O1xufSgpO1xuUHJvcGVydHkudGV4dEJhc2VsaW5lTWFwcGluZyA9IHtcbiAgJ2Jhc2VsaW5lJzogJ2FscGhhYmV0aWMnLFxuICAnYmVmb3JlLWVkZ2UnOiAndG9wJyxcbiAgJ3RleHQtYmVmb3JlLWVkZ2UnOiAndG9wJyxcbiAgJ21pZGRsZSc6ICdtaWRkbGUnLFxuICAnY2VudHJhbCc6ICdtaWRkbGUnLFxuICAnYWZ0ZXItZWRnZSc6ICdib3R0b20nLFxuICAndGV4dC1hZnRlci1lZGdlJzogJ2JvdHRvbScsXG4gICdpZGVvZ3JhcGhpYyc6ICdpZGVvZ3JhcGhpYycsXG4gICdhbHBoYWJldGljJzogJ2FscGhhYmV0aWMnLFxuICAnaGFuZ2luZyc6ICdoYW5naW5nJyxcbiAgJ21hdGhlbWF0aWNhbCc6ICdhbHBoYWJldGljJ1xufTtcblxudmFyIFZpZXdQb3J0ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gVmlld1BvcnQoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBWaWV3UG9ydCk7XG5cbiAgICB0aGlzLnZpZXdQb3J0cyA9IFtdO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShWaWV3UG9ydCwgW3tcbiAgICBrZXk6IFwiY2xlYXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgICB0aGlzLnZpZXdQb3J0cyA9IFtdO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZXRDdXJyZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldEN1cnJlbnQod2lkdGgsIGhlaWdodCkge1xuICAgICAgdGhpcy52aWV3UG9ydHMucHVzaCh7XG4gICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHRcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW1vdmVDdXJyZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbW92ZUN1cnJlbnQoKSB7XG4gICAgICB0aGlzLnZpZXdQb3J0cy5wb3AoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0Q3VycmVudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRDdXJyZW50KCkge1xuICAgICAgdmFyIHZpZXdQb3J0cyA9IHRoaXMudmlld1BvcnRzO1xuICAgICAgcmV0dXJuIHZpZXdQb3J0c1t2aWV3UG9ydHMubGVuZ3RoIC0gMV07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNvbXB1dGVTaXplXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXB1dGVTaXplKGQpIHtcbiAgICAgIGlmICh0eXBlb2YgZCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIGQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChkID09PSAneCcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lkdGg7XG4gICAgICB9XG5cbiAgICAgIGlmIChkID09PSAneScpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGVpZ2h0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHRoaXMud2lkdGgsIDIpICsgTWF0aC5wb3codGhpcy5oZWlnaHQsIDIpKSAvIE1hdGguc3FydCgyKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwid2lkdGhcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnQoKS53aWR0aDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiaGVpZ2h0XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50KCkuaGVpZ2h0O1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBWaWV3UG9ydDtcbn0oKTtcblxudmFyIFBvaW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gUG9pbnQoeCwgeSkge1xuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgUG9pbnQpO1xuXG4gICAgdGhpcy54ID0geDtcbiAgICB0aGlzLnkgPSB5O1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShQb2ludCwgW3tcbiAgICBrZXk6IFwiYW5nbGVUb1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhbmdsZVRvKHBvaW50KSB7XG4gICAgICByZXR1cm4gTWF0aC5hdGFuMihwb2ludC55IC0gdGhpcy55LCBwb2ludC54IC0gdGhpcy54KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYXBwbHlUcmFuc2Zvcm1cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYXBwbHlUcmFuc2Zvcm0odHJhbnNmb3JtKSB7XG4gICAgICB2YXIgeCA9IHRoaXMueCxcbiAgICAgICAgICB5ID0gdGhpcy55O1xuICAgICAgdmFyIHhwID0geCAqIHRyYW5zZm9ybVswXSArIHkgKiB0cmFuc2Zvcm1bMl0gKyB0cmFuc2Zvcm1bNF07XG4gICAgICB2YXIgeXAgPSB4ICogdHJhbnNmb3JtWzFdICsgeSAqIHRyYW5zZm9ybVszXSArIHRyYW5zZm9ybVs1XTtcbiAgICAgIHRoaXMueCA9IHhwO1xuICAgICAgdGhpcy55ID0geXA7XG4gICAgfVxuICB9XSwgW3tcbiAgICBrZXk6IFwicGFyc2VcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGFyc2UocG9pbnQpIHtcbiAgICAgIHZhciBkZWZhdWx0VmFsdWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDA7XG5cbiAgICAgIHZhciBfdG9OdW1iZXJzID0gdG9OdW1iZXJzKHBvaW50KSxcbiAgICAgICAgICBfdG9OdW1iZXJzMiA9IF9zbGljZWRUb0FycmF5X19kZWZhdWx0W1wiZGVmYXVsdFwiXShfdG9OdW1iZXJzLCAyKSxcbiAgICAgICAgICBfdG9OdW1iZXJzMiQgPSBfdG9OdW1iZXJzMlswXSxcbiAgICAgICAgICB4ID0gX3RvTnVtYmVyczIkID09PSB2b2lkIDAgPyBkZWZhdWx0VmFsdWUgOiBfdG9OdW1iZXJzMiQsXG4gICAgICAgICAgX3RvTnVtYmVyczIkMiA9IF90b051bWJlcnMyWzFdLFxuICAgICAgICAgIHkgPSBfdG9OdW1iZXJzMiQyID09PSB2b2lkIDAgPyBkZWZhdWx0VmFsdWUgOiBfdG9OdW1iZXJzMiQyO1xuXG4gICAgICByZXR1cm4gbmV3IFBvaW50KHgsIHkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXJzZVNjYWxlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhcnNlU2NhbGUoc2NhbGUpIHtcbiAgICAgIHZhciBkZWZhdWx0VmFsdWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDE7XG5cbiAgICAgIHZhciBfdG9OdW1iZXJzMyA9IHRvTnVtYmVycyhzY2FsZSksXG4gICAgICAgICAgX3RvTnVtYmVyczQgPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX3RvTnVtYmVyczMsIDIpLFxuICAgICAgICAgIF90b051bWJlcnM0JCA9IF90b051bWJlcnM0WzBdLFxuICAgICAgICAgIHggPSBfdG9OdW1iZXJzNCQgPT09IHZvaWQgMCA/IGRlZmF1bHRWYWx1ZSA6IF90b051bWJlcnM0JCxcbiAgICAgICAgICBfdG9OdW1iZXJzNCQyID0gX3RvTnVtYmVyczRbMV0sXG4gICAgICAgICAgeSA9IF90b051bWJlcnM0JDIgPT09IHZvaWQgMCA/IHggOiBfdG9OdW1iZXJzNCQyO1xuXG4gICAgICByZXR1cm4gbmV3IFBvaW50KHgsIHkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXJzZVBhdGhcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGFyc2VQYXRoKHBhdGgpIHtcbiAgICAgIHZhciBwb2ludHMgPSB0b051bWJlcnMocGF0aCk7XG4gICAgICB2YXIgbGVuID0gcG9pbnRzLmxlbmd0aDtcbiAgICAgIHZhciBwYXRoUG9pbnRzID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICAgICAgcGF0aFBvaW50cy5wdXNoKG5ldyBQb2ludChwb2ludHNbaV0sIHBvaW50c1tpICsgMV0pKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhdGhQb2ludHM7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFBvaW50O1xufSgpO1xuXG52YXIgTW91c2UgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBNb3VzZShzY3JlZW4pIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIE1vdXNlKTtcblxuICAgIHRoaXMuc2NyZWVuID0gc2NyZWVuO1xuICAgIHRoaXMud29ya2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZXZlbnRzID0gW107XG4gICAgdGhpcy5ldmVudEVsZW1lbnRzID0gW107IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWFzc2lnbm1lbnRcblxuICAgIHRoaXMub25DbGljayA9IHRoaXMub25DbGljay5iaW5kKHRoaXMpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hc3NpZ25tZW50XG5cbiAgICB0aGlzLm9uTW91c2VNb3ZlID0gdGhpcy5vbk1vdXNlTW92ZS5iaW5kKHRoaXMpO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShNb3VzZSwgW3tcbiAgICBrZXk6IFwiaXNXb3JraW5nXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGlzV29ya2luZygpIHtcbiAgICAgIHJldHVybiB0aGlzLndvcmtpbmc7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInN0YXJ0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgICAgaWYgKHRoaXMud29ya2luZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBzY3JlZW4gPSB0aGlzLnNjcmVlbixcbiAgICAgICAgICBvbkNsaWNrID0gdGhpcy5vbkNsaWNrLFxuICAgICAgICAgIG9uTW91c2VNb3ZlID0gdGhpcy5vbk1vdXNlTW92ZTtcbiAgICAgIHZhciBjYW52YXMgPSBzY3JlZW4uY3R4LmNhbnZhcztcbiAgICAgIGNhbnZhcy5vbmNsaWNrID0gb25DbGljaztcbiAgICAgIGNhbnZhcy5vbm1vdXNlbW92ZSA9IG9uTW91c2VNb3ZlO1xuICAgICAgdGhpcy53b3JraW5nID0gdHJ1ZTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic3RvcFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzdG9wKCkge1xuICAgICAgaWYgKCF0aGlzLndvcmtpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgY2FudmFzID0gdGhpcy5zY3JlZW4uY3R4LmNhbnZhcztcbiAgICAgIHRoaXMud29ya2luZyA9IGZhbHNlO1xuICAgICAgY2FudmFzLm9uY2xpY2sgPSBudWxsO1xuICAgICAgY2FudmFzLm9ubW91c2Vtb3ZlID0gbnVsbDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiaGFzRXZlbnRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGhhc0V2ZW50cygpIHtcbiAgICAgIHJldHVybiB0aGlzLndvcmtpbmcgJiYgdGhpcy5ldmVudHMubGVuZ3RoID4gMDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicnVuRXZlbnRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJ1bkV2ZW50cygpIHtcbiAgICAgIGlmICghdGhpcy53b3JraW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGRvY3VtZW50ID0gdGhpcy5zY3JlZW4sXG4gICAgICAgICAgZXZlbnRzID0gdGhpcy5ldmVudHMsXG4gICAgICAgICAgZXZlbnRFbGVtZW50cyA9IHRoaXMuZXZlbnRFbGVtZW50cztcbiAgICAgIHZhciBzdHlsZSA9IGRvY3VtZW50LmN0eC5jYW52YXMuc3R5bGU7XG5cbiAgICAgIGlmIChzdHlsZSkge1xuICAgICAgICBzdHlsZS5jdXJzb3IgPSAnJztcbiAgICAgIH1cblxuICAgICAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKF9yZWYsIGkpIHtcbiAgICAgICAgdmFyIHJ1biA9IF9yZWYucnVuO1xuICAgICAgICB2YXIgZWxlbWVudCA9IGV2ZW50RWxlbWVudHNbaV07XG5cbiAgICAgICAgd2hpbGUgKGVsZW1lbnQpIHtcbiAgICAgICAgICBydW4oZWxlbWVudCk7XG4gICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50O1xuICAgICAgICB9XG4gICAgICB9KTsgLy8gZG9uZSBydW5uaW5nLCBjbGVhclxuXG4gICAgICB0aGlzLmV2ZW50cyA9IFtdO1xuICAgICAgdGhpcy5ldmVudEVsZW1lbnRzID0gW107XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNoZWNrUGF0aFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjaGVja1BhdGgoZWxlbWVudCwgY3R4KSB7XG4gICAgICBpZiAoIXRoaXMud29ya2luZyB8fCAhY3R4KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuZXZlbnRzLFxuICAgICAgICAgIGV2ZW50RWxlbWVudHMgPSB0aGlzLmV2ZW50RWxlbWVudHM7XG4gICAgICBldmVudHMuZm9yRWFjaChmdW5jdGlvbiAoX3JlZjIsIGkpIHtcbiAgICAgICAgdmFyIHggPSBfcmVmMi54LFxuICAgICAgICAgICAgeSA9IF9yZWYyLnk7XG5cbiAgICAgICAgaWYgKCFldmVudEVsZW1lbnRzW2ldICYmIGN0eC5pc1BvaW50SW5QYXRoICYmIGN0eC5pc1BvaW50SW5QYXRoKHgsIHkpKSB7XG4gICAgICAgICAgZXZlbnRFbGVtZW50c1tpXSA9IGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjaGVja0JvdW5kaW5nQm94XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNoZWNrQm91bmRpbmdCb3goZWxlbWVudCwgYm91bmRpbmdCb3gpIHtcbiAgICAgIGlmICghdGhpcy53b3JraW5nIHx8ICFib3VuZGluZ0JveCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBldmVudHMgPSB0aGlzLmV2ZW50cyxcbiAgICAgICAgICBldmVudEVsZW1lbnRzID0gdGhpcy5ldmVudEVsZW1lbnRzO1xuICAgICAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKF9yZWYzLCBpKSB7XG4gICAgICAgIHZhciB4ID0gX3JlZjMueCxcbiAgICAgICAgICAgIHkgPSBfcmVmMy55O1xuXG4gICAgICAgIGlmICghZXZlbnRFbGVtZW50c1tpXSAmJiBib3VuZGluZ0JveC5pc1BvaW50SW5Cb3goeCwgeSkpIHtcbiAgICAgICAgICBldmVudEVsZW1lbnRzW2ldID0gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIm1hcFhZXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG1hcFhZKHgsIHkpIHtcbiAgICAgIHZhciBfdGhpcyRzY3JlZW4gPSB0aGlzLnNjcmVlbixcbiAgICAgICAgICB3aW5kb3cgPSBfdGhpcyRzY3JlZW4ud2luZG93LFxuICAgICAgICAgIGN0eCA9IF90aGlzJHNjcmVlbi5jdHg7XG4gICAgICB2YXIgcG9pbnQgPSBuZXcgUG9pbnQoeCwgeSk7XG4gICAgICB2YXIgZWxlbWVudCA9IGN0eC5jYW52YXM7XG5cbiAgICAgIHdoaWxlIChlbGVtZW50KSB7XG4gICAgICAgIHBvaW50LnggLT0gZWxlbWVudC5vZmZzZXRMZWZ0O1xuICAgICAgICBwb2ludC55IC09IGVsZW1lbnQub2Zmc2V0VG9wO1xuICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5vZmZzZXRQYXJlbnQ7XG4gICAgICB9XG5cbiAgICAgIGlmICh3aW5kb3cuc2Nyb2xsWCkge1xuICAgICAgICBwb2ludC54ICs9IHdpbmRvdy5zY3JvbGxYO1xuICAgICAgfVxuXG4gICAgICBpZiAod2luZG93LnNjcm9sbFkpIHtcbiAgICAgICAgcG9pbnQueSArPSB3aW5kb3cuc2Nyb2xsWTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBvaW50O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJvbkNsaWNrXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG9uQ2xpY2soZXZlbnQpIHtcbiAgICAgIHZhciBfdGhpcyRtYXBYWSA9IHRoaXMubWFwWFkoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSksXG4gICAgICAgICAgeCA9IF90aGlzJG1hcFhZLngsXG4gICAgICAgICAgeSA9IF90aGlzJG1hcFhZLnk7XG5cbiAgICAgIHRoaXMuZXZlbnRzLnB1c2goe1xuICAgICAgICB0eXBlOiAnb25jbGljaycsXG4gICAgICAgIHg6IHgsXG4gICAgICAgIHk6IHksXG4gICAgICAgIHJ1bjogZnVuY3Rpb24gcnVuKGV2ZW50VGFyZ2V0KSB7XG4gICAgICAgICAgaWYgKGV2ZW50VGFyZ2V0Lm9uQ2xpY2spIHtcbiAgICAgICAgICAgIGV2ZW50VGFyZ2V0Lm9uQ2xpY2soKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJvbk1vdXNlTW92ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBvbk1vdXNlTW92ZShldmVudCkge1xuICAgICAgdmFyIF90aGlzJG1hcFhZMiA9IHRoaXMubWFwWFkoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSksXG4gICAgICAgICAgeCA9IF90aGlzJG1hcFhZMi54LFxuICAgICAgICAgIHkgPSBfdGhpcyRtYXBYWTIueTtcblxuICAgICAgdGhpcy5ldmVudHMucHVzaCh7XG4gICAgICAgIHR5cGU6ICdvbm1vdXNlbW92ZScsXG4gICAgICAgIHg6IHgsXG4gICAgICAgIHk6IHksXG4gICAgICAgIHJ1bjogZnVuY3Rpb24gcnVuKGV2ZW50VGFyZ2V0KSB7XG4gICAgICAgICAgaWYgKGV2ZW50VGFyZ2V0Lm9uTW91c2VNb3ZlKSB7XG4gICAgICAgICAgICBldmVudFRhcmdldC5vbk1vdXNlTW92ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIE1vdXNlO1xufSgpO1xuXG52YXIgZGVmYXVsdFdpbmRvdyA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogbnVsbDtcbnZhciBkZWZhdWx0RmV0Y2gkMSA9IHR5cGVvZiBmZXRjaCAhPT0gJ3VuZGVmaW5lZCcgPyBmZXRjaC5iaW5kKHVuZGVmaW5lZCkgLy8gYGZldGNoYCBkZXBlbmRzIG9uIGNvbnRleHQ6IGBzb21lT2JqZWN0LmZldGNoKC4uLilgIHdpbGwgdGhyb3cgZXJyb3IuXG46IG51bGw7XG5cbnZhciBTY3JlZW4gPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTY3JlZW4oY3R4KSB7XG4gICAgdmFyIF9yZWYgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9LFxuICAgICAgICBfcmVmJGZldGNoID0gX3JlZi5mZXRjaCxcbiAgICAgICAgZmV0Y2ggPSBfcmVmJGZldGNoID09PSB2b2lkIDAgPyBkZWZhdWx0RmV0Y2gkMSA6IF9yZWYkZmV0Y2gsXG4gICAgICAgIF9yZWYkd2luZG93ID0gX3JlZi53aW5kb3csXG4gICAgICAgIHdpbmRvdyA9IF9yZWYkd2luZG93ID09PSB2b2lkIDAgPyBkZWZhdWx0V2luZG93IDogX3JlZiR3aW5kb3c7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFNjcmVlbik7XG5cbiAgICB0aGlzLmN0eCA9IGN0eDtcbiAgICB0aGlzLkZSQU1FUkFURSA9IDMwO1xuICAgIHRoaXMuTUFYX1ZJUlRVQUxfUElYRUxTID0gMzAwMDA7XG4gICAgdGhpcy5DTElFTlRfV0lEVEggPSA4MDA7XG4gICAgdGhpcy5DTElFTlRfSEVJR0hUID0gNjAwO1xuICAgIHRoaXMudmlld1BvcnQgPSBuZXcgVmlld1BvcnQoKTtcbiAgICB0aGlzLm1vdXNlID0gbmV3IE1vdXNlKHRoaXMpO1xuICAgIHRoaXMuYW5pbWF0aW9ucyA9IFtdO1xuICAgIHRoaXMud2FpdHMgPSBbXTtcbiAgICB0aGlzLmZyYW1lRHVyYXRpb24gPSAwO1xuICAgIHRoaXMuaXNSZWFkeUxvY2sgPSBmYWxzZTtcbiAgICB0aGlzLmlzRmlyc3RSZW5kZXIgPSB0cnVlO1xuICAgIHRoaXMuaW50ZXJ2YWxJZCA9IG51bGw7XG4gICAgdGhpcy53aW5kb3cgPSB3aW5kb3c7XG4gICAgdGhpcy5mZXRjaCA9IGZldGNoO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShTY3JlZW4sIFt7XG4gICAga2V5OiBcIndhaXRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gd2FpdChjaGVja2VyKSB7XG4gICAgICB0aGlzLndhaXRzLnB1c2goY2hlY2tlcik7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlYWR5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlYWR5KCkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1taXN1c2VkLXByb21pc2VzXG4gICAgICBpZiAoIXRoaXMucmVhZHlQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMucmVhZHlQcm9taXNlO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJpc1JlYWR5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGlzUmVhZHkoKSB7XG4gICAgICBpZiAodGhpcy5pc1JlYWR5TG9jaykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIGlzUmVhZHlMb2NrID0gdGhpcy53YWl0cy5ldmVyeShmdW5jdGlvbiAoXykge1xuICAgICAgICByZXR1cm4gXygpO1xuICAgICAgfSk7XG5cbiAgICAgIGlmIChpc1JlYWR5TG9jaykge1xuICAgICAgICB0aGlzLndhaXRzID0gW107XG5cbiAgICAgICAgaWYgKHRoaXMucmVzb2x2ZVJlYWR5KSB7XG4gICAgICAgICAgdGhpcy5yZXNvbHZlUmVhZHkoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmlzUmVhZHlMb2NrID0gaXNSZWFkeUxvY2s7XG4gICAgICByZXR1cm4gaXNSZWFkeUxvY2s7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNldERlZmF1bHRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldERlZmF1bHRzKGN0eCkge1xuICAgICAgLy8gaW5pdGlhbCB2YWx1ZXMgYW5kIGRlZmF1bHRzXG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSAncmdiYSgwLDAsMCwwKSc7XG4gICAgICBjdHgubGluZUNhcCA9ICdidXR0JztcbiAgICAgIGN0eC5saW5lSm9pbiA9ICdtaXRlcic7XG4gICAgICBjdHgubWl0ZXJMaW1pdCA9IDQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNldFZpZXdCb3hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0Vmlld0JveChfcmVmMikge1xuICAgICAgdmFyIGRvY3VtZW50ID0gX3JlZjIuZG9jdW1lbnQsXG4gICAgICAgICAgY3R4ID0gX3JlZjIuY3R4LFxuICAgICAgICAgIGFzcGVjdFJhdGlvID0gX3JlZjIuYXNwZWN0UmF0aW8sXG4gICAgICAgICAgd2lkdGggPSBfcmVmMi53aWR0aCxcbiAgICAgICAgICBkZXNpcmVkV2lkdGggPSBfcmVmMi5kZXNpcmVkV2lkdGgsXG4gICAgICAgICAgaGVpZ2h0ID0gX3JlZjIuaGVpZ2h0LFxuICAgICAgICAgIGRlc2lyZWRIZWlnaHQgPSBfcmVmMi5kZXNpcmVkSGVpZ2h0LFxuICAgICAgICAgIF9yZWYyJG1pblggPSBfcmVmMi5taW5YLFxuICAgICAgICAgIG1pblggPSBfcmVmMiRtaW5YID09PSB2b2lkIDAgPyAwIDogX3JlZjIkbWluWCxcbiAgICAgICAgICBfcmVmMiRtaW5ZID0gX3JlZjIubWluWSxcbiAgICAgICAgICBtaW5ZID0gX3JlZjIkbWluWSA9PT0gdm9pZCAwID8gMCA6IF9yZWYyJG1pblksXG4gICAgICAgICAgcmVmWCA9IF9yZWYyLnJlZlgsXG4gICAgICAgICAgcmVmWSA9IF9yZWYyLnJlZlksXG4gICAgICAgICAgX3JlZjIkY2xpcCA9IF9yZWYyLmNsaXAsXG4gICAgICAgICAgY2xpcCA9IF9yZWYyJGNsaXAgPT09IHZvaWQgMCA/IGZhbHNlIDogX3JlZjIkY2xpcCxcbiAgICAgICAgICBfcmVmMiRjbGlwWCA9IF9yZWYyLmNsaXBYLFxuICAgICAgICAgIGNsaXBYID0gX3JlZjIkY2xpcFggPT09IHZvaWQgMCA/IDAgOiBfcmVmMiRjbGlwWCxcbiAgICAgICAgICBfcmVmMiRjbGlwWSA9IF9yZWYyLmNsaXBZLFxuICAgICAgICAgIGNsaXBZID0gX3JlZjIkY2xpcFkgPT09IHZvaWQgMCA/IDAgOiBfcmVmMiRjbGlwWTtcbiAgICAgIC8vIGFzcGVjdCByYXRpbyAtIGh0dHA6Ly93d3cudzMub3JnL1RSL1NWRy9jb29yZHMuaHRtbCNQcmVzZXJ2ZUFzcGVjdFJhdGlvQXR0cmlidXRlXG4gICAgICB2YXIgY2xlYW5Bc3BlY3RSYXRpbyA9IGNvbXByZXNzU3BhY2VzKGFzcGVjdFJhdGlvKS5yZXBsYWNlKC9eZGVmZXJcXHMvLCAnJyk7IC8vIGlnbm9yZSBkZWZlclxuXG4gICAgICB2YXIgX2NsZWFuQXNwZWN0UmF0aW8kc3BsID0gY2xlYW5Bc3BlY3RSYXRpby5zcGxpdCgnICcpLFxuICAgICAgICAgIF9jbGVhbkFzcGVjdFJhdGlvJHNwbDIgPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX2NsZWFuQXNwZWN0UmF0aW8kc3BsLCAyKSxcbiAgICAgICAgICBhc3BlY3RSYXRpb0FsaWduID0gX2NsZWFuQXNwZWN0UmF0aW8kc3BsMlswXSxcbiAgICAgICAgICBhc3BlY3RSYXRpb01lZXRPclNsaWNlID0gX2NsZWFuQXNwZWN0UmF0aW8kc3BsMlsxXTtcblxuICAgICAgdmFyIGFsaWduID0gYXNwZWN0UmF0aW9BbGlnbiB8fCAneE1pZFlNaWQnO1xuICAgICAgdmFyIG1lZXRPclNsaWNlID0gYXNwZWN0UmF0aW9NZWV0T3JTbGljZSB8fCAnbWVldCc7IC8vIGNhbGN1bGF0ZSBzY2FsZVxuXG4gICAgICB2YXIgc2NhbGVYID0gd2lkdGggLyBkZXNpcmVkV2lkdGg7XG4gICAgICB2YXIgc2NhbGVZID0gaGVpZ2h0IC8gZGVzaXJlZEhlaWdodDtcbiAgICAgIHZhciBzY2FsZU1pbiA9IE1hdGgubWluKHNjYWxlWCwgc2NhbGVZKTtcbiAgICAgIHZhciBzY2FsZU1heCA9IE1hdGgubWF4KHNjYWxlWCwgc2NhbGVZKTtcbiAgICAgIHZhciBmaW5hbERlc2lyZWRXaWR0aCA9IGRlc2lyZWRXaWR0aDtcbiAgICAgIHZhciBmaW5hbERlc2lyZWRIZWlnaHQgPSBkZXNpcmVkSGVpZ2h0O1xuXG4gICAgICBpZiAobWVldE9yU2xpY2UgPT09ICdtZWV0Jykge1xuICAgICAgICBmaW5hbERlc2lyZWRXaWR0aCAqPSBzY2FsZU1pbjtcbiAgICAgICAgZmluYWxEZXNpcmVkSGVpZ2h0ICo9IHNjYWxlTWluO1xuICAgICAgfVxuXG4gICAgICBpZiAobWVldE9yU2xpY2UgPT09ICdzbGljZScpIHtcbiAgICAgICAgZmluYWxEZXNpcmVkV2lkdGggKj0gc2NhbGVNYXg7XG4gICAgICAgIGZpbmFsRGVzaXJlZEhlaWdodCAqPSBzY2FsZU1heDtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlZlhQcm9wID0gbmV3IFByb3BlcnR5KGRvY3VtZW50LCAncmVmWCcsIHJlZlgpO1xuICAgICAgdmFyIHJlZllQcm9wID0gbmV3IFByb3BlcnR5KGRvY3VtZW50LCAncmVmWScsIHJlZlkpO1xuICAgICAgdmFyIGhhc1JlZnMgPSByZWZYUHJvcC5oYXNWYWx1ZSgpICYmIHJlZllQcm9wLmhhc1ZhbHVlKCk7XG5cbiAgICAgIGlmIChoYXNSZWZzKSB7XG4gICAgICAgIGN0eC50cmFuc2xhdGUoLXNjYWxlTWluICogcmVmWFByb3AuZ2V0UGl4ZWxzKCd4JyksIC1zY2FsZU1pbiAqIHJlZllQcm9wLmdldFBpeGVscygneScpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNsaXApIHtcbiAgICAgICAgdmFyIHNjYWxlZENsaXBYID0gc2NhbGVNaW4gKiBjbGlwWDtcbiAgICAgICAgdmFyIHNjYWxlZENsaXBZID0gc2NhbGVNaW4gKiBjbGlwWTtcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBjdHgubW92ZVRvKHNjYWxlZENsaXBYLCBzY2FsZWRDbGlwWSk7XG4gICAgICAgIGN0eC5saW5lVG8od2lkdGgsIHNjYWxlZENsaXBZKTtcbiAgICAgICAgY3R4LmxpbmVUbyh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgY3R4LmxpbmVUbyhzY2FsZWRDbGlwWCwgaGVpZ2h0KTtcbiAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICBjdHguY2xpcCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWhhc1JlZnMpIHtcbiAgICAgICAgdmFyIGlzTWVldE1pblkgPSBtZWV0T3JTbGljZSA9PT0gJ21lZXQnICYmIHNjYWxlTWluID09PSBzY2FsZVk7XG4gICAgICAgIHZhciBpc1NsaWNlTWF4WSA9IG1lZXRPclNsaWNlID09PSAnc2xpY2UnICYmIHNjYWxlTWF4ID09PSBzY2FsZVk7XG4gICAgICAgIHZhciBpc01lZXRNaW5YID0gbWVldE9yU2xpY2UgPT09ICdtZWV0JyAmJiBzY2FsZU1pbiA9PT0gc2NhbGVYO1xuICAgICAgICB2YXIgaXNTbGljZU1heFggPSBtZWV0T3JTbGljZSA9PT0gJ3NsaWNlJyAmJiBzY2FsZU1heCA9PT0gc2NhbGVYO1xuXG4gICAgICAgIGlmIChhbGlnbi5zdGFydHNXaXRoKCd4TWlkJykgJiYgKGlzTWVldE1pblkgfHwgaXNTbGljZU1heFkpKSB7XG4gICAgICAgICAgY3R4LnRyYW5zbGF0ZSh3aWR0aCAvIDIuMCAtIGZpbmFsRGVzaXJlZFdpZHRoIC8gMi4wLCAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhbGlnbi5lbmRzV2l0aCgnWU1pZCcpICYmIChpc01lZXRNaW5YIHx8IGlzU2xpY2VNYXhYKSkge1xuICAgICAgICAgIGN0eC50cmFuc2xhdGUoMCwgaGVpZ2h0IC8gMi4wIC0gZmluYWxEZXNpcmVkSGVpZ2h0IC8gMi4wKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhbGlnbi5zdGFydHNXaXRoKCd4TWF4JykgJiYgKGlzTWVldE1pblkgfHwgaXNTbGljZU1heFkpKSB7XG4gICAgICAgICAgY3R4LnRyYW5zbGF0ZSh3aWR0aCAtIGZpbmFsRGVzaXJlZFdpZHRoLCAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhbGlnbi5lbmRzV2l0aCgnWU1heCcpICYmIChpc01lZXRNaW5YIHx8IGlzU2xpY2VNYXhYKSkge1xuICAgICAgICAgIGN0eC50cmFuc2xhdGUoMCwgaGVpZ2h0IC0gZmluYWxEZXNpcmVkSGVpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBzY2FsZVxuXG5cbiAgICAgIHN3aXRjaCAodHJ1ZSkge1xuICAgICAgICBjYXNlIGFsaWduID09PSAnbm9uZSc6XG4gICAgICAgICAgY3R4LnNjYWxlKHNjYWxlWCwgc2NhbGVZKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIG1lZXRPclNsaWNlID09PSAnbWVldCc6XG4gICAgICAgICAgY3R4LnNjYWxlKHNjYWxlTWluLCBzY2FsZU1pbik7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBtZWV0T3JTbGljZSA9PT0gJ3NsaWNlJzpcbiAgICAgICAgICBjdHguc2NhbGUoc2NhbGVNYXgsIHNjYWxlTWF4KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH0gLy8gdHJhbnNsYXRlXG5cblxuICAgICAgY3R4LnRyYW5zbGF0ZSgtbWluWCwgLW1pblkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzdGFydFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzdGFydChlbGVtZW50KSB7XG4gICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICB2YXIgX3JlZjMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9LFxuICAgICAgICAgIF9yZWYzJGVuYWJsZVJlZHJhdyA9IF9yZWYzLmVuYWJsZVJlZHJhdyxcbiAgICAgICAgICBlbmFibGVSZWRyYXcgPSBfcmVmMyRlbmFibGVSZWRyYXcgPT09IHZvaWQgMCA/IGZhbHNlIDogX3JlZjMkZW5hYmxlUmVkcmF3LFxuICAgICAgICAgIF9yZWYzJGlnbm9yZU1vdXNlID0gX3JlZjMuaWdub3JlTW91c2UsXG4gICAgICAgICAgaWdub3JlTW91c2UgPSBfcmVmMyRpZ25vcmVNb3VzZSA9PT0gdm9pZCAwID8gZmFsc2UgOiBfcmVmMyRpZ25vcmVNb3VzZSxcbiAgICAgICAgICBfcmVmMyRpZ25vcmVBbmltYXRpb24gPSBfcmVmMy5pZ25vcmVBbmltYXRpb24sXG4gICAgICAgICAgaWdub3JlQW5pbWF0aW9uID0gX3JlZjMkaWdub3JlQW5pbWF0aW9uID09PSB2b2lkIDAgPyBmYWxzZSA6IF9yZWYzJGlnbm9yZUFuaW1hdGlvbixcbiAgICAgICAgICBfcmVmMyRpZ25vcmVEaW1lbnNpb24gPSBfcmVmMy5pZ25vcmVEaW1lbnNpb25zLFxuICAgICAgICAgIGlnbm9yZURpbWVuc2lvbnMgPSBfcmVmMyRpZ25vcmVEaW1lbnNpb24gPT09IHZvaWQgMCA/IGZhbHNlIDogX3JlZjMkaWdub3JlRGltZW5zaW9uLFxuICAgICAgICAgIF9yZWYzJGlnbm9yZUNsZWFyID0gX3JlZjMuaWdub3JlQ2xlYXIsXG4gICAgICAgICAgaWdub3JlQ2xlYXIgPSBfcmVmMyRpZ25vcmVDbGVhciA9PT0gdm9pZCAwID8gZmFsc2UgOiBfcmVmMyRpZ25vcmVDbGVhcixcbiAgICAgICAgICBmb3JjZVJlZHJhdyA9IF9yZWYzLmZvcmNlUmVkcmF3LFxuICAgICAgICAgIHNjYWxlV2lkdGggPSBfcmVmMy5zY2FsZVdpZHRoLFxuICAgICAgICAgIHNjYWxlSGVpZ2h0ID0gX3JlZjMuc2NhbGVIZWlnaHQsXG4gICAgICAgICAgb2Zmc2V0WCA9IF9yZWYzLm9mZnNldFgsXG4gICAgICAgICAgb2Zmc2V0WSA9IF9yZWYzLm9mZnNldFk7XG5cbiAgICAgIHZhciBGUkFNRVJBVEUgPSB0aGlzLkZSQU1FUkFURSxcbiAgICAgICAgICBtb3VzZSA9IHRoaXMubW91c2U7XG4gICAgICB2YXIgZnJhbWVEdXJhdGlvbiA9IDEwMDAgLyBGUkFNRVJBVEU7XG4gICAgICB0aGlzLmZyYW1lRHVyYXRpb24gPSBmcmFtZUR1cmF0aW9uO1xuICAgICAgdGhpcy5yZWFkeVByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICBfdGhpcy5yZXNvbHZlUmVhZHkgPSByZXNvbHZlO1xuICAgICAgfSk7XG5cbiAgICAgIGlmICh0aGlzLmlzUmVhZHkoKSkge1xuICAgICAgICB0aGlzLnJlbmRlcihlbGVtZW50LCBpZ25vcmVEaW1lbnNpb25zLCBpZ25vcmVDbGVhciwgc2NhbGVXaWR0aCwgc2NhbGVIZWlnaHQsIG9mZnNldFgsIG9mZnNldFkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVuYWJsZVJlZHJhdykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgdmFyIHRoZW4gPSBub3c7XG4gICAgICB2YXIgZGVsdGEgPSAwO1xuXG4gICAgICB2YXIgdGljayA9IGZ1bmN0aW9uIHRpY2soKSB7XG4gICAgICAgIG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGRlbHRhID0gbm93IC0gdGhlbjtcblxuICAgICAgICBpZiAoZGVsdGEgPj0gZnJhbWVEdXJhdGlvbikge1xuICAgICAgICAgIHRoZW4gPSBub3cgLSBkZWx0YSAlIGZyYW1lRHVyYXRpb247XG5cbiAgICAgICAgICBpZiAoX3RoaXMuc2hvdWxkVXBkYXRlKGlnbm9yZUFuaW1hdGlvbiwgZm9yY2VSZWRyYXcpKSB7XG4gICAgICAgICAgICBfdGhpcy5yZW5kZXIoZWxlbWVudCwgaWdub3JlRGltZW5zaW9ucywgaWdub3JlQ2xlYXIsIHNjYWxlV2lkdGgsIHNjYWxlSGVpZ2h0LCBvZmZzZXRYLCBvZmZzZXRZKTtcblxuICAgICAgICAgICAgbW91c2UucnVuRXZlbnRzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgX3RoaXMuaW50ZXJ2YWxJZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZV9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGljayk7XG4gICAgICB9O1xuXG4gICAgICBpZiAoIWlnbm9yZU1vdXNlKSB7XG4gICAgICAgIG1vdXNlLnN0YXJ0KCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuaW50ZXJ2YWxJZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZV9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGljayk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInN0b3BcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc3RvcCgpIHtcbiAgICAgIGlmICh0aGlzLmludGVydmFsSWQpIHtcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5jYW5jZWwodGhpcy5pbnRlcnZhbElkKTtcbiAgICAgICAgdGhpcy5pbnRlcnZhbElkID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5tb3VzZS5zdG9wKCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNob3VsZFVwZGF0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzaG91bGRVcGRhdGUoaWdub3JlQW5pbWF0aW9uLCBmb3JjZVJlZHJhdykge1xuICAgICAgLy8gbmVlZCB1cGRhdGUgZnJvbSBhbmltYXRpb25zP1xuICAgICAgaWYgKCFpZ25vcmVBbmltYXRpb24pIHtcbiAgICAgICAgdmFyIGZyYW1lRHVyYXRpb24gPSB0aGlzLmZyYW1lRHVyYXRpb247XG4gICAgICAgIHZhciBzaG91bGRVcGRhdGUgPSB0aGlzLmFuaW1hdGlvbnMucmVkdWNlKGZ1bmN0aW9uIChzaG91bGRVcGRhdGUsIGFuaW1hdGlvbikge1xuICAgICAgICAgIHJldHVybiBhbmltYXRpb24udXBkYXRlKGZyYW1lRHVyYXRpb24pIHx8IHNob3VsZFVwZGF0ZTtcbiAgICAgICAgfSwgZmFsc2UpO1xuXG4gICAgICAgIGlmIChzaG91bGRVcGRhdGUpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBuZWVkIHVwZGF0ZSBmcm9tIHJlZHJhdz9cblxuXG4gICAgICBpZiAodHlwZW9mIGZvcmNlUmVkcmF3ID09PSAnZnVuY3Rpb24nICYmIGZvcmNlUmVkcmF3KCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5pc1JlYWR5TG9jayAmJiB0aGlzLmlzUmVhZHkoKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gLy8gbmVlZCB1cGRhdGUgZnJvbSBtb3VzZSBldmVudHM/XG5cblxuICAgICAgaWYgKHRoaXMubW91c2UuaGFzRXZlbnRzKCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcihlbGVtZW50LCBpZ25vcmVEaW1lbnNpb25zLCBpZ25vcmVDbGVhciwgc2NhbGVXaWR0aCwgc2NhbGVIZWlnaHQsIG9mZnNldFgsIG9mZnNldFkpIHtcbiAgICAgIHZhciBDTElFTlRfV0lEVEggPSB0aGlzLkNMSUVOVF9XSURUSCxcbiAgICAgICAgICBDTElFTlRfSEVJR0hUID0gdGhpcy5DTElFTlRfSEVJR0hULFxuICAgICAgICAgIHZpZXdQb3J0ID0gdGhpcy52aWV3UG9ydCxcbiAgICAgICAgICBjdHggPSB0aGlzLmN0eCxcbiAgICAgICAgICBpc0ZpcnN0UmVuZGVyID0gdGhpcy5pc0ZpcnN0UmVuZGVyO1xuICAgICAgdmFyIGNhbnZhcyA9IGN0eC5jYW52YXM7XG4gICAgICB2aWV3UG9ydC5jbGVhcigpO1xuXG4gICAgICBpZiAoY2FudmFzLndpZHRoICYmIGNhbnZhcy5oZWlnaHQpIHtcbiAgICAgICAgdmlld1BvcnQuc2V0Q3VycmVudChjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlld1BvcnQuc2V0Q3VycmVudChDTElFTlRfV0lEVEgsIENMSUVOVF9IRUlHSFQpO1xuICAgICAgfVxuXG4gICAgICB2YXIgd2lkdGhTdHlsZSA9IGVsZW1lbnQuZ2V0U3R5bGUoJ3dpZHRoJyk7XG4gICAgICB2YXIgaGVpZ2h0U3R5bGUgPSBlbGVtZW50LmdldFN0eWxlKCdoZWlnaHQnKTtcblxuICAgICAgaWYgKCFpZ25vcmVEaW1lbnNpb25zICYmIChpc0ZpcnN0UmVuZGVyIHx8IHR5cGVvZiBzY2FsZVdpZHRoICE9PSAnbnVtYmVyJyAmJiB0eXBlb2Ygc2NhbGVIZWlnaHQgIT09ICdudW1iZXInKSkge1xuICAgICAgICAvLyBzZXQgY2FudmFzIHNpemVcbiAgICAgICAgaWYgKHdpZHRoU3R5bGUuaGFzVmFsdWUoKSkge1xuICAgICAgICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoU3R5bGUuZ2V0UGl4ZWxzKCd4Jyk7XG5cbiAgICAgICAgICBpZiAoY2FudmFzLnN0eWxlKSB7XG4gICAgICAgICAgICBjYW52YXMuc3R5bGUud2lkdGggPSBcIlwiLmNvbmNhdChjYW52YXMud2lkdGgsIFwicHhcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhlaWdodFN0eWxlLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0U3R5bGUuZ2V0UGl4ZWxzKCd5Jyk7XG5cbiAgICAgICAgICBpZiAoY2FudmFzLnN0eWxlKSB7XG4gICAgICAgICAgICBjYW52YXMuc3R5bGUuaGVpZ2h0ID0gXCJcIi5jb25jYXQoY2FudmFzLmhlaWdodCwgXCJweFwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGNXaWR0aCA9IGNhbnZhcy5jbGllbnRXaWR0aCB8fCBjYW52YXMud2lkdGg7XG4gICAgICB2YXIgY0hlaWdodCA9IGNhbnZhcy5jbGllbnRIZWlnaHQgfHwgY2FudmFzLmhlaWdodDtcblxuICAgICAgaWYgKGlnbm9yZURpbWVuc2lvbnMgJiYgd2lkdGhTdHlsZS5oYXNWYWx1ZSgpICYmIGhlaWdodFN0eWxlLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgY1dpZHRoID0gd2lkdGhTdHlsZS5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgICAgY0hlaWdodCA9IGhlaWdodFN0eWxlLmdldFBpeGVscygneScpO1xuICAgICAgfVxuXG4gICAgICB2aWV3UG9ydC5zZXRDdXJyZW50KGNXaWR0aCwgY0hlaWdodCk7XG5cbiAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0WCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3gnLCB0cnVlKS5zZXRWYWx1ZShvZmZzZXRYKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBvZmZzZXRZID09PSAnbnVtYmVyJykge1xuICAgICAgICBlbGVtZW50LmdldEF0dHJpYnV0ZSgneScsIHRydWUpLnNldFZhbHVlKG9mZnNldFkpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHNjYWxlV2lkdGggPT09ICdudW1iZXInIHx8IHR5cGVvZiBzY2FsZUhlaWdodCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgdmFyIHZpZXdCb3ggPSB0b051bWJlcnMoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3ZpZXdCb3gnKS5nZXRTdHJpbmcoKSk7XG4gICAgICAgIHZhciB4UmF0aW8gPSAwO1xuICAgICAgICB2YXIgeVJhdGlvID0gMDtcblxuICAgICAgICBpZiAodHlwZW9mIHNjYWxlV2lkdGggPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgdmFyIF93aWR0aFN0eWxlID0gZWxlbWVudC5nZXRTdHlsZSgnd2lkdGgnKTtcblxuICAgICAgICAgIGlmIChfd2lkdGhTdHlsZS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICB4UmF0aW8gPSBfd2lkdGhTdHlsZS5nZXRQaXhlbHMoJ3gnKSAvIHNjYWxlV2lkdGg7XG4gICAgICAgICAgfSBlbHNlIGlmICghaXNOYU4odmlld0JveFsyXSkpIHtcbiAgICAgICAgICAgIHhSYXRpbyA9IHZpZXdCb3hbMl0gLyBzY2FsZVdpZHRoO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2Ygc2NhbGVIZWlnaHQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgdmFyIF9oZWlnaHRTdHlsZSA9IGVsZW1lbnQuZ2V0U3R5bGUoJ2hlaWdodCcpO1xuXG4gICAgICAgICAgaWYgKF9oZWlnaHRTdHlsZS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICB5UmF0aW8gPSBfaGVpZ2h0U3R5bGUuZ2V0UGl4ZWxzKCd5JykgLyBzY2FsZUhlaWdodDtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFpc05hTih2aWV3Qm94WzNdKSkge1xuICAgICAgICAgICAgeVJhdGlvID0gdmlld0JveFszXSAvIHNjYWxlSGVpZ2h0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgheFJhdGlvKSB7XG4gICAgICAgICAgeFJhdGlvID0geVJhdGlvO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF5UmF0aW8pIHtcbiAgICAgICAgICB5UmF0aW8gPSB4UmF0aW87XG4gICAgICAgIH1cblxuICAgICAgICBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd2lkdGgnLCB0cnVlKS5zZXRWYWx1ZShzY2FsZVdpZHRoKTtcbiAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIHRydWUpLnNldFZhbHVlKHNjYWxlSGVpZ2h0KTtcbiAgICAgICAgdmFyIHRyYW5zZm9ybVN0eWxlID0gZWxlbWVudC5nZXRTdHlsZSgndHJhbnNmb3JtJywgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgIHRyYW5zZm9ybVN0eWxlLnNldFZhbHVlKFwiXCIuY29uY2F0KHRyYW5zZm9ybVN0eWxlLmdldFN0cmluZygpLCBcIiBzY2FsZShcIikuY29uY2F0KDEuMCAvIHhSYXRpbywgXCIsIFwiKS5jb25jYXQoMS4wIC8geVJhdGlvLCBcIilcIikpO1xuICAgICAgfSAvLyBjbGVhciBhbmQgcmVuZGVyXG5cblxuICAgICAgaWYgKCFpZ25vcmVDbGVhcikge1xuICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIGNXaWR0aCwgY0hlaWdodCk7XG4gICAgICB9XG5cbiAgICAgIGVsZW1lbnQucmVuZGVyKGN0eCk7XG5cbiAgICAgIGlmIChpc0ZpcnN0UmVuZGVyKSB7XG4gICAgICAgIHRoaXMuaXNGaXJzdFJlbmRlciA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBTY3JlZW47XG59KCk7XG5TY3JlZW4uZGVmYXVsdFdpbmRvdyA9IGRlZmF1bHRXaW5kb3c7XG5TY3JlZW4uZGVmYXVsdEZldGNoID0gZGVmYXVsdEZldGNoJDE7XG5cbnZhciBkZWZhdWx0RmV0Y2ggPSBTY3JlZW4uZGVmYXVsdEZldGNoO1xudmFyIERlZmF1bHRET01QYXJzZXIgPSB0eXBlb2YgRE9NUGFyc2VyICE9PSAndW5kZWZpbmVkJyA/IERPTVBhcnNlciA6IG51bGw7XG5cbnZhciBQYXJzZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBQYXJzZXIoKSB7XG4gICAgdmFyIF9yZWYgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHt9LFxuICAgICAgICBfcmVmJGZldGNoID0gX3JlZi5mZXRjaCxcbiAgICAgICAgZmV0Y2ggPSBfcmVmJGZldGNoID09PSB2b2lkIDAgPyBkZWZhdWx0RmV0Y2ggOiBfcmVmJGZldGNoLFxuICAgICAgICBfcmVmJERPTVBhcnNlciA9IF9yZWYuRE9NUGFyc2VyLFxuICAgICAgICBET01QYXJzZXIgPSBfcmVmJERPTVBhcnNlciA9PT0gdm9pZCAwID8gRGVmYXVsdERPTVBhcnNlciA6IF9yZWYkRE9NUGFyc2VyO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBQYXJzZXIpO1xuXG4gICAgdGhpcy5mZXRjaCA9IGZldGNoO1xuICAgIHRoaXMuRE9NUGFyc2VyID0gRE9NUGFyc2VyO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShQYXJzZXIsIFt7XG4gICAga2V5OiBcInBhcnNlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfcGFyc2UgPSBfYXN5bmNUb0dlbmVyYXRvcl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oIC8qI19fUFVSRV9fKi9fcmVnZW5lcmF0b3JSdW50aW1lX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUocmVzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvclJ1bnRpbWVfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLndyYXAoZnVuY3Rpb24gX2NhbGxlZSQoX2NvbnRleHQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgaWYgKCFyZXNvdXJjZS5zdGFydHNXaXRoKCc8JykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAyO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LmFicnVwdChcInJldHVyblwiLCB0aGlzLnBhcnNlRnJvbVN0cmluZyhyZXNvdXJjZSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMubG9hZChyZXNvdXJjZSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgZnVuY3Rpb24gcGFyc2UoX3gpIHtcbiAgICAgICAgcmV0dXJuIF9wYXJzZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFyc2U7XG4gICAgfSgpXG4gIH0sIHtcbiAgICBrZXk6IFwicGFyc2VGcm9tU3RyaW5nXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhcnNlRnJvbVN0cmluZyh4bWwpIHtcbiAgICAgIHZhciBwYXJzZXIgPSBuZXcgdGhpcy5ET01QYXJzZXIoKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hlY2tEb2N1bWVudChwYXJzZXIucGFyc2VGcm9tU3RyaW5nKHhtbCwgJ2ltYWdlL3N2Zyt4bWwnKSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hlY2tEb2N1bWVudChwYXJzZXIucGFyc2VGcm9tU3RyaW5nKHhtbCwgJ3RleHQveG1sJykpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjaGVja0RvY3VtZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNoZWNrRG9jdW1lbnQoZG9jdW1lbnQpIHtcbiAgICAgIHZhciBwYXJzZXJFcnJvciA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdwYXJzZXJlcnJvcicpWzBdO1xuXG4gICAgICBpZiAocGFyc2VyRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHBhcnNlckVycm9yLnRleHRDb250ZW50KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGRvY3VtZW50O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJsb2FkXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfbG9hZCA9IF9hc3luY1RvR2VuZXJhdG9yX19kZWZhdWx0W1wiZGVmYXVsdFwiXSggLyojX19QVVJFX18qL19yZWdlbmVyYXRvclJ1bnRpbWVfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLm1hcmsoZnVuY3Rpb24gX2NhbGxlZTIodXJsKSB7XG4gICAgICAgIHZhciByZXNwb25zZSwgeG1sO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yUnVudGltZV9fZGVmYXVsdFtcImRlZmF1bHRcIl0ud3JhcChmdW5jdGlvbiBfY2FsbGVlMiQoX2NvbnRleHQyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSAyO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoKHVybCk7XG5cbiAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gX2NvbnRleHQyLnNlbnQ7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSA1O1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XG5cbiAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIHhtbCA9IF9jb250ZXh0Mi5zZW50O1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDIuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMucGFyc2VGcm9tU3RyaW5nKHhtbCkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDIuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTIsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICBmdW5jdGlvbiBsb2FkKF94Mikge1xuICAgICAgICByZXR1cm4gX2xvYWQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGxvYWQ7XG4gICAgfSgpXG4gIH1dKTtcblxuICByZXR1cm4gUGFyc2VyO1xufSgpO1xuXG52YXIgVHJhbnNsYXRlID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gVHJhbnNsYXRlKF8sIHBvaW50KSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBUcmFuc2xhdGUpO1xuXG4gICAgdGhpcy50eXBlID0gJ3RyYW5zbGF0ZSc7XG4gICAgdGhpcy5wb2ludCA9IG51bGw7XG4gICAgdGhpcy5wb2ludCA9IFBvaW50LnBhcnNlKHBvaW50KTtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oVHJhbnNsYXRlLCBbe1xuICAgIGtleTogXCJhcHBseVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhcHBseShjdHgpIHtcbiAgICAgIHZhciBfdGhpcyRwb2ludCA9IHRoaXMucG9pbnQsXG4gICAgICAgICAgeCA9IF90aGlzJHBvaW50LngsXG4gICAgICAgICAgeSA9IF90aGlzJHBvaW50Lnk7XG4gICAgICBjdHgudHJhbnNsYXRlKHggfHwgMC4wLCB5IHx8IDAuMCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInVuYXBwbHlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gdW5hcHBseShjdHgpIHtcbiAgICAgIHZhciBfdGhpcyRwb2ludDIgPSB0aGlzLnBvaW50LFxuICAgICAgICAgIHggPSBfdGhpcyRwb2ludDIueCxcbiAgICAgICAgICB5ID0gX3RoaXMkcG9pbnQyLnk7XG4gICAgICBjdHgudHJhbnNsYXRlKC0xLjAgKiB4IHx8IDAuMCwgLTEuMCAqIHkgfHwgMC4wKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYXBwbHlUb1BvaW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGx5VG9Qb2ludChwb2ludCkge1xuICAgICAgdmFyIF90aGlzJHBvaW50MyA9IHRoaXMucG9pbnQsXG4gICAgICAgICAgeCA9IF90aGlzJHBvaW50My54LFxuICAgICAgICAgIHkgPSBfdGhpcyRwb2ludDMueTtcbiAgICAgIHBvaW50LmFwcGx5VHJhbnNmb3JtKFsxLCAwLCAwLCAxLCB4IHx8IDAuMCwgeSB8fCAwLjBdKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gVHJhbnNsYXRlO1xufSgpO1xuXG52YXIgUm90YXRlID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gUm90YXRlKGRvY3VtZW50LCByb3RhdGUsIHRyYW5zZm9ybU9yaWdpbikge1xuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgUm90YXRlKTtcblxuICAgIHRoaXMudHlwZSA9ICdyb3RhdGUnO1xuICAgIHRoaXMuYW5nbGUgPSBudWxsO1xuICAgIHRoaXMub3JpZ2luWCA9IG51bGw7XG4gICAgdGhpcy5vcmlnaW5ZID0gbnVsbDtcbiAgICB0aGlzLmN4ID0gMDtcbiAgICB0aGlzLmN5ID0gMDtcbiAgICB2YXIgbnVtYmVycyA9IHRvTnVtYmVycyhyb3RhdGUpO1xuICAgIHRoaXMuYW5nbGUgPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICdhbmdsZScsIG51bWJlcnNbMF0pO1xuICAgIHRoaXMub3JpZ2luWCA9IHRyYW5zZm9ybU9yaWdpblswXTtcbiAgICB0aGlzLm9yaWdpblkgPSB0cmFuc2Zvcm1PcmlnaW5bMV07XG4gICAgdGhpcy5jeCA9IG51bWJlcnNbMV0gfHwgMDtcbiAgICB0aGlzLmN5ID0gbnVtYmVyc1syXSB8fCAwO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShSb3RhdGUsIFt7XG4gICAga2V5OiBcImFwcGx5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGx5KGN0eCkge1xuICAgICAgdmFyIGN4ID0gdGhpcy5jeCxcbiAgICAgICAgICBjeSA9IHRoaXMuY3ksXG4gICAgICAgICAgb3JpZ2luWCA9IHRoaXMub3JpZ2luWCxcbiAgICAgICAgICBvcmlnaW5ZID0gdGhpcy5vcmlnaW5ZLFxuICAgICAgICAgIGFuZ2xlID0gdGhpcy5hbmdsZTtcbiAgICAgIHZhciB0eCA9IGN4ICsgb3JpZ2luWC5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgIHZhciB0eSA9IGN5ICsgb3JpZ2luWS5nZXRQaXhlbHMoJ3knKTtcbiAgICAgIGN0eC50cmFuc2xhdGUodHgsIHR5KTtcbiAgICAgIGN0eC5yb3RhdGUoYW5nbGUuZ2V0UmFkaWFucygpKTtcbiAgICAgIGN0eC50cmFuc2xhdGUoLXR4LCAtdHkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ1bmFwcGx5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHVuYXBwbHkoY3R4KSB7XG4gICAgICB2YXIgY3ggPSB0aGlzLmN4LFxuICAgICAgICAgIGN5ID0gdGhpcy5jeSxcbiAgICAgICAgICBvcmlnaW5YID0gdGhpcy5vcmlnaW5YLFxuICAgICAgICAgIG9yaWdpblkgPSB0aGlzLm9yaWdpblksXG4gICAgICAgICAgYW5nbGUgPSB0aGlzLmFuZ2xlO1xuICAgICAgdmFyIHR4ID0gY3ggKyBvcmlnaW5YLmdldFBpeGVscygneCcpO1xuICAgICAgdmFyIHR5ID0gY3kgKyBvcmlnaW5ZLmdldFBpeGVscygneScpO1xuICAgICAgY3R4LnRyYW5zbGF0ZSh0eCwgdHkpO1xuICAgICAgY3R4LnJvdGF0ZSgtMS4wICogYW5nbGUuZ2V0UmFkaWFucygpKTtcbiAgICAgIGN0eC50cmFuc2xhdGUoLXR4LCAtdHkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJhcHBseVRvUG9pbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYXBwbHlUb1BvaW50KHBvaW50KSB7XG4gICAgICB2YXIgY3ggPSB0aGlzLmN4LFxuICAgICAgICAgIGN5ID0gdGhpcy5jeSxcbiAgICAgICAgICBhbmdsZSA9IHRoaXMuYW5nbGU7XG4gICAgICB2YXIgcmFkID0gYW5nbGUuZ2V0UmFkaWFucygpO1xuICAgICAgcG9pbnQuYXBwbHlUcmFuc2Zvcm0oWzEsIDAsIDAsIDEsIGN4IHx8IDAuMCwgY3kgfHwgMC4wIC8vIHRoaXMucC55XG4gICAgICBdKTtcbiAgICAgIHBvaW50LmFwcGx5VHJhbnNmb3JtKFtNYXRoLmNvcyhyYWQpLCBNYXRoLnNpbihyYWQpLCAtTWF0aC5zaW4ocmFkKSwgTWF0aC5jb3MocmFkKSwgMCwgMF0pO1xuICAgICAgcG9pbnQuYXBwbHlUcmFuc2Zvcm0oWzEsIDAsIDAsIDEsIC1jeCB8fCAwLjAsIC1jeSB8fCAwLjAgLy8gLXRoaXMucC55XG4gICAgICBdKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gUm90YXRlO1xufSgpO1xuXG52YXIgU2NhbGUgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTY2FsZShfLCBzY2FsZSwgdHJhbnNmb3JtT3JpZ2luKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBTY2FsZSk7XG5cbiAgICB0aGlzLnR5cGUgPSAnc2NhbGUnO1xuICAgIHRoaXMuc2NhbGUgPSBudWxsO1xuICAgIHRoaXMub3JpZ2luWCA9IG51bGw7XG4gICAgdGhpcy5vcmlnaW5ZID0gbnVsbDtcbiAgICB2YXIgc2NhbGVTaXplID0gUG9pbnQucGFyc2VTY2FsZShzY2FsZSk7IC8vIFdvcmthcm91bmQgZm9yIG5vZGUtY2FudmFzXG5cbiAgICBpZiAoc2NhbGVTaXplLnggPT09IDAgfHwgc2NhbGVTaXplLnkgPT09IDApIHtcbiAgICAgIHNjYWxlU2l6ZS54ID0gUFNFVURPX1pFUk87XG4gICAgICBzY2FsZVNpemUueSA9IFBTRVVET19aRVJPO1xuICAgIH1cblxuICAgIHRoaXMuc2NhbGUgPSBzY2FsZVNpemU7XG4gICAgdGhpcy5vcmlnaW5YID0gdHJhbnNmb3JtT3JpZ2luWzBdO1xuICAgIHRoaXMub3JpZ2luWSA9IHRyYW5zZm9ybU9yaWdpblsxXTtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oU2NhbGUsIFt7XG4gICAga2V5OiBcImFwcGx5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGx5KGN0eCkge1xuICAgICAgdmFyIF90aGlzJHNjYWxlID0gdGhpcy5zY2FsZSxcbiAgICAgICAgICB4ID0gX3RoaXMkc2NhbGUueCxcbiAgICAgICAgICB5ID0gX3RoaXMkc2NhbGUueSxcbiAgICAgICAgICBvcmlnaW5YID0gdGhpcy5vcmlnaW5YLFxuICAgICAgICAgIG9yaWdpblkgPSB0aGlzLm9yaWdpblk7XG4gICAgICB2YXIgdHggPSBvcmlnaW5YLmdldFBpeGVscygneCcpO1xuICAgICAgdmFyIHR5ID0gb3JpZ2luWS5nZXRQaXhlbHMoJ3knKTtcbiAgICAgIGN0eC50cmFuc2xhdGUodHgsIHR5KTtcbiAgICAgIGN0eC5zY2FsZSh4LCB5IHx8IHgpO1xuICAgICAgY3R4LnRyYW5zbGF0ZSgtdHgsIC10eSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInVuYXBwbHlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gdW5hcHBseShjdHgpIHtcbiAgICAgIHZhciBfdGhpcyRzY2FsZTIgPSB0aGlzLnNjYWxlLFxuICAgICAgICAgIHggPSBfdGhpcyRzY2FsZTIueCxcbiAgICAgICAgICB5ID0gX3RoaXMkc2NhbGUyLnksXG4gICAgICAgICAgb3JpZ2luWCA9IHRoaXMub3JpZ2luWCxcbiAgICAgICAgICBvcmlnaW5ZID0gdGhpcy5vcmlnaW5ZO1xuICAgICAgdmFyIHR4ID0gb3JpZ2luWC5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgIHZhciB0eSA9IG9yaWdpblkuZ2V0UGl4ZWxzKCd5Jyk7XG4gICAgICBjdHgudHJhbnNsYXRlKHR4LCB0eSk7XG4gICAgICBjdHguc2NhbGUoMS4wIC8geCwgMS4wIC8geSB8fCB4KTtcbiAgICAgIGN0eC50cmFuc2xhdGUoLXR4LCAtdHkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJhcHBseVRvUG9pbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYXBwbHlUb1BvaW50KHBvaW50KSB7XG4gICAgICB2YXIgX3RoaXMkc2NhbGUzID0gdGhpcy5zY2FsZSxcbiAgICAgICAgICB4ID0gX3RoaXMkc2NhbGUzLngsXG4gICAgICAgICAgeSA9IF90aGlzJHNjYWxlMy55O1xuICAgICAgcG9pbnQuYXBwbHlUcmFuc2Zvcm0oW3ggfHwgMC4wLCAwLCAwLCB5IHx8IDAuMCwgMCwgMF0pO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBTY2FsZTtcbn0oKTtcblxudmFyIE1hdHJpeCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIE1hdHJpeChfLCBtYXRyaXgsIHRyYW5zZm9ybU9yaWdpbikge1xuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgTWF0cml4KTtcblxuICAgIHRoaXMudHlwZSA9ICdtYXRyaXgnO1xuICAgIHRoaXMubWF0cml4ID0gW107XG4gICAgdGhpcy5vcmlnaW5YID0gbnVsbDtcbiAgICB0aGlzLm9yaWdpblkgPSBudWxsO1xuICAgIHRoaXMubWF0cml4ID0gdG9OdW1iZXJzKG1hdHJpeCk7XG4gICAgdGhpcy5vcmlnaW5YID0gdHJhbnNmb3JtT3JpZ2luWzBdO1xuICAgIHRoaXMub3JpZ2luWSA9IHRyYW5zZm9ybU9yaWdpblsxXTtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oTWF0cml4LCBbe1xuICAgIGtleTogXCJhcHBseVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhcHBseShjdHgpIHtcbiAgICAgIHZhciBvcmlnaW5YID0gdGhpcy5vcmlnaW5YLFxuICAgICAgICAgIG9yaWdpblkgPSB0aGlzLm9yaWdpblksXG4gICAgICAgICAgbWF0cml4ID0gdGhpcy5tYXRyaXg7XG4gICAgICB2YXIgdHggPSBvcmlnaW5YLmdldFBpeGVscygneCcpO1xuICAgICAgdmFyIHR5ID0gb3JpZ2luWS5nZXRQaXhlbHMoJ3knKTtcbiAgICAgIGN0eC50cmFuc2xhdGUodHgsIHR5KTtcbiAgICAgIGN0eC50cmFuc2Zvcm0obWF0cml4WzBdLCBtYXRyaXhbMV0sIG1hdHJpeFsyXSwgbWF0cml4WzNdLCBtYXRyaXhbNF0sIG1hdHJpeFs1XSk7XG4gICAgICBjdHgudHJhbnNsYXRlKC10eCwgLXR5KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwidW5hcHBseVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiB1bmFwcGx5KGN0eCkge1xuICAgICAgdmFyIG9yaWdpblggPSB0aGlzLm9yaWdpblgsXG4gICAgICAgICAgb3JpZ2luWSA9IHRoaXMub3JpZ2luWSxcbiAgICAgICAgICBtYXRyaXggPSB0aGlzLm1hdHJpeDtcbiAgICAgIHZhciBhID0gbWF0cml4WzBdO1xuICAgICAgdmFyIGIgPSBtYXRyaXhbMl07XG4gICAgICB2YXIgYyA9IG1hdHJpeFs0XTtcbiAgICAgIHZhciBkID0gbWF0cml4WzFdO1xuICAgICAgdmFyIGUgPSBtYXRyaXhbM107XG4gICAgICB2YXIgZiA9IG1hdHJpeFs1XTtcbiAgICAgIHZhciBnID0gMC4wO1xuICAgICAgdmFyIGggPSAwLjA7XG4gICAgICB2YXIgaSA9IDEuMDtcbiAgICAgIHZhciBkZXQgPSAxIC8gKGEgKiAoZSAqIGkgLSBmICogaCkgLSBiICogKGQgKiBpIC0gZiAqIGcpICsgYyAqIChkICogaCAtIGUgKiBnKSk7XG4gICAgICB2YXIgdHggPSBvcmlnaW5YLmdldFBpeGVscygneCcpO1xuICAgICAgdmFyIHR5ID0gb3JpZ2luWS5nZXRQaXhlbHMoJ3knKTtcbiAgICAgIGN0eC50cmFuc2xhdGUodHgsIHR5KTtcbiAgICAgIGN0eC50cmFuc2Zvcm0oZGV0ICogKGUgKiBpIC0gZiAqIGgpLCBkZXQgKiAoZiAqIGcgLSBkICogaSksIGRldCAqIChjICogaCAtIGIgKiBpKSwgZGV0ICogKGEgKiBpIC0gYyAqIGcpLCBkZXQgKiAoYiAqIGYgLSBjICogZSksIGRldCAqIChjICogZCAtIGEgKiBmKSk7XG4gICAgICBjdHgudHJhbnNsYXRlKC10eCwgLXR5KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYXBwbHlUb1BvaW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGx5VG9Qb2ludChwb2ludCkge1xuICAgICAgcG9pbnQuYXBwbHlUcmFuc2Zvcm0odGhpcy5tYXRyaXgpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBNYXRyaXg7XG59KCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRNKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JE0oKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JE0oKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgU2tldyA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX01hdHJpeCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFNrZXcsIF9NYXRyaXgpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkTShTa2V3KTtcblxuICBmdW5jdGlvbiBTa2V3KGRvY3VtZW50LCBza2V3LCB0cmFuc2Zvcm1PcmlnaW4pIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFNrZXcpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBkb2N1bWVudCwgc2tldywgdHJhbnNmb3JtT3JpZ2luKTtcbiAgICBfdGhpcy50eXBlID0gJ3NrZXcnO1xuICAgIF90aGlzLmFuZ2xlID0gbnVsbDtcbiAgICBfdGhpcy5hbmdsZSA9IG5ldyBQcm9wZXJ0eShkb2N1bWVudCwgJ2FuZ2xlJywgc2tldyk7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIFNrZXc7XG59KE1hdHJpeCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRMKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JEwoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JEwoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgU2tld1ggPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9Ta2V3KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oU2tld1gsIF9Ta2V3KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJEwoU2tld1gpO1xuXG4gIGZ1bmN0aW9uIFNrZXdYKGRvY3VtZW50LCBza2V3LCB0cmFuc2Zvcm1PcmlnaW4pIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFNrZXdYKTtcblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgZG9jdW1lbnQsIHNrZXcsIHRyYW5zZm9ybU9yaWdpbik7XG4gICAgX3RoaXMudHlwZSA9ICdza2V3WCc7XG4gICAgX3RoaXMubWF0cml4ID0gWzEsIDAsIE1hdGgudGFuKF90aGlzLmFuZ2xlLmdldFJhZGlhbnMoKSksIDEsIDAsIDBdO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIHJldHVybiBTa2V3WDtcbn0oU2tldyk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRLKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JEsoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JEsoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgU2tld1kgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9Ta2V3KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oU2tld1ksIF9Ta2V3KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJEsoU2tld1kpO1xuXG4gIGZ1bmN0aW9uIFNrZXdZKGRvY3VtZW50LCBza2V3LCB0cmFuc2Zvcm1PcmlnaW4pIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFNrZXdZKTtcblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgZG9jdW1lbnQsIHNrZXcsIHRyYW5zZm9ybU9yaWdpbik7XG4gICAgX3RoaXMudHlwZSA9ICdza2V3WSc7XG4gICAgX3RoaXMubWF0cml4ID0gWzEsIE1hdGgudGFuKF90aGlzLmFuZ2xlLmdldFJhZGlhbnMoKSksIDAsIDEsIDAsIDBdO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIHJldHVybiBTa2V3WTtcbn0oU2tldyk7XG5cbmZ1bmN0aW9uIHBhcnNlVHJhbnNmb3Jtcyh0cmFuc2Zvcm0pIHtcbiAgcmV0dXJuIGNvbXByZXNzU3BhY2VzKHRyYW5zZm9ybSkudHJpbSgpLnJlcGxhY2UoL1xcKShbYS16QS1aXSkvZywgJykgJDEnKS5yZXBsYWNlKC9cXCkoXFxzPyxcXHM/KS9nLCAnKSAnKS5zcGxpdCgvXFxzKD89W2Etel0pLyk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlVHJhbnNmb3JtKHRyYW5zZm9ybSkge1xuICB2YXIgX3RyYW5zZm9ybSRzcGxpdCA9IHRyYW5zZm9ybS5zcGxpdCgnKCcpLFxuICAgICAgX3RyYW5zZm9ybSRzcGxpdDIgPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX3RyYW5zZm9ybSRzcGxpdCwgMiksXG4gICAgICB0eXBlID0gX3RyYW5zZm9ybSRzcGxpdDJbMF0sXG4gICAgICB2YWx1ZSA9IF90cmFuc2Zvcm0kc3BsaXQyWzFdO1xuXG4gIHJldHVybiBbdHlwZS50cmltKCksIHZhbHVlLnRyaW0oKS5yZXBsYWNlKCcpJywgJycpXTtcbn1cblxudmFyIFRyYW5zZm9ybSA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFRyYW5zZm9ybShkb2N1bWVudCwgdHJhbnNmb3JtLCB0cmFuc2Zvcm1PcmlnaW4pIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBUcmFuc2Zvcm0pO1xuXG4gICAgdGhpcy5kb2N1bWVudCA9IGRvY3VtZW50O1xuICAgIHRoaXMudHJhbnNmb3JtcyA9IFtdO1xuICAgIHZhciBkYXRhID0gcGFyc2VUcmFuc2Zvcm1zKHRyYW5zZm9ybSk7XG4gICAgZGF0YS5mb3JFYWNoKGZ1bmN0aW9uICh0cmFuc2Zvcm0pIHtcbiAgICAgIGlmICh0cmFuc2Zvcm0gPT09ICdub25lJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBfcGFyc2VUcmFuc2Zvcm0gPSBwYXJzZVRyYW5zZm9ybSh0cmFuc2Zvcm0pLFxuICAgICAgICAgIF9wYXJzZVRyYW5zZm9ybTIgPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX3BhcnNlVHJhbnNmb3JtLCAyKSxcbiAgICAgICAgICB0eXBlID0gX3BhcnNlVHJhbnNmb3JtMlswXSxcbiAgICAgICAgICB2YWx1ZSA9IF9wYXJzZVRyYW5zZm9ybTJbMV07XG5cbiAgICAgIHZhciBUcmFuc2Zvcm1UeXBlID0gVHJhbnNmb3JtLnRyYW5zZm9ybVR5cGVzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIFRyYW5zZm9ybVR5cGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIF90aGlzLnRyYW5zZm9ybXMucHVzaChuZXcgVHJhbnNmb3JtVHlwZShfdGhpcy5kb2N1bWVudCwgdmFsdWUsIHRyYW5zZm9ybU9yaWdpbikpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShUcmFuc2Zvcm0sIFt7XG4gICAga2V5OiBcImFwcGx5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGx5KGN0eCkge1xuICAgICAgdmFyIHRyYW5zZm9ybXMgPSB0aGlzLnRyYW5zZm9ybXM7XG4gICAgICB2YXIgbGVuID0gdHJhbnNmb3Jtcy5sZW5ndGg7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdHJhbnNmb3Jtc1tpXS5hcHBseShjdHgpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ1bmFwcGx5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHVuYXBwbHkoY3R4KSB7XG4gICAgICB2YXIgdHJhbnNmb3JtcyA9IHRoaXMudHJhbnNmb3JtcztcbiAgICAgIHZhciBsZW4gPSB0cmFuc2Zvcm1zLmxlbmd0aDtcblxuICAgICAgZm9yICh2YXIgaSA9IGxlbiAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHRyYW5zZm9ybXNbaV0udW5hcHBseShjdHgpO1xuICAgICAgfVxuICAgIH0gLy8gVE9ETzogYXBwbHlUb1BvaW50IHVudXNlZCAuLi4gcmVtb3ZlP1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYXBwbHlUb1BvaW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGx5VG9Qb2ludChwb2ludCkge1xuICAgICAgdmFyIHRyYW5zZm9ybXMgPSB0aGlzLnRyYW5zZm9ybXM7XG4gICAgICB2YXIgbGVuID0gdHJhbnNmb3Jtcy5sZW5ndGg7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdHJhbnNmb3Jtc1tpXS5hcHBseVRvUG9pbnQocG9pbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfV0sIFt7XG4gICAga2V5OiBcImZyb21FbGVtZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21FbGVtZW50KGRvY3VtZW50LCBlbGVtZW50KSB7XG4gICAgICB2YXIgdHJhbnNmb3JtU3R5bGUgPSBlbGVtZW50LmdldFN0eWxlKCd0cmFuc2Zvcm0nLCBmYWxzZSwgdHJ1ZSk7XG5cbiAgICAgIHZhciBfZWxlbWVudCRnZXRTdHlsZSRzcGwgPSBlbGVtZW50LmdldFN0eWxlKCd0cmFuc2Zvcm0tb3JpZ2luJywgZmFsc2UsIHRydWUpLnNwbGl0KCksXG4gICAgICAgICAgX2VsZW1lbnQkZ2V0U3R5bGUkc3BsMiA9IF9zbGljZWRUb0FycmF5X19kZWZhdWx0W1wiZGVmYXVsdFwiXShfZWxlbWVudCRnZXRTdHlsZSRzcGwsIDIpLFxuICAgICAgICAgIHRyYW5zZm9ybU9yaWdpblhQcm9wZXJ0eSA9IF9lbGVtZW50JGdldFN0eWxlJHNwbDJbMF0sXG4gICAgICAgICAgX2VsZW1lbnQkZ2V0U3R5bGUkc3BsMyA9IF9lbGVtZW50JGdldFN0eWxlJHNwbDJbMV0sXG4gICAgICAgICAgdHJhbnNmb3JtT3JpZ2luWVByb3BlcnR5ID0gX2VsZW1lbnQkZ2V0U3R5bGUkc3BsMyA9PT0gdm9pZCAwID8gdHJhbnNmb3JtT3JpZ2luWFByb3BlcnR5IDogX2VsZW1lbnQkZ2V0U3R5bGUkc3BsMztcblxuICAgICAgdmFyIHRyYW5zZm9ybU9yaWdpbiA9IFt0cmFuc2Zvcm1PcmlnaW5YUHJvcGVydHksIHRyYW5zZm9ybU9yaWdpbllQcm9wZXJ0eV07XG5cbiAgICAgIGlmICh0cmFuc2Zvcm1TdHlsZS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIHJldHVybiBuZXcgVHJhbnNmb3JtKGRvY3VtZW50LCB0cmFuc2Zvcm1TdHlsZS5nZXRTdHJpbmcoKSwgdHJhbnNmb3JtT3JpZ2luKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFRyYW5zZm9ybTtcbn0oKTtcblRyYW5zZm9ybS50cmFuc2Zvcm1UeXBlcyA9IHtcbiAgdHJhbnNsYXRlOiBUcmFuc2xhdGUsXG4gIHJvdGF0ZTogUm90YXRlLFxuICBzY2FsZTogU2NhbGUsXG4gIG1hdHJpeDogTWF0cml4LFxuICBza2V3WDogU2tld1gsXG4gIHNrZXdZOiBTa2V3WVxufTtcblxudmFyIEVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBFbGVtZW50KGRvY3VtZW50LCBub2RlKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBjYXB0dXJlVGV4dE5vZGVzID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBmYWxzZTtcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgRWxlbWVudCk7XG5cbiAgICB0aGlzLmRvY3VtZW50ID0gZG9jdW1lbnQ7XG4gICAgdGhpcy5ub2RlID0gbm9kZTtcbiAgICB0aGlzLmNhcHR1cmVUZXh0Tm9kZXMgPSBjYXB0dXJlVGV4dE5vZGVzO1xuICAgIHRoaXMuYXR0cmlidXRlcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGhpcy5zdHlsZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuc3R5bGVzU3BlY2lmaWNpdHkgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuYW5pbWF0aW9uRnJvemVuID0gZmFsc2U7XG4gICAgdGhpcy5hbmltYXRpb25Gcm96ZW5WYWx1ZSA9ICcnO1xuICAgIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgICB0aGlzLmNoaWxkcmVuID0gW107XG5cbiAgICBpZiAoIW5vZGUgfHwgbm9kZS5ub2RlVHlwZSAhPT0gMSkge1xuICAgICAgLy8gRUxFTUVOVF9OT0RFXG4gICAgICByZXR1cm47XG4gICAgfSAvLyBhZGQgYXR0cmlidXRlc1xuXG5cbiAgICBBcnJheS5mcm9tKG5vZGUuYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlKSB7XG4gICAgICB2YXIgbm9kZU5hbWUgPSBub3JtYWxpemVBdHRyaWJ1dGVOYW1lKGF0dHJpYnV0ZS5ub2RlTmFtZSk7XG4gICAgICBfdGhpcy5hdHRyaWJ1dGVzW25vZGVOYW1lXSA9IG5ldyBQcm9wZXJ0eShkb2N1bWVudCwgbm9kZU5hbWUsIGF0dHJpYnV0ZS52YWx1ZSk7XG4gICAgfSk7XG4gICAgdGhpcy5hZGRTdHlsZXNGcm9tU3R5bGVEZWZpbml0aW9uKCk7IC8vIGFkZCBpbmxpbmUgc3R5bGVzXG5cbiAgICBpZiAodGhpcy5nZXRBdHRyaWJ1dGUoJ3N0eWxlJykuaGFzVmFsdWUoKSkge1xuICAgICAgdmFyIHN0eWxlcyA9IHRoaXMuZ2V0QXR0cmlidXRlKCdzdHlsZScpLmdldFN0cmluZygpLnNwbGl0KCc7JykubWFwKGZ1bmN0aW9uIChfKSB7XG4gICAgICAgIHJldHVybiBfLnRyaW0oKTtcbiAgICAgIH0pO1xuICAgICAgc3R5bGVzLmZvckVhY2goZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgICAgIGlmICghc3R5bGUpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgX3N0eWxlJHNwbGl0JG1hcCA9IHN0eWxlLnNwbGl0KCc6JykubWFwKGZ1bmN0aW9uIChfKSB7XG4gICAgICAgICAgcmV0dXJuIF8udHJpbSgpO1xuICAgICAgICB9KSxcbiAgICAgICAgICAgIF9zdHlsZSRzcGxpdCRtYXAyID0gX3NsaWNlZFRvQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF9zdHlsZSRzcGxpdCRtYXAsIDIpLFxuICAgICAgICAgICAgbmFtZSA9IF9zdHlsZSRzcGxpdCRtYXAyWzBdLFxuICAgICAgICAgICAgdmFsdWUgPSBfc3R5bGUkc3BsaXQkbWFwMlsxXTtcblxuICAgICAgICBfdGhpcy5zdHlsZXNbbmFtZV0gPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsIG5hbWUsIHZhbHVlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBkZWZpbml0aW9ucyA9IGRvY3VtZW50LmRlZmluaXRpb25zO1xuICAgIHZhciBpZCA9IHRoaXMuZ2V0QXR0cmlidXRlKCdpZCcpOyAvLyBhZGQgaWRcblxuICAgIGlmIChpZC5oYXNWYWx1ZSgpKSB7XG4gICAgICBpZiAoIWRlZmluaXRpb25zW2lkLmdldFN0cmluZygpXSkge1xuICAgICAgICBkZWZpbml0aW9uc1tpZC5nZXRTdHJpbmcoKV0gPSB0aGlzO1xuICAgICAgfVxuICAgIH1cblxuICAgIEFycmF5LmZyb20obm9kZS5jaGlsZE5vZGVzKS5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZE5vZGUpIHtcbiAgICAgIGlmIChjaGlsZE5vZGUubm9kZVR5cGUgPT09IDEpIHtcbiAgICAgICAgX3RoaXMuYWRkQ2hpbGQoY2hpbGROb2RlKTsgLy8gRUxFTUVOVF9OT0RFXG5cbiAgICAgIH0gZWxzZSBpZiAoY2FwdHVyZVRleHROb2RlcyAmJiAoY2hpbGROb2RlLm5vZGVUeXBlID09PSAzIHx8IGNoaWxkTm9kZS5ub2RlVHlwZSA9PT0gNCkpIHtcbiAgICAgICAgdmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY2hpbGROb2RlKTtcblxuICAgICAgICBpZiAodGV4dE5vZGUuZ2V0VGV4dCgpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBfdGhpcy5hZGRDaGlsZCh0ZXh0Tm9kZSk7IC8vIFRFWFRfTk9ERVxuXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oRWxlbWVudCwgW3tcbiAgICBrZXk6IFwiZ2V0QXR0cmlidXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEF0dHJpYnV0ZShuYW1lKSB7XG4gICAgICB2YXIgY3JlYXRlSWZOb3RFeGlzdHMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZhbHNlO1xuICAgICAgdmFyIGF0dHIgPSB0aGlzLmF0dHJpYnV0ZXNbbmFtZV07XG5cbiAgICAgIGlmICghYXR0ciAmJiBjcmVhdGVJZk5vdEV4aXN0cykge1xuICAgICAgICB2YXIgX2F0dHIgPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgbmFtZSwgJycpO1xuXG4gICAgICAgIHRoaXMuYXR0cmlidXRlc1tuYW1lXSA9IF9hdHRyO1xuICAgICAgICByZXR1cm4gX2F0dHI7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhdHRyIHx8IFByb3BlcnR5LmVtcHR5KHRoaXMuZG9jdW1lbnQpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRIcmVmQXR0cmlidXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEhyZWZBdHRyaWJ1dGUoKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcy5hdHRyaWJ1dGVzKSB7XG4gICAgICAgIGlmIChrZXkgPT09ICdocmVmJyB8fCBrZXkuZW5kc1dpdGgoJzpocmVmJykpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFByb3BlcnR5LmVtcHR5KHRoaXMuZG9jdW1lbnQpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRTdHlsZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRTdHlsZShuYW1lKSB7XG4gICAgICB2YXIgY3JlYXRlSWZOb3RFeGlzdHMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZhbHNlO1xuICAgICAgdmFyIHNraXBBbmNlc3RvcnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IGZhbHNlO1xuICAgICAgdmFyIHN0eWxlID0gdGhpcy5zdHlsZXNbbmFtZV07XG5cbiAgICAgIGlmIChzdHlsZSkge1xuICAgICAgICByZXR1cm4gc3R5bGU7XG4gICAgICB9XG5cbiAgICAgIHZhciBhdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUobmFtZSk7XG5cbiAgICAgIGlmIChhdHRyICE9PSBudWxsICYmIGF0dHIgIT09IHZvaWQgMCAmJiBhdHRyLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgdGhpcy5zdHlsZXNbbmFtZV0gPSBhdHRyOyAvLyBtb3ZlIHVwIHRvIG1lIHRvIGNhY2hlXG5cbiAgICAgICAgcmV0dXJuIGF0dHI7XG4gICAgICB9XG5cbiAgICAgIGlmICghc2tpcEFuY2VzdG9ycykge1xuICAgICAgICB2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnQ7XG5cbiAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgIHZhciBwYXJlbnRTdHlsZSA9IHBhcmVudC5nZXRTdHlsZShuYW1lKTtcblxuICAgICAgICAgIGlmIChwYXJlbnRTdHlsZSAhPT0gbnVsbCAmJiBwYXJlbnRTdHlsZSAhPT0gdm9pZCAwICYmIHBhcmVudFN0eWxlLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJlbnRTdHlsZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNyZWF0ZUlmTm90RXhpc3RzKSB7XG4gICAgICAgIHZhciBfc3R5bGUgPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgbmFtZSwgJycpO1xuXG4gICAgICAgIHRoaXMuc3R5bGVzW25hbWVdID0gX3N0eWxlO1xuICAgICAgICByZXR1cm4gX3N0eWxlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc3R5bGUgfHwgUHJvcGVydHkuZW1wdHkodGhpcy5kb2N1bWVudCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoY3R4KSB7XG4gICAgICAvLyBkb24ndCByZW5kZXIgZGlzcGxheT1ub25lXG4gICAgICAvLyBkb24ndCByZW5kZXIgdmlzaWJpbGl0eT1oaWRkZW5cbiAgICAgIGlmICh0aGlzLmdldFN0eWxlKCdkaXNwbGF5JykuZ2V0U3RyaW5nKCkgPT09ICdub25lJyB8fCB0aGlzLmdldFN0eWxlKCd2aXNpYmlsaXR5JykuZ2V0U3RyaW5nKCkgPT09ICdoaWRkZW4nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY3R4LnNhdmUoKTtcblxuICAgICAgaWYgKHRoaXMuZ2V0U3R5bGUoJ21hc2snKS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIC8vIG1hc2tcbiAgICAgICAgdmFyIG1hc2sgPSB0aGlzLmdldFN0eWxlKCdtYXNrJykuZ2V0RGVmaW5pdGlvbigpO1xuXG4gICAgICAgIGlmIChtYXNrKSB7XG4gICAgICAgICAgdGhpcy5hcHBseUVmZmVjdHMoY3R4KTtcbiAgICAgICAgICBtYXNrLmFwcGx5KGN0eCwgdGhpcyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5nZXRTdHlsZSgnZmlsdGVyJykuZ2V0VmFsdWUoJ25vbmUnKSAhPT0gJ25vbmUnKSB7XG4gICAgICAgIC8vIGZpbHRlclxuICAgICAgICB2YXIgZmlsdGVyID0gdGhpcy5nZXRTdHlsZSgnZmlsdGVyJykuZ2V0RGVmaW5pdGlvbigpO1xuXG4gICAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgICB0aGlzLmFwcGx5RWZmZWN0cyhjdHgpO1xuICAgICAgICAgIGZpbHRlci5hcHBseShjdHgsIHRoaXMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldENvbnRleHQoY3R4KTtcbiAgICAgICAgdGhpcy5yZW5kZXJDaGlsZHJlbihjdHgpO1xuICAgICAgICB0aGlzLmNsZWFyQ29udGV4dChjdHgpO1xuICAgICAgfVxuXG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZXRDb250ZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldENvbnRleHQoXykgey8vIE5PIFJFTkRFUlxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJhcHBseUVmZmVjdHNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYXBwbHlFZmZlY3RzKGN0eCkge1xuICAgICAgLy8gdHJhbnNmb3JtXG4gICAgICB2YXIgdHJhbnNmb3JtID0gVHJhbnNmb3JtLmZyb21FbGVtZW50KHRoaXMuZG9jdW1lbnQsIHRoaXMpO1xuXG4gICAgICBpZiAodHJhbnNmb3JtKSB7XG4gICAgICAgIHRyYW5zZm9ybS5hcHBseShjdHgpO1xuICAgICAgfSAvLyBjbGlwXG5cblxuICAgICAgdmFyIGNsaXBQYXRoU3R5bGVQcm9wID0gdGhpcy5nZXRTdHlsZSgnY2xpcC1wYXRoJywgZmFsc2UsIHRydWUpO1xuXG4gICAgICBpZiAoY2xpcFBhdGhTdHlsZVByb3AuaGFzVmFsdWUoKSkge1xuICAgICAgICB2YXIgY2xpcCA9IGNsaXBQYXRoU3R5bGVQcm9wLmdldERlZmluaXRpb24oKTtcblxuICAgICAgICBpZiAoY2xpcCkge1xuICAgICAgICAgIGNsaXAuYXBwbHkoY3R4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjbGVhckNvbnRleHRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY2xlYXJDb250ZXh0KF8pIHsvLyBOTyBSRU5ERVJcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyQ2hpbGRyZW5cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyQ2hpbGRyZW4oY3R4KSB7XG4gICAgICB0aGlzLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIGNoaWxkLnJlbmRlcihjdHgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImFkZENoaWxkXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFkZENoaWxkKGNoaWxkTm9kZSkge1xuICAgICAgdmFyIGNoaWxkID0gY2hpbGROb2RlIGluc3RhbmNlb2YgRWxlbWVudCA/IGNoaWxkTm9kZSA6IHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChjaGlsZE5vZGUpO1xuICAgICAgY2hpbGQucGFyZW50ID0gdGhpcztcblxuICAgICAgaWYgKCFFbGVtZW50Lmlnbm9yZUNoaWxkVHlwZXMuaW5jbHVkZXMoY2hpbGQudHlwZSkpIHtcbiAgICAgICAgdGhpcy5jaGlsZHJlbi5wdXNoKGNoaWxkKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwibWF0Y2hlc1NlbGVjdG9yXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG1hdGNoZXNTZWxlY3RvcihzZWxlY3Rvcikge1xuICAgICAgdmFyIF9ub2RlJGdldEF0dHJpYnV0ZTtcblxuICAgICAgdmFyIG5vZGUgPSB0aGlzLm5vZGU7XG5cbiAgICAgIGlmICh0eXBlb2Ygbm9kZS5tYXRjaGVzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBub2RlLm1hdGNoZXMoc2VsZWN0b3IpO1xuICAgICAgfVxuXG4gICAgICB2YXIgc3R5bGVDbGFzc2VzID0gKF9ub2RlJGdldEF0dHJpYnV0ZSA9IG5vZGUuZ2V0QXR0cmlidXRlKSA9PT0gbnVsbCB8fCBfbm9kZSRnZXRBdHRyaWJ1dGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9ub2RlJGdldEF0dHJpYnV0ZS5jYWxsKG5vZGUsICdjbGFzcycpO1xuXG4gICAgICBpZiAoIXN0eWxlQ2xhc3NlcyB8fCBzdHlsZUNsYXNzZXMgPT09ICcnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN0eWxlQ2xhc3Nlcy5zcGxpdCgnICcpLnNvbWUoZnVuY3Rpb24gKHN0eWxlQ2xhc3MpIHtcbiAgICAgICAgcmV0dXJuIFwiLlwiLmNvbmNhdChzdHlsZUNsYXNzKSA9PT0gc2VsZWN0b3I7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYWRkU3R5bGVzRnJvbVN0eWxlRGVmaW5pdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRTdHlsZXNGcm9tU3R5bGVEZWZpbml0aW9uKCkge1xuICAgICAgdmFyIF90aGlzJGRvY3VtZW50ID0gdGhpcy5kb2N1bWVudCxcbiAgICAgICAgICBzdHlsZXMgPSBfdGhpcyRkb2N1bWVudC5zdHlsZXMsXG4gICAgICAgICAgc3R5bGVzU3BlY2lmaWNpdHkgPSBfdGhpcyRkb2N1bWVudC5zdHlsZXNTcGVjaWZpY2l0eTtcblxuICAgICAgZm9yICh2YXIgc2VsZWN0b3IgaW4gc3R5bGVzKSB7XG4gICAgICAgIGlmICghc2VsZWN0b3Iuc3RhcnRzV2l0aCgnQCcpICYmIHRoaXMubWF0Y2hlc1NlbGVjdG9yKHNlbGVjdG9yKSkge1xuICAgICAgICAgIHZhciBzdHlsZSA9IHN0eWxlc1tzZWxlY3Rvcl07XG4gICAgICAgICAgdmFyIHNwZWNpZmljaXR5ID0gc3R5bGVzU3BlY2lmaWNpdHlbc2VsZWN0b3JdO1xuXG4gICAgICAgICAgaWYgKHN0eWxlKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBuYW1lIGluIHN0eWxlKSB7XG4gICAgICAgICAgICAgIHZhciBleGlzdGluZ1NwZWNpZmljaXR5ID0gdGhpcy5zdHlsZXNTcGVjaWZpY2l0eVtuYW1lXTtcblxuICAgICAgICAgICAgICBpZiAodHlwZW9mIGV4aXN0aW5nU3BlY2lmaWNpdHkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgZXhpc3RpbmdTcGVjaWZpY2l0eSA9ICcwMDAnO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKHNwZWNpZmljaXR5ID49IGV4aXN0aW5nU3BlY2lmaWNpdHkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0eWxlc1tuYW1lXSA9IHN0eWxlW25hbWVdO1xuICAgICAgICAgICAgICAgIHRoaXMuc3R5bGVzU3BlY2lmaWNpdHlbbmFtZV0gPSBzcGVjaWZpY2l0eTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW1vdmVTdHlsZXNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVtb3ZlU3R5bGVzKGVsZW1lbnQsIGlnbm9yZVN0eWxlcykge1xuICAgICAgdmFyIHRvUmVzdG9yZSA9IGlnbm9yZVN0eWxlcy5yZWR1Y2UoZnVuY3Rpb24gKHRvUmVzdG9yZSwgbmFtZSkge1xuICAgICAgICB2YXIgc3R5bGVQcm9wID0gZWxlbWVudC5nZXRTdHlsZShuYW1lKTtcblxuICAgICAgICBpZiAoIXN0eWxlUHJvcC5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgcmV0dXJuIHRvUmVzdG9yZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB2YWx1ZSA9IHN0eWxlUHJvcC5nZXRTdHJpbmcoKTtcbiAgICAgICAgc3R5bGVQcm9wLnNldFZhbHVlKCcnKTtcbiAgICAgICAgcmV0dXJuIFtdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRvUmVzdG9yZSksIFtbbmFtZSwgdmFsdWVdXSk7XG4gICAgICB9LCBbXSk7XG4gICAgICByZXR1cm4gdG9SZXN0b3JlO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZXN0b3JlU3R5bGVzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlc3RvcmVTdHlsZXMoZWxlbWVudCwgc3R5bGVzKSB7XG4gICAgICBzdHlsZXMuZm9yRWFjaChmdW5jdGlvbiAoX3JlZikge1xuICAgICAgICB2YXIgX3JlZjIgPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX3JlZiwgMiksXG4gICAgICAgICAgICBuYW1lID0gX3JlZjJbMF0sXG4gICAgICAgICAgICB2YWx1ZSA9IF9yZWYyWzFdO1xuXG4gICAgICAgIGVsZW1lbnQuZ2V0U3R5bGUobmFtZSwgdHJ1ZSkuc2V0VmFsdWUodmFsdWUpO1xuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImlzRmlyc3RDaGlsZFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBpc0ZpcnN0Q2hpbGQoKSB7XG4gICAgICB2YXIgX3RoaXMkcGFyZW50O1xuXG4gICAgICByZXR1cm4gKChfdGhpcyRwYXJlbnQgPSB0aGlzLnBhcmVudCkgPT09IG51bGwgfHwgX3RoaXMkcGFyZW50ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfdGhpcyRwYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzKSkgPT09IDA7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIEVsZW1lbnQ7XG59KCk7XG5FbGVtZW50Lmlnbm9yZUNoaWxkVHlwZXMgPSBbJ3RpdGxlJ107XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRKKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JEooKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JEooKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgVW5rbm93bkVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9FbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oVW5rbm93bkVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJEooVW5rbm93bkVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIFVua25vd25FbGVtZW50KGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBVbmtub3duRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIHJldHVybiBVbmtub3duRWxlbWVudDtcbn0oRWxlbWVudCk7XG5cbmZ1bmN0aW9uIHdyYXBGb250RmFtaWx5KGZvbnRGYW1pbHkpIHtcbiAgdmFyIHRyaW1tZWQgPSBmb250RmFtaWx5LnRyaW0oKTtcbiAgcmV0dXJuIC9eKCd8XCIpLy50ZXN0KHRyaW1tZWQpID8gdHJpbW1lZCA6IFwiXFxcIlwiLmNvbmNhdCh0cmltbWVkLCBcIlxcXCJcIik7XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVGb250RmFtaWx5KGZvbnRGYW1pbHkpIHtcbiAgcmV0dXJuIHR5cGVvZiBwcm9jZXNzID09PSAndW5kZWZpbmVkJyA/IGZvbnRGYW1pbHkgOiBmb250RmFtaWx5LnRyaW0oKS5zcGxpdCgnLCcpLm1hcCh3cmFwRm9udEZhbWlseSkuam9pbignLCcpO1xufVxuLyoqXHJcbiAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9mb250LXN0eWxlXHJcbiAqIEBwYXJhbSBmb250U3R5bGVcclxuICogQHJldHVybnMgQ1NTIGZvbnQgc3R5bGUuXHJcbiAqL1xuXG5cbmZ1bmN0aW9uIHByZXBhcmVGb250U3R5bGUoZm9udFN0eWxlKSB7XG4gIGlmICghZm9udFN0eWxlKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgdmFyIHRhcmdldEZvbnRTdHlsZSA9IGZvbnRTdHlsZS50cmltKCkudG9Mb3dlckNhc2UoKTtcblxuICBzd2l0Y2ggKHRhcmdldEZvbnRTdHlsZSkge1xuICAgIGNhc2UgJ25vcm1hbCc6XG4gICAgY2FzZSAnaXRhbGljJzpcbiAgICBjYXNlICdvYmxpcXVlJzpcbiAgICBjYXNlICdpbmhlcml0JzpcbiAgICBjYXNlICdpbml0aWFsJzpcbiAgICBjYXNlICd1bnNldCc6XG4gICAgICByZXR1cm4gdGFyZ2V0Rm9udFN0eWxlO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGlmICgvXm9ibGlxdWVcXHMrKC18KVxcZCtkZWckLy50ZXN0KHRhcmdldEZvbnRTdHlsZSkpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldEZvbnRTdHlsZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuICcnO1xuICB9XG59XG4vKipcclxuICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL2ZvbnQtd2VpZ2h0XHJcbiAqIEBwYXJhbSBmb250V2VpZ2h0XHJcbiAqIEByZXR1cm5zIENTUyBmb250IHdlaWdodC5cclxuICovXG5cblxuZnVuY3Rpb24gcHJlcGFyZUZvbnRXZWlnaHQoZm9udFdlaWdodCkge1xuICBpZiAoIWZvbnRXZWlnaHQpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICB2YXIgdGFyZ2V0Rm9udFdlaWdodCA9IGZvbnRXZWlnaHQudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG5cbiAgc3dpdGNoICh0YXJnZXRGb250V2VpZ2h0KSB7XG4gICAgY2FzZSAnbm9ybWFsJzpcbiAgICBjYXNlICdib2xkJzpcbiAgICBjYXNlICdsaWdodGVyJzpcbiAgICBjYXNlICdib2xkZXInOlxuICAgIGNhc2UgJ2luaGVyaXQnOlxuICAgIGNhc2UgJ2luaXRpYWwnOlxuICAgIGNhc2UgJ3Vuc2V0JzpcbiAgICAgIHJldHVybiB0YXJnZXRGb250V2VpZ2h0O1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGlmICgvXltcXGQuXSskLy50ZXN0KHRhcmdldEZvbnRXZWlnaHQpKSB7XG4gICAgICAgIHJldHVybiB0YXJnZXRGb250V2VpZ2h0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gJyc7XG4gIH1cbn1cblxudmFyIEZvbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBGb250KGZvbnRTdHlsZSwgZm9udFZhcmlhbnQsIGZvbnRXZWlnaHQsIGZvbnRTaXplLCBmb250RmFtaWx5LCBpbmhlcml0KSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBGb250KTtcblxuICAgIHZhciBpbmhlcml0Rm9udCA9IGluaGVyaXQgPyB0eXBlb2YgaW5oZXJpdCA9PT0gJ3N0cmluZycgPyBGb250LnBhcnNlKGluaGVyaXQpIDogaW5oZXJpdCA6IHt9O1xuICAgIHRoaXMuZm9udEZhbWlseSA9IGZvbnRGYW1pbHkgfHwgaW5oZXJpdEZvbnQuZm9udEZhbWlseTtcbiAgICB0aGlzLmZvbnRTaXplID0gZm9udFNpemUgfHwgaW5oZXJpdEZvbnQuZm9udFNpemU7XG4gICAgdGhpcy5mb250U3R5bGUgPSBmb250U3R5bGUgfHwgaW5oZXJpdEZvbnQuZm9udFN0eWxlO1xuICAgIHRoaXMuZm9udFdlaWdodCA9IGZvbnRXZWlnaHQgfHwgaW5oZXJpdEZvbnQuZm9udFdlaWdodDtcbiAgICB0aGlzLmZvbnRWYXJpYW50ID0gZm9udFZhcmlhbnQgfHwgaW5oZXJpdEZvbnQuZm9udFZhcmlhbnQ7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEZvbnQsIFt7XG4gICAga2V5OiBcInRvU3RyaW5nXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgcmV0dXJuIFtwcmVwYXJlRm9udFN0eWxlKHRoaXMuZm9udFN0eWxlKSwgdGhpcy5mb250VmFyaWFudCwgcHJlcGFyZUZvbnRXZWlnaHQodGhpcy5mb250V2VpZ2h0KSwgdGhpcy5mb250U2l6ZSwgLy8gV3JhcCBmb250RmFtaWx5IG9ubHkgb24gbm9kZWpzIGFuZCBvbmx5IGZvciBjYW52YXMuY3R4XG4gICAgICBwcmVwYXJlRm9udEZhbWlseSh0aGlzLmZvbnRGYW1pbHkpXS5qb2luKCcgJykudHJpbSgpO1xuICAgIH1cbiAgfV0sIFt7XG4gICAga2V5OiBcInBhcnNlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhcnNlKCkge1xuICAgICAgdmFyIGZvbnQgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6ICcnO1xuICAgICAgdmFyIGluaGVyaXQgPSBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZDtcbiAgICAgIHZhciBmb250U3R5bGUgPSAnJztcbiAgICAgIHZhciBmb250VmFyaWFudCA9ICcnO1xuICAgICAgdmFyIGZvbnRXZWlnaHQgPSAnJztcbiAgICAgIHZhciBmb250U2l6ZSA9ICcnO1xuICAgICAgdmFyIGZvbnRGYW1pbHkgPSAnJztcbiAgICAgIHZhciBwYXJ0cyA9IGNvbXByZXNzU3BhY2VzKGZvbnQpLnRyaW0oKS5zcGxpdCgnICcpO1xuICAgICAgdmFyIHNldCA9IHtcbiAgICAgICAgZm9udFNpemU6IGZhbHNlLFxuICAgICAgICBmb250U3R5bGU6IGZhbHNlLFxuICAgICAgICBmb250V2VpZ2h0OiBmYWxzZSxcbiAgICAgICAgZm9udFZhcmlhbnQ6IGZhbHNlXG4gICAgICB9O1xuICAgICAgcGFydHMuZm9yRWFjaChmdW5jdGlvbiAocGFydCkge1xuICAgICAgICBzd2l0Y2ggKHRydWUpIHtcbiAgICAgICAgICBjYXNlICFzZXQuZm9udFN0eWxlICYmIEZvbnQuc3R5bGVzLmluY2x1ZGVzKHBhcnQpOlxuICAgICAgICAgICAgaWYgKHBhcnQgIT09ICdpbmhlcml0Jykge1xuICAgICAgICAgICAgICBmb250U3R5bGUgPSBwYXJ0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXQuZm9udFN0eWxlID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSAhc2V0LmZvbnRWYXJpYW50ICYmIEZvbnQudmFyaWFudHMuaW5jbHVkZXMocGFydCk6XG4gICAgICAgICAgICBpZiAocGFydCAhPT0gJ2luaGVyaXQnKSB7XG4gICAgICAgICAgICAgIGZvbnRWYXJpYW50ID0gcGFydDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2V0LmZvbnRTdHlsZSA9IHRydWU7XG4gICAgICAgICAgICBzZXQuZm9udFZhcmlhbnQgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlICFzZXQuZm9udFdlaWdodCAmJiBGb250LndlaWdodHMuaW5jbHVkZXMocGFydCk6XG4gICAgICAgICAgICBpZiAocGFydCAhPT0gJ2luaGVyaXQnKSB7XG4gICAgICAgICAgICAgIGZvbnRXZWlnaHQgPSBwYXJ0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXQuZm9udFN0eWxlID0gdHJ1ZTtcbiAgICAgICAgICAgIHNldC5mb250VmFyaWFudCA9IHRydWU7XG4gICAgICAgICAgICBzZXQuZm9udFdlaWdodCA9IHRydWU7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgIXNldC5mb250U2l6ZTpcbiAgICAgICAgICAgIGlmIChwYXJ0ICE9PSAnaW5oZXJpdCcpIHtcbiAgICAgICAgICAgICAgdmFyIF9wYXJ0JHNwbGl0ID0gcGFydC5zcGxpdCgnLycpO1xuXG4gICAgICAgICAgICAgIHZhciBfcGFydCRzcGxpdDIgPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX3BhcnQkc3BsaXQsIDEpO1xuXG4gICAgICAgICAgICAgIGZvbnRTaXplID0gX3BhcnQkc3BsaXQyWzBdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXQuZm9udFN0eWxlID0gdHJ1ZTtcbiAgICAgICAgICAgIHNldC5mb250VmFyaWFudCA9IHRydWU7XG4gICAgICAgICAgICBzZXQuZm9udFdlaWdodCA9IHRydWU7XG4gICAgICAgICAgICBzZXQuZm9udFNpemUgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgaWYgKHBhcnQgIT09ICdpbmhlcml0Jykge1xuICAgICAgICAgICAgICBmb250RmFtaWx5ICs9IHBhcnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gbmV3IEZvbnQoZm9udFN0eWxlLCBmb250VmFyaWFudCwgZm9udFdlaWdodCwgZm9udFNpemUsIGZvbnRGYW1pbHksIGluaGVyaXQpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBGb250O1xufSgpO1xuRm9udC5zdHlsZXMgPSAnbm9ybWFsfGl0YWxpY3xvYmxpcXVlfGluaGVyaXQnO1xuRm9udC52YXJpYW50cyA9ICdub3JtYWx8c21hbGwtY2Fwc3xpbmhlcml0JztcbkZvbnQud2VpZ2h0cyA9ICdub3JtYWx8Ym9sZHxib2xkZXJ8bGlnaHRlcnwxMDB8MjAwfDMwMHw0MDB8NTAwfDYwMHw3MDB8ODAwfDkwMHxpbmhlcml0JztcblxudmFyIEJvdW5kaW5nQm94ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gQm91bmRpbmdCb3goKSB7XG4gICAgdmFyIHgxID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBOdW1iZXIuTmFOO1xuICAgIHZhciB5MSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogTnVtYmVyLk5hTjtcbiAgICB2YXIgeDIgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IE51bWJlci5OYU47XG4gICAgdmFyIHkyID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiBOdW1iZXIuTmFOO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBCb3VuZGluZ0JveCk7XG5cbiAgICB0aGlzLngxID0geDE7XG4gICAgdGhpcy55MSA9IHkxO1xuICAgIHRoaXMueDIgPSB4MjtcbiAgICB0aGlzLnkyID0geTI7XG4gICAgdGhpcy5hZGRQb2ludCh4MSwgeTEpO1xuICAgIHRoaXMuYWRkUG9pbnQoeDIsIHkyKTtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oQm91bmRpbmdCb3gsIFt7XG4gICAga2V5OiBcImFkZFBvaW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFkZFBvaW50KHgsIHkpIHtcbiAgICAgIGlmICh0eXBlb2YgeCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKGlzTmFOKHRoaXMueDEpIHx8IGlzTmFOKHRoaXMueDIpKSB7XG4gICAgICAgICAgdGhpcy54MSA9IHg7XG4gICAgICAgICAgdGhpcy54MiA9IHg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoeCA8IHRoaXMueDEpIHtcbiAgICAgICAgICB0aGlzLngxID0geDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh4ID4gdGhpcy54Mikge1xuICAgICAgICAgIHRoaXMueDIgPSB4O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgeSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKGlzTmFOKHRoaXMueTEpIHx8IGlzTmFOKHRoaXMueTIpKSB7XG4gICAgICAgICAgdGhpcy55MSA9IHk7XG4gICAgICAgICAgdGhpcy55MiA9IHk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoeSA8IHRoaXMueTEpIHtcbiAgICAgICAgICB0aGlzLnkxID0geTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh5ID4gdGhpcy55Mikge1xuICAgICAgICAgIHRoaXMueTIgPSB5O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImFkZFhcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYWRkWCh4KSB7XG4gICAgICB0aGlzLmFkZFBvaW50KHgsIG51bGwpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJhZGRZXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFkZFkoeSkge1xuICAgICAgdGhpcy5hZGRQb2ludChudWxsLCB5KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYWRkQm91bmRpbmdCb3hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYWRkQm91bmRpbmdCb3goYm91bmRpbmdCb3gpIHtcbiAgICAgIGlmICghYm91bmRpbmdCb3gpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgeDEgPSBib3VuZGluZ0JveC54MSxcbiAgICAgICAgICB5MSA9IGJvdW5kaW5nQm94LnkxLFxuICAgICAgICAgIHgyID0gYm91bmRpbmdCb3gueDIsXG4gICAgICAgICAgeTIgPSBib3VuZGluZ0JveC55MjtcbiAgICAgIHRoaXMuYWRkUG9pbnQoeDEsIHkxKTtcbiAgICAgIHRoaXMuYWRkUG9pbnQoeDIsIHkyKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwic3VtQ3ViaWNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc3VtQ3ViaWModCwgcDAsIHAxLCBwMiwgcDMpIHtcbiAgICAgIHJldHVybiBNYXRoLnBvdygxIC0gdCwgMykgKiBwMCArIDMgKiBNYXRoLnBvdygxIC0gdCwgMikgKiB0ICogcDEgKyAzICogKDEgLSB0KSAqIE1hdGgucG93KHQsIDIpICogcDIgKyBNYXRoLnBvdyh0LCAzKSAqIHAzO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJiZXppZXJDdXJ2ZUFkZFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBiZXppZXJDdXJ2ZUFkZChmb3JYLCBwMCwgcDEsIHAyLCBwMykge1xuICAgICAgdmFyIGIgPSA2ICogcDAgLSAxMiAqIHAxICsgNiAqIHAyO1xuICAgICAgdmFyIGEgPSAtMyAqIHAwICsgOSAqIHAxIC0gOSAqIHAyICsgMyAqIHAzO1xuICAgICAgdmFyIGMgPSAzICogcDEgLSAzICogcDA7XG5cbiAgICAgIGlmIChhID09PSAwKSB7XG4gICAgICAgIGlmIChiID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHQgPSAtYyAvIGI7XG5cbiAgICAgICAgaWYgKDAgPCB0ICYmIHQgPCAxKSB7XG4gICAgICAgICAgaWYgKGZvclgpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkWCh0aGlzLnN1bUN1YmljKHQsIHAwLCBwMSwgcDIsIHAzKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYWRkWSh0aGlzLnN1bUN1YmljKHQsIHAwLCBwMSwgcDIsIHAzKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgYjJhYyA9IE1hdGgucG93KGIsIDIpIC0gNCAqIGMgKiBhO1xuXG4gICAgICBpZiAoYjJhYyA8IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgdDEgPSAoLWIgKyBNYXRoLnNxcnQoYjJhYykpIC8gKDIgKiBhKTtcblxuICAgICAgaWYgKDAgPCB0MSAmJiB0MSA8IDEpIHtcbiAgICAgICAgaWYgKGZvclgpIHtcbiAgICAgICAgICB0aGlzLmFkZFgodGhpcy5zdW1DdWJpYyh0MSwgcDAsIHAxLCBwMiwgcDMpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmFkZFkodGhpcy5zdW1DdWJpYyh0MSwgcDAsIHAxLCBwMiwgcDMpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgdDIgPSAoLWIgLSBNYXRoLnNxcnQoYjJhYykpIC8gKDIgKiBhKTtcblxuICAgICAgaWYgKDAgPCB0MiAmJiB0MiA8IDEpIHtcbiAgICAgICAgaWYgKGZvclgpIHtcbiAgICAgICAgICB0aGlzLmFkZFgodGhpcy5zdW1DdWJpYyh0MiwgcDAsIHAxLCBwMiwgcDMpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmFkZFkodGhpcy5zdW1DdWJpYyh0MiwgcDAsIHAxLCBwMiwgcDMpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gLy8gZnJvbSBodHRwOi8vYmxvZy5oYWNrZXJzLWNhZmUubmV0LzIwMDkvMDYvaG93LXRvLWNhbGN1bGF0ZS1iZXppZXItY3VydmVzLWJvdW5kaW5nLmh0bWxcblxuICB9LCB7XG4gICAga2V5OiBcImFkZEJlemllckN1cnZlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFkZEJlemllckN1cnZlKHAweCwgcDB5LCBwMXgsIHAxeSwgcDJ4LCBwMnksIHAzeCwgcDN5KSB7XG4gICAgICB0aGlzLmFkZFBvaW50KHAweCwgcDB5KTtcbiAgICAgIHRoaXMuYWRkUG9pbnQocDN4LCBwM3kpO1xuICAgICAgdGhpcy5iZXppZXJDdXJ2ZUFkZCh0cnVlLCBwMHgsIHAxeCwgcDJ4LCBwM3gpO1xuICAgICAgdGhpcy5iZXppZXJDdXJ2ZUFkZChmYWxzZSwgcDB5LCBwMXksIHAyeSwgcDN5KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYWRkUXVhZHJhdGljQ3VydmVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYWRkUXVhZHJhdGljQ3VydmUocDB4LCBwMHksIHAxeCwgcDF5LCBwMngsIHAyeSkge1xuICAgICAgdmFyIGNwMXggPSBwMHggKyAyIC8gMyAqIChwMXggLSBwMHgpOyAvLyBDUDEgPSBRUDAgKyAyLzMgKihRUDEtUVAwKVxuXG4gICAgICB2YXIgY3AxeSA9IHAweSArIDIgLyAzICogKHAxeSAtIHAweSk7IC8vIENQMSA9IFFQMCArIDIvMyAqKFFQMS1RUDApXG5cbiAgICAgIHZhciBjcDJ4ID0gY3AxeCArIDEgLyAzICogKHAyeCAtIHAweCk7IC8vIENQMiA9IENQMSArIDEvMyAqKFFQMi1RUDApXG5cbiAgICAgIHZhciBjcDJ5ID0gY3AxeSArIDEgLyAzICogKHAyeSAtIHAweSk7IC8vIENQMiA9IENQMSArIDEvMyAqKFFQMi1RUDApXG5cbiAgICAgIHRoaXMuYWRkQmV6aWVyQ3VydmUocDB4LCBwMHksIGNwMXgsIGNwMngsIGNwMXksIGNwMnksIHAyeCwgcDJ5KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiaXNQb2ludEluQm94XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGlzUG9pbnRJbkJveCh4LCB5KSB7XG4gICAgICB2YXIgeDEgPSB0aGlzLngxLFxuICAgICAgICAgIHkxID0gdGhpcy55MSxcbiAgICAgICAgICB4MiA9IHRoaXMueDIsXG4gICAgICAgICAgeTIgPSB0aGlzLnkyO1xuICAgICAgcmV0dXJuIHgxIDw9IHggJiYgeCA8PSB4MiAmJiB5MSA8PSB5ICYmIHkgPD0geTI7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInhcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLngxO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ5XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy55MTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwid2lkdGhcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLngyIC0gdGhpcy54MTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiaGVpZ2h0XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy55MiAtIHRoaXMueTE7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIEJvdW5kaW5nQm94O1xufSgpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkSShEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRJKCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRJKCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIFBhdGhQYXJzZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9TVkdQYXRoRGF0YSkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFBhdGhQYXJzZXIsIF9TVkdQYXRoRGF0YSk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciRJKFBhdGhQYXJzZXIpO1xuXG4gIGZ1bmN0aW9uIFBhdGhQYXJzZXIocGF0aCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgUGF0aFBhcnNlcik7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHBhdGggLy8gRml4IHNwYWNlcyBhZnRlciBzaWducy5cbiAgICAucmVwbGFjZSgvKFsrXFwtLl0pXFxzKy9nbSwgJyQxJykgLy8gUmVtb3ZlIGludmFsaWQgcGFydC5cbiAgICAucmVwbGFjZSgvW15NbVp6TGxIaFZ2Q2NTc1FxVHRBYWVcXGRcXHMuLCstXS4qL2csICcnKSk7XG4gICAgX3RoaXMuY29udHJvbCA9IG51bGw7XG4gICAgX3RoaXMuc3RhcnQgPSBudWxsO1xuICAgIF90aGlzLmN1cnJlbnQgPSBudWxsO1xuICAgIF90aGlzLmNvbW1hbmQgPSBudWxsO1xuICAgIF90aGlzLmNvbW1hbmRzID0gX3RoaXMuY29tbWFuZHM7XG4gICAgX3RoaXMuaSA9IC0xO1xuICAgIF90aGlzLnByZXZpb3VzQ29tbWFuZCA9IG51bGw7XG4gICAgX3RoaXMucG9pbnRzID0gW107XG4gICAgX3RoaXMuYW5nbGVzID0gW107XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShQYXRoUGFyc2VyLCBbe1xuICAgIGtleTogXCJyZXNldFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZXNldCgpIHtcbiAgICAgIHRoaXMuaSA9IC0xO1xuICAgICAgdGhpcy5jb21tYW5kID0gbnVsbDtcbiAgICAgIHRoaXMucHJldmlvdXNDb21tYW5kID0gbnVsbDtcbiAgICAgIHRoaXMuc3RhcnQgPSBuZXcgUG9pbnQoMCwgMCk7XG4gICAgICB0aGlzLmNvbnRyb2wgPSBuZXcgUG9pbnQoMCwgMCk7XG4gICAgICB0aGlzLmN1cnJlbnQgPSBuZXcgUG9pbnQoMCwgMCk7XG4gICAgICB0aGlzLnBvaW50cyA9IFtdO1xuICAgICAgdGhpcy5hbmdsZXMgPSBbXTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiaXNFbmRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gaXNFbmQoKSB7XG4gICAgICB2YXIgaSA9IHRoaXMuaSxcbiAgICAgICAgICBjb21tYW5kcyA9IHRoaXMuY29tbWFuZHM7XG4gICAgICByZXR1cm4gaSA+PSBjb21tYW5kcy5sZW5ndGggLSAxO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJuZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgICB2YXIgY29tbWFuZCA9IHRoaXMuY29tbWFuZHNbKyt0aGlzLmldO1xuICAgICAgdGhpcy5wcmV2aW91c0NvbW1hbmQgPSB0aGlzLmNvbW1hbmQ7XG4gICAgICB0aGlzLmNvbW1hbmQgPSBjb21tYW5kO1xuICAgICAgcmV0dXJuIGNvbW1hbmQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldFBvaW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFBvaW50KCkge1xuICAgICAgdmFyIHhQcm9wID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiAneCc7XG4gICAgICB2YXIgeVByb3AgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6ICd5JztcbiAgICAgIHZhciBwb2ludCA9IG5ldyBQb2ludCh0aGlzLmNvbW1hbmRbeFByb3BdLCB0aGlzLmNvbW1hbmRbeVByb3BdKTtcbiAgICAgIHJldHVybiB0aGlzLm1ha2VBYnNvbHV0ZShwb2ludCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldEFzQ29udHJvbFBvaW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEFzQ29udHJvbFBvaW50KHhQcm9wLCB5UHJvcCkge1xuICAgICAgdmFyIHBvaW50ID0gdGhpcy5nZXRQb2ludCh4UHJvcCwgeVByb3ApO1xuICAgICAgdGhpcy5jb250cm9sID0gcG9pbnQ7XG4gICAgICByZXR1cm4gcG9pbnQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldEFzQ3VycmVudFBvaW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEFzQ3VycmVudFBvaW50KHhQcm9wLCB5UHJvcCkge1xuICAgICAgdmFyIHBvaW50ID0gdGhpcy5nZXRQb2ludCh4UHJvcCwgeVByb3ApO1xuICAgICAgdGhpcy5jdXJyZW50ID0gcG9pbnQ7XG4gICAgICByZXR1cm4gcG9pbnQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldFJlZmxlY3RlZENvbnRyb2xQb2ludFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRSZWZsZWN0ZWRDb250cm9sUG9pbnQoKSB7XG4gICAgICB2YXIgcHJldmlvdXNDb21tYW5kID0gdGhpcy5wcmV2aW91c0NvbW1hbmQudHlwZTtcblxuICAgICAgaWYgKHByZXZpb3VzQ29tbWFuZCAhPT0gc3ZnUGF0aGRhdGEuU1ZHUGF0aERhdGEuQ1VSVkVfVE8gJiYgcHJldmlvdXNDb21tYW5kICE9PSBzdmdQYXRoZGF0YS5TVkdQYXRoRGF0YS5TTU9PVEhfQ1VSVkVfVE8gJiYgcHJldmlvdXNDb21tYW5kICE9PSBzdmdQYXRoZGF0YS5TVkdQYXRoRGF0YS5RVUFEX1RPICYmIHByZXZpb3VzQ29tbWFuZCAhPT0gc3ZnUGF0aGRhdGEuU1ZHUGF0aERhdGEuU01PT1RIX1FVQURfVE8pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudDtcbiAgICAgIH0gLy8gcmVmbGVjdCBwb2ludFxuXG5cbiAgICAgIHZhciBfdGhpcyRjdXJyZW50ID0gdGhpcy5jdXJyZW50LFxuICAgICAgICAgIGN4ID0gX3RoaXMkY3VycmVudC54LFxuICAgICAgICAgIGN5ID0gX3RoaXMkY3VycmVudC55LFxuICAgICAgICAgIF90aGlzJGNvbnRyb2wgPSB0aGlzLmNvbnRyb2wsXG4gICAgICAgICAgb3ggPSBfdGhpcyRjb250cm9sLngsXG4gICAgICAgICAgb3kgPSBfdGhpcyRjb250cm9sLnk7XG4gICAgICB2YXIgcG9pbnQgPSBuZXcgUG9pbnQoMiAqIGN4IC0gb3gsIDIgKiBjeSAtIG95KTtcbiAgICAgIHJldHVybiBwb2ludDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwibWFrZUFic29sdXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG1ha2VBYnNvbHV0ZShwb2ludCkge1xuICAgICAgaWYgKHRoaXMuY29tbWFuZC5yZWxhdGl2ZSkge1xuICAgICAgICB2YXIgX3RoaXMkY3VycmVudDIgPSB0aGlzLmN1cnJlbnQsXG4gICAgICAgICAgICB4ID0gX3RoaXMkY3VycmVudDIueCxcbiAgICAgICAgICAgIHkgPSBfdGhpcyRjdXJyZW50Mi55O1xuICAgICAgICBwb2ludC54ICs9IHg7XG4gICAgICAgIHBvaW50LnkgKz0geTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBvaW50O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJhZGRNYXJrZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYWRkTWFya2VyKHBvaW50LCBmcm9tLCBwcmlvclRvKSB7XG4gICAgICB2YXIgcG9pbnRzID0gdGhpcy5wb2ludHMsXG4gICAgICAgICAgYW5nbGVzID0gdGhpcy5hbmdsZXM7IC8vIGlmIHRoZSBsYXN0IGFuZ2xlIGlzbid0IGZpbGxlZCBpbiBiZWNhdXNlIHdlIGRpZG4ndCBoYXZlIHRoaXMgcG9pbnQgeWV0IC4uLlxuXG4gICAgICBpZiAocHJpb3JUbyAmJiBhbmdsZXMubGVuZ3RoID4gMCAmJiAhYW5nbGVzW2FuZ2xlcy5sZW5ndGggLSAxXSkge1xuICAgICAgICBhbmdsZXNbYW5nbGVzLmxlbmd0aCAtIDFdID0gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXS5hbmdsZVRvKHByaW9yVG8pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmFkZE1hcmtlckFuZ2xlKHBvaW50LCBmcm9tID8gZnJvbS5hbmdsZVRvKHBvaW50KSA6IG51bGwpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJhZGRNYXJrZXJBbmdsZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRNYXJrZXJBbmdsZShwb2ludCwgYW5nbGUpIHtcbiAgICAgIHRoaXMucG9pbnRzLnB1c2gocG9pbnQpO1xuICAgICAgdGhpcy5hbmdsZXMucHVzaChhbmdsZSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldE1hcmtlclBvaW50c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRNYXJrZXJQb2ludHMoKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb2ludHM7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldE1hcmtlckFuZ2xlc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRNYXJrZXJBbmdsZXMoKSB7XG4gICAgICB2YXIgYW5nbGVzID0gdGhpcy5hbmdsZXM7XG4gICAgICB2YXIgbGVuID0gYW5nbGVzLmxlbmd0aDtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAoIWFuZ2xlc1tpXSkge1xuICAgICAgICAgIGZvciAodmFyIGogPSBpICsgMTsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgICBpZiAoYW5nbGVzW2pdKSB7XG4gICAgICAgICAgICAgIGFuZ2xlc1tpXSA9IGFuZ2xlc1tqXTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhbmdsZXM7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFBhdGhQYXJzZXI7XG59KHN2Z1BhdGhkYXRhLlNWR1BhdGhEYXRhKTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJEgoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkSCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkSCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBSZW5kZXJlZEVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9FbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oUmVuZGVyZWRFbGVtZW50LCBfRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciRIKFJlbmRlcmVkRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gUmVuZGVyZWRFbGVtZW50KCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgUmVuZGVyZWRFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgX3RoaXMubW9kaWZpZWRFbVNpemVTdGFjayA9IGZhbHNlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oUmVuZGVyZWRFbGVtZW50LCBbe1xuICAgIGtleTogXCJjYWxjdWxhdGVPcGFjaXR5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNhbGN1bGF0ZU9wYWNpdHkoKSB7XG4gICAgICB2YXIgb3BhY2l0eSA9IDEuMDsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzLCBjb25zaXN0ZW50LXRoaXNcblxuICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzO1xuXG4gICAgICB3aGlsZSAoZWxlbWVudCkge1xuICAgICAgICB2YXIgb3BhY2l0eVN0eWxlID0gZWxlbWVudC5nZXRTdHlsZSgnb3BhY2l0eScsIGZhbHNlLCB0cnVlKTsgLy8gbm8gYW5jZXN0b3JzIG9uIHN0eWxlIGNhbGxcblxuICAgICAgICBpZiAob3BhY2l0eVN0eWxlLmhhc1ZhbHVlKHRydWUpKSB7XG4gICAgICAgICAgb3BhY2l0eSAqPSBvcGFjaXR5U3R5bGUuZ2V0TnVtYmVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvcGFjaXR5O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJzZXRDb250ZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldENvbnRleHQoY3R4KSB7XG4gICAgICB2YXIgZnJvbU1lYXN1cmUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZhbHNlO1xuXG4gICAgICBpZiAoIWZyb21NZWFzdXJlKSB7XG4gICAgICAgIC8vIGNhdXNlcyBzdGFjayBvdmVyZmxvdyB3aGVuIG1lYXN1cmluZyB0ZXh0IHdpdGggZ3JhZGllbnRzXG4gICAgICAgIC8vIGZpbGxcbiAgICAgICAgdmFyIGZpbGxTdHlsZVByb3AgPSB0aGlzLmdldFN0eWxlKCdmaWxsJyk7XG4gICAgICAgIHZhciBmaWxsT3BhY2l0eVN0eWxlUHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ2ZpbGwtb3BhY2l0eScpO1xuICAgICAgICB2YXIgc3Ryb2tlU3R5bGVQcm9wID0gdGhpcy5nZXRTdHlsZSgnc3Ryb2tlJyk7XG4gICAgICAgIHZhciBzdHJva2VPcGFjaXR5UHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ3N0cm9rZS1vcGFjaXR5Jyk7XG5cbiAgICAgICAgaWYgKGZpbGxTdHlsZVByb3AuaXNVcmxEZWZpbml0aW9uKCkpIHtcbiAgICAgICAgICB2YXIgZmlsbFN0eWxlID0gZmlsbFN0eWxlUHJvcC5nZXRGaWxsU3R5bGVEZWZpbml0aW9uKHRoaXMsIGZpbGxPcGFjaXR5U3R5bGVQcm9wKTtcblxuICAgICAgICAgIGlmIChmaWxsU3R5bGUpIHtcbiAgICAgICAgICAgIGN0eC5maWxsU3R5bGUgPSBmaWxsU3R5bGU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGZpbGxTdHlsZVByb3AuaGFzVmFsdWUoKSkge1xuICAgICAgICAgIGlmIChmaWxsU3R5bGVQcm9wLmdldFN0cmluZygpID09PSAnY3VycmVudENvbG9yJykge1xuICAgICAgICAgICAgZmlsbFN0eWxlUHJvcC5zZXRWYWx1ZSh0aGlzLmdldFN0eWxlKCdjb2xvcicpLmdldENvbG9yKCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfZmlsbFN0eWxlID0gZmlsbFN0eWxlUHJvcC5nZXRDb2xvcigpO1xuXG4gICAgICAgICAgaWYgKF9maWxsU3R5bGUgIT09ICdpbmhlcml0Jykge1xuICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IF9maWxsU3R5bGUgPT09ICdub25lJyA/ICdyZ2JhKDAsMCwwLDApJyA6IF9maWxsU3R5bGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZpbGxPcGFjaXR5U3R5bGVQcm9wLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICB2YXIgX2ZpbGxTdHlsZTIgPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgJ2ZpbGwnLCBjdHguZmlsbFN0eWxlKS5hZGRPcGFjaXR5KGZpbGxPcGFjaXR5U3R5bGVQcm9wKS5nZXRDb2xvcigpO1xuXG4gICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IF9maWxsU3R5bGUyO1xuICAgICAgICB9IC8vIHN0cm9rZVxuXG5cbiAgICAgICAgaWYgKHN0cm9rZVN0eWxlUHJvcC5pc1VybERlZmluaXRpb24oKSkge1xuICAgICAgICAgIHZhciBzdHJva2VTdHlsZSA9IHN0cm9rZVN0eWxlUHJvcC5nZXRGaWxsU3R5bGVEZWZpbml0aW9uKHRoaXMsIHN0cm9rZU9wYWNpdHlQcm9wKTtcblxuICAgICAgICAgIGlmIChzdHJva2VTdHlsZSkge1xuICAgICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gc3Ryb2tlU3R5bGU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHN0cm9rZVN0eWxlUHJvcC5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgaWYgKHN0cm9rZVN0eWxlUHJvcC5nZXRTdHJpbmcoKSA9PT0gJ2N1cnJlbnRDb2xvcicpIHtcbiAgICAgICAgICAgIHN0cm9rZVN0eWxlUHJvcC5zZXRWYWx1ZSh0aGlzLmdldFN0eWxlKCdjb2xvcicpLmdldENvbG9yKCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfc3Ryb2tlU3R5bGUgPSBzdHJva2VTdHlsZVByb3AuZ2V0U3RyaW5nKCk7XG5cbiAgICAgICAgICBpZiAoX3N0cm9rZVN0eWxlICE9PSAnaW5oZXJpdCcpIHtcbiAgICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IF9zdHJva2VTdHlsZSA9PT0gJ25vbmUnID8gJ3JnYmEoMCwwLDAsMCknIDogX3N0cm9rZVN0eWxlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdHJva2VPcGFjaXR5UHJvcC5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgdmFyIF9zdHJva2VTdHlsZTIgPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgJ3N0cm9rZScsIGN0eC5zdHJva2VTdHlsZSkuYWRkT3BhY2l0eShzdHJva2VPcGFjaXR5UHJvcCkuZ2V0U3RyaW5nKCk7XG5cbiAgICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBfc3Ryb2tlU3R5bGUyO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0cm9rZVdpZHRoU3R5bGVQcm9wID0gdGhpcy5nZXRTdHlsZSgnc3Ryb2tlLXdpZHRoJyk7XG5cbiAgICAgICAgaWYgKHN0cm9rZVdpZHRoU3R5bGVQcm9wLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICB2YXIgbmV3TGluZVdpZHRoID0gc3Ryb2tlV2lkdGhTdHlsZVByb3AuZ2V0UGl4ZWxzKCk7XG4gICAgICAgICAgY3R4LmxpbmVXaWR0aCA9ICFuZXdMaW5lV2lkdGggPyBQU0VVRE9fWkVSTyAvLyBicm93c2VycyBkb24ndCByZXNwZWN0IDAgKG9yIG5vZGUtY2FudmFzPyA6LSlcbiAgICAgICAgICA6IG5ld0xpbmVXaWR0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzdHJva2VMaW5lY2FwU3R5bGVQcm9wID0gdGhpcy5nZXRTdHlsZSgnc3Ryb2tlLWxpbmVjYXAnKTtcbiAgICAgICAgdmFyIHN0cm9rZUxpbmVqb2luU3R5bGVQcm9wID0gdGhpcy5nZXRTdHlsZSgnc3Ryb2tlLWxpbmVqb2luJyk7XG4gICAgICAgIHZhciBzdHJva2VNaXRlcmxpbWl0UHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ3N0cm9rZS1taXRlcmxpbWl0Jyk7IC8vIE5FRUQgVEVTVFxuICAgICAgICAvLyBjb25zdCBwb2ludE9yZGVyU3R5bGVQcm9wID0gdGhpcy5nZXRTdHlsZSgncGFpbnQtb3JkZXInKTtcblxuICAgICAgICB2YXIgc3Ryb2tlRGFzaGFycmF5U3R5bGVQcm9wID0gdGhpcy5nZXRTdHlsZSgnc3Ryb2tlLWRhc2hhcnJheScpO1xuICAgICAgICB2YXIgc3Ryb2tlRGFzaG9mZnNldFByb3AgPSB0aGlzLmdldFN0eWxlKCdzdHJva2UtZGFzaG9mZnNldCcpO1xuXG4gICAgICAgIGlmIChzdHJva2VMaW5lY2FwU3R5bGVQcm9wLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICBjdHgubGluZUNhcCA9IHN0cm9rZUxpbmVjYXBTdHlsZVByb3AuZ2V0U3RyaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3Ryb2tlTGluZWpvaW5TdHlsZVByb3AuaGFzVmFsdWUoKSkge1xuICAgICAgICAgIGN0eC5saW5lSm9pbiA9IHN0cm9rZUxpbmVqb2luU3R5bGVQcm9wLmdldFN0cmluZygpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0cm9rZU1pdGVybGltaXRQcm9wLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICBjdHgubWl0ZXJMaW1pdCA9IHN0cm9rZU1pdGVybGltaXRQcm9wLmdldE51bWJlcigpO1xuICAgICAgICB9IC8vIE5FRUQgVEVTVFxuICAgICAgICAvLyBpZiAocG9pbnRPcmRlclN0eWxlUHJvcC5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIC8vIFx0Ly8gP1xuICAgICAgICAvLyBcdGN0eC5wYWludE9yZGVyID0gcG9pbnRPcmRlclN0eWxlUHJvcC5nZXRWYWx1ZSgpO1xuICAgICAgICAvLyB9XG5cblxuICAgICAgICBpZiAoc3Ryb2tlRGFzaGFycmF5U3R5bGVQcm9wLmhhc1ZhbHVlKCkgJiYgc3Ryb2tlRGFzaGFycmF5U3R5bGVQcm9wLmdldFN0cmluZygpICE9PSAnbm9uZScpIHtcbiAgICAgICAgICB2YXIgZ2FwcyA9IHRvTnVtYmVycyhzdHJva2VEYXNoYXJyYXlTdHlsZVByb3AuZ2V0U3RyaW5nKCkpO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBjdHguc2V0TGluZURhc2ggIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBjdHguc2V0TGluZURhc2goZ2Fwcyk7XG4gICAgICAgICAgfSBlbHNlIC8vIEB0cy1leHBlY3QtZXJyb3IgSGFuZGxlIGJyb3dzZXIgcHJlZml4LlxuICAgICAgICAgICAgaWYgKHR5cGVvZiBjdHgud2Via2l0TGluZURhc2ggIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgSGFuZGxlIGJyb3dzZXIgcHJlZml4LlxuICAgICAgICAgICAgICBjdHgud2Via2l0TGluZURhc2ggPSBnYXBzO1xuICAgICAgICAgICAgfSBlbHNlIC8vIEB0cy1leHBlY3QtZXJyb3IgSGFuZGxlIGJyb3dzZXIgcHJlZml4LlxuICAgICAgICAgICAgICBpZiAodHlwZW9mIGN0eC5tb3pEYXNoICE9PSAndW5kZWZpbmVkJyAmJiAhKGdhcHMubGVuZ3RoID09PSAxICYmIGdhcHNbMF0gPT09IDApKSB7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBIYW5kbGUgYnJvd3NlciBwcmVmaXguXG4gICAgICAgICAgICAgICAgY3R4Lm1vekRhc2ggPSBnYXBzO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgb2Zmc2V0ID0gc3Ryb2tlRGFzaG9mZnNldFByb3AuZ2V0UGl4ZWxzKCk7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGN0eC5saW5lRGFzaE9mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IG9mZnNldDtcbiAgICAgICAgICB9IGVsc2UgLy8gQHRzLWV4cGVjdC1lcnJvciBIYW5kbGUgYnJvd3NlciBwcmVmaXguXG4gICAgICAgICAgICBpZiAodHlwZW9mIGN0eC53ZWJraXRMaW5lRGFzaE9mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBIYW5kbGUgYnJvd3NlciBwcmVmaXguXG4gICAgICAgICAgICAgIGN0eC53ZWJraXRMaW5lRGFzaE9mZnNldCA9IG9mZnNldDtcbiAgICAgICAgICAgIH0gZWxzZSAvLyBAdHMtZXhwZWN0LWVycm9yIEhhbmRsZSBicm93c2VyIHByZWZpeC5cbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjdHgubW96RGFzaE9mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIEhhbmRsZSBicm93c2VyIHByZWZpeC5cbiAgICAgICAgICAgICAgICBjdHgubW96RGFzaE9mZnNldCA9IG9mZnNldDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IC8vIGZvbnRcblxuXG4gICAgICB0aGlzLm1vZGlmaWVkRW1TaXplU3RhY2sgPSBmYWxzZTtcblxuICAgICAgaWYgKHR5cGVvZiBjdHguZm9udCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdmFyIGZvbnRTdHlsZVByb3AgPSB0aGlzLmdldFN0eWxlKCdmb250Jyk7XG4gICAgICAgIHZhciBmb250U3R5bGVTdHlsZVByb3AgPSB0aGlzLmdldFN0eWxlKCdmb250LXN0eWxlJyk7XG4gICAgICAgIHZhciBmb250VmFyaWFudFN0eWxlUHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ2ZvbnQtdmFyaWFudCcpO1xuICAgICAgICB2YXIgZm9udFdlaWdodFN0eWxlUHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ2ZvbnQtd2VpZ2h0Jyk7XG4gICAgICAgIHZhciBmb250U2l6ZVN0eWxlUHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ2ZvbnQtc2l6ZScpO1xuICAgICAgICB2YXIgZm9udEZhbWlseVN0eWxlUHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ2ZvbnQtZmFtaWx5Jyk7XG4gICAgICAgIHZhciBmb250ID0gbmV3IEZvbnQoZm9udFN0eWxlU3R5bGVQcm9wLmdldFN0cmluZygpLCBmb250VmFyaWFudFN0eWxlUHJvcC5nZXRTdHJpbmcoKSwgZm9udFdlaWdodFN0eWxlUHJvcC5nZXRTdHJpbmcoKSwgZm9udFNpemVTdHlsZVByb3AuaGFzVmFsdWUoKSA/IFwiXCIuY29uY2F0KGZvbnRTaXplU3R5bGVQcm9wLmdldFBpeGVscyh0cnVlKSwgXCJweFwiKSA6ICcnLCBmb250RmFtaWx5U3R5bGVQcm9wLmdldFN0cmluZygpLCBGb250LnBhcnNlKGZvbnRTdHlsZVByb3AuZ2V0U3RyaW5nKCksIGN0eC5mb250KSk7XG4gICAgICAgIGZvbnRTdHlsZVN0eWxlUHJvcC5zZXRWYWx1ZShmb250LmZvbnRTdHlsZSk7XG4gICAgICAgIGZvbnRWYXJpYW50U3R5bGVQcm9wLnNldFZhbHVlKGZvbnQuZm9udFZhcmlhbnQpO1xuICAgICAgICBmb250V2VpZ2h0U3R5bGVQcm9wLnNldFZhbHVlKGZvbnQuZm9udFdlaWdodCk7XG4gICAgICAgIGZvbnRTaXplU3R5bGVQcm9wLnNldFZhbHVlKGZvbnQuZm9udFNpemUpO1xuICAgICAgICBmb250RmFtaWx5U3R5bGVQcm9wLnNldFZhbHVlKGZvbnQuZm9udEZhbWlseSk7XG4gICAgICAgIGN0eC5mb250ID0gZm9udC50b1N0cmluZygpO1xuXG4gICAgICAgIGlmIChmb250U2l6ZVN0eWxlUHJvcC5pc1BpeGVscygpKSB7XG4gICAgICAgICAgdGhpcy5kb2N1bWVudC5lbVNpemUgPSBmb250U2l6ZVN0eWxlUHJvcC5nZXRQaXhlbHMoKTtcbiAgICAgICAgICB0aGlzLm1vZGlmaWVkRW1TaXplU3RhY2sgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghZnJvbU1lYXN1cmUpIHtcbiAgICAgICAgLy8gZWZmZWN0c1xuICAgICAgICB0aGlzLmFwcGx5RWZmZWN0cyhjdHgpOyAvLyBvcGFjaXR5XG5cbiAgICAgICAgY3R4Lmdsb2JhbEFscGhhID0gdGhpcy5jYWxjdWxhdGVPcGFjaXR5KCk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNsZWFyQ29udGV4dFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjbGVhckNvbnRleHQoY3R4KSB7XG4gICAgICBfZ2V0X19kZWZhdWx0W1wiZGVmYXVsdFwiXShfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFJlbmRlcmVkRWxlbWVudC5wcm90b3R5cGUpLCBcImNsZWFyQ29udGV4dFwiLCB0aGlzKS5jYWxsKHRoaXMsIGN0eCk7XG5cbiAgICAgIGlmICh0aGlzLm1vZGlmaWVkRW1TaXplU3RhY2spIHtcbiAgICAgICAgdGhpcy5kb2N1bWVudC5wb3BFbVNpemUoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gUmVuZGVyZWRFbGVtZW50O1xufShFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJEcoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkRygpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkRygpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBQYXRoRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1JlbmRlcmVkRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFBhdGhFbGVtZW50LCBfUmVuZGVyZWRFbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJEcoUGF0aEVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIFBhdGhFbGVtZW50KGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBQYXRoRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcbiAgICBfdGhpcy50eXBlID0gJ3BhdGgnO1xuICAgIF90aGlzLnBhdGhQYXJzZXIgPSBudWxsO1xuICAgIF90aGlzLnBhdGhQYXJzZXIgPSBuZXcgUGF0aFBhcnNlcihfdGhpcy5nZXRBdHRyaWJ1dGUoJ2QnKS5nZXRTdHJpbmcoKSk7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShQYXRoRWxlbWVudCwgW3tcbiAgICBrZXk6IFwicGF0aFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoKGN0eCkge1xuICAgICAgdmFyIHBhdGhQYXJzZXIgPSB0aGlzLnBhdGhQYXJzZXI7XG4gICAgICB2YXIgYm91bmRpbmdCb3ggPSBuZXcgQm91bmRpbmdCb3goKTtcbiAgICAgIHBhdGhQYXJzZXIucmVzZXQoKTtcblxuICAgICAgaWYgKGN0eCkge1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICB9XG5cbiAgICAgIHdoaWxlICghcGF0aFBhcnNlci5pc0VuZCgpKSB7XG4gICAgICAgIHN3aXRjaCAocGF0aFBhcnNlci5uZXh0KCkudHlwZSkge1xuICAgICAgICAgIGNhc2UgUGF0aFBhcnNlci5NT1ZFX1RPOlxuICAgICAgICAgICAgdGhpcy5wYXRoTShjdHgsIGJvdW5kaW5nQm94KTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBQYXRoUGFyc2VyLkxJTkVfVE86XG4gICAgICAgICAgICB0aGlzLnBhdGhMKGN0eCwgYm91bmRpbmdCb3gpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuSE9SSVpfTElORV9UTzpcbiAgICAgICAgICAgIHRoaXMucGF0aEgoY3R4LCBib3VuZGluZ0JveCk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgUGF0aFBhcnNlci5WRVJUX0xJTkVfVE86XG4gICAgICAgICAgICB0aGlzLnBhdGhWKGN0eCwgYm91bmRpbmdCb3gpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuQ1VSVkVfVE86XG4gICAgICAgICAgICB0aGlzLnBhdGhDKGN0eCwgYm91bmRpbmdCb3gpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuU01PT1RIX0NVUlZFX1RPOlxuICAgICAgICAgICAgdGhpcy5wYXRoUyhjdHgsIGJvdW5kaW5nQm94KTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBQYXRoUGFyc2VyLlFVQURfVE86XG4gICAgICAgICAgICB0aGlzLnBhdGhRKGN0eCwgYm91bmRpbmdCb3gpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuU01PT1RIX1FVQURfVE86XG4gICAgICAgICAgICB0aGlzLnBhdGhUKGN0eCwgYm91bmRpbmdCb3gpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuQVJDOlxuICAgICAgICAgICAgdGhpcy5wYXRoQShjdHgsIGJvdW5kaW5nQm94KTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBQYXRoUGFyc2VyLkNMT1NFX1BBVEg6XG4gICAgICAgICAgICB0aGlzLnBhdGhaKGN0eCwgYm91bmRpbmdCb3gpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGJvdW5kaW5nQm94O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRCb3VuZGluZ0JveFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRCb3VuZGluZ0JveChfKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXRoKCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldE1hcmtlcnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0TWFya2VycygpIHtcbiAgICAgIHZhciBwYXRoUGFyc2VyID0gdGhpcy5wYXRoUGFyc2VyO1xuICAgICAgdmFyIHBvaW50cyA9IHBhdGhQYXJzZXIuZ2V0TWFya2VyUG9pbnRzKCk7XG4gICAgICB2YXIgYW5nbGVzID0gcGF0aFBhcnNlci5nZXRNYXJrZXJBbmdsZXMoKTtcbiAgICAgIHZhciBtYXJrZXJzID0gcG9pbnRzLm1hcChmdW5jdGlvbiAocG9pbnQsIGkpIHtcbiAgICAgICAgcmV0dXJuIFtwb2ludCwgYW5nbGVzW2ldXTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIG1hcmtlcnM7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlckNoaWxkcmVuXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlckNoaWxkcmVuKGN0eCkge1xuICAgICAgdGhpcy5wYXRoKGN0eCk7XG4gICAgICB0aGlzLmRvY3VtZW50LnNjcmVlbi5tb3VzZS5jaGVja1BhdGgodGhpcywgY3R4KTtcbiAgICAgIHZhciBmaWxsUnVsZVN0eWxlUHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ2ZpbGwtcnVsZScpO1xuXG4gICAgICBpZiAoY3R4LmZpbGxTdHlsZSAhPT0gJycpIHtcbiAgICAgICAgaWYgKGZpbGxSdWxlU3R5bGVQcm9wLmdldFN0cmluZygnaW5oZXJpdCcpICE9PSAnaW5oZXJpdCcpIHtcbiAgICAgICAgICBjdHguZmlsbChmaWxsUnVsZVN0eWxlUHJvcC5nZXRTdHJpbmcoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3R4LmZpbGwoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY3R4LnN0cm9rZVN0eWxlICE9PSAnJykge1xuICAgICAgICBpZiAodGhpcy5nZXRBdHRyaWJ1dGUoJ3ZlY3Rvci1lZmZlY3QnKS5nZXRTdHJpbmcoKSA9PT0gJ25vbi1zY2FsaW5nLXN0cm9rZScpIHtcbiAgICAgICAgICBjdHguc2F2ZSgpO1xuICAgICAgICAgIGN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7XG4gICAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBtYXJrZXJzID0gdGhpcy5nZXRNYXJrZXJzKCk7XG5cbiAgICAgIGlmIChtYXJrZXJzKSB7XG4gICAgICAgIHZhciBtYXJrZXJzTGFzdEluZGV4ID0gbWFya2Vycy5sZW5ndGggLSAxO1xuICAgICAgICB2YXIgbWFya2VyU3RhcnRTdHlsZVByb3AgPSB0aGlzLmdldFN0eWxlKCdtYXJrZXItc3RhcnQnKTtcbiAgICAgICAgdmFyIG1hcmtlck1pZFN0eWxlUHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ21hcmtlci1taWQnKTtcbiAgICAgICAgdmFyIG1hcmtlckVuZFN0eWxlUHJvcCA9IHRoaXMuZ2V0U3R5bGUoJ21hcmtlci1lbmQnKTtcblxuICAgICAgICBpZiAobWFya2VyU3RhcnRTdHlsZVByb3AuaXNVcmxEZWZpbml0aW9uKCkpIHtcbiAgICAgICAgICB2YXIgbWFya2VyID0gbWFya2VyU3RhcnRTdHlsZVByb3AuZ2V0RGVmaW5pdGlvbigpO1xuXG4gICAgICAgICAgdmFyIF9tYXJrZXJzJCA9IF9zbGljZWRUb0FycmF5X19kZWZhdWx0W1wiZGVmYXVsdFwiXShtYXJrZXJzWzBdLCAyKSxcbiAgICAgICAgICAgICAgcG9pbnQgPSBfbWFya2VycyRbMF0sXG4gICAgICAgICAgICAgIGFuZ2xlID0gX21hcmtlcnMkWzFdO1xuXG4gICAgICAgICAgbWFya2VyLnJlbmRlcihjdHgsIHBvaW50LCBhbmdsZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWFya2VyTWlkU3R5bGVQcm9wLmlzVXJsRGVmaW5pdGlvbigpKSB7XG4gICAgICAgICAgdmFyIF9tYXJrZXIgPSBtYXJrZXJNaWRTdHlsZVByb3AuZ2V0RGVmaW5pdGlvbigpO1xuXG4gICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBtYXJrZXJzTGFzdEluZGV4OyBpKyspIHtcbiAgICAgICAgICAgIHZhciBfbWFya2VycyRpID0gX3NsaWNlZFRvQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKG1hcmtlcnNbaV0sIDIpLFxuICAgICAgICAgICAgICAgIF9wb2ludCA9IF9tYXJrZXJzJGlbMF0sXG4gICAgICAgICAgICAgICAgX2FuZ2xlID0gX21hcmtlcnMkaVsxXTtcblxuICAgICAgICAgICAgX21hcmtlci5yZW5kZXIoY3R4LCBfcG9pbnQsIF9hbmdsZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hcmtlckVuZFN0eWxlUHJvcC5pc1VybERlZmluaXRpb24oKSkge1xuICAgICAgICAgIHZhciBfbWFya2VyMiA9IG1hcmtlckVuZFN0eWxlUHJvcC5nZXREZWZpbml0aW9uKCk7XG5cbiAgICAgICAgICB2YXIgX21hcmtlcnMkbWFya2Vyc0xhc3RJID0gX3NsaWNlZFRvQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKG1hcmtlcnNbbWFya2Vyc0xhc3RJbmRleF0sIDIpLFxuICAgICAgICAgICAgICBfcG9pbnQyID0gX21hcmtlcnMkbWFya2Vyc0xhc3RJWzBdLFxuICAgICAgICAgICAgICBfYW5nbGUyID0gX21hcmtlcnMkbWFya2Vyc0xhc3RJWzFdO1xuXG4gICAgICAgICAgX21hcmtlcjIucmVuZGVyKGN0eCwgX3BvaW50MiwgX2FuZ2xlMik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aE1cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aE0oY3R4LCBib3VuZGluZ0JveCkge1xuICAgICAgdmFyIHBhdGhQYXJzZXIgPSB0aGlzLnBhdGhQYXJzZXI7XG5cbiAgICAgIHZhciBfUGF0aEVsZW1lbnQkcGF0aE0gPSBQYXRoRWxlbWVudC5wYXRoTShwYXRoUGFyc2VyKSxcbiAgICAgICAgICBwb2ludCA9IF9QYXRoRWxlbWVudCRwYXRoTS5wb2ludDtcblxuICAgICAgdmFyIHggPSBwb2ludC54LFxuICAgICAgICAgIHkgPSBwb2ludC55O1xuICAgICAgcGF0aFBhcnNlci5hZGRNYXJrZXIocG9pbnQpO1xuICAgICAgYm91bmRpbmdCb3guYWRkUG9pbnQoeCwgeSk7XG5cbiAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgY3R4Lm1vdmVUbyh4LCB5KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aExcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aEwoY3R4LCBib3VuZGluZ0JveCkge1xuICAgICAgdmFyIHBhdGhQYXJzZXIgPSB0aGlzLnBhdGhQYXJzZXI7XG5cbiAgICAgIHZhciBfUGF0aEVsZW1lbnQkcGF0aEwgPSBQYXRoRWxlbWVudC5wYXRoTChwYXRoUGFyc2VyKSxcbiAgICAgICAgICBjdXJyZW50ID0gX1BhdGhFbGVtZW50JHBhdGhMLmN1cnJlbnQsXG4gICAgICAgICAgcG9pbnQgPSBfUGF0aEVsZW1lbnQkcGF0aEwucG9pbnQ7XG5cbiAgICAgIHZhciB4ID0gcG9pbnQueCxcbiAgICAgICAgICB5ID0gcG9pbnQueTtcbiAgICAgIHBhdGhQYXJzZXIuYWRkTWFya2VyKHBvaW50LCBjdXJyZW50KTtcbiAgICAgIGJvdW5kaW5nQm94LmFkZFBvaW50KHgsIHkpO1xuXG4gICAgICBpZiAoY3R4KSB7XG4gICAgICAgIGN0eC5saW5lVG8oeCwgeSk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhIXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhIKGN0eCwgYm91bmRpbmdCb3gpIHtcbiAgICAgIHZhciBwYXRoUGFyc2VyID0gdGhpcy5wYXRoUGFyc2VyO1xuXG4gICAgICB2YXIgX1BhdGhFbGVtZW50JHBhdGhIID0gUGF0aEVsZW1lbnQucGF0aEgocGF0aFBhcnNlciksXG4gICAgICAgICAgY3VycmVudCA9IF9QYXRoRWxlbWVudCRwYXRoSC5jdXJyZW50LFxuICAgICAgICAgIHBvaW50ID0gX1BhdGhFbGVtZW50JHBhdGhILnBvaW50O1xuXG4gICAgICB2YXIgeCA9IHBvaW50LngsXG4gICAgICAgICAgeSA9IHBvaW50Lnk7XG4gICAgICBwYXRoUGFyc2VyLmFkZE1hcmtlcihwb2ludCwgY3VycmVudCk7XG4gICAgICBib3VuZGluZ0JveC5hZGRQb2ludCh4LCB5KTtcblxuICAgICAgaWYgKGN0eCkge1xuICAgICAgICBjdHgubGluZVRvKHgsIHkpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXRoVlwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoVihjdHgsIGJvdW5kaW5nQm94KSB7XG4gICAgICB2YXIgcGF0aFBhcnNlciA9IHRoaXMucGF0aFBhcnNlcjtcblxuICAgICAgdmFyIF9QYXRoRWxlbWVudCRwYXRoViA9IFBhdGhFbGVtZW50LnBhdGhWKHBhdGhQYXJzZXIpLFxuICAgICAgICAgIGN1cnJlbnQgPSBfUGF0aEVsZW1lbnQkcGF0aFYuY3VycmVudCxcbiAgICAgICAgICBwb2ludCA9IF9QYXRoRWxlbWVudCRwYXRoVi5wb2ludDtcblxuICAgICAgdmFyIHggPSBwb2ludC54LFxuICAgICAgICAgIHkgPSBwb2ludC55O1xuICAgICAgcGF0aFBhcnNlci5hZGRNYXJrZXIocG9pbnQsIGN1cnJlbnQpO1xuICAgICAgYm91bmRpbmdCb3guYWRkUG9pbnQoeCwgeSk7XG5cbiAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgY3R4LmxpbmVUbyh4LCB5KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aENcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aEMoY3R4LCBib3VuZGluZ0JveCkge1xuICAgICAgdmFyIHBhdGhQYXJzZXIgPSB0aGlzLnBhdGhQYXJzZXI7XG5cbiAgICAgIHZhciBfUGF0aEVsZW1lbnQkcGF0aEMgPSBQYXRoRWxlbWVudC5wYXRoQyhwYXRoUGFyc2VyKSxcbiAgICAgICAgICBjdXJyZW50ID0gX1BhdGhFbGVtZW50JHBhdGhDLmN1cnJlbnQsXG4gICAgICAgICAgcG9pbnQgPSBfUGF0aEVsZW1lbnQkcGF0aEMucG9pbnQsXG4gICAgICAgICAgY29udHJvbFBvaW50ID0gX1BhdGhFbGVtZW50JHBhdGhDLmNvbnRyb2xQb2ludCxcbiAgICAgICAgICBjdXJyZW50UG9pbnQgPSBfUGF0aEVsZW1lbnQkcGF0aEMuY3VycmVudFBvaW50O1xuXG4gICAgICBwYXRoUGFyc2VyLmFkZE1hcmtlcihjdXJyZW50UG9pbnQsIGNvbnRyb2xQb2ludCwgcG9pbnQpO1xuICAgICAgYm91bmRpbmdCb3guYWRkQmV6aWVyQ3VydmUoY3VycmVudC54LCBjdXJyZW50LnksIHBvaW50LngsIHBvaW50LnksIGNvbnRyb2xQb2ludC54LCBjb250cm9sUG9pbnQueSwgY3VycmVudFBvaW50LngsIGN1cnJlbnRQb2ludC55KTtcblxuICAgICAgaWYgKGN0eCkge1xuICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyhwb2ludC54LCBwb2ludC55LCBjb250cm9sUG9pbnQueCwgY29udHJvbFBvaW50LnksIGN1cnJlbnRQb2ludC54LCBjdXJyZW50UG9pbnQueSk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhTXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhTKGN0eCwgYm91bmRpbmdCb3gpIHtcbiAgICAgIHZhciBwYXRoUGFyc2VyID0gdGhpcy5wYXRoUGFyc2VyO1xuXG4gICAgICB2YXIgX1BhdGhFbGVtZW50JHBhdGhTID0gUGF0aEVsZW1lbnQucGF0aFMocGF0aFBhcnNlciksXG4gICAgICAgICAgY3VycmVudCA9IF9QYXRoRWxlbWVudCRwYXRoUy5jdXJyZW50LFxuICAgICAgICAgIHBvaW50ID0gX1BhdGhFbGVtZW50JHBhdGhTLnBvaW50LFxuICAgICAgICAgIGNvbnRyb2xQb2ludCA9IF9QYXRoRWxlbWVudCRwYXRoUy5jb250cm9sUG9pbnQsXG4gICAgICAgICAgY3VycmVudFBvaW50ID0gX1BhdGhFbGVtZW50JHBhdGhTLmN1cnJlbnRQb2ludDtcblxuICAgICAgcGF0aFBhcnNlci5hZGRNYXJrZXIoY3VycmVudFBvaW50LCBjb250cm9sUG9pbnQsIHBvaW50KTtcbiAgICAgIGJvdW5kaW5nQm94LmFkZEJlemllckN1cnZlKGN1cnJlbnQueCwgY3VycmVudC55LCBwb2ludC54LCBwb2ludC55LCBjb250cm9sUG9pbnQueCwgY29udHJvbFBvaW50LnksIGN1cnJlbnRQb2ludC54LCBjdXJyZW50UG9pbnQueSk7XG5cbiAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgY3R4LmJlemllckN1cnZlVG8ocG9pbnQueCwgcG9pbnQueSwgY29udHJvbFBvaW50LngsIGNvbnRyb2xQb2ludC55LCBjdXJyZW50UG9pbnQueCwgY3VycmVudFBvaW50LnkpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXRoUVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoUShjdHgsIGJvdW5kaW5nQm94KSB7XG4gICAgICB2YXIgcGF0aFBhcnNlciA9IHRoaXMucGF0aFBhcnNlcjtcblxuICAgICAgdmFyIF9QYXRoRWxlbWVudCRwYXRoUSA9IFBhdGhFbGVtZW50LnBhdGhRKHBhdGhQYXJzZXIpLFxuICAgICAgICAgIGN1cnJlbnQgPSBfUGF0aEVsZW1lbnQkcGF0aFEuY3VycmVudCxcbiAgICAgICAgICBjb250cm9sUG9pbnQgPSBfUGF0aEVsZW1lbnQkcGF0aFEuY29udHJvbFBvaW50LFxuICAgICAgICAgIGN1cnJlbnRQb2ludCA9IF9QYXRoRWxlbWVudCRwYXRoUS5jdXJyZW50UG9pbnQ7XG5cbiAgICAgIHBhdGhQYXJzZXIuYWRkTWFya2VyKGN1cnJlbnRQb2ludCwgY29udHJvbFBvaW50LCBjb250cm9sUG9pbnQpO1xuICAgICAgYm91bmRpbmdCb3guYWRkUXVhZHJhdGljQ3VydmUoY3VycmVudC54LCBjdXJyZW50LnksIGNvbnRyb2xQb2ludC54LCBjb250cm9sUG9pbnQueSwgY3VycmVudFBvaW50LngsIGN1cnJlbnRQb2ludC55KTtcblxuICAgICAgaWYgKGN0eCkge1xuICAgICAgICBjdHgucXVhZHJhdGljQ3VydmVUbyhjb250cm9sUG9pbnQueCwgY29udHJvbFBvaW50LnksIGN1cnJlbnRQb2ludC54LCBjdXJyZW50UG9pbnQueSk7XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhUXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhUKGN0eCwgYm91bmRpbmdCb3gpIHtcbiAgICAgIHZhciBwYXRoUGFyc2VyID0gdGhpcy5wYXRoUGFyc2VyO1xuXG4gICAgICB2YXIgX1BhdGhFbGVtZW50JHBhdGhUID0gUGF0aEVsZW1lbnQucGF0aFQocGF0aFBhcnNlciksXG4gICAgICAgICAgY3VycmVudCA9IF9QYXRoRWxlbWVudCRwYXRoVC5jdXJyZW50LFxuICAgICAgICAgIGNvbnRyb2xQb2ludCA9IF9QYXRoRWxlbWVudCRwYXRoVC5jb250cm9sUG9pbnQsXG4gICAgICAgICAgY3VycmVudFBvaW50ID0gX1BhdGhFbGVtZW50JHBhdGhULmN1cnJlbnRQb2ludDtcblxuICAgICAgcGF0aFBhcnNlci5hZGRNYXJrZXIoY3VycmVudFBvaW50LCBjb250cm9sUG9pbnQsIGNvbnRyb2xQb2ludCk7XG4gICAgICBib3VuZGluZ0JveC5hZGRRdWFkcmF0aWNDdXJ2ZShjdXJyZW50LngsIGN1cnJlbnQueSwgY29udHJvbFBvaW50LngsIGNvbnRyb2xQb2ludC55LCBjdXJyZW50UG9pbnQueCwgY3VycmVudFBvaW50LnkpO1xuXG4gICAgICBpZiAoY3R4KSB7XG4gICAgICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKGNvbnRyb2xQb2ludC54LCBjb250cm9sUG9pbnQueSwgY3VycmVudFBvaW50LngsIGN1cnJlbnRQb2ludC55KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aEFcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aEEoY3R4LCBib3VuZGluZ0JveCkge1xuICAgICAgdmFyIHBhdGhQYXJzZXIgPSB0aGlzLnBhdGhQYXJzZXI7XG5cbiAgICAgIHZhciBfUGF0aEVsZW1lbnQkcGF0aEEgPSBQYXRoRWxlbWVudC5wYXRoQShwYXRoUGFyc2VyKSxcbiAgICAgICAgICBjdXJyZW50UG9pbnQgPSBfUGF0aEVsZW1lbnQkcGF0aEEuY3VycmVudFBvaW50LFxuICAgICAgICAgIHJYID0gX1BhdGhFbGVtZW50JHBhdGhBLnJYLFxuICAgICAgICAgIHJZID0gX1BhdGhFbGVtZW50JHBhdGhBLnJZLFxuICAgICAgICAgIHN3ZWVwRmxhZyA9IF9QYXRoRWxlbWVudCRwYXRoQS5zd2VlcEZsYWcsXG4gICAgICAgICAgeEF4aXNSb3RhdGlvbiA9IF9QYXRoRWxlbWVudCRwYXRoQS54QXhpc1JvdGF0aW9uLFxuICAgICAgICAgIGNlbnRwID0gX1BhdGhFbGVtZW50JHBhdGhBLmNlbnRwLFxuICAgICAgICAgIGExID0gX1BhdGhFbGVtZW50JHBhdGhBLmExLFxuICAgICAgICAgIGFkID0gX1BhdGhFbGVtZW50JHBhdGhBLmFkOyAvLyBmb3IgbWFya2Vyc1xuXG5cbiAgICAgIHZhciBkaXIgPSAxIC0gc3dlZXBGbGFnID8gMS4wIDogLTEuMDtcbiAgICAgIHZhciBhaCA9IGExICsgZGlyICogKGFkIC8gMi4wKTtcbiAgICAgIHZhciBoYWxmV2F5ID0gbmV3IFBvaW50KGNlbnRwLnggKyByWCAqIE1hdGguY29zKGFoKSwgY2VudHAueSArIHJZICogTWF0aC5zaW4oYWgpKTtcbiAgICAgIHBhdGhQYXJzZXIuYWRkTWFya2VyQW5nbGUoaGFsZldheSwgYWggLSBkaXIgKiBNYXRoLlBJIC8gMik7XG4gICAgICBwYXRoUGFyc2VyLmFkZE1hcmtlckFuZ2xlKGN1cnJlbnRQb2ludCwgYWggLSBkaXIgKiBNYXRoLlBJKTtcbiAgICAgIGJvdW5kaW5nQm94LmFkZFBvaW50KGN1cnJlbnRQb2ludC54LCBjdXJyZW50UG9pbnQueSk7IC8vIFRPRE86IHRoaXMgaXMgdG9vIG5haXZlLCBtYWtlIGl0IGJldHRlclxuXG4gICAgICBpZiAoY3R4ICYmICFpc05hTihhMSkgJiYgIWlzTmFOKGFkKSkge1xuICAgICAgICB2YXIgciA9IHJYID4gclkgPyByWCA6IHJZO1xuICAgICAgICB2YXIgc3ggPSByWCA+IHJZID8gMSA6IHJYIC8gclk7XG4gICAgICAgIHZhciBzeSA9IHJYID4gclkgPyByWSAvIHJYIDogMTtcbiAgICAgICAgY3R4LnRyYW5zbGF0ZShjZW50cC54LCBjZW50cC55KTtcbiAgICAgICAgY3R4LnJvdGF0ZSh4QXhpc1JvdGF0aW9uKTtcbiAgICAgICAgY3R4LnNjYWxlKHN4LCBzeSk7XG4gICAgICAgIGN0eC5hcmMoMCwgMCwgciwgYTEsIGExICsgYWQsIEJvb2xlYW4oMSAtIHN3ZWVwRmxhZykpO1xuICAgICAgICBjdHguc2NhbGUoMSAvIHN4LCAxIC8gc3kpO1xuICAgICAgICBjdHgucm90YXRlKC14QXhpc1JvdGF0aW9uKTtcbiAgICAgICAgY3R4LnRyYW5zbGF0ZSgtY2VudHAueCwgLWNlbnRwLnkpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXRoWlwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoWihjdHgsIGJvdW5kaW5nQm94KSB7XG4gICAgICBQYXRoRWxlbWVudC5wYXRoWih0aGlzLnBhdGhQYXJzZXIpO1xuXG4gICAgICBpZiAoY3R4KSB7XG4gICAgICAgIC8vIG9ubHkgY2xvc2UgcGF0aCBpZiBpdCBpcyBub3QgYSBzdHJhaWdodCBsaW5lXG4gICAgICAgIGlmIChib3VuZGluZ0JveC54MSAhPT0gYm91bmRpbmdCb3gueDIgJiYgYm91bmRpbmdCb3gueTEgIT09IGJvdW5kaW5nQm94LnkyKSB7XG4gICAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XSwgW3tcbiAgICBrZXk6IFwicGF0aE1cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aE0ocGF0aFBhcnNlcikge1xuICAgICAgdmFyIHBvaW50ID0gcGF0aFBhcnNlci5nZXRBc0N1cnJlbnRQb2ludCgpO1xuICAgICAgcGF0aFBhcnNlci5zdGFydCA9IHBhdGhQYXJzZXIuY3VycmVudDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBvaW50OiBwb2ludFxuICAgICAgfTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aExcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aEwocGF0aFBhcnNlcikge1xuICAgICAgdmFyIGN1cnJlbnQgPSBwYXRoUGFyc2VyLmN1cnJlbnQ7XG4gICAgICB2YXIgcG9pbnQgPSBwYXRoUGFyc2VyLmdldEFzQ3VycmVudFBvaW50KCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjdXJyZW50OiBjdXJyZW50LFxuICAgICAgICBwb2ludDogcG9pbnRcbiAgICAgIH07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhIXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhIKHBhdGhQYXJzZXIpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gcGF0aFBhcnNlci5jdXJyZW50LFxuICAgICAgICAgIGNvbW1hbmQgPSBwYXRoUGFyc2VyLmNvbW1hbmQ7XG4gICAgICB2YXIgcG9pbnQgPSBuZXcgUG9pbnQoKGNvbW1hbmQucmVsYXRpdmUgPyBjdXJyZW50LnggOiAwKSArIGNvbW1hbmQueCwgY3VycmVudC55KTtcbiAgICAgIHBhdGhQYXJzZXIuY3VycmVudCA9IHBvaW50O1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY3VycmVudDogY3VycmVudCxcbiAgICAgICAgcG9pbnQ6IHBvaW50XG4gICAgICB9O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXRoVlwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoVihwYXRoUGFyc2VyKSB7XG4gICAgICB2YXIgY3VycmVudCA9IHBhdGhQYXJzZXIuY3VycmVudCxcbiAgICAgICAgICBjb21tYW5kID0gcGF0aFBhcnNlci5jb21tYW5kO1xuICAgICAgdmFyIHBvaW50ID0gbmV3IFBvaW50KGN1cnJlbnQueCwgKGNvbW1hbmQucmVsYXRpdmUgPyBjdXJyZW50LnkgOiAwKSArIGNvbW1hbmQueSk7XG4gICAgICBwYXRoUGFyc2VyLmN1cnJlbnQgPSBwb2ludDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGN1cnJlbnQ6IGN1cnJlbnQsXG4gICAgICAgIHBvaW50OiBwb2ludFxuICAgICAgfTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aENcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aEMocGF0aFBhcnNlcikge1xuICAgICAgdmFyIGN1cnJlbnQgPSBwYXRoUGFyc2VyLmN1cnJlbnQ7XG4gICAgICB2YXIgcG9pbnQgPSBwYXRoUGFyc2VyLmdldFBvaW50KCd4MScsICd5MScpO1xuICAgICAgdmFyIGNvbnRyb2xQb2ludCA9IHBhdGhQYXJzZXIuZ2V0QXNDb250cm9sUG9pbnQoJ3gyJywgJ3kyJyk7XG4gICAgICB2YXIgY3VycmVudFBvaW50ID0gcGF0aFBhcnNlci5nZXRBc0N1cnJlbnRQb2ludCgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY3VycmVudDogY3VycmVudCxcbiAgICAgICAgcG9pbnQ6IHBvaW50LFxuICAgICAgICBjb250cm9sUG9pbnQ6IGNvbnRyb2xQb2ludCxcbiAgICAgICAgY3VycmVudFBvaW50OiBjdXJyZW50UG9pbnRcbiAgICAgIH07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhTXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhTKHBhdGhQYXJzZXIpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gcGF0aFBhcnNlci5jdXJyZW50O1xuICAgICAgdmFyIHBvaW50ID0gcGF0aFBhcnNlci5nZXRSZWZsZWN0ZWRDb250cm9sUG9pbnQoKTtcbiAgICAgIHZhciBjb250cm9sUG9pbnQgPSBwYXRoUGFyc2VyLmdldEFzQ29udHJvbFBvaW50KCd4MicsICd5MicpO1xuICAgICAgdmFyIGN1cnJlbnRQb2ludCA9IHBhdGhQYXJzZXIuZ2V0QXNDdXJyZW50UG9pbnQoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGN1cnJlbnQ6IGN1cnJlbnQsXG4gICAgICAgIHBvaW50OiBwb2ludCxcbiAgICAgICAgY29udHJvbFBvaW50OiBjb250cm9sUG9pbnQsXG4gICAgICAgIGN1cnJlbnRQb2ludDogY3VycmVudFBvaW50XG4gICAgICB9O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXRoUVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoUShwYXRoUGFyc2VyKSB7XG4gICAgICB2YXIgY3VycmVudCA9IHBhdGhQYXJzZXIuY3VycmVudDtcbiAgICAgIHZhciBjb250cm9sUG9pbnQgPSBwYXRoUGFyc2VyLmdldEFzQ29udHJvbFBvaW50KCd4MScsICd5MScpO1xuICAgICAgdmFyIGN1cnJlbnRQb2ludCA9IHBhdGhQYXJzZXIuZ2V0QXNDdXJyZW50UG9pbnQoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGN1cnJlbnQ6IGN1cnJlbnQsXG4gICAgICAgIGNvbnRyb2xQb2ludDogY29udHJvbFBvaW50LFxuICAgICAgICBjdXJyZW50UG9pbnQ6IGN1cnJlbnRQb2ludFxuICAgICAgfTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aFRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aFQocGF0aFBhcnNlcikge1xuICAgICAgdmFyIGN1cnJlbnQgPSBwYXRoUGFyc2VyLmN1cnJlbnQ7XG4gICAgICB2YXIgY29udHJvbFBvaW50ID0gcGF0aFBhcnNlci5nZXRSZWZsZWN0ZWRDb250cm9sUG9pbnQoKTtcbiAgICAgIHBhdGhQYXJzZXIuY29udHJvbCA9IGNvbnRyb2xQb2ludDtcbiAgICAgIHZhciBjdXJyZW50UG9pbnQgPSBwYXRoUGFyc2VyLmdldEFzQ3VycmVudFBvaW50KCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjdXJyZW50OiBjdXJyZW50LFxuICAgICAgICBjb250cm9sUG9pbnQ6IGNvbnRyb2xQb2ludCxcbiAgICAgICAgY3VycmVudFBvaW50OiBjdXJyZW50UG9pbnRcbiAgICAgIH07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhBXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhBKHBhdGhQYXJzZXIpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gcGF0aFBhcnNlci5jdXJyZW50LFxuICAgICAgICAgIGNvbW1hbmQgPSBwYXRoUGFyc2VyLmNvbW1hbmQ7XG4gICAgICB2YXIgclggPSBjb21tYW5kLnJYLFxuICAgICAgICAgIHJZID0gY29tbWFuZC5yWSxcbiAgICAgICAgICB4Um90ID0gY29tbWFuZC54Um90LFxuICAgICAgICAgIGxBcmNGbGFnID0gY29tbWFuZC5sQXJjRmxhZyxcbiAgICAgICAgICBzd2VlcEZsYWcgPSBjb21tYW5kLnN3ZWVwRmxhZztcbiAgICAgIHZhciB4QXhpc1JvdGF0aW9uID0geFJvdCAqIChNYXRoLlBJIC8gMTgwLjApO1xuICAgICAgdmFyIGN1cnJlbnRQb2ludCA9IHBhdGhQYXJzZXIuZ2V0QXNDdXJyZW50UG9pbnQoKTsgLy8gQ29udmVyc2lvbiBmcm9tIGVuZHBvaW50IHRvIGNlbnRlciBwYXJhbWV0ZXJpemF0aW9uXG4gICAgICAvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9pbXBsbm90ZS5odG1sI0FyY0ltcGxlbWVudGF0aW9uTm90ZXNcbiAgICAgIC8vIHgxJywgeTEnXG5cbiAgICAgIHZhciBjdXJycCA9IG5ldyBQb2ludChNYXRoLmNvcyh4QXhpc1JvdGF0aW9uKSAqIChjdXJyZW50LnggLSBjdXJyZW50UG9pbnQueCkgLyAyLjAgKyBNYXRoLnNpbih4QXhpc1JvdGF0aW9uKSAqIChjdXJyZW50LnkgLSBjdXJyZW50UG9pbnQueSkgLyAyLjAsIC1NYXRoLnNpbih4QXhpc1JvdGF0aW9uKSAqIChjdXJyZW50LnggLSBjdXJyZW50UG9pbnQueCkgLyAyLjAgKyBNYXRoLmNvcyh4QXhpc1JvdGF0aW9uKSAqIChjdXJyZW50LnkgLSBjdXJyZW50UG9pbnQueSkgLyAyLjApOyAvLyBhZGp1c3QgcmFkaWlcblxuICAgICAgdmFyIGwgPSBNYXRoLnBvdyhjdXJycC54LCAyKSAvIE1hdGgucG93KHJYLCAyKSArIE1hdGgucG93KGN1cnJwLnksIDIpIC8gTWF0aC5wb3coclksIDIpO1xuXG4gICAgICBpZiAobCA+IDEpIHtcbiAgICAgICAgclggKj0gTWF0aC5zcXJ0KGwpO1xuICAgICAgICByWSAqPSBNYXRoLnNxcnQobCk7XG4gICAgICB9IC8vIGN4JywgY3knXG5cblxuICAgICAgdmFyIHMgPSAobEFyY0ZsYWcgPT09IHN3ZWVwRmxhZyA/IC0xIDogMSkgKiBNYXRoLnNxcnQoKE1hdGgucG93KHJYLCAyKSAqIE1hdGgucG93KHJZLCAyKSAtIE1hdGgucG93KHJYLCAyKSAqIE1hdGgucG93KGN1cnJwLnksIDIpIC0gTWF0aC5wb3coclksIDIpICogTWF0aC5wb3coY3VycnAueCwgMikpIC8gKE1hdGgucG93KHJYLCAyKSAqIE1hdGgucG93KGN1cnJwLnksIDIpICsgTWF0aC5wb3coclksIDIpICogTWF0aC5wb3coY3VycnAueCwgMikpKTtcblxuICAgICAgaWYgKGlzTmFOKHMpKSB7XG4gICAgICAgIHMgPSAwO1xuICAgICAgfVxuXG4gICAgICB2YXIgY3BwID0gbmV3IFBvaW50KHMgKiByWCAqIGN1cnJwLnkgLyByWSwgcyAqIC1yWSAqIGN1cnJwLnggLyByWCk7IC8vIGN4LCBjeVxuXG4gICAgICB2YXIgY2VudHAgPSBuZXcgUG9pbnQoKGN1cnJlbnQueCArIGN1cnJlbnRQb2ludC54KSAvIDIuMCArIE1hdGguY29zKHhBeGlzUm90YXRpb24pICogY3BwLnggLSBNYXRoLnNpbih4QXhpc1JvdGF0aW9uKSAqIGNwcC55LCAoY3VycmVudC55ICsgY3VycmVudFBvaW50LnkpIC8gMi4wICsgTWF0aC5zaW4oeEF4aXNSb3RhdGlvbikgKiBjcHAueCArIE1hdGguY29zKHhBeGlzUm90YXRpb24pICogY3BwLnkpOyAvLyBpbml0aWFsIGFuZ2xlXG5cbiAgICAgIHZhciBhMSA9IHZlY3RvcnNBbmdsZShbMSwgMF0sIFsoY3VycnAueCAtIGNwcC54KSAvIHJYLCAoY3VycnAueSAtIGNwcC55KSAvIHJZXSk7IC8vIM64MVxuICAgICAgLy8gYW5nbGUgZGVsdGFcblxuICAgICAgdmFyIHUgPSBbKGN1cnJwLnggLSBjcHAueCkgLyByWCwgKGN1cnJwLnkgLSBjcHAueSkgLyByWV07XG4gICAgICB2YXIgdiA9IFsoLWN1cnJwLnggLSBjcHAueCkgLyByWCwgKC1jdXJycC55IC0gY3BwLnkpIC8gclldO1xuICAgICAgdmFyIGFkID0gdmVjdG9yc0FuZ2xlKHUsIHYpOyAvLyDOlM64XG5cbiAgICAgIGlmICh2ZWN0b3JzUmF0aW8odSwgdikgPD0gLTEpIHtcbiAgICAgICAgYWQgPSBNYXRoLlBJO1xuICAgICAgfVxuXG4gICAgICBpZiAodmVjdG9yc1JhdGlvKHUsIHYpID49IDEpIHtcbiAgICAgICAgYWQgPSAwO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjdXJyZW50UG9pbnQ6IGN1cnJlbnRQb2ludCxcbiAgICAgICAgclg6IHJYLFxuICAgICAgICByWTogclksXG4gICAgICAgIHN3ZWVwRmxhZzogc3dlZXBGbGFnLFxuICAgICAgICB4QXhpc1JvdGF0aW9uOiB4QXhpc1JvdGF0aW9uLFxuICAgICAgICBjZW50cDogY2VudHAsXG4gICAgICAgIGExOiBhMSxcbiAgICAgICAgYWQ6IGFkXG4gICAgICB9O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXRoWlwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoWihwYXRoUGFyc2VyKSB7XG4gICAgICBwYXRoUGFyc2VyLmN1cnJlbnQgPSBwYXRoUGFyc2VyLnN0YXJ0O1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBQYXRoRWxlbWVudDtcbn0oUmVuZGVyZWRFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJEYoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkRigpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkRigpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBHbHlwaEVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9QYXRoRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEdseXBoRWxlbWVudCwgX1BhdGhFbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJEYoR2x5cGhFbGVtZW50KTtcblxuICBmdW5jdGlvbiBHbHlwaEVsZW1lbnQoZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIEdseXBoRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcbiAgICBfdGhpcy50eXBlID0gJ2dseXBoJztcbiAgICBfdGhpcy5ob3JpekFkdlggPSBfdGhpcy5nZXRBdHRyaWJ1dGUoJ2hvcml6LWFkdi14JykuZ2V0TnVtYmVyKCk7XG4gICAgX3RoaXMudW5pY29kZSA9IF90aGlzLmdldEF0dHJpYnV0ZSgndW5pY29kZScpLmdldFN0cmluZygpO1xuICAgIF90aGlzLmFyYWJpY0Zvcm0gPSBfdGhpcy5nZXRBdHRyaWJ1dGUoJ2FyYWJpYy1mb3JtJykuZ2V0U3RyaW5nKCk7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIEdseXBoRWxlbWVudDtcbn0oUGF0aEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkRShEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRFKCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRFKCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIFRleHRFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUmVuZGVyZWRFbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oVGV4dEVsZW1lbnQsIF9SZW5kZXJlZEVsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkRShUZXh0RWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gVGV4dEVsZW1lbnQoZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFRleHRFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgZG9jdW1lbnQsIG5vZGUsICh0aGlzIGluc3RhbmNlb2YgVGV4dEVsZW1lbnQgPyB0aGlzLmNvbnN0cnVjdG9yIDogdm9pZCAwKSA9PT0gVGV4dEVsZW1lbnQgPyB0cnVlIDogY2FwdHVyZVRleHROb2Rlcyk7XG4gICAgX3RoaXMudHlwZSA9ICd0ZXh0JztcbiAgICBfdGhpcy54ID0gMDtcbiAgICBfdGhpcy55ID0gMDtcbiAgICBfdGhpcy5tZWFzdXJlQ2FjaGUgPSAtMTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFRleHRFbGVtZW50LCBbe1xuICAgIGtleTogXCJzZXRDb250ZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldENvbnRleHQoY3R4KSB7XG4gICAgICB2YXIgZnJvbU1lYXN1cmUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZhbHNlO1xuXG4gICAgICBfZ2V0X19kZWZhdWx0W1wiZGVmYXVsdFwiXShfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFRleHRFbGVtZW50LnByb3RvdHlwZSksIFwic2V0Q29udGV4dFwiLCB0aGlzKS5jYWxsKHRoaXMsIGN0eCwgZnJvbU1lYXN1cmUpO1xuXG4gICAgICB2YXIgdGV4dEJhc2VsaW5lID0gdGhpcy5nZXRTdHlsZSgnZG9taW5hbnQtYmFzZWxpbmUnKS5nZXRUZXh0QmFzZWxpbmUoKSB8fCB0aGlzLmdldFN0eWxlKCdhbGlnbm1lbnQtYmFzZWxpbmUnKS5nZXRUZXh0QmFzZWxpbmUoKTtcblxuICAgICAgaWYgKHRleHRCYXNlbGluZSkge1xuICAgICAgICBjdHgudGV4dEJhc2VsaW5lID0gdGV4dEJhc2VsaW5lO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJpbml0aWFsaXplQ29vcmRpbmF0ZXNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gaW5pdGlhbGl6ZUNvb3JkaW5hdGVzKCkge1xuICAgICAgdGhpcy54ID0gMDtcbiAgICAgIHRoaXMueSA9IDA7XG4gICAgICB0aGlzLmxlYWZUZXh0cyA9IFtdO1xuICAgICAgdGhpcy50ZXh0Q2h1bmtTdGFydCA9IDA7XG4gICAgICB0aGlzLm1pblggPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgICB0aGlzLm1heFggPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldEJvdW5kaW5nQm94XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEJvdW5kaW5nQm94KGN0eCkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIGlmICh0aGlzLnR5cGUgIT09ICd0ZXh0Jykge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRURWxlbWVudEJvdW5kaW5nQm94KGN0eCk7XG4gICAgICB9IC8vIGZpcnN0LCBjYWxjdWxhdGUgY2hpbGQgcG9zaXRpb25zXG5cblxuICAgICAgdGhpcy5pbml0aWFsaXplQ29vcmRpbmF0ZXMoKTtcbiAgICAgIHRoaXMuYWRqdXN0Q2hpbGRDb29yZGluYXRlc1JlY3Vyc2l2ZShjdHgpO1xuICAgICAgdmFyIGJvdW5kaW5nQm94ID0gbnVsbDsgLy8gdGhlbiBjYWxjdWxhdGUgYm91bmRpbmcgYm94XG5cbiAgICAgIHRoaXMuY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoXywgaSkge1xuICAgICAgICB2YXIgY2hpbGRCb3VuZGluZ0JveCA9IF90aGlzMi5nZXRDaGlsZEJvdW5kaW5nQm94KGN0eCwgX3RoaXMyLCBfdGhpczIsIGkpO1xuXG4gICAgICAgIGlmICghYm91bmRpbmdCb3gpIHtcbiAgICAgICAgICBib3VuZGluZ0JveCA9IGNoaWxkQm91bmRpbmdCb3g7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYm91bmRpbmdCb3guYWRkQm91bmRpbmdCb3goY2hpbGRCb3VuZGluZ0JveCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGJvdW5kaW5nQm94O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRGb250U2l6ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRGb250U2l6ZSgpIHtcbiAgICAgIHZhciBkb2N1bWVudCA9IHRoaXMuZG9jdW1lbnQsXG4gICAgICAgICAgcGFyZW50ID0gdGhpcy5wYXJlbnQ7XG4gICAgICB2YXIgaW5oZXJpdEZvbnRTaXplID0gRm9udC5wYXJzZShkb2N1bWVudC5jdHguZm9udCkuZm9udFNpemU7XG4gICAgICB2YXIgZm9udFNpemUgPSBwYXJlbnQuZ2V0U3R5bGUoJ2ZvbnQtc2l6ZScpLmdldE51bWJlcihpbmhlcml0Rm9udFNpemUpO1xuICAgICAgcmV0dXJuIGZvbnRTaXplO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRURWxlbWVudEJvdW5kaW5nQm94XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFRFbGVtZW50Qm91bmRpbmdCb3goY3R4KSB7XG4gICAgICB2YXIgZm9udFNpemUgPSB0aGlzLmdldEZvbnRTaXplKCk7XG4gICAgICByZXR1cm4gbmV3IEJvdW5kaW5nQm94KHRoaXMueCwgdGhpcy55IC0gZm9udFNpemUsIHRoaXMueCArIHRoaXMubWVhc3VyZVRleHQoY3R4KSwgdGhpcy55KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0R2x5cGhcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0R2x5cGgoZm9udCwgdGV4dCwgaSkge1xuICAgICAgdmFyIGNoYXIgPSB0ZXh0W2ldO1xuICAgICAgdmFyIGdseXBoID0gbnVsbDtcblxuICAgICAgaWYgKGZvbnQuaXNBcmFiaWMpIHtcbiAgICAgICAgdmFyIGxlbiA9IHRleHQubGVuZ3RoO1xuICAgICAgICB2YXIgcHJldkNoYXIgPSB0ZXh0W2kgLSAxXTtcbiAgICAgICAgdmFyIG5leHRDaGFyID0gdGV4dFtpICsgMV07XG4gICAgICAgIHZhciBhcmFiaWNGb3JtID0gJ2lzb2xhdGVkJztcblxuICAgICAgICBpZiAoKGkgPT09IDAgfHwgcHJldkNoYXIgPT09ICcgJykgJiYgaSA8IGxlbiAtIDEgJiYgbmV4dENoYXIgIT09ICcgJykge1xuICAgICAgICAgIGFyYWJpY0Zvcm0gPSAndGVybWluYWwnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGkgPiAwICYmIHByZXZDaGFyICE9PSAnICcgJiYgaSA8IGxlbiAtIDEgJiYgbmV4dENoYXIgIT09ICcgJykge1xuICAgICAgICAgIGFyYWJpY0Zvcm0gPSAnbWVkaWFsJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpID4gMCAmJiBwcmV2Q2hhciAhPT0gJyAnICYmIChpID09PSBsZW4gLSAxIHx8IG5leHRDaGFyID09PSAnICcpKSB7XG4gICAgICAgICAgYXJhYmljRm9ybSA9ICdpbml0aWFsJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgZm9udC5nbHlwaHNbY2hhcl0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgLy8gTkVFRCBURVNUXG4gICAgICAgICAgdmFyIG1heWJlR2x5cGggPSBmb250LmdseXBoc1tjaGFyXTtcbiAgICAgICAgICBnbHlwaCA9IG1heWJlR2x5cGggaW5zdGFuY2VvZiBHbHlwaEVsZW1lbnQgPyBtYXliZUdseXBoIDogbWF5YmVHbHlwaFthcmFiaWNGb3JtXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZ2x5cGggPSBmb250LmdseXBoc1tjaGFyXTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFnbHlwaCkge1xuICAgICAgICBnbHlwaCA9IGZvbnQubWlzc2luZ0dseXBoO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZ2x5cGg7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldFRleHRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0VGV4dCgpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0VGV4dEZyb21Ob2RlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFRleHRGcm9tTm9kZShub2RlKSB7XG4gICAgICB2YXIgdGV4dE5vZGUgPSBub2RlIHx8IHRoaXMubm9kZTtcbiAgICAgIHZhciBjaGlsZE5vZGVzID0gQXJyYXkuZnJvbSh0ZXh0Tm9kZS5wYXJlbnROb2RlLmNoaWxkTm9kZXMpO1xuICAgICAgdmFyIGluZGV4ID0gY2hpbGROb2Rlcy5pbmRleE9mKHRleHROb2RlKTtcbiAgICAgIHZhciBsYXN0SW5kZXggPSBjaGlsZE5vZGVzLmxlbmd0aCAtIDE7XG4gICAgICB2YXIgdGV4dCA9IGNvbXByZXNzU3BhY2VzKCAvLyB0ZXh0Tm9kZS52YWx1ZVxuICAgICAgLy8gfHwgdGV4dE5vZGUudGV4dFxuICAgICAgdGV4dE5vZGUudGV4dENvbnRlbnQgfHwgJycpO1xuXG4gICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgdGV4dCA9IHRyaW1MZWZ0KHRleHQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5kZXggPT09IGxhc3RJbmRleCkge1xuICAgICAgICB0ZXh0ID0gdHJpbVJpZ2h0KHRleHQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyQ2hpbGRyZW5cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyQ2hpbGRyZW4oY3R4KSB7XG4gICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgaWYgKHRoaXMudHlwZSAhPT0gJ3RleHQnKSB7XG4gICAgICAgIHRoaXMucmVuZGVyVEVsZW1lbnRDaGlsZHJlbihjdHgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IC8vIGZpcnN0LCBjYWxjdWxhdGUgY2hpbGQgcG9zaXRpb25zXG5cblxuICAgICAgdGhpcy5pbml0aWFsaXplQ29vcmRpbmF0ZXMoKTtcbiAgICAgIHRoaXMuYWRqdXN0Q2hpbGRDb29yZGluYXRlc1JlY3Vyc2l2ZShjdHgpOyAvLyB0aGVuIHJlbmRlclxuXG4gICAgICB0aGlzLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKF8sIGkpIHtcbiAgICAgICAgX3RoaXMzLnJlbmRlckNoaWxkKGN0eCwgX3RoaXMzLCBfdGhpczMsIGkpO1xuICAgICAgfSk7XG4gICAgICB2YXIgbW91c2UgPSB0aGlzLmRvY3VtZW50LnNjcmVlbi5tb3VzZTsgLy8gRG8gbm90IGNhbGMgYm91bmRpbmcgYm94IGlmIG1vdXNlIGlzIG5vdCB3b3JraW5nLlxuXG4gICAgICBpZiAobW91c2UuaXNXb3JraW5nKCkpIHtcbiAgICAgICAgbW91c2UuY2hlY2tCb3VuZGluZ0JveCh0aGlzLCB0aGlzLmdldEJvdW5kaW5nQm94KGN0eCkpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJURWxlbWVudENoaWxkcmVuXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlclRFbGVtZW50Q2hpbGRyZW4oY3R4KSB7XG4gICAgICB2YXIgZG9jdW1lbnQgPSB0aGlzLmRvY3VtZW50LFxuICAgICAgICAgIHBhcmVudCA9IHRoaXMucGFyZW50O1xuICAgICAgdmFyIHJlbmRlclRleHQgPSB0aGlzLmdldFRleHQoKTtcbiAgICAgIHZhciBjdXN0b21Gb250ID0gcGFyZW50LmdldFN0eWxlKCdmb250LWZhbWlseScpLmdldERlZmluaXRpb24oKTtcblxuICAgICAgaWYgKGN1c3RvbUZvbnQpIHtcbiAgICAgICAgdmFyIHVuaXRzUGVyRW0gPSBjdXN0b21Gb250LmZvbnRGYWNlLnVuaXRzUGVyRW07XG4gICAgICAgIHZhciBjdHhGb250ID0gRm9udC5wYXJzZShkb2N1bWVudC5jdHguZm9udCk7XG4gICAgICAgIHZhciBmb250U2l6ZSA9IHBhcmVudC5nZXRTdHlsZSgnZm9udC1zaXplJykuZ2V0TnVtYmVyKGN0eEZvbnQuZm9udFNpemUpO1xuICAgICAgICB2YXIgZm9udFN0eWxlID0gcGFyZW50LmdldFN0eWxlKCdmb250LXN0eWxlJykuZ2V0U3RyaW5nKGN0eEZvbnQuZm9udFN0eWxlKTtcbiAgICAgICAgdmFyIHNjYWxlID0gZm9udFNpemUgLyB1bml0c1BlckVtO1xuICAgICAgICB2YXIgdGV4dCA9IGN1c3RvbUZvbnQuaXNSVEwgPyByZW5kZXJUZXh0LnNwbGl0KCcnKS5yZXZlcnNlKCkuam9pbignJykgOiByZW5kZXJUZXh0O1xuICAgICAgICB2YXIgZHggPSB0b051bWJlcnMocGFyZW50LmdldEF0dHJpYnV0ZSgnZHgnKS5nZXRTdHJpbmcoKSk7XG4gICAgICAgIHZhciBsZW4gPSB0ZXh0Lmxlbmd0aDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgdmFyIGdseXBoID0gdGhpcy5nZXRHbHlwaChjdXN0b21Gb250LCB0ZXh0LCBpKTtcbiAgICAgICAgICBjdHgudHJhbnNsYXRlKHRoaXMueCwgdGhpcy55KTtcbiAgICAgICAgICBjdHguc2NhbGUoc2NhbGUsIC1zY2FsZSk7XG4gICAgICAgICAgdmFyIGx3ID0gY3R4LmxpbmVXaWR0aDtcbiAgICAgICAgICBjdHgubGluZVdpZHRoID0gY3R4LmxpbmVXaWR0aCAqIHVuaXRzUGVyRW0gLyBmb250U2l6ZTtcblxuICAgICAgICAgIGlmIChmb250U3R5bGUgPT09ICdpdGFsaWMnKSB7XG4gICAgICAgICAgICBjdHgudHJhbnNmb3JtKDEsIDAsIC40LCAxLCAwLCAwKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBnbHlwaC5yZW5kZXIoY3R4KTtcblxuICAgICAgICAgIGlmIChmb250U3R5bGUgPT09ICdpdGFsaWMnKSB7XG4gICAgICAgICAgICBjdHgudHJhbnNmb3JtKDEsIDAsIC0uNCwgMSwgMCwgMCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY3R4LmxpbmVXaWR0aCA9IGx3O1xuICAgICAgICAgIGN0eC5zY2FsZSgxIC8gc2NhbGUsIC0xIC8gc2NhbGUpO1xuICAgICAgICAgIGN0eC50cmFuc2xhdGUoLXRoaXMueCwgLXRoaXMueSk7XG4gICAgICAgICAgdGhpcy54ICs9IGZvbnRTaXplICogKGdseXBoLmhvcml6QWR2WCB8fCBjdXN0b21Gb250Lmhvcml6QWR2WCkgLyB1bml0c1BlckVtO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBkeFtpXSAhPT0gJ3VuZGVmaW5lZCcgJiYgIWlzTmFOKGR4W2ldKSkge1xuICAgICAgICAgICAgdGhpcy54ICs9IGR4W2ldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHggPSB0aGlzLngsXG4gICAgICAgICAgeSA9IHRoaXMueTsgLy8gTkVFRCBURVNUXG4gICAgICAvLyBpZiAoY3R4LnBhaW50T3JkZXIgPT09ICdzdHJva2UnKSB7XG4gICAgICAvLyBcdGlmIChjdHguc3Ryb2tlU3R5bGUpIHtcbiAgICAgIC8vIFx0XHRjdHguc3Ryb2tlVGV4dChyZW5kZXJUZXh0LCB4LCB5KTtcbiAgICAgIC8vIFx0fVxuICAgICAgLy8gXHRpZiAoY3R4LmZpbGxTdHlsZSkge1xuICAgICAgLy8gXHRcdGN0eC5maWxsVGV4dChyZW5kZXJUZXh0LCB4LCB5KTtcbiAgICAgIC8vIFx0fVxuICAgICAgLy8gfSBlbHNlIHtcblxuICAgICAgaWYgKGN0eC5maWxsU3R5bGUpIHtcbiAgICAgICAgY3R4LmZpbGxUZXh0KHJlbmRlclRleHQsIHgsIHkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY3R4LnN0cm9rZVN0eWxlKSB7XG4gICAgICAgIGN0eC5zdHJva2VUZXh0KHJlbmRlclRleHQsIHgsIHkpO1xuICAgICAgfSAvLyB9XG5cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYXBwbHlBbmNob3JpbmdcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYXBwbHlBbmNob3JpbmcoKSB7XG4gICAgICBpZiAodGhpcy50ZXh0Q2h1bmtTdGFydCA+PSB0aGlzLmxlYWZUZXh0cy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSAvLyBUaGlzIGlzIGJhc2ljYWxseSB0aGUgXCJBcHBseSBhbmNob3JpbmdcIiBwYXJ0IG9mIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9TVkcyL3RleHQuaHRtbCNUZXh0TGF5b3V0QWxnb3JpdGhtLlxuICAgICAgLy8gVGhlIGRpZmZlcmVuY2UgaXMgdGhhdCB3ZSBhcHBseSB0aGUgYW5jaG9yaW5nIGFzIHNvb24gYXMgYSBjaHVuayBpcyBmaW5pc2hlZC4gVGhpcyBzYXZlcyBzb21lIGV4dHJhIGxvb3BpbmcuXG4gICAgICAvLyBWZXJ0aWNhbCB0ZXh0IGlzIG5vdCBzdXBwb3J0ZWQuXG5cblxuICAgICAgdmFyIGZpcnN0RWxlbWVudCA9IHRoaXMubGVhZlRleHRzW3RoaXMudGV4dENodW5rU3RhcnRdO1xuICAgICAgdmFyIHRleHRBbmNob3IgPSBmaXJzdEVsZW1lbnQuZ2V0U3R5bGUoJ3RleHQtYW5jaG9yJykuZ2V0U3RyaW5nKCdzdGFydCcpO1xuICAgICAgdmFyIGlzUlRMID0gZmFsc2U7IC8vIHdlIHRyZWF0IFJUTCBsaWtlIExUUlxuXG4gICAgICB2YXIgc2hpZnQgPSAwO1xuXG4gICAgICBpZiAodGV4dEFuY2hvciA9PT0gJ3N0YXJ0JyAmJiAhaXNSVEwgfHwgdGV4dEFuY2hvciA9PT0gJ2VuZCcgJiYgaXNSVEwpIHtcbiAgICAgICAgc2hpZnQgPSBmaXJzdEVsZW1lbnQueCAtIHRoaXMubWluWDtcbiAgICAgIH0gZWxzZSBpZiAodGV4dEFuY2hvciA9PT0gJ2VuZCcgJiYgIWlzUlRMIHx8IHRleHRBbmNob3IgPT09ICdzdGFydCcgJiYgaXNSVEwpIHtcbiAgICAgICAgc2hpZnQgPSBmaXJzdEVsZW1lbnQueCAtIHRoaXMubWF4WDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNoaWZ0ID0gZmlyc3RFbGVtZW50LnggLSAodGhpcy5taW5YICsgdGhpcy5tYXhYKSAvIDI7XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRleHRDaHVua1N0YXJ0OyBpIDwgdGhpcy5sZWFmVGV4dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy5sZWFmVGV4dHNbaV0ueCArPSBzaGlmdDtcbiAgICAgIH0gLy8gc3RhcnQgbmV3IGNodW5rXG5cblxuICAgICAgdGhpcy5taW5YID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgICAgdGhpcy5tYXhYID0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xuICAgICAgdGhpcy50ZXh0Q2h1bmtTdGFydCA9IHRoaXMubGVhZlRleHRzLmxlbmd0aDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYWRqdXN0Q2hpbGRDb29yZGluYXRlc1JlY3Vyc2l2ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhZGp1c3RDaGlsZENvb3JkaW5hdGVzUmVjdXJzaXZlKGN0eCkge1xuICAgICAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgICAgIHRoaXMuY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoXywgaSkge1xuICAgICAgICBfdGhpczQuYWRqdXN0Q2hpbGRDb29yZGluYXRlc1JlY3Vyc2l2ZUNvcmUoY3R4LCBfdGhpczQsIF90aGlzNCwgaSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuYXBwbHlBbmNob3JpbmcoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYWRqdXN0Q2hpbGRDb29yZGluYXRlc1JlY3Vyc2l2ZUNvcmVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYWRqdXN0Q2hpbGRDb29yZGluYXRlc1JlY3Vyc2l2ZUNvcmUoY3R4LCB0ZXh0UGFyZW50LCBwYXJlbnQsIGkpIHtcbiAgICAgIHZhciBjaGlsZCA9IHBhcmVudC5jaGlsZHJlbltpXTtcblxuICAgICAgaWYgKGNoaWxkLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY2hpbGQuY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoXywgaSkge1xuICAgICAgICAgIHRleHRQYXJlbnQuYWRqdXN0Q2hpbGRDb29yZGluYXRlc1JlY3Vyc2l2ZUNvcmUoY3R4LCB0ZXh0UGFyZW50LCBjaGlsZCwgaSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gb25seSBsZWFmcyBhcmUgcmVsZXZhbnRcbiAgICAgICAgdGhpcy5hZGp1c3RDaGlsZENvb3JkaW5hdGVzKGN0eCwgdGV4dFBhcmVudCwgcGFyZW50LCBpKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiYWRqdXN0Q2hpbGRDb29yZGluYXRlc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhZGp1c3RDaGlsZENvb3JkaW5hdGVzKGN0eCwgdGV4dFBhcmVudCwgcGFyZW50LCBpKSB7XG4gICAgICB2YXIgY2hpbGQgPSBwYXJlbnQuY2hpbGRyZW5baV07XG5cbiAgICAgIGlmICh0eXBlb2YgY2hpbGQubWVhc3VyZVRleHQgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgfVxuXG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgY2hpbGQuc2V0Q29udGV4dChjdHgsIHRydWUpO1xuICAgICAgdmFyIHhBdHRyID0gY2hpbGQuZ2V0QXR0cmlidXRlKCd4Jyk7XG4gICAgICB2YXIgeUF0dHIgPSBjaGlsZC5nZXRBdHRyaWJ1dGUoJ3knKTtcbiAgICAgIHZhciBkeEF0dHIgPSBjaGlsZC5nZXRBdHRyaWJ1dGUoJ2R4Jyk7XG4gICAgICB2YXIgZHlBdHRyID0gY2hpbGQuZ2V0QXR0cmlidXRlKCdkeScpO1xuICAgICAgdmFyIGN1c3RvbUZvbnQgPSBjaGlsZC5nZXRTdHlsZSgnZm9udC1mYW1pbHknKS5nZXREZWZpbml0aW9uKCk7XG4gICAgICB2YXIgaXNSVEwgPSBCb29sZWFuKGN1c3RvbUZvbnQpICYmIGN1c3RvbUZvbnQuaXNSVEw7XG5cbiAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgIC8vIEZpcnN0IGNoaWxkcmVuIGluaGVyaXQgYXR0cmlidXRlcyBmcm9tIHBhcmVudChzKS4gUG9zaXRpb25hbCBhdHRyaWJ1dGVzXG4gICAgICAgIC8vIGFyZSBvbmx5IGluaGVyaXRlZCBmcm9tIGEgcGFyZW50IHRvIGl0J3MgZmlyc3QgY2hpbGQuXG4gICAgICAgIGlmICgheEF0dHIuaGFzVmFsdWUoKSkge1xuICAgICAgICAgIHhBdHRyLnNldFZhbHVlKGNoaWxkLmdldEluaGVyaXRlZEF0dHJpYnV0ZSgneCcpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgheUF0dHIuaGFzVmFsdWUoKSkge1xuICAgICAgICAgIHlBdHRyLnNldFZhbHVlKGNoaWxkLmdldEluaGVyaXRlZEF0dHJpYnV0ZSgneScpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZHhBdHRyLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICBkeEF0dHIuc2V0VmFsdWUoY2hpbGQuZ2V0SW5oZXJpdGVkQXR0cmlidXRlKCdkeCcpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZHlBdHRyLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICBkeUF0dHIuc2V0VmFsdWUoY2hpbGQuZ2V0SW5oZXJpdGVkQXR0cmlidXRlKCdkeScpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgd2lkdGggPSBjaGlsZC5tZWFzdXJlVGV4dChjdHgpO1xuXG4gICAgICBpZiAoaXNSVEwpIHtcbiAgICAgICAgdGV4dFBhcmVudC54IC09IHdpZHRoO1xuICAgICAgfVxuXG4gICAgICBpZiAoeEF0dHIuaGFzVmFsdWUoKSkge1xuICAgICAgICAvLyBhbiBcInhcIiBhdHRyaWJ1dGUgbWFya3MgdGhlIHN0YXJ0IG9mIGEgbmV3IGNodW5rXG4gICAgICAgIHRleHRQYXJlbnQuYXBwbHlBbmNob3JpbmcoKTtcbiAgICAgICAgY2hpbGQueCA9IHhBdHRyLmdldFBpeGVscygneCcpO1xuXG4gICAgICAgIGlmIChkeEF0dHIuaGFzVmFsdWUoKSkge1xuICAgICAgICAgIGNoaWxkLnggKz0gZHhBdHRyLmdldFBpeGVscygneCcpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZHhBdHRyLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICB0ZXh0UGFyZW50LnggKz0gZHhBdHRyLmdldFBpeGVscygneCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQueCA9IHRleHRQYXJlbnQueDtcbiAgICAgIH1cblxuICAgICAgdGV4dFBhcmVudC54ID0gY2hpbGQueDtcblxuICAgICAgaWYgKCFpc1JUTCkge1xuICAgICAgICB0ZXh0UGFyZW50LnggKz0gd2lkdGg7XG4gICAgICB9XG5cbiAgICAgIGlmICh5QXR0ci5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIGNoaWxkLnkgPSB5QXR0ci5nZXRQaXhlbHMoJ3knKTtcblxuICAgICAgICBpZiAoZHlBdHRyLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICBjaGlsZC55ICs9IGR5QXR0ci5nZXRQaXhlbHMoJ3knKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGR5QXR0ci5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgdGV4dFBhcmVudC55ICs9IGR5QXR0ci5nZXRQaXhlbHMoJ3knKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoaWxkLnkgPSB0ZXh0UGFyZW50Lnk7XG4gICAgICB9XG5cbiAgICAgIHRleHRQYXJlbnQueSA9IGNoaWxkLnk7IC8vIHVwZGF0ZSB0aGUgY3VycmVudCBjaHVuayBhbmQgaXQncyBib3VuZHNcblxuICAgICAgdGV4dFBhcmVudC5sZWFmVGV4dHMucHVzaChjaGlsZCk7XG4gICAgICB0ZXh0UGFyZW50Lm1pblggPSBNYXRoLm1pbih0ZXh0UGFyZW50Lm1pblgsIGNoaWxkLngsIGNoaWxkLnggKyB3aWR0aCk7XG4gICAgICB0ZXh0UGFyZW50Lm1heFggPSBNYXRoLm1heCh0ZXh0UGFyZW50Lm1heFgsIGNoaWxkLngsIGNoaWxkLnggKyB3aWR0aCk7XG4gICAgICBjaGlsZC5jbGVhckNvbnRleHQoY3R4KTtcbiAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICByZXR1cm4gY2hpbGQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldENoaWxkQm91bmRpbmdCb3hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0Q2hpbGRCb3VuZGluZ0JveChjdHgsIHRleHRQYXJlbnQsIHBhcmVudCwgaSkge1xuICAgICAgdmFyIGNoaWxkID0gcGFyZW50LmNoaWxkcmVuW2ldOyAvLyBub3QgYSB0ZXh0IG5vZGU/XG5cbiAgICAgIGlmICh0eXBlb2YgY2hpbGQuZ2V0Qm91bmRpbmdCb3ggIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciBib3VuZGluZ0JveCA9IGNoaWxkLmdldEJvdW5kaW5nQm94KGN0eCk7XG5cbiAgICAgIGlmICghYm91bmRpbmdCb3gpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKF8sIGkpIHtcbiAgICAgICAgdmFyIGNoaWxkQm91bmRpbmdCb3ggPSB0ZXh0UGFyZW50LmdldENoaWxkQm91bmRpbmdCb3goY3R4LCB0ZXh0UGFyZW50LCBjaGlsZCwgaSk7XG4gICAgICAgIGJvdW5kaW5nQm94LmFkZEJvdW5kaW5nQm94KGNoaWxkQm91bmRpbmdCb3gpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYm91bmRpbmdCb3g7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlckNoaWxkXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlckNoaWxkKGN0eCwgdGV4dFBhcmVudCwgcGFyZW50LCBpKSB7XG4gICAgICB2YXIgY2hpbGQgPSBwYXJlbnQuY2hpbGRyZW5baV07XG4gICAgICBjaGlsZC5yZW5kZXIoY3R4KTtcbiAgICAgIGNoaWxkLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKF8sIGkpIHtcbiAgICAgICAgdGV4dFBhcmVudC5yZW5kZXJDaGlsZChjdHgsIHRleHRQYXJlbnQsIGNoaWxkLCBpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJtZWFzdXJlVGV4dFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBtZWFzdXJlVGV4dChjdHgpIHtcbiAgICAgIHZhciBtZWFzdXJlQ2FjaGUgPSB0aGlzLm1lYXN1cmVDYWNoZTtcblxuICAgICAgaWYgKH5tZWFzdXJlQ2FjaGUpIHtcbiAgICAgICAgcmV0dXJuIG1lYXN1cmVDYWNoZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlbmRlclRleHQgPSB0aGlzLmdldFRleHQoKTtcbiAgICAgIHZhciBtZWFzdXJlID0gdGhpcy5tZWFzdXJlVGFyZ2V0VGV4dChjdHgsIHJlbmRlclRleHQpO1xuICAgICAgdGhpcy5tZWFzdXJlQ2FjaGUgPSBtZWFzdXJlO1xuICAgICAgcmV0dXJuIG1lYXN1cmU7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIm1lYXN1cmVUYXJnZXRUZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG1lYXN1cmVUYXJnZXRUZXh0KGN0eCwgdGFyZ2V0VGV4dCkge1xuICAgICAgaWYgKCF0YXJnZXRUZXh0Lmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cblxuICAgICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50O1xuICAgICAgdmFyIGN1c3RvbUZvbnQgPSBwYXJlbnQuZ2V0U3R5bGUoJ2ZvbnQtZmFtaWx5JykuZ2V0RGVmaW5pdGlvbigpO1xuXG4gICAgICBpZiAoY3VzdG9tRm9udCkge1xuICAgICAgICB2YXIgZm9udFNpemUgPSB0aGlzLmdldEZvbnRTaXplKCk7XG4gICAgICAgIHZhciB0ZXh0ID0gY3VzdG9tRm9udC5pc1JUTCA/IHRhcmdldFRleHQuc3BsaXQoJycpLnJldmVyc2UoKS5qb2luKCcnKSA6IHRhcmdldFRleHQ7XG4gICAgICAgIHZhciBkeCA9IHRvTnVtYmVycyhwYXJlbnQuZ2V0QXR0cmlidXRlKCdkeCcpLmdldFN0cmluZygpKTtcbiAgICAgICAgdmFyIGxlbiA9IHRleHQubGVuZ3RoO1xuICAgICAgICB2YXIgX21lYXN1cmUgPSAwO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICB2YXIgZ2x5cGggPSB0aGlzLmdldEdseXBoKGN1c3RvbUZvbnQsIHRleHQsIGkpO1xuICAgICAgICAgIF9tZWFzdXJlICs9IChnbHlwaC5ob3JpekFkdlggfHwgY3VzdG9tRm9udC5ob3JpekFkdlgpICogZm9udFNpemUgLyBjdXN0b21Gb250LmZvbnRGYWNlLnVuaXRzUGVyRW07XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGR4W2ldICE9PSAndW5kZWZpbmVkJyAmJiAhaXNOYU4oZHhbaV0pKSB7XG4gICAgICAgICAgICBfbWVhc3VyZSArPSBkeFtpXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gX21lYXN1cmU7XG4gICAgICB9XG5cbiAgICAgIGlmICghY3R4Lm1lYXN1cmVUZXh0KSB7XG4gICAgICAgIHJldHVybiB0YXJnZXRUZXh0Lmxlbmd0aCAqIDEwO1xuICAgICAgfVxuXG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgdGhpcy5zZXRDb250ZXh0KGN0eCwgdHJ1ZSk7XG5cbiAgICAgIHZhciBfY3R4JG1lYXN1cmVUZXh0ID0gY3R4Lm1lYXN1cmVUZXh0KHRhcmdldFRleHQpLFxuICAgICAgICAgIG1lYXN1cmUgPSBfY3R4JG1lYXN1cmVUZXh0LndpZHRoO1xuXG4gICAgICB0aGlzLmNsZWFyQ29udGV4dChjdHgpO1xuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICAgIHJldHVybiBtZWFzdXJlO1xuICAgIH1cbiAgICAvKipcclxuICAgICAqIEluaGVyaXRzIHBvc2l0aW9uYWwgYXR0cmlidXRlcyBmcm9tIHtAbGluayBUZXh0RWxlbWVudH0gcGFyZW50KHMpLiBBdHRyaWJ1dGVzXHJcbiAgICAgKiBhcmUgb25seSBpbmhlcml0ZWQgZnJvbSBhIHBhcmVudCB0byBpdHMgZmlyc3QgY2hpbGQuXHJcbiAgICAgKiBAcGFyYW0gbmFtZSAtIFRoZSBhdHRyaWJ1dGUgbmFtZS5cclxuICAgICAqIEByZXR1cm5zIFRoZSBhdHRyaWJ1dGUgdmFsdWUgb3IgbnVsbC5cclxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0SW5oZXJpdGVkQXR0cmlidXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEluaGVyaXRlZEF0dHJpYnV0ZShuYW1lKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXMsY29uc2lzdGVudC10aGlzXG4gICAgICB2YXIgY3VycmVudCA9IHRoaXM7XG5cbiAgICAgIHdoaWxlIChjdXJyZW50IGluc3RhbmNlb2YgVGV4dEVsZW1lbnQgJiYgY3VycmVudC5pc0ZpcnN0Q2hpbGQoKSkge1xuICAgICAgICB2YXIgcGFyZW50QXR0ciA9IGN1cnJlbnQucGFyZW50LmdldEF0dHJpYnV0ZShuYW1lKTtcblxuICAgICAgICBpZiAocGFyZW50QXR0ci5oYXNWYWx1ZSh0cnVlKSkge1xuICAgICAgICAgIHJldHVybiBwYXJlbnRBdHRyLmdldFZhbHVlKCcwJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50ID0gY3VycmVudC5wYXJlbnQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBUZXh0RWxlbWVudDtcbn0oUmVuZGVyZWRFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJEQoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkRCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkRCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBUU3BhbkVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9UZXh0RWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFRTcGFuRWxlbWVudCwgX1RleHRFbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJEQoVFNwYW5FbGVtZW50KTtcblxuICBmdW5jdGlvbiBUU3BhbkVsZW1lbnQoZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFRTcGFuRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCAodGhpcyBpbnN0YW5jZW9mIFRTcGFuRWxlbWVudCA/IHRoaXMuY29uc3RydWN0b3IgOiB2b2lkIDApID09PSBUU3BhbkVsZW1lbnQgPyB0cnVlIDogY2FwdHVyZVRleHROb2Rlcyk7XG4gICAgX3RoaXMudHlwZSA9ICd0c3Bhbic7IC8vIGlmIHRoaXMgbm9kZSBoYXMgY2hpbGRyZW4sIHRoZW4gdGhleSBvd24gdGhlIHRleHRcblxuICAgIF90aGlzLnRleHQgPSBfdGhpcy5jaGlsZHJlbi5sZW5ndGggPiAwID8gJycgOiBfdGhpcy5nZXRUZXh0RnJvbU5vZGUoKTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFRTcGFuRWxlbWVudCwgW3tcbiAgICBrZXk6IFwiZ2V0VGV4dFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRUZXh0KCkge1xuICAgICAgcmV0dXJuIHRoaXMudGV4dDtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gVFNwYW5FbGVtZW50O1xufShUZXh0RWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRDKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JEMoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JEMoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgVGV4dE5vZGUgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9UU3BhbkVsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShUZXh0Tm9kZSwgX1RTcGFuRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciRDKFRleHROb2RlKTtcblxuICBmdW5jdGlvbiBUZXh0Tm9kZSgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFRleHROb2RlKTtcblxuICAgIF90aGlzID0gX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgX3RoaXMudHlwZSA9ICd0ZXh0Tm9kZSc7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIFRleHROb2RlO1xufShUU3BhbkVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkQihEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRCKCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRCKCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIFNWR0VsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9SZW5kZXJlZEVsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShTVkdFbGVtZW50LCBfUmVuZGVyZWRFbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJEIoU1ZHRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gU1ZHRWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFNWR0VsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfdGhpcy50eXBlID0gJ3N2Zyc7XG4gICAgX3RoaXMucm9vdCA9IGZhbHNlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oU1ZHRWxlbWVudCwgW3tcbiAgICBrZXk6IFwic2V0Q29udGV4dFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRDb250ZXh0KGN0eCkge1xuICAgICAgdmFyIF90aGlzJG5vZGUkcGFyZW50Tm9kZTtcblxuICAgICAgdmFyIGRvY3VtZW50ID0gdGhpcy5kb2N1bWVudDtcbiAgICAgIHZhciBzY3JlZW4gPSBkb2N1bWVudC5zY3JlZW4sXG4gICAgICAgICAgd2luZG93ID0gZG9jdW1lbnQud2luZG93O1xuICAgICAgdmFyIGNhbnZhcyA9IGN0eC5jYW52YXM7XG4gICAgICBzY3JlZW4uc2V0RGVmYXVsdHMoY3R4KTtcblxuICAgICAgaWYgKGNhbnZhcy5zdHlsZSAmJiB0eXBlb2YgY3R4LmZvbnQgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdyAmJiB0eXBlb2Ygd2luZG93LmdldENvbXB1dGVkU3R5bGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGN0eC5mb250ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoY2FudmFzKS5nZXRQcm9wZXJ0eVZhbHVlKCdmb250Jyk7XG4gICAgICAgIHZhciBmb250U2l6ZVByb3AgPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICdmb250U2l6ZScsIEZvbnQucGFyc2UoY3R4LmZvbnQpLmZvbnRTaXplKTtcblxuICAgICAgICBpZiAoZm9udFNpemVQcm9wLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgICBkb2N1bWVudC5yb290RW1TaXplID0gZm9udFNpemVQcm9wLmdldFBpeGVscygneScpO1xuICAgICAgICAgIGRvY3VtZW50LmVtU2l6ZSA9IGRvY3VtZW50LnJvb3RFbVNpemU7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gY3JlYXRlIG5ldyB2aWV3IHBvcnRcblxuXG4gICAgICBpZiAoIXRoaXMuZ2V0QXR0cmlidXRlKCd4JykuaGFzVmFsdWUoKSkge1xuICAgICAgICB0aGlzLmdldEF0dHJpYnV0ZSgneCcsIHRydWUpLnNldFZhbHVlKDApO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuZ2V0QXR0cmlidXRlKCd5JykuaGFzVmFsdWUoKSkge1xuICAgICAgICB0aGlzLmdldEF0dHJpYnV0ZSgneScsIHRydWUpLnNldFZhbHVlKDApO1xuICAgICAgfVxuXG4gICAgICB2YXIgX3NjcmVlbiR2aWV3UG9ydCA9IHNjcmVlbi52aWV3UG9ydCxcbiAgICAgICAgICB3aWR0aCA9IF9zY3JlZW4kdmlld1BvcnQud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0ID0gX3NjcmVlbiR2aWV3UG9ydC5oZWlnaHQ7XG5cbiAgICAgIGlmICghdGhpcy5nZXRTdHlsZSgnd2lkdGgnKS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIHRoaXMuZ2V0U3R5bGUoJ3dpZHRoJywgdHJ1ZSkuc2V0VmFsdWUoJzEwMCUnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLmdldFN0eWxlKCdoZWlnaHQnKS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIHRoaXMuZ2V0U3R5bGUoJ2hlaWdodCcsIHRydWUpLnNldFZhbHVlKCcxMDAlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5nZXRTdHlsZSgnY29sb3InKS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIHRoaXMuZ2V0U3R5bGUoJ2NvbG9yJywgdHJ1ZSkuc2V0VmFsdWUoJ2JsYWNrJyk7XG4gICAgICB9XG5cbiAgICAgIHZhciByZWZYQXR0ciA9IHRoaXMuZ2V0QXR0cmlidXRlKCdyZWZYJyk7XG4gICAgICB2YXIgcmVmWUF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZSgncmVmWScpO1xuICAgICAgdmFyIHZpZXdCb3hBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3ZpZXdCb3gnKTtcbiAgICAgIHZhciB2aWV3Qm94ID0gdmlld0JveEF0dHIuaGFzVmFsdWUoKSA/IHRvTnVtYmVycyh2aWV3Qm94QXR0ci5nZXRTdHJpbmcoKSkgOiBudWxsO1xuICAgICAgdmFyIGNsaXAgPSAhdGhpcy5yb290ICYmIHRoaXMuZ2V0U3R5bGUoJ292ZXJmbG93JykuZ2V0VmFsdWUoJ2hpZGRlbicpICE9PSAndmlzaWJsZSc7XG4gICAgICB2YXIgbWluWCA9IDA7XG4gICAgICB2YXIgbWluWSA9IDA7XG4gICAgICB2YXIgY2xpcFggPSAwO1xuICAgICAgdmFyIGNsaXBZID0gMDtcblxuICAgICAgaWYgKHZpZXdCb3gpIHtcbiAgICAgICAgbWluWCA9IHZpZXdCb3hbMF07XG4gICAgICAgIG1pblkgPSB2aWV3Qm94WzFdO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMucm9vdCkge1xuICAgICAgICB3aWR0aCA9IHRoaXMuZ2V0U3R5bGUoJ3dpZHRoJykuZ2V0UGl4ZWxzKCd4Jyk7XG4gICAgICAgIGhlaWdodCA9IHRoaXMuZ2V0U3R5bGUoJ2hlaWdodCcpLmdldFBpeGVscygneScpO1xuXG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICdtYXJrZXInKSB7XG4gICAgICAgICAgY2xpcFggPSBtaW5YO1xuICAgICAgICAgIGNsaXBZID0gbWluWTtcbiAgICAgICAgICBtaW5YID0gMDtcbiAgICAgICAgICBtaW5ZID0gMDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzY3JlZW4udmlld1BvcnQuc2V0Q3VycmVudCh3aWR0aCwgaGVpZ2h0KTsgLy8gRGVmYXVsdCB2YWx1ZSBvZiB0cmFuc2Zvcm0tb3JpZ2luIGlzIGNlbnRlciBvbmx5IGZvciByb290IFNWRyBlbGVtZW50c1xuICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvU1ZHL0F0dHJpYnV0ZS90cmFuc2Zvcm0tb3JpZ2luXG5cbiAgICAgIGlmICh0aGlzLm5vZGUgLy8gaXMgbm90IHRlbXBvcmFyeSBTVkdFbGVtZW50XG4gICAgICAmJiAoIXRoaXMucGFyZW50IHx8ICgoX3RoaXMkbm9kZSRwYXJlbnROb2RlID0gdGhpcy5ub2RlLnBhcmVudE5vZGUpID09PSBudWxsIHx8IF90aGlzJG5vZGUkcGFyZW50Tm9kZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX3RoaXMkbm9kZSRwYXJlbnROb2RlLm5vZGVOYW1lKSA9PT0gJ2ZvcmVpZ25PYmplY3QnKSAmJiB0aGlzLmdldFN0eWxlKCd0cmFuc2Zvcm0nLCBmYWxzZSwgdHJ1ZSkuaGFzVmFsdWUoKSAmJiAhdGhpcy5nZXRTdHlsZSgndHJhbnNmb3JtLW9yaWdpbicsIGZhbHNlLCB0cnVlKS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIHRoaXMuZ2V0U3R5bGUoJ3RyYW5zZm9ybS1vcmlnaW4nLCB0cnVlLCB0cnVlKS5zZXRWYWx1ZSgnNTAlIDUwJScpO1xuICAgICAgfVxuXG4gICAgICBfZ2V0X19kZWZhdWx0W1wiZGVmYXVsdFwiXShfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFNWR0VsZW1lbnQucHJvdG90eXBlKSwgXCJzZXRDb250ZXh0XCIsIHRoaXMpLmNhbGwodGhpcywgY3R4KTtcblxuICAgICAgY3R4LnRyYW5zbGF0ZSh0aGlzLmdldEF0dHJpYnV0ZSgneCcpLmdldFBpeGVscygneCcpLCB0aGlzLmdldEF0dHJpYnV0ZSgneScpLmdldFBpeGVscygneScpKTtcblxuICAgICAgaWYgKHZpZXdCb3gpIHtcbiAgICAgICAgd2lkdGggPSB2aWV3Qm94WzJdO1xuICAgICAgICBoZWlnaHQgPSB2aWV3Qm94WzNdO1xuICAgICAgfVxuXG4gICAgICBkb2N1bWVudC5zZXRWaWV3Qm94KHtcbiAgICAgICAgY3R4OiBjdHgsXG4gICAgICAgIGFzcGVjdFJhdGlvOiB0aGlzLmdldEF0dHJpYnV0ZSgncHJlc2VydmVBc3BlY3RSYXRpbycpLmdldFN0cmluZygpLFxuICAgICAgICB3aWR0aDogc2NyZWVuLnZpZXdQb3J0LndpZHRoLFxuICAgICAgICBkZXNpcmVkV2lkdGg6IHdpZHRoLFxuICAgICAgICBoZWlnaHQ6IHNjcmVlbi52aWV3UG9ydC5oZWlnaHQsXG4gICAgICAgIGRlc2lyZWRIZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgbWluWDogbWluWCxcbiAgICAgICAgbWluWTogbWluWSxcbiAgICAgICAgcmVmWDogcmVmWEF0dHIuZ2V0VmFsdWUoKSxcbiAgICAgICAgcmVmWTogcmVmWUF0dHIuZ2V0VmFsdWUoKSxcbiAgICAgICAgY2xpcDogY2xpcCxcbiAgICAgICAgY2xpcFg6IGNsaXBYLFxuICAgICAgICBjbGlwWTogY2xpcFlcbiAgICAgIH0pO1xuXG4gICAgICBpZiAodmlld0JveCkge1xuICAgICAgICBzY3JlZW4udmlld1BvcnQucmVtb3ZlQ3VycmVudCgpO1xuICAgICAgICBzY3JlZW4udmlld1BvcnQuc2V0Q3VycmVudCh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY2xlYXJDb250ZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNsZWFyQ29udGV4dChjdHgpIHtcbiAgICAgIF9nZXRfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oU1ZHRWxlbWVudC5wcm90b3R5cGUpLCBcImNsZWFyQ29udGV4dFwiLCB0aGlzKS5jYWxsKHRoaXMsIGN0eCk7XG5cbiAgICAgIHRoaXMuZG9jdW1lbnQuc2NyZWVuLnZpZXdQb3J0LnJlbW92ZUN1cnJlbnQoKTtcbiAgICB9XG4gICAgLyoqXHJcbiAgICAgKiBSZXNpemUgU1ZHIHRvIGZpdCBpbiBnaXZlbiBzaXplLlxyXG4gICAgICogQHBhcmFtIHdpZHRoXHJcbiAgICAgKiBAcGFyYW0gaGVpZ2h0XHJcbiAgICAgKiBAcGFyYW0gcHJlc2VydmVBc3BlY3RSYXRpb1xyXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZXNpemVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVzaXplKHdpZHRoKSB7XG4gICAgICB2YXIgaGVpZ2h0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB3aWR0aDtcbiAgICAgIHZhciBwcmVzZXJ2ZUFzcGVjdFJhdGlvID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBmYWxzZTtcbiAgICAgIHZhciB3aWR0aEF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZSgnd2lkdGgnLCB0cnVlKTtcbiAgICAgIHZhciBoZWlnaHRBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIHRydWUpO1xuICAgICAgdmFyIHZpZXdCb3hBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3ZpZXdCb3gnKTtcbiAgICAgIHZhciBzdHlsZUF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZSgnc3R5bGUnKTtcbiAgICAgIHZhciBvcmlnaW5XaWR0aCA9IHdpZHRoQXR0ci5nZXROdW1iZXIoMCk7XG4gICAgICB2YXIgb3JpZ2luSGVpZ2h0ID0gaGVpZ2h0QXR0ci5nZXROdW1iZXIoMCk7XG5cbiAgICAgIGlmIChwcmVzZXJ2ZUFzcGVjdFJhdGlvKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcHJlc2VydmVBc3BlY3RSYXRpbyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aGlzLmdldEF0dHJpYnV0ZSgncHJlc2VydmVBc3BlY3RSYXRpbycsIHRydWUpLnNldFZhbHVlKHByZXNlcnZlQXNwZWN0UmF0aW8pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBwcmVzZXJ2ZUFzcGVjdFJhdGlvQXR0ciA9IHRoaXMuZ2V0QXR0cmlidXRlKCdwcmVzZXJ2ZUFzcGVjdFJhdGlvJyk7XG5cbiAgICAgICAgICBpZiAocHJlc2VydmVBc3BlY3RSYXRpb0F0dHIuaGFzVmFsdWUoKSkge1xuICAgICAgICAgICAgcHJlc2VydmVBc3BlY3RSYXRpb0F0dHIuc2V0VmFsdWUocHJlc2VydmVBc3BlY3RSYXRpb0F0dHIuZ2V0U3RyaW5nKCkucmVwbGFjZSgvXlxccyooXFxTLipcXFMpXFxzKiQvLCAnJDEnKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHdpZHRoQXR0ci5zZXRWYWx1ZSh3aWR0aCk7XG4gICAgICBoZWlnaHRBdHRyLnNldFZhbHVlKGhlaWdodCk7XG5cbiAgICAgIGlmICghdmlld0JveEF0dHIuaGFzVmFsdWUoKSkge1xuICAgICAgICB2aWV3Qm94QXR0ci5zZXRWYWx1ZShcIjAgMCBcIi5jb25jYXQob3JpZ2luV2lkdGggfHwgd2lkdGgsIFwiIFwiKS5jb25jYXQob3JpZ2luSGVpZ2h0IHx8IGhlaWdodCkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3R5bGVBdHRyLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgdmFyIHdpZHRoU3R5bGUgPSB0aGlzLmdldFN0eWxlKCd3aWR0aCcpO1xuICAgICAgICB2YXIgaGVpZ2h0U3R5bGUgPSB0aGlzLmdldFN0eWxlKCdoZWlnaHQnKTtcblxuICAgICAgICBpZiAod2lkdGhTdHlsZS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgd2lkdGhTdHlsZS5zZXRWYWx1ZShcIlwiLmNvbmNhdCh3aWR0aCwgXCJweFwiKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGVpZ2h0U3R5bGUuaGFzVmFsdWUoKSkge1xuICAgICAgICAgIGhlaWdodFN0eWxlLnNldFZhbHVlKFwiXCIuY29uY2F0KGhlaWdodCwgXCJweFwiKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gU1ZHRWxlbWVudDtcbn0oUmVuZGVyZWRFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJEEoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkQSgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkQSgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBSZWN0RWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1BhdGhFbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oUmVjdEVsZW1lbnQsIF9QYXRoRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciRBKFJlY3RFbGVtZW50KTtcblxuICBmdW5jdGlvbiBSZWN0RWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFJlY3RFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgX3RoaXMudHlwZSA9ICdyZWN0JztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFJlY3RFbGVtZW50LCBbe1xuICAgIGtleTogXCJwYXRoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGgoY3R4KSB7XG4gICAgICB2YXIgeCA9IHRoaXMuZ2V0QXR0cmlidXRlKCd4JykuZ2V0UGl4ZWxzKCd4Jyk7XG4gICAgICB2YXIgeSA9IHRoaXMuZ2V0QXR0cmlidXRlKCd5JykuZ2V0UGl4ZWxzKCd5Jyk7XG4gICAgICB2YXIgd2lkdGggPSB0aGlzLmdldFN0eWxlKCd3aWR0aCcsIGZhbHNlLCB0cnVlKS5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgIHZhciBoZWlnaHQgPSB0aGlzLmdldFN0eWxlKCdoZWlnaHQnLCBmYWxzZSwgdHJ1ZSkuZ2V0UGl4ZWxzKCd5Jyk7XG4gICAgICB2YXIgcnhBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3J4Jyk7XG4gICAgICB2YXIgcnlBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3J5Jyk7XG4gICAgICB2YXIgcnggPSByeEF0dHIuZ2V0UGl4ZWxzKCd4Jyk7XG4gICAgICB2YXIgcnkgPSByeUF0dHIuZ2V0UGl4ZWxzKCd5Jyk7XG5cbiAgICAgIGlmIChyeEF0dHIuaGFzVmFsdWUoKSAmJiAhcnlBdHRyLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgcnkgPSByeDtcbiAgICAgIH1cblxuICAgICAgaWYgKHJ5QXR0ci5oYXNWYWx1ZSgpICYmICFyeEF0dHIuaGFzVmFsdWUoKSkge1xuICAgICAgICByeCA9IHJ5O1xuICAgICAgfVxuXG4gICAgICByeCA9IE1hdGgubWluKHJ4LCB3aWR0aCAvIDIuMCk7XG4gICAgICByeSA9IE1hdGgubWluKHJ5LCBoZWlnaHQgLyAyLjApO1xuXG4gICAgICBpZiAoY3R4KSB7XG4gICAgICAgIHZhciBLQVBQQSA9IDQgKiAoKE1hdGguc3FydCgyKSAtIDEpIC8gMyk7XG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTsgLy8gYWx3YXlzIHN0YXJ0IHRoZSBwYXRoIHNvIHdlIGRvbid0IGZpbGwgcHJpb3IgcGF0aHNcblxuICAgICAgICBpZiAoaGVpZ2h0ID4gMCAmJiB3aWR0aCA+IDApIHtcbiAgICAgICAgICBjdHgubW92ZVRvKHggKyByeCwgeSk7XG4gICAgICAgICAgY3R4LmxpbmVUbyh4ICsgd2lkdGggLSByeCwgeSk7XG4gICAgICAgICAgY3R4LmJlemllckN1cnZlVG8oeCArIHdpZHRoIC0gcnggKyBLQVBQQSAqIHJ4LCB5LCB4ICsgd2lkdGgsIHkgKyByeSAtIEtBUFBBICogcnksIHggKyB3aWR0aCwgeSArIHJ5KTtcbiAgICAgICAgICBjdHgubGluZVRvKHggKyB3aWR0aCwgeSArIGhlaWdodCAtIHJ5KTtcbiAgICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyh4ICsgd2lkdGgsIHkgKyBoZWlnaHQgLSByeSArIEtBUFBBICogcnksIHggKyB3aWR0aCAtIHJ4ICsgS0FQUEEgKiByeCwgeSArIGhlaWdodCwgeCArIHdpZHRoIC0gcngsIHkgKyBoZWlnaHQpO1xuICAgICAgICAgIGN0eC5saW5lVG8oeCArIHJ4LCB5ICsgaGVpZ2h0KTtcbiAgICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyh4ICsgcnggLSBLQVBQQSAqIHJ4LCB5ICsgaGVpZ2h0LCB4LCB5ICsgaGVpZ2h0IC0gcnkgKyBLQVBQQSAqIHJ5LCB4LCB5ICsgaGVpZ2h0IC0gcnkpO1xuICAgICAgICAgIGN0eC5saW5lVG8oeCwgeSArIHJ5KTtcbiAgICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyh4LCB5ICsgcnkgLSBLQVBQQSAqIHJ5LCB4ICsgcnggLSBLQVBQQSAqIHJ4LCB5LCB4ICsgcngsIHkpO1xuICAgICAgICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IEJvdW5kaW5nQm94KHgsIHksIHggKyB3aWR0aCwgeSArIGhlaWdodCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldE1hcmtlcnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0TWFya2VycygpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBSZWN0RWxlbWVudDtcbn0oUGF0aEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkeihEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCR6KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCR6KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIENpcmNsZUVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9QYXRoRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKENpcmNsZUVsZW1lbnQsIF9QYXRoRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciR6KENpcmNsZUVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIENpcmNsZUVsZW1lbnQoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBDaXJjbGVFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgX3RoaXMudHlwZSA9ICdjaXJjbGUnO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oQ2lyY2xlRWxlbWVudCwgW3tcbiAgICBrZXk6IFwicGF0aFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoKGN0eCkge1xuICAgICAgdmFyIGN4ID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2N4JykuZ2V0UGl4ZWxzKCd4Jyk7XG4gICAgICB2YXIgY3kgPSB0aGlzLmdldEF0dHJpYnV0ZSgnY3knKS5nZXRQaXhlbHMoJ3knKTtcbiAgICAgIHZhciByID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3InKS5nZXRQaXhlbHMoKTtcblxuICAgICAgaWYgKGN0eCAmJiByID4gMCkge1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGN0eC5hcmMoY3gsIGN5LCByLCAwLCBNYXRoLlBJICogMiwgZmFsc2UpO1xuICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgQm91bmRpbmdCb3goY3ggLSByLCBjeSAtIHIsIGN4ICsgciwgY3kgKyByKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0TWFya2Vyc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRNYXJrZXJzKCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIENpcmNsZUVsZW1lbnQ7XG59KFBhdGhFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJHkoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkeSgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkeSgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBFbGxpcHNlRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1BhdGhFbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oRWxsaXBzZUVsZW1lbnQsIF9QYXRoRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciR5KEVsbGlwc2VFbGVtZW50KTtcblxuICBmdW5jdGlvbiBFbGxpcHNlRWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIEVsbGlwc2VFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgX3RoaXMudHlwZSA9ICdlbGxpcHNlJztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEVsbGlwc2VFbGVtZW50LCBbe1xuICAgIGtleTogXCJwYXRoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGgoY3R4KSB7XG4gICAgICB2YXIgS0FQUEEgPSA0ICogKChNYXRoLnNxcnQoMikgLSAxKSAvIDMpO1xuICAgICAgdmFyIHJ4ID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3J4JykuZ2V0UGl4ZWxzKCd4Jyk7XG4gICAgICB2YXIgcnkgPSB0aGlzLmdldEF0dHJpYnV0ZSgncnknKS5nZXRQaXhlbHMoJ3knKTtcbiAgICAgIHZhciBjeCA9IHRoaXMuZ2V0QXR0cmlidXRlKCdjeCcpLmdldFBpeGVscygneCcpO1xuICAgICAgdmFyIGN5ID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2N5JykuZ2V0UGl4ZWxzKCd5Jyk7XG5cbiAgICAgIGlmIChjdHggJiYgcnggPiAwICYmIHJ5ID4gMCkge1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGN0eC5tb3ZlVG8oY3ggKyByeCwgY3kpO1xuICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyhjeCArIHJ4LCBjeSArIEtBUFBBICogcnksIGN4ICsgS0FQUEEgKiByeCwgY3kgKyByeSwgY3gsIGN5ICsgcnkpO1xuICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyhjeCAtIEtBUFBBICogcngsIGN5ICsgcnksIGN4IC0gcngsIGN5ICsgS0FQUEEgKiByeSwgY3ggLSByeCwgY3kpO1xuICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyhjeCAtIHJ4LCBjeSAtIEtBUFBBICogcnksIGN4IC0gS0FQUEEgKiByeCwgY3kgLSByeSwgY3gsIGN5IC0gcnkpO1xuICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyhjeCArIEtBUFBBICogcngsIGN5IC0gcnksIGN4ICsgcngsIGN5IC0gS0FQUEEgKiByeSwgY3ggKyByeCwgY3kpO1xuICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgQm91bmRpbmdCb3goY3ggLSByeCwgY3kgLSByeSwgY3ggKyByeCwgY3kgKyByeSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldE1hcmtlcnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0TWFya2VycygpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBFbGxpcHNlRWxlbWVudDtcbn0oUGF0aEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkeChEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCR4KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCR4KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIExpbmVFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUGF0aEVsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShMaW5lRWxlbWVudCwgX1BhdGhFbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJHgoTGluZUVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIExpbmVFbGVtZW50KCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgTGluZUVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfdGhpcy50eXBlID0gJ2xpbmUnO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oTGluZUVsZW1lbnQsIFt7XG4gICAga2V5OiBcImdldFBvaW50c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRQb2ludHMoKSB7XG4gICAgICByZXR1cm4gW25ldyBQb2ludCh0aGlzLmdldEF0dHJpYnV0ZSgneDEnKS5nZXRQaXhlbHMoJ3gnKSwgdGhpcy5nZXRBdHRyaWJ1dGUoJ3kxJykuZ2V0UGl4ZWxzKCd5JykpLCBuZXcgUG9pbnQodGhpcy5nZXRBdHRyaWJ1dGUoJ3gyJykuZ2V0UGl4ZWxzKCd4JyksIHRoaXMuZ2V0QXR0cmlidXRlKCd5MicpLmdldFBpeGVscygneScpKV07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aChjdHgpIHtcbiAgICAgIHZhciBfdGhpcyRnZXRQb2ludHMgPSB0aGlzLmdldFBvaW50cygpLFxuICAgICAgICAgIF90aGlzJGdldFBvaW50czIgPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX3RoaXMkZ2V0UG9pbnRzLCAyKSxcbiAgICAgICAgICBfdGhpcyRnZXRQb2ludHMyJCA9IF90aGlzJGdldFBvaW50czJbMF0sXG4gICAgICAgICAgeDAgPSBfdGhpcyRnZXRQb2ludHMyJC54LFxuICAgICAgICAgIHkwID0gX3RoaXMkZ2V0UG9pbnRzMiQueSxcbiAgICAgICAgICBfdGhpcyRnZXRQb2ludHMyJDIgPSBfdGhpcyRnZXRQb2ludHMyWzFdLFxuICAgICAgICAgIHgxID0gX3RoaXMkZ2V0UG9pbnRzMiQyLngsXG4gICAgICAgICAgeTEgPSBfdGhpcyRnZXRQb2ludHMyJDIueTtcblxuICAgICAgaWYgKGN0eCkge1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGN0eC5tb3ZlVG8oeDAsIHkwKTtcbiAgICAgICAgY3R4LmxpbmVUbyh4MSwgeTEpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IEJvdW5kaW5nQm94KHgwLCB5MCwgeDEsIHkxKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0TWFya2Vyc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRNYXJrZXJzKCkge1xuICAgICAgdmFyIF90aGlzJGdldFBvaW50czMgPSB0aGlzLmdldFBvaW50cygpLFxuICAgICAgICAgIF90aGlzJGdldFBvaW50czQgPSBfc2xpY2VkVG9BcnJheV9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX3RoaXMkZ2V0UG9pbnRzMywgMiksXG4gICAgICAgICAgcDAgPSBfdGhpcyRnZXRQb2ludHM0WzBdLFxuICAgICAgICAgIHAxID0gX3RoaXMkZ2V0UG9pbnRzNFsxXTtcblxuICAgICAgdmFyIGEgPSBwMC5hbmdsZVRvKHAxKTtcbiAgICAgIHJldHVybiBbW3AwLCBhXSwgW3AxLCBhXV07XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIExpbmVFbGVtZW50O1xufShQYXRoRWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciR3KERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JHcoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JHcoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgUG9seWxpbmVFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUGF0aEVsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShQb2x5bGluZUVsZW1lbnQsIF9QYXRoRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciR3KFBvbHlsaW5lRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gUG9seWxpbmVFbGVtZW50KGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBQb2x5bGluZUVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcyk7XG4gICAgX3RoaXMudHlwZSA9ICdwb2x5bGluZSc7XG4gICAgX3RoaXMucG9pbnRzID0gW107XG4gICAgX3RoaXMucG9pbnRzID0gUG9pbnQucGFyc2VQYXRoKF90aGlzLmdldEF0dHJpYnV0ZSgncG9pbnRzJykuZ2V0U3RyaW5nKCkpO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oUG9seWxpbmVFbGVtZW50LCBbe1xuICAgIGtleTogXCJwYXRoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGgoY3R4KSB7XG4gICAgICB2YXIgcG9pbnRzID0gdGhpcy5wb2ludHM7XG5cbiAgICAgIHZhciBfcG9pbnRzID0gX3NsaWNlZFRvQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHBvaW50cywgMSksXG4gICAgICAgICAgX3BvaW50cyQgPSBfcG9pbnRzWzBdLFxuICAgICAgICAgIHgwID0gX3BvaW50cyQueCxcbiAgICAgICAgICB5MCA9IF9wb2ludHMkLnk7XG5cbiAgICAgIHZhciBib3VuZGluZ0JveCA9IG5ldyBCb3VuZGluZ0JveCh4MCwgeTApO1xuXG4gICAgICBpZiAoY3R4KSB7XG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgY3R4Lm1vdmVUbyh4MCwgeTApO1xuICAgICAgfVxuXG4gICAgICBwb2ludHMuZm9yRWFjaChmdW5jdGlvbiAoX3JlZikge1xuICAgICAgICB2YXIgeCA9IF9yZWYueCxcbiAgICAgICAgICAgIHkgPSBfcmVmLnk7XG4gICAgICAgIGJvdW5kaW5nQm94LmFkZFBvaW50KHgsIHkpO1xuXG4gICAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgICBjdHgubGluZVRvKHgsIHkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBib3VuZGluZ0JveDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0TWFya2Vyc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRNYXJrZXJzKCkge1xuICAgICAgdmFyIHBvaW50cyA9IHRoaXMucG9pbnRzO1xuICAgICAgdmFyIGxhc3RJbmRleCA9IHBvaW50cy5sZW5ndGggLSAxO1xuICAgICAgdmFyIG1hcmtlcnMgPSBbXTtcbiAgICAgIHBvaW50cy5mb3JFYWNoKGZ1bmN0aW9uIChwb2ludCwgaSkge1xuICAgICAgICBpZiAoaSA9PT0gbGFzdEluZGV4KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbWFya2Vycy5wdXNoKFtwb2ludCwgcG9pbnQuYW5nbGVUbyhwb2ludHNbaSArIDFdKV0pO1xuICAgICAgfSk7XG5cbiAgICAgIGlmIChtYXJrZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbWFya2Vycy5wdXNoKFtwb2ludHNbcG9pbnRzLmxlbmd0aCAtIDFdLCBtYXJrZXJzW21hcmtlcnMubGVuZ3RoIC0gMV1bMV1dKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG1hcmtlcnM7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFBvbHlsaW5lRWxlbWVudDtcbn0oUGF0aEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkdihEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCR2KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCR2KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIFBvbHlnb25FbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUG9seWxpbmVFbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oUG9seWdvbkVsZW1lbnQsIF9Qb2x5bGluZUVsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkdihQb2x5Z29uRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gUG9seWdvbkVsZW1lbnQoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBQb2x5Z29uRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF90aGlzLnR5cGUgPSAncG9seWdvbic7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShQb2x5Z29uRWxlbWVudCwgW3tcbiAgICBrZXk6IFwicGF0aFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoKGN0eCkge1xuICAgICAgdmFyIGJvdW5kaW5nQm94ID0gX2dldF9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShQb2x5Z29uRWxlbWVudC5wcm90b3R5cGUpLCBcInBhdGhcIiwgdGhpcykuY2FsbCh0aGlzLCBjdHgpO1xuXG4gICAgICB2YXIgX3RoaXMkcG9pbnRzID0gX3NsaWNlZFRvQXJyYXlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMucG9pbnRzLCAxKSxcbiAgICAgICAgICBfdGhpcyRwb2ludHMkID0gX3RoaXMkcG9pbnRzWzBdLFxuICAgICAgICAgIHggPSBfdGhpcyRwb2ludHMkLngsXG4gICAgICAgICAgeSA9IF90aGlzJHBvaW50cyQueTtcblxuICAgICAgaWYgKGN0eCkge1xuICAgICAgICBjdHgubGluZVRvKHgsIHkpO1xuICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBib3VuZGluZ0JveDtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gUG9seWdvbkVsZW1lbnQ7XG59KFBvbHlsaW5lRWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciR1KERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JHUoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JHUoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgUGF0dGVybkVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9FbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oUGF0dGVybkVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJHUoUGF0dGVybkVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIFBhdHRlcm5FbGVtZW50KCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgUGF0dGVybkVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfdGhpcy50eXBlID0gJ3BhdHRlcm4nO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oUGF0dGVybkVsZW1lbnQsIFt7XG4gICAga2V5OiBcImNyZWF0ZVBhdHRlcm5cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlUGF0dGVybihjdHgsIF8sIHBhcmVudE9wYWNpdHlQcm9wKSB7XG4gICAgICB2YXIgd2lkdGggPSB0aGlzLmdldFN0eWxlKCd3aWR0aCcpLmdldFBpeGVscygneCcsIHRydWUpO1xuICAgICAgdmFyIGhlaWdodCA9IHRoaXMuZ2V0U3R5bGUoJ2hlaWdodCcpLmdldFBpeGVscygneScsIHRydWUpOyAvLyByZW5kZXIgbWUgdXNpbmcgYSB0ZW1wb3Jhcnkgc3ZnIGVsZW1lbnRcblxuICAgICAgdmFyIHBhdHRlcm5TdmcgPSBuZXcgU1ZHRWxlbWVudCh0aGlzLmRvY3VtZW50LCBudWxsKTtcbiAgICAgIHBhdHRlcm5TdmcuYXR0cmlidXRlcy52aWV3Qm94ID0gbmV3IFByb3BlcnR5KHRoaXMuZG9jdW1lbnQsICd2aWV3Qm94JywgdGhpcy5nZXRBdHRyaWJ1dGUoJ3ZpZXdCb3gnKS5nZXRWYWx1ZSgpKTtcbiAgICAgIHBhdHRlcm5TdmcuYXR0cmlidXRlcy53aWR0aCA9IG5ldyBQcm9wZXJ0eSh0aGlzLmRvY3VtZW50LCAnd2lkdGgnLCBcIlwiLmNvbmNhdCh3aWR0aCwgXCJweFwiKSk7XG4gICAgICBwYXR0ZXJuU3ZnLmF0dHJpYnV0ZXMuaGVpZ2h0ID0gbmV3IFByb3BlcnR5KHRoaXMuZG9jdW1lbnQsICdoZWlnaHQnLCBcIlwiLmNvbmNhdChoZWlnaHQsIFwicHhcIikpO1xuICAgICAgcGF0dGVyblN2Zy5hdHRyaWJ1dGVzLnRyYW5zZm9ybSA9IG5ldyBQcm9wZXJ0eSh0aGlzLmRvY3VtZW50LCAndHJhbnNmb3JtJywgdGhpcy5nZXRBdHRyaWJ1dGUoJ3BhdHRlcm5UcmFuc2Zvcm0nKS5nZXRWYWx1ZSgpKTtcbiAgICAgIHBhdHRlcm5TdmcuY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuO1xuICAgICAgdmFyIHBhdHRlcm5DYW52YXMgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIHZhciBwYXR0ZXJuQ3R4ID0gcGF0dGVybkNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgdmFyIHhBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3gnKTtcbiAgICAgIHZhciB5QXR0ciA9IHRoaXMuZ2V0QXR0cmlidXRlKCd5Jyk7XG5cbiAgICAgIGlmICh4QXR0ci5oYXNWYWx1ZSgpICYmIHlBdHRyLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgcGF0dGVybkN0eC50cmFuc2xhdGUoeEF0dHIuZ2V0UGl4ZWxzKCd4JywgdHJ1ZSksIHlBdHRyLmdldFBpeGVscygneScsIHRydWUpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmVudE9wYWNpdHlQcm9wLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgdGhpcy5zdHlsZXNbJ2ZpbGwtb3BhY2l0eSddID0gcGFyZW50T3BhY2l0eVByb3A7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KHRoaXMuc3R5bGVzLCAnZmlsbC1vcGFjaXR5Jyk7XG4gICAgICB9IC8vIHJlbmRlciAzeDMgZ3JpZCBzbyB3aGVuIHdlIHRyYW5zZm9ybSB0aGVyZSdzIG5vIHdoaXRlIHNwYWNlIG9uIGVkZ2VzXG5cblxuICAgICAgZm9yICh2YXIgeCA9IC0xOyB4IDw9IDE7IHgrKykge1xuICAgICAgICBmb3IgKHZhciB5ID0gLTE7IHkgPD0gMTsgeSsrKSB7XG4gICAgICAgICAgcGF0dGVybkN0eC5zYXZlKCk7XG4gICAgICAgICAgcGF0dGVyblN2Zy5hdHRyaWJ1dGVzLnggPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgJ3gnLCB4ICogcGF0dGVybkNhbnZhcy53aWR0aCk7XG4gICAgICAgICAgcGF0dGVyblN2Zy5hdHRyaWJ1dGVzLnkgPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgJ3knLCB5ICogcGF0dGVybkNhbnZhcy5oZWlnaHQpO1xuICAgICAgICAgIHBhdHRlcm5TdmcucmVuZGVyKHBhdHRlcm5DdHgpO1xuICAgICAgICAgIHBhdHRlcm5DdHgucmVzdG9yZSgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBwYXR0ZXJuID0gY3R4LmNyZWF0ZVBhdHRlcm4ocGF0dGVybkNhbnZhcywgJ3JlcGVhdCcpO1xuICAgICAgcmV0dXJuIHBhdHRlcm47XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFBhdHRlcm5FbGVtZW50O1xufShFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJHQoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkdCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkdCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBNYXJrZXJFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKE1hcmtlckVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJHQoTWFya2VyRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gTWFya2VyRWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIE1hcmtlckVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfdGhpcy50eXBlID0gJ21hcmtlcic7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShNYXJrZXJFbGVtZW50LCBbe1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKGN0eCwgcG9pbnQsIGFuZ2xlKSB7XG4gICAgICBpZiAoIXBvaW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHggPSBwb2ludC54LFxuICAgICAgICAgIHkgPSBwb2ludC55O1xuICAgICAgdmFyIG9yaWVudCA9IHRoaXMuZ2V0QXR0cmlidXRlKCdvcmllbnQnKS5nZXRTdHJpbmcoJ2F1dG8nKTtcbiAgICAgIHZhciBtYXJrZXJVbml0cyA9IHRoaXMuZ2V0QXR0cmlidXRlKCdtYXJrZXJVbml0cycpLmdldFN0cmluZygnc3Ryb2tlV2lkdGgnKTtcbiAgICAgIGN0eC50cmFuc2xhdGUoeCwgeSk7XG5cbiAgICAgIGlmIChvcmllbnQgPT09ICdhdXRvJykge1xuICAgICAgICBjdHgucm90YXRlKGFuZ2xlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1hcmtlclVuaXRzID09PSAnc3Ryb2tlV2lkdGgnKSB7XG4gICAgICAgIGN0eC5zY2FsZShjdHgubGluZVdpZHRoLCBjdHgubGluZVdpZHRoKTtcbiAgICAgIH1cblxuICAgICAgY3R4LnNhdmUoKTsgLy8gcmVuZGVyIG1lIHVzaW5nIGEgdGVtcG9yYXJ5IHN2ZyBlbGVtZW50XG5cbiAgICAgIHZhciBtYXJrZXJTdmcgPSBuZXcgU1ZHRWxlbWVudCh0aGlzLmRvY3VtZW50LCBudWxsKTtcbiAgICAgIG1hcmtlclN2Zy50eXBlID0gdGhpcy50eXBlO1xuICAgICAgbWFya2VyU3ZnLmF0dHJpYnV0ZXMudmlld0JveCA9IG5ldyBQcm9wZXJ0eSh0aGlzLmRvY3VtZW50LCAndmlld0JveCcsIHRoaXMuZ2V0QXR0cmlidXRlKCd2aWV3Qm94JykuZ2V0VmFsdWUoKSk7XG4gICAgICBtYXJrZXJTdmcuYXR0cmlidXRlcy5yZWZYID0gbmV3IFByb3BlcnR5KHRoaXMuZG9jdW1lbnQsICdyZWZYJywgdGhpcy5nZXRBdHRyaWJ1dGUoJ3JlZlgnKS5nZXRWYWx1ZSgpKTtcbiAgICAgIG1hcmtlclN2Zy5hdHRyaWJ1dGVzLnJlZlkgPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgJ3JlZlknLCB0aGlzLmdldEF0dHJpYnV0ZSgncmVmWScpLmdldFZhbHVlKCkpO1xuICAgICAgbWFya2VyU3ZnLmF0dHJpYnV0ZXMud2lkdGggPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgJ3dpZHRoJywgdGhpcy5nZXRBdHRyaWJ1dGUoJ21hcmtlcldpZHRoJykuZ2V0VmFsdWUoKSk7XG4gICAgICBtYXJrZXJTdmcuYXR0cmlidXRlcy5oZWlnaHQgPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgJ2hlaWdodCcsIHRoaXMuZ2V0QXR0cmlidXRlKCdtYXJrZXJIZWlnaHQnKS5nZXRWYWx1ZSgpKTtcbiAgICAgIG1hcmtlclN2Zy5hdHRyaWJ1dGVzLm92ZXJmbG93ID0gbmV3IFByb3BlcnR5KHRoaXMuZG9jdW1lbnQsICdvdmVyZmxvdycsIHRoaXMuZ2V0QXR0cmlidXRlKCdvdmVyZmxvdycpLmdldFZhbHVlKCkpO1xuICAgICAgbWFya2VyU3ZnLmF0dHJpYnV0ZXMuZmlsbCA9IG5ldyBQcm9wZXJ0eSh0aGlzLmRvY3VtZW50LCAnZmlsbCcsIHRoaXMuZ2V0QXR0cmlidXRlKCdmaWxsJykuZ2V0Q29sb3IoJ2JsYWNrJykpO1xuICAgICAgbWFya2VyU3ZnLmF0dHJpYnV0ZXMuc3Ryb2tlID0gbmV3IFByb3BlcnR5KHRoaXMuZG9jdW1lbnQsICdzdHJva2UnLCB0aGlzLmdldEF0dHJpYnV0ZSgnc3Ryb2tlJykuZ2V0VmFsdWUoJ25vbmUnKSk7XG4gICAgICBtYXJrZXJTdmcuY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuO1xuICAgICAgbWFya2VyU3ZnLnJlbmRlcihjdHgpO1xuICAgICAgY3R4LnJlc3RvcmUoKTtcblxuICAgICAgaWYgKG1hcmtlclVuaXRzID09PSAnc3Ryb2tlV2lkdGgnKSB7XG4gICAgICAgIGN0eC5zY2FsZSgxIC8gY3R4LmxpbmVXaWR0aCwgMSAvIGN0eC5saW5lV2lkdGgpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3JpZW50ID09PSAnYXV0bycpIHtcbiAgICAgICAgY3R4LnJvdGF0ZSgtYW5nbGUpO1xuICAgICAgfVxuXG4gICAgICBjdHgudHJhbnNsYXRlKC14LCAteSk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIE1hcmtlckVsZW1lbnQ7XG59KEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkcyhEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRzKCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRzKCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIERlZnNFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlZnNFbGVtZW50LCBfRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciRzKERlZnNFbGVtZW50KTtcblxuICBmdW5jdGlvbiBEZWZzRWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIERlZnNFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgX3RoaXMudHlwZSA9ICdkZWZzJztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlZnNFbGVtZW50LCBbe1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkgey8vIE5PT1BcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gRGVmc0VsZW1lbnQ7XG59KEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkcihEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRyKCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRyKCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIEdFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUmVuZGVyZWRFbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oR0VsZW1lbnQsIF9SZW5kZXJlZEVsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkcihHRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gR0VsZW1lbnQoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBHRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF90aGlzLnR5cGUgPSAnZyc7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShHRWxlbWVudCwgW3tcbiAgICBrZXk6IFwiZ2V0Qm91bmRpbmdCb3hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0Qm91bmRpbmdCb3goY3R4KSB7XG4gICAgICB2YXIgYm91bmRpbmdCb3ggPSBuZXcgQm91bmRpbmdCb3goKTtcbiAgICAgIHRoaXMuY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgYm91bmRpbmdCb3guYWRkQm91bmRpbmdCb3goY2hpbGQuZ2V0Qm91bmRpbmdCb3goY3R4KSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBib3VuZGluZ0JveDtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gR0VsZW1lbnQ7XG59KFJlbmRlcmVkRWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRxKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JHEoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JHEoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgR3JhZGllbnRFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEdyYWRpZW50RWxlbWVudCwgX0VsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkcShHcmFkaWVudEVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIEdyYWRpZW50RWxlbWVudChkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcykge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgR3JhZGllbnRFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpO1xuICAgIF90aGlzLmF0dHJpYnV0ZXNUb0luaGVyaXQgPSBbJ2dyYWRpZW50VW5pdHMnXTtcbiAgICBfdGhpcy5zdG9wcyA9IFtdO1xuXG4gICAgdmFyIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZSA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF90aGlzKSxcbiAgICAgICAgc3RvcHMgPSBfYXNzZXJ0VGhpc0luaXRpYWxpemUuc3RvcHMsXG4gICAgICAgIGNoaWxkcmVuID0gX2Fzc2VydFRoaXNJbml0aWFsaXplLmNoaWxkcmVuO1xuXG4gICAgY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgIGlmIChjaGlsZC50eXBlID09PSAnc3RvcCcpIHtcbiAgICAgICAgc3RvcHMucHVzaChjaGlsZCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShHcmFkaWVudEVsZW1lbnQsIFt7XG4gICAga2V5OiBcImdldEdyYWRpZW50VW5pdHNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0R3JhZGllbnRVbml0cygpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgnZ3JhZGllbnRVbml0cycpLmdldFN0cmluZygnb2JqZWN0Qm91bmRpbmdCb3gnKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlR3JhZGllbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlR3JhZGllbnQoY3R4LCBlbGVtZW50LCBwYXJlbnRPcGFjaXR5UHJvcCkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhcywgY29uc2lzdGVudC10aGlzXG4gICAgICB2YXIgc3RvcHNDb250YWluZXIgPSB0aGlzO1xuXG4gICAgICBpZiAodGhpcy5nZXRIcmVmQXR0cmlidXRlKCkuaGFzVmFsdWUoKSkge1xuICAgICAgICBzdG9wc0NvbnRhaW5lciA9IHRoaXMuZ2V0SHJlZkF0dHJpYnV0ZSgpLmdldERlZmluaXRpb24oKTtcbiAgICAgICAgdGhpcy5pbmhlcml0U3RvcENvbnRhaW5lcihzdG9wc0NvbnRhaW5lcik7XG4gICAgICB9XG5cbiAgICAgIHZhciBfc3RvcHNDb250YWluZXIgPSBzdG9wc0NvbnRhaW5lcixcbiAgICAgICAgICBzdG9wcyA9IF9zdG9wc0NvbnRhaW5lci5zdG9wcztcbiAgICAgIHZhciBncmFkaWVudCA9IHRoaXMuZ2V0R3JhZGllbnQoY3R4LCBlbGVtZW50KTtcblxuICAgICAgaWYgKCFncmFkaWVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRQYXJlbnRPcGFjaXR5KHBhcmVudE9wYWNpdHlQcm9wLCBzdG9wc1tzdG9wcy5sZW5ndGggLSAxXS5jb2xvcik7XG4gICAgICB9XG5cbiAgICAgIHN0b3BzLmZvckVhY2goZnVuY3Rpb24gKHN0b3ApIHtcbiAgICAgICAgZ3JhZGllbnQuYWRkQ29sb3JTdG9wKHN0b3Aub2Zmc2V0LCBfdGhpczIuYWRkUGFyZW50T3BhY2l0eShwYXJlbnRPcGFjaXR5UHJvcCwgc3RvcC5jb2xvcikpO1xuICAgICAgfSk7XG5cbiAgICAgIGlmICh0aGlzLmdldEF0dHJpYnV0ZSgnZ3JhZGllbnRUcmFuc2Zvcm0nKS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIC8vIHJlbmRlciBhcyB0cmFuc2Zvcm1lZCBwYXR0ZXJuIG9uIHRlbXBvcmFyeSBjYW52YXNcbiAgICAgICAgdmFyIGRvY3VtZW50ID0gdGhpcy5kb2N1bWVudDtcbiAgICAgICAgdmFyIF9kb2N1bWVudCRzY3JlZW4gPSBkb2N1bWVudC5zY3JlZW4sXG4gICAgICAgICAgICBNQVhfVklSVFVBTF9QSVhFTFMgPSBfZG9jdW1lbnQkc2NyZWVuLk1BWF9WSVJUVUFMX1BJWEVMUyxcbiAgICAgICAgICAgIHZpZXdQb3J0ID0gX2RvY3VtZW50JHNjcmVlbi52aWV3UG9ydDtcblxuICAgICAgICB2YXIgX3ZpZXdQb3J0JHZpZXdQb3J0cyA9IF9zbGljZWRUb0FycmF5X19kZWZhdWx0W1wiZGVmYXVsdFwiXSh2aWV3UG9ydC52aWV3UG9ydHMsIDEpLFxuICAgICAgICAgICAgcm9vdFZpZXcgPSBfdmlld1BvcnQkdmlld1BvcnRzWzBdO1xuXG4gICAgICAgIHZhciByZWN0ID0gbmV3IFJlY3RFbGVtZW50KGRvY3VtZW50LCBudWxsKTtcbiAgICAgICAgcmVjdC5hdHRyaWJ1dGVzLnggPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICd4JywgLU1BWF9WSVJUVUFMX1BJWEVMUyAvIDMuMCk7XG4gICAgICAgIHJlY3QuYXR0cmlidXRlcy55ID0gbmV3IFByb3BlcnR5KGRvY3VtZW50LCAneScsIC1NQVhfVklSVFVBTF9QSVhFTFMgLyAzLjApO1xuICAgICAgICByZWN0LmF0dHJpYnV0ZXMud2lkdGggPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICd3aWR0aCcsIE1BWF9WSVJUVUFMX1BJWEVMUyk7XG4gICAgICAgIHJlY3QuYXR0cmlidXRlcy5oZWlnaHQgPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICdoZWlnaHQnLCBNQVhfVklSVFVBTF9QSVhFTFMpO1xuICAgICAgICB2YXIgZ3JvdXAgPSBuZXcgR0VsZW1lbnQoZG9jdW1lbnQsIG51bGwpO1xuICAgICAgICBncm91cC5hdHRyaWJ1dGVzLnRyYW5zZm9ybSA9IG5ldyBQcm9wZXJ0eShkb2N1bWVudCwgJ3RyYW5zZm9ybScsIHRoaXMuZ2V0QXR0cmlidXRlKCdncmFkaWVudFRyYW5zZm9ybScpLmdldFZhbHVlKCkpO1xuICAgICAgICBncm91cC5jaGlsZHJlbiA9IFtyZWN0XTtcbiAgICAgICAgdmFyIHBhdHRlcm5TdmcgPSBuZXcgU1ZHRWxlbWVudChkb2N1bWVudCwgbnVsbCk7XG4gICAgICAgIHBhdHRlcm5TdmcuYXR0cmlidXRlcy54ID0gbmV3IFByb3BlcnR5KGRvY3VtZW50LCAneCcsIDApO1xuICAgICAgICBwYXR0ZXJuU3ZnLmF0dHJpYnV0ZXMueSA9IG5ldyBQcm9wZXJ0eShkb2N1bWVudCwgJ3knLCAwKTtcbiAgICAgICAgcGF0dGVyblN2Zy5hdHRyaWJ1dGVzLndpZHRoID0gbmV3IFByb3BlcnR5KGRvY3VtZW50LCAnd2lkdGgnLCByb290Vmlldy53aWR0aCk7XG4gICAgICAgIHBhdHRlcm5TdmcuYXR0cmlidXRlcy5oZWlnaHQgPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICdoZWlnaHQnLCByb290Vmlldy5oZWlnaHQpO1xuICAgICAgICBwYXR0ZXJuU3ZnLmNoaWxkcmVuID0gW2dyb3VwXTtcbiAgICAgICAgdmFyIHBhdHRlcm5DYW52YXMgPSBkb2N1bWVudC5jcmVhdGVDYW52YXMocm9vdFZpZXcud2lkdGgsIHJvb3RWaWV3LmhlaWdodCk7XG4gICAgICAgIHZhciBwYXR0ZXJuQ3R4ID0gcGF0dGVybkNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICBwYXR0ZXJuQ3R4LmZpbGxTdHlsZSA9IGdyYWRpZW50O1xuICAgICAgICBwYXR0ZXJuU3ZnLnJlbmRlcihwYXR0ZXJuQ3R4KTtcbiAgICAgICAgcmV0dXJuIHBhdHRlcm5DdHguY3JlYXRlUGF0dGVybihwYXR0ZXJuQ2FudmFzLCAnbm8tcmVwZWF0Jyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBncmFkaWVudDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiaW5oZXJpdFN0b3BDb250YWluZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gaW5oZXJpdFN0b3BDb250YWluZXIoc3RvcHNDb250YWluZXIpIHtcbiAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICB0aGlzLmF0dHJpYnV0ZXNUb0luaGVyaXQuZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlVG9Jbmhlcml0KSB7XG4gICAgICAgIGlmICghX3RoaXMzLmdldEF0dHJpYnV0ZShhdHRyaWJ1dGVUb0luaGVyaXQpLmhhc1ZhbHVlKCkgJiYgc3RvcHNDb250YWluZXIuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZVRvSW5oZXJpdCkuaGFzVmFsdWUoKSkge1xuICAgICAgICAgIF90aGlzMy5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlVG9Jbmhlcml0LCB0cnVlKS5zZXRWYWx1ZShzdG9wc0NvbnRhaW5lci5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlVG9Jbmhlcml0KS5nZXRWYWx1ZSgpKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImFkZFBhcmVudE9wYWNpdHlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYWRkUGFyZW50T3BhY2l0eShwYXJlbnRPcGFjaXR5UHJvcCwgY29sb3IpIHtcbiAgICAgIGlmIChwYXJlbnRPcGFjaXR5UHJvcC5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIHZhciBjb2xvclByb3AgPSBuZXcgUHJvcGVydHkodGhpcy5kb2N1bWVudCwgJ2NvbG9yJywgY29sb3IpO1xuICAgICAgICByZXR1cm4gY29sb3JQcm9wLmFkZE9wYWNpdHkocGFyZW50T3BhY2l0eVByb3ApLmdldENvbG9yKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjb2xvcjtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gR3JhZGllbnRFbGVtZW50O1xufShFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJHAoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkcCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkcCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBMaW5lYXJHcmFkaWVudEVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9HcmFkaWVudEVsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShMaW5lYXJHcmFkaWVudEVsZW1lbnQsIF9HcmFkaWVudEVsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkcChMaW5lYXJHcmFkaWVudEVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIExpbmVhckdyYWRpZW50RWxlbWVudChkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcykge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgTGluZWFyR3JhZGllbnRFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpO1xuICAgIF90aGlzLnR5cGUgPSAnbGluZWFyR3JhZGllbnQnO1xuXG4gICAgX3RoaXMuYXR0cmlidXRlc1RvSW5oZXJpdC5wdXNoKCd4MScsICd5MScsICd4MicsICd5MicpO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShMaW5lYXJHcmFkaWVudEVsZW1lbnQsIFt7XG4gICAga2V5OiBcImdldEdyYWRpZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEdyYWRpZW50KGN0eCwgZWxlbWVudCkge1xuICAgICAgdmFyIGlzQm91bmRpbmdCb3hVbml0cyA9IHRoaXMuZ2V0R3JhZGllbnRVbml0cygpID09PSAnb2JqZWN0Qm91bmRpbmdCb3gnO1xuICAgICAgdmFyIGJvdW5kaW5nQm94ID0gaXNCb3VuZGluZ0JveFVuaXRzID8gZWxlbWVudC5nZXRCb3VuZGluZ0JveChjdHgpIDogbnVsbDtcblxuICAgICAgaWYgKGlzQm91bmRpbmdCb3hVbml0cyAmJiAhYm91bmRpbmdCb3gpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5nZXRBdHRyaWJ1dGUoJ3gxJykuaGFzVmFsdWUoKSAmJiAhdGhpcy5nZXRBdHRyaWJ1dGUoJ3kxJykuaGFzVmFsdWUoKSAmJiAhdGhpcy5nZXRBdHRyaWJ1dGUoJ3gyJykuaGFzVmFsdWUoKSAmJiAhdGhpcy5nZXRBdHRyaWJ1dGUoJ3kyJykuaGFzVmFsdWUoKSkge1xuICAgICAgICB0aGlzLmdldEF0dHJpYnV0ZSgneDEnLCB0cnVlKS5zZXRWYWx1ZSgwKTtcbiAgICAgICAgdGhpcy5nZXRBdHRyaWJ1dGUoJ3kxJywgdHJ1ZSkuc2V0VmFsdWUoMCk7XG4gICAgICAgIHRoaXMuZ2V0QXR0cmlidXRlKCd4MicsIHRydWUpLnNldFZhbHVlKDEpO1xuICAgICAgICB0aGlzLmdldEF0dHJpYnV0ZSgneTInLCB0cnVlKS5zZXRWYWx1ZSgwKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHgxID0gaXNCb3VuZGluZ0JveFVuaXRzID8gYm91bmRpbmdCb3gueCArIGJvdW5kaW5nQm94LndpZHRoICogdGhpcy5nZXRBdHRyaWJ1dGUoJ3gxJykuZ2V0TnVtYmVyKCkgOiB0aGlzLmdldEF0dHJpYnV0ZSgneDEnKS5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgIHZhciB5MSA9IGlzQm91bmRpbmdCb3hVbml0cyA/IGJvdW5kaW5nQm94LnkgKyBib3VuZGluZ0JveC5oZWlnaHQgKiB0aGlzLmdldEF0dHJpYnV0ZSgneTEnKS5nZXROdW1iZXIoKSA6IHRoaXMuZ2V0QXR0cmlidXRlKCd5MScpLmdldFBpeGVscygneScpO1xuICAgICAgdmFyIHgyID0gaXNCb3VuZGluZ0JveFVuaXRzID8gYm91bmRpbmdCb3gueCArIGJvdW5kaW5nQm94LndpZHRoICogdGhpcy5nZXRBdHRyaWJ1dGUoJ3gyJykuZ2V0TnVtYmVyKCkgOiB0aGlzLmdldEF0dHJpYnV0ZSgneDInKS5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgIHZhciB5MiA9IGlzQm91bmRpbmdCb3hVbml0cyA/IGJvdW5kaW5nQm94LnkgKyBib3VuZGluZ0JveC5oZWlnaHQgKiB0aGlzLmdldEF0dHJpYnV0ZSgneTInKS5nZXROdW1iZXIoKSA6IHRoaXMuZ2V0QXR0cmlidXRlKCd5MicpLmdldFBpeGVscygneScpO1xuXG4gICAgICBpZiAoeDEgPT09IHgyICYmIHkxID09PSB5Mikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGN0eC5jcmVhdGVMaW5lYXJHcmFkaWVudCh4MSwgeTEsIHgyLCB5Mik7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIExpbmVhckdyYWRpZW50RWxlbWVudDtcbn0oR3JhZGllbnRFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJG8oRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkbygpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkbygpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBSYWRpYWxHcmFkaWVudEVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9HcmFkaWVudEVsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShSYWRpYWxHcmFkaWVudEVsZW1lbnQsIF9HcmFkaWVudEVsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkbyhSYWRpYWxHcmFkaWVudEVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIFJhZGlhbEdyYWRpZW50RWxlbWVudChkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcykge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgUmFkaWFsR3JhZGllbnRFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpO1xuICAgIF90aGlzLnR5cGUgPSAncmFkaWFsR3JhZGllbnQnO1xuXG4gICAgX3RoaXMuYXR0cmlidXRlc1RvSW5oZXJpdC5wdXNoKCdjeCcsICdjeScsICdyJywgJ2Z4JywgJ2Z5JywgJ2ZyJyk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFJhZGlhbEdyYWRpZW50RWxlbWVudCwgW3tcbiAgICBrZXk6IFwiZ2V0R3JhZGllbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0R3JhZGllbnQoY3R4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgaXNCb3VuZGluZ0JveFVuaXRzID0gdGhpcy5nZXRHcmFkaWVudFVuaXRzKCkgPT09ICdvYmplY3RCb3VuZGluZ0JveCc7XG4gICAgICB2YXIgYm91bmRpbmdCb3ggPSBlbGVtZW50LmdldEJvdW5kaW5nQm94KGN0eCk7XG5cbiAgICAgIGlmIChpc0JvdW5kaW5nQm94VW5pdHMgJiYgIWJvdW5kaW5nQm94KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuZ2V0QXR0cmlidXRlKCdjeCcpLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgdGhpcy5nZXRBdHRyaWJ1dGUoJ2N4JywgdHJ1ZSkuc2V0VmFsdWUoJzUwJScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuZ2V0QXR0cmlidXRlKCdjeScpLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgdGhpcy5nZXRBdHRyaWJ1dGUoJ2N5JywgdHJ1ZSkuc2V0VmFsdWUoJzUwJScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuZ2V0QXR0cmlidXRlKCdyJykuaGFzVmFsdWUoKSkge1xuICAgICAgICB0aGlzLmdldEF0dHJpYnV0ZSgncicsIHRydWUpLnNldFZhbHVlKCc1MCUnKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGN4ID0gaXNCb3VuZGluZ0JveFVuaXRzID8gYm91bmRpbmdCb3gueCArIGJvdW5kaW5nQm94LndpZHRoICogdGhpcy5nZXRBdHRyaWJ1dGUoJ2N4JykuZ2V0TnVtYmVyKCkgOiB0aGlzLmdldEF0dHJpYnV0ZSgnY3gnKS5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgIHZhciBjeSA9IGlzQm91bmRpbmdCb3hVbml0cyA/IGJvdW5kaW5nQm94LnkgKyBib3VuZGluZ0JveC5oZWlnaHQgKiB0aGlzLmdldEF0dHJpYnV0ZSgnY3knKS5nZXROdW1iZXIoKSA6IHRoaXMuZ2V0QXR0cmlidXRlKCdjeScpLmdldFBpeGVscygneScpO1xuICAgICAgdmFyIGZ4ID0gY3g7XG4gICAgICB2YXIgZnkgPSBjeTtcblxuICAgICAgaWYgKHRoaXMuZ2V0QXR0cmlidXRlKCdmeCcpLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgZnggPSBpc0JvdW5kaW5nQm94VW5pdHMgPyBib3VuZGluZ0JveC54ICsgYm91bmRpbmdCb3gud2lkdGggKiB0aGlzLmdldEF0dHJpYnV0ZSgnZngnKS5nZXROdW1iZXIoKSA6IHRoaXMuZ2V0QXR0cmlidXRlKCdmeCcpLmdldFBpeGVscygneCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5nZXRBdHRyaWJ1dGUoJ2Z5JykuaGFzVmFsdWUoKSkge1xuICAgICAgICBmeSA9IGlzQm91bmRpbmdCb3hVbml0cyA/IGJvdW5kaW5nQm94LnkgKyBib3VuZGluZ0JveC5oZWlnaHQgKiB0aGlzLmdldEF0dHJpYnV0ZSgnZnknKS5nZXROdW1iZXIoKSA6IHRoaXMuZ2V0QXR0cmlidXRlKCdmeScpLmdldFBpeGVscygneScpO1xuICAgICAgfVxuXG4gICAgICB2YXIgciA9IGlzQm91bmRpbmdCb3hVbml0cyA/IChib3VuZGluZ0JveC53aWR0aCArIGJvdW5kaW5nQm94LmhlaWdodCkgLyAyLjAgKiB0aGlzLmdldEF0dHJpYnV0ZSgncicpLmdldE51bWJlcigpIDogdGhpcy5nZXRBdHRyaWJ1dGUoJ3InKS5nZXRQaXhlbHMoKTtcbiAgICAgIHZhciBmciA9IHRoaXMuZ2V0QXR0cmlidXRlKCdmcicpLmdldFBpeGVscygpO1xuICAgICAgcmV0dXJuIGN0eC5jcmVhdGVSYWRpYWxHcmFkaWVudChmeCwgZnksIGZyLCBjeCwgY3ksIHIpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBSYWRpYWxHcmFkaWVudEVsZW1lbnQ7XG59KEdyYWRpZW50RWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRuKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JG4oKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JG4oKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgU3RvcEVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9FbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oU3RvcEVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJG4oU3RvcEVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIFN0b3BFbGVtZW50KGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBTdG9wRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcbiAgICBfdGhpcy50eXBlID0gJ3N0b3AnO1xuICAgIHZhciBvZmZzZXQgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBfdGhpcy5nZXRBdHRyaWJ1dGUoJ29mZnNldCcpLmdldE51bWJlcigpKSk7XG5cbiAgICB2YXIgc3RvcE9wYWNpdHkgPSBfdGhpcy5nZXRTdHlsZSgnc3RvcC1vcGFjaXR5Jyk7XG5cbiAgICB2YXIgc3RvcENvbG9yID0gX3RoaXMuZ2V0U3R5bGUoJ3N0b3AtY29sb3InLCB0cnVlKTtcblxuICAgIGlmIChzdG9wQ29sb3IuZ2V0U3RyaW5nKCkgPT09ICcnKSB7XG4gICAgICBzdG9wQ29sb3Iuc2V0VmFsdWUoJyMwMDAnKTtcbiAgICB9XG5cbiAgICBpZiAoc3RvcE9wYWNpdHkuaGFzVmFsdWUoKSkge1xuICAgICAgc3RvcENvbG9yID0gc3RvcENvbG9yLmFkZE9wYWNpdHkoc3RvcE9wYWNpdHkpO1xuICAgIH1cblxuICAgIF90aGlzLm9mZnNldCA9IG9mZnNldDtcbiAgICBfdGhpcy5jb2xvciA9IHN0b3BDb2xvci5nZXRDb2xvcigpO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIHJldHVybiBTdG9wRWxlbWVudDtcbn0oRWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRtKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JG0oKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JG0oKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgQW5pbWF0ZUVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9FbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oQW5pbWF0ZUVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJG0oQW5pbWF0ZUVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIEFuaW1hdGVFbGVtZW50KGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBBbmltYXRlRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcbiAgICBfdGhpcy50eXBlID0gJ2FuaW1hdGUnO1xuICAgIF90aGlzLmR1cmF0aW9uID0gMDtcbiAgICBfdGhpcy5pbml0aWFsVmFsdWUgPSBudWxsO1xuICAgIF90aGlzLmluaXRpYWxVbml0cyA9ICcnO1xuICAgIF90aGlzLnJlbW92ZWQgPSBmYWxzZTtcbiAgICBfdGhpcy5mcm96ZW4gPSBmYWxzZTtcbiAgICBkb2N1bWVudC5zY3JlZW4uYW5pbWF0aW9ucy5wdXNoKF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF90aGlzKSk7XG4gICAgX3RoaXMuYmVnaW4gPSBfdGhpcy5nZXRBdHRyaWJ1dGUoJ2JlZ2luJykuZ2V0TWlsbGlzZWNvbmRzKCk7XG4gICAgX3RoaXMubWF4RHVyYXRpb24gPSBfdGhpcy5iZWdpbiArIF90aGlzLmdldEF0dHJpYnV0ZSgnZHVyJykuZ2V0TWlsbGlzZWNvbmRzKCk7XG4gICAgX3RoaXMuZnJvbSA9IF90aGlzLmdldEF0dHJpYnV0ZSgnZnJvbScpO1xuICAgIF90aGlzLnRvID0gX3RoaXMuZ2V0QXR0cmlidXRlKCd0bycpO1xuICAgIF90aGlzLnZhbHVlcyA9IG5ldyBQcm9wZXJ0eShkb2N1bWVudCwgJ3ZhbHVlcycsIG51bGwpO1xuXG4gICAgdmFyIHZhbHVlc0F0dHIgPSBfdGhpcy5nZXRBdHRyaWJ1dGUoJ3ZhbHVlcycpO1xuXG4gICAgaWYgKHZhbHVlc0F0dHIuaGFzVmFsdWUoKSkge1xuICAgICAgX3RoaXMudmFsdWVzLnNldFZhbHVlKHZhbHVlc0F0dHIuZ2V0U3RyaW5nKCkuc3BsaXQoJzsnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShBbmltYXRlRWxlbWVudCwgW3tcbiAgICBrZXk6IFwiZ2V0UHJvcGVydHlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UHJvcGVydHkoKSB7XG4gICAgICB2YXIgYXR0cmlidXRlVHlwZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCdhdHRyaWJ1dGVUeXBlJykuZ2V0U3RyaW5nKCk7XG4gICAgICB2YXIgYXR0cmlidXRlTmFtZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCdhdHRyaWJ1dGVOYW1lJykuZ2V0U3RyaW5nKCk7XG5cbiAgICAgIGlmIChhdHRyaWJ1dGVUeXBlID09PSAnQ1NTJykge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuZ2V0U3R5bGUoYXR0cmlidXRlTmFtZSwgdHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnBhcmVudC5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSwgdHJ1ZSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNhbGNWYWx1ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjYWxjVmFsdWUoKSB7XG4gICAgICB2YXIgaW5pdGlhbFVuaXRzID0gdGhpcy5pbml0aWFsVW5pdHM7XG5cbiAgICAgIHZhciBfdGhpcyRnZXRQcm9ncmVzcyA9IHRoaXMuZ2V0UHJvZ3Jlc3MoKSxcbiAgICAgICAgICBwcm9ncmVzcyA9IF90aGlzJGdldFByb2dyZXNzLnByb2dyZXNzLFxuICAgICAgICAgIGZyb20gPSBfdGhpcyRnZXRQcm9ncmVzcy5mcm9tLFxuICAgICAgICAgIHRvID0gX3RoaXMkZ2V0UHJvZ3Jlc3MudG87IC8vIHR3ZWVuIHZhbHVlIGxpbmVhcmx5XG5cblxuICAgICAgdmFyIG5ld1ZhbHVlID0gZnJvbS5nZXROdW1iZXIoKSArICh0by5nZXROdW1iZXIoKSAtIGZyb20uZ2V0TnVtYmVyKCkpICogcHJvZ3Jlc3M7XG5cbiAgICAgIGlmIChpbml0aWFsVW5pdHMgPT09ICclJykge1xuICAgICAgICBuZXdWYWx1ZSAqPSAxMDAuMDsgLy8gbnVtVmFsdWUoKSByZXR1cm5zIDAtMSB3aGVyZWFzIHByb3BlcnRpZXMgYXJlIDAtMTAwXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBcIlwiLmNvbmNhdChuZXdWYWx1ZSkuY29uY2F0KGluaXRpYWxVbml0cyk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInVwZGF0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiB1cGRhdGUoZGVsdGEpIHtcbiAgICAgIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudDtcbiAgICAgIHZhciBwcm9wID0gdGhpcy5nZXRQcm9wZXJ0eSgpOyAvLyBzZXQgaW5pdGlhbCB2YWx1ZVxuXG4gICAgICBpZiAoIXRoaXMuaW5pdGlhbFZhbHVlKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbFZhbHVlID0gcHJvcC5nZXRTdHJpbmcoKTtcbiAgICAgICAgdGhpcy5pbml0aWFsVW5pdHMgPSBwcm9wLmdldFVuaXRzKCk7XG4gICAgICB9IC8vIGlmIHdlJ3JlIHBhc3QgdGhlIGVuZCB0aW1lXG5cblxuICAgICAgaWYgKHRoaXMuZHVyYXRpb24gPiB0aGlzLm1heER1cmF0aW9uKSB7XG4gICAgICAgIHZhciBmaWxsID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2ZpbGwnKS5nZXRTdHJpbmcoJ3JlbW92ZScpOyAvLyBsb29wIGZvciBpbmRlZmluaXRlbHkgcmVwZWF0aW5nIGFuaW1hdGlvbnNcblxuICAgICAgICBpZiAodGhpcy5nZXRBdHRyaWJ1dGUoJ3JlcGVhdENvdW50JykuZ2V0U3RyaW5nKCkgPT09ICdpbmRlZmluaXRlJyB8fCB0aGlzLmdldEF0dHJpYnV0ZSgncmVwZWF0RHVyJykuZ2V0U3RyaW5nKCkgPT09ICdpbmRlZmluaXRlJykge1xuICAgICAgICAgIHRoaXMuZHVyYXRpb24gPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGZpbGwgPT09ICdmcmVlemUnICYmICF0aGlzLmZyb3plbikge1xuICAgICAgICAgIHRoaXMuZnJvemVuID0gdHJ1ZTtcbiAgICAgICAgICBwYXJlbnQuYW5pbWF0aW9uRnJvemVuID0gdHJ1ZTtcbiAgICAgICAgICBwYXJlbnQuYW5pbWF0aW9uRnJvemVuVmFsdWUgPSBwcm9wLmdldFN0cmluZygpO1xuICAgICAgICB9IGVsc2UgaWYgKGZpbGwgPT09ICdyZW1vdmUnICYmICF0aGlzLnJlbW92ZWQpIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZWQgPSB0cnVlO1xuICAgICAgICAgIHByb3Auc2V0VmFsdWUocGFyZW50LmFuaW1hdGlvbkZyb3plbiA/IHBhcmVudC5hbmltYXRpb25Gcm96ZW5WYWx1ZSA6IHRoaXMuaW5pdGlhbFZhbHVlKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5kdXJhdGlvbiArPSBkZWx0YTsgLy8gaWYgd2UncmUgcGFzdCB0aGUgYmVnaW4gdGltZVxuXG4gICAgICB2YXIgdXBkYXRlZCA9IGZhbHNlO1xuXG4gICAgICBpZiAodGhpcy5iZWdpbiA8IHRoaXMuZHVyYXRpb24pIHtcbiAgICAgICAgdmFyIG5ld1ZhbHVlID0gdGhpcy5jYWxjVmFsdWUoKTsgLy8gdHdlZW5cblxuICAgICAgICB2YXIgdHlwZUF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZSgndHlwZScpO1xuXG4gICAgICAgIGlmICh0eXBlQXR0ci5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgLy8gZm9yIHRyYW5zZm9ybSwgZXRjLlxuICAgICAgICAgIHZhciB0eXBlID0gdHlwZUF0dHIuZ2V0U3RyaW5nKCk7XG4gICAgICAgICAgbmV3VmFsdWUgPSBcIlwiLmNvbmNhdCh0eXBlLCBcIihcIikuY29uY2F0KG5ld1ZhbHVlLCBcIilcIik7XG4gICAgICAgIH1cblxuICAgICAgICBwcm9wLnNldFZhbHVlKG5ld1ZhbHVlKTtcbiAgICAgICAgdXBkYXRlZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB1cGRhdGVkO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRQcm9ncmVzc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRQcm9ncmVzcygpIHtcbiAgICAgIHZhciBkb2N1bWVudCA9IHRoaXMuZG9jdW1lbnQsXG4gICAgICAgICAgdmFsdWVzID0gdGhpcy52YWx1ZXM7XG4gICAgICB2YXIgcmVzdWx0ID0ge1xuICAgICAgICBwcm9ncmVzczogKHRoaXMuZHVyYXRpb24gLSB0aGlzLmJlZ2luKSAvICh0aGlzLm1heER1cmF0aW9uIC0gdGhpcy5iZWdpbilcbiAgICAgIH07XG5cbiAgICAgIGlmICh2YWx1ZXMuaGFzVmFsdWUoKSkge1xuICAgICAgICB2YXIgcCA9IHJlc3VsdC5wcm9ncmVzcyAqICh2YWx1ZXMuZ2V0VmFsdWUoKS5sZW5ndGggLSAxKTtcbiAgICAgICAgdmFyIGxiID0gTWF0aC5mbG9vcihwKTtcbiAgICAgICAgdmFyIHViID0gTWF0aC5jZWlsKHApO1xuICAgICAgICByZXN1bHQuZnJvbSA9IG5ldyBQcm9wZXJ0eShkb2N1bWVudCwgJ2Zyb20nLCBwYXJzZUZsb2F0KHZhbHVlcy5nZXRWYWx1ZSgpW2xiXSkpO1xuICAgICAgICByZXN1bHQudG8gPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICd0bycsIHBhcnNlRmxvYXQodmFsdWVzLmdldFZhbHVlKClbdWJdKSk7XG4gICAgICAgIHJlc3VsdC5wcm9ncmVzcyA9IChwIC0gbGIpIC8gKHViIC0gbGIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0LmZyb20gPSB0aGlzLmZyb207XG4gICAgICAgIHJlc3VsdC50byA9IHRoaXMudG87XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIEFuaW1hdGVFbGVtZW50O1xufShFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJGwoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkbCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkbCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBBbmltYXRlQ29sb3JFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfQW5pbWF0ZUVsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShBbmltYXRlQ29sb3JFbGVtZW50LCBfQW5pbWF0ZUVsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkbChBbmltYXRlQ29sb3JFbGVtZW50KTtcblxuICBmdW5jdGlvbiBBbmltYXRlQ29sb3JFbGVtZW50KCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgQW5pbWF0ZUNvbG9yRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF90aGlzLnR5cGUgPSAnYW5pbWF0ZUNvbG9yJztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEFuaW1hdGVDb2xvckVsZW1lbnQsIFt7XG4gICAga2V5OiBcImNhbGNWYWx1ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjYWxjVmFsdWUoKSB7XG4gICAgICB2YXIgX3RoaXMkZ2V0UHJvZ3Jlc3MgPSB0aGlzLmdldFByb2dyZXNzKCksXG4gICAgICAgICAgcHJvZ3Jlc3MgPSBfdGhpcyRnZXRQcm9ncmVzcy5wcm9ncmVzcyxcbiAgICAgICAgICBmcm9tID0gX3RoaXMkZ2V0UHJvZ3Jlc3MuZnJvbSxcbiAgICAgICAgICB0byA9IF90aGlzJGdldFByb2dyZXNzLnRvO1xuXG4gICAgICB2YXIgY29sb3JGcm9tID0gbmV3IFJHQkNvbG9yX19kZWZhdWx0W1wiZGVmYXVsdFwiXShmcm9tLmdldENvbG9yKCkpO1xuICAgICAgdmFyIGNvbG9yVG8gPSBuZXcgUkdCQ29sb3JfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRvLmdldENvbG9yKCkpO1xuXG4gICAgICBpZiAoY29sb3JGcm9tLm9rICYmIGNvbG9yVG8ub2spIHtcbiAgICAgICAgLy8gdHdlZW4gY29sb3IgbGluZWFybHlcbiAgICAgICAgdmFyIHIgPSBjb2xvckZyb20uciArIChjb2xvclRvLnIgLSBjb2xvckZyb20ucikgKiBwcm9ncmVzcztcbiAgICAgICAgdmFyIGcgPSBjb2xvckZyb20uZyArIChjb2xvclRvLmcgLSBjb2xvckZyb20uZykgKiBwcm9ncmVzcztcbiAgICAgICAgdmFyIGIgPSBjb2xvckZyb20uYiArIChjb2xvclRvLmIgLSBjb2xvckZyb20uYikgKiBwcm9ncmVzczsgLy8gPyBhbHBoYVxuXG4gICAgICAgIHJldHVybiBcInJnYihcIi5jb25jYXQoTWF0aC5mbG9vcihyKSwgXCIsIFwiKS5jb25jYXQoTWF0aC5mbG9vcihnKSwgXCIsIFwiKS5jb25jYXQoTWF0aC5mbG9vcihiKSwgXCIpXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoJ2Zyb20nKS5nZXRDb2xvcigpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBBbmltYXRlQ29sb3JFbGVtZW50O1xufShBbmltYXRlRWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRrKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGsoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGsoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9BbmltYXRlRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEFuaW1hdGVUcmFuc2Zvcm1FbGVtZW50LCBfQW5pbWF0ZUVsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkayhBbmltYXRlVHJhbnNmb3JtRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBBbmltYXRlVHJhbnNmb3JtRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF90aGlzLnR5cGUgPSAnYW5pbWF0ZVRyYW5zZm9ybSc7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShBbmltYXRlVHJhbnNmb3JtRWxlbWVudCwgW3tcbiAgICBrZXk6IFwiY2FsY1ZhbHVlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNhbGNWYWx1ZSgpIHtcbiAgICAgIHZhciBfdGhpcyRnZXRQcm9ncmVzcyA9IHRoaXMuZ2V0UHJvZ3Jlc3MoKSxcbiAgICAgICAgICBwcm9ncmVzcyA9IF90aGlzJGdldFByb2dyZXNzLnByb2dyZXNzLFxuICAgICAgICAgIGZyb20gPSBfdGhpcyRnZXRQcm9ncmVzcy5mcm9tLFxuICAgICAgICAgIHRvID0gX3RoaXMkZ2V0UHJvZ3Jlc3MudG87IC8vIHR3ZWVuIHZhbHVlIGxpbmVhcmx5XG5cblxuICAgICAgdmFyIHRyYW5zZm9ybUZyb20gPSB0b051bWJlcnMoZnJvbS5nZXRTdHJpbmcoKSk7XG4gICAgICB2YXIgdHJhbnNmb3JtVG8gPSB0b051bWJlcnModG8uZ2V0U3RyaW5nKCkpO1xuICAgICAgdmFyIG5ld1ZhbHVlID0gdHJhbnNmb3JtRnJvbS5tYXAoZnVuY3Rpb24gKGZyb20sIGkpIHtcbiAgICAgICAgdmFyIHRvID0gdHJhbnNmb3JtVG9baV07XG4gICAgICAgIHJldHVybiBmcm9tICsgKHRvIC0gZnJvbSkgKiBwcm9ncmVzcztcbiAgICAgIH0pLmpvaW4oJyAnKTtcbiAgICAgIHJldHVybiBuZXdWYWx1ZTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ7XG59KEFuaW1hdGVFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIkMShvLCBhbGxvd0FycmF5TGlrZSkgeyB2YXIgaXQgPSB0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXSB8fCBvW1wiQEBpdGVyYXRvclwiXTsgaWYgKCFpdCkgeyBpZiAoQXJyYXkuaXNBcnJheShvKSB8fCAoaXQgPSBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkkMShvKSkgfHwgYWxsb3dBcnJheUxpa2UgJiYgbyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHsgaWYgKGl0KSBvID0gaXQ7IHZhciBpID0gMDsgdmFyIEYgPSBmdW5jdGlvbiBGKCkge307IHJldHVybiB7IHM6IEYsIG46IGZ1bmN0aW9uIG4oKSB7IGlmIChpID49IG8ubGVuZ3RoKSByZXR1cm4geyBkb25lOiB0cnVlIH07IHJldHVybiB7IGRvbmU6IGZhbHNlLCB2YWx1ZTogb1tpKytdIH07IH0sIGU6IGZ1bmN0aW9uIGUoX2UpIHsgdGhyb3cgX2U7IH0sIGY6IEYgfTsgfSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGl0ZXJhdGUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7IH0gdmFyIG5vcm1hbENvbXBsZXRpb24gPSB0cnVlLCBkaWRFcnIgPSBmYWxzZSwgZXJyOyByZXR1cm4geyBzOiBmdW5jdGlvbiBzKCkgeyBpdCA9IGl0LmNhbGwobyk7IH0sIG46IGZ1bmN0aW9uIG4oKSB7IHZhciBzdGVwID0gaXQubmV4dCgpOyBub3JtYWxDb21wbGV0aW9uID0gc3RlcC5kb25lOyByZXR1cm4gc3RlcDsgfSwgZTogZnVuY3Rpb24gZShfZTIpIHsgZGlkRXJyID0gdHJ1ZTsgZXJyID0gX2UyOyB9LCBmOiBmdW5jdGlvbiBmKCkgeyB0cnkgeyBpZiAoIW5vcm1hbENvbXBsZXRpb24gJiYgaXQucmV0dXJuICE9IG51bGwpIGl0LnJldHVybigpOyB9IGZpbmFsbHkgeyBpZiAoZGlkRXJyKSB0aHJvdyBlcnI7IH0gfSB9OyB9XG5cbmZ1bmN0aW9uIF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSQxKG8sIG1pbkxlbikgeyBpZiAoIW8pIHJldHVybjsgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkkMShvLCBtaW5MZW4pOyB2YXIgbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSk7IGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7IGlmIChuID09PSBcIk1hcFwiIHx8IG4gPT09IFwiU2V0XCIpIHJldHVybiBBcnJheS5mcm9tKG8pOyBpZiAobiA9PT0gXCJBcmd1bWVudHNcIiB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChuKSkgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5JDEobywgbWluTGVuKTsgfVxuXG5mdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheSQxKGFyciwgbGVuKSB7IGlmIChsZW4gPT0gbnVsbCB8fCBsZW4gPiBhcnIubGVuZ3RoKSBsZW4gPSBhcnIubGVuZ3RoOyBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShsZW4pOyBpIDwgbGVuOyBpKyspIHsgYXJyMltpXSA9IGFycltpXTsgfSByZXR1cm4gYXJyMjsgfVxuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkaihEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRqKCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRqKCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIEZvbnRFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEZvbnRFbGVtZW50LCBfRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciRqKEZvbnRFbGVtZW50KTtcblxuICBmdW5jdGlvbiBGb250RWxlbWVudChkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcykge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgRm9udEVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcyk7XG4gICAgX3RoaXMudHlwZSA9ICdmb250JztcbiAgICBfdGhpcy5nbHlwaHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIF90aGlzLmhvcml6QWR2WCA9IF90aGlzLmdldEF0dHJpYnV0ZSgnaG9yaXotYWR2LXgnKS5nZXROdW1iZXIoKTtcbiAgICB2YXIgZGVmaW5pdGlvbnMgPSBkb2N1bWVudC5kZWZpbml0aW9ucztcblxuICAgIHZhciBfYXNzZXJ0VGhpc0luaXRpYWxpemUgPSBfYXNzZXJ0VGhpc0luaXRpYWxpemVkX19kZWZhdWx0W1wiZGVmYXVsdFwiXShfdGhpcyksXG4gICAgICAgIGNoaWxkcmVuID0gX2Fzc2VydFRoaXNJbml0aWFsaXplLmNoaWxkcmVuO1xuXG4gICAgdmFyIF9pdGVyYXRvciA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyJDEoY2hpbGRyZW4pLFxuICAgICAgICBfc3RlcDtcblxuICAgIHRyeSB7XG4gICAgICBmb3IgKF9pdGVyYXRvci5zKCk7ICEoX3N0ZXAgPSBfaXRlcmF0b3IubigpKS5kb25lOykge1xuICAgICAgICB2YXIgY2hpbGQgPSBfc3RlcC52YWx1ZTtcblxuICAgICAgICBzd2l0Y2ggKGNoaWxkLnR5cGUpIHtcbiAgICAgICAgICBjYXNlICdmb250LWZhY2UnOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBfdGhpcy5mb250RmFjZSA9IGNoaWxkO1xuICAgICAgICAgICAgICB2YXIgZm9udEZhbWlseVN0eWxlID0gY2hpbGQuZ2V0U3R5bGUoJ2ZvbnQtZmFtaWx5Jyk7XG5cbiAgICAgICAgICAgICAgaWYgKGZvbnRGYW1pbHlTdHlsZS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgZGVmaW5pdGlvbnNbZm9udEZhbWlseVN0eWxlLmdldFN0cmluZygpXSA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF90aGlzKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSAnbWlzc2luZy1nbHlwaCc6XG4gICAgICAgICAgICBfdGhpcy5taXNzaW5nR2x5cGggPSBjaGlsZDtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSAnZ2x5cGgnOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB2YXIgZ2x5cGggPSBjaGlsZDtcblxuICAgICAgICAgICAgICBpZiAoZ2x5cGguYXJhYmljRm9ybSkge1xuICAgICAgICAgICAgICAgIF90aGlzLmlzUlRMID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBfdGhpcy5pc0FyYWJpYyA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIF90aGlzLmdseXBoc1tnbHlwaC51bmljb2RlXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgIF90aGlzLmdseXBoc1tnbHlwaC51bmljb2RlXSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2x5cGhzW2dseXBoLnVuaWNvZGVdW2dseXBoLmFyYWJpY0Zvcm1dID0gZ2x5cGg7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuZ2x5cGhzW2dseXBoLnVuaWNvZGVdID0gZ2x5cGg7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIF9pdGVyYXRvci5lKGVycik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIF9pdGVyYXRvci5mKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShGb250RWxlbWVudCwgW3tcbiAgICBrZXk6IFwicmVuZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHsvLyBOTyBSRU5ERVJcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gRm9udEVsZW1lbnQ7XG59KEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkaShEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRpKCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRpKCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIEZvbnRGYWNlRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX0VsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShGb250RmFjZUVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJGkoRm9udEZhY2VFbGVtZW50KTtcblxuICBmdW5jdGlvbiBGb250RmFjZUVsZW1lbnQoZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIEZvbnRGYWNlRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcbiAgICBfdGhpcy50eXBlID0gJ2ZvbnQtZmFjZSc7XG4gICAgX3RoaXMuYXNjZW50ID0gX3RoaXMuZ2V0QXR0cmlidXRlKCdhc2NlbnQnKS5nZXROdW1iZXIoKTtcbiAgICBfdGhpcy5kZXNjZW50ID0gX3RoaXMuZ2V0QXR0cmlidXRlKCdkZXNjZW50JykuZ2V0TnVtYmVyKCk7XG4gICAgX3RoaXMudW5pdHNQZXJFbSA9IF90aGlzLmdldEF0dHJpYnV0ZSgndW5pdHMtcGVyLWVtJykuZ2V0TnVtYmVyKCk7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIEZvbnRGYWNlRWxlbWVudDtcbn0oRWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRoKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGgoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGgoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgTWlzc2luZ0dseXBoRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1BhdGhFbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oTWlzc2luZ0dseXBoRWxlbWVudCwgX1BhdGhFbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJGgoTWlzc2luZ0dseXBoRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gTWlzc2luZ0dseXBoRWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIE1pc3NpbmdHbHlwaEVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfdGhpcy50eXBlID0gJ21pc3NpbmctZ2x5cGgnO1xuICAgIF90aGlzLmhvcml6QWR2WCA9IDA7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIE1pc3NpbmdHbHlwaEVsZW1lbnQ7XG59KFBhdGhFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJGcoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkZygpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkZygpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBUUmVmRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1RleHRFbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oVFJlZkVsZW1lbnQsIF9UZXh0RWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciRnKFRSZWZFbGVtZW50KTtcblxuICBmdW5jdGlvbiBUUmVmRWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFRSZWZFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgX3RoaXMudHlwZSA9ICd0cmVmJztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFRSZWZFbGVtZW50LCBbe1xuICAgIGtleTogXCJnZXRUZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFRleHQoKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IHRoaXMuZ2V0SHJlZkF0dHJpYnV0ZSgpLmdldERlZmluaXRpb24oKTtcblxuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIGZpcnN0Q2hpbGQgPSBlbGVtZW50LmNoaWxkcmVuWzBdO1xuXG4gICAgICAgIGlmIChmaXJzdENoaWxkKSB7XG4gICAgICAgICAgcmV0dXJuIGZpcnN0Q2hpbGQuZ2V0VGV4dCgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gVFJlZkVsZW1lbnQ7XG59KFRleHRFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJGYoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkZigpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkZigpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBBRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1RleHRFbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oQUVsZW1lbnQsIF9UZXh0RWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciRmKEFFbGVtZW50KTtcblxuICBmdW5jdGlvbiBBRWxlbWVudChkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcykge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgQUVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcyk7XG4gICAgX3RoaXMudHlwZSA9ICdhJztcbiAgICB2YXIgY2hpbGROb2RlcyA9IG5vZGUuY2hpbGROb2RlcztcbiAgICB2YXIgZmlyc3RDaGlsZCA9IGNoaWxkTm9kZXNbMF07XG4gICAgdmFyIGhhc1RleHQgPSBjaGlsZE5vZGVzLmxlbmd0aCA+IDAgJiYgQXJyYXkuZnJvbShjaGlsZE5vZGVzKS5ldmVyeShmdW5jdGlvbiAobm9kZSkge1xuICAgICAgcmV0dXJuIG5vZGUubm9kZVR5cGUgPT09IDM7XG4gICAgfSk7XG4gICAgX3RoaXMuaGFzVGV4dCA9IGhhc1RleHQ7XG4gICAgX3RoaXMudGV4dCA9IGhhc1RleHQgPyBfdGhpcy5nZXRUZXh0RnJvbU5vZGUoZmlyc3RDaGlsZCkgOiAnJztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEFFbGVtZW50LCBbe1xuICAgIGtleTogXCJnZXRUZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFRleHQoKSB7XG4gICAgICByZXR1cm4gdGhpcy50ZXh0O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJDaGlsZHJlblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXJDaGlsZHJlbihjdHgpIHtcbiAgICAgIGlmICh0aGlzLmhhc1RleHQpIHtcbiAgICAgICAgLy8gcmVuZGVyIGFzIHRleHQgZWxlbWVudFxuICAgICAgICBfZ2V0X19kZWZhdWx0W1wiZGVmYXVsdFwiXShfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEFFbGVtZW50LnByb3RvdHlwZSksIFwicmVuZGVyQ2hpbGRyZW5cIiwgdGhpcykuY2FsbCh0aGlzLCBjdHgpO1xuXG4gICAgICAgIHZhciBkb2N1bWVudCA9IHRoaXMuZG9jdW1lbnQsXG4gICAgICAgICAgICB4ID0gdGhpcy54LFxuICAgICAgICAgICAgeSA9IHRoaXMueTtcbiAgICAgICAgdmFyIG1vdXNlID0gZG9jdW1lbnQuc2NyZWVuLm1vdXNlO1xuICAgICAgICB2YXIgZm9udFNpemUgPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICdmb250U2l6ZScsIEZvbnQucGFyc2UoZG9jdW1lbnQuY3R4LmZvbnQpLmZvbnRTaXplKTsgLy8gRG8gbm90IGNhbGMgYm91bmRpbmcgYm94IGlmIG1vdXNlIGlzIG5vdCB3b3JraW5nLlxuXG4gICAgICAgIGlmIChtb3VzZS5pc1dvcmtpbmcoKSkge1xuICAgICAgICAgIG1vdXNlLmNoZWNrQm91bmRpbmdCb3godGhpcywgbmV3IEJvdW5kaW5nQm94KHgsIHkgLSBmb250U2l6ZS5nZXRQaXhlbHMoJ3knKSwgeCArIHRoaXMubWVhc3VyZVRleHQoY3R4KSwgeSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyByZW5kZXIgYXMgdGVtcG9yYXJ5IGdyb3VwXG4gICAgICAgIHZhciBnID0gbmV3IEdFbGVtZW50KHRoaXMuZG9jdW1lbnQsIG51bGwpO1xuICAgICAgICBnLmNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbjtcbiAgICAgICAgZy5wYXJlbnQgPSB0aGlzO1xuICAgICAgICBnLnJlbmRlcihjdHgpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJvbkNsaWNrXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG9uQ2xpY2soKSB7XG4gICAgICB2YXIgd2luZG93ID0gdGhpcy5kb2N1bWVudC53aW5kb3c7XG5cbiAgICAgIGlmICh3aW5kb3cpIHtcbiAgICAgICAgd2luZG93Lm9wZW4odGhpcy5nZXRIcmVmQXR0cmlidXRlKCkuZ2V0U3RyaW5nKCkpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJvbk1vdXNlTW92ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBvbk1vdXNlTW92ZSgpIHtcbiAgICAgIHZhciBjdHggPSB0aGlzLmRvY3VtZW50LmN0eDtcbiAgICAgIGN0eC5jYW52YXMuc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBBRWxlbWVudDtcbn0oVGV4dEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlcihvLCBhbGxvd0FycmF5TGlrZSkgeyB2YXIgaXQgPSB0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXSB8fCBvW1wiQEBpdGVyYXRvclwiXTsgaWYgKCFpdCkgeyBpZiAoQXJyYXkuaXNBcnJheShvKSB8fCAoaXQgPSBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobykpIHx8IGFsbG93QXJyYXlMaWtlICYmIG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSB7IGlmIChpdCkgbyA9IGl0OyB2YXIgaSA9IDA7IHZhciBGID0gZnVuY3Rpb24gRigpIHt9OyByZXR1cm4geyBzOiBGLCBuOiBmdW5jdGlvbiBuKCkgeyBpZiAoaSA+PSBvLmxlbmd0aCkgcmV0dXJuIHsgZG9uZTogdHJ1ZSB9OyByZXR1cm4geyBkb25lOiBmYWxzZSwgdmFsdWU6IG9baSsrXSB9OyB9LCBlOiBmdW5jdGlvbiBlKF9lKSB7IHRocm93IF9lOyB9LCBmOiBGIH07IH0gdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBpdGVyYXRlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpOyB9IHZhciBub3JtYWxDb21wbGV0aW9uID0gdHJ1ZSwgZGlkRXJyID0gZmFsc2UsIGVycjsgcmV0dXJuIHsgczogZnVuY3Rpb24gcygpIHsgaXQgPSBpdC5jYWxsKG8pOyB9LCBuOiBmdW5jdGlvbiBuKCkgeyB2YXIgc3RlcCA9IGl0Lm5leHQoKTsgbm9ybWFsQ29tcGxldGlvbiA9IHN0ZXAuZG9uZTsgcmV0dXJuIHN0ZXA7IH0sIGU6IGZ1bmN0aW9uIGUoX2UyKSB7IGRpZEVyciA9IHRydWU7IGVyciA9IF9lMjsgfSwgZjogZnVuY3Rpb24gZigpIHsgdHJ5IHsgaWYgKCFub3JtYWxDb21wbGV0aW9uICYmIGl0LnJldHVybiAhPSBudWxsKSBpdC5yZXR1cm4oKTsgfSBmaW5hbGx5IHsgaWYgKGRpZEVycikgdGhyb3cgZXJyOyB9IH0gfTsgfVxuXG5mdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobywgbWluTGVuKSB7IGlmICghbykgcmV0dXJuOyBpZiAodHlwZW9mIG8gPT09IFwic3RyaW5nXCIpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pOyB2YXIgbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSk7IGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7IGlmIChuID09PSBcIk1hcFwiIHx8IG4gPT09IFwiU2V0XCIpIHJldHVybiBBcnJheS5mcm9tKG8pOyBpZiAobiA9PT0gXCJBcmd1bWVudHNcIiB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChuKSkgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7IH1cblxuZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHsgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+IGFyci5sZW5ndGgpIGxlbiA9IGFyci5sZW5ndGg7IGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9XG5cbmZ1bmN0aW9uIG93bktleXMkMihvYmplY3QsIGVudW1lcmFibGVPbmx5KSB7IHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTsgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHsgdmFyIHN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iamVjdCk7IGlmIChlbnVtZXJhYmxlT25seSkgeyBzeW1ib2xzID0gc3ltYm9scy5maWx0ZXIoZnVuY3Rpb24gKHN5bSkgeyByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHN5bSkuZW51bWVyYWJsZTsgfSk7IH0ga2V5cy5wdXNoLmFwcGx5KGtleXMsIHN5bWJvbHMpOyB9IHJldHVybiBrZXlzOyB9XG5cbmZ1bmN0aW9uIF9vYmplY3RTcHJlYWQkMih0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXSAhPSBudWxsID8gYXJndW1lbnRzW2ldIDoge307IGlmIChpICUgMikgeyBvd25LZXlzJDIoT2JqZWN0KHNvdXJjZSksIHRydWUpLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBfZGVmaW5lUHJvcGVydHlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRhcmdldCwga2V5LCBzb3VyY2Vba2V5XSk7IH0pOyB9IGVsc2UgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc291cmNlKSk7IH0gZWxzZSB7IG93bktleXMkMihPYmplY3Qoc291cmNlKSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzb3VyY2UsIGtleSkpOyB9KTsgfSB9IHJldHVybiB0YXJnZXQ7IH1cblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJGUoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkZSgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkZSgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBUZXh0UGF0aEVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9UZXh0RWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFRleHRQYXRoRWxlbWVudCwgX1RleHRFbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJGUoVGV4dFBhdGhFbGVtZW50KTtcblxuICBmdW5jdGlvbiBUZXh0UGF0aEVsZW1lbnQoZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFRleHRQYXRoRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcbiAgICBfdGhpcy50eXBlID0gJ3RleHRQYXRoJztcbiAgICBfdGhpcy50ZXh0V2lkdGggPSAwO1xuICAgIF90aGlzLnRleHRIZWlnaHQgPSAwO1xuICAgIF90aGlzLnBhdGhMZW5ndGggPSAtMTtcbiAgICBfdGhpcy5nbHlwaEluZm8gPSBudWxsO1xuICAgIF90aGlzLmxldHRlclNwYWNpbmdDYWNoZSA9IFtdO1xuICAgIF90aGlzLm1lYXN1cmVzQ2FjaGUgPSBuZXcgTWFwKFtbJycsIDBdXSk7XG5cbiAgICB2YXIgcGF0aEVsZW1lbnQgPSBfdGhpcy5nZXRIcmVmQXR0cmlidXRlKCkuZ2V0RGVmaW5pdGlvbigpO1xuXG4gICAgX3RoaXMudGV4dCA9IF90aGlzLmdldFRleHRGcm9tTm9kZSgpO1xuICAgIF90aGlzLmRhdGFBcnJheSA9IF90aGlzLnBhcnNlUGF0aERhdGEocGF0aEVsZW1lbnQpO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oVGV4dFBhdGhFbGVtZW50LCBbe1xuICAgIGtleTogXCJnZXRUZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFRleHQoKSB7XG4gICAgICByZXR1cm4gdGhpcy50ZXh0O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXRoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGgoY3R4KSB7XG4gICAgICB2YXIgZGF0YUFycmF5ID0gdGhpcy5kYXRhQXJyYXk7XG5cbiAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgfVxuXG4gICAgICBkYXRhQXJyYXkuZm9yRWFjaChmdW5jdGlvbiAoX3JlZikge1xuICAgICAgICB2YXIgdHlwZSA9IF9yZWYudHlwZSxcbiAgICAgICAgICAgIHBvaW50cyA9IF9yZWYucG9pbnRzO1xuXG4gICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgIGNhc2UgUGF0aFBhcnNlci5MSU5FX1RPOlxuICAgICAgICAgICAgaWYgKGN0eCkge1xuICAgICAgICAgICAgICBjdHgubGluZVRvKHBvaW50c1swXSwgcG9pbnRzWzFdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuTU9WRV9UTzpcbiAgICAgICAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgICAgICAgY3R4Lm1vdmVUbyhwb2ludHNbMF0sIHBvaW50c1sxXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBQYXRoUGFyc2VyLkNVUlZFX1RPOlxuICAgICAgICAgICAgaWYgKGN0eCkge1xuICAgICAgICAgICAgICBjdHguYmV6aWVyQ3VydmVUbyhwb2ludHNbMF0sIHBvaW50c1sxXSwgcG9pbnRzWzJdLCBwb2ludHNbM10sIHBvaW50c1s0XSwgcG9pbnRzWzVdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuUVVBRF9UTzpcbiAgICAgICAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgICAgICAgY3R4LnF1YWRyYXRpY0N1cnZlVG8ocG9pbnRzWzBdLCBwb2ludHNbMV0sIHBvaW50c1syXSwgcG9pbnRzWzNdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuQVJDOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB2YXIgX3BvaW50cyA9IF9zbGljZWRUb0FycmF5X19kZWZhdWx0W1wiZGVmYXVsdFwiXShwb2ludHMsIDgpLFxuICAgICAgICAgICAgICAgICAgY3ggPSBfcG9pbnRzWzBdLFxuICAgICAgICAgICAgICAgICAgY3kgPSBfcG9pbnRzWzFdLFxuICAgICAgICAgICAgICAgICAgcnggPSBfcG9pbnRzWzJdLFxuICAgICAgICAgICAgICAgICAgcnkgPSBfcG9pbnRzWzNdLFxuICAgICAgICAgICAgICAgICAgdGhldGEgPSBfcG9pbnRzWzRdLFxuICAgICAgICAgICAgICAgICAgZFRoZXRhID0gX3BvaW50c1s1XSxcbiAgICAgICAgICAgICAgICAgIHBzaSA9IF9wb2ludHNbNl0sXG4gICAgICAgICAgICAgICAgICBmcyA9IF9wb2ludHNbN107XG5cbiAgICAgICAgICAgICAgdmFyIHIgPSByeCA+IHJ5ID8gcnggOiByeTtcbiAgICAgICAgICAgICAgdmFyIHNjYWxlWCA9IHJ4ID4gcnkgPyAxIDogcnggLyByeTtcbiAgICAgICAgICAgICAgdmFyIHNjYWxlWSA9IHJ4ID4gcnkgPyByeSAvIHJ4IDogMTtcblxuICAgICAgICAgICAgICBpZiAoY3R4KSB7XG4gICAgICAgICAgICAgICAgY3R4LnRyYW5zbGF0ZShjeCwgY3kpO1xuICAgICAgICAgICAgICAgIGN0eC5yb3RhdGUocHNpKTtcbiAgICAgICAgICAgICAgICBjdHguc2NhbGUoc2NhbGVYLCBzY2FsZVkpO1xuICAgICAgICAgICAgICAgIGN0eC5hcmMoMCwgMCwgciwgdGhldGEsIHRoZXRhICsgZFRoZXRhLCBCb29sZWFuKDEgLSBmcykpO1xuICAgICAgICAgICAgICAgIGN0eC5zY2FsZSgxIC8gc2NhbGVYLCAxIC8gc2NhbGVZKTtcbiAgICAgICAgICAgICAgICBjdHgucm90YXRlKC1wc2kpO1xuICAgICAgICAgICAgICAgIGN0eC50cmFuc2xhdGUoLWN4LCAtY3kpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuQ0xPU0VfUEFUSDpcbiAgICAgICAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlckNoaWxkcmVuXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlckNoaWxkcmVuKGN0eCkge1xuICAgICAgdGhpcy5zZXRUZXh0RGF0YShjdHgpO1xuICAgICAgY3R4LnNhdmUoKTtcbiAgICAgIHZhciB0ZXh0RGVjb3JhdGlvbiA9IHRoaXMucGFyZW50LmdldFN0eWxlKCd0ZXh0LWRlY29yYXRpb24nKS5nZXRTdHJpbmcoKTtcbiAgICAgIHZhciBmb250U2l6ZSA9IHRoaXMuZ2V0Rm9udFNpemUoKTtcbiAgICAgIHZhciBnbHlwaEluZm8gPSB0aGlzLmdseXBoSW5mbztcbiAgICAgIHZhciBmaWxsID0gY3R4LmZpbGxTdHlsZTtcblxuICAgICAgaWYgKHRleHREZWNvcmF0aW9uID09PSAndW5kZXJsaW5lJykge1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICB9XG5cbiAgICAgIGdseXBoSW5mby5mb3JFYWNoKGZ1bmN0aW9uIChnbHlwaCwgaSkge1xuICAgICAgICB2YXIgcDAgPSBnbHlwaC5wMCxcbiAgICAgICAgICAgIHAxID0gZ2x5cGgucDEsXG4gICAgICAgICAgICByb3RhdGlvbiA9IGdseXBoLnJvdGF0aW9uLFxuICAgICAgICAgICAgcGFydGlhbFRleHQgPSBnbHlwaC50ZXh0O1xuICAgICAgICBjdHguc2F2ZSgpO1xuICAgICAgICBjdHgudHJhbnNsYXRlKHAwLngsIHAwLnkpO1xuICAgICAgICBjdHgucm90YXRlKHJvdGF0aW9uKTtcblxuICAgICAgICBpZiAoY3R4LmZpbGxTdHlsZSkge1xuICAgICAgICAgIGN0eC5maWxsVGV4dChwYXJ0aWFsVGV4dCwgMCwgMCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3R4LnN0cm9rZVN0eWxlKSB7XG4gICAgICAgICAgY3R4LnN0cm9rZVRleHQocGFydGlhbFRleHQsIDAsIDApO1xuICAgICAgICB9XG5cbiAgICAgICAgY3R4LnJlc3RvcmUoKTtcblxuICAgICAgICBpZiAodGV4dERlY29yYXRpb24gPT09ICd1bmRlcmxpbmUnKSB7XG4gICAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgIGN0eC5tb3ZlVG8ocDAueCwgcDAueSArIGZvbnRTaXplIC8gOCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY3R4LmxpbmVUbyhwMS54LCBwMS55ICsgZm9udFNpemUgLyA1KTtcbiAgICAgICAgfSAvLyAvLyBUbyBhc3Npc3Qgd2l0aCBkZWJ1Z2dpbmcgdmlzdWFsbHksIHVuY29tbWVudCBmb2xsb3dpbmdcbiAgICAgICAgLy9cbiAgICAgICAgLy8gY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICAvLyBpZiAoaSAlIDIpXG4gICAgICAgIC8vIFx0Y3R4LnN0cm9rZVN0eWxlID0gJ3JlZCc7XG4gICAgICAgIC8vIGVsc2VcbiAgICAgICAgLy8gXHRjdHguc3Ryb2tlU3R5bGUgPSAnZ3JlZW4nO1xuICAgICAgICAvLyBjdHgubW92ZVRvKHAwLngsIHAwLnkpO1xuICAgICAgICAvLyBjdHgubGluZVRvKHAxLngsIHAxLnkpO1xuICAgICAgICAvLyBjdHguc3Ryb2tlKCk7XG4gICAgICAgIC8vIGN0eC5jbG9zZVBhdGgoKTtcblxuICAgICAgfSk7XG5cbiAgICAgIGlmICh0ZXh0RGVjb3JhdGlvbiA9PT0gJ3VuZGVybGluZScpIHtcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IGZvbnRTaXplIC8gMjA7XG4gICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IGZpbGw7XG4gICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgfVxuXG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRMZXR0ZXJTcGFjaW5nQXRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0TGV0dGVyU3BhY2luZ0F0KCkge1xuICAgICAgdmFyIGlkeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogMDtcbiAgICAgIHJldHVybiB0aGlzLmxldHRlclNwYWNpbmdDYWNoZVtpZHhdIHx8IDA7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImZpbmRTZWdtZW50VG9GaXRDaGFyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGZpbmRTZWdtZW50VG9GaXRDaGFyKGN0eCwgYW5jaG9yLCB0ZXh0RnVsbFdpZHRoLCBmdWxsUGF0aFdpZHRoLCBzcGFjZXNOdW1iZXIsIGlucHV0T2Zmc2V0LCBkeSwgYywgY2hhckkpIHtcbiAgICAgIHZhciBvZmZzZXQgPSBpbnB1dE9mZnNldDtcbiAgICAgIHZhciBnbHlwaFdpZHRoID0gdGhpcy5tZWFzdXJlVGV4dChjdHgsIGMpO1xuXG4gICAgICBpZiAoYyA9PT0gJyAnICYmIGFuY2hvciA9PT0gJ2p1c3RpZnknICYmIHRleHRGdWxsV2lkdGggPCBmdWxsUGF0aFdpZHRoKSB7XG4gICAgICAgIGdseXBoV2lkdGggKz0gKGZ1bGxQYXRoV2lkdGggLSB0ZXh0RnVsbFdpZHRoKSAvIHNwYWNlc051bWJlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGNoYXJJID4gLTEpIHtcbiAgICAgICAgb2Zmc2V0ICs9IHRoaXMuZ2V0TGV0dGVyU3BhY2luZ0F0KGNoYXJJKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHNwbGluZVN0ZXAgPSB0aGlzLnRleHRIZWlnaHQgLyAyMDtcbiAgICAgIHZhciBwMCA9IHRoaXMuZ2V0RXF1aWRpc3RhbnRQb2ludE9uUGF0aChvZmZzZXQsIHNwbGluZVN0ZXAsIDApO1xuICAgICAgdmFyIHAxID0gdGhpcy5nZXRFcXVpZGlzdGFudFBvaW50T25QYXRoKG9mZnNldCArIGdseXBoV2lkdGgsIHNwbGluZVN0ZXAsIDApO1xuICAgICAgdmFyIHNlZ21lbnQgPSB7XG4gICAgICAgIHAwOiBwMCxcbiAgICAgICAgcDE6IHAxXG4gICAgICB9O1xuICAgICAgdmFyIHJvdGF0aW9uID0gcDAgJiYgcDEgPyBNYXRoLmF0YW4yKHAxLnkgLSBwMC55LCBwMS54IC0gcDAueCkgOiAwO1xuXG4gICAgICBpZiAoZHkpIHtcbiAgICAgICAgdmFyIGR5WCA9IE1hdGguY29zKE1hdGguUEkgLyAyICsgcm90YXRpb24pICogZHk7XG4gICAgICAgIHZhciBkeVkgPSBNYXRoLmNvcygtcm90YXRpb24pICogZHk7XG4gICAgICAgIHNlZ21lbnQucDAgPSBfb2JqZWN0U3ByZWFkJDIoX29iamVjdFNwcmVhZCQyKHt9LCBwMCksIHt9LCB7XG4gICAgICAgICAgeDogcDAueCArIGR5WCxcbiAgICAgICAgICB5OiBwMC55ICsgZHlZXG4gICAgICAgIH0pO1xuICAgICAgICBzZWdtZW50LnAxID0gX29iamVjdFNwcmVhZCQyKF9vYmplY3RTcHJlYWQkMih7fSwgcDEpLCB7fSwge1xuICAgICAgICAgIHg6IHAxLnggKyBkeVgsXG4gICAgICAgICAgeTogcDEueSArIGR5WVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgb2Zmc2V0ICs9IGdseXBoV2lkdGg7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgICAgc2VnbWVudDogc2VnbWVudCxcbiAgICAgICAgcm90YXRpb246IHJvdGF0aW9uXG4gICAgICB9O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJtZWFzdXJlVGV4dFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBtZWFzdXJlVGV4dChjdHgsIHRleHQpIHtcbiAgICAgIHZhciBtZWFzdXJlc0NhY2hlID0gdGhpcy5tZWFzdXJlc0NhY2hlO1xuICAgICAgdmFyIHRhcmdldFRleHQgPSB0ZXh0IHx8IHRoaXMuZ2V0VGV4dCgpO1xuXG4gICAgICBpZiAobWVhc3VyZXNDYWNoZS5oYXModGFyZ2V0VGV4dCkpIHtcbiAgICAgICAgcmV0dXJuIG1lYXN1cmVzQ2FjaGUuZ2V0KHRhcmdldFRleHQpO1xuICAgICAgfVxuXG4gICAgICB2YXIgbWVhc3VyZSA9IHRoaXMubWVhc3VyZVRhcmdldFRleHQoY3R4LCB0YXJnZXRUZXh0KTtcbiAgICAgIG1lYXN1cmVzQ2FjaGUuc2V0KHRhcmdldFRleHQsIG1lYXN1cmUpO1xuICAgICAgcmV0dXJuIG1lYXN1cmU7XG4gICAgfSAvLyBUaGlzIG1ldGhvZCBzdXBwb3NlcyB3aGF0IGFsbCBjdXN0b20gZm9udHMgYWxyZWFkeSBsb2FkZWQuXG4gICAgLy8gSWYgc29tZSBmb250IHdpbGwgYmUgbG9hZGVkIGFmdGVyIHRoaXMgbWV0aG9kIGNhbGwsIDx0ZXh0UGF0aD4gd2lsbCBub3QgYmUgcmVuZGVyZWQgY29ycmVjdGx5LlxuICAgIC8vIFlvdSBuZWVkIHRvIGNhbGwgdGhpcyBtZXRob2QgbWFudWFsbHkgdG8gdXBkYXRlIGdseXBocyBjYWNoZS5cblxuICB9LCB7XG4gICAga2V5OiBcInNldFRleHREYXRhXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldFRleHREYXRhKGN0eCkge1xuICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgIGlmICh0aGlzLmdseXBoSW5mbykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciByZW5kZXJUZXh0ID0gdGhpcy5nZXRUZXh0KCk7XG4gICAgICB2YXIgY2hhcnMgPSByZW5kZXJUZXh0LnNwbGl0KCcnKTtcbiAgICAgIHZhciBzcGFjZXNOdW1iZXIgPSByZW5kZXJUZXh0LnNwbGl0KCcgJykubGVuZ3RoIC0gMTtcbiAgICAgIHZhciBkeCA9IHRoaXMucGFyZW50LmdldEF0dHJpYnV0ZSgnZHgnKS5zcGxpdCgpLm1hcChmdW5jdGlvbiAoXykge1xuICAgICAgICByZXR1cm4gXy5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgIH0pO1xuICAgICAgdmFyIGR5ID0gdGhpcy5wYXJlbnQuZ2V0QXR0cmlidXRlKCdkeScpLmdldFBpeGVscygneScpO1xuICAgICAgdmFyIGFuY2hvciA9IHRoaXMucGFyZW50LmdldFN0eWxlKCd0ZXh0LWFuY2hvcicpLmdldFN0cmluZygnc3RhcnQnKTtcbiAgICAgIHZhciB0aGlzU3BhY2luZyA9IHRoaXMuZ2V0U3R5bGUoJ2xldHRlci1zcGFjaW5nJyk7XG4gICAgICB2YXIgcGFyZW50U3BhY2luZyA9IHRoaXMucGFyZW50LmdldFN0eWxlKCdsZXR0ZXItc3BhY2luZycpO1xuICAgICAgdmFyIGxldHRlclNwYWNpbmcgPSAwO1xuXG4gICAgICBpZiAoIXRoaXNTcGFjaW5nLmhhc1ZhbHVlKCkgfHwgdGhpc1NwYWNpbmcuZ2V0VmFsdWUoKSA9PT0gJ2luaGVyaXQnKSB7XG4gICAgICAgIGxldHRlclNwYWNpbmcgPSBwYXJlbnRTcGFjaW5nLmdldFBpeGVscygpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzU3BhY2luZy5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIGlmICh0aGlzU3BhY2luZy5nZXRWYWx1ZSgpICE9PSAnaW5pdGlhbCcgJiYgdGhpc1NwYWNpbmcuZ2V0VmFsdWUoKSAhPT0gJ3Vuc2V0Jykge1xuICAgICAgICAgIGxldHRlclNwYWNpbmcgPSB0aGlzU3BhY2luZy5nZXRQaXhlbHMoKTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBmaWxsIGxldHRlci1zcGFjaW5nIGNhY2hlXG5cblxuICAgICAgdmFyIGxldHRlclNwYWNpbmdDYWNoZSA9IFtdO1xuICAgICAgdmFyIHRleHRMZW4gPSByZW5kZXJUZXh0Lmxlbmd0aDtcbiAgICAgIHRoaXMubGV0dGVyU3BhY2luZ0NhY2hlID0gbGV0dGVyU3BhY2luZ0NhY2hlO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRleHRMZW47IGkrKykge1xuICAgICAgICBsZXR0ZXJTcGFjaW5nQ2FjaGUucHVzaCh0eXBlb2YgZHhbaV0gIT09ICd1bmRlZmluZWQnID8gZHhbaV0gOiBsZXR0ZXJTcGFjaW5nKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGR4U3VtID0gbGV0dGVyU3BhY2luZ0NhY2hlLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBjdXIsIGkpIHtcbiAgICAgICAgcmV0dXJuIGkgPT09IDAgPyAwIDogYWNjICsgY3VyIHx8IDA7XG4gICAgICB9LCAwKTtcbiAgICAgIHZhciB0ZXh0V2lkdGggPSB0aGlzLm1lYXN1cmVUZXh0KGN0eCk7XG4gICAgICB2YXIgdGV4dEZ1bGxXaWR0aCA9IE1hdGgubWF4KHRleHRXaWR0aCArIGR4U3VtLCAwKTtcbiAgICAgIHRoaXMudGV4dFdpZHRoID0gdGV4dFdpZHRoO1xuICAgICAgdGhpcy50ZXh0SGVpZ2h0ID0gdGhpcy5nZXRGb250U2l6ZSgpO1xuICAgICAgdGhpcy5nbHlwaEluZm8gPSBbXTtcbiAgICAgIHZhciBmdWxsUGF0aFdpZHRoID0gdGhpcy5nZXRQYXRoTGVuZ3RoKCk7XG4gICAgICB2YXIgc3RhcnRPZmZzZXQgPSB0aGlzLmdldFN0eWxlKCdzdGFydE9mZnNldCcpLmdldE51bWJlcigwKSAqIGZ1bGxQYXRoV2lkdGg7XG4gICAgICB2YXIgb2Zmc2V0ID0gMDtcblxuICAgICAgaWYgKGFuY2hvciA9PT0gJ21pZGRsZScgfHwgYW5jaG9yID09PSAnY2VudGVyJykge1xuICAgICAgICBvZmZzZXQgPSAtdGV4dEZ1bGxXaWR0aCAvIDI7XG4gICAgICB9XG5cbiAgICAgIGlmIChhbmNob3IgPT09ICdlbmQnIHx8IGFuY2hvciA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICBvZmZzZXQgPSAtdGV4dEZ1bGxXaWR0aDtcbiAgICAgIH1cblxuICAgICAgb2Zmc2V0ICs9IHN0YXJ0T2Zmc2V0O1xuICAgICAgY2hhcnMuZm9yRWFjaChmdW5jdGlvbiAoY2hhciwgaSkge1xuICAgICAgICAvLyBGaW5kIHN1Y2ggc2VnbWVudCB3aGF0IGRpc3RhbmNlIGJldHdlZW4gcDAgYW5kIHAxIGlzIGFwcHJveC4gd2lkdGggb2YgZ2x5cGhcbiAgICAgICAgdmFyIF90aGlzMiRmaW5kU2VnbWVudFRvRiA9IF90aGlzMi5maW5kU2VnbWVudFRvRml0Q2hhcihjdHgsIGFuY2hvciwgdGV4dEZ1bGxXaWR0aCwgZnVsbFBhdGhXaWR0aCwgc3BhY2VzTnVtYmVyLCBvZmZzZXQsIGR5LCBjaGFyLCBpKSxcbiAgICAgICAgICAgIG5leHRPZmZzZXQgPSBfdGhpczIkZmluZFNlZ21lbnRUb0Yub2Zmc2V0LFxuICAgICAgICAgICAgc2VnbWVudCA9IF90aGlzMiRmaW5kU2VnbWVudFRvRi5zZWdtZW50LFxuICAgICAgICAgICAgcm90YXRpb24gPSBfdGhpczIkZmluZFNlZ21lbnRUb0Yucm90YXRpb247XG5cbiAgICAgICAgb2Zmc2V0ID0gbmV4dE9mZnNldDtcblxuICAgICAgICBpZiAoIXNlZ21lbnQucDAgfHwgIXNlZ21lbnQucDEpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gLy8gY29uc3Qgd2lkdGggPSB0aGlzLmdldExpbmVMZW5ndGgoXG4gICAgICAgIC8vIFx0c2VnbWVudC5wMC54LFxuICAgICAgICAvLyBcdHNlZ21lbnQucDAueSxcbiAgICAgICAgLy8gXHRzZWdtZW50LnAxLngsXG4gICAgICAgIC8vIFx0c2VnbWVudC5wMS55XG4gICAgICAgIC8vICk7XG4gICAgICAgIC8vIE5vdGU6IFNpbmNlIGdseXBocyBhcmUgcmVuZGVyZWQgb25lIGF0IGEgdGltZSwgYW55IGtlcm5pbmcgcGFpciBkYXRhIGJ1aWx0IGludG8gdGhlIGZvbnQgd2lsbCBub3QgYmUgdXNlZC5cbiAgICAgICAgLy8gQ2FuIGZvcmVzZWUgaGF2aW5nIGEgcm91Z2ggcGFpciB0YWJsZSBidWlsdCBpbiB0aGF0IHRoZSBkZXZlbG9wZXIgY2FuIG92ZXJyaWRlIGFzIG5lZWRlZC5cbiAgICAgICAgLy8gT3IgdXNlIFwiZHhcIiBhdHRyaWJ1dGUgb2YgdGhlIDx0ZXh0PiBub2RlIGFzIGEgbmFpdmUgcmVwbGFjZW1lbnRcbiAgICAgICAgLy8gY29uc3Qga2VybiA9IDA7XG4gICAgICAgIC8vIHBsYWNlaG9sZGVyIGZvciBmdXR1cmUgaW1wbGVtZW50YXRpb25cbiAgICAgICAgLy8gY29uc3QgbWlkcG9pbnQgPSB0aGlzLmdldFBvaW50T25MaW5lKFxuICAgICAgICAvLyBcdGtlcm4gKyB3aWR0aCAvIDIuMCxcbiAgICAgICAgLy8gXHRzZWdtZW50LnAwLngsIHNlZ21lbnQucDAueSwgc2VnbWVudC5wMS54LCBzZWdtZW50LnAxLnlcbiAgICAgICAgLy8gKTtcblxuXG4gICAgICAgIF90aGlzMi5nbHlwaEluZm8ucHVzaCh7XG4gICAgICAgICAgLy8gdHJhbnNwb3NlWDogbWlkcG9pbnQueCxcbiAgICAgICAgICAvLyB0cmFuc3Bvc2VZOiBtaWRwb2ludC55LFxuICAgICAgICAgIHRleHQ6IGNoYXJzW2ldLFxuICAgICAgICAgIHAwOiBzZWdtZW50LnAwLFxuICAgICAgICAgIHAxOiBzZWdtZW50LnAxLFxuICAgICAgICAgIHJvdGF0aW9uOiByb3RhdGlvblxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXJzZVBhdGhEYXRhXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhcnNlUGF0aERhdGEocGF0aCkge1xuICAgICAgdGhpcy5wYXRoTGVuZ3RoID0gLTE7IC8vIHJlc2V0IHBhdGggbGVuZ3RoXG5cbiAgICAgIGlmICghcGF0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG5cbiAgICAgIHZhciBwYXRoQ29tbWFuZHMgPSBbXTtcbiAgICAgIHZhciBwYXRoUGFyc2VyID0gcGF0aC5wYXRoUGFyc2VyO1xuICAgICAgcGF0aFBhcnNlci5yZXNldCgpOyAvLyBjb252ZXJ0IGwsIEgsIGgsIFYsIGFuZCB2IHRvIExcblxuICAgICAgd2hpbGUgKCFwYXRoUGFyc2VyLmlzRW5kKCkpIHtcbiAgICAgICAgdmFyIGN1cnJlbnQgPSBwYXRoUGFyc2VyLmN1cnJlbnQ7XG4gICAgICAgIHZhciBzdGFydFggPSBjdXJyZW50ID8gY3VycmVudC54IDogMDtcbiAgICAgICAgdmFyIHN0YXJ0WSA9IGN1cnJlbnQgPyBjdXJyZW50LnkgOiAwO1xuICAgICAgICB2YXIgY29tbWFuZCA9IHBhdGhQYXJzZXIubmV4dCgpO1xuICAgICAgICB2YXIgbmV4dENvbW1hbmRUeXBlID0gY29tbWFuZC50eXBlO1xuICAgICAgICB2YXIgcG9pbnRzID0gW107XG5cbiAgICAgICAgc3dpdGNoIChjb21tYW5kLnR5cGUpIHtcbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuTU9WRV9UTzpcbiAgICAgICAgICAgIHRoaXMucGF0aE0ocGF0aFBhcnNlciwgcG9pbnRzKTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBQYXRoUGFyc2VyLkxJTkVfVE86XG4gICAgICAgICAgICBuZXh0Q29tbWFuZFR5cGUgPSB0aGlzLnBhdGhMKHBhdGhQYXJzZXIsIHBvaW50cyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgUGF0aFBhcnNlci5IT1JJWl9MSU5FX1RPOlxuICAgICAgICAgICAgbmV4dENvbW1hbmRUeXBlID0gdGhpcy5wYXRoSChwYXRoUGFyc2VyLCBwb2ludHMpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuVkVSVF9MSU5FX1RPOlxuICAgICAgICAgICAgbmV4dENvbW1hbmRUeXBlID0gdGhpcy5wYXRoVihwYXRoUGFyc2VyLCBwb2ludHMpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuQ1VSVkVfVE86XG4gICAgICAgICAgICB0aGlzLnBhdGhDKHBhdGhQYXJzZXIsIHBvaW50cyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgUGF0aFBhcnNlci5TTU9PVEhfQ1VSVkVfVE86XG4gICAgICAgICAgICBuZXh0Q29tbWFuZFR5cGUgPSB0aGlzLnBhdGhTKHBhdGhQYXJzZXIsIHBvaW50cyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgUGF0aFBhcnNlci5RVUFEX1RPOlxuICAgICAgICAgICAgdGhpcy5wYXRoUShwYXRoUGFyc2VyLCBwb2ludHMpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuU01PT1RIX1FVQURfVE86XG4gICAgICAgICAgICBuZXh0Q29tbWFuZFR5cGUgPSB0aGlzLnBhdGhUKHBhdGhQYXJzZXIsIHBvaW50cyk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgUGF0aFBhcnNlci5BUkM6XG4gICAgICAgICAgICBwb2ludHMgPSB0aGlzLnBhdGhBKHBhdGhQYXJzZXIpO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuQ0xPU0VfUEFUSDpcbiAgICAgICAgICAgIFBhdGhFbGVtZW50LnBhdGhaKHBhdGhQYXJzZXIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29tbWFuZC50eXBlICE9PSBQYXRoUGFyc2VyLkNMT1NFX1BBVEgpIHtcbiAgICAgICAgICBwYXRoQ29tbWFuZHMucHVzaCh7XG4gICAgICAgICAgICB0eXBlOiBuZXh0Q29tbWFuZFR5cGUsXG4gICAgICAgICAgICBwb2ludHM6IHBvaW50cyxcbiAgICAgICAgICAgIHN0YXJ0OiB7XG4gICAgICAgICAgICAgIHg6IHN0YXJ0WCxcbiAgICAgICAgICAgICAgeTogc3RhcnRZXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGF0aExlbmd0aDogdGhpcy5jYWxjTGVuZ3RoKHN0YXJ0WCwgc3RhcnRZLCBuZXh0Q29tbWFuZFR5cGUsIHBvaW50cylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYXRoQ29tbWFuZHMucHVzaCh7XG4gICAgICAgICAgICB0eXBlOiBQYXRoUGFyc2VyLkNMT1NFX1BBVEgsXG4gICAgICAgICAgICBwb2ludHM6IFtdLFxuICAgICAgICAgICAgcGF0aExlbmd0aDogMFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXRoQ29tbWFuZHM7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhNXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhNKHBhdGhQYXJzZXIsIHBvaW50cykge1xuICAgICAgdmFyIF9QYXRoRWxlbWVudCRwYXRoTSRwbyA9IFBhdGhFbGVtZW50LnBhdGhNKHBhdGhQYXJzZXIpLnBvaW50LFxuICAgICAgICAgIHggPSBfUGF0aEVsZW1lbnQkcGF0aE0kcG8ueCxcbiAgICAgICAgICB5ID0gX1BhdGhFbGVtZW50JHBhdGhNJHBvLnk7XG4gICAgICBwb2ludHMucHVzaCh4LCB5KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aExcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aEwocGF0aFBhcnNlciwgcG9pbnRzKSB7XG4gICAgICB2YXIgX1BhdGhFbGVtZW50JHBhdGhMJHBvID0gUGF0aEVsZW1lbnQucGF0aEwocGF0aFBhcnNlcikucG9pbnQsXG4gICAgICAgICAgeCA9IF9QYXRoRWxlbWVudCRwYXRoTCRwby54LFxuICAgICAgICAgIHkgPSBfUGF0aEVsZW1lbnQkcGF0aEwkcG8ueTtcbiAgICAgIHBvaW50cy5wdXNoKHgsIHkpO1xuICAgICAgcmV0dXJuIFBhdGhQYXJzZXIuTElORV9UTztcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aEhcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aEgocGF0aFBhcnNlciwgcG9pbnRzKSB7XG4gICAgICB2YXIgX1BhdGhFbGVtZW50JHBhdGhIJHBvID0gUGF0aEVsZW1lbnQucGF0aEgocGF0aFBhcnNlcikucG9pbnQsXG4gICAgICAgICAgeCA9IF9QYXRoRWxlbWVudCRwYXRoSCRwby54LFxuICAgICAgICAgIHkgPSBfUGF0aEVsZW1lbnQkcGF0aEgkcG8ueTtcbiAgICAgIHBvaW50cy5wdXNoKHgsIHkpO1xuICAgICAgcmV0dXJuIFBhdGhQYXJzZXIuTElORV9UTztcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aFZcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aFYocGF0aFBhcnNlciwgcG9pbnRzKSB7XG4gICAgICB2YXIgX1BhdGhFbGVtZW50JHBhdGhWJHBvID0gUGF0aEVsZW1lbnQucGF0aFYocGF0aFBhcnNlcikucG9pbnQsXG4gICAgICAgICAgeCA9IF9QYXRoRWxlbWVudCRwYXRoViRwby54LFxuICAgICAgICAgIHkgPSBfUGF0aEVsZW1lbnQkcGF0aFYkcG8ueTtcbiAgICAgIHBvaW50cy5wdXNoKHgsIHkpO1xuICAgICAgcmV0dXJuIFBhdGhQYXJzZXIuTElORV9UTztcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aENcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcGF0aEMocGF0aFBhcnNlciwgcG9pbnRzKSB7XG4gICAgICB2YXIgX1BhdGhFbGVtZW50JHBhdGhDID0gUGF0aEVsZW1lbnQucGF0aEMocGF0aFBhcnNlciksXG4gICAgICAgICAgcG9pbnQgPSBfUGF0aEVsZW1lbnQkcGF0aEMucG9pbnQsXG4gICAgICAgICAgY29udHJvbFBvaW50ID0gX1BhdGhFbGVtZW50JHBhdGhDLmNvbnRyb2xQb2ludCxcbiAgICAgICAgICBjdXJyZW50UG9pbnQgPSBfUGF0aEVsZW1lbnQkcGF0aEMuY3VycmVudFBvaW50O1xuXG4gICAgICBwb2ludHMucHVzaChwb2ludC54LCBwb2ludC55LCBjb250cm9sUG9pbnQueCwgY29udHJvbFBvaW50LnksIGN1cnJlbnRQb2ludC54LCBjdXJyZW50UG9pbnQueSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhTXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhTKHBhdGhQYXJzZXIsIHBvaW50cykge1xuICAgICAgdmFyIF9QYXRoRWxlbWVudCRwYXRoUyA9IFBhdGhFbGVtZW50LnBhdGhTKHBhdGhQYXJzZXIpLFxuICAgICAgICAgIHBvaW50ID0gX1BhdGhFbGVtZW50JHBhdGhTLnBvaW50LFxuICAgICAgICAgIGNvbnRyb2xQb2ludCA9IF9QYXRoRWxlbWVudCRwYXRoUy5jb250cm9sUG9pbnQsXG4gICAgICAgICAgY3VycmVudFBvaW50ID0gX1BhdGhFbGVtZW50JHBhdGhTLmN1cnJlbnRQb2ludDtcblxuICAgICAgcG9pbnRzLnB1c2gocG9pbnQueCwgcG9pbnQueSwgY29udHJvbFBvaW50LngsIGNvbnRyb2xQb2ludC55LCBjdXJyZW50UG9pbnQueCwgY3VycmVudFBvaW50LnkpO1xuICAgICAgcmV0dXJuIFBhdGhQYXJzZXIuQ1VSVkVfVE87XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhRXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhRKHBhdGhQYXJzZXIsIHBvaW50cykge1xuICAgICAgdmFyIF9QYXRoRWxlbWVudCRwYXRoUSA9IFBhdGhFbGVtZW50LnBhdGhRKHBhdGhQYXJzZXIpLFxuICAgICAgICAgIGNvbnRyb2xQb2ludCA9IF9QYXRoRWxlbWVudCRwYXRoUS5jb250cm9sUG9pbnQsXG4gICAgICAgICAgY3VycmVudFBvaW50ID0gX1BhdGhFbGVtZW50JHBhdGhRLmN1cnJlbnRQb2ludDtcblxuICAgICAgcG9pbnRzLnB1c2goY29udHJvbFBvaW50LngsIGNvbnRyb2xQb2ludC55LCBjdXJyZW50UG9pbnQueCwgY3VycmVudFBvaW50LnkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwYXRoVFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoVChwYXRoUGFyc2VyLCBwb2ludHMpIHtcbiAgICAgIHZhciBfUGF0aEVsZW1lbnQkcGF0aFQgPSBQYXRoRWxlbWVudC5wYXRoVChwYXRoUGFyc2VyKSxcbiAgICAgICAgICBjb250cm9sUG9pbnQgPSBfUGF0aEVsZW1lbnQkcGF0aFQuY29udHJvbFBvaW50LFxuICAgICAgICAgIGN1cnJlbnRQb2ludCA9IF9QYXRoRWxlbWVudCRwYXRoVC5jdXJyZW50UG9pbnQ7XG5cbiAgICAgIHBvaW50cy5wdXNoKGNvbnRyb2xQb2ludC54LCBjb250cm9sUG9pbnQueSwgY3VycmVudFBvaW50LngsIGN1cnJlbnRQb2ludC55KTtcbiAgICAgIHJldHVybiBQYXRoUGFyc2VyLlFVQURfVE87XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInBhdGhBXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHBhdGhBKHBhdGhQYXJzZXIpIHtcbiAgICAgIHZhciBfUGF0aEVsZW1lbnQkcGF0aEEgPSBQYXRoRWxlbWVudC5wYXRoQShwYXRoUGFyc2VyKSxcbiAgICAgICAgICByWCA9IF9QYXRoRWxlbWVudCRwYXRoQS5yWCxcbiAgICAgICAgICByWSA9IF9QYXRoRWxlbWVudCRwYXRoQS5yWSxcbiAgICAgICAgICBzd2VlcEZsYWcgPSBfUGF0aEVsZW1lbnQkcGF0aEEuc3dlZXBGbGFnLFxuICAgICAgICAgIHhBeGlzUm90YXRpb24gPSBfUGF0aEVsZW1lbnQkcGF0aEEueEF4aXNSb3RhdGlvbixcbiAgICAgICAgICBjZW50cCA9IF9QYXRoRWxlbWVudCRwYXRoQS5jZW50cCxcbiAgICAgICAgICBhMSA9IF9QYXRoRWxlbWVudCRwYXRoQS5hMSxcbiAgICAgICAgICBhZCA9IF9QYXRoRWxlbWVudCRwYXRoQS5hZDtcblxuICAgICAgaWYgKHN3ZWVwRmxhZyA9PT0gMCAmJiBhZCA+IDApIHtcbiAgICAgICAgYWQgLT0gMiAqIE1hdGguUEk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzd2VlcEZsYWcgPT09IDEgJiYgYWQgPCAwKSB7XG4gICAgICAgIGFkICs9IDIgKiBNYXRoLlBJO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gW2NlbnRwLngsIGNlbnRwLnksIHJYLCByWSwgYTEsIGFkLCB4QXhpc1JvdGF0aW9uLCBzd2VlcEZsYWddO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjYWxjTGVuZ3RoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNhbGNMZW5ndGgoeCwgeSwgY29tbWFuZFR5cGUsIHBvaW50cykge1xuICAgICAgdmFyIGxlbiA9IDA7XG4gICAgICB2YXIgcDEgPSBudWxsO1xuICAgICAgdmFyIHAyID0gbnVsbDtcbiAgICAgIHZhciB0ID0gMDtcblxuICAgICAgc3dpdGNoIChjb21tYW5kVHlwZSkge1xuICAgICAgICBjYXNlIFBhdGhQYXJzZXIuTElORV9UTzpcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXRMaW5lTGVuZ3RoKHgsIHksIHBvaW50c1swXSwgcG9pbnRzWzFdKTtcblxuICAgICAgICBjYXNlIFBhdGhQYXJzZXIuQ1VSVkVfVE86XG4gICAgICAgICAgLy8gQXBwcm94aW1hdGVzIGJ5IGJyZWFraW5nIGN1cnZlIGludG8gMTAwIGxpbmUgc2VnbWVudHNcbiAgICAgICAgICBsZW4gPSAwLjA7XG4gICAgICAgICAgcDEgPSB0aGlzLmdldFBvaW50T25DdWJpY0JlemllcigwLCB4LCB5LCBwb2ludHNbMF0sIHBvaW50c1sxXSwgcG9pbnRzWzJdLCBwb2ludHNbM10sIHBvaW50c1s0XSwgcG9pbnRzWzVdKTtcblxuICAgICAgICAgIGZvciAodCA9IDAuMDE7IHQgPD0gMTsgdCArPSAwLjAxKSB7XG4gICAgICAgICAgICBwMiA9IHRoaXMuZ2V0UG9pbnRPbkN1YmljQmV6aWVyKHQsIHgsIHksIHBvaW50c1swXSwgcG9pbnRzWzFdLCBwb2ludHNbMl0sIHBvaW50c1szXSwgcG9pbnRzWzRdLCBwb2ludHNbNV0pO1xuICAgICAgICAgICAgbGVuICs9IHRoaXMuZ2V0TGluZUxlbmd0aChwMS54LCBwMS55LCBwMi54LCBwMi55KTtcbiAgICAgICAgICAgIHAxID0gcDI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGxlbjtcblxuICAgICAgICBjYXNlIFBhdGhQYXJzZXIuUVVBRF9UTzpcbiAgICAgICAgICAvLyBBcHByb3hpbWF0ZXMgYnkgYnJlYWtpbmcgY3VydmUgaW50byAxMDAgbGluZSBzZWdtZW50c1xuICAgICAgICAgIGxlbiA9IDAuMDtcbiAgICAgICAgICBwMSA9IHRoaXMuZ2V0UG9pbnRPblF1YWRyYXRpY0JlemllcigwLCB4LCB5LCBwb2ludHNbMF0sIHBvaW50c1sxXSwgcG9pbnRzWzJdLCBwb2ludHNbM10pO1xuXG4gICAgICAgICAgZm9yICh0ID0gMC4wMTsgdCA8PSAxOyB0ICs9IDAuMDEpIHtcbiAgICAgICAgICAgIHAyID0gdGhpcy5nZXRQb2ludE9uUXVhZHJhdGljQmV6aWVyKHQsIHgsIHksIHBvaW50c1swXSwgcG9pbnRzWzFdLCBwb2ludHNbMl0sIHBvaW50c1szXSk7XG4gICAgICAgICAgICBsZW4gKz0gdGhpcy5nZXRMaW5lTGVuZ3RoKHAxLngsIHAxLnksIHAyLngsIHAyLnkpO1xuICAgICAgICAgICAgcDEgPSBwMjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbGVuO1xuXG4gICAgICAgIGNhc2UgUGF0aFBhcnNlci5BUkM6XG4gICAgICAgICAge1xuICAgICAgICAgICAgLy8gQXBwcm94aW1hdGVzIGJ5IGJyZWFraW5nIGN1cnZlIGludG8gbGluZSBzZWdtZW50c1xuICAgICAgICAgICAgbGVuID0gMC4wO1xuICAgICAgICAgICAgdmFyIHN0YXJ0ID0gcG9pbnRzWzRdOyAvLyA0ID0gdGhldGFcblxuICAgICAgICAgICAgdmFyIGRUaGV0YSA9IHBvaW50c1s1XTsgLy8gNSA9IGRUaGV0YVxuXG4gICAgICAgICAgICB2YXIgZW5kID0gcG9pbnRzWzRdICsgZFRoZXRhO1xuICAgICAgICAgICAgdmFyIGluYyA9IE1hdGguUEkgLyAxODAuMDsgLy8gMSBkZWdyZWUgcmVzb2x1dGlvblxuXG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoc3RhcnQgLSBlbmQpIDwgaW5jKSB7XG4gICAgICAgICAgICAgIGluYyA9IE1hdGguYWJzKHN0YXJ0IC0gZW5kKTtcbiAgICAgICAgICAgIH0gLy8gTm90ZTogZm9yIHB1cnBvc2Ugb2YgY2FsY3VsYXRpbmcgYXJjIGxlbmd0aCwgbm90IGdvaW5nIHRvIHdvcnJ5IGFib3V0IHJvdGF0aW5nIFgtYXhpcyBieSBhbmdsZSBwc2lcblxuXG4gICAgICAgICAgICBwMSA9IHRoaXMuZ2V0UG9pbnRPbkVsbGlwdGljYWxBcmMocG9pbnRzWzBdLCBwb2ludHNbMV0sIHBvaW50c1syXSwgcG9pbnRzWzNdLCBzdGFydCwgMCk7XG5cbiAgICAgICAgICAgIGlmIChkVGhldGEgPCAwKSB7XG4gICAgICAgICAgICAgIC8vIGNsb2Nrd2lzZVxuICAgICAgICAgICAgICBmb3IgKHQgPSBzdGFydCAtIGluYzsgdCA+IGVuZDsgdCAtPSBpbmMpIHtcbiAgICAgICAgICAgICAgICBwMiA9IHRoaXMuZ2V0UG9pbnRPbkVsbGlwdGljYWxBcmMocG9pbnRzWzBdLCBwb2ludHNbMV0sIHBvaW50c1syXSwgcG9pbnRzWzNdLCB0LCAwKTtcbiAgICAgICAgICAgICAgICBsZW4gKz0gdGhpcy5nZXRMaW5lTGVuZ3RoKHAxLngsIHAxLnksIHAyLngsIHAyLnkpO1xuICAgICAgICAgICAgICAgIHAxID0gcDI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIGNvdW50ZXItY2xvY2t3aXNlXG4gICAgICAgICAgICAgIGZvciAodCA9IHN0YXJ0ICsgaW5jOyB0IDwgZW5kOyB0ICs9IGluYykge1xuICAgICAgICAgICAgICAgIHAyID0gdGhpcy5nZXRQb2ludE9uRWxsaXB0aWNhbEFyYyhwb2ludHNbMF0sIHBvaW50c1sxXSwgcG9pbnRzWzJdLCBwb2ludHNbM10sIHQsIDApO1xuICAgICAgICAgICAgICAgIGxlbiArPSB0aGlzLmdldExpbmVMZW5ndGgocDEueCwgcDEueSwgcDIueCwgcDIueSk7XG4gICAgICAgICAgICAgICAgcDEgPSBwMjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwMiA9IHRoaXMuZ2V0UG9pbnRPbkVsbGlwdGljYWxBcmMocG9pbnRzWzBdLCBwb2ludHNbMV0sIHBvaW50c1syXSwgcG9pbnRzWzNdLCBlbmQsIDApO1xuICAgICAgICAgICAgbGVuICs9IHRoaXMuZ2V0TGluZUxlbmd0aChwMS54LCBwMS55LCBwMi54LCBwMi55KTtcbiAgICAgICAgICAgIHJldHVybiBsZW47XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0UG9pbnRPbkxpbmVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UG9pbnRPbkxpbmUoZGlzdCwgcDF4LCBwMXksIHAyeCwgcDJ5KSB7XG4gICAgICB2YXIgZnJvbVggPSBhcmd1bWVudHMubGVuZ3RoID4gNSAmJiBhcmd1bWVudHNbNV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1s1XSA6IHAxeDtcbiAgICAgIHZhciBmcm9tWSA9IGFyZ3VtZW50cy5sZW5ndGggPiA2ICYmIGFyZ3VtZW50c1s2XSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzZdIDogcDF5O1xuICAgICAgdmFyIG0gPSAocDJ5IC0gcDF5KSAvIChwMnggLSBwMXggKyBQU0VVRE9fWkVSTyk7XG4gICAgICB2YXIgcnVuID0gTWF0aC5zcXJ0KGRpc3QgKiBkaXN0IC8gKDEgKyBtICogbSkpO1xuXG4gICAgICBpZiAocDJ4IDwgcDF4KSB7XG4gICAgICAgIHJ1biAqPSAtMTtcbiAgICAgIH1cblxuICAgICAgdmFyIHJpc2UgPSBtICogcnVuO1xuICAgICAgdmFyIHB0ID0gbnVsbDtcblxuICAgICAgaWYgKHAyeCA9PT0gcDF4KSB7XG4gICAgICAgIC8vIHZlcnRpY2FsIGxpbmVcbiAgICAgICAgcHQgPSB7XG4gICAgICAgICAgeDogZnJvbVgsXG4gICAgICAgICAgeTogZnJvbVkgKyByaXNlXG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKChmcm9tWSAtIHAxeSkgLyAoZnJvbVggLSBwMXggKyBQU0VVRE9fWkVSTykgPT09IG0pIHtcbiAgICAgICAgcHQgPSB7XG4gICAgICAgICAgeDogZnJvbVggKyBydW4sXG4gICAgICAgICAgeTogZnJvbVkgKyByaXNlXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaXggPSAwO1xuICAgICAgICB2YXIgaXkgPSAwO1xuICAgICAgICB2YXIgbGVuID0gdGhpcy5nZXRMaW5lTGVuZ3RoKHAxeCwgcDF5LCBwMngsIHAyeSk7XG5cbiAgICAgICAgaWYgKGxlbiA8IFBTRVVET19aRVJPKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdSA9IChmcm9tWCAtIHAxeCkgKiAocDJ4IC0gcDF4KSArIChmcm9tWSAtIHAxeSkgKiAocDJ5IC0gcDF5KTtcbiAgICAgICAgdSAvPSBsZW4gKiBsZW47XG4gICAgICAgIGl4ID0gcDF4ICsgdSAqIChwMnggLSBwMXgpO1xuICAgICAgICBpeSA9IHAxeSArIHUgKiAocDJ5IC0gcDF5KTtcbiAgICAgICAgdmFyIHBSaXNlID0gdGhpcy5nZXRMaW5lTGVuZ3RoKGZyb21YLCBmcm9tWSwgaXgsIGl5KTtcbiAgICAgICAgdmFyIHBSdW4gPSBNYXRoLnNxcnQoZGlzdCAqIGRpc3QgLSBwUmlzZSAqIHBSaXNlKTtcbiAgICAgICAgcnVuID0gTWF0aC5zcXJ0KHBSdW4gKiBwUnVuIC8gKDEgKyBtICogbSkpO1xuXG4gICAgICAgIGlmIChwMnggPCBwMXgpIHtcbiAgICAgICAgICBydW4gKj0gLTE7XG4gICAgICAgIH1cblxuICAgICAgICByaXNlID0gbSAqIHJ1bjtcbiAgICAgICAgcHQgPSB7XG4gICAgICAgICAgeDogaXggKyBydW4sXG4gICAgICAgICAgeTogaXkgKyByaXNlXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwdDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0UG9pbnRPblBhdGhcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UG9pbnRPblBhdGgoZGlzdGFuY2UpIHtcbiAgICAgIHZhciBmdWxsTGVuID0gdGhpcy5nZXRQYXRoTGVuZ3RoKCk7XG4gICAgICB2YXIgY3VtdWxhdGl2ZVBhdGhMZW5ndGggPSAwO1xuICAgICAgdmFyIHAgPSBudWxsO1xuXG4gICAgICBpZiAoZGlzdGFuY2UgPCAtMC4wMDAwNSB8fCBkaXN0YW5jZSAtIDAuMDAwMDUgPiBmdWxsTGVuKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICB2YXIgZGF0YUFycmF5ID0gdGhpcy5kYXRhQXJyYXk7XG5cbiAgICAgIHZhciBfaXRlcmF0b3IgPSBfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlcihkYXRhQXJyYXkpLFxuICAgICAgICAgIF9zdGVwO1xuXG4gICAgICB0cnkge1xuICAgICAgICBmb3IgKF9pdGVyYXRvci5zKCk7ICEoX3N0ZXAgPSBfaXRlcmF0b3IubigpKS5kb25lOykge1xuICAgICAgICAgIHZhciBjb21tYW5kID0gX3N0ZXAudmFsdWU7XG5cbiAgICAgICAgICBpZiAoY29tbWFuZCAmJiAoY29tbWFuZC5wYXRoTGVuZ3RoIDwgMC4wMDAwNSB8fCBjdW11bGF0aXZlUGF0aExlbmd0aCArIGNvbW1hbmQucGF0aExlbmd0aCArIDAuMDAwMDUgPCBkaXN0YW5jZSkpIHtcbiAgICAgICAgICAgIGN1bXVsYXRpdmVQYXRoTGVuZ3RoICs9IGNvbW1hbmQucGF0aExlbmd0aDtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBkZWx0YSA9IGRpc3RhbmNlIC0gY3VtdWxhdGl2ZVBhdGhMZW5ndGg7XG4gICAgICAgICAgdmFyIGN1cnJlbnRUID0gMDtcblxuICAgICAgICAgIHN3aXRjaCAoY29tbWFuZC50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIFBhdGhQYXJzZXIuTElORV9UTzpcbiAgICAgICAgICAgICAgcCA9IHRoaXMuZ2V0UG9pbnRPbkxpbmUoZGVsdGEsIGNvbW1hbmQuc3RhcnQueCwgY29tbWFuZC5zdGFydC55LCBjb21tYW5kLnBvaW50c1swXSwgY29tbWFuZC5wb2ludHNbMV0sIGNvbW1hbmQuc3RhcnQueCwgY29tbWFuZC5zdGFydC55KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgUGF0aFBhcnNlci5BUkM6XG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2YXIgc3RhcnQgPSBjb21tYW5kLnBvaW50c1s0XTsgLy8gNCA9IHRoZXRhXG5cbiAgICAgICAgICAgICAgICB2YXIgZFRoZXRhID0gY29tbWFuZC5wb2ludHNbNV07IC8vIDUgPSBkVGhldGFcblxuICAgICAgICAgICAgICAgIHZhciBlbmQgPSBjb21tYW5kLnBvaW50c1s0XSArIGRUaGV0YTtcbiAgICAgICAgICAgICAgICBjdXJyZW50VCA9IHN0YXJ0ICsgZGVsdGEgLyBjb21tYW5kLnBhdGhMZW5ndGggKiBkVGhldGE7XG5cbiAgICAgICAgICAgICAgICBpZiAoZFRoZXRhIDwgMCAmJiBjdXJyZW50VCA8IGVuZCB8fCBkVGhldGEgPj0gMCAmJiBjdXJyZW50VCA+IGVuZCkge1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcCA9IHRoaXMuZ2V0UG9pbnRPbkVsbGlwdGljYWxBcmMoY29tbWFuZC5wb2ludHNbMF0sIGNvbW1hbmQucG9pbnRzWzFdLCBjb21tYW5kLnBvaW50c1syXSwgY29tbWFuZC5wb2ludHNbM10sIGN1cnJlbnRULCBjb21tYW5kLnBvaW50c1s2XSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSBQYXRoUGFyc2VyLkNVUlZFX1RPOlxuICAgICAgICAgICAgICBjdXJyZW50VCA9IGRlbHRhIC8gY29tbWFuZC5wYXRoTGVuZ3RoO1xuXG4gICAgICAgICAgICAgIGlmIChjdXJyZW50VCA+IDEpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50VCA9IDE7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBwID0gdGhpcy5nZXRQb2ludE9uQ3ViaWNCZXppZXIoY3VycmVudFQsIGNvbW1hbmQuc3RhcnQueCwgY29tbWFuZC5zdGFydC55LCBjb21tYW5kLnBvaW50c1swXSwgY29tbWFuZC5wb2ludHNbMV0sIGNvbW1hbmQucG9pbnRzWzJdLCBjb21tYW5kLnBvaW50c1szXSwgY29tbWFuZC5wb2ludHNbNF0sIGNvbW1hbmQucG9pbnRzWzVdKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgUGF0aFBhcnNlci5RVUFEX1RPOlxuICAgICAgICAgICAgICBjdXJyZW50VCA9IGRlbHRhIC8gY29tbWFuZC5wYXRoTGVuZ3RoO1xuXG4gICAgICAgICAgICAgIGlmIChjdXJyZW50VCA+IDEpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50VCA9IDE7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBwID0gdGhpcy5nZXRQb2ludE9uUXVhZHJhdGljQmV6aWVyKGN1cnJlbnRULCBjb21tYW5kLnN0YXJ0LngsIGNvbW1hbmQuc3RhcnQueSwgY29tbWFuZC5wb2ludHNbMF0sIGNvbW1hbmQucG9pbnRzWzFdLCBjb21tYW5kLnBvaW50c1syXSwgY29tbWFuZC5wb2ludHNbM10pO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocCkge1xuICAgICAgICAgICAgcmV0dXJuIHA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBfaXRlcmF0b3IuZShlcnIpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgX2l0ZXJhdG9yLmYoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldExpbmVMZW5ndGhcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0TGluZUxlbmd0aCh4MSwgeTEsIHgyLCB5Mikge1xuICAgICAgcmV0dXJuIE1hdGguc3FydCgoeDIgLSB4MSkgKiAoeDIgLSB4MSkgKyAoeTIgLSB5MSkgKiAoeTIgLSB5MSkpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRQYXRoTGVuZ3RoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFBhdGhMZW5ndGgoKSB7XG4gICAgICBpZiAodGhpcy5wYXRoTGVuZ3RoID09PSAtMSkge1xuICAgICAgICB0aGlzLnBhdGhMZW5ndGggPSB0aGlzLmRhdGFBcnJheS5yZWR1Y2UoZnVuY3Rpb24gKGxlbmd0aCwgY29tbWFuZCkge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kLnBhdGhMZW5ndGggPiAwID8gbGVuZ3RoICsgY29tbWFuZC5wYXRoTGVuZ3RoIDogbGVuZ3RoO1xuICAgICAgICB9LCAwKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMucGF0aExlbmd0aDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0UG9pbnRPbkN1YmljQmV6aWVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFBvaW50T25DdWJpY0JlemllcihwY3QsIHAxeCwgcDF5LCBwMngsIHAyeSwgcDN4LCBwM3ksIHA0eCwgcDR5KSB7XG4gICAgICB2YXIgeCA9IHA0eCAqIENCMShwY3QpICsgcDN4ICogQ0IyKHBjdCkgKyBwMnggKiBDQjMocGN0KSArIHAxeCAqIENCNChwY3QpO1xuICAgICAgdmFyIHkgPSBwNHkgKiBDQjEocGN0KSArIHAzeSAqIENCMihwY3QpICsgcDJ5ICogQ0IzKHBjdCkgKyBwMXkgKiBDQjQocGN0KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHg6IHgsXG4gICAgICAgIHk6IHlcbiAgICAgIH07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldFBvaW50T25RdWFkcmF0aWNCZXppZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0UG9pbnRPblF1YWRyYXRpY0JlemllcihwY3QsIHAxeCwgcDF5LCBwMngsIHAyeSwgcDN4LCBwM3kpIHtcbiAgICAgIHZhciB4ID0gcDN4ICogUUIxKHBjdCkgKyBwMnggKiBRQjIocGN0KSArIHAxeCAqIFFCMyhwY3QpO1xuICAgICAgdmFyIHkgPSBwM3kgKiBRQjEocGN0KSArIHAyeSAqIFFCMihwY3QpICsgcDF5ICogUUIzKHBjdCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB4OiB4LFxuICAgICAgICB5OiB5XG4gICAgICB9O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRQb2ludE9uRWxsaXB0aWNhbEFyY1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRQb2ludE9uRWxsaXB0aWNhbEFyYyhjeCwgY3ksIHJ4LCByeSwgdGhldGEsIHBzaSkge1xuICAgICAgdmFyIGNvc1BzaSA9IE1hdGguY29zKHBzaSk7XG4gICAgICB2YXIgc2luUHNpID0gTWF0aC5zaW4ocHNpKTtcbiAgICAgIHZhciBwdCA9IHtcbiAgICAgICAgeDogcnggKiBNYXRoLmNvcyh0aGV0YSksXG4gICAgICAgIHk6IHJ5ICogTWF0aC5zaW4odGhldGEpXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgeDogY3ggKyAocHQueCAqIGNvc1BzaSAtIHB0LnkgKiBzaW5Qc2kpLFxuICAgICAgICB5OiBjeSArIChwdC54ICogc2luUHNpICsgcHQueSAqIGNvc1BzaSlcbiAgICAgIH07XG4gICAgfSAvLyBUT0RPIG5lZWQgc29tZSBvcHRpbWlzYXRpb25zLiBwb3NzaWJseSBidWlsZCBjYWNoZSBvbmx5IGZvciBjdXJ2ZWQgc2VnbWVudHM/XG5cbiAgfSwge1xuICAgIGtleTogXCJidWlsZEVxdWlkaXN0YW50Q2FjaGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYnVpbGRFcXVpZGlzdGFudENhY2hlKGlucHV0U3RlcCwgaW5wdXRQcmVjaXNpb24pIHtcbiAgICAgIHZhciBmdWxsTGVuID0gdGhpcy5nZXRQYXRoTGVuZ3RoKCk7XG4gICAgICB2YXIgcHJlY2lzaW9uID0gaW5wdXRQcmVjaXNpb24gfHwgMC4yNTsgLy8gYWNjdXJhY3kgdnMgcGVyZm9ybWFuY2VcblxuICAgICAgdmFyIHN0ZXAgPSBpbnB1dFN0ZXAgfHwgZnVsbExlbiAvIDEwMDtcblxuICAgICAgaWYgKCF0aGlzLmVxdWlkaXN0YW50Q2FjaGUgfHwgdGhpcy5lcXVpZGlzdGFudENhY2hlLnN0ZXAgIT09IHN0ZXAgfHwgdGhpcy5lcXVpZGlzdGFudENhY2hlLnByZWNpc2lvbiAhPT0gcHJlY2lzaW9uKSB7XG4gICAgICAgIC8vIFByZXBhcmUgY2FjaGVcbiAgICAgICAgdGhpcy5lcXVpZGlzdGFudENhY2hlID0ge1xuICAgICAgICAgIHN0ZXA6IHN0ZXAsXG4gICAgICAgICAgcHJlY2lzaW9uOiBwcmVjaXNpb24sXG4gICAgICAgICAgcG9pbnRzOiBbXVxuICAgICAgICB9OyAvLyBDYWxjdWxhdGUgcG9pbnRzXG5cbiAgICAgICAgdmFyIHMgPSAwO1xuXG4gICAgICAgIGZvciAodmFyIGwgPSAwOyBsIDw9IGZ1bGxMZW47IGwgKz0gcHJlY2lzaW9uKSB7XG4gICAgICAgICAgdmFyIHAwID0gdGhpcy5nZXRQb2ludE9uUGF0aChsKTtcbiAgICAgICAgICB2YXIgcDEgPSB0aGlzLmdldFBvaW50T25QYXRoKGwgKyBwcmVjaXNpb24pO1xuXG4gICAgICAgICAgaWYgKCFwMCB8fCAhcDEpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHMgKz0gdGhpcy5nZXRMaW5lTGVuZ3RoKHAwLngsIHAwLnksIHAxLngsIHAxLnkpO1xuXG4gICAgICAgICAgaWYgKHMgPj0gc3RlcCkge1xuICAgICAgICAgICAgdGhpcy5lcXVpZGlzdGFudENhY2hlLnBvaW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgeDogcDAueCxcbiAgICAgICAgICAgICAgeTogcDAueSxcbiAgICAgICAgICAgICAgZGlzdGFuY2U6IGxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcyAtPSBzdGVwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRFcXVpZGlzdGFudFBvaW50T25QYXRoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEVxdWlkaXN0YW50UG9pbnRPblBhdGgodGFyZ2V0RGlzdGFuY2UsIHN0ZXAsIHByZWNpc2lvbikge1xuICAgICAgdGhpcy5idWlsZEVxdWlkaXN0YW50Q2FjaGUoc3RlcCwgcHJlY2lzaW9uKTtcblxuICAgICAgaWYgKHRhcmdldERpc3RhbmNlIDwgMCB8fCB0YXJnZXREaXN0YW5jZSAtIHRoaXMuZ2V0UGF0aExlbmd0aCgpID4gMC4wMDAwNSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdmFyIGlkeCA9IE1hdGgucm91bmQodGFyZ2V0RGlzdGFuY2UgLyB0aGlzLmdldFBhdGhMZW5ndGgoKSAqICh0aGlzLmVxdWlkaXN0YW50Q2FjaGUucG9pbnRzLmxlbmd0aCAtIDEpKTtcbiAgICAgIHJldHVybiB0aGlzLmVxdWlkaXN0YW50Q2FjaGUucG9pbnRzW2lkeF0gfHwgbnVsbDtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gVGV4dFBhdGhFbGVtZW50O1xufShUZXh0RWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRkKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGQoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGQoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgZGF0YVVyaVJlZ2V4ID0gL15cXHMqZGF0YTooKFteLyw7XStcXC9bXi8sO10rKSg/OjsoW14sOz1dKz1bXiw7PV0rKSk/KT8oPzo7KGJhc2U2NCkpPywoLiopJC9pO1xuXG52YXIgSW1hZ2VFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUmVuZGVyZWRFbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oSW1hZ2VFbGVtZW50LCBfUmVuZGVyZWRFbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJGQoSW1hZ2VFbGVtZW50KTtcblxuICBmdW5jdGlvbiBJbWFnZUVsZW1lbnQoZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIEltYWdlRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcbiAgICBfdGhpcy50eXBlID0gJ2ltYWdlJztcbiAgICBfdGhpcy5sb2FkZWQgPSBmYWxzZTtcblxuICAgIHZhciBocmVmID0gX3RoaXMuZ2V0SHJlZkF0dHJpYnV0ZSgpLmdldFN0cmluZygpO1xuXG4gICAgaWYgKCFocmVmKSB7XG4gICAgICByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKF90aGlzKTtcbiAgICB9XG5cbiAgICB2YXIgaXNTdmcgPSBocmVmLmVuZHNXaXRoKCcuc3ZnJykgfHwgL15cXHMqZGF0YTppbWFnZVxcL3N2Z1xcK3htbC9pLnRlc3QoaHJlZik7XG4gICAgZG9jdW1lbnQuaW1hZ2VzLnB1c2goX2Fzc2VydFRoaXNJbml0aWFsaXplZF9fZGVmYXVsdFtcImRlZmF1bHRcIl0oX3RoaXMpKTtcblxuICAgIGlmICghaXNTdmcpIHtcbiAgICAgIHZvaWQgX3RoaXMubG9hZEltYWdlKGhyZWYpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2b2lkIF90aGlzLmxvYWRTdmcoaHJlZik7XG4gICAgfVxuXG4gICAgX3RoaXMuaXNTdmcgPSBpc1N2ZztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEltYWdlRWxlbWVudCwgW3tcbiAgICBrZXk6IFwibG9hZEltYWdlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfbG9hZEltYWdlID0gX2FzeW5jVG9HZW5lcmF0b3JfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKCAvKiNfX1BVUkVfXyovX3JlZ2VuZXJhdG9yUnVudGltZV9fZGVmYXVsdFtcImRlZmF1bHRcIl0ubWFyayhmdW5jdGlvbiBfY2FsbGVlKGhyZWYpIHtcbiAgICAgICAgdmFyIGltYWdlO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yUnVudGltZV9fZGVmYXVsdFtcImRlZmF1bHRcIl0ud3JhcChmdW5jdGlvbiBfY2FsbGVlJChfY29udGV4dCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0LnByZXYgPSBfY29udGV4dC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfY29udGV4dC5wcmV2ID0gMDtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kb2N1bWVudC5jcmVhdGVJbWFnZShocmVmKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgaW1hZ2UgPSBfY29udGV4dC5zZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuaW1hZ2UgPSBpbWFnZTtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gMTA7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgIF9jb250ZXh0LnByZXYgPSA3O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0LnQwID0gX2NvbnRleHRbXCJjYXRjaFwiXSgwKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igd2hpbGUgbG9hZGluZyBpbWFnZSBcXFwiXCIuY29uY2F0KGhyZWYsIFwiXFxcIjpcIiksIF9jb250ZXh0LnQwKTtcblxuICAgICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICAgIHRoaXMubG9hZGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgICBjYXNlIDExOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUsIHRoaXMsIFtbMCwgN11dKTtcbiAgICAgIH0pKTtcblxuICAgICAgZnVuY3Rpb24gbG9hZEltYWdlKF94KSB7XG4gICAgICAgIHJldHVybiBfbG9hZEltYWdlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBsb2FkSW1hZ2U7XG4gICAgfSgpXG4gIH0sIHtcbiAgICBrZXk6IFwibG9hZFN2Z1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2xvYWRTdmcgPSBfYXN5bmNUb0dlbmVyYXRvcl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oIC8qI19fUFVSRV9fKi9fcmVnZW5lcmF0b3JSdW50aW1lX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUyKGhyZWYpIHtcbiAgICAgICAgdmFyIG1hdGNoLCBkYXRhLCByZXNwb25zZSwgc3ZnO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yUnVudGltZV9fZGVmYXVsdFtcImRlZmF1bHRcIl0ud3JhcChmdW5jdGlvbiBfY2FsbGVlMiQoX2NvbnRleHQyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgbWF0Y2ggPSBkYXRhVXJpUmVnZXguZXhlYyhocmVmKTtcblxuICAgICAgICAgICAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGRhdGEgPSBtYXRjaFs1XTtcblxuICAgICAgICAgICAgICAgIGlmIChtYXRjaFs0XSA9PT0gJ2Jhc2U2NCcpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuaW1hZ2UgPSBhdG9iKGRhdGEpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmltYWdlID0gZGVjb2RlVVJJQ29tcG9uZW50KGRhdGEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gMTk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIF9jb250ZXh0Mi5wcmV2ID0gNjtcbiAgICAgICAgICAgICAgICBfY29udGV4dDIubmV4dCA9IDk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnQuZmV0Y2goaHJlZik7XG5cbiAgICAgICAgICAgICAgY2FzZSA5OlxuICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gX2NvbnRleHQyLnNlbnQ7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSAxMjtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UudGV4dCgpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTI6XG4gICAgICAgICAgICAgICAgc3ZnID0gX2NvbnRleHQyLnNlbnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5pbWFnZSA9IHN2ZztcbiAgICAgICAgICAgICAgICBfY29udGV4dDIubmV4dCA9IDE5O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTY6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQyLnByZXYgPSAxNjtcbiAgICAgICAgICAgICAgICBfY29udGV4dDIudDAgPSBfY29udGV4dDJbXCJjYXRjaFwiXSg2KTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igd2hpbGUgbG9hZGluZyBpbWFnZSBcXFwiXCIuY29uY2F0KGhyZWYsIFwiXFxcIjpcIiksIF9jb250ZXh0Mi50MCk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxOTpcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgY2FzZSAyMDpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDIuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTIsIHRoaXMsIFtbNiwgMTZdXSk7XG4gICAgICB9KSk7XG5cbiAgICAgIGZ1bmN0aW9uIGxvYWRTdmcoX3gyKSB7XG4gICAgICAgIHJldHVybiBfbG9hZFN2Zy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbG9hZFN2ZztcbiAgICB9KClcbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJDaGlsZHJlblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXJDaGlsZHJlbihjdHgpIHtcbiAgICAgIHZhciBkb2N1bWVudCA9IHRoaXMuZG9jdW1lbnQsXG4gICAgICAgICAgaW1hZ2UgPSB0aGlzLmltYWdlLFxuICAgICAgICAgIGxvYWRlZCA9IHRoaXMubG9hZGVkO1xuICAgICAgdmFyIHggPSB0aGlzLmdldEF0dHJpYnV0ZSgneCcpLmdldFBpeGVscygneCcpO1xuICAgICAgdmFyIHkgPSB0aGlzLmdldEF0dHJpYnV0ZSgneScpLmdldFBpeGVscygneScpO1xuICAgICAgdmFyIHdpZHRoID0gdGhpcy5nZXRTdHlsZSgnd2lkdGgnKS5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgIHZhciBoZWlnaHQgPSB0aGlzLmdldFN0eWxlKCdoZWlnaHQnKS5nZXRQaXhlbHMoJ3knKTtcblxuICAgICAgaWYgKCFsb2FkZWQgfHwgIWltYWdlIHx8ICF3aWR0aCB8fCAhaGVpZ2h0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY3R4LnNhdmUoKTtcbiAgICAgIGN0eC50cmFuc2xhdGUoeCwgeSk7XG5cbiAgICAgIGlmICh0aGlzLmlzU3ZnKSB7XG4gICAgICAgIHZhciBzdWJEb2N1bWVudCA9IGRvY3VtZW50LmNhbnZnLmZvcmtTdHJpbmcoY3R4LCB0aGlzLmltYWdlLCB7XG4gICAgICAgICAgaWdub3JlTW91c2U6IHRydWUsXG4gICAgICAgICAgaWdub3JlQW5pbWF0aW9uOiB0cnVlLFxuICAgICAgICAgIGlnbm9yZURpbWVuc2lvbnM6IHRydWUsXG4gICAgICAgICAgaWdub3JlQ2xlYXI6IHRydWUsXG4gICAgICAgICAgb2Zmc2V0WDogMCxcbiAgICAgICAgICBvZmZzZXRZOiAwLFxuICAgICAgICAgIHNjYWxlV2lkdGg6IHdpZHRoLFxuICAgICAgICAgIHNjYWxlSGVpZ2h0OiBoZWlnaHRcbiAgICAgICAgfSk7XG4gICAgICAgIHN1YkRvY3VtZW50LmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5wYXJlbnQgPSB0aGlzO1xuICAgICAgICB2b2lkIHN1YkRvY3VtZW50LnJlbmRlcigpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIF9pbWFnZSA9IHRoaXMuaW1hZ2U7XG4gICAgICAgIGRvY3VtZW50LnNldFZpZXdCb3goe1xuICAgICAgICAgIGN0eDogY3R4LFxuICAgICAgICAgIGFzcGVjdFJhdGlvOiB0aGlzLmdldEF0dHJpYnV0ZSgncHJlc2VydmVBc3BlY3RSYXRpbycpLmdldFN0cmluZygpLFxuICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICBkZXNpcmVkV2lkdGg6IF9pbWFnZS53aWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgICBkZXNpcmVkSGVpZ2h0OiBfaW1hZ2UuaGVpZ2h0XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLmxvYWRlZCkge1xuICAgICAgICAgIGlmICh0eXBlb2YgX2ltYWdlLmNvbXBsZXRlID09PSAndW5kZWZpbmVkJyB8fCBfaW1hZ2UuY29tcGxldGUpIHtcbiAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoX2ltYWdlLCAwLCAwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0Qm91bmRpbmdCb3hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0Qm91bmRpbmdCb3goKSB7XG4gICAgICB2YXIgeCA9IHRoaXMuZ2V0QXR0cmlidXRlKCd4JykuZ2V0UGl4ZWxzKCd4Jyk7XG4gICAgICB2YXIgeSA9IHRoaXMuZ2V0QXR0cmlidXRlKCd5JykuZ2V0UGl4ZWxzKCd5Jyk7XG4gICAgICB2YXIgd2lkdGggPSB0aGlzLmdldFN0eWxlKCd3aWR0aCcpLmdldFBpeGVscygneCcpO1xuICAgICAgdmFyIGhlaWdodCA9IHRoaXMuZ2V0U3R5bGUoJ2hlaWdodCcpLmdldFBpeGVscygneScpO1xuICAgICAgcmV0dXJuIG5ldyBCb3VuZGluZ0JveCh4LCB5LCB4ICsgd2lkdGgsIHkgKyBoZWlnaHQpO1xuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBJbWFnZUVsZW1lbnQ7XG59KFJlbmRlcmVkRWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRjKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGMoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGMoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgU3ltYm9sRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1JlbmRlcmVkRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFN5bWJvbEVsZW1lbnQsIF9SZW5kZXJlZEVsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkYyhTeW1ib2xFbGVtZW50KTtcblxuICBmdW5jdGlvbiBTeW1ib2xFbGVtZW50KCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgU3ltYm9sRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF90aGlzLnR5cGUgPSAnc3ltYm9sJztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFN5bWJvbEVsZW1lbnQsIFt7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoXykgey8vIE5PIFJFTkRFUlxuICAgIH1cbiAgfV0pO1xuXG4gIHJldHVybiBTeW1ib2xFbGVtZW50O1xufShSZW5kZXJlZEVsZW1lbnQpO1xuXG52YXIgU1ZHRm9udExvYWRlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFNWR0ZvbnRMb2FkZXIoZG9jdW1lbnQpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFNWR0ZvbnRMb2FkZXIpO1xuXG4gICAgdGhpcy5kb2N1bWVudCA9IGRvY3VtZW50O1xuICAgIHRoaXMubG9hZGVkID0gZmFsc2U7XG4gICAgZG9jdW1lbnQuZm9udHMucHVzaCh0aGlzKTtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oU1ZHRm9udExvYWRlciwgW3tcbiAgICBrZXk6IFwibG9hZFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2xvYWQgPSBfYXN5bmNUb0dlbmVyYXRvcl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oIC8qI19fUFVSRV9fKi9fcmVnZW5lcmF0b3JSdW50aW1lX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUoZm9udEZhbWlseSwgdXJsKSB7XG4gICAgICAgIHZhciBkb2N1bWVudCwgc3ZnRG9jdW1lbnQsIGZvbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yUnVudGltZV9fZGVmYXVsdFtcImRlZmF1bHRcIl0ud3JhcChmdW5jdGlvbiBfY2FsbGVlJChfY29udGV4dCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0LnByZXYgPSBfY29udGV4dC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfY29udGV4dC5wcmV2ID0gMDtcbiAgICAgICAgICAgICAgICBkb2N1bWVudCA9IHRoaXMuZG9jdW1lbnQ7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LmNhbnZnLnBhcnNlci5sb2FkKHVybCk7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIHN2Z0RvY3VtZW50ID0gX2NvbnRleHQuc2VudDtcbiAgICAgICAgICAgICAgICBmb250cyA9IHN2Z0RvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdmb250Jyk7XG4gICAgICAgICAgICAgICAgQXJyYXkuZnJvbShmb250cykuZm9yRWFjaChmdW5jdGlvbiAoZm9udE5vZGUpIHtcbiAgICAgICAgICAgICAgICAgIHZhciBmb250ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChmb250Tm9kZSk7XG4gICAgICAgICAgICAgICAgICBkb2N1bWVudC5kZWZpbml0aW9uc1tmb250RmFtaWx5XSA9IGZvbnQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDEyO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgIGNhc2UgOTpcbiAgICAgICAgICAgICAgICBfY29udGV4dC5wcmV2ID0gOTtcbiAgICAgICAgICAgICAgICBfY29udGV4dC50MCA9IF9jb250ZXh0W1wiY2F0Y2hcIl0oMCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHdoaWxlIGxvYWRpbmcgZm9udCBcXFwiXCIuY29uY2F0KHVybCwgXCJcXFwiOlwiKSwgX2NvbnRleHQudDApO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTI6XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTM6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZSwgdGhpcywgW1swLCA5XV0pO1xuICAgICAgfSkpO1xuXG4gICAgICBmdW5jdGlvbiBsb2FkKF94LCBfeDIpIHtcbiAgICAgICAgcmV0dXJuIF9sb2FkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBsb2FkO1xuICAgIH0oKVxuICB9XSk7XG5cbiAgcmV0dXJuIFNWR0ZvbnRMb2FkZXI7XG59KCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciRiKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGIoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JGIoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgU3R5bGVFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFN0eWxlRWxlbWVudCwgX0VsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkYihTdHlsZUVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIFN0eWxlRWxlbWVudChkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcykge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgU3R5bGVFbGVtZW50KTtcblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgZG9jdW1lbnQsIG5vZGUsIGNhcHR1cmVUZXh0Tm9kZXMpO1xuICAgIF90aGlzLnR5cGUgPSAnc3R5bGUnO1xuICAgIHZhciBjc3MgPSBjb21wcmVzc1NwYWNlcyhBcnJheS5mcm9tKG5vZGUuY2hpbGROb2RlcykgLy8gTkVFRCBURVNUXG4gICAgLm1hcChmdW5jdGlvbiAoXykge1xuICAgICAgcmV0dXJuIF8udGV4dENvbnRlbnQ7XG4gICAgfSkuam9pbignJykucmVwbGFjZSgvKFxcL1xcKihbXipdfFtcXHJcXG5dfChcXCorKFteKi9dfFtcXHJcXG5dKSkpKlxcKitcXC8pfCheW1xcc10qXFwvXFwvLiopL2dtLCAnJykgLy8gcmVtb3ZlIGNvbW1lbnRzXG4gICAgLnJlcGxhY2UoL0BpbXBvcnQuKjsvZywgJycpIC8vIHJlbW92ZSBpbXBvcnRzXG4gICAgKTtcbiAgICB2YXIgY3NzRGVmcyA9IGNzcy5zcGxpdCgnfScpO1xuICAgIGNzc0RlZnMuZm9yRWFjaChmdW5jdGlvbiAoXykge1xuICAgICAgdmFyIGRlZiA9IF8udHJpbSgpO1xuXG4gICAgICBpZiAoIWRlZikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBjc3NQYXJ0cyA9IGRlZi5zcGxpdCgneycpO1xuICAgICAgdmFyIGNzc0NsYXNzZXMgPSBjc3NQYXJ0c1swXS5zcGxpdCgnLCcpO1xuICAgICAgdmFyIGNzc1Byb3BzID0gY3NzUGFydHNbMV0uc3BsaXQoJzsnKTtcbiAgICAgIGNzc0NsYXNzZXMuZm9yRWFjaChmdW5jdGlvbiAoXykge1xuICAgICAgICB2YXIgY3NzQ2xhc3MgPSBfLnRyaW0oKTtcblxuICAgICAgICBpZiAoIWNzc0NsYXNzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHByb3BzID0gZG9jdW1lbnQuc3R5bGVzW2Nzc0NsYXNzXSB8fCB7fTtcbiAgICAgICAgY3NzUHJvcHMuZm9yRWFjaChmdW5jdGlvbiAoY3NzUHJvcCkge1xuICAgICAgICAgIHZhciBwcm9wID0gY3NzUHJvcC5pbmRleE9mKCc6Jyk7XG4gICAgICAgICAgdmFyIG5hbWUgPSBjc3NQcm9wLnN1YnN0cigwLCBwcm9wKS50cmltKCk7XG4gICAgICAgICAgdmFyIHZhbHVlID0gY3NzUHJvcC5zdWJzdHIocHJvcCArIDEsIGNzc1Byb3AubGVuZ3RoIC0gcHJvcCkudHJpbSgpO1xuXG4gICAgICAgICAgaWYgKG5hbWUgJiYgdmFsdWUpIHtcbiAgICAgICAgICAgIHByb3BzW25hbWVdID0gbmV3IFByb3BlcnR5KGRvY3VtZW50LCBuYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgZG9jdW1lbnQuc3R5bGVzW2Nzc0NsYXNzXSA9IHByb3BzO1xuICAgICAgICBkb2N1bWVudC5zdHlsZXNTcGVjaWZpY2l0eVtjc3NDbGFzc10gPSBnZXRTZWxlY3RvclNwZWNpZmljaXR5KGNzc0NsYXNzKTtcblxuICAgICAgICBpZiAoY3NzQ2xhc3MgPT09ICdAZm9udC1mYWNlJykge1xuICAgICAgICAgIC8vICAmJiAhbm9kZUVudlxuICAgICAgICAgIHZhciBmb250RmFtaWx5ID0gcHJvcHNbJ2ZvbnQtZmFtaWx5J10uZ2V0U3RyaW5nKCkucmVwbGFjZSgvXCJ8Jy9nLCAnJyk7XG4gICAgICAgICAgdmFyIHNyY3MgPSBwcm9wcy5zcmMuZ2V0U3RyaW5nKCkuc3BsaXQoJywnKTtcbiAgICAgICAgICBzcmNzLmZvckVhY2goZnVuY3Rpb24gKHNyYykge1xuICAgICAgICAgICAgaWYgKHNyYy5pbmRleE9mKCdmb3JtYXQoXCJzdmdcIiknKSA+IDApIHtcbiAgICAgICAgICAgICAgdmFyIHVybCA9IHBhcnNlRXh0ZXJuYWxVcmwoc3JjKTtcblxuICAgICAgICAgICAgICBpZiAodXJsKSB7XG4gICAgICAgICAgICAgICAgdm9pZCBuZXcgU1ZHRm9udExvYWRlcihkb2N1bWVudCkubG9hZChmb250RmFtaWx5LCB1cmwpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIHJldHVybiBTdHlsZUVsZW1lbnQ7XG59KEVsZW1lbnQpO1xuU3R5bGVFbGVtZW50LnBhcnNlRXh0ZXJuYWxVcmwgPSBwYXJzZUV4dGVybmFsVXJsO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkYShEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRhKCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCRhKCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIFVzZUVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9SZW5kZXJlZEVsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShVc2VFbGVtZW50LCBfUmVuZGVyZWRFbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJGEoVXNlRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gVXNlRWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFVzZUVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfdGhpcy50eXBlID0gJ3VzZSc7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShVc2VFbGVtZW50LCBbe1xuICAgIGtleTogXCJzZXRDb250ZXh0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldENvbnRleHQoY3R4KSB7XG4gICAgICBfZ2V0X19kZWZhdWx0W1wiZGVmYXVsdFwiXShfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFVzZUVsZW1lbnQucHJvdG90eXBlKSwgXCJzZXRDb250ZXh0XCIsIHRoaXMpLmNhbGwodGhpcywgY3R4KTtcblxuICAgICAgdmFyIHhBdHRyID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3gnKTtcbiAgICAgIHZhciB5QXR0ciA9IHRoaXMuZ2V0QXR0cmlidXRlKCd5Jyk7XG5cbiAgICAgIGlmICh4QXR0ci5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIGN0eC50cmFuc2xhdGUoeEF0dHIuZ2V0UGl4ZWxzKCd4JyksIDApO1xuICAgICAgfVxuXG4gICAgICBpZiAoeUF0dHIuaGFzVmFsdWUoKSkge1xuICAgICAgICBjdHgudHJhbnNsYXRlKDAsIHlBdHRyLmdldFBpeGVscygneScpKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicGF0aFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBwYXRoKGN0eCkge1xuICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQ7XG5cbiAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgIGVsZW1lbnQucGF0aChjdHgpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJDaGlsZHJlblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXJDaGlsZHJlbihjdHgpIHtcbiAgICAgIHZhciBkb2N1bWVudCA9IHRoaXMuZG9jdW1lbnQsXG4gICAgICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblxuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHRlbXBTdmcgPSBlbGVtZW50O1xuXG4gICAgICAgIGlmIChlbGVtZW50LnR5cGUgPT09ICdzeW1ib2wnKSB7XG4gICAgICAgICAgLy8gcmVuZGVyIG1lIHVzaW5nIGEgdGVtcG9yYXJ5IHN2ZyBlbGVtZW50IGluIHN5bWJvbCBjYXNlcyAoaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHL3N0cnVjdC5odG1sI1VzZUVsZW1lbnQpXG4gICAgICAgICAgdGVtcFN2ZyA9IG5ldyBTVkdFbGVtZW50KGRvY3VtZW50LCBudWxsKTtcbiAgICAgICAgICB0ZW1wU3ZnLmF0dHJpYnV0ZXMudmlld0JveCA9IG5ldyBQcm9wZXJ0eShkb2N1bWVudCwgJ3ZpZXdCb3gnLCBlbGVtZW50LmdldEF0dHJpYnV0ZSgndmlld0JveCcpLmdldFN0cmluZygpKTtcbiAgICAgICAgICB0ZW1wU3ZnLmF0dHJpYnV0ZXMucHJlc2VydmVBc3BlY3RSYXRpbyA9IG5ldyBQcm9wZXJ0eShkb2N1bWVudCwgJ3ByZXNlcnZlQXNwZWN0UmF0aW8nLCBlbGVtZW50LmdldEF0dHJpYnV0ZSgncHJlc2VydmVBc3BlY3RSYXRpbycpLmdldFN0cmluZygpKTtcbiAgICAgICAgICB0ZW1wU3ZnLmF0dHJpYnV0ZXMub3ZlcmZsb3cgPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICdvdmVyZmxvdycsIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdvdmVyZmxvdycpLmdldFN0cmluZygpKTtcbiAgICAgICAgICB0ZW1wU3ZnLmNoaWxkcmVuID0gZWxlbWVudC5jaGlsZHJlbjsgLy8gZWxlbWVudCBpcyBzdGlsbCB0aGUgcGFyZW50IG9mIHRoZSBjaGlsZHJlblxuXG4gICAgICAgICAgZWxlbWVudC5zdHlsZXMub3BhY2l0eSA9IG5ldyBQcm9wZXJ0eShkb2N1bWVudCwgJ29wYWNpdHknLCB0aGlzLmNhbGN1bGF0ZU9wYWNpdHkoKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGVtcFN2Zy50eXBlID09PSAnc3ZnJykge1xuICAgICAgICAgIHZhciB3aWR0aFN0eWxlID0gdGhpcy5nZXRTdHlsZSgnd2lkdGgnLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgICAgdmFyIGhlaWdodFN0eWxlID0gdGhpcy5nZXRTdHlsZSgnaGVpZ2h0JywgZmFsc2UsIHRydWUpOyAvLyBpZiBzeW1ib2wgb3Igc3ZnLCBpbmhlcml0IHdpZHRoL2hlaWdodCBmcm9tIG1lXG5cbiAgICAgICAgICBpZiAod2lkdGhTdHlsZS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICB0ZW1wU3ZnLmF0dHJpYnV0ZXMud2lkdGggPSBuZXcgUHJvcGVydHkoZG9jdW1lbnQsICd3aWR0aCcsIHdpZHRoU3R5bGUuZ2V0U3RyaW5nKCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChoZWlnaHRTdHlsZS5oYXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICB0ZW1wU3ZnLmF0dHJpYnV0ZXMuaGVpZ2h0ID0gbmV3IFByb3BlcnR5KGRvY3VtZW50LCAnaGVpZ2h0JywgaGVpZ2h0U3R5bGUuZ2V0U3RyaW5nKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvbGRQYXJlbnQgPSB0ZW1wU3ZnLnBhcmVudDtcbiAgICAgICAgdGVtcFN2Zy5wYXJlbnQgPSB0aGlzO1xuICAgICAgICB0ZW1wU3ZnLnJlbmRlcihjdHgpO1xuICAgICAgICB0ZW1wU3ZnLnBhcmVudCA9IG9sZFBhcmVudDtcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0Qm91bmRpbmdCb3hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0Qm91bmRpbmdCb3goY3R4KSB7XG4gICAgICB2YXIgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblxuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQuZ2V0Qm91bmRpbmdCb3goY3R4KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImVsZW1lbnRUcmFuc2Zvcm1cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZWxlbWVudFRyYW5zZm9ybSgpIHtcbiAgICAgIHZhciBkb2N1bWVudCA9IHRoaXMuZG9jdW1lbnQsXG4gICAgICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcbiAgICAgIHJldHVybiBUcmFuc2Zvcm0uZnJvbUVsZW1lbnQoZG9jdW1lbnQsIGVsZW1lbnQpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJlbGVtZW50XCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICBpZiAoIXRoaXMuY2FjaGVkRWxlbWVudCkge1xuICAgICAgICB0aGlzLmNhY2hlZEVsZW1lbnQgPSB0aGlzLmdldEhyZWZBdHRyaWJ1dGUoKS5nZXREZWZpbml0aW9uKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmNhY2hlZEVsZW1lbnQ7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIFVzZUVsZW1lbnQ7XG59KFJlbmRlcmVkRWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciQ5KERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JDkoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JDkoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG5mdW5jdGlvbiBpbUdldChpbWcsIHgsIHksIHdpZHRoLCBfaGVpZ2h0LCByZ2JhKSB7XG4gIHJldHVybiBpbWdbeSAqIHdpZHRoICogNCArIHggKiA0ICsgcmdiYV07XG59XG5cbmZ1bmN0aW9uIGltU2V0KGltZywgeCwgeSwgd2lkdGgsIF9oZWlnaHQsIHJnYmEsIHZhbCkge1xuICBpbWdbeSAqIHdpZHRoICogNCArIHggKiA0ICsgcmdiYV0gPSB2YWw7XG59XG5cbmZ1bmN0aW9uIG0obWF0cml4LCBpLCB2KSB7XG4gIHZhciBtaSA9IG1hdHJpeFtpXTtcbiAgcmV0dXJuIG1pICogdjtcbn1cblxuZnVuY3Rpb24gYyhhLCBtMSwgbTIsIG0zKSB7XG4gIHJldHVybiBtMSArIE1hdGguY29zKGEpICogbTIgKyBNYXRoLnNpbihhKSAqIG0zO1xufVxuXG52YXIgRmVDb2xvck1hdHJpeEVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9FbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oRmVDb2xvck1hdHJpeEVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJDkoRmVDb2xvck1hdHJpeEVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIEZlQ29sb3JNYXRyaXhFbGVtZW50KGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBGZUNvbG9yTWF0cml4RWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcbiAgICBfdGhpcy50eXBlID0gJ2ZlQ29sb3JNYXRyaXgnO1xuICAgIHZhciBtYXRyaXggPSB0b051bWJlcnMoX3RoaXMuZ2V0QXR0cmlidXRlKCd2YWx1ZXMnKS5nZXRTdHJpbmcoKSk7XG5cbiAgICBzd2l0Y2ggKF90aGlzLmdldEF0dHJpYnV0ZSgndHlwZScpLmdldFN0cmluZygnbWF0cml4JykpIHtcbiAgICAgIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL1NWRy9maWx0ZXJzLmh0bWwjZmVDb2xvck1hdHJpeEVsZW1lbnRcbiAgICAgIGNhc2UgJ3NhdHVyYXRlJzpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBzID0gbWF0cml4WzBdO1xuICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIGFycmF5LWVsZW1lbnQtbmV3bGluZSAqL1xuXG4gICAgICAgICAgbWF0cml4ID0gWzAuMjEzICsgMC43ODcgKiBzLCAwLjcxNSAtIDAuNzE1ICogcywgMC4wNzIgLSAwLjA3MiAqIHMsIDAsIDAsIDAuMjEzIC0gMC4yMTMgKiBzLCAwLjcxNSArIDAuMjg1ICogcywgMC4wNzIgLSAwLjA3MiAqIHMsIDAsIDAsIDAuMjEzIC0gMC4yMTMgKiBzLCAwLjcxNSAtIDAuNzE1ICogcywgMC4wNzIgKyAwLjkyOCAqIHMsIDAsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDFdO1xuICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgYXJyYXktZWxlbWVudC1uZXdsaW5lICovXG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlICdodWVSb3RhdGUnOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGEgPSBtYXRyaXhbMF0gKiBNYXRoLlBJIC8gMTgwLjA7XG4gICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgYXJyYXktZWxlbWVudC1uZXdsaW5lICovXG5cbiAgICAgICAgICBtYXRyaXggPSBbYyhhLCAwLjIxMywgMC43ODcsIC0wLjIxMyksIGMoYSwgMC43MTUsIC0wLjcxNSwgLTAuNzE1KSwgYyhhLCAwLjA3MiwgLTAuMDcyLCAwLjkyOCksIDAsIDAsIGMoYSwgMC4yMTMsIC0wLjIxMywgMC4xNDMpLCBjKGEsIDAuNzE1LCAwLjI4NSwgMC4xNDApLCBjKGEsIDAuMDcyLCAtMC4wNzIsIC0wLjI4MyksIDAsIDAsIGMoYSwgMC4yMTMsIC0wLjIxMywgLTAuNzg3KSwgYyhhLCAwLjcxNSwgLTAuNzE1LCAwLjcxNSksIGMoYSwgMC4wNzIsIDAuOTI4LCAwLjA3MiksIDAsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDFdO1xuICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgYXJyYXktZWxlbWVudC1uZXdsaW5lICovXG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlICdsdW1pbmFuY2VUb0FscGhhJzpcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgYXJyYXktZWxlbWVudC1uZXdsaW5lICovXG4gICAgICAgIG1hdHJpeCA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLjIxMjUsIDAuNzE1NCwgMC4wNzIxLCAwLCAwLCAwLCAwLCAwLCAwLCAxXTtcbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBhcnJheS1lbGVtZW50LW5ld2xpbmUgKi9cblxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBfdGhpcy5tYXRyaXggPSBtYXRyaXg7XG4gICAgX3RoaXMuaW5jbHVkZU9wYWNpdHkgPSBfdGhpcy5nZXRBdHRyaWJ1dGUoJ2luY2x1ZGVPcGFjaXR5JykuaGFzVmFsdWUoKTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEZlQ29sb3JNYXRyaXhFbGVtZW50LCBbe1xuICAgIGtleTogXCJhcHBseVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhcHBseShjdHgsIF94LCBfeSwgd2lkdGgsIGhlaWdodCkge1xuICAgICAgLy8gYXNzdW1pbmcgeD09MCAmJiB5PT0wIGZvciBub3dcbiAgICAgIHZhciBpbmNsdWRlT3BhY2l0eSA9IHRoaXMuaW5jbHVkZU9wYWNpdHksXG4gICAgICAgICAgbWF0cml4ID0gdGhpcy5tYXRyaXg7XG4gICAgICB2YXIgc3JjRGF0YSA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAgIGZvciAodmFyIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHtcbiAgICAgICAgZm9yICh2YXIgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7XG4gICAgICAgICAgdmFyIHIgPSBpbUdldChzcmNEYXRhLmRhdGEsIHgsIHksIHdpZHRoLCBoZWlnaHQsIDApO1xuICAgICAgICAgIHZhciBnID0gaW1HZXQoc3JjRGF0YS5kYXRhLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCAxKTtcbiAgICAgICAgICB2YXIgYiA9IGltR2V0KHNyY0RhdGEuZGF0YSwgeCwgeSwgd2lkdGgsIGhlaWdodCwgMik7XG4gICAgICAgICAgdmFyIGEgPSBpbUdldChzcmNEYXRhLmRhdGEsIHgsIHksIHdpZHRoLCBoZWlnaHQsIDMpO1xuICAgICAgICAgIHZhciBuciA9IG0obWF0cml4LCAwLCByKSArIG0obWF0cml4LCAxLCBnKSArIG0obWF0cml4LCAyLCBiKSArIG0obWF0cml4LCAzLCBhKSArIG0obWF0cml4LCA0LCAxKTtcbiAgICAgICAgICB2YXIgbmcgPSBtKG1hdHJpeCwgNSwgcikgKyBtKG1hdHJpeCwgNiwgZykgKyBtKG1hdHJpeCwgNywgYikgKyBtKG1hdHJpeCwgOCwgYSkgKyBtKG1hdHJpeCwgOSwgMSk7XG4gICAgICAgICAgdmFyIG5iID0gbShtYXRyaXgsIDEwLCByKSArIG0obWF0cml4LCAxMSwgZykgKyBtKG1hdHJpeCwgMTIsIGIpICsgbShtYXRyaXgsIDEzLCBhKSArIG0obWF0cml4LCAxNCwgMSk7XG4gICAgICAgICAgdmFyIG5hID0gbShtYXRyaXgsIDE1LCByKSArIG0obWF0cml4LCAxNiwgZykgKyBtKG1hdHJpeCwgMTcsIGIpICsgbShtYXRyaXgsIDE4LCBhKSArIG0obWF0cml4LCAxOSwgMSk7XG5cbiAgICAgICAgICBpZiAoaW5jbHVkZU9wYWNpdHkpIHtcbiAgICAgICAgICAgIG5yID0gMDtcbiAgICAgICAgICAgIG5nID0gMDtcbiAgICAgICAgICAgIG5iID0gMDtcbiAgICAgICAgICAgIG5hICo9IGEgLyAyNTU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaW1TZXQoc3JjRGF0YS5kYXRhLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCAwLCBucik7XG4gICAgICAgICAgaW1TZXQoc3JjRGF0YS5kYXRhLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCAxLCBuZyk7XG4gICAgICAgICAgaW1TZXQoc3JjRGF0YS5kYXRhLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCAyLCBuYik7XG4gICAgICAgICAgaW1TZXQoc3JjRGF0YS5kYXRhLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCAzLCBuYSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIGN0eC5wdXRJbWFnZURhdGEoc3JjRGF0YSwgMCwgMCk7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIEZlQ29sb3JNYXRyaXhFbGVtZW50O1xufShFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJDgoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkOCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkOCgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBNYXNrRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX0VsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShNYXNrRWxlbWVudCwgX0VsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkOChNYXNrRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gTWFza0VsZW1lbnQoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBNYXNrRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF90aGlzLnR5cGUgPSAnbWFzayc7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShNYXNrRWxlbWVudCwgW3tcbiAgICBrZXk6IFwiYXBwbHlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYXBwbHkoY3R4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgZG9jdW1lbnQgPSB0aGlzLmRvY3VtZW50OyAvLyByZW5kZXIgYXMgdGVtcCBzdmdcblxuICAgICAgdmFyIHggPSB0aGlzLmdldEF0dHJpYnV0ZSgneCcpLmdldFBpeGVscygneCcpO1xuICAgICAgdmFyIHkgPSB0aGlzLmdldEF0dHJpYnV0ZSgneScpLmdldFBpeGVscygneScpO1xuICAgICAgdmFyIHdpZHRoID0gdGhpcy5nZXRTdHlsZSgnd2lkdGgnKS5nZXRQaXhlbHMoJ3gnKTtcbiAgICAgIHZhciBoZWlnaHQgPSB0aGlzLmdldFN0eWxlKCdoZWlnaHQnKS5nZXRQaXhlbHMoJ3knKTtcblxuICAgICAgaWYgKCF3aWR0aCAmJiAhaGVpZ2h0KSB7XG4gICAgICAgIHZhciBib3VuZGluZ0JveCA9IG5ldyBCb3VuZGluZ0JveCgpO1xuICAgICAgICB0aGlzLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgYm91bmRpbmdCb3guYWRkQm91bmRpbmdCb3goY2hpbGQuZ2V0Qm91bmRpbmdCb3goY3R4KSk7XG4gICAgICAgIH0pO1xuICAgICAgICB4ID0gTWF0aC5mbG9vcihib3VuZGluZ0JveC54MSk7XG4gICAgICAgIHkgPSBNYXRoLmZsb29yKGJvdW5kaW5nQm94LnkxKTtcbiAgICAgICAgd2lkdGggPSBNYXRoLmZsb29yKGJvdW5kaW5nQm94LndpZHRoKTtcbiAgICAgICAgaGVpZ2h0ID0gTWF0aC5mbG9vcihib3VuZGluZ0JveC5oZWlnaHQpO1xuICAgICAgfVxuXG4gICAgICB2YXIgaWdub3JlZFN0eWxlcyA9IHRoaXMucmVtb3ZlU3R5bGVzKGVsZW1lbnQsIE1hc2tFbGVtZW50Lmlnbm9yZVN0eWxlcyk7XG4gICAgICB2YXIgbWFza0NhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUNhbnZhcyh4ICsgd2lkdGgsIHkgKyBoZWlnaHQpO1xuICAgICAgdmFyIG1hc2tDdHggPSBtYXNrQ2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICBkb2N1bWVudC5zY3JlZW4uc2V0RGVmYXVsdHMobWFza0N0eCk7XG4gICAgICB0aGlzLnJlbmRlckNoaWxkcmVuKG1hc2tDdHgpOyAvLyBjb252ZXJ0IG1hc2sgdG8gYWxwaGEgd2l0aCBhIGZha2Ugbm9kZVxuICAgICAgLy8gVE9ETzogcmVmYWN0b3Igb3V0IGFwcGx5IGZyb20gZmVDb2xvck1hdHJpeFxuXG4gICAgICBuZXcgRmVDb2xvck1hdHJpeEVsZW1lbnQoZG9jdW1lbnQsIHtcbiAgICAgICAgbm9kZVR5cGU6IDEsXG4gICAgICAgIGNoaWxkTm9kZXM6IFtdLFxuICAgICAgICBhdHRyaWJ1dGVzOiBbe1xuICAgICAgICAgIG5vZGVOYW1lOiAndHlwZScsXG4gICAgICAgICAgdmFsdWU6ICdsdW1pbmFuY2VUb0FscGhhJ1xuICAgICAgICB9LCB7XG4gICAgICAgICAgbm9kZU5hbWU6ICdpbmNsdWRlT3BhY2l0eScsXG4gICAgICAgICAgdmFsdWU6ICd0cnVlJ1xuICAgICAgICB9XVxuICAgICAgfSkuYXBwbHkobWFza0N0eCwgMCwgMCwgeCArIHdpZHRoLCB5ICsgaGVpZ2h0KTtcbiAgICAgIHZhciB0bXBDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVDYW52YXMoeCArIHdpZHRoLCB5ICsgaGVpZ2h0KTtcbiAgICAgIHZhciB0bXBDdHggPSB0bXBDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgIGRvY3VtZW50LnNjcmVlbi5zZXREZWZhdWx0cyh0bXBDdHgpO1xuICAgICAgZWxlbWVudC5yZW5kZXIodG1wQ3R4KTtcbiAgICAgIHRtcEN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnZGVzdGluYXRpb24taW4nO1xuICAgICAgdG1wQ3R4LmZpbGxTdHlsZSA9IG1hc2tDdHguY3JlYXRlUGF0dGVybihtYXNrQ2FudmFzLCAnbm8tcmVwZWF0Jyk7XG4gICAgICB0bXBDdHguZmlsbFJlY3QoMCwgMCwgeCArIHdpZHRoLCB5ICsgaGVpZ2h0KTtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSB0bXBDdHguY3JlYXRlUGF0dGVybih0bXBDYW52YXMsICduby1yZXBlYXQnKTtcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCB4ICsgd2lkdGgsIHkgKyBoZWlnaHQpOyAvLyByZWFzc2lnbiBtYXNrXG5cbiAgICAgIHRoaXMucmVzdG9yZVN0eWxlcyhlbGVtZW50LCBpZ25vcmVkU3R5bGVzKTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwicmVuZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcihfKSB7Ly8gTk8gUkVOREVSXG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIE1hc2tFbGVtZW50O1xufShFbGVtZW50KTtcbk1hc2tFbGVtZW50Lmlnbm9yZVN0eWxlcyA9IFsnbWFzaycsICd0cmFuc2Zvcm0nLCAnY2xpcC1wYXRoJ107XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciQ3KERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JDcoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JDcoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgbm9vcCA9IGZ1bmN0aW9uIG5vb3AoKSB7Ly8gTk9PUFxufTtcblxudmFyIENsaXBQYXRoRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX0VsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShDbGlwUGF0aEVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJDcoQ2xpcFBhdGhFbGVtZW50KTtcblxuICBmdW5jdGlvbiBDbGlwUGF0aEVsZW1lbnQoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBDbGlwUGF0aEVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfdGhpcy50eXBlID0gJ2NsaXBQYXRoJztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKENsaXBQYXRoRWxlbWVudCwgW3tcbiAgICBrZXk6IFwiYXBwbHlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYXBwbHkoY3R4KSB7XG4gICAgICB2YXIgZG9jdW1lbnQgPSB0aGlzLmRvY3VtZW50O1xuICAgICAgdmFyIGNvbnRleHRQcm90byA9IFJlZmxlY3QuZ2V0UHJvdG90eXBlT2YoY3R4KTtcbiAgICAgIHZhciBiZWdpblBhdGggPSBjdHguYmVnaW5QYXRoLFxuICAgICAgICAgIGNsb3NlUGF0aCA9IGN0eC5jbG9zZVBhdGg7XG5cbiAgICAgIGlmIChjb250ZXh0UHJvdG8pIHtcbiAgICAgICAgY29udGV4dFByb3RvLmJlZ2luUGF0aCA9IG5vb3A7XG4gICAgICAgIGNvbnRleHRQcm90by5jbG9zZVBhdGggPSBub29wO1xuICAgICAgfVxuXG4gICAgICBSZWZsZWN0LmFwcGx5KGJlZ2luUGF0aCwgY3R4LCBbXSk7XG4gICAgICB0aGlzLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2hpbGQucGF0aCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdHJhbnNmb3JtID0gdHlwZW9mIGNoaWxkLmVsZW1lbnRUcmFuc2Zvcm0gIT09ICd1bmRlZmluZWQnID8gY2hpbGQuZWxlbWVudFRyYW5zZm9ybSgpIDogbnVsbDsgLy8gaGFuZGxlIDx1c2UgLz5cblxuICAgICAgICBpZiAoIXRyYW5zZm9ybSkge1xuICAgICAgICAgIHRyYW5zZm9ybSA9IFRyYW5zZm9ybS5mcm9tRWxlbWVudChkb2N1bWVudCwgY2hpbGQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRyYW5zZm9ybSkge1xuICAgICAgICAgIHRyYW5zZm9ybS5hcHBseShjdHgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQucGF0aChjdHgpO1xuXG4gICAgICAgIGlmIChjb250ZXh0UHJvdG8pIHtcbiAgICAgICAgICBjb250ZXh0UHJvdG8uY2xvc2VQYXRoID0gY2xvc2VQYXRoO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRyYW5zZm9ybSkge1xuICAgICAgICAgIHRyYW5zZm9ybS51bmFwcGx5KGN0eCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgUmVmbGVjdC5hcHBseShjbG9zZVBhdGgsIGN0eCwgW10pO1xuICAgICAgY3R4LmNsaXAoKTtcblxuICAgICAgaWYgKGNvbnRleHRQcm90bykge1xuICAgICAgICBjb250ZXh0UHJvdG8uYmVnaW5QYXRoID0gYmVnaW5QYXRoO1xuICAgICAgICBjb250ZXh0UHJvdG8uY2xvc2VQYXRoID0gY2xvc2VQYXRoO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKF8pIHsvLyBOTyBSRU5ERVJcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gQ2xpcFBhdGhFbGVtZW50O1xufShFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJDYoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkNigpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkNigpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBGaWx0ZXJFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEZpbHRlckVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJDYoRmlsdGVyRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gRmlsdGVyRWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIEZpbHRlckVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfdGhpcy50eXBlID0gJ2ZpbHRlcic7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShGaWx0ZXJFbGVtZW50LCBbe1xuICAgIGtleTogXCJhcHBseVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBhcHBseShjdHgsIGVsZW1lbnQpIHtcbiAgICAgIC8vIHJlbmRlciBhcyB0ZW1wIHN2Z1xuICAgICAgdmFyIGRvY3VtZW50ID0gdGhpcy5kb2N1bWVudCxcbiAgICAgICAgICBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XG4gICAgICB2YXIgYm91bmRpbmdCb3ggPSBlbGVtZW50LmdldEJvdW5kaW5nQm94KGN0eCk7XG5cbiAgICAgIGlmICghYm91bmRpbmdCb3gpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgcHggPSAwO1xuICAgICAgdmFyIHB5ID0gMDtcbiAgICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIHZhciBlZmQgPSBjaGlsZC5leHRyYUZpbHRlckRpc3RhbmNlIHx8IDA7XG4gICAgICAgIHB4ID0gTWF0aC5tYXgocHgsIGVmZCk7XG4gICAgICAgIHB5ID0gTWF0aC5tYXgocHksIGVmZCk7XG4gICAgICB9KTtcbiAgICAgIHZhciB3aWR0aCA9IE1hdGguZmxvb3IoYm91bmRpbmdCb3gud2lkdGgpO1xuICAgICAgdmFyIGhlaWdodCA9IE1hdGguZmxvb3IoYm91bmRpbmdCb3guaGVpZ2h0KTtcbiAgICAgIHZhciB0bXBDYW52YXNXaWR0aCA9IHdpZHRoICsgMiAqIHB4O1xuICAgICAgdmFyIHRtcENhbnZhc0hlaWdodCA9IGhlaWdodCArIDIgKiBweTtcblxuICAgICAgaWYgKHRtcENhbnZhc1dpZHRoIDwgMSB8fCB0bXBDYW52YXNIZWlnaHQgPCAxKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHggPSBNYXRoLmZsb29yKGJvdW5kaW5nQm94LngpO1xuICAgICAgdmFyIHkgPSBNYXRoLmZsb29yKGJvdW5kaW5nQm94LnkpO1xuICAgICAgdmFyIGlnbm9yZWRTdHlsZXMgPSB0aGlzLnJlbW92ZVN0eWxlcyhlbGVtZW50LCBGaWx0ZXJFbGVtZW50Lmlnbm9yZVN0eWxlcyk7XG4gICAgICB2YXIgdG1wQ2FudmFzID0gZG9jdW1lbnQuY3JlYXRlQ2FudmFzKHRtcENhbnZhc1dpZHRoLCB0bXBDYW52YXNIZWlnaHQpO1xuICAgICAgdmFyIHRtcEN0eCA9IHRtcENhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgZG9jdW1lbnQuc2NyZWVuLnNldERlZmF1bHRzKHRtcEN0eCk7XG4gICAgICB0bXBDdHgudHJhbnNsYXRlKC14ICsgcHgsIC15ICsgcHkpO1xuICAgICAgZWxlbWVudC5yZW5kZXIodG1wQ3R4KTsgLy8gYXBwbHkgZmlsdGVyc1xuXG4gICAgICBjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICBpZiAodHlwZW9mIGNoaWxkLmFwcGx5ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgY2hpbGQuYXBwbHkodG1wQ3R4LCAwLCAwLCB0bXBDYW52YXNXaWR0aCwgdG1wQ2FudmFzSGVpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgfSk7IC8vIHJlbmRlciBvbiBtZVxuXG4gICAgICBjdHguZHJhd0ltYWdlKHRtcENhbnZhcywgMCwgMCwgdG1wQ2FudmFzV2lkdGgsIHRtcENhbnZhc0hlaWdodCwgeCAtIHB4LCB5IC0gcHksIHRtcENhbnZhc1dpZHRoLCB0bXBDYW52YXNIZWlnaHQpO1xuICAgICAgdGhpcy5yZXN0b3JlU3R5bGVzKGVsZW1lbnQsIGlnbm9yZWRTdHlsZXMpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKF8pIHsvLyBOTyBSRU5ERVJcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gRmlsdGVyRWxlbWVudDtcbn0oRWxlbWVudCk7XG5GaWx0ZXJFbGVtZW50Lmlnbm9yZVN0eWxlcyA9IFsnZmlsdGVyJywgJ3RyYW5zZm9ybScsICdjbGlwLXBhdGgnXTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJDUoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkNSgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkNSgpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBGZURyb3BTaGFkb3dFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEZlRHJvcFNoYWRvd0VsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJDUoRmVEcm9wU2hhZG93RWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gRmVEcm9wU2hhZG93RWxlbWVudChkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcykge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgRmVEcm9wU2hhZG93RWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKTtcbiAgICBfdGhpcy50eXBlID0gJ2ZlRHJvcFNoYWRvdyc7XG5cbiAgICBfdGhpcy5hZGRTdHlsZXNGcm9tU3R5bGVEZWZpbml0aW9uKCk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEZlRHJvcFNoYWRvd0VsZW1lbnQsIFt7XG4gICAga2V5OiBcImFwcGx5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGx5KF8sIF94LCBfeSwgX3dpZHRoLCBfaGVpZ2h0KSB7Ly8gVE9ETzogaW1wbGVtZW50XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIEZlRHJvcFNoYWRvd0VsZW1lbnQ7XG59KEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkNChEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCQ0KCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCQ0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIEZlTW9ycGhvbG9neUVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9FbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oRmVNb3JwaG9sb2d5RWxlbWVudCwgX0VsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkNChGZU1vcnBob2xvZ3lFbGVtZW50KTtcblxuICBmdW5jdGlvbiBGZU1vcnBob2xvZ3lFbGVtZW50KCkge1xuICAgIHZhciBfdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVja19fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgRmVNb3JwaG9sb2d5RWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF90aGlzLnR5cGUgPSAnZmVNb3JwaG9sb2d5JztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEZlTW9ycGhvbG9neUVsZW1lbnQsIFt7XG4gICAga2V5OiBcImFwcGx5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGx5KF8sIF94LCBfeSwgX3dpZHRoLCBfaGVpZ2h0KSB7Ly8gVE9ETzogaW1wbGVtZW50XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIEZlTW9ycGhvbG9neUVsZW1lbnQ7XG59KEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIkMyhEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCQzKCk7IHJldHVybiBmdW5jdGlvbiBfY3JlYXRlU3VwZXJJbnRlcm5hbCgpIHsgdmFyIFN1cGVyID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXShEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5fX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIHJlc3VsdCk7IH07IH1cblxuZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCQzKCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIEZlQ29tcG9zaXRlRWxlbWVudCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX0VsZW1lbnQpIHtcbiAgX2luaGVyaXRzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShGZUNvbXBvc2l0ZUVsZW1lbnQsIF9FbGVtZW50KTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyJDMoRmVDb21wb3NpdGVFbGVtZW50KTtcblxuICBmdW5jdGlvbiBGZUNvbXBvc2l0ZUVsZW1lbnQoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBGZUNvbXBvc2l0ZUVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfdGhpcy50eXBlID0gJ2ZlQ29tcG9zaXRlJztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICBfY3JlYXRlQ2xhc3NfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKEZlQ29tcG9zaXRlRWxlbWVudCwgW3tcbiAgICBrZXk6IFwiYXBwbHlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gYXBwbHkoXywgX3gsIF95LCBfd2lkdGgsIF9oZWlnaHQpIHsvLyBUT0RPOiBpbXBsZW1lbnRcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gRmVDb21wb3NpdGVFbGVtZW50O1xufShFbGVtZW50KTtcblxuZnVuY3Rpb24gX2NyZWF0ZVN1cGVyJDIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkMigpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcykuY29uc3RydWN0b3I7IHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7IH0gZWxzZSB7IHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH0gcmV0dXJuIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QkMigpIHsgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlOyBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlOyBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlOyB0cnkgeyBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9XG5cbnZhciBGZUdhdXNzaWFuQmx1ckVsZW1lbnQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9FbGVtZW50KSB7XG4gIF9pbmhlcml0c19fZGVmYXVsdFtcImRlZmF1bHRcIl0oRmVHYXVzc2lhbkJsdXJFbGVtZW50LCBfRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlciQyKEZlR2F1c3NpYW5CbHVyRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gRmVHYXVzc2lhbkJsdXJFbGVtZW50KGRvY3VtZW50LCBub2RlLCBjYXB0dXJlVGV4dE5vZGVzKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBGZUdhdXNzaWFuQmx1ckVsZW1lbnQpO1xuXG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBkb2N1bWVudCwgbm9kZSwgY2FwdHVyZVRleHROb2Rlcyk7XG4gICAgX3RoaXMudHlwZSA9ICdmZUdhdXNzaWFuQmx1cic7XG4gICAgX3RoaXMuYmx1clJhZGl1cyA9IE1hdGguZmxvb3IoX3RoaXMuZ2V0QXR0cmlidXRlKCdzdGREZXZpYXRpb24nKS5nZXROdW1iZXIoKSk7XG4gICAgX3RoaXMuZXh0cmFGaWx0ZXJEaXN0YW5jZSA9IF90aGlzLmJsdXJSYWRpdXM7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShGZUdhdXNzaWFuQmx1ckVsZW1lbnQsIFt7XG4gICAga2V5OiBcImFwcGx5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGx5KGN0eCwgeCwgeSwgd2lkdGgsIGhlaWdodCkge1xuICAgICAgdmFyIGRvY3VtZW50ID0gdGhpcy5kb2N1bWVudCxcbiAgICAgICAgICBibHVyUmFkaXVzID0gdGhpcy5ibHVyUmFkaXVzO1xuICAgICAgdmFyIGJvZHkgPSBkb2N1bWVudC53aW5kb3cgPyBkb2N1bWVudC53aW5kb3cuZG9jdW1lbnQuYm9keSA6IG51bGw7XG4gICAgICB2YXIgY2FudmFzID0gY3R4LmNhbnZhczsgLy8gU3RhY2tCbHVyIHJlcXVpcmVzIGNhbnZhcyBiZSBvbiBkb2N1bWVudFxuXG4gICAgICBjYW52YXMuaWQgPSBkb2N1bWVudC5nZXRVbmlxdWVJZCgpO1xuXG4gICAgICBpZiAoYm9keSkge1xuICAgICAgICBjYW52YXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgYm9keS5hcHBlbmRDaGlsZChjYW52YXMpO1xuICAgICAgfVxuXG4gICAgICBzdGFja2JsdXJDYW52YXMuY2FudmFzUkdCQShjYW52YXMsIHgsIHksIHdpZHRoLCBoZWlnaHQsIGJsdXJSYWRpdXMpO1xuXG4gICAgICBpZiAoYm9keSkge1xuICAgICAgICBib2R5LnJlbW92ZUNoaWxkKGNhbnZhcyk7XG4gICAgICB9XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIEZlR2F1c3NpYW5CbHVyRWxlbWVudDtcbn0oRWxlbWVudCk7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlciQxKERlcml2ZWQpIHsgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JDEoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0JDEoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG52YXIgVGl0bGVFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKFRpdGxlRWxlbWVudCwgX0VsZW1lbnQpO1xuXG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIkMShUaXRsZUVsZW1lbnQpO1xuXG4gIGZ1bmN0aW9uIFRpdGxlRWxlbWVudCgpIHtcbiAgICB2YXIgX3RoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIFRpdGxlRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF90aGlzLnR5cGUgPSAndGl0bGUnO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIHJldHVybiBUaXRsZUVsZW1lbnQ7XG59KEVsZW1lbnQpO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlcml2ZWQpLCByZXN1bHQ7IGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7IHZhciBOZXdUYXJnZXQgPSBfZ2V0UHJvdG90eXBlT2ZfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybl9fZGVmYXVsdFtcImRlZmF1bHRcIl0odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxudmFyIERlc2NFbGVtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfRWxlbWVudCkge1xuICBfaW5oZXJpdHNfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKERlc2NFbGVtZW50LCBfRWxlbWVudCk7XG5cbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlcihEZXNjRWxlbWVudCk7XG5cbiAgZnVuY3Rpb24gRGVzY0VsZW1lbnQoKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBEZXNjRWxlbWVudCk7XG5cbiAgICBfdGhpcyA9IF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF90aGlzLnR5cGUgPSAnZGVzYyc7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIERlc2NFbGVtZW50O1xufShFbGVtZW50KTtcblxudmFyIGVsZW1lbnRzID0ge1xuICAnc3ZnJzogU1ZHRWxlbWVudCxcbiAgJ3JlY3QnOiBSZWN0RWxlbWVudCxcbiAgJ2NpcmNsZSc6IENpcmNsZUVsZW1lbnQsXG4gICdlbGxpcHNlJzogRWxsaXBzZUVsZW1lbnQsXG4gICdsaW5lJzogTGluZUVsZW1lbnQsXG4gICdwb2x5bGluZSc6IFBvbHlsaW5lRWxlbWVudCxcbiAgJ3BvbHlnb24nOiBQb2x5Z29uRWxlbWVudCxcbiAgJ3BhdGgnOiBQYXRoRWxlbWVudCxcbiAgJ3BhdHRlcm4nOiBQYXR0ZXJuRWxlbWVudCxcbiAgJ21hcmtlcic6IE1hcmtlckVsZW1lbnQsXG4gICdkZWZzJzogRGVmc0VsZW1lbnQsXG4gICdsaW5lYXJHcmFkaWVudCc6IExpbmVhckdyYWRpZW50RWxlbWVudCxcbiAgJ3JhZGlhbEdyYWRpZW50JzogUmFkaWFsR3JhZGllbnRFbGVtZW50LFxuICAnc3RvcCc6IFN0b3BFbGVtZW50LFxuICAnYW5pbWF0ZSc6IEFuaW1hdGVFbGVtZW50LFxuICAnYW5pbWF0ZUNvbG9yJzogQW5pbWF0ZUNvbG9yRWxlbWVudCxcbiAgJ2FuaW1hdGVUcmFuc2Zvcm0nOiBBbmltYXRlVHJhbnNmb3JtRWxlbWVudCxcbiAgJ2ZvbnQnOiBGb250RWxlbWVudCxcbiAgJ2ZvbnQtZmFjZSc6IEZvbnRGYWNlRWxlbWVudCxcbiAgJ21pc3NpbmctZ2x5cGgnOiBNaXNzaW5nR2x5cGhFbGVtZW50LFxuICAnZ2x5cGgnOiBHbHlwaEVsZW1lbnQsXG4gICd0ZXh0JzogVGV4dEVsZW1lbnQsXG4gICd0c3Bhbic6IFRTcGFuRWxlbWVudCxcbiAgJ3RyZWYnOiBUUmVmRWxlbWVudCxcbiAgJ2EnOiBBRWxlbWVudCxcbiAgJ3RleHRQYXRoJzogVGV4dFBhdGhFbGVtZW50LFxuICAnaW1hZ2UnOiBJbWFnZUVsZW1lbnQsXG4gICdnJzogR0VsZW1lbnQsXG4gICdzeW1ib2wnOiBTeW1ib2xFbGVtZW50LFxuICAnc3R5bGUnOiBTdHlsZUVsZW1lbnQsXG4gICd1c2UnOiBVc2VFbGVtZW50LFxuICAnbWFzayc6IE1hc2tFbGVtZW50LFxuICAnY2xpcFBhdGgnOiBDbGlwUGF0aEVsZW1lbnQsXG4gICdmaWx0ZXInOiBGaWx0ZXJFbGVtZW50LFxuICAnZmVEcm9wU2hhZG93JzogRmVEcm9wU2hhZG93RWxlbWVudCxcbiAgJ2ZlTW9ycGhvbG9neSc6IEZlTW9ycGhvbG9neUVsZW1lbnQsXG4gICdmZUNvbXBvc2l0ZSc6IEZlQ29tcG9zaXRlRWxlbWVudCxcbiAgJ2ZlQ29sb3JNYXRyaXgnOiBGZUNvbG9yTWF0cml4RWxlbWVudCxcbiAgJ2ZlR2F1c3NpYW5CbHVyJzogRmVHYXVzc2lhbkJsdXJFbGVtZW50LFxuICAndGl0bGUnOiBUaXRsZUVsZW1lbnQsXG4gICdkZXNjJzogRGVzY0VsZW1lbnRcbn07XG5cbmZ1bmN0aW9uIG93bktleXMkMShvYmplY3QsIGVudW1lcmFibGVPbmx5KSB7IHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTsgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHsgdmFyIHN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKG9iamVjdCk7IGlmIChlbnVtZXJhYmxlT25seSkgeyBzeW1ib2xzID0gc3ltYm9scy5maWx0ZXIoZnVuY3Rpb24gKHN5bSkgeyByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHN5bSkuZW51bWVyYWJsZTsgfSk7IH0ga2V5cy5wdXNoLmFwcGx5KGtleXMsIHN5bWJvbHMpOyB9IHJldHVybiBrZXlzOyB9XG5cbmZ1bmN0aW9uIF9vYmplY3RTcHJlYWQkMSh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXSAhPSBudWxsID8gYXJndW1lbnRzW2ldIDoge307IGlmIChpICUgMikgeyBvd25LZXlzJDEoT2JqZWN0KHNvdXJjZSksIHRydWUpLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBfZGVmaW5lUHJvcGVydHlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRhcmdldCwga2V5LCBzb3VyY2Vba2V5XSk7IH0pOyB9IGVsc2UgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc291cmNlKSk7IH0gZWxzZSB7IG93bktleXMkMShPYmplY3Qoc291cmNlKSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzb3VyY2UsIGtleSkpOyB9KTsgfSB9IHJldHVybiB0YXJnZXQ7IH1cblxuZnVuY3Rpb24gY3JlYXRlQ2FudmFzKHdpZHRoLCBoZWlnaHQpIHtcbiAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICBjYW52YXMud2lkdGggPSB3aWR0aDtcbiAgY2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgcmV0dXJuIGNhbnZhcztcbn1cblxuZnVuY3Rpb24gY3JlYXRlSW1hZ2UoX3gpIHtcbiAgcmV0dXJuIF9jcmVhdGVJbWFnZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5mdW5jdGlvbiBfY3JlYXRlSW1hZ2UoKSB7XG4gIF9jcmVhdGVJbWFnZSA9IF9hc3luY1RvR2VuZXJhdG9yX19kZWZhdWx0W1wiZGVmYXVsdFwiXSggLyojX19QVVJFX18qL19yZWdlbmVyYXRvclJ1bnRpbWVfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLm1hcmsoZnVuY3Rpb24gX2NhbGxlZShzcmMpIHtcbiAgICB2YXIgYW5vbnltb3VzQ3Jvc3NPcmlnaW4sXG4gICAgICAgIGltYWdlLFxuICAgICAgICBfYXJncyA9IGFyZ3VtZW50cztcbiAgICByZXR1cm4gX3JlZ2VuZXJhdG9yUnVudGltZV9fZGVmYXVsdFtcImRlZmF1bHRcIl0ud3JhcChmdW5jdGlvbiBfY2FsbGVlJChfY29udGV4dCkge1xuICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgIGFub255bW91c0Nyb3NzT3JpZ2luID0gX2FyZ3MubGVuZ3RoID4gMSAmJiBfYXJnc1sxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3NbMV0gOiBmYWxzZTtcbiAgICAgICAgICAgIGltYWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJyk7XG5cbiAgICAgICAgICAgIGlmIChhbm9ueW1vdXNDcm9zc09yaWdpbikge1xuICAgICAgICAgICAgICBpbWFnZS5jcm9zc09yaWdpbiA9ICdBbm9ueW1vdXMnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlc29sdmUoaW1hZ2UpO1xuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgIGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoX2V2ZW50LCBfc291cmNlLCBfbGluZW5vLCBfY29sbm8sIGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICBpbWFnZS5zcmMgPSBzcmM7XG4gICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIF9jYWxsZWUpO1xuICB9KSk7XG4gIHJldHVybiBfY3JlYXRlSW1hZ2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxudmFyIERvY3VtZW50ID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRG9jdW1lbnQoY2FudmcpIHtcbiAgICB2YXIgX3JlZiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge30sXG4gICAgICAgIF9yZWYkcm9vdEVtU2l6ZSA9IF9yZWYucm9vdEVtU2l6ZSxcbiAgICAgICAgcm9vdEVtU2l6ZSA9IF9yZWYkcm9vdEVtU2l6ZSA9PT0gdm9pZCAwID8gMTIgOiBfcmVmJHJvb3RFbVNpemUsXG4gICAgICAgIF9yZWYkZW1TaXplID0gX3JlZi5lbVNpemUsXG4gICAgICAgIGVtU2l6ZSA9IF9yZWYkZW1TaXplID09PSB2b2lkIDAgPyAxMiA6IF9yZWYkZW1TaXplLFxuICAgICAgICBfcmVmJGNyZWF0ZUNhbnZhcyA9IF9yZWYuY3JlYXRlQ2FudmFzLFxuICAgICAgICBjcmVhdGVDYW52YXMgPSBfcmVmJGNyZWF0ZUNhbnZhcyA9PT0gdm9pZCAwID8gRG9jdW1lbnQuY3JlYXRlQ2FudmFzIDogX3JlZiRjcmVhdGVDYW52YXMsXG4gICAgICAgIF9yZWYkY3JlYXRlSW1hZ2UgPSBfcmVmLmNyZWF0ZUltYWdlLFxuICAgICAgICBjcmVhdGVJbWFnZSA9IF9yZWYkY3JlYXRlSW1hZ2UgPT09IHZvaWQgMCA/IERvY3VtZW50LmNyZWF0ZUltYWdlIDogX3JlZiRjcmVhdGVJbWFnZSxcbiAgICAgICAgYW5vbnltb3VzQ3Jvc3NPcmlnaW4gPSBfcmVmLmFub255bW91c0Nyb3NzT3JpZ2luO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrX19kZWZhdWx0W1wiZGVmYXVsdFwiXSh0aGlzLCBEb2N1bWVudCk7XG5cbiAgICB0aGlzLmNhbnZnID0gY2Fudmc7XG4gICAgdGhpcy5kZWZpbml0aW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGhpcy5zdHlsZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuc3R5bGVzU3BlY2lmaWNpdHkgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuaW1hZ2VzID0gW107XG4gICAgdGhpcy5mb250cyA9IFtdO1xuICAgIHRoaXMuZW1TaXplU3RhY2sgPSBbXTtcbiAgICB0aGlzLnVuaXF1ZUlkID0gMDtcbiAgICB0aGlzLnNjcmVlbiA9IGNhbnZnLnNjcmVlbjtcbiAgICB0aGlzLnJvb3RFbVNpemUgPSByb290RW1TaXplO1xuICAgIHRoaXMuZW1TaXplID0gZW1TaXplO1xuICAgIHRoaXMuY3JlYXRlQ2FudmFzID0gY3JlYXRlQ2FudmFzO1xuICAgIHRoaXMuY3JlYXRlSW1hZ2UgPSB0aGlzLmJpbmRDcmVhdGVJbWFnZShjcmVhdGVJbWFnZSwgYW5vbnltb3VzQ3Jvc3NPcmlnaW4pO1xuICAgIHRoaXMuc2NyZWVuLndhaXQodGhpcy5pc0ltYWdlc0xvYWRlZC5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLnNjcmVlbi53YWl0KHRoaXMuaXNGb250c0xvYWRlZC5iaW5kKHRoaXMpKTtcbiAgfVxuXG4gIF9jcmVhdGVDbGFzc19fZGVmYXVsdFtcImRlZmF1bHRcIl0oRG9jdW1lbnQsIFt7XG4gICAga2V5OiBcImJpbmRDcmVhdGVJbWFnZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBiaW5kQ3JlYXRlSW1hZ2UoY3JlYXRlSW1hZ2UsIGFub255bW91c0Nyb3NzT3JpZ2luKSB7XG4gICAgICBpZiAodHlwZW9mIGFub255bW91c0Nyb3NzT3JpZ2luID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzb3VyY2UsIGZvcmNlQW5vbnltb3VzQ3Jvc3NPcmlnaW4pIHtcbiAgICAgICAgICByZXR1cm4gY3JlYXRlSW1hZ2Uoc291cmNlLCB0eXBlb2YgZm9yY2VBbm9ueW1vdXNDcm9zc09yaWdpbiA9PT0gJ2Jvb2xlYW4nID8gZm9yY2VBbm9ueW1vdXNDcm9zc09yaWdpbiA6IGFub255bW91c0Nyb3NzT3JpZ2luKTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNyZWF0ZUltYWdlO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJwb3BFbVNpemVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcG9wRW1TaXplKCkge1xuICAgICAgdmFyIGVtU2l6ZVN0YWNrID0gdGhpcy5lbVNpemVTdGFjaztcbiAgICAgIGVtU2l6ZVN0YWNrLnBvcCgpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRVbmlxdWVJZFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRVbmlxdWVJZCgpIHtcbiAgICAgIHJldHVybiBcImNhbnZnXCIuY29uY2F0KCsrdGhpcy51bmlxdWVJZCk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImlzSW1hZ2VzTG9hZGVkXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGlzSW1hZ2VzTG9hZGVkKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaW1hZ2VzLmV2ZXJ5KGZ1bmN0aW9uIChfKSB7XG4gICAgICAgIHJldHVybiBfLmxvYWRlZDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJpc0ZvbnRzTG9hZGVkXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGlzRm9udHNMb2FkZWQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5mb250cy5ldmVyeShmdW5jdGlvbiAoXykge1xuICAgICAgICByZXR1cm4gXy5sb2FkZWQ7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlRG9jdW1lbnRFbGVtZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNyZWF0ZURvY3VtZW50RWxlbWVudChkb2N1bWVudCkge1xuICAgICAgdmFyIGRvY3VtZW50RWxlbWVudCA9IHRoaXMuY3JlYXRlRWxlbWVudChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpO1xuICAgICAgZG9jdW1lbnRFbGVtZW50LnJvb3QgPSB0cnVlO1xuICAgICAgZG9jdW1lbnRFbGVtZW50LmFkZFN0eWxlc0Zyb21TdHlsZURlZmluaXRpb24oKTtcbiAgICAgIHRoaXMuZG9jdW1lbnRFbGVtZW50ID0gZG9jdW1lbnRFbGVtZW50O1xuICAgICAgcmV0dXJuIGRvY3VtZW50RWxlbWVudDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlRWxlbWVudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjcmVhdGVFbGVtZW50KG5vZGUpIHtcbiAgICAgIHZhciBlbGVtZW50VHlwZSA9IG5vZGUubm9kZU5hbWUucmVwbGFjZSgvXlteOl0rOi8sICcnKTtcbiAgICAgIHZhciBFbGVtZW50VHlwZSA9IERvY3VtZW50LmVsZW1lbnRUeXBlc1tlbGVtZW50VHlwZV07XG5cbiAgICAgIGlmICh0eXBlb2YgRWxlbWVudFR5cGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiBuZXcgRWxlbWVudFR5cGUodGhpcywgbm9kZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgVW5rbm93bkVsZW1lbnQodGhpcywgbm9kZSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNyZWF0ZVRleHROb2RlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNyZWF0ZVRleHROb2RlKG5vZGUpIHtcbiAgICAgIHJldHVybiBuZXcgVGV4dE5vZGUodGhpcywgbm9kZSk7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInNldFZpZXdCb3hcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0Vmlld0JveChjb25maWcpIHtcbiAgICAgIHRoaXMuc2NyZWVuLnNldFZpZXdCb3goX29iamVjdFNwcmVhZCQxKHtcbiAgICAgICAgZG9jdW1lbnQ6IHRoaXNcbiAgICAgIH0sIGNvbmZpZykpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJ3aW5kb3dcIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLnNjcmVlbi53aW5kb3c7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImZldGNoXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5zY3JlZW4uZmV0Y2g7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImN0eFwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2NyZWVuLmN0eDtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZW1TaXplXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICB2YXIgZW1TaXplU3RhY2sgPSB0aGlzLmVtU2l6ZVN0YWNrO1xuICAgICAgcmV0dXJuIGVtU2l6ZVN0YWNrW2VtU2l6ZVN0YWNrLmxlbmd0aCAtIDFdO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbiBzZXQodmFsdWUpIHtcbiAgICAgIHZhciBlbVNpemVTdGFjayA9IHRoaXMuZW1TaXplU3RhY2s7XG4gICAgICBlbVNpemVTdGFjay5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gRG9jdW1lbnQ7XG59KCk7XG5Eb2N1bWVudC5jcmVhdGVDYW52YXMgPSBjcmVhdGVDYW52YXM7XG5Eb2N1bWVudC5jcmVhdGVJbWFnZSA9IGNyZWF0ZUltYWdlO1xuRG9jdW1lbnQuZWxlbWVudFR5cGVzID0gZWxlbWVudHM7XG5cbmZ1bmN0aW9uIG93bktleXMob2JqZWN0LCBlbnVtZXJhYmxlT25seSkgeyB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7IGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7IHZhciBzeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmplY3QpOyBpZiAoZW51bWVyYWJsZU9ubHkpIHsgc3ltYm9scyA9IHN5bWJvbHMuZmlsdGVyKGZ1bmN0aW9uIChzeW0pIHsgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBzeW0pLmVudW1lcmFibGU7IH0pOyB9IGtleXMucHVzaC5hcHBseShrZXlzLCBzeW1ib2xzKTsgfSByZXR1cm4ga2V5czsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0U3ByZWFkKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldICE9IG51bGwgPyBhcmd1bWVudHNbaV0gOiB7fTsgaWYgKGkgJSAyKSB7IG93bktleXMoT2JqZWN0KHNvdXJjZSksIHRydWUpLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBfZGVmaW5lUHJvcGVydHlfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRhcmdldCwga2V5LCBzb3VyY2Vba2V5XSk7IH0pOyB9IGVsc2UgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc291cmNlKSk7IH0gZWxzZSB7IG93bktleXMoT2JqZWN0KHNvdXJjZSkpLmZvckVhY2goZnVuY3Rpb24gKGtleSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc291cmNlLCBrZXkpKTsgfSk7IH0gfSByZXR1cm4gdGFyZ2V0OyB9XG4vKipcclxuICogU1ZHIHJlbmRlcmVyIG9uIGNhbnZhcy5cclxuICovXG5cbnZhciBDYW52ZyA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIC8qKlxyXG4gICAqIE1haW4gY29uc3RydWN0b3IuXHJcbiAgICogQHBhcmFtIGN0eCAtIFJlbmRlcmluZyBjb250ZXh0LlxyXG4gICAqIEBwYXJhbSBzdmcgLSBTVkcgRG9jdW1lbnQuXHJcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBSZW5kZXJpbmcgb3B0aW9ucy5cclxuICAgKi9cbiAgZnVuY3Rpb24gQ2FudmcoY3R4LCBzdmcpIHtcbiAgICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDoge307XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2tfX2RlZmF1bHRbXCJkZWZhdWx0XCJdKHRoaXMsIENhbnZnKTtcblxuICAgIHRoaXMucGFyc2VyID0gbmV3IFBhcnNlcihvcHRpb25zKTtcbiAgICB0aGlzLnNjcmVlbiA9IG5ldyBTY3JlZW4oY3R4LCBvcHRpb25zKTtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHZhciBkb2N1bWVudCA9IG5ldyBEb2N1bWVudCh0aGlzLCBvcHRpb25zKTtcbiAgICB2YXIgZG9jdW1lbnRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRFbGVtZW50KHN2Zyk7XG4gICAgdGhpcy5kb2N1bWVudCA9IGRvY3VtZW50O1xuICAgIHRoaXMuZG9jdW1lbnRFbGVtZW50ID0gZG9jdW1lbnRFbGVtZW50O1xuICB9XG4gIC8qKlxyXG4gICAqIENyZWF0ZSBDYW52ZyBpbnN0YW5jZSBmcm9tIFNWRyBzb3VyY2Ugc3RyaW5nIG9yIFVSTC5cclxuICAgKiBAcGFyYW0gY3R4IC0gUmVuZGVyaW5nIGNvbnRleHQuXHJcbiAgICogQHBhcmFtIHN2ZyAtIFNWRyBzb3VyY2Ugc3RyaW5nIG9yIFVSTC5cclxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFJlbmRlcmluZyBvcHRpb25zLlxyXG4gICAqIEByZXR1cm5zIENhbnZnIGluc3RhbmNlLlxyXG4gICAqL1xuXG5cbiAgX2NyZWF0ZUNsYXNzX19kZWZhdWx0W1wiZGVmYXVsdFwiXShDYW52ZywgW3tcbiAgICBrZXk6IFwiZm9ya1wiLFxuXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGUgbmV3IENhbnZnIGluc3RhbmNlIHdpdGggaW5oZXJpdGVkIG9wdGlvbnMuXHJcbiAgICAgKiBAcGFyYW0gY3R4IC0gUmVuZGVyaW5nIGNvbnRleHQuXHJcbiAgICAgKiBAcGFyYW0gc3ZnIC0gU1ZHIHNvdXJjZSBzdHJpbmcgb3IgVVJMLlxyXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBSZW5kZXJpbmcgb3B0aW9ucy5cclxuICAgICAqIEByZXR1cm5zIENhbnZnIGluc3RhbmNlLlxyXG4gICAgICovXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGZvcmsoY3R4LCBzdmcpIHtcbiAgICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB7fTtcbiAgICAgIHJldHVybiBDYW52Zy5mcm9tKGN0eCwgc3ZnLCBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIHRoaXMub3B0aW9ucyksIG9wdGlvbnMpKTtcbiAgICB9XG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGUgbmV3IENhbnZnIGluc3RhbmNlIHdpdGggaW5oZXJpdGVkIG9wdGlvbnMuXHJcbiAgICAgKiBAcGFyYW0gY3R4IC0gUmVuZGVyaW5nIGNvbnRleHQuXHJcbiAgICAgKiBAcGFyYW0gc3ZnIC0gU1ZHIHNvdXJjZSBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIFJlbmRlcmluZyBvcHRpb25zLlxyXG4gICAgICogQHJldHVybnMgQ2FudmcgaW5zdGFuY2UuXHJcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImZvcmtTdHJpbmdcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZm9ya1N0cmluZyhjdHgsIHN2Zykge1xuICAgICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuICAgICAgcmV0dXJuIENhbnZnLmZyb21TdHJpbmcoY3R4LCBzdmcsIF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgdGhpcy5vcHRpb25zKSwgb3B0aW9ucykpO1xuICAgIH1cbiAgICAvKipcclxuICAgICAqIERvY3VtZW50IGlzIHJlYWR5IHByb21pc2UuXHJcbiAgICAgKiBAcmV0dXJucyBSZWFkeSBwcm9taXNlLlxyXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZWFkeVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZWFkeSgpIHtcbiAgICAgIHJldHVybiB0aGlzLnNjcmVlbi5yZWFkeSgpO1xuICAgIH1cbiAgICAvKipcclxuICAgICAqIERvY3VtZW50IGlzIHJlYWR5IHZhbHVlLlxyXG4gICAgICogQHJldHVybnMgSXMgcmVhZHkgb3Igbm90LlxyXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJpc1JlYWR5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGlzUmVhZHkoKSB7XG4gICAgICByZXR1cm4gdGhpcy5zY3JlZW4uaXNSZWFkeSgpO1xuICAgIH1cbiAgICAvKipcclxuICAgICAqIFJlbmRlciBvbmx5IGZpcnN0IGZyYW1lLCBpZ25vcmluZyBhbmltYXRpb25zIGFuZCBtb3VzZS5cclxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gUmVuZGVyaW5nIG9wdGlvbnMuXHJcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3JlbmRlciA9IF9hc3luY1RvR2VuZXJhdG9yX19kZWZhdWx0W1wiZGVmYXVsdFwiXSggLyojX19QVVJFX18qL19yZWdlbmVyYXRvclJ1bnRpbWVfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLm1hcmsoZnVuY3Rpb24gX2NhbGxlZSgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvclJ1bnRpbWVfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLndyYXAoZnVuY3Rpb24gX2NhbGxlZSQoX2NvbnRleHQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzLmxlbmd0aCA+IDAgJiYgX2FyZ3NbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzWzBdIDoge307XG4gICAgICAgICAgICAgICAgdGhpcy5zdGFydChfb2JqZWN0U3ByZWFkKHtcbiAgICAgICAgICAgICAgICAgIGVuYWJsZVJlZHJhdzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIGlnbm9yZUFuaW1hdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIGlnbm9yZU1vdXNlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSwgb3B0aW9ucykpO1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSA0O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlYWR5KCk7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gX3JlbmRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVuZGVyO1xuICAgIH0oKVxuICAgIC8qKlxyXG4gICAgICogU3RhcnQgcmVuZGVyaW5nLlxyXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBSZW5kZXIgb3B0aW9ucy5cclxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwic3RhcnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc3RhcnQoKSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDoge307XG4gICAgICB2YXIgZG9jdW1lbnRFbGVtZW50ID0gdGhpcy5kb2N1bWVudEVsZW1lbnQsXG4gICAgICAgICAgc2NyZWVuID0gdGhpcy5zY3JlZW4sXG4gICAgICAgICAgYmFzZU9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICBzY3JlZW4uc3RhcnQoZG9jdW1lbnRFbGVtZW50LCBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe1xuICAgICAgICBlbmFibGVSZWRyYXc6IHRydWVcbiAgICAgIH0sIGJhc2VPcHRpb25zKSwgb3B0aW9ucykpO1xuICAgIH1cbiAgICAvKipcclxuICAgICAqIFN0b3AgcmVuZGVyaW5nLlxyXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJzdG9wXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHN0b3AoKSB7XG4gICAgICB0aGlzLnNjcmVlbi5zdG9wKCk7XG4gICAgfVxuICAgIC8qKlxyXG4gICAgICogUmVzaXplIFNWRyB0byBmaXQgaW4gZ2l2ZW4gc2l6ZS5cclxuICAgICAqIEBwYXJhbSB3aWR0aFxyXG4gICAgICogQHBhcmFtIGhlaWdodFxyXG4gICAgICogQHBhcmFtIHByZXNlcnZlQXNwZWN0UmF0aW9cclxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwicmVzaXplXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlc2l6ZSh3aWR0aCkge1xuICAgICAgdmFyIGhlaWdodCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogd2lkdGg7XG4gICAgICB2YXIgcHJlc2VydmVBc3BlY3RSYXRpbyA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogZmFsc2U7XG4gICAgICB0aGlzLmRvY3VtZW50RWxlbWVudC5yZXNpemUod2lkdGgsIGhlaWdodCwgcHJlc2VydmVBc3BlY3RSYXRpbyk7XG4gICAgfVxuICB9XSwgW3tcbiAgICBrZXk6IFwiZnJvbVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2Zyb20gPSBfYXN5bmNUb0dlbmVyYXRvcl9fZGVmYXVsdFtcImRlZmF1bHRcIl0oIC8qI19fUFVSRV9fKi9fcmVnZW5lcmF0b3JSdW50aW1lX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUyKGN0eCwgc3ZnKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGFyc2VyLFxuICAgICAgICAgICAgc3ZnRG9jdW1lbnQsXG4gICAgICAgICAgICBfYXJnczIgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3JSdW50aW1lX19kZWZhdWx0W1wiZGVmYXVsdFwiXS53cmFwKGZ1bmN0aW9uIF9jYWxsZWUyJChfY29udGV4dDIpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDIucHJldiA9IF9jb250ZXh0Mi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MyLmxlbmd0aCA+IDIgJiYgX2FyZ3MyWzJdICE9PSB1bmRlZmluZWQgPyBfYXJnczJbMl0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXJzZXIgPSBuZXcgUGFyc2VyKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VyLnBhcnNlKHN2Zyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIHN2Z0RvY3VtZW50ID0gX2NvbnRleHQyLnNlbnQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgbmV3IENhbnZnKGN0eCwgc3ZnRG9jdW1lbnQsIG9wdGlvbnMpKTtcblxuICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUyKTtcbiAgICAgIH0pKTtcblxuICAgICAgZnVuY3Rpb24gZnJvbShfeCwgX3gyKSB7XG4gICAgICAgIHJldHVybiBfZnJvbS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZnJvbTtcbiAgICB9KClcbiAgICAvKipcclxuICAgICAqIENyZWF0ZSBDYW52ZyBpbnN0YW5jZSBmcm9tIFNWRyBzb3VyY2Ugc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIGN0eCAtIFJlbmRlcmluZyBjb250ZXh0LlxyXG4gICAgICogQHBhcmFtIHN2ZyAtIFNWRyBzb3VyY2Ugc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBSZW5kZXJpbmcgb3B0aW9ucy5cclxuICAgICAqIEByZXR1cm5zIENhbnZnIGluc3RhbmNlLlxyXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJmcm9tU3RyaW5nXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21TdHJpbmcoY3R4LCBzdmcpIHtcbiAgICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB7fTtcbiAgICAgIHZhciBwYXJzZXIgPSBuZXcgUGFyc2VyKG9wdGlvbnMpO1xuICAgICAgdmFyIHN2Z0RvY3VtZW50ID0gcGFyc2VyLnBhcnNlRnJvbVN0cmluZyhzdmcpO1xuICAgICAgcmV0dXJuIG5ldyBDYW52ZyhjdHgsIHN2Z0RvY3VtZW50LCBvcHRpb25zKTtcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gQ2Fudmc7XG59KCk7XG5cbmV4cG9ydHMuQUVsZW1lbnQgPSBBRWxlbWVudDtcbmV4cG9ydHMuQW5pbWF0ZUNvbG9yRWxlbWVudCA9IEFuaW1hdGVDb2xvckVsZW1lbnQ7XG5leHBvcnRzLkFuaW1hdGVFbGVtZW50ID0gQW5pbWF0ZUVsZW1lbnQ7XG5leHBvcnRzLkFuaW1hdGVUcmFuc2Zvcm1FbGVtZW50ID0gQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ7XG5leHBvcnRzLkJvdW5kaW5nQm94ID0gQm91bmRpbmdCb3g7XG5leHBvcnRzLkNCMSA9IENCMTtcbmV4cG9ydHMuQ0IyID0gQ0IyO1xuZXhwb3J0cy5DQjMgPSBDQjM7XG5leHBvcnRzLkNCNCA9IENCNDtcbmV4cG9ydHMuQ2FudmcgPSBDYW52ZztcbmV4cG9ydHMuQ2lyY2xlRWxlbWVudCA9IENpcmNsZUVsZW1lbnQ7XG5leHBvcnRzLkNsaXBQYXRoRWxlbWVudCA9IENsaXBQYXRoRWxlbWVudDtcbmV4cG9ydHMuRGVmc0VsZW1lbnQgPSBEZWZzRWxlbWVudDtcbmV4cG9ydHMuRGVzY0VsZW1lbnQgPSBEZXNjRWxlbWVudDtcbmV4cG9ydHMuRG9jdW1lbnQgPSBEb2N1bWVudDtcbmV4cG9ydHMuRWxlbWVudCA9IEVsZW1lbnQ7XG5leHBvcnRzLkVsbGlwc2VFbGVtZW50ID0gRWxsaXBzZUVsZW1lbnQ7XG5leHBvcnRzLkZlQ29sb3JNYXRyaXhFbGVtZW50ID0gRmVDb2xvck1hdHJpeEVsZW1lbnQ7XG5leHBvcnRzLkZlQ29tcG9zaXRlRWxlbWVudCA9IEZlQ29tcG9zaXRlRWxlbWVudDtcbmV4cG9ydHMuRmVEcm9wU2hhZG93RWxlbWVudCA9IEZlRHJvcFNoYWRvd0VsZW1lbnQ7XG5leHBvcnRzLkZlR2F1c3NpYW5CbHVyRWxlbWVudCA9IEZlR2F1c3NpYW5CbHVyRWxlbWVudDtcbmV4cG9ydHMuRmVNb3JwaG9sb2d5RWxlbWVudCA9IEZlTW9ycGhvbG9neUVsZW1lbnQ7XG5leHBvcnRzLkZpbHRlckVsZW1lbnQgPSBGaWx0ZXJFbGVtZW50O1xuZXhwb3J0cy5Gb250ID0gRm9udDtcbmV4cG9ydHMuRm9udEVsZW1lbnQgPSBGb250RWxlbWVudDtcbmV4cG9ydHMuRm9udEZhY2VFbGVtZW50ID0gRm9udEZhY2VFbGVtZW50O1xuZXhwb3J0cy5HRWxlbWVudCA9IEdFbGVtZW50O1xuZXhwb3J0cy5HbHlwaEVsZW1lbnQgPSBHbHlwaEVsZW1lbnQ7XG5leHBvcnRzLkdyYWRpZW50RWxlbWVudCA9IEdyYWRpZW50RWxlbWVudDtcbmV4cG9ydHMuSW1hZ2VFbGVtZW50ID0gSW1hZ2VFbGVtZW50O1xuZXhwb3J0cy5MaW5lRWxlbWVudCA9IExpbmVFbGVtZW50O1xuZXhwb3J0cy5MaW5lYXJHcmFkaWVudEVsZW1lbnQgPSBMaW5lYXJHcmFkaWVudEVsZW1lbnQ7XG5leHBvcnRzLk1hcmtlckVsZW1lbnQgPSBNYXJrZXJFbGVtZW50O1xuZXhwb3J0cy5NYXNrRWxlbWVudCA9IE1hc2tFbGVtZW50O1xuZXhwb3J0cy5NYXRyaXggPSBNYXRyaXg7XG5leHBvcnRzLk1pc3NpbmdHbHlwaEVsZW1lbnQgPSBNaXNzaW5nR2x5cGhFbGVtZW50O1xuZXhwb3J0cy5Nb3VzZSA9IE1vdXNlO1xuZXhwb3J0cy5QU0VVRE9fWkVSTyA9IFBTRVVET19aRVJPO1xuZXhwb3J0cy5QYXJzZXIgPSBQYXJzZXI7XG5leHBvcnRzLlBhdGhFbGVtZW50ID0gUGF0aEVsZW1lbnQ7XG5leHBvcnRzLlBhdGhQYXJzZXIgPSBQYXRoUGFyc2VyO1xuZXhwb3J0cy5QYXR0ZXJuRWxlbWVudCA9IFBhdHRlcm5FbGVtZW50O1xuZXhwb3J0cy5Qb2ludCA9IFBvaW50O1xuZXhwb3J0cy5Qb2x5Z29uRWxlbWVudCA9IFBvbHlnb25FbGVtZW50O1xuZXhwb3J0cy5Qb2x5bGluZUVsZW1lbnQgPSBQb2x5bGluZUVsZW1lbnQ7XG5leHBvcnRzLlByb3BlcnR5ID0gUHJvcGVydHk7XG5leHBvcnRzLlFCMSA9IFFCMTtcbmV4cG9ydHMuUUIyID0gUUIyO1xuZXhwb3J0cy5RQjMgPSBRQjM7XG5leHBvcnRzLlJhZGlhbEdyYWRpZW50RWxlbWVudCA9IFJhZGlhbEdyYWRpZW50RWxlbWVudDtcbmV4cG9ydHMuUmVjdEVsZW1lbnQgPSBSZWN0RWxlbWVudDtcbmV4cG9ydHMuUmVuZGVyZWRFbGVtZW50ID0gUmVuZGVyZWRFbGVtZW50O1xuZXhwb3J0cy5Sb3RhdGUgPSBSb3RhdGU7XG5leHBvcnRzLlNWR0VsZW1lbnQgPSBTVkdFbGVtZW50O1xuZXhwb3J0cy5TVkdGb250TG9hZGVyID0gU1ZHRm9udExvYWRlcjtcbmV4cG9ydHMuU2NhbGUgPSBTY2FsZTtcbmV4cG9ydHMuU2NyZWVuID0gU2NyZWVuO1xuZXhwb3J0cy5Ta2V3ID0gU2tldztcbmV4cG9ydHMuU2tld1ggPSBTa2V3WDtcbmV4cG9ydHMuU2tld1kgPSBTa2V3WTtcbmV4cG9ydHMuU3RvcEVsZW1lbnQgPSBTdG9wRWxlbWVudDtcbmV4cG9ydHMuU3R5bGVFbGVtZW50ID0gU3R5bGVFbGVtZW50O1xuZXhwb3J0cy5TeW1ib2xFbGVtZW50ID0gU3ltYm9sRWxlbWVudDtcbmV4cG9ydHMuVFJlZkVsZW1lbnQgPSBUUmVmRWxlbWVudDtcbmV4cG9ydHMuVFNwYW5FbGVtZW50ID0gVFNwYW5FbGVtZW50O1xuZXhwb3J0cy5UZXh0RWxlbWVudCA9IFRleHRFbGVtZW50O1xuZXhwb3J0cy5UZXh0UGF0aEVsZW1lbnQgPSBUZXh0UGF0aEVsZW1lbnQ7XG5leHBvcnRzLlRpdGxlRWxlbWVudCA9IFRpdGxlRWxlbWVudDtcbmV4cG9ydHMuVHJhbnNmb3JtID0gVHJhbnNmb3JtO1xuZXhwb3J0cy5UcmFuc2xhdGUgPSBUcmFuc2xhdGU7XG5leHBvcnRzLlVua25vd25FbGVtZW50ID0gVW5rbm93bkVsZW1lbnQ7XG5leHBvcnRzLlVzZUVsZW1lbnQgPSBVc2VFbGVtZW50O1xuZXhwb3J0cy5WaWV3UG9ydCA9IFZpZXdQb3J0O1xuZXhwb3J0cy5jb21wcmVzc1NwYWNlcyA9IGNvbXByZXNzU3BhY2VzO1xuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBDYW52ZztcbmV4cG9ydHMuZ2V0U2VsZWN0b3JTcGVjaWZpY2l0eSA9IGdldFNlbGVjdG9yU3BlY2lmaWNpdHk7XG5leHBvcnRzLm5vcm1hbGl6ZUF0dHJpYnV0ZU5hbWUgPSBub3JtYWxpemVBdHRyaWJ1dGVOYW1lO1xuZXhwb3J0cy5ub3JtYWxpemVDb2xvciA9IG5vcm1hbGl6ZUNvbG9yO1xuZXhwb3J0cy5wYXJzZUV4dGVybmFsVXJsID0gcGFyc2VFeHRlcm5hbFVybDtcbmV4cG9ydHMucHJlc2V0cyA9IGluZGV4O1xuZXhwb3J0cy50b051bWJlcnMgPSB0b051bWJlcnM7XG5leHBvcnRzLnRyaW1MZWZ0ID0gdHJpbUxlZnQ7XG5leHBvcnRzLnRyaW1SaWdodCA9IHRyaW1SaWdodDtcbmV4cG9ydHMudmVjdG9yTWFnbml0dWRlID0gdmVjdG9yTWFnbml0dWRlO1xuZXhwb3J0cy52ZWN0b3JzQW5nbGUgPSB2ZWN0b3JzQW5nbGU7XG5leHBvcnRzLnZlY3RvcnNSYXRpbyA9IHZlY3RvcnNSYXRpbztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKbWFXeGxJam9pYVc1a1pYZ3VZMnB6SWl3aWMyOTFjbU5sY3lJNlcxMHNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklqczdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096c2lmUT09XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/canvg/lib/index.cjs\n");
|
|
|
|
/***/ })
|
|
|
|
};
|
|
; |