"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/jspdf-autotable";
exports.ids = ["vendor-chunks/jspdf-autotable"];
exports.modules = {
/***/ "(ssr)/./node_modules/jspdf-autotable/dist/jspdf.plugin.autotable.mjs":
/*!**********************************************************************!*\
!*** ./node_modules/jspdf-autotable/dist/jspdf.plugin.autotable.mjs ***!
\**********************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Cell: () => (/* binding */ Cell),\n/* harmony export */ CellHookData: () => (/* binding */ CellHookData),\n/* harmony export */ Column: () => (/* binding */ Column),\n/* harmony export */ HookData: () => (/* binding */ HookData),\n/* harmony export */ Row: () => (/* binding */ Row),\n/* harmony export */ Table: () => (/* binding */ Table),\n/* harmony export */ __createTable: () => (/* binding */ __createTable),\n/* harmony export */ __drawTable: () => (/* binding */ __drawTable),\n/* harmony export */ applyPlugin: () => (/* binding */ applyPlugin),\n/* harmony export */ autoTable: () => (/* binding */ autoTable),\n/* harmony export */ \"default\": () => (/* binding */ autoTable)\n/* harmony export */ });\n/**\n * Improved text function with halign and valign support\n * Inspiration from: http://stackoverflow.com/questions/28327510/align-text-right-using-jspdf/28433113#28433113\n */\nfunction autoTableText (text, x, y, styles, doc) {\n styles = styles || {};\n var PHYSICAL_LINE_HEIGHT = 1.15;\n var k = doc.internal.scaleFactor;\n var fontSize = doc.internal.getFontSize() / k;\n var lineHeightFactor = doc.getLineHeightFactor\n ? doc.getLineHeightFactor()\n : PHYSICAL_LINE_HEIGHT;\n var lineHeight = fontSize * lineHeightFactor;\n var splitRegex = /\\r\\n|\\r|\\n/g;\n var splitText = '';\n var lineCount = 1;\n if (styles.valign === 'middle' ||\n styles.valign === 'bottom' ||\n styles.halign === 'center' ||\n styles.halign === 'right') {\n splitText = typeof text === 'string' ? text.split(splitRegex) : text;\n lineCount = splitText.length || 1;\n }\n // Align the top\n y += fontSize * (2 - PHYSICAL_LINE_HEIGHT);\n if (styles.valign === 'middle')\n y -= (lineCount / 2) * lineHeight;\n else if (styles.valign === 'bottom')\n y -= lineCount * lineHeight;\n if (styles.halign === 'center' || styles.halign === 'right') {\n var alignSize = fontSize;\n if (styles.halign === 'center')\n alignSize *= 0.5;\n if (splitText && lineCount >= 1) {\n for (var iLine = 0; iLine < splitText.length; iLine++) {\n doc.text(splitText[iLine], x - doc.getStringUnitWidth(splitText[iLine]) * alignSize, y);\n y += lineHeight;\n }\n return doc;\n }\n x -= doc.getStringUnitWidth(text) * alignSize;\n }\n if (styles.halign === 'justify') {\n doc.text(text, x, y, { maxWidth: styles.maxWidth || 100, align: 'justify' });\n }\n else {\n doc.text(text, x, y);\n }\n return doc;\n}\n\nvar globalDefaults = {};\nvar DocHandler = /** @class */ (function () {\n function DocHandler(jsPDFDocument) {\n this.jsPDFDocument = jsPDFDocument;\n this.userStyles = {\n // Black for versions of jspdf without getTextColor\n textColor: jsPDFDocument.getTextColor\n ? this.jsPDFDocument.getTextColor()\n : 0,\n fontSize: jsPDFDocument.internal.getFontSize(),\n fontStyle: jsPDFDocument.internal.getFont().fontStyle,\n font: jsPDFDocument.internal.getFont().fontName,\n // 0 for versions of jspdf without getLineWidth\n lineWidth: jsPDFDocument.getLineWidth\n ? this.jsPDFDocument.getLineWidth()\n : 0,\n // Black for versions of jspdf without getDrawColor\n lineColor: jsPDFDocument.getDrawColor\n ? this.jsPDFDocument.getDrawColor()\n : 0,\n };\n }\n DocHandler.setDefaults = function (defaults, doc) {\n if (doc === void 0) { doc = null; }\n if (doc) {\n doc.__autoTableDocumentDefaults = defaults;\n }\n else {\n globalDefaults = defaults;\n }\n };\n DocHandler.unifyColor = function (c) {\n if (Array.isArray(c)) {\n return c;\n }\n else if (typeof c === 'number') {\n return [c, c, c];\n }\n else if (typeof c === 'string') {\n return [c];\n }\n else {\n return null;\n }\n };\n DocHandler.prototype.applyStyles = function (styles, fontOnly) {\n // Font style needs to be applied before font\n // https://github.com/simonbengtsson/jsPDF-AutoTable/issues/632\n var _a, _b, _c;\n if (fontOnly === void 0) { fontOnly = false; }\n if (styles.fontStyle && this.jsPDFDocument.setFontStyle) {\n this.jsPDFDocument.setFontStyle(styles.fontStyle);\n }\n var _d = this.jsPDFDocument.internal.getFont(), fontStyle = _d.fontStyle, fontName = _d.fontName;\n if (styles.font)\n fontName = styles.font;\n if (styles.fontStyle) {\n fontStyle = styles.fontStyle;\n var availableFontStyles = this.getFontList()[fontName];\n if (availableFontStyles &&\n availableFontStyles.indexOf(fontStyle) === -1 &&\n this.jsPDFDocument.setFontStyle) {\n // Common issue was that the default bold in headers\n // made custom fonts not work. For example:\n // https://github.com/simonbengtsson/jsPDF-AutoTable/issues/653\n this.jsPDFDocument.setFontStyle(availableFontStyles[0]);\n fontStyle = availableFontStyles[0];\n }\n }\n this.jsPDFDocument.setFont(fontName, fontStyle);\n if (styles.fontSize)\n this.jsPDFDocument.setFontSize(styles.fontSize);\n if (fontOnly) {\n return; // Performance improvement\n }\n var color = DocHandler.unifyColor(styles.fillColor);\n if (color)\n (_a = this.jsPDFDocument).setFillColor.apply(_a, color);\n color = DocHandler.unifyColor(styles.textColor);\n if (color)\n (_b = this.jsPDFDocument).setTextColor.apply(_b, color);\n color = DocHandler.unifyColor(styles.lineColor);\n if (color)\n (_c = this.jsPDFDocument).setDrawColor.apply(_c, color);\n if (typeof styles.lineWidth === 'number') {\n this.jsPDFDocument.setLineWidth(styles.lineWidth);\n }\n };\n DocHandler.prototype.splitTextToSize = function (text, size, opts) {\n return this.jsPDFDocument.splitTextToSize(text, size, opts);\n };\n /**\n * Adds a rectangle to the PDF\n * @param x Coordinate (in units declared at inception of PDF document) against left edge of the page\n * @param y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n * @param width Width (in units declared at inception of PDF document)\n * @param height Height (in units declared at inception of PDF document)\n * @param fillStyle A string specifying the painting style or null. Valid styles include: 'S' [default] - stroke, 'F' - fill, and 'DF' (or 'FD') - fill then stroke.\n */\n DocHandler.prototype.rect = function (x, y, width, height, fillStyle) {\n // null is excluded from fillStyle possible values because it isn't needed\n // and is prone to bugs as it's used to postpone setting the style\n // https://rawgit.com/MrRio/jsPDF/master/docs/jsPDF.html#rect\n return this.jsPDFDocument.rect(x, y, width, height, fillStyle);\n };\n DocHandler.prototype.getLastAutoTable = function () {\n return this.jsPDFDocument.lastAutoTable || null;\n };\n DocHandler.prototype.getTextWidth = function (text) {\n return this.jsPDFDocument.getTextWidth(text);\n };\n DocHandler.prototype.getDocument = function () {\n return this.jsPDFDocument;\n };\n DocHandler.prototype.setPage = function (page) {\n this.jsPDFDocument.setPage(page);\n };\n DocHandler.prototype.addPage = function () {\n return this.jsPDFDocument.addPage();\n };\n DocHandler.prototype.getFontList = function () {\n return this.jsPDFDocument.getFontList();\n };\n DocHandler.prototype.getGlobalOptions = function () {\n return globalDefaults || {};\n };\n DocHandler.prototype.getDocumentOptions = function () {\n return this.jsPDFDocument.__autoTableDocumentDefaults || {};\n };\n DocHandler.prototype.pageSize = function () {\n var pageSize = this.jsPDFDocument.internal.pageSize;\n // JSPDF 1.4 uses get functions instead of properties on pageSize\n if (pageSize.width == null) {\n pageSize = { width: pageSize.getWidth(), height: pageSize.getHeight() };\n }\n return pageSize;\n };\n DocHandler.prototype.scaleFactor = function () {\n return this.jsPDFDocument.internal.scaleFactor;\n };\n DocHandler.prototype.getLineHeightFactor = function () {\n var doc = this.jsPDFDocument;\n return doc.getLineHeightFactor ? doc.getLineHeightFactor() : 1.15;\n };\n DocHandler.prototype.getLineHeight = function (fontSize) {\n return (fontSize / this.scaleFactor()) * this.getLineHeightFactor();\n };\n DocHandler.prototype.pageNumber = function () {\n var pageInfo = this.jsPDFDocument.internal.getCurrentPageInfo();\n if (!pageInfo) {\n // Only recent versions of jspdf has pageInfo\n return this.jsPDFDocument.internal.getNumberOfPages();\n }\n return pageInfo.pageNumber;\n };\n return DocHandler;\n}());\n\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nfunction __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\ntypeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\n\nvar HtmlRowInput = /** @class */ (function (_super) {\n __extends(HtmlRowInput, _super);\n function HtmlRowInput(element) {\n var _this = _super.call(this) || this;\n _this._element = element;\n return _this;\n }\n return HtmlRowInput;\n}(Array));\n// Base style for all themes\nfunction defaultStyles(scaleFactor) {\n return {\n font: 'helvetica', // helvetica, times, courier\n fontStyle: 'normal', // normal, bold, italic, bolditalic\n overflow: 'linebreak', // linebreak, ellipsize, visible or hidden\n fillColor: false, // Either false for transparent, rbg array e.g. [255, 255, 255] or gray level e.g 200\n textColor: 20,\n halign: 'left', // left, center, right, justify\n valign: 'top', // top, middle, bottom\n fontSize: 10,\n cellPadding: 5 / scaleFactor, // number or {top,left,right,left,vertical,horizontal}\n lineColor: 200,\n lineWidth: 0,\n cellWidth: 'auto', // 'auto'|'wrap'|number\n minCellHeight: 0,\n minCellWidth: 0,\n };\n}\nfunction getTheme(name) {\n var themes = {\n striped: {\n table: { fillColor: 255, textColor: 80, fontStyle: 'normal' },\n head: { textColor: 255, fillColor: [41, 128, 185], fontStyle: 'bold' },\n body: {},\n foot: { textColor: 255, fillColor: [41, 128, 185], fontStyle: 'bold' },\n alternateRow: { fillColor: 245 },\n },\n grid: {\n table: {\n fillColor: 255,\n textColor: 80,\n fontStyle: 'normal',\n lineWidth: 0.1,\n },\n head: {\n textColor: 255,\n fillColor: [26, 188, 156],\n fontStyle: 'bold',\n lineWidth: 0,\n },\n body: {},\n foot: {\n textColor: 255,\n fillColor: [26, 188, 156],\n fontStyle: 'bold',\n lineWidth: 0,\n },\n alternateRow: {},\n },\n plain: { head: { fontStyle: 'bold' }, foot: { fontStyle: 'bold' } },\n };\n return themes[name];\n}\n\nfunction getStringWidth(text, styles, doc) {\n doc.applyStyles(styles, true);\n var textArr = Array.isArray(text) ? text : [text];\n var widestLineWidth = textArr\n .map(function (text) { return doc.getTextWidth(text); })\n .reduce(function (a, b) { return Math.max(a, b); }, 0);\n return widestLineWidth;\n}\nfunction addTableBorder(doc, table, startPos, cursor) {\n var lineWidth = table.settings.tableLineWidth;\n var lineColor = table.settings.tableLineColor;\n doc.applyStyles({ lineWidth: lineWidth, lineColor: lineColor });\n var fillStyle = getFillStyle(lineWidth, false);\n if (fillStyle) {\n doc.rect(startPos.x, startPos.y, table.getWidth(doc.pageSize().width), cursor.y - startPos.y, fillStyle);\n }\n}\nfunction getFillStyle(lineWidth, fillColor) {\n var drawLine = lineWidth > 0;\n var drawBackground = fillColor || fillColor === 0;\n if (drawLine && drawBackground) {\n return 'DF'; // Fill then stroke\n }\n else if (drawLine) {\n return 'S'; // Only stroke (transparent background)\n }\n else if (drawBackground) {\n return 'F'; // Only fill, no stroke\n }\n else {\n return null;\n }\n}\nfunction parseSpacing(value, defaultValue) {\n var _a, _b, _c, _d;\n value = value || defaultValue;\n if (Array.isArray(value)) {\n if (value.length >= 4) {\n return {\n top: value[0],\n right: value[1],\n bottom: value[2],\n left: value[3],\n };\n }\n else if (value.length === 3) {\n return {\n top: value[0],\n right: value[1],\n bottom: value[2],\n left: value[1],\n };\n }\n else if (value.length === 2) {\n return {\n top: value[0],\n right: value[1],\n bottom: value[0],\n left: value[1],\n };\n }\n else if (value.length === 1) {\n value = value[0];\n }\n else {\n value = defaultValue;\n }\n }\n if (typeof value === 'object') {\n if (typeof value.vertical === 'number') {\n value.top = value.vertical;\n value.bottom = value.vertical;\n }\n if (typeof value.horizontal === 'number') {\n value.right = value.horizontal;\n value.left = value.horizontal;\n }\n return {\n left: (_a = value.left) !== null && _a !== void 0 ? _a : defaultValue,\n top: (_b = value.top) !== null && _b !== void 0 ? _b : defaultValue,\n right: (_c = value.right) !== null && _c !== void 0 ? _c : defaultValue,\n bottom: (_d = value.bottom) !== null && _d !== void 0 ? _d : defaultValue,\n };\n }\n if (typeof value !== 'number') {\n value = defaultValue;\n }\n return { top: value, right: value, bottom: value, left: value };\n}\nfunction getPageAvailableWidth(doc, table) {\n var margins = parseSpacing(table.settings.margin, 0);\n return doc.pageSize().width - (margins.left + margins.right);\n}\n\n// Limitations\n// - No support for border spacing\n// - No support for transparency\nfunction parseCss(supportedFonts, element, scaleFactor, style, window) {\n var result = {};\n var pxScaleFactor = 96 / 72;\n var backgroundColor = parseColor(element, function (elem) {\n return window.getComputedStyle(elem)['backgroundColor'];\n });\n if (backgroundColor != null)\n result.fillColor = backgroundColor;\n var textColor = parseColor(element, function (elem) {\n return window.getComputedStyle(elem)['color'];\n });\n if (textColor != null)\n result.textColor = textColor;\n var padding = parsePadding(style, scaleFactor);\n if (padding)\n result.cellPadding = padding;\n var borderColorSide = 'borderTopColor';\n var finalScaleFactor = pxScaleFactor * scaleFactor;\n var btw = style.borderTopWidth;\n if (style.borderBottomWidth === btw &&\n style.borderRightWidth === btw &&\n style.borderLeftWidth === btw) {\n var borderWidth = (parseFloat(btw) || 0) / finalScaleFactor;\n if (borderWidth)\n result.lineWidth = borderWidth;\n }\n else {\n result.lineWidth = {\n top: (parseFloat(style.borderTopWidth) || 0) / finalScaleFactor,\n right: (parseFloat(style.borderRightWidth) || 0) / finalScaleFactor,\n bottom: (parseFloat(style.borderBottomWidth) || 0) / finalScaleFactor,\n left: (parseFloat(style.borderLeftWidth) || 0) / finalScaleFactor,\n };\n // Choose border color of first available side\n // could be improved by supporting object as lineColor\n if (!result.lineWidth.top) {\n if (result.lineWidth.right) {\n borderColorSide = 'borderRightColor';\n }\n else if (result.lineWidth.bottom) {\n borderColorSide = 'borderBottomColor';\n }\n else if (result.lineWidth.left) {\n borderColorSide = 'borderLeftColor';\n }\n }\n }\n var borderColor = parseColor(element, function (elem) {\n return window.getComputedStyle(elem)[borderColorSide];\n });\n if (borderColor != null)\n result.lineColor = borderColor;\n var accepted = ['left', 'right', 'center', 'justify'];\n if (accepted.indexOf(style.textAlign) !== -1) {\n result.halign = style.textAlign;\n }\n accepted = ['middle', 'bottom', 'top'];\n if (accepted.indexOf(style.verticalAlign) !== -1) {\n result.valign = style.verticalAlign;\n }\n var res = parseInt(style.fontSize || '');\n if (!isNaN(res))\n result.fontSize = res / pxScaleFactor;\n var fontStyle = parseFontStyle(style);\n if (fontStyle)\n result.fontStyle = fontStyle;\n var font = (style.fontFamily || '').toLowerCase();\n if (supportedFonts.indexOf(font) !== -1) {\n result.font = font;\n }\n return result;\n}\nfunction parseFontStyle(style) {\n var res = '';\n if (style.fontWeight === 'bold' ||\n style.fontWeight === 'bolder' ||\n parseInt(style.fontWeight) >= 700) {\n res = 'bold';\n }\n if (style.fontStyle === 'italic' || style.fontStyle === 'oblique') {\n res += 'italic';\n }\n return res;\n}\nfunction parseColor(element, styleGetter) {\n var cssColor = realColor(element, styleGetter);\n if (!cssColor)\n return null;\n var rgba = cssColor.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d*\\.?\\d*))?\\)$/);\n if (!rgba || !Array.isArray(rgba)) {\n return null;\n }\n var color = [\n parseInt(rgba[1]),\n parseInt(rgba[2]),\n parseInt(rgba[3]),\n ];\n var alpha = parseInt(rgba[4]);\n if (alpha === 0 || isNaN(color[0]) || isNaN(color[1]) || isNaN(color[2])) {\n return null;\n }\n return color;\n}\nfunction realColor(elem, styleGetter) {\n var bg = styleGetter(elem);\n if (bg === 'rgba(0, 0, 0, 0)' ||\n bg === 'transparent' ||\n bg === 'initial' ||\n bg === 'inherit') {\n if (elem.parentElement == null) {\n return null;\n }\n return realColor(elem.parentElement, styleGetter);\n }\n else {\n return bg;\n }\n}\nfunction parsePadding(style, scaleFactor) {\n var val = [\n style.paddingTop,\n style.paddingRight,\n style.paddingBottom,\n style.paddingLeft,\n ];\n var pxScaleFactor = 96 / (72 / scaleFactor);\n var linePadding = (parseInt(style.lineHeight) - parseInt(style.fontSize)) / scaleFactor / 2;\n var inputPadding = val.map(function (n) {\n return parseInt(n || '0') / pxScaleFactor;\n });\n var padding = parseSpacing(inputPadding, 0);\n if (linePadding > padding.top) {\n padding.top = linePadding;\n }\n if (linePadding > padding.bottom) {\n padding.bottom = linePadding;\n }\n return padding;\n}\n\nfunction parseHtml(doc, input, window, includeHiddenHtml, useCss) {\n var _a, _b;\n if (includeHiddenHtml === void 0) { includeHiddenHtml = false; }\n if (useCss === void 0) { useCss = false; }\n var tableElement;\n if (typeof input === 'string') {\n tableElement = window.document.querySelector(input);\n }\n else {\n tableElement = input;\n }\n var supportedFonts = Object.keys(doc.getFontList());\n var scaleFactor = doc.scaleFactor();\n var head = [], body = [], foot = [];\n if (!tableElement) {\n console.error('Html table could not be found with input: ', input);\n return { head: head, body: body, foot: foot };\n }\n for (var i = 0; i < tableElement.rows.length; i++) {\n var element = tableElement.rows[i];\n var tagName = (_b = (_a = element === null || element === void 0 ? void 0 : element.parentElement) === null || _a === void 0 ? void 0 : _a.tagName) === null || _b === void 0 ? void 0 : _b.toLowerCase();\n var row = parseRowContent(supportedFonts, scaleFactor, window, element, includeHiddenHtml, useCss);\n if (!row)\n continue;\n if (tagName === 'thead') {\n head.push(row);\n }\n else if (tagName === 'tfoot') {\n foot.push(row);\n }\n else {\n // Add to body both if parent is tbody or table\n body.push(row);\n }\n }\n return { head: head, body: body, foot: foot };\n}\nfunction parseRowContent(supportedFonts, scaleFactor, window, row, includeHidden, useCss) {\n var resultRow = new HtmlRowInput(row);\n for (var i = 0; i < row.cells.length; i++) {\n var cell = row.cells[i];\n var style_1 = window.getComputedStyle(cell);\n if (includeHidden || style_1.display !== 'none') {\n var cellStyles = void 0;\n if (useCss) {\n cellStyles = parseCss(supportedFonts, cell, scaleFactor, style_1, window);\n }\n resultRow.push({\n rowSpan: cell.rowSpan,\n colSpan: cell.colSpan,\n styles: cellStyles,\n _element: cell,\n content: parseCellContent(cell),\n });\n }\n }\n var style = window.getComputedStyle(row);\n if (resultRow.length > 0 && (includeHidden || style.display !== 'none')) {\n return resultRow;\n }\n}\nfunction parseCellContent(orgCell) {\n // Work on cloned node to make sure no changes are applied to html table\n var cell = orgCell.cloneNode(true);\n // Remove extra space and line breaks in markup to make it more similar to\n // what would be shown in html\n cell.innerHTML = cell.innerHTML.replace(/\\n/g, '').replace(/ +/g, ' ');\n // Preserve
tags as line breaks in the pdf\n cell.innerHTML = cell.innerHTML\n .split(//) //start with '
'.\n .map(function (part) { return part.trim(); })\n .join('\\n');\n // innerText for ie\n return cell.innerText || cell.textContent || '';\n}\n\nfunction validateInput(global, document, current) {\n for (var _i = 0, _a = [global, document, current]; _i < _a.length; _i++) {\n var options = _a[_i];\n if (options && typeof options !== 'object') {\n console.error('The options parameter should be of type object, is: ' + typeof options);\n }\n if (options.startY && typeof options.startY !== 'number') {\n console.error('Invalid value for startY option', options.startY);\n delete options.startY;\n }\n }\n}\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\nfunction assign(target, s, s1, s2, s3) {\n if (target == null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n var to = Object(target);\n for (var index = 1; index < arguments.length; index++) {\n // eslint-disable-next-line prefer-rest-params\n var nextSource = arguments[index];\n if (nextSource != null) {\n // Skip over if undefined or null\n for (var nextKey in nextSource) {\n // Avoid bugs when hasOwnProperty is shadowed\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n}\n\nfunction parseInput(d, current) {\n var doc = new DocHandler(d);\n var document = doc.getDocumentOptions();\n var global = doc.getGlobalOptions();\n validateInput(global, document, current);\n var options = assign({}, global, document, current);\n var win;\n if (typeof window !== 'undefined') {\n win = window;\n }\n var styles = parseStyles(global, document, current);\n var hooks = parseHooks(global, document, current);\n var settings = parseSettings(doc, options);\n var content = parseContent$1(doc, options, win);\n return { id: current.tableId, content: content, hooks: hooks, styles: styles, settings: settings };\n}\nfunction parseStyles(gInput, dInput, cInput) {\n var styleOptions = {\n styles: {},\n headStyles: {},\n bodyStyles: {},\n footStyles: {},\n alternateRowStyles: {},\n columnStyles: {},\n };\n var _loop_1 = function (prop) {\n if (prop === 'columnStyles') {\n var global = gInput[prop];\n var document_1 = dInput[prop];\n var current = cInput[prop];\n styleOptions.columnStyles = assign({}, global, document_1, current);\n }\n else {\n var allOptions = [gInput, dInput, cInput];\n var styles = allOptions.map(function (opts) { return opts[prop] || {}; });\n styleOptions[prop] = assign({}, styles[0], styles[1], styles[2]);\n }\n };\n for (var _i = 0, _a = Object.keys(styleOptions); _i < _a.length; _i++) {\n var prop = _a[_i];\n _loop_1(prop);\n }\n return styleOptions;\n}\nfunction parseHooks(global, document, current) {\n var allOptions = [global, document, current];\n var result = {\n didParseCell: [],\n willDrawCell: [],\n didDrawCell: [],\n willDrawPage: [],\n didDrawPage: [],\n };\n for (var _i = 0, allOptions_1 = allOptions; _i < allOptions_1.length; _i++) {\n var options = allOptions_1[_i];\n if (options.didParseCell)\n result.didParseCell.push(options.didParseCell);\n if (options.willDrawCell)\n result.willDrawCell.push(options.willDrawCell);\n if (options.didDrawCell)\n result.didDrawCell.push(options.didDrawCell);\n if (options.willDrawPage)\n result.willDrawPage.push(options.willDrawPage);\n if (options.didDrawPage)\n result.didDrawPage.push(options.didDrawPage);\n }\n return result;\n}\nfunction parseSettings(doc, options) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;\n var margin = parseSpacing(options.margin, 40 / doc.scaleFactor());\n var startY = (_a = getStartY(doc, options.startY)) !== null && _a !== void 0 ? _a : margin.top;\n var showFoot;\n if (options.showFoot === true) {\n showFoot = 'everyPage';\n }\n else if (options.showFoot === false) {\n showFoot = 'never';\n }\n else {\n showFoot = (_b = options.showFoot) !== null && _b !== void 0 ? _b : 'everyPage';\n }\n var showHead;\n if (options.showHead === true) {\n showHead = 'everyPage';\n }\n else if (options.showHead === false) {\n showHead = 'never';\n }\n else {\n showHead = (_c = options.showHead) !== null && _c !== void 0 ? _c : 'everyPage';\n }\n var useCss = (_d = options.useCss) !== null && _d !== void 0 ? _d : false;\n var theme = options.theme || (useCss ? 'plain' : 'striped');\n var horizontalPageBreak = !!options.horizontalPageBreak;\n var horizontalPageBreakRepeat = (_e = options.horizontalPageBreakRepeat) !== null && _e !== void 0 ? _e : null;\n return {\n includeHiddenHtml: (_f = options.includeHiddenHtml) !== null && _f !== void 0 ? _f : false,\n useCss: useCss,\n theme: theme,\n startY: startY,\n margin: margin,\n pageBreak: (_g = options.pageBreak) !== null && _g !== void 0 ? _g : 'auto',\n rowPageBreak: (_h = options.rowPageBreak) !== null && _h !== void 0 ? _h : 'auto',\n tableWidth: (_j = options.tableWidth) !== null && _j !== void 0 ? _j : 'auto',\n showHead: showHead,\n showFoot: showFoot,\n tableLineWidth: (_k = options.tableLineWidth) !== null && _k !== void 0 ? _k : 0,\n tableLineColor: (_l = options.tableLineColor) !== null && _l !== void 0 ? _l : 200,\n horizontalPageBreak: horizontalPageBreak,\n horizontalPageBreakRepeat: horizontalPageBreakRepeat,\n horizontalPageBreakBehaviour: (_m = options.horizontalPageBreakBehaviour) !== null && _m !== void 0 ? _m : 'afterAllRows',\n };\n}\nfunction getStartY(doc, userStartY) {\n var previous = doc.getLastAutoTable();\n var sf = doc.scaleFactor();\n var currentPage = doc.pageNumber();\n var isSamePageAsPreviousTable = false;\n if (previous && previous.startPageNumber) {\n var endingPage = previous.startPageNumber + previous.pageNumber - 1;\n isSamePageAsPreviousTable = endingPage === currentPage;\n }\n if (typeof userStartY === 'number') {\n return userStartY;\n }\n else if (userStartY == null || userStartY === false) {\n if (isSamePageAsPreviousTable && (previous === null || previous === void 0 ? void 0 : previous.finalY) != null) {\n // Some users had issues with overlapping tables when they used multiple\n // tables without setting startY so setting it here to a sensible default.\n return previous.finalY + 20 / sf;\n }\n }\n return null;\n}\nfunction parseContent$1(doc, options, window) {\n var head = options.head || [];\n var body = options.body || [];\n var foot = options.foot || [];\n if (options.html) {\n var hidden = options.includeHiddenHtml;\n if (window) {\n var htmlContent = parseHtml(doc, options.html, window, hidden, options.useCss) || {};\n head = htmlContent.head || head;\n body = htmlContent.body || head;\n foot = htmlContent.foot || head;\n }\n else {\n console.error('Cannot parse html in non browser environment');\n }\n }\n var columns = options.columns || parseColumns(head, body, foot);\n return { columns: columns, head: head, body: body, foot: foot };\n}\nfunction parseColumns(head, body, foot) {\n var firstRow = head[0] || body[0] || foot[0] || [];\n var result = [];\n Object.keys(firstRow)\n .filter(function (key) { return key !== '_element'; })\n .forEach(function (key) {\n var colSpan = 1;\n var input;\n if (Array.isArray(firstRow)) {\n input = firstRow[parseInt(key)];\n }\n else {\n input = firstRow[key];\n }\n if (typeof input === 'object' && !Array.isArray(input)) {\n colSpan = (input === null || input === void 0 ? void 0 : input.colSpan) || 1;\n }\n for (var i = 0; i < colSpan; i++) {\n var id = void 0;\n if (Array.isArray(firstRow)) {\n id = result.length;\n }\n else {\n id = key + (i > 0 ? \"_\".concat(i) : '');\n }\n var rowResult = { dataKey: id };\n result.push(rowResult);\n }\n });\n return result;\n}\n\nvar HookData = /** @class */ (function () {\n function HookData(doc, table, cursor) {\n this.table = table;\n this.pageNumber = table.pageNumber;\n this.settings = table.settings;\n this.cursor = cursor;\n this.doc = doc.getDocument();\n }\n return HookData;\n}());\nvar CellHookData = /** @class */ (function (_super) {\n __extends(CellHookData, _super);\n function CellHookData(doc, table, cell, row, column, cursor) {\n var _this = _super.call(this, doc, table, cursor) || this;\n _this.cell = cell;\n _this.row = row;\n _this.column = column;\n _this.section = row.section;\n return _this;\n }\n return CellHookData;\n}(HookData));\n\nvar Table = /** @class */ (function () {\n function Table(input, content) {\n this.pageNumber = 1;\n this.id = input.id;\n this.settings = input.settings;\n this.styles = input.styles;\n this.hooks = input.hooks;\n this.columns = content.columns;\n this.head = content.head;\n this.body = content.body;\n this.foot = content.foot;\n }\n Table.prototype.getHeadHeight = function (columns) {\n return this.head.reduce(function (acc, row) { return acc + row.getMaxCellHeight(columns); }, 0);\n };\n Table.prototype.getFootHeight = function (columns) {\n return this.foot.reduce(function (acc, row) { return acc + row.getMaxCellHeight(columns); }, 0);\n };\n Table.prototype.allRows = function () {\n return this.head.concat(this.body).concat(this.foot);\n };\n Table.prototype.callCellHooks = function (doc, handlers, cell, row, column, cursor) {\n for (var _i = 0, handlers_1 = handlers; _i < handlers_1.length; _i++) {\n var handler = handlers_1[_i];\n var data = new CellHookData(doc, this, cell, row, column, cursor);\n var result = handler(data) === false;\n // Make sure text is always string[] since user can assign string\n cell.text = Array.isArray(cell.text) ? cell.text : [cell.text];\n if (result) {\n return false;\n }\n }\n return true;\n };\n Table.prototype.callEndPageHooks = function (doc, cursor) {\n doc.applyStyles(doc.userStyles);\n for (var _i = 0, _a = this.hooks.didDrawPage; _i < _a.length; _i++) {\n var handler = _a[_i];\n handler(new HookData(doc, this, cursor));\n }\n };\n Table.prototype.callWillDrawPageHooks = function (doc, cursor) {\n for (var _i = 0, _a = this.hooks.willDrawPage; _i < _a.length; _i++) {\n var handler = _a[_i];\n handler(new HookData(doc, this, cursor));\n }\n };\n Table.prototype.getWidth = function (pageWidth) {\n if (typeof this.settings.tableWidth === 'number') {\n return this.settings.tableWidth;\n }\n else if (this.settings.tableWidth === 'wrap') {\n var wrappedWidth = this.columns.reduce(function (total, col) { return total + col.wrappedWidth; }, 0);\n return wrappedWidth;\n }\n else {\n var margin = this.settings.margin;\n return pageWidth - margin.left - margin.right;\n }\n };\n return Table;\n}());\nvar Row = /** @class */ (function () {\n function Row(raw, index, section, cells, spansMultiplePages) {\n if (spansMultiplePages === void 0) { spansMultiplePages = false; }\n this.height = 0;\n this.raw = raw;\n if (raw instanceof HtmlRowInput) {\n this.raw = raw._element;\n this.element = raw._element;\n }\n this.index = index;\n this.section = section;\n this.cells = cells;\n this.spansMultiplePages = spansMultiplePages;\n }\n Row.prototype.getMaxCellHeight = function (columns) {\n var _this = this;\n return columns.reduce(function (acc, column) { var _a; return Math.max(acc, ((_a = _this.cells[column.index]) === null || _a === void 0 ? void 0 : _a.height) || 0); }, 0);\n };\n Row.prototype.hasRowSpan = function (columns) {\n var _this = this;\n return (columns.filter(function (column) {\n var cell = _this.cells[column.index];\n if (!cell)\n return false;\n return cell.rowSpan > 1;\n }).length > 0);\n };\n Row.prototype.canEntireRowFit = function (height, columns) {\n return this.getMaxCellHeight(columns) <= height;\n };\n Row.prototype.getMinimumRowHeight = function (columns, doc) {\n var _this = this;\n return columns.reduce(function (acc, column) {\n var cell = _this.cells[column.index];\n if (!cell)\n return 0;\n var lineHeight = doc.getLineHeight(cell.styles.fontSize);\n var vPadding = cell.padding('vertical');\n var oneRowHeight = vPadding + lineHeight;\n return oneRowHeight > acc ? oneRowHeight : acc;\n }, 0);\n };\n return Row;\n}());\nvar Cell = /** @class */ (function () {\n function Cell(raw, styles, section) {\n var _a;\n this.contentHeight = 0;\n this.contentWidth = 0;\n this.wrappedWidth = 0;\n this.minReadableWidth = 0;\n this.minWidth = 0;\n this.width = 0;\n this.height = 0;\n this.x = 0;\n this.y = 0;\n this.styles = styles;\n this.section = section;\n this.raw = raw;\n var content = raw;\n if (raw != null && typeof raw === 'object' && !Array.isArray(raw)) {\n this.rowSpan = raw.rowSpan || 1;\n this.colSpan = raw.colSpan || 1;\n content = (_a = raw.content) !== null && _a !== void 0 ? _a : raw;\n if (raw._element) {\n this.raw = raw._element;\n }\n }\n else {\n this.rowSpan = 1;\n this.colSpan = 1;\n }\n // Stringify 0 and false, but not undefined or null\n var text = content != null ? '' + content : '';\n var splitRegex = /\\r\\n|\\r|\\n/g;\n this.text = text.split(splitRegex);\n }\n Cell.prototype.getTextPos = function () {\n var y;\n if (this.styles.valign === 'top') {\n y = this.y + this.padding('top');\n }\n else if (this.styles.valign === 'bottom') {\n y = this.y + this.height - this.padding('bottom');\n }\n else {\n var netHeight = this.height - this.padding('vertical');\n y = this.y + netHeight / 2 + this.padding('top');\n }\n var x;\n if (this.styles.halign === 'right') {\n x = this.x + this.width - this.padding('right');\n }\n else if (this.styles.halign === 'center') {\n var netWidth = this.width - this.padding('horizontal');\n x = this.x + netWidth / 2 + this.padding('left');\n }\n else {\n x = this.x + this.padding('left');\n }\n return { x: x, y: y };\n };\n // TODO (v4): replace parameters with only (lineHeight)\n Cell.prototype.getContentHeight = function (scaleFactor, lineHeightFactor) {\n if (lineHeightFactor === void 0) { lineHeightFactor = 1.15; }\n var lineCount = Array.isArray(this.text) ? this.text.length : 1;\n var lineHeight = (this.styles.fontSize / scaleFactor) * lineHeightFactor;\n var height = lineCount * lineHeight + this.padding('vertical');\n return Math.max(height, this.styles.minCellHeight);\n };\n Cell.prototype.padding = function (name) {\n var padding = parseSpacing(this.styles.cellPadding, 0);\n if (name === 'vertical') {\n return padding.top + padding.bottom;\n }\n else if (name === 'horizontal') {\n return padding.left + padding.right;\n }\n else {\n return padding[name];\n }\n };\n return Cell;\n}());\nvar Column = /** @class */ (function () {\n function Column(dataKey, raw, index) {\n this.wrappedWidth = 0;\n this.minReadableWidth = 0;\n this.minWidth = 0;\n this.width = 0;\n this.dataKey = dataKey;\n this.raw = raw;\n this.index = index;\n }\n Column.prototype.getMaxCustomCellWidth = function (table) {\n var max = 0;\n for (var _i = 0, _a = table.allRows(); _i < _a.length; _i++) {\n var row = _a[_i];\n var cell = row.cells[this.index];\n if (cell && typeof cell.styles.cellWidth === 'number') {\n max = Math.max(max, cell.styles.cellWidth);\n }\n }\n return max;\n };\n return Column;\n}());\n\n/**\n * Calculate the column widths\n */\nfunction calculateWidths(doc, table) {\n calculate(doc, table);\n var resizableColumns = [];\n var initialTableWidth = 0;\n table.columns.forEach(function (column) {\n var customWidth = column.getMaxCustomCellWidth(table);\n if (customWidth) {\n // final column width\n column.width = customWidth;\n }\n else {\n // initial column width (will be resized)\n column.width = column.wrappedWidth;\n resizableColumns.push(column);\n }\n initialTableWidth += column.width;\n });\n // width difference that needs to be distributed\n var resizeWidth = table.getWidth(doc.pageSize().width) - initialTableWidth;\n // first resize attempt: with respect to minReadableWidth and minWidth\n if (resizeWidth) {\n resizeWidth = resizeColumns(resizableColumns, resizeWidth, function (column) {\n return Math.max(column.minReadableWidth, column.minWidth);\n });\n }\n // second resize attempt: ignore minReadableWidth but respect minWidth\n if (resizeWidth) {\n resizeWidth = resizeColumns(resizableColumns, resizeWidth, function (column) { return column.minWidth; });\n }\n resizeWidth = Math.abs(resizeWidth);\n if (!table.settings.horizontalPageBreak &&\n resizeWidth > 0.1 / doc.scaleFactor()) {\n // Table can't get smaller due to custom-width or minWidth restrictions\n // We can't really do much here. Up to user to for example\n // reduce font size, increase page size or remove custom cell widths\n // to allow more columns to be reduced in size\n resizeWidth = resizeWidth < 1 ? resizeWidth : Math.round(resizeWidth);\n console.log(\"Of the table content, \".concat(resizeWidth, \" units width could not fit page\"));\n }\n applyColSpans(table);\n fitContent(table, doc);\n applyRowSpans(table);\n}\nfunction calculate(doc, table) {\n var sf = doc.scaleFactor();\n var horizontalPageBreak = table.settings.horizontalPageBreak;\n var availablePageWidth = getPageAvailableWidth(doc, table);\n table.allRows().forEach(function (row) {\n for (var _i = 0, _a = table.columns; _i < _a.length; _i++) {\n var column = _a[_i];\n var cell = row.cells[column.index];\n if (!cell)\n continue;\n var hooks = table.hooks.didParseCell;\n table.callCellHooks(doc, hooks, cell, row, column, null);\n var padding = cell.padding('horizontal');\n cell.contentWidth = getStringWidth(cell.text, cell.styles, doc) + padding;\n // Using [^\\S\\u00A0] instead of \\s ensures that we split the text on all\n // whitespace except non-breaking spaces (\\u00A0). We need to preserve\n // them in the split process to ensure correct word separation and width\n // calculation.\n var longestWordWidth = getStringWidth(cell.text.join(' ').split(/[^\\S\\u00A0]+/), cell.styles, doc);\n cell.minReadableWidth = longestWordWidth + cell.padding('horizontal');\n if (typeof cell.styles.cellWidth === 'number') {\n cell.minWidth = cell.styles.cellWidth;\n cell.wrappedWidth = cell.styles.cellWidth;\n }\n else if (cell.styles.cellWidth === 'wrap' ||\n horizontalPageBreak === true) {\n // cell width should not be more than available page width\n if (cell.contentWidth > availablePageWidth) {\n cell.minWidth = availablePageWidth;\n cell.wrappedWidth = availablePageWidth;\n }\n else {\n cell.minWidth = cell.contentWidth;\n cell.wrappedWidth = cell.contentWidth;\n }\n }\n else {\n // auto\n var defaultMinWidth = 10 / sf;\n cell.minWidth = cell.styles.minCellWidth || defaultMinWidth;\n cell.wrappedWidth = cell.contentWidth;\n if (cell.minWidth > cell.wrappedWidth) {\n cell.wrappedWidth = cell.minWidth;\n }\n }\n }\n });\n table.allRows().forEach(function (row) {\n for (var _i = 0, _a = table.columns; _i < _a.length; _i++) {\n var column = _a[_i];\n var cell = row.cells[column.index];\n // For now we ignore the minWidth and wrappedWidth of colspan cells when calculating colspan widths.\n // Could probably be improved upon however.\n if (cell && cell.colSpan === 1) {\n column.wrappedWidth = Math.max(column.wrappedWidth, cell.wrappedWidth);\n column.minWidth = Math.max(column.minWidth, cell.minWidth);\n column.minReadableWidth = Math.max(column.minReadableWidth, cell.minReadableWidth);\n }\n else {\n // Respect cellWidth set in columnStyles even if there is no cells for this column\n // or if the column only have colspan cells. Since the width of colspan cells\n // does not affect the width of columns, setting columnStyles cellWidth enables the\n // user to at least do it manually.\n // Note that this is not perfect for now since for example row and table styles are\n // not accounted for\n var columnStyles = table.styles.columnStyles[column.dataKey] ||\n table.styles.columnStyles[column.index] ||\n {};\n var cellWidth = columnStyles.cellWidth || columnStyles.minCellWidth;\n if (cellWidth && typeof cellWidth === 'number') {\n column.minWidth = cellWidth;\n column.wrappedWidth = cellWidth;\n }\n }\n if (cell) {\n // Make sure all columns get at least min width even though width calculations are not based on them\n if (cell.colSpan > 1 && !column.minWidth) {\n column.minWidth = cell.minWidth;\n }\n if (cell.colSpan > 1 && !column.wrappedWidth) {\n column.wrappedWidth = cell.minWidth;\n }\n }\n }\n });\n}\n/**\n * Distribute resizeWidth on passed resizable columns\n */\nfunction resizeColumns(columns, resizeWidth, getMinWidth) {\n var initialResizeWidth = resizeWidth;\n var sumWrappedWidth = columns.reduce(function (acc, column) { return acc + column.wrappedWidth; }, 0);\n for (var i = 0; i < columns.length; i++) {\n var column = columns[i];\n var ratio = column.wrappedWidth / sumWrappedWidth;\n var suggestedChange = initialResizeWidth * ratio;\n var suggestedWidth = column.width + suggestedChange;\n var minWidth = getMinWidth(column);\n var newWidth = suggestedWidth < minWidth ? minWidth : suggestedWidth;\n resizeWidth -= newWidth - column.width;\n column.width = newWidth;\n }\n resizeWidth = Math.round(resizeWidth * 1e10) / 1e10;\n // Run the resizer again if there's remaining width needs\n // to be distributed and there're columns that can be resized\n if (resizeWidth) {\n var resizableColumns = columns.filter(function (column) {\n return resizeWidth < 0\n ? column.width > getMinWidth(column) // check if column can shrink\n : true; // check if column can grow\n });\n if (resizableColumns.length) {\n resizeWidth = resizeColumns(resizableColumns, resizeWidth, getMinWidth);\n }\n }\n return resizeWidth;\n}\nfunction applyRowSpans(table) {\n var rowSpanCells = {};\n var colRowSpansLeft = 1;\n var all = table.allRows();\n for (var rowIndex = 0; rowIndex < all.length; rowIndex++) {\n var row = all[rowIndex];\n for (var _i = 0, _a = table.columns; _i < _a.length; _i++) {\n var column = _a[_i];\n var data = rowSpanCells[column.index];\n if (colRowSpansLeft > 1) {\n colRowSpansLeft--;\n delete row.cells[column.index];\n }\n else if (data) {\n data.cell.height += row.height;\n colRowSpansLeft = data.cell.colSpan;\n delete row.cells[column.index];\n data.left--;\n if (data.left <= 1) {\n delete rowSpanCells[column.index];\n }\n }\n else {\n var cell = row.cells[column.index];\n if (!cell) {\n continue;\n }\n cell.height = row.height;\n if (cell.rowSpan > 1) {\n var remaining = all.length - rowIndex;\n var left = cell.rowSpan > remaining ? remaining : cell.rowSpan;\n rowSpanCells[column.index] = { cell: cell, left: left, row: row };\n }\n }\n }\n }\n}\nfunction applyColSpans(table) {\n var all = table.allRows();\n for (var rowIndex = 0; rowIndex < all.length; rowIndex++) {\n var row = all[rowIndex];\n var colSpanCell = null;\n var combinedColSpanWidth = 0;\n var colSpansLeft = 0;\n for (var columnIndex = 0; columnIndex < table.columns.length; columnIndex++) {\n var column = table.columns[columnIndex];\n // Width and colspan\n colSpansLeft -= 1;\n if (colSpansLeft > 1 && table.columns[columnIndex + 1]) {\n combinedColSpanWidth += column.width;\n delete row.cells[column.index];\n }\n else if (colSpanCell) {\n var cell = colSpanCell;\n delete row.cells[column.index];\n colSpanCell = null;\n cell.width = column.width + combinedColSpanWidth;\n }\n else {\n var cell = row.cells[column.index];\n if (!cell)\n continue;\n colSpansLeft = cell.colSpan;\n combinedColSpanWidth = 0;\n if (cell.colSpan > 1) {\n colSpanCell = cell;\n combinedColSpanWidth += column.width;\n continue;\n }\n cell.width = column.width + combinedColSpanWidth;\n }\n }\n }\n}\nfunction fitContent(table, doc) {\n var rowSpanHeight = { count: 0, height: 0 };\n for (var _i = 0, _a = table.allRows(); _i < _a.length; _i++) {\n var row = _a[_i];\n for (var _b = 0, _c = table.columns; _b < _c.length; _b++) {\n var column = _c[_b];\n var cell = row.cells[column.index];\n if (!cell)\n continue;\n doc.applyStyles(cell.styles, true);\n var textSpace = cell.width - cell.padding('horizontal');\n if (cell.styles.overflow === 'linebreak') {\n // Add one pt to textSpace to fix rounding error\n cell.text = doc.splitTextToSize(cell.text, textSpace + 1 / doc.scaleFactor(), { fontSize: cell.styles.fontSize });\n }\n else if (cell.styles.overflow === 'ellipsize') {\n cell.text = ellipsize(cell.text, textSpace, cell.styles, doc, '...');\n }\n else if (cell.styles.overflow === 'hidden') {\n cell.text = ellipsize(cell.text, textSpace, cell.styles, doc, '');\n }\n else if (typeof cell.styles.overflow === 'function') {\n var result = cell.styles.overflow(cell.text, textSpace);\n if (typeof result === 'string') {\n cell.text = [result];\n }\n else {\n cell.text = result;\n }\n }\n cell.contentHeight = cell.getContentHeight(doc.scaleFactor(), doc.getLineHeightFactor());\n var realContentHeight = cell.contentHeight / cell.rowSpan;\n if (cell.rowSpan > 1 &&\n rowSpanHeight.count * rowSpanHeight.height <\n realContentHeight * cell.rowSpan) {\n rowSpanHeight = { height: realContentHeight, count: cell.rowSpan };\n }\n else if (rowSpanHeight && rowSpanHeight.count > 0) {\n if (rowSpanHeight.height > realContentHeight) {\n realContentHeight = rowSpanHeight.height;\n }\n }\n if (realContentHeight > row.height) {\n row.height = realContentHeight;\n }\n }\n rowSpanHeight.count--;\n }\n}\nfunction ellipsize(text, width, styles, doc, overflow) {\n return text.map(function (str) { return ellipsizeStr(str, width, styles, doc, overflow); });\n}\nfunction ellipsizeStr(text, width, styles, doc, overflow) {\n var precision = 10000 * doc.scaleFactor();\n width = Math.ceil(width * precision) / precision;\n if (width >= getStringWidth(text, styles, doc)) {\n return text;\n }\n while (width < getStringWidth(text + overflow, styles, doc)) {\n if (text.length <= 1) {\n break;\n }\n text = text.substring(0, text.length - 1);\n }\n return text.trim() + overflow;\n}\n\nfunction createTable(jsPDFDoc, input) {\n var doc = new DocHandler(jsPDFDoc);\n var content = parseContent(input, doc.scaleFactor());\n var table = new Table(input, content);\n calculateWidths(doc, table);\n doc.applyStyles(doc.userStyles);\n return table;\n}\nfunction parseContent(input, sf) {\n var content = input.content;\n var columns = createColumns(content.columns);\n // If no head or foot is set, try generating it with content from columns\n if (content.head.length === 0) {\n var sectionRow = generateSectionRow(columns, 'head');\n if (sectionRow)\n content.head.push(sectionRow);\n }\n if (content.foot.length === 0) {\n var sectionRow = generateSectionRow(columns, 'foot');\n if (sectionRow)\n content.foot.push(sectionRow);\n }\n var theme = input.settings.theme;\n var styles = input.styles;\n return {\n columns: columns,\n head: parseSection('head', content.head, columns, styles, theme, sf),\n body: parseSection('body', content.body, columns, styles, theme, sf),\n foot: parseSection('foot', content.foot, columns, styles, theme, sf),\n };\n}\nfunction parseSection(sectionName, sectionRows, columns, styleProps, theme, scaleFactor) {\n var rowSpansLeftForColumn = {};\n var result = sectionRows.map(function (rawRow, rowIndex) {\n var skippedRowForRowSpans = 0;\n var cells = {};\n var colSpansAdded = 0;\n var columnSpansLeft = 0;\n for (var _i = 0, columns_1 = columns; _i < columns_1.length; _i++) {\n var column = columns_1[_i];\n if (rowSpansLeftForColumn[column.index] == null ||\n rowSpansLeftForColumn[column.index].left === 0) {\n if (columnSpansLeft === 0) {\n var rawCell = void 0;\n if (Array.isArray(rawRow)) {\n rawCell =\n rawRow[column.index - colSpansAdded - skippedRowForRowSpans];\n }\n else {\n rawCell = rawRow[column.dataKey];\n }\n var cellInputStyles = {};\n if (typeof rawCell === 'object' && !Array.isArray(rawCell)) {\n cellInputStyles = (rawCell === null || rawCell === void 0 ? void 0 : rawCell.styles) || {};\n }\n var styles = cellStyles(sectionName, column, rowIndex, theme, styleProps, scaleFactor, cellInputStyles);\n var cell = new Cell(rawCell, styles, sectionName);\n // dataKey is not used internally no more but keep for\n // backwards compat in hooks\n cells[column.dataKey] = cell;\n cells[column.index] = cell;\n columnSpansLeft = cell.colSpan - 1;\n rowSpansLeftForColumn[column.index] = {\n left: cell.rowSpan - 1,\n times: columnSpansLeft,\n };\n }\n else {\n columnSpansLeft--;\n colSpansAdded++;\n }\n }\n else {\n rowSpansLeftForColumn[column.index].left--;\n columnSpansLeft = rowSpansLeftForColumn[column.index].times;\n skippedRowForRowSpans++;\n }\n }\n return new Row(rawRow, rowIndex, sectionName, cells);\n });\n return result;\n}\nfunction generateSectionRow(columns, section) {\n var sectionRow = {};\n columns.forEach(function (col) {\n if (col.raw != null) {\n var title = getSectionTitle(section, col.raw);\n if (title != null)\n sectionRow[col.dataKey] = title;\n }\n });\n return Object.keys(sectionRow).length > 0 ? sectionRow : null;\n}\nfunction getSectionTitle(section, column) {\n if (section === 'head') {\n if (typeof column === 'object') {\n return column.header || null;\n }\n else if (typeof column === 'string' || typeof column === 'number') {\n return column;\n }\n }\n else if (section === 'foot' && typeof column === 'object') {\n return column.footer;\n }\n return null;\n}\nfunction createColumns(columns) {\n return columns.map(function (input, index) {\n var _a;\n var key;\n if (typeof input === 'object') {\n key = (_a = input.dataKey) !== null && _a !== void 0 ? _a : index;\n }\n else {\n key = index;\n }\n return new Column(key, input, index);\n });\n}\nfunction cellStyles(sectionName, column, rowIndex, themeName, styles, scaleFactor, cellInputStyles) {\n var theme = getTheme(themeName);\n var sectionStyles;\n if (sectionName === 'head') {\n sectionStyles = styles.headStyles;\n }\n else if (sectionName === 'body') {\n sectionStyles = styles.bodyStyles;\n }\n else if (sectionName === 'foot') {\n sectionStyles = styles.footStyles;\n }\n var otherStyles = assign({}, theme.table, theme[sectionName], styles.styles, sectionStyles);\n var columnStyles = styles.columnStyles[column.dataKey] ||\n styles.columnStyles[column.index] ||\n {};\n var colStyles = sectionName === 'body' ? columnStyles : {};\n var rowStyles = sectionName === 'body' && rowIndex % 2 === 0\n ? assign({}, theme.alternateRow, styles.alternateRowStyles)\n : {};\n var defaultStyle = defaultStyles(scaleFactor);\n var themeStyles = assign({}, defaultStyle, otherStyles, rowStyles, colStyles);\n return assign(themeStyles, cellInputStyles);\n}\n\n// get columns can be fit into page\nfunction getColumnsCanFitInPage(doc, table, config) {\n var _a;\n if (config === void 0) { config = {}; }\n // Get page width\n var remainingWidth = getPageAvailableWidth(doc, table);\n // Get column data key to repeat\n var repeatColumnsMap = new Map();\n var colIndexes = [];\n var columns = [];\n var horizontalPageBreakRepeat = [];\n if (Array.isArray(table.settings.horizontalPageBreakRepeat)) {\n horizontalPageBreakRepeat = table.settings.horizontalPageBreakRepeat;\n // It can be a single value of type string or number (even number: 0)\n }\n else if (typeof table.settings.horizontalPageBreakRepeat === 'string' ||\n typeof table.settings.horizontalPageBreakRepeat === 'number') {\n horizontalPageBreakRepeat = [table.settings.horizontalPageBreakRepeat];\n }\n // Code to repeat the given column in split pages\n horizontalPageBreakRepeat.forEach(function (field) {\n var col = table.columns.find(function (item) { return item.dataKey === field || item.index === field; });\n if (col && !repeatColumnsMap.has(col.index)) {\n repeatColumnsMap.set(col.index, true);\n colIndexes.push(col.index);\n columns.push(table.columns[col.index]);\n remainingWidth -= col.wrappedWidth;\n }\n });\n var first = true;\n var i = (_a = config === null || config === void 0 ? void 0 : config.start) !== null && _a !== void 0 ? _a : 0; // make sure couter is initiated outside the loop\n while (i < table.columns.length) {\n // Prevent duplicates\n if (repeatColumnsMap.has(i)) {\n i++;\n continue;\n }\n var colWidth = table.columns[i].wrappedWidth;\n // Take at least one column even if it doesn't fit\n if (first || remainingWidth >= colWidth) {\n first = false;\n colIndexes.push(i);\n columns.push(table.columns[i]);\n remainingWidth -= colWidth;\n }\n else {\n break;\n }\n i++;\n }\n return { colIndexes: colIndexes, columns: columns, lastIndex: i - 1 };\n}\nfunction calculateAllColumnsCanFitInPage(doc, table) {\n var allResults = [];\n for (var i = 0; i < table.columns.length; i++) {\n var result = getColumnsCanFitInPage(doc, table, { start: i });\n if (result.columns.length) {\n allResults.push(result);\n i = result.lastIndex;\n }\n }\n return allResults;\n}\n\nfunction drawTable(jsPDFDoc, table) {\n var settings = table.settings;\n var startY = settings.startY;\n var margin = settings.margin;\n var cursor = { x: margin.left, y: startY };\n var sectionsHeight = table.getHeadHeight(table.columns) + table.getFootHeight(table.columns);\n var minTableBottomPos = startY + margin.bottom + sectionsHeight;\n if (settings.pageBreak === 'avoid') {\n var rows = table.body;\n var tableHeight = rows.reduce(function (acc, row) { return acc + row.height; }, 0);\n minTableBottomPos += tableHeight;\n }\n var doc = new DocHandler(jsPDFDoc);\n if (settings.pageBreak === 'always' ||\n (settings.startY != null && minTableBottomPos > doc.pageSize().height)) {\n nextPage(doc);\n cursor.y = margin.top;\n }\n table.callWillDrawPageHooks(doc, cursor);\n var startPos = assign({}, cursor);\n table.startPageNumber = doc.pageNumber();\n if (settings.horizontalPageBreak) {\n // managed flow for split columns\n printTableWithHorizontalPageBreak(doc, table, startPos, cursor);\n }\n else {\n // normal flow\n doc.applyStyles(doc.userStyles);\n if (settings.showHead === 'firstPage' ||\n settings.showHead === 'everyPage') {\n table.head.forEach(function (row) {\n return printRow(doc, table, row, cursor, table.columns);\n });\n }\n doc.applyStyles(doc.userStyles);\n table.body.forEach(function (row, index) {\n var isLastRow = index === table.body.length - 1;\n printFullRow(doc, table, row, isLastRow, startPos, cursor, table.columns);\n });\n doc.applyStyles(doc.userStyles);\n if (settings.showFoot === 'lastPage' || settings.showFoot === 'everyPage') {\n table.foot.forEach(function (row) {\n return printRow(doc, table, row, cursor, table.columns);\n });\n }\n }\n addTableBorder(doc, table, startPos, cursor);\n table.callEndPageHooks(doc, cursor);\n table.finalY = cursor.y;\n jsPDFDoc.lastAutoTable = table;\n doc.applyStyles(doc.userStyles);\n}\nfunction printTableWithHorizontalPageBreak(doc, table, startPos, cursor) {\n // calculate width of columns and render only those which can fit into page\n var allColumnsCanFitResult = calculateAllColumnsCanFitInPage(doc, table);\n var settings = table.settings;\n if (settings.horizontalPageBreakBehaviour === 'afterAllRows') {\n allColumnsCanFitResult.forEach(function (colsAndIndexes, index) {\n doc.applyStyles(doc.userStyles);\n // add page to print next columns in new page\n if (index > 0) {\n // When adding a page here, make sure not to print the footers\n // because they were already printed before on this same loop\n addPage(doc, table, startPos, cursor, colsAndIndexes.columns, true);\n }\n else {\n // print head for selected columns\n printHead(doc, table, cursor, colsAndIndexes.columns);\n }\n // print body & footer for selected columns\n printBody(doc, table, startPos, cursor, colsAndIndexes.columns);\n printFoot(doc, table, cursor, colsAndIndexes.columns);\n });\n }\n else {\n var lastRowIndexOfLastPage_1 = -1;\n var firstColumnsToFitResult = allColumnsCanFitResult[0];\n var _loop_1 = function () {\n // Print the first columns, taking note of the last row printed\n var lastPrintedRowIndex = lastRowIndexOfLastPage_1;\n if (firstColumnsToFitResult) {\n doc.applyStyles(doc.userStyles);\n var firstColumnsToFit = firstColumnsToFitResult.columns;\n if (lastRowIndexOfLastPage_1 >= 0) {\n // When adding a page here, make sure not to print the footers\n // because they were already printed before on this same loop\n addPage(doc, table, startPos, cursor, firstColumnsToFit, true);\n }\n else {\n printHead(doc, table, cursor, firstColumnsToFit);\n }\n lastPrintedRowIndex = printBodyWithoutPageBreaks(doc, table, lastRowIndexOfLastPage_1 + 1, cursor, firstColumnsToFit);\n printFoot(doc, table, cursor, firstColumnsToFit);\n }\n // Check how many rows were printed, so that the next columns would not print more rows than that\n var maxNumberOfRows = lastPrintedRowIndex - lastRowIndexOfLastPage_1;\n // Print the next columns, never exceding maxNumberOfRows\n allColumnsCanFitResult.slice(1).forEach(function (colsAndIndexes) {\n doc.applyStyles(doc.userStyles);\n // When adding a page here, make sure not to print the footers\n // because they were already printed before on this same loop\n addPage(doc, table, startPos, cursor, colsAndIndexes.columns, true);\n printBodyWithoutPageBreaks(doc, table, lastRowIndexOfLastPage_1 + 1, cursor, colsAndIndexes.columns, maxNumberOfRows);\n printFoot(doc, table, cursor, colsAndIndexes.columns);\n });\n lastRowIndexOfLastPage_1 = lastPrintedRowIndex;\n };\n while (lastRowIndexOfLastPage_1 < table.body.length - 1) {\n _loop_1();\n }\n }\n}\nfunction printHead(doc, table, cursor, columns) {\n var settings = table.settings;\n doc.applyStyles(doc.userStyles);\n if (settings.showHead === 'firstPage' || settings.showHead === 'everyPage') {\n table.head.forEach(function (row) { return printRow(doc, table, row, cursor, columns); });\n }\n}\nfunction printBody(doc, table, startPos, cursor, columns) {\n doc.applyStyles(doc.userStyles);\n table.body.forEach(function (row, index) {\n var isLastRow = index === table.body.length - 1;\n printFullRow(doc, table, row, isLastRow, startPos, cursor, columns);\n });\n}\nfunction printBodyWithoutPageBreaks(doc, table, startRowIndex, cursor, columns, maxNumberOfRows) {\n doc.applyStyles(doc.userStyles);\n maxNumberOfRows = maxNumberOfRows !== null && maxNumberOfRows !== void 0 ? maxNumberOfRows : table.body.length;\n var endRowIndex = Math.min(startRowIndex + maxNumberOfRows, table.body.length);\n var lastPrintedRowIndex = -1;\n var rows = table.body.slice(startRowIndex, endRowIndex);\n for (var index = 0; index < rows.length; index++) {\n var row = rows[index];\n var isLastRow = startRowIndex + index === table.body.length - 1;\n var remainingSpace = getRemainingPageSpace(doc, table, isLastRow, cursor);\n if (row.canEntireRowFit(remainingSpace, columns)) {\n printRow(doc, table, row, cursor, columns);\n lastPrintedRowIndex = startRowIndex + index;\n }\n else {\n break;\n }\n }\n return lastPrintedRowIndex;\n}\nfunction printFoot(doc, table, cursor, columns) {\n var settings = table.settings;\n doc.applyStyles(doc.userStyles);\n if (settings.showFoot === 'lastPage' || settings.showFoot === 'everyPage') {\n table.foot.forEach(function (row) { return printRow(doc, table, row, cursor, columns); });\n }\n}\nfunction getRemainingLineCount(cell, remainingPageSpace, doc) {\n var lineHeight = doc.getLineHeight(cell.styles.fontSize);\n var vPadding = cell.padding('vertical');\n var remainingLines = Math.floor((remainingPageSpace - vPadding) / lineHeight);\n return Math.max(0, remainingLines);\n}\nfunction modifyRowToFit(row, remainingPageSpace, table, doc) {\n var cells = {};\n row.spansMultiplePages = true;\n row.height = 0;\n var rowHeight = 0;\n for (var _i = 0, _a = table.columns; _i < _a.length; _i++) {\n var column = _a[_i];\n var cell = row.cells[column.index];\n if (!cell)\n continue;\n if (!Array.isArray(cell.text)) {\n cell.text = [cell.text];\n }\n var remainderCell = new Cell(cell.raw, cell.styles, cell.section);\n remainderCell = assign(remainderCell, cell);\n remainderCell.text = [];\n var remainingLineCount = getRemainingLineCount(cell, remainingPageSpace, doc);\n if (cell.text.length > remainingLineCount) {\n remainderCell.text = cell.text.splice(remainingLineCount, cell.text.length);\n }\n var scaleFactor = doc.scaleFactor();\n var lineHeightFactor = doc.getLineHeightFactor();\n cell.contentHeight = cell.getContentHeight(scaleFactor, lineHeightFactor);\n if (cell.contentHeight >= remainingPageSpace) {\n cell.contentHeight = remainingPageSpace;\n remainderCell.styles.minCellHeight -= remainingPageSpace;\n }\n if (cell.contentHeight > row.height) {\n row.height = cell.contentHeight;\n }\n remainderCell.contentHeight = remainderCell.getContentHeight(scaleFactor, lineHeightFactor);\n if (remainderCell.contentHeight > rowHeight) {\n rowHeight = remainderCell.contentHeight;\n }\n cells[column.index] = remainderCell;\n }\n var remainderRow = new Row(row.raw, -1, row.section, cells, true);\n remainderRow.height = rowHeight;\n for (var _b = 0, _c = table.columns; _b < _c.length; _b++) {\n var column = _c[_b];\n var remainderCell = remainderRow.cells[column.index];\n if (remainderCell) {\n remainderCell.height = remainderRow.height;\n }\n var cell = row.cells[column.index];\n if (cell) {\n cell.height = row.height;\n }\n }\n return remainderRow;\n}\nfunction shouldPrintOnCurrentPage(doc, row, remainingPageSpace, table) {\n var pageHeight = doc.pageSize().height;\n var margin = table.settings.margin;\n var marginHeight = margin.top + margin.bottom;\n var maxRowHeight = pageHeight - marginHeight;\n if (row.section === 'body') {\n // Should also take into account that head and foot is not\n // on every page with some settings\n maxRowHeight -=\n table.getHeadHeight(table.columns) + table.getFootHeight(table.columns);\n }\n var minRowHeight = row.getMinimumRowHeight(table.columns, doc);\n var minRowFits = minRowHeight < remainingPageSpace;\n if (minRowHeight > maxRowHeight) {\n console.log(\"Will not be able to print row \".concat(row.index, \" correctly since it's minimum height is larger than page height\"));\n return true;\n }\n if (!minRowFits) {\n return false;\n }\n var rowHasRowSpanCell = row.hasRowSpan(table.columns);\n var rowHigherThanPage = row.getMaxCellHeight(table.columns) > maxRowHeight;\n if (rowHigherThanPage) {\n if (rowHasRowSpanCell) {\n console.log(\"The content of row \".concat(row.index, \" will not be drawn correctly since drawing rows with a height larger than the page height and has cells with rowspans is not supported.\"));\n }\n return true;\n }\n if (rowHasRowSpanCell) {\n // Currently a new page is required whenever a rowspan row don't fit a page.\n return false;\n }\n if (table.settings.rowPageBreak === 'avoid') {\n return false;\n }\n // In all other cases print the row on current page\n return true;\n}\nfunction printFullRow(doc, table, row, isLastRow, startPos, cursor, columns) {\n var remainingSpace = getRemainingPageSpace(doc, table, isLastRow, cursor);\n if (row.canEntireRowFit(remainingSpace, columns)) {\n // The row fits in the current page\n printRow(doc, table, row, cursor, columns);\n }\n else if (shouldPrintOnCurrentPage(doc, row, remainingSpace, table)) {\n // The row gets split in two here, each piece in one page\n var remainderRow = modifyRowToFit(row, remainingSpace, table, doc);\n printRow(doc, table, row, cursor, columns);\n addPage(doc, table, startPos, cursor, columns);\n printFullRow(doc, table, remainderRow, isLastRow, startPos, cursor, columns);\n }\n else {\n // The row get printed entirelly on the next page\n addPage(doc, table, startPos, cursor, columns);\n printFullRow(doc, table, row, isLastRow, startPos, cursor, columns);\n }\n}\nfunction printRow(doc, table, row, cursor, columns) {\n cursor.x = table.settings.margin.left;\n for (var _i = 0, columns_1 = columns; _i < columns_1.length; _i++) {\n var column = columns_1[_i];\n var cell = row.cells[column.index];\n if (!cell) {\n cursor.x += column.width;\n continue;\n }\n doc.applyStyles(cell.styles);\n cell.x = cursor.x;\n cell.y = cursor.y;\n var result = table.callCellHooks(doc, table.hooks.willDrawCell, cell, row, column, cursor);\n if (result === false) {\n cursor.x += column.width;\n continue;\n }\n drawCellRect(doc, cell, cursor);\n var textPos = cell.getTextPos();\n autoTableText(cell.text, textPos.x, textPos.y, {\n halign: cell.styles.halign,\n valign: cell.styles.valign,\n maxWidth: Math.ceil(cell.width - cell.padding('left') - cell.padding('right')),\n }, doc.getDocument());\n table.callCellHooks(doc, table.hooks.didDrawCell, cell, row, column, cursor);\n cursor.x += column.width;\n }\n cursor.y += row.height;\n}\nfunction drawCellRect(doc, cell, cursor) {\n var cellStyles = cell.styles;\n // https://github.com/simonbengtsson/jsPDF-AutoTable/issues/774\n // TODO (v4): better solution?\n doc.getDocument().setFillColor(doc.getDocument().getFillColor());\n if (typeof cellStyles.lineWidth === 'number') {\n // Draw cell background with normal borders\n var fillStyle = getFillStyle(cellStyles.lineWidth, cellStyles.fillColor);\n if (fillStyle) {\n doc.rect(cell.x, cursor.y, cell.width, cell.height, fillStyle);\n }\n }\n else if (typeof cellStyles.lineWidth === 'object') {\n // Draw cell background\n if (cellStyles.fillColor) {\n doc.rect(cell.x, cursor.y, cell.width, cell.height, 'F');\n }\n // Draw cell individual borders\n drawCellBorders(doc, cell, cursor, cellStyles.lineWidth);\n }\n}\n/**\n * Draw all specified borders. Borders are centered on cell's edge and lengthened\n * to overlap with neighbours to create sharp corners.\n * @param doc\n * @param cell\n * @param cursor\n * @param fillColor\n * @param lineWidth\n */\nfunction drawCellBorders(doc, cell, cursor, lineWidth) {\n var x1, y1, x2, y2;\n if (lineWidth.top) {\n x1 = cursor.x;\n y1 = cursor.y;\n x2 = cursor.x + cell.width;\n y2 = cursor.y;\n if (lineWidth.right) {\n x2 += 0.5 * lineWidth.right;\n }\n if (lineWidth.left) {\n x1 -= 0.5 * lineWidth.left;\n }\n drawLine(lineWidth.top, x1, y1, x2, y2);\n }\n if (lineWidth.bottom) {\n x1 = cursor.x;\n y1 = cursor.y + cell.height;\n x2 = cursor.x + cell.width;\n y2 = cursor.y + cell.height;\n if (lineWidth.right) {\n x2 += 0.5 * lineWidth.right;\n }\n if (lineWidth.left) {\n x1 -= 0.5 * lineWidth.left;\n }\n drawLine(lineWidth.bottom, x1, y1, x2, y2);\n }\n if (lineWidth.left) {\n x1 = cursor.x;\n y1 = cursor.y;\n x2 = cursor.x;\n y2 = cursor.y + cell.height;\n if (lineWidth.top) {\n y1 -= 0.5 * lineWidth.top;\n }\n if (lineWidth.bottom) {\n y2 += 0.5 * lineWidth.bottom;\n }\n drawLine(lineWidth.left, x1, y1, x2, y2);\n }\n if (lineWidth.right) {\n x1 = cursor.x + cell.width;\n y1 = cursor.y;\n x2 = cursor.x + cell.width;\n y2 = cursor.y + cell.height;\n if (lineWidth.top) {\n y1 -= 0.5 * lineWidth.top;\n }\n if (lineWidth.bottom) {\n y2 += 0.5 * lineWidth.bottom;\n }\n drawLine(lineWidth.right, x1, y1, x2, y2);\n }\n function drawLine(width, x1, y1, x2, y2) {\n doc.getDocument().setLineWidth(width);\n doc.getDocument().line(x1, y1, x2, y2, 'S');\n }\n}\nfunction getRemainingPageSpace(doc, table, isLastRow, cursor) {\n var bottomContentHeight = table.settings.margin.bottom;\n var showFoot = table.settings.showFoot;\n if (showFoot === 'everyPage' || (showFoot === 'lastPage' && isLastRow)) {\n bottomContentHeight += table.getFootHeight(table.columns);\n }\n return doc.pageSize().height - cursor.y - bottomContentHeight;\n}\nfunction addPage(doc, table, startPos, cursor, columns, suppressFooter) {\n if (columns === void 0) { columns = []; }\n if (suppressFooter === void 0) { suppressFooter = false; }\n doc.applyStyles(doc.userStyles);\n if (table.settings.showFoot === 'everyPage' && !suppressFooter) {\n table.foot.forEach(function (row) { return printRow(doc, table, row, cursor, columns); });\n }\n // Add user content just before adding new page ensure it will\n // be drawn above other things on the page\n table.callEndPageHooks(doc, cursor);\n var margin = table.settings.margin;\n addTableBorder(doc, table, startPos, cursor);\n nextPage(doc);\n table.pageNumber++;\n cursor.x = margin.left;\n cursor.y = margin.top;\n startPos.y = margin.top;\n // call didAddPage hooks before any content is added to the page\n table.callWillDrawPageHooks(doc, cursor);\n if (table.settings.showHead === 'everyPage') {\n table.head.forEach(function (row) { return printRow(doc, table, row, cursor, columns); });\n doc.applyStyles(doc.userStyles);\n }\n}\nfunction nextPage(doc) {\n var current = doc.pageNumber();\n doc.setPage(current + 1);\n var newCurrent = doc.pageNumber();\n if (newCurrent === current) {\n doc.addPage();\n return true;\n }\n return false;\n}\n\nfunction applyPlugin(jsPDF) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n jsPDF.API.autoTable = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var options = args[0];\n var input = parseInput(this, options);\n var table = createTable(this, input);\n drawTable(this, table);\n return this;\n };\n // Assign false to enable `doc.lastAutoTable.finalY || 40` sugar\n jsPDF.API.lastAutoTable = false;\n jsPDF.API.autoTableText = function (text, x, y, styles) {\n autoTableText(text, x, y, styles, this);\n };\n jsPDF.API.autoTableSetDefaults = function (defaults) {\n DocHandler.setDefaults(defaults, this);\n return this;\n };\n jsPDF.autoTableSetDefaults = function (defaults, doc) {\n DocHandler.setDefaults(defaults, doc);\n };\n jsPDF.API.autoTableHtmlToJson = function (tableElem, includeHiddenElements) {\n var _a;\n if (includeHiddenElements === void 0) { includeHiddenElements = false; }\n if (typeof window === 'undefined') {\n console.error('Cannot run autoTableHtmlToJson in non browser environment');\n return null;\n }\n var doc = new DocHandler(this);\n var _b = parseHtml(doc, tableElem, window, includeHiddenElements, false), head = _b.head, body = _b.body;\n var columns = ((_a = head[0]) === null || _a === void 0 ? void 0 : _a.map(function (c) { return c.content; })) || [];\n return { columns: columns, rows: body, data: body };\n };\n}\n\nvar _a;\nfunction autoTable(d, options) {\n var input = parseInput(d, options);\n var table = createTable(d, input);\n drawTable(d, table);\n}\n// Experimental export\nfunction __createTable(d, options) {\n var input = parseInput(d, options);\n return createTable(d, input);\n}\nfunction __drawTable(d, table) {\n drawTable(d, table);\n}\ntry {\n if (typeof window !== 'undefined' && window) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n var anyWindow = window;\n var jsPDF = anyWindow.jsPDF || ((_a = anyWindow.jspdf) === null || _a === void 0 ? void 0 : _a.jsPDF);\n if (jsPDF) {\n applyPlugin(jsPDF);\n }\n }\n}\ncatch (error) {\n console.error('Could not apply autoTable plugin', error);\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvanNwZGYtYXV0b3RhYmxlL2Rpc3QvanNwZGYucGx1Z2luLmF1dG90YWJsZS5tanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywwQkFBMEI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQixvREFBb0Q7QUFDbkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQThDLHVCQUF1QjtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjtBQUNuQjtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsd0RBQXdEO0FBQy9HO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtB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QTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCO0FBQzlCLHFDQUFxQztBQUNyQztBQUNBO0FBQ0EsNENBQTRDLG9EQUFvRDtBQUNoRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDLG9EQUFvRDtBQUNoRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qix1QkFBdUI7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0Q7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUdBQWlHLG1CQUFtQjtBQUNwSCxpQkFBaUI7QUFDakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRXNJIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vdmVyaWZ5cGFjay1mcm9udGVuZC8uL25vZGVfbW9kdWxlcy9qc3BkZi1hdXRvdGFibGUvZGlzdC9qc3BkZi5wbHVnaW4uYXV0b3RhYmxlLm1qcz82MjAyIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSW1wcm92ZWQgdGV4dCBmdW5jdGlvbiB3aXRoIGhhbGlnbiBhbmQgdmFsaWduIHN1cHBvcnRcbiAqIEluc3BpcmF0aW9uIGZyb206IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjgzMjc1MTAvYWxpZ24tdGV4dC1yaWdodC11c2luZy1qc3BkZi8yODQzMzExMyMyODQzMzExM1xuICovXG5mdW5jdGlvbiBhdXRvVGFibGVUZXh0ICh0ZXh0LCB4LCB5LCBzdHlsZXMsIGRvYykge1xuICAgIHN0eWxlcyA9IHN0eWxlcyB8fCB7fTtcbiAgICB2YXIgUEhZU0lDQUxfTElORV9IRUlHSFQgPSAxLjE1O1xuICAgIHZhciBrID0gZG9jLmludGVybmFsLnNjYWxlRmFjdG9yO1xuICAgIHZhciBmb250U2l6ZSA9IGRvYy5pbnRlcm5hbC5nZXRGb250U2l6ZSgpIC8gaztcbiAgICB2YXIgbGluZUhlaWdodEZhY3RvciA9IGRvYy5nZXRMaW5lSGVpZ2h0RmFjdG9yXG4gICAgICAgID8gZG9jLmdldExpbmVIZWlnaHRGYWN0b3IoKVxuICAgICAgICA6IFBIWVNJQ0FMX0xJTkVfSEVJR0hUO1xuICAgIHZhciBsaW5lSGVpZ2h0ID0gZm9udFNpemUgKiBsaW5lSGVpZ2h0RmFjdG9yO1xuICAgIHZhciBzcGxpdFJlZ2V4ID0gL1xcclxcbnxcXHJ8XFxuL2c7XG4gICAgdmFyIHNwbGl0VGV4dCA9ICcnO1xuICAgIHZhciBsaW5lQ291bnQgPSAxO1xuICAgIGlmIChzdHlsZXMudmFsaWduID09PSAnbWlkZGxlJyB8fFxuICAgICAgICBzdHlsZXMudmFsaWduID09PSAnYm90dG9tJyB8fFxuICAgICAgICBzdHlsZXMuaGFsaWduID09PSAnY2VudGVyJyB8fFxuICAgICAgICBzdHlsZXMuaGFsaWduID09PSAncmlnaHQnKSB7XG4gICAgICAgIHNwbGl0VGV4dCA9IHR5cGVvZiB0ZXh0ID09PSAnc3RyaW5nJyA/IHRleHQuc3BsaXQoc3BsaXRSZWdleCkgOiB0ZXh0O1xuICAgICAgICBsaW5lQ291bnQgPSBzcGxpdFRleHQubGVuZ3RoIHx8IDE7XG4gICAgfVxuICAgIC8vIEFsaWduIHRoZSB0b3BcbiAgICB5ICs9IGZvbnRTaXplICogKDIgLSBQSFlTSUNBTF9MSU5FX0hFSUdIVCk7XG4gICAgaWYgKHN0eWxlcy52YWxpZ24gPT09ICdtaWRkbGUnKVxuICAgICAgICB5IC09IChsaW5lQ291bnQgLyAyKSAqIGxpbmVIZWlnaHQ7XG4gICAgZWxzZSBpZiAoc3R5bGVzLnZhbGlnbiA9PT0gJ2JvdHRvbScpXG4gICAgICAgIHkgLT0gbGluZUNvdW50ICogbGluZUhlaWdodDtcbiAgICBpZiAoc3R5bGVzLmhhbGlnbiA9PT0gJ2NlbnRlcicgfHwgc3R5bGVzLmhhbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICB2YXIgYWxpZ25TaXplID0gZm9udFNpemU7XG4gICAgICAgIGlmIChzdHlsZXMuaGFsaWduID09PSAnY2VudGVyJylcbiAgICAgICAgICAgIGFsaWduU2l6ZSAqPSAwLjU7XG4gICAgICAgIGlmIChzcGxpdFRleHQgJiYgbGluZUNvdW50ID49IDEpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGlMaW5lID0gMDsgaUxpbmUgPCBzcGxpdFRleHQubGVuZ3RoOyBpTGluZSsrKSB7XG4gICAgICAgICAgICAgICAgZG9jLnRleHQoc3BsaXRUZXh0W2lMaW5lXSwgeCAtIGRvYy5nZXRTdHJpbmdVbml0V2lkdGgoc3BsaXRUZXh0W2lMaW5lXSkgKiBhbGlnblNpemUsIHkpO1xuICAgICAgICAgICAgICAgIHkgKz0gbGluZUhlaWdodDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkb2M7XG4gICAgICAgIH1cbiAgICAgICAgeCAtPSBkb2MuZ2V0U3RyaW5nVW5pdFdpZHRoKHRleHQpICogYWxpZ25TaXplO1xuICAgIH1cbiAgICBpZiAoc3R5bGVzLmhhbGlnbiA9PT0gJ2p1c3RpZnknKSB7XG4gICAgICAgIGRvYy50ZXh0KHRleHQsIHgsIHksIHsgbWF4V2lkdGg6IHN0eWxlcy5tYXhXaWR0aCB8fCAxMDAsIGFsaWduOiAnanVzdGlmeScgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBkb2MudGV4dCh0ZXh0LCB4LCB5KTtcbiAgICB9XG4gICAgcmV0dXJuIGRvYztcbn1cblxudmFyIGdsb2JhbERlZmF1bHRzID0ge307XG52YXIgRG9jSGFuZGxlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBEb2NIYW5kbGVyKGpzUERGRG9jdW1lbnQpIHtcbiAgICAgICAgdGhpcy5qc1BERkRvY3VtZW50ID0ganNQREZEb2N1bWVudDtcbiAgICAgICAgdGhpcy51c2VyU3R5bGVzID0ge1xuICAgICAgICAgICAgLy8gQmxhY2sgZm9yIHZlcnNpb25zIG9mIGpzcGRmIHdpdGhvdXQgZ2V0VGV4dENvbG9yXG4gICAgICAgICAgICB0ZXh0Q29sb3I6IGpzUERGRG9jdW1lbnQuZ2V0VGV4dENvbG9yXG4gICAgICAgICAgICAgICAgPyB0aGlzLmpzUERGRG9jdW1lbnQuZ2V0VGV4dENvbG9yKClcbiAgICAgICAgICAgICAgICA6IDAsXG4gICAgICAgICAgICBmb250U2l6ZToganNQREZEb2N1bWVudC5pbnRlcm5hbC5nZXRGb250U2l6ZSgpLFxuICAgICAgICAgICAgZm9udFN0eWxlOiBqc1BERkRvY3VtZW50LmludGVybmFsLmdldEZvbnQoKS5mb250U3R5bGUsXG4gICAgICAgICAgICBmb250OiBqc1BERkRvY3VtZW50LmludGVybmFsLmdldEZvbnQoKS5mb250TmFtZSxcbiAgICAgICAgICAgIC8vIDAgZm9yIHZlcnNpb25zIG9mIGpzcGRmIHdpdGhvdXQgZ2V0TGluZVdpZHRoXG4gICAgICAgICAgICBsaW5lV2lkdGg6IGpzUERGRG9jdW1lbnQuZ2V0TGluZVdpZHRoXG4gICAgICAgICAgICAgICAgPyB0aGlzLmpzUERGRG9jdW1lbnQuZ2V0TGluZVdpZHRoKClcbiAgICAgICAgICAgICAgICA6IDAsXG4gICAgICAgICAgICAvLyBCbGFjayBmb3IgdmVyc2lvbnMgb2YganNwZGYgd2l0aG91dCBnZXREcmF3Q29sb3JcbiAgICAgICAgICAgIGxpbmVDb2xvcjoganNQREZEb2N1bWVudC5nZXREcmF3Q29sb3JcbiAgICAgICAgICAgICAgICA/IHRoaXMuanNQREZEb2N1bWVudC5nZXREcmF3Q29sb3IoKVxuICAgICAgICAgICAgICAgIDogMCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgRG9jSGFuZGxlci5zZXREZWZhdWx0cyA9IGZ1bmN0aW9uIChkZWZhdWx0cywgZG9jKSB7XG4gICAgICAgIGlmIChkb2MgPT09IHZvaWQgMCkgeyBkb2MgPSBudWxsOyB9XG4gICAgICAgIGlmIChkb2MpIHtcbiAgICAgICAgICAgIGRvYy5fX2F1dG9UYWJsZURvY3VtZW50RGVmYXVsdHMgPSBkZWZhdWx0cztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGdsb2JhbERlZmF1bHRzID0gZGVmYXVsdHM7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIERvY0hhbmRsZXIudW5pZnlDb2xvciA9IGZ1bmN0aW9uIChjKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGMpKSB7XG4gICAgICAgICAgICByZXR1cm4gYztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgYyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHJldHVybiBbYywgYywgY107XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gW2NdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIERvY0hhbmRsZXIucHJvdG90eXBlLmFwcGx5U3R5bGVzID0gZnVuY3Rpb24gKHN0eWxlcywgZm9udE9ubHkpIHtcbiAgICAgICAgLy8gRm9udCBzdHlsZSBuZWVkcyB0byBiZSBhcHBsaWVkIGJlZm9yZSBmb250XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9zaW1vbmJlbmd0c3Nvbi9qc1BERi1BdXRvVGFibGUvaXNzdWVzLzYzMlxuICAgICAgICB2YXIgX2EsIF9iLCBfYztcbiAgICAgICAgaWYgKGZvbnRPbmx5ID09PSB2b2lkIDApIHsgZm9udE9ubHkgPSBmYWxzZTsgfVxuICAgICAgICBpZiAoc3R5bGVzLmZvbnRTdHlsZSAmJiB0aGlzLmpzUERGRG9jdW1lbnQuc2V0Rm9udFN0eWxlKSB7XG4gICAgICAgICAgICB0aGlzLmpzUERGRG9jdW1lbnQuc2V0Rm9udFN0eWxlKHN0eWxlcy5mb250U3R5bGUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBfZCA9IHRoaXMuanNQREZEb2N1bWVudC5pbnRlcm5hbC5nZXRGb250KCksIGZvbnRTdHlsZSA9IF9kLmZvbnRTdHlsZSwgZm9udE5hbWUgPSBfZC5mb250TmFtZTtcbiAgICAgICAgaWYgKHN0eWxlcy5mb250KVxuICAgICAgICAgICAgZm9udE5hbWUgPSBzdHlsZXMuZm9udDtcbiAgICAgICAgaWYgKHN0eWxlcy5mb250U3R5bGUpIHtcbiAgICAgICAgICAgIGZvbnRTdHlsZSA9IHN0eWxlcy5mb250U3R5bGU7XG4gICAgICAgICAgICB2YXIgYXZhaWxhYmxlRm9udFN0eWxlcyA9IHRoaXMuZ2V0Rm9udExpc3QoKVtmb250TmFtZV07XG4gICAgICAgICAgICBpZiAoYXZhaWxhYmxlRm9udFN0eWxlcyAmJlxuICAgICAgICAgICAgICAgIGF2YWlsYWJsZUZvbnRTdHlsZXMuaW5kZXhPZihmb250U3R5bGUpID09PSAtMSAmJlxuICAgICAgICAgICAgICAgIHRoaXMuanNQREZEb2N1bWVudC5zZXRGb250U3R5bGUpIHtcbiAgICAgICAgICAgICAgICAvLyBDb21tb24gaXNzdWUgd2FzIHRoYXQgdGhlIGRlZmF1bHQgYm9sZCBpbiBoZWFkZXJzXG4gICAgICAgICAgICAgICAgLy8gbWFkZSBjdXN0b20gZm9udHMgbm90IHdvcmsuIEZvciBleGFtcGxlOlxuICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9zaW1vbmJlbmd0c3Nvbi9qc1BERi1BdXRvVGFibGUvaXNzdWVzLzY1M1xuICAgICAgICAgICAgICAgIHRoaXMuanNQREZEb2N1bWVudC5zZXRGb250U3R5bGUoYXZhaWxhYmxlRm9udFN0eWxlc1swXSk7XG4gICAgICAgICAgICAgICAgZm9udFN0eWxlID0gYXZhaWxhYmxlRm9udFN0eWxlc1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmpzUERGRG9jdW1lbnQuc2V0Rm9udChmb250TmFtZSwgZm9udFN0eWxlKTtcbiAgICAgICAgaWYgKHN0eWxlcy5mb250U2l6ZSlcbiAgICAgICAgICAgIHRoaXMuanNQREZEb2N1bWVudC5zZXRGb250U2l6ZShzdHlsZXMuZm9udFNpemUpO1xuICAgICAgICBpZiAoZm9udE9ubHkpIHtcbiAgICAgICAgICAgIHJldHVybjsgLy8gUGVyZm9ybWFuY2UgaW1wcm92ZW1lbnRcbiAgICAgICAgfVxuICAgICAgICB2YXIgY29sb3IgPSBEb2NIYW5kbGVyLnVuaWZ5Q29sb3Ioc3R5bGVzLmZpbGxDb2xvcik7XG4gICAgICAgIGlmIChjb2xvcilcbiAgICAgICAgICAgIChfYSA9IHRoaXMuanNQREZEb2N1bWVudCkuc2V0RmlsbENvbG9yLmFwcGx5KF9hLCBjb2xvcik7XG4gICAgICAgIGNvbG9yID0gRG9jSGFuZGxlci51bmlmeUNvbG9yKHN0eWxlcy50ZXh0Q29sb3IpO1xuICAgICAgICBpZiAoY29sb3IpXG4gICAgICAgICAgICAoX2IgPSB0aGlzLmpzUERGRG9jdW1lbnQpLnNldFRleHRDb2xvci5hcHBseShfYiwgY29sb3IpO1xuICAgICAgICBjb2xvciA9IERvY0hhbmRsZXIudW5pZnlDb2xvcihzdHlsZXMubGluZUNvbG9yKTtcbiAgICAgICAgaWYgKGNvbG9yKVxuICAgICAgICAgICAgKF9jID0gdGhpcy5qc1BERkRvY3VtZW50KS5zZXREcmF3Q29sb3IuYXBwbHkoX2MsIGNvbG9yKTtcbiAgICAgICAgaWYgKHR5cGVvZiBzdHlsZXMubGluZVdpZHRoID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdGhpcy5qc1BERkRvY3VtZW50LnNldExpbmVXaWR0aChzdHlsZXMubGluZVdpZHRoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRG9jSGFuZGxlci5wcm90b3R5cGUuc3BsaXRUZXh0VG9TaXplID0gZnVuY3Rpb24gKHRleHQsIHNpemUsIG9wdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuanNQREZEb2N1bWVudC5zcGxpdFRleHRUb1NpemUodGV4dCwgc2l6ZSwgb3B0cyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBBZGRzIGEgcmVjdGFuZ2xlIHRvIHRoZSBQREZcbiAgICAgKiBAcGFyYW0geCBDb29yZGluYXRlIChpbiB1bml0cyBkZWNsYXJlZCBhdCBpbmNlcHRpb24gb2YgUERGIGRvY3VtZW50KSBhZ2FpbnN0IGxlZnQgZWRnZSBvZiB0aGUgcGFnZVxuICAgICAqIEBwYXJhbSB5IENvb3JkaW5hdGUgKGluIHVuaXRzIGRlY2xhcmVkIGF0IGluY2VwdGlvbiBvZiBQREYgZG9jdW1lbnQpIGFnYWluc3QgdXBwZXIgZWRnZSBvZiB0aGUgcGFnZVxuICAgICAqIEBwYXJhbSB3aWR0aCBXaWR0aCAoaW4gdW5pdHMgZGVjbGFyZWQgYXQgaW5jZXB0aW9uIG9mIFBERiBkb2N1bWVudClcbiAgICAgKiBAcGFyYW0gaGVpZ2h0IEhlaWdodCAoaW4gdW5pdHMgZGVjbGFyZWQgYXQgaW5jZXB0aW9uIG9mIFBERiBkb2N1bWVudClcbiAgICAgKiBAcGFyYW0gZmlsbFN0eWxlIEEgc3RyaW5nIHNwZWNpZnlpbmcgdGhlIHBhaW50aW5nIHN0eWxlIG9yIG51bGwuIFZhbGlkIHN0eWxlcyBpbmNsdWRlOiAnUycgW2RlZmF1bHRdIC0gc3Ryb2tlLCAnRicgLSBmaWxsLCBhbmQgJ0RGJyAob3IgJ0ZEJykgLSBmaWxsIHRoZW4gc3Ryb2tlLlxuICAgICAqL1xuICAgIERvY0hhbmRsZXIucHJvdG90eXBlLnJlY3QgPSBmdW5jdGlvbiAoeCwgeSwgd2lkdGgsIGhlaWdodCwgZmlsbFN0eWxlKSB7XG4gICAgICAgIC8vIG51bGwgaXMgZXhjbHVkZWQgZnJvbSBmaWxsU3R5bGUgcG9zc2libGUgdmFsdWVzIGJlY2F1c2UgaXQgaXNuJ3QgbmVlZGVkXG4gICAgICAgIC8vIGFuZCBpcyBwcm9uZSB0byBidWdzIGFzIGl0J3MgdXNlZCB0byBwb3N0cG9uZSBzZXR0aW5nIHRoZSBzdHlsZVxuICAgICAgICAvLyBodHRwczovL3Jhd2dpdC5jb20vTXJSaW8vanNQREYvbWFzdGVyL2RvY3MvanNQREYuaHRtbCNyZWN0XG4gICAgICAgIHJldHVybiB0aGlzLmpzUERGRG9jdW1lbnQucmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0LCBmaWxsU3R5bGUpO1xuICAgIH07XG4gICAgRG9jSGFuZGxlci5wcm90b3R5cGUuZ2V0TGFzdEF1dG9UYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuanNQREZEb2N1bWVudC5sYXN0QXV0b1RhYmxlIHx8IG51bGw7XG4gICAgfTtcbiAgICBEb2NIYW5kbGVyLnByb3RvdHlwZS5nZXRUZXh0V2lkdGggPSBmdW5jdGlvbiAodGV4dCkge1xuICAgICAgICByZXR1cm4gdGhpcy5qc1BERkRvY3VtZW50LmdldFRleHRXaWR0aCh0ZXh0KTtcbiAgICB9O1xuICAgIERvY0hhbmRsZXIucHJvdG90eXBlLmdldERvY3VtZW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5qc1BERkRvY3VtZW50O1xuICAgIH07XG4gICAgRG9jSGFuZGxlci5wcm90b3R5cGUuc2V0UGFnZSA9IGZ1bmN0aW9uIChwYWdlKSB7XG4gICAgICAgIHRoaXMuanNQREZEb2N1bWVudC5zZXRQYWdlKHBhZ2UpO1xuICAgIH07XG4gICAgRG9jSGFuZGxlci5wcm90b3R5cGUuYWRkUGFnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuanNQREZEb2N1bWVudC5hZGRQYWdlKCk7XG4gICAgfTtcbiAgICBEb2NIYW5kbGVyLnByb3RvdHlwZS5nZXRGb250TGlzdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuanNQREZEb2N1bWVudC5nZXRGb250TGlzdCgpO1xuICAgIH07XG4gICAgRG9jSGFuZGxlci5wcm90b3R5cGUuZ2V0R2xvYmFsT3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGdsb2JhbERlZmF1bHRzIHx8IHt9O1xuICAgIH07XG4gICAgRG9jSGFuZGxlci5wcm90b3R5cGUuZ2V0RG9jdW1lbnRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5qc1BERkRvY3VtZW50Ll9fYXV0b1RhYmxlRG9jdW1lbnREZWZhdWx0cyB8fCB7fTtcbiAgICB9O1xuICAgIERvY0hhbmRsZXIucHJvdG90eXBlLnBhZ2VTaXplID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcGFnZVNpemUgPSB0aGlzLmpzUERGRG9jdW1lbnQuaW50ZXJuYWwucGFnZVNpemU7XG4gICAgICAgIC8vIEpTUERGIDEuNCB1c2VzIGdldCBmdW5jdGlvbnMgaW5zdGVhZCBvZiBwcm9wZXJ0aWVzIG9uIHBhZ2VTaXplXG4gICAgICAgIGlmIChwYWdlU2l6ZS53aWR0aCA9PSBudWxsKSB7XG4gICAgICAgICAgICBwYWdlU2l6ZSA9IHsgd2lkdGg6IHBhZ2VTaXplLmdldFdpZHRoKCksIGhlaWdodDogcGFnZVNpemUuZ2V0SGVpZ2h0KCkgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFnZVNpemU7XG4gICAgfTtcbiAgICBEb2NIYW5kbGVyLnByb3RvdHlwZS5zY2FsZUZhY3RvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuanNQREZEb2N1bWVudC5pbnRlcm5hbC5zY2FsZUZhY3RvcjtcbiAgICB9O1xuICAgIERvY0hhbmRsZXIucHJvdG90eXBlLmdldExpbmVIZWlnaHRGYWN0b3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkb2MgPSB0aGlzLmpzUERGRG9jdW1lbnQ7XG4gICAgICAgIHJldHVybiBkb2MuZ2V0TGluZUhlaWdodEZhY3RvciA/IGRvYy5nZXRMaW5lSGVpZ2h0RmFjdG9yKCkgOiAxLjE1O1xuICAgIH07XG4gICAgRG9jSGFuZGxlci5wcm90b3R5cGUuZ2V0TGluZUhlaWdodCA9IGZ1bmN0aW9uIChmb250U2l6ZSkge1xuICAgICAgICByZXR1cm4gKGZvbnRTaXplIC8gdGhpcy5zY2FsZUZhY3RvcigpKSAqIHRoaXMuZ2V0TGluZUhlaWdodEZhY3RvcigpO1xuICAgIH07XG4gICAgRG9jSGFuZGxlci5wcm90b3R5cGUucGFnZU51bWJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBhZ2VJbmZvID0gdGhpcy5qc1BERkRvY3VtZW50LmludGVybmFsLmdldEN1cnJlbnRQYWdlSW5mbygpO1xuICAgICAgICBpZiAoIXBhZ2VJbmZvKSB7XG4gICAgICAgICAgICAvLyBPbmx5IHJlY2VudCB2ZXJzaW9ucyBvZiBqc3BkZiBoYXMgcGFnZUluZm9cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmpzUERGRG9jdW1lbnQuaW50ZXJuYWwuZ2V0TnVtYmVyT2ZQYWdlcygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwYWdlSW5mby5wYWdlTnVtYmVyO1xuICAgIH07XG4gICAgcmV0dXJuIERvY0hhbmRsZXI7XG59KCkpO1xuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UsIFN1cHByZXNzZWRFcnJvciwgU3ltYm9sLCBJdGVyYXRvciAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxudHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gXCJmdW5jdGlvblwiID8gU3VwcHJlc3NlZEVycm9yIDogZnVuY3Rpb24gKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7XHJcbiAgICB2YXIgZSA9IG5ldyBFcnJvcihtZXNzYWdlKTtcclxuICAgIHJldHVybiBlLm5hbWUgPSBcIlN1cHByZXNzZWRFcnJvclwiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7XHJcbn07XG5cbnZhciBIdG1sUm93SW5wdXQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKEh0bWxSb3dJbnB1dCwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBIdG1sUm93SW5wdXQoZWxlbWVudCkge1xuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgICAgICBfdGhpcy5fZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgcmV0dXJuIEh0bWxSb3dJbnB1dDtcbn0oQXJyYXkpKTtcbi8vIEJhc2Ugc3R5bGUgZm9yIGFsbCB0aGVtZXNcbmZ1bmN0aW9uIGRlZmF1bHRTdHlsZXMoc2NhbGVGYWN0b3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBmb250OiAnaGVsdmV0aWNhJywgLy8gaGVsdmV0aWNhLCB0aW1lcywgY291cmllclxuICAgICAgICBmb250U3R5bGU6ICdub3JtYWwnLCAvLyBub3JtYWwsIGJvbGQsIGl0YWxpYywgYm9sZGl0YWxpY1xuICAgICAgICBvdmVyZmxvdzogJ2xpbmVicmVhaycsIC8vIGxpbmVicmVhaywgZWxsaXBzaXplLCB2aXNpYmxlIG9yIGhpZGRlblxuICAgICAgICBmaWxsQ29sb3I6IGZhbHNlLCAvLyBFaXRoZXIgZmFsc2UgZm9yIHRyYW5zcGFyZW50LCByYmcgYXJyYXkgZS5nLiBbMjU1LCAyNTUsIDI1NV0gb3IgZ3JheSBsZXZlbCBlLmcgMjAwXG4gICAgICAgIHRleHRDb2xvcjogMjAsXG4gICAgICAgIGhhbGlnbjogJ2xlZnQnLCAvLyBsZWZ0LCBjZW50ZXIsIHJpZ2h0LCBqdXN0aWZ5XG4gICAgICAgIHZhbGlnbjogJ3RvcCcsIC8vIHRvcCwgbWlkZGxlLCBib3R0b21cbiAgICAgICAgZm9udFNpemU6IDEwLFxuICAgICAgICBjZWxsUGFkZGluZzogNSAvIHNjYWxlRmFjdG9yLCAvLyBudW1iZXIgb3Ige3RvcCxsZWZ0LHJpZ2h0LGxlZnQsdmVydGljYWwsaG9yaXpvbnRhbH1cbiAgICAgICAgbGluZUNvbG9yOiAyMDAsXG4gICAgICAgIGxpbmVXaWR0aDogMCxcbiAgICAgICAgY2VsbFdpZHRoOiAnYXV0bycsIC8vICdhdXRvJ3wnd3JhcCd8bnVtYmVyXG4gICAgICAgIG1pbkNlbGxIZWlnaHQ6IDAsXG4gICAgICAgIG1pbkNlbGxXaWR0aDogMCxcbiAgICB9O1xufVxuZnVuY3Rpb24gZ2V0VGhlbWUobmFtZSkge1xuICAgIHZhciB0aGVtZXMgPSB7XG4gICAgICAgIHN0cmlwZWQ6IHtcbiAgICAgICAgICAgIHRhYmxlOiB7IGZpbGxDb2xvcjogMjU1LCB0ZXh0Q29sb3I6IDgwLCBmb250U3R5bGU6ICdub3JtYWwnIH0sXG4gICAgICAgICAgICBoZWFkOiB7IHRleHRDb2xvcjogMjU1LCBmaWxsQ29sb3I6IFs0MSwgMTI4LCAxODVdLCBmb250U3R5bGU6ICdib2xkJyB9LFxuICAgICAgICAgICAgYm9keToge30sXG4gICAgICAgICAgICBmb290OiB7IHRleHRDb2xvcjogMjU1LCBmaWxsQ29sb3I6IFs0MSwgMTI4LCAxODVdLCBmb250U3R5bGU6ICdib2xkJyB9LFxuICAgICAgICAgICAgYWx0ZXJuYXRlUm93OiB7IGZpbGxDb2xvcjogMjQ1IH0sXG4gICAgICAgIH0sXG4gICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICAgIHRhYmxlOiB7XG4gICAgICAgICAgICAgICAgZmlsbENvbG9yOiAyNTUsXG4gICAgICAgICAgICAgICAgdGV4dENvbG9yOiA4MCxcbiAgICAgICAgICAgICAgICBmb250U3R5bGU6ICdub3JtYWwnLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMC4xLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGhlYWQ6IHtcbiAgICAgICAgICAgICAgICB0ZXh0Q29sb3I6IDI1NSxcbiAgICAgICAgICAgICAgICBmaWxsQ29sb3I6IFsyNiwgMTg4LCAxNTZdLFxuICAgICAgICAgICAgICAgIGZvbnRTdHlsZTogJ2JvbGQnLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiB7fSxcbiAgICAgICAgICAgIGZvb3Q6IHtcbiAgICAgICAgICAgICAgICB0ZXh0Q29sb3I6IDI1NSxcbiAgICAgICAgICAgICAgICBmaWxsQ29sb3I6IFsyNiwgMTg4LCAxNTZdLFxuICAgICAgICAgICAgICAgIGZvbnRTdHlsZTogJ2JvbGQnLFxuICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhbHRlcm5hdGVSb3c6IHt9LFxuICAgICAgICB9LFxuICAgICAgICBwbGFpbjogeyBoZWFkOiB7IGZvbnRTdHlsZTogJ2JvbGQnIH0sIGZvb3Q6IHsgZm9udFN0eWxlOiAnYm9sZCcgfSB9LFxuICAgIH07XG4gICAgcmV0dXJuIHRoZW1lc1tuYW1lXTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RyaW5nV2lkdGgodGV4dCwgc3R5bGVzLCBkb2MpIHtcbiAgICBkb2MuYXBwbHlTdHlsZXMoc3R5bGVzLCB0cnVlKTtcbiAgICB2YXIgdGV4dEFyciA9IEFycmF5LmlzQXJyYXkodGV4dCkgPyB0ZXh0IDogW3RleHRdO1xuICAgIHZhciB3aWRlc3RMaW5lV2lkdGggPSB0ZXh0QXJyXG4gICAgICAgIC5tYXAoZnVuY3Rpb24gKHRleHQpIHsgcmV0dXJuIGRvYy5nZXRUZXh0V2lkdGgodGV4dCk7IH0pXG4gICAgICAgIC5yZWR1Y2UoZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIE1hdGgubWF4KGEsIGIpOyB9LCAwKTtcbiAgICByZXR1cm4gd2lkZXN0TGluZVdpZHRoO1xufVxuZnVuY3Rpb24gYWRkVGFibGVCb3JkZXIoZG9jLCB0YWJsZSwgc3RhcnRQb3MsIGN1cnNvcikge1xuICAgIHZhciBsaW5lV2lkdGggPSB0YWJsZS5zZXR0aW5ncy50YWJsZUxpbmVXaWR0aDtcbiAgICB2YXIgbGluZUNvbG9yID0gdGFibGUuc2V0dGluZ3MudGFibGVMaW5lQ29sb3I7XG4gICAgZG9jLmFwcGx5U3R5bGVzKHsgbGluZVdpZHRoOiBsaW5lV2lkdGgsIGxpbmVDb2xvcjogbGluZUNvbG9yIH0pO1xuICAgIHZhciBmaWxsU3R5bGUgPSBnZXRGaWxsU3R5bGUobGluZVdpZHRoLCBmYWxzZSk7XG4gICAgaWYgKGZpbGxTdHlsZSkge1xuICAgICAgICBkb2MucmVjdChzdGFydFBvcy54LCBzdGFydFBvcy55LCB0YWJsZS5nZXRXaWR0aChkb2MucGFnZVNpemUoKS53aWR0aCksIGN1cnNvci55IC0gc3RhcnRQb3MueSwgZmlsbFN0eWxlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRGaWxsU3R5bGUobGluZVdpZHRoLCBmaWxsQ29sb3IpIHtcbiAgICB2YXIgZHJhd0xpbmUgPSBsaW5lV2lkdGggPiAwO1xuICAgIHZhciBkcmF3QmFja2dyb3VuZCA9IGZpbGxDb2xvciB8fCBmaWxsQ29sb3IgPT09IDA7XG4gICAgaWYgKGRyYXdMaW5lICYmIGRyYXdCYWNrZ3JvdW5kKSB7XG4gICAgICAgIHJldHVybiAnREYnOyAvLyBGaWxsIHRoZW4gc3Ryb2tlXG4gICAgfVxuICAgIGVsc2UgaWYgKGRyYXdMaW5lKSB7XG4gICAgICAgIHJldHVybiAnUyc7IC8vIE9ubHkgc3Ryb2tlICh0cmFuc3BhcmVudCBiYWNrZ3JvdW5kKVxuICAgIH1cbiAgICBlbHNlIGlmIChkcmF3QmFja2dyb3VuZCkge1xuICAgICAgICByZXR1cm4gJ0YnOyAvLyBPbmx5IGZpbGwsIG5vIHN0cm9rZVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufVxuZnVuY3Rpb24gcGFyc2VTcGFjaW5nKHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICB2YXIgX2EsIF9iLCBfYywgX2Q7XG4gICAgdmFsdWUgPSB2YWx1ZSB8fCBkZWZhdWx0VmFsdWU7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPj0gNCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0b3A6IHZhbHVlWzBdLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiB2YWx1ZVsxXSxcbiAgICAgICAgICAgICAgICBib3R0b206IHZhbHVlWzJdLFxuICAgICAgICAgICAgICAgIGxlZnQ6IHZhbHVlWzNdLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh2YWx1ZS5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdG9wOiB2YWx1ZVswXSxcbiAgICAgICAgICAgICAgICByaWdodDogdmFsdWVbMV0sXG4gICAgICAgICAgICAgICAgYm90dG9tOiB2YWx1ZVsyXSxcbiAgICAgICAgICAgICAgICBsZWZ0OiB2YWx1ZVsxXSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodmFsdWUubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHRvcDogdmFsdWVbMF0sXG4gICAgICAgICAgICAgICAgcmlnaHQ6IHZhbHVlWzFdLFxuICAgICAgICAgICAgICAgIGJvdHRvbTogdmFsdWVbMF0sXG4gICAgICAgICAgICAgICAgbGVmdDogdmFsdWVbMV0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZVswXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUudmVydGljYWwgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICB2YWx1ZS50b3AgPSB2YWx1ZS52ZXJ0aWNhbDtcbiAgICAgICAgICAgIHZhbHVlLmJvdHRvbSA9IHZhbHVlLnZlcnRpY2FsO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUuaG9yaXpvbnRhbCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHZhbHVlLnJpZ2h0ID0gdmFsdWUuaG9yaXpvbnRhbDtcbiAgICAgICAgICAgIHZhbHVlLmxlZnQgPSB2YWx1ZS5ob3Jpem9udGFsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsZWZ0OiAoX2EgPSB2YWx1ZS5sZWZ0KSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBkZWZhdWx0VmFsdWUsXG4gICAgICAgICAgICB0b3A6IChfYiA9IHZhbHVlLnRvcCkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogZGVmYXVsdFZhbHVlLFxuICAgICAgICAgICAgcmlnaHQ6IChfYyA9IHZhbHVlLnJpZ2h0KSAhPT0gbnVsbCAmJiBfYyAhPT0gdm9pZCAwID8gX2MgOiBkZWZhdWx0VmFsdWUsXG4gICAgICAgICAgICBib3R0b206IChfZCA9IHZhbHVlLmJvdHRvbSkgIT09IG51bGwgJiYgX2QgIT09IHZvaWQgMCA/IF9kIDogZGVmYXVsdFZhbHVlLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJykge1xuICAgICAgICB2YWx1ZSA9IGRlZmF1bHRWYWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHsgdG9wOiB2YWx1ZSwgcmlnaHQ6IHZhbHVlLCBib3R0b206IHZhbHVlLCBsZWZ0OiB2YWx1ZSB9O1xufVxuZnVuY3Rpb24gZ2V0UGFnZUF2YWlsYWJsZVdpZHRoKGRvYywgdGFibGUpIHtcbiAgICB2YXIgbWFyZ2lucyA9IHBhcnNlU3BhY2luZyh0YWJsZS5zZXR0aW5ncy5tYXJnaW4sIDApO1xuICAgIHJldHVybiBkb2MucGFnZVNpemUoKS53aWR0aCAtIChtYXJnaW5zLmxlZnQgKyBtYXJnaW5zLnJpZ2h0KTtcbn1cblxuLy8gTGltaXRhdGlvbnNcbi8vIC0gTm8gc3VwcG9ydCBmb3IgYm9yZGVyIHNwYWNpbmdcbi8vIC0gTm8gc3VwcG9ydCBmb3IgdHJhbnNwYXJlbmN5XG5mdW5jdGlvbiBwYXJzZUNzcyhzdXBwb3J0ZWRGb250cywgZWxlbWVudCwgc2NhbGVGYWN0b3IsIHN0eWxlLCB3aW5kb3cpIHtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgdmFyIHB4U2NhbGVGYWN0b3IgPSA5NiAvIDcyO1xuICAgIHZhciBiYWNrZ3JvdW5kQ29sb3IgPSBwYXJzZUNvbG9yKGVsZW1lbnQsIGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtKVsnYmFja2dyb3VuZENvbG9yJ107XG4gICAgfSk7XG4gICAgaWYgKGJhY2tncm91bmRDb2xvciAhPSBudWxsKVxuICAgICAgICByZXN1bHQuZmlsbENvbG9yID0gYmFja2dyb3VuZENvbG9yO1xuICAgIHZhciB0ZXh0Q29sb3IgPSBwYXJzZUNvbG9yKGVsZW1lbnQsIGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtKVsnY29sb3InXTtcbiAgICB9KTtcbiAgICBpZiAodGV4dENvbG9yICE9IG51bGwpXG4gICAgICAgIHJlc3VsdC50ZXh0Q29sb3IgPSB0ZXh0Q29sb3I7XG4gICAgdmFyIHBhZGRpbmcgPSBwYXJzZVBhZGRpbmcoc3R5bGUsIHNjYWxlRmFjdG9yKTtcbiAgICBpZiAocGFkZGluZylcbiAgICAgICAgcmVzdWx0LmNlbGxQYWRkaW5nID0gcGFkZGluZztcbiAgICB2YXIgYm9yZGVyQ29sb3JTaWRlID0gJ2JvcmRlclRvcENvbG9yJztcbiAgICB2YXIgZmluYWxTY2FsZUZhY3RvciA9IHB4U2NhbGVGYWN0b3IgKiBzY2FsZUZhY3RvcjtcbiAgICB2YXIgYnR3ID0gc3R5bGUuYm9yZGVyVG9wV2lkdGg7XG4gICAgaWYgKHN0eWxlLmJvcmRlckJvdHRvbVdpZHRoID09PSBidHcgJiZcbiAgICAgICAgc3R5bGUuYm9yZGVyUmlnaHRXaWR0aCA9PT0gYnR3ICYmXG4gICAgICAgIHN0eWxlLmJvcmRlckxlZnRXaWR0aCA9PT0gYnR3KSB7XG4gICAgICAgIHZhciBib3JkZXJXaWR0aCA9IChwYXJzZUZsb2F0KGJ0dykgfHwgMCkgLyBmaW5hbFNjYWxlRmFjdG9yO1xuICAgICAgICBpZiAoYm9yZGVyV2lkdGgpXG4gICAgICAgICAgICByZXN1bHQubGluZVdpZHRoID0gYm9yZGVyV2lkdGg7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXN1bHQubGluZVdpZHRoID0ge1xuICAgICAgICAgICAgdG9wOiAocGFyc2VGbG9hdChzdHlsZS5ib3JkZXJUb3BXaWR0aCkgfHwgMCkgLyBmaW5hbFNjYWxlRmFjdG9yLFxuICAgICAgICAgICAgcmlnaHQ6IChwYXJzZUZsb2F0KHN0eWxlLmJvcmRlclJpZ2h0V2lkdGgpIHx8IDApIC8gZmluYWxTY2FsZUZhY3RvcixcbiAgICAgICAgICAgIGJvdHRvbTogKHBhcnNlRmxvYXQoc3R5bGUuYm9yZGVyQm90dG9tV2lkdGgpIHx8IDApIC8gZmluYWxTY2FsZUZhY3RvcixcbiAgICAgICAgICAgIGxlZnQ6IChwYXJzZUZsb2F0KHN0eWxlLmJvcmRlckxlZnRXaWR0aCkgfHwgMCkgLyBmaW5hbFNjYWxlRmFjdG9yLFxuICAgICAgICB9O1xuICAgICAgICAvLyBDaG9vc2UgYm9yZGVyIGNvbG9yIG9mIGZpcnN0IGF2YWlsYWJsZSBzaWRlXG4gICAgICAgIC8vIGNvdWxkIGJlIGltcHJvdmVkIGJ5IHN1cHBvcnRpbmcgb2JqZWN0IGFzIGxpbmVDb2xvclxuICAgICAgICBpZiAoIXJlc3VsdC5saW5lV2lkdGgudG9wKSB7XG4gICAgICAgICAgICBpZiAocmVzdWx0LmxpbmVXaWR0aC5yaWdodCkge1xuICAgICAgICAgICAgICAgIGJvcmRlckNvbG9yU2lkZSA9ICdib3JkZXJSaWdodENvbG9yJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdC5saW5lV2lkdGguYm90dG9tKSB7XG4gICAgICAgICAgICAgICAgYm9yZGVyQ29sb3JTaWRlID0gJ2JvcmRlckJvdHRvbUNvbG9yJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdC5saW5lV2lkdGgubGVmdCkge1xuICAgICAgICAgICAgICAgIGJvcmRlckNvbG9yU2lkZSA9ICdib3JkZXJMZWZ0Q29sb3InO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHZhciBib3JkZXJDb2xvciA9IHBhcnNlQ29sb3IoZWxlbWVudCwgZnVuY3Rpb24gKGVsZW0pIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW0pW2JvcmRlckNvbG9yU2lkZV07XG4gICAgfSk7XG4gICAgaWYgKGJvcmRlckNvbG9yICE9IG51bGwpXG4gICAgICAgIHJlc3VsdC5saW5lQ29sb3IgPSBib3JkZXJDb2xvcjtcbiAgICB2YXIgYWNjZXB0ZWQgPSBbJ2xlZnQnLCAncmlnaHQnLCAnY2VudGVyJywgJ2p1c3RpZnknXTtcbiAgICBpZiAoYWNjZXB0ZWQuaW5kZXhPZihzdHlsZS50ZXh0QWxpZ24pICE9PSAtMSkge1xuICAgICAgICByZXN1bHQuaGFsaWduID0gc3R5bGUudGV4dEFsaWduO1xuICAgIH1cbiAgICBhY2NlcHRlZCA9IFsnbWlkZGxlJywgJ2JvdHRvbScsICd0b3AnXTtcbiAgICBpZiAoYWNjZXB0ZWQuaW5kZXhPZihzdHlsZS52ZXJ0aWNhbEFsaWduKSAhPT0gLTEpIHtcbiAgICAgICAgcmVzdWx0LnZhbGlnbiA9IHN0eWxlLnZlcnRpY2FsQWxpZ247XG4gICAgfVxuICAgIHZhciByZXMgPSBwYXJzZUludChzdHlsZS5mb250U2l6ZSB8fCAnJyk7XG4gICAgaWYgKCFpc05hTihyZXMpKVxuICAgICAgICByZXN1bHQuZm9udFNpemUgPSByZXMgLyBweFNjYWxlRmFjdG9yO1xuICAgIHZhciBmb250U3R5bGUgPSBwYXJzZUZvbnRTdHlsZShzdHlsZSk7XG4gICAgaWYgKGZvbnRTdHlsZSlcbiAgICAgICAgcmVzdWx0LmZvbnRTdHlsZSA9IGZvbnRTdHlsZTtcbiAgICB2YXIgZm9udCA9IChzdHlsZS5mb250RmFtaWx5IHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChzdXBwb3J0ZWRGb250cy5pbmRleE9mKGZvbnQpICE9PSAtMSkge1xuICAgICAgICByZXN1bHQuZm9udCA9IGZvbnQ7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBwYXJzZUZvbnRTdHlsZShzdHlsZSkge1xuICAgIHZhciByZXMgPSAnJztcbiAgICBpZiAoc3R5bGUuZm9udFdlaWdodCA9PT0gJ2JvbGQnIHx8XG4gICAgICAgIHN0eWxlLmZvbnRXZWlnaHQgPT09ICdib2xkZXInIHx8XG4gICAgICAgIHBhcnNlSW50KHN0eWxlLmZvbnRXZWlnaHQpID49IDcwMCkge1xuICAgICAgICByZXMgPSAnYm9sZCc7XG4gICAgfVxuICAgIGlmIChzdHlsZS5mb250U3R5bGUgPT09ICdpdGFsaWMnIHx8IHN0eWxlLmZvbnRTdHlsZSA9PT0gJ29ibGlxdWUnKSB7XG4gICAgICAgIHJlcyArPSAnaXRhbGljJztcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cbmZ1bmN0aW9uIHBhcnNlQ29sb3IoZWxlbWVudCwgc3R5bGVHZXR0ZXIpIHtcbiAgICB2YXIgY3NzQ29sb3IgPSByZWFsQ29sb3IoZWxlbWVudCwgc3R5bGVHZXR0ZXIpO1xuICAgIGlmICghY3NzQ29sb3IpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIHZhciByZ2JhID0gY3NzQ29sb3IubWF0Y2goL15yZ2JhP1xcKChcXGQrKSxcXHMqKFxcZCspLFxccyooXFxkKykoPzosXFxzKihcXGQqXFwuP1xcZCopKT9cXCkkLyk7XG4gICAgaWYgKCFyZ2JhIHx8ICFBcnJheS5pc0FycmF5KHJnYmEpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgY29sb3IgPSBbXG4gICAgICAgIHBhcnNlSW50KHJnYmFbMV0pLFxuICAgICAgICBwYXJzZUludChyZ2JhWzJdKSxcbiAgICAgICAgcGFyc2VJbnQocmdiYVszXSksXG4gICAgXTtcbiAgICB2YXIgYWxwaGEgPSBwYXJzZUludChyZ2JhWzRdKTtcbiAgICBpZiAoYWxwaGEgPT09IDAgfHwgaXNOYU4oY29sb3JbMF0pIHx8IGlzTmFOKGNvbG9yWzFdKSB8fCBpc05hTihjb2xvclsyXSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjb2xvcjtcbn1cbmZ1bmN0aW9uIHJlYWxDb2xvcihlbGVtLCBzdHlsZUdldHRlcikge1xuICAgIHZhciBiZyA9IHN0eWxlR2V0dGVyKGVsZW0pO1xuICAgIGlmIChiZyA9PT0gJ3JnYmEoMCwgMCwgMCwgMCknIHx8XG4gICAgICAgIGJnID09PSAndHJhbnNwYXJlbnQnIHx8XG4gICAgICAgIGJnID09PSAnaW5pdGlhbCcgfHxcbiAgICAgICAgYmcgPT09ICdpbmhlcml0Jykge1xuICAgICAgICBpZiAoZWxlbS5wYXJlbnRFbGVtZW50ID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWFsQ29sb3IoZWxlbS5wYXJlbnRFbGVtZW50LCBzdHlsZUdldHRlcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gYmc7XG4gICAgfVxufVxuZnVuY3Rpb24gcGFyc2VQYWRkaW5nKHN0eWxlLCBzY2FsZUZhY3Rvcikge1xuICAgIHZhciB2YWwgPSBbXG4gICAgICAgIHN0eWxlLnBhZGRpbmdUb3AsXG4gICAgICAgIHN0eWxlLnBhZGRpbmdSaWdodCxcbiAgICAgICAgc3R5bGUucGFkZGluZ0JvdHRvbSxcbiAgICAgICAgc3R5bGUucGFkZGluZ0xlZnQsXG4gICAgXTtcbiAgICB2YXIgcHhTY2FsZUZhY3RvciA9IDk2IC8gKDcyIC8gc2NhbGVGYWN0b3IpO1xuICAgIHZhciBsaW5lUGFkZGluZyA9IChwYXJzZUludChzdHlsZS5saW5lSGVpZ2h0KSAtIHBhcnNlSW50KHN0eWxlLmZvbnRTaXplKSkgLyBzY2FsZUZhY3RvciAvIDI7XG4gICAgdmFyIGlucHV0UGFkZGluZyA9IHZhbC5tYXAoZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KG4gfHwgJzAnKSAvIHB4U2NhbGVGYWN0b3I7XG4gICAgfSk7XG4gICAgdmFyIHBhZGRpbmcgPSBwYXJzZVNwYWNpbmcoaW5wdXRQYWRkaW5nLCAwKTtcbiAgICBpZiAobGluZVBhZGRpbmcgPiBwYWRkaW5nLnRvcCkge1xuICAgICAgICBwYWRkaW5nLnRvcCA9IGxpbmVQYWRkaW5nO1xuICAgIH1cbiAgICBpZiAobGluZVBhZGRpbmcgPiBwYWRkaW5nLmJvdHRvbSkge1xuICAgICAgICBwYWRkaW5nLmJvdHRvbSA9IGxpbmVQYWRkaW5nO1xuICAgIH1cbiAgICByZXR1cm4gcGFkZGluZztcbn1cblxuZnVuY3Rpb24gcGFyc2VIdG1sKGRvYywgaW5wdXQsIHdpbmRvdywgaW5jbHVkZUhpZGRlbkh0bWwsIHVzZUNzcykge1xuICAgIHZhciBfYSwgX2I7XG4gICAgaWYgKGluY2x1ZGVIaWRkZW5IdG1sID09PSB2b2lkIDApIHsgaW5jbHVkZUhpZGRlbkh0bWwgPSBmYWxzZTsgfVxuICAgIGlmICh1c2VDc3MgPT09IHZvaWQgMCkgeyB1c2VDc3MgPSBmYWxzZTsgfVxuICAgIHZhciB0YWJsZUVsZW1lbnQ7XG4gICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGFibGVFbGVtZW50ID0gd2luZG93LmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoaW5wdXQpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdGFibGVFbGVtZW50ID0gaW5wdXQ7XG4gICAgfVxuICAgIHZhciBzdXBwb3J0ZWRGb250cyA9IE9iamVjdC5rZXlzKGRvYy5nZXRGb250TGlzdCgpKTtcbiAgICB2YXIgc2NhbGVGYWN0b3IgPSBkb2Muc2NhbGVGYWN0b3IoKTtcbiAgICB2YXIgaGVhZCA9IFtdLCBib2R5ID0gW10sIGZvb3QgPSBbXTtcbiAgICBpZiAoIXRhYmxlRWxlbWVudCkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdIdG1sIHRhYmxlIGNvdWxkIG5vdCBiZSBmb3VuZCB3aXRoIGlucHV0OiAnLCBpbnB1dCk7XG4gICAgICAgIHJldHVybiB7IGhlYWQ6IGhlYWQsIGJvZHk6IGJvZHksIGZvb3Q6IGZvb3QgfTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZUVsZW1lbnQucm93cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZWxlbWVudCA9IHRhYmxlRWxlbWVudC5yb3dzW2ldO1xuICAgICAgICB2YXIgdGFnTmFtZSA9IChfYiA9IChfYSA9IGVsZW1lbnQgPT09IG51bGwgfHwgZWxlbWVudCA9PT0gdm9pZCAwID8gdm9pZCAwIDogZWxlbWVudC5wYXJlbnRFbGVtZW50KSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EudGFnTmFtZSkgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciByb3cgPSBwYXJzZVJvd0NvbnRlbnQoc3VwcG9ydGVkRm9udHMsIHNjYWxlRmFjdG9yLCB3aW5kb3csIGVsZW1lbnQsIGluY2x1ZGVIaWRkZW5IdG1sLCB1c2VDc3MpO1xuICAgICAgICBpZiAoIXJvdylcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBpZiAodGFnTmFtZSA9PT0gJ3RoZWFkJykge1xuICAgICAgICAgICAgaGVhZC5wdXNoKHJvdyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGFnTmFtZSA9PT0gJ3Rmb290Jykge1xuICAgICAgICAgICAgZm9vdC5wdXNoKHJvdyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBBZGQgdG8gYm9keSBib3RoIGlmIHBhcmVudCBpcyB0Ym9keSBvciB0YWJsZVxuICAgICAgICAgICAgYm9keS5wdXNoKHJvdyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgaGVhZDogaGVhZCwgYm9keTogYm9keSwgZm9vdDogZm9vdCB9O1xufVxuZnVuY3Rpb24gcGFyc2VSb3dDb250ZW50KHN1cHBvcnRlZEZvbnRzLCBzY2FsZUZhY3Rvciwgd2luZG93LCByb3csIGluY2x1ZGVIaWRkZW4sIHVzZUNzcykge1xuICAgIHZhciByZXN1bHRSb3cgPSBuZXcgSHRtbFJvd0lucHV0KHJvdyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByb3cuY2VsbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNlbGwgPSByb3cuY2VsbHNbaV07XG4gICAgICAgIHZhciBzdHlsZV8xID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoY2VsbCk7XG4gICAgICAgIGlmIChpbmNsdWRlSGlkZGVuIHx8IHN0eWxlXzEuZGlzcGxheSAhPT0gJ25vbmUnKSB7XG4gICAgICAgICAgICB2YXIgY2VsbFN0eWxlcyA9IHZvaWQgMDtcbiAgICAgICAgICAgIGlmICh1c2VDc3MpIHtcbiAgICAgICAgICAgICAgICBjZWxsU3R5bGVzID0gcGFyc2VDc3Moc3VwcG9ydGVkRm9udHMsIGNlbGwsIHNjYWxlRmFjdG9yLCBzdHlsZV8xLCB3aW5kb3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0Um93LnB1c2goe1xuICAgICAgICAgICAgICAgIHJvd1NwYW46IGNlbGwucm93U3BhbixcbiAgICAgICAgICAgICAgICBjb2xTcGFuOiBjZWxsLmNvbFNwYW4sXG4gICAgICAgICAgICAgICAgc3R5bGVzOiBjZWxsU3R5bGVzLFxuICAgICAgICAgICAgICAgIF9lbGVtZW50OiBjZWxsLFxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHBhcnNlQ2VsbENvbnRlbnQoY2VsbCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB2YXIgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShyb3cpO1xuICAgIGlmIChyZXN1bHRSb3cubGVuZ3RoID4gMCAmJiAoaW5jbHVkZUhpZGRlbiB8fCBzdHlsZS5kaXNwbGF5ICE9PSAnbm9uZScpKSB7XG4gICAgICAgIHJldHVybiByZXN1bHRSb3c7XG4gICAgfVxufVxuZnVuY3Rpb24gcGFyc2VDZWxsQ29udGVudChvcmdDZWxsKSB7XG4gICAgLy8gV29yayBvbiBjbG9uZWQgbm9kZSB0byBtYWtlIHN1cmUgbm8gY2hhbmdlcyBhcmUgYXBwbGllZCB0byBodG1sIHRhYmxlXG4gICAgdmFyIGNlbGwgPSBvcmdDZWxsLmNsb25lTm9kZSh0cnVlKTtcbiAgICAvLyBSZW1vdmUgZXh0cmEgc3BhY2UgYW5kIGxpbmUgYnJlYWtzIGluIG1hcmt1cCB0byBtYWtlIGl0IG1vcmUgc2ltaWxhciB0b1xuICAgIC8vIHdoYXQgd291bGQgYmUgc2hvd24gaW4gaHRtbFxuICAgIGNlbGwuaW5uZXJIVE1MID0gY2VsbC5pbm5lckhUTUwucmVwbGFjZSgvXFxuL2csICcnKS5yZXBsYWNlKC8gKy9nLCAnICcpO1xuICAgIC8vIFByZXNlcnZlIDxicj4gdGFncyBhcyBsaW5lIGJyZWFrcyBpbiB0aGUgcGRmXG4gICAgY2VsbC5pbm5lckhUTUwgPSBjZWxsLmlubmVySFRNTFxuICAgICAgICAuc3BsaXQoLzxici4qPz4vKSAvL3N0YXJ0IHdpdGggJzxicicgYW5kIGVuZHMgd2l0aCAnPicuXG4gICAgICAgIC5tYXAoZnVuY3Rpb24gKHBhcnQpIHsgcmV0dXJuIHBhcnQudHJpbSgpOyB9KVxuICAgICAgICAuam9pbignXFxuJyk7XG4gICAgLy8gaW5uZXJUZXh0IGZvciBpZVxuICAgIHJldHVybiBjZWxsLmlubmVyVGV4dCB8fCBjZWxsLnRleHRDb250ZW50IHx8ICcnO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZUlucHV0KGdsb2JhbCwgZG9jdW1lbnQsIGN1cnJlbnQpIHtcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gW2dsb2JhbCwgZG9jdW1lbnQsIGN1cnJlbnRdOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IF9hW19pXTtcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgb3B0aW9ucyBwYXJhbWV0ZXIgc2hvdWxkIGJlIG9mIHR5cGUgb2JqZWN0LCBpczogJyArIHR5cGVvZiBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucy5zdGFydFkgJiYgdHlwZW9mIG9wdGlvbnMuc3RhcnRZICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignSW52YWxpZCB2YWx1ZSBmb3Igc3RhcnRZIG9wdGlvbicsIG9wdGlvbnMuc3RhcnRZKTtcbiAgICAgICAgICAgIGRlbGV0ZSBvcHRpb25zLnN0YXJ0WTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzICovXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvYXNzaWduXG5mdW5jdGlvbiBhc3NpZ24odGFyZ2V0LCBzLCBzMSwgczIsIHMzKSB7XG4gICAgaWYgKHRhcmdldCA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IHVuZGVmaW5lZCBvciBudWxsIHRvIG9iamVjdCcpO1xuICAgIH1cbiAgICB2YXIgdG8gPSBPYmplY3QodGFyZ2V0KTtcbiAgICBmb3IgKHZhciBpbmRleCA9IDE7IGluZGV4IDwgYXJndW1lbnRzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXJlc3QtcGFyYW1zXG4gICAgICAgIHZhciBuZXh0U291cmNlID0gYXJndW1lbnRzW2luZGV4XTtcbiAgICAgICAgaWYgKG5leHRTb3VyY2UgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gU2tpcCBvdmVyIGlmIHVuZGVmaW5lZCBvciBudWxsXG4gICAgICAgICAgICBmb3IgKHZhciBuZXh0S2V5IGluIG5leHRTb3VyY2UpIHtcbiAgICAgICAgICAgICAgICAvLyBBdm9pZCBidWdzIHdoZW4gaGFzT3duUHJvcGVydHkgaXMgc2hhZG93ZWRcbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG5leHRTb3VyY2UsIG5leHRLZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvW25leHRLZXldID0gbmV4dFNvdXJjZVtuZXh0S2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRvO1xufVxuXG5mdW5jdGlvbiBwYXJzZUlucHV0KGQsIGN1cnJlbnQpIHtcbiAgICB2YXIgZG9jID0gbmV3IERvY0hhbmRsZXIoZCk7XG4gICAgdmFyIGRvY3VtZW50ID0gZG9jLmdldERvY3VtZW50T3B0aW9ucygpO1xuICAgIHZhciBnbG9iYWwgPSBkb2MuZ2V0R2xvYmFsT3B0aW9ucygpO1xuICAgIHZhbGlkYXRlSW5wdXQoZ2xvYmFsLCBkb2N1bWVudCwgY3VycmVudCk7XG4gICAgdmFyIG9wdGlvbnMgPSBhc3NpZ24oe30sIGdsb2JhbCwgZG9jdW1lbnQsIGN1cnJlbnQpO1xuICAgIHZhciB3aW47XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHdpbiA9IHdpbmRvdztcbiAgICB9XG4gICAgdmFyIHN0eWxlcyA9IHBhcnNlU3R5bGVzKGdsb2JhbCwgZG9jdW1lbnQsIGN1cnJlbnQpO1xuICAgIHZhciBob29rcyA9IHBhcnNlSG9va3MoZ2xvYmFsLCBkb2N1bWVudCwgY3VycmVudCk7XG4gICAgdmFyIHNldHRpbmdzID0gcGFyc2VTZXR0aW5ncyhkb2MsIG9wdGlvbnMpO1xuICAgIHZhciBjb250ZW50ID0gcGFyc2VDb250ZW50JDEoZG9jLCBvcHRpb25zLCB3aW4pO1xuICAgIHJldHVybiB7IGlkOiBjdXJyZW50LnRhYmxlSWQsIGNvbnRlbnQ6IGNvbnRlbnQsIGhvb2tzOiBob29rcywgc3R5bGVzOiBzdHlsZXMsIHNldHRpbmdzOiBzZXR0aW5ncyB9O1xufVxuZnVuY3Rpb24gcGFyc2VTdHlsZXMoZ0lucHV0LCBkSW5wdXQsIGNJbnB1dCkge1xuICAgIHZhciBzdHlsZU9wdGlvbnMgPSB7XG4gICAgICAgIHN0eWxlczoge30sXG4gICAgICAgIGhlYWRTdHlsZXM6IHt9LFxuICAgICAgICBib2R5U3R5bGVzOiB7fSxcbiAgICAgICAgZm9vdFN0eWxlczoge30sXG4gICAgICAgIGFsdGVybmF0ZVJvd1N0eWxlczoge30sXG4gICAgICAgIGNvbHVtblN0eWxlczoge30sXG4gICAgfTtcbiAgICB2YXIgX2xvb3BfMSA9IGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgICAgIGlmIChwcm9wID09PSAnY29sdW1uU3R5bGVzJykge1xuICAgICAgICAgICAgdmFyIGdsb2JhbCA9IGdJbnB1dFtwcm9wXTtcbiAgICAgICAgICAgIHZhciBkb2N1bWVudF8xID0gZElucHV0W3Byb3BdO1xuICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSBjSW5wdXRbcHJvcF07XG4gICAgICAgICAgICBzdHlsZU9wdGlvbnMuY29sdW1uU3R5bGVzID0gYXNzaWduKHt9LCBnbG9iYWwsIGRvY3VtZW50XzEsIGN1cnJlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGFsbE9wdGlvbnMgPSBbZ0lucHV0LCBkSW5wdXQsIGNJbnB1dF07XG4gICAgICAgICAgICB2YXIgc3R5bGVzID0gYWxsT3B0aW9ucy5tYXAoZnVuY3Rpb24gKG9wdHMpIHsgcmV0dXJuIG9wdHNbcHJvcF0gfHwge307IH0pO1xuICAgICAgICAgICAgc3R5bGVPcHRpb25zW3Byb3BdID0gYXNzaWduKHt9LCBzdHlsZXNbMF0sIHN0eWxlc1sxXSwgc3R5bGVzWzJdKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IE9iamVjdC5rZXlzKHN0eWxlT3B0aW9ucyk7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhciBwcm9wID0gX2FbX2ldO1xuICAgICAgICBfbG9vcF8xKHByb3ApO1xuICAgIH1cbiAgICByZXR1cm4gc3R5bGVPcHRpb25zO1xufVxuZnVuY3Rpb24gcGFyc2VIb29rcyhnbG9iYWwsIGRvY3VtZW50LCBjdXJyZW50KSB7XG4gICAgdmFyIGFsbE9wdGlvbnMgPSBbZ2xvYmFsLCBkb2N1bWVudCwgY3VycmVudF07XG4gICAgdmFyIHJlc3VsdCA9IHtcbiAgICAgICAgZGlkUGFyc2VDZWxsOiBbXSxcbiAgICAgICAgd2lsbERyYXdDZWxsOiBbXSxcbiAgICAgICAgZGlkRHJhd0NlbGw6IFtdLFxuICAgICAgICB3aWxsRHJhd1BhZ2U6IFtdLFxuICAgICAgICBkaWREcmF3UGFnZTogW10sXG4gICAgfTtcbiAgICBmb3IgKHZhciBfaSA9IDAsIGFsbE9wdGlvbnNfMSA9IGFsbE9wdGlvbnM7IF9pIDwgYWxsT3B0aW9uc18xLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IGFsbE9wdGlvbnNfMVtfaV07XG4gICAgICAgIGlmIChvcHRpb25zLmRpZFBhcnNlQ2VsbClcbiAgICAgICAgICAgIHJlc3VsdC5kaWRQYXJzZUNlbGwucHVzaChvcHRpb25zLmRpZFBhcnNlQ2VsbCk7XG4gICAgICAgIGlmIChvcHRpb25zLndpbGxEcmF3Q2VsbClcbiAgICAgICAgICAgIHJlc3VsdC53aWxsRHJhd0NlbGwucHVzaChvcHRpb25zLndpbGxEcmF3Q2VsbCk7XG4gICAgICAgIGlmIChvcHRpb25zLmRpZERyYXdDZWxsKVxuICAgICAgICAgICAgcmVzdWx0LmRpZERyYXdDZWxsLnB1c2gob3B0aW9ucy5kaWREcmF3Q2VsbCk7XG4gICAgICAgIGlmIChvcHRpb25zLndpbGxEcmF3UGFnZSlcbiAgICAgICAgICAgIHJlc3VsdC53aWxsRHJhd1BhZ2UucHVzaChvcHRpb25zLndpbGxEcmF3UGFnZSk7XG4gICAgICAgIGlmIChvcHRpb25zLmRpZERyYXdQYWdlKVxuICAgICAgICAgICAgcmVzdWx0LmRpZERyYXdQYWdlLnB1c2gob3B0aW9ucy5kaWREcmF3UGFnZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBwYXJzZVNldHRpbmdzKGRvYywgb3B0aW9ucykge1xuICAgIHZhciBfYSwgX2IsIF9jLCBfZCwgX2UsIF9mLCBfZywgX2gsIF9qLCBfaywgX2wsIF9tO1xuICAgIHZhciBtYXJnaW4gPSBwYXJzZVNwYWNpbmcob3B0aW9ucy5tYXJnaW4sIDQwIC8gZG9jLnNjYWxlRmFjdG9yKCkpO1xuICAgIHZhciBzdGFydFkgPSAoX2EgPSBnZXRTdGFydFkoZG9jLCBvcHRpb25zLnN0YXJ0WSkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IG1hcmdpbi50b3A7XG4gICAgdmFyIHNob3dGb290O1xuICAgIGlmIChvcHRpb25zLnNob3dGb290ID09PSB0cnVlKSB7XG4gICAgICAgIHNob3dGb290ID0gJ2V2ZXJ5UGFnZSc7XG4gICAgfVxuICAgIGVsc2UgaWYgKG9wdGlvbnMuc2hvd0Zvb3QgPT09IGZhbHNlKSB7XG4gICAgICAgIHNob3dGb290ID0gJ25ldmVyJztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNob3dGb290ID0gKF9iID0gb3B0aW9ucy5zaG93Rm9vdCkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogJ2V2ZXJ5UGFnZSc7XG4gICAgfVxuICAgIHZhciBzaG93SGVhZDtcbiAgICBpZiAob3B0aW9ucy5zaG93SGVhZCA9PT0gdHJ1ZSkge1xuICAgICAgICBzaG93SGVhZCA9ICdldmVyeVBhZ2UnO1xuICAgIH1cbiAgICBlbHNlIGlmIChvcHRpb25zLnNob3dIZWFkID09PSBmYWxzZSkge1xuICAgICAgICBzaG93SGVhZCA9ICduZXZlcic7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzaG93SGVhZCA9IChfYyA9IG9wdGlvbnMuc2hvd0hlYWQpICE9PSBudWxsICYmIF9jICE9PSB2b2lkIDAgPyBfYyA6ICdldmVyeVBhZ2UnO1xuICAgIH1cbiAgICB2YXIgdXNlQ3NzID0gKF9kID0gb3B0aW9ucy51c2VDc3MpICE9PSBudWxsICYmIF9kICE9PSB2b2lkIDAgPyBfZCA6IGZhbHNlO1xuICAgIHZhciB0aGVtZSA9IG9wdGlvbnMudGhlbWUgfHwgKHVzZUNzcyA/ICdwbGFpbicgOiAnc3RyaXBlZCcpO1xuICAgIHZhciBob3Jpem9udGFsUGFnZUJyZWFrID0gISFvcHRpb25zLmhvcml6b250YWxQYWdlQnJlYWs7XG4gICAgdmFyIGhvcml6b250YWxQYWdlQnJlYWtSZXBlYXQgPSAoX2UgPSBvcHRpb25zLmhvcml6b250YWxQYWdlQnJlYWtSZXBlYXQpICE9PSBudWxsICYmIF9lICE9PSB2b2lkIDAgPyBfZSA6IG51bGw7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgaW5jbHVkZUhpZGRlbkh0bWw6IChfZiA9IG9wdGlvbnMuaW5jbHVkZUhpZGRlbkh0bWwpICE9PSBudWxsICYmIF9mICE9PSB2b2lkIDAgPyBfZiA6IGZhbHNlLFxuICAgICAgICB1c2VDc3M6IHVzZUNzcyxcbiAgICAgICAgdGhlbWU6IHRoZW1lLFxuICAgICAgICBzdGFydFk6IHN0YXJ0WSxcbiAgICAgICAgbWFyZ2luOiBtYXJnaW4sXG4gICAgICAgIHBhZ2VCcmVhazogKF9nID0gb3B0aW9ucy5wYWdlQnJlYWspICE9PSBudWxsICYmIF9nICE9PSB2b2lkIDAgPyBfZyA6ICdhdXRvJyxcbiAgICAgICAgcm93UGFnZUJyZWFrOiAoX2ggPSBvcHRpb25zLnJvd1BhZ2VCcmVhaykgIT09IG51bGwgJiYgX2ggIT09IHZvaWQgMCA/IF9oIDogJ2F1dG8nLFxuICAgICAgICB0YWJsZVdpZHRoOiAoX2ogPSBvcHRpb25zLnRhYmxlV2lkdGgpICE9PSBudWxsICYmIF9qICE9PSB2b2lkIDAgPyBfaiA6ICdhdXRvJyxcbiAgICAgICAgc2hvd0hlYWQ6IHNob3dIZWFkLFxuICAgICAgICBzaG93Rm9vdDogc2hvd0Zvb3QsXG4gICAgICAgIHRhYmxlTGluZVdpZHRoOiAoX2sgPSBvcHRpb25zLnRhYmxlTGluZVdpZHRoKSAhPT0gbnVsbCAmJiBfayAhPT0gdm9pZCAwID8gX2sgOiAwLFxuICAgICAgICB0YWJsZUxpbmVDb2xvcjogKF9sID0gb3B0aW9ucy50YWJsZUxpbmVDb2xvcikgIT09IG51bGwgJiYgX2wgIT09IHZvaWQgMCA/IF9sIDogMjAwLFxuICAgICAgICBob3Jpem9udGFsUGFnZUJyZWFrOiBob3Jpem9udGFsUGFnZUJyZWFrLFxuICAgICAgICBob3Jpem9udGFsUGFnZUJyZWFrUmVwZWF0OiBob3Jpem9udGFsUGFnZUJyZWFrUmVwZWF0LFxuICAgICAgICBob3Jpem9udGFsUGFnZUJyZWFrQmVoYXZpb3VyOiAoX20gPSBvcHRpb25zLmhvcml6b250YWxQYWdlQnJlYWtCZWhhdmlvdXIpICE9PSBudWxsICYmIF9tICE9PSB2b2lkIDAgPyBfbSA6ICdhZnRlckFsbFJvd3MnLFxuICAgIH07XG59XG5mdW5jdGlvbiBnZXRTdGFydFkoZG9jLCB1c2VyU3RhcnRZKSB7XG4gICAgdmFyIHByZXZpb3VzID0gZG9jLmdldExhc3RBdXRvVGFibGUoKTtcbiAgICB2YXIgc2YgPSBkb2Muc2NhbGVGYWN0b3IoKTtcbiAgICB2YXIgY3VycmVudFBhZ2UgPSBkb2MucGFnZU51bWJlcigpO1xuICAgIHZhciBpc1NhbWVQYWdlQXNQcmV2aW91c1RhYmxlID0gZmFsc2U7XG4gICAgaWYgKHByZXZpb3VzICYmIHByZXZpb3VzLnN0YXJ0UGFnZU51bWJlcikge1xuICAgICAgICB2YXIgZW5kaW5nUGFnZSA9IHByZXZpb3VzLnN0YXJ0UGFnZU51bWJlciArIHByZXZpb3VzLnBhZ2VOdW1iZXIgLSAxO1xuICAgICAgICBpc1NhbWVQYWdlQXNQcmV2aW91c1RhYmxlID0gZW5kaW5nUGFnZSA9PT0gY3VycmVudFBhZ2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdXNlclN0YXJ0WSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIHVzZXJTdGFydFk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHVzZXJTdGFydFkgPT0gbnVsbCB8fCB1c2VyU3RhcnRZID09PSBmYWxzZSkge1xuICAgICAgICBpZiAoaXNTYW1lUGFnZUFzUHJldmlvdXNUYWJsZSAmJiAocHJldmlvdXMgPT09IG51bGwgfHwgcHJldmlvdXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHByZXZpb3VzLmZpbmFsWSkgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gU29tZSB1c2VycyBoYWQgaXNzdWVzIHdpdGggb3ZlcmxhcHBpbmcgdGFibGVzIHdoZW4gdGhleSB1c2VkIG11bHRpcGxlXG4gICAgICAgICAgICAvLyB0YWJsZXMgd2l0aG91dCBzZXR0aW5nIHN0YXJ0WSBzbyBzZXR0aW5nIGl0IGhlcmUgdG8gYSBzZW5zaWJsZSBkZWZhdWx0LlxuICAgICAgICAgICAgcmV0dXJuIHByZXZpb3VzLmZpbmFsWSArIDIwIC8gc2Y7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBwYXJzZUNvbnRlbnQkMShkb2MsIG9wdGlvbnMsIHdpbmRvdykge1xuICAgIHZhciBoZWFkID0gb3B0aW9ucy5oZWFkIHx8IFtdO1xuICAgIHZhciBib2R5ID0gb3B0aW9ucy5ib2R5IHx8IFtdO1xuICAgIHZhciBmb290ID0gb3B0aW9ucy5mb290IHx8IFtdO1xuICAgIGlmIChvcHRpb25zLmh0bWwpIHtcbiAgICAgICAgdmFyIGhpZGRlbiA9IG9wdGlvbnMuaW5jbHVkZUhpZGRlbkh0bWw7XG4gICAgICAgIGlmICh3aW5kb3cpIHtcbiAgICAgICAgICAgIHZhciBodG1sQ29udGVudCA9IHBhcnNlSHRtbChkb2MsIG9wdGlvbnMuaHRtbCwgd2luZG93LCBoaWRkZW4sIG9wdGlvbnMudXNlQ3NzKSB8fCB7fTtcbiAgICAgICAgICAgIGhlYWQgPSBodG1sQ29udGVudC5oZWFkIHx8IGhlYWQ7XG4gICAgICAgICAgICBib2R5ID0gaHRtbENvbnRlbnQuYm9keSB8fCBoZWFkO1xuICAgICAgICAgICAgZm9vdCA9IGh0bWxDb250ZW50LmZvb3QgfHwgaGVhZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Nhbm5vdCBwYXJzZSBodG1sIGluIG5vbiBicm93c2VyIGVudmlyb25tZW50Jyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmFyIGNvbHVtbnMgPSBvcHRpb25zLmNvbHVtbnMgfHwgcGFyc2VDb2x1bW5zKGhlYWQsIGJvZHksIGZvb3QpO1xuICAgIHJldHVybiB7IGNvbHVtbnM6IGNvbHVtbnMsIGhlYWQ6IGhlYWQsIGJvZHk6IGJvZHksIGZvb3Q6IGZvb3QgfTtcbn1cbmZ1bmN0aW9uIHBhcnNlQ29sdW1ucyhoZWFkLCBib2R5LCBmb290KSB7XG4gICAgdmFyIGZpcnN0Um93ID0gaGVhZFswXSB8fCBib2R5WzBdIHx8IGZvb3RbMF0gfHwgW107XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIE9iamVjdC5rZXlzKGZpcnN0Um93KVxuICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIGtleSAhPT0gJ19lbGVtZW50JzsgfSlcbiAgICAgICAgLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgY29sU3BhbiA9IDE7XG4gICAgICAgIHZhciBpbnB1dDtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZmlyc3RSb3cpKSB7XG4gICAgICAgICAgICBpbnB1dCA9IGZpcnN0Um93W3BhcnNlSW50KGtleSldO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5wdXQgPSBmaXJzdFJvd1trZXldO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KGlucHV0KSkge1xuICAgICAgICAgICAgY29sU3BhbiA9IChpbnB1dCA9PT0gbnVsbCB8fCBpbnB1dCA9PT0gdm9pZCAwID8gdm9pZCAwIDogaW5wdXQuY29sU3BhbikgfHwgMTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbFNwYW47IGkrKykge1xuICAgICAgICAgICAgdmFyIGlkID0gdm9pZCAwO1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZmlyc3RSb3cpKSB7XG4gICAgICAgICAgICAgICAgaWQgPSByZXN1bHQubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWQgPSBrZXkgKyAoaSA+IDAgPyBcIl9cIi5jb25jYXQoaSkgOiAnJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcm93UmVzdWx0ID0geyBkYXRhS2V5OiBpZCB9O1xuICAgICAgICAgICAgcmVzdWx0LnB1c2gocm93UmVzdWx0KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbnZhciBIb29rRGF0YSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBIb29rRGF0YShkb2MsIHRhYmxlLCBjdXJzb3IpIHtcbiAgICAgICAgdGhpcy50YWJsZSA9IHRhYmxlO1xuICAgICAgICB0aGlzLnBhZ2VOdW1iZXIgPSB0YWJsZS5wYWdlTnVtYmVyO1xuICAgICAgICB0aGlzLnNldHRpbmdzID0gdGFibGUuc2V0dGluZ3M7XG4gICAgICAgIHRoaXMuY3Vyc29yID0gY3Vyc29yO1xuICAgICAgICB0aGlzLmRvYyA9IGRvYy5nZXREb2N1bWVudCgpO1xuICAgIH1cbiAgICByZXR1cm4gSG9va0RhdGE7XG59KCkpO1xudmFyIENlbGxIb29rRGF0YSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgICBfX2V4dGVuZHMoQ2VsbEhvb2tEYXRhLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIENlbGxIb29rRGF0YShkb2MsIHRhYmxlLCBjZWxsLCByb3csIGNvbHVtbiwgY3Vyc29yKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGRvYywgdGFibGUsIGN1cnNvcikgfHwgdGhpcztcbiAgICAgICAgX3RoaXMuY2VsbCA9IGNlbGw7XG4gICAgICAgIF90aGlzLnJvdyA9IHJvdztcbiAgICAgICAgX3RoaXMuY29sdW1uID0gY29sdW1uO1xuICAgICAgICBfdGhpcy5zZWN0aW9uID0gcm93LnNlY3Rpb247XG4gICAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG4gICAgcmV0dXJuIENlbGxIb29rRGF0YTtcbn0oSG9va0RhdGEpKTtcblxudmFyIFRhYmxlID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFRhYmxlKGlucHV0LCBjb250ZW50KSB7XG4gICAgICAgIHRoaXMucGFnZU51bWJlciA9IDE7XG4gICAgICAgIHRoaXMuaWQgPSBpbnB1dC5pZDtcbiAgICAgICAgdGhpcy5zZXR0aW5ncyA9IGlucHV0LnNldHRpbmdzO1xuICAgICAgICB0aGlzLnN0eWxlcyA9IGlucHV0LnN0eWxlcztcbiAgICAgICAgdGhpcy5ob29rcyA9IGlucHV0Lmhvb2tzO1xuICAgICAgICB0aGlzLmNvbHVtbnMgPSBjb250ZW50LmNvbHVtbnM7XG4gICAgICAgIHRoaXMuaGVhZCA9IGNvbnRlbnQuaGVhZDtcbiAgICAgICAgdGhpcy5ib2R5ID0gY29udGVudC5ib2R5O1xuICAgICAgICB0aGlzLmZvb3QgPSBjb250ZW50LmZvb3Q7XG4gICAgfVxuICAgIFRhYmxlLnByb3RvdHlwZS5nZXRIZWFkSGVpZ2h0ID0gZnVuY3Rpb24gKGNvbHVtbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGVhZC5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcm93KSB7IHJldHVybiBhY2MgKyByb3cuZ2V0TWF4Q2VsbEhlaWdodChjb2x1bW5zKTsgfSwgMCk7XG4gICAgfTtcbiAgICBUYWJsZS5wcm90b3R5cGUuZ2V0Rm9vdEhlaWdodCA9IGZ1bmN0aW9uIChjb2x1bW5zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvb3QucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHJvdykgeyByZXR1cm4gYWNjICsgcm93LmdldE1heENlbGxIZWlnaHQoY29sdW1ucyk7IH0sIDApO1xuICAgIH07XG4gICAgVGFibGUucHJvdG90eXBlLmFsbFJvd3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhlYWQuY29uY2F0KHRoaXMuYm9keSkuY29uY2F0KHRoaXMuZm9vdCk7XG4gICAgfTtcbiAgICBUYWJsZS5wcm90b3R5cGUuY2FsbENlbGxIb29rcyA9IGZ1bmN0aW9uIChkb2MsIGhhbmRsZXJzLCBjZWxsLCByb3csIGNvbHVtbiwgY3Vyc29yKSB7XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgaGFuZGxlcnNfMSA9IGhhbmRsZXJzOyBfaSA8IGhhbmRsZXJzXzEubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgaGFuZGxlciA9IGhhbmRsZXJzXzFbX2ldO1xuICAgICAgICAgICAgdmFyIGRhdGEgPSBuZXcgQ2VsbEhvb2tEYXRhKGRvYywgdGhpcywgY2VsbCwgcm93LCBjb2x1bW4sIGN1cnNvcik7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gaGFuZGxlcihkYXRhKSA9PT0gZmFsc2U7XG4gICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGV4dCBpcyBhbHdheXMgc3RyaW5nW10gc2luY2UgdXNlciBjYW4gYXNzaWduIHN0cmluZ1xuICAgICAgICAgICAgY2VsbC50ZXh0ID0gQXJyYXkuaXNBcnJheShjZWxsLnRleHQpID8gY2VsbC50ZXh0IDogW2NlbGwudGV4dF07XG4gICAgICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgVGFibGUucHJvdG90eXBlLmNhbGxFbmRQYWdlSG9va3MgPSBmdW5jdGlvbiAoZG9jLCBjdXJzb3IpIHtcbiAgICAgICAgZG9jLmFwcGx5U3R5bGVzKGRvYy51c2VyU3R5bGVzKTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMuaG9va3MuZGlkRHJhd1BhZ2U7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgaGFuZGxlciA9IF9hW19pXTtcbiAgICAgICAgICAgIGhhbmRsZXIobmV3IEhvb2tEYXRhKGRvYywgdGhpcywgY3Vyc29yKSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRhYmxlLnByb3RvdHlwZS5jYWxsV2lsbERyYXdQYWdlSG9va3MgPSBmdW5jdGlvbiAoZG9jLCBjdXJzb3IpIHtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMuaG9va3Mud2lsbERyYXdQYWdlOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgdmFyIGhhbmRsZXIgPSBfYVtfaV07XG4gICAgICAgICAgICBoYW5kbGVyKG5ldyBIb29rRGF0YShkb2MsIHRoaXMsIGN1cnNvcikpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBUYWJsZS5wcm90b3R5cGUuZ2V0V2lkdGggPSBmdW5jdGlvbiAocGFnZVdpZHRoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5zZXR0aW5ncy50YWJsZVdpZHRoID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0dGluZ3MudGFibGVXaWR0aDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnNldHRpbmdzLnRhYmxlV2lkdGggPT09ICd3cmFwJykge1xuICAgICAgICAgICAgdmFyIHdyYXBwZWRXaWR0aCA9IHRoaXMuY29sdW1ucy5yZWR1Y2UoZnVuY3Rpb24gKHRvdGFsLCBjb2wpIHsgcmV0dXJuIHRvdGFsICsgY29sLndyYXBwZWRXaWR0aDsgfSwgMCk7XG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlZFdpZHRoO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIG1hcmdpbiA9IHRoaXMuc2V0dGluZ3MubWFyZ2luO1xuICAgICAgICAgICAgcmV0dXJuIHBhZ2VXaWR0aCAtIG1hcmdpbi5sZWZ0IC0gbWFyZ2luLnJpZ2h0O1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gVGFibGU7XG59KCkpO1xudmFyIFJvdyA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBSb3cocmF3LCBpbmRleCwgc2VjdGlvbiwgY2VsbHMsIHNwYW5zTXVsdGlwbGVQYWdlcykge1xuICAgICAgICBpZiAoc3BhbnNNdWx0aXBsZVBhZ2VzID09PSB2b2lkIDApIHsgc3BhbnNNdWx0aXBsZVBhZ2VzID0gZmFsc2U7IH1cbiAgICAgICAgdGhpcy5oZWlnaHQgPSAwO1xuICAgICAgICB0aGlzLnJhdyA9IHJhdztcbiAgICAgICAgaWYgKHJhdyBpbnN0YW5jZW9mIEh0bWxSb3dJbnB1dCkge1xuICAgICAgICAgICAgdGhpcy5yYXcgPSByYXcuX2VsZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSByYXcuX2VsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgICAgICB0aGlzLnNlY3Rpb24gPSBzZWN0aW9uO1xuICAgICAgICB0aGlzLmNlbGxzID0gY2VsbHM7XG4gICAgICAgIHRoaXMuc3BhbnNNdWx0aXBsZVBhZ2VzID0gc3BhbnNNdWx0aXBsZVBhZ2VzO1xuICAgIH1cbiAgICBSb3cucHJvdG90eXBlLmdldE1heENlbGxIZWlnaHQgPSBmdW5jdGlvbiAoY29sdW1ucykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICByZXR1cm4gY29sdW1ucy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgY29sdW1uKSB7IHZhciBfYTsgcmV0dXJuIE1hdGgubWF4KGFjYywgKChfYSA9IF90aGlzLmNlbGxzW2NvbHVtbi5pbmRleF0pID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5oZWlnaHQpIHx8IDApOyB9LCAwKTtcbiAgICB9O1xuICAgIFJvdy5wcm90b3R5cGUuaGFzUm93U3BhbiA9IGZ1bmN0aW9uIChjb2x1bW5zKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiAoY29sdW1ucy5maWx0ZXIoZnVuY3Rpb24gKGNvbHVtbikge1xuICAgICAgICAgICAgdmFyIGNlbGwgPSBfdGhpcy5jZWxsc1tjb2x1bW4uaW5kZXhdO1xuICAgICAgICAgICAgaWYgKCFjZWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiBjZWxsLnJvd1NwYW4gPiAxO1xuICAgICAgICB9KS5sZW5ndGggPiAwKTtcbiAgICB9O1xuICAgIFJvdy5wcm90b3R5cGUuY2FuRW50aXJlUm93Rml0ID0gZnVuY3Rpb24gKGhlaWdodCwgY29sdW1ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRNYXhDZWxsSGVpZ2h0KGNvbHVtbnMpIDw9IGhlaWdodDtcbiAgICB9O1xuICAgIFJvdy5wcm90b3R5cGUuZ2V0TWluaW11bVJvd0hlaWdodCA9IGZ1bmN0aW9uIChjb2x1bW5zLCBkb2MpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGNvbHVtbnMucmVkdWNlKGZ1bmN0aW9uIChhY2MsIGNvbHVtbikge1xuICAgICAgICAgICAgdmFyIGNlbGwgPSBfdGhpcy5jZWxsc1tjb2x1bW4uaW5kZXhdO1xuICAgICAgICAgICAgaWYgKCFjZWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgdmFyIGxpbmVIZWlnaHQgPSBkb2MuZ2V0TGluZUhlaWdodChjZWxsLnN0eWxlcy5mb250U2l6ZSk7XG4gICAgICAgICAgICB2YXIgdlBhZGRpbmcgPSBjZWxsLnBhZGRpbmcoJ3ZlcnRpY2FsJyk7XG4gICAgICAgICAgICB2YXIgb25lUm93SGVpZ2h0ID0gdlBhZGRpbmcgKyBsaW5lSGVpZ2h0O1xuICAgICAgICAgICAgcmV0dXJuIG9uZVJvd0hlaWdodCA+IGFjYyA/IG9uZVJvd0hlaWdodCA6IGFjYztcbiAgICAgICAgfSwgMCk7XG4gICAgfTtcbiAgICByZXR1cm4gUm93O1xufSgpKTtcbnZhciBDZWxsID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENlbGwocmF3LCBzdHlsZXMsIHNlY3Rpb24pIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB0aGlzLmNvbnRlbnRIZWlnaHQgPSAwO1xuICAgICAgICB0aGlzLmNvbnRlbnRXaWR0aCA9IDA7XG4gICAgICAgIHRoaXMud3JhcHBlZFdpZHRoID0gMDtcbiAgICAgICAgdGhpcy5taW5SZWFkYWJsZVdpZHRoID0gMDtcbiAgICAgICAgdGhpcy5taW5XaWR0aCA9IDA7XG4gICAgICAgIHRoaXMud2lkdGggPSAwO1xuICAgICAgICB0aGlzLmhlaWdodCA9IDA7XG4gICAgICAgIHRoaXMueCA9IDA7XG4gICAgICAgIHRoaXMueSA9IDA7XG4gICAgICAgIHRoaXMuc3R5bGVzID0gc3R5bGVzO1xuICAgICAgICB0aGlzLnNlY3Rpb24gPSBzZWN0aW9uO1xuICAgICAgICB0aGlzLnJhdyA9IHJhdztcbiAgICAgICAgdmFyIGNvbnRlbnQgPSByYXc7XG4gICAgICAgIGlmIChyYXcgIT0gbnVsbCAmJiB0eXBlb2YgcmF3ID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheShyYXcpKSB7XG4gICAgICAgICAgICB0aGlzLnJvd1NwYW4gPSByYXcucm93U3BhbiB8fCAxO1xuICAgICAgICAgICAgdGhpcy5jb2xTcGFuID0gcmF3LmNvbFNwYW4gfHwgMTtcbiAgICAgICAgICAgIGNvbnRlbnQgPSAoX2EgPSByYXcuY29udGVudCkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogcmF3O1xuICAgICAgICAgICAgaWYgKHJhdy5fZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMucmF3ID0gcmF3Ll9lbGVtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5yb3dTcGFuID0gMTtcbiAgICAgICAgICAgIHRoaXMuY29sU3BhbiA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU3RyaW5naWZ5IDAgYW5kIGZhbHNlLCBidXQgbm90IHVuZGVmaW5lZCBvciBudWxsXG4gICAgICAgIHZhciB0ZXh0ID0gY29udGVudCAhPSBudWxsID8gJycgKyBjb250ZW50IDogJyc7XG4gICAgICAgIHZhciBzcGxpdFJlZ2V4ID0gL1xcclxcbnxcXHJ8XFxuL2c7XG4gICAgICAgIHRoaXMudGV4dCA9IHRleHQuc3BsaXQoc3BsaXRSZWdleCk7XG4gICAgfVxuICAgIENlbGwucHJvdG90eXBlLmdldFRleHRQb3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB5O1xuICAgICAgICBpZiAodGhpcy5zdHlsZXMudmFsaWduID09PSAndG9wJykge1xuICAgICAgICAgICAgeSA9IHRoaXMueSArIHRoaXMucGFkZGluZygndG9wJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5zdHlsZXMudmFsaWduID09PSAnYm90dG9tJykge1xuICAgICAgICAgICAgeSA9IHRoaXMueSArIHRoaXMuaGVpZ2h0IC0gdGhpcy5wYWRkaW5nKCdib3R0b20nKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBuZXRIZWlnaHQgPSB0aGlzLmhlaWdodCAtIHRoaXMucGFkZGluZygndmVydGljYWwnKTtcbiAgICAgICAgICAgIHkgPSB0aGlzLnkgKyBuZXRIZWlnaHQgLyAyICsgdGhpcy5wYWRkaW5nKCd0b3AnKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgeDtcbiAgICAgICAgaWYgKHRoaXMuc3R5bGVzLmhhbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgeCA9IHRoaXMueCArIHRoaXMud2lkdGggLSB0aGlzLnBhZGRpbmcoJ3JpZ2h0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5zdHlsZXMuaGFsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICAgICAgdmFyIG5ldFdpZHRoID0gdGhpcy53aWR0aCAtIHRoaXMucGFkZGluZygnaG9yaXpvbnRhbCcpO1xuICAgICAgICAgICAgeCA9IHRoaXMueCArIG5ldFdpZHRoIC8gMiArIHRoaXMucGFkZGluZygnbGVmdCcpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgeCA9IHRoaXMueCArIHRoaXMucGFkZGluZygnbGVmdCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHg6IHgsIHk6IHkgfTtcbiAgICB9O1xuICAgIC8vIFRPRE8gKHY0KTogcmVwbGFjZSBwYXJhbWV0ZXJzIHdpdGggb25seSAobGluZUhlaWdodClcbiAgICBDZWxsLnByb3RvdHlwZS5nZXRDb250ZW50SGVpZ2h0ID0gZnVuY3Rpb24gKHNjYWxlRmFjdG9yLCBsaW5lSGVpZ2h0RmFjdG9yKSB7XG4gICAgICAgIGlmIChsaW5lSGVpZ2h0RmFjdG9yID09PSB2b2lkIDApIHsgbGluZUhlaWdodEZhY3RvciA9IDEuMTU7IH1cbiAgICAgICAgdmFyIGxpbmVDb3VudCA9IEFycmF5LmlzQXJyYXkodGhpcy50ZXh0KSA/IHRoaXMudGV4dC5sZW5ndGggOiAxO1xuICAgICAgICB2YXIgbGluZUhlaWdodCA9ICh0aGlzLnN0eWxlcy5mb250U2l6ZSAvIHNjYWxlRmFjdG9yKSAqIGxpbmVIZWlnaHRGYWN0b3I7XG4gICAgICAgIHZhciBoZWlnaHQgPSBsaW5lQ291bnQgKiBsaW5lSGVpZ2h0ICsgdGhpcy5wYWRkaW5nKCd2ZXJ0aWNhbCcpO1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgoaGVpZ2h0LCB0aGlzLnN0eWxlcy5taW5DZWxsSGVpZ2h0KTtcbiAgICB9O1xuICAgIENlbGwucHJvdG90eXBlLnBhZGRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB2YXIgcGFkZGluZyA9IHBhcnNlU3BhY2luZyh0aGlzLnN0eWxlcy5jZWxsUGFkZGluZywgMCk7XG4gICAgICAgIGlmIChuYW1lID09PSAndmVydGljYWwnKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFkZGluZy50b3AgKyBwYWRkaW5nLmJvdHRvbTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICAgIHJldHVybiBwYWRkaW5nLmxlZnQgKyBwYWRkaW5nLnJpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHBhZGRpbmdbbmFtZV07XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBDZWxsO1xufSgpKTtcbnZhciBDb2x1bW4gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29sdW1uKGRhdGFLZXksIHJhdywgaW5kZXgpIHtcbiAgICAgICAgdGhpcy53cmFwcGVkV2lkdGggPSAwO1xuICAgICAgICB0aGlzLm1pblJlYWRhYmxlV2lkdGggPSAwO1xuICAgICAgICB0aGlzLm1pbldpZHRoID0gMDtcbiAgICAgICAgdGhpcy53aWR0aCA9IDA7XG4gICAgICAgIHRoaXMuZGF0YUtleSA9IGRhdGFLZXk7XG4gICAgICAgIHRoaXMucmF3ID0gcmF3O1xuICAgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgfVxuICAgIENvbHVtbi5wcm90b3R5cGUuZ2V0TWF4Q3VzdG9tQ2VsbFdpZHRoID0gZnVuY3Rpb24gKHRhYmxlKSB7XG4gICAgICAgIHZhciBtYXggPSAwO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGFibGUuYWxsUm93cygpOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgdmFyIHJvdyA9IF9hW19pXTtcbiAgICAgICAgICAgIHZhciBjZWxsID0gcm93LmNlbGxzW3RoaXMuaW5kZXhdO1xuICAgICAgICAgICAgaWYgKGNlbGwgJiYgdHlwZW9mIGNlbGwuc3R5bGVzLmNlbGxXaWR0aCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBtYXggPSBNYXRoLm1heChtYXgsIGNlbGwuc3R5bGVzLmNlbGxXaWR0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICB9O1xuICAgIHJldHVybiBDb2x1bW47XG59KCkpO1xuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgY29sdW1uIHdpZHRoc1xuICovXG5mdW5jdGlvbiBjYWxjdWxhdGVXaWR0aHMoZG9jLCB0YWJsZSkge1xuICAgIGNhbGN1bGF0ZShkb2MsIHRhYmxlKTtcbiAgICB2YXIgcmVzaXphYmxlQ29sdW1ucyA9IFtdO1xuICAgIHZhciBpbml0aWFsVGFibGVXaWR0aCA9IDA7XG4gICAgdGFibGUuY29sdW1ucy5mb3JFYWNoKGZ1bmN0aW9uIChjb2x1bW4pIHtcbiAgICAgICAgdmFyIGN1c3RvbVdpZHRoID0gY29sdW1uLmdldE1heEN1c3RvbUNlbGxXaWR0aCh0YWJsZSk7XG4gICAgICAgIGlmIChjdXN0b21XaWR0aCkge1xuICAgICAgICAgICAgLy8gZmluYWwgY29sdW1uIHdpZHRoXG4gICAgICAgICAgICBjb2x1bW4ud2lkdGggPSBjdXN0b21XaWR0aDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGluaXRpYWwgY29sdW1uIHdpZHRoICh3aWxsIGJlIHJlc2l6ZWQpXG4gICAgICAgICAgICBjb2x1bW4ud2lkdGggPSBjb2x1bW4ud3JhcHBlZFdpZHRoO1xuICAgICAgICAgICAgcmVzaXphYmxlQ29sdW1ucy5wdXNoKGNvbHVtbik7XG4gICAgICAgIH1cbiAgICAgICAgaW5pdGlhbFRhYmxlV2lkdGggKz0gY29sdW1uLndpZHRoO1xuICAgIH0pO1xuICAgIC8vIHdpZHRoIGRpZmZlcmVuY2UgdGhhdCBuZWVkcyB0byBiZSBkaXN0cmlidXRlZFxuICAgIHZhciByZXNpemVXaWR0aCA9IHRhYmxlLmdldFdpZHRoKGRvYy5wYWdlU2l6ZSgpLndpZHRoKSAtIGluaXRpYWxUYWJsZVdpZHRoO1xuICAgIC8vIGZpcnN0IHJlc2l6ZSBhdHRlbXB0OiB3aXRoIHJlc3BlY3QgdG8gbWluUmVhZGFibGVXaWR0aCBhbmQgbWluV2lkdGhcbiAgICBpZiAocmVzaXplV2lkdGgpIHtcbiAgICAgICAgcmVzaXplV2lkdGggPSByZXNpemVDb2x1bW5zKHJlc2l6YWJsZUNvbHVtbnMsIHJlc2l6ZVdpZHRoLCBmdW5jdGlvbiAoY29sdW1uKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5tYXgoY29sdW1uLm1pblJlYWRhYmxlV2lkdGgsIGNvbHVtbi5taW5XaWR0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBzZWNvbmQgcmVzaXplIGF0dGVtcHQ6IGlnbm9yZSBtaW5SZWFkYWJsZVdpZHRoIGJ1dCByZXNwZWN0IG1pbldpZHRoXG4gICAgaWYgKHJlc2l6ZVdpZHRoKSB7XG4gICAgICAgIHJlc2l6ZVdpZHRoID0gcmVzaXplQ29sdW1ucyhyZXNpemFibGVDb2x1bW5zLCByZXNpemVXaWR0aCwgZnVuY3Rpb24gKGNvbHVtbikgeyByZXR1cm4gY29sdW1uLm1pbldpZHRoOyB9KTtcbiAgICB9XG4gICAgcmVzaXplV2lkdGggPSBNYXRoLmFicyhyZXNpemVXaWR0aCk7XG4gICAgaWYgKCF0YWJsZS5zZXR0aW5ncy5ob3Jpem9udGFsUGFnZUJyZWFrICYmXG4gICAgICAgIHJlc2l6ZVdpZHRoID4gMC4xIC8gZG9jLnNjYWxlRmFjdG9yKCkpIHtcbiAgICAgICAgLy8gVGFibGUgY2FuJ3QgZ2V0IHNtYWxsZXIgZHVlIHRvIGN1c3RvbS13aWR0aCBvciBtaW5XaWR0aCByZXN0cmljdGlvbnNcbiAgICAgICAgLy8gV2UgY2FuJ3QgcmVhbGx5IGRvIG11Y2ggaGVyZS4gVXAgdG8gdXNlciB0byBmb3IgZXhhbXBsZVxuICAgICAgICAvLyByZWR1Y2UgZm9udCBzaXplLCBpbmNyZWFzZSBwYWdlIHNpemUgb3IgcmVtb3ZlIGN1c3RvbSBjZWxsIHdpZHRoc1xuICAgICAgICAvLyB0byBhbGxvdyBtb3JlIGNvbHVtbnMgdG8gYmUgcmVkdWNlZCBpbiBzaXplXG4gICAgICAgIHJlc2l6ZVdpZHRoID0gcmVzaXplV2lkdGggPCAxID8gcmVzaXplV2lkdGggOiBNYXRoLnJvdW5kKHJlc2l6ZVdpZHRoKTtcbiAgICAgICAgY29uc29sZS5sb2coXCJPZiB0aGUgdGFibGUgY29udGVudCwgXCIuY29uY2F0KHJlc2l6ZVdpZHRoLCBcIiB1bml0cyB3aWR0aCBjb3VsZCBub3QgZml0IHBhZ2VcIikpO1xuICAgIH1cbiAgICBhcHBseUNvbFNwYW5zKHRhYmxlKTtcbiAgICBmaXRDb250ZW50KHRhYmxlLCBkb2MpO1xuICAgIGFwcGx5Um93U3BhbnModGFibGUpO1xufVxuZnVuY3Rpb24gY2FsY3VsYXRlKGRvYywgdGFibGUpIHtcbiAgICB2YXIgc2YgPSBkb2Muc2NhbGVGYWN0b3IoKTtcbiAgICB2YXIgaG9yaXpvbnRhbFBhZ2VCcmVhayA9IHRhYmxlLnNldHRpbmdzLmhvcml6b250YWxQYWdlQnJlYWs7XG4gICAgdmFyIGF2YWlsYWJsZVBhZ2VXaWR0aCA9IGdldFBhZ2VBdmFpbGFibGVXaWR0aChkb2MsIHRhYmxlKTtcbiAgICB0YWJsZS5hbGxSb3dzKCkuZm9yRWFjaChmdW5jdGlvbiAocm93KSB7XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0YWJsZS5jb2x1bW5zOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgdmFyIGNvbHVtbiA9IF9hW19pXTtcbiAgICAgICAgICAgIHZhciBjZWxsID0gcm93LmNlbGxzW2NvbHVtbi5pbmRleF07XG4gICAgICAgICAgICBpZiAoIWNlbGwpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB2YXIgaG9va3MgPSB0YWJsZS5ob29rcy5kaWRQYXJzZUNlbGw7XG4gICAgICAgICAgICB0YWJsZS5jYWxsQ2VsbEhvb2tzKGRvYywgaG9va3MsIGNlbGwsIHJvdywgY29sdW1uLCBudWxsKTtcbiAgICAgICAgICAgIHZhciBwYWRkaW5nID0gY2VsbC5wYWRkaW5nKCdob3Jpem9udGFsJyk7XG4gICAgICAgICAgICBjZWxsLmNvbnRlbnRXaWR0aCA9IGdldFN0cmluZ1dpZHRoKGNlbGwudGV4dCwgY2VsbC5zdHlsZXMsIGRvYykgKyBwYWRkaW5nO1xuICAgICAgICAgICAgLy8gVXNpbmcgW15cXFNcXHUwMEEwXSBpbnN0ZWFkIG9mIFxccyBlbnN1cmVzIHRoYXQgd2Ugc3BsaXQgdGhlIHRleHQgb24gYWxsXG4gICAgICAgICAgICAvLyB3aGl0ZXNwYWNlIGV4Y2VwdCBub24tYnJlYWtpbmcgc3BhY2VzIChcXHUwMEEwKS4gV2UgbmVlZCB0byBwcmVzZXJ2ZVxuICAgICAgICAgICAgLy8gdGhlbSBpbiB0aGUgc3BsaXQgcHJvY2VzcyB0byBlbnN1cmUgY29ycmVjdCB3b3JkIHNlcGFyYXRpb24gYW5kIHdpZHRoXG4gICAgICAgICAgICAvLyBjYWxjdWxhdGlvbi5cbiAgICAgICAgICAgIHZhciBsb25nZXN0V29yZFdpZHRoID0gZ2V0U3RyaW5nV2lkdGgoY2VsbC50ZXh0LmpvaW4oJyAnKS5zcGxpdCgvW15cXFNcXHUwMEEwXSsvKSwgY2VsbC5zdHlsZXMsIGRvYyk7XG4gICAgICAgICAgICBjZWxsLm1pblJlYWRhYmxlV2lkdGggPSBsb25nZXN0V29yZFdpZHRoICsgY2VsbC5wYWRkaW5nKCdob3Jpem9udGFsJyk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGNlbGwuc3R5bGVzLmNlbGxXaWR0aCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBjZWxsLm1pbldpZHRoID0gY2VsbC5zdHlsZXMuY2VsbFdpZHRoO1xuICAgICAgICAgICAgICAgIGNlbGwud3JhcHBlZFdpZHRoID0gY2VsbC5zdHlsZXMuY2VsbFdpZHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2VsbC5zdHlsZXMuY2VsbFdpZHRoID09PSAnd3JhcCcgfHxcbiAgICAgICAgICAgICAgICBob3Jpem9udGFsUGFnZUJyZWFrID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgLy8gY2VsbCB3aWR0aCBzaG91bGQgbm90IGJlIG1vcmUgdGhhbiBhdmFpbGFibGUgcGFnZSB3aWR0aFxuICAgICAgICAgICAgICAgIGlmIChjZWxsLmNvbnRlbnRXaWR0aCA+IGF2YWlsYWJsZVBhZ2VXaWR0aCkge1xuICAgICAgICAgICAgICAgICAgICBjZWxsLm1pbldpZHRoID0gYXZhaWxhYmxlUGFnZVdpZHRoO1xuICAgICAgICAgICAgICAgICAgICBjZWxsLndyYXBwZWRXaWR0aCA9IGF2YWlsYWJsZVBhZ2VXaWR0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNlbGwubWluV2lkdGggPSBjZWxsLmNvbnRlbnRXaWR0aDtcbiAgICAgICAgICAgICAgICAgICAgY2VsbC53cmFwcGVkV2lkdGggPSBjZWxsLmNvbnRlbnRXaWR0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBhdXRvXG4gICAgICAgICAgICAgICAgdmFyIGRlZmF1bHRNaW5XaWR0aCA9IDEwIC8gc2Y7XG4gICAgICAgICAgICAgICAgY2VsbC5taW5XaWR0aCA9IGNlbGwuc3R5bGVzLm1pbkNlbGxXaWR0aCB8fCBkZWZhdWx0TWluV2lkdGg7XG4gICAgICAgICAgICAgICAgY2VsbC53cmFwcGVkV2lkdGggPSBjZWxsLmNvbnRlbnRXaWR0aDtcbiAgICAgICAgICAgICAgICBpZiAoY2VsbC5taW5XaWR0aCA+IGNlbGwud3JhcHBlZFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNlbGwud3JhcHBlZFdpZHRoID0gY2VsbC5taW5XaWR0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICB0YWJsZS5hbGxSb3dzKCkuZm9yRWFjaChmdW5jdGlvbiAocm93KSB7XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0YWJsZS5jb2x1bW5zOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgdmFyIGNvbHVtbiA9IF9hW19pXTtcbiAgICAgICAgICAgIHZhciBjZWxsID0gcm93LmNlbGxzW2NvbHVtbi5pbmRleF07XG4gICAgICAgICAgICAvLyBGb3Igbm93IHdlIGlnbm9yZSB0aGUgbWluV2lkdGggYW5kIHdyYXBwZWRXaWR0aCBvZiBjb2xzcGFuIGNlbGxzIHdoZW4gY2FsY3VsYXRpbmcgY29sc3BhbiB3aWR0aHMuXG4gICAgICAgICAgICAvLyBDb3VsZCBwcm9iYWJseSBiZSBpbXByb3ZlZCB1cG9uIGhvd2V2ZXIuXG4gICAgICAgICAgICBpZiAoY2VsbCAmJiBjZWxsLmNvbFNwYW4gPT09IDEpIHtcbiAgICAgICAgICAgICAgICBjb2x1bW4ud3JhcHBlZFdpZHRoID0gTWF0aC5tYXgoY29sdW1uLndyYXBwZWRXaWR0aCwgY2VsbC53cmFwcGVkV2lkdGgpO1xuICAgICAgICAgICAgICAgIGNvbHVtbi5taW5XaWR0aCA9IE1hdGgubWF4KGNvbHVtbi5taW5XaWR0aCwgY2VsbC5taW5XaWR0aCk7XG4gICAgICAgICAgICAgICAgY29sdW1uLm1pblJlYWRhYmxlV2lkdGggPSBNYXRoLm1heChjb2x1bW4ubWluUmVhZGFibGVXaWR0aCwgY2VsbC5taW5SZWFkYWJsZVdpZHRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJlc3BlY3QgY2VsbFdpZHRoIHNldCBpbiBjb2x1bW5TdHlsZXMgZXZlbiBpZiB0aGVyZSBpcyBubyBjZWxscyBmb3IgdGhpcyBjb2x1bW5cbiAgICAgICAgICAgICAgICAvLyBvciBpZiB0aGUgY29sdW1uIG9ubHkgaGF2ZSBjb2xzcGFuIGNlbGxzLiBTaW5jZSB0aGUgd2lkdGggb2YgY29sc3BhbiBjZWxsc1xuICAgICAgICAgICAgICAgIC8vIGRvZXMgbm90IGFmZmVjdCB0aGUgd2lkdGggb2YgY29sdW1ucywgc2V0dGluZyBjb2x1bW5TdHlsZXMgY2VsbFdpZHRoIGVuYWJsZXMgdGhlXG4gICAgICAgICAgICAgICAgLy8gdXNlciB0byBhdCBsZWFzdCBkbyBpdCBtYW51YWxseS5cbiAgICAgICAgICAgICAgICAvLyBOb3RlIHRoYXQgdGhpcyBpcyBub3QgcGVyZmVjdCBmb3Igbm93IHNpbmNlIGZvciBleGFtcGxlIHJvdyBhbmQgdGFibGUgc3R5bGVzIGFyZVxuICAgICAgICAgICAgICAgIC8vIG5vdCBhY2NvdW50ZWQgZm9yXG4gICAgICAgICAgICAgICAgdmFyIGNvbHVtblN0eWxlcyA9IHRhYmxlLnN0eWxlcy5jb2x1bW5TdHlsZXNbY29sdW1uLmRhdGFLZXldIHx8XG4gICAgICAgICAgICAgICAgICAgIHRhYmxlLnN0eWxlcy5jb2x1bW5TdHlsZXNbY29sdW1uLmluZGV4XSB8fFxuICAgICAgICAgICAgICAgICAgICB7fTtcbiAgICAgICAgICAgICAgICB2YXIgY2VsbFdpZHRoID0gY29sdW1uU3R5bGVzLmNlbGxXaWR0aCB8fCBjb2x1bW5TdHlsZXMubWluQ2VsbFdpZHRoO1xuICAgICAgICAgICAgICAgIGlmIChjZWxsV2lkdGggJiYgdHlwZW9mIGNlbGxXaWR0aCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uLm1pbldpZHRoID0gY2VsbFdpZHRoO1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW4ud3JhcHBlZFdpZHRoID0gY2VsbFdpZHRoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjZWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIGFsbCBjb2x1bW5zIGdldCBhdCBsZWFzdCBtaW4gd2lkdGggZXZlbiB0aG91Z2ggd2lkdGggY2FsY3VsYXRpb25zIGFyZSBub3QgYmFzZWQgb24gdGhlbVxuICAgICAgICAgICAgICAgIGlmIChjZWxsLmNvbFNwYW4gPiAxICYmICFjb2x1bW4ubWluV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uLm1pbldpZHRoID0gY2VsbC5taW5XaWR0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNlbGwuY29sU3BhbiA+IDEgJiYgIWNvbHVtbi53cmFwcGVkV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29sdW1uLndyYXBwZWRXaWR0aCA9IGNlbGwubWluV2lkdGg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59XG4vKipcbiAqIERpc3RyaWJ1dGUgcmVzaXplV2lkdGggb24gcGFzc2VkIHJlc2l6YWJsZSBjb2x1bW5zXG4gKi9cbmZ1bmN0aW9uIHJlc2l6ZUNvbHVtbnMoY29sdW1ucywgcmVzaXplV2lkdGgsIGdldE1pbldpZHRoKSB7XG4gICAgdmFyIGluaXRpYWxSZXNpemVXaWR0aCA9IHJlc2l6ZVdpZHRoO1xuICAgIHZhciBzdW1XcmFwcGVkV2lkdGggPSBjb2x1bW5zLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBjb2x1bW4pIHsgcmV0dXJuIGFjYyArIGNvbHVtbi53cmFwcGVkV2lkdGg7IH0sIDApO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29sdW1ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY29sdW1uID0gY29sdW1uc1tpXTtcbiAgICAgICAgdmFyIHJhdGlvID0gY29sdW1uLndyYXBwZWRXaWR0aCAvIHN1bVdyYXBwZWRXaWR0aDtcbiAgICAgICAgdmFyIHN1Z2dlc3RlZENoYW5nZSA9IGluaXRpYWxSZXNpemVXaWR0aCAqIHJhdGlvO1xuICAgICAgICB2YXIgc3VnZ2VzdGVkV2lkdGggPSBjb2x1bW4ud2lkdGggKyBzdWdnZXN0ZWRDaGFuZ2U7XG4gICAgICAgIHZhciBtaW5XaWR0aCA9IGdldE1pbldpZHRoKGNvbHVtbik7XG4gICAgICAgIHZhciBuZXdXaWR0aCA9IHN1Z2dlc3RlZFdpZHRoIDwgbWluV2lkdGggPyBtaW5XaWR0aCA6IHN1Z2dlc3RlZFdpZHRoO1xuICAgICAgICByZXNpemVXaWR0aCAtPSBuZXdXaWR0aCAtIGNvbHVtbi53aWR0aDtcbiAgICAgICAgY29sdW1uLndpZHRoID0gbmV3V2lkdGg7XG4gICAgfVxuICAgIHJlc2l6ZVdpZHRoID0gTWF0aC5yb3VuZChyZXNpemVXaWR0aCAqIDFlMTApIC8gMWUxMDtcbiAgICAvLyBSdW4gdGhlIHJlc2l6ZXIgYWdhaW4gaWYgdGhlcmUncyByZW1haW5pbmcgd2lkdGggbmVlZHNcbiAgICAvLyB0byBiZSBkaXN0cmlidXRlZCBhbmQgdGhlcmUncmUgY29sdW1ucyB0aGF0IGNhbiBiZSByZXNpemVkXG4gICAgaWYgKHJlc2l6ZVdpZHRoKSB7XG4gICAgICAgIHZhciByZXNpemFibGVDb2x1bW5zID0gY29sdW1ucy5maWx0ZXIoZnVuY3Rpb24gKGNvbHVtbikge1xuICAgICAgICAgICAgcmV0dXJuIHJlc2l6ZVdpZHRoIDwgMFxuICAgICAgICAgICAgICAgID8gY29sdW1uLndpZHRoID4gZ2V0TWluV2lkdGgoY29sdW1uKSAvLyBjaGVjayBpZiBjb2x1bW4gY2FuIHNocmlua1xuICAgICAgICAgICAgICAgIDogdHJ1ZTsgLy8gY2hlY2sgaWYgY29sdW1uIGNhbiBncm93XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzaXphYmxlQ29sdW1ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJlc2l6ZVdpZHRoID0gcmVzaXplQ29sdW1ucyhyZXNpemFibGVDb2x1bW5zLCByZXNpemVXaWR0aCwgZ2V0TWluV2lkdGgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNpemVXaWR0aDtcbn1cbmZ1bmN0aW9uIGFwcGx5Um93U3BhbnModGFibGUpIHtcbiAgICB2YXIgcm93U3BhbkNlbGxzID0ge307XG4gICAgdmFyIGNvbFJvd1NwYW5zTGVmdCA9IDE7XG4gICAgdmFyIGFsbCA9IHRhYmxlLmFsbFJvd3MoKTtcbiAgICBmb3IgKHZhciByb3dJbmRleCA9IDA7IHJvd0luZGV4IDwgYWxsLmxlbmd0aDsgcm93SW5kZXgrKykge1xuICAgICAgICB2YXIgcm93ID0gYWxsW3Jvd0luZGV4XTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRhYmxlLmNvbHVtbnM7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgY29sdW1uID0gX2FbX2ldO1xuICAgICAgICAgICAgdmFyIGRhdGEgPSByb3dTcGFuQ2VsbHNbY29sdW1uLmluZGV4XTtcbiAgICAgICAgICAgIGlmIChjb2xSb3dTcGFuc0xlZnQgPiAxKSB7XG4gICAgICAgICAgICAgICAgY29sUm93U3BhbnNMZWZ0LS07XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJvdy5jZWxsc1tjb2x1bW4uaW5kZXhdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIGRhdGEuY2VsbC5oZWlnaHQgKz0gcm93LmhlaWdodDtcbiAgICAgICAgICAgICAgICBjb2xSb3dTcGFuc0xlZnQgPSBkYXRhLmNlbGwuY29sU3BhbjtcbiAgICAgICAgICAgICAgICBkZWxldGUgcm93LmNlbGxzW2NvbHVtbi5pbmRleF07XG4gICAgICAgICAgICAgICAgZGF0YS5sZWZ0LS07XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEubGVmdCA8PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByb3dTcGFuQ2VsbHNbY29sdW1uLmluZGV4XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgY2VsbCA9IHJvdy5jZWxsc1tjb2x1bW4uaW5kZXhdO1xuICAgICAgICAgICAgICAgIGlmICghY2VsbCkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2VsbC5oZWlnaHQgPSByb3cuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIGlmIChjZWxsLnJvd1NwYW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZW1haW5pbmcgPSBhbGwubGVuZ3RoIC0gcm93SW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsZWZ0ID0gY2VsbC5yb3dTcGFuID4gcmVtYWluaW5nID8gcmVtYWluaW5nIDogY2VsbC5yb3dTcGFuO1xuICAgICAgICAgICAgICAgICAgICByb3dTcGFuQ2VsbHNbY29sdW1uLmluZGV4XSA9IHsgY2VsbDogY2VsbCwgbGVmdDogbGVmdCwgcm93OiByb3cgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBhcHBseUNvbFNwYW5zKHRhYmxlKSB7XG4gICAgdmFyIGFsbCA9IHRhYmxlLmFsbFJvd3MoKTtcbiAgICBmb3IgKHZhciByb3dJbmRleCA9IDA7IHJvd0luZGV4IDwgYWxsLmxlbmd0aDsgcm93SW5kZXgrKykge1xuICAgICAgICB2YXIgcm93ID0gYWxsW3Jvd0luZGV4XTtcbiAgICAgICAgdmFyIGNvbFNwYW5DZWxsID0gbnVsbDtcbiAgICAgICAgdmFyIGNvbWJpbmVkQ29sU3BhbldpZHRoID0gMDtcbiAgICAgICAgdmFyIGNvbFNwYW5zTGVmdCA9IDA7XG4gICAgICAgIGZvciAodmFyIGNvbHVtbkluZGV4ID0gMDsgY29sdW1uSW5kZXggPCB0YWJsZS5jb2x1bW5zLmxlbmd0aDsgY29sdW1uSW5kZXgrKykge1xuICAgICAgICAgICAgdmFyIGNvbHVtbiA9IHRhYmxlLmNvbHVtbnNbY29sdW1uSW5kZXhdO1xuICAgICAgICAgICAgLy8gV2lkdGggYW5kIGNvbHNwYW5cbiAgICAgICAgICAgIGNvbFNwYW5zTGVmdCAtPSAxO1xuICAgICAgICAgICAgaWYgKGNvbFNwYW5zTGVmdCA+IDEgJiYgdGFibGUuY29sdW1uc1tjb2x1bW5JbmRleCArIDFdKSB7XG4gICAgICAgICAgICAgICAgY29tYmluZWRDb2xTcGFuV2lkdGggKz0gY29sdW1uLndpZHRoO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSByb3cuY2VsbHNbY29sdW1uLmluZGV4XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNvbFNwYW5DZWxsKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBjb2xTcGFuQ2VsbDtcbiAgICAgICAgICAgICAgICBkZWxldGUgcm93LmNlbGxzW2NvbHVtbi5pbmRleF07XG4gICAgICAgICAgICAgICAgY29sU3BhbkNlbGwgPSBudWxsO1xuICAgICAgICAgICAgICAgIGNlbGwud2lkdGggPSBjb2x1bW4ud2lkdGggKyBjb21iaW5lZENvbFNwYW5XaWR0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBjZWxsID0gcm93LmNlbGxzW2NvbHVtbi5pbmRleF07XG4gICAgICAgICAgICAgICAgaWYgKCFjZWxsKVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBjb2xTcGFuc0xlZnQgPSBjZWxsLmNvbFNwYW47XG4gICAgICAgICAgICAgICAgY29tYmluZWRDb2xTcGFuV2lkdGggPSAwO1xuICAgICAgICAgICAgICAgIGlmIChjZWxsLmNvbFNwYW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbFNwYW5DZWxsID0gY2VsbDtcbiAgICAgICAgICAgICAgICAgICAgY29tYmluZWRDb2xTcGFuV2lkdGggKz0gY29sdW1uLndpZHRoO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2VsbC53aWR0aCA9IGNvbHVtbi53aWR0aCArIGNvbWJpbmVkQ29sU3BhbldpZHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gZml0Q29udGVudCh0YWJsZSwgZG9jKSB7XG4gICAgdmFyIHJvd1NwYW5IZWlnaHQgPSB7IGNvdW50OiAwLCBoZWlnaHQ6IDAgfTtcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGFibGUuYWxsUm93cygpOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YXIgcm93ID0gX2FbX2ldO1xuICAgICAgICBmb3IgKHZhciBfYiA9IDAsIF9jID0gdGFibGUuY29sdW1uczsgX2IgPCBfYy5sZW5ndGg7IF9iKyspIHtcbiAgICAgICAgICAgIHZhciBjb2x1bW4gPSBfY1tfYl07XG4gICAgICAgICAgICB2YXIgY2VsbCA9IHJvdy5jZWxsc1tjb2x1bW4uaW5kZXhdO1xuICAgICAgICAgICAgaWYgKCFjZWxsKVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgZG9jLmFwcGx5U3R5bGVzKGNlbGwuc3R5bGVzLCB0cnVlKTtcbiAgICAgICAgICAgIHZhciB0ZXh0U3BhY2UgPSBjZWxsLndpZHRoIC0gY2VsbC5wYWRkaW5nKCdob3Jpem9udGFsJyk7XG4gICAgICAgICAgICBpZiAoY2VsbC5zdHlsZXMub3ZlcmZsb3cgPT09ICdsaW5lYnJlYWsnKSB7XG4gICAgICAgICAgICAgICAgLy8gQWRkIG9uZSBwdCB0byB0ZXh0U3BhY2UgdG8gZml4IHJvdW5kaW5nIGVycm9yXG4gICAgICAgICAgICAgICAgY2VsbC50ZXh0ID0gZG9jLnNwbGl0VGV4dFRvU2l6ZShjZWxsLnRleHQsIHRleHRTcGFjZSArIDEgLyBkb2Muc2NhbGVGYWN0b3IoKSwgeyBmb250U2l6ZTogY2VsbC5zdHlsZXMuZm9udFNpemUgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjZWxsLnN0eWxlcy5vdmVyZmxvdyA9PT0gJ2VsbGlwc2l6ZScpIHtcbiAgICAgICAgICAgICAgICBjZWxsLnRleHQgPSBlbGxpcHNpemUoY2VsbC50ZXh0LCB0ZXh0U3BhY2UsIGNlbGwuc3R5bGVzLCBkb2MsICcuLi4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNlbGwuc3R5bGVzLm92ZXJmbG93ID09PSAnaGlkZGVuJykge1xuICAgICAgICAgICAgICAgIGNlbGwudGV4dCA9IGVsbGlwc2l6ZShjZWxsLnRleHQsIHRleHRTcGFjZSwgY2VsbC5zdHlsZXMsIGRvYywgJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIGNlbGwuc3R5bGVzLm92ZXJmbG93ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGNlbGwuc3R5bGVzLm92ZXJmbG93KGNlbGwudGV4dCwgdGV4dFNwYWNlKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgY2VsbC50ZXh0ID0gW3Jlc3VsdF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjZWxsLnRleHQgPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2VsbC5jb250ZW50SGVpZ2h0ID0gY2VsbC5nZXRDb250ZW50SGVpZ2h0KGRvYy5zY2FsZUZhY3RvcigpLCBkb2MuZ2V0TGluZUhlaWdodEZhY3RvcigpKTtcbiAgICAgICAgICAgIHZhciByZWFsQ29udGVudEhlaWdodCA9IGNlbGwuY29udGVudEhlaWdodCAvIGNlbGwucm93U3BhbjtcbiAgICAgICAgICAgIGlmIChjZWxsLnJvd1NwYW4gPiAxICYmXG4gICAgICAgICAgICAgICAgcm93U3BhbkhlaWdodC5jb3VudCAqIHJvd1NwYW5IZWlnaHQuaGVpZ2h0IDxcbiAgICAgICAgICAgICAgICAgICAgcmVhbENvbnRlbnRIZWlnaHQgKiBjZWxsLnJvd1NwYW4pIHtcbiAgICAgICAgICAgICAgICByb3dTcGFuSGVpZ2h0ID0geyBoZWlnaHQ6IHJlYWxDb250ZW50SGVpZ2h0LCBjb3VudDogY2VsbC5yb3dTcGFuIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChyb3dTcGFuSGVpZ2h0ICYmIHJvd1NwYW5IZWlnaHQuY291bnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJvd1NwYW5IZWlnaHQuaGVpZ2h0ID4gcmVhbENvbnRlbnRIZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVhbENvbnRlbnRIZWlnaHQgPSByb3dTcGFuSGVpZ2h0LmhlaWdodDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVhbENvbnRlbnRIZWlnaHQgPiByb3cuaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcm93LmhlaWdodCA9IHJlYWxDb250ZW50SGVpZ2h0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJvd1NwYW5IZWlnaHQuY291bnQtLTtcbiAgICB9XG59XG5mdW5jdGlvbiBlbGxpcHNpemUodGV4dCwgd2lkdGgsIHN0eWxlcywgZG9jLCBvdmVyZmxvdykge1xuICAgIHJldHVybiB0ZXh0Lm1hcChmdW5jdGlvbiAoc3RyKSB7IHJldHVybiBlbGxpcHNpemVTdHIoc3RyLCB3aWR0aCwgc3R5bGVzLCBkb2MsIG92ZXJmbG93KTsgfSk7XG59XG5mdW5jdGlvbiBlbGxpcHNpemVTdHIodGV4dCwgd2lkdGgsIHN0eWxlcywgZG9jLCBvdmVyZmxvdykge1xuICAgIHZhciBwcmVjaXNpb24gPSAxMDAwMCAqIGRvYy5zY2FsZUZhY3RvcigpO1xuICAgIHdpZHRoID0gTWF0aC5jZWlsKHdpZHRoICogcHJlY2lzaW9uKSAvIHByZWNpc2lvbjtcbiAgICBpZiAod2lkdGggPj0gZ2V0U3RyaW5nV2lkdGgodGV4dCwgc3R5bGVzLCBkb2MpKSB7XG4gICAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cbiAgICB3aGlsZSAod2lkdGggPCBnZXRTdHJpbmdXaWR0aCh0ZXh0ICsgb3ZlcmZsb3csIHN0eWxlcywgZG9jKSkge1xuICAgICAgICBpZiAodGV4dC5sZW5ndGggPD0gMSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdGV4dCA9IHRleHQuc3Vic3RyaW5nKDAsIHRleHQubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIHJldHVybiB0ZXh0LnRyaW0oKSArIG92ZXJmbG93O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUYWJsZShqc1BERkRvYywgaW5wdXQpIHtcbiAgICB2YXIgZG9jID0gbmV3IERvY0hhbmRsZXIoanNQREZEb2MpO1xuICAgIHZhciBjb250ZW50ID0gcGFyc2VDb250ZW50KGlucHV0LCBkb2Muc2NhbGVGYWN0b3IoKSk7XG4gICAgdmFyIHRhYmxlID0gbmV3IFRhYmxlKGlucHV0LCBjb250ZW50KTtcbiAgICBjYWxjdWxhdGVXaWR0aHMoZG9jLCB0YWJsZSk7XG4gICAgZG9jLmFwcGx5U3R5bGVzKGRvYy51c2VyU3R5bGVzKTtcbiAgICByZXR1cm4gdGFibGU7XG59XG5mdW5jdGlvbiBwYXJzZUNvbnRlbnQoaW5wdXQsIHNmKSB7XG4gICAgdmFyIGNvbnRlbnQgPSBpbnB1dC5jb250ZW50O1xuICAgIHZhciBjb2x1bW5zID0gY3JlYXRlQ29sdW1ucyhjb250ZW50LmNvbHVtbnMpO1xuICAgIC8vIElmIG5vIGhlYWQgb3IgZm9vdCBpcyBzZXQsIHRyeSBnZW5lcmF0aW5nIGl0IHdpdGggY29udGVudCBmcm9tIGNvbHVtbnNcbiAgICBpZiAoY29udGVudC5oZWFkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIgc2VjdGlvblJvdyA9IGdlbmVyYXRlU2VjdGlvblJvdyhjb2x1bW5zLCAnaGVhZCcpO1xuICAgICAgICBpZiAoc2VjdGlvblJvdylcbiAgICAgICAgICAgIGNvbnRlbnQuaGVhZC5wdXNoKHNlY3Rpb25Sb3cpO1xuICAgIH1cbiAgICBpZiAoY29udGVudC5mb290Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIgc2VjdGlvblJvdyA9IGdlbmVyYXRlU2VjdGlvblJvdyhjb2x1bW5zLCAnZm9vdCcpO1xuICAgICAgICBpZiAoc2VjdGlvblJvdylcbiAgICAgICAgICAgIGNvbnRlbnQuZm9vdC5wdXNoKHNlY3Rpb25Sb3cpO1xuICAgIH1cbiAgICB2YXIgdGhlbWUgPSBpbnB1dC5zZXR0aW5ncy50aGVtZTtcbiAgICB2YXIgc3R5bGVzID0gaW5wdXQuc3R5bGVzO1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvbHVtbnM6IGNvbHVtbnMsXG4gICAgICAgIGhlYWQ6IHBhcnNlU2VjdGlvbignaGVhZCcsIGNvbnRlbnQuaGVhZCwgY29sdW1ucywgc3R5bGVzLCB0aGVtZSwgc2YpLFxuICAgICAgICBib2R5OiBwYXJzZVNlY3Rpb24oJ2JvZHknLCBjb250ZW50LmJvZHksIGNvbHVtbnMsIHN0eWxlcywgdGhlbWUsIHNmKSxcbiAgICAgICAgZm9vdDogcGFyc2VTZWN0aW9uKCdmb290JywgY29udGVudC5mb290LCBjb2x1bW5zLCBzdHlsZXMsIHRoZW1lLCBzZiksXG4gICAgfTtcbn1cbmZ1bmN0aW9uIHBhcnNlU2VjdGlvbihzZWN0aW9uTmFtZSwgc2VjdGlvblJvd3MsIGNvbHVtbnMsIHN0eWxlUHJvcHMsIHRoZW1lLCBzY2FsZUZhY3Rvcikge1xuICAgIHZhciByb3dTcGFuc0xlZnRGb3JDb2x1bW4gPSB7fTtcbiAgICB2YXIgcmVzdWx0ID0gc2VjdGlvblJvd3MubWFwKGZ1bmN0aW9uIChyYXdSb3csIHJvd0luZGV4KSB7XG4gICAgICAgIHZhciBza2lwcGVkUm93Rm9yUm93U3BhbnMgPSAwO1xuICAgICAgICB2YXIgY2VsbHMgPSB7fTtcbiAgICAgICAgdmFyIGNvbFNwYW5zQWRkZWQgPSAwO1xuICAgICAgICB2YXIgY29sdW1uU3BhbnNMZWZ0ID0gMDtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBjb2x1bW5zXzEgPSBjb2x1bW5zOyBfaSA8IGNvbHVtbnNfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciBjb2x1bW4gPSBjb2x1bW5zXzFbX2ldO1xuICAgICAgICAgICAgaWYgKHJvd1NwYW5zTGVmdEZvckNvbHVtbltjb2x1bW4uaW5kZXhdID09IG51bGwgfHxcbiAgICAgICAgICAgICAgICByb3dTcGFuc0xlZnRGb3JDb2x1bW5bY29sdW1uLmluZGV4XS5sZWZ0ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbHVtblNwYW5zTGVmdCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmF3Q2VsbCA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmF3Um93KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmF3Q2VsbCA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3Um93W2NvbHVtbi5pbmRleCAtIGNvbFNwYW5zQWRkZWQgLSBza2lwcGVkUm93Rm9yUm93U3BhbnNdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmF3Q2VsbCA9IHJhd1Jvd1tjb2x1bW4uZGF0YUtleV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGxJbnB1dFN0eWxlcyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJhd0NlbGwgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHJhd0NlbGwpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjZWxsSW5wdXRTdHlsZXMgPSAocmF3Q2VsbCA9PT0gbnVsbCB8fCByYXdDZWxsID09PSB2b2lkIDAgPyB2b2lkIDAgOiByYXdDZWxsLnN0eWxlcykgfHwge307XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0eWxlcyA9IGNlbGxTdHlsZXMoc2VjdGlvbk5hbWUsIGNvbHVtbiwgcm93SW5kZXgsIHRoZW1lLCBzdHlsZVByb3BzLCBzY2FsZUZhY3RvciwgY2VsbElucHV0U3R5bGVzKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGwgPSBuZXcgQ2VsbChyYXdDZWxsLCBzdHlsZXMsIHNlY3Rpb25OYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gZGF0YUtleSBpcyBub3QgdXNlZCBpbnRlcm5hbGx5IG5vIG1vcmUgYnV0IGtlZXAgZm9yXG4gICAgICAgICAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgaW4gaG9va3NcbiAgICAgICAgICAgICAgICAgICAgY2VsbHNbY29sdW1uLmRhdGFLZXldID0gY2VsbDtcbiAgICAgICAgICAgICAgICAgICAgY2VsbHNbY29sdW1uLmluZGV4XSA9IGNlbGw7XG4gICAgICAgICAgICAgICAgICAgIGNvbHVtblNwYW5zTGVmdCA9IGNlbGwuY29sU3BhbiAtIDE7XG4gICAgICAgICAgICAgICAgICAgIHJvd1NwYW5zTGVmdEZvckNvbHVtbltjb2x1bW4uaW5kZXhdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdDogY2VsbC5yb3dTcGFuIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVzOiBjb2x1bW5TcGFuc0xlZnQsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW5TcGFuc0xlZnQtLTtcbiAgICAgICAgICAgICAgICAgICAgY29sU3BhbnNBZGRlZCsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJvd1NwYW5zTGVmdEZvckNvbHVtbltjb2x1bW4uaW5kZXhdLmxlZnQtLTtcbiAgICAgICAgICAgICAgICBjb2x1bW5TcGFuc0xlZnQgPSByb3dTcGFuc0xlZnRGb3JDb2x1bW5bY29sdW1uLmluZGV4XS50aW1lcztcbiAgICAgICAgICAgICAgICBza2lwcGVkUm93Rm9yUm93U3BhbnMrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFJvdyhyYXdSb3csIHJvd0luZGV4LCBzZWN0aW9uTmFtZSwgY2VsbHMpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBnZW5lcmF0ZVNlY3Rpb25Sb3coY29sdW1ucywgc2VjdGlvbikge1xuICAgIHZhciBzZWN0aW9uUm93ID0ge307XG4gICAgY29sdW1ucy5mb3JFYWNoKGZ1bmN0aW9uIChjb2wpIHtcbiAgICAgICAgaWYgKGNvbC5yYXcgIT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIHRpdGxlID0gZ2V0U2VjdGlvblRpdGxlKHNlY3Rpb24sIGNvbC5yYXcpO1xuICAgICAgICAgICAgaWYgKHRpdGxlICE9IG51bGwpXG4gICAgICAgICAgICAgICAgc2VjdGlvblJvd1tjb2wuZGF0YUtleV0gPSB0aXRsZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhzZWN0aW9uUm93KS5sZW5ndGggPiAwID8gc2VjdGlvblJvdyA6IG51bGw7XG59XG5mdW5jdGlvbiBnZXRTZWN0aW9uVGl0bGUoc2VjdGlvbiwgY29sdW1uKSB7XG4gICAgaWYgKHNlY3Rpb24gPT09ICdoZWFkJykge1xuICAgICAgICBpZiAodHlwZW9mIGNvbHVtbiA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBjb2x1bW4uaGVhZGVyIHx8IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGNvbHVtbiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIGNvbHVtbiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHJldHVybiBjb2x1bW47XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAoc2VjdGlvbiA9PT0gJ2Zvb3QnICYmIHR5cGVvZiBjb2x1bW4gPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBjb2x1bW4uZm9vdGVyO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUNvbHVtbnMoY29sdW1ucykge1xuICAgIHJldHVybiBjb2x1bW5zLm1hcChmdW5jdGlvbiAoaW5wdXQsIGluZGV4KSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGtleSA9IChfYSA9IGlucHV0LmRhdGFLZXkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IGluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAga2V5ID0gaW5kZXg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBDb2x1bW4oa2V5LCBpbnB1dCwgaW5kZXgpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gY2VsbFN0eWxlcyhzZWN0aW9uTmFtZSwgY29sdW1uLCByb3dJbmRleCwgdGhlbWVOYW1lLCBzdHlsZXMsIHNjYWxlRmFjdG9yLCBjZWxsSW5wdXRTdHlsZXMpIHtcbiAgICB2YXIgdGhlbWUgPSBnZXRUaGVtZSh0aGVtZU5hbWUpO1xuICAgIHZhciBzZWN0aW9uU3R5bGVzO1xuICAgIGlmIChzZWN0aW9uTmFtZSA9PT0gJ2hlYWQnKSB7XG4gICAgICAgIHNlY3Rpb25TdHlsZXMgPSBzdHlsZXMuaGVhZFN0eWxlcztcbiAgICB9XG4gICAgZWxzZSBpZiAoc2VjdGlvbk5hbWUgPT09ICdib2R5Jykge1xuICAgICAgICBzZWN0aW9uU3R5bGVzID0gc3R5bGVzLmJvZHlTdHlsZXM7XG4gICAgfVxuICAgIGVsc2UgaWYgKHNlY3Rpb25OYW1lID09PSAnZm9vdCcpIHtcbiAgICAgICAgc2VjdGlvblN0eWxlcyA9IHN0eWxlcy5mb290U3R5bGVzO1xuICAgIH1cbiAgICB2YXIgb3RoZXJTdHlsZXMgPSBhc3NpZ24oe30sIHRoZW1lLnRhYmxlLCB0aGVtZVtzZWN0aW9uTmFtZV0sIHN0eWxlcy5zdHlsZXMsIHNlY3Rpb25TdHlsZXMpO1xuICAgIHZhciBjb2x1bW5TdHlsZXMgPSBzdHlsZXMuY29sdW1uU3R5bGVzW2NvbHVtbi5kYXRhS2V5XSB8fFxuICAgICAgICBzdHlsZXMuY29sdW1uU3R5bGVzW2NvbHVtbi5pbmRleF0gfHxcbiAgICAgICAge307XG4gICAgdmFyIGNvbFN0eWxlcyA9IHNlY3Rpb25OYW1lID09PSAnYm9keScgPyBjb2x1bW5TdHlsZXMgOiB7fTtcbiAgICB2YXIgcm93U3R5bGVzID0gc2VjdGlvbk5hbWUgPT09ICdib2R5JyAmJiByb3dJbmRleCAlIDIgPT09IDBcbiAgICAgICAgPyBhc3NpZ24oe30sIHRoZW1lLmFsdGVybmF0ZVJvdywgc3R5bGVzLmFsdGVybmF0ZVJvd1N0eWxlcylcbiAgICAgICAgOiB7fTtcbiAgICB2YXIgZGVmYXVsdFN0eWxlID0gZGVmYXVsdFN0eWxlcyhzY2FsZUZhY3Rvcik7XG4gICAgdmFyIHRoZW1lU3R5bGVzID0gYXNzaWduKHt9LCBkZWZhdWx0U3R5bGUsIG90aGVyU3R5bGVzLCByb3dTdHlsZXMsIGNvbFN0eWxlcyk7XG4gICAgcmV0dXJuIGFzc2lnbih0aGVtZVN0eWxlcywgY2VsbElucHV0U3R5bGVzKTtcbn1cblxuLy8gZ2V0IGNvbHVtbnMgY2FuIGJlIGZpdCBpbnRvIHBhZ2VcbmZ1bmN0aW9uIGdldENvbHVtbnNDYW5GaXRJblBhZ2UoZG9jLCB0YWJsZSwgY29uZmlnKSB7XG4gICAgdmFyIF9hO1xuICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxuICAgIC8vIEdldCBwYWdlIHdpZHRoXG4gICAgdmFyIHJlbWFpbmluZ1dpZHRoID0gZ2V0UGFnZUF2YWlsYWJsZVdpZHRoKGRvYywgdGFibGUpO1xuICAgIC8vIEdldCBjb2x1bW4gZGF0YSBrZXkgdG8gcmVwZWF0XG4gICAgdmFyIHJlcGVhdENvbHVtbnNNYXAgPSBuZXcgTWFwKCk7XG4gICAgdmFyIGNvbEluZGV4ZXMgPSBbXTtcbiAgICB2YXIgY29sdW1ucyA9IFtdO1xuICAgIHZhciBob3Jpem9udGFsUGFnZUJyZWFrUmVwZWF0ID0gW107XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGFibGUuc2V0dGluZ3MuaG9yaXpvbnRhbFBhZ2VCcmVha1JlcGVhdCkpIHtcbiAgICAgICAgaG9yaXpvbnRhbFBhZ2VCcmVha1JlcGVhdCA9IHRhYmxlLnNldHRpbmdzLmhvcml6b250YWxQYWdlQnJlYWtSZXBlYXQ7XG4gICAgICAgIC8vIEl0IGNhbiBiZSBhIHNpbmdsZSB2YWx1ZSBvZiB0eXBlIHN0cmluZyBvciBudW1iZXIgKGV2ZW4gbnVtYmVyOiAwKVxuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgdGFibGUuc2V0dGluZ3MuaG9yaXpvbnRhbFBhZ2VCcmVha1JlcGVhdCA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgdHlwZW9mIHRhYmxlLnNldHRpbmdzLmhvcml6b250YWxQYWdlQnJlYWtSZXBlYXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGhvcml6b250YWxQYWdlQnJlYWtSZXBlYXQgPSBbdGFibGUuc2V0dGluZ3MuaG9yaXpvbnRhbFBhZ2VCcmVha1JlcGVhdF07XG4gICAgfVxuICAgIC8vIENvZGUgdG8gcmVwZWF0IHRoZSBnaXZlbiBjb2x1bW4gaW4gc3BsaXQgcGFnZXNcbiAgICBob3Jpem9udGFsUGFnZUJyZWFrUmVwZWF0LmZvckVhY2goZnVuY3Rpb24gKGZpZWxkKSB7XG4gICAgICAgIHZhciBjb2wgPSB0YWJsZS5jb2x1bW5zLmZpbmQoZnVuY3Rpb24gKGl0ZW0pIHsgcmV0dXJuIGl0ZW0uZGF0YUtleSA9PT0gZmllbGQgfHwgaXRlbS5pbmRleCA9PT0gZmllbGQ7IH0pO1xuICAgICAgICBpZiAoY29sICYmICFyZXBlYXRDb2x1bW5zTWFwLmhhcyhjb2wuaW5kZXgpKSB7XG4gICAgICAgICAgICByZXBlYXRDb2x1bW5zTWFwLnNldChjb2wuaW5kZXgsIHRydWUpO1xuICAgICAgICAgICAgY29sSW5kZXhlcy5wdXNoKGNvbC5pbmRleCk7XG4gICAgICAgICAgICBjb2x1bW5zLnB1c2godGFibGUuY29sdW1uc1tjb2wuaW5kZXhdKTtcbiAgICAgICAgICAgIHJlbWFpbmluZ1dpZHRoIC09IGNvbC53cmFwcGVkV2lkdGg7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICB2YXIgZmlyc3QgPSB0cnVlO1xuICAgIHZhciBpID0gKF9hID0gY29uZmlnID09PSBudWxsIHx8IGNvbmZpZyA9PT0gdm9pZCAwID8gdm9pZCAwIDogY29uZmlnLnN0YXJ0KSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiAwOyAvLyBtYWtlIHN1cmUgY291dGVyIGlzIGluaXRpYXRlZCBvdXRzaWRlIHRoZSBsb29wXG4gICAgd2hpbGUgKGkgPCB0YWJsZS5jb2x1bW5zLmxlbmd0aCkge1xuICAgICAgICAvLyBQcmV2ZW50IGR1cGxpY2F0ZXNcbiAgICAgICAgaWYgKHJlcGVhdENvbHVtbnNNYXAuaGFzKGkpKSB7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY29sV2lkdGggPSB0YWJsZS5jb2x1bW5zW2ldLndyYXBwZWRXaWR0aDtcbiAgICAgICAgLy8gVGFrZSBhdCBsZWFzdCBvbmUgY29sdW1uIGV2ZW4gaWYgaXQgZG9lc24ndCBmaXRcbiAgICAgICAgaWYgKGZpcnN0IHx8IHJlbWFpbmluZ1dpZHRoID49IGNvbFdpZHRoKSB7XG4gICAgICAgICAgICBmaXJzdCA9IGZhbHNlO1xuICAgICAgICAgICAgY29sSW5kZXhlcy5wdXNoKGkpO1xuICAgICAgICAgICAgY29sdW1ucy5wdXNoKHRhYmxlLmNvbHVtbnNbaV0pO1xuICAgICAgICAgICAgcmVtYWluaW5nV2lkdGggLT0gY29sV2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpKys7XG4gICAgfVxuICAgIHJldHVybiB7IGNvbEluZGV4ZXM6IGNvbEluZGV4ZXMsIGNvbHVtbnM6IGNvbHVtbnMsIGxhc3RJbmRleDogaSAtIDEgfTtcbn1cbmZ1bmN0aW9uIGNhbGN1bGF0ZUFsbENvbHVtbnNDYW5GaXRJblBhZ2UoZG9jLCB0YWJsZSkge1xuICAgIHZhciBhbGxSZXN1bHRzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0YWJsZS5jb2x1bW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBnZXRDb2x1bW5zQ2FuRml0SW5QYWdlKGRvYywgdGFibGUsIHsgc3RhcnQ6IGkgfSk7XG4gICAgICAgIGlmIChyZXN1bHQuY29sdW1ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFsbFJlc3VsdHMucHVzaChyZXN1bHQpO1xuICAgICAgICAgICAgaSA9IHJlc3VsdC5sYXN0SW5kZXg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFsbFJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIGRyYXdUYWJsZShqc1BERkRvYywgdGFibGUpIHtcbiAgICB2YXIgc2V0dGluZ3MgPSB0YWJsZS5zZXR0aW5ncztcbiAgICB2YXIgc3RhcnRZID0gc2V0dGluZ3Muc3RhcnRZO1xuICAgIHZhciBtYXJnaW4gPSBzZXR0aW5ncy5tYXJnaW47XG4gICAgdmFyIGN1cnNvciA9IHsgeDogbWFyZ2luLmxlZnQsIHk6IHN0YXJ0WSB9O1xuICAgIHZhciBzZWN0aW9uc0hlaWdodCA9IHRhYmxlLmdldEhlYWRIZWlnaHQodGFibGUuY29sdW1ucykgKyB0YWJsZS5nZXRGb290SGVpZ2h0KHRhYmxlLmNvbHVtbnMpO1xuICAgIHZhciBtaW5UYWJsZUJvdHRvbVBvcyA9IHN0YXJ0WSArIG1hcmdpbi5ib3R0b20gKyBzZWN0aW9uc0hlaWdodDtcbiAgICBpZiAoc2V0dGluZ3MucGFnZUJyZWFrID09PSAnYXZvaWQnKSB7XG4gICAgICAgIHZhciByb3dzID0gdGFibGUuYm9keTtcbiAgICAgICAgdmFyIHRhYmxlSGVpZ2h0ID0gcm93cy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcm93KSB7IHJldHVybiBhY2MgKyByb3cuaGVpZ2h0OyB9LCAwKTtcbiAgICAgICAgbWluVGFibGVCb3R0b21Qb3MgKz0gdGFibGVIZWlnaHQ7XG4gICAgfVxuICAgIHZhciBkb2MgPSBuZXcgRG9jSGFuZGxlcihqc1BERkRvYyk7XG4gICAgaWYgKHNldHRpbmdzLnBhZ2VCcmVhayA9PT0gJ2Fsd2F5cycgfHxcbiAgICAgICAgKHNldHRpbmdzLnN0YXJ0WSAhPSBudWxsICYmIG1pblRhYmxlQm90dG9tUG9zID4gZG9jLnBhZ2VTaXplKCkuaGVpZ2h0KSkge1xuICAgICAgICBuZXh0UGFnZShkb2MpO1xuICAgICAgICBjdXJzb3IueSA9IG1hcmdpbi50b3A7XG4gICAgfVxuICAgIHRhYmxlLmNhbGxXaWxsRHJhd1BhZ2VIb29rcyhkb2MsIGN1cnNvcik7XG4gICAgdmFyIHN0YXJ0UG9zID0gYXNzaWduKHt9LCBjdXJzb3IpO1xuICAgIHRhYmxlLnN0YXJ0UGFnZU51bWJlciA9IGRvYy5wYWdlTnVtYmVyKCk7XG4gICAgaWYgKHNldHRpbmdzLmhvcml6b250YWxQYWdlQnJlYWspIHtcbiAgICAgICAgLy8gbWFuYWdlZCBmbG93IGZvciBzcGxpdCBjb2x1bW5zXG4gICAgICAgIHByaW50VGFibGVXaXRoSG9yaXpvbnRhbFBhZ2VCcmVhayhkb2MsIHRhYmxlLCBzdGFydFBvcywgY3Vyc29yKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIG5vcm1hbCBmbG93XG4gICAgICAgIGRvYy5hcHBseVN0eWxlcyhkb2MudXNlclN0eWxlcyk7XG4gICAgICAgIGlmIChzZXR0aW5ncy5zaG93SGVhZCA9PT0gJ2ZpcnN0UGFnZScgfHxcbiAgICAgICAgICAgIHNldHRpbmdzLnNob3dIZWFkID09PSAnZXZlcnlQYWdlJykge1xuICAgICAgICAgICAgdGFibGUuaGVhZC5mb3JFYWNoKGZ1bmN0aW9uIChyb3cpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJpbnRSb3coZG9jLCB0YWJsZSwgcm93LCBjdXJzb3IsIHRhYmxlLmNvbHVtbnMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZG9jLmFwcGx5U3R5bGVzKGRvYy51c2VyU3R5bGVzKTtcbiAgICAgICAgdGFibGUuYm9keS5mb3JFYWNoKGZ1bmN0aW9uIChyb3csIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgaXNMYXN0Um93ID0gaW5kZXggPT09IHRhYmxlLmJvZHkubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIHByaW50RnVsbFJvdyhkb2MsIHRhYmxlLCByb3csIGlzTGFzdFJvdywgc3RhcnRQb3MsIGN1cnNvciwgdGFibGUuY29sdW1ucyk7XG4gICAgICAgIH0pO1xuICAgICAgICBkb2MuYXBwbHlTdHlsZXMoZG9jLnVzZXJTdHlsZXMpO1xuICAgICAgICBpZiAoc2V0dGluZ3Muc2hvd0Zvb3QgPT09ICdsYXN0UGFnZScgfHwgc2V0dGluZ3Muc2hvd0Zvb3QgPT09ICdldmVyeVBhZ2UnKSB7XG4gICAgICAgICAgICB0YWJsZS5mb290LmZvckVhY2goZnVuY3Rpb24gKHJvdykge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcmludFJvdyhkb2MsIHRhYmxlLCByb3csIGN1cnNvciwgdGFibGUuY29sdW1ucyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRUYWJsZUJvcmRlcihkb2MsIHRhYmxlLCBzdGFydFBvcywgY3Vyc29yKTtcbiAgICB0YWJsZS5jYWxsRW5kUGFnZUhvb2tzKGRvYywgY3Vyc29yKTtcbiAgICB0YWJsZS5maW5hbFkgPSBjdXJzb3IueTtcbiAgICBqc1BERkRvYy5sYXN0QXV0b1RhYmxlID0gdGFibGU7XG4gICAgZG9jLmFwcGx5U3R5bGVzKGRvYy51c2VyU3R5bGVzKTtcbn1cbmZ1bmN0aW9uIHByaW50VGFibGVXaXRoSG9yaXpvbnRhbFBhZ2VCcmVhayhkb2MsIHRhYmxlLCBzdGFydFBvcywgY3Vyc29yKSB7XG4gICAgLy8gY2FsY3VsYXRlIHdpZHRoIG9mIGNvbHVtbnMgYW5kIHJlbmRlciBvbmx5IHRob3NlIHdoaWNoIGNhbiBmaXQgaW50byBwYWdlXG4gICAgdmFyIGFsbENvbHVtbnNDYW5GaXRSZXN1bHQgPSBjYWxjdWxhdGVBbGxDb2x1bW5zQ2FuRml0SW5QYWdlKGRvYywgdGFibGUpO1xuICAgIHZhciBzZXR0aW5ncyA9IHRhYmxlLnNldHRpbmdzO1xuICAgIGlmIChzZXR0aW5ncy5ob3Jpem9udGFsUGFnZUJyZWFrQmVoYXZpb3VyID09PSAnYWZ0ZXJBbGxSb3dzJykge1xuICAgICAgICBhbGxDb2x1bW5zQ2FuRml0UmVzdWx0LmZvckVhY2goZnVuY3Rpb24gKGNvbHNBbmRJbmRleGVzLCBpbmRleCkge1xuICAgICAgICAgICAgZG9jLmFwcGx5U3R5bGVzKGRvYy51c2VyU3R5bGVzKTtcbiAgICAgICAgICAgIC8vIGFkZCBwYWdlIHRvIHByaW50IG5leHQgY29sdW1ucyBpbiBuZXcgcGFnZVxuICAgICAgICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICAgICAgICAgIC8vIFdoZW4gYWRkaW5nIGEgcGFnZSBoZXJlLCBtYWtlIHN1cmUgbm90IHRvIHByaW50IHRoZSBmb290ZXJzXG4gICAgICAgICAgICAgICAgLy8gYmVjYXVzZSB0aGV5IHdlcmUgYWxyZWFkeSBwcmludGVkIGJlZm9yZSBvbiB0aGlzIHNhbWUgbG9vcFxuICAgICAgICAgICAgICAgIGFkZFBhZ2UoZG9jLCB0YWJsZSwgc3RhcnRQb3MsIGN1cnNvciwgY29sc0FuZEluZGV4ZXMuY29sdW1ucywgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBwcmludCBoZWFkIGZvciBzZWxlY3RlZCBjb2x1bW5zXG4gICAgICAgICAgICAgICAgcHJpbnRIZWFkKGRvYywgdGFibGUsIGN1cnNvciwgY29sc0FuZEluZGV4ZXMuY29sdW1ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBwcmludCBib2R5ICYgZm9vdGVyIGZvciBzZWxlY3RlZCBjb2x1bW5zXG4gICAgICAgICAgICBwcmludEJvZHkoZG9jLCB0YWJsZSwgc3RhcnRQb3MsIGN1cnNvciwgY29sc0FuZEluZGV4ZXMuY29sdW1ucyk7XG4gICAgICAgICAgICBwcmludEZvb3QoZG9jLCB0YWJsZSwgY3Vyc29yLCBjb2xzQW5kSW5kZXhlcy5jb2x1bW5zKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgbGFzdFJvd0luZGV4T2ZMYXN0UGFnZV8xID0gLTE7XG4gICAgICAgIHZhciBmaXJzdENvbHVtbnNUb0ZpdFJlc3VsdCA9IGFsbENvbHVtbnNDYW5GaXRSZXN1bHRbMF07XG4gICAgICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gUHJpbnQgdGhlIGZpcnN0IGNvbHVtbnMsIHRha2luZyBub3RlIG9mIHRoZSBsYXN0IHJvdyBwcmludGVkXG4gICAgICAgICAgICB2YXIgbGFzdFByaW50ZWRSb3dJbmRleCA9IGxhc3RSb3dJbmRleE9mTGFzdFBhZ2VfMTtcbiAgICAgICAgICAgIGlmIChmaXJzdENvbHVtbnNUb0ZpdFJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGRvYy5hcHBseVN0eWxlcyhkb2MudXNlclN0eWxlcyk7XG4gICAgICAgICAgICAgICAgdmFyIGZpcnN0Q29sdW1uc1RvRml0ID0gZmlyc3RDb2x1bW5zVG9GaXRSZXN1bHQuY29sdW1ucztcbiAgICAgICAgICAgICAgICBpZiAobGFzdFJvd0luZGV4T2ZMYXN0UGFnZV8xID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiBhZGRpbmcgYSBwYWdlIGhlcmUsIG1ha2Ugc3VyZSBub3QgdG8gcHJpbnQgdGhlIGZvb3RlcnNcbiAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSB0aGV5IHdlcmUgYWxyZWFkeSBwcmludGVkIGJlZm9yZSBvbiB0aGlzIHNhbWUgbG9vcFxuICAgICAgICAgICAgICAgICAgICBhZGRQYWdlKGRvYywgdGFibGUsIHN0YXJ0UG9zLCBjdXJzb3IsIGZpcnN0Q29sdW1uc1RvRml0LCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHByaW50SGVhZChkb2MsIHRhYmxlLCBjdXJzb3IsIGZpcnN0Q29sdW1uc1RvRml0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGFzdFByaW50ZWRSb3dJbmRleCA9IHByaW50Qm9keVdpdGhvdXRQYWdlQnJlYWtzKGRvYywgdGFibGUsIGxhc3RSb3dJbmRleE9mTGFzdFBhZ2VfMSArIDEsIGN1cnNvciwgZmlyc3RDb2x1bW5zVG9GaXQpO1xuICAgICAgICAgICAgICAgIHByaW50Rm9vdChkb2MsIHRhYmxlLCBjdXJzb3IsIGZpcnN0Q29sdW1uc1RvRml0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIENoZWNrIGhvdyBtYW55IHJvd3Mgd2VyZSBwcmludGVkLCBzbyB0aGF0IHRoZSBuZXh0IGNvbHVtbnMgd291bGQgbm90IHByaW50IG1vcmUgcm93cyB0aGFuIHRoYXRcbiAgICAgICAgICAgIHZhciBtYXhOdW1iZXJPZlJvd3MgPSBsYXN0UHJpbnRlZFJvd0luZGV4IC0gbGFzdFJvd0luZGV4T2ZMYXN0UGFnZV8xO1xuICAgICAgICAgICAgLy8gUHJpbnQgdGhlIG5leHQgY29sdW1ucywgbmV2ZXIgZXhjZWRpbmcgbWF4TnVtYmVyT2ZSb3dzXG4gICAgICAgICAgICBhbGxDb2x1bW5zQ2FuRml0UmVzdWx0LnNsaWNlKDEpLmZvckVhY2goZnVuY3Rpb24gKGNvbHNBbmRJbmRleGVzKSB7XG4gICAgICAgICAgICAgICAgZG9jLmFwcGx5U3R5bGVzKGRvYy51c2VyU3R5bGVzKTtcbiAgICAgICAgICAgICAgICAvLyBXaGVuIGFkZGluZyBhIHBhZ2UgaGVyZSwgbWFrZSBzdXJlIG5vdCB0byBwcmludCB0aGUgZm9vdGVyc1xuICAgICAgICAgICAgICAgIC8vIGJlY2F1c2UgdGhleSB3ZXJlIGFscmVhZHkgcHJpbnRlZCBiZWZvcmUgb24gdGhpcyBzYW1lIGxvb3BcbiAgICAgICAgICAgICAgICBhZGRQYWdlKGRvYywgdGFibGUsIHN0YXJ0UG9zLCBjdXJzb3IsIGNvbHNBbmRJbmRleGVzLmNvbHVtbnMsIHRydWUpO1xuICAgICAgICAgICAgICAgIHByaW50Qm9keVdpdGhvdXRQYWdlQnJlYWtzKGRvYywgdGFibGUsIGxhc3RSb3dJbmRleE9mTGFzdFBhZ2VfMSArIDEsIGN1cnNvciwgY29sc0FuZEluZGV4ZXMuY29sdW1ucywgbWF4TnVtYmVyT2ZSb3dzKTtcbiAgICAgICAgICAgICAgICBwcmludEZvb3QoZG9jLCB0YWJsZSwgY3Vyc29yLCBjb2xzQW5kSW5kZXhlcy5jb2x1bW5zKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbGFzdFJvd0luZGV4T2ZMYXN0UGFnZV8xID0gbGFzdFByaW50ZWRSb3dJbmRleDtcbiAgICAgICAgfTtcbiAgICAgICAgd2hpbGUgKGxhc3RSb3dJbmRleE9mTGFzdFBhZ2VfMSA8IHRhYmxlLmJvZHkubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgX2xvb3BfMSgpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gcHJpbnRIZWFkKGRvYywgdGFibGUsIGN1cnNvciwgY29sdW1ucykge1xuICAgIHZhciBzZXR0aW5ncyA9IHRhYmxlLnNldHRpbmdzO1xuICAgIGRvYy5hcHBseVN0eWxlcyhkb2MudXNlclN0eWxlcyk7XG4gICAgaWYgKHNldHRpbmdzLnNob3dIZWFkID09PSAnZmlyc3RQYWdlJyB8fCBzZXR0aW5ncy5zaG93SGVhZCA9PT0gJ2V2ZXJ5UGFnZScpIHtcbiAgICAgICAgdGFibGUuaGVhZC5mb3JFYWNoKGZ1bmN0aW9uIChyb3cpIHsgcmV0dXJuIHByaW50Um93KGRvYywgdGFibGUsIHJvdywgY3Vyc29yLCBjb2x1bW5zKTsgfSk7XG4gICAgfVxufVxuZnVuY3Rpb24gcHJpbnRCb2R5KGRvYywgdGFibGUsIHN0YXJ0UG9zLCBjdXJzb3IsIGNvbHVtbnMpIHtcbiAgICBkb2MuYXBwbHlTdHlsZXMoZG9jLnVzZXJTdHlsZXMpO1xuICAgIHRhYmxlLmJvZHkuZm9yRWFjaChmdW5jdGlvbiAocm93LCBpbmRleCkge1xuICAgICAgICB2YXIgaXNMYXN0Um93ID0gaW5kZXggPT09IHRhYmxlLmJvZHkubGVuZ3RoIC0gMTtcbiAgICAgICAgcHJpbnRGdWxsUm93KGRvYywgdGFibGUsIHJvdywgaXNMYXN0Um93LCBzdGFydFBvcywgY3Vyc29yLCBjb2x1bW5zKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIHByaW50Qm9keVdpdGhvdXRQYWdlQnJlYWtzKGRvYywgdGFibGUsIHN0YXJ0Um93SW5kZXgsIGN1cnNvciwgY29sdW1ucywgbWF4TnVtYmVyT2ZSb3dzKSB7XG4gICAgZG9jLmFwcGx5U3R5bGVzKGRvYy51c2VyU3R5bGVzKTtcbiAgICBtYXhOdW1iZXJPZlJvd3MgPSBtYXhOdW1iZXJPZlJvd3MgIT09IG51bGwgJiYgbWF4TnVtYmVyT2ZSb3dzICE9PSB2b2lkIDAgPyBtYXhOdW1iZXJPZlJvd3MgOiB0YWJsZS5ib2R5Lmxlbmd0aDtcbiAgICB2YXIgZW5kUm93SW5kZXggPSBNYXRoLm1pbihzdGFydFJvd0luZGV4ICsgbWF4TnVtYmVyT2ZSb3dzLCB0YWJsZS5ib2R5Lmxlbmd0aCk7XG4gICAgdmFyIGxhc3RQcmludGVkUm93SW5kZXggPSAtMTtcbiAgICB2YXIgcm93cyA9IHRhYmxlLmJvZHkuc2xpY2Uoc3RhcnRSb3dJbmRleCwgZW5kUm93SW5kZXgpO1xuICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCByb3dzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICB2YXIgcm93ID0gcm93c1tpbmRleF07XG4gICAgICAgIHZhciBpc0xhc3RSb3cgPSBzdGFydFJvd0luZGV4ICsgaW5kZXggPT09IHRhYmxlLmJvZHkubGVuZ3RoIC0gMTtcbiAgICAgICAgdmFyIHJlbWFpbmluZ1NwYWNlID0gZ2V0UmVtYWluaW5nUGFnZVNwYWNlKGRvYywgdGFibGUsIGlzTGFzdFJvdywgY3Vyc29yKTtcbiAgICAgICAgaWYgKHJvdy5jYW5FbnRpcmVSb3dGaXQocmVtYWluaW5nU3BhY2UsIGNvbHVtbnMpKSB7XG4gICAgICAgICAgICBwcmludFJvdyhkb2MsIHRhYmxlLCByb3csIGN1cnNvciwgY29sdW1ucyk7XG4gICAgICAgICAgICBsYXN0UHJpbnRlZFJvd0luZGV4ID0gc3RhcnRSb3dJbmRleCArIGluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxhc3RQcmludGVkUm93SW5kZXg7XG59XG5mdW5jdGlvbiBwcmludEZvb3QoZG9jLCB0YWJsZSwgY3Vyc29yLCBjb2x1bW5zKSB7XG4gICAgdmFyIHNldHRpbmdzID0gdGFibGUuc2V0dGluZ3M7XG4gICAgZG9jLmFwcGx5U3R5bGVzKGRvYy51c2VyU3R5bGVzKTtcbiAgICBpZiAoc2V0dGluZ3Muc2hvd0Zvb3QgPT09ICdsYXN0UGFnZScgfHwgc2V0dGluZ3Muc2hvd0Zvb3QgPT09ICdldmVyeVBhZ2UnKSB7XG4gICAgICAgIHRhYmxlLmZvb3QuZm9yRWFjaChmdW5jdGlvbiAocm93KSB7IHJldHVybiBwcmludFJvdyhkb2MsIHRhYmxlLCByb3csIGN1cnNvciwgY29sdW1ucyk7IH0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldFJlbWFpbmluZ0xpbmVDb3VudChjZWxsLCByZW1haW5pbmdQYWdlU3BhY2UsIGRvYykge1xuICAgIHZhciBsaW5lSGVpZ2h0ID0gZG9jLmdldExpbmVIZWlnaHQoY2VsbC5zdHlsZXMuZm9udFNpemUpO1xuICAgIHZhciB2UGFkZGluZyA9IGNlbGwucGFkZGluZygndmVydGljYWwnKTtcbiAgICB2YXIgcmVtYWluaW5nTGluZXMgPSBNYXRoLmZsb29yKChyZW1haW5pbmdQYWdlU3BhY2UgLSB2UGFkZGluZykgLyBsaW5lSGVpZ2h0KTtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgcmVtYWluaW5nTGluZXMpO1xufVxuZnVuY3Rpb24gbW9kaWZ5Um93VG9GaXQocm93LCByZW1haW5pbmdQYWdlU3BhY2UsIHRhYmxlLCBkb2MpIHtcbiAgICB2YXIgY2VsbHMgPSB7fTtcbiAgICByb3cuc3BhbnNNdWx0aXBsZVBhZ2VzID0gdHJ1ZTtcbiAgICByb3cuaGVpZ2h0ID0gMDtcbiAgICB2YXIgcm93SGVpZ2h0ID0gMDtcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGFibGUuY29sdW1uczsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFyIGNvbHVtbiA9IF9hW19pXTtcbiAgICAgICAgdmFyIGNlbGwgPSByb3cuY2VsbHNbY29sdW1uLmluZGV4XTtcbiAgICAgICAgaWYgKCFjZWxsKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShjZWxsLnRleHQpKSB7XG4gICAgICAgICAgICBjZWxsLnRleHQgPSBbY2VsbC50ZXh0XTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVtYWluZGVyQ2VsbCA9IG5ldyBDZWxsKGNlbGwucmF3LCBjZWxsLnN0eWxlcywgY2VsbC5zZWN0aW9uKTtcbiAgICAgICAgcmVtYWluZGVyQ2VsbCA9IGFzc2lnbihyZW1haW5kZXJDZWxsLCBjZWxsKTtcbiAgICAgICAgcmVtYWluZGVyQ2VsbC50ZXh0ID0gW107XG4gICAgICAgIHZhciByZW1haW5pbmdMaW5lQ291bnQgPSBnZXRSZW1haW5pbmdMaW5lQ291bnQoY2VsbCwgcmVtYWluaW5nUGFnZVNwYWNlLCBkb2MpO1xuICAgICAgICBpZiAoY2VsbC50ZXh0Lmxlbmd0aCA+IHJlbWFpbmluZ0xpbmVDb3VudCkge1xuICAgICAgICAgICAgcmVtYWluZGVyQ2VsbC50ZXh0ID0gY2VsbC50ZXh0LnNwbGljZShyZW1haW5pbmdMaW5lQ291bnQsIGNlbGwudGV4dC5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzY2FsZUZhY3RvciA9IGRvYy5zY2FsZUZhY3RvcigpO1xuICAgICAgICB2YXIgbGluZUhlaWdodEZhY3RvciA9IGRvYy5nZXRMaW5lSGVpZ2h0RmFjdG9yKCk7XG4gICAgICAgIGNlbGwuY29udGVudEhlaWdodCA9IGNlbGwuZ2V0Q29udGVudEhlaWdodChzY2FsZUZhY3RvciwgbGluZUhlaWdodEZhY3Rvcik7XG4gICAgICAgIGlmIChjZWxsLmNvbnRlbnRIZWlnaHQgPj0gcmVtYWluaW5nUGFnZVNwYWNlKSB7XG4gICAgICAgICAgICBjZWxsLmNvbnRlbnRIZWlnaHQgPSByZW1haW5pbmdQYWdlU3BhY2U7XG4gICAgICAgICAgICByZW1haW5kZXJDZWxsLnN0eWxlcy5taW5DZWxsSGVpZ2h0IC09IHJlbWFpbmluZ1BhZ2VTcGFjZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2VsbC5jb250ZW50SGVpZ2h0ID4gcm93LmhlaWdodCkge1xuICAgICAgICAgICAgcm93LmhlaWdodCA9IGNlbGwuY29udGVudEhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICByZW1haW5kZXJDZWxsLmNvbnRlbnRIZWlnaHQgPSByZW1haW5kZXJDZWxsLmdldENvbnRlbnRIZWlnaHQoc2NhbGVGYWN0b3IsIGxpbmVIZWlnaHRGYWN0b3IpO1xuICAgICAgICBpZiAocmVtYWluZGVyQ2VsbC5jb250ZW50SGVpZ2h0ID4gcm93SGVpZ2h0KSB7XG4gICAgICAgICAgICByb3dIZWlnaHQgPSByZW1haW5kZXJDZWxsLmNvbnRlbnRIZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgY2VsbHNbY29sdW1uLmluZGV4XSA9IHJlbWFpbmRlckNlbGw7XG4gICAgfVxuICAgIHZhciByZW1haW5kZXJSb3cgPSBuZXcgUm93KHJvdy5yYXcsIC0xLCByb3cuc2VjdGlvbiwgY2VsbHMsIHRydWUpO1xuICAgIHJlbWFpbmRlclJvdy5oZWlnaHQgPSByb3dIZWlnaHQ7XG4gICAgZm9yICh2YXIgX2IgPSAwLCBfYyA9IHRhYmxlLmNvbHVtbnM7IF9iIDwgX2MubGVuZ3RoOyBfYisrKSB7XG4gICAgICAgIHZhciBjb2x1bW4gPSBfY1tfYl07XG4gICAgICAgIHZhciByZW1haW5kZXJDZWxsID0gcmVtYWluZGVyUm93LmNlbGxzW2NvbHVtbi5pbmRleF07XG4gICAgICAgIGlmIChyZW1haW5kZXJDZWxsKSB7XG4gICAgICAgICAgICByZW1haW5kZXJDZWxsLmhlaWdodCA9IHJlbWFpbmRlclJvdy5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNlbGwgPSByb3cuY2VsbHNbY29sdW1uLmluZGV4XTtcbiAgICAgICAgaWYgKGNlbGwpIHtcbiAgICAgICAgICAgIGNlbGwuaGVpZ2h0ID0gcm93LmhlaWdodDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVtYWluZGVyUm93O1xufVxuZnVuY3Rpb24gc2hvdWxkUHJpbnRPbkN1cnJlbnRQYWdlKGRvYywgcm93LCByZW1haW5pbmdQYWdlU3BhY2UsIHRhYmxlKSB7XG4gICAgdmFyIHBhZ2VIZWlnaHQgPSBkb2MucGFnZVNpemUoKS5oZWlnaHQ7XG4gICAgdmFyIG1hcmdpbiA9IHRhYmxlLnNldHRpbmdzLm1hcmdpbjtcbiAgICB2YXIgbWFyZ2luSGVpZ2h0ID0gbWFyZ2luLnRvcCArIG1hcmdpbi5ib3R0b207XG4gICAgdmFyIG1heFJvd0hlaWdodCA9IHBhZ2VIZWlnaHQgLSBtYXJnaW5IZWlnaHQ7XG4gICAgaWYgKHJvdy5zZWN0aW9uID09PSAnYm9keScpIHtcbiAgICAgICAgLy8gU2hvdWxkIGFsc28gdGFrZSBpbnRvIGFjY291bnQgdGhhdCBoZWFkIGFuZCBmb290IGlzIG5vdFxuICAgICAgICAvLyBvbiBldmVyeSBwYWdlIHdpdGggc29tZSBzZXR0aW5nc1xuICAgICAgICBtYXhSb3dIZWlnaHQgLT1cbiAgICAgICAgICAgIHRhYmxlLmdldEhlYWRIZWlnaHQodGFibGUuY29sdW1ucykgKyB0YWJsZS5nZXRGb290SGVpZ2h0KHRhYmxlLmNvbHVtbnMpO1xuICAgIH1cbiAgICB2YXIgbWluUm93SGVpZ2h0ID0gcm93LmdldE1pbmltdW1Sb3dIZWlnaHQodGFibGUuY29sdW1ucywgZG9jKTtcbiAgICB2YXIgbWluUm93Rml0cyA9IG1pblJvd0hlaWdodCA8IHJlbWFpbmluZ1BhZ2VTcGFjZTtcbiAgICBpZiAobWluUm93SGVpZ2h0ID4gbWF4Um93SGVpZ2h0KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiV2lsbCBub3QgYmUgYWJsZSB0byBwcmludCByb3cgXCIuY29uY2F0KHJvdy5pbmRleCwgXCIgY29ycmVjdGx5IHNpbmNlIGl0J3MgbWluaW11bSBoZWlnaHQgaXMgbGFyZ2VyIHRoYW4gcGFnZSBoZWlnaHRcIikpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCFtaW5Sb3dGaXRzKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIHJvd0hhc1Jvd1NwYW5DZWxsID0gcm93Lmhhc1Jvd1NwYW4odGFibGUuY29sdW1ucyk7XG4gICAgdmFyIHJvd0hpZ2hlclRoYW5QYWdlID0gcm93LmdldE1heENlbGxIZWlnaHQodGFibGUuY29sdW1ucykgPiBtYXhSb3dIZWlnaHQ7XG4gICAgaWYgKHJvd0hpZ2hlclRoYW5QYWdlKSB7XG4gICAgICAgIGlmIChyb3dIYXNSb3dTcGFuQ2VsbCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJUaGUgY29udGVudCBvZiByb3cgXCIuY29uY2F0KHJvdy5pbmRleCwgXCIgd2lsbCBub3QgYmUgZHJhd24gY29ycmVjdGx5IHNpbmNlIGRyYXdpbmcgcm93cyB3aXRoIGEgaGVpZ2h0IGxhcmdlciB0aGFuIHRoZSBwYWdlIGhlaWdodCBhbmQgaGFzIGNlbGxzIHdpdGggcm93c3BhbnMgaXMgbm90IHN1cHBvcnRlZC5cIikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAocm93SGFzUm93U3BhbkNlbGwpIHtcbiAgICAgICAgLy8gQ3VycmVudGx5IGEgbmV3IHBhZ2UgaXMgcmVxdWlyZWQgd2hlbmV2ZXIgYSByb3dzcGFuIHJvdyBkb24ndCBmaXQgYSBwYWdlLlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0YWJsZS5zZXR0aW5ncy5yb3dQYWdlQnJlYWsgPT09ICdhdm9pZCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBJbiBhbGwgb3RoZXIgY2FzZXMgcHJpbnQgdGhlIHJvdyBvbiBjdXJyZW50IHBhZ2VcbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIHByaW50RnVsbFJvdyhkb2MsIHRhYmxlLCByb3csIGlzTGFzdFJvdywgc3RhcnRQb3MsIGN1cnNvciwgY29sdW1ucykge1xuICAgIHZhciByZW1haW5pbmdTcGFjZSA9IGdldFJlbWFpbmluZ1BhZ2VTcGFjZShkb2MsIHRhYmxlLCBpc0xhc3RSb3csIGN1cnNvcik7XG4gICAgaWYgKHJvdy5jYW5FbnRpcmVSb3dGaXQocmVtYWluaW5nU3BhY2UsIGNvbHVtbnMpKSB7XG4gICAgICAgIC8vIFRoZSByb3cgZml0cyBpbiB0aGUgY3VycmVudCBwYWdlXG4gICAgICAgIHByaW50Um93KGRvYywgdGFibGUsIHJvdywgY3Vyc29yLCBjb2x1bW5zKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc2hvdWxkUHJpbnRPbkN1cnJlbnRQYWdlKGRvYywgcm93LCByZW1haW5pbmdTcGFjZSwgdGFibGUpKSB7XG4gICAgICAgIC8vIFRoZSByb3cgZ2V0cyBzcGxpdCBpbiB0d28gaGVyZSwgZWFjaCBwaWVjZSBpbiBvbmUgcGFnZVxuICAgICAgICB2YXIgcmVtYWluZGVyUm93ID0gbW9kaWZ5Um93VG9GaXQocm93LCByZW1haW5pbmdTcGFjZSwgdGFibGUsIGRvYyk7XG4gICAgICAgIHByaW50Um93KGRvYywgdGFibGUsIHJvdywgY3Vyc29yLCBjb2x1bW5zKTtcbiAgICAgICAgYWRkUGFnZShkb2MsIHRhYmxlLCBzdGFydFBvcywgY3Vyc29yLCBjb2x1bW5zKTtcbiAgICAgICAgcHJpbnRGdWxsUm93KGRvYywgdGFibGUsIHJlbWFpbmRlclJvdywgaXNMYXN0Um93LCBzdGFydFBvcywgY3Vyc29yLCBjb2x1bW5zKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIFRoZSByb3cgZ2V0IHByaW50ZWQgZW50aXJlbGx5IG9uIHRoZSBuZXh0IHBhZ2VcbiAgICAgICAgYWRkUGFnZShkb2MsIHRhYmxlLCBzdGFydFBvcywgY3Vyc29yLCBjb2x1bW5zKTtcbiAgICAgICAgcHJpbnRGdWxsUm93KGRvYywgdGFibGUsIHJvdywgaXNMYXN0Um93LCBzdGFydFBvcywgY3Vyc29yLCBjb2x1bW5zKTtcbiAgICB9XG59XG5mdW5jdGlvbiBwcmludFJvdyhkb2MsIHRhYmxlLCByb3csIGN1cnNvciwgY29sdW1ucykge1xuICAgIGN1cnNvci54ID0gdGFibGUuc2V0dGluZ3MubWFyZ2luLmxlZnQ7XG4gICAgZm9yICh2YXIgX2kgPSAwLCBjb2x1bW5zXzEgPSBjb2x1bW5zOyBfaSA8IGNvbHVtbnNfMS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFyIGNvbHVtbiA9IGNvbHVtbnNfMVtfaV07XG4gICAgICAgIHZhciBjZWxsID0gcm93LmNlbGxzW2NvbHVtbi5pbmRleF07XG4gICAgICAgIGlmICghY2VsbCkge1xuICAgICAgICAgICAgY3Vyc29yLnggKz0gY29sdW1uLndpZHRoO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgZG9jLmFwcGx5U3R5bGVzKGNlbGwuc3R5bGVzKTtcbiAgICAgICAgY2VsbC54ID0gY3Vyc29yLng7XG4gICAgICAgIGNlbGwueSA9IGN1cnNvci55O1xuICAgICAgICB2YXIgcmVzdWx0ID0gdGFibGUuY2FsbENlbGxIb29rcyhkb2MsIHRhYmxlLmhvb2tzLndpbGxEcmF3Q2VsbCwgY2VsbCwgcm93LCBjb2x1bW4sIGN1cnNvcik7XG4gICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBjdXJzb3IueCArPSBjb2x1bW4ud2lkdGg7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBkcmF3Q2VsbFJlY3QoZG9jLCBjZWxsLCBjdXJzb3IpO1xuICAgICAgICB2YXIgdGV4dFBvcyA9IGNlbGwuZ2V0VGV4dFBvcygpO1xuICAgICAgICBhdXRvVGFibGVUZXh0KGNlbGwudGV4dCwgdGV4dFBvcy54LCB0ZXh0UG9zLnksIHtcbiAgICAgICAgICAgIGhhbGlnbjogY2VsbC5zdHlsZXMuaGFsaWduLFxuICAgICAgICAgICAgdmFsaWduOiBjZWxsLnN0eWxlcy52YWxpZ24sXG4gICAgICAgICAgICBtYXhXaWR0aDogTWF0aC5jZWlsKGNlbGwud2lkdGggLSBjZWxsLnBhZGRpbmcoJ2xlZnQnKSAtIGNlbGwucGFkZGluZygncmlnaHQnKSksXG4gICAgICAgIH0sIGRvYy5nZXREb2N1bWVudCgpKTtcbiAgICAgICAgdGFibGUuY2FsbENlbGxIb29rcyhkb2MsIHRhYmxlLmhvb2tzLmRpZERyYXdDZWxsLCBjZWxsLCByb3csIGNvbHVtbiwgY3Vyc29yKTtcbiAgICAgICAgY3Vyc29yLnggKz0gY29sdW1uLndpZHRoO1xuICAgIH1cbiAgICBjdXJzb3IueSArPSByb3cuaGVpZ2h0O1xufVxuZnVuY3Rpb24gZHJhd0NlbGxSZWN0KGRvYywgY2VsbCwgY3Vyc29yKSB7XG4gICAgdmFyIGNlbGxTdHlsZXMgPSBjZWxsLnN0eWxlcztcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vc2ltb25iZW5ndHNzb24vanNQREYtQXV0b1RhYmxlL2lzc3Vlcy83NzRcbiAgICAvLyBUT0RPICh2NCk6IGJldHRlciBzb2x1dGlvbj9cbiAgICBkb2MuZ2V0RG9jdW1lbnQoKS5zZXRGaWxsQ29sb3IoZG9jLmdldERvY3VtZW50KCkuZ2V0RmlsbENvbG9yKCkpO1xuICAgIGlmICh0eXBlb2YgY2VsbFN0eWxlcy5saW5lV2lkdGggPT09ICdudW1iZXInKSB7XG4gICAgICAgIC8vIERyYXcgY2VsbCBiYWNrZ3JvdW5kIHdpdGggbm9ybWFsIGJvcmRlcnNcbiAgICAgICAgdmFyIGZpbGxTdHlsZSA9IGdldEZpbGxTdHlsZShjZWxsU3R5bGVzLmxpbmVXaWR0aCwgY2VsbFN0eWxlcy5maWxsQ29sb3IpO1xuICAgICAgICBpZiAoZmlsbFN0eWxlKSB7XG4gICAgICAgICAgICBkb2MucmVjdChjZWxsLngsIGN1cnNvci55LCBjZWxsLndpZHRoLCBjZWxsLmhlaWdodCwgZmlsbFN0eWxlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgY2VsbFN0eWxlcy5saW5lV2lkdGggPT09ICdvYmplY3QnKSB7XG4gICAgICAgIC8vIERyYXcgY2VsbCBiYWNrZ3JvdW5kXG4gICAgICAgIGlmIChjZWxsU3R5bGVzLmZpbGxDb2xvcikge1xuICAgICAgICAgICAgZG9jLnJlY3QoY2VsbC54LCBjdXJzb3IueSwgY2VsbC53aWR0aCwgY2VsbC5oZWlnaHQsICdGJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRHJhdyBjZWxsIGluZGl2aWR1YWwgYm9yZGVyc1xuICAgICAgICBkcmF3Q2VsbEJvcmRlcnMoZG9jLCBjZWxsLCBjdXJzb3IsIGNlbGxTdHlsZXMubGluZVdpZHRoKTtcbiAgICB9XG59XG4vKipcbiAqIERyYXcgYWxsIHNwZWNpZmllZCBib3JkZXJzLiBCb3JkZXJzIGFyZSBjZW50ZXJlZCBvbiBjZWxsJ3MgZWRnZSBhbmQgbGVuZ3RoZW5lZFxuICogdG8gb3ZlcmxhcCB3aXRoIG5laWdoYm91cnMgdG8gY3JlYXRlIHNoYXJwIGNvcm5lcnMuXG4gKiBAcGFyYW0gZG9jXG4gKiBAcGFyYW0gY2VsbFxuICogQHBhcmFtIGN1cnNvclxuICogQHBhcmFtIGZpbGxDb2xvclxuICogQHBhcmFtIGxpbmVXaWR0aFxuICovXG5mdW5jdGlvbiBkcmF3Q2VsbEJvcmRlcnMoZG9jLCBjZWxsLCBjdXJzb3IsIGxpbmVXaWR0aCkge1xuICAgIHZhciB4MSwgeTEsIHgyLCB5MjtcbiAgICBpZiAobGluZVdpZHRoLnRvcCkge1xuICAgICAgICB4MSA9IGN1cnNvci54O1xuICAgICAgICB5MSA9IGN1cnNvci55O1xuICAgICAgICB4MiA9IGN1cnNvci54ICsgY2VsbC53aWR0aDtcbiAgICAgICAgeTIgPSBjdXJzb3IueTtcbiAgICAgICAgaWYgKGxpbmVXaWR0aC5yaWdodCkge1xuICAgICAgICAgICAgeDIgKz0gMC41ICogbGluZVdpZHRoLnJpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW5lV2lkdGgubGVmdCkge1xuICAgICAgICAgICAgeDEgLT0gMC41ICogbGluZVdpZHRoLmxlZnQ7XG4gICAgICAgIH1cbiAgICAgICAgZHJhd0xpbmUobGluZVdpZHRoLnRvcCwgeDEsIHkxLCB4MiwgeTIpO1xuICAgIH1cbiAgICBpZiAobGluZVdpZHRoLmJvdHRvbSkge1xuICAgICAgICB4MSA9IGN1cnNvci54O1xuICAgICAgICB5MSA9IGN1cnNvci55ICsgY2VsbC5oZWlnaHQ7XG4gICAgICAgIHgyID0gY3Vyc29yLnggKyBjZWxsLndpZHRoO1xuICAgICAgICB5MiA9IGN1cnNvci55ICsgY2VsbC5oZWlnaHQ7XG4gICAgICAgIGlmIChsaW5lV2lkdGgucmlnaHQpIHtcbiAgICAgICAgICAgIHgyICs9IDAuNSAqIGxpbmVXaWR0aC5yaWdodDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGluZVdpZHRoLmxlZnQpIHtcbiAgICAgICAgICAgIHgxIC09IDAuNSAqIGxpbmVXaWR0aC5sZWZ0O1xuICAgICAgICB9XG4gICAgICAgIGRyYXdMaW5lKGxpbmVXaWR0aC5ib3R0b20sIHgxLCB5MSwgeDIsIHkyKTtcbiAgICB9XG4gICAgaWYgKGxpbmVXaWR0aC5sZWZ0KSB7XG4gICAgICAgIHgxID0gY3Vyc29yLng7XG4gICAgICAgIHkxID0gY3Vyc29yLnk7XG4gICAgICAgIHgyID0gY3Vyc29yLng7XG4gICAgICAgIHkyID0gY3Vyc29yLnkgKyBjZWxsLmhlaWdodDtcbiAgICAgICAgaWYgKGxpbmVXaWR0aC50b3ApIHtcbiAgICAgICAgICAgIHkxIC09IDAuNSAqIGxpbmVXaWR0aC50b3A7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxpbmVXaWR0aC5ib3R0b20pIHtcbiAgICAgICAgICAgIHkyICs9IDAuNSAqIGxpbmVXaWR0aC5ib3R0b207XG4gICAgICAgIH1cbiAgICAgICAgZHJhd0xpbmUobGluZVdpZHRoLmxlZnQsIHgxLCB5MSwgeDIsIHkyKTtcbiAgICB9XG4gICAgaWYgKGxpbmVXaWR0aC5yaWdodCkge1xuICAgICAgICB4MSA9IGN1cnNvci54ICsgY2VsbC53aWR0aDtcbiAgICAgICAgeTEgPSBjdXJzb3IueTtcbiAgICAgICAgeDIgPSBjdXJzb3IueCArIGNlbGwud2lkdGg7XG4gICAgICAgIHkyID0gY3Vyc29yLnkgKyBjZWxsLmhlaWdodDtcbiAgICAgICAgaWYgKGxpbmVXaWR0aC50b3ApIHtcbiAgICAgICAgICAgIHkxIC09IDAuNSAqIGxpbmVXaWR0aC50b3A7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxpbmVXaWR0aC5ib3R0b20pIHtcbiAgICAgICAgICAgIHkyICs9IDAuNSAqIGxpbmVXaWR0aC5ib3R0b207XG4gICAgICAgIH1cbiAgICAgICAgZHJhd0xpbmUobGluZVdpZHRoLnJpZ2h0LCB4MSwgeTEsIHgyLCB5Mik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGRyYXdMaW5lKHdpZHRoLCB4MSwgeTEsIHgyLCB5Mikge1xuICAgICAgICBkb2MuZ2V0RG9jdW1lbnQoKS5zZXRMaW5lV2lkdGgod2lkdGgpO1xuICAgICAgICBkb2MuZ2V0RG9jdW1lbnQoKS5saW5lKHgxLCB5MSwgeDIsIHkyLCAnUycpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldFJlbWFpbmluZ1BhZ2VTcGFjZShkb2MsIHRhYmxlLCBpc0xhc3RSb3csIGN1cnNvcikge1xuICAgIHZhciBib3R0b21Db250ZW50SGVpZ2h0ID0gdGFibGUuc2V0dGluZ3MubWFyZ2luLmJvdHRvbTtcbiAgICB2YXIgc2hvd0Zvb3QgPSB0YWJsZS5zZXR0aW5ncy5zaG93Rm9vdDtcbiAgICBpZiAoc2hvd0Zvb3QgPT09ICdldmVyeVBhZ2UnIHx8IChzaG93Rm9vdCA9PT0gJ2xhc3RQYWdlJyAmJiBpc0xhc3RSb3cpKSB7XG4gICAgICAgIGJvdHRvbUNvbnRlbnRIZWlnaHQgKz0gdGFibGUuZ2V0Rm9vdEhlaWdodCh0YWJsZS5jb2x1bW5zKTtcbiAgICB9XG4gICAgcmV0dXJuIGRvYy5wYWdlU2l6ZSgpLmhlaWdodCAtIGN1cnNvci55IC0gYm90dG9tQ29udGVudEhlaWdodDtcbn1cbmZ1bmN0aW9uIGFkZFBhZ2UoZG9jLCB0YWJsZSwgc3RhcnRQb3MsIGN1cnNvciwgY29sdW1ucywgc3VwcHJlc3NGb290ZXIpIHtcbiAgICBpZiAoY29sdW1ucyA9PT0gdm9pZCAwKSB7IGNvbHVtbnMgPSBbXTsgfVxuICAgIGlmIChzdXBwcmVzc0Zvb3RlciA9PT0gdm9pZCAwKSB7IHN1cHByZXNzRm9vdGVyID0gZmFsc2U7IH1cbiAgICBkb2MuYXBwbHlTdHlsZXMoZG9jLnVzZXJTdHlsZXMpO1xuICAgIGlmICh0YWJsZS5zZXR0aW5ncy5zaG93Rm9vdCA9PT0gJ2V2ZXJ5UGFnZScgJiYgIXN1cHByZXNzRm9vdGVyKSB7XG4gICAgICAgIHRhYmxlLmZvb3QuZm9yRWFjaChmdW5jdGlvbiAocm93KSB7IHJldHVybiBwcmludFJvdyhkb2MsIHRhYmxlLCByb3csIGN1cnNvciwgY29sdW1ucyk7IH0pO1xuICAgIH1cbiAgICAvLyBBZGQgdXNlciBjb250ZW50IGp1c3QgYmVmb3JlIGFkZGluZyBuZXcgcGFnZSBlbnN1cmUgaXQgd2lsbFxuICAgIC8vIGJlIGRyYXduIGFib3ZlIG90aGVyIHRoaW5ncyBvbiB0aGUgcGFnZVxuICAgIHRhYmxlLmNhbGxFbmRQYWdlSG9va3MoZG9jLCBjdXJzb3IpO1xuICAgIHZhciBtYXJnaW4gPSB0YWJsZS5zZXR0aW5ncy5tYXJnaW47XG4gICAgYWRkVGFibGVCb3JkZXIoZG9jLCB0YWJsZSwgc3RhcnRQb3MsIGN1cnNvcik7XG4gICAgbmV4dFBhZ2UoZG9jKTtcbiAgICB0YWJsZS5wYWdlTnVtYmVyKys7XG4gICAgY3Vyc29yLnggPSBtYXJnaW4ubGVmdDtcbiAgICBjdXJzb3IueSA9IG1hcmdpbi50b3A7XG4gICAgc3RhcnRQb3MueSA9IG1hcmdpbi50b3A7XG4gICAgLy8gY2FsbCBkaWRBZGRQYWdlIGhvb2tzIGJlZm9yZSBhbnkgY29udGVudCBpcyBhZGRlZCB0byB0aGUgcGFnZVxuICAgIHRhYmxlLmNhbGxXaWxsRHJhd1BhZ2VIb29rcyhkb2MsIGN1cnNvcik7XG4gICAgaWYgKHRhYmxlLnNldHRpbmdzLnNob3dIZWFkID09PSAnZXZlcnlQYWdlJykge1xuICAgICAgICB0YWJsZS5oZWFkLmZvckVhY2goZnVuY3Rpb24gKHJvdykgeyByZXR1cm4gcHJpbnRSb3coZG9jLCB0YWJsZSwgcm93LCBjdXJzb3IsIGNvbHVtbnMpOyB9KTtcbiAgICAgICAgZG9jLmFwcGx5U3R5bGVzKGRvYy51c2VyU3R5bGVzKTtcbiAgICB9XG59XG5mdW5jdGlvbiBuZXh0UGFnZShkb2MpIHtcbiAgICB2YXIgY3VycmVudCA9IGRvYy5wYWdlTnVtYmVyKCk7XG4gICAgZG9jLnNldFBhZ2UoY3VycmVudCArIDEpO1xuICAgIHZhciBuZXdDdXJyZW50ID0gZG9jLnBhZ2VOdW1iZXIoKTtcbiAgICBpZiAobmV3Q3VycmVudCA9PT0gY3VycmVudCkge1xuICAgICAgICBkb2MuYWRkUGFnZSgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBhcHBseVBsdWdpbihqc1BERikge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAganNQREYuQVBJLmF1dG9UYWJsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgb3B0aW9ucyA9IGFyZ3NbMF07XG4gICAgICAgIHZhciBpbnB1dCA9IHBhcnNlSW5wdXQodGhpcywgb3B0aW9ucyk7XG4gICAgICAgIHZhciB0YWJsZSA9IGNyZWF0ZVRhYmxlKHRoaXMsIGlucHV0KTtcbiAgICAgICAgZHJhd1RhYmxlKHRoaXMsIHRhYmxlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvLyBBc3NpZ24gZmFsc2UgdG8gZW5hYmxlIGBkb2MubGFzdEF1dG9UYWJsZS5maW5hbFkgfHwgNDBgIHN1Z2FyXG4gICAganNQREYuQVBJLmxhc3RBdXRvVGFibGUgPSBmYWxzZTtcbiAgICBqc1BERi5BUEkuYXV0b1RhYmxlVGV4dCA9IGZ1bmN0aW9uICh0ZXh0LCB4LCB5LCBzdHlsZXMpIHtcbiAgICAgICAgYXV0b1RhYmxlVGV4dCh0ZXh0LCB4LCB5LCBzdHlsZXMsIHRoaXMpO1xuICAgIH07XG4gICAganNQREYuQVBJLmF1dG9UYWJsZVNldERlZmF1bHRzID0gZnVuY3Rpb24gKGRlZmF1bHRzKSB7XG4gICAgICAgIERvY0hhbmRsZXIuc2V0RGVmYXVsdHMoZGVmYXVsdHMsIHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIGpzUERGLmF1dG9UYWJsZVNldERlZmF1bHRzID0gZnVuY3Rpb24gKGRlZmF1bHRzLCBkb2MpIHtcbiAgICAgICAgRG9jSGFuZGxlci5zZXREZWZhdWx0cyhkZWZhdWx0cywgZG9jKTtcbiAgICB9O1xuICAgIGpzUERGLkFQSS5hdXRvVGFibGVIdG1sVG9Kc29uID0gZnVuY3Rpb24gKHRhYmxlRWxlbSwgaW5jbHVkZUhpZGRlbkVsZW1lbnRzKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgaWYgKGluY2x1ZGVIaWRkZW5FbGVtZW50cyA9PT0gdm9pZCAwKSB7IGluY2x1ZGVIaWRkZW5FbGVtZW50cyA9IGZhbHNlOyB9XG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignQ2Fubm90IHJ1biBhdXRvVGFibGVIdG1sVG9Kc29uIGluIG5vbiBicm93c2VyIGVudmlyb25tZW50Jyk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZG9jID0gbmV3IERvY0hhbmRsZXIodGhpcyk7XG4gICAgICAgIHZhciBfYiA9IHBhcnNlSHRtbChkb2MsIHRhYmxlRWxlbSwgd2luZG93LCBpbmNsdWRlSGlkZGVuRWxlbWVudHMsIGZhbHNlKSwgaGVhZCA9IF9iLmhlYWQsIGJvZHkgPSBfYi5ib2R5O1xuICAgICAgICB2YXIgY29sdW1ucyA9ICgoX2EgPSBoZWFkWzBdKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EubWFwKGZ1bmN0aW9uIChjKSB7IHJldHVybiBjLmNvbnRlbnQ7IH0pKSB8fCBbXTtcbiAgICAgICAgcmV0dXJuIHsgY29sdW1uczogY29sdW1ucywgcm93czogYm9keSwgZGF0YTogYm9keSB9O1xuICAgIH07XG59XG5cbnZhciBfYTtcbmZ1bmN0aW9uIGF1dG9UYWJsZShkLCBvcHRpb25zKSB7XG4gICAgdmFyIGlucHV0ID0gcGFyc2VJbnB1dChkLCBvcHRpb25zKTtcbiAgICB2YXIgdGFibGUgPSBjcmVhdGVUYWJsZShkLCBpbnB1dCk7XG4gICAgZHJhd1RhYmxlKGQsIHRhYmxlKTtcbn1cbi8vIEV4cGVyaW1lbnRhbCBleHBvcnRcbmZ1bmN0aW9uIF9fY3JlYXRlVGFibGUoZCwgb3B0aW9ucykge1xuICAgIHZhciBpbnB1dCA9IHBhcnNlSW5wdXQoZCwgb3B0aW9ucyk7XG4gICAgcmV0dXJuIGNyZWF0ZVRhYmxlKGQsIGlucHV0KTtcbn1cbmZ1bmN0aW9uIF9fZHJhd1RhYmxlKGQsIHRhYmxlKSB7XG4gICAgZHJhd1RhYmxlKGQsIHRhYmxlKTtcbn1cbnRyeSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdykge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICB2YXIgYW55V2luZG93ID0gd2luZG93O1xuICAgICAgICB2YXIganNQREYgPSBhbnlXaW5kb3cuanNQREYgfHwgKChfYSA9IGFueVdpbmRvdy5qc3BkZikgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmpzUERGKTtcbiAgICAgICAgaWYgKGpzUERGKSB7XG4gICAgICAgICAgICBhcHBseVBsdWdpbihqc1BERik7XG4gICAgICAgIH1cbiAgICB9XG59XG5jYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zb2xlLmVycm9yKCdDb3VsZCBub3QgYXBwbHkgYXV0b1RhYmxlIHBsdWdpbicsIGVycm9yKTtcbn1cblxuZXhwb3J0IHsgQ2VsbCwgQ2VsbEhvb2tEYXRhLCBDb2x1bW4sIEhvb2tEYXRhLCBSb3csIFRhYmxlLCBfX2NyZWF0ZVRhYmxlLCBfX2RyYXdUYWJsZSwgYXBwbHlQbHVnaW4sIGF1dG9UYWJsZSwgYXV0b1RhYmxlIGFzIGRlZmF1bHQgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/jspdf-autotable/dist/jspdf.plugin.autotable.mjs\n");
/***/ })
};
;