\n * * “Catmull-Rom curveto” is a not standard SVG command and added in 2.0 to make life easier.\n * Note: there is a special case when path consist of just three commands: “M10,10R…z”. In this case path will smoothly connects to its beginning.\n > Usage\n | var c = paper.path(\"M10 10L90 90\");\n | // draw a diagonal line:\n | // move to 10,10, line to 90,90\n * For example of path strings, check out these icons: http://raphaeljs.com/icons/\n \\*/\n paperproto.path = function (pathString) {\n pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E);\n var out = R._engine.path(R.format[apply](R, arguments), this);\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Paper.image\n [ method ]\n **\n * Embeds an image into the surface.\n **\n > Parameters\n **\n - src (string) URI of the source image\n - x (number) x coordinate position\n - y (number) y coordinate position\n - width (number) width of the image\n - height (number) height of the image\n = (object) Raphaël element object with type “image”\n **\n > Usage\n | var c = paper.image(\"apple.png\", 10, 10, 80, 80);\n \\*/\n paperproto.image = function (src, x, y, w, h) {\n var out = R._engine.image(this, src || \"about:blank\", x || 0, y || 0, w || 0, h || 0);\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Paper.text\n [ method ]\n **\n * Draws a text string. If you need line breaks, put “\\n” in the string.\n **\n > Parameters\n **\n - x (number) x coordinate position\n - y (number) y coordinate position\n - text (string) The text string to draw\n = (object) Raphaël element object with type “text”\n **\n > Usage\n | var t = paper.text(50, 50, \"Raphaël\\nkicks\\nbutt!\");\n \\*/\n paperproto.text = function (x, y, text) {\n var out = R._engine.text(this, x || 0, y || 0, Str(text));\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Paper.set\n [ method ]\n **\n * Creates array-like object to keep and operate several elements at once.\n * Warning: it doesn’t create any elements for itself in the page, it just groups existing elements.\n * Sets act as pseudo elements — all methods available to an element can be used on a set.\n = (object) array-like object that represents set of elements\n **\n > Usage\n | var st = paper.set();\n | st.push(\n | paper.circle(10, 10, 5),\n | paper.circle(30, 10, 5)\n | );\n | st.attr({fill: \"red\"}); // changes the fill of both circles\n \\*/\n paperproto.set = function (itemsArray) {\n !R.is(itemsArray, \"array\") && (itemsArray = Array.prototype.splice.call(arguments, 0, arguments.length));\n var out = new Set(itemsArray);\n this.__set__ && this.__set__.push(out);\n out[\"paper\"] = this;\n out[\"type\"] = \"set\";\n return out;\n };\n /*\\\n * Paper.setStart\n [ method ]\n **\n * Creates @Paper.set. All elements that will be created after calling this method and before calling\n * @Paper.setFinish will be added to the set.\n **\n > Usage\n | paper.setStart();\n | paper.circle(10, 10, 5),\n | paper.circle(30, 10, 5)\n | var st = paper.setFinish();\n | st.attr({fill: \"red\"}); // changes the fill of both circles\n \\*/\n paperproto.setStart = function (set) {\n this.__set__ = set || this.set();\n };\n /*\\\n * Paper.setFinish\n [ method ]\n **\n * See @Paper.setStart. This method finishes catching and returns resulting set.\n **\n = (object) set\n \\*/\n paperproto.setFinish = function (set) {\n var out = this.__set__;\n delete this.__set__;\n return out;\n };\n /*\\\n * Paper.getSize\n [ method ]\n **\n * Obtains current paper actual size.\n **\n = (object)\n \\*/\n paperproto.getSize = function () {\n var container = this.canvas.parentNode;\n return {\n width: container.offsetWidth,\n height: container.offsetHeight\n };\n };\n /*\\\n * Paper.setSize\n [ method ]\n **\n * If you need to change dimensions of the canvas call this method\n **\n > Parameters\n **\n - width (number) new width of the canvas\n - height (number) new height of the canvas\n \\*/\n paperproto.setSize = function (width, height) {\n return R._engine.setSize.call(this, width, height);\n };\n /*\\\n * Paper.setViewBox\n [ method ]\n **\n * Sets the view box of the paper. Practically it gives you ability to zoom and pan whole paper surface by\n * specifying new boundaries.\n **\n > Parameters\n **\n - x (number) new x position, default is `0`\n - y (number) new y position, default is `0`\n - w (number) new width of the canvas\n - h (number) new height of the canvas\n - fit (boolean) `true` if you want graphics to fit into new boundary box\n \\*/\n paperproto.setViewBox = function (x, y, w, h, fit) {\n return R._engine.setViewBox.call(this, x, y, w, h, fit);\n };\n /*\\\n * Paper.top\n [ property ]\n **\n * Points to the topmost element on the paper\n \\*/\n /*\\\n * Paper.bottom\n [ property ]\n **\n * Points to the bottom element on the paper\n \\*/\n paperproto.top = paperproto.bottom = null;\n /*\\\n * Paper.raphael\n [ property ]\n **\n * Points to the @Raphael object/function\n \\*/\n paperproto.raphael = R;\n var getOffset = function (elem) {\n var box = elem.getBoundingClientRect(),\n doc = elem.ownerDocument,\n body = doc.body,\n docElem = doc.documentElement,\n clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,\n top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop,\n left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft;\n return {\n y: top,\n x: left\n };\n };\n /*\\\n * Paper.getElementByPoint\n [ method ]\n **\n * Returns you topmost element under given point.\n **\n = (object) Raphaël element object\n > Parameters\n **\n - x (number) x coordinate from the top left corner of the window\n - y (number) y coordinate from the top left corner of the window\n > Usage\n | paper.getElementByPoint(mouseX, mouseY).attr({stroke: \"#f00\"});\n \\*/\n paperproto.getElementByPoint = function (x, y) {\n var paper = this,\n svg = paper.canvas,\n target = g.doc.elementFromPoint(x, y);\n if (g.win.opera && target.tagName == \"svg\") {\n var so = getOffset(svg),\n sr = svg.createSVGRect();\n sr.x = x - so.x;\n sr.y = y - so.y;\n sr.width = sr.height = 1;\n var hits = svg.getIntersectionList(sr, null);\n if (hits.length) {\n target = hits[hits.length - 1];\n }\n }\n if (!target) {\n return null;\n }\n while (target.parentNode && target != svg.parentNode && !target.raphael) {\n target = target.parentNode;\n }\n target == paper.canvas.parentNode && (target = svg);\n target = target && target.raphael ? paper.getById(target.raphaelid) : null;\n return target;\n };\n\n /*\\\n * Paper.getElementsByBBox\n [ method ]\n **\n * Returns set of elements that have an intersecting bounding box\n **\n > Parameters\n **\n - bbox (object) bbox to check with\n = (object) @Set\n \\*/\n paperproto.getElementsByBBox = function (bbox) {\n var set = this.set();\n this.forEach(function (el) {\n if (R.isBBoxIntersect(el.getBBox(), bbox)) {\n set.push(el);\n }\n });\n return set;\n };\n\n /*\\\n * Paper.getById\n [ method ]\n **\n * Returns you element by its internal ID.\n **\n > Parameters\n **\n - id (number) id\n = (object) Raphaël element object\n \\*/\n paperproto.getById = function (id) {\n var bot = this.bottom;\n while (bot) {\n if (bot.id == id) {\n return bot;\n }\n bot = bot.next;\n }\n return null;\n };\n /*\\\n * Paper.forEach\n [ method ]\n **\n * Executes given function for each element on the paper\n *\n * If callback function returns `false` it will stop loop running.\n **\n > Parameters\n **\n - callback (function) function to run\n - thisArg (object) context object for the callback\n = (object) Paper object\n > Usage\n | paper.forEach(function (el) {\n | el.attr({ stroke: \"blue\" });\n | });\n \\*/\n paperproto.forEach = function (callback, thisArg) {\n var bot = this.bottom;\n while (bot) {\n if (callback.call(thisArg, bot) === false) {\n return this;\n }\n bot = bot.next;\n }\n return this;\n };\n /*\\\n * Paper.getElementsByPoint\n [ method ]\n **\n * Returns set of elements that have common point inside\n **\n > Parameters\n **\n - x (number) x coordinate of the point\n - y (number) y coordinate of the point\n = (object) @Set\n \\*/\n paperproto.getElementsByPoint = function (x, y) {\n var set = this.set();\n this.forEach(function (el) {\n if (el.isPointInside(x, y)) {\n set.push(el);\n }\n });\n return set;\n };\n function x_y() {\n return this.x + S + this.y;\n }\n function x_y_w_h() {\n return this.x + S + this.y + S + this.width + \" \\xd7 \" + this.height;\n }\n /*\\\n * Element.isPointInside\n [ method ]\n **\n * Determine if given point is inside this element’s shape\n **\n > Parameters\n **\n - x (number) x coordinate of the point\n - y (number) y coordinate of the point\n = (boolean) `true` if point inside the shape\n \\*/\n elproto.isPointInside = function (x, y) {\n var rp = this.realPath = getPath[this.type](this);\n if (this.attr('transform') && this.attr('transform').length) {\n rp = R.transformPath(rp, this.attr('transform'));\n }\n return R.isPointInsidePath(rp, x, y);\n };\n /*\\\n * Element.getBBox\n [ method ]\n **\n * Return bounding box for a given element\n **\n > Parameters\n **\n - isWithoutTransform (boolean) flag, `true` if you want to have bounding box before transformations. Default is `false`.\n = (object) Bounding box object:\n o {\n o x: (number) top left corner x\n o y: (number) top left corner y\n o x2: (number) bottom right corner x\n o y2: (number) bottom right corner y\n o width: (number) width\n o height: (number) height\n o }\n \\*/\n elproto.getBBox = function (isWithoutTransform) {\n if (this.removed) {\n return {};\n }\n var _ = this._;\n if (isWithoutTransform) {\n if (_.dirty || !_.bboxwt) {\n this.realPath = getPath[this.type](this);\n _.bboxwt = pathDimensions(this.realPath);\n _.bboxwt.toString = x_y_w_h;\n _.dirty = 0;\n }\n return _.bboxwt;\n }\n if (_.dirty || _.dirtyT || !_.bbox) {\n if (_.dirty || !this.realPath) {\n _.bboxwt = 0;\n this.realPath = getPath[this.type](this);\n }\n _.bbox = pathDimensions(mapPath(this.realPath, this.matrix));\n _.bbox.toString = x_y_w_h;\n _.dirty = _.dirtyT = 0;\n }\n return _.bbox;\n };\n /*\\\n * Element.clone\n [ method ]\n **\n = (object) clone of a given element\n **\n \\*/\n elproto.clone = function () {\n if (this.removed) {\n return null;\n }\n var out = this.paper[this.type]().attr(this.attr());\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Element.glow\n [ method ]\n **\n * Return set of elements that create glow-like effect around given element. See @Paper.set.\n *\n * Note: Glow is not connected to the element. If you change element attributes it won’t adjust itself.\n **\n > Parameters\n **\n - glow (object) #optional parameters object with all properties optional:\n o {\n o width (number) size of the glow, default is `10`\n o fill (boolean) will it be filled, default is `false`\n o opacity (number) opacity, default is `0.5`\n o offsetx (number) horizontal offset, default is `0`\n o offsety (number) vertical offset, default is `0`\n o color (string) glow colour, default is `black`\n o }\n = (object) @Paper.set of elements that represents glow\n \\*/\n elproto.glow = function (glow) {\n if (this.type == \"text\") {\n return null;\n }\n glow = glow || {};\n var s = {\n width: (glow.width || 10) + (+this.attr(\"stroke-width\") || 1),\n fill: glow.fill || false,\n opacity: glow.opacity == null ? .5 : glow.opacity,\n offsetx: glow.offsetx || 0,\n offsety: glow.offsety || 0,\n color: glow.color || \"#000\"\n },\n c = s.width / 2,\n r = this.paper,\n out = r.set(),\n path = this.realPath || getPath[this.type](this);\n path = this.matrix ? mapPath(path, this.matrix) : path;\n for (var i = 1; i < c + 1; i++) {\n out.push(r.path(path).attr({\n stroke: s.color,\n fill: s.fill ? s.color : \"none\",\n \"stroke-linejoin\": \"round\",\n \"stroke-linecap\": \"round\",\n \"stroke-width\": +(s.width / c * i).toFixed(3),\n opacity: +(s.opacity / c).toFixed(3)\n }));\n }\n return out.insertBefore(this).translate(s.offsetx, s.offsety);\n };\n var curveslengths = {},\n getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {\n if (length == null) {\n return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);\n } else {\n return R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, getTatLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length));\n }\n },\n getLengthFactory = function (istotal, subpath) {\n return function (path, length, onlystart) {\n path = path2curve(path);\n var x, y, p, l, sp = \"\", subpaths = {}, point,\n len = 0;\n for (var i = 0, ii = path.length; i < ii; i++) {\n p = path[i];\n if (p[0] == \"M\") {\n x = +p[1];\n y = +p[2];\n } else {\n l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);\n if (len + l > length) {\n if (subpath && !subpaths.start) {\n point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n sp += [\"C\" + point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];\n if (onlystart) {return sp;}\n subpaths.start = sp;\n sp = [\"M\" + point.x, point.y + \"C\" + point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]].join();\n len += l;\n x = +p[5];\n y = +p[6];\n continue;\n }\n if (!istotal && !subpath) {\n point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n return {x: point.x, y: point.y, alpha: point.alpha};\n }\n }\n len += l;\n x = +p[5];\n y = +p[6];\n }\n sp += p.shift() + p;\n }\n subpaths.end = sp;\n point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1);\n point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});\n return point;\n };\n };\n var getTotalLength = getLengthFactory(1),\n getPointAtLength = getLengthFactory(),\n getSubpathsAtLength = getLengthFactory(0, 1);\n /*\\\n * Raphael.getTotalLength\n [ method ]\n **\n * Returns length of the given path in pixels.\n **\n > Parameters\n **\n - path (string) SVG path string.\n **\n = (number) length.\n \\*/\n R.getTotalLength = getTotalLength;\n /*\\\n * Raphael.getPointAtLength\n [ method ]\n **\n * Return coordinates of the point located at the given length on the given path.\n **\n > Parameters\n **\n - path (string) SVG path string\n - length (number)\n **\n = (object) representation of the point:\n o {\n o x: (number) x coordinate\n o y: (number) y coordinate\n o alpha: (number) angle of derivative\n o }\n \\*/\n R.getPointAtLength = getPointAtLength;\n /*\\\n * Raphael.getSubpath\n [ method ]\n **\n * Return subpath of a given path from given length to given length.\n **\n > Parameters\n **\n - path (string) SVG path string\n - from (number) position of the start of the segment\n - to (number) position of the end of the segment\n **\n = (string) pathstring for the segment\n \\*/\n R.getSubpath = function (path, from, to) {\n if (this.getTotalLength(path) - to < 1e-6) {\n return getSubpathsAtLength(path, from).end;\n }\n var a = getSubpathsAtLength(path, to, 1);\n return from ? getSubpathsAtLength(a, from).end : a;\n };\n /*\\\n * Element.getTotalLength\n [ method ]\n **\n * Returns length of the path in pixels. Only works for element of “path” type.\n = (number) length.\n \\*/\n elproto.getTotalLength = function () {\n var path = this.getPath();\n if (!path) {\n return;\n }\n\n if (this.node.getTotalLength) {\n return this.node.getTotalLength();\n }\n\n return getTotalLength(path);\n };\n /*\\\n * Element.getPointAtLength\n [ method ]\n **\n * Return coordinates of the point located at the given length on the given path. Only works for element of “path” type.\n **\n > Parameters\n **\n - length (number)\n **\n = (object) representation of the point:\n o {\n o x: (number) x coordinate\n o y: (number) y coordinate\n o alpha: (number) angle of derivative\n o }\n \\*/\n elproto.getPointAtLength = function (length) {\n var path = this.getPath();\n if (!path) {\n return;\n }\n\n return getPointAtLength(path, length);\n };\n /*\\\n * Element.getPath\n [ method ]\n **\n * Returns path of the element. Only works for elements of “path” type and simple elements like circle.\n = (object) path\n **\n \\*/\n elproto.getPath = function () {\n var path,\n getPath = R._getPath[this.type];\n\n if (this.type == \"text\" || this.type == \"set\") {\n return;\n }\n\n if (getPath) {\n path = getPath(this);\n }\n\n return path;\n };\n /*\\\n * Element.getSubpath\n [ method ]\n **\n * Return subpath of a given element from given length to given length. Only works for element of “path” type.\n **\n > Parameters\n **\n - from (number) position of the start of the segment\n - to (number) position of the end of the segment\n **\n = (string) pathstring for the segment\n \\*/\n elproto.getSubpath = function (from, to) {\n var path = this.getPath();\n if (!path) {\n return;\n }\n\n return R.getSubpath(path, from, to);\n };\n /*\\\n * Raphael.easing_formulas\n [ property ]\n **\n * Object that contains easing formulas for animation. You could extend it with your own. By default it has following list of easing:\n #
\n \\*/\n var ef = R.easing_formulas = {\n linear: function (n) {\n return n;\n },\n \"<\": function (n) {\n return pow(n, 1.7);\n },\n \">\": function (n) {\n return pow(n, .48);\n },\n \"<>\": function (n) {\n var q = .48 - n / 1.04,\n Q = math.sqrt(.1734 + q * q),\n x = Q - q,\n X = pow(abs(x), 1 / 3) * (x < 0 ? -1 : 1),\n y = -Q - q,\n Y = pow(abs(y), 1 / 3) * (y < 0 ? -1 : 1),\n t = X + Y + .5;\n return (1 - t) * 3 * t * t + t * t * t;\n },\n backIn: function (n) {\n var s = 1.70158;\n return n * n * ((s + 1) * n - s);\n },\n backOut: function (n) {\n n = n - 1;\n var s = 1.70158;\n return n * n * ((s + 1) * n + s) + 1;\n },\n elastic: function (n) {\n if (n == !!n) {\n return n;\n }\n return pow(2, -10 * n) * math.sin((n - .075) * (2 * PI) / .3) + 1;\n },\n bounce: function (n) {\n var s = 7.5625,\n p = 2.75,\n l;\n if (n < (1 / p)) {\n l = s * n * n;\n } else {\n if (n < (2 / p)) {\n n -= (1.5 / p);\n l = s * n * n + .75;\n } else {\n if (n < (2.5 / p)) {\n n -= (2.25 / p);\n l = s * n * n + .9375;\n } else {\n n -= (2.625 / p);\n l = s * n * n + .984375;\n }\n }\n }\n return l;\n }\n };\n ef.easeIn = ef[\"ease-in\"] = ef[\"<\"];\n ef.easeOut = ef[\"ease-out\"] = ef[\">\"];\n ef.easeInOut = ef[\"ease-in-out\"] = ef[\"<>\"];\n ef[\"back-in\"] = ef.backIn;\n ef[\"back-out\"] = ef.backOut;\n\n var animationElements = [],\n requestAnimFrame = window.requestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function (callback) {\n setTimeout(callback, 16);\n },\n animation = function () {\n var Now = +new Date,\n l = 0;\n for (; l < animationElements.length; l++) {\n var e = animationElements[l];\n if (e.el.removed || e.paused) {\n continue;\n }\n var time = Now - e.start,\n ms = e.ms,\n easing = e.easing,\n from = e.from,\n diff = e.diff,\n to = e.to,\n t = e.t,\n that = e.el,\n set = {},\n now,\n init = {},\n key;\n if (e.initstatus) {\n time = (e.initstatus * e.anim.top - e.prev) / (e.percent - e.prev) * ms;\n e.status = e.initstatus;\n delete e.initstatus;\n e.stop && animationElements.splice(l--, 1);\n } else {\n e.status = (e.prev + (e.percent - e.prev) * (time / ms)) / e.anim.top;\n }\n if (time < 0) {\n continue;\n }\n if (time < ms) {\n var pos = easing(time / ms);\n for (var attr in from) if (from[has](attr)) {\n switch (availableAnimAttrs[attr]) {\n case nu:\n now = +from[attr] + pos * ms * diff[attr];\n break;\n case \"colour\":\n now = \"rgb(\" + [\n upto255(round(from[attr].r + pos * ms * diff[attr].r)),\n upto255(round(from[attr].g + pos * ms * diff[attr].g)),\n upto255(round(from[attr].b + pos * ms * diff[attr].b))\n ].join(\",\") + \")\";\n break;\n case \"path\":\n now = [];\n for (var i = 0, ii = from[attr].length; i < ii; i++) {\n now[i] = [from[attr][i][0]];\n for (var j = 1, jj = from[attr][i].length; j < jj; j++) {\n now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j];\n }\n now[i] = now[i].join(S);\n }\n now = now.join(S);\n break;\n case \"transform\":\n if (diff[attr].real) {\n now = [];\n for (i = 0, ii = from[attr].length; i < ii; i++) {\n now[i] = [from[attr][i][0]];\n for (j = 1, jj = from[attr][i].length; j < jj; j++) {\n now[i][j] = from[attr][i][j] + pos * ms * diff[attr][i][j];\n }\n }\n } else {\n var get = function (i) {\n return +from[attr][i] + pos * ms * diff[attr][i];\n };\n // now = [[\"r\", get(2), 0, 0], [\"t\", get(3), get(4)], [\"s\", get(0), get(1), 0, 0]];\n now = [[\"m\", get(0), get(1), get(2), get(3), get(4), get(5)]];\n }\n break;\n case \"csv\":\n if (attr == \"clip-rect\") {\n now = [];\n i = 4;\n while (i--) {\n now[i] = +from[attr][i] + pos * ms * diff[attr][i];\n }\n }\n break;\n default:\n var from2 = [][concat](from[attr]);\n now = [];\n i = that.paper.customAttributes[attr].length;\n while (i--) {\n now[i] = +from2[i] + pos * ms * diff[attr][i];\n }\n break;\n }\n set[attr] = now;\n }\n that.attr(set);\n (function (id, that, anim) {\n setTimeout(function () {\n eve(\"raphael.anim.frame.\" + id, that, anim);\n });\n })(that.id, that, e.anim);\n } else {\n (function(f, el, a) {\n setTimeout(function() {\n eve(\"raphael.anim.frame.\" + el.id, el, a);\n eve(\"raphael.anim.finish.\" + el.id, el, a);\n R.is(f, \"function\") && f.call(el);\n });\n })(e.callback, that, e.anim);\n that.attr(to);\n animationElements.splice(l--, 1);\n if (e.repeat > 1 && !e.next) {\n for (key in to) if (to[has](key)) {\n init[key] = e.totalOrigin[key];\n }\n e.el.attr(init);\n runAnimation(e.anim, e.el, e.anim.percents[0], null, e.totalOrigin, e.repeat - 1);\n }\n if (e.next && !e.stop) {\n runAnimation(e.anim, e.el, e.next, null, e.totalOrigin, e.repeat);\n }\n }\n }\n animationElements.length && requestAnimFrame(animation);\n },\n upto255 = function (color) {\n return color > 255 ? 255 : color < 0 ? 0 : color;\n };\n /*\\\n * Element.animateWith\n [ method ]\n **\n * Acts similar to @Element.animate, but ensure that given animation runs in sync with another given element.\n **\n > Parameters\n **\n - el (object) element to sync with\n - anim (object) animation to sync with\n - params (object) #optional final attributes for the element, see also @Element.attr\n - ms (number) #optional number of milliseconds for animation to run\n - easing (string) #optional easing type. Accept on of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX, XX, XX, XX)`\n - callback (function) #optional callback function. Will be called at the end of animation.\n * or\n - element (object) element to sync with\n - anim (object) animation to sync with\n - animation (object) #optional animation object, see @Raphael.animation\n **\n = (object) original element\n \\*/\n elproto.animateWith = function (el, anim, params, ms, easing, callback) {\n var element = this;\n if (element.removed) {\n callback && callback.call(element);\n return element;\n }\n var a = params instanceof Animation ? params : R.animation(params, ms, easing, callback),\n x, y;\n runAnimation(a, element, a.percents[0], null, element.attr());\n for (var i = 0, ii = animationElements.length; i < ii; i++) {\n if (animationElements[i].anim == anim && animationElements[i].el == el) {\n animationElements[ii - 1].start = animationElements[i].start;\n break;\n }\n }\n return element;\n //\n //\n // var a = params ? R.animation(params, ms, easing, callback) : anim,\n // status = element.status(anim);\n // return this.animate(a).status(a, status * anim.ms / a.ms);\n };\n function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) {\n var cx = 3 * p1x,\n bx = 3 * (p2x - p1x) - cx,\n ax = 1 - cx - bx,\n cy = 3 * p1y,\n by = 3 * (p2y - p1y) - cy,\n ay = 1 - cy - by;\n function sampleCurveX(t) {\n return ((ax * t + bx) * t + cx) * t;\n }\n function solve(x, epsilon) {\n var t = solveCurveX(x, epsilon);\n return ((ay * t + by) * t + cy) * t;\n }\n function solveCurveX(x, epsilon) {\n var t0, t1, t2, x2, d2, i;\n for(t2 = x, i = 0; i < 8; i++) {\n x2 = sampleCurveX(t2) - x;\n if (abs(x2) < epsilon) {\n return t2;\n }\n d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;\n if (abs(d2) < 1e-6) {\n break;\n }\n t2 = t2 - x2 / d2;\n }\n t0 = 0;\n t1 = 1;\n t2 = x;\n if (t2 < t0) {\n return t0;\n }\n if (t2 > t1) {\n return t1;\n }\n while (t0 < t1) {\n x2 = sampleCurveX(t2);\n if (abs(x2 - x) < epsilon) {\n return t2;\n }\n if (x > x2) {\n t0 = t2;\n } else {\n t1 = t2;\n }\n t2 = (t1 - t0) / 2 + t0;\n }\n return t2;\n }\n return solve(t, 1 / (200 * duration));\n }\n elproto.onAnimation = function (f) {\n f ? eve.on(\"raphael.anim.frame.\" + this.id, f) : eve.unbind(\"raphael.anim.frame.\" + this.id);\n return this;\n };\n function Animation(anim, ms) {\n var percents = [],\n newAnim = {};\n this.ms = ms;\n this.times = 1;\n if (anim) {\n for (var attr in anim) if (anim[has](attr)) {\n newAnim[toFloat(attr)] = anim[attr];\n percents.push(toFloat(attr));\n }\n percents.sort(sortByNumber);\n }\n this.anim = newAnim;\n this.top = percents[percents.length - 1];\n this.percents = percents;\n }\n /*\\\n * Animation.delay\n [ method ]\n **\n * Creates a copy of existing animation object with given delay.\n **\n > Parameters\n **\n - delay (number) number of ms to pass between animation start and actual animation\n **\n = (object) new altered Animation object\n | var anim = Raphael.animation({cx: 10, cy: 20}, 2e3);\n | circle1.animate(anim); // run the given animation immediately\n | circle2.animate(anim.delay(500)); // run the given animation after 500 ms\n \\*/\n Animation.prototype.delay = function (delay) {\n var a = new Animation(this.anim, this.ms);\n a.times = this.times;\n a.del = +delay || 0;\n return a;\n };\n /*\\\n * Animation.repeat\n [ method ]\n **\n * Creates a copy of existing animation object with given repetition.\n **\n > Parameters\n **\n - repeat (number) number iterations of animation. For infinite animation pass `Infinity`\n **\n = (object) new altered Animation object\n \\*/\n Animation.prototype.repeat = function (times) {\n var a = new Animation(this.anim, this.ms);\n a.del = this.del;\n a.times = math.floor(mmax(times, 0)) || 1;\n return a;\n };\n function runAnimation(anim, element, percent, status, totalOrigin, times) {\n percent = toFloat(percent);\n var params,\n isInAnim,\n isInAnimSet,\n percents = [],\n next,\n prev,\n timestamp,\n ms = anim.ms,\n from = {},\n to = {},\n diff = {};\n if (status) {\n for (i = 0, ii = animationElements.length; i < ii; i++) {\n var e = animationElements[i];\n if (e.el.id == element.id && e.anim == anim) {\n if (e.percent != percent) {\n animationElements.splice(i, 1);\n isInAnimSet = 1;\n } else {\n isInAnim = e;\n }\n element.attr(e.totalOrigin);\n break;\n }\n }\n } else {\n status = +to; // NaN\n }\n for (var i = 0, ii = anim.percents.length; i < ii; i++) {\n if (anim.percents[i] == percent || anim.percents[i] > status * anim.top) {\n percent = anim.percents[i];\n prev = anim.percents[i - 1] || 0;\n ms = ms / anim.top * (percent - prev);\n next = anim.percents[i + 1];\n params = anim.anim[percent];\n break;\n } else if (status) {\n element.attr(anim.anim[anim.percents[i]]);\n }\n }\n if (!params) {\n return;\n }\n if (!isInAnim) {\n for (var attr in params) if (params[has](attr)) {\n if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) {\n from[attr] = element.attr(attr);\n (from[attr] == null) && (from[attr] = availableAttrs[attr]);\n to[attr] = params[attr];\n switch (availableAnimAttrs[attr]) {\n case nu:\n diff[attr] = (to[attr] - from[attr]) / ms;\n break;\n case \"colour\":\n from[attr] = R.getRGB(from[attr]);\n var toColour = R.getRGB(to[attr]);\n diff[attr] = {\n r: (toColour.r - from[attr].r) / ms,\n g: (toColour.g - from[attr].g) / ms,\n b: (toColour.b - from[attr].b) / ms\n };\n break;\n case \"path\":\n var pathes = path2curve(from[attr], to[attr]),\n toPath = pathes[1];\n from[attr] = pathes[0];\n diff[attr] = [];\n for (i = 0, ii = from[attr].length; i < ii; i++) {\n diff[attr][i] = [0];\n for (var j = 1, jj = from[attr][i].length; j < jj; j++) {\n diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms;\n }\n }\n break;\n case \"transform\":\n var _ = element._,\n eq = equaliseTransform(_[attr], to[attr]);\n if (eq) {\n from[attr] = eq.from;\n to[attr] = eq.to;\n diff[attr] = [];\n diff[attr].real = true;\n for (i = 0, ii = from[attr].length; i < ii; i++) {\n diff[attr][i] = [from[attr][i][0]];\n for (j = 1, jj = from[attr][i].length; j < jj; j++) {\n diff[attr][i][j] = (to[attr][i][j] - from[attr][i][j]) / ms;\n }\n }\n } else {\n var m = (element.matrix || new Matrix),\n to2 = {\n _: {transform: _.transform},\n getBBox: function () {\n return element.getBBox(1);\n }\n };\n from[attr] = [\n m.a,\n m.b,\n m.c,\n m.d,\n m.e,\n m.f\n ];\n extractTransform(to2, to[attr]);\n to[attr] = to2._.transform;\n diff[attr] = [\n (to2.matrix.a - m.a) / ms,\n (to2.matrix.b - m.b) / ms,\n (to2.matrix.c - m.c) / ms,\n (to2.matrix.d - m.d) / ms,\n (to2.matrix.e - m.e) / ms,\n (to2.matrix.f - m.f) / ms\n ];\n // from[attr] = [_.sx, _.sy, _.deg, _.dx, _.dy];\n // var to2 = {_:{}, getBBox: function () { return element.getBBox(); }};\n // extractTransform(to2, to[attr]);\n // diff[attr] = [\n // (to2._.sx - _.sx) / ms,\n // (to2._.sy - _.sy) / ms,\n // (to2._.deg - _.deg) / ms,\n // (to2._.dx - _.dx) / ms,\n // (to2._.dy - _.dy) / ms\n // ];\n }\n break;\n case \"csv\":\n var values = Str(params[attr])[split](separator),\n from2 = Str(from[attr])[split](separator);\n if (attr == \"clip-rect\") {\n from[attr] = from2;\n diff[attr] = [];\n i = from2.length;\n while (i--) {\n diff[attr][i] = (values[i] - from[attr][i]) / ms;\n }\n }\n to[attr] = values;\n break;\n default:\n values = [][concat](params[attr]);\n from2 = [][concat](from[attr]);\n diff[attr] = [];\n i = element.paper.customAttributes[attr].length;\n while (i--) {\n diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms;\n }\n break;\n }\n }\n }\n var easing = params.easing,\n easyeasy = R.easing_formulas[easing];\n if (!easyeasy) {\n easyeasy = Str(easing).match(bezierrg);\n if (easyeasy && easyeasy.length == 5) {\n var curve = easyeasy;\n easyeasy = function (t) {\n return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms);\n };\n } else {\n easyeasy = pipe;\n }\n }\n timestamp = params.start || anim.start || +new Date;\n e = {\n anim: anim,\n percent: percent,\n timestamp: timestamp,\n start: timestamp + (anim.del || 0),\n status: 0,\n initstatus: status || 0,\n stop: false,\n ms: ms,\n easing: easyeasy,\n from: from,\n diff: diff,\n to: to,\n el: element,\n callback: params.callback,\n prev: prev,\n next: next,\n repeat: times || anim.times,\n origin: element.attr(),\n totalOrigin: totalOrigin\n };\n animationElements.push(e);\n if (status && !isInAnim && !isInAnimSet) {\n e.stop = true;\n e.start = new Date - ms * status;\n if (animationElements.length == 1) {\n return animation();\n }\n }\n if (isInAnimSet) {\n e.start = new Date - e.ms * status;\n }\n animationElements.length == 1 && requestAnimFrame(animation);\n } else {\n isInAnim.initstatus = status;\n isInAnim.start = new Date - isInAnim.ms * status;\n }\n eve(\"raphael.anim.start.\" + element.id, element, anim);\n }\n /*\\\n * Raphael.animation\n [ method ]\n **\n * Creates an animation object that can be passed to the @Element.animate or @Element.animateWith methods.\n * See also @Animation.delay and @Animation.repeat methods.\n **\n > Parameters\n **\n - params (object) final attributes for the element, see also @Element.attr\n - ms (number) number of milliseconds for animation to run\n - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX, XX, XX, XX)`\n - callback (function) #optional callback function. Will be called at the end of animation.\n **\n = (object) @Animation\n \\*/\n R.animation = function (params, ms, easing, callback) {\n if (params instanceof Animation) {\n return params;\n }\n if (R.is(easing, \"function\") || !easing) {\n callback = callback || easing || null;\n easing = null;\n }\n params = Object(params);\n ms = +ms || 0;\n var p = {},\n json,\n attr;\n for (attr in params) if (params[has](attr) && toFloat(attr) != attr && toFloat(attr) + \"%\" != attr) {\n json = true;\n p[attr] = params[attr];\n }\n if (!json) {\n // if percent-like syntax is used and end-of-all animation callback used\n if(callback){\n // find the last one\n var lastKey = 0;\n for(var i in params){\n var percent = toInt(i);\n if(params[has](i) && percent > lastKey){\n lastKey = percent;\n }\n }\n lastKey += '%';\n // if already defined callback in the last keyframe, skip\n !params[lastKey].callback && (params[lastKey].callback = callback);\n }\n return new Animation(params, ms);\n } else {\n easing && (p.easing = easing);\n callback && (p.callback = callback);\n return new Animation({100: p}, ms);\n }\n };\n /*\\\n * Element.animate\n [ method ]\n **\n * Creates and starts animation for given element.\n **\n > Parameters\n **\n - params (object) final attributes for the element, see also @Element.attr\n - ms (number) number of milliseconds for animation to run\n - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX, XX, XX, XX)`\n - callback (function) #optional callback function. Will be called at the end of animation.\n * or\n - animation (object) animation object, see @Raphael.animation\n **\n = (object) original element\n \\*/\n elproto.animate = function (params, ms, easing, callback) {\n var element = this;\n if (element.removed) {\n callback && callback.call(element);\n return element;\n }\n var anim = params instanceof Animation ? params : R.animation(params, ms, easing, callback);\n runAnimation(anim, element, anim.percents[0], null, element.attr());\n return element;\n };\n /*\\\n * Element.setTime\n [ method ]\n **\n * Sets the status of animation of the element in milliseconds. Similar to @Element.status method.\n **\n > Parameters\n **\n - anim (object) animation object\n - value (number) number of milliseconds from the beginning of the animation\n **\n = (object) original element if `value` is specified\n * Note, that during animation following events are triggered:\n *\n * On each animation frame event `anim.frame.`, on start `anim.start.` and on end `anim.finish.`.\n \\*/\n elproto.setTime = function (anim, value) {\n if (anim && value != null) {\n this.status(anim, mmin(value, anim.ms) / anim.ms);\n }\n return this;\n };\n /*\\\n * Element.status\n [ method ]\n **\n * Gets or sets the status of animation of the element.\n **\n > Parameters\n **\n - anim (object) #optional animation object\n - value (number) #optional 0 – 1. If specified, method works like a setter and sets the status of a given animation to the value. This will cause animation to jump to the given position.\n **\n = (number) status\n * or\n = (array) status if `anim` is not specified. Array of objects in format:\n o {\n o anim: (object) animation object\n o status: (number) status\n o }\n * or\n = (object) original element if `value` is specified\n \\*/\n elproto.status = function (anim, value) {\n var out = [],\n i = 0,\n len,\n e;\n if (value != null) {\n runAnimation(anim, this, -1, mmin(value, 1));\n return this;\n } else {\n len = animationElements.length;\n for (; i < len; i++) {\n e = animationElements[i];\n if (e.el.id == this.id && (!anim || e.anim == anim)) {\n if (anim) {\n return e.status;\n }\n out.push({\n anim: e.anim,\n status: e.status\n });\n }\n }\n if (anim) {\n return 0;\n }\n return out;\n }\n };\n /*\\\n * Element.pause\n [ method ]\n **\n * Stops animation of the element with ability to resume it later on.\n **\n > Parameters\n **\n - anim (object) #optional animation object\n **\n = (object) original element\n \\*/\n elproto.pause = function (anim) {\n for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {\n if (eve(\"raphael.anim.pause.\" + this.id, this, animationElements[i].anim) !== false) {\n animationElements[i].paused = true;\n }\n }\n return this;\n };\n /*\\\n * Element.resume\n [ method ]\n **\n * Resumes animation if it was paused with @Element.pause method.\n **\n > Parameters\n **\n - anim (object) #optional animation object\n **\n = (object) original element\n \\*/\n elproto.resume = function (anim) {\n for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {\n var e = animationElements[i];\n if (eve(\"raphael.anim.resume.\" + this.id, this, e.anim) !== false) {\n delete e.paused;\n this.status(e.anim, e.status);\n }\n }\n return this;\n };\n /*\\\n * Element.stop\n [ method ]\n **\n * Stops animation of the element.\n **\n > Parameters\n **\n - anim (object) #optional animation object\n **\n = (object) original element\n \\*/\n elproto.stop = function (anim) {\n for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {\n if (eve(\"raphael.anim.stop.\" + this.id, this, animationElements[i].anim) !== false) {\n animationElements.splice(i--, 1);\n }\n }\n return this;\n };\n function stopAnimation(paper) {\n for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.paper == paper) {\n animationElements.splice(i--, 1);\n }\n }\n eve.on(\"raphael.remove\", stopAnimation);\n eve.on(\"raphael.clear\", stopAnimation);\n elproto.toString = function () {\n return \"Rapha\\xebl\\u2019s object\";\n };\n\n // Set\n var Set = function (items) {\n this.items = [];\n this.length = 0;\n this.type = \"set\";\n if (items) {\n for (var i = 0, ii = items.length; i < ii; i++) {\n if (items[i] && (items[i].constructor == elproto.constructor || items[i].constructor == Set)) {\n this[this.items.length] = this.items[this.items.length] = items[i];\n this.length++;\n }\n }\n }\n },\n setproto = Set.prototype;\n /*\\\n * Set.push\n [ method ]\n **\n * Adds each argument to the current set.\n = (object) original element\n \\*/\n setproto.push = function () {\n var item,\n len;\n for (var i = 0, ii = arguments.length; i < ii; i++) {\n item = arguments[i];\n if (item && (item.constructor == elproto.constructor || item.constructor == Set)) {\n len = this.items.length;\n this[len] = this.items[len] = item;\n this.length++;\n }\n }\n return this;\n };\n /*\\\n * Set.pop\n [ method ]\n **\n * Removes last element and returns it.\n = (object) element\n \\*/\n setproto.pop = function () {\n this.length && delete this[this.length--];\n return this.items.pop();\n };\n /*\\\n * Set.forEach\n [ method ]\n **\n * Executes given function for each element in the set.\n *\n * If function returns `false` it will stop loop running.\n **\n > Parameters\n **\n - callback (function) function to run\n - thisArg (object) context object for the callback\n = (object) Set object\n \\*/\n setproto.forEach = function (callback, thisArg) {\n for (var i = 0, ii = this.items.length; i < ii; i++) {\n if (callback.call(thisArg, this.items[i], i) === false) {\n return this;\n }\n }\n return this;\n };\n for (var method in elproto) if (elproto[has](method)) {\n setproto[method] = (function (methodname) {\n return function () {\n var arg = arguments;\n return this.forEach(function (el) {\n el[methodname][apply](el, arg);\n });\n };\n })(method);\n }\n setproto.attr = function (name, value) {\n if (name && R.is(name, array) && R.is(name[0], \"object\")) {\n for (var j = 0, jj = name.length; j < jj; j++) {\n this.items[j].attr(name[j]);\n }\n } else {\n for (var i = 0, ii = this.items.length; i < ii; i++) {\n this.items[i].attr(name, value);\n }\n }\n return this;\n };\n /*\\\n * Set.clear\n [ method ]\n **\n * Removes all elements from the set\n \\*/\n setproto.clear = function () {\n while (this.length) {\n this.pop();\n }\n };\n /*\\\n * Set.splice\n [ method ]\n **\n * Removes given element from the set\n **\n > Parameters\n **\n - index (number) position of the deletion\n - count (number) number of element to remove\n - insertion… (object) #optional elements to insert\n = (object) set elements that were deleted\n \\*/\n setproto.splice = function (index, count, insertion) {\n index = index < 0 ? mmax(this.length + index, 0) : index;\n count = mmax(0, mmin(this.length - index, count));\n var tail = [],\n todel = [],\n args = [],\n i;\n for (i = 2; i < arguments.length; i++) {\n args.push(arguments[i]);\n }\n for (i = 0; i < count; i++) {\n todel.push(this[index + i]);\n }\n for (; i < this.length - index; i++) {\n tail.push(this[index + i]);\n }\n var arglen = args.length;\n for (i = 0; i < arglen + tail.length; i++) {\n this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen];\n }\n i = this.items.length = this.length -= count - arglen;\n while (this[i]) {\n delete this[i++];\n }\n return new Set(todel);\n };\n /*\\\n * Set.exclude\n [ method ]\n **\n * Removes given element from the set\n **\n > Parameters\n **\n - element (object) element to remove\n = (boolean) `true` if object was found & removed from the set\n \\*/\n setproto.exclude = function (el) {\n for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) {\n this.splice(i, 1);\n return true;\n }\n };\n setproto.animate = function (params, ms, easing, callback) {\n (R.is(easing, \"function\") || !easing) && (callback = easing || null);\n var len = this.items.length,\n i = len,\n item,\n set = this,\n collector;\n if (!len) {\n return this;\n }\n callback && (collector = function () {\n !--len && callback.call(set);\n });\n easing = R.is(easing, string) ? easing : collector;\n var anim = R.animation(params, ms, easing, collector);\n item = this.items[--i].animate(anim);\n while (i--) {\n this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, anim, anim);\n (this.items[i] && !this.items[i].removed) || len--;\n }\n return this;\n };\n setproto.insertAfter = function (el) {\n var i = this.items.length;\n while (i--) {\n this.items[i].insertAfter(el);\n }\n return this;\n };\n setproto.getBBox = function () {\n var x = [],\n y = [],\n x2 = [],\n y2 = [];\n for (var i = this.items.length; i--;) if (!this.items[i].removed) {\n var box = this.items[i].getBBox();\n x.push(box.x);\n y.push(box.y);\n x2.push(box.x + box.width);\n y2.push(box.y + box.height);\n }\n x = mmin[apply](0, x);\n y = mmin[apply](0, y);\n x2 = mmax[apply](0, x2);\n y2 = mmax[apply](0, y2);\n return {\n x: x,\n y: y,\n x2: x2,\n y2: y2,\n width: x2 - x,\n height: y2 - y\n };\n };\n setproto.clone = function (s) {\n s = this.paper.set();\n for (var i = 0, ii = this.items.length; i < ii; i++) {\n s.push(this.items[i].clone());\n }\n return s;\n };\n setproto.toString = function () {\n return \"Rapha\\xebl\\u2018s set\";\n };\n\n setproto.glow = function(glowConfig) {\n var ret = this.paper.set();\n this.forEach(function(shape, index){\n var g = shape.glow(glowConfig);\n if(g != null){\n g.forEach(function(shape2, index2){\n ret.push(shape2);\n });\n }\n });\n return ret;\n };\n\n\n /*\\\n * Set.isPointInside\n [ method ]\n **\n * Determine if given point is inside this set’s elements\n **\n > Parameters\n **\n - x (number) x coordinate of the point\n - y (number) y coordinate of the point\n = (boolean) `true` if point is inside any of the set's elements\n \\*/\n setproto.isPointInside = function (x, y) {\n var isPointInside = false;\n this.forEach(function (el) {\n if (el.isPointInside(x, y)) {\n isPointInside = true;\n return false; // stop loop\n }\n });\n return isPointInside;\n };\n\n /*\\\n * Raphael.registerFont\n [ method ]\n **\n * Adds given font to the registered set of fonts for Raphaël. Should be used as an internal call from within Cufón’s font file.\n * Returns original parameter, so it could be used with chaining.\n # More about Cufón and how to convert your font form TTF, OTF, etc to JavaScript file.\n **\n > Parameters\n **\n - font (object) the font to register\n = (object) the font you passed in\n > Usage\n | Cufon.registerFont(Raphael.registerFont({…}));\n \\*/\n R.registerFont = function (font) {\n if (!font.face) {\n return font;\n }\n this.fonts = this.fonts || {};\n var fontcopy = {\n w: font.w,\n face: {},\n glyphs: {}\n },\n family = font.face[\"font-family\"];\n for (var prop in font.face) if (font.face[has](prop)) {\n fontcopy.face[prop] = font.face[prop];\n }\n if (this.fonts[family]) {\n this.fonts[family].push(fontcopy);\n } else {\n this.fonts[family] = [fontcopy];\n }\n if (!font.svg) {\n fontcopy.face[\"units-per-em\"] = toInt(font.face[\"units-per-em\"], 10);\n for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) {\n var path = font.glyphs[glyph];\n fontcopy.glyphs[glyph] = {\n w: path.w,\n k: {},\n d: path.d && \"M\" + path.d.replace(/[mlcxtrv]/g, function (command) {\n return {l: \"L\", c: \"C\", x: \"z\", t: \"m\", r: \"l\", v: \"c\"}[command] || \"M\";\n }) + \"z\"\n };\n if (path.k) {\n for (var k in path.k) if (path[has](k)) {\n fontcopy.glyphs[glyph].k[k] = path.k[k];\n }\n }\n }\n }\n return font;\n };\n /*\\\n * Paper.getFont\n [ method ]\n **\n * Finds font object in the registered fonts by given parameters. You could specify only one word from the font name, like “Myriad” for “Myriad Pro”.\n **\n > Parameters\n **\n - family (string) font family name or any word from it\n - weight (string) #optional font weight\n - style (string) #optional font style\n - stretch (string) #optional font stretch\n = (object) the font object\n > Usage\n | paper.print(100, 100, \"Test string\", paper.getFont(\"Times\", 800), 30);\n \\*/\n paperproto.getFont = function (family, weight, style, stretch) {\n stretch = stretch || \"normal\";\n style = style || \"normal\";\n weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;\n if (!R.fonts) {\n return;\n }\n var font = R.fonts[family];\n if (!font) {\n var name = new RegExp(\"(^|\\\\s)\" + family.replace(/[^\\w\\d\\s+!~.:_-]/g, E) + \"(\\\\s|$)\", \"i\");\n for (var fontName in R.fonts) if (R.fonts[has](fontName)) {\n if (name.test(fontName)) {\n font = R.fonts[fontName];\n break;\n }\n }\n }\n var thefont;\n if (font) {\n for (var i = 0, ii = font.length; i < ii; i++) {\n thefont = font[i];\n if (thefont.face[\"font-weight\"] == weight && (thefont.face[\"font-style\"] == style || !thefont.face[\"font-style\"]) && thefont.face[\"font-stretch\"] == stretch) {\n break;\n }\n }\n }\n return thefont;\n };\n /*\\\n * Paper.print\n [ method ]\n **\n * Creates path that represent given text written using given font at given position with given size.\n * Result of the method is path element that contains whole text as a separate path.\n **\n > Parameters\n **\n - x (number) x position of the text\n - y (number) y position of the text\n - string (string) text to print\n - font (object) font object, see @Paper.getFont\n - size (number) #optional size of the font, default is `16`\n - origin (string) #optional could be `\"baseline\"` or `\"middle\"`, default is `\"middle\"`\n - letter_spacing (number) #optional number in range `-1..1`, default is `0`\n - line_spacing (number) #optional number in range `1..3`, default is `1`\n = (object) resulting path element, which consist of all letters\n > Usage\n | var txt = r.print(10, 50, \"print\", r.getFont(\"Museo\"), 30).attr({fill: \"#fff\"});\n \\*/\n paperproto.print = function (x, y, string, font, size, origin, letter_spacing, line_spacing) {\n origin = origin || \"middle\"; // baseline|middle\n letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1);\n line_spacing = mmax(mmin(line_spacing || 1, 3), 1);\n var letters = Str(string)[split](E),\n shift = 0,\n notfirst = 0,\n path = E,\n scale;\n R.is(font, \"string\") && (font = this.getFont(font));\n if (font) {\n scale = (size || 16) / font.face[\"units-per-em\"];\n var bb = font.face.bbox[split](separator),\n top = +bb[0],\n lineHeight = bb[3] - bb[1],\n shifty = 0,\n height = +bb[1] + (origin == \"baseline\" ? lineHeight + (+font.face.descent) : lineHeight / 2);\n for (var i = 0, ii = letters.length; i < ii; i++) {\n if (letters[i] == \"\\n\") {\n shift = 0;\n curr = 0;\n notfirst = 0;\n shifty += lineHeight * line_spacing;\n } else {\n var prev = notfirst && font.glyphs[letters[i - 1]] || {},\n curr = font.glyphs[letters[i]];\n shift += notfirst ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0;\n notfirst = 1;\n }\n if (curr && curr.d) {\n path += R.transformPath(curr.d, [\"t\", shift * scale, shifty * scale, \"s\", scale, scale, top, height, \"t\", (x - top) / scale, (y - height) / scale]);\n }\n }\n }\n return this.path(path).attr({\n fill: \"#000\",\n stroke: \"none\"\n });\n };\n\n /*\\\n * Paper.add\n [ method ]\n **\n * Imports elements in JSON array in format `{type: type, }`\n **\n > Parameters\n **\n - json (array)\n = (object) resulting set of imported elements\n > Usage\n | paper.add([\n | {\n | type: \"circle\",\n | cx: 10,\n | cy: 10,\n | r: 5\n | },\n | {\n | type: \"rect\",\n | x: 10,\n | y: 10,\n | width: 10,\n | height: 10,\n | fill: \"#fc0\"\n | }\n | ]);\n \\*/\n paperproto.add = function (json) {\n if (R.is(json, \"array\")) {\n var res = this.set(),\n i = 0,\n ii = json.length,\n j;\n for (; i < ii; i++) {\n j = json[i] || {};\n elements[has](j.type) && res.push(this[j.type]().attr(j));\n }\n }\n return res;\n };\n\n /*\\\n * Raphael.format\n [ method ]\n **\n * Simple format function. Replaces construction of type “`{}`” to the corresponding argument.\n **\n > Parameters\n **\n - token (string) string to format\n - … (string) rest of arguments will be treated as parameters for replacement\n = (string) formated string\n > Usage\n | var x = 10,\n | y = 20,\n | width = 40,\n | height = 50;\n | // this will draw a rectangular shape equivalent to \"M10,20h40v50h-40z\"\n | paper.path(Raphael.format(\"M{0},{1}h{2}v{3}h{4}z\", x, y, width, height, -width));\n \\*/\n R.format = function (token, params) {\n var args = R.is(params, array) ? [0][concat](params) : arguments;\n token && R.is(token, string) && args.length - 1 && (token = token.replace(formatrg, function (str, i) {\n return args[++i] == null ? E : args[i];\n }));\n return token || E;\n };\n /*\\\n * Raphael.fullfill\n [ method ]\n **\n * A little bit more advanced format function than @Raphael.format. Replaces construction of type “`{}`” to the corresponding argument.\n **\n > Parameters\n **\n - token (string) string to format\n - json (object) object which properties will be used as a replacement\n = (string) formated string\n > Usage\n | // this will draw a rectangular shape equivalent to \"M10,20h40v50h-40z\"\n | paper.path(Raphael.fullfill(\"M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z\", {\n | x: 10,\n | y: 20,\n | dim: {\n | width: 40,\n | height: 50,\n | \"negative width\": -40\n | }\n | }));\n \\*/\n R.fullfill = (function () {\n var tokenRegex = /\\{([^\\}]+)\\}/g,\n objNotationRegex = /(?:(?:^|\\.)(.+?)(?=\\[|\\.|$|\\()|\\[('|\")(.+?)\\2\\])(\\(\\))?/g, // matches .xxxxx or [\"xxxxx\"] to run over object properties\n replacer = function (all, key, obj) {\n var res = obj;\n key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {\n name = name || quotedName;\n if (res) {\n if (name in res) {\n res = res[name];\n }\n typeof res == \"function\" && isFunc && (res = res());\n }\n });\n res = (res == null || res == obj ? all : res) + \"\";\n return res;\n };\n return function (str, obj) {\n return String(str).replace(tokenRegex, function (all, key) {\n return replacer(all, key, obj);\n });\n };\n })();\n /*\\\n * Raphael.ninja\n [ method ]\n **\n * If you want to leave no trace of Raphaël (Well, Raphaël creates only one global variable `Raphael`, but anyway.) You can use `ninja` method.\n * Beware, that in this case plugins could stop working, because they are depending on global variable existence.\n **\n = (object) Raphael object\n > Usage\n | (function (local_raphael) {\n | var paper = local_raphael(10, 10, 320, 200);\n | …\n | })(Raphael.ninja());\n \\*/\n R.ninja = function () {\n if (oldRaphael.was) {\n g.win.Raphael = oldRaphael.is;\n } else {\n // IE8 raises an error when deleting window property\n window.Raphael = undefined;\n try {\n delete window.Raphael;\n } catch(e) {}\n }\n return R;\n };\n /*\\\n * Raphael.st\n [ property (object) ]\n **\n * You can add your own method to elements and sets. It is wise to add a set method for each element method\n * you added, so you will be able to call the same method on sets too.\n **\n * See also @Raphael.el.\n > Usage\n | Raphael.el.red = function () {\n | this.attr({fill: \"#f00\"});\n | };\n | Raphael.st.red = function () {\n | this.forEach(function (el) {\n | el.red();\n | });\n | };\n | // then use it\n | paper.set(paper.circle(100, 100, 20), paper.circle(110, 100, 20)).red();\n \\*/\n R.st = setproto;\n\n eve.on(\"raphael.DOMload\", function () {\n loaded = true;\n });\n\n // Firefox <3.6 fix: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html\n (function (doc, loaded, f) {\n if (doc.readyState == null && doc.addEventListener){\n doc.addEventListener(loaded, f = function () {\n doc.removeEventListener(loaded, f, false);\n doc.readyState = \"complete\";\n }, false);\n doc.readyState = \"loading\";\n }\n function isLoaded() {\n (/in/).test(doc.readyState) ? setTimeout(isLoaded, 9) : R.eve(\"raphael.DOMload\");\n }\n isLoaded();\n })(document, \"DOMContentLoaded\");\n\n return R;\n}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9kZXYvcmFwaGFlbC5jb3JlLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vUmFwaGFlbC8uL2Rldi9yYXBoYWVsLmNvcmUuanM/OTRkOSJdLCJzb3VyY2VzQ29udGVudCI6WyJkZWZpbmUoW1wiZXZlXCJdLCBmdW5jdGlvbihldmUpIHtcblxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIGEgY2FudmFzIG9iamVjdCBvbiB3aGljaCB0byBkcmF3LlxuICAgICAqIFlvdSBtdXN0IGRvIHRoaXMgZmlyc3QsIGFzIGFsbCBmdXR1cmUgY2FsbHMgdG8gZHJhd2luZyBtZXRob2RzXG4gICAgICogZnJvbSB0aGlzIGluc3RhbmNlIHdpbGwgYmUgYm91bmQgdG8gdGhpcyBjYW52YXMuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGNvbnRhaW5lciAoSFRNTEVsZW1lbnR8c3RyaW5nKSBET00gZWxlbWVudCBvciBpdHMgSUQgd2hpY2ggaXMgZ29pbmcgdG8gYmUgYSBwYXJlbnQgZm9yIGRyYXdpbmcgc3VyZmFjZVxuICAgICAtIHdpZHRoIChudW1iZXIpXG4gICAgIC0gaGVpZ2h0IChudW1iZXIpXG4gICAgIC0gY2FsbGJhY2sgKGZ1bmN0aW9uKSAjb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gd2hpY2ggaXMgZ29pbmcgdG8gYmUgZXhlY3V0ZWQgaW4gdGhlIGNvbnRleHQgb2YgbmV3bHkgY3JlYXRlZCBwYXBlclxuICAgICAqIG9yXG4gICAgIC0geCAobnVtYmVyKVxuICAgICAtIHkgKG51bWJlcilcbiAgICAgLSB3aWR0aCAobnVtYmVyKVxuICAgICAtIGhlaWdodCAobnVtYmVyKVxuICAgICAtIGNhbGxiYWNrIChmdW5jdGlvbikgI29wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHdoaWNoIGlzIGdvaW5nIHRvIGJlIGV4ZWN1dGVkIGluIHRoZSBjb250ZXh0IG9mIG5ld2x5IGNyZWF0ZWQgcGFwZXJcbiAgICAgKiBvclxuICAgICAtIGFsbCAoYXJyYXkpIChmaXJzdCAzIG9yIDQgZWxlbWVudHMgaW4gdGhlIGFycmF5IGFyZSBlcXVhbCB0byBbY29udGFpbmVySUQsIHdpZHRoLCBoZWlnaHRdIG9yIFt4LCB5LCB3aWR0aCwgaGVpZ2h0XS4gVGhlIHJlc3QgYXJlIGVsZW1lbnQgZGVzY3JpcHRpb25zIGluIGZvcm1hdCB7dHlwZTogdHlwZSwgPGF0dHJpYnV0ZXM+fSkuIFNlZSBAUGFwZXIuYWRkLlxuICAgICAtIGNhbGxiYWNrIChmdW5jdGlvbikgI29wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHdoaWNoIGlzIGdvaW5nIHRvIGJlIGV4ZWN1dGVkIGluIHRoZSBjb250ZXh0IG9mIG5ld2x5IGNyZWF0ZWQgcGFwZXJcbiAgICAgKiBvclxuICAgICAtIG9uUmVhZHlDYWxsYmFjayAoZnVuY3Rpb24pIGZ1bmN0aW9uIHRoYXQgaXMgZ29pbmcgdG8gYmUgY2FsbGVkIG9uIERPTSByZWFkeSBldmVudC4gWW91IGNhbiBhbHNvIHN1YnNjcmliZSB0byB0aGlzIGV2ZW50IHZpYSBFdmXigJlzIOKAnERPTUxvYWTigJ0gZXZlbnQuIEluIHRoaXMgY2FzZSBtZXRob2QgcmV0dXJucyBgdW5kZWZpbmVkYC5cbiAgICAgPSAob2JqZWN0KSBAUGFwZXJcbiAgICAgPiBVc2FnZVxuICAgICB8IC8vIEVhY2ggb2YgdGhlIGZvbGxvd2luZyBleGFtcGxlcyBjcmVhdGUgYSBjYW52YXNcbiAgICAgfCAvLyB0aGF0IGlzIDMyMHB4IHdpZGUgYnkgMjAwcHggaGlnaC5cbiAgICAgfCAvLyBDYW52YXMgaXMgY3JlYXRlZCBhdCB0aGUgdmlld3BvcnTigJlzIDEwLDUwIGNvb3JkaW5hdGUuXG4gICAgIHwgdmFyIHBhcGVyID0gUmFwaGFlbCgxMCwgNTAsIDMyMCwgMjAwKTtcbiAgICAgfCAvLyBDYW52YXMgaXMgY3JlYXRlZCBhdCB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSAjbm90ZXBhZCBlbGVtZW50XG4gICAgIHwgLy8gKG9yIGl0cyB0b3AgcmlnaHQgY29ybmVyIGluIGRpcj1cInJ0bFwiIGVsZW1lbnRzKVxuICAgICB8IHZhciBwYXBlciA9IFJhcGhhZWwoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJub3RlcGFkXCIpLCAzMjAsIDIwMCk7XG4gICAgIHwgLy8gU2FtZSBhcyBhYm92ZVxuICAgICB8IHZhciBwYXBlciA9IFJhcGhhZWwoXCJub3RlcGFkXCIsIDMyMCwgMjAwKTtcbiAgICAgfCAvLyBJbWFnZSBkdW1wXG4gICAgIHwgdmFyIHNldCA9IFJhcGhhZWwoW1wibm90ZXBhZFwiLCAzMjAsIDIwMCwge1xuICAgICB8ICAgICB0eXBlOiBcInJlY3RcIixcbiAgICAgfCAgICAgeDogMTAsXG4gICAgIHwgICAgIHk6IDEwLFxuICAgICB8ICAgICB3aWR0aDogMjUsXG4gICAgIHwgICAgIGhlaWdodDogMjUsXG4gICAgIHwgICAgIHN0cm9rZTogXCIjZjAwXCJcbiAgICAgfCB9LCB7XG4gICAgIHwgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICB8ICAgICB4OiAzMCxcbiAgICAgfCAgICAgeTogNDAsXG4gICAgIHwgICAgIHRleHQ6IFwiRHVtcFwiXG4gICAgIHwgfV0pO1xuICAgIFxcKi9cbiAgICBmdW5jdGlvbiBSKGZpcnN0KSB7XG4gICAgICAgIGlmIChSLmlzKGZpcnN0LCBcImZ1bmN0aW9uXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gbG9hZGVkID8gZmlyc3QoKSA6IGV2ZS5vbihcInJhcGhhZWwuRE9NbG9hZFwiLCBmaXJzdCk7XG4gICAgICAgIH0gZWxzZSBpZiAoUi5pcyhmaXJzdCwgYXJyYXkpKSB7XG4gICAgICAgICAgICByZXR1cm4gUi5fZW5naW5lLmNyZWF0ZVthcHBseV0oUiwgZmlyc3Quc3BsaWNlKDAsIDMgKyBSLmlzKGZpcnN0WzBdLCBudSkpKS5hZGQoZmlyc3QpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICAgICAgICAgICAgaWYgKFIuaXMoYXJnc1thcmdzLmxlbmd0aCAtIDFdLCBcImZ1bmN0aW9uXCIpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGYgPSBhcmdzLnBvcCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2FkZWQgPyBmLmNhbGwoUi5fZW5naW5lLmNyZWF0ZVthcHBseV0oUiwgYXJncykpIDogZXZlLm9uKFwicmFwaGFlbC5ET01sb2FkXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZi5jYWxsKFIuX2VuZ2luZS5jcmVhdGVbYXBwbHldKFIsIGFyZ3MpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFIuX2VuZ2luZS5jcmVhdGVbYXBwbHldKFIsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgUi52ZXJzaW9uID0gXCIyLjIuMFwiO1xuICAgIFIuZXZlID0gZXZlO1xuICAgIHZhciBsb2FkZWQsXG4gICAgICAgIHNlcGFyYXRvciA9IC9bLCBdKy8sXG4gICAgICAgIGVsZW1lbnRzID0ge2NpcmNsZTogMSwgcmVjdDogMSwgcGF0aDogMSwgZWxsaXBzZTogMSwgdGV4dDogMSwgaW1hZ2U6IDF9LFxuICAgICAgICBmb3JtYXRyZyA9IC9cXHsoXFxkKylcXH0vZyxcbiAgICAgICAgcHJvdG8gPSBcInByb3RvdHlwZVwiLFxuICAgICAgICBoYXMgPSBcImhhc093blByb3BlcnR5XCIsXG4gICAgICAgIGcgPSB7XG4gICAgICAgICAgICBkb2M6IGRvY3VtZW50LFxuICAgICAgICAgICAgd2luOiB3aW5kb3dcbiAgICAgICAgfSxcbiAgICAgICAgb2xkUmFwaGFlbCA9IHtcbiAgICAgICAgICAgIHdhczogT2JqZWN0LnByb3RvdHlwZVtoYXNdLmNhbGwoZy53aW4sIFwiUmFwaGFlbFwiKSxcbiAgICAgICAgICAgIGlzOiBnLndpbi5SYXBoYWVsXG4gICAgICAgIH0sXG4gICAgICAgIFBhcGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLypcXFxuICAgICAgICAgICAgICogUGFwZXIuY2FcbiAgICAgICAgICAgICBbIHByb3BlcnR5IChvYmplY3QpIF1cbiAgICAgICAgICAgICAqKlxuICAgICAgICAgICAgICogU2hvcnRjdXQgZm9yIEBQYXBlci5jdXN0b21BdHRyaWJ1dGVzXG4gICAgICAgICAgICBcXCovXG4gICAgICAgICAgICAvKlxcXG4gICAgICAgICAgICAgKiBQYXBlci5jdXN0b21BdHRyaWJ1dGVzXG4gICAgICAgICAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICAgICAgICAgKipcbiAgICAgICAgICAgICAqIElmIHlvdSBoYXZlIGEgc2V0IG9mIGF0dHJpYnV0ZXMgdGhhdCB5b3Ugd291bGQgbGlrZSB0byByZXByZXNlbnRcbiAgICAgICAgICAgICAqIGFzIGEgZnVuY3Rpb24gb2Ygc29tZSBudW1iZXIgeW91IGNhbiBkbyBpdCBlYXNpbHkgd2l0aCBjdXN0b20gYXR0cmlidXRlczpcbiAgICAgICAgICAgICA+IFVzYWdlXG4gICAgICAgICAgICAgfCBwYXBlci5jdXN0b21BdHRyaWJ1dGVzLmh1ZSA9IGZ1bmN0aW9uIChudW0pIHtcbiAgICAgICAgICAgICB8ICAgICBudW0gPSBudW0gJSAxO1xuICAgICAgICAgICAgIHwgICAgIHJldHVybiB7ZmlsbDogXCJoc2IoXCIgKyBudW0gKyBcIiwgMC43NSwgMSlcIn07XG4gICAgICAgICAgICAgfCB9O1xuICAgICAgICAgICAgIHwgLy8gQ3VzdG9tIGF0dHJpYnV0ZSDigJxodWXigJ0gd2lsbCBjaGFuZ2UgZmlsbFxuICAgICAgICAgICAgIHwgLy8gdG8gYmUgZ2l2ZW4gaHVlIHdpdGggZml4ZWQgc2F0dXJhdGlvbiBhbmQgYnJpZ2h0bmVzcy5cbiAgICAgICAgICAgICB8IC8vIE5vdyB5b3UgY2FuIHVzZSBpdCBsaWtlIHRoaXM6XG4gICAgICAgICAgICAgfCB2YXIgYyA9IHBhcGVyLmNpcmNsZSgxMCwgMTAsIDEwKS5hdHRyKHtodWU6IC40NX0pO1xuICAgICAgICAgICAgIHwgLy8gb3IgZXZlbiBsaWtlIHRoaXM6XG4gICAgICAgICAgICAgfCBjLmFuaW1hdGUoe2h1ZTogMX0sIDFlMyk7XG4gICAgICAgICAgICAgfFxuICAgICAgICAgICAgIHwgLy8gWW91IGNvdWxkIGFsc28gY3JlYXRlIGN1c3RvbSBhdHRyaWJ1dGVcbiAgICAgICAgICAgICB8IC8vIHdpdGggbXVsdGlwbGUgcGFyYW1ldGVyczpcbiAgICAgICAgICAgICB8IHBhcGVyLmN1c3RvbUF0dHJpYnV0ZXMuaHNiID0gZnVuY3Rpb24gKGgsIHMsIGIpIHtcbiAgICAgICAgICAgICB8ICAgICByZXR1cm4ge2ZpbGw6IFwiaHNiKFwiICsgW2gsIHMsIGJdLmpvaW4oXCIsXCIpICsgXCIpXCJ9O1xuICAgICAgICAgICAgIHwgfTtcbiAgICAgICAgICAgICB8IGMuYXR0cih7aHNiOiBcIjAuNSAuOCAxXCJ9KTtcbiAgICAgICAgICAgICB8IGMuYW5pbWF0ZSh7aHNiOiBbMSwgMCwgMC41XX0sIDFlMyk7XG4gICAgICAgICAgICBcXCovXG4gICAgICAgICAgICB0aGlzLmNhID0gdGhpcy5jdXN0b21BdHRyaWJ1dGVzID0ge307XG4gICAgICAgIH0sXG4gICAgICAgIHBhcGVycHJvdG8sXG4gICAgICAgIGFwcGVuZENoaWxkID0gXCJhcHBlbmRDaGlsZFwiLFxuICAgICAgICBhcHBseSA9IFwiYXBwbHlcIixcbiAgICAgICAgY29uY2F0ID0gXCJjb25jYXRcIixcbiAgICAgICAgc3VwcG9ydHNUb3VjaCA9ICgnb250b3VjaHN0YXJ0JyBpbiBnLndpbikgfHwgZy53aW4uRG9jdW1lbnRUb3VjaCAmJiBnLmRvYyBpbnN0YW5jZW9mIERvY3VtZW50VG91Y2gsIC8vdGFrZW4gZnJvbSBNb2Rlcm5penIgdG91Y2ggdGVzdFxuICAgICAgICBFID0gXCJcIixcbiAgICAgICAgUyA9IFwiIFwiLFxuICAgICAgICBTdHIgPSBTdHJpbmcsXG4gICAgICAgIHNwbGl0ID0gXCJzcGxpdFwiLFxuICAgICAgICBldmVudHMgPSBcImNsaWNrIGRibGNsaWNrIG1vdXNlZG93biBtb3VzZW1vdmUgbW91c2VvdXQgbW91c2VvdmVyIG1vdXNldXAgdG91Y2hzdGFydCB0b3VjaG1vdmUgdG91Y2hlbmQgdG91Y2hjYW5jZWxcIltzcGxpdF0oUyksXG4gICAgICAgIHRvdWNoTWFwID0ge1xuICAgICAgICAgICAgbW91c2Vkb3duOiBcInRvdWNoc3RhcnRcIixcbiAgICAgICAgICAgIG1vdXNlbW92ZTogXCJ0b3VjaG1vdmVcIixcbiAgICAgICAgICAgIG1vdXNldXA6IFwidG91Y2hlbmRcIlxuICAgICAgICB9LFxuICAgICAgICBsb3dlckNhc2UgPSBTdHIucHJvdG90eXBlLnRvTG93ZXJDYXNlLFxuICAgICAgICBtYXRoID0gTWF0aCxcbiAgICAgICAgbW1heCA9IG1hdGgubWF4LFxuICAgICAgICBtbWluID0gbWF0aC5taW4sXG4gICAgICAgIGFicyA9IG1hdGguYWJzLFxuICAgICAgICBwb3cgPSBtYXRoLnBvdyxcbiAgICAgICAgUEkgPSBtYXRoLlBJLFxuICAgICAgICBudSA9IFwibnVtYmVyXCIsXG4gICAgICAgIHN0cmluZyA9IFwic3RyaW5nXCIsXG4gICAgICAgIGFycmF5ID0gXCJhcnJheVwiLFxuICAgICAgICB0b1N0cmluZyA9IFwidG9TdHJpbmdcIixcbiAgICAgICAgZmlsbFN0cmluZyA9IFwiZmlsbFwiLFxuICAgICAgICBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcsXG4gICAgICAgIHBhcGVyID0ge30sXG4gICAgICAgIHB1c2ggPSBcInB1c2hcIixcbiAgICAgICAgSVNVUkwgPSBSLl9JU1VSTCA9IC9edXJsXFwoWydcIl0/KC4rPylbJ1wiXT9cXCkkL2ksXG4gICAgICAgIGNvbG91clJlZ0V4cCA9IC9eXFxzKigoI1thLWZcXGRdezZ9KXwoI1thLWZcXGRdezN9KXxyZ2JhP1xcKFxccyooW1xcZFxcLl0rJT9cXHMqLFxccypbXFxkXFwuXSslP1xccyosXFxzKltcXGRcXC5dKyU/KD86XFxzKixcXHMqW1xcZFxcLl0rJT8pPylcXHMqXFwpfGhzYmE/XFwoXFxzKihbXFxkXFwuXSsoPzpkZWd8XFx4YjB8JSk/XFxzKixcXHMqW1xcZFxcLl0rJT9cXHMqLFxccypbXFxkXFwuXSsoPzolP1xccyosXFxzKltcXGRcXC5dKyk/KSU/XFxzKlxcKXxoc2xhP1xcKFxccyooW1xcZFxcLl0rKD86ZGVnfFxceGIwfCUpP1xccyosXFxzKltcXGRcXC5dKyU/XFxzKixcXHMqW1xcZFxcLl0rKD86JT9cXHMqLFxccypbXFxkXFwuXSspPyklP1xccypcXCkpXFxzKiQvaSxcbiAgICAgICAgaXNuYW4gPSB7XCJOYU5cIjogMSwgXCJJbmZpbml0eVwiOiAxLCBcIi1JbmZpbml0eVwiOiAxfSxcbiAgICAgICAgYmV6aWVycmcgPSAvXig/OmN1YmljLSk/YmV6aWVyXFwoKFteLF0rKSwoW14sXSspLChbXixdKyksKFteXFwpXSspXFwpLyxcbiAgICAgICAgcm91bmQgPSBtYXRoLnJvdW5kLFxuICAgICAgICBzZXRBdHRyaWJ1dGUgPSBcInNldEF0dHJpYnV0ZVwiLFxuICAgICAgICB0b0Zsb2F0ID0gcGFyc2VGbG9hdCxcbiAgICAgICAgdG9JbnQgPSBwYXJzZUludCxcbiAgICAgICAgdXBwZXJDYXNlID0gU3RyLnByb3RvdHlwZS50b1VwcGVyQ2FzZSxcbiAgICAgICAgYXZhaWxhYmxlQXR0cnMgPSBSLl9hdmFpbGFibGVBdHRycyA9IHtcbiAgICAgICAgICAgIFwiYXJyb3ctZW5kXCI6IFwibm9uZVwiLFxuICAgICAgICAgICAgXCJhcnJvdy1zdGFydFwiOiBcIm5vbmVcIixcbiAgICAgICAgICAgIGJsdXI6IDAsXG4gICAgICAgICAgICBcImNsaXAtcmVjdFwiOiBcIjAgMCAxZTkgMWU5XCIsXG4gICAgICAgICAgICBjdXJzb3I6IFwiZGVmYXVsdFwiLFxuICAgICAgICAgICAgY3g6IDAsXG4gICAgICAgICAgICBjeTogMCxcbiAgICAgICAgICAgIGZpbGw6IFwiI2ZmZlwiLFxuICAgICAgICAgICAgXCJmaWxsLW9wYWNpdHlcIjogMSxcbiAgICAgICAgICAgIGZvbnQ6ICcxMHB4IFwiQXJpYWxcIicsXG4gICAgICAgICAgICBcImZvbnQtZmFtaWx5XCI6ICdcIkFyaWFsXCInLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIxMFwiLFxuICAgICAgICAgICAgXCJmb250LXN0eWxlXCI6IFwibm9ybWFsXCIsXG4gICAgICAgICAgICBcImZvbnQtd2VpZ2h0XCI6IDQwMCxcbiAgICAgICAgICAgIGdyYWRpZW50OiAwLFxuICAgICAgICAgICAgaGVpZ2h0OiAwLFxuICAgICAgICAgICAgaHJlZjogXCJodHRwOi8vcmFwaGFlbGpzLmNvbS9cIixcbiAgICAgICAgICAgIFwibGV0dGVyLXNwYWNpbmdcIjogMCxcbiAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICBwYXRoOiBcIk0wLDBcIixcbiAgICAgICAgICAgIHI6IDAsXG4gICAgICAgICAgICByeDogMCxcbiAgICAgICAgICAgIHJ5OiAwLFxuICAgICAgICAgICAgc3JjOiBcIlwiLFxuICAgICAgICAgICAgc3Ryb2tlOiBcIiMwMDBcIixcbiAgICAgICAgICAgIFwic3Ryb2tlLWRhc2hhcnJheVwiOiBcIlwiLFxuICAgICAgICAgICAgXCJzdHJva2UtbGluZWNhcFwiOiBcImJ1dHRcIixcbiAgICAgICAgICAgIFwic3Ryb2tlLWxpbmVqb2luXCI6IFwiYnV0dFwiLFxuICAgICAgICAgICAgXCJzdHJva2UtbWl0ZXJsaW1pdFwiOiAwLFxuICAgICAgICAgICAgXCJzdHJva2Utb3BhY2l0eVwiOiAxLFxuICAgICAgICAgICAgXCJzdHJva2Utd2lkdGhcIjogMSxcbiAgICAgICAgICAgIHRhcmdldDogXCJfYmxhbmtcIixcbiAgICAgICAgICAgIFwidGV4dC1hbmNob3JcIjogXCJtaWRkbGVcIixcbiAgICAgICAgICAgIHRpdGxlOiBcIlJhcGhhZWxcIixcbiAgICAgICAgICAgIHRyYW5zZm9ybTogXCJcIixcbiAgICAgICAgICAgIHdpZHRoOiAwLFxuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICBcImNsYXNzXCI6IFwiXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXZhaWxhYmxlQW5pbUF0dHJzID0gUi5fYXZhaWxhYmxlQW5pbUF0dHJzID0ge1xuICAgICAgICAgICAgYmx1cjogbnUsXG4gICAgICAgICAgICBcImNsaXAtcmVjdFwiOiBcImNzdlwiLFxuICAgICAgICAgICAgY3g6IG51LFxuICAgICAgICAgICAgY3k6IG51LFxuICAgICAgICAgICAgZmlsbDogXCJjb2xvdXJcIixcbiAgICAgICAgICAgIFwiZmlsbC1vcGFjaXR5XCI6IG51LFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogbnUsXG4gICAgICAgICAgICBoZWlnaHQ6IG51LFxuICAgICAgICAgICAgb3BhY2l0eTogbnUsXG4gICAgICAgICAgICBwYXRoOiBcInBhdGhcIixcbiAgICAgICAgICAgIHI6IG51LFxuICAgICAgICAgICAgcng6IG51LFxuICAgICAgICAgICAgcnk6IG51LFxuICAgICAgICAgICAgc3Ryb2tlOiBcImNvbG91clwiLFxuICAgICAgICAgICAgXCJzdHJva2Utb3BhY2l0eVwiOiBudSxcbiAgICAgICAgICAgIFwic3Ryb2tlLXdpZHRoXCI6IG51LFxuICAgICAgICAgICAgdHJhbnNmb3JtOiBcInRyYW5zZm9ybVwiLFxuICAgICAgICAgICAgd2lkdGg6IG51LFxuICAgICAgICAgICAgeDogbnUsXG4gICAgICAgICAgICB5OiBudVxuICAgICAgICB9LFxuICAgICAgICB3aGl0ZXNwYWNlID0gL1tcXHgwOVxceDBhXFx4MGJcXHgwY1xceDBkXFx4MjBcXHhhMFxcdTE2ODBcXHUxODBlXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMGFcXHUyMDJmXFx1MjA1ZlxcdTMwMDBcXHUyMDI4XFx1MjAyOV0vZyxcbiAgICAgICAgY29tbWFTcGFjZXMgPSAvW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSosW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSovLFxuICAgICAgICBoc3JnID0ge2hzOiAxLCByZzogMX0sXG4gICAgICAgIHAycyA9IC8sPyhbYWNobG1xcnN0dnh6XSksPy9naSxcbiAgICAgICAgcGF0aENvbW1hbmQgPSAvKFthY2hsbXJxc3R2el0pW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5LF0qKCgtP1xcZCpcXC4/XFxkKig/OmVbXFwtK10/XFxkKyk/W1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSosP1tcXHgwOVxceDBhXFx4MGJcXHgwY1xceDBkXFx4MjBcXHhhMFxcdTE2ODBcXHUxODBlXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMGFcXHUyMDJmXFx1MjA1ZlxcdTMwMDBcXHUyMDI4XFx1MjAyOV0qKSspL2lnLFxuICAgICAgICB0Q29tbWFuZCA9IC8oW3JzdG1dKVtcXHgwOVxceDBhXFx4MGJcXHgwY1xceDBkXFx4MjBcXHhhMFxcdTE2ODBcXHUxODBlXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMGFcXHUyMDJmXFx1MjA1ZlxcdTMwMDBcXHUyMDI4XFx1MjAyOSxdKigoLT9cXGQqXFwuP1xcZCooPzplW1xcLStdP1xcZCspP1tcXHgwOVxceDBhXFx4MGJcXHgwY1xceDBkXFx4MjBcXHhhMFxcdTE2ODBcXHUxODBlXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMGFcXHUyMDJmXFx1MjA1ZlxcdTMwMDBcXHUyMDI4XFx1MjAyOV0qLD9bXFx4MDlcXHgwYVxceDBiXFx4MGNcXHgwZFxceDIwXFx4YTBcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MjAyOFxcdTIwMjldKikrKS9pZyxcbiAgICAgICAgcGF0aFZhbHVlcyA9IC8oLT9cXGQqXFwuP1xcZCooPzplW1xcLStdP1xcZCspPylbXFx4MDlcXHgwYVxceDBiXFx4MGNcXHgwZFxceDIwXFx4YTBcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MjAyOFxcdTIwMjldKiw/W1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSovaWcsXG4gICAgICAgIHJhZGlhbF9ncmFkaWVudCA9IFIuX3JhZGlhbF9ncmFkaWVudCA9IC9ecig/OlxcKChbXixdKz8pW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSosW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSooW15cXCldKz8pXFwpKT8vLFxuICAgICAgICBlbGRhdGEgPSB7fSxcbiAgICAgICAgc29ydEJ5S2V5ID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBhLmtleSAtIGIua2V5O1xuICAgICAgICB9LFxuICAgICAgICBzb3J0QnlOdW1iZXIgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgcmV0dXJuIHRvRmxvYXQoYSkgLSB0b0Zsb2F0KGIpO1xuICAgICAgICB9LFxuICAgICAgICBmdW4gPSBmdW5jdGlvbiAoKSB7fSxcbiAgICAgICAgcGlwZSA9IGZ1bmN0aW9uICh4KSB7XG4gICAgICAgICAgICByZXR1cm4geDtcbiAgICAgICAgfSxcbiAgICAgICAgcmVjdFBhdGggPSBSLl9yZWN0UGF0aCA9IGZ1bmN0aW9uICh4LCB5LCB3LCBoLCByKSB7XG4gICAgICAgICAgICBpZiAocikge1xuICAgICAgICAgICAgICAgIHJldHVybiBbW1wiTVwiLCB4ICsgciwgeV0sIFtcImxcIiwgdyAtIHIgKiAyLCAwXSwgW1wiYVwiLCByLCByLCAwLCAwLCAxLCByLCByXSwgW1wibFwiLCAwLCBoIC0gciAqIDJdLCBbXCJhXCIsIHIsIHIsIDAsIDAsIDEsIC1yLCByXSwgW1wibFwiLCByICogMiAtIHcsIDBdLCBbXCJhXCIsIHIsIHIsIDAsIDAsIDEsIC1yLCAtcl0sIFtcImxcIiwgMCwgciAqIDIgLSBoXSwgW1wiYVwiLCByLCByLCAwLCAwLCAxLCByLCAtcl0sIFtcInpcIl1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtbXCJNXCIsIHgsIHldLCBbXCJsXCIsIHcsIDBdLCBbXCJsXCIsIDAsIGhdLCBbXCJsXCIsIC13LCAwXSwgW1wielwiXV07XG4gICAgICAgIH0sXG4gICAgICAgIGVsbGlwc2VQYXRoID0gZnVuY3Rpb24gKHgsIHksIHJ4LCByeSkge1xuICAgICAgICAgICAgaWYgKHJ5ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByeSA9IHJ4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtbXCJNXCIsIHgsIHldLCBbXCJtXCIsIDAsIC1yeV0sIFtcImFcIiwgcngsIHJ5LCAwLCAxLCAxLCAwLCAyICogcnldLCBbXCJhXCIsIHJ4LCByeSwgMCwgMSwgMSwgMCwgLTIgKiByeV0sIFtcInpcIl1dO1xuICAgICAgICB9LFxuICAgICAgICBnZXRQYXRoID0gUi5fZ2V0UGF0aCA9IHtcbiAgICAgICAgICAgIHBhdGg6IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbC5hdHRyKFwicGF0aFwiKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjaXJjbGU6IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgIHZhciBhID0gZWwuYXR0cnM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGVsbGlwc2VQYXRoKGEuY3gsIGEuY3ksIGEucik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZWxsaXBzZTogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgdmFyIGEgPSBlbC5hdHRycztcbiAgICAgICAgICAgICAgICByZXR1cm4gZWxsaXBzZVBhdGgoYS5jeCwgYS5jeSwgYS5yeCwgYS5yeSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVjdDogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgdmFyIGEgPSBlbC5hdHRycztcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjdFBhdGgoYS54LCBhLnksIGEud2lkdGgsIGEuaGVpZ2h0LCBhLnIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGltYWdlOiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICB2YXIgYSA9IGVsLmF0dHJzO1xuICAgICAgICAgICAgICAgIHJldHVybiByZWN0UGF0aChhLngsIGEueSwgYS53aWR0aCwgYS5oZWlnaHQpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRleHQ6IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgIHZhciBiYm94ID0gZWwuX2dldEJCb3goKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjdFBhdGgoYmJveC54LCBiYm94LnksIGJib3gud2lkdGgsIGJib3guaGVpZ2h0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgOiBmdW5jdGlvbihlbCkge1xuICAgICAgICAgICAgICAgIHZhciBiYm94ID0gZWwuX2dldEJCb3goKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjdFBhdGgoYmJveC54LCBiYm94LnksIGJib3gud2lkdGgsIGJib3guaGVpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBSYXBoYWVsLm1hcFBhdGhcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFRyYW5zZm9ybSB0aGUgcGF0aCBzdHJpbmcgd2l0aCBnaXZlbiBtYXRyaXguXG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0gcGF0aCAoc3RyaW5nKSBwYXRoIHN0cmluZ1xuICAgICAgICAgLSBtYXRyaXggKG9iamVjdCkgc2VlIEBNYXRyaXhcbiAgICAgICAgID0gKHN0cmluZykgdHJhbnNmb3JtZWQgcGF0aCBzdHJpbmdcbiAgICAgICAgXFwqL1xuICAgICAgICBtYXBQYXRoID0gUi5tYXBQYXRoID0gZnVuY3Rpb24gKHBhdGgsIG1hdHJpeCkge1xuICAgICAgICAgICAgaWYgKCFtYXRyaXgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB4LCB5LCBpLCBqLCBpaSwgamosIHBhdGhpO1xuICAgICAgICAgICAgcGF0aCA9IHBhdGgyY3VydmUocGF0aCk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IHBhdGgubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIHBhdGhpID0gcGF0aFtpXTtcbiAgICAgICAgICAgICAgICBmb3IgKGogPSAxLCBqaiA9IHBhdGhpLmxlbmd0aDsgaiA8IGpqOyBqICs9IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgeCA9IG1hdHJpeC54KHBhdGhpW2pdLCBwYXRoaVtqICsgMV0pO1xuICAgICAgICAgICAgICAgICAgICB5ID0gbWF0cml4LnkocGF0aGlbal0sIHBhdGhpW2ogKyAxXSk7XG4gICAgICAgICAgICAgICAgICAgIHBhdGhpW2pdID0geDtcbiAgICAgICAgICAgICAgICAgICAgcGF0aGlbaiArIDFdID0geTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgICAgfTtcblxuICAgIFIuX2cgPSBnO1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnR5cGVcbiAgICAgWyBwcm9wZXJ0eSAoc3RyaW5nKSBdXG4gICAgICoqXG4gICAgICogQ2FuIGJlIOKAnFNWR+KAnSwg4oCcVk1M4oCdIG9yIGVtcHR5LCBkZXBlbmRpbmcgb24gYnJvd3NlciBzdXBwb3J0LlxuICAgIFxcKi9cbiAgICBSLnR5cGUgPSAoZy53aW4uU1ZHQW5nbGUgfHwgZy5kb2MuaW1wbGVtZW50YXRpb24uaGFzRmVhdHVyZShcImh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjQmFzaWNTdHJ1Y3R1cmVcIiwgXCIxLjFcIikgPyBcIlNWR1wiIDogXCJWTUxcIik7XG4gICAgaWYgKFIudHlwZSA9PSBcIlZNTFwiKSB7XG4gICAgICAgIHZhciBkID0gZy5kb2MuY3JlYXRlRWxlbWVudChcImRpdlwiKSxcbiAgICAgICAgICAgIGI7XG4gICAgICAgIGQuaW5uZXJIVE1MID0gJzx2OnNoYXBlIGFkaj1cIjFcIi8+JztcbiAgICAgICAgYiA9IGQuZmlyc3RDaGlsZDtcbiAgICAgICAgYi5zdHlsZS5iZWhhdmlvciA9IFwidXJsKCNkZWZhdWx0I1ZNTClcIjtcbiAgICAgICAgaWYgKCEoYiAmJiB0eXBlb2YgYi5hZGogPT0gXCJvYmplY3RcIikpIHtcbiAgICAgICAgICAgIHJldHVybiAoUi50eXBlID0gRSk7XG4gICAgICAgIH1cbiAgICAgICAgZCA9IG51bGw7XG4gICAgfVxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnN2Z1xuICAgICBbIHByb3BlcnR5IChib29sZWFuKSBdXG4gICAgICoqXG4gICAgICogYHRydWVgIGlmIGJyb3dzZXIgc3VwcG9ydHMgU1ZHLlxuICAgIFxcKi9cbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC52bWxcbiAgICAgWyBwcm9wZXJ0eSAoYm9vbGVhbikgXVxuICAgICAqKlxuICAgICAqIGB0cnVlYCBpZiBicm93c2VyIHN1cHBvcnRzIFZNTC5cbiAgICBcXCovXG4gICAgUi5zdmcgPSAhKFIudm1sID0gUi50eXBlID09IFwiVk1MXCIpO1xuICAgIFIuX1BhcGVyID0gUGFwZXI7XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZm5cbiAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICoqXG4gICAgICogWW91IGNhbiBhZGQgeW91ciBvd24gbWV0aG9kIHRvIHRoZSBjYW52YXMuIEZvciBleGFtcGxlIGlmIHlvdSB3YW50IHRvIGRyYXcgYSBwaWUgY2hhcnQsXG4gICAgICogeW91IGNhbiBjcmVhdGUgeW91ciBvd24gcGllIGNoYXJ0IGZ1bmN0aW9uIGFuZCBzaGlwIGl0IGFzIGEgUmFwaGHDq2wgcGx1Z2luLiBUbyBkbyB0aGlzXG4gICAgICogeW91IG5lZWQgdG8gZXh0ZW5kIHRoZSBgUmFwaGFlbC5mbmAgb2JqZWN0LiBZb3Ugc2hvdWxkIG1vZGlmeSB0aGUgYGZuYCBvYmplY3QgYmVmb3JlIGFcbiAgICAgKiBSYXBoYcOrbCBpbnN0YW5jZSBpcyBjcmVhdGVkLCBvdGhlcndpc2UgaXQgd2lsbCB0YWtlIG5vIGVmZmVjdC4gUGxlYXNlIG5vdGUgdGhhdCB0aGVcbiAgICAgKiBhYmlsaXR5IGZvciBuYW1lc3BhY2VkIHBsdWdpbnMgd2FzIHJlbW92ZWQgaW4gUmFwaGFlbCAyLjAuIEl0IGlzIHVwIHRvIHRoZSBwbHVnaW4gdG9cbiAgICAgKiBlbnN1cmUgYW55IG5hbWVzcGFjaW5nIGVuc3VyZXMgcHJvcGVyIGNvbnRleHQuXG4gICAgID4gVXNhZ2VcbiAgICAgfCBSYXBoYWVsLmZuLmFycm93ID0gZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCBzaXplKSB7XG4gICAgIHwgICAgIHJldHVybiB0aGlzLnBhdGgoIC4uLiApO1xuICAgICB8IH07XG4gICAgIHwgLy8gb3IgY3JlYXRlIG5hbWVzcGFjZVxuICAgICB8IFJhcGhhZWwuZm4ubXlzdHVmZiA9IHtcbiAgICAgfCAgICAgYXJyb3c6IGZ1bmN0aW9uICgpIHvigKZ9LFxuICAgICB8ICAgICBzdGFyOiBmdW5jdGlvbiAoKSB74oCmfSxcbiAgICAgfCAgICAgLy8gZXRj4oCmXG4gICAgIHwgfTtcbiAgICAgfCB2YXIgcGFwZXIgPSBSYXBoYWVsKDEwLCAxMCwgNjMwLCA0ODApO1xuICAgICB8IC8vIHRoZW4gdXNlIGl0XG4gICAgIHwgcGFwZXIuYXJyb3coMTAsIDEwLCAzMCwgMzAsIDUpLmF0dHIoe2ZpbGw6IFwiI2YwMFwifSk7XG4gICAgIHwgcGFwZXIubXlzdHVmZi5hcnJvdygpO1xuICAgICB8IHBhcGVyLm15c3R1ZmYuc3RhcigpO1xuICAgIFxcKi9cbiAgICBSLmZuID0gcGFwZXJwcm90byA9IFBhcGVyLnByb3RvdHlwZSA9IFIucHJvdG90eXBlO1xuICAgIFIuX2lkID0gMDtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5pc1xuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogSGFuZGZ1bCBvZiByZXBsYWNlbWVudHMgZm9yIGB0eXBlb2ZgIG9wZXJhdG9yLlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBvICjigKYpIGFueSBvYmplY3Qgb3IgcHJpbWl0aXZlXG4gICAgIC0gdHlwZSAoc3RyaW5nKSBuYW1lIG9mIHRoZSB0eXBlLCBpLmUuIOKAnHN0cmluZ+KAnSwg4oCcZnVuY3Rpb27igJ0sIOKAnG51bWJlcuKAnSwgZXRjLlxuICAgICA9IChib29sZWFuKSBpcyBnaXZlbiB2YWx1ZSBpcyBvZiBnaXZlbiB0eXBlXG4gICAgXFwqL1xuICAgIFIuaXMgPSBmdW5jdGlvbiAobywgdHlwZSkge1xuICAgICAgICB0eXBlID0gbG93ZXJDYXNlLmNhbGwodHlwZSk7XG4gICAgICAgIGlmICh0eXBlID09IFwiZmluaXRlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiAhaXNuYW5baGFzXSgrbyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT0gXCJhcnJheVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gbyBpbnN0YW5jZW9mIEFycmF5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAgKHR5cGUgPT0gXCJudWxsXCIgJiYgbyA9PT0gbnVsbCkgfHxcbiAgICAgICAgICAgICAgICAodHlwZSA9PSB0eXBlb2YgbyAmJiBvICE9PSBudWxsKSB8fFxuICAgICAgICAgICAgICAgICh0eXBlID09IFwib2JqZWN0XCIgJiYgbyA9PT0gT2JqZWN0KG8pKSB8fFxuICAgICAgICAgICAgICAgICh0eXBlID09IFwiYXJyYXlcIiAmJiBBcnJheS5pc0FycmF5ICYmIEFycmF5LmlzQXJyYXkobykpIHx8XG4gICAgICAgICAgICAgICAgb2JqZWN0VG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSkudG9Mb3dlckNhc2UoKSA9PSB0eXBlO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBjbG9uZShvYmopIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmogPT0gXCJmdW5jdGlvblwiIHx8IE9iamVjdChvYmopICE9PSBvYmopIHtcbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlcyA9IG5ldyBvYmouY29uc3RydWN0b3I7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIGlmIChvYmpbaGFzXShrZXkpKSB7XG4gICAgICAgICAgICByZXNba2V5XSA9IGNsb25lKG9ialtrZXldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmFuZ2xlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm5zIGFuZ2xlIGJldHdlZW4gdHdvIG9yIHRocmVlIHBvaW50c1xuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSB4MSAobnVtYmVyKSB4IGNvb3JkIG9mIGZpcnN0IHBvaW50XG4gICAgIC0geTEgKG51bWJlcikgeSBjb29yZCBvZiBmaXJzdCBwb2ludFxuICAgICAtIHgyIChudW1iZXIpIHggY29vcmQgb2Ygc2Vjb25kIHBvaW50XG4gICAgIC0geTIgKG51bWJlcikgeSBjb29yZCBvZiBzZWNvbmQgcG9pbnRcbiAgICAgLSB4MyAobnVtYmVyKSAjb3B0aW9uYWwgeCBjb29yZCBvZiB0aGlyZCBwb2ludFxuICAgICAtIHkzIChudW1iZXIpICNvcHRpb25hbCB5IGNvb3JkIG9mIHRoaXJkIHBvaW50XG4gICAgID0gKG51bWJlcikgYW5nbGUgaW4gZGVncmVlcy5cbiAgICBcXCovXG4gICAgUi5hbmdsZSA9IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKSB7XG4gICAgICAgIGlmICh4MyA9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgeCA9IHgxIC0geDIsXG4gICAgICAgICAgICAgICAgeSA9IHkxIC0geTI7XG4gICAgICAgICAgICBpZiAoIXggJiYgIXkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAoMTgwICsgbWF0aC5hdGFuMigteSwgLXgpICogMTgwIC8gUEkgKyAzNjApICUgMzYwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFIuYW5nbGUoeDEsIHkxLCB4MywgeTMpIC0gUi5hbmdsZSh4MiwgeTIsIHgzLCB5Myk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnJhZFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogVHJhbnNmb3JtIGFuZ2xlIHRvIHJhZGlhbnNcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gZGVnIChudW1iZXIpIGFuZ2xlIGluIGRlZ3JlZXNcbiAgICAgPSAobnVtYmVyKSBhbmdsZSBpbiByYWRpYW5zLlxuICAgIFxcKi9cbiAgICBSLnJhZCA9IGZ1bmN0aW9uIChkZWcpIHtcbiAgICAgICAgcmV0dXJuIGRlZyAlIDM2MCAqIFBJIC8gMTgwO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZGVnXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBUcmFuc2Zvcm0gYW5nbGUgdG8gZGVncmVlc1xuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSByYWQgKG51bWJlcikgYW5nbGUgaW4gcmFkaWFuc1xuICAgICA9IChudW1iZXIpIGFuZ2xlIGluIGRlZ3JlZXMuXG4gICAgXFwqL1xuICAgIFIuZGVnID0gZnVuY3Rpb24gKHJhZCkge1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCAoKHJhZCAqIDE4MCAvIFBJJSAzNjApKiAxMDAwKSAvIDEwMDA7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5zbmFwVG9cbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFNuYXBzIGdpdmVuIHZhbHVlIHRvIGdpdmVuIGdyaWQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIHZhbHVlcyAoYXJyYXl8bnVtYmVyKSBnaXZlbiBhcnJheSBvZiB2YWx1ZXMgb3Igc3RlcCBvZiB0aGUgZ3JpZFxuICAgICAtIHZhbHVlIChudW1iZXIpIHZhbHVlIHRvIGFkanVzdFxuICAgICAtIHRvbGVyYW5jZSAobnVtYmVyKSAjb3B0aW9uYWwgdG9sZXJhbmNlIGZvciBzbmFwcGluZy4gRGVmYXVsdCBpcyBgMTBgLlxuICAgICA9IChudW1iZXIpIGFkanVzdGVkIHZhbHVlLlxuICAgIFxcKi9cbiAgICBSLnNuYXBUbyA9IGZ1bmN0aW9uICh2YWx1ZXMsIHZhbHVlLCB0b2xlcmFuY2UpIHtcbiAgICAgICAgdG9sZXJhbmNlID0gUi5pcyh0b2xlcmFuY2UsIFwiZmluaXRlXCIpID8gdG9sZXJhbmNlIDogMTA7XG4gICAgICAgIGlmIChSLmlzKHZhbHVlcywgYXJyYXkpKSB7XG4gICAgICAgICAgICB2YXIgaSA9IHZhbHVlcy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSBpZiAoYWJzKHZhbHVlc1tpXSAtIHZhbHVlKSA8PSB0b2xlcmFuY2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzID0gK3ZhbHVlcztcbiAgICAgICAgICAgIHZhciByZW0gPSB2YWx1ZSAlIHZhbHVlcztcbiAgICAgICAgICAgIGlmIChyZW0gPCB0b2xlcmFuY2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgLSByZW07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVtID4gdmFsdWVzIC0gdG9sZXJhbmNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlIC0gcmVtICsgdmFsdWVzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuY3JlYXRlVVVJRFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyBSRkM0MTIyLCB2ZXJzaW9uIDQgSURcbiAgICBcXCovXG4gICAgdmFyIGNyZWF0ZVVVSUQgPSBSLmNyZWF0ZVVVSUQgPSAoZnVuY3Rpb24gKHV1aWRSZWdFeCwgdXVpZFJlcGxhY2VyKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJ4eHh4eHh4eC14eHh4LTR4eHgteXh4eC14eHh4eHh4eHh4eHhcIi5yZXBsYWNlKHV1aWRSZWdFeCwgdXVpZFJlcGxhY2VyKS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICB9O1xuICAgIH0pKC9beHldL2csIGZ1bmN0aW9uIChjKSB7XG4gICAgICAgIHZhciByID0gbWF0aC5yYW5kb20oKSAqIDE2IHwgMCxcbiAgICAgICAgICAgIHYgPSBjID09IFwieFwiID8gciA6IChyICYgMyB8IDgpO1xuICAgICAgICByZXR1cm4gdi50b1N0cmluZygxNik7XG4gICAgfSk7XG5cbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5zZXRXaW5kb3dcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFVzZWQgd2hlbiB5b3UgbmVlZCB0byBkcmF3IGluIGAmbHQ7aWZyYW1lPmAuIFN3aXRjaGVkIHdpbmRvdyB0byB0aGUgaWZyYW1lIG9uZS5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gbmV3d2luICh3aW5kb3cpIG5ldyB3aW5kb3cgb2JqZWN0XG4gICAgXFwqL1xuICAgIFIuc2V0V2luZG93ID0gZnVuY3Rpb24gKG5ld3dpbikge1xuICAgICAgICBldmUoXCJyYXBoYWVsLnNldFdpbmRvd1wiLCBSLCBnLndpbiwgbmV3d2luKTtcbiAgICAgICAgZy53aW4gPSBuZXd3aW47XG4gICAgICAgIGcuZG9jID0gZy53aW4uZG9jdW1lbnQ7XG4gICAgICAgIGlmIChSLl9lbmdpbmUuaW5pdFdpbikge1xuICAgICAgICAgICAgUi5fZW5naW5lLmluaXRXaW4oZy53aW4pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICB2YXIgdG9IZXggPSBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgaWYgKFIudm1sKSB7XG4gICAgICAgICAgICAvLyBodHRwOi8vZGVhbi5lZHdhcmRzLm5hbWUvd2VibG9nLzIwMDkvMTAvY29udmVydC1hbnktY29sb3VyLXZhbHVlLXRvLWhleC1pbi1tc2llL1xuICAgICAgICAgICAgdmFyIHRyaW0gPSAvXlxccyt8XFxzKyQvZztcbiAgICAgICAgICAgIHZhciBib2Q7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBkb2N1bSA9IG5ldyBBY3RpdmVYT2JqZWN0KFwiaHRtbGZpbGVcIik7XG4gICAgICAgICAgICAgICAgZG9jdW0ud3JpdGUoXCI8Ym9keT5cIik7XG4gICAgICAgICAgICAgICAgZG9jdW0uY2xvc2UoKTtcbiAgICAgICAgICAgICAgICBib2QgPSBkb2N1bS5ib2R5O1xuICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgICAgYm9kID0gY3JlYXRlUG9wdXAoKS5kb2N1bWVudC5ib2R5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHJhbmdlID0gYm9kLmNyZWF0ZVRleHRSYW5nZSgpO1xuICAgICAgICAgICAgdG9IZXggPSBjYWNoZXIoZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYm9kLnN0eWxlLmNvbG9yID0gU3RyKGNvbG9yKS5yZXBsYWNlKHRyaW0sIEUpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSByYW5nZS5xdWVyeUNvbW1hbmRWYWx1ZShcIkZvcmVDb2xvclwiKTtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAoKHZhbHVlICYgMjU1KSA8PCAxNikgfCAodmFsdWUgJiA2NTI4MCkgfCAoKHZhbHVlICYgMTY3MTE2ODApID4+PiAxNik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIiNcIiArIChcIjAwMDAwMFwiICsgdmFsdWUudG9TdHJpbmcoMTYpKS5zbGljZSgtNik7XG4gICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm5vbmVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBpID0gZy5kb2MuY3JlYXRlRWxlbWVudChcImlcIik7XG4gICAgICAgICAgICBpLnRpdGxlID0gXCJSYXBoYVxceGVibCBDb2xvdXIgUGlja2VyXCI7XG4gICAgICAgICAgICBpLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgIGcuZG9jLmJvZHkuYXBwZW5kQ2hpbGQoaSk7XG4gICAgICAgICAgICB0b0hleCA9IGNhY2hlcihmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgICAgICAgICBpLnN0eWxlLmNvbG9yID0gY29sb3I7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGcuZG9jLmRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGUoaSwgRSkuZ2V0UHJvcGVydHlWYWx1ZShcImNvbG9yXCIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRvSGV4KGNvbG9yKTtcbiAgICB9LFxuICAgIGhzYnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gXCJoc2IoXCIgKyBbdGhpcy5oLCB0aGlzLnMsIHRoaXMuYl0gKyBcIilcIjtcbiAgICB9LFxuICAgIGhzbHRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gXCJoc2woXCIgKyBbdGhpcy5oLCB0aGlzLnMsIHRoaXMubF0gKyBcIilcIjtcbiAgICB9LFxuICAgIHJnYnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oZXg7XG4gICAgfSxcbiAgICBwcmVwYXJlUkdCID0gZnVuY3Rpb24gKHIsIGcsIGIpIHtcbiAgICAgICAgaWYgKGcgPT0gbnVsbCAmJiBSLmlzKHIsIFwib2JqZWN0XCIpICYmIFwiclwiIGluIHIgJiYgXCJnXCIgaW4gciAmJiBcImJcIiBpbiByKSB7XG4gICAgICAgICAgICBiID0gci5iO1xuICAgICAgICAgICAgZyA9IHIuZztcbiAgICAgICAgICAgIHIgPSByLnI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGcgPT0gbnVsbCAmJiBSLmlzKHIsIHN0cmluZykpIHtcbiAgICAgICAgICAgIHZhciBjbHIgPSBSLmdldFJHQihyKTtcbiAgICAgICAgICAgIHIgPSBjbHIucjtcbiAgICAgICAgICAgIGcgPSBjbHIuZztcbiAgICAgICAgICAgIGIgPSBjbHIuYjtcbiAgICAgICAgfVxuICAgICAgICBpZiAociA+IDEgfHwgZyA+IDEgfHwgYiA+IDEpIHtcbiAgICAgICAgICAgIHIgLz0gMjU1O1xuICAgICAgICAgICAgZyAvPSAyNTU7XG4gICAgICAgICAgICBiIC89IDI1NTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbciwgZywgYl07XG4gICAgfSxcbiAgICBwYWNrYWdlUkdCID0gZnVuY3Rpb24gKHIsIGcsIGIsIG8pIHtcbiAgICAgICAgciAqPSAyNTU7XG4gICAgICAgIGcgKj0gMjU1O1xuICAgICAgICBiICo9IDI1NTtcbiAgICAgICAgdmFyIHJnYiA9IHtcbiAgICAgICAgICAgIHI6IHIsXG4gICAgICAgICAgICBnOiBnLFxuICAgICAgICAgICAgYjogYixcbiAgICAgICAgICAgIGhleDogUi5yZ2IociwgZywgYiksXG4gICAgICAgICAgICB0b1N0cmluZzogcmdidG9TdHJpbmdcbiAgICAgICAgfTtcbiAgICAgICAgUi5pcyhvLCBcImZpbml0ZVwiKSAmJiAocmdiLm9wYWNpdHkgPSBvKTtcbiAgICAgICAgcmV0dXJuIHJnYjtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuY29sb3JcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFBhcnNlcyB0aGUgY29sb3Igc3RyaW5nIGFuZCByZXR1cm5zIG9iamVjdCB3aXRoIGFsbCB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBjb2xvci5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gY2xyIChzdHJpbmcpIGNvbG9yIHN0cmluZyBpbiBvbmUgb2YgdGhlIHN1cHBvcnRlZCBmb3JtYXRzIChzZWUgQFJhcGhhZWwuZ2V0UkdCKVxuICAgICA9IChvYmplY3QpIENvbWJpbmVkIFJHQiAmIEhTQiBvYmplY3QgaW4gZm9ybWF0OlxuICAgICBvIHtcbiAgICAgbyAgICAgciAobnVtYmVyKSByZWQsXG4gICAgIG8gICAgIGcgKG51bWJlcikgZ3JlZW4sXG4gICAgIG8gICAgIGIgKG51bWJlcikgYmx1ZSxcbiAgICAgbyAgICAgaGV4IChzdHJpbmcpIGNvbG9yIGluIEhUTUwvQ1NTIGZvcm1hdDogI+KAouKAouKAouKAouKAouKAoixcbiAgICAgbyAgICAgZXJyb3IgKGJvb2xlYW4pIGB0cnVlYCBpZiBzdHJpbmcgY2Fu4oCZdCBiZSBwYXJzZWQsXG4gICAgIG8gICAgIGggKG51bWJlcikgaHVlLFxuICAgICBvICAgICBzIChudW1iZXIpIHNhdHVyYXRpb24sXG4gICAgIG8gICAgIHYgKG51bWJlcikgdmFsdWUgKGJyaWdodG5lc3MpLFxuICAgICBvICAgICBsIChudW1iZXIpIGxpZ2h0bmVzc1xuICAgICBvIH1cbiAgICBcXCovXG4gICAgUi5jb2xvciA9IGZ1bmN0aW9uIChjbHIpIHtcbiAgICAgICAgdmFyIHJnYjtcbiAgICAgICAgaWYgKFIuaXMoY2xyLCBcIm9iamVjdFwiKSAmJiBcImhcIiBpbiBjbHIgJiYgXCJzXCIgaW4gY2xyICYmIFwiYlwiIGluIGNscikge1xuICAgICAgICAgICAgcmdiID0gUi5oc2IycmdiKGNscik7XG4gICAgICAgICAgICBjbHIuciA9IHJnYi5yO1xuICAgICAgICAgICAgY2xyLmcgPSByZ2IuZztcbiAgICAgICAgICAgIGNsci5iID0gcmdiLmI7XG4gICAgICAgICAgICBjbHIuaGV4ID0gcmdiLmhleDtcbiAgICAgICAgfSBlbHNlIGlmIChSLmlzKGNsciwgXCJvYmplY3RcIikgJiYgXCJoXCIgaW4gY2xyICYmIFwic1wiIGluIGNsciAmJiBcImxcIiBpbiBjbHIpIHtcbiAgICAgICAgICAgIHJnYiA9IFIuaHNsMnJnYihjbHIpO1xuICAgICAgICAgICAgY2xyLnIgPSByZ2IucjtcbiAgICAgICAgICAgIGNsci5nID0gcmdiLmc7XG4gICAgICAgICAgICBjbHIuYiA9IHJnYi5iO1xuICAgICAgICAgICAgY2xyLmhleCA9IHJnYi5oZXg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoUi5pcyhjbHIsIFwic3RyaW5nXCIpKSB7XG4gICAgICAgICAgICAgICAgY2xyID0gUi5nZXRSR0IoY2xyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChSLmlzKGNsciwgXCJvYmplY3RcIikgJiYgXCJyXCIgaW4gY2xyICYmIFwiZ1wiIGluIGNsciAmJiBcImJcIiBpbiBjbHIpIHtcbiAgICAgICAgICAgICAgICByZ2IgPSBSLnJnYjJoc2woY2xyKTtcbiAgICAgICAgICAgICAgICBjbHIuaCA9IHJnYi5oO1xuICAgICAgICAgICAgICAgIGNsci5zID0gcmdiLnM7XG4gICAgICAgICAgICAgICAgY2xyLmwgPSByZ2IubDtcbiAgICAgICAgICAgICAgICByZ2IgPSBSLnJnYjJoc2IoY2xyKTtcbiAgICAgICAgICAgICAgICBjbHIudiA9IHJnYi5iO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjbHIgPSB7aGV4OiBcIm5vbmVcIn07XG4gICAgICAgICAgICAgICAgY2xyLnIgPSBjbHIuZyA9IGNsci5iID0gY2xyLmggPSBjbHIucyA9IGNsci52ID0gY2xyLmwgPSAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjbHIudG9TdHJpbmcgPSByZ2J0b1N0cmluZztcbiAgICAgICAgcmV0dXJuIGNscjtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmhzYjJyZ2JcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIENvbnZlcnRzIEhTQiB2YWx1ZXMgdG8gUkdCIG9iamVjdC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaCAobnVtYmVyKSBodWVcbiAgICAgLSBzIChudW1iZXIpIHNhdHVyYXRpb25cbiAgICAgLSB2IChudW1iZXIpIHZhbHVlIG9yIGJyaWdodG5lc3NcbiAgICAgPSAob2JqZWN0KSBSR0Igb2JqZWN0IGluIGZvcm1hdDpcbiAgICAgbyB7XG4gICAgIG8gICAgIHIgKG51bWJlcikgcmVkLFxuICAgICBvICAgICBnIChudW1iZXIpIGdyZWVuLFxuICAgICBvICAgICBiIChudW1iZXIpIGJsdWUsXG4gICAgIG8gICAgIGhleCAoc3RyaW5nKSBjb2xvciBpbiBIVE1ML0NTUyBmb3JtYXQ6ICPigKLigKLigKLigKLigKLigKJcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIuaHNiMnJnYiA9IGZ1bmN0aW9uIChoLCBzLCB2LCBvKSB7XG4gICAgICAgIGlmICh0aGlzLmlzKGgsIFwib2JqZWN0XCIpICYmIFwiaFwiIGluIGggJiYgXCJzXCIgaW4gaCAmJiBcImJcIiBpbiBoKSB7XG4gICAgICAgICAgICB2ID0gaC5iO1xuICAgICAgICAgICAgcyA9IGgucztcbiAgICAgICAgICAgIG8gPSBoLm87XG4gICAgICAgICAgICBoID0gaC5oO1xuICAgICAgICB9XG4gICAgICAgIGggKj0gMzYwO1xuICAgICAgICB2YXIgUiwgRywgQiwgWCwgQztcbiAgICAgICAgaCA9IChoICUgMzYwKSAvIDYwO1xuICAgICAgICBDID0gdiAqIHM7XG4gICAgICAgIFggPSBDICogKDEgLSBhYnMoaCAlIDIgLSAxKSk7XG4gICAgICAgIFIgPSBHID0gQiA9IHYgLSBDO1xuXG4gICAgICAgIGggPSB+fmg7XG4gICAgICAgIFIgKz0gW0MsIFgsIDAsIDAsIFgsIENdW2hdO1xuICAgICAgICBHICs9IFtYLCBDLCBDLCBYLCAwLCAwXVtoXTtcbiAgICAgICAgQiArPSBbMCwgMCwgWCwgQywgQywgWF1baF07XG4gICAgICAgIHJldHVybiBwYWNrYWdlUkdCKFIsIEcsIEIsIG8pO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuaHNsMnJnYlxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ29udmVydHMgSFNMIHZhbHVlcyB0byBSR0Igb2JqZWN0LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoIChudW1iZXIpIGh1ZVxuICAgICAtIHMgKG51bWJlcikgc2F0dXJhdGlvblxuICAgICAtIGwgKG51bWJlcikgbHVtaW5vc2l0eVxuICAgICA9IChvYmplY3QpIFJHQiBvYmplY3QgaW4gZm9ybWF0OlxuICAgICBvIHtcbiAgICAgbyAgICAgciAobnVtYmVyKSByZWQsXG4gICAgIG8gICAgIGcgKG51bWJlcikgZ3JlZW4sXG4gICAgIG8gICAgIGIgKG51bWJlcikgYmx1ZSxcbiAgICAgbyAgICAgaGV4IChzdHJpbmcpIGNvbG9yIGluIEhUTUwvQ1NTIGZvcm1hdDogI+KAouKAouKAouKAouKAouKAolxuICAgICBvIH1cbiAgICBcXCovXG4gICAgUi5oc2wycmdiID0gZnVuY3Rpb24gKGgsIHMsIGwsIG8pIHtcbiAgICAgICAgaWYgKHRoaXMuaXMoaCwgXCJvYmplY3RcIikgJiYgXCJoXCIgaW4gaCAmJiBcInNcIiBpbiBoICYmIFwibFwiIGluIGgpIHtcbiAgICAgICAgICAgIGwgPSBoLmw7XG4gICAgICAgICAgICBzID0gaC5zO1xuICAgICAgICAgICAgaCA9IGguaDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaCA+IDEgfHwgcyA+IDEgfHwgbCA+IDEpIHtcbiAgICAgICAgICAgIGggLz0gMzYwO1xuICAgICAgICAgICAgcyAvPSAxMDA7XG4gICAgICAgICAgICBsIC89IDEwMDtcbiAgICAgICAgfVxuICAgICAgICBoICo9IDM2MDtcbiAgICAgICAgdmFyIFIsIEcsIEIsIFgsIEM7XG4gICAgICAgIGggPSAoaCAlIDM2MCkgLyA2MDtcbiAgICAgICAgQyA9IDIgKiBzICogKGwgPCAuNSA/IGwgOiAxIC0gbCk7XG4gICAgICAgIFggPSBDICogKDEgLSBhYnMoaCAlIDIgLSAxKSk7XG4gICAgICAgIFIgPSBHID0gQiA9IGwgLSBDIC8gMjtcblxuICAgICAgICBoID0gfn5oO1xuICAgICAgICBSICs9IFtDLCBYLCAwLCAwLCBYLCBDXVtoXTtcbiAgICAgICAgRyArPSBbWCwgQywgQywgWCwgMCwgMF1baF07XG4gICAgICAgIEIgKz0gWzAsIDAsIFgsIEMsIEMsIFhdW2hdO1xuICAgICAgICByZXR1cm4gcGFja2FnZVJHQihSLCBHLCBCLCBvKTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnJnYjJoc2JcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIENvbnZlcnRzIFJHQiB2YWx1ZXMgdG8gSFNCIG9iamVjdC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gciAobnVtYmVyKSByZWRcbiAgICAgLSBnIChudW1iZXIpIGdyZWVuXG4gICAgIC0gYiAobnVtYmVyKSBibHVlXG4gICAgID0gKG9iamVjdCkgSFNCIG9iamVjdCBpbiBmb3JtYXQ6XG4gICAgIG8ge1xuICAgICBvICAgICBoIChudW1iZXIpIGh1ZVxuICAgICBvICAgICBzIChudW1iZXIpIHNhdHVyYXRpb25cbiAgICAgbyAgICAgYiAobnVtYmVyKSBicmlnaHRuZXNzXG4gICAgIG8gfVxuICAgIFxcKi9cbiAgICBSLnJnYjJoc2IgPSBmdW5jdGlvbiAociwgZywgYikge1xuICAgICAgICBiID0gcHJlcGFyZVJHQihyLCBnLCBiKTtcbiAgICAgICAgciA9IGJbMF07XG4gICAgICAgIGcgPSBiWzFdO1xuICAgICAgICBiID0gYlsyXTtcblxuICAgICAgICB2YXIgSCwgUywgViwgQztcbiAgICAgICAgViA9IG1tYXgociwgZywgYik7XG4gICAgICAgIEMgPSBWIC0gbW1pbihyLCBnLCBiKTtcbiAgICAgICAgSCA9IChDID09IDAgPyBudWxsIDpcbiAgICAgICAgICAgICBWID09IHIgPyAoZyAtIGIpIC8gQyA6XG4gICAgICAgICAgICAgViA9PSBnID8gKGIgLSByKSAvIEMgKyAyIDpcbiAgICAgICAgICAgICAgICAgICAgICAociAtIGcpIC8gQyArIDRcbiAgICAgICAgICAgICk7XG4gICAgICAgIEggPSAoKEggKyAzNjApICUgNikgKiA2MCAvIDM2MDtcbiAgICAgICAgUyA9IEMgPT0gMCA/IDAgOiBDIC8gVjtcbiAgICAgICAgcmV0dXJuIHtoOiBILCBzOiBTLCBiOiBWLCB0b1N0cmluZzogaHNidG9TdHJpbmd9O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwucmdiMmhzbFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ29udmVydHMgUkdCIHZhbHVlcyB0byBIU0wgb2JqZWN0LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSByIChudW1iZXIpIHJlZFxuICAgICAtIGcgKG51bWJlcikgZ3JlZW5cbiAgICAgLSBiIChudW1iZXIpIGJsdWVcbiAgICAgPSAob2JqZWN0KSBIU0wgb2JqZWN0IGluIGZvcm1hdDpcbiAgICAgbyB7XG4gICAgIG8gICAgIGggKG51bWJlcikgaHVlXG4gICAgIG8gICAgIHMgKG51bWJlcikgc2F0dXJhdGlvblxuICAgICBvICAgICBsIChudW1iZXIpIGx1bWlub3NpdHlcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIucmdiMmhzbCA9IGZ1bmN0aW9uIChyLCBnLCBiKSB7XG4gICAgICAgIGIgPSBwcmVwYXJlUkdCKHIsIGcsIGIpO1xuICAgICAgICByID0gYlswXTtcbiAgICAgICAgZyA9IGJbMV07XG4gICAgICAgIGIgPSBiWzJdO1xuXG4gICAgICAgIHZhciBILCBTLCBMLCBNLCBtLCBDO1xuICAgICAgICBNID0gbW1heChyLCBnLCBiKTtcbiAgICAgICAgbSA9IG1taW4ociwgZywgYik7XG4gICAgICAgIEMgPSBNIC0gbTtcbiAgICAgICAgSCA9IChDID09IDAgPyBudWxsIDpcbiAgICAgICAgICAgICBNID09IHIgPyAoZyAtIGIpIC8gQyA6XG4gICAgICAgICAgICAgTSA9PSBnID8gKGIgLSByKSAvIEMgKyAyIDpcbiAgICAgICAgICAgICAgICAgICAgICAociAtIGcpIC8gQyArIDQpO1xuICAgICAgICBIID0gKChIICsgMzYwKSAlIDYpICogNjAgLyAzNjA7XG4gICAgICAgIEwgPSAoTSArIG0pIC8gMjtcbiAgICAgICAgUyA9IChDID09IDAgPyAwIDpcbiAgICAgICAgICAgICBMIDwgLjUgPyBDIC8gKDIgKiBMKSA6XG4gICAgICAgICAgICAgICAgICAgICAgQyAvICgyIC0gMiAqIEwpKTtcbiAgICAgICAgcmV0dXJuIHtoOiBILCBzOiBTLCBsOiBMLCB0b1N0cmluZzogaHNsdG9TdHJpbmd9O1xuICAgIH07XG4gICAgUi5fcGF0aDJzdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmpvaW4oXCIsXCIpLnJlcGxhY2UocDJzLCBcIiQxXCIpO1xuICAgIH07XG4gICAgZnVuY3Rpb24gcmVwdXNoKGFycmF5LCBpdGVtKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGFycmF5Lmxlbmd0aDsgaSA8IGlpOyBpKyspIGlmIChhcnJheVtpXSA9PT0gaXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIGFycmF5LnB1c2goYXJyYXkuc3BsaWNlKGksIDEpWzBdKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBjYWNoZXIoZiwgc2NvcGUsIHBvc3Rwcm9jZXNzb3IpIHtcbiAgICAgICAgZnVuY3Rpb24gbmV3ZigpIHtcbiAgICAgICAgICAgIHZhciBhcmcgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApLFxuICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmcuam9pbihcIlxcdTI0MDBcIiksXG4gICAgICAgICAgICAgICAgY2FjaGUgPSBuZXdmLmNhY2hlID0gbmV3Zi5jYWNoZSB8fCB7fSxcbiAgICAgICAgICAgICAgICBjb3VudCA9IG5ld2YuY291bnQgPSBuZXdmLmNvdW50IHx8IFtdO1xuICAgICAgICAgICAgaWYgKGNhY2hlW2hhc10oYXJncykpIHtcbiAgICAgICAgICAgICAgICByZXB1c2goY291bnQsIGFyZ3MpO1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3N0cHJvY2Vzc29yID8gcG9zdHByb2Nlc3NvcihjYWNoZVthcmdzXSkgOiBjYWNoZVthcmdzXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvdW50Lmxlbmd0aCA+PSAxZTMgJiYgZGVsZXRlIGNhY2hlW2NvdW50LnNoaWZ0KCldO1xuICAgICAgICAgICAgY291bnQucHVzaChhcmdzKTtcbiAgICAgICAgICAgIGNhY2hlW2FyZ3NdID0gZlthcHBseV0oc2NvcGUsIGFyZyk7XG4gICAgICAgICAgICByZXR1cm4gcG9zdHByb2Nlc3NvciA/IHBvc3Rwcm9jZXNzb3IoY2FjaGVbYXJnc10pIDogY2FjaGVbYXJnc107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ld2Y7XG4gICAgfVxuXG4gICAgdmFyIHByZWxvYWQgPSBSLl9wcmVsb2FkID0gZnVuY3Rpb24gKHNyYywgZikge1xuICAgICAgICB2YXIgaW1nID0gZy5kb2MuY3JlYXRlRWxlbWVudChcImltZ1wiKTtcbiAgICAgICAgaW1nLnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOmFic29sdXRlO2xlZnQ6LTk5OTllbTt0b3A6LTk5OTllbVwiO1xuICAgICAgICBpbWcub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZi5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5vbmxvYWQgPSBudWxsO1xuICAgICAgICAgICAgZy5kb2MuYm9keS5yZW1vdmVDaGlsZCh0aGlzKTtcbiAgICAgICAgfTtcbiAgICAgICAgaW1nLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnLmRvYy5ib2R5LnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgICAgICB9O1xuICAgICAgICBnLmRvYy5ib2R5LmFwcGVuZENoaWxkKGltZyk7XG4gICAgICAgIGltZy5zcmMgPSBzcmM7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGNsclRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oZXg7XG4gICAgfVxuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZ2V0UkdCXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBQYXJzZXMgY29sb3VyIHN0cmluZyBhcyBSR0Igb2JqZWN0XG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGNvbG91ciAoc3RyaW5nKSBjb2xvdXIgc3RyaW5nIGluIG9uZSBvZiBmb3JtYXRzOlxuICAgICAjIDx1bD5cbiAgICAgIyAgICAgPGxpPkNvbG91ciBuYW1lICjigJw8Y29kZT5yZWQ8L2NvZGU+4oCdLCDigJw8Y29kZT5ncmVlbjwvY29kZT7igJ0sIOKAnDxjb2RlPmNvcm5mbG93ZXJibHVlPC9jb2RlPuKAnSwgZXRjKTwvbGk+XG4gICAgICMgICAgIDxsaT4j4oCi4oCi4oCiIOKAlCBzaG9ydGVuZWQgSFRNTCBjb2xvdXI6ICjigJw8Y29kZT4jMDAwPC9jb2RlPuKAnSwg4oCcPGNvZGU+I2ZjMDwvY29kZT7igJ0sIGV0Yyk8L2xpPlxuICAgICAjICAgICA8bGk+I+KAouKAouKAouKAouKAouKAoiDigJQgZnVsbCBsZW5ndGggSFRNTCBjb2xvdXI6ICjigJw8Y29kZT4jMDAwMDAwPC9jb2RlPuKAnSwg4oCcPGNvZGU+I2JkMjMwMDwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPnJnYijigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiKSDigJQgcmVkLCBncmVlbiBhbmQgYmx1ZSBjaGFubmVsc+KAmSB2YWx1ZXM6ICjigJw8Y29kZT5yZ2IoMjAwLCZuYnNwOzEwMCwmbmJzcDswKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPnJnYijigKLigKLigKIlLCDigKLigKLigKIlLCDigKLigKLigKIlKSDigJQgc2FtZSBhcyBhYm92ZSwgYnV0IGluICU6ICjigJw8Y29kZT5yZ2IoMTAwJSwmbmJzcDsxNzUlLCZuYnNwOzAlKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPmhzYijigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiKSDigJQgaHVlLCBzYXR1cmF0aW9uIGFuZCBicmlnaHRuZXNzIHZhbHVlczogKOKAnDxjb2RlPmhzYigwLjUsJm5ic3A7MC4yNSwmbmJzcDsxKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPmhzYijigKLigKLigKIlLCDigKLigKLigKIlLCDigKLigKLigKIlKSDigJQgc2FtZSBhcyBhYm92ZSwgYnV0IGluICU8L2xpPlxuICAgICAjICAgICA8bGk+aHNsKOKAouKAouKAoiwg4oCi4oCi4oCiLCDigKLigKLigKIpIOKAlCBzYW1lIGFzIGhzYjwvbGk+XG4gICAgICMgICAgIDxsaT5oc2wo4oCi4oCi4oCiJSwg4oCi4oCi4oCiJSwg4oCi4oCi4oCiJSkg4oCUIHNhbWUgYXMgaHNiPC9saT5cbiAgICAgIyA8L3VsPlxuICAgICA9IChvYmplY3QpIFJHQiBvYmplY3QgaW4gZm9ybWF0OlxuICAgICBvIHtcbiAgICAgbyAgICAgciAobnVtYmVyKSByZWQsXG4gICAgIG8gICAgIGcgKG51bWJlcikgZ3JlZW4sXG4gICAgIG8gICAgIGIgKG51bWJlcikgYmx1ZVxuICAgICBvICAgICBoZXggKHN0cmluZykgY29sb3IgaW4gSFRNTC9DU1MgZm9ybWF0OiAj4oCi4oCi4oCi4oCi4oCi4oCiLFxuICAgICBvICAgICBlcnJvciAoYm9vbGVhbikgdHJ1ZSBpZiBzdHJpbmcgY2Fu4oCZdCBiZSBwYXJzZWRcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIuZ2V0UkdCID0gY2FjaGVyKGZ1bmN0aW9uIChjb2xvdXIpIHtcbiAgICAgICAgaWYgKCFjb2xvdXIgfHwgISEoKGNvbG91ciA9IFN0cihjb2xvdXIpKS5pbmRleE9mKFwiLVwiKSArIDEpKSB7XG4gICAgICAgICAgICByZXR1cm4ge3I6IC0xLCBnOiAtMSwgYjogLTEsIGhleDogXCJub25lXCIsIGVycm9yOiAxLCB0b1N0cmluZzogY2xyVG9TdHJpbmd9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb2xvdXIgPT0gXCJub25lXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB7cjogLTEsIGc6IC0xLCBiOiAtMSwgaGV4OiBcIm5vbmVcIiwgdG9TdHJpbmc6IGNsclRvU3RyaW5nfTtcbiAgICAgICAgfVxuICAgICAgICAhKGhzcmdbaGFzXShjb2xvdXIudG9Mb3dlckNhc2UoKS5zdWJzdHJpbmcoMCwgMikpIHx8IGNvbG91ci5jaGFyQXQoKSA9PSBcIiNcIikgJiYgKGNvbG91ciA9IHRvSGV4KGNvbG91cikpO1xuICAgICAgICB2YXIgcmVzLFxuICAgICAgICAgICAgcmVkLFxuICAgICAgICAgICAgZ3JlZW4sXG4gICAgICAgICAgICBibHVlLFxuICAgICAgICAgICAgb3BhY2l0eSxcbiAgICAgICAgICAgIHQsXG4gICAgICAgICAgICB2YWx1ZXMsXG4gICAgICAgICAgICByZ2IgPSBjb2xvdXIubWF0Y2goY29sb3VyUmVnRXhwKTtcbiAgICAgICAgaWYgKHJnYikge1xuICAgICAgICAgICAgaWYgKHJnYlsyXSkge1xuICAgICAgICAgICAgICAgIGJsdWUgPSB0b0ludChyZ2JbMl0uc3Vic3RyaW5nKDUpLCAxNik7XG4gICAgICAgICAgICAgICAgZ3JlZW4gPSB0b0ludChyZ2JbMl0uc3Vic3RyaW5nKDMsIDUpLCAxNik7XG4gICAgICAgICAgICAgICAgcmVkID0gdG9JbnQocmdiWzJdLnN1YnN0cmluZygxLCAzKSwgMTYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJnYlszXSkge1xuICAgICAgICAgICAgICAgIGJsdWUgPSB0b0ludCgodCA9IHJnYlszXS5jaGFyQXQoMykpICsgdCwgMTYpO1xuICAgICAgICAgICAgICAgIGdyZWVuID0gdG9JbnQoKHQgPSByZ2JbM10uY2hhckF0KDIpKSArIHQsIDE2KTtcbiAgICAgICAgICAgICAgICByZWQgPSB0b0ludCgodCA9IHJnYlszXS5jaGFyQXQoMSkpICsgdCwgMTYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJnYls0XSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcyA9IHJnYls0XVtzcGxpdF0oY29tbWFTcGFjZXMpO1xuICAgICAgICAgICAgICAgIHJlZCA9IHRvRmxvYXQodmFsdWVzWzBdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMF0uc2xpY2UoLTEpID09IFwiJVwiICYmIChyZWQgKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgZ3JlZW4gPSB0b0Zsb2F0KHZhbHVlc1sxXSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzFdLnNsaWNlKC0xKSA9PSBcIiVcIiAmJiAoZ3JlZW4gKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgYmx1ZSA9IHRvRmxvYXQodmFsdWVzWzJdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMl0uc2xpY2UoLTEpID09IFwiJVwiICYmIChibHVlICo9IDIuNTUpO1xuICAgICAgICAgICAgICAgIHJnYlsxXS50b0xvd2VyQ2FzZSgpLnNsaWNlKDAsIDQpID09IFwicmdiYVwiICYmIChvcGFjaXR5ID0gdG9GbG9hdCh2YWx1ZXNbM10pKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbM10gJiYgdmFsdWVzWzNdLnNsaWNlKC0xKSA9PSBcIiVcIiAmJiAob3BhY2l0eSAvPSAxMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJnYls1XSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcyA9IHJnYls1XVtzcGxpdF0oY29tbWFTcGFjZXMpO1xuICAgICAgICAgICAgICAgIHJlZCA9IHRvRmxvYXQodmFsdWVzWzBdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMF0uc2xpY2UoLTEpID09IFwiJVwiICYmIChyZWQgKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgZ3JlZW4gPSB0b0Zsb2F0KHZhbHVlc1sxXSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzFdLnNsaWNlKC0xKSA9PSBcIiVcIiAmJiAoZ3JlZW4gKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgYmx1ZSA9IHRvRmxvYXQodmFsdWVzWzJdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMl0uc2xpY2UoLTEpID09IFwiJVwiICYmIChibHVlICo9IDIuNTUpO1xuICAgICAgICAgICAgICAgICh2YWx1ZXNbMF0uc2xpY2UoLTMpID09IFwiZGVnXCIgfHwgdmFsdWVzWzBdLnNsaWNlKC0xKSA9PSBcIlxceGIwXCIpICYmIChyZWQgLz0gMzYwKTtcbiAgICAgICAgICAgICAgICByZ2JbMV0udG9Mb3dlckNhc2UoKS5zbGljZSgwLCA0KSA9PSBcImhzYmFcIiAmJiAob3BhY2l0eSA9IHRvRmxvYXQodmFsdWVzWzNdKSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzNdICYmIHZhbHVlc1szXS5zbGljZSgtMSkgPT0gXCIlXCIgJiYgKG9wYWNpdHkgLz0gMTAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gUi5oc2IycmdiKHJlZCwgZ3JlZW4sIGJsdWUsIG9wYWNpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJnYls2XSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcyA9IHJnYls2XVtzcGxpdF0oY29tbWFTcGFjZXMpO1xuICAgICAgICAgICAgICAgIHJlZCA9IHRvRmxvYXQodmFsdWVzWzBdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMF0uc2xpY2UoLTEpID09IFwiJVwiICYmIChyZWQgKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgZ3JlZW4gPSB0b0Zsb2F0KHZhbHVlc1sxXSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzFdLnNsaWNlKC0xKSA9PSBcIiVcIiAmJiAoZ3JlZW4gKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgYmx1ZSA9IHRvRmxvYXQodmFsdWVzWzJdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMl0uc2xpY2UoLTEpID09IFwiJVwiICYmIChibHVlICo9IDIuNTUpO1xuICAgICAgICAgICAgICAgICh2YWx1ZXNbMF0uc2xpY2UoLTMpID09IFwiZGVnXCIgfHwgdmFsdWVzWzBdLnNsaWNlKC0xKSA9PSBcIlxceGIwXCIpICYmIChyZWQgLz0gMzYwKTtcbiAgICAgICAgICAgICAgICByZ2JbMV0udG9Mb3dlckNhc2UoKS5zbGljZSgwLCA0KSA9PSBcImhzbGFcIiAmJiAob3BhY2l0eSA9IHRvRmxvYXQodmFsdWVzWzNdKSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzNdICYmIHZhbHVlc1szXS5zbGljZSgtMSkgPT0gXCIlXCIgJiYgKG9wYWNpdHkgLz0gMTAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gUi5oc2wycmdiKHJlZCwgZ3JlZW4sIGJsdWUsIG9wYWNpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmdiID0ge3I6IHJlZCwgZzogZ3JlZW4sIGI6IGJsdWUsIHRvU3RyaW5nOiBjbHJUb1N0cmluZ307XG4gICAgICAgICAgICByZ2IuaGV4ID0gXCIjXCIgKyAoMTY3NzcyMTYgfCBibHVlIHwgKGdyZWVuIDw8IDgpIHwgKHJlZCA8PCAxNikpLnRvU3RyaW5nKDE2KS5zbGljZSgxKTtcbiAgICAgICAgICAgIFIuaXMob3BhY2l0eSwgXCJmaW5pdGVcIikgJiYgKHJnYi5vcGFjaXR5ID0gb3BhY2l0eSk7XG4gICAgICAgICAgICByZXR1cm4gcmdiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7cjogLTEsIGc6IC0xLCBiOiAtMSwgaGV4OiBcIm5vbmVcIiwgZXJyb3I6IDEsIHRvU3RyaW5nOiBjbHJUb1N0cmluZ307XG4gICAgfSwgUik7XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuaHNiXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDb252ZXJ0cyBIU0IgdmFsdWVzIHRvIGhleCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29sb3VyLlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoIChudW1iZXIpIGh1ZVxuICAgICAtIHMgKG51bWJlcikgc2F0dXJhdGlvblxuICAgICAtIGIgKG51bWJlcikgdmFsdWUgb3IgYnJpZ2h0bmVzc1xuICAgICA9IChzdHJpbmcpIGhleCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29sb3VyLlxuICAgIFxcKi9cbiAgICBSLmhzYiA9IGNhY2hlcihmdW5jdGlvbiAoaCwgcywgYikge1xuICAgICAgICByZXR1cm4gUi5oc2IycmdiKGgsIHMsIGIpLmhleDtcbiAgICB9KTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5oc2xcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIENvbnZlcnRzIEhTTCB2YWx1ZXMgdG8gaGV4IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb2xvdXIuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGggKG51bWJlcikgaHVlXG4gICAgIC0gcyAobnVtYmVyKSBzYXR1cmF0aW9uXG4gICAgIC0gbCAobnVtYmVyKSBsdW1pbm9zaXR5XG4gICAgID0gKHN0cmluZykgaGV4IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb2xvdXIuXG4gICAgXFwqL1xuICAgIFIuaHNsID0gY2FjaGVyKGZ1bmN0aW9uIChoLCBzLCBsKSB7XG4gICAgICAgIHJldHVybiBSLmhzbDJyZ2IoaCwgcywgbCkuaGV4O1xuICAgIH0pO1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnJnYlxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ29udmVydHMgUkdCIHZhbHVlcyB0byBoZXggcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbG91ci5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gciAobnVtYmVyKSByZWRcbiAgICAgLSBnIChudW1iZXIpIGdyZWVuXG4gICAgIC0gYiAobnVtYmVyKSBibHVlXG4gICAgID0gKHN0cmluZykgaGV4IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb2xvdXIuXG4gICAgXFwqL1xuICAgIFIucmdiID0gY2FjaGVyKGZ1bmN0aW9uIChyLCBnLCBiKSB7XG4gICAgICAgIGZ1bmN0aW9uIHJvdW5kKHgpIHsgcmV0dXJuICh4ICsgMC41KSB8IDA7IH1cbiAgICAgICAgcmV0dXJuIFwiI1wiICsgKDE2Nzc3MjE2IHwgcm91bmQoYikgfCAocm91bmQoZykgPDwgOCkgfCAocm91bmQocikgPDwgMTYpKS50b1N0cmluZygxNikuc2xpY2UoMSk7XG4gICAgfSk7XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZ2V0Q29sb3JcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIE9uIGVhY2ggY2FsbCByZXR1cm5zIG5leHQgY29sb3VyIGluIHRoZSBzcGVjdHJ1bS4gVG8gcmVzZXQgaXQgYmFjayB0byByZWQgY2FsbCBAUmFwaGFlbC5nZXRDb2xvci5yZXNldFxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSB2YWx1ZSAobnVtYmVyKSAjb3B0aW9uYWwgYnJpZ2h0bmVzcywgZGVmYXVsdCBpcyBgMC43NWBcbiAgICAgPSAoc3RyaW5nKSBoZXggcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbG91ci5cbiAgICBcXCovXG4gICAgUi5nZXRDb2xvciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmdldENvbG9yLnN0YXJ0ID0gdGhpcy5nZXRDb2xvci5zdGFydCB8fCB7aDogMCwgczogMSwgYjogdmFsdWUgfHwgLjc1fSxcbiAgICAgICAgICAgIHJnYiA9IHRoaXMuaHNiMnJnYihzdGFydC5oLCBzdGFydC5zLCBzdGFydC5iKTtcbiAgICAgICAgc3RhcnQuaCArPSAuMDc1O1xuICAgICAgICBpZiAoc3RhcnQuaCA+IDEpIHtcbiAgICAgICAgICAgIHN0YXJ0LmggPSAwO1xuICAgICAgICAgICAgc3RhcnQucyAtPSAuMjtcbiAgICAgICAgICAgIHN0YXJ0LnMgPD0gMCAmJiAodGhpcy5nZXRDb2xvci5zdGFydCA9IHtoOiAwLCBzOiAxLCBiOiBzdGFydC5ifSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJnYi5oZXg7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5nZXRDb2xvci5yZXNldFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVzZXRzIHNwZWN0cnVtIHBvc2l0aW9uIGZvciBAUmFwaGFlbC5nZXRDb2xvciBiYWNrIHRvIHJlZC5cbiAgICBcXCovXG4gICAgUi5nZXRDb2xvci5yZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuc3RhcnQ7XG4gICAgfTtcblxuICAgIC8vIGh0dHA6Ly9zY2hlcGVycy5jYy9nZXR0aW5nLXRvLXRoZS1wb2ludFxuICAgIGZ1bmN0aW9uIGNhdG11bGxSb20yYmV6aWVyKGNycCwgeikge1xuICAgICAgICB2YXIgZCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgaUxlbiA9IGNycC5sZW5ndGg7IGlMZW4gLSAyICogIXogPiBpOyBpICs9IDIpIHtcbiAgICAgICAgICAgIHZhciBwID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAge3g6ICtjcnBbaSAtIDJdLCB5OiArY3JwW2kgLSAxXX0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7eDogK2NycFtpXSwgICAgIHk6ICtjcnBbaSArIDFdfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHt4OiArY3JwW2kgKyAyXSwgeTogK2NycFtpICsgM119LFxuICAgICAgICAgICAgICAgICAgICAgICAge3g6ICtjcnBbaSArIDRdLCB5OiArY3JwW2kgKyA1XX1cbiAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIGlmICh6KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpKSB7XG4gICAgICAgICAgICAgICAgICAgIHBbMF0gPSB7eDogK2NycFtpTGVuIC0gMl0sIHk6ICtjcnBbaUxlbiAtIDFdfTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlMZW4gLSA0ID09IGkpIHtcbiAgICAgICAgICAgICAgICAgICAgcFszXSA9IHt4OiArY3JwWzBdLCB5OiArY3JwWzFdfTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlMZW4gLSAyID09IGkpIHtcbiAgICAgICAgICAgICAgICAgICAgcFsyXSA9IHt4OiArY3JwWzBdLCB5OiArY3JwWzFdfTtcbiAgICAgICAgICAgICAgICAgICAgcFszXSA9IHt4OiArY3JwWzJdLCB5OiArY3JwWzNdfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChpTGVuIC0gNCA9PSBpKSB7XG4gICAgICAgICAgICAgICAgICAgIHBbM10gPSBwWzJdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWkpIHtcbiAgICAgICAgICAgICAgICAgICAgcFswXSA9IHt4OiArY3JwW2ldLCB5OiArY3JwW2kgKyAxXX07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZC5wdXNoKFtcIkNcIixcbiAgICAgICAgICAgICAgICAgICgtcFswXS54ICsgNiAqIHBbMV0ueCArIHBbMl0ueCkgLyA2LFxuICAgICAgICAgICAgICAgICAgKC1wWzBdLnkgKyA2ICogcFsxXS55ICsgcFsyXS55KSAvIDYsXG4gICAgICAgICAgICAgICAgICAocFsxXS54ICsgNiAqIHBbMl0ueCAtIHBbM10ueCkgLyA2LFxuICAgICAgICAgICAgICAgICAgKHBbMV0ueSArIDYqcFsyXS55IC0gcFszXS55KSAvIDYsXG4gICAgICAgICAgICAgICAgICBwWzJdLngsXG4gICAgICAgICAgICAgICAgICBwWzJdLnlcbiAgICAgICAgICAgIF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGQ7XG4gICAgfVxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnBhcnNlUGF0aFN0cmluZ1xuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogVXRpbGl0eSBtZXRob2RcbiAgICAgKipcbiAgICAgKiBQYXJzZXMgZ2l2ZW4gcGF0aCBzdHJpbmcgaW50byBhbiBhcnJheSBvZiBhcnJheXMgb2YgcGF0aCBzZWdtZW50cy5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gcGF0aFN0cmluZyAoc3RyaW5nfGFycmF5KSBwYXRoIHN0cmluZyBvciBhcnJheSBvZiBzZWdtZW50cyAoaW4gdGhlIGxhc3QgY2FzZSBpdCB3aWxsIGJlIHJldHVybmVkIHN0cmFpZ2h0IGF3YXkpXG4gICAgID0gKGFycmF5KSBhcnJheSBvZiBzZWdtZW50cy5cbiAgICBcXCovXG4gICAgUi5wYXJzZVBhdGhTdHJpbmcgPSBmdW5jdGlvbiAocGF0aFN0cmluZykge1xuICAgICAgICBpZiAoIXBhdGhTdHJpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwdGggPSBwYXRocyhwYXRoU3RyaW5nKTtcbiAgICAgICAgaWYgKHB0aC5hcnIpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXRoQ2xvbmUocHRoLmFycik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcGFyYW1Db3VudHMgPSB7YTogNywgYzogNiwgaDogMSwgbDogMiwgbTogMiwgcjogNCwgcTogNCwgczogNCwgdDogMiwgdjogMSwgejogMH0sXG4gICAgICAgICAgICBkYXRhID0gW107XG4gICAgICAgIGlmIChSLmlzKHBhdGhTdHJpbmcsIGFycmF5KSAmJiBSLmlzKHBhdGhTdHJpbmdbMF0sIGFycmF5KSkgeyAvLyByb3VnaCBhc3N1bXB0aW9uXG4gICAgICAgICAgICBkYXRhID0gcGF0aENsb25lKHBhdGhTdHJpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgIFN0cihwYXRoU3RyaW5nKS5yZXBsYWNlKHBhdGhDb21tYW5kLCBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgICAgICAgICAgIHZhciBwYXJhbXMgPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGIudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICBjLnJlcGxhY2UocGF0aFZhbHVlcywgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgICAgICAgICAgYiAmJiBwYXJhbXMucHVzaCgrYik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKG5hbWUgPT0gXCJtXCIgJiYgcGFyYW1zLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5wdXNoKFtiXVtjb25jYXRdKHBhcmFtcy5zcGxpY2UoMCwgMikpKTtcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IFwibFwiO1xuICAgICAgICAgICAgICAgICAgICBiID0gYiA9PSBcIm1cIiA/IFwibFwiIDogXCJMXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuYW1lID09IFwiclwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEucHVzaChbYl1bY29uY2F0XShwYXJhbXMpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Ugd2hpbGUgKHBhcmFtcy5sZW5ndGggPj0gcGFyYW1Db3VudHNbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5wdXNoKFtiXVtjb25jYXRdKHBhcmFtcy5zcGxpY2UoMCwgcGFyYW1Db3VudHNbbmFtZV0pKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFyYW1Db3VudHNbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YS50b1N0cmluZyA9IFIuX3BhdGgyc3RyaW5nO1xuICAgICAgICBwdGguYXJyID0gcGF0aENsb25lKGRhdGEpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnBhcnNlVHJhbnNmb3JtU3RyaW5nXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBVdGlsaXR5IG1ldGhvZFxuICAgICAqKlxuICAgICAqIFBhcnNlcyBnaXZlbiBwYXRoIHN0cmluZyBpbnRvIGFuIGFycmF5IG9mIHRyYW5zZm9ybWF0aW9ucy5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gVFN0cmluZyAoc3RyaW5nfGFycmF5KSB0cmFuc2Zvcm0gc3RyaW5nIG9yIGFycmF5IG9mIHRyYW5zZm9ybWF0aW9ucyAoaW4gdGhlIGxhc3QgY2FzZSBpdCB3aWxsIGJlIHJldHVybmVkIHN0cmFpZ2h0IGF3YXkpXG4gICAgID0gKGFycmF5KSBhcnJheSBvZiB0cmFuc2Zvcm1hdGlvbnMuXG4gICAgXFwqL1xuICAgIFIucGFyc2VUcmFuc2Zvcm1TdHJpbmcgPSBjYWNoZXIoZnVuY3Rpb24gKFRTdHJpbmcpIHtcbiAgICAgICAgaWYgKCFUU3RyaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGFyYW1Db3VudHMgPSB7cjogMywgczogNCwgdDogMiwgbTogNn0sXG4gICAgICAgICAgICBkYXRhID0gW107XG4gICAgICAgIGlmIChSLmlzKFRTdHJpbmcsIGFycmF5KSAmJiBSLmlzKFRTdHJpbmdbMF0sIGFycmF5KSkgeyAvLyByb3VnaCBhc3N1bXB0aW9uXG4gICAgICAgICAgICBkYXRhID0gcGF0aENsb25lKFRTdHJpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgIFN0cihUU3RyaW5nKS5yZXBsYWNlKHRDb21tYW5kLCBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgICAgICAgICAgIHZhciBwYXJhbXMgPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGxvd2VyQ2FzZS5jYWxsKGIpO1xuICAgICAgICAgICAgICAgIGMucmVwbGFjZShwYXRoVmFsdWVzLCBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgICBiICYmIHBhcmFtcy5wdXNoKCtiKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBkYXRhLnB1c2goW2JdW2NvbmNhdF0ocGFyYW1zKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhLnRvU3RyaW5nID0gUi5fcGF0aDJzdHJpbmc7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH0pO1xuICAgIC8vIFBBVEhTXG4gICAgdmFyIHBhdGhzID0gZnVuY3Rpb24gKHBzKSB7XG4gICAgICAgIHZhciBwID0gcGF0aHMucHMgPSBwYXRocy5wcyB8fCB7fTtcbiAgICAgICAgaWYgKHBbcHNdKSB7XG4gICAgICAgICAgICBwW3BzXS5zbGVlcCA9IDEwMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBbcHNdID0ge1xuICAgICAgICAgICAgICAgIHNsZWVwOiAxMDBcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gcCkgaWYgKHBbaGFzXShrZXkpICYmIGtleSAhPSBwcykge1xuICAgICAgICAgICAgICAgIHBba2V5XS5zbGVlcC0tO1xuICAgICAgICAgICAgICAgICFwW2tleV0uc2xlZXAgJiYgZGVsZXRlIHBba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwW3BzXTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmZpbmREb3RzQXRTZWdtZW50XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBVdGlsaXR5IG1ldGhvZFxuICAgICAqKlxuICAgICAqIEZpbmQgZG90IGNvb3JkaW5hdGVzIG9uIHRoZSBnaXZlbiBjdWJpYyBiZXppZXIgY3VydmUgYXQgdGhlIGdpdmVuIHQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIHAxeCAobnVtYmVyKSB4IG9mIHRoZSBmaXJzdCBwb2ludCBvZiB0aGUgY3VydmVcbiAgICAgLSBwMXkgKG51bWJlcikgeSBvZiB0aGUgZmlyc3QgcG9pbnQgb2YgdGhlIGN1cnZlXG4gICAgIC0gYzF4IChudW1iZXIpIHggb2YgdGhlIGZpcnN0IGFuY2hvciBvZiB0aGUgY3VydmVcbiAgICAgLSBjMXkgKG51bWJlcikgeSBvZiB0aGUgZmlyc3QgYW5jaG9yIG9mIHRoZSBjdXJ2ZVxuICAgICAtIGMyeCAobnVtYmVyKSB4IG9mIHRoZSBzZWNvbmQgYW5jaG9yIG9mIHRoZSBjdXJ2ZVxuICAgICAtIGMyeSAobnVtYmVyKSB5IG9mIHRoZSBzZWNvbmQgYW5jaG9yIG9mIHRoZSBjdXJ2ZVxuICAgICAtIHAyeCAobnVtYmVyKSB4IG9mIHRoZSBzZWNvbmQgcG9pbnQgb2YgdGhlIGN1cnZlXG4gICAgIC0gcDJ5IChudW1iZXIpIHkgb2YgdGhlIHNlY29uZCBwb2ludCBvZiB0aGUgY3VydmVcbiAgICAgLSB0IChudW1iZXIpIHBvc2l0aW9uIG9uIHRoZSBjdXJ2ZSAoMC4uMSlcbiAgICAgPSAob2JqZWN0KSBwb2ludCBpbmZvcm1hdGlvbiBpbiBmb3JtYXQ6XG4gICAgIG8ge1xuICAgICBvICAgICB4OiAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50XG4gICAgIG8gICAgIHk6IChudW1iZXIpIHkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgbyAgICAgbToge1xuICAgICBvICAgICAgICAgeDogKG51bWJlcikgeCBjb29yZGluYXRlIG9mIHRoZSBsZWZ0IGFuY2hvclxuICAgICBvICAgICAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBsZWZ0IGFuY2hvclxuICAgICBvICAgICB9XG4gICAgIG8gICAgIG46IHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgcmlnaHQgYW5jaG9yXG4gICAgIG8gICAgICAgICB5OiAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJpZ2h0IGFuY2hvclxuICAgICBvICAgICB9XG4gICAgIG8gICAgIHN0YXJ0OiB7XG4gICAgIG8gICAgICAgICB4OiAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0IG9mIHRoZSBjdXJ2ZVxuICAgICBvICAgICAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydCBvZiB0aGUgY3VydmVcbiAgICAgbyAgICAgfVxuICAgICBvICAgICBlbmQ6IHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIG9mIHRoZSBjdXJ2ZVxuICAgICBvICAgICAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgb2YgdGhlIGN1cnZlXG4gICAgIG8gICAgIH1cbiAgICAgbyAgICAgYWxwaGE6IChudW1iZXIpIGFuZ2xlIG9mIHRoZSBjdXJ2ZSBkZXJpdmF0aXZlIGF0IHRoZSBwb2ludFxuICAgICBvIH1cbiAgICBcXCovXG4gICAgUi5maW5kRG90c0F0U2VnbWVudCA9IGZ1bmN0aW9uIChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdCkge1xuICAgICAgICB2YXIgdDEgPSAxIC0gdCxcbiAgICAgICAgICAgIHQxMyA9IHBvdyh0MSwgMyksXG4gICAgICAgICAgICB0MTIgPSBwb3codDEsIDIpLFxuICAgICAgICAgICAgdDIgPSB0ICogdCxcbiAgICAgICAgICAgIHQzID0gdDIgKiB0LFxuICAgICAgICAgICAgeCA9IHQxMyAqIHAxeCArIHQxMiAqIDMgKiB0ICogYzF4ICsgdDEgKiAzICogdCAqIHQgKiBjMnggKyB0MyAqIHAyeCxcbiAgICAgICAgICAgIHkgPSB0MTMgKiBwMXkgKyB0MTIgKiAzICogdCAqIGMxeSArIHQxICogMyAqIHQgKiB0ICogYzJ5ICsgdDMgKiBwMnksXG4gICAgICAgICAgICBteCA9IHAxeCArIDIgKiB0ICogKGMxeCAtIHAxeCkgKyB0MiAqIChjMnggLSAyICogYzF4ICsgcDF4KSxcbiAgICAgICAgICAgIG15ID0gcDF5ICsgMiAqIHQgKiAoYzF5IC0gcDF5KSArIHQyICogKGMyeSAtIDIgKiBjMXkgKyBwMXkpLFxuICAgICAgICAgICAgbnggPSBjMXggKyAyICogdCAqIChjMnggLSBjMXgpICsgdDIgKiAocDJ4IC0gMiAqIGMyeCArIGMxeCksXG4gICAgICAgICAgICBueSA9IGMxeSArIDIgKiB0ICogKGMyeSAtIGMxeSkgKyB0MiAqIChwMnkgLSAyICogYzJ5ICsgYzF5KSxcbiAgICAgICAgICAgIGF4ID0gdDEgKiBwMXggKyB0ICogYzF4LFxuICAgICAgICAgICAgYXkgPSB0MSAqIHAxeSArIHQgKiBjMXksXG4gICAgICAgICAgICBjeCA9IHQxICogYzJ4ICsgdCAqIHAyeCxcbiAgICAgICAgICAgIGN5ID0gdDEgKiBjMnkgKyB0ICogcDJ5LFxuICAgICAgICAgICAgYWxwaGEgPSAoOTAgLSBtYXRoLmF0YW4yKG14IC0gbngsIG15IC0gbnkpICogMTgwIC8gUEkpO1xuICAgICAgICAobXggPiBueCB8fCBteSA8IG55KSAmJiAoYWxwaGEgKz0gMTgwKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgbToge3g6IG14LCB5OiBteX0sXG4gICAgICAgICAgICBuOiB7eDogbngsIHk6IG55fSxcbiAgICAgICAgICAgIHN0YXJ0OiB7eDogYXgsIHk6IGF5fSxcbiAgICAgICAgICAgIGVuZDoge3g6IGN4LCB5OiBjeX0sXG4gICAgICAgICAgICBhbHBoYTogYWxwaGFcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmJlemllckJCb3hcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogUmV0dXJuIGJvdW5kaW5nIGJveCBvZiBhIGdpdmVuIGN1YmljIGJlemllciBjdXJ2ZVxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBwMXggKG51bWJlcikgeCBvZiB0aGUgZmlyc3QgcG9pbnQgb2YgdGhlIGN1cnZlXG4gICAgIC0gcDF5IChudW1iZXIpIHkgb2YgdGhlIGZpcnN0IHBvaW50IG9mIHRoZSBjdXJ2ZVxuICAgICAtIGMxeCAobnVtYmVyKSB4IG9mIHRoZSBmaXJzdCBhbmNob3Igb2YgdGhlIGN1cnZlXG4gICAgIC0gYzF5IChudW1iZXIpIHkgb2YgdGhlIGZpcnN0IGFuY2hvciBvZiB0aGUgY3VydmVcbiAgICAgLSBjMnggKG51bWJlcikgeCBvZiB0aGUgc2Vjb25kIGFuY2hvciBvZiB0aGUgY3VydmVcbiAgICAgLSBjMnkgKG51bWJlcikgeSBvZiB0aGUgc2Vjb25kIGFuY2hvciBvZiB0aGUgY3VydmVcbiAgICAgLSBwMnggKG51bWJlcikgeCBvZiB0aGUgc2Vjb25kIHBvaW50IG9mIHRoZSBjdXJ2ZVxuICAgICAtIHAyeSAobnVtYmVyKSB5IG9mIHRoZSBzZWNvbmQgcG9pbnQgb2YgdGhlIGN1cnZlXG4gICAgICogb3JcbiAgICAgLSBiZXogKGFycmF5KSBhcnJheSBvZiBzaXggcG9pbnRzIGZvciBiZXppZXIgY3VydmVcbiAgICAgPSAob2JqZWN0KSBwb2ludCBpbmZvcm1hdGlvbiBpbiBmb3JtYXQ6XG4gICAgIG8ge1xuICAgICBvICAgICBtaW46IHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgbGVmdCBwb2ludFxuICAgICBvICAgICAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSB0b3AgcG9pbnRcbiAgICAgbyAgICAgfVxuICAgICBvICAgICBtYXg6IHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgcmlnaHQgcG9pbnRcbiAgICAgbyAgICAgICAgIHk6IChudW1iZXIpIHkgY29vcmRpbmF0ZSBvZiB0aGUgYm90dG9tIHBvaW50XG4gICAgIG8gICAgIH1cbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIuYmV6aWVyQkJveCA9IGZ1bmN0aW9uIChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSkge1xuICAgICAgICBpZiAoIVIuaXMocDF4LCBcImFycmF5XCIpKSB7XG4gICAgICAgICAgICBwMXggPSBbcDF4LCBwMXksIGMxeCwgYzF5LCBjMngsIGMyeSwgcDJ4LCBwMnldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBiYm94ID0gY3VydmVEaW0uYXBwbHkobnVsbCwgcDF4KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IGJib3gubWluLngsXG4gICAgICAgICAgICB5OiBiYm94Lm1pbi55LFxuICAgICAgICAgICAgeDI6IGJib3gubWF4LngsXG4gICAgICAgICAgICB5MjogYmJveC5tYXgueSxcbiAgICAgICAgICAgIHdpZHRoOiBiYm94Lm1heC54IC0gYmJveC5taW4ueCxcbiAgICAgICAgICAgIGhlaWdodDogYmJveC5tYXgueSAtIGJib3gubWluLnlcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmlzUG9pbnRJbnNpZGVCQm94XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBVdGlsaXR5IG1ldGhvZFxuICAgICAqKlxuICAgICAqIFJldHVybnMgYHRydWVgIGlmIGdpdmVuIHBvaW50IGlzIGluc2lkZSBib3VuZGluZyBib3hlcy5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gYmJveCAoc3RyaW5nKSBib3VuZGluZyBib3hcbiAgICAgLSB4IChzdHJpbmcpIHggY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgLSB5IChzdHJpbmcpIHkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgPSAoYm9vbGVhbikgYHRydWVgIGlmIHBvaW50IGluc2lkZVxuICAgIFxcKi9cbiAgICBSLmlzUG9pbnRJbnNpZGVCQm94ID0gZnVuY3Rpb24gKGJib3gsIHgsIHkpIHtcbiAgICAgICAgcmV0dXJuIHggPj0gYmJveC54ICYmIHggPD0gYmJveC54MiAmJiB5ID49IGJib3gueSAmJiB5IDw9IGJib3gueTI7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5pc0JCb3hJbnRlcnNlY3RcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogUmV0dXJucyBgdHJ1ZWAgaWYgdHdvIGJvdW5kaW5nIGJveGVzIGludGVyc2VjdFxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBiYm94MSAoc3RyaW5nKSBmaXJzdCBib3VuZGluZyBib3hcbiAgICAgLSBiYm94MiAoc3RyaW5nKSBzZWNvbmQgYm91bmRpbmcgYm94XG4gICAgID0gKGJvb2xlYW4pIGB0cnVlYCBpZiB0aGV5IGludGVyc2VjdFxuICAgIFxcKi9cbiAgICBSLmlzQkJveEludGVyc2VjdCA9IGZ1bmN0aW9uIChiYm94MSwgYmJveDIpIHtcbiAgICAgICAgdmFyIGkgPSBSLmlzUG9pbnRJbnNpZGVCQm94O1xuICAgICAgICByZXR1cm4gaShiYm94MiwgYmJveDEueCwgYmJveDEueSlcbiAgICAgICAgICAgIHx8IGkoYmJveDIsIGJib3gxLngyLCBiYm94MS55KVxuICAgICAgICAgICAgfHwgaShiYm94MiwgYmJveDEueCwgYmJveDEueTIpXG4gICAgICAgICAgICB8fCBpKGJib3gyLCBiYm94MS54MiwgYmJveDEueTIpXG4gICAgICAgICAgICB8fCBpKGJib3gxLCBiYm94Mi54LCBiYm94Mi55KVxuICAgICAgICAgICAgfHwgaShiYm94MSwgYmJveDIueDIsIGJib3gyLnkpXG4gICAgICAgICAgICB8fCBpKGJib3gxLCBiYm94Mi54LCBiYm94Mi55MilcbiAgICAgICAgICAgIHx8IGkoYmJveDEsIGJib3gyLngyLCBiYm94Mi55MilcbiAgICAgICAgICAgIHx8IChiYm94MS54IDwgYmJveDIueDIgJiYgYmJveDEueCA+IGJib3gyLnggfHwgYmJveDIueCA8IGJib3gxLngyICYmIGJib3gyLnggPiBiYm94MS54KVxuICAgICAgICAgICAgJiYgKGJib3gxLnkgPCBiYm94Mi55MiAmJiBiYm94MS55ID4gYmJveDIueSB8fCBiYm94Mi55IDwgYmJveDEueTIgJiYgYmJveDIueSA+IGJib3gxLnkpO1xuICAgIH07XG4gICAgZnVuY3Rpb24gYmFzZTModCwgcDEsIHAyLCBwMywgcDQpIHtcbiAgICAgICAgdmFyIHQxID0gLTMgKiBwMSArIDkgKiBwMiAtIDkgKiBwMyArIDMgKiBwNCxcbiAgICAgICAgICAgIHQyID0gdCAqIHQxICsgNiAqIHAxIC0gMTIgKiBwMiArIDYgKiBwMztcbiAgICAgICAgcmV0dXJuIHQgKiB0MiAtIDMgKiBwMSArIDMgKiBwMjtcbiAgICB9XG4gICAgZnVuY3Rpb24gYmV6bGVuKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgeikge1xuICAgICAgICBpZiAoeiA9PSBudWxsKSB7XG4gICAgICAgICAgICB6ID0gMTtcbiAgICAgICAgfVxuICAgICAgICB6ID0geiA+IDEgPyAxIDogeiA8IDAgPyAwIDogejtcbiAgICAgICAgdmFyIHoyID0geiAvIDIsXG4gICAgICAgICAgICBuID0gMTIsXG4gICAgICAgICAgICBUdmFsdWVzID0gWy0wLjEyNTIsMC4xMjUyLC0wLjM2NzgsMC4zNjc4LC0wLjU4NzMsMC41ODczLC0wLjc2OTksMC43Njk5LC0wLjkwNDEsMC45MDQxLC0wLjk4MTYsMC45ODE2XSxcbiAgICAgICAgICAgIEN2YWx1ZXMgPSBbMC4yNDkxLDAuMjQ5MSwwLjIzMzUsMC4yMzM1LDAuMjAzMiwwLjIwMzIsMC4xNjAxLDAuMTYwMSwwLjEwNjksMC4xMDY5LDAuMDQ3MiwwLjA0NzJdLFxuICAgICAgICAgICAgc3VtID0gMDtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBjdCA9IHoyICogVHZhbHVlc1tpXSArIHoyLFxuICAgICAgICAgICAgICAgIHhiYXNlID0gYmFzZTMoY3QsIHgxLCB4MiwgeDMsIHg0KSxcbiAgICAgICAgICAgICAgICB5YmFzZSA9IGJhc2UzKGN0LCB5MSwgeTIsIHkzLCB5NCksXG4gICAgICAgICAgICAgICAgY29tYiA9IHhiYXNlICogeGJhc2UgKyB5YmFzZSAqIHliYXNlO1xuICAgICAgICAgICAgc3VtICs9IEN2YWx1ZXNbaV0gKiBtYXRoLnNxcnQoY29tYik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHoyICogc3VtO1xuICAgIH1cbiAgICBmdW5jdGlvbiBnZXRUYXRMZW4oeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCBsbCkge1xuICAgICAgICBpZiAobGwgPCAwIHx8IGJlemxlbih4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQpIDwgbGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdCA9IDEsXG4gICAgICAgICAgICBzdGVwID0gdCAvIDIsXG4gICAgICAgICAgICB0MiA9IHQgLSBzdGVwLFxuICAgICAgICAgICAgbCxcbiAgICAgICAgICAgIGUgPSAuMDE7XG4gICAgICAgIGwgPSBiZXpsZW4oeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB0Mik7XG4gICAgICAgIHdoaWxlIChhYnMobCAtIGxsKSA+IGUpIHtcbiAgICAgICAgICAgIHN0ZXAgLz0gMjtcbiAgICAgICAgICAgIHQyICs9IChsIDwgbGwgPyAxIDogLTEpICogc3RlcDtcbiAgICAgICAgICAgIGwgPSBiZXpsZW4oeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB0Mik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQyO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpbnRlcnNlY3QoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIG1tYXgoeDEsIHgyKSA8IG1taW4oeDMsIHg0KSB8fFxuICAgICAgICAgICAgbW1pbih4MSwgeDIpID4gbW1heCh4MywgeDQpIHx8XG4gICAgICAgICAgICBtbWF4KHkxLCB5MikgPCBtbWluKHkzLCB5NCkgfHxcbiAgICAgICAgICAgIG1taW4oeTEsIHkyKSA+IG1tYXgoeTMsIHk0KVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbnggPSAoeDEgKiB5MiAtIHkxICogeDIpICogKHgzIC0geDQpIC0gKHgxIC0geDIpICogKHgzICogeTQgLSB5MyAqIHg0KSxcbiAgICAgICAgICAgIG55ID0gKHgxICogeTIgLSB5MSAqIHgyKSAqICh5MyAtIHk0KSAtICh5MSAtIHkyKSAqICh4MyAqIHk0IC0geTMgKiB4NCksXG4gICAgICAgICAgICBkZW5vbWluYXRvciA9ICh4MSAtIHgyKSAqICh5MyAtIHk0KSAtICh5MSAtIHkyKSAqICh4MyAtIHg0KTtcblxuICAgICAgICBpZiAoIWRlbm9taW5hdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHB4ID0gbnggLyBkZW5vbWluYXRvcixcbiAgICAgICAgICAgIHB5ID0gbnkgLyBkZW5vbWluYXRvcixcbiAgICAgICAgICAgIHB4MiA9ICtweC50b0ZpeGVkKDIpLFxuICAgICAgICAgICAgcHkyID0gK3B5LnRvRml4ZWQoMik7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHB4MiA8ICttbWluKHgxLCB4MikudG9GaXhlZCgyKSB8fFxuICAgICAgICAgICAgcHgyID4gK21tYXgoeDEsIHgyKS50b0ZpeGVkKDIpIHx8XG4gICAgICAgICAgICBweDIgPCArbW1pbih4MywgeDQpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgICAgIHB4MiA+ICttbWF4KHgzLCB4NCkudG9GaXhlZCgyKSB8fFxuICAgICAgICAgICAgcHkyIDwgK21taW4oeTEsIHkyKS50b0ZpeGVkKDIpIHx8XG4gICAgICAgICAgICBweTIgPiArbW1heCh5MSwgeTIpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgICAgIHB5MiA8ICttbWluKHkzLCB5NCkudG9GaXhlZCgyKSB8fFxuICAgICAgICAgICAgcHkyID4gK21tYXgoeTMsIHk0KS50b0ZpeGVkKDIpXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7eDogcHgsIHk6IHB5fTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaW50ZXIoYmV6MSwgYmV6Mikge1xuICAgICAgICByZXR1cm4gaW50ZXJIZWxwZXIoYmV6MSwgYmV6Mik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGludGVyQ291bnQoYmV6MSwgYmV6Mikge1xuICAgICAgICByZXR1cm4gaW50ZXJIZWxwZXIoYmV6MSwgYmV6MiwgMSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGludGVySGVscGVyKGJlejEsIGJlejIsIGp1c3RDb3VudCkge1xuICAgICAgICB2YXIgYmJveDEgPSBSLmJlemllckJCb3goYmV6MSksXG4gICAgICAgICAgICBiYm94MiA9IFIuYmV6aWVyQkJveChiZXoyKTtcbiAgICAgICAgaWYgKCFSLmlzQkJveEludGVyc2VjdChiYm94MSwgYmJveDIpKSB7XG4gICAgICAgICAgICByZXR1cm4ganVzdENvdW50ID8gMCA6IFtdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBsMSA9IGJlemxlbi5hcHBseSgwLCBiZXoxKSxcbiAgICAgICAgICAgIGwyID0gYmV6bGVuLmFwcGx5KDAsIGJlejIpLFxuICAgICAgICAgICAgbjEgPSBtbWF4KH5+KGwxIC8gNSksIDEpLFxuICAgICAgICAgICAgbjIgPSBtbWF4KH5+KGwyIC8gNSksIDEpLFxuICAgICAgICAgICAgZG90czEgPSBbXSxcbiAgICAgICAgICAgIGRvdHMyID0gW10sXG4gICAgICAgICAgICB4eSA9IHt9LFxuICAgICAgICAgICAgcmVzID0ganVzdENvdW50ID8gMCA6IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG4xICsgMTsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgcCA9IFIuZmluZERvdHNBdFNlZ21lbnQuYXBwbHkoUiwgYmV6MS5jb25jYXQoaSAvIG4xKSk7XG4gICAgICAgICAgICBkb3RzMS5wdXNoKHt4OiBwLngsIHk6IHAueSwgdDogaSAvIG4xfSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IG4yICsgMTsgaSsrKSB7XG4gICAgICAgICAgICBwID0gUi5maW5kRG90c0F0U2VnbWVudC5hcHBseShSLCBiZXoyLmNvbmNhdChpIC8gbjIpKTtcbiAgICAgICAgICAgIGRvdHMyLnB1c2goe3g6IHAueCwgeTogcC55LCB0OiBpIC8gbjJ9KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjE7IGkrKykge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBuMjsgaisrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRpID0gZG90czFbaV0sXG4gICAgICAgICAgICAgICAgICAgIGRpMSA9IGRvdHMxW2kgKyAxXSxcbiAgICAgICAgICAgICAgICAgICAgZGogPSBkb3RzMltqXSxcbiAgICAgICAgICAgICAgICAgICAgZGoxID0gZG90czJbaiArIDFdLFxuICAgICAgICAgICAgICAgICAgICBjaSA9IGFicyhkaTEueCAtIGRpLngpIDwgLjAwMSA/IFwieVwiIDogXCJ4XCIsXG4gICAgICAgICAgICAgICAgICAgIGNqID0gYWJzKGRqMS54IC0gZGoueCkgPCAuMDAxID8gXCJ5XCIgOiBcInhcIixcbiAgICAgICAgICAgICAgICAgICAgaXMgPSBpbnRlcnNlY3QoZGkueCwgZGkueSwgZGkxLngsIGRpMS55LCBkai54LCBkai55LCBkajEueCwgZGoxLnkpO1xuICAgICAgICAgICAgICAgIGlmIChpcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoeHlbaXMueC50b0ZpeGVkKDQpXSA9PSBpcy55LnRvRml4ZWQoNCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHh5W2lzLngudG9GaXhlZCg0KV0gPSBpcy55LnRvRml4ZWQoNCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0MSA9IGRpLnQgKyBhYnMoKGlzW2NpXSAtIGRpW2NpXSkgLyAoZGkxW2NpXSAtIGRpW2NpXSkpICogKGRpMS50IC0gZGkudCksXG4gICAgICAgICAgICAgICAgICAgICAgICB0MiA9IGRqLnQgKyBhYnMoKGlzW2NqXSAtIGRqW2NqXSkgLyAoZGoxW2NqXSAtIGRqW2NqXSkpICogKGRqMS50IC0gZGoudCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0MSA+PSAwICYmIHQxIDw9IDEuMDAxICYmIHQyID49IDAgJiYgdDIgPD0gMS4wMDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqdXN0Q291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBpcy54LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpcy55LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0MTogbW1pbih0MSwgMSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQyOiBtbWluKHQyLCAxKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnBhdGhJbnRlcnNlY3Rpb25cbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogRmluZHMgaW50ZXJzZWN0aW9ucyBvZiB0d28gcGF0aHNcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gcGF0aDEgKHN0cmluZykgcGF0aCBzdHJpbmdcbiAgICAgLSBwYXRoMiAoc3RyaW5nKSBwYXRoIHN0cmluZ1xuICAgICA9IChhcnJheSkgZG90cyBvZiBpbnRlcnNlY3Rpb25cbiAgICAgbyBbXG4gICAgIG8gICAgIHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgbyAgICAgICAgIHk6IChudW1iZXIpIHkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgbyAgICAgICAgIHQxOiAobnVtYmVyKSB0IHZhbHVlIGZvciBzZWdtZW50IG9mIHBhdGgxXG4gICAgIG8gICAgICAgICB0MjogKG51bWJlcikgdCB2YWx1ZSBmb3Igc2VnbWVudCBvZiBwYXRoMlxuICAgICBvICAgICAgICAgc2VnbWVudDE6IChudW1iZXIpIG9yZGVyIG51bWJlciBmb3Igc2VnbWVudCBvZiBwYXRoMVxuICAgICBvICAgICAgICAgc2VnbWVudDI6IChudW1iZXIpIG9yZGVyIG51bWJlciBmb3Igc2VnbWVudCBvZiBwYXRoMlxuICAgICBvICAgICAgICAgYmV6MTogKGFycmF5KSBlaWdodCBjb29yZGluYXRlcyByZXByZXNlbnRpbmcgYmV6acOpciBjdXJ2ZSBmb3IgdGhlIHNlZ21lbnQgb2YgcGF0aDFcbiAgICAgbyAgICAgICAgIGJlejI6IChhcnJheSkgZWlnaHQgY29vcmRpbmF0ZXMgcmVwcmVzZW50aW5nIGJlemnDqXIgY3VydmUgZm9yIHRoZSBzZWdtZW50IG9mIHBhdGgyXG4gICAgIG8gICAgIH1cbiAgICAgbyBdXG4gICAgXFwqL1xuICAgIFIucGF0aEludGVyc2VjdGlvbiA9IGZ1bmN0aW9uIChwYXRoMSwgcGF0aDIpIHtcbiAgICAgICAgcmV0dXJuIGludGVyUGF0aEhlbHBlcihwYXRoMSwgcGF0aDIpO1xuICAgIH07XG4gICAgUi5wYXRoSW50ZXJzZWN0aW9uTnVtYmVyID0gZnVuY3Rpb24gKHBhdGgxLCBwYXRoMikge1xuICAgICAgICByZXR1cm4gaW50ZXJQYXRoSGVscGVyKHBhdGgxLCBwYXRoMiwgMSk7XG4gICAgfTtcbiAgICBmdW5jdGlvbiBpbnRlclBhdGhIZWxwZXIocGF0aDEsIHBhdGgyLCBqdXN0Q291bnQpIHtcbiAgICAgICAgcGF0aDEgPSBSLl9wYXRoMmN1cnZlKHBhdGgxKTtcbiAgICAgICAgcGF0aDIgPSBSLl9wYXRoMmN1cnZlKHBhdGgyKTtcbiAgICAgICAgdmFyIHgxLCB5MSwgeDIsIHkyLCB4MW0sIHkxbSwgeDJtLCB5Mm0sIGJlejEsIGJlejIsXG4gICAgICAgICAgICByZXMgPSBqdXN0Q291bnQgPyAwIDogW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHBhdGgxLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBwaSA9IHBhdGgxW2ldO1xuICAgICAgICAgICAgaWYgKHBpWzBdID09IFwiTVwiKSB7XG4gICAgICAgICAgICAgICAgeDEgPSB4MW0gPSBwaVsxXTtcbiAgICAgICAgICAgICAgICB5MSA9IHkxbSA9IHBpWzJdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAocGlbMF0gPT0gXCJDXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgYmV6MSA9IFt4MSwgeTFdLmNvbmNhdChwaS5zbGljZSgxKSk7XG4gICAgICAgICAgICAgICAgICAgIHgxID0gYmV6MVs2XTtcbiAgICAgICAgICAgICAgICAgICAgeTEgPSBiZXoxWzddO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJlejEgPSBbeDEsIHkxLCB4MSwgeTEsIHgxbSwgeTFtLCB4MW0sIHkxbV07XG4gICAgICAgICAgICAgICAgICAgIHgxID0geDFtO1xuICAgICAgICAgICAgICAgICAgICB5MSA9IHkxbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gcGF0aDIubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcGogPSBwYXRoMltqXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBqWzBdID09IFwiTVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4MiA9IHgybSA9IHBqWzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgeTIgPSB5Mm0gPSBwalsyXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwalswXSA9PSBcIkNcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlejIgPSBbeDIsIHkyXS5jb25jYXQocGouc2xpY2UoMSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgyID0gYmV6Mls2XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MiA9IGJlejJbN107XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlejIgPSBbeDIsIHkyLCB4MiwgeTIsIHgybSwgeTJtLCB4Mm0sIHkybV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDIgPSB4Mm07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTIgPSB5Mm07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW50ciA9IGludGVySGVscGVyKGJlejEsIGJlejIsIGp1c3RDb3VudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoanVzdENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzICs9IGludHI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgPSAwLCBrayA9IGludHIubGVuZ3RoOyBrIDwga2s7IGsrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRyW2tdLnNlZ21lbnQxID0gaTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50cltrXS5zZWdtZW50MiA9IGo7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHJba10uYmV6MSA9IGJlejE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHJba10uYmV6MiA9IGJlejI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoaW50cik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuaXNQb2ludEluc2lkZVBhdGhcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogUmV0dXJucyBgdHJ1ZWAgaWYgZ2l2ZW4gcG9pbnQgaXMgaW5zaWRlIGEgZ2l2ZW4gY2xvc2VkIHBhdGguXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIHBhdGggKHN0cmluZykgcGF0aCBzdHJpbmdcbiAgICAgLSB4IChudW1iZXIpIHggb2YgdGhlIHBvaW50XG4gICAgIC0geSAobnVtYmVyKSB5IG9mIHRoZSBwb2ludFxuICAgICA9IChib29sZWFuKSB0cnVlLCBpZiBwb2ludCBpcyBpbnNpZGUgdGhlIHBhdGhcbiAgICBcXCovXG4gICAgUi5pc1BvaW50SW5zaWRlUGF0aCA9IGZ1bmN0aW9uIChwYXRoLCB4LCB5KSB7XG4gICAgICAgIHZhciBiYm94ID0gUi5wYXRoQkJveChwYXRoKTtcbiAgICAgICAgcmV0dXJuIFIuaXNQb2ludEluc2lkZUJCb3goYmJveCwgeCwgeSkgJiZcbiAgICAgICAgICAgICAgIGludGVyUGF0aEhlbHBlcihwYXRoLCBbW1wiTVwiLCB4LCB5XSwgW1wiSFwiLCBiYm94LngyICsgMTBdXSwgMSkgJSAyID09IDE7XG4gICAgfTtcbiAgICBSLl9yZW1vdmVkRmFjdG9yeSA9IGZ1bmN0aW9uIChtZXRob2RuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBldmUoXCJyYXBoYWVsLmxvZ1wiLCBudWxsLCBcIlJhcGhhXFx4ZWJsOiB5b3UgYXJlIGNhbGxpbmcgdG8gbWV0aG9kIFxcdTIwMWNcIiArIG1ldGhvZG5hbWUgKyBcIlxcdTIwMWQgb2YgcmVtb3ZlZCBvYmplY3RcIiwgbWV0aG9kbmFtZSk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5wYXRoQkJveFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogVXRpbGl0eSBtZXRob2RcbiAgICAgKipcbiAgICAgKiBSZXR1cm4gYm91bmRpbmcgYm94IG9mIGEgZ2l2ZW4gcGF0aFxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBwYXRoIChzdHJpbmcpIHBhdGggc3RyaW5nXG4gICAgID0gKG9iamVjdCkgYm91bmRpbmcgYm94XG4gICAgIG8ge1xuICAgICBvICAgICB4OiAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIGxlZnQgdG9wIHBvaW50IG9mIHRoZSBib3hcbiAgICAgbyAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBsZWZ0IHRvcCBwb2ludCBvZiB0aGUgYm94XG4gICAgIG8gICAgIHgyOiAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIHJpZ2h0IGJvdHRvbSBwb2ludCBvZiB0aGUgYm94XG4gICAgIG8gICAgIHkyOiAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJpZ2h0IGJvdHRvbSBwb2ludCBvZiB0aGUgYm94XG4gICAgIG8gICAgIHdpZHRoOiAobnVtYmVyKSB3aWR0aCBvZiB0aGUgYm94XG4gICAgIG8gICAgIGhlaWdodDogKG51bWJlcikgaGVpZ2h0IG9mIHRoZSBib3hcbiAgICAgbyAgICAgY3g6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBib3hcbiAgICAgbyAgICAgY3k6IChudW1iZXIpIHkgY29vcmRpbmF0ZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBib3hcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIHZhciBwYXRoRGltZW5zaW9ucyA9IFIucGF0aEJCb3ggPSBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICB2YXIgcHRoID0gcGF0aHMocGF0aCk7XG4gICAgICAgIGlmIChwdGguYmJveCkge1xuICAgICAgICAgICAgcmV0dXJuIGNsb25lKHB0aC5iYm94KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybiB7eDogMCwgeTogMCwgd2lkdGg6IDAsIGhlaWdodDogMCwgeDI6IDAsIHkyOiAwfTtcbiAgICAgICAgfVxuICAgICAgICBwYXRoID0gcGF0aDJjdXJ2ZShwYXRoKTtcbiAgICAgICAgdmFyIHggPSAwLFxuICAgICAgICAgICAgeSA9IDAsXG4gICAgICAgICAgICBYID0gW10sXG4gICAgICAgICAgICBZID0gW10sXG4gICAgICAgICAgICBwO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBwYXRoLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgIHAgPSBwYXRoW2ldO1xuICAgICAgICAgICAgaWYgKHBbMF0gPT0gXCJNXCIpIHtcbiAgICAgICAgICAgICAgICB4ID0gcFsxXTtcbiAgICAgICAgICAgICAgICB5ID0gcFsyXTtcbiAgICAgICAgICAgICAgICBYLnB1c2goeCk7XG4gICAgICAgICAgICAgICAgWS5wdXNoKHkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgZGltID0gY3VydmVEaW0oeCwgeSwgcFsxXSwgcFsyXSwgcFszXSwgcFs0XSwgcFs1XSwgcFs2XSk7XG4gICAgICAgICAgICAgICAgWCA9IFhbY29uY2F0XShkaW0ubWluLngsIGRpbS5tYXgueCk7XG4gICAgICAgICAgICAgICAgWSA9IFlbY29uY2F0XShkaW0ubWluLnksIGRpbS5tYXgueSk7XG4gICAgICAgICAgICAgICAgeCA9IHBbNV07XG4gICAgICAgICAgICAgICAgeSA9IHBbNl07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHhtaW4gPSBtbWluW2FwcGx5XSgwLCBYKSxcbiAgICAgICAgICAgIHltaW4gPSBtbWluW2FwcGx5XSgwLCBZKSxcbiAgICAgICAgICAgIHhtYXggPSBtbWF4W2FwcGx5XSgwLCBYKSxcbiAgICAgICAgICAgIHltYXggPSBtbWF4W2FwcGx5XSgwLCBZKSxcbiAgICAgICAgICAgIHdpZHRoID0geG1heCAtIHhtaW4sXG4gICAgICAgICAgICBoZWlnaHQgPSB5bWF4IC0geW1pbixcbiAgICAgICAgICAgICAgICBiYiA9IHtcbiAgICAgICAgICAgICAgICB4OiB4bWluLFxuICAgICAgICAgICAgICAgIHk6IHltaW4sXG4gICAgICAgICAgICAgICAgeDI6IHhtYXgsXG4gICAgICAgICAgICAgICAgeTI6IHltYXgsXG4gICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0LFxuICAgICAgICAgICAgICAgIGN4OiB4bWluICsgd2lkdGggLyAyLFxuICAgICAgICAgICAgICAgIGN5OiB5bWluICsgaGVpZ2h0IC8gMlxuICAgICAgICAgICAgfTtcbiAgICAgICAgcHRoLmJib3ggPSBjbG9uZShiYik7XG4gICAgICAgIHJldHVybiBiYjtcbiAgICB9LFxuICAgICAgICBwYXRoQ2xvbmUgPSBmdW5jdGlvbiAocGF0aEFycmF5KSB7XG4gICAgICAgICAgICB2YXIgcmVzID0gY2xvbmUocGF0aEFycmF5KTtcbiAgICAgICAgICAgIHJlcy50b1N0cmluZyA9IFIuX3BhdGgyc3RyaW5nO1xuICAgICAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgICAgfSxcbiAgICAgICAgcGF0aFRvUmVsYXRpdmUgPSBSLl9wYXRoVG9SZWxhdGl2ZSA9IGZ1bmN0aW9uIChwYXRoQXJyYXkpIHtcbiAgICAgICAgICAgIHZhciBwdGggPSBwYXRocyhwYXRoQXJyYXkpO1xuICAgICAgICAgICAgaWYgKHB0aC5yZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGF0aENsb25lKHB0aC5yZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFSLmlzKHBhdGhBcnJheSwgYXJyYXkpIHx8ICFSLmlzKHBhdGhBcnJheSAmJiBwYXRoQXJyYXlbMF0sIGFycmF5KSkgeyAvLyByb3VnaCBhc3N1bXB0aW9uXG4gICAgICAgICAgICAgICAgcGF0aEFycmF5ID0gUi5wYXJzZVBhdGhTdHJpbmcocGF0aEFycmF5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciByZXMgPSBbXSxcbiAgICAgICAgICAgICAgICB4ID0gMCxcbiAgICAgICAgICAgICAgICB5ID0gMCxcbiAgICAgICAgICAgICAgICBteCA9IDAsXG4gICAgICAgICAgICAgICAgbXkgPSAwLFxuICAgICAgICAgICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgICAgICAgIGlmIChwYXRoQXJyYXlbMF1bMF0gPT0gXCJNXCIpIHtcbiAgICAgICAgICAgICAgICB4ID0gcGF0aEFycmF5WzBdWzFdO1xuICAgICAgICAgICAgICAgIHkgPSBwYXRoQXJyYXlbMF1bMl07XG4gICAgICAgICAgICAgICAgbXggPSB4O1xuICAgICAgICAgICAgICAgIG15ID0geTtcbiAgICAgICAgICAgICAgICBzdGFydCsrO1xuICAgICAgICAgICAgICAgIHJlcy5wdXNoKFtcIk1cIiwgeCwgeV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0LCBpaSA9IHBhdGhBcnJheS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHIgPSByZXNbaV0gPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgcGEgPSBwYXRoQXJyYXlbaV07XG4gICAgICAgICAgICAgICAgaWYgKHBhWzBdICE9IGxvd2VyQ2FzZS5jYWxsKHBhWzBdKSkge1xuICAgICAgICAgICAgICAgICAgICByWzBdID0gbG93ZXJDYXNlLmNhbGwocGFbMF0pO1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHJbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJhXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgclsxXSA9IHBhWzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbMl0gPSBwYVsyXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzNdID0gcGFbM107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcls0XSA9IHBhWzRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbNV0gPSBwYVs1XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzZdID0gKyhwYVs2XSAtIHgpLnRvRml4ZWQoMyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcls3XSA9ICsocGFbN10gLSB5KS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcInZcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzFdID0gKyhwYVsxXSAtIHkpLnRvRml4ZWQoMyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwibVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG14ID0gcGFbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXkgPSBwYVsyXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDEsIGpqID0gcGEubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByW2pdID0gKyhwYVtqXSAtICgoaiAlIDIpID8geCA6IHkpKS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHIgPSByZXNbaV0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhWzBdID09IFwibVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBteCA9IHBhWzFdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgICAgIG15ID0gcGFbMl0gKyB5O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgPSAwLCBrayA9IHBhLmxlbmd0aDsgayA8IGtrOyBrKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc1tpXVtrXSA9IHBhW2tdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBsZW4gPSByZXNbaV0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAocmVzW2ldWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ6XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gbXg7XG4gICAgICAgICAgICAgICAgICAgICAgICB5ID0gbXk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImhcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gK3Jlc1tpXVtsZW4gLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwidlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgeSArPSArcmVzW2ldW2xlbiAtIDFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICtyZXNbaV1bbGVuIC0gMl07XG4gICAgICAgICAgICAgICAgICAgICAgICB5ICs9ICtyZXNbaV1bbGVuIC0gMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzLnRvU3RyaW5nID0gUi5fcGF0aDJzdHJpbmc7XG4gICAgICAgICAgICBwdGgucmVsID0gcGF0aENsb25lKHJlcyk7XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9LFxuICAgICAgICBwYXRoVG9BYnNvbHV0ZSA9IFIuX3BhdGhUb0Fic29sdXRlID0gZnVuY3Rpb24gKHBhdGhBcnJheSkge1xuICAgICAgICAgICAgdmFyIHB0aCA9IHBhdGhzKHBhdGhBcnJheSk7XG4gICAgICAgICAgICBpZiAocHRoLmFicykge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoQ2xvbmUocHRoLmFicyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIVIuaXMocGF0aEFycmF5LCBhcnJheSkgfHwgIVIuaXMocGF0aEFycmF5ICYmIHBhdGhBcnJheVswXSwgYXJyYXkpKSB7IC8vIHJvdWdoIGFzc3VtcHRpb25cbiAgICAgICAgICAgICAgICBwYXRoQXJyYXkgPSBSLnBhcnNlUGF0aFN0cmluZyhwYXRoQXJyYXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFwYXRoQXJyYXkgfHwgIXBhdGhBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW1tcIk1cIiwgMCwgMF1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHJlcyA9IFtdLFxuICAgICAgICAgICAgICAgIHggPSAwLFxuICAgICAgICAgICAgICAgIHkgPSAwLFxuICAgICAgICAgICAgICAgIG14ID0gMCxcbiAgICAgICAgICAgICAgICBteSA9IDAsXG4gICAgICAgICAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICAgICAgaWYgKHBhdGhBcnJheVswXVswXSA9PSBcIk1cIikge1xuICAgICAgICAgICAgICAgIHggPSArcGF0aEFycmF5WzBdWzFdO1xuICAgICAgICAgICAgICAgIHkgPSArcGF0aEFycmF5WzBdWzJdO1xuICAgICAgICAgICAgICAgIG14ID0geDtcbiAgICAgICAgICAgICAgICBteSA9IHk7XG4gICAgICAgICAgICAgICAgc3RhcnQrKztcbiAgICAgICAgICAgICAgICByZXNbMF0gPSBbXCJNXCIsIHgsIHldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGNyeiA9IHBhdGhBcnJheS5sZW5ndGggPT0gMyAmJiBwYXRoQXJyYXlbMF1bMF0gPT0gXCJNXCIgJiYgcGF0aEFycmF5WzFdWzBdLnRvVXBwZXJDYXNlKCkgPT0gXCJSXCIgJiYgcGF0aEFycmF5WzJdWzBdLnRvVXBwZXJDYXNlKCkgPT0gXCJaXCI7XG4gICAgICAgICAgICBmb3IgKHZhciByLCBwYSwgaSA9IHN0YXJ0LCBpaSA9IHBhdGhBcnJheS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcmVzLnB1c2gociA9IFtdKTtcbiAgICAgICAgICAgICAgICBwYSA9IHBhdGhBcnJheVtpXTtcbiAgICAgICAgICAgICAgICBpZiAocGFbMF0gIT0gdXBwZXJDYXNlLmNhbGwocGFbMF0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJbMF0gPSB1cHBlckNhc2UuY2FsbChwYVswXSk7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoclswXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkFcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzFdID0gcGFbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgclsyXSA9IHBhWzJdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbM10gPSBwYVszXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzRdID0gcGFbNF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcls1XSA9IHBhWzVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbNl0gPSArKHBhWzZdICsgeCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcls3XSA9ICsocGFbN10gKyB5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJWXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgclsxXSA9ICtwYVsxXSArIHk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiSFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbMV0gPSArcGFbMV0gKyB4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcIlJcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG90cyA9IFt4LCB5XVtjb25jYXRdKHBhLnNsaWNlKDEpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMiwgamogPSBkb3RzLmxlbmd0aDsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG90c1tqXSA9ICtkb3RzW2pdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG90c1srK2pdID0gK2RvdHNbal0gKyB5O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gcmVzW2NvbmNhdF0oY2F0bXVsbFJvbTJiZXppZXIoZG90cywgY3J6KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiTVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG14ID0gK3BhWzFdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBteSA9ICtwYVsyXSArIHk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDEsIGpqID0gcGEubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByW2pdID0gK3BhW2pdICsgKChqICUgMikgPyB4IDogeSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYVswXSA9PSBcIlJcIikge1xuICAgICAgICAgICAgICAgICAgICBkb3RzID0gW3gsIHldW2NvbmNhdF0ocGEuc2xpY2UoMSkpO1xuICAgICAgICAgICAgICAgICAgICByZXMucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlc1tjb25jYXRdKGNhdG11bGxSb20yYmV6aWVyKGRvdHMsIGNyeikpO1xuICAgICAgICAgICAgICAgICAgICByID0gW1wiUlwiXVtjb25jYXRdKHBhLnNsaWNlKC0yKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgayA9IDAsIGtrID0gcGEubGVuZ3RoOyBrIDwga2s7IGsrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcltrXSA9IHBhW2tdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN3aXRjaCAoclswXSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiWlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgeCA9IG14O1xuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IG15O1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJIXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gclsxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiVlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIk1cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIG14ID0gcltyLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbXkgPSByW3IubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gcltyLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJbci5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXMudG9TdHJpbmcgPSBSLl9wYXRoMnN0cmluZztcbiAgICAgICAgICAgIHB0aC5hYnMgPSBwYXRoQ2xvbmUocmVzKTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0sXG4gICAgICAgIGwyYyA9IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5Mikge1xuICAgICAgICAgICAgcmV0dXJuIFt4MSwgeTEsIHgyLCB5MiwgeDIsIHkyXTtcbiAgICAgICAgfSxcbiAgICAgICAgcTJjID0gZnVuY3Rpb24gKHgxLCB5MSwgYXgsIGF5LCB4MiwgeTIpIHtcbiAgICAgICAgICAgIHZhciBfMTMgPSAxIC8gMyxcbiAgICAgICAgICAgICAgICBfMjMgPSAyIC8gMztcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgICAgICAgIF8xMyAqIHgxICsgXzIzICogYXgsXG4gICAgICAgICAgICAgICAgICAgIF8xMyAqIHkxICsgXzIzICogYXksXG4gICAgICAgICAgICAgICAgICAgIF8xMyAqIHgyICsgXzIzICogYXgsXG4gICAgICAgICAgICAgICAgICAgIF8xMyAqIHkyICsgXzIzICogYXksXG4gICAgICAgICAgICAgICAgICAgIHgyLFxuICAgICAgICAgICAgICAgICAgICB5MlxuICAgICAgICAgICAgICAgIF07XG4gICAgICAgIH0sXG4gICAgICAgIGEyYyA9IGZ1bmN0aW9uICh4MSwgeTEsIHJ4LCByeSwgYW5nbGUsIGxhcmdlX2FyY19mbGFnLCBzd2VlcF9mbGFnLCB4MiwgeTIsIHJlY3Vyc2l2ZSkge1xuICAgICAgICAgICAgLy8gZm9yIG1vcmUgaW5mb3JtYXRpb24gb2Ygd2hlcmUgdGhpcyBtYXRoIGNhbWUgZnJvbSB2aXNpdDpcbiAgICAgICAgICAgIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ltcGxub3RlLmh0bWwjQXJjSW1wbGVtZW50YXRpb25Ob3Rlc1xuICAgICAgICAgICAgdmFyIF8xMjAgPSBQSSAqIDEyMCAvIDE4MCxcbiAgICAgICAgICAgICAgICByYWQgPSBQSSAvIDE4MCAqICgrYW5nbGUgfHwgMCksXG4gICAgICAgICAgICAgICAgcmVzID0gW10sXG4gICAgICAgICAgICAgICAgeHksXG4gICAgICAgICAgICAgICAgcm90YXRlID0gY2FjaGVyKGZ1bmN0aW9uICh4LCB5LCByYWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIFggPSB4ICogbWF0aC5jb3MocmFkKSAtIHkgKiBtYXRoLnNpbihyYWQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgWSA9IHggKiBtYXRoLnNpbihyYWQpICsgeSAqIG1hdGguY29zKHJhZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7eDogWCwgeTogWX07XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoIXJlY3Vyc2l2ZSkge1xuICAgICAgICAgICAgICAgIHh5ID0gcm90YXRlKHgxLCB5MSwgLXJhZCk7XG4gICAgICAgICAgICAgICAgeDEgPSB4eS54O1xuICAgICAgICAgICAgICAgIHkxID0geHkueTtcbiAgICAgICAgICAgICAgICB4eSA9IHJvdGF0ZSh4MiwgeTIsIC1yYWQpO1xuICAgICAgICAgICAgICAgIHgyID0geHkueDtcbiAgICAgICAgICAgICAgICB5MiA9IHh5Lnk7XG4gICAgICAgICAgICAgICAgdmFyIGNvcyA9IG1hdGguY29zKFBJIC8gMTgwICogYW5nbGUpLFxuICAgICAgICAgICAgICAgICAgICBzaW4gPSBtYXRoLnNpbihQSSAvIDE4MCAqIGFuZ2xlKSxcbiAgICAgICAgICAgICAgICAgICAgeCA9ICh4MSAtIHgyKSAvIDIsXG4gICAgICAgICAgICAgICAgICAgIHkgPSAoeTEgLSB5MikgLyAyO1xuICAgICAgICAgICAgICAgIHZhciBoID0gKHggKiB4KSAvIChyeCAqIHJ4KSArICh5ICogeSkgLyAocnkgKiByeSk7XG4gICAgICAgICAgICAgICAgaWYgKGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGggPSBtYXRoLnNxcnQoaCk7XG4gICAgICAgICAgICAgICAgICAgIHJ4ID0gaCAqIHJ4O1xuICAgICAgICAgICAgICAgICAgICByeSA9IGggKiByeTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHJ4MiA9IHJ4ICogcngsXG4gICAgICAgICAgICAgICAgICAgIHJ5MiA9IHJ5ICogcnksXG4gICAgICAgICAgICAgICAgICAgIGsgPSAobGFyZ2VfYXJjX2ZsYWcgPT0gc3dlZXBfZmxhZyA/IC0xIDogMSkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0aC5zcXJ0KGFicygocngyICogcnkyIC0gcngyICogeSAqIHkgLSByeTIgKiB4ICogeCkgLyAocngyICogeSAqIHkgKyByeTIgKiB4ICogeCkpKSxcbiAgICAgICAgICAgICAgICAgICAgY3ggPSBrICogcnggKiB5IC8gcnkgKyAoeDEgKyB4MikgLyAyLFxuICAgICAgICAgICAgICAgICAgICBjeSA9IGsgKiAtcnkgKiB4IC8gcnggKyAoeTEgKyB5MikgLyAyLFxuICAgICAgICAgICAgICAgICAgICBmMSA9IG1hdGguYXNpbigoKHkxIC0gY3kpIC8gcnkpLnRvRml4ZWQoOSkpLFxuICAgICAgICAgICAgICAgICAgICBmMiA9IG1hdGguYXNpbigoKHkyIC0gY3kpIC8gcnkpLnRvRml4ZWQoOSkpO1xuXG4gICAgICAgICAgICAgICAgZjEgPSB4MSA8IGN4ID8gUEkgLSBmMSA6IGYxO1xuICAgICAgICAgICAgICAgIGYyID0geDIgPCBjeCA/IFBJIC0gZjIgOiBmMjtcbiAgICAgICAgICAgICAgICBmMSA8IDAgJiYgKGYxID0gUEkgKiAyICsgZjEpO1xuICAgICAgICAgICAgICAgIGYyIDwgMCAmJiAoZjIgPSBQSSAqIDIgKyBmMik7XG4gICAgICAgICAgICAgICAgaWYgKHN3ZWVwX2ZsYWcgJiYgZjEgPiBmMikge1xuICAgICAgICAgICAgICAgICAgICBmMSA9IGYxIC0gUEkgKiAyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXN3ZWVwX2ZsYWcgJiYgZjIgPiBmMSkge1xuICAgICAgICAgICAgICAgICAgICBmMiA9IGYyIC0gUEkgKiAyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZjEgPSByZWN1cnNpdmVbMF07XG4gICAgICAgICAgICAgICAgZjIgPSByZWN1cnNpdmVbMV07XG4gICAgICAgICAgICAgICAgY3ggPSByZWN1cnNpdmVbMl07XG4gICAgICAgICAgICAgICAgY3kgPSByZWN1cnNpdmVbM107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGYgPSBmMiAtIGYxO1xuICAgICAgICAgICAgaWYgKGFicyhkZikgPiBfMTIwKSB7XG4gICAgICAgICAgICAgICAgdmFyIGYyb2xkID0gZjIsXG4gICAgICAgICAgICAgICAgICAgIHgyb2xkID0geDIsXG4gICAgICAgICAgICAgICAgICAgIHkyb2xkID0geTI7XG4gICAgICAgICAgICAgICAgZjIgPSBmMSArIF8xMjAgKiAoc3dlZXBfZmxhZyAmJiBmMiA+IGYxID8gMSA6IC0xKTtcbiAgICAgICAgICAgICAgICB4MiA9IGN4ICsgcnggKiBtYXRoLmNvcyhmMik7XG4gICAgICAgICAgICAgICAgeTIgPSBjeSArIHJ5ICogbWF0aC5zaW4oZjIpO1xuICAgICAgICAgICAgICAgIHJlcyA9IGEyYyh4MiwgeTIsIHJ4LCByeSwgYW5nbGUsIDAsIHN3ZWVwX2ZsYWcsIHgyb2xkLCB5Mm9sZCwgW2YyLCBmMm9sZCwgY3gsIGN5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZiA9IGYyIC0gZjE7XG4gICAgICAgICAgICB2YXIgYzEgPSBtYXRoLmNvcyhmMSksXG4gICAgICAgICAgICAgICAgczEgPSBtYXRoLnNpbihmMSksXG4gICAgICAgICAgICAgICAgYzIgPSBtYXRoLmNvcyhmMiksXG4gICAgICAgICAgICAgICAgczIgPSBtYXRoLnNpbihmMiksXG4gICAgICAgICAgICAgICAgdCA9IG1hdGgudGFuKGRmIC8gNCksXG4gICAgICAgICAgICAgICAgaHggPSA0IC8gMyAqIHJ4ICogdCxcbiAgICAgICAgICAgICAgICBoeSA9IDQgLyAzICogcnkgKiB0LFxuICAgICAgICAgICAgICAgIG0xID0gW3gxLCB5MV0sXG4gICAgICAgICAgICAgICAgbTIgPSBbeDEgKyBoeCAqIHMxLCB5MSAtIGh5ICogYzFdLFxuICAgICAgICAgICAgICAgIG0zID0gW3gyICsgaHggKiBzMiwgeTIgLSBoeSAqIGMyXSxcbiAgICAgICAgICAgICAgICBtNCA9IFt4MiwgeTJdO1xuICAgICAgICAgICAgbTJbMF0gPSAyICogbTFbMF0gLSBtMlswXTtcbiAgICAgICAgICAgIG0yWzFdID0gMiAqIG0xWzFdIC0gbTJbMV07XG4gICAgICAgICAgICBpZiAocmVjdXJzaXZlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFttMiwgbTMsIG00XVtjb25jYXRdKHJlcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlcyA9IFttMiwgbTMsIG00XVtjb25jYXRdKHJlcykuam9pbigpW3NwbGl0XShcIixcIik7XG4gICAgICAgICAgICAgICAgdmFyIG5ld3JlcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHJlcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld3Jlc1tpXSA9IGkgJSAyID8gcm90YXRlKHJlc1tpIC0gMV0sIHJlc1tpXSwgcmFkKS55IDogcm90YXRlKHJlc1tpXSwgcmVzW2kgKyAxXSwgcmFkKS54O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3cmVzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmaW5kRG90QXRTZWdtZW50ID0gZnVuY3Rpb24gKHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCB0KSB7XG4gICAgICAgICAgICB2YXIgdDEgPSAxIC0gdDtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgeDogcG93KHQxLCAzKSAqIHAxeCArIHBvdyh0MSwgMikgKiAzICogdCAqIGMxeCArIHQxICogMyAqIHQgKiB0ICogYzJ4ICsgcG93KHQsIDMpICogcDJ4LFxuICAgICAgICAgICAgICAgIHk6IHBvdyh0MSwgMykgKiBwMXkgKyBwb3codDEsIDIpICogMyAqIHQgKiBjMXkgKyB0MSAqIDMgKiB0ICogdCAqIGMyeSArIHBvdyh0LCAzKSAqIHAyeVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgY3VydmVEaW0gPSBjYWNoZXIoZnVuY3Rpb24gKHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5KSB7XG4gICAgICAgICAgICB2YXIgYSA9IChjMnggLSAyICogYzF4ICsgcDF4KSAtIChwMnggLSAyICogYzJ4ICsgYzF4KSxcbiAgICAgICAgICAgICAgICBiID0gMiAqIChjMXggLSBwMXgpIC0gMiAqIChjMnggLSBjMXgpLFxuICAgICAgICAgICAgICAgIGMgPSBwMXggLSBjMXgsXG4gICAgICAgICAgICAgICAgdDEgPSAoLWIgKyBtYXRoLnNxcnQoYiAqIGIgLSA0ICogYSAqIGMpKSAvIDIgLyBhLFxuICAgICAgICAgICAgICAgIHQyID0gKC1iIC0gbWF0aC5zcXJ0KGIgKiBiIC0gNCAqIGEgKiBjKSkgLyAyIC8gYSxcbiAgICAgICAgICAgICAgICB5ID0gW3AxeSwgcDJ5XSxcbiAgICAgICAgICAgICAgICB4ID0gW3AxeCwgcDJ4XSxcbiAgICAgICAgICAgICAgICBkb3Q7XG4gICAgICAgICAgICBhYnModDEpID4gXCIxZTEyXCIgJiYgKHQxID0gLjUpO1xuICAgICAgICAgICAgYWJzKHQyKSA+IFwiMWUxMlwiICYmICh0MiA9IC41KTtcbiAgICAgICAgICAgIGlmICh0MSA+IDAgJiYgdDEgPCAxKSB7XG4gICAgICAgICAgICAgICAgZG90ID0gZmluZERvdEF0U2VnbWVudChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdDEpO1xuICAgICAgICAgICAgICAgIHgucHVzaChkb3QueCk7XG4gICAgICAgICAgICAgICAgeS5wdXNoKGRvdC55KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0MiA+IDAgJiYgdDIgPCAxKSB7XG4gICAgICAgICAgICAgICAgZG90ID0gZmluZERvdEF0U2VnbWVudChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdDIpO1xuICAgICAgICAgICAgICAgIHgucHVzaChkb3QueCk7XG4gICAgICAgICAgICAgICAgeS5wdXNoKGRvdC55KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGEgPSAoYzJ5IC0gMiAqIGMxeSArIHAxeSkgLSAocDJ5IC0gMiAqIGMyeSArIGMxeSk7XG4gICAgICAgICAgICBiID0gMiAqIChjMXkgLSBwMXkpIC0gMiAqIChjMnkgLSBjMXkpO1xuICAgICAgICAgICAgYyA9IHAxeSAtIGMxeTtcbiAgICAgICAgICAgIHQxID0gKC1iICsgbWF0aC5zcXJ0KGIgKiBiIC0gNCAqIGEgKiBjKSkgLyAyIC8gYTtcbiAgICAgICAgICAgIHQyID0gKC1iIC0gbWF0aC5zcXJ0KGIgKiBiIC0gNCAqIGEgKiBjKSkgLyAyIC8gYTtcbiAgICAgICAgICAgIGFicyh0MSkgPiBcIjFlMTJcIiAmJiAodDEgPSAuNSk7XG4gICAgICAgICAgICBhYnModDIpID4gXCIxZTEyXCIgJiYgKHQyID0gLjUpO1xuICAgICAgICAgICAgaWYgKHQxID4gMCAmJiB0MSA8IDEpIHtcbiAgICAgICAgICAgICAgICBkb3QgPSBmaW5kRG90QXRTZWdtZW50KHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCB0MSk7XG4gICAgICAgICAgICAgICAgeC5wdXNoKGRvdC54KTtcbiAgICAgICAgICAgICAgICB5LnB1c2goZG90LnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHQyID4gMCAmJiB0MiA8IDEpIHtcbiAgICAgICAgICAgICAgICBkb3QgPSBmaW5kRG90QXRTZWdtZW50KHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCB0Mik7XG4gICAgICAgICAgICAgICAgeC5wdXNoKGRvdC54KTtcbiAgICAgICAgICAgICAgICB5LnB1c2goZG90LnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBtaW46IHt4OiBtbWluW2FwcGx5XSgwLCB4KSwgeTogbW1pblthcHBseV0oMCwgeSl9LFxuICAgICAgICAgICAgICAgIG1heDoge3g6IG1tYXhbYXBwbHldKDAsIHgpLCB5OiBtbWF4W2FwcGx5XSgwLCB5KX1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pLFxuICAgICAgICBwYXRoMmN1cnZlID0gUi5fcGF0aDJjdXJ2ZSA9IGNhY2hlcihmdW5jdGlvbiAocGF0aCwgcGF0aDIpIHtcbiAgICAgICAgICAgIHZhciBwdGggPSAhcGF0aDIgJiYgcGF0aHMocGF0aCk7XG4gICAgICAgICAgICBpZiAoIXBhdGgyICYmIHB0aC5jdXJ2ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoQ2xvbmUocHRoLmN1cnZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBwID0gcGF0aFRvQWJzb2x1dGUocGF0aCksXG4gICAgICAgICAgICAgICAgcDIgPSBwYXRoMiAmJiBwYXRoVG9BYnNvbHV0ZShwYXRoMiksXG4gICAgICAgICAgICAgICAgYXR0cnMgPSB7eDogMCwgeTogMCwgYng6IDAsIGJ5OiAwLCBYOiAwLCBZOiAwLCBxeDogbnVsbCwgcXk6IG51bGx9LFxuICAgICAgICAgICAgICAgIGF0dHJzMiA9IHt4OiAwLCB5OiAwLCBieDogMCwgYnk6IDAsIFg6IDAsIFk6IDAsIHF4OiBudWxsLCBxeTogbnVsbH0sXG4gICAgICAgICAgICAgICAgcHJvY2Vzc1BhdGggPSBmdW5jdGlvbiAocGF0aCwgZCwgcGNvbSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbngsIG55LCB0cSA9IHtUOjEsIFE6MX07XG4gICAgICAgICAgICAgICAgICAgIGlmICghcGF0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtcIkNcIiwgZC54LCBkLnksIGQueCwgZC55LCBkLngsIGQueV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgIShwYXRoWzBdIGluIHRxKSAmJiAoZC5xeCA9IGQucXkgPSBudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChwYXRoWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiTVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQuWCA9IHBhdGhbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5ZID0gcGF0aFsyXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJBXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShhMmNbYXBwbHldKDAsIFtkLngsIGQueV1bY29uY2F0XShwYXRoLnNsaWNlKDEpKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcIlNcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGNvbSA9PSBcIkNcIiB8fCBwY29tID09IFwiU1wiKSB7IC8vIEluIFwiU1wiIGNhc2Ugd2UgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCwgaWYgdGhlIHByZXZpb3VzIGNvbW1hbmQgaXMgQy9TLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBueCA9IGQueCAqIDIgLSBkLmJ4OyAgICAgICAgICAvLyBBbmQgcmVmbGVjdCB0aGUgcHJldmlvdXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnkgPSBkLnkgKiAyIC0gZC5ieTsgICAgICAgICAgLy8gY29tbWFuZCdzIGNvbnRyb2wgcG9pbnQgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgcG9pbnQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvciBzb21lIGVsc2Ugb3Igbm90aGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBueCA9IGQueDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnkgPSBkLnk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBbXCJDXCIsIG54LCBueV1bY29uY2F0XShwYXRoLnNsaWNlKDEpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJUXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBjb20gPT0gXCJRXCIgfHwgcGNvbSA9PSBcIlRcIikgeyAvLyBJbiBcIlRcIiBjYXNlIHdlIGhhdmUgdG8gdGFrZSBpbnRvIGFjY291bnQsIGlmIHRoZSBwcmV2aW91cyBjb21tYW5kIGlzIFEvVC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeCA9IGQueCAqIDIgLSBkLnF4OyAgICAgICAgLy8gQW5kIG1ha2UgYSByZWZsZWN0aW9uIHNpbWlsYXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeSA9IGQueSAqIDIgLSBkLnF5OyAgICAgICAgLy8gdG8gY2FzZSBcIlNcIi5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yIHNvbWV0aGluZyBlbHNlIG9yIG5vdGhpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeCA9IGQueDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeSA9IGQueTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShxMmMoZC54LCBkLnksIGQucXgsIGQucXksIHBhdGhbMV0sIHBhdGhbMl0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJRXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeCA9IHBhdGhbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeSA9IHBhdGhbMl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShxMmMoZC54LCBkLnksIHBhdGhbMV0sIHBhdGhbMl0sIHBhdGhbM10sIHBhdGhbNF0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJMXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShsMmMoZC54LCBkLnksIHBhdGhbMV0sIHBhdGhbMl0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJIXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShsMmMoZC54LCBkLnksIHBhdGhbMV0sIGQueSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcIlZcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gW1wiQ1wiXVtjb25jYXRdKGwyYyhkLngsIGQueSwgZC54LCBwYXRoWzFdKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiWlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBbXCJDXCJdW2NvbmNhdF0obDJjKGQueCwgZC55LCBkLlgsIGQuWSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXRoO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZml4QXJjID0gZnVuY3Rpb24gKHBwLCBpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcFtpXS5sZW5ndGggPiA3KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcFtpXS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBpID0gcHBbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocGkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNvbXMxW2ldPVwiQVwiOyAvLyBpZiBjcmVhdGVkIG11bHRpcGxlIEM6cywgdGhlaXIgb3JpZ2luYWwgc2VnIGlzIHNhdmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcDIgJiYgKHBjb21zMltpXT1cIkFcIik7IC8vIHRoZSBzYW1lIGFzIGFib3ZlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHAuc3BsaWNlKGkrKywgMCwgW1wiQ1wiXVtjb25jYXRdKHBpLnNwbGljZSgwLCA2KSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcHAuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWkgPSBtbWF4KHAubGVuZ3RoLCBwMiAmJiBwMi5sZW5ndGggfHwgMCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGZpeE0gPSBmdW5jdGlvbiAocGF0aDEsIHBhdGgyLCBhMSwgYTIsIGkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGgxICYmIHBhdGgyICYmIHBhdGgxW2ldWzBdID09IFwiTVwiICYmIHBhdGgyW2ldWzBdICE9IFwiTVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRoMi5zcGxpY2UoaSwgMCwgW1wiTVwiLCBhMi54LCBhMi55XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhMS5ieCA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBhMS5ieSA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBhMS54ID0gcGF0aDFbaV1bMV07XG4gICAgICAgICAgICAgICAgICAgICAgICBhMS55ID0gcGF0aDFbaV1bMl07XG4gICAgICAgICAgICAgICAgICAgICAgICBpaSA9IG1tYXgocC5sZW5ndGgsIHAyICYmIHAyLmxlbmd0aCB8fCAwKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcGNvbXMxID0gW10sIC8vIHBhdGggY29tbWFuZHMgb2Ygb3JpZ2luYWwgcGF0aCBwXG4gICAgICAgICAgICAgICAgcGNvbXMyID0gW10sIC8vIHBhdGggY29tbWFuZHMgb2Ygb3JpZ2luYWwgcGF0aCBwMlxuICAgICAgICAgICAgICAgIHBmaXJzdCA9IFwiXCIsIC8vIHRlbXBvcmFyeSBob2xkZXIgZm9yIG9yaWdpbmFsIHBhdGggY29tbWFuZFxuICAgICAgICAgICAgICAgIHBjb20gPSBcIlwiOyAvLyBob2xkZXIgZm9yIHByZXZpb3VzIHBhdGggY29tbWFuZCBvZiBvcmlnaW5hbCBwYXRoXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBtbWF4KHAubGVuZ3RoLCBwMiAmJiBwMi5sZW5ndGggfHwgMCk7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcFtpXSAmJiAocGZpcnN0ID0gcFtpXVswXSk7IC8vIHNhdmUgY3VycmVudCBwYXRoIGNvbW1hbmRcblxuICAgICAgICAgICAgICAgIGlmIChwZmlyc3QgIT0gXCJDXCIpIC8vIEMgaXMgbm90IHNhdmVkIHlldCwgYmVjYXVzZSBpdCBtYXkgYmUgcmVzdWx0IG9mIGNvbnZlcnNpb25cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHBjb21zMVtpXSA9IHBmaXJzdDsgLy8gU2F2ZSBjdXJyZW50IHBhdGggY29tbWFuZFxuICAgICAgICAgICAgICAgICAgICBpICYmICggcGNvbSA9IHBjb21zMVtpLTFdKTsgLy8gR2V0IHByZXZpb3VzIHBhdGggY29tbWFuZCBwY29tXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBbaV0gPSBwcm9jZXNzUGF0aChwW2ldLCBhdHRycywgcGNvbSk7IC8vIFByZXZpb3VzIHBhdGggY29tbWFuZCBpcyBpbnB1dHRlZCB0byBwcm9jZXNzUGF0aFxuXG4gICAgICAgICAgICAgICAgaWYgKHBjb21zMVtpXSAhPSBcIkFcIiAmJiBwZmlyc3QgPT0gXCJDXCIpIHBjb21zMVtpXSA9IFwiQ1wiOyAvLyBBIGlzIHRoZSBvbmx5IGNvbW1hbmRcbiAgICAgICAgICAgICAgICAvLyB3aGljaCBtYXkgcHJvZHVjZSBtdWx0aXBsZSBDOnNcbiAgICAgICAgICAgICAgICAvLyBzbyB3ZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IEMgaXMgYWxzbyBDIGluIG9yaWdpbmFsIHBhdGhcblxuICAgICAgICAgICAgICAgIGZpeEFyYyhwLCBpKTsgLy8gZml4QXJjIGFkZHMgYWxzbyB0aGUgcmlnaHQgYW1vdW50IG9mIEE6cyB0byBwY29tczFcblxuICAgICAgICAgICAgICAgIGlmIChwMikgeyAvLyB0aGUgc2FtZSBwcm9jZWR1cmVzIGlzIGRvbmUgdG8gcDJcbiAgICAgICAgICAgICAgICAgICAgcDJbaV0gJiYgKHBmaXJzdCA9IHAyW2ldWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBmaXJzdCAhPSBcIkNcIilcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGNvbXMyW2ldID0gcGZpcnN0O1xuICAgICAgICAgICAgICAgICAgICAgICAgaSAmJiAocGNvbSA9IHBjb21zMltpLTFdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwMltpXSA9IHByb2Nlc3NQYXRoKHAyW2ldLCBhdHRyczIsIHBjb20pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwY29tczJbaV0hPVwiQVwiICYmIHBmaXJzdD09XCJDXCIpIHBjb21zMltpXT1cIkNcIjtcblxuICAgICAgICAgICAgICAgICAgICBmaXhBcmMocDIsIGkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmaXhNKHAsIHAyLCBhdHRycywgYXR0cnMyLCBpKTtcbiAgICAgICAgICAgICAgICBmaXhNKHAyLCBwLCBhdHRyczIsIGF0dHJzLCBpKTtcbiAgICAgICAgICAgICAgICB2YXIgc2VnID0gcFtpXSxcbiAgICAgICAgICAgICAgICAgICAgc2VnMiA9IHAyICYmIHAyW2ldLFxuICAgICAgICAgICAgICAgICAgICBzZWdsZW4gPSBzZWcubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICBzZWcybGVuID0gcDIgJiYgc2VnMi5sZW5ndGg7XG4gICAgICAgICAgICAgICAgYXR0cnMueCA9IHNlZ1tzZWdsZW4gLSAyXTtcbiAgICAgICAgICAgICAgICBhdHRycy55ID0gc2VnW3NlZ2xlbiAtIDFdO1xuICAgICAgICAgICAgICAgIGF0dHJzLmJ4ID0gdG9GbG9hdChzZWdbc2VnbGVuIC0gNF0pIHx8IGF0dHJzLng7XG4gICAgICAgICAgICAgICAgYXR0cnMuYnkgPSB0b0Zsb2F0KHNlZ1tzZWdsZW4gLSAzXSkgfHwgYXR0cnMueTtcbiAgICAgICAgICAgICAgICBhdHRyczIuYnggPSBwMiAmJiAodG9GbG9hdChzZWcyW3NlZzJsZW4gLSA0XSkgfHwgYXR0cnMyLngpO1xuICAgICAgICAgICAgICAgIGF0dHJzMi5ieSA9IHAyICYmICh0b0Zsb2F0KHNlZzJbc2VnMmxlbiAtIDNdKSB8fCBhdHRyczIueSk7XG4gICAgICAgICAgICAgICAgYXR0cnMyLnggPSBwMiAmJiBzZWcyW3NlZzJsZW4gLSAyXTtcbiAgICAgICAgICAgICAgICBhdHRyczIueSA9IHAyICYmIHNlZzJbc2VnMmxlbiAtIDFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFwMikge1xuICAgICAgICAgICAgICAgIHB0aC5jdXJ2ZSA9IHBhdGhDbG9uZShwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwMiA/IFtwLCBwMl0gOiBwO1xuICAgICAgICB9LCBudWxsLCBwYXRoQ2xvbmUpLFxuICAgICAgICBwYXJzZURvdHMgPSBSLl9wYXJzZURvdHMgPSBjYWNoZXIoZnVuY3Rpb24gKGdyYWRpZW50KSB7XG4gICAgICAgICAgICB2YXIgZG90cyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZ3JhZGllbnQubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBkb3QgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgcGFyID0gZ3JhZGllbnRbaV0ubWF0Y2goL14oW146XSopOj8oW1xcZFxcLl0qKS8pO1xuICAgICAgICAgICAgICAgIGRvdC5jb2xvciA9IFIuZ2V0UkdCKHBhclsxXSk7XG4gICAgICAgICAgICAgICAgaWYgKGRvdC5jb2xvci5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZG90Lm9wYWNpdHkgPSBkb3QuY29sb3Iub3BhY2l0eTtcbiAgICAgICAgICAgICAgICBkb3QuY29sb3IgPSBkb3QuY29sb3IuaGV4O1xuICAgICAgICAgICAgICAgIHBhclsyXSAmJiAoZG90Lm9mZnNldCA9IHBhclsyXSArIFwiJVwiKTtcbiAgICAgICAgICAgICAgICBkb3RzLnB1c2goZG90KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoaSA9IDEsIGlpID0gZG90cy5sZW5ndGggLSAxOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghZG90c1tpXS5vZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0YXJ0ID0gdG9GbG9hdChkb3RzW2kgLSAxXS5vZmZzZXQgfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmQgPSAwO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gaSArIDE7IGogPCBpaTsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG90c1tqXS5vZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQgPSBkb3RzW2pdLm9mZnNldDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIWVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW5kID0gMTAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgaiA9IGlpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVuZCA9IHRvRmxvYXQoZW5kKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGQgPSAoZW5kIC0gc3RhcnQpIC8gKGogLSBpICsgMSk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgajsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydCArPSBkO1xuICAgICAgICAgICAgICAgICAgICAgICAgZG90c1tpXS5vZmZzZXQgPSBzdGFydCArIFwiJVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRvdHM7XG4gICAgICAgIH0pLFxuICAgICAgICB0ZWFyID0gUi5fdGVhciA9IGZ1bmN0aW9uIChlbCwgcGFwZXIpIHtcbiAgICAgICAgICAgIGVsID09IHBhcGVyLnRvcCAmJiAocGFwZXIudG9wID0gZWwucHJldik7XG4gICAgICAgICAgICBlbCA9PSBwYXBlci5ib3R0b20gJiYgKHBhcGVyLmJvdHRvbSA9IGVsLm5leHQpO1xuICAgICAgICAgICAgZWwubmV4dCAmJiAoZWwubmV4dC5wcmV2ID0gZWwucHJldik7XG4gICAgICAgICAgICBlbC5wcmV2ICYmIChlbC5wcmV2Lm5leHQgPSBlbC5uZXh0KTtcbiAgICAgICAgfSxcbiAgICAgICAgdG9mcm9udCA9IFIuX3RvZnJvbnQgPSBmdW5jdGlvbiAoZWwsIHBhcGVyKSB7XG4gICAgICAgICAgICBpZiAocGFwZXIudG9wID09PSBlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRlYXIoZWwsIHBhcGVyKTtcbiAgICAgICAgICAgIGVsLm5leHQgPSBudWxsO1xuICAgICAgICAgICAgZWwucHJldiA9IHBhcGVyLnRvcDtcbiAgICAgICAgICAgIHBhcGVyLnRvcC5uZXh0ID0gZWw7XG4gICAgICAgICAgICBwYXBlci50b3AgPSBlbDtcbiAgICAgICAgfSxcbiAgICAgICAgdG9iYWNrID0gUi5fdG9iYWNrID0gZnVuY3Rpb24gKGVsLCBwYXBlcikge1xuICAgICAgICAgICAgaWYgKHBhcGVyLmJvdHRvbSA9PT0gZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZWFyKGVsLCBwYXBlcik7XG4gICAgICAgICAgICBlbC5uZXh0ID0gcGFwZXIuYm90dG9tO1xuICAgICAgICAgICAgZWwucHJldiA9IG51bGw7XG4gICAgICAgICAgICBwYXBlci5ib3R0b20ucHJldiA9IGVsO1xuICAgICAgICAgICAgcGFwZXIuYm90dG9tID0gZWw7XG4gICAgICAgIH0sXG4gICAgICAgIGluc2VydGFmdGVyID0gUi5faW5zZXJ0YWZ0ZXIgPSBmdW5jdGlvbiAoZWwsIGVsMiwgcGFwZXIpIHtcbiAgICAgICAgICAgIHRlYXIoZWwsIHBhcGVyKTtcbiAgICAgICAgICAgIGVsMiA9PSBwYXBlci50b3AgJiYgKHBhcGVyLnRvcCA9IGVsKTtcbiAgICAgICAgICAgIGVsMi5uZXh0ICYmIChlbDIubmV4dC5wcmV2ID0gZWwpO1xuICAgICAgICAgICAgZWwubmV4dCA9IGVsMi5uZXh0O1xuICAgICAgICAgICAgZWwucHJldiA9IGVsMjtcbiAgICAgICAgICAgIGVsMi5uZXh0ID0gZWw7XG4gICAgICAgIH0sXG4gICAgICAgIGluc2VydGJlZm9yZSA9IFIuX2luc2VydGJlZm9yZSA9IGZ1bmN0aW9uIChlbCwgZWwyLCBwYXBlcikge1xuICAgICAgICAgICAgdGVhcihlbCwgcGFwZXIpO1xuICAgICAgICAgICAgZWwyID09IHBhcGVyLmJvdHRvbSAmJiAocGFwZXIuYm90dG9tID0gZWwpO1xuICAgICAgICAgICAgZWwyLnByZXYgJiYgKGVsMi5wcmV2Lm5leHQgPSBlbCk7XG4gICAgICAgICAgICBlbC5wcmV2ID0gZWwyLnByZXY7XG4gICAgICAgICAgICBlbDIucHJldiA9IGVsO1xuICAgICAgICAgICAgZWwubmV4dCA9IGVsMjtcbiAgICAgICAgfSxcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBSYXBoYWVsLnRvTWF0cml4XG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBVdGlsaXR5IG1ldGhvZFxuICAgICAgICAgKipcbiAgICAgICAgICogUmV0dXJucyBtYXRyaXggb2YgdHJhbnNmb3JtYXRpb25zIGFwcGxpZWQgdG8gYSBnaXZlbiBwYXRoXG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0gcGF0aCAoc3RyaW5nKSBwYXRoIHN0cmluZ1xuICAgICAgICAgLSB0cmFuc2Zvcm0gKHN0cmluZ3xhcnJheSkgdHJhbnNmb3JtYXRpb24gc3RyaW5nXG4gICAgICAgICA9IChvYmplY3QpIEBNYXRyaXhcbiAgICAgICAgXFwqL1xuICAgICAgICB0b01hdHJpeCA9IFIudG9NYXRyaXggPSBmdW5jdGlvbiAocGF0aCwgdHJhbnNmb3JtKSB7XG4gICAgICAgICAgICB2YXIgYmIgPSBwYXRoRGltZW5zaW9ucyhwYXRoKSxcbiAgICAgICAgICAgICAgICBlbCA9IHtcbiAgICAgICAgICAgICAgICAgICAgXzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiBFXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGdldEJCb3g6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBiYjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBleHRyYWN0VHJhbnNmb3JtKGVsLCB0cmFuc2Zvcm0pO1xuICAgICAgICAgICAgcmV0dXJuIGVsLm1hdHJpeDtcbiAgICAgICAgfSxcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBSYXBoYWVsLnRyYW5zZm9ybVBhdGhcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICAgICAqKlxuICAgICAgICAgKiBSZXR1cm5zIHBhdGggdHJhbnNmb3JtZWQgYnkgYSBnaXZlbiB0cmFuc2Zvcm1hdGlvblxuICAgICAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICAgICAtIHBhdGggKHN0cmluZykgcGF0aCBzdHJpbmdcbiAgICAgICAgIC0gdHJhbnNmb3JtIChzdHJpbmd8YXJyYXkpIHRyYW5zZm9ybWF0aW9uIHN0cmluZ1xuICAgICAgICAgPSAoc3RyaW5nKSBwYXRoXG4gICAgICAgIFxcKi9cbiAgICAgICAgdHJhbnNmb3JtUGF0aCA9IFIudHJhbnNmb3JtUGF0aCA9IGZ1bmN0aW9uIChwYXRoLCB0cmFuc2Zvcm0pIHtcbiAgICAgICAgICAgIHJldHVybiBtYXBQYXRoKHBhdGgsIHRvTWF0cml4KHBhdGgsIHRyYW5zZm9ybSkpO1xuICAgICAgICB9LFxuICAgICAgICBleHRyYWN0VHJhbnNmb3JtID0gUi5fZXh0cmFjdFRyYW5zZm9ybSA9IGZ1bmN0aW9uIChlbCwgdHN0cikge1xuICAgICAgICAgICAgaWYgKHRzdHIgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbC5fLnRyYW5zZm9ybTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRzdHIgPSBTdHIodHN0cikucmVwbGFjZSgvXFwuezN9fFxcdTIwMjYvZywgZWwuXy50cmFuc2Zvcm0gfHwgRSk7XG4gICAgICAgICAgICB2YXIgdGRhdGEgPSBSLnBhcnNlVHJhbnNmb3JtU3RyaW5nKHRzdHIpLFxuICAgICAgICAgICAgICAgIGRlZyA9IDAsXG4gICAgICAgICAgICAgICAgZHggPSAwLFxuICAgICAgICAgICAgICAgIGR5ID0gMCxcbiAgICAgICAgICAgICAgICBzeCA9IDEsXG4gICAgICAgICAgICAgICAgc3kgPSAxLFxuICAgICAgICAgICAgICAgIF8gPSBlbC5fLFxuICAgICAgICAgICAgICAgIG0gPSBuZXcgTWF0cml4O1xuICAgICAgICAgICAgXy50cmFuc2Zvcm0gPSB0ZGF0YSB8fCBbXTtcbiAgICAgICAgICAgIGlmICh0ZGF0YSkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRkYXRhLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSB0ZGF0YVtpXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRsZW4gPSB0Lmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBTdHIodFswXSkudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFic29sdXRlID0gdFswXSAhPSBjb21tYW5kLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW52ZXIgPSBhYnNvbHV0ZSA/IG0uaW52ZXJ0KCkgOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgeDEsXG4gICAgICAgICAgICAgICAgICAgICAgICB5MSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHgyLFxuICAgICAgICAgICAgICAgICAgICAgICAgeTIsXG4gICAgICAgICAgICAgICAgICAgICAgICBiYjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbW1hbmQgPT0gXCJ0XCIgJiYgdGxlbiA9PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWJzb2x1dGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4MSA9IGludmVyLngoMCwgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTEgPSBpbnZlci55KDAsIDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgyID0gaW52ZXIueCh0WzFdLCB0WzJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MiA9IGludmVyLnkodFsxXSwgdFsyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbS50cmFuc2xhdGUoeDIgLSB4MSwgeTIgLSB5MSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0udHJhbnNsYXRlKHRbMV0sIHRbMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gXCJyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bGVuID09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYiA9IGJiIHx8IGVsLmdldEJCb3goMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5yb3RhdGUodFsxXSwgYmIueCArIGJiLndpZHRoIC8gMiwgYmIueSArIGJiLmhlaWdodCAvIDIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZyArPSB0WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0bGVuID09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWJzb2x1dGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDIgPSBpbnZlci54KHRbMl0sIHRbM10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MiA9IGludmVyLnkodFsyXSwgdFszXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0ucm90YXRlKHRbMV0sIHgyLCB5Mik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5yb3RhdGUodFsxXSwgdFsyXSwgdFszXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZyArPSB0WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gXCJzXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bGVuID09IDIgfHwgdGxlbiA9PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmIgPSBiYiB8fCBlbC5nZXRCQm94KDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uc2NhbGUodFsxXSwgdFt0bGVuIC0gMV0sIGJiLnggKyBiYi53aWR0aCAvIDIsIGJiLnkgKyBiYi5oZWlnaHQgLyAyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeCAqPSB0WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5ICo9IHRbdGxlbiAtIDFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0bGVuID09IDUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWJzb2x1dGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDIgPSBpbnZlci54KHRbM10sIHRbNF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MiA9IGludmVyLnkodFszXSwgdFs0XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uc2NhbGUodFsxXSwgdFsyXSwgeDIsIHkyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtLnNjYWxlKHRbMV0sIHRbMl0sIHRbM10sIHRbNF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeCAqPSB0WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5ICo9IHRbMl07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSBcIm1cIiAmJiB0bGVuID09IDcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG0uYWRkKHRbMV0sIHRbMl0sIHRbM10sIHRbNF0sIHRbNV0sIHRbNl0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF8uZGlydHlUID0gMTtcbiAgICAgICAgICAgICAgICAgICAgZWwubWF0cml4ID0gbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qXFxcbiAgICAgICAgICAgICAqIEVsZW1lbnQubWF0cml4XG4gICAgICAgICAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICAgICAgICAgKipcbiAgICAgICAgICAgICAqIEtlZXBzIEBNYXRyaXggb2JqZWN0LCB3aGljaCByZXByZXNlbnRzIGVsZW1lbnQgdHJhbnNmb3JtYXRpb25cbiAgICAgICAgICAgIFxcKi9cbiAgICAgICAgICAgIGVsLm1hdHJpeCA9IG07XG5cbiAgICAgICAgICAgIF8uc3ggPSBzeDtcbiAgICAgICAgICAgIF8uc3kgPSBzeTtcbiAgICAgICAgICAgIF8uZGVnID0gZGVnO1xuICAgICAgICAgICAgXy5keCA9IGR4ID0gbS5lO1xuICAgICAgICAgICAgXy5keSA9IGR5ID0gbS5mO1xuXG4gICAgICAgICAgICBpZiAoc3ggPT0gMSAmJiBzeSA9PSAxICYmICFkZWcgJiYgXy5iYm94KSB7XG4gICAgICAgICAgICAgICAgXy5iYm94LnggKz0gK2R4O1xuICAgICAgICAgICAgICAgIF8uYmJveC55ICs9ICtkeTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgXy5kaXJ0eVQgPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBnZXRFbXB0eSA9IGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICB2YXIgbCA9IGl0ZW1bMF07XG4gICAgICAgICAgICBzd2l0Y2ggKGwudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJ0XCI6IHJldHVybiBbbCwgMCwgMF07XG4gICAgICAgICAgICAgICAgY2FzZSBcIm1cIjogcmV0dXJuIFtsLCAxLCAwLCAwLCAxLCAwLCAwXTtcbiAgICAgICAgICAgICAgICBjYXNlIFwiclwiOiBpZiAoaXRlbS5sZW5ndGggPT0gNCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW2wsIDAsIGl0ZW1bMl0sIGl0ZW1bM11dO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbbCwgMF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgXCJzXCI6IGlmIChpdGVtLmxlbmd0aCA9PSA1KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbbCwgMSwgMSwgaXRlbVszXSwgaXRlbVs0XV07XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpdGVtLmxlbmd0aCA9PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbbCwgMSwgMV07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtsLCAxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVxdWFsaXNlVHJhbnNmb3JtID0gUi5fZXF1YWxpc2VUcmFuc2Zvcm0gPSBmdW5jdGlvbiAodDEsIHQyKSB7XG4gICAgICAgICAgICB0MiA9IFN0cih0MikucmVwbGFjZSgvXFwuezN9fFxcdTIwMjYvZywgdDEpO1xuICAgICAgICAgICAgdDEgPSBSLnBhcnNlVHJhbnNmb3JtU3RyaW5nKHQxKSB8fCBbXTtcbiAgICAgICAgICAgIHQyID0gUi5wYXJzZVRyYW5zZm9ybVN0cmluZyh0MikgfHwgW107XG4gICAgICAgICAgICB2YXIgbWF4bGVuZ3RoID0gbW1heCh0MS5sZW5ndGgsIHQyLmxlbmd0aCksXG4gICAgICAgICAgICAgICAgZnJvbSA9IFtdLFxuICAgICAgICAgICAgICAgIHRvID0gW10sXG4gICAgICAgICAgICAgICAgaSA9IDAsIGosIGpqLFxuICAgICAgICAgICAgICAgIHR0MSwgdHQyO1xuICAgICAgICAgICAgZm9yICg7IGkgPCBtYXhsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHR0MSA9IHQxW2ldIHx8IGdldEVtcHR5KHQyW2ldKTtcbiAgICAgICAgICAgICAgICB0dDIgPSB0MltpXSB8fCBnZXRFbXB0eSh0dDEpO1xuICAgICAgICAgICAgICAgIGlmICgodHQxWzBdICE9IHR0MlswXSkgfHxcbiAgICAgICAgICAgICAgICAgICAgKHR0MVswXS50b0xvd2VyQ2FzZSgpID09IFwiclwiICYmICh0dDFbMl0gIT0gdHQyWzJdIHx8IHR0MVszXSAhPSB0dDJbM10pKSB8fFxuICAgICAgICAgICAgICAgICAgICAodHQxWzBdLnRvTG93ZXJDYXNlKCkgPT0gXCJzXCIgJiYgKHR0MVszXSAhPSB0dDJbM10gfHwgdHQxWzRdICE9IHR0Mls0XSkpXG4gICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZyb21baV0gPSBbXTtcbiAgICAgICAgICAgICAgICB0b1tpXSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAoaiA9IDAsIGpqID0gbW1heCh0dDEubGVuZ3RoLCB0dDIubGVuZ3RoKTsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaiBpbiB0dDEgJiYgKGZyb21baV1bal0gPSB0dDFbal0pO1xuICAgICAgICAgICAgICAgICAgICBqIGluIHR0MiAmJiAodG9baV1bal0gPSB0dDJbal0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZnJvbTogZnJvbSxcbiAgICAgICAgICAgICAgICB0bzogdG9cbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgUi5fZ2V0Q29udGFpbmVyID0gZnVuY3Rpb24gKHgsIHksIHcsIGgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lcjtcbiAgICAgICAgY29udGFpbmVyID0gaCA9PSBudWxsICYmICFSLmlzKHgsIFwib2JqZWN0XCIpID8gZy5kb2MuZ2V0RWxlbWVudEJ5SWQoeCkgOiB4O1xuICAgICAgICBpZiAoY29udGFpbmVyID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udGFpbmVyLnRhZ05hbWUpIHtcbiAgICAgICAgICAgIGlmICh5ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb250YWluZXI6IGNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGNvbnRhaW5lci5zdHlsZS5waXhlbFdpZHRoIHx8IGNvbnRhaW5lci5vZmZzZXRXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBjb250YWluZXIuc3R5bGUucGl4ZWxIZWlnaHQgfHwgY29udGFpbmVyLm9mZnNldEhlaWdodFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogY29udGFpbmVyLFxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogeSxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGFpbmVyOiAxLFxuICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICB3aWR0aDogdyxcbiAgICAgICAgICAgIGhlaWdodDogaFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwucGF0aFRvUmVsYXRpdmVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogQ29udmVydHMgcGF0aCB0byByZWxhdGl2ZSBmb3JtXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIHBhdGhTdHJpbmcgKHN0cmluZ3xhcnJheSkgcGF0aCBzdHJpbmcgb3IgYXJyYXkgb2Ygc2VnbWVudHNcbiAgICAgPSAoYXJyYXkpIGFycmF5IG9mIHNlZ21lbnRzLlxuICAgIFxcKi9cbiAgICBSLnBhdGhUb1JlbGF0aXZlID0gcGF0aFRvUmVsYXRpdmU7XG4gICAgUi5fZW5naW5lID0ge307XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwucGF0aDJjdXJ2ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogVXRpbGl0eSBtZXRob2RcbiAgICAgKipcbiAgICAgKiBDb252ZXJ0cyBwYXRoIHRvIGEgbmV3IHBhdGggd2hlcmUgYWxsIHNlZ21lbnRzIGFyZSBjdWJpYyBiZXppZXIgY3VydmVzLlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBwYXRoU3RyaW5nIChzdHJpbmd8YXJyYXkpIHBhdGggc3RyaW5nIG9yIGFycmF5IG9mIHNlZ21lbnRzXG4gICAgID0gKGFycmF5KSBhcnJheSBvZiBzZWdtZW50cy5cbiAgICBcXCovXG4gICAgUi5wYXRoMmN1cnZlID0gcGF0aDJjdXJ2ZTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5tYXRyaXhcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogUmV0dXJucyBtYXRyaXggYmFzZWQgb24gZ2l2ZW4gcGFyYW1ldGVycy5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gYSAobnVtYmVyKVxuICAgICAtIGIgKG51bWJlcilcbiAgICAgLSBjIChudW1iZXIpXG4gICAgIC0gZCAobnVtYmVyKVxuICAgICAtIGUgKG51bWJlcilcbiAgICAgLSBmIChudW1iZXIpXG4gICAgID0gKG9iamVjdCkgQE1hdHJpeFxuICAgIFxcKi9cbiAgICBSLm1hdHJpeCA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkLCBlLCBmKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWF0cml4KGEsIGIsIGMsIGQsIGUsIGYpO1xuICAgIH07XG4gICAgZnVuY3Rpb24gTWF0cml4KGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICAgICAgaWYgKGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5hID0gK2E7XG4gICAgICAgICAgICB0aGlzLmIgPSArYjtcbiAgICAgICAgICAgIHRoaXMuYyA9ICtjO1xuICAgICAgICAgICAgdGhpcy5kID0gK2Q7XG4gICAgICAgICAgICB0aGlzLmUgPSArZTtcbiAgICAgICAgICAgIHRoaXMuZiA9ICtmO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hID0gMTtcbiAgICAgICAgICAgIHRoaXMuYiA9IDA7XG4gICAgICAgICAgICB0aGlzLmMgPSAwO1xuICAgICAgICAgICAgdGhpcy5kID0gMTtcbiAgICAgICAgICAgIHRoaXMuZSA9IDA7XG4gICAgICAgICAgICB0aGlzLmYgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIChmdW5jdGlvbiAobWF0cml4cHJvdG8pIHtcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBNYXRyaXguYWRkXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBBZGRzIGdpdmVuIG1hdHJpeCB0byBleGlzdGluZyBvbmUuXG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0gYSAobnVtYmVyKVxuICAgICAgICAgLSBiIChudW1iZXIpXG4gICAgICAgICAtIGMgKG51bWJlcilcbiAgICAgICAgIC0gZCAobnVtYmVyKVxuICAgICAgICAgLSBlIChudW1iZXIpXG4gICAgICAgICAtIGYgKG51bWJlcilcbiAgICAgICAgIG9yXG4gICAgICAgICAtIG1hdHJpeCAob2JqZWN0KSBATWF0cml4XG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8uYWRkID0gZnVuY3Rpb24gKGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICAgICAgICAgIHZhciBvdXQgPSBbW10sIFtdLCBbXV0sXG4gICAgICAgICAgICAgICAgbSA9IFtbdGhpcy5hLCB0aGlzLmMsIHRoaXMuZV0sIFt0aGlzLmIsIHRoaXMuZCwgdGhpcy5mXSwgWzAsIDAsIDFdXSxcbiAgICAgICAgICAgICAgICBtYXRyaXggPSBbW2EsIGMsIGVdLCBbYiwgZCwgZl0sIFswLCAwLCAxXV0sXG4gICAgICAgICAgICAgICAgeCwgeSwgeiwgcmVzO1xuXG4gICAgICAgICAgICBpZiAoYSAmJiBhIGluc3RhbmNlb2YgTWF0cml4KSB7XG4gICAgICAgICAgICAgICAgbWF0cml4ID0gW1thLmEsIGEuYywgYS5lXSwgW2EuYiwgYS5kLCBhLmZdLCBbMCwgMCwgMV1dO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgMzsgeCsrKSB7XG4gICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IDM7IHkrKykge1xuICAgICAgICAgICAgICAgICAgICByZXMgPSAwO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHogPSAwOyB6IDwgMzsgeisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXMgKz0gbVt4XVt6XSAqIG1hdHJpeFt6XVt5XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBvdXRbeF1beV0gPSByZXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hID0gb3V0WzBdWzBdO1xuICAgICAgICAgICAgdGhpcy5iID0gb3V0WzFdWzBdO1xuICAgICAgICAgICAgdGhpcy5jID0gb3V0WzBdWzFdO1xuICAgICAgICAgICAgdGhpcy5kID0gb3V0WzFdWzFdO1xuICAgICAgICAgICAgdGhpcy5lID0gb3V0WzBdWzJdO1xuICAgICAgICAgICAgdGhpcy5mID0gb3V0WzFdWzJdO1xuICAgICAgICB9O1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIE1hdHJpeC5pbnZlcnRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFJldHVybnMgaW52ZXJ0ZWQgdmVyc2lvbiBvZiB0aGUgbWF0cml4XG4gICAgICAgICA9IChvYmplY3QpIEBNYXRyaXhcbiAgICAgICAgXFwqL1xuICAgICAgICBtYXRyaXhwcm90by5pbnZlcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgbWUgPSB0aGlzLFxuICAgICAgICAgICAgICAgIHggPSBtZS5hICogbWUuZCAtIG1lLmIgKiBtZS5jO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRyaXgobWUuZCAvIHgsIC1tZS5iIC8geCwgLW1lLmMgLyB4LCBtZS5hIC8geCwgKG1lLmMgKiBtZS5mIC0gbWUuZCAqIG1lLmUpIC8geCwgKG1lLmIgKiBtZS5lIC0gbWUuYSAqIG1lLmYpIC8geCk7XG4gICAgICAgIH07XG4gICAgICAgIC8qXFxcbiAgICAgICAgICogTWF0cml4LmNsb25lXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBSZXR1cm5zIGNvcHkgb2YgdGhlIG1hdHJpeFxuICAgICAgICAgPSAob2JqZWN0KSBATWF0cml4XG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8uY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1hdHJpeCh0aGlzLmEsIHRoaXMuYiwgdGhpcy5jLCB0aGlzLmQsIHRoaXMuZSwgdGhpcy5mKTtcbiAgICAgICAgfTtcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBNYXRyaXgudHJhbnNsYXRlXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBUcmFuc2xhdGUgdGhlIG1hdHJpeFxuICAgICAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICAgICAtIHggKG51bWJlcilcbiAgICAgICAgIC0geSAobnVtYmVyKVxuICAgICAgICBcXCovXG4gICAgICAgIG1hdHJpeHByb3RvLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgICAgICB0aGlzLmFkZCgxLCAwLCAwLCAxLCB4LCB5KTtcbiAgICAgICAgfTtcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBNYXRyaXguc2NhbGVcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFNjYWxlcyB0aGUgbWF0cml4XG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0geCAobnVtYmVyKVxuICAgICAgICAgLSB5IChudW1iZXIpICNvcHRpb25hbFxuICAgICAgICAgLSBjeCAobnVtYmVyKSAjb3B0aW9uYWxcbiAgICAgICAgIC0gY3kgKG51bWJlcikgI29wdGlvbmFsXG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8uc2NhbGUgPSBmdW5jdGlvbiAoeCwgeSwgY3gsIGN5KSB7XG4gICAgICAgICAgICB5ID09IG51bGwgJiYgKHkgPSB4KTtcbiAgICAgICAgICAgIChjeCB8fCBjeSkgJiYgdGhpcy5hZGQoMSwgMCwgMCwgMSwgY3gsIGN5KTtcbiAgICAgICAgICAgIHRoaXMuYWRkKHgsIDAsIDAsIHksIDAsIDApO1xuICAgICAgICAgICAgKGN4IHx8IGN5KSAmJiB0aGlzLmFkZCgxLCAwLCAwLCAxLCAtY3gsIC1jeSk7XG4gICAgICAgIH07XG4gICAgICAgIC8qXFxcbiAgICAgICAgICogTWF0cml4LnJvdGF0ZVxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKipcbiAgICAgICAgICogUm90YXRlcyB0aGUgbWF0cml4XG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0gYSAobnVtYmVyKVxuICAgICAgICAgLSB4IChudW1iZXIpXG4gICAgICAgICAtIHkgKG51bWJlcilcbiAgICAgICAgXFwqL1xuICAgICAgICBtYXRyaXhwcm90by5yb3RhdGUgPSBmdW5jdGlvbiAoYSwgeCwgeSkge1xuICAgICAgICAgICAgYSA9IFIucmFkKGEpO1xuICAgICAgICAgICAgeCA9IHggfHwgMDtcbiAgICAgICAgICAgIHkgPSB5IHx8IDA7XG4gICAgICAgICAgICB2YXIgY29zID0gK21hdGguY29zKGEpLnRvRml4ZWQoOSksXG4gICAgICAgICAgICAgICAgc2luID0gK21hdGguc2luKGEpLnRvRml4ZWQoOSk7XG4gICAgICAgICAgICB0aGlzLmFkZChjb3MsIHNpbiwgLXNpbiwgY29zLCB4LCB5KTtcbiAgICAgICAgICAgIHRoaXMuYWRkKDEsIDAsIDAsIDEsIC14LCAteSk7XG4gICAgICAgIH07XG4gICAgICAgIC8qXFxcbiAgICAgICAgICogTWF0cml4LnhcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFJldHVybiB4IGNvb3JkaW5hdGUgZm9yIGdpdmVuIHBvaW50IGFmdGVyIHRyYW5zZm9ybWF0aW9uIGRlc2NyaWJlZCBieSB0aGUgbWF0cml4LiBTZWUgYWxzbyBATWF0cml4LnlcbiAgICAgICAgID4gUGFyYW1ldGVyc1xuICAgICAgICAgLSB4IChudW1iZXIpXG4gICAgICAgICAtIHkgKG51bWJlcilcbiAgICAgICAgID0gKG51bWJlcikgeFxuICAgICAgICBcXCovXG4gICAgICAgIG1hdHJpeHByb3RvLnggPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICAgICAgcmV0dXJuIHggKiB0aGlzLmEgKyB5ICogdGhpcy5jICsgdGhpcy5lO1xuICAgICAgICB9O1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIE1hdHJpeC55XG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBSZXR1cm4geSBjb29yZGluYXRlIGZvciBnaXZlbiBwb2ludCBhZnRlciB0cmFuc2Zvcm1hdGlvbiBkZXNjcmliZWQgYnkgdGhlIG1hdHJpeC4gU2VlIGFsc28gQE1hdHJpeC54XG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0geCAobnVtYmVyKVxuICAgICAgICAgLSB5IChudW1iZXIpXG4gICAgICAgICA9IChudW1iZXIpIHlcbiAgICAgICAgXFwqL1xuICAgICAgICBtYXRyaXhwcm90by55ID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgICAgIHJldHVybiB4ICogdGhpcy5iICsgeSAqIHRoaXMuZCArIHRoaXMuZjtcbiAgICAgICAgfTtcbiAgICAgICAgbWF0cml4cHJvdG8uZ2V0ID0gZnVuY3Rpb24gKGkpIHtcbiAgICAgICAgICAgIHJldHVybiArdGhpc1tTdHIuZnJvbUNoYXJDb2RlKDk3ICsgaSldLnRvRml4ZWQoNCk7XG4gICAgICAgIH07XG4gICAgICAgIG1hdHJpeHByb3RvLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIFIuc3ZnID9cbiAgICAgICAgICAgICAgICBcIm1hdHJpeChcIiArIFt0aGlzLmdldCgwKSwgdGhpcy5nZXQoMSksIHRoaXMuZ2V0KDIpLCB0aGlzLmdldCgzKSwgdGhpcy5nZXQoNCksIHRoaXMuZ2V0KDUpXS5qb2luKCkgKyBcIilcIiA6XG4gICAgICAgICAgICAgICAgW3RoaXMuZ2V0KDApLCB0aGlzLmdldCgyKSwgdGhpcy5nZXQoMSksIHRoaXMuZ2V0KDMpLCAwLCAwXS5qb2luKCk7XG4gICAgICAgIH07XG4gICAgICAgIG1hdHJpeHByb3RvLnRvRmlsdGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIFwicHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0Lk1hdHJpeChNMTE9XCIgKyB0aGlzLmdldCgwKSArXG4gICAgICAgICAgICAgICAgXCIsIE0xMj1cIiArIHRoaXMuZ2V0KDIpICsgXCIsIE0yMT1cIiArIHRoaXMuZ2V0KDEpICsgXCIsIE0yMj1cIiArIHRoaXMuZ2V0KDMpICtcbiAgICAgICAgICAgICAgICBcIiwgRHg9XCIgKyB0aGlzLmdldCg0KSArIFwiLCBEeT1cIiArIHRoaXMuZ2V0KDUpICsgXCIsIHNpemluZ21ldGhvZD0nYXV0byBleHBhbmQnKVwiO1xuICAgICAgICB9O1xuICAgICAgICBtYXRyaXhwcm90by5vZmZzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gW3RoaXMuZS50b0ZpeGVkKDQpLCB0aGlzLmYudG9GaXhlZCg0KV07XG4gICAgICAgIH07XG4gICAgICAgIGZ1bmN0aW9uIG5vcm0oYSkge1xuICAgICAgICAgICAgcmV0dXJuIGFbMF0gKiBhWzBdICsgYVsxXSAqIGFbMV07XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbm9ybWFsaXplKGEpIHtcbiAgICAgICAgICAgIHZhciBtYWcgPSBtYXRoLnNxcnQobm9ybShhKSk7XG4gICAgICAgICAgICBhWzBdICYmIChhWzBdIC89IG1hZyk7XG4gICAgICAgICAgICBhWzFdICYmIChhWzFdIC89IG1hZyk7XG4gICAgICAgIH1cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBNYXRyaXguc3BsaXRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFNwbGl0cyBtYXRyaXggaW50byBwcmltaXRpdmUgdHJhbnNmb3JtYXRpb25zXG4gICAgICAgICA9IChvYmplY3QpIGluIGZvcm1hdDpcbiAgICAgICAgIG8gZHggKG51bWJlcikgdHJhbnNsYXRpb24gYnkgeFxuICAgICAgICAgbyBkeSAobnVtYmVyKSB0cmFuc2xhdGlvbiBieSB5XG4gICAgICAgICBvIHNjYWxleCAobnVtYmVyKSBzY2FsZSBieSB4XG4gICAgICAgICBvIHNjYWxleSAobnVtYmVyKSBzY2FsZSBieSB5XG4gICAgICAgICBvIHNoZWFyIChudW1iZXIpIHNoZWFyXG4gICAgICAgICBvIHJvdGF0ZSAobnVtYmVyKSByb3RhdGlvbiBpbiBkZWdcbiAgICAgICAgIG8gaXNTaW1wbGUgKGJvb2xlYW4pIGNvdWxkIGl0IGJlIHJlcHJlc2VudGVkIHZpYSBzaW1wbGUgdHJhbnNmb3JtYXRpb25zXG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8uc3BsaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgb3V0ID0ge307XG4gICAgICAgICAgICAvLyB0cmFuc2xhdGlvblxuICAgICAgICAgICAgb3V0LmR4ID0gdGhpcy5lO1xuICAgICAgICAgICAgb3V0LmR5ID0gdGhpcy5mO1xuXG4gICAgICAgICAgICAvLyBzY2FsZSBhbmQgc2hlYXJcbiAgICAgICAgICAgIHZhciByb3cgPSBbW3RoaXMuYSwgdGhpcy5jXSwgW3RoaXMuYiwgdGhpcy5kXV07XG4gICAgICAgICAgICBvdXQuc2NhbGV4ID0gbWF0aC5zcXJ0KG5vcm0ocm93WzBdKSk7XG4gICAgICAgICAgICBub3JtYWxpemUocm93WzBdKTtcblxuICAgICAgICAgICAgb3V0LnNoZWFyID0gcm93WzBdWzBdICogcm93WzFdWzBdICsgcm93WzBdWzFdICogcm93WzFdWzFdO1xuICAgICAgICAgICAgcm93WzFdID0gW3Jvd1sxXVswXSAtIHJvd1swXVswXSAqIG91dC5zaGVhciwgcm93WzFdWzFdIC0gcm93WzBdWzFdICogb3V0LnNoZWFyXTtcblxuICAgICAgICAgICAgb3V0LnNjYWxleSA9IG1hdGguc3FydChub3JtKHJvd1sxXSkpO1xuICAgICAgICAgICAgbm9ybWFsaXplKHJvd1sxXSk7XG4gICAgICAgICAgICBvdXQuc2hlYXIgLz0gb3V0LnNjYWxleTtcblxuICAgICAgICAgICAgLy8gcm90YXRpb25cbiAgICAgICAgICAgIHZhciBzaW4gPSAtcm93WzBdWzFdLFxuICAgICAgICAgICAgICAgIGNvcyA9IHJvd1sxXVsxXTtcbiAgICAgICAgICAgIGlmIChjb3MgPCAwKSB7XG4gICAgICAgICAgICAgICAgb3V0LnJvdGF0ZSA9IFIuZGVnKG1hdGguYWNvcyhjb3MpKTtcbiAgICAgICAgICAgICAgICBpZiAoc2luIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICBvdXQucm90YXRlID0gMzYwIC0gb3V0LnJvdGF0ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG91dC5yb3RhdGUgPSBSLmRlZyhtYXRoLmFzaW4oc2luKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG91dC5pc1NpbXBsZSA9ICErb3V0LnNoZWFyLnRvRml4ZWQoOSkgJiYgKG91dC5zY2FsZXgudG9GaXhlZCg5KSA9PSBvdXQuc2NhbGV5LnRvRml4ZWQoOSkgfHwgIW91dC5yb3RhdGUpO1xuICAgICAgICAgICAgb3V0LmlzU3VwZXJTaW1wbGUgPSAhK291dC5zaGVhci50b0ZpeGVkKDkpICYmIG91dC5zY2FsZXgudG9GaXhlZCg5KSA9PSBvdXQuc2NhbGV5LnRvRml4ZWQoOSkgJiYgIW91dC5yb3RhdGU7XG4gICAgICAgICAgICBvdXQubm9Sb3RhdGlvbiA9ICErb3V0LnNoZWFyLnRvRml4ZWQoOSkgJiYgIW91dC5yb3RhdGU7XG4gICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICB9O1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIE1hdHJpeC50b1RyYW5zZm9ybVN0cmluZ1xuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKipcbiAgICAgICAgICogUmV0dXJuIHRyYW5zZm9ybSBzdHJpbmcgdGhhdCByZXByZXNlbnRzIGdpdmVuIG1hdHJpeFxuICAgICAgICAgPSAoc3RyaW5nKSB0cmFuc2Zvcm0gc3RyaW5nXG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8udG9UcmFuc2Zvcm1TdHJpbmcgPSBmdW5jdGlvbiAoc2hvcnRlcikge1xuICAgICAgICAgICAgdmFyIHMgPSBzaG9ydGVyIHx8IHRoaXNbc3BsaXRdKCk7XG4gICAgICAgICAgICBpZiAocy5pc1NpbXBsZSkge1xuICAgICAgICAgICAgICAgIHMuc2NhbGV4ID0gK3Muc2NhbGV4LnRvRml4ZWQoNCk7XG4gICAgICAgICAgICAgICAgcy5zY2FsZXkgPSArcy5zY2FsZXkudG9GaXhlZCg0KTtcbiAgICAgICAgICAgICAgICBzLnJvdGF0ZSA9ICtzLnJvdGF0ZS50b0ZpeGVkKDQpO1xuICAgICAgICAgICAgICAgIHJldHVybiAgKHMuZHggfHwgcy5keSA/IFwidFwiICsgW3MuZHgsIHMuZHldIDogRSkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgKHMuc2NhbGV4ICE9IDEgfHwgcy5zY2FsZXkgIT0gMSA/IFwic1wiICsgW3Muc2NhbGV4LCBzLnNjYWxleSwgMCwgMF0gOiBFKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAocy5yb3RhdGUgPyBcInJcIiArIFtzLnJvdGF0ZSwgMCwgMF0gOiBFKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwibVwiICsgW3RoaXMuZ2V0KDApLCB0aGlzLmdldCgxKSwgdGhpcy5nZXQoMiksIHRoaXMuZ2V0KDMpLCB0aGlzLmdldCg0KSwgdGhpcy5nZXQoNSldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pKE1hdHJpeC5wcm90b3R5cGUpO1xuXG4gICAgdmFyIHByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgfSxcbiAgICBwcmV2ZW50VG91Y2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9yaWdpbmFsRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9LFxuICAgIHN0b3BQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxCdWJibGUgPSB0cnVlO1xuICAgIH0sXG4gICAgc3RvcFRvdWNoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcmlnaW5hbEV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0sXG4gICAgZ2V0RXZlbnRQb3NpdGlvbiA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciBzY3JvbGxZID0gZy5kb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBnLmRvYy5ib2R5LnNjcm9sbFRvcCxcbiAgICAgICAgICAgIHNjcm9sbFggPSBnLmRvYy5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCBnLmRvYy5ib2R5LnNjcm9sbExlZnQ7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IGUuY2xpZW50WCArIHNjcm9sbFgsXG4gICAgICAgICAgICB5OiBlLmNsaWVudFkgKyBzY3JvbGxZXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBhZGRFdmVudCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChnLmRvYy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG9iaiwgdHlwZSwgZm4sIGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgZiA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSBnZXRFdmVudFBvc2l0aW9uKGUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm4uY2FsbChlbGVtZW50LCBlLCBwb3MueCwgcG9zLnkpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgb2JqLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZiwgZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRzVG91Y2ggJiYgdG91Y2hNYXBbdHlwZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIF9mID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSBnZXRFdmVudFBvc2l0aW9uKGUpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZGUgPSBlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlLnRhcmdldFRvdWNoZXMgJiYgZS50YXJnZXRUb3VjaGVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS50YXJnZXRUb3VjaGVzW2ldLnRhcmdldCA9PSBvYmopIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSA9IGUudGFyZ2V0VG91Y2hlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5vcmlnaW5hbEV2ZW50ID0gb2xkZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCA9IHByZXZlbnRUb3VjaDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24gPSBzdG9wVG91Y2g7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZuLmNhbGwoZWxlbWVudCwgZSwgcG9zLngsIHBvcy55KTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgb2JqLmFkZEV2ZW50TGlzdGVuZXIodG91Y2hNYXBbdHlwZV0sIF9mLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgZiwgZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0c1RvdWNoICYmIHRvdWNoTWFwW3R5cGVdKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnJlbW92ZUV2ZW50TGlzdGVuZXIodG91Y2hNYXBbdHlwZV0sIF9mLCBmYWxzZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoZy5kb2MuYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqLCB0eXBlLCBmbiwgZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHZhciBmID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZSA9IGUgfHwgZy53aW4uZXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxZID0gZy5kb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBnLmRvYy5ib2R5LnNjcm9sbFRvcCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFggPSBnLmRvYy5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCBnLmRvYy5ib2R5LnNjcm9sbExlZnQsXG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gZS5jbGllbnRYICsgc2Nyb2xsWCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBlLmNsaWVudFkgKyBzY3JvbGxZO1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0ID0gZS5wcmV2ZW50RGVmYXVsdCB8fCBwcmV2ZW50RGVmYXVsdDtcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24gPSBlLnN0b3BQcm9wYWdhdGlvbiB8fCBzdG9wUHJvcGFnYXRpb247XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmbi5jYWxsKGVsZW1lbnQsIGUsIHgsIHkpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgb2JqLmF0dGFjaEV2ZW50KFwib25cIiArIHR5cGUsIGYpO1xuICAgICAgICAgICAgICAgIHZhciBkZXRhY2hlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqLmRldGFjaEV2ZW50KFwib25cIiArIHR5cGUsIGYpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXRhY2hlcjtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9KSgpLFxuICAgIGRyYWcgPSBbXSxcbiAgICBkcmFnTW92ZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciB4ID0gZS5jbGllbnRYLFxuICAgICAgICAgICAgeSA9IGUuY2xpZW50WSxcbiAgICAgICAgICAgIHNjcm9sbFkgPSBnLmRvYy5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wIHx8IGcuZG9jLmJvZHkuc2Nyb2xsVG9wLFxuICAgICAgICAgICAgc2Nyb2xsWCA9IGcuZG9jLmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0IHx8IGcuZG9jLmJvZHkuc2Nyb2xsTGVmdCxcbiAgICAgICAgICAgIGRyYWdpLFxuICAgICAgICAgICAgaiA9IGRyYWcubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoai0tKSB7XG4gICAgICAgICAgICBkcmFnaSA9IGRyYWdbal07XG4gICAgICAgICAgICBpZiAoc3VwcG9ydHNUb3VjaCAmJiBlLnRvdWNoZXMpIHtcbiAgICAgICAgICAgICAgICB2YXIgaSA9IGUudG91Y2hlcy5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgIHRvdWNoO1xuICAgICAgICAgICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgdG91Y2ggPSBlLnRvdWNoZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh0b3VjaC5pZGVudGlmaWVyID09IGRyYWdpLmVsLl9kcmFnLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gdG91Y2guY2xpZW50WDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB0b3VjaC5jbGllbnRZO1xuICAgICAgICAgICAgICAgICAgICAgICAgKGUub3JpZ2luYWxFdmVudCA/IGUub3JpZ2luYWxFdmVudCA6IGUpLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG5vZGUgPSBkcmFnaS5lbC5ub2RlLFxuICAgICAgICAgICAgICAgIG8sXG4gICAgICAgICAgICAgICAgbmV4dCA9IG5vZGUubmV4dFNpYmxpbmcsXG4gICAgICAgICAgICAgICAgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlLFxuICAgICAgICAgICAgICAgIGRpc3BsYXkgPSBub2RlLnN0eWxlLmRpc3BsYXk7XG4gICAgICAgICAgICBnLndpbi5vcGVyYSAmJiBwYXJlbnQucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICAgICAgICBub2RlLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgIG8gPSBkcmFnaS5lbC5wYXBlci5nZXRFbGVtZW50QnlQb2ludCh4LCB5KTtcbiAgICAgICAgICAgIG5vZGUuc3R5bGUuZGlzcGxheSA9IGRpc3BsYXk7XG4gICAgICAgICAgICBnLndpbi5vcGVyYSAmJiAobmV4dCA/IHBhcmVudC5pbnNlcnRCZWZvcmUobm9kZSwgbmV4dCkgOiBwYXJlbnQuYXBwZW5kQ2hpbGQobm9kZSkpO1xuICAgICAgICAgICAgbyAmJiBldmUoXCJyYXBoYWVsLmRyYWcub3Zlci5cIiArIGRyYWdpLmVsLmlkLCBkcmFnaS5lbCwgbyk7XG4gICAgICAgICAgICB4ICs9IHNjcm9sbFg7XG4gICAgICAgICAgICB5ICs9IHNjcm9sbFk7XG4gICAgICAgICAgICBldmUoXCJyYXBoYWVsLmRyYWcubW92ZS5cIiArIGRyYWdpLmVsLmlkLCBkcmFnaS5tb3ZlX3Njb3BlIHx8IGRyYWdpLmVsLCB4IC0gZHJhZ2kuZWwuX2RyYWcueCwgeSAtIGRyYWdpLmVsLl9kcmFnLnksIHgsIHksIGUpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBkcmFnVXAgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICBSLnVubW91c2Vtb3ZlKGRyYWdNb3ZlKS51bm1vdXNldXAoZHJhZ1VwKTtcbiAgICAgICAgdmFyIGkgPSBkcmFnLmxlbmd0aCxcbiAgICAgICAgICAgIGRyYWdpO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBkcmFnaSA9IGRyYWdbaV07XG4gICAgICAgICAgICBkcmFnaS5lbC5fZHJhZyA9IHt9O1xuICAgICAgICAgICAgZXZlKFwicmFwaGFlbC5kcmFnLmVuZC5cIiArIGRyYWdpLmVsLmlkLCBkcmFnaS5lbmRfc2NvcGUgfHwgZHJhZ2kuc3RhcnRfc2NvcGUgfHwgZHJhZ2kubW92ZV9zY29wZSB8fCBkcmFnaS5lbCwgZSk7XG4gICAgICAgIH1cbiAgICAgICAgZHJhZyA9IFtdO1xuICAgIH0sXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZWxcbiAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICoqXG4gICAgICogWW91IGNhbiBhZGQgeW91ciBvd24gbWV0aG9kIHRvIGVsZW1lbnRzLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSB3YW50IHRvIGhhY2sgZGVmYXVsdCBmdW5jdGlvbmFsaXR5IG9yXG4gICAgICogd2FudCB0byB3cmFwIHNvbWUgY29tbW9uIHRyYW5zZm9ybWF0aW9uIG9yIGF0dHJpYnV0ZXMgaW4gb25lIG1ldGhvZC4gSW4gZGlmZmVyZW5jZSB0byBjYW52YXMgbWV0aG9kcyxcbiAgICAgKiB5b3UgY2FuIHJlZGVmaW5lIGVsZW1lbnQgbWV0aG9kIGF0IGFueSB0aW1lLiBFeHBlbmRpbmcgZWxlbWVudCBtZXRob2RzIHdvdWxkbuKAmXQgYWZmZWN0IHNldC5cbiAgICAgPiBVc2FnZVxuICAgICB8IFJhcGhhZWwuZWwucmVkID0gZnVuY3Rpb24gKCkge1xuICAgICB8ICAgICB0aGlzLmF0dHIoe2ZpbGw6IFwiI2YwMFwifSk7XG4gICAgIHwgfTtcbiAgICAgfCAvLyB0aGVuIHVzZSBpdFxuICAgICB8IHBhcGVyLmNpcmNsZSgxMDAsIDEwMCwgMjApLnJlZCgpO1xuICAgIFxcKi9cbiAgICBlbHByb3RvID0gUi5lbCA9IHt9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LmNsaWNrXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXIgZm9yIGNsaWNrIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVuY2xpY2tcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgY2xpY2sgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgI29wdGlvbmFsIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuZGJsY2xpY2tcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEFkZHMgZXZlbnQgaGFuZGxlciBmb3IgZG91YmxlIGNsaWNrIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVuZGJsY2xpY2tcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgZG91YmxlIGNsaWNrIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50Lm1vdXNlZG93blxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZWRvd24gZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgaGFuZGxlciBmb3IgdGhlIGV2ZW50XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQudW5tb3VzZWRvd25cbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgbW91c2Vkb3duIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50Lm1vdXNlbW92ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZW1vdmUgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgaGFuZGxlciBmb3IgdGhlIGV2ZW50XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQudW5tb3VzZW1vdmVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgbW91c2Vtb3ZlIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50Lm1vdXNlb3V0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXIgZm9yIG1vdXNlb3V0IGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVubW91c2VvdXRcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgbW91c2VvdXQgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgI29wdGlvbmFsIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQubW91c2VvdmVyXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXIgZm9yIG1vdXNlb3ZlciBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC51bm1vdXNlb3ZlclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZW92ZXIgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgI29wdGlvbmFsIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQubW91c2V1cFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZXVwIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVubW91c2V1cFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZXVwIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnRvdWNoc3RhcnRcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEFkZHMgZXZlbnQgaGFuZGxlciBmb3IgdG91Y2hzdGFydCBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC51bnRvdWNoc3RhcnRcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgdG91Y2hzdGFydCBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSAjb3B0aW9uYWwgaGFuZGxlciBmb3IgdGhlIGV2ZW50XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG5cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC50b3VjaG1vdmVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEFkZHMgZXZlbnQgaGFuZGxlciBmb3IgdG91Y2htb3ZlIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVudG91Y2htb3ZlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZW1vdmVzIGV2ZW50IGhhbmRsZXIgZm9yIHRvdWNobW92ZSBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSAjb3B0aW9uYWwgaGFuZGxlciBmb3IgdGhlIGV2ZW50XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG5cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC50b3VjaGVuZFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVyIGZvciB0b3VjaGVuZCBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC51bnRvdWNoZW5kXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZW1vdmVzIGV2ZW50IGhhbmRsZXIgZm9yIHRvdWNoZW5kIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnRvdWNoY2FuY2VsXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXIgZm9yIHRvdWNoY2FuY2VsIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVudG91Y2hjYW5jZWxcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgdG91Y2hjYW5jZWwgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgI29wdGlvbmFsIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGZvciAodmFyIGkgPSBldmVudHMubGVuZ3RoOyBpLS07KSB7XG4gICAgICAgIChmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgICAgICAgICBSW2V2ZW50TmFtZV0gPSBlbHByb3RvW2V2ZW50TmFtZV0gPSBmdW5jdGlvbiAoZm4sIHNjb3BlKSB7XG4gICAgICAgICAgICAgICAgaWYgKFIuaXMoZm4sIFwiZnVuY3Rpb25cIikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudHMgPSB0aGlzLmV2ZW50cyB8fCBbXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudHMucHVzaCh7bmFtZTogZXZlbnROYW1lLCBmOiBmbiwgdW5iaW5kOiBhZGRFdmVudCh0aGlzLnNoYXBlIHx8IHRoaXMubm9kZSB8fCBnLmRvYywgZXZlbnROYW1lLCBmbiwgc2NvcGUgfHwgdGhpcyl9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgUltcInVuXCIgKyBldmVudE5hbWVdID0gZWxwcm90b1tcInVuXCIgKyBldmVudE5hbWVdID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgICAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuZXZlbnRzIHx8IFtdLFxuICAgICAgICAgICAgICAgICAgICBsID0gZXZlbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB3aGlsZSAobC0tKXtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50c1tsXS5uYW1lID09IGV2ZW50TmFtZSAmJiAoUi5pcyhmbiwgXCJ1bmRlZmluZWRcIikgfHwgZXZlbnRzW2xdLmYgPT0gZm4pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudHNbbF0udW5iaW5kKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudHMuc3BsaWNlKGwsIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgIWV2ZW50cy5sZW5ndGggJiYgZGVsZXRlIHRoaXMuZXZlbnRzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkoZXZlbnRzW2ldKTtcbiAgICB9XG5cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5kYXRhXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIG9yIHJldHJpZXZlcyBnaXZlbiB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggZ2l2ZW4ga2V5LlxuICAgICAqKlxuICAgICAqIFNlZSBhbHNvIEBFbGVtZW50LnJlbW92ZURhdGFcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0ga2V5IChzdHJpbmcpIGtleSB0byBzdG9yZSBkYXRhXG4gICAgIC0gdmFsdWUgKGFueSkgI29wdGlvbmFsIHZhbHVlIHRvIHN0b3JlXG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICAgKiBvciwgaWYgdmFsdWUgaXMgbm90IHNwZWNpZmllZDpcbiAgICAgPSAoYW55KSB2YWx1ZVxuICAgICAqIG9yLCBpZiBrZXkgYW5kIHZhbHVlIGFyZSBub3Qgc3BlY2lmaWVkOlxuICAgICA9IChvYmplY3QpIEtleS92YWx1ZSBwYWlycyBmb3IgYWxsIHRoZSBkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgZWxlbWVudC5cbiAgICAgPiBVc2FnZVxuICAgICB8IGZvciAodmFyIGkgPSAwLCBpIDwgNSwgaSsrKSB7XG4gICAgIHwgICAgIHBhcGVyLmNpcmNsZSgxMCArIDE1ICogaSwgMTAsIDEwKVxuICAgICB8ICAgICAgICAgIC5hdHRyKHtmaWxsOiBcIiMwMDBcIn0pXG4gICAgIHwgICAgICAgICAgLmRhdGEoXCJpXCIsIGkpXG4gICAgIHwgICAgICAgICAgLmNsaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgfCAgICAgICAgICAgICBhbGVydCh0aGlzLmRhdGEoXCJpXCIpKTtcbiAgICAgfCAgICAgICAgICB9KTtcbiAgICAgfCB9XG4gICAgXFwqL1xuICAgIGVscHJvdG8uZGF0YSA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICAgIHZhciBkYXRhID0gZWxkYXRhW3RoaXMuaWRdID0gZWxkYXRhW3RoaXMuaWRdIHx8IHt9O1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgICAgICBpZiAoUi5pcyhrZXksIFwib2JqZWN0XCIpKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBrZXkpIGlmIChrZXlbaGFzXShpKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGEoaSwga2V5W2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBldmUoXCJyYXBoYWVsLmRhdGEuZ2V0LlwiICsgdGhpcy5pZCwgdGhpcywgZGF0YVtrZXldLCBrZXkpO1xuICAgICAgICAgICAgcmV0dXJuIGRhdGFba2V5XTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgZXZlKFwicmFwaGFlbC5kYXRhLnNldC5cIiArIHRoaXMuaWQsIHRoaXMsIHZhbHVlLCBrZXkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnJlbW92ZURhdGFcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGFuIGVsZW1lbnQgYnkgZ2l2ZW4ga2V5LlxuICAgICAqIElmIGtleSBpcyBub3QgcHJvdmlkZWQsIHJlbW92ZXMgYWxsIHRoZSBkYXRhIG9mIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBrZXkgKHN0cmluZykgI29wdGlvbmFsIGtleVxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8ucmVtb3ZlRGF0YSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7XG4gICAgICAgICAgICBlbGRhdGFbdGhpcy5pZF0gPSB7fTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVsZGF0YVt0aGlzLmlkXSAmJiBkZWxldGUgZWxkYXRhW3RoaXMuaWRdW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAgLypcXFxuICAgICAqIEVsZW1lbnQuZ2V0RGF0YVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0cmlldmVzIHRoZSBlbGVtZW50IGRhdGFcbiAgICAgPSAob2JqZWN0KSBkYXRhXG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0RGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNsb25lKGVsZGF0YVt0aGlzLmlkXSB8fCB7fSk7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5ob3ZlclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVycyBmb3IgaG92ZXIgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBmX2luIChmdW5jdGlvbikgaGFuZGxlciBmb3IgaG92ZXIgaW5cbiAgICAgLSBmX291dCAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIGhvdmVyIG91dFxuICAgICAtIGljb250ZXh0IChvYmplY3QpICNvcHRpb25hbCBjb250ZXh0IGZvciBob3ZlciBpbiBoYW5kbGVyXG4gICAgIC0gb2NvbnRleHQgKG9iamVjdCkgI29wdGlvbmFsIGNvbnRleHQgZm9yIGhvdmVyIG91dCBoYW5kbGVyXG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5ob3ZlciA9IGZ1bmN0aW9uIChmX2luLCBmX291dCwgc2NvcGVfaW4sIHNjb3BlX291dCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tb3VzZW92ZXIoZl9pbiwgc2NvcGVfaW4pLm1vdXNlb3V0KGZfb3V0LCBzY29wZV9vdXQgfHwgc2NvcGVfaW4pO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQudW5ob3ZlclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBldmVudCBoYW5kbGVycyBmb3IgaG92ZXIgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBmX2luIChmdW5jdGlvbikgaGFuZGxlciBmb3IgaG92ZXIgaW5cbiAgICAgLSBmX291dCAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIGhvdmVyIG91dFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8udW5ob3ZlciA9IGZ1bmN0aW9uIChmX2luLCBmX291dCkge1xuICAgICAgICByZXR1cm4gdGhpcy51bm1vdXNlb3ZlcihmX2luKS51bm1vdXNlb3V0KGZfb3V0KTtcbiAgICB9O1xuICAgIHZhciBkcmFnZ2FibGUgPSBbXTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5kcmFnXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXJzIGZvciBkcmFnIG9mIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBvbm1vdmUgKGZ1bmN0aW9uKSBoYW5kbGVyIGZvciBtb3ZpbmdcbiAgICAgLSBvbnN0YXJ0IChmdW5jdGlvbikgaGFuZGxlciBmb3IgZHJhZyBzdGFydFxuICAgICAtIG9uZW5kIChmdW5jdGlvbikgaGFuZGxlciBmb3IgZHJhZyBlbmRcbiAgICAgLSBtY29udGV4dCAob2JqZWN0KSAjb3B0aW9uYWwgY29udGV4dCBmb3IgbW92aW5nIGhhbmRsZXJcbiAgICAgLSBzY29udGV4dCAob2JqZWN0KSAjb3B0aW9uYWwgY29udGV4dCBmb3IgZHJhZyBzdGFydCBoYW5kbGVyXG4gICAgIC0gZWNvbnRleHQgKG9iamVjdCkgI29wdGlvbmFsIGNvbnRleHQgZm9yIGRyYWcgZW5kIGhhbmRsZXJcbiAgICAgKiBBZGRpdGlvbmFsbHkgZm9sbG93aW5nIGBkcmFnYCBldmVudHMgd2lsbCBiZSB0cmlnZ2VyZWQ6IGBkcmFnLnN0YXJ0LjxpZD5gIG9uIHN0YXJ0LFxuICAgICAqIGBkcmFnLmVuZC48aWQ+YCBvbiBlbmQgYW5kIGBkcmFnLm1vdmUuPGlkPmAgb24gZXZlcnkgbW92ZS4gV2hlbiBlbGVtZW50IHdpbGwgYmUgZHJhZ2dlZCBvdmVyIGFub3RoZXIgZWxlbWVudFxuICAgICAqIGBkcmFnLm92ZXIuPGlkPmAgd2lsbCBiZSBmaXJlZCBhcyB3ZWxsLlxuICAgICAqXG4gICAgICogU3RhcnQgZXZlbnQgYW5kIHN0YXJ0IGhhbmRsZXIgd2lsbCBiZSBjYWxsZWQgaW4gc3BlY2lmaWVkIGNvbnRleHQgb3IgaW4gY29udGV4dCBvZiB0aGUgZWxlbWVudCB3aXRoIGZvbGxvd2luZyBwYXJhbWV0ZXJzOlxuICAgICBvIHggKG51bWJlcikgeCBwb3NpdGlvbiBvZiB0aGUgbW91c2VcbiAgICAgbyB5IChudW1iZXIpIHkgcG9zaXRpb24gb2YgdGhlIG1vdXNlXG4gICAgIG8gZXZlbnQgKG9iamVjdCkgRE9NIGV2ZW50IG9iamVjdFxuICAgICAqIE1vdmUgZXZlbnQgYW5kIG1vdmUgaGFuZGxlciB3aWxsIGJlIGNhbGxlZCBpbiBzcGVjaWZpZWQgY29udGV4dCBvciBpbiBjb250ZXh0IG9mIHRoZSBlbGVtZW50IHdpdGggZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gICAgIG8gZHggKG51bWJlcikgc2hpZnQgYnkgeCBmcm9tIHRoZSBzdGFydCBwb2ludFxuICAgICBvIGR5IChudW1iZXIpIHNoaWZ0IGJ5IHkgZnJvbSB0aGUgc3RhcnQgcG9pbnRcbiAgICAgbyB4IChudW1iZXIpIHggcG9zaXRpb24gb2YgdGhlIG1vdXNlXG4gICAgIG8geSAobnVtYmVyKSB5IHBvc2l0aW9uIG9mIHRoZSBtb3VzZVxuICAgICBvIGV2ZW50IChvYmplY3QpIERPTSBldmVudCBvYmplY3RcbiAgICAgKiBFbmQgZXZlbnQgYW5kIGVuZCBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIGluIHNwZWNpZmllZCBjb250ZXh0IG9yIGluIGNvbnRleHQgb2YgdGhlIGVsZW1lbnQgd2l0aCBmb2xsb3dpbmcgcGFyYW1ldGVyczpcbiAgICAgbyBldmVudCAob2JqZWN0KSBET00gZXZlbnQgb2JqZWN0XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5kcmFnID0gZnVuY3Rpb24gKG9ubW92ZSwgb25zdGFydCwgb25lbmQsIG1vdmVfc2NvcGUsIHN0YXJ0X3Njb3BlLCBlbmRfc2NvcGUpIHtcbiAgICAgICAgZnVuY3Rpb24gc3RhcnQoZSkge1xuICAgICAgICAgICAgKGUub3JpZ2luYWxFdmVudCB8fCBlKS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdmFyIHggPSBlLmNsaWVudFgsXG4gICAgICAgICAgICAgICAgeSA9IGUuY2xpZW50WSxcbiAgICAgICAgICAgICAgICBzY3JvbGxZID0gZy5kb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBnLmRvYy5ib2R5LnNjcm9sbFRvcCxcbiAgICAgICAgICAgICAgICBzY3JvbGxYID0gZy5kb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHwgZy5kb2MuYm9keS5zY3JvbGxMZWZ0O1xuICAgICAgICAgICAgdGhpcy5fZHJhZy5pZCA9IGUuaWRlbnRpZmllcjtcbiAgICAgICAgICAgIGlmIChzdXBwb3J0c1RvdWNoICYmIGUudG91Y2hlcykge1xuICAgICAgICAgICAgICAgIHZhciBpID0gZS50b3VjaGVzLmxlbmd0aCwgdG91Y2g7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICB0b3VjaCA9IGUudG91Y2hlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZHJhZy5pZCA9IHRvdWNoLmlkZW50aWZpZXI7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0b3VjaC5pZGVudGlmaWVyID09IHRoaXMuX2RyYWcuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHggPSB0b3VjaC5jbGllbnRYO1xuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHRvdWNoLmNsaWVudFk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2RyYWcueCA9IHggKyBzY3JvbGxYO1xuICAgICAgICAgICAgdGhpcy5fZHJhZy55ID0geSArIHNjcm9sbFk7XG4gICAgICAgICAgICAhZHJhZy5sZW5ndGggJiYgUi5tb3VzZW1vdmUoZHJhZ01vdmUpLm1vdXNldXAoZHJhZ1VwKTtcbiAgICAgICAgICAgIGRyYWcucHVzaCh7ZWw6IHRoaXMsIG1vdmVfc2NvcGU6IG1vdmVfc2NvcGUsIHN0YXJ0X3Njb3BlOiBzdGFydF9zY29wZSwgZW5kX3Njb3BlOiBlbmRfc2NvcGV9KTtcbiAgICAgICAgICAgIG9uc3RhcnQgJiYgZXZlLm9uKFwicmFwaGFlbC5kcmFnLnN0YXJ0LlwiICsgdGhpcy5pZCwgb25zdGFydCk7XG4gICAgICAgICAgICBvbm1vdmUgJiYgZXZlLm9uKFwicmFwaGFlbC5kcmFnLm1vdmUuXCIgKyB0aGlzLmlkLCBvbm1vdmUpO1xuICAgICAgICAgICAgb25lbmQgJiYgZXZlLm9uKFwicmFwaGFlbC5kcmFnLmVuZC5cIiArIHRoaXMuaWQsIG9uZW5kKTtcbiAgICAgICAgICAgIGV2ZShcInJhcGhhZWwuZHJhZy5zdGFydC5cIiArIHRoaXMuaWQsIHN0YXJ0X3Njb3BlIHx8IG1vdmVfc2NvcGUgfHwgdGhpcywgZS5jbGllbnRYICsgc2Nyb2xsWCwgZS5jbGllbnRZICsgc2Nyb2xsWSwgZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZHJhZyA9IHt9O1xuICAgICAgICBkcmFnZ2FibGUucHVzaCh7ZWw6IHRoaXMsIHN0YXJ0OiBzdGFydH0pO1xuICAgICAgICB0aGlzLm1vdXNlZG93bihzdGFydCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQub25EcmFnT3ZlclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogU2hvcnRjdXQgZm9yIGFzc2lnbmluZyBldmVudCBoYW5kbGVyIGZvciBgZHJhZy5vdmVyLjxpZD5gIGV2ZW50LCB3aGVyZSBpZCBpcyBpZCBvZiB0aGUgZWxlbWVudCAoc2VlIEBFbGVtZW50LmlkKS5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gZiAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIGV2ZW50LCBmaXJzdCBhcmd1bWVudCB3b3VsZCBiZSB0aGUgZWxlbWVudCB5b3UgYXJlIGRyYWdnaW5nIG92ZXJcbiAgICBcXCovXG4gICAgZWxwcm90by5vbkRyYWdPdmVyID0gZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgZiA/IGV2ZS5vbihcInJhcGhhZWwuZHJhZy5vdmVyLlwiICsgdGhpcy5pZCwgZikgOiBldmUudW5iaW5kKFwicmFwaGFlbC5kcmFnLm92ZXIuXCIgKyB0aGlzLmlkKTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVuZHJhZ1xuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBhbGwgZHJhZyBldmVudCBoYW5kbGVycyBmcm9tIGdpdmVuIGVsZW1lbnQuXG4gICAgXFwqL1xuICAgIGVscHJvdG8udW5kcmFnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaSA9IGRyYWdnYWJsZS5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIGlmIChkcmFnZ2FibGVbaV0uZWwgPT0gdGhpcykge1xuICAgICAgICAgICAgdGhpcy51bm1vdXNlZG93bihkcmFnZ2FibGVbaV0uc3RhcnQpO1xuICAgICAgICAgICAgZHJhZ2dhYmxlLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIGV2ZS51bmJpbmQoXCJyYXBoYWVsLmRyYWcuKi5cIiArIHRoaXMuaWQpO1xuICAgICAgICB9XG4gICAgICAgICFkcmFnZ2FibGUubGVuZ3RoICYmIFIudW5tb3VzZW1vdmUoZHJhZ01vdmUpLnVubW91c2V1cChkcmFnVXApO1xuICAgICAgICBkcmFnID0gW107XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIuY2lyY2xlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBEcmF3cyBhIGNpcmNsZS5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIGNlbnRyZVxuICAgICAtIHkgKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBjZW50cmVcbiAgICAgLSByIChudW1iZXIpIHJhZGl1c1xuICAgICA9IChvYmplY3QpIFJhcGhhw6tsIGVsZW1lbnQgb2JqZWN0IHdpdGggdHlwZSDigJxjaXJjbGXigJ1cbiAgICAgKipcbiAgICAgPiBVc2FnZVxuICAgICB8IHZhciBjID0gcGFwZXIuY2lyY2xlKDUwLCA1MCwgNDApO1xuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLmNpcmNsZSA9IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHZhciBvdXQgPSBSLl9lbmdpbmUuY2lyY2xlKHRoaXMsIHggfHwgMCwgeSB8fCAwLCByIHx8IDApO1xuICAgICAgICB0aGlzLl9fc2V0X18gJiYgdGhpcy5fX3NldF9fLnB1c2gob3V0KTtcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5yZWN0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICAqIERyYXdzIGEgcmVjdGFuZ2xlLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSB4IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgdG9wIGxlZnQgY29ybmVyXG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRvcCBsZWZ0IGNvcm5lclxuICAgICAtIHdpZHRoIChudW1iZXIpIHdpZHRoXG4gICAgIC0gaGVpZ2h0IChudW1iZXIpIGhlaWdodFxuICAgICAtIHIgKG51bWJlcikgI29wdGlvbmFsIHJhZGl1cyBmb3Igcm91bmRlZCBjb3JuZXJzLCBkZWZhdWx0IGlzIDBcbiAgICAgPSAob2JqZWN0KSBSYXBoYcOrbCBlbGVtZW50IG9iamVjdCB3aXRoIHR5cGUg4oCccmVjdOKAnVxuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgLy8gcmVndWxhciByZWN0YW5nbGVcbiAgICAgfCB2YXIgYyA9IHBhcGVyLnJlY3QoMTAsIDEwLCA1MCwgNTApO1xuICAgICB8IC8vIHJlY3RhbmdsZSB3aXRoIHJvdW5kZWQgY29ybmVyc1xuICAgICB8IHZhciBjID0gcGFwZXIucmVjdCg0MCwgNDAsIDUwLCA1MCwgMTApO1xuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnJlY3QgPSBmdW5jdGlvbiAoeCwgeSwgdywgaCwgcikge1xuICAgICAgICB2YXIgb3V0ID0gUi5fZW5naW5lLnJlY3QodGhpcywgeCB8fCAwLCB5IHx8IDAsIHcgfHwgMCwgaCB8fCAwLCByIHx8IDApO1xuICAgICAgICB0aGlzLl9fc2V0X18gJiYgdGhpcy5fX3NldF9fLnB1c2gob3V0KTtcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5lbGxpcHNlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBEcmF3cyBhbiBlbGxpcHNlLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSB4IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgY2VudHJlXG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIGNlbnRyZVxuICAgICAtIHJ4IChudW1iZXIpIGhvcml6b250YWwgcmFkaXVzXG4gICAgIC0gcnkgKG51bWJlcikgdmVydGljYWwgcmFkaXVzXG4gICAgID0gKG9iamVjdCkgUmFwaGHDq2wgZWxlbWVudCBvYmplY3Qgd2l0aCB0eXBlIOKAnGVsbGlwc2XigJ1cbiAgICAgKipcbiAgICAgPiBVc2FnZVxuICAgICB8IHZhciBjID0gcGFwZXIuZWxsaXBzZSg1MCwgNTAsIDQwLCAyMCk7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8uZWxsaXBzZSA9IGZ1bmN0aW9uICh4LCB5LCByeCwgcnkpIHtcbiAgICAgICAgdmFyIG91dCA9IFIuX2VuZ2luZS5lbGxpcHNlKHRoaXMsIHggfHwgMCwgeSB8fCAwLCByeCB8fCAwLCByeSB8fCAwKTtcbiAgICAgICAgdGhpcy5fX3NldF9fICYmIHRoaXMuX19zZXRfXy5wdXNoKG91dCk7XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIucGF0aFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ3JlYXRlcyBhIHBhdGggZWxlbWVudCBieSBnaXZlbiBwYXRoIGRhdGEgc3RyaW5nLlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBwYXRoU3RyaW5nIChzdHJpbmcpICNvcHRpb25hbCBwYXRoIHN0cmluZyBpbiBTVkcgZm9ybWF0LlxuICAgICAqIFBhdGggc3RyaW5nIGNvbnNpc3RzIG9mIG9uZS1sZXR0ZXIgY29tbWFuZHMsIGZvbGxvd2VkIGJ5IGNvbW1hIHNlcHJhcmF0ZWQgYXJndW1lbnRzIGluIG51bWVyY2FsIGZvcm0uIEV4YW1wbGU6XG4gICAgIHwgXCJNMTAsMjBMMzAsNDBcIlxuICAgICAqIEhlcmUgd2UgY2FuIHNlZSB0d28gY29tbWFuZHM6IOKAnE3igJ0sIHdpdGggYXJndW1lbnRzIGAoMTAsIDIwKWAgYW5kIOKAnEzigJ0gd2l0aCBhcmd1bWVudHMgYCgzMCwgNDApYC4gVXBwZXIgY2FzZSBsZXR0ZXIgbWVhbiBjb21tYW5kIGlzIGFic29sdXRlLCBsb3dlciBjYXNl4oCUcmVsYXRpdmUuXG4gICAgICpcbiAgICAgIyA8cD5IZXJlIGlzIHNob3J0IGxpc3Qgb2YgY29tbWFuZHMgYXZhaWxhYmxlLCBmb3IgbW9yZSBkZXRhaWxzIHNlZSA8YSBocmVmPVwiaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHL3BhdGhzLmh0bWwjUGF0aERhdGFcIiB0aXRsZT1cIkRldGFpbHMgb2YgYSBwYXRoJ3MgZGF0YSBhdHRyaWJ1dGUncyBmb3JtYXQgYXJlIGRlc2NyaWJlZCBpbiB0aGUgU1ZHIHNwZWNpZmljYXRpb24uXCI+U1ZHIHBhdGggc3RyaW5nIGZvcm1hdDwvYT4uPC9wPlxuICAgICAjIDx0YWJsZT48dGhlYWQ+PHRyPjx0aD5Db21tYW5kPC90aD48dGg+TmFtZTwvdGg+PHRoPlBhcmFtZXRlcnM8L3RoPjwvdHI+PC90aGVhZD48dGJvZHk+XG4gICAgICMgPHRyPjx0ZD5NPC90ZD48dGQ+bW92ZXRvPC90ZD48dGQ+KHggeSkrPC90ZD48L3RyPlxuICAgICAjIDx0cj48dGQ+WjwvdGQ+PHRkPmNsb3NlcGF0aDwvdGQ+PHRkPihub25lKTwvdGQ+PC90cj5cbiAgICAgIyA8dHI+PHRkPkw8L3RkPjx0ZD5saW5ldG88L3RkPjx0ZD4oeCB5KSs8L3RkPjwvdHI+XG4gICAgICMgPHRyPjx0ZD5IPC90ZD48dGQ+aG9yaXpvbnRhbCBsaW5ldG88L3RkPjx0ZD54KzwvdGQ+PC90cj5cbiAgICAgIyA8dHI+PHRkPlY8L3RkPjx0ZD52ZXJ0aWNhbCBsaW5ldG88L3RkPjx0ZD55KzwvdGQ+PC90cj5cbiAgICAgIyA8dHI+PHRkPkM8L3RkPjx0ZD5jdXJ2ZXRvPC90ZD48dGQ+KHgxIHkxIHgyIHkyIHggeSkrPC90ZD48L3RyPlxuICAgICAjIDx0cj48dGQ+UzwvdGQ+PHRkPnNtb290aCBjdXJ2ZXRvPC90ZD48dGQ+KHgyIHkyIHggeSkrPC90ZD48L3RyPlxuICAgICAjIDx0cj48dGQ+UTwvdGQ+PHRkPnF1YWRyYXRpYyBCw6l6aWVyIGN1cnZldG88L3RkPjx0ZD4oeDEgeTEgeCB5KSs8L3RkPjwvdHI+XG4gICAgICMgPHRyPjx0ZD5UPC90ZD48dGQ+c21vb3RoIHF1YWRyYXRpYyBCw6l6aWVyIGN1cnZldG88L3RkPjx0ZD4oeCB5KSs8L3RkPjwvdHI+XG4gICAgICMgPHRyPjx0ZD5BPC90ZD48dGQ+ZWxsaXB0aWNhbCBhcmM8L3RkPjx0ZD4ocnggcnkgeC1heGlzLXJvdGF0aW9uIGxhcmdlLWFyYy1mbGFnIHN3ZWVwLWZsYWcgeCB5KSs8L3RkPjwvdHI+XG4gICAgICMgPHRyPjx0ZD5SPC90ZD48dGQ+PGEgaHJlZj1cImh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ2F0bXVsbOKAk1JvbV9zcGxpbmUjQ2F0bXVsbC5FMi44MC45M1JvbV9zcGxpbmVcIj5DYXRtdWxsLVJvbSBjdXJ2ZXRvPC9hPio8L3RkPjx0ZD54MSB5MSAoeCB5KSs8L3RkPjwvdHI+PC90Ym9keT48L3RhYmxlPlxuICAgICAqICog4oCcQ2F0bXVsbC1Sb20gY3VydmV0b+KAnSBpcyBhIG5vdCBzdGFuZGFyZCBTVkcgY29tbWFuZCBhbmQgYWRkZWQgaW4gMi4wIHRvIG1ha2UgbGlmZSBlYXNpZXIuXG4gICAgICogTm90ZTogdGhlcmUgaXMgYSBzcGVjaWFsIGNhc2Ugd2hlbiBwYXRoIGNvbnNpc3Qgb2YganVzdCB0aHJlZSBjb21tYW5kczog4oCcTTEwLDEwUuKApnrigJ0uIEluIHRoaXMgY2FzZSBwYXRoIHdpbGwgc21vb3RobHkgY29ubmVjdHMgdG8gaXRzIGJlZ2lubmluZy5cbiAgICAgPiBVc2FnZVxuICAgICB8IHZhciBjID0gcGFwZXIucGF0aChcIk0xMCAxMEw5MCA5MFwiKTtcbiAgICAgfCAvLyBkcmF3IGEgZGlhZ29uYWwgbGluZTpcbiAgICAgfCAvLyBtb3ZlIHRvIDEwLDEwLCBsaW5lIHRvIDkwLDkwXG4gICAgICogRm9yIGV4YW1wbGUgb2YgcGF0aCBzdHJpbmdzLCBjaGVjayBvdXQgdGhlc2UgaWNvbnM6IGh0dHA6Ly9yYXBoYWVsanMuY29tL2ljb25zL1xuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnBhdGggPSBmdW5jdGlvbiAocGF0aFN0cmluZykge1xuICAgICAgICBwYXRoU3RyaW5nICYmICFSLmlzKHBhdGhTdHJpbmcsIHN0cmluZykgJiYgIVIuaXMocGF0aFN0cmluZ1swXSwgYXJyYXkpICYmIChwYXRoU3RyaW5nICs9IEUpO1xuICAgICAgICB2YXIgb3V0ID0gUi5fZW5naW5lLnBhdGgoUi5mb3JtYXRbYXBwbHldKFIsIGFyZ3VtZW50cyksIHRoaXMpO1xuICAgICAgICB0aGlzLl9fc2V0X18gJiYgdGhpcy5fX3NldF9fLnB1c2gob3V0KTtcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5pbWFnZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogRW1iZWRzIGFuIGltYWdlIGludG8gdGhlIHN1cmZhY2UuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHNyYyAoc3RyaW5nKSBVUkkgb2YgdGhlIHNvdXJjZSBpbWFnZVxuICAgICAtIHggKG51bWJlcikgeCBjb29yZGluYXRlIHBvc2l0aW9uXG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgcG9zaXRpb25cbiAgICAgLSB3aWR0aCAobnVtYmVyKSB3aWR0aCBvZiB0aGUgaW1hZ2VcbiAgICAgLSBoZWlnaHQgKG51bWJlcikgaGVpZ2h0IG9mIHRoZSBpbWFnZVxuICAgICA9IChvYmplY3QpIFJhcGhhw6tsIGVsZW1lbnQgb2JqZWN0IHdpdGggdHlwZSDigJxpbWFnZeKAnVxuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgdmFyIGMgPSBwYXBlci5pbWFnZShcImFwcGxlLnBuZ1wiLCAxMCwgMTAsIDgwLCA4MCk7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8uaW1hZ2UgPSBmdW5jdGlvbiAoc3JjLCB4LCB5LCB3LCBoKSB7XG4gICAgICAgIHZhciBvdXQgPSBSLl9lbmdpbmUuaW1hZ2UodGhpcywgc3JjIHx8IFwiYWJvdXQ6YmxhbmtcIiwgeCB8fCAwLCB5IHx8IDAsIHcgfHwgMCwgaCB8fCAwKTtcbiAgICAgICAgdGhpcy5fX3NldF9fICYmIHRoaXMuX19zZXRfXy5wdXNoKG91dCk7XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIudGV4dFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogRHJhd3MgYSB0ZXh0IHN0cmluZy4gSWYgeW91IG5lZWQgbGluZSBicmVha3MsIHB1dCDigJxcXG7igJ0gaW4gdGhlIHN0cmluZy5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSB4IGNvb3JkaW5hdGUgcG9zaXRpb25cbiAgICAgLSB5IChudW1iZXIpIHkgY29vcmRpbmF0ZSBwb3NpdGlvblxuICAgICAtIHRleHQgKHN0cmluZykgVGhlIHRleHQgc3RyaW5nIHRvIGRyYXdcbiAgICAgPSAob2JqZWN0KSBSYXBoYcOrbCBlbGVtZW50IG9iamVjdCB3aXRoIHR5cGUg4oCcdGV4dOKAnVxuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgdmFyIHQgPSBwYXBlci50ZXh0KDUwLCA1MCwgXCJSYXBoYcOrbFxcbmtpY2tzXFxuYnV0dCFcIik7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8udGV4dCA9IGZ1bmN0aW9uICh4LCB5LCB0ZXh0KSB7XG4gICAgICAgIHZhciBvdXQgPSBSLl9lbmdpbmUudGV4dCh0aGlzLCB4IHx8IDAsIHkgfHwgMCwgU3RyKHRleHQpKTtcbiAgICAgICAgdGhpcy5fX3NldF9fICYmIHRoaXMuX19zZXRfXy5wdXNoKG91dCk7XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIuc2V0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIGFycmF5LWxpa2Ugb2JqZWN0IHRvIGtlZXAgYW5kIG9wZXJhdGUgc2V2ZXJhbCBlbGVtZW50cyBhdCBvbmNlLlxuICAgICAqIFdhcm5pbmc6IGl0IGRvZXNu4oCZdCBjcmVhdGUgYW55IGVsZW1lbnRzIGZvciBpdHNlbGYgaW4gdGhlIHBhZ2UsIGl0IGp1c3QgZ3JvdXBzIGV4aXN0aW5nIGVsZW1lbnRzLlxuICAgICAqIFNldHMgYWN0IGFzIHBzZXVkbyBlbGVtZW50cyDigJQgYWxsIG1ldGhvZHMgYXZhaWxhYmxlIHRvIGFuIGVsZW1lbnQgY2FuIGJlIHVzZWQgb24gYSBzZXQuXG4gICAgID0gKG9iamVjdCkgYXJyYXktbGlrZSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHNldCBvZiBlbGVtZW50c1xuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgdmFyIHN0ID0gcGFwZXIuc2V0KCk7XG4gICAgIHwgc3QucHVzaChcbiAgICAgfCAgICAgcGFwZXIuY2lyY2xlKDEwLCAxMCwgNSksXG4gICAgIHwgICAgIHBhcGVyLmNpcmNsZSgzMCwgMTAsIDUpXG4gICAgIHwgKTtcbiAgICAgfCBzdC5hdHRyKHtmaWxsOiBcInJlZFwifSk7IC8vIGNoYW5nZXMgdGhlIGZpbGwgb2YgYm90aCBjaXJjbGVzXG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8uc2V0ID0gZnVuY3Rpb24gKGl0ZW1zQXJyYXkpIHtcbiAgICAgICAgIVIuaXMoaXRlbXNBcnJheSwgXCJhcnJheVwiKSAmJiAoaXRlbXNBcnJheSA9IEFycmF5LnByb3RvdHlwZS5zcGxpY2UuY2FsbChhcmd1bWVudHMsIDAsIGFyZ3VtZW50cy5sZW5ndGgpKTtcbiAgICAgICAgdmFyIG91dCA9IG5ldyBTZXQoaXRlbXNBcnJheSk7XG4gICAgICAgIHRoaXMuX19zZXRfXyAmJiB0aGlzLl9fc2V0X18ucHVzaChvdXQpO1xuICAgICAgICBvdXRbXCJwYXBlclwiXSA9IHRoaXM7XG4gICAgICAgIG91dFtcInR5cGVcIl0gPSBcInNldFwiO1xuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLnNldFN0YXJ0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIEBQYXBlci5zZXQuIEFsbCBlbGVtZW50cyB0aGF0IHdpbGwgYmUgY3JlYXRlZCBhZnRlciBjYWxsaW5nIHRoaXMgbWV0aG9kIGFuZCBiZWZvcmUgY2FsbGluZ1xuICAgICAqIEBQYXBlci5zZXRGaW5pc2ggd2lsbCBiZSBhZGRlZCB0byB0aGUgc2V0LlxuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgcGFwZXIuc2V0U3RhcnQoKTtcbiAgICAgfCBwYXBlci5jaXJjbGUoMTAsIDEwLCA1KSxcbiAgICAgfCBwYXBlci5jaXJjbGUoMzAsIDEwLCA1KVxuICAgICB8IHZhciBzdCA9IHBhcGVyLnNldEZpbmlzaCgpO1xuICAgICB8IHN0LmF0dHIoe2ZpbGw6IFwicmVkXCJ9KTsgLy8gY2hhbmdlcyB0aGUgZmlsbCBvZiBib3RoIGNpcmNsZXNcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5zZXRTdGFydCA9IGZ1bmN0aW9uIChzZXQpIHtcbiAgICAgICAgdGhpcy5fX3NldF9fID0gc2V0IHx8IHRoaXMuc2V0KCk7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIuc2V0RmluaXNoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTZWUgQFBhcGVyLnNldFN0YXJ0LiBUaGlzIG1ldGhvZCBmaW5pc2hlcyBjYXRjaGluZyBhbmQgcmV0dXJucyByZXN1bHRpbmcgc2V0LlxuICAgICAqKlxuICAgICA9IChvYmplY3QpIHNldFxuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnNldEZpbmlzaCA9IGZ1bmN0aW9uIChzZXQpIHtcbiAgICAgICAgdmFyIG91dCA9IHRoaXMuX19zZXRfXztcbiAgICAgICAgZGVsZXRlIHRoaXMuX19zZXRfXztcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5nZXRTaXplXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBPYnRhaW5zIGN1cnJlbnQgcGFwZXIgYWN0dWFsIHNpemUuXG4gICAgICoqXG4gICAgID0gKG9iamVjdClcbiAgICAgXFwqL1xuICAgIHBhcGVycHJvdG8uZ2V0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY2FudmFzLnBhcmVudE5vZGU7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB3aWR0aDogY29udGFpbmVyLm9mZnNldFdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBjb250YWluZXIub2Zmc2V0SGVpZ2h0XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIuc2V0U2l6ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogSWYgeW91IG5lZWQgdG8gY2hhbmdlIGRpbWVuc2lvbnMgb2YgdGhlIGNhbnZhcyBjYWxsIHRoaXMgbWV0aG9kXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHdpZHRoIChudW1iZXIpIG5ldyB3aWR0aCBvZiB0aGUgY2FudmFzXG4gICAgIC0gaGVpZ2h0IChudW1iZXIpIG5ldyBoZWlnaHQgb2YgdGhlIGNhbnZhc1xuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnNldFNpemUgPSBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCkge1xuICAgICAgICByZXR1cm4gUi5fZW5naW5lLnNldFNpemUuY2FsbCh0aGlzLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5zZXRWaWV3Qm94XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTZXRzIHRoZSB2aWV3IGJveCBvZiB0aGUgcGFwZXIuIFByYWN0aWNhbGx5IGl0IGdpdmVzIHlvdSBhYmlsaXR5IHRvIHpvb20gYW5kIHBhbiB3aG9sZSBwYXBlciBzdXJmYWNlIGJ5XG4gICAgICogc3BlY2lmeWluZyBuZXcgYm91bmRhcmllcy5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSBuZXcgeCBwb3NpdGlvbiwgZGVmYXVsdCBpcyBgMGBcbiAgICAgLSB5IChudW1iZXIpIG5ldyB5IHBvc2l0aW9uLCBkZWZhdWx0IGlzIGAwYFxuICAgICAtIHcgKG51bWJlcikgbmV3IHdpZHRoIG9mIHRoZSBjYW52YXNcbiAgICAgLSBoIChudW1iZXIpIG5ldyBoZWlnaHQgb2YgdGhlIGNhbnZhc1xuICAgICAtIGZpdCAoYm9vbGVhbikgYHRydWVgIGlmIHlvdSB3YW50IGdyYXBoaWNzIHRvIGZpdCBpbnRvIG5ldyBib3VuZGFyeSBib3hcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5zZXRWaWV3Qm94ID0gZnVuY3Rpb24gKHgsIHksIHcsIGgsIGZpdCkge1xuICAgICAgICByZXR1cm4gUi5fZW5naW5lLnNldFZpZXdCb3guY2FsbCh0aGlzLCB4LCB5LCB3LCBoLCBmaXQpO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLnRvcFxuICAgICBbIHByb3BlcnR5IF1cbiAgICAgKipcbiAgICAgKiBQb2ludHMgdG8gdGhlIHRvcG1vc3QgZWxlbWVudCBvbiB0aGUgcGFwZXJcbiAgICBcXCovXG4gICAgLypcXFxuICAgICAqIFBhcGVyLmJvdHRvbVxuICAgICBbIHByb3BlcnR5IF1cbiAgICAgKipcbiAgICAgKiBQb2ludHMgdG8gdGhlIGJvdHRvbSBlbGVtZW50IG9uIHRoZSBwYXBlclxuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnRvcCA9IHBhcGVycHJvdG8uYm90dG9tID0gbnVsbDtcbiAgICAvKlxcXG4gICAgICogUGFwZXIucmFwaGFlbFxuICAgICBbIHByb3BlcnR5IF1cbiAgICAgKipcbiAgICAgKiBQb2ludHMgdG8gdGhlIEBSYXBoYWVsIG9iamVjdC9mdW5jdGlvblxuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnJhcGhhZWwgPSBSO1xuICAgIHZhciBnZXRPZmZzZXQgPSBmdW5jdGlvbiAoZWxlbSkge1xuICAgICAgICB2YXIgYm94ID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcbiAgICAgICAgICAgIGRvYyA9IGVsZW0ub3duZXJEb2N1bWVudCxcbiAgICAgICAgICAgIGJvZHkgPSBkb2MuYm9keSxcbiAgICAgICAgICAgIGRvY0VsZW0gPSBkb2MuZG9jdW1lbnRFbGVtZW50LFxuICAgICAgICAgICAgY2xpZW50VG9wID0gZG9jRWxlbS5jbGllbnRUb3AgfHwgYm9keS5jbGllbnRUb3AgfHwgMCwgY2xpZW50TGVmdCA9IGRvY0VsZW0uY2xpZW50TGVmdCB8fCBib2R5LmNsaWVudExlZnQgfHwgMCxcbiAgICAgICAgICAgIHRvcCAgPSBib3gudG9wICArIChnLndpbi5wYWdlWU9mZnNldCB8fCBkb2NFbGVtLnNjcm9sbFRvcCB8fCBib2R5LnNjcm9sbFRvcCApIC0gY2xpZW50VG9wLFxuICAgICAgICAgICAgbGVmdCA9IGJveC5sZWZ0ICsgKGcud2luLnBhZ2VYT2Zmc2V0IHx8IGRvY0VsZW0uc2Nyb2xsTGVmdCB8fCBib2R5LnNjcm9sbExlZnQpIC0gY2xpZW50TGVmdDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHk6IHRvcCxcbiAgICAgICAgICAgIHg6IGxlZnRcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5nZXRFbGVtZW50QnlQb2ludFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyB5b3UgdG9wbW9zdCBlbGVtZW50IHVuZGVyIGdpdmVuIHBvaW50LlxuICAgICAqKlxuICAgICA9IChvYmplY3QpIFJhcGhhw6tsIGVsZW1lbnQgb2JqZWN0XG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHggKG51bWJlcikgeCBjb29yZGluYXRlIGZyb20gdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgd2luZG93XG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgZnJvbSB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSB3aW5kb3dcbiAgICAgPiBVc2FnZVxuICAgICB8IHBhcGVyLmdldEVsZW1lbnRCeVBvaW50KG1vdXNlWCwgbW91c2VZKS5hdHRyKHtzdHJva2U6IFwiI2YwMFwifSk7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8uZ2V0RWxlbWVudEJ5UG9pbnQgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICB2YXIgcGFwZXIgPSB0aGlzLFxuICAgICAgICAgICAgc3ZnID0gcGFwZXIuY2FudmFzLFxuICAgICAgICAgICAgdGFyZ2V0ID0gZy5kb2MuZWxlbWVudEZyb21Qb2ludCh4LCB5KTtcbiAgICAgICAgaWYgKGcud2luLm9wZXJhICYmIHRhcmdldC50YWdOYW1lID09IFwic3ZnXCIpIHtcbiAgICAgICAgICAgIHZhciBzbyA9IGdldE9mZnNldChzdmcpLFxuICAgICAgICAgICAgICAgIHNyID0gc3ZnLmNyZWF0ZVNWR1JlY3QoKTtcbiAgICAgICAgICAgIHNyLnggPSB4IC0gc28ueDtcbiAgICAgICAgICAgIHNyLnkgPSB5IC0gc28ueTtcbiAgICAgICAgICAgIHNyLndpZHRoID0gc3IuaGVpZ2h0ID0gMTtcbiAgICAgICAgICAgIHZhciBoaXRzID0gc3ZnLmdldEludGVyc2VjdGlvbkxpc3Qoc3IsIG51bGwpO1xuICAgICAgICAgICAgaWYgKGhpdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0ID0gaGl0c1toaXRzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAodGFyZ2V0LnBhcmVudE5vZGUgJiYgdGFyZ2V0ICE9IHN2Zy5wYXJlbnROb2RlICYmICF0YXJnZXQucmFwaGFlbCkge1xuICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgdGFyZ2V0ID09IHBhcGVyLmNhbnZhcy5wYXJlbnROb2RlICYmICh0YXJnZXQgPSBzdmcpO1xuICAgICAgICB0YXJnZXQgPSB0YXJnZXQgJiYgdGFyZ2V0LnJhcGhhZWwgPyBwYXBlci5nZXRCeUlkKHRhcmdldC5yYXBoYWVsaWQpIDogbnVsbDtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFBhcGVyLmdldEVsZW1lbnRzQnlCQm94XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm5zIHNldCBvZiBlbGVtZW50cyB0aGF0IGhhdmUgYW4gaW50ZXJzZWN0aW5nIGJvdW5kaW5nIGJveFxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBiYm94IChvYmplY3QpIGJib3ggdG8gY2hlY2sgd2l0aFxuICAgICA9IChvYmplY3QpIEBTZXRcbiAgICAgXFwqL1xuICAgIHBhcGVycHJvdG8uZ2V0RWxlbWVudHNCeUJCb3ggPSBmdW5jdGlvbiAoYmJveCkge1xuICAgICAgICB2YXIgc2V0ID0gdGhpcy5zZXQoKTtcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgaWYgKFIuaXNCQm94SW50ZXJzZWN0KGVsLmdldEJCb3goKSwgYmJveCkpIHtcbiAgICAgICAgICAgICAgICBzZXQucHVzaChlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2V0O1xuICAgIH07XG5cbiAgICAvKlxcXG4gICAgICogUGFwZXIuZ2V0QnlJZFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyB5b3UgZWxlbWVudCBieSBpdHMgaW50ZXJuYWwgSUQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGlkIChudW1iZXIpIGlkXG4gICAgID0gKG9iamVjdCkgUmFwaGHDq2wgZWxlbWVudCBvYmplY3RcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5nZXRCeUlkID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIHZhciBib3QgPSB0aGlzLmJvdHRvbTtcbiAgICAgICAgd2hpbGUgKGJvdCkge1xuICAgICAgICAgICAgaWYgKGJvdC5pZCA9PSBpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBib3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBib3QgPSBib3QubmV4dDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5mb3JFYWNoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBFeGVjdXRlcyBnaXZlbiBmdW5jdGlvbiBmb3IgZWFjaCBlbGVtZW50IG9uIHRoZSBwYXBlclxuICAgICAqXG4gICAgICogSWYgY2FsbGJhY2sgZnVuY3Rpb24gcmV0dXJucyBgZmFsc2VgIGl0IHdpbGwgc3RvcCBsb29wIHJ1bm5pbmcuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGNhbGxiYWNrIChmdW5jdGlvbikgZnVuY3Rpb24gdG8gcnVuXG4gICAgIC0gdGhpc0FyZyAob2JqZWN0KSBjb250ZXh0IG9iamVjdCBmb3IgdGhlIGNhbGxiYWNrXG4gICAgID0gKG9iamVjdCkgUGFwZXIgb2JqZWN0XG4gICAgID4gVXNhZ2VcbiAgICAgfCBwYXBlci5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICB8ICAgICBlbC5hdHRyKHsgc3Ryb2tlOiBcImJsdWVcIiB9KTtcbiAgICAgfCB9KTtcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5mb3JFYWNoID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzQXJnKSB7XG4gICAgICAgIHZhciBib3QgPSB0aGlzLmJvdHRvbTtcbiAgICAgICAgd2hpbGUgKGJvdCkge1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrLmNhbGwodGhpc0FyZywgYm90KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJvdCA9IGJvdC5uZXh0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLmdldEVsZW1lbnRzQnlQb2ludFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyBzZXQgb2YgZWxlbWVudHMgdGhhdCBoYXZlIGNvbW1vbiBwb2ludCBpbnNpZGVcbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50XG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50XG4gICAgID0gKG9iamVjdCkgQFNldFxuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLmdldEVsZW1lbnRzQnlQb2ludCA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIHZhciBzZXQgPSB0aGlzLnNldCgpO1xuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICBpZiAoZWwuaXNQb2ludEluc2lkZSh4LCB5KSkge1xuICAgICAgICAgICAgICAgIHNldC5wdXNoKGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzZXQ7XG4gICAgfTtcbiAgICBmdW5jdGlvbiB4X3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnggKyBTICsgdGhpcy55O1xuICAgIH1cbiAgICBmdW5jdGlvbiB4X3lfd19oKCkge1xuICAgICAgICByZXR1cm4gdGhpcy54ICsgUyArIHRoaXMueSArIFMgKyB0aGlzLndpZHRoICsgXCIgXFx4ZDcgXCIgKyB0aGlzLmhlaWdodDtcbiAgICB9XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuaXNQb2ludEluc2lkZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogRGV0ZXJtaW5lIGlmIGdpdmVuIHBvaW50IGlzIGluc2lkZSB0aGlzIGVsZW1lbnTigJlzIHNoYXBlXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHggKG51bWJlcikgeCBjb29yZGluYXRlIG9mIHRoZSBwb2ludFxuICAgICAtIHkgKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBwb2ludFxuICAgICA9IChib29sZWFuKSBgdHJ1ZWAgaWYgcG9pbnQgaW5zaWRlIHRoZSBzaGFwZVxuICAgIFxcKi9cbiAgICBlbHByb3RvLmlzUG9pbnRJbnNpZGUgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICB2YXIgcnAgPSB0aGlzLnJlYWxQYXRoID0gZ2V0UGF0aFt0aGlzLnR5cGVdKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5hdHRyKCd0cmFuc2Zvcm0nKSAmJiB0aGlzLmF0dHIoJ3RyYW5zZm9ybScpLmxlbmd0aCkge1xuICAgICAgICAgICAgcnAgPSBSLnRyYW5zZm9ybVBhdGgocnAsIHRoaXMuYXR0cigndHJhbnNmb3JtJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSLmlzUG9pbnRJbnNpZGVQYXRoKHJwLCB4LCB5KTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LmdldEJCb3hcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJldHVybiBib3VuZGluZyBib3ggZm9yIGEgZ2l2ZW4gZWxlbWVudFxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBpc1dpdGhvdXRUcmFuc2Zvcm0gKGJvb2xlYW4pIGZsYWcsIGB0cnVlYCBpZiB5b3Ugd2FudCB0byBoYXZlIGJvdW5kaW5nIGJveCBiZWZvcmUgdHJhbnNmb3JtYXRpb25zLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gICAgID0gKG9iamVjdCkgQm91bmRpbmcgYm94IG9iamVjdDpcbiAgICAgbyB7XG4gICAgIG8gICAgIHg6IChudW1iZXIpIHRvcCBsZWZ0IGNvcm5lciB4XG4gICAgIG8gICAgIHk6IChudW1iZXIpIHRvcCBsZWZ0IGNvcm5lciB5XG4gICAgIG8gICAgIHgyOiAobnVtYmVyKSBib3R0b20gcmlnaHQgY29ybmVyIHhcbiAgICAgbyAgICAgeTI6IChudW1iZXIpIGJvdHRvbSByaWdodCBjb3JuZXIgeVxuICAgICBvICAgICB3aWR0aDogKG51bWJlcikgd2lkdGhcbiAgICAgbyAgICAgaGVpZ2h0OiAobnVtYmVyKSBoZWlnaHRcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0QkJveCA9IGZ1bmN0aW9uIChpc1dpdGhvdXRUcmFuc2Zvcm0pIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICB9XG4gICAgICAgIHZhciBfID0gdGhpcy5fO1xuICAgICAgICBpZiAoaXNXaXRob3V0VHJhbnNmb3JtKSB7XG4gICAgICAgICAgICBpZiAoXy5kaXJ0eSB8fCAhXy5iYm94d3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlYWxQYXRoID0gZ2V0UGF0aFt0aGlzLnR5cGVdKHRoaXMpO1xuICAgICAgICAgICAgICAgIF8uYmJveHd0ID0gcGF0aERpbWVuc2lvbnModGhpcy5yZWFsUGF0aCk7XG4gICAgICAgICAgICAgICAgXy5iYm94d3QudG9TdHJpbmcgPSB4X3lfd19oO1xuICAgICAgICAgICAgICAgIF8uZGlydHkgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIF8uYmJveHd0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChfLmRpcnR5IHx8IF8uZGlydHlUIHx8ICFfLmJib3gpIHtcbiAgICAgICAgICAgIGlmIChfLmRpcnR5IHx8ICF0aGlzLnJlYWxQYXRoKSB7XG4gICAgICAgICAgICAgICAgXy5iYm94d3QgPSAwO1xuICAgICAgICAgICAgICAgIHRoaXMucmVhbFBhdGggPSBnZXRQYXRoW3RoaXMudHlwZV0odGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfLmJib3ggPSBwYXRoRGltZW5zaW9ucyhtYXBQYXRoKHRoaXMucmVhbFBhdGgsIHRoaXMubWF0cml4KSk7XG4gICAgICAgICAgICBfLmJib3gudG9TdHJpbmcgPSB4X3lfd19oO1xuICAgICAgICAgICAgXy5kaXJ0eSA9IF8uZGlydHlUID0gMDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gXy5iYm94O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuY2xvbmVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICA9IChvYmplY3QpIGNsb25lIG9mIGEgZ2l2ZW4gZWxlbWVudFxuICAgICAqKlxuICAgIFxcKi9cbiAgICBlbHByb3RvLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5yZW1vdmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgb3V0ID0gdGhpcy5wYXBlclt0aGlzLnR5cGVdKCkuYXR0cih0aGlzLmF0dHIoKSk7XG4gICAgICAgIHRoaXMuX19zZXRfXyAmJiB0aGlzLl9fc2V0X18ucHVzaChvdXQpO1xuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuZ2xvd1xuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJuIHNldCBvZiBlbGVtZW50cyB0aGF0IGNyZWF0ZSBnbG93LWxpa2UgZWZmZWN0IGFyb3VuZCBnaXZlbiBlbGVtZW50LiBTZWUgQFBhcGVyLnNldC5cbiAgICAgKlxuICAgICAqIE5vdGU6IEdsb3cgaXMgbm90IGNvbm5lY3RlZCB0byB0aGUgZWxlbWVudC4gSWYgeW91IGNoYW5nZSBlbGVtZW50IGF0dHJpYnV0ZXMgaXQgd29u4oCZdCBhZGp1c3QgaXRzZWxmLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBnbG93IChvYmplY3QpICNvcHRpb25hbCBwYXJhbWV0ZXJzIG9iamVjdCB3aXRoIGFsbCBwcm9wZXJ0aWVzIG9wdGlvbmFsOlxuICAgICBvIHtcbiAgICAgbyAgICAgd2lkdGggKG51bWJlcikgc2l6ZSBvZiB0aGUgZ2xvdywgZGVmYXVsdCBpcyBgMTBgXG4gICAgIG8gICAgIGZpbGwgKGJvb2xlYW4pIHdpbGwgaXQgYmUgZmlsbGVkLCBkZWZhdWx0IGlzIGBmYWxzZWBcbiAgICAgbyAgICAgb3BhY2l0eSAobnVtYmVyKSBvcGFjaXR5LCBkZWZhdWx0IGlzIGAwLjVgXG4gICAgIG8gICAgIG9mZnNldHggKG51bWJlcikgaG9yaXpvbnRhbCBvZmZzZXQsIGRlZmF1bHQgaXMgYDBgXG4gICAgIG8gICAgIG9mZnNldHkgKG51bWJlcikgdmVydGljYWwgb2Zmc2V0LCBkZWZhdWx0IGlzIGAwYFxuICAgICBvICAgICBjb2xvciAoc3RyaW5nKSBnbG93IGNvbG91ciwgZGVmYXVsdCBpcyBgYmxhY2tgXG4gICAgIG8gfVxuICAgICA9IChvYmplY3QpIEBQYXBlci5zZXQgb2YgZWxlbWVudHMgdGhhdCByZXByZXNlbnRzIGdsb3dcbiAgICBcXCovXG4gICAgZWxwcm90by5nbG93ID0gZnVuY3Rpb24gKGdsb3cpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PSBcInRleHRcIikge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2xvdyA9IGdsb3cgfHwge307XG4gICAgICAgIHZhciBzID0ge1xuICAgICAgICAgICAgd2lkdGg6IChnbG93LndpZHRoIHx8IDEwKSArICgrdGhpcy5hdHRyKFwic3Ryb2tlLXdpZHRoXCIpIHx8IDEpLFxuICAgICAgICAgICAgZmlsbDogZ2xvdy5maWxsIHx8IGZhbHNlLFxuICAgICAgICAgICAgb3BhY2l0eTogZ2xvdy5vcGFjaXR5ID09IG51bGwgPyAuNSA6IGdsb3cub3BhY2l0eSxcbiAgICAgICAgICAgIG9mZnNldHg6IGdsb3cub2Zmc2V0eCB8fCAwLFxuICAgICAgICAgICAgb2Zmc2V0eTogZ2xvdy5vZmZzZXR5IHx8IDAsXG4gICAgICAgICAgICBjb2xvcjogZ2xvdy5jb2xvciB8fCBcIiMwMDBcIlxuICAgICAgICB9LFxuICAgICAgICAgICAgYyA9IHMud2lkdGggLyAyLFxuICAgICAgICAgICAgciA9IHRoaXMucGFwZXIsXG4gICAgICAgICAgICBvdXQgPSByLnNldCgpLFxuICAgICAgICAgICAgcGF0aCA9IHRoaXMucmVhbFBhdGggfHwgZ2V0UGF0aFt0aGlzLnR5cGVdKHRoaXMpO1xuICAgICAgICBwYXRoID0gdGhpcy5tYXRyaXggPyBtYXBQYXRoKHBhdGgsIHRoaXMubWF0cml4KSA6IHBhdGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYyArIDE7IGkrKykge1xuICAgICAgICAgICAgb3V0LnB1c2goci5wYXRoKHBhdGgpLmF0dHIoe1xuICAgICAgICAgICAgICAgIHN0cm9rZTogcy5jb2xvcixcbiAgICAgICAgICAgICAgICBmaWxsOiBzLmZpbGwgPyBzLmNvbG9yIDogXCJub25lXCIsXG4gICAgICAgICAgICAgICAgXCJzdHJva2UtbGluZWpvaW5cIjogXCJyb3VuZFwiLFxuICAgICAgICAgICAgICAgIFwic3Ryb2tlLWxpbmVjYXBcIjogXCJyb3VuZFwiLFxuICAgICAgICAgICAgICAgIFwic3Ryb2tlLXdpZHRoXCI6ICsocy53aWR0aCAvIGMgKiBpKS50b0ZpeGVkKDMpLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6ICsocy5vcGFjaXR5IC8gYykudG9GaXhlZCgzKVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQuaW5zZXJ0QmVmb3JlKHRoaXMpLnRyYW5zbGF0ZShzLm9mZnNldHgsIHMub2Zmc2V0eSk7XG4gICAgfTtcbiAgICB2YXIgY3VydmVzbGVuZ3RocyA9IHt9LFxuICAgIGdldFBvaW50QXRTZWdtZW50TGVuZ3RoID0gZnVuY3Rpb24gKHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKGxlbmd0aCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYmV6bGVuKHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBSLmZpbmREb3RzQXRTZWdtZW50KHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCBnZXRUYXRMZW4ocDF4LCBwMXksIGMxeCwgYzF5LCBjMngsIGMyeSwgcDJ4LCBwMnksIGxlbmd0aCkpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBnZXRMZW5ndGhGYWN0b3J5ID0gZnVuY3Rpb24gKGlzdG90YWwsIHN1YnBhdGgpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChwYXRoLCBsZW5ndGgsIG9ubHlzdGFydCkge1xuICAgICAgICAgICAgcGF0aCA9IHBhdGgyY3VydmUocGF0aCk7XG4gICAgICAgICAgICB2YXIgeCwgeSwgcCwgbCwgc3AgPSBcIlwiLCBzdWJwYXRocyA9IHt9LCBwb2ludCxcbiAgICAgICAgICAgICAgICBsZW4gPSAwO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gcGF0aC5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcCA9IHBhdGhbaV07XG4gICAgICAgICAgICAgICAgaWYgKHBbMF0gPT0gXCJNXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgeCA9ICtwWzFdO1xuICAgICAgICAgICAgICAgICAgICB5ID0gK3BbMl07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbCA9IGdldFBvaW50QXRTZWdtZW50TGVuZ3RoKHgsIHksIHBbMV0sIHBbMl0sIHBbM10sIHBbNF0sIHBbNV0sIHBbNl0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAobGVuICsgbCA+IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1YnBhdGggJiYgIXN1YnBhdGhzLnN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnQgPSBnZXRQb2ludEF0U2VnbWVudExlbmd0aCh4LCB5LCBwWzFdLCBwWzJdLCBwWzNdLCBwWzRdLCBwWzVdLCBwWzZdLCBsZW5ndGggLSBsZW4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwICs9IFtcIkNcIiArIHBvaW50LnN0YXJ0LngsIHBvaW50LnN0YXJ0LnksIHBvaW50Lm0ueCwgcG9pbnQubS55LCBwb2ludC54LCBwb2ludC55XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob25seXN0YXJ0KSB7cmV0dXJuIHNwO31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwYXRocy5zdGFydCA9IHNwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwID0gW1wiTVwiICsgcG9pbnQueCwgcG9pbnQueSArIFwiQ1wiICsgcG9pbnQubi54LCBwb2ludC5uLnksIHBvaW50LmVuZC54LCBwb2ludC5lbmQueSwgcFs1XSwgcFs2XV0uam9pbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiArPSBsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSArcFs1XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gK3BbNl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzdG90YWwgJiYgIXN1YnBhdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludCA9IGdldFBvaW50QXRTZWdtZW50TGVuZ3RoKHgsIHksIHBbMV0sIHBbMl0sIHBbM10sIHBbNF0sIHBbNV0sIHBbNl0sIGxlbmd0aCAtIGxlbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHt4OiBwb2ludC54LCB5OiBwb2ludC55LCBhbHBoYTogcG9pbnQuYWxwaGF9O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGxlbiArPSBsO1xuICAgICAgICAgICAgICAgICAgICB4ID0gK3BbNV07XG4gICAgICAgICAgICAgICAgICAgIHkgPSArcFs2XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3AgKz0gcC5zaGlmdCgpICsgcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1YnBhdGhzLmVuZCA9IHNwO1xuICAgICAgICAgICAgcG9pbnQgPSBpc3RvdGFsID8gbGVuIDogc3VicGF0aCA/IHN1YnBhdGhzIDogUi5maW5kRG90c0F0U2VnbWVudCh4LCB5LCBwWzBdLCBwWzFdLCBwWzJdLCBwWzNdLCBwWzRdLCBwWzVdLCAxKTtcbiAgICAgICAgICAgIHBvaW50LmFscGhhICYmIChwb2ludCA9IHt4OiBwb2ludC54LCB5OiBwb2ludC55LCBhbHBoYTogcG9pbnQuYWxwaGF9KTtcbiAgICAgICAgICAgIHJldHVybiBwb2ludDtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHZhciBnZXRUb3RhbExlbmd0aCA9IGdldExlbmd0aEZhY3RvcnkoMSksXG4gICAgICAgIGdldFBvaW50QXRMZW5ndGggPSBnZXRMZW5ndGhGYWN0b3J5KCksXG4gICAgICAgIGdldFN1YnBhdGhzQXRMZW5ndGggPSBnZXRMZW5ndGhGYWN0b3J5KDAsIDEpO1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmdldFRvdGFsTGVuZ3RoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm5zIGxlbmd0aCBvZiB0aGUgZ2l2ZW4gcGF0aCBpbiBwaXhlbHMuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHBhdGggKHN0cmluZykgU1ZHIHBhdGggc3RyaW5nLlxuICAgICAqKlxuICAgICA9IChudW1iZXIpIGxlbmd0aC5cbiAgICBcXCovXG4gICAgUi5nZXRUb3RhbExlbmd0aCA9IGdldFRvdGFsTGVuZ3RoO1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmdldFBvaW50QXRMZW5ndGhcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJldHVybiBjb29yZGluYXRlcyBvZiB0aGUgcG9pbnQgbG9jYXRlZCBhdCB0aGUgZ2l2ZW4gbGVuZ3RoIG9uIHRoZSBnaXZlbiBwYXRoLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBwYXRoIChzdHJpbmcpIFNWRyBwYXRoIHN0cmluZ1xuICAgICAtIGxlbmd0aCAobnVtYmVyKVxuICAgICAqKlxuICAgICA9IChvYmplY3QpIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwb2ludDpcbiAgICAgbyB7XG4gICAgIG8gICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZVxuICAgICBvICAgICB5OiAobnVtYmVyKSB5IGNvb3JkaW5hdGVcbiAgICAgbyAgICAgYWxwaGE6IChudW1iZXIpIGFuZ2xlIG9mIGRlcml2YXRpdmVcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIuZ2V0UG9pbnRBdExlbmd0aCA9IGdldFBvaW50QXRMZW5ndGg7XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZ2V0U3VicGF0aFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJuIHN1YnBhdGggb2YgYSBnaXZlbiBwYXRoIGZyb20gZ2l2ZW4gbGVuZ3RoIHRvIGdpdmVuIGxlbmd0aC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gcGF0aCAoc3RyaW5nKSBTVkcgcGF0aCBzdHJpbmdcbiAgICAgLSBmcm9tIChudW1iZXIpIHBvc2l0aW9uIG9mIHRoZSBzdGFydCBvZiB0aGUgc2VnbWVudFxuICAgICAtIHRvIChudW1iZXIpIHBvc2l0aW9uIG9mIHRoZSBlbmQgb2YgdGhlIHNlZ21lbnRcbiAgICAgKipcbiAgICAgPSAoc3RyaW5nKSBwYXRoc3RyaW5nIGZvciB0aGUgc2VnbWVudFxuICAgIFxcKi9cbiAgICBSLmdldFN1YnBhdGggPSBmdW5jdGlvbiAocGF0aCwgZnJvbSwgdG8pIHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0VG90YWxMZW5ndGgocGF0aCkgLSB0byA8IDFlLTYpIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRTdWJwYXRoc0F0TGVuZ3RoKHBhdGgsIGZyb20pLmVuZDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYSA9IGdldFN1YnBhdGhzQXRMZW5ndGgocGF0aCwgdG8sIDEpO1xuICAgICAgICByZXR1cm4gZnJvbSA/IGdldFN1YnBhdGhzQXRMZW5ndGgoYSwgZnJvbSkuZW5kIDogYTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LmdldFRvdGFsTGVuZ3RoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm5zIGxlbmd0aCBvZiB0aGUgcGF0aCBpbiBwaXhlbHMuIE9ubHkgd29ya3MgZm9yIGVsZW1lbnQgb2Yg4oCccGF0aOKAnSB0eXBlLlxuICAgICA9IChudW1iZXIpIGxlbmd0aC5cbiAgICBcXCovXG4gICAgZWxwcm90by5nZXRUb3RhbExlbmd0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLmdldFBhdGgoKTtcbiAgICAgICAgaWYgKCFwYXRoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5ub2RlLmdldFRvdGFsTGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ub2RlLmdldFRvdGFsTGVuZ3RoKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ2V0VG90YWxMZW5ndGgocGF0aCk7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5nZXRQb2ludEF0TGVuZ3RoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm4gY29vcmRpbmF0ZXMgb2YgdGhlIHBvaW50IGxvY2F0ZWQgYXQgdGhlIGdpdmVuIGxlbmd0aCBvbiB0aGUgZ2l2ZW4gcGF0aC4gT25seSB3b3JrcyBmb3IgZWxlbWVudCBvZiDigJxwYXRo4oCdIHR5cGUuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGxlbmd0aCAobnVtYmVyKVxuICAgICAqKlxuICAgICA9IChvYmplY3QpIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwb2ludDpcbiAgICAgbyB7XG4gICAgIG8gICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZVxuICAgICBvICAgICB5OiAobnVtYmVyKSB5IGNvb3JkaW5hdGVcbiAgICAgbyAgICAgYWxwaGE6IChudW1iZXIpIGFuZ2xlIG9mIGRlcml2YXRpdmVcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0UG9pbnRBdExlbmd0aCA9IGZ1bmN0aW9uIChsZW5ndGgpIHtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLmdldFBhdGgoKTtcbiAgICAgICAgaWYgKCFwYXRoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ2V0UG9pbnRBdExlbmd0aChwYXRoLCBsZW5ndGgpO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuZ2V0UGF0aFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyBwYXRoIG9mIHRoZSBlbGVtZW50LiBPbmx5IHdvcmtzIGZvciBlbGVtZW50cyBvZiDigJxwYXRo4oCdIHR5cGUgYW5kIHNpbXBsZSBlbGVtZW50cyBsaWtlIGNpcmNsZS5cbiAgICAgPSAob2JqZWN0KSBwYXRoXG4gICAgICoqXG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0UGF0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBhdGgsXG4gICAgICAgICAgICBnZXRQYXRoID0gUi5fZ2V0UGF0aFt0aGlzLnR5cGVdO1xuXG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT0gXCJ0ZXh0XCIgfHwgdGhpcy50eXBlID09IFwic2V0XCIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChnZXRQYXRoKSB7XG4gICAgICAgICAgICBwYXRoID0gZ2V0UGF0aCh0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuZ2V0U3VicGF0aFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJuIHN1YnBhdGggb2YgYSBnaXZlbiBlbGVtZW50IGZyb20gZ2l2ZW4gbGVuZ3RoIHRvIGdpdmVuIGxlbmd0aC4gT25seSB3b3JrcyBmb3IgZWxlbWVudCBvZiDigJxwYXRo4oCdIHR5cGUuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGZyb20gKG51bWJlcikgcG9zaXRpb24gb2YgdGhlIHN0YXJ0IG9mIHRoZSBzZWdtZW50XG4gICAgIC0gdG8gKG51bWJlcikgcG9zaXRpb24gb2YgdGhlIGVuZCBvZiB0aGUgc2VnbWVudFxuICAgICAqKlxuICAgICA9IChzdHJpbmcpIHBhdGhzdHJpbmcgZm9yIHRoZSBzZWdtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0U3VicGF0aCA9IGZ1bmN0aW9uIChmcm9tLCB0bykge1xuICAgICAgICB2YXIgcGF0aCA9IHRoaXMuZ2V0UGF0aCgpO1xuICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBSLmdldFN1YnBhdGgocGF0aCwgZnJvbSwgdG8pO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZWFzaW5nX2Zvcm11bGFzXG4gICAgIFsgcHJvcGVydHkgXVxuICAgICAqKlxuICAgICAqIE9iamVjdCB0aGF0IGNvbnRhaW5zIGVhc2luZyBmb3JtdWxhcyBmb3IgYW5pbWF0aW9uLiBZb3UgY291bGQgZXh0ZW5kIGl0IHdpdGggeW91ciBvd24uIEJ5IGRlZmF1bHQgaXQgaGFzIGZvbGxvd2luZyBsaXN0IG9mIGVhc2luZzpcbiAgICAgIyA8dWw+XG4gICAgICMgICAgIDxsaT7igJxsaW5lYXLigJ08L2xpPlxuICAgICAjICAgICA8bGk+4oCcJmx0O+KAnSBvciDigJxlYXNlSW7igJ0gb3Ig4oCcZWFzZS1pbuKAnTwvbGk+XG4gICAgICMgICAgIDxsaT7igJw+4oCdIG9yIOKAnGVhc2VPdXTigJ0gb3Ig4oCcZWFzZS1vdXTigJ08L2xpPlxuICAgICAjICAgICA8bGk+4oCcJmx0Oz7igJ0gb3Ig4oCcZWFzZUluT3V04oCdIG9yIOKAnGVhc2UtaW4tb3V04oCdPC9saT5cbiAgICAgIyAgICAgPGxpPuKAnGJhY2tJbuKAnSBvciDigJxiYWNrLWlu4oCdPC9saT5cbiAgICAgIyAgICAgPGxpPuKAnGJhY2tPdXTigJ0gb3Ig4oCcYmFjay1vdXTigJ08L2xpPlxuICAgICAjICAgICA8bGk+4oCcZWxhc3RpY+KAnTwvbGk+XG4gICAgICMgICAgIDxsaT7igJxib3VuY2XigJ08L2xpPlxuICAgICAjIDwvdWw+XG4gICAgICMgPHA+U2VlIGFsc28gPGEgaHJlZj1cImh0dHA6Ly9yYXBoYWVsanMuY29tL2Vhc2luZy5odG1sXCI+RWFzaW5nIGRlbW88L2E+LjwvcD5cbiAgICBcXCovXG4gICAgdmFyIGVmID0gUi5lYXNpbmdfZm9ybXVsYXMgPSB7XG4gICAgICAgIGxpbmVhcjogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIHJldHVybiBuO1xuICAgICAgICB9LFxuICAgICAgICBcIjxcIjogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIHJldHVybiBwb3cobiwgMS43KTtcbiAgICAgICAgfSxcbiAgICAgICAgXCI+XCI6IGZ1bmN0aW9uIChuKSB7XG4gICAgICAgICAgICByZXR1cm4gcG93KG4sIC40OCk7XG4gICAgICAgIH0sXG4gICAgICAgIFwiPD5cIjogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIHZhciBxID0gLjQ4IC0gbiAvIDEuMDQsXG4gICAgICAgICAgICAgICAgUSA9IG1hdGguc3FydCguMTczNCArIHEgKiBxKSxcbiAgICAgICAgICAgICAgICB4ID0gUSAtIHEsXG4gICAgICAgICAgICAgICAgWCA9IHBvdyhhYnMoeCksIDEgLyAzKSAqICh4IDwgMCA/IC0xIDogMSksXG4gICAgICAgICAgICAgICAgeSA9IC1RIC0gcSxcbiAgICAgICAgICAgICAgICBZID0gcG93KGFicyh5KSwgMSAvIDMpICogKHkgPCAwID8gLTEgOiAxKSxcbiAgICAgICAgICAgICAgICB0ID0gWCArIFkgKyAuNTtcbiAgICAgICAgICAgIHJldHVybiAoMSAtIHQpICogMyAqIHQgKiB0ICsgdCAqIHQgKiB0O1xuICAgICAgICB9LFxuICAgICAgICBiYWNrSW46IGZ1bmN0aW9uIChuKSB7XG4gICAgICAgICAgICB2YXIgcyA9IDEuNzAxNTg7XG4gICAgICAgICAgICByZXR1cm4gbiAqIG4gKiAoKHMgKyAxKSAqIG4gLSBzKTtcbiAgICAgICAgfSxcbiAgICAgICAgYmFja091dDogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIG4gPSBuIC0gMTtcbiAgICAgICAgICAgIHZhciBzID0gMS43MDE1ODtcbiAgICAgICAgICAgIHJldHVybiBuICogbiAqICgocyArIDEpICogbiArIHMpICsgMTtcbiAgICAgICAgfSxcbiAgICAgICAgZWxhc3RpYzogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIGlmIChuID09ICEhbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHBvdygyLCAtMTAgKiBuKSAqIG1hdGguc2luKChuIC0gLjA3NSkgKiAoMiAqIFBJKSAvIC4zKSArIDE7XG4gICAgICAgIH0sXG4gICAgICAgIGJvdW5jZTogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIHZhciBzID0gNy41NjI1LFxuICAgICAgICAgICAgICAgIHAgPSAyLjc1LFxuICAgICAgICAgICAgICAgIGw7XG4gICAgICAgICAgICBpZiAobiA8ICgxIC8gcCkpIHtcbiAgICAgICAgICAgICAgICBsID0gcyAqIG4gKiBuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAobiA8ICgyIC8gcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbiAtPSAoMS41IC8gcCk7XG4gICAgICAgICAgICAgICAgICAgIGwgPSBzICogbiAqIG4gKyAuNzU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG4gPCAoMi41IC8gcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG4gLT0gKDIuMjUgLyBwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGwgPSBzICogbiAqIG4gKyAuOTM3NTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG4gLT0gKDIuNjI1IC8gcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBsID0gcyAqIG4gKiBuICsgLjk4NDM3NTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBsO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBlZi5lYXNlSW4gPSBlZltcImVhc2UtaW5cIl0gPSBlZltcIjxcIl07XG4gICAgZWYuZWFzZU91dCA9IGVmW1wiZWFzZS1vdXRcIl0gPSBlZltcIj5cIl07XG4gICAgZWYuZWFzZUluT3V0ID0gZWZbXCJlYXNlLWluLW91dFwiXSA9IGVmW1wiPD5cIl07XG4gICAgZWZbXCJiYWNrLWluXCJdID0gZWYuYmFja0luO1xuICAgIGVmW1wiYmFjay1vdXRcIl0gPSBlZi5iYWNrT3V0O1xuXG4gICAgdmFyIGFuaW1hdGlvbkVsZW1lbnRzID0gW10sXG4gICAgICAgIHJlcXVlc3RBbmltRnJhbWUgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lICAgICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cub1JlcXVlc3RBbmltYXRpb25GcmFtZSAgICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubXNSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGNhbGxiYWNrLCAxNik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICBhbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgTm93ID0gK25ldyBEYXRlLFxuICAgICAgICAgICAgICAgIGwgPSAwO1xuICAgICAgICAgICAgZm9yICg7IGwgPCBhbmltYXRpb25FbGVtZW50cy5sZW5ndGg7IGwrKykge1xuICAgICAgICAgICAgICAgIHZhciBlID0gYW5pbWF0aW9uRWxlbWVudHNbbF07XG4gICAgICAgICAgICAgICAgaWYgKGUuZWwucmVtb3ZlZCB8fCBlLnBhdXNlZCkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHRpbWUgPSBOb3cgLSBlLnN0YXJ0LFxuICAgICAgICAgICAgICAgICAgICBtcyA9IGUubXMsXG4gICAgICAgICAgICAgICAgICAgIGVhc2luZyA9IGUuZWFzaW5nLFxuICAgICAgICAgICAgICAgICAgICBmcm9tID0gZS5mcm9tLFxuICAgICAgICAgICAgICAgICAgICBkaWZmID0gZS5kaWZmLFxuICAgICAgICAgICAgICAgICAgICB0byA9IGUudG8sXG4gICAgICAgICAgICAgICAgICAgIHQgPSBlLnQsXG4gICAgICAgICAgICAgICAgICAgIHRoYXQgPSBlLmVsLFxuICAgICAgICAgICAgICAgICAgICBzZXQgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgbm93LFxuICAgICAgICAgICAgICAgICAgICBpbml0ID0ge30sXG4gICAgICAgICAgICAgICAgICAgIGtleTtcbiAgICAgICAgICAgICAgICBpZiAoZS5pbml0c3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRpbWUgPSAoZS5pbml0c3RhdHVzICogZS5hbmltLnRvcCAtIGUucHJldikgLyAoZS5wZXJjZW50IC0gZS5wcmV2KSAqIG1zO1xuICAgICAgICAgICAgICAgICAgICBlLnN0YXR1cyA9IGUuaW5pdHN0YXR1cztcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGUuaW5pdHN0YXR1cztcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wICYmIGFuaW1hdGlvbkVsZW1lbnRzLnNwbGljZShsLS0sIDEpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGUuc3RhdHVzID0gKGUucHJldiArIChlLnBlcmNlbnQgLSBlLnByZXYpICogKHRpbWUgLyBtcykpIC8gZS5hbmltLnRvcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRpbWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGltZSA8IG1zKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSBlYXNpbmcodGltZSAvIG1zKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgYXR0ciBpbiBmcm9tKSBpZiAoZnJvbVtoYXNdKGF0dHIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGF2YWlsYWJsZUFuaW1BdHRyc1thdHRyXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgbnU6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9ICtmcm9tW2F0dHJdICsgcG9zICogbXMgKiBkaWZmW2F0dHJdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiY29sb3VyXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9IFwicmdiKFwiICsgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXB0bzI1NShyb3VuZChmcm9tW2F0dHJdLnIgKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl0ucikpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXB0bzI1NShyb3VuZChmcm9tW2F0dHJdLmcgKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl0uZykpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXB0bzI1NShyb3VuZChmcm9tW2F0dHJdLmIgKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl0uYikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0uam9pbihcIixcIikgKyBcIilcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcInBhdGhcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93ID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZyb21bYXR0cl0ubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93W2ldID0gW2Zyb21bYXR0cl1baV1bMF1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDEsIGpqID0gZnJvbVthdHRyXVtpXS5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93W2ldW2pdID0gK2Zyb21bYXR0cl1baV1bal0gKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl1baV1bal07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3dbaV0gPSBub3dbaV0uam9pbihTKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBub3cuam9pbihTKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcInRyYW5zZm9ybVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlmZlthdHRyXS5yZWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGlpID0gZnJvbVthdHRyXS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93W2ldID0gW2Zyb21bYXR0cl1baV1bMF1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDEsIGpqID0gZnJvbVthdHRyXVtpXS5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vd1tpXVtqXSA9IGZyb21bYXR0cl1baV1bal0gKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl1baV1bal07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGdldCA9IGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICtmcm9tW2F0dHJdW2ldICsgcG9zICogbXMgKiBkaWZmW2F0dHJdW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdyA9IFtbXCJyXCIsIGdldCgyKSwgMCwgMF0sIFtcInRcIiwgZ2V0KDMpLCBnZXQoNCldLCBbXCJzXCIsIGdldCgwKSwgZ2V0KDEpLCAwLCAwXV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBbW1wibVwiLCBnZXQoMCksIGdldCgxKSwgZ2V0KDIpLCBnZXQoMyksIGdldCg0KSwgZ2V0KDUpXV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcImNzdlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ciA9PSBcImNsaXAtcmVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPSA0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vd1tpXSA9ICtmcm9tW2F0dHJdW2ldICsgcG9zICogbXMgKiBkaWZmW2F0dHJdW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmcm9tMiA9IFtdW2NvbmNhdF0oZnJvbVthdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID0gdGhhdC5wYXBlci5jdXN0b21BdHRyaWJ1dGVzW2F0dHJdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93W2ldID0gK2Zyb20yW2ldICsgcG9zICogbXMgKiBkaWZmW2F0dHJdW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0W2F0dHJdID0gbm93O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuYXR0cihzZXQpO1xuICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKGlkLCB0aGF0LCBhbmltKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmUoXCJyYXBoYWVsLmFuaW0uZnJhbWUuXCIgKyBpZCwgdGhhdCwgYW5pbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSkodGhhdC5pZCwgdGhhdCwgZS5hbmltKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24oZiwgZWwsIGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlKFwicmFwaGFlbC5hbmltLmZyYW1lLlwiICsgZWwuaWQsIGVsLCBhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmUoXCJyYXBoYWVsLmFuaW0uZmluaXNoLlwiICsgZWwuaWQsIGVsLCBhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSLmlzKGYsIFwiZnVuY3Rpb25cIikgJiYgZi5jYWxsKGVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KShlLmNhbGxiYWNrLCB0aGF0LCBlLmFuaW0pO1xuICAgICAgICAgICAgICAgICAgICB0aGF0LmF0dHIodG8pO1xuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25FbGVtZW50cy5zcGxpY2UobC0tLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGUucmVwZWF0ID4gMSAmJiAhZS5uZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiB0bykgaWYgKHRvW2hhc10oa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXRba2V5XSA9IGUudG90YWxPcmlnaW5ba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGUuZWwuYXR0cihpbml0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bkFuaW1hdGlvbihlLmFuaW0sIGUuZWwsIGUuYW5pbS5wZXJjZW50c1swXSwgbnVsbCwgZS50b3RhbE9yaWdpbiwgZS5yZXBlYXQgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZS5uZXh0ICYmICFlLnN0b3ApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bkFuaW1hdGlvbihlLmFuaW0sIGUuZWwsIGUubmV4dCwgbnVsbCwgZS50b3RhbE9yaWdpbiwgZS5yZXBlYXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoICYmIHJlcXVlc3RBbmltRnJhbWUoYW5pbWF0aW9uKTtcbiAgICAgICAgfSxcbiAgICAgICAgdXB0bzI1NSA9IGZ1bmN0aW9uIChjb2xvcikge1xuICAgICAgICAgICAgcmV0dXJuIGNvbG9yID4gMjU1ID8gMjU1IDogY29sb3IgPCAwID8gMCA6IGNvbG9yO1xuICAgICAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LmFuaW1hdGVXaXRoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBY3RzIHNpbWlsYXIgdG8gQEVsZW1lbnQuYW5pbWF0ZSwgYnV0IGVuc3VyZSB0aGF0IGdpdmVuIGFuaW1hdGlvbiBydW5zIGluIHN5bmMgd2l0aCBhbm90aGVyIGdpdmVuIGVsZW1lbnQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGVsIChvYmplY3QpIGVsZW1lbnQgdG8gc3luYyB3aXRoXG4gICAgIC0gYW5pbSAob2JqZWN0KSBhbmltYXRpb24gdG8gc3luYyB3aXRoXG4gICAgIC0gcGFyYW1zIChvYmplY3QpICNvcHRpb25hbCBmaW5hbCBhdHRyaWJ1dGVzIGZvciB0aGUgZWxlbWVudCwgc2VlIGFsc28gQEVsZW1lbnQuYXR0clxuICAgICAtIG1zIChudW1iZXIpICNvcHRpb25hbCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGZvciBhbmltYXRpb24gdG8gcnVuXG4gICAgIC0gZWFzaW5nIChzdHJpbmcpICNvcHRpb25hbCBlYXNpbmcgdHlwZS4gQWNjZXB0IG9uIG9mIEBSYXBoYWVsLmVhc2luZ19mb3JtdWxhcyBvciBDU1MgZm9ybWF0OiBgY3ViaWMmI3gyMDEwO2JlemllcihYWCwmIzE2MDtYWCwmIzE2MDtYWCwmIzE2MDtYWClgXG4gICAgIC0gY2FsbGJhY2sgKGZ1bmN0aW9uKSAjb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24uIFdpbGwgYmUgY2FsbGVkIGF0IHRoZSBlbmQgb2YgYW5pbWF0aW9uLlxuICAgICAqIG9yXG4gICAgIC0gZWxlbWVudCAob2JqZWN0KSBlbGVtZW50IHRvIHN5bmMgd2l0aFxuICAgICAtIGFuaW0gKG9iamVjdCkgYW5pbWF0aW9uIHRvIHN5bmMgd2l0aFxuICAgICAtIGFuaW1hdGlvbiAob2JqZWN0KSAjb3B0aW9uYWwgYW5pbWF0aW9uIG9iamVjdCwgc2VlIEBSYXBoYWVsLmFuaW1hdGlvblxuICAgICAqKlxuICAgICA9IChvYmplY3QpIG9yaWdpbmFsIGVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5hbmltYXRlV2l0aCA9IGZ1bmN0aW9uIChlbCwgYW5pbSwgcGFyYW1zLCBtcywgZWFzaW5nLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXM7XG4gICAgICAgIGlmIChlbGVtZW50LnJlbW92ZWQpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrLmNhbGwoZWxlbWVudCk7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYSA9IHBhcmFtcyBpbnN0YW5jZW9mIEFuaW1hdGlvbiA/IHBhcmFtcyA6IFIuYW5pbWF0aW9uKHBhcmFtcywgbXMsIGVhc2luZywgY2FsbGJhY2spLFxuICAgICAgICAgICAgeCwgeTtcbiAgICAgICAgcnVuQW5pbWF0aW9uKGEsIGVsZW1lbnQsIGEucGVyY2VudHNbMF0sIG51bGwsIGVsZW1lbnQuYXR0cigpKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgaWYgKGFuaW1hdGlvbkVsZW1lbnRzW2ldLmFuaW0gPT0gYW5pbSAmJiBhbmltYXRpb25FbGVtZW50c1tpXS5lbCA9PSBlbCkge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbkVsZW1lbnRzW2lpIC0gMV0uc3RhcnQgPSBhbmltYXRpb25FbGVtZW50c1tpXS5zdGFydDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgLy9cbiAgICAgICAgLy9cbiAgICAgICAgLy8gdmFyIGEgPSBwYXJhbXMgPyBSLmFuaW1hdGlvbihwYXJhbXMsIG1zLCBlYXNpbmcsIGNhbGxiYWNrKSA6IGFuaW0sXG4gICAgICAgIC8vICAgICBzdGF0dXMgPSBlbGVtZW50LnN0YXR1cyhhbmltKTtcbiAgICAgICAgLy8gcmV0dXJuIHRoaXMuYW5pbWF0ZShhKS5zdGF0dXMoYSwgc3RhdHVzICogYW5pbS5tcyAvIGEubXMpO1xuICAgIH07XG4gICAgZnVuY3Rpb24gQ3ViaWNCZXppZXJBdFRpbWUodCwgcDF4LCBwMXksIHAyeCwgcDJ5LCBkdXJhdGlvbikge1xuICAgICAgICB2YXIgY3ggPSAzICogcDF4LFxuICAgICAgICAgICAgYnggPSAzICogKHAyeCAtIHAxeCkgLSBjeCxcbiAgICAgICAgICAgIGF4ID0gMSAtIGN4IC0gYngsXG4gICAgICAgICAgICBjeSA9IDMgKiBwMXksXG4gICAgICAgICAgICBieSA9IDMgKiAocDJ5IC0gcDF5KSAtIGN5LFxuICAgICAgICAgICAgYXkgPSAxIC0gY3kgLSBieTtcbiAgICAgICAgZnVuY3Rpb24gc2FtcGxlQ3VydmVYKHQpIHtcbiAgICAgICAgICAgIHJldHVybiAoKGF4ICogdCArIGJ4KSAqIHQgKyBjeCkgKiB0O1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHNvbHZlKHgsIGVwc2lsb24pIHtcbiAgICAgICAgICAgIHZhciB0ID0gc29sdmVDdXJ2ZVgoeCwgZXBzaWxvbik7XG4gICAgICAgICAgICByZXR1cm4gKChheSAqIHQgKyBieSkgKiB0ICsgY3kpICogdDtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzb2x2ZUN1cnZlWCh4LCBlcHNpbG9uKSB7XG4gICAgICAgICAgICB2YXIgdDAsIHQxLCB0MiwgeDIsIGQyLCBpO1xuICAgICAgICAgICAgZm9yKHQyID0geCwgaSA9IDA7IGkgPCA4OyBpKyspIHtcbiAgICAgICAgICAgICAgICB4MiA9IHNhbXBsZUN1cnZlWCh0MikgLSB4O1xuICAgICAgICAgICAgICAgIGlmIChhYnMoeDIpIDwgZXBzaWxvbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGQyID0gKDMgKiBheCAqIHQyICsgMiAqIGJ4KSAqIHQyICsgY3g7XG4gICAgICAgICAgICAgICAgaWYgKGFicyhkMikgPCAxZS02KSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0MiA9IHQyIC0geDIgLyBkMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHQwID0gMDtcbiAgICAgICAgICAgIHQxID0gMTtcbiAgICAgICAgICAgIHQyID0geDtcbiAgICAgICAgICAgIGlmICh0MiA8IHQwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHQwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHQyID4gdDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3aGlsZSAodDAgPCB0MSkge1xuICAgICAgICAgICAgICAgIHgyID0gc2FtcGxlQ3VydmVYKHQyKTtcbiAgICAgICAgICAgICAgICBpZiAoYWJzKHgyIC0geCkgPCBlcHNpbG9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0MjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHggPiB4Mikge1xuICAgICAgICAgICAgICAgICAgICB0MCA9IHQyO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHQxID0gdDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHQyID0gKHQxIC0gdDApIC8gMiArIHQwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHQyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzb2x2ZSh0LCAxIC8gKDIwMCAqIGR1cmF0aW9uKSk7XG4gICAgfVxuICAgIGVscHJvdG8ub25BbmltYXRpb24gPSBmdW5jdGlvbiAoZikge1xuICAgICAgICBmID8gZXZlLm9uKFwicmFwaGFlbC5hbmltLmZyYW1lLlwiICsgdGhpcy5pZCwgZikgOiBldmUudW5iaW5kKFwicmFwaGFlbC5hbmltLmZyYW1lLlwiICsgdGhpcy5pZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgZnVuY3Rpb24gQW5pbWF0aW9uKGFuaW0sIG1zKSB7XG4gICAgICAgIHZhciBwZXJjZW50cyA9IFtdLFxuICAgICAgICAgICAgbmV3QW5pbSA9IHt9O1xuICAgICAgICB0aGlzLm1zID0gbXM7XG4gICAgICAgIHRoaXMudGltZXMgPSAxO1xuICAgICAgICBpZiAoYW5pbSkge1xuICAgICAgICAgICAgZm9yICh2YXIgYXR0ciBpbiBhbmltKSBpZiAoYW5pbVtoYXNdKGF0dHIpKSB7XG4gICAgICAgICAgICAgICAgbmV3QW5pbVt0b0Zsb2F0KGF0dHIpXSA9IGFuaW1bYXR0cl07XG4gICAgICAgICAgICAgICAgcGVyY2VudHMucHVzaCh0b0Zsb2F0KGF0dHIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBlcmNlbnRzLnNvcnQoc29ydEJ5TnVtYmVyKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFuaW0gPSBuZXdBbmltO1xuICAgICAgICB0aGlzLnRvcCA9IHBlcmNlbnRzW3BlcmNlbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgICB0aGlzLnBlcmNlbnRzID0gcGVyY2VudHM7XG4gICAgfVxuICAgIC8qXFxcbiAgICAgKiBBbmltYXRpb24uZGVsYXlcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIGV4aXN0aW5nIGFuaW1hdGlvbiBvYmplY3Qgd2l0aCBnaXZlbiBkZWxheS5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gZGVsYXkgKG51bWJlcikgbnVtYmVyIG9mIG1zIHRvIHBhc3MgYmV0d2VlbiBhbmltYXRpb24gc3RhcnQgYW5kIGFjdHVhbCBhbmltYXRpb25cbiAgICAgKipcbiAgICAgPSAob2JqZWN0KSBuZXcgYWx0ZXJlZCBBbmltYXRpb24gb2JqZWN0XG4gICAgIHwgdmFyIGFuaW0gPSBSYXBoYWVsLmFuaW1hdGlvbih7Y3g6IDEwLCBjeTogMjB9LCAyZTMpO1xuICAgICB8IGNpcmNsZTEuYW5pbWF0ZShhbmltKTsgLy8gcnVuIHRoZSBnaXZlbiBhbmltYXRpb24gaW1tZWRpYXRlbHlcbiAgICAgfCBjaXJjbGUyLmFuaW1hdGUoYW5pbS5kZWxheSg1MDApKTsgLy8gcnVuIHRoZSBnaXZlbiBhbmltYXRpb24gYWZ0ZXIgNTAwIG1zXG4gICAgXFwqL1xuICAgIEFuaW1hdGlvbi5wcm90b3R5cGUuZGVsYXkgPSBmdW5jdGlvbiAoZGVsYXkpIHtcbiAgICAgICAgdmFyIGEgPSBuZXcgQW5pbWF0aW9uKHRoaXMuYW5pbSwgdGhpcy5tcyk7XG4gICAgICAgIGEudGltZXMgPSB0aGlzLnRpbWVzO1xuICAgICAgICBhLmRlbCA9ICtkZWxheSB8fCAwO1xuICAgICAgICByZXR1cm4gYTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBBbmltYXRpb24ucmVwZWF0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIGEgY29weSBvZiBleGlzdGluZyBhbmltYXRpb24gb2JqZWN0IHdpdGggZ2l2ZW4gcmVwZXRpdGlvbi5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gcmVwZWF0IChudW1iZXIpIG51bWJlciBpdGVyYXRpb25zIG9mIGFuaW1hdGlvbi4gRm9yIGluZmluaXRlIGFuaW1hdGlvbiBwYXNzIGBJbmZpbml0eWBcbiAgICAgKipcbiAgICAgPSAob2JqZWN0KSBuZXcgYWx0ZXJlZCBBbmltYXRpb24gb2JqZWN0XG4gICAgXFwqL1xuICAgIEFuaW1hdGlvbi5wcm90b3R5cGUucmVwZWF0ID0gZnVuY3Rpb24gKHRpbWVzKSB7XG4gICAgICAgIHZhciBhID0gbmV3IEFuaW1hdGlvbih0aGlzLmFuaW0sIHRoaXMubXMpO1xuICAgICAgICBhLmRlbCA9IHRoaXMuZGVsO1xuICAgICAgICBhLnRpbWVzID0gbWF0aC5mbG9vcihtbWF4KHRpbWVzLCAwKSkgfHwgMTtcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfTtcbiAgICBmdW5jdGlvbiBydW5BbmltYXRpb24oYW5pbSwgZWxlbWVudCwgcGVyY2VudCwgc3RhdHVzLCB0b3RhbE9yaWdpbiwgdGltZXMpIHtcbiAgICAgICAgcGVyY2VudCA9IHRvRmxvYXQocGVyY2VudCk7XG4gICAgICAgIHZhciBwYXJhbXMsXG4gICAgICAgICAgICBpc0luQW5pbSxcbiAgICAgICAgICAgIGlzSW5BbmltU2V0LFxuICAgICAgICAgICAgcGVyY2VudHMgPSBbXSxcbiAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICBwcmV2LFxuICAgICAgICAgICAgdGltZXN0YW1wLFxuICAgICAgICAgICAgbXMgPSBhbmltLm1zLFxuICAgICAgICAgICAgZnJvbSA9IHt9LFxuICAgICAgICAgICAgdG8gPSB7fSxcbiAgICAgICAgICAgIGRpZmYgPSB7fTtcbiAgICAgICAgaWYgKHN0YXR1cykge1xuICAgICAgICAgICAgZm9yIChpID0gMCwgaWkgPSBhbmltYXRpb25FbGVtZW50cy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGUgPSBhbmltYXRpb25FbGVtZW50c1tpXTtcbiAgICAgICAgICAgICAgICBpZiAoZS5lbC5pZCA9PSBlbGVtZW50LmlkICYmIGUuYW5pbSA9PSBhbmltKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlLnBlcmNlbnQgIT0gcGVyY2VudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNJbkFuaW1TZXQgPSAxO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNJbkFuaW0gPSBlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYXR0cihlLnRvdGFsT3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RhdHVzID0gK3RvOyAvLyBOYU5cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBhbmltLnBlcmNlbnRzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChhbmltLnBlcmNlbnRzW2ldID09IHBlcmNlbnQgfHwgYW5pbS5wZXJjZW50c1tpXSA+IHN0YXR1cyAqIGFuaW0udG9wKSB7XG4gICAgICAgICAgICAgICAgcGVyY2VudCA9IGFuaW0ucGVyY2VudHNbaV07XG4gICAgICAgICAgICAgICAgcHJldiA9IGFuaW0ucGVyY2VudHNbaSAtIDFdIHx8IDA7XG4gICAgICAgICAgICAgICAgbXMgPSBtcyAvIGFuaW0udG9wICogKHBlcmNlbnQgLSBwcmV2KTtcbiAgICAgICAgICAgICAgICBuZXh0ID0gYW5pbS5wZXJjZW50c1tpICsgMV07XG4gICAgICAgICAgICAgICAgcGFyYW1zID0gYW5pbS5hbmltW3BlcmNlbnRdO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0dXMpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmF0dHIoYW5pbS5hbmltW2FuaW0ucGVyY2VudHNbaV1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIXBhcmFtcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNJbkFuaW0pIHtcbiAgICAgICAgICAgIGZvciAodmFyIGF0dHIgaW4gcGFyYW1zKSBpZiAocGFyYW1zW2hhc10oYXR0cikpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXZhaWxhYmxlQW5pbUF0dHJzW2hhc10oYXR0cikgfHwgZWxlbWVudC5wYXBlci5jdXN0b21BdHRyaWJ1dGVzW2hhc10oYXR0cikpIHtcbiAgICAgICAgICAgICAgICAgICAgZnJvbVthdHRyXSA9IGVsZW1lbnQuYXR0cihhdHRyKTtcbiAgICAgICAgICAgICAgICAgICAgKGZyb21bYXR0cl0gPT0gbnVsbCkgJiYgKGZyb21bYXR0cl0gPSBhdmFpbGFibGVBdHRyc1thdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgIHRvW2F0dHJdID0gcGFyYW1zW2F0dHJdO1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGF2YWlsYWJsZUFuaW1BdHRyc1thdHRyXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBudTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdID0gKHRvW2F0dHJdIC0gZnJvbVthdHRyXSkgLyBtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJjb2xvdXJcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tW2F0dHJdID0gUi5nZXRSR0IoZnJvbVthdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRvQ29sb3VyID0gUi5nZXRSR0IodG9bYXR0cl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHI6ICh0b0NvbG91ci5yIC0gZnJvbVthdHRyXS5yKSAvIG1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnOiAodG9Db2xvdXIuZyAtIGZyb21bYXR0cl0uZykgLyBtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjogKHRvQ29sb3VyLmIgLSBmcm9tW2F0dHJdLmIpIC8gbXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcInBhdGhcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGF0aGVzID0gcGF0aDJjdXJ2ZShmcm9tW2F0dHJdLCB0b1thdHRyXSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvUGF0aCA9IHBhdGhlc1sxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tW2F0dHJdID0gcGF0aGVzWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IGZyb21bYXR0cl0ubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdW2ldID0gWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMSwgamogPSBmcm9tW2F0dHJdW2ldLmxlbmd0aDsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl1baV1bal0gPSAodG9QYXRoW2ldW2pdIC0gZnJvbVthdHRyXVtpXVtqXSkgLyBtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ0cmFuc2Zvcm1cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgXyA9IGVsZW1lbnQuXyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXEgPSBlcXVhbGlzZVRyYW5zZm9ybShfW2F0dHJdLCB0b1thdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21bYXR0cl0gPSBlcS5mcm9tO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1thdHRyXSA9IGVxLnRvO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0ucmVhbCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGlpID0gZnJvbVthdHRyXS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdW2ldID0gW2Zyb21bYXR0cl1baV1bMF1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMSwgamogPSBmcm9tW2F0dHJdW2ldLmxlbmd0aDsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdW2ldW2pdID0gKHRvW2F0dHJdW2ldW2pdIC0gZnJvbVthdHRyXVtpXVtqXSkgLyBtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtID0gKGVsZW1lbnQubWF0cml4IHx8IG5ldyBNYXRyaXgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8yID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF86IHt0cmFuc2Zvcm06IF8udHJhbnNmb3JtfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRCQm94OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmdldEJCb3goMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVthdHRyXSA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uYSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uYixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uZlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYWN0VHJhbnNmb3JtKHRvMiwgdG9bYXR0cl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1thdHRyXSA9IHRvMi5fLnRyYW5zZm9ybTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlmZlthdHRyXSA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0bzIubWF0cml4LmEgLSBtLmEpIC8gbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodG8yLm1hdHJpeC5iIC0gbS5iKSAvIG1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRvMi5tYXRyaXguYyAtIG0uYykgLyBtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0bzIubWF0cml4LmQgLSBtLmQpIC8gbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodG8yLm1hdHJpeC5lIC0gbS5lKSAvIG1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRvMi5tYXRyaXguZiAtIG0uZikgLyBtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmcm9tW2F0dHJdID0gW18uc3gsIF8uc3ksIF8uZGVnLCBfLmR4LCBfLmR5XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFyIHRvMiA9IHtfOnt9LCBnZXRCQm94OiBmdW5jdGlvbiAoKSB7IHJldHVybiBlbGVtZW50LmdldEJCb3goKTsgfX07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhY3RUcmFuc2Zvcm0odG8yLCB0b1thdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpZmZbYXR0cl0gPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAodG8yLl8uc3ggLSBfLnN4KSAvIG1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgKHRvMi5fLnN5IC0gXy5zeSkgLyBtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICh0bzIuXy5kZWcgLSBfLmRlZykgLyBtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICh0bzIuXy5keCAtIF8uZHgpIC8gbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAodG8yLl8uZHkgLSBfLmR5KSAvIG1zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcImNzdlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBTdHIocGFyYW1zW2F0dHJdKVtzcGxpdF0oc2VwYXJhdG9yKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbTIgPSBTdHIoZnJvbVthdHRyXSlbc3BsaXRdKHNlcGFyYXRvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHIgPT0gXCJjbGlwLXJlY3RcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tW2F0dHJdID0gZnJvbTI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9IGZyb20yLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlmZlthdHRyXVtpXSA9ICh2YWx1ZXNbaV0gLSBmcm9tW2F0dHJdW2ldKSAvIG1zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvW2F0dHJdID0gdmFsdWVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBbXVtjb25jYXRdKHBhcmFtc1thdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbTIgPSBbXVtjb25jYXRdKGZyb21bYXR0cl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID0gZWxlbWVudC5wYXBlci5jdXN0b21BdHRyaWJ1dGVzW2F0dHJdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl1baV0gPSAoKHZhbHVlc1tpXSB8fCAwKSAtIChmcm9tMltpXSB8fCAwKSkgLyBtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZWFzaW5nID0gcGFyYW1zLmVhc2luZyxcbiAgICAgICAgICAgICAgICBlYXN5ZWFzeSA9IFIuZWFzaW5nX2Zvcm11bGFzW2Vhc2luZ107XG4gICAgICAgICAgICBpZiAoIWVhc3llYXN5KSB7XG4gICAgICAgICAgICAgICAgZWFzeWVhc3kgPSBTdHIoZWFzaW5nKS5tYXRjaChiZXppZXJyZyk7XG4gICAgICAgICAgICAgICAgaWYgKGVhc3llYXN5ICYmIGVhc3llYXN5Lmxlbmd0aCA9PSA1KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJ2ZSA9IGVhc3llYXN5O1xuICAgICAgICAgICAgICAgICAgICBlYXN5ZWFzeSA9IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ3ViaWNCZXppZXJBdFRpbWUodCwgK2N1cnZlWzFdLCArY3VydmVbMl0sICtjdXJ2ZVszXSwgK2N1cnZlWzRdLCBtcyk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZWFzeWVhc3kgPSBwaXBlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRpbWVzdGFtcCA9IHBhcmFtcy5zdGFydCB8fCBhbmltLnN0YXJ0IHx8ICtuZXcgRGF0ZTtcbiAgICAgICAgICAgIGUgPSB7XG4gICAgICAgICAgICAgICAgYW5pbTogYW5pbSxcbiAgICAgICAgICAgICAgICBwZXJjZW50OiBwZXJjZW50LFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxuICAgICAgICAgICAgICAgIHN0YXJ0OiB0aW1lc3RhbXAgKyAoYW5pbS5kZWwgfHwgMCksXG4gICAgICAgICAgICAgICAgc3RhdHVzOiAwLFxuICAgICAgICAgICAgICAgIGluaXRzdGF0dXM6IHN0YXR1cyB8fCAwLFxuICAgICAgICAgICAgICAgIHN0b3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1zOiBtcyxcbiAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc3llYXN5LFxuICAgICAgICAgICAgICAgIGZyb206IGZyb20sXG4gICAgICAgICAgICAgICAgZGlmZjogZGlmZixcbiAgICAgICAgICAgICAgICB0bzogdG8sXG4gICAgICAgICAgICAgICAgZWw6IGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6IHBhcmFtcy5jYWxsYmFjayxcbiAgICAgICAgICAgICAgICBwcmV2OiBwcmV2LFxuICAgICAgICAgICAgICAgIG5leHQ6IG5leHQsXG4gICAgICAgICAgICAgICAgcmVwZWF0OiB0aW1lcyB8fCBhbmltLnRpbWVzLFxuICAgICAgICAgICAgICAgIG9yaWdpbjogZWxlbWVudC5hdHRyKCksXG4gICAgICAgICAgICAgICAgdG90YWxPcmlnaW46IHRvdGFsT3JpZ2luXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHMucHVzaChlKTtcbiAgICAgICAgICAgIGlmIChzdGF0dXMgJiYgIWlzSW5BbmltICYmICFpc0luQW5pbVNldCkge1xuICAgICAgICAgICAgICAgIGUuc3RvcCA9IHRydWU7XG4gICAgICAgICAgICAgICAgZS5zdGFydCA9IG5ldyBEYXRlIC0gbXMgKiBzdGF0dXM7XG4gICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbkVsZW1lbnRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmltYXRpb24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNJbkFuaW1TZXQpIHtcbiAgICAgICAgICAgICAgICBlLnN0YXJ0ID0gbmV3IERhdGUgLSBlLm1zICogc3RhdHVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoID09IDEgJiYgcmVxdWVzdEFuaW1GcmFtZShhbmltYXRpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaXNJbkFuaW0uaW5pdHN0YXR1cyA9IHN0YXR1cztcbiAgICAgICAgICAgIGlzSW5BbmltLnN0YXJ0ID0gbmV3IERhdGUgLSBpc0luQW5pbS5tcyAqIHN0YXR1cztcbiAgICAgICAgfVxuICAgICAgICBldmUoXCJyYXBoYWVsLmFuaW0uc3RhcnQuXCIgKyBlbGVtZW50LmlkLCBlbGVtZW50LCBhbmltKTtcbiAgICB9XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuYW5pbWF0aW9uXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIGFuIGFuaW1hdGlvbiBvYmplY3QgdGhhdCBjYW4gYmUgcGFzc2VkIHRvIHRoZSBARWxlbWVudC5hbmltYXRlIG9yIEBFbGVtZW50LmFuaW1hdGVXaXRoIG1ldGhvZHMuXG4gICAgICogU2VlIGFsc28gQEFuaW1hdGlvbi5kZWxheSBhbmQgQEFuaW1hdGlvbi5yZXBlYXQgbWV0aG9kcy5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gcGFyYW1zIChvYmplY3QpIGZpbmFsIGF0dHJpYnV0ZXMgZm9yIHRoZSBlbGVtZW50LCBzZWUgYWxzbyBARWxlbWVudC5hdHRyXG4gICAgIC0gbXMgKG51bWJlcikgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBmb3IgYW5pbWF0aW9uIHRvIHJ1blxuICAgICAtIGVhc2luZyAoc3RyaW5nKSAjb3B0aW9uYWwgZWFzaW5nIHR5cGUuIEFjY2VwdCBvbmUgb2YgQFJhcGhhZWwuZWFzaW5nX2Zvcm11bGFzIG9yIENTUyBmb3JtYXQ6IGBjdWJpYyYjeDIwMTA7YmV6aWVyKFhYLCYjMTYwO1hYLCYjMTYwO1hYLCYjMTYwO1hYKWBcbiAgICAgLSBjYWxsYmFjayAoZnVuY3Rpb24pICNvcHRpb25hbCBjYWxsYmFjayBmdW5jdGlvbi4gV2lsbCBiZSBjYWxsZWQgYXQgdGhlIGVuZCBvZiBhbmltYXRpb24uXG4gICAgICoqXG4gICAgID0gKG9iamVjdCkgQEFuaW1hdGlvblxuICAgIFxcKi9cbiAgICBSLmFuaW1hdGlvbiA9IGZ1bmN0aW9uIChwYXJhbXMsIG1zLCBlYXNpbmcsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChwYXJhbXMgaW5zdGFuY2VvZiBBbmltYXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJhbXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFIuaXMoZWFzaW5nLCBcImZ1bmN0aW9uXCIpIHx8ICFlYXNpbmcpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZWFzaW5nIHx8IG51bGw7XG4gICAgICAgICAgICBlYXNpbmcgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHBhcmFtcyA9IE9iamVjdChwYXJhbXMpO1xuICAgICAgICBtcyA9ICttcyB8fCAwO1xuICAgICAgICB2YXIgcCA9IHt9LFxuICAgICAgICAgICAganNvbixcbiAgICAgICAgICAgIGF0dHI7XG4gICAgICAgIGZvciAoYXR0ciBpbiBwYXJhbXMpIGlmIChwYXJhbXNbaGFzXShhdHRyKSAmJiB0b0Zsb2F0KGF0dHIpICE9IGF0dHIgJiYgdG9GbG9hdChhdHRyKSArIFwiJVwiICE9IGF0dHIpIHtcbiAgICAgICAgICAgIGpzb24gPSB0cnVlO1xuICAgICAgICAgICAgcFthdHRyXSA9IHBhcmFtc1thdHRyXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWpzb24pIHtcbiAgICAgICAgICAgIC8vIGlmIHBlcmNlbnQtbGlrZSBzeW50YXggaXMgdXNlZCBhbmQgZW5kLW9mLWFsbCBhbmltYXRpb24gY2FsbGJhY2sgdXNlZFxuICAgICAgICAgICAgaWYoY2FsbGJhY2spe1xuICAgICAgICAgICAgICAgIC8vIGZpbmQgdGhlIGxhc3Qgb25lXG4gICAgICAgICAgICAgICAgdmFyIGxhc3RLZXkgPSAwO1xuICAgICAgICAgICAgICAgIGZvcih2YXIgaSBpbiBwYXJhbXMpe1xuICAgICAgICAgICAgICAgICAgICB2YXIgcGVyY2VudCA9IHRvSW50KGkpO1xuICAgICAgICAgICAgICAgICAgICBpZihwYXJhbXNbaGFzXShpKSAmJiBwZXJjZW50ID4gbGFzdEtleSl7XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0S2V5ID0gcGVyY2VudDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsYXN0S2V5ICs9ICclJztcbiAgICAgICAgICAgICAgICAvLyBpZiBhbHJlYWR5IGRlZmluZWQgY2FsbGJhY2sgaW4gdGhlIGxhc3Qga2V5ZnJhbWUsIHNraXBcbiAgICAgICAgICAgICAgICAhcGFyYW1zW2xhc3RLZXldLmNhbGxiYWNrICYmIChwYXJhbXNbbGFzdEtleV0uY2FsbGJhY2sgPSBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBBbmltYXRpb24ocGFyYW1zLCBtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlYXNpbmcgJiYgKHAuZWFzaW5nID0gZWFzaW5nKTtcbiAgICAgICAgICAgIGNhbGxiYWNrICYmIChwLmNhbGxiYWNrID0gY2FsbGJhY2spO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBBbmltYXRpb24oezEwMDogcH0sIG1zKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuYW5pbWF0ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ3JlYXRlcyBhbmQgc3RhcnRzIGFuaW1hdGlvbiBmb3IgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gcGFyYW1zIChvYmplY3QpIGZpbmFsIGF0dHJpYnV0ZXMgZm9yIHRoZSBlbGVtZW50LCBzZWUgYWxzbyBARWxlbWVudC5hdHRyXG4gICAgIC0gbXMgKG51bWJlcikgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBmb3IgYW5pbWF0aW9uIHRvIHJ1blxuICAgICAtIGVhc2luZyAoc3RyaW5nKSAjb3B0aW9uYWwgZWFzaW5nIHR5cGUuIEFjY2VwdCBvbmUgb2YgQFJhcGhhZWwuZWFzaW5nX2Zvcm11bGFzIG9yIENTUyBmb3JtYXQ6IGBjdWJpYyYjeDIwMTA7YmV6aWVyKFhYLCYjMTYwO1hYLCYjMTYwO1hYLCYjMTYwO1hYKWBcbiAgICAgLSBjYWxsYmFjayAoZnVuY3Rpb24pICNvcHRpb25hbCBjYWxsYmFjayBmdW5jdGlvbi4gV2lsbCBiZSBjYWxsZWQgYXQgdGhlIGVuZCBvZiBhbmltYXRpb24uXG4gICAgICogb3JcbiAgICAgLSBhbmltYXRpb24gKG9iamVjdCkgYW5pbWF0aW9uIG9iamVjdCwgc2VlIEBSYXBoYWVsLmFuaW1hdGlvblxuICAgICAqKlxuICAgICA9IChvYmplY3QpIG9yaWdpbmFsIGVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5hbmltYXRlID0gZnVuY3Rpb24gKHBhcmFtcywgbXMsIGVhc2luZywgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzO1xuICAgICAgICBpZiAoZWxlbWVudC5yZW1vdmVkKSB7XG4gICAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjay5jYWxsKGVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFuaW0gPSBwYXJhbXMgaW5zdGFuY2VvZiBBbmltYXRpb24gPyBwYXJhbXMgOiBSLmFuaW1hdGlvbihwYXJhbXMsIG1zLCBlYXNpbmcsIGNhbGxiYWNrKTtcbiAgICAgICAgcnVuQW5pbWF0aW9uKGFuaW0sIGVsZW1lbnQsIGFuaW0ucGVyY2VudHNbMF0sIG51bGwsIGVsZW1lbnQuYXR0cigpKTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5zZXRUaW1lXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTZXRzIHRoZSBzdGF0dXMgb2YgYW5pbWF0aW9uIG9mIHRoZSBlbGVtZW50IGluIG1pbGxpc2Vjb25kcy4gU2ltaWxhciB0byBARWxlbWVudC5zdGF0dXMgbWV0aG9kLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBhbmltIChvYmplY3QpIGFuaW1hdGlvbiBvYmplY3RcbiAgICAgLSB2YWx1ZSAobnVtYmVyKSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgYW5pbWF0aW9uXG4gICAgICoqXG4gICAgID0gKG9iamVjdCkgb3JpZ2luYWwgZWxlbWVudCBpZiBgdmFsdWVgIGlzIHNwZWNpZmllZFxuICAgICAqIE5vdGUsIHRoYXQgZHVyaW5nIGFuaW1hdGlvbiBmb2xsb3dpbmcgZXZlbnRzIGFyZSB0cmlnZ2VyZWQ6XG4gICAgICpcbiAgICAgKiBPbiBlYWNoIGFuaW1hdGlvbiBmcmFtZSBldmVudCBgYW5pbS5mcmFtZS48aWQ+YCwgb24gc3RhcnQgYGFuaW0uc3RhcnQuPGlkPmAgYW5kIG9uIGVuZCBgYW5pbS5maW5pc2guPGlkPmAuXG4gICAgXFwqL1xuICAgIGVscHJvdG8uc2V0VGltZSA9IGZ1bmN0aW9uIChhbmltLCB2YWx1ZSkge1xuICAgICAgICBpZiAoYW5pbSAmJiB2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXR1cyhhbmltLCBtbWluKHZhbHVlLCBhbmltLm1zKSAvIGFuaW0ubXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuc3RhdHVzXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBHZXRzIG9yIHNldHMgdGhlIHN0YXR1cyBvZiBhbmltYXRpb24gb2YgdGhlIGVsZW1lbnQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGFuaW0gKG9iamVjdCkgI29wdGlvbmFsIGFuaW1hdGlvbiBvYmplY3RcbiAgICAgLSB2YWx1ZSAobnVtYmVyKSAjb3B0aW9uYWwgMCDigJMgMS4gSWYgc3BlY2lmaWVkLCBtZXRob2Qgd29ya3MgbGlrZSBhIHNldHRlciBhbmQgc2V0cyB0aGUgc3RhdHVzIG9mIGEgZ2l2ZW4gYW5pbWF0aW9uIHRvIHRoZSB2YWx1ZS4gVGhpcyB3aWxsIGNhdXNlIGFuaW1hdGlvbiB0byBqdW1wIHRvIHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgICAgKipcbiAgICAgPSAobnVtYmVyKSBzdGF0dXNcbiAgICAgKiBvclxuICAgICA9IChhcnJheSkgc3RhdHVzIGlmIGBhbmltYCBpcyBub3Qgc3BlY2lmaWVkLiBBcnJheSBvZiBvYmplY3RzIGluIGZvcm1hdDpcbiAgICAgbyB7XG4gICAgIG8gICAgIGFuaW06IChvYmplY3QpIGFuaW1hdGlvbiBvYmplY3RcbiAgICAgbyAgICAgc3RhdHVzOiAobnVtYmVyKSBzdGF0dXNcbiAgICAgbyB9XG4gICAgICogb3JcbiAgICAgPSAob2JqZWN0KSBvcmlnaW5hbCBlbGVtZW50IGlmIGB2YWx1ZWAgaXMgc3BlY2lmaWVkXG4gICAgXFwqL1xuICAgIGVscHJvdG8uc3RhdHVzID0gZnVuY3Rpb24gKGFuaW0sIHZhbHVlKSB7XG4gICAgICAgIHZhciBvdXQgPSBbXSxcbiAgICAgICAgICAgIGkgPSAwLFxuICAgICAgICAgICAgbGVuLFxuICAgICAgICAgICAgZTtcbiAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJ1bkFuaW1hdGlvbihhbmltLCB0aGlzLCAtMSwgbW1pbih2YWx1ZSwgMSkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZW4gPSBhbmltYXRpb25FbGVtZW50cy5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZSA9IGFuaW1hdGlvbkVsZW1lbnRzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChlLmVsLmlkID09IHRoaXMuaWQgJiYgKCFhbmltIHx8IGUuYW5pbSA9PSBhbmltKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5pbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGUuc3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG91dC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuaW06IGUuYW5pbSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogZS5zdGF0dXNcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFuaW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvdXQ7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnBhdXNlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTdG9wcyBhbmltYXRpb24gb2YgdGhlIGVsZW1lbnQgd2l0aCBhYmlsaXR5IHRvIHJlc3VtZSBpdCBsYXRlciBvbi5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gYW5pbSAob2JqZWN0KSAjb3B0aW9uYWwgYW5pbWF0aW9uIG9iamVjdFxuICAgICAqKlxuICAgICA9IChvYmplY3QpIG9yaWdpbmFsIGVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5wYXVzZSA9IGZ1bmN0aW9uIChhbmltKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoOyBpKyspIGlmIChhbmltYXRpb25FbGVtZW50c1tpXS5lbC5pZCA9PSB0aGlzLmlkICYmICghYW5pbSB8fCBhbmltYXRpb25FbGVtZW50c1tpXS5hbmltID09IGFuaW0pKSB7XG4gICAgICAgICAgICBpZiAoZXZlKFwicmFwaGFlbC5hbmltLnBhdXNlLlwiICsgdGhpcy5pZCwgdGhpcywgYW5pbWF0aW9uRWxlbWVudHNbaV0uYW5pbSkgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHNbaV0ucGF1c2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnJlc3VtZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVzdW1lcyBhbmltYXRpb24gaWYgaXQgd2FzIHBhdXNlZCB3aXRoIEBFbGVtZW50LnBhdXNlIG1ldGhvZC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gYW5pbSAob2JqZWN0KSAjb3B0aW9uYWwgYW5pbWF0aW9uIG9iamVjdFxuICAgICAqKlxuICAgICA9IChvYmplY3QpIG9yaWdpbmFsIGVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5yZXN1bWUgPSBmdW5jdGlvbiAoYW5pbSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFuaW1hdGlvbkVsZW1lbnRzLmxlbmd0aDsgaSsrKSBpZiAoYW5pbWF0aW9uRWxlbWVudHNbaV0uZWwuaWQgPT0gdGhpcy5pZCAmJiAoIWFuaW0gfHwgYW5pbWF0aW9uRWxlbWVudHNbaV0uYW5pbSA9PSBhbmltKSkge1xuICAgICAgICAgICAgdmFyIGUgPSBhbmltYXRpb25FbGVtZW50c1tpXTtcbiAgICAgICAgICAgIGlmIChldmUoXCJyYXBoYWVsLmFuaW0ucmVzdW1lLlwiICsgdGhpcy5pZCwgdGhpcywgZS5hbmltKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgZS5wYXVzZWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0dXMoZS5hbmltLCBlLnN0YXR1cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5zdG9wXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTdG9wcyBhbmltYXRpb24gb2YgdGhlIGVsZW1lbnQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGFuaW0gKG9iamVjdCkgI29wdGlvbmFsIGFuaW1hdGlvbiBvYmplY3RcbiAgICAgKipcbiAgICAgPSAob2JqZWN0KSBvcmlnaW5hbCBlbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8uc3RvcCA9IGZ1bmN0aW9uIChhbmltKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoOyBpKyspIGlmIChhbmltYXRpb25FbGVtZW50c1tpXS5lbC5pZCA9PSB0aGlzLmlkICYmICghYW5pbSB8fCBhbmltYXRpb25FbGVtZW50c1tpXS5hbmltID09IGFuaW0pKSB7XG4gICAgICAgICAgICBpZiAoZXZlKFwicmFwaGFlbC5hbmltLnN0b3AuXCIgKyB0aGlzLmlkLCB0aGlzLCBhbmltYXRpb25FbGVtZW50c1tpXS5hbmltKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25FbGVtZW50cy5zcGxpY2UoaS0tLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIGZ1bmN0aW9uIHN0b3BBbmltYXRpb24ocGFwZXIpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbmltYXRpb25FbGVtZW50cy5sZW5ndGg7IGkrKykgaWYgKGFuaW1hdGlvbkVsZW1lbnRzW2ldLmVsLnBhcGVyID09IHBhcGVyKSB7XG4gICAgICAgICAgICBhbmltYXRpb25FbGVtZW50cy5zcGxpY2UoaS0tLCAxKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBldmUub24oXCJyYXBoYWVsLnJlbW92ZVwiLCBzdG9wQW5pbWF0aW9uKTtcbiAgICBldmUub24oXCJyYXBoYWVsLmNsZWFyXCIsIHN0b3BBbmltYXRpb24pO1xuICAgIGVscHJvdG8udG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBcIlJhcGhhXFx4ZWJsXFx1MjAxOXMgb2JqZWN0XCI7XG4gICAgfTtcblxuICAgIC8vIFNldFxuICAgIHZhciBTZXQgPSBmdW5jdGlvbiAoaXRlbXMpIHtcbiAgICAgICAgdGhpcy5pdGVtcyA9IFtdO1xuICAgICAgICB0aGlzLmxlbmd0aCA9IDA7XG4gICAgICAgIHRoaXMudHlwZSA9IFwic2V0XCI7XG4gICAgICAgIGlmIChpdGVtcykge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gaXRlbXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpdGVtc1tpXSAmJiAoaXRlbXNbaV0uY29uc3RydWN0b3IgPT0gZWxwcm90by5jb25zdHJ1Y3RvciB8fCBpdGVtc1tpXS5jb25zdHJ1Y3RvciA9PSBTZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbdGhpcy5pdGVtcy5sZW5ndGhdID0gdGhpcy5pdGVtc1t0aGlzLml0ZW1zLmxlbmd0aF0gPSBpdGVtc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHNldHByb3RvID0gU2V0LnByb3RvdHlwZTtcbiAgICAvKlxcXG4gICAgICogU2V0LnB1c2hcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEFkZHMgZWFjaCBhcmd1bWVudCB0byB0aGUgY3VycmVudCBzZXQuXG4gICAgID0gKG9iamVjdCkgb3JpZ2luYWwgZWxlbWVudFxuICAgIFxcKi9cbiAgICBzZXRwcm90by5wdXNoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaXRlbSxcbiAgICAgICAgICAgIGxlbjtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgIGl0ZW0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICBpZiAoaXRlbSAmJiAoaXRlbS5jb25zdHJ1Y3RvciA9PSBlbHByb3RvLmNvbnN0cnVjdG9yIHx8IGl0ZW0uY29uc3RydWN0b3IgPT0gU2V0KSkge1xuICAgICAgICAgICAgICAgIGxlbiA9IHRoaXMuaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHRoaXNbbGVuXSA9IHRoaXMuaXRlbXNbbGVuXSA9IGl0ZW07XG4gICAgICAgICAgICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBTZXQucG9wXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZW1vdmVzIGxhc3QgZWxlbWVudCBhbmQgcmV0dXJucyBpdC5cbiAgICAgPSAob2JqZWN0KSBlbGVtZW50XG4gICAgXFwqL1xuICAgIHNldHByb3RvLnBvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5sZW5ndGggJiYgZGVsZXRlIHRoaXNbdGhpcy5sZW5ndGgtLV07XG4gICAgICAgIHJldHVybiB0aGlzLml0ZW1zLnBvcCgpO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFNldC5mb3JFYWNoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBFeGVjdXRlcyBnaXZlbiBmdW5jdGlvbiBmb3IgZWFjaCBlbGVtZW50IGluIHRoZSBzZXQuXG4gICAgICpcbiAgICAgKiBJZiBmdW5jdGlvbiByZXR1cm5zIGBmYWxzZWAgaXQgd2lsbCBzdG9wIGxvb3AgcnVubmluZy5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gY2FsbGJhY2sgKGZ1bmN0aW9uKSBmdW5jdGlvbiB0byBydW5cbiAgICAgLSB0aGlzQXJnIChvYmplY3QpIGNvbnRleHQgb2JqZWN0IGZvciB0aGUgY2FsbGJhY2tcbiAgICAgPSAob2JqZWN0KSBTZXQgb2JqZWN0XG4gICAgXFwqL1xuICAgIHNldHByb3RvLmZvckVhY2ggPSBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5pdGVtcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB0aGlzLml0ZW1zW2ldLCBpKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIGZvciAodmFyIG1ldGhvZCBpbiBlbHByb3RvKSBpZiAoZWxwcm90b1toYXNdKG1ldGhvZCkpIHtcbiAgICAgICAgc2V0cHJvdG9bbWV0aG9kXSA9IChmdW5jdGlvbiAobWV0aG9kbmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXJnID0gYXJndW1lbnRzO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsW21ldGhvZG5hbWVdW2FwcGx5XShlbCwgYXJnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG1ldGhvZCk7XG4gICAgfVxuICAgIHNldHByb3RvLmF0dHIgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKG5hbWUgJiYgUi5pcyhuYW1lLCBhcnJheSkgJiYgUi5pcyhuYW1lWzBdLCBcIm9iamVjdFwiKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gbmFtZS5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtc1tqXS5hdHRyKG5hbWVbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5pdGVtcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtc1tpXS5hdHRyKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBTZXQuY2xlYXJcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhlIHNldFxuICAgIFxcKi9cbiAgICBzZXRwcm90by5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2hpbGUgKHRoaXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnBvcCgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogU2V0LnNwbGljZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBnaXZlbiBlbGVtZW50IGZyb20gdGhlIHNldFxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBpbmRleCAobnVtYmVyKSBwb3NpdGlvbiBvZiB0aGUgZGVsZXRpb25cbiAgICAgLSBjb3VudCAobnVtYmVyKSBudW1iZXIgb2YgZWxlbWVudCB0byByZW1vdmVcbiAgICAgLSBpbnNlcnRpb27igKYgKG9iamVjdCkgI29wdGlvbmFsIGVsZW1lbnRzIHRvIGluc2VydFxuICAgICA9IChvYmplY3QpIHNldCBlbGVtZW50cyB0aGF0IHdlcmUgZGVsZXRlZFxuICAgIFxcKi9cbiAgICBzZXRwcm90by5zcGxpY2UgPSBmdW5jdGlvbiAoaW5kZXgsIGNvdW50LCBpbnNlcnRpb24pIHtcbiAgICAgICAgaW5kZXggPSBpbmRleCA8IDAgPyBtbWF4KHRoaXMubGVuZ3RoICsgaW5kZXgsIDApIDogaW5kZXg7XG4gICAgICAgIGNvdW50ID0gbW1heCgwLCBtbWluKHRoaXMubGVuZ3RoIC0gaW5kZXgsIGNvdW50KSk7XG4gICAgICAgIHZhciB0YWlsID0gW10sXG4gICAgICAgICAgICB0b2RlbCA9IFtdLFxuICAgICAgICAgICAgYXJncyA9IFtdLFxuICAgICAgICAgICAgaTtcbiAgICAgICAgZm9yIChpID0gMjsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgIHRvZGVsLnB1c2godGhpc1tpbmRleCArIGldKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKDsgaSA8IHRoaXMubGVuZ3RoIC0gaW5kZXg7IGkrKykge1xuICAgICAgICAgICAgdGFpbC5wdXNoKHRoaXNbaW5kZXggKyBpXSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFyZ2xlbiA9IGFyZ3MubGVuZ3RoO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXJnbGVuICsgdGFpbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5pdGVtc1tpbmRleCArIGldID0gdGhpc1tpbmRleCArIGldID0gaSA8IGFyZ2xlbiA/IGFyZ3NbaV0gOiB0YWlsW2kgLSBhcmdsZW5dO1xuICAgICAgICB9XG4gICAgICAgIGkgPSB0aGlzLml0ZW1zLmxlbmd0aCA9IHRoaXMubGVuZ3RoIC09IGNvdW50IC0gYXJnbGVuO1xuICAgICAgICB3aGlsZSAodGhpc1tpXSkge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXNbaSsrXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFNldCh0b2RlbCk7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogU2V0LmV4Y2x1ZGVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZ2l2ZW4gZWxlbWVudCBmcm9tIHRoZSBzZXRcbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gZWxlbWVudCAob2JqZWN0KSBlbGVtZW50IHRvIHJlbW92ZVxuICAgICA9IChib29sZWFuKSBgdHJ1ZWAgaWYgb2JqZWN0IHdhcyBmb3VuZCAmIHJlbW92ZWQgZnJvbSB0aGUgc2V0XG4gICAgXFwqL1xuICAgIHNldHByb3RvLmV4Y2x1ZGUgPSBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSBpZiAodGhpc1tpXSA9PSBlbCkge1xuICAgICAgICAgICAgdGhpcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgc2V0cHJvdG8uYW5pbWF0ZSA9IGZ1bmN0aW9uIChwYXJhbXMsIG1zLCBlYXNpbmcsIGNhbGxiYWNrKSB7XG4gICAgICAgIChSLmlzKGVhc2luZywgXCJmdW5jdGlvblwiKSB8fCAhZWFzaW5nKSAmJiAoY2FsbGJhY2sgPSBlYXNpbmcgfHwgbnVsbCk7XG4gICAgICAgIHZhciBsZW4gPSB0aGlzLml0ZW1zLmxlbmd0aCxcbiAgICAgICAgICAgIGkgPSBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgc2V0ID0gdGhpcyxcbiAgICAgICAgICAgIGNvbGxlY3RvcjtcbiAgICAgICAgaWYgKCFsZW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIGNhbGxiYWNrICYmIChjb2xsZWN0b3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAhLS1sZW4gJiYgY2FsbGJhY2suY2FsbChzZXQpO1xuICAgICAgICB9KTtcbiAgICAgICAgZWFzaW5nID0gUi5pcyhlYXNpbmcsIHN0cmluZykgPyBlYXNpbmcgOiBjb2xsZWN0b3I7XG4gICAgICAgIHZhciBhbmltID0gUi5hbmltYXRpb24ocGFyYW1zLCBtcywgZWFzaW5nLCBjb2xsZWN0b3IpO1xuICAgICAgICBpdGVtID0gdGhpcy5pdGVtc1stLWldLmFuaW1hdGUoYW5pbSk7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIHRoaXMuaXRlbXNbaV0gJiYgIXRoaXMuaXRlbXNbaV0ucmVtb3ZlZCAmJiB0aGlzLml0ZW1zW2ldLmFuaW1hdGVXaXRoKGl0ZW0sIGFuaW0sIGFuaW0pO1xuICAgICAgICAgICAgKHRoaXMuaXRlbXNbaV0gJiYgIXRoaXMuaXRlbXNbaV0ucmVtb3ZlZCkgfHwgbGVuLS07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBzZXRwcm90by5pbnNlcnRBZnRlciA9IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICB2YXIgaSA9IHRoaXMuaXRlbXMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICB0aGlzLml0ZW1zW2ldLmluc2VydEFmdGVyKGVsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIHNldHByb3RvLmdldEJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB4ID0gW10sXG4gICAgICAgICAgICB5ID0gW10sXG4gICAgICAgICAgICB4MiA9IFtdLFxuICAgICAgICAgICAgeTIgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMuaXRlbXMubGVuZ3RoOyBpLS07KSBpZiAoIXRoaXMuaXRlbXNbaV0ucmVtb3ZlZCkge1xuICAgICAgICAgICAgdmFyIGJveCA9IHRoaXMuaXRlbXNbaV0uZ2V0QkJveCgpO1xuICAgICAgICAgICAgeC5wdXNoKGJveC54KTtcbiAgICAgICAgICAgIHkucHVzaChib3gueSk7XG4gICAgICAgICAgICB4Mi5wdXNoKGJveC54ICsgYm94LndpZHRoKTtcbiAgICAgICAgICAgIHkyLnB1c2goYm94LnkgKyBib3guaGVpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICB4ID0gbW1pblthcHBseV0oMCwgeCk7XG4gICAgICAgIHkgPSBtbWluW2FwcGx5XSgwLCB5KTtcbiAgICAgICAgeDIgPSBtbWF4W2FwcGx5XSgwLCB4Mik7XG4gICAgICAgIHkyID0gbW1heFthcHBseV0oMCwgeTIpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICB4MjogeDIsXG4gICAgICAgICAgICB5MjogeTIsXG4gICAgICAgICAgICB3aWR0aDogeDIgLSB4LFxuICAgICAgICAgICAgaGVpZ2h0OiB5MiAtIHlcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHNldHByb3RvLmNsb25lID0gZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgcyA9IHRoaXMucGFwZXIuc2V0KCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMuaXRlbXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgcy5wdXNoKHRoaXMuaXRlbXNbaV0uY2xvbmUoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfTtcbiAgICBzZXRwcm90by50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFwiUmFwaGFcXHhlYmxcXHUyMDE4cyBzZXRcIjtcbiAgICB9O1xuXG4gICAgc2V0cHJvdG8uZ2xvdyA9IGZ1bmN0aW9uKGdsb3dDb25maWcpIHtcbiAgICAgICAgdmFyIHJldCA9IHRoaXMucGFwZXIuc2V0KCk7XG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbihzaGFwZSwgaW5kZXgpe1xuICAgICAgICAgICAgdmFyIGcgPSBzaGFwZS5nbG93KGdsb3dDb25maWcpO1xuICAgICAgICAgICAgaWYoZyAhPSBudWxsKXtcbiAgICAgICAgICAgICAgICBnLmZvckVhY2goZnVuY3Rpb24oc2hhcGUyLCBpbmRleDIpe1xuICAgICAgICAgICAgICAgICAgICByZXQucHVzaChzaGFwZTIpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9O1xuXG5cbiAgICAvKlxcXG4gICAgICogU2V0LmlzUG9pbnRJbnNpZGVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIERldGVybWluZSBpZiBnaXZlbiBwb2ludCBpcyBpbnNpZGUgdGhpcyBzZXTigJlzIGVsZW1lbnRzXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHggKG51bWJlcikgeCBjb29yZGluYXRlIG9mIHRoZSBwb2ludFxuICAgICAtIHkgKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBwb2ludFxuICAgICA9IChib29sZWFuKSBgdHJ1ZWAgaWYgcG9pbnQgaXMgaW5zaWRlIGFueSBvZiB0aGUgc2V0J3MgZWxlbWVudHNcbiAgICAgXFwqL1xuICAgIHNldHByb3RvLmlzUG9pbnRJbnNpZGUgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICB2YXIgaXNQb2ludEluc2lkZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICBpZiAoZWwuaXNQb2ludEluc2lkZSh4LCB5KSkge1xuICAgICAgICAgICAgICAgIGlzUG9pbnRJbnNpZGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gc3RvcCBsb29wXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gaXNQb2ludEluc2lkZTtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwucmVnaXN0ZXJGb250XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGdpdmVuIGZvbnQgdG8gdGhlIHJlZ2lzdGVyZWQgc2V0IG9mIGZvbnRzIGZvciBSYXBoYcOrbC4gU2hvdWxkIGJlIHVzZWQgYXMgYW4gaW50ZXJuYWwgY2FsbCBmcm9tIHdpdGhpbiBDdWbDs27igJlzIGZvbnQgZmlsZS5cbiAgICAgKiBSZXR1cm5zIG9yaWdpbmFsIHBhcmFtZXRlciwgc28gaXQgY291bGQgYmUgdXNlZCB3aXRoIGNoYWluaW5nLlxuICAgICAjIDxhIGhyZWY9XCJodHRwOi8vd2lraS5naXRodWIuY29tL3NvcmNjdS9jdWZvbi9hYm91dFwiPk1vcmUgYWJvdXQgQ3Vmw7NuIGFuZCBob3cgdG8gY29udmVydCB5b3VyIGZvbnQgZm9ybSBUVEYsIE9URiwgZXRjIHRvIEphdmFTY3JpcHQgZmlsZS48L2E+XG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGZvbnQgKG9iamVjdCkgdGhlIGZvbnQgdG8gcmVnaXN0ZXJcbiAgICAgPSAob2JqZWN0KSB0aGUgZm9udCB5b3UgcGFzc2VkIGluXG4gICAgID4gVXNhZ2VcbiAgICAgfCBDdWZvbi5yZWdpc3RlckZvbnQoUmFwaGFlbC5yZWdpc3RlckZvbnQoe+KApn0pKTtcbiAgICBcXCovXG4gICAgUi5yZWdpc3RlckZvbnQgPSBmdW5jdGlvbiAoZm9udCkge1xuICAgICAgICBpZiAoIWZvbnQuZmFjZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvbnQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb250cyA9IHRoaXMuZm9udHMgfHwge307XG4gICAgICAgIHZhciBmb250Y29weSA9IHtcbiAgICAgICAgICAgICAgICB3OiBmb250LncsXG4gICAgICAgICAgICAgICAgZmFjZToge30sXG4gICAgICAgICAgICAgICAgZ2x5cGhzOiB7fVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZhbWlseSA9IGZvbnQuZmFjZVtcImZvbnQtZmFtaWx5XCJdO1xuICAgICAgICBmb3IgKHZhciBwcm9wIGluIGZvbnQuZmFjZSkgaWYgKGZvbnQuZmFjZVtoYXNdKHByb3ApKSB7XG4gICAgICAgICAgICBmb250Y29weS5mYWNlW3Byb3BdID0gZm9udC5mYWNlW3Byb3BdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmZvbnRzW2ZhbWlseV0pIHtcbiAgICAgICAgICAgIHRoaXMuZm9udHNbZmFtaWx5XS5wdXNoKGZvbnRjb3B5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZm9udHNbZmFtaWx5XSA9IFtmb250Y29weV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFmb250LnN2Zykge1xuICAgICAgICAgICAgZm9udGNvcHkuZmFjZVtcInVuaXRzLXBlci1lbVwiXSA9IHRvSW50KGZvbnQuZmFjZVtcInVuaXRzLXBlci1lbVwiXSwgMTApO1xuICAgICAgICAgICAgZm9yICh2YXIgZ2x5cGggaW4gZm9udC5nbHlwaHMpIGlmIChmb250LmdseXBoc1toYXNdKGdseXBoKSkge1xuICAgICAgICAgICAgICAgIHZhciBwYXRoID0gZm9udC5nbHlwaHNbZ2x5cGhdO1xuICAgICAgICAgICAgICAgIGZvbnRjb3B5LmdseXBoc1tnbHlwaF0gPSB7XG4gICAgICAgICAgICAgICAgICAgIHc6IHBhdGgudyxcbiAgICAgICAgICAgICAgICAgICAgazoge30sXG4gICAgICAgICAgICAgICAgICAgIGQ6IHBhdGguZCAmJiBcIk1cIiArIHBhdGguZC5yZXBsYWNlKC9bbWxjeHRydl0vZywgZnVuY3Rpb24gKGNvbW1hbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge2w6IFwiTFwiLCBjOiBcIkNcIiwgeDogXCJ6XCIsIHQ6IFwibVwiLCByOiBcImxcIiwgdjogXCJjXCJ9W2NvbW1hbmRdIHx8IFwiTVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkgKyBcInpcIlxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHBhdGguaykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrIGluIHBhdGguaykgaWYgKHBhdGhbaGFzXShrKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9udGNvcHkuZ2x5cGhzW2dseXBoXS5rW2tdID0gcGF0aC5rW2tdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmb250O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLmdldEZvbnRcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEZpbmRzIGZvbnQgb2JqZWN0IGluIHRoZSByZWdpc3RlcmVkIGZvbnRzIGJ5IGdpdmVuIHBhcmFtZXRlcnMuIFlvdSBjb3VsZCBzcGVjaWZ5IG9ubHkgb25lIHdvcmQgZnJvbSB0aGUgZm9udCBuYW1lLCBsaWtlIOKAnE15cmlhZOKAnSBmb3Ig4oCcTXlyaWFkIFByb+KAnS5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gZmFtaWx5IChzdHJpbmcpIGZvbnQgZmFtaWx5IG5hbWUgb3IgYW55IHdvcmQgZnJvbSBpdFxuICAgICAtIHdlaWdodCAoc3RyaW5nKSAjb3B0aW9uYWwgZm9udCB3ZWlnaHRcbiAgICAgLSBzdHlsZSAoc3RyaW5nKSAjb3B0aW9uYWwgZm9udCBzdHlsZVxuICAgICAtIHN0cmV0Y2ggKHN0cmluZykgI29wdGlvbmFsIGZvbnQgc3RyZXRjaFxuICAgICA9IChvYmplY3QpIHRoZSBmb250IG9iamVjdFxuICAgICA+IFVzYWdlXG4gICAgIHwgcGFwZXIucHJpbnQoMTAwLCAxMDAsIFwiVGVzdCBzdHJpbmdcIiwgcGFwZXIuZ2V0Rm9udChcIlRpbWVzXCIsIDgwMCksIDMwKTtcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5nZXRGb250ID0gZnVuY3Rpb24gKGZhbWlseSwgd2VpZ2h0LCBzdHlsZSwgc3RyZXRjaCkge1xuICAgICAgICBzdHJldGNoID0gc3RyZXRjaCB8fCBcIm5vcm1hbFwiO1xuICAgICAgICBzdHlsZSA9IHN0eWxlIHx8IFwibm9ybWFsXCI7XG4gICAgICAgIHdlaWdodCA9ICt3ZWlnaHQgfHwge25vcm1hbDogNDAwLCBib2xkOiA3MDAsIGxpZ2h0ZXI6IDMwMCwgYm9sZGVyOiA4MDB9W3dlaWdodF0gfHwgNDAwO1xuICAgICAgICBpZiAoIVIuZm9udHMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZm9udCA9IFIuZm9udHNbZmFtaWx5XTtcbiAgICAgICAgaWYgKCFmb250KSB7XG4gICAgICAgICAgICB2YXIgbmFtZSA9IG5ldyBSZWdFeHAoXCIoXnxcXFxccylcIiArIGZhbWlseS5yZXBsYWNlKC9bXlxcd1xcZFxccyshfi46Xy1dL2csIEUpICsgXCIoXFxcXHN8JClcIiwgXCJpXCIpO1xuICAgICAgICAgICAgZm9yICh2YXIgZm9udE5hbWUgaW4gUi5mb250cykgaWYgKFIuZm9udHNbaGFzXShmb250TmFtZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAobmFtZS50ZXN0KGZvbnROYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBmb250ID0gUi5mb250c1tmb250TmFtZV07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgdGhlZm9udDtcbiAgICAgICAgaWYgKGZvbnQpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZvbnQubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoZWZvbnQgPSBmb250W2ldO1xuICAgICAgICAgICAgICAgIGlmICh0aGVmb250LmZhY2VbXCJmb250LXdlaWdodFwiXSA9PSB3ZWlnaHQgJiYgKHRoZWZvbnQuZmFjZVtcImZvbnQtc3R5bGVcIl0gPT0gc3R5bGUgfHwgIXRoZWZvbnQuZmFjZVtcImZvbnQtc3R5bGVcIl0pICYmIHRoZWZvbnQuZmFjZVtcImZvbnQtc3RyZXRjaFwiXSA9PSBzdHJldGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhlZm9udDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5wcmludFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ3JlYXRlcyBwYXRoIHRoYXQgcmVwcmVzZW50IGdpdmVuIHRleHQgd3JpdHRlbiB1c2luZyBnaXZlbiBmb250IGF0IGdpdmVuIHBvc2l0aW9uIHdpdGggZ2l2ZW4gc2l6ZS5cbiAgICAgKiBSZXN1bHQgb2YgdGhlIG1ldGhvZCBpcyBwYXRoIGVsZW1lbnQgdGhhdCBjb250YWlucyB3aG9sZSB0ZXh0IGFzIGEgc2VwYXJhdGUgcGF0aC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSB4IHBvc2l0aW9uIG9mIHRoZSB0ZXh0XG4gICAgIC0geSAobnVtYmVyKSB5IHBvc2l0aW9uIG9mIHRoZSB0ZXh0XG4gICAgIC0gc3RyaW5nIChzdHJpbmcpIHRleHQgdG8gcHJpbnRcbiAgICAgLSBmb250IChvYmplY3QpIGZvbnQgb2JqZWN0LCBzZWUgQFBhcGVyLmdldEZvbnRcbiAgICAgLSBzaXplIChudW1iZXIpICNvcHRpb25hbCBzaXplIG9mIHRoZSBmb250LCBkZWZhdWx0IGlzIGAxNmBcbiAgICAgLSBvcmlnaW4gKHN0cmluZykgI29wdGlvbmFsIGNvdWxkIGJlIGBcImJhc2VsaW5lXCJgIG9yIGBcIm1pZGRsZVwiYCwgZGVmYXVsdCBpcyBgXCJtaWRkbGVcImBcbiAgICAgLSBsZXR0ZXJfc3BhY2luZyAobnVtYmVyKSAjb3B0aW9uYWwgbnVtYmVyIGluIHJhbmdlIGAtMS4uMWAsIGRlZmF1bHQgaXMgYDBgXG4gICAgIC0gbGluZV9zcGFjaW5nIChudW1iZXIpICNvcHRpb25hbCBudW1iZXIgaW4gcmFuZ2UgYDEuLjNgLCBkZWZhdWx0IGlzIGAxYFxuICAgICA9IChvYmplY3QpIHJlc3VsdGluZyBwYXRoIGVsZW1lbnQsIHdoaWNoIGNvbnNpc3Qgb2YgYWxsIGxldHRlcnNcbiAgICAgPiBVc2FnZVxuICAgICB8IHZhciB0eHQgPSByLnByaW50KDEwLCA1MCwgXCJwcmludFwiLCByLmdldEZvbnQoXCJNdXNlb1wiKSwgMzApLmF0dHIoe2ZpbGw6IFwiI2ZmZlwifSk7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8ucHJpbnQgPSBmdW5jdGlvbiAoeCwgeSwgc3RyaW5nLCBmb250LCBzaXplLCBvcmlnaW4sIGxldHRlcl9zcGFjaW5nLCBsaW5lX3NwYWNpbmcpIHtcbiAgICAgICAgb3JpZ2luID0gb3JpZ2luIHx8IFwibWlkZGxlXCI7IC8vIGJhc2VsaW5lfG1pZGRsZVxuICAgICAgICBsZXR0ZXJfc3BhY2luZyA9IG1tYXgobW1pbihsZXR0ZXJfc3BhY2luZyB8fCAwLCAxKSwgLTEpO1xuICAgICAgICBsaW5lX3NwYWNpbmcgPSBtbWF4KG1taW4obGluZV9zcGFjaW5nIHx8IDEsIDMpLCAxKTtcbiAgICAgICAgdmFyIGxldHRlcnMgPSBTdHIoc3RyaW5nKVtzcGxpdF0oRSksXG4gICAgICAgICAgICBzaGlmdCA9IDAsXG4gICAgICAgICAgICBub3RmaXJzdCA9IDAsXG4gICAgICAgICAgICBwYXRoID0gRSxcbiAgICAgICAgICAgIHNjYWxlO1xuICAgICAgICBSLmlzKGZvbnQsIFwic3RyaW5nXCIpICYmIChmb250ID0gdGhpcy5nZXRGb250KGZvbnQpKTtcbiAgICAgICAgaWYgKGZvbnQpIHtcbiAgICAgICAgICAgIHNjYWxlID0gKHNpemUgfHwgMTYpIC8gZm9udC5mYWNlW1widW5pdHMtcGVyLWVtXCJdO1xuICAgICAgICAgICAgdmFyIGJiID0gZm9udC5mYWNlLmJib3hbc3BsaXRdKHNlcGFyYXRvciksXG4gICAgICAgICAgICAgICAgdG9wID0gK2JiWzBdLFxuICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQgPSBiYlszXSAtIGJiWzFdLFxuICAgICAgICAgICAgICAgIHNoaWZ0eSA9IDAsXG4gICAgICAgICAgICAgICAgaGVpZ2h0ID0gK2JiWzFdICsgKG9yaWdpbiA9PSBcImJhc2VsaW5lXCIgPyBsaW5lSGVpZ2h0ICsgKCtmb250LmZhY2UuZGVzY2VudCkgOiBsaW5lSGVpZ2h0IC8gMik7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBsZXR0ZXJzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAobGV0dGVyc1tpXSA9PSBcIlxcblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHNoaWZ0ID0gMDtcbiAgICAgICAgICAgICAgICAgICAgY3VyciA9IDA7XG4gICAgICAgICAgICAgICAgICAgIG5vdGZpcnN0ID0gMDtcbiAgICAgICAgICAgICAgICAgICAgc2hpZnR5ICs9IGxpbmVIZWlnaHQgKiBsaW5lX3NwYWNpbmc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByZXYgPSBub3RmaXJzdCAmJiBmb250LmdseXBoc1tsZXR0ZXJzW2kgLSAxXV0gfHwge30sXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyID0gZm9udC5nbHlwaHNbbGV0dGVyc1tpXV07XG4gICAgICAgICAgICAgICAgICAgIHNoaWZ0ICs9IG5vdGZpcnN0ID8gKHByZXYudyB8fCBmb250LncpICsgKHByZXYuayAmJiBwcmV2LmtbbGV0dGVyc1tpXV0gfHwgMCkgKyAoZm9udC53ICogbGV0dGVyX3NwYWNpbmcpIDogMDtcbiAgICAgICAgICAgICAgICAgICAgbm90Zmlyc3QgPSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoY3VyciAmJiBjdXJyLmQpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aCArPSBSLnRyYW5zZm9ybVBhdGgoY3Vyci5kLCBbXCJ0XCIsIHNoaWZ0ICogc2NhbGUsIHNoaWZ0eSAqIHNjYWxlLCBcInNcIiwgc2NhbGUsIHNjYWxlLCB0b3AsIGhlaWdodCwgXCJ0XCIsICh4IC0gdG9wKSAvIHNjYWxlLCAoeSAtIGhlaWdodCkgLyBzY2FsZV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5wYXRoKHBhdGgpLmF0dHIoe1xuICAgICAgICAgICAgZmlsbDogXCIjMDAwXCIsXG4gICAgICAgICAgICBzdHJva2U6IFwibm9uZVwiXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKlxcXG4gICAgICogUGFwZXIuYWRkXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBJbXBvcnRzIGVsZW1lbnRzIGluIEpTT04gYXJyYXkgaW4gZm9ybWF0IGB7dHlwZTogdHlwZSwgPGF0dHJpYnV0ZXM+fWBcbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0ganNvbiAoYXJyYXkpXG4gICAgID0gKG9iamVjdCkgcmVzdWx0aW5nIHNldCBvZiBpbXBvcnRlZCBlbGVtZW50c1xuICAgICA+IFVzYWdlXG4gICAgIHwgcGFwZXIuYWRkKFtcbiAgICAgfCAgICAge1xuICAgICB8ICAgICAgICAgdHlwZTogXCJjaXJjbGVcIixcbiAgICAgfCAgICAgICAgIGN4OiAxMCxcbiAgICAgfCAgICAgICAgIGN5OiAxMCxcbiAgICAgfCAgICAgICAgIHI6IDVcbiAgICAgfCAgICAgfSxcbiAgICAgfCAgICAge1xuICAgICB8ICAgICAgICAgdHlwZTogXCJyZWN0XCIsXG4gICAgIHwgICAgICAgICB4OiAxMCxcbiAgICAgfCAgICAgICAgIHk6IDEwLFxuICAgICB8ICAgICAgICAgd2lkdGg6IDEwLFxuICAgICB8ICAgICAgICAgaGVpZ2h0OiAxMCxcbiAgICAgfCAgICAgICAgIGZpbGw6IFwiI2ZjMFwiXG4gICAgIHwgICAgIH1cbiAgICAgfCBdKTtcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5hZGQgPSBmdW5jdGlvbiAoanNvbikge1xuICAgICAgICBpZiAoUi5pcyhqc29uLCBcImFycmF5XCIpKSB7XG4gICAgICAgICAgICB2YXIgcmVzID0gdGhpcy5zZXQoKSxcbiAgICAgICAgICAgICAgICBpID0gMCxcbiAgICAgICAgICAgICAgICBpaSA9IGpzb24ubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGo7XG4gICAgICAgICAgICBmb3IgKDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICBqID0ganNvbltpXSB8fCB7fTtcbiAgICAgICAgICAgICAgICBlbGVtZW50c1toYXNdKGoudHlwZSkgJiYgcmVzLnB1c2godGhpc1tqLnR5cGVdKCkuYXR0cihqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZm9ybWF0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTaW1wbGUgZm9ybWF0IGZ1bmN0aW9uLiBSZXBsYWNlcyBjb25zdHJ1Y3Rpb24gb2YgdHlwZSDigJxgezxudW1iZXI+fWDigJ0gdG8gdGhlIGNvcnJlc3BvbmRpbmcgYXJndW1lbnQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHRva2VuIChzdHJpbmcpIHN0cmluZyB0byBmb3JtYXRcbiAgICAgLSDigKYgKHN0cmluZykgcmVzdCBvZiBhcmd1bWVudHMgd2lsbCBiZSB0cmVhdGVkIGFzIHBhcmFtZXRlcnMgZm9yIHJlcGxhY2VtZW50XG4gICAgID0gKHN0cmluZykgZm9ybWF0ZWQgc3RyaW5nXG4gICAgID4gVXNhZ2VcbiAgICAgfCB2YXIgeCA9IDEwLFxuICAgICB8ICAgICB5ID0gMjAsXG4gICAgIHwgICAgIHdpZHRoID0gNDAsXG4gICAgIHwgICAgIGhlaWdodCA9IDUwO1xuICAgICB8IC8vIHRoaXMgd2lsbCBkcmF3IGEgcmVjdGFuZ3VsYXIgc2hhcGUgZXF1aXZhbGVudCB0byBcIk0xMCwyMGg0MHY1MGgtNDB6XCJcbiAgICAgfCBwYXBlci5wYXRoKFJhcGhhZWwuZm9ybWF0KFwiTXswfSx7MX1oezJ9dnszfWh7NH16XCIsIHgsIHksIHdpZHRoLCBoZWlnaHQsIC13aWR0aCkpO1xuICAgIFxcKi9cbiAgICBSLmZvcm1hdCA9IGZ1bmN0aW9uICh0b2tlbiwgcGFyYW1zKSB7XG4gICAgICAgIHZhciBhcmdzID0gUi5pcyhwYXJhbXMsIGFycmF5KSA/IFswXVtjb25jYXRdKHBhcmFtcykgOiBhcmd1bWVudHM7XG4gICAgICAgIHRva2VuICYmIFIuaXModG9rZW4sIHN0cmluZykgJiYgYXJncy5sZW5ndGggLSAxICYmICh0b2tlbiA9IHRva2VuLnJlcGxhY2UoZm9ybWF0cmcsIGZ1bmN0aW9uIChzdHIsIGkpIHtcbiAgICAgICAgICAgIHJldHVybiBhcmdzWysraV0gPT0gbnVsbCA/IEUgOiBhcmdzW2ldO1xuICAgICAgICB9KSk7XG4gICAgICAgIHJldHVybiB0b2tlbiB8fCBFO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZnVsbGZpbGxcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEEgbGl0dGxlIGJpdCBtb3JlIGFkdmFuY2VkIGZvcm1hdCBmdW5jdGlvbiB0aGFuIEBSYXBoYWVsLmZvcm1hdC4gUmVwbGFjZXMgY29uc3RydWN0aW9uIG9mIHR5cGUg4oCcYHs8bmFtZT59YOKAnSB0byB0aGUgY29ycmVzcG9uZGluZyBhcmd1bWVudC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gdG9rZW4gKHN0cmluZykgc3RyaW5nIHRvIGZvcm1hdFxuICAgICAtIGpzb24gKG9iamVjdCkgb2JqZWN0IHdoaWNoIHByb3BlcnRpZXMgd2lsbCBiZSB1c2VkIGFzIGEgcmVwbGFjZW1lbnRcbiAgICAgPSAoc3RyaW5nKSBmb3JtYXRlZCBzdHJpbmdcbiAgICAgPiBVc2FnZVxuICAgICB8IC8vIHRoaXMgd2lsbCBkcmF3IGEgcmVjdGFuZ3VsYXIgc2hhcGUgZXF1aXZhbGVudCB0byBcIk0xMCwyMGg0MHY1MGgtNDB6XCJcbiAgICAgfCBwYXBlci5wYXRoKFJhcGhhZWwuZnVsbGZpbGwoXCJNe3h9LHt5fWh7ZGltLndpZHRofXZ7ZGltLmhlaWdodH1oe2RpbVsnbmVnYXRpdmUgd2lkdGgnXX16XCIsIHtcbiAgICAgfCAgICAgeDogMTAsXG4gICAgIHwgICAgIHk6IDIwLFxuICAgICB8ICAgICBkaW06IHtcbiAgICAgfCAgICAgICAgIHdpZHRoOiA0MCxcbiAgICAgfCAgICAgICAgIGhlaWdodDogNTAsXG4gICAgIHwgICAgICAgICBcIm5lZ2F0aXZlIHdpZHRoXCI6IC00MFxuICAgICB8ICAgICB9XG4gICAgIHwgfSkpO1xuICAgIFxcKi9cbiAgICBSLmZ1bGxmaWxsID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRva2VuUmVnZXggPSAvXFx7KFteXFx9XSspXFx9L2csXG4gICAgICAgICAgICBvYmpOb3RhdGlvblJlZ2V4ID0gLyg/Oig/Ol58XFwuKSguKz8pKD89XFxbfFxcLnwkfFxcKCl8XFxbKCd8XCIpKC4rPylcXDJcXF0pKFxcKFxcKSk/L2csIC8vIG1hdGNoZXMgLnh4eHh4IG9yIFtcInh4eHh4XCJdIHRvIHJ1biBvdmVyIG9iamVjdCBwcm9wZXJ0aWVzXG4gICAgICAgICAgICByZXBsYWNlciA9IGZ1bmN0aW9uIChhbGwsIGtleSwgb2JqKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlcyA9IG9iajtcbiAgICAgICAgICAgICAgICBrZXkucmVwbGFjZShvYmpOb3RhdGlvblJlZ2V4LCBmdW5jdGlvbiAoYWxsLCBuYW1lLCBxdW90ZSwgcXVvdGVkTmFtZSwgaXNGdW5jKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lIHx8IHF1b3RlZE5hbWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lIGluIHJlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlc1tuYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiByZXMgPT0gXCJmdW5jdGlvblwiICYmIGlzRnVuYyAmJiAocmVzID0gcmVzKCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmVzID0gKHJlcyA9PSBudWxsIHx8IHJlcyA9PSBvYmogPyBhbGwgOiByZXMpICsgXCJcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzdHIsIG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZyhzdHIpLnJlcGxhY2UodG9rZW5SZWdleCwgZnVuY3Rpb24gKGFsbCwga2V5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcGxhY2VyKGFsbCwga2V5LCBvYmopO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfSkoKTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5uaW5qYVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogSWYgeW91IHdhbnQgdG8gbGVhdmUgbm8gdHJhY2Ugb2YgUmFwaGHDq2wgKFdlbGwsIFJhcGhhw6tsIGNyZWF0ZXMgb25seSBvbmUgZ2xvYmFsIHZhcmlhYmxlIGBSYXBoYWVsYCwgYnV0IGFueXdheS4pIFlvdSBjYW4gdXNlIGBuaW5qYWAgbWV0aG9kLlxuICAgICAqIEJld2FyZSwgdGhhdCBpbiB0aGlzIGNhc2UgcGx1Z2lucyBjb3VsZCBzdG9wIHdvcmtpbmcsIGJlY2F1c2UgdGhleSBhcmUgZGVwZW5kaW5nIG9uIGdsb2JhbCB2YXJpYWJsZSBleGlzdGVuY2UuXG4gICAgICoqXG4gICAgID0gKG9iamVjdCkgUmFwaGFlbCBvYmplY3RcbiAgICAgPiBVc2FnZVxuICAgICB8IChmdW5jdGlvbiAobG9jYWxfcmFwaGFlbCkge1xuICAgICB8ICAgICB2YXIgcGFwZXIgPSBsb2NhbF9yYXBoYWVsKDEwLCAxMCwgMzIwLCAyMDApO1xuICAgICB8ICAgICDigKZcbiAgICAgfCB9KShSYXBoYWVsLm5pbmphKCkpO1xuICAgIFxcKi9cbiAgICBSLm5pbmphID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAob2xkUmFwaGFlbC53YXMpIHtcbiAgICAgICAgICAgIGcud2luLlJhcGhhZWwgPSBvbGRSYXBoYWVsLmlzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSUU4IHJhaXNlcyBhbiBlcnJvciB3aGVuIGRlbGV0aW5nIHdpbmRvdyBwcm9wZXJ0eVxuICAgICAgICAgICAgd2luZG93LlJhcGhhZWwgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3cuUmFwaGFlbDtcbiAgICAgICAgICAgIH0gY2F0Y2goZSkge31cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUjtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnN0XG4gICAgIFsgcHJvcGVydHkgKG9iamVjdCkgXVxuICAgICAqKlxuICAgICAqIFlvdSBjYW4gYWRkIHlvdXIgb3duIG1ldGhvZCB0byBlbGVtZW50cyBhbmQgc2V0cy4gSXQgaXMgd2lzZSB0byBhZGQgYSBzZXQgbWV0aG9kIGZvciBlYWNoIGVsZW1lbnQgbWV0aG9kXG4gICAgICogeW91IGFkZGVkLCBzbyB5b3Ugd2lsbCBiZSBhYmxlIHRvIGNhbGwgdGhlIHNhbWUgbWV0aG9kIG9uIHNldHMgdG9vLlxuICAgICAqKlxuICAgICAqIFNlZSBhbHNvIEBSYXBoYWVsLmVsLlxuICAgICA+IFVzYWdlXG4gICAgIHwgUmFwaGFlbC5lbC5yZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgIHwgICAgIHRoaXMuYXR0cih7ZmlsbDogXCIjZjAwXCJ9KTtcbiAgICAgfCB9O1xuICAgICB8IFJhcGhhZWwuc3QucmVkID0gZnVuY3Rpb24gKCkge1xuICAgICB8ICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgIHwgICAgICAgICBlbC5yZWQoKTtcbiAgICAgfCAgICAgfSk7XG4gICAgIHwgfTtcbiAgICAgfCAvLyB0aGVuIHVzZSBpdFxuICAgICB8IHBhcGVyLnNldChwYXBlci5jaXJjbGUoMTAwLCAxMDAsIDIwKSwgcGFwZXIuY2lyY2xlKDExMCwgMTAwLCAyMCkpLnJlZCgpO1xuICAgIFxcKi9cbiAgICBSLnN0ID0gc2V0cHJvdG87XG5cbiAgICBldmUub24oXCJyYXBoYWVsLkRPTWxvYWRcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2FkZWQgPSB0cnVlO1xuICAgIH0pO1xuXG4gICAgLy8gRmlyZWZveCA8My42IGZpeDogaHR0cDovL3dlYnJlZmxlY3Rpb24uYmxvZ3Nwb3QuY29tLzIwMDkvMTEvMTk1LWNoYXJzLXRvLWhlbHAtbGF6eS1sb2FkaW5nLmh0bWxcbiAgICAoZnVuY3Rpb24gKGRvYywgbG9hZGVkLCBmKSB7XG4gICAgICAgIGlmIChkb2MucmVhZHlTdGF0ZSA9PSBudWxsICYmIGRvYy5hZGRFdmVudExpc3RlbmVyKXtcbiAgICAgICAgICAgIGRvYy5hZGRFdmVudExpc3RlbmVyKGxvYWRlZCwgZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcihsb2FkZWQsIGYsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBkb2MucmVhZHlTdGF0ZSA9IFwiY29tcGxldGVcIjtcbiAgICAgICAgICAgIH0sIGZhbHNlKTtcbiAgICAgICAgICAgIGRvYy5yZWFkeVN0YXRlID0gXCJsb2FkaW5nXCI7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNMb2FkZWQoKSB7XG4gICAgICAgICAgICAoL2luLykudGVzdChkb2MucmVhZHlTdGF0ZSkgPyBzZXRUaW1lb3V0KGlzTG9hZGVkLCA5KSA6IFIuZXZlKFwicmFwaGFlbC5ET01sb2FkXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlzTG9hZGVkKCk7XG4gICAgfSkoZG9jdW1lbnQsIFwiRE9NQ29udGVudExvYWRlZFwiKTtcblxuICAgIHJldHVybiBSO1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./dev/raphael.core.js\n");
+
+/***/ }),
+
+/***/ "./dev/raphael.svg.js":
+/*!****************************!*\
+ !*** ./dev/raphael.svg.js ***!
+ \****************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! ./raphael.core */ \"./dev/raphael.core.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function(R) {\n if (R && !R.svg) {\n return;\n }\n\n var has = \"hasOwnProperty\",\n Str = String,\n toFloat = parseFloat,\n toInt = parseInt,\n math = Math,\n mmax = math.max,\n abs = math.abs,\n pow = math.pow,\n separator = /[, ]+/,\n eve = R.eve,\n E = \"\",\n S = \" \";\n var xlink = \"http://www.w3.org/1999/xlink\",\n markers = {\n block: \"M5,0 0,2.5 5,5z\",\n classic: \"M5,0 0,2.5 5,5 3.5,3 3.5,2z\",\n diamond: \"M2.5,0 5,2.5 2.5,5 0,2.5z\",\n open: \"M6,1 1,3.5 6,6\",\n oval: \"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z\"\n },\n markerCounter = {};\n R.toString = function () {\n return \"Your browser supports SVG.\\nYou are running Rapha\\xebl \" + this.version;\n };\n var $ = function (el, attr) {\n if (attr) {\n if (typeof el == \"string\") {\n el = $(el);\n }\n for (var key in attr) if (attr[has](key)) {\n if (key.substring(0, 6) == \"xlink:\") {\n el.setAttributeNS(xlink, key.substring(6), Str(attr[key]));\n } else {\n el.setAttribute(key, Str(attr[key]));\n }\n }\n } else {\n el = R._g.doc.createElementNS(\"http://www.w3.org/2000/svg\", el);\n el.style && (el.style.webkitTapHighlightColor = \"rgba(0,0,0,0)\");\n }\n return el;\n },\n addGradientFill = function (element, gradient) {\n var type = \"linear\",\n id = element.id + gradient,\n fx = .5, fy = .5,\n o = element.node,\n SVG = element.paper,\n s = o.style,\n el = R._g.doc.getElementById(id);\n if (!el) {\n gradient = Str(gradient).replace(R._radial_gradient, function (all, _fx, _fy) {\n type = \"radial\";\n if (_fx && _fy) {\n fx = toFloat(_fx);\n fy = toFloat(_fy);\n var dir = ((fy > .5) * 2 - 1);\n pow(fx - .5, 2) + pow(fy - .5, 2) > .25 &&\n (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) &&\n fy != .5 &&\n (fy = fy.toFixed(5) - 1e-5 * dir);\n }\n return E;\n });\n gradient = gradient.split(/\\s*\\-\\s*/);\n if (type == \"linear\") {\n var angle = gradient.shift();\n angle = -toFloat(angle);\n if (isNaN(angle)) {\n return null;\n }\n var vector = [0, 0, math.cos(R.rad(angle)), math.sin(R.rad(angle))],\n max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1);\n vector[2] *= max;\n vector[3] *= max;\n if (vector[2] < 0) {\n vector[0] = -vector[2];\n vector[2] = 0;\n }\n if (vector[3] < 0) {\n vector[1] = -vector[3];\n vector[3] = 0;\n }\n }\n var dots = R._parseDots(gradient);\n if (!dots) {\n return null;\n }\n id = id.replace(/[\\(\\)\\s,\\xb0#]/g, \"_\");\n\n if (element.gradient && id != element.gradient.id) {\n SVG.defs.removeChild(element.gradient);\n delete element.gradient;\n }\n\n if (!element.gradient) {\n el = $(type + \"Gradient\", {id: id});\n element.gradient = el;\n $(el, type == \"radial\" ? {\n fx: fx,\n fy: fy\n } : {\n x1: vector[0],\n y1: vector[1],\n x2: vector[2],\n y2: vector[3],\n gradientTransform: element.matrix.invert()\n });\n SVG.defs.appendChild(el);\n for (var i = 0, ii = dots.length; i < ii; i++) {\n el.appendChild($(\"stop\", {\n offset: dots[i].offset ? dots[i].offset : i ? \"100%\" : \"0%\",\n \"stop-color\": dots[i].color || \"#fff\",\n \"stop-opacity\": isFinite(dots[i].opacity) ? dots[i].opacity : 1\n }));\n }\n }\n }\n $(o, {\n fill: fillurl(id),\n opacity: 1,\n \"fill-opacity\": 1\n });\n s.fill = E;\n s.opacity = 1;\n s.fillOpacity = 1;\n return 1;\n },\n isIE9or10 = function () {\n var mode = document.documentMode;\n return mode && (mode === 9 || mode === 10);\n },\n fillurl = function (id) {\n if (isIE9or10()) {\n return \"url('#\" + id + \"')\";\n }\n var location = document.location;\n var locationString = (\n location.protocol + '//' +\n location.host +\n location.pathname +\n location.search\n );\n return \"url('\" + locationString + \"#\" + id + \"')\";\n },\n updatePosition = function (o) {\n var bbox = o.getBBox(1);\n $(o.pattern, {patternTransform: o.matrix.invert() + \" translate(\" + bbox.x + \",\" + bbox.y + \")\"});\n },\n addArrow = function (o, value, isEnd) {\n if (o.type == \"path\") {\n var values = Str(value).toLowerCase().split(\"-\"),\n p = o.paper,\n se = isEnd ? \"end\" : \"start\",\n node = o.node,\n attrs = o.attrs,\n stroke = attrs[\"stroke-width\"],\n i = values.length,\n type = \"classic\",\n from,\n to,\n dx,\n refX,\n attr,\n w = 3,\n h = 3,\n t = 5;\n while (i--) {\n switch (values[i]) {\n case \"block\":\n case \"classic\":\n case \"oval\":\n case \"diamond\":\n case \"open\":\n case \"none\":\n type = values[i];\n break;\n case \"wide\": h = 5; break;\n case \"narrow\": h = 2; break;\n case \"long\": w = 5; break;\n case \"short\": w = 2; break;\n }\n }\n if (type == \"open\") {\n w += 2;\n h += 2;\n t += 2;\n dx = 1;\n refX = isEnd ? 4 : 1;\n attr = {\n fill: \"none\",\n stroke: attrs.stroke\n };\n } else {\n refX = dx = w / 2;\n attr = {\n fill: attrs.stroke,\n stroke: \"none\"\n };\n }\n if (o._.arrows) {\n if (isEnd) {\n o._.arrows.endPath && markerCounter[o._.arrows.endPath]--;\n o._.arrows.endMarker && markerCounter[o._.arrows.endMarker]--;\n } else {\n o._.arrows.startPath && markerCounter[o._.arrows.startPath]--;\n o._.arrows.startMarker && markerCounter[o._.arrows.startMarker]--;\n }\n } else {\n o._.arrows = {};\n }\n if (type != \"none\") {\n var pathId = \"raphael-marker-\" + type,\n markerId = \"raphael-marker-\" + se + type + w + h + \"-obj\" + o.id;\n if (!R._g.doc.getElementById(pathId)) {\n p.defs.appendChild($($(\"path\"), {\n \"stroke-linecap\": \"round\",\n d: markers[type],\n id: pathId\n }));\n markerCounter[pathId] = 1;\n } else {\n markerCounter[pathId]++;\n }\n var marker = R._g.doc.getElementById(markerId),\n use;\n if (!marker) {\n marker = $($(\"marker\"), {\n id: markerId,\n markerHeight: h,\n markerWidth: w,\n orient: \"auto\",\n refX: refX,\n refY: h / 2\n });\n use = $($(\"use\"), {\n \"xlink:href\": \"#\" + pathId,\n transform: (isEnd ? \"rotate(180 \" + w / 2 + \" \" + h / 2 + \") \" : E) + \"scale(\" + w / t + \",\" + h / t + \")\",\n \"stroke-width\": (1 / ((w / t + h / t) / 2)).toFixed(4)\n });\n marker.appendChild(use);\n p.defs.appendChild(marker);\n markerCounter[markerId] = 1;\n } else {\n markerCounter[markerId]++;\n use = marker.getElementsByTagName(\"use\")[0];\n }\n $(use, attr);\n var delta = dx * (type != \"diamond\" && type != \"oval\");\n if (isEnd) {\n from = o._.arrows.startdx * stroke || 0;\n to = R.getTotalLength(attrs.path) - delta * stroke;\n } else {\n from = delta * stroke;\n to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);\n }\n attr = {};\n attr[\"marker-\" + se] = \"url(#\" + markerId + \")\";\n if (to || from) {\n attr.d = R.getSubpath(attrs.path, from, to);\n }\n $(node, attr);\n o._.arrows[se + \"Path\"] = pathId;\n o._.arrows[se + \"Marker\"] = markerId;\n o._.arrows[se + \"dx\"] = delta;\n o._.arrows[se + \"Type\"] = type;\n o._.arrows[se + \"String\"] = value;\n } else {\n if (isEnd) {\n from = o._.arrows.startdx * stroke || 0;\n to = R.getTotalLength(attrs.path) - from;\n } else {\n from = 0;\n to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);\n }\n o._.arrows[se + \"Path\"] && $(node, {d: R.getSubpath(attrs.path, from, to)});\n delete o._.arrows[se + \"Path\"];\n delete o._.arrows[se + \"Marker\"];\n delete o._.arrows[se + \"dx\"];\n delete o._.arrows[se + \"Type\"];\n delete o._.arrows[se + \"String\"];\n }\n for (attr in markerCounter) if (markerCounter[has](attr) && !markerCounter[attr]) {\n var item = R._g.doc.getElementById(attr);\n item && item.parentNode.removeChild(item);\n }\n }\n },\n dasharray = {\n \"-\": [3, 1],\n \".\": [1, 1],\n \"-.\": [3, 1, 1, 1],\n \"-..\": [3, 1, 1, 1, 1, 1],\n \". \": [1, 3],\n \"- \": [4, 3],\n \"--\": [8, 3],\n \"- .\": [4, 3, 1, 3],\n \"--.\": [8, 3, 1, 3],\n \"--..\": [8, 3, 1, 3, 1, 3]\n },\n addDashes = function (o, value, params) {\n value = dasharray[Str(value).toLowerCase()];\n if (value) {\n var width = o.attrs[\"stroke-width\"] || \"1\",\n butt = {round: width, square: width, butt: 0}[o.attrs[\"stroke-linecap\"] || params[\"stroke-linecap\"]] || 0,\n dashes = [],\n i = value.length;\n while (i--) {\n dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt;\n }\n $(o.node, {\"stroke-dasharray\": dashes.join(\",\")});\n }\n else {\n $(o.node, {\"stroke-dasharray\": \"none\"});\n }\n },\n setFillAndStroke = function (o, params) {\n var node = o.node,\n attrs = o.attrs,\n vis = node.style.visibility;\n node.style.visibility = \"hidden\";\n for (var att in params) {\n if (params[has](att)) {\n if (!R._availableAttrs[has](att)) {\n continue;\n }\n var value = params[att];\n attrs[att] = value;\n switch (att) {\n case \"blur\":\n o.blur(value);\n break;\n case \"title\":\n var title = node.getElementsByTagName(\"title\");\n\n // Use the existing .\n if (title.length && (title = title[0])) {\n title.firstChild.nodeValue = value;\n } else {\n title = $(\"title\");\n var val = R._g.doc.createTextNode(value);\n title.appendChild(val);\n node.appendChild(title);\n }\n break;\n case \"href\":\n case \"target\":\n var pn = node.parentNode;\n if (pn.tagName.toLowerCase() != \"a\") {\n var hl = $(\"a\");\n pn.insertBefore(hl, node);\n hl.appendChild(node);\n pn = hl;\n }\n if (att == \"target\") {\n pn.setAttributeNS(xlink, \"show\", value == \"blank\" ? \"new\" : value);\n } else {\n pn.setAttributeNS(xlink, att, value);\n }\n break;\n case \"cursor\":\n node.style.cursor = value;\n break;\n case \"transform\":\n o.transform(value);\n break;\n case \"arrow-start\":\n addArrow(o, value);\n break;\n case \"arrow-end\":\n addArrow(o, value, 1);\n break;\n case \"clip-rect\":\n var rect = Str(value).split(separator);\n if (rect.length == 4) {\n o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);\n var el = $(\"clipPath\"),\n rc = $(\"rect\");\n el.id = R.createUUID();\n $(rc, {\n x: rect[0],\n y: rect[1],\n width: rect[2],\n height: rect[3]\n });\n el.appendChild(rc);\n o.paper.defs.appendChild(el);\n $(node, {\"clip-path\": \"url(#\" + el.id + \")\"});\n o.clip = rc;\n }\n if (!value) {\n var path = node.getAttribute(\"clip-path\");\n if (path) {\n var clip = R._g.doc.getElementById(path.replace(/(^url\\(#|\\)$)/g, E));\n clip && clip.parentNode.removeChild(clip);\n $(node, {\"clip-path\": E});\n delete o.clip;\n }\n }\n break;\n case \"path\":\n if (o.type == \"path\") {\n $(node, {d: value ? attrs.path = R._pathToAbsolute(value) : \"M0,0\"});\n o._.dirty = 1;\n if (o._.arrows) {\n \"startString\" in o._.arrows && addArrow(o, o._.arrows.startString);\n \"endString\" in o._.arrows && addArrow(o, o._.arrows.endString, 1);\n }\n }\n break;\n case \"width\":\n node.setAttribute(att, value);\n o._.dirty = 1;\n if (attrs.fx) {\n att = \"x\";\n value = attrs.x;\n } else {\n break;\n }\n case \"x\":\n if (attrs.fx) {\n value = -attrs.x - (attrs.width || 0);\n }\n case \"rx\":\n if (att == \"rx\" && o.type == \"rect\") {\n break;\n }\n case \"cx\":\n node.setAttribute(att, value);\n o.pattern && updatePosition(o);\n o._.dirty = 1;\n break;\n case \"height\":\n node.setAttribute(att, value);\n o._.dirty = 1;\n if (attrs.fy) {\n att = \"y\";\n value = attrs.y;\n } else {\n break;\n }\n case \"y\":\n if (attrs.fy) {\n value = -attrs.y - (attrs.height || 0);\n }\n case \"ry\":\n if (att == \"ry\" && o.type == \"rect\") {\n break;\n }\n case \"cy\":\n node.setAttribute(att, value);\n o.pattern && updatePosition(o);\n o._.dirty = 1;\n break;\n case \"r\":\n if (o.type == \"rect\") {\n $(node, {rx: value, ry: value});\n } else {\n node.setAttribute(att, value);\n }\n o._.dirty = 1;\n break;\n case \"src\":\n if (o.type == \"image\") {\n node.setAttributeNS(xlink, \"href\", value);\n }\n break;\n case \"stroke-width\":\n if (o._.sx != 1 || o._.sy != 1) {\n value /= mmax(abs(o._.sx), abs(o._.sy)) || 1;\n }\n node.setAttribute(att, value);\n if (attrs[\"stroke-dasharray\"]) {\n addDashes(o, attrs[\"stroke-dasharray\"], params);\n }\n if (o._.arrows) {\n \"startString\" in o._.arrows && addArrow(o, o._.arrows.startString);\n \"endString\" in o._.arrows && addArrow(o, o._.arrows.endString, 1);\n }\n break;\n case \"stroke-dasharray\":\n addDashes(o, value, params);\n break;\n case \"fill\":\n var isURL = Str(value).match(R._ISURL);\n if (isURL) {\n el = $(\"pattern\");\n var ig = $(\"image\");\n el.id = R.createUUID();\n $(el, {x: 0, y: 0, patternUnits: \"userSpaceOnUse\", height: 1, width: 1});\n $(ig, {x: 0, y: 0, \"xlink:href\": isURL[1]});\n el.appendChild(ig);\n\n (function (el) {\n R._preload(isURL[1], function () {\n var w = this.offsetWidth,\n h = this.offsetHeight;\n $(el, {width: w, height: h});\n $(ig, {width: w, height: h});\n });\n })(el);\n o.paper.defs.appendChild(el);\n $(node, {fill: \"url(#\" + el.id + \")\"});\n o.pattern = el;\n o.pattern && updatePosition(o);\n break;\n }\n var clr = R.getRGB(value);\n if (!clr.error) {\n delete params.gradient;\n delete attrs.gradient;\n !R.is(attrs.opacity, \"undefined\") &&\n R.is(params.opacity, \"undefined\") &&\n $(node, {opacity: attrs.opacity});\n !R.is(attrs[\"fill-opacity\"], \"undefined\") &&\n R.is(params[\"fill-opacity\"], \"undefined\") &&\n $(node, {\"fill-opacity\": attrs[\"fill-opacity\"]});\n } else if ((o.type == \"circle\" || o.type == \"ellipse\" || Str(value).charAt() != \"r\") && addGradientFill(o, value)) {\n if (\"opacity\" in attrs || \"fill-opacity\" in attrs) {\n var gradient = R._g.doc.getElementById(node.getAttribute(\"fill\").replace(/^url\\(#|\\)$/g, E));\n if (gradient) {\n var stops = gradient.getElementsByTagName(\"stop\");\n $(stops[stops.length - 1], {\"stop-opacity\": (\"opacity\" in attrs ? attrs.opacity : 1) * (\"fill-opacity\" in attrs ? attrs[\"fill-opacity\"] : 1)});\n }\n }\n attrs.gradient = value;\n attrs.fill = \"none\";\n break;\n }\n clr[has](\"opacity\") && $(node, {\"fill-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n case \"stroke\":\n clr = R.getRGB(value);\n node.setAttribute(att, clr.hex);\n att == \"stroke\" && clr[has](\"opacity\") && $(node, {\"stroke-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n if (att == \"stroke\" && o._.arrows) {\n \"startString\" in o._.arrows && addArrow(o, o._.arrows.startString);\n \"endString\" in o._.arrows && addArrow(o, o._.arrows.endString, 1);\n }\n break;\n case \"gradient\":\n (o.type == \"circle\" || o.type == \"ellipse\" || Str(value).charAt() != \"r\") && addGradientFill(o, value);\n break;\n case \"opacity\":\n if (attrs.gradient && !attrs[has](\"stroke-opacity\")) {\n $(node, {\"stroke-opacity\": value > 1 ? value / 100 : value});\n }\n // fall\n case \"fill-opacity\":\n if (attrs.gradient) {\n gradient = R._g.doc.getElementById(node.getAttribute(\"fill\").replace(/^url\\(#|\\)$/g, E));\n if (gradient) {\n stops = gradient.getElementsByTagName(\"stop\");\n $(stops[stops.length - 1], {\"stop-opacity\": value});\n }\n break;\n }\n default:\n att == \"font-size\" && (value = toInt(value, 10) + \"px\");\n var cssrule = att.replace(/(\\-.)/g, function (w) {\n return w.substring(1).toUpperCase();\n });\n node.style[cssrule] = value;\n o._.dirty = 1;\n node.setAttribute(att, value);\n break;\n }\n }\n }\n\n tuneText(o, params);\n node.style.visibility = vis;\n },\n leading = 1.2,\n tuneText = function (el, params) {\n if (el.type != \"text\" || !(params[has](\"text\") || params[has](\"font\") || params[has](\"font-size\") || params[has](\"x\") || params[has](\"y\"))) {\n return;\n }\n var a = el.attrs,\n node = el.node,\n fontSize = node.firstChild ? toInt(R._g.doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue(\"font-size\"), 10) : 10;\n\n if (params[has](\"text\")) {\n a.text = params.text;\n while (node.firstChild) {\n node.removeChild(node.firstChild);\n }\n var texts = Str(params.text).split(\"\\n\"),\n tspans = [],\n tspan;\n for (var i = 0, ii = texts.length; i < ii; i++) {\n tspan = $(\"tspan\");\n i && $(tspan, {dy: fontSize * leading, x: a.x});\n tspan.appendChild(R._g.doc.createTextNode(texts[i]));\n node.appendChild(tspan);\n tspans[i] = tspan;\n }\n } else {\n tspans = node.getElementsByTagName(\"tspan\");\n for (i = 0, ii = tspans.length; i < ii; i++) if (i) {\n $(tspans[i], {dy: fontSize * leading, x: a.x});\n } else {\n $(tspans[0], {dy: 0});\n }\n }\n $(node, {x: a.x, y: a.y});\n el._.dirty = 1;\n var bb = el._getBBox(),\n dif = a.y - (bb.y + bb.height / 2);\n dif && R.is(dif, \"finite\") && $(tspans[0], {dy: dif});\n },\n getRealNode = function (node) {\n if (node.parentNode && node.parentNode.tagName.toLowerCase() === \"a\") {\n return node.parentNode;\n } else {\n return node;\n }\n },\n Element = function (node, svg) {\n var X = 0,\n Y = 0;\n /*\\\n * Element.node\n [ property (object) ]\n **\n * Gives you a reference to the DOM object, so you can assign event handlers or just mess around.\n **\n * Note: Don’t mess with it.\n > Usage\n | // draw a circle at coordinate 10,10 with radius of 10\n | var c = paper.circle(10, 10, 10);\n | c.node.onclick = function () {\n | c.attr(\"fill\", \"red\");\n | };\n \\*/\n this[0] = this.node = node;\n /*\\\n * Element.raphael\n [ property (object) ]\n **\n * Internal reference to @Raphael object. In case it is not available.\n > Usage\n | Raphael.el.red = function () {\n | var hsb = this.paper.raphael.rgb2hsb(this.attr(\"fill\"));\n | hsb.h = 1;\n | this.attr({fill: this.paper.raphael.hsb2rgb(hsb).hex});\n | }\n \\*/\n node.raphael = true;\n /*\\\n * Element.id\n [ property (number) ]\n **\n * Unique id of the element. Especially useful when you want to listen to events of the element,\n * because all events are fired in format `..`. Also useful for @Paper.getById method.\n \\*/\n this.id = guid();\n node.raphaelid = this.id;\n\n /**\n * Method that returns a 5 letter/digit id, enough for 36^5 = 60466176 elements\n * @returns {string} id\n */\n function guid() {\n return (\"0000\" + (Math.random()*Math.pow(36,5) << 0).toString(36)).slice(-5);\n }\n\n this.matrix = R.matrix();\n this.realPath = null;\n /*\\\n * Element.paper\n [ property (object) ]\n **\n * Internal reference to “paper” where object drawn. Mainly for use in plugins and element extensions.\n > Usage\n | Raphael.el.cross = function () {\n | this.attr({fill: \"red\"});\n | this.paper.path(\"M10,10L50,50M50,10L10,50\")\n | .attr({stroke: \"red\"});\n | }\n \\*/\n this.paper = svg;\n this.attrs = this.attrs || {};\n this._ = {\n transform: [],\n sx: 1,\n sy: 1,\n deg: 0,\n dx: 0,\n dy: 0,\n dirty: 1\n };\n !svg.bottom && (svg.bottom = this);\n /*\\\n * Element.prev\n [ property (object) ]\n **\n * Reference to the previous element in the hierarchy.\n \\*/\n this.prev = svg.top;\n svg.top && (svg.top.next = this);\n svg.top = this;\n /*\\\n * Element.next\n [ property (object) ]\n **\n * Reference to the next element in the hierarchy.\n \\*/\n this.next = null;\n },\n elproto = R.el;\n\n Element.prototype = elproto;\n elproto.constructor = Element;\n\n R._engine.path = function (pathString, SVG) {\n var el = $(\"path\");\n SVG.canvas && SVG.canvas.appendChild(el);\n var p = new Element(el, SVG);\n p.type = \"path\";\n setFillAndStroke(p, {\n fill: \"none\",\n stroke: \"#000\",\n path: pathString\n });\n return p;\n };\n /*\\\n * Element.rotate\n [ method ]\n **\n * Deprecated! Use @Element.transform instead.\n * Adds rotation by given angle around given point to the list of\n * transformations of the element.\n > Parameters\n - deg (number) angle in degrees\n - cx (number) #optional x coordinate of the centre of rotation\n - cy (number) #optional y coordinate of the centre of rotation\n * If cx & cy aren’t specified centre of the shape is used as a point of rotation.\n = (object) @Element\n \\*/\n elproto.rotate = function (deg, cx, cy) {\n if (this.removed) {\n return this;\n }\n deg = Str(deg).split(separator);\n if (deg.length - 1) {\n cx = toFloat(deg[1]);\n cy = toFloat(deg[2]);\n }\n deg = toFloat(deg[0]);\n (cy == null) && (cx = cy);\n if (cx == null || cy == null) {\n var bbox = this.getBBox(1);\n cx = bbox.x + bbox.width / 2;\n cy = bbox.y + bbox.height / 2;\n }\n this.transform(this._.transform.concat([[\"r\", deg, cx, cy]]));\n return this;\n };\n /*\\\n * Element.scale\n [ method ]\n **\n * Deprecated! Use @Element.transform instead.\n * Adds scale by given amount relative to given point to the list of\n * transformations of the element.\n > Parameters\n - sx (number) horisontal scale amount\n - sy (number) vertical scale amount\n - cx (number) #optional x coordinate of the centre of scale\n - cy (number) #optional y coordinate of the centre of scale\n * If cx & cy aren’t specified centre of the shape is used instead.\n = (object) @Element\n \\*/\n elproto.scale = function (sx, sy, cx, cy) {\n if (this.removed) {\n return this;\n }\n sx = Str(sx).split(separator);\n if (sx.length - 1) {\n sy = toFloat(sx[1]);\n cx = toFloat(sx[2]);\n cy = toFloat(sx[3]);\n }\n sx = toFloat(sx[0]);\n (sy == null) && (sy = sx);\n (cy == null) && (cx = cy);\n if (cx == null || cy == null) {\n var bbox = this.getBBox(1);\n }\n cx = cx == null ? bbox.x + bbox.width / 2 : cx;\n cy = cy == null ? bbox.y + bbox.height / 2 : cy;\n this.transform(this._.transform.concat([[\"s\", sx, sy, cx, cy]]));\n return this;\n };\n /*\\\n * Element.translate\n [ method ]\n **\n * Deprecated! Use @Element.transform instead.\n * Adds translation by given amount to the list of transformations of the element.\n > Parameters\n - dx (number) horisontal shift\n - dy (number) vertical shift\n = (object) @Element\n \\*/\n elproto.translate = function (dx, dy) {\n if (this.removed) {\n return this;\n }\n dx = Str(dx).split(separator);\n if (dx.length - 1) {\n dy = toFloat(dx[1]);\n }\n dx = toFloat(dx[0]) || 0;\n dy = +dy || 0;\n this.transform(this._.transform.concat([[\"t\", dx, dy]]));\n return this;\n };\n /*\\\n * Element.transform\n [ method ]\n **\n * Adds transformation to the element which is separate to other attributes,\n * i.e. translation doesn’t change `x` or `y` of the rectange. The format\n * of transformation string is similar to the path string syntax:\n | \"t100,100r30,100,100s2,2,100,100r45s1.5\"\n * Each letter is a command. There are four commands: `t` is for translate, `r` is for rotate, `s` is for\n * scale and `m` is for matrix.\n *\n * There are also alternative “absolute” translation, rotation and scale: `T`, `R` and `S`. They will not take previous transformation into account. For example, `...T100,0` will always move element 100 px horisontally, while `...t100,0` could move it vertically if there is `r90` before. Just compare results of `r90t100,0` and `r90T100,0`.\n *\n * So, the example line above could be read like “translate by 100, 100; rotate 30° around 100, 100; scale twice around 100, 100;\n * rotate 45° around centre; scale 1.5 times relative to centre”. As you can see rotate and scale commands have origin\n * coordinates as optional parameters, the default is the centre point of the element.\n * Matrix accepts six parameters.\n > Usage\n | var el = paper.rect(10, 20, 300, 200);\n | // translate 100, 100, rotate 45°, translate -100, 0\n | el.transform(\"t100,100r45t-100,0\");\n | // if you want you can append or prepend transformations\n | el.transform(\"...t50,50\");\n | el.transform(\"s2...\");\n | // or even wrap\n | el.transform(\"t50,50...t-50-50\");\n | // to reset transformation call method with empty string\n | el.transform(\"\");\n | // to get current value call it without parameters\n | console.log(el.transform());\n > Parameters\n - tstr (string) #optional transformation string\n * If tstr isn’t specified\n = (string) current transformation string\n * else\n = (object) @Element\n \\*/\n elproto.transform = function (tstr) {\n var _ = this._;\n if (tstr == null) {\n return _.transform;\n }\n R._extractTransform(this, tstr);\n\n this.clip && $(this.clip, {transform: this.matrix.invert()});\n this.pattern && updatePosition(this);\n this.node && $(this.node, {transform: this.matrix});\n\n if (_.sx != 1 || _.sy != 1) {\n var sw = this.attrs[has](\"stroke-width\") ? this.attrs[\"stroke-width\"] : 1;\n this.attr({\"stroke-width\": sw});\n }\n\n return this;\n };\n /*\\\n * Element.hide\n [ method ]\n **\n * Makes element invisible. See @Element.show.\n = (object) @Element\n \\*/\n elproto.hide = function () {\n if(!this.removed) this.node.style.display = \"none\";\n return this;\n };\n /*\\\n * Element.show\n [ method ]\n **\n * Makes element visible. See @Element.hide.\n = (object) @Element\n \\*/\n elproto.show = function () {\n if(!this.removed) this.node.style.display = \"\";\n return this;\n };\n /*\\\n * Element.remove\n [ method ]\n **\n * Removes element from the paper.\n \\*/\n elproto.remove = function () {\n var node = getRealNode(this.node);\n if (this.removed || !node.parentNode) {\n return;\n }\n var paper = this.paper;\n paper.__set__ && paper.__set__.exclude(this);\n eve.unbind(\"raphael.*.*.\" + this.id);\n if (this.gradient) {\n paper.defs.removeChild(this.gradient);\n }\n R._tear(this, paper);\n\n node.parentNode.removeChild(node);\n\n // Remove custom data for element\n this.removeData();\n\n for (var i in this) {\n this[i] = typeof this[i] == \"function\" ? R._removedFactory(i) : null;\n }\n this.removed = true;\n };\n elproto._getBBox = function () {\n if (this.node.style.display == \"none\") {\n this.show();\n var hide = true;\n }\n var canvasHidden = false,\n containerStyle;\n if (this.paper.canvas.parentElement) {\n containerStyle = this.paper.canvas.parentElement.style;\n } //IE10+ can't find parentElement\n else if (this.paper.canvas.parentNode) {\n containerStyle = this.paper.canvas.parentNode.style;\n }\n\n if(containerStyle && containerStyle.display == \"none\") {\n canvasHidden = true;\n containerStyle.display = \"\";\n }\n var bbox = {};\n try {\n bbox = this.node.getBBox();\n } catch(e) {\n // Firefox 3.0.x, 25.0.1 (probably more versions affected) play badly here - possible fix\n bbox = {\n x: this.node.clientLeft,\n y: this.node.clientTop,\n width: this.node.clientWidth,\n height: this.node.clientHeight\n }\n } finally {\n bbox = bbox || {};\n if(canvasHidden){\n containerStyle.display = \"none\";\n }\n }\n hide && this.hide();\n return bbox;\n };\n /*\\\n * Element.attr\n [ method ]\n **\n * Sets the attributes of the element.\n > Parameters\n - attrName (string) attribute’s name\n - value (string) value\n * or\n - params (object) object of name/value pairs\n * or\n - attrName (string) attribute’s name\n * or\n - attrNames (array) in this case method returns array of current values for given attribute names\n = (object) @Element if attrsName & value or params are passed in.\n = (...) value of the attribute if only attrsName is passed in.\n = (array) array of values of the attribute if attrsNames is passed in.\n = (object) object of attributes if nothing is passed in.\n > Possible parameters\n #
Please refer to the SVG specification for an explanation of these parameters.
\n o arrow-end (string) arrowhead on the end of the path. The format for string is `[-[-]]`. Possible types: `classic`, `block`, `open`, `oval`, `diamond`, `none`, width: `wide`, `narrow`, `medium`, length: `long`, `short`, `midium`.\n o clip-rect (string) comma or space separated values: x, y, width and height\n o cursor (string) CSS type of the cursor\n o cx (number) the x-axis coordinate of the center of the circle, or ellipse\n o cy (number) the y-axis coordinate of the center of the circle, or ellipse\n o fill (string) colour, gradient or image\n o fill-opacity (number)\n o font (string)\n o font-family (string)\n o font-size (number) font size in pixels\n o font-weight (string)\n o height (number)\n o href (string) URL, if specified element behaves as hyperlink\n o opacity (number)\n o path (string) SVG path string format\n o r (number) radius of the circle, ellipse or rounded corner on the rect\n o rx (number) horisontal radius of the ellipse\n o ry (number) vertical radius of the ellipse\n o src (string) image URL, only works for @Element.image element\n o stroke (string) stroke colour\n o stroke-dasharray (string) [“”, “none”, “`-`”, “`.`”, “`-.`”, “`-..`”, “`. `”, “`- `”, “`--`”, “`- .`”, “`--.`”, “`--..`”]\n o stroke-linecap (string) [“`butt`”, “`square`”, “`round`”]\n o stroke-linejoin (string) [“`bevel`”, “`round`”, “`miter`”]\n o stroke-miterlimit (number)\n o stroke-opacity (number)\n o stroke-width (number) stroke width in pixels, default is '1'\n o target (string) used with href\n o text (string) contents of the text element. Use `\\n` for multiline text\n o text-anchor (string) [“`start`”, “`middle`”, “`end`”], default is “`middle`”\n o title (string) will create tooltip with a given text\n o transform (string) see @Element.transform\n o width (number)\n o x (number)\n o y (number)\n > Gradients\n * Linear gradient format: “`‹angle›-‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`90-#fff-#000`” – 90°\n * gradient from white to black or “`0-#fff-#f00:20-#000`” – 0° gradient from white via red (at 20%) to black.\n *\n * radial gradient: “`r[(‹fx›, ‹fy›)]‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`r#fff-#000`” –\n * gradient from white to black or “`r(0.25, 0.75)#fff-#000`” – gradient from white to black with focus point\n * at 0.25, 0.75. Focus point coordinates are in 0..1 range. Radial gradients can only be applied to circles and ellipses.\n > Path String\n #