From b722b5dc096a2abb0b8a64b60adfa6abfe42271f Mon Sep 17 00:00:00 2001 From: SonjaTuro Date: Sat, 2 Mar 2024 20:57:28 +1100 Subject: [PATCH] Add hunger indicator --- package-lock.json | 19 +- package.json | 3 +- resources/dist/components/duckmode-feeder.js | 25029 ++++++++++++++++- resources/js/components/feeder.js | 37 +- resources/views/feeder-widget.blade.php | 16 +- src/FeederWidget.php | 27 + src/Livewire/HungerChart.php | 34 + 7 files changed, 25155 insertions(+), 10 deletions(-) create mode 100644 src/Livewire/HungerChart.php diff --git a/package-lock.json b/package-lock.json index ac240b2..c5b44b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,8 @@ "packages": { "": { "dependencies": { - "canvas-gauges": "^2.1.7-radial" + "canvas-gauges": "^2.1.7-radial", + "chart.js": "^4.4.2" }, "devDependencies": { "esbuild": "^0.17.19" @@ -363,11 +364,27 @@ "node": ">=12" } }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + }, "node_modules/canvas-gauges": { "version": "2.1.7-radial", "resolved": "https://registry.npmjs.org/canvas-gauges/-/canvas-gauges-2.1.7-radial.tgz", "integrity": "sha512-BtgLcptUQL9Q4WxiC2wSfKI209TZSVmSJtzrh7a0M26KvtYVqVpflenDKpmSQWZyrzFORPgCOXvsXYkudY5t1Q==" }, + "node_modules/chart.js": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz", + "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/esbuild": { "version": "0.17.19", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", diff --git a/package.json b/package.json index 2697889..4433a97 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "esbuild": "^0.17.19" }, "dependencies": { - "canvas-gauges": "^2.1.7-radial" + "canvas-gauges": "^2.1.7-radial", + "chart.js": "^4.4.2" } } diff --git a/resources/dist/components/duckmode-feeder.js b/resources/dist/components/duckmode-feeder.js index d4ae935..7727d51 100644 --- a/resources/dist/components/duckmode-feeder.js +++ b/resources/dist/components/duckmode-feeder.js @@ -1,16 +1,24957 @@ +var __defProp = Object.defineProperty; +var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __publicField = (obj, key, value) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + return value; +}; + +// node_modules/@kurkle/color/dist/color.esm.js +function round(v) { + return v + 0.5 | 0; +} +var lim = (v, l2, h) => Math.max(Math.min(v, h), l2); +function p2b(v) { + return lim(round(v * 2.55), 0, 255); +} +function n2b(v) { + return lim(round(v * 255), 0, 255); +} +function b2n(v) { + return lim(round(v / 2.55) / 100, 0, 1); +} +function n2p(v) { + return lim(round(v * 100), 0, 100); +} +var map$1 = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15 }; +var hex = [..."0123456789ABCDEF"]; +var h1 = (b) => hex[b & 15]; +var h2 = (b) => hex[(b & 240) >> 4] + hex[b & 15]; +var eq = (b) => (b & 240) >> 4 === (b & 15); +var isShort = (v) => eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a); +function hexParse(str) { + var len = str.length; + var ret; + if (str[0] === "#") { + if (len === 4 || len === 5) { + ret = { + r: 255 & map$1[str[1]] * 17, + g: 255 & map$1[str[2]] * 17, + b: 255 & map$1[str[3]] * 17, + a: len === 5 ? map$1[str[4]] * 17 : 255 + }; + } else if (len === 7 || len === 9) { + ret = { + r: map$1[str[1]] << 4 | map$1[str[2]], + g: map$1[str[3]] << 4 | map$1[str[4]], + b: map$1[str[5]] << 4 | map$1[str[6]], + a: len === 9 ? map$1[str[7]] << 4 | map$1[str[8]] : 255 + }; + } + } + return ret; +} +var alpha = (a, f) => a < 255 ? f(a) : ""; +function hexString(v) { + var f = isShort(v) ? h1 : h2; + return v ? "#" + f(v.r) + f(v.g) + f(v.b) + alpha(v.a, f) : void 0; +} +var HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/; +function hsl2rgbn(h, s2, l2) { + const a = s2 * Math.min(l2, 1 - l2); + const f = (n2, k = (n2 + h / 30) % 12) => l2 - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); + return [f(0), f(8), f(4)]; +} +function hsv2rgbn(h, s2, v) { + const f = (n2, k = (n2 + h / 60) % 6) => v - v * s2 * Math.max(Math.min(k, 4 - k, 1), 0); + return [f(5), f(3), f(1)]; +} +function hwb2rgbn(h, w, b) { + const rgb = hsl2rgbn(h, 1, 0.5); + let i; + if (w + b > 1) { + i = 1 / (w + b); + w *= i; + b *= i; + } + for (i = 0; i < 3; i++) { + rgb[i] *= 1 - w - b; + rgb[i] += w; + } + return rgb; +} +function hueValue(r, g, b, d, max) { + if (r === max) { + return (g - b) / d + (g < b ? 6 : 0); + } + if (g === max) { + return (b - r) / d + 2; + } + return (r - g) / d + 4; +} +function rgb2hsl(v) { + const range = 255; + const r = v.r / range; + const g = v.g / range; + const b = v.b / range; + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + const l2 = (max + min) / 2; + let h, s2, d; + if (max !== min) { + d = max - min; + s2 = l2 > 0.5 ? d / (2 - max - min) : d / (max + min); + h = hueValue(r, g, b, d, max); + h = h * 60 + 0.5; + } + return [h | 0, s2 || 0, l2]; +} +function calln(f, a, b, c) { + return (Array.isArray(a) ? f(a[0], a[1], a[2]) : f(a, b, c)).map(n2b); +} +function hsl2rgb(h, s2, l2) { + return calln(hsl2rgbn, h, s2, l2); +} +function hwb2rgb(h, w, b) { + return calln(hwb2rgbn, h, w, b); +} +function hsv2rgb(h, s2, v) { + return calln(hsv2rgbn, h, s2, v); +} +function hue(h) { + return (h % 360 + 360) % 360; +} +function hueParse(str) { + const m = HUE_RE.exec(str); + let a = 255; + let v; + if (!m) { + return; + } + if (m[5] !== v) { + a = m[6] ? p2b(+m[5]) : n2b(+m[5]); + } + const h = hue(+m[2]); + const p1 = +m[3] / 100; + const p2 = +m[4] / 100; + if (m[1] === "hwb") { + v = hwb2rgb(h, p1, p2); + } else if (m[1] === "hsv") { + v = hsv2rgb(h, p1, p2); + } else { + v = hsl2rgb(h, p1, p2); + } + return { + r: v[0], + g: v[1], + b: v[2], + a + }; +} +function rotate(v, deg) { + var h = rgb2hsl(v); + h[0] = hue(h[0] + deg); + h = hsl2rgb(h); + v.r = h[0]; + v.g = h[1]; + v.b = h[2]; +} +function hslString(v) { + if (!v) { + return; + } + const a = rgb2hsl(v); + const h = a[0]; + const s2 = n2p(a[1]); + const l2 = n2p(a[2]); + return v.a < 255 ? `hsla(${h}, ${s2}%, ${l2}%, ${b2n(v.a)})` : `hsl(${h}, ${s2}%, ${l2}%)`; +} +var map = { + x: "dark", + Z: "light", + Y: "re", + X: "blu", + W: "gr", + V: "medium", + U: "slate", + A: "ee", + T: "ol", + S: "or", + B: "ra", + C: "lateg", + D: "ights", + R: "in", + Q: "turquois", + E: "hi", + P: "ro", + O: "al", + N: "le", + M: "de", + L: "yello", + F: "en", + K: "ch", + G: "arks", + H: "ea", + I: "ightg", + J: "wh" +}; +var names$1 = { + OiceXe: "f0f8ff", + antiquewEte: "faebd7", + aqua: "ffff", + aquamarRe: "7fffd4", + azuY: "f0ffff", + beige: "f5f5dc", + bisque: "ffe4c4", + black: "0", + blanKedOmond: "ffebcd", + Xe: "ff", + XeviTet: "8a2be2", + bPwn: "a52a2a", + burlywood: "deb887", + caMtXe: "5f9ea0", + KartYuse: "7fff00", + KocTate: "d2691e", + cSO: "ff7f50", + cSnflowerXe: "6495ed", + cSnsilk: "fff8dc", + crimson: "dc143c", + cyan: "ffff", + xXe: "8b", + xcyan: "8b8b", + xgTMnPd: "b8860b", + xWay: "a9a9a9", + xgYF: "6400", + xgYy: "a9a9a9", + xkhaki: "bdb76b", + xmagFta: "8b008b", + xTivegYF: "556b2f", + xSange: "ff8c00", + xScEd: "9932cc", + xYd: "8b0000", + xsOmon: "e9967a", + xsHgYF: "8fbc8f", + xUXe: "483d8b", + xUWay: "2f4f4f", + xUgYy: "2f4f4f", + xQe: "ced1", + xviTet: "9400d3", + dAppRk: "ff1493", + dApskyXe: "bfff", + dimWay: "696969", + dimgYy: "696969", + dodgerXe: "1e90ff", + fiYbrick: "b22222", + flSOwEte: "fffaf0", + foYstWAn: "228b22", + fuKsia: "ff00ff", + gaRsbSo: "dcdcdc", + ghostwEte: "f8f8ff", + gTd: "ffd700", + gTMnPd: "daa520", + Way: "808080", + gYF: "8000", + gYFLw: "adff2f", + gYy: "808080", + honeyMw: "f0fff0", + hotpRk: "ff69b4", + RdianYd: "cd5c5c", + Rdigo: "4b0082", + ivSy: "fffff0", + khaki: "f0e68c", + lavFMr: "e6e6fa", + lavFMrXsh: "fff0f5", + lawngYF: "7cfc00", + NmoncEffon: "fffacd", + ZXe: "add8e6", + ZcSO: "f08080", + Zcyan: "e0ffff", + ZgTMnPdLw: "fafad2", + ZWay: "d3d3d3", + ZgYF: "90ee90", + ZgYy: "d3d3d3", + ZpRk: "ffb6c1", + ZsOmon: "ffa07a", + ZsHgYF: "20b2aa", + ZskyXe: "87cefa", + ZUWay: "778899", + ZUgYy: "778899", + ZstAlXe: "b0c4de", + ZLw: "ffffe0", + lime: "ff00", + limegYF: "32cd32", + lRF: "faf0e6", + magFta: "ff00ff", + maPon: "800000", + VaquamarRe: "66cdaa", + VXe: "cd", + VScEd: "ba55d3", + VpurpN: "9370db", + VsHgYF: "3cb371", + VUXe: "7b68ee", + VsprRggYF: "fa9a", + VQe: "48d1cc", + VviTetYd: "c71585", + midnightXe: "191970", + mRtcYam: "f5fffa", + mistyPse: "ffe4e1", + moccasR: "ffe4b5", + navajowEte: "ffdead", + navy: "80", + Tdlace: "fdf5e6", + Tive: "808000", + TivedBb: "6b8e23", + Sange: "ffa500", + SangeYd: "ff4500", + ScEd: "da70d6", + pOegTMnPd: "eee8aa", + pOegYF: "98fb98", + pOeQe: "afeeee", + pOeviTetYd: "db7093", + papayawEp: "ffefd5", + pHKpuff: "ffdab9", + peru: "cd853f", + pRk: "ffc0cb", + plum: "dda0dd", + powMrXe: "b0e0e6", + purpN: "800080", + YbeccapurpN: "663399", + Yd: "ff0000", + Psybrown: "bc8f8f", + PyOXe: "4169e1", + saddNbPwn: "8b4513", + sOmon: "fa8072", + sandybPwn: "f4a460", + sHgYF: "2e8b57", + sHshell: "fff5ee", + siFna: "a0522d", + silver: "c0c0c0", + skyXe: "87ceeb", + UXe: "6a5acd", + UWay: "708090", + UgYy: "708090", + snow: "fffafa", + sprRggYF: "ff7f", + stAlXe: "4682b4", + tan: "d2b48c", + teO: "8080", + tEstN: "d8bfd8", + tomato: "ff6347", + Qe: "40e0d0", + viTet: "ee82ee", + JHt: "f5deb3", + wEte: "ffffff", + wEtesmoke: "f5f5f5", + Lw: "ffff00", + LwgYF: "9acd32" +}; +function unpack() { + const unpacked = {}; + const keys = Object.keys(names$1); + const tkeys = Object.keys(map); + let i, j, k, ok, nk; + for (i = 0; i < keys.length; i++) { + ok = nk = keys[i]; + for (j = 0; j < tkeys.length; j++) { + k = tkeys[j]; + nk = nk.replace(k, map[k]); + } + k = parseInt(names$1[ok], 16); + unpacked[nk] = [k >> 16 & 255, k >> 8 & 255, k & 255]; + } + return unpacked; +} +var names; +function nameParse(str) { + if (!names) { + names = unpack(); + names.transparent = [0, 0, 0, 0]; + } + const a = names[str.toLowerCase()]; + return a && { + r: a[0], + g: a[1], + b: a[2], + a: a.length === 4 ? a[3] : 255 + }; +} +var RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/; +function rgbParse(str) { + const m = RGB_RE.exec(str); + let a = 255; + let r, g, b; + if (!m) { + return; + } + if (m[7] !== r) { + const v = +m[7]; + a = m[8] ? p2b(v) : lim(v * 255, 0, 255); + } + r = +m[1]; + g = +m[3]; + b = +m[5]; + r = 255 & (m[2] ? p2b(r) : lim(r, 0, 255)); + g = 255 & (m[4] ? p2b(g) : lim(g, 0, 255)); + b = 255 & (m[6] ? p2b(b) : lim(b, 0, 255)); + return { + r, + g, + b, + a + }; +} +function rgbString(v) { + return v && (v.a < 255 ? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})` : `rgb(${v.r}, ${v.g}, ${v.b})`); +} +var to = (v) => v <= 31308e-7 ? v * 12.92 : Math.pow(v, 1 / 2.4) * 1.055 - 0.055; +var from = (v) => v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4); +function interpolate(rgb1, rgb2, t) { + const r = from(b2n(rgb1.r)); + const g = from(b2n(rgb1.g)); + const b = from(b2n(rgb1.b)); + return { + r: n2b(to(r + t * (from(b2n(rgb2.r)) - r))), + g: n2b(to(g + t * (from(b2n(rgb2.g)) - g))), + b: n2b(to(b + t * (from(b2n(rgb2.b)) - b))), + a: rgb1.a + t * (rgb2.a - rgb1.a) + }; +} +function modHSL(v, i, ratio) { + if (v) { + let tmp = rgb2hsl(v); + tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1)); + tmp = hsl2rgb(tmp); + v.r = tmp[0]; + v.g = tmp[1]; + v.b = tmp[2]; + } +} +function clone(v, proto) { + return v ? Object.assign(proto || {}, v) : v; +} +function fromObject(input) { + var v = { r: 0, g: 0, b: 0, a: 255 }; + if (Array.isArray(input)) { + if (input.length >= 3) { + v = { r: input[0], g: input[1], b: input[2], a: 255 }; + if (input.length > 3) { + v.a = n2b(input[3]); + } + } + } else { + v = clone(input, { r: 0, g: 0, b: 0, a: 1 }); + v.a = n2b(v.a); + } + return v; +} +function functionParse(str) { + if (str.charAt(0) === "r") { + return rgbParse(str); + } + return hueParse(str); +} +var Color = class { + constructor(input) { + if (input instanceof Color) { + return input; + } + const type = typeof input; + let v; + if (type === "object") { + v = fromObject(input); + } else if (type === "string") { + v = hexParse(input) || nameParse(input) || functionParse(input); + } + this._rgb = v; + this._valid = !!v; + } + get valid() { + return this._valid; + } + get rgb() { + var v = clone(this._rgb); + if (v) { + v.a = b2n(v.a); + } + return v; + } + set rgb(obj) { + this._rgb = fromObject(obj); + } + rgbString() { + return this._valid ? rgbString(this._rgb) : void 0; + } + hexString() { + return this._valid ? hexString(this._rgb) : void 0; + } + hslString() { + return this._valid ? hslString(this._rgb) : void 0; + } + mix(color3, weight) { + if (color3) { + const c1 = this.rgb; + const c2 = color3.rgb; + let w2; + const p = weight === w2 ? 0.5 : weight; + const w = 2 * p - 1; + const a = c1.a - c2.a; + const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2; + w2 = 1 - w1; + c1.r = 255 & w1 * c1.r + w2 * c2.r + 0.5; + c1.g = 255 & w1 * c1.g + w2 * c2.g + 0.5; + c1.b = 255 & w1 * c1.b + w2 * c2.b + 0.5; + c1.a = p * c1.a + (1 - p) * c2.a; + this.rgb = c1; + } + return this; + } + interpolate(color3, t) { + if (color3) { + this._rgb = interpolate(this._rgb, color3._rgb, t); + } + return this; + } + clone() { + return new Color(this.rgb); + } + alpha(a) { + this._rgb.a = n2b(a); + return this; + } + clearer(ratio) { + const rgb = this._rgb; + rgb.a *= 1 - ratio; + return this; + } + greyscale() { + const rgb = this._rgb; + const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11); + rgb.r = rgb.g = rgb.b = val; + return this; + } + opaquer(ratio) { + const rgb = this._rgb; + rgb.a *= 1 + ratio; + return this; + } + negate() { + const v = this._rgb; + v.r = 255 - v.r; + v.g = 255 - v.g; + v.b = 255 - v.b; + return this; + } + lighten(ratio) { + modHSL(this._rgb, 2, ratio); + return this; + } + darken(ratio) { + modHSL(this._rgb, 2, -ratio); + return this; + } + saturate(ratio) { + modHSL(this._rgb, 1, ratio); + return this; + } + desaturate(ratio) { + modHSL(this._rgb, 1, -ratio); + return this; + } + rotate(deg) { + rotate(this._rgb, deg); + return this; + } +}; + +// node_modules/chart.js/dist/chunks/helpers.segment.js +function noop() { +} +var uid = (() => { + let id = 0; + return () => id++; +})(); +function isNullOrUndef(value) { + return value === null || typeof value === "undefined"; +} +function isArray(value) { + if (Array.isArray && Array.isArray(value)) { + return true; + } + const type = Object.prototype.toString.call(value); + if (type.slice(0, 7) === "[object" && type.slice(-6) === "Array]") { + return true; + } + return false; +} +function isObject(value) { + return value !== null && Object.prototype.toString.call(value) === "[object Object]"; +} +function isNumberFinite(value) { + return (typeof value === "number" || value instanceof Number) && isFinite(+value); +} +function finiteOrDefault(value, defaultValue) { + return isNumberFinite(value) ? value : defaultValue; +} +function valueOrDefault(value, defaultValue) { + return typeof value === "undefined" ? defaultValue : value; +} +var toPercentage = (value, dimension) => typeof value === "string" && value.endsWith("%") ? parseFloat(value) / 100 : +value / dimension; +var toDimension = (value, dimension) => typeof value === "string" && value.endsWith("%") ? parseFloat(value) / 100 * dimension : +value; +function callback(fn, args, thisArg) { + if (fn && typeof fn.call === "function") { + return fn.apply(thisArg, args); + } +} +function each(loopable, fn, thisArg, reverse) { + let i, len, keys; + if (isArray(loopable)) { + len = loopable.length; + if (reverse) { + for (i = len - 1; i >= 0; i--) { + fn.call(thisArg, loopable[i], i); + } + } else { + for (i = 0; i < len; i++) { + fn.call(thisArg, loopable[i], i); + } + } + } else if (isObject(loopable)) { + keys = Object.keys(loopable); + len = keys.length; + for (i = 0; i < len; i++) { + fn.call(thisArg, loopable[keys[i]], keys[i]); + } + } +} +function _elementsEqual(a0, a1) { + let i, ilen, v0, v1; + if (!a0 || !a1 || a0.length !== a1.length) { + return false; + } + for (i = 0, ilen = a0.length; i < ilen; ++i) { + v0 = a0[i]; + v1 = a1[i]; + if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) { + return false; + } + } + return true; +} +function clone2(source) { + if (isArray(source)) { + return source.map(clone2); + } + if (isObject(source)) { + const target = /* @__PURE__ */ Object.create(null); + const keys = Object.keys(source); + const klen = keys.length; + let k = 0; + for (; k < klen; ++k) { + target[keys[k]] = clone2(source[keys[k]]); + } + return target; + } + return source; +} +function isValidKey(key) { + return [ + "__proto__", + "prototype", + "constructor" + ].indexOf(key) === -1; +} +function _merger(key, target, source, options) { + if (!isValidKey(key)) { + return; + } + const tval = target[key]; + const sval = source[key]; + if (isObject(tval) && isObject(sval)) { + merge(tval, sval, options); + } else { + target[key] = clone2(sval); + } +} +function merge(target, source, options) { + const sources = isArray(source) ? source : [ + source + ]; + const ilen = sources.length; + if (!isObject(target)) { + return target; + } + options = options || {}; + const merger = options.merger || _merger; + let current; + for (let i = 0; i < ilen; ++i) { + current = sources[i]; + if (!isObject(current)) { + continue; + } + const keys = Object.keys(current); + for (let k = 0, klen = keys.length; k < klen; ++k) { + merger(keys[k], target, current, options); + } + } + return target; +} +function mergeIf(target, source) { + return merge(target, source, { + merger: _mergerIf + }); +} +function _mergerIf(key, target, source) { + if (!isValidKey(key)) { + return; + } + const tval = target[key]; + const sval = source[key]; + if (isObject(tval) && isObject(sval)) { + mergeIf(tval, sval); + } else if (!Object.prototype.hasOwnProperty.call(target, key)) { + target[key] = clone2(sval); + } +} +var keyResolvers = { + // Chart.helpers.core resolveObjectKey should resolve empty key to root object + "": (v) => v, + // default resolvers + x: (o) => o.x, + y: (o) => o.y +}; +function _splitKey(key) { + const parts = key.split("."); + const keys = []; + let tmp = ""; + for (const part of parts) { + tmp += part; + if (tmp.endsWith("\\")) { + tmp = tmp.slice(0, -1) + "."; + } else { + keys.push(tmp); + tmp = ""; + } + } + return keys; +} +function _getKeyResolver(key) { + const keys = _splitKey(key); + return (obj) => { + for (const k of keys) { + if (k === "") { + break; + } + obj = obj && obj[k]; + } + return obj; + }; +} +function resolveObjectKey(obj, key) { + const resolver = keyResolvers[key] || (keyResolvers[key] = _getKeyResolver(key)); + return resolver(obj); +} +function _capitalize(str) { + return str.charAt(0).toUpperCase() + str.slice(1); +} +var defined = (value) => typeof value !== "undefined"; +var isFunction = (value) => typeof value === "function"; +var setsEqual = (a, b) => { + if (a.size !== b.size) { + return false; + } + for (const item of a) { + if (!b.has(item)) { + return false; + } + } + return true; +}; +function _isClickEvent(e) { + return e.type === "mouseup" || e.type === "click" || e.type === "contextmenu"; +} +var PI = Math.PI; +var TAU = 2 * PI; +var PITAU = TAU + PI; +var INFINITY = Number.POSITIVE_INFINITY; +var RAD_PER_DEG = PI / 180; +var HALF_PI = PI / 2; +var QUARTER_PI = PI / 4; +var TWO_THIRDS_PI = PI * 2 / 3; +var log10 = Math.log10; +var sign = Math.sign; +function almostEquals(x, y, epsilon) { + return Math.abs(x - y) < epsilon; +} +function niceNum(range) { + const roundedRange = Math.round(range); + range = almostEquals(range, roundedRange, range / 1e3) ? roundedRange : range; + const niceRange = Math.pow(10, Math.floor(log10(range))); + const fraction = range / niceRange; + const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10; + return niceFraction * niceRange; +} +function _factorize(value) { + const result = []; + const sqrt = Math.sqrt(value); + let i; + for (i = 1; i < sqrt; i++) { + if (value % i === 0) { + result.push(i); + result.push(value / i); + } + } + if (sqrt === (sqrt | 0)) { + result.push(sqrt); + } + result.sort((a, b) => a - b).pop(); + return result; +} +function isNumber(n2) { + return !isNaN(parseFloat(n2)) && isFinite(n2); +} +function almostWhole(x, epsilon) { + const rounded = Math.round(x); + return rounded - epsilon <= x && rounded + epsilon >= x; +} +function _setMinAndMaxByKey(array, target, property) { + let i, ilen, value; + for (i = 0, ilen = array.length; i < ilen; i++) { + value = array[i][property]; + if (!isNaN(value)) { + target.min = Math.min(target.min, value); + target.max = Math.max(target.max, value); + } + } +} +function toRadians(degrees) { + return degrees * (PI / 180); +} +function toDegrees(radians) { + return radians * (180 / PI); +} +function _decimalPlaces(x) { + if (!isNumberFinite(x)) { + return; + } + let e = 1; + let p = 0; + while (Math.round(x * e) / e !== x) { + e *= 10; + p++; + } + return p; +} +function getAngleFromPoint(centrePoint, anglePoint) { + const distanceFromXCenter = anglePoint.x - centrePoint.x; + const distanceFromYCenter = anglePoint.y - centrePoint.y; + const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); + let angle = Math.atan2(distanceFromYCenter, distanceFromXCenter); + if (angle < -0.5 * PI) { + angle += TAU; + } + return { + angle, + distance: radialDistanceFromCenter + }; +} +function distanceBetweenPoints(pt1, pt2) { + return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2)); +} +function _angleDiff(a, b) { + return (a - b + PITAU) % TAU - PI; +} +function _normalizeAngle(a) { + return (a % TAU + TAU) % TAU; +} +function _angleBetween(angle, start, end, sameAngleIsFullCircle) { + const a = _normalizeAngle(angle); + const s2 = _normalizeAngle(start); + const e = _normalizeAngle(end); + const angleToStart = _normalizeAngle(s2 - a); + const angleToEnd = _normalizeAngle(e - a); + const startToAngle = _normalizeAngle(a - s2); + const endToAngle = _normalizeAngle(a - e); + return a === s2 || a === e || sameAngleIsFullCircle && s2 === e || angleToStart > angleToEnd && startToAngle < endToAngle; +} +function _limitValue(value, min, max) { + return Math.max(min, Math.min(max, value)); +} +function _int16Range(value) { + return _limitValue(value, -32768, 32767); +} +function _isBetween(value, start, end, epsilon = 1e-6) { + return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon; +} +function _lookup(table, value, cmp) { + cmp = cmp || ((index2) => table[index2] < value); + let hi = table.length - 1; + let lo = 0; + let mid; + while (hi - lo > 1) { + mid = lo + hi >> 1; + if (cmp(mid)) { + lo = mid; + } else { + hi = mid; + } + } + return { + lo, + hi + }; +} +var _lookupByKey = (table, key, value, last) => _lookup(table, value, last ? (index2) => { + const ti = table[index2][key]; + return ti < value || ti === value && table[index2 + 1][key] === value; +} : (index2) => table[index2][key] < value); +var _rlookupByKey = (table, key, value) => _lookup(table, value, (index2) => table[index2][key] >= value); +function _filterBetween(values, min, max) { + let start = 0; + let end = values.length; + while (start < end && values[start] < min) { + start++; + } + while (end > start && values[end - 1] > max) { + end--; + } + return start > 0 || end < values.length ? values.slice(start, end) : values; +} +var arrayEvents = [ + "push", + "pop", + "shift", + "splice", + "unshift" +]; +function listenArrayEvents(array, listener) { + if (array._chartjs) { + array._chartjs.listeners.push(listener); + return; + } + Object.defineProperty(array, "_chartjs", { + configurable: true, + enumerable: false, + value: { + listeners: [ + listener + ] + } + }); + arrayEvents.forEach((key) => { + const method = "_onData" + _capitalize(key); + const base = array[key]; + Object.defineProperty(array, key, { + configurable: true, + enumerable: false, + value(...args) { + const res = base.apply(this, args); + array._chartjs.listeners.forEach((object) => { + if (typeof object[method] === "function") { + object[method](...args); + } + }); + return res; + } + }); + }); +} +function unlistenArrayEvents(array, listener) { + const stub = array._chartjs; + if (!stub) { + return; + } + const listeners = stub.listeners; + const index2 = listeners.indexOf(listener); + if (index2 !== -1) { + listeners.splice(index2, 1); + } + if (listeners.length > 0) { + return; + } + arrayEvents.forEach((key) => { + delete array[key]; + }); + delete array._chartjs; +} +function _arrayUnique(items) { + const set3 = new Set(items); + if (set3.size === items.length) { + return items; + } + return Array.from(set3); +} +var requestAnimFrame = function() { + if (typeof window === "undefined") { + return function(callback3) { + return callback3(); + }; + } + return window.requestAnimationFrame; +}(); +function throttled(fn, thisArg) { + let argsToUse = []; + let ticking = false; + return function(...args) { + argsToUse = args; + if (!ticking) { + ticking = true; + requestAnimFrame.call(window, () => { + ticking = false; + fn.apply(thisArg, argsToUse); + }); + } + }; +} +function debounce(fn, delay) { + let timeout; + return function(...args) { + if (delay) { + clearTimeout(timeout); + timeout = setTimeout(fn, delay, args); + } else { + fn.apply(this, args); + } + return delay; + }; +} +var _toLeftRightCenter = (align) => align === "start" ? "left" : align === "end" ? "right" : "center"; +var _alignStartEnd = (align, start, end) => align === "start" ? start : align === "end" ? end : (start + end) / 2; +var _textX = (align, left, right, rtl) => { + const check = rtl ? "left" : "right"; + return align === check ? right : align === "center" ? (left + right) / 2 : left; +}; +function _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled) { + const pointCount = points.length; + let start = 0; + let count = pointCount; + if (meta._sorted) { + const { iScale, _parsed } = meta; + const axis = iScale.axis; + const { min, max, minDefined, maxDefined } = iScale.getUserBounds(); + if (minDefined) { + start = _limitValue(Math.min( + // @ts-expect-error Need to type _parsed + _lookupByKey(_parsed, axis, min).lo, + // @ts-expect-error Need to fix types on _lookupByKey + animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo + ), 0, pointCount - 1); + } + if (maxDefined) { + count = _limitValue(Math.max( + // @ts-expect-error Need to type _parsed + _lookupByKey(_parsed, iScale.axis, max, true).hi + 1, + // @ts-expect-error Need to fix types on _lookupByKey + animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max), true).hi + 1 + ), start, pointCount) - start; + } else { + count = pointCount - start; + } + } + return { + start, + count + }; +} +function _scaleRangesChanged(meta) { + const { xScale, yScale, _scaleRanges } = meta; + const newRanges = { + xmin: xScale.min, + xmax: xScale.max, + ymin: yScale.min, + ymax: yScale.max + }; + if (!_scaleRanges) { + meta._scaleRanges = newRanges; + return true; + } + const changed = _scaleRanges.xmin !== xScale.min || _scaleRanges.xmax !== xScale.max || _scaleRanges.ymin !== yScale.min || _scaleRanges.ymax !== yScale.max; + Object.assign(_scaleRanges, newRanges); + return changed; +} +var atEdge = (t) => t === 0 || t === 1; +var elasticIn = (t, s2, p) => -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s2) * TAU / p)); +var elasticOut = (t, s2, p) => Math.pow(2, -10 * t) * Math.sin((t - s2) * TAU / p) + 1; +var effects = { + linear: (t) => t, + easeInQuad: (t) => t * t, + easeOutQuad: (t) => -t * (t - 2), + easeInOutQuad: (t) => (t /= 0.5) < 1 ? 0.5 * t * t : -0.5 * (--t * (t - 2) - 1), + easeInCubic: (t) => t * t * t, + easeOutCubic: (t) => (t -= 1) * t * t + 1, + easeInOutCubic: (t) => (t /= 0.5) < 1 ? 0.5 * t * t * t : 0.5 * ((t -= 2) * t * t + 2), + easeInQuart: (t) => t * t * t * t, + easeOutQuart: (t) => -((t -= 1) * t * t * t - 1), + easeInOutQuart: (t) => (t /= 0.5) < 1 ? 0.5 * t * t * t * t : -0.5 * ((t -= 2) * t * t * t - 2), + easeInQuint: (t) => t * t * t * t * t, + easeOutQuint: (t) => (t -= 1) * t * t * t * t + 1, + easeInOutQuint: (t) => (t /= 0.5) < 1 ? 0.5 * t * t * t * t * t : 0.5 * ((t -= 2) * t * t * t * t + 2), + easeInSine: (t) => -Math.cos(t * HALF_PI) + 1, + easeOutSine: (t) => Math.sin(t * HALF_PI), + easeInOutSine: (t) => -0.5 * (Math.cos(PI * t) - 1), + easeInExpo: (t) => t === 0 ? 0 : Math.pow(2, 10 * (t - 1)), + easeOutExpo: (t) => t === 1 ? 1 : -Math.pow(2, -10 * t) + 1, + easeInOutExpo: (t) => atEdge(t) ? t : t < 0.5 ? 0.5 * Math.pow(2, 10 * (t * 2 - 1)) : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2), + easeInCirc: (t) => t >= 1 ? t : -(Math.sqrt(1 - t * t) - 1), + easeOutCirc: (t) => Math.sqrt(1 - (t -= 1) * t), + easeInOutCirc: (t) => (t /= 0.5) < 1 ? -0.5 * (Math.sqrt(1 - t * t) - 1) : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1), + easeInElastic: (t) => atEdge(t) ? t : elasticIn(t, 0.075, 0.3), + easeOutElastic: (t) => atEdge(t) ? t : elasticOut(t, 0.075, 0.3), + easeInOutElastic(t) { + const s2 = 0.1125; + const p = 0.45; + return atEdge(t) ? t : t < 0.5 ? 0.5 * elasticIn(t * 2, s2, p) : 0.5 + 0.5 * elasticOut(t * 2 - 1, s2, p); + }, + easeInBack(t) { + const s2 = 1.70158; + return t * t * ((s2 + 1) * t - s2); + }, + easeOutBack(t) { + const s2 = 1.70158; + return (t -= 1) * t * ((s2 + 1) * t + s2) + 1; + }, + easeInOutBack(t) { + let s2 = 1.70158; + if ((t /= 0.5) < 1) { + return 0.5 * (t * t * (((s2 *= 1.525) + 1) * t - s2)); + } + return 0.5 * ((t -= 2) * t * (((s2 *= 1.525) + 1) * t + s2) + 2); + }, + easeInBounce: (t) => 1 - effects.easeOutBounce(1 - t), + easeOutBounce(t) { + const m = 7.5625; + const d = 2.75; + if (t < 1 / d) { + return m * t * t; + } + if (t < 2 / d) { + return m * (t -= 1.5 / d) * t + 0.75; + } + if (t < 2.5 / d) { + return m * (t -= 2.25 / d) * t + 0.9375; + } + return m * (t -= 2.625 / d) * t + 0.984375; + }, + easeInOutBounce: (t) => t < 0.5 ? effects.easeInBounce(t * 2) * 0.5 : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5 +}; +function isPatternOrGradient(value) { + if (value && typeof value === "object") { + const type = value.toString(); + return type === "[object CanvasPattern]" || type === "[object CanvasGradient]"; + } + return false; +} +function color(value) { + return isPatternOrGradient(value) ? value : new Color(value); +} +function getHoverColor(value) { + return isPatternOrGradient(value) ? value : new Color(value).saturate(0.5).darken(0.1).hexString(); +} +var numbers = [ + "x", + "y", + "borderWidth", + "radius", + "tension" +]; +var colors = [ + "color", + "borderColor", + "backgroundColor" +]; +function applyAnimationsDefaults(defaults3) { + defaults3.set("animation", { + delay: void 0, + duration: 1e3, + easing: "easeOutQuart", + fn: void 0, + from: void 0, + loop: void 0, + to: void 0, + type: void 0 + }); + defaults3.describe("animation", { + _fallback: false, + _indexable: false, + _scriptable: (name) => name !== "onProgress" && name !== "onComplete" && name !== "fn" + }); + defaults3.set("animations", { + colors: { + type: "color", + properties: colors + }, + numbers: { + type: "number", + properties: numbers + } + }); + defaults3.describe("animations", { + _fallback: "animation" + }); + defaults3.set("transitions", { + active: { + animation: { + duration: 400 + } + }, + resize: { + animation: { + duration: 0 + } + }, + show: { + animations: { + colors: { + from: "transparent" + }, + visible: { + type: "boolean", + duration: 0 + } + } + }, + hide: { + animations: { + colors: { + to: "transparent" + }, + visible: { + type: "boolean", + easing: "linear", + fn: (v) => v | 0 + } + } + } + }); +} +function applyLayoutsDefaults(defaults3) { + defaults3.set("layout", { + autoPadding: true, + padding: { + top: 0, + right: 0, + bottom: 0, + left: 0 + } + }); +} +var intlCache = /* @__PURE__ */ new Map(); +function getNumberFormat(locale, options) { + options = options || {}; + const cacheKey = locale + JSON.stringify(options); + let formatter = intlCache.get(cacheKey); + if (!formatter) { + formatter = new Intl.NumberFormat(locale, options); + intlCache.set(cacheKey, formatter); + } + return formatter; +} +function formatNumber(num, locale, options) { + return getNumberFormat(locale, options).format(num); +} +var formatters = { + values(value) { + return isArray(value) ? value : "" + value; + }, + numeric(tickValue, index2, ticks) { + if (tickValue === 0) { + return "0"; + } + const locale = this.chart.options.locale; + let notation; + let delta = tickValue; + if (ticks.length > 1) { + const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value)); + if (maxTick < 1e-4 || maxTick > 1e15) { + notation = "scientific"; + } + delta = calculateDelta(tickValue, ticks); + } + const logDelta = log10(Math.abs(delta)); + const numDecimal = isNaN(logDelta) ? 1 : Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0); + const options = { + notation, + minimumFractionDigits: numDecimal, + maximumFractionDigits: numDecimal + }; + Object.assign(options, this.options.ticks.format); + return formatNumber(tickValue, locale, options); + }, + logarithmic(tickValue, index2, ticks) { + if (tickValue === 0) { + return "0"; + } + const remain = ticks[index2].significand || tickValue / Math.pow(10, Math.floor(log10(tickValue))); + if ([ + 1, + 2, + 3, + 5, + 10, + 15 + ].includes(remain) || index2 > 0.8 * ticks.length) { + return formatters.numeric.call(this, tickValue, index2, ticks); + } + return ""; + } +}; +function calculateDelta(tickValue, ticks) { + let delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value; + if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) { + delta = tickValue - Math.floor(tickValue); + } + return delta; +} +var Ticks = { + formatters +}; +function applyScaleDefaults(defaults3) { + defaults3.set("scale", { + display: true, + offset: false, + reverse: false, + beginAtZero: false, + bounds: "ticks", + clip: true, + grace: 0, + grid: { + display: true, + lineWidth: 1, + drawOnChartArea: true, + drawTicks: true, + tickLength: 8, + tickWidth: (_ctx, options) => options.lineWidth, + tickColor: (_ctx, options) => options.color, + offset: false + }, + border: { + display: true, + dash: [], + dashOffset: 0, + width: 1 + }, + title: { + display: false, + text: "", + padding: { + top: 4, + bottom: 4 + } + }, + ticks: { + minRotation: 0, + maxRotation: 50, + mirror: false, + textStrokeWidth: 0, + textStrokeColor: "", + padding: 3, + display: true, + autoSkip: true, + autoSkipPadding: 3, + labelOffset: 0, + callback: Ticks.formatters.values, + minor: {}, + major: {}, + align: "center", + crossAlign: "near", + showLabelBackdrop: false, + backdropColor: "rgba(255, 255, 255, 0.75)", + backdropPadding: 2 + } + }); + defaults3.route("scale.ticks", "color", "", "color"); + defaults3.route("scale.grid", "color", "", "borderColor"); + defaults3.route("scale.border", "color", "", "borderColor"); + defaults3.route("scale.title", "color", "", "color"); + defaults3.describe("scale", { + _fallback: false, + _scriptable: (name) => !name.startsWith("before") && !name.startsWith("after") && name !== "callback" && name !== "parser", + _indexable: (name) => name !== "borderDash" && name !== "tickBorderDash" && name !== "dash" + }); + defaults3.describe("scales", { + _fallback: "scale" + }); + defaults3.describe("scale.ticks", { + _scriptable: (name) => name !== "backdropPadding" && name !== "callback", + _indexable: (name) => name !== "backdropPadding" + }); +} +var overrides = /* @__PURE__ */ Object.create(null); +var descriptors = /* @__PURE__ */ Object.create(null); +function getScope$1(node, key) { + if (!key) { + return node; + } + const keys = key.split("."); + for (let i = 0, n2 = keys.length; i < n2; ++i) { + const k = keys[i]; + node = node[k] || (node[k] = /* @__PURE__ */ Object.create(null)); + } + return node; +} +function set(root, scope, values) { + if (typeof scope === "string") { + return merge(getScope$1(root, scope), values); + } + return merge(getScope$1(root, ""), scope); +} +var Defaults = class { + constructor(_descriptors3, _appliers) { + this.animation = void 0; + this.backgroundColor = "rgba(0,0,0,0.1)"; + this.borderColor = "rgba(0,0,0,0.1)"; + this.color = "#666"; + this.datasets = {}; + this.devicePixelRatio = (context) => context.chart.platform.getDevicePixelRatio(); + this.elements = {}; + this.events = [ + "mousemove", + "mouseout", + "click", + "touchstart", + "touchmove" + ]; + this.font = { + family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + size: 12, + style: "normal", + lineHeight: 1.2, + weight: null + }; + this.hover = {}; + this.hoverBackgroundColor = (ctx, options) => getHoverColor(options.backgroundColor); + this.hoverBorderColor = (ctx, options) => getHoverColor(options.borderColor); + this.hoverColor = (ctx, options) => getHoverColor(options.color); + this.indexAxis = "x"; + this.interaction = { + mode: "nearest", + intersect: true, + includeInvisible: false + }; + this.maintainAspectRatio = true; + this.onHover = null; + this.onClick = null; + this.parsing = true; + this.plugins = {}; + this.responsive = true; + this.scale = void 0; + this.scales = {}; + this.showLine = true; + this.drawActiveElementsOnTop = true; + this.describe(_descriptors3); + this.apply(_appliers); + } + set(scope, values) { + return set(this, scope, values); + } + get(scope) { + return getScope$1(this, scope); + } + describe(scope, values) { + return set(descriptors, scope, values); + } + override(scope, values) { + return set(overrides, scope, values); + } + route(scope, name, targetScope, targetName) { + const scopeObject = getScope$1(this, scope); + const targetScopeObject = getScope$1(this, targetScope); + const privateName = "_" + name; + Object.defineProperties(scopeObject, { + [privateName]: { + value: scopeObject[name], + writable: true + }, + [name]: { + enumerable: true, + get() { + const local = this[privateName]; + const target = targetScopeObject[targetName]; + if (isObject(local)) { + return Object.assign({}, target, local); + } + return valueOrDefault(local, target); + }, + set(value) { + this[privateName] = value; + } + } + }); + } + apply(appliers) { + appliers.forEach((apply) => apply(this)); + } +}; +var defaults = /* @__PURE__ */ new Defaults({ + _scriptable: (name) => !name.startsWith("on"), + _indexable: (name) => name !== "events", + hover: { + _fallback: "interaction" + }, + interaction: { + _scriptable: false, + _indexable: false + } +}, [ + applyAnimationsDefaults, + applyLayoutsDefaults, + applyScaleDefaults +]); +function toFontString(font) { + if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) { + return null; + } + return (font.style ? font.style + " " : "") + (font.weight ? font.weight + " " : "") + font.size + "px " + font.family; +} +function _measureText(ctx, data, gc, longest, string) { + let textWidth = data[string]; + if (!textWidth) { + textWidth = data[string] = ctx.measureText(string).width; + gc.push(string); + } + if (textWidth > longest) { + longest = textWidth; + } + return longest; +} +function _longestText(ctx, font, arrayOfThings, cache) { + cache = cache || {}; + let data = cache.data = cache.data || {}; + let gc = cache.garbageCollect = cache.garbageCollect || []; + if (cache.font !== font) { + data = cache.data = {}; + gc = cache.garbageCollect = []; + cache.font = font; + } + ctx.save(); + ctx.font = font; + let longest = 0; + const ilen = arrayOfThings.length; + let i, j, jlen, thing, nestedThing; + for (i = 0; i < ilen; i++) { + thing = arrayOfThings[i]; + if (thing !== void 0 && thing !== null && !isArray(thing)) { + longest = _measureText(ctx, data, gc, longest, thing); + } else if (isArray(thing)) { + for (j = 0, jlen = thing.length; j < jlen; j++) { + nestedThing = thing[j]; + if (nestedThing !== void 0 && nestedThing !== null && !isArray(nestedThing)) { + longest = _measureText(ctx, data, gc, longest, nestedThing); + } + } + } + } + ctx.restore(); + const gcLen = gc.length / 2; + if (gcLen > arrayOfThings.length) { + for (i = 0; i < gcLen; i++) { + delete data[gc[i]]; + } + gc.splice(0, gcLen); + } + return longest; +} +function _alignPixel(chart, pixel, width) { + const devicePixelRatio = chart.currentDevicePixelRatio; + const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0; + return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth; +} +function clearCanvas(canvas, ctx) { + ctx = ctx || canvas.getContext("2d"); + ctx.save(); + ctx.resetTransform(); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.restore(); +} +function drawPoint(ctx, options, x, y) { + drawPointLegend(ctx, options, x, y, null); +} +function drawPointLegend(ctx, options, x, y, w) { + let type, xOffset, yOffset, size, cornerRadius, width, xOffsetW, yOffsetW; + const style = options.pointStyle; + const rotation = options.rotation; + const radius = options.radius; + let rad = (rotation || 0) * RAD_PER_DEG; + if (style && typeof style === "object") { + type = style.toString(); + if (type === "[object HTMLImageElement]" || type === "[object HTMLCanvasElement]") { + ctx.save(); + ctx.translate(x, y); + ctx.rotate(rad); + ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height); + ctx.restore(); + return; + } + } + if (isNaN(radius) || radius <= 0) { + return; + } + ctx.beginPath(); + switch (style) { + default: + if (w) { + ctx.ellipse(x, y, w / 2, radius, 0, 0, TAU); + } else { + ctx.arc(x, y, radius, 0, TAU); + } + ctx.closePath(); + break; + case "triangle": + width = w ? w / 2 : radius; + ctx.moveTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius); + rad += TWO_THIRDS_PI; + ctx.lineTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius); + rad += TWO_THIRDS_PI; + ctx.lineTo(x + Math.sin(rad) * width, y - Math.cos(rad) * radius); + ctx.closePath(); + break; + case "rectRounded": + cornerRadius = radius * 0.516; + size = radius - cornerRadius; + xOffset = Math.cos(rad + QUARTER_PI) * size; + xOffsetW = Math.cos(rad + QUARTER_PI) * (w ? w / 2 - cornerRadius : size); + yOffset = Math.sin(rad + QUARTER_PI) * size; + yOffsetW = Math.sin(rad + QUARTER_PI) * (w ? w / 2 - cornerRadius : size); + ctx.arc(x - xOffsetW, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI); + ctx.arc(x + yOffsetW, y - xOffset, cornerRadius, rad - HALF_PI, rad); + ctx.arc(x + xOffsetW, y + yOffset, cornerRadius, rad, rad + HALF_PI); + ctx.arc(x - yOffsetW, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI); + ctx.closePath(); + break; + case "rect": + if (!rotation) { + size = Math.SQRT1_2 * radius; + width = w ? w / 2 : size; + ctx.rect(x - width, y - size, 2 * width, 2 * size); + break; + } + rad += QUARTER_PI; + case "rectRot": + xOffsetW = Math.cos(rad) * (w ? w / 2 : radius); + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + yOffsetW = Math.sin(rad) * (w ? w / 2 : radius); + ctx.moveTo(x - xOffsetW, y - yOffset); + ctx.lineTo(x + yOffsetW, y - xOffset); + ctx.lineTo(x + xOffsetW, y + yOffset); + ctx.lineTo(x - yOffsetW, y + xOffset); + ctx.closePath(); + break; + case "crossRot": + rad += QUARTER_PI; + case "cross": + xOffsetW = Math.cos(rad) * (w ? w / 2 : radius); + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + yOffsetW = Math.sin(rad) * (w ? w / 2 : radius); + ctx.moveTo(x - xOffsetW, y - yOffset); + ctx.lineTo(x + xOffsetW, y + yOffset); + ctx.moveTo(x + yOffsetW, y - xOffset); + ctx.lineTo(x - yOffsetW, y + xOffset); + break; + case "star": + xOffsetW = Math.cos(rad) * (w ? w / 2 : radius); + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + yOffsetW = Math.sin(rad) * (w ? w / 2 : radius); + ctx.moveTo(x - xOffsetW, y - yOffset); + ctx.lineTo(x + xOffsetW, y + yOffset); + ctx.moveTo(x + yOffsetW, y - xOffset); + ctx.lineTo(x - yOffsetW, y + xOffset); + rad += QUARTER_PI; + xOffsetW = Math.cos(rad) * (w ? w / 2 : radius); + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + yOffsetW = Math.sin(rad) * (w ? w / 2 : radius); + ctx.moveTo(x - xOffsetW, y - yOffset); + ctx.lineTo(x + xOffsetW, y + yOffset); + ctx.moveTo(x + yOffsetW, y - xOffset); + ctx.lineTo(x - yOffsetW, y + xOffset); + break; + case "line": + xOffset = w ? w / 2 : Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + xOffset, y + yOffset); + break; + case "dash": + ctx.moveTo(x, y); + ctx.lineTo(x + Math.cos(rad) * (w ? w / 2 : radius), y + Math.sin(rad) * radius); + break; + case false: + ctx.closePath(); + break; + } + ctx.fill(); + if (options.borderWidth > 0) { + ctx.stroke(); + } +} +function _isPointInArea(point, area, margin) { + margin = margin || 0.5; + return !area || point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin; +} +function clipArea(ctx, area) { + ctx.save(); + ctx.beginPath(); + ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); + ctx.clip(); +} +function unclipArea(ctx) { + ctx.restore(); +} +function _steppedLineTo(ctx, previous, target, flip, mode) { + if (!previous) { + return ctx.lineTo(target.x, target.y); + } + if (mode === "middle") { + const midpoint = (previous.x + target.x) / 2; + ctx.lineTo(midpoint, previous.y); + ctx.lineTo(midpoint, target.y); + } else if (mode === "after" !== !!flip) { + ctx.lineTo(previous.x, target.y); + } else { + ctx.lineTo(target.x, previous.y); + } + ctx.lineTo(target.x, target.y); +} +function _bezierCurveTo(ctx, previous, target, flip) { + if (!previous) { + return ctx.lineTo(target.x, target.y); + } + ctx.bezierCurveTo(flip ? previous.cp1x : previous.cp2x, flip ? previous.cp1y : previous.cp2y, flip ? target.cp2x : target.cp1x, flip ? target.cp2y : target.cp1y, target.x, target.y); +} +function setRenderOpts(ctx, opts) { + if (opts.translation) { + ctx.translate(opts.translation[0], opts.translation[1]); + } + if (!isNullOrUndef(opts.rotation)) { + ctx.rotate(opts.rotation); + } + if (opts.color) { + ctx.fillStyle = opts.color; + } + if (opts.textAlign) { + ctx.textAlign = opts.textAlign; + } + if (opts.textBaseline) { + ctx.textBaseline = opts.textBaseline; + } +} +function decorateText(ctx, x, y, line, opts) { + if (opts.strikethrough || opts.underline) { + const metrics = ctx.measureText(line); + const left = x - metrics.actualBoundingBoxLeft; + const right = x + metrics.actualBoundingBoxRight; + const top = y - metrics.actualBoundingBoxAscent; + const bottom = y + metrics.actualBoundingBoxDescent; + const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom; + ctx.strokeStyle = ctx.fillStyle; + ctx.beginPath(); + ctx.lineWidth = opts.decorationWidth || 2; + ctx.moveTo(left, yDecoration); + ctx.lineTo(right, yDecoration); + ctx.stroke(); + } +} +function drawBackdrop(ctx, opts) { + const oldColor = ctx.fillStyle; + ctx.fillStyle = opts.color; + ctx.fillRect(opts.left, opts.top, opts.width, opts.height); + ctx.fillStyle = oldColor; +} +function renderText(ctx, text, x, y, font, opts = {}) { + const lines = isArray(text) ? text : [ + text + ]; + const stroke = opts.strokeWidth > 0 && opts.strokeColor !== ""; + let i, line; + ctx.save(); + ctx.font = font.string; + setRenderOpts(ctx, opts); + for (i = 0; i < lines.length; ++i) { + line = lines[i]; + if (opts.backdrop) { + drawBackdrop(ctx, opts.backdrop); + } + if (stroke) { + if (opts.strokeColor) { + ctx.strokeStyle = opts.strokeColor; + } + if (!isNullOrUndef(opts.strokeWidth)) { + ctx.lineWidth = opts.strokeWidth; + } + ctx.strokeText(line, x, y, opts.maxWidth); + } + ctx.fillText(line, x, y, opts.maxWidth); + decorateText(ctx, x, y, line, opts); + y += Number(font.lineHeight); + } + ctx.restore(); +} +function addRoundedRectPath(ctx, rect) { + const { x, y, w, h, radius } = rect; + ctx.arc(x + radius.topLeft, y + radius.topLeft, radius.topLeft, 1.5 * PI, PI, true); + ctx.lineTo(x, y + h - radius.bottomLeft); + ctx.arc(x + radius.bottomLeft, y + h - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true); + ctx.lineTo(x + w - radius.bottomRight, y + h); + ctx.arc(x + w - radius.bottomRight, y + h - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true); + ctx.lineTo(x + w, y + radius.topRight); + ctx.arc(x + w - radius.topRight, y + radius.topRight, radius.topRight, 0, -HALF_PI, true); + ctx.lineTo(x + radius.topLeft, y); +} +var LINE_HEIGHT = /^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/; +var FONT_STYLE = /^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/; +function toLineHeight(value, size) { + const matches = ("" + value).match(LINE_HEIGHT); + if (!matches || matches[1] === "normal") { + return size * 1.2; + } + value = +matches[2]; + switch (matches[3]) { + case "px": + return value; + case "%": + value /= 100; + break; + } + return size * value; +} +var numberOrZero = (v) => +v || 0; +function _readValueToProps(value, props) { + const ret = {}; + const objProps = isObject(props); + const keys = objProps ? Object.keys(props) : props; + const read = isObject(value) ? objProps ? (prop) => valueOrDefault(value[prop], value[props[prop]]) : (prop) => value[prop] : () => value; + for (const prop of keys) { + ret[prop] = numberOrZero(read(prop)); + } + return ret; +} +function toTRBL(value) { + return _readValueToProps(value, { + top: "y", + right: "x", + bottom: "y", + left: "x" + }); +} +function toTRBLCorners(value) { + return _readValueToProps(value, [ + "topLeft", + "topRight", + "bottomLeft", + "bottomRight" + ]); +} +function toPadding(value) { + const obj = toTRBL(value); + obj.width = obj.left + obj.right; + obj.height = obj.top + obj.bottom; + return obj; +} +function toFont(options, fallback) { + options = options || {}; + fallback = fallback || defaults.font; + let size = valueOrDefault(options.size, fallback.size); + if (typeof size === "string") { + size = parseInt(size, 10); + } + let style = valueOrDefault(options.style, fallback.style); + if (style && !("" + style).match(FONT_STYLE)) { + console.warn('Invalid font style specified: "' + style + '"'); + style = void 0; + } + const font = { + family: valueOrDefault(options.family, fallback.family), + lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size), + size, + style, + weight: valueOrDefault(options.weight, fallback.weight), + string: "" + }; + font.string = toFontString(font); + return font; +} +function resolve(inputs, context, index2, info) { + let cacheable = true; + let i, ilen, value; + for (i = 0, ilen = inputs.length; i < ilen; ++i) { + value = inputs[i]; + if (value === void 0) { + continue; + } + if (context !== void 0 && typeof value === "function") { + value = value(context); + cacheable = false; + } + if (index2 !== void 0 && isArray(value)) { + value = value[index2 % value.length]; + cacheable = false; + } + if (value !== void 0) { + if (info && !cacheable) { + info.cacheable = false; + } + return value; + } + } +} +function _addGrace(minmax, grace, beginAtZero) { + const { min, max } = minmax; + const change = toDimension(grace, (max - min) / 2); + const keepZero = (value, add) => beginAtZero && value === 0 ? 0 : value + add; + return { + min: keepZero(min, -Math.abs(change)), + max: keepZero(max, change) + }; +} +function createContext(parentContext, context) { + return Object.assign(Object.create(parentContext), context); +} +function _createResolver(scopes, prefixes = [ + "" +], rootScopes, fallback, getTarget = () => scopes[0]) { + const finalRootScopes = rootScopes || scopes; + if (typeof fallback === "undefined") { + fallback = _resolve("_fallback", scopes); + } + const cache = { + [Symbol.toStringTag]: "Object", + _cacheable: true, + _scopes: scopes, + _rootScopes: finalRootScopes, + _fallback: fallback, + _getTarget: getTarget, + override: (scope) => _createResolver([ + scope, + ...scopes + ], prefixes, finalRootScopes, fallback) + }; + return new Proxy(cache, { + /** + * A trap for the delete operator. + */ + deleteProperty(target, prop) { + delete target[prop]; + delete target._keys; + delete scopes[0][prop]; + return true; + }, + /** + * A trap for getting property values. + */ + get(target, prop) { + return _cached(target, prop, () => _resolveWithPrefixes(prop, prefixes, scopes, target)); + }, + /** + * A trap for Object.getOwnPropertyDescriptor. + * Also used by Object.hasOwnProperty. + */ + getOwnPropertyDescriptor(target, prop) { + return Reflect.getOwnPropertyDescriptor(target._scopes[0], prop); + }, + /** + * A trap for Object.getPrototypeOf. + */ + getPrototypeOf() { + return Reflect.getPrototypeOf(scopes[0]); + }, + /** + * A trap for the in operator. + */ + has(target, prop) { + return getKeysFromAllScopes(target).includes(prop); + }, + /** + * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols. + */ + ownKeys(target) { + return getKeysFromAllScopes(target); + }, + /** + * A trap for setting property values. + */ + set(target, prop, value) { + const storage = target._storage || (target._storage = getTarget()); + target[prop] = storage[prop] = value; + delete target._keys; + return true; + } + }); +} +function _attachContext(proxy, context, subProxy, descriptorDefaults) { + const cache = { + _cacheable: false, + _proxy: proxy, + _context: context, + _subProxy: subProxy, + _stack: /* @__PURE__ */ new Set(), + _descriptors: _descriptors(proxy, descriptorDefaults), + setContext: (ctx) => _attachContext(proxy, ctx, subProxy, descriptorDefaults), + override: (scope) => _attachContext(proxy.override(scope), context, subProxy, descriptorDefaults) + }; + return new Proxy(cache, { + /** + * A trap for the delete operator. + */ + deleteProperty(target, prop) { + delete target[prop]; + delete proxy[prop]; + return true; + }, + /** + * A trap for getting property values. + */ + get(target, prop, receiver) { + return _cached(target, prop, () => _resolveWithContext(target, prop, receiver)); + }, + /** + * A trap for Object.getOwnPropertyDescriptor. + * Also used by Object.hasOwnProperty. + */ + getOwnPropertyDescriptor(target, prop) { + return target._descriptors.allKeys ? Reflect.has(proxy, prop) ? { + enumerable: true, + configurable: true + } : void 0 : Reflect.getOwnPropertyDescriptor(proxy, prop); + }, + /** + * A trap for Object.getPrototypeOf. + */ + getPrototypeOf() { + return Reflect.getPrototypeOf(proxy); + }, + /** + * A trap for the in operator. + */ + has(target, prop) { + return Reflect.has(proxy, prop); + }, + /** + * A trap for Object.getOwnPropertyNames and Object.getOwnPropertySymbols. + */ + ownKeys() { + return Reflect.ownKeys(proxy); + }, + /** + * A trap for setting property values. + */ + set(target, prop, value) { + proxy[prop] = value; + delete target[prop]; + return true; + } + }); +} +function _descriptors(proxy, defaults3 = { + scriptable: true, + indexable: true +}) { + const { _scriptable = defaults3.scriptable, _indexable = defaults3.indexable, _allKeys = defaults3.allKeys } = proxy; + return { + allKeys: _allKeys, + scriptable: _scriptable, + indexable: _indexable, + isScriptable: isFunction(_scriptable) ? _scriptable : () => _scriptable, + isIndexable: isFunction(_indexable) ? _indexable : () => _indexable + }; +} +var readKey = (prefix, name) => prefix ? prefix + _capitalize(name) : name; +var needsSubResolver = (prop, value) => isObject(value) && prop !== "adapters" && (Object.getPrototypeOf(value) === null || value.constructor === Object); +function _cached(target, prop, resolve3) { + if (Object.prototype.hasOwnProperty.call(target, prop)) { + return target[prop]; + } + const value = resolve3(); + target[prop] = value; + return value; +} +function _resolveWithContext(target, prop, receiver) { + const { _proxy, _context, _subProxy, _descriptors: descriptors3 } = target; + let value = _proxy[prop]; + if (isFunction(value) && descriptors3.isScriptable(prop)) { + value = _resolveScriptable(prop, value, target, receiver); + } + if (isArray(value) && value.length) { + value = _resolveArray(prop, value, target, descriptors3.isIndexable); + } + if (needsSubResolver(prop, value)) { + value = _attachContext(value, _context, _subProxy && _subProxy[prop], descriptors3); + } + return value; +} +function _resolveScriptable(prop, getValue, target, receiver) { + const { _proxy, _context, _subProxy, _stack } = target; + if (_stack.has(prop)) { + throw new Error("Recursion detected: " + Array.from(_stack).join("->") + "->" + prop); + } + _stack.add(prop); + let value = getValue(_context, _subProxy || receiver); + _stack.delete(prop); + if (needsSubResolver(prop, value)) { + value = createSubResolver(_proxy._scopes, _proxy, prop, value); + } + return value; +} +function _resolveArray(prop, value, target, isIndexable) { + const { _proxy, _context, _subProxy, _descriptors: descriptors3 } = target; + if (typeof _context.index !== "undefined" && isIndexable(prop)) { + return value[_context.index % value.length]; + } else if (isObject(value[0])) { + const arr = value; + const scopes = _proxy._scopes.filter((s2) => s2 !== arr); + value = []; + for (const item of arr) { + const resolver = createSubResolver(scopes, _proxy, prop, item); + value.push(_attachContext(resolver, _context, _subProxy && _subProxy[prop], descriptors3)); + } + } + return value; +} +function resolveFallback(fallback, prop, value) { + return isFunction(fallback) ? fallback(prop, value) : fallback; +} +var getScope = (key, parent) => key === true ? parent : typeof key === "string" ? resolveObjectKey(parent, key) : void 0; +function addScopes(set3, parentScopes, key, parentFallback, value) { + for (const parent of parentScopes) { + const scope = getScope(key, parent); + if (scope) { + set3.add(scope); + const fallback = resolveFallback(scope._fallback, key, value); + if (typeof fallback !== "undefined" && fallback !== key && fallback !== parentFallback) { + return fallback; + } + } else if (scope === false && typeof parentFallback !== "undefined" && key !== parentFallback) { + return null; + } + } + return false; +} +function createSubResolver(parentScopes, resolver, prop, value) { + const rootScopes = resolver._rootScopes; + const fallback = resolveFallback(resolver._fallback, prop, value); + const allScopes = [ + ...parentScopes, + ...rootScopes + ]; + const set3 = /* @__PURE__ */ new Set(); + set3.add(value); + let key = addScopesFromKey(set3, allScopes, prop, fallback || prop, value); + if (key === null) { + return false; + } + if (typeof fallback !== "undefined" && fallback !== prop) { + key = addScopesFromKey(set3, allScopes, fallback, key, value); + if (key === null) { + return false; + } + } + return _createResolver(Array.from(set3), [ + "" + ], rootScopes, fallback, () => subGetTarget(resolver, prop, value)); +} +function addScopesFromKey(set3, allScopes, key, fallback, item) { + while (key) { + key = addScopes(set3, allScopes, key, fallback, item); + } + return key; +} +function subGetTarget(resolver, prop, value) { + const parent = resolver._getTarget(); + if (!(prop in parent)) { + parent[prop] = {}; + } + const target = parent[prop]; + if (isArray(target) && isObject(value)) { + return value; + } + return target || {}; +} +function _resolveWithPrefixes(prop, prefixes, scopes, proxy) { + let value; + for (const prefix of prefixes) { + value = _resolve(readKey(prefix, prop), scopes); + if (typeof value !== "undefined") { + return needsSubResolver(prop, value) ? createSubResolver(scopes, proxy, prop, value) : value; + } + } +} +function _resolve(key, scopes) { + for (const scope of scopes) { + if (!scope) { + continue; + } + const value = scope[key]; + if (typeof value !== "undefined") { + return value; + } + } +} +function getKeysFromAllScopes(target) { + let keys = target._keys; + if (!keys) { + keys = target._keys = resolveKeysFromAllScopes(target._scopes); + } + return keys; +} +function resolveKeysFromAllScopes(scopes) { + const set3 = /* @__PURE__ */ new Set(); + for (const scope of scopes) { + for (const key of Object.keys(scope).filter((k) => !k.startsWith("_"))) { + set3.add(key); + } + } + return Array.from(set3); +} +function _parseObjectDataRadialScale(meta, data, start, count) { + const { iScale } = meta; + const { key = "r" } = this._parsing; + const parsed = new Array(count); + let i, ilen, index2, item; + for (i = 0, ilen = count; i < ilen; ++i) { + index2 = i + start; + item = data[index2]; + parsed[i] = { + r: iScale.parse(resolveObjectKey(item, key), index2) + }; + } + return parsed; +} +var EPSILON = Number.EPSILON || 1e-14; +var getPoint = (points, i) => i < points.length && !points[i].skip && points[i]; +var getValueAxis = (indexAxis) => indexAxis === "x" ? "y" : "x"; +function splineCurve(firstPoint, middlePoint, afterPoint, t) { + const previous = firstPoint.skip ? middlePoint : firstPoint; + const current = middlePoint; + const next = afterPoint.skip ? middlePoint : afterPoint; + const d01 = distanceBetweenPoints(current, previous); + const d12 = distanceBetweenPoints(next, current); + let s01 = d01 / (d01 + d12); + let s12 = d12 / (d01 + d12); + s01 = isNaN(s01) ? 0 : s01; + s12 = isNaN(s12) ? 0 : s12; + const fa = t * s01; + const fb = t * s12; + return { + previous: { + x: current.x - fa * (next.x - previous.x), + y: current.y - fa * (next.y - previous.y) + }, + next: { + x: current.x + fb * (next.x - previous.x), + y: current.y + fb * (next.y - previous.y) + } + }; +} +function monotoneAdjust(points, deltaK, mK) { + const pointsLen = points.length; + let alphaK, betaK, tauK, squaredMagnitude, pointCurrent; + let pointAfter = getPoint(points, 0); + for (let i = 0; i < pointsLen - 1; ++i) { + pointCurrent = pointAfter; + pointAfter = getPoint(points, i + 1); + if (!pointCurrent || !pointAfter) { + continue; + } + if (almostEquals(deltaK[i], 0, EPSILON)) { + mK[i] = mK[i + 1] = 0; + continue; + } + alphaK = mK[i] / deltaK[i]; + betaK = mK[i + 1] / deltaK[i]; + squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2); + if (squaredMagnitude <= 9) { + continue; + } + tauK = 3 / Math.sqrt(squaredMagnitude); + mK[i] = alphaK * tauK * deltaK[i]; + mK[i + 1] = betaK * tauK * deltaK[i]; + } +} +function monotoneCompute(points, mK, indexAxis = "x") { + const valueAxis = getValueAxis(indexAxis); + const pointsLen = points.length; + let delta, pointBefore, pointCurrent; + let pointAfter = getPoint(points, 0); + for (let i = 0; i < pointsLen; ++i) { + pointBefore = pointCurrent; + pointCurrent = pointAfter; + pointAfter = getPoint(points, i + 1); + if (!pointCurrent) { + continue; + } + const iPixel = pointCurrent[indexAxis]; + const vPixel = pointCurrent[valueAxis]; + if (pointBefore) { + delta = (iPixel - pointBefore[indexAxis]) / 3; + pointCurrent[`cp1${indexAxis}`] = iPixel - delta; + pointCurrent[`cp1${valueAxis}`] = vPixel - delta * mK[i]; + } + if (pointAfter) { + delta = (pointAfter[indexAxis] - iPixel) / 3; + pointCurrent[`cp2${indexAxis}`] = iPixel + delta; + pointCurrent[`cp2${valueAxis}`] = vPixel + delta * mK[i]; + } + } +} +function splineCurveMonotone(points, indexAxis = "x") { + const valueAxis = getValueAxis(indexAxis); + const pointsLen = points.length; + const deltaK = Array(pointsLen).fill(0); + const mK = Array(pointsLen); + let i, pointBefore, pointCurrent; + let pointAfter = getPoint(points, 0); + for (i = 0; i < pointsLen; ++i) { + pointBefore = pointCurrent; + pointCurrent = pointAfter; + pointAfter = getPoint(points, i + 1); + if (!pointCurrent) { + continue; + } + if (pointAfter) { + const slopeDelta = pointAfter[indexAxis] - pointCurrent[indexAxis]; + deltaK[i] = slopeDelta !== 0 ? (pointAfter[valueAxis] - pointCurrent[valueAxis]) / slopeDelta : 0; + } + mK[i] = !pointBefore ? deltaK[i] : !pointAfter ? deltaK[i - 1] : sign(deltaK[i - 1]) !== sign(deltaK[i]) ? 0 : (deltaK[i - 1] + deltaK[i]) / 2; + } + monotoneAdjust(points, deltaK, mK); + monotoneCompute(points, mK, indexAxis); +} +function capControlPoint(pt, min, max) { + return Math.max(Math.min(pt, max), min); +} +function capBezierPoints(points, area) { + let i, ilen, point, inArea, inAreaPrev; + let inAreaNext = _isPointInArea(points[0], area); + for (i = 0, ilen = points.length; i < ilen; ++i) { + inAreaPrev = inArea; + inArea = inAreaNext; + inAreaNext = i < ilen - 1 && _isPointInArea(points[i + 1], area); + if (!inArea) { + continue; + } + point = points[i]; + if (inAreaPrev) { + point.cp1x = capControlPoint(point.cp1x, area.left, area.right); + point.cp1y = capControlPoint(point.cp1y, area.top, area.bottom); + } + if (inAreaNext) { + point.cp2x = capControlPoint(point.cp2x, area.left, area.right); + point.cp2y = capControlPoint(point.cp2y, area.top, area.bottom); + } + } +} +function _updateBezierControlPoints(points, options, area, loop, indexAxis) { + let i, ilen, point, controlPoints; + if (options.spanGaps) { + points = points.filter((pt) => !pt.skip); + } + if (options.cubicInterpolationMode === "monotone") { + splineCurveMonotone(points, indexAxis); + } else { + let prev = loop ? points[points.length - 1] : points[0]; + for (i = 0, ilen = points.length; i < ilen; ++i) { + point = points[i]; + controlPoints = splineCurve(prev, point, points[Math.min(i + 1, ilen - (loop ? 0 : 1)) % ilen], options.tension); + point.cp1x = controlPoints.previous.x; + point.cp1y = controlPoints.previous.y; + point.cp2x = controlPoints.next.x; + point.cp2y = controlPoints.next.y; + prev = point; + } + } + if (options.capBezierPoints) { + capBezierPoints(points, area); + } +} +function _isDomSupported() { + return typeof window !== "undefined" && typeof document !== "undefined"; +} +function _getParentNode(domNode) { + let parent = domNode.parentNode; + if (parent && parent.toString() === "[object ShadowRoot]") { + parent = parent.host; + } + return parent; +} +function parseMaxStyle(styleValue, node, parentProperty) { + let valueInPixels; + if (typeof styleValue === "string") { + valueInPixels = parseInt(styleValue, 10); + if (styleValue.indexOf("%") !== -1) { + valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty]; + } + } else { + valueInPixels = styleValue; + } + return valueInPixels; +} +var getComputedStyle = (element) => element.ownerDocument.defaultView.getComputedStyle(element, null); +function getStyle(el, property) { + return getComputedStyle(el).getPropertyValue(property); +} +var positions = [ + "top", + "right", + "bottom", + "left" +]; +function getPositionedStyle(styles, style, suffix) { + const result = {}; + suffix = suffix ? "-" + suffix : ""; + for (let i = 0; i < 4; i++) { + const pos = positions[i]; + result[pos] = parseFloat(styles[style + "-" + pos + suffix]) || 0; + } + result.width = result.left + result.right; + result.height = result.top + result.bottom; + return result; +} +var useOffsetPos = (x, y, target) => (x > 0 || y > 0) && (!target || !target.shadowRoot); +function getCanvasPosition(e, canvas) { + const touches = e.touches; + const source = touches && touches.length ? touches[0] : e; + const { offsetX, offsetY } = source; + let box = false; + let x, y; + if (useOffsetPos(offsetX, offsetY, e.target)) { + x = offsetX; + y = offsetY; + } else { + const rect = canvas.getBoundingClientRect(); + x = source.clientX - rect.left; + y = source.clientY - rect.top; + box = true; + } + return { + x, + y, + box + }; +} +function getRelativePosition(event, chart) { + if ("native" in event) { + return event; + } + const { canvas, currentDevicePixelRatio } = chart; + const style = getComputedStyle(canvas); + const borderBox = style.boxSizing === "border-box"; + const paddings = getPositionedStyle(style, "padding"); + const borders = getPositionedStyle(style, "border", "width"); + const { x, y, box } = getCanvasPosition(event, canvas); + const xOffset = paddings.left + (box && borders.left); + const yOffset = paddings.top + (box && borders.top); + let { width, height } = chart; + if (borderBox) { + width -= paddings.width + borders.width; + height -= paddings.height + borders.height; + } + return { + x: Math.round((x - xOffset) / width * canvas.width / currentDevicePixelRatio), + y: Math.round((y - yOffset) / height * canvas.height / currentDevicePixelRatio) + }; +} +function getContainerSize(canvas, width, height) { + let maxWidth, maxHeight; + if (width === void 0 || height === void 0) { + const container = _getParentNode(canvas); + if (!container) { + width = canvas.clientWidth; + height = canvas.clientHeight; + } else { + const rect = container.getBoundingClientRect(); + const containerStyle = getComputedStyle(container); + const containerBorder = getPositionedStyle(containerStyle, "border", "width"); + const containerPadding = getPositionedStyle(containerStyle, "padding"); + width = rect.width - containerPadding.width - containerBorder.width; + height = rect.height - containerPadding.height - containerBorder.height; + maxWidth = parseMaxStyle(containerStyle.maxWidth, container, "clientWidth"); + maxHeight = parseMaxStyle(containerStyle.maxHeight, container, "clientHeight"); + } + } + return { + width, + height, + maxWidth: maxWidth || INFINITY, + maxHeight: maxHeight || INFINITY + }; +} +var round1 = (v) => Math.round(v * 10) / 10; +function getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) { + const style = getComputedStyle(canvas); + const margins = getPositionedStyle(style, "margin"); + const maxWidth = parseMaxStyle(style.maxWidth, canvas, "clientWidth") || INFINITY; + const maxHeight = parseMaxStyle(style.maxHeight, canvas, "clientHeight") || INFINITY; + const containerSize = getContainerSize(canvas, bbWidth, bbHeight); + let { width, height } = containerSize; + if (style.boxSizing === "content-box") { + const borders = getPositionedStyle(style, "border", "width"); + const paddings = getPositionedStyle(style, "padding"); + width -= paddings.width + borders.width; + height -= paddings.height + borders.height; + } + width = Math.max(0, width - margins.width); + height = Math.max(0, aspectRatio ? width / aspectRatio : height - margins.height); + width = round1(Math.min(width, maxWidth, containerSize.maxWidth)); + height = round1(Math.min(height, maxHeight, containerSize.maxHeight)); + if (width && !height) { + height = round1(width / 2); + } + const maintainHeight = bbWidth !== void 0 || bbHeight !== void 0; + if (maintainHeight && aspectRatio && containerSize.height && height > containerSize.height) { + height = containerSize.height; + width = round1(Math.floor(height * aspectRatio)); + } + return { + width, + height + }; +} +function retinaScale(chart, forceRatio, forceStyle) { + const pixelRatio = forceRatio || 1; + const deviceHeight = Math.floor(chart.height * pixelRatio); + const deviceWidth = Math.floor(chart.width * pixelRatio); + chart.height = Math.floor(chart.height); + chart.width = Math.floor(chart.width); + const canvas = chart.canvas; + if (canvas.style && (forceStyle || !canvas.style.height && !canvas.style.width)) { + canvas.style.height = `${chart.height}px`; + canvas.style.width = `${chart.width}px`; + } + if (chart.currentDevicePixelRatio !== pixelRatio || canvas.height !== deviceHeight || canvas.width !== deviceWidth) { + chart.currentDevicePixelRatio = pixelRatio; + canvas.height = deviceHeight; + canvas.width = deviceWidth; + chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); + return true; + } + return false; +} +var supportsEventListenerOptions = function() { + let passiveSupported = false; + try { + const options = { + get passive() { + passiveSupported = true; + return false; + } + }; + if (_isDomSupported()) { + window.addEventListener("test", null, options); + window.removeEventListener("test", null, options); + } + } catch (e) { + } + return passiveSupported; +}(); +function readUsedSize(element, property) { + const value = getStyle(element, property); + const matches = value && value.match(/^(\d+)(\.\d+)?px$/); + return matches ? +matches[1] : void 0; +} +function _pointInLine(p1, p2, t, mode) { + return { + x: p1.x + t * (p2.x - p1.x), + y: p1.y + t * (p2.y - p1.y) + }; +} +function _steppedInterpolation(p1, p2, t, mode) { + return { + x: p1.x + t * (p2.x - p1.x), + y: mode === "middle" ? t < 0.5 ? p1.y : p2.y : mode === "after" ? t < 1 ? p1.y : p2.y : t > 0 ? p2.y : p1.y + }; +} +function _bezierInterpolation(p1, p2, t, mode) { + const cp1 = { + x: p1.cp2x, + y: p1.cp2y + }; + const cp2 = { + x: p2.cp1x, + y: p2.cp1y + }; + const a = _pointInLine(p1, cp1, t); + const b = _pointInLine(cp1, cp2, t); + const c = _pointInLine(cp2, p2, t); + const d = _pointInLine(a, b, t); + const e = _pointInLine(b, c, t); + return _pointInLine(d, e, t); +} +var getRightToLeftAdapter = function(rectX, width) { + return { + x(x) { + return rectX + rectX + width - x; + }, + setWidth(w) { + width = w; + }, + textAlign(align) { + if (align === "center") { + return align; + } + return align === "right" ? "left" : "right"; + }, + xPlus(x, value) { + return x - value; + }, + leftForLtr(x, itemWidth) { + return x - itemWidth; + } + }; +}; +var getLeftToRightAdapter = function() { + return { + x(x) { + return x; + }, + setWidth(w) { + }, + textAlign(align) { + return align; + }, + xPlus(x, value) { + return x + value; + }, + leftForLtr(x, _itemWidth) { + return x; + } + }; +}; +function getRtlAdapter(rtl, rectX, width) { + return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter(); +} +function overrideTextDirection(ctx, direction) { + let style, original; + if (direction === "ltr" || direction === "rtl") { + style = ctx.canvas.style; + original = [ + style.getPropertyValue("direction"), + style.getPropertyPriority("direction") + ]; + style.setProperty("direction", direction, "important"); + ctx.prevTextDirection = original; + } +} +function restoreTextDirection(ctx, original) { + if (original !== void 0) { + delete ctx.prevTextDirection; + ctx.canvas.style.setProperty("direction", original[0], original[1]); + } +} +function propertyFn(property) { + if (property === "angle") { + return { + between: _angleBetween, + compare: _angleDiff, + normalize: _normalizeAngle + }; + } + return { + between: _isBetween, + compare: (a, b) => a - b, + normalize: (x) => x + }; +} +function normalizeSegment({ start, end, count, loop, style }) { + return { + start: start % count, + end: end % count, + loop: loop && (end - start + 1) % count === 0, + style + }; +} +function getSegment(segment, points, bounds) { + const { property, start: startBound, end: endBound } = bounds; + const { between, normalize } = propertyFn(property); + const count = points.length; + let { start, end, loop } = segment; + let i, ilen; + if (loop) { + start += count; + end += count; + for (i = 0, ilen = count; i < ilen; ++i) { + if (!between(normalize(points[start % count][property]), startBound, endBound)) { + break; + } + start--; + end--; + } + start %= count; + end %= count; + } + if (end < start) { + end += count; + } + return { + start, + end, + loop, + style: segment.style + }; +} +function _boundSegment(segment, points, bounds) { + if (!bounds) { + return [ + segment + ]; + } + const { property, start: startBound, end: endBound } = bounds; + const count = points.length; + const { compare, between, normalize } = propertyFn(property); + const { start, end, loop, style } = getSegment(segment, points, bounds); + const result = []; + let inside = false; + let subStart = null; + let value, point, prevValue; + const startIsBefore = () => between(startBound, prevValue, value) && compare(startBound, prevValue) !== 0; + const endIsBefore = () => compare(endBound, value) === 0 || between(endBound, prevValue, value); + const shouldStart = () => inside || startIsBefore(); + const shouldStop = () => !inside || endIsBefore(); + for (let i = start, prev = start; i <= end; ++i) { + point = points[i % count]; + if (point.skip) { + continue; + } + value = normalize(point[property]); + if (value === prevValue) { + continue; + } + inside = between(value, startBound, endBound); + if (subStart === null && shouldStart()) { + subStart = compare(value, startBound) === 0 ? i : prev; + } + if (subStart !== null && shouldStop()) { + result.push(normalizeSegment({ + start: subStart, + end: i, + loop, + count, + style + })); + subStart = null; + } + prev = i; + prevValue = value; + } + if (subStart !== null) { + result.push(normalizeSegment({ + start: subStart, + end, + loop, + count, + style + })); + } + return result; +} +function _boundSegments(line, bounds) { + const result = []; + const segments = line.segments; + for (let i = 0; i < segments.length; i++) { + const sub = _boundSegment(segments[i], line.points, bounds); + if (sub.length) { + result.push(...sub); + } + } + return result; +} +function findStartAndEnd(points, count, loop, spanGaps) { + let start = 0; + let end = count - 1; + if (loop && !spanGaps) { + while (start < count && !points[start].skip) { + start++; + } + } + while (start < count && points[start].skip) { + start++; + } + start %= count; + if (loop) { + end += start; + } + while (end > start && points[end % count].skip) { + end--; + } + end %= count; + return { + start, + end + }; +} +function solidSegments(points, start, max, loop) { + const count = points.length; + const result = []; + let last = start; + let prev = points[start]; + let end; + for (end = start + 1; end <= max; ++end) { + const cur = points[end % count]; + if (cur.skip || cur.stop) { + if (!prev.skip) { + loop = false; + result.push({ + start: start % count, + end: (end - 1) % count, + loop + }); + start = last = cur.stop ? end : null; + } + } else { + last = end; + if (prev.skip) { + start = end; + } + } + prev = cur; + } + if (last !== null) { + result.push({ + start: start % count, + end: last % count, + loop + }); + } + return result; +} +function _computeSegments(line, segmentOptions) { + const points = line.points; + const spanGaps = line.options.spanGaps; + const count = points.length; + if (!count) { + return []; + } + const loop = !!line._loop; + const { start, end } = findStartAndEnd(points, count, loop, spanGaps); + if (spanGaps === true) { + return splitByStyles(line, [ + { + start, + end, + loop + } + ], points, segmentOptions); + } + const max = end < start ? end + count : end; + const completeLoop = !!line._fullLoop && start === 0 && end === count - 1; + return splitByStyles(line, solidSegments(points, start, max, completeLoop), points, segmentOptions); +} +function splitByStyles(line, segments, points, segmentOptions) { + if (!segmentOptions || !segmentOptions.setContext || !points) { + return segments; + } + return doSplitByStyles(line, segments, points, segmentOptions); +} +function doSplitByStyles(line, segments, points, segmentOptions) { + const chartContext = line._chart.getContext(); + const baseStyle = readStyle(line.options); + const { _datasetIndex: datasetIndex, options: { spanGaps } } = line; + const count = points.length; + const result = []; + let prevStyle = baseStyle; + let start = segments[0].start; + let i = start; + function addStyle(s2, e, l2, st) { + const dir = spanGaps ? -1 : 1; + if (s2 === e) { + return; + } + s2 += count; + while (points[s2 % count].skip) { + s2 -= dir; + } + while (points[e % count].skip) { + e += dir; + } + if (s2 % count !== e % count) { + result.push({ + start: s2 % count, + end: e % count, + loop: l2, + style: st + }); + prevStyle = st; + start = e % count; + } + } + for (const segment of segments) { + start = spanGaps ? start : segment.start; + let prev = points[start % count]; + let style; + for (i = start + 1; i <= segment.end; i++) { + const pt = points[i % count]; + style = readStyle(segmentOptions.setContext(createContext(chartContext, { + type: "segment", + p0: prev, + p1: pt, + p0DataIndex: (i - 1) % count, + p1DataIndex: i % count, + datasetIndex + }))); + if (styleChanged(style, prevStyle)) { + addStyle(start, i - 1, segment.loop, prevStyle); + } + prev = pt; + prevStyle = style; + } + if (start < i - 1) { + addStyle(start, i - 1, segment.loop, prevStyle); + } + } + return result; +} +function readStyle(options) { + return { + backgroundColor: options.backgroundColor, + borderCapStyle: options.borderCapStyle, + borderDash: options.borderDash, + borderDashOffset: options.borderDashOffset, + borderJoinStyle: options.borderJoinStyle, + borderWidth: options.borderWidth, + borderColor: options.borderColor + }; +} +function styleChanged(style, prevStyle) { + if (!prevStyle) { + return false; + } + const cache = []; + const replacer = function(key, value) { + if (!isPatternOrGradient(value)) { + return value; + } + if (!cache.includes(value)) { + cache.push(value); + } + return cache.indexOf(value); + }; + return JSON.stringify(style, replacer) !== JSON.stringify(prevStyle, replacer); +} + +// node_modules/chart.js/dist/chart.js +var Animator = class { + constructor() { + this._request = null; + this._charts = /* @__PURE__ */ new Map(); + this._running = false; + this._lastDate = void 0; + } + _notify(chart, anims, date, type) { + const callbacks = anims.listeners[type]; + const numSteps = anims.duration; + callbacks.forEach((fn) => fn({ + chart, + initial: anims.initial, + numSteps, + currentStep: Math.min(date - anims.start, numSteps) + })); + } + _refresh() { + if (this._request) { + return; + } + this._running = true; + this._request = requestAnimFrame.call(window, () => { + this._update(); + this._request = null; + if (this._running) { + this._refresh(); + } + }); + } + _update(date = Date.now()) { + let remaining = 0; + this._charts.forEach((anims, chart) => { + if (!anims.running || !anims.items.length) { + return; + } + const items = anims.items; + let i = items.length - 1; + let draw2 = false; + let item; + for (; i >= 0; --i) { + item = items[i]; + if (item._active) { + if (item._total > anims.duration) { + anims.duration = item._total; + } + item.tick(date); + draw2 = true; + } else { + items[i] = items[items.length - 1]; + items.pop(); + } + } + if (draw2) { + chart.draw(); + this._notify(chart, anims, date, "progress"); + } + if (!items.length) { + anims.running = false; + this._notify(chart, anims, date, "complete"); + anims.initial = false; + } + remaining += items.length; + }); + this._lastDate = date; + if (remaining === 0) { + this._running = false; + } + } + _getAnims(chart) { + const charts = this._charts; + let anims = charts.get(chart); + if (!anims) { + anims = { + running: false, + initial: true, + items: [], + listeners: { + complete: [], + progress: [] + } + }; + charts.set(chart, anims); + } + return anims; + } + listen(chart, event, cb) { + this._getAnims(chart).listeners[event].push(cb); + } + add(chart, items) { + if (!items || !items.length) { + return; + } + this._getAnims(chart).items.push(...items); + } + has(chart) { + return this._getAnims(chart).items.length > 0; + } + start(chart) { + const anims = this._charts.get(chart); + if (!anims) { + return; + } + anims.running = true; + anims.start = Date.now(); + anims.duration = anims.items.reduce((acc, cur) => Math.max(acc, cur._duration), 0); + this._refresh(); + } + running(chart) { + if (!this._running) { + return false; + } + const anims = this._charts.get(chart); + if (!anims || !anims.running || !anims.items.length) { + return false; + } + return true; + } + stop(chart) { + const anims = this._charts.get(chart); + if (!anims || !anims.items.length) { + return; + } + const items = anims.items; + let i = items.length - 1; + for (; i >= 0; --i) { + items[i].cancel(); + } + anims.items = []; + this._notify(chart, anims, Date.now(), "complete"); + } + remove(chart) { + return this._charts.delete(chart); + } +}; +var animator = /* @__PURE__ */ new Animator(); +var transparent = "transparent"; +var interpolators = { + boolean(from3, to3, factor) { + return factor > 0.5 ? to3 : from3; + }, + color(from3, to3, factor) { + const c0 = color(from3 || transparent); + const c1 = c0.valid && color(to3 || transparent); + return c1 && c1.valid ? c1.mix(c0, factor).hexString() : to3; + }, + number(from3, to3, factor) { + return from3 + (to3 - from3) * factor; + } +}; +var Animation = class { + constructor(cfg, target, prop, to3) { + const currentValue = target[prop]; + to3 = resolve([ + cfg.to, + to3, + currentValue, + cfg.from + ]); + const from3 = resolve([ + cfg.from, + currentValue, + to3 + ]); + this._active = true; + this._fn = cfg.fn || interpolators[cfg.type || typeof from3]; + this._easing = effects[cfg.easing] || effects.linear; + this._start = Math.floor(Date.now() + (cfg.delay || 0)); + this._duration = this._total = Math.floor(cfg.duration); + this._loop = !!cfg.loop; + this._target = target; + this._prop = prop; + this._from = from3; + this._to = to3; + this._promises = void 0; + } + active() { + return this._active; + } + update(cfg, to3, date) { + if (this._active) { + this._notify(false); + const currentValue = this._target[this._prop]; + const elapsed = date - this._start; + const remain = this._duration - elapsed; + this._start = date; + this._duration = Math.floor(Math.max(remain, cfg.duration)); + this._total += elapsed; + this._loop = !!cfg.loop; + this._to = resolve([ + cfg.to, + to3, + currentValue, + cfg.from + ]); + this._from = resolve([ + cfg.from, + currentValue, + to3 + ]); + } + } + cancel() { + if (this._active) { + this.tick(Date.now()); + this._active = false; + this._notify(false); + } + } + tick(date) { + const elapsed = date - this._start; + const duration = this._duration; + const prop = this._prop; + const from3 = this._from; + const loop = this._loop; + const to3 = this._to; + let factor; + this._active = from3 !== to3 && (loop || elapsed < duration); + if (!this._active) { + this._target[prop] = to3; + this._notify(true); + return; + } + if (elapsed < 0) { + this._target[prop] = from3; + return; + } + factor = elapsed / duration % 2; + factor = loop && factor > 1 ? 2 - factor : factor; + factor = this._easing(Math.min(1, Math.max(0, factor))); + this._target[prop] = this._fn(from3, to3, factor); + } + wait() { + const promises = this._promises || (this._promises = []); + return new Promise((res, rej) => { + promises.push({ + res, + rej + }); + }); + } + _notify(resolved) { + const method = resolved ? "res" : "rej"; + const promises = this._promises || []; + for (let i = 0; i < promises.length; i++) { + promises[i][method](); + } + } +}; +var Animations = class { + constructor(chart, config) { + this._chart = chart; + this._properties = /* @__PURE__ */ new Map(); + this.configure(config); + } + configure(config) { + if (!isObject(config)) { + return; + } + const animationOptions = Object.keys(defaults.animation); + const animatedProps = this._properties; + Object.getOwnPropertyNames(config).forEach((key) => { + const cfg = config[key]; + if (!isObject(cfg)) { + return; + } + const resolved = {}; + for (const option of animationOptions) { + resolved[option] = cfg[option]; + } + (isArray(cfg.properties) && cfg.properties || [ + key + ]).forEach((prop) => { + if (prop === key || !animatedProps.has(prop)) { + animatedProps.set(prop, resolved); + } + }); + }); + } + _animateOptions(target, values) { + const newOptions = values.options; + const options = resolveTargetOptions(target, newOptions); + if (!options) { + return []; + } + const animations = this._createAnimations(options, newOptions); + if (newOptions.$shared) { + awaitAll(target.options.$animations, newOptions).then(() => { + target.options = newOptions; + }, () => { + }); + } + return animations; + } + _createAnimations(target, values) { + const animatedProps = this._properties; + const animations = []; + const running = target.$animations || (target.$animations = {}); + const props = Object.keys(values); + const date = Date.now(); + let i; + for (i = props.length - 1; i >= 0; --i) { + const prop = props[i]; + if (prop.charAt(0) === "$") { + continue; + } + if (prop === "options") { + animations.push(...this._animateOptions(target, values)); + continue; + } + const value = values[prop]; + let animation = running[prop]; + const cfg = animatedProps.get(prop); + if (animation) { + if (cfg && animation.active()) { + animation.update(cfg, value, date); + continue; + } else { + animation.cancel(); + } + } + if (!cfg || !cfg.duration) { + target[prop] = value; + continue; + } + running[prop] = animation = new Animation(cfg, target, prop, value); + animations.push(animation); + } + return animations; + } + update(target, values) { + if (this._properties.size === 0) { + Object.assign(target, values); + return; + } + const animations = this._createAnimations(target, values); + if (animations.length) { + animator.add(this._chart, animations); + return true; + } + } +}; +function awaitAll(animations, properties) { + const running = []; + const keys = Object.keys(properties); + for (let i = 0; i < keys.length; i++) { + const anim = animations[keys[i]]; + if (anim && anim.active()) { + running.push(anim.wait()); + } + } + return Promise.all(running); +} +function resolveTargetOptions(target, newOptions) { + if (!newOptions) { + return; + } + let options = target.options; + if (!options) { + target.options = newOptions; + return; + } + if (options.$shared) { + target.options = options = Object.assign({}, options, { + $shared: false, + $animations: {} + }); + } + return options; +} +function scaleClip(scale, allowedOverflow) { + const opts = scale && scale.options || {}; + const reverse = opts.reverse; + const min = opts.min === void 0 ? allowedOverflow : 0; + const max = opts.max === void 0 ? allowedOverflow : 0; + return { + start: reverse ? max : min, + end: reverse ? min : max + }; +} +function defaultClip(xScale, yScale, allowedOverflow) { + if (allowedOverflow === false) { + return false; + } + const x = scaleClip(xScale, allowedOverflow); + const y = scaleClip(yScale, allowedOverflow); + return { + top: y.end, + right: x.end, + bottom: y.start, + left: x.start + }; +} +function toClip(value) { + let t, r, b, l2; + if (isObject(value)) { + t = value.top; + r = value.right; + b = value.bottom; + l2 = value.left; + } else { + t = r = b = l2 = value; + } + return { + top: t, + right: r, + bottom: b, + left: l2, + disabled: value === false + }; +} +function getSortedDatasetIndices(chart, filterVisible) { + const keys = []; + const metasets = chart._getSortedDatasetMetas(filterVisible); + let i, ilen; + for (i = 0, ilen = metasets.length; i < ilen; ++i) { + keys.push(metasets[i].index); + } + return keys; +} +function applyStack(stack, value, dsIndex, options = {}) { + const keys = stack.keys; + const singleMode = options.mode === "single"; + let i, ilen, datasetIndex, otherValue; + if (value === null) { + return; + } + for (i = 0, ilen = keys.length; i < ilen; ++i) { + datasetIndex = +keys[i]; + if (datasetIndex === dsIndex) { + if (options.all) { + continue; + } + break; + } + otherValue = stack.values[datasetIndex]; + if (isNumberFinite(otherValue) && (singleMode || value === 0 || sign(value) === sign(otherValue))) { + value += otherValue; + } + } + return value; +} +function convertObjectDataToArray(data) { + const keys = Object.keys(data); + const adata = new Array(keys.length); + let i, ilen, key; + for (i = 0, ilen = keys.length; i < ilen; ++i) { + key = keys[i]; + adata[i] = { + x: key, + y: data[key] + }; + } + return adata; +} +function isStacked(scale, meta) { + const stacked = scale && scale.options.stacked; + return stacked || stacked === void 0 && meta.stack !== void 0; +} +function getStackKey(indexScale, valueScale, meta) { + return `${indexScale.id}.${valueScale.id}.${meta.stack || meta.type}`; +} +function getUserBounds(scale) { + const { min, max, minDefined, maxDefined } = scale.getUserBounds(); + return { + min: minDefined ? min : Number.NEGATIVE_INFINITY, + max: maxDefined ? max : Number.POSITIVE_INFINITY + }; +} +function getOrCreateStack(stacks, stackKey, indexValue) { + const subStack = stacks[stackKey] || (stacks[stackKey] = {}); + return subStack[indexValue] || (subStack[indexValue] = {}); +} +function getLastIndexInStack(stack, vScale, positive, type) { + for (const meta of vScale.getMatchingVisibleMetas(type).reverse()) { + const value = stack[meta.index]; + if (positive && value > 0 || !positive && value < 0) { + return meta.index; + } + } + return null; +} +function updateStacks(controller, parsed) { + const { chart, _cachedMeta: meta } = controller; + const stacks = chart._stacks || (chart._stacks = {}); + const { iScale, vScale, index: datasetIndex } = meta; + const iAxis = iScale.axis; + const vAxis = vScale.axis; + const key = getStackKey(iScale, vScale, meta); + const ilen = parsed.length; + let stack; + for (let i = 0; i < ilen; ++i) { + const item = parsed[i]; + const { [iAxis]: index2, [vAxis]: value } = item; + const itemStacks = item._stacks || (item._stacks = {}); + stack = itemStacks[vAxis] = getOrCreateStack(stacks, key, index2); + stack[datasetIndex] = value; + stack._top = getLastIndexInStack(stack, vScale, true, meta.type); + stack._bottom = getLastIndexInStack(stack, vScale, false, meta.type); + const visualValues = stack._visualValues || (stack._visualValues = {}); + visualValues[datasetIndex] = value; + } +} +function getFirstScaleId(chart, axis) { + const scales2 = chart.scales; + return Object.keys(scales2).filter((key) => scales2[key].axis === axis).shift(); +} +function createDatasetContext(parent, index2) { + return createContext(parent, { + active: false, + dataset: void 0, + datasetIndex: index2, + index: index2, + mode: "default", + type: "dataset" + }); +} +function createDataContext(parent, index2, element) { + return createContext(parent, { + active: false, + dataIndex: index2, + parsed: void 0, + raw: void 0, + element, + index: index2, + mode: "default", + type: "data" + }); +} +function clearStacks(meta, items) { + const datasetIndex = meta.controller.index; + const axis = meta.vScale && meta.vScale.axis; + if (!axis) { + return; + } + items = items || meta._parsed; + for (const parsed of items) { + const stacks = parsed._stacks; + if (!stacks || stacks[axis] === void 0 || stacks[axis][datasetIndex] === void 0) { + return; + } + delete stacks[axis][datasetIndex]; + if (stacks[axis]._visualValues !== void 0 && stacks[axis]._visualValues[datasetIndex] !== void 0) { + delete stacks[axis]._visualValues[datasetIndex]; + } + } +} +var isDirectUpdateMode = (mode) => mode === "reset" || mode === "none"; +var cloneIfNotShared = (cached, shared) => shared ? cached : Object.assign({}, cached); +var createStack = (canStack, meta, chart) => canStack && !meta.hidden && meta._stacked && { + keys: getSortedDatasetIndices(chart, true), + values: null +}; +var DatasetController = class { + constructor(chart, datasetIndex) { + this.chart = chart; + this._ctx = chart.ctx; + this.index = datasetIndex; + this._cachedDataOpts = {}; + this._cachedMeta = this.getMeta(); + this._type = this._cachedMeta.type; + this.options = void 0; + this._parsing = false; + this._data = void 0; + this._objectData = void 0; + this._sharedOptions = void 0; + this._drawStart = void 0; + this._drawCount = void 0; + this.enableOptionSharing = false; + this.supportsDecimation = false; + this.$context = void 0; + this._syncList = []; + this.datasetElementType = new.target.datasetElementType; + this.dataElementType = new.target.dataElementType; + this.initialize(); + } + initialize() { + const meta = this._cachedMeta; + this.configure(); + this.linkScales(); + meta._stacked = isStacked(meta.vScale, meta); + this.addElements(); + if (this.options.fill && !this.chart.isPluginEnabled("filler")) { + console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options"); + } + } + updateIndex(datasetIndex) { + if (this.index !== datasetIndex) { + clearStacks(this._cachedMeta); + } + this.index = datasetIndex; + } + linkScales() { + const chart = this.chart; + const meta = this._cachedMeta; + const dataset = this.getDataset(); + const chooseId = (axis, x, y, r) => axis === "x" ? x : axis === "r" ? r : y; + const xid = meta.xAxisID = valueOrDefault(dataset.xAxisID, getFirstScaleId(chart, "x")); + const yid = meta.yAxisID = valueOrDefault(dataset.yAxisID, getFirstScaleId(chart, "y")); + const rid = meta.rAxisID = valueOrDefault(dataset.rAxisID, getFirstScaleId(chart, "r")); + const indexAxis = meta.indexAxis; + const iid = meta.iAxisID = chooseId(indexAxis, xid, yid, rid); + const vid = meta.vAxisID = chooseId(indexAxis, yid, xid, rid); + meta.xScale = this.getScaleForId(xid); + meta.yScale = this.getScaleForId(yid); + meta.rScale = this.getScaleForId(rid); + meta.iScale = this.getScaleForId(iid); + meta.vScale = this.getScaleForId(vid); + } + getDataset() { + return this.chart.data.datasets[this.index]; + } + getMeta() { + return this.chart.getDatasetMeta(this.index); + } + getScaleForId(scaleID) { + return this.chart.scales[scaleID]; + } + _getOtherScale(scale) { + const meta = this._cachedMeta; + return scale === meta.iScale ? meta.vScale : meta.iScale; + } + reset() { + this._update("reset"); + } + _destroy() { + const meta = this._cachedMeta; + if (this._data) { + unlistenArrayEvents(this._data, this); + } + if (meta._stacked) { + clearStacks(meta); + } + } + _dataCheck() { + const dataset = this.getDataset(); + const data = dataset.data || (dataset.data = []); + const _data = this._data; + if (isObject(data)) { + this._data = convertObjectDataToArray(data); + } else if (_data !== data) { + if (_data) { + unlistenArrayEvents(_data, this); + const meta = this._cachedMeta; + clearStacks(meta); + meta._parsed = []; + } + if (data && Object.isExtensible(data)) { + listenArrayEvents(data, this); + } + this._syncList = []; + this._data = data; + } + } + addElements() { + const meta = this._cachedMeta; + this._dataCheck(); + if (this.datasetElementType) { + meta.dataset = new this.datasetElementType(); + } + } + buildOrUpdateElements(resetNewElements) { + const meta = this._cachedMeta; + const dataset = this.getDataset(); + let stackChanged = false; + this._dataCheck(); + const oldStacked = meta._stacked; + meta._stacked = isStacked(meta.vScale, meta); + if (meta.stack !== dataset.stack) { + stackChanged = true; + clearStacks(meta); + meta.stack = dataset.stack; + } + this._resyncElements(resetNewElements); + if (stackChanged || oldStacked !== meta._stacked) { + updateStacks(this, meta._parsed); + } + } + configure() { + const config = this.chart.config; + const scopeKeys = config.datasetScopeKeys(this._type); + const scopes = config.getOptionScopes(this.getDataset(), scopeKeys, true); + this.options = config.createResolver(scopes, this.getContext()); + this._parsing = this.options.parsing; + this._cachedDataOpts = {}; + } + parse(start, count) { + const { _cachedMeta: meta, _data: data } = this; + const { iScale, _stacked } = meta; + const iAxis = iScale.axis; + let sorted = start === 0 && count === data.length ? true : meta._sorted; + let prev = start > 0 && meta._parsed[start - 1]; + let i, cur, parsed; + if (this._parsing === false) { + meta._parsed = data; + meta._sorted = true; + parsed = data; + } else { + if (isArray(data[start])) { + parsed = this.parseArrayData(meta, data, start, count); + } else if (isObject(data[start])) { + parsed = this.parseObjectData(meta, data, start, count); + } else { + parsed = this.parsePrimitiveData(meta, data, start, count); + } + const isNotInOrderComparedToPrev = () => cur[iAxis] === null || prev && cur[iAxis] < prev[iAxis]; + for (i = 0; i < count; ++i) { + meta._parsed[i + start] = cur = parsed[i]; + if (sorted) { + if (isNotInOrderComparedToPrev()) { + sorted = false; + } + prev = cur; + } + } + meta._sorted = sorted; + } + if (_stacked) { + updateStacks(this, parsed); + } + } + parsePrimitiveData(meta, data, start, count) { + const { iScale, vScale } = meta; + const iAxis = iScale.axis; + const vAxis = vScale.axis; + const labels = iScale.getLabels(); + const singleScale = iScale === vScale; + const parsed = new Array(count); + let i, ilen, index2; + for (i = 0, ilen = count; i < ilen; ++i) { + index2 = i + start; + parsed[i] = { + [iAxis]: singleScale || iScale.parse(labels[index2], index2), + [vAxis]: vScale.parse(data[index2], index2) + }; + } + return parsed; + } + parseArrayData(meta, data, start, count) { + const { xScale, yScale } = meta; + const parsed = new Array(count); + let i, ilen, index2, item; + for (i = 0, ilen = count; i < ilen; ++i) { + index2 = i + start; + item = data[index2]; + parsed[i] = { + x: xScale.parse(item[0], index2), + y: yScale.parse(item[1], index2) + }; + } + return parsed; + } + parseObjectData(meta, data, start, count) { + const { xScale, yScale } = meta; + const { xAxisKey = "x", yAxisKey = "y" } = this._parsing; + const parsed = new Array(count); + let i, ilen, index2, item; + for (i = 0, ilen = count; i < ilen; ++i) { + index2 = i + start; + item = data[index2]; + parsed[i] = { + x: xScale.parse(resolveObjectKey(item, xAxisKey), index2), + y: yScale.parse(resolveObjectKey(item, yAxisKey), index2) + }; + } + return parsed; + } + getParsed(index2) { + return this._cachedMeta._parsed[index2]; + } + getDataElement(index2) { + return this._cachedMeta.data[index2]; + } + applyStack(scale, parsed, mode) { + const chart = this.chart; + const meta = this._cachedMeta; + const value = parsed[scale.axis]; + const stack = { + keys: getSortedDatasetIndices(chart, true), + values: parsed._stacks[scale.axis]._visualValues + }; + return applyStack(stack, value, meta.index, { + mode + }); + } + updateRangeFromParsed(range, scale, parsed, stack) { + const parsedValue = parsed[scale.axis]; + let value = parsedValue === null ? NaN : parsedValue; + const values = stack && parsed._stacks[scale.axis]; + if (stack && values) { + stack.values = values; + value = applyStack(stack, parsedValue, this._cachedMeta.index); + } + range.min = Math.min(range.min, value); + range.max = Math.max(range.max, value); + } + getMinMax(scale, canStack) { + const meta = this._cachedMeta; + const _parsed = meta._parsed; + const sorted = meta._sorted && scale === meta.iScale; + const ilen = _parsed.length; + const otherScale = this._getOtherScale(scale); + const stack = createStack(canStack, meta, this.chart); + const range = { + min: Number.POSITIVE_INFINITY, + max: Number.NEGATIVE_INFINITY + }; + const { min: otherMin, max: otherMax } = getUserBounds(otherScale); + let i, parsed; + function _skip() { + parsed = _parsed[i]; + const otherValue = parsed[otherScale.axis]; + return !isNumberFinite(parsed[scale.axis]) || otherMin > otherValue || otherMax < otherValue; + } + for (i = 0; i < ilen; ++i) { + if (_skip()) { + continue; + } + this.updateRangeFromParsed(range, scale, parsed, stack); + if (sorted) { + break; + } + } + if (sorted) { + for (i = ilen - 1; i >= 0; --i) { + if (_skip()) { + continue; + } + this.updateRangeFromParsed(range, scale, parsed, stack); + break; + } + } + return range; + } + getAllParsedValues(scale) { + const parsed = this._cachedMeta._parsed; + const values = []; + let i, ilen, value; + for (i = 0, ilen = parsed.length; i < ilen; ++i) { + value = parsed[i][scale.axis]; + if (isNumberFinite(value)) { + values.push(value); + } + } + return values; + } + getMaxOverflow() { + return false; + } + getLabelAndValue(index2) { + const meta = this._cachedMeta; + const iScale = meta.iScale; + const vScale = meta.vScale; + const parsed = this.getParsed(index2); + return { + label: iScale ? "" + iScale.getLabelForValue(parsed[iScale.axis]) : "", + value: vScale ? "" + vScale.getLabelForValue(parsed[vScale.axis]) : "" + }; + } + _update(mode) { + const meta = this._cachedMeta; + this.update(mode || "default"); + meta._clip = toClip(valueOrDefault(this.options.clip, defaultClip(meta.xScale, meta.yScale, this.getMaxOverflow()))); + } + update(mode) { + } + draw() { + const ctx = this._ctx; + const chart = this.chart; + const meta = this._cachedMeta; + const elements2 = meta.data || []; + const area = chart.chartArea; + const active = []; + const start = this._drawStart || 0; + const count = this._drawCount || elements2.length - start; + const drawActiveElementsOnTop = this.options.drawActiveElementsOnTop; + let i; + if (meta.dataset) { + meta.dataset.draw(ctx, area, start, count); + } + for (i = start; i < start + count; ++i) { + const element = elements2[i]; + if (element.hidden) { + continue; + } + if (element.active && drawActiveElementsOnTop) { + active.push(element); + } else { + element.draw(ctx, area); + } + } + for (i = 0; i < active.length; ++i) { + active[i].draw(ctx, area); + } + } + getStyle(index2, active) { + const mode = active ? "active" : "default"; + return index2 === void 0 && this._cachedMeta.dataset ? this.resolveDatasetElementOptions(mode) : this.resolveDataElementOptions(index2 || 0, mode); + } + getContext(index2, active, mode) { + const dataset = this.getDataset(); + let context; + if (index2 >= 0 && index2 < this._cachedMeta.data.length) { + const element = this._cachedMeta.data[index2]; + context = element.$context || (element.$context = createDataContext(this.getContext(), index2, element)); + context.parsed = this.getParsed(index2); + context.raw = dataset.data[index2]; + context.index = context.dataIndex = index2; + } else { + context = this.$context || (this.$context = createDatasetContext(this.chart.getContext(), this.index)); + context.dataset = dataset; + context.index = context.datasetIndex = this.index; + } + context.active = !!active; + context.mode = mode; + return context; + } + resolveDatasetElementOptions(mode) { + return this._resolveElementOptions(this.datasetElementType.id, mode); + } + resolveDataElementOptions(index2, mode) { + return this._resolveElementOptions(this.dataElementType.id, mode, index2); + } + _resolveElementOptions(elementType, mode = "default", index2) { + const active = mode === "active"; + const cache = this._cachedDataOpts; + const cacheKey = elementType + "-" + mode; + const cached = cache[cacheKey]; + const sharing = this.enableOptionSharing && defined(index2); + if (cached) { + return cloneIfNotShared(cached, sharing); + } + const config = this.chart.config; + const scopeKeys = config.datasetElementScopeKeys(this._type, elementType); + const prefixes = active ? [ + `${elementType}Hover`, + "hover", + elementType, + "" + ] : [ + elementType, + "" + ]; + const scopes = config.getOptionScopes(this.getDataset(), scopeKeys); + const names3 = Object.keys(defaults.elements[elementType]); + const context = () => this.getContext(index2, active, mode); + const values = config.resolveNamedOptions(scopes, names3, context, prefixes); + if (values.$shared) { + values.$shared = sharing; + cache[cacheKey] = Object.freeze(cloneIfNotShared(values, sharing)); + } + return values; + } + _resolveAnimations(index2, transition, active) { + const chart = this.chart; + const cache = this._cachedDataOpts; + const cacheKey = `animation-${transition}`; + const cached = cache[cacheKey]; + if (cached) { + return cached; + } + let options; + if (chart.options.animation !== false) { + const config = this.chart.config; + const scopeKeys = config.datasetAnimationScopeKeys(this._type, transition); + const scopes = config.getOptionScopes(this.getDataset(), scopeKeys); + options = config.createResolver(scopes, this.getContext(index2, active, transition)); + } + const animations = new Animations(chart, options && options.animations); + if (options && options._cacheable) { + cache[cacheKey] = Object.freeze(animations); + } + return animations; + } + getSharedOptions(options) { + if (!options.$shared) { + return; + } + return this._sharedOptions || (this._sharedOptions = Object.assign({}, options)); + } + includeOptions(mode, sharedOptions) { + return !sharedOptions || isDirectUpdateMode(mode) || this.chart._animationsDisabled; + } + _getSharedOptions(start, mode) { + const firstOpts = this.resolveDataElementOptions(start, mode); + const previouslySharedOptions = this._sharedOptions; + const sharedOptions = this.getSharedOptions(firstOpts); + const includeOptions = this.includeOptions(mode, sharedOptions) || sharedOptions !== previouslySharedOptions; + this.updateSharedOptions(sharedOptions, mode, firstOpts); + return { + sharedOptions, + includeOptions + }; + } + updateElement(element, index2, properties, mode) { + if (isDirectUpdateMode(mode)) { + Object.assign(element, properties); + } else { + this._resolveAnimations(index2, mode).update(element, properties); + } + } + updateSharedOptions(sharedOptions, mode, newOptions) { + if (sharedOptions && !isDirectUpdateMode(mode)) { + this._resolveAnimations(void 0, mode).update(sharedOptions, newOptions); + } + } + _setStyle(element, index2, mode, active) { + element.active = active; + const options = this.getStyle(index2, active); + this._resolveAnimations(index2, mode, active).update(element, { + options: !active && this.getSharedOptions(options) || options + }); + } + removeHoverStyle(element, datasetIndex, index2) { + this._setStyle(element, index2, "active", false); + } + setHoverStyle(element, datasetIndex, index2) { + this._setStyle(element, index2, "active", true); + } + _removeDatasetHoverStyle() { + const element = this._cachedMeta.dataset; + if (element) { + this._setStyle(element, void 0, "active", false); + } + } + _setDatasetHoverStyle() { + const element = this._cachedMeta.dataset; + if (element) { + this._setStyle(element, void 0, "active", true); + } + } + _resyncElements(resetNewElements) { + const data = this._data; + const elements2 = this._cachedMeta.data; + for (const [method, arg1, arg2] of this._syncList) { + this[method](arg1, arg2); + } + this._syncList = []; + const numMeta = elements2.length; + const numData = data.length; + const count = Math.min(numData, numMeta); + if (count) { + this.parse(0, count); + } + if (numData > numMeta) { + this._insertElements(numMeta, numData - numMeta, resetNewElements); + } else if (numData < numMeta) { + this._removeElements(numData, numMeta - numData); + } + } + _insertElements(start, count, resetNewElements = true) { + const meta = this._cachedMeta; + const data = meta.data; + const end = start + count; + let i; + const move = (arr) => { + arr.length += count; + for (i = arr.length - 1; i >= end; i--) { + arr[i] = arr[i - count]; + } + }; + move(data); + for (i = start; i < end; ++i) { + data[i] = new this.dataElementType(); + } + if (this._parsing) { + move(meta._parsed); + } + this.parse(start, count); + if (resetNewElements) { + this.updateElements(data, start, count, "reset"); + } + } + updateElements(element, start, count, mode) { + } + _removeElements(start, count) { + const meta = this._cachedMeta; + if (this._parsing) { + const removed = meta._parsed.splice(start, count); + if (meta._stacked) { + clearStacks(meta, removed); + } + } + meta.data.splice(start, count); + } + _sync(args) { + if (this._parsing) { + this._syncList.push(args); + } else { + const [method, arg1, arg2] = args; + this[method](arg1, arg2); + } + this.chart._dataChanges.push([ + this.index, + ...args + ]); + } + _onDataPush() { + const count = arguments.length; + this._sync([ + "_insertElements", + this.getDataset().data.length - count, + count + ]); + } + _onDataPop() { + this._sync([ + "_removeElements", + this._cachedMeta.data.length - 1, + 1 + ]); + } + _onDataShift() { + this._sync([ + "_removeElements", + 0, + 1 + ]); + } + _onDataSplice(start, count) { + if (count) { + this._sync([ + "_removeElements", + start, + count + ]); + } + const newCount = arguments.length - 2; + if (newCount) { + this._sync([ + "_insertElements", + start, + newCount + ]); + } + } + _onDataUnshift() { + this._sync([ + "_insertElements", + 0, + arguments.length + ]); + } +}; +__publicField(DatasetController, "defaults", {}); +__publicField(DatasetController, "datasetElementType", null); +__publicField(DatasetController, "dataElementType", null); +function getAllScaleValues(scale, type) { + if (!scale._cache.$bar) { + const visibleMetas = scale.getMatchingVisibleMetas(type); + let values = []; + for (let i = 0, ilen = visibleMetas.length; i < ilen; i++) { + values = values.concat(visibleMetas[i].controller.getAllParsedValues(scale)); + } + scale._cache.$bar = _arrayUnique(values.sort((a, b) => a - b)); + } + return scale._cache.$bar; +} +function computeMinSampleSize(meta) { + const scale = meta.iScale; + const values = getAllScaleValues(scale, meta.type); + let min = scale._length; + let i, ilen, curr, prev; + const updateMinAndPrev = () => { + if (curr === 32767 || curr === -32768) { + return; + } + if (defined(prev)) { + min = Math.min(min, Math.abs(curr - prev) || min); + } + prev = curr; + }; + for (i = 0, ilen = values.length; i < ilen; ++i) { + curr = scale.getPixelForValue(values[i]); + updateMinAndPrev(); + } + prev = void 0; + for (i = 0, ilen = scale.ticks.length; i < ilen; ++i) { + curr = scale.getPixelForTick(i); + updateMinAndPrev(); + } + return min; +} +function computeFitCategoryTraits(index2, ruler, options, stackCount) { + const thickness = options.barThickness; + let size, ratio; + if (isNullOrUndef(thickness)) { + size = ruler.min * options.categoryPercentage; + ratio = options.barPercentage; + } else { + size = thickness * stackCount; + ratio = 1; + } + return { + chunk: size / stackCount, + ratio, + start: ruler.pixels[index2] - size / 2 + }; +} +function computeFlexCategoryTraits(index2, ruler, options, stackCount) { + const pixels = ruler.pixels; + const curr = pixels[index2]; + let prev = index2 > 0 ? pixels[index2 - 1] : null; + let next = index2 < pixels.length - 1 ? pixels[index2 + 1] : null; + const percent = options.categoryPercentage; + if (prev === null) { + prev = curr - (next === null ? ruler.end - ruler.start : next - curr); + } + if (next === null) { + next = curr + curr - prev; + } + const start = curr - (curr - Math.min(prev, next)) / 2 * percent; + const size = Math.abs(next - prev) / 2 * percent; + return { + chunk: size / stackCount, + ratio: options.barPercentage, + start + }; +} +function parseFloatBar(entry, item, vScale, i) { + const startValue = vScale.parse(entry[0], i); + const endValue = vScale.parse(entry[1], i); + const min = Math.min(startValue, endValue); + const max = Math.max(startValue, endValue); + let barStart = min; + let barEnd = max; + if (Math.abs(min) > Math.abs(max)) { + barStart = max; + barEnd = min; + } + item[vScale.axis] = barEnd; + item._custom = { + barStart, + barEnd, + start: startValue, + end: endValue, + min, + max + }; +} +function parseValue(entry, item, vScale, i) { + if (isArray(entry)) { + parseFloatBar(entry, item, vScale, i); + } else { + item[vScale.axis] = vScale.parse(entry, i); + } + return item; +} +function parseArrayOrPrimitive(meta, data, start, count) { + const iScale = meta.iScale; + const vScale = meta.vScale; + const labels = iScale.getLabels(); + const singleScale = iScale === vScale; + const parsed = []; + let i, ilen, item, entry; + for (i = start, ilen = start + count; i < ilen; ++i) { + entry = data[i]; + item = {}; + item[iScale.axis] = singleScale || iScale.parse(labels[i], i); + parsed.push(parseValue(entry, item, vScale, i)); + } + return parsed; +} +function isFloatBar(custom) { + return custom && custom.barStart !== void 0 && custom.barEnd !== void 0; +} +function barSign(size, vScale, actualBase) { + if (size !== 0) { + return sign(size); + } + return (vScale.isHorizontal() ? 1 : -1) * (vScale.min >= actualBase ? 1 : -1); +} +function borderProps(properties) { + let reverse, start, end, top, bottom; + if (properties.horizontal) { + reverse = properties.base > properties.x; + start = "left"; + end = "right"; + } else { + reverse = properties.base < properties.y; + start = "bottom"; + end = "top"; + } + if (reverse) { + top = "end"; + bottom = "start"; + } else { + top = "start"; + bottom = "end"; + } + return { + start, + end, + reverse, + top, + bottom + }; +} +function setBorderSkipped(properties, options, stack, index2) { + let edge = options.borderSkipped; + const res = {}; + if (!edge) { + properties.borderSkipped = res; + return; + } + if (edge === true) { + properties.borderSkipped = { + top: true, + right: true, + bottom: true, + left: true + }; + return; + } + const { start, end, reverse, top, bottom } = borderProps(properties); + if (edge === "middle" && stack) { + properties.enableBorderRadius = true; + if ((stack._top || 0) === index2) { + edge = top; + } else if ((stack._bottom || 0) === index2) { + edge = bottom; + } else { + res[parseEdge(bottom, start, end, reverse)] = true; + edge = top; + } + } + res[parseEdge(edge, start, end, reverse)] = true; + properties.borderSkipped = res; +} +function parseEdge(edge, a, b, reverse) { + if (reverse) { + edge = swap(edge, a, b); + edge = startEnd(edge, b, a); + } else { + edge = startEnd(edge, a, b); + } + return edge; +} +function swap(orig, v1, v2) { + return orig === v1 ? v2 : orig === v2 ? v1 : orig; +} +function startEnd(v, start, end) { + return v === "start" ? start : v === "end" ? end : v; +} +function setInflateAmount(properties, { inflateAmount }, ratio) { + properties.inflateAmount = inflateAmount === "auto" ? ratio === 1 ? 0.33 : 0 : inflateAmount; +} +var BarController = class extends DatasetController { + parsePrimitiveData(meta, data, start, count) { + return parseArrayOrPrimitive(meta, data, start, count); + } + parseArrayData(meta, data, start, count) { + return parseArrayOrPrimitive(meta, data, start, count); + } + parseObjectData(meta, data, start, count) { + const { iScale, vScale } = meta; + const { xAxisKey = "x", yAxisKey = "y" } = this._parsing; + const iAxisKey = iScale.axis === "x" ? xAxisKey : yAxisKey; + const vAxisKey = vScale.axis === "x" ? xAxisKey : yAxisKey; + const parsed = []; + let i, ilen, item, obj; + for (i = start, ilen = start + count; i < ilen; ++i) { + obj = data[i]; + item = {}; + item[iScale.axis] = iScale.parse(resolveObjectKey(obj, iAxisKey), i); + parsed.push(parseValue(resolveObjectKey(obj, vAxisKey), item, vScale, i)); + } + return parsed; + } + updateRangeFromParsed(range, scale, parsed, stack) { + super.updateRangeFromParsed(range, scale, parsed, stack); + const custom = parsed._custom; + if (custom && scale === this._cachedMeta.vScale) { + range.min = Math.min(range.min, custom.min); + range.max = Math.max(range.max, custom.max); + } + } + getMaxOverflow() { + return 0; + } + getLabelAndValue(index2) { + const meta = this._cachedMeta; + const { iScale, vScale } = meta; + const parsed = this.getParsed(index2); + const custom = parsed._custom; + const value = isFloatBar(custom) ? "[" + custom.start + ", " + custom.end + "]" : "" + vScale.getLabelForValue(parsed[vScale.axis]); + return { + label: "" + iScale.getLabelForValue(parsed[iScale.axis]), + value + }; + } + initialize() { + this.enableOptionSharing = true; + super.initialize(); + const meta = this._cachedMeta; + meta.stack = this.getDataset().stack; + } + update(mode) { + const meta = this._cachedMeta; + this.updateElements(meta.data, 0, meta.data.length, mode); + } + updateElements(bars, start, count, mode) { + const reset = mode === "reset"; + const { index: index2, _cachedMeta: { vScale } } = this; + const base = vScale.getBasePixel(); + const horizontal = vScale.isHorizontal(); + const ruler = this._getRuler(); + const { sharedOptions, includeOptions } = this._getSharedOptions(start, mode); + for (let i = start; i < start + count; i++) { + const parsed = this.getParsed(i); + const vpixels = reset || isNullOrUndef(parsed[vScale.axis]) ? { + base, + head: base + } : this._calculateBarValuePixels(i); + const ipixels = this._calculateBarIndexPixels(i, ruler); + const stack = (parsed._stacks || {})[vScale.axis]; + const properties = { + horizontal, + base: vpixels.base, + enableBorderRadius: !stack || isFloatBar(parsed._custom) || index2 === stack._top || index2 === stack._bottom, + x: horizontal ? vpixels.head : ipixels.center, + y: horizontal ? ipixels.center : vpixels.head, + height: horizontal ? ipixels.size : Math.abs(vpixels.size), + width: horizontal ? Math.abs(vpixels.size) : ipixels.size + }; + if (includeOptions) { + properties.options = sharedOptions || this.resolveDataElementOptions(i, bars[i].active ? "active" : mode); + } + const options = properties.options || bars[i].options; + setBorderSkipped(properties, options, stack, index2); + setInflateAmount(properties, options, ruler.ratio); + this.updateElement(bars[i], i, properties, mode); + } + } + _getStacks(last, dataIndex) { + const { iScale } = this._cachedMeta; + const metasets = iScale.getMatchingVisibleMetas(this._type).filter((meta) => meta.controller.options.grouped); + const stacked = iScale.options.stacked; + const stacks = []; + const skipNull = (meta) => { + const parsed = meta.controller.getParsed(dataIndex); + const val = parsed && parsed[meta.vScale.axis]; + if (isNullOrUndef(val) || isNaN(val)) { + return true; + } + }; + for (const meta of metasets) { + if (dataIndex !== void 0 && skipNull(meta)) { + continue; + } + if (stacked === false || stacks.indexOf(meta.stack) === -1 || stacked === void 0 && meta.stack === void 0) { + stacks.push(meta.stack); + } + if (meta.index === last) { + break; + } + } + if (!stacks.length) { + stacks.push(void 0); + } + return stacks; + } + _getStackCount(index2) { + return this._getStacks(void 0, index2).length; + } + _getStackIndex(datasetIndex, name, dataIndex) { + const stacks = this._getStacks(datasetIndex, dataIndex); + const index2 = name !== void 0 ? stacks.indexOf(name) : -1; + return index2 === -1 ? stacks.length - 1 : index2; + } + _getRuler() { + const opts = this.options; + const meta = this._cachedMeta; + const iScale = meta.iScale; + const pixels = []; + let i, ilen; + for (i = 0, ilen = meta.data.length; i < ilen; ++i) { + pixels.push(iScale.getPixelForValue(this.getParsed(i)[iScale.axis], i)); + } + const barThickness = opts.barThickness; + const min = barThickness || computeMinSampleSize(meta); + return { + min, + pixels, + start: iScale._startPixel, + end: iScale._endPixel, + stackCount: this._getStackCount(), + scale: iScale, + grouped: opts.grouped, + ratio: barThickness ? 1 : opts.categoryPercentage * opts.barPercentage + }; + } + _calculateBarValuePixels(index2) { + const { _cachedMeta: { vScale, _stacked, index: datasetIndex }, options: { base: baseValue, minBarLength } } = this; + const actualBase = baseValue || 0; + const parsed = this.getParsed(index2); + const custom = parsed._custom; + const floating = isFloatBar(custom); + let value = parsed[vScale.axis]; + let start = 0; + let length = _stacked ? this.applyStack(vScale, parsed, _stacked) : value; + let head, size; + if (length !== value) { + start = length - value; + length = value; + } + if (floating) { + value = custom.barStart; + length = custom.barEnd - custom.barStart; + if (value !== 0 && sign(value) !== sign(custom.barEnd)) { + start = 0; + } + start += value; + } + const startValue = !isNullOrUndef(baseValue) && !floating ? baseValue : start; + let base = vScale.getPixelForValue(startValue); + if (this.chart.getDataVisibility(index2)) { + head = vScale.getPixelForValue(start + length); + } else { + head = base; + } + size = head - base; + if (Math.abs(size) < minBarLength) { + size = barSign(size, vScale, actualBase) * minBarLength; + if (value === actualBase) { + base -= size / 2; + } + const startPixel = vScale.getPixelForDecimal(0); + const endPixel = vScale.getPixelForDecimal(1); + const min = Math.min(startPixel, endPixel); + const max = Math.max(startPixel, endPixel); + base = Math.max(Math.min(base, max), min); + head = base + size; + if (_stacked && !floating) { + parsed._stacks[vScale.axis]._visualValues[datasetIndex] = vScale.getValueForPixel(head) - vScale.getValueForPixel(base); + } + } + if (base === vScale.getPixelForValue(actualBase)) { + const halfGrid = sign(size) * vScale.getLineWidthForValue(actualBase) / 2; + base += halfGrid; + size -= halfGrid; + } + return { + size, + base, + head, + center: head + size / 2 + }; + } + _calculateBarIndexPixels(index2, ruler) { + const scale = ruler.scale; + const options = this.options; + const skipNull = options.skipNull; + const maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity); + let center, size; + if (ruler.grouped) { + const stackCount = skipNull ? this._getStackCount(index2) : ruler.stackCount; + const range = options.barThickness === "flex" ? computeFlexCategoryTraits(index2, ruler, options, stackCount) : computeFitCategoryTraits(index2, ruler, options, stackCount); + const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index2 : void 0); + center = range.start + range.chunk * stackIndex + range.chunk / 2; + size = Math.min(maxBarThickness, range.chunk * range.ratio); + } else { + center = scale.getPixelForValue(this.getParsed(index2)[scale.axis], index2); + size = Math.min(maxBarThickness, ruler.min * ruler.ratio); + } + return { + base: center - size / 2, + head: center + size / 2, + center, + size + }; + } + draw() { + const meta = this._cachedMeta; + const vScale = meta.vScale; + const rects = meta.data; + const ilen = rects.length; + let i = 0; + for (; i < ilen; ++i) { + if (this.getParsed(i)[vScale.axis] !== null) { + rects[i].draw(this._ctx); + } + } + } +}; +__publicField(BarController, "id", "bar"); +__publicField(BarController, "defaults", { + datasetElementType: false, + dataElementType: "bar", + categoryPercentage: 0.8, + barPercentage: 0.9, + grouped: true, + animations: { + numbers: { + type: "number", + properties: [ + "x", + "y", + "base", + "width", + "height" + ] + } + } +}); +__publicField(BarController, "overrides", { + scales: { + _index_: { + type: "category", + offset: true, + grid: { + offset: true + } + }, + _value_: { + type: "linear", + beginAtZero: true + } + } +}); +var BubbleController = class extends DatasetController { + initialize() { + this.enableOptionSharing = true; + super.initialize(); + } + parsePrimitiveData(meta, data, start, count) { + const parsed = super.parsePrimitiveData(meta, data, start, count); + for (let i = 0; i < parsed.length; i++) { + parsed[i]._custom = this.resolveDataElementOptions(i + start).radius; + } + return parsed; + } + parseArrayData(meta, data, start, count) { + const parsed = super.parseArrayData(meta, data, start, count); + for (let i = 0; i < parsed.length; i++) { + const item = data[start + i]; + parsed[i]._custom = valueOrDefault(item[2], this.resolveDataElementOptions(i + start).radius); + } + return parsed; + } + parseObjectData(meta, data, start, count) { + const parsed = super.parseObjectData(meta, data, start, count); + for (let i = 0; i < parsed.length; i++) { + const item = data[start + i]; + parsed[i]._custom = valueOrDefault(item && item.r && +item.r, this.resolveDataElementOptions(i + start).radius); + } + return parsed; + } + getMaxOverflow() { + const data = this._cachedMeta.data; + let max = 0; + for (let i = data.length - 1; i >= 0; --i) { + max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2); + } + return max > 0 && max; + } + getLabelAndValue(index2) { + const meta = this._cachedMeta; + const labels = this.chart.data.labels || []; + const { xScale, yScale } = meta; + const parsed = this.getParsed(index2); + const x = xScale.getLabelForValue(parsed.x); + const y = yScale.getLabelForValue(parsed.y); + const r = parsed._custom; + return { + label: labels[index2] || "", + value: "(" + x + ", " + y + (r ? ", " + r : "") + ")" + }; + } + update(mode) { + const points = this._cachedMeta.data; + this.updateElements(points, 0, points.length, mode); + } + updateElements(points, start, count, mode) { + const reset = mode === "reset"; + const { iScale, vScale } = this._cachedMeta; + const { sharedOptions, includeOptions } = this._getSharedOptions(start, mode); + const iAxis = iScale.axis; + const vAxis = vScale.axis; + for (let i = start; i < start + count; i++) { + const point = points[i]; + const parsed = !reset && this.getParsed(i); + const properties = {}; + const iPixel = properties[iAxis] = reset ? iScale.getPixelForDecimal(0.5) : iScale.getPixelForValue(parsed[iAxis]); + const vPixel = properties[vAxis] = reset ? vScale.getBasePixel() : vScale.getPixelForValue(parsed[vAxis]); + properties.skip = isNaN(iPixel) || isNaN(vPixel); + if (includeOptions) { + properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? "active" : mode); + if (reset) { + properties.options.radius = 0; + } + } + this.updateElement(point, i, properties, mode); + } + } + resolveDataElementOptions(index2, mode) { + const parsed = this.getParsed(index2); + let values = super.resolveDataElementOptions(index2, mode); + if (values.$shared) { + values = Object.assign({}, values, { + $shared: false + }); + } + const radius = values.radius; + if (mode !== "active") { + values.radius = 0; + } + values.radius += valueOrDefault(parsed && parsed._custom, radius); + return values; + } +}; +__publicField(BubbleController, "id", "bubble"); +__publicField(BubbleController, "defaults", { + datasetElementType: false, + dataElementType: "point", + animations: { + numbers: { + type: "number", + properties: [ + "x", + "y", + "borderWidth", + "radius" + ] + } + } +}); +__publicField(BubbleController, "overrides", { + scales: { + x: { + type: "linear" + }, + y: { + type: "linear" + } + } +}); +function getRatioAndOffset(rotation, circumference, cutout) { + let ratioX = 1; + let ratioY = 1; + let offsetX = 0; + let offsetY = 0; + if (circumference < TAU) { + const startAngle = rotation; + const endAngle = startAngle + circumference; + const startX = Math.cos(startAngle); + const startY = Math.sin(startAngle); + const endX = Math.cos(endAngle); + const endY = Math.sin(endAngle); + const calcMax = (angle, a, b) => _angleBetween(angle, startAngle, endAngle, true) ? 1 : Math.max(a, a * cutout, b, b * cutout); + const calcMin = (angle, a, b) => _angleBetween(angle, startAngle, endAngle, true) ? -1 : Math.min(a, a * cutout, b, b * cutout); + const maxX = calcMax(0, startX, endX); + const maxY = calcMax(HALF_PI, startY, endY); + const minX = calcMin(PI, startX, endX); + const minY = calcMin(PI + HALF_PI, startY, endY); + ratioX = (maxX - minX) / 2; + ratioY = (maxY - minY) / 2; + offsetX = -(maxX + minX) / 2; + offsetY = -(maxY + minY) / 2; + } + return { + ratioX, + ratioY, + offsetX, + offsetY + }; +} +var DoughnutController = class extends DatasetController { + constructor(chart, datasetIndex) { + super(chart, datasetIndex); + this.enableOptionSharing = true; + this.innerRadius = void 0; + this.outerRadius = void 0; + this.offsetX = void 0; + this.offsetY = void 0; + } + linkScales() { + } + parse(start, count) { + const data = this.getDataset().data; + const meta = this._cachedMeta; + if (this._parsing === false) { + meta._parsed = data; + } else { + let getter = (i2) => +data[i2]; + if (isObject(data[start])) { + const { key = "value" } = this._parsing; + getter = (i2) => +resolveObjectKey(data[i2], key); + } + let i, ilen; + for (i = start, ilen = start + count; i < ilen; ++i) { + meta._parsed[i] = getter(i); + } + } + } + _getRotation() { + return toRadians(this.options.rotation - 90); + } + _getCircumference() { + return toRadians(this.options.circumference); + } + _getRotationExtents() { + let min = TAU; + let max = -TAU; + for (let i = 0; i < this.chart.data.datasets.length; ++i) { + if (this.chart.isDatasetVisible(i) && this.chart.getDatasetMeta(i).type === this._type) { + const controller = this.chart.getDatasetMeta(i).controller; + const rotation = controller._getRotation(); + const circumference = controller._getCircumference(); + min = Math.min(min, rotation); + max = Math.max(max, rotation + circumference); + } + } + return { + rotation: min, + circumference: max - min + }; + } + update(mode) { + const chart = this.chart; + const { chartArea } = chart; + const meta = this._cachedMeta; + const arcs = meta.data; + const spacing = this.getMaxBorderWidth() + this.getMaxOffset(arcs) + this.options.spacing; + const maxSize = Math.max((Math.min(chartArea.width, chartArea.height) - spacing) / 2, 0); + const cutout = Math.min(toPercentage(this.options.cutout, maxSize), 1); + const chartWeight = this._getRingWeight(this.index); + const { circumference, rotation } = this._getRotationExtents(); + const { ratioX, ratioY, offsetX, offsetY } = getRatioAndOffset(rotation, circumference, cutout); + const maxWidth = (chartArea.width - spacing) / ratioX; + const maxHeight = (chartArea.height - spacing) / ratioY; + const maxRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0); + const outerRadius = toDimension(this.options.radius, maxRadius); + const innerRadius = Math.max(outerRadius * cutout, 0); + const radiusLength = (outerRadius - innerRadius) / this._getVisibleDatasetWeightTotal(); + this.offsetX = offsetX * outerRadius; + this.offsetY = offsetY * outerRadius; + meta.total = this.calculateTotal(); + this.outerRadius = outerRadius - radiusLength * this._getRingWeightOffset(this.index); + this.innerRadius = Math.max(this.outerRadius - radiusLength * chartWeight, 0); + this.updateElements(arcs, 0, arcs.length, mode); + } + _circumference(i, reset) { + const opts = this.options; + const meta = this._cachedMeta; + const circumference = this._getCircumference(); + if (reset && opts.animation.animateRotate || !this.chart.getDataVisibility(i) || meta._parsed[i] === null || meta.data[i].hidden) { + return 0; + } + return this.calculateCircumference(meta._parsed[i] * circumference / TAU); + } + updateElements(arcs, start, count, mode) { + const reset = mode === "reset"; + const chart = this.chart; + const chartArea = chart.chartArea; + const opts = chart.options; + const animationOpts = opts.animation; + const centerX = (chartArea.left + chartArea.right) / 2; + const centerY = (chartArea.top + chartArea.bottom) / 2; + const animateScale = reset && animationOpts.animateScale; + const innerRadius = animateScale ? 0 : this.innerRadius; + const outerRadius = animateScale ? 0 : this.outerRadius; + const { sharedOptions, includeOptions } = this._getSharedOptions(start, mode); + let startAngle = this._getRotation(); + let i; + for (i = 0; i < start; ++i) { + startAngle += this._circumference(i, reset); + } + for (i = start; i < start + count; ++i) { + const circumference = this._circumference(i, reset); + const arc = arcs[i]; + const properties = { + x: centerX + this.offsetX, + y: centerY + this.offsetY, + startAngle, + endAngle: startAngle + circumference, + circumference, + outerRadius, + innerRadius + }; + if (includeOptions) { + properties.options = sharedOptions || this.resolveDataElementOptions(i, arc.active ? "active" : mode); + } + startAngle += circumference; + this.updateElement(arc, i, properties, mode); + } + } + calculateTotal() { + const meta = this._cachedMeta; + const metaData = meta.data; + let total = 0; + let i; + for (i = 0; i < metaData.length; i++) { + const value = meta._parsed[i]; + if (value !== null && !isNaN(value) && this.chart.getDataVisibility(i) && !metaData[i].hidden) { + total += Math.abs(value); + } + } + return total; + } + calculateCircumference(value) { + const total = this._cachedMeta.total; + if (total > 0 && !isNaN(value)) { + return TAU * (Math.abs(value) / total); + } + return 0; + } + getLabelAndValue(index2) { + const meta = this._cachedMeta; + const chart = this.chart; + const labels = chart.data.labels || []; + const value = formatNumber(meta._parsed[index2], chart.options.locale); + return { + label: labels[index2] || "", + value + }; + } + getMaxBorderWidth(arcs) { + let max = 0; + const chart = this.chart; + let i, ilen, meta, controller, options; + if (!arcs) { + for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) { + if (chart.isDatasetVisible(i)) { + meta = chart.getDatasetMeta(i); + arcs = meta.data; + controller = meta.controller; + break; + } + } + } + if (!arcs) { + return 0; + } + for (i = 0, ilen = arcs.length; i < ilen; ++i) { + options = controller.resolveDataElementOptions(i); + if (options.borderAlign !== "inner") { + max = Math.max(max, options.borderWidth || 0, options.hoverBorderWidth || 0); + } + } + return max; + } + getMaxOffset(arcs) { + let max = 0; + for (let i = 0, ilen = arcs.length; i < ilen; ++i) { + const options = this.resolveDataElementOptions(i); + max = Math.max(max, options.offset || 0, options.hoverOffset || 0); + } + return max; + } + _getRingWeightOffset(datasetIndex) { + let ringWeightOffset = 0; + for (let i = 0; i < datasetIndex; ++i) { + if (this.chart.isDatasetVisible(i)) { + ringWeightOffset += this._getRingWeight(i); + } + } + return ringWeightOffset; + } + _getRingWeight(datasetIndex) { + return Math.max(valueOrDefault(this.chart.data.datasets[datasetIndex].weight, 1), 0); + } + _getVisibleDatasetWeightTotal() { + return this._getRingWeightOffset(this.chart.data.datasets.length) || 1; + } +}; +__publicField(DoughnutController, "id", "doughnut"); +__publicField(DoughnutController, "defaults", { + datasetElementType: false, + dataElementType: "arc", + animation: { + animateRotate: true, + animateScale: false + }, + animations: { + numbers: { + type: "number", + properties: [ + "circumference", + "endAngle", + "innerRadius", + "outerRadius", + "startAngle", + "x", + "y", + "offset", + "borderWidth", + "spacing" + ] + } + }, + cutout: "50%", + rotation: 0, + circumference: 360, + radius: "100%", + spacing: 0, + indexAxis: "r" +}); +__publicField(DoughnutController, "descriptors", { + _scriptable: (name) => name !== "spacing", + _indexable: (name) => name !== "spacing" && !name.startsWith("borderDash") && !name.startsWith("hoverBorderDash") +}); +__publicField(DoughnutController, "overrides", { + aspectRatio: 1, + plugins: { + legend: { + labels: { + generateLabels(chart) { + const data = chart.data; + if (data.labels.length && data.datasets.length) { + const { labels: { pointStyle, color: color3 } } = chart.legend.options; + return data.labels.map((label, i) => { + const meta = chart.getDatasetMeta(0); + const style = meta.controller.getStyle(i); + return { + text: label, + fillStyle: style.backgroundColor, + strokeStyle: style.borderColor, + fontColor: color3, + lineWidth: style.borderWidth, + pointStyle, + hidden: !chart.getDataVisibility(i), + index: i + }; + }); + } + return []; + } + }, + onClick(e, legendItem, legend) { + legend.chart.toggleDataVisibility(legendItem.index); + legend.chart.update(); + } + } + } +}); +var LineController = class extends DatasetController { + initialize() { + this.enableOptionSharing = true; + this.supportsDecimation = true; + super.initialize(); + } + update(mode) { + const meta = this._cachedMeta; + const { dataset: line, data: points = [], _dataset } = meta; + const animationsDisabled = this.chart._animationsDisabled; + let { start, count } = _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled); + this._drawStart = start; + this._drawCount = count; + if (_scaleRangesChanged(meta)) { + start = 0; + count = points.length; + } + line._chart = this.chart; + line._datasetIndex = this.index; + line._decimated = !!_dataset._decimated; + line.points = points; + const options = this.resolveDatasetElementOptions(mode); + if (!this.options.showLine) { + options.borderWidth = 0; + } + options.segment = this.options.segment; + this.updateElement(line, void 0, { + animated: !animationsDisabled, + options + }, mode); + this.updateElements(points, start, count, mode); + } + updateElements(points, start, count, mode) { + const reset = mode === "reset"; + const { iScale, vScale, _stacked, _dataset } = this._cachedMeta; + const { sharedOptions, includeOptions } = this._getSharedOptions(start, mode); + const iAxis = iScale.axis; + const vAxis = vScale.axis; + const { spanGaps, segment } = this.options; + const maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY; + const directUpdate = this.chart._animationsDisabled || reset || mode === "none"; + const end = start + count; + const pointsCount = points.length; + let prevParsed = start > 0 && this.getParsed(start - 1); + for (let i = 0; i < pointsCount; ++i) { + const point = points[i]; + const properties = directUpdate ? point : {}; + if (i < start || i >= end) { + properties.skip = true; + continue; + } + const parsed = this.getParsed(i); + const nullData = isNullOrUndef(parsed[vAxis]); + const iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i); + const vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i); + properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData; + properties.stop = i > 0 && Math.abs(parsed[iAxis] - prevParsed[iAxis]) > maxGapLength; + if (segment) { + properties.parsed = parsed; + properties.raw = _dataset.data[i]; + } + if (includeOptions) { + properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? "active" : mode); + } + if (!directUpdate) { + this.updateElement(point, i, properties, mode); + } + prevParsed = parsed; + } + } + getMaxOverflow() { + const meta = this._cachedMeta; + const dataset = meta.dataset; + const border = dataset.options && dataset.options.borderWidth || 0; + const data = meta.data || []; + if (!data.length) { + return border; + } + const firstPoint = data[0].size(this.resolveDataElementOptions(0)); + const lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1)); + return Math.max(border, firstPoint, lastPoint) / 2; + } + draw() { + const meta = this._cachedMeta; + meta.dataset.updateControlPoints(this.chart.chartArea, meta.iScale.axis); + super.draw(); + } +}; +__publicField(LineController, "id", "line"); +__publicField(LineController, "defaults", { + datasetElementType: "line", + dataElementType: "point", + showLine: true, + spanGaps: false +}); +__publicField(LineController, "overrides", { + scales: { + _index_: { + type: "category" + }, + _value_: { + type: "linear" + } + } +}); +var PolarAreaController = class extends DatasetController { + constructor(chart, datasetIndex) { + super(chart, datasetIndex); + this.innerRadius = void 0; + this.outerRadius = void 0; + } + getLabelAndValue(index2) { + const meta = this._cachedMeta; + const chart = this.chart; + const labels = chart.data.labels || []; + const value = formatNumber(meta._parsed[index2].r, chart.options.locale); + return { + label: labels[index2] || "", + value + }; + } + parseObjectData(meta, data, start, count) { + return _parseObjectDataRadialScale.bind(this)(meta, data, start, count); + } + update(mode) { + const arcs = this._cachedMeta.data; + this._updateRadius(); + this.updateElements(arcs, 0, arcs.length, mode); + } + getMinMax() { + const meta = this._cachedMeta; + const range = { + min: Number.POSITIVE_INFINITY, + max: Number.NEGATIVE_INFINITY + }; + meta.data.forEach((element, index2) => { + const parsed = this.getParsed(index2).r; + if (!isNaN(parsed) && this.chart.getDataVisibility(index2)) { + if (parsed < range.min) { + range.min = parsed; + } + if (parsed > range.max) { + range.max = parsed; + } + } + }); + return range; + } + _updateRadius() { + const chart = this.chart; + const chartArea = chart.chartArea; + const opts = chart.options; + const minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); + const outerRadius = Math.max(minSize / 2, 0); + const innerRadius = Math.max(opts.cutoutPercentage ? outerRadius / 100 * opts.cutoutPercentage : 1, 0); + const radiusLength = (outerRadius - innerRadius) / chart.getVisibleDatasetCount(); + this.outerRadius = outerRadius - radiusLength * this.index; + this.innerRadius = this.outerRadius - radiusLength; + } + updateElements(arcs, start, count, mode) { + const reset = mode === "reset"; + const chart = this.chart; + const opts = chart.options; + const animationOpts = opts.animation; + const scale = this._cachedMeta.rScale; + const centerX = scale.xCenter; + const centerY = scale.yCenter; + const datasetStartAngle = scale.getIndexAngle(0) - 0.5 * PI; + let angle = datasetStartAngle; + let i; + const defaultAngle = 360 / this.countVisibleElements(); + for (i = 0; i < start; ++i) { + angle += this._computeAngle(i, mode, defaultAngle); + } + for (i = start; i < start + count; i++) { + const arc = arcs[i]; + let startAngle = angle; + let endAngle = angle + this._computeAngle(i, mode, defaultAngle); + let outerRadius = chart.getDataVisibility(i) ? scale.getDistanceFromCenterForValue(this.getParsed(i).r) : 0; + angle = endAngle; + if (reset) { + if (animationOpts.animateScale) { + outerRadius = 0; + } + if (animationOpts.animateRotate) { + startAngle = endAngle = datasetStartAngle; + } + } + const properties = { + x: centerX, + y: centerY, + innerRadius: 0, + outerRadius, + startAngle, + endAngle, + options: this.resolveDataElementOptions(i, arc.active ? "active" : mode) + }; + this.updateElement(arc, i, properties, mode); + } + } + countVisibleElements() { + const meta = this._cachedMeta; + let count = 0; + meta.data.forEach((element, index2) => { + if (!isNaN(this.getParsed(index2).r) && this.chart.getDataVisibility(index2)) { + count++; + } + }); + return count; + } + _computeAngle(index2, mode, defaultAngle) { + return this.chart.getDataVisibility(index2) ? toRadians(this.resolveDataElementOptions(index2, mode).angle || defaultAngle) : 0; + } +}; +__publicField(PolarAreaController, "id", "polarArea"); +__publicField(PolarAreaController, "defaults", { + dataElementType: "arc", + animation: { + animateRotate: true, + animateScale: true + }, + animations: { + numbers: { + type: "number", + properties: [ + "x", + "y", + "startAngle", + "endAngle", + "innerRadius", + "outerRadius" + ] + } + }, + indexAxis: "r", + startAngle: 0 +}); +__publicField(PolarAreaController, "overrides", { + aspectRatio: 1, + plugins: { + legend: { + labels: { + generateLabels(chart) { + const data = chart.data; + if (data.labels.length && data.datasets.length) { + const { labels: { pointStyle, color: color3 } } = chart.legend.options; + return data.labels.map((label, i) => { + const meta = chart.getDatasetMeta(0); + const style = meta.controller.getStyle(i); + return { + text: label, + fillStyle: style.backgroundColor, + strokeStyle: style.borderColor, + fontColor: color3, + lineWidth: style.borderWidth, + pointStyle, + hidden: !chart.getDataVisibility(i), + index: i + }; + }); + } + return []; + } + }, + onClick(e, legendItem, legend) { + legend.chart.toggleDataVisibility(legendItem.index); + legend.chart.update(); + } + } + }, + scales: { + r: { + type: "radialLinear", + angleLines: { + display: false + }, + beginAtZero: true, + grid: { + circular: true + }, + pointLabels: { + display: false + }, + startAngle: 0 + } + } +}); +var PieController = class extends DoughnutController { +}; +__publicField(PieController, "id", "pie"); +__publicField(PieController, "defaults", { + cutout: 0, + rotation: 0, + circumference: 360, + radius: "100%" +}); +var RadarController = class extends DatasetController { + getLabelAndValue(index2) { + const vScale = this._cachedMeta.vScale; + const parsed = this.getParsed(index2); + return { + label: vScale.getLabels()[index2], + value: "" + vScale.getLabelForValue(parsed[vScale.axis]) + }; + } + parseObjectData(meta, data, start, count) { + return _parseObjectDataRadialScale.bind(this)(meta, data, start, count); + } + update(mode) { + const meta = this._cachedMeta; + const line = meta.dataset; + const points = meta.data || []; + const labels = meta.iScale.getLabels(); + line.points = points; + if (mode !== "resize") { + const options = this.resolveDatasetElementOptions(mode); + if (!this.options.showLine) { + options.borderWidth = 0; + } + const properties = { + _loop: true, + _fullLoop: labels.length === points.length, + options + }; + this.updateElement(line, void 0, properties, mode); + } + this.updateElements(points, 0, points.length, mode); + } + updateElements(points, start, count, mode) { + const scale = this._cachedMeta.rScale; + const reset = mode === "reset"; + for (let i = start; i < start + count; i++) { + const point = points[i]; + const options = this.resolveDataElementOptions(i, point.active ? "active" : mode); + const pointPosition = scale.getPointPositionForValue(i, this.getParsed(i).r); + const x = reset ? scale.xCenter : pointPosition.x; + const y = reset ? scale.yCenter : pointPosition.y; + const properties = { + x, + y, + angle: pointPosition.angle, + skip: isNaN(x) || isNaN(y), + options + }; + this.updateElement(point, i, properties, mode); + } + } +}; +__publicField(RadarController, "id", "radar"); +__publicField(RadarController, "defaults", { + datasetElementType: "line", + dataElementType: "point", + indexAxis: "r", + showLine: true, + elements: { + line: { + fill: "start" + } + } +}); +__publicField(RadarController, "overrides", { + aspectRatio: 1, + scales: { + r: { + type: "radialLinear" + } + } +}); +var ScatterController = class extends DatasetController { + getLabelAndValue(index2) { + const meta = this._cachedMeta; + const labels = this.chart.data.labels || []; + const { xScale, yScale } = meta; + const parsed = this.getParsed(index2); + const x = xScale.getLabelForValue(parsed.x); + const y = yScale.getLabelForValue(parsed.y); + return { + label: labels[index2] || "", + value: "(" + x + ", " + y + ")" + }; + } + update(mode) { + const meta = this._cachedMeta; + const { data: points = [] } = meta; + const animationsDisabled = this.chart._animationsDisabled; + let { start, count } = _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled); + this._drawStart = start; + this._drawCount = count; + if (_scaleRangesChanged(meta)) { + start = 0; + count = points.length; + } + if (this.options.showLine) { + if (!this.datasetElementType) { + this.addElements(); + } + const { dataset: line, _dataset } = meta; + line._chart = this.chart; + line._datasetIndex = this.index; + line._decimated = !!_dataset._decimated; + line.points = points; + const options = this.resolveDatasetElementOptions(mode); + options.segment = this.options.segment; + this.updateElement(line, void 0, { + animated: !animationsDisabled, + options + }, mode); + } else if (this.datasetElementType) { + delete meta.dataset; + this.datasetElementType = false; + } + this.updateElements(points, start, count, mode); + } + addElements() { + const { showLine } = this.options; + if (!this.datasetElementType && showLine) { + this.datasetElementType = this.chart.registry.getElement("line"); + } + super.addElements(); + } + updateElements(points, start, count, mode) { + const reset = mode === "reset"; + const { iScale, vScale, _stacked, _dataset } = this._cachedMeta; + const firstOpts = this.resolveDataElementOptions(start, mode); + const sharedOptions = this.getSharedOptions(firstOpts); + const includeOptions = this.includeOptions(mode, sharedOptions); + const iAxis = iScale.axis; + const vAxis = vScale.axis; + const { spanGaps, segment } = this.options; + const maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY; + const directUpdate = this.chart._animationsDisabled || reset || mode === "none"; + let prevParsed = start > 0 && this.getParsed(start - 1); + for (let i = start; i < start + count; ++i) { + const point = points[i]; + const parsed = this.getParsed(i); + const properties = directUpdate ? point : {}; + const nullData = isNullOrUndef(parsed[vAxis]); + const iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i); + const vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i); + properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData; + properties.stop = i > 0 && Math.abs(parsed[iAxis] - prevParsed[iAxis]) > maxGapLength; + if (segment) { + properties.parsed = parsed; + properties.raw = _dataset.data[i]; + } + if (includeOptions) { + properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? "active" : mode); + } + if (!directUpdate) { + this.updateElement(point, i, properties, mode); + } + prevParsed = parsed; + } + this.updateSharedOptions(sharedOptions, mode, firstOpts); + } + getMaxOverflow() { + const meta = this._cachedMeta; + const data = meta.data || []; + if (!this.options.showLine) { + let max = 0; + for (let i = data.length - 1; i >= 0; --i) { + max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2); + } + return max > 0 && max; + } + const dataset = meta.dataset; + const border = dataset.options && dataset.options.borderWidth || 0; + if (!data.length) { + return border; + } + const firstPoint = data[0].size(this.resolveDataElementOptions(0)); + const lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1)); + return Math.max(border, firstPoint, lastPoint) / 2; + } +}; +__publicField(ScatterController, "id", "scatter"); +__publicField(ScatterController, "defaults", { + datasetElementType: false, + dataElementType: "point", + showLine: false, + fill: false +}); +__publicField(ScatterController, "overrides", { + interaction: { + mode: "point" + }, + scales: { + x: { + type: "linear" + }, + y: { + type: "linear" + } + } +}); +var controllers = /* @__PURE__ */ Object.freeze({ + __proto__: null, + BarController, + BubbleController, + DoughnutController, + LineController, + PieController, + PolarAreaController, + RadarController, + ScatterController +}); +function abstract() { + throw new Error("This method is not implemented: Check that a complete date adapter is provided."); +} +var DateAdapterBase = class { + constructor(options) { + __publicField(this, "options"); + this.options = options || {}; + } + /** + * Override default date adapter methods. + * Accepts type parameter to define options type. + * @example + * Chart._adapters._date.override<{myAdapterOption: string}>({ + * init() { + * console.log(this.options.myAdapterOption); + * } + * }) + */ + static override(members) { + Object.assign(DateAdapterBase.prototype, members); + } + // eslint-disable-next-line @typescript-eslint/no-empty-function + init() { + } + formats() { + return abstract(); + } + parse() { + return abstract(); + } + format() { + return abstract(); + } + add() { + return abstract(); + } + diff() { + return abstract(); + } + startOf() { + return abstract(); + } + endOf() { + return abstract(); + } +}; +var adapters = { + _date: DateAdapterBase +}; +function binarySearch(metaset, axis, value, intersect) { + const { controller, data, _sorted } = metaset; + const iScale = controller._cachedMeta.iScale; + if (iScale && axis === iScale.axis && axis !== "r" && _sorted && data.length) { + const lookupMethod = iScale._reversePixels ? _rlookupByKey : _lookupByKey; + if (!intersect) { + return lookupMethod(data, axis, value); + } else if (controller._sharedOptions) { + const el = data[0]; + const range = typeof el.getRange === "function" && el.getRange(axis); + if (range) { + const start = lookupMethod(data, axis, value - range); + const end = lookupMethod(data, axis, value + range); + return { + lo: start.lo, + hi: end.hi + }; + } + } + } + return { + lo: 0, + hi: data.length - 1 + }; +} +function evaluateInteractionItems(chart, axis, position, handler, intersect) { + const metasets = chart.getSortedVisibleDatasetMetas(); + const value = position[axis]; + for (let i = 0, ilen = metasets.length; i < ilen; ++i) { + const { index: index2, data } = metasets[i]; + const { lo, hi } = binarySearch(metasets[i], axis, value, intersect); + for (let j = lo; j <= hi; ++j) { + const element = data[j]; + if (!element.skip) { + handler(element, index2, j); + } + } + } +} +function getDistanceMetricForAxis(axis) { + const useX = axis.indexOf("x") !== -1; + const useY = axis.indexOf("y") !== -1; + return function(pt1, pt2) { + const deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0; + const deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0; + return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); + }; +} +function getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) { + const items = []; + if (!includeInvisible && !chart.isPointInArea(position)) { + return items; + } + const evaluationFunc = function(element, datasetIndex, index2) { + if (!includeInvisible && !_isPointInArea(element, chart.chartArea, 0)) { + return; + } + if (element.inRange(position.x, position.y, useFinalPosition)) { + items.push({ + element, + datasetIndex, + index: index2 + }); + } + }; + evaluateInteractionItems(chart, axis, position, evaluationFunc, true); + return items; +} +function getNearestRadialItems(chart, position, axis, useFinalPosition) { + let items = []; + function evaluationFunc(element, datasetIndex, index2) { + const { startAngle, endAngle } = element.getProps([ + "startAngle", + "endAngle" + ], useFinalPosition); + const { angle } = getAngleFromPoint(element, { + x: position.x, + y: position.y + }); + if (_angleBetween(angle, startAngle, endAngle)) { + items.push({ + element, + datasetIndex, + index: index2 + }); + } + } + evaluateInteractionItems(chart, axis, position, evaluationFunc); + return items; +} +function getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) { + let items = []; + const distanceMetric = getDistanceMetricForAxis(axis); + let minDistance = Number.POSITIVE_INFINITY; + function evaluationFunc(element, datasetIndex, index2) { + const inRange2 = element.inRange(position.x, position.y, useFinalPosition); + if (intersect && !inRange2) { + return; + } + const center = element.getCenterPoint(useFinalPosition); + const pointInArea = !!includeInvisible || chart.isPointInArea(center); + if (!pointInArea && !inRange2) { + return; + } + const distance = distanceMetric(position, center); + if (distance < minDistance) { + items = [ + { + element, + datasetIndex, + index: index2 + } + ]; + minDistance = distance; + } else if (distance === minDistance) { + items.push({ + element, + datasetIndex, + index: index2 + }); + } + } + evaluateInteractionItems(chart, axis, position, evaluationFunc); + return items; +} +function getNearestItems(chart, position, axis, intersect, useFinalPosition, includeInvisible) { + if (!includeInvisible && !chart.isPointInArea(position)) { + return []; + } + return axis === "r" && !intersect ? getNearestRadialItems(chart, position, axis, useFinalPosition) : getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition, includeInvisible); +} +function getAxisItems(chart, position, axis, intersect, useFinalPosition) { + const items = []; + const rangeMethod = axis === "x" ? "inXRange" : "inYRange"; + let intersectsItem = false; + evaluateInteractionItems(chart, axis, position, (element, datasetIndex, index2) => { + if (element[rangeMethod](position[axis], useFinalPosition)) { + items.push({ + element, + datasetIndex, + index: index2 + }); + intersectsItem = intersectsItem || element.inRange(position.x, position.y, useFinalPosition); + } + }); + if (intersect && !intersectsItem) { + return []; + } + return items; +} +var Interaction = { + evaluateInteractionItems, + modes: { + index(chart, e, options, useFinalPosition) { + const position = getRelativePosition(e, chart); + const axis = options.axis || "x"; + const includeInvisible = options.includeInvisible || false; + const items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible); + const elements2 = []; + if (!items.length) { + return []; + } + chart.getSortedVisibleDatasetMetas().forEach((meta) => { + const index2 = items[0].index; + const element = meta.data[index2]; + if (element && !element.skip) { + elements2.push({ + element, + datasetIndex: meta.index, + index: index2 + }); + } + }); + return elements2; + }, + dataset(chart, e, options, useFinalPosition) { + const position = getRelativePosition(e, chart); + const axis = options.axis || "xy"; + const includeInvisible = options.includeInvisible || false; + let items = options.intersect ? getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible) : getNearestItems(chart, position, axis, false, useFinalPosition, includeInvisible); + if (items.length > 0) { + const datasetIndex = items[0].datasetIndex; + const data = chart.getDatasetMeta(datasetIndex).data; + items = []; + for (let i = 0; i < data.length; ++i) { + items.push({ + element: data[i], + datasetIndex, + index: i + }); + } + } + return items; + }, + point(chart, e, options, useFinalPosition) { + const position = getRelativePosition(e, chart); + const axis = options.axis || "xy"; + const includeInvisible = options.includeInvisible || false; + return getIntersectItems(chart, position, axis, useFinalPosition, includeInvisible); + }, + nearest(chart, e, options, useFinalPosition) { + const position = getRelativePosition(e, chart); + const axis = options.axis || "xy"; + const includeInvisible = options.includeInvisible || false; + return getNearestItems(chart, position, axis, options.intersect, useFinalPosition, includeInvisible); + }, + x(chart, e, options, useFinalPosition) { + const position = getRelativePosition(e, chart); + return getAxisItems(chart, position, "x", options.intersect, useFinalPosition); + }, + y(chart, e, options, useFinalPosition) { + const position = getRelativePosition(e, chart); + return getAxisItems(chart, position, "y", options.intersect, useFinalPosition); + } + } +}; +var STATIC_POSITIONS = [ + "left", + "top", + "right", + "bottom" +]; +function filterByPosition(array, position) { + return array.filter((v) => v.pos === position); +} +function filterDynamicPositionByAxis(array, axis) { + return array.filter((v) => STATIC_POSITIONS.indexOf(v.pos) === -1 && v.box.axis === axis); +} +function sortByWeight(array, reverse) { + return array.sort((a, b) => { + const v0 = reverse ? b : a; + const v1 = reverse ? a : b; + return v0.weight === v1.weight ? v0.index - v1.index : v0.weight - v1.weight; + }); +} +function wrapBoxes(boxes) { + const layoutBoxes = []; + let i, ilen, box, pos, stack, stackWeight; + for (i = 0, ilen = (boxes || []).length; i < ilen; ++i) { + box = boxes[i]; + ({ position: pos, options: { stack, stackWeight = 1 } } = box); + layoutBoxes.push({ + index: i, + box, + pos, + horizontal: box.isHorizontal(), + weight: box.weight, + stack: stack && pos + stack, + stackWeight + }); + } + return layoutBoxes; +} +function buildStacks(layouts2) { + const stacks = {}; + for (const wrap of layouts2) { + const { stack, pos, stackWeight } = wrap; + if (!stack || !STATIC_POSITIONS.includes(pos)) { + continue; + } + const _stack = stacks[stack] || (stacks[stack] = { + count: 0, + placed: 0, + weight: 0, + size: 0 + }); + _stack.count++; + _stack.weight += stackWeight; + } + return stacks; +} +function setLayoutDims(layouts2, params) { + const stacks = buildStacks(layouts2); + const { vBoxMaxWidth, hBoxMaxHeight } = params; + let i, ilen, layout; + for (i = 0, ilen = layouts2.length; i < ilen; ++i) { + layout = layouts2[i]; + const { fullSize } = layout.box; + const stack = stacks[layout.stack]; + const factor = stack && layout.stackWeight / stack.weight; + if (layout.horizontal) { + layout.width = factor ? factor * vBoxMaxWidth : fullSize && params.availableWidth; + layout.height = hBoxMaxHeight; + } else { + layout.width = vBoxMaxWidth; + layout.height = factor ? factor * hBoxMaxHeight : fullSize && params.availableHeight; + } + } + return stacks; +} +function buildLayoutBoxes(boxes) { + const layoutBoxes = wrapBoxes(boxes); + const fullSize = sortByWeight(layoutBoxes.filter((wrap) => wrap.box.fullSize), true); + const left = sortByWeight(filterByPosition(layoutBoxes, "left"), true); + const right = sortByWeight(filterByPosition(layoutBoxes, "right")); + const top = sortByWeight(filterByPosition(layoutBoxes, "top"), true); + const bottom = sortByWeight(filterByPosition(layoutBoxes, "bottom")); + const centerHorizontal = filterDynamicPositionByAxis(layoutBoxes, "x"); + const centerVertical = filterDynamicPositionByAxis(layoutBoxes, "y"); + return { + fullSize, + leftAndTop: left.concat(top), + rightAndBottom: right.concat(centerVertical).concat(bottom).concat(centerHorizontal), + chartArea: filterByPosition(layoutBoxes, "chartArea"), + vertical: left.concat(right).concat(centerVertical), + horizontal: top.concat(bottom).concat(centerHorizontal) + }; +} +function getCombinedMax(maxPadding, chartArea, a, b) { + return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]); +} +function updateMaxPadding(maxPadding, boxPadding) { + maxPadding.top = Math.max(maxPadding.top, boxPadding.top); + maxPadding.left = Math.max(maxPadding.left, boxPadding.left); + maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom); + maxPadding.right = Math.max(maxPadding.right, boxPadding.right); +} +function updateDims(chartArea, params, layout, stacks) { + const { pos, box } = layout; + const maxPadding = chartArea.maxPadding; + if (!isObject(pos)) { + if (layout.size) { + chartArea[pos] -= layout.size; + } + const stack = stacks[layout.stack] || { + size: 0, + count: 1 + }; + stack.size = Math.max(stack.size, layout.horizontal ? box.height : box.width); + layout.size = stack.size / stack.count; + chartArea[pos] += layout.size; + } + if (box.getPadding) { + updateMaxPadding(maxPadding, box.getPadding()); + } + const newWidth = Math.max(0, params.outerWidth - getCombinedMax(maxPadding, chartArea, "left", "right")); + const newHeight = Math.max(0, params.outerHeight - getCombinedMax(maxPadding, chartArea, "top", "bottom")); + const widthChanged = newWidth !== chartArea.w; + const heightChanged = newHeight !== chartArea.h; + chartArea.w = newWidth; + chartArea.h = newHeight; + return layout.horizontal ? { + same: widthChanged, + other: heightChanged + } : { + same: heightChanged, + other: widthChanged + }; +} +function handleMaxPadding(chartArea) { + const maxPadding = chartArea.maxPadding; + function updatePos(pos) { + const change = Math.max(maxPadding[pos] - chartArea[pos], 0); + chartArea[pos] += change; + return change; + } + chartArea.y += updatePos("top"); + chartArea.x += updatePos("left"); + updatePos("right"); + updatePos("bottom"); +} +function getMargins(horizontal, chartArea) { + const maxPadding = chartArea.maxPadding; + function marginForPositions(positions2) { + const margin = { + left: 0, + top: 0, + right: 0, + bottom: 0 + }; + positions2.forEach((pos) => { + margin[pos] = Math.max(chartArea[pos], maxPadding[pos]); + }); + return margin; + } + return horizontal ? marginForPositions([ + "left", + "right" + ]) : marginForPositions([ + "top", + "bottom" + ]); +} +function fitBoxes(boxes, chartArea, params, stacks) { + const refitBoxes = []; + let i, ilen, layout, box, refit, changed; + for (i = 0, ilen = boxes.length, refit = 0; i < ilen; ++i) { + layout = boxes[i]; + box = layout.box; + box.update(layout.width || chartArea.w, layout.height || chartArea.h, getMargins(layout.horizontal, chartArea)); + const { same, other } = updateDims(chartArea, params, layout, stacks); + refit |= same && refitBoxes.length; + changed = changed || other; + if (!box.fullSize) { + refitBoxes.push(layout); + } + } + return refit && fitBoxes(refitBoxes, chartArea, params, stacks) || changed; +} +function setBoxDims(box, left, top, width, height) { + box.top = top; + box.left = left; + box.right = left + width; + box.bottom = top + height; + box.width = width; + box.height = height; +} +function placeBoxes(boxes, chartArea, params, stacks) { + const userPadding = params.padding; + let { x, y } = chartArea; + for (const layout of boxes) { + const box = layout.box; + const stack = stacks[layout.stack] || { + count: 1, + placed: 0, + weight: 1 + }; + const weight = layout.stackWeight / stack.weight || 1; + if (layout.horizontal) { + const width = chartArea.w * weight; + const height = stack.size || box.height; + if (defined(stack.start)) { + y = stack.start; + } + if (box.fullSize) { + setBoxDims(box, userPadding.left, y, params.outerWidth - userPadding.right - userPadding.left, height); + } else { + setBoxDims(box, chartArea.left + stack.placed, y, width, height); + } + stack.start = y; + stack.placed += width; + y = box.bottom; + } else { + const height = chartArea.h * weight; + const width = stack.size || box.width; + if (defined(stack.start)) { + x = stack.start; + } + if (box.fullSize) { + setBoxDims(box, x, userPadding.top, width, params.outerHeight - userPadding.bottom - userPadding.top); + } else { + setBoxDims(box, x, chartArea.top + stack.placed, width, height); + } + stack.start = x; + stack.placed += height; + x = box.right; + } + } + chartArea.x = x; + chartArea.y = y; +} +var layouts = { + addBox(chart, item) { + if (!chart.boxes) { + chart.boxes = []; + } + item.fullSize = item.fullSize || false; + item.position = item.position || "top"; + item.weight = item.weight || 0; + item._layers = item._layers || function() { + return [ + { + z: 0, + draw(chartArea) { + item.draw(chartArea); + } + } + ]; + }; + chart.boxes.push(item); + }, + removeBox(chart, layoutItem) { + const index2 = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1; + if (index2 !== -1) { + chart.boxes.splice(index2, 1); + } + }, + configure(chart, item, options) { + item.fullSize = options.fullSize; + item.position = options.position; + item.weight = options.weight; + }, + update(chart, width, height, minPadding) { + if (!chart) { + return; + } + const padding = toPadding(chart.options.layout.padding); + const availableWidth = Math.max(width - padding.width, 0); + const availableHeight = Math.max(height - padding.height, 0); + const boxes = buildLayoutBoxes(chart.boxes); + const verticalBoxes = boxes.vertical; + const horizontalBoxes = boxes.horizontal; + each(chart.boxes, (box) => { + if (typeof box.beforeLayout === "function") { + box.beforeLayout(); + } + }); + const visibleVerticalBoxCount = verticalBoxes.reduce((total, wrap) => wrap.box.options && wrap.box.options.display === false ? total : total + 1, 0) || 1; + const params = Object.freeze({ + outerWidth: width, + outerHeight: height, + padding, + availableWidth, + availableHeight, + vBoxMaxWidth: availableWidth / 2 / visibleVerticalBoxCount, + hBoxMaxHeight: availableHeight / 2 + }); + const maxPadding = Object.assign({}, padding); + updateMaxPadding(maxPadding, toPadding(minPadding)); + const chartArea = Object.assign({ + maxPadding, + w: availableWidth, + h: availableHeight, + x: padding.left, + y: padding.top + }, padding); + const stacks = setLayoutDims(verticalBoxes.concat(horizontalBoxes), params); + fitBoxes(boxes.fullSize, chartArea, params, stacks); + fitBoxes(verticalBoxes, chartArea, params, stacks); + if (fitBoxes(horizontalBoxes, chartArea, params, stacks)) { + fitBoxes(verticalBoxes, chartArea, params, stacks); + } + handleMaxPadding(chartArea); + placeBoxes(boxes.leftAndTop, chartArea, params, stacks); + chartArea.x += chartArea.w; + chartArea.y += chartArea.h; + placeBoxes(boxes.rightAndBottom, chartArea, params, stacks); + chart.chartArea = { + left: chartArea.left, + top: chartArea.top, + right: chartArea.left + chartArea.w, + bottom: chartArea.top + chartArea.h, + height: chartArea.h, + width: chartArea.w + }; + each(boxes.chartArea, (layout) => { + const box = layout.box; + Object.assign(box, chart.chartArea); + box.update(chartArea.w, chartArea.h, { + left: 0, + top: 0, + right: 0, + bottom: 0 + }); + }); + } +}; +var BasePlatform = class { + acquireContext(canvas, aspectRatio) { + } + releaseContext(context) { + return false; + } + addEventListener(chart, type, listener) { + } + removeEventListener(chart, type, listener) { + } + getDevicePixelRatio() { + return 1; + } + getMaximumSize(element, width, height, aspectRatio) { + width = Math.max(0, width || element.width); + height = height || element.height; + return { + width, + height: Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height) + }; + } + isAttached(canvas) { + return true; + } + updateConfig(config) { + } +}; +var BasicPlatform = class extends BasePlatform { + acquireContext(item) { + return item && item.getContext && item.getContext("2d") || null; + } + updateConfig(config) { + config.options.animation = false; + } +}; +var EXPANDO_KEY = "$chartjs"; +var EVENT_TYPES = { + touchstart: "mousedown", + touchmove: "mousemove", + touchend: "mouseup", + pointerenter: "mouseenter", + pointerdown: "mousedown", + pointermove: "mousemove", + pointerup: "mouseup", + pointerleave: "mouseout", + pointerout: "mouseout" +}; +var isNullOrEmpty = (value) => value === null || value === ""; +function initCanvas(canvas, aspectRatio) { + const style = canvas.style; + const renderHeight = canvas.getAttribute("height"); + const renderWidth = canvas.getAttribute("width"); + canvas[EXPANDO_KEY] = { + initial: { + height: renderHeight, + width: renderWidth, + style: { + display: style.display, + height: style.height, + width: style.width + } + } + }; + style.display = style.display || "block"; + style.boxSizing = style.boxSizing || "border-box"; + if (isNullOrEmpty(renderWidth)) { + const displayWidth = readUsedSize(canvas, "width"); + if (displayWidth !== void 0) { + canvas.width = displayWidth; + } + } + if (isNullOrEmpty(renderHeight)) { + if (canvas.style.height === "") { + canvas.height = canvas.width / (aspectRatio || 2); + } else { + const displayHeight = readUsedSize(canvas, "height"); + if (displayHeight !== void 0) { + canvas.height = displayHeight; + } + } + } + return canvas; +} +var eventListenerOptions = supportsEventListenerOptions ? { + passive: true +} : false; +function addListener(node, type, listener) { + if (node) { + node.addEventListener(type, listener, eventListenerOptions); + } +} +function removeListener(chart, type, listener) { + if (chart && chart.canvas) { + chart.canvas.removeEventListener(type, listener, eventListenerOptions); + } +} +function fromNativeEvent(event, chart) { + const type = EVENT_TYPES[event.type] || event.type; + const { x, y } = getRelativePosition(event, chart); + return { + type, + chart, + native: event, + x: x !== void 0 ? x : null, + y: y !== void 0 ? y : null + }; +} +function nodeListContains(nodeList, canvas) { + for (const node of nodeList) { + if (node === canvas || node.contains(canvas)) { + return true; + } + } +} +function createAttachObserver(chart, type, listener) { + const canvas = chart.canvas; + const observer = new MutationObserver((entries) => { + let trigger = false; + for (const entry of entries) { + trigger = trigger || nodeListContains(entry.addedNodes, canvas); + trigger = trigger && !nodeListContains(entry.removedNodes, canvas); + } + if (trigger) { + listener(); + } + }); + observer.observe(document, { + childList: true, + subtree: true + }); + return observer; +} +function createDetachObserver(chart, type, listener) { + const canvas = chart.canvas; + const observer = new MutationObserver((entries) => { + let trigger = false; + for (const entry of entries) { + trigger = trigger || nodeListContains(entry.removedNodes, canvas); + trigger = trigger && !nodeListContains(entry.addedNodes, canvas); + } + if (trigger) { + listener(); + } + }); + observer.observe(document, { + childList: true, + subtree: true + }); + return observer; +} +var drpListeningCharts = /* @__PURE__ */ new Map(); +var oldDevicePixelRatio = 0; +function onWindowResize() { + const dpr = window.devicePixelRatio; + if (dpr === oldDevicePixelRatio) { + return; + } + oldDevicePixelRatio = dpr; + drpListeningCharts.forEach((resize, chart) => { + if (chart.currentDevicePixelRatio !== dpr) { + resize(); + } + }); +} +function listenDevicePixelRatioChanges(chart, resize) { + if (!drpListeningCharts.size) { + window.addEventListener("resize", onWindowResize); + } + drpListeningCharts.set(chart, resize); +} +function unlistenDevicePixelRatioChanges(chart) { + drpListeningCharts.delete(chart); + if (!drpListeningCharts.size) { + window.removeEventListener("resize", onWindowResize); + } +} +function createResizeObserver(chart, type, listener) { + const canvas = chart.canvas; + const container = canvas && _getParentNode(canvas); + if (!container) { + return; + } + const resize = throttled((width, height) => { + const w = container.clientWidth; + listener(width, height); + if (w < container.clientWidth) { + listener(); + } + }, window); + const observer = new ResizeObserver((entries) => { + const entry = entries[0]; + const width = entry.contentRect.width; + const height = entry.contentRect.height; + if (width === 0 && height === 0) { + return; + } + resize(width, height); + }); + observer.observe(container); + listenDevicePixelRatioChanges(chart, resize); + return observer; +} +function releaseObserver(chart, type, observer) { + if (observer) { + observer.disconnect(); + } + if (type === "resize") { + unlistenDevicePixelRatioChanges(chart); + } +} +function createProxyAndListen(chart, type, listener) { + const canvas = chart.canvas; + const proxy = throttled((event) => { + if (chart.ctx !== null) { + listener(fromNativeEvent(event, chart)); + } + }, chart); + addListener(canvas, type, proxy); + return proxy; +} +var DomPlatform = class extends BasePlatform { + acquireContext(canvas, aspectRatio) { + const context = canvas && canvas.getContext && canvas.getContext("2d"); + if (context && context.canvas === canvas) { + initCanvas(canvas, aspectRatio); + return context; + } + return null; + } + releaseContext(context) { + const canvas = context.canvas; + if (!canvas[EXPANDO_KEY]) { + return false; + } + const initial = canvas[EXPANDO_KEY].initial; + [ + "height", + "width" + ].forEach((prop) => { + const value = initial[prop]; + if (isNullOrUndef(value)) { + canvas.removeAttribute(prop); + } else { + canvas.setAttribute(prop, value); + } + }); + const style = initial.style || {}; + Object.keys(style).forEach((key) => { + canvas.style[key] = style[key]; + }); + canvas.width = canvas.width; + delete canvas[EXPANDO_KEY]; + return true; + } + addEventListener(chart, type, listener) { + this.removeEventListener(chart, type); + const proxies = chart.$proxies || (chart.$proxies = {}); + const handlers = { + attach: createAttachObserver, + detach: createDetachObserver, + resize: createResizeObserver + }; + const handler = handlers[type] || createProxyAndListen; + proxies[type] = handler(chart, type, listener); + } + removeEventListener(chart, type) { + const proxies = chart.$proxies || (chart.$proxies = {}); + const proxy = proxies[type]; + if (!proxy) { + return; + } + const handlers = { + attach: releaseObserver, + detach: releaseObserver, + resize: releaseObserver + }; + const handler = handlers[type] || removeListener; + handler(chart, type, proxy); + proxies[type] = void 0; + } + getDevicePixelRatio() { + return window.devicePixelRatio; + } + getMaximumSize(canvas, width, height, aspectRatio) { + return getMaximumSize(canvas, width, height, aspectRatio); + } + isAttached(canvas) { + const container = _getParentNode(canvas); + return !!(container && container.isConnected); + } +}; +function _detectPlatform(canvas) { + if (!_isDomSupported() || typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas) { + return BasicPlatform; + } + return DomPlatform; +} +var Element = class { + constructor() { + __publicField(this, "x"); + __publicField(this, "y"); + __publicField(this, "active", false); + __publicField(this, "options"); + __publicField(this, "$animations"); + } + tooltipPosition(useFinalPosition) { + const { x, y } = this.getProps([ + "x", + "y" + ], useFinalPosition); + return { + x, + y + }; + } + hasValue() { + return isNumber(this.x) && isNumber(this.y); + } + getProps(props, final) { + const anims = this.$animations; + if (!final || !anims) { + return this; + } + const ret = {}; + props.forEach((prop) => { + ret[prop] = anims[prop] && anims[prop].active() ? anims[prop]._to : this[prop]; + }); + return ret; + } +}; +__publicField(Element, "defaults", {}); +__publicField(Element, "defaultRoutes"); +function autoSkip(scale, ticks) { + const tickOpts = scale.options.ticks; + const determinedMaxTicks = determineMaxTicks(scale); + const ticksLimit = Math.min(tickOpts.maxTicksLimit || determinedMaxTicks, determinedMaxTicks); + const majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : []; + const numMajorIndices = majorIndices.length; + const first = majorIndices[0]; + const last = majorIndices[numMajorIndices - 1]; + const newTicks = []; + if (numMajorIndices > ticksLimit) { + skipMajors(ticks, newTicks, majorIndices, numMajorIndices / ticksLimit); + return newTicks; + } + const spacing = calculateSpacing(majorIndices, ticks, ticksLimit); + if (numMajorIndices > 0) { + let i, ilen; + const avgMajorSpacing = numMajorIndices > 1 ? Math.round((last - first) / (numMajorIndices - 1)) : null; + skip(ticks, newTicks, spacing, isNullOrUndef(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first); + for (i = 0, ilen = numMajorIndices - 1; i < ilen; i++) { + skip(ticks, newTicks, spacing, majorIndices[i], majorIndices[i + 1]); + } + skip(ticks, newTicks, spacing, last, isNullOrUndef(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing); + return newTicks; + } + skip(ticks, newTicks, spacing); + return newTicks; +} +function determineMaxTicks(scale) { + const offset2 = scale.options.offset; + const tickLength = scale._tickSize(); + const maxScale = scale._length / tickLength + (offset2 ? 0 : 1); + const maxChart = scale._maxLength / tickLength; + return Math.floor(Math.min(maxScale, maxChart)); +} +function calculateSpacing(majorIndices, ticks, ticksLimit) { + const evenMajorSpacing = getEvenSpacing(majorIndices); + const spacing = ticks.length / ticksLimit; + if (!evenMajorSpacing) { + return Math.max(spacing, 1); + } + const factors = _factorize(evenMajorSpacing); + for (let i = 0, ilen = factors.length - 1; i < ilen; i++) { + const factor = factors[i]; + if (factor > spacing) { + return factor; + } + } + return Math.max(spacing, 1); +} +function getMajorIndices(ticks) { + const result = []; + let i, ilen; + for (i = 0, ilen = ticks.length; i < ilen; i++) { + if (ticks[i].major) { + result.push(i); + } + } + return result; +} +function skipMajors(ticks, newTicks, majorIndices, spacing) { + let count = 0; + let next = majorIndices[0]; + let i; + spacing = Math.ceil(spacing); + for (i = 0; i < ticks.length; i++) { + if (i === next) { + newTicks.push(ticks[i]); + count++; + next = majorIndices[count * spacing]; + } + } +} +function skip(ticks, newTicks, spacing, majorStart, majorEnd) { + const start = valueOrDefault(majorStart, 0); + const end = Math.min(valueOrDefault(majorEnd, ticks.length), ticks.length); + let count = 0; + let length, i, next; + spacing = Math.ceil(spacing); + if (majorEnd) { + length = majorEnd - majorStart; + spacing = length / Math.floor(length / spacing); + } + next = start; + while (next < 0) { + count++; + next = Math.round(start + count * spacing); + } + for (i = Math.max(start, 0); i < end; i++) { + if (i === next) { + newTicks.push(ticks[i]); + count++; + next = Math.round(start + count * spacing); + } + } +} +function getEvenSpacing(arr) { + const len = arr.length; + let i, diff; + if (len < 2) { + return false; + } + for (diff = arr[0], i = 1; i < len; ++i) { + if (arr[i] - arr[i - 1] !== diff) { + return false; + } + } + return diff; +} +var reverseAlign = (align) => align === "left" ? "right" : align === "right" ? "left" : align; +var offsetFromEdge = (scale, edge, offset2) => edge === "top" || edge === "left" ? scale[edge] + offset2 : scale[edge] - offset2; +var getTicksLimit = (ticksLength, maxTicksLimit) => Math.min(maxTicksLimit || ticksLength, ticksLength); +function sample(arr, numItems) { + const result = []; + const increment = arr.length / numItems; + const len = arr.length; + let i = 0; + for (; i < len; i += increment) { + result.push(arr[Math.floor(i)]); + } + return result; +} +function getPixelForGridLine(scale, index2, offsetGridLines) { + const length = scale.ticks.length; + const validIndex2 = Math.min(index2, length - 1); + const start = scale._startPixel; + const end = scale._endPixel; + const epsilon = 1e-6; + let lineValue = scale.getPixelForTick(validIndex2); + let offset2; + if (offsetGridLines) { + if (length === 1) { + offset2 = Math.max(lineValue - start, end - lineValue); + } else if (index2 === 0) { + offset2 = (scale.getPixelForTick(1) - lineValue) / 2; + } else { + offset2 = (lineValue - scale.getPixelForTick(validIndex2 - 1)) / 2; + } + lineValue += validIndex2 < index2 ? offset2 : -offset2; + if (lineValue < start - epsilon || lineValue > end + epsilon) { + return; + } + } + return lineValue; +} +function garbageCollect(caches, length) { + each(caches, (cache) => { + const gc = cache.gc; + const gcLen = gc.length / 2; + let i; + if (gcLen > length) { + for (i = 0; i < gcLen; ++i) { + delete cache.data[gc[i]]; + } + gc.splice(0, gcLen); + } + }); +} +function getTickMarkLength(options) { + return options.drawTicks ? options.tickLength : 0; +} +function getTitleHeight(options, fallback) { + if (!options.display) { + return 0; + } + const font = toFont(options.font, fallback); + const padding = toPadding(options.padding); + const lines = isArray(options.text) ? options.text.length : 1; + return lines * font.lineHeight + padding.height; +} +function createScaleContext(parent, scale) { + return createContext(parent, { + scale, + type: "scale" + }); +} +function createTickContext(parent, index2, tick) { + return createContext(parent, { + tick, + index: index2, + type: "tick" + }); +} +function titleAlign(align, position, reverse) { + let ret = _toLeftRightCenter(align); + if (reverse && position !== "right" || !reverse && position === "right") { + ret = reverseAlign(ret); + } + return ret; +} +function titleArgs(scale, offset2, position, align) { + const { top, left, bottom, right, chart } = scale; + const { chartArea, scales: scales2 } = chart; + let rotation = 0; + let maxWidth, titleX, titleY; + const height = bottom - top; + const width = right - left; + if (scale.isHorizontal()) { + titleX = _alignStartEnd(align, left, right); + if (isObject(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + titleY = scales2[positionAxisID].getPixelForValue(value) + height - offset2; + } else if (position === "center") { + titleY = (chartArea.bottom + chartArea.top) / 2 + height - offset2; + } else { + titleY = offsetFromEdge(scale, position, offset2); + } + maxWidth = right - left; + } else { + if (isObject(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + titleX = scales2[positionAxisID].getPixelForValue(value) - width + offset2; + } else if (position === "center") { + titleX = (chartArea.left + chartArea.right) / 2 - width + offset2; + } else { + titleX = offsetFromEdge(scale, position, offset2); + } + titleY = _alignStartEnd(align, bottom, top); + rotation = position === "left" ? -HALF_PI : HALF_PI; + } + return { + titleX, + titleY, + maxWidth, + rotation + }; +} +var Scale = class extends Element { + constructor(cfg) { + super(); + this.id = cfg.id; + this.type = cfg.type; + this.options = void 0; + this.ctx = cfg.ctx; + this.chart = cfg.chart; + this.top = void 0; + this.bottom = void 0; + this.left = void 0; + this.right = void 0; + this.width = void 0; + this.height = void 0; + this._margins = { + left: 0, + right: 0, + top: 0, + bottom: 0 + }; + this.maxWidth = void 0; + this.maxHeight = void 0; + this.paddingTop = void 0; + this.paddingBottom = void 0; + this.paddingLeft = void 0; + this.paddingRight = void 0; + this.axis = void 0; + this.labelRotation = void 0; + this.min = void 0; + this.max = void 0; + this._range = void 0; + this.ticks = []; + this._gridLineItems = null; + this._labelItems = null; + this._labelSizes = null; + this._length = 0; + this._maxLength = 0; + this._longestTextCache = {}; + this._startPixel = void 0; + this._endPixel = void 0; + this._reversePixels = false; + this._userMax = void 0; + this._userMin = void 0; + this._suggestedMax = void 0; + this._suggestedMin = void 0; + this._ticksLength = 0; + this._borderValue = 0; + this._cache = {}; + this._dataLimitsCached = false; + this.$context = void 0; + } + init(options) { + this.options = options.setContext(this.getContext()); + this.axis = options.axis; + this._userMin = this.parse(options.min); + this._userMax = this.parse(options.max); + this._suggestedMin = this.parse(options.suggestedMin); + this._suggestedMax = this.parse(options.suggestedMax); + } + parse(raw, index2) { + return raw; + } + getUserBounds() { + let { _userMin, _userMax, _suggestedMin, _suggestedMax } = this; + _userMin = finiteOrDefault(_userMin, Number.POSITIVE_INFINITY); + _userMax = finiteOrDefault(_userMax, Number.NEGATIVE_INFINITY); + _suggestedMin = finiteOrDefault(_suggestedMin, Number.POSITIVE_INFINITY); + _suggestedMax = finiteOrDefault(_suggestedMax, Number.NEGATIVE_INFINITY); + return { + min: finiteOrDefault(_userMin, _suggestedMin), + max: finiteOrDefault(_userMax, _suggestedMax), + minDefined: isNumberFinite(_userMin), + maxDefined: isNumberFinite(_userMax) + }; + } + getMinMax(canStack) { + let { min, max, minDefined, maxDefined } = this.getUserBounds(); + let range; + if (minDefined && maxDefined) { + return { + min, + max + }; + } + const metas = this.getMatchingVisibleMetas(); + for (let i = 0, ilen = metas.length; i < ilen; ++i) { + range = metas[i].controller.getMinMax(this, canStack); + if (!minDefined) { + min = Math.min(min, range.min); + } + if (!maxDefined) { + max = Math.max(max, range.max); + } + } + min = maxDefined && min > max ? max : min; + max = minDefined && min > max ? min : max; + return { + min: finiteOrDefault(min, finiteOrDefault(max, min)), + max: finiteOrDefault(max, finiteOrDefault(min, max)) + }; + } + getPadding() { + return { + left: this.paddingLeft || 0, + top: this.paddingTop || 0, + right: this.paddingRight || 0, + bottom: this.paddingBottom || 0 + }; + } + getTicks() { + return this.ticks; + } + getLabels() { + const data = this.chart.data; + return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || []; + } + getLabelItems(chartArea = this.chart.chartArea) { + const items = this._labelItems || (this._labelItems = this._computeLabelItems(chartArea)); + return items; + } + beforeLayout() { + this._cache = {}; + this._dataLimitsCached = false; + } + beforeUpdate() { + callback(this.options.beforeUpdate, [ + this + ]); + } + update(maxWidth, maxHeight, margins) { + const { beginAtZero, grace, ticks: tickOpts } = this.options; + const sampleSize = tickOpts.sampleSize; + this.beforeUpdate(); + this.maxWidth = maxWidth; + this.maxHeight = maxHeight; + this._margins = margins = Object.assign({ + left: 0, + right: 0, + top: 0, + bottom: 0 + }, margins); + this.ticks = null; + this._labelSizes = null; + this._gridLineItems = null; + this._labelItems = null; + this.beforeSetDimensions(); + this.setDimensions(); + this.afterSetDimensions(); + this._maxLength = this.isHorizontal() ? this.width + margins.left + margins.right : this.height + margins.top + margins.bottom; + if (!this._dataLimitsCached) { + this.beforeDataLimits(); + this.determineDataLimits(); + this.afterDataLimits(); + this._range = _addGrace(this, grace, beginAtZero); + this._dataLimitsCached = true; + } + this.beforeBuildTicks(); + this.ticks = this.buildTicks() || []; + this.afterBuildTicks(); + const samplingEnabled = sampleSize < this.ticks.length; + this._convertTicksToLabels(samplingEnabled ? sample(this.ticks, sampleSize) : this.ticks); + this.configure(); + this.beforeCalculateLabelRotation(); + this.calculateLabelRotation(); + this.afterCalculateLabelRotation(); + if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === "auto")) { + this.ticks = autoSkip(this, this.ticks); + this._labelSizes = null; + this.afterAutoSkip(); + } + if (samplingEnabled) { + this._convertTicksToLabels(this.ticks); + } + this.beforeFit(); + this.fit(); + this.afterFit(); + this.afterUpdate(); + } + configure() { + let reversePixels = this.options.reverse; + let startPixel, endPixel; + if (this.isHorizontal()) { + startPixel = this.left; + endPixel = this.right; + } else { + startPixel = this.top; + endPixel = this.bottom; + reversePixels = !reversePixels; + } + this._startPixel = startPixel; + this._endPixel = endPixel; + this._reversePixels = reversePixels; + this._length = endPixel - startPixel; + this._alignToPixels = this.options.alignToPixels; + } + afterUpdate() { + callback(this.options.afterUpdate, [ + this + ]); + } + beforeSetDimensions() { + callback(this.options.beforeSetDimensions, [ + this + ]); + } + setDimensions() { + if (this.isHorizontal()) { + this.width = this.maxWidth; + this.left = 0; + this.right = this.width; + } else { + this.height = this.maxHeight; + this.top = 0; + this.bottom = this.height; + } + this.paddingLeft = 0; + this.paddingTop = 0; + this.paddingRight = 0; + this.paddingBottom = 0; + } + afterSetDimensions() { + callback(this.options.afterSetDimensions, [ + this + ]); + } + _callHooks(name) { + this.chart.notifyPlugins(name, this.getContext()); + callback(this.options[name], [ + this + ]); + } + beforeDataLimits() { + this._callHooks("beforeDataLimits"); + } + determineDataLimits() { + } + afterDataLimits() { + this._callHooks("afterDataLimits"); + } + beforeBuildTicks() { + this._callHooks("beforeBuildTicks"); + } + buildTicks() { + return []; + } + afterBuildTicks() { + this._callHooks("afterBuildTicks"); + } + beforeTickToLabelConversion() { + callback(this.options.beforeTickToLabelConversion, [ + this + ]); + } + generateTickLabels(ticks) { + const tickOpts = this.options.ticks; + let i, ilen, tick; + for (i = 0, ilen = ticks.length; i < ilen; i++) { + tick = ticks[i]; + tick.label = callback(tickOpts.callback, [ + tick.value, + i, + ticks + ], this); + } + } + afterTickToLabelConversion() { + callback(this.options.afterTickToLabelConversion, [ + this + ]); + } + beforeCalculateLabelRotation() { + callback(this.options.beforeCalculateLabelRotation, [ + this + ]); + } + calculateLabelRotation() { + const options = this.options; + const tickOpts = options.ticks; + const numTicks = getTicksLimit(this.ticks.length, options.ticks.maxTicksLimit); + const minRotation = tickOpts.minRotation || 0; + const maxRotation = tickOpts.maxRotation; + let labelRotation = minRotation; + let tickWidth, maxHeight, maxLabelDiagonal; + if (!this._isVisible() || !tickOpts.display || minRotation >= maxRotation || numTicks <= 1 || !this.isHorizontal()) { + this.labelRotation = minRotation; + return; + } + const labelSizes = this._getLabelSizes(); + const maxLabelWidth = labelSizes.widest.width; + const maxLabelHeight = labelSizes.highest.height; + const maxWidth = _limitValue(this.chart.width - maxLabelWidth, 0, this.maxWidth); + tickWidth = options.offset ? this.maxWidth / numTicks : maxWidth / (numTicks - 1); + if (maxLabelWidth + 6 > tickWidth) { + tickWidth = maxWidth / (numTicks - (options.offset ? 0.5 : 1)); + maxHeight = this.maxHeight - getTickMarkLength(options.grid) - tickOpts.padding - getTitleHeight(options.title, this.chart.options.font); + maxLabelDiagonal = Math.sqrt(maxLabelWidth * maxLabelWidth + maxLabelHeight * maxLabelHeight); + labelRotation = toDegrees(Math.min(Math.asin(_limitValue((labelSizes.highest.height + 6) / tickWidth, -1, 1)), Math.asin(_limitValue(maxHeight / maxLabelDiagonal, -1, 1)) - Math.asin(_limitValue(maxLabelHeight / maxLabelDiagonal, -1, 1)))); + labelRotation = Math.max(minRotation, Math.min(maxRotation, labelRotation)); + } + this.labelRotation = labelRotation; + } + afterCalculateLabelRotation() { + callback(this.options.afterCalculateLabelRotation, [ + this + ]); + } + afterAutoSkip() { + } + beforeFit() { + callback(this.options.beforeFit, [ + this + ]); + } + fit() { + const minSize = { + width: 0, + height: 0 + }; + const { chart, options: { ticks: tickOpts, title: titleOpts, grid: gridOpts } } = this; + const display = this._isVisible(); + const isHorizontal = this.isHorizontal(); + if (display) { + const titleHeight = getTitleHeight(titleOpts, chart.options.font); + if (isHorizontal) { + minSize.width = this.maxWidth; + minSize.height = getTickMarkLength(gridOpts) + titleHeight; + } else { + minSize.height = this.maxHeight; + minSize.width = getTickMarkLength(gridOpts) + titleHeight; + } + if (tickOpts.display && this.ticks.length) { + const { first, last, widest, highest } = this._getLabelSizes(); + const tickPadding = tickOpts.padding * 2; + const angleRadians = toRadians(this.labelRotation); + const cos = Math.cos(angleRadians); + const sin = Math.sin(angleRadians); + if (isHorizontal) { + const labelHeight = tickOpts.mirror ? 0 : sin * widest.width + cos * highest.height; + minSize.height = Math.min(this.maxHeight, minSize.height + labelHeight + tickPadding); + } else { + const labelWidth = tickOpts.mirror ? 0 : cos * widest.width + sin * highest.height; + minSize.width = Math.min(this.maxWidth, minSize.width + labelWidth + tickPadding); + } + this._calculatePadding(first, last, sin, cos); + } + } + this._handleMargins(); + if (isHorizontal) { + this.width = this._length = chart.width - this._margins.left - this._margins.right; + this.height = minSize.height; + } else { + this.width = minSize.width; + this.height = this._length = chart.height - this._margins.top - this._margins.bottom; + } + } + _calculatePadding(first, last, sin, cos) { + const { ticks: { align, padding }, position } = this.options; + const isRotated = this.labelRotation !== 0; + const labelsBelowTicks = position !== "top" && this.axis === "x"; + if (this.isHorizontal()) { + const offsetLeft = this.getPixelForTick(0) - this.left; + const offsetRight = this.right - this.getPixelForTick(this.ticks.length - 1); + let paddingLeft = 0; + let paddingRight = 0; + if (isRotated) { + if (labelsBelowTicks) { + paddingLeft = cos * first.width; + paddingRight = sin * last.height; + } else { + paddingLeft = sin * first.height; + paddingRight = cos * last.width; + } + } else if (align === "start") { + paddingRight = last.width; + } else if (align === "end") { + paddingLeft = first.width; + } else if (align !== "inner") { + paddingLeft = first.width / 2; + paddingRight = last.width / 2; + } + this.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * this.width / (this.width - offsetLeft), 0); + this.paddingRight = Math.max((paddingRight - offsetRight + padding) * this.width / (this.width - offsetRight), 0); + } else { + let paddingTop = last.height / 2; + let paddingBottom = first.height / 2; + if (align === "start") { + paddingTop = 0; + paddingBottom = first.height; + } else if (align === "end") { + paddingTop = last.height; + paddingBottom = 0; + } + this.paddingTop = paddingTop + padding; + this.paddingBottom = paddingBottom + padding; + } + } + _handleMargins() { + if (this._margins) { + this._margins.left = Math.max(this.paddingLeft, this._margins.left); + this._margins.top = Math.max(this.paddingTop, this._margins.top); + this._margins.right = Math.max(this.paddingRight, this._margins.right); + this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom); + } + } + afterFit() { + callback(this.options.afterFit, [ + this + ]); + } + isHorizontal() { + const { axis, position } = this.options; + return position === "top" || position === "bottom" || axis === "x"; + } + isFullSize() { + return this.options.fullSize; + } + _convertTicksToLabels(ticks) { + this.beforeTickToLabelConversion(); + this.generateTickLabels(ticks); + let i, ilen; + for (i = 0, ilen = ticks.length; i < ilen; i++) { + if (isNullOrUndef(ticks[i].label)) { + ticks.splice(i, 1); + ilen--; + i--; + } + } + this.afterTickToLabelConversion(); + } + _getLabelSizes() { + let labelSizes = this._labelSizes; + if (!labelSizes) { + const sampleSize = this.options.ticks.sampleSize; + let ticks = this.ticks; + if (sampleSize < ticks.length) { + ticks = sample(ticks, sampleSize); + } + this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length, this.options.ticks.maxTicksLimit); + } + return labelSizes; + } + _computeLabelSizes(ticks, length, maxTicksLimit) { + const { ctx, _longestTextCache: caches } = this; + const widths = []; + const heights = []; + const increment = Math.floor(length / getTicksLimit(length, maxTicksLimit)); + let widestLabelSize = 0; + let highestLabelSize = 0; + let i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel; + for (i = 0; i < length; i += increment) { + label = ticks[i].label; + tickFont = this._resolveTickFontOptions(i); + ctx.font = fontString = tickFont.string; + cache = caches[fontString] = caches[fontString] || { + data: {}, + gc: [] + }; + lineHeight = tickFont.lineHeight; + width = height = 0; + if (!isNullOrUndef(label) && !isArray(label)) { + width = _measureText(ctx, cache.data, cache.gc, width, label); + height = lineHeight; + } else if (isArray(label)) { + for (j = 0, jlen = label.length; j < jlen; ++j) { + nestedLabel = label[j]; + if (!isNullOrUndef(nestedLabel) && !isArray(nestedLabel)) { + width = _measureText(ctx, cache.data, cache.gc, width, nestedLabel); + height += lineHeight; + } + } + } + widths.push(width); + heights.push(height); + widestLabelSize = Math.max(width, widestLabelSize); + highestLabelSize = Math.max(height, highestLabelSize); + } + garbageCollect(caches, length); + const widest = widths.indexOf(widestLabelSize); + const highest = heights.indexOf(highestLabelSize); + const valueAt = (idx) => ({ + width: widths[idx] || 0, + height: heights[idx] || 0 + }); + return { + first: valueAt(0), + last: valueAt(length - 1), + widest: valueAt(widest), + highest: valueAt(highest), + widths, + heights + }; + } + getLabelForValue(value) { + return value; + } + getPixelForValue(value, index2) { + return NaN; + } + getValueForPixel(pixel) { + } + getPixelForTick(index2) { + const ticks = this.ticks; + if (index2 < 0 || index2 > ticks.length - 1) { + return null; + } + return this.getPixelForValue(ticks[index2].value); + } + getPixelForDecimal(decimal) { + if (this._reversePixels) { + decimal = 1 - decimal; + } + const pixel = this._startPixel + decimal * this._length; + return _int16Range(this._alignToPixels ? _alignPixel(this.chart, pixel, 0) : pixel); + } + getDecimalForPixel(pixel) { + const decimal = (pixel - this._startPixel) / this._length; + return this._reversePixels ? 1 - decimal : decimal; + } + getBasePixel() { + return this.getPixelForValue(this.getBaseValue()); + } + getBaseValue() { + const { min, max } = this; + return min < 0 && max < 0 ? max : min > 0 && max > 0 ? min : 0; + } + getContext(index2) { + const ticks = this.ticks || []; + if (index2 >= 0 && index2 < ticks.length) { + const tick = ticks[index2]; + return tick.$context || (tick.$context = createTickContext(this.getContext(), index2, tick)); + } + return this.$context || (this.$context = createScaleContext(this.chart.getContext(), this)); + } + _tickSize() { + const optionTicks = this.options.ticks; + const rot = toRadians(this.labelRotation); + const cos = Math.abs(Math.cos(rot)); + const sin = Math.abs(Math.sin(rot)); + const labelSizes = this._getLabelSizes(); + const padding = optionTicks.autoSkipPadding || 0; + const w = labelSizes ? labelSizes.widest.width + padding : 0; + const h = labelSizes ? labelSizes.highest.height + padding : 0; + return this.isHorizontal() ? h * cos > w * sin ? w / cos : h / sin : h * sin < w * cos ? h / cos : w / sin; + } + _isVisible() { + const display = this.options.display; + if (display !== "auto") { + return !!display; + } + return this.getMatchingVisibleMetas().length > 0; + } + _computeGridLineItems(chartArea) { + const axis = this.axis; + const chart = this.chart; + const options = this.options; + const { grid, position, border } = options; + const offset2 = grid.offset; + const isHorizontal = this.isHorizontal(); + const ticks = this.ticks; + const ticksLength = ticks.length + (offset2 ? 1 : 0); + const tl = getTickMarkLength(grid); + const items = []; + const borderOpts = border.setContext(this.getContext()); + const axisWidth = borderOpts.display ? borderOpts.width : 0; + const axisHalfWidth = axisWidth / 2; + const alignBorderValue = function(pixel) { + return _alignPixel(chart, pixel, axisWidth); + }; + let borderValue, i, lineValue, alignedLineValue; + let tx1, ty1, tx2, ty2, x1, y1, x2, y2; + if (position === "top") { + borderValue = alignBorderValue(this.bottom); + ty1 = this.bottom - tl; + ty2 = borderValue - axisHalfWidth; + y1 = alignBorderValue(chartArea.top) + axisHalfWidth; + y2 = chartArea.bottom; + } else if (position === "bottom") { + borderValue = alignBorderValue(this.top); + y1 = chartArea.top; + y2 = alignBorderValue(chartArea.bottom) - axisHalfWidth; + ty1 = borderValue + axisHalfWidth; + ty2 = this.top + tl; + } else if (position === "left") { + borderValue = alignBorderValue(this.right); + tx1 = this.right - tl; + tx2 = borderValue - axisHalfWidth; + x1 = alignBorderValue(chartArea.left) + axisHalfWidth; + x2 = chartArea.right; + } else if (position === "right") { + borderValue = alignBorderValue(this.left); + x1 = chartArea.left; + x2 = alignBorderValue(chartArea.right) - axisHalfWidth; + tx1 = borderValue + axisHalfWidth; + tx2 = this.left + tl; + } else if (axis === "x") { + if (position === "center") { + borderValue = alignBorderValue((chartArea.top + chartArea.bottom) / 2 + 0.5); + } else if (isObject(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value)); + } + y1 = chartArea.top; + y2 = chartArea.bottom; + ty1 = borderValue + axisHalfWidth; + ty2 = ty1 + tl; + } else if (axis === "y") { + if (position === "center") { + borderValue = alignBorderValue((chartArea.left + chartArea.right) / 2); + } else if (isObject(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value)); + } + tx1 = borderValue - axisHalfWidth; + tx2 = tx1 - tl; + x1 = chartArea.left; + x2 = chartArea.right; + } + const limit = valueOrDefault(options.ticks.maxTicksLimit, ticksLength); + const step = Math.max(1, Math.ceil(ticksLength / limit)); + for (i = 0; i < ticksLength; i += step) { + const context = this.getContext(i); + const optsAtIndex = grid.setContext(context); + const optsAtIndexBorder = border.setContext(context); + const lineWidth = optsAtIndex.lineWidth; + const lineColor = optsAtIndex.color; + const borderDash = optsAtIndexBorder.dash || []; + const borderDashOffset = optsAtIndexBorder.dashOffset; + const tickWidth = optsAtIndex.tickWidth; + const tickColor = optsAtIndex.tickColor; + const tickBorderDash = optsAtIndex.tickBorderDash || []; + const tickBorderDashOffset = optsAtIndex.tickBorderDashOffset; + lineValue = getPixelForGridLine(this, i, offset2); + if (lineValue === void 0) { + continue; + } + alignedLineValue = _alignPixel(chart, lineValue, lineWidth); + if (isHorizontal) { + tx1 = tx2 = x1 = x2 = alignedLineValue; + } else { + ty1 = ty2 = y1 = y2 = alignedLineValue; + } + items.push({ + tx1, + ty1, + tx2, + ty2, + x1, + y1, + x2, + y2, + width: lineWidth, + color: lineColor, + borderDash, + borderDashOffset, + tickWidth, + tickColor, + tickBorderDash, + tickBorderDashOffset + }); + } + this._ticksLength = ticksLength; + this._borderValue = borderValue; + return items; + } + _computeLabelItems(chartArea) { + const axis = this.axis; + const options = this.options; + const { position, ticks: optionTicks } = options; + const isHorizontal = this.isHorizontal(); + const ticks = this.ticks; + const { align, crossAlign, padding, mirror } = optionTicks; + const tl = getTickMarkLength(options.grid); + const tickAndPadding = tl + padding; + const hTickAndPadding = mirror ? -padding : tickAndPadding; + const rotation = -toRadians(this.labelRotation); + const items = []; + let i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset; + let textBaseline = "middle"; + if (position === "top") { + y = this.bottom - hTickAndPadding; + textAlign = this._getXAxisLabelAlignment(); + } else if (position === "bottom") { + y = this.top + hTickAndPadding; + textAlign = this._getXAxisLabelAlignment(); + } else if (position === "left") { + const ret = this._getYAxisLabelAlignment(tl); + textAlign = ret.textAlign; + x = ret.x; + } else if (position === "right") { + const ret = this._getYAxisLabelAlignment(tl); + textAlign = ret.textAlign; + x = ret.x; + } else if (axis === "x") { + if (position === "center") { + y = (chartArea.top + chartArea.bottom) / 2 + tickAndPadding; + } else if (isObject(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + y = this.chart.scales[positionAxisID].getPixelForValue(value) + tickAndPadding; + } + textAlign = this._getXAxisLabelAlignment(); + } else if (axis === "y") { + if (position === "center") { + x = (chartArea.left + chartArea.right) / 2 - tickAndPadding; + } else if (isObject(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + x = this.chart.scales[positionAxisID].getPixelForValue(value); + } + textAlign = this._getYAxisLabelAlignment(tl).textAlign; + } + if (axis === "y") { + if (align === "start") { + textBaseline = "top"; + } else if (align === "end") { + textBaseline = "bottom"; + } + } + const labelSizes = this._getLabelSizes(); + for (i = 0, ilen = ticks.length; i < ilen; ++i) { + tick = ticks[i]; + label = tick.label; + const optsAtIndex = optionTicks.setContext(this.getContext(i)); + pixel = this.getPixelForTick(i) + optionTicks.labelOffset; + font = this._resolveTickFontOptions(i); + lineHeight = font.lineHeight; + lineCount = isArray(label) ? label.length : 1; + const halfCount = lineCount / 2; + const color3 = optsAtIndex.color; + const strokeColor = optsAtIndex.textStrokeColor; + const strokeWidth = optsAtIndex.textStrokeWidth; + let tickTextAlign = textAlign; + if (isHorizontal) { + x = pixel; + if (textAlign === "inner") { + if (i === ilen - 1) { + tickTextAlign = !this.options.reverse ? "right" : "left"; + } else if (i === 0) { + tickTextAlign = !this.options.reverse ? "left" : "right"; + } else { + tickTextAlign = "center"; + } + } + if (position === "top") { + if (crossAlign === "near" || rotation !== 0) { + textOffset = -lineCount * lineHeight + lineHeight / 2; + } else if (crossAlign === "center") { + textOffset = -labelSizes.highest.height / 2 - halfCount * lineHeight + lineHeight; + } else { + textOffset = -labelSizes.highest.height + lineHeight / 2; + } + } else { + if (crossAlign === "near" || rotation !== 0) { + textOffset = lineHeight / 2; + } else if (crossAlign === "center") { + textOffset = labelSizes.highest.height / 2 - halfCount * lineHeight; + } else { + textOffset = labelSizes.highest.height - lineCount * lineHeight; + } + } + if (mirror) { + textOffset *= -1; + } + if (rotation !== 0 && !optsAtIndex.showLabelBackdrop) { + x += lineHeight / 2 * Math.sin(rotation); + } + } else { + y = pixel; + textOffset = (1 - lineCount) * lineHeight / 2; + } + let backdrop; + if (optsAtIndex.showLabelBackdrop) { + const labelPadding = toPadding(optsAtIndex.backdropPadding); + const height = labelSizes.heights[i]; + const width = labelSizes.widths[i]; + let top = textOffset - labelPadding.top; + let left = 0 - labelPadding.left; + switch (textBaseline) { + case "middle": + top -= height / 2; + break; + case "bottom": + top -= height; + break; + } + switch (textAlign) { + case "center": + left -= width / 2; + break; + case "right": + left -= width; + break; + case "inner": + if (i === ilen - 1) { + left -= width; + } else if (i > 0) { + left -= width / 2; + } + break; + } + backdrop = { + left, + top, + width: width + labelPadding.width, + height: height + labelPadding.height, + color: optsAtIndex.backdropColor + }; + } + items.push({ + label, + font, + textOffset, + options: { + rotation, + color: color3, + strokeColor, + strokeWidth, + textAlign: tickTextAlign, + textBaseline, + translation: [ + x, + y + ], + backdrop + } + }); + } + return items; + } + _getXAxisLabelAlignment() { + const { position, ticks } = this.options; + const rotation = -toRadians(this.labelRotation); + if (rotation) { + return position === "top" ? "left" : "right"; + } + let align = "center"; + if (ticks.align === "start") { + align = "left"; + } else if (ticks.align === "end") { + align = "right"; + } else if (ticks.align === "inner") { + align = "inner"; + } + return align; + } + _getYAxisLabelAlignment(tl) { + const { position, ticks: { crossAlign, mirror, padding } } = this.options; + const labelSizes = this._getLabelSizes(); + const tickAndPadding = tl + padding; + const widest = labelSizes.widest.width; + let textAlign; + let x; + if (position === "left") { + if (mirror) { + x = this.right + padding; + if (crossAlign === "near") { + textAlign = "left"; + } else if (crossAlign === "center") { + textAlign = "center"; + x += widest / 2; + } else { + textAlign = "right"; + x += widest; + } + } else { + x = this.right - tickAndPadding; + if (crossAlign === "near") { + textAlign = "right"; + } else if (crossAlign === "center") { + textAlign = "center"; + x -= widest / 2; + } else { + textAlign = "left"; + x = this.left; + } + } + } else if (position === "right") { + if (mirror) { + x = this.left + padding; + if (crossAlign === "near") { + textAlign = "right"; + } else if (crossAlign === "center") { + textAlign = "center"; + x -= widest / 2; + } else { + textAlign = "left"; + x -= widest; + } + } else { + x = this.left + tickAndPadding; + if (crossAlign === "near") { + textAlign = "left"; + } else if (crossAlign === "center") { + textAlign = "center"; + x += widest / 2; + } else { + textAlign = "right"; + x = this.right; + } + } + } else { + textAlign = "right"; + } + return { + textAlign, + x + }; + } + _computeLabelArea() { + if (this.options.ticks.mirror) { + return; + } + const chart = this.chart; + const position = this.options.position; + if (position === "left" || position === "right") { + return { + top: 0, + left: this.left, + bottom: chart.height, + right: this.right + }; + } + if (position === "top" || position === "bottom") { + return { + top: this.top, + left: 0, + bottom: this.bottom, + right: chart.width + }; + } + } + drawBackground() { + const { ctx, options: { backgroundColor }, left, top, width, height } = this; + if (backgroundColor) { + ctx.save(); + ctx.fillStyle = backgroundColor; + ctx.fillRect(left, top, width, height); + ctx.restore(); + } + } + getLineWidthForValue(value) { + const grid = this.options.grid; + if (!this._isVisible() || !grid.display) { + return 0; + } + const ticks = this.ticks; + const index2 = ticks.findIndex((t) => t.value === value); + if (index2 >= 0) { + const opts = grid.setContext(this.getContext(index2)); + return opts.lineWidth; + } + return 0; + } + drawGrid(chartArea) { + const grid = this.options.grid; + const ctx = this.ctx; + const items = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(chartArea)); + let i, ilen; + const drawLine = (p1, p2, style) => { + if (!style.width || !style.color) { + return; + } + ctx.save(); + ctx.lineWidth = style.width; + ctx.strokeStyle = style.color; + ctx.setLineDash(style.borderDash || []); + ctx.lineDashOffset = style.borderDashOffset; + ctx.beginPath(); + ctx.moveTo(p1.x, p1.y); + ctx.lineTo(p2.x, p2.y); + ctx.stroke(); + ctx.restore(); + }; + if (grid.display) { + for (i = 0, ilen = items.length; i < ilen; ++i) { + const item = items[i]; + if (grid.drawOnChartArea) { + drawLine({ + x: item.x1, + y: item.y1 + }, { + x: item.x2, + y: item.y2 + }, item); + } + if (grid.drawTicks) { + drawLine({ + x: item.tx1, + y: item.ty1 + }, { + x: item.tx2, + y: item.ty2 + }, { + color: item.tickColor, + width: item.tickWidth, + borderDash: item.tickBorderDash, + borderDashOffset: item.tickBorderDashOffset + }); + } + } + } + } + drawBorder() { + const { chart, ctx, options: { border, grid } } = this; + const borderOpts = border.setContext(this.getContext()); + const axisWidth = border.display ? borderOpts.width : 0; + if (!axisWidth) { + return; + } + const lastLineWidth = grid.setContext(this.getContext(0)).lineWidth; + const borderValue = this._borderValue; + let x1, x2, y1, y2; + if (this.isHorizontal()) { + x1 = _alignPixel(chart, this.left, axisWidth) - axisWidth / 2; + x2 = _alignPixel(chart, this.right, lastLineWidth) + lastLineWidth / 2; + y1 = y2 = borderValue; + } else { + y1 = _alignPixel(chart, this.top, axisWidth) - axisWidth / 2; + y2 = _alignPixel(chart, this.bottom, lastLineWidth) + lastLineWidth / 2; + x1 = x2 = borderValue; + } + ctx.save(); + ctx.lineWidth = borderOpts.width; + ctx.strokeStyle = borderOpts.color; + ctx.beginPath(); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); + ctx.restore(); + } + drawLabels(chartArea) { + const optionTicks = this.options.ticks; + if (!optionTicks.display) { + return; + } + const ctx = this.ctx; + const area = this._computeLabelArea(); + if (area) { + clipArea(ctx, area); + } + const items = this.getLabelItems(chartArea); + for (const item of items) { + const renderTextOptions = item.options; + const tickFont = item.font; + const label = item.label; + const y = item.textOffset; + renderText(ctx, label, 0, y, tickFont, renderTextOptions); + } + if (area) { + unclipArea(ctx); + } + } + drawTitle() { + const { ctx, options: { position, title, reverse } } = this; + if (!title.display) { + return; + } + const font = toFont(title.font); + const padding = toPadding(title.padding); + const align = title.align; + let offset2 = font.lineHeight / 2; + if (position === "bottom" || position === "center" || isObject(position)) { + offset2 += padding.bottom; + if (isArray(title.text)) { + offset2 += font.lineHeight * (title.text.length - 1); + } + } else { + offset2 += padding.top; + } + const { titleX, titleY, maxWidth, rotation } = titleArgs(this, offset2, position, align); + renderText(ctx, title.text, 0, 0, font, { + color: title.color, + maxWidth, + rotation, + textAlign: titleAlign(align, position, reverse), + textBaseline: "middle", + translation: [ + titleX, + titleY + ] + }); + } + draw(chartArea) { + if (!this._isVisible()) { + return; + } + this.drawBackground(); + this.drawGrid(chartArea); + this.drawBorder(); + this.drawTitle(); + this.drawLabels(chartArea); + } + _layers() { + const opts = this.options; + const tz = opts.ticks && opts.ticks.z || 0; + const gz = valueOrDefault(opts.grid && opts.grid.z, -1); + const bz = valueOrDefault(opts.border && opts.border.z, 0); + if (!this._isVisible() || this.draw !== Scale.prototype.draw) { + return [ + { + z: tz, + draw: (chartArea) => { + this.draw(chartArea); + } + } + ]; + } + return [ + { + z: gz, + draw: (chartArea) => { + this.drawBackground(); + this.drawGrid(chartArea); + this.drawTitle(); + } + }, + { + z: bz, + draw: () => { + this.drawBorder(); + } + }, + { + z: tz, + draw: (chartArea) => { + this.drawLabels(chartArea); + } + } + ]; + } + getMatchingVisibleMetas(type) { + const metas = this.chart.getSortedVisibleDatasetMetas(); + const axisID = this.axis + "AxisID"; + const result = []; + let i, ilen; + for (i = 0, ilen = metas.length; i < ilen; ++i) { + const meta = metas[i]; + if (meta[axisID] === this.id && (!type || meta.type === type)) { + result.push(meta); + } + } + return result; + } + _resolveTickFontOptions(index2) { + const opts = this.options.ticks.setContext(this.getContext(index2)); + return toFont(opts.font); + } + _maxDigits() { + const fontSize = this._resolveTickFontOptions(0).lineHeight; + return (this.isHorizontal() ? this.width : this.height) / fontSize; + } +}; +var TypedRegistry = class { + constructor(type, scope, override) { + this.type = type; + this.scope = scope; + this.override = override; + this.items = /* @__PURE__ */ Object.create(null); + } + isForType(type) { + return Object.prototype.isPrototypeOf.call(this.type.prototype, type.prototype); + } + register(item) { + const proto = Object.getPrototypeOf(item); + let parentScope; + if (isIChartComponent(proto)) { + parentScope = this.register(proto); + } + const items = this.items; + const id = item.id; + const scope = this.scope + "." + id; + if (!id) { + throw new Error("class does not have id: " + item); + } + if (id in items) { + return scope; + } + items[id] = item; + registerDefaults(item, scope, parentScope); + if (this.override) { + defaults.override(item.id, item.overrides); + } + return scope; + } + get(id) { + return this.items[id]; + } + unregister(item) { + const items = this.items; + const id = item.id; + const scope = this.scope; + if (id in items) { + delete items[id]; + } + if (scope && id in defaults[scope]) { + delete defaults[scope][id]; + if (this.override) { + delete overrides[id]; + } + } + } +}; +function registerDefaults(item, scope, parentScope) { + const itemDefaults = merge(/* @__PURE__ */ Object.create(null), [ + parentScope ? defaults.get(parentScope) : {}, + defaults.get(scope), + item.defaults + ]); + defaults.set(scope, itemDefaults); + if (item.defaultRoutes) { + routeDefaults(scope, item.defaultRoutes); + } + if (item.descriptors) { + defaults.describe(scope, item.descriptors); + } +} +function routeDefaults(scope, routes) { + Object.keys(routes).forEach((property) => { + const propertyParts = property.split("."); + const sourceName = propertyParts.pop(); + const sourceScope = [ + scope + ].concat(propertyParts).join("."); + const parts = routes[property].split("."); + const targetName = parts.pop(); + const targetScope = parts.join("."); + defaults.route(sourceScope, sourceName, targetScope, targetName); + }); +} +function isIChartComponent(proto) { + return "id" in proto && "defaults" in proto; +} +var Registry = class { + constructor() { + this.controllers = new TypedRegistry(DatasetController, "datasets", true); + this.elements = new TypedRegistry(Element, "elements"); + this.plugins = new TypedRegistry(Object, "plugins"); + this.scales = new TypedRegistry(Scale, "scales"); + this._typedRegistries = [ + this.controllers, + this.scales, + this.elements + ]; + } + add(...args) { + this._each("register", args); + } + remove(...args) { + this._each("unregister", args); + } + addControllers(...args) { + this._each("register", args, this.controllers); + } + addElements(...args) { + this._each("register", args, this.elements); + } + addPlugins(...args) { + this._each("register", args, this.plugins); + } + addScales(...args) { + this._each("register", args, this.scales); + } + getController(id) { + return this._get(id, this.controllers, "controller"); + } + getElement(id) { + return this._get(id, this.elements, "element"); + } + getPlugin(id) { + return this._get(id, this.plugins, "plugin"); + } + getScale(id) { + return this._get(id, this.scales, "scale"); + } + removeControllers(...args) { + this._each("unregister", args, this.controllers); + } + removeElements(...args) { + this._each("unregister", args, this.elements); + } + removePlugins(...args) { + this._each("unregister", args, this.plugins); + } + removeScales(...args) { + this._each("unregister", args, this.scales); + } + _each(method, args, typedRegistry) { + [ + ...args + ].forEach((arg) => { + const reg = typedRegistry || this._getRegistryForType(arg); + if (typedRegistry || reg.isForType(arg) || reg === this.plugins && arg.id) { + this._exec(method, reg, arg); + } else { + each(arg, (item) => { + const itemReg = typedRegistry || this._getRegistryForType(item); + this._exec(method, itemReg, item); + }); + } + }); + } + _exec(method, registry2, component) { + const camelMethod = _capitalize(method); + callback(component["before" + camelMethod], [], component); + registry2[method](component); + callback(component["after" + camelMethod], [], component); + } + _getRegistryForType(type) { + for (let i = 0; i < this._typedRegistries.length; i++) { + const reg = this._typedRegistries[i]; + if (reg.isForType(type)) { + return reg; + } + } + return this.plugins; + } + _get(id, typedRegistry, type) { + const item = typedRegistry.get(id); + if (item === void 0) { + throw new Error('"' + id + '" is not a registered ' + type + "."); + } + return item; + } +}; +var registry = /* @__PURE__ */ new Registry(); +var PluginService = class { + constructor() { + this._init = []; + } + notify(chart, hook, args, filter) { + if (hook === "beforeInit") { + this._init = this._createDescriptors(chart, true); + this._notify(this._init, chart, "install"); + } + const descriptors3 = filter ? this._descriptors(chart).filter(filter) : this._descriptors(chart); + const result = this._notify(descriptors3, chart, hook, args); + if (hook === "afterDestroy") { + this._notify(descriptors3, chart, "stop"); + this._notify(this._init, chart, "uninstall"); + } + return result; + } + _notify(descriptors3, chart, hook, args) { + args = args || {}; + for (const descriptor of descriptors3) { + const plugin = descriptor.plugin; + const method = plugin[hook]; + const params = [ + chart, + args, + descriptor.options + ]; + if (callback(method, params, plugin) === false && args.cancelable) { + return false; + } + } + return true; + } + invalidate() { + if (!isNullOrUndef(this._cache)) { + this._oldCache = this._cache; + this._cache = void 0; + } + } + _descriptors(chart) { + if (this._cache) { + return this._cache; + } + const descriptors3 = this._cache = this._createDescriptors(chart); + this._notifyStateChanges(chart); + return descriptors3; + } + _createDescriptors(chart, all) { + const config = chart && chart.config; + const options = valueOrDefault(config.options && config.options.plugins, {}); + const plugins2 = allPlugins(config); + return options === false && !all ? [] : createDescriptors(chart, plugins2, options, all); + } + _notifyStateChanges(chart) { + const previousDescriptors = this._oldCache || []; + const descriptors3 = this._cache; + const diff = (a, b) => a.filter((x) => !b.some((y) => x.plugin.id === y.plugin.id)); + this._notify(diff(previousDescriptors, descriptors3), chart, "stop"); + this._notify(diff(descriptors3, previousDescriptors), chart, "start"); + } +}; +function allPlugins(config) { + const localIds = {}; + const plugins2 = []; + const keys = Object.keys(registry.plugins.items); + for (let i = 0; i < keys.length; i++) { + plugins2.push(registry.getPlugin(keys[i])); + } + const local = config.plugins || []; + for (let i = 0; i < local.length; i++) { + const plugin = local[i]; + if (plugins2.indexOf(plugin) === -1) { + plugins2.push(plugin); + localIds[plugin.id] = true; + } + } + return { + plugins: plugins2, + localIds + }; +} +function getOpts(options, all) { + if (!all && options === false) { + return null; + } + if (options === true) { + return {}; + } + return options; +} +function createDescriptors(chart, { plugins: plugins2, localIds }, options, all) { + const result = []; + const context = chart.getContext(); + for (const plugin of plugins2) { + const id = plugin.id; + const opts = getOpts(options[id], all); + if (opts === null) { + continue; + } + result.push({ + plugin, + options: pluginOpts(chart.config, { + plugin, + local: localIds[id] + }, opts, context) + }); + } + return result; +} +function pluginOpts(config, { plugin, local }, opts, context) { + const keys = config.pluginScopeKeys(plugin); + const scopes = config.getOptionScopes(opts, keys); + if (local && plugin.defaults) { + scopes.push(plugin.defaults); + } + return config.createResolver(scopes, context, [ + "" + ], { + scriptable: false, + indexable: false, + allKeys: true + }); +} +function getIndexAxis(type, options) { + const datasetDefaults = defaults.datasets[type] || {}; + const datasetOptions = (options.datasets || {})[type] || {}; + return datasetOptions.indexAxis || options.indexAxis || datasetDefaults.indexAxis || "x"; +} +function getAxisFromDefaultScaleID(id, indexAxis) { + let axis = id; + if (id === "_index_") { + axis = indexAxis; + } else if (id === "_value_") { + axis = indexAxis === "x" ? "y" : "x"; + } + return axis; +} +function getDefaultScaleIDFromAxis(axis, indexAxis) { + return axis === indexAxis ? "_index_" : "_value_"; +} +function idMatchesAxis(id) { + if (id === "x" || id === "y" || id === "r") { + return id; + } +} +function axisFromPosition(position) { + if (position === "top" || position === "bottom") { + return "x"; + } + if (position === "left" || position === "right") { + return "y"; + } +} +function determineAxis(id, ...scaleOptions) { + if (idMatchesAxis(id)) { + return id; + } + for (const opts of scaleOptions) { + const axis = opts.axis || axisFromPosition(opts.position) || id.length > 1 && idMatchesAxis(id[0].toLowerCase()); + if (axis) { + return axis; + } + } + throw new Error(`Cannot determine type of '${id}' axis. Please provide 'axis' or 'position' option.`); +} +function getAxisFromDataset(id, axis, dataset) { + if (dataset[axis + "AxisID"] === id) { + return { + axis + }; + } +} +function retrieveAxisFromDatasets(id, config) { + if (config.data && config.data.datasets) { + const boundDs = config.data.datasets.filter((d) => d.xAxisID === id || d.yAxisID === id); + if (boundDs.length) { + return getAxisFromDataset(id, "x", boundDs[0]) || getAxisFromDataset(id, "y", boundDs[0]); + } + } + return {}; +} +function mergeScaleConfig(config, options) { + const chartDefaults = overrides[config.type] || { + scales: {} + }; + const configScales = options.scales || {}; + const chartIndexAxis = getIndexAxis(config.type, options); + const scales2 = /* @__PURE__ */ Object.create(null); + Object.keys(configScales).forEach((id) => { + const scaleConf = configScales[id]; + if (!isObject(scaleConf)) { + return console.error(`Invalid scale configuration for scale: ${id}`); + } + if (scaleConf._proxy) { + return console.warn(`Ignoring resolver passed as options for scale: ${id}`); + } + const axis = determineAxis(id, scaleConf, retrieveAxisFromDatasets(id, config), defaults.scales[scaleConf.type]); + const defaultId = getDefaultScaleIDFromAxis(axis, chartIndexAxis); + const defaultScaleOptions = chartDefaults.scales || {}; + scales2[id] = mergeIf(/* @__PURE__ */ Object.create(null), [ + { + axis + }, + scaleConf, + defaultScaleOptions[axis], + defaultScaleOptions[defaultId] + ]); + }); + config.data.datasets.forEach((dataset) => { + const type = dataset.type || config.type; + const indexAxis = dataset.indexAxis || getIndexAxis(type, options); + const datasetDefaults = overrides[type] || {}; + const defaultScaleOptions = datasetDefaults.scales || {}; + Object.keys(defaultScaleOptions).forEach((defaultID) => { + const axis = getAxisFromDefaultScaleID(defaultID, indexAxis); + const id = dataset[axis + "AxisID"] || axis; + scales2[id] = scales2[id] || /* @__PURE__ */ Object.create(null); + mergeIf(scales2[id], [ + { + axis + }, + configScales[id], + defaultScaleOptions[defaultID] + ]); + }); + }); + Object.keys(scales2).forEach((key) => { + const scale = scales2[key]; + mergeIf(scale, [ + defaults.scales[scale.type], + defaults.scale + ]); + }); + return scales2; +} +function initOptions(config) { + const options = config.options || (config.options = {}); + options.plugins = valueOrDefault(options.plugins, {}); + options.scales = mergeScaleConfig(config, options); +} +function initData(data) { + data = data || {}; + data.datasets = data.datasets || []; + data.labels = data.labels || []; + return data; +} +function initConfig(config) { + config = config || {}; + config.data = initData(config.data); + initOptions(config); + return config; +} +var keyCache = /* @__PURE__ */ new Map(); +var keysCached = /* @__PURE__ */ new Set(); +function cachedKeys(cacheKey, generate) { + let keys = keyCache.get(cacheKey); + if (!keys) { + keys = generate(); + keyCache.set(cacheKey, keys); + keysCached.add(keys); + } + return keys; +} +var addIfFound = (set3, obj, key) => { + const opts = resolveObjectKey(obj, key); + if (opts !== void 0) { + set3.add(opts); + } +}; +var Config = class { + constructor(config) { + this._config = initConfig(config); + this._scopeCache = /* @__PURE__ */ new Map(); + this._resolverCache = /* @__PURE__ */ new Map(); + } + get platform() { + return this._config.platform; + } + get type() { + return this._config.type; + } + set type(type) { + this._config.type = type; + } + get data() { + return this._config.data; + } + set data(data) { + this._config.data = initData(data); + } + get options() { + return this._config.options; + } + set options(options) { + this._config.options = options; + } + get plugins() { + return this._config.plugins; + } + update() { + const config = this._config; + this.clearCache(); + initOptions(config); + } + clearCache() { + this._scopeCache.clear(); + this._resolverCache.clear(); + } + datasetScopeKeys(datasetType) { + return cachedKeys(datasetType, () => [ + [ + `datasets.${datasetType}`, + "" + ] + ]); + } + datasetAnimationScopeKeys(datasetType, transition) { + return cachedKeys(`${datasetType}.transition.${transition}`, () => [ + [ + `datasets.${datasetType}.transitions.${transition}`, + `transitions.${transition}` + ], + [ + `datasets.${datasetType}`, + "" + ] + ]); + } + datasetElementScopeKeys(datasetType, elementType) { + return cachedKeys(`${datasetType}-${elementType}`, () => [ + [ + `datasets.${datasetType}.elements.${elementType}`, + `datasets.${datasetType}`, + `elements.${elementType}`, + "" + ] + ]); + } + pluginScopeKeys(plugin) { + const id = plugin.id; + const type = this.type; + return cachedKeys(`${type}-plugin-${id}`, () => [ + [ + `plugins.${id}`, + ...plugin.additionalOptionScopes || [] + ] + ]); + } + _cachedScopes(mainScope, resetCache) { + const _scopeCache = this._scopeCache; + let cache = _scopeCache.get(mainScope); + if (!cache || resetCache) { + cache = /* @__PURE__ */ new Map(); + _scopeCache.set(mainScope, cache); + } + return cache; + } + getOptionScopes(mainScope, keyLists, resetCache) { + const { options, type } = this; + const cache = this._cachedScopes(mainScope, resetCache); + const cached = cache.get(keyLists); + if (cached) { + return cached; + } + const scopes = /* @__PURE__ */ new Set(); + keyLists.forEach((keys) => { + if (mainScope) { + scopes.add(mainScope); + keys.forEach((key) => addIfFound(scopes, mainScope, key)); + } + keys.forEach((key) => addIfFound(scopes, options, key)); + keys.forEach((key) => addIfFound(scopes, overrides[type] || {}, key)); + keys.forEach((key) => addIfFound(scopes, defaults, key)); + keys.forEach((key) => addIfFound(scopes, descriptors, key)); + }); + const array = Array.from(scopes); + if (array.length === 0) { + array.push(/* @__PURE__ */ Object.create(null)); + } + if (keysCached.has(keyLists)) { + cache.set(keyLists, array); + } + return array; + } + chartOptionScopes() { + const { options, type } = this; + return [ + options, + overrides[type] || {}, + defaults.datasets[type] || {}, + { + type + }, + defaults, + descriptors + ]; + } + resolveNamedOptions(scopes, names3, context, prefixes = [ + "" + ]) { + const result = { + $shared: true + }; + const { resolver, subPrefixes } = getResolver(this._resolverCache, scopes, prefixes); + let options = resolver; + if (needContext(resolver, names3)) { + result.$shared = false; + context = isFunction(context) ? context() : context; + const subResolver = this.createResolver(scopes, context, subPrefixes); + options = _attachContext(resolver, context, subResolver); + } + for (const prop of names3) { + result[prop] = options[prop]; + } + return result; + } + createResolver(scopes, context, prefixes = [ + "" + ], descriptorDefaults) { + const { resolver } = getResolver(this._resolverCache, scopes, prefixes); + return isObject(context) ? _attachContext(resolver, context, void 0, descriptorDefaults) : resolver; + } +}; +function getResolver(resolverCache, scopes, prefixes) { + let cache = resolverCache.get(scopes); + if (!cache) { + cache = /* @__PURE__ */ new Map(); + resolverCache.set(scopes, cache); + } + const cacheKey = prefixes.join(); + let cached = cache.get(cacheKey); + if (!cached) { + const resolver = _createResolver(scopes, prefixes); + cached = { + resolver, + subPrefixes: prefixes.filter((p) => !p.toLowerCase().includes("hover")) + }; + cache.set(cacheKey, cached); + } + return cached; +} +var hasFunction = (value) => isObject(value) && Object.getOwnPropertyNames(value).some((key) => isFunction(value[key])); +function needContext(proxy, names3) { + const { isScriptable, isIndexable } = _descriptors(proxy); + for (const prop of names3) { + const scriptable = isScriptable(prop); + const indexable = isIndexable(prop); + const value = (indexable || scriptable) && proxy[prop]; + if (scriptable && (isFunction(value) || hasFunction(value)) || indexable && isArray(value)) { + return true; + } + } + return false; +} +var version = "4.4.2"; +var KNOWN_POSITIONS = [ + "top", + "bottom", + "left", + "right", + "chartArea" +]; +function positionIsHorizontal(position, axis) { + return position === "top" || position === "bottom" || KNOWN_POSITIONS.indexOf(position) === -1 && axis === "x"; +} +function compare2Level(l1, l2) { + return function(a, b) { + return a[l1] === b[l1] ? a[l2] - b[l2] : a[l1] - b[l1]; + }; +} +function onAnimationsComplete(context) { + const chart = context.chart; + const animationOptions = chart.options.animation; + chart.notifyPlugins("afterRender"); + callback(animationOptions && animationOptions.onComplete, [ + context + ], chart); +} +function onAnimationProgress(context) { + const chart = context.chart; + const animationOptions = chart.options.animation; + callback(animationOptions && animationOptions.onProgress, [ + context + ], chart); +} +function getCanvas(item) { + if (_isDomSupported() && typeof item === "string") { + item = document.getElementById(item); + } else if (item && item.length) { + item = item[0]; + } + if (item && item.canvas) { + item = item.canvas; + } + return item; +} +var instances = {}; +var getChart = (key) => { + const canvas = getCanvas(key); + return Object.values(instances).filter((c) => c.canvas === canvas).pop(); +}; +function moveNumericKeys(obj, start, move) { + const keys = Object.keys(obj); + for (const key of keys) { + const intKey = +key; + if (intKey >= start) { + const value = obj[key]; + delete obj[key]; + if (move > 0 || intKey > start) { + obj[intKey + move] = value; + } + } + } +} +function determineLastEvent(e, lastEvent, inChartArea, isClick) { + if (!inChartArea || e.type === "mouseout") { + return null; + } + if (isClick) { + return lastEvent; + } + return e; +} +function getSizeForArea(scale, chartArea, field) { + return scale.options.clip ? scale[field] : chartArea[field]; +} +function getDatasetArea(meta, chartArea) { + const { xScale, yScale } = meta; + if (xScale && yScale) { + return { + left: getSizeForArea(xScale, chartArea, "left"), + right: getSizeForArea(xScale, chartArea, "right"), + top: getSizeForArea(yScale, chartArea, "top"), + bottom: getSizeForArea(yScale, chartArea, "bottom") + }; + } + return chartArea; +} +var Chart = class { + static register(...items) { + registry.add(...items); + invalidatePlugins(); + } + static unregister(...items) { + registry.remove(...items); + invalidatePlugins(); + } + constructor(item, userConfig) { + const config = this.config = new Config(userConfig); + const initialCanvas = getCanvas(item); + const existingChart = getChart(initialCanvas); + if (existingChart) { + throw new Error("Canvas is already in use. Chart with ID '" + existingChart.id + "' must be destroyed before the canvas with ID '" + existingChart.canvas.id + "' can be reused."); + } + const options = config.createResolver(config.chartOptionScopes(), this.getContext()); + this.platform = new (config.platform || _detectPlatform(initialCanvas))(); + this.platform.updateConfig(config); + const context = this.platform.acquireContext(initialCanvas, options.aspectRatio); + const canvas = context && context.canvas; + const height = canvas && canvas.height; + const width = canvas && canvas.width; + this.id = uid(); + this.ctx = context; + this.canvas = canvas; + this.width = width; + this.height = height; + this._options = options; + this._aspectRatio = this.aspectRatio; + this._layers = []; + this._metasets = []; + this._stacks = void 0; + this.boxes = []; + this.currentDevicePixelRatio = void 0; + this.chartArea = void 0; + this._active = []; + this._lastEvent = void 0; + this._listeners = {}; + this._responsiveListeners = void 0; + this._sortedMetasets = []; + this.scales = {}; + this._plugins = new PluginService(); + this.$proxies = {}; + this._hiddenIndices = {}; + this.attached = false; + this._animationsDisabled = void 0; + this.$context = void 0; + this._doResize = debounce((mode) => this.update(mode), options.resizeDelay || 0); + this._dataChanges = []; + instances[this.id] = this; + if (!context || !canvas) { + console.error("Failed to create chart: can't acquire context from the given item"); + return; + } + animator.listen(this, "complete", onAnimationsComplete); + animator.listen(this, "progress", onAnimationProgress); + this._initialize(); + if (this.attached) { + this.update(); + } + } + get aspectRatio() { + const { options: { aspectRatio, maintainAspectRatio }, width, height, _aspectRatio } = this; + if (!isNullOrUndef(aspectRatio)) { + return aspectRatio; + } + if (maintainAspectRatio && _aspectRatio) { + return _aspectRatio; + } + return height ? width / height : null; + } + get data() { + return this.config.data; + } + set data(data) { + this.config.data = data; + } + get options() { + return this._options; + } + set options(options) { + this.config.options = options; + } + get registry() { + return registry; + } + _initialize() { + this.notifyPlugins("beforeInit"); + if (this.options.responsive) { + this.resize(); + } else { + retinaScale(this, this.options.devicePixelRatio); + } + this.bindEvents(); + this.notifyPlugins("afterInit"); + return this; + } + clear() { + clearCanvas(this.canvas, this.ctx); + return this; + } + stop() { + animator.stop(this); + return this; + } + resize(width, height) { + if (!animator.running(this)) { + this._resize(width, height); + } else { + this._resizeBeforeDraw = { + width, + height + }; + } + } + _resize(width, height) { + const options = this.options; + const canvas = this.canvas; + const aspectRatio = options.maintainAspectRatio && this.aspectRatio; + const newSize = this.platform.getMaximumSize(canvas, width, height, aspectRatio); + const newRatio = options.devicePixelRatio || this.platform.getDevicePixelRatio(); + const mode = this.width ? "resize" : "attach"; + this.width = newSize.width; + this.height = newSize.height; + this._aspectRatio = this.aspectRatio; + if (!retinaScale(this, newRatio, true)) { + return; + } + this.notifyPlugins("resize", { + size: newSize + }); + callback(options.onResize, [ + this, + newSize + ], this); + if (this.attached) { + if (this._doResize(mode)) { + this.render(); + } + } + } + ensureScalesHaveIDs() { + const options = this.options; + const scalesOptions = options.scales || {}; + each(scalesOptions, (axisOptions, axisID) => { + axisOptions.id = axisID; + }); + } + buildOrUpdateScales() { + const options = this.options; + const scaleOpts = options.scales; + const scales2 = this.scales; + const updated = Object.keys(scales2).reduce((obj, id) => { + obj[id] = false; + return obj; + }, {}); + let items = []; + if (scaleOpts) { + items = items.concat(Object.keys(scaleOpts).map((id) => { + const scaleOptions = scaleOpts[id]; + const axis = determineAxis(id, scaleOptions); + const isRadial = axis === "r"; + const isHorizontal = axis === "x"; + return { + options: scaleOptions, + dposition: isRadial ? "chartArea" : isHorizontal ? "bottom" : "left", + dtype: isRadial ? "radialLinear" : isHorizontal ? "category" : "linear" + }; + })); + } + each(items, (item) => { + const scaleOptions = item.options; + const id = scaleOptions.id; + const axis = determineAxis(id, scaleOptions); + const scaleType = valueOrDefault(scaleOptions.type, item.dtype); + if (scaleOptions.position === void 0 || positionIsHorizontal(scaleOptions.position, axis) !== positionIsHorizontal(item.dposition)) { + scaleOptions.position = item.dposition; + } + updated[id] = true; + let scale = null; + if (id in scales2 && scales2[id].type === scaleType) { + scale = scales2[id]; + } else { + const scaleClass = registry.getScale(scaleType); + scale = new scaleClass({ + id, + type: scaleType, + ctx: this.ctx, + chart: this + }); + scales2[scale.id] = scale; + } + scale.init(scaleOptions, options); + }); + each(updated, (hasUpdated, id) => { + if (!hasUpdated) { + delete scales2[id]; + } + }); + each(scales2, (scale) => { + layouts.configure(this, scale, scale.options); + layouts.addBox(this, scale); + }); + } + _updateMetasets() { + const metasets = this._metasets; + const numData = this.data.datasets.length; + const numMeta = metasets.length; + metasets.sort((a, b) => a.index - b.index); + if (numMeta > numData) { + for (let i = numData; i < numMeta; ++i) { + this._destroyDatasetMeta(i); + } + metasets.splice(numData, numMeta - numData); + } + this._sortedMetasets = metasets.slice(0).sort(compare2Level("order", "index")); + } + _removeUnreferencedMetasets() { + const { _metasets: metasets, data: { datasets } } = this; + if (metasets.length > datasets.length) { + delete this._stacks; + } + metasets.forEach((meta, index2) => { + if (datasets.filter((x) => x === meta._dataset).length === 0) { + this._destroyDatasetMeta(index2); + } + }); + } + buildOrUpdateControllers() { + const newControllers = []; + const datasets = this.data.datasets; + let i, ilen; + this._removeUnreferencedMetasets(); + for (i = 0, ilen = datasets.length; i < ilen; i++) { + const dataset = datasets[i]; + let meta = this.getDatasetMeta(i); + const type = dataset.type || this.config.type; + if (meta.type && meta.type !== type) { + this._destroyDatasetMeta(i); + meta = this.getDatasetMeta(i); + } + meta.type = type; + meta.indexAxis = dataset.indexAxis || getIndexAxis(type, this.options); + meta.order = dataset.order || 0; + meta.index = i; + meta.label = "" + dataset.label; + meta.visible = this.isDatasetVisible(i); + if (meta.controller) { + meta.controller.updateIndex(i); + meta.controller.linkScales(); + } else { + const ControllerClass = registry.getController(type); + const { datasetElementType, dataElementType } = defaults.datasets[type]; + Object.assign(ControllerClass, { + dataElementType: registry.getElement(dataElementType), + datasetElementType: datasetElementType && registry.getElement(datasetElementType) + }); + meta.controller = new ControllerClass(this, i); + newControllers.push(meta.controller); + } + } + this._updateMetasets(); + return newControllers; + } + _resetElements() { + each(this.data.datasets, (dataset, datasetIndex) => { + this.getDatasetMeta(datasetIndex).controller.reset(); + }, this); + } + reset() { + this._resetElements(); + this.notifyPlugins("reset"); + } + update(mode) { + const config = this.config; + config.update(); + const options = this._options = config.createResolver(config.chartOptionScopes(), this.getContext()); + const animsDisabled = this._animationsDisabled = !options.animation; + this._updateScales(); + this._checkEventBindings(); + this._updateHiddenIndices(); + this._plugins.invalidate(); + if (this.notifyPlugins("beforeUpdate", { + mode, + cancelable: true + }) === false) { + return; + } + const newControllers = this.buildOrUpdateControllers(); + this.notifyPlugins("beforeElementsUpdate"); + let minPadding = 0; + for (let i = 0, ilen = this.data.datasets.length; i < ilen; i++) { + const { controller } = this.getDatasetMeta(i); + const reset = !animsDisabled && newControllers.indexOf(controller) === -1; + controller.buildOrUpdateElements(reset); + minPadding = Math.max(+controller.getMaxOverflow(), minPadding); + } + minPadding = this._minPadding = options.layout.autoPadding ? minPadding : 0; + this._updateLayout(minPadding); + if (!animsDisabled) { + each(newControllers, (controller) => { + controller.reset(); + }); + } + this._updateDatasets(mode); + this.notifyPlugins("afterUpdate", { + mode + }); + this._layers.sort(compare2Level("z", "_idx")); + const { _active, _lastEvent } = this; + if (_lastEvent) { + this._eventHandler(_lastEvent, true); + } else if (_active.length) { + this._updateHoverStyles(_active, _active, true); + } + this.render(); + } + _updateScales() { + each(this.scales, (scale) => { + layouts.removeBox(this, scale); + }); + this.ensureScalesHaveIDs(); + this.buildOrUpdateScales(); + } + _checkEventBindings() { + const options = this.options; + const existingEvents = new Set(Object.keys(this._listeners)); + const newEvents = new Set(options.events); + if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) { + this.unbindEvents(); + this.bindEvents(); + } + } + _updateHiddenIndices() { + const { _hiddenIndices } = this; + const changes = this._getUniformDataChanges() || []; + for (const { method, start, count } of changes) { + const move = method === "_removeElements" ? -count : count; + moveNumericKeys(_hiddenIndices, start, move); + } + } + _getUniformDataChanges() { + const _dataChanges = this._dataChanges; + if (!_dataChanges || !_dataChanges.length) { + return; + } + this._dataChanges = []; + const datasetCount = this.data.datasets.length; + const makeSet = (idx) => new Set(_dataChanges.filter((c) => c[0] === idx).map((c, i) => i + "," + c.splice(1).join(","))); + const changeSet = makeSet(0); + for (let i = 1; i < datasetCount; i++) { + if (!setsEqual(changeSet, makeSet(i))) { + return; + } + } + return Array.from(changeSet).map((c) => c.split(",")).map((a) => ({ + method: a[1], + start: +a[2], + count: +a[3] + })); + } + _updateLayout(minPadding) { + if (this.notifyPlugins("beforeLayout", { + cancelable: true + }) === false) { + return; + } + layouts.update(this, this.width, this.height, minPadding); + const area = this.chartArea; + const noArea = area.width <= 0 || area.height <= 0; + this._layers = []; + each(this.boxes, (box) => { + if (noArea && box.position === "chartArea") { + return; + } + if (box.configure) { + box.configure(); + } + this._layers.push(...box._layers()); + }, this); + this._layers.forEach((item, index2) => { + item._idx = index2; + }); + this.notifyPlugins("afterLayout"); + } + _updateDatasets(mode) { + if (this.notifyPlugins("beforeDatasetsUpdate", { + mode, + cancelable: true + }) === false) { + return; + } + for (let i = 0, ilen = this.data.datasets.length; i < ilen; ++i) { + this.getDatasetMeta(i).controller.configure(); + } + for (let i = 0, ilen = this.data.datasets.length; i < ilen; ++i) { + this._updateDataset(i, isFunction(mode) ? mode({ + datasetIndex: i + }) : mode); + } + this.notifyPlugins("afterDatasetsUpdate", { + mode + }); + } + _updateDataset(index2, mode) { + const meta = this.getDatasetMeta(index2); + const args = { + meta, + index: index2, + mode, + cancelable: true + }; + if (this.notifyPlugins("beforeDatasetUpdate", args) === false) { + return; + } + meta.controller._update(mode); + args.cancelable = false; + this.notifyPlugins("afterDatasetUpdate", args); + } + render() { + if (this.notifyPlugins("beforeRender", { + cancelable: true + }) === false) { + return; + } + if (animator.has(this)) { + if (this.attached && !animator.running(this)) { + animator.start(this); + } + } else { + this.draw(); + onAnimationsComplete({ + chart: this + }); + } + } + draw() { + let i; + if (this._resizeBeforeDraw) { + const { width, height } = this._resizeBeforeDraw; + this._resize(width, height); + this._resizeBeforeDraw = null; + } + this.clear(); + if (this.width <= 0 || this.height <= 0) { + return; + } + if (this.notifyPlugins("beforeDraw", { + cancelable: true + }) === false) { + return; + } + const layers = this._layers; + for (i = 0; i < layers.length && layers[i].z <= 0; ++i) { + layers[i].draw(this.chartArea); + } + this._drawDatasets(); + for (; i < layers.length; ++i) { + layers[i].draw(this.chartArea); + } + this.notifyPlugins("afterDraw"); + } + _getSortedDatasetMetas(filterVisible) { + const metasets = this._sortedMetasets; + const result = []; + let i, ilen; + for (i = 0, ilen = metasets.length; i < ilen; ++i) { + const meta = metasets[i]; + if (!filterVisible || meta.visible) { + result.push(meta); + } + } + return result; + } + getSortedVisibleDatasetMetas() { + return this._getSortedDatasetMetas(true); + } + _drawDatasets() { + if (this.notifyPlugins("beforeDatasetsDraw", { + cancelable: true + }) === false) { + return; + } + const metasets = this.getSortedVisibleDatasetMetas(); + for (let i = metasets.length - 1; i >= 0; --i) { + this._drawDataset(metasets[i]); + } + this.notifyPlugins("afterDatasetsDraw"); + } + _drawDataset(meta) { + const ctx = this.ctx; + const clip = meta._clip; + const useClip = !clip.disabled; + const area = getDatasetArea(meta, this.chartArea); + const args = { + meta, + index: meta.index, + cancelable: true + }; + if (this.notifyPlugins("beforeDatasetDraw", args) === false) { + return; + } + if (useClip) { + clipArea(ctx, { + left: clip.left === false ? 0 : area.left - clip.left, + right: clip.right === false ? this.width : area.right + clip.right, + top: clip.top === false ? 0 : area.top - clip.top, + bottom: clip.bottom === false ? this.height : area.bottom + clip.bottom + }); + } + meta.controller.draw(); + if (useClip) { + unclipArea(ctx); + } + args.cancelable = false; + this.notifyPlugins("afterDatasetDraw", args); + } + isPointInArea(point) { + return _isPointInArea(point, this.chartArea, this._minPadding); + } + getElementsAtEventForMode(e, mode, options, useFinalPosition) { + const method = Interaction.modes[mode]; + if (typeof method === "function") { + return method(this, e, options, useFinalPosition); + } + return []; + } + getDatasetMeta(datasetIndex) { + const dataset = this.data.datasets[datasetIndex]; + const metasets = this._metasets; + let meta = metasets.filter((x) => x && x._dataset === dataset).pop(); + if (!meta) { + meta = { + type: null, + data: [], + dataset: null, + controller: null, + hidden: null, + xAxisID: null, + yAxisID: null, + order: dataset && dataset.order || 0, + index: datasetIndex, + _dataset: dataset, + _parsed: [], + _sorted: false + }; + metasets.push(meta); + } + return meta; + } + getContext() { + return this.$context || (this.$context = createContext(null, { + chart: this, + type: "chart" + })); + } + getVisibleDatasetCount() { + return this.getSortedVisibleDatasetMetas().length; + } + isDatasetVisible(datasetIndex) { + const dataset = this.data.datasets[datasetIndex]; + if (!dataset) { + return false; + } + const meta = this.getDatasetMeta(datasetIndex); + return typeof meta.hidden === "boolean" ? !meta.hidden : !dataset.hidden; + } + setDatasetVisibility(datasetIndex, visible) { + const meta = this.getDatasetMeta(datasetIndex); + meta.hidden = !visible; + } + toggleDataVisibility(index2) { + this._hiddenIndices[index2] = !this._hiddenIndices[index2]; + } + getDataVisibility(index2) { + return !this._hiddenIndices[index2]; + } + _updateVisibility(datasetIndex, dataIndex, visible) { + const mode = visible ? "show" : "hide"; + const meta = this.getDatasetMeta(datasetIndex); + const anims = meta.controller._resolveAnimations(void 0, mode); + if (defined(dataIndex)) { + meta.data[dataIndex].hidden = !visible; + this.update(); + } else { + this.setDatasetVisibility(datasetIndex, visible); + anims.update(meta, { + visible + }); + this.update((ctx) => ctx.datasetIndex === datasetIndex ? mode : void 0); + } + } + hide(datasetIndex, dataIndex) { + this._updateVisibility(datasetIndex, dataIndex, false); + } + show(datasetIndex, dataIndex) { + this._updateVisibility(datasetIndex, dataIndex, true); + } + _destroyDatasetMeta(datasetIndex) { + const meta = this._metasets[datasetIndex]; + if (meta && meta.controller) { + meta.controller._destroy(); + } + delete this._metasets[datasetIndex]; + } + _stop() { + let i, ilen; + this.stop(); + animator.remove(this); + for (i = 0, ilen = this.data.datasets.length; i < ilen; ++i) { + this._destroyDatasetMeta(i); + } + } + destroy() { + this.notifyPlugins("beforeDestroy"); + const { canvas, ctx } = this; + this._stop(); + this.config.clearCache(); + if (canvas) { + this.unbindEvents(); + clearCanvas(canvas, ctx); + this.platform.releaseContext(ctx); + this.canvas = null; + this.ctx = null; + } + delete instances[this.id]; + this.notifyPlugins("afterDestroy"); + } + toBase64Image(...args) { + return this.canvas.toDataURL(...args); + } + bindEvents() { + this.bindUserEvents(); + if (this.options.responsive) { + this.bindResponsiveEvents(); + } else { + this.attached = true; + } + } + bindUserEvents() { + const listeners = this._listeners; + const platform = this.platform; + const _add = (type, listener2) => { + platform.addEventListener(this, type, listener2); + listeners[type] = listener2; + }; + const listener = (e, x, y) => { + e.offsetX = x; + e.offsetY = y; + this._eventHandler(e); + }; + each(this.options.events, (type) => _add(type, listener)); + } + bindResponsiveEvents() { + if (!this._responsiveListeners) { + this._responsiveListeners = {}; + } + const listeners = this._responsiveListeners; + const platform = this.platform; + const _add = (type, listener2) => { + platform.addEventListener(this, type, listener2); + listeners[type] = listener2; + }; + const _remove = (type, listener2) => { + if (listeners[type]) { + platform.removeEventListener(this, type, listener2); + delete listeners[type]; + } + }; + const listener = (width, height) => { + if (this.canvas) { + this.resize(width, height); + } + }; + let detached; + const attached = () => { + _remove("attach", attached); + this.attached = true; + this.resize(); + _add("resize", listener); + _add("detach", detached); + }; + detached = () => { + this.attached = false; + _remove("resize", listener); + this._stop(); + this._resize(0, 0); + _add("attach", attached); + }; + if (platform.isAttached(this.canvas)) { + attached(); + } else { + detached(); + } + } + unbindEvents() { + each(this._listeners, (listener, type) => { + this.platform.removeEventListener(this, type, listener); + }); + this._listeners = {}; + each(this._responsiveListeners, (listener, type) => { + this.platform.removeEventListener(this, type, listener); + }); + this._responsiveListeners = void 0; + } + updateHoverStyle(items, mode, enabled) { + const prefix = enabled ? "set" : "remove"; + let meta, item, i, ilen; + if (mode === "dataset") { + meta = this.getDatasetMeta(items[0].datasetIndex); + meta.controller["_" + prefix + "DatasetHoverStyle"](); + } + for (i = 0, ilen = items.length; i < ilen; ++i) { + item = items[i]; + const controller = item && this.getDatasetMeta(item.datasetIndex).controller; + if (controller) { + controller[prefix + "HoverStyle"](item.element, item.datasetIndex, item.index); + } + } + } + getActiveElements() { + return this._active || []; + } + setActiveElements(activeElements) { + const lastActive = this._active || []; + const active = activeElements.map(({ datasetIndex, index: index2 }) => { + const meta = this.getDatasetMeta(datasetIndex); + if (!meta) { + throw new Error("No dataset found at index " + datasetIndex); + } + return { + datasetIndex, + element: meta.data[index2], + index: index2 + }; + }); + const changed = !_elementsEqual(active, lastActive); + if (changed) { + this._active = active; + this._lastEvent = null; + this._updateHoverStyles(active, lastActive); + } + } + notifyPlugins(hook, args, filter) { + return this._plugins.notify(this, hook, args, filter); + } + isPluginEnabled(pluginId) { + return this._plugins._cache.filter((p) => p.plugin.id === pluginId).length === 1; + } + _updateHoverStyles(active, lastActive, replay) { + const hoverOptions = this.options.hover; + const diff = (a, b) => a.filter((x) => !b.some((y) => x.datasetIndex === y.datasetIndex && x.index === y.index)); + const deactivated = diff(lastActive, active); + const activated = replay ? active : diff(active, lastActive); + if (deactivated.length) { + this.updateHoverStyle(deactivated, hoverOptions.mode, false); + } + if (activated.length && hoverOptions.mode) { + this.updateHoverStyle(activated, hoverOptions.mode, true); + } + } + _eventHandler(e, replay) { + const args = { + event: e, + replay, + cancelable: true, + inChartArea: this.isPointInArea(e) + }; + const eventFilter = (plugin) => (plugin.options.events || this.options.events).includes(e.native.type); + if (this.notifyPlugins("beforeEvent", args, eventFilter) === false) { + return; + } + const changed = this._handleEvent(e, replay, args.inChartArea); + args.cancelable = false; + this.notifyPlugins("afterEvent", args, eventFilter); + if (changed || args.changed) { + this.render(); + } + return this; + } + _handleEvent(e, replay, inChartArea) { + const { _active: lastActive = [], options } = this; + const useFinalPosition = replay; + const active = this._getActiveElements(e, lastActive, inChartArea, useFinalPosition); + const isClick = _isClickEvent(e); + const lastEvent = determineLastEvent(e, this._lastEvent, inChartArea, isClick); + if (inChartArea) { + this._lastEvent = null; + callback(options.onHover, [ + e, + active, + this + ], this); + if (isClick) { + callback(options.onClick, [ + e, + active, + this + ], this); + } + } + const changed = !_elementsEqual(active, lastActive); + if (changed || replay) { + this._active = active; + this._updateHoverStyles(active, lastActive, replay); + } + this._lastEvent = lastEvent; + return changed; + } + _getActiveElements(e, lastActive, inChartArea, useFinalPosition) { + if (e.type === "mouseout") { + return []; + } + if (!inChartArea) { + return lastActive; + } + const hoverOptions = this.options.hover; + return this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition); + } +}; +__publicField(Chart, "defaults", defaults); +__publicField(Chart, "instances", instances); +__publicField(Chart, "overrides", overrides); +__publicField(Chart, "registry", registry); +__publicField(Chart, "version", version); +__publicField(Chart, "getChart", getChart); +function invalidatePlugins() { + return each(Chart.instances, (chart) => chart._plugins.invalidate()); +} +function clipArc(ctx, element, endAngle) { + const { startAngle, pixelMargin, x, y, outerRadius, innerRadius } = element; + let angleMargin = pixelMargin / outerRadius; + ctx.beginPath(); + ctx.arc(x, y, outerRadius, startAngle - angleMargin, endAngle + angleMargin); + if (innerRadius > pixelMargin) { + angleMargin = pixelMargin / innerRadius; + ctx.arc(x, y, innerRadius, endAngle + angleMargin, startAngle - angleMargin, true); + } else { + ctx.arc(x, y, pixelMargin, endAngle + HALF_PI, startAngle - HALF_PI); + } + ctx.closePath(); + ctx.clip(); +} +function toRadiusCorners(value) { + return _readValueToProps(value, [ + "outerStart", + "outerEnd", + "innerStart", + "innerEnd" + ]); +} +function parseBorderRadius$1(arc, innerRadius, outerRadius, angleDelta) { + const o = toRadiusCorners(arc.options.borderRadius); + const halfThickness = (outerRadius - innerRadius) / 2; + const innerLimit = Math.min(halfThickness, angleDelta * innerRadius / 2); + const computeOuterLimit = (val) => { + const outerArcLimit = (outerRadius - Math.min(halfThickness, val)) * angleDelta / 2; + return _limitValue(val, 0, Math.min(halfThickness, outerArcLimit)); + }; + return { + outerStart: computeOuterLimit(o.outerStart), + outerEnd: computeOuterLimit(o.outerEnd), + innerStart: _limitValue(o.innerStart, 0, innerLimit), + innerEnd: _limitValue(o.innerEnd, 0, innerLimit) + }; +} +function rThetaToXY(r, theta, x, y) { + return { + x: x + r * Math.cos(theta), + y: y + r * Math.sin(theta) + }; +} +function pathArc(ctx, element, offset2, spacing, end, circular) { + const { x, y, startAngle: start, pixelMargin, innerRadius: innerR } = element; + const outerRadius = Math.max(element.outerRadius + spacing + offset2 - pixelMargin, 0); + const innerRadius = innerR > 0 ? innerR + spacing + offset2 + pixelMargin : 0; + let spacingOffset = 0; + const alpha3 = end - start; + if (spacing) { + const noSpacingInnerRadius = innerR > 0 ? innerR - spacing : 0; + const noSpacingOuterRadius = outerRadius > 0 ? outerRadius - spacing : 0; + const avNogSpacingRadius = (noSpacingInnerRadius + noSpacingOuterRadius) / 2; + const adjustedAngle = avNogSpacingRadius !== 0 ? alpha3 * avNogSpacingRadius / (avNogSpacingRadius + spacing) : alpha3; + spacingOffset = (alpha3 - adjustedAngle) / 2; + } + const beta = Math.max(1e-3, alpha3 * outerRadius - offset2 / PI) / outerRadius; + const angleOffset = (alpha3 - beta) / 2; + const startAngle = start + angleOffset + spacingOffset; + const endAngle = end - angleOffset - spacingOffset; + const { outerStart, outerEnd, innerStart, innerEnd } = parseBorderRadius$1(element, innerRadius, outerRadius, endAngle - startAngle); + const outerStartAdjustedRadius = outerRadius - outerStart; + const outerEndAdjustedRadius = outerRadius - outerEnd; + const outerStartAdjustedAngle = startAngle + outerStart / outerStartAdjustedRadius; + const outerEndAdjustedAngle = endAngle - outerEnd / outerEndAdjustedRadius; + const innerStartAdjustedRadius = innerRadius + innerStart; + const innerEndAdjustedRadius = innerRadius + innerEnd; + const innerStartAdjustedAngle = startAngle + innerStart / innerStartAdjustedRadius; + const innerEndAdjustedAngle = endAngle - innerEnd / innerEndAdjustedRadius; + ctx.beginPath(); + if (circular) { + const outerMidAdjustedAngle = (outerStartAdjustedAngle + outerEndAdjustedAngle) / 2; + ctx.arc(x, y, outerRadius, outerStartAdjustedAngle, outerMidAdjustedAngle); + ctx.arc(x, y, outerRadius, outerMidAdjustedAngle, outerEndAdjustedAngle); + if (outerEnd > 0) { + const pCenter = rThetaToXY(outerEndAdjustedRadius, outerEndAdjustedAngle, x, y); + ctx.arc(pCenter.x, pCenter.y, outerEnd, outerEndAdjustedAngle, endAngle + HALF_PI); + } + const p4 = rThetaToXY(innerEndAdjustedRadius, endAngle, x, y); + ctx.lineTo(p4.x, p4.y); + if (innerEnd > 0) { + const pCenter = rThetaToXY(innerEndAdjustedRadius, innerEndAdjustedAngle, x, y); + ctx.arc(pCenter.x, pCenter.y, innerEnd, endAngle + HALF_PI, innerEndAdjustedAngle + Math.PI); + } + const innerMidAdjustedAngle = (endAngle - innerEnd / innerRadius + (startAngle + innerStart / innerRadius)) / 2; + ctx.arc(x, y, innerRadius, endAngle - innerEnd / innerRadius, innerMidAdjustedAngle, true); + ctx.arc(x, y, innerRadius, innerMidAdjustedAngle, startAngle + innerStart / innerRadius, true); + if (innerStart > 0) { + const pCenter = rThetaToXY(innerStartAdjustedRadius, innerStartAdjustedAngle, x, y); + ctx.arc(pCenter.x, pCenter.y, innerStart, innerStartAdjustedAngle + Math.PI, startAngle - HALF_PI); + } + const p8 = rThetaToXY(outerStartAdjustedRadius, startAngle, x, y); + ctx.lineTo(p8.x, p8.y); + if (outerStart > 0) { + const pCenter = rThetaToXY(outerStartAdjustedRadius, outerStartAdjustedAngle, x, y); + ctx.arc(pCenter.x, pCenter.y, outerStart, startAngle - HALF_PI, outerStartAdjustedAngle); + } + } else { + ctx.moveTo(x, y); + const outerStartX = Math.cos(outerStartAdjustedAngle) * outerRadius + x; + const outerStartY = Math.sin(outerStartAdjustedAngle) * outerRadius + y; + ctx.lineTo(outerStartX, outerStartY); + const outerEndX = Math.cos(outerEndAdjustedAngle) * outerRadius + x; + const outerEndY = Math.sin(outerEndAdjustedAngle) * outerRadius + y; + ctx.lineTo(outerEndX, outerEndY); + } + ctx.closePath(); +} +function drawArc(ctx, element, offset2, spacing, circular) { + const { fullCircles, startAngle, circumference } = element; + let endAngle = element.endAngle; + if (fullCircles) { + pathArc(ctx, element, offset2, spacing, endAngle, circular); + for (let i = 0; i < fullCircles; ++i) { + ctx.fill(); + } + if (!isNaN(circumference)) { + endAngle = startAngle + (circumference % TAU || TAU); + } + } + pathArc(ctx, element, offset2, spacing, endAngle, circular); + ctx.fill(); + return endAngle; +} +function drawBorder(ctx, element, offset2, spacing, circular) { + const { fullCircles, startAngle, circumference, options } = element; + const { borderWidth, borderJoinStyle, borderDash, borderDashOffset } = options; + const inner = options.borderAlign === "inner"; + if (!borderWidth) { + return; + } + ctx.setLineDash(borderDash || []); + ctx.lineDashOffset = borderDashOffset; + if (inner) { + ctx.lineWidth = borderWidth * 2; + ctx.lineJoin = borderJoinStyle || "round"; + } else { + ctx.lineWidth = borderWidth; + ctx.lineJoin = borderJoinStyle || "bevel"; + } + let endAngle = element.endAngle; + if (fullCircles) { + pathArc(ctx, element, offset2, spacing, endAngle, circular); + for (let i = 0; i < fullCircles; ++i) { + ctx.stroke(); + } + if (!isNaN(circumference)) { + endAngle = startAngle + (circumference % TAU || TAU); + } + } + if (inner) { + clipArc(ctx, element, endAngle); + } + if (!fullCircles) { + pathArc(ctx, element, offset2, spacing, endAngle, circular); + ctx.stroke(); + } +} +var ArcElement = class extends Element { + constructor(cfg) { + super(); + __publicField(this, "circumference"); + __publicField(this, "endAngle"); + __publicField(this, "fullCircles"); + __publicField(this, "innerRadius"); + __publicField(this, "outerRadius"); + __publicField(this, "pixelMargin"); + __publicField(this, "startAngle"); + this.options = void 0; + this.circumference = void 0; + this.startAngle = void 0; + this.endAngle = void 0; + this.innerRadius = void 0; + this.outerRadius = void 0; + this.pixelMargin = 0; + this.fullCircles = 0; + if (cfg) { + Object.assign(this, cfg); + } + } + inRange(chartX, chartY, useFinalPosition) { + const point = this.getProps([ + "x", + "y" + ], useFinalPosition); + const { angle, distance } = getAngleFromPoint(point, { + x: chartX, + y: chartY + }); + const { startAngle, endAngle, innerRadius, outerRadius, circumference } = this.getProps([ + "startAngle", + "endAngle", + "innerRadius", + "outerRadius", + "circumference" + ], useFinalPosition); + const rAdjust = (this.options.spacing + this.options.borderWidth) / 2; + const _circumference = valueOrDefault(circumference, endAngle - startAngle); + const betweenAngles = _circumference >= TAU || _angleBetween(angle, startAngle, endAngle); + const withinRadius = _isBetween(distance, innerRadius + rAdjust, outerRadius + rAdjust); + return betweenAngles && withinRadius; + } + getCenterPoint(useFinalPosition) { + const { x, y, startAngle, endAngle, innerRadius, outerRadius } = this.getProps([ + "x", + "y", + "startAngle", + "endAngle", + "innerRadius", + "outerRadius" + ], useFinalPosition); + const { offset: offset2, spacing } = this.options; + const halfAngle = (startAngle + endAngle) / 2; + const halfRadius = (innerRadius + outerRadius + spacing + offset2) / 2; + return { + x: x + Math.cos(halfAngle) * halfRadius, + y: y + Math.sin(halfAngle) * halfRadius + }; + } + tooltipPosition(useFinalPosition) { + return this.getCenterPoint(useFinalPosition); + } + draw(ctx) { + const { options, circumference } = this; + const offset2 = (options.offset || 0) / 4; + const spacing = (options.spacing || 0) / 2; + const circular = options.circular; + this.pixelMargin = options.borderAlign === "inner" ? 0.33 : 0; + this.fullCircles = circumference > TAU ? Math.floor(circumference / TAU) : 0; + if (circumference === 0 || this.innerRadius < 0 || this.outerRadius < 0) { + return; + } + ctx.save(); + const halfAngle = (this.startAngle + this.endAngle) / 2; + ctx.translate(Math.cos(halfAngle) * offset2, Math.sin(halfAngle) * offset2); + const fix = 1 - Math.sin(Math.min(PI, circumference || 0)); + const radiusOffset = offset2 * fix; + ctx.fillStyle = options.backgroundColor; + ctx.strokeStyle = options.borderColor; + drawArc(ctx, this, radiusOffset, spacing, circular); + drawBorder(ctx, this, radiusOffset, spacing, circular); + ctx.restore(); + } +}; +__publicField(ArcElement, "id", "arc"); +__publicField(ArcElement, "defaults", { + borderAlign: "center", + borderColor: "#fff", + borderDash: [], + borderDashOffset: 0, + borderJoinStyle: void 0, + borderRadius: 0, + borderWidth: 2, + offset: 0, + spacing: 0, + angle: void 0, + circular: true +}); +__publicField(ArcElement, "defaultRoutes", { + backgroundColor: "backgroundColor" +}); +__publicField(ArcElement, "descriptors", { + _scriptable: true, + _indexable: (name) => name !== "borderDash" +}); +function setStyle(ctx, options, style = options) { + ctx.lineCap = valueOrDefault(style.borderCapStyle, options.borderCapStyle); + ctx.setLineDash(valueOrDefault(style.borderDash, options.borderDash)); + ctx.lineDashOffset = valueOrDefault(style.borderDashOffset, options.borderDashOffset); + ctx.lineJoin = valueOrDefault(style.borderJoinStyle, options.borderJoinStyle); + ctx.lineWidth = valueOrDefault(style.borderWidth, options.borderWidth); + ctx.strokeStyle = valueOrDefault(style.borderColor, options.borderColor); +} +function lineTo(ctx, previous, target) { + ctx.lineTo(target.x, target.y); +} +function getLineMethod(options) { + if (options.stepped) { + return _steppedLineTo; + } + if (options.tension || options.cubicInterpolationMode === "monotone") { + return _bezierCurveTo; + } + return lineTo; +} +function pathVars(points, segment, params = {}) { + const count = points.length; + const { start: paramsStart = 0, end: paramsEnd = count - 1 } = params; + const { start: segmentStart, end: segmentEnd } = segment; + const start = Math.max(paramsStart, segmentStart); + const end = Math.min(paramsEnd, segmentEnd); + const outside = paramsStart < segmentStart && paramsEnd < segmentStart || paramsStart > segmentEnd && paramsEnd > segmentEnd; + return { + count, + start, + loop: segment.loop, + ilen: end < start && !outside ? count + end - start : end - start + }; +} +function pathSegment(ctx, line, segment, params) { + const { points, options } = line; + const { count, start, loop, ilen } = pathVars(points, segment, params); + const lineMethod = getLineMethod(options); + let { move = true, reverse } = params || {}; + let i, point, prev; + for (i = 0; i <= ilen; ++i) { + point = points[(start + (reverse ? ilen - i : i)) % count]; + if (point.skip) { + continue; + } else if (move) { + ctx.moveTo(point.x, point.y); + move = false; + } else { + lineMethod(ctx, prev, point, reverse, options.stepped); + } + prev = point; + } + if (loop) { + point = points[(start + (reverse ? ilen : 0)) % count]; + lineMethod(ctx, prev, point, reverse, options.stepped); + } + return !!loop; +} +function fastPathSegment(ctx, line, segment, params) { + const points = line.points; + const { count, start, ilen } = pathVars(points, segment, params); + const { move = true, reverse } = params || {}; + let avgX = 0; + let countX = 0; + let i, point, prevX, minY, maxY, lastY; + const pointIndex = (index2) => (start + (reverse ? ilen - index2 : index2)) % count; + const drawX = () => { + if (minY !== maxY) { + ctx.lineTo(avgX, maxY); + ctx.lineTo(avgX, minY); + ctx.lineTo(avgX, lastY); + } + }; + if (move) { + point = points[pointIndex(0)]; + ctx.moveTo(point.x, point.y); + } + for (i = 0; i <= ilen; ++i) { + point = points[pointIndex(i)]; + if (point.skip) { + continue; + } + const x = point.x; + const y = point.y; + const truncX = x | 0; + if (truncX === prevX) { + if (y < minY) { + minY = y; + } else if (y > maxY) { + maxY = y; + } + avgX = (countX * avgX + x) / ++countX; + } else { + drawX(); + ctx.lineTo(x, y); + prevX = truncX; + countX = 0; + minY = maxY = y; + } + lastY = y; + } + drawX(); +} +function _getSegmentMethod(line) { + const opts = line.options; + const borderDash = opts.borderDash && opts.borderDash.length; + const useFastPath = !line._decimated && !line._loop && !opts.tension && opts.cubicInterpolationMode !== "monotone" && !opts.stepped && !borderDash; + return useFastPath ? fastPathSegment : pathSegment; +} +function _getInterpolationMethod(options) { + if (options.stepped) { + return _steppedInterpolation; + } + if (options.tension || options.cubicInterpolationMode === "monotone") { + return _bezierInterpolation; + } + return _pointInLine; +} +function strokePathWithCache(ctx, line, start, count) { + let path = line._path; + if (!path) { + path = line._path = new Path2D(); + if (line.path(path, start, count)) { + path.closePath(); + } + } + setStyle(ctx, line.options); + ctx.stroke(path); +} +function strokePathDirect(ctx, line, start, count) { + const { segments, options } = line; + const segmentMethod = _getSegmentMethod(line); + for (const segment of segments) { + setStyle(ctx, options, segment.style); + ctx.beginPath(); + if (segmentMethod(ctx, line, segment, { + start, + end: start + count - 1 + })) { + ctx.closePath(); + } + ctx.stroke(); + } +} +var usePath2D = typeof Path2D === "function"; +function draw(ctx, line, start, count) { + if (usePath2D && !line.options.segment) { + strokePathWithCache(ctx, line, start, count); + } else { + strokePathDirect(ctx, line, start, count); + } +} +var LineElement = class extends Element { + constructor(cfg) { + super(); + this.animated = true; + this.options = void 0; + this._chart = void 0; + this._loop = void 0; + this._fullLoop = void 0; + this._path = void 0; + this._points = void 0; + this._segments = void 0; + this._decimated = false; + this._pointsUpdated = false; + this._datasetIndex = void 0; + if (cfg) { + Object.assign(this, cfg); + } + } + updateControlPoints(chartArea, indexAxis) { + const options = this.options; + if ((options.tension || options.cubicInterpolationMode === "monotone") && !options.stepped && !this._pointsUpdated) { + const loop = options.spanGaps ? this._loop : this._fullLoop; + _updateBezierControlPoints(this._points, options, chartArea, loop, indexAxis); + this._pointsUpdated = true; + } + } + set points(points) { + this._points = points; + delete this._segments; + delete this._path; + this._pointsUpdated = false; + } + get points() { + return this._points; + } + get segments() { + return this._segments || (this._segments = _computeSegments(this, this.options.segment)); + } + first() { + const segments = this.segments; + const points = this.points; + return segments.length && points[segments[0].start]; + } + last() { + const segments = this.segments; + const points = this.points; + const count = segments.length; + return count && points[segments[count - 1].end]; + } + interpolate(point, property) { + const options = this.options; + const value = point[property]; + const points = this.points; + const segments = _boundSegments(this, { + property, + start: value, + end: value + }); + if (!segments.length) { + return; + } + const result = []; + const _interpolate = _getInterpolationMethod(options); + let i, ilen; + for (i = 0, ilen = segments.length; i < ilen; ++i) { + const { start, end } = segments[i]; + const p1 = points[start]; + const p2 = points[end]; + if (p1 === p2) { + result.push(p1); + continue; + } + const t = Math.abs((value - p1[property]) / (p2[property] - p1[property])); + const interpolated = _interpolate(p1, p2, t, options.stepped); + interpolated[property] = point[property]; + result.push(interpolated); + } + return result.length === 1 ? result[0] : result; + } + pathSegment(ctx, segment, params) { + const segmentMethod = _getSegmentMethod(this); + return segmentMethod(ctx, this, segment, params); + } + path(ctx, start, count) { + const segments = this.segments; + const segmentMethod = _getSegmentMethod(this); + let loop = this._loop; + start = start || 0; + count = count || this.points.length - start; + for (const segment of segments) { + loop &= segmentMethod(ctx, this, segment, { + start, + end: start + count - 1 + }); + } + return !!loop; + } + draw(ctx, chartArea, start, count) { + const options = this.options || {}; + const points = this.points || []; + if (points.length && options.borderWidth) { + ctx.save(); + draw(ctx, this, start, count); + ctx.restore(); + } + if (this.animated) { + this._pointsUpdated = false; + this._path = void 0; + } + } +}; +__publicField(LineElement, "id", "line"); +__publicField(LineElement, "defaults", { + borderCapStyle: "butt", + borderDash: [], + borderDashOffset: 0, + borderJoinStyle: "miter", + borderWidth: 3, + capBezierPoints: true, + cubicInterpolationMode: "default", + fill: false, + spanGaps: false, + stepped: false, + tension: 0 +}); +__publicField(LineElement, "defaultRoutes", { + backgroundColor: "backgroundColor", + borderColor: "borderColor" +}); +__publicField(LineElement, "descriptors", { + _scriptable: true, + _indexable: (name) => name !== "borderDash" && name !== "fill" +}); +function inRange$1(el, pos, axis, useFinalPosition) { + const options = el.options; + const { [axis]: value } = el.getProps([ + axis + ], useFinalPosition); + return Math.abs(pos - value) < options.radius + options.hitRadius; +} +var PointElement = class extends Element { + constructor(cfg) { + super(); + __publicField(this, "parsed"); + __publicField(this, "skip"); + __publicField(this, "stop"); + this.options = void 0; + this.parsed = void 0; + this.skip = void 0; + this.stop = void 0; + if (cfg) { + Object.assign(this, cfg); + } + } + inRange(mouseX, mouseY, useFinalPosition) { + const options = this.options; + const { x, y } = this.getProps([ + "x", + "y" + ], useFinalPosition); + return Math.pow(mouseX - x, 2) + Math.pow(mouseY - y, 2) < Math.pow(options.hitRadius + options.radius, 2); + } + inXRange(mouseX, useFinalPosition) { + return inRange$1(this, mouseX, "x", useFinalPosition); + } + inYRange(mouseY, useFinalPosition) { + return inRange$1(this, mouseY, "y", useFinalPosition); + } + getCenterPoint(useFinalPosition) { + const { x, y } = this.getProps([ + "x", + "y" + ], useFinalPosition); + return { + x, + y + }; + } + size(options) { + options = options || this.options || {}; + let radius = options.radius || 0; + radius = Math.max(radius, radius && options.hoverRadius || 0); + const borderWidth = radius && options.borderWidth || 0; + return (radius + borderWidth) * 2; + } + draw(ctx, area) { + const options = this.options; + if (this.skip || options.radius < 0.1 || !_isPointInArea(this, area, this.size(options) / 2)) { + return; + } + ctx.strokeStyle = options.borderColor; + ctx.lineWidth = options.borderWidth; + ctx.fillStyle = options.backgroundColor; + drawPoint(ctx, options, this.x, this.y); + } + getRange() { + const options = this.options || {}; + return options.radius + options.hitRadius; + } +}; +__publicField(PointElement, "id", "point"); +/** +* @type {any} +*/ +__publicField(PointElement, "defaults", { + borderWidth: 1, + hitRadius: 1, + hoverBorderWidth: 1, + hoverRadius: 4, + pointStyle: "circle", + radius: 3, + rotation: 0 +}); +/** +* @type {any} +*/ +__publicField(PointElement, "defaultRoutes", { + backgroundColor: "backgroundColor", + borderColor: "borderColor" +}); +function getBarBounds(bar, useFinalPosition) { + const { x, y, base, width, height } = bar.getProps([ + "x", + "y", + "base", + "width", + "height" + ], useFinalPosition); + let left, right, top, bottom, half; + if (bar.horizontal) { + half = height / 2; + left = Math.min(x, base); + right = Math.max(x, base); + top = y - half; + bottom = y + half; + } else { + half = width / 2; + left = x - half; + right = x + half; + top = Math.min(y, base); + bottom = Math.max(y, base); + } + return { + left, + top, + right, + bottom + }; +} +function skipOrLimit(skip3, value, min, max) { + return skip3 ? 0 : _limitValue(value, min, max); +} +function parseBorderWidth(bar, maxW, maxH) { + const value = bar.options.borderWidth; + const skip3 = bar.borderSkipped; + const o = toTRBL(value); + return { + t: skipOrLimit(skip3.top, o.top, 0, maxH), + r: skipOrLimit(skip3.right, o.right, 0, maxW), + b: skipOrLimit(skip3.bottom, o.bottom, 0, maxH), + l: skipOrLimit(skip3.left, o.left, 0, maxW) + }; +} +function parseBorderRadius(bar, maxW, maxH) { + const { enableBorderRadius } = bar.getProps([ + "enableBorderRadius" + ]); + const value = bar.options.borderRadius; + const o = toTRBLCorners(value); + const maxR = Math.min(maxW, maxH); + const skip3 = bar.borderSkipped; + const enableBorder = enableBorderRadius || isObject(value); + return { + topLeft: skipOrLimit(!enableBorder || skip3.top || skip3.left, o.topLeft, 0, maxR), + topRight: skipOrLimit(!enableBorder || skip3.top || skip3.right, o.topRight, 0, maxR), + bottomLeft: skipOrLimit(!enableBorder || skip3.bottom || skip3.left, o.bottomLeft, 0, maxR), + bottomRight: skipOrLimit(!enableBorder || skip3.bottom || skip3.right, o.bottomRight, 0, maxR) + }; +} +function boundingRects(bar) { + const bounds = getBarBounds(bar); + const width = bounds.right - bounds.left; + const height = bounds.bottom - bounds.top; + const border = parseBorderWidth(bar, width / 2, height / 2); + const radius = parseBorderRadius(bar, width / 2, height / 2); + return { + outer: { + x: bounds.left, + y: bounds.top, + w: width, + h: height, + radius + }, + inner: { + x: bounds.left + border.l, + y: bounds.top + border.t, + w: width - border.l - border.r, + h: height - border.t - border.b, + radius: { + topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)), + topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)), + bottomLeft: Math.max(0, radius.bottomLeft - Math.max(border.b, border.l)), + bottomRight: Math.max(0, radius.bottomRight - Math.max(border.b, border.r)) + } + } + }; +} +function inRange(bar, x, y, useFinalPosition) { + const skipX = x === null; + const skipY = y === null; + const skipBoth = skipX && skipY; + const bounds = bar && !skipBoth && getBarBounds(bar, useFinalPosition); + return bounds && (skipX || _isBetween(x, bounds.left, bounds.right)) && (skipY || _isBetween(y, bounds.top, bounds.bottom)); +} +function hasRadius(radius) { + return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight; +} +function addNormalRectPath(ctx, rect) { + ctx.rect(rect.x, rect.y, rect.w, rect.h); +} +function inflateRect(rect, amount, refRect = {}) { + const x = rect.x !== refRect.x ? -amount : 0; + const y = rect.y !== refRect.y ? -amount : 0; + const w = (rect.x + rect.w !== refRect.x + refRect.w ? amount : 0) - x; + const h = (rect.y + rect.h !== refRect.y + refRect.h ? amount : 0) - y; + return { + x: rect.x + x, + y: rect.y + y, + w: rect.w + w, + h: rect.h + h, + radius: rect.radius + }; +} +var BarElement = class extends Element { + constructor(cfg) { + super(); + this.options = void 0; + this.horizontal = void 0; + this.base = void 0; + this.width = void 0; + this.height = void 0; + this.inflateAmount = void 0; + if (cfg) { + Object.assign(this, cfg); + } + } + draw(ctx) { + const { inflateAmount, options: { borderColor, backgroundColor } } = this; + const { inner, outer } = boundingRects(this); + const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath; + ctx.save(); + if (outer.w !== inner.w || outer.h !== inner.h) { + ctx.beginPath(); + addRectPath(ctx, inflateRect(outer, inflateAmount, inner)); + ctx.clip(); + addRectPath(ctx, inflateRect(inner, -inflateAmount, outer)); + ctx.fillStyle = borderColor; + ctx.fill("evenodd"); + } + ctx.beginPath(); + addRectPath(ctx, inflateRect(inner, inflateAmount)); + ctx.fillStyle = backgroundColor; + ctx.fill(); + ctx.restore(); + } + inRange(mouseX, mouseY, useFinalPosition) { + return inRange(this, mouseX, mouseY, useFinalPosition); + } + inXRange(mouseX, useFinalPosition) { + return inRange(this, mouseX, null, useFinalPosition); + } + inYRange(mouseY, useFinalPosition) { + return inRange(this, null, mouseY, useFinalPosition); + } + getCenterPoint(useFinalPosition) { + const { x, y, base, horizontal } = this.getProps([ + "x", + "y", + "base", + "horizontal" + ], useFinalPosition); + return { + x: horizontal ? (x + base) / 2 : x, + y: horizontal ? y : (y + base) / 2 + }; + } + getRange(axis) { + return axis === "x" ? this.width / 2 : this.height / 2; + } +}; +__publicField(BarElement, "id", "bar"); +__publicField(BarElement, "defaults", { + borderSkipped: "start", + borderWidth: 0, + borderRadius: 0, + inflateAmount: "auto", + pointStyle: void 0 +}); +__publicField(BarElement, "defaultRoutes", { + backgroundColor: "backgroundColor", + borderColor: "borderColor" +}); +var elements = /* @__PURE__ */ Object.freeze({ + __proto__: null, + ArcElement, + BarElement, + LineElement, + PointElement +}); +var BORDER_COLORS = [ + "rgb(54, 162, 235)", + "rgb(255, 99, 132)", + "rgb(255, 159, 64)", + "rgb(255, 205, 86)", + "rgb(75, 192, 192)", + "rgb(153, 102, 255)", + "rgb(201, 203, 207)" + // grey +]; +var BACKGROUND_COLORS = /* @__PURE__ */ BORDER_COLORS.map((color3) => color3.replace("rgb(", "rgba(").replace(")", ", 0.5)")); +function getBorderColor(i) { + return BORDER_COLORS[i % BORDER_COLORS.length]; +} +function getBackgroundColor(i) { + return BACKGROUND_COLORS[i % BACKGROUND_COLORS.length]; +} +function colorizeDefaultDataset(dataset, i) { + dataset.borderColor = getBorderColor(i); + dataset.backgroundColor = getBackgroundColor(i); + return ++i; +} +function colorizeDoughnutDataset(dataset, i) { + dataset.backgroundColor = dataset.data.map(() => getBorderColor(i++)); + return i; +} +function colorizePolarAreaDataset(dataset, i) { + dataset.backgroundColor = dataset.data.map(() => getBackgroundColor(i++)); + return i; +} +function getColorizer(chart) { + let i = 0; + return (dataset, datasetIndex) => { + const controller = chart.getDatasetMeta(datasetIndex).controller; + if (controller instanceof DoughnutController) { + i = colorizeDoughnutDataset(dataset, i); + } else if (controller instanceof PolarAreaController) { + i = colorizePolarAreaDataset(dataset, i); + } else if (controller) { + i = colorizeDefaultDataset(dataset, i); + } + }; +} +function containsColorsDefinitions(descriptors3) { + let k; + for (k in descriptors3) { + if (descriptors3[k].borderColor || descriptors3[k].backgroundColor) { + return true; + } + } + return false; +} +function containsColorsDefinition(descriptor) { + return descriptor && (descriptor.borderColor || descriptor.backgroundColor); +} +var plugin_colors = { + id: "colors", + defaults: { + enabled: true, + forceOverride: false + }, + beforeLayout(chart, _args, options) { + if (!options.enabled) { + return; + } + const { data: { datasets }, options: chartOptions } = chart.config; + const { elements: elements2 } = chartOptions; + if (!options.forceOverride && (containsColorsDefinitions(datasets) || containsColorsDefinition(chartOptions) || elements2 && containsColorsDefinitions(elements2))) { + return; + } + const colorizer = getColorizer(chart); + datasets.forEach(colorizer); + } +}; +function lttbDecimation(data, start, count, availableWidth, options) { + const samples = options.samples || availableWidth; + if (samples >= count) { + return data.slice(start, start + count); + } + const decimated = []; + const bucketWidth = (count - 2) / (samples - 2); + let sampledIndex = 0; + const endIndex = start + count - 1; + let a = start; + let i, maxAreaPoint, maxArea, area, nextA; + decimated[sampledIndex++] = data[a]; + for (i = 0; i < samples - 2; i++) { + let avgX = 0; + let avgY = 0; + let j; + const avgRangeStart = Math.floor((i + 1) * bucketWidth) + 1 + start; + const avgRangeEnd = Math.min(Math.floor((i + 2) * bucketWidth) + 1, count) + start; + const avgRangeLength = avgRangeEnd - avgRangeStart; + for (j = avgRangeStart; j < avgRangeEnd; j++) { + avgX += data[j].x; + avgY += data[j].y; + } + avgX /= avgRangeLength; + avgY /= avgRangeLength; + const rangeOffs = Math.floor(i * bucketWidth) + 1 + start; + const rangeTo = Math.min(Math.floor((i + 1) * bucketWidth) + 1, count) + start; + const { x: pointAx, y: pointAy } = data[a]; + maxArea = area = -1; + for (j = rangeOffs; j < rangeTo; j++) { + area = 0.5 * Math.abs((pointAx - avgX) * (data[j].y - pointAy) - (pointAx - data[j].x) * (avgY - pointAy)); + if (area > maxArea) { + maxArea = area; + maxAreaPoint = data[j]; + nextA = j; + } + } + decimated[sampledIndex++] = maxAreaPoint; + a = nextA; + } + decimated[sampledIndex++] = data[endIndex]; + return decimated; +} +function minMaxDecimation(data, start, count, availableWidth) { + let avgX = 0; + let countX = 0; + let i, point, x, y, prevX, minIndex, maxIndex, startIndex, minY, maxY; + const decimated = []; + const endIndex = start + count - 1; + const xMin = data[start].x; + const xMax = data[endIndex].x; + const dx = xMax - xMin; + for (i = start; i < start + count; ++i) { + point = data[i]; + x = (point.x - xMin) / dx * availableWidth; + y = point.y; + const truncX = x | 0; + if (truncX === prevX) { + if (y < minY) { + minY = y; + minIndex = i; + } else if (y > maxY) { + maxY = y; + maxIndex = i; + } + avgX = (countX * avgX + point.x) / ++countX; + } else { + const lastIndex = i - 1; + if (!isNullOrUndef(minIndex) && !isNullOrUndef(maxIndex)) { + const intermediateIndex1 = Math.min(minIndex, maxIndex); + const intermediateIndex2 = Math.max(minIndex, maxIndex); + if (intermediateIndex1 !== startIndex && intermediateIndex1 !== lastIndex) { + decimated.push({ + ...data[intermediateIndex1], + x: avgX + }); + } + if (intermediateIndex2 !== startIndex && intermediateIndex2 !== lastIndex) { + decimated.push({ + ...data[intermediateIndex2], + x: avgX + }); + } + } + if (i > 0 && lastIndex !== startIndex) { + decimated.push(data[lastIndex]); + } + decimated.push(point); + prevX = truncX; + countX = 0; + minY = maxY = y; + minIndex = maxIndex = startIndex = i; + } + } + return decimated; +} +function cleanDecimatedDataset(dataset) { + if (dataset._decimated) { + const data = dataset._data; + delete dataset._decimated; + delete dataset._data; + Object.defineProperty(dataset, "data", { + configurable: true, + enumerable: true, + writable: true, + value: data + }); + } +} +function cleanDecimatedData(chart) { + chart.data.datasets.forEach((dataset) => { + cleanDecimatedDataset(dataset); + }); +} +function getStartAndCountOfVisiblePointsSimplified(meta, points) { + const pointCount = points.length; + let start = 0; + let count; + const { iScale } = meta; + const { min, max, minDefined, maxDefined } = iScale.getUserBounds(); + if (minDefined) { + start = _limitValue(_lookupByKey(points, iScale.axis, min).lo, 0, pointCount - 1); + } + if (maxDefined) { + count = _limitValue(_lookupByKey(points, iScale.axis, max).hi + 1, start, pointCount) - start; + } else { + count = pointCount - start; + } + return { + start, + count + }; +} +var plugin_decimation = { + id: "decimation", + defaults: { + algorithm: "min-max", + enabled: false + }, + beforeElementsUpdate: (chart, args, options) => { + if (!options.enabled) { + cleanDecimatedData(chart); + return; + } + const availableWidth = chart.width; + chart.data.datasets.forEach((dataset, datasetIndex) => { + const { _data, indexAxis } = dataset; + const meta = chart.getDatasetMeta(datasetIndex); + const data = _data || dataset.data; + if (resolve([ + indexAxis, + chart.options.indexAxis + ]) === "y") { + return; + } + if (!meta.controller.supportsDecimation) { + return; + } + const xAxis = chart.scales[meta.xAxisID]; + if (xAxis.type !== "linear" && xAxis.type !== "time") { + return; + } + if (chart.options.parsing) { + return; + } + let { start, count } = getStartAndCountOfVisiblePointsSimplified(meta, data); + const threshold = options.threshold || 4 * availableWidth; + if (count <= threshold) { + cleanDecimatedDataset(dataset); + return; + } + if (isNullOrUndef(_data)) { + dataset._data = data; + delete dataset.data; + Object.defineProperty(dataset, "data", { + configurable: true, + enumerable: true, + get: function() { + return this._decimated; + }, + set: function(d) { + this._data = d; + } + }); + } + let decimated; + switch (options.algorithm) { + case "lttb": + decimated = lttbDecimation(data, start, count, availableWidth, options); + break; + case "min-max": + decimated = minMaxDecimation(data, start, count, availableWidth); + break; + default: + throw new Error(`Unsupported decimation algorithm '${options.algorithm}'`); + } + dataset._decimated = decimated; + }); + }, + destroy(chart) { + cleanDecimatedData(chart); + } +}; +function _segments(line, target, property) { + const segments = line.segments; + const points = line.points; + const tpoints = target.points; + const parts = []; + for (const segment of segments) { + let { start, end } = segment; + end = _findSegmentEnd(start, end, points); + const bounds = _getBounds(property, points[start], points[end], segment.loop); + if (!target.segments) { + parts.push({ + source: segment, + target: bounds, + start: points[start], + end: points[end] + }); + continue; + } + const targetSegments = _boundSegments(target, bounds); + for (const tgt of targetSegments) { + const subBounds = _getBounds(property, tpoints[tgt.start], tpoints[tgt.end], tgt.loop); + const fillSources = _boundSegment(segment, points, subBounds); + for (const fillSource of fillSources) { + parts.push({ + source: fillSource, + target: tgt, + start: { + [property]: _getEdge(bounds, subBounds, "start", Math.max) + }, + end: { + [property]: _getEdge(bounds, subBounds, "end", Math.min) + } + }); + } + } + } + return parts; +} +function _getBounds(property, first, last, loop) { + if (loop) { + return; + } + let start = first[property]; + let end = last[property]; + if (property === "angle") { + start = _normalizeAngle(start); + end = _normalizeAngle(end); + } + return { + property, + start, + end + }; +} +function _pointsFromSegments(boundary, line) { + const { x = null, y = null } = boundary || {}; + const linePoints = line.points; + const points = []; + line.segments.forEach(({ start, end }) => { + end = _findSegmentEnd(start, end, linePoints); + const first = linePoints[start]; + const last = linePoints[end]; + if (y !== null) { + points.push({ + x: first.x, + y + }); + points.push({ + x: last.x, + y + }); + } else if (x !== null) { + points.push({ + x, + y: first.y + }); + points.push({ + x, + y: last.y + }); + } + }); + return points; +} +function _findSegmentEnd(start, end, points) { + for (; end > start; end--) { + const point = points[end]; + if (!isNaN(point.x) && !isNaN(point.y)) { + break; + } + } + return end; +} +function _getEdge(a, b, prop, fn) { + if (a && b) { + return fn(a[prop], b[prop]); + } + return a ? a[prop] : b ? b[prop] : 0; +} +function _createBoundaryLine(boundary, line) { + let points = []; + let _loop = false; + if (isArray(boundary)) { + _loop = true; + points = boundary; + } else { + points = _pointsFromSegments(boundary, line); + } + return points.length ? new LineElement({ + points, + options: { + tension: 0 + }, + _loop, + _fullLoop: _loop + }) : null; +} +function _shouldApplyFill(source) { + return source && source.fill !== false; +} +function _resolveTarget(sources, index2, propagate) { + const source = sources[index2]; + let fill2 = source.fill; + const visited = [ + index2 + ]; + let target; + if (!propagate) { + return fill2; + } + while (fill2 !== false && visited.indexOf(fill2) === -1) { + if (!isNumberFinite(fill2)) { + return fill2; + } + target = sources[fill2]; + if (!target) { + return false; + } + if (target.visible) { + return fill2; + } + visited.push(fill2); + fill2 = target.fill; + } + return false; +} +function _decodeFill(line, index2, count) { + const fill2 = parseFillOption(line); + if (isObject(fill2)) { + return isNaN(fill2.value) ? false : fill2; + } + let target = parseFloat(fill2); + if (isNumberFinite(target) && Math.floor(target) === target) { + return decodeTargetIndex(fill2[0], index2, target, count); + } + return [ + "origin", + "start", + "end", + "stack", + "shape" + ].indexOf(fill2) >= 0 && fill2; +} +function decodeTargetIndex(firstCh, index2, target, count) { + if (firstCh === "-" || firstCh === "+") { + target = index2 + target; + } + if (target === index2 || target < 0 || target >= count) { + return false; + } + return target; +} +function _getTargetPixel(fill2, scale) { + let pixel = null; + if (fill2 === "start") { + pixel = scale.bottom; + } else if (fill2 === "end") { + pixel = scale.top; + } else if (isObject(fill2)) { + pixel = scale.getPixelForValue(fill2.value); + } else if (scale.getBasePixel) { + pixel = scale.getBasePixel(); + } + return pixel; +} +function _getTargetValue(fill2, scale, startValue) { + let value; + if (fill2 === "start") { + value = startValue; + } else if (fill2 === "end") { + value = scale.options.reverse ? scale.min : scale.max; + } else if (isObject(fill2)) { + value = fill2.value; + } else { + value = scale.getBaseValue(); + } + return value; +} +function parseFillOption(line) { + const options = line.options; + const fillOption = options.fill; + let fill2 = valueOrDefault(fillOption && fillOption.target, fillOption); + if (fill2 === void 0) { + fill2 = !!options.backgroundColor; + } + if (fill2 === false || fill2 === null) { + return false; + } + if (fill2 === true) { + return "origin"; + } + return fill2; +} +function _buildStackLine(source) { + const { scale, index: index2, line } = source; + const points = []; + const segments = line.segments; + const sourcePoints = line.points; + const linesBelow = getLinesBelow(scale, index2); + linesBelow.push(_createBoundaryLine({ + x: null, + y: scale.bottom + }, line)); + for (let i = 0; i < segments.length; i++) { + const segment = segments[i]; + for (let j = segment.start; j <= segment.end; j++) { + addPointsBelow(points, sourcePoints[j], linesBelow); + } + } + return new LineElement({ + points, + options: {} + }); +} +function getLinesBelow(scale, index2) { + const below = []; + const metas = scale.getMatchingVisibleMetas("line"); + for (let i = 0; i < metas.length; i++) { + const meta = metas[i]; + if (meta.index === index2) { + break; + } + if (!meta.hidden) { + below.unshift(meta.dataset); + } + } + return below; +} +function addPointsBelow(points, sourcePoint, linesBelow) { + const postponed = []; + for (let j = 0; j < linesBelow.length; j++) { + const line = linesBelow[j]; + const { first, last, point } = findPoint(line, sourcePoint, "x"); + if (!point || first && last) { + continue; + } + if (first) { + postponed.unshift(point); + } else { + points.push(point); + if (!last) { + break; + } + } + } + points.push(...postponed); +} +function findPoint(line, sourcePoint, property) { + const point = line.interpolate(sourcePoint, property); + if (!point) { + return {}; + } + const pointValue = point[property]; + const segments = line.segments; + const linePoints = line.points; + let first = false; + let last = false; + for (let i = 0; i < segments.length; i++) { + const segment = segments[i]; + const firstValue = linePoints[segment.start][property]; + const lastValue = linePoints[segment.end][property]; + if (_isBetween(pointValue, firstValue, lastValue)) { + first = pointValue === firstValue; + last = pointValue === lastValue; + break; + } + } + return { + first, + last, + point + }; +} +var simpleArc = class { + constructor(opts) { + this.x = opts.x; + this.y = opts.y; + this.radius = opts.radius; + } + pathSegment(ctx, bounds, opts) { + const { x, y, radius } = this; + bounds = bounds || { + start: 0, + end: TAU + }; + ctx.arc(x, y, radius, bounds.end, bounds.start, true); + return !opts.bounds; + } + interpolate(point) { + const { x, y, radius } = this; + const angle = point.angle; + return { + x: x + Math.cos(angle) * radius, + y: y + Math.sin(angle) * radius, + angle + }; + } +}; +function _getTarget(source) { + const { chart, fill: fill2, line } = source; + if (isNumberFinite(fill2)) { + return getLineByIndex(chart, fill2); + } + if (fill2 === "stack") { + return _buildStackLine(source); + } + if (fill2 === "shape") { + return true; + } + const boundary = computeBoundary(source); + if (boundary instanceof simpleArc) { + return boundary; + } + return _createBoundaryLine(boundary, line); +} +function getLineByIndex(chart, index2) { + const meta = chart.getDatasetMeta(index2); + const visible = meta && chart.isDatasetVisible(index2); + return visible ? meta.dataset : null; +} +function computeBoundary(source) { + const scale = source.scale || {}; + if (scale.getPointPositionForValue) { + return computeCircularBoundary(source); + } + return computeLinearBoundary(source); +} +function computeLinearBoundary(source) { + const { scale = {}, fill: fill2 } = source; + const pixel = _getTargetPixel(fill2, scale); + if (isNumberFinite(pixel)) { + const horizontal = scale.isHorizontal(); + return { + x: horizontal ? pixel : null, + y: horizontal ? null : pixel + }; + } + return null; +} +function computeCircularBoundary(source) { + const { scale, fill: fill2 } = source; + const options = scale.options; + const length = scale.getLabels().length; + const start = options.reverse ? scale.max : scale.min; + const value = _getTargetValue(fill2, scale, start); + const target = []; + if (options.grid.circular) { + const center = scale.getPointPositionForValue(0, start); + return new simpleArc({ + x: center.x, + y: center.y, + radius: scale.getDistanceFromCenterForValue(value) + }); + } + for (let i = 0; i < length; ++i) { + target.push(scale.getPointPositionForValue(i, value)); + } + return target; +} +function _drawfill(ctx, source, area) { + const target = _getTarget(source); + const { line, scale, axis } = source; + const lineOpts = line.options; + const fillOption = lineOpts.fill; + const color3 = lineOpts.backgroundColor; + const { above = color3, below = color3 } = fillOption || {}; + if (target && line.points.length) { + clipArea(ctx, area); + doFill(ctx, { + line, + target, + above, + below, + area, + scale, + axis + }); + unclipArea(ctx); + } +} +function doFill(ctx, cfg) { + const { line, target, above, below, area, scale } = cfg; + const property = line._loop ? "angle" : cfg.axis; + ctx.save(); + if (property === "x" && below !== above) { + clipVertical(ctx, target, area.top); + fill(ctx, { + line, + target, + color: above, + scale, + property + }); + ctx.restore(); + ctx.save(); + clipVertical(ctx, target, area.bottom); + } + fill(ctx, { + line, + target, + color: below, + scale, + property + }); + ctx.restore(); +} +function clipVertical(ctx, target, clipY) { + const { segments, points } = target; + let first = true; + let lineLoop = false; + ctx.beginPath(); + for (const segment of segments) { + const { start, end } = segment; + const firstPoint = points[start]; + const lastPoint = points[_findSegmentEnd(start, end, points)]; + if (first) { + ctx.moveTo(firstPoint.x, firstPoint.y); + first = false; + } else { + ctx.lineTo(firstPoint.x, clipY); + ctx.lineTo(firstPoint.x, firstPoint.y); + } + lineLoop = !!target.pathSegment(ctx, segment, { + move: lineLoop + }); + if (lineLoop) { + ctx.closePath(); + } else { + ctx.lineTo(lastPoint.x, clipY); + } + } + ctx.lineTo(target.first().x, clipY); + ctx.closePath(); + ctx.clip(); +} +function fill(ctx, cfg) { + const { line, target, property, color: color3, scale } = cfg; + const segments = _segments(line, target, property); + for (const { source: src, target: tgt, start, end } of segments) { + const { style: { backgroundColor = color3 } = {} } = src; + const notShape = target !== true; + ctx.save(); + ctx.fillStyle = backgroundColor; + clipBounds(ctx, scale, notShape && _getBounds(property, start, end)); + ctx.beginPath(); + const lineLoop = !!line.pathSegment(ctx, src); + let loop; + if (notShape) { + if (lineLoop) { + ctx.closePath(); + } else { + interpolatedLineTo(ctx, target, end, property); + } + const targetLoop = !!target.pathSegment(ctx, tgt, { + move: lineLoop, + reverse: true + }); + loop = lineLoop && targetLoop; + if (!loop) { + interpolatedLineTo(ctx, target, start, property); + } + } + ctx.closePath(); + ctx.fill(loop ? "evenodd" : "nonzero"); + ctx.restore(); + } +} +function clipBounds(ctx, scale, bounds) { + const { top, bottom } = scale.chart.chartArea; + const { property, start, end } = bounds || {}; + if (property === "x") { + ctx.beginPath(); + ctx.rect(start, top, end - start, bottom - top); + ctx.clip(); + } +} +function interpolatedLineTo(ctx, target, point, property) { + const interpolatedPoint = target.interpolate(point, property); + if (interpolatedPoint) { + ctx.lineTo(interpolatedPoint.x, interpolatedPoint.y); + } +} +var index = { + id: "filler", + afterDatasetsUpdate(chart, _args, options) { + const count = (chart.data.datasets || []).length; + const sources = []; + let meta, i, line, source; + for (i = 0; i < count; ++i) { + meta = chart.getDatasetMeta(i); + line = meta.dataset; + source = null; + if (line && line.options && line instanceof LineElement) { + source = { + visible: chart.isDatasetVisible(i), + index: i, + fill: _decodeFill(line, i, count), + chart, + axis: meta.controller.options.indexAxis, + scale: meta.vScale, + line + }; + } + meta.$filler = source; + sources.push(source); + } + for (i = 0; i < count; ++i) { + source = sources[i]; + if (!source || source.fill === false) { + continue; + } + source.fill = _resolveTarget(sources, i, options.propagate); + } + }, + beforeDraw(chart, _args, options) { + const draw2 = options.drawTime === "beforeDraw"; + const metasets = chart.getSortedVisibleDatasetMetas(); + const area = chart.chartArea; + for (let i = metasets.length - 1; i >= 0; --i) { + const source = metasets[i].$filler; + if (!source) { + continue; + } + source.line.updateControlPoints(area, source.axis); + if (draw2 && source.fill) { + _drawfill(chart.ctx, source, area); + } + } + }, + beforeDatasetsDraw(chart, _args, options) { + if (options.drawTime !== "beforeDatasetsDraw") { + return; + } + const metasets = chart.getSortedVisibleDatasetMetas(); + for (let i = metasets.length - 1; i >= 0; --i) { + const source = metasets[i].$filler; + if (_shouldApplyFill(source)) { + _drawfill(chart.ctx, source, chart.chartArea); + } + } + }, + beforeDatasetDraw(chart, args, options) { + const source = args.meta.$filler; + if (!_shouldApplyFill(source) || options.drawTime !== "beforeDatasetDraw") { + return; + } + _drawfill(chart.ctx, source, chart.chartArea); + }, + defaults: { + propagate: true, + drawTime: "beforeDatasetDraw" + } +}; +var getBoxSize = (labelOpts, fontSize) => { + let { boxHeight = fontSize, boxWidth = fontSize } = labelOpts; + if (labelOpts.usePointStyle) { + boxHeight = Math.min(boxHeight, fontSize); + boxWidth = labelOpts.pointStyleWidth || Math.min(boxWidth, fontSize); + } + return { + boxWidth, + boxHeight, + itemHeight: Math.max(fontSize, boxHeight) + }; +}; +var itemsEqual = (a, b) => a !== null && b !== null && a.datasetIndex === b.datasetIndex && a.index === b.index; +var Legend = class extends Element { + constructor(config) { + super(); + this._added = false; + this.legendHitBoxes = []; + this._hoveredItem = null; + this.doughnutMode = false; + this.chart = config.chart; + this.options = config.options; + this.ctx = config.ctx; + this.legendItems = void 0; + this.columnSizes = void 0; + this.lineWidths = void 0; + this.maxHeight = void 0; + this.maxWidth = void 0; + this.top = void 0; + this.bottom = void 0; + this.left = void 0; + this.right = void 0; + this.height = void 0; + this.width = void 0; + this._margins = void 0; + this.position = void 0; + this.weight = void 0; + this.fullSize = void 0; + } + update(maxWidth, maxHeight, margins) { + this.maxWidth = maxWidth; + this.maxHeight = maxHeight; + this._margins = margins; + this.setDimensions(); + this.buildLabels(); + this.fit(); + } + setDimensions() { + if (this.isHorizontal()) { + this.width = this.maxWidth; + this.left = this._margins.left; + this.right = this.width; + } else { + this.height = this.maxHeight; + this.top = this._margins.top; + this.bottom = this.height; + } + } + buildLabels() { + const labelOpts = this.options.labels || {}; + let legendItems = callback(labelOpts.generateLabels, [ + this.chart + ], this) || []; + if (labelOpts.filter) { + legendItems = legendItems.filter((item) => labelOpts.filter(item, this.chart.data)); + } + if (labelOpts.sort) { + legendItems = legendItems.sort((a, b) => labelOpts.sort(a, b, this.chart.data)); + } + if (this.options.reverse) { + legendItems.reverse(); + } + this.legendItems = legendItems; + } + fit() { + const { options, ctx } = this; + if (!options.display) { + this.width = this.height = 0; + return; + } + const labelOpts = options.labels; + const labelFont = toFont(labelOpts.font); + const fontSize = labelFont.size; + const titleHeight = this._computeTitleHeight(); + const { boxWidth, itemHeight } = getBoxSize(labelOpts, fontSize); + let width, height; + ctx.font = labelFont.string; + if (this.isHorizontal()) { + width = this.maxWidth; + height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight) + 10; + } else { + height = this.maxHeight; + width = this._fitCols(titleHeight, labelFont, boxWidth, itemHeight) + 10; + } + this.width = Math.min(width, options.maxWidth || this.maxWidth); + this.height = Math.min(height, options.maxHeight || this.maxHeight); + } + _fitRows(titleHeight, fontSize, boxWidth, itemHeight) { + const { ctx, maxWidth, options: { labels: { padding } } } = this; + const hitboxes = this.legendHitBoxes = []; + const lineWidths = this.lineWidths = [ + 0 + ]; + const lineHeight = itemHeight + padding; + let totalHeight = titleHeight; + ctx.textAlign = "left"; + ctx.textBaseline = "middle"; + let row = -1; + let top = -lineHeight; + this.legendItems.forEach((legendItem, i) => { + const itemWidth = boxWidth + fontSize / 2 + ctx.measureText(legendItem.text).width; + if (i === 0 || lineWidths[lineWidths.length - 1] + itemWidth + 2 * padding > maxWidth) { + totalHeight += lineHeight; + lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = 0; + top += lineHeight; + row++; + } + hitboxes[i] = { + left: 0, + top, + row, + width: itemWidth, + height: itemHeight + }; + lineWidths[lineWidths.length - 1] += itemWidth + padding; + }); + return totalHeight; + } + _fitCols(titleHeight, labelFont, boxWidth, _itemHeight) { + const { ctx, maxHeight, options: { labels: { padding } } } = this; + const hitboxes = this.legendHitBoxes = []; + const columnSizes = this.columnSizes = []; + const heightLimit = maxHeight - titleHeight; + let totalWidth = padding; + let currentColWidth = 0; + let currentColHeight = 0; + let left = 0; + let col = 0; + this.legendItems.forEach((legendItem, i) => { + const { itemWidth, itemHeight } = calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight); + if (i > 0 && currentColHeight + itemHeight + 2 * padding > heightLimit) { + totalWidth += currentColWidth + padding; + columnSizes.push({ + width: currentColWidth, + height: currentColHeight + }); + left += currentColWidth + padding; + col++; + currentColWidth = currentColHeight = 0; + } + hitboxes[i] = { + left, + top: currentColHeight, + col, + width: itemWidth, + height: itemHeight + }; + currentColWidth = Math.max(currentColWidth, itemWidth); + currentColHeight += itemHeight + padding; + }); + totalWidth += currentColWidth; + columnSizes.push({ + width: currentColWidth, + height: currentColHeight + }); + return totalWidth; + } + adjustHitBoxes() { + if (!this.options.display) { + return; + } + const titleHeight = this._computeTitleHeight(); + const { legendHitBoxes: hitboxes, options: { align, labels: { padding }, rtl } } = this; + const rtlHelper = getRtlAdapter(rtl, this.left, this.width); + if (this.isHorizontal()) { + let row = 0; + let left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]); + for (const hitbox of hitboxes) { + if (row !== hitbox.row) { + row = hitbox.row; + left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]); + } + hitbox.top += this.top + titleHeight + padding; + hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(left), hitbox.width); + left += hitbox.width + padding; + } + } else { + let col = 0; + let top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height); + for (const hitbox of hitboxes) { + if (hitbox.col !== col) { + col = hitbox.col; + top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height); + } + hitbox.top = top; + hitbox.left += this.left + padding; + hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(hitbox.left), hitbox.width); + top += hitbox.height + padding; + } + } + } + isHorizontal() { + return this.options.position === "top" || this.options.position === "bottom"; + } + draw() { + if (this.options.display) { + const ctx = this.ctx; + clipArea(ctx, this); + this._draw(); + unclipArea(ctx); + } + } + _draw() { + const { options: opts, columnSizes, lineWidths, ctx } = this; + const { align, labels: labelOpts } = opts; + const defaultColor = defaults.color; + const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width); + const labelFont = toFont(labelOpts.font); + const { padding } = labelOpts; + const fontSize = labelFont.size; + const halfFontSize = fontSize / 2; + let cursor; + this.drawTitle(); + ctx.textAlign = rtlHelper.textAlign("left"); + ctx.textBaseline = "middle"; + ctx.lineWidth = 0.5; + ctx.font = labelFont.string; + const { boxWidth, boxHeight, itemHeight } = getBoxSize(labelOpts, fontSize); + const drawLegendBox = function(x, y, legendItem) { + if (isNaN(boxWidth) || boxWidth <= 0 || isNaN(boxHeight) || boxHeight < 0) { + return; + } + ctx.save(); + const lineWidth = valueOrDefault(legendItem.lineWidth, 1); + ctx.fillStyle = valueOrDefault(legendItem.fillStyle, defaultColor); + ctx.lineCap = valueOrDefault(legendItem.lineCap, "butt"); + ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, 0); + ctx.lineJoin = valueOrDefault(legendItem.lineJoin, "miter"); + ctx.lineWidth = lineWidth; + ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, defaultColor); + ctx.setLineDash(valueOrDefault(legendItem.lineDash, [])); + if (labelOpts.usePointStyle) { + const drawOptions = { + radius: boxHeight * Math.SQRT2 / 2, + pointStyle: legendItem.pointStyle, + rotation: legendItem.rotation, + borderWidth: lineWidth + }; + const centerX = rtlHelper.xPlus(x, boxWidth / 2); + const centerY = y + halfFontSize; + drawPointLegend(ctx, drawOptions, centerX, centerY, labelOpts.pointStyleWidth && boxWidth); + } else { + const yBoxTop = y + Math.max((fontSize - boxHeight) / 2, 0); + const xBoxLeft = rtlHelper.leftForLtr(x, boxWidth); + const borderRadius = toTRBLCorners(legendItem.borderRadius); + ctx.beginPath(); + if (Object.values(borderRadius).some((v) => v !== 0)) { + addRoundedRectPath(ctx, { + x: xBoxLeft, + y: yBoxTop, + w: boxWidth, + h: boxHeight, + radius: borderRadius + }); + } else { + ctx.rect(xBoxLeft, yBoxTop, boxWidth, boxHeight); + } + ctx.fill(); + if (lineWidth !== 0) { + ctx.stroke(); + } + } + ctx.restore(); + }; + const fillText = function(x, y, legendItem) { + renderText(ctx, legendItem.text, x, y + itemHeight / 2, labelFont, { + strikethrough: legendItem.hidden, + textAlign: rtlHelper.textAlign(legendItem.textAlign) + }); + }; + const isHorizontal = this.isHorizontal(); + const titleHeight = this._computeTitleHeight(); + if (isHorizontal) { + cursor = { + x: _alignStartEnd(align, this.left + padding, this.right - lineWidths[0]), + y: this.top + padding + titleHeight, + line: 0 + }; + } else { + cursor = { + x: this.left + padding, + y: _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[0].height), + line: 0 + }; + } + overrideTextDirection(this.ctx, opts.textDirection); + const lineHeight = itemHeight + padding; + this.legendItems.forEach((legendItem, i) => { + ctx.strokeStyle = legendItem.fontColor; + ctx.fillStyle = legendItem.fontColor; + const textWidth = ctx.measureText(legendItem.text).width; + const textAlign = rtlHelper.textAlign(legendItem.textAlign || (legendItem.textAlign = labelOpts.textAlign)); + const width = boxWidth + halfFontSize + textWidth; + let x = cursor.x; + let y = cursor.y; + rtlHelper.setWidth(this.width); + if (isHorizontal) { + if (i > 0 && x + width + padding > this.right) { + y = cursor.y += lineHeight; + cursor.line++; + x = cursor.x = _alignStartEnd(align, this.left + padding, this.right - lineWidths[cursor.line]); + } + } else if (i > 0 && y + lineHeight > this.bottom) { + x = cursor.x = x + columnSizes[cursor.line].width + padding; + cursor.line++; + y = cursor.y = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[cursor.line].height); + } + const realX = rtlHelper.x(x); + drawLegendBox(realX, y, legendItem); + x = _textX(textAlign, x + boxWidth + halfFontSize, isHorizontal ? x + width : this.right, opts.rtl); + fillText(rtlHelper.x(x), y, legendItem); + if (isHorizontal) { + cursor.x += width + padding; + } else if (typeof legendItem.text !== "string") { + const fontLineHeight = labelFont.lineHeight; + cursor.y += calculateLegendItemHeight(legendItem, fontLineHeight) + padding; + } else { + cursor.y += lineHeight; + } + }); + restoreTextDirection(this.ctx, opts.textDirection); + } + drawTitle() { + const opts = this.options; + const titleOpts = opts.title; + const titleFont = toFont(titleOpts.font); + const titlePadding = toPadding(titleOpts.padding); + if (!titleOpts.display) { + return; + } + const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width); + const ctx = this.ctx; + const position = titleOpts.position; + const halfFontSize = titleFont.size / 2; + const topPaddingPlusHalfFontSize = titlePadding.top + halfFontSize; + let y; + let left = this.left; + let maxWidth = this.width; + if (this.isHorizontal()) { + maxWidth = Math.max(...this.lineWidths); + y = this.top + topPaddingPlusHalfFontSize; + left = _alignStartEnd(opts.align, left, this.right - maxWidth); + } else { + const maxHeight = this.columnSizes.reduce((acc, size) => Math.max(acc, size.height), 0); + y = topPaddingPlusHalfFontSize + _alignStartEnd(opts.align, this.top, this.bottom - maxHeight - opts.labels.padding - this._computeTitleHeight()); + } + const x = _alignStartEnd(position, left, left + maxWidth); + ctx.textAlign = rtlHelper.textAlign(_toLeftRightCenter(position)); + ctx.textBaseline = "middle"; + ctx.strokeStyle = titleOpts.color; + ctx.fillStyle = titleOpts.color; + ctx.font = titleFont.string; + renderText(ctx, titleOpts.text, x, y, titleFont); + } + _computeTitleHeight() { + const titleOpts = this.options.title; + const titleFont = toFont(titleOpts.font); + const titlePadding = toPadding(titleOpts.padding); + return titleOpts.display ? titleFont.lineHeight + titlePadding.height : 0; + } + _getLegendItemAt(x, y) { + let i, hitBox, lh; + if (_isBetween(x, this.left, this.right) && _isBetween(y, this.top, this.bottom)) { + lh = this.legendHitBoxes; + for (i = 0; i < lh.length; ++i) { + hitBox = lh[i]; + if (_isBetween(x, hitBox.left, hitBox.left + hitBox.width) && _isBetween(y, hitBox.top, hitBox.top + hitBox.height)) { + return this.legendItems[i]; + } + } + } + return null; + } + handleEvent(e) { + const opts = this.options; + if (!isListened(e.type, opts)) { + return; + } + const hoveredItem = this._getLegendItemAt(e.x, e.y); + if (e.type === "mousemove" || e.type === "mouseout") { + const previous = this._hoveredItem; + const sameItem = itemsEqual(previous, hoveredItem); + if (previous && !sameItem) { + callback(opts.onLeave, [ + e, + previous, + this + ], this); + } + this._hoveredItem = hoveredItem; + if (hoveredItem && !sameItem) { + callback(opts.onHover, [ + e, + hoveredItem, + this + ], this); + } + } else if (hoveredItem) { + callback(opts.onClick, [ + e, + hoveredItem, + this + ], this); + } + } +}; +function calculateItemSize(boxWidth, labelFont, ctx, legendItem, _itemHeight) { + const itemWidth = calculateItemWidth(legendItem, boxWidth, labelFont, ctx); + const itemHeight = calculateItemHeight(_itemHeight, legendItem, labelFont.lineHeight); + return { + itemWidth, + itemHeight + }; +} +function calculateItemWidth(legendItem, boxWidth, labelFont, ctx) { + let legendItemText = legendItem.text; + if (legendItemText && typeof legendItemText !== "string") { + legendItemText = legendItemText.reduce((a, b) => a.length > b.length ? a : b); + } + return boxWidth + labelFont.size / 2 + ctx.measureText(legendItemText).width; +} +function calculateItemHeight(_itemHeight, legendItem, fontLineHeight) { + let itemHeight = _itemHeight; + if (typeof legendItem.text !== "string") { + itemHeight = calculateLegendItemHeight(legendItem, fontLineHeight); + } + return itemHeight; +} +function calculateLegendItemHeight(legendItem, fontLineHeight) { + const labelHeight = legendItem.text ? legendItem.text.length : 0; + return fontLineHeight * labelHeight; +} +function isListened(type, opts) { + if ((type === "mousemove" || type === "mouseout") && (opts.onHover || opts.onLeave)) { + return true; + } + if (opts.onClick && (type === "click" || type === "mouseup")) { + return true; + } + return false; +} +var plugin_legend = { + id: "legend", + _element: Legend, + start(chart, _args, options) { + const legend = chart.legend = new Legend({ + ctx: chart.ctx, + options, + chart + }); + layouts.configure(chart, legend, options); + layouts.addBox(chart, legend); + }, + stop(chart) { + layouts.removeBox(chart, chart.legend); + delete chart.legend; + }, + beforeUpdate(chart, _args, options) { + const legend = chart.legend; + layouts.configure(chart, legend, options); + legend.options = options; + }, + afterUpdate(chart) { + const legend = chart.legend; + legend.buildLabels(); + legend.adjustHitBoxes(); + }, + afterEvent(chart, args) { + if (!args.replay) { + chart.legend.handleEvent(args.event); + } + }, + defaults: { + display: true, + position: "top", + align: "center", + fullSize: true, + reverse: false, + weight: 1e3, + onClick(e, legendItem, legend) { + const index2 = legendItem.datasetIndex; + const ci = legend.chart; + if (ci.isDatasetVisible(index2)) { + ci.hide(index2); + legendItem.hidden = true; + } else { + ci.show(index2); + legendItem.hidden = false; + } + }, + onHover: null, + onLeave: null, + labels: { + color: (ctx) => ctx.chart.options.color, + boxWidth: 40, + padding: 10, + generateLabels(chart) { + const datasets = chart.data.datasets; + const { labels: { usePointStyle, pointStyle, textAlign, color: color3, useBorderRadius, borderRadius } } = chart.legend.options; + return chart._getSortedDatasetMetas().map((meta) => { + const style = meta.controller.getStyle(usePointStyle ? 0 : void 0); + const borderWidth = toPadding(style.borderWidth); + return { + text: datasets[meta.index].label, + fillStyle: style.backgroundColor, + fontColor: color3, + hidden: !meta.visible, + lineCap: style.borderCapStyle, + lineDash: style.borderDash, + lineDashOffset: style.borderDashOffset, + lineJoin: style.borderJoinStyle, + lineWidth: (borderWidth.width + borderWidth.height) / 4, + strokeStyle: style.borderColor, + pointStyle: pointStyle || style.pointStyle, + rotation: style.rotation, + textAlign: textAlign || style.textAlign, + borderRadius: useBorderRadius && (borderRadius || style.borderRadius), + datasetIndex: meta.index + }; + }, this); + } + }, + title: { + color: (ctx) => ctx.chart.options.color, + display: false, + position: "center", + text: "" + } + }, + descriptors: { + _scriptable: (name) => !name.startsWith("on"), + labels: { + _scriptable: (name) => ![ + "generateLabels", + "filter", + "sort" + ].includes(name) + } + } +}; +var Title = class extends Element { + constructor(config) { + super(); + this.chart = config.chart; + this.options = config.options; + this.ctx = config.ctx; + this._padding = void 0; + this.top = void 0; + this.bottom = void 0; + this.left = void 0; + this.right = void 0; + this.width = void 0; + this.height = void 0; + this.position = void 0; + this.weight = void 0; + this.fullSize = void 0; + } + update(maxWidth, maxHeight) { + const opts = this.options; + this.left = 0; + this.top = 0; + if (!opts.display) { + this.width = this.height = this.right = this.bottom = 0; + return; + } + this.width = this.right = maxWidth; + this.height = this.bottom = maxHeight; + const lineCount = isArray(opts.text) ? opts.text.length : 1; + this._padding = toPadding(opts.padding); + const textSize = lineCount * toFont(opts.font).lineHeight + this._padding.height; + if (this.isHorizontal()) { + this.height = textSize; + } else { + this.width = textSize; + } + } + isHorizontal() { + const pos = this.options.position; + return pos === "top" || pos === "bottom"; + } + _drawArgs(offset2) { + const { top, left, bottom, right, options } = this; + const align = options.align; + let rotation = 0; + let maxWidth, titleX, titleY; + if (this.isHorizontal()) { + titleX = _alignStartEnd(align, left, right); + titleY = top + offset2; + maxWidth = right - left; + } else { + if (options.position === "left") { + titleX = left + offset2; + titleY = _alignStartEnd(align, bottom, top); + rotation = PI * -0.5; + } else { + titleX = right - offset2; + titleY = _alignStartEnd(align, top, bottom); + rotation = PI * 0.5; + } + maxWidth = bottom - top; + } + return { + titleX, + titleY, + maxWidth, + rotation + }; + } + draw() { + const ctx = this.ctx; + const opts = this.options; + if (!opts.display) { + return; + } + const fontOpts = toFont(opts.font); + const lineHeight = fontOpts.lineHeight; + const offset2 = lineHeight / 2 + this._padding.top; + const { titleX, titleY, maxWidth, rotation } = this._drawArgs(offset2); + renderText(ctx, opts.text, 0, 0, fontOpts, { + color: opts.color, + maxWidth, + rotation, + textAlign: _toLeftRightCenter(opts.align), + textBaseline: "middle", + translation: [ + titleX, + titleY + ] + }); + } +}; +function createTitle(chart, titleOpts) { + const title = new Title({ + ctx: chart.ctx, + options: titleOpts, + chart + }); + layouts.configure(chart, title, titleOpts); + layouts.addBox(chart, title); + chart.titleBlock = title; +} +var plugin_title = { + id: "title", + _element: Title, + start(chart, _args, options) { + createTitle(chart, options); + }, + stop(chart) { + const titleBlock = chart.titleBlock; + layouts.removeBox(chart, titleBlock); + delete chart.titleBlock; + }, + beforeUpdate(chart, _args, options) { + const title = chart.titleBlock; + layouts.configure(chart, title, options); + title.options = options; + }, + defaults: { + align: "center", + display: false, + font: { + weight: "bold" + }, + fullSize: true, + padding: 10, + position: "top", + text: "", + weight: 2e3 + }, + defaultRoutes: { + color: "color" + }, + descriptors: { + _scriptable: true, + _indexable: false + } +}; +var map2 = /* @__PURE__ */ new WeakMap(); +var plugin_subtitle = { + id: "subtitle", + start(chart, _args, options) { + const title = new Title({ + ctx: chart.ctx, + options, + chart + }); + layouts.configure(chart, title, options); + layouts.addBox(chart, title); + map2.set(chart, title); + }, + stop(chart) { + layouts.removeBox(chart, map2.get(chart)); + map2.delete(chart); + }, + beforeUpdate(chart, _args, options) { + const title = map2.get(chart); + layouts.configure(chart, title, options); + title.options = options; + }, + defaults: { + align: "center", + display: false, + font: { + weight: "normal" + }, + fullSize: true, + padding: 0, + position: "top", + text: "", + weight: 1500 + }, + defaultRoutes: { + color: "color" + }, + descriptors: { + _scriptable: true, + _indexable: false + } +}; +var positioners = { + average(items) { + if (!items.length) { + return false; + } + let i, len; + let xSet = /* @__PURE__ */ new Set(); + let y = 0; + let count = 0; + for (i = 0, len = items.length; i < len; ++i) { + const el = items[i].element; + if (el && el.hasValue()) { + const pos = el.tooltipPosition(); + xSet.add(pos.x); + y += pos.y; + ++count; + } + } + const xAverage = [ + ...xSet + ].reduce((a, b) => a + b) / xSet.size; + return { + x: xAverage, + y: y / count + }; + }, + nearest(items, eventPosition) { + if (!items.length) { + return false; + } + let x = eventPosition.x; + let y = eventPosition.y; + let minDistance = Number.POSITIVE_INFINITY; + let i, len, nearestElement; + for (i = 0, len = items.length; i < len; ++i) { + const el = items[i].element; + if (el && el.hasValue()) { + const center = el.getCenterPoint(); + const d = distanceBetweenPoints(eventPosition, center); + if (d < minDistance) { + minDistance = d; + nearestElement = el; + } + } + } + if (nearestElement) { + const tp = nearestElement.tooltipPosition(); + x = tp.x; + y = tp.y; + } + return { + x, + y + }; + } +}; +function pushOrConcat(base, toPush) { + if (toPush) { + if (isArray(toPush)) { + Array.prototype.push.apply(base, toPush); + } else { + base.push(toPush); + } + } + return base; +} +function splitNewlines(str) { + if ((typeof str === "string" || str instanceof String) && str.indexOf("\n") > -1) { + return str.split("\n"); + } + return str; +} +function createTooltipItem(chart, item) { + const { element, datasetIndex, index: index2 } = item; + const controller = chart.getDatasetMeta(datasetIndex).controller; + const { label, value } = controller.getLabelAndValue(index2); + return { + chart, + label, + parsed: controller.getParsed(index2), + raw: chart.data.datasets[datasetIndex].data[index2], + formattedValue: value, + dataset: controller.getDataset(), + dataIndex: index2, + datasetIndex, + element + }; +} +function getTooltipSize(tooltip, options) { + const ctx = tooltip.chart.ctx; + const { body, footer, title } = tooltip; + const { boxWidth, boxHeight } = options; + const bodyFont = toFont(options.bodyFont); + const titleFont = toFont(options.titleFont); + const footerFont = toFont(options.footerFont); + const titleLineCount = title.length; + const footerLineCount = footer.length; + const bodyLineItemCount = body.length; + const padding = toPadding(options.padding); + let height = padding.height; + let width = 0; + let combinedBodyLength = body.reduce((count, bodyItem) => count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length, 0); + combinedBodyLength += tooltip.beforeBody.length + tooltip.afterBody.length; + if (titleLineCount) { + height += titleLineCount * titleFont.lineHeight + (titleLineCount - 1) * options.titleSpacing + options.titleMarginBottom; + } + if (combinedBodyLength) { + const bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFont.lineHeight) : bodyFont.lineHeight; + height += bodyLineItemCount * bodyLineHeight + (combinedBodyLength - bodyLineItemCount) * bodyFont.lineHeight + (combinedBodyLength - 1) * options.bodySpacing; + } + if (footerLineCount) { + height += options.footerMarginTop + footerLineCount * footerFont.lineHeight + (footerLineCount - 1) * options.footerSpacing; + } + let widthPadding = 0; + const maxLineWidth = function(line) { + width = Math.max(width, ctx.measureText(line).width + widthPadding); + }; + ctx.save(); + ctx.font = titleFont.string; + each(tooltip.title, maxLineWidth); + ctx.font = bodyFont.string; + each(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth); + widthPadding = options.displayColors ? boxWidth + 2 + options.boxPadding : 0; + each(body, (bodyItem) => { + each(bodyItem.before, maxLineWidth); + each(bodyItem.lines, maxLineWidth); + each(bodyItem.after, maxLineWidth); + }); + widthPadding = 0; + ctx.font = footerFont.string; + each(tooltip.footer, maxLineWidth); + ctx.restore(); + width += padding.width; + return { + width, + height + }; +} +function determineYAlign(chart, size) { + const { y, height } = size; + if (y < height / 2) { + return "top"; + } else if (y > chart.height - height / 2) { + return "bottom"; + } + return "center"; +} +function doesNotFitWithAlign(xAlign, chart, options, size) { + const { x, width } = size; + const caret = options.caretSize + options.caretPadding; + if (xAlign === "left" && x + width + caret > chart.width) { + return true; + } + if (xAlign === "right" && x - width - caret < 0) { + return true; + } +} +function determineXAlign(chart, options, size, yAlign) { + const { x, width } = size; + const { width: chartWidth, chartArea: { left, right } } = chart; + let xAlign = "center"; + if (yAlign === "center") { + xAlign = x <= (left + right) / 2 ? "left" : "right"; + } else if (x <= width / 2) { + xAlign = "left"; + } else if (x >= chartWidth - width / 2) { + xAlign = "right"; + } + if (doesNotFitWithAlign(xAlign, chart, options, size)) { + xAlign = "center"; + } + return xAlign; +} +function determineAlignment(chart, options, size) { + const yAlign = size.yAlign || options.yAlign || determineYAlign(chart, size); + return { + xAlign: size.xAlign || options.xAlign || determineXAlign(chart, options, size, yAlign), + yAlign + }; +} +function alignX(size, xAlign) { + let { x, width } = size; + if (xAlign === "right") { + x -= width; + } else if (xAlign === "center") { + x -= width / 2; + } + return x; +} +function alignY(size, yAlign, paddingAndSize) { + let { y, height } = size; + if (yAlign === "top") { + y += paddingAndSize; + } else if (yAlign === "bottom") { + y -= height + paddingAndSize; + } else { + y -= height / 2; + } + return y; +} +function getBackgroundPoint(options, size, alignment, chart) { + const { caretSize, caretPadding, cornerRadius } = options; + const { xAlign, yAlign } = alignment; + const paddingAndSize = caretSize + caretPadding; + const { topLeft, topRight, bottomLeft, bottomRight } = toTRBLCorners(cornerRadius); + let x = alignX(size, xAlign); + const y = alignY(size, yAlign, paddingAndSize); + if (yAlign === "center") { + if (xAlign === "left") { + x += paddingAndSize; + } else if (xAlign === "right") { + x -= paddingAndSize; + } + } else if (xAlign === "left") { + x -= Math.max(topLeft, bottomLeft) + caretSize; + } else if (xAlign === "right") { + x += Math.max(topRight, bottomRight) + caretSize; + } + return { + x: _limitValue(x, 0, chart.width - size.width), + y: _limitValue(y, 0, chart.height - size.height) + }; +} +function getAlignedX(tooltip, align, options) { + const padding = toPadding(options.padding); + return align === "center" ? tooltip.x + tooltip.width / 2 : align === "right" ? tooltip.x + tooltip.width - padding.right : tooltip.x + padding.left; +} +function getBeforeAfterBodyLines(callback3) { + return pushOrConcat([], splitNewlines(callback3)); +} +function createTooltipContext(parent, tooltip, tooltipItems) { + return createContext(parent, { + tooltip, + tooltipItems, + type: "tooltip" + }); +} +function overrideCallbacks(callbacks, context) { + const override = context && context.dataset && context.dataset.tooltip && context.dataset.tooltip.callbacks; + return override ? callbacks.override(override) : callbacks; +} +var defaultCallbacks = { + beforeTitle: noop, + title(tooltipItems) { + if (tooltipItems.length > 0) { + const item = tooltipItems[0]; + const labels = item.chart.data.labels; + const labelCount = labels ? labels.length : 0; + if (this && this.options && this.options.mode === "dataset") { + return item.dataset.label || ""; + } else if (item.label) { + return item.label; + } else if (labelCount > 0 && item.dataIndex < labelCount) { + return labels[item.dataIndex]; + } + } + return ""; + }, + afterTitle: noop, + beforeBody: noop, + beforeLabel: noop, + label(tooltipItem) { + if (this && this.options && this.options.mode === "dataset") { + return tooltipItem.label + ": " + tooltipItem.formattedValue || tooltipItem.formattedValue; + } + let label = tooltipItem.dataset.label || ""; + if (label) { + label += ": "; + } + const value = tooltipItem.formattedValue; + if (!isNullOrUndef(value)) { + label += value; + } + return label; + }, + labelColor(tooltipItem) { + const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex); + const options = meta.controller.getStyle(tooltipItem.dataIndex); + return { + borderColor: options.borderColor, + backgroundColor: options.backgroundColor, + borderWidth: options.borderWidth, + borderDash: options.borderDash, + borderDashOffset: options.borderDashOffset, + borderRadius: 0 + }; + }, + labelTextColor() { + return this.options.bodyColor; + }, + labelPointStyle(tooltipItem) { + const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex); + const options = meta.controller.getStyle(tooltipItem.dataIndex); + return { + pointStyle: options.pointStyle, + rotation: options.rotation + }; + }, + afterLabel: noop, + afterBody: noop, + beforeFooter: noop, + footer: noop, + afterFooter: noop +}; +function invokeCallbackWithFallback(callbacks, name, ctx, arg) { + const result = callbacks[name].call(ctx, arg); + if (typeof result === "undefined") { + return defaultCallbacks[name].call(ctx, arg); + } + return result; +} +var Tooltip = class extends Element { + constructor(config) { + super(); + this.opacity = 0; + this._active = []; + this._eventPosition = void 0; + this._size = void 0; + this._cachedAnimations = void 0; + this._tooltipItems = []; + this.$animations = void 0; + this.$context = void 0; + this.chart = config.chart; + this.options = config.options; + this.dataPoints = void 0; + this.title = void 0; + this.beforeBody = void 0; + this.body = void 0; + this.afterBody = void 0; + this.footer = void 0; + this.xAlign = void 0; + this.yAlign = void 0; + this.x = void 0; + this.y = void 0; + this.height = void 0; + this.width = void 0; + this.caretX = void 0; + this.caretY = void 0; + this.labelColors = void 0; + this.labelPointStyles = void 0; + this.labelTextColors = void 0; + } + initialize(options) { + this.options = options; + this._cachedAnimations = void 0; + this.$context = void 0; + } + _resolveAnimations() { + const cached = this._cachedAnimations; + if (cached) { + return cached; + } + const chart = this.chart; + const options = this.options.setContext(this.getContext()); + const opts = options.enabled && chart.options.animation && options.animations; + const animations = new Animations(this.chart, opts); + if (opts._cacheable) { + this._cachedAnimations = Object.freeze(animations); + } + return animations; + } + getContext() { + return this.$context || (this.$context = createTooltipContext(this.chart.getContext(), this, this._tooltipItems)); + } + getTitle(context, options) { + const { callbacks } = options; + const beforeTitle = invokeCallbackWithFallback(callbacks, "beforeTitle", this, context); + const title = invokeCallbackWithFallback(callbacks, "title", this, context); + const afterTitle = invokeCallbackWithFallback(callbacks, "afterTitle", this, context); + let lines = []; + lines = pushOrConcat(lines, splitNewlines(beforeTitle)); + lines = pushOrConcat(lines, splitNewlines(title)); + lines = pushOrConcat(lines, splitNewlines(afterTitle)); + return lines; + } + getBeforeBody(tooltipItems, options) { + return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, "beforeBody", this, tooltipItems)); + } + getBody(tooltipItems, options) { + const { callbacks } = options; + const bodyItems = []; + each(tooltipItems, (context) => { + const bodyItem = { + before: [], + lines: [], + after: [] + }; + const scoped = overrideCallbacks(callbacks, context); + pushOrConcat(bodyItem.before, splitNewlines(invokeCallbackWithFallback(scoped, "beforeLabel", this, context))); + pushOrConcat(bodyItem.lines, invokeCallbackWithFallback(scoped, "label", this, context)); + pushOrConcat(bodyItem.after, splitNewlines(invokeCallbackWithFallback(scoped, "afterLabel", this, context))); + bodyItems.push(bodyItem); + }); + return bodyItems; + } + getAfterBody(tooltipItems, options) { + return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks, "afterBody", this, tooltipItems)); + } + getFooter(tooltipItems, options) { + const { callbacks } = options; + const beforeFooter = invokeCallbackWithFallback(callbacks, "beforeFooter", this, tooltipItems); + const footer = invokeCallbackWithFallback(callbacks, "footer", this, tooltipItems); + const afterFooter = invokeCallbackWithFallback(callbacks, "afterFooter", this, tooltipItems); + let lines = []; + lines = pushOrConcat(lines, splitNewlines(beforeFooter)); + lines = pushOrConcat(lines, splitNewlines(footer)); + lines = pushOrConcat(lines, splitNewlines(afterFooter)); + return lines; + } + _createItems(options) { + const active = this._active; + const data = this.chart.data; + const labelColors = []; + const labelPointStyles = []; + const labelTextColors = []; + let tooltipItems = []; + let i, len; + for (i = 0, len = active.length; i < len; ++i) { + tooltipItems.push(createTooltipItem(this.chart, active[i])); + } + if (options.filter) { + tooltipItems = tooltipItems.filter((element, index2, array) => options.filter(element, index2, array, data)); + } + if (options.itemSort) { + tooltipItems = tooltipItems.sort((a, b) => options.itemSort(a, b, data)); + } + each(tooltipItems, (context) => { + const scoped = overrideCallbacks(options.callbacks, context); + labelColors.push(invokeCallbackWithFallback(scoped, "labelColor", this, context)); + labelPointStyles.push(invokeCallbackWithFallback(scoped, "labelPointStyle", this, context)); + labelTextColors.push(invokeCallbackWithFallback(scoped, "labelTextColor", this, context)); + }); + this.labelColors = labelColors; + this.labelPointStyles = labelPointStyles; + this.labelTextColors = labelTextColors; + this.dataPoints = tooltipItems; + return tooltipItems; + } + update(changed, replay) { + const options = this.options.setContext(this.getContext()); + const active = this._active; + let properties; + let tooltipItems = []; + if (!active.length) { + if (this.opacity !== 0) { + properties = { + opacity: 0 + }; + } + } else { + const position = positioners[options.position].call(this, active, this._eventPosition); + tooltipItems = this._createItems(options); + this.title = this.getTitle(tooltipItems, options); + this.beforeBody = this.getBeforeBody(tooltipItems, options); + this.body = this.getBody(tooltipItems, options); + this.afterBody = this.getAfterBody(tooltipItems, options); + this.footer = this.getFooter(tooltipItems, options); + const size = this._size = getTooltipSize(this, options); + const positionAndSize = Object.assign({}, position, size); + const alignment = determineAlignment(this.chart, options, positionAndSize); + const backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this.chart); + this.xAlign = alignment.xAlign; + this.yAlign = alignment.yAlign; + properties = { + opacity: 1, + x: backgroundPoint.x, + y: backgroundPoint.y, + width: size.width, + height: size.height, + caretX: position.x, + caretY: position.y + }; + } + this._tooltipItems = tooltipItems; + this.$context = void 0; + if (properties) { + this._resolveAnimations().update(this, properties); + } + if (changed && options.external) { + options.external.call(this, { + chart: this.chart, + tooltip: this, + replay + }); + } + } + drawCaret(tooltipPoint, ctx, size, options) { + const caretPosition = this.getCaretPosition(tooltipPoint, size, options); + ctx.lineTo(caretPosition.x1, caretPosition.y1); + ctx.lineTo(caretPosition.x2, caretPosition.y2); + ctx.lineTo(caretPosition.x3, caretPosition.y3); + } + getCaretPosition(tooltipPoint, size, options) { + const { xAlign, yAlign } = this; + const { caretSize, cornerRadius } = options; + const { topLeft, topRight, bottomLeft, bottomRight } = toTRBLCorners(cornerRadius); + const { x: ptX, y: ptY } = tooltipPoint; + const { width, height } = size; + let x1, x2, x3, y1, y2, y3; + if (yAlign === "center") { + y2 = ptY + height / 2; + if (xAlign === "left") { + x1 = ptX; + x2 = x1 - caretSize; + y1 = y2 + caretSize; + y3 = y2 - caretSize; + } else { + x1 = ptX + width; + x2 = x1 + caretSize; + y1 = y2 - caretSize; + y3 = y2 + caretSize; + } + x3 = x1; + } else { + if (xAlign === "left") { + x2 = ptX + Math.max(topLeft, bottomLeft) + caretSize; + } else if (xAlign === "right") { + x2 = ptX + width - Math.max(topRight, bottomRight) - caretSize; + } else { + x2 = this.caretX; + } + if (yAlign === "top") { + y1 = ptY; + y2 = y1 - caretSize; + x1 = x2 - caretSize; + x3 = x2 + caretSize; + } else { + y1 = ptY + height; + y2 = y1 + caretSize; + x1 = x2 + caretSize; + x3 = x2 - caretSize; + } + y3 = y1; + } + return { + x1, + x2, + x3, + y1, + y2, + y3 + }; + } + drawTitle(pt, ctx, options) { + const title = this.title; + const length = title.length; + let titleFont, titleSpacing, i; + if (length) { + const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width); + pt.x = getAlignedX(this, options.titleAlign, options); + ctx.textAlign = rtlHelper.textAlign(options.titleAlign); + ctx.textBaseline = "middle"; + titleFont = toFont(options.titleFont); + titleSpacing = options.titleSpacing; + ctx.fillStyle = options.titleColor; + ctx.font = titleFont.string; + for (i = 0; i < length; ++i) { + ctx.fillText(title[i], rtlHelper.x(pt.x), pt.y + titleFont.lineHeight / 2); + pt.y += titleFont.lineHeight + titleSpacing; + if (i + 1 === length) { + pt.y += options.titleMarginBottom - titleSpacing; + } + } + } + } + _drawColorBox(ctx, pt, i, rtlHelper, options) { + const labelColor = this.labelColors[i]; + const labelPointStyle = this.labelPointStyles[i]; + const { boxHeight, boxWidth } = options; + const bodyFont = toFont(options.bodyFont); + const colorX = getAlignedX(this, "left", options); + const rtlColorX = rtlHelper.x(colorX); + const yOffSet = boxHeight < bodyFont.lineHeight ? (bodyFont.lineHeight - boxHeight) / 2 : 0; + const colorY = pt.y + yOffSet; + if (options.usePointStyle) { + const drawOptions = { + radius: Math.min(boxWidth, boxHeight) / 2, + pointStyle: labelPointStyle.pointStyle, + rotation: labelPointStyle.rotation, + borderWidth: 1 + }; + const centerX = rtlHelper.leftForLtr(rtlColorX, boxWidth) + boxWidth / 2; + const centerY = colorY + boxHeight / 2; + ctx.strokeStyle = options.multiKeyBackground; + ctx.fillStyle = options.multiKeyBackground; + drawPoint(ctx, drawOptions, centerX, centerY); + ctx.strokeStyle = labelColor.borderColor; + ctx.fillStyle = labelColor.backgroundColor; + drawPoint(ctx, drawOptions, centerX, centerY); + } else { + ctx.lineWidth = isObject(labelColor.borderWidth) ? Math.max(...Object.values(labelColor.borderWidth)) : labelColor.borderWidth || 1; + ctx.strokeStyle = labelColor.borderColor; + ctx.setLineDash(labelColor.borderDash || []); + ctx.lineDashOffset = labelColor.borderDashOffset || 0; + const outerX = rtlHelper.leftForLtr(rtlColorX, boxWidth); + const innerX = rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - 2); + const borderRadius = toTRBLCorners(labelColor.borderRadius); + if (Object.values(borderRadius).some((v) => v !== 0)) { + ctx.beginPath(); + ctx.fillStyle = options.multiKeyBackground; + addRoundedRectPath(ctx, { + x: outerX, + y: colorY, + w: boxWidth, + h: boxHeight, + radius: borderRadius + }); + ctx.fill(); + ctx.stroke(); + ctx.fillStyle = labelColor.backgroundColor; + ctx.beginPath(); + addRoundedRectPath(ctx, { + x: innerX, + y: colorY + 1, + w: boxWidth - 2, + h: boxHeight - 2, + radius: borderRadius + }); + ctx.fill(); + } else { + ctx.fillStyle = options.multiKeyBackground; + ctx.fillRect(outerX, colorY, boxWidth, boxHeight); + ctx.strokeRect(outerX, colorY, boxWidth, boxHeight); + ctx.fillStyle = labelColor.backgroundColor; + ctx.fillRect(innerX, colorY + 1, boxWidth - 2, boxHeight - 2); + } + } + ctx.fillStyle = this.labelTextColors[i]; + } + drawBody(pt, ctx, options) { + const { body } = this; + const { bodySpacing, bodyAlign, displayColors, boxHeight, boxWidth, boxPadding } = options; + const bodyFont = toFont(options.bodyFont); + let bodyLineHeight = bodyFont.lineHeight; + let xLinePadding = 0; + const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width); + const fillLineOfText = function(line) { + ctx.fillText(line, rtlHelper.x(pt.x + xLinePadding), pt.y + bodyLineHeight / 2); + pt.y += bodyLineHeight + bodySpacing; + }; + const bodyAlignForCalculation = rtlHelper.textAlign(bodyAlign); + let bodyItem, textColor, lines, i, j, ilen, jlen; + ctx.textAlign = bodyAlign; + ctx.textBaseline = "middle"; + ctx.font = bodyFont.string; + pt.x = getAlignedX(this, bodyAlignForCalculation, options); + ctx.fillStyle = options.bodyColor; + each(this.beforeBody, fillLineOfText); + xLinePadding = displayColors && bodyAlignForCalculation !== "right" ? bodyAlign === "center" ? boxWidth / 2 + boxPadding : boxWidth + 2 + boxPadding : 0; + for (i = 0, ilen = body.length; i < ilen; ++i) { + bodyItem = body[i]; + textColor = this.labelTextColors[i]; + ctx.fillStyle = textColor; + each(bodyItem.before, fillLineOfText); + lines = bodyItem.lines; + if (displayColors && lines.length) { + this._drawColorBox(ctx, pt, i, rtlHelper, options); + bodyLineHeight = Math.max(bodyFont.lineHeight, boxHeight); + } + for (j = 0, jlen = lines.length; j < jlen; ++j) { + fillLineOfText(lines[j]); + bodyLineHeight = bodyFont.lineHeight; + } + each(bodyItem.after, fillLineOfText); + } + xLinePadding = 0; + bodyLineHeight = bodyFont.lineHeight; + each(this.afterBody, fillLineOfText); + pt.y -= bodySpacing; + } + drawFooter(pt, ctx, options) { + const footer = this.footer; + const length = footer.length; + let footerFont, i; + if (length) { + const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width); + pt.x = getAlignedX(this, options.footerAlign, options); + pt.y += options.footerMarginTop; + ctx.textAlign = rtlHelper.textAlign(options.footerAlign); + ctx.textBaseline = "middle"; + footerFont = toFont(options.footerFont); + ctx.fillStyle = options.footerColor; + ctx.font = footerFont.string; + for (i = 0; i < length; ++i) { + ctx.fillText(footer[i], rtlHelper.x(pt.x), pt.y + footerFont.lineHeight / 2); + pt.y += footerFont.lineHeight + options.footerSpacing; + } + } + } + drawBackground(pt, ctx, tooltipSize, options) { + const { xAlign, yAlign } = this; + const { x, y } = pt; + const { width, height } = tooltipSize; + const { topLeft, topRight, bottomLeft, bottomRight } = toTRBLCorners(options.cornerRadius); + ctx.fillStyle = options.backgroundColor; + ctx.strokeStyle = options.borderColor; + ctx.lineWidth = options.borderWidth; + ctx.beginPath(); + ctx.moveTo(x + topLeft, y); + if (yAlign === "top") { + this.drawCaret(pt, ctx, tooltipSize, options); + } + ctx.lineTo(x + width - topRight, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + topRight); + if (yAlign === "center" && xAlign === "right") { + this.drawCaret(pt, ctx, tooltipSize, options); + } + ctx.lineTo(x + width, y + height - bottomRight); + ctx.quadraticCurveTo(x + width, y + height, x + width - bottomRight, y + height); + if (yAlign === "bottom") { + this.drawCaret(pt, ctx, tooltipSize, options); + } + ctx.lineTo(x + bottomLeft, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - bottomLeft); + if (yAlign === "center" && xAlign === "left") { + this.drawCaret(pt, ctx, tooltipSize, options); + } + ctx.lineTo(x, y + topLeft); + ctx.quadraticCurveTo(x, y, x + topLeft, y); + ctx.closePath(); + ctx.fill(); + if (options.borderWidth > 0) { + ctx.stroke(); + } + } + _updateAnimationTarget(options) { + const chart = this.chart; + const anims = this.$animations; + const animX = anims && anims.x; + const animY = anims && anims.y; + if (animX || animY) { + const position = positioners[options.position].call(this, this._active, this._eventPosition); + if (!position) { + return; + } + const size = this._size = getTooltipSize(this, options); + const positionAndSize = Object.assign({}, position, this._size); + const alignment = determineAlignment(chart, options, positionAndSize); + const point = getBackgroundPoint(options, positionAndSize, alignment, chart); + if (animX._to !== point.x || animY._to !== point.y) { + this.xAlign = alignment.xAlign; + this.yAlign = alignment.yAlign; + this.width = size.width; + this.height = size.height; + this.caretX = position.x; + this.caretY = position.y; + this._resolveAnimations().update(this, point); + } + } + } + _willRender() { + return !!this.opacity; + } + draw(ctx) { + const options = this.options.setContext(this.getContext()); + let opacity = this.opacity; + if (!opacity) { + return; + } + this._updateAnimationTarget(options); + const tooltipSize = { + width: this.width, + height: this.height + }; + const pt = { + x: this.x, + y: this.y + }; + opacity = Math.abs(opacity) < 1e-3 ? 0 : opacity; + const padding = toPadding(options.padding); + const hasTooltipContent = this.title.length || this.beforeBody.length || this.body.length || this.afterBody.length || this.footer.length; + if (options.enabled && hasTooltipContent) { + ctx.save(); + ctx.globalAlpha = opacity; + this.drawBackground(pt, ctx, tooltipSize, options); + overrideTextDirection(ctx, options.textDirection); + pt.y += padding.top; + this.drawTitle(pt, ctx, options); + this.drawBody(pt, ctx, options); + this.drawFooter(pt, ctx, options); + restoreTextDirection(ctx, options.textDirection); + ctx.restore(); + } + } + getActiveElements() { + return this._active || []; + } + setActiveElements(activeElements, eventPosition) { + const lastActive = this._active; + const active = activeElements.map(({ datasetIndex, index: index2 }) => { + const meta = this.chart.getDatasetMeta(datasetIndex); + if (!meta) { + throw new Error("Cannot find a dataset at index " + datasetIndex); + } + return { + datasetIndex, + element: meta.data[index2], + index: index2 + }; + }); + const changed = !_elementsEqual(lastActive, active); + const positionChanged = this._positionChanged(active, eventPosition); + if (changed || positionChanged) { + this._active = active; + this._eventPosition = eventPosition; + this._ignoreReplayEvents = true; + this.update(true); + } + } + handleEvent(e, replay, inChartArea = true) { + if (replay && this._ignoreReplayEvents) { + return false; + } + this._ignoreReplayEvents = false; + const options = this.options; + const lastActive = this._active || []; + const active = this._getActiveElements(e, lastActive, replay, inChartArea); + const positionChanged = this._positionChanged(active, e); + const changed = replay || !_elementsEqual(active, lastActive) || positionChanged; + if (changed) { + this._active = active; + if (options.enabled || options.external) { + this._eventPosition = { + x: e.x, + y: e.y + }; + this.update(true, replay); + } + } + return changed; + } + _getActiveElements(e, lastActive, replay, inChartArea) { + const options = this.options; + if (e.type === "mouseout") { + return []; + } + if (!inChartArea) { + return lastActive.filter((i) => this.chart.data.datasets[i.datasetIndex] && this.chart.getDatasetMeta(i.datasetIndex).controller.getParsed(i.index) !== void 0); + } + const active = this.chart.getElementsAtEventForMode(e, options.mode, options, replay); + if (options.reverse) { + active.reverse(); + } + return active; + } + _positionChanged(active, e) { + const { caretX, caretY, options } = this; + const position = positioners[options.position].call(this, active, e); + return position !== false && (caretX !== position.x || caretY !== position.y); + } +}; +__publicField(Tooltip, "positioners", positioners); +var plugin_tooltip = { + id: "tooltip", + _element: Tooltip, + positioners, + afterInit(chart, _args, options) { + if (options) { + chart.tooltip = new Tooltip({ + chart, + options + }); + } + }, + beforeUpdate(chart, _args, options) { + if (chart.tooltip) { + chart.tooltip.initialize(options); + } + }, + reset(chart, _args, options) { + if (chart.tooltip) { + chart.tooltip.initialize(options); + } + }, + afterDraw(chart) { + const tooltip = chart.tooltip; + if (tooltip && tooltip._willRender()) { + const args = { + tooltip + }; + if (chart.notifyPlugins("beforeTooltipDraw", { + ...args, + cancelable: true + }) === false) { + return; + } + tooltip.draw(chart.ctx); + chart.notifyPlugins("afterTooltipDraw", args); + } + }, + afterEvent(chart, args) { + if (chart.tooltip) { + const useFinalPosition = args.replay; + if (chart.tooltip.handleEvent(args.event, useFinalPosition, args.inChartArea)) { + args.changed = true; + } + } + }, + defaults: { + enabled: true, + external: null, + position: "average", + backgroundColor: "rgba(0,0,0,0.8)", + titleColor: "#fff", + titleFont: { + weight: "bold" + }, + titleSpacing: 2, + titleMarginBottom: 6, + titleAlign: "left", + bodyColor: "#fff", + bodySpacing: 2, + bodyFont: {}, + bodyAlign: "left", + footerColor: "#fff", + footerSpacing: 2, + footerMarginTop: 6, + footerFont: { + weight: "bold" + }, + footerAlign: "left", + padding: 6, + caretPadding: 2, + caretSize: 5, + cornerRadius: 6, + boxHeight: (ctx, opts) => opts.bodyFont.size, + boxWidth: (ctx, opts) => opts.bodyFont.size, + multiKeyBackground: "#fff", + displayColors: true, + boxPadding: 0, + borderColor: "rgba(0,0,0,0)", + borderWidth: 0, + animation: { + duration: 400, + easing: "easeOutQuart" + }, + animations: { + numbers: { + type: "number", + properties: [ + "x", + "y", + "width", + "height", + "caretX", + "caretY" + ] + }, + opacity: { + easing: "linear", + duration: 200 + } + }, + callbacks: defaultCallbacks + }, + defaultRoutes: { + bodyFont: "font", + footerFont: "font", + titleFont: "font" + }, + descriptors: { + _scriptable: (name) => name !== "filter" && name !== "itemSort" && name !== "external", + _indexable: false, + callbacks: { + _scriptable: false, + _indexable: false + }, + animation: { + _fallback: false + }, + animations: { + _fallback: "animation" + } + }, + additionalOptionScopes: [ + "interaction" + ] +}; +var plugins = /* @__PURE__ */ Object.freeze({ + __proto__: null, + Colors: plugin_colors, + Decimation: plugin_decimation, + Filler: index, + Legend: plugin_legend, + SubTitle: plugin_subtitle, + Title: plugin_title, + Tooltip: plugin_tooltip +}); +var addIfString = (labels, raw, index2, addedLabels) => { + if (typeof raw === "string") { + index2 = labels.push(raw) - 1; + addedLabels.unshift({ + index: index2, + label: raw + }); + } else if (isNaN(raw)) { + index2 = null; + } + return index2; +}; +function findOrAddLabel(labels, raw, index2, addedLabels) { + const first = labels.indexOf(raw); + if (first === -1) { + return addIfString(labels, raw, index2, addedLabels); + } + const last = labels.lastIndexOf(raw); + return first !== last ? index2 : first; +} +var validIndex = (index2, max) => index2 === null ? null : _limitValue(Math.round(index2), 0, max); +function _getLabelForValue(value) { + const labels = this.getLabels(); + if (value >= 0 && value < labels.length) { + return labels[value]; + } + return value; +} +var CategoryScale = class extends Scale { + constructor(cfg) { + super(cfg); + this._startValue = void 0; + this._valueRange = 0; + this._addedLabels = []; + } + init(scaleOptions) { + const added = this._addedLabels; + if (added.length) { + const labels = this.getLabels(); + for (const { index: index2, label } of added) { + if (labels[index2] === label) { + labels.splice(index2, 1); + } + } + this._addedLabels = []; + } + super.init(scaleOptions); + } + parse(raw, index2) { + if (isNullOrUndef(raw)) { + return null; + } + const labels = this.getLabels(); + index2 = isFinite(index2) && labels[index2] === raw ? index2 : findOrAddLabel(labels, raw, valueOrDefault(index2, raw), this._addedLabels); + return validIndex(index2, labels.length - 1); + } + determineDataLimits() { + const { minDefined, maxDefined } = this.getUserBounds(); + let { min, max } = this.getMinMax(true); + if (this.options.bounds === "ticks") { + if (!minDefined) { + min = 0; + } + if (!maxDefined) { + max = this.getLabels().length - 1; + } + } + this.min = min; + this.max = max; + } + buildTicks() { + const min = this.min; + const max = this.max; + const offset2 = this.options.offset; + const ticks = []; + let labels = this.getLabels(); + labels = min === 0 && max === labels.length - 1 ? labels : labels.slice(min, max + 1); + this._valueRange = Math.max(labels.length - (offset2 ? 0 : 1), 1); + this._startValue = this.min - (offset2 ? 0.5 : 0); + for (let value = min; value <= max; value++) { + ticks.push({ + value + }); + } + return ticks; + } + getLabelForValue(value) { + return _getLabelForValue.call(this, value); + } + configure() { + super.configure(); + if (!this.isHorizontal()) { + this._reversePixels = !this._reversePixels; + } + } + getPixelForValue(value) { + if (typeof value !== "number") { + value = this.parse(value); + } + return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange); + } + getPixelForTick(index2) { + const ticks = this.ticks; + if (index2 < 0 || index2 > ticks.length - 1) { + return null; + } + return this.getPixelForValue(ticks[index2].value); + } + getValueForPixel(pixel) { + return Math.round(this._startValue + this.getDecimalForPixel(pixel) * this._valueRange); + } + getBasePixel() { + return this.bottom; + } +}; +__publicField(CategoryScale, "id", "category"); +__publicField(CategoryScale, "defaults", { + ticks: { + callback: _getLabelForValue + } +}); +function generateTicks$1(generationOptions, dataRange) { + const ticks = []; + const MIN_SPACING = 1e-14; + const { bounds, step, min, max, precision, count, maxTicks, maxDigits, includeBounds } = generationOptions; + const unit = step || 1; + const maxSpaces = maxTicks - 1; + const { min: rmin, max: rmax } = dataRange; + const minDefined = !isNullOrUndef(min); + const maxDefined = !isNullOrUndef(max); + const countDefined = !isNullOrUndef(count); + const minSpacing = (rmax - rmin) / (maxDigits + 1); + let spacing = niceNum((rmax - rmin) / maxSpaces / unit) * unit; + let factor, niceMin, niceMax, numSpaces; + if (spacing < MIN_SPACING && !minDefined && !maxDefined) { + return [ + { + value: rmin + }, + { + value: rmax + } + ]; + } + numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing); + if (numSpaces > maxSpaces) { + spacing = niceNum(numSpaces * spacing / maxSpaces / unit) * unit; + } + if (!isNullOrUndef(precision)) { + factor = Math.pow(10, precision); + spacing = Math.ceil(spacing * factor) / factor; + } + if (bounds === "ticks") { + niceMin = Math.floor(rmin / spacing) * spacing; + niceMax = Math.ceil(rmax / spacing) * spacing; + } else { + niceMin = rmin; + niceMax = rmax; + } + if (minDefined && maxDefined && step && almostWhole((max - min) / step, spacing / 1e3)) { + numSpaces = Math.round(Math.min((max - min) / spacing, maxTicks)); + spacing = (max - min) / numSpaces; + niceMin = min; + niceMax = max; + } else if (countDefined) { + niceMin = minDefined ? min : niceMin; + niceMax = maxDefined ? max : niceMax; + numSpaces = count - 1; + spacing = (niceMax - niceMin) / numSpaces; + } else { + numSpaces = (niceMax - niceMin) / spacing; + if (almostEquals(numSpaces, Math.round(numSpaces), spacing / 1e3)) { + numSpaces = Math.round(numSpaces); + } else { + numSpaces = Math.ceil(numSpaces); + } + } + const decimalPlaces = Math.max(_decimalPlaces(spacing), _decimalPlaces(niceMin)); + factor = Math.pow(10, isNullOrUndef(precision) ? decimalPlaces : precision); + niceMin = Math.round(niceMin * factor) / factor; + niceMax = Math.round(niceMax * factor) / factor; + let j = 0; + if (minDefined) { + if (includeBounds && niceMin !== min) { + ticks.push({ + value: min + }); + if (niceMin < min) { + j++; + } + if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, relativeLabelSize(min, minSpacing, generationOptions))) { + j++; + } + } else if (niceMin < min) { + j++; + } + } + for (; j < numSpaces; ++j) { + const tickValue = Math.round((niceMin + j * spacing) * factor) / factor; + if (maxDefined && tickValue > max) { + break; + } + ticks.push({ + value: tickValue + }); + } + if (maxDefined && includeBounds && niceMax !== max) { + if (ticks.length && almostEquals(ticks[ticks.length - 1].value, max, relativeLabelSize(max, minSpacing, generationOptions))) { + ticks[ticks.length - 1].value = max; + } else { + ticks.push({ + value: max + }); + } + } else if (!maxDefined || niceMax === max) { + ticks.push({ + value: niceMax + }); + } + return ticks; +} +function relativeLabelSize(value, minSpacing, { horizontal, minRotation }) { + const rad = toRadians(minRotation); + const ratio = (horizontal ? Math.sin(rad) : Math.cos(rad)) || 1e-3; + const length = 0.75 * minSpacing * ("" + value).length; + return Math.min(minSpacing / ratio, length); +} +var LinearScaleBase = class extends Scale { + constructor(cfg) { + super(cfg); + this.start = void 0; + this.end = void 0; + this._startValue = void 0; + this._endValue = void 0; + this._valueRange = 0; + } + parse(raw, index2) { + if (isNullOrUndef(raw)) { + return null; + } + if ((typeof raw === "number" || raw instanceof Number) && !isFinite(+raw)) { + return null; + } + return +raw; + } + handleTickRangeOptions() { + const { beginAtZero } = this.options; + const { minDefined, maxDefined } = this.getUserBounds(); + let { min, max } = this; + const setMin = (v) => min = minDefined ? min : v; + const setMax = (v) => max = maxDefined ? max : v; + if (beginAtZero) { + const minSign = sign(min); + const maxSign = sign(max); + if (minSign < 0 && maxSign < 0) { + setMax(0); + } else if (minSign > 0 && maxSign > 0) { + setMin(0); + } + } + if (min === max) { + let offset2 = max === 0 ? 1 : Math.abs(max * 0.05); + setMax(max + offset2); + if (!beginAtZero) { + setMin(min - offset2); + } + } + this.min = min; + this.max = max; + } + getTickLimit() { + const tickOpts = this.options.ticks; + let { maxTicksLimit, stepSize } = tickOpts; + let maxTicks; + if (stepSize) { + maxTicks = Math.ceil(this.max / stepSize) - Math.floor(this.min / stepSize) + 1; + if (maxTicks > 1e3) { + console.warn(`scales.${this.id}.ticks.stepSize: ${stepSize} would result generating up to ${maxTicks} ticks. Limiting to 1000.`); + maxTicks = 1e3; + } + } else { + maxTicks = this.computeTickLimit(); + maxTicksLimit = maxTicksLimit || 11; + } + if (maxTicksLimit) { + maxTicks = Math.min(maxTicksLimit, maxTicks); + } + return maxTicks; + } + computeTickLimit() { + return Number.POSITIVE_INFINITY; + } + buildTicks() { + const opts = this.options; + const tickOpts = opts.ticks; + let maxTicks = this.getTickLimit(); + maxTicks = Math.max(2, maxTicks); + const numericGeneratorOptions = { + maxTicks, + bounds: opts.bounds, + min: opts.min, + max: opts.max, + precision: tickOpts.precision, + step: tickOpts.stepSize, + count: tickOpts.count, + maxDigits: this._maxDigits(), + horizontal: this.isHorizontal(), + minRotation: tickOpts.minRotation || 0, + includeBounds: tickOpts.includeBounds !== false + }; + const dataRange = this._range || this; + const ticks = generateTicks$1(numericGeneratorOptions, dataRange); + if (opts.bounds === "ticks") { + _setMinAndMaxByKey(ticks, this, "value"); + } + if (opts.reverse) { + ticks.reverse(); + this.start = this.max; + this.end = this.min; + } else { + this.start = this.min; + this.end = this.max; + } + return ticks; + } + configure() { + const ticks = this.ticks; + let start = this.min; + let end = this.max; + super.configure(); + if (this.options.offset && ticks.length) { + const offset2 = (end - start) / Math.max(ticks.length - 1, 1) / 2; + start -= offset2; + end += offset2; + } + this._startValue = start; + this._endValue = end; + this._valueRange = end - start; + } + getLabelForValue(value) { + return formatNumber(value, this.chart.options.locale, this.options.ticks.format); + } +}; +var LinearScale = class extends LinearScaleBase { + determineDataLimits() { + const { min, max } = this.getMinMax(true); + this.min = isNumberFinite(min) ? min : 0; + this.max = isNumberFinite(max) ? max : 1; + this.handleTickRangeOptions(); + } + computeTickLimit() { + const horizontal = this.isHorizontal(); + const length = horizontal ? this.width : this.height; + const minRotation = toRadians(this.options.ticks.minRotation); + const ratio = (horizontal ? Math.sin(minRotation) : Math.cos(minRotation)) || 1e-3; + const tickFont = this._resolveTickFontOptions(0); + return Math.ceil(length / Math.min(40, tickFont.lineHeight / ratio)); + } + getPixelForValue(value) { + return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange); + } + getValueForPixel(pixel) { + return this._startValue + this.getDecimalForPixel(pixel) * this._valueRange; + } +}; +__publicField(LinearScale, "id", "linear"); +__publicField(LinearScale, "defaults", { + ticks: { + callback: Ticks.formatters.numeric + } +}); +var log10Floor = (v) => Math.floor(log10(v)); +var changeExponent = (v, m) => Math.pow(10, log10Floor(v) + m); +function isMajor(tickVal) { + const remain = tickVal / Math.pow(10, log10Floor(tickVal)); + return remain === 1; +} +function steps(min, max, rangeExp) { + const rangeStep = Math.pow(10, rangeExp); + const start = Math.floor(min / rangeStep); + const end = Math.ceil(max / rangeStep); + return end - start; +} +function startExp(min, max) { + const range = max - min; + let rangeExp = log10Floor(range); + while (steps(min, max, rangeExp) > 10) { + rangeExp++; + } + while (steps(min, max, rangeExp) < 10) { + rangeExp--; + } + return Math.min(rangeExp, log10Floor(min)); +} +function generateTicks(generationOptions, { min, max }) { + min = finiteOrDefault(generationOptions.min, min); + const ticks = []; + const minExp = log10Floor(min); + let exp = startExp(min, max); + let precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1; + const stepSize = Math.pow(10, exp); + const base = minExp > exp ? Math.pow(10, minExp) : 0; + const start = Math.round((min - base) * precision) / precision; + const offset2 = Math.floor((min - base) / stepSize / 10) * stepSize * 10; + let significand = Math.floor((start - offset2) / Math.pow(10, exp)); + let value = finiteOrDefault(generationOptions.min, Math.round((base + offset2 + significand * Math.pow(10, exp)) * precision) / precision); + while (value < max) { + ticks.push({ + value, + major: isMajor(value), + significand + }); + if (significand >= 10) { + significand = significand < 15 ? 15 : 20; + } else { + significand++; + } + if (significand >= 20) { + exp++; + significand = 2; + precision = exp >= 0 ? 1 : precision; + } + value = Math.round((base + offset2 + significand * Math.pow(10, exp)) * precision) / precision; + } + const lastTick = finiteOrDefault(generationOptions.max, value); + ticks.push({ + value: lastTick, + major: isMajor(lastTick), + significand + }); + return ticks; +} +var LogarithmicScale = class extends Scale { + constructor(cfg) { + super(cfg); + this.start = void 0; + this.end = void 0; + this._startValue = void 0; + this._valueRange = 0; + } + parse(raw, index2) { + const value = LinearScaleBase.prototype.parse.apply(this, [ + raw, + index2 + ]); + if (value === 0) { + this._zero = true; + return void 0; + } + return isNumberFinite(value) && value > 0 ? value : null; + } + determineDataLimits() { + const { min, max } = this.getMinMax(true); + this.min = isNumberFinite(min) ? Math.max(0, min) : null; + this.max = isNumberFinite(max) ? Math.max(0, max) : null; + if (this.options.beginAtZero) { + this._zero = true; + } + if (this._zero && this.min !== this._suggestedMin && !isNumberFinite(this._userMin)) { + this.min = min === changeExponent(this.min, 0) ? changeExponent(this.min, -1) : changeExponent(this.min, 0); + } + this.handleTickRangeOptions(); + } + handleTickRangeOptions() { + const { minDefined, maxDefined } = this.getUserBounds(); + let min = this.min; + let max = this.max; + const setMin = (v) => min = minDefined ? min : v; + const setMax = (v) => max = maxDefined ? max : v; + if (min === max) { + if (min <= 0) { + setMin(1); + setMax(10); + } else { + setMin(changeExponent(min, -1)); + setMax(changeExponent(max, 1)); + } + } + if (min <= 0) { + setMin(changeExponent(max, -1)); + } + if (max <= 0) { + setMax(changeExponent(min, 1)); + } + this.min = min; + this.max = max; + } + buildTicks() { + const opts = this.options; + const generationOptions = { + min: this._userMin, + max: this._userMax + }; + const ticks = generateTicks(generationOptions, this); + if (opts.bounds === "ticks") { + _setMinAndMaxByKey(ticks, this, "value"); + } + if (opts.reverse) { + ticks.reverse(); + this.start = this.max; + this.end = this.min; + } else { + this.start = this.min; + this.end = this.max; + } + return ticks; + } + getLabelForValue(value) { + return value === void 0 ? "0" : formatNumber(value, this.chart.options.locale, this.options.ticks.format); + } + configure() { + const start = this.min; + super.configure(); + this._startValue = log10(start); + this._valueRange = log10(this.max) - log10(start); + } + getPixelForValue(value) { + if (value === void 0 || value === 0) { + value = this.min; + } + if (value === null || isNaN(value)) { + return NaN; + } + return this.getPixelForDecimal(value === this.min ? 0 : (log10(value) - this._startValue) / this._valueRange); + } + getValueForPixel(pixel) { + const decimal = this.getDecimalForPixel(pixel); + return Math.pow(10, this._startValue + decimal * this._valueRange); + } +}; +__publicField(LogarithmicScale, "id", "logarithmic"); +__publicField(LogarithmicScale, "defaults", { + ticks: { + callback: Ticks.formatters.logarithmic, + major: { + enabled: true + } + } +}); +function getTickBackdropHeight(opts) { + const tickOpts = opts.ticks; + if (tickOpts.display && opts.display) { + const padding = toPadding(tickOpts.backdropPadding); + return valueOrDefault(tickOpts.font && tickOpts.font.size, defaults.font.size) + padding.height; + } + return 0; +} +function measureLabelSize(ctx, font, label) { + label = isArray(label) ? label : [ + label + ]; + return { + w: _longestText(ctx, font.string, label), + h: label.length * font.lineHeight + }; +} +function determineLimits(angle, pos, size, min, max) { + if (angle === min || angle === max) { + return { + start: pos - size / 2, + end: pos + size / 2 + }; + } else if (angle < min || angle > max) { + return { + start: pos - size, + end: pos + }; + } + return { + start: pos, + end: pos + size + }; +} +function fitWithPointLabels(scale) { + const orig = { + l: scale.left + scale._padding.left, + r: scale.right - scale._padding.right, + t: scale.top + scale._padding.top, + b: scale.bottom - scale._padding.bottom + }; + const limits = Object.assign({}, orig); + const labelSizes = []; + const padding = []; + const valueCount = scale._pointLabels.length; + const pointLabelOpts = scale.options.pointLabels; + const additionalAngle = pointLabelOpts.centerPointLabels ? PI / valueCount : 0; + for (let i = 0; i < valueCount; i++) { + const opts = pointLabelOpts.setContext(scale.getPointLabelContext(i)); + padding[i] = opts.padding; + const pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle); + const plFont = toFont(opts.font); + const textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]); + labelSizes[i] = textSize; + const angleRadians = _normalizeAngle(scale.getIndexAngle(i) + additionalAngle); + const angle = Math.round(toDegrees(angleRadians)); + const hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180); + const vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270); + updateLimits(limits, orig, angleRadians, hLimits, vLimits); + } + scale.setCenterPoint(orig.l - limits.l, limits.r - orig.r, orig.t - limits.t, limits.b - orig.b); + scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding); +} +function updateLimits(limits, orig, angle, hLimits, vLimits) { + const sin = Math.abs(Math.sin(angle)); + const cos = Math.abs(Math.cos(angle)); + let x = 0; + let y = 0; + if (hLimits.start < orig.l) { + x = (orig.l - hLimits.start) / sin; + limits.l = Math.min(limits.l, orig.l - x); + } else if (hLimits.end > orig.r) { + x = (hLimits.end - orig.r) / sin; + limits.r = Math.max(limits.r, orig.r + x); + } + if (vLimits.start < orig.t) { + y = (orig.t - vLimits.start) / cos; + limits.t = Math.min(limits.t, orig.t - y); + } else if (vLimits.end > orig.b) { + y = (vLimits.end - orig.b) / cos; + limits.b = Math.max(limits.b, orig.b + y); + } +} +function createPointLabelItem(scale, index2, itemOpts) { + const outerDistance = scale.drawingArea; + const { extra, additionalAngle, padding, size } = itemOpts; + const pointLabelPosition = scale.getPointPosition(index2, outerDistance + extra + padding, additionalAngle); + const angle = Math.round(toDegrees(_normalizeAngle(pointLabelPosition.angle + HALF_PI))); + const y = yForAngle(pointLabelPosition.y, size.h, angle); + const textAlign = getTextAlignForAngle(angle); + const left = leftForTextAlign(pointLabelPosition.x, size.w, textAlign); + return { + visible: true, + x: pointLabelPosition.x, + y, + textAlign, + left, + top: y, + right: left + size.w, + bottom: y + size.h + }; +} +function isNotOverlapped(item, area) { + if (!area) { + return true; + } + const { left, top, right, bottom } = item; + const apexesInArea = _isPointInArea({ + x: left, + y: top + }, area) || _isPointInArea({ + x: left, + y: bottom + }, area) || _isPointInArea({ + x: right, + y: top + }, area) || _isPointInArea({ + x: right, + y: bottom + }, area); + return !apexesInArea; +} +function buildPointLabelItems(scale, labelSizes, padding) { + const items = []; + const valueCount = scale._pointLabels.length; + const opts = scale.options; + const { centerPointLabels, display } = opts.pointLabels; + const itemOpts = { + extra: getTickBackdropHeight(opts) / 2, + additionalAngle: centerPointLabels ? PI / valueCount : 0 + }; + let area; + for (let i = 0; i < valueCount; i++) { + itemOpts.padding = padding[i]; + itemOpts.size = labelSizes[i]; + const item = createPointLabelItem(scale, i, itemOpts); + items.push(item); + if (display === "auto") { + item.visible = isNotOverlapped(item, area); + if (item.visible) { + area = item; + } + } + } + return items; +} +function getTextAlignForAngle(angle) { + if (angle === 0 || angle === 180) { + return "center"; + } else if (angle < 180) { + return "left"; + } + return "right"; +} +function leftForTextAlign(x, w, align) { + if (align === "right") { + x -= w; + } else if (align === "center") { + x -= w / 2; + } + return x; +} +function yForAngle(y, h, angle) { + if (angle === 90 || angle === 270) { + y -= h / 2; + } else if (angle > 270 || angle < 90) { + y -= h; + } + return y; +} +function drawPointLabelBox(ctx, opts, item) { + const { left, top, right, bottom } = item; + const { backdropColor } = opts; + if (!isNullOrUndef(backdropColor)) { + const borderRadius = toTRBLCorners(opts.borderRadius); + const padding = toPadding(opts.backdropPadding); + ctx.fillStyle = backdropColor; + const backdropLeft = left - padding.left; + const backdropTop = top - padding.top; + const backdropWidth = right - left + padding.width; + const backdropHeight = bottom - top + padding.height; + if (Object.values(borderRadius).some((v) => v !== 0)) { + ctx.beginPath(); + addRoundedRectPath(ctx, { + x: backdropLeft, + y: backdropTop, + w: backdropWidth, + h: backdropHeight, + radius: borderRadius + }); + ctx.fill(); + } else { + ctx.fillRect(backdropLeft, backdropTop, backdropWidth, backdropHeight); + } + } +} +function drawPointLabels(scale, labelCount) { + const { ctx, options: { pointLabels } } = scale; + for (let i = labelCount - 1; i >= 0; i--) { + const item = scale._pointLabelItems[i]; + if (!item.visible) { + continue; + } + const optsAtIndex = pointLabels.setContext(scale.getPointLabelContext(i)); + drawPointLabelBox(ctx, optsAtIndex, item); + const plFont = toFont(optsAtIndex.font); + const { x, y, textAlign } = item; + renderText(ctx, scale._pointLabels[i], x, y + plFont.lineHeight / 2, plFont, { + color: optsAtIndex.color, + textAlign, + textBaseline: "middle" + }); + } +} +function pathRadiusLine(scale, radius, circular, labelCount) { + const { ctx } = scale; + if (circular) { + ctx.arc(scale.xCenter, scale.yCenter, radius, 0, TAU); + } else { + let pointPosition = scale.getPointPosition(0, radius); + ctx.moveTo(pointPosition.x, pointPosition.y); + for (let i = 1; i < labelCount; i++) { + pointPosition = scale.getPointPosition(i, radius); + ctx.lineTo(pointPosition.x, pointPosition.y); + } + } +} +function drawRadiusLine(scale, gridLineOpts, radius, labelCount, borderOpts) { + const ctx = scale.ctx; + const circular = gridLineOpts.circular; + const { color: color3, lineWidth } = gridLineOpts; + if (!circular && !labelCount || !color3 || !lineWidth || radius < 0) { + return; + } + ctx.save(); + ctx.strokeStyle = color3; + ctx.lineWidth = lineWidth; + ctx.setLineDash(borderOpts.dash); + ctx.lineDashOffset = borderOpts.dashOffset; + ctx.beginPath(); + pathRadiusLine(scale, radius, circular, labelCount); + ctx.closePath(); + ctx.stroke(); + ctx.restore(); +} +function createPointLabelContext(parent, index2, label) { + return createContext(parent, { + label, + index: index2, + type: "pointLabel" + }); +} +var RadialLinearScale = class extends LinearScaleBase { + constructor(cfg) { + super(cfg); + this.xCenter = void 0; + this.yCenter = void 0; + this.drawingArea = void 0; + this._pointLabels = []; + this._pointLabelItems = []; + } + setDimensions() { + const padding = this._padding = toPadding(getTickBackdropHeight(this.options) / 2); + const w = this.width = this.maxWidth - padding.width; + const h = this.height = this.maxHeight - padding.height; + this.xCenter = Math.floor(this.left + w / 2 + padding.left); + this.yCenter = Math.floor(this.top + h / 2 + padding.top); + this.drawingArea = Math.floor(Math.min(w, h) / 2); + } + determineDataLimits() { + const { min, max } = this.getMinMax(false); + this.min = isNumberFinite(min) && !isNaN(min) ? min : 0; + this.max = isNumberFinite(max) && !isNaN(max) ? max : 0; + this.handleTickRangeOptions(); + } + computeTickLimit() { + return Math.ceil(this.drawingArea / getTickBackdropHeight(this.options)); + } + generateTickLabels(ticks) { + LinearScaleBase.prototype.generateTickLabels.call(this, ticks); + this._pointLabels = this.getLabels().map((value, index2) => { + const label = callback(this.options.pointLabels.callback, [ + value, + index2 + ], this); + return label || label === 0 ? label : ""; + }).filter((v, i) => this.chart.getDataVisibility(i)); + } + fit() { + const opts = this.options; + if (opts.display && opts.pointLabels.display) { + fitWithPointLabels(this); + } else { + this.setCenterPoint(0, 0, 0, 0); + } + } + setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) { + this.xCenter += Math.floor((leftMovement - rightMovement) / 2); + this.yCenter += Math.floor((topMovement - bottomMovement) / 2); + this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement)); + } + getIndexAngle(index2) { + const angleMultiplier = TAU / (this._pointLabels.length || 1); + const startAngle = this.options.startAngle || 0; + return _normalizeAngle(index2 * angleMultiplier + toRadians(startAngle)); + } + getDistanceFromCenterForValue(value) { + if (isNullOrUndef(value)) { + return NaN; + } + const scalingFactor = this.drawingArea / (this.max - this.min); + if (this.options.reverse) { + return (this.max - value) * scalingFactor; + } + return (value - this.min) * scalingFactor; + } + getValueForDistanceFromCenter(distance) { + if (isNullOrUndef(distance)) { + return NaN; + } + const scaledDistance = distance / (this.drawingArea / (this.max - this.min)); + return this.options.reverse ? this.max - scaledDistance : this.min + scaledDistance; + } + getPointLabelContext(index2) { + const pointLabels = this._pointLabels || []; + if (index2 >= 0 && index2 < pointLabels.length) { + const pointLabel = pointLabels[index2]; + return createPointLabelContext(this.getContext(), index2, pointLabel); + } + } + getPointPosition(index2, distanceFromCenter, additionalAngle = 0) { + const angle = this.getIndexAngle(index2) - HALF_PI + additionalAngle; + return { + x: Math.cos(angle) * distanceFromCenter + this.xCenter, + y: Math.sin(angle) * distanceFromCenter + this.yCenter, + angle + }; + } + getPointPositionForValue(index2, value) { + return this.getPointPosition(index2, this.getDistanceFromCenterForValue(value)); + } + getBasePosition(index2) { + return this.getPointPositionForValue(index2 || 0, this.getBaseValue()); + } + getPointLabelPosition(index2) { + const { left, top, right, bottom } = this._pointLabelItems[index2]; + return { + left, + top, + right, + bottom + }; + } + drawBackground() { + const { backgroundColor, grid: { circular } } = this.options; + if (backgroundColor) { + const ctx = this.ctx; + ctx.save(); + ctx.beginPath(); + pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length); + ctx.closePath(); + ctx.fillStyle = backgroundColor; + ctx.fill(); + ctx.restore(); + } + } + drawGrid() { + const ctx = this.ctx; + const opts = this.options; + const { angleLines, grid, border } = opts; + const labelCount = this._pointLabels.length; + let i, offset2, position; + if (opts.pointLabels.display) { + drawPointLabels(this, labelCount); + } + if (grid.display) { + this.ticks.forEach((tick, index2) => { + if (index2 !== 0 || index2 === 0 && this.min < 0) { + offset2 = this.getDistanceFromCenterForValue(tick.value); + const context = this.getContext(index2); + const optsAtIndex = grid.setContext(context); + const optsAtIndexBorder = border.setContext(context); + drawRadiusLine(this, optsAtIndex, offset2, labelCount, optsAtIndexBorder); + } + }); + } + if (angleLines.display) { + ctx.save(); + for (i = labelCount - 1; i >= 0; i--) { + const optsAtIndex = angleLines.setContext(this.getPointLabelContext(i)); + const { color: color3, lineWidth } = optsAtIndex; + if (!lineWidth || !color3) { + continue; + } + ctx.lineWidth = lineWidth; + ctx.strokeStyle = color3; + ctx.setLineDash(optsAtIndex.borderDash); + ctx.lineDashOffset = optsAtIndex.borderDashOffset; + offset2 = this.getDistanceFromCenterForValue(opts.ticks.reverse ? this.min : this.max); + position = this.getPointPosition(i, offset2); + ctx.beginPath(); + ctx.moveTo(this.xCenter, this.yCenter); + ctx.lineTo(position.x, position.y); + ctx.stroke(); + } + ctx.restore(); + } + } + drawBorder() { + } + drawLabels() { + const ctx = this.ctx; + const opts = this.options; + const tickOpts = opts.ticks; + if (!tickOpts.display) { + return; + } + const startAngle = this.getIndexAngle(0); + let offset2, width; + ctx.save(); + ctx.translate(this.xCenter, this.yCenter); + ctx.rotate(startAngle); + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + this.ticks.forEach((tick, index2) => { + if (index2 === 0 && this.min >= 0 && !opts.reverse) { + return; + } + const optsAtIndex = tickOpts.setContext(this.getContext(index2)); + const tickFont = toFont(optsAtIndex.font); + offset2 = this.getDistanceFromCenterForValue(this.ticks[index2].value); + if (optsAtIndex.showLabelBackdrop) { + ctx.font = tickFont.string; + width = ctx.measureText(tick.label).width; + ctx.fillStyle = optsAtIndex.backdropColor; + const padding = toPadding(optsAtIndex.backdropPadding); + ctx.fillRect(-width / 2 - padding.left, -offset2 - tickFont.size / 2 - padding.top, width + padding.width, tickFont.size + padding.height); + } + renderText(ctx, tick.label, 0, -offset2, tickFont, { + color: optsAtIndex.color, + strokeColor: optsAtIndex.textStrokeColor, + strokeWidth: optsAtIndex.textStrokeWidth + }); + }); + ctx.restore(); + } + drawTitle() { + } +}; +__publicField(RadialLinearScale, "id", "radialLinear"); +__publicField(RadialLinearScale, "defaults", { + display: true, + animate: true, + position: "chartArea", + angleLines: { + display: true, + lineWidth: 1, + borderDash: [], + borderDashOffset: 0 + }, + grid: { + circular: false + }, + startAngle: 0, + ticks: { + showLabelBackdrop: true, + callback: Ticks.formatters.numeric + }, + pointLabels: { + backdropColor: void 0, + backdropPadding: 2, + display: true, + font: { + size: 10 + }, + callback(label) { + return label; + }, + padding: 5, + centerPointLabels: false + } +}); +__publicField(RadialLinearScale, "defaultRoutes", { + "angleLines.color": "borderColor", + "pointLabels.color": "color", + "ticks.color": "color" +}); +__publicField(RadialLinearScale, "descriptors", { + angleLines: { + _fallback: "grid" + } +}); +var INTERVALS = { + millisecond: { + common: true, + size: 1, + steps: 1e3 + }, + second: { + common: true, + size: 1e3, + steps: 60 + }, + minute: { + common: true, + size: 6e4, + steps: 60 + }, + hour: { + common: true, + size: 36e5, + steps: 24 + }, + day: { + common: true, + size: 864e5, + steps: 30 + }, + week: { + common: false, + size: 6048e5, + steps: 4 + }, + month: { + common: true, + size: 2628e6, + steps: 12 + }, + quarter: { + common: false, + size: 7884e6, + steps: 4 + }, + year: { + common: true, + size: 3154e7 + } +}; +var UNITS = /* @__PURE__ */ Object.keys(INTERVALS); +function sorter(a, b) { + return a - b; +} +function parse(scale, input) { + if (isNullOrUndef(input)) { + return null; + } + const adapter = scale._adapter; + const { parser, round: round3, isoWeekday } = scale._parseOpts; + let value = input; + if (typeof parser === "function") { + value = parser(value); + } + if (!isNumberFinite(value)) { + value = typeof parser === "string" ? adapter.parse(value, parser) : adapter.parse(value); + } + if (value === null) { + return null; + } + if (round3) { + value = round3 === "week" && (isNumber(isoWeekday) || isoWeekday === true) ? adapter.startOf(value, "isoWeek", isoWeekday) : adapter.startOf(value, round3); + } + return +value; +} +function determineUnitForAutoTicks(minUnit, min, max, capacity) { + const ilen = UNITS.length; + for (let i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) { + const interval = INTERVALS[UNITS[i]]; + const factor = interval.steps ? interval.steps : Number.MAX_SAFE_INTEGER; + if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) { + return UNITS[i]; + } + } + return UNITS[ilen - 1]; +} +function determineUnitForFormatting(scale, numTicks, minUnit, min, max) { + for (let i = UNITS.length - 1; i >= UNITS.indexOf(minUnit); i--) { + const unit = UNITS[i]; + if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= numTicks - 1) { + return unit; + } + } + return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0]; +} +function determineMajorUnit(unit) { + for (let i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) { + if (INTERVALS[UNITS[i]].common) { + return UNITS[i]; + } + } +} +function addTick(ticks, time, timestamps) { + if (!timestamps) { + ticks[time] = true; + } else if (timestamps.length) { + const { lo, hi } = _lookup(timestamps, time); + const timestamp = timestamps[lo] >= time ? timestamps[lo] : timestamps[hi]; + ticks[timestamp] = true; + } +} +function setMajorTicks(scale, ticks, map4, majorUnit) { + const adapter = scale._adapter; + const first = +adapter.startOf(ticks[0].value, majorUnit); + const last = ticks[ticks.length - 1].value; + let major, index2; + for (major = first; major <= last; major = +adapter.add(major, 1, majorUnit)) { + index2 = map4[major]; + if (index2 >= 0) { + ticks[index2].major = true; + } + } + return ticks; +} +function ticksFromTimestamps(scale, values, majorUnit) { + const ticks = []; + const map4 = {}; + const ilen = values.length; + let i, value; + for (i = 0; i < ilen; ++i) { + value = values[i]; + map4[value] = i; + ticks.push({ + value, + major: false + }); + } + return ilen === 0 || !majorUnit ? ticks : setMajorTicks(scale, ticks, map4, majorUnit); +} +var TimeScale = class extends Scale { + constructor(props) { + super(props); + this._cache = { + data: [], + labels: [], + all: [] + }; + this._unit = "day"; + this._majorUnit = void 0; + this._offsets = {}; + this._normalized = false; + this._parseOpts = void 0; + } + init(scaleOpts, opts = {}) { + const time = scaleOpts.time || (scaleOpts.time = {}); + const adapter = this._adapter = new adapters._date(scaleOpts.adapters.date); + adapter.init(opts); + mergeIf(time.displayFormats, adapter.formats()); + this._parseOpts = { + parser: time.parser, + round: time.round, + isoWeekday: time.isoWeekday + }; + super.init(scaleOpts); + this._normalized = opts.normalized; + } + parse(raw, index2) { + if (raw === void 0) { + return null; + } + return parse(this, raw); + } + beforeLayout() { + super.beforeLayout(); + this._cache = { + data: [], + labels: [], + all: [] + }; + } + determineDataLimits() { + const options = this.options; + const adapter = this._adapter; + const unit = options.time.unit || "day"; + let { min, max, minDefined, maxDefined } = this.getUserBounds(); + function _applyBounds(bounds) { + if (!minDefined && !isNaN(bounds.min)) { + min = Math.min(min, bounds.min); + } + if (!maxDefined && !isNaN(bounds.max)) { + max = Math.max(max, bounds.max); + } + } + if (!minDefined || !maxDefined) { + _applyBounds(this._getLabelBounds()); + if (options.bounds !== "ticks" || options.ticks.source !== "labels") { + _applyBounds(this.getMinMax(false)); + } + } + min = isNumberFinite(min) && !isNaN(min) ? min : +adapter.startOf(Date.now(), unit); + max = isNumberFinite(max) && !isNaN(max) ? max : +adapter.endOf(Date.now(), unit) + 1; + this.min = Math.min(min, max - 1); + this.max = Math.max(min + 1, max); + } + _getLabelBounds() { + const arr = this.getLabelTimestamps(); + let min = Number.POSITIVE_INFINITY; + let max = Number.NEGATIVE_INFINITY; + if (arr.length) { + min = arr[0]; + max = arr[arr.length - 1]; + } + return { + min, + max + }; + } + buildTicks() { + const options = this.options; + const timeOpts = options.time; + const tickOpts = options.ticks; + const timestamps = tickOpts.source === "labels" ? this.getLabelTimestamps() : this._generate(); + if (options.bounds === "ticks" && timestamps.length) { + this.min = this._userMin || timestamps[0]; + this.max = this._userMax || timestamps[timestamps.length - 1]; + } + const min = this.min; + const max = this.max; + const ticks = _filterBetween(timestamps, min, max); + this._unit = timeOpts.unit || (tickOpts.autoSkip ? determineUnitForAutoTicks(timeOpts.minUnit, this.min, this.max, this._getLabelCapacity(min)) : determineUnitForFormatting(this, ticks.length, timeOpts.minUnit, this.min, this.max)); + this._majorUnit = !tickOpts.major.enabled || this._unit === "year" ? void 0 : determineMajorUnit(this._unit); + this.initOffsets(timestamps); + if (options.reverse) { + ticks.reverse(); + } + return ticksFromTimestamps(this, ticks, this._majorUnit); + } + afterAutoSkip() { + if (this.options.offsetAfterAutoskip) { + this.initOffsets(this.ticks.map((tick) => +tick.value)); + } + } + initOffsets(timestamps = []) { + let start = 0; + let end = 0; + let first, last; + if (this.options.offset && timestamps.length) { + first = this.getDecimalForValue(timestamps[0]); + if (timestamps.length === 1) { + start = 1 - first; + } else { + start = (this.getDecimalForValue(timestamps[1]) - first) / 2; + } + last = this.getDecimalForValue(timestamps[timestamps.length - 1]); + if (timestamps.length === 1) { + end = last; + } else { + end = (last - this.getDecimalForValue(timestamps[timestamps.length - 2])) / 2; + } + } + const limit = timestamps.length < 3 ? 0.5 : 0.25; + start = _limitValue(start, 0, limit); + end = _limitValue(end, 0, limit); + this._offsets = { + start, + end, + factor: 1 / (start + 1 + end) + }; + } + _generate() { + const adapter = this._adapter; + const min = this.min; + const max = this.max; + const options = this.options; + const timeOpts = options.time; + const minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, this._getLabelCapacity(min)); + const stepSize = valueOrDefault(options.ticks.stepSize, 1); + const weekday = minor === "week" ? timeOpts.isoWeekday : false; + const hasWeekday = isNumber(weekday) || weekday === true; + const ticks = {}; + let first = min; + let time, count; + if (hasWeekday) { + first = +adapter.startOf(first, "isoWeek", weekday); + } + first = +adapter.startOf(first, hasWeekday ? "day" : minor); + if (adapter.diff(max, min, minor) > 1e5 * stepSize) { + throw new Error(min + " and " + max + " are too far apart with stepSize of " + stepSize + " " + minor); + } + const timestamps = options.ticks.source === "data" && this.getDataTimestamps(); + for (time = first, count = 0; time < max; time = +adapter.add(time, stepSize, minor), count++) { + addTick(ticks, time, timestamps); + } + if (time === max || options.bounds === "ticks" || count === 1) { + addTick(ticks, time, timestamps); + } + return Object.keys(ticks).sort(sorter).map((x) => +x); + } + getLabelForValue(value) { + const adapter = this._adapter; + const timeOpts = this.options.time; + if (timeOpts.tooltipFormat) { + return adapter.format(value, timeOpts.tooltipFormat); + } + return adapter.format(value, timeOpts.displayFormats.datetime); + } + format(value, format) { + const options = this.options; + const formats = options.time.displayFormats; + const unit = this._unit; + const fmt = format || formats[unit]; + return this._adapter.format(value, fmt); + } + _tickFormatFunction(time, index2, ticks, format) { + const options = this.options; + const formatter = options.ticks.callback; + if (formatter) { + return callback(formatter, [ + time, + index2, + ticks + ], this); + } + const formats = options.time.displayFormats; + const unit = this._unit; + const majorUnit = this._majorUnit; + const minorFormat = unit && formats[unit]; + const majorFormat = majorUnit && formats[majorUnit]; + const tick = ticks[index2]; + const major = majorUnit && majorFormat && tick && tick.major; + return this._adapter.format(time, format || (major ? majorFormat : minorFormat)); + } + generateTickLabels(ticks) { + let i, ilen, tick; + for (i = 0, ilen = ticks.length; i < ilen; ++i) { + tick = ticks[i]; + tick.label = this._tickFormatFunction(tick.value, i, ticks); + } + } + getDecimalForValue(value) { + return value === null ? NaN : (value - this.min) / (this.max - this.min); + } + getPixelForValue(value) { + const offsets = this._offsets; + const pos = this.getDecimalForValue(value); + return this.getPixelForDecimal((offsets.start + pos) * offsets.factor); + } + getValueForPixel(pixel) { + const offsets = this._offsets; + const pos = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end; + return this.min + pos * (this.max - this.min); + } + _getLabelSize(label) { + const ticksOpts = this.options.ticks; + const tickLabelWidth = this.ctx.measureText(label).width; + const angle = toRadians(this.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation); + const cosRotation = Math.cos(angle); + const sinRotation = Math.sin(angle); + const tickFontSize = this._resolveTickFontOptions(0).size; + return { + w: tickLabelWidth * cosRotation + tickFontSize * sinRotation, + h: tickLabelWidth * sinRotation + tickFontSize * cosRotation + }; + } + _getLabelCapacity(exampleTime) { + const timeOpts = this.options.time; + const displayFormats = timeOpts.displayFormats; + const format = displayFormats[timeOpts.unit] || displayFormats.millisecond; + const exampleLabel = this._tickFormatFunction(exampleTime, 0, ticksFromTimestamps(this, [ + exampleTime + ], this._majorUnit), format); + const size = this._getLabelSize(exampleLabel); + const capacity = Math.floor(this.isHorizontal() ? this.width / size.w : this.height / size.h) - 1; + return capacity > 0 ? capacity : 1; + } + getDataTimestamps() { + let timestamps = this._cache.data || []; + let i, ilen; + if (timestamps.length) { + return timestamps; + } + const metas = this.getMatchingVisibleMetas(); + if (this._normalized && metas.length) { + return this._cache.data = metas[0].controller.getAllParsedValues(this); + } + for (i = 0, ilen = metas.length; i < ilen; ++i) { + timestamps = timestamps.concat(metas[i].controller.getAllParsedValues(this)); + } + return this._cache.data = this.normalize(timestamps); + } + getLabelTimestamps() { + const timestamps = this._cache.labels || []; + let i, ilen; + if (timestamps.length) { + return timestamps; + } + const labels = this.getLabels(); + for (i = 0, ilen = labels.length; i < ilen; ++i) { + timestamps.push(parse(this, labels[i])); + } + return this._cache.labels = this._normalized ? timestamps : this.normalize(timestamps); + } + normalize(values) { + return _arrayUnique(values.sort(sorter)); + } +}; +__publicField(TimeScale, "id", "time"); +__publicField(TimeScale, "defaults", { + bounds: "data", + adapters: {}, + time: { + parser: false, + unit: false, + round: false, + isoWeekday: false, + minUnit: "millisecond", + displayFormats: {} + }, + ticks: { + source: "auto", + callback: false, + major: { + enabled: false + } + } +}); +function interpolate2(table, val, reverse) { + let lo = 0; + let hi = table.length - 1; + let prevSource, nextSource, prevTarget, nextTarget; + if (reverse) { + if (val >= table[lo].pos && val <= table[hi].pos) { + ({ lo, hi } = _lookupByKey(table, "pos", val)); + } + ({ pos: prevSource, time: prevTarget } = table[lo]); + ({ pos: nextSource, time: nextTarget } = table[hi]); + } else { + if (val >= table[lo].time && val <= table[hi].time) { + ({ lo, hi } = _lookupByKey(table, "time", val)); + } + ({ time: prevSource, pos: prevTarget } = table[lo]); + ({ time: nextSource, pos: nextTarget } = table[hi]); + } + const span = nextSource - prevSource; + return span ? prevTarget + (nextTarget - prevTarget) * (val - prevSource) / span : prevTarget; +} +var TimeSeriesScale = class extends TimeScale { + constructor(props) { + super(props); + this._table = []; + this._minPos = void 0; + this._tableRange = void 0; + } + initOffsets() { + const timestamps = this._getTimestampsForTable(); + const table = this._table = this.buildLookupTable(timestamps); + this._minPos = interpolate2(table, this.min); + this._tableRange = interpolate2(table, this.max) - this._minPos; + super.initOffsets(timestamps); + } + buildLookupTable(timestamps) { + const { min, max } = this; + const items = []; + const table = []; + let i, ilen, prev, curr, next; + for (i = 0, ilen = timestamps.length; i < ilen; ++i) { + curr = timestamps[i]; + if (curr >= min && curr <= max) { + items.push(curr); + } + } + if (items.length < 2) { + return [ + { + time: min, + pos: 0 + }, + { + time: max, + pos: 1 + } + ]; + } + for (i = 0, ilen = items.length; i < ilen; ++i) { + next = items[i + 1]; + prev = items[i - 1]; + curr = items[i]; + if (Math.round((next + prev) / 2) !== curr) { + table.push({ + time: curr, + pos: i / (ilen - 1) + }); + } + } + return table; + } + _generate() { + const min = this.min; + const max = this.max; + let timestamps = super.getDataTimestamps(); + if (!timestamps.includes(min) || !timestamps.length) { + timestamps.splice(0, 0, min); + } + if (!timestamps.includes(max) || timestamps.length === 1) { + timestamps.push(max); + } + return timestamps.sort((a, b) => a - b); + } + _getTimestampsForTable() { + let timestamps = this._cache.all || []; + if (timestamps.length) { + return timestamps; + } + const data = this.getDataTimestamps(); + const label = this.getLabelTimestamps(); + if (data.length && label.length) { + timestamps = this.normalize(data.concat(label)); + } else { + timestamps = data.length ? data : label; + } + timestamps = this._cache.all = timestamps; + return timestamps; + } + getDecimalForValue(value) { + return (interpolate2(this._table, value) - this._minPos) / this._tableRange; + } + getValueForPixel(pixel) { + const offsets = this._offsets; + const decimal = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end; + return interpolate2(this._table, decimal * this._tableRange + this._minPos, true); + } +}; +__publicField(TimeSeriesScale, "id", "timeseries"); +__publicField(TimeSeriesScale, "defaults", TimeScale.defaults); +var scales = /* @__PURE__ */ Object.freeze({ + __proto__: null, + CategoryScale, + LinearScale, + LogarithmicScale, + RadialLinearScale, + TimeScale, + TimeSeriesScale +}); +var registerables = [ + controllers, + elements, + plugins, + scales +]; + +// node_modules/chart.js/auto/auto.js +Chart.register(...registerables); + +// ../../../node_modules/@kurkle/color/dist/color.esm.js +function round2(v) { + return v + 0.5 | 0; +} +var lim2 = (v, l2, h) => Math.max(Math.min(v, h), l2); +function p2b2(v) { + return lim2(round2(v * 2.55), 0, 255); +} +function n2b2(v) { + return lim2(round2(v * 255), 0, 255); +} +function b2n2(v) { + return lim2(round2(v / 2.55) / 100, 0, 1); +} +function n2p2(v) { + return lim2(round2(v * 100), 0, 100); +} +var map$12 = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15 }; +var hex2 = [..."0123456789ABCDEF"]; +var h12 = (b) => hex2[b & 15]; +var h22 = (b) => hex2[(b & 240) >> 4] + hex2[b & 15]; +var eq2 = (b) => (b & 240) >> 4 === (b & 15); +var isShort2 = (v) => eq2(v.r) && eq2(v.g) && eq2(v.b) && eq2(v.a); +function hexParse2(str) { + var len = str.length; + var ret; + if (str[0] === "#") { + if (len === 4 || len === 5) { + ret = { + r: 255 & map$12[str[1]] * 17, + g: 255 & map$12[str[2]] * 17, + b: 255 & map$12[str[3]] * 17, + a: len === 5 ? map$12[str[4]] * 17 : 255 + }; + } else if (len === 7 || len === 9) { + ret = { + r: map$12[str[1]] << 4 | map$12[str[2]], + g: map$12[str[3]] << 4 | map$12[str[4]], + b: map$12[str[5]] << 4 | map$12[str[6]], + a: len === 9 ? map$12[str[7]] << 4 | map$12[str[8]] : 255 + }; + } + } + return ret; +} +var alpha2 = (a, f) => a < 255 ? f(a) : ""; +function hexString2(v) { + var f = isShort2(v) ? h12 : h22; + return v ? "#" + f(v.r) + f(v.g) + f(v.b) + alpha2(v.a, f) : void 0; +} +var HUE_RE2 = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/; +function hsl2rgbn2(h, s2, l2) { + const a = s2 * Math.min(l2, 1 - l2); + const f = (n2, k = (n2 + h / 30) % 12) => l2 - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); + return [f(0), f(8), f(4)]; +} +function hsv2rgbn2(h, s2, v) { + const f = (n2, k = (n2 + h / 60) % 6) => v - v * s2 * Math.max(Math.min(k, 4 - k, 1), 0); + return [f(5), f(3), f(1)]; +} +function hwb2rgbn2(h, w, b) { + const rgb = hsl2rgbn2(h, 1, 0.5); + let i; + if (w + b > 1) { + i = 1 / (w + b); + w *= i; + b *= i; + } + for (i = 0; i < 3; i++) { + rgb[i] *= 1 - w - b; + rgb[i] += w; + } + return rgb; +} +function hueValue2(r, g, b, d, max) { + if (r === max) { + return (g - b) / d + (g < b ? 6 : 0); + } + if (g === max) { + return (b - r) / d + 2; + } + return (r - g) / d + 4; +} +function rgb2hsl2(v) { + const range = 255; + const r = v.r / range; + const g = v.g / range; + const b = v.b / range; + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + const l2 = (max + min) / 2; + let h, s2, d; + if (max !== min) { + d = max - min; + s2 = l2 > 0.5 ? d / (2 - max - min) : d / (max + min); + h = hueValue2(r, g, b, d, max); + h = h * 60 + 0.5; + } + return [h | 0, s2 || 0, l2]; +} +function calln2(f, a, b, c) { + return (Array.isArray(a) ? f(a[0], a[1], a[2]) : f(a, b, c)).map(n2b2); +} +function hsl2rgb2(h, s2, l2) { + return calln2(hsl2rgbn2, h, s2, l2); +} +function hwb2rgb2(h, w, b) { + return calln2(hwb2rgbn2, h, w, b); +} +function hsv2rgb2(h, s2, v) { + return calln2(hsv2rgbn2, h, s2, v); +} +function hue2(h) { + return (h % 360 + 360) % 360; +} +function hueParse2(str) { + const m = HUE_RE2.exec(str); + let a = 255; + let v; + if (!m) { + return; + } + if (m[5] !== v) { + a = m[6] ? p2b2(+m[5]) : n2b2(+m[5]); + } + const h = hue2(+m[2]); + const p1 = +m[3] / 100; + const p2 = +m[4] / 100; + if (m[1] === "hwb") { + v = hwb2rgb2(h, p1, p2); + } else if (m[1] === "hsv") { + v = hsv2rgb2(h, p1, p2); + } else { + v = hsl2rgb2(h, p1, p2); + } + return { + r: v[0], + g: v[1], + b: v[2], + a + }; +} +function rotate2(v, deg) { + var h = rgb2hsl2(v); + h[0] = hue2(h[0] + deg); + h = hsl2rgb2(h); + v.r = h[0]; + v.g = h[1]; + v.b = h[2]; +} +function hslString2(v) { + if (!v) { + return; + } + const a = rgb2hsl2(v); + const h = a[0]; + const s2 = n2p2(a[1]); + const l2 = n2p2(a[2]); + return v.a < 255 ? `hsla(${h}, ${s2}%, ${l2}%, ${b2n2(v.a)})` : `hsl(${h}, ${s2}%, ${l2}%)`; +} +var map3 = { + x: "dark", + Z: "light", + Y: "re", + X: "blu", + W: "gr", + V: "medium", + U: "slate", + A: "ee", + T: "ol", + S: "or", + B: "ra", + C: "lateg", + D: "ights", + R: "in", + Q: "turquois", + E: "hi", + P: "ro", + O: "al", + N: "le", + M: "de", + L: "yello", + F: "en", + K: "ch", + G: "arks", + H: "ea", + I: "ightg", + J: "wh" +}; +var names$12 = { + OiceXe: "f0f8ff", + antiquewEte: "faebd7", + aqua: "ffff", + aquamarRe: "7fffd4", + azuY: "f0ffff", + beige: "f5f5dc", + bisque: "ffe4c4", + black: "0", + blanKedOmond: "ffebcd", + Xe: "ff", + XeviTet: "8a2be2", + bPwn: "a52a2a", + burlywood: "deb887", + caMtXe: "5f9ea0", + KartYuse: "7fff00", + KocTate: "d2691e", + cSO: "ff7f50", + cSnflowerXe: "6495ed", + cSnsilk: "fff8dc", + crimson: "dc143c", + cyan: "ffff", + xXe: "8b", + xcyan: "8b8b", + xgTMnPd: "b8860b", + xWay: "a9a9a9", + xgYF: "6400", + xgYy: "a9a9a9", + xkhaki: "bdb76b", + xmagFta: "8b008b", + xTivegYF: "556b2f", + xSange: "ff8c00", + xScEd: "9932cc", + xYd: "8b0000", + xsOmon: "e9967a", + xsHgYF: "8fbc8f", + xUXe: "483d8b", + xUWay: "2f4f4f", + xUgYy: "2f4f4f", + xQe: "ced1", + xviTet: "9400d3", + dAppRk: "ff1493", + dApskyXe: "bfff", + dimWay: "696969", + dimgYy: "696969", + dodgerXe: "1e90ff", + fiYbrick: "b22222", + flSOwEte: "fffaf0", + foYstWAn: "228b22", + fuKsia: "ff00ff", + gaRsbSo: "dcdcdc", + ghostwEte: "f8f8ff", + gTd: "ffd700", + gTMnPd: "daa520", + Way: "808080", + gYF: "8000", + gYFLw: "adff2f", + gYy: "808080", + honeyMw: "f0fff0", + hotpRk: "ff69b4", + RdianYd: "cd5c5c", + Rdigo: "4b0082", + ivSy: "fffff0", + khaki: "f0e68c", + lavFMr: "e6e6fa", + lavFMrXsh: "fff0f5", + lawngYF: "7cfc00", + NmoncEffon: "fffacd", + ZXe: "add8e6", + ZcSO: "f08080", + Zcyan: "e0ffff", + ZgTMnPdLw: "fafad2", + ZWay: "d3d3d3", + ZgYF: "90ee90", + ZgYy: "d3d3d3", + ZpRk: "ffb6c1", + ZsOmon: "ffa07a", + ZsHgYF: "20b2aa", + ZskyXe: "87cefa", + ZUWay: "778899", + ZUgYy: "778899", + ZstAlXe: "b0c4de", + ZLw: "ffffe0", + lime: "ff00", + limegYF: "32cd32", + lRF: "faf0e6", + magFta: "ff00ff", + maPon: "800000", + VaquamarRe: "66cdaa", + VXe: "cd", + VScEd: "ba55d3", + VpurpN: "9370db", + VsHgYF: "3cb371", + VUXe: "7b68ee", + VsprRggYF: "fa9a", + VQe: "48d1cc", + VviTetYd: "c71585", + midnightXe: "191970", + mRtcYam: "f5fffa", + mistyPse: "ffe4e1", + moccasR: "ffe4b5", + navajowEte: "ffdead", + navy: "80", + Tdlace: "fdf5e6", + Tive: "808000", + TivedBb: "6b8e23", + Sange: "ffa500", + SangeYd: "ff4500", + ScEd: "da70d6", + pOegTMnPd: "eee8aa", + pOegYF: "98fb98", + pOeQe: "afeeee", + pOeviTetYd: "db7093", + papayawEp: "ffefd5", + pHKpuff: "ffdab9", + peru: "cd853f", + pRk: "ffc0cb", + plum: "dda0dd", + powMrXe: "b0e0e6", + purpN: "800080", + YbeccapurpN: "663399", + Yd: "ff0000", + Psybrown: "bc8f8f", + PyOXe: "4169e1", + saddNbPwn: "8b4513", + sOmon: "fa8072", + sandybPwn: "f4a460", + sHgYF: "2e8b57", + sHshell: "fff5ee", + siFna: "a0522d", + silver: "c0c0c0", + skyXe: "87ceeb", + UXe: "6a5acd", + UWay: "708090", + UgYy: "708090", + snow: "fffafa", + sprRggYF: "ff7f", + stAlXe: "4682b4", + tan: "d2b48c", + teO: "8080", + tEstN: "d8bfd8", + tomato: "ff6347", + Qe: "40e0d0", + viTet: "ee82ee", + JHt: "f5deb3", + wEte: "ffffff", + wEtesmoke: "f5f5f5", + Lw: "ffff00", + LwgYF: "9acd32" +}; +function unpack2() { + const unpacked = {}; + const keys = Object.keys(names$12); + const tkeys = Object.keys(map3); + let i, j, k, ok, nk; + for (i = 0; i < keys.length; i++) { + ok = nk = keys[i]; + for (j = 0; j < tkeys.length; j++) { + k = tkeys[j]; + nk = nk.replace(k, map3[k]); + } + k = parseInt(names$12[ok], 16); + unpacked[nk] = [k >> 16 & 255, k >> 8 & 255, k & 255]; + } + return unpacked; +} +var names2; +function nameParse2(str) { + if (!names2) { + names2 = unpack2(); + names2.transparent = [0, 0, 0, 0]; + } + const a = names2[str.toLowerCase()]; + return a && { + r: a[0], + g: a[1], + b: a[2], + a: a.length === 4 ? a[3] : 255 + }; +} +var RGB_RE2 = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/; +function rgbParse2(str) { + const m = RGB_RE2.exec(str); + let a = 255; + let r, g, b; + if (!m) { + return; + } + if (m[7] !== r) { + const v = +m[7]; + a = m[8] ? p2b2(v) : lim2(v * 255, 0, 255); + } + r = +m[1]; + g = +m[3]; + b = +m[5]; + r = 255 & (m[2] ? p2b2(r) : lim2(r, 0, 255)); + g = 255 & (m[4] ? p2b2(g) : lim2(g, 0, 255)); + b = 255 & (m[6] ? p2b2(b) : lim2(b, 0, 255)); + return { + r, + g, + b, + a + }; +} +function rgbString2(v) { + return v && (v.a < 255 ? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n2(v.a)})` : `rgb(${v.r}, ${v.g}, ${v.b})`); +} +var to2 = (v) => v <= 31308e-7 ? v * 12.92 : Math.pow(v, 1 / 2.4) * 1.055 - 0.055; +var from2 = (v) => v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4); +function interpolate3(rgb1, rgb2, t) { + const r = from2(b2n2(rgb1.r)); + const g = from2(b2n2(rgb1.g)); + const b = from2(b2n2(rgb1.b)); + return { + r: n2b2(to2(r + t * (from2(b2n2(rgb2.r)) - r))), + g: n2b2(to2(g + t * (from2(b2n2(rgb2.g)) - g))), + b: n2b2(to2(b + t * (from2(b2n2(rgb2.b)) - b))), + a: rgb1.a + t * (rgb2.a - rgb1.a) + }; +} +function modHSL2(v, i, ratio) { + if (v) { + let tmp = rgb2hsl2(v); + tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1)); + tmp = hsl2rgb2(tmp); + v.r = tmp[0]; + v.g = tmp[1]; + v.b = tmp[2]; + } +} +function clone3(v, proto) { + return v ? Object.assign(proto || {}, v) : v; +} +function fromObject2(input) { + var v = { r: 0, g: 0, b: 0, a: 255 }; + if (Array.isArray(input)) { + if (input.length >= 3) { + v = { r: input[0], g: input[1], b: input[2], a: 255 }; + if (input.length > 3) { + v.a = n2b2(input[3]); + } + } + } else { + v = clone3(input, { r: 0, g: 0, b: 0, a: 1 }); + v.a = n2b2(v.a); + } + return v; +} +function functionParse2(str) { + if (str.charAt(0) === "r") { + return rgbParse2(str); + } + return hueParse2(str); +} +var Color2 = class { + constructor(input) { + if (input instanceof Color2) { + return input; + } + const type = typeof input; + let v; + if (type === "object") { + v = fromObject2(input); + } else if (type === "string") { + v = hexParse2(input) || nameParse2(input) || functionParse2(input); + } + this._rgb = v; + this._valid = !!v; + } + get valid() { + return this._valid; + } + get rgb() { + var v = clone3(this._rgb); + if (v) { + v.a = b2n2(v.a); + } + return v; + } + set rgb(obj) { + this._rgb = fromObject2(obj); + } + rgbString() { + return this._valid ? rgbString2(this._rgb) : void 0; + } + hexString() { + return this._valid ? hexString2(this._rgb) : void 0; + } + hslString() { + return this._valid ? hslString2(this._rgb) : void 0; + } + mix(color3, weight) { + if (color3) { + const c1 = this.rgb; + const c2 = color3.rgb; + let w2; + const p = weight === w2 ? 0.5 : weight; + const w = 2 * p - 1; + const a = c1.a - c2.a; + const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2; + w2 = 1 - w1; + c1.r = 255 & w1 * c1.r + w2 * c2.r + 0.5; + c1.g = 255 & w1 * c1.g + w2 * c2.g + 0.5; + c1.b = 255 & w1 * c1.b + w2 * c2.b + 0.5; + c1.a = p * c1.a + (1 - p) * c2.a; + this.rgb = c1; + } + return this; + } + interpolate(color3, t) { + if (color3) { + this._rgb = interpolate3(this._rgb, color3._rgb, t); + } + return this; + } + clone() { + return new Color2(this.rgb); + } + alpha(a) { + this._rgb.a = n2b2(a); + return this; + } + clearer(ratio) { + const rgb = this._rgb; + rgb.a *= 1 - ratio; + return this; + } + greyscale() { + const rgb = this._rgb; + const val = round2(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11); + rgb.r = rgb.g = rgb.b = val; + return this; + } + opaquer(ratio) { + const rgb = this._rgb; + rgb.a *= 1 + ratio; + return this; + } + negate() { + const v = this._rgb; + v.r = 255 - v.r; + v.g = 255 - v.g; + v.b = 255 - v.b; + return this; + } + lighten(ratio) { + modHSL2(this._rgb, 2, ratio); + return this; + } + darken(ratio) { + modHSL2(this._rgb, 2, -ratio); + return this; + } + saturate(ratio) { + modHSL2(this._rgb, 1, ratio); + return this; + } + desaturate(ratio) { + modHSL2(this._rgb, 1, -ratio); + return this; + } + rotate(deg) { + rotate2(this._rgb, deg); + return this; + } +}; + +// ../../../node_modules/chart.js/dist/chunks/helpers.segment.js +var uid2 = (() => { + let id = 0; + return () => id++; +})(); +function isNullOrUndef2(value) { + return value === null || typeof value === "undefined"; +} +function isArray2(value) { + if (Array.isArray && Array.isArray(value)) { + return true; + } + const type = Object.prototype.toString.call(value); + if (type.slice(0, 7) === "[object" && type.slice(-6) === "Array]") { + return true; + } + return false; +} +function isObject2(value) { + return value !== null && Object.prototype.toString.call(value) === "[object Object]"; +} +function isNumberFinite2(value) { + return (typeof value === "number" || value instanceof Number) && isFinite(+value); +} +function finiteOrDefault2(value, defaultValue) { + return isNumberFinite2(value) ? value : defaultValue; +} +function valueOrDefault2(value, defaultValue) { + return typeof value === "undefined" ? defaultValue : value; +} +var toDimension2 = (value, dimension) => typeof value === "string" && value.endsWith("%") ? parseFloat(value) / 100 * dimension : +value; +function callback2(fn, args, thisArg) { + if (fn && typeof fn.call === "function") { + return fn.apply(thisArg, args); + } +} +function each2(loopable, fn, thisArg, reverse) { + let i, len, keys; + if (isArray2(loopable)) { + len = loopable.length; + if (reverse) { + for (i = len - 1; i >= 0; i--) { + fn.call(thisArg, loopable[i], i); + } + } else { + for (i = 0; i < len; i++) { + fn.call(thisArg, loopable[i], i); + } + } + } else if (isObject2(loopable)) { + keys = Object.keys(loopable); + len = keys.length; + for (i = 0; i < len; i++) { + fn.call(thisArg, loopable[keys[i]], keys[i]); + } + } +} +function clone4(source) { + if (isArray2(source)) { + return source.map(clone4); + } + if (isObject2(source)) { + const target = /* @__PURE__ */ Object.create(null); + const keys = Object.keys(source); + const klen = keys.length; + let k = 0; + for (; k < klen; ++k) { + target[keys[k]] = clone4(source[keys[k]]); + } + return target; + } + return source; +} +function isValidKey2(key) { + return [ + "__proto__", + "prototype", + "constructor" + ].indexOf(key) === -1; +} +function _merger2(key, target, source, options) { + if (!isValidKey2(key)) { + return; + } + const tval = target[key]; + const sval = source[key]; + if (isObject2(tval) && isObject2(sval)) { + merge2(tval, sval, options); + } else { + target[key] = clone4(sval); + } +} +function merge2(target, source, options) { + const sources = isArray2(source) ? source : [ + source + ]; + const ilen = sources.length; + if (!isObject2(target)) { + return target; + } + options = options || {}; + const merger = options.merger || _merger2; + let current; + for (let i = 0; i < ilen; ++i) { + current = sources[i]; + if (!isObject2(current)) { + continue; + } + const keys = Object.keys(current); + for (let k = 0, klen = keys.length; k < klen; ++k) { + merger(keys[k], target, current, options); + } + } + return target; +} +function mergeIf2(target, source) { + return merge2(target, source, { + merger: _mergerIf2 + }); +} +function _mergerIf2(key, target, source) { + if (!isValidKey2(key)) { + return; + } + const tval = target[key]; + const sval = source[key]; + if (isObject2(tval) && isObject2(sval)) { + mergeIf2(tval, sval); + } else if (!Object.prototype.hasOwnProperty.call(target, key)) { + target[key] = clone4(sval); + } +} +var PI2 = Math.PI; +var TAU2 = 2 * PI2; +var PITAU2 = TAU2 + PI2; +var INFINITY2 = Number.POSITIVE_INFINITY; +var RAD_PER_DEG2 = PI2 / 180; +var HALF_PI2 = PI2 / 2; +var QUARTER_PI2 = PI2 / 4; +var TWO_THIRDS_PI2 = PI2 * 2 / 3; +var log102 = Math.log10; +var sign2 = Math.sign; +function almostEquals2(x, y, epsilon) { + return Math.abs(x - y) < epsilon; +} +function niceNum2(range) { + const roundedRange = Math.round(range); + range = almostEquals2(range, roundedRange, range / 1e3) ? roundedRange : range; + const niceRange = Math.pow(10, Math.floor(log102(range))); + const fraction = range / niceRange; + const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10; + return niceFraction * niceRange; +} +function _factorize2(value) { + const result = []; + const sqrt = Math.sqrt(value); + let i; + for (i = 1; i < sqrt; i++) { + if (value % i === 0) { + result.push(i); + result.push(value / i); + } + } + if (sqrt === (sqrt | 0)) { + result.push(sqrt); + } + result.sort((a, b) => a - b).pop(); + return result; +} +function isNumber2(n2) { + return !isNaN(parseFloat(n2)) && isFinite(n2); +} +function almostWhole2(x, epsilon) { + const rounded = Math.round(x); + return rounded - epsilon <= x && rounded + epsilon >= x; +} +function _setMinAndMaxByKey2(array, target, property) { + let i, ilen, value; + for (i = 0, ilen = array.length; i < ilen; i++) { + value = array[i][property]; + if (!isNaN(value)) { + target.min = Math.min(target.min, value); + target.max = Math.max(target.max, value); + } + } +} +function toRadians2(degrees) { + return degrees * (PI2 / 180); +} +function toDegrees2(radians) { + return radians * (180 / PI2); +} +function _decimalPlaces2(x) { + if (!isNumberFinite2(x)) { + return; + } + let e = 1; + let p = 0; + while (Math.round(x * e) / e !== x) { + e *= 10; + p++; + } + return p; +} +function _normalizeAngle2(a) { + return (a % TAU2 + TAU2) % TAU2; +} +function _limitValue2(value, min, max) { + return Math.max(min, Math.min(max, value)); +} +function _int16Range2(value) { + return _limitValue2(value, -32768, 32767); +} +function _lookup2(table, value, cmp) { + cmp = cmp || ((index2) => table[index2] < value); + let hi = table.length - 1; + let lo = 0; + let mid; + while (hi - lo > 1) { + mid = lo + hi >> 1; + if (cmp(mid)) { + lo = mid; + } else { + hi = mid; + } + } + return { + lo, + hi + }; +} +var _lookupByKey2 = (table, key, value, last) => _lookup2(table, value, last ? (index2) => { + const ti = table[index2][key]; + return ti < value || ti === value && table[index2 + 1][key] === value; +} : (index2) => table[index2][key] < value); +function _filterBetween2(values, min, max) { + let start = 0; + let end = values.length; + while (start < end && values[start] < min) { + start++; + } + while (end > start && values[end - 1] > max) { + end--; + } + return start > 0 || end < values.length ? values.slice(start, end) : values; +} +function _arrayUnique2(items) { + const set3 = new Set(items); + if (set3.size === items.length) { + return items; + } + return Array.from(set3); +} +var requestAnimFrame2 = function() { + if (typeof window === "undefined") { + return function(callback3) { + return callback3(); + }; + } + return window.requestAnimationFrame; +}(); +var _toLeftRightCenter2 = (align) => align === "start" ? "left" : align === "end" ? "right" : "center"; +var _alignStartEnd2 = (align, start, end) => align === "start" ? start : align === "end" ? end : (start + end) / 2; +function isPatternOrGradient2(value) { + if (value && typeof value === "object") { + const type = value.toString(); + return type === "[object CanvasPattern]" || type === "[object CanvasGradient]"; + } + return false; +} +function getHoverColor2(value) { + return isPatternOrGradient2(value) ? value : new Color2(value).saturate(0.5).darken(0.1).hexString(); +} +var numbers2 = [ + "x", + "y", + "borderWidth", + "radius", + "tension" +]; +var colors2 = [ + "color", + "borderColor", + "backgroundColor" +]; +function applyAnimationsDefaults2(defaults3) { + defaults3.set("animation", { + delay: void 0, + duration: 1e3, + easing: "easeOutQuart", + fn: void 0, + from: void 0, + loop: void 0, + to: void 0, + type: void 0 + }); + defaults3.describe("animation", { + _fallback: false, + _indexable: false, + _scriptable: (name) => name !== "onProgress" && name !== "onComplete" && name !== "fn" + }); + defaults3.set("animations", { + colors: { + type: "color", + properties: colors2 + }, + numbers: { + type: "number", + properties: numbers2 + } + }); + defaults3.describe("animations", { + _fallback: "animation" + }); + defaults3.set("transitions", { + active: { + animation: { + duration: 400 + } + }, + resize: { + animation: { + duration: 0 + } + }, + show: { + animations: { + colors: { + from: "transparent" + }, + visible: { + type: "boolean", + duration: 0 + } + } + }, + hide: { + animations: { + colors: { + to: "transparent" + }, + visible: { + type: "boolean", + easing: "linear", + fn: (v) => v | 0 + } + } + } + }); +} +function applyLayoutsDefaults2(defaults3) { + defaults3.set("layout", { + autoPadding: true, + padding: { + top: 0, + right: 0, + bottom: 0, + left: 0 + } + }); +} +var intlCache2 = /* @__PURE__ */ new Map(); +function getNumberFormat2(locale, options) { + options = options || {}; + const cacheKey = locale + JSON.stringify(options); + let formatter = intlCache2.get(cacheKey); + if (!formatter) { + formatter = new Intl.NumberFormat(locale, options); + intlCache2.set(cacheKey, formatter); + } + return formatter; +} +function formatNumber2(num, locale, options) { + return getNumberFormat2(locale, options).format(num); +} +var formatters2 = { + values(value) { + return isArray2(value) ? value : "" + value; + }, + numeric(tickValue, index2, ticks) { + if (tickValue === 0) { + return "0"; + } + const locale = this.chart.options.locale; + let notation; + let delta = tickValue; + if (ticks.length > 1) { + const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value)); + if (maxTick < 1e-4 || maxTick > 1e15) { + notation = "scientific"; + } + delta = calculateDelta2(tickValue, ticks); + } + const logDelta = log102(Math.abs(delta)); + const numDecimal = isNaN(logDelta) ? 1 : Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0); + const options = { + notation, + minimumFractionDigits: numDecimal, + maximumFractionDigits: numDecimal + }; + Object.assign(options, this.options.ticks.format); + return formatNumber2(tickValue, locale, options); + }, + logarithmic(tickValue, index2, ticks) { + if (tickValue === 0) { + return "0"; + } + const remain = ticks[index2].significand || tickValue / Math.pow(10, Math.floor(log102(tickValue))); + if ([ + 1, + 2, + 3, + 5, + 10, + 15 + ].includes(remain) || index2 > 0.8 * ticks.length) { + return formatters2.numeric.call(this, tickValue, index2, ticks); + } + return ""; + } +}; +function calculateDelta2(tickValue, ticks) { + let delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value; + if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) { + delta = tickValue - Math.floor(tickValue); + } + return delta; +} +var Ticks2 = { + formatters: formatters2 +}; +function applyScaleDefaults2(defaults3) { + defaults3.set("scale", { + display: true, + offset: false, + reverse: false, + beginAtZero: false, + bounds: "ticks", + clip: true, + grace: 0, + grid: { + display: true, + lineWidth: 1, + drawOnChartArea: true, + drawTicks: true, + tickLength: 8, + tickWidth: (_ctx, options) => options.lineWidth, + tickColor: (_ctx, options) => options.color, + offset: false + }, + border: { + display: true, + dash: [], + dashOffset: 0, + width: 1 + }, + title: { + display: false, + text: "", + padding: { + top: 4, + bottom: 4 + } + }, + ticks: { + minRotation: 0, + maxRotation: 50, + mirror: false, + textStrokeWidth: 0, + textStrokeColor: "", + padding: 3, + display: true, + autoSkip: true, + autoSkipPadding: 3, + labelOffset: 0, + callback: Ticks2.formatters.values, + minor: {}, + major: {}, + align: "center", + crossAlign: "near", + showLabelBackdrop: false, + backdropColor: "rgba(255, 255, 255, 0.75)", + backdropPadding: 2 + } + }); + defaults3.route("scale.ticks", "color", "", "color"); + defaults3.route("scale.grid", "color", "", "borderColor"); + defaults3.route("scale.border", "color", "", "borderColor"); + defaults3.route("scale.title", "color", "", "color"); + defaults3.describe("scale", { + _fallback: false, + _scriptable: (name) => !name.startsWith("before") && !name.startsWith("after") && name !== "callback" && name !== "parser", + _indexable: (name) => name !== "borderDash" && name !== "tickBorderDash" && name !== "dash" + }); + defaults3.describe("scales", { + _fallback: "scale" + }); + defaults3.describe("scale.ticks", { + _scriptable: (name) => name !== "backdropPadding" && name !== "callback", + _indexable: (name) => name !== "backdropPadding" + }); +} +var overrides2 = /* @__PURE__ */ Object.create(null); +var descriptors2 = /* @__PURE__ */ Object.create(null); +function getScope$12(node, key) { + if (!key) { + return node; + } + const keys = key.split("."); + for (let i = 0, n2 = keys.length; i < n2; ++i) { + const k = keys[i]; + node = node[k] || (node[k] = /* @__PURE__ */ Object.create(null)); + } + return node; +} +function set2(root, scope, values) { + if (typeof scope === "string") { + return merge2(getScope$12(root, scope), values); + } + return merge2(getScope$12(root, ""), scope); +} +var Defaults2 = class { + constructor(_descriptors3, _appliers) { + this.animation = void 0; + this.backgroundColor = "rgba(0,0,0,0.1)"; + this.borderColor = "rgba(0,0,0,0.1)"; + this.color = "#666"; + this.datasets = {}; + this.devicePixelRatio = (context) => context.chart.platform.getDevicePixelRatio(); + this.elements = {}; + this.events = [ + "mousemove", + "mouseout", + "click", + "touchstart", + "touchmove" + ]; + this.font = { + family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + size: 12, + style: "normal", + lineHeight: 1.2, + weight: null + }; + this.hover = {}; + this.hoverBackgroundColor = (ctx, options) => getHoverColor2(options.backgroundColor); + this.hoverBorderColor = (ctx, options) => getHoverColor2(options.borderColor); + this.hoverColor = (ctx, options) => getHoverColor2(options.color); + this.indexAxis = "x"; + this.interaction = { + mode: "nearest", + intersect: true, + includeInvisible: false + }; + this.maintainAspectRatio = true; + this.onHover = null; + this.onClick = null; + this.parsing = true; + this.plugins = {}; + this.responsive = true; + this.scale = void 0; + this.scales = {}; + this.showLine = true; + this.drawActiveElementsOnTop = true; + this.describe(_descriptors3); + this.apply(_appliers); + } + set(scope, values) { + return set2(this, scope, values); + } + get(scope) { + return getScope$12(this, scope); + } + describe(scope, values) { + return set2(descriptors2, scope, values); + } + override(scope, values) { + return set2(overrides2, scope, values); + } + route(scope, name, targetScope, targetName) { + const scopeObject = getScope$12(this, scope); + const targetScopeObject = getScope$12(this, targetScope); + const privateName = "_" + name; + Object.defineProperties(scopeObject, { + [privateName]: { + value: scopeObject[name], + writable: true + }, + [name]: { + enumerable: true, + get() { + const local = this[privateName]; + const target = targetScopeObject[targetName]; + if (isObject2(local)) { + return Object.assign({}, target, local); + } + return valueOrDefault2(local, target); + }, + set(value) { + this[privateName] = value; + } + } + }); + } + apply(appliers) { + appliers.forEach((apply) => apply(this)); + } +}; +var defaults2 = /* @__PURE__ */ new Defaults2({ + _scriptable: (name) => !name.startsWith("on"), + _indexable: (name) => name !== "events", + hover: { + _fallback: "interaction" + }, + interaction: { + _scriptable: false, + _indexable: false + } +}, [ + applyAnimationsDefaults2, + applyLayoutsDefaults2, + applyScaleDefaults2 +]); +function toFontString2(font) { + if (!font || isNullOrUndef2(font.size) || isNullOrUndef2(font.family)) { + return null; + } + return (font.style ? font.style + " " : "") + (font.weight ? font.weight + " " : "") + font.size + "px " + font.family; +} +function _measureText2(ctx, data, gc, longest, string) { + let textWidth = data[string]; + if (!textWidth) { + textWidth = data[string] = ctx.measureText(string).width; + gc.push(string); + } + if (textWidth > longest) { + longest = textWidth; + } + return longest; +} +function _longestText2(ctx, font, arrayOfThings, cache) { + cache = cache || {}; + let data = cache.data = cache.data || {}; + let gc = cache.garbageCollect = cache.garbageCollect || []; + if (cache.font !== font) { + data = cache.data = {}; + gc = cache.garbageCollect = []; + cache.font = font; + } + ctx.save(); + ctx.font = font; + let longest = 0; + const ilen = arrayOfThings.length; + let i, j, jlen, thing, nestedThing; + for (i = 0; i < ilen; i++) { + thing = arrayOfThings[i]; + if (thing !== void 0 && thing !== null && !isArray2(thing)) { + longest = _measureText2(ctx, data, gc, longest, thing); + } else if (isArray2(thing)) { + for (j = 0, jlen = thing.length; j < jlen; j++) { + nestedThing = thing[j]; + if (nestedThing !== void 0 && nestedThing !== null && !isArray2(nestedThing)) { + longest = _measureText2(ctx, data, gc, longest, nestedThing); + } + } + } + } + ctx.restore(); + const gcLen = gc.length / 2; + if (gcLen > arrayOfThings.length) { + for (i = 0; i < gcLen; i++) { + delete data[gc[i]]; + } + gc.splice(0, gcLen); + } + return longest; +} +function _alignPixel2(chart, pixel, width) { + const devicePixelRatio = chart.currentDevicePixelRatio; + const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0; + return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth; +} +function _isPointInArea2(point, area, margin) { + margin = margin || 0.5; + return !area || point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin; +} +function clipArea2(ctx, area) { + ctx.save(); + ctx.beginPath(); + ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); + ctx.clip(); +} +function unclipArea2(ctx) { + ctx.restore(); +} +function setRenderOpts2(ctx, opts) { + if (opts.translation) { + ctx.translate(opts.translation[0], opts.translation[1]); + } + if (!isNullOrUndef2(opts.rotation)) { + ctx.rotate(opts.rotation); + } + if (opts.color) { + ctx.fillStyle = opts.color; + } + if (opts.textAlign) { + ctx.textAlign = opts.textAlign; + } + if (opts.textBaseline) { + ctx.textBaseline = opts.textBaseline; + } +} +function decorateText2(ctx, x, y, line, opts) { + if (opts.strikethrough || opts.underline) { + const metrics = ctx.measureText(line); + const left = x - metrics.actualBoundingBoxLeft; + const right = x + metrics.actualBoundingBoxRight; + const top = y - metrics.actualBoundingBoxAscent; + const bottom = y + metrics.actualBoundingBoxDescent; + const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom; + ctx.strokeStyle = ctx.fillStyle; + ctx.beginPath(); + ctx.lineWidth = opts.decorationWidth || 2; + ctx.moveTo(left, yDecoration); + ctx.lineTo(right, yDecoration); + ctx.stroke(); + } +} +function drawBackdrop2(ctx, opts) { + const oldColor = ctx.fillStyle; + ctx.fillStyle = opts.color; + ctx.fillRect(opts.left, opts.top, opts.width, opts.height); + ctx.fillStyle = oldColor; +} +function renderText2(ctx, text, x, y, font, opts = {}) { + const lines = isArray2(text) ? text : [ + text + ]; + const stroke = opts.strokeWidth > 0 && opts.strokeColor !== ""; + let i, line; + ctx.save(); + ctx.font = font.string; + setRenderOpts2(ctx, opts); + for (i = 0; i < lines.length; ++i) { + line = lines[i]; + if (opts.backdrop) { + drawBackdrop2(ctx, opts.backdrop); + } + if (stroke) { + if (opts.strokeColor) { + ctx.strokeStyle = opts.strokeColor; + } + if (!isNullOrUndef2(opts.strokeWidth)) { + ctx.lineWidth = opts.strokeWidth; + } + ctx.strokeText(line, x, y, opts.maxWidth); + } + ctx.fillText(line, x, y, opts.maxWidth); + decorateText2(ctx, x, y, line, opts); + y += Number(font.lineHeight); + } + ctx.restore(); +} +function addRoundedRectPath2(ctx, rect) { + const { x, y, w, h, radius } = rect; + ctx.arc(x + radius.topLeft, y + radius.topLeft, radius.topLeft, 1.5 * PI2, PI2, true); + ctx.lineTo(x, y + h - radius.bottomLeft); + ctx.arc(x + radius.bottomLeft, y + h - radius.bottomLeft, radius.bottomLeft, PI2, HALF_PI2, true); + ctx.lineTo(x + w - radius.bottomRight, y + h); + ctx.arc(x + w - radius.bottomRight, y + h - radius.bottomRight, radius.bottomRight, HALF_PI2, 0, true); + ctx.lineTo(x + w, y + radius.topRight); + ctx.arc(x + w - radius.topRight, y + radius.topRight, radius.topRight, 0, -HALF_PI2, true); + ctx.lineTo(x + radius.topLeft, y); +} +var LINE_HEIGHT2 = /^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/; +var FONT_STYLE2 = /^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/; +function toLineHeight2(value, size) { + const matches = ("" + value).match(LINE_HEIGHT2); + if (!matches || matches[1] === "normal") { + return size * 1.2; + } + value = +matches[2]; + switch (matches[3]) { + case "px": + return value; + case "%": + value /= 100; + break; + } + return size * value; +} +var numberOrZero2 = (v) => +v || 0; +function _readValueToProps2(value, props) { + const ret = {}; + const objProps = isObject2(props); + const keys = objProps ? Object.keys(props) : props; + const read = isObject2(value) ? objProps ? (prop) => valueOrDefault2(value[prop], value[props[prop]]) : (prop) => value[prop] : () => value; + for (const prop of keys) { + ret[prop] = numberOrZero2(read(prop)); + } + return ret; +} +function toTRBL2(value) { + return _readValueToProps2(value, { + top: "y", + right: "x", + bottom: "y", + left: "x" + }); +} +function toTRBLCorners2(value) { + return _readValueToProps2(value, [ + "topLeft", + "topRight", + "bottomLeft", + "bottomRight" + ]); +} +function toPadding2(value) { + const obj = toTRBL2(value); + obj.width = obj.left + obj.right; + obj.height = obj.top + obj.bottom; + return obj; +} +function toFont2(options, fallback) { + options = options || {}; + fallback = fallback || defaults2.font; + let size = valueOrDefault2(options.size, fallback.size); + if (typeof size === "string") { + size = parseInt(size, 10); + } + let style = valueOrDefault2(options.style, fallback.style); + if (style && !("" + style).match(FONT_STYLE2)) { + console.warn('Invalid font style specified: "' + style + '"'); + style = void 0; + } + const font = { + family: valueOrDefault2(options.family, fallback.family), + lineHeight: toLineHeight2(valueOrDefault2(options.lineHeight, fallback.lineHeight), size), + size, + style, + weight: valueOrDefault2(options.weight, fallback.weight), + string: "" + }; + font.string = toFontString2(font); + return font; +} +function _addGrace2(minmax, grace, beginAtZero) { + const { min, max } = minmax; + const change = toDimension2(grace, (max - min) / 2); + const keepZero = (value, add) => beginAtZero && value === 0 ? 0 : value + add; + return { + min: keepZero(min, -Math.abs(change)), + max: keepZero(max, change) + }; +} +function createContext2(parentContext, context) { + return Object.assign(Object.create(parentContext), context); +} +var EPSILON2 = Number.EPSILON || 1e-14; +function _isDomSupported2() { + return typeof window !== "undefined" && typeof document !== "undefined"; +} +var supportsEventListenerOptions2 = function() { + let passiveSupported = false; + try { + const options = { + get passive() { + passiveSupported = true; + return false; + } + }; + if (_isDomSupported2()) { + window.addEventListener("test", null, options); + window.removeEventListener("test", null, options); + } + } catch (e) { + } + return passiveSupported; +}(); + +// ../../../node_modules/chart.js/dist/chart.js +function abstract2() { + throw new Error("This method is not implemented: Check that a complete date adapter is provided."); +} +var DateAdapterBase2 = class { + constructor(options) { + __publicField(this, "options"); + this.options = options || {}; + } + /** + * Override default date adapter methods. + * Accepts type parameter to define options type. + * @example + * Chart._adapters._date.override<{myAdapterOption: string}>({ + * init() { + * console.log(this.options.myAdapterOption); + * } + * }) + */ + static override(members) { + Object.assign(DateAdapterBase2.prototype, members); + } + // eslint-disable-next-line @typescript-eslint/no-empty-function + init() { + } + formats() { + return abstract2(); + } + parse() { + return abstract2(); + } + format() { + return abstract2(); + } + add() { + return abstract2(); + } + diff() { + return abstract2(); + } + startOf() { + return abstract2(); + } + endOf() { + return abstract2(); + } +}; +var adapters2 = { + _date: DateAdapterBase2 +}; +var Element2 = class { + constructor() { + __publicField(this, "x"); + __publicField(this, "y"); + __publicField(this, "active", false); + __publicField(this, "options"); + __publicField(this, "$animations"); + } + tooltipPosition(useFinalPosition) { + const { x, y } = this.getProps([ + "x", + "y" + ], useFinalPosition); + return { + x, + y + }; + } + hasValue() { + return isNumber2(this.x) && isNumber2(this.y); + } + getProps(props, final) { + const anims = this.$animations; + if (!final || !anims) { + return this; + } + const ret = {}; + props.forEach((prop) => { + ret[prop] = anims[prop] && anims[prop].active() ? anims[prop]._to : this[prop]; + }); + return ret; + } +}; +__publicField(Element2, "defaults", {}); +__publicField(Element2, "defaultRoutes"); +function autoSkip2(scale, ticks) { + const tickOpts = scale.options.ticks; + const determinedMaxTicks = determineMaxTicks2(scale); + const ticksLimit = Math.min(tickOpts.maxTicksLimit || determinedMaxTicks, determinedMaxTicks); + const majorIndices = tickOpts.major.enabled ? getMajorIndices2(ticks) : []; + const numMajorIndices = majorIndices.length; + const first = majorIndices[0]; + const last = majorIndices[numMajorIndices - 1]; + const newTicks = []; + if (numMajorIndices > ticksLimit) { + skipMajors2(ticks, newTicks, majorIndices, numMajorIndices / ticksLimit); + return newTicks; + } + const spacing = calculateSpacing2(majorIndices, ticks, ticksLimit); + if (numMajorIndices > 0) { + let i, ilen; + const avgMajorSpacing = numMajorIndices > 1 ? Math.round((last - first) / (numMajorIndices - 1)) : null; + skip2(ticks, newTicks, spacing, isNullOrUndef2(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first); + for (i = 0, ilen = numMajorIndices - 1; i < ilen; i++) { + skip2(ticks, newTicks, spacing, majorIndices[i], majorIndices[i + 1]); + } + skip2(ticks, newTicks, spacing, last, isNullOrUndef2(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing); + return newTicks; + } + skip2(ticks, newTicks, spacing); + return newTicks; +} +function determineMaxTicks2(scale) { + const offset2 = scale.options.offset; + const tickLength = scale._tickSize(); + const maxScale = scale._length / tickLength + (offset2 ? 0 : 1); + const maxChart = scale._maxLength / tickLength; + return Math.floor(Math.min(maxScale, maxChart)); +} +function calculateSpacing2(majorIndices, ticks, ticksLimit) { + const evenMajorSpacing = getEvenSpacing2(majorIndices); + const spacing = ticks.length / ticksLimit; + if (!evenMajorSpacing) { + return Math.max(spacing, 1); + } + const factors = _factorize2(evenMajorSpacing); + for (let i = 0, ilen = factors.length - 1; i < ilen; i++) { + const factor = factors[i]; + if (factor > spacing) { + return factor; + } + } + return Math.max(spacing, 1); +} +function getMajorIndices2(ticks) { + const result = []; + let i, ilen; + for (i = 0, ilen = ticks.length; i < ilen; i++) { + if (ticks[i].major) { + result.push(i); + } + } + return result; +} +function skipMajors2(ticks, newTicks, majorIndices, spacing) { + let count = 0; + let next = majorIndices[0]; + let i; + spacing = Math.ceil(spacing); + for (i = 0; i < ticks.length; i++) { + if (i === next) { + newTicks.push(ticks[i]); + count++; + next = majorIndices[count * spacing]; + } + } +} +function skip2(ticks, newTicks, spacing, majorStart, majorEnd) { + const start = valueOrDefault2(majorStart, 0); + const end = Math.min(valueOrDefault2(majorEnd, ticks.length), ticks.length); + let count = 0; + let length, i, next; + spacing = Math.ceil(spacing); + if (majorEnd) { + length = majorEnd - majorStart; + spacing = length / Math.floor(length / spacing); + } + next = start; + while (next < 0) { + count++; + next = Math.round(start + count * spacing); + } + for (i = Math.max(start, 0); i < end; i++) { + if (i === next) { + newTicks.push(ticks[i]); + count++; + next = Math.round(start + count * spacing); + } + } +} +function getEvenSpacing2(arr) { + const len = arr.length; + let i, diff; + if (len < 2) { + return false; + } + for (diff = arr[0], i = 1; i < len; ++i) { + if (arr[i] - arr[i - 1] !== diff) { + return false; + } + } + return diff; +} +var reverseAlign2 = (align) => align === "left" ? "right" : align === "right" ? "left" : align; +var offsetFromEdge2 = (scale, edge, offset2) => edge === "top" || edge === "left" ? scale[edge] + offset2 : scale[edge] - offset2; +var getTicksLimit2 = (ticksLength, maxTicksLimit) => Math.min(maxTicksLimit || ticksLength, ticksLength); +function sample2(arr, numItems) { + const result = []; + const increment = arr.length / numItems; + const len = arr.length; + let i = 0; + for (; i < len; i += increment) { + result.push(arr[Math.floor(i)]); + } + return result; +} +function getPixelForGridLine2(scale, index2, offsetGridLines) { + const length = scale.ticks.length; + const validIndex2 = Math.min(index2, length - 1); + const start = scale._startPixel; + const end = scale._endPixel; + const epsilon = 1e-6; + let lineValue = scale.getPixelForTick(validIndex2); + let offset2; + if (offsetGridLines) { + if (length === 1) { + offset2 = Math.max(lineValue - start, end - lineValue); + } else if (index2 === 0) { + offset2 = (scale.getPixelForTick(1) - lineValue) / 2; + } else { + offset2 = (lineValue - scale.getPixelForTick(validIndex2 - 1)) / 2; + } + lineValue += validIndex2 < index2 ? offset2 : -offset2; + if (lineValue < start - epsilon || lineValue > end + epsilon) { + return; + } + } + return lineValue; +} +function garbageCollect2(caches, length) { + each2(caches, (cache) => { + const gc = cache.gc; + const gcLen = gc.length / 2; + let i; + if (gcLen > length) { + for (i = 0; i < gcLen; ++i) { + delete cache.data[gc[i]]; + } + gc.splice(0, gcLen); + } + }); +} +function getTickMarkLength2(options) { + return options.drawTicks ? options.tickLength : 0; +} +function getTitleHeight2(options, fallback) { + if (!options.display) { + return 0; + } + const font = toFont2(options.font, fallback); + const padding = toPadding2(options.padding); + const lines = isArray2(options.text) ? options.text.length : 1; + return lines * font.lineHeight + padding.height; +} +function createScaleContext2(parent, scale) { + return createContext2(parent, { + scale, + type: "scale" + }); +} +function createTickContext2(parent, index2, tick) { + return createContext2(parent, { + tick, + index: index2, + type: "tick" + }); +} +function titleAlign2(align, position, reverse) { + let ret = _toLeftRightCenter2(align); + if (reverse && position !== "right" || !reverse && position === "right") { + ret = reverseAlign2(ret); + } + return ret; +} +function titleArgs2(scale, offset2, position, align) { + const { top, left, bottom, right, chart } = scale; + const { chartArea, scales: scales2 } = chart; + let rotation = 0; + let maxWidth, titleX, titleY; + const height = bottom - top; + const width = right - left; + if (scale.isHorizontal()) { + titleX = _alignStartEnd2(align, left, right); + if (isObject2(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + titleY = scales2[positionAxisID].getPixelForValue(value) + height - offset2; + } else if (position === "center") { + titleY = (chartArea.bottom + chartArea.top) / 2 + height - offset2; + } else { + titleY = offsetFromEdge2(scale, position, offset2); + } + maxWidth = right - left; + } else { + if (isObject2(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + titleX = scales2[positionAxisID].getPixelForValue(value) - width + offset2; + } else if (position === "center") { + titleX = (chartArea.left + chartArea.right) / 2 - width + offset2; + } else { + titleX = offsetFromEdge2(scale, position, offset2); + } + titleY = _alignStartEnd2(align, bottom, top); + rotation = position === "left" ? -HALF_PI2 : HALF_PI2; + } + return { + titleX, + titleY, + maxWidth, + rotation + }; +} +var Scale2 = class extends Element2 { + constructor(cfg) { + super(); + this.id = cfg.id; + this.type = cfg.type; + this.options = void 0; + this.ctx = cfg.ctx; + this.chart = cfg.chart; + this.top = void 0; + this.bottom = void 0; + this.left = void 0; + this.right = void 0; + this.width = void 0; + this.height = void 0; + this._margins = { + left: 0, + right: 0, + top: 0, + bottom: 0 + }; + this.maxWidth = void 0; + this.maxHeight = void 0; + this.paddingTop = void 0; + this.paddingBottom = void 0; + this.paddingLeft = void 0; + this.paddingRight = void 0; + this.axis = void 0; + this.labelRotation = void 0; + this.min = void 0; + this.max = void 0; + this._range = void 0; + this.ticks = []; + this._gridLineItems = null; + this._labelItems = null; + this._labelSizes = null; + this._length = 0; + this._maxLength = 0; + this._longestTextCache = {}; + this._startPixel = void 0; + this._endPixel = void 0; + this._reversePixels = false; + this._userMax = void 0; + this._userMin = void 0; + this._suggestedMax = void 0; + this._suggestedMin = void 0; + this._ticksLength = 0; + this._borderValue = 0; + this._cache = {}; + this._dataLimitsCached = false; + this.$context = void 0; + } + init(options) { + this.options = options.setContext(this.getContext()); + this.axis = options.axis; + this._userMin = this.parse(options.min); + this._userMax = this.parse(options.max); + this._suggestedMin = this.parse(options.suggestedMin); + this._suggestedMax = this.parse(options.suggestedMax); + } + parse(raw, index2) { + return raw; + } + getUserBounds() { + let { _userMin, _userMax, _suggestedMin, _suggestedMax } = this; + _userMin = finiteOrDefault2(_userMin, Number.POSITIVE_INFINITY); + _userMax = finiteOrDefault2(_userMax, Number.NEGATIVE_INFINITY); + _suggestedMin = finiteOrDefault2(_suggestedMin, Number.POSITIVE_INFINITY); + _suggestedMax = finiteOrDefault2(_suggestedMax, Number.NEGATIVE_INFINITY); + return { + min: finiteOrDefault2(_userMin, _suggestedMin), + max: finiteOrDefault2(_userMax, _suggestedMax), + minDefined: isNumberFinite2(_userMin), + maxDefined: isNumberFinite2(_userMax) + }; + } + getMinMax(canStack) { + let { min, max, minDefined, maxDefined } = this.getUserBounds(); + let range; + if (minDefined && maxDefined) { + return { + min, + max + }; + } + const metas = this.getMatchingVisibleMetas(); + for (let i = 0, ilen = metas.length; i < ilen; ++i) { + range = metas[i].controller.getMinMax(this, canStack); + if (!minDefined) { + min = Math.min(min, range.min); + } + if (!maxDefined) { + max = Math.max(max, range.max); + } + } + min = maxDefined && min > max ? max : min; + max = minDefined && min > max ? min : max; + return { + min: finiteOrDefault2(min, finiteOrDefault2(max, min)), + max: finiteOrDefault2(max, finiteOrDefault2(min, max)) + }; + } + getPadding() { + return { + left: this.paddingLeft || 0, + top: this.paddingTop || 0, + right: this.paddingRight || 0, + bottom: this.paddingBottom || 0 + }; + } + getTicks() { + return this.ticks; + } + getLabels() { + const data = this.chart.data; + return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || []; + } + getLabelItems(chartArea = this.chart.chartArea) { + const items = this._labelItems || (this._labelItems = this._computeLabelItems(chartArea)); + return items; + } + beforeLayout() { + this._cache = {}; + this._dataLimitsCached = false; + } + beforeUpdate() { + callback2(this.options.beforeUpdate, [ + this + ]); + } + update(maxWidth, maxHeight, margins) { + const { beginAtZero, grace, ticks: tickOpts } = this.options; + const sampleSize = tickOpts.sampleSize; + this.beforeUpdate(); + this.maxWidth = maxWidth; + this.maxHeight = maxHeight; + this._margins = margins = Object.assign({ + left: 0, + right: 0, + top: 0, + bottom: 0 + }, margins); + this.ticks = null; + this._labelSizes = null; + this._gridLineItems = null; + this._labelItems = null; + this.beforeSetDimensions(); + this.setDimensions(); + this.afterSetDimensions(); + this._maxLength = this.isHorizontal() ? this.width + margins.left + margins.right : this.height + margins.top + margins.bottom; + if (!this._dataLimitsCached) { + this.beforeDataLimits(); + this.determineDataLimits(); + this.afterDataLimits(); + this._range = _addGrace2(this, grace, beginAtZero); + this._dataLimitsCached = true; + } + this.beforeBuildTicks(); + this.ticks = this.buildTicks() || []; + this.afterBuildTicks(); + const samplingEnabled = sampleSize < this.ticks.length; + this._convertTicksToLabels(samplingEnabled ? sample2(this.ticks, sampleSize) : this.ticks); + this.configure(); + this.beforeCalculateLabelRotation(); + this.calculateLabelRotation(); + this.afterCalculateLabelRotation(); + if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === "auto")) { + this.ticks = autoSkip2(this, this.ticks); + this._labelSizes = null; + this.afterAutoSkip(); + } + if (samplingEnabled) { + this._convertTicksToLabels(this.ticks); + } + this.beforeFit(); + this.fit(); + this.afterFit(); + this.afterUpdate(); + } + configure() { + let reversePixels = this.options.reverse; + let startPixel, endPixel; + if (this.isHorizontal()) { + startPixel = this.left; + endPixel = this.right; + } else { + startPixel = this.top; + endPixel = this.bottom; + reversePixels = !reversePixels; + } + this._startPixel = startPixel; + this._endPixel = endPixel; + this._reversePixels = reversePixels; + this._length = endPixel - startPixel; + this._alignToPixels = this.options.alignToPixels; + } + afterUpdate() { + callback2(this.options.afterUpdate, [ + this + ]); + } + beforeSetDimensions() { + callback2(this.options.beforeSetDimensions, [ + this + ]); + } + setDimensions() { + if (this.isHorizontal()) { + this.width = this.maxWidth; + this.left = 0; + this.right = this.width; + } else { + this.height = this.maxHeight; + this.top = 0; + this.bottom = this.height; + } + this.paddingLeft = 0; + this.paddingTop = 0; + this.paddingRight = 0; + this.paddingBottom = 0; + } + afterSetDimensions() { + callback2(this.options.afterSetDimensions, [ + this + ]); + } + _callHooks(name) { + this.chart.notifyPlugins(name, this.getContext()); + callback2(this.options[name], [ + this + ]); + } + beforeDataLimits() { + this._callHooks("beforeDataLimits"); + } + determineDataLimits() { + } + afterDataLimits() { + this._callHooks("afterDataLimits"); + } + beforeBuildTicks() { + this._callHooks("beforeBuildTicks"); + } + buildTicks() { + return []; + } + afterBuildTicks() { + this._callHooks("afterBuildTicks"); + } + beforeTickToLabelConversion() { + callback2(this.options.beforeTickToLabelConversion, [ + this + ]); + } + generateTickLabels(ticks) { + const tickOpts = this.options.ticks; + let i, ilen, tick; + for (i = 0, ilen = ticks.length; i < ilen; i++) { + tick = ticks[i]; + tick.label = callback2(tickOpts.callback, [ + tick.value, + i, + ticks + ], this); + } + } + afterTickToLabelConversion() { + callback2(this.options.afterTickToLabelConversion, [ + this + ]); + } + beforeCalculateLabelRotation() { + callback2(this.options.beforeCalculateLabelRotation, [ + this + ]); + } + calculateLabelRotation() { + const options = this.options; + const tickOpts = options.ticks; + const numTicks = getTicksLimit2(this.ticks.length, options.ticks.maxTicksLimit); + const minRotation = tickOpts.minRotation || 0; + const maxRotation = tickOpts.maxRotation; + let labelRotation = minRotation; + let tickWidth, maxHeight, maxLabelDiagonal; + if (!this._isVisible() || !tickOpts.display || minRotation >= maxRotation || numTicks <= 1 || !this.isHorizontal()) { + this.labelRotation = minRotation; + return; + } + const labelSizes = this._getLabelSizes(); + const maxLabelWidth = labelSizes.widest.width; + const maxLabelHeight = labelSizes.highest.height; + const maxWidth = _limitValue2(this.chart.width - maxLabelWidth, 0, this.maxWidth); + tickWidth = options.offset ? this.maxWidth / numTicks : maxWidth / (numTicks - 1); + if (maxLabelWidth + 6 > tickWidth) { + tickWidth = maxWidth / (numTicks - (options.offset ? 0.5 : 1)); + maxHeight = this.maxHeight - getTickMarkLength2(options.grid) - tickOpts.padding - getTitleHeight2(options.title, this.chart.options.font); + maxLabelDiagonal = Math.sqrt(maxLabelWidth * maxLabelWidth + maxLabelHeight * maxLabelHeight); + labelRotation = toDegrees2(Math.min(Math.asin(_limitValue2((labelSizes.highest.height + 6) / tickWidth, -1, 1)), Math.asin(_limitValue2(maxHeight / maxLabelDiagonal, -1, 1)) - Math.asin(_limitValue2(maxLabelHeight / maxLabelDiagonal, -1, 1)))); + labelRotation = Math.max(minRotation, Math.min(maxRotation, labelRotation)); + } + this.labelRotation = labelRotation; + } + afterCalculateLabelRotation() { + callback2(this.options.afterCalculateLabelRotation, [ + this + ]); + } + afterAutoSkip() { + } + beforeFit() { + callback2(this.options.beforeFit, [ + this + ]); + } + fit() { + const minSize = { + width: 0, + height: 0 + }; + const { chart, options: { ticks: tickOpts, title: titleOpts, grid: gridOpts } } = this; + const display = this._isVisible(); + const isHorizontal = this.isHorizontal(); + if (display) { + const titleHeight = getTitleHeight2(titleOpts, chart.options.font); + if (isHorizontal) { + minSize.width = this.maxWidth; + minSize.height = getTickMarkLength2(gridOpts) + titleHeight; + } else { + minSize.height = this.maxHeight; + minSize.width = getTickMarkLength2(gridOpts) + titleHeight; + } + if (tickOpts.display && this.ticks.length) { + const { first, last, widest, highest } = this._getLabelSizes(); + const tickPadding = tickOpts.padding * 2; + const angleRadians = toRadians2(this.labelRotation); + const cos = Math.cos(angleRadians); + const sin = Math.sin(angleRadians); + if (isHorizontal) { + const labelHeight = tickOpts.mirror ? 0 : sin * widest.width + cos * highest.height; + minSize.height = Math.min(this.maxHeight, minSize.height + labelHeight + tickPadding); + } else { + const labelWidth = tickOpts.mirror ? 0 : cos * widest.width + sin * highest.height; + minSize.width = Math.min(this.maxWidth, minSize.width + labelWidth + tickPadding); + } + this._calculatePadding(first, last, sin, cos); + } + } + this._handleMargins(); + if (isHorizontal) { + this.width = this._length = chart.width - this._margins.left - this._margins.right; + this.height = minSize.height; + } else { + this.width = minSize.width; + this.height = this._length = chart.height - this._margins.top - this._margins.bottom; + } + } + _calculatePadding(first, last, sin, cos) { + const { ticks: { align, padding }, position } = this.options; + const isRotated = this.labelRotation !== 0; + const labelsBelowTicks = position !== "top" && this.axis === "x"; + if (this.isHorizontal()) { + const offsetLeft = this.getPixelForTick(0) - this.left; + const offsetRight = this.right - this.getPixelForTick(this.ticks.length - 1); + let paddingLeft = 0; + let paddingRight = 0; + if (isRotated) { + if (labelsBelowTicks) { + paddingLeft = cos * first.width; + paddingRight = sin * last.height; + } else { + paddingLeft = sin * first.height; + paddingRight = cos * last.width; + } + } else if (align === "start") { + paddingRight = last.width; + } else if (align === "end") { + paddingLeft = first.width; + } else if (align !== "inner") { + paddingLeft = first.width / 2; + paddingRight = last.width / 2; + } + this.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * this.width / (this.width - offsetLeft), 0); + this.paddingRight = Math.max((paddingRight - offsetRight + padding) * this.width / (this.width - offsetRight), 0); + } else { + let paddingTop = last.height / 2; + let paddingBottom = first.height / 2; + if (align === "start") { + paddingTop = 0; + paddingBottom = first.height; + } else if (align === "end") { + paddingTop = last.height; + paddingBottom = 0; + } + this.paddingTop = paddingTop + padding; + this.paddingBottom = paddingBottom + padding; + } + } + _handleMargins() { + if (this._margins) { + this._margins.left = Math.max(this.paddingLeft, this._margins.left); + this._margins.top = Math.max(this.paddingTop, this._margins.top); + this._margins.right = Math.max(this.paddingRight, this._margins.right); + this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom); + } + } + afterFit() { + callback2(this.options.afterFit, [ + this + ]); + } + isHorizontal() { + const { axis, position } = this.options; + return position === "top" || position === "bottom" || axis === "x"; + } + isFullSize() { + return this.options.fullSize; + } + _convertTicksToLabels(ticks) { + this.beforeTickToLabelConversion(); + this.generateTickLabels(ticks); + let i, ilen; + for (i = 0, ilen = ticks.length; i < ilen; i++) { + if (isNullOrUndef2(ticks[i].label)) { + ticks.splice(i, 1); + ilen--; + i--; + } + } + this.afterTickToLabelConversion(); + } + _getLabelSizes() { + let labelSizes = this._labelSizes; + if (!labelSizes) { + const sampleSize = this.options.ticks.sampleSize; + let ticks = this.ticks; + if (sampleSize < ticks.length) { + ticks = sample2(ticks, sampleSize); + } + this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length, this.options.ticks.maxTicksLimit); + } + return labelSizes; + } + _computeLabelSizes(ticks, length, maxTicksLimit) { + const { ctx, _longestTextCache: caches } = this; + const widths = []; + const heights = []; + const increment = Math.floor(length / getTicksLimit2(length, maxTicksLimit)); + let widestLabelSize = 0; + let highestLabelSize = 0; + let i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel; + for (i = 0; i < length; i += increment) { + label = ticks[i].label; + tickFont = this._resolveTickFontOptions(i); + ctx.font = fontString = tickFont.string; + cache = caches[fontString] = caches[fontString] || { + data: {}, + gc: [] + }; + lineHeight = tickFont.lineHeight; + width = height = 0; + if (!isNullOrUndef2(label) && !isArray2(label)) { + width = _measureText2(ctx, cache.data, cache.gc, width, label); + height = lineHeight; + } else if (isArray2(label)) { + for (j = 0, jlen = label.length; j < jlen; ++j) { + nestedLabel = label[j]; + if (!isNullOrUndef2(nestedLabel) && !isArray2(nestedLabel)) { + width = _measureText2(ctx, cache.data, cache.gc, width, nestedLabel); + height += lineHeight; + } + } + } + widths.push(width); + heights.push(height); + widestLabelSize = Math.max(width, widestLabelSize); + highestLabelSize = Math.max(height, highestLabelSize); + } + garbageCollect2(caches, length); + const widest = widths.indexOf(widestLabelSize); + const highest = heights.indexOf(highestLabelSize); + const valueAt = (idx) => ({ + width: widths[idx] || 0, + height: heights[idx] || 0 + }); + return { + first: valueAt(0), + last: valueAt(length - 1), + widest: valueAt(widest), + highest: valueAt(highest), + widths, + heights + }; + } + getLabelForValue(value) { + return value; + } + getPixelForValue(value, index2) { + return NaN; + } + getValueForPixel(pixel) { + } + getPixelForTick(index2) { + const ticks = this.ticks; + if (index2 < 0 || index2 > ticks.length - 1) { + return null; + } + return this.getPixelForValue(ticks[index2].value); + } + getPixelForDecimal(decimal) { + if (this._reversePixels) { + decimal = 1 - decimal; + } + const pixel = this._startPixel + decimal * this._length; + return _int16Range2(this._alignToPixels ? _alignPixel2(this.chart, pixel, 0) : pixel); + } + getDecimalForPixel(pixel) { + const decimal = (pixel - this._startPixel) / this._length; + return this._reversePixels ? 1 - decimal : decimal; + } + getBasePixel() { + return this.getPixelForValue(this.getBaseValue()); + } + getBaseValue() { + const { min, max } = this; + return min < 0 && max < 0 ? max : min > 0 && max > 0 ? min : 0; + } + getContext(index2) { + const ticks = this.ticks || []; + if (index2 >= 0 && index2 < ticks.length) { + const tick = ticks[index2]; + return tick.$context || (tick.$context = createTickContext2(this.getContext(), index2, tick)); + } + return this.$context || (this.$context = createScaleContext2(this.chart.getContext(), this)); + } + _tickSize() { + const optionTicks = this.options.ticks; + const rot = toRadians2(this.labelRotation); + const cos = Math.abs(Math.cos(rot)); + const sin = Math.abs(Math.sin(rot)); + const labelSizes = this._getLabelSizes(); + const padding = optionTicks.autoSkipPadding || 0; + const w = labelSizes ? labelSizes.widest.width + padding : 0; + const h = labelSizes ? labelSizes.highest.height + padding : 0; + return this.isHorizontal() ? h * cos > w * sin ? w / cos : h / sin : h * sin < w * cos ? h / cos : w / sin; + } + _isVisible() { + const display = this.options.display; + if (display !== "auto") { + return !!display; + } + return this.getMatchingVisibleMetas().length > 0; + } + _computeGridLineItems(chartArea) { + const axis = this.axis; + const chart = this.chart; + const options = this.options; + const { grid, position, border } = options; + const offset2 = grid.offset; + const isHorizontal = this.isHorizontal(); + const ticks = this.ticks; + const ticksLength = ticks.length + (offset2 ? 1 : 0); + const tl = getTickMarkLength2(grid); + const items = []; + const borderOpts = border.setContext(this.getContext()); + const axisWidth = borderOpts.display ? borderOpts.width : 0; + const axisHalfWidth = axisWidth / 2; + const alignBorderValue = function(pixel) { + return _alignPixel2(chart, pixel, axisWidth); + }; + let borderValue, i, lineValue, alignedLineValue; + let tx1, ty1, tx2, ty2, x1, y1, x2, y2; + if (position === "top") { + borderValue = alignBorderValue(this.bottom); + ty1 = this.bottom - tl; + ty2 = borderValue - axisHalfWidth; + y1 = alignBorderValue(chartArea.top) + axisHalfWidth; + y2 = chartArea.bottom; + } else if (position === "bottom") { + borderValue = alignBorderValue(this.top); + y1 = chartArea.top; + y2 = alignBorderValue(chartArea.bottom) - axisHalfWidth; + ty1 = borderValue + axisHalfWidth; + ty2 = this.top + tl; + } else if (position === "left") { + borderValue = alignBorderValue(this.right); + tx1 = this.right - tl; + tx2 = borderValue - axisHalfWidth; + x1 = alignBorderValue(chartArea.left) + axisHalfWidth; + x2 = chartArea.right; + } else if (position === "right") { + borderValue = alignBorderValue(this.left); + x1 = chartArea.left; + x2 = alignBorderValue(chartArea.right) - axisHalfWidth; + tx1 = borderValue + axisHalfWidth; + tx2 = this.left + tl; + } else if (axis === "x") { + if (position === "center") { + borderValue = alignBorderValue((chartArea.top + chartArea.bottom) / 2 + 0.5); + } else if (isObject2(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value)); + } + y1 = chartArea.top; + y2 = chartArea.bottom; + ty1 = borderValue + axisHalfWidth; + ty2 = ty1 + tl; + } else if (axis === "y") { + if (position === "center") { + borderValue = alignBorderValue((chartArea.left + chartArea.right) / 2); + } else if (isObject2(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value)); + } + tx1 = borderValue - axisHalfWidth; + tx2 = tx1 - tl; + x1 = chartArea.left; + x2 = chartArea.right; + } + const limit = valueOrDefault2(options.ticks.maxTicksLimit, ticksLength); + const step = Math.max(1, Math.ceil(ticksLength / limit)); + for (i = 0; i < ticksLength; i += step) { + const context = this.getContext(i); + const optsAtIndex = grid.setContext(context); + const optsAtIndexBorder = border.setContext(context); + const lineWidth = optsAtIndex.lineWidth; + const lineColor = optsAtIndex.color; + const borderDash = optsAtIndexBorder.dash || []; + const borderDashOffset = optsAtIndexBorder.dashOffset; + const tickWidth = optsAtIndex.tickWidth; + const tickColor = optsAtIndex.tickColor; + const tickBorderDash = optsAtIndex.tickBorderDash || []; + const tickBorderDashOffset = optsAtIndex.tickBorderDashOffset; + lineValue = getPixelForGridLine2(this, i, offset2); + if (lineValue === void 0) { + continue; + } + alignedLineValue = _alignPixel2(chart, lineValue, lineWidth); + if (isHorizontal) { + tx1 = tx2 = x1 = x2 = alignedLineValue; + } else { + ty1 = ty2 = y1 = y2 = alignedLineValue; + } + items.push({ + tx1, + ty1, + tx2, + ty2, + x1, + y1, + x2, + y2, + width: lineWidth, + color: lineColor, + borderDash, + borderDashOffset, + tickWidth, + tickColor, + tickBorderDash, + tickBorderDashOffset + }); + } + this._ticksLength = ticksLength; + this._borderValue = borderValue; + return items; + } + _computeLabelItems(chartArea) { + const axis = this.axis; + const options = this.options; + const { position, ticks: optionTicks } = options; + const isHorizontal = this.isHorizontal(); + const ticks = this.ticks; + const { align, crossAlign, padding, mirror } = optionTicks; + const tl = getTickMarkLength2(options.grid); + const tickAndPadding = tl + padding; + const hTickAndPadding = mirror ? -padding : tickAndPadding; + const rotation = -toRadians2(this.labelRotation); + const items = []; + let i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset; + let textBaseline = "middle"; + if (position === "top") { + y = this.bottom - hTickAndPadding; + textAlign = this._getXAxisLabelAlignment(); + } else if (position === "bottom") { + y = this.top + hTickAndPadding; + textAlign = this._getXAxisLabelAlignment(); + } else if (position === "left") { + const ret = this._getYAxisLabelAlignment(tl); + textAlign = ret.textAlign; + x = ret.x; + } else if (position === "right") { + const ret = this._getYAxisLabelAlignment(tl); + textAlign = ret.textAlign; + x = ret.x; + } else if (axis === "x") { + if (position === "center") { + y = (chartArea.top + chartArea.bottom) / 2 + tickAndPadding; + } else if (isObject2(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + y = this.chart.scales[positionAxisID].getPixelForValue(value) + tickAndPadding; + } + textAlign = this._getXAxisLabelAlignment(); + } else if (axis === "y") { + if (position === "center") { + x = (chartArea.left + chartArea.right) / 2 - tickAndPadding; + } else if (isObject2(position)) { + const positionAxisID = Object.keys(position)[0]; + const value = position[positionAxisID]; + x = this.chart.scales[positionAxisID].getPixelForValue(value); + } + textAlign = this._getYAxisLabelAlignment(tl).textAlign; + } + if (axis === "y") { + if (align === "start") { + textBaseline = "top"; + } else if (align === "end") { + textBaseline = "bottom"; + } + } + const labelSizes = this._getLabelSizes(); + for (i = 0, ilen = ticks.length; i < ilen; ++i) { + tick = ticks[i]; + label = tick.label; + const optsAtIndex = optionTicks.setContext(this.getContext(i)); + pixel = this.getPixelForTick(i) + optionTicks.labelOffset; + font = this._resolveTickFontOptions(i); + lineHeight = font.lineHeight; + lineCount = isArray2(label) ? label.length : 1; + const halfCount = lineCount / 2; + const color3 = optsAtIndex.color; + const strokeColor = optsAtIndex.textStrokeColor; + const strokeWidth = optsAtIndex.textStrokeWidth; + let tickTextAlign = textAlign; + if (isHorizontal) { + x = pixel; + if (textAlign === "inner") { + if (i === ilen - 1) { + tickTextAlign = !this.options.reverse ? "right" : "left"; + } else if (i === 0) { + tickTextAlign = !this.options.reverse ? "left" : "right"; + } else { + tickTextAlign = "center"; + } + } + if (position === "top") { + if (crossAlign === "near" || rotation !== 0) { + textOffset = -lineCount * lineHeight + lineHeight / 2; + } else if (crossAlign === "center") { + textOffset = -labelSizes.highest.height / 2 - halfCount * lineHeight + lineHeight; + } else { + textOffset = -labelSizes.highest.height + lineHeight / 2; + } + } else { + if (crossAlign === "near" || rotation !== 0) { + textOffset = lineHeight / 2; + } else if (crossAlign === "center") { + textOffset = labelSizes.highest.height / 2 - halfCount * lineHeight; + } else { + textOffset = labelSizes.highest.height - lineCount * lineHeight; + } + } + if (mirror) { + textOffset *= -1; + } + if (rotation !== 0 && !optsAtIndex.showLabelBackdrop) { + x += lineHeight / 2 * Math.sin(rotation); + } + } else { + y = pixel; + textOffset = (1 - lineCount) * lineHeight / 2; + } + let backdrop; + if (optsAtIndex.showLabelBackdrop) { + const labelPadding = toPadding2(optsAtIndex.backdropPadding); + const height = labelSizes.heights[i]; + const width = labelSizes.widths[i]; + let top = textOffset - labelPadding.top; + let left = 0 - labelPadding.left; + switch (textBaseline) { + case "middle": + top -= height / 2; + break; + case "bottom": + top -= height; + break; + } + switch (textAlign) { + case "center": + left -= width / 2; + break; + case "right": + left -= width; + break; + case "inner": + if (i === ilen - 1) { + left -= width; + } else if (i > 0) { + left -= width / 2; + } + break; + } + backdrop = { + left, + top, + width: width + labelPadding.width, + height: height + labelPadding.height, + color: optsAtIndex.backdropColor + }; + } + items.push({ + label, + font, + textOffset, + options: { + rotation, + color: color3, + strokeColor, + strokeWidth, + textAlign: tickTextAlign, + textBaseline, + translation: [ + x, + y + ], + backdrop + } + }); + } + return items; + } + _getXAxisLabelAlignment() { + const { position, ticks } = this.options; + const rotation = -toRadians2(this.labelRotation); + if (rotation) { + return position === "top" ? "left" : "right"; + } + let align = "center"; + if (ticks.align === "start") { + align = "left"; + } else if (ticks.align === "end") { + align = "right"; + } else if (ticks.align === "inner") { + align = "inner"; + } + return align; + } + _getYAxisLabelAlignment(tl) { + const { position, ticks: { crossAlign, mirror, padding } } = this.options; + const labelSizes = this._getLabelSizes(); + const tickAndPadding = tl + padding; + const widest = labelSizes.widest.width; + let textAlign; + let x; + if (position === "left") { + if (mirror) { + x = this.right + padding; + if (crossAlign === "near") { + textAlign = "left"; + } else if (crossAlign === "center") { + textAlign = "center"; + x += widest / 2; + } else { + textAlign = "right"; + x += widest; + } + } else { + x = this.right - tickAndPadding; + if (crossAlign === "near") { + textAlign = "right"; + } else if (crossAlign === "center") { + textAlign = "center"; + x -= widest / 2; + } else { + textAlign = "left"; + x = this.left; + } + } + } else if (position === "right") { + if (mirror) { + x = this.left + padding; + if (crossAlign === "near") { + textAlign = "right"; + } else if (crossAlign === "center") { + textAlign = "center"; + x -= widest / 2; + } else { + textAlign = "left"; + x -= widest; + } + } else { + x = this.left + tickAndPadding; + if (crossAlign === "near") { + textAlign = "left"; + } else if (crossAlign === "center") { + textAlign = "center"; + x += widest / 2; + } else { + textAlign = "right"; + x = this.right; + } + } + } else { + textAlign = "right"; + } + return { + textAlign, + x + }; + } + _computeLabelArea() { + if (this.options.ticks.mirror) { + return; + } + const chart = this.chart; + const position = this.options.position; + if (position === "left" || position === "right") { + return { + top: 0, + left: this.left, + bottom: chart.height, + right: this.right + }; + } + if (position === "top" || position === "bottom") { + return { + top: this.top, + left: 0, + bottom: this.bottom, + right: chart.width + }; + } + } + drawBackground() { + const { ctx, options: { backgroundColor }, left, top, width, height } = this; + if (backgroundColor) { + ctx.save(); + ctx.fillStyle = backgroundColor; + ctx.fillRect(left, top, width, height); + ctx.restore(); + } + } + getLineWidthForValue(value) { + const grid = this.options.grid; + if (!this._isVisible() || !grid.display) { + return 0; + } + const ticks = this.ticks; + const index2 = ticks.findIndex((t) => t.value === value); + if (index2 >= 0) { + const opts = grid.setContext(this.getContext(index2)); + return opts.lineWidth; + } + return 0; + } + drawGrid(chartArea) { + const grid = this.options.grid; + const ctx = this.ctx; + const items = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(chartArea)); + let i, ilen; + const drawLine = (p1, p2, style) => { + if (!style.width || !style.color) { + return; + } + ctx.save(); + ctx.lineWidth = style.width; + ctx.strokeStyle = style.color; + ctx.setLineDash(style.borderDash || []); + ctx.lineDashOffset = style.borderDashOffset; + ctx.beginPath(); + ctx.moveTo(p1.x, p1.y); + ctx.lineTo(p2.x, p2.y); + ctx.stroke(); + ctx.restore(); + }; + if (grid.display) { + for (i = 0, ilen = items.length; i < ilen; ++i) { + const item = items[i]; + if (grid.drawOnChartArea) { + drawLine({ + x: item.x1, + y: item.y1 + }, { + x: item.x2, + y: item.y2 + }, item); + } + if (grid.drawTicks) { + drawLine({ + x: item.tx1, + y: item.ty1 + }, { + x: item.tx2, + y: item.ty2 + }, { + color: item.tickColor, + width: item.tickWidth, + borderDash: item.tickBorderDash, + borderDashOffset: item.tickBorderDashOffset + }); + } + } + } + } + drawBorder() { + const { chart, ctx, options: { border, grid } } = this; + const borderOpts = border.setContext(this.getContext()); + const axisWidth = border.display ? borderOpts.width : 0; + if (!axisWidth) { + return; + } + const lastLineWidth = grid.setContext(this.getContext(0)).lineWidth; + const borderValue = this._borderValue; + let x1, x2, y1, y2; + if (this.isHorizontal()) { + x1 = _alignPixel2(chart, this.left, axisWidth) - axisWidth / 2; + x2 = _alignPixel2(chart, this.right, lastLineWidth) + lastLineWidth / 2; + y1 = y2 = borderValue; + } else { + y1 = _alignPixel2(chart, this.top, axisWidth) - axisWidth / 2; + y2 = _alignPixel2(chart, this.bottom, lastLineWidth) + lastLineWidth / 2; + x1 = x2 = borderValue; + } + ctx.save(); + ctx.lineWidth = borderOpts.width; + ctx.strokeStyle = borderOpts.color; + ctx.beginPath(); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); + ctx.restore(); + } + drawLabels(chartArea) { + const optionTicks = this.options.ticks; + if (!optionTicks.display) { + return; + } + const ctx = this.ctx; + const area = this._computeLabelArea(); + if (area) { + clipArea2(ctx, area); + } + const items = this.getLabelItems(chartArea); + for (const item of items) { + const renderTextOptions = item.options; + const tickFont = item.font; + const label = item.label; + const y = item.textOffset; + renderText2(ctx, label, 0, y, tickFont, renderTextOptions); + } + if (area) { + unclipArea2(ctx); + } + } + drawTitle() { + const { ctx, options: { position, title, reverse } } = this; + if (!title.display) { + return; + } + const font = toFont2(title.font); + const padding = toPadding2(title.padding); + const align = title.align; + let offset2 = font.lineHeight / 2; + if (position === "bottom" || position === "center" || isObject2(position)) { + offset2 += padding.bottom; + if (isArray2(title.text)) { + offset2 += font.lineHeight * (title.text.length - 1); + } + } else { + offset2 += padding.top; + } + const { titleX, titleY, maxWidth, rotation } = titleArgs2(this, offset2, position, align); + renderText2(ctx, title.text, 0, 0, font, { + color: title.color, + maxWidth, + rotation, + textAlign: titleAlign2(align, position, reverse), + textBaseline: "middle", + translation: [ + titleX, + titleY + ] + }); + } + draw(chartArea) { + if (!this._isVisible()) { + return; + } + this.drawBackground(); + this.drawGrid(chartArea); + this.drawBorder(); + this.drawTitle(); + this.drawLabels(chartArea); + } + _layers() { + const opts = this.options; + const tz = opts.ticks && opts.ticks.z || 0; + const gz = valueOrDefault2(opts.grid && opts.grid.z, -1); + const bz = valueOrDefault2(opts.border && opts.border.z, 0); + if (!this._isVisible() || this.draw !== Scale2.prototype.draw) { + return [ + { + z: tz, + draw: (chartArea) => { + this.draw(chartArea); + } + } + ]; + } + return [ + { + z: gz, + draw: (chartArea) => { + this.drawBackground(); + this.drawGrid(chartArea); + this.drawTitle(); + } + }, + { + z: bz, + draw: () => { + this.drawBorder(); + } + }, + { + z: tz, + draw: (chartArea) => { + this.drawLabels(chartArea); + } + } + ]; + } + getMatchingVisibleMetas(type) { + const metas = this.chart.getSortedVisibleDatasetMetas(); + const axisID = this.axis + "AxisID"; + const result = []; + let i, ilen; + for (i = 0, ilen = metas.length; i < ilen; ++i) { + const meta = metas[i]; + if (meta[axisID] === this.id && (!type || meta.type === type)) { + result.push(meta); + } + } + return result; + } + _resolveTickFontOptions(index2) { + const opts = this.options.ticks.setContext(this.getContext(index2)); + return toFont2(opts.font); + } + _maxDigits() { + const fontSize = this._resolveTickFontOptions(0).lineHeight; + return (this.isHorizontal() ? this.width : this.height) / fontSize; + } +}; +function generateTicks$12(generationOptions, dataRange) { + const ticks = []; + const MIN_SPACING = 1e-14; + const { bounds, step, min, max, precision, count, maxTicks, maxDigits, includeBounds } = generationOptions; + const unit = step || 1; + const maxSpaces = maxTicks - 1; + const { min: rmin, max: rmax } = dataRange; + const minDefined = !isNullOrUndef2(min); + const maxDefined = !isNullOrUndef2(max); + const countDefined = !isNullOrUndef2(count); + const minSpacing = (rmax - rmin) / (maxDigits + 1); + let spacing = niceNum2((rmax - rmin) / maxSpaces / unit) * unit; + let factor, niceMin, niceMax, numSpaces; + if (spacing < MIN_SPACING && !minDefined && !maxDefined) { + return [ + { + value: rmin + }, + { + value: rmax + } + ]; + } + numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing); + if (numSpaces > maxSpaces) { + spacing = niceNum2(numSpaces * spacing / maxSpaces / unit) * unit; + } + if (!isNullOrUndef2(precision)) { + factor = Math.pow(10, precision); + spacing = Math.ceil(spacing * factor) / factor; + } + if (bounds === "ticks") { + niceMin = Math.floor(rmin / spacing) * spacing; + niceMax = Math.ceil(rmax / spacing) * spacing; + } else { + niceMin = rmin; + niceMax = rmax; + } + if (minDefined && maxDefined && step && almostWhole2((max - min) / step, spacing / 1e3)) { + numSpaces = Math.round(Math.min((max - min) / spacing, maxTicks)); + spacing = (max - min) / numSpaces; + niceMin = min; + niceMax = max; + } else if (countDefined) { + niceMin = minDefined ? min : niceMin; + niceMax = maxDefined ? max : niceMax; + numSpaces = count - 1; + spacing = (niceMax - niceMin) / numSpaces; + } else { + numSpaces = (niceMax - niceMin) / spacing; + if (almostEquals2(numSpaces, Math.round(numSpaces), spacing / 1e3)) { + numSpaces = Math.round(numSpaces); + } else { + numSpaces = Math.ceil(numSpaces); + } + } + const decimalPlaces = Math.max(_decimalPlaces2(spacing), _decimalPlaces2(niceMin)); + factor = Math.pow(10, isNullOrUndef2(precision) ? decimalPlaces : precision); + niceMin = Math.round(niceMin * factor) / factor; + niceMax = Math.round(niceMax * factor) / factor; + let j = 0; + if (minDefined) { + if (includeBounds && niceMin !== min) { + ticks.push({ + value: min + }); + if (niceMin < min) { + j++; + } + if (almostEquals2(Math.round((niceMin + j * spacing) * factor) / factor, min, relativeLabelSize2(min, minSpacing, generationOptions))) { + j++; + } + } else if (niceMin < min) { + j++; + } + } + for (; j < numSpaces; ++j) { + const tickValue = Math.round((niceMin + j * spacing) * factor) / factor; + if (maxDefined && tickValue > max) { + break; + } + ticks.push({ + value: tickValue + }); + } + if (maxDefined && includeBounds && niceMax !== max) { + if (ticks.length && almostEquals2(ticks[ticks.length - 1].value, max, relativeLabelSize2(max, minSpacing, generationOptions))) { + ticks[ticks.length - 1].value = max; + } else { + ticks.push({ + value: max + }); + } + } else if (!maxDefined || niceMax === max) { + ticks.push({ + value: niceMax + }); + } + return ticks; +} +function relativeLabelSize2(value, minSpacing, { horizontal, minRotation }) { + const rad = toRadians2(minRotation); + const ratio = (horizontal ? Math.sin(rad) : Math.cos(rad)) || 1e-3; + const length = 0.75 * minSpacing * ("" + value).length; + return Math.min(minSpacing / ratio, length); +} +var LinearScaleBase2 = class extends Scale2 { + constructor(cfg) { + super(cfg); + this.start = void 0; + this.end = void 0; + this._startValue = void 0; + this._endValue = void 0; + this._valueRange = 0; + } + parse(raw, index2) { + if (isNullOrUndef2(raw)) { + return null; + } + if ((typeof raw === "number" || raw instanceof Number) && !isFinite(+raw)) { + return null; + } + return +raw; + } + handleTickRangeOptions() { + const { beginAtZero } = this.options; + const { minDefined, maxDefined } = this.getUserBounds(); + let { min, max } = this; + const setMin = (v) => min = minDefined ? min : v; + const setMax = (v) => max = maxDefined ? max : v; + if (beginAtZero) { + const minSign = sign2(min); + const maxSign = sign2(max); + if (minSign < 0 && maxSign < 0) { + setMax(0); + } else if (minSign > 0 && maxSign > 0) { + setMin(0); + } + } + if (min === max) { + let offset2 = max === 0 ? 1 : Math.abs(max * 0.05); + setMax(max + offset2); + if (!beginAtZero) { + setMin(min - offset2); + } + } + this.min = min; + this.max = max; + } + getTickLimit() { + const tickOpts = this.options.ticks; + let { maxTicksLimit, stepSize } = tickOpts; + let maxTicks; + if (stepSize) { + maxTicks = Math.ceil(this.max / stepSize) - Math.floor(this.min / stepSize) + 1; + if (maxTicks > 1e3) { + console.warn(`scales.${this.id}.ticks.stepSize: ${stepSize} would result generating up to ${maxTicks} ticks. Limiting to 1000.`); + maxTicks = 1e3; + } + } else { + maxTicks = this.computeTickLimit(); + maxTicksLimit = maxTicksLimit || 11; + } + if (maxTicksLimit) { + maxTicks = Math.min(maxTicksLimit, maxTicks); + } + return maxTicks; + } + computeTickLimit() { + return Number.POSITIVE_INFINITY; + } + buildTicks() { + const opts = this.options; + const tickOpts = opts.ticks; + let maxTicks = this.getTickLimit(); + maxTicks = Math.max(2, maxTicks); + const numericGeneratorOptions = { + maxTicks, + bounds: opts.bounds, + min: opts.min, + max: opts.max, + precision: tickOpts.precision, + step: tickOpts.stepSize, + count: tickOpts.count, + maxDigits: this._maxDigits(), + horizontal: this.isHorizontal(), + minRotation: tickOpts.minRotation || 0, + includeBounds: tickOpts.includeBounds !== false + }; + const dataRange = this._range || this; + const ticks = generateTicks$12(numericGeneratorOptions, dataRange); + if (opts.bounds === "ticks") { + _setMinAndMaxByKey2(ticks, this, "value"); + } + if (opts.reverse) { + ticks.reverse(); + this.start = this.max; + this.end = this.min; + } else { + this.start = this.min; + this.end = this.max; + } + return ticks; + } + configure() { + const ticks = this.ticks; + let start = this.min; + let end = this.max; + super.configure(); + if (this.options.offset && ticks.length) { + const offset2 = (end - start) / Math.max(ticks.length - 1, 1) / 2; + start -= offset2; + end += offset2; + } + this._startValue = start; + this._endValue = end; + this._valueRange = end - start; + } + getLabelForValue(value) { + return formatNumber2(value, this.chart.options.locale, this.options.ticks.format); + } +}; +var LinearScale2 = class extends LinearScaleBase2 { + determineDataLimits() { + const { min, max } = this.getMinMax(true); + this.min = isNumberFinite2(min) ? min : 0; + this.max = isNumberFinite2(max) ? max : 1; + this.handleTickRangeOptions(); + } + computeTickLimit() { + const horizontal = this.isHorizontal(); + const length = horizontal ? this.width : this.height; + const minRotation = toRadians2(this.options.ticks.minRotation); + const ratio = (horizontal ? Math.sin(minRotation) : Math.cos(minRotation)) || 1e-3; + const tickFont = this._resolveTickFontOptions(0); + return Math.ceil(length / Math.min(40, tickFont.lineHeight / ratio)); + } + getPixelForValue(value) { + return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange); + } + getValueForPixel(pixel) { + return this._startValue + this.getDecimalForPixel(pixel) * this._valueRange; + } +}; +__publicField(LinearScale2, "id", "linear"); +__publicField(LinearScale2, "defaults", { + ticks: { + callback: Ticks2.formatters.numeric + } +}); +var log10Floor2 = (v) => Math.floor(log102(v)); +var changeExponent2 = (v, m) => Math.pow(10, log10Floor2(v) + m); +function isMajor2(tickVal) { + const remain = tickVal / Math.pow(10, log10Floor2(tickVal)); + return remain === 1; +} +function steps2(min, max, rangeExp) { + const rangeStep = Math.pow(10, rangeExp); + const start = Math.floor(min / rangeStep); + const end = Math.ceil(max / rangeStep); + return end - start; +} +function startExp2(min, max) { + const range = max - min; + let rangeExp = log10Floor2(range); + while (steps2(min, max, rangeExp) > 10) { + rangeExp++; + } + while (steps2(min, max, rangeExp) < 10) { + rangeExp--; + } + return Math.min(rangeExp, log10Floor2(min)); +} +function generateTicks2(generationOptions, { min, max }) { + min = finiteOrDefault2(generationOptions.min, min); + const ticks = []; + const minExp = log10Floor2(min); + let exp = startExp2(min, max); + let precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1; + const stepSize = Math.pow(10, exp); + const base = minExp > exp ? Math.pow(10, minExp) : 0; + const start = Math.round((min - base) * precision) / precision; + const offset2 = Math.floor((min - base) / stepSize / 10) * stepSize * 10; + let significand = Math.floor((start - offset2) / Math.pow(10, exp)); + let value = finiteOrDefault2(generationOptions.min, Math.round((base + offset2 + significand * Math.pow(10, exp)) * precision) / precision); + while (value < max) { + ticks.push({ + value, + major: isMajor2(value), + significand + }); + if (significand >= 10) { + significand = significand < 15 ? 15 : 20; + } else { + significand++; + } + if (significand >= 20) { + exp++; + significand = 2; + precision = exp >= 0 ? 1 : precision; + } + value = Math.round((base + offset2 + significand * Math.pow(10, exp)) * precision) / precision; + } + const lastTick = finiteOrDefault2(generationOptions.max, value); + ticks.push({ + value: lastTick, + major: isMajor2(lastTick), + significand + }); + return ticks; +} +var LogarithmicScale2 = class extends Scale2 { + constructor(cfg) { + super(cfg); + this.start = void 0; + this.end = void 0; + this._startValue = void 0; + this._valueRange = 0; + } + parse(raw, index2) { + const value = LinearScaleBase2.prototype.parse.apply(this, [ + raw, + index2 + ]); + if (value === 0) { + this._zero = true; + return void 0; + } + return isNumberFinite2(value) && value > 0 ? value : null; + } + determineDataLimits() { + const { min, max } = this.getMinMax(true); + this.min = isNumberFinite2(min) ? Math.max(0, min) : null; + this.max = isNumberFinite2(max) ? Math.max(0, max) : null; + if (this.options.beginAtZero) { + this._zero = true; + } + if (this._zero && this.min !== this._suggestedMin && !isNumberFinite2(this._userMin)) { + this.min = min === changeExponent2(this.min, 0) ? changeExponent2(this.min, -1) : changeExponent2(this.min, 0); + } + this.handleTickRangeOptions(); + } + handleTickRangeOptions() { + const { minDefined, maxDefined } = this.getUserBounds(); + let min = this.min; + let max = this.max; + const setMin = (v) => min = minDefined ? min : v; + const setMax = (v) => max = maxDefined ? max : v; + if (min === max) { + if (min <= 0) { + setMin(1); + setMax(10); + } else { + setMin(changeExponent2(min, -1)); + setMax(changeExponent2(max, 1)); + } + } + if (min <= 0) { + setMin(changeExponent2(max, -1)); + } + if (max <= 0) { + setMax(changeExponent2(min, 1)); + } + this.min = min; + this.max = max; + } + buildTicks() { + const opts = this.options; + const generationOptions = { + min: this._userMin, + max: this._userMax + }; + const ticks = generateTicks2(generationOptions, this); + if (opts.bounds === "ticks") { + _setMinAndMaxByKey2(ticks, this, "value"); + } + if (opts.reverse) { + ticks.reverse(); + this.start = this.max; + this.end = this.min; + } else { + this.start = this.min; + this.end = this.max; + } + return ticks; + } + getLabelForValue(value) { + return value === void 0 ? "0" : formatNumber2(value, this.chart.options.locale, this.options.ticks.format); + } + configure() { + const start = this.min; + super.configure(); + this._startValue = log102(start); + this._valueRange = log102(this.max) - log102(start); + } + getPixelForValue(value) { + if (value === void 0 || value === 0) { + value = this.min; + } + if (value === null || isNaN(value)) { + return NaN; + } + return this.getPixelForDecimal(value === this.min ? 0 : (log102(value) - this._startValue) / this._valueRange); + } + getValueForPixel(pixel) { + const decimal = this.getDecimalForPixel(pixel); + return Math.pow(10, this._startValue + decimal * this._valueRange); + } +}; +__publicField(LogarithmicScale2, "id", "logarithmic"); +__publicField(LogarithmicScale2, "defaults", { + ticks: { + callback: Ticks2.formatters.logarithmic, + major: { + enabled: true + } + } +}); +function getTickBackdropHeight2(opts) { + const tickOpts = opts.ticks; + if (tickOpts.display && opts.display) { + const padding = toPadding2(tickOpts.backdropPadding); + return valueOrDefault2(tickOpts.font && tickOpts.font.size, defaults2.font.size) + padding.height; + } + return 0; +} +function measureLabelSize2(ctx, font, label) { + label = isArray2(label) ? label : [ + label + ]; + return { + w: _longestText2(ctx, font.string, label), + h: label.length * font.lineHeight + }; +} +function determineLimits2(angle, pos, size, min, max) { + if (angle === min || angle === max) { + return { + start: pos - size / 2, + end: pos + size / 2 + }; + } else if (angle < min || angle > max) { + return { + start: pos - size, + end: pos + }; + } + return { + start: pos, + end: pos + size + }; +} +function fitWithPointLabels2(scale) { + const orig = { + l: scale.left + scale._padding.left, + r: scale.right - scale._padding.right, + t: scale.top + scale._padding.top, + b: scale.bottom - scale._padding.bottom + }; + const limits = Object.assign({}, orig); + const labelSizes = []; + const padding = []; + const valueCount = scale._pointLabels.length; + const pointLabelOpts = scale.options.pointLabels; + const additionalAngle = pointLabelOpts.centerPointLabels ? PI2 / valueCount : 0; + for (let i = 0; i < valueCount; i++) { + const opts = pointLabelOpts.setContext(scale.getPointLabelContext(i)); + padding[i] = opts.padding; + const pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle); + const plFont = toFont2(opts.font); + const textSize = measureLabelSize2(scale.ctx, plFont, scale._pointLabels[i]); + labelSizes[i] = textSize; + const angleRadians = _normalizeAngle2(scale.getIndexAngle(i) + additionalAngle); + const angle = Math.round(toDegrees2(angleRadians)); + const hLimits = determineLimits2(angle, pointPosition.x, textSize.w, 0, 180); + const vLimits = determineLimits2(angle, pointPosition.y, textSize.h, 90, 270); + updateLimits2(limits, orig, angleRadians, hLimits, vLimits); + } + scale.setCenterPoint(orig.l - limits.l, limits.r - orig.r, orig.t - limits.t, limits.b - orig.b); + scale._pointLabelItems = buildPointLabelItems2(scale, labelSizes, padding); +} +function updateLimits2(limits, orig, angle, hLimits, vLimits) { + const sin = Math.abs(Math.sin(angle)); + const cos = Math.abs(Math.cos(angle)); + let x = 0; + let y = 0; + if (hLimits.start < orig.l) { + x = (orig.l - hLimits.start) / sin; + limits.l = Math.min(limits.l, orig.l - x); + } else if (hLimits.end > orig.r) { + x = (hLimits.end - orig.r) / sin; + limits.r = Math.max(limits.r, orig.r + x); + } + if (vLimits.start < orig.t) { + y = (orig.t - vLimits.start) / cos; + limits.t = Math.min(limits.t, orig.t - y); + } else if (vLimits.end > orig.b) { + y = (vLimits.end - orig.b) / cos; + limits.b = Math.max(limits.b, orig.b + y); + } +} +function createPointLabelItem2(scale, index2, itemOpts) { + const outerDistance = scale.drawingArea; + const { extra, additionalAngle, padding, size } = itemOpts; + const pointLabelPosition = scale.getPointPosition(index2, outerDistance + extra + padding, additionalAngle); + const angle = Math.round(toDegrees2(_normalizeAngle2(pointLabelPosition.angle + HALF_PI2))); + const y = yForAngle2(pointLabelPosition.y, size.h, angle); + const textAlign = getTextAlignForAngle2(angle); + const left = leftForTextAlign2(pointLabelPosition.x, size.w, textAlign); + return { + visible: true, + x: pointLabelPosition.x, + y, + textAlign, + left, + top: y, + right: left + size.w, + bottom: y + size.h + }; +} +function isNotOverlapped2(item, area) { + if (!area) { + return true; + } + const { left, top, right, bottom } = item; + const apexesInArea = _isPointInArea2({ + x: left, + y: top + }, area) || _isPointInArea2({ + x: left, + y: bottom + }, area) || _isPointInArea2({ + x: right, + y: top + }, area) || _isPointInArea2({ + x: right, + y: bottom + }, area); + return !apexesInArea; +} +function buildPointLabelItems2(scale, labelSizes, padding) { + const items = []; + const valueCount = scale._pointLabels.length; + const opts = scale.options; + const { centerPointLabels, display } = opts.pointLabels; + const itemOpts = { + extra: getTickBackdropHeight2(opts) / 2, + additionalAngle: centerPointLabels ? PI2 / valueCount : 0 + }; + let area; + for (let i = 0; i < valueCount; i++) { + itemOpts.padding = padding[i]; + itemOpts.size = labelSizes[i]; + const item = createPointLabelItem2(scale, i, itemOpts); + items.push(item); + if (display === "auto") { + item.visible = isNotOverlapped2(item, area); + if (item.visible) { + area = item; + } + } + } + return items; +} +function getTextAlignForAngle2(angle) { + if (angle === 0 || angle === 180) { + return "center"; + } else if (angle < 180) { + return "left"; + } + return "right"; +} +function leftForTextAlign2(x, w, align) { + if (align === "right") { + x -= w; + } else if (align === "center") { + x -= w / 2; + } + return x; +} +function yForAngle2(y, h, angle) { + if (angle === 90 || angle === 270) { + y -= h / 2; + } else if (angle > 270 || angle < 90) { + y -= h; + } + return y; +} +function drawPointLabelBox2(ctx, opts, item) { + const { left, top, right, bottom } = item; + const { backdropColor } = opts; + if (!isNullOrUndef2(backdropColor)) { + const borderRadius = toTRBLCorners2(opts.borderRadius); + const padding = toPadding2(opts.backdropPadding); + ctx.fillStyle = backdropColor; + const backdropLeft = left - padding.left; + const backdropTop = top - padding.top; + const backdropWidth = right - left + padding.width; + const backdropHeight = bottom - top + padding.height; + if (Object.values(borderRadius).some((v) => v !== 0)) { + ctx.beginPath(); + addRoundedRectPath2(ctx, { + x: backdropLeft, + y: backdropTop, + w: backdropWidth, + h: backdropHeight, + radius: borderRadius + }); + ctx.fill(); + } else { + ctx.fillRect(backdropLeft, backdropTop, backdropWidth, backdropHeight); + } + } +} +function drawPointLabels2(scale, labelCount) { + const { ctx, options: { pointLabels } } = scale; + for (let i = labelCount - 1; i >= 0; i--) { + const item = scale._pointLabelItems[i]; + if (!item.visible) { + continue; + } + const optsAtIndex = pointLabels.setContext(scale.getPointLabelContext(i)); + drawPointLabelBox2(ctx, optsAtIndex, item); + const plFont = toFont2(optsAtIndex.font); + const { x, y, textAlign } = item; + renderText2(ctx, scale._pointLabels[i], x, y + plFont.lineHeight / 2, plFont, { + color: optsAtIndex.color, + textAlign, + textBaseline: "middle" + }); + } +} +function pathRadiusLine2(scale, radius, circular, labelCount) { + const { ctx } = scale; + if (circular) { + ctx.arc(scale.xCenter, scale.yCenter, radius, 0, TAU2); + } else { + let pointPosition = scale.getPointPosition(0, radius); + ctx.moveTo(pointPosition.x, pointPosition.y); + for (let i = 1; i < labelCount; i++) { + pointPosition = scale.getPointPosition(i, radius); + ctx.lineTo(pointPosition.x, pointPosition.y); + } + } +} +function drawRadiusLine2(scale, gridLineOpts, radius, labelCount, borderOpts) { + const ctx = scale.ctx; + const circular = gridLineOpts.circular; + const { color: color3, lineWidth } = gridLineOpts; + if (!circular && !labelCount || !color3 || !lineWidth || radius < 0) { + return; + } + ctx.save(); + ctx.strokeStyle = color3; + ctx.lineWidth = lineWidth; + ctx.setLineDash(borderOpts.dash); + ctx.lineDashOffset = borderOpts.dashOffset; + ctx.beginPath(); + pathRadiusLine2(scale, radius, circular, labelCount); + ctx.closePath(); + ctx.stroke(); + ctx.restore(); +} +function createPointLabelContext2(parent, index2, label) { + return createContext2(parent, { + label, + index: index2, + type: "pointLabel" + }); +} +var RadialLinearScale2 = class extends LinearScaleBase2 { + constructor(cfg) { + super(cfg); + this.xCenter = void 0; + this.yCenter = void 0; + this.drawingArea = void 0; + this._pointLabels = []; + this._pointLabelItems = []; + } + setDimensions() { + const padding = this._padding = toPadding2(getTickBackdropHeight2(this.options) / 2); + const w = this.width = this.maxWidth - padding.width; + const h = this.height = this.maxHeight - padding.height; + this.xCenter = Math.floor(this.left + w / 2 + padding.left); + this.yCenter = Math.floor(this.top + h / 2 + padding.top); + this.drawingArea = Math.floor(Math.min(w, h) / 2); + } + determineDataLimits() { + const { min, max } = this.getMinMax(false); + this.min = isNumberFinite2(min) && !isNaN(min) ? min : 0; + this.max = isNumberFinite2(max) && !isNaN(max) ? max : 0; + this.handleTickRangeOptions(); + } + computeTickLimit() { + return Math.ceil(this.drawingArea / getTickBackdropHeight2(this.options)); + } + generateTickLabels(ticks) { + LinearScaleBase2.prototype.generateTickLabels.call(this, ticks); + this._pointLabels = this.getLabels().map((value, index2) => { + const label = callback2(this.options.pointLabels.callback, [ + value, + index2 + ], this); + return label || label === 0 ? label : ""; + }).filter((v, i) => this.chart.getDataVisibility(i)); + } + fit() { + const opts = this.options; + if (opts.display && opts.pointLabels.display) { + fitWithPointLabels2(this); + } else { + this.setCenterPoint(0, 0, 0, 0); + } + } + setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) { + this.xCenter += Math.floor((leftMovement - rightMovement) / 2); + this.yCenter += Math.floor((topMovement - bottomMovement) / 2); + this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement)); + } + getIndexAngle(index2) { + const angleMultiplier = TAU2 / (this._pointLabels.length || 1); + const startAngle = this.options.startAngle || 0; + return _normalizeAngle2(index2 * angleMultiplier + toRadians2(startAngle)); + } + getDistanceFromCenterForValue(value) { + if (isNullOrUndef2(value)) { + return NaN; + } + const scalingFactor = this.drawingArea / (this.max - this.min); + if (this.options.reverse) { + return (this.max - value) * scalingFactor; + } + return (value - this.min) * scalingFactor; + } + getValueForDistanceFromCenter(distance) { + if (isNullOrUndef2(distance)) { + return NaN; + } + const scaledDistance = distance / (this.drawingArea / (this.max - this.min)); + return this.options.reverse ? this.max - scaledDistance : this.min + scaledDistance; + } + getPointLabelContext(index2) { + const pointLabels = this._pointLabels || []; + if (index2 >= 0 && index2 < pointLabels.length) { + const pointLabel = pointLabels[index2]; + return createPointLabelContext2(this.getContext(), index2, pointLabel); + } + } + getPointPosition(index2, distanceFromCenter, additionalAngle = 0) { + const angle = this.getIndexAngle(index2) - HALF_PI2 + additionalAngle; + return { + x: Math.cos(angle) * distanceFromCenter + this.xCenter, + y: Math.sin(angle) * distanceFromCenter + this.yCenter, + angle + }; + } + getPointPositionForValue(index2, value) { + return this.getPointPosition(index2, this.getDistanceFromCenterForValue(value)); + } + getBasePosition(index2) { + return this.getPointPositionForValue(index2 || 0, this.getBaseValue()); + } + getPointLabelPosition(index2) { + const { left, top, right, bottom } = this._pointLabelItems[index2]; + return { + left, + top, + right, + bottom + }; + } + drawBackground() { + const { backgroundColor, grid: { circular } } = this.options; + if (backgroundColor) { + const ctx = this.ctx; + ctx.save(); + ctx.beginPath(); + pathRadiusLine2(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length); + ctx.closePath(); + ctx.fillStyle = backgroundColor; + ctx.fill(); + ctx.restore(); + } + } + drawGrid() { + const ctx = this.ctx; + const opts = this.options; + const { angleLines, grid, border } = opts; + const labelCount = this._pointLabels.length; + let i, offset2, position; + if (opts.pointLabels.display) { + drawPointLabels2(this, labelCount); + } + if (grid.display) { + this.ticks.forEach((tick, index2) => { + if (index2 !== 0 || index2 === 0 && this.min < 0) { + offset2 = this.getDistanceFromCenterForValue(tick.value); + const context = this.getContext(index2); + const optsAtIndex = grid.setContext(context); + const optsAtIndexBorder = border.setContext(context); + drawRadiusLine2(this, optsAtIndex, offset2, labelCount, optsAtIndexBorder); + } + }); + } + if (angleLines.display) { + ctx.save(); + for (i = labelCount - 1; i >= 0; i--) { + const optsAtIndex = angleLines.setContext(this.getPointLabelContext(i)); + const { color: color3, lineWidth } = optsAtIndex; + if (!lineWidth || !color3) { + continue; + } + ctx.lineWidth = lineWidth; + ctx.strokeStyle = color3; + ctx.setLineDash(optsAtIndex.borderDash); + ctx.lineDashOffset = optsAtIndex.borderDashOffset; + offset2 = this.getDistanceFromCenterForValue(opts.ticks.reverse ? this.min : this.max); + position = this.getPointPosition(i, offset2); + ctx.beginPath(); + ctx.moveTo(this.xCenter, this.yCenter); + ctx.lineTo(position.x, position.y); + ctx.stroke(); + } + ctx.restore(); + } + } + drawBorder() { + } + drawLabels() { + const ctx = this.ctx; + const opts = this.options; + const tickOpts = opts.ticks; + if (!tickOpts.display) { + return; + } + const startAngle = this.getIndexAngle(0); + let offset2, width; + ctx.save(); + ctx.translate(this.xCenter, this.yCenter); + ctx.rotate(startAngle); + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + this.ticks.forEach((tick, index2) => { + if (index2 === 0 && this.min >= 0 && !opts.reverse) { + return; + } + const optsAtIndex = tickOpts.setContext(this.getContext(index2)); + const tickFont = toFont2(optsAtIndex.font); + offset2 = this.getDistanceFromCenterForValue(this.ticks[index2].value); + if (optsAtIndex.showLabelBackdrop) { + ctx.font = tickFont.string; + width = ctx.measureText(tick.label).width; + ctx.fillStyle = optsAtIndex.backdropColor; + const padding = toPadding2(optsAtIndex.backdropPadding); + ctx.fillRect(-width / 2 - padding.left, -offset2 - tickFont.size / 2 - padding.top, width + padding.width, tickFont.size + padding.height); + } + renderText2(ctx, tick.label, 0, -offset2, tickFont, { + color: optsAtIndex.color, + strokeColor: optsAtIndex.textStrokeColor, + strokeWidth: optsAtIndex.textStrokeWidth + }); + }); + ctx.restore(); + } + drawTitle() { + } +}; +__publicField(RadialLinearScale2, "id", "radialLinear"); +__publicField(RadialLinearScale2, "defaults", { + display: true, + animate: true, + position: "chartArea", + angleLines: { + display: true, + lineWidth: 1, + borderDash: [], + borderDashOffset: 0 + }, + grid: { + circular: false + }, + startAngle: 0, + ticks: { + showLabelBackdrop: true, + callback: Ticks2.formatters.numeric + }, + pointLabels: { + backdropColor: void 0, + backdropPadding: 2, + display: true, + font: { + size: 10 + }, + callback(label) { + return label; + }, + padding: 5, + centerPointLabels: false + } +}); +__publicField(RadialLinearScale2, "defaultRoutes", { + "angleLines.color": "borderColor", + "pointLabels.color": "color", + "ticks.color": "color" +}); +__publicField(RadialLinearScale2, "descriptors", { + angleLines: { + _fallback: "grid" + } +}); +var INTERVALS2 = { + millisecond: { + common: true, + size: 1, + steps: 1e3 + }, + second: { + common: true, + size: 1e3, + steps: 60 + }, + minute: { + common: true, + size: 6e4, + steps: 60 + }, + hour: { + common: true, + size: 36e5, + steps: 24 + }, + day: { + common: true, + size: 864e5, + steps: 30 + }, + week: { + common: false, + size: 6048e5, + steps: 4 + }, + month: { + common: true, + size: 2628e6, + steps: 12 + }, + quarter: { + common: false, + size: 7884e6, + steps: 4 + }, + year: { + common: true, + size: 3154e7 + } +}; +var UNITS2 = /* @__PURE__ */ Object.keys(INTERVALS2); +function sorter2(a, b) { + return a - b; +} +function parse2(scale, input) { + if (isNullOrUndef2(input)) { + return null; + } + const adapter = scale._adapter; + const { parser, round: round3, isoWeekday } = scale._parseOpts; + let value = input; + if (typeof parser === "function") { + value = parser(value); + } + if (!isNumberFinite2(value)) { + value = typeof parser === "string" ? adapter.parse(value, parser) : adapter.parse(value); + } + if (value === null) { + return null; + } + if (round3) { + value = round3 === "week" && (isNumber2(isoWeekday) || isoWeekday === true) ? adapter.startOf(value, "isoWeek", isoWeekday) : adapter.startOf(value, round3); + } + return +value; +} +function determineUnitForAutoTicks2(minUnit, min, max, capacity) { + const ilen = UNITS2.length; + for (let i = UNITS2.indexOf(minUnit); i < ilen - 1; ++i) { + const interval = INTERVALS2[UNITS2[i]]; + const factor = interval.steps ? interval.steps : Number.MAX_SAFE_INTEGER; + if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) { + return UNITS2[i]; + } + } + return UNITS2[ilen - 1]; +} +function determineUnitForFormatting2(scale, numTicks, minUnit, min, max) { + for (let i = UNITS2.length - 1; i >= UNITS2.indexOf(minUnit); i--) { + const unit = UNITS2[i]; + if (INTERVALS2[unit].common && scale._adapter.diff(max, min, unit) >= numTicks - 1) { + return unit; + } + } + return UNITS2[minUnit ? UNITS2.indexOf(minUnit) : 0]; +} +function determineMajorUnit2(unit) { + for (let i = UNITS2.indexOf(unit) + 1, ilen = UNITS2.length; i < ilen; ++i) { + if (INTERVALS2[UNITS2[i]].common) { + return UNITS2[i]; + } + } +} +function addTick2(ticks, time, timestamps) { + if (!timestamps) { + ticks[time] = true; + } else if (timestamps.length) { + const { lo, hi } = _lookup2(timestamps, time); + const timestamp = timestamps[lo] >= time ? timestamps[lo] : timestamps[hi]; + ticks[timestamp] = true; + } +} +function setMajorTicks2(scale, ticks, map4, majorUnit) { + const adapter = scale._adapter; + const first = +adapter.startOf(ticks[0].value, majorUnit); + const last = ticks[ticks.length - 1].value; + let major, index2; + for (major = first; major <= last; major = +adapter.add(major, 1, majorUnit)) { + index2 = map4[major]; + if (index2 >= 0) { + ticks[index2].major = true; + } + } + return ticks; +} +function ticksFromTimestamps2(scale, values, majorUnit) { + const ticks = []; + const map4 = {}; + const ilen = values.length; + let i, value; + for (i = 0; i < ilen; ++i) { + value = values[i]; + map4[value] = i; + ticks.push({ + value, + major: false + }); + } + return ilen === 0 || !majorUnit ? ticks : setMajorTicks2(scale, ticks, map4, majorUnit); +} +var TimeScale2 = class extends Scale2 { + constructor(props) { + super(props); + this._cache = { + data: [], + labels: [], + all: [] + }; + this._unit = "day"; + this._majorUnit = void 0; + this._offsets = {}; + this._normalized = false; + this._parseOpts = void 0; + } + init(scaleOpts, opts = {}) { + const time = scaleOpts.time || (scaleOpts.time = {}); + const adapter = this._adapter = new adapters2._date(scaleOpts.adapters.date); + adapter.init(opts); + mergeIf2(time.displayFormats, adapter.formats()); + this._parseOpts = { + parser: time.parser, + round: time.round, + isoWeekday: time.isoWeekday + }; + super.init(scaleOpts); + this._normalized = opts.normalized; + } + parse(raw, index2) { + if (raw === void 0) { + return null; + } + return parse2(this, raw); + } + beforeLayout() { + super.beforeLayout(); + this._cache = { + data: [], + labels: [], + all: [] + }; + } + determineDataLimits() { + const options = this.options; + const adapter = this._adapter; + const unit = options.time.unit || "day"; + let { min, max, minDefined, maxDefined } = this.getUserBounds(); + function _applyBounds(bounds) { + if (!minDefined && !isNaN(bounds.min)) { + min = Math.min(min, bounds.min); + } + if (!maxDefined && !isNaN(bounds.max)) { + max = Math.max(max, bounds.max); + } + } + if (!minDefined || !maxDefined) { + _applyBounds(this._getLabelBounds()); + if (options.bounds !== "ticks" || options.ticks.source !== "labels") { + _applyBounds(this.getMinMax(false)); + } + } + min = isNumberFinite2(min) && !isNaN(min) ? min : +adapter.startOf(Date.now(), unit); + max = isNumberFinite2(max) && !isNaN(max) ? max : +adapter.endOf(Date.now(), unit) + 1; + this.min = Math.min(min, max - 1); + this.max = Math.max(min + 1, max); + } + _getLabelBounds() { + const arr = this.getLabelTimestamps(); + let min = Number.POSITIVE_INFINITY; + let max = Number.NEGATIVE_INFINITY; + if (arr.length) { + min = arr[0]; + max = arr[arr.length - 1]; + } + return { + min, + max + }; + } + buildTicks() { + const options = this.options; + const timeOpts = options.time; + const tickOpts = options.ticks; + const timestamps = tickOpts.source === "labels" ? this.getLabelTimestamps() : this._generate(); + if (options.bounds === "ticks" && timestamps.length) { + this.min = this._userMin || timestamps[0]; + this.max = this._userMax || timestamps[timestamps.length - 1]; + } + const min = this.min; + const max = this.max; + const ticks = _filterBetween2(timestamps, min, max); + this._unit = timeOpts.unit || (tickOpts.autoSkip ? determineUnitForAutoTicks2(timeOpts.minUnit, this.min, this.max, this._getLabelCapacity(min)) : determineUnitForFormatting2(this, ticks.length, timeOpts.minUnit, this.min, this.max)); + this._majorUnit = !tickOpts.major.enabled || this._unit === "year" ? void 0 : determineMajorUnit2(this._unit); + this.initOffsets(timestamps); + if (options.reverse) { + ticks.reverse(); + } + return ticksFromTimestamps2(this, ticks, this._majorUnit); + } + afterAutoSkip() { + if (this.options.offsetAfterAutoskip) { + this.initOffsets(this.ticks.map((tick) => +tick.value)); + } + } + initOffsets(timestamps = []) { + let start = 0; + let end = 0; + let first, last; + if (this.options.offset && timestamps.length) { + first = this.getDecimalForValue(timestamps[0]); + if (timestamps.length === 1) { + start = 1 - first; + } else { + start = (this.getDecimalForValue(timestamps[1]) - first) / 2; + } + last = this.getDecimalForValue(timestamps[timestamps.length - 1]); + if (timestamps.length === 1) { + end = last; + } else { + end = (last - this.getDecimalForValue(timestamps[timestamps.length - 2])) / 2; + } + } + const limit = timestamps.length < 3 ? 0.5 : 0.25; + start = _limitValue2(start, 0, limit); + end = _limitValue2(end, 0, limit); + this._offsets = { + start, + end, + factor: 1 / (start + 1 + end) + }; + } + _generate() { + const adapter = this._adapter; + const min = this.min; + const max = this.max; + const options = this.options; + const timeOpts = options.time; + const minor = timeOpts.unit || determineUnitForAutoTicks2(timeOpts.minUnit, min, max, this._getLabelCapacity(min)); + const stepSize = valueOrDefault2(options.ticks.stepSize, 1); + const weekday = minor === "week" ? timeOpts.isoWeekday : false; + const hasWeekday = isNumber2(weekday) || weekday === true; + const ticks = {}; + let first = min; + let time, count; + if (hasWeekday) { + first = +adapter.startOf(first, "isoWeek", weekday); + } + first = +adapter.startOf(first, hasWeekday ? "day" : minor); + if (adapter.diff(max, min, minor) > 1e5 * stepSize) { + throw new Error(min + " and " + max + " are too far apart with stepSize of " + stepSize + " " + minor); + } + const timestamps = options.ticks.source === "data" && this.getDataTimestamps(); + for (time = first, count = 0; time < max; time = +adapter.add(time, stepSize, minor), count++) { + addTick2(ticks, time, timestamps); + } + if (time === max || options.bounds === "ticks" || count === 1) { + addTick2(ticks, time, timestamps); + } + return Object.keys(ticks).sort(sorter2).map((x) => +x); + } + getLabelForValue(value) { + const adapter = this._adapter; + const timeOpts = this.options.time; + if (timeOpts.tooltipFormat) { + return adapter.format(value, timeOpts.tooltipFormat); + } + return adapter.format(value, timeOpts.displayFormats.datetime); + } + format(value, format) { + const options = this.options; + const formats = options.time.displayFormats; + const unit = this._unit; + const fmt = format || formats[unit]; + return this._adapter.format(value, fmt); + } + _tickFormatFunction(time, index2, ticks, format) { + const options = this.options; + const formatter = options.ticks.callback; + if (formatter) { + return callback2(formatter, [ + time, + index2, + ticks + ], this); + } + const formats = options.time.displayFormats; + const unit = this._unit; + const majorUnit = this._majorUnit; + const minorFormat = unit && formats[unit]; + const majorFormat = majorUnit && formats[majorUnit]; + const tick = ticks[index2]; + const major = majorUnit && majorFormat && tick && tick.major; + return this._adapter.format(time, format || (major ? majorFormat : minorFormat)); + } + generateTickLabels(ticks) { + let i, ilen, tick; + for (i = 0, ilen = ticks.length; i < ilen; ++i) { + tick = ticks[i]; + tick.label = this._tickFormatFunction(tick.value, i, ticks); + } + } + getDecimalForValue(value) { + return value === null ? NaN : (value - this.min) / (this.max - this.min); + } + getPixelForValue(value) { + const offsets = this._offsets; + const pos = this.getDecimalForValue(value); + return this.getPixelForDecimal((offsets.start + pos) * offsets.factor); + } + getValueForPixel(pixel) { + const offsets = this._offsets; + const pos = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end; + return this.min + pos * (this.max - this.min); + } + _getLabelSize(label) { + const ticksOpts = this.options.ticks; + const tickLabelWidth = this.ctx.measureText(label).width; + const angle = toRadians2(this.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation); + const cosRotation = Math.cos(angle); + const sinRotation = Math.sin(angle); + const tickFontSize = this._resolveTickFontOptions(0).size; + return { + w: tickLabelWidth * cosRotation + tickFontSize * sinRotation, + h: tickLabelWidth * sinRotation + tickFontSize * cosRotation + }; + } + _getLabelCapacity(exampleTime) { + const timeOpts = this.options.time; + const displayFormats = timeOpts.displayFormats; + const format = displayFormats[timeOpts.unit] || displayFormats.millisecond; + const exampleLabel = this._tickFormatFunction(exampleTime, 0, ticksFromTimestamps2(this, [ + exampleTime + ], this._majorUnit), format); + const size = this._getLabelSize(exampleLabel); + const capacity = Math.floor(this.isHorizontal() ? this.width / size.w : this.height / size.h) - 1; + return capacity > 0 ? capacity : 1; + } + getDataTimestamps() { + let timestamps = this._cache.data || []; + let i, ilen; + if (timestamps.length) { + return timestamps; + } + const metas = this.getMatchingVisibleMetas(); + if (this._normalized && metas.length) { + return this._cache.data = metas[0].controller.getAllParsedValues(this); + } + for (i = 0, ilen = metas.length; i < ilen; ++i) { + timestamps = timestamps.concat(metas[i].controller.getAllParsedValues(this)); + } + return this._cache.data = this.normalize(timestamps); + } + getLabelTimestamps() { + const timestamps = this._cache.labels || []; + let i, ilen; + if (timestamps.length) { + return timestamps; + } + const labels = this.getLabels(); + for (i = 0, ilen = labels.length; i < ilen; ++i) { + timestamps.push(parse2(this, labels[i])); + } + return this._cache.labels = this._normalized ? timestamps : this.normalize(timestamps); + } + normalize(values) { + return _arrayUnique2(values.sort(sorter2)); + } +}; +__publicField(TimeScale2, "id", "time"); +__publicField(TimeScale2, "defaults", { + bounds: "data", + adapters: {}, + time: { + parser: false, + unit: false, + round: false, + isoWeekday: false, + minUnit: "millisecond", + displayFormats: {} + }, + ticks: { + source: "auto", + callback: false, + major: { + enabled: false + } + } +}); +function interpolate4(table, val, reverse) { + let lo = 0; + let hi = table.length - 1; + let prevSource, nextSource, prevTarget, nextTarget; + if (reverse) { + if (val >= table[lo].pos && val <= table[hi].pos) { + ({ lo, hi } = _lookupByKey2(table, "pos", val)); + } + ({ pos: prevSource, time: prevTarget } = table[lo]); + ({ pos: nextSource, time: nextTarget } = table[hi]); + } else { + if (val >= table[lo].time && val <= table[hi].time) { + ({ lo, hi } = _lookupByKey2(table, "time", val)); + } + ({ time: prevSource, pos: prevTarget } = table[lo]); + ({ time: nextSource, pos: nextTarget } = table[hi]); + } + const span = nextSource - prevSource; + return span ? prevTarget + (nextTarget - prevTarget) * (val - prevSource) / span : prevTarget; +} +var TimeSeriesScale2 = class extends TimeScale2 { + constructor(props) { + super(props); + this._table = []; + this._minPos = void 0; + this._tableRange = void 0; + } + initOffsets() { + const timestamps = this._getTimestampsForTable(); + const table = this._table = this.buildLookupTable(timestamps); + this._minPos = interpolate4(table, this.min); + this._tableRange = interpolate4(table, this.max) - this._minPos; + super.initOffsets(timestamps); + } + buildLookupTable(timestamps) { + const { min, max } = this; + const items = []; + const table = []; + let i, ilen, prev, curr, next; + for (i = 0, ilen = timestamps.length; i < ilen; ++i) { + curr = timestamps[i]; + if (curr >= min && curr <= max) { + items.push(curr); + } + } + if (items.length < 2) { + return [ + { + time: min, + pos: 0 + }, + { + time: max, + pos: 1 + } + ]; + } + for (i = 0, ilen = items.length; i < ilen; ++i) { + next = items[i + 1]; + prev = items[i - 1]; + curr = items[i]; + if (Math.round((next + prev) / 2) !== curr) { + table.push({ + time: curr, + pos: i / (ilen - 1) + }); + } + } + return table; + } + _generate() { + const min = this.min; + const max = this.max; + let timestamps = super.getDataTimestamps(); + if (!timestamps.includes(min) || !timestamps.length) { + timestamps.splice(0, 0, min); + } + if (!timestamps.includes(max) || timestamps.length === 1) { + timestamps.push(max); + } + return timestamps.sort((a, b) => a - b); + } + _getTimestampsForTable() { + let timestamps = this._cache.all || []; + if (timestamps.length) { + return timestamps; + } + const data = this.getDataTimestamps(); + const label = this.getLabelTimestamps(); + if (data.length && label.length) { + timestamps = this.normalize(data.concat(label)); + } else { + timestamps = data.length ? data : label; + } + timestamps = this._cache.all = timestamps; + return timestamps; + } + getDecimalForValue(value) { + return (interpolate4(this._table, value) - this._minPos) / this._tableRange; + } + getValueForPixel(pixel) { + const offsets = this._offsets; + const decimal = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end; + return interpolate4(this._table, decimal * this._tableRange + this._minPos, true); + } +}; +__publicField(TimeSeriesScale2, "id", "timeseries"); +__publicField(TimeSeriesScale2, "defaults", TimeScale2.defaults); + +// ../../../node_modules/luxon/src/errors.js +var LuxonError = class extends Error { +}; +var InvalidDateTimeError = class extends LuxonError { + constructor(reason) { + super(`Invalid DateTime: ${reason.toMessage()}`); + } +}; +var InvalidIntervalError = class extends LuxonError { + constructor(reason) { + super(`Invalid Interval: ${reason.toMessage()}`); + } +}; +var InvalidDurationError = class extends LuxonError { + constructor(reason) { + super(`Invalid Duration: ${reason.toMessage()}`); + } +}; +var ConflictingSpecificationError = class extends LuxonError { +}; +var InvalidUnitError = class extends LuxonError { + constructor(unit) { + super(`Invalid unit ${unit}`); + } +}; +var InvalidArgumentError = class extends LuxonError { +}; +var ZoneIsAbstractError = class extends LuxonError { + constructor() { + super("Zone is an abstract class"); + } +}; + +// ../../../node_modules/luxon/src/impl/formats.js +var n = "numeric"; +var s = "short"; +var l = "long"; +var DATE_SHORT = { + year: n, + month: n, + day: n +}; +var DATE_MED = { + year: n, + month: s, + day: n +}; +var DATE_MED_WITH_WEEKDAY = { + year: n, + month: s, + day: n, + weekday: s +}; +var DATE_FULL = { + year: n, + month: l, + day: n +}; +var DATE_HUGE = { + year: n, + month: l, + day: n, + weekday: l +}; +var TIME_SIMPLE = { + hour: n, + minute: n +}; +var TIME_WITH_SECONDS = { + hour: n, + minute: n, + second: n +}; +var TIME_WITH_SHORT_OFFSET = { + hour: n, + minute: n, + second: n, + timeZoneName: s +}; +var TIME_WITH_LONG_OFFSET = { + hour: n, + minute: n, + second: n, + timeZoneName: l +}; +var TIME_24_SIMPLE = { + hour: n, + minute: n, + hourCycle: "h23" +}; +var TIME_24_WITH_SECONDS = { + hour: n, + minute: n, + second: n, + hourCycle: "h23" +}; +var TIME_24_WITH_SHORT_OFFSET = { + hour: n, + minute: n, + second: n, + hourCycle: "h23", + timeZoneName: s +}; +var TIME_24_WITH_LONG_OFFSET = { + hour: n, + minute: n, + second: n, + hourCycle: "h23", + timeZoneName: l +}; +var DATETIME_SHORT = { + year: n, + month: n, + day: n, + hour: n, + minute: n +}; +var DATETIME_SHORT_WITH_SECONDS = { + year: n, + month: n, + day: n, + hour: n, + minute: n, + second: n +}; +var DATETIME_MED = { + year: n, + month: s, + day: n, + hour: n, + minute: n +}; +var DATETIME_MED_WITH_SECONDS = { + year: n, + month: s, + day: n, + hour: n, + minute: n, + second: n +}; +var DATETIME_MED_WITH_WEEKDAY = { + year: n, + month: s, + day: n, + weekday: s, + hour: n, + minute: n +}; +var DATETIME_FULL = { + year: n, + month: l, + day: n, + hour: n, + minute: n, + timeZoneName: s +}; +var DATETIME_FULL_WITH_SECONDS = { + year: n, + month: l, + day: n, + hour: n, + minute: n, + second: n, + timeZoneName: s +}; +var DATETIME_HUGE = { + year: n, + month: l, + day: n, + weekday: l, + hour: n, + minute: n, + timeZoneName: l +}; +var DATETIME_HUGE_WITH_SECONDS = { + year: n, + month: l, + day: n, + weekday: l, + hour: n, + minute: n, + second: n, + timeZoneName: l +}; + +// ../../../node_modules/luxon/src/zone.js +var Zone = class { + /** + * The type of zone + * @abstract + * @type {string} + */ + get type() { + throw new ZoneIsAbstractError(); + } + /** + * The name of this zone. + * @abstract + * @type {string} + */ + get name() { + throw new ZoneIsAbstractError(); + } + get ianaName() { + return this.name; + } + /** + * Returns whether the offset is known to be fixed for the whole year. + * @abstract + * @type {boolean} + */ + get isUniversal() { + throw new ZoneIsAbstractError(); + } + /** + * Returns the offset's common name (such as EST) at the specified timestamp + * @abstract + * @param {number} ts - Epoch milliseconds for which to get the name + * @param {Object} opts - Options to affect the format + * @param {string} opts.format - What style of offset to return. Accepts 'long' or 'short'. + * @param {string} opts.locale - What locale to return the offset name in. + * @return {string} + */ + offsetName(ts, opts) { + throw new ZoneIsAbstractError(); + } + /** + * Returns the offset's value as a string + * @abstract + * @param {number} ts - Epoch milliseconds for which to get the offset + * @param {string} format - What style of offset to return. + * Accepts 'narrow', 'short', or 'techie'. Returning '+6', '+06:00', or '+0600' respectively + * @return {string} + */ + formatOffset(ts, format) { + throw new ZoneIsAbstractError(); + } + /** + * Return the offset in minutes for this zone at the specified timestamp. + * @abstract + * @param {number} ts - Epoch milliseconds for which to compute the offset + * @return {number} + */ + offset(ts) { + throw new ZoneIsAbstractError(); + } + /** + * Return whether this Zone is equal to another zone + * @abstract + * @param {Zone} otherZone - the zone to compare + * @return {boolean} + */ + equals(otherZone) { + throw new ZoneIsAbstractError(); + } + /** + * Return whether this Zone is valid. + * @abstract + * @type {boolean} + */ + get isValid() { + throw new ZoneIsAbstractError(); + } +}; + +// ../../../node_modules/luxon/src/zones/systemZone.js +var singleton = null; +var SystemZone = class extends Zone { + /** + * Get a singleton instance of the local zone + * @return {SystemZone} + */ + static get instance() { + if (singleton === null) { + singleton = new SystemZone(); + } + return singleton; + } + /** @override **/ + get type() { + return "system"; + } + /** @override **/ + get name() { + return new Intl.DateTimeFormat().resolvedOptions().timeZone; + } + /** @override **/ + get isUniversal() { + return false; + } + /** @override **/ + offsetName(ts, { format, locale }) { + return parseZoneInfo(ts, format, locale); + } + /** @override **/ + formatOffset(ts, format) { + return formatOffset(this.offset(ts), format); + } + /** @override **/ + offset(ts) { + return -new Date(ts).getTimezoneOffset(); + } + /** @override **/ + equals(otherZone) { + return otherZone.type === "system"; + } + /** @override **/ + get isValid() { + return true; + } +}; + +// ../../../node_modules/luxon/src/zones/IANAZone.js +var dtfCache = {}; +function makeDTF(zone) { + if (!dtfCache[zone]) { + dtfCache[zone] = new Intl.DateTimeFormat("en-US", { + hour12: false, + timeZone: zone, + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + era: "short" + }); + } + return dtfCache[zone]; +} +var typeToPos = { + year: 0, + month: 1, + day: 2, + era: 3, + hour: 4, + minute: 5, + second: 6 +}; +function hackyOffset(dtf, date) { + const formatted = dtf.format(date).replace(/\u200E/g, ""), parsed = /(\d+)\/(\d+)\/(\d+) (AD|BC),? (\d+):(\d+):(\d+)/.exec(formatted), [, fMonth, fDay, fYear, fadOrBc, fHour, fMinute, fSecond] = parsed; + return [fYear, fMonth, fDay, fadOrBc, fHour, fMinute, fSecond]; +} +function partsOffset(dtf, date) { + const formatted = dtf.formatToParts(date); + const filled = []; + for (let i = 0; i < formatted.length; i++) { + const { type, value } = formatted[i]; + const pos = typeToPos[type]; + if (type === "era") { + filled[pos] = value; + } else if (!isUndefined(pos)) { + filled[pos] = parseInt(value, 10); + } + } + return filled; +} +var ianaZoneCache = {}; +var IANAZone = class extends Zone { + /** + * @param {string} name - Zone name + * @return {IANAZone} + */ + static create(name) { + if (!ianaZoneCache[name]) { + ianaZoneCache[name] = new IANAZone(name); + } + return ianaZoneCache[name]; + } + /** + * Reset local caches. Should only be necessary in testing scenarios. + * @return {void} + */ + static resetCache() { + ianaZoneCache = {}; + dtfCache = {}; + } + /** + * Returns whether the provided string is a valid specifier. This only checks the string's format, not that the specifier identifies a known zone; see isValidZone for that. + * @param {string} s - The string to check validity on + * @example IANAZone.isValidSpecifier("America/New_York") //=> true + * @example IANAZone.isValidSpecifier("Sport~~blorp") //=> false + * @deprecated This method returns false for some valid IANA names. Use isValidZone instead. + * @return {boolean} + */ + static isValidSpecifier(s2) { + return this.isValidZone(s2); + } + /** + * Returns whether the provided string identifies a real zone + * @param {string} zone - The string to check + * @example IANAZone.isValidZone("America/New_York") //=> true + * @example IANAZone.isValidZone("Fantasia/Castle") //=> false + * @example IANAZone.isValidZone("Sport~~blorp") //=> false + * @return {boolean} + */ + static isValidZone(zone) { + if (!zone) { + return false; + } + try { + new Intl.DateTimeFormat("en-US", { timeZone: zone }).format(); + return true; + } catch (e) { + return false; + } + } + constructor(name) { + super(); + this.zoneName = name; + this.valid = IANAZone.isValidZone(name); + } + /** @override **/ + get type() { + return "iana"; + } + /** @override **/ + get name() { + return this.zoneName; + } + /** @override **/ + get isUniversal() { + return false; + } + /** @override **/ + offsetName(ts, { format, locale }) { + return parseZoneInfo(ts, format, locale, this.name); + } + /** @override **/ + formatOffset(ts, format) { + return formatOffset(this.offset(ts), format); + } + /** @override **/ + offset(ts) { + const date = new Date(ts); + if (isNaN(date)) + return NaN; + const dtf = makeDTF(this.name); + let [year, month, day, adOrBc, hour, minute, second] = dtf.formatToParts ? partsOffset(dtf, date) : hackyOffset(dtf, date); + if (adOrBc === "BC") { + year = -Math.abs(year) + 1; + } + const adjustedHour = hour === 24 ? 0 : hour; + const asUTC = objToLocalTS({ + year, + month, + day, + hour: adjustedHour, + minute, + second, + millisecond: 0 + }); + let asTS = +date; + const over = asTS % 1e3; + asTS -= over >= 0 ? over : 1e3 + over; + return (asUTC - asTS) / (60 * 1e3); + } + /** @override **/ + equals(otherZone) { + return otherZone.type === "iana" && otherZone.name === this.name; + } + /** @override **/ + get isValid() { + return this.valid; + } +}; + +// ../../../node_modules/luxon/src/impl/locale.js +var intlLFCache = {}; +function getCachedLF(locString, opts = {}) { + const key = JSON.stringify([locString, opts]); + let dtf = intlLFCache[key]; + if (!dtf) { + dtf = new Intl.ListFormat(locString, opts); + intlLFCache[key] = dtf; + } + return dtf; +} +var intlDTCache = {}; +function getCachedDTF(locString, opts = {}) { + const key = JSON.stringify([locString, opts]); + let dtf = intlDTCache[key]; + if (!dtf) { + dtf = new Intl.DateTimeFormat(locString, opts); + intlDTCache[key] = dtf; + } + return dtf; +} +var intlNumCache = {}; +function getCachedINF(locString, opts = {}) { + const key = JSON.stringify([locString, opts]); + let inf = intlNumCache[key]; + if (!inf) { + inf = new Intl.NumberFormat(locString, opts); + intlNumCache[key] = inf; + } + return inf; +} +var intlRelCache = {}; +function getCachedRTF(locString, opts = {}) { + const { base, ...cacheKeyOpts } = opts; + const key = JSON.stringify([locString, cacheKeyOpts]); + let inf = intlRelCache[key]; + if (!inf) { + inf = new Intl.RelativeTimeFormat(locString, opts); + intlRelCache[key] = inf; + } + return inf; +} +var sysLocaleCache = null; +function systemLocale() { + if (sysLocaleCache) { + return sysLocaleCache; + } else { + sysLocaleCache = new Intl.DateTimeFormat().resolvedOptions().locale; + return sysLocaleCache; + } +} +var weekInfoCache = {}; +function getCachedWeekInfo(locString) { + let data = weekInfoCache[locString]; + if (!data) { + const locale = new Intl.Locale(locString); + data = "getWeekInfo" in locale ? locale.getWeekInfo() : locale.weekInfo; + weekInfoCache[locString] = data; + } + return data; +} +function parseLocaleString(localeStr) { + const xIndex = localeStr.indexOf("-x-"); + if (xIndex !== -1) { + localeStr = localeStr.substring(0, xIndex); + } + const uIndex = localeStr.indexOf("-u-"); + if (uIndex === -1) { + return [localeStr]; + } else { + let options; + let selectedStr; + try { + options = getCachedDTF(localeStr).resolvedOptions(); + selectedStr = localeStr; + } catch (e) { + const smaller = localeStr.substring(0, uIndex); + options = getCachedDTF(smaller).resolvedOptions(); + selectedStr = smaller; + } + const { numberingSystem, calendar } = options; + return [selectedStr, numberingSystem, calendar]; + } +} +function intlConfigString(localeStr, numberingSystem, outputCalendar) { + if (outputCalendar || numberingSystem) { + if (!localeStr.includes("-u-")) { + localeStr += "-u"; + } + if (outputCalendar) { + localeStr += `-ca-${outputCalendar}`; + } + if (numberingSystem) { + localeStr += `-nu-${numberingSystem}`; + } + return localeStr; + } else { + return localeStr; + } +} +function mapMonths(f) { + const ms = []; + for (let i = 1; i <= 12; i++) { + const dt = DateTime.utc(2009, i, 1); + ms.push(f(dt)); + } + return ms; +} +function mapWeekdays(f) { + const ms = []; + for (let i = 1; i <= 7; i++) { + const dt = DateTime.utc(2016, 11, 13 + i); + ms.push(f(dt)); + } + return ms; +} +function listStuff(loc, length, englishFn, intlFn) { + const mode = loc.listingMode(); + if (mode === "error") { + return null; + } else if (mode === "en") { + return englishFn(length); + } else { + return intlFn(length); + } +} +function supportsFastNumbers(loc) { + if (loc.numberingSystem && loc.numberingSystem !== "latn") { + return false; + } else { + return loc.numberingSystem === "latn" || !loc.locale || loc.locale.startsWith("en") || new Intl.DateTimeFormat(loc.intl).resolvedOptions().numberingSystem === "latn"; + } +} +var PolyNumberFormatter = class { + constructor(intl, forceSimple, opts) { + this.padTo = opts.padTo || 0; + this.floor = opts.floor || false; + const { padTo, floor, ...otherOpts } = opts; + if (!forceSimple || Object.keys(otherOpts).length > 0) { + const intlOpts = { useGrouping: false, ...opts }; + if (opts.padTo > 0) + intlOpts.minimumIntegerDigits = opts.padTo; + this.inf = getCachedINF(intl, intlOpts); + } + } + format(i) { + if (this.inf) { + const fixed = this.floor ? Math.floor(i) : i; + return this.inf.format(fixed); + } else { + const fixed = this.floor ? Math.floor(i) : roundTo(i, 3); + return padStart(fixed, this.padTo); + } + } +}; +var PolyDateFormatter = class { + constructor(dt, intl, opts) { + this.opts = opts; + this.originalZone = void 0; + let z = void 0; + if (this.opts.timeZone) { + this.dt = dt; + } else if (dt.zone.type === "fixed") { + const gmtOffset = -1 * (dt.offset / 60); + const offsetZ = gmtOffset >= 0 ? `Etc/GMT+${gmtOffset}` : `Etc/GMT${gmtOffset}`; + if (dt.offset !== 0 && IANAZone.create(offsetZ).valid) { + z = offsetZ; + this.dt = dt; + } else { + z = "UTC"; + this.dt = dt.offset === 0 ? dt : dt.setZone("UTC").plus({ minutes: dt.offset }); + this.originalZone = dt.zone; + } + } else if (dt.zone.type === "system") { + this.dt = dt; + } else if (dt.zone.type === "iana") { + this.dt = dt; + z = dt.zone.name; + } else { + z = "UTC"; + this.dt = dt.setZone("UTC").plus({ minutes: dt.offset }); + this.originalZone = dt.zone; + } + const intlOpts = { ...this.opts }; + intlOpts.timeZone = intlOpts.timeZone || z; + this.dtf = getCachedDTF(intl, intlOpts); + } + format() { + if (this.originalZone) { + return this.formatToParts().map(({ value }) => value).join(""); + } + return this.dtf.format(this.dt.toJSDate()); + } + formatToParts() { + const parts = this.dtf.formatToParts(this.dt.toJSDate()); + if (this.originalZone) { + return parts.map((part) => { + if (part.type === "timeZoneName") { + const offsetName = this.originalZone.offsetName(this.dt.ts, { + locale: this.dt.locale, + format: this.opts.timeZoneName + }); + return { + ...part, + value: offsetName + }; + } else { + return part; + } + }); + } + return parts; + } + resolvedOptions() { + return this.dtf.resolvedOptions(); + } +}; +var PolyRelFormatter = class { + constructor(intl, isEnglish, opts) { + this.opts = { style: "long", ...opts }; + if (!isEnglish && hasRelative()) { + this.rtf = getCachedRTF(intl, opts); + } + } + format(count, unit) { + if (this.rtf) { + return this.rtf.format(count, unit); + } else { + return formatRelativeTime(unit, count, this.opts.numeric, this.opts.style !== "long"); + } + } + formatToParts(count, unit) { + if (this.rtf) { + return this.rtf.formatToParts(count, unit); + } else { + return []; + } + } +}; +var fallbackWeekSettings = { + firstDay: 1, + minimalDays: 4, + weekend: [6, 7] +}; +var Locale = class { + static fromOpts(opts) { + return Locale.create( + opts.locale, + opts.numberingSystem, + opts.outputCalendar, + opts.weekSettings, + opts.defaultToEN + ); + } + static create(locale, numberingSystem, outputCalendar, weekSettings, defaultToEN = false) { + const specifiedLocale = locale || Settings.defaultLocale; + const localeR = specifiedLocale || (defaultToEN ? "en-US" : systemLocale()); + const numberingSystemR = numberingSystem || Settings.defaultNumberingSystem; + const outputCalendarR = outputCalendar || Settings.defaultOutputCalendar; + const weekSettingsR = validateWeekSettings(weekSettings) || Settings.defaultWeekSettings; + return new Locale(localeR, numberingSystemR, outputCalendarR, weekSettingsR, specifiedLocale); + } + static resetCache() { + sysLocaleCache = null; + intlDTCache = {}; + intlNumCache = {}; + intlRelCache = {}; + } + static fromObject({ locale, numberingSystem, outputCalendar, weekSettings } = {}) { + return Locale.create(locale, numberingSystem, outputCalendar, weekSettings); + } + constructor(locale, numbering, outputCalendar, weekSettings, specifiedLocale) { + const [parsedLocale, parsedNumberingSystem, parsedOutputCalendar] = parseLocaleString(locale); + this.locale = parsedLocale; + this.numberingSystem = numbering || parsedNumberingSystem || null; + this.outputCalendar = outputCalendar || parsedOutputCalendar || null; + this.weekSettings = weekSettings; + this.intl = intlConfigString(this.locale, this.numberingSystem, this.outputCalendar); + this.weekdaysCache = { format: {}, standalone: {} }; + this.monthsCache = { format: {}, standalone: {} }; + this.meridiemCache = null; + this.eraCache = {}; + this.specifiedLocale = specifiedLocale; + this.fastNumbersCached = null; + } + get fastNumbers() { + if (this.fastNumbersCached == null) { + this.fastNumbersCached = supportsFastNumbers(this); + } + return this.fastNumbersCached; + } + listingMode() { + const isActuallyEn = this.isEnglish(); + const hasNoWeirdness = (this.numberingSystem === null || this.numberingSystem === "latn") && (this.outputCalendar === null || this.outputCalendar === "gregory"); + return isActuallyEn && hasNoWeirdness ? "en" : "intl"; + } + clone(alts) { + if (!alts || Object.getOwnPropertyNames(alts).length === 0) { + return this; + } else { + return Locale.create( + alts.locale || this.specifiedLocale, + alts.numberingSystem || this.numberingSystem, + alts.outputCalendar || this.outputCalendar, + validateWeekSettings(alts.weekSettings) || this.weekSettings, + alts.defaultToEN || false + ); + } + } + redefaultToEN(alts = {}) { + return this.clone({ ...alts, defaultToEN: true }); + } + redefaultToSystem(alts = {}) { + return this.clone({ ...alts, defaultToEN: false }); + } + months(length, format = false) { + return listStuff(this, length, months, () => { + const intl = format ? { month: length, day: "numeric" } : { month: length }, formatStr = format ? "format" : "standalone"; + if (!this.monthsCache[formatStr][length]) { + this.monthsCache[formatStr][length] = mapMonths((dt) => this.extract(dt, intl, "month")); + } + return this.monthsCache[formatStr][length]; + }); + } + weekdays(length, format = false) { + return listStuff(this, length, weekdays, () => { + const intl = format ? { weekday: length, year: "numeric", month: "long", day: "numeric" } : { weekday: length }, formatStr = format ? "format" : "standalone"; + if (!this.weekdaysCache[formatStr][length]) { + this.weekdaysCache[formatStr][length] = mapWeekdays( + (dt) => this.extract(dt, intl, "weekday") + ); + } + return this.weekdaysCache[formatStr][length]; + }); + } + meridiems() { + return listStuff( + this, + void 0, + () => meridiems, + () => { + if (!this.meridiemCache) { + const intl = { hour: "numeric", hourCycle: "h12" }; + this.meridiemCache = [DateTime.utc(2016, 11, 13, 9), DateTime.utc(2016, 11, 13, 19)].map( + (dt) => this.extract(dt, intl, "dayperiod") + ); + } + return this.meridiemCache; + } + ); + } + eras(length) { + return listStuff(this, length, eras, () => { + const intl = { era: length }; + if (!this.eraCache[length]) { + this.eraCache[length] = [DateTime.utc(-40, 1, 1), DateTime.utc(2017, 1, 1)].map( + (dt) => this.extract(dt, intl, "era") + ); + } + return this.eraCache[length]; + }); + } + extract(dt, intlOpts, field) { + const df = this.dtFormatter(dt, intlOpts), results = df.formatToParts(), matching = results.find((m) => m.type.toLowerCase() === field); + return matching ? matching.value : null; + } + numberFormatter(opts = {}) { + return new PolyNumberFormatter(this.intl, opts.forceSimple || this.fastNumbers, opts); + } + dtFormatter(dt, intlOpts = {}) { + return new PolyDateFormatter(dt, this.intl, intlOpts); + } + relFormatter(opts = {}) { + return new PolyRelFormatter(this.intl, this.isEnglish(), opts); + } + listFormatter(opts = {}) { + return getCachedLF(this.intl, opts); + } + isEnglish() { + return this.locale === "en" || this.locale.toLowerCase() === "en-us" || new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us"); + } + getWeekSettings() { + if (this.weekSettings) { + return this.weekSettings; + } else if (!hasLocaleWeekInfo()) { + return fallbackWeekSettings; + } else { + return getCachedWeekInfo(this.locale); + } + } + getStartOfWeek() { + return this.getWeekSettings().firstDay; + } + getMinDaysInFirstWeek() { + return this.getWeekSettings().minimalDays; + } + getWeekendDays() { + return this.getWeekSettings().weekend; + } + equals(other) { + return this.locale === other.locale && this.numberingSystem === other.numberingSystem && this.outputCalendar === other.outputCalendar; + } +}; + +// ../../../node_modules/luxon/src/zones/fixedOffsetZone.js +var singleton2 = null; +var FixedOffsetZone = class extends Zone { + /** + * Get a singleton instance of UTC + * @return {FixedOffsetZone} + */ + static get utcInstance() { + if (singleton2 === null) { + singleton2 = new FixedOffsetZone(0); + } + return singleton2; + } + /** + * Get an instance with a specified offset + * @param {number} offset - The offset in minutes + * @return {FixedOffsetZone} + */ + static instance(offset2) { + return offset2 === 0 ? FixedOffsetZone.utcInstance : new FixedOffsetZone(offset2); + } + /** + * Get an instance of FixedOffsetZone from a UTC offset string, like "UTC+6" + * @param {string} s - The offset string to parse + * @example FixedOffsetZone.parseSpecifier("UTC+6") + * @example FixedOffsetZone.parseSpecifier("UTC+06") + * @example FixedOffsetZone.parseSpecifier("UTC-6:00") + * @return {FixedOffsetZone} + */ + static parseSpecifier(s2) { + if (s2) { + const r = s2.match(/^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$/i); + if (r) { + return new FixedOffsetZone(signedOffset(r[1], r[2])); + } + } + return null; + } + constructor(offset2) { + super(); + this.fixed = offset2; + } + /** @override **/ + get type() { + return "fixed"; + } + /** @override **/ + get name() { + return this.fixed === 0 ? "UTC" : `UTC${formatOffset(this.fixed, "narrow")}`; + } + get ianaName() { + if (this.fixed === 0) { + return "Etc/UTC"; + } else { + return `Etc/GMT${formatOffset(-this.fixed, "narrow")}`; + } + } + /** @override **/ + offsetName() { + return this.name; + } + /** @override **/ + formatOffset(ts, format) { + return formatOffset(this.fixed, format); + } + /** @override **/ + get isUniversal() { + return true; + } + /** @override **/ + offset() { + return this.fixed; + } + /** @override **/ + equals(otherZone) { + return otherZone.type === "fixed" && otherZone.fixed === this.fixed; + } + /** @override **/ + get isValid() { + return true; + } +}; + +// ../../../node_modules/luxon/src/zones/invalidZone.js +var InvalidZone = class extends Zone { + constructor(zoneName) { + super(); + this.zoneName = zoneName; + } + /** @override **/ + get type() { + return "invalid"; + } + /** @override **/ + get name() { + return this.zoneName; + } + /** @override **/ + get isUniversal() { + return false; + } + /** @override **/ + offsetName() { + return null; + } + /** @override **/ + formatOffset() { + return ""; + } + /** @override **/ + offset() { + return NaN; + } + /** @override **/ + equals() { + return false; + } + /** @override **/ + get isValid() { + return false; + } +}; + +// ../../../node_modules/luxon/src/impl/zoneUtil.js +function normalizeZone(input, defaultZone2) { + let offset2; + if (isUndefined(input) || input === null) { + return defaultZone2; + } else if (input instanceof Zone) { + return input; + } else if (isString(input)) { + const lowered = input.toLowerCase(); + if (lowered === "default") + return defaultZone2; + else if (lowered === "local" || lowered === "system") + return SystemZone.instance; + else if (lowered === "utc" || lowered === "gmt") + return FixedOffsetZone.utcInstance; + else + return FixedOffsetZone.parseSpecifier(lowered) || IANAZone.create(input); + } else if (isNumber3(input)) { + return FixedOffsetZone.instance(input); + } else if (typeof input === "object" && "offset" in input && typeof input.offset === "function") { + return input; + } else { + return new InvalidZone(input); + } +} + +// ../../../node_modules/luxon/src/settings.js +var now = () => Date.now(); +var defaultZone = "system"; +var defaultLocale = null; +var defaultNumberingSystem = null; +var defaultOutputCalendar = null; +var twoDigitCutoffYear = 60; +var throwOnInvalid; +var defaultWeekSettings = null; +var Settings = class { + /** + * Get the callback for returning the current timestamp. + * @type {function} + */ + static get now() { + return now; + } + /** + * Set the callback for returning the current timestamp. + * The function should return a number, which will be interpreted as an Epoch millisecond count + * @type {function} + * @example Settings.now = () => Date.now() + 3000 // pretend it is 3 seconds in the future + * @example Settings.now = () => 0 // always pretend it's Jan 1, 1970 at midnight in UTC time + */ + static set now(n2) { + now = n2; + } + /** + * Set the default time zone to create DateTimes in. Does not affect existing instances. + * Use the value "system" to reset this value to the system's time zone. + * @type {string} + */ + static set defaultZone(zone) { + defaultZone = zone; + } + /** + * Get the default time zone object currently used to create DateTimes. Does not affect existing instances. + * The default value is the system's time zone (the one set on the machine that runs this code). + * @type {Zone} + */ + static get defaultZone() { + return normalizeZone(defaultZone, SystemZone.instance); + } + /** + * Get the default locale to create DateTimes with. Does not affect existing instances. + * @type {string} + */ + static get defaultLocale() { + return defaultLocale; + } + /** + * Set the default locale to create DateTimes with. Does not affect existing instances. + * @type {string} + */ + static set defaultLocale(locale) { + defaultLocale = locale; + } + /** + * Get the default numbering system to create DateTimes with. Does not affect existing instances. + * @type {string} + */ + static get defaultNumberingSystem() { + return defaultNumberingSystem; + } + /** + * Set the default numbering system to create DateTimes with. Does not affect existing instances. + * @type {string} + */ + static set defaultNumberingSystem(numberingSystem) { + defaultNumberingSystem = numberingSystem; + } + /** + * Get the default output calendar to create DateTimes with. Does not affect existing instances. + * @type {string} + */ + static get defaultOutputCalendar() { + return defaultOutputCalendar; + } + /** + * Set the default output calendar to create DateTimes with. Does not affect existing instances. + * @type {string} + */ + static set defaultOutputCalendar(outputCalendar) { + defaultOutputCalendar = outputCalendar; + } + /** + * @typedef {Object} WeekSettings + * @property {number} firstDay + * @property {number} minimalDays + * @property {number[]} weekend + */ + /** + * @return {WeekSettings|null} + */ + static get defaultWeekSettings() { + return defaultWeekSettings; + } + /** + * Allows overriding the default locale week settings, i.e. the start of the week, the weekend and + * how many days are required in the first week of a year. + * Does not affect existing instances. + * + * @param {WeekSettings|null} weekSettings + */ + static set defaultWeekSettings(weekSettings) { + defaultWeekSettings = validateWeekSettings(weekSettings); + } + /** + * Get the cutoff year after which a string encoding a year as two digits is interpreted to occur in the current century. + * @type {number} + */ + static get twoDigitCutoffYear() { + return twoDigitCutoffYear; + } + /** + * Set the cutoff year after which a string encoding a year as two digits is interpreted to occur in the current century. + * @type {number} + * @example Settings.twoDigitCutoffYear = 0 // cut-off year is 0, so all 'yy' are interpreted as current century + * @example Settings.twoDigitCutoffYear = 50 // '49' -> 1949; '50' -> 2050 + * @example Settings.twoDigitCutoffYear = 1950 // interpreted as 50 + * @example Settings.twoDigitCutoffYear = 2050 // ALSO interpreted as 50 + */ + static set twoDigitCutoffYear(cutoffYear) { + twoDigitCutoffYear = cutoffYear % 100; + } + /** + * Get whether Luxon will throw when it encounters invalid DateTimes, Durations, or Intervals + * @type {boolean} + */ + static get throwOnInvalid() { + return throwOnInvalid; + } + /** + * Set whether Luxon will throw when it encounters invalid DateTimes, Durations, or Intervals + * @type {boolean} + */ + static set throwOnInvalid(t) { + throwOnInvalid = t; + } + /** + * Reset Luxon's global caches. Should only be necessary in testing scenarios. + * @return {void} + */ + static resetCaches() { + Locale.resetCache(); + IANAZone.resetCache(); + } +}; + +// ../../../node_modules/luxon/src/impl/invalid.js +var Invalid = class { + constructor(reason, explanation) { + this.reason = reason; + this.explanation = explanation; + } + toMessage() { + if (this.explanation) { + return `${this.reason}: ${this.explanation}`; + } else { + return this.reason; + } + } +}; + +// ../../../node_modules/luxon/src/impl/conversions.js +var nonLeapLadder = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; +var leapLadder = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]; +function unitOutOfRange(unit, value) { + return new Invalid( + "unit out of range", + `you specified ${value} (of type ${typeof value}) as a ${unit}, which is invalid` + ); +} +function dayOfWeek(year, month, day) { + const d = new Date(Date.UTC(year, month - 1, day)); + if (year < 100 && year >= 0) { + d.setUTCFullYear(d.getUTCFullYear() - 1900); + } + const js = d.getUTCDay(); + return js === 0 ? 7 : js; +} +function computeOrdinal(year, month, day) { + return day + (isLeapYear(year) ? leapLadder : nonLeapLadder)[month - 1]; +} +function uncomputeOrdinal(year, ordinal) { + const table = isLeapYear(year) ? leapLadder : nonLeapLadder, month0 = table.findIndex((i) => i < ordinal), day = ordinal - table[month0]; + return { month: month0 + 1, day }; +} +function isoWeekdayToLocal(isoWeekday, startOfWeek) { + return (isoWeekday - startOfWeek + 7) % 7 + 1; +} +function gregorianToWeek(gregObj, minDaysInFirstWeek = 4, startOfWeek = 1) { + const { year, month, day } = gregObj, ordinal = computeOrdinal(year, month, day), weekday = isoWeekdayToLocal(dayOfWeek(year, month, day), startOfWeek); + let weekNumber = Math.floor((ordinal - weekday + 14 - minDaysInFirstWeek) / 7), weekYear; + if (weekNumber < 1) { + weekYear = year - 1; + weekNumber = weeksInWeekYear(weekYear, minDaysInFirstWeek, startOfWeek); + } else if (weekNumber > weeksInWeekYear(year, minDaysInFirstWeek, startOfWeek)) { + weekYear = year + 1; + weekNumber = 1; + } else { + weekYear = year; + } + return { weekYear, weekNumber, weekday, ...timeObject(gregObj) }; +} +function weekToGregorian(weekData, minDaysInFirstWeek = 4, startOfWeek = 1) { + const { weekYear, weekNumber, weekday } = weekData, weekdayOfJan4 = isoWeekdayToLocal(dayOfWeek(weekYear, 1, minDaysInFirstWeek), startOfWeek), yearInDays = daysInYear(weekYear); + let ordinal = weekNumber * 7 + weekday - weekdayOfJan4 - 7 + minDaysInFirstWeek, year; + if (ordinal < 1) { + year = weekYear - 1; + ordinal += daysInYear(year); + } else if (ordinal > yearInDays) { + year = weekYear + 1; + ordinal -= daysInYear(weekYear); + } else { + year = weekYear; + } + const { month, day } = uncomputeOrdinal(year, ordinal); + return { year, month, day, ...timeObject(weekData) }; +} +function gregorianToOrdinal(gregData) { + const { year, month, day } = gregData; + const ordinal = computeOrdinal(year, month, day); + return { year, ordinal, ...timeObject(gregData) }; +} +function ordinalToGregorian(ordinalData) { + const { year, ordinal } = ordinalData; + const { month, day } = uncomputeOrdinal(year, ordinal); + return { year, month, day, ...timeObject(ordinalData) }; +} +function usesLocalWeekValues(obj, loc) { + const hasLocaleWeekData = !isUndefined(obj.localWeekday) || !isUndefined(obj.localWeekNumber) || !isUndefined(obj.localWeekYear); + if (hasLocaleWeekData) { + const hasIsoWeekData = !isUndefined(obj.weekday) || !isUndefined(obj.weekNumber) || !isUndefined(obj.weekYear); + if (hasIsoWeekData) { + throw new ConflictingSpecificationError( + "Cannot mix locale-based week fields with ISO-based week fields" + ); + } + if (!isUndefined(obj.localWeekday)) + obj.weekday = obj.localWeekday; + if (!isUndefined(obj.localWeekNumber)) + obj.weekNumber = obj.localWeekNumber; + if (!isUndefined(obj.localWeekYear)) + obj.weekYear = obj.localWeekYear; + delete obj.localWeekday; + delete obj.localWeekNumber; + delete obj.localWeekYear; + return { + minDaysInFirstWeek: loc.getMinDaysInFirstWeek(), + startOfWeek: loc.getStartOfWeek() + }; + } else { + return { minDaysInFirstWeek: 4, startOfWeek: 1 }; + } +} +function hasInvalidWeekData(obj, minDaysInFirstWeek = 4, startOfWeek = 1) { + const validYear = isInteger(obj.weekYear), validWeek = integerBetween( + obj.weekNumber, + 1, + weeksInWeekYear(obj.weekYear, minDaysInFirstWeek, startOfWeek) + ), validWeekday = integerBetween(obj.weekday, 1, 7); + if (!validYear) { + return unitOutOfRange("weekYear", obj.weekYear); + } else if (!validWeek) { + return unitOutOfRange("week", obj.weekNumber); + } else if (!validWeekday) { + return unitOutOfRange("weekday", obj.weekday); + } else + return false; +} +function hasInvalidOrdinalData(obj) { + const validYear = isInteger(obj.year), validOrdinal = integerBetween(obj.ordinal, 1, daysInYear(obj.year)); + if (!validYear) { + return unitOutOfRange("year", obj.year); + } else if (!validOrdinal) { + return unitOutOfRange("ordinal", obj.ordinal); + } else + return false; +} +function hasInvalidGregorianData(obj) { + const validYear = isInteger(obj.year), validMonth = integerBetween(obj.month, 1, 12), validDay = integerBetween(obj.day, 1, daysInMonth(obj.year, obj.month)); + if (!validYear) { + return unitOutOfRange("year", obj.year); + } else if (!validMonth) { + return unitOutOfRange("month", obj.month); + } else if (!validDay) { + return unitOutOfRange("day", obj.day); + } else + return false; +} +function hasInvalidTimeData(obj) { + const { hour, minute, second, millisecond } = obj; + const validHour = integerBetween(hour, 0, 23) || hour === 24 && minute === 0 && second === 0 && millisecond === 0, validMinute = integerBetween(minute, 0, 59), validSecond = integerBetween(second, 0, 59), validMillisecond = integerBetween(millisecond, 0, 999); + if (!validHour) { + return unitOutOfRange("hour", hour); + } else if (!validMinute) { + return unitOutOfRange("minute", minute); + } else if (!validSecond) { + return unitOutOfRange("second", second); + } else if (!validMillisecond) { + return unitOutOfRange("millisecond", millisecond); + } else + return false; +} + +// ../../../node_modules/luxon/src/impl/util.js +function isUndefined(o) { + return typeof o === "undefined"; +} +function isNumber3(o) { + return typeof o === "number"; +} +function isInteger(o) { + return typeof o === "number" && o % 1 === 0; +} +function isString(o) { + return typeof o === "string"; +} +function isDate(o) { + return Object.prototype.toString.call(o) === "[object Date]"; +} +function hasRelative() { + try { + return typeof Intl !== "undefined" && !!Intl.RelativeTimeFormat; + } catch (e) { + return false; + } +} +function hasLocaleWeekInfo() { + try { + return typeof Intl !== "undefined" && !!Intl.Locale && ("weekInfo" in Intl.Locale.prototype || "getWeekInfo" in Intl.Locale.prototype); + } catch (e) { + return false; + } +} +function maybeArray(thing) { + return Array.isArray(thing) ? thing : [thing]; +} +function bestBy(arr, by, compare) { + if (arr.length === 0) { + return void 0; + } + return arr.reduce((best, next) => { + const pair = [by(next), next]; + if (!best) { + return pair; + } else if (compare(best[0], pair[0]) === best[0]) { + return best; + } else { + return pair; + } + }, null)[1]; +} +function pick(obj, keys) { + return keys.reduce((a, k) => { + a[k] = obj[k]; + return a; + }, {}); +} +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} +function validateWeekSettings(settings) { + if (settings == null) { + return null; + } else if (typeof settings !== "object") { + throw new InvalidArgumentError("Week settings must be an object"); + } else { + if (!integerBetween(settings.firstDay, 1, 7) || !integerBetween(settings.minimalDays, 1, 7) || !Array.isArray(settings.weekend) || settings.weekend.some((v) => !integerBetween(v, 1, 7))) { + throw new InvalidArgumentError("Invalid week settings"); + } + return { + firstDay: settings.firstDay, + minimalDays: settings.minimalDays, + weekend: Array.from(settings.weekend) + }; + } +} +function integerBetween(thing, bottom, top) { + return isInteger(thing) && thing >= bottom && thing <= top; +} +function floorMod(x, n2) { + return x - n2 * Math.floor(x / n2); +} +function padStart(input, n2 = 2) { + const isNeg = input < 0; + let padded; + if (isNeg) { + padded = "-" + ("" + -input).padStart(n2, "0"); + } else { + padded = ("" + input).padStart(n2, "0"); + } + return padded; +} +function parseInteger(string) { + if (isUndefined(string) || string === null || string === "") { + return void 0; + } else { + return parseInt(string, 10); + } +} +function parseFloating(string) { + if (isUndefined(string) || string === null || string === "") { + return void 0; + } else { + return parseFloat(string); + } +} +function parseMillis(fraction) { + if (isUndefined(fraction) || fraction === null || fraction === "") { + return void 0; + } else { + const f = parseFloat("0." + fraction) * 1e3; + return Math.floor(f); + } +} +function roundTo(number, digits, towardZero = false) { + const factor = 10 ** digits, rounder = towardZero ? Math.trunc : Math.round; + return rounder(number * factor) / factor; +} +function isLeapYear(year) { + return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); +} +function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; +} +function daysInMonth(year, month) { + const modMonth = floorMod(month - 1, 12) + 1, modYear = year + (month - modMonth) / 12; + if (modMonth === 2) { + return isLeapYear(modYear) ? 29 : 28; + } else { + return [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][modMonth - 1]; + } +} +function objToLocalTS(obj) { + let d = Date.UTC( + obj.year, + obj.month - 1, + obj.day, + obj.hour, + obj.minute, + obj.second, + obj.millisecond + ); + if (obj.year < 100 && obj.year >= 0) { + d = new Date(d); + d.setUTCFullYear(obj.year, obj.month - 1, obj.day); + } + return +d; +} +function firstWeekOffset(year, minDaysInFirstWeek, startOfWeek) { + const fwdlw = isoWeekdayToLocal(dayOfWeek(year, 1, minDaysInFirstWeek), startOfWeek); + return -fwdlw + minDaysInFirstWeek - 1; +} +function weeksInWeekYear(weekYear, minDaysInFirstWeek = 4, startOfWeek = 1) { + const weekOffset = firstWeekOffset(weekYear, minDaysInFirstWeek, startOfWeek); + const weekOffsetNext = firstWeekOffset(weekYear + 1, minDaysInFirstWeek, startOfWeek); + return (daysInYear(weekYear) - weekOffset + weekOffsetNext) / 7; +} +function untruncateYear(year) { + if (year > 99) { + return year; + } else + return year > Settings.twoDigitCutoffYear ? 1900 + year : 2e3 + year; +} +function parseZoneInfo(ts, offsetFormat, locale, timeZone = null) { + const date = new Date(ts), intlOpts = { + hourCycle: "h23", + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit" + }; + if (timeZone) { + intlOpts.timeZone = timeZone; + } + const modified = { timeZoneName: offsetFormat, ...intlOpts }; + const parsed = new Intl.DateTimeFormat(locale, modified).formatToParts(date).find((m) => m.type.toLowerCase() === "timezonename"); + return parsed ? parsed.value : null; +} +function signedOffset(offHourStr, offMinuteStr) { + let offHour = parseInt(offHourStr, 10); + if (Number.isNaN(offHour)) { + offHour = 0; + } + const offMin = parseInt(offMinuteStr, 10) || 0, offMinSigned = offHour < 0 || Object.is(offHour, -0) ? -offMin : offMin; + return offHour * 60 + offMinSigned; +} +function asNumber(value) { + const numericValue = Number(value); + if (typeof value === "boolean" || value === "" || Number.isNaN(numericValue)) + throw new InvalidArgumentError(`Invalid unit value ${value}`); + return numericValue; +} +function normalizeObject(obj, normalizer) { + const normalized = {}; + for (const u in obj) { + if (hasOwnProperty(obj, u)) { + const v = obj[u]; + if (v === void 0 || v === null) + continue; + normalized[normalizer(u)] = asNumber(v); + } + } + return normalized; +} +function formatOffset(offset2, format) { + const hours = Math.trunc(Math.abs(offset2 / 60)), minutes = Math.trunc(Math.abs(offset2 % 60)), sign3 = offset2 >= 0 ? "+" : "-"; + switch (format) { + case "short": + return `${sign3}${padStart(hours, 2)}:${padStart(minutes, 2)}`; + case "narrow": + return `${sign3}${hours}${minutes > 0 ? `:${minutes}` : ""}`; + case "techie": + return `${sign3}${padStart(hours, 2)}${padStart(minutes, 2)}`; + default: + throw new RangeError(`Value format ${format} is out of range for property format`); + } +} +function timeObject(obj) { + return pick(obj, ["hour", "minute", "second", "millisecond"]); +} + +// ../../../node_modules/luxon/src/impl/english.js +var monthsLong = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" +]; +var monthsShort = [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" +]; +var monthsNarrow = ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]; +function months(length) { + switch (length) { + case "narrow": + return [...monthsNarrow]; + case "short": + return [...monthsShort]; + case "long": + return [...monthsLong]; + case "numeric": + return ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]; + case "2-digit": + return ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]; + default: + return null; + } +} +var weekdaysLong = [ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday" +]; +var weekdaysShort = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; +var weekdaysNarrow = ["M", "T", "W", "T", "F", "S", "S"]; +function weekdays(length) { + switch (length) { + case "narrow": + return [...weekdaysNarrow]; + case "short": + return [...weekdaysShort]; + case "long": + return [...weekdaysLong]; + case "numeric": + return ["1", "2", "3", "4", "5", "6", "7"]; + default: + return null; + } +} +var meridiems = ["AM", "PM"]; +var erasLong = ["Before Christ", "Anno Domini"]; +var erasShort = ["BC", "AD"]; +var erasNarrow = ["B", "A"]; +function eras(length) { + switch (length) { + case "narrow": + return [...erasNarrow]; + case "short": + return [...erasShort]; + case "long": + return [...erasLong]; + default: + return null; + } +} +function meridiemForDateTime(dt) { + return meridiems[dt.hour < 12 ? 0 : 1]; +} +function weekdayForDateTime(dt, length) { + return weekdays(length)[dt.weekday - 1]; +} +function monthForDateTime(dt, length) { + return months(length)[dt.month - 1]; +} +function eraForDateTime(dt, length) { + return eras(length)[dt.year < 0 ? 0 : 1]; +} +function formatRelativeTime(unit, count, numeric = "always", narrow = false) { + const units = { + years: ["year", "yr."], + quarters: ["quarter", "qtr."], + months: ["month", "mo."], + weeks: ["week", "wk."], + days: ["day", "day", "days"], + hours: ["hour", "hr."], + minutes: ["minute", "min."], + seconds: ["second", "sec."] + }; + const lastable = ["hours", "minutes", "seconds"].indexOf(unit) === -1; + if (numeric === "auto" && lastable) { + const isDay = unit === "days"; + switch (count) { + case 1: + return isDay ? "tomorrow" : `next ${units[unit][0]}`; + case -1: + return isDay ? "yesterday" : `last ${units[unit][0]}`; + case 0: + return isDay ? "today" : `this ${units[unit][0]}`; + default: + } + } + const isInPast = Object.is(count, -0) || count < 0, fmtValue = Math.abs(count), singular = fmtValue === 1, lilUnits = units[unit], fmtUnit = narrow ? singular ? lilUnits[1] : lilUnits[2] || lilUnits[1] : singular ? units[unit][0] : unit; + return isInPast ? `${fmtValue} ${fmtUnit} ago` : `in ${fmtValue} ${fmtUnit}`; +} + +// ../../../node_modules/luxon/src/impl/formatter.js +function stringifyTokens(splits, tokenToString) { + let s2 = ""; + for (const token of splits) { + if (token.literal) { + s2 += token.val; + } else { + s2 += tokenToString(token.val); + } + } + return s2; +} +var macroTokenToFormatOpts = { + D: DATE_SHORT, + DD: DATE_MED, + DDD: DATE_FULL, + DDDD: DATE_HUGE, + t: TIME_SIMPLE, + tt: TIME_WITH_SECONDS, + ttt: TIME_WITH_SHORT_OFFSET, + tttt: TIME_WITH_LONG_OFFSET, + T: TIME_24_SIMPLE, + TT: TIME_24_WITH_SECONDS, + TTT: TIME_24_WITH_SHORT_OFFSET, + TTTT: TIME_24_WITH_LONG_OFFSET, + f: DATETIME_SHORT, + ff: DATETIME_MED, + fff: DATETIME_FULL, + ffff: DATETIME_HUGE, + F: DATETIME_SHORT_WITH_SECONDS, + FF: DATETIME_MED_WITH_SECONDS, + FFF: DATETIME_FULL_WITH_SECONDS, + FFFF: DATETIME_HUGE_WITH_SECONDS +}; +var Formatter = class { + static create(locale, opts = {}) { + return new Formatter(locale, opts); + } + static parseFormat(fmt) { + let current = null, currentFull = "", bracketed = false; + const splits = []; + for (let i = 0; i < fmt.length; i++) { + const c = fmt.charAt(i); + if (c === "'") { + if (currentFull.length > 0) { + splits.push({ literal: bracketed || /^\s+$/.test(currentFull), val: currentFull }); + } + current = null; + currentFull = ""; + bracketed = !bracketed; + } else if (bracketed) { + currentFull += c; + } else if (c === current) { + currentFull += c; + } else { + if (currentFull.length > 0) { + splits.push({ literal: /^\s+$/.test(currentFull), val: currentFull }); + } + currentFull = c; + current = c; + } + } + if (currentFull.length > 0) { + splits.push({ literal: bracketed || /^\s+$/.test(currentFull), val: currentFull }); + } + return splits; + } + static macroTokenToFormatOpts(token) { + return macroTokenToFormatOpts[token]; + } + constructor(locale, formatOpts) { + this.opts = formatOpts; + this.loc = locale; + this.systemLoc = null; + } + formatWithSystemDefault(dt, opts) { + if (this.systemLoc === null) { + this.systemLoc = this.loc.redefaultToSystem(); + } + const df = this.systemLoc.dtFormatter(dt, { ...this.opts, ...opts }); + return df.format(); + } + dtFormatter(dt, opts = {}) { + return this.loc.dtFormatter(dt, { ...this.opts, ...opts }); + } + formatDateTime(dt, opts) { + return this.dtFormatter(dt, opts).format(); + } + formatDateTimeParts(dt, opts) { + return this.dtFormatter(dt, opts).formatToParts(); + } + formatInterval(interval, opts) { + const df = this.dtFormatter(interval.start, opts); + return df.dtf.formatRange(interval.start.toJSDate(), interval.end.toJSDate()); + } + resolvedOptions(dt, opts) { + return this.dtFormatter(dt, opts).resolvedOptions(); + } + num(n2, p = 0) { + if (this.opts.forceSimple) { + return padStart(n2, p); + } + const opts = { ...this.opts }; + if (p > 0) { + opts.padTo = p; + } + return this.loc.numberFormatter(opts).format(n2); + } + formatDateTimeFromString(dt, fmt) { + const knownEnglish = this.loc.listingMode() === "en", useDateTimeFormatter = this.loc.outputCalendar && this.loc.outputCalendar !== "gregory", string = (opts, extract) => this.loc.extract(dt, opts, extract), formatOffset2 = (opts) => { + if (dt.isOffsetFixed && dt.offset === 0 && opts.allowZ) { + return "Z"; + } + return dt.isValid ? dt.zone.formatOffset(dt.ts, opts.format) : ""; + }, meridiem = () => knownEnglish ? meridiemForDateTime(dt) : string({ hour: "numeric", hourCycle: "h12" }, "dayperiod"), month = (length, standalone) => knownEnglish ? monthForDateTime(dt, length) : string(standalone ? { month: length } : { month: length, day: "numeric" }, "month"), weekday = (length, standalone) => knownEnglish ? weekdayForDateTime(dt, length) : string( + standalone ? { weekday: length } : { weekday: length, month: "long", day: "numeric" }, + "weekday" + ), maybeMacro = (token) => { + const formatOpts = Formatter.macroTokenToFormatOpts(token); + if (formatOpts) { + return this.formatWithSystemDefault(dt, formatOpts); + } else { + return token; + } + }, era = (length) => knownEnglish ? eraForDateTime(dt, length) : string({ era: length }, "era"), tokenToString = (token) => { + switch (token) { + case "S": + return this.num(dt.millisecond); + case "u": + case "SSS": + return this.num(dt.millisecond, 3); + case "s": + return this.num(dt.second); + case "ss": + return this.num(dt.second, 2); + case "uu": + return this.num(Math.floor(dt.millisecond / 10), 2); + case "uuu": + return this.num(Math.floor(dt.millisecond / 100)); + case "m": + return this.num(dt.minute); + case "mm": + return this.num(dt.minute, 2); + case "h": + return this.num(dt.hour % 12 === 0 ? 12 : dt.hour % 12); + case "hh": + return this.num(dt.hour % 12 === 0 ? 12 : dt.hour % 12, 2); + case "H": + return this.num(dt.hour); + case "HH": + return this.num(dt.hour, 2); + case "Z": + return formatOffset2({ format: "narrow", allowZ: this.opts.allowZ }); + case "ZZ": + return formatOffset2({ format: "short", allowZ: this.opts.allowZ }); + case "ZZZ": + return formatOffset2({ format: "techie", allowZ: this.opts.allowZ }); + case "ZZZZ": + return dt.zone.offsetName(dt.ts, { format: "short", locale: this.loc.locale }); + case "ZZZZZ": + return dt.zone.offsetName(dt.ts, { format: "long", locale: this.loc.locale }); + case "z": + return dt.zoneName; + case "a": + return meridiem(); + case "d": + return useDateTimeFormatter ? string({ day: "numeric" }, "day") : this.num(dt.day); + case "dd": + return useDateTimeFormatter ? string({ day: "2-digit" }, "day") : this.num(dt.day, 2); + case "c": + return this.num(dt.weekday); + case "ccc": + return weekday("short", true); + case "cccc": + return weekday("long", true); + case "ccccc": + return weekday("narrow", true); + case "E": + return this.num(dt.weekday); + case "EEE": + return weekday("short", false); + case "EEEE": + return weekday("long", false); + case "EEEEE": + return weekday("narrow", false); + case "L": + return useDateTimeFormatter ? string({ month: "numeric", day: "numeric" }, "month") : this.num(dt.month); + case "LL": + return useDateTimeFormatter ? string({ month: "2-digit", day: "numeric" }, "month") : this.num(dt.month, 2); + case "LLL": + return month("short", true); + case "LLLL": + return month("long", true); + case "LLLLL": + return month("narrow", true); + case "M": + return useDateTimeFormatter ? string({ month: "numeric" }, "month") : this.num(dt.month); + case "MM": + return useDateTimeFormatter ? string({ month: "2-digit" }, "month") : this.num(dt.month, 2); + case "MMM": + return month("short", false); + case "MMMM": + return month("long", false); + case "MMMMM": + return month("narrow", false); + case "y": + return useDateTimeFormatter ? string({ year: "numeric" }, "year") : this.num(dt.year); + case "yy": + return useDateTimeFormatter ? string({ year: "2-digit" }, "year") : this.num(dt.year.toString().slice(-2), 2); + case "yyyy": + return useDateTimeFormatter ? string({ year: "numeric" }, "year") : this.num(dt.year, 4); + case "yyyyyy": + return useDateTimeFormatter ? string({ year: "numeric" }, "year") : this.num(dt.year, 6); + case "G": + return era("short"); + case "GG": + return era("long"); + case "GGGGG": + return era("narrow"); + case "kk": + return this.num(dt.weekYear.toString().slice(-2), 2); + case "kkkk": + return this.num(dt.weekYear, 4); + case "W": + return this.num(dt.weekNumber); + case "WW": + return this.num(dt.weekNumber, 2); + case "n": + return this.num(dt.localWeekNumber); + case "nn": + return this.num(dt.localWeekNumber, 2); + case "ii": + return this.num(dt.localWeekYear.toString().slice(-2), 2); + case "iiii": + return this.num(dt.localWeekYear, 4); + case "o": + return this.num(dt.ordinal); + case "ooo": + return this.num(dt.ordinal, 3); + case "q": + return this.num(dt.quarter); + case "qq": + return this.num(dt.quarter, 2); + case "X": + return this.num(Math.floor(dt.ts / 1e3)); + case "x": + return this.num(dt.ts); + default: + return maybeMacro(token); + } + }; + return stringifyTokens(Formatter.parseFormat(fmt), tokenToString); + } + formatDurationFromString(dur, fmt) { + const tokenToField = (token) => { + switch (token[0]) { + case "S": + return "millisecond"; + case "s": + return "second"; + case "m": + return "minute"; + case "h": + return "hour"; + case "d": + return "day"; + case "w": + return "week"; + case "M": + return "month"; + case "y": + return "year"; + default: + return null; + } + }, tokenToString = (lildur) => (token) => { + const mapped = tokenToField(token); + if (mapped) { + return this.num(lildur.get(mapped), token.length); + } else { + return token; + } + }, tokens = Formatter.parseFormat(fmt), realTokens = tokens.reduce( + (found, { literal, val }) => literal ? found : found.concat(val), + [] + ), collapsed = dur.shiftTo(...realTokens.map(tokenToField).filter((t) => t)); + return stringifyTokens(tokens, tokenToString(collapsed)); + } +}; + +// ../../../node_modules/luxon/src/impl/regexParser.js +var ianaRegex = /[A-Za-z_+-]{1,256}(?::?\/[A-Za-z0-9_+-]{1,256}(?:\/[A-Za-z0-9_+-]{1,256})?)?/; +function combineRegexes(...regexes) { + const full = regexes.reduce((f, r) => f + r.source, ""); + return RegExp(`^${full}$`); +} +function combineExtractors(...extractors) { + return (m) => extractors.reduce( + ([mergedVals, mergedZone, cursor], ex) => { + const [val, zone, next] = ex(m, cursor); + return [{ ...mergedVals, ...val }, zone || mergedZone, next]; + }, + [{}, null, 1] + ).slice(0, 2); +} +function parse3(s2, ...patterns) { + if (s2 == null) { + return [null, null]; + } + for (const [regex, extractor] of patterns) { + const m = regex.exec(s2); + if (m) { + return extractor(m); + } + } + return [null, null]; +} +function simpleParse(...keys) { + return (match2, cursor) => { + const ret = {}; + let i; + for (i = 0; i < keys.length; i++) { + ret[keys[i]] = parseInteger(match2[cursor + i]); + } + return [ret, null, cursor + i]; + }; +} +var offsetRegex = /(?:(Z)|([+-]\d\d)(?::?(\d\d))?)/; +var isoExtendedZone = `(?:${offsetRegex.source}?(?:\\[(${ianaRegex.source})\\])?)?`; +var isoTimeBaseRegex = /(\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,30}))?)?)?/; +var isoTimeRegex = RegExp(`${isoTimeBaseRegex.source}${isoExtendedZone}`); +var isoTimeExtensionRegex = RegExp(`(?:T${isoTimeRegex.source})?`); +var isoYmdRegex = /([+-]\d{6}|\d{4})(?:-?(\d\d)(?:-?(\d\d))?)?/; +var isoWeekRegex = /(\d{4})-?W(\d\d)(?:-?(\d))?/; +var isoOrdinalRegex = /(\d{4})-?(\d{3})/; +var extractISOWeekData = simpleParse("weekYear", "weekNumber", "weekDay"); +var extractISOOrdinalData = simpleParse("year", "ordinal"); +var sqlYmdRegex = /(\d{4})-(\d\d)-(\d\d)/; +var sqlTimeRegex = RegExp( + `${isoTimeBaseRegex.source} ?(?:${offsetRegex.source}|(${ianaRegex.source}))?` +); +var sqlTimeExtensionRegex = RegExp(`(?: ${sqlTimeRegex.source})?`); +function int(match2, pos, fallback) { + const m = match2[pos]; + return isUndefined(m) ? fallback : parseInteger(m); +} +function extractISOYmd(match2, cursor) { + const item = { + year: int(match2, cursor), + month: int(match2, cursor + 1, 1), + day: int(match2, cursor + 2, 1) + }; + return [item, null, cursor + 3]; +} +function extractISOTime(match2, cursor) { + const item = { + hours: int(match2, cursor, 0), + minutes: int(match2, cursor + 1, 0), + seconds: int(match2, cursor + 2, 0), + milliseconds: parseMillis(match2[cursor + 3]) + }; + return [item, null, cursor + 4]; +} +function extractISOOffset(match2, cursor) { + const local = !match2[cursor] && !match2[cursor + 1], fullOffset = signedOffset(match2[cursor + 1], match2[cursor + 2]), zone = local ? null : FixedOffsetZone.instance(fullOffset); + return [{}, zone, cursor + 3]; +} +function extractIANAZone(match2, cursor) { + const zone = match2[cursor] ? IANAZone.create(match2[cursor]) : null; + return [{}, zone, cursor + 1]; +} +var isoTimeOnly = RegExp(`^T?${isoTimeBaseRegex.source}$`); +var isoDuration = /^-?P(?:(?:(-?\d{1,20}(?:\.\d{1,20})?)Y)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20}(?:\.\d{1,20})?)W)?(?:(-?\d{1,20}(?:\.\d{1,20})?)D)?(?:T(?:(-?\d{1,20}(?:\.\d{1,20})?)H)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20})(?:[.,](-?\d{1,20}))?S)?)?)$/; +function extractISODuration(match2) { + const [s2, yearStr, monthStr, weekStr, dayStr, hourStr, minuteStr, secondStr, millisecondsStr] = match2; + const hasNegativePrefix = s2[0] === "-"; + const negativeSeconds = secondStr && secondStr[0] === "-"; + const maybeNegate = (num, force = false) => num !== void 0 && (force || num && hasNegativePrefix) ? -num : num; + return [ + { + years: maybeNegate(parseFloating(yearStr)), + months: maybeNegate(parseFloating(monthStr)), + weeks: maybeNegate(parseFloating(weekStr)), + days: maybeNegate(parseFloating(dayStr)), + hours: maybeNegate(parseFloating(hourStr)), + minutes: maybeNegate(parseFloating(minuteStr)), + seconds: maybeNegate(parseFloating(secondStr), secondStr === "-0"), + milliseconds: maybeNegate(parseMillis(millisecondsStr), negativeSeconds) + } + ]; +} +var obsOffsets = { + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 +}; +function fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { + const result = { + year: yearStr.length === 2 ? untruncateYear(parseInteger(yearStr)) : parseInteger(yearStr), + month: monthsShort.indexOf(monthStr) + 1, + day: parseInteger(dayStr), + hour: parseInteger(hourStr), + minute: parseInteger(minuteStr) + }; + if (secondStr) + result.second = parseInteger(secondStr); + if (weekdayStr) { + result.weekday = weekdayStr.length > 3 ? weekdaysLong.indexOf(weekdayStr) + 1 : weekdaysShort.indexOf(weekdayStr) + 1; + } + return result; +} +var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/; +function extractRFC2822(match2) { + const [ + , + weekdayStr, + dayStr, + monthStr, + yearStr, + hourStr, + minuteStr, + secondStr, + obsOffset, + milOffset, + offHourStr, + offMinuteStr + ] = match2, result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr); + let offset2; + if (obsOffset) { + offset2 = obsOffsets[obsOffset]; + } else if (milOffset) { + offset2 = 0; + } else { + offset2 = signedOffset(offHourStr, offMinuteStr); + } + return [result, new FixedOffsetZone(offset2)]; +} +function preprocessRFC2822(s2) { + return s2.replace(/\([^()]*\)|[\n\t]/g, " ").replace(/(\s\s+)/g, " ").trim(); +} +var rfc1123 = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/; +var rfc850 = /^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/; +var ascii = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/; +function extractRFC1123Or850(match2) { + const [, weekdayStr, dayStr, monthStr, yearStr, hourStr, minuteStr, secondStr] = match2, result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr); + return [result, FixedOffsetZone.utcInstance]; +} +function extractASCII(match2) { + const [, weekdayStr, monthStr, dayStr, hourStr, minuteStr, secondStr, yearStr] = match2, result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr); + return [result, FixedOffsetZone.utcInstance]; +} +var isoYmdWithTimeExtensionRegex = combineRegexes(isoYmdRegex, isoTimeExtensionRegex); +var isoWeekWithTimeExtensionRegex = combineRegexes(isoWeekRegex, isoTimeExtensionRegex); +var isoOrdinalWithTimeExtensionRegex = combineRegexes(isoOrdinalRegex, isoTimeExtensionRegex); +var isoTimeCombinedRegex = combineRegexes(isoTimeRegex); +var extractISOYmdTimeAndOffset = combineExtractors( + extractISOYmd, + extractISOTime, + extractISOOffset, + extractIANAZone +); +var extractISOWeekTimeAndOffset = combineExtractors( + extractISOWeekData, + extractISOTime, + extractISOOffset, + extractIANAZone +); +var extractISOOrdinalDateAndTime = combineExtractors( + extractISOOrdinalData, + extractISOTime, + extractISOOffset, + extractIANAZone +); +var extractISOTimeAndOffset = combineExtractors( + extractISOTime, + extractISOOffset, + extractIANAZone +); +function parseISODate(s2) { + return parse3( + s2, + [isoYmdWithTimeExtensionRegex, extractISOYmdTimeAndOffset], + [isoWeekWithTimeExtensionRegex, extractISOWeekTimeAndOffset], + [isoOrdinalWithTimeExtensionRegex, extractISOOrdinalDateAndTime], + [isoTimeCombinedRegex, extractISOTimeAndOffset] + ); +} +function parseRFC2822Date(s2) { + return parse3(preprocessRFC2822(s2), [rfc2822, extractRFC2822]); +} +function parseHTTPDate(s2) { + return parse3( + s2, + [rfc1123, extractRFC1123Or850], + [rfc850, extractRFC1123Or850], + [ascii, extractASCII] + ); +} +function parseISODuration(s2) { + return parse3(s2, [isoDuration, extractISODuration]); +} +var extractISOTimeOnly = combineExtractors(extractISOTime); +function parseISOTimeOnly(s2) { + return parse3(s2, [isoTimeOnly, extractISOTimeOnly]); +} +var sqlYmdWithTimeExtensionRegex = combineRegexes(sqlYmdRegex, sqlTimeExtensionRegex); +var sqlTimeCombinedRegex = combineRegexes(sqlTimeRegex); +var extractISOTimeOffsetAndIANAZone = combineExtractors( + extractISOTime, + extractISOOffset, + extractIANAZone +); +function parseSQL(s2) { + return parse3( + s2, + [sqlYmdWithTimeExtensionRegex, extractISOYmdTimeAndOffset], + [sqlTimeCombinedRegex, extractISOTimeOffsetAndIANAZone] + ); +} + +// ../../../node_modules/luxon/src/duration.js +var INVALID = "Invalid Duration"; +var lowOrderMatrix = { + weeks: { + days: 7, + hours: 7 * 24, + minutes: 7 * 24 * 60, + seconds: 7 * 24 * 60 * 60, + milliseconds: 7 * 24 * 60 * 60 * 1e3 + }, + days: { + hours: 24, + minutes: 24 * 60, + seconds: 24 * 60 * 60, + milliseconds: 24 * 60 * 60 * 1e3 + }, + hours: { minutes: 60, seconds: 60 * 60, milliseconds: 60 * 60 * 1e3 }, + minutes: { seconds: 60, milliseconds: 60 * 1e3 }, + seconds: { milliseconds: 1e3 } +}; +var casualMatrix = { + years: { + quarters: 4, + months: 12, + weeks: 52, + days: 365, + hours: 365 * 24, + minutes: 365 * 24 * 60, + seconds: 365 * 24 * 60 * 60, + milliseconds: 365 * 24 * 60 * 60 * 1e3 + }, + quarters: { + months: 3, + weeks: 13, + days: 91, + hours: 91 * 24, + minutes: 91 * 24 * 60, + seconds: 91 * 24 * 60 * 60, + milliseconds: 91 * 24 * 60 * 60 * 1e3 + }, + months: { + weeks: 4, + days: 30, + hours: 30 * 24, + minutes: 30 * 24 * 60, + seconds: 30 * 24 * 60 * 60, + milliseconds: 30 * 24 * 60 * 60 * 1e3 + }, + ...lowOrderMatrix +}; +var daysInYearAccurate = 146097 / 400; +var daysInMonthAccurate = 146097 / 4800; +var accurateMatrix = { + years: { + quarters: 4, + months: 12, + weeks: daysInYearAccurate / 7, + days: daysInYearAccurate, + hours: daysInYearAccurate * 24, + minutes: daysInYearAccurate * 24 * 60, + seconds: daysInYearAccurate * 24 * 60 * 60, + milliseconds: daysInYearAccurate * 24 * 60 * 60 * 1e3 + }, + quarters: { + months: 3, + weeks: daysInYearAccurate / 28, + days: daysInYearAccurate / 4, + hours: daysInYearAccurate * 24 / 4, + minutes: daysInYearAccurate * 24 * 60 / 4, + seconds: daysInYearAccurate * 24 * 60 * 60 / 4, + milliseconds: daysInYearAccurate * 24 * 60 * 60 * 1e3 / 4 + }, + months: { + weeks: daysInMonthAccurate / 7, + days: daysInMonthAccurate, + hours: daysInMonthAccurate * 24, + minutes: daysInMonthAccurate * 24 * 60, + seconds: daysInMonthAccurate * 24 * 60 * 60, + milliseconds: daysInMonthAccurate * 24 * 60 * 60 * 1e3 + }, + ...lowOrderMatrix +}; +var orderedUnits = [ + "years", + "quarters", + "months", + "weeks", + "days", + "hours", + "minutes", + "seconds", + "milliseconds" +]; +var reverseUnits = orderedUnits.slice(0).reverse(); +function clone5(dur, alts, clear = false) { + const conf = { + values: clear ? alts.values : { ...dur.values, ...alts.values || {} }, + loc: dur.loc.clone(alts.loc), + conversionAccuracy: alts.conversionAccuracy || dur.conversionAccuracy, + matrix: alts.matrix || dur.matrix + }; + return new Duration(conf); +} +function durationToMillis(matrix, vals) { + let sum = vals.milliseconds ?? 0; + for (const unit of reverseUnits.slice(1)) { + if (vals[unit]) { + sum += vals[unit] * matrix[unit]["milliseconds"]; + } + } + return sum; +} +function normalizeValues(matrix, vals) { + const factor = durationToMillis(matrix, vals) < 0 ? -1 : 1; + orderedUnits.reduceRight((previous, current) => { + if (!isUndefined(vals[current])) { + if (previous) { + const previousVal = vals[previous] * factor; + const conv = matrix[current][previous]; + const rollUp = Math.floor(previousVal / conv); + vals[current] += rollUp * factor; + vals[previous] -= rollUp * conv * factor; + } + return current; + } else { + return previous; + } + }, null); + orderedUnits.reduce((previous, current) => { + if (!isUndefined(vals[current])) { + if (previous) { + const fraction = vals[previous] % 1; + vals[previous] -= fraction; + vals[current] += fraction * matrix[previous][current]; + } + return current; + } else { + return previous; + } + }, null); +} +function removeZeroes(vals) { + const newVals = {}; + for (const [key, value] of Object.entries(vals)) { + if (value !== 0) { + newVals[key] = value; + } + } + return newVals; +} +var Duration = class { + /** + * @private + */ + constructor(config) { + const accurate = config.conversionAccuracy === "longterm" || false; + let matrix = accurate ? accurateMatrix : casualMatrix; + if (config.matrix) { + matrix = config.matrix; + } + this.values = config.values; + this.loc = config.loc || Locale.create(); + this.conversionAccuracy = accurate ? "longterm" : "casual"; + this.invalid = config.invalid || null; + this.matrix = matrix; + this.isLuxonDuration = true; + } + /** + * Create Duration from a number of milliseconds. + * @param {number} count of milliseconds + * @param {Object} opts - options for parsing + * @param {string} [opts.locale='en-US'] - the locale to use + * @param {string} opts.numberingSystem - the numbering system to use + * @param {string} [opts.conversionAccuracy='casual'] - the conversion system to use + * @return {Duration} + */ + static fromMillis(count, opts) { + return Duration.fromObject({ milliseconds: count }, opts); + } + /** + * Create a Duration from a JavaScript object with keys like 'years' and 'hours'. + * If this object is empty then a zero milliseconds duration is returned. + * @param {Object} obj - the object to create the DateTime from + * @param {number} obj.years + * @param {number} obj.quarters + * @param {number} obj.months + * @param {number} obj.weeks + * @param {number} obj.days + * @param {number} obj.hours + * @param {number} obj.minutes + * @param {number} obj.seconds + * @param {number} obj.milliseconds + * @param {Object} [opts=[]] - options for creating this Duration + * @param {string} [opts.locale='en-US'] - the locale to use + * @param {string} opts.numberingSystem - the numbering system to use + * @param {string} [opts.conversionAccuracy='casual'] - the preset conversion system to use + * @param {string} [opts.matrix=Object] - the custom conversion system to use + * @return {Duration} + */ + static fromObject(obj, opts = {}) { + if (obj == null || typeof obj !== "object") { + throw new InvalidArgumentError( + `Duration.fromObject: argument expected to be an object, got ${obj === null ? "null" : typeof obj}` + ); + } + return new Duration({ + values: normalizeObject(obj, Duration.normalizeUnit), + loc: Locale.fromObject(opts), + conversionAccuracy: opts.conversionAccuracy, + matrix: opts.matrix + }); + } + /** + * Create a Duration from DurationLike. + * + * @param {Object | number | Duration} durationLike + * One of: + * - object with keys like 'years' and 'hours'. + * - number representing milliseconds + * - Duration instance + * @return {Duration} + */ + static fromDurationLike(durationLike) { + if (isNumber3(durationLike)) { + return Duration.fromMillis(durationLike); + } else if (Duration.isDuration(durationLike)) { + return durationLike; + } else if (typeof durationLike === "object") { + return Duration.fromObject(durationLike); + } else { + throw new InvalidArgumentError( + `Unknown duration argument ${durationLike} of type ${typeof durationLike}` + ); + } + } + /** + * Create a Duration from an ISO 8601 duration string. + * @param {string} text - text to parse + * @param {Object} opts - options for parsing + * @param {string} [opts.locale='en-US'] - the locale to use + * @param {string} opts.numberingSystem - the numbering system to use + * @param {string} [opts.conversionAccuracy='casual'] - the preset conversion system to use + * @param {string} [opts.matrix=Object] - the preset conversion system to use + * @see https://en.wikipedia.org/wiki/ISO_8601#Durations + * @example Duration.fromISO('P3Y6M1W4DT12H30M5S').toObject() //=> { years: 3, months: 6, weeks: 1, days: 4, hours: 12, minutes: 30, seconds: 5 } + * @example Duration.fromISO('PT23H').toObject() //=> { hours: 23 } + * @example Duration.fromISO('P5Y3M').toObject() //=> { years: 5, months: 3 } + * @return {Duration} + */ + static fromISO(text, opts) { + const [parsed] = parseISODuration(text); + if (parsed) { + return Duration.fromObject(parsed, opts); + } else { + return Duration.invalid("unparsable", `the input "${text}" can't be parsed as ISO 8601`); + } + } + /** + * Create a Duration from an ISO 8601 time string. + * @param {string} text - text to parse + * @param {Object} opts - options for parsing + * @param {string} [opts.locale='en-US'] - the locale to use + * @param {string} opts.numberingSystem - the numbering system to use + * @param {string} [opts.conversionAccuracy='casual'] - the preset conversion system to use + * @param {string} [opts.matrix=Object] - the conversion system to use + * @see https://en.wikipedia.org/wiki/ISO_8601#Times + * @example Duration.fromISOTime('11:22:33.444').toObject() //=> { hours: 11, minutes: 22, seconds: 33, milliseconds: 444 } + * @example Duration.fromISOTime('11:00').toObject() //=> { hours: 11, minutes: 0, seconds: 0 } + * @example Duration.fromISOTime('T11:00').toObject() //=> { hours: 11, minutes: 0, seconds: 0 } + * @example Duration.fromISOTime('1100').toObject() //=> { hours: 11, minutes: 0, seconds: 0 } + * @example Duration.fromISOTime('T1100').toObject() //=> { hours: 11, minutes: 0, seconds: 0 } + * @return {Duration} + */ + static fromISOTime(text, opts) { + const [parsed] = parseISOTimeOnly(text); + if (parsed) { + return Duration.fromObject(parsed, opts); + } else { + return Duration.invalid("unparsable", `the input "${text}" can't be parsed as ISO 8601`); + } + } + /** + * Create an invalid Duration. + * @param {string} reason - simple string of why this datetime is invalid. Should not contain parameters or anything else data-dependent + * @param {string} [explanation=null] - longer explanation, may include parameters and other useful debugging information + * @return {Duration} + */ + static invalid(reason, explanation = null) { + if (!reason) { + throw new InvalidArgumentError("need to specify a reason the Duration is invalid"); + } + const invalid = reason instanceof Invalid ? reason : new Invalid(reason, explanation); + if (Settings.throwOnInvalid) { + throw new InvalidDurationError(invalid); + } else { + return new Duration({ invalid }); + } + } + /** + * @private + */ + static normalizeUnit(unit) { + const normalized = { + year: "years", + years: "years", + quarter: "quarters", + quarters: "quarters", + month: "months", + months: "months", + week: "weeks", + weeks: "weeks", + day: "days", + days: "days", + hour: "hours", + hours: "hours", + minute: "minutes", + minutes: "minutes", + second: "seconds", + seconds: "seconds", + millisecond: "milliseconds", + milliseconds: "milliseconds" + }[unit ? unit.toLowerCase() : unit]; + if (!normalized) + throw new InvalidUnitError(unit); + return normalized; + } + /** + * Check if an object is a Duration. Works across context boundaries + * @param {object} o + * @return {boolean} + */ + static isDuration(o) { + return o && o.isLuxonDuration || false; + } + /** + * Get the locale of a Duration, such 'en-GB' + * @type {string} + */ + get locale() { + return this.isValid ? this.loc.locale : null; + } + /** + * Get the numbering system of a Duration, such 'beng'. The numbering system is used when formatting the Duration + * + * @type {string} + */ + get numberingSystem() { + return this.isValid ? this.loc.numberingSystem : null; + } + /** + * Returns a string representation of this Duration formatted according to the specified format string. You may use these tokens: + * * `S` for milliseconds + * * `s` for seconds + * * `m` for minutes + * * `h` for hours + * * `d` for days + * * `w` for weeks + * * `M` for months + * * `y` for years + * Notes: + * * Add padding by repeating the token, e.g. "yy" pads the years to two digits, "hhhh" pads the hours out to four digits + * * Tokens can be escaped by wrapping with single quotes. + * * The duration will be converted to the set of units in the format string using {@link Duration#shiftTo} and the Durations's conversion accuracy setting. + * @param {string} fmt - the format string + * @param {Object} opts - options + * @param {boolean} [opts.floor=true] - floor numerical values + * @example Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toFormat("y d s") //=> "1 6 2" + * @example Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toFormat("yy dd sss") //=> "01 06 002" + * @example Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toFormat("M S") //=> "12 518402000" + * @return {string} + */ + toFormat(fmt, opts = {}) { + const fmtOpts = { + ...opts, + floor: opts.round !== false && opts.floor !== false + }; + return this.isValid ? Formatter.create(this.loc, fmtOpts).formatDurationFromString(this, fmt) : INVALID; + } + /** + * Returns a string representation of a Duration with all units included. + * To modify its behavior, use `listStyle` and any Intl.NumberFormat option, though `unitDisplay` is especially relevant. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options + * @param {Object} opts - Formatting options. Accepts the same keys as the options parameter of the native `Intl.NumberFormat` constructor, as well as `listStyle`. + * @param {string} [opts.listStyle='narrow'] - How to format the merged list. Corresponds to the `style` property of the options parameter of the native `Intl.ListFormat` constructor. + * @example + * ```js + * var dur = Duration.fromObject({ days: 1, hours: 5, minutes: 6 }) + * dur.toHuman() //=> '1 day, 5 hours, 6 minutes' + * dur.toHuman({ listStyle: "long" }) //=> '1 day, 5 hours, and 6 minutes' + * dur.toHuman({ unitDisplay: "short" }) //=> '1 day, 5 hr, 6 min' + * ``` + */ + toHuman(opts = {}) { + if (!this.isValid) + return INVALID; + const l2 = orderedUnits.map((unit) => { + const val = this.values[unit]; + if (isUndefined(val)) { + return null; + } + return this.loc.numberFormatter({ style: "unit", unitDisplay: "long", ...opts, unit: unit.slice(0, -1) }).format(val); + }).filter((n2) => n2); + return this.loc.listFormatter({ type: "conjunction", style: opts.listStyle || "narrow", ...opts }).format(l2); + } + /** + * Returns a JavaScript object with this Duration's values. + * @example Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toObject() //=> { years: 1, days: 6, seconds: 2 } + * @return {Object} + */ + toObject() { + if (!this.isValid) + return {}; + return { ...this.values }; + } + /** + * Returns an ISO 8601-compliant string representation of this Duration. + * @see https://en.wikipedia.org/wiki/ISO_8601#Durations + * @example Duration.fromObject({ years: 3, seconds: 45 }).toISO() //=> 'P3YT45S' + * @example Duration.fromObject({ months: 4, seconds: 45 }).toISO() //=> 'P4MT45S' + * @example Duration.fromObject({ months: 5 }).toISO() //=> 'P5M' + * @example Duration.fromObject({ minutes: 5 }).toISO() //=> 'PT5M' + * @example Duration.fromObject({ milliseconds: 6 }).toISO() //=> 'PT0.006S' + * @return {string} + */ + toISO() { + if (!this.isValid) + return null; + let s2 = "P"; + if (this.years !== 0) + s2 += this.years + "Y"; + if (this.months !== 0 || this.quarters !== 0) + s2 += this.months + this.quarters * 3 + "M"; + if (this.weeks !== 0) + s2 += this.weeks + "W"; + if (this.days !== 0) + s2 += this.days + "D"; + if (this.hours !== 0 || this.minutes !== 0 || this.seconds !== 0 || this.milliseconds !== 0) + s2 += "T"; + if (this.hours !== 0) + s2 += this.hours + "H"; + if (this.minutes !== 0) + s2 += this.minutes + "M"; + if (this.seconds !== 0 || this.milliseconds !== 0) + s2 += roundTo(this.seconds + this.milliseconds / 1e3, 3) + "S"; + if (s2 === "P") + s2 += "T0S"; + return s2; + } + /** + * Returns an ISO 8601-compliant string representation of this Duration, formatted as a time of day. + * Note that this will return null if the duration is invalid, negative, or equal to or greater than 24 hours. + * @see https://en.wikipedia.org/wiki/ISO_8601#Times + * @param {Object} opts - options + * @param {boolean} [opts.suppressMilliseconds=false] - exclude milliseconds from the format if they're 0 + * @param {boolean} [opts.suppressSeconds=false] - exclude seconds from the format if they're 0 + * @param {boolean} [opts.includePrefix=false] - include the `T` prefix + * @param {string} [opts.format='extended'] - choose between the basic and extended format + * @example Duration.fromObject({ hours: 11 }).toISOTime() //=> '11:00:00.000' + * @example Duration.fromObject({ hours: 11 }).toISOTime({ suppressMilliseconds: true }) //=> '11:00:00' + * @example Duration.fromObject({ hours: 11 }).toISOTime({ suppressSeconds: true }) //=> '11:00' + * @example Duration.fromObject({ hours: 11 }).toISOTime({ includePrefix: true }) //=> 'T11:00:00.000' + * @example Duration.fromObject({ hours: 11 }).toISOTime({ format: 'basic' }) //=> '110000.000' + * @return {string} + */ + toISOTime(opts = {}) { + if (!this.isValid) + return null; + const millis = this.toMillis(); + if (millis < 0 || millis >= 864e5) + return null; + opts = { + suppressMilliseconds: false, + suppressSeconds: false, + includePrefix: false, + format: "extended", + ...opts, + includeOffset: false + }; + const dateTime = DateTime.fromMillis(millis, { zone: "UTC" }); + return dateTime.toISOTime(opts); + } + /** + * Returns an ISO 8601 representation of this Duration appropriate for use in JSON. + * @return {string} + */ + toJSON() { + return this.toISO(); + } + /** + * Returns an ISO 8601 representation of this Duration appropriate for use in debugging. + * @return {string} + */ + toString() { + return this.toISO(); + } + /** + * Returns a string representation of this Duration appropriate for the REPL. + * @return {string} + */ + [Symbol.for("nodejs.util.inspect.custom")]() { + if (this.isValid) { + return `Duration { values: ${JSON.stringify(this.values)} }`; + } else { + return `Duration { Invalid, reason: ${this.invalidReason} }`; + } + } + /** + * Returns an milliseconds value of this Duration. + * @return {number} + */ + toMillis() { + if (!this.isValid) + return NaN; + return durationToMillis(this.matrix, this.values); + } + /** + * Returns an milliseconds value of this Duration. Alias of {@link toMillis} + * @return {number} + */ + valueOf() { + return this.toMillis(); + } + /** + * Make this Duration longer by the specified amount. Return a newly-constructed Duration. + * @param {Duration|Object|number} duration - The amount to add. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject() + * @return {Duration} + */ + plus(duration) { + if (!this.isValid) + return this; + const dur = Duration.fromDurationLike(duration), result = {}; + for (const k of orderedUnits) { + if (hasOwnProperty(dur.values, k) || hasOwnProperty(this.values, k)) { + result[k] = dur.get(k) + this.get(k); + } + } + return clone5(this, { values: result }, true); + } + /** + * Make this Duration shorter by the specified amount. Return a newly-constructed Duration. + * @param {Duration|Object|number} duration - The amount to subtract. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject() + * @return {Duration} + */ + minus(duration) { + if (!this.isValid) + return this; + const dur = Duration.fromDurationLike(duration); + return this.plus(dur.negate()); + } + /** + * Scale this Duration by the specified amount. Return a newly-constructed Duration. + * @param {function} fn - The function to apply to each unit. Arity is 1 or 2: the value of the unit and, optionally, the unit name. Must return a number. + * @example Duration.fromObject({ hours: 1, minutes: 30 }).mapUnits(x => x * 2) //=> { hours: 2, minutes: 60 } + * @example Duration.fromObject({ hours: 1, minutes: 30 }).mapUnits((x, u) => u === "hours" ? x * 2 : x) //=> { hours: 2, minutes: 30 } + * @return {Duration} + */ + mapUnits(fn) { + if (!this.isValid) + return this; + const result = {}; + for (const k of Object.keys(this.values)) { + result[k] = asNumber(fn(this.values[k], k)); + } + return clone5(this, { values: result }, true); + } + /** + * Get the value of unit. + * @param {string} unit - a unit such as 'minute' or 'day' + * @example Duration.fromObject({years: 2, days: 3}).get('years') //=> 2 + * @example Duration.fromObject({years: 2, days: 3}).get('months') //=> 0 + * @example Duration.fromObject({years: 2, days: 3}).get('days') //=> 3 + * @return {number} + */ + get(unit) { + return this[Duration.normalizeUnit(unit)]; + } + /** + * "Set" the values of specified units. Return a newly-constructed Duration. + * @param {Object} values - a mapping of units to numbers + * @example dur.set({ years: 2017 }) + * @example dur.set({ hours: 8, minutes: 30 }) + * @return {Duration} + */ + set(values) { + if (!this.isValid) + return this; + const mixed = { ...this.values, ...normalizeObject(values, Duration.normalizeUnit) }; + return clone5(this, { values: mixed }); + } + /** + * "Set" the locale and/or numberingSystem. Returns a newly-constructed Duration. + * @example dur.reconfigure({ locale: 'en-GB' }) + * @return {Duration} + */ + reconfigure({ locale, numberingSystem, conversionAccuracy, matrix } = {}) { + const loc = this.loc.clone({ locale, numberingSystem }); + const opts = { loc, matrix, conversionAccuracy }; + return clone5(this, opts); + } + /** + * Return the length of the duration in the specified unit. + * @param {string} unit - a unit such as 'minutes' or 'days' + * @example Duration.fromObject({years: 1}).as('days') //=> 365 + * @example Duration.fromObject({years: 1}).as('months') //=> 12 + * @example Duration.fromObject({hours: 60}).as('days') //=> 2.5 + * @return {number} + */ + as(unit) { + return this.isValid ? this.shiftTo(unit).get(unit) : NaN; + } + /** + * Reduce this Duration to its canonical representation in its current units. + * Assuming the overall value of the Duration is positive, this means: + * - excessive values for lower-order units are converted to higher-order units (if possible, see first and second example) + * - negative lower-order units are converted to higher order units (there must be such a higher order unit, otherwise + * the overall value would be negative, see third example) + * - fractional values for higher-order units are converted to lower-order units (if possible, see fourth example) + * + * If the overall value is negative, the result of this method is equivalent to `this.negate().normalize().negate()`. + * @example Duration.fromObject({ years: 2, days: 5000 }).normalize().toObject() //=> { years: 15, days: 255 } + * @example Duration.fromObject({ days: 5000 }).normalize().toObject() //=> { days: 5000 } + * @example Duration.fromObject({ hours: 12, minutes: -45 }).normalize().toObject() //=> { hours: 11, minutes: 15 } + * @example Duration.fromObject({ years: 2.5, days: 0, hours: 0 }).normalize().toObject() //=> { years: 2, days: 182, hours: 12 } + * @return {Duration} + */ + normalize() { + if (!this.isValid) + return this; + const vals = this.toObject(); + normalizeValues(this.matrix, vals); + return clone5(this, { values: vals }, true); + } + /** + * Rescale units to its largest representation + * @example Duration.fromObject({ milliseconds: 90000 }).rescale().toObject() //=> { minutes: 1, seconds: 30 } + * @return {Duration} + */ + rescale() { + if (!this.isValid) + return this; + const vals = removeZeroes(this.normalize().shiftToAll().toObject()); + return clone5(this, { values: vals }, true); + } + /** + * Convert this Duration into its representation in a different set of units. + * @example Duration.fromObject({ hours: 1, seconds: 30 }).shiftTo('minutes', 'milliseconds').toObject() //=> { minutes: 60, milliseconds: 30000 } + * @return {Duration} + */ + shiftTo(...units) { + if (!this.isValid) + return this; + if (units.length === 0) { + return this; + } + units = units.map((u) => Duration.normalizeUnit(u)); + const built = {}, accumulated = {}, vals = this.toObject(); + let lastUnit; + for (const k of orderedUnits) { + if (units.indexOf(k) >= 0) { + lastUnit = k; + let own = 0; + for (const ak in accumulated) { + own += this.matrix[ak][k] * accumulated[ak]; + accumulated[ak] = 0; + } + if (isNumber3(vals[k])) { + own += vals[k]; + } + const i = Math.trunc(own); + built[k] = i; + accumulated[k] = (own * 1e3 - i * 1e3) / 1e3; + } else if (isNumber3(vals[k])) { + accumulated[k] = vals[k]; + } + } + for (const key in accumulated) { + if (accumulated[key] !== 0) { + built[lastUnit] += key === lastUnit ? accumulated[key] : accumulated[key] / this.matrix[lastUnit][key]; + } + } + normalizeValues(this.matrix, built); + return clone5(this, { values: built }, true); + } + /** + * Shift this Duration to all available units. + * Same as shiftTo("years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds") + * @return {Duration} + */ + shiftToAll() { + if (!this.isValid) + return this; + return this.shiftTo( + "years", + "months", + "weeks", + "days", + "hours", + "minutes", + "seconds", + "milliseconds" + ); + } + /** + * Return the negative of this Duration. + * @example Duration.fromObject({ hours: 1, seconds: 30 }).negate().toObject() //=> { hours: -1, seconds: -30 } + * @return {Duration} + */ + negate() { + if (!this.isValid) + return this; + const negated = {}; + for (const k of Object.keys(this.values)) { + negated[k] = this.values[k] === 0 ? 0 : -this.values[k]; + } + return clone5(this, { values: negated }, true); + } + /** + * Get the years. + * @type {number} + */ + get years() { + return this.isValid ? this.values.years || 0 : NaN; + } + /** + * Get the quarters. + * @type {number} + */ + get quarters() { + return this.isValid ? this.values.quarters || 0 : NaN; + } + /** + * Get the months. + * @type {number} + */ + get months() { + return this.isValid ? this.values.months || 0 : NaN; + } + /** + * Get the weeks + * @type {number} + */ + get weeks() { + return this.isValid ? this.values.weeks || 0 : NaN; + } + /** + * Get the days. + * @type {number} + */ + get days() { + return this.isValid ? this.values.days || 0 : NaN; + } + /** + * Get the hours. + * @type {number} + */ + get hours() { + return this.isValid ? this.values.hours || 0 : NaN; + } + /** + * Get the minutes. + * @type {number} + */ + get minutes() { + return this.isValid ? this.values.minutes || 0 : NaN; + } + /** + * Get the seconds. + * @return {number} + */ + get seconds() { + return this.isValid ? this.values.seconds || 0 : NaN; + } + /** + * Get the milliseconds. + * @return {number} + */ + get milliseconds() { + return this.isValid ? this.values.milliseconds || 0 : NaN; + } + /** + * Returns whether the Duration is invalid. Invalid durations are returned by diff operations + * on invalid DateTimes or Intervals. + * @return {boolean} + */ + get isValid() { + return this.invalid === null; + } + /** + * Returns an error code if this Duration became invalid, or null if the Duration is valid + * @return {string} + */ + get invalidReason() { + return this.invalid ? this.invalid.reason : null; + } + /** + * Returns an explanation of why this Duration became invalid, or null if the Duration is valid + * @type {string} + */ + get invalidExplanation() { + return this.invalid ? this.invalid.explanation : null; + } + /** + * Equality check + * Two Durations are equal iff they have the same units and the same values for each unit. + * @param {Duration} other + * @return {boolean} + */ + equals(other) { + if (!this.isValid || !other.isValid) { + return false; + } + if (!this.loc.equals(other.loc)) { + return false; + } + function eq3(v1, v2) { + if (v1 === void 0 || v1 === 0) + return v2 === void 0 || v2 === 0; + return v1 === v2; + } + for (const u of orderedUnits) { + if (!eq3(this.values[u], other.values[u])) { + return false; + } + } + return true; + } +}; + +// ../../../node_modules/luxon/src/interval.js +var INVALID2 = "Invalid Interval"; +function validateStartEnd(start, end) { + if (!start || !start.isValid) { + return Interval.invalid("missing or invalid start"); + } else if (!end || !end.isValid) { + return Interval.invalid("missing or invalid end"); + } else if (end < start) { + return Interval.invalid( + "end before start", + `The end of an interval must be after its start, but you had start=${start.toISO()} and end=${end.toISO()}` + ); + } else { + return null; + } +} +var Interval = class { + /** + * @private + */ + constructor(config) { + this.s = config.start; + this.e = config.end; + this.invalid = config.invalid || null; + this.isLuxonInterval = true; + } + /** + * Create an invalid Interval. + * @param {string} reason - simple string of why this Interval is invalid. Should not contain parameters or anything else data-dependent + * @param {string} [explanation=null] - longer explanation, may include parameters and other useful debugging information + * @return {Interval} + */ + static invalid(reason, explanation = null) { + if (!reason) { + throw new InvalidArgumentError("need to specify a reason the Interval is invalid"); + } + const invalid = reason instanceof Invalid ? reason : new Invalid(reason, explanation); + if (Settings.throwOnInvalid) { + throw new InvalidIntervalError(invalid); + } else { + return new Interval({ invalid }); + } + } + /** + * Create an Interval from a start DateTime and an end DateTime. Inclusive of the start but not the end. + * @param {DateTime|Date|Object} start + * @param {DateTime|Date|Object} end + * @return {Interval} + */ + static fromDateTimes(start, end) { + const builtStart = friendlyDateTime(start), builtEnd = friendlyDateTime(end); + const validateError = validateStartEnd(builtStart, builtEnd); + if (validateError == null) { + return new Interval({ + start: builtStart, + end: builtEnd + }); + } else { + return validateError; + } + } + /** + * Create an Interval from a start DateTime and a Duration to extend to. + * @param {DateTime|Date|Object} start + * @param {Duration|Object|number} duration - the length of the Interval. + * @return {Interval} + */ + static after(start, duration) { + const dur = Duration.fromDurationLike(duration), dt = friendlyDateTime(start); + return Interval.fromDateTimes(dt, dt.plus(dur)); + } + /** + * Create an Interval from an end DateTime and a Duration to extend backwards to. + * @param {DateTime|Date|Object} end + * @param {Duration|Object|number} duration - the length of the Interval. + * @return {Interval} + */ + static before(end, duration) { + const dur = Duration.fromDurationLike(duration), dt = friendlyDateTime(end); + return Interval.fromDateTimes(dt.minus(dur), dt); + } + /** + * Create an Interval from an ISO 8601 string. + * Accepts `/`, `/`, and `/` formats. + * @param {string} text - the ISO string to parse + * @param {Object} [opts] - options to pass {@link DateTime#fromISO} and optionally {@link Duration#fromISO} + * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals + * @return {Interval} + */ + static fromISO(text, opts) { + const [s2, e] = (text || "").split("/", 2); + if (s2 && e) { + let start, startIsValid; + try { + start = DateTime.fromISO(s2, opts); + startIsValid = start.isValid; + } catch (e2) { + startIsValid = false; + } + let end, endIsValid; + try { + end = DateTime.fromISO(e, opts); + endIsValid = end.isValid; + } catch (e2) { + endIsValid = false; + } + if (startIsValid && endIsValid) { + return Interval.fromDateTimes(start, end); + } + if (startIsValid) { + const dur = Duration.fromISO(e, opts); + if (dur.isValid) { + return Interval.after(start, dur); + } + } else if (endIsValid) { + const dur = Duration.fromISO(s2, opts); + if (dur.isValid) { + return Interval.before(end, dur); + } + } + } + return Interval.invalid("unparsable", `the input "${text}" can't be parsed as ISO 8601`); + } + /** + * Check if an object is an Interval. Works across context boundaries + * @param {object} o + * @return {boolean} + */ + static isInterval(o) { + return o && o.isLuxonInterval || false; + } + /** + * Returns the start of the Interval + * @type {DateTime} + */ + get start() { + return this.isValid ? this.s : null; + } + /** + * Returns the end of the Interval + * @type {DateTime} + */ + get end() { + return this.isValid ? this.e : null; + } + /** + * Returns whether this Interval's end is at least its start, meaning that the Interval isn't 'backwards'. + * @type {boolean} + */ + get isValid() { + return this.invalidReason === null; + } + /** + * Returns an error code if this Interval is invalid, or null if the Interval is valid + * @type {string} + */ + get invalidReason() { + return this.invalid ? this.invalid.reason : null; + } + /** + * Returns an explanation of why this Interval became invalid, or null if the Interval is valid + * @type {string} + */ + get invalidExplanation() { + return this.invalid ? this.invalid.explanation : null; + } + /** + * Returns the length of the Interval in the specified unit. + * @param {string} unit - the unit (such as 'hours' or 'days') to return the length in. + * @return {number} + */ + length(unit = "milliseconds") { + return this.isValid ? this.toDuration(...[unit]).get(unit) : NaN; + } + /** + * Returns the count of minutes, hours, days, months, or years included in the Interval, even in part. + * Unlike {@link Interval#length} this counts sections of the calendar, not periods of time, e.g. specifying 'day' + * asks 'what dates are included in this interval?', not 'how many days long is this interval?' + * @param {string} [unit='milliseconds'] - the unit of time to count. + * @param {Object} opts - options + * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week; this operation will always use the locale of the start DateTime + * @return {number} + */ + count(unit = "milliseconds", opts) { + if (!this.isValid) + return NaN; + const start = this.start.startOf(unit, opts); + let end; + if (opts?.useLocaleWeeks) { + end = this.end.reconfigure({ locale: start.locale }); + } else { + end = this.end; + } + end = end.startOf(unit, opts); + return Math.floor(end.diff(start, unit).get(unit)) + (end.valueOf() !== this.end.valueOf()); + } + /** + * Returns whether this Interval's start and end are both in the same unit of time + * @param {string} unit - the unit of time to check sameness on + * @return {boolean} + */ + hasSame(unit) { + return this.isValid ? this.isEmpty() || this.e.minus(1).hasSame(this.s, unit) : false; + } + /** + * Return whether this Interval has the same start and end DateTimes. + * @return {boolean} + */ + isEmpty() { + return this.s.valueOf() === this.e.valueOf(); + } + /** + * Return whether this Interval's start is after the specified DateTime. + * @param {DateTime} dateTime + * @return {boolean} + */ + isAfter(dateTime) { + if (!this.isValid) + return false; + return this.s > dateTime; + } + /** + * Return whether this Interval's end is before the specified DateTime. + * @param {DateTime} dateTime + * @return {boolean} + */ + isBefore(dateTime) { + if (!this.isValid) + return false; + return this.e <= dateTime; + } + /** + * Return whether this Interval contains the specified DateTime. + * @param {DateTime} dateTime + * @return {boolean} + */ + contains(dateTime) { + if (!this.isValid) + return false; + return this.s <= dateTime && this.e > dateTime; + } + /** + * "Sets" the start and/or end dates. Returns a newly-constructed Interval. + * @param {Object} values - the values to set + * @param {DateTime} values.start - the starting DateTime + * @param {DateTime} values.end - the ending DateTime + * @return {Interval} + */ + set({ start, end } = {}) { + if (!this.isValid) + return this; + return Interval.fromDateTimes(start || this.s, end || this.e); + } + /** + * Split this Interval at each of the specified DateTimes + * @param {...DateTime} dateTimes - the unit of time to count. + * @return {Array} + */ + splitAt(...dateTimes) { + if (!this.isValid) + return []; + const sorted = dateTimes.map(friendlyDateTime).filter((d) => this.contains(d)).sort((a, b) => a.toMillis() - b.toMillis()), results = []; + let { s: s2 } = this, i = 0; + while (s2 < this.e) { + const added = sorted[i] || this.e, next = +added > +this.e ? this.e : added; + results.push(Interval.fromDateTimes(s2, next)); + s2 = next; + i += 1; + } + return results; + } + /** + * Split this Interval into smaller Intervals, each of the specified length. + * Left over time is grouped into a smaller interval + * @param {Duration|Object|number} duration - The length of each resulting interval. + * @return {Array} + */ + splitBy(duration) { + const dur = Duration.fromDurationLike(duration); + if (!this.isValid || !dur.isValid || dur.as("milliseconds") === 0) { + return []; + } + let { s: s2 } = this, idx = 1, next; + const results = []; + while (s2 < this.e) { + const added = this.start.plus(dur.mapUnits((x) => x * idx)); + next = +added > +this.e ? this.e : added; + results.push(Interval.fromDateTimes(s2, next)); + s2 = next; + idx += 1; + } + return results; + } + /** + * Split this Interval into the specified number of smaller intervals. + * @param {number} numberOfParts - The number of Intervals to divide the Interval into. + * @return {Array} + */ + divideEqually(numberOfParts) { + if (!this.isValid) + return []; + return this.splitBy(this.length() / numberOfParts).slice(0, numberOfParts); + } + /** + * Return whether this Interval overlaps with the specified Interval + * @param {Interval} other + * @return {boolean} + */ + overlaps(other) { + return this.e > other.s && this.s < other.e; + } + /** + * Return whether this Interval's end is adjacent to the specified Interval's start. + * @param {Interval} other + * @return {boolean} + */ + abutsStart(other) { + if (!this.isValid) + return false; + return +this.e === +other.s; + } + /** + * Return whether this Interval's start is adjacent to the specified Interval's end. + * @param {Interval} other + * @return {boolean} + */ + abutsEnd(other) { + if (!this.isValid) + return false; + return +other.e === +this.s; + } + /** + * Return whether this Interval engulfs the start and end of the specified Interval. + * @param {Interval} other + * @return {boolean} + */ + engulfs(other) { + if (!this.isValid) + return false; + return this.s <= other.s && this.e >= other.e; + } + /** + * Return whether this Interval has the same start and end as the specified Interval. + * @param {Interval} other + * @return {boolean} + */ + equals(other) { + if (!this.isValid || !other.isValid) { + return false; + } + return this.s.equals(other.s) && this.e.equals(other.e); + } + /** + * Return an Interval representing the intersection of this Interval and the specified Interval. + * Specifically, the resulting Interval has the maximum start time and the minimum end time of the two Intervals. + * Returns null if the intersection is empty, meaning, the intervals don't intersect. + * @param {Interval} other + * @return {Interval} + */ + intersection(other) { + if (!this.isValid) + return this; + const s2 = this.s > other.s ? this.s : other.s, e = this.e < other.e ? this.e : other.e; + if (s2 >= e) { + return null; + } else { + return Interval.fromDateTimes(s2, e); + } + } + /** + * Return an Interval representing the union of this Interval and the specified Interval. + * Specifically, the resulting Interval has the minimum start time and the maximum end time of the two Intervals. + * @param {Interval} other + * @return {Interval} + */ + union(other) { + if (!this.isValid) + return this; + const s2 = this.s < other.s ? this.s : other.s, e = this.e > other.e ? this.e : other.e; + return Interval.fromDateTimes(s2, e); + } + /** + * Merge an array of Intervals into a equivalent minimal set of Intervals. + * Combines overlapping and adjacent Intervals. + * @param {Array} intervals + * @return {Array} + */ + static merge(intervals) { + const [found, final] = intervals.sort((a, b) => a.s - b.s).reduce( + ([sofar, current], item) => { + if (!current) { + return [sofar, item]; + } else if (current.overlaps(item) || current.abutsStart(item)) { + return [sofar, current.union(item)]; + } else { + return [sofar.concat([current]), item]; + } + }, + [[], null] + ); + if (final) { + found.push(final); + } + return found; + } + /** + * Return an array of Intervals representing the spans of time that only appear in one of the specified Intervals. + * @param {Array} intervals + * @return {Array} + */ + static xor(intervals) { + let start = null, currentCount = 0; + const results = [], ends = intervals.map((i) => [ + { time: i.s, type: "s" }, + { time: i.e, type: "e" } + ]), flattened = Array.prototype.concat(...ends), arr = flattened.sort((a, b) => a.time - b.time); + for (const i of arr) { + currentCount += i.type === "s" ? 1 : -1; + if (currentCount === 1) { + start = i.time; + } else { + if (start && +start !== +i.time) { + results.push(Interval.fromDateTimes(start, i.time)); + } + start = null; + } + } + return Interval.merge(results); + } + /** + * Return an Interval representing the span of time in this Interval that doesn't overlap with any of the specified Intervals. + * @param {...Interval} intervals + * @return {Array} + */ + difference(...intervals) { + return Interval.xor([this].concat(intervals)).map((i) => this.intersection(i)).filter((i) => i && !i.isEmpty()); + } + /** + * Returns a string representation of this Interval appropriate for debugging. + * @return {string} + */ + toString() { + if (!this.isValid) + return INVALID2; + return `[${this.s.toISO()} \u2013 ${this.e.toISO()})`; + } + /** + * Returns a string representation of this Interval appropriate for the REPL. + * @return {string} + */ + [Symbol.for("nodejs.util.inspect.custom")]() { + if (this.isValid) { + return `Interval { start: ${this.s.toISO()}, end: ${this.e.toISO()} }`; + } else { + return `Interval { Invalid, reason: ${this.invalidReason} }`; + } + } + /** + * Returns a localized string representing this Interval. Accepts the same options as the + * Intl.DateTimeFormat constructor and any presets defined by Luxon, such as + * {@link DateTime.DATE_FULL} or {@link DateTime.TIME_SIMPLE}. The exact behavior of this method + * is browser-specific, but in general it will return an appropriate representation of the + * Interval in the assigned locale. Defaults to the system's locale if no locale has been + * specified. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat + * @param {Object} [formatOpts=DateTime.DATE_SHORT] - Either a DateTime preset or + * Intl.DateTimeFormat constructor options. + * @param {Object} opts - Options to override the configuration of the start DateTime. + * @example Interval.fromISO('2022-11-07T09:00Z/2022-11-08T09:00Z').toLocaleString(); //=> 11/7/2022 – 11/8/2022 + * @example Interval.fromISO('2022-11-07T09:00Z/2022-11-08T09:00Z').toLocaleString(DateTime.DATE_FULL); //=> November 7 – 8, 2022 + * @example Interval.fromISO('2022-11-07T09:00Z/2022-11-08T09:00Z').toLocaleString(DateTime.DATE_FULL, { locale: 'fr-FR' }); //=> 7–8 novembre 2022 + * @example Interval.fromISO('2022-11-07T17:00Z/2022-11-07T19:00Z').toLocaleString(DateTime.TIME_SIMPLE); //=> 6:00 – 8:00 PM + * @example Interval.fromISO('2022-11-07T17:00Z/2022-11-07T19:00Z').toLocaleString({ weekday: 'short', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }); //=> Mon, Nov 07, 6:00 – 8:00 p + * @return {string} + */ + toLocaleString(formatOpts = DATE_SHORT, opts = {}) { + return this.isValid ? Formatter.create(this.s.loc.clone(opts), formatOpts).formatInterval(this) : INVALID2; + } + /** + * Returns an ISO 8601-compliant string representation of this Interval. + * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals + * @param {Object} opts - The same options as {@link DateTime#toISO} + * @return {string} + */ + toISO(opts) { + if (!this.isValid) + return INVALID2; + return `${this.s.toISO(opts)}/${this.e.toISO(opts)}`; + } + /** + * Returns an ISO 8601-compliant string representation of date of this Interval. + * The time components are ignored. + * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals + * @return {string} + */ + toISODate() { + if (!this.isValid) + return INVALID2; + return `${this.s.toISODate()}/${this.e.toISODate()}`; + } + /** + * Returns an ISO 8601-compliant string representation of time of this Interval. + * The date components are ignored. + * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals + * @param {Object} opts - The same options as {@link DateTime#toISO} + * @return {string} + */ + toISOTime(opts) { + if (!this.isValid) + return INVALID2; + return `${this.s.toISOTime(opts)}/${this.e.toISOTime(opts)}`; + } + /** + * Returns a string representation of this Interval formatted according to the specified format + * string. **You may not want this.** See {@link Interval#toLocaleString} for a more flexible + * formatting tool. + * @param {string} dateFormat - The format string. This string formats the start and end time. + * See {@link DateTime#toFormat} for details. + * @param {Object} opts - Options. + * @param {string} [opts.separator = ' – '] - A separator to place between the start and end + * representations. + * @return {string} + */ + toFormat(dateFormat, { separator = " \u2013 " } = {}) { + if (!this.isValid) + return INVALID2; + return `${this.s.toFormat(dateFormat)}${separator}${this.e.toFormat(dateFormat)}`; + } + /** + * Return a Duration representing the time spanned by this interval. + * @param {string|string[]} [unit=['milliseconds']] - the unit or units (such as 'hours' or 'days') to include in the duration. + * @param {Object} opts - options that affect the creation of the Duration + * @param {string} [opts.conversionAccuracy='casual'] - the conversion system to use + * @example Interval.fromDateTimes(dt1, dt2).toDuration().toObject() //=> { milliseconds: 88489257 } + * @example Interval.fromDateTimes(dt1, dt2).toDuration('days').toObject() //=> { days: 1.0241812152777778 } + * @example Interval.fromDateTimes(dt1, dt2).toDuration(['hours', 'minutes']).toObject() //=> { hours: 24, minutes: 34.82095 } + * @example Interval.fromDateTimes(dt1, dt2).toDuration(['hours', 'minutes', 'seconds']).toObject() //=> { hours: 24, minutes: 34, seconds: 49.257 } + * @example Interval.fromDateTimes(dt1, dt2).toDuration('seconds').toObject() //=> { seconds: 88489.257 } + * @return {Duration} + */ + toDuration(unit, opts) { + if (!this.isValid) { + return Duration.invalid(this.invalidReason); + } + return this.e.diff(this.s, unit, opts); + } + /** + * Run mapFn on the interval start and end, returning a new Interval from the resulting DateTimes + * @param {function} mapFn + * @return {Interval} + * @example Interval.fromDateTimes(dt1, dt2).mapEndpoints(endpoint => endpoint.toUTC()) + * @example Interval.fromDateTimes(dt1, dt2).mapEndpoints(endpoint => endpoint.plus({ hours: 2 })) + */ + mapEndpoints(mapFn) { + return Interval.fromDateTimes(mapFn(this.s), mapFn(this.e)); + } +}; + +// ../../../node_modules/luxon/src/info.js +var Info = class { + /** + * Return whether the specified zone contains a DST. + * @param {string|Zone} [zone='local'] - Zone to check. Defaults to the environment's local zone. + * @return {boolean} + */ + static hasDST(zone = Settings.defaultZone) { + const proto = DateTime.now().setZone(zone).set({ month: 12 }); + return !zone.isUniversal && proto.offset !== proto.set({ month: 6 }).offset; + } + /** + * Return whether the specified zone is a valid IANA specifier. + * @param {string} zone - Zone to check + * @return {boolean} + */ + static isValidIANAZone(zone) { + return IANAZone.isValidZone(zone); + } + /** + * Converts the input into a {@link Zone} instance. + * + * * If `input` is already a Zone instance, it is returned unchanged. + * * If `input` is a string containing a valid time zone name, a Zone instance + * with that name is returned. + * * If `input` is a string that doesn't refer to a known time zone, a Zone + * instance with {@link Zone#isValid} == false is returned. + * * If `input is a number, a Zone instance with the specified fixed offset + * in minutes is returned. + * * If `input` is `null` or `undefined`, the default zone is returned. + * @param {string|Zone|number} [input] - the value to be converted + * @return {Zone} + */ + static normalizeZone(input) { + return normalizeZone(input, Settings.defaultZone); + } + /** + * Get the weekday on which the week starts according to the given locale. + * @param {Object} opts - options + * @param {string} [opts.locale] - the locale code + * @param {string} [opts.locObj=null] - an existing locale object to use + * @returns {number} the start of the week, 1 for Monday through 7 for Sunday + */ + static getStartOfWeek({ locale = null, locObj = null } = {}) { + return (locObj || Locale.create(locale)).getStartOfWeek(); + } + /** + * Get the minimum number of days necessary in a week before it is considered part of the next year according + * to the given locale. + * @param {Object} opts - options + * @param {string} [opts.locale] - the locale code + * @param {string} [opts.locObj=null] - an existing locale object to use + * @returns {number} + */ + static getMinimumDaysInFirstWeek({ locale = null, locObj = null } = {}) { + return (locObj || Locale.create(locale)).getMinDaysInFirstWeek(); + } + /** + * Get the weekdays, which are considered the weekend according to the given locale + * @param {Object} opts - options + * @param {string} [opts.locale] - the locale code + * @param {string} [opts.locObj=null] - an existing locale object to use + * @returns {number[]} an array of weekdays, 1 for Monday through 7 for Sunday + */ + static getWeekendWeekdays({ locale = null, locObj = null } = {}) { + return (locObj || Locale.create(locale)).getWeekendDays().slice(); + } + /** + * Return an array of standalone month names. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat + * @param {string} [length='long'] - the length of the month representation, such as "numeric", "2-digit", "narrow", "short", "long" + * @param {Object} opts - options + * @param {string} [opts.locale] - the locale code + * @param {string} [opts.numberingSystem=null] - the numbering system + * @param {string} [opts.locObj=null] - an existing locale object to use + * @param {string} [opts.outputCalendar='gregory'] - the calendar + * @example Info.months()[0] //=> 'January' + * @example Info.months('short')[0] //=> 'Jan' + * @example Info.months('numeric')[0] //=> '1' + * @example Info.months('short', { locale: 'fr-CA' } )[0] //=> 'janv.' + * @example Info.months('numeric', { locale: 'ar' })[0] //=> '١' + * @example Info.months('long', { outputCalendar: 'islamic' })[0] //=> 'Rabiʻ I' + * @return {Array} + */ + static months(length = "long", { locale = null, numberingSystem = null, locObj = null, outputCalendar = "gregory" } = {}) { + return (locObj || Locale.create(locale, numberingSystem, outputCalendar)).months(length); + } + /** + * Return an array of format month names. + * Format months differ from standalone months in that they're meant to appear next to the day of the month. In some languages, that + * changes the string. + * See {@link Info#months} + * @param {string} [length='long'] - the length of the month representation, such as "numeric", "2-digit", "narrow", "short", "long" + * @param {Object} opts - options + * @param {string} [opts.locale] - the locale code + * @param {string} [opts.numberingSystem=null] - the numbering system + * @param {string} [opts.locObj=null] - an existing locale object to use + * @param {string} [opts.outputCalendar='gregory'] - the calendar + * @return {Array} + */ + static monthsFormat(length = "long", { locale = null, numberingSystem = null, locObj = null, outputCalendar = "gregory" } = {}) { + return (locObj || Locale.create(locale, numberingSystem, outputCalendar)).months(length, true); + } + /** + * Return an array of standalone week names. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat + * @param {string} [length='long'] - the length of the weekday representation, such as "narrow", "short", "long". + * @param {Object} opts - options + * @param {string} [opts.locale] - the locale code + * @param {string} [opts.numberingSystem=null] - the numbering system + * @param {string} [opts.locObj=null] - an existing locale object to use + * @example Info.weekdays()[0] //=> 'Monday' + * @example Info.weekdays('short')[0] //=> 'Mon' + * @example Info.weekdays('short', { locale: 'fr-CA' })[0] //=> 'lun.' + * @example Info.weekdays('short', { locale: 'ar' })[0] //=> 'الاثنين' + * @return {Array} + */ + static weekdays(length = "long", { locale = null, numberingSystem = null, locObj = null } = {}) { + return (locObj || Locale.create(locale, numberingSystem, null)).weekdays(length); + } + /** + * Return an array of format week names. + * Format weekdays differ from standalone weekdays in that they're meant to appear next to more date information. In some languages, that + * changes the string. + * See {@link Info#weekdays} + * @param {string} [length='long'] - the length of the month representation, such as "narrow", "short", "long". + * @param {Object} opts - options + * @param {string} [opts.locale=null] - the locale code + * @param {string} [opts.numberingSystem=null] - the numbering system + * @param {string} [opts.locObj=null] - an existing locale object to use + * @return {Array} + */ + static weekdaysFormat(length = "long", { locale = null, numberingSystem = null, locObj = null } = {}) { + return (locObj || Locale.create(locale, numberingSystem, null)).weekdays(length, true); + } + /** + * Return an array of meridiems. + * @param {Object} opts - options + * @param {string} [opts.locale] - the locale code + * @example Info.meridiems() //=> [ 'AM', 'PM' ] + * @example Info.meridiems({ locale: 'my' }) //=> [ 'နံနက်', 'ညနေ' ] + * @return {Array} + */ + static meridiems({ locale = null } = {}) { + return Locale.create(locale).meridiems(); + } + /** + * Return an array of eras, such as ['BC', 'AD']. The locale can be specified, but the calendar system is always Gregorian. + * @param {string} [length='short'] - the length of the era representation, such as "short" or "long". + * @param {Object} opts - options + * @param {string} [opts.locale] - the locale code + * @example Info.eras() //=> [ 'BC', 'AD' ] + * @example Info.eras('long') //=> [ 'Before Christ', 'Anno Domini' ] + * @example Info.eras('long', { locale: 'fr' }) //=> [ 'avant Jésus-Christ', 'après Jésus-Christ' ] + * @return {Array} + */ + static eras(length = "short", { locale = null } = {}) { + return Locale.create(locale, null, "gregory").eras(length); + } + /** + * Return the set of available features in this environment. + * Some features of Luxon are not available in all environments. For example, on older browsers, relative time formatting support is not available. Use this function to figure out if that's the case. + * Keys: + * * `relative`: whether this environment supports relative time formatting + * * `localeWeek`: whether this environment supports different weekdays for the start of the week based on the locale + * @example Info.features() //=> { relative: false, localeWeek: true } + * @return {Object} + */ + static features() { + return { relative: hasRelative(), localeWeek: hasLocaleWeekInfo() }; + } +}; + +// ../../../node_modules/luxon/src/impl/diff.js +function dayDiff(earlier, later) { + const utcDayStart = (dt) => dt.toUTC(0, { keepLocalTime: true }).startOf("day").valueOf(), ms = utcDayStart(later) - utcDayStart(earlier); + return Math.floor(Duration.fromMillis(ms).as("days")); +} +function highOrderDiffs(cursor, later, units) { + const differs = [ + ["years", (a, b) => b.year - a.year], + ["quarters", (a, b) => b.quarter - a.quarter + (b.year - a.year) * 4], + ["months", (a, b) => b.month - a.month + (b.year - a.year) * 12], + [ + "weeks", + (a, b) => { + const days = dayDiff(a, b); + return (days - days % 7) / 7; + } + ], + ["days", dayDiff] + ]; + const results = {}; + const earlier = cursor; + let lowestOrder, highWater; + for (const [unit, differ] of differs) { + if (units.indexOf(unit) >= 0) { + lowestOrder = unit; + results[unit] = differ(cursor, later); + highWater = earlier.plus(results); + if (highWater > later) { + results[unit]--; + cursor = earlier.plus(results); + if (cursor > later) { + highWater = cursor; + results[unit]--; + cursor = earlier.plus(results); + } + } else { + cursor = highWater; + } + } + } + return [cursor, results, highWater, lowestOrder]; +} +function diff_default(earlier, later, units, opts) { + let [cursor, results, highWater, lowestOrder] = highOrderDiffs(earlier, later, units); + const remainingMillis = later - cursor; + const lowerOrderUnits = units.filter( + (u) => ["hours", "minutes", "seconds", "milliseconds"].indexOf(u) >= 0 + ); + if (lowerOrderUnits.length === 0) { + if (highWater < later) { + highWater = cursor.plus({ [lowestOrder]: 1 }); + } + if (highWater !== cursor) { + results[lowestOrder] = (results[lowestOrder] || 0) + remainingMillis / (highWater - cursor); + } + } + const duration = Duration.fromObject(results, opts); + if (lowerOrderUnits.length > 0) { + return Duration.fromMillis(remainingMillis, opts).shiftTo(...lowerOrderUnits).plus(duration); + } else { + return duration; + } +} + +// ../../../node_modules/luxon/src/impl/digits.js +var numberingSystems = { + arab: "[\u0660-\u0669]", + arabext: "[\u06F0-\u06F9]", + bali: "[\u1B50-\u1B59]", + beng: "[\u09E6-\u09EF]", + deva: "[\u0966-\u096F]", + fullwide: "[\uFF10-\uFF19]", + gujr: "[\u0AE6-\u0AEF]", + hanidec: "[\u3007|\u4E00|\u4E8C|\u4E09|\u56DB|\u4E94|\u516D|\u4E03|\u516B|\u4E5D]", + khmr: "[\u17E0-\u17E9]", + knda: "[\u0CE6-\u0CEF]", + laoo: "[\u0ED0-\u0ED9]", + limb: "[\u1946-\u194F]", + mlym: "[\u0D66-\u0D6F]", + mong: "[\u1810-\u1819]", + mymr: "[\u1040-\u1049]", + orya: "[\u0B66-\u0B6F]", + tamldec: "[\u0BE6-\u0BEF]", + telu: "[\u0C66-\u0C6F]", + thai: "[\u0E50-\u0E59]", + tibt: "[\u0F20-\u0F29]", + latn: "\\d" +}; +var numberingSystemsUTF16 = { + arab: [1632, 1641], + arabext: [1776, 1785], + bali: [6992, 7001], + beng: [2534, 2543], + deva: [2406, 2415], + fullwide: [65296, 65303], + gujr: [2790, 2799], + khmr: [6112, 6121], + knda: [3302, 3311], + laoo: [3792, 3801], + limb: [6470, 6479], + mlym: [3430, 3439], + mong: [6160, 6169], + mymr: [4160, 4169], + orya: [2918, 2927], + tamldec: [3046, 3055], + telu: [3174, 3183], + thai: [3664, 3673], + tibt: [3872, 3881] +}; +var hanidecChars = numberingSystems.hanidec.replace(/[\[|\]]/g, "").split(""); +function parseDigits(str) { + let value = parseInt(str, 10); + if (isNaN(value)) { + value = ""; + for (let i = 0; i < str.length; i++) { + const code = str.charCodeAt(i); + if (str[i].search(numberingSystems.hanidec) !== -1) { + value += hanidecChars.indexOf(str[i]); + } else { + for (const key in numberingSystemsUTF16) { + const [min, max] = numberingSystemsUTF16[key]; + if (code >= min && code <= max) { + value += code - min; + } + } + } + } + return parseInt(value, 10); + } else { + return value; + } +} +function digitRegex({ numberingSystem }, append = "") { + return new RegExp(`${numberingSystems[numberingSystem || "latn"]}${append}`); +} + +// ../../../node_modules/luxon/src/impl/tokenParser.js +var MISSING_FTP = "missing Intl.DateTimeFormat.formatToParts support"; +function intUnit(regex, post = (i) => i) { + return { regex, deser: ([s2]) => post(parseDigits(s2)) }; +} +var NBSP = String.fromCharCode(160); +var spaceOrNBSP = `[ ${NBSP}]`; +var spaceOrNBSPRegExp = new RegExp(spaceOrNBSP, "g"); +function fixListRegex(s2) { + return s2.replace(/\./g, "\\.?").replace(spaceOrNBSPRegExp, spaceOrNBSP); +} +function stripInsensitivities(s2) { + return s2.replace(/\./g, "").replace(spaceOrNBSPRegExp, " ").toLowerCase(); +} +function oneOf(strings, startIndex) { + if (strings === null) { + return null; + } else { + return { + regex: RegExp(strings.map(fixListRegex).join("|")), + deser: ([s2]) => strings.findIndex((i) => stripInsensitivities(s2) === stripInsensitivities(i)) + startIndex + }; + } +} +function offset(regex, groups) { + return { regex, deser: ([, h, m]) => signedOffset(h, m), groups }; +} +function simple(regex) { + return { regex, deser: ([s2]) => s2 }; +} +function escapeToken(value) { + return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); +} +function unitForToken(token, loc) { + const one = digitRegex(loc), two = digitRegex(loc, "{2}"), three = digitRegex(loc, "{3}"), four = digitRegex(loc, "{4}"), six = digitRegex(loc, "{6}"), oneOrTwo = digitRegex(loc, "{1,2}"), oneToThree = digitRegex(loc, "{1,3}"), oneToSix = digitRegex(loc, "{1,6}"), oneToNine = digitRegex(loc, "{1,9}"), twoToFour = digitRegex(loc, "{2,4}"), fourToSix = digitRegex(loc, "{4,6}"), literal = (t) => ({ regex: RegExp(escapeToken(t.val)), deser: ([s2]) => s2, literal: true }), unitate = (t) => { + if (token.literal) { + return literal(t); + } + switch (t.val) { + case "G": + return oneOf(loc.eras("short"), 0); + case "GG": + return oneOf(loc.eras("long"), 0); + case "y": + return intUnit(oneToSix); + case "yy": + return intUnit(twoToFour, untruncateYear); + case "yyyy": + return intUnit(four); + case "yyyyy": + return intUnit(fourToSix); + case "yyyyyy": + return intUnit(six); + case "M": + return intUnit(oneOrTwo); + case "MM": + return intUnit(two); + case "MMM": + return oneOf(loc.months("short", true), 1); + case "MMMM": + return oneOf(loc.months("long", true), 1); + case "L": + return intUnit(oneOrTwo); + case "LL": + return intUnit(two); + case "LLL": + return oneOf(loc.months("short", false), 1); + case "LLLL": + return oneOf(loc.months("long", false), 1); + case "d": + return intUnit(oneOrTwo); + case "dd": + return intUnit(two); + case "o": + return intUnit(oneToThree); + case "ooo": + return intUnit(three); + case "HH": + return intUnit(two); + case "H": + return intUnit(oneOrTwo); + case "hh": + return intUnit(two); + case "h": + return intUnit(oneOrTwo); + case "mm": + return intUnit(two); + case "m": + return intUnit(oneOrTwo); + case "q": + return intUnit(oneOrTwo); + case "qq": + return intUnit(two); + case "s": + return intUnit(oneOrTwo); + case "ss": + return intUnit(two); + case "S": + return intUnit(oneToThree); + case "SSS": + return intUnit(three); + case "u": + return simple(oneToNine); + case "uu": + return simple(oneOrTwo); + case "uuu": + return intUnit(one); + case "a": + return oneOf(loc.meridiems(), 0); + case "kkkk": + return intUnit(four); + case "kk": + return intUnit(twoToFour, untruncateYear); + case "W": + return intUnit(oneOrTwo); + case "WW": + return intUnit(two); + case "E": + case "c": + return intUnit(one); + case "EEE": + return oneOf(loc.weekdays("short", false), 1); + case "EEEE": + return oneOf(loc.weekdays("long", false), 1); + case "ccc": + return oneOf(loc.weekdays("short", true), 1); + case "cccc": + return oneOf(loc.weekdays("long", true), 1); + case "Z": + case "ZZ": + return offset(new RegExp(`([+-]${oneOrTwo.source})(?::(${two.source}))?`), 2); + case "ZZZ": + return offset(new RegExp(`([+-]${oneOrTwo.source})(${two.source})?`), 2); + case "z": + return simple(/[a-z_+-/]{1,256}?/i); + case " ": + return simple(/[^\S\n\r]/); + default: + return literal(t); + } + }; + const unit = unitate(token) || { + invalidReason: MISSING_FTP + }; + unit.token = token; + return unit; +} +var partTypeStyleToTokenVal = { + year: { + "2-digit": "yy", + numeric: "yyyyy" + }, + month: { + numeric: "M", + "2-digit": "MM", + short: "MMM", + long: "MMMM" + }, + day: { + numeric: "d", + "2-digit": "dd" + }, + weekday: { + short: "EEE", + long: "EEEE" + }, + dayperiod: "a", + dayPeriod: "a", + hour12: { + numeric: "h", + "2-digit": "hh" + }, + hour24: { + numeric: "H", + "2-digit": "HH" + }, + minute: { + numeric: "m", + "2-digit": "mm" + }, + second: { + numeric: "s", + "2-digit": "ss" + }, + timeZoneName: { + long: "ZZZZZ", + short: "ZZZ" + } +}; +function tokenForPart(part, formatOpts, resolvedOpts) { + const { type, value } = part; + if (type === "literal") { + const isSpace = /^\s+$/.test(value); + return { + literal: !isSpace, + val: isSpace ? " " : value + }; + } + const style = formatOpts[type]; + let actualType = type; + if (type === "hour") { + if (formatOpts.hour12 != null) { + actualType = formatOpts.hour12 ? "hour12" : "hour24"; + } else if (formatOpts.hourCycle != null) { + if (formatOpts.hourCycle === "h11" || formatOpts.hourCycle === "h12") { + actualType = "hour12"; + } else { + actualType = "hour24"; + } + } else { + actualType = resolvedOpts.hour12 ? "hour12" : "hour24"; + } + } + let val = partTypeStyleToTokenVal[actualType]; + if (typeof val === "object") { + val = val[style]; + } + if (val) { + return { + literal: false, + val + }; + } + return void 0; +} +function buildRegex(units) { + const re = units.map((u) => u.regex).reduce((f, r) => `${f}(${r.source})`, ""); + return [`^${re}$`, units]; +} +function match(input, regex, handlers) { + const matches = input.match(regex); + if (matches) { + const all = {}; + let matchIndex = 1; + for (const i in handlers) { + if (hasOwnProperty(handlers, i)) { + const h = handlers[i], groups = h.groups ? h.groups + 1 : 1; + if (!h.literal && h.token) { + all[h.token.val[0]] = h.deser(matches.slice(matchIndex, matchIndex + groups)); + } + matchIndex += groups; + } + } + return [matches, all]; + } else { + return [matches, {}]; + } +} +function dateTimeFromMatches(matches) { + const toField = (token) => { + switch (token) { + case "S": + return "millisecond"; + case "s": + return "second"; + case "m": + return "minute"; + case "h": + case "H": + return "hour"; + case "d": + return "day"; + case "o": + return "ordinal"; + case "L": + case "M": + return "month"; + case "y": + return "year"; + case "E": + case "c": + return "weekday"; + case "W": + return "weekNumber"; + case "k": + return "weekYear"; + case "q": + return "quarter"; + default: + return null; + } + }; + let zone = null; + let specificOffset; + if (!isUndefined(matches.z)) { + zone = IANAZone.create(matches.z); + } + if (!isUndefined(matches.Z)) { + if (!zone) { + zone = new FixedOffsetZone(matches.Z); + } + specificOffset = matches.Z; + } + if (!isUndefined(matches.q)) { + matches.M = (matches.q - 1) * 3 + 1; + } + if (!isUndefined(matches.h)) { + if (matches.h < 12 && matches.a === 1) { + matches.h += 12; + } else if (matches.h === 12 && matches.a === 0) { + matches.h = 0; + } + } + if (matches.G === 0 && matches.y) { + matches.y = -matches.y; + } + if (!isUndefined(matches.u)) { + matches.S = parseMillis(matches.u); + } + const vals = Object.keys(matches).reduce((r, k) => { + const f = toField(k); + if (f) { + r[f] = matches[k]; + } + return r; + }, {}); + return [vals, zone, specificOffset]; +} +var dummyDateTimeCache = null; +function getDummyDateTime() { + if (!dummyDateTimeCache) { + dummyDateTimeCache = DateTime.fromMillis(1555555555555); + } + return dummyDateTimeCache; +} +function maybeExpandMacroToken(token, locale) { + if (token.literal) { + return token; + } + const formatOpts = Formatter.macroTokenToFormatOpts(token.val); + const tokens = formatOptsToTokens(formatOpts, locale); + if (tokens == null || tokens.includes(void 0)) { + return token; + } + return tokens; +} +function expandMacroTokens(tokens, locale) { + return Array.prototype.concat(...tokens.map((t) => maybeExpandMacroToken(t, locale))); +} +function explainFromTokens(locale, input, format) { + const tokens = expandMacroTokens(Formatter.parseFormat(format), locale), units = tokens.map((t) => unitForToken(t, locale)), disqualifyingUnit = units.find((t) => t.invalidReason); + if (disqualifyingUnit) { + return { input, tokens, invalidReason: disqualifyingUnit.invalidReason }; + } else { + const [regexString, handlers] = buildRegex(units), regex = RegExp(regexString, "i"), [rawMatches, matches] = match(input, regex, handlers), [result, zone, specificOffset] = matches ? dateTimeFromMatches(matches) : [null, null, void 0]; + if (hasOwnProperty(matches, "a") && hasOwnProperty(matches, "H")) { + throw new ConflictingSpecificationError( + "Can't include meridiem when specifying 24-hour format" + ); + } + return { input, tokens, regex, rawMatches, matches, result, zone, specificOffset }; + } +} +function parseFromTokens(locale, input, format) { + const { result, zone, specificOffset, invalidReason } = explainFromTokens(locale, input, format); + return [result, zone, specificOffset, invalidReason]; +} +function formatOptsToTokens(formatOpts, locale) { + if (!formatOpts) { + return null; + } + const formatter = Formatter.create(locale, formatOpts); + const df = formatter.dtFormatter(getDummyDateTime()); + const parts = df.formatToParts(); + const resolvedOpts = df.resolvedOptions(); + return parts.map((p) => tokenForPart(p, formatOpts, resolvedOpts)); +} + +// ../../../node_modules/luxon/src/datetime.js +var INVALID3 = "Invalid DateTime"; +var MAX_DATE = 864e13; +function unsupportedZone(zone) { + return new Invalid("unsupported zone", `the zone "${zone.name}" is not supported`); +} +function possiblyCachedWeekData(dt) { + if (dt.weekData === null) { + dt.weekData = gregorianToWeek(dt.c); + } + return dt.weekData; +} +function possiblyCachedLocalWeekData(dt) { + if (dt.localWeekData === null) { + dt.localWeekData = gregorianToWeek( + dt.c, + dt.loc.getMinDaysInFirstWeek(), + dt.loc.getStartOfWeek() + ); + } + return dt.localWeekData; +} +function clone6(inst, alts) { + const current = { + ts: inst.ts, + zone: inst.zone, + c: inst.c, + o: inst.o, + loc: inst.loc, + invalid: inst.invalid + }; + return new DateTime({ ...current, ...alts, old: current }); +} +function fixOffset(localTS, o, tz) { + let utcGuess = localTS - o * 60 * 1e3; + const o2 = tz.offset(utcGuess); + if (o === o2) { + return [utcGuess, o]; + } + utcGuess -= (o2 - o) * 60 * 1e3; + const o3 = tz.offset(utcGuess); + if (o2 === o3) { + return [utcGuess, o2]; + } + return [localTS - Math.min(o2, o3) * 60 * 1e3, Math.max(o2, o3)]; +} +function tsToObj(ts, offset2) { + ts += offset2 * 60 * 1e3; + const d = new Date(ts); + return { + year: d.getUTCFullYear(), + month: d.getUTCMonth() + 1, + day: d.getUTCDate(), + hour: d.getUTCHours(), + minute: d.getUTCMinutes(), + second: d.getUTCSeconds(), + millisecond: d.getUTCMilliseconds() + }; +} +function objToTS(obj, offset2, zone) { + return fixOffset(objToLocalTS(obj), offset2, zone); +} +function adjustTime(inst, dur) { + const oPre = inst.o, year = inst.c.year + Math.trunc(dur.years), month = inst.c.month + Math.trunc(dur.months) + Math.trunc(dur.quarters) * 3, c = { + ...inst.c, + year, + month, + day: Math.min(inst.c.day, daysInMonth(year, month)) + Math.trunc(dur.days) + Math.trunc(dur.weeks) * 7 + }, millisToAdd = Duration.fromObject({ + years: dur.years - Math.trunc(dur.years), + quarters: dur.quarters - Math.trunc(dur.quarters), + months: dur.months - Math.trunc(dur.months), + weeks: dur.weeks - Math.trunc(dur.weeks), + days: dur.days - Math.trunc(dur.days), + hours: dur.hours, + minutes: dur.minutes, + seconds: dur.seconds, + milliseconds: dur.milliseconds + }).as("milliseconds"), localTS = objToLocalTS(c); + let [ts, o] = fixOffset(localTS, oPre, inst.zone); + if (millisToAdd !== 0) { + ts += millisToAdd; + o = inst.zone.offset(ts); + } + return { ts, o }; +} +function parseDataToDateTime(parsed, parsedZone, opts, format, text, specificOffset) { + const { setZone, zone } = opts; + if (parsed && Object.keys(parsed).length !== 0 || parsedZone) { + const interpretationZone = parsedZone || zone, inst = DateTime.fromObject(parsed, { + ...opts, + zone: interpretationZone, + specificOffset + }); + return setZone ? inst : inst.setZone(zone); + } else { + return DateTime.invalid( + new Invalid("unparsable", `the input "${text}" can't be parsed as ${format}`) + ); + } +} +function toTechFormat(dt, format, allowZ = true) { + return dt.isValid ? Formatter.create(Locale.create("en-US"), { + allowZ, + forceSimple: true + }).formatDateTimeFromString(dt, format) : null; +} +function toISODate(o, extended) { + const longFormat = o.c.year > 9999 || o.c.year < 0; + let c = ""; + if (longFormat && o.c.year >= 0) + c += "+"; + c += padStart(o.c.year, longFormat ? 6 : 4); + if (extended) { + c += "-"; + c += padStart(o.c.month); + c += "-"; + c += padStart(o.c.day); + } else { + c += padStart(o.c.month); + c += padStart(o.c.day); + } + return c; +} +function toISOTime(o, extended, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone) { + let c = padStart(o.c.hour); + if (extended) { + c += ":"; + c += padStart(o.c.minute); + if (o.c.millisecond !== 0 || o.c.second !== 0 || !suppressSeconds) { + c += ":"; + } + } else { + c += padStart(o.c.minute); + } + if (o.c.millisecond !== 0 || o.c.second !== 0 || !suppressSeconds) { + c += padStart(o.c.second); + if (o.c.millisecond !== 0 || !suppressMilliseconds) { + c += "."; + c += padStart(o.c.millisecond, 3); + } + } + if (includeOffset) { + if (o.isOffsetFixed && o.offset === 0 && !extendedZone) { + c += "Z"; + } else if (o.o < 0) { + c += "-"; + c += padStart(Math.trunc(-o.o / 60)); + c += ":"; + c += padStart(Math.trunc(-o.o % 60)); + } else { + c += "+"; + c += padStart(Math.trunc(o.o / 60)); + c += ":"; + c += padStart(Math.trunc(o.o % 60)); + } + } + if (extendedZone) { + c += "[" + o.zone.ianaName + "]"; + } + return c; +} +var defaultUnitValues = { + month: 1, + day: 1, + hour: 0, + minute: 0, + second: 0, + millisecond: 0 +}; +var defaultWeekUnitValues = { + weekNumber: 1, + weekday: 1, + hour: 0, + minute: 0, + second: 0, + millisecond: 0 +}; +var defaultOrdinalUnitValues = { + ordinal: 1, + hour: 0, + minute: 0, + second: 0, + millisecond: 0 +}; +var orderedUnits2 = ["year", "month", "day", "hour", "minute", "second", "millisecond"]; +var orderedWeekUnits = [ + "weekYear", + "weekNumber", + "weekday", + "hour", + "minute", + "second", + "millisecond" +]; +var orderedOrdinalUnits = ["year", "ordinal", "hour", "minute", "second", "millisecond"]; +function normalizeUnit(unit) { + const normalized = { + year: "year", + years: "year", + month: "month", + months: "month", + day: "day", + days: "day", + hour: "hour", + hours: "hour", + minute: "minute", + minutes: "minute", + quarter: "quarter", + quarters: "quarter", + second: "second", + seconds: "second", + millisecond: "millisecond", + milliseconds: "millisecond", + weekday: "weekday", + weekdays: "weekday", + weeknumber: "weekNumber", + weeksnumber: "weekNumber", + weeknumbers: "weekNumber", + weekyear: "weekYear", + weekyears: "weekYear", + ordinal: "ordinal" + }[unit.toLowerCase()]; + if (!normalized) + throw new InvalidUnitError(unit); + return normalized; +} +function normalizeUnitWithLocalWeeks(unit) { + switch (unit.toLowerCase()) { + case "localweekday": + case "localweekdays": + return "localWeekday"; + case "localweeknumber": + case "localweeknumbers": + return "localWeekNumber"; + case "localweekyear": + case "localweekyears": + return "localWeekYear"; + default: + return normalizeUnit(unit); + } +} +function quickDT(obj, opts) { + const zone = normalizeZone(opts.zone, Settings.defaultZone), loc = Locale.fromObject(opts), tsNow = Settings.now(); + let ts, o; + if (!isUndefined(obj.year)) { + for (const u of orderedUnits2) { + if (isUndefined(obj[u])) { + obj[u] = defaultUnitValues[u]; + } + } + const invalid = hasInvalidGregorianData(obj) || hasInvalidTimeData(obj); + if (invalid) { + return DateTime.invalid(invalid); + } + const offsetProvis = zone.offset(tsNow); + [ts, o] = objToTS(obj, offsetProvis, zone); + } else { + ts = tsNow; + } + return new DateTime({ ts, zone, loc, o }); +} +function diffRelative(start, end, opts) { + const round3 = isUndefined(opts.round) ? true : opts.round, format = (c, unit) => { + c = roundTo(c, round3 || opts.calendary ? 0 : 2, true); + const formatter = end.loc.clone(opts).relFormatter(opts); + return formatter.format(c, unit); + }, differ = (unit) => { + if (opts.calendary) { + if (!end.hasSame(start, unit)) { + return end.startOf(unit).diff(start.startOf(unit), unit).get(unit); + } else + return 0; + } else { + return end.diff(start, unit).get(unit); + } + }; + if (opts.unit) { + return format(differ(opts.unit), opts.unit); + } + for (const unit of opts.units) { + const count = differ(unit); + if (Math.abs(count) >= 1) { + return format(count, unit); + } + } + return format(start > end ? -0 : 0, opts.units[opts.units.length - 1]); +} +function lastOpts(argList) { + let opts = {}, args; + if (argList.length > 0 && typeof argList[argList.length - 1] === "object") { + opts = argList[argList.length - 1]; + args = Array.from(argList).slice(0, argList.length - 1); + } else { + args = Array.from(argList); + } + return [opts, args]; +} +var DateTime = class { + /** + * @access private + */ + constructor(config) { + const zone = config.zone || Settings.defaultZone; + let invalid = config.invalid || (Number.isNaN(config.ts) ? new Invalid("invalid input") : null) || (!zone.isValid ? unsupportedZone(zone) : null); + this.ts = isUndefined(config.ts) ? Settings.now() : config.ts; + let c = null, o = null; + if (!invalid) { + const unchanged = config.old && config.old.ts === this.ts && config.old.zone.equals(zone); + if (unchanged) { + [c, o] = [config.old.c, config.old.o]; + } else { + const ot = zone.offset(this.ts); + c = tsToObj(this.ts, ot); + invalid = Number.isNaN(c.year) ? new Invalid("invalid input") : null; + c = invalid ? null : c; + o = invalid ? null : ot; + } + } + this._zone = zone; + this.loc = config.loc || Locale.create(); + this.invalid = invalid; + this.weekData = null; + this.localWeekData = null; + this.c = c; + this.o = o; + this.isLuxonDateTime = true; + } + // CONSTRUCT + /** + * Create a DateTime for the current instant, in the system's time zone. + * + * Use Settings to override these default values if needed. + * @example DateTime.now().toISO() //~> now in the ISO format + * @return {DateTime} + */ + static now() { + return new DateTime({}); + } + /** + * Create a local DateTime + * @param {number} [year] - The calendar year. If omitted (as in, call `local()` with no arguments), the current time will be used + * @param {number} [month=1] - The month, 1-indexed + * @param {number} [day=1] - The day of the month, 1-indexed + * @param {number} [hour=0] - The hour of the day, in 24-hour time + * @param {number} [minute=0] - The minute of the hour, meaning a number between 0 and 59 + * @param {number} [second=0] - The second of the minute, meaning a number between 0 and 59 + * @param {number} [millisecond=0] - The millisecond of the second, meaning a number between 0 and 999 + * @example DateTime.local() //~> now + * @example DateTime.local({ zone: "America/New_York" }) //~> now, in US east coast time + * @example DateTime.local(2017) //~> 2017-01-01T00:00:00 + * @example DateTime.local(2017, 3) //~> 2017-03-01T00:00:00 + * @example DateTime.local(2017, 3, 12, { locale: "fr" }) //~> 2017-03-12T00:00:00, with a French locale + * @example DateTime.local(2017, 3, 12, 5) //~> 2017-03-12T05:00:00 + * @example DateTime.local(2017, 3, 12, 5, { zone: "utc" }) //~> 2017-03-12T05:00:00, in UTC + * @example DateTime.local(2017, 3, 12, 5, 45) //~> 2017-03-12T05:45:00 + * @example DateTime.local(2017, 3, 12, 5, 45, 10) //~> 2017-03-12T05:45:10 + * @example DateTime.local(2017, 3, 12, 5, 45, 10, 765) //~> 2017-03-12T05:45:10.765 + * @return {DateTime} + */ + static local() { + const [opts, args] = lastOpts(arguments), [year, month, day, hour, minute, second, millisecond] = args; + return quickDT({ year, month, day, hour, minute, second, millisecond }, opts); + } + /** + * Create a DateTime in UTC + * @param {number} [year] - The calendar year. If omitted (as in, call `utc()` with no arguments), the current time will be used + * @param {number} [month=1] - The month, 1-indexed + * @param {number} [day=1] - The day of the month + * @param {number} [hour=0] - The hour of the day, in 24-hour time + * @param {number} [minute=0] - The minute of the hour, meaning a number between 0 and 59 + * @param {number} [second=0] - The second of the minute, meaning a number between 0 and 59 + * @param {number} [millisecond=0] - The millisecond of the second, meaning a number between 0 and 999 + * @param {Object} options - configuration options for the DateTime + * @param {string} [options.locale] - a locale to set on the resulting DateTime instance + * @param {string} [options.outputCalendar] - the output calendar to set on the resulting DateTime instance + * @param {string} [options.numberingSystem] - the numbering system to set on the resulting DateTime instance + * @example DateTime.utc() //~> now + * @example DateTime.utc(2017) //~> 2017-01-01T00:00:00Z + * @example DateTime.utc(2017, 3) //~> 2017-03-01T00:00:00Z + * @example DateTime.utc(2017, 3, 12) //~> 2017-03-12T00:00:00Z + * @example DateTime.utc(2017, 3, 12, 5) //~> 2017-03-12T05:00:00Z + * @example DateTime.utc(2017, 3, 12, 5, 45) //~> 2017-03-12T05:45:00Z + * @example DateTime.utc(2017, 3, 12, 5, 45, { locale: "fr" }) //~> 2017-03-12T05:45:00Z with a French locale + * @example DateTime.utc(2017, 3, 12, 5, 45, 10) //~> 2017-03-12T05:45:10Z + * @example DateTime.utc(2017, 3, 12, 5, 45, 10, 765, { locale: "fr" }) //~> 2017-03-12T05:45:10.765Z with a French locale + * @return {DateTime} + */ + static utc() { + const [opts, args] = lastOpts(arguments), [year, month, day, hour, minute, second, millisecond] = args; + opts.zone = FixedOffsetZone.utcInstance; + return quickDT({ year, month, day, hour, minute, second, millisecond }, opts); + } + /** + * Create a DateTime from a JavaScript Date object. Uses the default zone. + * @param {Date} date - a JavaScript Date object + * @param {Object} options - configuration options for the DateTime + * @param {string|Zone} [options.zone='local'] - the zone to place the DateTime into + * @return {DateTime} + */ + static fromJSDate(date, options = {}) { + const ts = isDate(date) ? date.valueOf() : NaN; + if (Number.isNaN(ts)) { + return DateTime.invalid("invalid input"); + } + const zoneToUse = normalizeZone(options.zone, Settings.defaultZone); + if (!zoneToUse.isValid) { + return DateTime.invalid(unsupportedZone(zoneToUse)); + } + return new DateTime({ + ts, + zone: zoneToUse, + loc: Locale.fromObject(options) + }); + } + /** + * Create a DateTime from a number of milliseconds since the epoch (meaning since 1 January 1970 00:00:00 UTC). Uses the default zone. + * @param {number} milliseconds - a number of milliseconds since 1970 UTC + * @param {Object} options - configuration options for the DateTime + * @param {string|Zone} [options.zone='local'] - the zone to place the DateTime into + * @param {string} [options.locale] - a locale to set on the resulting DateTime instance + * @param {string} options.outputCalendar - the output calendar to set on the resulting DateTime instance + * @param {string} options.numberingSystem - the numbering system to set on the resulting DateTime instance + * @return {DateTime} + */ + static fromMillis(milliseconds, options = {}) { + if (!isNumber3(milliseconds)) { + throw new InvalidArgumentError( + `fromMillis requires a numerical input, but received a ${typeof milliseconds} with value ${milliseconds}` + ); + } else if (milliseconds < -MAX_DATE || milliseconds > MAX_DATE) { + return DateTime.invalid("Timestamp out of range"); + } else { + return new DateTime({ + ts: milliseconds, + zone: normalizeZone(options.zone, Settings.defaultZone), + loc: Locale.fromObject(options) + }); + } + } + /** + * Create a DateTime from a number of seconds since the epoch (meaning since 1 January 1970 00:00:00 UTC). Uses the default zone. + * @param {number} seconds - a number of seconds since 1970 UTC + * @param {Object} options - configuration options for the DateTime + * @param {string|Zone} [options.zone='local'] - the zone to place the DateTime into + * @param {string} [options.locale] - a locale to set on the resulting DateTime instance + * @param {string} options.outputCalendar - the output calendar to set on the resulting DateTime instance + * @param {string} options.numberingSystem - the numbering system to set on the resulting DateTime instance + * @return {DateTime} + */ + static fromSeconds(seconds, options = {}) { + if (!isNumber3(seconds)) { + throw new InvalidArgumentError("fromSeconds requires a numerical input"); + } else { + return new DateTime({ + ts: seconds * 1e3, + zone: normalizeZone(options.zone, Settings.defaultZone), + loc: Locale.fromObject(options) + }); + } + } + /** + * Create a DateTime from a JavaScript object with keys like 'year' and 'hour' with reasonable defaults. + * @param {Object} obj - the object to create the DateTime from + * @param {number} obj.year - a year, such as 1987 + * @param {number} obj.month - a month, 1-12 + * @param {number} obj.day - a day of the month, 1-31, depending on the month + * @param {number} obj.ordinal - day of the year, 1-365 or 366 + * @param {number} obj.weekYear - an ISO week year + * @param {number} obj.weekNumber - an ISO week number, between 1 and 52 or 53, depending on the year + * @param {number} obj.weekday - an ISO weekday, 1-7, where 1 is Monday and 7 is Sunday + * @param {number} obj.localWeekYear - a week year, according to the locale + * @param {number} obj.localWeekNumber - a week number, between 1 and 52 or 53, depending on the year, according to the locale + * @param {number} obj.localWeekday - a weekday, 1-7, where 1 is the first and 7 is the last day of the week, according to the locale + * @param {number} obj.hour - hour of the day, 0-23 + * @param {number} obj.minute - minute of the hour, 0-59 + * @param {number} obj.second - second of the minute, 0-59 + * @param {number} obj.millisecond - millisecond of the second, 0-999 + * @param {Object} opts - options for creating this DateTime + * @param {string|Zone} [opts.zone='local'] - interpret the numbers in the context of a particular zone. Can take any value taken as the first argument to setZone() + * @param {string} [opts.locale='system\'s locale'] - a locale to set on the resulting DateTime instance + * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance + * @param {string} opts.numberingSystem - the numbering system to set on the resulting DateTime instance + * @example DateTime.fromObject({ year: 1982, month: 5, day: 25}).toISODate() //=> '1982-05-25' + * @example DateTime.fromObject({ year: 1982 }).toISODate() //=> '1982-01-01' + * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }) //~> today at 10:26:06 + * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'utc' }), + * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'local' }) + * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'America/New_York' }) + * @example DateTime.fromObject({ weekYear: 2016, weekNumber: 2, weekday: 3 }).toISODate() //=> '2016-01-13' + * @example DateTime.fromObject({ localWeekYear: 2022, localWeekNumber: 1, localWeekday: 1 }, { locale: "en-US" }).toISODate() //=> '2021-12-26' + * @return {DateTime} + */ + static fromObject(obj, opts = {}) { + obj = obj || {}; + const zoneToUse = normalizeZone(opts.zone, Settings.defaultZone); + if (!zoneToUse.isValid) { + return DateTime.invalid(unsupportedZone(zoneToUse)); + } + const loc = Locale.fromObject(opts); + const normalized = normalizeObject(obj, normalizeUnitWithLocalWeeks); + const { minDaysInFirstWeek, startOfWeek } = usesLocalWeekValues(normalized, loc); + const tsNow = Settings.now(), offsetProvis = !isUndefined(opts.specificOffset) ? opts.specificOffset : zoneToUse.offset(tsNow), containsOrdinal = !isUndefined(normalized.ordinal), containsGregorYear = !isUndefined(normalized.year), containsGregorMD = !isUndefined(normalized.month) || !isUndefined(normalized.day), containsGregor = containsGregorYear || containsGregorMD, definiteWeekDef = normalized.weekYear || normalized.weekNumber; + if ((containsGregor || containsOrdinal) && definiteWeekDef) { + throw new ConflictingSpecificationError( + "Can't mix weekYear/weekNumber units with year/month/day or ordinals" + ); + } + if (containsGregorMD && containsOrdinal) { + throw new ConflictingSpecificationError("Can't mix ordinal dates with month/day"); + } + const useWeekData = definiteWeekDef || normalized.weekday && !containsGregor; + let units, defaultValues, objNow = tsToObj(tsNow, offsetProvis); + if (useWeekData) { + units = orderedWeekUnits; + defaultValues = defaultWeekUnitValues; + objNow = gregorianToWeek(objNow, minDaysInFirstWeek, startOfWeek); + } else if (containsOrdinal) { + units = orderedOrdinalUnits; + defaultValues = defaultOrdinalUnitValues; + objNow = gregorianToOrdinal(objNow); + } else { + units = orderedUnits2; + defaultValues = defaultUnitValues; + } + let foundFirst = false; + for (const u of units) { + const v = normalized[u]; + if (!isUndefined(v)) { + foundFirst = true; + } else if (foundFirst) { + normalized[u] = defaultValues[u]; + } else { + normalized[u] = objNow[u]; + } + } + const higherOrderInvalid = useWeekData ? hasInvalidWeekData(normalized, minDaysInFirstWeek, startOfWeek) : containsOrdinal ? hasInvalidOrdinalData(normalized) : hasInvalidGregorianData(normalized), invalid = higherOrderInvalid || hasInvalidTimeData(normalized); + if (invalid) { + return DateTime.invalid(invalid); + } + const gregorian = useWeekData ? weekToGregorian(normalized, minDaysInFirstWeek, startOfWeek) : containsOrdinal ? ordinalToGregorian(normalized) : normalized, [tsFinal, offsetFinal] = objToTS(gregorian, offsetProvis, zoneToUse), inst = new DateTime({ + ts: tsFinal, + zone: zoneToUse, + o: offsetFinal, + loc + }); + if (normalized.weekday && containsGregor && obj.weekday !== inst.weekday) { + return DateTime.invalid( + "mismatched weekday", + `you can't specify both a weekday of ${normalized.weekday} and a date of ${inst.toISO()}` + ); + } + return inst; + } + /** + * Create a DateTime from an ISO 8601 string + * @param {string} text - the ISO string + * @param {Object} opts - options to affect the creation + * @param {string|Zone} [opts.zone='local'] - use this zone if no offset is specified in the input string itself. Will also convert the time to this zone + * @param {boolean} [opts.setZone=false] - override the zone with a fixed-offset zone specified in the string itself, if it specifies one + * @param {string} [opts.locale='system's locale'] - a locale to set on the resulting DateTime instance + * @param {string} [opts.outputCalendar] - the output calendar to set on the resulting DateTime instance + * @param {string} [opts.numberingSystem] - the numbering system to set on the resulting DateTime instance + * @example DateTime.fromISO('2016-05-25T09:08:34.123') + * @example DateTime.fromISO('2016-05-25T09:08:34.123+06:00') + * @example DateTime.fromISO('2016-05-25T09:08:34.123+06:00', {setZone: true}) + * @example DateTime.fromISO('2016-05-25T09:08:34.123', {zone: 'utc'}) + * @example DateTime.fromISO('2016-W05-4') + * @return {DateTime} + */ + static fromISO(text, opts = {}) { + const [vals, parsedZone] = parseISODate(text); + return parseDataToDateTime(vals, parsedZone, opts, "ISO 8601", text); + } + /** + * Create a DateTime from an RFC 2822 string + * @param {string} text - the RFC 2822 string + * @param {Object} opts - options to affect the creation + * @param {string|Zone} [opts.zone='local'] - convert the time to this zone. Since the offset is always specified in the string itself, this has no effect on the interpretation of string, merely the zone the resulting DateTime is expressed in. + * @param {boolean} [opts.setZone=false] - override the zone with a fixed-offset zone specified in the string itself, if it specifies one + * @param {string} [opts.locale='system's locale'] - a locale to set on the resulting DateTime instance + * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance + * @param {string} opts.numberingSystem - the numbering system to set on the resulting DateTime instance + * @example DateTime.fromRFC2822('25 Nov 2016 13:23:12 GMT') + * @example DateTime.fromRFC2822('Fri, 25 Nov 2016 13:23:12 +0600') + * @example DateTime.fromRFC2822('25 Nov 2016 13:23 Z') + * @return {DateTime} + */ + static fromRFC2822(text, opts = {}) { + const [vals, parsedZone] = parseRFC2822Date(text); + return parseDataToDateTime(vals, parsedZone, opts, "RFC 2822", text); + } + /** + * Create a DateTime from an HTTP header date + * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 + * @param {string} text - the HTTP header date + * @param {Object} opts - options to affect the creation + * @param {string|Zone} [opts.zone='local'] - convert the time to this zone. Since HTTP dates are always in UTC, this has no effect on the interpretation of string, merely the zone the resulting DateTime is expressed in. + * @param {boolean} [opts.setZone=false] - override the zone with the fixed-offset zone specified in the string. For HTTP dates, this is always UTC, so this option is equivalent to setting the `zone` option to 'utc', but this option is included for consistency with similar methods. + * @param {string} [opts.locale='system's locale'] - a locale to set on the resulting DateTime instance + * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance + * @param {string} opts.numberingSystem - the numbering system to set on the resulting DateTime instance + * @example DateTime.fromHTTP('Sun, 06 Nov 1994 08:49:37 GMT') + * @example DateTime.fromHTTP('Sunday, 06-Nov-94 08:49:37 GMT') + * @example DateTime.fromHTTP('Sun Nov 6 08:49:37 1994') + * @return {DateTime} + */ + static fromHTTP(text, opts = {}) { + const [vals, parsedZone] = parseHTTPDate(text); + return parseDataToDateTime(vals, parsedZone, opts, "HTTP", opts); + } + /** + * Create a DateTime from an input string and format string. + * Defaults to en-US if no locale has been specified, regardless of the system's locale. For a table of tokens and their interpretations, see [here](https://moment.github.io/luxon/#/parsing?id=table-of-tokens). + * @param {string} text - the string to parse + * @param {string} fmt - the format the string is expected to be in (see the link below for the formats) + * @param {Object} opts - options to affect the creation + * @param {string|Zone} [opts.zone='local'] - use this zone if no offset is specified in the input string itself. Will also convert the DateTime to this zone + * @param {boolean} [opts.setZone=false] - override the zone with a zone specified in the string itself, if it specifies one + * @param {string} [opts.locale='en-US'] - a locale string to use when parsing. Will also set the DateTime to this locale + * @param {string} opts.numberingSystem - the numbering system to use when parsing. Will also set the resulting DateTime to this numbering system + * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance + * @return {DateTime} + */ + static fromFormat(text, fmt, opts = {}) { + if (isUndefined(text) || isUndefined(fmt)) { + throw new InvalidArgumentError("fromFormat requires an input string and a format"); + } + const { locale = null, numberingSystem = null } = opts, localeToUse = Locale.fromOpts({ + locale, + numberingSystem, + defaultToEN: true + }), [vals, parsedZone, specificOffset, invalid] = parseFromTokens(localeToUse, text, fmt); + if (invalid) { + return DateTime.invalid(invalid); + } else { + return parseDataToDateTime(vals, parsedZone, opts, `format ${fmt}`, text, specificOffset); + } + } + /** + * @deprecated use fromFormat instead + */ + static fromString(text, fmt, opts = {}) { + return DateTime.fromFormat(text, fmt, opts); + } + /** + * Create a DateTime from a SQL date, time, or datetime + * Defaults to en-US if no locale has been specified, regardless of the system's locale + * @param {string} text - the string to parse + * @param {Object} opts - options to affect the creation + * @param {string|Zone} [opts.zone='local'] - use this zone if no offset is specified in the input string itself. Will also convert the DateTime to this zone + * @param {boolean} [opts.setZone=false] - override the zone with a zone specified in the string itself, if it specifies one + * @param {string} [opts.locale='en-US'] - a locale string to use when parsing. Will also set the DateTime to this locale + * @param {string} opts.numberingSystem - the numbering system to use when parsing. Will also set the resulting DateTime to this numbering system + * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance + * @example DateTime.fromSQL('2017-05-15') + * @example DateTime.fromSQL('2017-05-15 09:12:34') + * @example DateTime.fromSQL('2017-05-15 09:12:34.342') + * @example DateTime.fromSQL('2017-05-15 09:12:34.342+06:00') + * @example DateTime.fromSQL('2017-05-15 09:12:34.342 America/Los_Angeles') + * @example DateTime.fromSQL('2017-05-15 09:12:34.342 America/Los_Angeles', { setZone: true }) + * @example DateTime.fromSQL('2017-05-15 09:12:34.342', { zone: 'America/Los_Angeles' }) + * @example DateTime.fromSQL('09:12:34.342') + * @return {DateTime} + */ + static fromSQL(text, opts = {}) { + const [vals, parsedZone] = parseSQL(text); + return parseDataToDateTime(vals, parsedZone, opts, "SQL", text); + } + /** + * Create an invalid DateTime. + * @param {string} reason - simple string of why this DateTime is invalid. Should not contain parameters or anything else data-dependent. + * @param {string} [explanation=null] - longer explanation, may include parameters and other useful debugging information + * @return {DateTime} + */ + static invalid(reason, explanation = null) { + if (!reason) { + throw new InvalidArgumentError("need to specify a reason the DateTime is invalid"); + } + const invalid = reason instanceof Invalid ? reason : new Invalid(reason, explanation); + if (Settings.throwOnInvalid) { + throw new InvalidDateTimeError(invalid); + } else { + return new DateTime({ invalid }); + } + } + /** + * Check if an object is an instance of DateTime. Works across context boundaries + * @param {object} o + * @return {boolean} + */ + static isDateTime(o) { + return o && o.isLuxonDateTime || false; + } + /** + * Produce the format string for a set of options + * @param formatOpts + * @param localeOpts + * @returns {string} + */ + static parseFormatForOpts(formatOpts, localeOpts = {}) { + const tokenList = formatOptsToTokens(formatOpts, Locale.fromObject(localeOpts)); + return !tokenList ? null : tokenList.map((t) => t ? t.val : null).join(""); + } + /** + * Produce the the fully expanded format token for the locale + * Does NOT quote characters, so quoted tokens will not round trip correctly + * @param fmt + * @param localeOpts + * @returns {string} + */ + static expandFormat(fmt, localeOpts = {}) { + const expanded = expandMacroTokens(Formatter.parseFormat(fmt), Locale.fromObject(localeOpts)); + return expanded.map((t) => t.val).join(""); + } + // INFO + /** + * Get the value of unit. + * @param {string} unit - a unit such as 'minute' or 'day' + * @example DateTime.local(2017, 7, 4).get('month'); //=> 7 + * @example DateTime.local(2017, 7, 4).get('day'); //=> 4 + * @return {number} + */ + get(unit) { + return this[unit]; + } + /** + * Returns whether the DateTime is valid. Invalid DateTimes occur when: + * * The DateTime was created from invalid calendar information, such as the 13th month or February 30 + * * The DateTime was created by an operation on another invalid date + * @type {boolean} + */ + get isValid() { + return this.invalid === null; + } + /** + * Returns an error code if this DateTime is invalid, or null if the DateTime is valid + * @type {string} + */ + get invalidReason() { + return this.invalid ? this.invalid.reason : null; + } + /** + * Returns an explanation of why this DateTime became invalid, or null if the DateTime is valid + * @type {string} + */ + get invalidExplanation() { + return this.invalid ? this.invalid.explanation : null; + } + /** + * Get the locale of a DateTime, such 'en-GB'. The locale is used when formatting the DateTime + * + * @type {string} + */ + get locale() { + return this.isValid ? this.loc.locale : null; + } + /** + * Get the numbering system of a DateTime, such 'beng'. The numbering system is used when formatting the DateTime + * + * @type {string} + */ + get numberingSystem() { + return this.isValid ? this.loc.numberingSystem : null; + } + /** + * Get the output calendar of a DateTime, such 'islamic'. The output calendar is used when formatting the DateTime + * + * @type {string} + */ + get outputCalendar() { + return this.isValid ? this.loc.outputCalendar : null; + } + /** + * Get the time zone associated with this DateTime. + * @type {Zone} + */ + get zone() { + return this._zone; + } + /** + * Get the name of the time zone. + * @type {string} + */ + get zoneName() { + return this.isValid ? this.zone.name : null; + } + /** + * Get the year + * @example DateTime.local(2017, 5, 25).year //=> 2017 + * @type {number} + */ + get year() { + return this.isValid ? this.c.year : NaN; + } + /** + * Get the quarter + * @example DateTime.local(2017, 5, 25).quarter //=> 2 + * @type {number} + */ + get quarter() { + return this.isValid ? Math.ceil(this.c.month / 3) : NaN; + } + /** + * Get the month (1-12). + * @example DateTime.local(2017, 5, 25).month //=> 5 + * @type {number} + */ + get month() { + return this.isValid ? this.c.month : NaN; + } + /** + * Get the day of the month (1-30ish). + * @example DateTime.local(2017, 5, 25).day //=> 25 + * @type {number} + */ + get day() { + return this.isValid ? this.c.day : NaN; + } + /** + * Get the hour of the day (0-23). + * @example DateTime.local(2017, 5, 25, 9).hour //=> 9 + * @type {number} + */ + get hour() { + return this.isValid ? this.c.hour : NaN; + } + /** + * Get the minute of the hour (0-59). + * @example DateTime.local(2017, 5, 25, 9, 30).minute //=> 30 + * @type {number} + */ + get minute() { + return this.isValid ? this.c.minute : NaN; + } + /** + * Get the second of the minute (0-59). + * @example DateTime.local(2017, 5, 25, 9, 30, 52).second //=> 52 + * @type {number} + */ + get second() { + return this.isValid ? this.c.second : NaN; + } + /** + * Get the millisecond of the second (0-999). + * @example DateTime.local(2017, 5, 25, 9, 30, 52, 654).millisecond //=> 654 + * @type {number} + */ + get millisecond() { + return this.isValid ? this.c.millisecond : NaN; + } + /** + * Get the week year + * @see https://en.wikipedia.org/wiki/ISO_week_date + * @example DateTime.local(2014, 12, 31).weekYear //=> 2015 + * @type {number} + */ + get weekYear() { + return this.isValid ? possiblyCachedWeekData(this).weekYear : NaN; + } + /** + * Get the week number of the week year (1-52ish). + * @see https://en.wikipedia.org/wiki/ISO_week_date + * @example DateTime.local(2017, 5, 25).weekNumber //=> 21 + * @type {number} + */ + get weekNumber() { + return this.isValid ? possiblyCachedWeekData(this).weekNumber : NaN; + } + /** + * Get the day of the week. + * 1 is Monday and 7 is Sunday + * @see https://en.wikipedia.org/wiki/ISO_week_date + * @example DateTime.local(2014, 11, 31).weekday //=> 4 + * @type {number} + */ + get weekday() { + return this.isValid ? possiblyCachedWeekData(this).weekday : NaN; + } + /** + * Returns true if this date is on a weekend according to the locale, false otherwise + * @returns {boolean} + */ + get isWeekend() { + return this.isValid && this.loc.getWeekendDays().includes(this.weekday); + } + /** + * Get the day of the week according to the locale. + * 1 is the first day of the week and 7 is the last day of the week. + * If the locale assigns Sunday as the first day of the week, then a date which is a Sunday will return 1, + * @returns {number} + */ + get localWeekday() { + return this.isValid ? possiblyCachedLocalWeekData(this).weekday : NaN; + } + /** + * Get the week number of the week year according to the locale. Different locales assign week numbers differently, + * because the week can start on different days of the week (see localWeekday) and because a different number of days + * is required for a week to count as the first week of a year. + * @returns {number} + */ + get localWeekNumber() { + return this.isValid ? possiblyCachedLocalWeekData(this).weekNumber : NaN; + } + /** + * Get the week year according to the locale. Different locales assign week numbers (and therefor week years) + * differently, see localWeekNumber. + * @returns {number} + */ + get localWeekYear() { + return this.isValid ? possiblyCachedLocalWeekData(this).weekYear : NaN; + } + /** + * Get the ordinal (meaning the day of the year) + * @example DateTime.local(2017, 5, 25).ordinal //=> 145 + * @type {number|DateTime} + */ + get ordinal() { + return this.isValid ? gregorianToOrdinal(this.c).ordinal : NaN; + } + /** + * Get the human readable short month name, such as 'Oct'. + * Defaults to the system's locale if no locale has been specified + * @example DateTime.local(2017, 10, 30).monthShort //=> Oct + * @type {string} + */ + get monthShort() { + return this.isValid ? Info.months("short", { locObj: this.loc })[this.month - 1] : null; + } + /** + * Get the human readable long month name, such as 'October'. + * Defaults to the system's locale if no locale has been specified + * @example DateTime.local(2017, 10, 30).monthLong //=> October + * @type {string} + */ + get monthLong() { + return this.isValid ? Info.months("long", { locObj: this.loc })[this.month - 1] : null; + } + /** + * Get the human readable short weekday, such as 'Mon'. + * Defaults to the system's locale if no locale has been specified + * @example DateTime.local(2017, 10, 30).weekdayShort //=> Mon + * @type {string} + */ + get weekdayShort() { + return this.isValid ? Info.weekdays("short", { locObj: this.loc })[this.weekday - 1] : null; + } + /** + * Get the human readable long weekday, such as 'Monday'. + * Defaults to the system's locale if no locale has been specified + * @example DateTime.local(2017, 10, 30).weekdayLong //=> Monday + * @type {string} + */ + get weekdayLong() { + return this.isValid ? Info.weekdays("long", { locObj: this.loc })[this.weekday - 1] : null; + } + /** + * Get the UTC offset of this DateTime in minutes + * @example DateTime.now().offset //=> -240 + * @example DateTime.utc().offset //=> 0 + * @type {number} + */ + get offset() { + return this.isValid ? +this.o : NaN; + } + /** + * Get the short human name for the zone's current offset, for example "EST" or "EDT". + * Defaults to the system's locale if no locale has been specified + * @type {string} + */ + get offsetNameShort() { + if (this.isValid) { + return this.zone.offsetName(this.ts, { + format: "short", + locale: this.locale + }); + } else { + return null; + } + } + /** + * Get the long human name for the zone's current offset, for example "Eastern Standard Time" or "Eastern Daylight Time". + * Defaults to the system's locale if no locale has been specified + * @type {string} + */ + get offsetNameLong() { + if (this.isValid) { + return this.zone.offsetName(this.ts, { + format: "long", + locale: this.locale + }); + } else { + return null; + } + } + /** + * Get whether this zone's offset ever changes, as in a DST. + * @type {boolean} + */ + get isOffsetFixed() { + return this.isValid ? this.zone.isUniversal : null; + } + /** + * Get whether the DateTime is in a DST. + * @type {boolean} + */ + get isInDST() { + if (this.isOffsetFixed) { + return false; + } else { + return this.offset > this.set({ month: 1, day: 1 }).offset || this.offset > this.set({ month: 5 }).offset; + } + } + /** + * Get those DateTimes which have the same local time as this DateTime, but a different offset from UTC + * in this DateTime's zone. During DST changes local time can be ambiguous, for example + * `2023-10-29T02:30:00` in `Europe/Berlin` can have offset `+01:00` or `+02:00`. + * This method will return both possible DateTimes if this DateTime's local time is ambiguous. + * @returns {DateTime[]} + */ + getPossibleOffsets() { + if (!this.isValid || this.isOffsetFixed) { + return [this]; + } + const dayMs = 864e5; + const minuteMs = 6e4; + const localTS = objToLocalTS(this.c); + const oEarlier = this.zone.offset(localTS - dayMs); + const oLater = this.zone.offset(localTS + dayMs); + const o1 = this.zone.offset(localTS - oEarlier * minuteMs); + const o2 = this.zone.offset(localTS - oLater * minuteMs); + if (o1 === o2) { + return [this]; + } + const ts1 = localTS - o1 * minuteMs; + const ts2 = localTS - o2 * minuteMs; + const c1 = tsToObj(ts1, o1); + const c2 = tsToObj(ts2, o2); + if (c1.hour === c2.hour && c1.minute === c2.minute && c1.second === c2.second && c1.millisecond === c2.millisecond) { + return [clone6(this, { ts: ts1 }), clone6(this, { ts: ts2 })]; + } + return [this]; + } + /** + * Returns true if this DateTime is in a leap year, false otherwise + * @example DateTime.local(2016).isInLeapYear //=> true + * @example DateTime.local(2013).isInLeapYear //=> false + * @type {boolean} + */ + get isInLeapYear() { + return isLeapYear(this.year); + } + /** + * Returns the number of days in this DateTime's month + * @example DateTime.local(2016, 2).daysInMonth //=> 29 + * @example DateTime.local(2016, 3).daysInMonth //=> 31 + * @type {number} + */ + get daysInMonth() { + return daysInMonth(this.year, this.month); + } + /** + * Returns the number of days in this DateTime's year + * @example DateTime.local(2016).daysInYear //=> 366 + * @example DateTime.local(2013).daysInYear //=> 365 + * @type {number} + */ + get daysInYear() { + return this.isValid ? daysInYear(this.year) : NaN; + } + /** + * Returns the number of weeks in this DateTime's year + * @see https://en.wikipedia.org/wiki/ISO_week_date + * @example DateTime.local(2004).weeksInWeekYear //=> 53 + * @example DateTime.local(2013).weeksInWeekYear //=> 52 + * @type {number} + */ + get weeksInWeekYear() { + return this.isValid ? weeksInWeekYear(this.weekYear) : NaN; + } + /** + * Returns the number of weeks in this DateTime's local week year + * @example DateTime.local(2020, 6, {locale: 'en-US'}).weeksInLocalWeekYear //=> 52 + * @example DateTime.local(2020, 6, {locale: 'de-DE'}).weeksInLocalWeekYear //=> 53 + * @type {number} + */ + get weeksInLocalWeekYear() { + return this.isValid ? weeksInWeekYear( + this.localWeekYear, + this.loc.getMinDaysInFirstWeek(), + this.loc.getStartOfWeek() + ) : NaN; + } + /** + * Returns the resolved Intl options for this DateTime. + * This is useful in understanding the behavior of formatting methods + * @param {Object} opts - the same options as toLocaleString + * @return {Object} + */ + resolvedLocaleOptions(opts = {}) { + const { locale, numberingSystem, calendar } = Formatter.create( + this.loc.clone(opts), + opts + ).resolvedOptions(this); + return { locale, numberingSystem, outputCalendar: calendar }; + } + // TRANSFORM + /** + * "Set" the DateTime's zone to UTC. Returns a newly-constructed DateTime. + * + * Equivalent to {@link DateTime#setZone}('utc') + * @param {number} [offset=0] - optionally, an offset from UTC in minutes + * @param {Object} [opts={}] - options to pass to `setZone()` + * @return {DateTime} + */ + toUTC(offset2 = 0, opts = {}) { + return this.setZone(FixedOffsetZone.instance(offset2), opts); + } + /** + * "Set" the DateTime's zone to the host's local zone. Returns a newly-constructed DateTime. + * + * Equivalent to `setZone('local')` + * @return {DateTime} + */ + toLocal() { + return this.setZone(Settings.defaultZone); + } + /** + * "Set" the DateTime's zone to specified zone. Returns a newly-constructed DateTime. + * + * By default, the setter keeps the underlying time the same (as in, the same timestamp), but the new instance will report different local times and consider DSTs when making computations, as with {@link DateTime#plus}. You may wish to use {@link DateTime#toLocal} and {@link DateTime#toUTC} which provide simple convenience wrappers for commonly used zones. + * @param {string|Zone} [zone='local'] - a zone identifier. As a string, that can be any IANA zone supported by the host environment, or a fixed-offset name of the form 'UTC+3', or the strings 'local' or 'utc'. You may also supply an instance of a {@link DateTime#Zone} class. + * @param {Object} opts - options + * @param {boolean} [opts.keepLocalTime=false] - If true, adjust the underlying time so that the local time stays the same, but in the target zone. You should rarely need this. + * @return {DateTime} + */ + setZone(zone, { keepLocalTime = false, keepCalendarTime = false } = {}) { + zone = normalizeZone(zone, Settings.defaultZone); + if (zone.equals(this.zone)) { + return this; + } else if (!zone.isValid) { + return DateTime.invalid(unsupportedZone(zone)); + } else { + let newTS = this.ts; + if (keepLocalTime || keepCalendarTime) { + const offsetGuess = zone.offset(this.ts); + const asObj = this.toObject(); + [newTS] = objToTS(asObj, offsetGuess, zone); + } + return clone6(this, { ts: newTS, zone }); + } + } + /** + * "Set" the locale, numberingSystem, or outputCalendar. Returns a newly-constructed DateTime. + * @param {Object} properties - the properties to set + * @example DateTime.local(2017, 5, 25).reconfigure({ locale: 'en-GB' }) + * @return {DateTime} + */ + reconfigure({ locale, numberingSystem, outputCalendar } = {}) { + const loc = this.loc.clone({ locale, numberingSystem, outputCalendar }); + return clone6(this, { loc }); + } + /** + * "Set" the locale. Returns a newly-constructed DateTime. + * Just a convenient alias for reconfigure({ locale }) + * @example DateTime.local(2017, 5, 25).setLocale('en-GB') + * @return {DateTime} + */ + setLocale(locale) { + return this.reconfigure({ locale }); + } + /** + * "Set" the values of specified units. Returns a newly-constructed DateTime. + * You can only set units with this method; for "setting" metadata, see {@link DateTime#reconfigure} and {@link DateTime#setZone}. + * + * This method also supports setting locale-based week units, i.e. `localWeekday`, `localWeekNumber` and `localWeekYear`. + * They cannot be mixed with ISO-week units like `weekday`. + * @param {Object} values - a mapping of units to numbers + * @example dt.set({ year: 2017 }) + * @example dt.set({ hour: 8, minute: 30 }) + * @example dt.set({ weekday: 5 }) + * @example dt.set({ year: 2005, ordinal: 234 }) + * @return {DateTime} + */ + set(values) { + if (!this.isValid) + return this; + const normalized = normalizeObject(values, normalizeUnitWithLocalWeeks); + const { minDaysInFirstWeek, startOfWeek } = usesLocalWeekValues(normalized, this.loc); + const settingWeekStuff = !isUndefined(normalized.weekYear) || !isUndefined(normalized.weekNumber) || !isUndefined(normalized.weekday), containsOrdinal = !isUndefined(normalized.ordinal), containsGregorYear = !isUndefined(normalized.year), containsGregorMD = !isUndefined(normalized.month) || !isUndefined(normalized.day), containsGregor = containsGregorYear || containsGregorMD, definiteWeekDef = normalized.weekYear || normalized.weekNumber; + if ((containsGregor || containsOrdinal) && definiteWeekDef) { + throw new ConflictingSpecificationError( + "Can't mix weekYear/weekNumber units with year/month/day or ordinals" + ); + } + if (containsGregorMD && containsOrdinal) { + throw new ConflictingSpecificationError("Can't mix ordinal dates with month/day"); + } + let mixed; + if (settingWeekStuff) { + mixed = weekToGregorian( + { ...gregorianToWeek(this.c, minDaysInFirstWeek, startOfWeek), ...normalized }, + minDaysInFirstWeek, + startOfWeek + ); + } else if (!isUndefined(normalized.ordinal)) { + mixed = ordinalToGregorian({ ...gregorianToOrdinal(this.c), ...normalized }); + } else { + mixed = { ...this.toObject(), ...normalized }; + if (isUndefined(normalized.day)) { + mixed.day = Math.min(daysInMonth(mixed.year, mixed.month), mixed.day); + } + } + const [ts, o] = objToTS(mixed, this.o, this.zone); + return clone6(this, { ts, o }); + } + /** + * Add a period of time to this DateTime and return the resulting DateTime + * + * Adding hours, minutes, seconds, or milliseconds increases the timestamp by the right number of milliseconds. Adding days, months, or years shifts the calendar, accounting for DSTs and leap years along the way. Thus, `dt.plus({ hours: 24 })` may result in a different time than `dt.plus({ days: 1 })` if there's a DST shift in between. + * @param {Duration|Object|number} duration - The amount to add. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject() + * @example DateTime.now().plus(123) //~> in 123 milliseconds + * @example DateTime.now().plus({ minutes: 15 }) //~> in 15 minutes + * @example DateTime.now().plus({ days: 1 }) //~> this time tomorrow + * @example DateTime.now().plus({ days: -1 }) //~> this time yesterday + * @example DateTime.now().plus({ hours: 3, minutes: 13 }) //~> in 3 hr, 13 min + * @example DateTime.now().plus(Duration.fromObject({ hours: 3, minutes: 13 })) //~> in 3 hr, 13 min + * @return {DateTime} + */ + plus(duration) { + if (!this.isValid) + return this; + const dur = Duration.fromDurationLike(duration); + return clone6(this, adjustTime(this, dur)); + } + /** + * Subtract a period of time to this DateTime and return the resulting DateTime + * See {@link DateTime#plus} + * @param {Duration|Object|number} duration - The amount to subtract. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject() + @return {DateTime} + */ + minus(duration) { + if (!this.isValid) + return this; + const dur = Duration.fromDurationLike(duration).negate(); + return clone6(this, adjustTime(this, dur)); + } + /** + * "Set" this DateTime to the beginning of a unit of time. + * @param {string} unit - The unit to go to the beginning of. Can be 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', or 'millisecond'. + * @param {Object} opts - options + * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week + * @example DateTime.local(2014, 3, 3).startOf('month').toISODate(); //=> '2014-03-01' + * @example DateTime.local(2014, 3, 3).startOf('year').toISODate(); //=> '2014-01-01' + * @example DateTime.local(2014, 3, 3).startOf('week').toISODate(); //=> '2014-03-03', weeks always start on Mondays + * @example DateTime.local(2014, 3, 3, 5, 30).startOf('day').toISOTime(); //=> '00:00.000-05:00' + * @example DateTime.local(2014, 3, 3, 5, 30).startOf('hour').toISOTime(); //=> '05:00:00.000-05:00' + * @return {DateTime} + */ + startOf(unit, { useLocaleWeeks = false } = {}) { + if (!this.isValid) + return this; + const o = {}, normalizedUnit = Duration.normalizeUnit(unit); + switch (normalizedUnit) { + case "years": + o.month = 1; + case "quarters": + case "months": + o.day = 1; + case "weeks": + case "days": + o.hour = 0; + case "hours": + o.minute = 0; + case "minutes": + o.second = 0; + case "seconds": + o.millisecond = 0; + break; + case "milliseconds": + break; + } + if (normalizedUnit === "weeks") { + if (useLocaleWeeks) { + const startOfWeek = this.loc.getStartOfWeek(); + const { weekday } = this; + if (weekday < startOfWeek) { + o.weekNumber = this.weekNumber - 1; + } + o.weekday = startOfWeek; + } else { + o.weekday = 1; + } + } + if (normalizedUnit === "quarters") { + const q = Math.ceil(this.month / 3); + o.month = (q - 1) * 3 + 1; + } + return this.set(o); + } + /** + * "Set" this DateTime to the end (meaning the last millisecond) of a unit of time + * @param {string} unit - The unit to go to the end of. Can be 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', or 'millisecond'. + * @param {Object} opts - options + * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week + * @example DateTime.local(2014, 3, 3).endOf('month').toISO(); //=> '2014-03-31T23:59:59.999-05:00' + * @example DateTime.local(2014, 3, 3).endOf('year').toISO(); //=> '2014-12-31T23:59:59.999-05:00' + * @example DateTime.local(2014, 3, 3).endOf('week').toISO(); // => '2014-03-09T23:59:59.999-05:00', weeks start on Mondays + * @example DateTime.local(2014, 3, 3, 5, 30).endOf('day').toISO(); //=> '2014-03-03T23:59:59.999-05:00' + * @example DateTime.local(2014, 3, 3, 5, 30).endOf('hour').toISO(); //=> '2014-03-03T05:59:59.999-05:00' + * @return {DateTime} + */ + endOf(unit, opts) { + return this.isValid ? this.plus({ [unit]: 1 }).startOf(unit, opts).minus(1) : this; + } + // OUTPUT + /** + * Returns a string representation of this DateTime formatted according to the specified format string. + * **You may not want this.** See {@link DateTime#toLocaleString} for a more flexible formatting tool. For a table of tokens and their interpretations, see [here](https://moment.github.io/luxon/#/formatting?id=table-of-tokens). + * Defaults to en-US if no locale has been specified, regardless of the system's locale. + * @param {string} fmt - the format string + * @param {Object} opts - opts to override the configuration options on this DateTime + * @example DateTime.now().toFormat('yyyy LLL dd') //=> '2017 Apr 22' + * @example DateTime.now().setLocale('fr').toFormat('yyyy LLL dd') //=> '2017 avr. 22' + * @example DateTime.now().toFormat('yyyy LLL dd', { locale: "fr" }) //=> '2017 avr. 22' + * @example DateTime.now().toFormat("HH 'hours and' mm 'minutes'") //=> '20 hours and 55 minutes' + * @return {string} + */ + toFormat(fmt, opts = {}) { + return this.isValid ? Formatter.create(this.loc.redefaultToEN(opts)).formatDateTimeFromString(this, fmt) : INVALID3; + } + /** + * Returns a localized string representing this date. Accepts the same options as the Intl.DateTimeFormat constructor and any presets defined by Luxon, such as `DateTime.DATE_FULL` or `DateTime.TIME_SIMPLE`. + * The exact behavior of this method is browser-specific, but in general it will return an appropriate representation + * of the DateTime in the assigned locale. + * Defaults to the system's locale if no locale has been specified + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat + * @param formatOpts {Object} - Intl.DateTimeFormat constructor options and configuration options + * @param {Object} opts - opts to override the configuration options on this DateTime + * @example DateTime.now().toLocaleString(); //=> 4/20/2017 + * @example DateTime.now().setLocale('en-gb').toLocaleString(); //=> '20/04/2017' + * @example DateTime.now().toLocaleString(DateTime.DATE_FULL); //=> 'April 20, 2017' + * @example DateTime.now().toLocaleString(DateTime.DATE_FULL, { locale: 'fr' }); //=> '28 août 2022' + * @example DateTime.now().toLocaleString(DateTime.TIME_SIMPLE); //=> '11:32 AM' + * @example DateTime.now().toLocaleString(DateTime.DATETIME_SHORT); //=> '4/20/2017, 11:32 AM' + * @example DateTime.now().toLocaleString({ weekday: 'long', month: 'long', day: '2-digit' }); //=> 'Thursday, April 20' + * @example DateTime.now().toLocaleString({ weekday: 'short', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }); //=> 'Thu, Apr 20, 11:27 AM' + * @example DateTime.now().toLocaleString({ hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }); //=> '11:32' + * @return {string} + */ + toLocaleString(formatOpts = DATE_SHORT, opts = {}) { + return this.isValid ? Formatter.create(this.loc.clone(opts), formatOpts).formatDateTime(this) : INVALID3; + } + /** + * Returns an array of format "parts", meaning individual tokens along with metadata. This is allows callers to post-process individual sections of the formatted output. + * Defaults to the system's locale if no locale has been specified + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/formatToParts + * @param opts {Object} - Intl.DateTimeFormat constructor options, same as `toLocaleString`. + * @example DateTime.now().toLocaleParts(); //=> [ + * //=> { type: 'day', value: '25' }, + * //=> { type: 'literal', value: '/' }, + * //=> { type: 'month', value: '05' }, + * //=> { type: 'literal', value: '/' }, + * //=> { type: 'year', value: '1982' } + * //=> ] + */ + toLocaleParts(opts = {}) { + return this.isValid ? Formatter.create(this.loc.clone(opts), opts).formatDateTimeParts(this) : []; + } + /** + * Returns an ISO 8601-compliant string representation of this DateTime + * @param {Object} opts - options + * @param {boolean} [opts.suppressMilliseconds=false] - exclude milliseconds from the format if they're 0 + * @param {boolean} [opts.suppressSeconds=false] - exclude seconds from the format if they're 0 + * @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00' + * @param {boolean} [opts.extendedZone=false] - add the time zone format extension + * @param {string} [opts.format='extended'] - choose between the basic and extended format + * @example DateTime.utc(1983, 5, 25).toISO() //=> '1982-05-25T00:00:00.000Z' + * @example DateTime.now().toISO() //=> '2017-04-22T20:47:05.335-04:00' + * @example DateTime.now().toISO({ includeOffset: false }) //=> '2017-04-22T20:47:05.335' + * @example DateTime.now().toISO({ format: 'basic' }) //=> '20170422T204705.335-0400' + * @return {string} + */ + toISO({ + format = "extended", + suppressSeconds = false, + suppressMilliseconds = false, + includeOffset = true, + extendedZone = false + } = {}) { + if (!this.isValid) { + return null; + } + const ext = format === "extended"; + let c = toISODate(this, ext); + c += "T"; + c += toISOTime(this, ext, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone); + return c; + } + /** + * Returns an ISO 8601-compliant string representation of this DateTime's date component + * @param {Object} opts - options + * @param {string} [opts.format='extended'] - choose between the basic and extended format + * @example DateTime.utc(1982, 5, 25).toISODate() //=> '1982-05-25' + * @example DateTime.utc(1982, 5, 25).toISODate({ format: 'basic' }) //=> '19820525' + * @return {string} + */ + toISODate({ format = "extended" } = {}) { + if (!this.isValid) { + return null; + } + return toISODate(this, format === "extended"); + } + /** + * Returns an ISO 8601-compliant string representation of this DateTime's week date + * @example DateTime.utc(1982, 5, 25).toISOWeekDate() //=> '1982-W21-2' + * @return {string} + */ + toISOWeekDate() { + return toTechFormat(this, "kkkk-'W'WW-c"); + } + /** + * Returns an ISO 8601-compliant string representation of this DateTime's time component + * @param {Object} opts - options + * @param {boolean} [opts.suppressMilliseconds=false] - exclude milliseconds from the format if they're 0 + * @param {boolean} [opts.suppressSeconds=false] - exclude seconds from the format if they're 0 + * @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00' + * @param {boolean} [opts.extendedZone=true] - add the time zone format extension + * @param {boolean} [opts.includePrefix=false] - include the `T` prefix + * @param {string} [opts.format='extended'] - choose between the basic and extended format + * @example DateTime.utc().set({ hour: 7, minute: 34 }).toISOTime() //=> '07:34:19.361Z' + * @example DateTime.utc().set({ hour: 7, minute: 34, seconds: 0, milliseconds: 0 }).toISOTime({ suppressSeconds: true }) //=> '07:34Z' + * @example DateTime.utc().set({ hour: 7, minute: 34 }).toISOTime({ format: 'basic' }) //=> '073419.361Z' + * @example DateTime.utc().set({ hour: 7, minute: 34 }).toISOTime({ includePrefix: true }) //=> 'T07:34:19.361Z' + * @return {string} + */ + toISOTime({ + suppressMilliseconds = false, + suppressSeconds = false, + includeOffset = true, + includePrefix = false, + extendedZone = false, + format = "extended" + } = {}) { + if (!this.isValid) { + return null; + } + let c = includePrefix ? "T" : ""; + return c + toISOTime( + this, + format === "extended", + suppressSeconds, + suppressMilliseconds, + includeOffset, + extendedZone + ); + } + /** + * Returns an RFC 2822-compatible string representation of this DateTime + * @example DateTime.utc(2014, 7, 13).toRFC2822() //=> 'Sun, 13 Jul 2014 00:00:00 +0000' + * @example DateTime.local(2014, 7, 13).toRFC2822() //=> 'Sun, 13 Jul 2014 00:00:00 -0400' + * @return {string} + */ + toRFC2822() { + return toTechFormat(this, "EEE, dd LLL yyyy HH:mm:ss ZZZ", false); + } + /** + * Returns a string representation of this DateTime appropriate for use in HTTP headers. The output is always expressed in GMT. + * Specifically, the string conforms to RFC 1123. + * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 + * @example DateTime.utc(2014, 7, 13).toHTTP() //=> 'Sun, 13 Jul 2014 00:00:00 GMT' + * @example DateTime.utc(2014, 7, 13, 19).toHTTP() //=> 'Sun, 13 Jul 2014 19:00:00 GMT' + * @return {string} + */ + toHTTP() { + return toTechFormat(this.toUTC(), "EEE, dd LLL yyyy HH:mm:ss 'GMT'"); + } + /** + * Returns a string representation of this DateTime appropriate for use in SQL Date + * @example DateTime.utc(2014, 7, 13).toSQLDate() //=> '2014-07-13' + * @return {string} + */ + toSQLDate() { + if (!this.isValid) { + return null; + } + return toISODate(this, true); + } + /** + * Returns a string representation of this DateTime appropriate for use in SQL Time + * @param {Object} opts - options + * @param {boolean} [opts.includeZone=false] - include the zone, such as 'America/New_York'. Overrides includeOffset. + * @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00' + * @param {boolean} [opts.includeOffsetSpace=true] - include the space between the time and the offset, such as '05:15:16.345 -04:00' + * @example DateTime.utc().toSQL() //=> '05:15:16.345' + * @example DateTime.now().toSQL() //=> '05:15:16.345 -04:00' + * @example DateTime.now().toSQL({ includeOffset: false }) //=> '05:15:16.345' + * @example DateTime.now().toSQL({ includeZone: false }) //=> '05:15:16.345 America/New_York' + * @return {string} + */ + toSQLTime({ includeOffset = true, includeZone = false, includeOffsetSpace = true } = {}) { + let fmt = "HH:mm:ss.SSS"; + if (includeZone || includeOffset) { + if (includeOffsetSpace) { + fmt += " "; + } + if (includeZone) { + fmt += "z"; + } else if (includeOffset) { + fmt += "ZZ"; + } + } + return toTechFormat(this, fmt, true); + } + /** + * Returns a string representation of this DateTime appropriate for use in SQL DateTime + * @param {Object} opts - options + * @param {boolean} [opts.includeZone=false] - include the zone, such as 'America/New_York'. Overrides includeOffset. + * @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00' + * @param {boolean} [opts.includeOffsetSpace=true] - include the space between the time and the offset, such as '05:15:16.345 -04:00' + * @example DateTime.utc(2014, 7, 13).toSQL() //=> '2014-07-13 00:00:00.000 Z' + * @example DateTime.local(2014, 7, 13).toSQL() //=> '2014-07-13 00:00:00.000 -04:00' + * @example DateTime.local(2014, 7, 13).toSQL({ includeOffset: false }) //=> '2014-07-13 00:00:00.000' + * @example DateTime.local(2014, 7, 13).toSQL({ includeZone: true }) //=> '2014-07-13 00:00:00.000 America/New_York' + * @return {string} + */ + toSQL(opts = {}) { + if (!this.isValid) { + return null; + } + return `${this.toSQLDate()} ${this.toSQLTime(opts)}`; + } + /** + * Returns a string representation of this DateTime appropriate for debugging + * @return {string} + */ + toString() { + return this.isValid ? this.toISO() : INVALID3; + } + /** + * Returns a string representation of this DateTime appropriate for the REPL. + * @return {string} + */ + [Symbol.for("nodejs.util.inspect.custom")]() { + if (this.isValid) { + return `DateTime { ts: ${this.toISO()}, zone: ${this.zone.name}, locale: ${this.locale} }`; + } else { + return `DateTime { Invalid, reason: ${this.invalidReason} }`; + } + } + /** + * Returns the epoch milliseconds of this DateTime. Alias of {@link DateTime#toMillis} + * @return {number} + */ + valueOf() { + return this.toMillis(); + } + /** + * Returns the epoch milliseconds of this DateTime. + * @return {number} + */ + toMillis() { + return this.isValid ? this.ts : NaN; + } + /** + * Returns the epoch seconds of this DateTime. + * @return {number} + */ + toSeconds() { + return this.isValid ? this.ts / 1e3 : NaN; + } + /** + * Returns the epoch seconds (as a whole number) of this DateTime. + * @return {number} + */ + toUnixInteger() { + return this.isValid ? Math.floor(this.ts / 1e3) : NaN; + } + /** + * Returns an ISO 8601 representation of this DateTime appropriate for use in JSON. + * @return {string} + */ + toJSON() { + return this.toISO(); + } + /** + * Returns a BSON serializable equivalent to this DateTime. + * @return {Date} + */ + toBSON() { + return this.toJSDate(); + } + /** + * Returns a JavaScript object with this DateTime's year, month, day, and so on. + * @param opts - options for generating the object + * @param {boolean} [opts.includeConfig=false] - include configuration attributes in the output + * @example DateTime.now().toObject() //=> { year: 2017, month: 4, day: 22, hour: 20, minute: 49, second: 42, millisecond: 268 } + * @return {Object} + */ + toObject(opts = {}) { + if (!this.isValid) + return {}; + const base = { ...this.c }; + if (opts.includeConfig) { + base.outputCalendar = this.outputCalendar; + base.numberingSystem = this.loc.numberingSystem; + base.locale = this.loc.locale; + } + return base; + } + /** + * Returns a JavaScript Date equivalent to this DateTime. + * @return {Date} + */ + toJSDate() { + return new Date(this.isValid ? this.ts : NaN); + } + // COMPARE + /** + * Return the difference between two DateTimes as a Duration. + * @param {DateTime} otherDateTime - the DateTime to compare this one to + * @param {string|string[]} [unit=['milliseconds']] - the unit or array of units (such as 'hours' or 'days') to include in the duration. + * @param {Object} opts - options that affect the creation of the Duration + * @param {string} [opts.conversionAccuracy='casual'] - the conversion system to use + * @example + * var i1 = DateTime.fromISO('1982-05-25T09:45'), + * i2 = DateTime.fromISO('1983-10-14T10:30'); + * i2.diff(i1).toObject() //=> { milliseconds: 43807500000 } + * i2.diff(i1, 'hours').toObject() //=> { hours: 12168.75 } + * i2.diff(i1, ['months', 'days']).toObject() //=> { months: 16, days: 19.03125 } + * i2.diff(i1, ['months', 'days', 'hours']).toObject() //=> { months: 16, days: 19, hours: 0.75 } + * @return {Duration} + */ + diff(otherDateTime, unit = "milliseconds", opts = {}) { + if (!this.isValid || !otherDateTime.isValid) { + return Duration.invalid("created by diffing an invalid DateTime"); + } + const durOpts = { locale: this.locale, numberingSystem: this.numberingSystem, ...opts }; + const units = maybeArray(unit).map(Duration.normalizeUnit), otherIsLater = otherDateTime.valueOf() > this.valueOf(), earlier = otherIsLater ? this : otherDateTime, later = otherIsLater ? otherDateTime : this, diffed = diff_default(earlier, later, units, durOpts); + return otherIsLater ? diffed.negate() : diffed; + } + /** + * Return the difference between this DateTime and right now. + * See {@link DateTime#diff} + * @param {string|string[]} [unit=['milliseconds']] - the unit or units units (such as 'hours' or 'days') to include in the duration + * @param {Object} opts - options that affect the creation of the Duration + * @param {string} [opts.conversionAccuracy='casual'] - the conversion system to use + * @return {Duration} + */ + diffNow(unit = "milliseconds", opts = {}) { + return this.diff(DateTime.now(), unit, opts); + } + /** + * Return an Interval spanning between this DateTime and another DateTime + * @param {DateTime} otherDateTime - the other end point of the Interval + * @return {Interval} + */ + until(otherDateTime) { + return this.isValid ? Interval.fromDateTimes(this, otherDateTime) : this; + } + /** + * Return whether this DateTime is in the same unit of time as another DateTime. + * Higher-order units must also be identical for this function to return `true`. + * Note that time zones are **ignored** in this comparison, which compares the **local** calendar time. Use {@link DateTime#setZone} to convert one of the dates if needed. + * @param {DateTime} otherDateTime - the other DateTime + * @param {string} unit - the unit of time to check sameness on + * @param {Object} opts - options + * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week; only the locale of this DateTime is used + * @example DateTime.now().hasSame(otherDT, 'day'); //~> true if otherDT is in the same current calendar day + * @return {boolean} + */ + hasSame(otherDateTime, unit, opts) { + if (!this.isValid) + return false; + const inputMs = otherDateTime.valueOf(); + const adjustedToZone = this.setZone(otherDateTime.zone, { keepLocalTime: true }); + return adjustedToZone.startOf(unit, opts) <= inputMs && inputMs <= adjustedToZone.endOf(unit, opts); + } + /** + * Equality check + * Two DateTimes are equal if and only if they represent the same millisecond, have the same zone and location, and are both valid. + * To compare just the millisecond values, use `+dt1 === +dt2`. + * @param {DateTime} other - the other DateTime + * @return {boolean} + */ + equals(other) { + return this.isValid && other.isValid && this.valueOf() === other.valueOf() && this.zone.equals(other.zone) && this.loc.equals(other.loc); + } + /** + * Returns a string representation of a this time relative to now, such as "in two days". Can only internationalize if your + * platform supports Intl.RelativeTimeFormat. Rounds down by default. + * @param {Object} options - options that affect the output + * @param {DateTime} [options.base=DateTime.now()] - the DateTime to use as the basis to which this time is compared. Defaults to now. + * @param {string} [options.style="long"] - the style of units, must be "long", "short", or "narrow" + * @param {string|string[]} options.unit - use a specific unit or array of units; if omitted, or an array, the method will pick the best unit. Use an array or one of "years", "quarters", "months", "weeks", "days", "hours", "minutes", or "seconds" + * @param {boolean} [options.round=true] - whether to round the numbers in the output. + * @param {number} [options.padding=0] - padding in milliseconds. This allows you to round up the result if it fits inside the threshold. Don't use in combination with {round: false} because the decimal output will include the padding. + * @param {string} options.locale - override the locale of this DateTime + * @param {string} options.numberingSystem - override the numberingSystem of this DateTime. The Intl system may choose not to honor this + * @example DateTime.now().plus({ days: 1 }).toRelative() //=> "in 1 day" + * @example DateTime.now().setLocale("es").toRelative({ days: 1 }) //=> "dentro de 1 día" + * @example DateTime.now().plus({ days: 1 }).toRelative({ locale: "fr" }) //=> "dans 23 heures" + * @example DateTime.now().minus({ days: 2 }).toRelative() //=> "2 days ago" + * @example DateTime.now().minus({ days: 2 }).toRelative({ unit: "hours" }) //=> "48 hours ago" + * @example DateTime.now().minus({ hours: 36 }).toRelative({ round: false }) //=> "1.5 days ago" + */ + toRelative(options = {}) { + if (!this.isValid) + return null; + const base = options.base || DateTime.fromObject({}, { zone: this.zone }), padding = options.padding ? this < base ? -options.padding : options.padding : 0; + let units = ["years", "months", "days", "hours", "minutes", "seconds"]; + let unit = options.unit; + if (Array.isArray(options.unit)) { + units = options.unit; + unit = void 0; + } + return diffRelative(base, this.plus(padding), { + ...options, + numeric: "always", + units, + unit + }); + } + /** + * Returns a string representation of this date relative to today, such as "yesterday" or "next month". + * Only internationalizes on platforms that supports Intl.RelativeTimeFormat. + * @param {Object} options - options that affect the output + * @param {DateTime} [options.base=DateTime.now()] - the DateTime to use as the basis to which this time is compared. Defaults to now. + * @param {string} options.locale - override the locale of this DateTime + * @param {string} options.unit - use a specific unit; if omitted, the method will pick the unit. Use one of "years", "quarters", "months", "weeks", or "days" + * @param {string} options.numberingSystem - override the numberingSystem of this DateTime. The Intl system may choose not to honor this + * @example DateTime.now().plus({ days: 1 }).toRelativeCalendar() //=> "tomorrow" + * @example DateTime.now().setLocale("es").plus({ days: 1 }).toRelative() //=> ""mañana" + * @example DateTime.now().plus({ days: 1 }).toRelativeCalendar({ locale: "fr" }) //=> "demain" + * @example DateTime.now().minus({ days: 2 }).toRelativeCalendar() //=> "2 days ago" + */ + toRelativeCalendar(options = {}) { + if (!this.isValid) + return null; + return diffRelative(options.base || DateTime.fromObject({}, { zone: this.zone }), this, { + ...options, + numeric: "auto", + units: ["years", "months", "days"], + calendary: true + }); + } + /** + * Return the min of several date times + * @param {...DateTime} dateTimes - the DateTimes from which to choose the minimum + * @return {DateTime} the min DateTime, or undefined if called with no argument + */ + static min(...dateTimes) { + if (!dateTimes.every(DateTime.isDateTime)) { + throw new InvalidArgumentError("min requires all arguments be DateTimes"); + } + return bestBy(dateTimes, (i) => i.valueOf(), Math.min); + } + /** + * Return the max of several date times + * @param {...DateTime} dateTimes - the DateTimes from which to choose the maximum + * @return {DateTime} the max DateTime, or undefined if called with no argument + */ + static max(...dateTimes) { + if (!dateTimes.every(DateTime.isDateTime)) { + throw new InvalidArgumentError("max requires all arguments be DateTimes"); + } + return bestBy(dateTimes, (i) => i.valueOf(), Math.max); + } + // MISC + /** + * Explain how a string would be parsed by fromFormat() + * @param {string} text - the string to parse + * @param {string} fmt - the format the string is expected to be in (see description) + * @param {Object} options - options taken by fromFormat() + * @return {Object} + */ + static fromFormatExplain(text, fmt, options = {}) { + const { locale = null, numberingSystem = null } = options, localeToUse = Locale.fromOpts({ + locale, + numberingSystem, + defaultToEN: true + }); + return explainFromTokens(localeToUse, text, fmt); + } + /** + * @deprecated use fromFormatExplain instead + */ + static fromStringExplain(text, fmt, options = {}) { + return DateTime.fromFormatExplain(text, fmt, options); + } + // FORMAT PRESETS + /** + * {@link DateTime#toLocaleString} format like 10/14/1983 + * @type {Object} + */ + static get DATE_SHORT() { + return DATE_SHORT; + } + /** + * {@link DateTime#toLocaleString} format like 'Oct 14, 1983' + * @type {Object} + */ + static get DATE_MED() { + return DATE_MED; + } + /** + * {@link DateTime#toLocaleString} format like 'Fri, Oct 14, 1983' + * @type {Object} + */ + static get DATE_MED_WITH_WEEKDAY() { + return DATE_MED_WITH_WEEKDAY; + } + /** + * {@link DateTime#toLocaleString} format like 'October 14, 1983' + * @type {Object} + */ + static get DATE_FULL() { + return DATE_FULL; + } + /** + * {@link DateTime#toLocaleString} format like 'Tuesday, October 14, 1983' + * @type {Object} + */ + static get DATE_HUGE() { + return DATE_HUGE; + } + /** + * {@link DateTime#toLocaleString} format like '09:30 AM'. Only 12-hour if the locale is. + * @type {Object} + */ + static get TIME_SIMPLE() { + return TIME_SIMPLE; + } + /** + * {@link DateTime#toLocaleString} format like '09:30:23 AM'. Only 12-hour if the locale is. + * @type {Object} + */ + static get TIME_WITH_SECONDS() { + return TIME_WITH_SECONDS; + } + /** + * {@link DateTime#toLocaleString} format like '09:30:23 AM EDT'. Only 12-hour if the locale is. + * @type {Object} + */ + static get TIME_WITH_SHORT_OFFSET() { + return TIME_WITH_SHORT_OFFSET; + } + /** + * {@link DateTime#toLocaleString} format like '09:30:23 AM Eastern Daylight Time'. Only 12-hour if the locale is. + * @type {Object} + */ + static get TIME_WITH_LONG_OFFSET() { + return TIME_WITH_LONG_OFFSET; + } + /** + * {@link DateTime#toLocaleString} format like '09:30', always 24-hour. + * @type {Object} + */ + static get TIME_24_SIMPLE() { + return TIME_24_SIMPLE; + } + /** + * {@link DateTime#toLocaleString} format like '09:30:23', always 24-hour. + * @type {Object} + */ + static get TIME_24_WITH_SECONDS() { + return TIME_24_WITH_SECONDS; + } + /** + * {@link DateTime#toLocaleString} format like '09:30:23 EDT', always 24-hour. + * @type {Object} + */ + static get TIME_24_WITH_SHORT_OFFSET() { + return TIME_24_WITH_SHORT_OFFSET; + } + /** + * {@link DateTime#toLocaleString} format like '09:30:23 Eastern Daylight Time', always 24-hour. + * @type {Object} + */ + static get TIME_24_WITH_LONG_OFFSET() { + return TIME_24_WITH_LONG_OFFSET; + } + /** + * {@link DateTime#toLocaleString} format like '10/14/1983, 9:30 AM'. Only 12-hour if the locale is. + * @type {Object} + */ + static get DATETIME_SHORT() { + return DATETIME_SHORT; + } + /** + * {@link DateTime#toLocaleString} format like '10/14/1983, 9:30:33 AM'. Only 12-hour if the locale is. + * @type {Object} + */ + static get DATETIME_SHORT_WITH_SECONDS() { + return DATETIME_SHORT_WITH_SECONDS; + } + /** + * {@link DateTime#toLocaleString} format like 'Oct 14, 1983, 9:30 AM'. Only 12-hour if the locale is. + * @type {Object} + */ + static get DATETIME_MED() { + return DATETIME_MED; + } + /** + * {@link DateTime#toLocaleString} format like 'Oct 14, 1983, 9:30:33 AM'. Only 12-hour if the locale is. + * @type {Object} + */ + static get DATETIME_MED_WITH_SECONDS() { + return DATETIME_MED_WITH_SECONDS; + } + /** + * {@link DateTime#toLocaleString} format like 'Fri, 14 Oct 1983, 9:30 AM'. Only 12-hour if the locale is. + * @type {Object} + */ + static get DATETIME_MED_WITH_WEEKDAY() { + return DATETIME_MED_WITH_WEEKDAY; + } + /** + * {@link DateTime#toLocaleString} format like 'October 14, 1983, 9:30 AM EDT'. Only 12-hour if the locale is. + * @type {Object} + */ + static get DATETIME_FULL() { + return DATETIME_FULL; + } + /** + * {@link DateTime#toLocaleString} format like 'October 14, 1983, 9:30:33 AM EDT'. Only 12-hour if the locale is. + * @type {Object} + */ + static get DATETIME_FULL_WITH_SECONDS() { + return DATETIME_FULL_WITH_SECONDS; + } + /** + * {@link DateTime#toLocaleString} format like 'Friday, October 14, 1983, 9:30 AM Eastern Daylight Time'. Only 12-hour if the locale is. + * @type {Object} + */ + static get DATETIME_HUGE() { + return DATETIME_HUGE; + } + /** + * {@link DateTime#toLocaleString} format like 'Friday, October 14, 1983, 9:30:33 AM Eastern Daylight Time'. Only 12-hour if the locale is. + * @type {Object} + */ + static get DATETIME_HUGE_WITH_SECONDS() { + return DATETIME_HUGE_WITH_SECONDS; + } +}; +function friendlyDateTime(dateTimeish) { + if (DateTime.isDateTime(dateTimeish)) { + return dateTimeish; + } else if (dateTimeish && dateTimeish.valueOf && isNumber3(dateTimeish.valueOf())) { + return DateTime.fromJSDate(dateTimeish); + } else if (dateTimeish && typeof dateTimeish === "object") { + return DateTime.fromObject(dateTimeish); + } else { + throw new InvalidArgumentError( + `Unknown datetime argument: ${dateTimeish}, of type ${typeof dateTimeish}` + ); + } +} + +// ../../../node_modules/chartjs-adapter-luxon/dist/chartjs-adapter-luxon.esm.js +var FORMATS = { + datetime: DateTime.DATETIME_MED_WITH_SECONDS, + millisecond: "h:mm:ss.SSS a", + second: DateTime.TIME_WITH_SECONDS, + minute: DateTime.TIME_SIMPLE, + hour: { hour: "numeric" }, + day: { day: "numeric", month: "short" }, + week: "DD", + month: { month: "short", year: "numeric" }, + quarter: "'Q'q - yyyy", + year: { year: "numeric" } +}; +adapters2._date.override({ + _id: "luxon", + // DEBUG + /** + * @private + */ + _create: function(time) { + return DateTime.fromMillis(time, this.options); + }, + init(chartOptions) { + if (!this.options.locale) { + this.options.locale = chartOptions.locale; + } + }, + formats: function() { + return FORMATS; + }, + parse: function(value, format) { + const options = this.options; + const type = typeof value; + if (value === null || type === "undefined") { + return null; + } + if (type === "number") { + value = this._create(value); + } else if (type === "string") { + if (typeof format === "string") { + value = DateTime.fromFormat(value, format, options); + } else { + value = DateTime.fromISO(value, options); + } + } else if (value instanceof Date) { + value = DateTime.fromJSDate(value, options); + } else if (type === "object" && !(value instanceof DateTime)) { + value = DateTime.fromObject(value, options); + } + return value.isValid ? value.valueOf() : null; + }, + format: function(time, format) { + const datetime = this._create(time); + return typeof format === "string" ? datetime.toFormat(format) : datetime.toLocaleString(format); + }, + add: function(time, amount, unit) { + const args = {}; + args[unit] = amount; + return this._create(time).plus(args).valueOf(); + }, + diff: function(max, min, unit) { + return this._create(max).diff(this._create(min)).as(unit).valueOf(); + }, + startOf: function(time, unit, weekday) { + if (unit === "isoWeek") { + weekday = Math.trunc(Math.min(Math.max(0, weekday), 6)); + const dateTime = this._create(time); + return dateTime.minus({ days: (dateTime.weekday - weekday + 7) % 7 }).startOf("day").valueOf(); + } + return unit ? this._create(time).startOf(unit).valueOf() : time; + }, + endOf: function(time, unit) { + return this._create(time).endOf(unit).valueOf(); + } +}); + // resources/js/components/feeder.js -function duckFeederWidget() { +function duckFeederWidget(data) { return { hungerLevel: 100, ducksMurdered: 0, audioPlayed: false, init() { + this.initChart(); setInterval(() => { this.hungerLevel--; if (this.hungerLevel < 0) { this.hungerLevel = 100; this.ducksMurdered++; } + this.updateChart(); }, 1e3); setInterval(() => { this.audioPlayed = false; @@ -25,10 +24966,94 @@ function duckFeederWidget() { if (this.hungerLevel > 100) { this.hungerLevel = 100; } + this.updateChart(); + }, + initChart() { + Chart.defaults.plugins.tooltip.enabled = false; + Chart.defaults.plugins.legend.display = false; + return new Chart(this.$refs.canvas, { + type: data.chart.type, + data: data.chart.cachedData, + options: data.chart.options + }); + }, + updateChart() { + let chart = this.getChart(); + chart.data = { + datasets: [{ + data: [this.hungerLevel, 100 - this.hungerLevel], + backgroundColor: [this.getStateColour(), "Gray"] + }] + }; + chart.update("resize"); + }, + getStateColour() { + return this.hungerLevel >= 50 ? "Green" : this.hungerLevel >= 15 ? "Orange" : "Red"; + }, + getChart() { + return Chart.getChart(this.$refs.canvas); } }; } export { duckFeederWidget as default }; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vanMvY29tcG9uZW50cy9mZWVkZXIuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGR1Y2tGZWVkZXJXaWRnZXQoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgaHVuZ2VyTGV2ZWw6IDEwMCxcbiAgICAgICAgZHVja3NNdXJkZXJlZDogMCxcbiAgICAgICAgYXVkaW9QbGF5ZWQ6IGZhbHNlLFxuICAgICAgICBpbml0KCkge1xuICAgICAgICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaHVuZ2VyTGV2ZWwtLTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5odW5nZXJMZXZlbCA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5odW5nZXJMZXZlbCA9IDEwMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kdWNrc011cmRlcmVkKys7IFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIDEwMDApO1xuXG4gICAgICAgICAgICAvLyBQcmV2ZW50IGF1ZGlvIHNwYW1cbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvUGxheWVkID0gZmFsc2U7XG4gICAgICAgICAgICB9LCAzMDAwKVxuICAgICAgICB9LFxuICAgICAgICBmZWVkRHVjaygpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5hdWRpb1BsYXllZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuJHJlZnMuZHVja21vZGVBdWRpby5wbGF5KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb1BsYXllZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHRoaXMuaHVuZ2VyTGV2ZWwgKz01O1xuICAgICAgICAgICAgaWYgKHRoaXMuaHVuZ2VyTGV2ZWwgPiAxMDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmh1bmdlckxldmVsID0gMTAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUFlLFNBQVIsbUJBQW9DO0FBQ3ZDLFNBQU87QUFBQSxJQUNILGFBQWE7QUFBQSxJQUNiLGVBQWU7QUFBQSxJQUNmLGFBQWE7QUFBQSxJQUNiLE9BQU87QUFDSCxrQkFBWSxNQUFNO0FBQ2QsYUFBSztBQUNMLFlBQUksS0FBSyxjQUFjLEdBQUc7QUFDdEIsZUFBSyxjQUFjO0FBQ25CLGVBQUs7QUFBQSxRQUNUO0FBQUEsTUFDSixHQUFHLEdBQUk7QUFHUCxrQkFBWSxNQUFNO0FBQ2QsYUFBSyxjQUFjO0FBQUEsTUFDdkIsR0FBRyxHQUFJO0FBQUEsSUFDWDtBQUFBLElBQ0EsV0FBVztBQUNQLFVBQUksQ0FBQyxLQUFLLGFBQWE7QUFDbkIsYUFBSyxNQUFNLGNBQWMsS0FBSztBQUM5QixhQUFLLGNBQWM7QUFBQSxNQUN2QjtBQUVBLFdBQUssZUFBYztBQUNuQixVQUFJLEtBQUssY0FBYyxLQUFLO0FBQ3hCLGFBQUssY0FBYztBQUFBLE1BQ3ZCO0FBQUEsSUFDSjtBQUFBLEVBQ0o7QUFDSjsiLAogICJuYW1lcyI6IFtdCn0K +/*! Bundled license information: + +@kurkle/color/dist/color.esm.js: + (*! + * @kurkle/color v0.3.2 + * https://github.com/kurkle/color#readme + * (c) 2023 Jukka Kurkela + * Released under the MIT License + *) + +chart.js/dist/chunks/helpers.segment.js: + (*! + * Chart.js v4.4.2 + * https://www.chartjs.org + * (c) 2024 Chart.js Contributors + * Released under the MIT License + *) + +chart.js/dist/chart.js: + (*! + * Chart.js v4.4.2 + * https://www.chartjs.org + * (c) 2024 Chart.js Contributors + * Released under the MIT License + *) + +@kurkle/color/dist/color.esm.js: + (*! + * @kurkle/color v0.3.2 + * https://github.com/kurkle/color#readme + * (c) 2023 Jukka Kurkela + * Released under the MIT License + *) + +chart.js/dist/chunks/helpers.segment.js: + (*! + * Chart.js v4.4.2 + * https://www.chartjs.org + * (c) 2024 Chart.js Contributors + * Released under the MIT License + *) + +chart.js/dist/chart.js: + (*! + * Chart.js v4.4.2 + * https://www.chartjs.org + * (c) 2024 Chart.js Contributors + * Released under the MIT License + *) + +chartjs-adapter-luxon/dist/chartjs-adapter-luxon.esm.js: + (*! + * chartjs-adapter-luxon v1.3.1 + * https://www.chartjs.org + * (c) 2023 chartjs-adapter-luxon Contributors + * Released under the MIT license + *) +*/ +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL0BrdXJrbGUvY29sb3IvZGlzdC9jb2xvci5lc20uanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMuY29yZS50cyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5tYXRoLnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLmNvbGxlY3Rpb24udHMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMuZXh0cmFzLnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLmVhc2luZy50cyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5jb2xvci50cyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5hbmltYXRpb25zLmRlZmF1bHRzLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmxheW91dHMuZGVmYXVsdHMuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMuaW50bC50cyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS50aWNrcy5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5zY2FsZS5kZWZhdWx0cy5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5kZWZhdWx0cy5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5jYW52YXMudHMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMub3B0aW9ucy50cyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5jb25maWcudHMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMuY3VydmUudHMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMuZG9tLnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLmludGVycG9sYXRpb24udHMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMucnRsLnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLnNlZ21lbnQuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUuYW5pbWF0b3IuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUuYW5pbWF0aW9uLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmFuaW1hdGlvbnMuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUuZGF0YXNldENvbnRyb2xsZXIuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb250cm9sbGVycy9jb250cm9sbGVyLmJhci5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvbnRyb2xsZXJzL2NvbnRyb2xsZXIuYnViYmxlLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5kb3VnaG51dC5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvbnRyb2xsZXJzL2NvbnRyb2xsZXIubGluZS5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvbnRyb2xsZXJzL2NvbnRyb2xsZXIucG9sYXJBcmVhLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5waWUuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb250cm9sbGVycy9jb250cm9sbGVyLnJhZGFyLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5zY2F0dGVyLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmFkYXB0ZXJzLnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmludGVyYWN0aW9uLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmxheW91dHMuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbGF0Zm9ybS9wbGF0Zm9ybS5iYXNlLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGxhdGZvcm0vcGxhdGZvcm0uYmFzaWMuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbGF0Zm9ybS9wbGF0Zm9ybS5kb20uanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbGF0Zm9ybS9pbmRleC5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5lbGVtZW50LnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnNjYWxlLmF1dG9za2lwLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnNjYWxlLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnR5cGVkUmVnaXN0cnkuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUucmVnaXN0cnkuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUucGx1Z2lucy5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5jb25maWcuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUuY29udHJvbGxlci5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2VsZW1lbnRzL2VsZW1lbnQuYXJjLnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvZWxlbWVudHMvZWxlbWVudC5saW5lLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvZWxlbWVudHMvZWxlbWVudC5wb2ludC50cyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2VsZW1lbnRzL2VsZW1lbnQuYmFyLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4uY29sb3JzLnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4uZGVjaW1hdGlvbi5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsdWdpbnMvcGx1Z2luLmZpbGxlci9maWxsZXIuc2VnbWVudC5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsdWdpbnMvcGx1Z2luLmZpbGxlci9maWxsZXIuaGVscGVyLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4uZmlsbGVyL2ZpbGxlci5vcHRpb25zLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4uZmlsbGVyL2ZpbGxlci50YXJnZXQuc3RhY2suanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi5maWxsZXIvc2ltcGxlQXJjLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4uZmlsbGVyL2ZpbGxlci50YXJnZXQuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi5maWxsZXIvZmlsbGVyLmRyYXdpbmcuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi5maWxsZXIvaW5kZXguanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi5sZWdlbmQuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi50aXRsZS5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsdWdpbnMvcGx1Z2luLnN1YnRpdGxlLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4udG9vbHRpcC5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3NjYWxlcy9zY2FsZS5jYXRlZ29yeS5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3NjYWxlcy9zY2FsZS5saW5lYXJiYXNlLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLmxpbmVhci5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3NjYWxlcy9zY2FsZS5sb2dhcml0aG1pYy5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3NjYWxlcy9zY2FsZS5yYWRpYWxMaW5lYXIuanMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9zY2FsZXMvc2NhbGUudGltZS5qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3NjYWxlcy9zY2FsZS50aW1lc2VyaWVzLmpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaW5kZXgudHMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL2F1dG8vYXV0by5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvQGt1cmtsZS9jb2xvci9kaXN0L2NvbG9yLmVzbS5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5jb3JlLnRzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLm1hdGgudHMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMuY29sbGVjdGlvbi50cyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5leHRyYXMudHMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMuZWFzaW5nLnRzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLmNvbG9yLnRzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmFuaW1hdGlvbnMuZGVmYXVsdHMuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUubGF5b3V0cy5kZWZhdWx0cy5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5pbnRsLnRzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnRpY2tzLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLnNjYWxlLmRlZmF1bHRzLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmRlZmF1bHRzLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLmNhbnZhcy50cyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5vcHRpb25zLnRzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvaGVscGVycy9oZWxwZXJzLmNvbmZpZy50cyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5jdXJ2ZS50cyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5kb20udHMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMuaW50ZXJwb2xhdGlvbi50cyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2hlbHBlcnMvaGVscGVycy5ydGwudHMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9oZWxwZXJzL2hlbHBlcnMuc2VnbWVudC5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5hbmltYXRvci5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5hbmltYXRpb24uanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUuYW5pbWF0aW9ucy5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5kYXRhc2V0Q29udHJvbGxlci5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvbnRyb2xsZXJzL2NvbnRyb2xsZXIuYmFyLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5idWJibGUuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb250cm9sbGVycy9jb250cm9sbGVyLmRvdWdobnV0LmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5saW5lLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29udHJvbGxlcnMvY29udHJvbGxlci5wb2xhckFyZWEuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb250cm9sbGVycy9jb250cm9sbGVyLnBpZS5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvbnRyb2xsZXJzL2NvbnRyb2xsZXIucmFkYXIuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb250cm9sbGVycy9jb250cm9sbGVyLnNjYXR0ZXIuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUuYWRhcHRlcnMudHMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUuaW50ZXJhY3Rpb24uanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUubGF5b3V0cy5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsYXRmb3JtL3BsYXRmb3JtLmJhc2UuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbGF0Zm9ybS9wbGF0Zm9ybS5iYXNpYy5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsYXRmb3JtL3BsYXRmb3JtLmRvbS5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsYXRmb3JtL2luZGV4LmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmVsZW1lbnQudHMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUuc2NhbGUuYXV0b3NraXAuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUuc2NhbGUuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9jb3JlL2NvcmUudHlwZWRSZWdpc3RyeS5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5yZWdpc3RyeS5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5wbHVnaW5zLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvY29yZS9jb3JlLmNvbmZpZy5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL2NvcmUvY29yZS5jb250cm9sbGVyLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvZWxlbWVudHMvZWxlbWVudC5hcmMudHMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9lbGVtZW50cy9lbGVtZW50LmxpbmUuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9lbGVtZW50cy9lbGVtZW50LnBvaW50LnRzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvZWxlbWVudHMvZWxlbWVudC5iYXIuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi5jb2xvcnMudHMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi5kZWNpbWF0aW9uLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4uZmlsbGVyL2ZpbGxlci5zZWdtZW50LmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4uZmlsbGVyL2ZpbGxlci5oZWxwZXIuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi5maWxsZXIvZmlsbGVyLm9wdGlvbnMuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi5maWxsZXIvZmlsbGVyLnRhcmdldC5zdGFjay5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsdWdpbnMvcGx1Z2luLmZpbGxlci9zaW1wbGVBcmMuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi5maWxsZXIvZmlsbGVyLnRhcmdldC5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsdWdpbnMvcGx1Z2luLmZpbGxlci9maWxsZXIuZHJhd2luZy5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsdWdpbnMvcGx1Z2luLmZpbGxlci9pbmRleC5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsdWdpbnMvcGx1Z2luLmxlZ2VuZC5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3BsdWdpbnMvcGx1Z2luLnRpdGxlLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvcGx1Z2lucy9wbHVnaW4uc3VidGl0bGUuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9wbHVnaW5zL3BsdWdpbi50b29sdGlwLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLmNhdGVnb3J5LmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLmxpbmVhcmJhc2UuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9zY2FsZXMvc2NhbGUubGluZWFyLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLmxvZ2FyaXRobWljLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLnJhZGlhbExpbmVhci5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvc3JjL3NjYWxlcy9zY2FsZS50aW1lLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jaGFydC5qcy9zcmMvc2NhbGVzL3NjYWxlLnRpbWVzZXJpZXMuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0LmpzL3NyYy9pbmRleC50cyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL2Vycm9ycy5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL2ltcGwvZm9ybWF0cy5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL3pvbmUuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2x1eG9uL3NyYy96b25lcy9zeXN0ZW1ab25lLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sdXhvbi9zcmMvem9uZXMvSUFOQVpvbmUuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2x1eG9uL3NyYy9pbXBsL2xvY2FsZS5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL3pvbmVzL2ZpeGVkT2Zmc2V0Wm9uZS5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL3pvbmVzL2ludmFsaWRab25lLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sdXhvbi9zcmMvaW1wbC96b25lVXRpbC5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL3NldHRpbmdzLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sdXhvbi9zcmMvaW1wbC9pbnZhbGlkLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sdXhvbi9zcmMvaW1wbC9jb252ZXJzaW9ucy5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL2ltcGwvdXRpbC5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL2ltcGwvZW5nbGlzaC5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL2ltcGwvZm9ybWF0dGVyLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sdXhvbi9zcmMvaW1wbC9yZWdleFBhcnNlci5qcyIsICIuLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvbHV4b24vc3JjL2R1cmF0aW9uLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sdXhvbi9zcmMvaW50ZXJ2YWwuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2x1eG9uL3NyYy9pbmZvLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sdXhvbi9zcmMvaW1wbC9kaWZmLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sdXhvbi9zcmMvaW1wbC9kaWdpdHMuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2x1eG9uL3NyYy9pbXBsL3Rva2VuUGFyc2VyLmpzIiwgIi4uLy4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sdXhvbi9zcmMvZGF0ZXRpbWUuanMiLCAiLi4vLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2NoYXJ0anMtYWRhcHRlci1sdXhvbi9kaXN0L2NoYXJ0anMtYWRhcHRlci1sdXhvbi5lc20uanMiLCAiLi4vLi4vanMvY29tcG9uZW50cy9mZWVkZXIuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qIVxuICogQGt1cmtsZS9jb2xvciB2MC4zLjJcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9rdXJrbGUvY29sb3IjcmVhZG1lXG4gKiAoYykgMjAyMyBKdWtrYSBLdXJrZWxhXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2VcbiAqL1xuZnVuY3Rpb24gcm91bmQodikge1xuICByZXR1cm4gdiArIDAuNSB8IDA7XG59XG5jb25zdCBsaW0gPSAodiwgbCwgaCkgPT4gTWF0aC5tYXgoTWF0aC5taW4odiwgaCksIGwpO1xuZnVuY3Rpb24gcDJiKHYpIHtcbiAgcmV0dXJuIGxpbShyb3VuZCh2ICogMi41NSksIDAsIDI1NSk7XG59XG5mdW5jdGlvbiBiMnAodikge1xuICByZXR1cm4gbGltKHJvdW5kKHYgLyAyLjU1KSwgMCwgMTAwKTtcbn1cbmZ1bmN0aW9uIG4yYih2KSB7XG4gIHJldHVybiBsaW0ocm91bmQodiAqIDI1NSksIDAsIDI1NSk7XG59XG5mdW5jdGlvbiBiMm4odikge1xuICByZXR1cm4gbGltKHJvdW5kKHYgLyAyLjU1KSAvIDEwMCwgMCwgMSk7XG59XG5mdW5jdGlvbiBuMnAodikge1xuICByZXR1cm4gbGltKHJvdW5kKHYgKiAxMDApLCAwLCAxMDApO1xufVxuXG5jb25zdCBtYXAkMSA9IHswOiAwLCAxOiAxLCAyOiAyLCAzOiAzLCA0OiA0LCA1OiA1LCA2OiA2LCA3OiA3LCA4OiA4LCA5OiA5LCBBOiAxMCwgQjogMTEsIEM6IDEyLCBEOiAxMywgRTogMTQsIEY6IDE1LCBhOiAxMCwgYjogMTEsIGM6IDEyLCBkOiAxMywgZTogMTQsIGY6IDE1fTtcbmNvbnN0IGhleCA9IFsuLi4nMDEyMzQ1Njc4OUFCQ0RFRiddO1xuY29uc3QgaDEgPSBiID0+IGhleFtiICYgMHhGXTtcbmNvbnN0IGgyID0gYiA9PiBoZXhbKGIgJiAweEYwKSA+PiA0XSArIGhleFtiICYgMHhGXTtcbmNvbnN0IGVxID0gYiA9PiAoKGIgJiAweEYwKSA+PiA0KSA9PT0gKGIgJiAweEYpO1xuY29uc3QgaXNTaG9ydCA9IHYgPT4gZXEodi5yKSAmJiBlcSh2LmcpICYmIGVxKHYuYikgJiYgZXEodi5hKTtcbmZ1bmN0aW9uIGhleFBhcnNlKHN0cikge1xuICB2YXIgbGVuID0gc3RyLmxlbmd0aDtcbiAgdmFyIHJldDtcbiAgaWYgKHN0clswXSA9PT0gJyMnKSB7XG4gICAgaWYgKGxlbiA9PT0gNCB8fCBsZW4gPT09IDUpIHtcbiAgICAgIHJldCA9IHtcbiAgICAgICAgcjogMjU1ICYgbWFwJDFbc3RyWzFdXSAqIDE3LFxuICAgICAgICBnOiAyNTUgJiBtYXAkMVtzdHJbMl1dICogMTcsXG4gICAgICAgIGI6IDI1NSAmIG1hcCQxW3N0clszXV0gKiAxNyxcbiAgICAgICAgYTogbGVuID09PSA1ID8gbWFwJDFbc3RyWzRdXSAqIDE3IDogMjU1XG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAobGVuID09PSA3IHx8IGxlbiA9PT0gOSkge1xuICAgICAgcmV0ID0ge1xuICAgICAgICByOiBtYXAkMVtzdHJbMV1dIDw8IDQgfCBtYXAkMVtzdHJbMl1dLFxuICAgICAgICBnOiBtYXAkMVtzdHJbM11dIDw8IDQgfCBtYXAkMVtzdHJbNF1dLFxuICAgICAgICBiOiBtYXAkMVtzdHJbNV1dIDw8IDQgfCBtYXAkMVtzdHJbNl1dLFxuICAgICAgICBhOiBsZW4gPT09IDkgPyAobWFwJDFbc3RyWzddXSA8PCA0IHwgbWFwJDFbc3RyWzhdXSkgOiAyNTVcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiByZXQ7XG59XG5jb25zdCBhbHBoYSA9IChhLCBmKSA9PiBhIDwgMjU1ID8gZihhKSA6ICcnO1xuZnVuY3Rpb24gaGV4U3RyaW5nKHYpIHtcbiAgdmFyIGYgPSBpc1Nob3J0KHYpID8gaDEgOiBoMjtcbiAgcmV0dXJuIHZcbiAgICA/ICcjJyArIGYodi5yKSArIGYodi5nKSArIGYodi5iKSArIGFscGhhKHYuYSwgZilcbiAgICA6IHVuZGVmaW5lZDtcbn1cblxuY29uc3QgSFVFX1JFID0gL14oaHNsYT98aHdifGhzdilcXChcXHMqKFstKy5lXFxkXSspKD86ZGVnKT9bXFxzLF0rKFstKy5lXFxkXSspJVtcXHMsXSsoWy0rLmVcXGRdKyklKD86W1xccyxdKyhbLSsuZVxcZF0rKSglKT8pP1xccypcXCkkLztcbmZ1bmN0aW9uIGhzbDJyZ2JuKGgsIHMsIGwpIHtcbiAgY29uc3QgYSA9IHMgKiBNYXRoLm1pbihsLCAxIC0gbCk7XG4gIGNvbnN0IGYgPSAobiwgayA9IChuICsgaCAvIDMwKSAlIDEyKSA9PiBsIC0gYSAqIE1hdGgubWF4KE1hdGgubWluKGsgLSAzLCA5IC0gaywgMSksIC0xKTtcbiAgcmV0dXJuIFtmKDApLCBmKDgpLCBmKDQpXTtcbn1cbmZ1bmN0aW9uIGhzdjJyZ2JuKGgsIHMsIHYpIHtcbiAgY29uc3QgZiA9IChuLCBrID0gKG4gKyBoIC8gNjApICUgNikgPT4gdiAtIHYgKiBzICogTWF0aC5tYXgoTWF0aC5taW4oaywgNCAtIGssIDEpLCAwKTtcbiAgcmV0dXJuIFtmKDUpLCBmKDMpLCBmKDEpXTtcbn1cbmZ1bmN0aW9uIGh3YjJyZ2JuKGgsIHcsIGIpIHtcbiAgY29uc3QgcmdiID0gaHNsMnJnYm4oaCwgMSwgMC41KTtcbiAgbGV0IGk7XG4gIGlmICh3ICsgYiA+IDEpIHtcbiAgICBpID0gMSAvICh3ICsgYik7XG4gICAgdyAqPSBpO1xuICAgIGIgKj0gaTtcbiAgfVxuICBmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKSB7XG4gICAgcmdiW2ldICo9IDEgLSB3IC0gYjtcbiAgICByZ2JbaV0gKz0gdztcbiAgfVxuICByZXR1cm4gcmdiO1xufVxuZnVuY3Rpb24gaHVlVmFsdWUociwgZywgYiwgZCwgbWF4KSB7XG4gIGlmIChyID09PSBtYXgpIHtcbiAgICByZXR1cm4gKChnIC0gYikgLyBkKSArIChnIDwgYiA/IDYgOiAwKTtcbiAgfVxuICBpZiAoZyA9PT0gbWF4KSB7XG4gICAgcmV0dXJuIChiIC0gcikgLyBkICsgMjtcbiAgfVxuICByZXR1cm4gKHIgLSBnKSAvIGQgKyA0O1xufVxuZnVuY3Rpb24gcmdiMmhzbCh2KSB7XG4gIGNvbnN0IHJhbmdlID0gMjU1O1xuICBjb25zdCByID0gdi5yIC8gcmFuZ2U7XG4gIGNvbnN0IGcgPSB2LmcgLyByYW5nZTtcbiAgY29uc3QgYiA9IHYuYiAvIHJhbmdlO1xuICBjb25zdCBtYXggPSBNYXRoLm1heChyLCBnLCBiKTtcbiAgY29uc3QgbWluID0gTWF0aC5taW4ociwgZywgYik7XG4gIGNvbnN0IGwgPSAobWF4ICsgbWluKSAvIDI7XG4gIGxldCBoLCBzLCBkO1xuICBpZiAobWF4ICE9PSBtaW4pIHtcbiAgICBkID0gbWF4IC0gbWluO1xuICAgIHMgPSBsID4gMC41ID8gZCAvICgyIC0gbWF4IC0gbWluKSA6IGQgLyAobWF4ICsgbWluKTtcbiAgICBoID0gaHVlVmFsdWUociwgZywgYiwgZCwgbWF4KTtcbiAgICBoID0gaCAqIDYwICsgMC41O1xuICB9XG4gIHJldHVybiBbaCB8IDAsIHMgfHwgMCwgbF07XG59XG5mdW5jdGlvbiBjYWxsbihmLCBhLCBiLCBjKSB7XG4gIHJldHVybiAoXG4gICAgQXJyYXkuaXNBcnJheShhKVxuICAgICAgPyBmKGFbMF0sIGFbMV0sIGFbMl0pXG4gICAgICA6IGYoYSwgYiwgYylcbiAgKS5tYXAobjJiKTtcbn1cbmZ1bmN0aW9uIGhzbDJyZ2IoaCwgcywgbCkge1xuICByZXR1cm4gY2FsbG4oaHNsMnJnYm4sIGgsIHMsIGwpO1xufVxuZnVuY3Rpb24gaHdiMnJnYihoLCB3LCBiKSB7XG4gIHJldHVybiBjYWxsbihod2IycmdibiwgaCwgdywgYik7XG59XG5mdW5jdGlvbiBoc3YycmdiKGgsIHMsIHYpIHtcbiAgcmV0dXJuIGNhbGxuKGhzdjJyZ2JuLCBoLCBzLCB2KTtcbn1cbmZ1bmN0aW9uIGh1ZShoKSB7XG4gIHJldHVybiAoaCAlIDM2MCArIDM2MCkgJSAzNjA7XG59XG5mdW5jdGlvbiBodWVQYXJzZShzdHIpIHtcbiAgY29uc3QgbSA9IEhVRV9SRS5leGVjKHN0cik7XG4gIGxldCBhID0gMjU1O1xuICBsZXQgdjtcbiAgaWYgKCFtKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChtWzVdICE9PSB2KSB7XG4gICAgYSA9IG1bNl0gPyBwMmIoK21bNV0pIDogbjJiKCttWzVdKTtcbiAgfVxuICBjb25zdCBoID0gaHVlKCttWzJdKTtcbiAgY29uc3QgcDEgPSArbVszXSAvIDEwMDtcbiAgY29uc3QgcDIgPSArbVs0XSAvIDEwMDtcbiAgaWYgKG1bMV0gPT09ICdod2InKSB7XG4gICAgdiA9IGh3YjJyZ2IoaCwgcDEsIHAyKTtcbiAgfSBlbHNlIGlmIChtWzFdID09PSAnaHN2Jykge1xuICAgIHYgPSBoc3YycmdiKGgsIHAxLCBwMik7XG4gIH0gZWxzZSB7XG4gICAgdiA9IGhzbDJyZ2IoaCwgcDEsIHAyKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIHI6IHZbMF0sXG4gICAgZzogdlsxXSxcbiAgICBiOiB2WzJdLFxuICAgIGE6IGFcbiAgfTtcbn1cbmZ1bmN0aW9uIHJvdGF0ZSh2LCBkZWcpIHtcbiAgdmFyIGggPSByZ2IyaHNsKHYpO1xuICBoWzBdID0gaHVlKGhbMF0gKyBkZWcpO1xuICBoID0gaHNsMnJnYihoKTtcbiAgdi5yID0gaFswXTtcbiAgdi5nID0gaFsxXTtcbiAgdi5iID0gaFsyXTtcbn1cbmZ1bmN0aW9uIGhzbFN0cmluZyh2KSB7XG4gIGlmICghdikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBhID0gcmdiMmhzbCh2KTtcbiAgY29uc3QgaCA9IGFbMF07XG4gIGNvbnN0IHMgPSBuMnAoYVsxXSk7XG4gIGNvbnN0IGwgPSBuMnAoYVsyXSk7XG4gIHJldHVybiB2LmEgPCAyNTVcbiAgICA/IGBoc2xhKCR7aH0sICR7c30lLCAke2x9JSwgJHtiMm4odi5hKX0pYFxuICAgIDogYGhzbCgke2h9LCAke3N9JSwgJHtsfSUpYDtcbn1cblxuY29uc3QgbWFwID0ge1xuICB4OiAnZGFyaycsXG4gIFo6ICdsaWdodCcsXG4gIFk6ICdyZScsXG4gIFg6ICdibHUnLFxuICBXOiAnZ3InLFxuICBWOiAnbWVkaXVtJyxcbiAgVTogJ3NsYXRlJyxcbiAgQTogJ2VlJyxcbiAgVDogJ29sJyxcbiAgUzogJ29yJyxcbiAgQjogJ3JhJyxcbiAgQzogJ2xhdGVnJyxcbiAgRDogJ2lnaHRzJyxcbiAgUjogJ2luJyxcbiAgUTogJ3R1cnF1b2lzJyxcbiAgRTogJ2hpJyxcbiAgUDogJ3JvJyxcbiAgTzogJ2FsJyxcbiAgTjogJ2xlJyxcbiAgTTogJ2RlJyxcbiAgTDogJ3llbGxvJyxcbiAgRjogJ2VuJyxcbiAgSzogJ2NoJyxcbiAgRzogJ2Fya3MnLFxuICBIOiAnZWEnLFxuICBJOiAnaWdodGcnLFxuICBKOiAnd2gnXG59O1xuY29uc3QgbmFtZXMkMSA9IHtcbiAgT2ljZVhlOiAnZjBmOGZmJyxcbiAgYW50aXF1ZXdFdGU6ICdmYWViZDcnLFxuICBhcXVhOiAnZmZmZicsXG4gIGFxdWFtYXJSZTogJzdmZmZkNCcsXG4gIGF6dVk6ICdmMGZmZmYnLFxuICBiZWlnZTogJ2Y1ZjVkYycsXG4gIGJpc3F1ZTogJ2ZmZTRjNCcsXG4gIGJsYWNrOiAnMCcsXG4gIGJsYW5LZWRPbW9uZDogJ2ZmZWJjZCcsXG4gIFhlOiAnZmYnLFxuICBYZXZpVGV0OiAnOGEyYmUyJyxcbiAgYlB3bjogJ2E1MmEyYScsXG4gIGJ1cmx5d29vZDogJ2RlYjg4NycsXG4gIGNhTXRYZTogJzVmOWVhMCcsXG4gIEthcnRZdXNlOiAnN2ZmZjAwJyxcbiAgS29jVGF0ZTogJ2QyNjkxZScsXG4gIGNTTzogJ2ZmN2Y1MCcsXG4gIGNTbmZsb3dlclhlOiAnNjQ5NWVkJyxcbiAgY1Nuc2lsazogJ2ZmZjhkYycsXG4gIGNyaW1zb246ICdkYzE0M2MnLFxuICBjeWFuOiAnZmZmZicsXG4gIHhYZTogJzhiJyxcbiAgeGN5YW46ICc4YjhiJyxcbiAgeGdUTW5QZDogJ2I4ODYwYicsXG4gIHhXYXk6ICdhOWE5YTknLFxuICB4Z1lGOiAnNjQwMCcsXG4gIHhnWXk6ICdhOWE5YTknLFxuICB4a2hha2k6ICdiZGI3NmInLFxuICB4bWFnRnRhOiAnOGIwMDhiJyxcbiAgeFRpdmVnWUY6ICc1NTZiMmYnLFxuICB4U2FuZ2U6ICdmZjhjMDAnLFxuICB4U2NFZDogJzk5MzJjYycsXG4gIHhZZDogJzhiMDAwMCcsXG4gIHhzT21vbjogJ2U5OTY3YScsXG4gIHhzSGdZRjogJzhmYmM4ZicsXG4gIHhVWGU6ICc0ODNkOGInLFxuICB4VVdheTogJzJmNGY0ZicsXG4gIHhVZ1l5OiAnMmY0ZjRmJyxcbiAgeFFlOiAnY2VkMScsXG4gIHh2aVRldDogJzk0MDBkMycsXG4gIGRBcHBSazogJ2ZmMTQ5MycsXG4gIGRBcHNreVhlOiAnYmZmZicsXG4gIGRpbVdheTogJzY5Njk2OScsXG4gIGRpbWdZeTogJzY5Njk2OScsXG4gIGRvZGdlclhlOiAnMWU5MGZmJyxcbiAgZmlZYnJpY2s6ICdiMjIyMjInLFxuICBmbFNPd0V0ZTogJ2ZmZmFmMCcsXG4gIGZvWXN0V0FuOiAnMjI4YjIyJyxcbiAgZnVLc2lhOiAnZmYwMGZmJyxcbiAgZ2FSc2JTbzogJ2RjZGNkYycsXG4gIGdob3N0d0V0ZTogJ2Y4ZjhmZicsXG4gIGdUZDogJ2ZmZDcwMCcsXG4gIGdUTW5QZDogJ2RhYTUyMCcsXG4gIFdheTogJzgwODA4MCcsXG4gIGdZRjogJzgwMDAnLFxuICBnWUZMdzogJ2FkZmYyZicsXG4gIGdZeTogJzgwODA4MCcsXG4gIGhvbmV5TXc6ICdmMGZmZjAnLFxuICBob3RwUms6ICdmZjY5YjQnLFxuICBSZGlhbllkOiAnY2Q1YzVjJyxcbiAgUmRpZ286ICc0YjAwODInLFxuICBpdlN5OiAnZmZmZmYwJyxcbiAga2hha2k6ICdmMGU2OGMnLFxuICBsYXZGTXI6ICdlNmU2ZmEnLFxuICBsYXZGTXJYc2g6ICdmZmYwZjUnLFxuICBsYXduZ1lGOiAnN2NmYzAwJyxcbiAgTm1vbmNFZmZvbjogJ2ZmZmFjZCcsXG4gIFpYZTogJ2FkZDhlNicsXG4gIFpjU086ICdmMDgwODAnLFxuICBaY3lhbjogJ2UwZmZmZicsXG4gIFpnVE1uUGRMdzogJ2ZhZmFkMicsXG4gIFpXYXk6ICdkM2QzZDMnLFxuICBaZ1lGOiAnOTBlZTkwJyxcbiAgWmdZeTogJ2QzZDNkMycsXG4gIFpwUms6ICdmZmI2YzEnLFxuICBac09tb246ICdmZmEwN2EnLFxuICBac0hnWUY6ICcyMGIyYWEnLFxuICBac2t5WGU6ICc4N2NlZmEnLFxuICBaVVdheTogJzc3ODg5OScsXG4gIFpVZ1l5OiAnNzc4ODk5JyxcbiAgWnN0QWxYZTogJ2IwYzRkZScsXG4gIFpMdzogJ2ZmZmZlMCcsXG4gIGxpbWU6ICdmZjAwJyxcbiAgbGltZWdZRjogJzMyY2QzMicsXG4gIGxSRjogJ2ZhZjBlNicsXG4gIG1hZ0Z0YTogJ2ZmMDBmZicsXG4gIG1hUG9uOiAnODAwMDAwJyxcbiAgVmFxdWFtYXJSZTogJzY2Y2RhYScsXG4gIFZYZTogJ2NkJyxcbiAgVlNjRWQ6ICdiYTU1ZDMnLFxuICBWcHVycE46ICc5MzcwZGInLFxuICBWc0hnWUY6ICczY2IzNzEnLFxuICBWVVhlOiAnN2I2OGVlJyxcbiAgVnNwclJnZ1lGOiAnZmE5YScsXG4gIFZRZTogJzQ4ZDFjYycsXG4gIFZ2aVRldFlkOiAnYzcxNTg1JyxcbiAgbWlkbmlnaHRYZTogJzE5MTk3MCcsXG4gIG1SdGNZYW06ICdmNWZmZmEnLFxuICBtaXN0eVBzZTogJ2ZmZTRlMScsXG4gIG1vY2Nhc1I6ICdmZmU0YjUnLFxuICBuYXZham93RXRlOiAnZmZkZWFkJyxcbiAgbmF2eTogJzgwJyxcbiAgVGRsYWNlOiAnZmRmNWU2JyxcbiAgVGl2ZTogJzgwODAwMCcsXG4gIFRpdmVkQmI6ICc2YjhlMjMnLFxuICBTYW5nZTogJ2ZmYTUwMCcsXG4gIFNhbmdlWWQ6ICdmZjQ1MDAnLFxuICBTY0VkOiAnZGE3MGQ2JyxcbiAgcE9lZ1RNblBkOiAnZWVlOGFhJyxcbiAgcE9lZ1lGOiAnOThmYjk4JyxcbiAgcE9lUWU6ICdhZmVlZWUnLFxuICBwT2V2aVRldFlkOiAnZGI3MDkzJyxcbiAgcGFwYXlhd0VwOiAnZmZlZmQ1JyxcbiAgcEhLcHVmZjogJ2ZmZGFiOScsXG4gIHBlcnU6ICdjZDg1M2YnLFxuICBwUms6ICdmZmMwY2InLFxuICBwbHVtOiAnZGRhMGRkJyxcbiAgcG93TXJYZTogJ2IwZTBlNicsXG4gIHB1cnBOOiAnODAwMDgwJyxcbiAgWWJlY2NhcHVycE46ICc2NjMzOTknLFxuICBZZDogJ2ZmMDAwMCcsXG4gIFBzeWJyb3duOiAnYmM4ZjhmJyxcbiAgUHlPWGU6ICc0MTY5ZTEnLFxuICBzYWRkTmJQd246ICc4YjQ1MTMnLFxuICBzT21vbjogJ2ZhODA3MicsXG4gIHNhbmR5YlB3bjogJ2Y0YTQ2MCcsXG4gIHNIZ1lGOiAnMmU4YjU3JyxcbiAgc0hzaGVsbDogJ2ZmZjVlZScsXG4gIHNpRm5hOiAnYTA1MjJkJyxcbiAgc2lsdmVyOiAnYzBjMGMwJyxcbiAgc2t5WGU6ICc4N2NlZWInLFxuICBVWGU6ICc2YTVhY2QnLFxuICBVV2F5OiAnNzA4MDkwJyxcbiAgVWdZeTogJzcwODA5MCcsXG4gIHNub3c6ICdmZmZhZmEnLFxuICBzcHJSZ2dZRjogJ2ZmN2YnLFxuICBzdEFsWGU6ICc0NjgyYjQnLFxuICB0YW46ICdkMmI0OGMnLFxuICB0ZU86ICc4MDgwJyxcbiAgdEVzdE46ICdkOGJmZDgnLFxuICB0b21hdG86ICdmZjYzNDcnLFxuICBRZTogJzQwZTBkMCcsXG4gIHZpVGV0OiAnZWU4MmVlJyxcbiAgSkh0OiAnZjVkZWIzJyxcbiAgd0V0ZTogJ2ZmZmZmZicsXG4gIHdFdGVzbW9rZTogJ2Y1ZjVmNScsXG4gIEx3OiAnZmZmZjAwJyxcbiAgTHdnWUY6ICc5YWNkMzInXG59O1xuZnVuY3Rpb24gdW5wYWNrKCkge1xuICBjb25zdCB1bnBhY2tlZCA9IHt9O1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMobmFtZXMkMSk7XG4gIGNvbnN0IHRrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcbiAgbGV0IGksIGosIGssIG9rLCBuaztcbiAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICBvayA9IG5rID0ga2V5c1tpXTtcbiAgICBmb3IgKGogPSAwOyBqIDwgdGtleXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGsgPSB0a2V5c1tqXTtcbiAgICAgIG5rID0gbmsucmVwbGFjZShrLCBtYXBba10pO1xuICAgIH1cbiAgICBrID0gcGFyc2VJbnQobmFtZXMkMVtva10sIDE2KTtcbiAgICB1bnBhY2tlZFtua10gPSBbayA+PiAxNiAmIDB4RkYsIGsgPj4gOCAmIDB4RkYsIGsgJiAweEZGXTtcbiAgfVxuICByZXR1cm4gdW5wYWNrZWQ7XG59XG5cbmxldCBuYW1lcztcbmZ1bmN0aW9uIG5hbWVQYXJzZShzdHIpIHtcbiAgaWYgKCFuYW1lcykge1xuICAgIG5hbWVzID0gdW5wYWNrKCk7XG4gICAgbmFtZXMudHJhbnNwYXJlbnQgPSBbMCwgMCwgMCwgMF07XG4gIH1cbiAgY29uc3QgYSA9IG5hbWVzW3N0ci50b0xvd2VyQ2FzZSgpXTtcbiAgcmV0dXJuIGEgJiYge1xuICAgIHI6IGFbMF0sXG4gICAgZzogYVsxXSxcbiAgICBiOiBhWzJdLFxuICAgIGE6IGEubGVuZ3RoID09PSA0ID8gYVszXSA6IDI1NVxuICB9O1xufVxuXG5jb25zdCBSR0JfUkUgPSAvXnJnYmE/XFwoXFxzKihbLSsuXFxkXSspKCUpP1tcXHMsXSsoWy0rLmVcXGRdKykoJSk/W1xccyxdKyhbLSsuZVxcZF0rKSglKT8oPzpbXFxzLC9dKyhbLSsuZVxcZF0rKSglKT8pP1xccypcXCkkLztcbmZ1bmN0aW9uIHJnYlBhcnNlKHN0cikge1xuICBjb25zdCBtID0gUkdCX1JFLmV4ZWMoc3RyKTtcbiAgbGV0IGEgPSAyNTU7XG4gIGxldCByLCBnLCBiO1xuICBpZiAoIW0pIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKG1bN10gIT09IHIpIHtcbiAgICBjb25zdCB2ID0gK21bN107XG4gICAgYSA9IG1bOF0gPyBwMmIodikgOiBsaW0odiAqIDI1NSwgMCwgMjU1KTtcbiAgfVxuICByID0gK21bMV07XG4gIGcgPSArbVszXTtcbiAgYiA9ICttWzVdO1xuICByID0gMjU1ICYgKG1bMl0gPyBwMmIocikgOiBsaW0ociwgMCwgMjU1KSk7XG4gIGcgPSAyNTUgJiAobVs0XSA/IHAyYihnKSA6IGxpbShnLCAwLCAyNTUpKTtcbiAgYiA9IDI1NSAmIChtWzZdID8gcDJiKGIpIDogbGltKGIsIDAsIDI1NSkpO1xuICByZXR1cm4ge1xuICAgIHI6IHIsXG4gICAgZzogZyxcbiAgICBiOiBiLFxuICAgIGE6IGFcbiAgfTtcbn1cbmZ1bmN0aW9uIHJnYlN0cmluZyh2KSB7XG4gIHJldHVybiB2ICYmIChcbiAgICB2LmEgPCAyNTVcbiAgICAgID8gYHJnYmEoJHt2LnJ9LCAke3YuZ30sICR7di5ifSwgJHtiMm4odi5hKX0pYFxuICAgICAgOiBgcmdiKCR7di5yfSwgJHt2Lmd9LCAke3YuYn0pYFxuICApO1xufVxuXG5jb25zdCB0byA9IHYgPT4gdiA8PSAwLjAwMzEzMDggPyB2ICogMTIuOTIgOiBNYXRoLnBvdyh2LCAxLjAgLyAyLjQpICogMS4wNTUgLSAwLjA1NTtcbmNvbnN0IGZyb20gPSB2ID0+IHYgPD0gMC4wNDA0NSA/IHYgLyAxMi45MiA6IE1hdGgucG93KCh2ICsgMC4wNTUpIC8gMS4wNTUsIDIuNCk7XG5mdW5jdGlvbiBpbnRlcnBvbGF0ZShyZ2IxLCByZ2IyLCB0KSB7XG4gIGNvbnN0IHIgPSBmcm9tKGIybihyZ2IxLnIpKTtcbiAgY29uc3QgZyA9IGZyb20oYjJuKHJnYjEuZykpO1xuICBjb25zdCBiID0gZnJvbShiMm4ocmdiMS5iKSk7XG4gIHJldHVybiB7XG4gICAgcjogbjJiKHRvKHIgKyB0ICogKGZyb20oYjJuKHJnYjIucikpIC0gcikpKSxcbiAgICBnOiBuMmIodG8oZyArIHQgKiAoZnJvbShiMm4ocmdiMi5nKSkgLSBnKSkpLFxuICAgIGI6IG4yYih0byhiICsgdCAqIChmcm9tKGIybihyZ2IyLmIpKSAtIGIpKSksXG4gICAgYTogcmdiMS5hICsgdCAqIChyZ2IyLmEgLSByZ2IxLmEpXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1vZEhTTCh2LCBpLCByYXRpbykge1xuICBpZiAodikge1xuICAgIGxldCB0bXAgPSByZ2IyaHNsKHYpO1xuICAgIHRtcFtpXSA9IE1hdGgubWF4KDAsIE1hdGgubWluKHRtcFtpXSArIHRtcFtpXSAqIHJhdGlvLCBpID09PSAwID8gMzYwIDogMSkpO1xuICAgIHRtcCA9IGhzbDJyZ2IodG1wKTtcbiAgICB2LnIgPSB0bXBbMF07XG4gICAgdi5nID0gdG1wWzFdO1xuICAgIHYuYiA9IHRtcFsyXTtcbiAgfVxufVxuZnVuY3Rpb24gY2xvbmUodiwgcHJvdG8pIHtcbiAgcmV0dXJuIHYgPyBPYmplY3QuYXNzaWduKHByb3RvIHx8IHt9LCB2KSA6IHY7XG59XG5mdW5jdGlvbiBmcm9tT2JqZWN0KGlucHV0KSB7XG4gIHZhciB2ID0ge3I6IDAsIGc6IDAsIGI6IDAsIGE6IDI1NX07XG4gIGlmIChBcnJheS5pc0FycmF5KGlucHV0KSkge1xuICAgIGlmIChpbnB1dC5sZW5ndGggPj0gMykge1xuICAgICAgdiA9IHtyOiBpbnB1dFswXSwgZzogaW5wdXRbMV0sIGI6IGlucHV0WzJdLCBhOiAyNTV9O1xuICAgICAgaWYgKGlucHV0Lmxlbmd0aCA+IDMpIHtcbiAgICAgICAgdi5hID0gbjJiKGlucHV0WzNdKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdiA9IGNsb25lKGlucHV0LCB7cjogMCwgZzogMCwgYjogMCwgYTogMX0pO1xuICAgIHYuYSA9IG4yYih2LmEpO1xuICB9XG4gIHJldHVybiB2O1xufVxuZnVuY3Rpb24gZnVuY3Rpb25QYXJzZShzdHIpIHtcbiAgaWYgKHN0ci5jaGFyQXQoMCkgPT09ICdyJykge1xuICAgIHJldHVybiByZ2JQYXJzZShzdHIpO1xuICB9XG4gIHJldHVybiBodWVQYXJzZShzdHIpO1xufVxuY2xhc3MgQ29sb3Ige1xuICBjb25zdHJ1Y3RvcihpbnB1dCkge1xuICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIENvbG9yKSB7XG4gICAgICByZXR1cm4gaW5wdXQ7XG4gICAgfVxuICAgIGNvbnN0IHR5cGUgPSB0eXBlb2YgaW5wdXQ7XG4gICAgbGV0IHY7XG4gICAgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICB2ID0gZnJvbU9iamVjdChpbnB1dCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgdiA9IGhleFBhcnNlKGlucHV0KSB8fCBuYW1lUGFyc2UoaW5wdXQpIHx8IGZ1bmN0aW9uUGFyc2UoaW5wdXQpO1xuICAgIH1cbiAgICB0aGlzLl9yZ2IgPSB2O1xuICAgIHRoaXMuX3ZhbGlkID0gISF2O1xuICB9XG4gIGdldCB2YWxpZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsaWQ7XG4gIH1cbiAgZ2V0IHJnYigpIHtcbiAgICB2YXIgdiA9IGNsb25lKHRoaXMuX3JnYik7XG4gICAgaWYgKHYpIHtcbiAgICAgIHYuYSA9IGIybih2LmEpO1xuICAgIH1cbiAgICByZXR1cm4gdjtcbiAgfVxuICBzZXQgcmdiKG9iaikge1xuICAgIHRoaXMuX3JnYiA9IGZyb21PYmplY3Qob2JqKTtcbiAgfVxuICByZ2JTdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbGlkID8gcmdiU3RyaW5nKHRoaXMuX3JnYikgOiB1bmRlZmluZWQ7XG4gIH1cbiAgaGV4U3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLl92YWxpZCA/IGhleFN0cmluZyh0aGlzLl9yZ2IpIDogdW5kZWZpbmVkO1xuICB9XG4gIGhzbFN0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsaWQgPyBoc2xTdHJpbmcodGhpcy5fcmdiKSA6IHVuZGVmaW5lZDtcbiAgfVxuICBtaXgoY29sb3IsIHdlaWdodCkge1xuICAgIGlmIChjb2xvcikge1xuICAgICAgY29uc3QgYzEgPSB0aGlzLnJnYjtcbiAgICAgIGNvbnN0IGMyID0gY29sb3IucmdiO1xuICAgICAgbGV0IHcyO1xuICAgICAgY29uc3QgcCA9IHdlaWdodCA9PT0gdzIgPyAwLjUgOiB3ZWlnaHQ7XG4gICAgICBjb25zdCB3ID0gMiAqIHAgLSAxO1xuICAgICAgY29uc3QgYSA9IGMxLmEgLSBjMi5hO1xuICAgICAgY29uc3QgdzEgPSAoKHcgKiBhID09PSAtMSA/IHcgOiAodyArIGEpIC8gKDEgKyB3ICogYSkpICsgMSkgLyAyLjA7XG4gICAgICB3MiA9IDEgLSB3MTtcbiAgICAgIGMxLnIgPSAweEZGICYgdzEgKiBjMS5yICsgdzIgKiBjMi5yICsgMC41O1xuICAgICAgYzEuZyA9IDB4RkYgJiB3MSAqIGMxLmcgKyB3MiAqIGMyLmcgKyAwLjU7XG4gICAgICBjMS5iID0gMHhGRiAmIHcxICogYzEuYiArIHcyICogYzIuYiArIDAuNTtcbiAgICAgIGMxLmEgPSBwICogYzEuYSArICgxIC0gcCkgKiBjMi5hO1xuICAgICAgdGhpcy5yZ2IgPSBjMTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgaW50ZXJwb2xhdGUoY29sb3IsIHQpIHtcbiAgICBpZiAoY29sb3IpIHtcbiAgICAgIHRoaXMuX3JnYiA9IGludGVycG9sYXRlKHRoaXMuX3JnYiwgY29sb3IuX3JnYiwgdCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIGNsb25lKCkge1xuICAgIHJldHVybiBuZXcgQ29sb3IodGhpcy5yZ2IpO1xuICB9XG4gIGFscGhhKGEpIHtcbiAgICB0aGlzLl9yZ2IuYSA9IG4yYihhKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBjbGVhcmVyKHJhdGlvKSB7XG4gICAgY29uc3QgcmdiID0gdGhpcy5fcmdiO1xuICAgIHJnYi5hICo9IDEgLSByYXRpbztcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBncmV5c2NhbGUoKSB7XG4gICAgY29uc3QgcmdiID0gdGhpcy5fcmdiO1xuICAgIGNvbnN0IHZhbCA9IHJvdW5kKHJnYi5yICogMC4zICsgcmdiLmcgKiAwLjU5ICsgcmdiLmIgKiAwLjExKTtcbiAgICByZ2IuciA9IHJnYi5nID0gcmdiLmIgPSB2YWw7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgb3BhcXVlcihyYXRpbykge1xuICAgIGNvbnN0IHJnYiA9IHRoaXMuX3JnYjtcbiAgICByZ2IuYSAqPSAxICsgcmF0aW87XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgbmVnYXRlKCkge1xuICAgIGNvbnN0IHYgPSB0aGlzLl9yZ2I7XG4gICAgdi5yID0gMjU1IC0gdi5yO1xuICAgIHYuZyA9IDI1NSAtIHYuZztcbiAgICB2LmIgPSAyNTUgLSB2LmI7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgbGlnaHRlbihyYXRpbykge1xuICAgIG1vZEhTTCh0aGlzLl9yZ2IsIDIsIHJhdGlvKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBkYXJrZW4ocmF0aW8pIHtcbiAgICBtb2RIU0wodGhpcy5fcmdiLCAyLCAtcmF0aW8pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHNhdHVyYXRlKHJhdGlvKSB7XG4gICAgbW9kSFNMKHRoaXMuX3JnYiwgMSwgcmF0aW8pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIGRlc2F0dXJhdGUocmF0aW8pIHtcbiAgICBtb2RIU0wodGhpcy5fcmdiLCAxLCAtcmF0aW8pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHJvdGF0ZShkZWcpIHtcbiAgICByb3RhdGUodGhpcy5fcmdiLCBkZWcpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4X2VzbShpbnB1dCkge1xuICByZXR1cm4gbmV3IENvbG9yKGlucHV0KTtcbn1cblxuZXhwb3J0IHsgQ29sb3IsIGIybiwgYjJwLCBpbmRleF9lc20gYXMgZGVmYXVsdCwgaGV4UGFyc2UsIGhleFN0cmluZywgaHNsMnJnYiwgaHNsU3RyaW5nLCBoc3YycmdiLCBodWVQYXJzZSwgaHdiMnJnYiwgbGltLCBuMmIsIG4ycCwgbmFtZVBhcnNlLCBwMmIsIHJnYjJoc2wsIHJnYlBhcnNlLCByZ2JTdHJpbmcsIHJvdGF0ZSwgcm91bmQgfTtcbiIsICIvKipcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuaGVscGVyc1xuICovXG5cbmltcG9ydCB0eXBlIHtBbnlPYmplY3R9IGZyb20gJy4uL3R5cGVzL2Jhc2ljLmpzJztcbmltcG9ydCB0eXBlIHtBY3RpdmVEYXRhUG9pbnQsIENoYXJ0RXZlbnR9IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcblxuLyoqXG4gKiBBbiBlbXB0eSBmdW5jdGlvbiB0aGF0IGNhbiBiZSB1c2VkLCBmb3IgZXhhbXBsZSwgZm9yIG9wdGlvbmFsIGNhbGxiYWNrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9vcCgpIHtcbiAgLyogbm9vcCAqL1xufVxuXG4vKipcbiAqIFJldHVybnMgYSB1bmlxdWUgaWQsIHNlcXVlbnRpYWxseSBnZW5lcmF0ZWQgZnJvbSBhIGdsb2JhbCB2YXJpYWJsZS5cbiAqL1xuZXhwb3J0IGNvbnN0IHVpZCA9ICgoKSA9PiB7XG4gIGxldCBpZCA9IDA7XG4gIHJldHVybiAoKSA9PiBpZCsrO1xufSkoKTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgYHZhbHVlYCBpcyBuZWl0aGVyIG51bGwgbm9yIHVuZGVmaW5lZCwgZWxzZSByZXR1cm5zIGZhbHNlLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHRlc3QuXG4gKiBAc2luY2UgMi43LjBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTnVsbE9yVW5kZWYodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBudWxsIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCc7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXkgKGluY2x1ZGluZyB0eXBlZCBhcnJheXMpLCBlbHNlIHJldHVybnMgZmFsc2UuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdGVzdC5cbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBcnJheTxUID0gdW5rbm93bj4odmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBUW10ge1xuICBpZiAoQXJyYXkuaXNBcnJheSAmJiBBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGNvbnN0IHR5cGUgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICBpZiAodHlwZS5zbGljZSgwLCA3KSA9PT0gJ1tvYmplY3QnICYmIHR5cGUuc2xpY2UoLTYpID09PSAnQXJyYXldJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QgKGV4Y2x1ZGluZyBudWxsKSwgZWxzZSByZXR1cm5zIGZhbHNlLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHRlc3QuXG4gKiBAc2luY2UgMi43LjBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgQW55T2JqZWN0IHtcbiAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT09ICdbb2JqZWN0IE9iamVjdF0nO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBgdmFsdWVgIGlzIGEgZmluaXRlIG51bWJlciwgZWxzZSByZXR1cm5zIGZhbHNlXG4gKiBAcGFyYW0gdmFsdWUgIC0gVGhlIHZhbHVlIHRvIHRlc3QuXG4gKi9cbmZ1bmN0aW9uIGlzTnVtYmVyRmluaXRlKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgbnVtYmVyIHtcbiAgcmV0dXJuICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInIHx8IHZhbHVlIGluc3RhbmNlb2YgTnVtYmVyKSAmJiBpc0Zpbml0ZSgrdmFsdWUpO1xufVxuZXhwb3J0IHtcbiAgaXNOdW1iZXJGaW5pdGUgYXMgaXNGaW5pdGUsXG59O1xuXG4vKipcbiAqIFJldHVybnMgYHZhbHVlYCBpZiBmaW5pdGUsIGVsc2UgcmV0dXJucyBgZGVmYXVsdFZhbHVlYC5cbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byByZXR1cm4gaWYgZGVmaW5lZC5cbiAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgLSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIGB2YWx1ZWAgaXMgbm90IGZpbml0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbml0ZU9yRGVmYXVsdCh2YWx1ZTogdW5rbm93biwgZGVmYXVsdFZhbHVlOiBudW1iZXIpIHtcbiAgcmV0dXJuIGlzTnVtYmVyRmluaXRlKHZhbHVlKSA/IHZhbHVlIDogZGVmYXVsdFZhbHVlO1xufVxuXG4vKipcbiAqIFJldHVybnMgYHZhbHVlYCBpZiBkZWZpbmVkLCBlbHNlIHJldHVybnMgYGRlZmF1bHRWYWx1ZWAuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIGRlZmluZWQuXG4gKiBAcGFyYW0gZGVmYXVsdFZhbHVlIC0gVGhlIHZhbHVlIHRvIHJldHVybiBpZiBgdmFsdWVgIGlzIHVuZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbHVlT3JEZWZhdWx0PFQ+KHZhbHVlOiBUIHwgdW5kZWZpbmVkLCBkZWZhdWx0VmFsdWU6IFQpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcgPyBkZWZhdWx0VmFsdWUgOiB2YWx1ZTtcbn1cblxuZXhwb3J0IGNvbnN0IHRvUGVyY2VudGFnZSA9ICh2YWx1ZTogbnVtYmVyIHwgc3RyaW5nLCBkaW1lbnNpb246IG51bWJlcikgPT5cbiAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5lbmRzV2l0aCgnJScpID9cbiAgICBwYXJzZUZsb2F0KHZhbHVlKSAvIDEwMFxuICAgIDogK3ZhbHVlIC8gZGltZW5zaW9uO1xuXG5leHBvcnQgY29uc3QgdG9EaW1lbnNpb24gPSAodmFsdWU6IG51bWJlciB8IHN0cmluZywgZGltZW5zaW9uOiBudW1iZXIpID0+XG4gIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUuZW5kc1dpdGgoJyUnKSA/XG4gICAgcGFyc2VGbG9hdCh2YWx1ZSkgLyAxMDAgKiBkaW1lbnNpb25cbiAgICA6ICt2YWx1ZTtcblxuLyoqXG4gKiBDYWxscyBgZm5gIHdpdGggdGhlIGdpdmVuIGBhcmdzYCBpbiB0aGUgc2NvcGUgZGVmaW5lZCBieSBgdGhpc0FyZ2AgYW5kIHJldHVybnMgdGhlXG4gKiB2YWx1ZSByZXR1cm5lZCBieSBgZm5gLiBJZiBgZm5gIGlzIG5vdCBhIGZ1bmN0aW9uLCB0aGlzIG1ldGhvZCByZXR1cm5zIHVuZGVmaW5lZC5cbiAqIEBwYXJhbSBmbiAtIFRoZSBmdW5jdGlvbiB0byBjYWxsLlxuICogQHBhcmFtIGFyZ3MgLSBUaGUgYXJndW1lbnRzIHdpdGggd2hpY2ggYGZuYCBzaG91bGQgYmUgY2FsbGVkLlxuICogQHBhcmFtIFt0aGlzQXJnXSAtIFRoZSB2YWx1ZSBvZiBgdGhpc2AgcHJvdmlkZWQgZm9yIHRoZSBjYWxsIHRvIGBmbmAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxsYmFjazxUIGV4dGVuZHMgKHRoaXM6IFRBLCAuLi5yZXN0QXJnczogdW5rbm93bltdKSA9PiBSLCBUQSwgUj4oXG4gIGZuOiBUIHwgdW5kZWZpbmVkLFxuICBhcmdzOiB1bmtub3duW10sXG4gIHRoaXNBcmc/OiBUQVxuKTogUiB8IHVuZGVmaW5lZCB7XG4gIGlmIChmbiAmJiB0eXBlb2YgZm4uY2FsbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgfVxufVxuXG4vKipcbiAqIE5vdGUoU0IpIGZvciBwZXJmb3JtYW5jZSBzYWtlLCB0aGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSB1c2VkIHdoZW4gbG9vcGFibGUgdHlwZVxuICogaXMgdW5rbm93biBvciBpbiBub25lIGludGVuc2l2ZSBjb2RlIChub3QgY2FsbGVkIG9mdGVuIGFuZCBzbWFsbCBsb29wYWJsZSkuIEVsc2VcbiAqIGl0J3MgcHJlZmVyYWJsZSB0byB1c2UgYSByZWd1bGFyIGZvcigpIGxvb3AgYW5kIHNhdmUgZXh0cmEgZnVuY3Rpb24gY2FsbHMuXG4gKiBAcGFyYW0gbG9vcGFibGUgLSBUaGUgb2JqZWN0IG9yIGFycmF5IHRvIGJlIGl0ZXJhdGVkLlxuICogQHBhcmFtIGZuIC0gVGhlIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggaXRlbS5cbiAqIEBwYXJhbSBbdGhpc0FyZ10gLSBUaGUgdmFsdWUgb2YgYHRoaXNgIHByb3ZpZGVkIGZvciB0aGUgY2FsbCB0byBgZm5gLlxuICogQHBhcmFtIFtyZXZlcnNlXSAtIElmIHRydWUsIGl0ZXJhdGVzIGJhY2t3YXJkIG9uIHRoZSBsb29wYWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVhY2g8VCwgVEE+KFxuICBsb29wYWJsZTogUmVjb3JkPHN0cmluZywgVD4sXG4gIGZuOiAodGhpczogVEEsIHY6IFQsIGk6IHN0cmluZykgPT4gdm9pZCxcbiAgdGhpc0FyZz86IFRBLFxuICByZXZlcnNlPzogYm9vbGVhblxuKTogdm9pZDtcbmV4cG9ydCBmdW5jdGlvbiBlYWNoPFQsIFRBPihcbiAgbG9vcGFibGU6IFRbXSxcbiAgZm46ICh0aGlzOiBUQSwgdjogVCwgaTogbnVtYmVyKSA9PiB2b2lkLFxuICB0aGlzQXJnPzogVEEsXG4gIHJldmVyc2U/OiBib29sZWFuXG4pOiB2b2lkO1xuZXhwb3J0IGZ1bmN0aW9uIGVhY2g8VCwgVEE+KFxuICBsb29wYWJsZTogVFtdIHwgUmVjb3JkPHN0cmluZywgVD4sXG4gIGZuOiAodGhpczogVEEsIHY6IFQsIGk6IGFueSkgPT4gdm9pZCxcbiAgdGhpc0FyZz86IFRBLFxuICByZXZlcnNlPzogYm9vbGVhblxuKSB7XG4gIGxldCBpOiBudW1iZXIsIGxlbjogbnVtYmVyLCBrZXlzOiBzdHJpbmdbXTtcbiAgaWYgKGlzQXJyYXkobG9vcGFibGUpKSB7XG4gICAgbGVuID0gbG9vcGFibGUubGVuZ3RoO1xuICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBmbi5jYWxsKHRoaXNBcmcsIGxvb3BhYmxlW2ldLCBpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIGZuLmNhbGwodGhpc0FyZywgbG9vcGFibGVbaV0sIGkpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChsb29wYWJsZSkpIHtcbiAgICBrZXlzID0gT2JqZWN0LmtleXMobG9vcGFibGUpO1xuICAgIGxlbiA9IGtleXMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgZm4uY2FsbCh0aGlzQXJnLCBsb29wYWJsZVtrZXlzW2ldXSwga2V5c1tpXSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBgYTBgIGFuZCBgYTFgIGFycmF5cyBoYXZlIHRoZSBzYW1lIGNvbnRlbnQsIGVsc2UgcmV0dXJucyBmYWxzZS5cbiAqIEBwYXJhbSBhMCAtIFRoZSBhcnJheSB0byBjb21wYXJlXG4gKiBAcGFyYW0gYTEgLSBUaGUgYXJyYXkgdG8gY29tcGFyZVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9lbGVtZW50c0VxdWFsKGEwOiBBY3RpdmVEYXRhUG9pbnRbXSwgYTE6IEFjdGl2ZURhdGFQb2ludFtdKSB7XG4gIGxldCBpOiBudW1iZXIsIGlsZW46IG51bWJlciwgdjA6IEFjdGl2ZURhdGFQb2ludCwgdjE6IEFjdGl2ZURhdGFQb2ludDtcblxuICBpZiAoIWEwIHx8ICFhMSB8fCBhMC5sZW5ndGggIT09IGExLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZvciAoaSA9IDAsIGlsZW4gPSBhMC5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICB2MCA9IGEwW2ldO1xuICAgIHYxID0gYTFbaV07XG5cbiAgICBpZiAodjAuZGF0YXNldEluZGV4ICE9PSB2MS5kYXRhc2V0SW5kZXggfHwgdjAuaW5kZXggIT09IHYxLmluZGV4KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGRlZXAgY29weSBvZiBgc291cmNlYCB3aXRob3V0IGtlZXBpbmcgcmVmZXJlbmNlcyBvbiBvYmplY3RzIGFuZCBhcnJheXMuXG4gKiBAcGFyYW0gc291cmNlIC0gVGhlIHZhbHVlIHRvIGNsb25lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xvbmU8VD4oc291cmNlOiBUKTogVCB7XG4gIGlmIChpc0FycmF5KHNvdXJjZSkpIHtcbiAgICByZXR1cm4gc291cmNlLm1hcChjbG9uZSkgYXMgdW5rbm93biBhcyBUO1xuICB9XG5cbiAgaWYgKGlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpO1xuICAgIGNvbnN0IGtsZW4gPSBrZXlzLmxlbmd0aDtcbiAgICBsZXQgayA9IDA7XG5cbiAgICBmb3IgKDsgayA8IGtsZW47ICsraykge1xuICAgICAgdGFyZ2V0W2tleXNba11dID0gY2xvbmUoc291cmNlW2tleXNba11dKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG5cbiAgcmV0dXJuIHNvdXJjZTtcbn1cblxuZnVuY3Rpb24gaXNWYWxpZEtleShrZXk6IHN0cmluZykge1xuICByZXR1cm4gWydfX3Byb3RvX18nLCAncHJvdG90eXBlJywgJ2NvbnN0cnVjdG9yJ10uaW5kZXhPZihrZXkpID09PSAtMTtcbn1cblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBtZXJnZXIgd2hlbiBDaGFydC5oZWxwZXJzLm1lcmdlIGlzIGNhbGxlZCB3aXRob3V0IG1lcmdlciBvcHRpb24uXG4gKiBOb3RlKFNCKTogYWxzbyB1c2VkIGJ5IG1lcmdlQ29uZmlnIGFuZCBtZXJnZVNjYWxlQ29uZmlnIGFzIGZhbGxiYWNrLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9tZXJnZXIoa2V5OiBzdHJpbmcsIHRhcmdldDogQW55T2JqZWN0LCBzb3VyY2U6IEFueU9iamVjdCwgb3B0aW9uczogQW55T2JqZWN0KSB7XG4gIGlmICghaXNWYWxpZEtleShrZXkpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgdHZhbCA9IHRhcmdldFtrZXldO1xuICBjb25zdCBzdmFsID0gc291cmNlW2tleV07XG5cbiAgaWYgKGlzT2JqZWN0KHR2YWwpICYmIGlzT2JqZWN0KHN2YWwpKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11c2UtYmVmb3JlLWRlZmluZVxuICAgIG1lcmdlKHR2YWwsIHN2YWwsIG9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIHRhcmdldFtrZXldID0gY2xvbmUoc3ZhbCk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBNZXJnZU9wdGlvbnMge1xuICBtZXJnZXI/OiAoa2V5OiBzdHJpbmcsIHRhcmdldDogQW55T2JqZWN0LCBzb3VyY2U6IEFueU9iamVjdCwgb3B0aW9ucz86IEFueU9iamVjdCkgPT4gdm9pZDtcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBkZWVwIGNvcGllcyBgc291cmNlYCBwcm9wZXJ0aWVzIGludG8gYHRhcmdldGAgd2l0aCB0aGUgZ2l2ZW4gYG9wdGlvbnNgLlxuICogSU1QT1JUQU5UOiBgdGFyZ2V0YCBpcyBub3QgY2xvbmVkIGFuZCB3aWxsIGJlIHVwZGF0ZWQgd2l0aCBgc291cmNlYCBwcm9wZXJ0aWVzLlxuICogQHBhcmFtIHRhcmdldCAtIFRoZSB0YXJnZXQgb2JqZWN0IGluIHdoaWNoIGFsbCBzb3VyY2VzIGFyZSBtZXJnZWQgaW50by5cbiAqIEBwYXJhbSBzb3VyY2UgLSBPYmplY3QocykgdG8gbWVyZ2UgaW50byBgdGFyZ2V0YC5cbiAqIEBwYXJhbSBbb3B0aW9uc10gLSBNZXJnaW5nIG9wdGlvbnM6XG4gKiBAcGFyYW0gW29wdGlvbnMubWVyZ2VyXSAtIFRoZSBtZXJnZSBtZXRob2QgKGtleSwgdGFyZ2V0LCBzb3VyY2UsIG9wdGlvbnMpXG4gKiBAcmV0dXJucyBUaGUgYHRhcmdldGAgb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2U8VD4odGFyZ2V0OiBULCBzb3VyY2U6IFtdLCBvcHRpb25zPzogTWVyZ2VPcHRpb25zKTogVDtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZTxULCBTMT4odGFyZ2V0OiBULCBzb3VyY2U6IFMxLCBvcHRpb25zPzogTWVyZ2VPcHRpb25zKTogVCAmIFMxO1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlPFQsIFMxPih0YXJnZXQ6IFQsIHNvdXJjZTogW1MxXSwgb3B0aW9ucz86IE1lcmdlT3B0aW9ucyk6IFQgJiBTMTtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZTxULCBTMSwgUzI+KHRhcmdldDogVCwgc291cmNlOiBbUzEsIFMyXSwgb3B0aW9ucz86IE1lcmdlT3B0aW9ucyk6IFQgJiBTMSAmIFMyO1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlPFQsIFMxLCBTMiwgUzM+KHRhcmdldDogVCwgc291cmNlOiBbUzEsIFMyLCBTM10sIG9wdGlvbnM/OiBNZXJnZU9wdGlvbnMpOiBUICYgUzEgJiBTMiAmIFMzO1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlPFQsIFMxLCBTMiwgUzMsIFM0PihcbiAgdGFyZ2V0OiBULFxuICBzb3VyY2U6IFtTMSwgUzIsIFMzLCBTNF0sXG4gIG9wdGlvbnM/OiBNZXJnZU9wdGlvbnNcbik6IFQgJiBTMSAmIFMyICYgUzMgJiBTNDtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZTxUPih0YXJnZXQ6IFQsIHNvdXJjZTogQW55T2JqZWN0W10sIG9wdGlvbnM/OiBNZXJnZU9wdGlvbnMpOiBBbnlPYmplY3Q7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2U8VD4odGFyZ2V0OiBULCBzb3VyY2U6IEFueU9iamVjdFtdLCBvcHRpb25zPzogTWVyZ2VPcHRpb25zKTogQW55T2JqZWN0IHtcbiAgY29uc3Qgc291cmNlcyA9IGlzQXJyYXkoc291cmNlKSA/IHNvdXJjZSA6IFtzb3VyY2VdO1xuICBjb25zdCBpbGVuID0gc291cmNlcy5sZW5ndGg7XG5cbiAgaWYgKCFpc09iamVjdCh0YXJnZXQpKSB7XG4gICAgcmV0dXJuIHRhcmdldCBhcyBBbnlPYmplY3Q7XG4gIH1cblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgY29uc3QgbWVyZ2VyID0gb3B0aW9ucy5tZXJnZXIgfHwgX21lcmdlcjtcbiAgbGV0IGN1cnJlbnQ6IEFueU9iamVjdDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGlsZW47ICsraSkge1xuICAgIGN1cnJlbnQgPSBzb3VyY2VzW2ldO1xuICAgIGlmICghaXNPYmplY3QoY3VycmVudCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhjdXJyZW50KTtcbiAgICBmb3IgKGxldCBrID0gMCwga2xlbiA9IGtleXMubGVuZ3RoOyBrIDwga2xlbjsgKytrKSB7XG4gICAgICBtZXJnZXIoa2V5c1trXSwgdGFyZ2V0LCBjdXJyZW50LCBvcHRpb25zIGFzIEFueU9iamVjdCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBkZWVwIGNvcGllcyBgc291cmNlYCBwcm9wZXJ0aWVzIGludG8gYHRhcmdldGAgKm9ubHkqIGlmIG5vdCBkZWZpbmVkIGluIHRhcmdldC5cbiAqIElNUE9SVEFOVDogYHRhcmdldGAgaXMgbm90IGNsb25lZCBhbmQgd2lsbCBiZSB1cGRhdGVkIHdpdGggYHNvdXJjZWAgcHJvcGVydGllcy5cbiAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgdGFyZ2V0IG9iamVjdCBpbiB3aGljaCBhbGwgc291cmNlcyBhcmUgbWVyZ2VkIGludG8uXG4gKiBAcGFyYW0gc291cmNlIC0gT2JqZWN0KHMpIHRvIG1lcmdlIGludG8gYHRhcmdldGAuXG4gKiBAcmV0dXJucyBUaGUgYHRhcmdldGAgb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VJZjxUPih0YXJnZXQ6IFQsIHNvdXJjZTogW10pOiBUO1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlSWY8VCwgUzE+KHRhcmdldDogVCwgc291cmNlOiBTMSk6IFQgJiBTMTtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUlmPFQsIFMxPih0YXJnZXQ6IFQsIHNvdXJjZTogW1MxXSk6IFQgJiBTMTtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUlmPFQsIFMxLCBTMj4odGFyZ2V0OiBULCBzb3VyY2U6IFtTMSwgUzJdKTogVCAmIFMxICYgUzI7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VJZjxULCBTMSwgUzIsIFMzPih0YXJnZXQ6IFQsIHNvdXJjZTogW1MxLCBTMiwgUzNdKTogVCAmIFMxICYgUzIgJiBTMztcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUlmPFQsIFMxLCBTMiwgUzMsIFM0Pih0YXJnZXQ6IFQsIHNvdXJjZTogW1MxLCBTMiwgUzMsIFM0XSk6IFQgJiBTMSAmIFMyICYgUzMgJiBTNDtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUlmPFQ+KHRhcmdldDogVCwgc291cmNlOiBBbnlPYmplY3RbXSk6IEFueU9iamVjdDtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUlmPFQ+KHRhcmdldDogVCwgc291cmNlOiBBbnlPYmplY3RbXSk6IEFueU9iamVjdCB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgcmV0dXJuIG1lcmdlPFQ+KHRhcmdldCwgc291cmNlLCB7bWVyZ2VyOiBfbWVyZ2VySWZ9KTtcbn1cblxuLyoqXG4gKiBNZXJnZXMgc291cmNlW2tleV0gaW4gdGFyZ2V0W2tleV0gb25seSBpZiB0YXJnZXRba2V5XSBpcyB1bmRlZmluZWQuXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX21lcmdlcklmKGtleTogc3RyaW5nLCB0YXJnZXQ6IEFueU9iamVjdCwgc291cmNlOiBBbnlPYmplY3QpIHtcbiAgaWYgKCFpc1ZhbGlkS2V5KGtleSkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB0dmFsID0gdGFyZ2V0W2tleV07XG4gIGNvbnN0IHN2YWwgPSBzb3VyY2Vba2V5XTtcblxuICBpZiAoaXNPYmplY3QodHZhbCkgJiYgaXNPYmplY3Qoc3ZhbCkpIHtcbiAgICBtZXJnZUlmKHR2YWwsIHN2YWwpO1xuICB9IGVsc2UgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGFyZ2V0LCBrZXkpKSB7XG4gICAgdGFyZ2V0W2tleV0gPSBjbG9uZShzdmFsKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfZGVwcmVjYXRlZChzY29wZTogc3RyaW5nLCB2YWx1ZTogdW5rbm93biwgcHJldmlvdXM6IHN0cmluZywgY3VycmVudDogc3RyaW5nKSB7XG4gIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc29sZS53YXJuKHNjb3BlICsgJzogXCInICsgcHJldmlvdXMgK1xuICAgICAgJ1wiIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgXCInICsgY3VycmVudCArICdcIiBpbnN0ZWFkJyk7XG4gIH1cbn1cblxuLy8gcmVzb2x2ZU9iamVjdEtleSByZXNvbHZlciBjYWNoZVxuY29uc3Qga2V5UmVzb2x2ZXJzID0ge1xuICAvLyBDaGFydC5oZWxwZXJzLmNvcmUgcmVzb2x2ZU9iamVjdEtleSBzaG91bGQgcmVzb2x2ZSBlbXB0eSBrZXkgdG8gcm9vdCBvYmplY3RcbiAgJyc6IHYgPT4gdixcbiAgLy8gZGVmYXVsdCByZXNvbHZlcnNcbiAgeDogbyA9PiBvLngsXG4gIHk6IG8gPT4gby55XG59O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc3BsaXRLZXkoa2V5OiBzdHJpbmcpIHtcbiAgY29uc3QgcGFydHMgPSBrZXkuc3BsaXQoJy4nKTtcbiAgY29uc3Qga2V5czogc3RyaW5nW10gPSBbXTtcbiAgbGV0IHRtcCA9ICcnO1xuICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICB0bXAgKz0gcGFydDtcbiAgICBpZiAodG1wLmVuZHNXaXRoKCdcXFxcJykpIHtcbiAgICAgIHRtcCA9IHRtcC5zbGljZSgwLCAtMSkgKyAnLic7XG4gICAgfSBlbHNlIHtcbiAgICAgIGtleXMucHVzaCh0bXApO1xuICAgICAgdG1wID0gJyc7XG4gICAgfVxuICB9XG4gIHJldHVybiBrZXlzO1xufVxuXG5mdW5jdGlvbiBfZ2V0S2V5UmVzb2x2ZXIoa2V5OiBzdHJpbmcpIHtcbiAgY29uc3Qga2V5cyA9IF9zcGxpdEtleShrZXkpO1xuICByZXR1cm4gb2JqID0+IHtcbiAgICBmb3IgKGNvbnN0IGsgb2Yga2V5cykge1xuICAgICAgaWYgKGsgPT09ICcnKSB7XG4gICAgICAgIC8vIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5OlxuICAgICAgICAvLyBDaGFydC5oZWxwZXJzLmNvcmUgcmVzb2x2ZU9iamVjdEtleSBzaG91bGQgYnJlYWsgYXQgZW1wdHkga2V5XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgb2JqID0gb2JqICYmIG9ialtrXTtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVPYmplY3RLZXkob2JqOiBBbnlPYmplY3QsIGtleTogc3RyaW5nKTogYW55IHtcbiAgY29uc3QgcmVzb2x2ZXIgPSBrZXlSZXNvbHZlcnNba2V5XSB8fCAoa2V5UmVzb2x2ZXJzW2tleV0gPSBfZ2V0S2V5UmVzb2x2ZXIoa2V5KSk7XG4gIHJldHVybiByZXNvbHZlcihvYmopO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfY2FwaXRhbGl6ZShzdHI6IHN0cmluZykge1xuICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xufVxuXG5cbmV4cG9ydCBjb25zdCBkZWZpbmVkID0gKHZhbHVlOiB1bmtub3duKSA9PiB0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnO1xuXG5leHBvcnQgY29uc3QgaXNGdW5jdGlvbiA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzICguLi5hcmdzOiBhbnlbXSkgPT4gYW55ID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJztcblxuLy8gQWRhcHRlZCBmcm9tIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzMxMTI4ODU1L2NvbXBhcmluZy1lY21hNi1zZXRzLWZvci1lcXVhbGl0eSMzMTEyOTM4NFxuZXhwb3J0IGNvbnN0IHNldHNFcXVhbCA9IDxUPihhOiBTZXQ8VD4sIGI6IFNldDxUPikgPT4ge1xuICBpZiAoYS5zaXplICE9PSBiLnNpemUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3IgKGNvbnN0IGl0ZW0gb2YgYSkge1xuICAgIGlmICghYi5oYXMoaXRlbSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogQHBhcmFtIGUgLSBUaGUgZXZlbnRcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfaXNDbGlja0V2ZW50KGU6IENoYXJ0RXZlbnQpIHtcbiAgcmV0dXJuIGUudHlwZSA9PT0gJ21vdXNldXAnIHx8IGUudHlwZSA9PT0gJ2NsaWNrJyB8fCBlLnR5cGUgPT09ICdjb250ZXh0bWVudSc7XG59XG4iLCAiaW1wb3J0IHR5cGUge1BvaW50fSBmcm9tICcuLi90eXBlcy9nZW9tZXRyaWMuanMnO1xuaW1wb3J0IHtpc0Zpbml0ZSBhcyBpc0Zpbml0ZU51bWJlcn0gZnJvbSAnLi9oZWxwZXJzLmNvcmUuanMnO1xuXG4vKipcbiAqIEBhbGlhcyBDaGFydC5oZWxwZXJzLm1hdGhcbiAqIEBuYW1lc3BhY2VcbiAqL1xuXG5leHBvcnQgY29uc3QgUEkgPSBNYXRoLlBJO1xuZXhwb3J0IGNvbnN0IFRBVSA9IDIgKiBQSTtcbmV4cG9ydCBjb25zdCBQSVRBVSA9IFRBVSArIFBJO1xuZXhwb3J0IGNvbnN0IElORklOSVRZID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuZXhwb3J0IGNvbnN0IFJBRF9QRVJfREVHID0gUEkgLyAxODA7XG5leHBvcnQgY29uc3QgSEFMRl9QSSA9IFBJIC8gMjtcbmV4cG9ydCBjb25zdCBRVUFSVEVSX1BJID0gUEkgLyA0O1xuZXhwb3J0IGNvbnN0IFRXT19USElSRFNfUEkgPSBQSSAqIDIgLyAzO1xuXG5leHBvcnQgY29uc3QgbG9nMTAgPSBNYXRoLmxvZzEwO1xuZXhwb3J0IGNvbnN0IHNpZ24gPSBNYXRoLnNpZ247XG5cbmV4cG9ydCBmdW5jdGlvbiBhbG1vc3RFcXVhbHMoeDogbnVtYmVyLCB5OiBudW1iZXIsIGVwc2lsb246IG51bWJlcikge1xuICByZXR1cm4gTWF0aC5hYnMoeCAtIHkpIDwgZXBzaWxvbjtcbn1cblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgbmljZSBudW1iZXIgYWxnb3JpdGhtIHVzZWQgaW4gZGV0ZXJtaW5pbmcgd2hlcmUgYXhpcyBsYWJlbHMgd2lsbCBnb1xuICovXG5leHBvcnQgZnVuY3Rpb24gbmljZU51bShyYW5nZTogbnVtYmVyKSB7XG4gIGNvbnN0IHJvdW5kZWRSYW5nZSA9IE1hdGgucm91bmQocmFuZ2UpO1xuICByYW5nZSA9IGFsbW9zdEVxdWFscyhyYW5nZSwgcm91bmRlZFJhbmdlLCByYW5nZSAvIDEwMDApID8gcm91bmRlZFJhbmdlIDogcmFuZ2U7XG4gIGNvbnN0IG5pY2VSYW5nZSA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKGxvZzEwKHJhbmdlKSkpO1xuICBjb25zdCBmcmFjdGlvbiA9IHJhbmdlIC8gbmljZVJhbmdlO1xuICBjb25zdCBuaWNlRnJhY3Rpb24gPSBmcmFjdGlvbiA8PSAxID8gMSA6IGZyYWN0aW9uIDw9IDIgPyAyIDogZnJhY3Rpb24gPD0gNSA/IDUgOiAxMDtcbiAgcmV0dXJuIG5pY2VGcmFjdGlvbiAqIG5pY2VSYW5nZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIGFycmF5IG9mIGZhY3RvcnMgc29ydGVkIGZyb20gMSB0byBzcXJ0KHZhbHVlKVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9mYWN0b3JpemUodmFsdWU6IG51bWJlcikge1xuICBjb25zdCByZXN1bHQ6IG51bWJlcltdID0gW107XG4gIGNvbnN0IHNxcnQgPSBNYXRoLnNxcnQodmFsdWUpO1xuICBsZXQgaTogbnVtYmVyO1xuXG4gIGZvciAoaSA9IDE7IGkgPCBzcXJ0OyBpKyspIHtcbiAgICBpZiAodmFsdWUgJSBpID09PSAwKSB7XG4gICAgICByZXN1bHQucHVzaChpKTtcbiAgICAgIHJlc3VsdC5wdXNoKHZhbHVlIC8gaSk7XG4gICAgfVxuICB9XG4gIGlmIChzcXJ0ID09PSAoc3FydCB8IDApKSB7IC8vIGlmIHZhbHVlIGlzIGEgc3F1YXJlIG51bWJlclxuICAgIHJlc3VsdC5wdXNoKHNxcnQpO1xuICB9XG5cbiAgcmVzdWx0LnNvcnQoKGEsIGIpID0+IGEgLSBiKS5wb3AoKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTnVtYmVyKG46IHVua25vd24pOiBuIGlzIG51bWJlciB7XG4gIHJldHVybiAhaXNOYU4ocGFyc2VGbG9hdChuIGFzIHN0cmluZykpICYmIGlzRmluaXRlKG4gYXMgbnVtYmVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbW9zdFdob2xlKHg6IG51bWJlciwgZXBzaWxvbjogbnVtYmVyKSB7XG4gIGNvbnN0IHJvdW5kZWQgPSBNYXRoLnJvdW5kKHgpO1xuICByZXR1cm4gKChyb3VuZGVkIC0gZXBzaWxvbikgPD0geCkgJiYgKChyb3VuZGVkICsgZXBzaWxvbikgPj0geCk7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9zZXRNaW5BbmRNYXhCeUtleShcbiAgYXJyYXk6IFJlY29yZDxzdHJpbmcsIG51bWJlcj5bXSxcbiAgdGFyZ2V0OiB7IG1pbjogbnVtYmVyLCBtYXg6IG51bWJlciB9LFxuICBwcm9wZXJ0eTogc3RyaW5nXG4pIHtcbiAgbGV0IGk6IG51bWJlciwgaWxlbjogbnVtYmVyLCB2YWx1ZTogbnVtYmVyO1xuXG4gIGZvciAoaSA9IDAsIGlsZW4gPSBhcnJheS5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcbiAgICB2YWx1ZSA9IGFycmF5W2ldW3Byb3BlcnR5XTtcbiAgICBpZiAoIWlzTmFOKHZhbHVlKSkge1xuICAgICAgdGFyZ2V0Lm1pbiA9IE1hdGgubWluKHRhcmdldC5taW4sIHZhbHVlKTtcbiAgICAgIHRhcmdldC5tYXggPSBNYXRoLm1heCh0YXJnZXQubWF4LCB2YWx1ZSk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b1JhZGlhbnMoZGVncmVlczogbnVtYmVyKSB7XG4gIHJldHVybiBkZWdyZWVzICogKFBJIC8gMTgwKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRvRGVncmVlcyhyYWRpYW5zOiBudW1iZXIpIHtcbiAgcmV0dXJuIHJhZGlhbnMgKiAoMTgwIC8gUEkpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlc1xuICogaS5lLiB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludCwgb2YgdGhlIHZhbHVlIG9mIHRoaXMgTnVtYmVyLlxuICogQHBhcmFtIHggLSBBIG51bWJlci5cbiAqIEByZXR1cm5zIFRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMuXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2RlY2ltYWxQbGFjZXMoeDogbnVtYmVyKSB7XG4gIGlmICghaXNGaW5pdGVOdW1iZXIoeCkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IGUgPSAxO1xuICBsZXQgcCA9IDA7XG4gIHdoaWxlIChNYXRoLnJvdW5kKHggKiBlKSAvIGUgIT09IHgpIHtcbiAgICBlICo9IDEwO1xuICAgIHArKztcbiAgfVxuICByZXR1cm4gcDtcbn1cblxuLy8gR2V0cyB0aGUgYW5nbGUgZnJvbSB2ZXJ0aWNhbCB1cHJpZ2h0IHRvIHRoZSBwb2ludCBhYm91dCBhIGNlbnRyZS5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBbmdsZUZyb21Qb2ludChcbiAgY2VudHJlUG9pbnQ6IFBvaW50LFxuICBhbmdsZVBvaW50OiBQb2ludFxuKSB7XG4gIGNvbnN0IGRpc3RhbmNlRnJvbVhDZW50ZXIgPSBhbmdsZVBvaW50LnggLSBjZW50cmVQb2ludC54O1xuICBjb25zdCBkaXN0YW5jZUZyb21ZQ2VudGVyID0gYW5nbGVQb2ludC55IC0gY2VudHJlUG9pbnQueTtcbiAgY29uc3QgcmFkaWFsRGlzdGFuY2VGcm9tQ2VudGVyID0gTWF0aC5zcXJ0KGRpc3RhbmNlRnJvbVhDZW50ZXIgKiBkaXN0YW5jZUZyb21YQ2VudGVyICsgZGlzdGFuY2VGcm9tWUNlbnRlciAqIGRpc3RhbmNlRnJvbVlDZW50ZXIpO1xuXG4gIGxldCBhbmdsZSA9IE1hdGguYXRhbjIoZGlzdGFuY2VGcm9tWUNlbnRlciwgZGlzdGFuY2VGcm9tWENlbnRlcik7XG5cbiAgaWYgKGFuZ2xlIDwgKC0wLjUgKiBQSSkpIHtcbiAgICBhbmdsZSArPSBUQVU7IC8vIG1ha2Ugc3VyZSB0aGUgcmV0dXJuZWQgYW5nbGUgaXMgaW4gdGhlIHJhbmdlIG9mICgtUEkvMiwgM1BJLzJdXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFuZ2xlLFxuICAgIGRpc3RhbmNlOiByYWRpYWxEaXN0YW5jZUZyb21DZW50ZXJcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRpc3RhbmNlQmV0d2VlblBvaW50cyhwdDE6IFBvaW50LCBwdDI6IFBvaW50KSB7XG4gIHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3cocHQyLnggLSBwdDEueCwgMikgKyBNYXRoLnBvdyhwdDIueSAtIHB0MS55LCAyKSk7XG59XG5cbi8qKlxuICogU2hvcnRlc3QgZGlzdGFuY2UgYmV0d2VlbiBhbmdsZXMsIGluIGVpdGhlciBkaXJlY3Rpb24uXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2FuZ2xlRGlmZihhOiBudW1iZXIsIGI6IG51bWJlcikge1xuICByZXR1cm4gKGEgLSBiICsgUElUQVUpICUgVEFVIC0gUEk7XG59XG5cbi8qKlxuICogTm9ybWFsaXplIGFuZ2xlIHRvIGJlIGJldHdlZW4gMCBhbmQgMipQSVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9ub3JtYWxpemVBbmdsZShhOiBudW1iZXIpIHtcbiAgcmV0dXJuIChhICUgVEFVICsgVEFVKSAlIFRBVTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2FuZ2xlQmV0d2VlbihhbmdsZTogbnVtYmVyLCBzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciwgc2FtZUFuZ2xlSXNGdWxsQ2lyY2xlPzogYm9vbGVhbikge1xuICBjb25zdCBhID0gX25vcm1hbGl6ZUFuZ2xlKGFuZ2xlKTtcbiAgY29uc3QgcyA9IF9ub3JtYWxpemVBbmdsZShzdGFydCk7XG4gIGNvbnN0IGUgPSBfbm9ybWFsaXplQW5nbGUoZW5kKTtcbiAgY29uc3QgYW5nbGVUb1N0YXJ0ID0gX25vcm1hbGl6ZUFuZ2xlKHMgLSBhKTtcbiAgY29uc3QgYW5nbGVUb0VuZCA9IF9ub3JtYWxpemVBbmdsZShlIC0gYSk7XG4gIGNvbnN0IHN0YXJ0VG9BbmdsZSA9IF9ub3JtYWxpemVBbmdsZShhIC0gcyk7XG4gIGNvbnN0IGVuZFRvQW5nbGUgPSBfbm9ybWFsaXplQW5nbGUoYSAtIGUpO1xuICByZXR1cm4gYSA9PT0gcyB8fCBhID09PSBlIHx8IChzYW1lQW5nbGVJc0Z1bGxDaXJjbGUgJiYgcyA9PT0gZSlcbiAgICB8fCAoYW5nbGVUb1N0YXJ0ID4gYW5nbGVUb0VuZCAmJiBzdGFydFRvQW5nbGUgPCBlbmRUb0FuZ2xlKTtcbn1cblxuLyoqXG4gKiBMaW1pdCBgdmFsdWVgIGJldHdlZW4gYG1pbmAgYW5kIGBtYXhgXG4gKiBAcGFyYW0gdmFsdWVcbiAqIEBwYXJhbSBtaW5cbiAqIEBwYXJhbSBtYXhcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfbGltaXRWYWx1ZSh2YWx1ZTogbnVtYmVyLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIpIHtcbiAgcmV0dXJuIE1hdGgubWF4KG1pbiwgTWF0aC5taW4obWF4LCB2YWx1ZSkpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9pbnQxNlJhbmdlKHZhbHVlOiBudW1iZXIpIHtcbiAgcmV0dXJuIF9saW1pdFZhbHVlKHZhbHVlLCAtMzI3NjgsIDMyNzY3KTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gdmFsdWVcbiAqIEBwYXJhbSBzdGFydFxuICogQHBhcmFtIGVuZFxuICogQHBhcmFtIFtlcHNpbG9uXVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9pc0JldHdlZW4odmFsdWU6IG51bWJlciwgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIsIGVwc2lsb24gPSAxZS02KSB7XG4gIHJldHVybiB2YWx1ZSA+PSBNYXRoLm1pbihzdGFydCwgZW5kKSAtIGVwc2lsb24gJiYgdmFsdWUgPD0gTWF0aC5tYXgoc3RhcnQsIGVuZCkgKyBlcHNpbG9uO1xufVxuIiwgImltcG9ydCB7X2NhcGl0YWxpemV9IGZyb20gJy4vaGVscGVycy5jb3JlLmpzJztcblxuLyoqXG4gKiBCaW5hcnkgc2VhcmNoXG4gKiBAcGFyYW0gdGFibGUgLSB0aGUgdGFibGUgc2VhcmNoLiBtdXN0IGJlIHNvcnRlZCFcbiAqIEBwYXJhbSB2YWx1ZSAtIHZhbHVlIHRvIGZpbmRcbiAqIEBwYXJhbSBjbXBcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfbG9va3VwKFxuICB0YWJsZTogbnVtYmVyW10sXG4gIHZhbHVlOiBudW1iZXIsXG4gIGNtcD86ICh2YWx1ZTogbnVtYmVyKSA9PiBib29sZWFuXG4pOiB7bG86IG51bWJlciwgaGk6IG51bWJlcn07XG5leHBvcnQgZnVuY3Rpb24gX2xvb2t1cDxUPihcbiAgdGFibGU6IFRbXSxcbiAgdmFsdWU6IG51bWJlcixcbiAgY21wOiAodmFsdWU6IG51bWJlcikgPT4gYm9vbGVhblxuKToge2xvOiBudW1iZXIsIGhpOiBudW1iZXJ9O1xuZXhwb3J0IGZ1bmN0aW9uIF9sb29rdXAoXG4gIHRhYmxlOiB1bmtub3duW10sXG4gIHZhbHVlOiBudW1iZXIsXG4gIGNtcD86ICh2YWx1ZTogbnVtYmVyKSA9PiBib29sZWFuXG4pIHtcbiAgY21wID0gY21wIHx8ICgoaW5kZXgpID0+IHRhYmxlW2luZGV4XSA8IHZhbHVlKTtcbiAgbGV0IGhpID0gdGFibGUubGVuZ3RoIC0gMTtcbiAgbGV0IGxvID0gMDtcbiAgbGV0IG1pZDogbnVtYmVyO1xuXG4gIHdoaWxlIChoaSAtIGxvID4gMSkge1xuICAgIG1pZCA9IChsbyArIGhpKSA+PiAxO1xuICAgIGlmIChjbXAobWlkKSkge1xuICAgICAgbG8gPSBtaWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhpID0gbWlkO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7bG8sIGhpfTtcbn1cblxuLyoqXG4gKiBCaW5hcnkgc2VhcmNoXG4gKiBAcGFyYW0gdGFibGUgLSB0aGUgdGFibGUgc2VhcmNoLiBtdXN0IGJlIHNvcnRlZCFcbiAqIEBwYXJhbSBrZXkgLSBwcm9wZXJ0eSBuYW1lIGZvciB0aGUgdmFsdWUgaW4gZWFjaCBlbnRyeVxuICogQHBhcmFtIHZhbHVlIC0gdmFsdWUgdG8gZmluZFxuICogQHBhcmFtIGxhc3QgLSBsb29rdXAgbGFzdCBpbmRleFxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IF9sb29rdXBCeUtleSA9IChcbiAgdGFibGU6IFJlY29yZDxzdHJpbmcsIG51bWJlcj5bXSxcbiAga2V5OiBzdHJpbmcsXG4gIHZhbHVlOiBudW1iZXIsXG4gIGxhc3Q/OiBib29sZWFuXG4pID0+XG4gIF9sb29rdXAodGFibGUsIHZhbHVlLCBsYXN0XG4gICAgPyBpbmRleCA9PiB7XG4gICAgICBjb25zdCB0aSA9IHRhYmxlW2luZGV4XVtrZXldO1xuICAgICAgcmV0dXJuIHRpIDwgdmFsdWUgfHwgdGkgPT09IHZhbHVlICYmIHRhYmxlW2luZGV4ICsgMV1ba2V5XSA9PT0gdmFsdWU7XG4gICAgfVxuICAgIDogaW5kZXggPT4gdGFibGVbaW5kZXhdW2tleV0gPCB2YWx1ZSk7XG5cbi8qKlxuICogUmV2ZXJzZSBiaW5hcnkgc2VhcmNoXG4gKiBAcGFyYW0gdGFibGUgLSB0aGUgdGFibGUgc2VhcmNoLiBtdXN0IGJlIHNvcnRlZCFcbiAqIEBwYXJhbSBrZXkgLSBwcm9wZXJ0eSBuYW1lIGZvciB0aGUgdmFsdWUgaW4gZWFjaCBlbnRyeVxuICogQHBhcmFtIHZhbHVlIC0gdmFsdWUgdG8gZmluZFxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IF9ybG9va3VwQnlLZXkgPSAoXG4gIHRhYmxlOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+W10sXG4gIGtleTogc3RyaW5nLFxuICB2YWx1ZTogbnVtYmVyXG4pID0+XG4gIF9sb29rdXAodGFibGUsIHZhbHVlLCBpbmRleCA9PiB0YWJsZVtpbmRleF1ba2V5XSA+PSB2YWx1ZSk7XG5cbi8qKlxuICogUmV0dXJuIHN1YnNldCBvZiBgdmFsdWVzYCBiZXR3ZWVuIGBtaW5gIGFuZCBgbWF4YCBpbmNsdXNpdmUuXG4gKiBWYWx1ZXMgYXJlIGFzc3VtZWQgdG8gYmUgaW4gc29ydGVkIG9yZGVyLlxuICogQHBhcmFtIHZhbHVlcyAtIHNvcnRlZCBhcnJheSBvZiB2YWx1ZXNcbiAqIEBwYXJhbSBtaW4gLSBtaW4gdmFsdWVcbiAqIEBwYXJhbSBtYXggLSBtYXggdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9maWx0ZXJCZXR3ZWVuKHZhbHVlczogbnVtYmVyW10sIG1pbjogbnVtYmVyLCBtYXg6IG51bWJlcikge1xuICBsZXQgc3RhcnQgPSAwO1xuICBsZXQgZW5kID0gdmFsdWVzLmxlbmd0aDtcblxuICB3aGlsZSAoc3RhcnQgPCBlbmQgJiYgdmFsdWVzW3N0YXJ0XSA8IG1pbikge1xuICAgIHN0YXJ0Kys7XG4gIH1cbiAgd2hpbGUgKGVuZCA+IHN0YXJ0ICYmIHZhbHVlc1tlbmQgLSAxXSA+IG1heCkge1xuICAgIGVuZC0tO1xuICB9XG5cbiAgcmV0dXJuIHN0YXJ0ID4gMCB8fCBlbmQgPCB2YWx1ZXMubGVuZ3RoXG4gICAgPyB2YWx1ZXMuc2xpY2Uoc3RhcnQsIGVuZClcbiAgICA6IHZhbHVlcztcbn1cblxuY29uc3QgYXJyYXlFdmVudHMgPSBbJ3B1c2gnLCAncG9wJywgJ3NoaWZ0JywgJ3NwbGljZScsICd1bnNoaWZ0J10gYXMgY29uc3Q7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXJyYXlMaXN0ZW5lcjxUPiB7XG4gIF9vbkRhdGFQdXNoPyguLi5pdGVtOiBUW10pOiB2b2lkO1xuICBfb25EYXRhUG9wPygpOiB2b2lkO1xuICBfb25EYXRhU2hpZnQ/KCk6IHZvaWQ7XG4gIF9vbkRhdGFTcGxpY2U/KGluZGV4OiBudW1iZXIsIGRlbGV0ZUNvdW50OiBudW1iZXIsIC4uLml0ZW1zOiBUW10pOiB2b2lkO1xuICBfb25EYXRhVW5zaGlmdD8oLi4uaXRlbTogVFtdKTogdm9pZDtcbn1cblxuLyoqXG4gKiBIb29rcyB0aGUgYXJyYXkgbWV0aG9kcyB0aGF0IGFkZCBvciByZW1vdmUgdmFsdWVzICgncHVzaCcsIHBvcCcsICdzaGlmdCcsICdzcGxpY2UnLFxuICogJ3Vuc2hpZnQnKSBhbmQgbm90aWZ5IHRoZSBsaXN0ZW5lciBBRlRFUiB0aGUgYXJyYXkgaGFzIGJlZW4gYWx0ZXJlZC4gTGlzdGVuZXJzIGFyZVxuICogY2FsbGVkIG9uIHRoZSAnX29uRGF0YSonIGNhbGxiYWNrcyAoZS5nLiBfb25EYXRhUHVzaCwgZXRjLikgd2l0aCBzYW1lIGFyZ3VtZW50cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RlbkFycmF5RXZlbnRzPFQ+KGFycmF5OiBUW10sIGxpc3RlbmVyOiBBcnJheUxpc3RlbmVyPFQ+KTogdm9pZDtcbmV4cG9ydCBmdW5jdGlvbiBsaXN0ZW5BcnJheUV2ZW50cyhhcnJheSwgbGlzdGVuZXIpIHtcbiAgaWYgKGFycmF5Ll9jaGFydGpzKSB7XG4gICAgYXJyYXkuX2NoYXJ0anMubGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcnJheSwgJ19jaGFydGpzJywge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZToge1xuICAgICAgbGlzdGVuZXJzOiBbbGlzdGVuZXJdXG4gICAgfVxuICB9KTtcblxuICBhcnJheUV2ZW50cy5mb3JFYWNoKChrZXkpID0+IHtcbiAgICBjb25zdCBtZXRob2QgPSAnX29uRGF0YScgKyBfY2FwaXRhbGl6ZShrZXkpO1xuICAgIGNvbnN0IGJhc2UgPSBhcnJheVtrZXldO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGFycmF5LCBrZXksIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgdmFsdWUoLi4uYXJncykge1xuICAgICAgICBjb25zdCByZXMgPSBiYXNlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXG4gICAgICAgIGFycmF5Ll9jaGFydGpzLmxpc3RlbmVycy5mb3JFYWNoKChvYmplY3QpID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdFttZXRob2RdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBvYmplY3RbbWV0aG9kXSguLi5hcmdzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5cbi8qKlxuICogUmVtb3ZlcyB0aGUgZ2l2ZW4gYXJyYXkgZXZlbnQgbGlzdGVuZXIgYW5kIGNsZWFudXAgZXh0cmEgYXR0YWNoZWQgcHJvcGVydGllcyAoc3VjaCBhc1xuICogdGhlIF9jaGFydGpzIHN0dWIgYW5kIG92ZXJyaWRkZW4gbWV0aG9kcykgaWYgYXJyYXkgZG9lc24ndCBoYXZlIGFueSBtb3JlIGxpc3RlbmVycy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVubGlzdGVuQXJyYXlFdmVudHM8VD4oYXJyYXk6IFRbXSwgbGlzdGVuZXI6IEFycmF5TGlzdGVuZXI8VD4pOiB2b2lkO1xuZXhwb3J0IGZ1bmN0aW9uIHVubGlzdGVuQXJyYXlFdmVudHMoYXJyYXksIGxpc3RlbmVyKSB7XG4gIGNvbnN0IHN0dWIgPSBhcnJheS5fY2hhcnRqcztcbiAgaWYgKCFzdHViKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgbGlzdGVuZXJzID0gc3R1Yi5saXN0ZW5lcnM7XG4gIGNvbnN0IGluZGV4ID0gbGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xuICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XG4gIH1cblxuICBpZiAobGlzdGVuZXJzLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBhcnJheUV2ZW50cy5mb3JFYWNoKChrZXkpID0+IHtcbiAgICBkZWxldGUgYXJyYXlba2V5XTtcbiAgfSk7XG5cbiAgZGVsZXRlIGFycmF5Ll9jaGFydGpzO1xufVxuXG4vKipcbiAqIEBwYXJhbSBpdGVtc1xuICovXG5leHBvcnQgZnVuY3Rpb24gX2FycmF5VW5pcXVlPFQ+KGl0ZW1zOiBUW10pIHtcbiAgY29uc3Qgc2V0ID0gbmV3IFNldDxUPihpdGVtcyk7XG5cbiAgaWYgKHNldC5zaXplID09PSBpdGVtcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICByZXR1cm4gQXJyYXkuZnJvbShzZXQpO1xufVxuIiwgImltcG9ydCB0eXBlIHtDaGFydE1ldGEsIFBvaW50RWxlbWVudH0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuXG5pbXBvcnQge19saW1pdFZhbHVlfSBmcm9tICcuL2hlbHBlcnMubWF0aC5qcyc7XG5pbXBvcnQge19sb29rdXBCeUtleX0gZnJvbSAnLi9oZWxwZXJzLmNvbGxlY3Rpb24uanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZm9udFN0cmluZyhwaXhlbFNpemU6IG51bWJlciwgZm9udFN0eWxlOiBzdHJpbmcsIGZvbnRGYW1pbHk6IHN0cmluZykge1xuICByZXR1cm4gZm9udFN0eWxlICsgJyAnICsgcGl4ZWxTaXplICsgJ3B4ICcgKyBmb250RmFtaWx5O1xufVxuXG4vKipcbiogUmVxdWVzdCBhbmltYXRpb24gcG9seWZpbGxcbiovXG5leHBvcnQgY29uc3QgcmVxdWVzdEFuaW1GcmFtZSA9IChmdW5jdGlvbigpIHtcbiAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9O1xuICB9XG4gIHJldHVybiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xufSgpKTtcblxuLyoqXG4gKiBUaHJvdHRsZXMgY2FsbGluZyBgZm5gIG9uY2UgcGVyIGFuaW1hdGlvbiBmcmFtZVxuICogTGF0ZXN0IGFyZ3VtZW50cyBhcmUgdXNlZCBvbiB0aGUgYWN0dWFsIGNhbGxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRocm90dGxlZDxUQXJncyBleHRlbmRzIEFycmF5PGFueT4+KFxuICBmbjogKC4uLmFyZ3M6IFRBcmdzKSA9PiB2b2lkLFxuICB0aGlzQXJnOiBhbnksXG4pIHtcbiAgbGV0IGFyZ3NUb1VzZSA9IFtdIGFzIFRBcmdzO1xuICBsZXQgdGlja2luZyA9IGZhbHNlO1xuXG4gIHJldHVybiBmdW5jdGlvbiguLi5hcmdzOiBUQXJncykge1xuICAgIC8vIFNhdmUgdGhlIGFyZ3MgZm9yIHVzZSBsYXRlclxuICAgIGFyZ3NUb1VzZSA9IGFyZ3M7XG4gICAgaWYgKCF0aWNraW5nKSB7XG4gICAgICB0aWNraW5nID0gdHJ1ZTtcbiAgICAgIHJlcXVlc3RBbmltRnJhbWUuY2FsbCh3aW5kb3csICgpID0+IHtcbiAgICAgICAgdGlja2luZyA9IGZhbHNlO1xuICAgICAgICBmbi5hcHBseSh0aGlzQXJnLCBhcmdzVG9Vc2UpO1xuICAgICAgfSk7XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIERlYm91bmNlcyBjYWxsaW5nIGBmbmAgZm9yIGBkZWxheWAgbXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlYm91bmNlPFRBcmdzIGV4dGVuZHMgQXJyYXk8YW55Pj4oZm46ICguLi5hcmdzOiBUQXJncykgPT4gdm9pZCwgZGVsYXk6IG51bWJlcikge1xuICBsZXQgdGltZW91dDtcbiAgcmV0dXJuIGZ1bmN0aW9uKC4uLmFyZ3M6IFRBcmdzKSB7XG4gICAgaWYgKGRlbGF5KSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChmbiwgZGVsYXksIGFyZ3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlbGF5O1xuICB9O1xufVxuXG4vKipcbiAqIENvbnZlcnRzICdzdGFydCcgdG8gJ2xlZnQnLCAnZW5kJyB0byAncmlnaHQnIGFuZCBvdGhlcnMgdG8gJ2NlbnRlcidcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjb25zdCBfdG9MZWZ0UmlnaHRDZW50ZXIgPSAoYWxpZ246ICdzdGFydCcgfCAnZW5kJyB8ICdjZW50ZXInKSA9PiBhbGlnbiA9PT0gJ3N0YXJ0JyA/ICdsZWZ0JyA6IGFsaWduID09PSAnZW5kJyA/ICdyaWdodCcgOiAnY2VudGVyJztcblxuLyoqXG4gKiBSZXR1cm5zIGBzdGFydGAsIGBlbmRgIG9yIGAoc3RhcnQgKyBlbmQpIC8gMmAgZGVwZW5kaW5nIG9uIGBhbGlnbmAuIERlZmF1bHRzIHRvIGBjZW50ZXJgXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY29uc3QgX2FsaWduU3RhcnRFbmQgPSAoYWxpZ246ICdzdGFydCcgfCAnZW5kJyB8ICdjZW50ZXInLCBzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcikgPT4gYWxpZ24gPT09ICdzdGFydCcgPyBzdGFydCA6IGFsaWduID09PSAnZW5kJyA/IGVuZCA6IChzdGFydCArIGVuZCkgLyAyO1xuXG4vKipcbiAqIFJldHVybnMgYGxlZnRgLCBgcmlnaHRgIG9yIGAobGVmdCArIHJpZ2h0KSAvIDJgIGRlcGVuZGluZyBvbiBgYWxpZ25gLiBEZWZhdWx0cyB0byBgbGVmdGBcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjb25zdCBfdGV4dFggPSAoYWxpZ246ICdsZWZ0JyB8ICdyaWdodCcgfCAnY2VudGVyJywgbGVmdDogbnVtYmVyLCByaWdodDogbnVtYmVyLCBydGw6IGJvb2xlYW4pID0+IHtcbiAgY29uc3QgY2hlY2sgPSBydGwgPyAnbGVmdCcgOiAncmlnaHQnO1xuICByZXR1cm4gYWxpZ24gPT09IGNoZWNrID8gcmlnaHQgOiBhbGlnbiA9PT0gJ2NlbnRlcicgPyAobGVmdCArIHJpZ2h0KSAvIDIgOiBsZWZ0O1xufTtcblxuLyoqXG4gKiBSZXR1cm4gc3RhcnQgYW5kIGNvdW50IG9mIHZpc2libGUgcG9pbnRzLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9nZXRTdGFydEFuZENvdW50T2ZWaXNpYmxlUG9pbnRzKG1ldGE6IENoYXJ0TWV0YTwnbGluZScgfCAnc2NhdHRlcic+LCBwb2ludHM6IFBvaW50RWxlbWVudFtdLCBhbmltYXRpb25zRGlzYWJsZWQ6IGJvb2xlYW4pIHtcbiAgY29uc3QgcG9pbnRDb3VudCA9IHBvaW50cy5sZW5ndGg7XG5cbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGNvdW50ID0gcG9pbnRDb3VudDtcblxuICBpZiAobWV0YS5fc29ydGVkKSB7XG4gICAgY29uc3Qge2lTY2FsZSwgX3BhcnNlZH0gPSBtZXRhO1xuICAgIGNvbnN0IGF4aXMgPSBpU2NhbGUuYXhpcztcbiAgICBjb25zdCB7bWluLCBtYXgsIG1pbkRlZmluZWQsIG1heERlZmluZWR9ID0gaVNjYWxlLmdldFVzZXJCb3VuZHMoKTtcblxuICAgIGlmIChtaW5EZWZpbmVkKSB7XG4gICAgICBzdGFydCA9IF9saW1pdFZhbHVlKE1hdGgubWluKFxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIE5lZWQgdG8gdHlwZSBfcGFyc2VkXG4gICAgICAgIF9sb29rdXBCeUtleShfcGFyc2VkLCBheGlzLCBtaW4pLmxvLFxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIE5lZWQgdG8gZml4IHR5cGVzIG9uIF9sb29rdXBCeUtleVxuICAgICAgICBhbmltYXRpb25zRGlzYWJsZWQgPyBwb2ludENvdW50IDogX2xvb2t1cEJ5S2V5KHBvaW50cywgYXhpcywgaVNjYWxlLmdldFBpeGVsRm9yVmFsdWUobWluKSkubG8pLFxuICAgICAgMCwgcG9pbnRDb3VudCAtIDEpO1xuICAgIH1cbiAgICBpZiAobWF4RGVmaW5lZCkge1xuICAgICAgY291bnQgPSBfbGltaXRWYWx1ZShNYXRoLm1heChcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBOZWVkIHRvIHR5cGUgX3BhcnNlZFxuICAgICAgICBfbG9va3VwQnlLZXkoX3BhcnNlZCwgaVNjYWxlLmF4aXMsIG1heCwgdHJ1ZSkuaGkgKyAxLFxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIE5lZWQgdG8gZml4IHR5cGVzIG9uIF9sb29rdXBCeUtleVxuICAgICAgICBhbmltYXRpb25zRGlzYWJsZWQgPyAwIDogX2xvb2t1cEJ5S2V5KHBvaW50cywgYXhpcywgaVNjYWxlLmdldFBpeGVsRm9yVmFsdWUobWF4KSwgdHJ1ZSkuaGkgKyAxKSxcbiAgICAgIHN0YXJ0LCBwb2ludENvdW50KSAtIHN0YXJ0O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb3VudCA9IHBvaW50Q291bnQgLSBzdGFydDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge3N0YXJ0LCBjb3VudH07XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBzY2FsZSByYW5nZXMgaGF2ZSBjaGFuZ2VkLlxuICogQHBhcmFtIHtvYmplY3R9IG1ldGEgLSBkYXRhc2V0IG1ldGEuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc2NhbGVSYW5nZXNDaGFuZ2VkKG1ldGEpIHtcbiAgY29uc3Qge3hTY2FsZSwgeVNjYWxlLCBfc2NhbGVSYW5nZXN9ID0gbWV0YTtcbiAgY29uc3QgbmV3UmFuZ2VzID0ge1xuICAgIHhtaW46IHhTY2FsZS5taW4sXG4gICAgeG1heDogeFNjYWxlLm1heCxcbiAgICB5bWluOiB5U2NhbGUubWluLFxuICAgIHltYXg6IHlTY2FsZS5tYXhcbiAgfTtcbiAgaWYgKCFfc2NhbGVSYW5nZXMpIHtcbiAgICBtZXRhLl9zY2FsZVJhbmdlcyA9IG5ld1JhbmdlcztcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBjb25zdCBjaGFuZ2VkID0gX3NjYWxlUmFuZ2VzLnhtaW4gIT09IHhTY2FsZS5taW5cblx0XHR8fCBfc2NhbGVSYW5nZXMueG1heCAhPT0geFNjYWxlLm1heFxuXHRcdHx8IF9zY2FsZVJhbmdlcy55bWluICE9PSB5U2NhbGUubWluXG5cdFx0fHwgX3NjYWxlUmFuZ2VzLnltYXggIT09IHlTY2FsZS5tYXg7XG5cbiAgT2JqZWN0LmFzc2lnbihfc2NhbGVSYW5nZXMsIG5ld1Jhbmdlcyk7XG4gIHJldHVybiBjaGFuZ2VkO1xufVxuIiwgImltcG9ydCB7UEksIFRBVSwgSEFMRl9QSX0gZnJvbSAnLi9oZWxwZXJzLm1hdGguanMnO1xuXG5jb25zdCBhdEVkZ2UgPSAodDogbnVtYmVyKSA9PiB0ID09PSAwIHx8IHQgPT09IDE7XG5jb25zdCBlbGFzdGljSW4gPSAodDogbnVtYmVyLCBzOiBudW1iZXIsIHA6IG51bWJlcikgPT4gLShNYXRoLnBvdygyLCAxMCAqICh0IC09IDEpKSAqIE1hdGguc2luKCh0IC0gcykgKiBUQVUgLyBwKSk7XG5jb25zdCBlbGFzdGljT3V0ID0gKHQ6IG51bWJlciwgczogbnVtYmVyLCBwOiBudW1iZXIpID0+IE1hdGgucG93KDIsIC0xMCAqIHQpICogTWF0aC5zaW4oKHQgLSBzKSAqIFRBVSAvIHApICsgMTtcblxuLyoqXG4gKiBFYXNpbmcgZnVuY3Rpb25zIGFkYXB0ZWQgZnJvbSBSb2JlcnQgUGVubmVyJ3MgZWFzaW5nIGVxdWF0aW9ucy5cbiAqIEBuYW1lc3BhY2UgQ2hhcnQuaGVscGVycy5lYXNpbmcuZWZmZWN0c1xuICogQHNlZSBodHRwOi8vd3d3LnJvYmVydHBlbm5lci5jb20vZWFzaW5nL1xuICovXG5jb25zdCBlZmZlY3RzID0ge1xuICBsaW5lYXI6ICh0OiBudW1iZXIpID0+IHQsXG5cbiAgZWFzZUluUXVhZDogKHQ6IG51bWJlcikgPT4gdCAqIHQsXG5cbiAgZWFzZU91dFF1YWQ6ICh0OiBudW1iZXIpID0+IC10ICogKHQgLSAyKSxcblxuICBlYXNlSW5PdXRRdWFkOiAodDogbnVtYmVyKSA9PiAoKHQgLz0gMC41KSA8IDEpXG4gICAgPyAwLjUgKiB0ICogdFxuICAgIDogLTAuNSAqICgoLS10KSAqICh0IC0gMikgLSAxKSxcblxuICBlYXNlSW5DdWJpYzogKHQ6IG51bWJlcikgPT4gdCAqIHQgKiB0LFxuXG4gIGVhc2VPdXRDdWJpYzogKHQ6IG51bWJlcikgPT4gKHQgLT0gMSkgKiB0ICogdCArIDEsXG5cbiAgZWFzZUluT3V0Q3ViaWM6ICh0OiBudW1iZXIpID0+ICgodCAvPSAwLjUpIDwgMSlcbiAgICA/IDAuNSAqIHQgKiB0ICogdFxuICAgIDogMC41ICogKCh0IC09IDIpICogdCAqIHQgKyAyKSxcblxuICBlYXNlSW5RdWFydDogKHQ6IG51bWJlcikgPT4gdCAqIHQgKiB0ICogdCxcblxuICBlYXNlT3V0UXVhcnQ6ICh0OiBudW1iZXIpID0+IC0oKHQgLT0gMSkgKiB0ICogdCAqIHQgLSAxKSxcblxuICBlYXNlSW5PdXRRdWFydDogKHQ6IG51bWJlcikgPT4gKCh0IC89IDAuNSkgPCAxKVxuICAgID8gMC41ICogdCAqIHQgKiB0ICogdFxuICAgIDogLTAuNSAqICgodCAtPSAyKSAqIHQgKiB0ICogdCAtIDIpLFxuXG4gIGVhc2VJblF1aW50OiAodDogbnVtYmVyKSA9PiB0ICogdCAqIHQgKiB0ICogdCxcblxuICBlYXNlT3V0UXVpbnQ6ICh0OiBudW1iZXIpID0+ICh0IC09IDEpICogdCAqIHQgKiB0ICogdCArIDEsXG5cbiAgZWFzZUluT3V0UXVpbnQ6ICh0OiBudW1iZXIpID0+ICgodCAvPSAwLjUpIDwgMSlcbiAgICA/IDAuNSAqIHQgKiB0ICogdCAqIHQgKiB0XG4gICAgOiAwLjUgKiAoKHQgLT0gMikgKiB0ICogdCAqIHQgKiB0ICsgMiksXG5cbiAgZWFzZUluU2luZTogKHQ6IG51bWJlcikgPT4gLU1hdGguY29zKHQgKiBIQUxGX1BJKSArIDEsXG5cbiAgZWFzZU91dFNpbmU6ICh0OiBudW1iZXIpID0+IE1hdGguc2luKHQgKiBIQUxGX1BJKSxcblxuICBlYXNlSW5PdXRTaW5lOiAodDogbnVtYmVyKSA9PiAtMC41ICogKE1hdGguY29zKFBJICogdCkgLSAxKSxcblxuICBlYXNlSW5FeHBvOiAodDogbnVtYmVyKSA9PiAodCA9PT0gMCkgPyAwIDogTWF0aC5wb3coMiwgMTAgKiAodCAtIDEpKSxcblxuICBlYXNlT3V0RXhwbzogKHQ6IG51bWJlcikgPT4gKHQgPT09IDEpID8gMSA6IC1NYXRoLnBvdygyLCAtMTAgKiB0KSArIDEsXG5cbiAgZWFzZUluT3V0RXhwbzogKHQ6IG51bWJlcikgPT4gYXRFZGdlKHQpID8gdCA6IHQgPCAwLjVcbiAgICA/IDAuNSAqIE1hdGgucG93KDIsIDEwICogKHQgKiAyIC0gMSkpXG4gICAgOiAwLjUgKiAoLU1hdGgucG93KDIsIC0xMCAqICh0ICogMiAtIDEpKSArIDIpLFxuXG4gIGVhc2VJbkNpcmM6ICh0OiBudW1iZXIpID0+ICh0ID49IDEpID8gdCA6IC0oTWF0aC5zcXJ0KDEgLSB0ICogdCkgLSAxKSxcblxuICBlYXNlT3V0Q2lyYzogKHQ6IG51bWJlcikgPT4gTWF0aC5zcXJ0KDEgLSAodCAtPSAxKSAqIHQpLFxuXG4gIGVhc2VJbk91dENpcmM6ICh0OiBudW1iZXIpID0+ICgodCAvPSAwLjUpIDwgMSlcbiAgICA/IC0wLjUgKiAoTWF0aC5zcXJ0KDEgLSB0ICogdCkgLSAxKVxuICAgIDogMC41ICogKE1hdGguc3FydCgxIC0gKHQgLT0gMikgKiB0KSArIDEpLFxuXG4gIGVhc2VJbkVsYXN0aWM6ICh0OiBudW1iZXIpID0+IGF0RWRnZSh0KSA/IHQgOiBlbGFzdGljSW4odCwgMC4wNzUsIDAuMyksXG5cbiAgZWFzZU91dEVsYXN0aWM6ICh0OiBudW1iZXIpID0+IGF0RWRnZSh0KSA/IHQgOiBlbGFzdGljT3V0KHQsIDAuMDc1LCAwLjMpLFxuXG4gIGVhc2VJbk91dEVsYXN0aWModDogbnVtYmVyKSB7XG4gICAgY29uc3QgcyA9IDAuMTEyNTtcbiAgICBjb25zdCBwID0gMC40NTtcbiAgICByZXR1cm4gYXRFZGdlKHQpID8gdCA6XG4gICAgICB0IDwgMC41XG4gICAgICAgID8gMC41ICogZWxhc3RpY0luKHQgKiAyLCBzLCBwKVxuICAgICAgICA6IDAuNSArIDAuNSAqIGVsYXN0aWNPdXQodCAqIDIgLSAxLCBzLCBwKTtcbiAgfSxcblxuICBlYXNlSW5CYWNrKHQ6IG51bWJlcikge1xuICAgIGNvbnN0IHMgPSAxLjcwMTU4O1xuICAgIHJldHVybiB0ICogdCAqICgocyArIDEpICogdCAtIHMpO1xuICB9LFxuXG4gIGVhc2VPdXRCYWNrKHQ6IG51bWJlcikge1xuICAgIGNvbnN0IHMgPSAxLjcwMTU4O1xuICAgIHJldHVybiAodCAtPSAxKSAqIHQgKiAoKHMgKyAxKSAqIHQgKyBzKSArIDE7XG4gIH0sXG5cbiAgZWFzZUluT3V0QmFjayh0OiBudW1iZXIpIHtcbiAgICBsZXQgcyA9IDEuNzAxNTg7XG4gICAgaWYgKCh0IC89IDAuNSkgPCAxKSB7XG4gICAgICByZXR1cm4gMC41ICogKHQgKiB0ICogKCgocyAqPSAoMS41MjUpKSArIDEpICogdCAtIHMpKTtcbiAgICB9XG4gICAgcmV0dXJuIDAuNSAqICgodCAtPSAyKSAqIHQgKiAoKChzICo9ICgxLjUyNSkpICsgMSkgKiB0ICsgcykgKyAyKTtcbiAgfSxcblxuICBlYXNlSW5Cb3VuY2U6ICh0OiBudW1iZXIpID0+IDEgLSBlZmZlY3RzLmVhc2VPdXRCb3VuY2UoMSAtIHQpLFxuXG4gIGVhc2VPdXRCb3VuY2UodDogbnVtYmVyKSB7XG4gICAgY29uc3QgbSA9IDcuNTYyNTtcbiAgICBjb25zdCBkID0gMi43NTtcbiAgICBpZiAodCA8ICgxIC8gZCkpIHtcbiAgICAgIHJldHVybiBtICogdCAqIHQ7XG4gICAgfVxuICAgIGlmICh0IDwgKDIgLyBkKSkge1xuICAgICAgcmV0dXJuIG0gKiAodCAtPSAoMS41IC8gZCkpICogdCArIDAuNzU7XG4gICAgfVxuICAgIGlmICh0IDwgKDIuNSAvIGQpKSB7XG4gICAgICByZXR1cm4gbSAqICh0IC09ICgyLjI1IC8gZCkpICogdCArIDAuOTM3NTtcbiAgICB9XG4gICAgcmV0dXJuIG0gKiAodCAtPSAoMi42MjUgLyBkKSkgKiB0ICsgMC45ODQzNzU7XG4gIH0sXG5cbiAgZWFzZUluT3V0Qm91bmNlOiAodDogbnVtYmVyKSA9PiAodCA8IDAuNSlcbiAgICA/IGVmZmVjdHMuZWFzZUluQm91bmNlKHQgKiAyKSAqIDAuNVxuICAgIDogZWZmZWN0cy5lYXNlT3V0Qm91bmNlKHQgKiAyIC0gMSkgKiAwLjUgKyAwLjUsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBFYXNpbmdGdW5jdGlvbiA9IGtleW9mIHR5cGVvZiBlZmZlY3RzXG5cbmV4cG9ydCBkZWZhdWx0IGVmZmVjdHM7XG4iLCAiaW1wb3J0IHtDb2xvcn0gZnJvbSAnQGt1cmtsZS9jb2xvcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1BhdHRlcm5PckdyYWRpZW50KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgQ2FudmFzUGF0dGVybiB8IENhbnZhc0dyYWRpZW50IHtcbiAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICBjb25zdCB0eXBlID0gdmFsdWUudG9TdHJpbmcoKTtcbiAgICByZXR1cm4gdHlwZSA9PT0gJ1tvYmplY3QgQ2FudmFzUGF0dGVybl0nIHx8IHR5cGUgPT09ICdbb2JqZWN0IENhbnZhc0dyYWRpZW50XSc7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb2xvcih2YWx1ZTogQ2FudmFzR3JhZGllbnQpOiBDYW52YXNHcmFkaWVudDtcbmV4cG9ydCBmdW5jdGlvbiBjb2xvcih2YWx1ZTogQ2FudmFzUGF0dGVybik6IENhbnZhc1BhdHRlcm47XG5leHBvcnQgZnVuY3Rpb24gY29sb3IoXG4gIHZhbHVlOlxuICB8IHN0cmluZ1xuICB8IHsgcjogbnVtYmVyOyBnOiBudW1iZXI7IGI6IG51bWJlcjsgYTogbnVtYmVyIH1cbiAgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl1cbiAgfCBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXVxuKTogQ29sb3I7XG5leHBvcnQgZnVuY3Rpb24gY29sb3IodmFsdWUpIHtcbiAgcmV0dXJuIGlzUGF0dGVybk9yR3JhZGllbnQodmFsdWUpID8gdmFsdWUgOiBuZXcgQ29sb3IodmFsdWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SG92ZXJDb2xvcih2YWx1ZTogQ2FudmFzR3JhZGllbnQpOiBDYW52YXNHcmFkaWVudDtcbmV4cG9ydCBmdW5jdGlvbiBnZXRIb3ZlckNvbG9yKHZhbHVlOiBDYW52YXNQYXR0ZXJuKTogQ2FudmFzUGF0dGVybjtcbmV4cG9ydCBmdW5jdGlvbiBnZXRIb3ZlckNvbG9yKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmc7XG5leHBvcnQgZnVuY3Rpb24gZ2V0SG92ZXJDb2xvcih2YWx1ZSkge1xuICByZXR1cm4gaXNQYXR0ZXJuT3JHcmFkaWVudCh2YWx1ZSlcbiAgICA/IHZhbHVlXG4gICAgOiBuZXcgQ29sb3IodmFsdWUpLnNhdHVyYXRlKDAuNSkuZGFya2VuKDAuMSkuaGV4U3RyaW5nKCk7XG59XG4iLCAiY29uc3QgbnVtYmVycyA9IFsneCcsICd5JywgJ2JvcmRlcldpZHRoJywgJ3JhZGl1cycsICd0ZW5zaW9uJ107XG5jb25zdCBjb2xvcnMgPSBbJ2NvbG9yJywgJ2JvcmRlckNvbG9yJywgJ2JhY2tncm91bmRDb2xvciddO1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlBbmltYXRpb25zRGVmYXVsdHMoZGVmYXVsdHMpIHtcbiAgZGVmYXVsdHMuc2V0KCdhbmltYXRpb24nLCB7XG4gICAgZGVsYXk6IHVuZGVmaW5lZCxcbiAgICBkdXJhdGlvbjogMTAwMCxcbiAgICBlYXNpbmc6ICdlYXNlT3V0UXVhcnQnLFxuICAgIGZuOiB1bmRlZmluZWQsXG4gICAgZnJvbTogdW5kZWZpbmVkLFxuICAgIGxvb3A6IHVuZGVmaW5lZCxcbiAgICB0bzogdW5kZWZpbmVkLFxuICAgIHR5cGU6IHVuZGVmaW5lZCxcbiAgfSk7XG5cbiAgZGVmYXVsdHMuZGVzY3JpYmUoJ2FuaW1hdGlvbicsIHtcbiAgICBfZmFsbGJhY2s6IGZhbHNlLFxuICAgIF9pbmRleGFibGU6IGZhbHNlLFxuICAgIF9zY3JpcHRhYmxlOiAobmFtZSkgPT4gbmFtZSAhPT0gJ29uUHJvZ3Jlc3MnICYmIG5hbWUgIT09ICdvbkNvbXBsZXRlJyAmJiBuYW1lICE9PSAnZm4nLFxuICB9KTtcblxuICBkZWZhdWx0cy5zZXQoJ2FuaW1hdGlvbnMnLCB7XG4gICAgY29sb3JzOiB7XG4gICAgICB0eXBlOiAnY29sb3InLFxuICAgICAgcHJvcGVydGllczogY29sb3JzXG4gICAgfSxcbiAgICBudW1iZXJzOiB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgIHByb3BlcnRpZXM6IG51bWJlcnNcbiAgICB9LFxuICB9KTtcblxuICBkZWZhdWx0cy5kZXNjcmliZSgnYW5pbWF0aW9ucycsIHtcbiAgICBfZmFsbGJhY2s6ICdhbmltYXRpb24nLFxuICB9KTtcblxuICBkZWZhdWx0cy5zZXQoJ3RyYW5zaXRpb25zJywge1xuICAgIGFjdGl2ZToge1xuICAgICAgYW5pbWF0aW9uOiB7XG4gICAgICAgIGR1cmF0aW9uOiA0MDBcbiAgICAgIH1cbiAgICB9LFxuICAgIHJlc2l6ZToge1xuICAgICAgYW5pbWF0aW9uOiB7XG4gICAgICAgIGR1cmF0aW9uOiAwXG4gICAgICB9XG4gICAgfSxcbiAgICBzaG93OiB7XG4gICAgICBhbmltYXRpb25zOiB7XG4gICAgICAgIGNvbG9yczoge1xuICAgICAgICAgIGZyb206ICd0cmFuc3BhcmVudCdcbiAgICAgICAgfSxcbiAgICAgICAgdmlzaWJsZToge1xuICAgICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICBkdXJhdGlvbjogMCAvLyBzaG93IGltbWVkaWF0ZWx5XG4gICAgICAgIH0sXG4gICAgICB9XG4gICAgfSxcbiAgICBoaWRlOiB7XG4gICAgICBhbmltYXRpb25zOiB7XG4gICAgICAgIGNvbG9yczoge1xuICAgICAgICAgIHRvOiAndHJhbnNwYXJlbnQnXG4gICAgICAgIH0sXG4gICAgICAgIHZpc2libGU6IHtcbiAgICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgICAgZWFzaW5nOiAnbGluZWFyJyxcbiAgICAgICAgICBmbjogdiA9PiB2IHwgMCAvLyBmb3Iga2VlcGluZyB0aGUgZGF0YXNldCB2aXNpYmxlIGFsbCB0aGUgd2F5IHRocm91Z2ggdGhlIGFuaW1hdGlvblxuICAgICAgICB9LFxuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGFwcGx5TGF5b3V0c0RlZmF1bHRzKGRlZmF1bHRzKSB7XG4gIGRlZmF1bHRzLnNldCgnbGF5b3V0Jywge1xuICAgIGF1dG9QYWRkaW5nOiB0cnVlLFxuICAgIHBhZGRpbmc6IHtcbiAgICAgIHRvcDogMCxcbiAgICAgIHJpZ2h0OiAwLFxuICAgICAgYm90dG9tOiAwLFxuICAgICAgbGVmdDogMFxuICAgIH1cbiAgfSk7XG59XG4iLCAiXG5jb25zdCBpbnRsQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgSW50bC5OdW1iZXJGb3JtYXQ+KCk7XG5cbmZ1bmN0aW9uIGdldE51bWJlckZvcm1hdChsb2NhbGU6IHN0cmluZywgb3B0aW9ucz86IEludGwuTnVtYmVyRm9ybWF0T3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgY29uc3QgY2FjaGVLZXkgPSBsb2NhbGUgKyBKU09OLnN0cmluZ2lmeShvcHRpb25zKTtcbiAgbGV0IGZvcm1hdHRlciA9IGludGxDYWNoZS5nZXQoY2FjaGVLZXkpO1xuICBpZiAoIWZvcm1hdHRlcikge1xuICAgIGZvcm1hdHRlciA9IG5ldyBJbnRsLk51bWJlckZvcm1hdChsb2NhbGUsIG9wdGlvbnMpO1xuICAgIGludGxDYWNoZS5zZXQoY2FjaGVLZXksIGZvcm1hdHRlcik7XG4gIH1cbiAgcmV0dXJuIGZvcm1hdHRlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdE51bWJlcihudW06IG51bWJlciwgbG9jYWxlOiBzdHJpbmcsIG9wdGlvbnM/OiBJbnRsLk51bWJlckZvcm1hdE9wdGlvbnMpIHtcbiAgcmV0dXJuIGdldE51bWJlckZvcm1hdChsb2NhbGUsIG9wdGlvbnMpLmZvcm1hdChudW0pO1xufVxuIiwgImltcG9ydCB7aXNBcnJheX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuaW1wb3J0IHtmb3JtYXROdW1iZXJ9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5pbnRsLmpzJztcbmltcG9ydCB7bG9nMTB9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcblxuLyoqXG4gKiBOYW1lc3BhY2UgdG8gaG9sZCBmb3JtYXR0ZXJzIGZvciBkaWZmZXJlbnQgdHlwZXMgb2YgdGlja3NcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuVGlja3MuZm9ybWF0dGVyc1xuICovXG5jb25zdCBmb3JtYXR0ZXJzID0ge1xuICAvKipcbiAgICogRm9ybWF0dGVyIGZvciB2YWx1ZSBsYWJlbHNcbiAgICogQG1ldGhvZCBDaGFydC5UaWNrcy5mb3JtYXR0ZXJzLnZhbHVlc1xuICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIHRvIGRpc3BsYXlcbiAgICogQHJldHVybiB7c3RyaW5nfHN0cmluZ1tdfSB0aGUgbGFiZWwgdG8gZGlzcGxheVxuICAgKi9cbiAgdmFsdWVzKHZhbHVlKSB7XG4gICAgcmV0dXJuIGlzQXJyYXkodmFsdWUpID8gLyoqIEB0eXBlIHtzdHJpbmdbXX0gKi8gKHZhbHVlKSA6ICcnICsgdmFsdWU7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEZvcm1hdHRlciBmb3IgbnVtZXJpYyB0aWNrc1xuICAgKiBAbWV0aG9kIENoYXJ0LlRpY2tzLmZvcm1hdHRlcnMubnVtZXJpY1xuICAgKiBAcGFyYW0gdGlja1ZhbHVlIHtudW1iZXJ9IHRoZSB2YWx1ZSB0byBiZSBmb3JtYXR0ZWRcbiAgICogQHBhcmFtIGluZGV4IHtudW1iZXJ9IHRoZSBwb3NpdGlvbiBvZiB0aGUgdGlja1ZhbHVlIHBhcmFtZXRlciBpbiB0aGUgdGlja3MgYXJyYXlcbiAgICogQHBhcmFtIHRpY2tzIHtvYmplY3RbXX0gdGhlIGxpc3Qgb2YgdGlja3MgYmVpbmcgY29udmVydGVkXG4gICAqIEByZXR1cm4ge3N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0aWNrVmFsdWUgcGFyYW1ldGVyXG4gICAqL1xuICBudW1lcmljKHRpY2tWYWx1ZSwgaW5kZXgsIHRpY2tzKSB7XG4gICAgaWYgKHRpY2tWYWx1ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuICcwJzsgLy8gbmV2ZXIgc2hvdyBkZWNpbWFsIHBsYWNlcyBmb3IgMFxuICAgIH1cblxuICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMuY2hhcnQub3B0aW9ucy5sb2NhbGU7XG4gICAgbGV0IG5vdGF0aW9uO1xuICAgIGxldCBkZWx0YSA9IHRpY2tWYWx1ZTsgLy8gVGhpcyBpcyB1c2VkIHdoZW4gdGhlcmUgYXJlIGxlc3MgdGhhbiAyIHRpY2tzIGFzIHRoZSB0aWNrIGludGVydmFsLlxuXG4gICAgaWYgKHRpY2tzLmxlbmd0aCA+IDEpIHtcbiAgICAgIC8vIGFsbCB0aWNrcyBhcmUgc21hbGwgb3IgdGhlcmUgaHVnZSBudW1iZXJzOyB1c2Ugc2NpZW50aWZpYyBub3RhdGlvblxuICAgICAgY29uc3QgbWF4VGljayA9IE1hdGgubWF4KE1hdGguYWJzKHRpY2tzWzBdLnZhbHVlKSwgTWF0aC5hYnModGlja3NbdGlja3MubGVuZ3RoIC0gMV0udmFsdWUpKTtcbiAgICAgIGlmIChtYXhUaWNrIDwgMWUtNCB8fCBtYXhUaWNrID4gMWUrMTUpIHtcbiAgICAgICAgbm90YXRpb24gPSAnc2NpZW50aWZpYyc7XG4gICAgICB9XG5cbiAgICAgIGRlbHRhID0gY2FsY3VsYXRlRGVsdGEodGlja1ZhbHVlLCB0aWNrcyk7XG4gICAgfVxuXG4gICAgY29uc3QgbG9nRGVsdGEgPSBsb2cxMChNYXRoLmFicyhkZWx0YSkpO1xuXG4gICAgLy8gV2hlbiBkYXRhc2V0cyBoYXZlIHZhbHVlcyBhcHByb2FjaGluZyBOdW1iZXIuTUFYX1ZBTFVFLCB0aGUgdGljayBjYWxjdWxhdGlvbnMgbWlnaHQgcmVzdWx0IGluXG4gICAgLy8gaW5maW5pdHkgYW5kIGV2ZW50dWFsbHkgTmFOLiBQYXNzaW5nIE5hTiBmb3IgbWluaW11bUZyYWN0aW9uRGlnaXRzIG9yIG1heGltdW1GcmFjdGlvbkRpZ2l0c1xuICAgIC8vIHdpbGwgbWFrZSB0aGUgbnVtYmVyIGZvcm1hdHRlciB0aHJvdy4gU28gaW5zdGVhZCB3ZSBjaGVjayBmb3IgaXNOYU4gYW5kIHVzZSBhIGZhbGxiYWNrIHZhbHVlLlxuICAgIC8vXG4gICAgLy8gdG9GaXhlZCBoYXMgYSBtYXggb2YgMjAgZGVjaW1hbCBwbGFjZXNcbiAgICBjb25zdCBudW1EZWNpbWFsID0gaXNOYU4obG9nRGVsdGEpID8gMSA6IE1hdGgubWF4KE1hdGgubWluKC0xICogTWF0aC5mbG9vcihsb2dEZWx0YSksIDIwKSwgMCk7XG5cbiAgICBjb25zdCBvcHRpb25zID0ge25vdGF0aW9uLCBtaW5pbXVtRnJhY3Rpb25EaWdpdHM6IG51bURlY2ltYWwsIG1heGltdW1GcmFjdGlvbkRpZ2l0czogbnVtRGVjaW1hbH07XG4gICAgT2JqZWN0LmFzc2lnbihvcHRpb25zLCB0aGlzLm9wdGlvbnMudGlja3MuZm9ybWF0KTtcblxuICAgIHJldHVybiBmb3JtYXROdW1iZXIodGlja1ZhbHVlLCBsb2NhbGUsIG9wdGlvbnMpO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIEZvcm1hdHRlciBmb3IgbG9nYXJpdGhtaWMgdGlja3NcbiAgICogQG1ldGhvZCBDaGFydC5UaWNrcy5mb3JtYXR0ZXJzLmxvZ2FyaXRobWljXG4gICAqIEBwYXJhbSB0aWNrVmFsdWUge251bWJlcn0gdGhlIHZhbHVlIHRvIGJlIGZvcm1hdHRlZFxuICAgKiBAcGFyYW0gaW5kZXgge251bWJlcn0gdGhlIHBvc2l0aW9uIG9mIHRoZSB0aWNrVmFsdWUgcGFyYW1ldGVyIGluIHRoZSB0aWNrcyBhcnJheVxuICAgKiBAcGFyYW0gdGlja3Mge29iamVjdFtdfSB0aGUgbGlzdCBvZiB0aWNrcyBiZWluZyBjb252ZXJ0ZWRcbiAgICogQHJldHVybiB7c3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHRpY2tWYWx1ZSBwYXJhbWV0ZXJcbiAgICovXG4gIGxvZ2FyaXRobWljKHRpY2tWYWx1ZSwgaW5kZXgsIHRpY2tzKSB7XG4gICAgaWYgKHRpY2tWYWx1ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuICcwJztcbiAgICB9XG4gICAgY29uc3QgcmVtYWluID0gdGlja3NbaW5kZXhdLnNpZ25pZmljYW5kIHx8ICh0aWNrVmFsdWUgLyAoTWF0aC5wb3coMTAsIE1hdGguZmxvb3IobG9nMTAodGlja1ZhbHVlKSkpKSk7XG4gICAgaWYgKFsxLCAyLCAzLCA1LCAxMCwgMTVdLmluY2x1ZGVzKHJlbWFpbikgfHwgaW5kZXggPiAwLjggKiB0aWNrcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmb3JtYXR0ZXJzLm51bWVyaWMuY2FsbCh0aGlzLCB0aWNrVmFsdWUsIGluZGV4LCB0aWNrcyk7XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxuXG59O1xuXG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZURlbHRhKHRpY2tWYWx1ZSwgdGlja3MpIHtcbiAgLy8gRmlndXJlIG91dCBob3cgbWFueSBkaWdpdHMgdG8gc2hvd1xuICAvLyBUaGUgc3BhY2UgYmV0d2VlbiB0aGUgZmlyc3QgdHdvIHRpY2tzIG1pZ2h0IGJlIHNtYWxsZXIgdGhhbiBub3JtYWwgc3BhY2luZ1xuICBsZXQgZGVsdGEgPSB0aWNrcy5sZW5ndGggPiAzID8gdGlja3NbMl0udmFsdWUgLSB0aWNrc1sxXS52YWx1ZSA6IHRpY2tzWzFdLnZhbHVlIC0gdGlja3NbMF0udmFsdWU7XG5cbiAgLy8gSWYgd2UgaGF2ZSBhIG51bWJlciBsaWtlIDIuNSBhcyB0aGUgZGVsdGEsIGZpZ3VyZSBvdXQgaG93IG1hbnkgZGVjaW1hbCBwbGFjZXMgd2UgbmVlZFxuICBpZiAoTWF0aC5hYnMoZGVsdGEpID49IDEgJiYgdGlja1ZhbHVlICE9PSBNYXRoLmZsb29yKHRpY2tWYWx1ZSkpIHtcbiAgICAvLyBub3QgYW4gaW50ZWdlclxuICAgIGRlbHRhID0gdGlja1ZhbHVlIC0gTWF0aC5mbG9vcih0aWNrVmFsdWUpO1xuICB9XG4gIHJldHVybiBkZWx0YTtcbn1cblxuLyoqXG4gKiBOYW1lc3BhY2UgdG8gaG9sZCBzdGF0aWMgdGljayBnZW5lcmF0aW9uIGZ1bmN0aW9uc1xuICogQG5hbWVzcGFjZSBDaGFydC5UaWNrc1xuICovXG5leHBvcnQgZGVmYXVsdCB7Zm9ybWF0dGVyc307XG4iLCAiaW1wb3J0IFRpY2tzIGZyb20gJy4vY29yZS50aWNrcy5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVNjYWxlRGVmYXVsdHMoZGVmYXVsdHMpIHtcbiAgZGVmYXVsdHMuc2V0KCdzY2FsZScsIHtcbiAgICBkaXNwbGF5OiB0cnVlLFxuICAgIG9mZnNldDogZmFsc2UsXG4gICAgcmV2ZXJzZTogZmFsc2UsXG4gICAgYmVnaW5BdFplcm86IGZhbHNlLFxuXG4gICAgLyoqXG4gICAgICogU2NhbGUgYm91bmRhcnkgc3RyYXRlZ3kgKGJ5cGFzc2VkIGJ5IG1pbi9tYXggdGltZSBvcHRpb25zKVxuICAgICAqIC0gYGRhdGFgOiBtYWtlIHN1cmUgZGF0YSBhcmUgZnVsbHkgdmlzaWJsZSwgdGlja3Mgb3V0c2lkZSBhcmUgcmVtb3ZlZFxuICAgICAqIC0gYHRpY2tzYDogbWFrZSBzdXJlIHRpY2tzIGFyZSBmdWxseSB2aXNpYmxlLCBkYXRhIG91dHNpZGUgYXJlIHRydW5jYXRlZFxuICAgICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvcHVsbC80NTU2XG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICovXG4gICAgYm91bmRzOiAndGlja3MnLFxuXG4gICAgY2xpcDogdHJ1ZSxcblxuICAgIC8qKlxuICAgICAqIEFkZGl0aW9uIGdyYWNlIGFkZGVkIHRvIG1heCBhbmQgcmVkdWNlZCBmcm9tIG1pbiBkYXRhIHZhbHVlLlxuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqL1xuICAgIGdyYWNlOiAwLFxuXG4gICAgLy8gZ3JpZCBsaW5lIHNldHRpbmdzXG4gICAgZ3JpZDoge1xuICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgIGRyYXdPbkNoYXJ0QXJlYTogdHJ1ZSxcbiAgICAgIGRyYXdUaWNrczogdHJ1ZSxcbiAgICAgIHRpY2tMZW5ndGg6IDgsXG4gICAgICB0aWNrV2lkdGg6IChfY3R4LCBvcHRpb25zKSA9PiBvcHRpb25zLmxpbmVXaWR0aCxcbiAgICAgIHRpY2tDb2xvcjogKF9jdHgsIG9wdGlvbnMpID0+IG9wdGlvbnMuY29sb3IsXG4gICAgICBvZmZzZXQ6IGZhbHNlLFxuICAgIH0sXG5cbiAgICBib3JkZXI6IHtcbiAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICBkYXNoOiBbXSxcbiAgICAgIGRhc2hPZmZzZXQ6IDAuMCxcbiAgICAgIHdpZHRoOiAxXG4gICAgfSxcblxuICAgIC8vIHNjYWxlIHRpdGxlXG4gICAgdGl0bGU6IHtcbiAgICAgIC8vIGRpc3BsYXkgcHJvcGVydHlcbiAgICAgIGRpc3BsYXk6IGZhbHNlLFxuXG4gICAgICAvLyBhY3R1YWwgbGFiZWxcbiAgICAgIHRleHQ6ICcnLFxuXG4gICAgICAvLyB0b3AvYm90dG9tIHBhZGRpbmdcbiAgICAgIHBhZGRpbmc6IHtcbiAgICAgICAgdG9wOiA0LFxuICAgICAgICBib3R0b206IDRcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLy8gbGFiZWwgc2V0dGluZ3NcbiAgICB0aWNrczoge1xuICAgICAgbWluUm90YXRpb246IDAsXG4gICAgICBtYXhSb3RhdGlvbjogNTAsXG4gICAgICBtaXJyb3I6IGZhbHNlLFxuICAgICAgdGV4dFN0cm9rZVdpZHRoOiAwLFxuICAgICAgdGV4dFN0cm9rZUNvbG9yOiAnJyxcbiAgICAgIHBhZGRpbmc6IDMsXG4gICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgYXV0b1NraXA6IHRydWUsXG4gICAgICBhdXRvU2tpcFBhZGRpbmc6IDMsXG4gICAgICBsYWJlbE9mZnNldDogMCxcbiAgICAgIC8vIFdlIHBhc3MgdGhyb3VnaCBhcnJheXMgdG8gYmUgcmVuZGVyZWQgYXMgbXVsdGlsaW5lIGxhYmVscywgd2UgY29udmVydCBPdGhlcnMgdG8gc3RyaW5ncyBoZXJlLlxuICAgICAgY2FsbGJhY2s6IFRpY2tzLmZvcm1hdHRlcnMudmFsdWVzLFxuICAgICAgbWlub3I6IHt9LFxuICAgICAgbWFqb3I6IHt9LFxuICAgICAgYWxpZ246ICdjZW50ZXInLFxuICAgICAgY3Jvc3NBbGlnbjogJ25lYXInLFxuXG4gICAgICBzaG93TGFiZWxCYWNrZHJvcDogZmFsc2UsXG4gICAgICBiYWNrZHJvcENvbG9yOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjc1KScsXG4gICAgICBiYWNrZHJvcFBhZGRpbmc6IDIsXG4gICAgfVxuICB9KTtcblxuICBkZWZhdWx0cy5yb3V0ZSgnc2NhbGUudGlja3MnLCAnY29sb3InLCAnJywgJ2NvbG9yJyk7XG4gIGRlZmF1bHRzLnJvdXRlKCdzY2FsZS5ncmlkJywgJ2NvbG9yJywgJycsICdib3JkZXJDb2xvcicpO1xuICBkZWZhdWx0cy5yb3V0ZSgnc2NhbGUuYm9yZGVyJywgJ2NvbG9yJywgJycsICdib3JkZXJDb2xvcicpO1xuICBkZWZhdWx0cy5yb3V0ZSgnc2NhbGUudGl0bGUnLCAnY29sb3InLCAnJywgJ2NvbG9yJyk7XG5cbiAgZGVmYXVsdHMuZGVzY3JpYmUoJ3NjYWxlJywge1xuICAgIF9mYWxsYmFjazogZmFsc2UsXG4gICAgX3NjcmlwdGFibGU6IChuYW1lKSA9PiAhbmFtZS5zdGFydHNXaXRoKCdiZWZvcmUnKSAmJiAhbmFtZS5zdGFydHNXaXRoKCdhZnRlcicpICYmIG5hbWUgIT09ICdjYWxsYmFjaycgJiYgbmFtZSAhPT0gJ3BhcnNlcicsXG4gICAgX2luZGV4YWJsZTogKG5hbWUpID0+IG5hbWUgIT09ICdib3JkZXJEYXNoJyAmJiBuYW1lICE9PSAndGlja0JvcmRlckRhc2gnICYmIG5hbWUgIT09ICdkYXNoJyxcbiAgfSk7XG5cbiAgZGVmYXVsdHMuZGVzY3JpYmUoJ3NjYWxlcycsIHtcbiAgICBfZmFsbGJhY2s6ICdzY2FsZScsXG4gIH0pO1xuXG4gIGRlZmF1bHRzLmRlc2NyaWJlKCdzY2FsZS50aWNrcycsIHtcbiAgICBfc2NyaXB0YWJsZTogKG5hbWUpID0+IG5hbWUgIT09ICdiYWNrZHJvcFBhZGRpbmcnICYmIG5hbWUgIT09ICdjYWxsYmFjaycsXG4gICAgX2luZGV4YWJsZTogKG5hbWUpID0+IG5hbWUgIT09ICdiYWNrZHJvcFBhZGRpbmcnLFxuICB9KTtcbn1cbiIsICJpbXBvcnQge2dldEhvdmVyQ29sb3J9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb2xvci5qcyc7XG5pbXBvcnQge2lzT2JqZWN0LCBtZXJnZSwgdmFsdWVPckRlZmF1bHR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7YXBwbHlBbmltYXRpb25zRGVmYXVsdHN9IGZyb20gJy4vY29yZS5hbmltYXRpb25zLmRlZmF1bHRzLmpzJztcbmltcG9ydCB7YXBwbHlMYXlvdXRzRGVmYXVsdHN9IGZyb20gJy4vY29yZS5sYXlvdXRzLmRlZmF1bHRzLmpzJztcbmltcG9ydCB7YXBwbHlTY2FsZURlZmF1bHRzfSBmcm9tICcuL2NvcmUuc2NhbGUuZGVmYXVsdHMuanMnO1xuXG5leHBvcnQgY29uc3Qgb3ZlcnJpZGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbmV4cG9ydCBjb25zdCBkZXNjcmlwdG9ycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IG5vZGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEByZXR1cm4ge29iamVjdH1cbiAqL1xuZnVuY3Rpb24gZ2V0U2NvcGUobm9kZSwga2V5KSB7XG4gIGlmICgha2V5KSB7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cbiAgY29uc3Qga2V5cyA9IGtleS5zcGxpdCgnLicpO1xuICBmb3IgKGxldCBpID0gMCwgbiA9IGtleXMubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgY29uc3QgayA9IGtleXNbaV07XG4gICAgbm9kZSA9IG5vZGVba10gfHwgKG5vZGVba10gPSBPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgfVxuICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gc2V0KHJvb3QsIHNjb3BlLCB2YWx1ZXMpIHtcbiAgaWYgKHR5cGVvZiBzY29wZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbWVyZ2UoZ2V0U2NvcGUocm9vdCwgc2NvcGUpLCB2YWx1ZXMpO1xuICB9XG4gIHJldHVybiBtZXJnZShnZXRTY29wZShyb290LCAnJyksIHNjb3BlKTtcbn1cblxuLyoqXG4gKiBQbGVhc2UgdXNlIHRoZSBtb2R1bGUncyBkZWZhdWx0IGV4cG9ydCB3aGljaCBwcm92aWRlcyBhIHNpbmdsZXRvbiBpbnN0YW5jZVxuICogTm90ZTogY2xhc3MgaXMgZXhwb3J0ZWQgZm9yIHR5cGVkb2NcbiAqL1xuZXhwb3J0IGNsYXNzIERlZmF1bHRzIHtcbiAgY29uc3RydWN0b3IoX2Rlc2NyaXB0b3JzLCBfYXBwbGllcnMpIHtcbiAgICB0aGlzLmFuaW1hdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmJhY2tncm91bmRDb2xvciA9ICdyZ2JhKDAsMCwwLDAuMSknO1xuICAgIHRoaXMuYm9yZGVyQ29sb3IgPSAncmdiYSgwLDAsMCwwLjEpJztcbiAgICB0aGlzLmNvbG9yID0gJyM2NjYnO1xuICAgIHRoaXMuZGF0YXNldHMgPSB7fTtcbiAgICB0aGlzLmRldmljZVBpeGVsUmF0aW8gPSAoY29udGV4dCkgPT4gY29udGV4dC5jaGFydC5wbGF0Zm9ybS5nZXREZXZpY2VQaXhlbFJhdGlvKCk7XG4gICAgdGhpcy5lbGVtZW50cyA9IHt9O1xuICAgIHRoaXMuZXZlbnRzID0gW1xuICAgICAgJ21vdXNlbW92ZScsXG4gICAgICAnbW91c2VvdXQnLFxuICAgICAgJ2NsaWNrJyxcbiAgICAgICd0b3VjaHN0YXJ0JyxcbiAgICAgICd0b3VjaG1vdmUnXG4gICAgXTtcbiAgICB0aGlzLmZvbnQgPSB7XG4gICAgICBmYW1pbHk6IFwiJ0hlbHZldGljYSBOZXVlJywgJ0hlbHZldGljYScsICdBcmlhbCcsIHNhbnMtc2VyaWZcIixcbiAgICAgIHNpemU6IDEyLFxuICAgICAgc3R5bGU6ICdub3JtYWwnLFxuICAgICAgbGluZUhlaWdodDogMS4yLFxuICAgICAgd2VpZ2h0OiBudWxsXG4gICAgfTtcbiAgICB0aGlzLmhvdmVyID0ge307XG4gICAgdGhpcy5ob3ZlckJhY2tncm91bmRDb2xvciA9IChjdHgsIG9wdGlvbnMpID0+IGdldEhvdmVyQ29sb3Iob3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IpO1xuICAgIHRoaXMuaG92ZXJCb3JkZXJDb2xvciA9IChjdHgsIG9wdGlvbnMpID0+IGdldEhvdmVyQ29sb3Iob3B0aW9ucy5ib3JkZXJDb2xvcik7XG4gICAgdGhpcy5ob3ZlckNvbG9yID0gKGN0eCwgb3B0aW9ucykgPT4gZ2V0SG92ZXJDb2xvcihvcHRpb25zLmNvbG9yKTtcbiAgICB0aGlzLmluZGV4QXhpcyA9ICd4JztcbiAgICB0aGlzLmludGVyYWN0aW9uID0ge1xuICAgICAgbW9kZTogJ25lYXJlc3QnLFxuICAgICAgaW50ZXJzZWN0OiB0cnVlLFxuICAgICAgaW5jbHVkZUludmlzaWJsZTogZmFsc2VcbiAgICB9O1xuICAgIHRoaXMubWFpbnRhaW5Bc3BlY3RSYXRpbyA9IHRydWU7XG4gICAgdGhpcy5vbkhvdmVyID0gbnVsbDtcbiAgICB0aGlzLm9uQ2xpY2sgPSBudWxsO1xuICAgIHRoaXMucGFyc2luZyA9IHRydWU7XG4gICAgdGhpcy5wbHVnaW5zID0ge307XG4gICAgdGhpcy5yZXNwb25zaXZlID0gdHJ1ZTtcbiAgICB0aGlzLnNjYWxlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc2NhbGVzID0ge307XG4gICAgdGhpcy5zaG93TGluZSA9IHRydWU7XG4gICAgdGhpcy5kcmF3QWN0aXZlRWxlbWVudHNPblRvcCA9IHRydWU7XG5cbiAgICB0aGlzLmRlc2NyaWJlKF9kZXNjcmlwdG9ycyk7XG4gICAgdGhpcy5hcHBseShfYXBwbGllcnMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gc2NvcGVcblx0ICogQHBhcmFtIHtvYmplY3R9IFt2YWx1ZXNdXG5cdCAqL1xuICBzZXQoc2NvcGUsIHZhbHVlcykge1xuICAgIHJldHVybiBzZXQodGhpcywgc2NvcGUsIHZhbHVlcyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNjb3BlXG5cdCAqL1xuICBnZXQoc2NvcGUpIHtcbiAgICByZXR1cm4gZ2V0U2NvcGUodGhpcywgc2NvcGUpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gc2NvcGVcblx0ICogQHBhcmFtIHtvYmplY3R9IFt2YWx1ZXNdXG5cdCAqL1xuICBkZXNjcmliZShzY29wZSwgdmFsdWVzKSB7XG4gICAgcmV0dXJuIHNldChkZXNjcmlwdG9ycywgc2NvcGUsIHZhbHVlcyk7XG4gIH1cblxuICBvdmVycmlkZShzY29wZSwgdmFsdWVzKSB7XG4gICAgcmV0dXJuIHNldChvdmVycmlkZXMsIHNjb3BlLCB2YWx1ZXMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJvdXRlcyB0aGUgbmFtZWQgZGVmYXVsdHMgdG8gZmFsbGJhY2sgdG8gYW5vdGhlciBzY29wZS9uYW1lLlxuXHQgKiBUaGlzIHJvdXRpbmcgaXMgdXNlZnVsIHdoZW4gdGhvc2UgdGFyZ2V0IHZhbHVlcywgbGlrZSBkZWZhdWx0cy5jb2xvciwgYXJlIGNoYW5nZWQgcnVudGltZS5cblx0ICogSWYgdGhlIHZhbHVlcyB3b3VsZCBiZSBjb3BpZWQsIHRoZSBydW50aW1lIGNoYW5nZSB3b3VsZCBub3QgdGFrZSBlZmZlY3QuIEJ5IHJvdXRpbmcsIHRoZVxuXHQgKiBmYWxsYmFjayBpcyBldmFsdWF0ZWQgYXQgZWFjaCBhY2Nlc3MsIHNvIGl0cyBhbHdheXMgdXAgdG8gZGF0ZS5cblx0ICpcblx0ICogRXhhbXBsZTpcblx0ICpcblx0ICogXHRkZWZhdWx0cy5yb3V0ZSgnZWxlbWVudHMuYXJjJywgJ2JhY2tncm91bmRDb2xvcicsICcnLCAnY29sb3InKVxuXHQgKiAgIC0gcmVhZHMgdGhlIGJhY2tncm91bmRDb2xvciBmcm9tIGRlZmF1bHRzLmNvbG9yIHdoZW4gdW5kZWZpbmVkIGxvY2FsbHlcblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNjb3BlIFNjb3BlIHRoaXMgcm91dGUgYXBwbGllcyB0by5cblx0ICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgUHJvcGVydHkgbmFtZSB0aGF0IHNob3VsZCBiZSByb3V0ZWQgdG8gZGlmZmVyZW50IG5hbWVzcGFjZSB3aGVuIG5vdCBkZWZpbmVkIGhlcmUuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0YXJnZXRTY29wZSBUaGUgbmFtZXNwYWNlIHdoZXJlIHRob3NlIHByb3BlcnRpZXMgc2hvdWxkIGJlIHJvdXRlZCB0by5cblx0ICogRW1wdHkgc3RyaW5nICgnJykgaXMgdGhlIHJvb3Qgb2YgZGVmYXVsdHMuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0YXJnZXROYW1lIFRoZSB0YXJnZXQgbmFtZSBpbiB0aGUgdGFyZ2V0IHNjb3BlIHRoZSBwcm9wZXJ0eSBzaG91bGQgYmUgcm91dGVkIHRvLlxuXHQgKi9cbiAgcm91dGUoc2NvcGUsIG5hbWUsIHRhcmdldFNjb3BlLCB0YXJnZXROYW1lKSB7XG4gICAgY29uc3Qgc2NvcGVPYmplY3QgPSBnZXRTY29wZSh0aGlzLCBzY29wZSk7XG4gICAgY29uc3QgdGFyZ2V0U2NvcGVPYmplY3QgPSBnZXRTY29wZSh0aGlzLCB0YXJnZXRTY29wZSk7XG4gICAgY29uc3QgcHJpdmF0ZU5hbWUgPSAnXycgKyBuYW1lO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoc2NvcGVPYmplY3QsIHtcbiAgICAgIC8vIEEgcHJpdmF0ZSBwcm9wZXJ0eSBpcyBkZWZpbmVkIHRvIGhvbGQgdGhlIGFjdHVhbCB2YWx1ZSwgd2hlbiB0aGlzIHByb3BlcnR5IGlzIHNldCBpbiBpdHMgc2NvcGUgKHNldCBpbiB0aGUgc2V0dGVyKVxuICAgICAgW3ByaXZhdGVOYW1lXToge1xuICAgICAgICB2YWx1ZTogc2NvcGVPYmplY3RbbmFtZV0sXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICB9LFxuICAgICAgLy8gVGhlIGFjdHVhbCBwcm9wZXJ0eSBpcyBkZWZpbmVkIGFzIGdldHRlci9zZXR0ZXIgc28gd2UgY2FuIGRvIHRoZSByb3V0aW5nIHdoZW4gdmFsdWUgaXMgbm90IGxvY2FsbHkgc2V0LlxuICAgICAgW25hbWVdOiB7XG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGdldCgpIHtcbiAgICAgICAgICBjb25zdCBsb2NhbCA9IHRoaXNbcHJpdmF0ZU5hbWVdO1xuICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHRhcmdldFNjb3BlT2JqZWN0W3RhcmdldE5hbWVdO1xuICAgICAgICAgIGlmIChpc09iamVjdChsb2NhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCB0YXJnZXQsIGxvY2FsKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlT3JEZWZhdWx0KGxvY2FsLCB0YXJnZXQpO1xuICAgICAgICB9LFxuICAgICAgICBzZXQodmFsdWUpIHtcbiAgICAgICAgICB0aGlzW3ByaXZhdGVOYW1lXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBhcHBseShhcHBsaWVycykge1xuICAgIGFwcGxpZXJzLmZvckVhY2goKGFwcGx5KSA9PiBhcHBseSh0aGlzKSk7XG4gIH1cbn1cblxuLy8gc2luZ2xldG9uIGluc3RhbmNlXG5leHBvcnQgZGVmYXVsdCAvKiAjX19QVVJFX18gKi8gbmV3IERlZmF1bHRzKHtcbiAgX3NjcmlwdGFibGU6IChuYW1lKSA9PiAhbmFtZS5zdGFydHNXaXRoKCdvbicpLFxuICBfaW5kZXhhYmxlOiAobmFtZSkgPT4gbmFtZSAhPT0gJ2V2ZW50cycsXG4gIGhvdmVyOiB7XG4gICAgX2ZhbGxiYWNrOiAnaW50ZXJhY3Rpb24nXG4gIH0sXG4gIGludGVyYWN0aW9uOiB7XG4gICAgX3NjcmlwdGFibGU6IGZhbHNlLFxuICAgIF9pbmRleGFibGU6IGZhbHNlLFxuICB9XG59LCBbYXBwbHlBbmltYXRpb25zRGVmYXVsdHMsIGFwcGx5TGF5b3V0c0RlZmF1bHRzLCBhcHBseVNjYWxlRGVmYXVsdHNdKTtcbiIsICJpbXBvcnQgdHlwZSB7XG4gIENoYXJ0LFxuICBQb2ludCxcbiAgRm9udFNwZWMsXG4gIENhbnZhc0ZvbnRTcGVjLFxuICBQb2ludFN0eWxlLFxuICBSZW5kZXJUZXh0T3B0cyxcbiAgQmFja2Ryb3BPcHRpb25zXG59IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcbmltcG9ydCB0eXBlIHtcbiAgVFJCTCxcbiAgU3BsaW5lUG9pbnQsXG4gIFJvdW5kZWRSZWN0LFxuICBUUkJMQ29ybmVyc1xufSBmcm9tICcuLi90eXBlcy9nZW9tZXRyaWMuanMnO1xuaW1wb3J0IHtpc0FycmF5LCBpc051bGxPclVuZGVmfSBmcm9tICcuL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge1BJLCBUQVUsIEhBTEZfUEksIFFVQVJURVJfUEksIFRXT19USElSRFNfUEksIFJBRF9QRVJfREVHfSBmcm9tICcuL2hlbHBlcnMubWF0aC5qcyc7XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIGZvbnQgb2JqZWN0IGludG8gYSBDU1MgZm9udCBzdHJpbmcuXG4gKiBAcGFyYW0gZm9udCAtIEEgZm9udCBvYmplY3QuXG4gKiBAcmV0dXJuIFRoZSBDU1MgZm9udCBzdHJpbmcuIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvZm9udFxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvRm9udFN0cmluZyhmb250OiBGb250U3BlYykge1xuICBpZiAoIWZvbnQgfHwgaXNOdWxsT3JVbmRlZihmb250LnNpemUpIHx8IGlzTnVsbE9yVW5kZWYoZm9udC5mYW1pbHkpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gKGZvbnQuc3R5bGUgPyBmb250LnN0eWxlICsgJyAnIDogJycpXG5cdFx0KyAoZm9udC53ZWlnaHQgPyBmb250LndlaWdodCArICcgJyA6ICcnKVxuXHRcdCsgZm9udC5zaXplICsgJ3B4ICdcblx0XHQrIGZvbnQuZmFtaWx5O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfbWVhc3VyZVRleHQoXG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+LFxuICBnYzogc3RyaW5nW10sXG4gIGxvbmdlc3Q6IG51bWJlcixcbiAgc3RyaW5nOiBzdHJpbmdcbikge1xuICBsZXQgdGV4dFdpZHRoID0gZGF0YVtzdHJpbmddO1xuICBpZiAoIXRleHRXaWR0aCkge1xuICAgIHRleHRXaWR0aCA9IGRhdGFbc3RyaW5nXSA9IGN0eC5tZWFzdXJlVGV4dChzdHJpbmcpLndpZHRoO1xuICAgIGdjLnB1c2goc3RyaW5nKTtcbiAgfVxuICBpZiAodGV4dFdpZHRoID4gbG9uZ2VzdCkge1xuICAgIGxvbmdlc3QgPSB0ZXh0V2lkdGg7XG4gIH1cbiAgcmV0dXJuIGxvbmdlc3Q7XG59XG5cbnR5cGUgVGhpbmcgPSBzdHJpbmcgfCB1bmRlZmluZWQgfCBudWxsXG50eXBlIFRoaW5ncyA9IChUaGluZyB8IFRoaW5nW10pW11cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuZXhwb3J0IGZ1bmN0aW9uIF9sb25nZXN0VGV4dChcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIGZvbnQ6IHN0cmluZyxcbiAgYXJyYXlPZlRoaW5nczogVGhpbmdzLFxuICBjYWNoZT86IHtkYXRhPzogUmVjb3JkPHN0cmluZywgbnVtYmVyPiwgZ2FyYmFnZUNvbGxlY3Q/OiBzdHJpbmdbXSwgZm9udD86IHN0cmluZ31cbikge1xuICBjYWNoZSA9IGNhY2hlIHx8IHt9O1xuICBsZXQgZGF0YSA9IGNhY2hlLmRhdGEgPSBjYWNoZS5kYXRhIHx8IHt9O1xuICBsZXQgZ2MgPSBjYWNoZS5nYXJiYWdlQ29sbGVjdCA9IGNhY2hlLmdhcmJhZ2VDb2xsZWN0IHx8IFtdO1xuXG4gIGlmIChjYWNoZS5mb250ICE9PSBmb250KSB7XG4gICAgZGF0YSA9IGNhY2hlLmRhdGEgPSB7fTtcbiAgICBnYyA9IGNhY2hlLmdhcmJhZ2VDb2xsZWN0ID0gW107XG4gICAgY2FjaGUuZm9udCA9IGZvbnQ7XG4gIH1cblxuICBjdHguc2F2ZSgpO1xuXG4gIGN0eC5mb250ID0gZm9udDtcbiAgbGV0IGxvbmdlc3QgPSAwO1xuICBjb25zdCBpbGVuID0gYXJyYXlPZlRoaW5ncy5sZW5ndGg7XG4gIGxldCBpOiBudW1iZXIsIGo6IG51bWJlciwgamxlbjogbnVtYmVyLCB0aGluZzogVGhpbmcgfCBUaGluZ1tdLCBuZXN0ZWRUaGluZzogVGhpbmcgfCBUaGluZ1tdO1xuICBmb3IgKGkgPSAwOyBpIDwgaWxlbjsgaSsrKSB7XG4gICAgdGhpbmcgPSBhcnJheU9mVGhpbmdzW2ldO1xuXG4gICAgLy8gVW5kZWZpbmVkIHN0cmluZ3MgYW5kIGFycmF5cyBzaG91bGQgbm90IGJlIG1lYXN1cmVkXG4gICAgaWYgKHRoaW5nICE9PSB1bmRlZmluZWQgJiYgdGhpbmcgIT09IG51bGwgJiYgIWlzQXJyYXkodGhpbmcpKSB7XG4gICAgICBsb25nZXN0ID0gX21lYXN1cmVUZXh0KGN0eCwgZGF0YSwgZ2MsIGxvbmdlc3QsIHRoaW5nKTtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkodGhpbmcpKSB7XG4gICAgICAvLyBpZiBpdCBpcyBhbiBhcnJheSBsZXRzIG1lYXN1cmUgZWFjaCBlbGVtZW50XG4gICAgICAvLyB0byBkbyBtYXliZSBzaW1wbGlmeSB0aGlzIGZ1bmN0aW9uIGEgYml0IHNvIHdlIGNhbiBkbyB0aGlzIG1vcmUgcmVjdXJzaXZlbHk/XG4gICAgICBmb3IgKGogPSAwLCBqbGVuID0gdGhpbmcubGVuZ3RoOyBqIDwgamxlbjsgaisrKSB7XG4gICAgICAgIG5lc3RlZFRoaW5nID0gdGhpbmdbal07XG4gICAgICAgIC8vIFVuZGVmaW5lZCBzdHJpbmdzIGFuZCBhcnJheXMgc2hvdWxkIG5vdCBiZSBtZWFzdXJlZFxuICAgICAgICBpZiAobmVzdGVkVGhpbmcgIT09IHVuZGVmaW5lZCAmJiBuZXN0ZWRUaGluZyAhPT0gbnVsbCAmJiAhaXNBcnJheShuZXN0ZWRUaGluZykpIHtcbiAgICAgICAgICBsb25nZXN0ID0gX21lYXN1cmVUZXh0KGN0eCwgZGF0YSwgZ2MsIGxvbmdlc3QsIG5lc3RlZFRoaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGN0eC5yZXN0b3JlKCk7XG5cbiAgY29uc3QgZ2NMZW4gPSBnYy5sZW5ndGggLyAyO1xuICBpZiAoZ2NMZW4gPiBhcnJheU9mVGhpbmdzLmxlbmd0aCkge1xuICAgIGZvciAoaSA9IDA7IGkgPCBnY0xlbjsgaSsrKSB7XG4gICAgICBkZWxldGUgZGF0YVtnY1tpXV07XG4gICAgfVxuICAgIGdjLnNwbGljZSgwLCBnY0xlbik7XG4gIH1cbiAgcmV0dXJuIGxvbmdlc3Q7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYWxpZ25lZCBwaXhlbCB2YWx1ZSB0byBhdm9pZCBhbnRpLWFsaWFzaW5nIGJsdXJcbiAqIEBwYXJhbSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZS5cbiAqIEBwYXJhbSBwaXhlbCAtIEEgcGl4ZWwgdmFsdWUuXG4gKiBAcGFyYW0gd2lkdGggLSBUaGUgd2lkdGggb2YgdGhlIGVsZW1lbnQuXG4gKiBAcmV0dXJucyBUaGUgYWxpZ25lZCBwaXhlbCB2YWx1ZS5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYWxpZ25QaXhlbChjaGFydDogQ2hhcnQsIHBpeGVsOiBudW1iZXIsIHdpZHRoOiBudW1iZXIpIHtcbiAgY29uc3QgZGV2aWNlUGl4ZWxSYXRpbyA9IGNoYXJ0LmN1cnJlbnREZXZpY2VQaXhlbFJhdGlvO1xuICBjb25zdCBoYWxmV2lkdGggPSB3aWR0aCAhPT0gMCA/IE1hdGgubWF4KHdpZHRoIC8gMiwgMC41KSA6IDA7XG4gIHJldHVybiBNYXRoLnJvdW5kKChwaXhlbCAtIGhhbGZXaWR0aCkgKiBkZXZpY2VQaXhlbFJhdGlvKSAvIGRldmljZVBpeGVsUmF0aW8gKyBoYWxmV2lkdGg7XG59XG5cbi8qKlxuICogQ2xlYXJzIHRoZSBlbnRpcmUgY2FudmFzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJDYW52YXMoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCwgY3R4PzogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEKSB7XG4gIGN0eCA9IGN0eCB8fCBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcblxuICBjdHguc2F2ZSgpO1xuICAvLyBjYW52YXMud2lkdGggYW5kIGNhbnZhcy5oZWlnaHQgZG8gbm90IGNvbnNpZGVyIHRoZSBjYW52YXMgdHJhbnNmb3JtLFxuICAvLyB3aGlsZSBjbGVhclJlY3QgZG9lc1xuICBjdHgucmVzZXRUcmFuc2Zvcm0oKTtcbiAgY3R4LmNsZWFyUmVjdCgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuICBjdHgucmVzdG9yZSgpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERyYXdQb2ludE9wdGlvbnMge1xuICBwb2ludFN0eWxlOiBQb2ludFN0eWxlO1xuICByb3RhdGlvbj86IG51bWJlcjtcbiAgcmFkaXVzOiBudW1iZXI7XG4gIGJvcmRlcldpZHRoOiBudW1iZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkcmF3UG9pbnQoXG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICBvcHRpb25zOiBEcmF3UG9pbnRPcHRpb25zLFxuICB4OiBudW1iZXIsXG4gIHk6IG51bWJlclxuKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgZHJhd1BvaW50TGVnZW5kKGN0eCwgb3B0aW9ucywgeCwgeSwgbnVsbCk7XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG5leHBvcnQgZnVuY3Rpb24gZHJhd1BvaW50TGVnZW5kKFxuICBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCxcbiAgb3B0aW9uczogRHJhd1BvaW50T3B0aW9ucyxcbiAgeDogbnVtYmVyLFxuICB5OiBudW1iZXIsXG4gIHc6IG51bWJlclxuKSB7XG4gIGxldCB0eXBlOiBzdHJpbmcsIHhPZmZzZXQ6IG51bWJlciwgeU9mZnNldDogbnVtYmVyLCBzaXplOiBudW1iZXIsIGNvcm5lclJhZGl1czogbnVtYmVyLCB3aWR0aDogbnVtYmVyLCB4T2Zmc2V0VzogbnVtYmVyLCB5T2Zmc2V0VzogbnVtYmVyO1xuICBjb25zdCBzdHlsZSA9IG9wdGlvbnMucG9pbnRTdHlsZTtcbiAgY29uc3Qgcm90YXRpb24gPSBvcHRpb25zLnJvdGF0aW9uO1xuICBjb25zdCByYWRpdXMgPSBvcHRpb25zLnJhZGl1cztcbiAgbGV0IHJhZCA9IChyb3RhdGlvbiB8fCAwKSAqIFJBRF9QRVJfREVHO1xuXG4gIGlmIChzdHlsZSAmJiB0eXBlb2Ygc3R5bGUgPT09ICdvYmplY3QnKSB7XG4gICAgdHlwZSA9IHN0eWxlLnRvU3RyaW5nKCk7XG4gICAgaWYgKHR5cGUgPT09ICdbb2JqZWN0IEhUTUxJbWFnZUVsZW1lbnRdJyB8fCB0eXBlID09PSAnW29iamVjdCBIVE1MQ2FudmFzRWxlbWVudF0nKSB7XG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgY3R4LnRyYW5zbGF0ZSh4LCB5KTtcbiAgICAgIGN0eC5yb3RhdGUocmFkKTtcbiAgICAgIGN0eC5kcmF3SW1hZ2Uoc3R5bGUsIC1zdHlsZS53aWR0aCAvIDIsIC1zdHlsZS5oZWlnaHQgLyAyLCBzdHlsZS53aWR0aCwgc3R5bGUuaGVpZ2h0KTtcbiAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzTmFOKHJhZGl1cykgfHwgcmFkaXVzIDw9IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjdHguYmVnaW5QYXRoKCk7XG5cbiAgc3dpdGNoIChzdHlsZSkge1xuICAvLyBEZWZhdWx0IGluY2x1ZGVzIGNpcmNsZVxuICAgIGRlZmF1bHQ6XG4gICAgICBpZiAodykge1xuICAgICAgICBjdHguZWxsaXBzZSh4LCB5LCB3IC8gMiwgcmFkaXVzLCAwLCAwLCBUQVUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3R4LmFyYyh4LCB5LCByYWRpdXMsIDAsIFRBVSk7XG4gICAgICB9XG4gICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0cmlhbmdsZSc6XG4gICAgICB3aWR0aCA9IHcgPyB3IC8gMiA6IHJhZGl1cztcbiAgICAgIGN0eC5tb3ZlVG8oeCArIE1hdGguc2luKHJhZCkgKiB3aWR0aCwgeSAtIE1hdGguY29zKHJhZCkgKiByYWRpdXMpO1xuICAgICAgcmFkICs9IFRXT19USElSRFNfUEk7XG4gICAgICBjdHgubGluZVRvKHggKyBNYXRoLnNpbihyYWQpICogd2lkdGgsIHkgLSBNYXRoLmNvcyhyYWQpICogcmFkaXVzKTtcbiAgICAgIHJhZCArPSBUV09fVEhJUkRTX1BJO1xuICAgICAgY3R4LmxpbmVUbyh4ICsgTWF0aC5zaW4ocmFkKSAqIHdpZHRoLCB5IC0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cyk7XG4gICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdyZWN0Um91bmRlZCc6XG4gICAgLy8gTk9URTogdGhlIHJvdW5kZWQgcmVjdCBpbXBsZW1lbnRhdGlvbiBjaGFuZ2VkIHRvIHVzZSBgYXJjYCBpbnN0ZWFkIG9mXG4gICAgLy8gYHF1YWRyYXRpY0N1cnZlVG9gIHNpbmNlIGl0IGdlbmVyYXRlcyBiZXR0ZXIgcmVzdWx0cyB3aGVuIHJlY3QgaXNcbiAgICAvLyBhbG1vc3QgYSBjaXJjbGUuIDAuNTE2IChpbnN0ZWFkIG9mIDAuNSkgcHJvZHVjZXMgcmVzdWx0cyB3aXRoIHZpc3VhbGx5XG4gICAgLy8gY2xvc2VyIHByb3BvcnRpb24gdG8gdGhlIHByZXZpb3VzIGltcGwgYW5kIGl0IGlzIGluc2NyaWJlZCBpbiB0aGVcbiAgICAvLyBjaXJjbGUgd2l0aCBgcmFkaXVzYC4gRm9yIG1vcmUgZGV0YWlscywgc2VlIHRoZSBmb2xsb3dpbmcgUFJzOlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy81NTk3XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzU4NThcbiAgICAgIGNvcm5lclJhZGl1cyA9IHJhZGl1cyAqIDAuNTE2O1xuICAgICAgc2l6ZSA9IHJhZGl1cyAtIGNvcm5lclJhZGl1cztcbiAgICAgIHhPZmZzZXQgPSBNYXRoLmNvcyhyYWQgKyBRVUFSVEVSX1BJKSAqIHNpemU7XG4gICAgICB4T2Zmc2V0VyA9IE1hdGguY29zKHJhZCArIFFVQVJURVJfUEkpICogKHcgPyB3IC8gMiAtIGNvcm5lclJhZGl1cyA6IHNpemUpO1xuICAgICAgeU9mZnNldCA9IE1hdGguc2luKHJhZCArIFFVQVJURVJfUEkpICogc2l6ZTtcbiAgICAgIHlPZmZzZXRXID0gTWF0aC5zaW4ocmFkICsgUVVBUlRFUl9QSSkgKiAodyA/IHcgLyAyIC0gY29ybmVyUmFkaXVzIDogc2l6ZSk7XG4gICAgICBjdHguYXJjKHggLSB4T2Zmc2V0VywgeSAtIHlPZmZzZXQsIGNvcm5lclJhZGl1cywgcmFkIC0gUEksIHJhZCAtIEhBTEZfUEkpO1xuICAgICAgY3R4LmFyYyh4ICsgeU9mZnNldFcsIHkgLSB4T2Zmc2V0LCBjb3JuZXJSYWRpdXMsIHJhZCAtIEhBTEZfUEksIHJhZCk7XG4gICAgICBjdHguYXJjKHggKyB4T2Zmc2V0VywgeSArIHlPZmZzZXQsIGNvcm5lclJhZGl1cywgcmFkLCByYWQgKyBIQUxGX1BJKTtcbiAgICAgIGN0eC5hcmMoeCAtIHlPZmZzZXRXLCB5ICsgeE9mZnNldCwgY29ybmVyUmFkaXVzLCByYWQgKyBIQUxGX1BJLCByYWQgKyBQSSk7XG4gICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdyZWN0JzpcbiAgICAgIGlmICghcm90YXRpb24pIHtcbiAgICAgICAgc2l6ZSA9IE1hdGguU1FSVDFfMiAqIHJhZGl1cztcbiAgICAgICAgd2lkdGggPSB3ID8gdyAvIDIgOiBzaXplO1xuICAgICAgICBjdHgucmVjdCh4IC0gd2lkdGgsIHkgLSBzaXplLCAyICogd2lkdGgsIDIgKiBzaXplKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICByYWQgKz0gUVVBUlRFUl9QSTtcbiAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSAncmVjdFJvdCc6XG4gICAgICB4T2Zmc2V0VyA9IE1hdGguY29zKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgIHhPZmZzZXQgPSBNYXRoLmNvcyhyYWQpICogcmFkaXVzO1xuICAgICAgeU9mZnNldCA9IE1hdGguc2luKHJhZCkgKiByYWRpdXM7XG4gICAgICB5T2Zmc2V0VyA9IE1hdGguc2luKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgIGN0eC5tb3ZlVG8oeCAtIHhPZmZzZXRXLCB5IC0geU9mZnNldCk7XG4gICAgICBjdHgubGluZVRvKHggKyB5T2Zmc2V0VywgeSAtIHhPZmZzZXQpO1xuICAgICAgY3R4LmxpbmVUbyh4ICsgeE9mZnNldFcsIHkgKyB5T2Zmc2V0KTtcbiAgICAgIGN0eC5saW5lVG8oeCAtIHlPZmZzZXRXLCB5ICsgeE9mZnNldCk7XG4gICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdjcm9zc1JvdCc6XG4gICAgICByYWQgKz0gUVVBUlRFUl9QSTtcbiAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgY2FzZSAnY3Jvc3MnOlxuICAgICAgeE9mZnNldFcgPSBNYXRoLmNvcyhyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICB4T2Zmc2V0ID0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cztcbiAgICAgIHlPZmZzZXQgPSBNYXRoLnNpbihyYWQpICogcmFkaXVzO1xuICAgICAgeU9mZnNldFcgPSBNYXRoLnNpbihyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICBjdHgubW92ZVRvKHggLSB4T2Zmc2V0VywgeSAtIHlPZmZzZXQpO1xuICAgICAgY3R4LmxpbmVUbyh4ICsgeE9mZnNldFcsIHkgKyB5T2Zmc2V0KTtcbiAgICAgIGN0eC5tb3ZlVG8oeCArIHlPZmZzZXRXLCB5IC0geE9mZnNldCk7XG4gICAgICBjdHgubGluZVRvKHggLSB5T2Zmc2V0VywgeSArIHhPZmZzZXQpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnc3Rhcic6XG4gICAgICB4T2Zmc2V0VyA9IE1hdGguY29zKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgIHhPZmZzZXQgPSBNYXRoLmNvcyhyYWQpICogcmFkaXVzO1xuICAgICAgeU9mZnNldCA9IE1hdGguc2luKHJhZCkgKiByYWRpdXM7XG4gICAgICB5T2Zmc2V0VyA9IE1hdGguc2luKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgIGN0eC5tb3ZlVG8oeCAtIHhPZmZzZXRXLCB5IC0geU9mZnNldCk7XG4gICAgICBjdHgubGluZVRvKHggKyB4T2Zmc2V0VywgeSArIHlPZmZzZXQpO1xuICAgICAgY3R4Lm1vdmVUbyh4ICsgeU9mZnNldFcsIHkgLSB4T2Zmc2V0KTtcbiAgICAgIGN0eC5saW5lVG8oeCAtIHlPZmZzZXRXLCB5ICsgeE9mZnNldCk7XG4gICAgICByYWQgKz0gUVVBUlRFUl9QSTtcbiAgICAgIHhPZmZzZXRXID0gTWF0aC5jb3MocmFkKSAqICh3ID8gdyAvIDIgOiByYWRpdXMpO1xuICAgICAgeE9mZnNldCA9IE1hdGguY29zKHJhZCkgKiByYWRpdXM7XG4gICAgICB5T2Zmc2V0ID0gTWF0aC5zaW4ocmFkKSAqIHJhZGl1cztcbiAgICAgIHlPZmZzZXRXID0gTWF0aC5zaW4ocmFkKSAqICh3ID8gdyAvIDIgOiByYWRpdXMpO1xuICAgICAgY3R4Lm1vdmVUbyh4IC0geE9mZnNldFcsIHkgLSB5T2Zmc2V0KTtcbiAgICAgIGN0eC5saW5lVG8oeCArIHhPZmZzZXRXLCB5ICsgeU9mZnNldCk7XG4gICAgICBjdHgubW92ZVRvKHggKyB5T2Zmc2V0VywgeSAtIHhPZmZzZXQpO1xuICAgICAgY3R4LmxpbmVUbyh4IC0geU9mZnNldFcsIHkgKyB4T2Zmc2V0KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2xpbmUnOlxuICAgICAgeE9mZnNldCA9IHcgPyB3IC8gMiA6IE1hdGguY29zKHJhZCkgKiByYWRpdXM7XG4gICAgICB5T2Zmc2V0ID0gTWF0aC5zaW4ocmFkKSAqIHJhZGl1cztcbiAgICAgIGN0eC5tb3ZlVG8oeCAtIHhPZmZzZXQsIHkgLSB5T2Zmc2V0KTtcbiAgICAgIGN0eC5saW5lVG8oeCArIHhPZmZzZXQsIHkgKyB5T2Zmc2V0KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Rhc2gnOlxuICAgICAgY3R4Lm1vdmVUbyh4LCB5KTtcbiAgICAgIGN0eC5saW5lVG8oeCArIE1hdGguY29zKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKSwgeSArIE1hdGguc2luKHJhZCkgKiByYWRpdXMpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBmYWxzZTpcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgY3R4LmZpbGwoKTtcbiAgaWYgKG9wdGlvbnMuYm9yZGVyV2lkdGggPiAwKSB7XG4gICAgY3R4LnN0cm9rZSgpO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBwb2ludCBpcyBpbnNpZGUgdGhlIHJlY3RhbmdsZVxuICogQHBhcmFtIHBvaW50IC0gVGhlIHBvaW50IHRvIHRlc3RcbiAqIEBwYXJhbSBhcmVhIC0gVGhlIHJlY3RhbmdsZVxuICogQHBhcmFtIG1hcmdpbiAtIGFsbG93ZWQgbWFyZ2luXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2lzUG9pbnRJbkFyZWEoXG4gIHBvaW50OiBQb2ludCxcbiAgYXJlYTogVFJCTCxcbiAgbWFyZ2luPzogbnVtYmVyXG4pIHtcbiAgbWFyZ2luID0gbWFyZ2luIHx8IDAuNTsgLy8gbWFyZ2luIC0gZGVmYXVsdCBpcyB0byBtYXRjaCByb3VuZGVkIGRlY2ltYWxzXG5cbiAgcmV0dXJuICFhcmVhIHx8IChwb2ludCAmJiBwb2ludC54ID4gYXJlYS5sZWZ0IC0gbWFyZ2luICYmIHBvaW50LnggPCBhcmVhLnJpZ2h0ICsgbWFyZ2luICYmXG5cdFx0cG9pbnQueSA+IGFyZWEudG9wIC0gbWFyZ2luICYmIHBvaW50LnkgPCBhcmVhLmJvdHRvbSArIG1hcmdpbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGlwQXJlYShjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgYXJlYTogVFJCTCkge1xuICBjdHguc2F2ZSgpO1xuICBjdHguYmVnaW5QYXRoKCk7XG4gIGN0eC5yZWN0KGFyZWEubGVmdCwgYXJlYS50b3AsIGFyZWEucmlnaHQgLSBhcmVhLmxlZnQsIGFyZWEuYm90dG9tIC0gYXJlYS50b3ApO1xuICBjdHguY2xpcCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdW5jbGlwQXJlYShjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCkge1xuICBjdHgucmVzdG9yZSgpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc3RlcHBlZExpbmVUbyhcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIHByZXZpb3VzOiBQb2ludCxcbiAgdGFyZ2V0OiBQb2ludCxcbiAgZmxpcD86IGJvb2xlYW4sXG4gIG1vZGU/OiBzdHJpbmdcbikge1xuICBpZiAoIXByZXZpb3VzKSB7XG4gICAgcmV0dXJuIGN0eC5saW5lVG8odGFyZ2V0LngsIHRhcmdldC55KTtcbiAgfVxuICBpZiAobW9kZSA9PT0gJ21pZGRsZScpIHtcbiAgICBjb25zdCBtaWRwb2ludCA9IChwcmV2aW91cy54ICsgdGFyZ2V0LngpIC8gMi4wO1xuICAgIGN0eC5saW5lVG8obWlkcG9pbnQsIHByZXZpb3VzLnkpO1xuICAgIGN0eC5saW5lVG8obWlkcG9pbnQsIHRhcmdldC55KTtcbiAgfSBlbHNlIGlmIChtb2RlID09PSAnYWZ0ZXInICE9PSAhIWZsaXApIHtcbiAgICBjdHgubGluZVRvKHByZXZpb3VzLngsIHRhcmdldC55KTtcbiAgfSBlbHNlIHtcbiAgICBjdHgubGluZVRvKHRhcmdldC54LCBwcmV2aW91cy55KTtcbiAgfVxuICBjdHgubGluZVRvKHRhcmdldC54LCB0YXJnZXQueSk7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9iZXppZXJDdXJ2ZVRvKFxuICBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCxcbiAgcHJldmlvdXM6IFNwbGluZVBvaW50LFxuICB0YXJnZXQ6IFNwbGluZVBvaW50LFxuICBmbGlwPzogYm9vbGVhblxuKSB7XG4gIGlmICghcHJldmlvdXMpIHtcbiAgICByZXR1cm4gY3R4LmxpbmVUbyh0YXJnZXQueCwgdGFyZ2V0LnkpO1xuICB9XG4gIGN0eC5iZXppZXJDdXJ2ZVRvKFxuICAgIGZsaXAgPyBwcmV2aW91cy5jcDF4IDogcHJldmlvdXMuY3AyeCxcbiAgICBmbGlwID8gcHJldmlvdXMuY3AxeSA6IHByZXZpb3VzLmNwMnksXG4gICAgZmxpcCA/IHRhcmdldC5jcDJ4IDogdGFyZ2V0LmNwMXgsXG4gICAgZmxpcCA/IHRhcmdldC5jcDJ5IDogdGFyZ2V0LmNwMXksXG4gICAgdGFyZ2V0LngsXG4gICAgdGFyZ2V0LnkpO1xufVxuXG5mdW5jdGlvbiBzZXRSZW5kZXJPcHRzKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCBvcHRzOiBSZW5kZXJUZXh0T3B0cykge1xuICBpZiAob3B0cy50cmFuc2xhdGlvbikge1xuICAgIGN0eC50cmFuc2xhdGUob3B0cy50cmFuc2xhdGlvblswXSwgb3B0cy50cmFuc2xhdGlvblsxXSk7XG4gIH1cblxuICBpZiAoIWlzTnVsbE9yVW5kZWYob3B0cy5yb3RhdGlvbikpIHtcbiAgICBjdHgucm90YXRlKG9wdHMucm90YXRpb24pO1xuICB9XG5cbiAgaWYgKG9wdHMuY29sb3IpIHtcbiAgICBjdHguZmlsbFN0eWxlID0gb3B0cy5jb2xvcjtcbiAgfVxuXG4gIGlmIChvcHRzLnRleHRBbGlnbikge1xuICAgIGN0eC50ZXh0QWxpZ24gPSBvcHRzLnRleHRBbGlnbjtcbiAgfVxuXG4gIGlmIChvcHRzLnRleHRCYXNlbGluZSkge1xuICAgIGN0eC50ZXh0QmFzZWxpbmUgPSBvcHRzLnRleHRCYXNlbGluZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWNvcmF0ZVRleHQoXG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICB4OiBudW1iZXIsXG4gIHk6IG51bWJlcixcbiAgbGluZTogc3RyaW5nLFxuICBvcHRzOiBSZW5kZXJUZXh0T3B0c1xuKSB7XG4gIGlmIChvcHRzLnN0cmlrZXRocm91Z2ggfHwgb3B0cy51bmRlcmxpbmUpIHtcbiAgICAvKipcbiAgICAgKiBOb3cgdGhhdCBJRTExIHN1cHBvcnQgaGFzIGJlZW4gZHJvcHBlZCwgd2UgY2FuIHVzZSBtb3JlXG4gICAgICogb2YgdGhlIFRleHRNZXRyaWNzIG9iamVjdC4gVGhlIGFjdHVhbCBib3VuZGluZyBib3hlc1xuICAgICAqIGFyZSB1bmZsYWdnZWQgaW4gQ2hyb21lLCBGaXJlZm94LCBFZGdlLCBhbmQgU2FmYXJpIHNvIHRoZXlcbiAgICAgKiBjYW4gYmUgc2FmZWx5IHVzZWQuXG4gICAgICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9UZXh0TWV0cmljcyNCcm93c2VyX2NvbXBhdGliaWxpdHlcbiAgICAgKi9cbiAgICBjb25zdCBtZXRyaWNzID0gY3R4Lm1lYXN1cmVUZXh0KGxpbmUpO1xuICAgIGNvbnN0IGxlZnQgPSB4IC0gbWV0cmljcy5hY3R1YWxCb3VuZGluZ0JveExlZnQ7XG4gICAgY29uc3QgcmlnaHQgPSB4ICsgbWV0cmljcy5hY3R1YWxCb3VuZGluZ0JveFJpZ2h0O1xuICAgIGNvbnN0IHRvcCA9IHkgLSBtZXRyaWNzLmFjdHVhbEJvdW5kaW5nQm94QXNjZW50O1xuICAgIGNvbnN0IGJvdHRvbSA9IHkgKyBtZXRyaWNzLmFjdHVhbEJvdW5kaW5nQm94RGVzY2VudDtcbiAgICBjb25zdCB5RGVjb3JhdGlvbiA9IG9wdHMuc3RyaWtldGhyb3VnaCA/ICh0b3AgKyBib3R0b20pIC8gMiA6IGJvdHRvbTtcblxuICAgIGN0eC5zdHJva2VTdHlsZSA9IGN0eC5maWxsU3R5bGU7XG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGN0eC5saW5lV2lkdGggPSBvcHRzLmRlY29yYXRpb25XaWR0aCB8fCAyO1xuICAgIGN0eC5tb3ZlVG8obGVmdCwgeURlY29yYXRpb24pO1xuICAgIGN0eC5saW5lVG8ocmlnaHQsIHlEZWNvcmF0aW9uKTtcbiAgICBjdHguc3Ryb2tlKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZHJhd0JhY2tkcm9wKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCBvcHRzOiBCYWNrZHJvcE9wdGlvbnMpIHtcbiAgY29uc3Qgb2xkQ29sb3IgPSBjdHguZmlsbFN0eWxlO1xuXG4gIGN0eC5maWxsU3R5bGUgPSBvcHRzLmNvbG9yIGFzIHN0cmluZztcbiAgY3R4LmZpbGxSZWN0KG9wdHMubGVmdCwgb3B0cy50b3AsIG9wdHMud2lkdGgsIG9wdHMuaGVpZ2h0KTtcbiAgY3R4LmZpbGxTdHlsZSA9IG9sZENvbG9yO1xufVxuXG4vKipcbiAqIFJlbmRlciB0ZXh0IG9udG8gdGhlIGNhbnZhc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyVGV4dChcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIHRleHQ6IHN0cmluZyB8IHN0cmluZ1tdLFxuICB4OiBudW1iZXIsXG4gIHk6IG51bWJlcixcbiAgZm9udDogQ2FudmFzRm9udFNwZWMsXG4gIG9wdHM6IFJlbmRlclRleHRPcHRzID0ge31cbikge1xuICBjb25zdCBsaW5lcyA9IGlzQXJyYXkodGV4dCkgPyB0ZXh0IDogW3RleHRdO1xuICBjb25zdCBzdHJva2UgPSBvcHRzLnN0cm9rZVdpZHRoID4gMCAmJiBvcHRzLnN0cm9rZUNvbG9yICE9PSAnJztcbiAgbGV0IGk6IG51bWJlciwgbGluZTogc3RyaW5nO1xuXG4gIGN0eC5zYXZlKCk7XG4gIGN0eC5mb250ID0gZm9udC5zdHJpbmc7XG4gIHNldFJlbmRlck9wdHMoY3R4LCBvcHRzKTtcblxuICBmb3IgKGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICBsaW5lID0gbGluZXNbaV07XG5cbiAgICBpZiAob3B0cy5iYWNrZHJvcCkge1xuICAgICAgZHJhd0JhY2tkcm9wKGN0eCwgb3B0cy5iYWNrZHJvcCk7XG4gICAgfVxuXG4gICAgaWYgKHN0cm9rZSkge1xuICAgICAgaWYgKG9wdHMuc3Ryb2tlQ29sb3IpIHtcbiAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gb3B0cy5zdHJva2VDb2xvcjtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc051bGxPclVuZGVmKG9wdHMuc3Ryb2tlV2lkdGgpKSB7XG4gICAgICAgIGN0eC5saW5lV2lkdGggPSBvcHRzLnN0cm9rZVdpZHRoO1xuICAgICAgfVxuXG4gICAgICBjdHguc3Ryb2tlVGV4dChsaW5lLCB4LCB5LCBvcHRzLm1heFdpZHRoKTtcbiAgICB9XG5cbiAgICBjdHguZmlsbFRleHQobGluZSwgeCwgeSwgb3B0cy5tYXhXaWR0aCk7XG4gICAgZGVjb3JhdGVUZXh0KGN0eCwgeCwgeSwgbGluZSwgb3B0cyk7XG5cbiAgICB5ICs9IE51bWJlcihmb250LmxpbmVIZWlnaHQpO1xuICB9XG5cbiAgY3R4LnJlc3RvcmUoKTtcbn1cblxuLyoqXG4gKiBBZGQgYSBwYXRoIG9mIGEgcmVjdGFuZ2xlIHdpdGggcm91bmRlZCBjb3JuZXJzIHRvIHRoZSBjdXJyZW50IHN1Yi1wYXRoXG4gKiBAcGFyYW0gY3R4IC0gQ29udGV4dFxuICogQHBhcmFtIHJlY3QgLSBCb3VuZGluZyByZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRSb3VuZGVkUmVjdFBhdGgoXG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICByZWN0OiBSb3VuZGVkUmVjdCAmIHsgcmFkaXVzOiBUUkJMQ29ybmVycyB9XG4pIHtcbiAgY29uc3Qge3gsIHksIHcsIGgsIHJhZGl1c30gPSByZWN0O1xuXG4gIC8vIHRvcCBsZWZ0IGFyY1xuICBjdHguYXJjKHggKyByYWRpdXMudG9wTGVmdCwgeSArIHJhZGl1cy50b3BMZWZ0LCByYWRpdXMudG9wTGVmdCwgMS41ICogUEksIFBJLCB0cnVlKTtcblxuICAvLyBsaW5lIGZyb20gdG9wIGxlZnQgdG8gYm90dG9tIGxlZnRcbiAgY3R4LmxpbmVUbyh4LCB5ICsgaCAtIHJhZGl1cy5ib3R0b21MZWZ0KTtcblxuICAvLyBib3R0b20gbGVmdCBhcmNcbiAgY3R4LmFyYyh4ICsgcmFkaXVzLmJvdHRvbUxlZnQsIHkgKyBoIC0gcmFkaXVzLmJvdHRvbUxlZnQsIHJhZGl1cy5ib3R0b21MZWZ0LCBQSSwgSEFMRl9QSSwgdHJ1ZSk7XG5cbiAgLy8gbGluZSBmcm9tIGJvdHRvbSBsZWZ0IHRvIGJvdHRvbSByaWdodFxuICBjdHgubGluZVRvKHggKyB3IC0gcmFkaXVzLmJvdHRvbVJpZ2h0LCB5ICsgaCk7XG5cbiAgLy8gYm90dG9tIHJpZ2h0IGFyY1xuICBjdHguYXJjKHggKyB3IC0gcmFkaXVzLmJvdHRvbVJpZ2h0LCB5ICsgaCAtIHJhZGl1cy5ib3R0b21SaWdodCwgcmFkaXVzLmJvdHRvbVJpZ2h0LCBIQUxGX1BJLCAwLCB0cnVlKTtcblxuICAvLyBsaW5lIGZyb20gYm90dG9tIHJpZ2h0IHRvIHRvcCByaWdodFxuICBjdHgubGluZVRvKHggKyB3LCB5ICsgcmFkaXVzLnRvcFJpZ2h0KTtcblxuICAvLyB0b3AgcmlnaHQgYXJjXG4gIGN0eC5hcmMoeCArIHcgLSByYWRpdXMudG9wUmlnaHQsIHkgKyByYWRpdXMudG9wUmlnaHQsIHJhZGl1cy50b3BSaWdodCwgMCwgLUhBTEZfUEksIHRydWUpO1xuXG4gIC8vIGxpbmUgZnJvbSB0b3AgcmlnaHQgdG8gdG9wIGxlZnRcbiAgY3R4LmxpbmVUbyh4ICsgcmFkaXVzLnRvcExlZnQsIHkpO1xufVxuIiwgImltcG9ydCBkZWZhdWx0cyBmcm9tICcuLi9jb3JlL2NvcmUuZGVmYXVsdHMuanMnO1xuaW1wb3J0IHtpc0FycmF5LCBpc09iamVjdCwgdG9EaW1lbnNpb24sIHZhbHVlT3JEZWZhdWx0fSBmcm9tICcuL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge3RvRm9udFN0cmluZ30gZnJvbSAnLi9oZWxwZXJzLmNhbnZhcy5qcyc7XG5pbXBvcnQgdHlwZSB7Q2hhcnRBcmVhLCBGb250U3BlYywgUG9pbnR9IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcbmltcG9ydCB0eXBlIHtUUkJMLCBUUkJMQ29ybmVyc30gZnJvbSAnLi4vdHlwZXMvZ2VvbWV0cmljLmpzJztcblxuY29uc3QgTElORV9IRUlHSFQgPSAvXihub3JtYWx8KFxcZCsoPzpcXC5cXGQrKT8pKHB4fGVtfCUpPykkLztcbmNvbnN0IEZPTlRfU1RZTEUgPSAvXihub3JtYWx8aXRhbGljfGluaXRpYWx8aW5oZXJpdHx1bnNldHwob2JsaXF1ZSggLT9bMC05XT9bMC05XWRlZyk/KSkkLztcblxuLyoqXG4gKiBAYWxpYXMgQ2hhcnQuaGVscGVycy5vcHRpb25zXG4gKiBAbmFtZXNwYWNlXG4gKi9cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIGxpbmUgaGVpZ2h0IGB2YWx1ZWAgaW4gcGl4ZWxzIGZvciBhIHNwZWNpZmljIGZvbnQgYHNpemVgLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIGxpbmVIZWlnaHQgdG8gcGFyc2UgKGVnLiAxLjYsICcxNHB4JywgJzc1JScsICcxLjZlbScpLlxuICogQHBhcmFtIHNpemUgLSBUaGUgZm9udCBzaXplIChpbiBwaXhlbHMpIHVzZWQgdG8gcmVzb2x2ZSByZWxhdGl2ZSBgdmFsdWVgLlxuICogQHJldHVybnMgVGhlIGVmZmVjdGl2ZSBsaW5lIGhlaWdodCBpbiBwaXhlbHMgKHNpemUgKiAxLjIgaWYgdmFsdWUgaXMgaW52YWxpZCkuXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9saW5lLWhlaWdodFxuICogQHNpbmNlIDIuNy4wXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0xpbmVIZWlnaHQodmFsdWU6IG51bWJlciB8IHN0cmluZywgc2l6ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgbWF0Y2hlcyA9ICgnJyArIHZhbHVlKS5tYXRjaChMSU5FX0hFSUdIVCk7XG4gIGlmICghbWF0Y2hlcyB8fCBtYXRjaGVzWzFdID09PSAnbm9ybWFsJykge1xuICAgIHJldHVybiBzaXplICogMS4yO1xuICB9XG5cbiAgdmFsdWUgPSArbWF0Y2hlc1syXTtcblxuICBzd2l0Y2ggKG1hdGNoZXNbM10pIHtcbiAgICBjYXNlICdweCc6XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgY2FzZSAnJSc6XG4gICAgICB2YWx1ZSAvPSAxMDA7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgYnJlYWs7XG4gIH1cblxuICByZXR1cm4gc2l6ZSAqIHZhbHVlO1xufVxuXG5jb25zdCBudW1iZXJPclplcm8gPSAodjogdW5rbm93bikgPT4gK3YgfHwgMDtcblxuLyoqXG4gKiBAcGFyYW0gdmFsdWVcbiAqIEBwYXJhbSBwcm9wc1xuICovXG5leHBvcnQgZnVuY3Rpb24gX3JlYWRWYWx1ZVRvUHJvcHM8SyBleHRlbmRzIHN0cmluZz4odmFsdWU6IG51bWJlciB8IFJlY29yZDxLLCBudW1iZXI+LCBwcm9wczogS1tdKTogUmVjb3JkPEssIG51bWJlcj47XG5leHBvcnQgZnVuY3Rpb24gX3JlYWRWYWx1ZVRvUHJvcHM8SyBleHRlbmRzIHN0cmluZywgVCBleHRlbmRzIHN0cmluZz4odmFsdWU6IG51bWJlciB8IFJlY29yZDxLICYgVCwgbnVtYmVyPiwgcHJvcHM6IFJlY29yZDxULCBLPik6IFJlY29yZDxULCBudW1iZXI+O1xuZXhwb3J0IGZ1bmN0aW9uIF9yZWFkVmFsdWVUb1Byb3BzKHZhbHVlOiBudW1iZXIgfCBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+LCBwcm9wczogc3RyaW5nW10gfCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSB7XG4gIGNvbnN0IHJldCA9IHt9O1xuICBjb25zdCBvYmpQcm9wcyA9IGlzT2JqZWN0KHByb3BzKTtcbiAgY29uc3Qga2V5cyA9IG9ialByb3BzID8gT2JqZWN0LmtleXMocHJvcHMpIDogcHJvcHM7XG4gIGNvbnN0IHJlYWQgPSBpc09iamVjdCh2YWx1ZSlcbiAgICA/IG9ialByb3BzXG4gICAgICA/IHByb3AgPT4gdmFsdWVPckRlZmF1bHQodmFsdWVbcHJvcF0sIHZhbHVlW3Byb3BzW3Byb3BdXSlcbiAgICAgIDogcHJvcCA9PiB2YWx1ZVtwcm9wXVxuICAgIDogKCkgPT4gdmFsdWU7XG5cbiAgZm9yIChjb25zdCBwcm9wIG9mIGtleXMpIHtcbiAgICByZXRbcHJvcF0gPSBudW1iZXJPclplcm8ocmVhZChwcm9wKSk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZ2l2ZW4gdmFsdWUgaW50byBhIFRSQkwgb2JqZWN0LlxuICogQHBhcmFtIHZhbHVlIC0gSWYgYSBudW1iZXIsIHNldCB0aGUgdmFsdWUgdG8gYWxsIFRSQkwgY29tcG9uZW50LFxuICogIGVsc2UsIGlmIGFuIG9iamVjdCwgdXNlIGRlZmluZWQgcHJvcGVydGllcyBhbmQgc2V0cyB1bmRlZmluZWQgb25lcyB0byAwLlxuICogIHggLyB5IGFyZSBzaG9ydGhhbmRzIGZvciBzYW1lIHZhbHVlIGZvciBsZWZ0L3JpZ2h0IGFuZCB0b3AvYm90dG9tLlxuICogQHJldHVybnMgVGhlIHBhZGRpbmcgdmFsdWVzICh0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQpXG4gKiBAc2luY2UgMy4wLjBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvVFJCTCh2YWx1ZTogbnVtYmVyIHwgVFJCTCB8IFBvaW50KSB7XG4gIHJldHVybiBfcmVhZFZhbHVlVG9Qcm9wcyh2YWx1ZSwge3RvcDogJ3knLCByaWdodDogJ3gnLCBib3R0b206ICd5JywgbGVmdDogJ3gnfSk7XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIHZhbHVlIGludG8gYSBUUkJMIGNvcm5lcnMgb2JqZWN0IChzaW1pbGFyIHdpdGggY3NzIGJvcmRlci1yYWRpdXMpLlxuICogQHBhcmFtIHZhbHVlIC0gSWYgYSBudW1iZXIsIHNldCB0aGUgdmFsdWUgdG8gYWxsIFRSQkwgY29ybmVyIGNvbXBvbmVudHMsXG4gKiAgZWxzZSwgaWYgYW4gb2JqZWN0LCB1c2UgZGVmaW5lZCBwcm9wZXJ0aWVzIGFuZCBzZXRzIHVuZGVmaW5lZCBvbmVzIHRvIDAuXG4gKiBAcmV0dXJucyBUaGUgVFJCTCBjb3JuZXIgdmFsdWVzICh0b3BMZWZ0LCB0b3BSaWdodCwgYm90dG9tTGVmdCwgYm90dG9tUmlnaHQpXG4gKiBAc2luY2UgMy4wLjBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvVFJCTENvcm5lcnModmFsdWU6IG51bWJlciB8IFRSQkxDb3JuZXJzKSB7XG4gIHJldHVybiBfcmVhZFZhbHVlVG9Qcm9wcyh2YWx1ZSwgWyd0b3BMZWZ0JywgJ3RvcFJpZ2h0JywgJ2JvdHRvbUxlZnQnLCAnYm90dG9tUmlnaHQnXSk7XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIHZhbHVlIGludG8gYSBwYWRkaW5nIG9iamVjdCB3aXRoIHByZS1jb21wdXRlZCB3aWR0aC9oZWlnaHQuXG4gKiBAcGFyYW0gdmFsdWUgLSBJZiBhIG51bWJlciwgc2V0IHRoZSB2YWx1ZSB0byBhbGwgVFJCTCBjb21wb25lbnQsXG4gKiAgZWxzZSwgaWYgYW4gb2JqZWN0LCB1c2UgZGVmaW5lZCBwcm9wZXJ0aWVzIGFuZCBzZXRzIHVuZGVmaW5lZCBvbmVzIHRvIDAuXG4gKiAgeCAvIHkgYXJlIHNob3J0aGFuZHMgZm9yIHNhbWUgdmFsdWUgZm9yIGxlZnQvcmlnaHQgYW5kIHRvcC9ib3R0b20uXG4gKiBAcmV0dXJucyBUaGUgcGFkZGluZyB2YWx1ZXMgKHRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdCwgd2lkdGgsIGhlaWdodClcbiAqIEBzaW5jZSAyLjcuMFxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9QYWRkaW5nKHZhbHVlPzogbnVtYmVyIHwgVFJCTCk6IENoYXJ0QXJlYSB7XG4gIGNvbnN0IG9iaiA9IHRvVFJCTCh2YWx1ZSkgYXMgQ2hhcnRBcmVhO1xuXG4gIG9iai53aWR0aCA9IG9iai5sZWZ0ICsgb2JqLnJpZ2h0O1xuICBvYmouaGVpZ2h0ID0gb2JqLnRvcCArIG9iai5ib3R0b207XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBQYXJzZXMgZm9udCBvcHRpb25zIGFuZCByZXR1cm5zIHRoZSBmb250IG9iamVjdC5cbiAqIEBwYXJhbSBvcHRpb25zIC0gQSBvYmplY3QgdGhhdCBjb250YWlucyBmb250IG9wdGlvbnMgdG8gYmUgcGFyc2VkLlxuICogQHBhcmFtIGZhbGxiYWNrIC0gQSBvYmplY3QgdGhhdCBjb250YWlucyBmYWxsYmFjayBmb250IG9wdGlvbnMuXG4gKiBAcmV0dXJuIFRoZSBmb250IG9iamVjdC5cbiAqIEBwcml2YXRlXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvRm9udChvcHRpb25zOiBQYXJ0aWFsPEZvbnRTcGVjPiwgZmFsbGJhY2s/OiBQYXJ0aWFsPEZvbnRTcGVjPikge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgZmFsbGJhY2sgPSBmYWxsYmFjayB8fCBkZWZhdWx0cy5mb250IGFzIEZvbnRTcGVjO1xuXG4gIGxldCBzaXplID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy5zaXplLCBmYWxsYmFjay5zaXplKTtcblxuICBpZiAodHlwZW9mIHNpemUgPT09ICdzdHJpbmcnKSB7XG4gICAgc2l6ZSA9IHBhcnNlSW50KHNpemUsIDEwKTtcbiAgfVxuICBsZXQgc3R5bGUgPSB2YWx1ZU9yRGVmYXVsdChvcHRpb25zLnN0eWxlLCBmYWxsYmFjay5zdHlsZSk7XG4gIGlmIChzdHlsZSAmJiAhKCcnICsgc3R5bGUpLm1hdGNoKEZPTlRfU1RZTEUpKSB7XG4gICAgY29uc29sZS53YXJuKCdJbnZhbGlkIGZvbnQgc3R5bGUgc3BlY2lmaWVkOiBcIicgKyBzdHlsZSArICdcIicpO1xuICAgIHN0eWxlID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgZm9udCA9IHtcbiAgICBmYW1pbHk6IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMuZmFtaWx5LCBmYWxsYmFjay5mYW1pbHkpLFxuICAgIGxpbmVIZWlnaHQ6IHRvTGluZUhlaWdodCh2YWx1ZU9yRGVmYXVsdChvcHRpb25zLmxpbmVIZWlnaHQsIGZhbGxiYWNrLmxpbmVIZWlnaHQpLCBzaXplKSxcbiAgICBzaXplLFxuICAgIHN0eWxlLFxuICAgIHdlaWdodDogdmFsdWVPckRlZmF1bHQob3B0aW9ucy53ZWlnaHQsIGZhbGxiYWNrLndlaWdodCksXG4gICAgc3RyaW5nOiAnJ1xuICB9O1xuXG4gIGZvbnQuc3RyaW5nID0gdG9Gb250U3RyaW5nKGZvbnQpO1xuICByZXR1cm4gZm9udDtcbn1cblxuLyoqXG4gKiBFdmFsdWF0ZXMgdGhlIGdpdmVuIGBpbnB1dHNgIHNlcXVlbnRpYWxseSBhbmQgcmV0dXJucyB0aGUgZmlyc3QgZGVmaW5lZCB2YWx1ZS5cbiAqIEBwYXJhbSBpbnB1dHMgLSBBbiBhcnJheSBvZiB2YWx1ZXMsIGZhbGxpbmcgYmFjayB0byB0aGUgbGFzdCB2YWx1ZS5cbiAqIEBwYXJhbSBjb250ZXh0IC0gSWYgZGVmaW5lZCBhbmQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgYSBmdW5jdGlvbiwgdGhlIHZhbHVlXG4gKiBpcyBjYWxsZWQgd2l0aCBgY29udGV4dGAgYXMgZmlyc3QgYXJndW1lbnQgYW5kIHRoZSByZXN1bHQgYmVjb21lcyB0aGUgbmV3IGlucHV0LlxuICogQHBhcmFtIGluZGV4IC0gSWYgZGVmaW5lZCBhbmQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgYW4gYXJyYXksIHRoZSB2YWx1ZVxuICogYXQgYGluZGV4YCBiZWNvbWUgdGhlIG5ldyBpbnB1dC5cbiAqIEBwYXJhbSBpbmZvIC0gb2JqZWN0IHRvIHJldHVybiBpbmZvcm1hdGlvbiBhYm91dCByZXNvbHV0aW9uIGluXG4gKiBAcGFyYW0gaW5mby5jYWNoZWFibGUgLSBXaWxsIGJlIHNldCB0byBgZmFsc2VgIGlmIG9wdGlvbiBpcyBub3QgY2FjaGVhYmxlLlxuICogQHNpbmNlIDIuNy4wXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlKGlucHV0czogQXJyYXk8dW5rbm93bj4sIGNvbnRleHQ/OiBvYmplY3QsIGluZGV4PzogbnVtYmVyLCBpbmZvPzogeyBjYWNoZWFibGU6IGJvb2xlYW4gfSkge1xuICBsZXQgY2FjaGVhYmxlID0gdHJ1ZTtcbiAgbGV0IGk6IG51bWJlciwgaWxlbjogbnVtYmVyLCB2YWx1ZTogdW5rbm93bjtcblxuICBmb3IgKGkgPSAwLCBpbGVuID0gaW5wdXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIHZhbHVlID0gaW5wdXRzW2ldO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGNvbnRleHQgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhbHVlID0gdmFsdWUoY29udGV4dCk7XG4gICAgICBjYWNoZWFibGUgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGluZGV4ICE9PSB1bmRlZmluZWQgJiYgaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHZhbHVlID0gdmFsdWVbaW5kZXggJSB2YWx1ZS5sZW5ndGhdO1xuICAgICAgY2FjaGVhYmxlID0gZmFsc2U7XG4gICAgfVxuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoaW5mbyAmJiAhY2FjaGVhYmxlKSB7XG4gICAgICAgIGluZm8uY2FjaGVhYmxlID0gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIG1pbm1heFxuICogQHBhcmFtIGdyYWNlXG4gKiBAcGFyYW0gYmVnaW5BdFplcm9cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYWRkR3JhY2UobWlubWF4OiB7IG1pbjogbnVtYmVyOyBtYXg6IG51bWJlcjsgfSwgZ3JhY2U6IG51bWJlciB8IHN0cmluZywgYmVnaW5BdFplcm86IGJvb2xlYW4pIHtcbiAgY29uc3Qge21pbiwgbWF4fSA9IG1pbm1heDtcbiAgY29uc3QgY2hhbmdlID0gdG9EaW1lbnNpb24oZ3JhY2UsIChtYXggLSBtaW4pIC8gMik7XG4gIGNvbnN0IGtlZXBaZXJvID0gKHZhbHVlOiBudW1iZXIsIGFkZDogbnVtYmVyKSA9PiBiZWdpbkF0WmVybyAmJiB2YWx1ZSA9PT0gMCA/IDAgOiB2YWx1ZSArIGFkZDtcbiAgcmV0dXJuIHtcbiAgICBtaW46IGtlZXBaZXJvKG1pbiwgLU1hdGguYWJzKGNoYW5nZSkpLFxuICAgIG1heDoga2VlcFplcm8obWF4LCBjaGFuZ2UpXG4gIH07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgY29udGV4dCBpbmhlcml0aW5nIHBhcmVudENvbnRleHRcbiAqIEBwYXJhbSBwYXJlbnRDb250ZXh0XG4gKiBAcGFyYW0gY29udGV4dFxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbnRleHQ8VCBleHRlbmRzIG9iamVjdD4ocGFyZW50Q29udGV4dDogbnVsbCwgY29udGV4dDogVCk6IFQ7XG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29udGV4dDxUIGV4dGVuZHMgb2JqZWN0LCBQIGV4dGVuZHMgVD4ocGFyZW50Q29udGV4dDogUCwgY29udGV4dDogVCk6IFAgJiBUO1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbnRleHQocGFyZW50Q29udGV4dDogb2JqZWN0LCBjb250ZXh0OiBvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT2JqZWN0LmNyZWF0ZShwYXJlbnRDb250ZXh0KSwgY29udGV4dCk7XG59XG4iLCAiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVzZS1iZWZvcmUtZGVmaW5lICovXG5pbXBvcnQgdHlwZSB7QW55T2JqZWN0fSBmcm9tICcuLi90eXBlcy9iYXNpYy5qcyc7XG5pbXBvcnQgdHlwZSB7Q2hhcnRNZXRhfSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIFJlc29sdmVyT2JqZWN0S2V5LFxuICBSZXNvbHZlckNhY2hlLFxuICBSZXNvbHZlclByb3h5LFxuICBEZXNjcmlwdG9yRGVmYXVsdHMsXG4gIERlc2NyaXB0b3IsXG4gIENvbnRleHRDYWNoZSxcbiAgQ29udGV4dFByb3h5XG59IGZyb20gJy4vaGVscGVycy5jb25maWcudHlwZXMuanMnO1xuaW1wb3J0IHtpc0FycmF5LCBpc0Z1bmN0aW9uLCBpc09iamVjdCwgcmVzb2x2ZU9iamVjdEtleSwgX2NhcGl0YWxpemV9IGZyb20gJy4vaGVscGVycy5jb3JlLmpzJztcblxuZXhwb3J0ICogZnJvbSAnLi9oZWxwZXJzLmNvbmZpZy50eXBlcy5qcyc7XG5cbi8qKlxuICogQ3JlYXRlcyBhIFByb3h5IGZvciByZXNvbHZpbmcgcmF3IHZhbHVlcyBmb3Igb3B0aW9ucy5cbiAqIEBwYXJhbSBzY29wZXMgLSBUaGUgb3B0aW9uIHNjb3BlcyB0byBsb29rIGZvciB2YWx1ZXMsIGluIHJlc29sdXRpb24gb3JkZXJcbiAqIEBwYXJhbSBwcmVmaXhlcyAtIFRoZSBwcmVmaXhlcyBmb3IgdmFsdWVzLCBpbiByZXNvbHV0aW9uIG9yZGVyLlxuICogQHBhcmFtIHJvb3RTY29wZXMgLSBUaGUgcm9vdCBvcHRpb24gc2NvcGVzXG4gKiBAcGFyYW0gZmFsbGJhY2sgLSBQYXJlbnQgc2NvcGVzIGZhbGxiYWNrXG4gKiBAcGFyYW0gZ2V0VGFyZ2V0IC0gY2FsbGJhY2sgZm9yIGdldHRpbmcgdGhlIHRhcmdldCBmb3IgY2hhbmdlZCB2YWx1ZXNcbiAqIEByZXR1cm5zIFByb3h5XG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2NyZWF0ZVJlc29sdmVyPFxuICBUIGV4dGVuZHMgQW55T2JqZWN0W10gPSBBbnlPYmplY3RbXSxcbiAgUiBleHRlbmRzIEFueU9iamVjdFtdID0gVFxuPihcbiAgc2NvcGVzOiBULFxuICBwcmVmaXhlcyA9IFsnJ10sXG4gIHJvb3RTY29wZXM/OiBSLFxuICBmYWxsYmFjaz86IFJlc29sdmVyT2JqZWN0S2V5LFxuICBnZXRUYXJnZXQgPSAoKSA9PiBzY29wZXNbMF1cbikge1xuICBjb25zdCBmaW5hbFJvb3RTY29wZXMgPSByb290U2NvcGVzIHx8IHNjb3BlcztcbiAgaWYgKHR5cGVvZiBmYWxsYmFjayA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBmYWxsYmFjayA9IF9yZXNvbHZlKCdfZmFsbGJhY2snLCBzY29wZXMpO1xuICB9XG4gIGNvbnN0IGNhY2hlOiBSZXNvbHZlckNhY2hlPFQsIFI+ID0ge1xuICAgIFtTeW1ib2wudG9TdHJpbmdUYWddOiAnT2JqZWN0JyxcbiAgICBfY2FjaGVhYmxlOiB0cnVlLFxuICAgIF9zY29wZXM6IHNjb3BlcyxcbiAgICBfcm9vdFNjb3BlczogZmluYWxSb290U2NvcGVzLFxuICAgIF9mYWxsYmFjazogZmFsbGJhY2ssXG4gICAgX2dldFRhcmdldDogZ2V0VGFyZ2V0LFxuICAgIG92ZXJyaWRlOiAoc2NvcGU6IEFueU9iamVjdCkgPT4gX2NyZWF0ZVJlc29sdmVyKFtzY29wZSwgLi4uc2NvcGVzXSwgcHJlZml4ZXMsIGZpbmFsUm9vdFNjb3BlcywgZmFsbGJhY2spLFxuICB9O1xuICByZXR1cm4gbmV3IFByb3h5KGNhY2hlLCB7XG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciB0aGUgZGVsZXRlIG9wZXJhdG9yLlxuICAgICAqL1xuICAgIGRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcDogc3RyaW5nKSB7XG4gICAgICBkZWxldGUgdGFyZ2V0W3Byb3BdOyAvLyByZW1vdmUgZnJvbSBjYWNoZVxuICAgICAgZGVsZXRlIHRhcmdldC5fa2V5czsgLy8gcmVtb3ZlIGNhY2hlZCBrZXlzXG4gICAgICBkZWxldGUgc2NvcGVzWzBdW3Byb3BdOyAvLyByZW1vdmUgZnJvbSB0b3AgbGV2ZWwgc2NvcGVcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIGdldHRpbmcgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqL1xuICAgIGdldCh0YXJnZXQsIHByb3A6IHN0cmluZykge1xuICAgICAgcmV0dXJuIF9jYWNoZWQodGFyZ2V0LCBwcm9wLFxuICAgICAgICAoKSA9PiBfcmVzb2x2ZVdpdGhQcmVmaXhlcyhwcm9wLCBwcmVmaXhlcywgc2NvcGVzLCB0YXJnZXQpKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLlxuICAgICAqIEFsc28gdXNlZCBieSBPYmplY3QuaGFzT3duUHJvcGVydHkuXG4gICAgICovXG4gICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcCkge1xuICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldC5fc2NvcGVzWzBdLCBwcm9wKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBPYmplY3QuZ2V0UHJvdG90eXBlT2YuXG4gICAgICovXG4gICAgZ2V0UHJvdG90eXBlT2YoKSB7XG4gICAgICByZXR1cm4gUmVmbGVjdC5nZXRQcm90b3R5cGVPZihzY29wZXNbMF0pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIHRoZSBpbiBvcGVyYXRvci5cbiAgICAgKi9cbiAgICBoYXModGFyZ2V0LCBwcm9wOiBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBnZXRLZXlzRnJvbUFsbFNjb3Blcyh0YXJnZXQpLmluY2x1ZGVzKHByb3ApO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIGFuZCBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzLlxuICAgICAqL1xuICAgIG93bktleXModGFyZ2V0KSB7XG4gICAgICByZXR1cm4gZ2V0S2V5c0Zyb21BbGxTY29wZXModGFyZ2V0KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBzZXR0aW5nIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKi9cbiAgICBzZXQodGFyZ2V0LCBwcm9wOiBzdHJpbmcsIHZhbHVlKSB7XG4gICAgICBjb25zdCBzdG9yYWdlID0gdGFyZ2V0Ll9zdG9yYWdlIHx8ICh0YXJnZXQuX3N0b3JhZ2UgPSBnZXRUYXJnZXQoKSk7XG4gICAgICB0YXJnZXRbcHJvcF0gPSBzdG9yYWdlW3Byb3BdID0gdmFsdWU7IC8vIHNldCB0byB0b3AgbGV2ZWwgc2NvcGUgKyBjYWNoZVxuICAgICAgZGVsZXRlIHRhcmdldC5fa2V5czsgLy8gcmVtb3ZlIGNhY2hlZCBrZXlzXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pIGFzIFJlc29sdmVyUHJveHk8VCwgUj47XG59XG5cbi8qKlxuICogUmV0dXJucyBhbiBQcm94eSBmb3IgcmVzb2x2aW5nIG9wdGlvbiB2YWx1ZXMgd2l0aCBjb250ZXh0LlxuICogQHBhcmFtIHByb3h5IC0gVGhlIFByb3h5IHJldHVybmVkIGJ5IGBfY3JlYXRlUmVzb2x2ZXJgXG4gKiBAcGFyYW0gY29udGV4dCAtIENvbnRleHQgb2JqZWN0IGZvciBzY3JpcHRhYmxlL2luZGV4YWJsZSBvcHRpb25zXG4gKiBAcGFyYW0gc3ViUHJveHkgLSBUaGUgcHJveHkgcHJvdmlkZWQgZm9yIHNjcmlwdGFibGUgb3B0aW9uc1xuICogQHBhcmFtIGRlc2NyaXB0b3JEZWZhdWx0cyAtIERlZmF1bHRzIGZvciBkZXNjcmlwdG9yc1xuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9hdHRhY2hDb250ZXh0PFxuICBUIGV4dGVuZHMgQW55T2JqZWN0W10gPSBBbnlPYmplY3RbXSxcbiAgUiBleHRlbmRzIEFueU9iamVjdFtdID0gVFxuPihcbiAgcHJveHk6IFJlc29sdmVyUHJveHk8VCwgUj4sXG4gIGNvbnRleHQ6IEFueU9iamVjdCxcbiAgc3ViUHJveHk/OiBSZXNvbHZlclByb3h5PFQsIFI+LFxuICBkZXNjcmlwdG9yRGVmYXVsdHM/OiBEZXNjcmlwdG9yRGVmYXVsdHNcbikge1xuICBjb25zdCBjYWNoZTogQ29udGV4dENhY2hlPFQsIFI+ID0ge1xuICAgIF9jYWNoZWFibGU6IGZhbHNlLFxuICAgIF9wcm94eTogcHJveHksXG4gICAgX2NvbnRleHQ6IGNvbnRleHQsXG4gICAgX3N1YlByb3h5OiBzdWJQcm94eSxcbiAgICBfc3RhY2s6IG5ldyBTZXQoKSxcbiAgICBfZGVzY3JpcHRvcnM6IF9kZXNjcmlwdG9ycyhwcm94eSwgZGVzY3JpcHRvckRlZmF1bHRzKSxcbiAgICBzZXRDb250ZXh0OiAoY3R4OiBBbnlPYmplY3QpID0+IF9hdHRhY2hDb250ZXh0KHByb3h5LCBjdHgsIHN1YlByb3h5LCBkZXNjcmlwdG9yRGVmYXVsdHMpLFxuICAgIG92ZXJyaWRlOiAoc2NvcGU6IEFueU9iamVjdCkgPT4gX2F0dGFjaENvbnRleHQocHJveHkub3ZlcnJpZGUoc2NvcGUpLCBjb250ZXh0LCBzdWJQcm94eSwgZGVzY3JpcHRvckRlZmF1bHRzKVxuICB9O1xuICByZXR1cm4gbmV3IFByb3h5KGNhY2hlLCB7XG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciB0aGUgZGVsZXRlIG9wZXJhdG9yLlxuICAgICAqL1xuICAgIGRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcCkge1xuICAgICAgZGVsZXRlIHRhcmdldFtwcm9wXTsgLy8gcmVtb3ZlIGZyb20gY2FjaGVcbiAgICAgIGRlbGV0ZSBwcm94eVtwcm9wXTsgLy8gcmVtb3ZlIGZyb20gcHJveHlcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIGdldHRpbmcgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqL1xuICAgIGdldCh0YXJnZXQsIHByb3A6IHN0cmluZywgcmVjZWl2ZXIpIHtcbiAgICAgIHJldHVybiBfY2FjaGVkKHRhcmdldCwgcHJvcCxcbiAgICAgICAgKCkgPT4gX3Jlc29sdmVXaXRoQ29udGV4dCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvci5cbiAgICAgKiBBbHNvIHVzZWQgYnkgT2JqZWN0Lmhhc093blByb3BlcnR5LlxuICAgICAqL1xuICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3ApIHtcbiAgICAgIHJldHVybiB0YXJnZXQuX2Rlc2NyaXB0b3JzLmFsbEtleXNcbiAgICAgICAgPyBSZWZsZWN0Lmhhcyhwcm94eSwgcHJvcCkgPyB7ZW51bWVyYWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlfSA6IHVuZGVmaW5lZFxuICAgICAgICA6IFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHByb3h5LCBwcm9wKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBPYmplY3QuZ2V0UHJvdG90eXBlT2YuXG4gICAgICovXG4gICAgZ2V0UHJvdG90eXBlT2YoKSB7XG4gICAgICByZXR1cm4gUmVmbGVjdC5nZXRQcm90b3R5cGVPZihwcm94eSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgdGhlIGluIG9wZXJhdG9yLlxuICAgICAqL1xuICAgIGhhcyh0YXJnZXQsIHByb3ApIHtcbiAgICAgIHJldHVybiBSZWZsZWN0Lmhhcyhwcm94eSwgcHJvcCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgYW5kIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMuXG4gICAgICovXG4gICAgb3duS2V5cygpIHtcbiAgICAgIHJldHVybiBSZWZsZWN0Lm93bktleXMocHJveHkpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIHNldHRpbmcgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqL1xuICAgIHNldCh0YXJnZXQsIHByb3AsIHZhbHVlKSB7XG4gICAgICBwcm94eVtwcm9wXSA9IHZhbHVlOyAvLyBzZXQgdG8gcHJveHlcbiAgICAgIGRlbGV0ZSB0YXJnZXRbcHJvcF07IC8vIHJlbW92ZSBmcm9tIGNhY2hlXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pIGFzIENvbnRleHRQcm94eTxULCBSPjtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2Rlc2NyaXB0b3JzKFxuICBwcm94eTogUmVzb2x2ZXJDYWNoZSxcbiAgZGVmYXVsdHM6IERlc2NyaXB0b3JEZWZhdWx0cyA9IHtzY3JpcHRhYmxlOiB0cnVlLCBpbmRleGFibGU6IHRydWV9XG4pOiBEZXNjcmlwdG9yIHtcbiAgY29uc3Qge19zY3JpcHRhYmxlID0gZGVmYXVsdHMuc2NyaXB0YWJsZSwgX2luZGV4YWJsZSA9IGRlZmF1bHRzLmluZGV4YWJsZSwgX2FsbEtleXMgPSBkZWZhdWx0cy5hbGxLZXlzfSA9IHByb3h5O1xuICByZXR1cm4ge1xuICAgIGFsbEtleXM6IF9hbGxLZXlzLFxuICAgIHNjcmlwdGFibGU6IF9zY3JpcHRhYmxlLFxuICAgIGluZGV4YWJsZTogX2luZGV4YWJsZSxcbiAgICBpc1NjcmlwdGFibGU6IGlzRnVuY3Rpb24oX3NjcmlwdGFibGUpID8gX3NjcmlwdGFibGUgOiAoKSA9PiBfc2NyaXB0YWJsZSxcbiAgICBpc0luZGV4YWJsZTogaXNGdW5jdGlvbihfaW5kZXhhYmxlKSA/IF9pbmRleGFibGUgOiAoKSA9PiBfaW5kZXhhYmxlXG4gIH07XG59XG5cbmNvbnN0IHJlYWRLZXkgPSAocHJlZml4OiBzdHJpbmcsIG5hbWU6IHN0cmluZykgPT4gcHJlZml4ID8gcHJlZml4ICsgX2NhcGl0YWxpemUobmFtZSkgOiBuYW1lO1xuY29uc3QgbmVlZHNTdWJSZXNvbHZlciA9IChwcm9wOiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKSA9PiBpc09iamVjdCh2YWx1ZSkgJiYgcHJvcCAhPT0gJ2FkYXB0ZXJzJyAmJlxuICAoT2JqZWN0LmdldFByb3RvdHlwZU9mKHZhbHVlKSA9PT0gbnVsbCB8fCB2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0KTtcblxuZnVuY3Rpb24gX2NhY2hlZChcbiAgdGFyZ2V0OiBBbnlPYmplY3QsXG4gIHByb3A6IHN0cmluZyxcbiAgcmVzb2x2ZTogKCkgPT4gdW5rbm93blxuKSB7XG4gIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGFyZ2V0LCBwcm9wKSkge1xuICAgIHJldHVybiB0YXJnZXRbcHJvcF07XG4gIH1cblxuICBjb25zdCB2YWx1ZSA9IHJlc29sdmUoKTtcbiAgLy8gY2FjaGUgdGhlIHJlc29sdmVkIHZhbHVlXG4gIHRhcmdldFtwcm9wXSA9IHZhbHVlO1xuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIF9yZXNvbHZlV2l0aENvbnRleHQoXG4gIHRhcmdldDogQ29udGV4dENhY2hlLFxuICBwcm9wOiBzdHJpbmcsXG4gIHJlY2VpdmVyOiBBbnlPYmplY3Rcbikge1xuICBjb25zdCB7X3Byb3h5LCBfY29udGV4dCwgX3N1YlByb3h5LCBfZGVzY3JpcHRvcnM6IGRlc2NyaXB0b3JzfSA9IHRhcmdldDtcbiAgbGV0IHZhbHVlID0gX3Byb3h5W3Byb3BdOyAvLyByZXNvbHZlIGZyb20gcHJveHlcblxuICAvLyByZXNvbHZlIHdpdGggY29udGV4dFxuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkgJiYgZGVzY3JpcHRvcnMuaXNTY3JpcHRhYmxlKHByb3ApKSB7XG4gICAgdmFsdWUgPSBfcmVzb2x2ZVNjcmlwdGFibGUocHJvcCwgdmFsdWUsIHRhcmdldCwgcmVjZWl2ZXIpO1xuICB9XG4gIGlmIChpc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGgpIHtcbiAgICB2YWx1ZSA9IF9yZXNvbHZlQXJyYXkocHJvcCwgdmFsdWUsIHRhcmdldCwgZGVzY3JpcHRvcnMuaXNJbmRleGFibGUpO1xuICB9XG4gIGlmIChuZWVkc1N1YlJlc29sdmVyKHByb3AsIHZhbHVlKSkge1xuICAgIC8vIGlmIHRoZSByZXNvbHZlZCB2YWx1ZSBpcyBhbiBvYmplY3QsIGNyZWF0ZSBhIHN1YiByZXNvbHZlciBmb3IgaXRcbiAgICB2YWx1ZSA9IF9hdHRhY2hDb250ZXh0KHZhbHVlLCBfY29udGV4dCwgX3N1YlByb3h5ICYmIF9zdWJQcm94eVtwcm9wXSwgZGVzY3JpcHRvcnMpO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gX3Jlc29sdmVTY3JpcHRhYmxlKFxuICBwcm9wOiBzdHJpbmcsXG4gIGdldFZhbHVlOiAoY3R4OiBBbnlPYmplY3QsIHN1YjogQW55T2JqZWN0KSA9PiB1bmtub3duLFxuICB0YXJnZXQ6IENvbnRleHRDYWNoZSxcbiAgcmVjZWl2ZXI6IEFueU9iamVjdFxuKSB7XG4gIGNvbnN0IHtfcHJveHksIF9jb250ZXh0LCBfc3ViUHJveHksIF9zdGFja30gPSB0YXJnZXQ7XG4gIGlmIChfc3RhY2suaGFzKHByb3ApKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWN1cnNpb24gZGV0ZWN0ZWQ6ICcgKyBBcnJheS5mcm9tKF9zdGFjaykuam9pbignLT4nKSArICctPicgKyBwcm9wKTtcbiAgfVxuICBfc3RhY2suYWRkKHByb3ApO1xuICBsZXQgdmFsdWUgPSBnZXRWYWx1ZShfY29udGV4dCwgX3N1YlByb3h5IHx8IHJlY2VpdmVyKTtcbiAgX3N0YWNrLmRlbGV0ZShwcm9wKTtcbiAgaWYgKG5lZWRzU3ViUmVzb2x2ZXIocHJvcCwgdmFsdWUpKSB7XG4gICAgLy8gV2hlbiBzY3JpcHRhYmxlIG9wdGlvbiByZXR1cm5zIGFuIG9iamVjdCwgY3JlYXRlIGEgcmVzb2x2ZXIgb24gdGhhdC5cbiAgICB2YWx1ZSA9IGNyZWF0ZVN1YlJlc29sdmVyKF9wcm94eS5fc2NvcGVzLCBfcHJveHksIHByb3AsIHZhbHVlKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIF9yZXNvbHZlQXJyYXkoXG4gIHByb3A6IHN0cmluZyxcbiAgdmFsdWU6IHVua25vd25bXSxcbiAgdGFyZ2V0OiBDb250ZXh0Q2FjaGUsXG4gIGlzSW5kZXhhYmxlOiAoa2V5OiBzdHJpbmcpID0+IGJvb2xlYW5cbikge1xuICBjb25zdCB7X3Byb3h5LCBfY29udGV4dCwgX3N1YlByb3h5LCBfZGVzY3JpcHRvcnM6IGRlc2NyaXB0b3JzfSA9IHRhcmdldDtcblxuICBpZiAodHlwZW9mIF9jb250ZXh0LmluZGV4ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luZGV4YWJsZShwcm9wKSkge1xuICAgIHJldHVybiB2YWx1ZVtfY29udGV4dC5pbmRleCAlIHZhbHVlLmxlbmd0aF07XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QodmFsdWVbMF0pKSB7XG4gICAgLy8gQXJyYXkgb2Ygb2JqZWN0cywgcmV0dXJuIGFycmF5IG9yIHJlc29sdmVyc1xuICAgIGNvbnN0IGFyciA9IHZhbHVlO1xuICAgIGNvbnN0IHNjb3BlcyA9IF9wcm94eS5fc2NvcGVzLmZpbHRlcihzID0+IHMgIT09IGFycik7XG4gICAgdmFsdWUgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXJyKSB7XG4gICAgICBjb25zdCByZXNvbHZlciA9IGNyZWF0ZVN1YlJlc29sdmVyKHNjb3BlcywgX3Byb3h5LCBwcm9wLCBpdGVtKTtcbiAgICAgIHZhbHVlLnB1c2goX2F0dGFjaENvbnRleHQocmVzb2x2ZXIsIF9jb250ZXh0LCBfc3ViUHJveHkgJiYgX3N1YlByb3h5W3Byb3BdLCBkZXNjcmlwdG9ycykpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVGYWxsYmFjayhcbiAgZmFsbGJhY2s6IFJlc29sdmVyT2JqZWN0S2V5IHwgKChwcm9wOiBSZXNvbHZlck9iamVjdEtleSwgdmFsdWU6IHVua25vd24pID0+IFJlc29sdmVyT2JqZWN0S2V5KSxcbiAgcHJvcDogUmVzb2x2ZXJPYmplY3RLZXksXG4gIHZhbHVlOiB1bmtub3duXG4pIHtcbiAgcmV0dXJuIGlzRnVuY3Rpb24oZmFsbGJhY2spID8gZmFsbGJhY2socHJvcCwgdmFsdWUpIDogZmFsbGJhY2s7XG59XG5cbmNvbnN0IGdldFNjb3BlID0gKGtleTogUmVzb2x2ZXJPYmplY3RLZXksIHBhcmVudDogQW55T2JqZWN0KSA9PiBrZXkgPT09IHRydWUgPyBwYXJlbnRcbiAgOiB0eXBlb2Yga2V5ID09PSAnc3RyaW5nJyA/IHJlc29sdmVPYmplY3RLZXkocGFyZW50LCBrZXkpIDogdW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBhZGRTY29wZXMoXG4gIHNldDogU2V0PEFueU9iamVjdD4sXG4gIHBhcmVudFNjb3BlczogQW55T2JqZWN0W10sXG4gIGtleTogUmVzb2x2ZXJPYmplY3RLZXksXG4gIHBhcmVudEZhbGxiYWNrOiBSZXNvbHZlck9iamVjdEtleSxcbiAgdmFsdWU6IHVua25vd25cbikge1xuICBmb3IgKGNvbnN0IHBhcmVudCBvZiBwYXJlbnRTY29wZXMpIHtcbiAgICBjb25zdCBzY29wZSA9IGdldFNjb3BlKGtleSwgcGFyZW50KTtcbiAgICBpZiAoc2NvcGUpIHtcbiAgICAgIHNldC5hZGQoc2NvcGUpO1xuICAgICAgY29uc3QgZmFsbGJhY2sgPSByZXNvbHZlRmFsbGJhY2soc2NvcGUuX2ZhbGxiYWNrLCBrZXksIHZhbHVlKTtcbiAgICAgIGlmICh0eXBlb2YgZmFsbGJhY2sgIT09ICd1bmRlZmluZWQnICYmIGZhbGxiYWNrICE9PSBrZXkgJiYgZmFsbGJhY2sgIT09IHBhcmVudEZhbGxiYWNrKSB7XG4gICAgICAgIC8vIFdoZW4gd2UgcmVhY2ggdGhlIGRlc2NyaXB0b3IgdGhhdCBkZWZpbmVzIGEgbmV3IF9mYWxsYmFjaywgcmV0dXJuIHRoYXQuXG4gICAgICAgIC8vIFRoZSBmYWxsYmFjayB3aWxsIHJlc3VtZSB0byB0aGF0IG5ldyBzY29wZS5cbiAgICAgICAgcmV0dXJuIGZhbGxiYWNrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc2NvcGUgPT09IGZhbHNlICYmIHR5cGVvZiBwYXJlbnRGYWxsYmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYga2V5ICE9PSBwYXJlbnRGYWxsYmFjaykge1xuICAgICAgLy8gRmFsbGJhY2sgdG8gYGZhbHNlYCByZXN1bHRzIHRvIGBmYWxzZWAsIHdoZW4gZmFsbGluZyBiYWNrIHRvIGRpZmZlcmVudCBrZXkuXG4gICAgICAvLyBGb3IgZXhhbXBsZSBgaW50ZXJhY3Rpb25gIGZyb20gYGhvdmVyYCBvciBgcGx1Z2lucy50b29sdGlwYCBhbmQgYGFuaW1hdGlvbmAgZnJvbSBgYW5pbWF0aW9uc2BcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVN1YlJlc29sdmVyKFxuICBwYXJlbnRTY29wZXM6IEFueU9iamVjdFtdLFxuICByZXNvbHZlcjogUmVzb2x2ZXJDYWNoZSxcbiAgcHJvcDogUmVzb2x2ZXJPYmplY3RLZXksXG4gIHZhbHVlOiB1bmtub3duXG4pIHtcbiAgY29uc3Qgcm9vdFNjb3BlcyA9IHJlc29sdmVyLl9yb290U2NvcGVzO1xuICBjb25zdCBmYWxsYmFjayA9IHJlc29sdmVGYWxsYmFjayhyZXNvbHZlci5fZmFsbGJhY2ssIHByb3AsIHZhbHVlKTtcbiAgY29uc3QgYWxsU2NvcGVzID0gWy4uLnBhcmVudFNjb3BlcywgLi4ucm9vdFNjb3Blc107XG4gIGNvbnN0IHNldCA9IG5ldyBTZXQ8QW55T2JqZWN0PigpO1xuICBzZXQuYWRkKHZhbHVlKTtcbiAgbGV0IGtleSA9IGFkZFNjb3Blc0Zyb21LZXkoc2V0LCBhbGxTY29wZXMsIHByb3AsIGZhbGxiYWNrIHx8IHByb3AsIHZhbHVlKTtcbiAgaWYgKGtleSA9PT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodHlwZW9mIGZhbGxiYWNrICE9PSAndW5kZWZpbmVkJyAmJiBmYWxsYmFjayAhPT0gcHJvcCkge1xuICAgIGtleSA9IGFkZFNjb3Blc0Zyb21LZXkoc2V0LCBhbGxTY29wZXMsIGZhbGxiYWNrLCBrZXksIHZhbHVlKTtcbiAgICBpZiAoa2V5ID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiBfY3JlYXRlUmVzb2x2ZXIoQXJyYXkuZnJvbShzZXQpLCBbJyddLCByb290U2NvcGVzLCBmYWxsYmFjayxcbiAgICAoKSA9PiBzdWJHZXRUYXJnZXQocmVzb2x2ZXIsIHByb3AgYXMgc3RyaW5nLCB2YWx1ZSkpO1xufVxuXG5mdW5jdGlvbiBhZGRTY29wZXNGcm9tS2V5KFxuICBzZXQ6IFNldDxBbnlPYmplY3Q+LFxuICBhbGxTY29wZXM6IEFueU9iamVjdFtdLFxuICBrZXk6IFJlc29sdmVyT2JqZWN0S2V5LFxuICBmYWxsYmFjazogUmVzb2x2ZXJPYmplY3RLZXksXG4gIGl0ZW06IHVua25vd25cbikge1xuICB3aGlsZSAoa2V5KSB7XG4gICAga2V5ID0gYWRkU2NvcGVzKHNldCwgYWxsU2NvcGVzLCBrZXksIGZhbGxiYWNrLCBpdGVtKTtcbiAgfVxuICByZXR1cm4ga2V5O1xufVxuXG5mdW5jdGlvbiBzdWJHZXRUYXJnZXQoXG4gIHJlc29sdmVyOiBSZXNvbHZlckNhY2hlLFxuICBwcm9wOiBzdHJpbmcsXG4gIHZhbHVlOiB1bmtub3duXG4pIHtcbiAgY29uc3QgcGFyZW50ID0gcmVzb2x2ZXIuX2dldFRhcmdldCgpO1xuICBpZiAoIShwcm9wIGluIHBhcmVudCkpIHtcbiAgICBwYXJlbnRbcHJvcF0gPSB7fTtcbiAgfVxuICBjb25zdCB0YXJnZXQgPSBwYXJlbnRbcHJvcF07XG4gIGlmIChpc0FycmF5KHRhcmdldCkgJiYgaXNPYmplY3QodmFsdWUpKSB7XG4gICAgLy8gRm9yIGFycmF5IG9mIG9iamVjdHMsIHRoZSBvYmplY3QgaXMgdXNlZCB0byBzdG9yZSB1cGRhdGVkIHZhbHVlc1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gdGFyZ2V0IHx8IHt9O1xufVxuXG5mdW5jdGlvbiBfcmVzb2x2ZVdpdGhQcmVmaXhlcyhcbiAgcHJvcDogc3RyaW5nLFxuICBwcmVmaXhlczogc3RyaW5nW10sXG4gIHNjb3BlczogQW55T2JqZWN0W10sXG4gIHByb3h5OiBSZXNvbHZlclByb3h5XG4pIHtcbiAgbGV0IHZhbHVlOiB1bmtub3duO1xuICBmb3IgKGNvbnN0IHByZWZpeCBvZiBwcmVmaXhlcykge1xuICAgIHZhbHVlID0gX3Jlc29sdmUocmVhZEtleShwcmVmaXgsIHByb3ApLCBzY29wZXMpO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gbmVlZHNTdWJSZXNvbHZlcihwcm9wLCB2YWx1ZSlcbiAgICAgICAgPyBjcmVhdGVTdWJSZXNvbHZlcihzY29wZXMsIHByb3h5LCBwcm9wLCB2YWx1ZSlcbiAgICAgICAgOiB2YWx1ZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX3Jlc29sdmUoa2V5OiBzdHJpbmcsIHNjb3BlczogQW55T2JqZWN0W10pIHtcbiAgZm9yIChjb25zdCBzY29wZSBvZiBzY29wZXMpIHtcbiAgICBpZiAoIXNjb3BlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWUgPSBzY29wZVtrZXldO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldEtleXNGcm9tQWxsU2NvcGVzKHRhcmdldDogUmVzb2x2ZXJDYWNoZSkge1xuICBsZXQga2V5cyA9IHRhcmdldC5fa2V5cztcbiAgaWYgKCFrZXlzKSB7XG4gICAga2V5cyA9IHRhcmdldC5fa2V5cyA9IHJlc29sdmVLZXlzRnJvbUFsbFNjb3Blcyh0YXJnZXQuX3Njb3Blcyk7XG4gIH1cbiAgcmV0dXJuIGtleXM7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVLZXlzRnJvbUFsbFNjb3BlcyhzY29wZXM6IEFueU9iamVjdFtdKSB7XG4gIGNvbnN0IHNldCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IHNjb3BlIG9mIHNjb3Blcykge1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHNjb3BlKS5maWx0ZXIoayA9PiAhay5zdGFydHNXaXRoKCdfJykpKSB7XG4gICAgICBzZXQuYWRkKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBBcnJheS5mcm9tKHNldCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfcGFyc2VPYmplY3REYXRhUmFkaWFsU2NhbGUoXG4gIG1ldGE6IENoYXJ0TWV0YTwnbGluZScgfCAnc2NhdHRlcic+LFxuICBkYXRhOiBBbnlPYmplY3RbXSxcbiAgc3RhcnQ6IG51bWJlcixcbiAgY291bnQ6IG51bWJlclxuKSB7XG4gIGNvbnN0IHtpU2NhbGV9ID0gbWV0YTtcbiAgY29uc3Qge2tleSA9ICdyJ30gPSB0aGlzLl9wYXJzaW5nO1xuICBjb25zdCBwYXJzZWQgPSBuZXcgQXJyYXk8e3I6IHVua25vd259Pihjb3VudCk7XG4gIGxldCBpOiBudW1iZXIsIGlsZW46IG51bWJlciwgaW5kZXg6IG51bWJlciwgaXRlbTogQW55T2JqZWN0O1xuXG4gIGZvciAoaSA9IDAsIGlsZW4gPSBjb3VudDsgaSA8IGlsZW47ICsraSkge1xuICAgIGluZGV4ID0gaSArIHN0YXJ0O1xuICAgIGl0ZW0gPSBkYXRhW2luZGV4XTtcbiAgICBwYXJzZWRbaV0gPSB7XG4gICAgICByOiBpU2NhbGUucGFyc2UocmVzb2x2ZU9iamVjdEtleShpdGVtLCBrZXkpLCBpbmRleClcbiAgICB9O1xuICB9XG4gIHJldHVybiBwYXJzZWQ7XG59XG4iLCAiaW1wb3J0IHthbG1vc3RFcXVhbHMsIGRpc3RhbmNlQmV0d2VlblBvaW50cywgc2lnbn0gZnJvbSAnLi9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IHtfaXNQb2ludEluQXJlYX0gZnJvbSAnLi9oZWxwZXJzLmNhbnZhcy5qcyc7XG5pbXBvcnQgdHlwZSB7Q2hhcnRBcmVhfSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7U3BsaW5lUG9pbnR9IGZyb20gJy4uL3R5cGVzL2dlb21ldHJpYy5qcyc7XG5cbmNvbnN0IEVQU0lMT04gPSBOdW1iZXIuRVBTSUxPTiB8fCAxZS0xNDtcblxudHlwZSBPcHRpb25hbFNwbGluZVBvaW50ID0gU3BsaW5lUG9pbnQgfCBmYWxzZVxuY29uc3QgZ2V0UG9pbnQgPSAocG9pbnRzOiBTcGxpbmVQb2ludFtdLCBpOiBudW1iZXIpOiBPcHRpb25hbFNwbGluZVBvaW50ID0+IGkgPCBwb2ludHMubGVuZ3RoICYmICFwb2ludHNbaV0uc2tpcCAmJiBwb2ludHNbaV07XG5jb25zdCBnZXRWYWx1ZUF4aXMgPSAoaW5kZXhBeGlzOiAneCcgfCAneScpID0+IGluZGV4QXhpcyA9PT0gJ3gnID8gJ3knIDogJ3gnO1xuXG5leHBvcnQgZnVuY3Rpb24gc3BsaW5lQ3VydmUoXG4gIGZpcnN0UG9pbnQ6IFNwbGluZVBvaW50LFxuICBtaWRkbGVQb2ludDogU3BsaW5lUG9pbnQsXG4gIGFmdGVyUG9pbnQ6IFNwbGluZVBvaW50LFxuICB0OiBudW1iZXJcbik6IHtcbiAgICBwcmV2aW91czogU3BsaW5lUG9pbnRcbiAgICBuZXh0OiBTcGxpbmVQb2ludFxuICB9IHtcbiAgLy8gUHJvcHMgdG8gUm9iIFNwZW5jZXIgYXQgc2NhbGVkIGlubm92YXRpb24gZm9yIGhpcyBwb3N0IG9uIHNwbGluaW5nIGJldHdlZW4gcG9pbnRzXG4gIC8vIGh0dHA6Ly9zY2FsZWRpbm5vdmF0aW9uLmNvbS9hbmFseXRpY3Mvc3BsaW5lcy9hYm91dFNwbGluZXMuaHRtbFxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gbXVzdCBhbHNvIHJlc3BlY3QgXCJza2lwcGVkXCIgcG9pbnRzXG5cbiAgY29uc3QgcHJldmlvdXMgPSBmaXJzdFBvaW50LnNraXAgPyBtaWRkbGVQb2ludCA6IGZpcnN0UG9pbnQ7XG4gIGNvbnN0IGN1cnJlbnQgPSBtaWRkbGVQb2ludDtcbiAgY29uc3QgbmV4dCA9IGFmdGVyUG9pbnQuc2tpcCA/IG1pZGRsZVBvaW50IDogYWZ0ZXJQb2ludDtcbiAgY29uc3QgZDAxID0gZGlzdGFuY2VCZXR3ZWVuUG9pbnRzKGN1cnJlbnQsIHByZXZpb3VzKTtcbiAgY29uc3QgZDEyID0gZGlzdGFuY2VCZXR3ZWVuUG9pbnRzKG5leHQsIGN1cnJlbnQpO1xuXG4gIGxldCBzMDEgPSBkMDEgLyAoZDAxICsgZDEyKTtcbiAgbGV0IHMxMiA9IGQxMiAvIChkMDEgKyBkMTIpO1xuXG4gIC8vIElmIGFsbCBwb2ludHMgYXJlIHRoZSBzYW1lLCBzMDEgJiBzMDIgd2lsbCBiZSBpbmZcbiAgczAxID0gaXNOYU4oczAxKSA/IDAgOiBzMDE7XG4gIHMxMiA9IGlzTmFOKHMxMikgPyAwIDogczEyO1xuXG4gIGNvbnN0IGZhID0gdCAqIHMwMTsgLy8gc2NhbGluZyBmYWN0b3IgZm9yIHRyaWFuZ2xlIFRhXG4gIGNvbnN0IGZiID0gdCAqIHMxMjtcblxuICByZXR1cm4ge1xuICAgIHByZXZpb3VzOiB7XG4gICAgICB4OiBjdXJyZW50LnggLSBmYSAqIChuZXh0LnggLSBwcmV2aW91cy54KSxcbiAgICAgIHk6IGN1cnJlbnQueSAtIGZhICogKG5leHQueSAtIHByZXZpb3VzLnkpXG4gICAgfSxcbiAgICBuZXh0OiB7XG4gICAgICB4OiBjdXJyZW50LnggKyBmYiAqIChuZXh0LnggLSBwcmV2aW91cy54KSxcbiAgICAgIHk6IGN1cnJlbnQueSArIGZiICogKG5leHQueSAtIHByZXZpb3VzLnkpXG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIEFkanVzdCB0YW5nZW50cyB0byBlbnN1cmUgbW9ub3RvbmljIHByb3BlcnRpZXNcbiAqL1xuZnVuY3Rpb24gbW9ub3RvbmVBZGp1c3QocG9pbnRzOiBTcGxpbmVQb2ludFtdLCBkZWx0YUs6IG51bWJlcltdLCBtSzogbnVtYmVyW10pIHtcbiAgY29uc3QgcG9pbnRzTGVuID0gcG9pbnRzLmxlbmd0aDtcblxuICBsZXQgYWxwaGFLOiBudW1iZXIsIGJldGFLOiBudW1iZXIsIHRhdUs6IG51bWJlciwgc3F1YXJlZE1hZ25pdHVkZTogbnVtYmVyLCBwb2ludEN1cnJlbnQ6IE9wdGlvbmFsU3BsaW5lUG9pbnQ7XG4gIGxldCBwb2ludEFmdGVyID0gZ2V0UG9pbnQocG9pbnRzLCAwKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb2ludHNMZW4gLSAxOyArK2kpIHtcbiAgICBwb2ludEN1cnJlbnQgPSBwb2ludEFmdGVyO1xuICAgIHBvaW50QWZ0ZXIgPSBnZXRQb2ludChwb2ludHMsIGkgKyAxKTtcbiAgICBpZiAoIXBvaW50Q3VycmVudCB8fCAhcG9pbnRBZnRlcikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGFsbW9zdEVxdWFscyhkZWx0YUtbaV0sIDAsIEVQU0lMT04pKSB7XG4gICAgICBtS1tpXSA9IG1LW2kgKyAxXSA9IDA7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBhbHBoYUsgPSBtS1tpXSAvIGRlbHRhS1tpXTtcbiAgICBiZXRhSyA9IG1LW2kgKyAxXSAvIGRlbHRhS1tpXTtcbiAgICBzcXVhcmVkTWFnbml0dWRlID0gTWF0aC5wb3coYWxwaGFLLCAyKSArIE1hdGgucG93KGJldGFLLCAyKTtcbiAgICBpZiAoc3F1YXJlZE1hZ25pdHVkZSA8PSA5KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB0YXVLID0gMyAvIE1hdGguc3FydChzcXVhcmVkTWFnbml0dWRlKTtcbiAgICBtS1tpXSA9IGFscGhhSyAqIHRhdUsgKiBkZWx0YUtbaV07XG4gICAgbUtbaSArIDFdID0gYmV0YUsgKiB0YXVLICogZGVsdGFLW2ldO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vbm90b25lQ29tcHV0ZShwb2ludHM6IFNwbGluZVBvaW50W10sIG1LOiBudW1iZXJbXSwgaW5kZXhBeGlzOiAneCcgfCAneScgPSAneCcpIHtcbiAgY29uc3QgdmFsdWVBeGlzID0gZ2V0VmFsdWVBeGlzKGluZGV4QXhpcyk7XG4gIGNvbnN0IHBvaW50c0xlbiA9IHBvaW50cy5sZW5ndGg7XG4gIGxldCBkZWx0YTogbnVtYmVyLCBwb2ludEJlZm9yZTogT3B0aW9uYWxTcGxpbmVQb2ludCwgcG9pbnRDdXJyZW50OiBPcHRpb25hbFNwbGluZVBvaW50O1xuICBsZXQgcG9pbnRBZnRlciA9IGdldFBvaW50KHBvaW50cywgMCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb2ludHNMZW47ICsraSkge1xuICAgIHBvaW50QmVmb3JlID0gcG9pbnRDdXJyZW50O1xuICAgIHBvaW50Q3VycmVudCA9IHBvaW50QWZ0ZXI7XG4gICAgcG9pbnRBZnRlciA9IGdldFBvaW50KHBvaW50cywgaSArIDEpO1xuICAgIGlmICghcG9pbnRDdXJyZW50KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBpUGl4ZWwgPSBwb2ludEN1cnJlbnRbaW5kZXhBeGlzXTtcbiAgICBjb25zdCB2UGl4ZWwgPSBwb2ludEN1cnJlbnRbdmFsdWVBeGlzXTtcbiAgICBpZiAocG9pbnRCZWZvcmUpIHtcbiAgICAgIGRlbHRhID0gKGlQaXhlbCAtIHBvaW50QmVmb3JlW2luZGV4QXhpc10pIC8gMztcbiAgICAgIHBvaW50Q3VycmVudFtgY3AxJHtpbmRleEF4aXN9YF0gPSBpUGl4ZWwgLSBkZWx0YTtcbiAgICAgIHBvaW50Q3VycmVudFtgY3AxJHt2YWx1ZUF4aXN9YF0gPSB2UGl4ZWwgLSBkZWx0YSAqIG1LW2ldO1xuICAgIH1cbiAgICBpZiAocG9pbnRBZnRlcikge1xuICAgICAgZGVsdGEgPSAocG9pbnRBZnRlcltpbmRleEF4aXNdIC0gaVBpeGVsKSAvIDM7XG4gICAgICBwb2ludEN1cnJlbnRbYGNwMiR7aW5kZXhBeGlzfWBdID0gaVBpeGVsICsgZGVsdGE7XG4gICAgICBwb2ludEN1cnJlbnRbYGNwMiR7dmFsdWVBeGlzfWBdID0gdlBpeGVsICsgZGVsdGEgKiBtS1tpXTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgQsOpemllciBjb250cm9sIHBvaW50cyBpbiBhIHNpbWlsYXIgd2F5IHRoYW4gfHNwbGluZUN1cnZlfCxcbiAqIGJ1dCBwcmVzZXJ2ZXMgbW9ub3RvbmljaXR5IG9mIHRoZSBwcm92aWRlZCBkYXRhIGFuZCBlbnN1cmVzIG5vIGxvY2FsIGV4dHJlbXVtcyBhcmUgYWRkZWRcbiAqIGJldHdlZW4gdGhlIGRhdGFzZXQgZGlzY3JldGUgcG9pbnRzIGR1ZSB0byB0aGUgaW50ZXJwb2xhdGlvbi5cbiAqIFNlZSA6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01vbm90b25lX2N1YmljX2ludGVycG9sYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNwbGluZUN1cnZlTW9ub3RvbmUocG9pbnRzOiBTcGxpbmVQb2ludFtdLCBpbmRleEF4aXM6ICd4JyB8ICd5JyA9ICd4Jykge1xuICBjb25zdCB2YWx1ZUF4aXMgPSBnZXRWYWx1ZUF4aXMoaW5kZXhBeGlzKTtcbiAgY29uc3QgcG9pbnRzTGVuID0gcG9pbnRzLmxlbmd0aDtcbiAgY29uc3QgZGVsdGFLOiBudW1iZXJbXSA9IEFycmF5KHBvaW50c0xlbikuZmlsbCgwKTtcbiAgY29uc3QgbUs6IG51bWJlcltdID0gQXJyYXkocG9pbnRzTGVuKTtcblxuICAvLyBDYWxjdWxhdGUgc2xvcGVzIChkZWx0YUspIGFuZCBpbml0aWFsaXplIHRhbmdlbnRzIChtSylcbiAgbGV0IGksIHBvaW50QmVmb3JlOiBPcHRpb25hbFNwbGluZVBvaW50LCBwb2ludEN1cnJlbnQ6IE9wdGlvbmFsU3BsaW5lUG9pbnQ7XG4gIGxldCBwb2ludEFmdGVyID0gZ2V0UG9pbnQocG9pbnRzLCAwKTtcblxuICBmb3IgKGkgPSAwOyBpIDwgcG9pbnRzTGVuOyArK2kpIHtcbiAgICBwb2ludEJlZm9yZSA9IHBvaW50Q3VycmVudDtcbiAgICBwb2ludEN1cnJlbnQgPSBwb2ludEFmdGVyO1xuICAgIHBvaW50QWZ0ZXIgPSBnZXRQb2ludChwb2ludHMsIGkgKyAxKTtcbiAgICBpZiAoIXBvaW50Q3VycmVudCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHBvaW50QWZ0ZXIpIHtcbiAgICAgIGNvbnN0IHNsb3BlRGVsdGEgPSBwb2ludEFmdGVyW2luZGV4QXhpc10gLSBwb2ludEN1cnJlbnRbaW5kZXhBeGlzXTtcblxuICAgICAgLy8gSW4gdGhlIGNhc2Ugb2YgdHdvIHBvaW50cyB0aGF0IGFwcGVhciBhdCB0aGUgc2FtZSB4IHBpeGVsLCBzbG9wZURlbHRhWCBpcyAwXG4gICAgICBkZWx0YUtbaV0gPSBzbG9wZURlbHRhICE9PSAwID8gKHBvaW50QWZ0ZXJbdmFsdWVBeGlzXSAtIHBvaW50Q3VycmVudFt2YWx1ZUF4aXNdKSAvIHNsb3BlRGVsdGEgOiAwO1xuICAgIH1cbiAgICBtS1tpXSA9ICFwb2ludEJlZm9yZSA/IGRlbHRhS1tpXVxuICAgICAgOiAhcG9pbnRBZnRlciA/IGRlbHRhS1tpIC0gMV1cbiAgICAgICAgOiAoc2lnbihkZWx0YUtbaSAtIDFdKSAhPT0gc2lnbihkZWx0YUtbaV0pKSA/IDBcbiAgICAgICAgICA6IChkZWx0YUtbaSAtIDFdICsgZGVsdGFLW2ldKSAvIDI7XG4gIH1cblxuICBtb25vdG9uZUFkanVzdChwb2ludHMsIGRlbHRhSywgbUspO1xuXG4gIG1vbm90b25lQ29tcHV0ZShwb2ludHMsIG1LLCBpbmRleEF4aXMpO1xufVxuXG5mdW5jdGlvbiBjYXBDb250cm9sUG9pbnQocHQ6IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKSB7XG4gIHJldHVybiBNYXRoLm1heChNYXRoLm1pbihwdCwgbWF4KSwgbWluKTtcbn1cblxuZnVuY3Rpb24gY2FwQmV6aWVyUG9pbnRzKHBvaW50czogU3BsaW5lUG9pbnRbXSwgYXJlYTogQ2hhcnRBcmVhKSB7XG4gIGxldCBpLCBpbGVuLCBwb2ludCwgaW5BcmVhLCBpbkFyZWFQcmV2O1xuICBsZXQgaW5BcmVhTmV4dCA9IF9pc1BvaW50SW5BcmVhKHBvaW50c1swXSwgYXJlYSk7XG4gIGZvciAoaSA9IDAsIGlsZW4gPSBwb2ludHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgaW5BcmVhUHJldiA9IGluQXJlYTtcbiAgICBpbkFyZWEgPSBpbkFyZWFOZXh0O1xuICAgIGluQXJlYU5leHQgPSBpIDwgaWxlbiAtIDEgJiYgX2lzUG9pbnRJbkFyZWEocG9pbnRzW2kgKyAxXSwgYXJlYSk7XG4gICAgaWYgKCFpbkFyZWEpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBwb2ludCA9IHBvaW50c1tpXTtcbiAgICBpZiAoaW5BcmVhUHJldikge1xuICAgICAgcG9pbnQuY3AxeCA9IGNhcENvbnRyb2xQb2ludChwb2ludC5jcDF4LCBhcmVhLmxlZnQsIGFyZWEucmlnaHQpO1xuICAgICAgcG9pbnQuY3AxeSA9IGNhcENvbnRyb2xQb2ludChwb2ludC5jcDF5LCBhcmVhLnRvcCwgYXJlYS5ib3R0b20pO1xuICAgIH1cbiAgICBpZiAoaW5BcmVhTmV4dCkge1xuICAgICAgcG9pbnQuY3AyeCA9IGNhcENvbnRyb2xQb2ludChwb2ludC5jcDJ4LCBhcmVhLmxlZnQsIGFyZWEucmlnaHQpO1xuICAgICAgcG9pbnQuY3AyeSA9IGNhcENvbnRyb2xQb2ludChwb2ludC5jcDJ5LCBhcmVhLnRvcCwgYXJlYS5ib3R0b20pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfdXBkYXRlQmV6aWVyQ29udHJvbFBvaW50cyhcbiAgcG9pbnRzOiBTcGxpbmVQb2ludFtdLFxuICBvcHRpb25zLFxuICBhcmVhOiBDaGFydEFyZWEsXG4gIGxvb3A6IGJvb2xlYW4sXG4gIGluZGV4QXhpczogJ3gnIHwgJ3knXG4pIHtcbiAgbGV0IGk6IG51bWJlciwgaWxlbjogbnVtYmVyLCBwb2ludDogU3BsaW5lUG9pbnQsIGNvbnRyb2xQb2ludHM6IFJldHVyblR5cGU8dHlwZW9mIHNwbGluZUN1cnZlPjtcblxuICAvLyBPbmx5IGNvbnNpZGVyIHBvaW50cyB0aGF0IGFyZSBkcmF3biBpbiBjYXNlIHRoZSBzcGFuR2FwcyBvcHRpb24gaXMgdXNlZFxuICBpZiAob3B0aW9ucy5zcGFuR2Fwcykge1xuICAgIHBvaW50cyA9IHBvaW50cy5maWx0ZXIoKHB0KSA9PiAhcHQuc2tpcCk7XG4gIH1cblxuICBpZiAob3B0aW9ucy5jdWJpY0ludGVycG9sYXRpb25Nb2RlID09PSAnbW9ub3RvbmUnKSB7XG4gICAgc3BsaW5lQ3VydmVNb25vdG9uZShwb2ludHMsIGluZGV4QXhpcyk7XG4gIH0gZWxzZSB7XG4gICAgbGV0IHByZXYgPSBsb29wID8gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXSA6IHBvaW50c1swXTtcbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICBjb250cm9sUG9pbnRzID0gc3BsaW5lQ3VydmUoXG4gICAgICAgIHByZXYsXG4gICAgICAgIHBvaW50LFxuICAgICAgICBwb2ludHNbTWF0aC5taW4oaSArIDEsIGlsZW4gLSAobG9vcCA/IDAgOiAxKSkgJSBpbGVuXSxcbiAgICAgICAgb3B0aW9ucy50ZW5zaW9uXG4gICAgICApO1xuICAgICAgcG9pbnQuY3AxeCA9IGNvbnRyb2xQb2ludHMucHJldmlvdXMueDtcbiAgICAgIHBvaW50LmNwMXkgPSBjb250cm9sUG9pbnRzLnByZXZpb3VzLnk7XG4gICAgICBwb2ludC5jcDJ4ID0gY29udHJvbFBvaW50cy5uZXh0Lng7XG4gICAgICBwb2ludC5jcDJ5ID0gY29udHJvbFBvaW50cy5uZXh0Lnk7XG4gICAgICBwcmV2ID0gcG9pbnQ7XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdGlvbnMuY2FwQmV6aWVyUG9pbnRzKSB7XG4gICAgY2FwQmV6aWVyUG9pbnRzKHBvaW50cywgYXJlYSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7Q2hhcnRBcmVhLCBTY2FsZX0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuaW1wb3J0IHR5cGUgQ2hhcnQgZnJvbSAnLi4vY29yZS9jb3JlLmNvbnRyb2xsZXIuanMnO1xuaW1wb3J0IHR5cGUge0NoYXJ0RXZlbnR9IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCB7SU5GSU5JVFl9IGZyb20gJy4vaGVscGVycy5tYXRoLmpzJztcblxuLyoqXG4gKiBOb3RlOiB0eXBlZGVmcyBhcmUgYXV0by1leHBvcnRlZCwgc28gdXNlIGEgbWFkZS11cCBgZG9tYCBuYW1lc3BhY2Ugd2hlcmVcbiAqIG5lY2Vzc2FyeSB0byBhdm9pZCBkdXBsaWNhdGVzIHdpdGggYGV4cG9ydCAqIGZyb20gJy4vaGVscGVyc2A7IHNlZVxuICogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy80NjAxMVxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL2NvcmUvY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IGRvbS5DaGFydFxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uLy4uL3R5cGVzJykuQ2hhcnRFdmVudCB9IENoYXJ0RXZlbnRcbiAqL1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfaXNEb21TdXBwb3J0ZWQoKTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfZ2V0UGFyZW50Tm9kZShkb21Ob2RlOiBIVE1MQ2FudmFzRWxlbWVudCk6IEhUTUxDYW52YXNFbGVtZW50IHtcbiAgbGV0IHBhcmVudCA9IGRvbU5vZGUucGFyZW50Tm9kZTtcbiAgaWYgKHBhcmVudCAmJiBwYXJlbnQudG9TdHJpbmcoKSA9PT0gJ1tvYmplY3QgU2hhZG93Um9vdF0nKSB7XG4gICAgcGFyZW50ID0gKHBhcmVudCBhcyBTaGFkb3dSb290KS5ob3N0O1xuICB9XG4gIHJldHVybiBwYXJlbnQgYXMgSFRNTENhbnZhc0VsZW1lbnQ7XG59XG5cbi8qKlxuICogY29udmVydCBtYXgtd2lkdGgvbWF4LWhlaWdodCB2YWx1ZXMgdGhhdCBtYXkgYmUgcGVyY2VudGFnZXMgaW50byBhIG51bWJlclxuICogQHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJzZU1heFN0eWxlKHN0eWxlVmFsdWU6IHN0cmluZyB8IG51bWJlciwgbm9kZTogSFRNTEVsZW1lbnQsIHBhcmVudFByb3BlcnR5OiBzdHJpbmcpIHtcbiAgbGV0IHZhbHVlSW5QaXhlbHM6IG51bWJlcjtcbiAgaWYgKHR5cGVvZiBzdHlsZVZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHZhbHVlSW5QaXhlbHMgPSBwYXJzZUludChzdHlsZVZhbHVlLCAxMCk7XG5cbiAgICBpZiAoc3R5bGVWYWx1ZS5pbmRleE9mKCclJykgIT09IC0xKSB7XG4gICAgICAvLyBwZXJjZW50YWdlICogc2l6ZSBpbiBkaW1lbnNpb25cbiAgICAgIHZhbHVlSW5QaXhlbHMgPSAodmFsdWVJblBpeGVscyAvIDEwMCkgKiBub2RlLnBhcmVudE5vZGVbcGFyZW50UHJvcGVydHldO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YWx1ZUluUGl4ZWxzID0gc3R5bGVWYWx1ZTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZUluUGl4ZWxzO1xufVxuXG5jb25zdCBnZXRDb21wdXRlZFN0eWxlID0gKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogQ1NTU3R5bGVEZWNsYXJhdGlvbiA9PlxuICBlbGVtZW50Lm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50LCBudWxsKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFN0eWxlKGVsOiBIVE1MRWxlbWVudCwgcHJvcGVydHk6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBnZXRDb21wdXRlZFN0eWxlKGVsKS5nZXRQcm9wZXJ0eVZhbHVlKHByb3BlcnR5KTtcbn1cblxuY29uc3QgcG9zaXRpb25zID0gWyd0b3AnLCAncmlnaHQnLCAnYm90dG9tJywgJ2xlZnQnXTtcbmZ1bmN0aW9uIGdldFBvc2l0aW9uZWRTdHlsZShzdHlsZXM6IENTU1N0eWxlRGVjbGFyYXRpb24sIHN0eWxlOiBzdHJpbmcsIHN1ZmZpeD86IHN0cmluZyk6IENoYXJ0QXJlYSB7XG4gIGNvbnN0IHJlc3VsdCA9IHt9IGFzIENoYXJ0QXJlYTtcbiAgc3VmZml4ID0gc3VmZml4ID8gJy0nICsgc3VmZml4IDogJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgY29uc3QgcG9zID0gcG9zaXRpb25zW2ldO1xuICAgIHJlc3VsdFtwb3NdID0gcGFyc2VGbG9hdChzdHlsZXNbc3R5bGUgKyAnLScgKyBwb3MgKyBzdWZmaXhdKSB8fCAwO1xuICB9XG4gIHJlc3VsdC53aWR0aCA9IHJlc3VsdC5sZWZ0ICsgcmVzdWx0LnJpZ2h0O1xuICByZXN1bHQuaGVpZ2h0ID0gcmVzdWx0LnRvcCArIHJlc3VsdC5ib3R0b207XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmNvbnN0IHVzZU9mZnNldFBvcyA9ICh4OiBudW1iZXIsIHk6IG51bWJlciwgdGFyZ2V0OiBIVE1MRWxlbWVudCB8IEV2ZW50VGFyZ2V0KSA9PlxuICAoeCA+IDAgfHwgeSA+IDApICYmICghdGFyZ2V0IHx8ICEodGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5zaGFkb3dSb290KTtcblxuLyoqXG4gKiBAcGFyYW0gZVxuICogQHBhcmFtIGNhbnZhc1xuICogQHJldHVybnMgQ2FudmFzIHBvc2l0aW9uXG4gKi9cbmZ1bmN0aW9uIGdldENhbnZhc1Bvc2l0aW9uKFxuICBlOiBFdmVudCB8IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50LFxuICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50XG4pOiB7XG4gICAgeDogbnVtYmVyO1xuICAgIHk6IG51bWJlcjtcbiAgICBib3g6IGJvb2xlYW47XG4gIH0ge1xuICBjb25zdCB0b3VjaGVzID0gKGUgYXMgVG91Y2hFdmVudCkudG91Y2hlcztcbiAgY29uc3Qgc291cmNlID0gKHRvdWNoZXMgJiYgdG91Y2hlcy5sZW5ndGggPyB0b3VjaGVzWzBdIDogZSkgYXMgTW91c2VFdmVudDtcbiAgY29uc3Qge29mZnNldFgsIG9mZnNldFl9ID0gc291cmNlIGFzIE1vdXNlRXZlbnQ7XG4gIGxldCBib3ggPSBmYWxzZTtcbiAgbGV0IHgsIHk7XG4gIGlmICh1c2VPZmZzZXRQb3Mob2Zmc2V0WCwgb2Zmc2V0WSwgZS50YXJnZXQpKSB7XG4gICAgeCA9IG9mZnNldFg7XG4gICAgeSA9IG9mZnNldFk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgcmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB4ID0gc291cmNlLmNsaWVudFggLSByZWN0LmxlZnQ7XG4gICAgeSA9IHNvdXJjZS5jbGllbnRZIC0gcmVjdC50b3A7XG4gICAgYm94ID0gdHJ1ZTtcbiAgfVxuICByZXR1cm4ge3gsIHksIGJveH07XG59XG5cbi8qKlxuICogR2V0cyBhbiBldmVudCdzIHgsIHkgY29vcmRpbmF0ZXMsIHJlbGF0aXZlIHRvIHRoZSBjaGFydCBhcmVhXG4gKiBAcGFyYW0gZXZlbnRcbiAqIEBwYXJhbSBjaGFydFxuICogQHJldHVybnMgeCBhbmQgeSBjb29yZGluYXRlcyBvZiB0aGUgZXZlbnRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVsYXRpdmVQb3NpdGlvbihcbiAgZXZlbnQ6IEV2ZW50IHwgQ2hhcnRFdmVudCB8IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50LFxuICBjaGFydDogQ2hhcnRcbik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSB7XG4gIGlmICgnbmF0aXZlJyBpbiBldmVudCkge1xuICAgIHJldHVybiBldmVudDtcbiAgfVxuXG4gIGNvbnN0IHtjYW52YXMsIGN1cnJlbnREZXZpY2VQaXhlbFJhdGlvfSA9IGNoYXJ0O1xuICBjb25zdCBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoY2FudmFzKTtcbiAgY29uc3QgYm9yZGVyQm94ID0gc3R5bGUuYm94U2l6aW5nID09PSAnYm9yZGVyLWJveCc7XG4gIGNvbnN0IHBhZGRpbmdzID0gZ2V0UG9zaXRpb25lZFN0eWxlKHN0eWxlLCAncGFkZGluZycpO1xuICBjb25zdCBib3JkZXJzID0gZ2V0UG9zaXRpb25lZFN0eWxlKHN0eWxlLCAnYm9yZGVyJywgJ3dpZHRoJyk7XG4gIGNvbnN0IHt4LCB5LCBib3h9ID0gZ2V0Q2FudmFzUG9zaXRpb24oZXZlbnQsIGNhbnZhcyk7XG4gIGNvbnN0IHhPZmZzZXQgPSBwYWRkaW5ncy5sZWZ0ICsgKGJveCAmJiBib3JkZXJzLmxlZnQpO1xuICBjb25zdCB5T2Zmc2V0ID0gcGFkZGluZ3MudG9wICsgKGJveCAmJiBib3JkZXJzLnRvcCk7XG5cbiAgbGV0IHt3aWR0aCwgaGVpZ2h0fSA9IGNoYXJ0O1xuICBpZiAoYm9yZGVyQm94KSB7XG4gICAgd2lkdGggLT0gcGFkZGluZ3Mud2lkdGggKyBib3JkZXJzLndpZHRoO1xuICAgIGhlaWdodCAtPSBwYWRkaW5ncy5oZWlnaHQgKyBib3JkZXJzLmhlaWdodDtcbiAgfVxuICByZXR1cm4ge1xuICAgIHg6IE1hdGgucm91bmQoKHggLSB4T2Zmc2V0KSAvIHdpZHRoICogY2FudmFzLndpZHRoIC8gY3VycmVudERldmljZVBpeGVsUmF0aW8pLFxuICAgIHk6IE1hdGgucm91bmQoKHkgLSB5T2Zmc2V0KSAvIGhlaWdodCAqIGNhbnZhcy5oZWlnaHQgLyBjdXJyZW50RGV2aWNlUGl4ZWxSYXRpbylcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0Q29udGFpbmVyU2l6ZShjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50LCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IFBhcnRpYWw8U2NhbGU+IHtcbiAgbGV0IG1heFdpZHRoOiBudW1iZXIsIG1heEhlaWdodDogbnVtYmVyO1xuXG4gIGlmICh3aWR0aCA9PT0gdW5kZWZpbmVkIHx8IGhlaWdodCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gX2dldFBhcmVudE5vZGUoY2FudmFzKTtcbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgd2lkdGggPSBjYW52YXMuY2xpZW50V2lkdGg7XG4gICAgICBoZWlnaHQgPSBjYW52YXMuY2xpZW50SGVpZ2h0O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCByZWN0ID0gY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOyAvLyB0aGlzIGlzIHRoZSBib3JkZXIgYm94IG9mIHRoZSBjb250YWluZXJcbiAgICAgIGNvbnN0IGNvbnRhaW5lclN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShjb250YWluZXIpO1xuICAgICAgY29uc3QgY29udGFpbmVyQm9yZGVyID0gZ2V0UG9zaXRpb25lZFN0eWxlKGNvbnRhaW5lclN0eWxlLCAnYm9yZGVyJywgJ3dpZHRoJyk7XG4gICAgICBjb25zdCBjb250YWluZXJQYWRkaW5nID0gZ2V0UG9zaXRpb25lZFN0eWxlKGNvbnRhaW5lclN0eWxlLCAncGFkZGluZycpO1xuICAgICAgd2lkdGggPSByZWN0LndpZHRoIC0gY29udGFpbmVyUGFkZGluZy53aWR0aCAtIGNvbnRhaW5lckJvcmRlci53aWR0aDtcbiAgICAgIGhlaWdodCA9IHJlY3QuaGVpZ2h0IC0gY29udGFpbmVyUGFkZGluZy5oZWlnaHQgLSBjb250YWluZXJCb3JkZXIuaGVpZ2h0O1xuICAgICAgbWF4V2lkdGggPSBwYXJzZU1heFN0eWxlKGNvbnRhaW5lclN0eWxlLm1heFdpZHRoLCBjb250YWluZXIsICdjbGllbnRXaWR0aCcpO1xuICAgICAgbWF4SGVpZ2h0ID0gcGFyc2VNYXhTdHlsZShjb250YWluZXJTdHlsZS5tYXhIZWlnaHQsIGNvbnRhaW5lciwgJ2NsaWVudEhlaWdodCcpO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIHdpZHRoLFxuICAgIGhlaWdodCxcbiAgICBtYXhXaWR0aDogbWF4V2lkdGggfHwgSU5GSU5JVFksXG4gICAgbWF4SGVpZ2h0OiBtYXhIZWlnaHQgfHwgSU5GSU5JVFlcbiAgfTtcbn1cblxuY29uc3Qgcm91bmQxID0gKHY6IG51bWJlcikgPT4gTWF0aC5yb3VuZCh2ICogMTApIC8gMTA7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG5leHBvcnQgZnVuY3Rpb24gZ2V0TWF4aW11bVNpemUoXG4gIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsXG4gIGJiV2lkdGg/OiBudW1iZXIsXG4gIGJiSGVpZ2h0PzogbnVtYmVyLFxuICBhc3BlY3RSYXRpbz86IG51bWJlclxuKTogeyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9IHtcbiAgY29uc3Qgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGNhbnZhcyk7XG4gIGNvbnN0IG1hcmdpbnMgPSBnZXRQb3NpdGlvbmVkU3R5bGUoc3R5bGUsICdtYXJnaW4nKTtcbiAgY29uc3QgbWF4V2lkdGggPSBwYXJzZU1heFN0eWxlKHN0eWxlLm1heFdpZHRoLCBjYW52YXMsICdjbGllbnRXaWR0aCcpIHx8IElORklOSVRZO1xuICBjb25zdCBtYXhIZWlnaHQgPSBwYXJzZU1heFN0eWxlKHN0eWxlLm1heEhlaWdodCwgY2FudmFzLCAnY2xpZW50SGVpZ2h0JykgfHwgSU5GSU5JVFk7XG4gIGNvbnN0IGNvbnRhaW5lclNpemUgPSBnZXRDb250YWluZXJTaXplKGNhbnZhcywgYmJXaWR0aCwgYmJIZWlnaHQpO1xuICBsZXQge3dpZHRoLCBoZWlnaHR9ID0gY29udGFpbmVyU2l6ZTtcblxuICBpZiAoc3R5bGUuYm94U2l6aW5nID09PSAnY29udGVudC1ib3gnKSB7XG4gICAgY29uc3QgYm9yZGVycyA9IGdldFBvc2l0aW9uZWRTdHlsZShzdHlsZSwgJ2JvcmRlcicsICd3aWR0aCcpO1xuICAgIGNvbnN0IHBhZGRpbmdzID0gZ2V0UG9zaXRpb25lZFN0eWxlKHN0eWxlLCAncGFkZGluZycpO1xuICAgIHdpZHRoIC09IHBhZGRpbmdzLndpZHRoICsgYm9yZGVycy53aWR0aDtcbiAgICBoZWlnaHQgLT0gcGFkZGluZ3MuaGVpZ2h0ICsgYm9yZGVycy5oZWlnaHQ7XG4gIH1cbiAgd2lkdGggPSBNYXRoLm1heCgwLCB3aWR0aCAtIG1hcmdpbnMud2lkdGgpO1xuICBoZWlnaHQgPSBNYXRoLm1heCgwLCBhc3BlY3RSYXRpbyA/IHdpZHRoIC8gYXNwZWN0UmF0aW8gOiBoZWlnaHQgLSBtYXJnaW5zLmhlaWdodCk7XG4gIHdpZHRoID0gcm91bmQxKE1hdGgubWluKHdpZHRoLCBtYXhXaWR0aCwgY29udGFpbmVyU2l6ZS5tYXhXaWR0aCkpO1xuICBoZWlnaHQgPSByb3VuZDEoTWF0aC5taW4oaGVpZ2h0LCBtYXhIZWlnaHQsIGNvbnRhaW5lclNpemUubWF4SGVpZ2h0KSk7XG4gIGlmICh3aWR0aCAmJiAhaGVpZ2h0KSB7XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzQ2NTlcbiAgICAvLyBJZiB0aGUgY2FudmFzIGhhcyB3aWR0aCwgYnV0IG5vIGhlaWdodCwgZGVmYXVsdCB0byBhc3BlY3RSYXRpbyBvZiAyIChjYW52YXMgZGVmYXVsdClcbiAgICBoZWlnaHQgPSByb3VuZDEod2lkdGggLyAyKTtcbiAgfVxuXG4gIGNvbnN0IG1haW50YWluSGVpZ2h0ID0gYmJXaWR0aCAhPT0gdW5kZWZpbmVkIHx8IGJiSGVpZ2h0ICE9PSB1bmRlZmluZWQ7XG5cbiAgaWYgKG1haW50YWluSGVpZ2h0ICYmIGFzcGVjdFJhdGlvICYmIGNvbnRhaW5lclNpemUuaGVpZ2h0ICYmIGhlaWdodCA+IGNvbnRhaW5lclNpemUuaGVpZ2h0KSB7XG4gICAgaGVpZ2h0ID0gY29udGFpbmVyU2l6ZS5oZWlnaHQ7XG4gICAgd2lkdGggPSByb3VuZDEoTWF0aC5mbG9vcihoZWlnaHQgKiBhc3BlY3RSYXRpbykpO1xuICB9XG5cbiAgcmV0dXJuIHt3aWR0aCwgaGVpZ2h0fTtcbn1cblxuLyoqXG4gKiBAcGFyYW0gY2hhcnRcbiAqIEBwYXJhbSBmb3JjZVJhdGlvXG4gKiBAcGFyYW0gZm9yY2VTdHlsZVxuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY2FudmFzIGNvbnRleHQgc2l6ZSBvciB0cmFuc2Zvcm1hdGlvbiBoYXMgY2hhbmdlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJldGluYVNjYWxlKFxuICBjaGFydDogQ2hhcnQsXG4gIGZvcmNlUmF0aW86IG51bWJlcixcbiAgZm9yY2VTdHlsZT86IGJvb2xlYW5cbik6IGJvb2xlYW4gfCB2b2lkIHtcbiAgY29uc3QgcGl4ZWxSYXRpbyA9IGZvcmNlUmF0aW8gfHwgMTtcbiAgY29uc3QgZGV2aWNlSGVpZ2h0ID0gTWF0aC5mbG9vcihjaGFydC5oZWlnaHQgKiBwaXhlbFJhdGlvKTtcbiAgY29uc3QgZGV2aWNlV2lkdGggPSBNYXRoLmZsb29yKGNoYXJ0LndpZHRoICogcGl4ZWxSYXRpbyk7XG5cbiAgY2hhcnQuaGVpZ2h0ID0gTWF0aC5mbG9vcihjaGFydC5oZWlnaHQpO1xuICBjaGFydC53aWR0aCA9IE1hdGguZmxvb3IoY2hhcnQud2lkdGgpO1xuXG4gIGNvbnN0IGNhbnZhcyA9IGNoYXJ0LmNhbnZhcztcblxuICAvLyBJZiBubyBzdHlsZSBoYXMgYmVlbiBzZXQgb24gdGhlIGNhbnZhcywgdGhlIHJlbmRlciBzaXplIGlzIHVzZWQgYXMgZGlzcGxheSBzaXplLFxuICAvLyBtYWtpbmcgdGhlIGNoYXJ0IHZpc3VhbGx5IGJpZ2dlciwgc28gbGV0J3MgZW5mb3JjZSBpdCB0byB0aGUgXCJjb3JyZWN0XCIgdmFsdWVzLlxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzM1NzVcbiAgaWYgKGNhbnZhcy5zdHlsZSAmJiAoZm9yY2VTdHlsZSB8fCAoIWNhbnZhcy5zdHlsZS5oZWlnaHQgJiYgIWNhbnZhcy5zdHlsZS53aWR0aCkpKSB7XG4gICAgY2FudmFzLnN0eWxlLmhlaWdodCA9IGAke2NoYXJ0LmhlaWdodH1weGA7XG4gICAgY2FudmFzLnN0eWxlLndpZHRoID0gYCR7Y2hhcnQud2lkdGh9cHhgO1xuICB9XG5cbiAgaWYgKGNoYXJ0LmN1cnJlbnREZXZpY2VQaXhlbFJhdGlvICE9PSBwaXhlbFJhdGlvXG4gICAgICB8fCBjYW52YXMuaGVpZ2h0ICE9PSBkZXZpY2VIZWlnaHRcbiAgICAgIHx8IGNhbnZhcy53aWR0aCAhPT0gZGV2aWNlV2lkdGgpIHtcbiAgICBjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyA9IHBpeGVsUmF0aW87XG4gICAgY2FudmFzLmhlaWdodCA9IGRldmljZUhlaWdodDtcbiAgICBjYW52YXMud2lkdGggPSBkZXZpY2VXaWR0aDtcbiAgICBjaGFydC5jdHguc2V0VHJhbnNmb3JtKHBpeGVsUmF0aW8sIDAsIDAsIHBpeGVsUmF0aW8sIDAsIDApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBEZXRlY3RzIHN1cHBvcnQgZm9yIG9wdGlvbnMgb2JqZWN0IGFyZ3VtZW50IGluIGFkZEV2ZW50TGlzdGVuZXIuXG4gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lciNTYWZlbHlfZGV0ZWN0aW5nX29wdGlvbl9zdXBwb3J0XG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydHNFdmVudExpc3RlbmVyT3B0aW9ucyA9IChmdW5jdGlvbigpIHtcbiAgbGV0IHBhc3NpdmVTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgdHJ5IHtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgZ2V0IHBhc3NpdmUoKSB7IC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgYnJvd3NlciBhdHRlbXB0cyB0byBhY2Nlc3MgdGhlIHBhc3NpdmUgcHJvcGVydHkuXG4gICAgICAgIHBhc3NpdmVTdXBwb3J0ZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBhcyBFdmVudExpc3RlbmVyT3B0aW9ucztcblxuICAgIGlmIChfaXNEb21TdXBwb3J0ZWQoKSkge1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Rlc3QnLCBudWxsLCBvcHRpb25zKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCd0ZXN0JywgbnVsbCwgb3B0aW9ucyk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gY29udGludWUgcmVnYXJkbGVzcyBvZiBlcnJvclxuICB9XG4gIHJldHVybiBwYXNzaXZlU3VwcG9ydGVkO1xufSgpKTtcblxuLyoqXG4gKiBUaGUgXCJ1c2VkXCIgc2l6ZSBpcyB0aGUgZmluYWwgdmFsdWUgb2YgYSBkaW1lbnNpb24gcHJvcGVydHkgYWZ0ZXIgYWxsIGNhbGN1bGF0aW9ucyBoYXZlXG4gKiBiZWVuIHBlcmZvcm1lZC4gVGhpcyBtZXRob2QgdXNlcyB0aGUgY29tcHV0ZWQgc3R5bGUgb2YgYGVsZW1lbnRgIGJ1dCByZXR1cm5zIHVuZGVmaW5lZFxuICogaWYgdGhlIGNvbXB1dGVkIHN0eWxlIGlzIG5vdCBleHByZXNzZWQgaW4gcGl4ZWxzLiBUaGF0IGNhbiBoYXBwZW4gaW4gc29tZSBjYXNlcyB3aGVyZVxuICogYGVsZW1lbnRgIGhhcyBhIHNpemUgcmVsYXRpdmUgdG8gaXRzIHBhcmVudCBhbmQgdGhpcyBsYXN0IG9uZSBpcyBub3QgeWV0IGRpc3BsYXllZCxcbiAqIGZvciBleGFtcGxlIGJlY2F1c2Ugb2YgYGRpc3BsYXk6IG5vbmVgIG9uIGEgcGFyZW50IG5vZGUuXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy91c2VkX3ZhbHVlXG4gKiBAcmV0dXJucyBTaXplIGluIHBpeGVscyBvciB1bmRlZmluZWQgaWYgdW5rbm93bi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmVhZFVzZWRTaXplKFxuICBlbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgcHJvcGVydHk6ICd3aWR0aCcgfCAnaGVpZ2h0J1xuKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgdmFsdWUgPSBnZXRTdHlsZShlbGVtZW50LCBwcm9wZXJ0eSk7XG4gIGNvbnN0IG1hdGNoZXMgPSB2YWx1ZSAmJiB2YWx1ZS5tYXRjaCgvXihcXGQrKShcXC5cXGQrKT9weCQvKTtcbiAgcmV0dXJuIG1hdGNoZXMgPyArbWF0Y2hlc1sxXSA6IHVuZGVmaW5lZDtcbn1cbiIsICJpbXBvcnQgdHlwZSB7UG9pbnQsIFNwbGluZVBvaW50fSBmcm9tICcuLi90eXBlcy9nZW9tZXRyaWMuanMnO1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfcG9pbnRJbkxpbmUocDE6IFBvaW50LCBwMjogUG9pbnQsIHQ6IG51bWJlciwgbW9kZT8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgcmV0dXJuIHtcbiAgICB4OiBwMS54ICsgdCAqIChwMi54IC0gcDEueCksXG4gICAgeTogcDEueSArIHQgKiAocDIueSAtIHAxLnkpXG4gIH07XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9zdGVwcGVkSW50ZXJwb2xhdGlvbihcbiAgcDE6IFBvaW50LFxuICBwMjogUG9pbnQsXG4gIHQ6IG51bWJlciwgbW9kZTogJ21pZGRsZScgfCAnYWZ0ZXInIHwgdW5rbm93blxuKSB7XG4gIHJldHVybiB7XG4gICAgeDogcDEueCArIHQgKiAocDIueCAtIHAxLngpLFxuICAgIHk6IG1vZGUgPT09ICdtaWRkbGUnID8gdCA8IDAuNSA/IHAxLnkgOiBwMi55XG4gICAgICA6IG1vZGUgPT09ICdhZnRlcicgPyB0IDwgMSA/IHAxLnkgOiBwMi55XG4gICAgICAgIDogdCA+IDAgPyBwMi55IDogcDEueVxuICB9O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYmV6aWVySW50ZXJwb2xhdGlvbihwMTogU3BsaW5lUG9pbnQsIHAyOiBTcGxpbmVQb2ludCwgdDogbnVtYmVyLCBtb2RlPykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBjb25zdCBjcDEgPSB7eDogcDEuY3AyeCwgeTogcDEuY3AyeX07XG4gIGNvbnN0IGNwMiA9IHt4OiBwMi5jcDF4LCB5OiBwMi5jcDF5fTtcbiAgY29uc3QgYSA9IF9wb2ludEluTGluZShwMSwgY3AxLCB0KTtcbiAgY29uc3QgYiA9IF9wb2ludEluTGluZShjcDEsIGNwMiwgdCk7XG4gIGNvbnN0IGMgPSBfcG9pbnRJbkxpbmUoY3AyLCBwMiwgdCk7XG4gIGNvbnN0IGQgPSBfcG9pbnRJbkxpbmUoYSwgYiwgdCk7XG4gIGNvbnN0IGUgPSBfcG9pbnRJbkxpbmUoYiwgYywgdCk7XG4gIHJldHVybiBfcG9pbnRJbkxpbmUoZCwgZSwgdCk7XG59XG4iLCAiZXhwb3J0IGludGVyZmFjZSBSVExBZGFwdGVyIHtcbiAgeCh4OiBudW1iZXIpOiBudW1iZXI7XG4gIHNldFdpZHRoKHc6IG51bWJlcik6IHZvaWQ7XG4gIHRleHRBbGlnbihhbGlnbjogJ2NlbnRlcicgfCAnbGVmdCcgfCAncmlnaHQnKTogJ2NlbnRlcicgfCAnbGVmdCcgfCAncmlnaHQnO1xuICB4UGx1cyh4OiBudW1iZXIsIHZhbHVlOiBudW1iZXIpOiBudW1iZXI7XG4gIGxlZnRGb3JMdHIoeDogbnVtYmVyLCBpdGVtV2lkdGg6IG51bWJlcik6IG51bWJlcjtcbn1cblxuY29uc3QgZ2V0UmlnaHRUb0xlZnRBZGFwdGVyID0gZnVuY3Rpb24ocmVjdFg6IG51bWJlciwgd2lkdGg6IG51bWJlcik6IFJUTEFkYXB0ZXIge1xuICByZXR1cm4ge1xuICAgIHgoeCkge1xuICAgICAgcmV0dXJuIHJlY3RYICsgcmVjdFggKyB3aWR0aCAtIHg7XG4gICAgfSxcbiAgICBzZXRXaWR0aCh3KSB7XG4gICAgICB3aWR0aCA9IHc7XG4gICAgfSxcbiAgICB0ZXh0QWxpZ24oYWxpZ24pIHtcbiAgICAgIGlmIChhbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgcmV0dXJuIGFsaWduO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFsaWduID09PSAncmlnaHQnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgICB9LFxuICAgIHhQbHVzKHgsIHZhbHVlKSB7XG4gICAgICByZXR1cm4geCAtIHZhbHVlO1xuICAgIH0sXG4gICAgbGVmdEZvckx0cih4LCBpdGVtV2lkdGgpIHtcbiAgICAgIHJldHVybiB4IC0gaXRlbVdpZHRoO1xuICAgIH0sXG4gIH07XG59O1xuXG5jb25zdCBnZXRMZWZ0VG9SaWdodEFkYXB0ZXIgPSBmdW5jdGlvbigpOiBSVExBZGFwdGVyIHtcbiAgcmV0dXJuIHtcbiAgICB4KHgpIHtcbiAgICAgIHJldHVybiB4O1xuICAgIH0sXG4gICAgc2V0V2lkdGgodykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgfSxcbiAgICB0ZXh0QWxpZ24oYWxpZ24pIHtcbiAgICAgIHJldHVybiBhbGlnbjtcbiAgICB9LFxuICAgIHhQbHVzKHgsIHZhbHVlKSB7XG4gICAgICByZXR1cm4geCArIHZhbHVlO1xuICAgIH0sXG4gICAgbGVmdEZvckx0cih4LCBfaXRlbVdpZHRoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICByZXR1cm4geDtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJ0bEFkYXB0ZXIocnRsOiBib29sZWFuLCByZWN0WDogbnVtYmVyLCB3aWR0aDogbnVtYmVyKSB7XG4gIHJldHVybiBydGwgPyBnZXRSaWdodFRvTGVmdEFkYXB0ZXIocmVjdFgsIHdpZHRoKSA6IGdldExlZnRUb1JpZ2h0QWRhcHRlcigpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gb3ZlcnJpZGVUZXh0RGlyZWN0aW9uKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCBkaXJlY3Rpb246ICdsdHInIHwgJ3J0bCcpIHtcbiAgbGV0IHN0eWxlOiBDU1NTdHlsZURlY2xhcmF0aW9uLCBvcmlnaW5hbDogW3N0cmluZywgc3RyaW5nXTtcbiAgaWYgKGRpcmVjdGlvbiA9PT0gJ2x0cicgfHwgZGlyZWN0aW9uID09PSAncnRsJykge1xuICAgIHN0eWxlID0gY3R4LmNhbnZhcy5zdHlsZTtcbiAgICBvcmlnaW5hbCA9IFtcbiAgICAgIHN0eWxlLmdldFByb3BlcnR5VmFsdWUoJ2RpcmVjdGlvbicpLFxuICAgICAgc3R5bGUuZ2V0UHJvcGVydHlQcmlvcml0eSgnZGlyZWN0aW9uJyksXG4gICAgXTtcblxuICAgIHN0eWxlLnNldFByb3BlcnR5KCdkaXJlY3Rpb24nLCBkaXJlY3Rpb24sICdpbXBvcnRhbnQnKTtcbiAgICAoY3R4IGFzIHsgcHJldlRleHREaXJlY3Rpb24/OiBbc3RyaW5nLCBzdHJpbmddIH0pLnByZXZUZXh0RGlyZWN0aW9uID0gb3JpZ2luYWw7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc3RvcmVUZXh0RGlyZWN0aW9uKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCBvcmlnaW5hbD86IFtzdHJpbmcsIHN0cmluZ10pIHtcbiAgaWYgKG9yaWdpbmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICBkZWxldGUgKGN0eCBhcyB7IHByZXZUZXh0RGlyZWN0aW9uPzogW3N0cmluZywgc3RyaW5nXSB9KS5wcmV2VGV4dERpcmVjdGlvbjtcbiAgICBjdHguY2FudmFzLnN0eWxlLnNldFByb3BlcnR5KCdkaXJlY3Rpb24nLCBvcmlnaW5hbFswXSwgb3JpZ2luYWxbMV0pO1xuICB9XG59XG4iLCAiaW1wb3J0IHtfYW5nbGVCZXR3ZWVuLCBfYW5nbGVEaWZmLCBfaXNCZXR3ZWVuLCBfbm9ybWFsaXplQW5nbGV9IGZyb20gJy4vaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCB7Y3JlYXRlQ29udGV4dH0gZnJvbSAnLi9oZWxwZXJzLm9wdGlvbnMuanMnO1xuaW1wb3J0IHtpc1BhdHRlcm5PckdyYWRpZW50fSBmcm9tICcuL2hlbHBlcnMuY29sb3IuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi9lbGVtZW50cy9lbGVtZW50LmxpbmUuanMnKS5kZWZhdWx0IH0gTGluZUVsZW1lbnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi9lbGVtZW50cy9lbGVtZW50LnBvaW50LmpzJykuZGVmYXVsdCB9IFBvaW50RWxlbWVudFxuICogQHR5cGVkZWYge3tzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlciwgbG9vcDogYm9vbGVhbiwgc3R5bGU/OiBhbnl9fSBTZWdtZW50XG4gKi9cblxuZnVuY3Rpb24gcHJvcGVydHlGbihwcm9wZXJ0eSkge1xuICBpZiAocHJvcGVydHkgPT09ICdhbmdsZScpIHtcbiAgICByZXR1cm4ge1xuICAgICAgYmV0d2VlbjogX2FuZ2xlQmV0d2VlbixcbiAgICAgIGNvbXBhcmU6IF9hbmdsZURpZmYsXG4gICAgICBub3JtYWxpemU6IF9ub3JtYWxpemVBbmdsZSxcbiAgICB9O1xuICB9XG4gIHJldHVybiB7XG4gICAgYmV0d2VlbjogX2lzQmV0d2VlbixcbiAgICBjb21wYXJlOiAoYSwgYikgPT4gYSAtIGIsXG4gICAgbm9ybWFsaXplOiB4ID0+IHhcbiAgfTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplU2VnbWVudCh7c3RhcnQsIGVuZCwgY291bnQsIGxvb3AsIHN0eWxlfSkge1xuICByZXR1cm4ge1xuICAgIHN0YXJ0OiBzdGFydCAlIGNvdW50LFxuICAgIGVuZDogZW5kICUgY291bnQsXG4gICAgbG9vcDogbG9vcCAmJiAoZW5kIC0gc3RhcnQgKyAxKSAlIGNvdW50ID09PSAwLFxuICAgIHN0eWxlXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldFNlZ21lbnQoc2VnbWVudCwgcG9pbnRzLCBib3VuZHMpIHtcbiAgY29uc3Qge3Byb3BlcnR5LCBzdGFydDogc3RhcnRCb3VuZCwgZW5kOiBlbmRCb3VuZH0gPSBib3VuZHM7XG4gIGNvbnN0IHtiZXR3ZWVuLCBub3JtYWxpemV9ID0gcHJvcGVydHlGbihwcm9wZXJ0eSk7XG4gIGNvbnN0IGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICBsZXQge3N0YXJ0LCBlbmQsIGxvb3B9ID0gc2VnbWVudDtcbiAgbGV0IGksIGlsZW47XG5cbiAgaWYgKGxvb3ApIHtcbiAgICBzdGFydCArPSBjb3VudDtcbiAgICBlbmQgKz0gY291bnQ7XG4gICAgZm9yIChpID0gMCwgaWxlbiA9IGNvdW50OyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBpZiAoIWJldHdlZW4obm9ybWFsaXplKHBvaW50c1tzdGFydCAlIGNvdW50XVtwcm9wZXJ0eV0pLCBzdGFydEJvdW5kLCBlbmRCb3VuZCkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBzdGFydC0tO1xuICAgICAgZW5kLS07XG4gICAgfVxuICAgIHN0YXJ0ICU9IGNvdW50O1xuICAgIGVuZCAlPSBjb3VudDtcbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkge1xuICAgIGVuZCArPSBjb3VudDtcbiAgfVxuICByZXR1cm4ge3N0YXJ0LCBlbmQsIGxvb3AsIHN0eWxlOiBzZWdtZW50LnN0eWxlfTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzdWItc2VnbWVudChzKSBvZiBhIGxpbmUgc2VnbWVudCB0aGF0IGZhbGwgaW4gdGhlIGdpdmVuIGJvdW5kc1xuICogQHBhcmFtIHtvYmplY3R9IHNlZ21lbnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBzZWdtZW50LnN0YXJ0IC0gc3RhcnQgaW5kZXggb2YgdGhlIHNlZ21lbnQsIHJlZmVycmluZyB0aGUgcG9pbnRzIGFycmF5XG4gKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudC5lbmQgLSBlbmQgaW5kZXggb2YgdGhlIHNlZ21lbnQsIHJlZmVycmluZyB0aGUgcG9pbnRzIGFycmF5XG4gKiBAcGFyYW0ge2Jvb2xlYW59IHNlZ21lbnQubG9vcCAtIGluZGljYXRlcyB0aGF0IHRoZSBzZWdtZW50IGlzIGEgbG9vcFxuICogQHBhcmFtIHtvYmplY3R9IFtzZWdtZW50LnN0eWxlXSAtIHNlZ21lbnQgc3R5bGVcbiAqIEBwYXJhbSB7UG9pbnRFbGVtZW50W119IHBvaW50cyAtIHRoZSBwb2ludHMgdGhhdCB0aGlzIHNlZ21lbnQgcmVmZXJzIHRvXG4gKiBAcGFyYW0ge29iamVjdH0gW2JvdW5kc11cbiAqIEBwYXJhbSB7c3RyaW5nfSBib3VuZHMucHJvcGVydHkgLSB0aGUgcHJvcGVydHkgb2YgYSBgUG9pbnRFbGVtZW50YCB3ZSBhcmUgYm91bmRpbmcuIGB4YCwgYHlgIG9yIGBhbmdsZWAuXG4gKiBAcGFyYW0ge251bWJlcn0gYm91bmRzLnN0YXJ0IC0gc3RhcnQgdmFsdWUgb2YgdGhlIHByb3BlcnR5XG4gKiBAcGFyYW0ge251bWJlcn0gYm91bmRzLmVuZCAtIGVuZCB2YWx1ZSBvZiB0aGUgcHJvcGVydHlcbiAqIEBwcml2YXRlXG4gKiovXG5leHBvcnQgZnVuY3Rpb24gX2JvdW5kU2VnbWVudChzZWdtZW50LCBwb2ludHMsIGJvdW5kcykge1xuICBpZiAoIWJvdW5kcykge1xuICAgIHJldHVybiBbc2VnbWVudF07XG4gIH1cblxuICBjb25zdCB7cHJvcGVydHksIHN0YXJ0OiBzdGFydEJvdW5kLCBlbmQ6IGVuZEJvdW5kfSA9IGJvdW5kcztcbiAgY29uc3QgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuICBjb25zdCB7Y29tcGFyZSwgYmV0d2Vlbiwgbm9ybWFsaXplfSA9IHByb3BlcnR5Rm4ocHJvcGVydHkpO1xuICBjb25zdCB7c3RhcnQsIGVuZCwgbG9vcCwgc3R5bGV9ID0gZ2V0U2VnbWVudChzZWdtZW50LCBwb2ludHMsIGJvdW5kcyk7XG5cbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGxldCBpbnNpZGUgPSBmYWxzZTtcbiAgbGV0IHN1YlN0YXJ0ID0gbnVsbDtcbiAgbGV0IHZhbHVlLCBwb2ludCwgcHJldlZhbHVlO1xuXG4gIGNvbnN0IHN0YXJ0SXNCZWZvcmUgPSAoKSA9PiBiZXR3ZWVuKHN0YXJ0Qm91bmQsIHByZXZWYWx1ZSwgdmFsdWUpICYmIGNvbXBhcmUoc3RhcnRCb3VuZCwgcHJldlZhbHVlKSAhPT0gMDtcbiAgY29uc3QgZW5kSXNCZWZvcmUgPSAoKSA9PiBjb21wYXJlKGVuZEJvdW5kLCB2YWx1ZSkgPT09IDAgfHwgYmV0d2VlbihlbmRCb3VuZCwgcHJldlZhbHVlLCB2YWx1ZSk7XG4gIGNvbnN0IHNob3VsZFN0YXJ0ID0gKCkgPT4gaW5zaWRlIHx8IHN0YXJ0SXNCZWZvcmUoKTtcbiAgY29uc3Qgc2hvdWxkU3RvcCA9ICgpID0+ICFpbnNpZGUgfHwgZW5kSXNCZWZvcmUoKTtcblxuICBmb3IgKGxldCBpID0gc3RhcnQsIHByZXYgPSBzdGFydDsgaSA8PSBlbmQ7ICsraSkge1xuICAgIHBvaW50ID0gcG9pbnRzW2kgJSBjb3VudF07XG5cbiAgICBpZiAocG9pbnQuc2tpcCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFsdWUgPSBub3JtYWxpemUocG9pbnRbcHJvcGVydHldKTtcblxuICAgIGlmICh2YWx1ZSA9PT0gcHJldlZhbHVlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpbnNpZGUgPSBiZXR3ZWVuKHZhbHVlLCBzdGFydEJvdW5kLCBlbmRCb3VuZCk7XG5cbiAgICBpZiAoc3ViU3RhcnQgPT09IG51bGwgJiYgc2hvdWxkU3RhcnQoKSkge1xuICAgICAgc3ViU3RhcnQgPSBjb21wYXJlKHZhbHVlLCBzdGFydEJvdW5kKSA9PT0gMCA/IGkgOiBwcmV2O1xuICAgIH1cblxuICAgIGlmIChzdWJTdGFydCAhPT0gbnVsbCAmJiBzaG91bGRTdG9wKCkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKG5vcm1hbGl6ZVNlZ21lbnQoe3N0YXJ0OiBzdWJTdGFydCwgZW5kOiBpLCBsb29wLCBjb3VudCwgc3R5bGV9KSk7XG4gICAgICBzdWJTdGFydCA9IG51bGw7XG4gICAgfVxuICAgIHByZXYgPSBpO1xuICAgIHByZXZWYWx1ZSA9IHZhbHVlO1xuICB9XG5cbiAgaWYgKHN1YlN0YXJ0ICE9PSBudWxsKSB7XG4gICAgcmVzdWx0LnB1c2gobm9ybWFsaXplU2VnbWVudCh7c3RhcnQ6IHN1YlN0YXJ0LCBlbmQsIGxvb3AsIGNvdW50LCBzdHlsZX0pKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzZWdtZW50cyBvZiB0aGUgbGluZSB0aGF0IGFyZSBpbnNpZGUgZ2l2ZW4gYm91bmRzXG4gKiBAcGFyYW0ge0xpbmVFbGVtZW50fSBsaW5lXG4gKiBAcGFyYW0ge29iamVjdH0gW2JvdW5kc11cbiAqIEBwYXJhbSB7c3RyaW5nfSBib3VuZHMucHJvcGVydHkgLSB0aGUgcHJvcGVydHkgd2UgYXJlIGJvdW5kaW5nIHdpdGguIGB4YCwgYHlgIG9yIGBhbmdsZWAuXG4gKiBAcGFyYW0ge251bWJlcn0gYm91bmRzLnN0YXJ0IC0gc3RhcnQgdmFsdWUgb2YgdGhlIGBwcm9wZXJ0eWBcbiAqIEBwYXJhbSB7bnVtYmVyfSBib3VuZHMuZW5kIC0gZW5kIHZhbHVlIG9mIHRoZSBgcHJvcGVydHlgXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2JvdW5kU2VnbWVudHMobGluZSwgYm91bmRzKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBzZWdtZW50cyA9IGxpbmUuc2VnbWVudHM7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHN1YiA9IF9ib3VuZFNlZ21lbnQoc2VnbWVudHNbaV0sIGxpbmUucG9pbnRzLCBib3VuZHMpO1xuICAgIGlmIChzdWIubGVuZ3RoKSB7XG4gICAgICByZXN1bHQucHVzaCguLi5zdWIpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEZpbmQgc3RhcnQgYW5kIGVuZCBpbmRleCBvZiBhIGxpbmUuXG4gKi9cbmZ1bmN0aW9uIGZpbmRTdGFydEFuZEVuZChwb2ludHMsIGNvdW50LCBsb29wLCBzcGFuR2Fwcykge1xuICBsZXQgc3RhcnQgPSAwO1xuICBsZXQgZW5kID0gY291bnQgLSAxO1xuXG4gIGlmIChsb29wICYmICFzcGFuR2Fwcykge1xuICAgIC8vIGxvb3AgYW5kIG5vdCBzcGFubmluZyBnYXBzLCBmaXJzdCBmaW5kIGEgZ2FwIHRvIHN0YXJ0IGZyb21cbiAgICB3aGlsZSAoc3RhcnQgPCBjb3VudCAmJiAhcG9pbnRzW3N0YXJ0XS5za2lwKSB7XG4gICAgICBzdGFydCsrO1xuICAgIH1cbiAgfVxuXG4gIC8vIGZpbmQgZmlyc3Qgbm9uIHNraXBwZWQgcG9pbnQgKGFmdGVyIHRoZSBmaXJzdCBnYXAgcG9zc2libHkpXG4gIHdoaWxlIChzdGFydCA8IGNvdW50ICYmIHBvaW50c1tzdGFydF0uc2tpcCkge1xuICAgIHN0YXJ0Kys7XG4gIH1cblxuICAvLyBpZiB3ZSBsb29wZWQgdG8gY291bnQsIHN0YXJ0IG5lZWRzIHRvIGJlIDBcbiAgc3RhcnQgJT0gY291bnQ7XG5cbiAgaWYgKGxvb3ApIHtcbiAgICAvLyBsb29wIHdpbGwgZ28gcGFzdCBjb3VudCwgaWYgc3RhcnQgPiAwXG4gICAgZW5kICs9IHN0YXJ0O1xuICB9XG5cbiAgd2hpbGUgKGVuZCA+IHN0YXJ0ICYmIHBvaW50c1tlbmQgJSBjb3VudF0uc2tpcCkge1xuICAgIGVuZC0tO1xuICB9XG5cbiAgLy8gZW5kIGNvdWxkIGJlIG1vcmUgdGhhbiBjb3VudCwgbm9ybWFsaXplXG4gIGVuZCAlPSBjb3VudDtcblxuICByZXR1cm4ge3N0YXJ0LCBlbmR9O1xufVxuXG4vKipcbiAqIENvbXB1dGUgc29saWQgc2VnbWVudHMgZnJvbSBQb2ludHMsIHdoZW4gc3BhbkdhcHMgPT09IGZhbHNlXG4gKiBAcGFyYW0ge1BvaW50RWxlbWVudFtdfSBwb2ludHMgLSB0aGUgcG9pbnRzXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgLSBzdGFydCBpbmRleFxuICogQHBhcmFtIHtudW1iZXJ9IG1heCAtIG1heCBpbmRleCAoY2FuIGdvIHBhc3QgY291bnQgb24gYSBsb29wKVxuICogQHBhcmFtIHtib29sZWFufSBsb29wIC0gYm9vbGVhbiBpbmRpY2F0aW5nIHRoYXQgdGhpcyB3b3VsZCBiZSBhIGxvb3AgaWYgbm8gZ2FwcyBhcmUgZm91bmRcbiAqL1xuZnVuY3Rpb24gc29saWRTZWdtZW50cyhwb2ludHMsIHN0YXJ0LCBtYXgsIGxvb3ApIHtcbiAgY29uc3QgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgbGV0IGxhc3QgPSBzdGFydDtcbiAgbGV0IHByZXYgPSBwb2ludHNbc3RhcnRdO1xuICBsZXQgZW5kO1xuXG4gIGZvciAoZW5kID0gc3RhcnQgKyAxOyBlbmQgPD0gbWF4OyArK2VuZCkge1xuICAgIGNvbnN0IGN1ciA9IHBvaW50c1tlbmQgJSBjb3VudF07XG4gICAgaWYgKGN1ci5za2lwIHx8IGN1ci5zdG9wKSB7XG4gICAgICBpZiAoIXByZXYuc2tpcCkge1xuICAgICAgICBsb29wID0gZmFsc2U7XG4gICAgICAgIHJlc3VsdC5wdXNoKHtzdGFydDogc3RhcnQgJSBjb3VudCwgZW5kOiAoZW5kIC0gMSkgJSBjb3VudCwgbG9vcH0pO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHN0YXJ0ID0gbGFzdCA9IGN1ci5zdG9wID8gZW5kIDogbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGFzdCA9IGVuZDtcbiAgICAgIGlmIChwcmV2LnNraXApIHtcbiAgICAgICAgc3RhcnQgPSBlbmQ7XG4gICAgICB9XG4gICAgfVxuICAgIHByZXYgPSBjdXI7XG4gIH1cblxuICBpZiAobGFzdCAhPT0gbnVsbCkge1xuICAgIHJlc3VsdC5wdXNoKHtzdGFydDogc3RhcnQgJSBjb3VudCwgZW5kOiBsYXN0ICUgY291bnQsIGxvb3B9KTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQ29tcHV0ZSB0aGUgY29udGludW91cyBzZWdtZW50cyB0aGF0IGRlZmluZSB0aGUgd2hvbGUgbGluZVxuICogVGhlcmUgY2FuIGJlIHNraXBwZWQgcG9pbnRzIHdpdGhpbiBhIHNlZ21lbnQsIGlmIHNwYW5HYXBzIGlzIHRydWUuXG4gKiBAcGFyYW0ge0xpbmVFbGVtZW50fSBsaW5lXG4gKiBAcGFyYW0ge29iamVjdH0gW3NlZ21lbnRPcHRpb25zXVxuICogQHJldHVybiB7U2VnbWVudFtdfVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jb21wdXRlU2VnbWVudHMobGluZSwgc2VnbWVudE9wdGlvbnMpIHtcbiAgY29uc3QgcG9pbnRzID0gbGluZS5wb2ludHM7XG4gIGNvbnN0IHNwYW5HYXBzID0gbGluZS5vcHRpb25zLnNwYW5HYXBzO1xuICBjb25zdCBjb3VudCA9IHBvaW50cy5sZW5ndGg7XG5cbiAgaWYgKCFjb3VudCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IGxvb3AgPSAhIWxpbmUuX2xvb3A7XG4gIGNvbnN0IHtzdGFydCwgZW5kfSA9IGZpbmRTdGFydEFuZEVuZChwb2ludHMsIGNvdW50LCBsb29wLCBzcGFuR2Fwcyk7XG5cbiAgaWYgKHNwYW5HYXBzID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIHNwbGl0QnlTdHlsZXMobGluZSwgW3tzdGFydCwgZW5kLCBsb29wfV0sIHBvaW50cywgc2VnbWVudE9wdGlvbnMpO1xuICB9XG5cbiAgY29uc3QgbWF4ID0gZW5kIDwgc3RhcnQgPyBlbmQgKyBjb3VudCA6IGVuZDtcbiAgY29uc3QgY29tcGxldGVMb29wID0gISFsaW5lLl9mdWxsTG9vcCAmJiBzdGFydCA9PT0gMCAmJiBlbmQgPT09IGNvdW50IC0gMTtcbiAgcmV0dXJuIHNwbGl0QnlTdHlsZXMobGluZSwgc29saWRTZWdtZW50cyhwb2ludHMsIHN0YXJ0LCBtYXgsIGNvbXBsZXRlTG9vcCksIHBvaW50cywgc2VnbWVudE9wdGlvbnMpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7U2VnbWVudFtdfSBzZWdtZW50c1xuICogQHBhcmFtIHtQb2ludEVsZW1lbnRbXX0gcG9pbnRzXG4gKiBAcGFyYW0ge29iamVjdH0gW3NlZ21lbnRPcHRpb25zXVxuICogQHJldHVybiB7U2VnbWVudFtdfVxuICovXG5mdW5jdGlvbiBzcGxpdEJ5U3R5bGVzKGxpbmUsIHNlZ21lbnRzLCBwb2ludHMsIHNlZ21lbnRPcHRpb25zKSB7XG4gIGlmICghc2VnbWVudE9wdGlvbnMgfHwgIXNlZ21lbnRPcHRpb25zLnNldENvbnRleHQgfHwgIXBvaW50cykge1xuICAgIHJldHVybiBzZWdtZW50cztcbiAgfVxuICByZXR1cm4gZG9TcGxpdEJ5U3R5bGVzKGxpbmUsIHNlZ21lbnRzLCBwb2ludHMsIHNlZ21lbnRPcHRpb25zKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0xpbmVFbGVtZW50fSBsaW5lXG4gKiBAcGFyYW0ge1NlZ21lbnRbXX0gc2VnbWVudHNcbiAqIEBwYXJhbSB7UG9pbnRFbGVtZW50W119IHBvaW50c1xuICogQHBhcmFtIHtvYmplY3R9IFtzZWdtZW50T3B0aW9uc11cbiAqIEByZXR1cm4ge1NlZ21lbnRbXX1cbiAqL1xuZnVuY3Rpb24gZG9TcGxpdEJ5U3R5bGVzKGxpbmUsIHNlZ21lbnRzLCBwb2ludHMsIHNlZ21lbnRPcHRpb25zKSB7XG4gIGNvbnN0IGNoYXJ0Q29udGV4dCA9IGxpbmUuX2NoYXJ0LmdldENvbnRleHQoKTtcbiAgY29uc3QgYmFzZVN0eWxlID0gcmVhZFN0eWxlKGxpbmUub3B0aW9ucyk7XG4gIGNvbnN0IHtfZGF0YXNldEluZGV4OiBkYXRhc2V0SW5kZXgsIG9wdGlvbnM6IHtzcGFuR2Fwc319ID0gbGluZTtcbiAgY29uc3QgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgbGV0IHByZXZTdHlsZSA9IGJhc2VTdHlsZTtcbiAgbGV0IHN0YXJ0ID0gc2VnbWVudHNbMF0uc3RhcnQ7XG4gIGxldCBpID0gc3RhcnQ7XG5cbiAgZnVuY3Rpb24gYWRkU3R5bGUocywgZSwgbCwgc3QpIHtcbiAgICBjb25zdCBkaXIgPSBzcGFuR2FwcyA/IC0xIDogMTtcbiAgICBpZiAocyA9PT0gZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBTdHlsZSBjYW4gbm90IHN0YXJ0L2VuZCBvbiBhIHNraXBwZWQgcG9pbnQsIGFkanVzdCBpbmRpY2VzIGFjY29yZGluZ2x5XG4gICAgcyArPSBjb3VudDtcbiAgICB3aGlsZSAocG9pbnRzW3MgJSBjb3VudF0uc2tpcCkge1xuICAgICAgcyAtPSBkaXI7XG4gICAgfVxuICAgIHdoaWxlIChwb2ludHNbZSAlIGNvdW50XS5za2lwKSB7XG4gICAgICBlICs9IGRpcjtcbiAgICB9XG4gICAgaWYgKHMgJSBjb3VudCAhPT0gZSAlIGNvdW50KSB7XG4gICAgICByZXN1bHQucHVzaCh7c3RhcnQ6IHMgJSBjb3VudCwgZW5kOiBlICUgY291bnQsIGxvb3A6IGwsIHN0eWxlOiBzdH0pO1xuICAgICAgcHJldlN0eWxlID0gc3Q7XG4gICAgICBzdGFydCA9IGUgJSBjb3VudDtcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpIHtcbiAgICBzdGFydCA9IHNwYW5HYXBzID8gc3RhcnQgOiBzZWdtZW50LnN0YXJ0O1xuICAgIGxldCBwcmV2ID0gcG9pbnRzW3N0YXJ0ICUgY291bnRdO1xuICAgIGxldCBzdHlsZTtcbiAgICBmb3IgKGkgPSBzdGFydCArIDE7IGkgPD0gc2VnbWVudC5lbmQ7IGkrKykge1xuICAgICAgY29uc3QgcHQgPSBwb2ludHNbaSAlIGNvdW50XTtcbiAgICAgIHN0eWxlID0gcmVhZFN0eWxlKHNlZ21lbnRPcHRpb25zLnNldENvbnRleHQoY3JlYXRlQ29udGV4dChjaGFydENvbnRleHQsIHtcbiAgICAgICAgdHlwZTogJ3NlZ21lbnQnLFxuICAgICAgICBwMDogcHJldixcbiAgICAgICAgcDE6IHB0LFxuICAgICAgICBwMERhdGFJbmRleDogKGkgLSAxKSAlIGNvdW50LFxuICAgICAgICBwMURhdGFJbmRleDogaSAlIGNvdW50LFxuICAgICAgICBkYXRhc2V0SW5kZXhcbiAgICAgIH0pKSk7XG4gICAgICBpZiAoc3R5bGVDaGFuZ2VkKHN0eWxlLCBwcmV2U3R5bGUpKSB7XG4gICAgICAgIGFkZFN0eWxlKHN0YXJ0LCBpIC0gMSwgc2VnbWVudC5sb29wLCBwcmV2U3R5bGUpO1xuICAgICAgfVxuICAgICAgcHJldiA9IHB0O1xuICAgICAgcHJldlN0eWxlID0gc3R5bGU7XG4gICAgfVxuICAgIGlmIChzdGFydCA8IGkgLSAxKSB7XG4gICAgICBhZGRTdHlsZShzdGFydCwgaSAtIDEsIHNlZ21lbnQubG9vcCwgcHJldlN0eWxlKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiByZWFkU3R5bGUob3B0aW9ucykge1xuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmRDb2xvcjogb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgYm9yZGVyQ2FwU3R5bGU6IG9wdGlvbnMuYm9yZGVyQ2FwU3R5bGUsXG4gICAgYm9yZGVyRGFzaDogb3B0aW9ucy5ib3JkZXJEYXNoLFxuICAgIGJvcmRlckRhc2hPZmZzZXQ6IG9wdGlvbnMuYm9yZGVyRGFzaE9mZnNldCxcbiAgICBib3JkZXJKb2luU3R5bGU6IG9wdGlvbnMuYm9yZGVySm9pblN0eWxlLFxuICAgIGJvcmRlcldpZHRoOiBvcHRpb25zLmJvcmRlcldpZHRoLFxuICAgIGJvcmRlckNvbG9yOiBvcHRpb25zLmJvcmRlckNvbG9yXG4gIH07XG59XG5cbmZ1bmN0aW9uIHN0eWxlQ2hhbmdlZChzdHlsZSwgcHJldlN0eWxlKSB7XG4gIGlmICghcHJldlN0eWxlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IGNhY2hlID0gW107XG4gIGNvbnN0IHJlcGxhY2VyID0gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIGlmICghaXNQYXR0ZXJuT3JHcmFkaWVudCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKCFjYWNoZS5pbmNsdWRlcyh2YWx1ZSkpIHtcbiAgICAgIGNhY2hlLnB1c2godmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gY2FjaGUuaW5kZXhPZih2YWx1ZSk7XG4gIH07XG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShzdHlsZSwgcmVwbGFjZXIpICE9PSBKU09OLnN0cmluZ2lmeShwcmV2U3R5bGUsIHJlcGxhY2VyKTtcbn1cbiIsICJpbXBvcnQge3JlcXVlc3RBbmltRnJhbWV9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5leHRyYXMuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuL2NvcmUuYW5pbWF0aW9uLmpzJykuZGVmYXVsdCB9IEFuaW1hdGlvblxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4vY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IENoYXJ0XG4gKi9cblxuLyoqXG4gKiBQbGVhc2UgdXNlIHRoZSBtb2R1bGUncyBkZWZhdWx0IGV4cG9ydCB3aGljaCBwcm92aWRlcyBhIHNpbmdsZXRvbiBpbnN0YW5jZVxuICogTm90ZTogY2xhc3MgaXMgZXhwb3J0IGZvciB0eXBlZG9jXG4gKi9cbmV4cG9ydCBjbGFzcyBBbmltYXRvciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX3JlcXVlc3QgPSBudWxsO1xuICAgIHRoaXMuX2NoYXJ0cyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLl9ydW5uaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fbGFzdERhdGUgPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9ub3RpZnkoY2hhcnQsIGFuaW1zLCBkYXRlLCB0eXBlKSB7XG4gICAgY29uc3QgY2FsbGJhY2tzID0gYW5pbXMubGlzdGVuZXJzW3R5cGVdO1xuICAgIGNvbnN0IG51bVN0ZXBzID0gYW5pbXMuZHVyYXRpb247XG5cbiAgICBjYWxsYmFja3MuZm9yRWFjaChmbiA9PiBmbih7XG4gICAgICBjaGFydCxcbiAgICAgIGluaXRpYWw6IGFuaW1zLmluaXRpYWwsXG4gICAgICBudW1TdGVwcyxcbiAgICAgIGN1cnJlbnRTdGVwOiBNYXRoLm1pbihkYXRlIC0gYW5pbXMuc3RhcnQsIG51bVN0ZXBzKVxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3JlZnJlc2goKSB7XG4gICAgaWYgKHRoaXMuX3JlcXVlc3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fcnVubmluZyA9IHRydWU7XG5cbiAgICB0aGlzLl9yZXF1ZXN0ID0gcmVxdWVzdEFuaW1GcmFtZS5jYWxsKHdpbmRvdywgKCkgPT4ge1xuICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgICB0aGlzLl9yZXF1ZXN0ID0gbnVsbDtcblxuICAgICAgaWYgKHRoaXMuX3J1bm5pbmcpIHtcbiAgICAgICAgdGhpcy5fcmVmcmVzaCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdXBkYXRlKGRhdGUgPSBEYXRlLm5vdygpKSB7XG4gICAgbGV0IHJlbWFpbmluZyA9IDA7XG5cbiAgICB0aGlzLl9jaGFydHMuZm9yRWFjaCgoYW5pbXMsIGNoYXJ0KSA9PiB7XG4gICAgICBpZiAoIWFuaW1zLnJ1bm5pbmcgfHwgIWFuaW1zLml0ZW1zLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBpdGVtcyA9IGFuaW1zLml0ZW1zO1xuICAgICAgbGV0IGkgPSBpdGVtcy5sZW5ndGggLSAxO1xuICAgICAgbGV0IGRyYXcgPSBmYWxzZTtcbiAgICAgIGxldCBpdGVtO1xuXG4gICAgICBmb3IgKDsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgaXRlbSA9IGl0ZW1zW2ldO1xuXG4gICAgICAgIGlmIChpdGVtLl9hY3RpdmUpIHtcbiAgICAgICAgICBpZiAoaXRlbS5fdG90YWwgPiBhbmltcy5kdXJhdGlvbikge1xuICAgICAgICAgICAgLy8gaWYgdGhlIGFuaW1hdGlvbiBoYXMgYmVlbiB1cGRhdGVkIGFuZCBpdHMgZHVyYXRpb24gcHJvbG9uZ2VkLFxuICAgICAgICAgICAgLy8gdXBkYXRlIHRvIHRvdGFsIGR1cmF0aW9uIG9mIGN1cnJlbnQgYW5pbWF0aW9ucyBydW4gKGZvciBwcm9ncmVzcyBldmVudClcbiAgICAgICAgICAgIGFuaW1zLmR1cmF0aW9uID0gaXRlbS5fdG90YWw7XG4gICAgICAgICAgfVxuICAgICAgICAgIGl0ZW0udGljayhkYXRlKTtcbiAgICAgICAgICBkcmF3ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBSZW1vdmUgdGhlIGl0ZW0gYnkgcmVwbGFjaW5nIGl0IHdpdGggbGFzdCBpdGVtIGFuZCByZW1vdmluZyB0aGUgbGFzdFxuICAgICAgICAgIC8vIEEgbG90IGZhc3RlciB0aGFuIHNwbGljZS5cbiAgICAgICAgICBpdGVtc1tpXSA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdO1xuICAgICAgICAgIGl0ZW1zLnBvcCgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChkcmF3KSB7XG4gICAgICAgIGNoYXJ0LmRyYXcoKTtcbiAgICAgICAgdGhpcy5fbm90aWZ5KGNoYXJ0LCBhbmltcywgZGF0ZSwgJ3Byb2dyZXNzJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgIGFuaW1zLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fbm90aWZ5KGNoYXJ0LCBhbmltcywgZGF0ZSwgJ2NvbXBsZXRlJyk7XG4gICAgICAgIGFuaW1zLmluaXRpYWwgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgcmVtYWluaW5nICs9IGl0ZW1zLmxlbmd0aDtcbiAgICB9KTtcblxuICAgIHRoaXMuX2xhc3REYXRlID0gZGF0ZTtcblxuICAgIGlmIChyZW1haW5pbmcgPT09IDApIHtcbiAgICAgIHRoaXMuX3J1bm5pbmcgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRBbmltcyhjaGFydCkge1xuICAgIGNvbnN0IGNoYXJ0cyA9IHRoaXMuX2NoYXJ0cztcbiAgICBsZXQgYW5pbXMgPSBjaGFydHMuZ2V0KGNoYXJ0KTtcbiAgICBpZiAoIWFuaW1zKSB7XG4gICAgICBhbmltcyA9IHtcbiAgICAgICAgcnVubmluZzogZmFsc2UsXG4gICAgICAgIGluaXRpYWw6IHRydWUsXG4gICAgICAgIGl0ZW1zOiBbXSxcbiAgICAgICAgbGlzdGVuZXJzOiB7XG4gICAgICAgICAgY29tcGxldGU6IFtdLFxuICAgICAgICAgIHByb2dyZXNzOiBbXVxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgY2hhcnRzLnNldChjaGFydCwgYW5pbXMpO1xuICAgIH1cbiAgICByZXR1cm4gYW5pbXM7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnRcblx0ICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IC0gZXZlbnQgbmFtZVxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYiAtIGNhbGxiYWNrXG5cdCAqL1xuICBsaXN0ZW4oY2hhcnQsIGV2ZW50LCBjYikge1xuICAgIHRoaXMuX2dldEFuaW1zKGNoYXJ0KS5saXN0ZW5lcnNbZXZlbnRdLnB1c2goY2IpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEFkZCBhbmltYXRpb25zXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG5cdCAqIEBwYXJhbSB7QW5pbWF0aW9uW119IGl0ZW1zIC0gYW5pbWF0aW9uc1xuXHQgKi9cbiAgYWRkKGNoYXJ0LCBpdGVtcykge1xuICAgIGlmICghaXRlbXMgfHwgIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9nZXRBbmltcyhjaGFydCkuaXRlbXMucHVzaCguLi5pdGVtcyk7XG4gIH1cblxuICAvKipcblx0ICogQ291bnRzIG51bWJlciBvZiBhY3RpdmUgYW5pbWF0aW9ucyBmb3IgdGhlIGNoYXJ0XG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG5cdCAqL1xuICBoYXMoY2hhcnQpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0QW5pbXMoY2hhcnQpLml0ZW1zLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcblx0ICogU3RhcnQgYW5pbWF0aW5nIChhbGwgY2hhcnRzKVxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydFxuXHQgKi9cbiAgc3RhcnQoY2hhcnQpIHtcbiAgICBjb25zdCBhbmltcyA9IHRoaXMuX2NoYXJ0cy5nZXQoY2hhcnQpO1xuICAgIGlmICghYW5pbXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgYW5pbXMucnVubmluZyA9IHRydWU7XG4gICAgYW5pbXMuc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIGFuaW1zLmR1cmF0aW9uID0gYW5pbXMuaXRlbXMucmVkdWNlKChhY2MsIGN1cikgPT4gTWF0aC5tYXgoYWNjLCBjdXIuX2R1cmF0aW9uKSwgMCk7XG4gICAgdGhpcy5fcmVmcmVzaCgpO1xuICB9XG5cbiAgcnVubmluZyhjaGFydCkge1xuICAgIGlmICghdGhpcy5fcnVubmluZykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBhbmltcyA9IHRoaXMuX2NoYXJ0cy5nZXQoY2hhcnQpO1xuICAgIGlmICghYW5pbXMgfHwgIWFuaW1zLnJ1bm5pbmcgfHwgIWFuaW1zLml0ZW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBTdG9wIGFsbCBhbmltYXRpb25zIGZvciB0aGUgY2hhcnRcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnRcblx0ICovXG4gIHN0b3AoY2hhcnQpIHtcbiAgICBjb25zdCBhbmltcyA9IHRoaXMuX2NoYXJ0cy5nZXQoY2hhcnQpO1xuICAgIGlmICghYW5pbXMgfHwgIWFuaW1zLml0ZW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpdGVtcyA9IGFuaW1zLml0ZW1zO1xuICAgIGxldCBpID0gaXRlbXMubGVuZ3RoIC0gMTtcblxuICAgIGZvciAoOyBpID49IDA7IC0taSkge1xuICAgICAgaXRlbXNbaV0uY2FuY2VsKCk7XG4gICAgfVxuICAgIGFuaW1zLml0ZW1zID0gW107XG4gICAgdGhpcy5fbm90aWZ5KGNoYXJ0LCBhbmltcywgRGF0ZS5ub3coKSwgJ2NvbXBsZXRlJyk7XG4gIH1cblxuICAvKipcblx0ICogUmVtb3ZlIGNoYXJ0IGZyb20gQW5pbWF0b3Jcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnRcblx0ICovXG4gIHJlbW92ZShjaGFydCkge1xuICAgIHJldHVybiB0aGlzLl9jaGFydHMuZGVsZXRlKGNoYXJ0KTtcbiAgfVxufVxuXG4vLyBzaW5nbGV0b24gaW5zdGFuY2VcbmV4cG9ydCBkZWZhdWx0IC8qICNfX1BVUkVfXyAqLyBuZXcgQW5pbWF0b3IoKTtcbiIsICJpbXBvcnQgZWZmZWN0cyBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZWFzaW5nLmpzJztcbmltcG9ydCB7cmVzb2x2ZX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm9wdGlvbnMuanMnO1xuaW1wb3J0IHtjb2xvciBhcyBoZWxwZXJzQ29sb3J9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb2xvci5qcyc7XG5cbmNvbnN0IHRyYW5zcGFyZW50ID0gJ3RyYW5zcGFyZW50JztcbmNvbnN0IGludGVycG9sYXRvcnMgPSB7XG4gIGJvb2xlYW4oZnJvbSwgdG8sIGZhY3Rvcikge1xuICAgIHJldHVybiBmYWN0b3IgPiAwLjUgPyB0byA6IGZyb207XG4gIH0sXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZnJvbVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZhY3RvclxuICAgKi9cbiAgY29sb3IoZnJvbSwgdG8sIGZhY3Rvcikge1xuICAgIGNvbnN0IGMwID0gaGVscGVyc0NvbG9yKGZyb20gfHwgdHJhbnNwYXJlbnQpO1xuICAgIGNvbnN0IGMxID0gYzAudmFsaWQgJiYgaGVscGVyc0NvbG9yKHRvIHx8IHRyYW5zcGFyZW50KTtcbiAgICByZXR1cm4gYzEgJiYgYzEudmFsaWRcbiAgICAgID8gYzEubWl4KGMwLCBmYWN0b3IpLmhleFN0cmluZygpXG4gICAgICA6IHRvO1xuICB9LFxuICBudW1iZXIoZnJvbSwgdG8sIGZhY3Rvcikge1xuICAgIHJldHVybiBmcm9tICsgKHRvIC0gZnJvbSkgKiBmYWN0b3I7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFuaW1hdGlvbiB7XG4gIGNvbnN0cnVjdG9yKGNmZywgdGFyZ2V0LCBwcm9wLCB0bykge1xuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHRhcmdldFtwcm9wXTtcblxuICAgIHRvID0gcmVzb2x2ZShbY2ZnLnRvLCB0bywgY3VycmVudFZhbHVlLCBjZmcuZnJvbV0pO1xuICAgIGNvbnN0IGZyb20gPSByZXNvbHZlKFtjZmcuZnJvbSwgY3VycmVudFZhbHVlLCB0b10pO1xuXG4gICAgdGhpcy5fYWN0aXZlID0gdHJ1ZTtcbiAgICB0aGlzLl9mbiA9IGNmZy5mbiB8fCBpbnRlcnBvbGF0b3JzW2NmZy50eXBlIHx8IHR5cGVvZiBmcm9tXTtcbiAgICB0aGlzLl9lYXNpbmcgPSBlZmZlY3RzW2NmZy5lYXNpbmddIHx8IGVmZmVjdHMubGluZWFyO1xuICAgIHRoaXMuX3N0YXJ0ID0gTWF0aC5mbG9vcihEYXRlLm5vdygpICsgKGNmZy5kZWxheSB8fCAwKSk7XG4gICAgdGhpcy5fZHVyYXRpb24gPSB0aGlzLl90b3RhbCA9IE1hdGguZmxvb3IoY2ZnLmR1cmF0aW9uKTtcbiAgICB0aGlzLl9sb29wID0gISFjZmcubG9vcDtcbiAgICB0aGlzLl90YXJnZXQgPSB0YXJnZXQ7XG4gICAgdGhpcy5fcHJvcCA9IHByb3A7XG4gICAgdGhpcy5fZnJvbSA9IGZyb207XG4gICAgdGhpcy5fdG8gPSB0bztcbiAgICB0aGlzLl9wcm9taXNlcyA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGFjdGl2ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fYWN0aXZlO1xuICB9XG5cbiAgdXBkYXRlKGNmZywgdG8sIGRhdGUpIHtcbiAgICBpZiAodGhpcy5fYWN0aXZlKSB7XG4gICAgICB0aGlzLl9ub3RpZnkoZmFsc2UpO1xuXG4gICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLl90YXJnZXRbdGhpcy5fcHJvcF07XG4gICAgICBjb25zdCBlbGFwc2VkID0gZGF0ZSAtIHRoaXMuX3N0YXJ0O1xuICAgICAgY29uc3QgcmVtYWluID0gdGhpcy5fZHVyYXRpb24gLSBlbGFwc2VkO1xuICAgICAgdGhpcy5fc3RhcnQgPSBkYXRlO1xuICAgICAgdGhpcy5fZHVyYXRpb24gPSBNYXRoLmZsb29yKE1hdGgubWF4KHJlbWFpbiwgY2ZnLmR1cmF0aW9uKSk7XG4gICAgICB0aGlzLl90b3RhbCArPSBlbGFwc2VkO1xuICAgICAgdGhpcy5fbG9vcCA9ICEhY2ZnLmxvb3A7XG4gICAgICB0aGlzLl90byA9IHJlc29sdmUoW2NmZy50bywgdG8sIGN1cnJlbnRWYWx1ZSwgY2ZnLmZyb21dKTtcbiAgICAgIHRoaXMuX2Zyb20gPSByZXNvbHZlKFtjZmcuZnJvbSwgY3VycmVudFZhbHVlLCB0b10pO1xuICAgIH1cbiAgfVxuXG4gIGNhbmNlbCgpIHtcbiAgICBpZiAodGhpcy5fYWN0aXZlKSB7XG4gICAgICAvLyB1cGRhdGUgY3VycmVudCBldmFsdWF0ZWQgdmFsdWUsIGZvciBzbW9vdGhlciBhbmltYXRpb25zXG4gICAgICB0aGlzLnRpY2soRGF0ZS5ub3coKSk7XG4gICAgICB0aGlzLl9hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuX25vdGlmeShmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgdGljayhkYXRlKSB7XG4gICAgY29uc3QgZWxhcHNlZCA9IGRhdGUgLSB0aGlzLl9zdGFydDtcbiAgICBjb25zdCBkdXJhdGlvbiA9IHRoaXMuX2R1cmF0aW9uO1xuICAgIGNvbnN0IHByb3AgPSB0aGlzLl9wcm9wO1xuICAgIGNvbnN0IGZyb20gPSB0aGlzLl9mcm9tO1xuICAgIGNvbnN0IGxvb3AgPSB0aGlzLl9sb29wO1xuICAgIGNvbnN0IHRvID0gdGhpcy5fdG87XG4gICAgbGV0IGZhY3RvcjtcblxuICAgIHRoaXMuX2FjdGl2ZSA9IGZyb20gIT09IHRvICYmIChsb29wIHx8IChlbGFwc2VkIDwgZHVyYXRpb24pKTtcblxuICAgIGlmICghdGhpcy5fYWN0aXZlKSB7XG4gICAgICB0aGlzLl90YXJnZXRbcHJvcF0gPSB0bztcbiAgICAgIHRoaXMuX25vdGlmeSh0cnVlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZWxhcHNlZCA8IDApIHtcbiAgICAgIHRoaXMuX3RhcmdldFtwcm9wXSA9IGZyb207XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZmFjdG9yID0gKGVsYXBzZWQgLyBkdXJhdGlvbikgJSAyO1xuICAgIGZhY3RvciA9IGxvb3AgJiYgZmFjdG9yID4gMSA/IDIgLSBmYWN0b3IgOiBmYWN0b3I7XG4gICAgZmFjdG9yID0gdGhpcy5fZWFzaW5nKE1hdGgubWluKDEsIE1hdGgubWF4KDAsIGZhY3RvcikpKTtcblxuICAgIHRoaXMuX3RhcmdldFtwcm9wXSA9IHRoaXMuX2ZuKGZyb20sIHRvLCBmYWN0b3IpO1xuICB9XG5cbiAgd2FpdCgpIHtcbiAgICBjb25zdCBwcm9taXNlcyA9IHRoaXMuX3Byb21pc2VzIHx8ICh0aGlzLl9wcm9taXNlcyA9IFtdKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlcywgcmVqKSA9PiB7XG4gICAgICBwcm9taXNlcy5wdXNoKHtyZXMsIHJlan0pO1xuICAgIH0pO1xuICB9XG5cbiAgX25vdGlmeShyZXNvbHZlZCkge1xuICAgIGNvbnN0IG1ldGhvZCA9IHJlc29sdmVkID8gJ3JlcycgOiAncmVqJztcbiAgICBjb25zdCBwcm9taXNlcyA9IHRoaXMuX3Byb21pc2VzIHx8IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvbWlzZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHByb21pc2VzW2ldW21ldGhvZF0oKTtcbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgYW5pbWF0b3IgZnJvbSAnLi9jb3JlLmFuaW1hdG9yLmpzJztcbmltcG9ydCBBbmltYXRpb24gZnJvbSAnLi9jb3JlLmFuaW1hdGlvbi5qcyc7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi9jb3JlLmRlZmF1bHRzLmpzJztcbmltcG9ydCB7aXNBcnJheSwgaXNPYmplY3R9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQW5pbWF0aW9ucyB7XG4gIGNvbnN0cnVjdG9yKGNoYXJ0LCBjb25maWcpIHtcbiAgICB0aGlzLl9jaGFydCA9IGNoYXJ0O1xuICAgIHRoaXMuX3Byb3BlcnRpZXMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5jb25maWd1cmUoY29uZmlnKTtcbiAgfVxuXG4gIGNvbmZpZ3VyZShjb25maWcpIHtcbiAgICBpZiAoIWlzT2JqZWN0KGNvbmZpZykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBhbmltYXRpb25PcHRpb25zID0gT2JqZWN0LmtleXMoZGVmYXVsdHMuYW5pbWF0aW9uKTtcbiAgICBjb25zdCBhbmltYXRlZFByb3BzID0gdGhpcy5fcHJvcGVydGllcztcblxuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGNvbmZpZykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY29uc3QgY2ZnID0gY29uZmlnW2tleV07XG4gICAgICBpZiAoIWlzT2JqZWN0KGNmZykpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzb2x2ZWQgPSB7fTtcbiAgICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIGFuaW1hdGlvbk9wdGlvbnMpIHtcbiAgICAgICAgcmVzb2x2ZWRbb3B0aW9uXSA9IGNmZ1tvcHRpb25dO1xuICAgICAgfVxuXG4gICAgICAoaXNBcnJheShjZmcucHJvcGVydGllcykgJiYgY2ZnLnByb3BlcnRpZXMgfHwgW2tleV0pLmZvckVhY2goKHByb3ApID0+IHtcbiAgICAgICAgaWYgKHByb3AgPT09IGtleSB8fCAhYW5pbWF0ZWRQcm9wcy5oYXMocHJvcCkpIHtcbiAgICAgICAgICBhbmltYXRlZFByb3BzLnNldChwcm9wLCByZXNvbHZlZCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG5cdCAqIFV0aWxpdHkgdG8gaGFuZGxlIGFuaW1hdGlvbiBvZiBgb3B0aW9uc2AuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfYW5pbWF0ZU9wdGlvbnModGFyZ2V0LCB2YWx1ZXMpIHtcbiAgICBjb25zdCBuZXdPcHRpb25zID0gdmFsdWVzLm9wdGlvbnM7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHJlc29sdmVUYXJnZXRPcHRpb25zKHRhcmdldCwgbmV3T3B0aW9ucyk7XG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgYW5pbWF0aW9ucyA9IHRoaXMuX2NyZWF0ZUFuaW1hdGlvbnMob3B0aW9ucywgbmV3T3B0aW9ucyk7XG4gICAgaWYgKG5ld09wdGlvbnMuJHNoYXJlZCkge1xuICAgICAgLy8gR29pbmcgdG8gc2hhcmVkIG9wdGlvbnM6XG4gICAgICAvLyBBZnRlciBhbGwgYW5pbWF0aW9ucyBhcmUgZG9uZSwgYXNzaWduIHRoZSBzaGFyZWQgb3B0aW9ucyBvYmplY3QgdG8gdGhlIGVsZW1lbnRcbiAgICAgIC8vIFNvIGFueSBuZXcgdXBkYXRlcyB0byB0aGUgc2hhcmVkIG9wdGlvbnMgYXJlIG9ic2VydmVkXG4gICAgICBhd2FpdEFsbCh0YXJnZXQub3B0aW9ucy4kYW5pbWF0aW9ucywgbmV3T3B0aW9ucykudGhlbigoKSA9PiB7XG4gICAgICAgIHRhcmdldC5vcHRpb25zID0gbmV3T3B0aW9ucztcbiAgICAgIH0sICgpID0+IHtcbiAgICAgICAgLy8gcmVqZWN0ZWQsIG5vb3BcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBhbmltYXRpb25zO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfY3JlYXRlQW5pbWF0aW9ucyh0YXJnZXQsIHZhbHVlcykge1xuICAgIGNvbnN0IGFuaW1hdGVkUHJvcHMgPSB0aGlzLl9wcm9wZXJ0aWVzO1xuICAgIGNvbnN0IGFuaW1hdGlvbnMgPSBbXTtcbiAgICBjb25zdCBydW5uaW5nID0gdGFyZ2V0LiRhbmltYXRpb25zIHx8ICh0YXJnZXQuJGFuaW1hdGlvbnMgPSB7fSk7XG4gICAgY29uc3QgcHJvcHMgPSBPYmplY3Qua2V5cyh2YWx1ZXMpO1xuICAgIGNvbnN0IGRhdGUgPSBEYXRlLm5vdygpO1xuICAgIGxldCBpO1xuXG4gICAgZm9yIChpID0gcHJvcHMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGNvbnN0IHByb3AgPSBwcm9wc1tpXTtcbiAgICAgIGlmIChwcm9wLmNoYXJBdCgwKSA9PT0gJyQnKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcCA9PT0gJ29wdGlvbnMnKSB7XG4gICAgICAgIGFuaW1hdGlvbnMucHVzaCguLi50aGlzLl9hbmltYXRlT3B0aW9ucyh0YXJnZXQsIHZhbHVlcykpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzW3Byb3BdO1xuICAgICAgbGV0IGFuaW1hdGlvbiA9IHJ1bm5pbmdbcHJvcF07XG4gICAgICBjb25zdCBjZmcgPSBhbmltYXRlZFByb3BzLmdldChwcm9wKTtcblxuICAgICAgaWYgKGFuaW1hdGlvbikge1xuICAgICAgICBpZiAoY2ZnICYmIGFuaW1hdGlvbi5hY3RpdmUoKSkge1xuICAgICAgICAgIC8vIFRoZXJlIGlzIGFuIGV4aXN0aW5nIGFjdGl2ZSBhbmltYXRpb24sIGxldCdzIHVwZGF0ZSB0aGF0XG4gICAgICAgICAgYW5pbWF0aW9uLnVwZGF0ZShjZmcsIHZhbHVlLCBkYXRlKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhbmltYXRpb24uY2FuY2VsKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghY2ZnIHx8ICFjZmcuZHVyYXRpb24pIHtcbiAgICAgICAgLy8gbm90IGFuaW1hdGVkLCBzZXQgZGlyZWN0bHkgdG8gbmV3IHZhbHVlXG4gICAgICAgIHRhcmdldFtwcm9wXSA9IHZhbHVlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgcnVubmluZ1twcm9wXSA9IGFuaW1hdGlvbiA9IG5ldyBBbmltYXRpb24oY2ZnLCB0YXJnZXQsIHByb3AsIHZhbHVlKTtcbiAgICAgIGFuaW1hdGlvbnMucHVzaChhbmltYXRpb24pO1xuICAgIH1cbiAgICByZXR1cm4gYW5pbWF0aW9ucztcbiAgfVxuXG5cbiAgLyoqXG5cdCAqIFVwZGF0ZSBgdGFyZ2V0YCBwcm9wZXJ0aWVzIHRvIG5ldyB2YWx1ZXMsIHVzaW5nIGNvbmZpZ3VyZWQgYW5pbWF0aW9uc1xuXHQgKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0IC0gb2JqZWN0IHRvIHVwZGF0ZVxuXHQgKiBAcGFyYW0ge29iamVjdH0gdmFsdWVzIC0gbmV3IHRhcmdldCBwcm9wZXJ0aWVzXG5cdCAqIEByZXR1cm5zIHtib29sZWFufHVuZGVmaW5lZH0gLSBgdHJ1ZWAgaWYgYW5pbWF0aW9ucyB3ZXJlIHN0YXJ0ZWRcblx0ICoqL1xuICB1cGRhdGUodGFyZ2V0LCB2YWx1ZXMpIHtcbiAgICBpZiAodGhpcy5fcHJvcGVydGllcy5zaXplID09PSAwKSB7XG4gICAgICAvLyBOb3RoaW5nIGlzIGFuaW1hdGVkLCBqdXN0IGFwcGx5IHRoZSBuZXcgdmFsdWVzLlxuICAgICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHZhbHVlcyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYW5pbWF0aW9ucyA9IHRoaXMuX2NyZWF0ZUFuaW1hdGlvbnModGFyZ2V0LCB2YWx1ZXMpO1xuXG4gICAgaWYgKGFuaW1hdGlvbnMubGVuZ3RoKSB7XG4gICAgICBhbmltYXRvci5hZGQodGhpcy5fY2hhcnQsIGFuaW1hdGlvbnMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGF3YWl0QWxsKGFuaW1hdGlvbnMsIHByb3BlcnRpZXMpIHtcbiAgY29uc3QgcnVubmluZyA9IFtdO1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGFuaW0gPSBhbmltYXRpb25zW2tleXNbaV1dO1xuICAgIGlmIChhbmltICYmIGFuaW0uYWN0aXZlKCkpIHtcbiAgICAgIHJ1bm5pbmcucHVzaChhbmltLndhaXQoKSk7XG4gICAgfVxuICB9XG4gIC8vIEB0cy1pZ25vcmVcbiAgcmV0dXJuIFByb21pc2UuYWxsKHJ1bm5pbmcpO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlVGFyZ2V0T3B0aW9ucyh0YXJnZXQsIG5ld09wdGlvbnMpIHtcbiAgaWYgKCFuZXdPcHRpb25zKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBvcHRpb25zID0gdGFyZ2V0Lm9wdGlvbnM7XG4gIGlmICghb3B0aW9ucykge1xuICAgIHRhcmdldC5vcHRpb25zID0gbmV3T3B0aW9ucztcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKG9wdGlvbnMuJHNoYXJlZCkge1xuICAgIC8vIEdvaW5nIGZyb20gc2hhcmVkIG9wdGlvbnMgdG8gZGlzdGluY3Qgb25lOlxuICAgIC8vIENyZWF0ZSBuZXcgb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyB0aGUgb2xkIHNoYXJlZCB2YWx1ZXMgYW5kIHN0YXJ0IHVwZGF0aW5nIHRoYXQuXG4gICAgdGFyZ2V0Lm9wdGlvbnMgPSBvcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucywgeyRzaGFyZWQ6IGZhbHNlLCAkYW5pbWF0aW9uczoge319KTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cbiIsICJpbXBvcnQgQW5pbWF0aW9ucyBmcm9tICcuL2NvcmUuYW5pbWF0aW9ucy5qcyc7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi9jb3JlLmRlZmF1bHRzLmpzJztcbmltcG9ydCB7aXNBcnJheSwgaXNGaW5pdGUsIGlzT2JqZWN0LCB2YWx1ZU9yRGVmYXVsdCwgcmVzb2x2ZU9iamVjdEtleSwgZGVmaW5lZH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuaW1wb3J0IHtsaXN0ZW5BcnJheUV2ZW50cywgdW5saXN0ZW5BcnJheUV2ZW50c30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvbGxlY3Rpb24uanMnO1xuaW1wb3J0IHtjcmVhdGVDb250ZXh0LCBzaWdufSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi9jb3JlLmNvbnRyb2xsZXIuanMnKS5kZWZhdWx0IH0gQ2hhcnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuL2NvcmUuc2NhbGUuanMnKS5kZWZhdWx0IH0gU2NhbGVcbiAqL1xuXG5mdW5jdGlvbiBzY2FsZUNsaXAoc2NhbGUsIGFsbG93ZWRPdmVyZmxvdykge1xuICBjb25zdCBvcHRzID0gc2NhbGUgJiYgc2NhbGUub3B0aW9ucyB8fCB7fTtcbiAgY29uc3QgcmV2ZXJzZSA9IG9wdHMucmV2ZXJzZTtcbiAgY29uc3QgbWluID0gb3B0cy5taW4gPT09IHVuZGVmaW5lZCA/IGFsbG93ZWRPdmVyZmxvdyA6IDA7XG4gIGNvbnN0IG1heCA9IG9wdHMubWF4ID09PSB1bmRlZmluZWQgPyBhbGxvd2VkT3ZlcmZsb3cgOiAwO1xuICByZXR1cm4ge1xuICAgIHN0YXJ0OiByZXZlcnNlID8gbWF4IDogbWluLFxuICAgIGVuZDogcmV2ZXJzZSA/IG1pbiA6IG1heFxuICB9O1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0Q2xpcCh4U2NhbGUsIHlTY2FsZSwgYWxsb3dlZE92ZXJmbG93KSB7XG4gIGlmIChhbGxvd2VkT3ZlcmZsb3cgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IHggPSBzY2FsZUNsaXAoeFNjYWxlLCBhbGxvd2VkT3ZlcmZsb3cpO1xuICBjb25zdCB5ID0gc2NhbGVDbGlwKHlTY2FsZSwgYWxsb3dlZE92ZXJmbG93KTtcblxuICByZXR1cm4ge1xuICAgIHRvcDogeS5lbmQsXG4gICAgcmlnaHQ6IHguZW5kLFxuICAgIGJvdHRvbTogeS5zdGFydCxcbiAgICBsZWZ0OiB4LnN0YXJ0XG4gIH07XG59XG5cbmZ1bmN0aW9uIHRvQ2xpcCh2YWx1ZSkge1xuICBsZXQgdCwgciwgYiwgbDtcblxuICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgdCA9IHZhbHVlLnRvcDtcbiAgICByID0gdmFsdWUucmlnaHQ7XG4gICAgYiA9IHZhbHVlLmJvdHRvbTtcbiAgICBsID0gdmFsdWUubGVmdDtcbiAgfSBlbHNlIHtcbiAgICB0ID0gciA9IGIgPSBsID0gdmFsdWU7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHRvcDogdCxcbiAgICByaWdodDogcixcbiAgICBib3R0b206IGIsXG4gICAgbGVmdDogbCxcbiAgICBkaXNhYmxlZDogdmFsdWUgPT09IGZhbHNlXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldFNvcnRlZERhdGFzZXRJbmRpY2VzKGNoYXJ0LCBmaWx0ZXJWaXNpYmxlKSB7XG4gIGNvbnN0IGtleXMgPSBbXTtcbiAgY29uc3QgbWV0YXNldHMgPSBjaGFydC5fZ2V0U29ydGVkRGF0YXNldE1ldGFzKGZpbHRlclZpc2libGUpO1xuICBsZXQgaSwgaWxlbjtcblxuICBmb3IgKGkgPSAwLCBpbGVuID0gbWV0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAga2V5cy5wdXNoKG1ldGFzZXRzW2ldLmluZGV4KTtcbiAgfVxuICByZXR1cm4ga2V5cztcbn1cblxuZnVuY3Rpb24gYXBwbHlTdGFjayhzdGFjaywgdmFsdWUsIGRzSW5kZXgsIG9wdGlvbnMgPSB7fSkge1xuICBjb25zdCBrZXlzID0gc3RhY2sua2V5cztcbiAgY29uc3Qgc2luZ2xlTW9kZSA9IG9wdGlvbnMubW9kZSA9PT0gJ3NpbmdsZSc7XG4gIGxldCBpLCBpbGVuLCBkYXRhc2V0SW5kZXgsIG90aGVyVmFsdWU7XG5cbiAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZm9yIChpID0gMCwgaWxlbiA9IGtleXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgZGF0YXNldEluZGV4ID0gK2tleXNbaV07XG4gICAgaWYgKGRhdGFzZXRJbmRleCA9PT0gZHNJbmRleCkge1xuICAgICAgaWYgKG9wdGlvbnMuYWxsKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIG90aGVyVmFsdWUgPSBzdGFjay52YWx1ZXNbZGF0YXNldEluZGV4XTtcbiAgICBpZiAoaXNGaW5pdGUob3RoZXJWYWx1ZSkgJiYgKHNpbmdsZU1vZGUgfHwgKHZhbHVlID09PSAwIHx8IHNpZ24odmFsdWUpID09PSBzaWduKG90aGVyVmFsdWUpKSkpIHtcbiAgICAgIHZhbHVlICs9IG90aGVyVmFsdWU7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gY29udmVydE9iamVjdERhdGFUb0FycmF5KGRhdGEpIHtcbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGRhdGEpO1xuICBjb25zdCBhZGF0YSA9IG5ldyBBcnJheShrZXlzLmxlbmd0aCk7XG4gIGxldCBpLCBpbGVuLCBrZXk7XG4gIGZvciAoaSA9IDAsIGlsZW4gPSBrZXlzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIGtleSA9IGtleXNbaV07XG4gICAgYWRhdGFbaV0gPSB7XG4gICAgICB4OiBrZXksXG4gICAgICB5OiBkYXRhW2tleV1cbiAgICB9O1xuICB9XG4gIHJldHVybiBhZGF0YTtcbn1cblxuZnVuY3Rpb24gaXNTdGFja2VkKHNjYWxlLCBtZXRhKSB7XG4gIGNvbnN0IHN0YWNrZWQgPSBzY2FsZSAmJiBzY2FsZS5vcHRpb25zLnN0YWNrZWQ7XG4gIHJldHVybiBzdGFja2VkIHx8IChzdGFja2VkID09PSB1bmRlZmluZWQgJiYgbWV0YS5zdGFjayAhPT0gdW5kZWZpbmVkKTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RhY2tLZXkoaW5kZXhTY2FsZSwgdmFsdWVTY2FsZSwgbWV0YSkge1xuICByZXR1cm4gYCR7aW5kZXhTY2FsZS5pZH0uJHt2YWx1ZVNjYWxlLmlkfS4ke21ldGEuc3RhY2sgfHwgbWV0YS50eXBlfWA7XG59XG5cbmZ1bmN0aW9uIGdldFVzZXJCb3VuZHMoc2NhbGUpIHtcbiAgY29uc3Qge21pbiwgbWF4LCBtaW5EZWZpbmVkLCBtYXhEZWZpbmVkfSA9IHNjYWxlLmdldFVzZXJCb3VuZHMoKTtcbiAgcmV0dXJuIHtcbiAgICBtaW46IG1pbkRlZmluZWQgPyBtaW4gOiBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksXG4gICAgbWF4OiBtYXhEZWZpbmVkID8gbWF4IDogTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldE9yQ3JlYXRlU3RhY2soc3RhY2tzLCBzdGFja0tleSwgaW5kZXhWYWx1ZSkge1xuICBjb25zdCBzdWJTdGFjayA9IHN0YWNrc1tzdGFja0tleV0gfHwgKHN0YWNrc1tzdGFja0tleV0gPSB7fSk7XG4gIHJldHVybiBzdWJTdGFja1tpbmRleFZhbHVlXSB8fCAoc3ViU3RhY2tbaW5kZXhWYWx1ZV0gPSB7fSk7XG59XG5cbmZ1bmN0aW9uIGdldExhc3RJbmRleEluU3RhY2soc3RhY2ssIHZTY2FsZSwgcG9zaXRpdmUsIHR5cGUpIHtcbiAgZm9yIChjb25zdCBtZXRhIG9mIHZTY2FsZS5nZXRNYXRjaGluZ1Zpc2libGVNZXRhcyh0eXBlKS5yZXZlcnNlKCkpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHN0YWNrW21ldGEuaW5kZXhdO1xuICAgIGlmICgocG9zaXRpdmUgJiYgdmFsdWUgPiAwKSB8fCAoIXBvc2l0aXZlICYmIHZhbHVlIDwgMCkpIHtcbiAgICAgIHJldHVybiBtZXRhLmluZGV4O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTdGFja3MoY29udHJvbGxlciwgcGFyc2VkKSB7XG4gIGNvbnN0IHtjaGFydCwgX2NhY2hlZE1ldGE6IG1ldGF9ID0gY29udHJvbGxlcjtcbiAgY29uc3Qgc3RhY2tzID0gY2hhcnQuX3N0YWNrcyB8fCAoY2hhcnQuX3N0YWNrcyA9IHt9KTsgLy8gbWFwIHN0cnVjdHVyZSBpcyB7c3RhY2tLZXk6IHtkYXRhc2V0SW5kZXg6IHZhbHVlfX1cbiAgY29uc3Qge2lTY2FsZSwgdlNjYWxlLCBpbmRleDogZGF0YXNldEluZGV4fSA9IG1ldGE7XG4gIGNvbnN0IGlBeGlzID0gaVNjYWxlLmF4aXM7XG4gIGNvbnN0IHZBeGlzID0gdlNjYWxlLmF4aXM7XG4gIGNvbnN0IGtleSA9IGdldFN0YWNrS2V5KGlTY2FsZSwgdlNjYWxlLCBtZXRhKTtcbiAgY29uc3QgaWxlbiA9IHBhcnNlZC5sZW5ndGg7XG4gIGxldCBzdGFjaztcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGlsZW47ICsraSkge1xuICAgIGNvbnN0IGl0ZW0gPSBwYXJzZWRbaV07XG4gICAgY29uc3Qge1tpQXhpc106IGluZGV4LCBbdkF4aXNdOiB2YWx1ZX0gPSBpdGVtO1xuICAgIGNvbnN0IGl0ZW1TdGFja3MgPSBpdGVtLl9zdGFja3MgfHwgKGl0ZW0uX3N0YWNrcyA9IHt9KTtcbiAgICBzdGFjayA9IGl0ZW1TdGFja3NbdkF4aXNdID0gZ2V0T3JDcmVhdGVTdGFjayhzdGFja3MsIGtleSwgaW5kZXgpO1xuICAgIHN0YWNrW2RhdGFzZXRJbmRleF0gPSB2YWx1ZTtcblxuICAgIHN0YWNrLl90b3AgPSBnZXRMYXN0SW5kZXhJblN0YWNrKHN0YWNrLCB2U2NhbGUsIHRydWUsIG1ldGEudHlwZSk7XG4gICAgc3RhY2suX2JvdHRvbSA9IGdldExhc3RJbmRleEluU3RhY2soc3RhY2ssIHZTY2FsZSwgZmFsc2UsIG1ldGEudHlwZSk7XG5cbiAgICBjb25zdCB2aXN1YWxWYWx1ZXMgPSBzdGFjay5fdmlzdWFsVmFsdWVzIHx8IChzdGFjay5fdmlzdWFsVmFsdWVzID0ge30pO1xuICAgIHZpc3VhbFZhbHVlc1tkYXRhc2V0SW5kZXhdID0gdmFsdWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0Rmlyc3RTY2FsZUlkKGNoYXJ0LCBheGlzKSB7XG4gIGNvbnN0IHNjYWxlcyA9IGNoYXJ0LnNjYWxlcztcbiAgcmV0dXJuIE9iamVjdC5rZXlzKHNjYWxlcykuZmlsdGVyKGtleSA9PiBzY2FsZXNba2V5XS5heGlzID09PSBheGlzKS5zaGlmdCgpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVEYXRhc2V0Q29udGV4dChwYXJlbnQsIGluZGV4KSB7XG4gIHJldHVybiBjcmVhdGVDb250ZXh0KHBhcmVudCxcbiAgICB7XG4gICAgICBhY3RpdmU6IGZhbHNlLFxuICAgICAgZGF0YXNldDogdW5kZWZpbmVkLFxuICAgICAgZGF0YXNldEluZGV4OiBpbmRleCxcbiAgICAgIGluZGV4LFxuICAgICAgbW9kZTogJ2RlZmF1bHQnLFxuICAgICAgdHlwZTogJ2RhdGFzZXQnXG4gICAgfVxuICApO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVEYXRhQ29udGV4dChwYXJlbnQsIGluZGV4LCBlbGVtZW50KSB7XG4gIHJldHVybiBjcmVhdGVDb250ZXh0KHBhcmVudCwge1xuICAgIGFjdGl2ZTogZmFsc2UsXG4gICAgZGF0YUluZGV4OiBpbmRleCxcbiAgICBwYXJzZWQ6IHVuZGVmaW5lZCxcbiAgICByYXc6IHVuZGVmaW5lZCxcbiAgICBlbGVtZW50LFxuICAgIGluZGV4LFxuICAgIG1vZGU6ICdkZWZhdWx0JyxcbiAgICB0eXBlOiAnZGF0YSdcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNsZWFyU3RhY2tzKG1ldGEsIGl0ZW1zKSB7XG4gIC8vIE5vdCB1c2luZyBtZXRhLmluZGV4IGhlcmUsIGJlY2F1c2UgaXQgbWlnaHQgYmUgYWxyZWFkeSB1cGRhdGVkIGlmIHRoZSBkYXRhc2V0IGNoYW5nZWQgbG9jYXRpb25cbiAgY29uc3QgZGF0YXNldEluZGV4ID0gbWV0YS5jb250cm9sbGVyLmluZGV4O1xuICBjb25zdCBheGlzID0gbWV0YS52U2NhbGUgJiYgbWV0YS52U2NhbGUuYXhpcztcbiAgaWYgKCFheGlzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaXRlbXMgPSBpdGVtcyB8fCBtZXRhLl9wYXJzZWQ7XG4gIGZvciAoY29uc3QgcGFyc2VkIG9mIGl0ZW1zKSB7XG4gICAgY29uc3Qgc3RhY2tzID0gcGFyc2VkLl9zdGFja3M7XG4gICAgaWYgKCFzdGFja3MgfHwgc3RhY2tzW2F4aXNdID09PSB1bmRlZmluZWQgfHwgc3RhY2tzW2F4aXNdW2RhdGFzZXRJbmRleF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkZWxldGUgc3RhY2tzW2F4aXNdW2RhdGFzZXRJbmRleF07XG4gICAgaWYgKHN0YWNrc1theGlzXS5fdmlzdWFsVmFsdWVzICE9PSB1bmRlZmluZWQgJiYgc3RhY2tzW2F4aXNdLl92aXN1YWxWYWx1ZXNbZGF0YXNldEluZGV4XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBkZWxldGUgc3RhY2tzW2F4aXNdLl92aXN1YWxWYWx1ZXNbZGF0YXNldEluZGV4XTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgaXNEaXJlY3RVcGRhdGVNb2RlID0gKG1vZGUpID0+IG1vZGUgPT09ICdyZXNldCcgfHwgbW9kZSA9PT0gJ25vbmUnO1xuY29uc3QgY2xvbmVJZk5vdFNoYXJlZCA9IChjYWNoZWQsIHNoYXJlZCkgPT4gc2hhcmVkID8gY2FjaGVkIDogT2JqZWN0LmFzc2lnbih7fSwgY2FjaGVkKTtcbmNvbnN0IGNyZWF0ZVN0YWNrID0gKGNhblN0YWNrLCBtZXRhLCBjaGFydCkgPT4gY2FuU3RhY2sgJiYgIW1ldGEuaGlkZGVuICYmIG1ldGEuX3N0YWNrZWRcbiAgJiYge2tleXM6IGdldFNvcnRlZERhdGFzZXRJbmRpY2VzKGNoYXJ0LCB0cnVlKSwgdmFsdWVzOiBudWxsfTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGF0YXNldENvbnRyb2xsZXIge1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge307XG5cbiAgLyoqXG4gICAqIEVsZW1lbnQgdHlwZSB1c2VkIHRvIGdlbmVyYXRlIGEgbWV0YSBkYXRhc2V0IChlLmcuIENoYXJ0LmVsZW1lbnQuTGluZUVsZW1lbnQpLlxuICAgKi9cbiAgc3RhdGljIGRhdGFzZXRFbGVtZW50VHlwZSA9IG51bGw7XG5cbiAgLyoqXG4gICAqIEVsZW1lbnQgdHlwZSB1c2VkIHRvIGdlbmVyYXRlIGEgbWV0YSBkYXRhIChlLmcuIENoYXJ0LmVsZW1lbnQuUG9pbnRFbGVtZW50KS5cbiAgICovXG4gIHN0YXRpYyBkYXRhRWxlbWVudFR5cGUgPSBudWxsO1xuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydFxuXHQgKiBAcGFyYW0ge251bWJlcn0gZGF0YXNldEluZGV4XG5cdCAqL1xuICBjb25zdHJ1Y3RvcihjaGFydCwgZGF0YXNldEluZGV4KSB7XG4gICAgdGhpcy5jaGFydCA9IGNoYXJ0O1xuICAgIHRoaXMuX2N0eCA9IGNoYXJ0LmN0eDtcbiAgICB0aGlzLmluZGV4ID0gZGF0YXNldEluZGV4O1xuICAgIHRoaXMuX2NhY2hlZERhdGFPcHRzID0ge307XG4gICAgdGhpcy5fY2FjaGVkTWV0YSA9IHRoaXMuZ2V0TWV0YSgpO1xuICAgIHRoaXMuX3R5cGUgPSB0aGlzLl9jYWNoZWRNZXRhLnR5cGU7XG4gICAgdGhpcy5vcHRpb25zID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7Ym9vbGVhbiB8IG9iamVjdH0gKi9cbiAgICB0aGlzLl9wYXJzaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fZGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9vYmplY3REYXRhID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3NoYXJlZE9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fZHJhd1N0YXJ0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2RyYXdDb3VudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmVuYWJsZU9wdGlvblNoYXJpbmcgPSBmYWxzZTtcbiAgICB0aGlzLnN1cHBvcnRzRGVjaW1hdGlvbiA9IGZhbHNlO1xuICAgIHRoaXMuJGNvbnRleHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fc3luY0xpc3QgPSBbXTtcbiAgICB0aGlzLmRhdGFzZXRFbGVtZW50VHlwZSA9IG5ldy50YXJnZXQuZGF0YXNldEVsZW1lbnRUeXBlO1xuICAgIHRoaXMuZGF0YUVsZW1lbnRUeXBlID0gbmV3LnRhcmdldC5kYXRhRWxlbWVudFR5cGU7XG5cbiAgICB0aGlzLmluaXRpYWxpemUoKTtcbiAgfVxuXG4gIGluaXRpYWxpemUoKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgdGhpcy5jb25maWd1cmUoKTtcbiAgICB0aGlzLmxpbmtTY2FsZXMoKTtcbiAgICBtZXRhLl9zdGFja2VkID0gaXNTdGFja2VkKG1ldGEudlNjYWxlLCBtZXRhKTtcbiAgICB0aGlzLmFkZEVsZW1lbnRzKCk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmZpbGwgJiYgIXRoaXMuY2hhcnQuaXNQbHVnaW5FbmFibGVkKCdmaWxsZXInKSkge1xuICAgICAgY29uc29sZS53YXJuKFwiVHJpZWQgdG8gdXNlIHRoZSAnZmlsbCcgb3B0aW9uIHdpdGhvdXQgdGhlICdGaWxsZXInIHBsdWdpbiBlbmFibGVkLiBQbGVhc2UgaW1wb3J0IGFuZCByZWdpc3RlciB0aGUgJ0ZpbGxlcicgcGx1Z2luIGFuZCBtYWtlIHN1cmUgaXQgaXMgbm90IGRpc2FibGVkIGluIHRoZSBvcHRpb25zXCIpO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUluZGV4KGRhdGFzZXRJbmRleCkge1xuICAgIGlmICh0aGlzLmluZGV4ICE9PSBkYXRhc2V0SW5kZXgpIHtcbiAgICAgIGNsZWFyU3RhY2tzKHRoaXMuX2NhY2hlZE1ldGEpO1xuICAgIH1cbiAgICB0aGlzLmluZGV4ID0gZGF0YXNldEluZGV4O1xuICB9XG5cbiAgbGlua1NjYWxlcygpIHtcbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgZGF0YXNldCA9IHRoaXMuZ2V0RGF0YXNldCgpO1xuXG4gICAgY29uc3QgY2hvb3NlSWQgPSAoYXhpcywgeCwgeSwgcikgPT4gYXhpcyA9PT0gJ3gnID8geCA6IGF4aXMgPT09ICdyJyA/IHIgOiB5O1xuXG4gICAgY29uc3QgeGlkID0gbWV0YS54QXhpc0lEID0gdmFsdWVPckRlZmF1bHQoZGF0YXNldC54QXhpc0lELCBnZXRGaXJzdFNjYWxlSWQoY2hhcnQsICd4JykpO1xuICAgIGNvbnN0IHlpZCA9IG1ldGEueUF4aXNJRCA9IHZhbHVlT3JEZWZhdWx0KGRhdGFzZXQueUF4aXNJRCwgZ2V0Rmlyc3RTY2FsZUlkKGNoYXJ0LCAneScpKTtcbiAgICBjb25zdCByaWQgPSBtZXRhLnJBeGlzSUQgPSB2YWx1ZU9yRGVmYXVsdChkYXRhc2V0LnJBeGlzSUQsIGdldEZpcnN0U2NhbGVJZChjaGFydCwgJ3InKSk7XG4gICAgY29uc3QgaW5kZXhBeGlzID0gbWV0YS5pbmRleEF4aXM7XG4gICAgY29uc3QgaWlkID0gbWV0YS5pQXhpc0lEID0gY2hvb3NlSWQoaW5kZXhBeGlzLCB4aWQsIHlpZCwgcmlkKTtcbiAgICBjb25zdCB2aWQgPSBtZXRhLnZBeGlzSUQgPSBjaG9vc2VJZChpbmRleEF4aXMsIHlpZCwgeGlkLCByaWQpO1xuICAgIG1ldGEueFNjYWxlID0gdGhpcy5nZXRTY2FsZUZvcklkKHhpZCk7XG4gICAgbWV0YS55U2NhbGUgPSB0aGlzLmdldFNjYWxlRm9ySWQoeWlkKTtcbiAgICBtZXRhLnJTY2FsZSA9IHRoaXMuZ2V0U2NhbGVGb3JJZChyaWQpO1xuICAgIG1ldGEuaVNjYWxlID0gdGhpcy5nZXRTY2FsZUZvcklkKGlpZCk7XG4gICAgbWV0YS52U2NhbGUgPSB0aGlzLmdldFNjYWxlRm9ySWQodmlkKTtcbiAgfVxuXG4gIGdldERhdGFzZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hhcnQuZGF0YS5kYXRhc2V0c1t0aGlzLmluZGV4XTtcbiAgfVxuXG4gIGdldE1ldGEoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hhcnQuZ2V0RGF0YXNldE1ldGEodGhpcy5pbmRleCk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IHNjYWxlSURcblx0ICogQHJldHVybiB7U2NhbGV9XG5cdCAqL1xuICBnZXRTY2FsZUZvcklkKHNjYWxlSUQpIHtcbiAgICByZXR1cm4gdGhpcy5jaGFydC5zY2FsZXNbc2NhbGVJRF07XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRPdGhlclNjYWxlKHNjYWxlKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgcmV0dXJuIHNjYWxlID09PSBtZXRhLmlTY2FsZVxuICAgICAgPyBtZXRhLnZTY2FsZVxuICAgICAgOiBtZXRhLmlTY2FsZTtcbiAgfVxuXG4gIHJlc2V0KCkge1xuICAgIHRoaXMuX3VwZGF0ZSgncmVzZXQnKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2Rlc3Ryb3koKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgaWYgKHRoaXMuX2RhdGEpIHtcbiAgICAgIHVubGlzdGVuQXJyYXlFdmVudHModGhpcy5fZGF0YSwgdGhpcyk7XG4gICAgfVxuICAgIGlmIChtZXRhLl9zdGFja2VkKSB7XG4gICAgICBjbGVhclN0YWNrcyhtZXRhKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9kYXRhQ2hlY2soKSB7XG4gICAgY29uc3QgZGF0YXNldCA9IHRoaXMuZ2V0RGF0YXNldCgpO1xuICAgIGNvbnN0IGRhdGEgPSBkYXRhc2V0LmRhdGEgfHwgKGRhdGFzZXQuZGF0YSA9IFtdKTtcbiAgICBjb25zdCBfZGF0YSA9IHRoaXMuX2RhdGE7XG5cbiAgICAvLyBJbiBvcmRlciB0byBjb3JyZWN0bHkgaGFuZGxlIGRhdGEgYWRkaXRpb24vZGVsZXRpb24gYW5pbWF0aW9uIChhbmQgdGh1cyBzaW11bGF0ZVxuICAgIC8vIHJlYWwtdGltZSBjaGFydHMpLCB3ZSBuZWVkIHRvIG1vbml0b3IgdGhlc2UgZGF0YSBtb2RpZmljYXRpb25zIGFuZCBzeW5jaHJvbml6ZVxuICAgIC8vIHRoZSBpbnRlcm5hbCBtZXRhZGF0YSBhY2NvcmRpbmdseS5cblxuICAgIGlmIChpc09iamVjdChkYXRhKSkge1xuICAgICAgdGhpcy5fZGF0YSA9IGNvbnZlcnRPYmplY3REYXRhVG9BcnJheShkYXRhKTtcbiAgICB9IGVsc2UgaWYgKF9kYXRhICE9PSBkYXRhKSB7XG4gICAgICBpZiAoX2RhdGEpIHtcbiAgICAgICAgLy8gVGhpcyBjYXNlIGhhcHBlbnMgd2hlbiB0aGUgdXNlciByZXBsYWNlZCB0aGUgZGF0YSBhcnJheSBpbnN0YW5jZS5cbiAgICAgICAgdW5saXN0ZW5BcnJheUV2ZW50cyhfZGF0YSwgdGhpcyk7XG4gICAgICAgIC8vIERpc2NhcmQgb2xkIHBhcnNlZCBkYXRhIGFuZCBzdGFja3NcbiAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgICAgIGNsZWFyU3RhY2tzKG1ldGEpO1xuICAgICAgICBtZXRhLl9wYXJzZWQgPSBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhICYmIE9iamVjdC5pc0V4dGVuc2libGUoZGF0YSkpIHtcbiAgICAgICAgbGlzdGVuQXJyYXlFdmVudHMoZGF0YSwgdGhpcyk7XG4gICAgICB9XG4gICAgICB0aGlzLl9zeW5jTGlzdCA9IFtdO1xuICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gICAgfVxuICB9XG5cbiAgYWRkRWxlbWVudHMoKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG5cbiAgICB0aGlzLl9kYXRhQ2hlY2soKTtcblxuICAgIGlmICh0aGlzLmRhdGFzZXRFbGVtZW50VHlwZSkge1xuICAgICAgbWV0YS5kYXRhc2V0ID0gbmV3IHRoaXMuZGF0YXNldEVsZW1lbnRUeXBlKCk7XG4gICAgfVxuICB9XG5cbiAgYnVpbGRPclVwZGF0ZUVsZW1lbnRzKHJlc2V0TmV3RWxlbWVudHMpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBkYXRhc2V0ID0gdGhpcy5nZXREYXRhc2V0KCk7XG4gICAgbGV0IHN0YWNrQ2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5fZGF0YUNoZWNrKCk7XG5cbiAgICAvLyBtYWtlIHN1cmUgY2FjaGVkIF9zdGFja2VkIHN0YXR1cyBpcyBjdXJyZW50XG4gICAgY29uc3Qgb2xkU3RhY2tlZCA9IG1ldGEuX3N0YWNrZWQ7XG4gICAgbWV0YS5fc3RhY2tlZCA9IGlzU3RhY2tlZChtZXRhLnZTY2FsZSwgbWV0YSk7XG5cbiAgICAvLyBkZXRlY3QgY2hhbmdlIGluIHN0YWNrIG9wdGlvblxuICAgIGlmIChtZXRhLnN0YWNrICE9PSBkYXRhc2V0LnN0YWNrKSB7XG4gICAgICBzdGFja0NoYW5nZWQgPSB0cnVlO1xuICAgICAgLy8gcmVtb3ZlIHZhbHVlcyBmcm9tIG9sZCBzdGFja1xuICAgICAgY2xlYXJTdGFja3MobWV0YSk7XG4gICAgICBtZXRhLnN0YWNrID0gZGF0YXNldC5zdGFjaztcbiAgICB9XG5cbiAgICAvLyBSZS1zeW5jIG1ldGEgZGF0YSBpbiBjYXNlIHRoZSB1c2VyIHJlcGxhY2VkIHRoZSBkYXRhIGFycmF5IG9yIGlmIHdlIG1pc3NlZFxuICAgIC8vIGFueSB1cGRhdGVzIGFuZCBzbyBtYWtlIHN1cmUgdGhhdCB3ZSBoYW5kbGUgbnVtYmVyIG9mIGRhdGFwb2ludHMgY2hhbmdpbmcuXG4gICAgdGhpcy5fcmVzeW5jRWxlbWVudHMocmVzZXROZXdFbGVtZW50cyk7XG5cbiAgICAvLyBpZiBzdGFjayBjaGFuZ2VkLCB1cGRhdGUgc3RhY2sgdmFsdWVzIGZvciB0aGUgd2hvbGUgZGF0YXNldFxuICAgIGlmIChzdGFja0NoYW5nZWQgfHwgb2xkU3RhY2tlZCAhPT0gbWV0YS5fc3RhY2tlZCkge1xuICAgICAgdXBkYXRlU3RhY2tzKHRoaXMsIG1ldGEuX3BhcnNlZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIE1lcmdlcyB1c2VyLXN1cHBsaWVkIGFuZCBkZWZhdWx0IGRhdGFzZXQtbGV2ZWwgb3B0aW9uc1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgY29uZmlndXJlKCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY2hhcnQuY29uZmlnO1xuICAgIGNvbnN0IHNjb3BlS2V5cyA9IGNvbmZpZy5kYXRhc2V0U2NvcGVLZXlzKHRoaXMuX3R5cGUpO1xuICAgIGNvbnN0IHNjb3BlcyA9IGNvbmZpZy5nZXRPcHRpb25TY29wZXModGhpcy5nZXREYXRhc2V0KCksIHNjb3BlS2V5cywgdHJ1ZSk7XG4gICAgdGhpcy5vcHRpb25zID0gY29uZmlnLmNyZWF0ZVJlc29sdmVyKHNjb3BlcywgdGhpcy5nZXRDb250ZXh0KCkpO1xuICAgIHRoaXMuX3BhcnNpbmcgPSB0aGlzLm9wdGlvbnMucGFyc2luZztcbiAgICB0aGlzLl9jYWNoZWREYXRhT3B0cyA9IHt9O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydFxuXHQgKiBAcGFyYW0ge251bWJlcn0gY291bnRcblx0ICovXG4gIHBhcnNlKHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IHtfY2FjaGVkTWV0YTogbWV0YSwgX2RhdGE6IGRhdGF9ID0gdGhpcztcbiAgICBjb25zdCB7aVNjYWxlLCBfc3RhY2tlZH0gPSBtZXRhO1xuICAgIGNvbnN0IGlBeGlzID0gaVNjYWxlLmF4aXM7XG5cbiAgICBsZXQgc29ydGVkID0gc3RhcnQgPT09IDAgJiYgY291bnQgPT09IGRhdGEubGVuZ3RoID8gdHJ1ZSA6IG1ldGEuX3NvcnRlZDtcbiAgICBsZXQgcHJldiA9IHN0YXJ0ID4gMCAmJiBtZXRhLl9wYXJzZWRbc3RhcnQgLSAxXTtcbiAgICBsZXQgaSwgY3VyLCBwYXJzZWQ7XG5cbiAgICBpZiAodGhpcy5fcGFyc2luZyA9PT0gZmFsc2UpIHtcbiAgICAgIG1ldGEuX3BhcnNlZCA9IGRhdGE7XG4gICAgICBtZXRhLl9zb3J0ZWQgPSB0cnVlO1xuICAgICAgcGFyc2VkID0gZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzQXJyYXkoZGF0YVtzdGFydF0pKSB7XG4gICAgICAgIHBhcnNlZCA9IHRoaXMucGFyc2VBcnJheURhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KTtcbiAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QoZGF0YVtzdGFydF0pKSB7XG4gICAgICAgIHBhcnNlZCA9IHRoaXMucGFyc2VPYmplY3REYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJzZWQgPSB0aGlzLnBhcnNlUHJpbWl0aXZlRGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpc05vdEluT3JkZXJDb21wYXJlZFRvUHJldiA9ICgpID0+IGN1cltpQXhpc10gPT09IG51bGwgfHwgKHByZXYgJiYgY3VyW2lBeGlzXSA8IHByZXZbaUF4aXNdKTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7XG4gICAgICAgIG1ldGEuX3BhcnNlZFtpICsgc3RhcnRdID0gY3VyID0gcGFyc2VkW2ldO1xuICAgICAgICBpZiAoc29ydGVkKSB7XG4gICAgICAgICAgaWYgKGlzTm90SW5PcmRlckNvbXBhcmVkVG9QcmV2KCkpIHtcbiAgICAgICAgICAgIHNvcnRlZCA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwcmV2ID0gY3VyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBtZXRhLl9zb3J0ZWQgPSBzb3J0ZWQ7XG4gICAgfVxuXG4gICAgaWYgKF9zdGFja2VkKSB7XG4gICAgICB1cGRhdGVTdGFja3ModGhpcywgcGFyc2VkKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogUGFyc2UgYXJyYXkgb2YgcHJpbWl0aXZlIHZhbHVlc1xuXHQgKiBAcGFyYW0ge29iamVjdH0gbWV0YSAtIGRhdGFzZXQgbWV0YVxuXHQgKiBAcGFyYW0ge2FycmF5fSBkYXRhIC0gZGF0YSBhcnJheS4gRXhhbXBsZSBbMSwzLDRdXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCAtIHN0YXJ0IGluZGV4XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBjb3VudCAtIG51bWJlciBvZiBpdGVtcyB0byBwYXJzZVxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fSBwYXJzZWQgaXRlbSAtIGl0ZW0gY29udGFpbmluZyBpbmRleCBhbmQgYSBwYXJzZWQgdmFsdWVcblx0ICogZm9yIGVhY2ggc2NhbGUgaWQuXG5cdCAqIEV4YW1wbGU6IHt4U2NhbGUwOiAwLCB5U2NhbGUwOiAxfVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBwYXJzZVByaW1pdGl2ZURhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgY29uc3Qge2lTY2FsZSwgdlNjYWxlfSA9IG1ldGE7XG4gICAgY29uc3QgaUF4aXMgPSBpU2NhbGUuYXhpcztcbiAgICBjb25zdCB2QXhpcyA9IHZTY2FsZS5heGlzO1xuICAgIGNvbnN0IGxhYmVscyA9IGlTY2FsZS5nZXRMYWJlbHMoKTtcbiAgICBjb25zdCBzaW5nbGVTY2FsZSA9IGlTY2FsZSA9PT0gdlNjYWxlO1xuICAgIGNvbnN0IHBhcnNlZCA9IG5ldyBBcnJheShjb3VudCk7XG4gICAgbGV0IGksIGlsZW4sIGluZGV4O1xuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IGNvdW50OyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBpbmRleCA9IGkgKyBzdGFydDtcbiAgICAgIHBhcnNlZFtpXSA9IHtcbiAgICAgICAgW2lBeGlzXTogc2luZ2xlU2NhbGUgfHwgaVNjYWxlLnBhcnNlKGxhYmVsc1tpbmRleF0sIGluZGV4KSxcbiAgICAgICAgW3ZBeGlzXTogdlNjYWxlLnBhcnNlKGRhdGFbaW5kZXhdLCBpbmRleClcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICAvKipcblx0ICogUGFyc2UgYXJyYXkgb2YgYXJyYXlzXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBtZXRhIC0gZGF0YXNldCBtZXRhXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGRhdGEgLSBkYXRhIGFycmF5LiBFeGFtcGxlIFtbMSwyXSxbMyw0XV1cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IC0gc3RhcnQgaW5kZXhcblx0ICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IC0gbnVtYmVyIG9mIGl0ZW1zIHRvIHBhcnNlXG5cdCAqIEByZXR1cm5zIHtvYmplY3R9IHBhcnNlZCBpdGVtIC0gaXRlbSBjb250YWluaW5nIGluZGV4IGFuZCBhIHBhcnNlZCB2YWx1ZVxuXHQgKiBmb3IgZWFjaCBzY2FsZSBpZC5cblx0ICogRXhhbXBsZToge3g6IDAsIHk6IDF9XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHBhcnNlQXJyYXlEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IHt4U2NhbGUsIHlTY2FsZX0gPSBtZXRhO1xuICAgIGNvbnN0IHBhcnNlZCA9IG5ldyBBcnJheShjb3VudCk7XG4gICAgbGV0IGksIGlsZW4sIGluZGV4LCBpdGVtO1xuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IGNvdW50OyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBpbmRleCA9IGkgKyBzdGFydDtcbiAgICAgIGl0ZW0gPSBkYXRhW2luZGV4XTtcbiAgICAgIHBhcnNlZFtpXSA9IHtcbiAgICAgICAgeDogeFNjYWxlLnBhcnNlKGl0ZW1bMF0sIGluZGV4KSxcbiAgICAgICAgeTogeVNjYWxlLnBhcnNlKGl0ZW1bMV0sIGluZGV4KVxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlZDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBQYXJzZSBhcnJheSBvZiBvYmplY3RzXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBtZXRhIC0gZGF0YXNldCBtZXRhXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGRhdGEgLSBkYXRhIGFycmF5LiBFeGFtcGxlIFt7eDoxLCB5OjV9LCB7eDoyLCB5OjEwfV1cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IC0gc3RhcnQgaW5kZXhcblx0ICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IC0gbnVtYmVyIG9mIGl0ZW1zIHRvIHBhcnNlXG5cdCAqIEByZXR1cm5zIHtvYmplY3R9IHBhcnNlZCBpdGVtIC0gaXRlbSBjb250YWluaW5nIGluZGV4IGFuZCBhIHBhcnNlZCB2YWx1ZVxuXHQgKiBmb3IgZWFjaCBzY2FsZSBpZC4gX2N1c3RvbSBpcyBvcHRpb25hbFxuXHQgKiBFeGFtcGxlOiB7eFNjYWxlMDogMCwgeVNjYWxlMDogMSwgX2N1c3RvbToge3I6IDEwLCBmb286ICdiYXInfX1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgcGFyc2VPYmplY3REYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IHt4U2NhbGUsIHlTY2FsZX0gPSBtZXRhO1xuICAgIGNvbnN0IHt4QXhpc0tleSA9ICd4JywgeUF4aXNLZXkgPSAneSd9ID0gdGhpcy5fcGFyc2luZztcbiAgICBjb25zdCBwYXJzZWQgPSBuZXcgQXJyYXkoY291bnQpO1xuICAgIGxldCBpLCBpbGVuLCBpbmRleCwgaXRlbTtcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBjb3VudDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgaW5kZXggPSBpICsgc3RhcnQ7XG4gICAgICBpdGVtID0gZGF0YVtpbmRleF07XG4gICAgICBwYXJzZWRbaV0gPSB7XG4gICAgICAgIHg6IHhTY2FsZS5wYXJzZShyZXNvbHZlT2JqZWN0S2V5KGl0ZW0sIHhBeGlzS2V5KSwgaW5kZXgpLFxuICAgICAgICB5OiB5U2NhbGUucGFyc2UocmVzb2x2ZU9iamVjdEtleShpdGVtLCB5QXhpc0tleSksIGluZGV4KVxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlZDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRQYXJzZWQoaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpcy5fY2FjaGVkTWV0YS5fcGFyc2VkW2luZGV4XTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXREYXRhRWxlbWVudChpbmRleCkge1xuICAgIHJldHVybiB0aGlzLl9jYWNoZWRNZXRhLmRhdGFbaW5kZXhdO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGFwcGx5U3RhY2soc2NhbGUsIHBhcnNlZCwgbW9kZSkge1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCB2YWx1ZSA9IHBhcnNlZFtzY2FsZS5heGlzXTtcbiAgICBjb25zdCBzdGFjayA9IHtcbiAgICAgIGtleXM6IGdldFNvcnRlZERhdGFzZXRJbmRpY2VzKGNoYXJ0LCB0cnVlKSxcbiAgICAgIHZhbHVlczogcGFyc2VkLl9zdGFja3Nbc2NhbGUuYXhpc10uX3Zpc3VhbFZhbHVlc1xuICAgIH07XG4gICAgcmV0dXJuIGFwcGx5U3RhY2soc3RhY2ssIHZhbHVlLCBtZXRhLmluZGV4LCB7bW9kZX0pO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHVwZGF0ZVJhbmdlRnJvbVBhcnNlZChyYW5nZSwgc2NhbGUsIHBhcnNlZCwgc3RhY2spIHtcbiAgICBjb25zdCBwYXJzZWRWYWx1ZSA9IHBhcnNlZFtzY2FsZS5heGlzXTtcbiAgICBsZXQgdmFsdWUgPSBwYXJzZWRWYWx1ZSA9PT0gbnVsbCA/IE5hTiA6IHBhcnNlZFZhbHVlO1xuICAgIGNvbnN0IHZhbHVlcyA9IHN0YWNrICYmIHBhcnNlZC5fc3RhY2tzW3NjYWxlLmF4aXNdO1xuICAgIGlmIChzdGFjayAmJiB2YWx1ZXMpIHtcbiAgICAgIHN0YWNrLnZhbHVlcyA9IHZhbHVlcztcbiAgICAgIHZhbHVlID0gYXBwbHlTdGFjayhzdGFjaywgcGFyc2VkVmFsdWUsIHRoaXMuX2NhY2hlZE1ldGEuaW5kZXgpO1xuICAgIH1cbiAgICByYW5nZS5taW4gPSBNYXRoLm1pbihyYW5nZS5taW4sIHZhbHVlKTtcbiAgICByYW5nZS5tYXggPSBNYXRoLm1heChyYW5nZS5tYXgsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRNaW5NYXgoc2NhbGUsIGNhblN0YWNrKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgX3BhcnNlZCA9IG1ldGEuX3BhcnNlZDtcbiAgICBjb25zdCBzb3J0ZWQgPSBtZXRhLl9zb3J0ZWQgJiYgc2NhbGUgPT09IG1ldGEuaVNjYWxlO1xuICAgIGNvbnN0IGlsZW4gPSBfcGFyc2VkLmxlbmd0aDtcbiAgICBjb25zdCBvdGhlclNjYWxlID0gdGhpcy5fZ2V0T3RoZXJTY2FsZShzY2FsZSk7XG4gICAgY29uc3Qgc3RhY2sgPSBjcmVhdGVTdGFjayhjYW5TdGFjaywgbWV0YSwgdGhpcy5jaGFydCk7XG4gICAgY29uc3QgcmFuZ2UgPSB7bWluOiBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksIG1heDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZfTtcbiAgICBjb25zdCB7bWluOiBvdGhlck1pbiwgbWF4OiBvdGhlck1heH0gPSBnZXRVc2VyQm91bmRzKG90aGVyU2NhbGUpO1xuICAgIGxldCBpLCBwYXJzZWQ7XG5cbiAgICBmdW5jdGlvbiBfc2tpcCgpIHtcbiAgICAgIHBhcnNlZCA9IF9wYXJzZWRbaV07XG4gICAgICBjb25zdCBvdGhlclZhbHVlID0gcGFyc2VkW290aGVyU2NhbGUuYXhpc107XG4gICAgICByZXR1cm4gIWlzRmluaXRlKHBhcnNlZFtzY2FsZS5heGlzXSkgfHwgb3RoZXJNaW4gPiBvdGhlclZhbHVlIHx8IG90aGVyTWF4IDwgb3RoZXJWYWx1ZTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBpZiAoX3NraXAoKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRoaXMudXBkYXRlUmFuZ2VGcm9tUGFyc2VkKHJhbmdlLCBzY2FsZSwgcGFyc2VkLCBzdGFjayk7XG4gICAgICBpZiAoc29ydGVkKSB7XG4gICAgICAgIC8vIGlmIHRoZSBkYXRhIGlzIHNvcnRlZCwgd2UgZG9uJ3QgbmVlZCB0byBjaGVjayBmdXJ0aGVyIGZyb20gdGhpcyBlbmQgb2YgYXJyYXlcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzb3J0ZWQpIHtcbiAgICAgIC8vIGluIHRoZSBzb3J0ZWQgY2FzZSwgZmluZCBmaXJzdCBub24tc2tpcHBlZCB2YWx1ZSBmcm9tIG90aGVyIGVuZCBvZiBhcnJheVxuICAgICAgZm9yIChpID0gaWxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIGlmIChfc2tpcCgpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVSYW5nZUZyb21QYXJzZWQocmFuZ2UsIHNjYWxlLCBwYXJzZWQsIHN0YWNrKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByYW5nZTtcbiAgfVxuXG4gIGdldEFsbFBhcnNlZFZhbHVlcyhzY2FsZSkge1xuICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuX2NhY2hlZE1ldGEuX3BhcnNlZDtcbiAgICBjb25zdCB2YWx1ZXMgPSBbXTtcbiAgICBsZXQgaSwgaWxlbiwgdmFsdWU7XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gcGFyc2VkLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgdmFsdWUgPSBwYXJzZWRbaV1bc2NhbGUuYXhpc107XG4gICAgICBpZiAoaXNGaW5pdGUodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcmV0dXJuIHtudW1iZXJ8Ym9vbGVhbn1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0TWF4T3ZlcmZsb3coKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldExhYmVsQW5kVmFsdWUoaW5kZXgpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBpU2NhbGUgPSBtZXRhLmlTY2FsZTtcbiAgICBjb25zdCB2U2NhbGUgPSBtZXRhLnZTY2FsZTtcbiAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxhYmVsOiBpU2NhbGUgPyAnJyArIGlTY2FsZS5nZXRMYWJlbEZvclZhbHVlKHBhcnNlZFtpU2NhbGUuYXhpc10pIDogJycsXG4gICAgICB2YWx1ZTogdlNjYWxlID8gJycgKyB2U2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWRbdlNjYWxlLmF4aXNdKSA6ICcnXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3VwZGF0ZShtb2RlKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgdGhpcy51cGRhdGUobW9kZSB8fCAnZGVmYXVsdCcpO1xuICAgIG1ldGEuX2NsaXAgPSB0b0NsaXAodmFsdWVPckRlZmF1bHQodGhpcy5vcHRpb25zLmNsaXAsIGRlZmF1bHRDbGlwKG1ldGEueFNjYWxlLCBtZXRhLnlTY2FsZSwgdGhpcy5nZXRNYXhPdmVyZmxvdygpKSkpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBtb2RlXG5cdCAqL1xuICB1cGRhdGUobW9kZSkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuXG4gIGRyYXcoKSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5fY3R4O1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBlbGVtZW50cyA9IG1ldGEuZGF0YSB8fCBbXTtcbiAgICBjb25zdCBhcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xuICAgIGNvbnN0IGFjdGl2ZSA9IFtdO1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5fZHJhd1N0YXJ0IHx8IDA7XG4gICAgY29uc3QgY291bnQgPSB0aGlzLl9kcmF3Q291bnQgfHwgKGVsZW1lbnRzLmxlbmd0aCAtIHN0YXJ0KTtcbiAgICBjb25zdCBkcmF3QWN0aXZlRWxlbWVudHNPblRvcCA9IHRoaXMub3B0aW9ucy5kcmF3QWN0aXZlRWxlbWVudHNPblRvcDtcbiAgICBsZXQgaTtcblxuICAgIGlmIChtZXRhLmRhdGFzZXQpIHtcbiAgICAgIG1ldGEuZGF0YXNldC5kcmF3KGN0eCwgYXJlYSwgc3RhcnQsIGNvdW50KTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IHN0YXJ0ICsgY291bnQ7ICsraSkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGVsZW1lbnRzW2ldO1xuICAgICAgaWYgKGVsZW1lbnQuaGlkZGVuKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGVsZW1lbnQuYWN0aXZlICYmIGRyYXdBY3RpdmVFbGVtZW50c09uVG9wKSB7XG4gICAgICAgIGFjdGl2ZS5wdXNoKGVsZW1lbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5kcmF3KGN0eCwgYXJlYSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IGFjdGl2ZS5sZW5ndGg7ICsraSkge1xuICAgICAgYWN0aXZlW2ldLmRyYXcoY3R4LCBhcmVhKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyBhIHNldCBvZiBwcmVkZWZpbmVkIHN0eWxlIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgYmUgdXNlZCB0byByZXByZXNlbnQgdGhlIGRhdGFzZXRcblx0ICogb3IgdGhlIGRhdGEgaWYgdGhlIGluZGV4IGlzIHNwZWNpZmllZFxuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBkYXRhIGluZGV4XG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FjdGl2ZV0gLSB0cnVlIGlmIGhvdmVyXG5cdCAqIEByZXR1cm4ge29iamVjdH0gc3R5bGUgb2JqZWN0XG5cdCAqL1xuICBnZXRTdHlsZShpbmRleCwgYWN0aXZlKSB7XG4gICAgY29uc3QgbW9kZSA9IGFjdGl2ZSA/ICdhY3RpdmUnIDogJ2RlZmF1bHQnO1xuICAgIHJldHVybiBpbmRleCA9PT0gdW5kZWZpbmVkICYmIHRoaXMuX2NhY2hlZE1ldGEuZGF0YXNldFxuICAgICAgPyB0aGlzLnJlc29sdmVEYXRhc2V0RWxlbWVudE9wdGlvbnMobW9kZSlcbiAgICAgIDogdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGluZGV4IHx8IDAsIG1vZGUpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldENvbnRleHQoaW5kZXgsIGFjdGl2ZSwgbW9kZSkge1xuICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLmdldERhdGFzZXQoKTtcbiAgICBsZXQgY29udGV4dDtcbiAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHRoaXMuX2NhY2hlZE1ldGEuZGF0YS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9jYWNoZWRNZXRhLmRhdGFbaW5kZXhdO1xuICAgICAgY29udGV4dCA9IGVsZW1lbnQuJGNvbnRleHQgfHxcbiAgICAgICAgKGVsZW1lbnQuJGNvbnRleHQgPSBjcmVhdGVEYXRhQ29udGV4dCh0aGlzLmdldENvbnRleHQoKSwgaW5kZXgsIGVsZW1lbnQpKTtcbiAgICAgIGNvbnRleHQucGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaW5kZXgpO1xuICAgICAgY29udGV4dC5yYXcgPSBkYXRhc2V0LmRhdGFbaW5kZXhdO1xuICAgICAgY29udGV4dC5pbmRleCA9IGNvbnRleHQuZGF0YUluZGV4ID0gaW5kZXg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRleHQgPSB0aGlzLiRjb250ZXh0IHx8XG4gICAgICAgICh0aGlzLiRjb250ZXh0ID0gY3JlYXRlRGF0YXNldENvbnRleHQodGhpcy5jaGFydC5nZXRDb250ZXh0KCksIHRoaXMuaW5kZXgpKTtcbiAgICAgIGNvbnRleHQuZGF0YXNldCA9IGRhdGFzZXQ7XG4gICAgICBjb250ZXh0LmluZGV4ID0gY29udGV4dC5kYXRhc2V0SW5kZXggPSB0aGlzLmluZGV4O1xuICAgIH1cblxuICAgIGNvbnRleHQuYWN0aXZlID0gISFhY3RpdmU7XG4gICAgY29udGV4dC5tb2RlID0gbW9kZTtcbiAgICByZXR1cm4gY29udGV4dDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gW21vZGVdXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHJlc29sdmVEYXRhc2V0RWxlbWVudE9wdGlvbnMobW9kZSkge1xuICAgIHJldHVybiB0aGlzLl9yZXNvbHZlRWxlbWVudE9wdGlvbnModGhpcy5kYXRhc2V0RWxlbWVudFR5cGUuaWQsIG1vZGUpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gW21vZGVdXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaW5kZXgsIG1vZGUpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZUVsZW1lbnRPcHRpb25zKHRoaXMuZGF0YUVsZW1lbnRUeXBlLmlkLCBtb2RlLCBpbmRleCk7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9yZXNvbHZlRWxlbWVudE9wdGlvbnMoZWxlbWVudFR5cGUsIG1vZGUgPSAnZGVmYXVsdCcsIGluZGV4KSB7XG4gICAgY29uc3QgYWN0aXZlID0gbW9kZSA9PT0gJ2FjdGl2ZSc7XG4gICAgY29uc3QgY2FjaGUgPSB0aGlzLl9jYWNoZWREYXRhT3B0cztcbiAgICBjb25zdCBjYWNoZUtleSA9IGVsZW1lbnRUeXBlICsgJy0nICsgbW9kZTtcbiAgICBjb25zdCBjYWNoZWQgPSBjYWNoZVtjYWNoZUtleV07XG4gICAgY29uc3Qgc2hhcmluZyA9IHRoaXMuZW5hYmxlT3B0aW9uU2hhcmluZyAmJiBkZWZpbmVkKGluZGV4KTtcbiAgICBpZiAoY2FjaGVkKSB7XG4gICAgICByZXR1cm4gY2xvbmVJZk5vdFNoYXJlZChjYWNoZWQsIHNoYXJpbmcpO1xuICAgIH1cbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNoYXJ0LmNvbmZpZztcbiAgICBjb25zdCBzY29wZUtleXMgPSBjb25maWcuZGF0YXNldEVsZW1lbnRTY29wZUtleXModGhpcy5fdHlwZSwgZWxlbWVudFR5cGUpO1xuICAgIGNvbnN0IHByZWZpeGVzID0gYWN0aXZlID8gW2Ake2VsZW1lbnRUeXBlfUhvdmVyYCwgJ2hvdmVyJywgZWxlbWVudFR5cGUsICcnXSA6IFtlbGVtZW50VHlwZSwgJyddO1xuICAgIGNvbnN0IHNjb3BlcyA9IGNvbmZpZy5nZXRPcHRpb25TY29wZXModGhpcy5nZXREYXRhc2V0KCksIHNjb3BlS2V5cyk7XG4gICAgY29uc3QgbmFtZXMgPSBPYmplY3Qua2V5cyhkZWZhdWx0cy5lbGVtZW50c1tlbGVtZW50VHlwZV0pO1xuICAgIC8vIGNvbnRleHQgaXMgcHJvdmlkZWQgYXMgYSBmdW5jdGlvbiwgYW5kIGlzIGNhbGxlZCBvbmx5IGlmIG5lZWRlZCxcbiAgICAvLyBzbyB3ZSBkb24ndCBjcmVhdGUgYSBjb250ZXh0IGZvciBlYWNoIGVsZW1lbnQgaWYgbm90IG5lZWRlZC5cbiAgICBjb25zdCBjb250ZXh0ID0gKCkgPT4gdGhpcy5nZXRDb250ZXh0KGluZGV4LCBhY3RpdmUsIG1vZGUpO1xuICAgIGNvbnN0IHZhbHVlcyA9IGNvbmZpZy5yZXNvbHZlTmFtZWRPcHRpb25zKHNjb3BlcywgbmFtZXMsIGNvbnRleHQsIHByZWZpeGVzKTtcblxuICAgIGlmICh2YWx1ZXMuJHNoYXJlZCkge1xuICAgICAgLy8gYCRzaGFyZWRgIGluZGljYXRlcyB0aGlzIHNldCBvZiBvcHRpb25zIGNhbiBiZSBzaGFyZWQgYmV0d2VlbiBtdWx0aXBsZSBlbGVtZW50cy5cbiAgICAgIC8vIFNoYXJpbmcgaXMgdXNlZCB0byByZWR1Y2UgbnVtYmVyIG9mIHByb3BlcnRpZXMgdG8gY2hhbmdlIGR1cmluZyBhbmltYXRpb24uXG4gICAgICB2YWx1ZXMuJHNoYXJlZCA9IHNoYXJpbmc7XG5cbiAgICAgIC8vIFdlIGNhY2hlIG9wdGlvbnMgYnkgYG1vZGVgLCB3aGljaCBjYW4gYmUgJ2FjdGl2ZScgZm9yIGV4YW1wbGUuIFRoaXMgZW5hYmxlcyB1c1xuICAgICAgLy8gdG8gaGF2ZSB0aGUgJ2FjdGl2ZScgZWxlbWVudCBvcHRpb25zIGFuZCAnZGVmYXVsdCcgb3B0aW9ucyB0byBzd2l0Y2ggYmV0d2VlblxuICAgICAgLy8gd2hlbiBpbnRlcmFjdGluZy5cbiAgICAgIGNhY2hlW2NhY2hlS2V5XSA9IE9iamVjdC5mcmVlemUoY2xvbmVJZk5vdFNoYXJlZCh2YWx1ZXMsIHNoYXJpbmcpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVzO1xuICB9XG5cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9yZXNvbHZlQW5pbWF0aW9ucyhpbmRleCwgdHJhbnNpdGlvbiwgYWN0aXZlKSB7XG4gICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgIGNvbnN0IGNhY2hlID0gdGhpcy5fY2FjaGVkRGF0YU9wdHM7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBgYW5pbWF0aW9uLSR7dHJhbnNpdGlvbn1gO1xuICAgIGNvbnN0IGNhY2hlZCA9IGNhY2hlW2NhY2hlS2V5XTtcbiAgICBpZiAoY2FjaGVkKSB7XG4gICAgICByZXR1cm4gY2FjaGVkO1xuICAgIH1cbiAgICBsZXQgb3B0aW9ucztcbiAgICBpZiAoY2hhcnQub3B0aW9ucy5hbmltYXRpb24gIT09IGZhbHNlKSB7XG4gICAgICBjb25zdCBjb25maWcgPSB0aGlzLmNoYXJ0LmNvbmZpZztcbiAgICAgIGNvbnN0IHNjb3BlS2V5cyA9IGNvbmZpZy5kYXRhc2V0QW5pbWF0aW9uU2NvcGVLZXlzKHRoaXMuX3R5cGUsIHRyYW5zaXRpb24pO1xuICAgICAgY29uc3Qgc2NvcGVzID0gY29uZmlnLmdldE9wdGlvblNjb3Blcyh0aGlzLmdldERhdGFzZXQoKSwgc2NvcGVLZXlzKTtcbiAgICAgIG9wdGlvbnMgPSBjb25maWcuY3JlYXRlUmVzb2x2ZXIoc2NvcGVzLCB0aGlzLmdldENvbnRleHQoaW5kZXgsIGFjdGl2ZSwgdHJhbnNpdGlvbikpO1xuICAgIH1cbiAgICBjb25zdCBhbmltYXRpb25zID0gbmV3IEFuaW1hdGlvbnMoY2hhcnQsIG9wdGlvbnMgJiYgb3B0aW9ucy5hbmltYXRpb25zKTtcbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLl9jYWNoZWFibGUpIHtcbiAgICAgIGNhY2hlW2NhY2hlS2V5XSA9IE9iamVjdC5mcmVlemUoYW5pbWF0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiBhbmltYXRpb25zO1xuICB9XG5cbiAgLyoqXG5cdCAqIFV0aWxpdHkgZm9yIGdldHRpbmcgdGhlIG9wdGlvbnMgb2JqZWN0IHNoYXJlZCBiZXR3ZWVuIGVsZW1lbnRzXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldFNoYXJlZE9wdGlvbnMob3B0aW9ucykge1xuICAgIGlmICghb3B0aW9ucy4kc2hhcmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9zaGFyZWRPcHRpb25zIHx8ICh0aGlzLl9zaGFyZWRPcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucykpO1xuICB9XG5cbiAgLyoqXG5cdCAqIFV0aWxpdHkgZm9yIGRldGVybWluaW5nIGlmIGBvcHRpb25zYCBzaG91bGQgYmUgaW5jbHVkZWQgaW4gdGhlIHVwZGF0ZWQgcHJvcGVydGllc1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBpbmNsdWRlT3B0aW9ucyhtb2RlLCBzaGFyZWRPcHRpb25zKSB7XG4gICAgcmV0dXJuICFzaGFyZWRPcHRpb25zIHx8IGlzRGlyZWN0VXBkYXRlTW9kZShtb2RlKSB8fCB0aGlzLmNoYXJ0Ll9hbmltYXRpb25zRGlzYWJsZWQ7XG4gIH1cblxuICAvKipcbiAgICogQHRvZG8gdjQsIHJlbmFtZSB0byBnZXRTaGFyZWRPcHRpb25zIGFuZCByZW1vdmUgZXhjZXNzIGZ1bmN0aW9uc1xuICAgKi9cbiAgX2dldFNoYXJlZE9wdGlvbnMoc3RhcnQsIG1vZGUpIHtcbiAgICBjb25zdCBmaXJzdE9wdHMgPSB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoc3RhcnQsIG1vZGUpO1xuICAgIGNvbnN0IHByZXZpb3VzbHlTaGFyZWRPcHRpb25zID0gdGhpcy5fc2hhcmVkT3B0aW9ucztcbiAgICBjb25zdCBzaGFyZWRPcHRpb25zID0gdGhpcy5nZXRTaGFyZWRPcHRpb25zKGZpcnN0T3B0cyk7XG4gICAgY29uc3QgaW5jbHVkZU9wdGlvbnMgPSB0aGlzLmluY2x1ZGVPcHRpb25zKG1vZGUsIHNoYXJlZE9wdGlvbnMpIHx8IChzaGFyZWRPcHRpb25zICE9PSBwcmV2aW91c2x5U2hhcmVkT3B0aW9ucyk7XG4gICAgdGhpcy51cGRhdGVTaGFyZWRPcHRpb25zKHNoYXJlZE9wdGlvbnMsIG1vZGUsIGZpcnN0T3B0cyk7XG4gICAgcmV0dXJuIHtzaGFyZWRPcHRpb25zLCBpbmNsdWRlT3B0aW9uc307XG4gIH1cblxuICAvKipcblx0ICogVXRpbGl0eSBmb3IgdXBkYXRpbmcgYW4gZWxlbWVudCB3aXRoIG5ldyBwcm9wZXJ0aWVzLCB1c2luZyBhbmltYXRpb25zIHdoZW4gYXBwcm9wcmlhdGUuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHVwZGF0ZUVsZW1lbnQoZWxlbWVudCwgaW5kZXgsIHByb3BlcnRpZXMsIG1vZGUpIHtcbiAgICBpZiAoaXNEaXJlY3RVcGRhdGVNb2RlKG1vZGUpKSB7XG4gICAgICBPYmplY3QuYXNzaWduKGVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZXNvbHZlQW5pbWF0aW9ucyhpbmRleCwgbW9kZSkudXBkYXRlKGVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBVdGlsaXR5IHRvIGFuaW1hdGUgdGhlIHNoYXJlZCBvcHRpb25zLCB0aGF0IGFyZSBwb3RlbnRpYWxseSBhZmZlY3RpbmcgbXVsdGlwbGUgZWxlbWVudHMuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHVwZGF0ZVNoYXJlZE9wdGlvbnMoc2hhcmVkT3B0aW9ucywgbW9kZSwgbmV3T3B0aW9ucykge1xuICAgIGlmIChzaGFyZWRPcHRpb25zICYmICFpc0RpcmVjdFVwZGF0ZU1vZGUobW9kZSkpIHtcbiAgICAgIHRoaXMuX3Jlc29sdmVBbmltYXRpb25zKHVuZGVmaW5lZCwgbW9kZSkudXBkYXRlKHNoYXJlZE9wdGlvbnMsIG5ld09wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3NldFN0eWxlKGVsZW1lbnQsIGluZGV4LCBtb2RlLCBhY3RpdmUpIHtcbiAgICBlbGVtZW50LmFjdGl2ZSA9IGFjdGl2ZTtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5nZXRTdHlsZShpbmRleCwgYWN0aXZlKTtcbiAgICB0aGlzLl9yZXNvbHZlQW5pbWF0aW9ucyhpbmRleCwgbW9kZSwgYWN0aXZlKS51cGRhdGUoZWxlbWVudCwge1xuICAgICAgLy8gV2hlbiBnb2luZyBmcm9tIGFjdGl2ZSB0byBpbmFjdGl2ZSwgd2UgbmVlZCB0byB1cGRhdGUgdG8gdGhlIHNoYXJlZCBvcHRpb25zLlxuICAgICAgLy8gVGhpcyB3YXkgdGhlIG9uY2UgaG92ZXJlZCBlbGVtZW50IHdpbGwgZW5kIHVwIHdpdGggdGhlIHNhbWUgb3JpZ2luYWwgc2hhcmVkIG9wdGlvbnMgaW5zdGFuY2UsIGFmdGVyIGFuaW1hdGlvbi5cbiAgICAgIG9wdGlvbnM6ICghYWN0aXZlICYmIHRoaXMuZ2V0U2hhcmVkT3B0aW9ucyhvcHRpb25zKSkgfHwgb3B0aW9uc1xuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlSG92ZXJTdHlsZShlbGVtZW50LCBkYXRhc2V0SW5kZXgsIGluZGV4KSB7XG4gICAgdGhpcy5fc2V0U3R5bGUoZWxlbWVudCwgaW5kZXgsICdhY3RpdmUnLCBmYWxzZSk7XG4gIH1cblxuICBzZXRIb3ZlclN0eWxlKGVsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXgpIHtcbiAgICB0aGlzLl9zZXRTdHlsZShlbGVtZW50LCBpbmRleCwgJ2FjdGl2ZScsIHRydWUpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfcmVtb3ZlRGF0YXNldEhvdmVyU3R5bGUoKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2NhY2hlZE1ldGEuZGF0YXNldDtcblxuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICB0aGlzLl9zZXRTdHlsZShlbGVtZW50LCB1bmRlZmluZWQsICdhY3RpdmUnLCBmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfc2V0RGF0YXNldEhvdmVyU3R5bGUoKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2NhY2hlZE1ldGEuZGF0YXNldDtcblxuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICB0aGlzLl9zZXRTdHlsZShlbGVtZW50LCB1bmRlZmluZWQsICdhY3RpdmUnLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9yZXN5bmNFbGVtZW50cyhyZXNldE5ld0VsZW1lbnRzKSB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLl9jYWNoZWRNZXRhLmRhdGE7XG5cbiAgICAvLyBBcHBseSBjaGFuZ2VzIGRldGVjdGVkIHRocm91Z2ggYXJyYXkgbGlzdGVuZXJzXG4gICAgZm9yIChjb25zdCBbbWV0aG9kLCBhcmcxLCBhcmcyXSBvZiB0aGlzLl9zeW5jTGlzdCkge1xuICAgICAgdGhpc1ttZXRob2RdKGFyZzEsIGFyZzIpO1xuICAgIH1cbiAgICB0aGlzLl9zeW5jTGlzdCA9IFtdO1xuXG4gICAgY29uc3QgbnVtTWV0YSA9IGVsZW1lbnRzLmxlbmd0aDtcbiAgICBjb25zdCBudW1EYXRhID0gZGF0YS5sZW5ndGg7XG4gICAgY29uc3QgY291bnQgPSBNYXRoLm1pbihudW1EYXRhLCBudW1NZXRhKTtcblxuICAgIGlmIChjb3VudCkge1xuICAgICAgLy8gVE9ETzogSXQgaXMgbm90IG9wdGltYWwgdG8gYWx3YXlzIHBhcnNlIHRoZSBvbGQgZGF0YVxuICAgICAgLy8gVGhpcyBpcyBkb25lIGJlY2F1c2Ugd2UgYXJlIG5vdCBkZXRlY3RpbmcgZGlyZWN0IGFzc2lnbm1lbnRzOlxuICAgICAgLy8gY2hhcnQuZGF0YS5kYXRhc2V0c1swXS5kYXRhWzVdID0gMTA7XG4gICAgICAvLyBjaGFydC5kYXRhLmRhdGFzZXRzWzBdLmRhdGFbNV0ueSA9IDEwO1xuICAgICAgdGhpcy5wYXJzZSgwLCBjb3VudCk7XG4gICAgfVxuXG4gICAgaWYgKG51bURhdGEgPiBudW1NZXRhKSB7XG4gICAgICB0aGlzLl9pbnNlcnRFbGVtZW50cyhudW1NZXRhLCBudW1EYXRhIC0gbnVtTWV0YSwgcmVzZXROZXdFbGVtZW50cyk7XG4gICAgfSBlbHNlIGlmIChudW1EYXRhIDwgbnVtTWV0YSkge1xuICAgICAgdGhpcy5fcmVtb3ZlRWxlbWVudHMobnVtRGF0YSwgbnVtTWV0YSAtIG51bURhdGEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2luc2VydEVsZW1lbnRzKHN0YXJ0LCBjb3VudCwgcmVzZXROZXdFbGVtZW50cyA9IHRydWUpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBkYXRhID0gbWV0YS5kYXRhO1xuICAgIGNvbnN0IGVuZCA9IHN0YXJ0ICsgY291bnQ7XG4gICAgbGV0IGk7XG5cbiAgICBjb25zdCBtb3ZlID0gKGFycikgPT4ge1xuICAgICAgYXJyLmxlbmd0aCArPSBjb3VudDtcbiAgICAgIGZvciAoaSA9IGFyci5sZW5ndGggLSAxOyBpID49IGVuZDsgaS0tKSB7XG4gICAgICAgIGFycltpXSA9IGFycltpIC0gY291bnRdO1xuICAgICAgfVxuICAgIH07XG4gICAgbW92ZShkYXRhKTtcblxuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIGRhdGFbaV0gPSBuZXcgdGhpcy5kYXRhRWxlbWVudFR5cGUoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcGFyc2luZykge1xuICAgICAgbW92ZShtZXRhLl9wYXJzZWQpO1xuICAgIH1cbiAgICB0aGlzLnBhcnNlKHN0YXJ0LCBjb3VudCk7XG5cbiAgICBpZiAocmVzZXROZXdFbGVtZW50cykge1xuICAgICAgdGhpcy51cGRhdGVFbGVtZW50cyhkYXRhLCBzdGFydCwgY291bnQsICdyZXNldCcpO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUVsZW1lbnRzKGVsZW1lbnQsIHN0YXJ0LCBjb3VudCwgbW9kZSkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3JlbW92ZUVsZW1lbnRzKHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGlmICh0aGlzLl9wYXJzaW5nKSB7XG4gICAgICBjb25zdCByZW1vdmVkID0gbWV0YS5fcGFyc2VkLnNwbGljZShzdGFydCwgY291bnQpO1xuICAgICAgaWYgKG1ldGEuX3N0YWNrZWQpIHtcbiAgICAgICAgY2xlYXJTdGFja3MobWV0YSwgcmVtb3ZlZCk7XG4gICAgICB9XG4gICAgfVxuICAgIG1ldGEuZGF0YS5zcGxpY2Uoc3RhcnQsIGNvdW50KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX3N5bmMoYXJncykge1xuICAgIGlmICh0aGlzLl9wYXJzaW5nKSB7XG4gICAgICB0aGlzLl9zeW5jTGlzdC5wdXNoKGFyZ3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBbbWV0aG9kLCBhcmcxLCBhcmcyXSA9IGFyZ3M7XG4gICAgICB0aGlzW21ldGhvZF0oYXJnMSwgYXJnMik7XG4gICAgfVxuICAgIHRoaXMuY2hhcnQuX2RhdGFDaGFuZ2VzLnB1c2goW3RoaXMuaW5kZXgsIC4uLmFyZ3NdKTtcbiAgfVxuXG4gIF9vbkRhdGFQdXNoKCkge1xuICAgIGNvbnN0IGNvdW50ID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB0aGlzLl9zeW5jKFsnX2luc2VydEVsZW1lbnRzJywgdGhpcy5nZXREYXRhc2V0KCkuZGF0YS5sZW5ndGggLSBjb3VudCwgY291bnRdKTtcbiAgfVxuXG4gIF9vbkRhdGFQb3AoKSB7XG4gICAgdGhpcy5fc3luYyhbJ19yZW1vdmVFbGVtZW50cycsIHRoaXMuX2NhY2hlZE1ldGEuZGF0YS5sZW5ndGggLSAxLCAxXSk7XG4gIH1cblxuICBfb25EYXRhU2hpZnQoKSB7XG4gICAgdGhpcy5fc3luYyhbJ19yZW1vdmVFbGVtZW50cycsIDAsIDFdKTtcbiAgfVxuXG4gIF9vbkRhdGFTcGxpY2Uoc3RhcnQsIGNvdW50KSB7XG4gICAgaWYgKGNvdW50KSB7XG4gICAgICB0aGlzLl9zeW5jKFsnX3JlbW92ZUVsZW1lbnRzJywgc3RhcnQsIGNvdW50XSk7XG4gICAgfVxuICAgIGNvbnN0IG5ld0NvdW50ID0gYXJndW1lbnRzLmxlbmd0aCAtIDI7XG4gICAgaWYgKG5ld0NvdW50KSB7XG4gICAgICB0aGlzLl9zeW5jKFsnX2luc2VydEVsZW1lbnRzJywgc3RhcnQsIG5ld0NvdW50XSk7XG4gICAgfVxuICB9XG5cbiAgX29uRGF0YVVuc2hpZnQoKSB7XG4gICAgdGhpcy5fc3luYyhbJ19pbnNlcnRFbGVtZW50cycsIDAsIGFyZ3VtZW50cy5sZW5ndGhdKTtcbiAgfVxufVxuIiwgImltcG9ydCBEYXRhc2V0Q29udHJvbGxlciBmcm9tICcuLi9jb3JlL2NvcmUuZGF0YXNldENvbnRyb2xsZXIuanMnO1xuaW1wb3J0IHtcbiAgX2FycmF5VW5pcXVlLCBpc0FycmF5LCBpc051bGxPclVuZGVmLFxuICB2YWx1ZU9yRGVmYXVsdCwgcmVzb2x2ZU9iamVjdEtleSwgc2lnbiwgZGVmaW5lZFxufSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcblxuZnVuY3Rpb24gZ2V0QWxsU2NhbGVWYWx1ZXMoc2NhbGUsIHR5cGUpIHtcbiAgaWYgKCFzY2FsZS5fY2FjaGUuJGJhcikge1xuICAgIGNvbnN0IHZpc2libGVNZXRhcyA9IHNjYWxlLmdldE1hdGNoaW5nVmlzaWJsZU1ldGFzKHR5cGUpO1xuICAgIGxldCB2YWx1ZXMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwLCBpbGVuID0gdmlzaWJsZU1ldGFzLmxlbmd0aDsgaSA8IGlsZW47IGkrKykge1xuICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdCh2aXNpYmxlTWV0YXNbaV0uY29udHJvbGxlci5nZXRBbGxQYXJzZWRWYWx1ZXMoc2NhbGUpKTtcbiAgICB9XG4gICAgc2NhbGUuX2NhY2hlLiRiYXIgPSBfYXJyYXlVbmlxdWUodmFsdWVzLnNvcnQoKGEsIGIpID0+IGEgLSBiKSk7XG4gIH1cbiAgcmV0dXJuIHNjYWxlLl9jYWNoZS4kYmFyO1xufVxuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBcIm9wdGltYWxcIiBzYW1wbGUgc2l6ZSB0byBtYWludGFpbiBiYXJzIGVxdWFsbHkgc2l6ZWQgd2hpbGUgcHJldmVudGluZyBvdmVybGFwLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY29tcHV0ZU1pblNhbXBsZVNpemUobWV0YSkge1xuICBjb25zdCBzY2FsZSA9IG1ldGEuaVNjYWxlO1xuICBjb25zdCB2YWx1ZXMgPSBnZXRBbGxTY2FsZVZhbHVlcyhzY2FsZSwgbWV0YS50eXBlKTtcbiAgbGV0IG1pbiA9IHNjYWxlLl9sZW5ndGg7XG4gIGxldCBpLCBpbGVuLCBjdXJyLCBwcmV2O1xuICBjb25zdCB1cGRhdGVNaW5BbmRQcmV2ID0gKCkgPT4ge1xuICAgIGlmIChjdXJyID09PSAzMjc2NyB8fCBjdXJyID09PSAtMzI3NjgpIHtcbiAgICAgIC8vIElnbm9yZSB0cnVuY2F0ZWQgcGl4ZWxzXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChkZWZpbmVkKHByZXYpKSB7XG4gICAgICAvLyBjdXJyIC0gcHJldiA9PT0gMCBpcyBpZ25vcmVkXG4gICAgICBtaW4gPSBNYXRoLm1pbihtaW4sIE1hdGguYWJzKGN1cnIgLSBwcmV2KSB8fCBtaW4pO1xuICAgIH1cbiAgICBwcmV2ID0gY3VycjtcbiAgfTtcblxuICBmb3IgKGkgPSAwLCBpbGVuID0gdmFsdWVzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIGN1cnIgPSBzY2FsZS5nZXRQaXhlbEZvclZhbHVlKHZhbHVlc1tpXSk7XG4gICAgdXBkYXRlTWluQW5kUHJldigpO1xuICB9XG5cbiAgcHJldiA9IHVuZGVmaW5lZDtcbiAgZm9yIChpID0gMCwgaWxlbiA9IHNjYWxlLnRpY2tzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIGN1cnIgPSBzY2FsZS5nZXRQaXhlbEZvclRpY2soaSk7XG4gICAgdXBkYXRlTWluQW5kUHJldigpO1xuICB9XG5cbiAgcmV0dXJuIG1pbjtcbn1cblxuLyoqXG4gKiBDb21wdXRlcyBhbiBcImlkZWFsXCIgY2F0ZWdvcnkgYmFzZWQgb24gdGhlIGFic29sdXRlIGJhciB0aGlja25lc3Mgb3IsIGlmIHVuZGVmaW5lZCBvciBudWxsLFxuICogdXNlcyB0aGUgc21hbGxlc3QgaW50ZXJ2YWwgKHNlZSBjb21wdXRlTWluU2FtcGxlU2l6ZSkgdGhhdCBwcmV2ZW50cyBiYXIgb3ZlcmxhcHBpbmcuIFRoaXNcbiAqIG1vZGUgY3VycmVudGx5IGFsd2F5cyBnZW5lcmF0ZXMgYmFycyBlcXVhbGx5IHNpemVkICh1bnRpbCB3ZSBpbnRyb2R1Y2Ugc2NyaXB0YWJsZSBvcHRpb25zPykuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjb21wdXRlRml0Q2F0ZWdvcnlUcmFpdHMoaW5kZXgsIHJ1bGVyLCBvcHRpb25zLCBzdGFja0NvdW50KSB7XG4gIGNvbnN0IHRoaWNrbmVzcyA9IG9wdGlvbnMuYmFyVGhpY2tuZXNzO1xuICBsZXQgc2l6ZSwgcmF0aW87XG5cbiAgaWYgKGlzTnVsbE9yVW5kZWYodGhpY2tuZXNzKSkge1xuICAgIHNpemUgPSBydWxlci5taW4gKiBvcHRpb25zLmNhdGVnb3J5UGVyY2VudGFnZTtcbiAgICByYXRpbyA9IG9wdGlvbnMuYmFyUGVyY2VudGFnZTtcbiAgfSBlbHNlIHtcbiAgICAvLyBXaGVuIGJhciB0aGlja25lc3MgaXMgZW5mb3JjZWQsIGNhdGVnb3J5IGFuZCBiYXIgcGVyY2VudGFnZXMgYXJlIGlnbm9yZWQuXG4gICAgLy8gTm90ZShTQik6IHdlIGNvdWxkIGFkZCBzdXBwb3J0IGZvciByZWxhdGl2ZSBiYXIgdGhpY2tuZXNzIChlLmcuIGJhclRoaWNrbmVzczogJzUwJScpXG4gICAgLy8gYW5kIGRlcHJlY2F0ZSBiYXJQZXJjZW50YWdlIHNpbmNlIHRoaXMgdmFsdWUgaXMgaWdub3JlZCB3aGVuIHRoaWNrbmVzcyBpcyBhYnNvbHV0ZS5cbiAgICBzaXplID0gdGhpY2tuZXNzICogc3RhY2tDb3VudDtcbiAgICByYXRpbyA9IDE7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNodW5rOiBzaXplIC8gc3RhY2tDb3VudCxcbiAgICByYXRpbyxcbiAgICBzdGFydDogcnVsZXIucGl4ZWxzW2luZGV4XSAtIChzaXplIC8gMilcbiAgfTtcbn1cblxuLyoqXG4gKiBDb21wdXRlcyBhbiBcIm9wdGltYWxcIiBjYXRlZ29yeSB0aGF0IGdsb2JhbGx5IGFycmFuZ2VzIGJhcnMgc2lkZSBieSBzaWRlIChubyBnYXAgd2hlblxuICogcGVyY2VudGFnZSBvcHRpb25zIGFyZSAxKSwgYmFzZWQgb24gdGhlIHByZXZpb3VzIGFuZCBmb2xsb3dpbmcgY2F0ZWdvcmllcy4gVGhpcyBtb2RlXG4gKiBnZW5lcmF0ZXMgYmFycyB3aXRoIGRpZmZlcmVudCB3aWR0aHMgd2hlbiBkYXRhIGFyZSBub3QgZXZlbmx5IHNwYWNlZC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVGbGV4Q2F0ZWdvcnlUcmFpdHMoaW5kZXgsIHJ1bGVyLCBvcHRpb25zLCBzdGFja0NvdW50KSB7XG4gIGNvbnN0IHBpeGVscyA9IHJ1bGVyLnBpeGVscztcbiAgY29uc3QgY3VyciA9IHBpeGVsc1tpbmRleF07XG4gIGxldCBwcmV2ID0gaW5kZXggPiAwID8gcGl4ZWxzW2luZGV4IC0gMV0gOiBudWxsO1xuICBsZXQgbmV4dCA9IGluZGV4IDwgcGl4ZWxzLmxlbmd0aCAtIDEgPyBwaXhlbHNbaW5kZXggKyAxXSA6IG51bGw7XG4gIGNvbnN0IHBlcmNlbnQgPSBvcHRpb25zLmNhdGVnb3J5UGVyY2VudGFnZTtcblxuICBpZiAocHJldiA9PT0gbnVsbCkge1xuICAgIC8vIGZpcnN0IGRhdGE6IGl0cyBzaXplIGlzIGRvdWJsZSBiYXNlZCBvbiB0aGUgbmV4dCBwb2ludCBvcixcbiAgICAvLyBpZiBpdCdzIGFsc28gdGhlIGxhc3QgZGF0YSwgd2UgdXNlIHRoZSBzY2FsZSBzaXplLlxuICAgIHByZXYgPSBjdXJyIC0gKG5leHQgPT09IG51bGwgPyBydWxlci5lbmQgLSBydWxlci5zdGFydCA6IG5leHQgLSBjdXJyKTtcbiAgfVxuXG4gIGlmIChuZXh0ID09PSBudWxsKSB7XG4gICAgLy8gbGFzdCBkYXRhOiBpdHMgc2l6ZSBpcyBhbHNvIGRvdWJsZSBiYXNlZCBvbiB0aGUgcHJldmlvdXMgcG9pbnQuXG4gICAgbmV4dCA9IGN1cnIgKyBjdXJyIC0gcHJldjtcbiAgfVxuXG4gIGNvbnN0IHN0YXJ0ID0gY3VyciAtIChjdXJyIC0gTWF0aC5taW4ocHJldiwgbmV4dCkpIC8gMiAqIHBlcmNlbnQ7XG4gIGNvbnN0IHNpemUgPSBNYXRoLmFicyhuZXh0IC0gcHJldikgLyAyICogcGVyY2VudDtcblxuICByZXR1cm4ge1xuICAgIGNodW5rOiBzaXplIC8gc3RhY2tDb3VudCxcbiAgICByYXRpbzogb3B0aW9ucy5iYXJQZXJjZW50YWdlLFxuICAgIHN0YXJ0XG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhcnNlRmxvYXRCYXIoZW50cnksIGl0ZW0sIHZTY2FsZSwgaSkge1xuICBjb25zdCBzdGFydFZhbHVlID0gdlNjYWxlLnBhcnNlKGVudHJ5WzBdLCBpKTtcbiAgY29uc3QgZW5kVmFsdWUgPSB2U2NhbGUucGFyc2UoZW50cnlbMV0sIGkpO1xuICBjb25zdCBtaW4gPSBNYXRoLm1pbihzdGFydFZhbHVlLCBlbmRWYWx1ZSk7XG4gIGNvbnN0IG1heCA9IE1hdGgubWF4KHN0YXJ0VmFsdWUsIGVuZFZhbHVlKTtcbiAgbGV0IGJhclN0YXJ0ID0gbWluO1xuICBsZXQgYmFyRW5kID0gbWF4O1xuXG4gIGlmIChNYXRoLmFicyhtaW4pID4gTWF0aC5hYnMobWF4KSkge1xuICAgIGJhclN0YXJ0ID0gbWF4O1xuICAgIGJhckVuZCA9IG1pbjtcbiAgfVxuXG4gIC8vIFN0b3JlIGBiYXJFbmRgIChmdXJ0aGVzdCBhd2F5IGZyb20gb3JpZ2luKSBhcyBwYXJzZWQgdmFsdWUsXG4gIC8vIHRvIG1ha2Ugc3RhY2tpbmcgc3RyYWlnaHQgZm9yd2FyZFxuICBpdGVtW3ZTY2FsZS5heGlzXSA9IGJhckVuZDtcblxuICBpdGVtLl9jdXN0b20gPSB7XG4gICAgYmFyU3RhcnQsXG4gICAgYmFyRW5kLFxuICAgIHN0YXJ0OiBzdGFydFZhbHVlLFxuICAgIGVuZDogZW5kVmFsdWUsXG4gICAgbWluLFxuICAgIG1heFxuICB9O1xufVxuXG5mdW5jdGlvbiBwYXJzZVZhbHVlKGVudHJ5LCBpdGVtLCB2U2NhbGUsIGkpIHtcbiAgaWYgKGlzQXJyYXkoZW50cnkpKSB7XG4gICAgcGFyc2VGbG9hdEJhcihlbnRyeSwgaXRlbSwgdlNjYWxlLCBpKTtcbiAgfSBlbHNlIHtcbiAgICBpdGVtW3ZTY2FsZS5heGlzXSA9IHZTY2FsZS5wYXJzZShlbnRyeSwgaSk7XG4gIH1cbiAgcmV0dXJuIGl0ZW07XG59XG5cbmZ1bmN0aW9uIHBhcnNlQXJyYXlPclByaW1pdGl2ZShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgY29uc3QgaVNjYWxlID0gbWV0YS5pU2NhbGU7XG4gIGNvbnN0IHZTY2FsZSA9IG1ldGEudlNjYWxlO1xuICBjb25zdCBsYWJlbHMgPSBpU2NhbGUuZ2V0TGFiZWxzKCk7XG4gIGNvbnN0IHNpbmdsZVNjYWxlID0gaVNjYWxlID09PSB2U2NhbGU7XG4gIGNvbnN0IHBhcnNlZCA9IFtdO1xuICBsZXQgaSwgaWxlbiwgaXRlbSwgZW50cnk7XG5cbiAgZm9yIChpID0gc3RhcnQsIGlsZW4gPSBzdGFydCArIGNvdW50OyBpIDwgaWxlbjsgKytpKSB7XG4gICAgZW50cnkgPSBkYXRhW2ldO1xuICAgIGl0ZW0gPSB7fTtcbiAgICBpdGVtW2lTY2FsZS5heGlzXSA9IHNpbmdsZVNjYWxlIHx8IGlTY2FsZS5wYXJzZShsYWJlbHNbaV0sIGkpO1xuICAgIHBhcnNlZC5wdXNoKHBhcnNlVmFsdWUoZW50cnksIGl0ZW0sIHZTY2FsZSwgaSkpO1xuICB9XG4gIHJldHVybiBwYXJzZWQ7XG59XG5cbmZ1bmN0aW9uIGlzRmxvYXRCYXIoY3VzdG9tKSB7XG4gIHJldHVybiBjdXN0b20gJiYgY3VzdG9tLmJhclN0YXJ0ICE9PSB1bmRlZmluZWQgJiYgY3VzdG9tLmJhckVuZCAhPT0gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBiYXJTaWduKHNpemUsIHZTY2FsZSwgYWN0dWFsQmFzZSkge1xuICBpZiAoc2l6ZSAhPT0gMCkge1xuICAgIHJldHVybiBzaWduKHNpemUpO1xuICB9XG4gIHJldHVybiAodlNjYWxlLmlzSG9yaXpvbnRhbCgpID8gMSA6IC0xKSAqICh2U2NhbGUubWluID49IGFjdHVhbEJhc2UgPyAxIDogLTEpO1xufVxuXG5mdW5jdGlvbiBib3JkZXJQcm9wcyhwcm9wZXJ0aWVzKSB7XG4gIGxldCByZXZlcnNlLCBzdGFydCwgZW5kLCB0b3AsIGJvdHRvbTtcbiAgaWYgKHByb3BlcnRpZXMuaG9yaXpvbnRhbCkge1xuICAgIHJldmVyc2UgPSBwcm9wZXJ0aWVzLmJhc2UgPiBwcm9wZXJ0aWVzLng7XG4gICAgc3RhcnQgPSAnbGVmdCc7XG4gICAgZW5kID0gJ3JpZ2h0JztcbiAgfSBlbHNlIHtcbiAgICByZXZlcnNlID0gcHJvcGVydGllcy5iYXNlIDwgcHJvcGVydGllcy55O1xuICAgIHN0YXJ0ID0gJ2JvdHRvbSc7XG4gICAgZW5kID0gJ3RvcCc7XG4gIH1cbiAgaWYgKHJldmVyc2UpIHtcbiAgICB0b3AgPSAnZW5kJztcbiAgICBib3R0b20gPSAnc3RhcnQnO1xuICB9IGVsc2Uge1xuICAgIHRvcCA9ICdzdGFydCc7XG4gICAgYm90dG9tID0gJ2VuZCc7XG4gIH1cbiAgcmV0dXJuIHtzdGFydCwgZW5kLCByZXZlcnNlLCB0b3AsIGJvdHRvbX07XG59XG5cbmZ1bmN0aW9uIHNldEJvcmRlclNraXBwZWQocHJvcGVydGllcywgb3B0aW9ucywgc3RhY2ssIGluZGV4KSB7XG4gIGxldCBlZGdlID0gb3B0aW9ucy5ib3JkZXJTa2lwcGVkO1xuICBjb25zdCByZXMgPSB7fTtcblxuICBpZiAoIWVkZ2UpIHtcbiAgICBwcm9wZXJ0aWVzLmJvcmRlclNraXBwZWQgPSByZXM7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGVkZ2UgPT09IHRydWUpIHtcbiAgICBwcm9wZXJ0aWVzLmJvcmRlclNraXBwZWQgPSB7dG9wOiB0cnVlLCByaWdodDogdHJ1ZSwgYm90dG9tOiB0cnVlLCBsZWZ0OiB0cnVlfTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB7c3RhcnQsIGVuZCwgcmV2ZXJzZSwgdG9wLCBib3R0b219ID0gYm9yZGVyUHJvcHMocHJvcGVydGllcyk7XG5cbiAgaWYgKGVkZ2UgPT09ICdtaWRkbGUnICYmIHN0YWNrKSB7XG4gICAgcHJvcGVydGllcy5lbmFibGVCb3JkZXJSYWRpdXMgPSB0cnVlO1xuICAgIGlmICgoc3RhY2suX3RvcCB8fCAwKSA9PT0gaW5kZXgpIHtcbiAgICAgIGVkZ2UgPSB0b3A7XG4gICAgfSBlbHNlIGlmICgoc3RhY2suX2JvdHRvbSB8fCAwKSA9PT0gaW5kZXgpIHtcbiAgICAgIGVkZ2UgPSBib3R0b207XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc1twYXJzZUVkZ2UoYm90dG9tLCBzdGFydCwgZW5kLCByZXZlcnNlKV0gPSB0cnVlO1xuICAgICAgZWRnZSA9IHRvcDtcbiAgICB9XG4gIH1cblxuICByZXNbcGFyc2VFZGdlKGVkZ2UsIHN0YXJ0LCBlbmQsIHJldmVyc2UpXSA9IHRydWU7XG4gIHByb3BlcnRpZXMuYm9yZGVyU2tpcHBlZCA9IHJlcztcbn1cblxuZnVuY3Rpb24gcGFyc2VFZGdlKGVkZ2UsIGEsIGIsIHJldmVyc2UpIHtcbiAgaWYgKHJldmVyc2UpIHtcbiAgICBlZGdlID0gc3dhcChlZGdlLCBhLCBiKTtcbiAgICBlZGdlID0gc3RhcnRFbmQoZWRnZSwgYiwgYSk7XG4gIH0gZWxzZSB7XG4gICAgZWRnZSA9IHN0YXJ0RW5kKGVkZ2UsIGEsIGIpO1xuICB9XG4gIHJldHVybiBlZGdlO1xufVxuXG5mdW5jdGlvbiBzd2FwKG9yaWcsIHYxLCB2Mikge1xuICByZXR1cm4gb3JpZyA9PT0gdjEgPyB2MiA6IG9yaWcgPT09IHYyID8gdjEgOiBvcmlnO1xufVxuXG5mdW5jdGlvbiBzdGFydEVuZCh2LCBzdGFydCwgZW5kKSB7XG4gIHJldHVybiB2ID09PSAnc3RhcnQnID8gc3RhcnQgOiB2ID09PSAnZW5kJyA/IGVuZCA6IHY7XG59XG5cbmZ1bmN0aW9uIHNldEluZmxhdGVBbW91bnQocHJvcGVydGllcywge2luZmxhdGVBbW91bnR9LCByYXRpbykge1xuICBwcm9wZXJ0aWVzLmluZmxhdGVBbW91bnQgPSBpbmZsYXRlQW1vdW50ID09PSAnYXV0bydcbiAgICA/IHJhdGlvID09PSAxID8gMC4zMyA6IDBcbiAgICA6IGluZmxhdGVBbW91bnQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhckNvbnRyb2xsZXIgZXh0ZW5kcyBEYXRhc2V0Q29udHJvbGxlciB7XG5cbiAgc3RhdGljIGlkID0gJ2Jhcic7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgZGF0YXNldEVsZW1lbnRUeXBlOiBmYWxzZSxcbiAgICBkYXRhRWxlbWVudFR5cGU6ICdiYXInLFxuXG4gICAgY2F0ZWdvcnlQZXJjZW50YWdlOiAwLjgsXG4gICAgYmFyUGVyY2VudGFnZTogMC45LFxuICAgIGdyb3VwZWQ6IHRydWUsXG5cbiAgICBhbmltYXRpb25zOiB7XG4gICAgICBudW1iZXJzOiB7XG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBwcm9wZXJ0aWVzOiBbJ3gnLCAneScsICdiYXNlJywgJ3dpZHRoJywgJ2hlaWdodCddXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIG92ZXJyaWRlcyA9IHtcbiAgICBzY2FsZXM6IHtcbiAgICAgIF9pbmRleF86IHtcbiAgICAgICAgdHlwZTogJ2NhdGVnb3J5JyxcbiAgICAgICAgb2Zmc2V0OiB0cnVlLFxuICAgICAgICBncmlkOiB7XG4gICAgICAgICAgb2Zmc2V0OiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBfdmFsdWVfOiB7XG4gICAgICAgIHR5cGU6ICdsaW5lYXInLFxuICAgICAgICBiZWdpbkF0WmVybzogdHJ1ZSxcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cblxuICAvKipcblx0ICogT3ZlcnJpZGluZyBwcmltaXRpdmUgZGF0YSBwYXJzaW5nIHNpbmNlIHdlIHN1cHBvcnQgbWl4ZWQgcHJpbWl0aXZlL2FycmF5XG5cdCAqIGRhdGEgZm9yIGZsb2F0IGJhcnNcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgcGFyc2VQcmltaXRpdmVEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIHJldHVybiBwYXJzZUFycmF5T3JQcmltaXRpdmUobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBPdmVycmlkaW5nIGFycmF5IGRhdGEgcGFyc2luZyBzaW5jZSB3ZSBzdXBwb3J0IG1peGVkIHByaW1pdGl2ZS9hcnJheVxuXHQgKiBkYXRhIGZvciBmbG9hdCBiYXJzXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHBhcnNlQXJyYXlEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIHJldHVybiBwYXJzZUFycmF5T3JQcmltaXRpdmUobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBPdmVycmlkaW5nIG9iamVjdCBkYXRhIHBhcnNpbmcgc2luY2Ugd2Ugc3VwcG9ydCBtaXhlZCBwcmltaXRpdmUvYXJyYXlcblx0ICogdmFsdWUtc2NhbGUgZGF0YSBmb3IgZmxvYXQgYmFyc1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBwYXJzZU9iamVjdERhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgY29uc3Qge2lTY2FsZSwgdlNjYWxlfSA9IG1ldGE7XG4gICAgY29uc3Qge3hBeGlzS2V5ID0gJ3gnLCB5QXhpc0tleSA9ICd5J30gPSB0aGlzLl9wYXJzaW5nO1xuICAgIGNvbnN0IGlBeGlzS2V5ID0gaVNjYWxlLmF4aXMgPT09ICd4JyA/IHhBeGlzS2V5IDogeUF4aXNLZXk7XG4gICAgY29uc3QgdkF4aXNLZXkgPSB2U2NhbGUuYXhpcyA9PT0gJ3gnID8geEF4aXNLZXkgOiB5QXhpc0tleTtcbiAgICBjb25zdCBwYXJzZWQgPSBbXTtcbiAgICBsZXQgaSwgaWxlbiwgaXRlbSwgb2JqO1xuICAgIGZvciAoaSA9IHN0YXJ0LCBpbGVuID0gc3RhcnQgKyBjb3VudDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgb2JqID0gZGF0YVtpXTtcbiAgICAgIGl0ZW0gPSB7fTtcbiAgICAgIGl0ZW1baVNjYWxlLmF4aXNdID0gaVNjYWxlLnBhcnNlKHJlc29sdmVPYmplY3RLZXkob2JqLCBpQXhpc0tleSksIGkpO1xuICAgICAgcGFyc2VkLnB1c2gocGFyc2VWYWx1ZShyZXNvbHZlT2JqZWN0S2V5KG9iaiwgdkF4aXNLZXkpLCBpdGVtLCB2U2NhbGUsIGkpKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlZDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICB1cGRhdGVSYW5nZUZyb21QYXJzZWQocmFuZ2UsIHNjYWxlLCBwYXJzZWQsIHN0YWNrKSB7XG4gICAgc3VwZXIudXBkYXRlUmFuZ2VGcm9tUGFyc2VkKHJhbmdlLCBzY2FsZSwgcGFyc2VkLCBzdGFjayk7XG4gICAgY29uc3QgY3VzdG9tID0gcGFyc2VkLl9jdXN0b207XG4gICAgaWYgKGN1c3RvbSAmJiBzY2FsZSA9PT0gdGhpcy5fY2FjaGVkTWV0YS52U2NhbGUpIHtcbiAgICAgIC8vIGZsb2F0IGJhcjogb25seSBvbmUgZW5kIG9mIHRoZSBiYXIgaXMgY29uc2lkZXJlZCBieSBgc3VwZXJgXG4gICAgICByYW5nZS5taW4gPSBNYXRoLm1pbihyYW5nZS5taW4sIGN1c3RvbS5taW4pO1xuICAgICAgcmFuZ2UubWF4ID0gTWF0aC5tYXgocmFuZ2UubWF4LCBjdXN0b20ubWF4KTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHJldHVybiB7bnVtYmVyfGJvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldE1heE92ZXJmbG93KCkge1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldExhYmVsQW5kVmFsdWUoaW5kZXgpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCB7aVNjYWxlLCB2U2NhbGV9ID0gbWV0YTtcbiAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG4gICAgY29uc3QgY3VzdG9tID0gcGFyc2VkLl9jdXN0b207XG4gICAgY29uc3QgdmFsdWUgPSBpc0Zsb2F0QmFyKGN1c3RvbSlcbiAgICAgID8gJ1snICsgY3VzdG9tLnN0YXJ0ICsgJywgJyArIGN1c3RvbS5lbmQgKyAnXSdcbiAgICAgIDogJycgKyB2U2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWRbdlNjYWxlLmF4aXNdKTtcblxuICAgIHJldHVybiB7XG4gICAgICBsYWJlbDogJycgKyBpU2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWRbaVNjYWxlLmF4aXNdKSxcbiAgICAgIHZhbHVlXG4gICAgfTtcbiAgfVxuXG4gIGluaXRpYWxpemUoKSB7XG4gICAgdGhpcy5lbmFibGVPcHRpb25TaGFyaW5nID0gdHJ1ZTtcblxuICAgIHN1cGVyLmluaXRpYWxpemUoKTtcblxuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIG1ldGEuc3RhY2sgPSB0aGlzLmdldERhdGFzZXQoKS5zdGFjaztcbiAgfVxuXG4gIHVwZGF0ZShtb2RlKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgdGhpcy51cGRhdGVFbGVtZW50cyhtZXRhLmRhdGEsIDAsIG1ldGEuZGF0YS5sZW5ndGgsIG1vZGUpO1xuICB9XG5cbiAgdXBkYXRlRWxlbWVudHMoYmFycywgc3RhcnQsIGNvdW50LCBtb2RlKSB7XG4gICAgY29uc3QgcmVzZXQgPSBtb2RlID09PSAncmVzZXQnO1xuICAgIGNvbnN0IHtpbmRleCwgX2NhY2hlZE1ldGE6IHt2U2NhbGV9fSA9IHRoaXM7XG4gICAgY29uc3QgYmFzZSA9IHZTY2FsZS5nZXRCYXNlUGl4ZWwoKTtcbiAgICBjb25zdCBob3Jpem9udGFsID0gdlNjYWxlLmlzSG9yaXpvbnRhbCgpO1xuICAgIGNvbnN0IHJ1bGVyID0gdGhpcy5fZ2V0UnVsZXIoKTtcbiAgICBjb25zdCB7c2hhcmVkT3B0aW9ucywgaW5jbHVkZU9wdGlvbnN9ID0gdGhpcy5fZ2V0U2hhcmVkT3B0aW9ucyhzdGFydCwgbW9kZSk7XG5cbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBzdGFydCArIGNvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGkpO1xuICAgICAgY29uc3QgdnBpeGVscyA9IHJlc2V0IHx8IGlzTnVsbE9yVW5kZWYocGFyc2VkW3ZTY2FsZS5heGlzXSkgPyB7YmFzZSwgaGVhZDogYmFzZX0gOiB0aGlzLl9jYWxjdWxhdGVCYXJWYWx1ZVBpeGVscyhpKTtcbiAgICAgIGNvbnN0IGlwaXhlbHMgPSB0aGlzLl9jYWxjdWxhdGVCYXJJbmRleFBpeGVscyhpLCBydWxlcik7XG4gICAgICBjb25zdCBzdGFjayA9IChwYXJzZWQuX3N0YWNrcyB8fCB7fSlbdlNjYWxlLmF4aXNdO1xuXG4gICAgICBjb25zdCBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBob3Jpem9udGFsLFxuICAgICAgICBiYXNlOiB2cGl4ZWxzLmJhc2UsXG4gICAgICAgIGVuYWJsZUJvcmRlclJhZGl1czogIXN0YWNrIHx8IGlzRmxvYXRCYXIocGFyc2VkLl9jdXN0b20pIHx8IChpbmRleCA9PT0gc3RhY2suX3RvcCB8fCBpbmRleCA9PT0gc3RhY2suX2JvdHRvbSksXG4gICAgICAgIHg6IGhvcml6b250YWwgPyB2cGl4ZWxzLmhlYWQgOiBpcGl4ZWxzLmNlbnRlcixcbiAgICAgICAgeTogaG9yaXpvbnRhbCA/IGlwaXhlbHMuY2VudGVyIDogdnBpeGVscy5oZWFkLFxuICAgICAgICBoZWlnaHQ6IGhvcml6b250YWwgPyBpcGl4ZWxzLnNpemUgOiBNYXRoLmFicyh2cGl4ZWxzLnNpemUpLFxuICAgICAgICB3aWR0aDogaG9yaXpvbnRhbCA/IE1hdGguYWJzKHZwaXhlbHMuc2l6ZSkgOiBpcGl4ZWxzLnNpemVcbiAgICAgIH07XG5cbiAgICAgIGlmIChpbmNsdWRlT3B0aW9ucykge1xuICAgICAgICBwcm9wZXJ0aWVzLm9wdGlvbnMgPSBzaGFyZWRPcHRpb25zIHx8IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpLCBiYXJzW2ldLmFjdGl2ZSA/ICdhY3RpdmUnIDogbW9kZSk7XG4gICAgICB9XG4gICAgICBjb25zdCBvcHRpb25zID0gcHJvcGVydGllcy5vcHRpb25zIHx8IGJhcnNbaV0ub3B0aW9ucztcbiAgICAgIHNldEJvcmRlclNraXBwZWQocHJvcGVydGllcywgb3B0aW9ucywgc3RhY2ssIGluZGV4KTtcbiAgICAgIHNldEluZmxhdGVBbW91bnQocHJvcGVydGllcywgb3B0aW9ucywgcnVsZXIucmF0aW8pO1xuICAgICAgdGhpcy51cGRhdGVFbGVtZW50KGJhcnNbaV0sIGksIHByb3BlcnRpZXMsIG1vZGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBzdGFja3MgYmFzZWQgb24gZ3JvdXBzIGFuZCBiYXIgdmlzaWJpbGl0eS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IFtsYXN0XSAtIFRoZSBkYXRhc2V0IGluZGV4XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbZGF0YUluZGV4XSAtIFRoZSBkYXRhIGluZGV4IG9mIHRoZSBydWxlclxuXHQgKiBAcmV0dXJucyB7c3RyaW5nW119IFRoZSBsaXN0IG9mIHN0YWNrIElEc1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldFN0YWNrcyhsYXN0LCBkYXRhSW5kZXgpIHtcbiAgICBjb25zdCB7aVNjYWxlfSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgbWV0YXNldHMgPSBpU2NhbGUuZ2V0TWF0Y2hpbmdWaXNpYmxlTWV0YXModGhpcy5fdHlwZSlcbiAgICAgIC5maWx0ZXIobWV0YSA9PiBtZXRhLmNvbnRyb2xsZXIub3B0aW9ucy5ncm91cGVkKTtcbiAgICBjb25zdCBzdGFja2VkID0gaVNjYWxlLm9wdGlvbnMuc3RhY2tlZDtcbiAgICBjb25zdCBzdGFja3MgPSBbXTtcblxuICAgIGNvbnN0IHNraXBOdWxsID0gKG1ldGEpID0+IHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IG1ldGEuY29udHJvbGxlci5nZXRQYXJzZWQoZGF0YUluZGV4KTtcbiAgICAgIGNvbnN0IHZhbCA9IHBhcnNlZCAmJiBwYXJzZWRbbWV0YS52U2NhbGUuYXhpc107XG5cbiAgICAgIGlmIChpc051bGxPclVuZGVmKHZhbCkgfHwgaXNOYU4odmFsKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBtZXRhIG9mIG1ldGFzZXRzKSB7XG4gICAgICBpZiAoZGF0YUluZGV4ICE9PSB1bmRlZmluZWQgJiYgc2tpcE51bGwobWV0YSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIHN0YWNrZWQgICB8IG1ldGEuc3RhY2tcbiAgICAgIC8vICAgICAgICAgICB8IGZvdW5kIHwgbm90IGZvdW5kIHwgdW5kZWZpbmVkXG4gICAgICAvLyBmYWxzZSAgICAgfCAgIHggICB8ICAgICB4ICAgICB8ICAgICB4XG4gICAgICAvLyB0cnVlICAgICAgfCAgICAgICB8ICAgICB4ICAgICB8XG4gICAgICAvLyB1bmRlZmluZWQgfCAgICAgICB8ICAgICB4ICAgICB8ICAgICB4XG4gICAgICBpZiAoc3RhY2tlZCA9PT0gZmFsc2UgfHwgc3RhY2tzLmluZGV4T2YobWV0YS5zdGFjaykgPT09IC0xIHx8XG5cdFx0XHRcdChzdGFja2VkID09PSB1bmRlZmluZWQgJiYgbWV0YS5zdGFjayA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICBzdGFja3MucHVzaChtZXRhLnN0YWNrKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXRhLmluZGV4ID09PSBsYXN0KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE5vIHN0YWNrcz8gdGhhdCBtZWFucyB0aGVyZSBpcyBubyB2aXNpYmxlIGRhdGEuIExldCdzIHN0aWxsIGluaXRpYWxpemUgYW4gYHVuZGVmaW5lZGBcbiAgICAvLyBzdGFjayB3aGVyZSBwb3NzaWJsZSBpbnZpc2libGUgYmFycyB3aWxsIGJlIGxvY2F0ZWQuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzYzNjhcbiAgICBpZiAoIXN0YWNrcy5sZW5ndGgpIHtcbiAgICAgIHN0YWNrcy5wdXNoKHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YWNrcztcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBlZmZlY3RpdmUgbnVtYmVyIG9mIHN0YWNrcyBiYXNlZCBvbiBncm91cHMgYW5kIGJhciB2aXNpYmlsaXR5LlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldFN0YWNrQ291bnQoaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0U3RhY2tzKHVuZGVmaW5lZCwgaW5kZXgpLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBzdGFjayBpbmRleCBmb3IgdGhlIGdpdmVuIGRhdGFzZXQgYmFzZWQgb24gZ3JvdXBzIGFuZCBiYXIgdmlzaWJpbGl0eS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IFtkYXRhc2V0SW5kZXhdIC0gVGhlIGRhdGFzZXQgaW5kZXhcblx0ICogQHBhcmFtIHtzdHJpbmd9IFtuYW1lXSAtIFRoZSBzdGFjayBuYW1lIHRvIGZpbmRcbiAgICogQHBhcmFtIHtudW1iZXJ9IFtkYXRhSW5kZXhdXG5cdCAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSBzdGFjayBpbmRleFxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldFN0YWNrSW5kZXgoZGF0YXNldEluZGV4LCBuYW1lLCBkYXRhSW5kZXgpIHtcbiAgICBjb25zdCBzdGFja3MgPSB0aGlzLl9nZXRTdGFja3MoZGF0YXNldEluZGV4LCBkYXRhSW5kZXgpO1xuICAgIGNvbnN0IGluZGV4ID0gKG5hbWUgIT09IHVuZGVmaW5lZClcbiAgICAgID8gc3RhY2tzLmluZGV4T2YobmFtZSlcbiAgICAgIDogLTE7IC8vIGluZGV4T2YgcmV0dXJucyAtMSBpZiBlbGVtZW50IGlzIG5vdCBwcmVzZW50XG5cbiAgICByZXR1cm4gKGluZGV4ID09PSAtMSlcbiAgICAgID8gc3RhY2tzLmxlbmd0aCAtIDFcbiAgICAgIDogaW5kZXg7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRSdWxlcigpIHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGlTY2FsZSA9IG1ldGEuaVNjYWxlO1xuICAgIGNvbnN0IHBpeGVscyA9IFtdO1xuICAgIGxldCBpLCBpbGVuO1xuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IG1ldGEuZGF0YS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHBpeGVscy5wdXNoKGlTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHRoaXMuZ2V0UGFyc2VkKGkpW2lTY2FsZS5heGlzXSwgaSkpO1xuICAgIH1cblxuICAgIGNvbnN0IGJhclRoaWNrbmVzcyA9IG9wdHMuYmFyVGhpY2tuZXNzO1xuICAgIGNvbnN0IG1pbiA9IGJhclRoaWNrbmVzcyB8fCBjb21wdXRlTWluU2FtcGxlU2l6ZShtZXRhKTtcblxuICAgIHJldHVybiB7XG4gICAgICBtaW4sXG4gICAgICBwaXhlbHMsXG4gICAgICBzdGFydDogaVNjYWxlLl9zdGFydFBpeGVsLFxuICAgICAgZW5kOiBpU2NhbGUuX2VuZFBpeGVsLFxuICAgICAgc3RhY2tDb3VudDogdGhpcy5fZ2V0U3RhY2tDb3VudCgpLFxuICAgICAgc2NhbGU6IGlTY2FsZSxcbiAgICAgIGdyb3VwZWQ6IG9wdHMuZ3JvdXBlZCxcbiAgICAgIC8vIGJhciB0aGlja25lc3MgcmF0aW8gdXNlZCBmb3Igbm9uLWdyb3VwZWQgYmFyc1xuICAgICAgcmF0aW86IGJhclRoaWNrbmVzcyA/IDEgOiBvcHRzLmNhdGVnb3J5UGVyY2VudGFnZSAqIG9wdHMuYmFyUGVyY2VudGFnZVxuICAgIH07XG4gIH1cblxuICAvKipcblx0ICogTm90ZTogcGl4ZWwgdmFsdWVzIGFyZSBub3QgY2xhbXBlZCB0byB0aGUgc2NhbGUgYXJlYS5cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9jYWxjdWxhdGVCYXJWYWx1ZVBpeGVscyhpbmRleCkge1xuICAgIGNvbnN0IHtfY2FjaGVkTWV0YToge3ZTY2FsZSwgX3N0YWNrZWQsIGluZGV4OiBkYXRhc2V0SW5kZXh9LCBvcHRpb25zOiB7YmFzZTogYmFzZVZhbHVlLCBtaW5CYXJMZW5ndGh9fSA9IHRoaXM7XG4gICAgY29uc3QgYWN0dWFsQmFzZSA9IGJhc2VWYWx1ZSB8fCAwO1xuICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGluZGV4KTtcbiAgICBjb25zdCBjdXN0b20gPSBwYXJzZWQuX2N1c3RvbTtcbiAgICBjb25zdCBmbG9hdGluZyA9IGlzRmxvYXRCYXIoY3VzdG9tKTtcbiAgICBsZXQgdmFsdWUgPSBwYXJzZWRbdlNjYWxlLmF4aXNdO1xuICAgIGxldCBzdGFydCA9IDA7XG4gICAgbGV0IGxlbmd0aCA9IF9zdGFja2VkID8gdGhpcy5hcHBseVN0YWNrKHZTY2FsZSwgcGFyc2VkLCBfc3RhY2tlZCkgOiB2YWx1ZTtcbiAgICBsZXQgaGVhZCwgc2l6ZTtcblxuICAgIGlmIChsZW5ndGggIT09IHZhbHVlKSB7XG4gICAgICBzdGFydCA9IGxlbmd0aCAtIHZhbHVlO1xuICAgICAgbGVuZ3RoID0gdmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKGZsb2F0aW5nKSB7XG4gICAgICB2YWx1ZSA9IGN1c3RvbS5iYXJTdGFydDtcbiAgICAgIGxlbmd0aCA9IGN1c3RvbS5iYXJFbmQgLSBjdXN0b20uYmFyU3RhcnQ7XG4gICAgICAvLyBiYXJzIGNyb3NzaW5nIG9yaWdpbiBhcmUgbm90IHN0YWNrZWRcbiAgICAgIGlmICh2YWx1ZSAhPT0gMCAmJiBzaWduKHZhbHVlKSAhPT0gc2lnbihjdXN0b20uYmFyRW5kKSkge1xuICAgICAgICBzdGFydCA9IDA7XG4gICAgICB9XG4gICAgICBzdGFydCArPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFydFZhbHVlID0gIWlzTnVsbE9yVW5kZWYoYmFzZVZhbHVlKSAmJiAhZmxvYXRpbmcgPyBiYXNlVmFsdWUgOiBzdGFydDtcbiAgICBsZXQgYmFzZSA9IHZTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHN0YXJ0VmFsdWUpO1xuXG4gICAgaWYgKHRoaXMuY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaW5kZXgpKSB7XG4gICAgICBoZWFkID0gdlNjYWxlLmdldFBpeGVsRm9yVmFsdWUoc3RhcnQgKyBsZW5ndGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXaGVuIG5vdCB2aXNpYmxlLCBubyBoZWlnaHRcbiAgICAgIGhlYWQgPSBiYXNlO1xuICAgIH1cblxuICAgIHNpemUgPSBoZWFkIC0gYmFzZTtcblxuICAgIGlmIChNYXRoLmFicyhzaXplKSA8IG1pbkJhckxlbmd0aCkge1xuICAgICAgc2l6ZSA9IGJhclNpZ24oc2l6ZSwgdlNjYWxlLCBhY3R1YWxCYXNlKSAqIG1pbkJhckxlbmd0aDtcbiAgICAgIGlmICh2YWx1ZSA9PT0gYWN0dWFsQmFzZSkge1xuICAgICAgICBiYXNlIC09IHNpemUgLyAyO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhcnRQaXhlbCA9IHZTY2FsZS5nZXRQaXhlbEZvckRlY2ltYWwoMCk7XG4gICAgICBjb25zdCBlbmRQaXhlbCA9IHZTY2FsZS5nZXRQaXhlbEZvckRlY2ltYWwoMSk7XG4gICAgICBjb25zdCBtaW4gPSBNYXRoLm1pbihzdGFydFBpeGVsLCBlbmRQaXhlbCk7XG4gICAgICBjb25zdCBtYXggPSBNYXRoLm1heChzdGFydFBpeGVsLCBlbmRQaXhlbCk7XG4gICAgICBiYXNlID0gTWF0aC5tYXgoTWF0aC5taW4oYmFzZSwgbWF4KSwgbWluKTtcbiAgICAgIGhlYWQgPSBiYXNlICsgc2l6ZTtcblxuICAgICAgaWYgKF9zdGFja2VkICYmICFmbG9hdGluZykge1xuICAgICAgICAvLyB2aXN1YWwgZGF0YSBjb29yZGluYXRlcyBhZnRlciBhcHBseWluZyBtaW5CYXJMZW5ndGhcbiAgICAgICAgcGFyc2VkLl9zdGFja3NbdlNjYWxlLmF4aXNdLl92aXN1YWxWYWx1ZXNbZGF0YXNldEluZGV4XSA9IHZTY2FsZS5nZXRWYWx1ZUZvclBpeGVsKGhlYWQpIC0gdlNjYWxlLmdldFZhbHVlRm9yUGl4ZWwoYmFzZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGJhc2UgPT09IHZTY2FsZS5nZXRQaXhlbEZvclZhbHVlKGFjdHVhbEJhc2UpKSB7XG4gICAgICBjb25zdCBoYWxmR3JpZCA9IHNpZ24oc2l6ZSkgKiB2U2NhbGUuZ2V0TGluZVdpZHRoRm9yVmFsdWUoYWN0dWFsQmFzZSkgLyAyO1xuICAgICAgYmFzZSArPSBoYWxmR3JpZDtcbiAgICAgIHNpemUgLT0gaGFsZkdyaWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHNpemUsXG4gICAgICBiYXNlLFxuICAgICAgaGVhZCxcbiAgICAgIGNlbnRlcjogaGVhZCArIHNpemUgLyAyXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2NhbGN1bGF0ZUJhckluZGV4UGl4ZWxzKGluZGV4LCBydWxlcikge1xuICAgIGNvbnN0IHNjYWxlID0gcnVsZXIuc2NhbGU7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBza2lwTnVsbCA9IG9wdGlvbnMuc2tpcE51bGw7XG4gICAgY29uc3QgbWF4QmFyVGhpY2tuZXNzID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy5tYXhCYXJUaGlja25lc3MsIEluZmluaXR5KTtcbiAgICBsZXQgY2VudGVyLCBzaXplO1xuICAgIGlmIChydWxlci5ncm91cGVkKSB7XG4gICAgICBjb25zdCBzdGFja0NvdW50ID0gc2tpcE51bGwgPyB0aGlzLl9nZXRTdGFja0NvdW50KGluZGV4KSA6IHJ1bGVyLnN0YWNrQ291bnQ7XG4gICAgICBjb25zdCByYW5nZSA9IG9wdGlvbnMuYmFyVGhpY2tuZXNzID09PSAnZmxleCdcbiAgICAgICAgPyBjb21wdXRlRmxleENhdGVnb3J5VHJhaXRzKGluZGV4LCBydWxlciwgb3B0aW9ucywgc3RhY2tDb3VudClcbiAgICAgICAgOiBjb21wdXRlRml0Q2F0ZWdvcnlUcmFpdHMoaW5kZXgsIHJ1bGVyLCBvcHRpb25zLCBzdGFja0NvdW50KTtcblxuICAgICAgY29uc3Qgc3RhY2tJbmRleCA9IHRoaXMuX2dldFN0YWNrSW5kZXgodGhpcy5pbmRleCwgdGhpcy5fY2FjaGVkTWV0YS5zdGFjaywgc2tpcE51bGwgPyBpbmRleCA6IHVuZGVmaW5lZCk7XG4gICAgICBjZW50ZXIgPSByYW5nZS5zdGFydCArIChyYW5nZS5jaHVuayAqIHN0YWNrSW5kZXgpICsgKHJhbmdlLmNodW5rIC8gMik7XG4gICAgICBzaXplID0gTWF0aC5taW4obWF4QmFyVGhpY2tuZXNzLCByYW5nZS5jaHVuayAqIHJhbmdlLnJhdGlvKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRm9yIG5vbi1ncm91cGVkIGJhciBjaGFydHMsIGV4YWN0IHBpeGVsIHZhbHVlcyBhcmUgdXNlZFxuICAgICAgY2VudGVyID0gc2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZSh0aGlzLmdldFBhcnNlZChpbmRleClbc2NhbGUuYXhpc10sIGluZGV4KTtcbiAgICAgIHNpemUgPSBNYXRoLm1pbihtYXhCYXJUaGlja25lc3MsIHJ1bGVyLm1pbiAqIHJ1bGVyLnJhdGlvKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYmFzZTogY2VudGVyIC0gc2l6ZSAvIDIsXG4gICAgICBoZWFkOiBjZW50ZXIgKyBzaXplIC8gMixcbiAgICAgIGNlbnRlcixcbiAgICAgIHNpemVcbiAgICB9O1xuICB9XG5cbiAgZHJhdygpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCB2U2NhbGUgPSBtZXRhLnZTY2FsZTtcbiAgICBjb25zdCByZWN0cyA9IG1ldGEuZGF0YTtcbiAgICBjb25zdCBpbGVuID0gcmVjdHMubGVuZ3RoO1xuICAgIGxldCBpID0gMDtcblxuICAgIGZvciAoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBpZiAodGhpcy5nZXRQYXJzZWQoaSlbdlNjYWxlLmF4aXNdICE9PSBudWxsKSB7XG4gICAgICAgIHJlY3RzW2ldLmRyYXcodGhpcy5fY3R4KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxufVxuIiwgImltcG9ydCBEYXRhc2V0Q29udHJvbGxlciBmcm9tICcuLi9jb3JlL2NvcmUuZGF0YXNldENvbnRyb2xsZXIuanMnO1xuaW1wb3J0IHt2YWx1ZU9yRGVmYXVsdH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdWJibGVDb250cm9sbGVyIGV4dGVuZHMgRGF0YXNldENvbnRyb2xsZXIge1xuXG4gIHN0YXRpYyBpZCA9ICdidWJibGUnO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIGRhdGFzZXRFbGVtZW50VHlwZTogZmFsc2UsXG4gICAgZGF0YUVsZW1lbnRUeXBlOiAncG9pbnQnLFxuXG4gICAgYW5pbWF0aW9uczoge1xuICAgICAgbnVtYmVyczoge1xuICAgICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgICAgcHJvcGVydGllczogWyd4JywgJ3knLCAnYm9yZGVyV2lkdGgnLCAncmFkaXVzJ11cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgb3ZlcnJpZGVzID0ge1xuICAgIHNjYWxlczoge1xuICAgICAgeDoge1xuICAgICAgICB0eXBlOiAnbGluZWFyJ1xuICAgICAgfSxcbiAgICAgIHk6IHtcbiAgICAgICAgdHlwZTogJ2xpbmVhcidcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgaW5pdGlhbGl6ZSgpIHtcbiAgICB0aGlzLmVuYWJsZU9wdGlvblNoYXJpbmcgPSB0cnVlO1xuICAgIHN1cGVyLmluaXRpYWxpemUoKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBQYXJzZSBhcnJheSBvZiBwcmltaXRpdmUgdmFsdWVzXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHBhcnNlUHJpbWl0aXZlRGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICBjb25zdCBwYXJzZWQgPSBzdXBlci5wYXJzZVByaW1pdGl2ZURhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnNlZC5sZW5ndGg7IGkrKykge1xuICAgICAgcGFyc2VkW2ldLl9jdXN0b20gPSB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSArIHN0YXJ0KS5yYWRpdXM7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICAvKipcblx0ICogUGFyc2UgYXJyYXkgb2YgYXJyYXlzXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHBhcnNlQXJyYXlEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IHBhcnNlZCA9IHN1cGVyLnBhcnNlQXJyYXlEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJzZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBkYXRhW3N0YXJ0ICsgaV07XG4gICAgICBwYXJzZWRbaV0uX2N1c3RvbSA9IHZhbHVlT3JEZWZhdWx0KGl0ZW1bMl0sIHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpICsgc3RhcnQpLnJhZGl1cyk7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICAvKipcblx0ICogUGFyc2UgYXJyYXkgb2Ygb2JqZWN0c1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBwYXJzZU9iamVjdERhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgY29uc3QgcGFyc2VkID0gc3VwZXIucGFyc2VPYmplY3REYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJzZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBkYXRhW3N0YXJ0ICsgaV07XG4gICAgICBwYXJzZWRbaV0uX2N1c3RvbSA9IHZhbHVlT3JEZWZhdWx0KGl0ZW0gJiYgaXRlbS5yICYmICtpdGVtLnIsIHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpICsgc3RhcnQpLnJhZGl1cyk7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0TWF4T3ZlcmZsb3coKSB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuX2NhY2hlZE1ldGEuZGF0YTtcblxuICAgIGxldCBtYXggPSAwO1xuICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBtYXggPSBNYXRoLm1heChtYXgsIGRhdGFbaV0uc2l6ZSh0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSkpIC8gMik7XG4gICAgfVxuICAgIHJldHVybiBtYXggPiAwICYmIG1heDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRMYWJlbEFuZFZhbHVlKGluZGV4KSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgbGFiZWxzID0gdGhpcy5jaGFydC5kYXRhLmxhYmVscyB8fCBbXTtcbiAgICBjb25zdCB7eFNjYWxlLCB5U2NhbGV9ID0gbWV0YTtcbiAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG4gICAgY29uc3QgeCA9IHhTY2FsZS5nZXRMYWJlbEZvclZhbHVlKHBhcnNlZC54KTtcbiAgICBjb25zdCB5ID0geVNjYWxlLmdldExhYmVsRm9yVmFsdWUocGFyc2VkLnkpO1xuICAgIGNvbnN0IHIgPSBwYXJzZWQuX2N1c3RvbTtcblxuICAgIHJldHVybiB7XG4gICAgICBsYWJlbDogbGFiZWxzW2luZGV4XSB8fCAnJyxcbiAgICAgIHZhbHVlOiAnKCcgKyB4ICsgJywgJyArIHkgKyAociA/ICcsICcgKyByIDogJycpICsgJyknXG4gICAgfTtcbiAgfVxuXG4gIHVwZGF0ZShtb2RlKSB7XG4gICAgY29uc3QgcG9pbnRzID0gdGhpcy5fY2FjaGVkTWV0YS5kYXRhO1xuXG4gICAgLy8gVXBkYXRlIFBvaW50c1xuICAgIHRoaXMudXBkYXRlRWxlbWVudHMocG9pbnRzLCAwLCBwb2ludHMubGVuZ3RoLCBtb2RlKTtcbiAgfVxuXG4gIHVwZGF0ZUVsZW1lbnRzKHBvaW50cywgc3RhcnQsIGNvdW50LCBtb2RlKSB7XG4gICAgY29uc3QgcmVzZXQgPSBtb2RlID09PSAncmVzZXQnO1xuICAgIGNvbnN0IHtpU2NhbGUsIHZTY2FsZX0gPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IHtzaGFyZWRPcHRpb25zLCBpbmNsdWRlT3B0aW9uc30gPSB0aGlzLl9nZXRTaGFyZWRPcHRpb25zKHN0YXJ0LCBtb2RlKTtcbiAgICBjb25zdCBpQXhpcyA9IGlTY2FsZS5heGlzO1xuICAgIGNvbnN0IHZBeGlzID0gdlNjYWxlLmF4aXM7XG5cbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBzdGFydCArIGNvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgY29uc3QgcGFyc2VkID0gIXJlc2V0ICYmIHRoaXMuZ2V0UGFyc2VkKGkpO1xuICAgICAgY29uc3QgcHJvcGVydGllcyA9IHt9O1xuICAgICAgY29uc3QgaVBpeGVsID0gcHJvcGVydGllc1tpQXhpc10gPSByZXNldCA/IGlTY2FsZS5nZXRQaXhlbEZvckRlY2ltYWwoMC41KSA6IGlTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHBhcnNlZFtpQXhpc10pO1xuICAgICAgY29uc3QgdlBpeGVsID0gcHJvcGVydGllc1t2QXhpc10gPSByZXNldCA/IHZTY2FsZS5nZXRCYXNlUGl4ZWwoKSA6IHZTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHBhcnNlZFt2QXhpc10pO1xuXG4gICAgICBwcm9wZXJ0aWVzLnNraXAgPSBpc05hTihpUGl4ZWwpIHx8IGlzTmFOKHZQaXhlbCk7XG5cbiAgICAgIGlmIChpbmNsdWRlT3B0aW9ucykge1xuICAgICAgICBwcm9wZXJ0aWVzLm9wdGlvbnMgPSBzaGFyZWRPcHRpb25zIHx8IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpLCBwb2ludC5hY3RpdmUgPyAnYWN0aXZlJyA6IG1vZGUpO1xuXG4gICAgICAgIGlmIChyZXNldCkge1xuICAgICAgICAgIHByb3BlcnRpZXMub3B0aW9ucy5yYWRpdXMgPSAwO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMudXBkYXRlRWxlbWVudChwb2ludCwgaSwgcHJvcGVydGllcywgbW9kZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gW21vZGVdXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaW5kZXgsIG1vZGUpIHtcbiAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG4gICAgbGV0IHZhbHVlcyA9IHN1cGVyLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaW5kZXgsIG1vZGUpO1xuXG4gICAgLy8gSW4gY2FzZSB2YWx1ZXMgd2VyZSBjYWNoZWQgKGFuZCB0aHVzIGZyb3plbiksIHdlIG5lZWQgdG8gY2xvbmUgdGhlIHZhbHVlc1xuICAgIGlmICh2YWx1ZXMuJHNoYXJlZCkge1xuICAgICAgdmFsdWVzID0gT2JqZWN0LmFzc2lnbih7fSwgdmFsdWVzLCB7JHNoYXJlZDogZmFsc2V9KTtcbiAgICB9XG5cbiAgICAvLyBDdXN0b20gcmFkaXVzIHJlc29sdXRpb25cbiAgICBjb25zdCByYWRpdXMgPSB2YWx1ZXMucmFkaXVzO1xuICAgIGlmIChtb2RlICE9PSAnYWN0aXZlJykge1xuICAgICAgdmFsdWVzLnJhZGl1cyA9IDA7XG4gICAgfVxuICAgIHZhbHVlcy5yYWRpdXMgKz0gdmFsdWVPckRlZmF1bHQocGFyc2VkICYmIHBhcnNlZC5fY3VzdG9tLCByYWRpdXMpO1xuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxufVxuIiwgImltcG9ydCBEYXRhc2V0Q29udHJvbGxlciBmcm9tICcuLi9jb3JlL2NvcmUuZGF0YXNldENvbnRyb2xsZXIuanMnO1xuaW1wb3J0IHtpc09iamVjdCwgcmVzb2x2ZU9iamVjdEtleSwgdG9QZXJjZW50YWdlLCB0b0RpbWVuc2lvbiwgdmFsdWVPckRlZmF1bHR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7Zm9ybWF0TnVtYmVyfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuaW50bC5qcyc7XG5pbXBvcnQge3RvUmFkaWFucywgUEksIFRBVSwgSEFMRl9QSSwgX2FuZ2xlQmV0d2Vlbn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi9jb3JlL2NvcmUuY29udHJvbGxlci5qcycpLmRlZmF1bHQgfSBDaGFydFxuICovXG5cbmZ1bmN0aW9uIGdldFJhdGlvQW5kT2Zmc2V0KHJvdGF0aW9uLCBjaXJjdW1mZXJlbmNlLCBjdXRvdXQpIHtcbiAgbGV0IHJhdGlvWCA9IDE7XG4gIGxldCByYXRpb1kgPSAxO1xuICBsZXQgb2Zmc2V0WCA9IDA7XG4gIGxldCBvZmZzZXRZID0gMDtcbiAgLy8gSWYgdGhlIGNoYXJ0J3MgY2lyY3VtZmVyZW5jZSBpc24ndCBhIGZ1bGwgY2lyY2xlLCBjYWxjdWxhdGUgc2l6ZSBhcyBhIHJhdGlvIG9mIHRoZSB3aWR0aC9oZWlnaHQgb2YgdGhlIGFyY1xuICBpZiAoY2lyY3VtZmVyZW5jZSA8IFRBVSkge1xuICAgIGNvbnN0IHN0YXJ0QW5nbGUgPSByb3RhdGlvbjtcbiAgICBjb25zdCBlbmRBbmdsZSA9IHN0YXJ0QW5nbGUgKyBjaXJjdW1mZXJlbmNlO1xuICAgIGNvbnN0IHN0YXJ0WCA9IE1hdGguY29zKHN0YXJ0QW5nbGUpO1xuICAgIGNvbnN0IHN0YXJ0WSA9IE1hdGguc2luKHN0YXJ0QW5nbGUpO1xuICAgIGNvbnN0IGVuZFggPSBNYXRoLmNvcyhlbmRBbmdsZSk7XG4gICAgY29uc3QgZW5kWSA9IE1hdGguc2luKGVuZEFuZ2xlKTtcbiAgICBjb25zdCBjYWxjTWF4ID0gKGFuZ2xlLCBhLCBiKSA9PiBfYW5nbGVCZXR3ZWVuKGFuZ2xlLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgdHJ1ZSkgPyAxIDogTWF0aC5tYXgoYSwgYSAqIGN1dG91dCwgYiwgYiAqIGN1dG91dCk7XG4gICAgY29uc3QgY2FsY01pbiA9IChhbmdsZSwgYSwgYikgPT4gX2FuZ2xlQmV0d2VlbihhbmdsZSwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIHRydWUpID8gLTEgOiBNYXRoLm1pbihhLCBhICogY3V0b3V0LCBiLCBiICogY3V0b3V0KTtcbiAgICBjb25zdCBtYXhYID0gY2FsY01heCgwLCBzdGFydFgsIGVuZFgpO1xuICAgIGNvbnN0IG1heFkgPSBjYWxjTWF4KEhBTEZfUEksIHN0YXJ0WSwgZW5kWSk7XG4gICAgY29uc3QgbWluWCA9IGNhbGNNaW4oUEksIHN0YXJ0WCwgZW5kWCk7XG4gICAgY29uc3QgbWluWSA9IGNhbGNNaW4oUEkgKyBIQUxGX1BJLCBzdGFydFksIGVuZFkpO1xuICAgIHJhdGlvWCA9IChtYXhYIC0gbWluWCkgLyAyO1xuICAgIHJhdGlvWSA9IChtYXhZIC0gbWluWSkgLyAyO1xuICAgIG9mZnNldFggPSAtKG1heFggKyBtaW5YKSAvIDI7XG4gICAgb2Zmc2V0WSA9IC0obWF4WSArIG1pblkpIC8gMjtcbiAgfVxuICByZXR1cm4ge3JhdGlvWCwgcmF0aW9ZLCBvZmZzZXRYLCBvZmZzZXRZfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRG91Z2hudXRDb250cm9sbGVyIGV4dGVuZHMgRGF0YXNldENvbnRyb2xsZXIge1xuXG4gIHN0YXRpYyBpZCA9ICdkb3VnaG51dCc7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgZGF0YXNldEVsZW1lbnRUeXBlOiBmYWxzZSxcbiAgICBkYXRhRWxlbWVudFR5cGU6ICdhcmMnLFxuICAgIGFuaW1hdGlvbjoge1xuICAgICAgLy8gQm9vbGVhbiAtIFdoZXRoZXIgd2UgYW5pbWF0ZSB0aGUgcm90YXRpb24gb2YgdGhlIERvdWdobnV0XG4gICAgICBhbmltYXRlUm90YXRlOiB0cnVlLFxuICAgICAgLy8gQm9vbGVhbiAtIFdoZXRoZXIgd2UgYW5pbWF0ZSBzY2FsaW5nIHRoZSBEb3VnaG51dCBmcm9tIHRoZSBjZW50cmVcbiAgICAgIGFuaW1hdGVTY2FsZTogZmFsc2VcbiAgICB9LFxuICAgIGFuaW1hdGlvbnM6IHtcbiAgICAgIG51bWJlcnM6IHtcbiAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgIHByb3BlcnRpZXM6IFsnY2lyY3VtZmVyZW5jZScsICdlbmRBbmdsZScsICdpbm5lclJhZGl1cycsICdvdXRlclJhZGl1cycsICdzdGFydEFuZ2xlJywgJ3gnLCAneScsICdvZmZzZXQnLCAnYm9yZGVyV2lkdGgnLCAnc3BhY2luZyddXG4gICAgICB9LFxuICAgIH0sXG4gICAgLy8gVGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIGNoYXJ0IHRoYXQgd2UgY3V0IG91dCBvZiB0aGUgbWlkZGxlLlxuICAgIGN1dG91dDogJzUwJScsXG5cbiAgICAvLyBUaGUgcm90YXRpb24gb2YgdGhlIGNoYXJ0LCB3aGVyZSB0aGUgZmlyc3QgZGF0YSBhcmMgYmVnaW5zLlxuICAgIHJvdGF0aW9uOiAwLFxuXG4gICAgLy8gVGhlIHRvdGFsIGNpcmN1bWZlcmVuY2Ugb2YgdGhlIGNoYXJ0LlxuICAgIGNpcmN1bWZlcmVuY2U6IDM2MCxcblxuICAgIC8vIFRoZSBvdXRlciByYWRpdXMgb2YgdGhlIGNoYXJ0XG4gICAgcmFkaXVzOiAnMTAwJScsXG5cbiAgICAvLyBTcGFjaW5nIGJldHdlZW4gYXJjc1xuICAgIHNwYWNpbmc6IDAsXG5cbiAgICBpbmRleEF4aXM6ICdyJyxcbiAgfTtcblxuICBzdGF0aWMgZGVzY3JpcHRvcnMgPSB7XG4gICAgX3NjcmlwdGFibGU6IChuYW1lKSA9PiBuYW1lICE9PSAnc3BhY2luZycsXG4gICAgX2luZGV4YWJsZTogKG5hbWUpID0+IG5hbWUgIT09ICdzcGFjaW5nJyAmJiAhbmFtZS5zdGFydHNXaXRoKCdib3JkZXJEYXNoJykgJiYgIW5hbWUuc3RhcnRzV2l0aCgnaG92ZXJCb3JkZXJEYXNoJyksXG4gIH07XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgb3ZlcnJpZGVzID0ge1xuICAgIGFzcGVjdFJhdGlvOiAxLFxuXG4gICAgLy8gTmVlZCB0byBvdmVycmlkZSB0aGVzZSB0byBnaXZlIGEgbmljZSBkZWZhdWx0XG4gICAgcGx1Z2luczoge1xuICAgICAgbGVnZW5kOiB7XG4gICAgICAgIGxhYmVsczoge1xuICAgICAgICAgIGdlbmVyYXRlTGFiZWxzKGNoYXJ0KSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0gY2hhcnQuZGF0YTtcbiAgICAgICAgICAgIGlmIChkYXRhLmxhYmVscy5sZW5ndGggJiYgZGF0YS5kYXRhc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3Qge2xhYmVsczoge3BvaW50U3R5bGUsIGNvbG9yfX0gPSBjaGFydC5sZWdlbmQub3B0aW9ucztcblxuICAgICAgICAgICAgICByZXR1cm4gZGF0YS5sYWJlbHMubWFwKChsYWJlbCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YSgwKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHlsZSA9IG1ldGEuY29udHJvbGxlci5nZXRTdHlsZShpKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICB0ZXh0OiBsYWJlbCxcbiAgICAgICAgICAgICAgICAgIGZpbGxTdHlsZTogc3R5bGUuYmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICAgICAgICAgc3Ryb2tlU3R5bGU6IHN0eWxlLmJvcmRlckNvbG9yLFxuICAgICAgICAgICAgICAgICAgZm9udENvbG9yOiBjb2xvcixcbiAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGUuYm9yZGVyV2lkdGgsXG4gICAgICAgICAgICAgICAgICBwb2ludFN0eWxlOiBwb2ludFN0eWxlLFxuICAgICAgICAgICAgICAgICAgaGlkZGVuOiAhY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaSksXG5cbiAgICAgICAgICAgICAgICAgIC8vIEV4dHJhIGRhdGEgdXNlZCBmb3IgdG9nZ2xpbmcgdGhlIGNvcnJlY3QgaXRlbVxuICAgICAgICAgICAgICAgICAgaW5kZXg6IGlcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgb25DbGljayhlLCBsZWdlbmRJdGVtLCBsZWdlbmQpIHtcbiAgICAgICAgICBsZWdlbmQuY2hhcnQudG9nZ2xlRGF0YVZpc2liaWxpdHkobGVnZW5kSXRlbS5pbmRleCk7XG4gICAgICAgICAgbGVnZW5kLmNoYXJ0LnVwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKGNoYXJ0LCBkYXRhc2V0SW5kZXgpIHtcbiAgICBzdXBlcihjaGFydCwgZGF0YXNldEluZGV4KTtcblxuICAgIHRoaXMuZW5hYmxlT3B0aW9uU2hhcmluZyA9IHRydWU7XG4gICAgdGhpcy5pbm5lclJhZGl1cyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm91dGVyUmFkaXVzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMub2Zmc2V0WCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm9mZnNldFkgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBsaW5rU2NhbGVzKCkge31cblxuICAvKipcblx0ICogT3ZlcnJpZGUgZGF0YSBwYXJzaW5nLCBzaW5jZSB3ZSBhcmUgbm90IHVzaW5nIHNjYWxlc1xuXHQgKi9cbiAgcGFyc2Uoc3RhcnQsIGNvdW50KSB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZ2V0RGF0YXNldCgpLmRhdGE7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG5cbiAgICBpZiAodGhpcy5fcGFyc2luZyA9PT0gZmFsc2UpIHtcbiAgICAgIG1ldGEuX3BhcnNlZCA9IGRhdGE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBnZXR0ZXIgPSAoaSkgPT4gK2RhdGFbaV07XG5cbiAgICAgIGlmIChpc09iamVjdChkYXRhW3N0YXJ0XSkpIHtcbiAgICAgICAgY29uc3Qge2tleSA9ICd2YWx1ZSd9ID0gdGhpcy5fcGFyc2luZztcbiAgICAgICAgZ2V0dGVyID0gKGkpID0+ICtyZXNvbHZlT2JqZWN0S2V5KGRhdGFbaV0sIGtleSk7XG4gICAgICB9XG5cbiAgICAgIGxldCBpLCBpbGVuO1xuICAgICAgZm9yIChpID0gc3RhcnQsIGlsZW4gPSBzdGFydCArIGNvdW50OyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICAgIG1ldGEuX3BhcnNlZFtpXSA9IGdldHRlcihpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRSb3RhdGlvbigpIHtcbiAgICByZXR1cm4gdG9SYWRpYW5zKHRoaXMub3B0aW9ucy5yb3RhdGlvbiAtIDkwKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldENpcmN1bWZlcmVuY2UoKSB7XG4gICAgcmV0dXJuIHRvUmFkaWFucyh0aGlzLm9wdGlvbnMuY2lyY3VtZmVyZW5jZSk7XG4gIH1cblxuICAvKipcblx0ICogR2V0IHRoZSBtYXhpbWFsIHJvdGF0aW9uICYgY2lyY3VtZmVyZW5jZSBleHRlbnRzXG5cdCAqIGFjcm9zcyBhbGwgdmlzaWJsZSBkYXRhc2V0cy5cblx0ICovXG4gIF9nZXRSb3RhdGlvbkV4dGVudHMoKSB7XG4gICAgbGV0IG1pbiA9IFRBVTtcbiAgICBsZXQgbWF4ID0gLVRBVTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAodGhpcy5jaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpICYmIHRoaXMuY2hhcnQuZ2V0RGF0YXNldE1ldGEoaSkudHlwZSA9PT0gdGhpcy5fdHlwZSkge1xuICAgICAgICBjb25zdCBjb250cm9sbGVyID0gdGhpcy5jaGFydC5nZXREYXRhc2V0TWV0YShpKS5jb250cm9sbGVyO1xuICAgICAgICBjb25zdCByb3RhdGlvbiA9IGNvbnRyb2xsZXIuX2dldFJvdGF0aW9uKCk7XG4gICAgICAgIGNvbnN0IGNpcmN1bWZlcmVuY2UgPSBjb250cm9sbGVyLl9nZXRDaXJjdW1mZXJlbmNlKCk7XG5cbiAgICAgICAgbWluID0gTWF0aC5taW4obWluLCByb3RhdGlvbik7XG4gICAgICAgIG1heCA9IE1hdGgubWF4KG1heCwgcm90YXRpb24gKyBjaXJjdW1mZXJlbmNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcm90YXRpb246IG1pbixcbiAgICAgIGNpcmN1bWZlcmVuY2U6IG1heCAtIG1pbixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBtb2RlXG5cdCAqL1xuICB1cGRhdGUobW9kZSkge1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCB7Y2hhcnRBcmVhfSA9IGNoYXJ0O1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGFyY3MgPSBtZXRhLmRhdGE7XG4gICAgY29uc3Qgc3BhY2luZyA9IHRoaXMuZ2V0TWF4Qm9yZGVyV2lkdGgoKSArIHRoaXMuZ2V0TWF4T2Zmc2V0KGFyY3MpICsgdGhpcy5vcHRpb25zLnNwYWNpbmc7XG4gICAgY29uc3QgbWF4U2l6ZSA9IE1hdGgubWF4KChNYXRoLm1pbihjaGFydEFyZWEud2lkdGgsIGNoYXJ0QXJlYS5oZWlnaHQpIC0gc3BhY2luZykgLyAyLCAwKTtcbiAgICBjb25zdCBjdXRvdXQgPSBNYXRoLm1pbih0b1BlcmNlbnRhZ2UodGhpcy5vcHRpb25zLmN1dG91dCwgbWF4U2l6ZSksIDEpO1xuICAgIGNvbnN0IGNoYXJ0V2VpZ2h0ID0gdGhpcy5fZ2V0UmluZ1dlaWdodCh0aGlzLmluZGV4KTtcblxuICAgIC8vIENvbXB1dGUgdGhlIG1heGltYWwgcm90YXRpb24gJiBjaXJjdW1mZXJlbmNlIGxpbWl0cy5cbiAgICAvLyBJZiB3ZSBvbmx5IGNvbnNpZGVyIG91ciBkYXRhc2V0LCB0aGlzIGNhbiBjYXVzZSBwcm9ibGVtcyB3aGVuIHR3byBkYXRhc2V0c1xuICAgIC8vIGFyZSBib3RoIGxlc3MgdGhhbiBhIGNpcmNsZSB3aXRoIGRpZmZlcmVudCByb3RhdGlvbnMgKHN0YXJ0aW5nIGFuZ2xlcylcbiAgICBjb25zdCB7Y2lyY3VtZmVyZW5jZSwgcm90YXRpb259ID0gdGhpcy5fZ2V0Um90YXRpb25FeHRlbnRzKCk7XG4gICAgY29uc3Qge3JhdGlvWCwgcmF0aW9ZLCBvZmZzZXRYLCBvZmZzZXRZfSA9IGdldFJhdGlvQW5kT2Zmc2V0KHJvdGF0aW9uLCBjaXJjdW1mZXJlbmNlLCBjdXRvdXQpO1xuICAgIGNvbnN0IG1heFdpZHRoID0gKGNoYXJ0QXJlYS53aWR0aCAtIHNwYWNpbmcpIC8gcmF0aW9YO1xuICAgIGNvbnN0IG1heEhlaWdodCA9IChjaGFydEFyZWEuaGVpZ2h0IC0gc3BhY2luZykgLyByYXRpb1k7XG4gICAgY29uc3QgbWF4UmFkaXVzID0gTWF0aC5tYXgoTWF0aC5taW4obWF4V2lkdGgsIG1heEhlaWdodCkgLyAyLCAwKTtcbiAgICBjb25zdCBvdXRlclJhZGl1cyA9IHRvRGltZW5zaW9uKHRoaXMub3B0aW9ucy5yYWRpdXMsIG1heFJhZGl1cyk7XG4gICAgY29uc3QgaW5uZXJSYWRpdXMgPSBNYXRoLm1heChvdXRlclJhZGl1cyAqIGN1dG91dCwgMCk7XG4gICAgY29uc3QgcmFkaXVzTGVuZ3RoID0gKG91dGVyUmFkaXVzIC0gaW5uZXJSYWRpdXMpIC8gdGhpcy5fZ2V0VmlzaWJsZURhdGFzZXRXZWlnaHRUb3RhbCgpO1xuICAgIHRoaXMub2Zmc2V0WCA9IG9mZnNldFggKiBvdXRlclJhZGl1cztcbiAgICB0aGlzLm9mZnNldFkgPSBvZmZzZXRZICogb3V0ZXJSYWRpdXM7XG5cbiAgICBtZXRhLnRvdGFsID0gdGhpcy5jYWxjdWxhdGVUb3RhbCgpO1xuXG4gICAgdGhpcy5vdXRlclJhZGl1cyA9IG91dGVyUmFkaXVzIC0gcmFkaXVzTGVuZ3RoICogdGhpcy5fZ2V0UmluZ1dlaWdodE9mZnNldCh0aGlzLmluZGV4KTtcbiAgICB0aGlzLmlubmVyUmFkaXVzID0gTWF0aC5tYXgodGhpcy5vdXRlclJhZGl1cyAtIHJhZGl1c0xlbmd0aCAqIGNoYXJ0V2VpZ2h0LCAwKTtcblxuICAgIHRoaXMudXBkYXRlRWxlbWVudHMoYXJjcywgMCwgYXJjcy5sZW5ndGgsIG1vZGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfY2lyY3VtZmVyZW5jZShpLCByZXNldCkge1xuICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgY2lyY3VtZmVyZW5jZSA9IHRoaXMuX2dldENpcmN1bWZlcmVuY2UoKTtcbiAgICBpZiAoKHJlc2V0ICYmIG9wdHMuYW5pbWF0aW9uLmFuaW1hdGVSb3RhdGUpIHx8ICF0aGlzLmNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGkpIHx8IG1ldGEuX3BhcnNlZFtpXSA9PT0gbnVsbCB8fCBtZXRhLmRhdGFbaV0uaGlkZGVuKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FsY3VsYXRlQ2lyY3VtZmVyZW5jZShtZXRhLl9wYXJzZWRbaV0gKiBjaXJjdW1mZXJlbmNlIC8gVEFVKTtcbiAgfVxuXG4gIHVwZGF0ZUVsZW1lbnRzKGFyY3MsIHN0YXJ0LCBjb3VudCwgbW9kZSkge1xuICAgIGNvbnN0IHJlc2V0ID0gbW9kZSA9PT0gJ3Jlc2V0JztcbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3QgY2hhcnRBcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xuICAgIGNvbnN0IG9wdHMgPSBjaGFydC5vcHRpb25zO1xuICAgIGNvbnN0IGFuaW1hdGlvbk9wdHMgPSBvcHRzLmFuaW1hdGlvbjtcbiAgICBjb25zdCBjZW50ZXJYID0gKGNoYXJ0QXJlYS5sZWZ0ICsgY2hhcnRBcmVhLnJpZ2h0KSAvIDI7XG4gICAgY29uc3QgY2VudGVyWSA9IChjaGFydEFyZWEudG9wICsgY2hhcnRBcmVhLmJvdHRvbSkgLyAyO1xuICAgIGNvbnN0IGFuaW1hdGVTY2FsZSA9IHJlc2V0ICYmIGFuaW1hdGlvbk9wdHMuYW5pbWF0ZVNjYWxlO1xuICAgIGNvbnN0IGlubmVyUmFkaXVzID0gYW5pbWF0ZVNjYWxlID8gMCA6IHRoaXMuaW5uZXJSYWRpdXM7XG4gICAgY29uc3Qgb3V0ZXJSYWRpdXMgPSBhbmltYXRlU2NhbGUgPyAwIDogdGhpcy5vdXRlclJhZGl1cztcbiAgICBjb25zdCB7c2hhcmVkT3B0aW9ucywgaW5jbHVkZU9wdGlvbnN9ID0gdGhpcy5fZ2V0U2hhcmVkT3B0aW9ucyhzdGFydCwgbW9kZSk7XG4gICAgbGV0IHN0YXJ0QW5nbGUgPSB0aGlzLl9nZXRSb3RhdGlvbigpO1xuICAgIGxldCBpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHN0YXJ0OyArK2kpIHtcbiAgICAgIHN0YXJ0QW5nbGUgKz0gdGhpcy5fY2lyY3VtZmVyZW5jZShpLCByZXNldCk7XG4gICAgfVxuXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBzdGFydCArIGNvdW50OyArK2kpIHtcbiAgICAgIGNvbnN0IGNpcmN1bWZlcmVuY2UgPSB0aGlzLl9jaXJjdW1mZXJlbmNlKGksIHJlc2V0KTtcbiAgICAgIGNvbnN0IGFyYyA9IGFyY3NbaV07XG4gICAgICBjb25zdCBwcm9wZXJ0aWVzID0ge1xuICAgICAgICB4OiBjZW50ZXJYICsgdGhpcy5vZmZzZXRYLFxuICAgICAgICB5OiBjZW50ZXJZICsgdGhpcy5vZmZzZXRZLFxuICAgICAgICBzdGFydEFuZ2xlLFxuICAgICAgICBlbmRBbmdsZTogc3RhcnRBbmdsZSArIGNpcmN1bWZlcmVuY2UsXG4gICAgICAgIGNpcmN1bWZlcmVuY2UsXG4gICAgICAgIG91dGVyUmFkaXVzLFxuICAgICAgICBpbm5lclJhZGl1c1xuICAgICAgfTtcbiAgICAgIGlmIChpbmNsdWRlT3B0aW9ucykge1xuICAgICAgICBwcm9wZXJ0aWVzLm9wdGlvbnMgPSBzaGFyZWRPcHRpb25zIHx8IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpLCBhcmMuYWN0aXZlID8gJ2FjdGl2ZScgOiBtb2RlKTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0QW5nbGUgKz0gY2lyY3VtZmVyZW5jZTtcblxuICAgICAgdGhpcy51cGRhdGVFbGVtZW50KGFyYywgaSwgcHJvcGVydGllcywgbW9kZSk7XG4gICAgfVxuICB9XG5cbiAgY2FsY3VsYXRlVG90YWwoKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgbWV0YURhdGEgPSBtZXRhLmRhdGE7XG4gICAgbGV0IHRvdGFsID0gMDtcbiAgICBsZXQgaTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBtZXRhRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdmFsdWUgPSBtZXRhLl9wYXJzZWRbaV07XG4gICAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgIWlzTmFOKHZhbHVlKSAmJiB0aGlzLmNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGkpICYmICFtZXRhRGF0YVtpXS5oaWRkZW4pIHtcbiAgICAgICAgdG90YWwgKz0gTWF0aC5hYnModmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0b3RhbDtcbiAgfVxuXG4gIGNhbGN1bGF0ZUNpcmN1bWZlcmVuY2UodmFsdWUpIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMuX2NhY2hlZE1ldGEudG90YWw7XG4gICAgaWYgKHRvdGFsID4gMCAmJiAhaXNOYU4odmFsdWUpKSB7XG4gICAgICByZXR1cm4gVEFVICogKE1hdGguYWJzKHZhbHVlKSAvIHRvdGFsKTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBnZXRMYWJlbEFuZFZhbHVlKGluZGV4KSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgIGNvbnN0IGxhYmVscyA9IGNoYXJ0LmRhdGEubGFiZWxzIHx8IFtdO1xuICAgIGNvbnN0IHZhbHVlID0gZm9ybWF0TnVtYmVyKG1ldGEuX3BhcnNlZFtpbmRleF0sIGNoYXJ0Lm9wdGlvbnMubG9jYWxlKTtcblxuICAgIHJldHVybiB7XG4gICAgICBsYWJlbDogbGFiZWxzW2luZGV4XSB8fCAnJyxcbiAgICAgIHZhbHVlLFxuICAgIH07XG4gIH1cblxuICBnZXRNYXhCb3JkZXJXaWR0aChhcmNzKSB7XG4gICAgbGV0IG1heCA9IDA7XG4gICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgIGxldCBpLCBpbGVuLCBtZXRhLCBjb250cm9sbGVyLCBvcHRpb25zO1xuXG4gICAgaWYgKCFhcmNzKSB7XG4gICAgICAvLyBGaW5kIHRoZSBvdXRtb3N0IHZpc2libGUgZGF0YXNldFxuICAgICAgZm9yIChpID0gMCwgaWxlbiA9IGNoYXJ0LmRhdGEuZGF0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICAgIGlmIChjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpKSB7XG4gICAgICAgICAgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGkpO1xuICAgICAgICAgIGFyY3MgPSBtZXRhLmRhdGE7XG4gICAgICAgICAgY29udHJvbGxlciA9IG1ldGEuY29udHJvbGxlcjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghYXJjcykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IGFyY3MubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBvcHRpb25zID0gY29udHJvbGxlci5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGkpO1xuICAgICAgaWYgKG9wdGlvbnMuYm9yZGVyQWxpZ24gIT09ICdpbm5lcicpIHtcbiAgICAgICAgbWF4ID0gTWF0aC5tYXgobWF4LCBvcHRpb25zLmJvcmRlcldpZHRoIHx8IDAsIG9wdGlvbnMuaG92ZXJCb3JkZXJXaWR0aCB8fCAwKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1heDtcbiAgfVxuXG4gIGdldE1heE9mZnNldChhcmNzKSB7XG4gICAgbGV0IG1heCA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMCwgaWxlbiA9IGFyY3MubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGkpO1xuICAgICAgbWF4ID0gTWF0aC5tYXgobWF4LCBvcHRpb25zLm9mZnNldCB8fCAwLCBvcHRpb25zLmhvdmVyT2Zmc2V0IHx8IDApO1xuICAgIH1cbiAgICByZXR1cm4gbWF4O1xuICB9XG5cbiAgLyoqXG5cdCAqIEdldCByYWRpdXMgbGVuZ3RoIG9mZnNldCBvZiB0aGUgZGF0YXNldCBpbiByZWxhdGlvbiB0byB0aGUgdmlzaWJsZSBkYXRhc2V0cyB3ZWlnaHRzLiBUaGlzIGFsbG93cyBkZXRlcm1pbmluZyB0aGUgaW5uZXIgYW5kIG91dGVyIHJhZGl1cyBjb3JyZWN0bHlcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRSaW5nV2VpZ2h0T2Zmc2V0KGRhdGFzZXRJbmRleCkge1xuICAgIGxldCByaW5nV2VpZ2h0T2Zmc2V0ID0gMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YXNldEluZGV4OyArK2kpIHtcbiAgICAgIGlmICh0aGlzLmNoYXJ0LmlzRGF0YXNldFZpc2libGUoaSkpIHtcbiAgICAgICAgcmluZ1dlaWdodE9mZnNldCArPSB0aGlzLl9nZXRSaW5nV2VpZ2h0KGkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByaW5nV2VpZ2h0T2Zmc2V0O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0UmluZ1dlaWdodChkYXRhc2V0SW5kZXgpIHtcbiAgICByZXR1cm4gTWF0aC5tYXgodmFsdWVPckRlZmF1bHQodGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzW2RhdGFzZXRJbmRleF0ud2VpZ2h0LCAxKSwgMCk7XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB0aGUgc3VtIG9mIGFsbCB2aXNpYmxlIGRhdGEgc2V0IHdlaWdodHMuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0VmlzaWJsZURhdGFzZXRXZWlnaHRUb3RhbCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0UmluZ1dlaWdodE9mZnNldCh0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHMubGVuZ3RoKSB8fCAxO1xuICB9XG59XG4iLCAiaW1wb3J0IERhdGFzZXRDb250cm9sbGVyIGZyb20gJy4uL2NvcmUvY29yZS5kYXRhc2V0Q29udHJvbGxlci5qcyc7XG5pbXBvcnQge2lzTnVsbE9yVW5kZWZ9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuaW1wb3J0IHtpc051bWJlcn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IHtfZ2V0U3RhcnRBbmRDb3VudE9mVmlzaWJsZVBvaW50cywgX3NjYWxlUmFuZ2VzQ2hhbmdlZH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmV4dHJhcy5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpbmVDb250cm9sbGVyIGV4dGVuZHMgRGF0YXNldENvbnRyb2xsZXIge1xuXG4gIHN0YXRpYyBpZCA9ICdsaW5lJztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICBkYXRhc2V0RWxlbWVudFR5cGU6ICdsaW5lJyxcbiAgICBkYXRhRWxlbWVudFR5cGU6ICdwb2ludCcsXG5cbiAgICBzaG93TGluZTogdHJ1ZSxcbiAgICBzcGFuR2FwczogZmFsc2UsXG4gIH07XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgb3ZlcnJpZGVzID0ge1xuICAgIHNjYWxlczoge1xuICAgICAgX2luZGV4Xzoge1xuICAgICAgICB0eXBlOiAnY2F0ZWdvcnknLFxuICAgICAgfSxcbiAgICAgIF92YWx1ZV86IHtcbiAgICAgICAgdHlwZTogJ2xpbmVhcicsXG4gICAgICB9LFxuICAgIH1cbiAgfTtcblxuICBpbml0aWFsaXplKCkge1xuICAgIHRoaXMuZW5hYmxlT3B0aW9uU2hhcmluZyA9IHRydWU7XG4gICAgdGhpcy5zdXBwb3J0c0RlY2ltYXRpb24gPSB0cnVlO1xuICAgIHN1cGVyLmluaXRpYWxpemUoKTtcbiAgfVxuXG4gIHVwZGF0ZShtb2RlKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3Qge2RhdGFzZXQ6IGxpbmUsIGRhdGE6IHBvaW50cyA9IFtdLCBfZGF0YXNldH0gPSBtZXRhO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBjb25zdCBhbmltYXRpb25zRGlzYWJsZWQgPSB0aGlzLmNoYXJ0Ll9hbmltYXRpb25zRGlzYWJsZWQ7XG4gICAgbGV0IHtzdGFydCwgY291bnR9ID0gX2dldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHMobWV0YSwgcG9pbnRzLCBhbmltYXRpb25zRGlzYWJsZWQpO1xuXG4gICAgdGhpcy5fZHJhd1N0YXJ0ID0gc3RhcnQ7XG4gICAgdGhpcy5fZHJhd0NvdW50ID0gY291bnQ7XG5cbiAgICBpZiAoX3NjYWxlUmFuZ2VzQ2hhbmdlZChtZXRhKSkge1xuICAgICAgc3RhcnQgPSAwO1xuICAgICAgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSBMaW5lXG4gICAgbGluZS5fY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgIGxpbmUuX2RhdGFzZXRJbmRleCA9IHRoaXMuaW5kZXg7XG4gICAgbGluZS5fZGVjaW1hdGVkID0gISFfZGF0YXNldC5fZGVjaW1hdGVkO1xuICAgIGxpbmUucG9pbnRzID0gcG9pbnRzO1xuXG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMucmVzb2x2ZURhdGFzZXRFbGVtZW50T3B0aW9ucyhtb2RlKTtcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5zaG93TGluZSkge1xuICAgICAgb3B0aW9ucy5ib3JkZXJXaWR0aCA9IDA7XG4gICAgfVxuICAgIG9wdGlvbnMuc2VnbWVudCA9IHRoaXMub3B0aW9ucy5zZWdtZW50O1xuICAgIHRoaXMudXBkYXRlRWxlbWVudChsaW5lLCB1bmRlZmluZWQsIHtcbiAgICAgIGFuaW1hdGVkOiAhYW5pbWF0aW9uc0Rpc2FibGVkLFxuICAgICAgb3B0aW9uc1xuICAgIH0sIG1vZGUpO1xuXG4gICAgLy8gVXBkYXRlIFBvaW50c1xuICAgIHRoaXMudXBkYXRlRWxlbWVudHMocG9pbnRzLCBzdGFydCwgY291bnQsIG1vZGUpO1xuICB9XG5cbiAgdXBkYXRlRWxlbWVudHMocG9pbnRzLCBzdGFydCwgY291bnQsIG1vZGUpIHtcbiAgICBjb25zdCByZXNldCA9IG1vZGUgPT09ICdyZXNldCc7XG4gICAgY29uc3Qge2lTY2FsZSwgdlNjYWxlLCBfc3RhY2tlZCwgX2RhdGFzZXR9ID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCB7c2hhcmVkT3B0aW9ucywgaW5jbHVkZU9wdGlvbnN9ID0gdGhpcy5fZ2V0U2hhcmVkT3B0aW9ucyhzdGFydCwgbW9kZSk7XG4gICAgY29uc3QgaUF4aXMgPSBpU2NhbGUuYXhpcztcbiAgICBjb25zdCB2QXhpcyA9IHZTY2FsZS5heGlzO1xuICAgIGNvbnN0IHtzcGFuR2Fwcywgc2VnbWVudH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgbWF4R2FwTGVuZ3RoID0gaXNOdW1iZXIoc3BhbkdhcHMpID8gc3BhbkdhcHMgOiBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgY29uc3QgZGlyZWN0VXBkYXRlID0gdGhpcy5jaGFydC5fYW5pbWF0aW9uc0Rpc2FibGVkIHx8IHJlc2V0IHx8IG1vZGUgPT09ICdub25lJztcbiAgICBjb25zdCBlbmQgPSBzdGFydCArIGNvdW50O1xuICAgIGNvbnN0IHBvaW50c0NvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgICBsZXQgcHJldlBhcnNlZCA9IHN0YXJ0ID4gMCAmJiB0aGlzLmdldFBhcnNlZChzdGFydCAtIDEpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb2ludHNDb3VudDsgKytpKSB7XG4gICAgICBjb25zdCBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSBkaXJlY3RVcGRhdGUgPyBwb2ludCA6IHt9O1xuXG4gICAgICBpZiAoaSA8IHN0YXJ0IHx8IGkgPj0gZW5kKSB7XG4gICAgICAgIHByb3BlcnRpZXMuc2tpcCA9IHRydWU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpKTtcbiAgICAgIGNvbnN0IG51bGxEYXRhID0gaXNOdWxsT3JVbmRlZihwYXJzZWRbdkF4aXNdKTtcbiAgICAgIGNvbnN0IGlQaXhlbCA9IHByb3BlcnRpZXNbaUF4aXNdID0gaVNjYWxlLmdldFBpeGVsRm9yVmFsdWUocGFyc2VkW2lBeGlzXSwgaSk7XG4gICAgICBjb25zdCB2UGl4ZWwgPSBwcm9wZXJ0aWVzW3ZBeGlzXSA9IHJlc2V0IHx8IG51bGxEYXRhID8gdlNjYWxlLmdldEJhc2VQaXhlbCgpIDogdlNjYWxlLmdldFBpeGVsRm9yVmFsdWUoX3N0YWNrZWQgPyB0aGlzLmFwcGx5U3RhY2sodlNjYWxlLCBwYXJzZWQsIF9zdGFja2VkKSA6IHBhcnNlZFt2QXhpc10sIGkpO1xuXG4gICAgICBwcm9wZXJ0aWVzLnNraXAgPSBpc05hTihpUGl4ZWwpIHx8IGlzTmFOKHZQaXhlbCkgfHwgbnVsbERhdGE7XG4gICAgICBwcm9wZXJ0aWVzLnN0b3AgPSBpID4gMCAmJiAoTWF0aC5hYnMocGFyc2VkW2lBeGlzXSAtIHByZXZQYXJzZWRbaUF4aXNdKSkgPiBtYXhHYXBMZW5ndGg7XG4gICAgICBpZiAoc2VnbWVudCkge1xuICAgICAgICBwcm9wZXJ0aWVzLnBhcnNlZCA9IHBhcnNlZDtcbiAgICAgICAgcHJvcGVydGllcy5yYXcgPSBfZGF0YXNldC5kYXRhW2ldO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5jbHVkZU9wdGlvbnMpIHtcbiAgICAgICAgcHJvcGVydGllcy5vcHRpb25zID0gc2hhcmVkT3B0aW9ucyB8fCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgcG9pbnQuYWN0aXZlID8gJ2FjdGl2ZScgOiBtb2RlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFkaXJlY3RVcGRhdGUpIHtcbiAgICAgICAgdGhpcy51cGRhdGVFbGVtZW50KHBvaW50LCBpLCBwcm9wZXJ0aWVzLCBtb2RlKTtcbiAgICAgIH1cblxuICAgICAgcHJldlBhcnNlZCA9IHBhcnNlZDtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0TWF4T3ZlcmZsb3coKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgZGF0YXNldCA9IG1ldGEuZGF0YXNldDtcbiAgICBjb25zdCBib3JkZXIgPSBkYXRhc2V0Lm9wdGlvbnMgJiYgZGF0YXNldC5vcHRpb25zLmJvcmRlcldpZHRoIHx8IDA7XG4gICAgY29uc3QgZGF0YSA9IG1ldGEuZGF0YSB8fCBbXTtcbiAgICBpZiAoIWRhdGEubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gYm9yZGVyO1xuICAgIH1cbiAgICBjb25zdCBmaXJzdFBvaW50ID0gZGF0YVswXS5zaXplKHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucygwKSk7XG4gICAgY29uc3QgbGFzdFBvaW50ID0gZGF0YVtkYXRhLmxlbmd0aCAtIDFdLnNpemUodGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGRhdGEubGVuZ3RoIC0gMSkpO1xuICAgIHJldHVybiBNYXRoLm1heChib3JkZXIsIGZpcnN0UG9pbnQsIGxhc3RQb2ludCkgLyAyO1xuICB9XG5cbiAgZHJhdygpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBtZXRhLmRhdGFzZXQudXBkYXRlQ29udHJvbFBvaW50cyh0aGlzLmNoYXJ0LmNoYXJ0QXJlYSwgbWV0YS5pU2NhbGUuYXhpcyk7XG4gICAgc3VwZXIuZHJhdygpO1xuICB9XG59XG4iLCAiaW1wb3J0IERhdGFzZXRDb250cm9sbGVyIGZyb20gJy4uL2NvcmUvY29yZS5kYXRhc2V0Q29udHJvbGxlci5qcyc7XG5pbXBvcnQge3RvUmFkaWFucywgUEksIGZvcm1hdE51bWJlciwgX3BhcnNlT2JqZWN0RGF0YVJhZGlhbFNjYWxlfSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUG9sYXJBcmVhQ29udHJvbGxlciBleHRlbmRzIERhdGFzZXRDb250cm9sbGVyIHtcblxuICBzdGF0aWMgaWQgPSAncG9sYXJBcmVhJztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICBkYXRhRWxlbWVudFR5cGU6ICdhcmMnLFxuICAgIGFuaW1hdGlvbjoge1xuICAgICAgYW5pbWF0ZVJvdGF0ZTogdHJ1ZSxcbiAgICAgIGFuaW1hdGVTY2FsZTogdHJ1ZVxuICAgIH0sXG4gICAgYW5pbWF0aW9uczoge1xuICAgICAgbnVtYmVyczoge1xuICAgICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgICAgcHJvcGVydGllczogWyd4JywgJ3knLCAnc3RhcnRBbmdsZScsICdlbmRBbmdsZScsICdpbm5lclJhZGl1cycsICdvdXRlclJhZGl1cyddXG4gICAgICB9LFxuICAgIH0sXG4gICAgaW5kZXhBeGlzOiAncicsXG4gICAgc3RhcnRBbmdsZTogMCxcbiAgfTtcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBvdmVycmlkZXMgPSB7XG4gICAgYXNwZWN0UmF0aW86IDEsXG5cbiAgICBwbHVnaW5zOiB7XG4gICAgICBsZWdlbmQ6IHtcbiAgICAgICAgbGFiZWxzOiB7XG4gICAgICAgICAgZ2VuZXJhdGVMYWJlbHMoY2hhcnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBjaGFydC5kYXRhO1xuICAgICAgICAgICAgaWYgKGRhdGEubGFiZWxzLmxlbmd0aCAmJiBkYXRhLmRhdGFzZXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBjb25zdCB7bGFiZWxzOiB7cG9pbnRTdHlsZSwgY29sb3J9fSA9IGNoYXJ0LmxlZ2VuZC5vcHRpb25zO1xuXG4gICAgICAgICAgICAgIHJldHVybiBkYXRhLmxhYmVscy5tYXAoKGxhYmVsLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKDApO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0eWxlID0gbWV0YS5jb250cm9sbGVyLmdldFN0eWxlKGkpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgIHRleHQ6IGxhYmVsLFxuICAgICAgICAgICAgICAgICAgZmlsbFN0eWxlOiBzdHlsZS5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAgICAgICAgICAgICBzdHJva2VTdHlsZTogc3R5bGUuYm9yZGVyQ29sb3IsXG4gICAgICAgICAgICAgICAgICBmb250Q29sb3I6IGNvbG9yLFxuICAgICAgICAgICAgICAgICAgbGluZVdpZHRoOiBzdHlsZS5ib3JkZXJXaWR0aCxcbiAgICAgICAgICAgICAgICAgIHBvaW50U3R5bGU6IHBvaW50U3R5bGUsXG4gICAgICAgICAgICAgICAgICBoaWRkZW46ICFjaGFydC5nZXREYXRhVmlzaWJpbGl0eShpKSxcblxuICAgICAgICAgICAgICAgICAgLy8gRXh0cmEgZGF0YSB1c2VkIGZvciB0b2dnbGluZyB0aGUgY29ycmVjdCBpdGVtXG4gICAgICAgICAgICAgICAgICBpbmRleDogaVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBvbkNsaWNrKGUsIGxlZ2VuZEl0ZW0sIGxlZ2VuZCkge1xuICAgICAgICAgIGxlZ2VuZC5jaGFydC50b2dnbGVEYXRhVmlzaWJpbGl0eShsZWdlbmRJdGVtLmluZGV4KTtcbiAgICAgICAgICBsZWdlbmQuY2hhcnQudXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgc2NhbGVzOiB7XG4gICAgICByOiB7XG4gICAgICAgIHR5cGU6ICdyYWRpYWxMaW5lYXInLFxuICAgICAgICBhbmdsZUxpbmVzOiB7XG4gICAgICAgICAgZGlzcGxheTogZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgYmVnaW5BdFplcm86IHRydWUsXG4gICAgICAgIGdyaWQ6IHtcbiAgICAgICAgICBjaXJjdWxhcjogdHJ1ZVxuICAgICAgICB9LFxuICAgICAgICBwb2ludExhYmVsczoge1xuICAgICAgICAgIGRpc3BsYXk6IGZhbHNlXG4gICAgICAgIH0sXG4gICAgICAgIHN0YXJ0QW5nbGU6IDBcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgY29uc3RydWN0b3IoY2hhcnQsIGRhdGFzZXRJbmRleCkge1xuICAgIHN1cGVyKGNoYXJ0LCBkYXRhc2V0SW5kZXgpO1xuXG4gICAgdGhpcy5pbm5lclJhZGl1cyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm91dGVyUmFkaXVzID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgZ2V0TGFiZWxBbmRWYWx1ZShpbmRleCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBsYWJlbHMgPSBjaGFydC5kYXRhLmxhYmVscyB8fCBbXTtcbiAgICBjb25zdCB2YWx1ZSA9IGZvcm1hdE51bWJlcihtZXRhLl9wYXJzZWRbaW5kZXhdLnIsIGNoYXJ0Lm9wdGlvbnMubG9jYWxlKTtcblxuICAgIHJldHVybiB7XG4gICAgICBsYWJlbDogbGFiZWxzW2luZGV4XSB8fCAnJyxcbiAgICAgIHZhbHVlLFxuICAgIH07XG4gIH1cblxuICBwYXJzZU9iamVjdERhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgcmV0dXJuIF9wYXJzZU9iamVjdERhdGFSYWRpYWxTY2FsZS5iaW5kKHRoaXMpKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gIH1cblxuICB1cGRhdGUobW9kZSkge1xuICAgIGNvbnN0IGFyY3MgPSB0aGlzLl9jYWNoZWRNZXRhLmRhdGE7XG5cbiAgICB0aGlzLl91cGRhdGVSYWRpdXMoKTtcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKGFyY3MsIDAsIGFyY3MubGVuZ3RoLCBtb2RlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBnZXRNaW5NYXgoKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgcmFuZ2UgPSB7bWluOiBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksIG1heDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZfTtcblxuICAgIG1ldGEuZGF0YS5mb3JFYWNoKChlbGVtZW50LCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaW5kZXgpLnI7XG5cbiAgICAgIGlmICghaXNOYU4ocGFyc2VkKSAmJiB0aGlzLmNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGluZGV4KSkge1xuICAgICAgICBpZiAocGFyc2VkIDwgcmFuZ2UubWluKSB7XG4gICAgICAgICAgcmFuZ2UubWluID0gcGFyc2VkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcnNlZCA+IHJhbmdlLm1heCkge1xuICAgICAgICAgIHJhbmdlLm1heCA9IHBhcnNlZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdXBkYXRlUmFkaXVzKCkge1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBjaGFydEFyZWEgPSBjaGFydC5jaGFydEFyZWE7XG4gICAgY29uc3Qgb3B0cyA9IGNoYXJ0Lm9wdGlvbnM7XG4gICAgY29uc3QgbWluU2l6ZSA9IE1hdGgubWluKGNoYXJ0QXJlYS5yaWdodCAtIGNoYXJ0QXJlYS5sZWZ0LCBjaGFydEFyZWEuYm90dG9tIC0gY2hhcnRBcmVhLnRvcCk7XG5cbiAgICBjb25zdCBvdXRlclJhZGl1cyA9IE1hdGgubWF4KG1pblNpemUgLyAyLCAwKTtcbiAgICBjb25zdCBpbm5lclJhZGl1cyA9IE1hdGgubWF4KG9wdHMuY3V0b3V0UGVyY2VudGFnZSA/IChvdXRlclJhZGl1cyAvIDEwMCkgKiAob3B0cy5jdXRvdXRQZXJjZW50YWdlKSA6IDEsIDApO1xuICAgIGNvbnN0IHJhZGl1c0xlbmd0aCA9IChvdXRlclJhZGl1cyAtIGlubmVyUmFkaXVzKSAvIGNoYXJ0LmdldFZpc2libGVEYXRhc2V0Q291bnQoKTtcblxuICAgIHRoaXMub3V0ZXJSYWRpdXMgPSBvdXRlclJhZGl1cyAtIChyYWRpdXNMZW5ndGggKiB0aGlzLmluZGV4KTtcbiAgICB0aGlzLmlubmVyUmFkaXVzID0gdGhpcy5vdXRlclJhZGl1cyAtIHJhZGl1c0xlbmd0aDtcbiAgfVxuXG4gIHVwZGF0ZUVsZW1lbnRzKGFyY3MsIHN0YXJ0LCBjb3VudCwgbW9kZSkge1xuICAgIGNvbnN0IHJlc2V0ID0gbW9kZSA9PT0gJ3Jlc2V0JztcbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3Qgb3B0cyA9IGNoYXJ0Lm9wdGlvbnM7XG4gICAgY29uc3QgYW5pbWF0aW9uT3B0cyA9IG9wdHMuYW5pbWF0aW9uO1xuICAgIGNvbnN0IHNjYWxlID0gdGhpcy5fY2FjaGVkTWV0YS5yU2NhbGU7XG4gICAgY29uc3QgY2VudGVyWCA9IHNjYWxlLnhDZW50ZXI7XG4gICAgY29uc3QgY2VudGVyWSA9IHNjYWxlLnlDZW50ZXI7XG4gICAgY29uc3QgZGF0YXNldFN0YXJ0QW5nbGUgPSBzY2FsZS5nZXRJbmRleEFuZ2xlKDApIC0gMC41ICogUEk7XG4gICAgbGV0IGFuZ2xlID0gZGF0YXNldFN0YXJ0QW5nbGU7XG4gICAgbGV0IGk7XG5cbiAgICBjb25zdCBkZWZhdWx0QW5nbGUgPSAzNjAgLyB0aGlzLmNvdW50VmlzaWJsZUVsZW1lbnRzKCk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgc3RhcnQ7ICsraSkge1xuICAgICAgYW5nbGUgKz0gdGhpcy5fY29tcHV0ZUFuZ2xlKGksIG1vZGUsIGRlZmF1bHRBbmdsZSk7XG4gICAgfVxuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBjb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCBhcmMgPSBhcmNzW2ldO1xuICAgICAgbGV0IHN0YXJ0QW5nbGUgPSBhbmdsZTtcbiAgICAgIGxldCBlbmRBbmdsZSA9IGFuZ2xlICsgdGhpcy5fY29tcHV0ZUFuZ2xlKGksIG1vZGUsIGRlZmF1bHRBbmdsZSk7XG4gICAgICBsZXQgb3V0ZXJSYWRpdXMgPSBjaGFydC5nZXREYXRhVmlzaWJpbGl0eShpKSA/IHNjYWxlLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKHRoaXMuZ2V0UGFyc2VkKGkpLnIpIDogMDtcbiAgICAgIGFuZ2xlID0gZW5kQW5nbGU7XG5cbiAgICAgIGlmIChyZXNldCkge1xuICAgICAgICBpZiAoYW5pbWF0aW9uT3B0cy5hbmltYXRlU2NhbGUpIHtcbiAgICAgICAgICBvdXRlclJhZGl1cyA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFuaW1hdGlvbk9wdHMuYW5pbWF0ZVJvdGF0ZSkge1xuICAgICAgICAgIHN0YXJ0QW5nbGUgPSBlbmRBbmdsZSA9IGRhdGFzZXRTdGFydEFuZ2xlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB7XG4gICAgICAgIHg6IGNlbnRlclgsXG4gICAgICAgIHk6IGNlbnRlclksXG4gICAgICAgIGlubmVyUmFkaXVzOiAwLFxuICAgICAgICBvdXRlclJhZGl1cyxcbiAgICAgICAgc3RhcnRBbmdsZSxcbiAgICAgICAgZW5kQW5nbGUsXG4gICAgICAgIG9wdGlvbnM6IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpLCBhcmMuYWN0aXZlID8gJ2FjdGl2ZScgOiBtb2RlKVxuICAgICAgfTtcblxuICAgICAgdGhpcy51cGRhdGVFbGVtZW50KGFyYywgaSwgcHJvcGVydGllcywgbW9kZSk7XG4gICAgfVxuICB9XG5cbiAgY291bnRWaXNpYmxlRWxlbWVudHMoKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgbGV0IGNvdW50ID0gMDtcblxuICAgIG1ldGEuZGF0YS5mb3JFYWNoKChlbGVtZW50LCBpbmRleCkgPT4ge1xuICAgICAgaWYgKCFpc05hTih0aGlzLmdldFBhcnNlZChpbmRleCkucikgJiYgdGhpcy5jaGFydC5nZXREYXRhVmlzaWJpbGl0eShpbmRleCkpIHtcbiAgICAgICAgY291bnQrKztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBjb3VudDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2NvbXB1dGVBbmdsZShpbmRleCwgbW9kZSwgZGVmYXVsdEFuZ2xlKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaW5kZXgpXG4gICAgICA/IHRvUmFkaWFucyh0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaW5kZXgsIG1vZGUpLmFuZ2xlIHx8IGRlZmF1bHRBbmdsZSlcbiAgICAgIDogMDtcbiAgfVxufVxuIiwgImltcG9ydCBEb3VnaG51dENvbnRyb2xsZXIgZnJvbSAnLi9jb250cm9sbGVyLmRvdWdobnV0LmpzJztcblxuLy8gUGllIGNoYXJ0cyBhcmUgRG91Z2hudXQgY2hhcnQgd2l0aCBkaWZmZXJlbnQgZGVmYXVsdHNcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBpZUNvbnRyb2xsZXIgZXh0ZW5kcyBEb3VnaG51dENvbnRyb2xsZXIge1xuXG4gIHN0YXRpYyBpZCA9ICdwaWUnO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIC8vIFRoZSBwZXJjZW50YWdlIG9mIHRoZSBjaGFydCB0aGF0IHdlIGN1dCBvdXQgb2YgdGhlIG1pZGRsZS5cbiAgICBjdXRvdXQ6IDAsXG5cbiAgICAvLyBUaGUgcm90YXRpb24gb2YgdGhlIGNoYXJ0LCB3aGVyZSB0aGUgZmlyc3QgZGF0YSBhcmMgYmVnaW5zLlxuICAgIHJvdGF0aW9uOiAwLFxuXG4gICAgLy8gVGhlIHRvdGFsIGNpcmN1bWZlcmVuY2Ugb2YgdGhlIGNoYXJ0LlxuICAgIGNpcmN1bWZlcmVuY2U6IDM2MCxcblxuICAgIC8vIFRoZSBvdXRlciByYWRpdXMgb2YgdGhlIGNoYXJ0XG4gICAgcmFkaXVzOiAnMTAwJSdcbiAgfTtcbn1cbiIsICJpbXBvcnQgRGF0YXNldENvbnRyb2xsZXIgZnJvbSAnLi4vY29yZS9jb3JlLmRhdGFzZXRDb250cm9sbGVyLmpzJztcbmltcG9ydCB7X3BhcnNlT2JqZWN0RGF0YVJhZGlhbFNjYWxlfSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmFkYXJDb250cm9sbGVyIGV4dGVuZHMgRGF0YXNldENvbnRyb2xsZXIge1xuXG4gIHN0YXRpYyBpZCA9ICdyYWRhcic7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgZGF0YXNldEVsZW1lbnRUeXBlOiAnbGluZScsXG4gICAgZGF0YUVsZW1lbnRUeXBlOiAncG9pbnQnLFxuICAgIGluZGV4QXhpczogJ3InLFxuICAgIHNob3dMaW5lOiB0cnVlLFxuICAgIGVsZW1lbnRzOiB7XG4gICAgICBsaW5lOiB7XG4gICAgICAgIGZpbGw6ICdzdGFydCdcbiAgICAgIH1cbiAgICB9LFxuICB9O1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIG92ZXJyaWRlcyA9IHtcbiAgICBhc3BlY3RSYXRpbzogMSxcblxuICAgIHNjYWxlczoge1xuICAgICAgcjoge1xuICAgICAgICB0eXBlOiAncmFkaWFsTGluZWFyJyxcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldExhYmVsQW5kVmFsdWUoaW5kZXgpIHtcbiAgICBjb25zdCB2U2NhbGUgPSB0aGlzLl9jYWNoZWRNZXRhLnZTY2FsZTtcbiAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6IHZTY2FsZS5nZXRMYWJlbHMoKVtpbmRleF0sXG4gICAgICB2YWx1ZTogJycgKyB2U2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWRbdlNjYWxlLmF4aXNdKVxuICAgIH07XG4gIH1cblxuICBwYXJzZU9iamVjdERhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgcmV0dXJuIF9wYXJzZU9iamVjdERhdGFSYWRpYWxTY2FsZS5iaW5kKHRoaXMpKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gIH1cblxuICB1cGRhdGUobW9kZSkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGxpbmUgPSBtZXRhLmRhdGFzZXQ7XG4gICAgY29uc3QgcG9pbnRzID0gbWV0YS5kYXRhIHx8IFtdO1xuICAgIGNvbnN0IGxhYmVscyA9IG1ldGEuaVNjYWxlLmdldExhYmVscygpO1xuXG4gICAgLy8gVXBkYXRlIExpbmVcbiAgICBsaW5lLnBvaW50cyA9IHBvaW50cztcbiAgICAvLyBJbiByZXNpemUgbW9kZSBvbmx5IHBvaW50IGxvY2F0aW9ucyBjaGFuZ2UsIHNvIG5vIG5lZWQgdG8gc2V0IHRoZSBwb2ludHMgb3Igb3B0aW9ucy5cbiAgICBpZiAobW9kZSAhPT0gJ3Jlc2l6ZScpIHtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnJlc29sdmVEYXRhc2V0RWxlbWVudE9wdGlvbnMobW9kZSk7XG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5zaG93TGluZSkge1xuICAgICAgICBvcHRpb25zLmJvcmRlcldpZHRoID0gMDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IHtcbiAgICAgICAgX2xvb3A6IHRydWUsXG4gICAgICAgIF9mdWxsTG9vcDogbGFiZWxzLmxlbmd0aCA9PT0gcG9pbnRzLmxlbmd0aCxcbiAgICAgICAgb3B0aW9uc1xuICAgICAgfTtcblxuICAgICAgdGhpcy51cGRhdGVFbGVtZW50KGxpbmUsIHVuZGVmaW5lZCwgcHJvcGVydGllcywgbW9kZSk7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIFBvaW50c1xuICAgIHRoaXMudXBkYXRlRWxlbWVudHMocG9pbnRzLCAwLCBwb2ludHMubGVuZ3RoLCBtb2RlKTtcbiAgfVxuXG4gIHVwZGF0ZUVsZW1lbnRzKHBvaW50cywgc3RhcnQsIGNvdW50LCBtb2RlKSB7XG4gICAgY29uc3Qgc2NhbGUgPSB0aGlzLl9jYWNoZWRNZXRhLnJTY2FsZTtcbiAgICBjb25zdCByZXNldCA9IG1vZGUgPT09ICdyZXNldCc7XG5cbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBzdGFydCArIGNvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpLCBwb2ludC5hY3RpdmUgPyAnYWN0aXZlJyA6IG1vZGUpO1xuICAgICAgY29uc3QgcG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZShpLCB0aGlzLmdldFBhcnNlZChpKS5yKTtcblxuICAgICAgY29uc3QgeCA9IHJlc2V0ID8gc2NhbGUueENlbnRlciA6IHBvaW50UG9zaXRpb24ueDtcbiAgICAgIGNvbnN0IHkgPSByZXNldCA/IHNjYWxlLnlDZW50ZXIgOiBwb2ludFBvc2l0aW9uLnk7XG5cbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB7XG4gICAgICAgIHgsXG4gICAgICAgIHksXG4gICAgICAgIGFuZ2xlOiBwb2ludFBvc2l0aW9uLmFuZ2xlLFxuICAgICAgICBza2lwOiBpc05hTih4KSB8fCBpc05hTih5KSxcbiAgICAgICAgb3B0aW9uc1xuICAgICAgfTtcblxuICAgICAgdGhpcy51cGRhdGVFbGVtZW50KHBvaW50LCBpLCBwcm9wZXJ0aWVzLCBtb2RlKTtcbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgRGF0YXNldENvbnRyb2xsZXIgZnJvbSAnLi4vY29yZS9jb3JlLmRhdGFzZXRDb250cm9sbGVyLmpzJztcbmltcG9ydCB7aXNOdWxsT3JVbmRlZn0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5pbXBvcnQge2lzTnVtYmVyfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMubWF0aC5qcyc7XG5pbXBvcnQge19nZXRTdGFydEFuZENvdW50T2ZWaXNpYmxlUG9pbnRzLCBfc2NhbGVSYW5nZXNDaGFuZ2VkfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZXh0cmFzLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2NhdHRlckNvbnRyb2xsZXIgZXh0ZW5kcyBEYXRhc2V0Q29udHJvbGxlciB7XG5cbiAgc3RhdGljIGlkID0gJ3NjYXR0ZXInO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIGRhdGFzZXRFbGVtZW50VHlwZTogZmFsc2UsXG4gICAgZGF0YUVsZW1lbnRUeXBlOiAncG9pbnQnLFxuICAgIHNob3dMaW5lOiBmYWxzZSxcbiAgICBmaWxsOiBmYWxzZVxuICB9O1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIG92ZXJyaWRlcyA9IHtcblxuICAgIGludGVyYWN0aW9uOiB7XG4gICAgICBtb2RlOiAncG9pbnQnXG4gICAgfSxcblxuICAgIHNjYWxlczoge1xuICAgICAgeDoge1xuICAgICAgICB0eXBlOiAnbGluZWFyJ1xuICAgICAgfSxcbiAgICAgIHk6IHtcbiAgICAgICAgdHlwZTogJ2xpbmVhcidcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldExhYmVsQW5kVmFsdWUoaW5kZXgpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBsYWJlbHMgPSB0aGlzLmNoYXJ0LmRhdGEubGFiZWxzIHx8IFtdO1xuICAgIGNvbnN0IHt4U2NhbGUsIHlTY2FsZX0gPSBtZXRhO1xuICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGluZGV4KTtcbiAgICBjb25zdCB4ID0geFNjYWxlLmdldExhYmVsRm9yVmFsdWUocGFyc2VkLngpO1xuICAgIGNvbnN0IHkgPSB5U2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWQueSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6IGxhYmVsc1tpbmRleF0gfHwgJycsXG4gICAgICB2YWx1ZTogJygnICsgeCArICcsICcgKyB5ICsgJyknXG4gICAgfTtcbiAgfVxuXG4gIHVwZGF0ZShtb2RlKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3Qge2RhdGE6IHBvaW50cyA9IFtdfSA9IG1ldGE7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGFuaW1hdGlvbnNEaXNhYmxlZCA9IHRoaXMuY2hhcnQuX2FuaW1hdGlvbnNEaXNhYmxlZDtcbiAgICBsZXQge3N0YXJ0LCBjb3VudH0gPSBfZ2V0U3RhcnRBbmRDb3VudE9mVmlzaWJsZVBvaW50cyhtZXRhLCBwb2ludHMsIGFuaW1hdGlvbnNEaXNhYmxlZCk7XG5cbiAgICB0aGlzLl9kcmF3U3RhcnQgPSBzdGFydDtcbiAgICB0aGlzLl9kcmF3Q291bnQgPSBjb3VudDtcblxuICAgIGlmIChfc2NhbGVSYW5nZXNDaGFuZ2VkKG1ldGEpKSB7XG4gICAgICBzdGFydCA9IDA7XG4gICAgICBjb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5zaG93TGluZSkge1xuXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMTEzMzNcbiAgICAgIGlmICghdGhpcy5kYXRhc2V0RWxlbWVudFR5cGUpIHtcbiAgICAgICAgdGhpcy5hZGRFbGVtZW50cygpO1xuICAgICAgfVxuICAgICAgY29uc3Qge2RhdGFzZXQ6IGxpbmUsIF9kYXRhc2V0fSA9IG1ldGE7XG5cbiAgICAgIC8vIFVwZGF0ZSBMaW5lXG4gICAgICBsaW5lLl9jaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgICBsaW5lLl9kYXRhc2V0SW5kZXggPSB0aGlzLmluZGV4O1xuICAgICAgbGluZS5fZGVjaW1hdGVkID0gISFfZGF0YXNldC5fZGVjaW1hdGVkO1xuICAgICAgbGluZS5wb2ludHMgPSBwb2ludHM7XG5cbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnJlc29sdmVEYXRhc2V0RWxlbWVudE9wdGlvbnMobW9kZSk7XG4gICAgICBvcHRpb25zLnNlZ21lbnQgPSB0aGlzLm9wdGlvbnMuc2VnbWVudDtcbiAgICAgIHRoaXMudXBkYXRlRWxlbWVudChsaW5lLCB1bmRlZmluZWQsIHtcbiAgICAgICAgYW5pbWF0ZWQ6ICFhbmltYXRpb25zRGlzYWJsZWQsXG4gICAgICAgIG9wdGlvbnNcbiAgICAgIH0sIG1vZGUpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhc2V0RWxlbWVudFR5cGUpIHtcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8xMTMzM1xuICAgICAgZGVsZXRlIG1ldGEuZGF0YXNldDtcbiAgICAgIHRoaXMuZGF0YXNldEVsZW1lbnRUeXBlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIFBvaW50c1xuICAgIHRoaXMudXBkYXRlRWxlbWVudHMocG9pbnRzLCBzdGFydCwgY291bnQsIG1vZGUpO1xuICB9XG5cbiAgYWRkRWxlbWVudHMoKSB7XG4gICAgY29uc3Qge3Nob3dMaW5lfSA9IHRoaXMub3B0aW9ucztcblxuICAgIGlmICghdGhpcy5kYXRhc2V0RWxlbWVudFR5cGUgJiYgc2hvd0xpbmUpIHtcbiAgICAgIHRoaXMuZGF0YXNldEVsZW1lbnRUeXBlID0gdGhpcy5jaGFydC5yZWdpc3RyeS5nZXRFbGVtZW50KCdsaW5lJyk7XG4gICAgfVxuXG4gICAgc3VwZXIuYWRkRWxlbWVudHMoKTtcbiAgfVxuXG4gIHVwZGF0ZUVsZW1lbnRzKHBvaW50cywgc3RhcnQsIGNvdW50LCBtb2RlKSB7XG4gICAgY29uc3QgcmVzZXQgPSBtb2RlID09PSAncmVzZXQnO1xuICAgIGNvbnN0IHtpU2NhbGUsIHZTY2FsZSwgX3N0YWNrZWQsIF9kYXRhc2V0fSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgZmlyc3RPcHRzID0gdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKHN0YXJ0LCBtb2RlKTtcbiAgICBjb25zdCBzaGFyZWRPcHRpb25zID0gdGhpcy5nZXRTaGFyZWRPcHRpb25zKGZpcnN0T3B0cyk7XG4gICAgY29uc3QgaW5jbHVkZU9wdGlvbnMgPSB0aGlzLmluY2x1ZGVPcHRpb25zKG1vZGUsIHNoYXJlZE9wdGlvbnMpO1xuICAgIGNvbnN0IGlBeGlzID0gaVNjYWxlLmF4aXM7XG4gICAgY29uc3QgdkF4aXMgPSB2U2NhbGUuYXhpcztcbiAgICBjb25zdCB7c3BhbkdhcHMsIHNlZ21lbnR9ID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IG1heEdhcExlbmd0aCA9IGlzTnVtYmVyKHNwYW5HYXBzKSA/IHNwYW5HYXBzIDogTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgIGNvbnN0IGRpcmVjdFVwZGF0ZSA9IHRoaXMuY2hhcnQuX2FuaW1hdGlvbnNEaXNhYmxlZCB8fCByZXNldCB8fCBtb2RlID09PSAnbm9uZSc7XG4gICAgbGV0IHByZXZQYXJzZWQgPSBzdGFydCA+IDAgJiYgdGhpcy5nZXRQYXJzZWQoc3RhcnQgLSAxKTtcblxuICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IHN0YXJ0ICsgY291bnQ7ICsraSkge1xuICAgICAgY29uc3QgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpKTtcbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSBkaXJlY3RVcGRhdGUgPyBwb2ludCA6IHt9O1xuICAgICAgY29uc3QgbnVsbERhdGEgPSBpc051bGxPclVuZGVmKHBhcnNlZFt2QXhpc10pO1xuICAgICAgY29uc3QgaVBpeGVsID0gcHJvcGVydGllc1tpQXhpc10gPSBpU2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShwYXJzZWRbaUF4aXNdLCBpKTtcbiAgICAgIGNvbnN0IHZQaXhlbCA9IHByb3BlcnRpZXNbdkF4aXNdID0gcmVzZXQgfHwgbnVsbERhdGEgPyB2U2NhbGUuZ2V0QmFzZVBpeGVsKCkgOiB2U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShfc3RhY2tlZCA/IHRoaXMuYXBwbHlTdGFjayh2U2NhbGUsIHBhcnNlZCwgX3N0YWNrZWQpIDogcGFyc2VkW3ZBeGlzXSwgaSk7XG5cbiAgICAgIHByb3BlcnRpZXMuc2tpcCA9IGlzTmFOKGlQaXhlbCkgfHwgaXNOYU4odlBpeGVsKSB8fCBudWxsRGF0YTtcbiAgICAgIHByb3BlcnRpZXMuc3RvcCA9IGkgPiAwICYmIChNYXRoLmFicyhwYXJzZWRbaUF4aXNdIC0gcHJldlBhcnNlZFtpQXhpc10pKSA+IG1heEdhcExlbmd0aDtcbiAgICAgIGlmIChzZWdtZW50KSB7XG4gICAgICAgIHByb3BlcnRpZXMucGFyc2VkID0gcGFyc2VkO1xuICAgICAgICBwcm9wZXJ0aWVzLnJhdyA9IF9kYXRhc2V0LmRhdGFbaV07XG4gICAgICB9XG5cbiAgICAgIGlmIChpbmNsdWRlT3B0aW9ucykge1xuICAgICAgICBwcm9wZXJ0aWVzLm9wdGlvbnMgPSBzaGFyZWRPcHRpb25zIHx8IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpLCBwb2ludC5hY3RpdmUgPyAnYWN0aXZlJyA6IG1vZGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWRpcmVjdFVwZGF0ZSkge1xuICAgICAgICB0aGlzLnVwZGF0ZUVsZW1lbnQocG9pbnQsIGksIHByb3BlcnRpZXMsIG1vZGUpO1xuICAgICAgfVxuXG4gICAgICBwcmV2UGFyc2VkID0gcGFyc2VkO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlU2hhcmVkT3B0aW9ucyhzaGFyZWRPcHRpb25zLCBtb2RlLCBmaXJzdE9wdHMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldE1heE92ZXJmbG93KCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGRhdGEgPSBtZXRhLmRhdGEgfHwgW107XG5cbiAgICBpZiAoIXRoaXMub3B0aW9ucy5zaG93TGluZSkge1xuICAgICAgbGV0IG1heCA9IDA7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICBtYXggPSBNYXRoLm1heChtYXgsIGRhdGFbaV0uc2l6ZSh0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSkpIC8gMik7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWF4ID4gMCAmJiBtYXg7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YXNldCA9IG1ldGEuZGF0YXNldDtcbiAgICBjb25zdCBib3JkZXIgPSBkYXRhc2V0Lm9wdGlvbnMgJiYgZGF0YXNldC5vcHRpb25zLmJvcmRlcldpZHRoIHx8IDA7XG5cbiAgICBpZiAoIWRhdGEubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gYm9yZGVyO1xuICAgIH1cblxuICAgIGNvbnN0IGZpcnN0UG9pbnQgPSBkYXRhWzBdLnNpemUodGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKDApKTtcbiAgICBjb25zdCBsYXN0UG9pbnQgPSBkYXRhW2RhdGEubGVuZ3RoIC0gMV0uc2l6ZSh0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoZGF0YS5sZW5ndGggLSAxKSk7XG4gICAgcmV0dXJuIE1hdGgubWF4KGJvcmRlciwgZmlyc3RQb2ludCwgbGFzdFBvaW50KSAvIDI7XG4gIH1cbn1cbiIsICIvKipcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuX2FkYXB0ZXJzXG4gKiBAc2luY2UgMi44LjBcbiAqIEBwcml2YXRlXG4gKi9cblxuaW1wb3J0IHR5cGUge0FueU9iamVjdH0gZnJvbSAnLi4vdHlwZXMvYmFzaWMuanMnO1xuaW1wb3J0IHR5cGUge0NoYXJ0T3B0aW9uc30gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuXG5leHBvcnQgdHlwZSBUaW1lVW5pdCA9ICdtaWxsaXNlY29uZCcgfCAnc2Vjb25kJyB8ICdtaW51dGUnIHwgJ2hvdXInIHwgJ2RheScgfCAnd2VlaycgfCAnbW9udGgnIHwgJ3F1YXJ0ZXInIHwgJ3llYXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIERhdGVBZGFwdGVyPFQgZXh0ZW5kcyBBbnlPYmplY3QgPSBBbnlPYmplY3Q+IHtcbiAgcmVhZG9ubHkgb3B0aW9uczogVDtcbiAgLyoqXG4gICAqIFdpbGwgY2FsbGVkIHdpdGggY2hhcnQgb3B0aW9ucyBhZnRlciBhZGFwdGVyIGNyZWF0aW9uLlxuICAgKi9cbiAgaW5pdCh0aGlzOiBEYXRlQWRhcHRlcjxUPiwgY2hhcnRPcHRpb25zOiBDaGFydE9wdGlvbnMpOiB2b2lkO1xuICAvKipcbiAgICogUmV0dXJucyBhIG1hcCBvZiB0aW1lIGZvcm1hdHMgZm9yIHRoZSBzdXBwb3J0ZWQgZm9ybWF0dGluZyB1bml0cyBkZWZpbmVkXG4gICAqIGluIFVuaXQgYXMgd2VsbCBhcyAnZGF0ZXRpbWUnIHJlcHJlc2VudGluZyBhIGRldGFpbGVkIGRhdGUvdGltZSBzdHJpbmcuXG4gICAqL1xuICBmb3JtYXRzKHRoaXM6IERhdGVBZGFwdGVyPFQ+KTogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgLyoqXG4gICAqIFBhcnNlcyB0aGUgZ2l2ZW4gYHZhbHVlYCBhbmQgcmV0dXJuIHRoZSBhc3NvY2lhdGVkIHRpbWVzdGFtcC5cbiAgICogQHBhcmFtIHZhbHVlIC0gdGhlIHZhbHVlIHRvIHBhcnNlICh1c3VhbGx5IGNvbWVzIGZyb20gdGhlIGRhdGEpXG4gICAqIEBwYXJhbSBbZm9ybWF0XSAtIHRoZSBleHBlY3RlZCBkYXRhIGZvcm1hdFxuICAgKi9cbiAgcGFyc2UodGhpczogRGF0ZUFkYXB0ZXI8VD4sIHZhbHVlOiB1bmtub3duLCBmb3JtYXQ/OiBUaW1lVW5pdCk6IG51bWJlciB8IG51bGw7XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgZGF0ZSBpbiB0aGUgc3BlY2lmaWVkIGBmb3JtYXRgIGZvciBhIGdpdmVuIGB0aW1lc3RhbXBgLlxuICAgKiBAcGFyYW0gdGltZXN0YW1wIC0gdGhlIHRpbWVzdGFtcCB0byBmb3JtYXRcbiAgICogQHBhcmFtIGZvcm1hdCAtIHRoZSBkYXRlL3RpbWUgdG9rZW5cbiAgICovXG4gIGZvcm1hdCh0aGlzOiBEYXRlQWRhcHRlcjxUPiwgdGltZXN0YW1wOiBudW1iZXIsIGZvcm1hdDogVGltZVVuaXQpOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgYGFtb3VudGAgb2YgYHVuaXRgIHRvIHRoZSBnaXZlbiBgdGltZXN0YW1wYC5cbiAgICogQHBhcmFtIHRpbWVzdGFtcCAtIHRoZSBpbnB1dCB0aW1lc3RhbXBcbiAgICogQHBhcmFtIGFtb3VudCAtIHRoZSBhbW91bnQgdG8gYWRkXG4gICAqIEBwYXJhbSB1bml0IC0gdGhlIHVuaXQgYXMgc3RyaW5nXG4gICAqL1xuICBhZGQodGhpczogRGF0ZUFkYXB0ZXI8VD4sIHRpbWVzdGFtcDogbnVtYmVyLCBhbW91bnQ6IG51bWJlciwgdW5pdDogVGltZVVuaXQpOiBudW1iZXI7XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYHVuaXRgIGJldHdlZW4gdGhlIGdpdmVuIHRpbWVzdGFtcHMuXG4gICAqIEBwYXJhbSBhIC0gdGhlIGlucHV0IHRpbWVzdGFtcCAocmVmZXJlbmNlKVxuICAgKiBAcGFyYW0gYiAtIHRoZSB0aW1lc3RhbXAgdG8gc3VidHJhY3RcbiAgICogQHBhcmFtIHVuaXQgLSB0aGUgdW5pdCBhcyBzdHJpbmdcbiAgICovXG4gIGRpZmYodGhpczogRGF0ZUFkYXB0ZXI8VD4sIGE6IG51bWJlciwgYjogbnVtYmVyLCB1bml0OiBUaW1lVW5pdCk6IG51bWJlcjtcbiAgLyoqXG4gICAqIFJldHVybnMgc3RhcnQgb2YgYHVuaXRgIGZvciB0aGUgZ2l2ZW4gYHRpbWVzdGFtcGAuXG4gICAqIEBwYXJhbSB0aW1lc3RhbXAgLSB0aGUgaW5wdXQgdGltZXN0YW1wXG4gICAqIEBwYXJhbSB1bml0IC0gdGhlIHVuaXQgYXMgc3RyaW5nXG4gICAqIEBwYXJhbSBbd2Vla2RheV0gLSB0aGUgSVNPIGRheSBvZiB0aGUgd2VlayB3aXRoIDEgYmVpbmcgTW9uZGF5XG4gICAqIGFuZCA3IGJlaW5nIFN1bmRheSAob25seSBuZWVkZWQgaWYgcGFyYW0gKnVuaXQqIGlzIGBpc29XZWVrYCkuXG4gICAqL1xuICBzdGFydE9mKHRoaXM6IERhdGVBZGFwdGVyPFQ+LCB0aW1lc3RhbXA6IG51bWJlciwgdW5pdDogVGltZVVuaXQgfCAnaXNvV2VlaycsIHdlZWtkYXk/OiBudW1iZXIpOiBudW1iZXI7XG4gIC8qKlxuICAgKiBSZXR1cm5zIGVuZCBvZiBgdW5pdGAgZm9yIHRoZSBnaXZlbiBgdGltZXN0YW1wYC5cbiAgICogQHBhcmFtIHRpbWVzdGFtcCAtIHRoZSBpbnB1dCB0aW1lc3RhbXBcbiAgICogQHBhcmFtIHVuaXQgLSB0aGUgdW5pdCBhcyBzdHJpbmdcbiAgICovXG4gIGVuZE9mKHRoaXM6IERhdGVBZGFwdGVyPFQ+LCB0aW1lc3RhbXA6IG51bWJlciwgdW5pdDogVGltZVVuaXQgfCAnaXNvV2VlaycpOiBudW1iZXI7XG59XG5cbmZ1bmN0aW9uIGFic3RyYWN0PFQgPSB2b2lkPigpOiBUIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQ6IENoZWNrIHRoYXQgYSBjb21wbGV0ZSBkYXRlIGFkYXB0ZXIgaXMgcHJvdmlkZWQuJyk7XG59XG5cbi8qKlxuICogRGF0ZSBhZGFwdGVyIChjdXJyZW50IHVzZWQgYnkgdGhlIHRpbWUgc2NhbGUpXG4gKiBAbmFtZXNwYWNlIENoYXJ0Ll9hZGFwdGVycy5fZGF0ZVxuICogQG1lbWJlcm9mIENoYXJ0Ll9hZGFwdGVyc1xuICogQHByaXZhdGVcbiAqL1xuY2xhc3MgRGF0ZUFkYXB0ZXJCYXNlIGltcGxlbWVudHMgRGF0ZUFkYXB0ZXIge1xuXG4gIC8qKlxuICAgKiBPdmVycmlkZSBkZWZhdWx0IGRhdGUgYWRhcHRlciBtZXRob2RzLlxuICAgKiBBY2NlcHRzIHR5cGUgcGFyYW1ldGVyIHRvIGRlZmluZSBvcHRpb25zIHR5cGUuXG4gICAqIEBleGFtcGxlXG4gICAqIENoYXJ0Ll9hZGFwdGVycy5fZGF0ZS5vdmVycmlkZTx7bXlBZGFwdGVyT3B0aW9uOiBzdHJpbmd9Pih7XG4gICAqICAgaW5pdCgpIHtcbiAgICogICAgIGNvbnNvbGUubG9nKHRoaXMub3B0aW9ucy5teUFkYXB0ZXJPcHRpb24pO1xuICAgKiAgIH1cbiAgICogfSlcbiAgICovXG4gIHN0YXRpYyBvdmVycmlkZTxUIGV4dGVuZHMgQW55T2JqZWN0ID0gQW55T2JqZWN0PihcbiAgICBtZW1iZXJzOiBQYXJ0aWFsPE9taXQ8RGF0ZUFkYXB0ZXI8VD4sICdvcHRpb25zJz4+XG4gICkge1xuICAgIE9iamVjdC5hc3NpZ24oRGF0ZUFkYXB0ZXJCYXNlLnByb3RvdHlwZSwgbWVtYmVycyk7XG4gIH1cblxuICByZWFkb25seSBvcHRpb25zOiBBbnlPYmplY3Q7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogQW55T2JqZWN0KSB7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgaW5pdCgpIHt9XG5cbiAgZm9ybWF0cygpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfVxuXG4gIHBhcnNlKCk6IG51bWJlciB8IG51bGwge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9XG5cbiAgZm9ybWF0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH1cblxuICBhZGQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfVxuXG4gIGRpZmYoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfVxuXG4gIHN0YXJ0T2YoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfVxuXG4gIGVuZE9mKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfZGF0ZTogRGF0ZUFkYXB0ZXJCYXNlXG59O1xuIiwgImltcG9ydCB7X2xvb2t1cEJ5S2V5LCBfcmxvb2t1cEJ5S2V5fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29sbGVjdGlvbi5qcyc7XG5pbXBvcnQge2dldFJlbGF0aXZlUG9zaXRpb259IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5kb20uanMnO1xuaW1wb3J0IHtfYW5nbGVCZXR3ZWVuLCBnZXRBbmdsZUZyb21Qb2ludH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IHtfaXNQb2ludEluQXJlYX0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4vY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IENoYXJ0XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vdHlwZXMvaW5kZXguanMnKS5DaGFydEV2ZW50IH0gQ2hhcnRFdmVudFxuICogQHR5cGVkZWYge3theGlzPzogc3RyaW5nLCBpbnRlcnNlY3Q/OiBib29sZWFuLCBpbmNsdWRlSW52aXNpYmxlPzogYm9vbGVhbn19IEludGVyYWN0aW9uT3B0aW9uc1xuICogQHR5cGVkZWYge3tkYXRhc2V0SW5kZXg6IG51bWJlciwgaW5kZXg6IG51bWJlciwgZWxlbWVudDogaW1wb3J0KCcuL2NvcmUuZWxlbWVudC5qcycpLmRlZmF1bHR9fSBJbnRlcmFjdGlvbkl0ZW1cbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi90eXBlcy9pbmRleC5qcycpLlBvaW50IH0gUG9pbnRcbiAqL1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBkbyBiaW5hcnkgc2VhcmNoIHdoZW4gcG9zc2libGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBtZXRhc2V0IC0gdGhlIGRhdGFzZXQgbWV0YVxuICogQHBhcmFtIHtzdHJpbmd9IGF4aXMgLSB0aGUgYXhpcyBtb2RlLiB4fHl8eHl8clxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gdGhlIHZhbHVlIHRvIGZpbmRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2ludGVyc2VjdF0gLSBzaG91bGQgdGhlIGVsZW1lbnQgaW50ZXJzZWN0XG4gKiBAcmV0dXJucyB7e2xvOm51bWJlciwgaGk6bnVtYmVyfX0gaW5kaWNlcyB0byBzZWFyY2ggZGF0YSBhcnJheSBiZXR3ZWVuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeVNlYXJjaChtZXRhc2V0LCBheGlzLCB2YWx1ZSwgaW50ZXJzZWN0KSB7XG4gIGNvbnN0IHtjb250cm9sbGVyLCBkYXRhLCBfc29ydGVkfSA9IG1ldGFzZXQ7XG4gIGNvbnN0IGlTY2FsZSA9IGNvbnRyb2xsZXIuX2NhY2hlZE1ldGEuaVNjYWxlO1xuICBpZiAoaVNjYWxlICYmIGF4aXMgPT09IGlTY2FsZS5heGlzICYmIGF4aXMgIT09ICdyJyAmJiBfc29ydGVkICYmIGRhdGEubGVuZ3RoKSB7XG4gICAgY29uc3QgbG9va3VwTWV0aG9kID0gaVNjYWxlLl9yZXZlcnNlUGl4ZWxzID8gX3Jsb29rdXBCeUtleSA6IF9sb29rdXBCeUtleTtcbiAgICBpZiAoIWludGVyc2VjdCkge1xuICAgICAgcmV0dXJuIGxvb2t1cE1ldGhvZChkYXRhLCBheGlzLCB2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChjb250cm9sbGVyLl9zaGFyZWRPcHRpb25zKSB7XG4gICAgICAvLyBfc2hhcmVkT3B0aW9ucyBpbmRpY2F0ZXMgdGhhdCBlYWNoIGVsZW1lbnQgaGFzIGVxdWFsIG9wdGlvbnMgLT4gZXF1YWwgcHJvcG9ydGlvbnNcbiAgICAgIC8vIFNvIHdlIGNhbiBkbyBhIHJhbmdlZCBiaW5hcnkgc2VhcmNoIGJhc2VkIG9uIHRoZSByYW5nZSBvZiBmaXJzdCBlbGVtZW50IGFuZFxuICAgICAgLy8gYmUgY29uZmlkZW50IHRvIGdldCB0aGUgZnVsbCByYW5nZSBvZiBpbmRpY2VzIHRoYXQgY2FuIGludGVyc2VjdCB3aXRoIHRoZSB2YWx1ZS5cbiAgICAgIGNvbnN0IGVsID0gZGF0YVswXTtcbiAgICAgIGNvbnN0IHJhbmdlID0gdHlwZW9mIGVsLmdldFJhbmdlID09PSAnZnVuY3Rpb24nICYmIGVsLmdldFJhbmdlKGF4aXMpO1xuICAgICAgaWYgKHJhbmdlKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gbG9va3VwTWV0aG9kKGRhdGEsIGF4aXMsIHZhbHVlIC0gcmFuZ2UpO1xuICAgICAgICBjb25zdCBlbmQgPSBsb29rdXBNZXRob2QoZGF0YSwgYXhpcywgdmFsdWUgKyByYW5nZSk7XG4gICAgICAgIHJldHVybiB7bG86IHN0YXJ0LmxvLCBoaTogZW5kLmhpfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLy8gRGVmYXVsdCB0byBhbGwgZWxlbWVudHMsIHdoZW4gYmluYXJ5IHNlYXJjaCBjYW4gbm90IGJlIHVzZWQuXG4gIHJldHVybiB7bG86IDAsIGhpOiBkYXRhLmxlbmd0aCAtIDF9O1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBzZWxlY3QgY2FuZGlkYXRlIGVsZW1lbnRzIGZvciBpbnRlcmFjdGlvblxuICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzIC0gdGhlIGF4aXMgbW9kZS4geHx5fHh5fHJcbiAqIEBwYXJhbSB7UG9pbnR9IHBvc2l0aW9uIC0gdGhlIHBvaW50IHRvIGJlIG5lYXJlc3QgdG8sIGluIHJlbGF0aXZlIGNvb3JkaW5hdGVzXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBoYW5kbGVyIC0gdGhlIGNhbGxiYWNrIHRvIGV4ZWN1dGUgZm9yIGVhY2ggdmlzaWJsZSBpdGVtXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpbnRlcnNlY3RdIC0gY29uc2lkZXIgaW50ZXJzZWN0aW5nIGl0ZW1zXG4gKi9cbmZ1bmN0aW9uIGV2YWx1YXRlSW50ZXJhY3Rpb25JdGVtcyhjaGFydCwgYXhpcywgcG9zaXRpb24sIGhhbmRsZXIsIGludGVyc2VjdCkge1xuICBjb25zdCBtZXRhc2V0cyA9IGNoYXJ0LmdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKTtcbiAgY29uc3QgdmFsdWUgPSBwb3NpdGlvbltheGlzXTtcbiAgZm9yIChsZXQgaSA9IDAsIGlsZW4gPSBtZXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBjb25zdCB7aW5kZXgsIGRhdGF9ID0gbWV0YXNldHNbaV07XG4gICAgY29uc3Qge2xvLCBoaX0gPSBiaW5hcnlTZWFyY2gobWV0YXNldHNbaV0sIGF4aXMsIHZhbHVlLCBpbnRlcnNlY3QpO1xuICAgIGZvciAobGV0IGogPSBsbzsgaiA8PSBoaTsgKytqKSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gZGF0YVtqXTtcbiAgICAgIGlmICghZWxlbWVudC5za2lwKSB7XG4gICAgICAgIGhhbmRsZXIoZWxlbWVudCwgaW5kZXgsIGopO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEdldCBhIGRpc3RhbmNlIG1ldHJpYyBmdW5jdGlvbiBmb3IgdHdvIHBvaW50cyBiYXNlZCBvbiB0aGVcbiAqIGF4aXMgbW9kZSBzZXR0aW5nXG4gKiBAcGFyYW0ge3N0cmluZ30gYXhpcyAtIHRoZSBheGlzIG1vZGUuIHh8eXx4eXxyXG4gKi9cbmZ1bmN0aW9uIGdldERpc3RhbmNlTWV0cmljRm9yQXhpcyhheGlzKSB7XG4gIGNvbnN0IHVzZVggPSBheGlzLmluZGV4T2YoJ3gnKSAhPT0gLTE7XG4gIGNvbnN0IHVzZVkgPSBheGlzLmluZGV4T2YoJ3knKSAhPT0gLTE7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHB0MSwgcHQyKSB7XG4gICAgY29uc3QgZGVsdGFYID0gdXNlWCA/IE1hdGguYWJzKHB0MS54IC0gcHQyLngpIDogMDtcbiAgICBjb25zdCBkZWx0YVkgPSB1c2VZID8gTWF0aC5hYnMocHQxLnkgLSBwdDIueSkgOiAwO1xuICAgIHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3coZGVsdGFYLCAyKSArIE1hdGgucG93KGRlbHRhWSwgMikpO1xuICB9O1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGl0ZW1zIHRoYXQgaW50ZXJzZWN0IHRoZSBldmVudCBwb3NpdGlvblxuICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnRcbiAqIEBwYXJhbSB7UG9pbnR9IHBvc2l0aW9uIC0gdGhlIHBvaW50IHRvIGJlIG5lYXJlc3QgdG8sIGluIHJlbGF0aXZlIGNvb3JkaW5hdGVzXG4gKiBAcGFyYW0ge3N0cmluZ30gYXhpcyAtIHRoZSBheGlzIG1vZGUuIHh8eXx4eXxyXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXSAtIHVzZSB0aGUgZWxlbWVudCdzIGFuaW1hdGlvbiB0YXJnZXQgaW5zdGVhZCBvZiBjdXJyZW50IHBvc2l0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpbmNsdWRlSW52aXNpYmxlXSAtIGluY2x1ZGUgaW52aXNpYmxlIHBvaW50cyB0aGF0IGFyZSBvdXRzaWRlIG9mIHRoZSBjaGFydCBhcmVhXG4gKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gdGhlIG5lYXJlc3QgaXRlbXNcbiAqL1xuZnVuY3Rpb24gZ2V0SW50ZXJzZWN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCB1c2VGaW5hbFBvc2l0aW9uLCBpbmNsdWRlSW52aXNpYmxlKSB7XG4gIGNvbnN0IGl0ZW1zID0gW107XG5cbiAgaWYgKCFpbmNsdWRlSW52aXNpYmxlICYmICFjaGFydC5pc1BvaW50SW5BcmVhKHBvc2l0aW9uKSkge1xuICAgIHJldHVybiBpdGVtcztcbiAgfVxuXG4gIGNvbnN0IGV2YWx1YXRpb25GdW5jID0gZnVuY3Rpb24oZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleCkge1xuICAgIGlmICghaW5jbHVkZUludmlzaWJsZSAmJiAhX2lzUG9pbnRJbkFyZWEoZWxlbWVudCwgY2hhcnQuY2hhcnRBcmVhLCAwKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZWxlbWVudC5pblJhbmdlKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHVzZUZpbmFsUG9zaXRpb24pKSB7XG4gICAgICBpdGVtcy5wdXNoKHtlbGVtZW50LCBkYXRhc2V0SW5kZXgsIGluZGV4fSk7XG4gICAgfVxuICB9O1xuXG4gIGV2YWx1YXRlSW50ZXJhY3Rpb25JdGVtcyhjaGFydCwgYXhpcywgcG9zaXRpb24sIGV2YWx1YXRpb25GdW5jLCB0cnVlKTtcbiAgcmV0dXJuIGl0ZW1zO1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGl0ZW1zIG5lYXJlc3QgdG8gdGhlIGV2ZW50IHBvc2l0aW9uIGZvciBhIHJhZGlhbCBjaGFydFxuICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgdG8gbG9vayBhdCBlbGVtZW50cyBmcm9tXG4gKiBAcGFyYW0ge1BvaW50fSBwb3NpdGlvbiAtIHRoZSBwb2ludCB0byBiZSBuZWFyZXN0IHRvLCBpbiByZWxhdGl2ZSBjb29yZGluYXRlc1xuICogQHBhcmFtIHtzdHJpbmd9IGF4aXMgLSB0aGUgYXhlcyBhbG9uZyB3aGljaCB0byBtZWFzdXJlIGRpc3RhbmNlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXSAtIHVzZSB0aGUgZWxlbWVudCdzIGFuaW1hdGlvbiB0YXJnZXQgaW5zdGVhZCBvZiBjdXJyZW50IHBvc2l0aW9uXG4gKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gdGhlIG5lYXJlc3QgaXRlbXNcbiAqL1xuZnVuY3Rpb24gZ2V0TmVhcmVzdFJhZGlhbEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgdXNlRmluYWxQb3NpdGlvbikge1xuICBsZXQgaXRlbXMgPSBbXTtcblxuICBmdW5jdGlvbiBldmFsdWF0aW9uRnVuYyhlbGVtZW50LCBkYXRhc2V0SW5kZXgsIGluZGV4KSB7XG4gICAgY29uc3Qge3N0YXJ0QW5nbGUsIGVuZEFuZ2xlfSA9IGVsZW1lbnQuZ2V0UHJvcHMoWydzdGFydEFuZ2xlJywgJ2VuZEFuZ2xlJ10sIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIGNvbnN0IHthbmdsZX0gPSBnZXRBbmdsZUZyb21Qb2ludChlbGVtZW50LCB7eDogcG9zaXRpb24ueCwgeTogcG9zaXRpb24ueX0pO1xuXG4gICAgaWYgKF9hbmdsZUJldHdlZW4oYW5nbGUsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlKSkge1xuICAgICAgaXRlbXMucHVzaCh7ZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleH0pO1xuICAgIH1cbiAgfVxuXG4gIGV2YWx1YXRlSW50ZXJhY3Rpb25JdGVtcyhjaGFydCwgYXhpcywgcG9zaXRpb24sIGV2YWx1YXRpb25GdW5jKTtcbiAgcmV0dXJuIGl0ZW1zO1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGl0ZW1zIG5lYXJlc3QgdG8gdGhlIGV2ZW50IHBvc2l0aW9uIGZvciBhIGNhcnRlc2lhbiBjaGFydFxuICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgdG8gbG9vayBhdCBlbGVtZW50cyBmcm9tXG4gKiBAcGFyYW0ge1BvaW50fSBwb3NpdGlvbiAtIHRoZSBwb2ludCB0byBiZSBuZWFyZXN0IHRvLCBpbiByZWxhdGl2ZSBjb29yZGluYXRlc1xuICogQHBhcmFtIHtzdHJpbmd9IGF4aXMgLSB0aGUgYXhlcyBhbG9uZyB3aGljaCB0byBtZWFzdXJlIGRpc3RhbmNlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpbnRlcnNlY3RdIC0gaWYgdHJ1ZSwgb25seSBjb25zaWRlciBpdGVtcyB0aGF0IGludGVyc2VjdCB0aGUgcG9zaXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3VzZUZpbmFsUG9zaXRpb25dIC0gdXNlIHRoZSBlbGVtZW50J3MgYW5pbWF0aW9uIHRhcmdldCBpbnN0ZWFkIG9mIGN1cnJlbnQgcG9zaXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2luY2x1ZGVJbnZpc2libGVdIC0gaW5jbHVkZSBpbnZpc2libGUgcG9pbnRzIHRoYXQgYXJlIG91dHNpZGUgb2YgdGhlIGNoYXJ0IGFyZWFcbiAqIEByZXR1cm4ge0ludGVyYWN0aW9uSXRlbVtdfSB0aGUgbmVhcmVzdCBpdGVtc1xuICovXG5mdW5jdGlvbiBnZXROZWFyZXN0Q2FydGVzaWFuSXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCBpbnRlcnNlY3QsIHVzZUZpbmFsUG9zaXRpb24sIGluY2x1ZGVJbnZpc2libGUpIHtcbiAgbGV0IGl0ZW1zID0gW107XG4gIGNvbnN0IGRpc3RhbmNlTWV0cmljID0gZ2V0RGlzdGFuY2VNZXRyaWNGb3JBeGlzKGF4aXMpO1xuICBsZXQgbWluRGlzdGFuY2UgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG5cbiAgZnVuY3Rpb24gZXZhbHVhdGlvbkZ1bmMoZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleCkge1xuICAgIGNvbnN0IGluUmFuZ2UgPSBlbGVtZW50LmluUmFuZ2UocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgaWYgKGludGVyc2VjdCAmJiAhaW5SYW5nZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNlbnRlciA9IGVsZW1lbnQuZ2V0Q2VudGVyUG9pbnQodXNlRmluYWxQb3NpdGlvbik7XG4gICAgY29uc3QgcG9pbnRJbkFyZWEgPSAhIWluY2x1ZGVJbnZpc2libGUgfHwgY2hhcnQuaXNQb2ludEluQXJlYShjZW50ZXIpO1xuICAgIGlmICghcG9pbnRJbkFyZWEgJiYgIWluUmFuZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkaXN0YW5jZSA9IGRpc3RhbmNlTWV0cmljKHBvc2l0aW9uLCBjZW50ZXIpO1xuICAgIGlmIChkaXN0YW5jZSA8IG1pbkRpc3RhbmNlKSB7XG4gICAgICBpdGVtcyA9IFt7ZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleH1dO1xuICAgICAgbWluRGlzdGFuY2UgPSBkaXN0YW5jZTtcbiAgICB9IGVsc2UgaWYgKGRpc3RhbmNlID09PSBtaW5EaXN0YW5jZSkge1xuICAgICAgLy8gQ2FuIGhhdmUgbXVsdGlwbGUgaXRlbXMgYXQgdGhlIHNhbWUgZGlzdGFuY2UgaW4gd2hpY2ggY2FzZSB3ZSBzb3J0IGJ5IHNpemVcbiAgICAgIGl0ZW1zLnB1c2goe2VsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXh9KTtcbiAgICB9XG4gIH1cblxuICBldmFsdWF0ZUludGVyYWN0aW9uSXRlbXMoY2hhcnQsIGF4aXMsIHBvc2l0aW9uLCBldmFsdWF0aW9uRnVuYyk7XG4gIHJldHVybiBpdGVtcztcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHRoZSBpdGVtcyBuZWFyZXN0IHRvIHRoZSBldmVudCBwb3NpdGlvbiBjb25zaWRlcmluZyBhbGwgdmlzaWJsZSBpdGVtcyBpbiB0aGUgY2hhcnRcbiAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHRvIGxvb2sgYXQgZWxlbWVudHMgZnJvbVxuICogQHBhcmFtIHtQb2ludH0gcG9zaXRpb24gLSB0aGUgcG9pbnQgdG8gYmUgbmVhcmVzdCB0bywgaW4gcmVsYXRpdmUgY29vcmRpbmF0ZXNcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzIC0gdGhlIGF4ZXMgYWxvbmcgd2hpY2ggdG8gbWVhc3VyZSBkaXN0YW5jZVxuICogQHBhcmFtIHtib29sZWFufSBbaW50ZXJzZWN0XSAtIGlmIHRydWUsIG9ubHkgY29uc2lkZXIgaXRlbXMgdGhhdCBpbnRlcnNlY3QgdGhlIHBvc2l0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXSAtIHVzZSB0aGUgZWxlbWVudCdzIGFuaW1hdGlvbiB0YXJnZXQgaW5zdGVhZCBvZiBjdXJyZW50IHBvc2l0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpbmNsdWRlSW52aXNpYmxlXSAtIGluY2x1ZGUgaW52aXNpYmxlIHBvaW50cyB0aGF0IGFyZSBvdXRzaWRlIG9mIHRoZSBjaGFydCBhcmVhXG4gKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gdGhlIG5lYXJlc3QgaXRlbXNcbiAqL1xuZnVuY3Rpb24gZ2V0TmVhcmVzdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgaW50ZXJzZWN0LCB1c2VGaW5hbFBvc2l0aW9uLCBpbmNsdWRlSW52aXNpYmxlKSB7XG4gIGlmICghaW5jbHVkZUludmlzaWJsZSAmJiAhY2hhcnQuaXNQb2ludEluQXJlYShwb3NpdGlvbikpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICByZXR1cm4gYXhpcyA9PT0gJ3InICYmICFpbnRlcnNlY3RcbiAgICA/IGdldE5lYXJlc3RSYWRpYWxJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIHVzZUZpbmFsUG9zaXRpb24pXG4gICAgOiBnZXROZWFyZXN0Q2FydGVzaWFuSXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCBpbnRlcnNlY3QsIHVzZUZpbmFsUG9zaXRpb24sIGluY2x1ZGVJbnZpc2libGUpO1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGl0ZW1zIG1hdGNoaW5nIGFsb25nIHRoZSBnaXZlbiBYIG9yIFkgYXhpc1xuICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgdG8gbG9vayBhdCBlbGVtZW50cyBmcm9tXG4gKiBAcGFyYW0ge1BvaW50fSBwb3NpdGlvbiAtIHRoZSBwb2ludCB0byBiZSBuZWFyZXN0IHRvLCBpbiByZWxhdGl2ZSBjb29yZGluYXRlc1xuICogQHBhcmFtIHtzdHJpbmd9IGF4aXMgLSB0aGUgYXhpcyB0byBtYXRjaFxuICogQHBhcmFtIHtib29sZWFufSBbaW50ZXJzZWN0XSAtIGlmIHRydWUsIG9ubHkgY29uc2lkZXIgaXRlbXMgdGhhdCBpbnRlcnNlY3QgdGhlIHBvc2l0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXSAtIHVzZSB0aGUgZWxlbWVudCdzIGFuaW1hdGlvbiB0YXJnZXQgaW5zdGVhZCBvZiBjdXJyZW50IHBvc2l0aW9uXG4gKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gdGhlIG5lYXJlc3QgaXRlbXNcbiAqL1xuZnVuY3Rpb24gZ2V0QXhpc0l0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgaW50ZXJzZWN0LCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gIGNvbnN0IGl0ZW1zID0gW107XG4gIGNvbnN0IHJhbmdlTWV0aG9kID0gYXhpcyA9PT0gJ3gnID8gJ2luWFJhbmdlJyA6ICdpbllSYW5nZSc7XG4gIGxldCBpbnRlcnNlY3RzSXRlbSA9IGZhbHNlO1xuXG4gIGV2YWx1YXRlSW50ZXJhY3Rpb25JdGVtcyhjaGFydCwgYXhpcywgcG9zaXRpb24sIChlbGVtZW50LCBkYXRhc2V0SW5kZXgsIGluZGV4KSA9PiB7XG4gICAgaWYgKGVsZW1lbnRbcmFuZ2VNZXRob2RdKHBvc2l0aW9uW2F4aXNdLCB1c2VGaW5hbFBvc2l0aW9uKSkge1xuICAgICAgaXRlbXMucHVzaCh7ZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleH0pO1xuICAgICAgaW50ZXJzZWN0c0l0ZW0gPSBpbnRlcnNlY3RzSXRlbSB8fCBlbGVtZW50LmluUmFuZ2UocG9zaXRpb24ueCwgcG9zaXRpb24ueSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgfVxuICB9KTtcblxuICAvLyBJZiB3ZSB3YW50IHRvIHRyaWdnZXIgb24gYW4gaW50ZXJzZWN0IGFuZCB3ZSBkb24ndCBoYXZlIGFueSBpdGVtc1xuICAvLyB0aGF0IGludGVyc2VjdCB0aGUgcG9zaXRpb24sIHJldHVybiBub3RoaW5nXG4gIGlmIChpbnRlcnNlY3QgJiYgIWludGVyc2VjdHNJdGVtKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHJldHVybiBpdGVtcztcbn1cblxuLyoqXG4gKiBDb250YWlucyBpbnRlcmFjdGlvbiByZWxhdGVkIGZ1bmN0aW9uc1xuICogQG5hbWVzcGFjZSBDaGFydC5JbnRlcmFjdGlvblxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8vIFBhcnQgb2YgdGhlIHB1YmxpYyBBUEkgdG8gZmFjaWxpdGF0ZSBkZXZlbG9wZXJzIGNyZWF0aW5nIHRoZWlyIG93biBtb2Rlc1xuICBldmFsdWF0ZUludGVyYWN0aW9uSXRlbXMsXG5cbiAgLy8gSGVscGVyIGZ1bmN0aW9uIGZvciBkaWZmZXJlbnQgbW9kZXNcbiAgbW9kZXM6IHtcbiAgICAvKipcblx0XHQgKiBSZXR1cm5zIGl0ZW1zIGF0IHRoZSBzYW1lIGluZGV4LiBJZiB0aGUgb3B0aW9ucy5pbnRlcnNlY3QgcGFyYW1ldGVyIGlzIHRydWUsIHdlIG9ubHkgcmV0dXJuIGl0ZW1zIGlmIHdlIGludGVyc2VjdCBzb21ldGhpbmdcblx0XHQgKiBJZiB0aGUgb3B0aW9ucy5pbnRlcnNlY3QgbW9kZSBpcyBmYWxzZSwgd2UgZmluZCB0aGUgbmVhcmVzdCBpdGVtIGFuZCByZXR1cm4gdGhlIGl0ZW1zIGF0IHRoZSBzYW1lIGluZGV4IGFzIHRoYXQgaXRlbVxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy5pbmRleFxuXHRcdCAqIEBzaW5jZSB2Mi40LjBcblx0XHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB3ZSBhcmUgcmV0dXJuaW5nIGl0ZW1zIGZyb21cblx0XHQgKiBAcGFyYW0ge0V2ZW50fSBlIC0gdGhlIGV2ZW50IHdlIGFyZSBmaW5kIHRoaW5ncyBhdFxuXHRcdCAqIEBwYXJhbSB7SW50ZXJhY3Rpb25PcHRpb25zfSBvcHRpb25zIC0gb3B0aW9ucyB0byB1c2Vcblx0XHQgKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXSAtIHVzZSBmaW5hbCBlbGVtZW50IHBvc2l0aW9uIChhbmltYXRpb24gdGFyZ2V0KVxuXHRcdCAqIEByZXR1cm4ge0ludGVyYWN0aW9uSXRlbVtdfSAtIGl0ZW1zIHRoYXQgYXJlIGZvdW5kXG5cdFx0ICovXG4gICAgaW5kZXgoY2hhcnQsIGUsIG9wdGlvbnMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG4gICAgICAvLyBEZWZhdWx0IGF4aXMgZm9yIGluZGV4IG1vZGUgaXMgJ3gnIHRvIG1hdGNoIG9sZCBiZWhhdmlvdXJcbiAgICAgIGNvbnN0IGF4aXMgPSBvcHRpb25zLmF4aXMgfHwgJ3gnO1xuICAgICAgY29uc3QgaW5jbHVkZUludmlzaWJsZSA9IG9wdGlvbnMuaW5jbHVkZUludmlzaWJsZSB8fCBmYWxzZTtcbiAgICAgIGNvbnN0IGl0ZW1zID0gb3B0aW9ucy5pbnRlcnNlY3RcbiAgICAgICAgPyBnZXRJbnRlcnNlY3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIHVzZUZpbmFsUG9zaXRpb24sIGluY2x1ZGVJbnZpc2libGUpXG4gICAgICAgIDogZ2V0TmVhcmVzdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgZmFsc2UsIHVzZUZpbmFsUG9zaXRpb24sIGluY2x1ZGVJbnZpc2libGUpO1xuICAgICAgY29uc3QgZWxlbWVudHMgPSBbXTtcblxuICAgICAgaWYgKCFpdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuXG4gICAgICBjaGFydC5nZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCkuZm9yRWFjaCgobWV0YSkgPT4ge1xuICAgICAgICBjb25zdCBpbmRleCA9IGl0ZW1zWzBdLmluZGV4O1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gbWV0YS5kYXRhW2luZGV4XTtcblxuICAgICAgICAvLyBkb24ndCBjb3VudCBpdGVtcyB0aGF0IGFyZSBza2lwcGVkIChudWxsIGRhdGEpXG4gICAgICAgIGlmIChlbGVtZW50ICYmICFlbGVtZW50LnNraXApIHtcbiAgICAgICAgICBlbGVtZW50cy5wdXNoKHtlbGVtZW50LCBkYXRhc2V0SW5kZXg6IG1ldGEuaW5kZXgsIGluZGV4fSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gZWxlbWVudHM7XG4gICAgfSxcblxuICAgIC8qKlxuXHRcdCAqIFJldHVybnMgaXRlbXMgaW4gdGhlIHNhbWUgZGF0YXNldC4gSWYgdGhlIG9wdGlvbnMuaW50ZXJzZWN0IHBhcmFtZXRlciBpcyB0cnVlLCB3ZSBvbmx5IHJldHVybiBpdGVtcyBpZiB3ZSBpbnRlcnNlY3Qgc29tZXRoaW5nXG5cdFx0ICogSWYgdGhlIG9wdGlvbnMuaW50ZXJzZWN0IGlzIGZhbHNlLCB3ZSBmaW5kIHRoZSBuZWFyZXN0IGl0ZW0gYW5kIHJldHVybiB0aGUgaXRlbXMgaW4gdGhhdCBkYXRhc2V0XG5cdFx0ICogQGZ1bmN0aW9uIENoYXJ0LkludGVyYWN0aW9uLm1vZGVzLmRhdGFzZXRcblx0XHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB3ZSBhcmUgcmV0dXJuaW5nIGl0ZW1zIGZyb21cblx0XHQgKiBAcGFyYW0ge0V2ZW50fSBlIC0gdGhlIGV2ZW50IHdlIGFyZSBmaW5kIHRoaW5ncyBhdFxuXHRcdCAqIEBwYXJhbSB7SW50ZXJhY3Rpb25PcHRpb25zfSBvcHRpb25zIC0gb3B0aW9ucyB0byB1c2Vcblx0XHQgKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXSAtIHVzZSBmaW5hbCBlbGVtZW50IHBvc2l0aW9uIChhbmltYXRpb24gdGFyZ2V0KVxuXHRcdCAqIEByZXR1cm4ge0ludGVyYWN0aW9uSXRlbVtdfSAtIGl0ZW1zIHRoYXQgYXJlIGZvdW5kXG5cdFx0ICovXG4gICAgZGF0YXNldChjaGFydCwgZSwgb3B0aW9ucywgdXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgY29uc3QgcG9zaXRpb24gPSBnZXRSZWxhdGl2ZVBvc2l0aW9uKGUsIGNoYXJ0KTtcbiAgICAgIGNvbnN0IGF4aXMgPSBvcHRpb25zLmF4aXMgfHwgJ3h5JztcbiAgICAgIGNvbnN0IGluY2x1ZGVJbnZpc2libGUgPSBvcHRpb25zLmluY2x1ZGVJbnZpc2libGUgfHwgZmFsc2U7XG4gICAgICBsZXQgaXRlbXMgPSBvcHRpb25zLmludGVyc2VjdFxuICAgICAgICA/IGdldEludGVyc2VjdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSkgOlxuICAgICAgICBnZXROZWFyZXN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCBmYWxzZSwgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSk7XG5cbiAgICAgIGlmIChpdGVtcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGRhdGFzZXRJbmRleCA9IGl0ZW1zWzBdLmRhdGFzZXRJbmRleDtcbiAgICAgICAgY29uc3QgZGF0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCkuZGF0YTtcbiAgICAgICAgaXRlbXMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7ZWxlbWVudDogZGF0YVtpXSwgZGF0YXNldEluZGV4LCBpbmRleDogaX0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBpdGVtcztcbiAgICB9LFxuXG4gICAgLyoqXG5cdFx0ICogUG9pbnQgbW9kZSByZXR1cm5zIGFsbCBlbGVtZW50cyB0aGF0IGhpdCB0ZXN0IGJhc2VkIG9uIHRoZSBldmVudCBwb3NpdGlvblxuXHRcdCAqIG9mIHRoZSBldmVudFxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy5pbnRlcnNlY3Rcblx0XHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB3ZSBhcmUgcmV0dXJuaW5nIGl0ZW1zIGZyb21cblx0XHQgKiBAcGFyYW0ge0V2ZW50fSBlIC0gdGhlIGV2ZW50IHdlIGFyZSBmaW5kIHRoaW5ncyBhdFxuXHRcdCAqIEBwYXJhbSB7SW50ZXJhY3Rpb25PcHRpb25zfSBvcHRpb25zIC0gb3B0aW9ucyB0byB1c2Vcblx0XHQgKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXSAtIHVzZSBmaW5hbCBlbGVtZW50IHBvc2l0aW9uIChhbmltYXRpb24gdGFyZ2V0KVxuXHRcdCAqIEByZXR1cm4ge0ludGVyYWN0aW9uSXRlbVtdfSAtIGl0ZW1zIHRoYXQgYXJlIGZvdW5kXG5cdFx0ICovXG4gICAgcG9pbnQoY2hhcnQsIGUsIG9wdGlvbnMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG4gICAgICBjb25zdCBheGlzID0gb3B0aW9ucy5heGlzIHx8ICd4eSc7XG4gICAgICBjb25zdCBpbmNsdWRlSW52aXNpYmxlID0gb3B0aW9ucy5pbmNsdWRlSW52aXNpYmxlIHx8IGZhbHNlO1xuICAgICAgcmV0dXJuIGdldEludGVyc2VjdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSk7XG4gICAgfSxcblxuICAgIC8qKlxuXHRcdCAqIG5lYXJlc3QgbW9kZSByZXR1cm5zIHRoZSBlbGVtZW50IGNsb3Nlc3QgdG8gdGhlIHBvaW50XG5cdFx0ICogQGZ1bmN0aW9uIENoYXJ0LkludGVyYWN0aW9uLm1vZGVzLmludGVyc2VjdFxuXHRcdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHdlIGFyZSByZXR1cm5pbmcgaXRlbXMgZnJvbVxuXHRcdCAqIEBwYXJhbSB7RXZlbnR9IGUgLSB0aGUgZXZlbnQgd2UgYXJlIGZpbmQgdGhpbmdzIGF0XG5cdFx0ICogQHBhcmFtIHtJbnRlcmFjdGlvbk9wdGlvbnN9IG9wdGlvbnMgLSBvcHRpb25zIHRvIHVzZVxuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW3VzZUZpbmFsUG9zaXRpb25dIC0gdXNlIGZpbmFsIGVsZW1lbnQgcG9zaXRpb24gKGFuaW1hdGlvbiB0YXJnZXQpXG5cdFx0ICogQHJldHVybiB7SW50ZXJhY3Rpb25JdGVtW119IC0gaXRlbXMgdGhhdCBhcmUgZm91bmRcblx0XHQgKi9cbiAgICBuZWFyZXN0KGNoYXJ0LCBlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuICAgICAgY29uc3QgYXhpcyA9IG9wdGlvbnMuYXhpcyB8fCAneHknO1xuICAgICAgY29uc3QgaW5jbHVkZUludmlzaWJsZSA9IG9wdGlvbnMuaW5jbHVkZUludmlzaWJsZSB8fCBmYWxzZTtcbiAgICAgIHJldHVybiBnZXROZWFyZXN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCBvcHRpb25zLmludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSk7XG4gICAgfSxcblxuICAgIC8qKlxuXHRcdCAqIHggbW9kZSByZXR1cm5zIHRoZSBlbGVtZW50cyB0aGF0IGhpdC10ZXN0IGF0IHRoZSBjdXJyZW50IHggY29vcmRpbmF0ZVxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy54XG5cdFx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgd2UgYXJlIHJldHVybmluZyBpdGVtcyBmcm9tXG5cdFx0ICogQHBhcmFtIHtFdmVudH0gZSAtIHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcblx0XHQgKiBAcGFyYW0ge0ludGVyYWN0aW9uT3B0aW9uc30gb3B0aW9ucyAtIG9wdGlvbnMgdG8gdXNlXG5cdFx0ICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl0gLSB1c2UgZmluYWwgZWxlbWVudCBwb3NpdGlvbiAoYW5pbWF0aW9uIHRhcmdldClcblx0XHQgKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gLSBpdGVtcyB0aGF0IGFyZSBmb3VuZFxuXHRcdCAqL1xuICAgIHgoY2hhcnQsIGUsIG9wdGlvbnMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG4gICAgICByZXR1cm4gZ2V0QXhpc0l0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgJ3gnLCBvcHRpb25zLmludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgfSxcblxuICAgIC8qKlxuXHRcdCAqIHkgbW9kZSByZXR1cm5zIHRoZSBlbGVtZW50cyB0aGF0IGhpdC10ZXN0IGF0IHRoZSBjdXJyZW50IHkgY29vcmRpbmF0ZVxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy55XG5cdFx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgd2UgYXJlIHJldHVybmluZyBpdGVtcyBmcm9tXG5cdFx0ICogQHBhcmFtIHtFdmVudH0gZSAtIHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcblx0XHQgKiBAcGFyYW0ge0ludGVyYWN0aW9uT3B0aW9uc30gb3B0aW9ucyAtIG9wdGlvbnMgdG8gdXNlXG5cdFx0ICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl0gLSB1c2UgZmluYWwgZWxlbWVudCBwb3NpdGlvbiAoYW5pbWF0aW9uIHRhcmdldClcblx0XHQgKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gLSBpdGVtcyB0aGF0IGFyZSBmb3VuZFxuXHRcdCAqL1xuICAgIHkoY2hhcnQsIGUsIG9wdGlvbnMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG4gICAgICByZXR1cm4gZ2V0QXhpc0l0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgJ3knLCBvcHRpb25zLmludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgfVxuICB9XG59O1xuIiwgImltcG9ydCB7ZGVmaW5lZCwgZWFjaCwgaXNPYmplY3R9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7dG9QYWRkaW5nfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMub3B0aW9ucy5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4vY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IENoYXJ0XG4gKi9cblxuY29uc3QgU1RBVElDX1BPU0lUSU9OUyA9IFsnbGVmdCcsICd0b3AnLCAncmlnaHQnLCAnYm90dG9tJ107XG5cbmZ1bmN0aW9uIGZpbHRlckJ5UG9zaXRpb24oYXJyYXksIHBvc2l0aW9uKSB7XG4gIHJldHVybiBhcnJheS5maWx0ZXIodiA9PiB2LnBvcyA9PT0gcG9zaXRpb24pO1xufVxuXG5mdW5jdGlvbiBmaWx0ZXJEeW5hbWljUG9zaXRpb25CeUF4aXMoYXJyYXksIGF4aXMpIHtcbiAgcmV0dXJuIGFycmF5LmZpbHRlcih2ID0+IFNUQVRJQ19QT1NJVElPTlMuaW5kZXhPZih2LnBvcykgPT09IC0xICYmIHYuYm94LmF4aXMgPT09IGF4aXMpO1xufVxuXG5mdW5jdGlvbiBzb3J0QnlXZWlnaHQoYXJyYXksIHJldmVyc2UpIHtcbiAgcmV0dXJuIGFycmF5LnNvcnQoKGEsIGIpID0+IHtcbiAgICBjb25zdCB2MCA9IHJldmVyc2UgPyBiIDogYTtcbiAgICBjb25zdCB2MSA9IHJldmVyc2UgPyBhIDogYjtcbiAgICByZXR1cm4gdjAud2VpZ2h0ID09PSB2MS53ZWlnaHQgP1xuICAgICAgdjAuaW5kZXggLSB2MS5pbmRleCA6XG4gICAgICB2MC53ZWlnaHQgLSB2MS53ZWlnaHQ7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB3cmFwQm94ZXMoYm94ZXMpIHtcbiAgY29uc3QgbGF5b3V0Qm94ZXMgPSBbXTtcbiAgbGV0IGksIGlsZW4sIGJveCwgcG9zLCBzdGFjaywgc3RhY2tXZWlnaHQ7XG5cbiAgZm9yIChpID0gMCwgaWxlbiA9IChib3hlcyB8fCBbXSkubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgYm94ID0gYm94ZXNbaV07XG4gICAgKHtwb3NpdGlvbjogcG9zLCBvcHRpb25zOiB7c3RhY2ssIHN0YWNrV2VpZ2h0ID0gMX19ID0gYm94KTtcbiAgICBsYXlvdXRCb3hlcy5wdXNoKHtcbiAgICAgIGluZGV4OiBpLFxuICAgICAgYm94LFxuICAgICAgcG9zLFxuICAgICAgaG9yaXpvbnRhbDogYm94LmlzSG9yaXpvbnRhbCgpLFxuICAgICAgd2VpZ2h0OiBib3gud2VpZ2h0LFxuICAgICAgc3RhY2s6IHN0YWNrICYmIChwb3MgKyBzdGFjayksXG4gICAgICBzdGFja1dlaWdodFxuICAgIH0pO1xuICB9XG4gIHJldHVybiBsYXlvdXRCb3hlcztcbn1cblxuZnVuY3Rpb24gYnVpbGRTdGFja3MobGF5b3V0cykge1xuICBjb25zdCBzdGFja3MgPSB7fTtcbiAgZm9yIChjb25zdCB3cmFwIG9mIGxheW91dHMpIHtcbiAgICBjb25zdCB7c3RhY2ssIHBvcywgc3RhY2tXZWlnaHR9ID0gd3JhcDtcbiAgICBpZiAoIXN0YWNrIHx8ICFTVEFUSUNfUE9TSVRJT05TLmluY2x1ZGVzKHBvcykpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBfc3RhY2sgPSBzdGFja3Nbc3RhY2tdIHx8IChzdGFja3Nbc3RhY2tdID0ge2NvdW50OiAwLCBwbGFjZWQ6IDAsIHdlaWdodDogMCwgc2l6ZTogMH0pO1xuICAgIF9zdGFjay5jb3VudCsrO1xuICAgIF9zdGFjay53ZWlnaHQgKz0gc3RhY2tXZWlnaHQ7XG4gIH1cbiAgcmV0dXJuIHN0YWNrcztcbn1cblxuLyoqXG4gKiBzdG9yZSBkaW1lbnNpb25zIHVzZWQgaW5zdGVhZCBvZiBhdmFpbGFibGUgY2hhcnRBcmVhIGluIGZpdEJveGVzXG4gKiovXG5mdW5jdGlvbiBzZXRMYXlvdXREaW1zKGxheW91dHMsIHBhcmFtcykge1xuICBjb25zdCBzdGFja3MgPSBidWlsZFN0YWNrcyhsYXlvdXRzKTtcbiAgY29uc3Qge3ZCb3hNYXhXaWR0aCwgaEJveE1heEhlaWdodH0gPSBwYXJhbXM7XG4gIGxldCBpLCBpbGVuLCBsYXlvdXQ7XG4gIGZvciAoaSA9IDAsIGlsZW4gPSBsYXlvdXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIGxheW91dCA9IGxheW91dHNbaV07XG4gICAgY29uc3Qge2Z1bGxTaXplfSA9IGxheW91dC5ib3g7XG4gICAgY29uc3Qgc3RhY2sgPSBzdGFja3NbbGF5b3V0LnN0YWNrXTtcbiAgICBjb25zdCBmYWN0b3IgPSBzdGFjayAmJiBsYXlvdXQuc3RhY2tXZWlnaHQgLyBzdGFjay53ZWlnaHQ7XG4gICAgaWYgKGxheW91dC5ob3Jpem9udGFsKSB7XG4gICAgICBsYXlvdXQud2lkdGggPSBmYWN0b3IgPyBmYWN0b3IgKiB2Qm94TWF4V2lkdGggOiBmdWxsU2l6ZSAmJiBwYXJhbXMuYXZhaWxhYmxlV2lkdGg7XG4gICAgICBsYXlvdXQuaGVpZ2h0ID0gaEJveE1heEhlaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgbGF5b3V0LndpZHRoID0gdkJveE1heFdpZHRoO1xuICAgICAgbGF5b3V0LmhlaWdodCA9IGZhY3RvciA/IGZhY3RvciAqIGhCb3hNYXhIZWlnaHQgOiBmdWxsU2l6ZSAmJiBwYXJhbXMuYXZhaWxhYmxlSGVpZ2h0O1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3RhY2tzO1xufVxuXG5mdW5jdGlvbiBidWlsZExheW91dEJveGVzKGJveGVzKSB7XG4gIGNvbnN0IGxheW91dEJveGVzID0gd3JhcEJveGVzKGJveGVzKTtcbiAgY29uc3QgZnVsbFNpemUgPSBzb3J0QnlXZWlnaHQobGF5b3V0Qm94ZXMuZmlsdGVyKHdyYXAgPT4gd3JhcC5ib3guZnVsbFNpemUpLCB0cnVlKTtcbiAgY29uc3QgbGVmdCA9IHNvcnRCeVdlaWdodChmaWx0ZXJCeVBvc2l0aW9uKGxheW91dEJveGVzLCAnbGVmdCcpLCB0cnVlKTtcbiAgY29uc3QgcmlnaHQgPSBzb3J0QnlXZWlnaHQoZmlsdGVyQnlQb3NpdGlvbihsYXlvdXRCb3hlcywgJ3JpZ2h0JykpO1xuICBjb25zdCB0b3AgPSBzb3J0QnlXZWlnaHQoZmlsdGVyQnlQb3NpdGlvbihsYXlvdXRCb3hlcywgJ3RvcCcpLCB0cnVlKTtcbiAgY29uc3QgYm90dG9tID0gc29ydEJ5V2VpZ2h0KGZpbHRlckJ5UG9zaXRpb24obGF5b3V0Qm94ZXMsICdib3R0b20nKSk7XG4gIGNvbnN0IGNlbnRlckhvcml6b250YWwgPSBmaWx0ZXJEeW5hbWljUG9zaXRpb25CeUF4aXMobGF5b3V0Qm94ZXMsICd4Jyk7XG4gIGNvbnN0IGNlbnRlclZlcnRpY2FsID0gZmlsdGVyRHluYW1pY1Bvc2l0aW9uQnlBeGlzKGxheW91dEJveGVzLCAneScpO1xuXG4gIHJldHVybiB7XG4gICAgZnVsbFNpemUsXG4gICAgbGVmdEFuZFRvcDogbGVmdC5jb25jYXQodG9wKSxcbiAgICByaWdodEFuZEJvdHRvbTogcmlnaHQuY29uY2F0KGNlbnRlclZlcnRpY2FsKS5jb25jYXQoYm90dG9tKS5jb25jYXQoY2VudGVySG9yaXpvbnRhbCksXG4gICAgY2hhcnRBcmVhOiBmaWx0ZXJCeVBvc2l0aW9uKGxheW91dEJveGVzLCAnY2hhcnRBcmVhJyksXG4gICAgdmVydGljYWw6IGxlZnQuY29uY2F0KHJpZ2h0KS5jb25jYXQoY2VudGVyVmVydGljYWwpLFxuICAgIGhvcml6b250YWw6IHRvcC5jb25jYXQoYm90dG9tKS5jb25jYXQoY2VudGVySG9yaXpvbnRhbClcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0Q29tYmluZWRNYXgobWF4UGFkZGluZywgY2hhcnRBcmVhLCBhLCBiKSB7XG4gIHJldHVybiBNYXRoLm1heChtYXhQYWRkaW5nW2FdLCBjaGFydEFyZWFbYV0pICsgTWF0aC5tYXgobWF4UGFkZGluZ1tiXSwgY2hhcnRBcmVhW2JdKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTWF4UGFkZGluZyhtYXhQYWRkaW5nLCBib3hQYWRkaW5nKSB7XG4gIG1heFBhZGRpbmcudG9wID0gTWF0aC5tYXgobWF4UGFkZGluZy50b3AsIGJveFBhZGRpbmcudG9wKTtcbiAgbWF4UGFkZGluZy5sZWZ0ID0gTWF0aC5tYXgobWF4UGFkZGluZy5sZWZ0LCBib3hQYWRkaW5nLmxlZnQpO1xuICBtYXhQYWRkaW5nLmJvdHRvbSA9IE1hdGgubWF4KG1heFBhZGRpbmcuYm90dG9tLCBib3hQYWRkaW5nLmJvdHRvbSk7XG4gIG1heFBhZGRpbmcucmlnaHQgPSBNYXRoLm1heChtYXhQYWRkaW5nLnJpZ2h0LCBib3hQYWRkaW5nLnJpZ2h0KTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRGltcyhjaGFydEFyZWEsIHBhcmFtcywgbGF5b3V0LCBzdGFja3MpIHtcbiAgY29uc3Qge3BvcywgYm94fSA9IGxheW91dDtcbiAgY29uc3QgbWF4UGFkZGluZyA9IGNoYXJ0QXJlYS5tYXhQYWRkaW5nO1xuXG4gIC8vIGR5bmFtaWNhbGx5IHBsYWNlZCBib3hlcyBzaXplIGlzIG5vdCBjb25zaWRlcmVkXG4gIGlmICghaXNPYmplY3QocG9zKSkge1xuICAgIGlmIChsYXlvdXQuc2l6ZSkge1xuICAgICAgLy8gdGhpcyBsYXlvdXQgd2FzIGFscmVhZHkgY291bnRlZCBmb3IsIGxldHMgZmlyc3QgcmVkdWNlIG9sZCBzaXplXG4gICAgICBjaGFydEFyZWFbcG9zXSAtPSBsYXlvdXQuc2l6ZTtcbiAgICB9XG4gICAgY29uc3Qgc3RhY2sgPSBzdGFja3NbbGF5b3V0LnN0YWNrXSB8fCB7c2l6ZTogMCwgY291bnQ6IDF9O1xuICAgIHN0YWNrLnNpemUgPSBNYXRoLm1heChzdGFjay5zaXplLCBsYXlvdXQuaG9yaXpvbnRhbCA/IGJveC5oZWlnaHQgOiBib3gud2lkdGgpO1xuICAgIGxheW91dC5zaXplID0gc3RhY2suc2l6ZSAvIHN0YWNrLmNvdW50O1xuICAgIGNoYXJ0QXJlYVtwb3NdICs9IGxheW91dC5zaXplO1xuICB9XG5cbiAgaWYgKGJveC5nZXRQYWRkaW5nKSB7XG4gICAgdXBkYXRlTWF4UGFkZGluZyhtYXhQYWRkaW5nLCBib3guZ2V0UGFkZGluZygpKTtcbiAgfVxuXG4gIGNvbnN0IG5ld1dpZHRoID0gTWF0aC5tYXgoMCwgcGFyYW1zLm91dGVyV2lkdGggLSBnZXRDb21iaW5lZE1heChtYXhQYWRkaW5nLCBjaGFydEFyZWEsICdsZWZ0JywgJ3JpZ2h0JykpO1xuICBjb25zdCBuZXdIZWlnaHQgPSBNYXRoLm1heCgwLCBwYXJhbXMub3V0ZXJIZWlnaHQgLSBnZXRDb21iaW5lZE1heChtYXhQYWRkaW5nLCBjaGFydEFyZWEsICd0b3AnLCAnYm90dG9tJykpO1xuICBjb25zdCB3aWR0aENoYW5nZWQgPSBuZXdXaWR0aCAhPT0gY2hhcnRBcmVhLnc7XG4gIGNvbnN0IGhlaWdodENoYW5nZWQgPSBuZXdIZWlnaHQgIT09IGNoYXJ0QXJlYS5oO1xuICBjaGFydEFyZWEudyA9IG5ld1dpZHRoO1xuICBjaGFydEFyZWEuaCA9IG5ld0hlaWdodDtcblxuICAvLyByZXR1cm4gYm9vbGVhbnMgb24gdGhlIGNoYW5nZXMgcGVyIGRpcmVjdGlvblxuICByZXR1cm4gbGF5b3V0Lmhvcml6b250YWxcbiAgICA/IHtzYW1lOiB3aWR0aENoYW5nZWQsIG90aGVyOiBoZWlnaHRDaGFuZ2VkfVxuICAgIDoge3NhbWU6IGhlaWdodENoYW5nZWQsIG90aGVyOiB3aWR0aENoYW5nZWR9O1xufVxuXG5mdW5jdGlvbiBoYW5kbGVNYXhQYWRkaW5nKGNoYXJ0QXJlYSkge1xuICBjb25zdCBtYXhQYWRkaW5nID0gY2hhcnRBcmVhLm1heFBhZGRpbmc7XG5cbiAgZnVuY3Rpb24gdXBkYXRlUG9zKHBvcykge1xuICAgIGNvbnN0IGNoYW5nZSA9IE1hdGgubWF4KG1heFBhZGRpbmdbcG9zXSAtIGNoYXJ0QXJlYVtwb3NdLCAwKTtcbiAgICBjaGFydEFyZWFbcG9zXSArPSBjaGFuZ2U7XG4gICAgcmV0dXJuIGNoYW5nZTtcbiAgfVxuICBjaGFydEFyZWEueSArPSB1cGRhdGVQb3MoJ3RvcCcpO1xuICBjaGFydEFyZWEueCArPSB1cGRhdGVQb3MoJ2xlZnQnKTtcbiAgdXBkYXRlUG9zKCdyaWdodCcpO1xuICB1cGRhdGVQb3MoJ2JvdHRvbScpO1xufVxuXG5mdW5jdGlvbiBnZXRNYXJnaW5zKGhvcml6b250YWwsIGNoYXJ0QXJlYSkge1xuICBjb25zdCBtYXhQYWRkaW5nID0gY2hhcnRBcmVhLm1heFBhZGRpbmc7XG5cbiAgZnVuY3Rpb24gbWFyZ2luRm9yUG9zaXRpb25zKHBvc2l0aW9ucykge1xuICAgIGNvbnN0IG1hcmdpbiA9IHtsZWZ0OiAwLCB0b3A6IDAsIHJpZ2h0OiAwLCBib3R0b206IDB9O1xuICAgIHBvc2l0aW9ucy5mb3JFYWNoKChwb3MpID0+IHtcbiAgICAgIG1hcmdpbltwb3NdID0gTWF0aC5tYXgoY2hhcnRBcmVhW3Bvc10sIG1heFBhZGRpbmdbcG9zXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG1hcmdpbjtcbiAgfVxuXG4gIHJldHVybiBob3Jpem9udGFsXG4gICAgPyBtYXJnaW5Gb3JQb3NpdGlvbnMoWydsZWZ0JywgJ3JpZ2h0J10pXG4gICAgOiBtYXJnaW5Gb3JQb3NpdGlvbnMoWyd0b3AnLCAnYm90dG9tJ10pO1xufVxuXG5mdW5jdGlvbiBmaXRCb3hlcyhib3hlcywgY2hhcnRBcmVhLCBwYXJhbXMsIHN0YWNrcykge1xuICBjb25zdCByZWZpdEJveGVzID0gW107XG4gIGxldCBpLCBpbGVuLCBsYXlvdXQsIGJveCwgcmVmaXQsIGNoYW5nZWQ7XG5cbiAgZm9yIChpID0gMCwgaWxlbiA9IGJveGVzLmxlbmd0aCwgcmVmaXQgPSAwOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgbGF5b3V0ID0gYm94ZXNbaV07XG4gICAgYm94ID0gbGF5b3V0LmJveDtcblxuICAgIGJveC51cGRhdGUoXG4gICAgICBsYXlvdXQud2lkdGggfHwgY2hhcnRBcmVhLncsXG4gICAgICBsYXlvdXQuaGVpZ2h0IHx8IGNoYXJ0QXJlYS5oLFxuICAgICAgZ2V0TWFyZ2lucyhsYXlvdXQuaG9yaXpvbnRhbCwgY2hhcnRBcmVhKVxuICAgICk7XG4gICAgY29uc3Qge3NhbWUsIG90aGVyfSA9IHVwZGF0ZURpbXMoY2hhcnRBcmVhLCBwYXJhbXMsIGxheW91dCwgc3RhY2tzKTtcblxuICAgIC8vIERpbWVuc2lvbnMgY2hhbmdlZCBhbmQgdGhlcmUgd2VyZSBub24gZnVsbCB3aWR0aCBib3hlcyBiZWZvcmUgdGhpc1xuICAgIC8vIC0+IHdlIGhhdmUgdG8gcmVmaXQgdGhvc2VcbiAgICByZWZpdCB8PSBzYW1lICYmIHJlZml0Qm94ZXMubGVuZ3RoO1xuXG4gICAgLy8gQ2hhcnQgYXJlYSBjaGFuZ2VkIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb25cbiAgICBjaGFuZ2VkID0gY2hhbmdlZCB8fCBvdGhlcjtcblxuICAgIGlmICghYm94LmZ1bGxTaXplKSB7IC8vIGZ1bGxTaXplIGJveGVzIGRvbid0IG5lZWQgdG8gYmUgcmUtZml0dGVkIGluIGFueSBjYXNlXG4gICAgICByZWZpdEJveGVzLnB1c2gobGF5b3V0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVmaXQgJiYgZml0Qm94ZXMocmVmaXRCb3hlcywgY2hhcnRBcmVhLCBwYXJhbXMsIHN0YWNrcykgfHwgY2hhbmdlZDtcbn1cblxuZnVuY3Rpb24gc2V0Qm94RGltcyhib3gsIGxlZnQsIHRvcCwgd2lkdGgsIGhlaWdodCkge1xuICBib3gudG9wID0gdG9wO1xuICBib3gubGVmdCA9IGxlZnQ7XG4gIGJveC5yaWdodCA9IGxlZnQgKyB3aWR0aDtcbiAgYm94LmJvdHRvbSA9IHRvcCArIGhlaWdodDtcbiAgYm94LndpZHRoID0gd2lkdGg7XG4gIGJveC5oZWlnaHQgPSBoZWlnaHQ7XG59XG5cbmZ1bmN0aW9uIHBsYWNlQm94ZXMoYm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpIHtcbiAgY29uc3QgdXNlclBhZGRpbmcgPSBwYXJhbXMucGFkZGluZztcbiAgbGV0IHt4LCB5fSA9IGNoYXJ0QXJlYTtcblxuICBmb3IgKGNvbnN0IGxheW91dCBvZiBib3hlcykge1xuICAgIGNvbnN0IGJveCA9IGxheW91dC5ib3g7XG4gICAgY29uc3Qgc3RhY2sgPSBzdGFja3NbbGF5b3V0LnN0YWNrXSB8fCB7Y291bnQ6IDEsIHBsYWNlZDogMCwgd2VpZ2h0OiAxfTtcbiAgICBjb25zdCB3ZWlnaHQgPSAobGF5b3V0LnN0YWNrV2VpZ2h0IC8gc3RhY2sud2VpZ2h0KSB8fCAxO1xuICAgIGlmIChsYXlvdXQuaG9yaXpvbnRhbCkge1xuICAgICAgY29uc3Qgd2lkdGggPSBjaGFydEFyZWEudyAqIHdlaWdodDtcbiAgICAgIGNvbnN0IGhlaWdodCA9IHN0YWNrLnNpemUgfHwgYm94LmhlaWdodDtcbiAgICAgIGlmIChkZWZpbmVkKHN0YWNrLnN0YXJ0KSkge1xuICAgICAgICB5ID0gc3RhY2suc3RhcnQ7XG4gICAgICB9XG4gICAgICBpZiAoYm94LmZ1bGxTaXplKSB7XG4gICAgICAgIHNldEJveERpbXMoYm94LCB1c2VyUGFkZGluZy5sZWZ0LCB5LCBwYXJhbXMub3V0ZXJXaWR0aCAtIHVzZXJQYWRkaW5nLnJpZ2h0IC0gdXNlclBhZGRpbmcubGVmdCwgaGVpZ2h0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldEJveERpbXMoYm94LCBjaGFydEFyZWEubGVmdCArIHN0YWNrLnBsYWNlZCwgeSwgd2lkdGgsIGhlaWdodCk7XG4gICAgICB9XG4gICAgICBzdGFjay5zdGFydCA9IHk7XG4gICAgICBzdGFjay5wbGFjZWQgKz0gd2lkdGg7XG4gICAgICB5ID0gYm94LmJvdHRvbTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaGVpZ2h0ID0gY2hhcnRBcmVhLmggKiB3ZWlnaHQ7XG4gICAgICBjb25zdCB3aWR0aCA9IHN0YWNrLnNpemUgfHwgYm94LndpZHRoO1xuICAgICAgaWYgKGRlZmluZWQoc3RhY2suc3RhcnQpKSB7XG4gICAgICAgIHggPSBzdGFjay5zdGFydDtcbiAgICAgIH1cbiAgICAgIGlmIChib3guZnVsbFNpemUpIHtcbiAgICAgICAgc2V0Qm94RGltcyhib3gsIHgsIHVzZXJQYWRkaW5nLnRvcCwgd2lkdGgsIHBhcmFtcy5vdXRlckhlaWdodCAtIHVzZXJQYWRkaW5nLmJvdHRvbSAtIHVzZXJQYWRkaW5nLnRvcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRCb3hEaW1zKGJveCwgeCwgY2hhcnRBcmVhLnRvcCArIHN0YWNrLnBsYWNlZCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICB9XG4gICAgICBzdGFjay5zdGFydCA9IHg7XG4gICAgICBzdGFjay5wbGFjZWQgKz0gaGVpZ2h0O1xuICAgICAgeCA9IGJveC5yaWdodDtcbiAgICB9XG4gIH1cblxuICBjaGFydEFyZWEueCA9IHg7XG4gIGNoYXJ0QXJlYS55ID0geTtcbn1cblxuLyoqXG4gKiBAaW50ZXJmYWNlIExheW91dEl0ZW1cbiAqIEB0eXBlZGVmIHtvYmplY3R9IExheW91dEl0ZW1cbiAqIEBwcm9wIHtzdHJpbmd9IHBvc2l0aW9uIC0gVGhlIHBvc2l0aW9uIG9mIHRoZSBpdGVtIGluIHRoZSBjaGFydCBsYXlvdXQuIFBvc3NpYmxlIHZhbHVlcyBhcmVcbiAqICdsZWZ0JywgJ3RvcCcsICdyaWdodCcsICdib3R0b20nLCBhbmQgJ2NoYXJ0QXJlYSdcbiAqIEBwcm9wIHtudW1iZXJ9IHdlaWdodCAtIFRoZSB3ZWlnaHQgdXNlZCB0byBzb3J0IHRoZSBpdGVtLiBIaWdoZXIgd2VpZ2h0cyBhcmUgZnVydGhlciBhd2F5IGZyb20gdGhlIGNoYXJ0IGFyZWFcbiAqIEBwcm9wIHtib29sZWFufSBmdWxsU2l6ZSAtIGlmIHRydWUsIGFuZCB0aGUgaXRlbSBpcyBob3Jpem9udGFsLCB0aGVuIHB1c2ggdmVydGljYWwgYm94ZXMgZG93blxuICogQHByb3Age2Z1bmN0aW9ufSBpc0hvcml6b250YWwgLSByZXR1cm5zIHRydWUgaWYgdGhlIGxheW91dCBpdGVtIGlzIGhvcml6b250YWwgKGllLiB0b3Agb3IgYm90dG9tKVxuICogQHByb3Age2Z1bmN0aW9ufSB1cGRhdGUgLSBUYWtlcyB0d28gcGFyYW1ldGVyczogd2lkdGggYW5kIGhlaWdodC4gUmV0dXJucyBzaXplIG9mIGl0ZW1cbiAqIEBwcm9wIHtmdW5jdGlvbn0gZHJhdyAtIERyYXdzIHRoZSBlbGVtZW50XG4gKiBAcHJvcCB7ZnVuY3Rpb259IFtnZXRQYWRkaW5nXSAtICBSZXR1cm5zIGFuIG9iamVjdCB3aXRoIHBhZGRpbmcgb24gdGhlIGVkZ2VzXG4gKiBAcHJvcCB7bnVtYmVyfSB3aWR0aCAtIFdpZHRoIG9mIGl0ZW0uIE11c3QgYmUgdmFsaWQgYWZ0ZXIgdXBkYXRlKClcbiAqIEBwcm9wIHtudW1iZXJ9IGhlaWdodCAtIEhlaWdodCBvZiBpdGVtLiBNdXN0IGJlIHZhbGlkIGFmdGVyIHVwZGF0ZSgpXG4gKiBAcHJvcCB7bnVtYmVyfSBsZWZ0IC0gTGVmdCBlZGdlIG9mIHRoZSBpdGVtLiBTZXQgYnkgbGF5b3V0IHN5c3RlbSBhbmQgY2Fubm90IGJlIHVzZWQgaW4gdXBkYXRlXG4gKiBAcHJvcCB7bnVtYmVyfSB0b3AgLSBUb3AgZWRnZSBvZiB0aGUgaXRlbS4gU2V0IGJ5IGxheW91dCBzeXN0ZW0gYW5kIGNhbm5vdCBiZSB1c2VkIGluIHVwZGF0ZVxuICogQHByb3Age251bWJlcn0gcmlnaHQgLSBSaWdodCBlZGdlIG9mIHRoZSBpdGVtLiBTZXQgYnkgbGF5b3V0IHN5c3RlbSBhbmQgY2Fubm90IGJlIHVzZWQgaW4gdXBkYXRlXG4gKiBAcHJvcCB7bnVtYmVyfSBib3R0b20gLSBCb3R0b20gZWRnZSBvZiB0aGUgaXRlbS4gU2V0IGJ5IGxheW91dCBzeXN0ZW0gYW5kIGNhbm5vdCBiZSB1c2VkIGluIHVwZGF0ZVxuICovXG5cbi8vIFRoZSBsYXlvdXQgc2VydmljZSBpcyB2ZXJ5IHNlbGYgZXhwbGFuYXRvcnkuICBJdCdzIHJlc3BvbnNpYmxlIGZvciB0aGUgbGF5b3V0IHdpdGhpbiBhIGNoYXJ0LlxuLy8gU2NhbGVzLCBMZWdlbmRzIGFuZCBQbHVnaW5zIGFsbCByZWx5IG9uIHRoZSBsYXlvdXQgc2VydmljZSBhbmQgY2FuIGVhc2lseSByZWdpc3RlciB0byBiZSBwbGFjZWQgYW55d2hlcmUgdGhleSBuZWVkXG4vLyBJdCBpcyB0aGlzIHNlcnZpY2UncyByZXNwb25zaWJpbGl0eSBvZiBjYXJyeWluZyBvdXQgdGhhdCBsYXlvdXQuXG5leHBvcnQgZGVmYXVsdCB7XG5cbiAgLyoqXG5cdCAqIFJlZ2lzdGVyIGEgYm94IHRvIGEgY2hhcnQuXG5cdCAqIEEgYm94IGlzIHNpbXBseSBhIHJlZmVyZW5jZSB0byBhbiBvYmplY3QgdGhhdCByZXF1aXJlcyBsYXlvdXQuIGVnLiBTY2FsZXMsIExlZ2VuZCwgVGl0bGUuXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHRvIHVzZVxuXHQgKiBAcGFyYW0ge0xheW91dEl0ZW19IGl0ZW0gLSB0aGUgaXRlbSB0byBhZGQgdG8gYmUgbGFpZCBvdXRcblx0ICovXG4gIGFkZEJveChjaGFydCwgaXRlbSkge1xuICAgIGlmICghY2hhcnQuYm94ZXMpIHtcbiAgICAgIGNoYXJ0LmJveGVzID0gW107XG4gICAgfVxuXG4gICAgLy8gaW5pdGlhbGl6ZSBpdGVtIHdpdGggZGVmYXVsdCB2YWx1ZXNcbiAgICBpdGVtLmZ1bGxTaXplID0gaXRlbS5mdWxsU2l6ZSB8fCBmYWxzZTtcbiAgICBpdGVtLnBvc2l0aW9uID0gaXRlbS5wb3NpdGlvbiB8fCAndG9wJztcbiAgICBpdGVtLndlaWdodCA9IGl0ZW0ud2VpZ2h0IHx8IDA7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGl0ZW0uX2xheWVycyA9IGl0ZW0uX2xheWVycyB8fCBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBbe1xuICAgICAgICB6OiAwLFxuICAgICAgICBkcmF3KGNoYXJ0QXJlYSkge1xuICAgICAgICAgIGl0ZW0uZHJhdyhjaGFydEFyZWEpO1xuICAgICAgICB9XG4gICAgICB9XTtcbiAgICB9O1xuXG4gICAgY2hhcnQuYm94ZXMucHVzaChpdGVtKTtcbiAgfSxcblxuICAvKipcblx0ICogUmVtb3ZlIGEgbGF5b3V0SXRlbSBmcm9tIGEgY2hhcnRcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgdG8gcmVtb3ZlIHRoZSBib3ggZnJvbVxuXHQgKiBAcGFyYW0ge0xheW91dEl0ZW19IGxheW91dEl0ZW0gLSB0aGUgaXRlbSB0byByZW1vdmUgZnJvbSB0aGUgbGF5b3V0XG5cdCAqL1xuICByZW1vdmVCb3goY2hhcnQsIGxheW91dEl0ZW0pIHtcbiAgICBjb25zdCBpbmRleCA9IGNoYXJ0LmJveGVzID8gY2hhcnQuYm94ZXMuaW5kZXhPZihsYXlvdXRJdGVtKSA6IC0xO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIGNoYXJ0LmJveGVzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuXHQgKiBTZXRzIChvciB1cGRhdGVzKSBvcHRpb25zIG9uIHRoZSBnaXZlbiBgaXRlbWAuXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IGluIHdoaWNoIHRoZSBpdGVtIGxpdmVzIChvciB3aWxsIGJlIGFkZGVkIHRvKVxuXHQgKiBAcGFyYW0ge0xheW91dEl0ZW19IGl0ZW0gLSB0aGUgaXRlbSB0byBjb25maWd1cmUgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9uc1xuXHQgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9ucyAtIHRoZSBuZXcgaXRlbSBvcHRpb25zLlxuXHQgKi9cbiAgY29uZmlndXJlKGNoYXJ0LCBpdGVtLCBvcHRpb25zKSB7XG4gICAgaXRlbS5mdWxsU2l6ZSA9IG9wdGlvbnMuZnVsbFNpemU7XG4gICAgaXRlbS5wb3NpdGlvbiA9IG9wdGlvbnMucG9zaXRpb247XG4gICAgaXRlbS53ZWlnaHQgPSBvcHRpb25zLndlaWdodDtcbiAgfSxcblxuICAvKipcblx0ICogRml0cyBib3hlcyBvZiB0aGUgZ2l2ZW4gY2hhcnQgaW50byB0aGUgZ2l2ZW4gc2l6ZSBieSBoYXZpbmcgZWFjaCBib3ggbWVhc3VyZSBpdHNlbGZcblx0ICogdGhlbiBydW5uaW5nIGEgZml0dGluZyBhbGdvcml0aG1cblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnRcblx0ICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIC0gdGhlIHdpZHRoIHRvIGZpdCBpbnRvXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQgLSB0aGUgaGVpZ2h0IHRvIGZpdCBpbnRvXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtaW5QYWRkaW5nIC0gbWluaW11bSBwYWRkaW5nIHJlcXVpcmVkIGZvciBlYWNoIHNpZGUgb2YgY2hhcnQgYXJlYVxuXHQgKi9cbiAgdXBkYXRlKGNoYXJ0LCB3aWR0aCwgaGVpZ2h0LCBtaW5QYWRkaW5nKSB7XG4gICAgaWYgKCFjaGFydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcoY2hhcnQub3B0aW9ucy5sYXlvdXQucGFkZGluZyk7XG4gICAgY29uc3QgYXZhaWxhYmxlV2lkdGggPSBNYXRoLm1heCh3aWR0aCAtIHBhZGRpbmcud2lkdGgsIDApO1xuICAgIGNvbnN0IGF2YWlsYWJsZUhlaWdodCA9IE1hdGgubWF4KGhlaWdodCAtIHBhZGRpbmcuaGVpZ2h0LCAwKTtcbiAgICBjb25zdCBib3hlcyA9IGJ1aWxkTGF5b3V0Qm94ZXMoY2hhcnQuYm94ZXMpO1xuICAgIGNvbnN0IHZlcnRpY2FsQm94ZXMgPSBib3hlcy52ZXJ0aWNhbDtcbiAgICBjb25zdCBob3Jpem9udGFsQm94ZXMgPSBib3hlcy5ob3Jpem9udGFsO1xuXG4gICAgLy8gQmVmb3JlIGFueSBjaGFuZ2VzIGFyZSBtYWRlLCBub3RpZnkgYm94ZXMgdGhhdCBhbiB1cGRhdGUgaXMgYWJvdXQgdG8gYmVpbmdcbiAgICAvLyBUaGlzIGlzIHVzZWQgdG8gY2xlYXIgYW55IGNhY2hlZCBkYXRhIChlLmcuIHNjYWxlIGxpbWl0cylcbiAgICBlYWNoKGNoYXJ0LmJveGVzLCBib3ggPT4ge1xuICAgICAgaWYgKHR5cGVvZiBib3guYmVmb3JlTGF5b3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGJveC5iZWZvcmVMYXlvdXQoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEVzc2VudGlhbGx5IHdlIG5vdyBoYXZlIGFueSBudW1iZXIgb2YgYm94ZXMgb24gZWFjaCBvZiB0aGUgNCBzaWRlcy5cbiAgICAvLyBPdXIgY2FudmFzIGxvb2tzIGxpa2UgdGhlIGZvbGxvd2luZy5cbiAgICAvLyBUaGUgYXJlYXMgTDEgYW5kIEwyIGFyZSB0aGUgbGVmdCBheGVzLiBSMSBpcyB0aGUgcmlnaHQgYXhpcywgVDEgaXMgdGhlIHRvcCBheGlzIGFuZFxuICAgIC8vIEIxIGlzIHRoZSBib3R0b20gYXhpc1xuICAgIC8vIFRoZXJlIGFyZSBhbHNvIDQgcXVhZHJhbnQtbGlrZSBsb2NhdGlvbnMgKGxlZnQgdG8gcmlnaHQgaW5zdGVhZCBvZiBjbG9ja3dpc2UpIHJlc2VydmVkIGZvciBjaGFydCBvdmVybGF5c1xuICAgIC8vIFRoZXNlIGxvY2F0aW9ucyBhcmUgc2luZ2xlLWJveCBsb2NhdGlvbnMgb25seSwgd2hlbiB0cnlpbmcgdG8gcmVnaXN0ZXIgYSBjaGFydEFyZWEgbG9jYXRpb24gdGhhdCBpcyBhbHJlYWR5IHRha2VuLFxuICAgIC8vIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duLlxuICAgIC8vXG4gICAgLy8gfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18XG4gICAgLy8gfCAgICAgICAgICAgICAgICAgIFQxIChGdWxsIFdpZHRoKSAgICAgICAgICAgICAgICAgICB8XG4gICAgLy8gfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18XG4gICAgLy8gfCAgICB8ICAgIHwgICAgICAgICAgICAgICAgIFQyICAgICAgICAgICAgICAgICAgfCAgICB8XG4gICAgLy8gfCAgICB8LS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS18XG4gICAgLy8gfCAgICB8ICAgIHwgQzEgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQzIgfCAgICB8XG4gICAgLy8gfCAgICB8ICAgIHwtLS0tfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLS0tfCAgICB8XG4gICAgLy8gfCAgICB8ICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICB8XG4gICAgLy8gfCBMMSB8IEwyIHwgICAgICAgICAgIENoYXJ0QXJlYSAoQzApICAgICAgICAgICAgfCBSMSB8XG4gICAgLy8gfCAgICB8ICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICB8XG4gICAgLy8gfCAgICB8ICAgIHwtLS0tfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLS0tfCAgICB8XG4gICAgLy8gfCAgICB8ICAgIHwgQzMgfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQzQgfCAgICB8XG4gICAgLy8gfCAgICB8LS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS18XG4gICAgLy8gfCAgICB8ICAgIHwgICAgICAgICAgICAgICAgIEIxICAgICAgICAgICAgICAgICAgfCAgICB8XG4gICAgLy8gfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18XG4gICAgLy8gfCAgICAgICAgICAgICAgICAgIEIyIChGdWxsIFdpZHRoKSAgICAgICAgICAgICAgICAgICB8XG4gICAgLy8gfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18XG4gICAgLy9cblxuICAgIGNvbnN0IHZpc2libGVWZXJ0aWNhbEJveENvdW50ID0gdmVydGljYWxCb3hlcy5yZWR1Y2UoKHRvdGFsLCB3cmFwKSA9PlxuICAgICAgd3JhcC5ib3gub3B0aW9ucyAmJiB3cmFwLmJveC5vcHRpb25zLmRpc3BsYXkgPT09IGZhbHNlID8gdG90YWwgOiB0b3RhbCArIDEsIDApIHx8IDE7XG5cbiAgICBjb25zdCBwYXJhbXMgPSBPYmplY3QuZnJlZXplKHtcbiAgICAgIG91dGVyV2lkdGg6IHdpZHRoLFxuICAgICAgb3V0ZXJIZWlnaHQ6IGhlaWdodCxcbiAgICAgIHBhZGRpbmcsXG4gICAgICBhdmFpbGFibGVXaWR0aCxcbiAgICAgIGF2YWlsYWJsZUhlaWdodCxcbiAgICAgIHZCb3hNYXhXaWR0aDogYXZhaWxhYmxlV2lkdGggLyAyIC8gdmlzaWJsZVZlcnRpY2FsQm94Q291bnQsXG4gICAgICBoQm94TWF4SGVpZ2h0OiBhdmFpbGFibGVIZWlnaHQgLyAyXG4gICAgfSk7XG4gICAgY29uc3QgbWF4UGFkZGluZyA9IE9iamVjdC5hc3NpZ24oe30sIHBhZGRpbmcpO1xuICAgIHVwZGF0ZU1heFBhZGRpbmcobWF4UGFkZGluZywgdG9QYWRkaW5nKG1pblBhZGRpbmcpKTtcbiAgICBjb25zdCBjaGFydEFyZWEgPSBPYmplY3QuYXNzaWduKHtcbiAgICAgIG1heFBhZGRpbmcsXG4gICAgICB3OiBhdmFpbGFibGVXaWR0aCxcbiAgICAgIGg6IGF2YWlsYWJsZUhlaWdodCxcbiAgICAgIHg6IHBhZGRpbmcubGVmdCxcbiAgICAgIHk6IHBhZGRpbmcudG9wXG4gICAgfSwgcGFkZGluZyk7XG5cbiAgICBjb25zdCBzdGFja3MgPSBzZXRMYXlvdXREaW1zKHZlcnRpY2FsQm94ZXMuY29uY2F0KGhvcml6b250YWxCb3hlcyksIHBhcmFtcyk7XG5cbiAgICAvLyBGaXJzdCBmaXQgdGhlIGZ1bGxTaXplIGJveGVzLCB0byByZWR1Y2UgcHJvYmFiaWxpdHkgb2YgcmUtZml0dGluZy5cbiAgICBmaXRCb3hlcyhib3hlcy5mdWxsU2l6ZSwgY2hhcnRBcmVhLCBwYXJhbXMsIHN0YWNrcyk7XG5cbiAgICAvLyBUaGVuIGZpdCB2ZXJ0aWNhbCBib3hlc1xuICAgIGZpdEJveGVzKHZlcnRpY2FsQm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpO1xuXG4gICAgLy8gVGhlbiBmaXQgaG9yaXpvbnRhbCBib3hlc1xuICAgIGlmIChmaXRCb3hlcyhob3Jpem9udGFsQm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpKSB7XG4gICAgICAvLyBpZiB0aGUgYXJlYSBjaGFuZ2VkLCByZS1maXQgdmVydGljYWwgYm94ZXNcbiAgICAgIGZpdEJveGVzKHZlcnRpY2FsQm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpO1xuICAgIH1cblxuICAgIGhhbmRsZU1heFBhZGRpbmcoY2hhcnRBcmVhKTtcblxuICAgIC8vIEZpbmFsbHkgcGxhY2UgdGhlIGJveGVzIHRvIGNvcnJlY3QgY29vcmRpbmF0ZXNcbiAgICBwbGFjZUJveGVzKGJveGVzLmxlZnRBbmRUb3AsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpO1xuXG4gICAgLy8gTW92ZSB0byBvcHBvc2l0ZSBzaWRlIG9mIGNoYXJ0XG4gICAgY2hhcnRBcmVhLnggKz0gY2hhcnRBcmVhLnc7XG4gICAgY2hhcnRBcmVhLnkgKz0gY2hhcnRBcmVhLmg7XG5cbiAgICBwbGFjZUJveGVzKGJveGVzLnJpZ2h0QW5kQm90dG9tLCBjaGFydEFyZWEsIHBhcmFtcywgc3RhY2tzKTtcblxuICAgIGNoYXJ0LmNoYXJ0QXJlYSA9IHtcbiAgICAgIGxlZnQ6IGNoYXJ0QXJlYS5sZWZ0LFxuICAgICAgdG9wOiBjaGFydEFyZWEudG9wLFxuICAgICAgcmlnaHQ6IGNoYXJ0QXJlYS5sZWZ0ICsgY2hhcnRBcmVhLncsXG4gICAgICBib3R0b206IGNoYXJ0QXJlYS50b3AgKyBjaGFydEFyZWEuaCxcbiAgICAgIGhlaWdodDogY2hhcnRBcmVhLmgsXG4gICAgICB3aWR0aDogY2hhcnRBcmVhLncsXG4gICAgfTtcblxuICAgIC8vIEZpbmFsbHkgdXBkYXRlIGJveGVzIGluIGNoYXJ0QXJlYSAocmFkaWFsIHNjYWxlIGZvciBleGFtcGxlKVxuICAgIGVhY2goYm94ZXMuY2hhcnRBcmVhLCAobGF5b3V0KSA9PiB7XG4gICAgICBjb25zdCBib3ggPSBsYXlvdXQuYm94O1xuICAgICAgT2JqZWN0LmFzc2lnbihib3gsIGNoYXJ0LmNoYXJ0QXJlYSk7XG4gICAgICBib3gudXBkYXRlKGNoYXJ0QXJlYS53LCBjaGFydEFyZWEuaCwge2xlZnQ6IDAsIHRvcDogMCwgcmlnaHQ6IDAsIGJvdHRvbTogMH0pO1xuICAgIH0pO1xuICB9XG59O1xuIiwgIlxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vY29yZS9jb3JlLmNvbnRyb2xsZXIuanMnKS5kZWZhdWx0IH0gQ2hhcnRcbiAqL1xuXG4vKipcbiAqIEFic3RyYWN0IGNsYXNzIHRoYXQgYWxsb3dzIGFic3RyYWN0aW5nIHBsYXRmb3JtIGRlcGVuZGVuY2llcyBhd2F5IGZyb20gdGhlIGNoYXJ0LlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYXNlUGxhdGZvcm0ge1xuICAvKipcblx0ICogQ2FsbGVkIGF0IGNoYXJ0IGNvbnN0cnVjdGlvbiB0aW1lLCByZXR1cm5zIGEgY29udGV4dDJkIGluc3RhbmNlIGltcGxlbWVudGluZ1xuXHQgKiB0aGUgW1czQyBDYW52YXMgMkQgQ29udGV4dCBBUEkgc3RhbmRhcmRde0BsaW5rIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yZGNvbnRleHQvfS5cblx0ICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzIC0gVGhlIGNhbnZhcyBmcm9tIHdoaWNoIHRvIGFjcXVpcmUgY29udGV4dCAocGxhdGZvcm0gc3BlY2lmaWMpXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbYXNwZWN0UmF0aW9dIC0gVGhlIGNoYXJ0IG9wdGlvbnNcblx0ICovXG4gIGFjcXVpcmVDb250ZXh0KGNhbnZhcywgYXNwZWN0UmF0aW8pIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcblxuICAvKipcblx0ICogQ2FsbGVkIGF0IGNoYXJ0IGRlc3RydWN0aW9uIHRpbWUsIHJlbGVhc2VzIGFueSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgY29udGV4dFxuXHQgKiBwcmV2aW91c2x5IHJldHVybmVkIGJ5IHRoZSBhY3F1aXJlQ29udGV4dCgpIG1ldGhvZC5cblx0ICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgLSBUaGUgY29udGV4dDJkIGluc3RhbmNlXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSBtZXRob2Qgc3VjY2VlZGVkLCBlbHNlIGZhbHNlXG5cdCAqL1xuICByZWxlYXNlQ29udGV4dChjb250ZXh0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcblx0ICogUmVnaXN0ZXJzIHRoZSBzcGVjaWZpZWQgbGlzdGVuZXIgb24gdGhlIGdpdmVuIGNoYXJ0LlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIENoYXJ0IGZyb20gd2hpY2ggdG8gbGlzdGVuIGZvciBldmVudFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSAoe0BsaW5rIENoYXJ0RXZlbnR9KSB0eXBlIHRvIGxpc3RlbiBmb3Jcblx0ICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgLSBSZWNlaXZlcyBhIG5vdGlmaWNhdGlvbiAoYW4gb2JqZWN0IHRoYXQgaW1wbGVtZW50c1xuXHQgKiB0aGUge0BsaW5rIENoYXJ0RXZlbnR9IGludGVyZmFjZSkgd2hlbiBhbiBldmVudCBvZiB0aGUgc3BlY2lmaWVkIHR5cGUgb2NjdXJzLlxuXHQgKi9cbiAgYWRkRXZlbnRMaXN0ZW5lcihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcblxuICAvKipcblx0ICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIGFkZEV2ZW50TGlzdGVuZXIuXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gQ2hhcnQgZnJvbSB3aGljaCB0byByZW1vdmUgdGhlIGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlICh7QGxpbmsgQ2hhcnRFdmVudH0pIHR5cGUgdG8gcmVtb3ZlXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIC0gVGhlIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHJlbW92ZSBmcm9tIHRoZSBldmVudCB0YXJnZXQuXG5cdCAqL1xuICByZW1vdmVFdmVudExpc3RlbmVyKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuXG4gIC8qKlxuXHQgKiBAcmV0dXJucyB7bnVtYmVyfSB0aGUgY3VycmVudCBkZXZpY2VQaXhlbFJhdGlvIG9mIHRoZSBkZXZpY2UgdGhpcyBwbGF0Zm9ybSBpcyBjb25uZWN0ZWQgdG8uXG5cdCAqL1xuICBnZXREZXZpY2VQaXhlbFJhdGlvKCkge1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJldHVybnMgdGhlIG1heGltdW0gc2l6ZSBpbiBwaXhlbHMgb2YgZ2l2ZW4gY2FudmFzIGVsZW1lbnQuXG5cdCAqIEBwYXJhbSB7SFRNTENhbnZhc0VsZW1lbnR9IGVsZW1lbnRcblx0ICogQHBhcmFtIHtudW1iZXJ9IFt3aWR0aF0gLSBjb250ZW50IHdpZHRoIG9mIHBhcmVudCBlbGVtZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbaGVpZ2h0XSAtIGNvbnRlbnQgaGVpZ2h0IG9mIHBhcmVudCBlbGVtZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbYXNwZWN0UmF0aW9dIC0gYXNwZWN0IHJhdGlvIHRvIG1haW50YWluXG5cdCAqL1xuICBnZXRNYXhpbXVtU2l6ZShlbGVtZW50LCB3aWR0aCwgaGVpZ2h0LCBhc3BlY3RSYXRpbykge1xuICAgIHdpZHRoID0gTWF0aC5tYXgoMCwgd2lkdGggfHwgZWxlbWVudC53aWR0aCk7XG4gICAgaGVpZ2h0ID0gaGVpZ2h0IHx8IGVsZW1lbnQuaGVpZ2h0O1xuICAgIHJldHVybiB7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodDogTWF0aC5tYXgoMCwgYXNwZWN0UmF0aW8gPyBNYXRoLmZsb29yKHdpZHRoIC8gYXNwZWN0UmF0aW8pIDogaGVpZ2h0KVxuICAgIH07XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSBjYW52YXMgaXMgYXR0YWNoZWQgdG8gdGhlIHBsYXRmb3JtLCBmYWxzZSBpZiBub3QuXG5cdCAqL1xuICBpc0F0dGFjaGVkKGNhbnZhcykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyBjb25maWcgd2l0aCBwbGF0Zm9ybSBzcGVjaWZpYyByZXF1aXJlbWVudHNcbiAgICogQHBhcmFtIHtpbXBvcnQoJy4uL2NvcmUvY29yZS5jb25maWcuanMnKS5kZWZhdWx0fSBjb25maWdcbiAgICovXG4gIHVwZGF0ZUNvbmZpZyhjb25maWcpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIC8vIG5vLW9wXG4gIH1cbn1cbiIsICIvKipcbiAqIFBsYXRmb3JtIGZhbGxiYWNrIGltcGxlbWVudGF0aW9uIChtaW5pbWFsKS5cbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvcHVsbC80NTkxI2lzc3VlY29tbWVudC0zMTk1NzU5MzlcbiAqL1xuXG5pbXBvcnQgQmFzZVBsYXRmb3JtIGZyb20gJy4vcGxhdGZvcm0uYmFzZS5qcyc7XG5cbi8qKlxuICogUGxhdGZvcm0gY2xhc3MgZm9yIGNoYXJ0cyB3aXRob3V0IGFjY2VzcyB0byB0aGUgRE9NIG9yIHRvIG1hbnkgZWxlbWVudCBwcm9wZXJ0aWVzXG4gKiBUaGlzIHBsYXRmb3JtIGlzIHVzZWQgYnkgZGVmYXVsdCBmb3IgYW55IGNoYXJ0IHBhc3NlZCBhbiBPZmZzY3JlZW5DYW52YXMuXG4gKiBAZXh0ZW5kcyBCYXNlUGxhdGZvcm1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmFzaWNQbGF0Zm9ybSBleHRlbmRzIEJhc2VQbGF0Zm9ybSB7XG4gIGFjcXVpcmVDb250ZXh0KGl0ZW0pIHtcbiAgICAvLyBUbyBwcmV2ZW50IGNhbnZhcyBmaW5nZXJwcmludGluZywgc29tZSBhZGQtb25zIHVuZGVmaW5lIHRoZSBnZXRDb250ZXh0XG4gICAgLy8gbWV0aG9kLCBmb3IgZXhhbXBsZTogaHR0cHM6Ly9naXRodWIuY29tL2trYXBzbmVyL0NhbnZhc0Jsb2NrZXJcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMjgwN1xuICAgIHJldHVybiBpdGVtICYmIGl0ZW0uZ2V0Q29udGV4dCAmJiBpdGVtLmdldENvbnRleHQoJzJkJykgfHwgbnVsbDtcbiAgfVxuICB1cGRhdGVDb25maWcoY29uZmlnKSB7XG4gICAgY29uZmlnLm9wdGlvbnMuYW5pbWF0aW9uID0gZmFsc2U7XG4gIH1cbn1cbiIsICIvKipcbiAqIENoYXJ0LlBsYXRmb3JtIGltcGxlbWVudGF0aW9uIGZvciB0YXJnZXRpbmcgYSB3ZWIgYnJvd3NlclxuICovXG5cbmltcG9ydCBCYXNlUGxhdGZvcm0gZnJvbSAnLi9wbGF0Zm9ybS5iYXNlLmpzJztcbmltcG9ydCB7X2dldFBhcmVudE5vZGUsIGdldFJlbGF0aXZlUG9zaXRpb24sIHN1cHBvcnRzRXZlbnRMaXN0ZW5lck9wdGlvbnMsIHJlYWRVc2VkU2l6ZSwgZ2V0TWF4aW11bVNpemV9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5kb20uanMnO1xuaW1wb3J0IHt0aHJvdHRsZWR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5leHRyYXMuanMnO1xuaW1wb3J0IHtpc051bGxPclVuZGVmfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL2NvcmUvY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IENoYXJ0XG4gKi9cblxuY29uc3QgRVhQQU5ET19LRVkgPSAnJGNoYXJ0anMnO1xuXG4vKipcbiAqIERPTSBldmVudCB0eXBlcyAtPiBDaGFydC5qcyBldmVudCB0eXBlcy5cbiAqIE5vdGU6IG9ubHkgZXZlbnRzIHdpdGggZGlmZmVyZW50IHR5cGVzIGFyZSBtYXBwZWQuXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0V2ZW50c1xuICovXG5jb25zdCBFVkVOVF9UWVBFUyA9IHtcbiAgdG91Y2hzdGFydDogJ21vdXNlZG93bicsXG4gIHRvdWNobW92ZTogJ21vdXNlbW92ZScsXG4gIHRvdWNoZW5kOiAnbW91c2V1cCcsXG4gIHBvaW50ZXJlbnRlcjogJ21vdXNlZW50ZXInLFxuICBwb2ludGVyZG93bjogJ21vdXNlZG93bicsXG4gIHBvaW50ZXJtb3ZlOiAnbW91c2Vtb3ZlJyxcbiAgcG9pbnRlcnVwOiAnbW91c2V1cCcsXG4gIHBvaW50ZXJsZWF2ZTogJ21vdXNlb3V0JyxcbiAgcG9pbnRlcm91dDogJ21vdXNlb3V0J1xufTtcblxuY29uc3QgaXNOdWxsT3JFbXB0eSA9IHZhbHVlID0+IHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSAnJztcbi8qKlxuICogSW5pdGlhbGl6ZXMgdGhlIGNhbnZhcyBzdHlsZSBhbmQgcmVuZGVyIHNpemUgd2l0aG91dCBtb2RpZnlpbmcgdGhlIGNhbnZhcyBkaXNwbGF5IHNpemUsXG4gKiBzaW5jZSByZXNwb25zaXZlbmVzcyBpcyBoYW5kbGVkIGJ5IHRoZSBjb250cm9sbGVyLnJlc2l6ZSgpIG1ldGhvZC4gVGhlIGNvbmZpZyBpcyB1c2VkXG4gKiB0byBkZXRlcm1pbmUgdGhlIGFzcGVjdCByYXRpbyB0byBhcHBseSBpbiBjYXNlIG5vIGV4cGxpY2l0IGhlaWdodCBoYXMgYmVlbiBzcGVjaWZpZWQuXG4gKiBAcGFyYW0ge0hUTUxDYW52YXNFbGVtZW50fSBjYW52YXNcbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXNwZWN0UmF0aW9dXG4gKi9cbmZ1bmN0aW9uIGluaXRDYW52YXMoY2FudmFzLCBhc3BlY3RSYXRpbykge1xuICBjb25zdCBzdHlsZSA9IGNhbnZhcy5zdHlsZTtcblxuICAvLyBOT1RFKFNCKSBjYW52YXMuZ2V0QXR0cmlidXRlKCd3aWR0aCcpICE9PSBjYW52YXMud2lkdGg6IGluIHRoZSBmaXJzdCBjYXNlIGl0XG4gIC8vIHJldHVybnMgbnVsbCBvciAnJyBpZiBubyBleHBsaWNpdCB2YWx1ZSBoYXMgYmVlbiBzZXQgdG8gdGhlIGNhbnZhcyBhdHRyaWJ1dGUuXG4gIGNvbnN0IHJlbmRlckhlaWdodCA9IGNhbnZhcy5nZXRBdHRyaWJ1dGUoJ2hlaWdodCcpO1xuICBjb25zdCByZW5kZXJXaWR0aCA9IGNhbnZhcy5nZXRBdHRyaWJ1dGUoJ3dpZHRoJyk7XG5cbiAgLy8gQ2hhcnQuanMgbW9kaWZpZXMgc29tZSBjYW52YXMgdmFsdWVzIHRoYXQgd2Ugd2FudCB0byByZXN0b3JlIG9uIGRlc3Ryb3lcbiAgY2FudmFzW0VYUEFORE9fS0VZXSA9IHtcbiAgICBpbml0aWFsOiB7XG4gICAgICBoZWlnaHQ6IHJlbmRlckhlaWdodCxcbiAgICAgIHdpZHRoOiByZW5kZXJXaWR0aCxcbiAgICAgIHN0eWxlOiB7XG4gICAgICAgIGRpc3BsYXk6IHN0eWxlLmRpc3BsYXksXG4gICAgICAgIGhlaWdodDogc3R5bGUuaGVpZ2h0LFxuICAgICAgICB3aWR0aDogc3R5bGUud2lkdGhcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLy8gRm9yY2UgY2FudmFzIHRvIGRpc3BsYXkgYXMgYmxvY2sgdG8gYXZvaWQgZXh0cmEgc3BhY2UgY2F1c2VkIGJ5IGlubGluZVxuICAvLyBlbGVtZW50cywgd2hpY2ggd291bGQgaW50ZXJmZXJlIHdpdGggdGhlIHJlc3BvbnNpdmUgcmVzaXplIHByb2Nlc3MuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8yNTM4XG4gIHN0eWxlLmRpc3BsYXkgPSBzdHlsZS5kaXNwbGF5IHx8ICdibG9jayc7XG4gIC8vIEluY2x1ZGUgcG9zc2libGUgYm9yZGVycyBpbiB0aGUgc2l6ZVxuICBzdHlsZS5ib3hTaXppbmcgPSBzdHlsZS5ib3hTaXppbmcgfHwgJ2JvcmRlci1ib3gnO1xuXG4gIGlmIChpc051bGxPckVtcHR5KHJlbmRlcldpZHRoKSkge1xuICAgIGNvbnN0IGRpc3BsYXlXaWR0aCA9IHJlYWRVc2VkU2l6ZShjYW52YXMsICd3aWR0aCcpO1xuICAgIGlmIChkaXNwbGF5V2lkdGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2FudmFzLndpZHRoID0gZGlzcGxheVdpZHRoO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc051bGxPckVtcHR5KHJlbmRlckhlaWdodCkpIHtcbiAgICBpZiAoY2FudmFzLnN0eWxlLmhlaWdodCA9PT0gJycpIHtcbiAgICAgIC8vIElmIG5vIGV4cGxpY2l0IHJlbmRlciBoZWlnaHQgYW5kIHN0eWxlIGhlaWdodCwgbGV0J3MgYXBwbHkgdGhlIGFzcGVjdCByYXRpbyxcbiAgICAgIC8vIHdoaWNoIG9uZSBjYW4gYmUgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyIGJ1dCBhbHNvIGJ5IGNoYXJ0cyBhcyBkZWZhdWx0IG9wdGlvblxuICAgICAgLy8gKGkuZS4gb3B0aW9ucy5hc3BlY3RSYXRpbykuIElmIG5vdCBzcGVjaWZpZWQsIHVzZSBjYW52YXMgYXNwZWN0IHJhdGlvIG9mIDIuXG4gICAgICBjYW52YXMuaGVpZ2h0ID0gY2FudmFzLndpZHRoIC8gKGFzcGVjdFJhdGlvIHx8IDIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBkaXNwbGF5SGVpZ2h0ID0gcmVhZFVzZWRTaXplKGNhbnZhcywgJ2hlaWdodCcpO1xuICAgICAgaWYgKGRpc3BsYXlIZWlnaHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gZGlzcGxheUhlaWdodDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gY2FudmFzO1xufVxuXG4vLyBEZWZhdWx0IHBhc3NpdmUgdG8gdHJ1ZSBhcyBleHBlY3RlZCBieSBDaHJvbWUgZm9yICd0b3VjaHN0YXJ0JyBhbmQgJ3RvdWNoZW5kJyBldmVudHMuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNDI4N1xuY29uc3QgZXZlbnRMaXN0ZW5lck9wdGlvbnMgPSBzdXBwb3J0c0V2ZW50TGlzdGVuZXJPcHRpb25zID8ge3Bhc3NpdmU6IHRydWV9IDogZmFsc2U7XG5cbmZ1bmN0aW9uIGFkZExpc3RlbmVyKG5vZGUsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmIChub2RlKSB7XG4gICAgbm9kZS5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBldmVudExpc3RlbmVyT3B0aW9ucyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIoY2hhcnQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmIChjaGFydCAmJiBjaGFydC5jYW52YXMpIHtcbiAgICBjaGFydC5jYW52YXMucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgZXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZyb21OYXRpdmVFdmVudChldmVudCwgY2hhcnQpIHtcbiAgY29uc3QgdHlwZSA9IEVWRU5UX1RZUEVTW2V2ZW50LnR5cGVdIHx8IGV2ZW50LnR5cGU7XG4gIGNvbnN0IHt4LCB5fSA9IGdldFJlbGF0aXZlUG9zaXRpb24oZXZlbnQsIGNoYXJ0KTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlLFxuICAgIGNoYXJ0LFxuICAgIG5hdGl2ZTogZXZlbnQsXG4gICAgeDogeCAhPT0gdW5kZWZpbmVkID8geCA6IG51bGwsXG4gICAgeTogeSAhPT0gdW5kZWZpbmVkID8geSA6IG51bGwsXG4gIH07XG59XG5cbmZ1bmN0aW9uIG5vZGVMaXN0Q29udGFpbnMobm9kZUxpc3QsIGNhbnZhcykge1xuICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZUxpc3QpIHtcbiAgICBpZiAobm9kZSA9PT0gY2FudmFzIHx8IG5vZGUuY29udGFpbnMoY2FudmFzKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUF0dGFjaE9ic2VydmVyKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge1xuICBjb25zdCBjYW52YXMgPSBjaGFydC5jYW52YXM7XG4gIGNvbnN0IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoZW50cmllcyA9PiB7XG4gICAgbGV0IHRyaWdnZXIgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIHRyaWdnZXIgPSB0cmlnZ2VyIHx8IG5vZGVMaXN0Q29udGFpbnMoZW50cnkuYWRkZWROb2RlcywgY2FudmFzKTtcbiAgICAgIHRyaWdnZXIgPSB0cmlnZ2VyICYmICFub2RlTGlzdENvbnRhaW5zKGVudHJ5LnJlbW92ZWROb2RlcywgY2FudmFzKTtcbiAgICB9XG4gICAgaWYgKHRyaWdnZXIpIHtcbiAgICAgIGxpc3RlbmVyKCk7XG4gICAgfVxuICB9KTtcbiAgb2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudCwge2NoaWxkTGlzdDogdHJ1ZSwgc3VidHJlZTogdHJ1ZX0pO1xuICByZXR1cm4gb2JzZXJ2ZXI7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURldGFjaE9ic2VydmVyKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge1xuICBjb25zdCBjYW52YXMgPSBjaGFydC5jYW52YXM7XG4gIGNvbnN0IG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoZW50cmllcyA9PiB7XG4gICAgbGV0IHRyaWdnZXIgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIHRyaWdnZXIgPSB0cmlnZ2VyIHx8IG5vZGVMaXN0Q29udGFpbnMoZW50cnkucmVtb3ZlZE5vZGVzLCBjYW52YXMpO1xuICAgICAgdHJpZ2dlciA9IHRyaWdnZXIgJiYgIW5vZGVMaXN0Q29udGFpbnMoZW50cnkuYWRkZWROb2RlcywgY2FudmFzKTtcbiAgICB9XG4gICAgaWYgKHRyaWdnZXIpIHtcbiAgICAgIGxpc3RlbmVyKCk7XG4gICAgfVxuICB9KTtcbiAgb2JzZXJ2ZXIub2JzZXJ2ZShkb2N1bWVudCwge2NoaWxkTGlzdDogdHJ1ZSwgc3VidHJlZTogdHJ1ZX0pO1xuICByZXR1cm4gb2JzZXJ2ZXI7XG59XG5cbmNvbnN0IGRycExpc3RlbmluZ0NoYXJ0cyA9IG5ldyBNYXAoKTtcbmxldCBvbGREZXZpY2VQaXhlbFJhdGlvID0gMDtcblxuZnVuY3Rpb24gb25XaW5kb3dSZXNpemUoKSB7XG4gIGNvbnN0IGRwciA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICBpZiAoZHByID09PSBvbGREZXZpY2VQaXhlbFJhdGlvKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIG9sZERldmljZVBpeGVsUmF0aW8gPSBkcHI7XG4gIGRycExpc3RlbmluZ0NoYXJ0cy5mb3JFYWNoKChyZXNpemUsIGNoYXJ0KSA9PiB7XG4gICAgaWYgKGNoYXJ0LmN1cnJlbnREZXZpY2VQaXhlbFJhdGlvICE9PSBkcHIpIHtcbiAgICAgIHJlc2l6ZSgpO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGxpc3RlbkRldmljZVBpeGVsUmF0aW9DaGFuZ2VzKGNoYXJ0LCByZXNpemUpIHtcbiAgaWYgKCFkcnBMaXN0ZW5pbmdDaGFydHMuc2l6ZSkge1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBvbldpbmRvd1Jlc2l6ZSk7XG4gIH1cbiAgZHJwTGlzdGVuaW5nQ2hhcnRzLnNldChjaGFydCwgcmVzaXplKTtcbn1cblxuZnVuY3Rpb24gdW5saXN0ZW5EZXZpY2VQaXhlbFJhdGlvQ2hhbmdlcyhjaGFydCkge1xuICBkcnBMaXN0ZW5pbmdDaGFydHMuZGVsZXRlKGNoYXJ0KTtcbiAgaWYgKCFkcnBMaXN0ZW5pbmdDaGFydHMuc2l6ZSkge1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBvbldpbmRvd1Jlc2l6ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUmVzaXplT2JzZXJ2ZXIoY2hhcnQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIGNvbnN0IGNhbnZhcyA9IGNoYXJ0LmNhbnZhcztcbiAgY29uc3QgY29udGFpbmVyID0gY2FudmFzICYmIF9nZXRQYXJlbnROb2RlKGNhbnZhcyk7XG4gIGlmICghY29udGFpbmVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IHJlc2l6ZSA9IHRocm90dGxlZCgod2lkdGgsIGhlaWdodCkgPT4ge1xuICAgIGNvbnN0IHcgPSBjb250YWluZXIuY2xpZW50V2lkdGg7XG4gICAgbGlzdGVuZXIod2lkdGgsIGhlaWdodCk7XG4gICAgaWYgKHcgPCBjb250YWluZXIuY2xpZW50V2lkdGgpIHtcbiAgICAgIC8vIElmIHRoZSBjb250YWluZXIgc2l6ZSBzaHJhbmsgZHVyaW5nIGNoYXJ0IHJlc2l6ZSwgbGV0J3MgYXNzdW1lXG4gICAgICAvLyBzY3JvbGxiYXIgYXBwZWFyZWQuIFNvIHdlIHJlc2l6ZSBhZ2FpbiB3aXRoIHRoZSBzY3JvbGxiYXIgdmlzaWJsZSAtXG4gICAgICAvLyBlZmZlY3RpdmVseSBtYWtpbmcgY2hhcnQgc21hbGxlciBhbmQgdGhlIHNjcm9sbGJhciBoaWRkZW4gYWdhaW4uXG4gICAgICAvLyBCZWNhdXNlIHdlIGFyZSBpbnNpZGUgYHRocm90dGxlZGAsIGFuZCBjdXJyZW50bHkgYHRpY2tpbmdgLCBzY3JvbGxcbiAgICAgIC8vIGV2ZW50cyBhcmUgaWdub3JlZCBkdXJpbmcgdGhpcyB3aG9sZSAyIHJlc2l6ZSBwcm9jZXNzLlxuICAgICAgLy8gSWYgd2UgYXNzdW1lZCB3cm9uZyBhbmQgc29tZXRoaW5nIGVsc2UgaGFwcGVuZWQsIHdlIGFyZSByZXNpemluZ1xuICAgICAgLy8gdHdpY2UgaW4gYSBmcmFtZSAocG90ZW50aWFsIHBlcmZvcm1hbmNlIGlzc3VlKVxuICAgICAgbGlzdGVuZXIoKTtcbiAgICB9XG4gIH0sIHdpbmRvdyk7XG5cbiAgLy8gQHRzLWlnbm9yZSB1bnRpbCBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzM3ODYxIGltcGxlbWVudGVkXG4gIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKGVudHJpZXMgPT4ge1xuICAgIGNvbnN0IGVudHJ5ID0gZW50cmllc1swXTtcbiAgICBjb25zdCB3aWR0aCA9IGVudHJ5LmNvbnRlbnRSZWN0LndpZHRoO1xuICAgIGNvbnN0IGhlaWdodCA9IGVudHJ5LmNvbnRlbnRSZWN0LmhlaWdodDtcbiAgICAvLyBXaGVuIGl0cyBjb250YWluZXIncyBkaXNwbGF5IGlzIHNldCB0byAnbm9uZScgdGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHdpdGggYVxuICAgIC8vIHNpemUgb2YgKDAsIDApLCB3aGljaCB3aWxsIGNhdXNlIHRoZSBjaGFydCB0byBsb3NlIGl0cyBvcmlnaW5hbCBoZWlnaHQsIHNvIHNraXBcbiAgICAvLyByZXNpemluZyBpbiBzdWNoIGNhc2UuXG4gICAgaWYgKHdpZHRoID09PSAwICYmIGhlaWdodCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZXNpemUod2lkdGgsIGhlaWdodCk7XG4gIH0pO1xuICBvYnNlcnZlci5vYnNlcnZlKGNvbnRhaW5lcik7XG4gIGxpc3RlbkRldmljZVBpeGVsUmF0aW9DaGFuZ2VzKGNoYXJ0LCByZXNpemUpO1xuXG4gIHJldHVybiBvYnNlcnZlcjtcbn1cblxuZnVuY3Rpb24gcmVsZWFzZU9ic2VydmVyKGNoYXJ0LCB0eXBlLCBvYnNlcnZlcikge1xuICBpZiAob2JzZXJ2ZXIpIHtcbiAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gIH1cbiAgaWYgKHR5cGUgPT09ICdyZXNpemUnKSB7XG4gICAgdW5saXN0ZW5EZXZpY2VQaXhlbFJhdGlvQ2hhbmdlcyhjaGFydCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUHJveHlBbmRMaXN0ZW4oY2hhcnQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIGNvbnN0IGNhbnZhcyA9IGNoYXJ0LmNhbnZhcztcbiAgY29uc3QgcHJveHkgPSB0aHJvdHRsZWQoKGV2ZW50KSA9PiB7XG4gICAgLy8gVGhpcyBjYXNlIGNhbiBvY2N1ciBpZiB0aGUgY2hhcnQgaXMgZGVzdHJveWVkIHdoaWxlIHdhaXRpbmdcbiAgICAvLyBmb3IgdGhlIHRocm90dGxlZCBmdW5jdGlvbiB0byBvY2N1ci4gV2UgcHJldmVudCBjcmFzaGVzIGJ5IGNoZWNraW5nXG4gICAgLy8gZm9yIGEgZGVzdHJveWVkIGNoYXJ0XG4gICAgaWYgKGNoYXJ0LmN0eCAhPT0gbnVsbCkge1xuICAgICAgbGlzdGVuZXIoZnJvbU5hdGl2ZUV2ZW50KGV2ZW50LCBjaGFydCkpO1xuICAgIH1cbiAgfSwgY2hhcnQpO1xuXG4gIGFkZExpc3RlbmVyKGNhbnZhcywgdHlwZSwgcHJveHkpO1xuXG4gIHJldHVybiBwcm94eTtcbn1cblxuLyoqXG4gKiBQbGF0Zm9ybSBjbGFzcyBmb3IgY2hhcnRzIHRoYXQgY2FuIGFjY2VzcyB0aGUgRE9NIGFuZCBnbG9iYWwgd2luZG93L2RvY3VtZW50IHByb3BlcnRpZXNcbiAqIEBleHRlbmRzIEJhc2VQbGF0Zm9ybVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb21QbGF0Zm9ybSBleHRlbmRzIEJhc2VQbGF0Zm9ybSB7XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7SFRNTENhbnZhc0VsZW1lbnR9IGNhbnZhc1xuXHQgKiBAcGFyYW0ge251bWJlcn0gW2FzcGVjdFJhdGlvXVxuXHQgKiBAcmV0dXJuIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR8bnVsbH1cblx0ICovXG4gIGFjcXVpcmVDb250ZXh0KGNhbnZhcywgYXNwZWN0UmF0aW8pIHtcbiAgICAvLyBUbyBwcmV2ZW50IGNhbnZhcyBmaW5nZXJwcmludGluZywgc29tZSBhZGQtb25zIHVuZGVmaW5lIHRoZSBnZXRDb250ZXh0XG4gICAgLy8gbWV0aG9kLCBmb3IgZXhhbXBsZTogaHR0cHM6Ly9naXRodWIuY29tL2trYXBzbmVyL0NhbnZhc0Jsb2NrZXJcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMjgwN1xuICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMgJiYgY2FudmFzLmdldENvbnRleHQgJiYgY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG5cbiAgICAvLyBgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudC9DYW52YXNSZW5kZXJpbmdDb250ZXh0MkRgIGZhaWxzIHdoZW4gdGhlIGNhbnZhcyBpc1xuICAgIC8vIGluc2lkZSBhbiBpZnJhbWUgb3Igd2hlbiBydW5uaW5nIGluIGEgcHJvdGVjdGVkIGVudmlyb25tZW50LiBXZSBjb3VsZCBndWVzcyB0aGVcbiAgICAvLyB0eXBlcyBmcm9tIHRoZWlyIHRvU3RyaW5nKCkgdmFsdWUgYnV0IGxldCdzIGtlZXAgdGhpbmdzIGZsZXhpYmxlIGFuZCBhc3N1bWUgaXQnc1xuICAgIC8vIGEgc3VmZmljaWVudCBjb25kaXRpb24gaWYgdGhlIGNhbnZhcyBoYXMgYSBjb250ZXh0MkQgd2hpY2ggaGFzIGNhbnZhcyBhcyBgY2FudmFzYC5cbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMzg4N1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy80MTAyXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzQxNTJcbiAgICBpZiAoY29udGV4dCAmJiBjb250ZXh0LmNhbnZhcyA9PT0gY2FudmFzKSB7XG4gICAgICAvLyBMb2FkIHBsYXRmb3JtIHJlc291cmNlcyBvbiBmaXJzdCBjaGFydCBjcmVhdGlvbiwgdG8gbWFrZSBpdCBwb3NzaWJsZSB0b1xuICAgICAgLy8gaW1wb3J0IHRoZSBsaWJyYXJ5IGJlZm9yZSBzZXR0aW5nIHBsYXRmb3JtIG9wdGlvbnMuXG4gICAgICBpbml0Q2FudmFzKGNhbnZhcywgYXNwZWN0UmF0aW8pO1xuICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHRcblx0ICovXG4gIHJlbGVhc2VDb250ZXh0KGNvbnRleHQpIHtcbiAgICBjb25zdCBjYW52YXMgPSBjb250ZXh0LmNhbnZhcztcbiAgICBpZiAoIWNhbnZhc1tFWFBBTkRPX0tFWV0pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsID0gY2FudmFzW0VYUEFORE9fS0VZXS5pbml0aWFsO1xuICAgIFsnaGVpZ2h0JywgJ3dpZHRoJ10uZm9yRWFjaCgocHJvcCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBpbml0aWFsW3Byb3BdO1xuICAgICAgaWYgKGlzTnVsbE9yVW5kZWYodmFsdWUpKSB7XG4gICAgICAgIGNhbnZhcy5yZW1vdmVBdHRyaWJ1dGUocHJvcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYW52YXMuc2V0QXR0cmlidXRlKHByb3AsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IHN0eWxlID0gaW5pdGlhbC5zdHlsZSB8fCB7fTtcbiAgICBPYmplY3Qua2V5cyhzdHlsZSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBjYW52YXMuc3R5bGVba2V5XSA9IHN0eWxlW2tleV07XG4gICAgfSk7XG5cbiAgICAvLyBUaGUgY2FudmFzIHJlbmRlciBzaXplIG1pZ2h0IGhhdmUgYmVlbiBjaGFuZ2VkIChhbmQgdGh1cyB0aGUgc3RhdGUgc3RhY2sgZGlzY2FyZGVkKSxcbiAgICAvLyB3ZSBjYW4ndCB1c2Ugc2F2ZSgpIGFuZCByZXN0b3JlKCkgdG8gcmVzdG9yZSB0aGUgaW5pdGlhbCBzdGF0ZS4gU28gbWFrZSBzdXJlIHRoYXQgYXRcbiAgICAvLyBsZWFzdCB0aGUgY2FudmFzIGNvbnRleHQgaXMgcmVzZXQgdG8gdGhlIGRlZmF1bHQgc3RhdGUgYnkgc2V0dGluZyB0aGUgY2FudmFzIHdpZHRoLlxuICAgIC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDExL1dELWh0bWw1LTIwMTEwNTI1L3RoZS1jYW52YXMtZWxlbWVudC5odG1sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtYXNzaWduXG4gICAgY2FudmFzLndpZHRoID0gY2FudmFzLndpZHRoO1xuXG4gICAgZGVsZXRlIGNhbnZhc1tFWFBBTkRPX0tFWV07XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcblx0ICpcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnRcblx0ICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcblx0ICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXJcblx0ICovXG4gIGFkZEV2ZW50TGlzdGVuZXIoY2hhcnQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgLy8gQ2FuIGhhdmUgb25seSBvbmUgbGlzdGVuZXIgcGVyIHR5cGUsIHNvIG1ha2Ugc3VyZSBwcmV2aW91cyBpcyByZW1vdmVkXG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKGNoYXJ0LCB0eXBlKTtcblxuICAgIGNvbnN0IHByb3hpZXMgPSBjaGFydC4kcHJveGllcyB8fCAoY2hhcnQuJHByb3hpZXMgPSB7fSk7XG4gICAgY29uc3QgaGFuZGxlcnMgPSB7XG4gICAgICBhdHRhY2g6IGNyZWF0ZUF0dGFjaE9ic2VydmVyLFxuICAgICAgZGV0YWNoOiBjcmVhdGVEZXRhY2hPYnNlcnZlcixcbiAgICAgIHJlc2l6ZTogY3JlYXRlUmVzaXplT2JzZXJ2ZXJcbiAgICB9O1xuICAgIGNvbnN0IGhhbmRsZXIgPSBoYW5kbGVyc1t0eXBlXSB8fCBjcmVhdGVQcm94eUFuZExpc3RlbjtcbiAgICBwcm94aWVzW3R5cGVdID0gaGFuZGxlcihjaGFydCwgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG5cblxuICAvKipcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnRcblx0ICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcblx0ICovXG4gIHJlbW92ZUV2ZW50TGlzdGVuZXIoY2hhcnQsIHR5cGUpIHtcbiAgICBjb25zdCBwcm94aWVzID0gY2hhcnQuJHByb3hpZXMgfHwgKGNoYXJ0LiRwcm94aWVzID0ge30pO1xuICAgIGNvbnN0IHByb3h5ID0gcHJveGllc1t0eXBlXTtcblxuICAgIGlmICghcHJveHkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoYW5kbGVycyA9IHtcbiAgICAgIGF0dGFjaDogcmVsZWFzZU9ic2VydmVyLFxuICAgICAgZGV0YWNoOiByZWxlYXNlT2JzZXJ2ZXIsXG4gICAgICByZXNpemU6IHJlbGVhc2VPYnNlcnZlclxuICAgIH07XG4gICAgY29uc3QgaGFuZGxlciA9IGhhbmRsZXJzW3R5cGVdIHx8IHJlbW92ZUxpc3RlbmVyO1xuICAgIGhhbmRsZXIoY2hhcnQsIHR5cGUsIHByb3h5KTtcbiAgICBwcm94aWVzW3R5cGVdID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgZ2V0RGV2aWNlUGl4ZWxSYXRpbygpIHtcbiAgICByZXR1cm4gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbd2lkdGhdIC0gY29udGVudCB3aWR0aCBvZiBwYXJlbnQgZWxlbWVudFxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2hlaWdodF0gLSBjb250ZW50IGhlaWdodCBvZiBwYXJlbnQgZWxlbWVudFxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2FzcGVjdFJhdGlvXSAtIGFzcGVjdCByYXRpbyB0byBtYWludGFpblxuXHQgKi9cbiAgZ2V0TWF4aW11bVNpemUoY2FudmFzLCB3aWR0aCwgaGVpZ2h0LCBhc3BlY3RSYXRpbykge1xuICAgIHJldHVybiBnZXRNYXhpbXVtU2l6ZShjYW52YXMsIHdpZHRoLCBoZWlnaHQsIGFzcGVjdFJhdGlvKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge0hUTUxDYW52YXNFbGVtZW50fSBjYW52YXNcblx0ICovXG4gIGlzQXR0YWNoZWQoY2FudmFzKSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gX2dldFBhcmVudE5vZGUoY2FudmFzKTtcbiAgICByZXR1cm4gISEoY29udGFpbmVyICYmIGNvbnRhaW5lci5pc0Nvbm5lY3RlZCk7XG4gIH1cbn1cbiIsICJpbXBvcnQge19pc0RvbVN1cHBvcnRlZH0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5pbXBvcnQgQmFzZVBsYXRmb3JtIGZyb20gJy4vcGxhdGZvcm0uYmFzZS5qcyc7XG5pbXBvcnQgQmFzaWNQbGF0Zm9ybSBmcm9tICcuL3BsYXRmb3JtLmJhc2ljLmpzJztcbmltcG9ydCBEb21QbGF0Zm9ybSBmcm9tICcuL3BsYXRmb3JtLmRvbS5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBfZGV0ZWN0UGxhdGZvcm0oY2FudmFzKSB7XG4gIGlmICghX2lzRG9tU3VwcG9ydGVkKCkgfHwgKHR5cGVvZiBPZmZzY3JlZW5DYW52YXMgIT09ICd1bmRlZmluZWQnICYmIGNhbnZhcyBpbnN0YW5jZW9mIE9mZnNjcmVlbkNhbnZhcykpIHtcbiAgICByZXR1cm4gQmFzaWNQbGF0Zm9ybTtcbiAgfVxuICByZXR1cm4gRG9tUGxhdGZvcm07XG59XG5cbmV4cG9ydCB7QmFzZVBsYXRmb3JtLCBCYXNpY1BsYXRmb3JtLCBEb21QbGF0Zm9ybX07XG4iLCAiaW1wb3J0IHR5cGUge0FueU9iamVjdH0gZnJvbSAnLi4vdHlwZXMvYmFzaWMuanMnO1xuaW1wb3J0IHR5cGUge1BvaW50fSBmcm9tICcuLi90eXBlcy9nZW9tZXRyaWMuanMnO1xuaW1wb3J0IHR5cGUge0FuaW1hdGlvbn0gZnJvbSAnLi4vdHlwZXMvYW5pbWF0aW9uLmpzJztcbmltcG9ydCB7aXNOdW1iZXJ9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRWxlbWVudDxUID0gQW55T2JqZWN0LCBPID0gQW55T2JqZWN0PiB7XG5cbiAgc3RhdGljIGRlZmF1bHRzID0ge307XG4gIHN0YXRpYyBkZWZhdWx0Um91dGVzID0gdW5kZWZpbmVkO1xuXG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICBhY3RpdmUgPSBmYWxzZTtcbiAgb3B0aW9uczogTztcbiAgJGFuaW1hdGlvbnM6IFJlY29yZDxrZXlvZiBULCBBbmltYXRpb24+O1xuXG4gIHRvb2x0aXBQb3NpdGlvbih1c2VGaW5hbFBvc2l0aW9uOiBib29sZWFuKTogUG9pbnQge1xuICAgIGNvbnN0IHt4LCB5fSA9IHRoaXMuZ2V0UHJvcHMoWyd4JywgJ3knXSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgcmV0dXJuIHt4LCB5fSBhcyBQb2ludDtcbiAgfVxuXG4gIGhhc1ZhbHVlKCkge1xuICAgIHJldHVybiBpc051bWJlcih0aGlzLngpICYmIGlzTnVtYmVyKHRoaXMueSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgY3VycmVudCBvciBmaW5hbCB2YWx1ZSBvZiBlYWNoIHByb3AuIENhbiByZXR1cm4gZXh0cmEgcHJvcGVydGllcyAod2hvbGUgb2JqZWN0KS5cbiAgICogQHBhcmFtIHByb3BzIC0gcHJvcGVydGllcyB0byBnZXRcbiAgICogQHBhcmFtIFtmaW5hbF0gLSBnZXQgdGhlIGZpbmFsIHZhbHVlIChhbmltYXRpb24gdGFyZ2V0KVxuICAgKi9cbiAgZ2V0UHJvcHM8UCBleHRlbmRzIChrZXlvZiBUKVtdPihwcm9wczogUCwgZmluYWw/OiBib29sZWFuKTogUGljazxULCBQW251bWJlcl0+O1xuICBnZXRQcm9wczxQIGV4dGVuZHMgc3RyaW5nPihwcm9wczogUFtdLCBmaW5hbD86IGJvb2xlYW4pOiBQYXJ0aWFsPFJlY29yZDxQLCB1bmtub3duPj47XG4gIGdldFByb3BzKHByb3BzOiBzdHJpbmdbXSwgZmluYWw/OiBib29sZWFuKTogUGFydGlhbDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ge1xuICAgIGNvbnN0IGFuaW1zID0gdGhpcy4kYW5pbWF0aW9ucztcbiAgICBpZiAoIWZpbmFsIHx8ICFhbmltcykge1xuICAgICAgLy8gbGV0J3Mgbm90IGNyZWF0ZSBhbiBvYmplY3QsIGlmIG5vdCBuZWVkZWRcbiAgICAgIHJldHVybiB0aGlzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIH1cbiAgICBjb25zdCByZXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgcHJvcHMuZm9yRWFjaCgocHJvcCkgPT4ge1xuICAgICAgcmV0W3Byb3BdID0gYW5pbXNbcHJvcF0gJiYgYW5pbXNbcHJvcF0uYWN0aXZlKCkgPyBhbmltc1twcm9wXS5fdG8gOiB0aGlzW3Byb3AgYXMgc3RyaW5nXTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmV0O1xuICB9XG59XG4iLCAiaW1wb3J0IHtpc051bGxPclVuZGVmLCB2YWx1ZU9yRGVmYXVsdH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuaW1wb3J0IHtfZmFjdG9yaXplfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMubWF0aC5qcyc7XG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi9jb3JlLmNvbnRyb2xsZXIuanMnKS5kZWZhdWx0IH0gQ2hhcnRcbiAqIEB0eXBlZGVmIHt7dmFsdWU6bnVtYmVyIHwgc3RyaW5nLCBsYWJlbD86c3RyaW5nLCBtYWpvcj86Ym9vbGVhbiwgJGNvbnRleHQ/OmFueX19IFRpY2tcbiAqL1xuXG4vKipcbiAqIFJldHVybnMgYSBzdWJzZXQgb2YgdGlja3MgdG8gYmUgcGxvdHRlZCB0byBhdm9pZCBvdmVybGFwcGluZyBsYWJlbHMuXG4gKiBAcGFyYW0ge2ltcG9ydCgnLi9jb3JlLnNjYWxlLmpzJykuZGVmYXVsdH0gc2NhbGVcbiAqIEBwYXJhbSB7VGlja1tdfSB0aWNrc1xuICogQHJldHVybiB7VGlja1tdfVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF1dG9Ta2lwKHNjYWxlLCB0aWNrcykge1xuICBjb25zdCB0aWNrT3B0cyA9IHNjYWxlLm9wdGlvbnMudGlja3M7XG4gIGNvbnN0IGRldGVybWluZWRNYXhUaWNrcyA9IGRldGVybWluZU1heFRpY2tzKHNjYWxlKTtcbiAgY29uc3QgdGlja3NMaW1pdCA9IE1hdGgubWluKHRpY2tPcHRzLm1heFRpY2tzTGltaXQgfHwgZGV0ZXJtaW5lZE1heFRpY2tzLCBkZXRlcm1pbmVkTWF4VGlja3MpO1xuICBjb25zdCBtYWpvckluZGljZXMgPSB0aWNrT3B0cy5tYWpvci5lbmFibGVkID8gZ2V0TWFqb3JJbmRpY2VzKHRpY2tzKSA6IFtdO1xuICBjb25zdCBudW1NYWpvckluZGljZXMgPSBtYWpvckluZGljZXMubGVuZ3RoO1xuICBjb25zdCBmaXJzdCA9IG1ham9ySW5kaWNlc1swXTtcbiAgY29uc3QgbGFzdCA9IG1ham9ySW5kaWNlc1tudW1NYWpvckluZGljZXMgLSAxXTtcbiAgY29uc3QgbmV3VGlja3MgPSBbXTtcblxuICAvLyBJZiB0aGVyZSBhcmUgdG9vIG1hbnkgbWFqb3IgdGlja3MgdG8gZGlzcGxheSB0aGVtIGFsbFxuICBpZiAobnVtTWFqb3JJbmRpY2VzID4gdGlja3NMaW1pdCkge1xuICAgIHNraXBNYWpvcnModGlja3MsIG5ld1RpY2tzLCBtYWpvckluZGljZXMsIG51bU1ham9ySW5kaWNlcyAvIHRpY2tzTGltaXQpO1xuICAgIHJldHVybiBuZXdUaWNrcztcbiAgfVxuXG4gIGNvbnN0IHNwYWNpbmcgPSBjYWxjdWxhdGVTcGFjaW5nKG1ham9ySW5kaWNlcywgdGlja3MsIHRpY2tzTGltaXQpO1xuXG4gIGlmIChudW1NYWpvckluZGljZXMgPiAwKSB7XG4gICAgbGV0IGksIGlsZW47XG4gICAgY29uc3QgYXZnTWFqb3JTcGFjaW5nID0gbnVtTWFqb3JJbmRpY2VzID4gMSA/IE1hdGgucm91bmQoKGxhc3QgLSBmaXJzdCkgLyAobnVtTWFqb3JJbmRpY2VzIC0gMSkpIDogbnVsbDtcbiAgICBza2lwKHRpY2tzLCBuZXdUaWNrcywgc3BhY2luZywgaXNOdWxsT3JVbmRlZihhdmdNYWpvclNwYWNpbmcpID8gMCA6IGZpcnN0IC0gYXZnTWFqb3JTcGFjaW5nLCBmaXJzdCk7XG4gICAgZm9yIChpID0gMCwgaWxlbiA9IG51bU1ham9ySW5kaWNlcyAtIDE7IGkgPCBpbGVuOyBpKyspIHtcbiAgICAgIHNraXAodGlja3MsIG5ld1RpY2tzLCBzcGFjaW5nLCBtYWpvckluZGljZXNbaV0sIG1ham9ySW5kaWNlc1tpICsgMV0pO1xuICAgIH1cbiAgICBza2lwKHRpY2tzLCBuZXdUaWNrcywgc3BhY2luZywgbGFzdCwgaXNOdWxsT3JVbmRlZihhdmdNYWpvclNwYWNpbmcpID8gdGlja3MubGVuZ3RoIDogbGFzdCArIGF2Z01ham9yU3BhY2luZyk7XG4gICAgcmV0dXJuIG5ld1RpY2tzO1xuICB9XG4gIHNraXAodGlja3MsIG5ld1RpY2tzLCBzcGFjaW5nKTtcbiAgcmV0dXJuIG5ld1RpY2tzO1xufVxuXG5mdW5jdGlvbiBkZXRlcm1pbmVNYXhUaWNrcyhzY2FsZSkge1xuICBjb25zdCBvZmZzZXQgPSBzY2FsZS5vcHRpb25zLm9mZnNldDtcbiAgY29uc3QgdGlja0xlbmd0aCA9IHNjYWxlLl90aWNrU2l6ZSgpO1xuICBjb25zdCBtYXhTY2FsZSA9IHNjYWxlLl9sZW5ndGggLyB0aWNrTGVuZ3RoICsgKG9mZnNldCA/IDAgOiAxKTtcbiAgY29uc3QgbWF4Q2hhcnQgPSBzY2FsZS5fbWF4TGVuZ3RoIC8gdGlja0xlbmd0aDtcbiAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5taW4obWF4U2NhbGUsIG1heENoYXJ0KSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJbXX0gbWFqb3JJbmRpY2VzXG4gKiBAcGFyYW0ge1RpY2tbXX0gdGlja3NcbiAqIEBwYXJhbSB7bnVtYmVyfSB0aWNrc0xpbWl0XG4gKi9cbmZ1bmN0aW9uIGNhbGN1bGF0ZVNwYWNpbmcobWFqb3JJbmRpY2VzLCB0aWNrcywgdGlja3NMaW1pdCkge1xuICBjb25zdCBldmVuTWFqb3JTcGFjaW5nID0gZ2V0RXZlblNwYWNpbmcobWFqb3JJbmRpY2VzKTtcbiAgY29uc3Qgc3BhY2luZyA9IHRpY2tzLmxlbmd0aCAvIHRpY2tzTGltaXQ7XG5cbiAgLy8gSWYgdGhlIG1ham9yIHRpY2tzIGFyZSBldmVubHkgc3BhY2VkIGFwYXJ0LCBwbGFjZSB0aGUgbWlub3IgdGlja3NcbiAgLy8gc28gdGhhdCB0aGV5IGRpdmlkZSB0aGUgbWFqb3IgdGlja3MgaW50byBldmVuIGNodW5rc1xuICBpZiAoIWV2ZW5NYWpvclNwYWNpbmcpIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoc3BhY2luZywgMSk7XG4gIH1cblxuICBjb25zdCBmYWN0b3JzID0gX2ZhY3Rvcml6ZShldmVuTWFqb3JTcGFjaW5nKTtcbiAgZm9yIChsZXQgaSA9IDAsIGlsZW4gPSBmYWN0b3JzLmxlbmd0aCAtIDE7IGkgPCBpbGVuOyBpKyspIHtcbiAgICBjb25zdCBmYWN0b3IgPSBmYWN0b3JzW2ldO1xuICAgIGlmIChmYWN0b3IgPiBzcGFjaW5nKSB7XG4gICAgICByZXR1cm4gZmFjdG9yO1xuICAgIH1cbiAgfVxuICByZXR1cm4gTWF0aC5tYXgoc3BhY2luZywgMSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtUaWNrW119IHRpY2tzXG4gKi9cbmZ1bmN0aW9uIGdldE1ham9ySW5kaWNlcyh0aWNrcykge1xuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgbGV0IGksIGlsZW47XG4gIGZvciAoaSA9IDAsIGlsZW4gPSB0aWNrcy5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcbiAgICBpZiAodGlja3NbaV0ubWFqb3IpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEBwYXJhbSB7VGlja1tdfSB0aWNrc1xuICogQHBhcmFtIHtUaWNrW119IG5ld1RpY2tzXG4gKiBAcGFyYW0ge251bWJlcltdfSBtYWpvckluZGljZXNcbiAqIEBwYXJhbSB7bnVtYmVyfSBzcGFjaW5nXG4gKi9cbmZ1bmN0aW9uIHNraXBNYWpvcnModGlja3MsIG5ld1RpY2tzLCBtYWpvckluZGljZXMsIHNwYWNpbmcpIHtcbiAgbGV0IGNvdW50ID0gMDtcbiAgbGV0IG5leHQgPSBtYWpvckluZGljZXNbMF07XG4gIGxldCBpO1xuXG4gIHNwYWNpbmcgPSBNYXRoLmNlaWwoc3BhY2luZyk7XG4gIGZvciAoaSA9IDA7IGkgPCB0aWNrcy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpID09PSBuZXh0KSB7XG4gICAgICBuZXdUaWNrcy5wdXNoKHRpY2tzW2ldKTtcbiAgICAgIGNvdW50Kys7XG4gICAgICBuZXh0ID0gbWFqb3JJbmRpY2VzW2NvdW50ICogc3BhY2luZ107XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtUaWNrW119IHRpY2tzXG4gKiBAcGFyYW0ge1RpY2tbXX0gbmV3VGlja3NcbiAqIEBwYXJhbSB7bnVtYmVyfSBzcGFjaW5nXG4gKiBAcGFyYW0ge251bWJlcn0gW21ham9yU3RhcnRdXG4gKiBAcGFyYW0ge251bWJlcn0gW21ham9yRW5kXVxuICovXG5mdW5jdGlvbiBza2lwKHRpY2tzLCBuZXdUaWNrcywgc3BhY2luZywgbWFqb3JTdGFydCwgbWFqb3JFbmQpIHtcbiAgY29uc3Qgc3RhcnQgPSB2YWx1ZU9yRGVmYXVsdChtYWpvclN0YXJ0LCAwKTtcbiAgY29uc3QgZW5kID0gTWF0aC5taW4odmFsdWVPckRlZmF1bHQobWFqb3JFbmQsIHRpY2tzLmxlbmd0aCksIHRpY2tzLmxlbmd0aCk7XG4gIGxldCBjb3VudCA9IDA7XG4gIGxldCBsZW5ndGgsIGksIG5leHQ7XG5cbiAgc3BhY2luZyA9IE1hdGguY2VpbChzcGFjaW5nKTtcbiAgaWYgKG1ham9yRW5kKSB7XG4gICAgbGVuZ3RoID0gbWFqb3JFbmQgLSBtYWpvclN0YXJ0O1xuICAgIHNwYWNpbmcgPSBsZW5ndGggLyBNYXRoLmZsb29yKGxlbmd0aCAvIHNwYWNpbmcpO1xuICB9XG5cbiAgbmV4dCA9IHN0YXJ0O1xuXG4gIHdoaWxlIChuZXh0IDwgMCkge1xuICAgIGNvdW50Kys7XG4gICAgbmV4dCA9IE1hdGgucm91bmQoc3RhcnQgKyBjb3VudCAqIHNwYWNpbmcpO1xuICB9XG5cbiAgZm9yIChpID0gTWF0aC5tYXgoc3RhcnQsIDApOyBpIDwgZW5kOyBpKyspIHtcbiAgICBpZiAoaSA9PT0gbmV4dCkge1xuICAgICAgbmV3VGlja3MucHVzaCh0aWNrc1tpXSk7XG4gICAgICBjb3VudCsrO1xuICAgICAgbmV4dCA9IE1hdGgucm91bmQoc3RhcnQgKyBjb3VudCAqIHNwYWNpbmcpO1xuICAgIH1cbiAgfVxufVxuXG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJbXX0gYXJyXG4gKi9cbmZ1bmN0aW9uIGdldEV2ZW5TcGFjaW5nKGFycikge1xuICBjb25zdCBsZW4gPSBhcnIubGVuZ3RoO1xuICBsZXQgaSwgZGlmZjtcblxuICBpZiAobGVuIDwgMikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZvciAoZGlmZiA9IGFyclswXSwgaSA9IDE7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhcnJbaV0gLSBhcnJbaSAtIDFdICE9PSBkaWZmKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiBkaWZmO1xufVxuIiwgImltcG9ydCBFbGVtZW50IGZyb20gJy4vY29yZS5lbGVtZW50LmpzJztcbmltcG9ydCB7X2FsaWduUGl4ZWwsIF9tZWFzdXJlVGV4dCwgcmVuZGVyVGV4dCwgY2xpcEFyZWEsIHVuY2xpcEFyZWF9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jYW52YXMuanMnO1xuaW1wb3J0IHtjYWxsYmFjayBhcyBjYWxsLCBlYWNoLCBmaW5pdGVPckRlZmF1bHQsIGlzQXJyYXksIGlzRmluaXRlLCBpc051bGxPclVuZGVmLCBpc09iamVjdCwgdmFsdWVPckRlZmF1bHR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7dG9EZWdyZWVzLCB0b1JhZGlhbnMsIF9pbnQxNlJhbmdlLCBfbGltaXRWYWx1ZSwgSEFMRl9QSX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IHtfYWxpZ25TdGFydEVuZCwgX3RvTGVmdFJpZ2h0Q2VudGVyfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZXh0cmFzLmpzJztcbmltcG9ydCB7Y3JlYXRlQ29udGV4dCwgdG9Gb250LCB0b1BhZGRpbmcsIF9hZGRHcmFjZX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm9wdGlvbnMuanMnO1xuaW1wb3J0IHthdXRvU2tpcH0gZnJvbSAnLi9jb3JlLnNjYWxlLmF1dG9za2lwLmpzJztcblxuY29uc3QgcmV2ZXJzZUFsaWduID0gKGFsaWduKSA9PiBhbGlnbiA9PT0gJ2xlZnQnID8gJ3JpZ2h0JyA6IGFsaWduID09PSAncmlnaHQnID8gJ2xlZnQnIDogYWxpZ247XG5jb25zdCBvZmZzZXRGcm9tRWRnZSA9IChzY2FsZSwgZWRnZSwgb2Zmc2V0KSA9PiBlZGdlID09PSAndG9wJyB8fCBlZGdlID09PSAnbGVmdCcgPyBzY2FsZVtlZGdlXSArIG9mZnNldCA6IHNjYWxlW2VkZ2VdIC0gb2Zmc2V0O1xuY29uc3QgZ2V0VGlja3NMaW1pdCA9ICh0aWNrc0xlbmd0aCwgbWF4VGlja3NMaW1pdCkgPT4gTWF0aC5taW4obWF4VGlja3NMaW1pdCB8fCB0aWNrc0xlbmd0aCwgdGlja3NMZW5ndGgpO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi90eXBlcy9pbmRleC5qcycpLkNoYXJ0IH0gQ2hhcnRcbiAqIEB0eXBlZGVmIHt7dmFsdWU6bnVtYmVyIHwgc3RyaW5nLCBsYWJlbD86c3RyaW5nLCBtYWpvcj86Ym9vbGVhbiwgJGNvbnRleHQ/OmFueX19IFRpY2tcbiAqL1xuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgYXJyYXkgY29udGFpbmluZyBudW1JdGVtcyBmcm9tIGFyclxuICogQHBhcmFtIHthbnlbXX0gYXJyXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtSXRlbXNcbiAqL1xuZnVuY3Rpb24gc2FtcGxlKGFyciwgbnVtSXRlbXMpIHtcbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGNvbnN0IGluY3JlbWVudCA9IGFyci5sZW5ndGggLyBudW1JdGVtcztcbiAgY29uc3QgbGVuID0gYXJyLmxlbmd0aDtcbiAgbGV0IGkgPSAwO1xuXG4gIGZvciAoOyBpIDwgbGVuOyBpICs9IGluY3JlbWVudCkge1xuICAgIHJlc3VsdC5wdXNoKGFycltNYXRoLmZsb29yKGkpXSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1NjYWxlfSBzY2FsZVxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9mZnNldEdyaWRMaW5lc1xuICovXG5mdW5jdGlvbiBnZXRQaXhlbEZvckdyaWRMaW5lKHNjYWxlLCBpbmRleCwgb2Zmc2V0R3JpZExpbmVzKSB7XG4gIGNvbnN0IGxlbmd0aCA9IHNjYWxlLnRpY2tzLmxlbmd0aDtcbiAgY29uc3QgdmFsaWRJbmRleCA9IE1hdGgubWluKGluZGV4LCBsZW5ndGggLSAxKTtcbiAgY29uc3Qgc3RhcnQgPSBzY2FsZS5fc3RhcnRQaXhlbDtcbiAgY29uc3QgZW5kID0gc2NhbGUuX2VuZFBpeGVsO1xuICBjb25zdCBlcHNpbG9uID0gMWUtNjsgLy8gMWUtNiBpcyBtYXJnaW4gaW4gcGl4ZWxzIGZvciBhY2N1bXVsYXRlZCBlcnJvci5cbiAgbGV0IGxpbmVWYWx1ZSA9IHNjYWxlLmdldFBpeGVsRm9yVGljayh2YWxpZEluZGV4KTtcbiAgbGV0IG9mZnNldDtcblxuICBpZiAob2Zmc2V0R3JpZExpbmVzKSB7XG4gICAgaWYgKGxlbmd0aCA9PT0gMSkge1xuICAgICAgb2Zmc2V0ID0gTWF0aC5tYXgobGluZVZhbHVlIC0gc3RhcnQsIGVuZCAtIGxpbmVWYWx1ZSk7XG4gICAgfSBlbHNlIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgb2Zmc2V0ID0gKHNjYWxlLmdldFBpeGVsRm9yVGljaygxKSAtIGxpbmVWYWx1ZSkgLyAyO1xuICAgIH0gZWxzZSB7XG4gICAgICBvZmZzZXQgPSAobGluZVZhbHVlIC0gc2NhbGUuZ2V0UGl4ZWxGb3JUaWNrKHZhbGlkSW5kZXggLSAxKSkgLyAyO1xuICAgIH1cbiAgICBsaW5lVmFsdWUgKz0gdmFsaWRJbmRleCA8IGluZGV4ID8gb2Zmc2V0IDogLW9mZnNldDtcblxuICAgIC8vIFJldHVybiB1bmRlZmluZWQgaWYgdGhlIHBpeGVsIGlzIG91dCBvZiB0aGUgcmFuZ2VcbiAgICBpZiAobGluZVZhbHVlIDwgc3RhcnQgLSBlcHNpbG9uIHx8IGxpbmVWYWx1ZSA+IGVuZCArIGVwc2lsb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGxpbmVWYWx1ZTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gY2FjaGVzXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoXG4gKi9cbmZ1bmN0aW9uIGdhcmJhZ2VDb2xsZWN0KGNhY2hlcywgbGVuZ3RoKSB7XG4gIGVhY2goY2FjaGVzLCAoY2FjaGUpID0+IHtcbiAgICBjb25zdCBnYyA9IGNhY2hlLmdjO1xuICAgIGNvbnN0IGdjTGVuID0gZ2MubGVuZ3RoIC8gMjtcbiAgICBsZXQgaTtcbiAgICBpZiAoZ2NMZW4gPiBsZW5ndGgpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBnY0xlbjsgKytpKSB7XG4gICAgICAgIGRlbGV0ZSBjYWNoZS5kYXRhW2djW2ldXTtcbiAgICAgIH1cbiAgICAgIGdjLnNwbGljZSgwLCBnY0xlbik7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICovXG5mdW5jdGlvbiBnZXRUaWNrTWFya0xlbmd0aChvcHRpb25zKSB7XG4gIHJldHVybiBvcHRpb25zLmRyYXdUaWNrcyA/IG9wdGlvbnMudGlja0xlbmd0aCA6IDA7XG59XG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gZ2V0VGl0bGVIZWlnaHQob3B0aW9ucywgZmFsbGJhY2spIHtcbiAgaWYgKCFvcHRpb25zLmRpc3BsYXkpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIGNvbnN0IGZvbnQgPSB0b0ZvbnQob3B0aW9ucy5mb250LCBmYWxsYmFjayk7XG4gIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcob3B0aW9ucy5wYWRkaW5nKTtcbiAgY29uc3QgbGluZXMgPSBpc0FycmF5KG9wdGlvbnMudGV4dCkgPyBvcHRpb25zLnRleHQubGVuZ3RoIDogMTtcblxuICByZXR1cm4gKGxpbmVzICogZm9udC5saW5lSGVpZ2h0KSArIHBhZGRpbmcuaGVpZ2h0O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTY2FsZUNvbnRleHQocGFyZW50LCBzY2FsZSkge1xuICByZXR1cm4gY3JlYXRlQ29udGV4dChwYXJlbnQsIHtcbiAgICBzY2FsZSxcbiAgICB0eXBlOiAnc2NhbGUnXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUaWNrQ29udGV4dChwYXJlbnQsIGluZGV4LCB0aWNrKSB7XG4gIHJldHVybiBjcmVhdGVDb250ZXh0KHBhcmVudCwge1xuICAgIHRpY2ssXG4gICAgaW5kZXgsXG4gICAgdHlwZTogJ3RpY2snXG4gIH0pO1xufVxuXG5mdW5jdGlvbiB0aXRsZUFsaWduKGFsaWduLCBwb3NpdGlvbiwgcmV2ZXJzZSkge1xuICAvKiogQHR5cGUge0NhbnZhc1RleHRBbGlnbn0gKi9cbiAgbGV0IHJldCA9IF90b0xlZnRSaWdodENlbnRlcihhbGlnbik7XG4gIGlmICgocmV2ZXJzZSAmJiBwb3NpdGlvbiAhPT0gJ3JpZ2h0JykgfHwgKCFyZXZlcnNlICYmIHBvc2l0aW9uID09PSAncmlnaHQnKSkge1xuICAgIHJldCA9IHJldmVyc2VBbGlnbihyZXQpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIHRpdGxlQXJncyhzY2FsZSwgb2Zmc2V0LCBwb3NpdGlvbiwgYWxpZ24pIHtcbiAgY29uc3Qge3RvcCwgbGVmdCwgYm90dG9tLCByaWdodCwgY2hhcnR9ID0gc2NhbGU7XG4gIGNvbnN0IHtjaGFydEFyZWEsIHNjYWxlc30gPSBjaGFydDtcbiAgbGV0IHJvdGF0aW9uID0gMDtcbiAgbGV0IG1heFdpZHRoLCB0aXRsZVgsIHRpdGxlWTtcbiAgY29uc3QgaGVpZ2h0ID0gYm90dG9tIC0gdG9wO1xuICBjb25zdCB3aWR0aCA9IHJpZ2h0IC0gbGVmdDtcblxuICBpZiAoc2NhbGUuaXNIb3Jpem9udGFsKCkpIHtcbiAgICB0aXRsZVggPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgbGVmdCwgcmlnaHQpO1xuXG4gICAgaWYgKGlzT2JqZWN0KHBvc2l0aW9uKSkge1xuICAgICAgY29uc3QgcG9zaXRpb25BeGlzSUQgPSBPYmplY3Qua2V5cyhwb3NpdGlvbilbMF07XG4gICAgICBjb25zdCB2YWx1ZSA9IHBvc2l0aW9uW3Bvc2l0aW9uQXhpc0lEXTtcbiAgICAgIHRpdGxlWSA9IHNjYWxlc1twb3NpdGlvbkF4aXNJRF0uZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSkgKyBoZWlnaHQgLSBvZmZzZXQ7XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgIHRpdGxlWSA9IChjaGFydEFyZWEuYm90dG9tICsgY2hhcnRBcmVhLnRvcCkgLyAyICsgaGVpZ2h0IC0gb2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aXRsZVkgPSBvZmZzZXRGcm9tRWRnZShzY2FsZSwgcG9zaXRpb24sIG9mZnNldCk7XG4gICAgfVxuICAgIG1heFdpZHRoID0gcmlnaHQgLSBsZWZ0O1xuICB9IGVsc2Uge1xuICAgIGlmIChpc09iamVjdChwb3NpdGlvbikpIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uQXhpc0lEID0gT2JqZWN0LmtleXMocG9zaXRpb24pWzBdO1xuICAgICAgY29uc3QgdmFsdWUgPSBwb3NpdGlvbltwb3NpdGlvbkF4aXNJRF07XG4gICAgICB0aXRsZVggPSBzY2FsZXNbcG9zaXRpb25BeGlzSURdLmdldFBpeGVsRm9yVmFsdWUodmFsdWUpIC0gd2lkdGggKyBvZmZzZXQ7XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgIHRpdGxlWCA9IChjaGFydEFyZWEubGVmdCArIGNoYXJ0QXJlYS5yaWdodCkgLyAyIC0gd2lkdGggKyBvZmZzZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRpdGxlWCA9IG9mZnNldEZyb21FZGdlKHNjYWxlLCBwb3NpdGlvbiwgb2Zmc2V0KTtcbiAgICB9XG4gICAgdGl0bGVZID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIGJvdHRvbSwgdG9wKTtcbiAgICByb3RhdGlvbiA9IHBvc2l0aW9uID09PSAnbGVmdCcgPyAtSEFMRl9QSSA6IEhBTEZfUEk7XG4gIH1cbiAgcmV0dXJuIHt0aXRsZVgsIHRpdGxlWSwgbWF4V2lkdGgsIHJvdGF0aW9ufTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2NhbGUgZXh0ZW5kcyBFbGVtZW50IHtcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LXN0YXRlbWVudHNcbiAgY29uc3RydWN0b3IoY2ZnKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgIHRoaXMuaWQgPSBjZmcuaWQ7XG4gICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgdGhpcy50eXBlID0gY2ZnLnR5cGU7XG4gICAgLyoqIEB0eXBlIHthbnl9ICovXG4gICAgdGhpcy5vcHRpb25zID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSAqL1xuICAgIHRoaXMuY3R4ID0gY2ZnLmN0eDtcbiAgICAvKiogQHR5cGUge0NoYXJ0fSAqL1xuICAgIHRoaXMuY2hhcnQgPSBjZmcuY2hhcnQ7XG5cbiAgICAvLyBpbXBsZW1lbnRzIGJveFxuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMudG9wID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuYm90dG9tID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMubGVmdCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLnJpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMud2lkdGggPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5oZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fbWFyZ2lucyA9IHtcbiAgICAgIGxlZnQ6IDAsXG4gICAgICByaWdodDogMCxcbiAgICAgIHRvcDogMCxcbiAgICAgIGJvdHRvbTogMFxuICAgIH07XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5tYXhXaWR0aCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLm1heEhlaWdodCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLnBhZGRpbmdUb3AgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5wYWRkaW5nQm90dG9tID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMucGFkZGluZ0xlZnQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5wYWRkaW5nUmlnaHQgPSB1bmRlZmluZWQ7XG5cbiAgICAvLyBzY2FsZS1zcGVjaWZpYyBwcm9wZXJ0aWVzXG4gICAgLyoqIEB0eXBlIHtzdHJpbmc9fSAqL1xuICAgIHRoaXMuYXhpcyA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcj19ICovXG4gICAgdGhpcy5sYWJlbFJvdGF0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWluID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWF4ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3JhbmdlID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7VGlja1tdfSAqL1xuICAgIHRoaXMudGlja3MgPSBbXTtcbiAgICAvKiogQHR5cGUge29iamVjdFtdfG51bGx9ICovXG4gICAgdGhpcy5fZ3JpZExpbmVJdGVtcyA9IG51bGw7XG4gICAgLyoqIEB0eXBlIHtvYmplY3RbXXxudWxsfSAqL1xuICAgIHRoaXMuX2xhYmVsSXRlbXMgPSBudWxsO1xuICAgIC8qKiBAdHlwZSB7b2JqZWN0fG51bGx9ICovXG4gICAgdGhpcy5fbGFiZWxTaXplcyA9IG51bGw7XG4gICAgdGhpcy5fbGVuZ3RoID0gMDtcbiAgICB0aGlzLl9tYXhMZW5ndGggPSAwO1xuICAgIHRoaXMuX2xvbmdlc3RUZXh0Q2FjaGUgPSB7fTtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLl9zdGFydFBpeGVsID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuX2VuZFBpeGVsID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3JldmVyc2VQaXhlbHMgPSBmYWxzZTtcbiAgICB0aGlzLl91c2VyTWF4ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3VzZXJNaW4gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fc3VnZ2VzdGVkTWF4ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3N1Z2dlc3RlZE1pbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl90aWNrc0xlbmd0aCA9IDA7XG4gICAgdGhpcy5fYm9yZGVyVmFsdWUgPSAwO1xuICAgIHRoaXMuX2NhY2hlID0ge307XG4gICAgdGhpcy5fZGF0YUxpbWl0c0NhY2hlZCA9IGZhbHNlO1xuICAgIHRoaXMuJGNvbnRleHQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHthbnl9IG9wdGlvbnNcblx0ICogQHNpbmNlIDMuMFxuXHQgKi9cbiAgaW5pdChvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucy5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpKTtcblxuICAgIHRoaXMuYXhpcyA9IG9wdGlvbnMuYXhpcztcblxuICAgIC8vIHBhcnNlIG1pbi9tYXggdmFsdWUsIHNvIHdlIGNhbiBwcm9wZXJseSBkZXRlcm1pbmUgbWluL21heCBmb3Igb3RoZXIgc2NhbGVzXG4gICAgdGhpcy5fdXNlck1pbiA9IHRoaXMucGFyc2Uob3B0aW9ucy5taW4pO1xuICAgIHRoaXMuX3VzZXJNYXggPSB0aGlzLnBhcnNlKG9wdGlvbnMubWF4KTtcbiAgICB0aGlzLl9zdWdnZXN0ZWRNaW4gPSB0aGlzLnBhcnNlKG9wdGlvbnMuc3VnZ2VzdGVkTWluKTtcbiAgICB0aGlzLl9zdWdnZXN0ZWRNYXggPSB0aGlzLnBhcnNlKG9wdGlvbnMuc3VnZ2VzdGVkTWF4KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBQYXJzZSBhIHN1cHBvcnRlZCBpbnB1dCB2YWx1ZSB0byBpbnRlcm5hbCByZXByZXNlbnRhdGlvbi5cblx0ICogQHBhcmFtIHsqfSByYXdcblx0ICogQHBhcmFtIHtudW1iZXJ9IFtpbmRleF1cblx0ICogQHNpbmNlIDMuMFxuXHQgKi9cbiAgcGFyc2UocmF3LCBpbmRleCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgcmV0dXJuIHJhdztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcmV0dXJuIHt7bWluOiBudW1iZXIsIG1heDogbnVtYmVyLCBtaW5EZWZpbmVkOiBib29sZWFuLCBtYXhEZWZpbmVkOiBib29sZWFufX1cblx0ICogQHByb3RlY3RlZFxuXHQgKiBAc2luY2UgMy4wXG5cdCAqL1xuICBnZXRVc2VyQm91bmRzKCkge1xuICAgIGxldCB7X3VzZXJNaW4sIF91c2VyTWF4LCBfc3VnZ2VzdGVkTWluLCBfc3VnZ2VzdGVkTWF4fSA9IHRoaXM7XG4gICAgX3VzZXJNaW4gPSBmaW5pdGVPckRlZmF1bHQoX3VzZXJNaW4sIE51bWJlci5QT1NJVElWRV9JTkZJTklUWSk7XG4gICAgX3VzZXJNYXggPSBmaW5pdGVPckRlZmF1bHQoX3VzZXJNYXgsIE51bWJlci5ORUdBVElWRV9JTkZJTklUWSk7XG4gICAgX3N1Z2dlc3RlZE1pbiA9IGZpbml0ZU9yRGVmYXVsdChfc3VnZ2VzdGVkTWluLCBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpO1xuICAgIF9zdWdnZXN0ZWRNYXggPSBmaW5pdGVPckRlZmF1bHQoX3N1Z2dlc3RlZE1heCwgTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZKTtcbiAgICByZXR1cm4ge1xuICAgICAgbWluOiBmaW5pdGVPckRlZmF1bHQoX3VzZXJNaW4sIF9zdWdnZXN0ZWRNaW4pLFxuICAgICAgbWF4OiBmaW5pdGVPckRlZmF1bHQoX3VzZXJNYXgsIF9zdWdnZXN0ZWRNYXgpLFxuICAgICAgbWluRGVmaW5lZDogaXNGaW5pdGUoX3VzZXJNaW4pLFxuICAgICAgbWF4RGVmaW5lZDogaXNGaW5pdGUoX3VzZXJNYXgpXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGNhblN0YWNrXG5cdCAqIEByZXR1cm4ge3ttaW46IG51bWJlciwgbWF4OiBudW1iZXJ9fVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqIEBzaW5jZSAzLjBcblx0ICovXG4gIGdldE1pbk1heChjYW5TdGFjaykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItY29uc3RcbiAgICBsZXQge21pbiwgbWF4LCBtaW5EZWZpbmVkLCBtYXhEZWZpbmVkfSA9IHRoaXMuZ2V0VXNlckJvdW5kcygpO1xuICAgIGxldCByYW5nZTtcblxuICAgIGlmIChtaW5EZWZpbmVkICYmIG1heERlZmluZWQpIHtcbiAgICAgIHJldHVybiB7bWluLCBtYXh9O1xuICAgIH1cblxuICAgIGNvbnN0IG1ldGFzID0gdGhpcy5nZXRNYXRjaGluZ1Zpc2libGVNZXRhcygpO1xuICAgIGZvciAobGV0IGkgPSAwLCBpbGVuID0gbWV0YXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICByYW5nZSA9IG1ldGFzW2ldLmNvbnRyb2xsZXIuZ2V0TWluTWF4KHRoaXMsIGNhblN0YWNrKTtcbiAgICAgIGlmICghbWluRGVmaW5lZCkge1xuICAgICAgICBtaW4gPSBNYXRoLm1pbihtaW4sIHJhbmdlLm1pbik7XG4gICAgICB9XG4gICAgICBpZiAoIW1heERlZmluZWQpIHtcbiAgICAgICAgbWF4ID0gTWF0aC5tYXgobWF4LCByYW5nZS5tYXgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE1ha2Ugc3VyZSBtaW4gPD0gbWF4IHdoZW4gb25seSBtaW4gb3IgbWF4IGlzIGRlZmluZWQgYnkgdXNlciBhbmQgdGhlIGRhdGEgaXMgb3V0c2lkZSB0aGF0IHJhbmdlXG4gICAgbWluID0gbWF4RGVmaW5lZCAmJiBtaW4gPiBtYXggPyBtYXggOiBtaW47XG4gICAgbWF4ID0gbWluRGVmaW5lZCAmJiBtaW4gPiBtYXggPyBtaW4gOiBtYXg7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbWluOiBmaW5pdGVPckRlZmF1bHQobWluLCBmaW5pdGVPckRlZmF1bHQobWF4LCBtaW4pKSxcbiAgICAgIG1heDogZmluaXRlT3JEZWZhdWx0KG1heCwgZmluaXRlT3JEZWZhdWx0KG1pbiwgbWF4KSlcbiAgICB9O1xuICB9XG5cbiAgLyoqXG5cdCAqIEdldCB0aGUgcGFkZGluZyBuZWVkZWQgZm9yIHRoZSBzY2FsZVxuXHQgKiBAcmV0dXJuIHt7dG9wOiBudW1iZXIsIGxlZnQ6IG51bWJlciwgYm90dG9tOiBudW1iZXIsIHJpZ2h0OiBudW1iZXJ9fSB0aGUgbmVjZXNzYXJ5IHBhZGRpbmdcblx0ICogQHByaXZhdGVcblx0ICovXG4gIGdldFBhZGRpbmcoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxlZnQ6IHRoaXMucGFkZGluZ0xlZnQgfHwgMCxcbiAgICAgIHRvcDogdGhpcy5wYWRkaW5nVG9wIHx8IDAsXG4gICAgICByaWdodDogdGhpcy5wYWRkaW5nUmlnaHQgfHwgMCxcbiAgICAgIGJvdHRvbTogdGhpcy5wYWRkaW5nQm90dG9tIHx8IDBcbiAgICB9O1xuICB9XG5cbiAgLyoqXG5cdCAqIFJldHVybnMgdGhlIHNjYWxlIHRpY2sgb2JqZWN0c1xuXHQgKiBAcmV0dXJuIHtUaWNrW119XG5cdCAqIEBzaW5jZSAyLjdcblx0ICovXG4gIGdldFRpY2tzKCkge1xuICAgIHJldHVybiB0aGlzLnRpY2tzO1xuICB9XG5cbiAgLyoqXG5cdCAqIEByZXR1cm4ge3N0cmluZ1tdfVxuXHQgKi9cbiAgZ2V0TGFiZWxzKCkge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmNoYXJ0LmRhdGE7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5sYWJlbHMgfHwgKHRoaXMuaXNIb3Jpem9udGFsKCkgPyBkYXRhLnhMYWJlbHMgOiBkYXRhLnlMYWJlbHMpIHx8IGRhdGEubGFiZWxzIHx8IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydCgnLi4vdHlwZXMuanMnKS5MYWJlbEl0ZW1bXX1cbiAgICovXG4gIGdldExhYmVsSXRlbXMoY2hhcnRBcmVhID0gdGhpcy5jaGFydC5jaGFydEFyZWEpIHtcbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuX2xhYmVsSXRlbXMgfHwgKHRoaXMuX2xhYmVsSXRlbXMgPSB0aGlzLl9jb21wdXRlTGFiZWxJdGVtcyhjaGFydEFyZWEpKTtcbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICAvLyBXaGVuIGEgbmV3IGxheW91dCBpcyBjcmVhdGVkLCByZXNldCB0aGUgZGF0YSBsaW1pdHMgY2FjaGVcbiAgYmVmb3JlTGF5b3V0KCkge1xuICAgIHRoaXMuX2NhY2hlID0ge307XG4gICAgdGhpcy5fZGF0YUxpbWl0c0NhY2hlZCA9IGZhbHNlO1xuICB9XG5cbiAgLy8gVGhlc2UgbWV0aG9kcyBhcmUgb3JkZXJlZCBieSBsaWZlY3ljbGUuIFV0aWxpdGllcyB0aGVuIGZvbGxvdy5cbiAgLy8gQW55IGZ1bmN0aW9uIGRlZmluZWQgaGVyZSBpcyBpbmhlcml0ZWQgYnkgYWxsIHNjYWxlIHR5cGVzLlxuICAvLyBBbnkgZnVuY3Rpb24gY2FuIGJlIGV4dGVuZGVkIGJ5IHRoZSBzY2FsZSB0eXBlXG5cbiAgYmVmb3JlVXBkYXRlKCkge1xuICAgIGNhbGwodGhpcy5vcHRpb25zLmJlZm9yZVVwZGF0ZSwgW3RoaXNdKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gbWF4V2lkdGggLSB0aGUgbWF4IHdpZHRoIGluIHBpeGVsc1xuXHQgKiBAcGFyYW0ge251bWJlcn0gbWF4SGVpZ2h0IC0gdGhlIG1heCBoZWlnaHQgaW4gcGl4ZWxzXG5cdCAqIEBwYXJhbSB7e3RvcDogbnVtYmVyLCBsZWZ0OiBudW1iZXIsIGJvdHRvbTogbnVtYmVyLCByaWdodDogbnVtYmVyfX0gbWFyZ2lucyAtIHRoZSBzcGFjZSBiZXR3ZWVuIHRoZSBlZGdlIG9mIHRoZSBvdGhlciBzY2FsZXMgYW5kIGVkZ2Ugb2YgdGhlIGNoYXJ0XG5cdCAqICAgVGhpcyBzcGFjZSBjb21lcyBmcm9tIHR3byBzb3VyY2VzOlxuXHQgKiAgICAgLSBwYWRkaW5nIC0gc3BhY2UgdGhhdCdzIHJlcXVpcmVkIHRvIHNob3cgdGhlIGxhYmVscyBhdCB0aGUgZWRnZXMgb2YgdGhlIHNjYWxlXG5cdCAqICAgICAtIHRoaWNrbmVzcyBvZiBzY2FsZXMgb3IgbGVnZW5kcyBpbiBhbm90aGVyIG9yaWVudGF0aW9uXG5cdCAqL1xuICB1cGRhdGUobWF4V2lkdGgsIG1heEhlaWdodCwgbWFyZ2lucykge1xuICAgIGNvbnN0IHtiZWdpbkF0WmVybywgZ3JhY2UsIHRpY2tzOiB0aWNrT3B0c30gPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3Qgc2FtcGxlU2l6ZSA9IHRpY2tPcHRzLnNhbXBsZVNpemU7XG5cbiAgICAvLyBVcGRhdGUgTGlmZWN5Y2xlIC0gUHJvYmFibHkgZG9uJ3Qgd2FudCB0byBldmVyIGV4dGVuZCBvciBvdmVyd3JpdGUgdGhpcyBmdW5jdGlvbiA7KVxuICAgIHRoaXMuYmVmb3JlVXBkYXRlKCk7XG5cbiAgICAvLyBBYnNvcmIgdGhlIG1hc3RlciBtZWFzdXJlbWVudHNcbiAgICB0aGlzLm1heFdpZHRoID0gbWF4V2lkdGg7XG4gICAgdGhpcy5tYXhIZWlnaHQgPSBtYXhIZWlnaHQ7XG4gICAgdGhpcy5fbWFyZ2lucyA9IG1hcmdpbnMgPSBPYmplY3QuYXNzaWduKHtcbiAgICAgIGxlZnQ6IDAsXG4gICAgICByaWdodDogMCxcbiAgICAgIHRvcDogMCxcbiAgICAgIGJvdHRvbTogMFxuICAgIH0sIG1hcmdpbnMpO1xuXG4gICAgdGhpcy50aWNrcyA9IG51bGw7XG4gICAgdGhpcy5fbGFiZWxTaXplcyA9IG51bGw7XG4gICAgdGhpcy5fZ3JpZExpbmVJdGVtcyA9IG51bGw7XG4gICAgdGhpcy5fbGFiZWxJdGVtcyA9IG51bGw7XG5cbiAgICAvLyBEaW1lbnNpb25zXG4gICAgdGhpcy5iZWZvcmVTZXREaW1lbnNpb25zKCk7XG4gICAgdGhpcy5zZXREaW1lbnNpb25zKCk7XG4gICAgdGhpcy5hZnRlclNldERpbWVuc2lvbnMoKTtcblxuICAgIHRoaXMuX21heExlbmd0aCA9IHRoaXMuaXNIb3Jpem9udGFsKClcbiAgICAgID8gdGhpcy53aWR0aCArIG1hcmdpbnMubGVmdCArIG1hcmdpbnMucmlnaHRcbiAgICAgIDogdGhpcy5oZWlnaHQgKyBtYXJnaW5zLnRvcCArIG1hcmdpbnMuYm90dG9tO1xuXG4gICAgLy8gRGF0YSBtaW4vbWF4XG4gICAgaWYgKCF0aGlzLl9kYXRhTGltaXRzQ2FjaGVkKSB7XG4gICAgICB0aGlzLmJlZm9yZURhdGFMaW1pdHMoKTtcbiAgICAgIHRoaXMuZGV0ZXJtaW5lRGF0YUxpbWl0cygpO1xuICAgICAgdGhpcy5hZnRlckRhdGFMaW1pdHMoKTtcbiAgICAgIHRoaXMuX3JhbmdlID0gX2FkZEdyYWNlKHRoaXMsIGdyYWNlLCBiZWdpbkF0WmVybyk7XG4gICAgICB0aGlzLl9kYXRhTGltaXRzQ2FjaGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLmJlZm9yZUJ1aWxkVGlja3MoKTtcblxuICAgIHRoaXMudGlja3MgPSB0aGlzLmJ1aWxkVGlja3MoKSB8fCBbXTtcblxuICAgIC8vIEFsbG93IG1vZGlmaWNhdGlvbiBvZiB0aWNrcyBpbiBjYWxsYmFjay5cbiAgICB0aGlzLmFmdGVyQnVpbGRUaWNrcygpO1xuXG4gICAgLy8gQ29tcHV0ZSB0aWNrIHJvdGF0aW9uIGFuZCBmaXQgdXNpbmcgYSBzYW1wbGVkIHN1YnNldCBvZiBsYWJlbHNcbiAgICAvLyBXZSBnZW5lcmFsbHkgZG9uJ3QgbmVlZCB0byBjb21wdXRlIHRoZSBzaXplIG9mIGV2ZXJ5IHNpbmdsZSBsYWJlbCBmb3IgZGV0ZXJtaW5pbmcgc2NhbGUgc2l6ZVxuICAgIGNvbnN0IHNhbXBsaW5nRW5hYmxlZCA9IHNhbXBsZVNpemUgPCB0aGlzLnRpY2tzLmxlbmd0aDtcbiAgICB0aGlzLl9jb252ZXJ0VGlja3NUb0xhYmVscyhzYW1wbGluZ0VuYWJsZWQgPyBzYW1wbGUodGhpcy50aWNrcywgc2FtcGxlU2l6ZSkgOiB0aGlzLnRpY2tzKTtcblxuICAgIC8vIGNvbmZpZ3VyZSBpcyBjYWxsZWQgdHdpY2UsIG9uY2UgaGVyZSwgb25jZSBmcm9tIGNvcmUuY29udHJvbGxlci51cGRhdGVMYXlvdXQuXG4gICAgLy8gSGVyZSB3ZSBoYXZlbid0IGJlZW4gcG9zaXRpb25lZCB5ZXQsIGJ1dCBkaW1lbnNpb25zIGFyZSBjb3JyZWN0LlxuICAgIC8vIFZhcmlhYmxlcyBzZXQgaW4gY29uZmlndXJlIGFyZSBuZWVkZWQgZm9yIGNhbGN1bGF0ZUxhYmVsUm90YXRpb24sIGFuZFxuICAgIC8vIGl0J3Mgb2sgdGhhdCBjb29yZGluYXRlcyBhcmUgbm90IGNvcnJlY3QgdGhlcmUsIG9ubHkgZGltZW5zaW9ucyBtYXR0ZXIuXG4gICAgdGhpcy5jb25maWd1cmUoKTtcblxuICAgIC8vIFRpY2sgUm90YXRpb25cbiAgICB0aGlzLmJlZm9yZUNhbGN1bGF0ZUxhYmVsUm90YXRpb24oKTtcbiAgICB0aGlzLmNhbGN1bGF0ZUxhYmVsUm90YXRpb24oKTsgLy8gUHJlY29uZGl0aW9uczogbnVtYmVyIG9mIHRpY2tzIGFuZCBzaXplcyBvZiBsYXJnZXN0IGxhYmVscyBtdXN0IGJlIGNhbGN1bGF0ZWQgYmVmb3JlaGFuZFxuICAgIHRoaXMuYWZ0ZXJDYWxjdWxhdGVMYWJlbFJvdGF0aW9uKCk7XG5cbiAgICAvLyBBdXRvLXNraXBcbiAgICBpZiAodGlja09wdHMuZGlzcGxheSAmJiAodGlja09wdHMuYXV0b1NraXAgfHwgdGlja09wdHMuc291cmNlID09PSAnYXV0bycpKSB7XG4gICAgICB0aGlzLnRpY2tzID0gYXV0b1NraXAodGhpcywgdGhpcy50aWNrcyk7XG4gICAgICB0aGlzLl9sYWJlbFNpemVzID0gbnVsbDtcbiAgICAgIHRoaXMuYWZ0ZXJBdXRvU2tpcCgpO1xuICAgIH1cblxuICAgIGlmIChzYW1wbGluZ0VuYWJsZWQpIHtcbiAgICAgIC8vIEdlbmVyYXRlIGxhYmVscyB1c2luZyBhbGwgbm9uLXNraXBwZWQgdGlja3NcbiAgICAgIHRoaXMuX2NvbnZlcnRUaWNrc1RvTGFiZWxzKHRoaXMudGlja3MpO1xuICAgIH1cblxuICAgIHRoaXMuYmVmb3JlRml0KCk7XG4gICAgdGhpcy5maXQoKTsgLy8gUHJlY29uZGl0aW9uczogbGFiZWwgcm90YXRpb24gYW5kIGxhYmVsIHNpemVzIG11c3QgYmUgY2FsY3VsYXRlZCBiZWZvcmVoYW5kXG4gICAgdGhpcy5hZnRlckZpdCgpO1xuXG4gICAgLy8gSU1QT1JUQU5UOiBhZnRlciB0aGlzIHBvaW50LCB3ZSBjb25zaWRlciB0aGF0IGB0aGlzLnRpY2tzYCB3aWxsIE5FVkVSIGNoYW5nZSFcblxuICAgIHRoaXMuYWZ0ZXJVcGRhdGUoKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBjb25maWd1cmUoKSB7XG4gICAgbGV0IHJldmVyc2VQaXhlbHMgPSB0aGlzLm9wdGlvbnMucmV2ZXJzZTtcbiAgICBsZXQgc3RhcnRQaXhlbCwgZW5kUGl4ZWw7XG5cbiAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgc3RhcnRQaXhlbCA9IHRoaXMubGVmdDtcbiAgICAgIGVuZFBpeGVsID0gdGhpcy5yaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhcnRQaXhlbCA9IHRoaXMudG9wO1xuICAgICAgZW5kUGl4ZWwgPSB0aGlzLmJvdHRvbTtcbiAgICAgIC8vIGJ5IGRlZmF1bHQgdmVydGljYWwgc2NhbGVzIGFyZSBmcm9tIGJvdHRvbSB0byB0b3AsIHNvIHBpeGVscyBhcmUgcmV2ZXJzZWRcbiAgICAgIHJldmVyc2VQaXhlbHMgPSAhcmV2ZXJzZVBpeGVscztcbiAgICB9XG4gICAgdGhpcy5fc3RhcnRQaXhlbCA9IHN0YXJ0UGl4ZWw7XG4gICAgdGhpcy5fZW5kUGl4ZWwgPSBlbmRQaXhlbDtcbiAgICB0aGlzLl9yZXZlcnNlUGl4ZWxzID0gcmV2ZXJzZVBpeGVscztcbiAgICB0aGlzLl9sZW5ndGggPSBlbmRQaXhlbCAtIHN0YXJ0UGl4ZWw7XG4gICAgdGhpcy5fYWxpZ25Ub1BpeGVscyA9IHRoaXMub3B0aW9ucy5hbGlnblRvUGl4ZWxzO1xuICB9XG5cbiAgYWZ0ZXJVcGRhdGUoKSB7XG4gICAgY2FsbCh0aGlzLm9wdGlvbnMuYWZ0ZXJVcGRhdGUsIFt0aGlzXSk7XG4gIH1cblxuICAvL1xuXG4gIGJlZm9yZVNldERpbWVuc2lvbnMoKSB7XG4gICAgY2FsbCh0aGlzLm9wdGlvbnMuYmVmb3JlU2V0RGltZW5zaW9ucywgW3RoaXNdKTtcbiAgfVxuICBzZXREaW1lbnNpb25zKCkge1xuICAgIC8vIFNldCB0aGUgdW5jb25zdHJhaW5lZCBkaW1lbnNpb24gYmVmb3JlIGxhYmVsIHJvdGF0aW9uXG4gICAgaWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgIC8vIFJlc2V0IHBvc2l0aW9uIGJlZm9yZSBjYWxjdWxhdGluZyByb3RhdGlvblxuICAgICAgdGhpcy53aWR0aCA9IHRoaXMubWF4V2lkdGg7XG4gICAgICB0aGlzLmxlZnQgPSAwO1xuICAgICAgdGhpcy5yaWdodCA9IHRoaXMud2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5tYXhIZWlnaHQ7XG5cbiAgICAgIC8vIFJlc2V0IHBvc2l0aW9uIGJlZm9yZSBjYWxjdWxhdGluZyByb3RhdGlvblxuICAgICAgdGhpcy50b3AgPSAwO1xuICAgICAgdGhpcy5ib3R0b20gPSB0aGlzLmhlaWdodDtcbiAgICB9XG5cbiAgICAvLyBSZXNldCBwYWRkaW5nXG4gICAgdGhpcy5wYWRkaW5nTGVmdCA9IDA7XG4gICAgdGhpcy5wYWRkaW5nVG9wID0gMDtcbiAgICB0aGlzLnBhZGRpbmdSaWdodCA9IDA7XG4gICAgdGhpcy5wYWRkaW5nQm90dG9tID0gMDtcbiAgfVxuICBhZnRlclNldERpbWVuc2lvbnMoKSB7XG4gICAgY2FsbCh0aGlzLm9wdGlvbnMuYWZ0ZXJTZXREaW1lbnNpb25zLCBbdGhpc10pO1xuICB9XG5cbiAgX2NhbGxIb29rcyhuYW1lKSB7XG4gICAgdGhpcy5jaGFydC5ub3RpZnlQbHVnaW5zKG5hbWUsIHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICBjYWxsKHRoaXMub3B0aW9uc1tuYW1lXSwgW3RoaXNdKTtcbiAgfVxuXG4gIC8vIERhdGEgbGltaXRzXG4gIGJlZm9yZURhdGFMaW1pdHMoKSB7XG4gICAgdGhpcy5fY2FsbEhvb2tzKCdiZWZvcmVEYXRhTGltaXRzJyk7XG4gIH1cbiAgZGV0ZXJtaW5lRGF0YUxpbWl0cygpIHt9XG4gIGFmdGVyRGF0YUxpbWl0cygpIHtcbiAgICB0aGlzLl9jYWxsSG9va3MoJ2FmdGVyRGF0YUxpbWl0cycpO1xuICB9XG5cbiAgLy9cbiAgYmVmb3JlQnVpbGRUaWNrcygpIHtcbiAgICB0aGlzLl9jYWxsSG9va3MoJ2JlZm9yZUJ1aWxkVGlja3MnKTtcbiAgfVxuICAvKipcblx0ICogQHJldHVybiB7b2JqZWN0W119IHRoZSB0aWNrc1xuXHQgKi9cbiAgYnVpbGRUaWNrcygpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgYWZ0ZXJCdWlsZFRpY2tzKCkge1xuICAgIHRoaXMuX2NhbGxIb29rcygnYWZ0ZXJCdWlsZFRpY2tzJyk7XG4gIH1cblxuICBiZWZvcmVUaWNrVG9MYWJlbENvbnZlcnNpb24oKSB7XG4gICAgY2FsbCh0aGlzLm9wdGlvbnMuYmVmb3JlVGlja1RvTGFiZWxDb252ZXJzaW9uLCBbdGhpc10pO1xuICB9XG4gIC8qKlxuXHQgKiBDb252ZXJ0IHRpY2tzIHRvIGxhYmVsIHN0cmluZ3Ncblx0ICogQHBhcmFtIHtUaWNrW119IHRpY2tzXG5cdCAqL1xuICBnZW5lcmF0ZVRpY2tMYWJlbHModGlja3MpIHtcbiAgICBjb25zdCB0aWNrT3B0cyA9IHRoaXMub3B0aW9ucy50aWNrcztcbiAgICBsZXQgaSwgaWxlbiwgdGljaztcbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gdGlja3MubGVuZ3RoOyBpIDwgaWxlbjsgaSsrKSB7XG4gICAgICB0aWNrID0gdGlja3NbaV07XG4gICAgICB0aWNrLmxhYmVsID0gY2FsbCh0aWNrT3B0cy5jYWxsYmFjaywgW3RpY2sudmFsdWUsIGksIHRpY2tzXSwgdGhpcyk7XG4gICAgfVxuICB9XG4gIGFmdGVyVGlja1RvTGFiZWxDb252ZXJzaW9uKCkge1xuICAgIGNhbGwodGhpcy5vcHRpb25zLmFmdGVyVGlja1RvTGFiZWxDb252ZXJzaW9uLCBbdGhpc10pO1xuICB9XG5cbiAgLy9cblxuICBiZWZvcmVDYWxjdWxhdGVMYWJlbFJvdGF0aW9uKCkge1xuICAgIGNhbGwodGhpcy5vcHRpb25zLmJlZm9yZUNhbGN1bGF0ZUxhYmVsUm90YXRpb24sIFt0aGlzXSk7XG4gIH1cbiAgY2FsY3VsYXRlTGFiZWxSb3RhdGlvbigpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHRpY2tPcHRzID0gb3B0aW9ucy50aWNrcztcbiAgICBjb25zdCBudW1UaWNrcyA9IGdldFRpY2tzTGltaXQodGhpcy50aWNrcy5sZW5ndGgsIG9wdGlvbnMudGlja3MubWF4VGlja3NMaW1pdCk7XG4gICAgY29uc3QgbWluUm90YXRpb24gPSB0aWNrT3B0cy5taW5Sb3RhdGlvbiB8fCAwO1xuICAgIGNvbnN0IG1heFJvdGF0aW9uID0gdGlja09wdHMubWF4Um90YXRpb247XG4gICAgbGV0IGxhYmVsUm90YXRpb24gPSBtaW5Sb3RhdGlvbjtcbiAgICBsZXQgdGlja1dpZHRoLCBtYXhIZWlnaHQsIG1heExhYmVsRGlhZ29uYWw7XG5cbiAgICBpZiAoIXRoaXMuX2lzVmlzaWJsZSgpIHx8ICF0aWNrT3B0cy5kaXNwbGF5IHx8IG1pblJvdGF0aW9uID49IG1heFJvdGF0aW9uIHx8IG51bVRpY2tzIDw9IDEgfHwgIXRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgIHRoaXMubGFiZWxSb3RhdGlvbiA9IG1pblJvdGF0aW9uO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGxhYmVsU2l6ZXMgPSB0aGlzLl9nZXRMYWJlbFNpemVzKCk7XG4gICAgY29uc3QgbWF4TGFiZWxXaWR0aCA9IGxhYmVsU2l6ZXMud2lkZXN0LndpZHRoO1xuICAgIGNvbnN0IG1heExhYmVsSGVpZ2h0ID0gbGFiZWxTaXplcy5oaWdoZXN0LmhlaWdodDtcblxuICAgIC8vIEVzdGltYXRlIHRoZSB3aWR0aCBvZiBlYWNoIGdyaWQgYmFzZWQgb24gdGhlIGNhbnZhcyB3aWR0aCwgdGhlIG1heGltdW1cbiAgICAvLyBsYWJlbCB3aWR0aCBhbmQgdGhlIG51bWJlciBvZiB0aWNrIGludGVydmFsc1xuICAgIGNvbnN0IG1heFdpZHRoID0gX2xpbWl0VmFsdWUodGhpcy5jaGFydC53aWR0aCAtIG1heExhYmVsV2lkdGgsIDAsIHRoaXMubWF4V2lkdGgpO1xuICAgIHRpY2tXaWR0aCA9IG9wdGlvbnMub2Zmc2V0ID8gdGhpcy5tYXhXaWR0aCAvIG51bVRpY2tzIDogbWF4V2lkdGggLyAobnVtVGlja3MgLSAxKTtcblxuICAgIC8vIEFsbG93IDMgcGl4ZWxzIHgyIHBhZGRpbmcgZWl0aGVyIHNpZGUgZm9yIGxhYmVsIHJlYWRhYmlsaXR5XG4gICAgaWYgKG1heExhYmVsV2lkdGggKyA2ID4gdGlja1dpZHRoKSB7XG4gICAgICB0aWNrV2lkdGggPSBtYXhXaWR0aCAvIChudW1UaWNrcyAtIChvcHRpb25zLm9mZnNldCA/IDAuNSA6IDEpKTtcbiAgICAgIG1heEhlaWdodCA9IHRoaXMubWF4SGVpZ2h0IC0gZ2V0VGlja01hcmtMZW5ndGgob3B0aW9ucy5ncmlkKVxuXHRcdFx0XHQtIHRpY2tPcHRzLnBhZGRpbmcgLSBnZXRUaXRsZUhlaWdodChvcHRpb25zLnRpdGxlLCB0aGlzLmNoYXJ0Lm9wdGlvbnMuZm9udCk7XG4gICAgICBtYXhMYWJlbERpYWdvbmFsID0gTWF0aC5zcXJ0KG1heExhYmVsV2lkdGggKiBtYXhMYWJlbFdpZHRoICsgbWF4TGFiZWxIZWlnaHQgKiBtYXhMYWJlbEhlaWdodCk7XG4gICAgICBsYWJlbFJvdGF0aW9uID0gdG9EZWdyZWVzKE1hdGgubWluKFxuICAgICAgICBNYXRoLmFzaW4oX2xpbWl0VmFsdWUoKGxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQgKyA2KSAvIHRpY2tXaWR0aCwgLTEsIDEpKSxcbiAgICAgICAgTWF0aC5hc2luKF9saW1pdFZhbHVlKG1heEhlaWdodCAvIG1heExhYmVsRGlhZ29uYWwsIC0xLCAxKSkgLSBNYXRoLmFzaW4oX2xpbWl0VmFsdWUobWF4TGFiZWxIZWlnaHQgLyBtYXhMYWJlbERpYWdvbmFsLCAtMSwgMSkpXG4gICAgICApKTtcbiAgICAgIGxhYmVsUm90YXRpb24gPSBNYXRoLm1heChtaW5Sb3RhdGlvbiwgTWF0aC5taW4obWF4Um90YXRpb24sIGxhYmVsUm90YXRpb24pKTtcbiAgICB9XG5cbiAgICB0aGlzLmxhYmVsUm90YXRpb24gPSBsYWJlbFJvdGF0aW9uO1xuICB9XG4gIGFmdGVyQ2FsY3VsYXRlTGFiZWxSb3RhdGlvbigpIHtcbiAgICBjYWxsKHRoaXMub3B0aW9ucy5hZnRlckNhbGN1bGF0ZUxhYmVsUm90YXRpb24sIFt0aGlzXSk7XG4gIH1cbiAgYWZ0ZXJBdXRvU2tpcCgpIHt9XG5cbiAgLy9cblxuICBiZWZvcmVGaXQoKSB7XG4gICAgY2FsbCh0aGlzLm9wdGlvbnMuYmVmb3JlRml0LCBbdGhpc10pO1xuICB9XG4gIGZpdCgpIHtcbiAgICAvLyBSZXNldFxuICAgIGNvbnN0IG1pblNpemUgPSB7XG4gICAgICB3aWR0aDogMCxcbiAgICAgIGhlaWdodDogMFxuICAgIH07XG5cbiAgICBjb25zdCB7Y2hhcnQsIG9wdGlvbnM6IHt0aWNrczogdGlja09wdHMsIHRpdGxlOiB0aXRsZU9wdHMsIGdyaWQ6IGdyaWRPcHRzfX0gPSB0aGlzO1xuICAgIGNvbnN0IGRpc3BsYXkgPSB0aGlzLl9pc1Zpc2libGUoKTtcbiAgICBjb25zdCBpc0hvcml6b250YWwgPSB0aGlzLmlzSG9yaXpvbnRhbCgpO1xuXG4gICAgaWYgKGRpc3BsYXkpIHtcbiAgICAgIGNvbnN0IHRpdGxlSGVpZ2h0ID0gZ2V0VGl0bGVIZWlnaHQodGl0bGVPcHRzLCBjaGFydC5vcHRpb25zLmZvbnQpO1xuICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICBtaW5TaXplLndpZHRoID0gdGhpcy5tYXhXaWR0aDtcbiAgICAgICAgbWluU2l6ZS5oZWlnaHQgPSBnZXRUaWNrTWFya0xlbmd0aChncmlkT3B0cykgKyB0aXRsZUhlaWdodDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1pblNpemUuaGVpZ2h0ID0gdGhpcy5tYXhIZWlnaHQ7IC8vIGZpbGwgYWxsIHRoZSBoZWlnaHRcbiAgICAgICAgbWluU2l6ZS53aWR0aCA9IGdldFRpY2tNYXJrTGVuZ3RoKGdyaWRPcHRzKSArIHRpdGxlSGVpZ2h0O1xuICAgICAgfVxuXG4gICAgICAvLyBEb24ndCBib3RoZXIgZml0dGluZyB0aGUgdGlja3MgaWYgd2UgYXJlIG5vdCBzaG93aW5nIHRoZSBsYWJlbHNcbiAgICAgIGlmICh0aWNrT3B0cy5kaXNwbGF5ICYmIHRoaXMudGlja3MubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHtmaXJzdCwgbGFzdCwgd2lkZXN0LCBoaWdoZXN0fSA9IHRoaXMuX2dldExhYmVsU2l6ZXMoKTtcbiAgICAgICAgY29uc3QgdGlja1BhZGRpbmcgPSB0aWNrT3B0cy5wYWRkaW5nICogMjtcbiAgICAgICAgY29uc3QgYW5nbGVSYWRpYW5zID0gdG9SYWRpYW5zKHRoaXMubGFiZWxSb3RhdGlvbik7XG4gICAgICAgIGNvbnN0IGNvcyA9IE1hdGguY29zKGFuZ2xlUmFkaWFucyk7XG4gICAgICAgIGNvbnN0IHNpbiA9IE1hdGguc2luKGFuZ2xlUmFkaWFucyk7XG5cbiAgICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICAvLyBBIGhvcml6b250YWwgYXhpcyBpcyBtb3JlIGNvbnN0cmFpbmVkIGJ5IHRoZSBoZWlnaHQuXG4gICAgICAgICAgY29uc3QgbGFiZWxIZWlnaHQgPSB0aWNrT3B0cy5taXJyb3IgPyAwIDogc2luICogd2lkZXN0LndpZHRoICsgY29zICogaGlnaGVzdC5oZWlnaHQ7XG4gICAgICAgICAgbWluU2l6ZS5oZWlnaHQgPSBNYXRoLm1pbih0aGlzLm1heEhlaWdodCwgbWluU2l6ZS5oZWlnaHQgKyBsYWJlbEhlaWdodCArIHRpY2tQYWRkaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQSB2ZXJ0aWNhbCBheGlzIGlzIG1vcmUgY29uc3RyYWluZWQgYnkgdGhlIHdpZHRoLiBMYWJlbHMgYXJlIHRoZVxuICAgICAgICAvLyBkb21pbmFudCBmYWN0b3IgaGVyZSwgc28gZ2V0IHRoYXQgbGVuZ3RoIGZpcnN0IGFuZCBhY2NvdW50IGZvciBwYWRkaW5nXG4gICAgICAgICAgY29uc3QgbGFiZWxXaWR0aCA9IHRpY2tPcHRzLm1pcnJvciA/IDAgOiBjb3MgKiB3aWRlc3Qud2lkdGggKyBzaW4gKiBoaWdoZXN0LmhlaWdodDtcblxuICAgICAgICAgIG1pblNpemUud2lkdGggPSBNYXRoLm1pbih0aGlzLm1heFdpZHRoLCBtaW5TaXplLndpZHRoICsgbGFiZWxXaWR0aCArIHRpY2tQYWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9jYWxjdWxhdGVQYWRkaW5nKGZpcnN0LCBsYXN0LCBzaW4sIGNvcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5faGFuZGxlTWFyZ2lucygpO1xuXG4gICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgdGhpcy53aWR0aCA9IHRoaXMuX2xlbmd0aCA9IGNoYXJ0LndpZHRoIC0gdGhpcy5fbWFyZ2lucy5sZWZ0IC0gdGhpcy5fbWFyZ2lucy5yaWdodDtcbiAgICAgIHRoaXMuaGVpZ2h0ID0gbWluU2l6ZS5oZWlnaHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMud2lkdGggPSBtaW5TaXplLndpZHRoO1xuICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLl9sZW5ndGggPSBjaGFydC5oZWlnaHQgLSB0aGlzLl9tYXJnaW5zLnRvcCAtIHRoaXMuX21hcmdpbnMuYm90dG9tO1xuICAgIH1cbiAgfVxuXG4gIF9jYWxjdWxhdGVQYWRkaW5nKGZpcnN0LCBsYXN0LCBzaW4sIGNvcykge1xuICAgIGNvbnN0IHt0aWNrczoge2FsaWduLCBwYWRkaW5nfSwgcG9zaXRpb259ID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IGlzUm90YXRlZCA9IHRoaXMubGFiZWxSb3RhdGlvbiAhPT0gMDtcbiAgICBjb25zdCBsYWJlbHNCZWxvd1RpY2tzID0gcG9zaXRpb24gIT09ICd0b3AnICYmIHRoaXMuYXhpcyA9PT0gJ3gnO1xuXG4gICAgaWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgIGNvbnN0IG9mZnNldExlZnQgPSB0aGlzLmdldFBpeGVsRm9yVGljaygwKSAtIHRoaXMubGVmdDtcbiAgICAgIGNvbnN0IG9mZnNldFJpZ2h0ID0gdGhpcy5yaWdodCAtIHRoaXMuZ2V0UGl4ZWxGb3JUaWNrKHRoaXMudGlja3MubGVuZ3RoIC0gMSk7XG4gICAgICBsZXQgcGFkZGluZ0xlZnQgPSAwO1xuICAgICAgbGV0IHBhZGRpbmdSaWdodCA9IDA7XG5cbiAgICAgIC8vIEVuc3VyZSB0aGF0IG91ciB0aWNrcyBhcmUgYWx3YXlzIGluc2lkZSB0aGUgY2FudmFzLiBXaGVuIHJvdGF0ZWQsIHRpY2tzIGFyZSByaWdodCBhbGlnbmVkXG4gICAgICAvLyB3aGljaCBtZWFucyB0aGF0IHRoZSByaWdodCBwYWRkaW5nIGlzIGRvbWluYXRlZCBieSB0aGUgZm9udCBoZWlnaHRcbiAgICAgIGlmIChpc1JvdGF0ZWQpIHtcbiAgICAgICAgaWYgKGxhYmVsc0JlbG93VGlja3MpIHtcbiAgICAgICAgICBwYWRkaW5nTGVmdCA9IGNvcyAqIGZpcnN0LndpZHRoO1xuICAgICAgICAgIHBhZGRpbmdSaWdodCA9IHNpbiAqIGxhc3QuaGVpZ2h0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhZGRpbmdMZWZ0ID0gc2luICogZmlyc3QuaGVpZ2h0O1xuICAgICAgICAgIHBhZGRpbmdSaWdodCA9IGNvcyAqIGxhc3Qud2lkdGg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoYWxpZ24gPT09ICdzdGFydCcpIHtcbiAgICAgICAgcGFkZGluZ1JpZ2h0ID0gbGFzdC53aWR0aDtcbiAgICAgIH0gZWxzZSBpZiAoYWxpZ24gPT09ICdlbmQnKSB7XG4gICAgICAgIHBhZGRpbmdMZWZ0ID0gZmlyc3Qud2lkdGg7XG4gICAgICB9IGVsc2UgaWYgKGFsaWduICE9PSAnaW5uZXInKSB7XG4gICAgICAgIHBhZGRpbmdMZWZ0ID0gZmlyc3Qud2lkdGggLyAyO1xuICAgICAgICBwYWRkaW5nUmlnaHQgPSBsYXN0LndpZHRoIC8gMjtcbiAgICAgIH1cblxuICAgICAgLy8gQWRqdXN0IHBhZGRpbmcgdGFraW5nIGludG8gYWNjb3VudCBjaGFuZ2VzIGluIG9mZnNldHNcbiAgICAgIHRoaXMucGFkZGluZ0xlZnQgPSBNYXRoLm1heCgocGFkZGluZ0xlZnQgLSBvZmZzZXRMZWZ0ICsgcGFkZGluZykgKiB0aGlzLndpZHRoIC8gKHRoaXMud2lkdGggLSBvZmZzZXRMZWZ0KSwgMCk7XG4gICAgICB0aGlzLnBhZGRpbmdSaWdodCA9IE1hdGgubWF4KChwYWRkaW5nUmlnaHQgLSBvZmZzZXRSaWdodCArIHBhZGRpbmcpICogdGhpcy53aWR0aCAvICh0aGlzLndpZHRoIC0gb2Zmc2V0UmlnaHQpLCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHBhZGRpbmdUb3AgPSBsYXN0LmhlaWdodCAvIDI7XG4gICAgICBsZXQgcGFkZGluZ0JvdHRvbSA9IGZpcnN0LmhlaWdodCAvIDI7XG5cbiAgICAgIGlmIChhbGlnbiA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICBwYWRkaW5nVG9wID0gMDtcbiAgICAgICAgcGFkZGluZ0JvdHRvbSA9IGZpcnN0LmhlaWdodDtcbiAgICAgIH0gZWxzZSBpZiAoYWxpZ24gPT09ICdlbmQnKSB7XG4gICAgICAgIHBhZGRpbmdUb3AgPSBsYXN0LmhlaWdodDtcbiAgICAgICAgcGFkZGluZ0JvdHRvbSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMucGFkZGluZ1RvcCA9IHBhZGRpbmdUb3AgKyBwYWRkaW5nO1xuICAgICAgdGhpcy5wYWRkaW5nQm90dG9tID0gcGFkZGluZ0JvdHRvbSArIHBhZGRpbmc7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEhhbmRsZSBtYXJnaW5zIGFuZCBwYWRkaW5nIGludGVyYWN0aW9uc1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2hhbmRsZU1hcmdpbnMoKSB7XG4gICAgaWYgKHRoaXMuX21hcmdpbnMpIHtcbiAgICAgIHRoaXMuX21hcmdpbnMubGVmdCA9IE1hdGgubWF4KHRoaXMucGFkZGluZ0xlZnQsIHRoaXMuX21hcmdpbnMubGVmdCk7XG4gICAgICB0aGlzLl9tYXJnaW5zLnRvcCA9IE1hdGgubWF4KHRoaXMucGFkZGluZ1RvcCwgdGhpcy5fbWFyZ2lucy50b3ApO1xuICAgICAgdGhpcy5fbWFyZ2lucy5yaWdodCA9IE1hdGgubWF4KHRoaXMucGFkZGluZ1JpZ2h0LCB0aGlzLl9tYXJnaW5zLnJpZ2h0KTtcbiAgICAgIHRoaXMuX21hcmdpbnMuYm90dG9tID0gTWF0aC5tYXgodGhpcy5wYWRkaW5nQm90dG9tLCB0aGlzLl9tYXJnaW5zLmJvdHRvbSk7XG4gICAgfVxuICB9XG5cbiAgYWZ0ZXJGaXQoKSB7XG4gICAgY2FsbCh0aGlzLm9wdGlvbnMuYWZ0ZXJGaXQsIFt0aGlzXSk7XG4gIH1cblxuICAvLyBTaGFyZWQgTWV0aG9kc1xuICAvKipcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG4gIGlzSG9yaXpvbnRhbCgpIHtcbiAgICBjb25zdCB7YXhpcywgcG9zaXRpb259ID0gdGhpcy5vcHRpb25zO1xuICAgIHJldHVybiBwb3NpdGlvbiA9PT0gJ3RvcCcgfHwgcG9zaXRpb24gPT09ICdib3R0b20nIHx8IGF4aXMgPT09ICd4JztcbiAgfVxuICAvKipcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICovXG4gIGlzRnVsbFNpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5mdWxsU2l6ZTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge1RpY2tbXX0gdGlja3Ncblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9jb252ZXJ0VGlja3NUb0xhYmVscyh0aWNrcykge1xuICAgIHRoaXMuYmVmb3JlVGlja1RvTGFiZWxDb252ZXJzaW9uKCk7XG5cbiAgICB0aGlzLmdlbmVyYXRlVGlja0xhYmVscyh0aWNrcyk7XG5cbiAgICAvLyBUaWNrcyBzaG91bGQgYmUgc2tpcHBlZCB3aGVuIGNhbGxiYWNrIHJldHVybnMgbnVsbCBvciB1bmRlZiwgc28gbGV0cyByZW1vdmUgdGhvc2UuXG4gICAgbGV0IGksIGlsZW47XG4gICAgZm9yIChpID0gMCwgaWxlbiA9IHRpY2tzLmxlbmd0aDsgaSA8IGlsZW47IGkrKykge1xuICAgICAgaWYgKGlzTnVsbE9yVW5kZWYodGlja3NbaV0ubGFiZWwpKSB7XG4gICAgICAgIHRpY2tzLnNwbGljZShpLCAxKTtcbiAgICAgICAgaWxlbi0tO1xuICAgICAgICBpLS07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5hZnRlclRpY2tUb0xhYmVsQ29udmVyc2lvbigpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEByZXR1cm4ge3sgZmlyc3Q6IG9iamVjdCwgbGFzdDogb2JqZWN0LCB3aWRlc3Q6IG9iamVjdCwgaGlnaGVzdDogb2JqZWN0LCB3aWR0aHM6IEFycmF5LCBoZWlnaHRzOiBhcnJheSB9fVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldExhYmVsU2l6ZXMoKSB7XG4gICAgbGV0IGxhYmVsU2l6ZXMgPSB0aGlzLl9sYWJlbFNpemVzO1xuXG4gICAgaWYgKCFsYWJlbFNpemVzKSB7XG4gICAgICBjb25zdCBzYW1wbGVTaXplID0gdGhpcy5vcHRpb25zLnRpY2tzLnNhbXBsZVNpemU7XG4gICAgICBsZXQgdGlja3MgPSB0aGlzLnRpY2tzO1xuICAgICAgaWYgKHNhbXBsZVNpemUgPCB0aWNrcy5sZW5ndGgpIHtcbiAgICAgICAgdGlja3MgPSBzYW1wbGUodGlja3MsIHNhbXBsZVNpemUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9sYWJlbFNpemVzID0gbGFiZWxTaXplcyA9IHRoaXMuX2NvbXB1dGVMYWJlbFNpemVzKHRpY2tzLCB0aWNrcy5sZW5ndGgsIHRoaXMub3B0aW9ucy50aWNrcy5tYXhUaWNrc0xpbWl0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGFiZWxTaXplcztcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHt3aWR0aCwgaGVpZ2h0LCBvZmZzZXR9IG9iamVjdHMgZm9yIHRoZSBmaXJzdCwgbGFzdCwgd2lkZXN0LCBoaWdoZXN0IHRpY2tcblx0ICogbGFiZWxzIHdoZXJlIG9mZnNldCBpbmRpY2F0ZXMgdGhlIGFuY2hvciBwb2ludCBvZmZzZXQgZnJvbSB0aGUgdG9wIGluIHBpeGVscy5cblx0ICogQHJldHVybiB7eyBmaXJzdDogb2JqZWN0LCBsYXN0OiBvYmplY3QsIHdpZGVzdDogb2JqZWN0LCBoaWdoZXN0OiBvYmplY3QsIHdpZHRoczogQXJyYXksIGhlaWdodHM6IGFycmF5IH19XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfY29tcHV0ZUxhYmVsU2l6ZXModGlja3MsIGxlbmd0aCwgbWF4VGlja3NMaW1pdCkge1xuICAgIGNvbnN0IHtjdHgsIF9sb25nZXN0VGV4dENhY2hlOiBjYWNoZXN9ID0gdGhpcztcbiAgICBjb25zdCB3aWR0aHMgPSBbXTtcbiAgICBjb25zdCBoZWlnaHRzID0gW107XG4gICAgY29uc3QgaW5jcmVtZW50ID0gTWF0aC5mbG9vcihsZW5ndGggLyBnZXRUaWNrc0xpbWl0KGxlbmd0aCwgbWF4VGlja3NMaW1pdCkpO1xuICAgIGxldCB3aWRlc3RMYWJlbFNpemUgPSAwO1xuICAgIGxldCBoaWdoZXN0TGFiZWxTaXplID0gMDtcbiAgICBsZXQgaSwgaiwgamxlbiwgbGFiZWwsIHRpY2tGb250LCBmb250U3RyaW5nLCBjYWNoZSwgbGluZUhlaWdodCwgd2lkdGgsIGhlaWdodCwgbmVzdGVkTGFiZWw7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IGluY3JlbWVudCkge1xuICAgICAgbGFiZWwgPSB0aWNrc1tpXS5sYWJlbDtcbiAgICAgIHRpY2tGb250ID0gdGhpcy5fcmVzb2x2ZVRpY2tGb250T3B0aW9ucyhpKTtcbiAgICAgIGN0eC5mb250ID0gZm9udFN0cmluZyA9IHRpY2tGb250LnN0cmluZztcbiAgICAgIGNhY2hlID0gY2FjaGVzW2ZvbnRTdHJpbmddID0gY2FjaGVzW2ZvbnRTdHJpbmddIHx8IHtkYXRhOiB7fSwgZ2M6IFtdfTtcbiAgICAgIGxpbmVIZWlnaHQgPSB0aWNrRm9udC5saW5lSGVpZ2h0O1xuICAgICAgd2lkdGggPSBoZWlnaHQgPSAwO1xuICAgICAgLy8gVW5kZWZpbmVkIGxhYmVscyBhbmQgYXJyYXlzIHNob3VsZCBub3QgYmUgbWVhc3VyZWRcbiAgICAgIGlmICghaXNOdWxsT3JVbmRlZihsYWJlbCkgJiYgIWlzQXJyYXkobGFiZWwpKSB7XG4gICAgICAgIHdpZHRoID0gX21lYXN1cmVUZXh0KGN0eCwgY2FjaGUuZGF0YSwgY2FjaGUuZ2MsIHdpZHRoLCBsYWJlbCk7XG4gICAgICAgIGhlaWdodCA9IGxpbmVIZWlnaHQ7XG4gICAgICB9IGVsc2UgaWYgKGlzQXJyYXkobGFiZWwpKSB7XG4gICAgICAgIC8vIGlmIGl0IGlzIGFuIGFycmF5IGxldCdzIG1lYXN1cmUgZWFjaCBlbGVtZW50XG4gICAgICAgIGZvciAoaiA9IDAsIGpsZW4gPSBsYWJlbC5sZW5ndGg7IGogPCBqbGVuOyArK2opIHtcbiAgICAgICAgICBuZXN0ZWRMYWJlbCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobGFiZWxbal0pO1xuICAgICAgICAgIC8vIFVuZGVmaW5lZCBsYWJlbHMgYW5kIGFycmF5cyBzaG91bGQgbm90IGJlIG1lYXN1cmVkXG4gICAgICAgICAgaWYgKCFpc051bGxPclVuZGVmKG5lc3RlZExhYmVsKSAmJiAhaXNBcnJheShuZXN0ZWRMYWJlbCkpIHtcbiAgICAgICAgICAgIHdpZHRoID0gX21lYXN1cmVUZXh0KGN0eCwgY2FjaGUuZGF0YSwgY2FjaGUuZ2MsIHdpZHRoLCBuZXN0ZWRMYWJlbCk7XG4gICAgICAgICAgICBoZWlnaHQgKz0gbGluZUhlaWdodDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHdpZHRocy5wdXNoKHdpZHRoKTtcbiAgICAgIGhlaWdodHMucHVzaChoZWlnaHQpO1xuICAgICAgd2lkZXN0TGFiZWxTaXplID0gTWF0aC5tYXgod2lkdGgsIHdpZGVzdExhYmVsU2l6ZSk7XG4gICAgICBoaWdoZXN0TGFiZWxTaXplID0gTWF0aC5tYXgoaGVpZ2h0LCBoaWdoZXN0TGFiZWxTaXplKTtcbiAgICB9XG4gICAgZ2FyYmFnZUNvbGxlY3QoY2FjaGVzLCBsZW5ndGgpO1xuXG4gICAgY29uc3Qgd2lkZXN0ID0gd2lkdGhzLmluZGV4T2Yod2lkZXN0TGFiZWxTaXplKTtcbiAgICBjb25zdCBoaWdoZXN0ID0gaGVpZ2h0cy5pbmRleE9mKGhpZ2hlc3RMYWJlbFNpemUpO1xuXG4gICAgY29uc3QgdmFsdWVBdCA9IChpZHgpID0+ICh7d2lkdGg6IHdpZHRoc1tpZHhdIHx8IDAsIGhlaWdodDogaGVpZ2h0c1tpZHhdIHx8IDB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBmaXJzdDogdmFsdWVBdCgwKSxcbiAgICAgIGxhc3Q6IHZhbHVlQXQobGVuZ3RoIC0gMSksXG4gICAgICB3aWRlc3Q6IHZhbHVlQXQod2lkZXN0KSxcbiAgICAgIGhpZ2hlc3Q6IHZhbHVlQXQoaGlnaGVzdCksXG4gICAgICB3aWR0aHMsXG4gICAgICBoZWlnaHRzLFxuICAgIH07XG4gIH1cblxuICAvKipcblx0ICogVXNlZCB0byBnZXQgdGhlIGxhYmVsIHRvIGRpc3BsYXkgaW4gdGhlIHRvb2x0aXAgZm9yIHRoZSBnaXZlbiB2YWx1ZVxuXHQgKiBAcGFyYW0geyp9IHZhbHVlXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG4gIGdldExhYmVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB0aGUgbG9jYXRpb24gb2YgdGhlIGdpdmVuIGRhdGEgcG9pbnQuIFZhbHVlIGNhbiBlaXRoZXIgYmUgYW4gaW5kZXggb3IgYSBudW1lcmljYWwgdmFsdWVcblx0ICogVGhlIGNvb3JkaW5hdGUgKDAsIDApIGlzIGF0IHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGUgY2FudmFzXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWVcblx0ICogQHBhcmFtIHtudW1iZXJ9IFtpbmRleF1cblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSwgaW5kZXgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIHJldHVybiBOYU47XG4gIH1cblxuICAvKipcblx0ICogVXNlZCB0byBnZXQgdGhlIGRhdGEgdmFsdWUgZnJvbSBhIGdpdmVuIHBpeGVsLiBUaGlzIGlzIHRoZSBpbnZlcnNlIG9mIGdldFBpeGVsRm9yVmFsdWVcblx0ICogVGhlIGNvb3JkaW5hdGUgKDAsIDApIGlzIGF0IHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGUgY2FudmFzXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFxuXHQgKiBAcmV0dXJuIHsqfVxuXHQgKi9cbiAgZ2V0VmFsdWVGb3JQaXhlbChwaXhlbCkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBsb2NhdGlvbiBvZiB0aGUgdGljayBhdCB0aGUgZ2l2ZW4gaW5kZXhcblx0ICogVGhlIGNvb3JkaW5hdGUgKDAsIDApIGlzIGF0IHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGUgY2FudmFzXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuICBnZXRQaXhlbEZvclRpY2soaW5kZXgpIHtcbiAgICBjb25zdCB0aWNrcyA9IHRoaXMudGlja3M7XG4gICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+IHRpY2tzLmxlbmd0aCAtIDEpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5nZXRQaXhlbEZvclZhbHVlKHRpY2tzW2luZGV4XS52YWx1ZSk7XG4gIH1cblxuICAvKipcblx0ICogVXRpbGl0eSBmb3IgZ2V0dGluZyB0aGUgcGl4ZWwgbG9jYXRpb24gb2YgYSBwZXJjZW50YWdlIG9mIHNjYWxlXG5cdCAqIFRoZSBjb29yZGluYXRlICgwLCAwKSBpcyBhdCB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlIGNhbnZhc1xuXHQgKiBAcGFyYW0ge251bWJlcn0gZGVjaW1hbFxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuICBnZXRQaXhlbEZvckRlY2ltYWwoZGVjaW1hbCkge1xuICAgIGlmICh0aGlzLl9yZXZlcnNlUGl4ZWxzKSB7XG4gICAgICBkZWNpbWFsID0gMSAtIGRlY2ltYWw7XG4gICAgfVxuXG4gICAgY29uc3QgcGl4ZWwgPSB0aGlzLl9zdGFydFBpeGVsICsgZGVjaW1hbCAqIHRoaXMuX2xlbmd0aDtcbiAgICByZXR1cm4gX2ludDE2UmFuZ2UodGhpcy5fYWxpZ25Ub1BpeGVscyA/IF9hbGlnblBpeGVsKHRoaXMuY2hhcnQsIHBpeGVsLCAwKSA6IHBpeGVsKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgZ2V0RGVjaW1hbEZvclBpeGVsKHBpeGVsKSB7XG4gICAgY29uc3QgZGVjaW1hbCA9IChwaXhlbCAtIHRoaXMuX3N0YXJ0UGl4ZWwpIC8gdGhpcy5fbGVuZ3RoO1xuICAgIHJldHVybiB0aGlzLl9yZXZlcnNlUGl4ZWxzID8gMSAtIGRlY2ltYWwgOiBkZWNpbWFsO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJldHVybnMgdGhlIHBpeGVsIGZvciB0aGUgbWluaW11bSBjaGFydCB2YWx1ZVxuXHQgKiBUaGUgY29vcmRpbmF0ZSAoMCwgMCkgaXMgYXQgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZSBjYW52YXNcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgZ2V0QmFzZVBpeGVsKCkge1xuICAgIHJldHVybiB0aGlzLmdldFBpeGVsRm9yVmFsdWUodGhpcy5nZXRCYXNlVmFsdWUoKSk7XG4gIH1cblxuICAvKipcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgZ2V0QmFzZVZhbHVlKCkge1xuICAgIGNvbnN0IHttaW4sIG1heH0gPSB0aGlzO1xuXG4gICAgcmV0dXJuIG1pbiA8IDAgJiYgbWF4IDwgMCA/IG1heCA6XG4gICAgICBtaW4gPiAwICYmIG1heCA+IDAgPyBtaW4gOlxuICAgICAgMDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRDb250ZXh0KGluZGV4KSB7XG4gICAgY29uc3QgdGlja3MgPSB0aGlzLnRpY2tzIHx8IFtdO1xuXG4gICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCB0aWNrcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHRpY2sgPSB0aWNrc1tpbmRleF07XG4gICAgICByZXR1cm4gdGljay4kY29udGV4dCB8fFxuXHRcdFx0XHQodGljay4kY29udGV4dCA9IGNyZWF0ZVRpY2tDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpLCBpbmRleCwgdGljaykpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy4kY29udGV4dCB8fFxuXHRcdFx0KHRoaXMuJGNvbnRleHQgPSBjcmVhdGVTY2FsZUNvbnRleHQodGhpcy5jaGFydC5nZXRDb250ZXh0KCksIHRoaXMpKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdGlja1NpemUoKSB7XG4gICAgY29uc3Qgb3B0aW9uVGlja3MgPSB0aGlzLm9wdGlvbnMudGlja3M7XG5cbiAgICAvLyBDYWxjdWxhdGUgc3BhY2UgbmVlZGVkIGJ5IGxhYmVsIGluIGF4aXMgZGlyZWN0aW9uLlxuICAgIGNvbnN0IHJvdCA9IHRvUmFkaWFucyh0aGlzLmxhYmVsUm90YXRpb24pO1xuICAgIGNvbnN0IGNvcyA9IE1hdGguYWJzKE1hdGguY29zKHJvdCkpO1xuICAgIGNvbnN0IHNpbiA9IE1hdGguYWJzKE1hdGguc2luKHJvdCkpO1xuXG4gICAgY29uc3QgbGFiZWxTaXplcyA9IHRoaXMuX2dldExhYmVsU2l6ZXMoKTtcbiAgICBjb25zdCBwYWRkaW5nID0gb3B0aW9uVGlja3MuYXV0b1NraXBQYWRkaW5nIHx8IDA7XG4gICAgY29uc3QgdyA9IGxhYmVsU2l6ZXMgPyBsYWJlbFNpemVzLndpZGVzdC53aWR0aCArIHBhZGRpbmcgOiAwO1xuICAgIGNvbnN0IGggPSBsYWJlbFNpemVzID8gbGFiZWxTaXplcy5oaWdoZXN0LmhlaWdodCArIHBhZGRpbmcgOiAwO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHNwYWNlIG5lZWRlZCBmb3IgMSB0aWNrIGluIGF4aXMgZGlyZWN0aW9uLlxuICAgIHJldHVybiB0aGlzLmlzSG9yaXpvbnRhbCgpXG4gICAgICA/IGggKiBjb3MgPiB3ICogc2luID8gdyAvIGNvcyA6IGggLyBzaW5cbiAgICAgIDogaCAqIHNpbiA8IHcgKiBjb3MgPyBoIC8gY29zIDogdyAvIHNpbjtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcmV0dXJuIHtib29sZWFufVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2lzVmlzaWJsZSgpIHtcbiAgICBjb25zdCBkaXNwbGF5ID0gdGhpcy5vcHRpb25zLmRpc3BsYXk7XG5cbiAgICBpZiAoZGlzcGxheSAhPT0gJ2F1dG8nKSB7XG4gICAgICByZXR1cm4gISFkaXNwbGF5O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmdldE1hdGNoaW5nVmlzaWJsZU1ldGFzKCkubGVuZ3RoID4gMDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2NvbXB1dGVHcmlkTGluZUl0ZW1zKGNoYXJ0QXJlYSkge1xuICAgIGNvbnN0IGF4aXMgPSB0aGlzLmF4aXM7XG4gICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3Qge2dyaWQsIHBvc2l0aW9uLCBib3JkZXJ9ID0gb3B0aW9ucztcbiAgICBjb25zdCBvZmZzZXQgPSBncmlkLm9mZnNldDtcbiAgICBjb25zdCBpc0hvcml6b250YWwgPSB0aGlzLmlzSG9yaXpvbnRhbCgpO1xuICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICBjb25zdCB0aWNrc0xlbmd0aCA9IHRpY2tzLmxlbmd0aCArIChvZmZzZXQgPyAxIDogMCk7XG4gICAgY29uc3QgdGwgPSBnZXRUaWNrTWFya0xlbmd0aChncmlkKTtcbiAgICBjb25zdCBpdGVtcyA9IFtdO1xuXG4gICAgY29uc3QgYm9yZGVyT3B0cyA9IGJvcmRlci5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICBjb25zdCBheGlzV2lkdGggPSBib3JkZXJPcHRzLmRpc3BsYXkgPyBib3JkZXJPcHRzLndpZHRoIDogMDtcbiAgICBjb25zdCBheGlzSGFsZldpZHRoID0gYXhpc1dpZHRoIC8gMjtcbiAgICBjb25zdCBhbGlnbkJvcmRlclZhbHVlID0gZnVuY3Rpb24ocGl4ZWwpIHtcbiAgICAgIHJldHVybiBfYWxpZ25QaXhlbChjaGFydCwgcGl4ZWwsIGF4aXNXaWR0aCk7XG4gICAgfTtcbiAgICBsZXQgYm9yZGVyVmFsdWUsIGksIGxpbmVWYWx1ZSwgYWxpZ25lZExpbmVWYWx1ZTtcbiAgICBsZXQgdHgxLCB0eTEsIHR4MiwgdHkyLCB4MSwgeTEsIHgyLCB5MjtcblxuICAgIGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcpIHtcbiAgICAgIGJvcmRlclZhbHVlID0gYWxpZ25Cb3JkZXJWYWx1ZSh0aGlzLmJvdHRvbSk7XG4gICAgICB0eTEgPSB0aGlzLmJvdHRvbSAtIHRsO1xuICAgICAgdHkyID0gYm9yZGVyVmFsdWUgLSBheGlzSGFsZldpZHRoO1xuICAgICAgeTEgPSBhbGlnbkJvcmRlclZhbHVlKGNoYXJ0QXJlYS50b3ApICsgYXhpc0hhbGZXaWR0aDtcbiAgICAgIHkyID0gY2hhcnRBcmVhLmJvdHRvbTtcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnYm90dG9tJykge1xuICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKHRoaXMudG9wKTtcbiAgICAgIHkxID0gY2hhcnRBcmVhLnRvcDtcbiAgICAgIHkyID0gYWxpZ25Cb3JkZXJWYWx1ZShjaGFydEFyZWEuYm90dG9tKSAtIGF4aXNIYWxmV2lkdGg7XG4gICAgICB0eTEgPSBib3JkZXJWYWx1ZSArIGF4aXNIYWxmV2lkdGg7XG4gICAgICB0eTIgPSB0aGlzLnRvcCArIHRsO1xuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdsZWZ0Jykge1xuICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKHRoaXMucmlnaHQpO1xuICAgICAgdHgxID0gdGhpcy5yaWdodCAtIHRsO1xuICAgICAgdHgyID0gYm9yZGVyVmFsdWUgLSBheGlzSGFsZldpZHRoO1xuICAgICAgeDEgPSBhbGlnbkJvcmRlclZhbHVlKGNoYXJ0QXJlYS5sZWZ0KSArIGF4aXNIYWxmV2lkdGg7XG4gICAgICB4MiA9IGNoYXJ0QXJlYS5yaWdodDtcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAncmlnaHQnKSB7XG4gICAgICBib3JkZXJWYWx1ZSA9IGFsaWduQm9yZGVyVmFsdWUodGhpcy5sZWZ0KTtcbiAgICAgIHgxID0gY2hhcnRBcmVhLmxlZnQ7XG4gICAgICB4MiA9IGFsaWduQm9yZGVyVmFsdWUoY2hhcnRBcmVhLnJpZ2h0KSAtIGF4aXNIYWxmV2lkdGg7XG4gICAgICB0eDEgPSBib3JkZXJWYWx1ZSArIGF4aXNIYWxmV2lkdGg7XG4gICAgICB0eDIgPSB0aGlzLmxlZnQgKyB0bDtcbiAgICB9IGVsc2UgaWYgKGF4aXMgPT09ICd4Jykge1xuICAgICAgaWYgKHBvc2l0aW9uID09PSAnY2VudGVyJykge1xuICAgICAgICBib3JkZXJWYWx1ZSA9IGFsaWduQm9yZGVyVmFsdWUoKGNoYXJ0QXJlYS50b3AgKyBjaGFydEFyZWEuYm90dG9tKSAvIDIgKyAwLjUpO1xuICAgICAgfSBlbHNlIGlmIChpc09iamVjdChwb3NpdGlvbikpIHtcbiAgICAgICAgY29uc3QgcG9zaXRpb25BeGlzSUQgPSBPYmplY3Qua2V5cyhwb3NpdGlvbilbMF07XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcG9zaXRpb25bcG9zaXRpb25BeGlzSURdO1xuICAgICAgICBib3JkZXJWYWx1ZSA9IGFsaWduQm9yZGVyVmFsdWUodGhpcy5jaGFydC5zY2FsZXNbcG9zaXRpb25BeGlzSURdLmdldFBpeGVsRm9yVmFsdWUodmFsdWUpKTtcbiAgICAgIH1cblxuICAgICAgeTEgPSBjaGFydEFyZWEudG9wO1xuICAgICAgeTIgPSBjaGFydEFyZWEuYm90dG9tO1xuICAgICAgdHkxID0gYm9yZGVyVmFsdWUgKyBheGlzSGFsZldpZHRoO1xuICAgICAgdHkyID0gdHkxICsgdGw7XG4gICAgfSBlbHNlIGlmIChheGlzID09PSAneScpIHtcbiAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKChjaGFydEFyZWEubGVmdCArIGNoYXJ0QXJlYS5yaWdodCkgLyAyKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QocG9zaXRpb24pKSB7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uQXhpc0lEID0gT2JqZWN0LmtleXMocG9zaXRpb24pWzBdO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHBvc2l0aW9uW3Bvc2l0aW9uQXhpc0lEXTtcbiAgICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKHRoaXMuY2hhcnQuc2NhbGVzW3Bvc2l0aW9uQXhpc0lEXS5nZXRQaXhlbEZvclZhbHVlKHZhbHVlKSk7XG4gICAgICB9XG5cbiAgICAgIHR4MSA9IGJvcmRlclZhbHVlIC0gYXhpc0hhbGZXaWR0aDtcbiAgICAgIHR4MiA9IHR4MSAtIHRsO1xuICAgICAgeDEgPSBjaGFydEFyZWEubGVmdDtcbiAgICAgIHgyID0gY2hhcnRBcmVhLnJpZ2h0O1xuICAgIH1cblxuICAgIGNvbnN0IGxpbWl0ID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy50aWNrcy5tYXhUaWNrc0xpbWl0LCB0aWNrc0xlbmd0aCk7XG4gICAgY29uc3Qgc3RlcCA9IE1hdGgubWF4KDEsIE1hdGguY2VpbCh0aWNrc0xlbmd0aCAvIGxpbWl0KSk7XG4gICAgZm9yIChpID0gMDsgaSA8IHRpY2tzTGVuZ3RoOyBpICs9IHN0ZXApIHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmdldENvbnRleHQoaSk7XG4gICAgICBjb25zdCBvcHRzQXRJbmRleCA9IGdyaWQuc2V0Q29udGV4dChjb250ZXh0KTtcbiAgICAgIGNvbnN0IG9wdHNBdEluZGV4Qm9yZGVyID0gYm9yZGVyLnNldENvbnRleHQoY29udGV4dCk7XG5cbiAgICAgIGNvbnN0IGxpbmVXaWR0aCA9IG9wdHNBdEluZGV4LmxpbmVXaWR0aDtcbiAgICAgIGNvbnN0IGxpbmVDb2xvciA9IG9wdHNBdEluZGV4LmNvbG9yO1xuICAgICAgY29uc3QgYm9yZGVyRGFzaCA9IG9wdHNBdEluZGV4Qm9yZGVyLmRhc2ggfHwgW107XG4gICAgICBjb25zdCBib3JkZXJEYXNoT2Zmc2V0ID0gb3B0c0F0SW5kZXhCb3JkZXIuZGFzaE9mZnNldDtcblxuICAgICAgY29uc3QgdGlja1dpZHRoID0gb3B0c0F0SW5kZXgudGlja1dpZHRoO1xuICAgICAgY29uc3QgdGlja0NvbG9yID0gb3B0c0F0SW5kZXgudGlja0NvbG9yO1xuICAgICAgY29uc3QgdGlja0JvcmRlckRhc2ggPSBvcHRzQXRJbmRleC50aWNrQm9yZGVyRGFzaCB8fCBbXTtcbiAgICAgIGNvbnN0IHRpY2tCb3JkZXJEYXNoT2Zmc2V0ID0gb3B0c0F0SW5kZXgudGlja0JvcmRlckRhc2hPZmZzZXQ7XG5cbiAgICAgIGxpbmVWYWx1ZSA9IGdldFBpeGVsRm9yR3JpZExpbmUodGhpcywgaSwgb2Zmc2V0KTtcblxuICAgICAgLy8gU2tpcCBpZiB0aGUgcGl4ZWwgaXMgb3V0IG9mIHRoZSByYW5nZVxuICAgICAgaWYgKGxpbmVWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBhbGlnbmVkTGluZVZhbHVlID0gX2FsaWduUGl4ZWwoY2hhcnQsIGxpbmVWYWx1ZSwgbGluZVdpZHRoKTtcblxuICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICB0eDEgPSB0eDIgPSB4MSA9IHgyID0gYWxpZ25lZExpbmVWYWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHR5MSA9IHR5MiA9IHkxID0geTIgPSBhbGlnbmVkTGluZVZhbHVlO1xuICAgICAgfVxuXG4gICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgdHgxLFxuICAgICAgICB0eTEsXG4gICAgICAgIHR4MixcbiAgICAgICAgdHkyLFxuICAgICAgICB4MSxcbiAgICAgICAgeTEsXG4gICAgICAgIHgyLFxuICAgICAgICB5MixcbiAgICAgICAgd2lkdGg6IGxpbmVXaWR0aCxcbiAgICAgICAgY29sb3I6IGxpbmVDb2xvcixcbiAgICAgICAgYm9yZGVyRGFzaCxcbiAgICAgICAgYm9yZGVyRGFzaE9mZnNldCxcbiAgICAgICAgdGlja1dpZHRoLFxuICAgICAgICB0aWNrQ29sb3IsXG4gICAgICAgIHRpY2tCb3JkZXJEYXNoLFxuICAgICAgICB0aWNrQm9yZGVyRGFzaE9mZnNldCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX3RpY2tzTGVuZ3RoID0gdGlja3NMZW5ndGg7XG4gICAgdGhpcy5fYm9yZGVyVmFsdWUgPSBib3JkZXJWYWx1ZTtcblxuICAgIHJldHVybiBpdGVtcztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2NvbXB1dGVMYWJlbEl0ZW1zKGNoYXJ0QXJlYSkge1xuICAgIGNvbnN0IGF4aXMgPSB0aGlzLmF4aXM7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB7cG9zaXRpb24sIHRpY2tzOiBvcHRpb25UaWNrc30gPSBvcHRpb25zO1xuICAgIGNvbnN0IGlzSG9yaXpvbnRhbCA9IHRoaXMuaXNIb3Jpem9udGFsKCk7XG4gICAgY29uc3QgdGlja3MgPSB0aGlzLnRpY2tzO1xuICAgIGNvbnN0IHthbGlnbiwgY3Jvc3NBbGlnbiwgcGFkZGluZywgbWlycm9yfSA9IG9wdGlvblRpY2tzO1xuICAgIGNvbnN0IHRsID0gZ2V0VGlja01hcmtMZW5ndGgob3B0aW9ucy5ncmlkKTtcbiAgICBjb25zdCB0aWNrQW5kUGFkZGluZyA9IHRsICsgcGFkZGluZztcbiAgICBjb25zdCBoVGlja0FuZFBhZGRpbmcgPSBtaXJyb3IgPyAtcGFkZGluZyA6IHRpY2tBbmRQYWRkaW5nO1xuICAgIGNvbnN0IHJvdGF0aW9uID0gLXRvUmFkaWFucyh0aGlzLmxhYmVsUm90YXRpb24pO1xuICAgIGNvbnN0IGl0ZW1zID0gW107XG4gICAgbGV0IGksIGlsZW4sIHRpY2ssIGxhYmVsLCB4LCB5LCB0ZXh0QWxpZ24sIHBpeGVsLCBmb250LCBsaW5lSGVpZ2h0LCBsaW5lQ291bnQsIHRleHRPZmZzZXQ7XG4gICAgbGV0IHRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuXG4gICAgaWYgKHBvc2l0aW9uID09PSAndG9wJykge1xuICAgICAgeSA9IHRoaXMuYm90dG9tIC0gaFRpY2tBbmRQYWRkaW5nO1xuICAgICAgdGV4dEFsaWduID0gdGhpcy5fZ2V0WEF4aXNMYWJlbEFsaWdubWVudCgpO1xuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICB5ID0gdGhpcy50b3AgKyBoVGlja0FuZFBhZGRpbmc7XG4gICAgICB0ZXh0QWxpZ24gPSB0aGlzLl9nZXRYQXhpc0xhYmVsQWxpZ25tZW50KCk7XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2xlZnQnKSB7XG4gICAgICBjb25zdCByZXQgPSB0aGlzLl9nZXRZQXhpc0xhYmVsQWxpZ25tZW50KHRsKTtcbiAgICAgIHRleHRBbGlnbiA9IHJldC50ZXh0QWxpZ247XG4gICAgICB4ID0gcmV0Lng7XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgY29uc3QgcmV0ID0gdGhpcy5fZ2V0WUF4aXNMYWJlbEFsaWdubWVudCh0bCk7XG4gICAgICB0ZXh0QWxpZ24gPSByZXQudGV4dEFsaWduO1xuICAgICAgeCA9IHJldC54O1xuICAgIH0gZWxzZSBpZiAoYXhpcyA9PT0gJ3gnKSB7XG4gICAgICBpZiAocG9zaXRpb24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgIHkgPSAoKGNoYXJ0QXJlYS50b3AgKyBjaGFydEFyZWEuYm90dG9tKSAvIDIpICsgdGlja0FuZFBhZGRpbmc7XG4gICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHBvc2l0aW9uKSkge1xuICAgICAgICBjb25zdCBwb3NpdGlvbkF4aXNJRCA9IE9iamVjdC5rZXlzKHBvc2l0aW9uKVswXTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBwb3NpdGlvbltwb3NpdGlvbkF4aXNJRF07XG4gICAgICAgIHkgPSB0aGlzLmNoYXJ0LnNjYWxlc1twb3NpdGlvbkF4aXNJRF0uZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSkgKyB0aWNrQW5kUGFkZGluZztcbiAgICAgIH1cbiAgICAgIHRleHRBbGlnbiA9IHRoaXMuX2dldFhBeGlzTGFiZWxBbGlnbm1lbnQoKTtcbiAgICB9IGVsc2UgaWYgKGF4aXMgPT09ICd5Jykge1xuICAgICAgaWYgKHBvc2l0aW9uID09PSAnY2VudGVyJykge1xuICAgICAgICB4ID0gKChjaGFydEFyZWEubGVmdCArIGNoYXJ0QXJlYS5yaWdodCkgLyAyKSAtIHRpY2tBbmRQYWRkaW5nO1xuICAgICAgfSBlbHNlIGlmIChpc09iamVjdChwb3NpdGlvbikpIHtcbiAgICAgICAgY29uc3QgcG9zaXRpb25BeGlzSUQgPSBPYmplY3Qua2V5cyhwb3NpdGlvbilbMF07XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcG9zaXRpb25bcG9zaXRpb25BeGlzSURdO1xuICAgICAgICB4ID0gdGhpcy5jaGFydC5zY2FsZXNbcG9zaXRpb25BeGlzSURdLmdldFBpeGVsRm9yVmFsdWUodmFsdWUpO1xuICAgICAgfVxuICAgICAgdGV4dEFsaWduID0gdGhpcy5fZ2V0WUF4aXNMYWJlbEFsaWdubWVudCh0bCkudGV4dEFsaWduO1xuICAgIH1cblxuICAgIGlmIChheGlzID09PSAneScpIHtcbiAgICAgIGlmIChhbGlnbiA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICB0ZXh0QmFzZWxpbmUgPSAndG9wJztcbiAgICAgIH0gZWxzZSBpZiAoYWxpZ24gPT09ICdlbmQnKSB7XG4gICAgICAgIHRleHRCYXNlbGluZSA9ICdib3R0b20nO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGxhYmVsU2l6ZXMgPSB0aGlzLl9nZXRMYWJlbFNpemVzKCk7XG4gICAgZm9yIChpID0gMCwgaWxlbiA9IHRpY2tzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgdGljayA9IHRpY2tzW2ldO1xuICAgICAgbGFiZWwgPSB0aWNrLmxhYmVsO1xuXG4gICAgICBjb25zdCBvcHRzQXRJbmRleCA9IG9wdGlvblRpY2tzLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KGkpKTtcbiAgICAgIHBpeGVsID0gdGhpcy5nZXRQaXhlbEZvclRpY2soaSkgKyBvcHRpb25UaWNrcy5sYWJlbE9mZnNldDtcbiAgICAgIGZvbnQgPSB0aGlzLl9yZXNvbHZlVGlja0ZvbnRPcHRpb25zKGkpO1xuICAgICAgbGluZUhlaWdodCA9IGZvbnQubGluZUhlaWdodDtcbiAgICAgIGxpbmVDb3VudCA9IGlzQXJyYXkobGFiZWwpID8gbGFiZWwubGVuZ3RoIDogMTtcbiAgICAgIGNvbnN0IGhhbGZDb3VudCA9IGxpbmVDb3VudCAvIDI7XG4gICAgICBjb25zdCBjb2xvciA9IG9wdHNBdEluZGV4LmNvbG9yO1xuICAgICAgY29uc3Qgc3Ryb2tlQ29sb3IgPSBvcHRzQXRJbmRleC50ZXh0U3Ryb2tlQ29sb3I7XG4gICAgICBjb25zdCBzdHJva2VXaWR0aCA9IG9wdHNBdEluZGV4LnRleHRTdHJva2VXaWR0aDtcbiAgICAgIGxldCB0aWNrVGV4dEFsaWduID0gdGV4dEFsaWduO1xuXG4gICAgICBpZiAoaXNIb3Jpem9udGFsKSB7XG4gICAgICAgIHggPSBwaXhlbDtcblxuICAgICAgICBpZiAodGV4dEFsaWduID09PSAnaW5uZXInKSB7XG4gICAgICAgICAgaWYgKGkgPT09IGlsZW4gLSAxKSB7XG4gICAgICAgICAgICB0aWNrVGV4dEFsaWduID0gIXRoaXMub3B0aW9ucy5yZXZlcnNlID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgICAgICAgICB9IGVsc2UgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgIHRpY2tUZXh0QWxpZ24gPSAhdGhpcy5vcHRpb25zLnJldmVyc2UgPyAnbGVmdCcgOiAncmlnaHQnO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aWNrVGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAndG9wJykge1xuICAgICAgICAgIGlmIChjcm9zc0FsaWduID09PSAnbmVhcicgfHwgcm90YXRpb24gIT09IDApIHtcbiAgICAgICAgICAgIHRleHRPZmZzZXQgPSAtbGluZUNvdW50ICogbGluZUhlaWdodCArIGxpbmVIZWlnaHQgLyAyO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY3Jvc3NBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgIHRleHRPZmZzZXQgPSAtbGFiZWxTaXplcy5oaWdoZXN0LmhlaWdodCAvIDIgLSBoYWxmQ291bnQgKiBsaW5lSGVpZ2h0ICsgbGluZUhlaWdodDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGV4dE9mZnNldCA9IC1sYWJlbFNpemVzLmhpZ2hlc3QuaGVpZ2h0ICsgbGluZUhlaWdodCAvIDI7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1sb25lbHktaWZcbiAgICAgICAgICBpZiAoY3Jvc3NBbGlnbiA9PT0gJ25lYXInIHx8IHJvdGF0aW9uICE9PSAwKSB7XG4gICAgICAgICAgICB0ZXh0T2Zmc2V0ID0gbGluZUhlaWdodCAvIDI7XG4gICAgICAgICAgfSBlbHNlIGlmIChjcm9zc0FsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICAgICAgdGV4dE9mZnNldCA9IGxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQgLyAyIC0gaGFsZkNvdW50ICogbGluZUhlaWdodDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGV4dE9mZnNldCA9IGxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQgLSBsaW5lQ291bnQgKiBsaW5lSGVpZ2h0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobWlycm9yKSB7XG4gICAgICAgICAgdGV4dE9mZnNldCAqPSAtMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocm90YXRpb24gIT09IDAgJiYgIW9wdHNBdEluZGV4LnNob3dMYWJlbEJhY2tkcm9wKSB7XG4gICAgICAgICAgeCArPSAobGluZUhlaWdodCAvIDIpICogTWF0aC5zaW4ocm90YXRpb24pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB5ID0gcGl4ZWw7XG4gICAgICAgIHRleHRPZmZzZXQgPSAoMSAtIGxpbmVDb3VudCkgKiBsaW5lSGVpZ2h0IC8gMjtcbiAgICAgIH1cblxuICAgICAgbGV0IGJhY2tkcm9wO1xuXG4gICAgICBpZiAob3B0c0F0SW5kZXguc2hvd0xhYmVsQmFja2Ryb3ApIHtcbiAgICAgICAgY29uc3QgbGFiZWxQYWRkaW5nID0gdG9QYWRkaW5nKG9wdHNBdEluZGV4LmJhY2tkcm9wUGFkZGluZyk7XG4gICAgICAgIGNvbnN0IGhlaWdodCA9IGxhYmVsU2l6ZXMuaGVpZ2h0c1tpXTtcbiAgICAgICAgY29uc3Qgd2lkdGggPSBsYWJlbFNpemVzLndpZHRoc1tpXTtcblxuICAgICAgICBsZXQgdG9wID0gdGV4dE9mZnNldCAtIGxhYmVsUGFkZGluZy50b3A7XG4gICAgICAgIGxldCBsZWZ0ID0gMCAtIGxhYmVsUGFkZGluZy5sZWZ0O1xuXG4gICAgICAgIHN3aXRjaCAodGV4dEJhc2VsaW5lKSB7XG4gICAgICAgIGNhc2UgJ21pZGRsZSc6XG4gICAgICAgICAgdG9wIC09IGhlaWdodCAvIDI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgICAgdG9wIC09IGhlaWdodDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAodGV4dEFsaWduKSB7XG4gICAgICAgIGNhc2UgJ2NlbnRlcic6XG4gICAgICAgICAgbGVmdCAtPSB3aWR0aCAvIDI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgICBsZWZ0IC09IHdpZHRoO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdpbm5lcic6XG4gICAgICAgICAgaWYgKGkgPT09IGlsZW4gLSAxKSB7XG4gICAgICAgICAgICBsZWZ0IC09IHdpZHRoO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgIGxlZnQgLT0gd2lkdGggLyAyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGJhY2tkcm9wID0ge1xuICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgdG9wLFxuICAgICAgICAgIHdpZHRoOiB3aWR0aCArIGxhYmVsUGFkZGluZy53aWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IGhlaWdodCArIGxhYmVsUGFkZGluZy5oZWlnaHQsXG5cbiAgICAgICAgICBjb2xvcjogb3B0c0F0SW5kZXguYmFja2Ryb3BDb2xvcixcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgIGxhYmVsLFxuICAgICAgICBmb250LFxuICAgICAgICB0ZXh0T2Zmc2V0LFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgcm90YXRpb24sXG4gICAgICAgICAgY29sb3IsXG4gICAgICAgICAgc3Ryb2tlQ29sb3IsXG4gICAgICAgICAgc3Ryb2tlV2lkdGgsXG4gICAgICAgICAgdGV4dEFsaWduOiB0aWNrVGV4dEFsaWduLFxuICAgICAgICAgIHRleHRCYXNlbGluZSxcbiAgICAgICAgICB0cmFuc2xhdGlvbjogW3gsIHldLFxuICAgICAgICAgIGJhY2tkcm9wLFxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICBfZ2V0WEF4aXNMYWJlbEFsaWdubWVudCgpIHtcbiAgICBjb25zdCB7cG9zaXRpb24sIHRpY2tzfSA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCByb3RhdGlvbiA9IC10b1JhZGlhbnModGhpcy5sYWJlbFJvdGF0aW9uKTtcblxuICAgIGlmIChyb3RhdGlvbikge1xuICAgICAgcmV0dXJuIHBvc2l0aW9uID09PSAndG9wJyA/ICdsZWZ0JyA6ICdyaWdodCc7XG4gICAgfVxuXG4gICAgbGV0IGFsaWduID0gJ2NlbnRlcic7XG5cbiAgICBpZiAodGlja3MuYWxpZ24gPT09ICdzdGFydCcpIHtcbiAgICAgIGFsaWduID0gJ2xlZnQnO1xuICAgIH0gZWxzZSBpZiAodGlja3MuYWxpZ24gPT09ICdlbmQnKSB7XG4gICAgICBhbGlnbiA9ICdyaWdodCc7XG4gICAgfSBlbHNlIGlmICh0aWNrcy5hbGlnbiA9PT0gJ2lubmVyJykge1xuICAgICAgYWxpZ24gPSAnaW5uZXInO1xuICAgIH1cblxuICAgIHJldHVybiBhbGlnbjtcbiAgfVxuXG4gIF9nZXRZQXhpc0xhYmVsQWxpZ25tZW50KHRsKSB7XG4gICAgY29uc3Qge3Bvc2l0aW9uLCB0aWNrczoge2Nyb3NzQWxpZ24sIG1pcnJvciwgcGFkZGluZ319ID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IGxhYmVsU2l6ZXMgPSB0aGlzLl9nZXRMYWJlbFNpemVzKCk7XG4gICAgY29uc3QgdGlja0FuZFBhZGRpbmcgPSB0bCArIHBhZGRpbmc7XG4gICAgY29uc3Qgd2lkZXN0ID0gbGFiZWxTaXplcy53aWRlc3Qud2lkdGg7XG5cbiAgICBsZXQgdGV4dEFsaWduO1xuICAgIGxldCB4O1xuXG4gICAgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgIGlmIChtaXJyb3IpIHtcbiAgICAgICAgeCA9IHRoaXMucmlnaHQgKyBwYWRkaW5nO1xuXG4gICAgICAgIGlmIChjcm9zc0FsaWduID09PSAnbmVhcicpIHtcbiAgICAgICAgICB0ZXh0QWxpZ24gPSAnbGVmdCc7XG4gICAgICAgIH0gZWxzZSBpZiAoY3Jvc3NBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICB0ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICAgICAgICB4ICs9ICh3aWRlc3QgLyAyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0ZXh0QWxpZ24gPSAncmlnaHQnO1xuICAgICAgICAgIHggKz0gd2lkZXN0O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4ID0gdGhpcy5yaWdodCAtIHRpY2tBbmRQYWRkaW5nO1xuXG4gICAgICAgIGlmIChjcm9zc0FsaWduID09PSAnbmVhcicpIHtcbiAgICAgICAgICB0ZXh0QWxpZ24gPSAncmlnaHQnO1xuICAgICAgICB9IGVsc2UgaWYgKGNyb3NzQWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgICAgeCAtPSAod2lkZXN0IC8gMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICAgIHggPSB0aGlzLmxlZnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAncmlnaHQnKSB7XG4gICAgICBpZiAobWlycm9yKSB7XG4gICAgICAgIHggPSB0aGlzLmxlZnQgKyBwYWRkaW5nO1xuXG4gICAgICAgIGlmIChjcm9zc0FsaWduID09PSAnbmVhcicpIHtcbiAgICAgICAgICB0ZXh0QWxpZ24gPSAncmlnaHQnO1xuICAgICAgICB9IGVsc2UgaWYgKGNyb3NzQWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgICAgeCAtPSAod2lkZXN0IC8gMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICAgIHggLT0gd2lkZXN0O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4ID0gdGhpcy5sZWZ0ICsgdGlja0FuZFBhZGRpbmc7XG5cbiAgICAgICAgaWYgKGNyb3NzQWxpZ24gPT09ICduZWFyJykge1xuICAgICAgICAgIHRleHRBbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgfSBlbHNlIGlmIChjcm9zc0FsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICAgIHRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICAgIHggKz0gd2lkZXN0IC8gMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0ZXh0QWxpZ24gPSAncmlnaHQnO1xuICAgICAgICAgIHggPSB0aGlzLnJpZ2h0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRleHRBbGlnbiA9ICdyaWdodCc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHt0ZXh0QWxpZ24sIHh9O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfY29tcHV0ZUxhYmVsQXJlYSgpIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLnRpY2tzLm1pcnJvcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMub3B0aW9ucy5wb3NpdGlvbjtcblxuICAgIGlmIChwb3NpdGlvbiA9PT0gJ2xlZnQnIHx8IHBvc2l0aW9uID09PSAncmlnaHQnKSB7XG4gICAgICByZXR1cm4ge3RvcDogMCwgbGVmdDogdGhpcy5sZWZ0LCBib3R0b206IGNoYXJ0LmhlaWdodCwgcmlnaHQ6IHRoaXMucmlnaHR9O1xuICAgIH0gaWYgKHBvc2l0aW9uID09PSAndG9wJyB8fCBwb3NpdGlvbiA9PT0gJ2JvdHRvbScpIHtcbiAgICAgIHJldHVybiB7dG9wOiB0aGlzLnRvcCwgbGVmdDogMCwgYm90dG9tOiB0aGlzLmJvdHRvbSwgcmlnaHQ6IGNoYXJ0LndpZHRofTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgZHJhd0JhY2tncm91bmQoKSB7XG4gICAgY29uc3Qge2N0eCwgb3B0aW9uczoge2JhY2tncm91bmRDb2xvcn0sIGxlZnQsIHRvcCwgd2lkdGgsIGhlaWdodH0gPSB0aGlzO1xuICAgIGlmIChiYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICBjdHguZmlsbFN0eWxlID0gYmFja2dyb3VuZENvbG9yO1xuICAgICAgY3R4LmZpbGxSZWN0KGxlZnQsIHRvcCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cbiAgfVxuXG4gIGdldExpbmVXaWR0aEZvclZhbHVlKHZhbHVlKSB7XG4gICAgY29uc3QgZ3JpZCA9IHRoaXMub3B0aW9ucy5ncmlkO1xuICAgIGlmICghdGhpcy5faXNWaXNpYmxlKCkgfHwgIWdyaWQuZGlzcGxheSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICBjb25zdCBpbmRleCA9IHRpY2tzLmZpbmRJbmRleCh0ID0+IHQudmFsdWUgPT09IHZhbHVlKTtcbiAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgY29uc3Qgb3B0cyA9IGdyaWQuc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoaW5kZXgpKTtcbiAgICAgIHJldHVybiBvcHRzLmxpbmVXaWR0aDtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZHJhd0dyaWQoY2hhcnRBcmVhKSB7XG4gICAgY29uc3QgZ3JpZCA9IHRoaXMub3B0aW9ucy5ncmlkO1xuICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5fZ3JpZExpbmVJdGVtcyB8fCAodGhpcy5fZ3JpZExpbmVJdGVtcyA9IHRoaXMuX2NvbXB1dGVHcmlkTGluZUl0ZW1zKGNoYXJ0QXJlYSkpO1xuICAgIGxldCBpLCBpbGVuO1xuXG4gICAgY29uc3QgZHJhd0xpbmUgPSAocDEsIHAyLCBzdHlsZSkgPT4ge1xuICAgICAgaWYgKCFzdHlsZS53aWR0aCB8fCAhc3R5bGUuY29sb3IpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY3R4LnNhdmUoKTtcbiAgICAgIGN0eC5saW5lV2lkdGggPSBzdHlsZS53aWR0aDtcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IHN0eWxlLmNvbG9yO1xuICAgICAgY3R4LnNldExpbmVEYXNoKHN0eWxlLmJvcmRlckRhc2ggfHwgW10pO1xuICAgICAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gc3R5bGUuYm9yZGVyRGFzaE9mZnNldDtcblxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgY3R4Lm1vdmVUbyhwMS54LCBwMS55KTtcbiAgICAgIGN0eC5saW5lVG8ocDIueCwgcDIueSk7XG4gICAgICBjdHguc3Ryb2tlKCk7XG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH07XG5cbiAgICBpZiAoZ3JpZC5kaXNwbGF5KSB7XG4gICAgICBmb3IgKGkgPSAwLCBpbGVuID0gaXRlbXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtc1tpXTtcblxuICAgICAgICBpZiAoZ3JpZC5kcmF3T25DaGFydEFyZWEpIHtcbiAgICAgICAgICBkcmF3TGluZShcbiAgICAgICAgICAgIHt4OiBpdGVtLngxLCB5OiBpdGVtLnkxfSxcbiAgICAgICAgICAgIHt4OiBpdGVtLngyLCB5OiBpdGVtLnkyfSxcbiAgICAgICAgICAgIGl0ZW1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGdyaWQuZHJhd1RpY2tzKSB7XG4gICAgICAgICAgZHJhd0xpbmUoXG4gICAgICAgICAgICB7eDogaXRlbS50eDEsIHk6IGl0ZW0udHkxfSxcbiAgICAgICAgICAgIHt4OiBpdGVtLnR4MiwgeTogaXRlbS50eTJ9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb2xvcjogaXRlbS50aWNrQ29sb3IsXG4gICAgICAgICAgICAgIHdpZHRoOiBpdGVtLnRpY2tXaWR0aCxcbiAgICAgICAgICAgICAgYm9yZGVyRGFzaDogaXRlbS50aWNrQm9yZGVyRGFzaCxcbiAgICAgICAgICAgICAgYm9yZGVyRGFzaE9mZnNldDogaXRlbS50aWNrQm9yZGVyRGFzaE9mZnNldFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZHJhd0JvcmRlcigpIHtcbiAgICBjb25zdCB7Y2hhcnQsIGN0eCwgb3B0aW9uczoge2JvcmRlciwgZ3JpZH19ID0gdGhpcztcbiAgICBjb25zdCBib3JkZXJPcHRzID0gYm9yZGVyLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KCkpO1xuICAgIGNvbnN0IGF4aXNXaWR0aCA9IGJvcmRlci5kaXNwbGF5ID8gYm9yZGVyT3B0cy53aWR0aCA6IDA7XG4gICAgaWYgKCFheGlzV2lkdGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGFzdExpbmVXaWR0aCA9IGdyaWQuc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoMCkpLmxpbmVXaWR0aDtcbiAgICBjb25zdCBib3JkZXJWYWx1ZSA9IHRoaXMuX2JvcmRlclZhbHVlO1xuICAgIGxldCB4MSwgeDIsIHkxLCB5MjtcblxuICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICB4MSA9IF9hbGlnblBpeGVsKGNoYXJ0LCB0aGlzLmxlZnQsIGF4aXNXaWR0aCkgLSBheGlzV2lkdGggLyAyO1xuICAgICAgeDIgPSBfYWxpZ25QaXhlbChjaGFydCwgdGhpcy5yaWdodCwgbGFzdExpbmVXaWR0aCkgKyBsYXN0TGluZVdpZHRoIC8gMjtcbiAgICAgIHkxID0geTIgPSBib3JkZXJWYWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgeTEgPSBfYWxpZ25QaXhlbChjaGFydCwgdGhpcy50b3AsIGF4aXNXaWR0aCkgLSBheGlzV2lkdGggLyAyO1xuICAgICAgeTIgPSBfYWxpZ25QaXhlbChjaGFydCwgdGhpcy5ib3R0b20sIGxhc3RMaW5lV2lkdGgpICsgbGFzdExpbmVXaWR0aCAvIDI7XG4gICAgICB4MSA9IHgyID0gYm9yZGVyVmFsdWU7XG4gICAgfVxuICAgIGN0eC5zYXZlKCk7XG4gICAgY3R4LmxpbmVXaWR0aCA9IGJvcmRlck9wdHMud2lkdGg7XG4gICAgY3R4LnN0cm9rZVN0eWxlID0gYm9yZGVyT3B0cy5jb2xvcjtcblxuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHgubW92ZVRvKHgxLCB5MSk7XG4gICAgY3R4LmxpbmVUbyh4MiwgeTIpO1xuICAgIGN0eC5zdHJva2UoKTtcblxuICAgIGN0eC5yZXN0b3JlKCk7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZHJhd0xhYmVscyhjaGFydEFyZWEpIHtcbiAgICBjb25zdCBvcHRpb25UaWNrcyA9IHRoaXMub3B0aW9ucy50aWNrcztcblxuICAgIGlmICghb3B0aW9uVGlja3MuZGlzcGxheSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuXG4gICAgY29uc3QgYXJlYSA9IHRoaXMuX2NvbXB1dGVMYWJlbEFyZWEoKTtcbiAgICBpZiAoYXJlYSkge1xuICAgICAgY2xpcEFyZWEoY3R4LCBhcmVhKTtcbiAgICB9XG5cbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuZ2V0TGFiZWxJdGVtcyhjaGFydEFyZWEpO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgY29uc3QgcmVuZGVyVGV4dE9wdGlvbnMgPSBpdGVtLm9wdGlvbnM7XG4gICAgICBjb25zdCB0aWNrRm9udCA9IGl0ZW0uZm9udDtcbiAgICAgIGNvbnN0IGxhYmVsID0gaXRlbS5sYWJlbDtcbiAgICAgIGNvbnN0IHkgPSBpdGVtLnRleHRPZmZzZXQ7XG4gICAgICByZW5kZXJUZXh0KGN0eCwgbGFiZWwsIDAsIHksIHRpY2tGb250LCByZW5kZXJUZXh0T3B0aW9ucyk7XG4gICAgfVxuXG4gICAgaWYgKGFyZWEpIHtcbiAgICAgIHVuY2xpcEFyZWEoY3R4KTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZHJhd1RpdGxlKCkge1xuICAgIGNvbnN0IHtjdHgsIG9wdGlvbnM6IHtwb3NpdGlvbiwgdGl0bGUsIHJldmVyc2V9fSA9IHRoaXM7XG5cbiAgICBpZiAoIXRpdGxlLmRpc3BsYXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBmb250ID0gdG9Gb250KHRpdGxlLmZvbnQpO1xuICAgIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcodGl0bGUucGFkZGluZyk7XG4gICAgY29uc3QgYWxpZ24gPSB0aXRsZS5hbGlnbjtcbiAgICBsZXQgb2Zmc2V0ID0gZm9udC5saW5lSGVpZ2h0IC8gMjtcblxuICAgIGlmIChwb3NpdGlvbiA9PT0gJ2JvdHRvbScgfHwgcG9zaXRpb24gPT09ICdjZW50ZXInIHx8IGlzT2JqZWN0KHBvc2l0aW9uKSkge1xuICAgICAgb2Zmc2V0ICs9IHBhZGRpbmcuYm90dG9tO1xuICAgICAgaWYgKGlzQXJyYXkodGl0bGUudGV4dCkpIHtcbiAgICAgICAgb2Zmc2V0ICs9IGZvbnQubGluZUhlaWdodCAqICh0aXRsZS50ZXh0Lmxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvZmZzZXQgKz0gcGFkZGluZy50b3A7XG4gICAgfVxuXG4gICAgY29uc3Qge3RpdGxlWCwgdGl0bGVZLCBtYXhXaWR0aCwgcm90YXRpb259ID0gdGl0bGVBcmdzKHRoaXMsIG9mZnNldCwgcG9zaXRpb24sIGFsaWduKTtcblxuICAgIHJlbmRlclRleHQoY3R4LCB0aXRsZS50ZXh0LCAwLCAwLCBmb250LCB7XG4gICAgICBjb2xvcjogdGl0bGUuY29sb3IsXG4gICAgICBtYXhXaWR0aCxcbiAgICAgIHJvdGF0aW9uLFxuICAgICAgdGV4dEFsaWduOiB0aXRsZUFsaWduKGFsaWduLCBwb3NpdGlvbiwgcmV2ZXJzZSksXG4gICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgdHJhbnNsYXRpb246IFt0aXRsZVgsIHRpdGxlWV0sXG4gICAgfSk7XG4gIH1cblxuICBkcmF3KGNoYXJ0QXJlYSkge1xuICAgIGlmICghdGhpcy5faXNWaXNpYmxlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmRyYXdCYWNrZ3JvdW5kKCk7XG4gICAgdGhpcy5kcmF3R3JpZChjaGFydEFyZWEpO1xuICAgIHRoaXMuZHJhd0JvcmRlcigpO1xuICAgIHRoaXMuZHJhd1RpdGxlKCk7XG4gICAgdGhpcy5kcmF3TGFiZWxzKGNoYXJ0QXJlYSk7XG4gIH1cblxuICAvKipcblx0ICogQHJldHVybiB7b2JqZWN0W119XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfbGF5ZXJzKCkge1xuICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgdHogPSBvcHRzLnRpY2tzICYmIG9wdHMudGlja3MueiB8fCAwO1xuICAgIGNvbnN0IGd6ID0gdmFsdWVPckRlZmF1bHQob3B0cy5ncmlkICYmIG9wdHMuZ3JpZC56LCAtMSk7XG4gICAgY29uc3QgYnogPSB2YWx1ZU9yRGVmYXVsdChvcHRzLmJvcmRlciAmJiBvcHRzLmJvcmRlci56LCAwKTtcblxuICAgIGlmICghdGhpcy5faXNWaXNpYmxlKCkgfHwgdGhpcy5kcmF3ICE9PSBTY2FsZS5wcm90b3R5cGUuZHJhdykge1xuICAgICAgLy8gYmFja3dhcmQgY29tcGF0aWJpbGl0eTogZHJhdyBoYXMgYmVlbiBvdmVycmlkZGVuIGJ5IGN1c3RvbSBzY2FsZVxuICAgICAgcmV0dXJuIFt7XG4gICAgICAgIHo6IHR6LFxuICAgICAgICBkcmF3OiAoY2hhcnRBcmVhKSA9PiB7XG4gICAgICAgICAgdGhpcy5kcmF3KGNoYXJ0QXJlYSk7XG4gICAgICAgIH1cbiAgICAgIH1dO1xuICAgIH1cblxuICAgIHJldHVybiBbe1xuICAgICAgejogZ3osXG4gICAgICBkcmF3OiAoY2hhcnRBcmVhKSA9PiB7XG4gICAgICAgIHRoaXMuZHJhd0JhY2tncm91bmQoKTtcbiAgICAgICAgdGhpcy5kcmF3R3JpZChjaGFydEFyZWEpO1xuICAgICAgICB0aGlzLmRyYXdUaXRsZSgpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIHo6IGJ6LFxuICAgICAgZHJhdzogKCkgPT4ge1xuICAgICAgICB0aGlzLmRyYXdCb3JkZXIoKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICB6OiB0eixcbiAgICAgIGRyYXc6IChjaGFydEFyZWEpID0+IHtcbiAgICAgICAgdGhpcy5kcmF3TGFiZWxzKGNoYXJ0QXJlYSk7XG4gICAgICB9XG4gICAgfV07XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB2aXNpYmxlIGRhdGFzZXQgbWV0YXMgdGhhdCBhcmUgYXR0YWNoZWQgdG8gdGhpcyBzY2FsZVxuXHQgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVdIC0gaWYgc3BlY2lmaWVkLCBhbHNvIGZpbHRlciBieSBkYXRhc2V0IHR5cGVcblx0ICogQHJldHVybiB7b2JqZWN0W119XG5cdCAqL1xuICBnZXRNYXRjaGluZ1Zpc2libGVNZXRhcyh0eXBlKSB7XG4gICAgY29uc3QgbWV0YXMgPSB0aGlzLmNoYXJ0LmdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKTtcbiAgICBjb25zdCBheGlzSUQgPSB0aGlzLmF4aXMgKyAnQXhpc0lEJztcbiAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICBsZXQgaSwgaWxlbjtcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBtZXRhcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIGNvbnN0IG1ldGEgPSBtZXRhc1tpXTtcbiAgICAgIGlmIChtZXRhW2F4aXNJRF0gPT09IHRoaXMuaWQgJiYgKCF0eXBlIHx8IG1ldGEudHlwZSA9PT0gdHlwZSkpIHtcbiAgICAgICAgcmVzdWx0LnB1c2gobWV0YSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG5cdCAqIEByZXR1cm4ge29iamVjdH1cblx0ICogQHByb3RlY3RlZFxuIFx0ICovXG4gIF9yZXNvbHZlVGlja0ZvbnRPcHRpb25zKGluZGV4KSB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucy50aWNrcy5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dChpbmRleCkpO1xuICAgIHJldHVybiB0b0ZvbnQob3B0cy5mb250KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBfbWF4RGlnaXRzKCkge1xuICAgIGNvbnN0IGZvbnRTaXplID0gdGhpcy5fcmVzb2x2ZVRpY2tGb250T3B0aW9ucygwKS5saW5lSGVpZ2h0O1xuICAgIHJldHVybiAodGhpcy5pc0hvcml6b250YWwoKSA/IHRoaXMud2lkdGggOiB0aGlzLmhlaWdodCkgLyBmb250U2l6ZTtcbiAgfVxufVxuIiwgImltcG9ydCB7bWVyZ2V9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuaW1wb3J0IGRlZmF1bHRzLCB7b3ZlcnJpZGVzfSBmcm9tICcuL2NvcmUuZGVmYXVsdHMuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHt7aWQ6IHN0cmluZywgZGVmYXVsdHM6IGFueSwgb3ZlcnJpZGVzPzogYW55LCBkZWZhdWx0Um91dGVzOiBhbnl9fSBJQ2hhcnRDb21wb25lbnRcbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUeXBlZFJlZ2lzdHJ5IHtcbiAgY29uc3RydWN0b3IodHlwZSwgc2NvcGUsIG92ZXJyaWRlKSB7XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB0aGlzLnNjb3BlID0gc2NvcGU7XG4gICAgdGhpcy5vdmVycmlkZSA9IG92ZXJyaWRlO1xuICAgIHRoaXMuaXRlbXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB9XG5cbiAgaXNGb3JUeXBlKHR5cGUpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5pc1Byb3RvdHlwZU9mLmNhbGwodGhpcy50eXBlLnByb3RvdHlwZSwgdHlwZS5wcm90b3R5cGUpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7SUNoYXJ0Q29tcG9uZW50fSBpdGVtXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBzY29wZSB3aGVyZSBpdGVtcyBkZWZhdWx0cyB3ZXJlIHJlZ2lzdGVyZWQgdG8uXG5cdCAqL1xuICByZWdpc3RlcihpdGVtKSB7XG4gICAgY29uc3QgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoaXRlbSk7XG4gICAgbGV0IHBhcmVudFNjb3BlO1xuXG4gICAgaWYgKGlzSUNoYXJ0Q29tcG9uZW50KHByb3RvKSkge1xuICAgICAgLy8gTWFrZSBzdXJlIHRoZSBwYXJlbnQgaXMgcmVnaXN0ZXJlZCBhbmQgbm90ZSB0aGUgc2NvcGUgd2hlcmUgaXRzIGRlZmF1bHRzIGFyZS5cbiAgICAgIHBhcmVudFNjb3BlID0gdGhpcy5yZWdpc3Rlcihwcm90byk7XG4gICAgfVxuXG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zO1xuICAgIGNvbnN0IGlkID0gaXRlbS5pZDtcbiAgICBjb25zdCBzY29wZSA9IHRoaXMuc2NvcGUgKyAnLicgKyBpZDtcblxuICAgIGlmICghaWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2xhc3MgZG9lcyBub3QgaGF2ZSBpZDogJyArIGl0ZW0pO1xuICAgIH1cblxuICAgIGlmIChpZCBpbiBpdGVtcykge1xuICAgICAgLy8gYWxyZWFkeSByZWdpc3RlcmVkXG4gICAgICByZXR1cm4gc2NvcGU7XG4gICAgfVxuXG4gICAgaXRlbXNbaWRdID0gaXRlbTtcbiAgICByZWdpc3RlckRlZmF1bHRzKGl0ZW0sIHNjb3BlLCBwYXJlbnRTY29wZSk7XG4gICAgaWYgKHRoaXMub3ZlcnJpZGUpIHtcbiAgICAgIGRlZmF1bHRzLm92ZXJyaWRlKGl0ZW0uaWQsIGl0ZW0ub3ZlcnJpZGVzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2NvcGU7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IGlkXG5cdCAqIEByZXR1cm5zIHtvYmplY3Q/fVxuXHQgKi9cbiAgZ2V0KGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuaXRlbXNbaWRdO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7SUNoYXJ0Q29tcG9uZW50fSBpdGVtXG5cdCAqL1xuICB1bnJlZ2lzdGVyKGl0ZW0pIHtcbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXM7XG4gICAgY29uc3QgaWQgPSBpdGVtLmlkO1xuICAgIGNvbnN0IHNjb3BlID0gdGhpcy5zY29wZTtcblxuICAgIGlmIChpZCBpbiBpdGVtcykge1xuICAgICAgZGVsZXRlIGl0ZW1zW2lkXTtcbiAgICB9XG5cbiAgICBpZiAoc2NvcGUgJiYgaWQgaW4gZGVmYXVsdHNbc2NvcGVdKSB7XG4gICAgICBkZWxldGUgZGVmYXVsdHNbc2NvcGVdW2lkXTtcbiAgICAgIGlmICh0aGlzLm92ZXJyaWRlKSB7XG4gICAgICAgIGRlbGV0ZSBvdmVycmlkZXNbaWRdO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZWdpc3RlckRlZmF1bHRzKGl0ZW0sIHNjb3BlLCBwYXJlbnRTY29wZSkge1xuICAvLyBJbmhlcml0IHRoZSBwYXJlbnQncyBkZWZhdWx0cyBhbmQga2VlcCBleGlzdGluZyBkZWZhdWx0c1xuICBjb25zdCBpdGVtRGVmYXVsdHMgPSBtZXJnZShPYmplY3QuY3JlYXRlKG51bGwpLCBbXG4gICAgcGFyZW50U2NvcGUgPyBkZWZhdWx0cy5nZXQocGFyZW50U2NvcGUpIDoge30sXG4gICAgZGVmYXVsdHMuZ2V0KHNjb3BlKSxcbiAgICBpdGVtLmRlZmF1bHRzXG4gIF0pO1xuXG4gIGRlZmF1bHRzLnNldChzY29wZSwgaXRlbURlZmF1bHRzKTtcblxuICBpZiAoaXRlbS5kZWZhdWx0Um91dGVzKSB7XG4gICAgcm91dGVEZWZhdWx0cyhzY29wZSwgaXRlbS5kZWZhdWx0Um91dGVzKTtcbiAgfVxuXG4gIGlmIChpdGVtLmRlc2NyaXB0b3JzKSB7XG4gICAgZGVmYXVsdHMuZGVzY3JpYmUoc2NvcGUsIGl0ZW0uZGVzY3JpcHRvcnMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJvdXRlRGVmYXVsdHMoc2NvcGUsIHJvdXRlcykge1xuICBPYmplY3Qua2V5cyhyb3V0ZXMpLmZvckVhY2gocHJvcGVydHkgPT4ge1xuICAgIGNvbnN0IHByb3BlcnR5UGFydHMgPSBwcm9wZXJ0eS5zcGxpdCgnLicpO1xuICAgIGNvbnN0IHNvdXJjZU5hbWUgPSBwcm9wZXJ0eVBhcnRzLnBvcCgpO1xuICAgIGNvbnN0IHNvdXJjZVNjb3BlID0gW3Njb3BlXS5jb25jYXQocHJvcGVydHlQYXJ0cykuam9pbignLicpO1xuICAgIGNvbnN0IHBhcnRzID0gcm91dGVzW3Byb3BlcnR5XS5zcGxpdCgnLicpO1xuICAgIGNvbnN0IHRhcmdldE5hbWUgPSBwYXJ0cy5wb3AoKTtcbiAgICBjb25zdCB0YXJnZXRTY29wZSA9IHBhcnRzLmpvaW4oJy4nKTtcbiAgICBkZWZhdWx0cy5yb3V0ZShzb3VyY2VTY29wZSwgc291cmNlTmFtZSwgdGFyZ2V0U2NvcGUsIHRhcmdldE5hbWUpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gaXNJQ2hhcnRDb21wb25lbnQocHJvdG8pIHtcbiAgcmV0dXJuICdpZCcgaW4gcHJvdG8gJiYgJ2RlZmF1bHRzJyBpbiBwcm90bztcbn1cbiIsICJpbXBvcnQgRGF0YXNldENvbnRyb2xsZXIgZnJvbSAnLi9jb3JlLmRhdGFzZXRDb250cm9sbGVyLmpzJztcbmltcG9ydCBFbGVtZW50IGZyb20gJy4vY29yZS5lbGVtZW50LmpzJztcbmltcG9ydCBTY2FsZSBmcm9tICcuL2NvcmUuc2NhbGUuanMnO1xuaW1wb3J0IFR5cGVkUmVnaXN0cnkgZnJvbSAnLi9jb3JlLnR5cGVkUmVnaXN0cnkuanMnO1xuaW1wb3J0IHtlYWNoLCBjYWxsYmFjayBhcyBjYWxsLCBfY2FwaXRhbGl6ZX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuXG4vKipcbiAqIFBsZWFzZSB1c2UgdGhlIG1vZHVsZSdzIGRlZmF1bHQgZXhwb3J0IHdoaWNoIHByb3ZpZGVzIGEgc2luZ2xldG9uIGluc3RhbmNlXG4gKiBOb3RlOiBjbGFzcyBpcyBleHBvcnRlZCBmb3IgdHlwZWRvY1xuICovXG5leHBvcnQgY2xhc3MgUmVnaXN0cnkge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmNvbnRyb2xsZXJzID0gbmV3IFR5cGVkUmVnaXN0cnkoRGF0YXNldENvbnRyb2xsZXIsICdkYXRhc2V0cycsIHRydWUpO1xuICAgIHRoaXMuZWxlbWVudHMgPSBuZXcgVHlwZWRSZWdpc3RyeShFbGVtZW50LCAnZWxlbWVudHMnKTtcbiAgICB0aGlzLnBsdWdpbnMgPSBuZXcgVHlwZWRSZWdpc3RyeShPYmplY3QsICdwbHVnaW5zJyk7XG4gICAgdGhpcy5zY2FsZXMgPSBuZXcgVHlwZWRSZWdpc3RyeShTY2FsZSwgJ3NjYWxlcycpO1xuICAgIC8vIE9yZGVyIGlzIGltcG9ydGFudCwgU2NhbGUgaGFzIEVsZW1lbnQgaW4gcHJvdG90eXBlIGNoYWluLFxuICAgIC8vIHNvIFNjYWxlcyBtdXN0IGJlIGJlZm9yZSBFbGVtZW50cy4gUGx1Z2lucyBhcmUgYSBmYWxsYmFjaywgc28gbm90IGxpc3RlZCBoZXJlLlxuICAgIHRoaXMuX3R5cGVkUmVnaXN0cmllcyA9IFt0aGlzLmNvbnRyb2xsZXJzLCB0aGlzLnNjYWxlcywgdGhpcy5lbGVtZW50c107XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtICB7Li4uYW55fSBhcmdzXG5cdCAqL1xuICBhZGQoLi4uYXJncykge1xuICAgIHRoaXMuX2VhY2goJ3JlZ2lzdGVyJywgYXJncyk7XG4gIH1cblxuICByZW1vdmUoLi4uYXJncykge1xuICAgIHRoaXMuX2VhY2goJ3VucmVnaXN0ZXInLCBhcmdzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0gIHsuLi50eXBlb2YgRGF0YXNldENvbnRyb2xsZXJ9IGFyZ3Ncblx0ICovXG4gIGFkZENvbnRyb2xsZXJzKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9lYWNoKCdyZWdpc3RlcicsIGFyZ3MsIHRoaXMuY29udHJvbGxlcnMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSAgey4uLnR5cGVvZiBFbGVtZW50fSBhcmdzXG5cdCAqL1xuICBhZGRFbGVtZW50cyguLi5hcmdzKSB7XG4gICAgdGhpcy5fZWFjaCgncmVnaXN0ZXInLCBhcmdzLCB0aGlzLmVsZW1lbnRzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0gIHsuLi5hbnl9IGFyZ3Ncblx0ICovXG4gIGFkZFBsdWdpbnMoLi4uYXJncykge1xuICAgIHRoaXMuX2VhY2goJ3JlZ2lzdGVyJywgYXJncywgdGhpcy5wbHVnaW5zKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0gIHsuLi50eXBlb2YgU2NhbGV9IGFyZ3Ncblx0ICovXG4gIGFkZFNjYWxlcyguLi5hcmdzKSB7XG4gICAgdGhpcy5fZWFjaCgncmVnaXN0ZXInLCBhcmdzLCB0aGlzLnNjYWxlcyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IGlkXG5cdCAqIEByZXR1cm5zIHt0eXBlb2YgRGF0YXNldENvbnRyb2xsZXJ9XG5cdCAqL1xuICBnZXRDb250cm9sbGVyKGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldChpZCwgdGhpcy5jb250cm9sbGVycywgJ2NvbnRyb2xsZXInKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaWRcblx0ICogQHJldHVybnMge3R5cGVvZiBFbGVtZW50fVxuXHQgKi9cbiAgZ2V0RWxlbWVudChpZCkge1xuICAgIHJldHVybiB0aGlzLl9nZXQoaWQsIHRoaXMuZWxlbWVudHMsICdlbGVtZW50Jyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IGlkXG5cdCAqIEByZXR1cm5zIHtvYmplY3R9XG5cdCAqL1xuICBnZXRQbHVnaW4oaWQpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0KGlkLCB0aGlzLnBsdWdpbnMsICdwbHVnaW4nKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaWRcblx0ICogQHJldHVybnMge3R5cGVvZiBTY2FsZX1cblx0ICovXG4gIGdldFNjYWxlKGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldChpZCwgdGhpcy5zY2FsZXMsICdzY2FsZScpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSAgey4uLnR5cGVvZiBEYXRhc2V0Q29udHJvbGxlcn0gYXJnc1xuXHQgKi9cbiAgcmVtb3ZlQ29udHJvbGxlcnMoLi4uYXJncykge1xuICAgIHRoaXMuX2VhY2goJ3VucmVnaXN0ZXInLCBhcmdzLCB0aGlzLmNvbnRyb2xsZXJzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0gIHsuLi50eXBlb2YgRWxlbWVudH0gYXJnc1xuXHQgKi9cbiAgcmVtb3ZlRWxlbWVudHMoLi4uYXJncykge1xuICAgIHRoaXMuX2VhY2goJ3VucmVnaXN0ZXInLCBhcmdzLCB0aGlzLmVsZW1lbnRzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0gIHsuLi5hbnl9IGFyZ3Ncblx0ICovXG4gIHJlbW92ZVBsdWdpbnMoLi4uYXJncykge1xuICAgIHRoaXMuX2VhY2goJ3VucmVnaXN0ZXInLCBhcmdzLCB0aGlzLnBsdWdpbnMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSAgey4uLnR5cGVvZiBTY2FsZX0gYXJnc1xuXHQgKi9cbiAgcmVtb3ZlU2NhbGVzKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9lYWNoKCd1bnJlZ2lzdGVyJywgYXJncywgdGhpcy5zY2FsZXMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZWFjaChtZXRob2QsIGFyZ3MsIHR5cGVkUmVnaXN0cnkpIHtcbiAgICBbLi4uYXJnc10uZm9yRWFjaChhcmcgPT4ge1xuICAgICAgY29uc3QgcmVnID0gdHlwZWRSZWdpc3RyeSB8fCB0aGlzLl9nZXRSZWdpc3RyeUZvclR5cGUoYXJnKTtcbiAgICAgIGlmICh0eXBlZFJlZ2lzdHJ5IHx8IHJlZy5pc0ZvclR5cGUoYXJnKSB8fCAocmVnID09PSB0aGlzLnBsdWdpbnMgJiYgYXJnLmlkKSkge1xuICAgICAgICB0aGlzLl9leGVjKG1ldGhvZCwgcmVnLCBhcmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSGFuZGxlIGxvb3BhYmxlIGFyZ3NcbiAgICAgICAgLy8gVXNlIGNhc2U6XG4gICAgICAgIC8vICBpbXBvcnQgKiBhcyBwbHVnaW5zIGZyb20gJy4vcGx1Z2lucy5qcyc7XG4gICAgICAgIC8vICBDaGFydC5yZWdpc3RlcihwbHVnaW5zKTtcbiAgICAgICAgZWFjaChhcmcsIGl0ZW0gPT4ge1xuICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBtaXhlZCB0eXBlcyBpbiB0aGUgbG9vcGFibGUsIG1ha2Ugc3VyZSB0aG9zZSBhcmVcbiAgICAgICAgICAvLyByZWdpc3RlcmVkIGluIGNvcnJlY3QgcmVnaXN0cnlcbiAgICAgICAgICAvLyBVc2UgY2FzZTogKHRyZWVtYXAgZXhwb3J0aW5nIGNvbnRyb2xsZXIsIGVsZW1lbnRzIGV0YylcbiAgICAgICAgICAvLyAgaW1wb3J0ICogYXMgdHJlZW1hcCBmcm9tICdjaGFydGpzLWNoYXJ0LXRyZWVtYXAuanMnO1xuICAgICAgICAgIC8vICBDaGFydC5yZWdpc3Rlcih0cmVlbWFwKTtcblxuICAgICAgICAgIGNvbnN0IGl0ZW1SZWcgPSB0eXBlZFJlZ2lzdHJ5IHx8IHRoaXMuX2dldFJlZ2lzdHJ5Rm9yVHlwZShpdGVtKTtcbiAgICAgICAgICB0aGlzLl9leGVjKG1ldGhvZCwgaXRlbVJlZywgaXRlbSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZXhlYyhtZXRob2QsIHJlZ2lzdHJ5LCBjb21wb25lbnQpIHtcbiAgICBjb25zdCBjYW1lbE1ldGhvZCA9IF9jYXBpdGFsaXplKG1ldGhvZCk7XG4gICAgY2FsbChjb21wb25lbnRbJ2JlZm9yZScgKyBjYW1lbE1ldGhvZF0sIFtdLCBjb21wb25lbnQpOyAvLyBiZWZvcmVSZWdpc3RlciAvIGJlZm9yZVVucmVnaXN0ZXJcbiAgICByZWdpc3RyeVttZXRob2RdKGNvbXBvbmVudCk7XG4gICAgY2FsbChjb21wb25lbnRbJ2FmdGVyJyArIGNhbWVsTWV0aG9kXSwgW10sIGNvbXBvbmVudCk7IC8vIGFmdGVyUmVnaXN0ZXIgLyBhZnRlclVucmVnaXN0ZXJcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldFJlZ2lzdHJ5Rm9yVHlwZSh0eXBlKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl90eXBlZFJlZ2lzdHJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJlZyA9IHRoaXMuX3R5cGVkUmVnaXN0cmllc1tpXTtcbiAgICAgIGlmIChyZWcuaXNGb3JUeXBlKHR5cGUpKSB7XG4gICAgICAgIHJldHVybiByZWc7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIHBsdWdpbnMgaXMgdGhlIGZhbGxiYWNrIHJlZ2lzdHJ5XG4gICAgcmV0dXJuIHRoaXMucGx1Z2lucztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldChpZCwgdHlwZWRSZWdpc3RyeSwgdHlwZSkge1xuICAgIGNvbnN0IGl0ZW0gPSB0eXBlZFJlZ2lzdHJ5LmdldChpZCk7XG4gICAgaWYgKGl0ZW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdcIicgKyBpZCArICdcIiBpcyBub3QgYSByZWdpc3RlcmVkICcgKyB0eXBlICsgJy4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGl0ZW07XG4gIH1cblxufVxuXG4vLyBzaW5nbGV0b24gaW5zdGFuY2VcbmV4cG9ydCBkZWZhdWx0IC8qICNfX1BVUkVfXyAqLyBuZXcgUmVnaXN0cnkoKTtcbiIsICJpbXBvcnQgcmVnaXN0cnkgZnJvbSAnLi9jb3JlLnJlZ2lzdHJ5LmpzJztcbmltcG9ydCB7Y2FsbGJhY2sgYXMgY2FsbENhbGxiYWNrLCBpc051bGxPclVuZGVmLCB2YWx1ZU9yRGVmYXVsdH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuL2NvcmUuY29udHJvbGxlci5qcycpLmRlZmF1bHQgfSBDaGFydFxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL3R5cGVzL2luZGV4LmpzJykuQ2hhcnRFdmVudCB9IENoYXJ0RXZlbnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi9wbHVnaW5zL3BsdWdpbi50b29sdGlwLmpzJykuZGVmYXVsdCB9IFRvb2x0aXBcbiAqL1xuXG4vKipcbiAqIEBjYWxsYmFjayBmaWx0ZXJDYWxsYmFja1xuICogQHBhcmFtIHt7cGx1Z2luOiBvYmplY3QsIG9wdGlvbnM6IG9iamVjdH19IHZhbHVlXG4gKiBAcGFyYW0ge251bWJlcn0gW2luZGV4XVxuICogQHBhcmFtIHthcnJheX0gW2FycmF5XVxuICogQHBhcmFtIHtvYmplY3R9IFt0aGlzQXJnXVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBsdWdpblNlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9pbml0ID0gW107XG4gIH1cblxuICAvKipcblx0ICogQ2FsbHMgZW5hYmxlZCBwbHVnaW5zIGZvciBgY2hhcnRgIG9uIHRoZSBzcGVjaWZpZWQgaG9vayBhbmQgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cblx0ICogVGhpcyBtZXRob2QgaW1tZWRpYXRlbHkgcmV0dXJucyBhcyBzb29uIGFzIGEgcGx1Z2luIGV4cGxpY2l0bHkgcmV0dXJucyBmYWxzZS4gVGhlXG5cdCAqIHJldHVybmVkIHZhbHVlIGNhbiBiZSB1c2VkLCBmb3IgaW5zdGFuY2UsIHRvIGludGVycnVwdCB0aGUgY3VycmVudCBhY3Rpb24uXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gVGhlIGNoYXJ0IGluc3RhbmNlIGZvciB3aGljaCBwbHVnaW5zIHNob3VsZCBiZSBjYWxsZWQuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBob29rIC0gVGhlIG5hbWUgb2YgdGhlIHBsdWdpbiBtZXRob2QgdG8gY2FsbCAoZS5nLiAnYmVmb3JlVXBkYXRlJykuXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbYXJnc10gLSBFeHRyYSBhcmd1bWVudHMgdG8gYXBwbHkgdG8gdGhlIGhvb2sgY2FsbC5cbiAgICogQHBhcmFtIHtmaWx0ZXJDYWxsYmFja30gW2ZpbHRlcl0gLSBGaWx0ZXJpbmcgZnVuY3Rpb24gZm9yIGxpbWl0aW5nIHdoaWNoIHBsdWdpbnMgYXJlIG5vdGlmaWVkXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBmYWxzZSBpZiBhbnkgb2YgdGhlIHBsdWdpbnMgcmV0dXJuIGZhbHNlLCBlbHNlIHJldHVybnMgdHJ1ZS5cblx0ICovXG4gIG5vdGlmeShjaGFydCwgaG9vaywgYXJncywgZmlsdGVyKSB7XG4gICAgaWYgKGhvb2sgPT09ICdiZWZvcmVJbml0Jykge1xuICAgICAgdGhpcy5faW5pdCA9IHRoaXMuX2NyZWF0ZURlc2NyaXB0b3JzKGNoYXJ0LCB0cnVlKTtcbiAgICAgIHRoaXMuX25vdGlmeSh0aGlzLl9pbml0LCBjaGFydCwgJ2luc3RhbGwnKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXNjcmlwdG9ycyA9IGZpbHRlciA/IHRoaXMuX2Rlc2NyaXB0b3JzKGNoYXJ0KS5maWx0ZXIoZmlsdGVyKSA6IHRoaXMuX2Rlc2NyaXB0b3JzKGNoYXJ0KTtcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9ub3RpZnkoZGVzY3JpcHRvcnMsIGNoYXJ0LCBob29rLCBhcmdzKTtcblxuICAgIGlmIChob29rID09PSAnYWZ0ZXJEZXN0cm95Jykge1xuICAgICAgdGhpcy5fbm90aWZ5KGRlc2NyaXB0b3JzLCBjaGFydCwgJ3N0b3AnKTtcbiAgICAgIHRoaXMuX25vdGlmeSh0aGlzLl9pbml0LCBjaGFydCwgJ3VuaW5zdGFsbCcpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfbm90aWZ5KGRlc2NyaXB0b3JzLCBjaGFydCwgaG9vaywgYXJncykge1xuICAgIGFyZ3MgPSBhcmdzIHx8IHt9O1xuICAgIGZvciAoY29uc3QgZGVzY3JpcHRvciBvZiBkZXNjcmlwdG9ycykge1xuICAgICAgY29uc3QgcGx1Z2luID0gZGVzY3JpcHRvci5wbHVnaW47XG4gICAgICBjb25zdCBtZXRob2QgPSBwbHVnaW5baG9va107XG4gICAgICBjb25zdCBwYXJhbXMgPSBbY2hhcnQsIGFyZ3MsIGRlc2NyaXB0b3Iub3B0aW9uc107XG4gICAgICBpZiAoY2FsbENhbGxiYWNrKG1ldGhvZCwgcGFyYW1zLCBwbHVnaW4pID09PSBmYWxzZSAmJiBhcmdzLmNhbmNlbGFibGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaW52YWxpZGF0ZSgpIHtcbiAgICAvLyBXaGVuIHBsdWdpbnMgYXJlIHJlZ2lzdGVyZWQsIHRoZXJlIGlzIHRoZSBwb3NzaWJpbGl0eSBvZiBhIGRvdWJsZVxuICAgIC8vIGludmFsaWRhdGUgc2l0dWF0aW9uLiBJbiB0aGlzIGNhc2UsIHdlIG9ubHkgd2FudCB0byBpbnZhbGlkYXRlIG9uY2UuXG4gICAgLy8gSWYgd2UgaW52YWxpZGF0ZSBtdWx0aXBsZSB0aW1lcywgdGhlIGBfb2xkQ2FjaGVgIGlzIGxvc3QgYW5kIGFsbCBvZiB0aGVcbiAgICAvLyBwbHVnaW5zIGFyZSByZXN0YXJ0ZWQgd2l0aG91dCBiZWluZyBjb3JyZWN0bHkgc3RvcHBlZC5cbiAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzgxNDdcbiAgICBpZiAoIWlzTnVsbE9yVW5kZWYodGhpcy5fY2FjaGUpKSB7XG4gICAgICB0aGlzLl9vbGRDYWNoZSA9IHRoaXMuX2NhY2hlO1xuICAgICAgdGhpcy5fY2FjaGUgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZGVzY3JpcHRvcnMoY2hhcnQpIHtcbiAgICBpZiAodGhpcy5fY2FjaGUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXNjcmlwdG9ycyA9IHRoaXMuX2NhY2hlID0gdGhpcy5fY3JlYXRlRGVzY3JpcHRvcnMoY2hhcnQpO1xuXG4gICAgdGhpcy5fbm90aWZ5U3RhdGVDaGFuZ2VzKGNoYXJ0KTtcblxuICAgIHJldHVybiBkZXNjcmlwdG9ycztcbiAgfVxuXG4gIF9jcmVhdGVEZXNjcmlwdG9ycyhjaGFydCwgYWxsKSB7XG4gICAgY29uc3QgY29uZmlnID0gY2hhcnQgJiYgY2hhcnQuY29uZmlnO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB2YWx1ZU9yRGVmYXVsdChjb25maWcub3B0aW9ucyAmJiBjb25maWcub3B0aW9ucy5wbHVnaW5zLCB7fSk7XG4gICAgY29uc3QgcGx1Z2lucyA9IGFsbFBsdWdpbnMoY29uZmlnKTtcbiAgICAvLyBvcHRpb25zID09PSBmYWxzZSA9PiBhbGwgcGx1Z2lucyBhcmUgZGlzYWJsZWRcbiAgICByZXR1cm4gb3B0aW9ucyA9PT0gZmFsc2UgJiYgIWFsbCA/IFtdIDogY3JlYXRlRGVzY3JpcHRvcnMoY2hhcnQsIHBsdWdpbnMsIG9wdGlvbnMsIGFsbCk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnRcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9ub3RpZnlTdGF0ZUNoYW5nZXMoY2hhcnQpIHtcbiAgICBjb25zdCBwcmV2aW91c0Rlc2NyaXB0b3JzID0gdGhpcy5fb2xkQ2FjaGUgfHwgW107XG4gICAgY29uc3QgZGVzY3JpcHRvcnMgPSB0aGlzLl9jYWNoZTtcbiAgICBjb25zdCBkaWZmID0gKGEsIGIpID0+IGEuZmlsdGVyKHggPT4gIWIuc29tZSh5ID0+IHgucGx1Z2luLmlkID09PSB5LnBsdWdpbi5pZCkpO1xuICAgIHRoaXMuX25vdGlmeShkaWZmKHByZXZpb3VzRGVzY3JpcHRvcnMsIGRlc2NyaXB0b3JzKSwgY2hhcnQsICdzdG9wJyk7XG4gICAgdGhpcy5fbm90aWZ5KGRpZmYoZGVzY3JpcHRvcnMsIHByZXZpb3VzRGVzY3JpcHRvcnMpLCBjaGFydCwgJ3N0YXJ0Jyk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydCgnLi9jb3JlLmNvbmZpZy5qcycpLmRlZmF1bHR9IGNvbmZpZ1xuICovXG5mdW5jdGlvbiBhbGxQbHVnaW5zKGNvbmZpZykge1xuICBjb25zdCBsb2NhbElkcyA9IHt9O1xuICBjb25zdCBwbHVnaW5zID0gW107XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhyZWdpc3RyeS5wbHVnaW5zLml0ZW1zKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgcGx1Z2lucy5wdXNoKHJlZ2lzdHJ5LmdldFBsdWdpbihrZXlzW2ldKSk7XG4gIH1cblxuICBjb25zdCBsb2NhbCA9IGNvbmZpZy5wbHVnaW5zIHx8IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxvY2FsLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgcGx1Z2luID0gbG9jYWxbaV07XG5cbiAgICBpZiAocGx1Z2lucy5pbmRleE9mKHBsdWdpbikgPT09IC0xKSB7XG4gICAgICBwbHVnaW5zLnB1c2gocGx1Z2luKTtcbiAgICAgIGxvY2FsSWRzW3BsdWdpbi5pZF0gPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7cGx1Z2lucywgbG9jYWxJZHN9O1xufVxuXG5mdW5jdGlvbiBnZXRPcHRzKG9wdGlvbnMsIGFsbCkge1xuICBpZiAoIWFsbCAmJiBvcHRpb25zID09PSBmYWxzZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmIChvcHRpb25zID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIHJldHVybiBvcHRpb25zO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVEZXNjcmlwdG9ycyhjaGFydCwge3BsdWdpbnMsIGxvY2FsSWRzfSwgb3B0aW9ucywgYWxsKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBjb250ZXh0ID0gY2hhcnQuZ2V0Q29udGV4dCgpO1xuXG4gIGZvciAoY29uc3QgcGx1Z2luIG9mIHBsdWdpbnMpIHtcbiAgICBjb25zdCBpZCA9IHBsdWdpbi5pZDtcbiAgICBjb25zdCBvcHRzID0gZ2V0T3B0cyhvcHRpb25zW2lkXSwgYWxsKTtcbiAgICBpZiAob3B0cyA9PT0gbnVsbCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgIHBsdWdpbixcbiAgICAgIG9wdGlvbnM6IHBsdWdpbk9wdHMoY2hhcnQuY29uZmlnLCB7cGx1Z2luLCBsb2NhbDogbG9jYWxJZHNbaWRdfSwgb3B0cywgY29udGV4dClcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHBsdWdpbk9wdHMoY29uZmlnLCB7cGx1Z2luLCBsb2NhbH0sIG9wdHMsIGNvbnRleHQpIHtcbiAgY29uc3Qga2V5cyA9IGNvbmZpZy5wbHVnaW5TY29wZUtleXMocGx1Z2luKTtcbiAgY29uc3Qgc2NvcGVzID0gY29uZmlnLmdldE9wdGlvblNjb3BlcyhvcHRzLCBrZXlzKTtcbiAgaWYgKGxvY2FsICYmIHBsdWdpbi5kZWZhdWx0cykge1xuICAgIC8vIG1ha2Ugc3VyZSBwbHVnaW4gZGVmYXVsdHMgYXJlIGluIHNjb3BlcyBmb3IgbG9jYWwgKG5vdCByZWdpc3RlcmVkKSBwbHVnaW5zXG4gICAgc2NvcGVzLnB1c2gocGx1Z2luLmRlZmF1bHRzKTtcbiAgfVxuICByZXR1cm4gY29uZmlnLmNyZWF0ZVJlc29sdmVyKHNjb3BlcywgY29udGV4dCwgWycnXSwge1xuICAgIC8vIFRoZXNlIGFyZSBqdXN0IGRlZmF1bHRzIHRoYXQgcGx1Z2lucyBjYW4gb3ZlcnJpZGVcbiAgICBzY3JpcHRhYmxlOiBmYWxzZSxcbiAgICBpbmRleGFibGU6IGZhbHNlLFxuICAgIGFsbEtleXM6IHRydWVcbiAgfSk7XG59XG4iLCAiaW1wb3J0IGRlZmF1bHRzLCB7b3ZlcnJpZGVzLCBkZXNjcmlwdG9yc30gZnJvbSAnLi9jb3JlLmRlZmF1bHRzLmpzJztcbmltcG9ydCB7bWVyZ2VJZiwgcmVzb2x2ZU9iamVjdEtleSwgaXNBcnJheSwgaXNGdW5jdGlvbiwgdmFsdWVPckRlZmF1bHQsIGlzT2JqZWN0fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge19hdHRhY2hDb250ZXh0LCBfY3JlYXRlUmVzb2x2ZXIsIF9kZXNjcmlwdG9yc30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvbmZpZy5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbmRleEF4aXModHlwZSwgb3B0aW9ucykge1xuICBjb25zdCBkYXRhc2V0RGVmYXVsdHMgPSBkZWZhdWx0cy5kYXRhc2V0c1t0eXBlXSB8fCB7fTtcbiAgY29uc3QgZGF0YXNldE9wdGlvbnMgPSAob3B0aW9ucy5kYXRhc2V0cyB8fCB7fSlbdHlwZV0gfHwge307XG4gIHJldHVybiBkYXRhc2V0T3B0aW9ucy5pbmRleEF4aXMgfHwgb3B0aW9ucy5pbmRleEF4aXMgfHwgZGF0YXNldERlZmF1bHRzLmluZGV4QXhpcyB8fCAneCc7XG59XG5cbmZ1bmN0aW9uIGdldEF4aXNGcm9tRGVmYXVsdFNjYWxlSUQoaWQsIGluZGV4QXhpcykge1xuICBsZXQgYXhpcyA9IGlkO1xuICBpZiAoaWQgPT09ICdfaW5kZXhfJykge1xuICAgIGF4aXMgPSBpbmRleEF4aXM7XG4gIH0gZWxzZSBpZiAoaWQgPT09ICdfdmFsdWVfJykge1xuICAgIGF4aXMgPSBpbmRleEF4aXMgPT09ICd4JyA/ICd5JyA6ICd4JztcbiAgfVxuICByZXR1cm4gYXhpcztcbn1cblxuZnVuY3Rpb24gZ2V0RGVmYXVsdFNjYWxlSURGcm9tQXhpcyhheGlzLCBpbmRleEF4aXMpIHtcbiAgcmV0dXJuIGF4aXMgPT09IGluZGV4QXhpcyA/ICdfaW5kZXhfJyA6ICdfdmFsdWVfJztcbn1cblxuZnVuY3Rpb24gaWRNYXRjaGVzQXhpcyhpZCkge1xuICBpZiAoaWQgPT09ICd4JyB8fCBpZCA9PT0gJ3knIHx8IGlkID09PSAncicpIHtcbiAgICByZXR1cm4gaWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXhpc0Zyb21Qb3NpdGlvbihwb3NpdGlvbikge1xuICBpZiAocG9zaXRpb24gPT09ICd0b3AnIHx8IHBvc2l0aW9uID09PSAnYm90dG9tJykge1xuICAgIHJldHVybiAneCc7XG4gIH1cbiAgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcgfHwgcG9zaXRpb24gPT09ICdyaWdodCcpIHtcbiAgICByZXR1cm4gJ3knO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZXRlcm1pbmVBeGlzKGlkLCAuLi5zY2FsZU9wdGlvbnMpIHtcbiAgaWYgKGlkTWF0Y2hlc0F4aXMoaWQpKSB7XG4gICAgcmV0dXJuIGlkO1xuICB9XG4gIGZvciAoY29uc3Qgb3B0cyBvZiBzY2FsZU9wdGlvbnMpIHtcbiAgICBjb25zdCBheGlzID0gb3B0cy5heGlzXG4gICAgICB8fCBheGlzRnJvbVBvc2l0aW9uKG9wdHMucG9zaXRpb24pXG4gICAgICB8fCBpZC5sZW5ndGggPiAxICYmIGlkTWF0Y2hlc0F4aXMoaWRbMF0udG9Mb3dlckNhc2UoKSk7XG4gICAgaWYgKGF4aXMpIHtcbiAgICAgIHJldHVybiBheGlzO1xuICAgIH1cbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBkZXRlcm1pbmUgdHlwZSBvZiAnJHtpZH0nIGF4aXMuIFBsZWFzZSBwcm92aWRlICdheGlzJyBvciAncG9zaXRpb24nIG9wdGlvbi5gKTtcbn1cblxuZnVuY3Rpb24gZ2V0QXhpc0Zyb21EYXRhc2V0KGlkLCBheGlzLCBkYXRhc2V0KSB7XG4gIGlmIChkYXRhc2V0W2F4aXMgKyAnQXhpc0lEJ10gPT09IGlkKSB7XG4gICAgcmV0dXJuIHtheGlzfTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXRyaWV2ZUF4aXNGcm9tRGF0YXNldHMoaWQsIGNvbmZpZykge1xuICBpZiAoY29uZmlnLmRhdGEgJiYgY29uZmlnLmRhdGEuZGF0YXNldHMpIHtcbiAgICBjb25zdCBib3VuZERzID0gY29uZmlnLmRhdGEuZGF0YXNldHMuZmlsdGVyKChkKSA9PiBkLnhBeGlzSUQgPT09IGlkIHx8IGQueUF4aXNJRCA9PT0gaWQpO1xuICAgIGlmIChib3VuZERzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGdldEF4aXNGcm9tRGF0YXNldChpZCwgJ3gnLCBib3VuZERzWzBdKSB8fCBnZXRBeGlzRnJvbURhdGFzZXQoaWQsICd5JywgYm91bmREc1swXSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7fTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VTY2FsZUNvbmZpZyhjb25maWcsIG9wdGlvbnMpIHtcbiAgY29uc3QgY2hhcnREZWZhdWx0cyA9IG92ZXJyaWRlc1tjb25maWcudHlwZV0gfHwge3NjYWxlczoge319O1xuICBjb25zdCBjb25maWdTY2FsZXMgPSBvcHRpb25zLnNjYWxlcyB8fCB7fTtcbiAgY29uc3QgY2hhcnRJbmRleEF4aXMgPSBnZXRJbmRleEF4aXMoY29uZmlnLnR5cGUsIG9wdGlvbnMpO1xuICBjb25zdCBzY2FsZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gIC8vIEZpcnN0IGZpZ3VyZSBvdXQgZmlyc3Qgc2NhbGUgaWQncyBwZXIgYXhpcy5cbiAgT2JqZWN0LmtleXMoY29uZmlnU2NhbGVzKS5mb3JFYWNoKGlkID0+IHtcbiAgICBjb25zdCBzY2FsZUNvbmYgPSBjb25maWdTY2FsZXNbaWRdO1xuICAgIGlmICghaXNPYmplY3Qoc2NhbGVDb25mKSkge1xuICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEludmFsaWQgc2NhbGUgY29uZmlndXJhdGlvbiBmb3Igc2NhbGU6ICR7aWR9YCk7XG4gICAgfVxuICAgIGlmIChzY2FsZUNvbmYuX3Byb3h5KSB7XG4gICAgICByZXR1cm4gY29uc29sZS53YXJuKGBJZ25vcmluZyByZXNvbHZlciBwYXNzZWQgYXMgb3B0aW9ucyBmb3Igc2NhbGU6ICR7aWR9YCk7XG4gICAgfVxuICAgIGNvbnN0IGF4aXMgPSBkZXRlcm1pbmVBeGlzKGlkLCBzY2FsZUNvbmYsIHJldHJpZXZlQXhpc0Zyb21EYXRhc2V0cyhpZCwgY29uZmlnKSwgZGVmYXVsdHMuc2NhbGVzW3NjYWxlQ29uZi50eXBlXSk7XG4gICAgY29uc3QgZGVmYXVsdElkID0gZ2V0RGVmYXVsdFNjYWxlSURGcm9tQXhpcyhheGlzLCBjaGFydEluZGV4QXhpcyk7XG4gICAgY29uc3QgZGVmYXVsdFNjYWxlT3B0aW9ucyA9IGNoYXJ0RGVmYXVsdHMuc2NhbGVzIHx8IHt9O1xuICAgIHNjYWxlc1tpZF0gPSBtZXJnZUlmKE9iamVjdC5jcmVhdGUobnVsbCksIFt7YXhpc30sIHNjYWxlQ29uZiwgZGVmYXVsdFNjYWxlT3B0aW9uc1theGlzXSwgZGVmYXVsdFNjYWxlT3B0aW9uc1tkZWZhdWx0SWRdXSk7XG4gIH0pO1xuXG4gIC8vIFRoZW4gbWVyZ2UgZGF0YXNldCBkZWZhdWx0cyB0byBzY2FsZSBjb25maWdzXG4gIGNvbmZpZy5kYXRhLmRhdGFzZXRzLmZvckVhY2goZGF0YXNldCA9PiB7XG4gICAgY29uc3QgdHlwZSA9IGRhdGFzZXQudHlwZSB8fCBjb25maWcudHlwZTtcbiAgICBjb25zdCBpbmRleEF4aXMgPSBkYXRhc2V0LmluZGV4QXhpcyB8fCBnZXRJbmRleEF4aXModHlwZSwgb3B0aW9ucyk7XG4gICAgY29uc3QgZGF0YXNldERlZmF1bHRzID0gb3ZlcnJpZGVzW3R5cGVdIHx8IHt9O1xuICAgIGNvbnN0IGRlZmF1bHRTY2FsZU9wdGlvbnMgPSBkYXRhc2V0RGVmYXVsdHMuc2NhbGVzIHx8IHt9O1xuICAgIE9iamVjdC5rZXlzKGRlZmF1bHRTY2FsZU9wdGlvbnMpLmZvckVhY2goZGVmYXVsdElEID0+IHtcbiAgICAgIGNvbnN0IGF4aXMgPSBnZXRBeGlzRnJvbURlZmF1bHRTY2FsZUlEKGRlZmF1bHRJRCwgaW5kZXhBeGlzKTtcbiAgICAgIGNvbnN0IGlkID0gZGF0YXNldFtheGlzICsgJ0F4aXNJRCddIHx8IGF4aXM7XG4gICAgICBzY2FsZXNbaWRdID0gc2NhbGVzW2lkXSB8fCBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgbWVyZ2VJZihzY2FsZXNbaWRdLCBbe2F4aXN9LCBjb25maWdTY2FsZXNbaWRdLCBkZWZhdWx0U2NhbGVPcHRpb25zW2RlZmF1bHRJRF1dKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gYXBwbHkgc2NhbGUgZGVmYXVsdHMsIGlmIG5vdCBvdmVycmlkZGVuIGJ5IGRhdGFzZXQgZGVmYXVsdHNcbiAgT2JqZWN0LmtleXMoc2NhbGVzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgY29uc3Qgc2NhbGUgPSBzY2FsZXNba2V5XTtcbiAgICBtZXJnZUlmKHNjYWxlLCBbZGVmYXVsdHMuc2NhbGVzW3NjYWxlLnR5cGVdLCBkZWZhdWx0cy5zY2FsZV0pO1xuICB9KTtcblxuICByZXR1cm4gc2NhbGVzO1xufVxuXG5mdW5jdGlvbiBpbml0T3B0aW9ucyhjb25maWcpIHtcbiAgY29uc3Qgb3B0aW9ucyA9IGNvbmZpZy5vcHRpb25zIHx8IChjb25maWcub3B0aW9ucyA9IHt9KTtcblxuICBvcHRpb25zLnBsdWdpbnMgPSB2YWx1ZU9yRGVmYXVsdChvcHRpb25zLnBsdWdpbnMsIHt9KTtcbiAgb3B0aW9ucy5zY2FsZXMgPSBtZXJnZVNjYWxlQ29uZmlnKGNvbmZpZywgb3B0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGluaXREYXRhKGRhdGEpIHtcbiAgZGF0YSA9IGRhdGEgfHwge307XG4gIGRhdGEuZGF0YXNldHMgPSBkYXRhLmRhdGFzZXRzIHx8IFtdO1xuICBkYXRhLmxhYmVscyA9IGRhdGEubGFiZWxzIHx8IFtdO1xuICByZXR1cm4gZGF0YTtcbn1cblxuZnVuY3Rpb24gaW5pdENvbmZpZyhjb25maWcpIHtcbiAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICBjb25maWcuZGF0YSA9IGluaXREYXRhKGNvbmZpZy5kYXRhKTtcblxuICBpbml0T3B0aW9ucyhjb25maWcpO1xuXG4gIHJldHVybiBjb25maWc7XG59XG5cbmNvbnN0IGtleUNhY2hlID0gbmV3IE1hcCgpO1xuY29uc3Qga2V5c0NhY2hlZCA9IG5ldyBTZXQoKTtcblxuZnVuY3Rpb24gY2FjaGVkS2V5cyhjYWNoZUtleSwgZ2VuZXJhdGUpIHtcbiAgbGV0IGtleXMgPSBrZXlDYWNoZS5nZXQoY2FjaGVLZXkpO1xuICBpZiAoIWtleXMpIHtcbiAgICBrZXlzID0gZ2VuZXJhdGUoKTtcbiAgICBrZXlDYWNoZS5zZXQoY2FjaGVLZXksIGtleXMpO1xuICAgIGtleXNDYWNoZWQuYWRkKGtleXMpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufVxuXG5jb25zdCBhZGRJZkZvdW5kID0gKHNldCwgb2JqLCBrZXkpID0+IHtcbiAgY29uc3Qgb3B0cyA9IHJlc29sdmVPYmplY3RLZXkob2JqLCBrZXkpO1xuICBpZiAob3B0cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgc2V0LmFkZChvcHRzKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29uZmlnIHtcbiAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgdGhpcy5fY29uZmlnID0gaW5pdENvbmZpZyhjb25maWcpO1xuICAgIHRoaXMuX3Njb3BlQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5fcmVzb2x2ZXJDYWNoZSA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIGdldCBwbGF0Zm9ybSgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLnBsYXRmb3JtO1xuICB9XG5cbiAgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZy50eXBlO1xuICB9XG5cbiAgc2V0IHR5cGUodHlwZSkge1xuICAgIHRoaXMuX2NvbmZpZy50eXBlID0gdHlwZTtcbiAgfVxuXG4gIGdldCBkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLl9jb25maWcuZGF0YTtcbiAgfVxuXG4gIHNldCBkYXRhKGRhdGEpIHtcbiAgICB0aGlzLl9jb25maWcuZGF0YSA9IGluaXREYXRhKGRhdGEpO1xuICB9XG5cbiAgZ2V0IG9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZy5vcHRpb25zO1xuICB9XG5cbiAgc2V0IG9wdGlvbnMob3B0aW9ucykge1xuICAgIHRoaXMuX2NvbmZpZy5vcHRpb25zID0gb3B0aW9ucztcbiAgfVxuXG4gIGdldCBwbHVnaW5zKCkge1xuICAgIHJldHVybiB0aGlzLl9jb25maWcucGx1Z2lucztcbiAgfVxuXG4gIHVwZGF0ZSgpIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLl9jb25maWc7XG4gICAgdGhpcy5jbGVhckNhY2hlKCk7XG4gICAgaW5pdE9wdGlvbnMoY29uZmlnKTtcbiAgfVxuXG4gIGNsZWFyQ2FjaGUoKSB7XG4gICAgdGhpcy5fc2NvcGVDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMuX3Jlc29sdmVyQ2FjaGUuY2xlYXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBvcHRpb24gc2NvcGUga2V5cyBmb3IgcmVzb2x2aW5nIGRhdGFzZXQgb3B0aW9ucy5cbiAgICogVGhlc2Uga2V5cyBkbyBub3QgaW5jbHVkZSB0aGUgZGF0YXNldCBpdHNlbGYsIGJlY2F1c2UgaXQgaXMgbm90IHVuZGVyIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhc2V0VHlwZVxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXVtdfVxuICAgKi9cbiAgZGF0YXNldFNjb3BlS2V5cyhkYXRhc2V0VHlwZSkge1xuICAgIHJldHVybiBjYWNoZWRLZXlzKGRhdGFzZXRUeXBlLFxuICAgICAgKCkgPT4gW1tcbiAgICAgICAgYGRhdGFzZXRzLiR7ZGF0YXNldFR5cGV9YCxcbiAgICAgICAgJydcbiAgICAgIF1dKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBvcHRpb24gc2NvcGUga2V5cyBmb3IgcmVzb2x2aW5nIGRhdGFzZXQgYW5pbWF0aW9uIG9wdGlvbnMuXG4gICAqIFRoZXNlIGtleXMgZG8gbm90IGluY2x1ZGUgdGhlIGRhdGFzZXQgaXRzZWxmLCBiZWNhdXNlIGl0IGlzIG5vdCB1bmRlciBvcHRpb25zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YXNldFR5cGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRyYW5zaXRpb25cbiAgICogQHJldHVybiB7c3RyaW5nW11bXX1cbiAgICovXG4gIGRhdGFzZXRBbmltYXRpb25TY29wZUtleXMoZGF0YXNldFR5cGUsIHRyYW5zaXRpb24pIHtcbiAgICByZXR1cm4gY2FjaGVkS2V5cyhgJHtkYXRhc2V0VHlwZX0udHJhbnNpdGlvbi4ke3RyYW5zaXRpb259YCxcbiAgICAgICgpID0+IFtcbiAgICAgICAgW1xuICAgICAgICAgIGBkYXRhc2V0cy4ke2RhdGFzZXRUeXBlfS50cmFuc2l0aW9ucy4ke3RyYW5zaXRpb259YCxcbiAgICAgICAgICBgdHJhbnNpdGlvbnMuJHt0cmFuc2l0aW9ufWAsXG4gICAgICAgIF0sXG4gICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgYXJlIHVzZWQgZm9yIGxvb2tpbmcgdXAgdGhlIGBhbmltYXRpb25zYCBhbmQgYGFuaW1hdGlvbmAga2V5c1xuICAgICAgICBbXG4gICAgICAgICAgYGRhdGFzZXRzLiR7ZGF0YXNldFR5cGV9YCxcbiAgICAgICAgICAnJ1xuICAgICAgICBdXG4gICAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBvcHRpb25zIHNjb3BlIGtleXMgZm9yIHJlc29sdmluZyBlbGVtZW50IG9wdGlvbnMgdGhhdCBiZWxvbmdcbiAgICogdG8gYW4gZGF0YXNldC4gVGhlc2Uga2V5cyBkbyBub3QgaW5jbHVkZSB0aGUgZGF0YXNldCBpdHNlbGYsIGJlY2F1c2UgaXRcbiAgICogaXMgbm90IHVuZGVyIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhc2V0VHlwZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZWxlbWVudFR5cGVcbiAgICogQHJldHVybiB7c3RyaW5nW11bXX1cbiAgICovXG4gIGRhdGFzZXRFbGVtZW50U2NvcGVLZXlzKGRhdGFzZXRUeXBlLCBlbGVtZW50VHlwZSkge1xuICAgIHJldHVybiBjYWNoZWRLZXlzKGAke2RhdGFzZXRUeXBlfS0ke2VsZW1lbnRUeXBlfWAsXG4gICAgICAoKSA9PiBbW1xuICAgICAgICBgZGF0YXNldHMuJHtkYXRhc2V0VHlwZX0uZWxlbWVudHMuJHtlbGVtZW50VHlwZX1gLFxuICAgICAgICBgZGF0YXNldHMuJHtkYXRhc2V0VHlwZX1gLFxuICAgICAgICBgZWxlbWVudHMuJHtlbGVtZW50VHlwZX1gLFxuICAgICAgICAnJ1xuICAgICAgXV0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIG9wdGlvbnMgc2NvcGUga2V5cyBmb3IgcmVzb2x2aW5nIHBsdWdpbiBvcHRpb25zLlxuICAgKiBAcGFyYW0ge3tpZDogc3RyaW5nLCBhZGRpdGlvbmFsT3B0aW9uU2NvcGVzPzogc3RyaW5nW119fSBwbHVnaW5cbiAgICogQHJldHVybiB7c3RyaW5nW11bXX1cbiAgICovXG4gIHBsdWdpblNjb3BlS2V5cyhwbHVnaW4pIHtcbiAgICBjb25zdCBpZCA9IHBsdWdpbi5pZDtcbiAgICBjb25zdCB0eXBlID0gdGhpcy50eXBlO1xuICAgIHJldHVybiBjYWNoZWRLZXlzKGAke3R5cGV9LXBsdWdpbi0ke2lkfWAsXG4gICAgICAoKSA9PiBbW1xuICAgICAgICBgcGx1Z2lucy4ke2lkfWAsXG4gICAgICAgIC4uLnBsdWdpbi5hZGRpdGlvbmFsT3B0aW9uU2NvcGVzIHx8IFtdLFxuICAgICAgXV0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfY2FjaGVkU2NvcGVzKG1haW5TY29wZSwgcmVzZXRDYWNoZSkge1xuICAgIGNvbnN0IF9zY29wZUNhY2hlID0gdGhpcy5fc2NvcGVDYWNoZTtcbiAgICBsZXQgY2FjaGUgPSBfc2NvcGVDYWNoZS5nZXQobWFpblNjb3BlKTtcbiAgICBpZiAoIWNhY2hlIHx8IHJlc2V0Q2FjaGUpIHtcbiAgICAgIGNhY2hlID0gbmV3IE1hcCgpO1xuICAgICAgX3Njb3BlQ2FjaGUuc2V0KG1haW5TY29wZSwgY2FjaGUpO1xuICAgIH1cbiAgICByZXR1cm4gY2FjaGU7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIG9iamVjdHMgZnJvbSBvcHRpb25zIGFuZCBkZWZhdWx0cyBmb3Igb3B0aW9uIHZhbHVlIHJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBtYWluU2NvcGUgLSBUaGUgbWFpbiBzY29wZSBvYmplY3QgZm9yIG9wdGlvbnNcbiAgICogQHBhcmFtIHtzdHJpbmdbXVtdfSBrZXlMaXN0cyAtIFRoZSBhcnJheXMgb2Yga2V5cyBpbiByZXNvbHV0aW9uIG9yZGVyXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Jlc2V0Q2FjaGVdIC0gcmVzZXQgdGhlIGNhY2hlIGZvciB0aGlzIG1haW5TY29wZVxuICAgKi9cbiAgZ2V0T3B0aW9uU2NvcGVzKG1haW5TY29wZSwga2V5TGlzdHMsIHJlc2V0Q2FjaGUpIHtcbiAgICBjb25zdCB7b3B0aW9ucywgdHlwZX0gPSB0aGlzO1xuICAgIGNvbnN0IGNhY2hlID0gdGhpcy5fY2FjaGVkU2NvcGVzKG1haW5TY29wZSwgcmVzZXRDYWNoZSk7XG4gICAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGtleUxpc3RzKTtcbiAgICBpZiAoY2FjaGVkKSB7XG4gICAgICByZXR1cm4gY2FjaGVkO1xuICAgIH1cblxuICAgIGNvbnN0IHNjb3BlcyA9IG5ldyBTZXQoKTtcblxuICAgIGtleUxpc3RzLmZvckVhY2goa2V5cyA9PiB7XG4gICAgICBpZiAobWFpblNjb3BlKSB7XG4gICAgICAgIHNjb3Blcy5hZGQobWFpblNjb3BlKTtcbiAgICAgICAga2V5cy5mb3JFYWNoKGtleSA9PiBhZGRJZkZvdW5kKHNjb3BlcywgbWFpblNjb3BlLCBrZXkpKTtcbiAgICAgIH1cbiAgICAgIGtleXMuZm9yRWFjaChrZXkgPT4gYWRkSWZGb3VuZChzY29wZXMsIG9wdGlvbnMsIGtleSkpO1xuICAgICAga2V5cy5mb3JFYWNoKGtleSA9PiBhZGRJZkZvdW5kKHNjb3Blcywgb3ZlcnJpZGVzW3R5cGVdIHx8IHt9LCBrZXkpKTtcbiAgICAgIGtleXMuZm9yRWFjaChrZXkgPT4gYWRkSWZGb3VuZChzY29wZXMsIGRlZmF1bHRzLCBrZXkpKTtcbiAgICAgIGtleXMuZm9yRWFjaChrZXkgPT4gYWRkSWZGb3VuZChzY29wZXMsIGRlc2NyaXB0b3JzLCBrZXkpKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGFycmF5ID0gQXJyYXkuZnJvbShzY29wZXMpO1xuICAgIGlmIChhcnJheS5sZW5ndGggPT09IDApIHtcbiAgICAgIGFycmF5LnB1c2goT2JqZWN0LmNyZWF0ZShudWxsKSk7XG4gICAgfVxuICAgIGlmIChrZXlzQ2FjaGVkLmhhcyhrZXlMaXN0cykpIHtcbiAgICAgIGNhY2hlLnNldChrZXlMaXN0cywgYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgb3B0aW9uIHNjb3BlcyBmb3IgcmVzb2x2aW5nIGNoYXJ0IG9wdGlvbnNcbiAgICogQHJldHVybiB7b2JqZWN0W119XG4gICAqL1xuICBjaGFydE9wdGlvblNjb3BlcygpIHtcbiAgICBjb25zdCB7b3B0aW9ucywgdHlwZX0gPSB0aGlzO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIG9wdGlvbnMsXG4gICAgICBvdmVycmlkZXNbdHlwZV0gfHwge30sXG4gICAgICBkZWZhdWx0cy5kYXRhc2V0c1t0eXBlXSB8fCB7fSwgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzg1MzFcbiAgICAgIHt0eXBlfSxcbiAgICAgIGRlZmF1bHRzLFxuICAgICAgZGVzY3JpcHRvcnNcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0W119IHNjb3Blc1xuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBuYW1lc1xuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufG9iamVjdH0gY29udGV4dFxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbcHJlZml4ZXNdXG4gICAqIEByZXR1cm4ge29iamVjdH1cbiAgICovXG4gIHJlc29sdmVOYW1lZE9wdGlvbnMoc2NvcGVzLCBuYW1lcywgY29udGV4dCwgcHJlZml4ZXMgPSBbJyddKSB7XG4gICAgY29uc3QgcmVzdWx0ID0geyRzaGFyZWQ6IHRydWV9O1xuICAgIGNvbnN0IHtyZXNvbHZlciwgc3ViUHJlZml4ZXN9ID0gZ2V0UmVzb2x2ZXIodGhpcy5fcmVzb2x2ZXJDYWNoZSwgc2NvcGVzLCBwcmVmaXhlcyk7XG4gICAgbGV0IG9wdGlvbnMgPSByZXNvbHZlcjtcbiAgICBpZiAobmVlZENvbnRleHQocmVzb2x2ZXIsIG5hbWVzKSkge1xuICAgICAgcmVzdWx0LiRzaGFyZWQgPSBmYWxzZTtcbiAgICAgIGNvbnRleHQgPSBpc0Z1bmN0aW9uKGNvbnRleHQpID8gY29udGV4dCgpIDogY29udGV4dDtcbiAgICAgIC8vIHN1YlJlc29sdmVyIGlzIHBhc3NlZCB0byBzY3JpcHRhYmxlIG9wdGlvbnMuIEl0IHNob3VsZCBub3QgcmVzb2x2ZSB0byBob3ZlciBvcHRpb25zLlxuICAgICAgY29uc3Qgc3ViUmVzb2x2ZXIgPSB0aGlzLmNyZWF0ZVJlc29sdmVyKHNjb3BlcywgY29udGV4dCwgc3ViUHJlZml4ZXMpO1xuICAgICAgb3B0aW9ucyA9IF9hdHRhY2hDb250ZXh0KHJlc29sdmVyLCBjb250ZXh0LCBzdWJSZXNvbHZlcik7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBwcm9wIG9mIG5hbWVzKSB7XG4gICAgICByZXN1bHRbcHJvcF0gPSBvcHRpb25zW3Byb3BdO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0W119IHNjb3Blc1xuICAgKiBAcGFyYW0ge29iamVjdH0gW2NvbnRleHRdXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IFtwcmVmaXhlc11cbiAgICogQHBhcmFtIHt7c2NyaXB0YWJsZTogYm9vbGVhbiwgaW5kZXhhYmxlOiBib29sZWFuLCBhbGxLZXlzPzogYm9vbGVhbn19IFtkZXNjcmlwdG9yRGVmYXVsdHNdXG4gICAqL1xuICBjcmVhdGVSZXNvbHZlcihzY29wZXMsIGNvbnRleHQsIHByZWZpeGVzID0gWycnXSwgZGVzY3JpcHRvckRlZmF1bHRzKSB7XG4gICAgY29uc3Qge3Jlc29sdmVyfSA9IGdldFJlc29sdmVyKHRoaXMuX3Jlc29sdmVyQ2FjaGUsIHNjb3BlcywgcHJlZml4ZXMpO1xuICAgIHJldHVybiBpc09iamVjdChjb250ZXh0KVxuICAgICAgPyBfYXR0YWNoQ29udGV4dChyZXNvbHZlciwgY29udGV4dCwgdW5kZWZpbmVkLCBkZXNjcmlwdG9yRGVmYXVsdHMpXG4gICAgICA6IHJlc29sdmVyO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFJlc29sdmVyKHJlc29sdmVyQ2FjaGUsIHNjb3BlcywgcHJlZml4ZXMpIHtcbiAgbGV0IGNhY2hlID0gcmVzb2x2ZXJDYWNoZS5nZXQoc2NvcGVzKTtcbiAgaWYgKCFjYWNoZSkge1xuICAgIGNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHJlc29sdmVyQ2FjaGUuc2V0KHNjb3BlcywgY2FjaGUpO1xuICB9XG4gIGNvbnN0IGNhY2hlS2V5ID0gcHJlZml4ZXMuam9pbigpO1xuICBsZXQgY2FjaGVkID0gY2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgaWYgKCFjYWNoZWQpIHtcbiAgICBjb25zdCByZXNvbHZlciA9IF9jcmVhdGVSZXNvbHZlcihzY29wZXMsIHByZWZpeGVzKTtcbiAgICBjYWNoZWQgPSB7XG4gICAgICByZXNvbHZlcixcbiAgICAgIHN1YlByZWZpeGVzOiBwcmVmaXhlcy5maWx0ZXIocCA9PiAhcC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdob3ZlcicpKVxuICAgIH07XG4gICAgY2FjaGUuc2V0KGNhY2hlS2V5LCBjYWNoZWQpO1xuICB9XG4gIHJldHVybiBjYWNoZWQ7XG59XG5cbmNvbnN0IGhhc0Z1bmN0aW9uID0gdmFsdWUgPT4gaXNPYmplY3QodmFsdWUpXG4gICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHZhbHVlKS5zb21lKChrZXkpID0+IGlzRnVuY3Rpb24odmFsdWVba2V5XSkpO1xuXG5mdW5jdGlvbiBuZWVkQ29udGV4dChwcm94eSwgbmFtZXMpIHtcbiAgY29uc3Qge2lzU2NyaXB0YWJsZSwgaXNJbmRleGFibGV9ID0gX2Rlc2NyaXB0b3JzKHByb3h5KTtcblxuICBmb3IgKGNvbnN0IHByb3Agb2YgbmFtZXMpIHtcbiAgICBjb25zdCBzY3JpcHRhYmxlID0gaXNTY3JpcHRhYmxlKHByb3ApO1xuICAgIGNvbnN0IGluZGV4YWJsZSA9IGlzSW5kZXhhYmxlKHByb3ApO1xuICAgIGNvbnN0IHZhbHVlID0gKGluZGV4YWJsZSB8fCBzY3JpcHRhYmxlKSAmJiBwcm94eVtwcm9wXTtcbiAgICBpZiAoKHNjcmlwdGFibGUgJiYgKGlzRnVuY3Rpb24odmFsdWUpIHx8IGhhc0Z1bmN0aW9uKHZhbHVlKSkpXG4gICAgICB8fCAoaW5kZXhhYmxlICYmIGlzQXJyYXkodmFsdWUpKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cbiIsICJpbXBvcnQgYW5pbWF0b3IgZnJvbSAnLi9jb3JlLmFuaW1hdG9yLmpzJztcbmltcG9ydCBkZWZhdWx0cywge292ZXJyaWRlc30gZnJvbSAnLi9jb3JlLmRlZmF1bHRzLmpzJztcbmltcG9ydCBJbnRlcmFjdGlvbiBmcm9tICcuL2NvcmUuaW50ZXJhY3Rpb24uanMnO1xuaW1wb3J0IGxheW91dHMgZnJvbSAnLi9jb3JlLmxheW91dHMuanMnO1xuaW1wb3J0IHtfZGV0ZWN0UGxhdGZvcm19IGZyb20gJy4uL3BsYXRmb3JtL2luZGV4LmpzJztcbmltcG9ydCBQbHVnaW5TZXJ2aWNlIGZyb20gJy4vY29yZS5wbHVnaW5zLmpzJztcbmltcG9ydCByZWdpc3RyeSBmcm9tICcuL2NvcmUucmVnaXN0cnkuanMnO1xuaW1wb3J0IENvbmZpZywge2RldGVybWluZUF4aXMsIGdldEluZGV4QXhpc30gZnJvbSAnLi9jb3JlLmNvbmZpZy5qcyc7XG5pbXBvcnQge3JldGluYVNjYWxlLCBfaXNEb21TdXBwb3J0ZWR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5kb20uanMnO1xuaW1wb3J0IHtlYWNoLCBjYWxsYmFjayBhcyBjYWxsQ2FsbGJhY2ssIHVpZCwgdmFsdWVPckRlZmF1bHQsIF9lbGVtZW50c0VxdWFsLCBpc051bGxPclVuZGVmLCBzZXRzRXF1YWwsIGRlZmluZWQsIGlzRnVuY3Rpb24sIF9pc0NsaWNrRXZlbnR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7Y2xlYXJDYW52YXMsIGNsaXBBcmVhLCBjcmVhdGVDb250ZXh0LCB1bmNsaXBBcmVhLCBfaXNQb2ludEluQXJlYX0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG4vLyBAdHMtaWdub3JlXG5pbXBvcnQge3ZlcnNpb259IGZyb20gJy4uLy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQge2RlYm91bmNlfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZXh0cmFzLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vdHlwZXMvaW5kZXguanMnKS5DaGFydEV2ZW50IH0gQ2hhcnRFdmVudFxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL3R5cGVzL2luZGV4LmpzJykuUG9pbnQgfSBQb2ludFxuICovXG5cbmNvbnN0IEtOT1dOX1BPU0lUSU9OUyA9IFsndG9wJywgJ2JvdHRvbScsICdsZWZ0JywgJ3JpZ2h0JywgJ2NoYXJ0QXJlYSddO1xuZnVuY3Rpb24gcG9zaXRpb25Jc0hvcml6b250YWwocG9zaXRpb24sIGF4aXMpIHtcbiAgcmV0dXJuIHBvc2l0aW9uID09PSAndG9wJyB8fCBwb3NpdGlvbiA9PT0gJ2JvdHRvbScgfHwgKEtOT1dOX1BPU0lUSU9OUy5pbmRleE9mKHBvc2l0aW9uKSA9PT0gLTEgJiYgYXhpcyA9PT0gJ3gnKTtcbn1cblxuZnVuY3Rpb24gY29tcGFyZTJMZXZlbChsMSwgbDIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gYVtsMV0gPT09IGJbbDFdXG4gICAgICA/IGFbbDJdIC0gYltsMl1cbiAgICAgIDogYVtsMV0gLSBiW2wxXTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gb25BbmltYXRpb25zQ29tcGxldGUoY29udGV4dCkge1xuICBjb25zdCBjaGFydCA9IGNvbnRleHQuY2hhcnQ7XG4gIGNvbnN0IGFuaW1hdGlvbk9wdGlvbnMgPSBjaGFydC5vcHRpb25zLmFuaW1hdGlvbjtcblxuICBjaGFydC5ub3RpZnlQbHVnaW5zKCdhZnRlclJlbmRlcicpO1xuICBjYWxsQ2FsbGJhY2soYW5pbWF0aW9uT3B0aW9ucyAmJiBhbmltYXRpb25PcHRpb25zLm9uQ29tcGxldGUsIFtjb250ZXh0XSwgY2hhcnQpO1xufVxuXG5mdW5jdGlvbiBvbkFuaW1hdGlvblByb2dyZXNzKGNvbnRleHQpIHtcbiAgY29uc3QgY2hhcnQgPSBjb250ZXh0LmNoYXJ0O1xuICBjb25zdCBhbmltYXRpb25PcHRpb25zID0gY2hhcnQub3B0aW9ucy5hbmltYXRpb247XG4gIGNhbGxDYWxsYmFjayhhbmltYXRpb25PcHRpb25zICYmIGFuaW1hdGlvbk9wdGlvbnMub25Qcm9ncmVzcywgW2NvbnRleHRdLCBjaGFydCk7XG59XG5cbi8qKlxuICogQ2hhcnQuanMgY2FuIHRha2UgYSBzdHJpbmcgaWQgb2YgYSBjYW52YXMgZWxlbWVudCwgYSAyZCBjb250ZXh0LCBvciBhIGNhbnZhcyBlbGVtZW50IGl0c2VsZi5cbiAqIEF0dGVtcHQgdG8gdW53cmFwIHRoZSBpdGVtIHBhc3NlZCBpbnRvIHRoZSBjaGFydCBjb25zdHJ1Y3RvciBzbyB0aGF0IGl0IGlzIGEgY2FudmFzIGVsZW1lbnQgKGlmIHBvc3NpYmxlKS5cbiAqL1xuZnVuY3Rpb24gZ2V0Q2FudmFzKGl0ZW0pIHtcbiAgaWYgKF9pc0RvbVN1cHBvcnRlZCgpICYmIHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgIGl0ZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpdGVtKTtcbiAgfSBlbHNlIGlmIChpdGVtICYmIGl0ZW0ubGVuZ3RoKSB7XG4gICAgLy8gU3VwcG9ydCBmb3IgYXJyYXkgYmFzZWQgcXVlcmllcyAoc3VjaCBhcyBqUXVlcnkpXG4gICAgaXRlbSA9IGl0ZW1bMF07XG4gIH1cblxuICBpZiAoaXRlbSAmJiBpdGVtLmNhbnZhcykge1xuICAgIC8vIFN1cHBvcnQgZm9yIGFueSBvYmplY3QgYXNzb2NpYXRlZCB0byBhIGNhbnZhcyAoaW5jbHVkaW5nIGEgY29udGV4dDJkKVxuICAgIGl0ZW0gPSBpdGVtLmNhbnZhcztcbiAgfVxuICByZXR1cm4gaXRlbTtcbn1cblxuY29uc3QgaW5zdGFuY2VzID0ge307XG5jb25zdCBnZXRDaGFydCA9IChrZXkpID0+IHtcbiAgY29uc3QgY2FudmFzID0gZ2V0Q2FudmFzKGtleSk7XG4gIHJldHVybiBPYmplY3QudmFsdWVzKGluc3RhbmNlcykuZmlsdGVyKChjKSA9PiBjLmNhbnZhcyA9PT0gY2FudmFzKS5wb3AoKTtcbn07XG5cbmZ1bmN0aW9uIG1vdmVOdW1lcmljS2V5cyhvYmosIHN0YXJ0LCBtb3ZlKSB7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgY29uc3QgaW50S2V5ID0gK2tleTtcbiAgICBpZiAoaW50S2V5ID49IHN0YXJ0KSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IG9ialtrZXldO1xuICAgICAgZGVsZXRlIG9ialtrZXldO1xuICAgICAgaWYgKG1vdmUgPiAwIHx8IGludEtleSA+IHN0YXJ0KSB7XG4gICAgICAgIG9ialtpbnRLZXkgKyBtb3ZlXSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7Q2hhcnRFdmVudH0gZVxuICogQHBhcmFtIHtDaGFydEV2ZW50fG51bGx9IGxhc3RFdmVudFxuICogQHBhcmFtIHtib29sZWFufSBpbkNoYXJ0QXJlYVxuICogQHBhcmFtIHtib29sZWFufSBpc0NsaWNrXG4gKiBAcmV0dXJucyB7Q2hhcnRFdmVudHxudWxsfVxuICovXG5mdW5jdGlvbiBkZXRlcm1pbmVMYXN0RXZlbnQoZSwgbGFzdEV2ZW50LCBpbkNoYXJ0QXJlYSwgaXNDbGljaykge1xuICBpZiAoIWluQ2hhcnRBcmVhIHx8IGUudHlwZSA9PT0gJ21vdXNlb3V0Jykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmIChpc0NsaWNrKSB7XG4gICAgcmV0dXJuIGxhc3RFdmVudDtcbiAgfVxuICByZXR1cm4gZTtcbn1cblxuZnVuY3Rpb24gZ2V0U2l6ZUZvckFyZWEoc2NhbGUsIGNoYXJ0QXJlYSwgZmllbGQpIHtcbiAgcmV0dXJuIHNjYWxlLm9wdGlvbnMuY2xpcCA/IHNjYWxlW2ZpZWxkXSA6IGNoYXJ0QXJlYVtmaWVsZF07XG59XG5cbmZ1bmN0aW9uIGdldERhdGFzZXRBcmVhKG1ldGEsIGNoYXJ0QXJlYSkge1xuICBjb25zdCB7eFNjYWxlLCB5U2NhbGV9ID0gbWV0YTtcbiAgaWYgKHhTY2FsZSAmJiB5U2NhbGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbGVmdDogZ2V0U2l6ZUZvckFyZWEoeFNjYWxlLCBjaGFydEFyZWEsICdsZWZ0JyksXG4gICAgICByaWdodDogZ2V0U2l6ZUZvckFyZWEoeFNjYWxlLCBjaGFydEFyZWEsICdyaWdodCcpLFxuICAgICAgdG9wOiBnZXRTaXplRm9yQXJlYSh5U2NhbGUsIGNoYXJ0QXJlYSwgJ3RvcCcpLFxuICAgICAgYm90dG9tOiBnZXRTaXplRm9yQXJlYSh5U2NhbGUsIGNoYXJ0QXJlYSwgJ2JvdHRvbScpXG4gICAgfTtcbiAgfVxuICByZXR1cm4gY2hhcnRBcmVhO1xufVxuXG5jbGFzcyBDaGFydCB7XG5cbiAgc3RhdGljIGRlZmF1bHRzID0gZGVmYXVsdHM7XG4gIHN0YXRpYyBpbnN0YW5jZXMgPSBpbnN0YW5jZXM7XG4gIHN0YXRpYyBvdmVycmlkZXMgPSBvdmVycmlkZXM7XG4gIHN0YXRpYyByZWdpc3RyeSA9IHJlZ2lzdHJ5O1xuICBzdGF0aWMgdmVyc2lvbiA9IHZlcnNpb247XG4gIHN0YXRpYyBnZXRDaGFydCA9IGdldENoYXJ0O1xuXG4gIHN0YXRpYyByZWdpc3RlciguLi5pdGVtcykge1xuICAgIHJlZ2lzdHJ5LmFkZCguLi5pdGVtcyk7XG4gICAgaW52YWxpZGF0ZVBsdWdpbnMoKTtcbiAgfVxuXG4gIHN0YXRpYyB1bnJlZ2lzdGVyKC4uLml0ZW1zKSB7XG4gICAgcmVnaXN0cnkucmVtb3ZlKC4uLml0ZW1zKTtcbiAgICBpbnZhbGlkYXRlUGx1Z2lucygpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1zdGF0ZW1lbnRzXG4gIGNvbnN0cnVjdG9yKGl0ZW0sIHVzZXJDb25maWcpIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZyA9IG5ldyBDb25maWcodXNlckNvbmZpZyk7XG4gICAgY29uc3QgaW5pdGlhbENhbnZhcyA9IGdldENhbnZhcyhpdGVtKTtcbiAgICBjb25zdCBleGlzdGluZ0NoYXJ0ID0gZ2V0Q2hhcnQoaW5pdGlhbENhbnZhcyk7XG4gICAgaWYgKGV4aXN0aW5nQ2hhcnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0NhbnZhcyBpcyBhbHJlYWR5IGluIHVzZS4gQ2hhcnQgd2l0aCBJRCBcXCcnICsgZXhpc3RpbmdDaGFydC5pZCArICdcXCcnICtcblx0XHRcdFx0JyBtdXN0IGJlIGRlc3Ryb3llZCBiZWZvcmUgdGhlIGNhbnZhcyB3aXRoIElEIFxcJycgKyBleGlzdGluZ0NoYXJ0LmNhbnZhcy5pZCArICdcXCcgY2FuIGJlIHJldXNlZC4nXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IG9wdGlvbnMgPSBjb25maWcuY3JlYXRlUmVzb2x2ZXIoY29uZmlnLmNoYXJ0T3B0aW9uU2NvcGVzKCksIHRoaXMuZ2V0Q29udGV4dCgpKTtcblxuICAgIHRoaXMucGxhdGZvcm0gPSBuZXcgKGNvbmZpZy5wbGF0Zm9ybSB8fCBfZGV0ZWN0UGxhdGZvcm0oaW5pdGlhbENhbnZhcykpKCk7XG4gICAgdGhpcy5wbGF0Zm9ybS51cGRhdGVDb25maWcoY29uZmlnKTtcblxuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLnBsYXRmb3JtLmFjcXVpcmVDb250ZXh0KGluaXRpYWxDYW52YXMsIG9wdGlvbnMuYXNwZWN0UmF0aW8pO1xuICAgIGNvbnN0IGNhbnZhcyA9IGNvbnRleHQgJiYgY29udGV4dC5jYW52YXM7XG4gICAgY29uc3QgaGVpZ2h0ID0gY2FudmFzICYmIGNhbnZhcy5oZWlnaHQ7XG4gICAgY29uc3Qgd2lkdGggPSBjYW52YXMgJiYgY2FudmFzLndpZHRoO1xuXG4gICAgdGhpcy5pZCA9IHVpZCgpO1xuICAgIHRoaXMuY3R4ID0gY29udGV4dDtcbiAgICB0aGlzLmNhbnZhcyA9IGNhbnZhcztcbiAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgdGhpcy5fb3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgLy8gU3RvcmUgdGhlIHByZXZpb3VzbHkgdXNlZCBhc3BlY3QgcmF0aW8gdG8gZGV0ZXJtaW5lIGlmIGEgcmVzaXplXG4gICAgLy8gaXMgbmVlZGVkIGR1cmluZyB1cGRhdGVzLiBEbyB0aGlzIGFmdGVyIF9vcHRpb25zIGlzIHNldCBzaW5jZVxuICAgIC8vIGFzcGVjdFJhdGlvIHVzZXMgYSBnZXR0ZXJcbiAgICB0aGlzLl9hc3BlY3RSYXRpbyA9IHRoaXMuYXNwZWN0UmF0aW87XG4gICAgdGhpcy5fbGF5ZXJzID0gW107XG4gICAgdGhpcy5fbWV0YXNldHMgPSBbXTtcbiAgICB0aGlzLl9zdGFja3MgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5ib3hlcyA9IFtdO1xuICAgIHRoaXMuY3VycmVudERldmljZVBpeGVsUmF0aW8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jaGFydEFyZWEgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fYWN0aXZlID0gW107XG4gICAgdGhpcy5fbGFzdEV2ZW50ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xuICAgIC8qKiBAdHlwZSB7P3thdHRhY2g/OiBmdW5jdGlvbiwgZGV0YWNoPzogZnVuY3Rpb24sIHJlc2l6ZT86IGZ1bmN0aW9ufX0gKi9cbiAgICB0aGlzLl9yZXNwb25zaXZlTGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3NvcnRlZE1ldGFzZXRzID0gW107XG4gICAgdGhpcy5zY2FsZXMgPSB7fTtcbiAgICB0aGlzLl9wbHVnaW5zID0gbmV3IFBsdWdpblNlcnZpY2UoKTtcbiAgICB0aGlzLiRwcm94aWVzID0ge307XG4gICAgdGhpcy5faGlkZGVuSW5kaWNlcyA9IHt9O1xuICAgIHRoaXMuYXR0YWNoZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9hbmltYXRpb25zRGlzYWJsZWQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy4kY29udGV4dCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9kb1Jlc2l6ZSA9IGRlYm91bmNlKG1vZGUgPT4gdGhpcy51cGRhdGUobW9kZSksIG9wdGlvbnMucmVzaXplRGVsYXkgfHwgMCk7XG4gICAgdGhpcy5fZGF0YUNoYW5nZXMgPSBbXTtcblxuICAgIC8vIEFkZCB0aGUgY2hhcnQgaW5zdGFuY2UgdG8gdGhlIGdsb2JhbCBuYW1lc3BhY2VcbiAgICBpbnN0YW5jZXNbdGhpcy5pZF0gPSB0aGlzO1xuXG4gICAgaWYgKCFjb250ZXh0IHx8ICFjYW52YXMpIHtcbiAgICAgIC8vIFRoZSBnaXZlbiBpdGVtIGlzIG5vdCBhIGNvbXBhdGlibGUgY29udGV4dDJkIGVsZW1lbnQsIGxldCdzIHJldHVybiBiZWZvcmUgZmluYWxpemluZ1xuICAgICAgLy8gdGhlIGNoYXJ0IGluaXRpYWxpemF0aW9uIGJ1dCBhZnRlciBzZXR0aW5nIGJhc2ljIGNoYXJ0IC8gY29udHJvbGxlciBwcm9wZXJ0aWVzIHRoYXRcbiAgICAgIC8vIGNhbiBoZWxwIHRvIGZpZ3VyZSBvdXQgdGhhdCB0aGUgY2hhcnQgaXMgbm90IHZhbGlkIChlLmcgY2hhcnQuY2FudmFzICE9PSBudWxsKTtcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8yODA3XG4gICAgICBjb25zb2xlLmVycm9yKFwiRmFpbGVkIHRvIGNyZWF0ZSBjaGFydDogY2FuJ3QgYWNxdWlyZSBjb250ZXh0IGZyb20gdGhlIGdpdmVuIGl0ZW1cIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYW5pbWF0b3IubGlzdGVuKHRoaXMsICdjb21wbGV0ZScsIG9uQW5pbWF0aW9uc0NvbXBsZXRlKTtcbiAgICBhbmltYXRvci5saXN0ZW4odGhpcywgJ3Byb2dyZXNzJywgb25BbmltYXRpb25Qcm9ncmVzcyk7XG5cbiAgICB0aGlzLl9pbml0aWFsaXplKCk7XG4gICAgaWYgKHRoaXMuYXR0YWNoZWQpIHtcbiAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGFzcGVjdFJhdGlvKCkge1xuICAgIGNvbnN0IHtvcHRpb25zOiB7YXNwZWN0UmF0aW8sIG1haW50YWluQXNwZWN0UmF0aW99LCB3aWR0aCwgaGVpZ2h0LCBfYXNwZWN0UmF0aW99ID0gdGhpcztcbiAgICBpZiAoIWlzTnVsbE9yVW5kZWYoYXNwZWN0UmF0aW8pKSB7XG4gICAgICAvLyBJZiBhc3BlY3RSYXRpbyBpcyBkZWZpbmVkIGluIG9wdGlvbnMsIHVzZSB0aGF0LlxuICAgICAgcmV0dXJuIGFzcGVjdFJhdGlvO1xuICAgIH1cblxuICAgIGlmIChtYWludGFpbkFzcGVjdFJhdGlvICYmIF9hc3BlY3RSYXRpbykge1xuICAgICAgLy8gSWYgbWFpbnRhaW5Bc3BlY3RSYXRpbyBpcyB0cnV0aGx5IGFuZCB3ZSBoYWQgcHJldmlvdXNseSBkZXRlcm1pbmVkIF9hc3BlY3RSYXRpbywgdXNlIHRoYXRcbiAgICAgIHJldHVybiBfYXNwZWN0UmF0aW87XG4gICAgfVxuXG4gICAgLy8gQ2FsY3VsYXRlXG4gICAgcmV0dXJuIGhlaWdodCA/IHdpZHRoIC8gaGVpZ2h0IDogbnVsbDtcbiAgfVxuXG4gIGdldCBkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhO1xuICB9XG5cbiAgc2V0IGRhdGEoZGF0YSkge1xuICAgIHRoaXMuY29uZmlnLmRhdGEgPSBkYXRhO1xuICB9XG5cbiAgZ2V0IG9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbnM7XG4gIH1cblxuICBzZXQgb3B0aW9ucyhvcHRpb25zKSB7XG4gICAgdGhpcy5jb25maWcub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICBnZXQgcmVnaXN0cnkoKSB7XG4gICAgcmV0dXJuIHJlZ2lzdHJ5O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfaW5pdGlhbGl6ZSgpIHtcbiAgICAvLyBCZWZvcmUgaW5pdCBwbHVnaW4gbm90aWZpY2F0aW9uXG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVJbml0Jyk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnJlc3BvbnNpdmUpIHtcbiAgICAgIHRoaXMucmVzaXplKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldGluYVNjYWxlKHRoaXMsIHRoaXMub3B0aW9ucy5kZXZpY2VQaXhlbFJhdGlvKTtcbiAgICB9XG5cbiAgICB0aGlzLmJpbmRFdmVudHMoKTtcblxuICAgIC8vIEFmdGVyIGluaXQgcGx1Z2luIG5vdGlmaWNhdGlvblxuICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJJbml0Jyk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIGNsZWFyQ2FudmFzKHRoaXMuY2FudmFzLCB0aGlzLmN0eCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdG9wKCkge1xuICAgIGFuaW1hdG9yLnN0b3AodGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcblx0ICogUmVzaXplIHRoZSBjaGFydCB0byBpdHMgY29udGFpbmVyIG9yIHRvIGV4cGxpY2l0IGRpbWVuc2lvbnMuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbd2lkdGhdXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbaGVpZ2h0XVxuXHQgKi9cbiAgcmVzaXplKHdpZHRoLCBoZWlnaHQpIHtcbiAgICBpZiAoIWFuaW1hdG9yLnJ1bm5pbmcodGhpcykpIHtcbiAgICAgIHRoaXMuX3Jlc2l6ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcmVzaXplQmVmb3JlRHJhdyA9IHt3aWR0aCwgaGVpZ2h0fTtcbiAgICB9XG4gIH1cblxuICBfcmVzaXplKHdpZHRoLCBoZWlnaHQpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMuY2FudmFzO1xuICAgIGNvbnN0IGFzcGVjdFJhdGlvID0gb3B0aW9ucy5tYWludGFpbkFzcGVjdFJhdGlvICYmIHRoaXMuYXNwZWN0UmF0aW87XG4gICAgY29uc3QgbmV3U2l6ZSA9IHRoaXMucGxhdGZvcm0uZ2V0TWF4aW11bVNpemUoY2FudmFzLCB3aWR0aCwgaGVpZ2h0LCBhc3BlY3RSYXRpbyk7XG4gICAgY29uc3QgbmV3UmF0aW8gPSBvcHRpb25zLmRldmljZVBpeGVsUmF0aW8gfHwgdGhpcy5wbGF0Zm9ybS5nZXREZXZpY2VQaXhlbFJhdGlvKCk7XG4gICAgY29uc3QgbW9kZSA9IHRoaXMud2lkdGggPyAncmVzaXplJyA6ICdhdHRhY2gnO1xuXG4gICAgdGhpcy53aWR0aCA9IG5ld1NpemUud2lkdGg7XG4gICAgdGhpcy5oZWlnaHQgPSBuZXdTaXplLmhlaWdodDtcbiAgICB0aGlzLl9hc3BlY3RSYXRpbyA9IHRoaXMuYXNwZWN0UmF0aW87XG4gICAgaWYgKCFyZXRpbmFTY2FsZSh0aGlzLCBuZXdSYXRpbywgdHJ1ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ3Jlc2l6ZScsIHtzaXplOiBuZXdTaXplfSk7XG5cbiAgICBjYWxsQ2FsbGJhY2sob3B0aW9ucy5vblJlc2l6ZSwgW3RoaXMsIG5ld1NpemVdLCB0aGlzKTtcblxuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICBpZiAodGhpcy5fZG9SZXNpemUobW9kZSkpIHtcbiAgICAgICAgLy8gVGhlIHJlc2l6ZSB1cGRhdGUgaXMgZGVsYXllZCwgb25seSBkcmF3IHdpdGhvdXQgdXBkYXRpbmcuXG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZW5zdXJlU2NhbGVzSGF2ZUlEcygpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHNjYWxlc09wdGlvbnMgPSBvcHRpb25zLnNjYWxlcyB8fCB7fTtcblxuICAgIGVhY2goc2NhbGVzT3B0aW9ucywgKGF4aXNPcHRpb25zLCBheGlzSUQpID0+IHtcbiAgICAgIGF4aXNPcHRpb25zLmlkID0gYXhpc0lEO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG5cdCAqIEJ1aWxkcyBhIG1hcCBvZiBzY2FsZSBJRCB0byBzY2FsZSBvYmplY3QgZm9yIGZ1dHVyZSBsb29rdXAuXG5cdCAqL1xuICBidWlsZE9yVXBkYXRlU2NhbGVzKCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3Qgc2NhbGVPcHRzID0gb3B0aW9ucy5zY2FsZXM7XG4gICAgY29uc3Qgc2NhbGVzID0gdGhpcy5zY2FsZXM7XG4gICAgY29uc3QgdXBkYXRlZCA9IE9iamVjdC5rZXlzKHNjYWxlcykucmVkdWNlKChvYmosIGlkKSA9PiB7XG4gICAgICBvYmpbaWRdID0gZmFsc2U7XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH0sIHt9KTtcbiAgICBsZXQgaXRlbXMgPSBbXTtcblxuICAgIGlmIChzY2FsZU9wdHMpIHtcbiAgICAgIGl0ZW1zID0gaXRlbXMuY29uY2F0KFxuICAgICAgICBPYmplY3Qua2V5cyhzY2FsZU9wdHMpLm1hcCgoaWQpID0+IHtcbiAgICAgICAgICBjb25zdCBzY2FsZU9wdGlvbnMgPSBzY2FsZU9wdHNbaWRdO1xuICAgICAgICAgIGNvbnN0IGF4aXMgPSBkZXRlcm1pbmVBeGlzKGlkLCBzY2FsZU9wdGlvbnMpO1xuICAgICAgICAgIGNvbnN0IGlzUmFkaWFsID0gYXhpcyA9PT0gJ3InO1xuICAgICAgICAgIGNvbnN0IGlzSG9yaXpvbnRhbCA9IGF4aXMgPT09ICd4JztcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb3B0aW9uczogc2NhbGVPcHRpb25zLFxuICAgICAgICAgICAgZHBvc2l0aW9uOiBpc1JhZGlhbCA/ICdjaGFydEFyZWEnIDogaXNIb3Jpem9udGFsID8gJ2JvdHRvbScgOiAnbGVmdCcsXG4gICAgICAgICAgICBkdHlwZTogaXNSYWRpYWwgPyAncmFkaWFsTGluZWFyJyA6IGlzSG9yaXpvbnRhbCA/ICdjYXRlZ29yeScgOiAnbGluZWFyJ1xuICAgICAgICAgIH07XG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cblxuICAgIGVhY2goaXRlbXMsIChpdGVtKSA9PiB7XG4gICAgICBjb25zdCBzY2FsZU9wdGlvbnMgPSBpdGVtLm9wdGlvbnM7XG4gICAgICBjb25zdCBpZCA9IHNjYWxlT3B0aW9ucy5pZDtcbiAgICAgIGNvbnN0IGF4aXMgPSBkZXRlcm1pbmVBeGlzKGlkLCBzY2FsZU9wdGlvbnMpO1xuICAgICAgY29uc3Qgc2NhbGVUeXBlID0gdmFsdWVPckRlZmF1bHQoc2NhbGVPcHRpb25zLnR5cGUsIGl0ZW0uZHR5cGUpO1xuXG4gICAgICBpZiAoc2NhbGVPcHRpb25zLnBvc2l0aW9uID09PSB1bmRlZmluZWQgfHwgcG9zaXRpb25Jc0hvcml6b250YWwoc2NhbGVPcHRpb25zLnBvc2l0aW9uLCBheGlzKSAhPT0gcG9zaXRpb25Jc0hvcml6b250YWwoaXRlbS5kcG9zaXRpb24pKSB7XG4gICAgICAgIHNjYWxlT3B0aW9ucy5wb3NpdGlvbiA9IGl0ZW0uZHBvc2l0aW9uO1xuICAgICAgfVxuXG4gICAgICB1cGRhdGVkW2lkXSA9IHRydWU7XG4gICAgICBsZXQgc2NhbGUgPSBudWxsO1xuICAgICAgaWYgKGlkIGluIHNjYWxlcyAmJiBzY2FsZXNbaWRdLnR5cGUgPT09IHNjYWxlVHlwZSkge1xuICAgICAgICBzY2FsZSA9IHNjYWxlc1tpZF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzY2FsZUNsYXNzID0gcmVnaXN0cnkuZ2V0U2NhbGUoc2NhbGVUeXBlKTtcbiAgICAgICAgc2NhbGUgPSBuZXcgc2NhbGVDbGFzcyh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgdHlwZTogc2NhbGVUeXBlLFxuICAgICAgICAgIGN0eDogdGhpcy5jdHgsXG4gICAgICAgICAgY2hhcnQ6IHRoaXNcbiAgICAgICAgfSk7XG4gICAgICAgIHNjYWxlc1tzY2FsZS5pZF0gPSBzY2FsZTtcbiAgICAgIH1cblxuICAgICAgc2NhbGUuaW5pdChzY2FsZU9wdGlvbnMsIG9wdGlvbnMpO1xuICAgIH0pO1xuICAgIC8vIGNsZWFyIHVwIGRpc2NhcmRlZCBzY2FsZXNcbiAgICBlYWNoKHVwZGF0ZWQsIChoYXNVcGRhdGVkLCBpZCkgPT4ge1xuICAgICAgaWYgKCFoYXNVcGRhdGVkKSB7XG4gICAgICAgIGRlbGV0ZSBzY2FsZXNbaWRdO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZWFjaChzY2FsZXMsIChzY2FsZSkgPT4ge1xuICAgICAgbGF5b3V0cy5jb25maWd1cmUodGhpcywgc2NhbGUsIHNjYWxlLm9wdGlvbnMpO1xuICAgICAgbGF5b3V0cy5hZGRCb3godGhpcywgc2NhbGUpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdXBkYXRlTWV0YXNldHMoKSB7XG4gICAgY29uc3QgbWV0YXNldHMgPSB0aGlzLl9tZXRhc2V0cztcbiAgICBjb25zdCBudW1EYXRhID0gdGhpcy5kYXRhLmRhdGFzZXRzLmxlbmd0aDtcbiAgICBjb25zdCBudW1NZXRhID0gbWV0YXNldHMubGVuZ3RoO1xuXG4gICAgbWV0YXNldHMuc29ydCgoYSwgYikgPT4gYS5pbmRleCAtIGIuaW5kZXgpO1xuICAgIGlmIChudW1NZXRhID4gbnVtRGF0YSkge1xuICAgICAgZm9yIChsZXQgaSA9IG51bURhdGE7IGkgPCBudW1NZXRhOyArK2kpIHtcbiAgICAgICAgdGhpcy5fZGVzdHJveURhdGFzZXRNZXRhKGkpO1xuICAgICAgfVxuICAgICAgbWV0YXNldHMuc3BsaWNlKG51bURhdGEsIG51bU1ldGEgLSBudW1EYXRhKTtcbiAgICB9XG4gICAgdGhpcy5fc29ydGVkTWV0YXNldHMgPSBtZXRhc2V0cy5zbGljZSgwKS5zb3J0KGNvbXBhcmUyTGV2ZWwoJ29yZGVyJywgJ2luZGV4JykpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfcmVtb3ZlVW5yZWZlcmVuY2VkTWV0YXNldHMoKSB7XG4gICAgY29uc3Qge19tZXRhc2V0czogbWV0YXNldHMsIGRhdGE6IHtkYXRhc2V0c319ID0gdGhpcztcbiAgICBpZiAobWV0YXNldHMubGVuZ3RoID4gZGF0YXNldHMubGVuZ3RoKSB7XG4gICAgICBkZWxldGUgdGhpcy5fc3RhY2tzO1xuICAgIH1cbiAgICBtZXRhc2V0cy5mb3JFYWNoKChtZXRhLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGRhdGFzZXRzLmZpbHRlcih4ID0+IHggPT09IG1ldGEuX2RhdGFzZXQpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLl9kZXN0cm95RGF0YXNldE1ldGEoaW5kZXgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgYnVpbGRPclVwZGF0ZUNvbnRyb2xsZXJzKCkge1xuICAgIGNvbnN0IG5ld0NvbnRyb2xsZXJzID0gW107XG4gICAgY29uc3QgZGF0YXNldHMgPSB0aGlzLmRhdGEuZGF0YXNldHM7XG4gICAgbGV0IGksIGlsZW47XG5cbiAgICB0aGlzLl9yZW1vdmVVbnJlZmVyZW5jZWRNZXRhc2V0cygpO1xuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IGRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47IGkrKykge1xuICAgICAgY29uc3QgZGF0YXNldCA9IGRhdGFzZXRzW2ldO1xuICAgICAgbGV0IG1ldGEgPSB0aGlzLmdldERhdGFzZXRNZXRhKGkpO1xuICAgICAgY29uc3QgdHlwZSA9IGRhdGFzZXQudHlwZSB8fCB0aGlzLmNvbmZpZy50eXBlO1xuXG4gICAgICBpZiAobWV0YS50eXBlICYmIG1ldGEudHlwZSAhPT0gdHlwZSkge1xuICAgICAgICB0aGlzLl9kZXN0cm95RGF0YXNldE1ldGEoaSk7XG4gICAgICAgIG1ldGEgPSB0aGlzLmdldERhdGFzZXRNZXRhKGkpO1xuICAgICAgfVxuICAgICAgbWV0YS50eXBlID0gdHlwZTtcbiAgICAgIG1ldGEuaW5kZXhBeGlzID0gZGF0YXNldC5pbmRleEF4aXMgfHwgZ2V0SW5kZXhBeGlzKHR5cGUsIHRoaXMub3B0aW9ucyk7XG4gICAgICBtZXRhLm9yZGVyID0gZGF0YXNldC5vcmRlciB8fCAwO1xuICAgICAgbWV0YS5pbmRleCA9IGk7XG4gICAgICBtZXRhLmxhYmVsID0gJycgKyBkYXRhc2V0LmxhYmVsO1xuICAgICAgbWV0YS52aXNpYmxlID0gdGhpcy5pc0RhdGFzZXRWaXNpYmxlKGkpO1xuXG4gICAgICBpZiAobWV0YS5jb250cm9sbGVyKSB7XG4gICAgICAgIG1ldGEuY29udHJvbGxlci51cGRhdGVJbmRleChpKTtcbiAgICAgICAgbWV0YS5jb250cm9sbGVyLmxpbmtTY2FsZXMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IENvbnRyb2xsZXJDbGFzcyA9IHJlZ2lzdHJ5LmdldENvbnRyb2xsZXIodHlwZSk7XG4gICAgICAgIGNvbnN0IHtkYXRhc2V0RWxlbWVudFR5cGUsIGRhdGFFbGVtZW50VHlwZX0gPSBkZWZhdWx0cy5kYXRhc2V0c1t0eXBlXTtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihDb250cm9sbGVyQ2xhc3MsIHtcbiAgICAgICAgICBkYXRhRWxlbWVudFR5cGU6IHJlZ2lzdHJ5LmdldEVsZW1lbnQoZGF0YUVsZW1lbnRUeXBlKSxcbiAgICAgICAgICBkYXRhc2V0RWxlbWVudFR5cGU6IGRhdGFzZXRFbGVtZW50VHlwZSAmJiByZWdpc3RyeS5nZXRFbGVtZW50KGRhdGFzZXRFbGVtZW50VHlwZSlcbiAgICAgICAgfSk7XG4gICAgICAgIG1ldGEuY29udHJvbGxlciA9IG5ldyBDb250cm9sbGVyQ2xhc3ModGhpcywgaSk7XG4gICAgICAgIG5ld0NvbnRyb2xsZXJzLnB1c2gobWV0YS5jb250cm9sbGVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl91cGRhdGVNZXRhc2V0cygpO1xuICAgIHJldHVybiBuZXdDb250cm9sbGVycztcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXNldCB0aGUgZWxlbWVudHMgb2YgYWxsIGRhdGFzZXRzXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfcmVzZXRFbGVtZW50cygpIHtcbiAgICBlYWNoKHRoaXMuZGF0YS5kYXRhc2V0cywgKGRhdGFzZXQsIGRhdGFzZXRJbmRleCkgPT4ge1xuICAgICAgdGhpcy5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpLmNvbnRyb2xsZXIucmVzZXQoKTtcbiAgICB9LCB0aGlzKTtcbiAgfVxuXG4gIC8qKlxuXHQqIFJlc2V0cyB0aGUgY2hhcnQgYmFjayB0byBpdHMgc3RhdGUgYmVmb3JlIHRoZSBpbml0aWFsIGFuaW1hdGlvblxuXHQqL1xuICByZXNldCgpIHtcbiAgICB0aGlzLl9yZXNldEVsZW1lbnRzKCk7XG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdyZXNldCcpO1xuICB9XG5cbiAgdXBkYXRlKG1vZGUpIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZztcblxuICAgIGNvbmZpZy51cGRhdGUoKTtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5fb3B0aW9ucyA9IGNvbmZpZy5jcmVhdGVSZXNvbHZlcihjb25maWcuY2hhcnRPcHRpb25TY29wZXMoKSwgdGhpcy5nZXRDb250ZXh0KCkpO1xuICAgIGNvbnN0IGFuaW1zRGlzYWJsZWQgPSB0aGlzLl9hbmltYXRpb25zRGlzYWJsZWQgPSAhb3B0aW9ucy5hbmltYXRpb247XG5cbiAgICB0aGlzLl91cGRhdGVTY2FsZXMoKTtcbiAgICB0aGlzLl9jaGVja0V2ZW50QmluZGluZ3MoKTtcbiAgICB0aGlzLl91cGRhdGVIaWRkZW5JbmRpY2VzKCk7XG5cbiAgICAvLyBwbHVnaW5zIG9wdGlvbnMgcmVmZXJlbmNlcyBtaWdodCBoYXZlIGNoYW5nZSwgbGV0J3MgaW52YWxpZGF0ZSB0aGUgY2FjaGVcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNTExMSNpc3N1ZWNvbW1lbnQtMzU1OTM0MTY3XG4gICAgdGhpcy5fcGx1Z2lucy5pbnZhbGlkYXRlKCk7XG5cbiAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVVcGRhdGUnLCB7bW9kZSwgY2FuY2VsYWJsZTogdHJ1ZX0pID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIE1ha2Ugc3VyZSBkYXRhc2V0IGNvbnRyb2xsZXJzIGFyZSB1cGRhdGVkIGFuZCBuZXcgY29udHJvbGxlcnMgYXJlIHJlc2V0XG4gICAgY29uc3QgbmV3Q29udHJvbGxlcnMgPSB0aGlzLmJ1aWxkT3JVcGRhdGVDb250cm9sbGVycygpO1xuXG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVFbGVtZW50c1VwZGF0ZScpO1xuXG4gICAgLy8gTWFrZSBzdXJlIGFsbCBkYXRhc2V0IGNvbnRyb2xsZXJzIGhhdmUgY29ycmVjdCBtZXRhIGRhdGEgY291bnRzXG4gICAgbGV0IG1pblBhZGRpbmcgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwLCBpbGVuID0gdGhpcy5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47IGkrKykge1xuICAgICAgY29uc3Qge2NvbnRyb2xsZXJ9ID0gdGhpcy5nZXREYXRhc2V0TWV0YShpKTtcbiAgICAgIGNvbnN0IHJlc2V0ID0gIWFuaW1zRGlzYWJsZWQgJiYgbmV3Q29udHJvbGxlcnMuaW5kZXhPZihjb250cm9sbGVyKSA9PT0gLTE7XG4gICAgICAvLyBOZXcgY29udHJvbGxlcnMgd2lsbCBiZSByZXNldCBhZnRlciB0aGUgbGF5b3V0IHBhc3MsIHNvIHdlIG9ubHkgd2FudCB0byBtb2RpZnlcbiAgICAgIC8vIGVsZW1lbnRzIGFkZGVkIHRvIG5ldyBkYXRhc2V0c1xuICAgICAgY29udHJvbGxlci5idWlsZE9yVXBkYXRlRWxlbWVudHMocmVzZXQpO1xuICAgICAgbWluUGFkZGluZyA9IE1hdGgubWF4KCtjb250cm9sbGVyLmdldE1heE92ZXJmbG93KCksIG1pblBhZGRpbmcpO1xuICAgIH1cbiAgICBtaW5QYWRkaW5nID0gdGhpcy5fbWluUGFkZGluZyA9IG9wdGlvbnMubGF5b3V0LmF1dG9QYWRkaW5nID8gbWluUGFkZGluZyA6IDA7XG4gICAgdGhpcy5fdXBkYXRlTGF5b3V0KG1pblBhZGRpbmcpO1xuXG4gICAgLy8gT25seSByZXNldCB0aGUgY29udHJvbGxlcnMgaWYgd2UgaGF2ZSBhbmltYXRpb25zXG4gICAgaWYgKCFhbmltc0Rpc2FibGVkKSB7XG4gICAgICAvLyBDYW4gb25seSByZXNldCB0aGUgbmV3IGNvbnRyb2xsZXJzIGFmdGVyIHRoZSBzY2FsZXMgaGF2ZSBiZWVuIHVwZGF0ZWRcbiAgICAgIC8vIFJlc2V0IGlzIGRvbmUgdG8gZ2V0IHRoZSBzdGFydGluZyBwb2ludCBmb3IgdGhlIGluaXRpYWwgYW5pbWF0aW9uXG4gICAgICBlYWNoKG5ld0NvbnRyb2xsZXJzLCAoY29udHJvbGxlcikgPT4ge1xuICAgICAgICBjb250cm9sbGVyLnJlc2V0KCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl91cGRhdGVEYXRhc2V0cyhtb2RlKTtcblxuICAgIC8vIERvIHRoaXMgYmVmb3JlIHJlbmRlciBzbyB0aGF0IGFueSBwbHVnaW5zIHRoYXQgbmVlZCBmaW5hbCBzY2FsZSB1cGRhdGVzIGNhbiB1c2UgaXRcbiAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyVXBkYXRlJywge21vZGV9KTtcblxuICAgIHRoaXMuX2xheWVycy5zb3J0KGNvbXBhcmUyTGV2ZWwoJ3onLCAnX2lkeCcpKTtcblxuICAgIC8vIFJlcGxheSBsYXN0IGV2ZW50IGZyb20gYmVmb3JlIHVwZGF0ZSwgb3Igc2V0IGhvdmVyIHN0eWxlcyBvbiBhY3RpdmUgZWxlbWVudHNcbiAgICBjb25zdCB7X2FjdGl2ZSwgX2xhc3RFdmVudH0gPSB0aGlzO1xuICAgIGlmIChfbGFzdEV2ZW50KSB7XG4gICAgICB0aGlzLl9ldmVudEhhbmRsZXIoX2xhc3RFdmVudCwgdHJ1ZSk7XG4gICAgfSBlbHNlIGlmIChfYWN0aXZlLmxlbmd0aCkge1xuICAgICAgdGhpcy5fdXBkYXRlSG92ZXJTdHlsZXMoX2FjdGl2ZSwgX2FjdGl2ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX3VwZGF0ZVNjYWxlcygpIHtcbiAgICBlYWNoKHRoaXMuc2NhbGVzLCAoc2NhbGUpID0+IHtcbiAgICAgIGxheW91dHMucmVtb3ZlQm94KHRoaXMsIHNjYWxlKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZW5zdXJlU2NhbGVzSGF2ZUlEcygpO1xuICAgIHRoaXMuYnVpbGRPclVwZGF0ZVNjYWxlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfY2hlY2tFdmVudEJpbmRpbmdzKCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgZXhpc3RpbmdFdmVudHMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKHRoaXMuX2xpc3RlbmVycykpO1xuICAgIGNvbnN0IG5ld0V2ZW50cyA9IG5ldyBTZXQob3B0aW9ucy5ldmVudHMpO1xuXG4gICAgaWYgKCFzZXRzRXF1YWwoZXhpc3RpbmdFdmVudHMsIG5ld0V2ZW50cykgfHwgISF0aGlzLl9yZXNwb25zaXZlTGlzdGVuZXJzICE9PSBvcHRpb25zLnJlc3BvbnNpdmUpIHtcbiAgICAgIC8vIFRoZSBjb25maWd1cmVkIGV2ZW50cyBoYXZlIGNoYW5nZWQuIFJlYmluZC5cbiAgICAgIHRoaXMudW5iaW5kRXZlbnRzKCk7XG4gICAgICB0aGlzLmJpbmRFdmVudHMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF91cGRhdGVIaWRkZW5JbmRpY2VzKCkge1xuICAgIGNvbnN0IHtfaGlkZGVuSW5kaWNlc30gPSB0aGlzO1xuICAgIGNvbnN0IGNoYW5nZXMgPSB0aGlzLl9nZXRVbmlmb3JtRGF0YUNoYW5nZXMoKSB8fCBbXTtcbiAgICBmb3IgKGNvbnN0IHttZXRob2QsIHN0YXJ0LCBjb3VudH0gb2YgY2hhbmdlcykge1xuICAgICAgY29uc3QgbW92ZSA9IG1ldGhvZCA9PT0gJ19yZW1vdmVFbGVtZW50cycgPyAtY291bnQgOiBjb3VudDtcbiAgICAgIG1vdmVOdW1lcmljS2V5cyhfaGlkZGVuSW5kaWNlcywgc3RhcnQsIG1vdmUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX2dldFVuaWZvcm1EYXRhQ2hhbmdlcygpIHtcbiAgICBjb25zdCBfZGF0YUNoYW5nZXMgPSB0aGlzLl9kYXRhQ2hhbmdlcztcbiAgICBpZiAoIV9kYXRhQ2hhbmdlcyB8fCAhX2RhdGFDaGFuZ2VzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2RhdGFDaGFuZ2VzID0gW107XG4gICAgY29uc3QgZGF0YXNldENvdW50ID0gdGhpcy5kYXRhLmRhdGFzZXRzLmxlbmd0aDtcbiAgICBjb25zdCBtYWtlU2V0ID0gKGlkeCkgPT4gbmV3IFNldChcbiAgICAgIF9kYXRhQ2hhbmdlc1xuICAgICAgICAuZmlsdGVyKGMgPT4gY1swXSA9PT0gaWR4KVxuICAgICAgICAubWFwKChjLCBpKSA9PiBpICsgJywnICsgYy5zcGxpY2UoMSkuam9pbignLCcpKVxuICAgICk7XG5cbiAgICBjb25zdCBjaGFuZ2VTZXQgPSBtYWtlU2V0KDApO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZGF0YXNldENvdW50OyBpKyspIHtcbiAgICAgIGlmICghc2V0c0VxdWFsKGNoYW5nZVNldCwgbWFrZVNldChpKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gQXJyYXkuZnJvbShjaGFuZ2VTZXQpXG4gICAgICAubWFwKGMgPT4gYy5zcGxpdCgnLCcpKVxuICAgICAgLm1hcChhID0+ICh7bWV0aG9kOiBhWzFdLCBzdGFydDogK2FbMl0sIGNvdW50OiArYVszXX0pKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBVcGRhdGVzIHRoZSBjaGFydCBsYXlvdXQgdW5sZXNzIGEgcGx1Z2luIHJldHVybnMgYGZhbHNlYCB0byB0aGUgYGJlZm9yZUxheW91dGBcblx0ICogaG9vaywgaW4gd2hpY2ggY2FzZSwgcGx1Z2lucyB3aWxsIG5vdCBiZSBjYWxsZWQgb24gYGFmdGVyTGF5b3V0YC5cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF91cGRhdGVMYXlvdXQobWluUGFkZGluZykge1xuICAgIGlmICh0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZUxheW91dCcsIHtjYW5jZWxhYmxlOiB0cnVlfSkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGF5b3V0cy51cGRhdGUodGhpcywgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQsIG1pblBhZGRpbmcpO1xuXG4gICAgY29uc3QgYXJlYSA9IHRoaXMuY2hhcnRBcmVhO1xuICAgIGNvbnN0IG5vQXJlYSA9IGFyZWEud2lkdGggPD0gMCB8fCBhcmVhLmhlaWdodCA8PSAwO1xuXG4gICAgdGhpcy5fbGF5ZXJzID0gW107XG4gICAgZWFjaCh0aGlzLmJveGVzLCAoYm94KSA9PiB7XG4gICAgICBpZiAobm9BcmVhICYmIGJveC5wb3NpdGlvbiA9PT0gJ2NoYXJ0QXJlYScpIHtcbiAgICAgICAgLy8gU2tpcCBkcmF3aW5nIGFuZCBjb25maWd1cmluZyBjaGFydEFyZWEgYm94ZXMgd2hlbiBjaGFydEFyZWEgaXMgemVybyBvciBuZWdhdGl2ZVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGNvbmZpZ3VyZSBpcyBjYWxsZWQgdHdpY2UsIG9uY2UgaW4gY29yZS5zY2FsZS51cGRhdGUgYW5kIG9uY2UgaGVyZS5cbiAgICAgIC8vIEhlcmUgdGhlIGJveGVzIGFyZSBmdWxseSB1cGRhdGVkIGFuZCBhdCB0aGVpciBmaW5hbCBwb3NpdGlvbnMuXG4gICAgICBpZiAoYm94LmNvbmZpZ3VyZSkge1xuICAgICAgICBib3guY29uZmlndXJlKCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9sYXllcnMucHVzaCguLi5ib3guX2xheWVycygpKTtcbiAgICB9LCB0aGlzKTtcblxuICAgIHRoaXMuX2xheWVycy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgaXRlbS5faWR4ID0gaW5kZXg7XG4gICAgfSk7XG5cbiAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyTGF5b3V0Jyk7XG4gIH1cblxuICAvKipcblx0ICogVXBkYXRlcyBhbGwgZGF0YXNldHMgdW5sZXNzIGEgcGx1Z2luIHJldHVybnMgYGZhbHNlYCB0byB0aGUgYGJlZm9yZURhdGFzZXRzVXBkYXRlYFxuXHQgKiBob29rLCBpbiB3aGljaCBjYXNlLCBwbHVnaW5zIHdpbGwgbm90IGJlIGNhbGxlZCBvbiBgYWZ0ZXJEYXRhc2V0c1VwZGF0ZWAuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdXBkYXRlRGF0YXNldHMobW9kZSkge1xuICAgIGlmICh0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZURhdGFzZXRzVXBkYXRlJywge21vZGUsIGNhbmNlbGFibGU6IHRydWV9KSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMCwgaWxlbiA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHRoaXMuZ2V0RGF0YXNldE1ldGEoaSkuY29udHJvbGxlci5jb25maWd1cmUoKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMCwgaWxlbiA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURhdGFzZXQoaSwgaXNGdW5jdGlvbihtb2RlKSA/IG1vZGUoe2RhdGFzZXRJbmRleDogaX0pIDogbW9kZSk7XG4gICAgfVxuXG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdhZnRlckRhdGFzZXRzVXBkYXRlJywge21vZGV9KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBVcGRhdGVzIGRhdGFzZXQgYXQgaW5kZXggdW5sZXNzIGEgcGx1Z2luIHJldHVybnMgYGZhbHNlYCB0byB0aGUgYGJlZm9yZURhdGFzZXRVcGRhdGVgXG5cdCAqIGhvb2ssIGluIHdoaWNoIGNhc2UsIHBsdWdpbnMgd2lsbCBub3QgYmUgY2FsbGVkIG9uIGBhZnRlckRhdGFzZXRVcGRhdGVgLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3VwZGF0ZURhdGFzZXQoaW5kZXgsIG1vZGUpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShpbmRleCk7XG4gICAgY29uc3QgYXJncyA9IHttZXRhLCBpbmRleCwgbW9kZSwgY2FuY2VsYWJsZTogdHJ1ZX07XG5cbiAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVEYXRhc2V0VXBkYXRlJywgYXJncykgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbWV0YS5jb250cm9sbGVyLl91cGRhdGUobW9kZSk7XG5cbiAgICBhcmdzLmNhbmNlbGFibGUgPSBmYWxzZTtcbiAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyRGF0YXNldFVwZGF0ZScsIGFyZ3MpO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGlmICh0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZVJlbmRlcicsIHtjYW5jZWxhYmxlOiB0cnVlfSkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGFuaW1hdG9yLmhhcyh0aGlzKSkge1xuICAgICAgaWYgKHRoaXMuYXR0YWNoZWQgJiYgIWFuaW1hdG9yLnJ1bm5pbmcodGhpcykpIHtcbiAgICAgICAgYW5pbWF0b3Iuc3RhcnQodGhpcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZHJhdygpO1xuICAgICAgb25BbmltYXRpb25zQ29tcGxldGUoe2NoYXJ0OiB0aGlzfSk7XG4gICAgfVxuICB9XG5cbiAgZHJhdygpIHtcbiAgICBsZXQgaTtcbiAgICBpZiAodGhpcy5fcmVzaXplQmVmb3JlRHJhdykge1xuICAgICAgY29uc3Qge3dpZHRoLCBoZWlnaHR9ID0gdGhpcy5fcmVzaXplQmVmb3JlRHJhdztcbiAgICAgIHRoaXMuX3Jlc2l6ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIHRoaXMuX3Jlc2l6ZUJlZm9yZURyYXcgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLmNsZWFyKCk7XG5cbiAgICBpZiAodGhpcy53aWR0aCA8PSAwIHx8IHRoaXMuaGVpZ2h0IDw9IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVEcmF3Jywge2NhbmNlbGFibGU6IHRydWV9KSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBCZWNhdXNlIG9mIHBsdWdpbiBob29rcyAoYmVmb3JlL2FmdGVyRGF0YXNldHNEcmF3KSwgZGF0YXNldHMgY2FuJ3RcbiAgICAvLyBjdXJyZW50bHkgYmUgcGFydCBvZiBsYXllcnMuIEluc3RlYWQsIHdlIGRyYXdcbiAgICAvLyBsYXllcnMgPD0gMCBiZWZvcmUoZGVmYXVsdCwgYmFja3dhcmQgY29tcGF0KSwgYW5kIHRoZSByZXN0IGFmdGVyXG4gICAgY29uc3QgbGF5ZXJzID0gdGhpcy5fbGF5ZXJzO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsYXllcnMubGVuZ3RoICYmIGxheWVyc1tpXS56IDw9IDA7ICsraSkge1xuICAgICAgbGF5ZXJzW2ldLmRyYXcodGhpcy5jaGFydEFyZWEpO1xuICAgIH1cblxuICAgIHRoaXMuX2RyYXdEYXRhc2V0cygpO1xuXG4gICAgLy8gUmVzdCBvZiBsYXllcnNcbiAgICBmb3IgKDsgaSA8IGxheWVycy5sZW5ndGg7ICsraSkge1xuICAgICAgbGF5ZXJzW2ldLmRyYXcodGhpcy5jaGFydEFyZWEpO1xuICAgIH1cblxuICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJEcmF3Jyk7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRTb3J0ZWREYXRhc2V0TWV0YXMoZmlsdGVyVmlzaWJsZSkge1xuICAgIGNvbnN0IG1ldGFzZXRzID0gdGhpcy5fc29ydGVkTWV0YXNldHM7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgbGV0IGksIGlsZW47XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gbWV0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBjb25zdCBtZXRhID0gbWV0YXNldHNbaV07XG4gICAgICBpZiAoIWZpbHRlclZpc2libGUgfHwgbWV0YS52aXNpYmxlKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKG1ldGEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcblx0ICogR2V0cyB0aGUgdmlzaWJsZSBkYXRhc2V0IG1ldGFzIGluIGRyYXdpbmcgb3JkZXJcblx0ICogQHJldHVybiB7b2JqZWN0W119XG5cdCAqL1xuICBnZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRTb3J0ZWREYXRhc2V0TWV0YXModHJ1ZSk7XG4gIH1cblxuICAvKipcblx0ICogRHJhd3MgYWxsIGRhdGFzZXRzIHVubGVzcyBhIHBsdWdpbiByZXR1cm5zIGBmYWxzZWAgdG8gdGhlIGBiZWZvcmVEYXRhc2V0c0RyYXdgXG5cdCAqIGhvb2ssIGluIHdoaWNoIGNhc2UsIHBsdWdpbnMgd2lsbCBub3QgYmUgY2FsbGVkIG9uIGBhZnRlckRhdGFzZXRzRHJhd2AuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZHJhd0RhdGFzZXRzKCkge1xuICAgIGlmICh0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZURhdGFzZXRzRHJhdycsIHtjYW5jZWxhYmxlOiB0cnVlfSkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbWV0YXNldHMgPSB0aGlzLmdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKTtcbiAgICBmb3IgKGxldCBpID0gbWV0YXNldHMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHRoaXMuX2RyYXdEYXRhc2V0KG1ldGFzZXRzW2ldKTtcbiAgICB9XG5cbiAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyRGF0YXNldHNEcmF3Jyk7XG4gIH1cblxuICAvKipcblx0ICogRHJhd3MgZGF0YXNldCBhdCBpbmRleCB1bmxlc3MgYSBwbHVnaW4gcmV0dXJucyBgZmFsc2VgIHRvIHRoZSBgYmVmb3JlRGF0YXNldERyYXdgXG5cdCAqIGhvb2ssIGluIHdoaWNoIGNhc2UsIHBsdWdpbnMgd2lsbCBub3QgYmUgY2FsbGVkIG9uIGBhZnRlckRhdGFzZXREcmF3YC5cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9kcmF3RGF0YXNldChtZXRhKSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgY2xpcCA9IG1ldGEuX2NsaXA7XG4gICAgY29uc3QgdXNlQ2xpcCA9ICFjbGlwLmRpc2FibGVkO1xuICAgIGNvbnN0IGFyZWEgPSBnZXREYXRhc2V0QXJlYShtZXRhLCB0aGlzLmNoYXJ0QXJlYSk7XG4gICAgY29uc3QgYXJncyA9IHtcbiAgICAgIG1ldGEsXG4gICAgICBpbmRleDogbWV0YS5pbmRleCxcbiAgICAgIGNhbmNlbGFibGU6IHRydWVcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlRGF0YXNldERyYXcnLCBhcmdzKSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodXNlQ2xpcCkge1xuICAgICAgY2xpcEFyZWEoY3R4LCB7XG4gICAgICAgIGxlZnQ6IGNsaXAubGVmdCA9PT0gZmFsc2UgPyAwIDogYXJlYS5sZWZ0IC0gY2xpcC5sZWZ0LFxuICAgICAgICByaWdodDogY2xpcC5yaWdodCA9PT0gZmFsc2UgPyB0aGlzLndpZHRoIDogYXJlYS5yaWdodCArIGNsaXAucmlnaHQsXG4gICAgICAgIHRvcDogY2xpcC50b3AgPT09IGZhbHNlID8gMCA6IGFyZWEudG9wIC0gY2xpcC50b3AsXG4gICAgICAgIGJvdHRvbTogY2xpcC5ib3R0b20gPT09IGZhbHNlID8gdGhpcy5oZWlnaHQgOiBhcmVhLmJvdHRvbSArIGNsaXAuYm90dG9tXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBtZXRhLmNvbnRyb2xsZXIuZHJhdygpO1xuXG4gICAgaWYgKHVzZUNsaXApIHtcbiAgICAgIHVuY2xpcEFyZWEoY3R4KTtcbiAgICB9XG5cbiAgICBhcmdzLmNhbmNlbGFibGUgPSBmYWxzZTtcbiAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyRGF0YXNldERyYXcnLCBhcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gcG9pbnQgaXMgaW4gdGhlIGNoYXJ0IGFyZWEuXG4gICAqIEBwYXJhbSB7UG9pbnR9IHBvaW50IC0gaW4gcmVsYXRpdmUgY29vcmRpbmF0ZXMgKHNlZSwgZS5nLiwgZ2V0UmVsYXRpdmVQb3NpdGlvbilcbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBpc1BvaW50SW5BcmVhKHBvaW50KSB7XG4gICAgcmV0dXJuIF9pc1BvaW50SW5BcmVhKHBvaW50LCB0aGlzLmNoYXJ0QXJlYSwgdGhpcy5fbWluUGFkZGluZyk7XG4gIH1cblxuICBnZXRFbGVtZW50c0F0RXZlbnRGb3JNb2RlKGUsIG1vZGUsIG9wdGlvbnMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICBjb25zdCBtZXRob2QgPSBJbnRlcmFjdGlvbi5tb2Rlc1ttb2RlXTtcbiAgICBpZiAodHlwZW9mIG1ldGhvZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIG1ldGhvZCh0aGlzLCBlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW107XG4gIH1cblxuICBnZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpIHtcbiAgICBjb25zdCBkYXRhc2V0ID0gdGhpcy5kYXRhLmRhdGFzZXRzW2RhdGFzZXRJbmRleF07XG4gICAgY29uc3QgbWV0YXNldHMgPSB0aGlzLl9tZXRhc2V0cztcbiAgICBsZXQgbWV0YSA9IG1ldGFzZXRzLmZpbHRlcih4ID0+IHggJiYgeC5fZGF0YXNldCA9PT0gZGF0YXNldCkucG9wKCk7XG5cbiAgICBpZiAoIW1ldGEpIHtcbiAgICAgIG1ldGEgPSB7XG4gICAgICAgIHR5cGU6IG51bGwsXG4gICAgICAgIGRhdGE6IFtdLFxuICAgICAgICBkYXRhc2V0OiBudWxsLFxuICAgICAgICBjb250cm9sbGVyOiBudWxsLFxuICAgICAgICBoaWRkZW46IG51bGwsXHRcdFx0Ly8gU2VlIGlzRGF0YXNldFZpc2libGUoKSBjb21tZW50XG4gICAgICAgIHhBeGlzSUQ6IG51bGwsXG4gICAgICAgIHlBeGlzSUQ6IG51bGwsXG4gICAgICAgIG9yZGVyOiBkYXRhc2V0ICYmIGRhdGFzZXQub3JkZXIgfHwgMCxcbiAgICAgICAgaW5kZXg6IGRhdGFzZXRJbmRleCxcbiAgICAgICAgX2RhdGFzZXQ6IGRhdGFzZXQsXG4gICAgICAgIF9wYXJzZWQ6IFtdLFxuICAgICAgICBfc29ydGVkOiBmYWxzZVxuICAgICAgfTtcbiAgICAgIG1ldGFzZXRzLnB1c2gobWV0YSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1ldGE7XG4gIH1cblxuICBnZXRDb250ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLiRjb250ZXh0IHx8ICh0aGlzLiRjb250ZXh0ID0gY3JlYXRlQ29udGV4dChudWxsLCB7Y2hhcnQ6IHRoaXMsIHR5cGU6ICdjaGFydCd9KSk7XG4gIH1cblxuICBnZXRWaXNpYmxlRGF0YXNldENvdW50KCkge1xuICAgIHJldHVybiB0aGlzLmdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKS5sZW5ndGg7XG4gIH1cblxuICBpc0RhdGFzZXRWaXNpYmxlKGRhdGFzZXRJbmRleCkge1xuICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XTtcbiAgICBpZiAoIWRhdGFzZXQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xuXG4gICAgLy8gbWV0YS5oaWRkZW4gaXMgYSBwZXIgY2hhcnQgZGF0YXNldCBoaWRkZW4gZmxhZyBvdmVycmlkZSB3aXRoIDMgc3RhdGVzOiBpZiB0cnVlIG9yIGZhbHNlLFxuICAgIC8vIHRoZSBkYXRhc2V0LmhpZGRlbiB2YWx1ZSBpcyBpZ25vcmVkLCBlbHNlIGlmIG51bGwsIHRoZSBkYXRhc2V0IGhpZGRlbiBzdGF0ZSBpcyByZXR1cm5lZC5cbiAgICByZXR1cm4gdHlwZW9mIG1ldGEuaGlkZGVuID09PSAnYm9vbGVhbicgPyAhbWV0YS5oaWRkZW4gOiAhZGF0YXNldC5oaWRkZW47XG4gIH1cblxuICBzZXREYXRhc2V0VmlzaWJpbGl0eShkYXRhc2V0SW5kZXgsIHZpc2libGUpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xuICAgIG1ldGEuaGlkZGVuID0gIXZpc2libGU7XG4gIH1cblxuICB0b2dnbGVEYXRhVmlzaWJpbGl0eShpbmRleCkge1xuICAgIHRoaXMuX2hpZGRlbkluZGljZXNbaW5kZXhdID0gIXRoaXMuX2hpZGRlbkluZGljZXNbaW5kZXhdO1xuICB9XG5cbiAgZ2V0RGF0YVZpc2liaWxpdHkoaW5kZXgpIHtcbiAgICByZXR1cm4gIXRoaXMuX2hpZGRlbkluZGljZXNbaW5kZXhdO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdXBkYXRlVmlzaWJpbGl0eShkYXRhc2V0SW5kZXgsIGRhdGFJbmRleCwgdmlzaWJsZSkge1xuICAgIGNvbnN0IG1vZGUgPSB2aXNpYmxlID8gJ3Nob3cnIDogJ2hpZGUnO1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG4gICAgY29uc3QgYW5pbXMgPSBtZXRhLmNvbnRyb2xsZXIuX3Jlc29sdmVBbmltYXRpb25zKHVuZGVmaW5lZCwgbW9kZSk7XG5cbiAgICBpZiAoZGVmaW5lZChkYXRhSW5kZXgpKSB7XG4gICAgICBtZXRhLmRhdGFbZGF0YUluZGV4XS5oaWRkZW4gPSAhdmlzaWJsZTtcbiAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0RGF0YXNldFZpc2liaWxpdHkoZGF0YXNldEluZGV4LCB2aXNpYmxlKTtcbiAgICAgIC8vIEFuaW1hdGUgdmlzaWJsZSBzdGF0ZSwgc28gaGlkZSBhbmltYXRpb24gY2FuIGJlIHNlZW4uIFRoaXMgY291bGQgYmUgaGFuZGxlZCBiZXR0ZXIgaWYgdXBkYXRlIC8gdXBkYXRlRGF0YXNldCByZXR1cm5lZCBhIFByb21pc2UuXG4gICAgICBhbmltcy51cGRhdGUobWV0YSwge3Zpc2libGV9KTtcbiAgICAgIHRoaXMudXBkYXRlKChjdHgpID0+IGN0eC5kYXRhc2V0SW5kZXggPT09IGRhdGFzZXRJbmRleCA/IG1vZGUgOiB1bmRlZmluZWQpO1xuICAgIH1cbiAgfVxuXG4gIGhpZGUoZGF0YXNldEluZGV4LCBkYXRhSW5kZXgpIHtcbiAgICB0aGlzLl91cGRhdGVWaXNpYmlsaXR5KGRhdGFzZXRJbmRleCwgZGF0YUluZGV4LCBmYWxzZSk7XG4gIH1cblxuICBzaG93KGRhdGFzZXRJbmRleCwgZGF0YUluZGV4KSB7XG4gICAgdGhpcy5fdXBkYXRlVmlzaWJpbGl0eShkYXRhc2V0SW5kZXgsIGRhdGFJbmRleCwgdHJ1ZSk7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9kZXN0cm95RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX21ldGFzZXRzW2RhdGFzZXRJbmRleF07XG4gICAgaWYgKG1ldGEgJiYgbWV0YS5jb250cm9sbGVyKSB7XG4gICAgICBtZXRhLmNvbnRyb2xsZXIuX2Rlc3Ryb3koKTtcbiAgICB9XG4gICAgZGVsZXRlIHRoaXMuX21ldGFzZXRzW2RhdGFzZXRJbmRleF07XG4gIH1cblxuICBfc3RvcCgpIHtcbiAgICBsZXQgaSwgaWxlbjtcbiAgICB0aGlzLnN0b3AoKTtcbiAgICBhbmltYXRvci5yZW1vdmUodGhpcyk7XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gdGhpcy5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgdGhpcy5fZGVzdHJveURhdGFzZXRNZXRhKGkpO1xuICAgIH1cbiAgfVxuXG4gIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVEZXN0cm95Jyk7XG4gICAgY29uc3Qge2NhbnZhcywgY3R4fSA9IHRoaXM7XG5cbiAgICB0aGlzLl9zdG9wKCk7XG4gICAgdGhpcy5jb25maWcuY2xlYXJDYWNoZSgpO1xuXG4gICAgaWYgKGNhbnZhcykge1xuICAgICAgdGhpcy51bmJpbmRFdmVudHMoKTtcbiAgICAgIGNsZWFyQ2FudmFzKGNhbnZhcywgY3R4KTtcbiAgICAgIHRoaXMucGxhdGZvcm0ucmVsZWFzZUNvbnRleHQoY3R4KTtcbiAgICAgIHRoaXMuY2FudmFzID0gbnVsbDtcbiAgICAgIHRoaXMuY3R4ID0gbnVsbDtcbiAgICB9XG5cbiAgICBkZWxldGUgaW5zdGFuY2VzW3RoaXMuaWRdO1xuXG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdhZnRlckRlc3Ryb3knKTtcbiAgfVxuXG4gIHRvQmFzZTY0SW1hZ2UoLi4uYXJncykge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy50b0RhdGFVUkwoLi4uYXJncyk7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIGJpbmRFdmVudHMoKSB7XG4gICAgdGhpcy5iaW5kVXNlckV2ZW50cygpO1xuICAgIGlmICh0aGlzLm9wdGlvbnMucmVzcG9uc2l2ZSkge1xuICAgICAgdGhpcy5iaW5kUmVzcG9uc2l2ZUV2ZW50cygpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmF0dGFjaGVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGJpbmRVc2VyRXZlbnRzKCkge1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycztcbiAgICBjb25zdCBwbGF0Zm9ybSA9IHRoaXMucGxhdGZvcm07XG5cbiAgICBjb25zdCBfYWRkID0gKHR5cGUsIGxpc3RlbmVyKSA9PiB7XG4gICAgICBwbGF0Zm9ybS5hZGRFdmVudExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyKTtcbiAgICAgIGxpc3RlbmVyc1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgIH07XG5cbiAgICBjb25zdCBsaXN0ZW5lciA9IChlLCB4LCB5KSA9PiB7XG4gICAgICBlLm9mZnNldFggPSB4O1xuICAgICAgZS5vZmZzZXRZID0geTtcbiAgICAgIHRoaXMuX2V2ZW50SGFuZGxlcihlKTtcbiAgICB9O1xuXG4gICAgZWFjaCh0aGlzLm9wdGlvbnMuZXZlbnRzLCAodHlwZSkgPT4gX2FkZCh0eXBlLCBsaXN0ZW5lcikpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBiaW5kUmVzcG9uc2l2ZUV2ZW50cygpIHtcbiAgICBpZiAoIXRoaXMuX3Jlc3BvbnNpdmVMaXN0ZW5lcnMpIHtcbiAgICAgIHRoaXMuX3Jlc3BvbnNpdmVMaXN0ZW5lcnMgPSB7fTtcbiAgICB9XG4gICAgY29uc3QgbGlzdGVuZXJzID0gdGhpcy5fcmVzcG9uc2l2ZUxpc3RlbmVycztcbiAgICBjb25zdCBwbGF0Zm9ybSA9IHRoaXMucGxhdGZvcm07XG5cbiAgICBjb25zdCBfYWRkID0gKHR5cGUsIGxpc3RlbmVyKSA9PiB7XG4gICAgICBwbGF0Zm9ybS5hZGRFdmVudExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyKTtcbiAgICAgIGxpc3RlbmVyc1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgIH07XG4gICAgY29uc3QgX3JlbW92ZSA9ICh0eXBlLCBsaXN0ZW5lcikgPT4ge1xuICAgICAgaWYgKGxpc3RlbmVyc1t0eXBlXSkge1xuICAgICAgICBwbGF0Zm9ybS5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgZGVsZXRlIGxpc3RlbmVyc1t0eXBlXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgbGlzdGVuZXIgPSAod2lkdGgsIGhlaWdodCkgPT4ge1xuICAgICAgaWYgKHRoaXMuY2FudmFzKSB7XG4gICAgICAgIHRoaXMucmVzaXplKHdpZHRoLCBoZWlnaHQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBsZXQgZGV0YWNoZWQ7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgY29uc3QgYXR0YWNoZWQgPSAoKSA9PiB7XG4gICAgICBfcmVtb3ZlKCdhdHRhY2gnLCBhdHRhY2hlZCk7XG5cbiAgICAgIHRoaXMuYXR0YWNoZWQgPSB0cnVlO1xuICAgICAgdGhpcy5yZXNpemUoKTtcblxuICAgICAgX2FkZCgncmVzaXplJywgbGlzdGVuZXIpO1xuICAgICAgX2FkZCgnZGV0YWNoJywgZGV0YWNoZWQpO1xuICAgIH07XG5cbiAgICBkZXRhY2hlZCA9ICgpID0+IHtcbiAgICAgIHRoaXMuYXR0YWNoZWQgPSBmYWxzZTtcblxuICAgICAgX3JlbW92ZSgncmVzaXplJywgbGlzdGVuZXIpO1xuXG4gICAgICAvLyBTdG9wIGFuaW1hdGluZyBhbmQgcmVtb3ZlIG1ldGFzZXRzLCBzbyB3aGVuIHJlLWF0dGFjaGVkLCB0aGUgYW5pbWF0aW9ucyBzdGFydCBmcm9tIGJlZ2lubmluZy5cbiAgICAgIHRoaXMuX3N0b3AoKTtcbiAgICAgIHRoaXMuX3Jlc2l6ZSgwLCAwKTtcblxuICAgICAgX2FkZCgnYXR0YWNoJywgYXR0YWNoZWQpO1xuICAgIH07XG5cbiAgICBpZiAocGxhdGZvcm0uaXNBdHRhY2hlZCh0aGlzLmNhbnZhcykpIHtcbiAgICAgIGF0dGFjaGVkKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRldGFjaGVkKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICB1bmJpbmRFdmVudHMoKSB7XG4gICAgZWFjaCh0aGlzLl9saXN0ZW5lcnMsIChsaXN0ZW5lciwgdHlwZSkgPT4ge1xuICAgICAgdGhpcy5wbGF0Zm9ybS5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyKTtcbiAgICB9KTtcbiAgICB0aGlzLl9saXN0ZW5lcnMgPSB7fTtcblxuICAgIGVhY2godGhpcy5fcmVzcG9uc2l2ZUxpc3RlbmVycywgKGxpc3RlbmVyLCB0eXBlKSA9PiB7XG4gICAgICB0aGlzLnBsYXRmb3JtLnJlbW92ZUV2ZW50TGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIpO1xuICAgIH0pO1xuICAgIHRoaXMuX3Jlc3BvbnNpdmVMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG4gIH1cblxuICB1cGRhdGVIb3ZlclN0eWxlKGl0ZW1zLCBtb2RlLCBlbmFibGVkKSB7XG4gICAgY29uc3QgcHJlZml4ID0gZW5hYmxlZCA/ICdzZXQnIDogJ3JlbW92ZSc7XG4gICAgbGV0IG1ldGEsIGl0ZW0sIGksIGlsZW47XG5cbiAgICBpZiAobW9kZSA9PT0gJ2RhdGFzZXQnKSB7XG4gICAgICBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShpdGVtc1swXS5kYXRhc2V0SW5kZXgpO1xuICAgICAgbWV0YS5jb250cm9sbGVyWydfJyArIHByZWZpeCArICdEYXRhc2V0SG92ZXJTdHlsZSddKCk7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgaXRlbSA9IGl0ZW1zW2ldO1xuICAgICAgY29uc3QgY29udHJvbGxlciA9IGl0ZW0gJiYgdGhpcy5nZXREYXRhc2V0TWV0YShpdGVtLmRhdGFzZXRJbmRleCkuY29udHJvbGxlcjtcbiAgICAgIGlmIChjb250cm9sbGVyKSB7XG4gICAgICAgIGNvbnRyb2xsZXJbcHJlZml4ICsgJ0hvdmVyU3R5bGUnXShpdGVtLmVsZW1lbnQsIGl0ZW0uZGF0YXNldEluZGV4LCBpdGVtLmluZGV4KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogR2V0IGFjdGl2ZSAoaG92ZXJlZCkgZWxlbWVudHNcblx0ICogQHJldHVybnMgYXJyYXlcblx0ICovXG4gIGdldEFjdGl2ZUVsZW1lbnRzKCkge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmUgfHwgW107XG4gIH1cblxuICAvKipcblx0ICogU2V0IGFjdGl2ZSAoaG92ZXJlZCkgZWxlbWVudHNcblx0ICogQHBhcmFtIHthcnJheX0gYWN0aXZlRWxlbWVudHMgTmV3IGFjdGl2ZSBkYXRhIHBvaW50c1xuXHQgKi9cbiAgc2V0QWN0aXZlRWxlbWVudHMoYWN0aXZlRWxlbWVudHMpIHtcbiAgICBjb25zdCBsYXN0QWN0aXZlID0gdGhpcy5fYWN0aXZlIHx8IFtdO1xuICAgIGNvbnN0IGFjdGl2ZSA9IGFjdGl2ZUVsZW1lbnRzLm1hcCgoe2RhdGFzZXRJbmRleCwgaW5kZXh9KSA9PiB7XG4gICAgICBjb25zdCBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xuICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gZGF0YXNldCBmb3VuZCBhdCBpbmRleCAnICsgZGF0YXNldEluZGV4KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YXNldEluZGV4LFxuICAgICAgICBlbGVtZW50OiBtZXRhLmRhdGFbaW5kZXhdLFxuICAgICAgICBpbmRleCxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgY29uc3QgY2hhbmdlZCA9ICFfZWxlbWVudHNFcXVhbChhY3RpdmUsIGxhc3RBY3RpdmUpO1xuXG4gICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgIHRoaXMuX2FjdGl2ZSA9IGFjdGl2ZTtcbiAgICAgIC8vIE1ha2Ugc3VyZSB3ZSBkb24ndCB1c2UgdGhlIHByZXZpb3VzIG1vdXNlIGV2ZW50IHRvIG92ZXJyaWRlIHRoZSBhY3RpdmUgZWxlbWVudHMgaW4gdXBkYXRlLlxuICAgICAgdGhpcy5fbGFzdEV2ZW50ID0gbnVsbDtcbiAgICAgIHRoaXMuX3VwZGF0ZUhvdmVyU3R5bGVzKGFjdGl2ZSwgbGFzdEFjdGl2ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIENhbGxzIGVuYWJsZWQgcGx1Z2lucyBvbiB0aGUgc3BlY2lmaWVkIGhvb2sgYW5kIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG5cdCAqIFRoaXMgbWV0aG9kIGltbWVkaWF0ZWx5IHJldHVybnMgYXMgc29vbiBhcyBhIHBsdWdpbiBleHBsaWNpdGx5IHJldHVybnMgZmFsc2UuIFRoZVxuXHQgKiByZXR1cm5lZCB2YWx1ZSBjYW4gYmUgdXNlZCwgZm9yIGluc3RhbmNlLCB0byBpbnRlcnJ1cHQgdGhlIGN1cnJlbnQgYWN0aW9uLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaG9vayAtIFRoZSBuYW1lIG9mIHRoZSBwbHVnaW4gbWV0aG9kIHRvIGNhbGwgKGUuZy4gJ2JlZm9yZVVwZGF0ZScpLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gW2FyZ3NdIC0gRXh0cmEgYXJndW1lbnRzIHRvIGFwcGx5IHRvIHRoZSBob29rIGNhbGwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KCcuL2NvcmUucGx1Z2lucy5qcycpLmZpbHRlckNhbGxiYWNrfSBbZmlsdGVyXSAtIEZpbHRlcmluZyBmdW5jdGlvbiBmb3IgbGltaXRpbmcgd2hpY2ggcGx1Z2lucyBhcmUgbm90aWZpZWRcblx0ICogQHJldHVybnMge2Jvb2xlYW59IGZhbHNlIGlmIGFueSBvZiB0aGUgcGx1Z2lucyByZXR1cm4gZmFsc2UsIGVsc2UgcmV0dXJucyB0cnVlLlxuXHQgKi9cbiAgbm90aWZ5UGx1Z2lucyhob29rLCBhcmdzLCBmaWx0ZXIpIHtcbiAgICByZXR1cm4gdGhpcy5fcGx1Z2lucy5ub3RpZnkodGhpcywgaG9vaywgYXJncywgZmlsdGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHBsdWdpbiB3aXRoIHRoZSBzcGVjaWZpYyBJRCBpcyByZWdpc3RlcmVkIGFuZCBlbmFibGVkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwbHVnaW5JZCAtIFRoZSBJRCBvZiB0aGUgcGx1Z2luIG9mIHdoaWNoIHRvIGNoZWNrIGlmIGl0IGlzIGVuYWJsZWRcbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBpc1BsdWdpbkVuYWJsZWQocGx1Z2luSWQpIHtcbiAgICByZXR1cm4gdGhpcy5fcGx1Z2lucy5fY2FjaGUuZmlsdGVyKHAgPT4gcC5wbHVnaW4uaWQgPT09IHBsdWdpbklkKS5sZW5ndGggPT09IDE7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF91cGRhdGVIb3ZlclN0eWxlcyhhY3RpdmUsIGxhc3RBY3RpdmUsIHJlcGxheSkge1xuICAgIGNvbnN0IGhvdmVyT3B0aW9ucyA9IHRoaXMub3B0aW9ucy5ob3ZlcjtcbiAgICBjb25zdCBkaWZmID0gKGEsIGIpID0+IGEuZmlsdGVyKHggPT4gIWIuc29tZSh5ID0+IHguZGF0YXNldEluZGV4ID09PSB5LmRhdGFzZXRJbmRleCAmJiB4LmluZGV4ID09PSB5LmluZGV4KSk7XG4gICAgY29uc3QgZGVhY3RpdmF0ZWQgPSBkaWZmKGxhc3RBY3RpdmUsIGFjdGl2ZSk7XG4gICAgY29uc3QgYWN0aXZhdGVkID0gcmVwbGF5ID8gYWN0aXZlIDogZGlmZihhY3RpdmUsIGxhc3RBY3RpdmUpO1xuXG4gICAgaWYgKGRlYWN0aXZhdGVkLmxlbmd0aCkge1xuICAgICAgdGhpcy51cGRhdGVIb3ZlclN0eWxlKGRlYWN0aXZhdGVkLCBob3Zlck9wdGlvbnMubW9kZSwgZmFsc2UpO1xuICAgIH1cblxuICAgIGlmIChhY3RpdmF0ZWQubGVuZ3RoICYmIGhvdmVyT3B0aW9ucy5tb2RlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUhvdmVyU3R5bGUoYWN0aXZhdGVkLCBob3Zlck9wdGlvbnMubW9kZSwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZXZlbnRIYW5kbGVyKGUsIHJlcGxheSkge1xuICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICBldmVudDogZSxcbiAgICAgIHJlcGxheSxcbiAgICAgIGNhbmNlbGFibGU6IHRydWUsXG4gICAgICBpbkNoYXJ0QXJlYTogdGhpcy5pc1BvaW50SW5BcmVhKGUpXG4gICAgfTtcbiAgICBjb25zdCBldmVudEZpbHRlciA9IChwbHVnaW4pID0+IChwbHVnaW4ub3B0aW9ucy5ldmVudHMgfHwgdGhpcy5vcHRpb25zLmV2ZW50cykuaW5jbHVkZXMoZS5uYXRpdmUudHlwZSk7XG5cbiAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVFdmVudCcsIGFyZ3MsIGV2ZW50RmlsdGVyKSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjaGFuZ2VkID0gdGhpcy5faGFuZGxlRXZlbnQoZSwgcmVwbGF5LCBhcmdzLmluQ2hhcnRBcmVhKTtcblxuICAgIGFyZ3MuY2FuY2VsYWJsZSA9IGZhbHNlO1xuICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJFdmVudCcsIGFyZ3MsIGV2ZW50RmlsdGVyKTtcblxuICAgIGlmIChjaGFuZ2VkIHx8IGFyZ3MuY2hhbmdlZCkge1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuXHQgKiBIYW5kbGUgYW4gZXZlbnRcblx0ICogQHBhcmFtIHtDaGFydEV2ZW50fSBlIHRoZSBldmVudCB0byBoYW5kbGVcblx0ICogQHBhcmFtIHtib29sZWFufSBbcmVwbGF5XSAtIHRydWUgaWYgdGhlIGV2ZW50IHdhcyByZXBsYXllZCBieSBgdXBkYXRlYFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpbkNoYXJ0QXJlYV0gLSB0cnVlIGlmIHRoZSBldmVudCBpcyBpbnNpZGUgY2hhcnRBcmVhXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgdGhlIGNoYXJ0IG5lZWRzIHRvIHJlLXJlbmRlclxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2hhbmRsZUV2ZW50KGUsIHJlcGxheSwgaW5DaGFydEFyZWEpIHtcbiAgICBjb25zdCB7X2FjdGl2ZTogbGFzdEFjdGl2ZSA9IFtdLCBvcHRpb25zfSA9IHRoaXM7XG5cbiAgICAvLyBJZiB0aGUgZXZlbnQgaXMgcmVwbGF5ZWQgZnJvbSBgdXBkYXRlYCwgd2Ugc2hvdWxkIGV2YWx1YXRlIHdpdGggdGhlIGZpbmFsIHBvc2l0aW9ucy5cbiAgICAvL1xuICAgIC8vIFRoZSBgcmVwbGF5YDpcbiAgICAvLyBJdCdzIHRoZSBsYXN0IGV2ZW50IChleGNsdWRpbmcgY2xpY2spIHRoYXQgaGFzIG9jY3VycmVkIGJlZm9yZSBgdXBkYXRlYC5cbiAgICAvLyBTbyBtb3VzZSBoYXMgbm90IG1vdmVkLiBJdCdzIGFsc28gb3ZlciB0aGUgY2hhcnQsIGJlY2F1c2UgdGhlcmUgaXMgYSBgcmVwbGF5YC5cbiAgICAvL1xuICAgIC8vIFRoZSB3aHk6XG4gICAgLy8gSWYgYW5pbWF0aW9ucyBhcmUgYWN0aXZlLCB0aGUgZWxlbWVudHMgaGF2ZW4ndCBtb3ZlZCB5ZXQgY29tcGFyZWQgdG8gc3RhdGUgYmVmb3JlIHVwZGF0ZS5cbiAgICAvLyBCdXQgaWYgdGhleSB3aWxsLCB3ZSBhcmUgYWN0aXZhdGluZyB0aGUgZWxlbWVudHMgdGhhdCB3b3VsZCBiZSBhY3RpdmUsIGlmIHRoaXMgY2hlY2tcbiAgICAvLyB3YXMgZG9uZSBhZnRlciB0aGUgYW5pbWF0aW9ucyBoYXZlIGNvbXBsZXRlZC4gPT4gXCJmaW5hbCBwb3NpdGlvbnNcIi5cbiAgICAvLyBJZiB0aGVyZSBpcyBubyBhbmltYXRpb25zLCB0aGUgXCJmaW5hbFwiIGFuZCBcImN1cnJlbnRcIiBwb3NpdGlvbnMgYXJlIGVxdWFsLlxuICAgIC8vIFRoaXMgaXMgZG9uZSBzbyB3ZSBkbyBub3QgaGF2ZSB0byBldmFsdWF0ZSB0aGUgYWN0aXZlIGVsZW1lbnRzIGVhY2ggYW5pbWF0aW9uIGZyYW1lXG4gICAgLy8gLSBpdCB3b3VsZCBiZSBleHBlbnNpdmUuXG4gICAgY29uc3QgdXNlRmluYWxQb3NpdGlvbiA9IHJlcGxheTtcbiAgICBjb25zdCBhY3RpdmUgPSB0aGlzLl9nZXRBY3RpdmVFbGVtZW50cyhlLCBsYXN0QWN0aXZlLCBpbkNoYXJ0QXJlYSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgY29uc3QgaXNDbGljayA9IF9pc0NsaWNrRXZlbnQoZSk7XG4gICAgY29uc3QgbGFzdEV2ZW50ID0gZGV0ZXJtaW5lTGFzdEV2ZW50KGUsIHRoaXMuX2xhc3RFdmVudCwgaW5DaGFydEFyZWEsIGlzQ2xpY2spO1xuXG4gICAgaWYgKGluQ2hhcnRBcmVhKSB7XG4gICAgICAvLyBTZXQgX2xhc3RFdmVudCB0byBudWxsIHdoaWxlIHdlIGFyZSBwcm9jZXNzaW5nIHRoZSBldmVudCBoYW5kbGVycy5cbiAgICAgIC8vIFRoaXMgcHJldmVudHMgcmVjdXJzaW9uIGlmIHRoZSBoYW5kbGVyIGNhbGxzIGNoYXJ0LnVwZGF0ZSgpXG4gICAgICB0aGlzLl9sYXN0RXZlbnQgPSBudWxsO1xuXG4gICAgICAvLyBJbnZva2Ugb25Ib3ZlciBob29rXG4gICAgICBjYWxsQ2FsbGJhY2sob3B0aW9ucy5vbkhvdmVyLCBbZSwgYWN0aXZlLCB0aGlzXSwgdGhpcyk7XG5cbiAgICAgIGlmIChpc0NsaWNrKSB7XG4gICAgICAgIGNhbGxDYWxsYmFjayhvcHRpb25zLm9uQ2xpY2ssIFtlLCBhY3RpdmUsIHRoaXNdLCB0aGlzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjaGFuZ2VkID0gIV9lbGVtZW50c0VxdWFsKGFjdGl2ZSwgbGFzdEFjdGl2ZSk7XG4gICAgaWYgKGNoYW5nZWQgfHwgcmVwbGF5KSB7XG4gICAgICB0aGlzLl9hY3RpdmUgPSBhY3RpdmU7XG4gICAgICB0aGlzLl91cGRhdGVIb3ZlclN0eWxlcyhhY3RpdmUsIGxhc3RBY3RpdmUsIHJlcGxheSk7XG4gICAgfVxuXG4gICAgdGhpcy5fbGFzdEV2ZW50ID0gbGFzdEV2ZW50O1xuXG4gICAgcmV0dXJuIGNoYW5nZWQ7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtDaGFydEV2ZW50fSBlIC0gVGhlIGV2ZW50XG4gICAqIEBwYXJhbSB7aW1wb3J0KCcuLi90eXBlcy9pbmRleC5qcycpLkFjdGl2ZUVsZW1lbnRbXX0gbGFzdEFjdGl2ZSAtIFByZXZpb3VzbHkgYWN0aXZlIGVsZW1lbnRzXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaW5DaGFydEFyZWEgLSBJcyB0aGUgZW52ZW50IGluc2lkZSBjaGFydEFyZWFcbiAgICogQHBhcmFtIHtib29sZWFufSB1c2VGaW5hbFBvc2l0aW9uIC0gU2hvdWxkIHRoZSBldmFsdWF0aW9uIGJlIGRvbmUgd2l0aCBjdXJyZW50IG9yIGZpbmFsIChhZnRlciBhbmltYXRpb24pIGVsZW1lbnQgcG9zaXRpb25zXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoJy4uL3R5cGVzL2luZGV4LmpzJykuQWN0aXZlRWxlbWVudFtdfSAtIFRoZSBhY3RpdmUgZWxlbWVudHNcbiAgICogQHByYXZhdGVcbiAgICovXG4gIF9nZXRBY3RpdmVFbGVtZW50cyhlLCBsYXN0QWN0aXZlLCBpbkNoYXJ0QXJlYSwgdXNlRmluYWxQb3NpdGlvbikge1xuICAgIGlmIChlLnR5cGUgPT09ICdtb3VzZW91dCcpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBpZiAoIWluQ2hhcnRBcmVhKSB7XG4gICAgICAvLyBMZXQgdXNlciBjb250cm9sIHRoZSBhY3RpdmUgZWxlbWVudHMgb3V0c2lkZSBjaGFydEFyZWEuIEVnLiB1c2luZyBMZWdlbmQuXG4gICAgICByZXR1cm4gbGFzdEFjdGl2ZTtcbiAgICB9XG5cbiAgICBjb25zdCBob3Zlck9wdGlvbnMgPSB0aGlzLm9wdGlvbnMuaG92ZXI7XG4gICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudHNBdEV2ZW50Rm9yTW9kZShlLCBob3Zlck9wdGlvbnMubW9kZSwgaG92ZXJPcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgfVxufVxuXG4vLyBAdHMtaWdub3JlXG5mdW5jdGlvbiBpbnZhbGlkYXRlUGx1Z2lucygpIHtcbiAgcmV0dXJuIGVhY2goQ2hhcnQuaW5zdGFuY2VzLCAoY2hhcnQpID0+IGNoYXJ0Ll9wbHVnaW5zLmludmFsaWRhdGUoKSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoYXJ0O1xuIiwgImltcG9ydCBFbGVtZW50IGZyb20gJy4uL2NvcmUvY29yZS5lbGVtZW50LmpzJztcbmltcG9ydCB7X2FuZ2xlQmV0d2VlbiwgZ2V0QW5nbGVGcm9tUG9pbnQsIFRBVSwgSEFMRl9QSSwgdmFsdWVPckRlZmF1bHR9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuaW1wb3J0IHtQSSwgX2lzQmV0d2VlbiwgX2xpbWl0VmFsdWV9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCB7X3JlYWRWYWx1ZVRvUHJvcHN9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5vcHRpb25zLmpzJztcbmltcG9ydCB0eXBlIHtBcmNPcHRpb25zLCBQb2ludH0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuXG5cbmZ1bmN0aW9uIGNsaXBBcmMoY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsIGVsZW1lbnQ6IEFyY0VsZW1lbnQsIGVuZEFuZ2xlOiBudW1iZXIpIHtcbiAgY29uc3Qge3N0YXJ0QW5nbGUsIHBpeGVsTWFyZ2luLCB4LCB5LCBvdXRlclJhZGl1cywgaW5uZXJSYWRpdXN9ID0gZWxlbWVudDtcbiAgbGV0IGFuZ2xlTWFyZ2luID0gcGl4ZWxNYXJnaW4gLyBvdXRlclJhZGl1cztcblxuICAvLyBEcmF3IGFuIGlubmVyIGJvcmRlciBieSBjbGlwcGluZyB0aGUgYXJjIGFuZCBkcmF3aW5nIGEgZG91YmxlLXdpZHRoIGJvcmRlclxuICAvLyBFbmxhcmdlIHRoZSBjbGlwcGluZyBhcmMgYnkgMC4zMyBwaXhlbHMgdG8gZWxpbWluYXRlIGdsaXRjaGVzIGJldHdlZW4gYm9yZGVyc1xuICBjdHguYmVnaW5QYXRoKCk7XG4gIGN0eC5hcmMoeCwgeSwgb3V0ZXJSYWRpdXMsIHN0YXJ0QW5nbGUgLSBhbmdsZU1hcmdpbiwgZW5kQW5nbGUgKyBhbmdsZU1hcmdpbik7XG4gIGlmIChpbm5lclJhZGl1cyA+IHBpeGVsTWFyZ2luKSB7XG4gICAgYW5nbGVNYXJnaW4gPSBwaXhlbE1hcmdpbiAvIGlubmVyUmFkaXVzO1xuICAgIGN0eC5hcmMoeCwgeSwgaW5uZXJSYWRpdXMsIGVuZEFuZ2xlICsgYW5nbGVNYXJnaW4sIHN0YXJ0QW5nbGUgLSBhbmdsZU1hcmdpbiwgdHJ1ZSk7XG4gIH0gZWxzZSB7XG4gICAgY3R4LmFyYyh4LCB5LCBwaXhlbE1hcmdpbiwgZW5kQW5nbGUgKyBIQUxGX1BJLCBzdGFydEFuZ2xlIC0gSEFMRl9QSSk7XG4gIH1cbiAgY3R4LmNsb3NlUGF0aCgpO1xuICBjdHguY2xpcCgpO1xufVxuXG5mdW5jdGlvbiB0b1JhZGl1c0Nvcm5lcnModmFsdWUpIHtcbiAgcmV0dXJuIF9yZWFkVmFsdWVUb1Byb3BzKHZhbHVlLCBbJ291dGVyU3RhcnQnLCAnb3V0ZXJFbmQnLCAnaW5uZXJTdGFydCcsICdpbm5lckVuZCddKTtcbn1cblxuLyoqXG4gKiBQYXJzZSBib3JkZXIgcmFkaXVzIGZyb20gdGhlIHByb3ZpZGVkIG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gcGFyc2VCb3JkZXJSYWRpdXMoYXJjOiBBcmNFbGVtZW50LCBpbm5lclJhZGl1czogbnVtYmVyLCBvdXRlclJhZGl1czogbnVtYmVyLCBhbmdsZURlbHRhOiBudW1iZXIpIHtcbiAgY29uc3QgbyA9IHRvUmFkaXVzQ29ybmVycyhhcmMub3B0aW9ucy5ib3JkZXJSYWRpdXMpO1xuICBjb25zdCBoYWxmVGhpY2tuZXNzID0gKG91dGVyUmFkaXVzIC0gaW5uZXJSYWRpdXMpIC8gMjtcbiAgY29uc3QgaW5uZXJMaW1pdCA9IE1hdGgubWluKGhhbGZUaGlja25lc3MsIGFuZ2xlRGVsdGEgKiBpbm5lclJhZGl1cyAvIDIpO1xuXG4gIC8vIE91dGVyIGxpbWl0cyBhcmUgY29tcGxpY2F0ZWQuIFdlIHdhbnQgdG8gY29tcHV0ZSB0aGUgYXZhaWxhYmxlIGFuZ3VsYXIgZGlzdGFuY2UgYXRcbiAgLy8gYSByYWRpdXMgb2Ygb3V0ZXJSYWRpdXMgLSBib3JkZXJSYWRpdXMgYmVjYXVzZSBmb3Igc21hbGwgYW5ndWxhciBkaXN0YW5jZXMsIHRoaXMgdGVybSBsaW1pdHMuXG4gIC8vIFdlIGNvbXB1dGUgYXQgciA9IG91dGVyUmFkaXVzIC0gYm9yZGVyUmFkaXVzIGJlY2F1c2UgdGhpcyBjaXJjbGUgZGVmaW5lcyB0aGUgY2VudGVyIG9mIHRoZSBib3JkZXIgY29ybmVycy5cbiAgLy9cbiAgLy8gSWYgdGhlIGJvcmRlclJhZGl1cyBpcyBsYXJnZSwgdGhhdCB2YWx1ZSBjYW4gYmVjb21lIG5lZ2F0aXZlLlxuICAvLyBUaGlzIGNhdXNlcyB0aGUgb3V0ZXIgYm9yZGVycyB0byBsb3NlIHRoZWlyIHJhZGl1cyBlbnRpcmVseSwgd2hpY2ggaXMgcmF0aGVyIHVuZXhwZWN0ZWQuIFRvIHNvbHZlIHRoYXQsIGlmIGJvcmRlclJhZGl1cyA+IG91dGVyUmFkaXVzXG4gIC8vIHdlIGtub3cgdGhhdCB0aGUgdGhpY2tuZXNzIHRlcm0gd2lsbCBkb21pbmF0ZSBhbmQgY29tcHV0ZSB0aGUgbGltaXRzIGF0IHRoYXQgcG9pbnRcbiAgY29uc3QgY29tcHV0ZU91dGVyTGltaXQgPSAodmFsKSA9PiB7XG4gICAgY29uc3Qgb3V0ZXJBcmNMaW1pdCA9IChvdXRlclJhZGl1cyAtIE1hdGgubWluKGhhbGZUaGlja25lc3MsIHZhbCkpICogYW5nbGVEZWx0YSAvIDI7XG4gICAgcmV0dXJuIF9saW1pdFZhbHVlKHZhbCwgMCwgTWF0aC5taW4oaGFsZlRoaWNrbmVzcywgb3V0ZXJBcmNMaW1pdCkpO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgb3V0ZXJTdGFydDogY29tcHV0ZU91dGVyTGltaXQoby5vdXRlclN0YXJ0KSxcbiAgICBvdXRlckVuZDogY29tcHV0ZU91dGVyTGltaXQoby5vdXRlckVuZCksXG4gICAgaW5uZXJTdGFydDogX2xpbWl0VmFsdWUoby5pbm5lclN0YXJ0LCAwLCBpbm5lckxpbWl0KSxcbiAgICBpbm5lckVuZDogX2xpbWl0VmFsdWUoby5pbm5lckVuZCwgMCwgaW5uZXJMaW1pdCksXG4gIH07XG59XG5cbi8qKlxuICogQ29udmVydCAociwg8J2cgykgdG8gKHgsIHkpXG4gKi9cbmZ1bmN0aW9uIHJUaGV0YVRvWFkocjogbnVtYmVyLCB0aGV0YTogbnVtYmVyLCB4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICByZXR1cm4ge1xuICAgIHg6IHggKyByICogTWF0aC5jb3ModGhldGEpLFxuICAgIHk6IHkgKyByICogTWF0aC5zaW4odGhldGEpLFxuICB9O1xufVxuXG5cbi8qKlxuICogUGF0aCB0aGUgYXJjLCByZXNwZWN0aW5nIGJvcmRlciByYWRpdXMgYnkgc2VwYXJhdGluZyBpbnRvIGxlZnQgYW5kIHJpZ2h0IGhhbHZlcy5cbiAqXG4gKiAgIFN0YXJ0ICAgICAgRW5kXG4gKlxuICogICAgMS0tLT5hLS0tPjIgICAgT3V0ZXJcbiAqICAgLyAgICAgICAgICAgXFxcbiAqICAgOCAgICAgICAgICAgM1xuICogICB8ICAgICAgICAgICB8XG4gKiAgIHwgICAgICAgICAgIHxcbiAqICAgNyAgICAgICAgICAgNFxuICogICBcXCAgICAgICAgICAgL1xuICogICAgNjwtLS1iPC0tLTUgICAgSW5uZXJcbiAqL1xuZnVuY3Rpb24gcGF0aEFyYyhcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIGVsZW1lbnQ6IEFyY0VsZW1lbnQsXG4gIG9mZnNldDogbnVtYmVyLFxuICBzcGFjaW5nOiBudW1iZXIsXG4gIGVuZDogbnVtYmVyLFxuICBjaXJjdWxhcjogYm9vbGVhbixcbikge1xuICBjb25zdCB7eCwgeSwgc3RhcnRBbmdsZTogc3RhcnQsIHBpeGVsTWFyZ2luLCBpbm5lclJhZGl1czogaW5uZXJSfSA9IGVsZW1lbnQ7XG5cbiAgY29uc3Qgb3V0ZXJSYWRpdXMgPSBNYXRoLm1heChlbGVtZW50Lm91dGVyUmFkaXVzICsgc3BhY2luZyArIG9mZnNldCAtIHBpeGVsTWFyZ2luLCAwKTtcbiAgY29uc3QgaW5uZXJSYWRpdXMgPSBpbm5lclIgPiAwID8gaW5uZXJSICsgc3BhY2luZyArIG9mZnNldCArIHBpeGVsTWFyZ2luIDogMDtcblxuICBsZXQgc3BhY2luZ09mZnNldCA9IDA7XG4gIGNvbnN0IGFscGhhID0gZW5kIC0gc3RhcnQ7XG5cbiAgaWYgKHNwYWNpbmcpIHtcbiAgICAvLyBXaGVuIHNwYWNpbmcgaXMgcHJlc2VudCwgaXQgaXMgdGhlIHNhbWUgZm9yIGFsbCBpdGVtc1xuICAgIC8vIFNvIHdlIGFkanVzdCB0aGUgc3RhcnQgYW5kIGVuZCBhbmdsZSBvZiB0aGUgYXJjIHN1Y2ggdGhhdFxuICAgIC8vIHRoZSBkaXN0YW5jZSBpcyB0aGUgc2FtZSBhcyBpdCB3b3VsZCBiZSB3aXRob3V0IHRoZSBzcGFjaW5nXG4gICAgY29uc3Qgbm9TcGFjaW5nSW5uZXJSYWRpdXMgPSBpbm5lclIgPiAwID8gaW5uZXJSIC0gc3BhY2luZyA6IDA7XG4gICAgY29uc3Qgbm9TcGFjaW5nT3V0ZXJSYWRpdXMgPSBvdXRlclJhZGl1cyA+IDAgPyBvdXRlclJhZGl1cyAtIHNwYWNpbmcgOiAwO1xuICAgIGNvbnN0IGF2Tm9nU3BhY2luZ1JhZGl1cyA9IChub1NwYWNpbmdJbm5lclJhZGl1cyArIG5vU3BhY2luZ091dGVyUmFkaXVzKSAvIDI7XG4gICAgY29uc3QgYWRqdXN0ZWRBbmdsZSA9IGF2Tm9nU3BhY2luZ1JhZGl1cyAhPT0gMCA/IChhbHBoYSAqIGF2Tm9nU3BhY2luZ1JhZGl1cykgLyAoYXZOb2dTcGFjaW5nUmFkaXVzICsgc3BhY2luZykgOiBhbHBoYTtcbiAgICBzcGFjaW5nT2Zmc2V0ID0gKGFscGhhIC0gYWRqdXN0ZWRBbmdsZSkgLyAyO1xuICB9XG5cbiAgY29uc3QgYmV0YSA9IE1hdGgubWF4KDAuMDAxLCBhbHBoYSAqIG91dGVyUmFkaXVzIC0gb2Zmc2V0IC8gUEkpIC8gb3V0ZXJSYWRpdXM7XG4gIGNvbnN0IGFuZ2xlT2Zmc2V0ID0gKGFscGhhIC0gYmV0YSkgLyAyO1xuICBjb25zdCBzdGFydEFuZ2xlID0gc3RhcnQgKyBhbmdsZU9mZnNldCArIHNwYWNpbmdPZmZzZXQ7XG4gIGNvbnN0IGVuZEFuZ2xlID0gZW5kIC0gYW5nbGVPZmZzZXQgLSBzcGFjaW5nT2Zmc2V0O1xuICBjb25zdCB7b3V0ZXJTdGFydCwgb3V0ZXJFbmQsIGlubmVyU3RhcnQsIGlubmVyRW5kfSA9IHBhcnNlQm9yZGVyUmFkaXVzKGVsZW1lbnQsIGlubmVyUmFkaXVzLCBvdXRlclJhZGl1cywgZW5kQW5nbGUgLSBzdGFydEFuZ2xlKTtcblxuICBjb25zdCBvdXRlclN0YXJ0QWRqdXN0ZWRSYWRpdXMgPSBvdXRlclJhZGl1cyAtIG91dGVyU3RhcnQ7XG4gIGNvbnN0IG91dGVyRW5kQWRqdXN0ZWRSYWRpdXMgPSBvdXRlclJhZGl1cyAtIG91dGVyRW5kO1xuICBjb25zdCBvdXRlclN0YXJ0QWRqdXN0ZWRBbmdsZSA9IHN0YXJ0QW5nbGUgKyBvdXRlclN0YXJ0IC8gb3V0ZXJTdGFydEFkanVzdGVkUmFkaXVzO1xuICBjb25zdCBvdXRlckVuZEFkanVzdGVkQW5nbGUgPSBlbmRBbmdsZSAtIG91dGVyRW5kIC8gb3V0ZXJFbmRBZGp1c3RlZFJhZGl1cztcblxuICBjb25zdCBpbm5lclN0YXJ0QWRqdXN0ZWRSYWRpdXMgPSBpbm5lclJhZGl1cyArIGlubmVyU3RhcnQ7XG4gIGNvbnN0IGlubmVyRW5kQWRqdXN0ZWRSYWRpdXMgPSBpbm5lclJhZGl1cyArIGlubmVyRW5kO1xuICBjb25zdCBpbm5lclN0YXJ0QWRqdXN0ZWRBbmdsZSA9IHN0YXJ0QW5nbGUgKyBpbm5lclN0YXJ0IC8gaW5uZXJTdGFydEFkanVzdGVkUmFkaXVzO1xuICBjb25zdCBpbm5lckVuZEFkanVzdGVkQW5nbGUgPSBlbmRBbmdsZSAtIGlubmVyRW5kIC8gaW5uZXJFbmRBZGp1c3RlZFJhZGl1cztcblxuICBjdHguYmVnaW5QYXRoKCk7XG5cbiAgaWYgKGNpcmN1bGFyKSB7XG4gICAgLy8gVGhlIGZpcnN0IGFyYyBzZWdtZW50cyBmcm9tIHBvaW50IDEgdG8gcG9pbnQgYSB0byBwb2ludCAyXG4gICAgY29uc3Qgb3V0ZXJNaWRBZGp1c3RlZEFuZ2xlID0gKG91dGVyU3RhcnRBZGp1c3RlZEFuZ2xlICsgb3V0ZXJFbmRBZGp1c3RlZEFuZ2xlKSAvIDI7XG4gICAgY3R4LmFyYyh4LCB5LCBvdXRlclJhZGl1cywgb3V0ZXJTdGFydEFkanVzdGVkQW5nbGUsIG91dGVyTWlkQWRqdXN0ZWRBbmdsZSk7XG4gICAgY3R4LmFyYyh4LCB5LCBvdXRlclJhZGl1cywgb3V0ZXJNaWRBZGp1c3RlZEFuZ2xlLCBvdXRlckVuZEFkanVzdGVkQW5nbGUpO1xuXG4gICAgLy8gVGhlIGNvcm5lciBzZWdtZW50IGZyb20gcG9pbnQgMiB0byBwb2ludCAzXG4gICAgaWYgKG91dGVyRW5kID4gMCkge1xuICAgICAgY29uc3QgcENlbnRlciA9IHJUaGV0YVRvWFkob3V0ZXJFbmRBZGp1c3RlZFJhZGl1cywgb3V0ZXJFbmRBZGp1c3RlZEFuZ2xlLCB4LCB5KTtcbiAgICAgIGN0eC5hcmMocENlbnRlci54LCBwQ2VudGVyLnksIG91dGVyRW5kLCBvdXRlckVuZEFkanVzdGVkQW5nbGUsIGVuZEFuZ2xlICsgSEFMRl9QSSk7XG4gICAgfVxuXG4gICAgLy8gVGhlIGxpbmUgZnJvbSBwb2ludCAzIHRvIHBvaW50IDRcbiAgICBjb25zdCBwNCA9IHJUaGV0YVRvWFkoaW5uZXJFbmRBZGp1c3RlZFJhZGl1cywgZW5kQW5nbGUsIHgsIHkpO1xuICAgIGN0eC5saW5lVG8ocDQueCwgcDQueSk7XG5cbiAgICAvLyBUaGUgY29ybmVyIHNlZ21lbnQgZnJvbSBwb2ludCA0IHRvIHBvaW50IDVcbiAgICBpZiAoaW5uZXJFbmQgPiAwKSB7XG4gICAgICBjb25zdCBwQ2VudGVyID0gclRoZXRhVG9YWShpbm5lckVuZEFkanVzdGVkUmFkaXVzLCBpbm5lckVuZEFkanVzdGVkQW5nbGUsIHgsIHkpO1xuICAgICAgY3R4LmFyYyhwQ2VudGVyLngsIHBDZW50ZXIueSwgaW5uZXJFbmQsIGVuZEFuZ2xlICsgSEFMRl9QSSwgaW5uZXJFbmRBZGp1c3RlZEFuZ2xlICsgTWF0aC5QSSk7XG4gICAgfVxuXG4gICAgLy8gVGhlIGlubmVyIGFyYyBmcm9tIHBvaW50IDUgdG8gcG9pbnQgYiB0byBwb2ludCA2XG4gICAgY29uc3QgaW5uZXJNaWRBZGp1c3RlZEFuZ2xlID0gKChlbmRBbmdsZSAtIChpbm5lckVuZCAvIGlubmVyUmFkaXVzKSkgKyAoc3RhcnRBbmdsZSArIChpbm5lclN0YXJ0IC8gaW5uZXJSYWRpdXMpKSkgLyAyO1xuICAgIGN0eC5hcmMoeCwgeSwgaW5uZXJSYWRpdXMsIGVuZEFuZ2xlIC0gKGlubmVyRW5kIC8gaW5uZXJSYWRpdXMpLCBpbm5lck1pZEFkanVzdGVkQW5nbGUsIHRydWUpO1xuICAgIGN0eC5hcmMoeCwgeSwgaW5uZXJSYWRpdXMsIGlubmVyTWlkQWRqdXN0ZWRBbmdsZSwgc3RhcnRBbmdsZSArIChpbm5lclN0YXJ0IC8gaW5uZXJSYWRpdXMpLCB0cnVlKTtcblxuICAgIC8vIFRoZSBjb3JuZXIgc2VnbWVudCBmcm9tIHBvaW50IDYgdG8gcG9pbnQgN1xuICAgIGlmIChpbm5lclN0YXJ0ID4gMCkge1xuICAgICAgY29uc3QgcENlbnRlciA9IHJUaGV0YVRvWFkoaW5uZXJTdGFydEFkanVzdGVkUmFkaXVzLCBpbm5lclN0YXJ0QWRqdXN0ZWRBbmdsZSwgeCwgeSk7XG4gICAgICBjdHguYXJjKHBDZW50ZXIueCwgcENlbnRlci55LCBpbm5lclN0YXJ0LCBpbm5lclN0YXJ0QWRqdXN0ZWRBbmdsZSArIE1hdGguUEksIHN0YXJ0QW5nbGUgLSBIQUxGX1BJKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgbGluZSBmcm9tIHBvaW50IDcgdG8gcG9pbnQgOFxuICAgIGNvbnN0IHA4ID0gclRoZXRhVG9YWShvdXRlclN0YXJ0QWRqdXN0ZWRSYWRpdXMsIHN0YXJ0QW5nbGUsIHgsIHkpO1xuICAgIGN0eC5saW5lVG8ocDgueCwgcDgueSk7XG5cbiAgICAvLyBUaGUgY29ybmVyIHNlZ21lbnQgZnJvbSBwb2ludCA4IHRvIHBvaW50IDFcbiAgICBpZiAob3V0ZXJTdGFydCA+IDApIHtcbiAgICAgIGNvbnN0IHBDZW50ZXIgPSByVGhldGFUb1hZKG91dGVyU3RhcnRBZGp1c3RlZFJhZGl1cywgb3V0ZXJTdGFydEFkanVzdGVkQW5nbGUsIHgsIHkpO1xuICAgICAgY3R4LmFyYyhwQ2VudGVyLngsIHBDZW50ZXIueSwgb3V0ZXJTdGFydCwgc3RhcnRBbmdsZSAtIEhBTEZfUEksIG91dGVyU3RhcnRBZGp1c3RlZEFuZ2xlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY3R4Lm1vdmVUbyh4LCB5KTtcblxuICAgIGNvbnN0IG91dGVyU3RhcnRYID0gTWF0aC5jb3Mob3V0ZXJTdGFydEFkanVzdGVkQW5nbGUpICogb3V0ZXJSYWRpdXMgKyB4O1xuICAgIGNvbnN0IG91dGVyU3RhcnRZID0gTWF0aC5zaW4ob3V0ZXJTdGFydEFkanVzdGVkQW5nbGUpICogb3V0ZXJSYWRpdXMgKyB5O1xuICAgIGN0eC5saW5lVG8ob3V0ZXJTdGFydFgsIG91dGVyU3RhcnRZKTtcblxuICAgIGNvbnN0IG91dGVyRW5kWCA9IE1hdGguY29zKG91dGVyRW5kQWRqdXN0ZWRBbmdsZSkgKiBvdXRlclJhZGl1cyArIHg7XG4gICAgY29uc3Qgb3V0ZXJFbmRZID0gTWF0aC5zaW4ob3V0ZXJFbmRBZGp1c3RlZEFuZ2xlKSAqIG91dGVyUmFkaXVzICsgeTtcbiAgICBjdHgubGluZVRvKG91dGVyRW5kWCwgb3V0ZXJFbmRZKTtcbiAgfVxuXG4gIGN0eC5jbG9zZVBhdGgoKTtcbn1cblxuZnVuY3Rpb24gZHJhd0FyYyhcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIGVsZW1lbnQ6IEFyY0VsZW1lbnQsXG4gIG9mZnNldDogbnVtYmVyLFxuICBzcGFjaW5nOiBudW1iZXIsXG4gIGNpcmN1bGFyOiBib29sZWFuLFxuKSB7XG4gIGNvbnN0IHtmdWxsQ2lyY2xlcywgc3RhcnRBbmdsZSwgY2lyY3VtZmVyZW5jZX0gPSBlbGVtZW50O1xuICBsZXQgZW5kQW5nbGUgPSBlbGVtZW50LmVuZEFuZ2xlO1xuICBpZiAoZnVsbENpcmNsZXMpIHtcbiAgICBwYXRoQXJjKGN0eCwgZWxlbWVudCwgb2Zmc2V0LCBzcGFjaW5nLCBlbmRBbmdsZSwgY2lyY3VsYXIpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZnVsbENpcmNsZXM7ICsraSkge1xuICAgICAgY3R4LmZpbGwoKTtcbiAgICB9XG4gICAgaWYgKCFpc05hTihjaXJjdW1mZXJlbmNlKSkge1xuICAgICAgZW5kQW5nbGUgPSBzdGFydEFuZ2xlICsgKGNpcmN1bWZlcmVuY2UgJSBUQVUgfHwgVEFVKTtcbiAgICB9XG4gIH1cbiAgcGF0aEFyYyhjdHgsIGVsZW1lbnQsIG9mZnNldCwgc3BhY2luZywgZW5kQW5nbGUsIGNpcmN1bGFyKTtcbiAgY3R4LmZpbGwoKTtcbiAgcmV0dXJuIGVuZEFuZ2xlO1xufVxuXG5mdW5jdGlvbiBkcmF3Qm9yZGVyKFxuICBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCxcbiAgZWxlbWVudDogQXJjRWxlbWVudCxcbiAgb2Zmc2V0OiBudW1iZXIsXG4gIHNwYWNpbmc6IG51bWJlcixcbiAgY2lyY3VsYXI6IGJvb2xlYW4sXG4pIHtcbiAgY29uc3Qge2Z1bGxDaXJjbGVzLCBzdGFydEFuZ2xlLCBjaXJjdW1mZXJlbmNlLCBvcHRpb25zfSA9IGVsZW1lbnQ7XG4gIGNvbnN0IHtib3JkZXJXaWR0aCwgYm9yZGVySm9pblN0eWxlLCBib3JkZXJEYXNoLCBib3JkZXJEYXNoT2Zmc2V0fSA9IG9wdGlvbnM7XG4gIGNvbnN0IGlubmVyID0gb3B0aW9ucy5ib3JkZXJBbGlnbiA9PT0gJ2lubmVyJztcblxuICBpZiAoIWJvcmRlcldpZHRoKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY3R4LnNldExpbmVEYXNoKGJvcmRlckRhc2ggfHwgW10pO1xuICBjdHgubGluZURhc2hPZmZzZXQgPSBib3JkZXJEYXNoT2Zmc2V0O1xuXG4gIGlmIChpbm5lcikge1xuICAgIGN0eC5saW5lV2lkdGggPSBib3JkZXJXaWR0aCAqIDI7XG4gICAgY3R4LmxpbmVKb2luID0gYm9yZGVySm9pblN0eWxlIHx8ICdyb3VuZCc7XG4gIH0gZWxzZSB7XG4gICAgY3R4LmxpbmVXaWR0aCA9IGJvcmRlcldpZHRoO1xuICAgIGN0eC5saW5lSm9pbiA9IGJvcmRlckpvaW5TdHlsZSB8fCAnYmV2ZWwnO1xuICB9XG5cbiAgbGV0IGVuZEFuZ2xlID0gZWxlbWVudC5lbmRBbmdsZTtcbiAgaWYgKGZ1bGxDaXJjbGVzKSB7XG4gICAgcGF0aEFyYyhjdHgsIGVsZW1lbnQsIG9mZnNldCwgc3BhY2luZywgZW5kQW5nbGUsIGNpcmN1bGFyKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZ1bGxDaXJjbGVzOyArK2kpIHtcbiAgICAgIGN0eC5zdHJva2UoKTtcbiAgICB9XG4gICAgaWYgKCFpc05hTihjaXJjdW1mZXJlbmNlKSkge1xuICAgICAgZW5kQW5nbGUgPSBzdGFydEFuZ2xlICsgKGNpcmN1bWZlcmVuY2UgJSBUQVUgfHwgVEFVKTtcbiAgICB9XG4gIH1cblxuICBpZiAoaW5uZXIpIHtcbiAgICBjbGlwQXJjKGN0eCwgZWxlbWVudCwgZW5kQW5nbGUpO1xuICB9XG5cbiAgaWYgKCFmdWxsQ2lyY2xlcykge1xuICAgIHBhdGhBcmMoY3R4LCBlbGVtZW50LCBvZmZzZXQsIHNwYWNpbmcsIGVuZEFuZ2xlLCBjaXJjdWxhcik7XG4gICAgY3R4LnN0cm9rZSgpO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXJjUHJvcHMgZXh0ZW5kcyBQb2ludCB7XG4gIHN0YXJ0QW5nbGU6IG51bWJlcjtcbiAgZW5kQW5nbGU6IG51bWJlcjtcbiAgaW5uZXJSYWRpdXM6IG51bWJlcjtcbiAgb3V0ZXJSYWRpdXM6IG51bWJlcjtcbiAgY2lyY3VtZmVyZW5jZTogbnVtYmVyO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBcmNFbGVtZW50IGV4dGVuZHMgRWxlbWVudDxBcmNQcm9wcywgQXJjT3B0aW9ucz4ge1xuXG4gIHN0YXRpYyBpZCA9ICdhcmMnO1xuXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICBib3JkZXJBbGlnbjogJ2NlbnRlcicsXG4gICAgYm9yZGVyQ29sb3I6ICcjZmZmJyxcbiAgICBib3JkZXJEYXNoOiBbXSxcbiAgICBib3JkZXJEYXNoT2Zmc2V0OiAwLFxuICAgIGJvcmRlckpvaW5TdHlsZTogdW5kZWZpbmVkLFxuICAgIGJvcmRlclJhZGl1czogMCxcbiAgICBib3JkZXJXaWR0aDogMixcbiAgICBvZmZzZXQ6IDAsXG4gICAgc3BhY2luZzogMCxcbiAgICBhbmdsZTogdW5kZWZpbmVkLFxuICAgIGNpcmN1bGFyOiB0cnVlLFxuICB9O1xuXG4gIHN0YXRpYyBkZWZhdWx0Um91dGVzID0ge1xuICAgIGJhY2tncm91bmRDb2xvcjogJ2JhY2tncm91bmRDb2xvcidcbiAgfTtcblxuICBzdGF0aWMgZGVzY3JpcHRvcnMgPSB7XG4gICAgX3NjcmlwdGFibGU6IHRydWUsXG4gICAgX2luZGV4YWJsZTogKG5hbWUpID0+IG5hbWUgIT09ICdib3JkZXJEYXNoJ1xuICB9O1xuXG4gIGNpcmN1bWZlcmVuY2U6IG51bWJlcjtcbiAgZW5kQW5nbGU6IG51bWJlcjtcbiAgZnVsbENpcmNsZXM6IG51bWJlcjtcbiAgaW5uZXJSYWRpdXM6IG51bWJlcjtcbiAgb3V0ZXJSYWRpdXM6IG51bWJlcjtcbiAgcGl4ZWxNYXJnaW46IG51bWJlcjtcbiAgc3RhcnRBbmdsZTogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKGNmZykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLm9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jaXJjdW1mZXJlbmNlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc3RhcnRBbmdsZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmVuZEFuZ2xlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaW5uZXJSYWRpdXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5vdXRlclJhZGl1cyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnBpeGVsTWFyZ2luID0gMDtcbiAgICB0aGlzLmZ1bGxDaXJjbGVzID0gMDtcblxuICAgIGlmIChjZmcpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24odGhpcywgY2ZnKTtcbiAgICB9XG4gIH1cblxuICBpblJhbmdlKGNoYXJ0WDogbnVtYmVyLCBjaGFydFk6IG51bWJlciwgdXNlRmluYWxQb3NpdGlvbjogYm9vbGVhbikge1xuICAgIGNvbnN0IHBvaW50ID0gdGhpcy5nZXRQcm9wcyhbJ3gnLCAneSddLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICBjb25zdCB7YW5nbGUsIGRpc3RhbmNlfSA9IGdldEFuZ2xlRnJvbVBvaW50KHBvaW50LCB7eDogY2hhcnRYLCB5OiBjaGFydFl9KTtcbiAgICBjb25zdCB7c3RhcnRBbmdsZSwgZW5kQW5nbGUsIGlubmVyUmFkaXVzLCBvdXRlclJhZGl1cywgY2lyY3VtZmVyZW5jZX0gPSB0aGlzLmdldFByb3BzKFtcbiAgICAgICdzdGFydEFuZ2xlJyxcbiAgICAgICdlbmRBbmdsZScsXG4gICAgICAnaW5uZXJSYWRpdXMnLFxuICAgICAgJ291dGVyUmFkaXVzJyxcbiAgICAgICdjaXJjdW1mZXJlbmNlJ1xuICAgIF0sIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIGNvbnN0IHJBZGp1c3QgPSAodGhpcy5vcHRpb25zLnNwYWNpbmcgKyB0aGlzLm9wdGlvbnMuYm9yZGVyV2lkdGgpIC8gMjtcbiAgICBjb25zdCBfY2lyY3VtZmVyZW5jZSA9IHZhbHVlT3JEZWZhdWx0KGNpcmN1bWZlcmVuY2UsIGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSk7XG4gICAgY29uc3QgYmV0d2VlbkFuZ2xlcyA9IF9jaXJjdW1mZXJlbmNlID49IFRBVSB8fCBfYW5nbGVCZXR3ZWVuKGFuZ2xlLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSk7XG4gICAgY29uc3Qgd2l0aGluUmFkaXVzID0gX2lzQmV0d2VlbihkaXN0YW5jZSwgaW5uZXJSYWRpdXMgKyByQWRqdXN0LCBvdXRlclJhZGl1cyArIHJBZGp1c3QpO1xuXG4gICAgcmV0dXJuIChiZXR3ZWVuQW5nbGVzICYmIHdpdGhpblJhZGl1cyk7XG4gIH1cblxuICBnZXRDZW50ZXJQb2ludCh1c2VGaW5hbFBvc2l0aW9uOiBib29sZWFuKSB7XG4gICAgY29uc3Qge3gsIHksIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBpbm5lclJhZGl1cywgb3V0ZXJSYWRpdXN9ID0gdGhpcy5nZXRQcm9wcyhbXG4gICAgICAneCcsXG4gICAgICAneScsXG4gICAgICAnc3RhcnRBbmdsZScsXG4gICAgICAnZW5kQW5nbGUnLFxuICAgICAgJ2lubmVyUmFkaXVzJyxcbiAgICAgICdvdXRlclJhZGl1cydcbiAgICBdLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICBjb25zdCB7b2Zmc2V0LCBzcGFjaW5nfSA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBoYWxmQW5nbGUgPSAoc3RhcnRBbmdsZSArIGVuZEFuZ2xlKSAvIDI7XG4gICAgY29uc3QgaGFsZlJhZGl1cyA9IChpbm5lclJhZGl1cyArIG91dGVyUmFkaXVzICsgc3BhY2luZyArIG9mZnNldCkgLyAyO1xuICAgIHJldHVybiB7XG4gICAgICB4OiB4ICsgTWF0aC5jb3MoaGFsZkFuZ2xlKSAqIGhhbGZSYWRpdXMsXG4gICAgICB5OiB5ICsgTWF0aC5zaW4oaGFsZkFuZ2xlKSAqIGhhbGZSYWRpdXNcbiAgICB9O1xuICB9XG5cbiAgdG9vbHRpcFBvc2l0aW9uKHVzZUZpbmFsUG9zaXRpb246IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDZW50ZXJQb2ludCh1c2VGaW5hbFBvc2l0aW9uKTtcbiAgfVxuXG4gIGRyYXcoY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQpIHtcbiAgICBjb25zdCB7b3B0aW9ucywgY2lyY3VtZmVyZW5jZX0gPSB0aGlzO1xuICAgIGNvbnN0IG9mZnNldCA9IChvcHRpb25zLm9mZnNldCB8fCAwKSAvIDQ7XG4gICAgY29uc3Qgc3BhY2luZyA9IChvcHRpb25zLnNwYWNpbmcgfHwgMCkgLyAyO1xuICAgIGNvbnN0IGNpcmN1bGFyID0gb3B0aW9ucy5jaXJjdWxhcjtcbiAgICB0aGlzLnBpeGVsTWFyZ2luID0gKG9wdGlvbnMuYm9yZGVyQWxpZ24gPT09ICdpbm5lcicpID8gMC4zMyA6IDA7XG4gICAgdGhpcy5mdWxsQ2lyY2xlcyA9IGNpcmN1bWZlcmVuY2UgPiBUQVUgPyBNYXRoLmZsb29yKGNpcmN1bWZlcmVuY2UgLyBUQVUpIDogMDtcblxuICAgIGlmIChjaXJjdW1mZXJlbmNlID09PSAwIHx8IHRoaXMuaW5uZXJSYWRpdXMgPCAwIHx8IHRoaXMub3V0ZXJSYWRpdXMgPCAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY3R4LnNhdmUoKTtcblxuICAgIGNvbnN0IGhhbGZBbmdsZSA9ICh0aGlzLnN0YXJ0QW5nbGUgKyB0aGlzLmVuZEFuZ2xlKSAvIDI7XG4gICAgY3R4LnRyYW5zbGF0ZShNYXRoLmNvcyhoYWxmQW5nbGUpICogb2Zmc2V0LCBNYXRoLnNpbihoYWxmQW5nbGUpICogb2Zmc2V0KTtcbiAgICBjb25zdCBmaXggPSAxIC0gTWF0aC5zaW4oTWF0aC5taW4oUEksIGNpcmN1bWZlcmVuY2UgfHwgMCkpO1xuICAgIGNvbnN0IHJhZGl1c09mZnNldCA9IG9mZnNldCAqIGZpeDtcblxuICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLmJhY2tncm91bmRDb2xvcjtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBvcHRpb25zLmJvcmRlckNvbG9yO1xuXG4gICAgZHJhd0FyYyhjdHgsIHRoaXMsIHJhZGl1c09mZnNldCwgc3BhY2luZywgY2lyY3VsYXIpO1xuICAgIGRyYXdCb3JkZXIoY3R4LCB0aGlzLCByYWRpdXNPZmZzZXQsIHNwYWNpbmcsIGNpcmN1bGFyKTtcblxuICAgIGN0eC5yZXN0b3JlKCk7XG4gIH1cbn1cbiIsICJpbXBvcnQgRWxlbWVudCBmcm9tICcuLi9jb3JlL2NvcmUuZWxlbWVudC5qcyc7XG5pbXBvcnQge19iZXppZXJJbnRlcnBvbGF0aW9uLCBfcG9pbnRJbkxpbmUsIF9zdGVwcGVkSW50ZXJwb2xhdGlvbn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmludGVycG9sYXRpb24uanMnO1xuaW1wb3J0IHtfY29tcHV0ZVNlZ21lbnRzLCBfYm91bmRTZWdtZW50c30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLnNlZ21lbnQuanMnO1xuaW1wb3J0IHtfc3RlcHBlZExpbmVUbywgX2JlemllckN1cnZlVG99IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jYW52YXMuanMnO1xuaW1wb3J0IHtfdXBkYXRlQmV6aWVyQ29udHJvbFBvaW50c30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmN1cnZlLmpzJztcbmltcG9ydCB7dmFsdWVPckRlZmF1bHR9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuL2VsZW1lbnQucG9pbnQuanMnKS5kZWZhdWx0IH0gUG9pbnRFbGVtZW50XG4gKi9cblxuZnVuY3Rpb24gc2V0U3R5bGUoY3R4LCBvcHRpb25zLCBzdHlsZSA9IG9wdGlvbnMpIHtcbiAgY3R4LmxpbmVDYXAgPSB2YWx1ZU9yRGVmYXVsdChzdHlsZS5ib3JkZXJDYXBTdHlsZSwgb3B0aW9ucy5ib3JkZXJDYXBTdHlsZSk7XG4gIGN0eC5zZXRMaW5lRGFzaCh2YWx1ZU9yRGVmYXVsdChzdHlsZS5ib3JkZXJEYXNoLCBvcHRpb25zLmJvcmRlckRhc2gpKTtcbiAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gdmFsdWVPckRlZmF1bHQoc3R5bGUuYm9yZGVyRGFzaE9mZnNldCwgb3B0aW9ucy5ib3JkZXJEYXNoT2Zmc2V0KTtcbiAgY3R4LmxpbmVKb2luID0gdmFsdWVPckRlZmF1bHQoc3R5bGUuYm9yZGVySm9pblN0eWxlLCBvcHRpb25zLmJvcmRlckpvaW5TdHlsZSk7XG4gIGN0eC5saW5lV2lkdGggPSB2YWx1ZU9yRGVmYXVsdChzdHlsZS5ib3JkZXJXaWR0aCwgb3B0aW9ucy5ib3JkZXJXaWR0aCk7XG4gIGN0eC5zdHJva2VTdHlsZSA9IHZhbHVlT3JEZWZhdWx0KHN0eWxlLmJvcmRlckNvbG9yLCBvcHRpb25zLmJvcmRlckNvbG9yKTtcbn1cblxuZnVuY3Rpb24gbGluZVRvKGN0eCwgcHJldmlvdXMsIHRhcmdldCkge1xuICBjdHgubGluZVRvKHRhcmdldC54LCB0YXJnZXQueSk7XG59XG5cbi8qKlxuICogQHJldHVybnMge2FueX1cbiAqL1xuZnVuY3Rpb24gZ2V0TGluZU1ldGhvZChvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zLnN0ZXBwZWQpIHtcbiAgICByZXR1cm4gX3N0ZXBwZWRMaW5lVG87XG4gIH1cblxuICBpZiAob3B0aW9ucy50ZW5zaW9uIHx8IG9wdGlvbnMuY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSA9PT0gJ21vbm90b25lJykge1xuICAgIHJldHVybiBfYmV6aWVyQ3VydmVUbztcbiAgfVxuXG4gIHJldHVybiBsaW5lVG87XG59XG5cbmZ1bmN0aW9uIHBhdGhWYXJzKHBvaW50cywgc2VnbWVudCwgcGFyYW1zID0ge30pIHtcbiAgY29uc3QgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuICBjb25zdCB7c3RhcnQ6IHBhcmFtc1N0YXJ0ID0gMCwgZW5kOiBwYXJhbXNFbmQgPSBjb3VudCAtIDF9ID0gcGFyYW1zO1xuICBjb25zdCB7c3RhcnQ6IHNlZ21lbnRTdGFydCwgZW5kOiBzZWdtZW50RW5kfSA9IHNlZ21lbnQ7XG4gIGNvbnN0IHN0YXJ0ID0gTWF0aC5tYXgocGFyYW1zU3RhcnQsIHNlZ21lbnRTdGFydCk7XG4gIGNvbnN0IGVuZCA9IE1hdGgubWluKHBhcmFtc0VuZCwgc2VnbWVudEVuZCk7XG4gIGNvbnN0IG91dHNpZGUgPSBwYXJhbXNTdGFydCA8IHNlZ21lbnRTdGFydCAmJiBwYXJhbXNFbmQgPCBzZWdtZW50U3RhcnQgfHwgcGFyYW1zU3RhcnQgPiBzZWdtZW50RW5kICYmIHBhcmFtc0VuZCA+IHNlZ21lbnRFbmQ7XG5cbiAgcmV0dXJuIHtcbiAgICBjb3VudCxcbiAgICBzdGFydCxcbiAgICBsb29wOiBzZWdtZW50Lmxvb3AsXG4gICAgaWxlbjogZW5kIDwgc3RhcnQgJiYgIW91dHNpZGUgPyBjb3VudCArIGVuZCAtIHN0YXJ0IDogZW5kIC0gc3RhcnRcbiAgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgcGF0aCBmcm9tIHBvaW50cywgZ3JvdXBpbmcgYnkgdHJ1bmNhdGVkIHgtY29vcmRpbmF0ZVxuICogUG9pbnRzIG5lZWQgdG8gYmUgaW4gb3JkZXIgYnkgeC1jb29yZGluYXRlIGZvciB0aGlzIHRvIHdvcmsgZWZmaWNpZW50bHlcbiAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfFBhdGgyRH0gY3R4IC0gQ29udGV4dFxuICogQHBhcmFtIHtMaW5lRWxlbWVudH0gbGluZVxuICogQHBhcmFtIHtvYmplY3R9IHNlZ21lbnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBzZWdtZW50LnN0YXJ0IC0gc3RhcnQgaW5kZXggb2YgdGhlIHNlZ21lbnQsIHJlZmVycmluZyB0aGUgcG9pbnRzIGFycmF5XG4gKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudC5lbmQgLSBlbmQgaW5kZXggb2YgdGhlIHNlZ21lbnQsIHJlZmVycmluZyB0aGUgcG9pbnRzIGFycmF5XG4gKiBAcGFyYW0ge2Jvb2xlYW59IHNlZ21lbnQubG9vcCAtIGluZGljYXRlcyB0aGF0IHRoZSBzZWdtZW50IGlzIGEgbG9vcFxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtc1xuICogQHBhcmFtIHtib29sZWFufSBwYXJhbXMubW92ZSAtIG1vdmUgdG8gc3RhcnRpbmcgcG9pbnQgKHZzIGxpbmUgdG8gaXQpXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHBhcmFtcy5yZXZlcnNlIC0gcGF0aCB0aGUgc2VnbWVudCBmcm9tIGVuZCB0byBzdGFydFxuICogQHBhcmFtIHtudW1iZXJ9IHBhcmFtcy5zdGFydCAtIGxpbWl0IHNlZ21lbnQgdG8gcG9pbnRzIHN0YXJ0aW5nIGZyb20gYHN0YXJ0YCBpbmRleFxuICogQHBhcmFtIHtudW1iZXJ9IHBhcmFtcy5lbmQgLSBsaW1pdCBzZWdtZW50IHRvIHBvaW50cyBlbmRpbmcgYXQgYHN0YXJ0YCArIGBjb3VudGAgaW5kZXhcbiAqL1xuZnVuY3Rpb24gcGF0aFNlZ21lbnQoY3R4LCBsaW5lLCBzZWdtZW50LCBwYXJhbXMpIHtcbiAgY29uc3Qge3BvaW50cywgb3B0aW9uc30gPSBsaW5lO1xuICBjb25zdCB7Y291bnQsIHN0YXJ0LCBsb29wLCBpbGVufSA9IHBhdGhWYXJzKHBvaW50cywgc2VnbWVudCwgcGFyYW1zKTtcbiAgY29uc3QgbGluZU1ldGhvZCA9IGdldExpbmVNZXRob2Qob3B0aW9ucyk7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItY29uc3RcbiAgbGV0IHttb3ZlID0gdHJ1ZSwgcmV2ZXJzZX0gPSBwYXJhbXMgfHwge307XG4gIGxldCBpLCBwb2ludCwgcHJldjtcblxuICBmb3IgKGkgPSAwOyBpIDw9IGlsZW47ICsraSkge1xuICAgIHBvaW50ID0gcG9pbnRzWyhzdGFydCArIChyZXZlcnNlID8gaWxlbiAtIGkgOiBpKSkgJSBjb3VudF07XG5cbiAgICBpZiAocG9pbnQuc2tpcCkge1xuICAgICAgLy8gSWYgdGhlcmUgaXMgYSBza2lwcGVkIHBvaW50IGluc2lkZSBhIHNlZ21lbnQsIHNwYW5HYXBzIG11c3QgYmUgdHJ1ZVxuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIGlmIChtb3ZlKSB7XG4gICAgICBjdHgubW92ZVRvKHBvaW50LngsIHBvaW50LnkpO1xuICAgICAgbW92ZSA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaW5lTWV0aG9kKGN0eCwgcHJldiwgcG9pbnQsIHJldmVyc2UsIG9wdGlvbnMuc3RlcHBlZCk7XG4gICAgfVxuXG4gICAgcHJldiA9IHBvaW50O1xuICB9XG5cbiAgaWYgKGxvb3ApIHtcbiAgICBwb2ludCA9IHBvaW50c1soc3RhcnQgKyAocmV2ZXJzZSA/IGlsZW4gOiAwKSkgJSBjb3VudF07XG4gICAgbGluZU1ldGhvZChjdHgsIHByZXYsIHBvaW50LCByZXZlcnNlLCBvcHRpb25zLnN0ZXBwZWQpO1xuICB9XG5cbiAgcmV0dXJuICEhbG9vcDtcbn1cblxuLyoqXG4gKiBDcmVhdGUgcGF0aCBmcm9tIHBvaW50cywgZ3JvdXBpbmcgYnkgdHJ1bmNhdGVkIHgtY29vcmRpbmF0ZVxuICogUG9pbnRzIG5lZWQgdG8gYmUgaW4gb3JkZXIgYnkgeC1jb29yZGluYXRlIGZvciB0aGlzIHRvIHdvcmsgZWZmaWNpZW50bHlcbiAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfFBhdGgyRH0gY3R4IC0gQ29udGV4dFxuICogQHBhcmFtIHtMaW5lRWxlbWVudH0gbGluZVxuICogQHBhcmFtIHtvYmplY3R9IHNlZ21lbnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBzZWdtZW50LnN0YXJ0IC0gc3RhcnQgaW5kZXggb2YgdGhlIHNlZ21lbnQsIHJlZmVycmluZyB0aGUgcG9pbnRzIGFycmF5XG4gKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudC5lbmQgLSBlbmQgaW5kZXggb2YgdGhlIHNlZ21lbnQsIHJlZmVycmluZyB0aGUgcG9pbnRzIGFycmF5XG4gKiBAcGFyYW0ge2Jvb2xlYW59IHNlZ21lbnQubG9vcCAtIGluZGljYXRlcyB0aGF0IHRoZSBzZWdtZW50IGlzIGEgbG9vcFxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtc1xuICogQHBhcmFtIHtib29sZWFufSBwYXJhbXMubW92ZSAtIG1vdmUgdG8gc3RhcnRpbmcgcG9pbnQgKHZzIGxpbmUgdG8gaXQpXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHBhcmFtcy5yZXZlcnNlIC0gcGF0aCB0aGUgc2VnbWVudCBmcm9tIGVuZCB0byBzdGFydFxuICogQHBhcmFtIHtudW1iZXJ9IHBhcmFtcy5zdGFydCAtIGxpbWl0IHNlZ21lbnQgdG8gcG9pbnRzIHN0YXJ0aW5nIGZyb20gYHN0YXJ0YCBpbmRleFxuICogQHBhcmFtIHtudW1iZXJ9IHBhcmFtcy5lbmQgLSBsaW1pdCBzZWdtZW50IHRvIHBvaW50cyBlbmRpbmcgYXQgYHN0YXJ0YCArIGBjb3VudGAgaW5kZXhcbiAqL1xuZnVuY3Rpb24gZmFzdFBhdGhTZWdtZW50KGN0eCwgbGluZSwgc2VnbWVudCwgcGFyYW1zKSB7XG4gIGNvbnN0IHBvaW50cyA9IGxpbmUucG9pbnRzO1xuICBjb25zdCB7Y291bnQsIHN0YXJ0LCBpbGVufSA9IHBhdGhWYXJzKHBvaW50cywgc2VnbWVudCwgcGFyYW1zKTtcbiAgY29uc3Qge21vdmUgPSB0cnVlLCByZXZlcnNlfSA9IHBhcmFtcyB8fCB7fTtcbiAgbGV0IGF2Z1ggPSAwO1xuICBsZXQgY291bnRYID0gMDtcbiAgbGV0IGksIHBvaW50LCBwcmV2WCwgbWluWSwgbWF4WSwgbGFzdFk7XG5cbiAgY29uc3QgcG9pbnRJbmRleCA9IChpbmRleCkgPT4gKHN0YXJ0ICsgKHJldmVyc2UgPyBpbGVuIC0gaW5kZXggOiBpbmRleCkpICUgY291bnQ7XG4gIGNvbnN0IGRyYXdYID0gKCkgPT4ge1xuICAgIGlmIChtaW5ZICE9PSBtYXhZKSB7XG4gICAgICAvLyBEcmF3IGxpbmUgdG8gbWF4WSBhbmQgbWluWSwgdXNpbmcgdGhlIGF2ZXJhZ2UgeC1jb29yZGluYXRlXG4gICAgICBjdHgubGluZVRvKGF2Z1gsIG1heFkpO1xuICAgICAgY3R4LmxpbmVUbyhhdmdYLCBtaW5ZKTtcbiAgICAgIC8vIExpbmUgdG8geS12YWx1ZSBvZiBsYXN0IHBvaW50IGluIGdyb3VwLiBTbyB0aGUgbGluZSBjb250aW51ZXNcbiAgICAgIC8vIGZyb20gY29ycmVjdCBwb3NpdGlvbi4gTm90IHVzaW5nIG1vdmUsIHRvIGhhdmUgc29saWQgcGF0aC5cbiAgICAgIGN0eC5saW5lVG8oYXZnWCwgbGFzdFkpO1xuICAgIH1cbiAgfTtcblxuICBpZiAobW92ZSkge1xuICAgIHBvaW50ID0gcG9pbnRzW3BvaW50SW5kZXgoMCldO1xuICAgIGN0eC5tb3ZlVG8ocG9pbnQueCwgcG9pbnQueSk7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDw9IGlsZW47ICsraSkge1xuICAgIHBvaW50ID0gcG9pbnRzW3BvaW50SW5kZXgoaSldO1xuXG4gICAgaWYgKHBvaW50LnNraXApIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIGEgc2tpcHBlZCBwb2ludCBpbnNpZGUgYSBzZWdtZW50LCBzcGFuR2FwcyBtdXN0IGJlIHRydWVcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHggPSBwb2ludC54O1xuICAgIGNvbnN0IHkgPSBwb2ludC55O1xuICAgIGNvbnN0IHRydW5jWCA9IHggfCAwOyAvLyB0cnVuY2F0ZWQgeC1jb29yZGluYXRlXG5cbiAgICBpZiAodHJ1bmNYID09PSBwcmV2WCkge1xuICAgICAgLy8gRGV0ZXJtaW5lIGBtaW5ZYCAvIGBtYXhZYCBhbmQgYGF2Z1hgIHdoaWxlIHdlIHN0YXkgd2l0aGluIHNhbWUgeC1wb3NpdGlvblxuICAgICAgaWYgKHkgPCBtaW5ZKSB7XG4gICAgICAgIG1pblkgPSB5O1xuICAgICAgfSBlbHNlIGlmICh5ID4gbWF4WSkge1xuICAgICAgICBtYXhZID0geTtcbiAgICAgIH1cbiAgICAgIC8vIEZvciBmaXJzdCBwb2ludCBpbiBncm91cCwgY291bnRYIGlzIGAwYCwgc28gYXZlcmFnZSB3aWxsIGJlIGB4YCAvIDEuXG4gICAgICBhdmdYID0gKGNvdW50WCAqIGF2Z1ggKyB4KSAvICsrY291bnRYO1xuICAgIH0gZWxzZSB7XG4gICAgICBkcmF3WCgpO1xuICAgICAgLy8gRHJhdyBsaW5lIHRvIG5leHQgeC1wb3NpdGlvbiwgdXNpbmcgdGhlIGZpcnN0IChvciBvbmx5KVxuICAgICAgLy8geS12YWx1ZSBpbiB0aGF0IGdyb3VwXG4gICAgICBjdHgubGluZVRvKHgsIHkpO1xuXG4gICAgICBwcmV2WCA9IHRydW5jWDtcbiAgICAgIGNvdW50WCA9IDA7XG4gICAgICBtaW5ZID0gbWF4WSA9IHk7XG4gICAgfVxuICAgIC8vIEtlZXAgdHJhY2sgb2YgdGhlIGxhc3QgeS12YWx1ZSBpbiBncm91cFxuICAgIGxhc3RZID0geTtcbiAgfVxuICBkcmF3WCgpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7TGluZUVsZW1lbnR9IGxpbmUgLSB0aGUgbGluZVxuICogQHJldHVybnMge2Z1bmN0aW9ufVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gX2dldFNlZ21lbnRNZXRob2QobGluZSkge1xuICBjb25zdCBvcHRzID0gbGluZS5vcHRpb25zO1xuICBjb25zdCBib3JkZXJEYXNoID0gb3B0cy5ib3JkZXJEYXNoICYmIG9wdHMuYm9yZGVyRGFzaC5sZW5ndGg7XG4gIGNvbnN0IHVzZUZhc3RQYXRoID0gIWxpbmUuX2RlY2ltYXRlZCAmJiAhbGluZS5fbG9vcCAmJiAhb3B0cy50ZW5zaW9uICYmIG9wdHMuY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSAhPT0gJ21vbm90b25lJyAmJiAhb3B0cy5zdGVwcGVkICYmICFib3JkZXJEYXNoO1xuICByZXR1cm4gdXNlRmFzdFBhdGggPyBmYXN0UGF0aFNlZ21lbnQgOiBwYXRoU2VnbWVudDtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBfZ2V0SW50ZXJwb2xhdGlvbk1ldGhvZChvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zLnN0ZXBwZWQpIHtcbiAgICByZXR1cm4gX3N0ZXBwZWRJbnRlcnBvbGF0aW9uO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMudGVuc2lvbiB8fCBvcHRpb25zLmN1YmljSW50ZXJwb2xhdGlvbk1vZGUgPT09ICdtb25vdG9uZScpIHtcbiAgICByZXR1cm4gX2JlemllckludGVycG9sYXRpb247XG4gIH1cblxuICByZXR1cm4gX3BvaW50SW5MaW5lO1xufVxuXG5mdW5jdGlvbiBzdHJva2VQYXRoV2l0aENhY2hlKGN0eCwgbGluZSwgc3RhcnQsIGNvdW50KSB7XG4gIGxldCBwYXRoID0gbGluZS5fcGF0aDtcbiAgaWYgKCFwYXRoKSB7XG4gICAgcGF0aCA9IGxpbmUuX3BhdGggPSBuZXcgUGF0aDJEKCk7XG4gICAgaWYgKGxpbmUucGF0aChwYXRoLCBzdGFydCwgY291bnQpKSB7XG4gICAgICBwYXRoLmNsb3NlUGF0aCgpO1xuICAgIH1cbiAgfVxuICBzZXRTdHlsZShjdHgsIGxpbmUub3B0aW9ucyk7XG4gIGN0eC5zdHJva2UocGF0aCk7XG59XG5cbmZ1bmN0aW9uIHN0cm9rZVBhdGhEaXJlY3QoY3R4LCBsaW5lLCBzdGFydCwgY291bnQpIHtcbiAgY29uc3Qge3NlZ21lbnRzLCBvcHRpb25zfSA9IGxpbmU7XG4gIGNvbnN0IHNlZ21lbnRNZXRob2QgPSBfZ2V0U2VnbWVudE1ldGhvZChsaW5lKTtcblxuICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpIHtcbiAgICBzZXRTdHlsZShjdHgsIG9wdGlvbnMsIHNlZ21lbnQuc3R5bGUpO1xuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBpZiAoc2VnbWVudE1ldGhvZChjdHgsIGxpbmUsIHNlZ21lbnQsIHtzdGFydCwgZW5kOiBzdGFydCArIGNvdW50IC0gMX0pKSB7XG4gICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgfVxuICAgIGN0eC5zdHJva2UoKTtcbiAgfVxufVxuXG5jb25zdCB1c2VQYXRoMkQgPSB0eXBlb2YgUGF0aDJEID09PSAnZnVuY3Rpb24nO1xuXG5mdW5jdGlvbiBkcmF3KGN0eCwgbGluZSwgc3RhcnQsIGNvdW50KSB7XG4gIGlmICh1c2VQYXRoMkQgJiYgIWxpbmUub3B0aW9ucy5zZWdtZW50KSB7XG4gICAgc3Ryb2tlUGF0aFdpdGhDYWNoZShjdHgsIGxpbmUsIHN0YXJ0LCBjb3VudCk7XG4gIH0gZWxzZSB7XG4gICAgc3Ryb2tlUGF0aERpcmVjdChjdHgsIGxpbmUsIHN0YXJ0LCBjb3VudCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGluZUVsZW1lbnQgZXh0ZW5kcyBFbGVtZW50IHtcblxuICBzdGF0aWMgaWQgPSAnbGluZSc7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgYm9yZGVyQ2FwU3R5bGU6ICdidXR0JyxcbiAgICBib3JkZXJEYXNoOiBbXSxcbiAgICBib3JkZXJEYXNoT2Zmc2V0OiAwLFxuICAgIGJvcmRlckpvaW5TdHlsZTogJ21pdGVyJyxcbiAgICBib3JkZXJXaWR0aDogMyxcbiAgICBjYXBCZXppZXJQb2ludHM6IHRydWUsXG4gICAgY3ViaWNJbnRlcnBvbGF0aW9uTW9kZTogJ2RlZmF1bHQnLFxuICAgIGZpbGw6IGZhbHNlLFxuICAgIHNwYW5HYXBzOiBmYWxzZSxcbiAgICBzdGVwcGVkOiBmYWxzZSxcbiAgICB0ZW5zaW9uOiAwLFxuICB9O1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRSb3V0ZXMgPSB7XG4gICAgYmFja2dyb3VuZENvbG9yOiAnYmFja2dyb3VuZENvbG9yJyxcbiAgICBib3JkZXJDb2xvcjogJ2JvcmRlckNvbG9yJ1xuICB9O1xuXG5cbiAgc3RhdGljIGRlc2NyaXB0b3JzID0ge1xuICAgIF9zY3JpcHRhYmxlOiB0cnVlLFxuICAgIF9pbmRleGFibGU6IChuYW1lKSA9PiBuYW1lICE9PSAnYm9yZGVyRGFzaCcgJiYgbmFtZSAhPT0gJ2ZpbGwnLFxuICB9O1xuXG5cbiAgY29uc3RydWN0b3IoY2ZnKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuYW5pbWF0ZWQgPSB0cnVlO1xuICAgIHRoaXMub3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9jaGFydCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9sb29wID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2Z1bGxMb29wID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3BhdGggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcG9pbnRzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3NlZ21lbnRzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2RlY2ltYXRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3BvaW50c1VwZGF0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9kYXRhc2V0SW5kZXggPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAoY2ZnKSB7XG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGNmZyk7XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlQ29udHJvbFBvaW50cyhjaGFydEFyZWEsIGluZGV4QXhpcykge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgaWYgKChvcHRpb25zLnRlbnNpb24gfHwgb3B0aW9ucy5jdWJpY0ludGVycG9sYXRpb25Nb2RlID09PSAnbW9ub3RvbmUnKSAmJiAhb3B0aW9ucy5zdGVwcGVkICYmICF0aGlzLl9wb2ludHNVcGRhdGVkKSB7XG4gICAgICBjb25zdCBsb29wID0gb3B0aW9ucy5zcGFuR2FwcyA/IHRoaXMuX2xvb3AgOiB0aGlzLl9mdWxsTG9vcDtcbiAgICAgIF91cGRhdGVCZXppZXJDb250cm9sUG9pbnRzKHRoaXMuX3BvaW50cywgb3B0aW9ucywgY2hhcnRBcmVhLCBsb29wLCBpbmRleEF4aXMpO1xuICAgICAgdGhpcy5fcG9pbnRzVXBkYXRlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgc2V0IHBvaW50cyhwb2ludHMpIHtcbiAgICB0aGlzLl9wb2ludHMgPSBwb2ludHM7XG4gICAgZGVsZXRlIHRoaXMuX3NlZ21lbnRzO1xuICAgIGRlbGV0ZSB0aGlzLl9wYXRoO1xuICAgIHRoaXMuX3BvaW50c1VwZGF0ZWQgPSBmYWxzZTtcbiAgfVxuXG4gIGdldCBwb2ludHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BvaW50cztcbiAgfVxuXG4gIGdldCBzZWdtZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy5fc2VnbWVudHMgfHwgKHRoaXMuX3NlZ21lbnRzID0gX2NvbXB1dGVTZWdtZW50cyh0aGlzLCB0aGlzLm9wdGlvbnMuc2VnbWVudCkpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEZpcnN0IG5vbi1za2lwcGVkIHBvaW50IG9uIHRoaXMgbGluZVxuXHQgKiBAcmV0dXJucyB7UG9pbnRFbGVtZW50fHVuZGVmaW5lZH1cblx0ICovXG4gIGZpcnN0KCkge1xuICAgIGNvbnN0IHNlZ21lbnRzID0gdGhpcy5zZWdtZW50cztcbiAgICBjb25zdCBwb2ludHMgPSB0aGlzLnBvaW50cztcbiAgICByZXR1cm4gc2VnbWVudHMubGVuZ3RoICYmIHBvaW50c1tzZWdtZW50c1swXS5zdGFydF07XG4gIH1cblxuICAvKipcblx0ICogTGFzdCBub24tc2tpcHBlZCBwb2ludCBvbiB0aGlzIGxpbmVcblx0ICogQHJldHVybnMge1BvaW50RWxlbWVudHx1bmRlZmluZWR9XG5cdCAqL1xuICBsYXN0KCkge1xuICAgIGNvbnN0IHNlZ21lbnRzID0gdGhpcy5zZWdtZW50cztcbiAgICBjb25zdCBwb2ludHMgPSB0aGlzLnBvaW50cztcbiAgICBjb25zdCBjb3VudCA9IHNlZ21lbnRzLmxlbmd0aDtcbiAgICByZXR1cm4gY291bnQgJiYgcG9pbnRzW3NlZ21lbnRzW2NvdW50IC0gMV0uZW5kXTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBJbnRlcnBvbGF0ZSBhIHBvaW50IGluIHRoaXMgbGluZSBhdCB0aGUgc2FtZSB2YWx1ZSBvbiBgcHJvcGVydHlgIGFzXG5cdCAqIHRoZSByZWZlcmVuY2UgYHBvaW50YCBwcm92aWRlZFxuXHQgKiBAcGFyYW0ge1BvaW50RWxlbWVudH0gcG9pbnQgLSB0aGUgcmVmZXJlbmNlIHBvaW50XG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSAtIHRoZSBwcm9wZXJ0eSB0byBtYXRjaCBvblxuXHQgKiBAcmV0dXJucyB7UG9pbnRFbGVtZW50fHVuZGVmaW5lZH1cblx0ICovXG4gIGludGVycG9sYXRlKHBvaW50LCBwcm9wZXJ0eSkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgdmFsdWUgPSBwb2ludFtwcm9wZXJ0eV07XG4gICAgY29uc3QgcG9pbnRzID0gdGhpcy5wb2ludHM7XG4gICAgY29uc3Qgc2VnbWVudHMgPSBfYm91bmRTZWdtZW50cyh0aGlzLCB7cHJvcGVydHksIHN0YXJ0OiB2YWx1ZSwgZW5kOiB2YWx1ZX0pO1xuXG4gICAgaWYgKCFzZWdtZW50cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICBjb25zdCBfaW50ZXJwb2xhdGUgPSBfZ2V0SW50ZXJwb2xhdGlvbk1ldGhvZChvcHRpb25zKTtcbiAgICBsZXQgaSwgaWxlbjtcbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gc2VnbWVudHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBjb25zdCB7c3RhcnQsIGVuZH0gPSBzZWdtZW50c1tpXTtcbiAgICAgIGNvbnN0IHAxID0gcG9pbnRzW3N0YXJ0XTtcbiAgICAgIGNvbnN0IHAyID0gcG9pbnRzW2VuZF07XG4gICAgICBpZiAocDEgPT09IHAyKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHAxKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCB0ID0gTWF0aC5hYnMoKHZhbHVlIC0gcDFbcHJvcGVydHldKSAvIChwMltwcm9wZXJ0eV0gLSBwMVtwcm9wZXJ0eV0pKTtcbiAgICAgIGNvbnN0IGludGVycG9sYXRlZCA9IF9pbnRlcnBvbGF0ZShwMSwgcDIsIHQsIG9wdGlvbnMuc3RlcHBlZCk7XG4gICAgICBpbnRlcnBvbGF0ZWRbcHJvcGVydHldID0gcG9pbnRbcHJvcGVydHldO1xuICAgICAgcmVzdWx0LnB1c2goaW50ZXJwb2xhdGVkKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdC5sZW5ndGggPT09IDEgPyByZXN1bHRbMF0gOiByZXN1bHQ7XG4gIH1cblxuICAvKipcblx0ICogQXBwZW5kIGEgc2VnbWVudCBvZiB0aGlzIGxpbmUgdG8gY3VycmVudCBwYXRoLlxuXHQgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY3R4XG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBzZWdtZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzZWdtZW50LnN0YXJ0IC0gc3RhcnQgaW5kZXggb2YgdGhlIHNlZ21lbnQsIHJlZmVycmluZyB0aGUgcG9pbnRzIGFycmF5XG4gXHQgKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudC5lbmQgLSBlbmQgaW5kZXggb2YgdGhlIHNlZ21lbnQsIHJlZmVycmluZyB0aGUgcG9pbnRzIGFycmF5XG4gXHQgKiBAcGFyYW0ge2Jvb2xlYW59IHNlZ21lbnQubG9vcCAtIGluZGljYXRlcyB0aGF0IHRoZSBzZWdtZW50IGlzIGEgbG9vcFxuXHQgKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gcGFyYW1zLm1vdmUgLSBtb3ZlIHRvIHN0YXJ0aW5nIHBvaW50ICh2cyBsaW5lIHRvIGl0KVxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IHBhcmFtcy5yZXZlcnNlIC0gcGF0aCB0aGUgc2VnbWVudCBmcm9tIGVuZCB0byBzdGFydFxuXHQgKiBAcGFyYW0ge251bWJlcn0gcGFyYW1zLnN0YXJ0IC0gbGltaXQgc2VnbWVudCB0byBwb2ludHMgc3RhcnRpbmcgZnJvbSBgc3RhcnRgIGluZGV4XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBwYXJhbXMuZW5kIC0gbGltaXQgc2VnbWVudCB0byBwb2ludHMgZW5kaW5nIGF0IGBzdGFydGAgKyBgY291bnRgIGluZGV4XG5cdCAqIEByZXR1cm5zIHt1bmRlZmluZWR8Ym9vbGVhbn0gLSB0cnVlIGlmIHRoZSBzZWdtZW50IGlzIGEgZnVsbCBsb29wIChwYXRoIHNob3VsZCBiZSBjbG9zZWQpXG5cdCAqL1xuICBwYXRoU2VnbWVudChjdHgsIHNlZ21lbnQsIHBhcmFtcykge1xuICAgIGNvbnN0IHNlZ21lbnRNZXRob2QgPSBfZ2V0U2VnbWVudE1ldGhvZCh0aGlzKTtcbiAgICByZXR1cm4gc2VnbWVudE1ldGhvZChjdHgsIHRoaXMsIHNlZ21lbnQsIHBhcmFtcyk7XG4gIH1cblxuICAvKipcblx0ICogQXBwZW5kIGFsbCBzZWdtZW50cyBvZiB0aGlzIGxpbmUgdG8gY3VycmVudCBwYXRoLlxuXHQgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRHxQYXRoMkR9IGN0eFxuXHQgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0XVxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2NvdW50XVxuXHQgKiBAcmV0dXJucyB7dW5kZWZpbmVkfGJvb2xlYW59IC0gdHJ1ZSBpZiBsaW5lIGlzIGEgZnVsbCBsb29wIChwYXRoIHNob3VsZCBiZSBjbG9zZWQpXG5cdCAqL1xuICBwYXRoKGN0eCwgc3RhcnQsIGNvdW50KSB7XG4gICAgY29uc3Qgc2VnbWVudHMgPSB0aGlzLnNlZ21lbnRzO1xuICAgIGNvbnN0IHNlZ21lbnRNZXRob2QgPSBfZ2V0U2VnbWVudE1ldGhvZCh0aGlzKTtcbiAgICBsZXQgbG9vcCA9IHRoaXMuX2xvb3A7XG5cbiAgICBzdGFydCA9IHN0YXJ0IHx8IDA7XG4gICAgY291bnQgPSBjb3VudCB8fCAodGhpcy5wb2ludHMubGVuZ3RoIC0gc3RhcnQpO1xuXG4gICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgICBsb29wICY9IHNlZ21lbnRNZXRob2QoY3R4LCB0aGlzLCBzZWdtZW50LCB7c3RhcnQsIGVuZDogc3RhcnQgKyBjb3VudCAtIDF9KTtcbiAgICB9XG4gICAgcmV0dXJuICEhbG9vcDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBEcmF3XG5cdCAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjdHhcblx0ICogQHBhcmFtIHtvYmplY3R9IGNoYXJ0QXJlYVxuXHQgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0XVxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2NvdW50XVxuXHQgKi9cbiAgZHJhdyhjdHgsIGNoYXJ0QXJlYSwgc3RhcnQsIGNvdW50KSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyB8fCB7fTtcbiAgICBjb25zdCBwb2ludHMgPSB0aGlzLnBvaW50cyB8fCBbXTtcblxuICAgIGlmIChwb2ludHMubGVuZ3RoICYmIG9wdGlvbnMuYm9yZGVyV2lkdGgpIHtcbiAgICAgIGN0eC5zYXZlKCk7XG5cbiAgICAgIGRyYXcoY3R4LCB0aGlzLCBzdGFydCwgY291bnQpO1xuXG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmFuaW1hdGVkKSB7XG4gICAgICAvLyBXaGVuIGxpbmUgaXMgYW5pbWF0ZWQsIHRoZSBjb250cm9sIHBvaW50cyBhbmQgcGF0aCBhcmUgbm90IGNhY2hlZC5cbiAgICAgIHRoaXMuX3BvaW50c1VwZGF0ZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuX3BhdGggPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG59XG4iLCAiaW1wb3J0IEVsZW1lbnQgZnJvbSAnLi4vY29yZS9jb3JlLmVsZW1lbnQuanMnO1xuaW1wb3J0IHtkcmF3UG9pbnQsIF9pc1BvaW50SW5BcmVhfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY2FudmFzLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgQ2FydGVzaWFuUGFyc2VkRGF0YSxcbiAgQ2hhcnRBcmVhLFxuICBQb2ludCxcbiAgUG9pbnRIb3Zlck9wdGlvbnMsXG4gIFBvaW50T3B0aW9ucyxcbn0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuXG5mdW5jdGlvbiBpblJhbmdlKGVsOiBQb2ludEVsZW1lbnQsIHBvczogbnVtYmVyLCBheGlzOiAneCcgfCAneScsIHVzZUZpbmFsUG9zaXRpb24/OiBib29sZWFuKSB7XG4gIGNvbnN0IG9wdGlvbnMgPSBlbC5vcHRpb25zO1xuICBjb25zdCB7W2F4aXNdOiB2YWx1ZX0gPSBlbC5nZXRQcm9wcyhbYXhpc10sIHVzZUZpbmFsUG9zaXRpb24pO1xuXG4gIHJldHVybiAoTWF0aC5hYnMocG9zIC0gdmFsdWUpIDwgb3B0aW9ucy5yYWRpdXMgKyBvcHRpb25zLmhpdFJhZGl1cyk7XG59XG5cbmV4cG9ydCB0eXBlIFBvaW50UHJvcHMgPSBQb2ludFxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQb2ludEVsZW1lbnQgZXh0ZW5kcyBFbGVtZW50PFBvaW50UHJvcHMsIFBvaW50T3B0aW9ucyAmIFBvaW50SG92ZXJPcHRpb25zPiB7XG5cbiAgc3RhdGljIGlkID0gJ3BvaW50JztcblxuICBwYXJzZWQ6IENhcnRlc2lhblBhcnNlZERhdGE7XG4gIHNraXA/OiBib29sZWFuO1xuICBzdG9wPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICBib3JkZXJXaWR0aDogMSxcbiAgICBoaXRSYWRpdXM6IDEsXG4gICAgaG92ZXJCb3JkZXJXaWR0aDogMSxcbiAgICBob3ZlclJhZGl1czogNCxcbiAgICBwb2ludFN0eWxlOiAnY2lyY2xlJyxcbiAgICByYWRpdXM6IDMsXG4gICAgcm90YXRpb246IDBcbiAgfTtcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0Um91dGVzID0ge1xuICAgIGJhY2tncm91bmRDb2xvcjogJ2JhY2tncm91bmRDb2xvcicsXG4gICAgYm9yZGVyQ29sb3I6ICdib3JkZXJDb2xvcidcbiAgfTtcblxuICBjb25zdHJ1Y3RvcihjZmcpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5vcHRpb25zID0gdW5kZWZpbmVkO1xuICAgIHRoaXMucGFyc2VkID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc2tpcCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnN0b3AgPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAoY2ZnKSB7XG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGNmZyk7XG4gICAgfVxuICB9XG5cbiAgaW5SYW5nZShtb3VzZVg6IG51bWJlciwgbW91c2VZOiBudW1iZXIsIHVzZUZpbmFsUG9zaXRpb24/OiBib29sZWFuKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB7eCwgeX0gPSB0aGlzLmdldFByb3BzKFsneCcsICd5J10sIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIHJldHVybiAoKE1hdGgucG93KG1vdXNlWCAtIHgsIDIpICsgTWF0aC5wb3cobW91c2VZIC0geSwgMikpIDwgTWF0aC5wb3cob3B0aW9ucy5oaXRSYWRpdXMgKyBvcHRpb25zLnJhZGl1cywgMikpO1xuICB9XG5cbiAgaW5YUmFuZ2UobW91c2VYOiBudW1iZXIsIHVzZUZpbmFsUG9zaXRpb24/OiBib29sZWFuKSB7XG4gICAgcmV0dXJuIGluUmFuZ2UodGhpcywgbW91c2VYLCAneCcsIHVzZUZpbmFsUG9zaXRpb24pO1xuICB9XG5cbiAgaW5ZUmFuZ2UobW91c2VZOiBudW1iZXIsIHVzZUZpbmFsUG9zaXRpb24/OiBib29sZWFuKSB7XG4gICAgcmV0dXJuIGluUmFuZ2UodGhpcywgbW91c2VZLCAneScsIHVzZUZpbmFsUG9zaXRpb24pO1xuICB9XG5cbiAgZ2V0Q2VudGVyUG9pbnQodXNlRmluYWxQb3NpdGlvbj86IGJvb2xlYW4pIHtcbiAgICBjb25zdCB7eCwgeX0gPSB0aGlzLmdldFByb3BzKFsneCcsICd5J10sIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIHJldHVybiB7eCwgeX07XG4gIH1cblxuICBzaXplKG9wdGlvbnM/OiBQYXJ0aWFsPFBvaW50T3B0aW9ucyAmIFBvaW50SG92ZXJPcHRpb25zPikge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHRoaXMub3B0aW9ucyB8fCB7fTtcbiAgICBsZXQgcmFkaXVzID0gb3B0aW9ucy5yYWRpdXMgfHwgMDtcbiAgICByYWRpdXMgPSBNYXRoLm1heChyYWRpdXMsIHJhZGl1cyAmJiBvcHRpb25zLmhvdmVyUmFkaXVzIHx8IDApO1xuICAgIGNvbnN0IGJvcmRlcldpZHRoID0gcmFkaXVzICYmIG9wdGlvbnMuYm9yZGVyV2lkdGggfHwgMDtcbiAgICByZXR1cm4gKHJhZGl1cyArIGJvcmRlcldpZHRoKSAqIDI7XG4gIH1cblxuICBkcmF3KGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCBhcmVhOiBDaGFydEFyZWEpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuXG4gICAgaWYgKHRoaXMuc2tpcCB8fCBvcHRpb25zLnJhZGl1cyA8IDAuMSB8fCAhX2lzUG9pbnRJbkFyZWEodGhpcywgYXJlYSwgdGhpcy5zaXplKG9wdGlvbnMpIC8gMikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBvcHRpb25zLmJvcmRlckNvbG9yO1xuICAgIGN0eC5saW5lV2lkdGggPSBvcHRpb25zLmJvcmRlcldpZHRoO1xuICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLmJhY2tncm91bmRDb2xvcjtcbiAgICBkcmF3UG9pbnQoY3R4LCBvcHRpb25zLCB0aGlzLngsIHRoaXMueSk7XG4gIH1cblxuICBnZXRSYW5nZSgpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zIHx8IHt9O1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgRmFsbGJhY2tzIHNob3VsZCBuZXZlciBiZSBoaXQgaW4gcHJhY3RpY2VcbiAgICByZXR1cm4gb3B0aW9ucy5yYWRpdXMgKyBvcHRpb25zLmhpdFJhZGl1cztcbiAgfVxufVxuIiwgImltcG9ydCBFbGVtZW50IGZyb20gJy4uL2NvcmUvY29yZS5lbGVtZW50LmpzJztcbmltcG9ydCB7aXNPYmplY3QsIF9pc0JldHdlZW4sIF9saW1pdFZhbHVlfSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcbmltcG9ydCB7YWRkUm91bmRlZFJlY3RQYXRofSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY2FudmFzLmpzJztcbmltcG9ydCB7dG9UUkJMLCB0b1RSQkxDb3JuZXJzfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMub3B0aW9ucy5qcyc7XG5cbi8qKiBAdHlwZWRlZiB7eyB4OiBudW1iZXIsIHk6IG51bWJlciwgYmFzZTogbnVtYmVyLCBob3Jpem9udGFsOiBib29sZWFuLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciB9fSBCYXJQcm9wcyAqL1xuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGJvdW5kcyBvZiB0aGUgYmFyIHJlZ2FyZGxlc3Mgb2YgdGhlIG9yaWVudGF0aW9uXG4gKiBAcGFyYW0ge0JhckVsZW1lbnR9IGJhciB0aGUgYmFyXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXVxuICogQHJldHVybiB7b2JqZWN0fSBib3VuZHMgb2YgdGhlIGJhclxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0QmFyQm91bmRzKGJhciwgdXNlRmluYWxQb3NpdGlvbikge1xuICBjb25zdCB7eCwgeSwgYmFzZSwgd2lkdGgsIGhlaWdodH0gPSAvKiogQHR5cGUge0JhclByb3BzfSAqLyAoYmFyLmdldFByb3BzKFsneCcsICd5JywgJ2Jhc2UnLCAnd2lkdGgnLCAnaGVpZ2h0J10sIHVzZUZpbmFsUG9zaXRpb24pKTtcblxuICBsZXQgbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tLCBoYWxmO1xuXG4gIGlmIChiYXIuaG9yaXpvbnRhbCkge1xuICAgIGhhbGYgPSBoZWlnaHQgLyAyO1xuICAgIGxlZnQgPSBNYXRoLm1pbih4LCBiYXNlKTtcbiAgICByaWdodCA9IE1hdGgubWF4KHgsIGJhc2UpO1xuICAgIHRvcCA9IHkgLSBoYWxmO1xuICAgIGJvdHRvbSA9IHkgKyBoYWxmO1xuICB9IGVsc2Uge1xuICAgIGhhbGYgPSB3aWR0aCAvIDI7XG4gICAgbGVmdCA9IHggLSBoYWxmO1xuICAgIHJpZ2h0ID0geCArIGhhbGY7XG4gICAgdG9wID0gTWF0aC5taW4oeSwgYmFzZSk7XG4gICAgYm90dG9tID0gTWF0aC5tYXgoeSwgYmFzZSk7XG4gIH1cblxuICByZXR1cm4ge2xlZnQsIHRvcCwgcmlnaHQsIGJvdHRvbX07XG59XG5cbmZ1bmN0aW9uIHNraXBPckxpbWl0KHNraXAsIHZhbHVlLCBtaW4sIG1heCkge1xuICByZXR1cm4gc2tpcCA/IDAgOiBfbGltaXRWYWx1ZSh2YWx1ZSwgbWluLCBtYXgpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUJvcmRlcldpZHRoKGJhciwgbWF4VywgbWF4SCkge1xuICBjb25zdCB2YWx1ZSA9IGJhci5vcHRpb25zLmJvcmRlcldpZHRoO1xuICBjb25zdCBza2lwID0gYmFyLmJvcmRlclNraXBwZWQ7XG4gIGNvbnN0IG8gPSB0b1RSQkwodmFsdWUpO1xuXG4gIHJldHVybiB7XG4gICAgdDogc2tpcE9yTGltaXQoc2tpcC50b3AsIG8udG9wLCAwLCBtYXhIKSxcbiAgICByOiBza2lwT3JMaW1pdChza2lwLnJpZ2h0LCBvLnJpZ2h0LCAwLCBtYXhXKSxcbiAgICBiOiBza2lwT3JMaW1pdChza2lwLmJvdHRvbSwgby5ib3R0b20sIDAsIG1heEgpLFxuICAgIGw6IHNraXBPckxpbWl0KHNraXAubGVmdCwgby5sZWZ0LCAwLCBtYXhXKVxuICB9O1xufVxuXG5mdW5jdGlvbiBwYXJzZUJvcmRlclJhZGl1cyhiYXIsIG1heFcsIG1heEgpIHtcbiAgY29uc3Qge2VuYWJsZUJvcmRlclJhZGl1c30gPSBiYXIuZ2V0UHJvcHMoWydlbmFibGVCb3JkZXJSYWRpdXMnXSk7XG4gIGNvbnN0IHZhbHVlID0gYmFyLm9wdGlvbnMuYm9yZGVyUmFkaXVzO1xuICBjb25zdCBvID0gdG9UUkJMQ29ybmVycyh2YWx1ZSk7XG4gIGNvbnN0IG1heFIgPSBNYXRoLm1pbihtYXhXLCBtYXhIKTtcbiAgY29uc3Qgc2tpcCA9IGJhci5ib3JkZXJTa2lwcGVkO1xuXG4gIC8vIElmIHRoZSB2YWx1ZSBpcyBhbiBvYmplY3QsIGFzc3VtZSB0aGUgdXNlciBrbm93cyB3aGF0IHRoZXkgYXJlIGRvaW5nXG4gIC8vIGFuZCBhcHBseSBhcyBkaXJlY3RlZC5cbiAgY29uc3QgZW5hYmxlQm9yZGVyID0gZW5hYmxlQm9yZGVyUmFkaXVzIHx8IGlzT2JqZWN0KHZhbHVlKTtcblxuICByZXR1cm4ge1xuICAgIHRvcExlZnQ6IHNraXBPckxpbWl0KCFlbmFibGVCb3JkZXIgfHwgc2tpcC50b3AgfHwgc2tpcC5sZWZ0LCBvLnRvcExlZnQsIDAsIG1heFIpLFxuICAgIHRvcFJpZ2h0OiBza2lwT3JMaW1pdCghZW5hYmxlQm9yZGVyIHx8IHNraXAudG9wIHx8IHNraXAucmlnaHQsIG8udG9wUmlnaHQsIDAsIG1heFIpLFxuICAgIGJvdHRvbUxlZnQ6IHNraXBPckxpbWl0KCFlbmFibGVCb3JkZXIgfHwgc2tpcC5ib3R0b20gfHwgc2tpcC5sZWZ0LCBvLmJvdHRvbUxlZnQsIDAsIG1heFIpLFxuICAgIGJvdHRvbVJpZ2h0OiBza2lwT3JMaW1pdCghZW5hYmxlQm9yZGVyIHx8IHNraXAuYm90dG9tIHx8IHNraXAucmlnaHQsIG8uYm90dG9tUmlnaHQsIDAsIG1heFIpXG4gIH07XG59XG5cbmZ1bmN0aW9uIGJvdW5kaW5nUmVjdHMoYmFyKSB7XG4gIGNvbnN0IGJvdW5kcyA9IGdldEJhckJvdW5kcyhiYXIpO1xuICBjb25zdCB3aWR0aCA9IGJvdW5kcy5yaWdodCAtIGJvdW5kcy5sZWZ0O1xuICBjb25zdCBoZWlnaHQgPSBib3VuZHMuYm90dG9tIC0gYm91bmRzLnRvcDtcbiAgY29uc3QgYm9yZGVyID0gcGFyc2VCb3JkZXJXaWR0aChiYXIsIHdpZHRoIC8gMiwgaGVpZ2h0IC8gMik7XG4gIGNvbnN0IHJhZGl1cyA9IHBhcnNlQm9yZGVyUmFkaXVzKGJhciwgd2lkdGggLyAyLCBoZWlnaHQgLyAyKTtcblxuICByZXR1cm4ge1xuICAgIG91dGVyOiB7XG4gICAgICB4OiBib3VuZHMubGVmdCxcbiAgICAgIHk6IGJvdW5kcy50b3AsXG4gICAgICB3OiB3aWR0aCxcbiAgICAgIGg6IGhlaWdodCxcbiAgICAgIHJhZGl1c1xuICAgIH0sXG4gICAgaW5uZXI6IHtcbiAgICAgIHg6IGJvdW5kcy5sZWZ0ICsgYm9yZGVyLmwsXG4gICAgICB5OiBib3VuZHMudG9wICsgYm9yZGVyLnQsXG4gICAgICB3OiB3aWR0aCAtIGJvcmRlci5sIC0gYm9yZGVyLnIsXG4gICAgICBoOiBoZWlnaHQgLSBib3JkZXIudCAtIGJvcmRlci5iLFxuICAgICAgcmFkaXVzOiB7XG4gICAgICAgIHRvcExlZnQ6IE1hdGgubWF4KDAsIHJhZGl1cy50b3BMZWZ0IC0gTWF0aC5tYXgoYm9yZGVyLnQsIGJvcmRlci5sKSksXG4gICAgICAgIHRvcFJpZ2h0OiBNYXRoLm1heCgwLCByYWRpdXMudG9wUmlnaHQgLSBNYXRoLm1heChib3JkZXIudCwgYm9yZGVyLnIpKSxcbiAgICAgICAgYm90dG9tTGVmdDogTWF0aC5tYXgoMCwgcmFkaXVzLmJvdHRvbUxlZnQgLSBNYXRoLm1heChib3JkZXIuYiwgYm9yZGVyLmwpKSxcbiAgICAgICAgYm90dG9tUmlnaHQ6IE1hdGgubWF4KDAsIHJhZGl1cy5ib3R0b21SaWdodCAtIE1hdGgubWF4KGJvcmRlci5iLCBib3JkZXIucikpLFxuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gaW5SYW5nZShiYXIsIHgsIHksIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgY29uc3Qgc2tpcFggPSB4ID09PSBudWxsO1xuICBjb25zdCBza2lwWSA9IHkgPT09IG51bGw7XG4gIGNvbnN0IHNraXBCb3RoID0gc2tpcFggJiYgc2tpcFk7XG4gIGNvbnN0IGJvdW5kcyA9IGJhciAmJiAhc2tpcEJvdGggJiYgZ2V0QmFyQm91bmRzKGJhciwgdXNlRmluYWxQb3NpdGlvbik7XG5cbiAgcmV0dXJuIGJvdW5kc1xuXHRcdCYmIChza2lwWCB8fCBfaXNCZXR3ZWVuKHgsIGJvdW5kcy5sZWZ0LCBib3VuZHMucmlnaHQpKVxuXHRcdCYmIChza2lwWSB8fCBfaXNCZXR3ZWVuKHksIGJvdW5kcy50b3AsIGJvdW5kcy5ib3R0b20pKTtcbn1cblxuZnVuY3Rpb24gaGFzUmFkaXVzKHJhZGl1cykge1xuICByZXR1cm4gcmFkaXVzLnRvcExlZnQgfHwgcmFkaXVzLnRvcFJpZ2h0IHx8IHJhZGl1cy5ib3R0b21MZWZ0IHx8IHJhZGl1cy5ib3R0b21SaWdodDtcbn1cblxuLyoqXG4gKiBBZGQgYSBwYXRoIG9mIGEgcmVjdGFuZ2xlIHRvIHRoZSBjdXJyZW50IHN1Yi1wYXRoXG4gKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY3R4IENvbnRleHRcbiAqIEBwYXJhbSB7Kn0gcmVjdCBCb3VuZGluZyByZWN0XG4gKi9cbmZ1bmN0aW9uIGFkZE5vcm1hbFJlY3RQYXRoKGN0eCwgcmVjdCkge1xuICBjdHgucmVjdChyZWN0LngsIHJlY3QueSwgcmVjdC53LCByZWN0LmgpO1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlUmVjdChyZWN0LCBhbW91bnQsIHJlZlJlY3QgPSB7fSkge1xuICBjb25zdCB4ID0gcmVjdC54ICE9PSByZWZSZWN0LnggPyAtYW1vdW50IDogMDtcbiAgY29uc3QgeSA9IHJlY3QueSAhPT0gcmVmUmVjdC55ID8gLWFtb3VudCA6IDA7XG4gIGNvbnN0IHcgPSAocmVjdC54ICsgcmVjdC53ICE9PSByZWZSZWN0LnggKyByZWZSZWN0LncgPyBhbW91bnQgOiAwKSAtIHg7XG4gIGNvbnN0IGggPSAocmVjdC55ICsgcmVjdC5oICE9PSByZWZSZWN0LnkgKyByZWZSZWN0LmggPyBhbW91bnQgOiAwKSAtIHk7XG4gIHJldHVybiB7XG4gICAgeDogcmVjdC54ICsgeCxcbiAgICB5OiByZWN0LnkgKyB5LFxuICAgIHc6IHJlY3QudyArIHcsXG4gICAgaDogcmVjdC5oICsgaCxcbiAgICByYWRpdXM6IHJlY3QucmFkaXVzXG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhckVsZW1lbnQgZXh0ZW5kcyBFbGVtZW50IHtcblxuICBzdGF0aWMgaWQgPSAnYmFyJztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICBib3JkZXJTa2lwcGVkOiAnc3RhcnQnLFxuICAgIGJvcmRlcldpZHRoOiAwLFxuICAgIGJvcmRlclJhZGl1czogMCxcbiAgICBpbmZsYXRlQW1vdW50OiAnYXV0bycsXG4gICAgcG9pbnRTdHlsZTogdW5kZWZpbmVkXG4gIH07XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdFJvdXRlcyA9IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6ICdiYWNrZ3JvdW5kQ29sb3InLFxuICAgIGJvcmRlckNvbG9yOiAnYm9yZGVyQ29sb3InXG4gIH07XG5cbiAgY29uc3RydWN0b3IoY2ZnKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMub3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmhvcml6b250YWwgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5iYXNlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMud2lkdGggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5oZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5pbmZsYXRlQW1vdW50ID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGNmZykge1xuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBjZmcpO1xuICAgIH1cbiAgfVxuXG4gIGRyYXcoY3R4KSB7XG4gICAgY29uc3Qge2luZmxhdGVBbW91bnQsIG9wdGlvbnM6IHtib3JkZXJDb2xvciwgYmFja2dyb3VuZENvbG9yfX0gPSB0aGlzO1xuICAgIGNvbnN0IHtpbm5lciwgb3V0ZXJ9ID0gYm91bmRpbmdSZWN0cyh0aGlzKTtcbiAgICBjb25zdCBhZGRSZWN0UGF0aCA9IGhhc1JhZGl1cyhvdXRlci5yYWRpdXMpID8gYWRkUm91bmRlZFJlY3RQYXRoIDogYWRkTm9ybWFsUmVjdFBhdGg7XG5cbiAgICBjdHguc2F2ZSgpO1xuXG4gICAgaWYgKG91dGVyLncgIT09IGlubmVyLncgfHwgb3V0ZXIuaCAhPT0gaW5uZXIuaCkge1xuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgYWRkUmVjdFBhdGgoY3R4LCBpbmZsYXRlUmVjdChvdXRlciwgaW5mbGF0ZUFtb3VudCwgaW5uZXIpKTtcbiAgICAgIGN0eC5jbGlwKCk7XG4gICAgICBhZGRSZWN0UGF0aChjdHgsIGluZmxhdGVSZWN0KGlubmVyLCAtaW5mbGF0ZUFtb3VudCwgb3V0ZXIpKTtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBib3JkZXJDb2xvcjtcbiAgICAgIGN0eC5maWxsKCdldmVub2RkJyk7XG4gICAgfVxuXG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGFkZFJlY3RQYXRoKGN0eCwgaW5mbGF0ZVJlY3QoaW5uZXIsIGluZmxhdGVBbW91bnQpKTtcbiAgICBjdHguZmlsbFN0eWxlID0gYmFja2dyb3VuZENvbG9yO1xuICAgIGN0eC5maWxsKCk7XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICB9XG5cbiAgaW5SYW5nZShtb3VzZVgsIG1vdXNlWSwgdXNlRmluYWxQb3NpdGlvbikge1xuICAgIHJldHVybiBpblJhbmdlKHRoaXMsIG1vdXNlWCwgbW91c2VZLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgfVxuXG4gIGluWFJhbmdlKG1vdXNlWCwgdXNlRmluYWxQb3NpdGlvbikge1xuICAgIHJldHVybiBpblJhbmdlKHRoaXMsIG1vdXNlWCwgbnVsbCwgdXNlRmluYWxQb3NpdGlvbik7XG4gIH1cblxuICBpbllSYW5nZShtb3VzZVksIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICByZXR1cm4gaW5SYW5nZSh0aGlzLCBudWxsLCBtb3VzZVksIHVzZUZpbmFsUG9zaXRpb24pO1xuICB9XG5cbiAgZ2V0Q2VudGVyUG9pbnQodXNlRmluYWxQb3NpdGlvbikge1xuICAgIGNvbnN0IHt4LCB5LCBiYXNlLCBob3Jpem9udGFsfSA9IC8qKiBAdHlwZSB7QmFyUHJvcHN9ICovICh0aGlzLmdldFByb3BzKFsneCcsICd5JywgJ2Jhc2UnLCAnaG9yaXpvbnRhbCddLCB1c2VGaW5hbFBvc2l0aW9uKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IGhvcml6b250YWwgPyAoeCArIGJhc2UpIC8gMiA6IHgsXG4gICAgICB5OiBob3Jpem9udGFsID8geSA6ICh5ICsgYmFzZSkgLyAyXG4gICAgfTtcbiAgfVxuXG4gIGdldFJhbmdlKGF4aXMpIHtcbiAgICByZXR1cm4gYXhpcyA9PT0gJ3gnID8gdGhpcy53aWR0aCAvIDIgOiB0aGlzLmhlaWdodCAvIDI7XG4gIH1cbn1cbiIsICJpbXBvcnQge0RvdWdobnV0Q29udHJvbGxlciwgUG9sYXJBcmVhQ29udHJvbGxlcn0gZnJvbSAnLi4vaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge0NoYXJ0LCBDaGFydERhdGFzZXR9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBDb2xvcnNQbHVnaW5PcHRpb25zIHtcbiAgZW5hYmxlZD86IGJvb2xlYW47XG4gIGZvcmNlT3ZlcnJpZGU/OiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgQ29sb3JzRGVzY3JpcHRvciB7XG4gIGJhY2tncm91bmRDb2xvcj86IHVua25vd247XG4gIGJvcmRlckNvbG9yPzogdW5rbm93bjtcbn1cblxuY29uc3QgQk9SREVSX0NPTE9SUyA9IFtcbiAgJ3JnYig1NCwgMTYyLCAyMzUpJywgLy8gYmx1ZVxuICAncmdiKDI1NSwgOTksIDEzMiknLCAvLyByZWRcbiAgJ3JnYigyNTUsIDE1OSwgNjQpJywgLy8gb3JhbmdlXG4gICdyZ2IoMjU1LCAyMDUsIDg2KScsIC8vIHllbGxvd1xuICAncmdiKDc1LCAxOTIsIDE5MiknLCAvLyBncmVlblxuICAncmdiKDE1MywgMTAyLCAyNTUpJywgLy8gcHVycGxlXG4gICdyZ2IoMjAxLCAyMDMsIDIwNyknIC8vIGdyZXlcbl07XG5cbi8vIEJvcmRlciBjb2xvcnMgd2l0aCA1MCUgdHJhbnNwYXJlbmN5XG5jb25zdCBCQUNLR1JPVU5EX0NPTE9SUyA9IC8qICNfX1BVUkVfXyAqLyBCT1JERVJfQ09MT1JTLm1hcChjb2xvciA9PiBjb2xvci5yZXBsYWNlKCdyZ2IoJywgJ3JnYmEoJykucmVwbGFjZSgnKScsICcsIDAuNSknKSk7XG5cbmZ1bmN0aW9uIGdldEJvcmRlckNvbG9yKGk6IG51bWJlcikge1xuICByZXR1cm4gQk9SREVSX0NPTE9SU1tpICUgQk9SREVSX0NPTE9SUy5sZW5ndGhdO1xufVxuXG5mdW5jdGlvbiBnZXRCYWNrZ3JvdW5kQ29sb3IoaTogbnVtYmVyKSB7XG4gIHJldHVybiBCQUNLR1JPVU5EX0NPTE9SU1tpICUgQkFDS0dST1VORF9DT0xPUlMubGVuZ3RoXTtcbn1cblxuZnVuY3Rpb24gY29sb3JpemVEZWZhdWx0RGF0YXNldChkYXRhc2V0OiBDaGFydERhdGFzZXQsIGk6IG51bWJlcikge1xuICBkYXRhc2V0LmJvcmRlckNvbG9yID0gZ2V0Qm9yZGVyQ29sb3IoaSk7XG4gIGRhdGFzZXQuYmFja2dyb3VuZENvbG9yID0gZ2V0QmFja2dyb3VuZENvbG9yKGkpO1xuXG4gIHJldHVybiArK2k7XG59XG5cbmZ1bmN0aW9uIGNvbG9yaXplRG91Z2hudXREYXRhc2V0KGRhdGFzZXQ6IENoYXJ0RGF0YXNldCwgaTogbnVtYmVyKSB7XG4gIGRhdGFzZXQuYmFja2dyb3VuZENvbG9yID0gZGF0YXNldC5kYXRhLm1hcCgoKSA9PiBnZXRCb3JkZXJDb2xvcihpKyspKTtcblxuICByZXR1cm4gaTtcbn1cblxuZnVuY3Rpb24gY29sb3JpemVQb2xhckFyZWFEYXRhc2V0KGRhdGFzZXQ6IENoYXJ0RGF0YXNldCwgaTogbnVtYmVyKSB7XG4gIGRhdGFzZXQuYmFja2dyb3VuZENvbG9yID0gZGF0YXNldC5kYXRhLm1hcCgoKSA9PiBnZXRCYWNrZ3JvdW5kQ29sb3IoaSsrKSk7XG5cbiAgcmV0dXJuIGk7XG59XG5cbmZ1bmN0aW9uIGdldENvbG9yaXplcihjaGFydDogQ2hhcnQpIHtcbiAgbGV0IGkgPSAwO1xuXG4gIHJldHVybiAoZGF0YXNldDogQ2hhcnREYXRhc2V0LCBkYXRhc2V0SW5kZXg6IG51bWJlcikgPT4ge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBjaGFydC5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpLmNvbnRyb2xsZXI7XG5cbiAgICBpZiAoY29udHJvbGxlciBpbnN0YW5jZW9mIERvdWdobnV0Q29udHJvbGxlcikge1xuICAgICAgaSA9IGNvbG9yaXplRG91Z2hudXREYXRhc2V0KGRhdGFzZXQsIGkpO1xuICAgIH0gZWxzZSBpZiAoY29udHJvbGxlciBpbnN0YW5jZW9mIFBvbGFyQXJlYUNvbnRyb2xsZXIpIHtcbiAgICAgIGkgPSBjb2xvcml6ZVBvbGFyQXJlYURhdGFzZXQoZGF0YXNldCwgaSk7XG4gICAgfSBlbHNlIGlmIChjb250cm9sbGVyKSB7XG4gICAgICBpID0gY29sb3JpemVEZWZhdWx0RGF0YXNldChkYXRhc2V0LCBpKTtcbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zQ29sb3JzRGVmaW5pdGlvbnMoXG4gIGRlc2NyaXB0b3JzOiBDb2xvcnNEZXNjcmlwdG9yW10gfCBSZWNvcmQ8c3RyaW5nLCBDb2xvcnNEZXNjcmlwdG9yPlxuKSB7XG4gIGxldCBrOiBudW1iZXIgfCBzdHJpbmc7XG5cbiAgZm9yIChrIGluIGRlc2NyaXB0b3JzKSB7XG4gICAgaWYgKGRlc2NyaXB0b3JzW2tdLmJvcmRlckNvbG9yIHx8IGRlc2NyaXB0b3JzW2tdLmJhY2tncm91bmRDb2xvcikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjb250YWluc0NvbG9yc0RlZmluaXRpb24oXG4gIGRlc2NyaXB0b3I6IENvbG9yc0Rlc2NyaXB0b3Jcbikge1xuICByZXR1cm4gZGVzY3JpcHRvciAmJiAoZGVzY3JpcHRvci5ib3JkZXJDb2xvciB8fCBkZXNjcmlwdG9yLmJhY2tncm91bmRDb2xvcik7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgaWQ6ICdjb2xvcnMnLFxuXG4gIGRlZmF1bHRzOiB7XG4gICAgZW5hYmxlZDogdHJ1ZSxcbiAgICBmb3JjZU92ZXJyaWRlOiBmYWxzZVxuICB9IGFzIENvbG9yc1BsdWdpbk9wdGlvbnMsXG5cbiAgYmVmb3JlTGF5b3V0KGNoYXJ0OiBDaGFydCwgX2FyZ3MsIG9wdGlvbnM6IENvbG9yc1BsdWdpbk9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMuZW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHtcbiAgICAgIGRhdGE6IHtkYXRhc2V0c30sXG4gICAgICBvcHRpb25zOiBjaGFydE9wdGlvbnNcbiAgICB9ID0gY2hhcnQuY29uZmlnO1xuICAgIGNvbnN0IHtlbGVtZW50c30gPSBjaGFydE9wdGlvbnM7XG5cbiAgICBpZiAoIW9wdGlvbnMuZm9yY2VPdmVycmlkZSAmJiAoY29udGFpbnNDb2xvcnNEZWZpbml0aW9ucyhkYXRhc2V0cykgfHwgY29udGFpbnNDb2xvcnNEZWZpbml0aW9uKGNoYXJ0T3B0aW9ucykgfHwgKGVsZW1lbnRzICYmIGNvbnRhaW5zQ29sb3JzRGVmaW5pdGlvbnMoZWxlbWVudHMpKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb2xvcml6ZXIgPSBnZXRDb2xvcml6ZXIoY2hhcnQpO1xuXG4gICAgZGF0YXNldHMuZm9yRWFjaChjb2xvcml6ZXIpO1xuICB9XG59O1xuIiwgImltcG9ydCB7X2xpbWl0VmFsdWUsIF9sb29rdXBCeUtleSwgaXNOdWxsT3JVbmRlZiwgcmVzb2x2ZX0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5cbmZ1bmN0aW9uIGx0dGJEZWNpbWF0aW9uKGRhdGEsIHN0YXJ0LCBjb3VudCwgYXZhaWxhYmxlV2lkdGgsIG9wdGlvbnMpIHtcbiAgLyoqXG4gICAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBMYXJnZXN0IFRyaWFuZ2xlIFRocmVlIEJ1Y2tldHMgYWxnb3JpdGhtLlxuICAgKlxuICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGJhc2VkIG9uIHRoZSBvcmlnaW5hbCBpbXBsZW1lbnRhdGlvbiBieSBTdmVpbm4gU3RlaW5hcnNzb25cbiAgICogaW4gaHR0cHM6Ly9naXRodWIuY29tL3N2ZWlubi1zdGVpbmFyc3Nvbi9mbG90LWRvd25zYW1wbGUvYmxvYi9tYXN0ZXIvanF1ZXJ5LmZsb3QuZG93bnNhbXBsZS5qc1xuICAgKlxuICAgKiBUaGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24gaXMgTUlUIGxpY2Vuc2VkLlxuICAgKi9cbiAgY29uc3Qgc2FtcGxlcyA9IG9wdGlvbnMuc2FtcGxlcyB8fCBhdmFpbGFibGVXaWR0aDtcbiAgLy8gVGhlcmUgYXJlIGxlc3MgcG9pbnRzIHRoYW4gdGhlIHRocmVzaG9sZCwgcmV0dXJuaW5nIHRoZSB3aG9sZSBhcnJheVxuICBpZiAoc2FtcGxlcyA+PSBjb3VudCkge1xuICAgIHJldHVybiBkYXRhLnNsaWNlKHN0YXJ0LCBzdGFydCArIGNvdW50KTtcbiAgfVxuXG4gIGNvbnN0IGRlY2ltYXRlZCA9IFtdO1xuXG4gIGNvbnN0IGJ1Y2tldFdpZHRoID0gKGNvdW50IC0gMikgLyAoc2FtcGxlcyAtIDIpO1xuICBsZXQgc2FtcGxlZEluZGV4ID0gMDtcbiAgY29uc3QgZW5kSW5kZXggPSBzdGFydCArIGNvdW50IC0gMTtcbiAgLy8gU3RhcnRpbmcgZnJvbSBvZmZzZXRcbiAgbGV0IGEgPSBzdGFydDtcbiAgbGV0IGksIG1heEFyZWFQb2ludCwgbWF4QXJlYSwgYXJlYSwgbmV4dEE7XG5cbiAgZGVjaW1hdGVkW3NhbXBsZWRJbmRleCsrXSA9IGRhdGFbYV07XG5cbiAgZm9yIChpID0gMDsgaSA8IHNhbXBsZXMgLSAyOyBpKyspIHtcbiAgICBsZXQgYXZnWCA9IDA7XG4gICAgbGV0IGF2Z1kgPSAwO1xuICAgIGxldCBqO1xuXG4gICAgLy8gQWRkaW5nIG9mZnNldFxuICAgIGNvbnN0IGF2Z1JhbmdlU3RhcnQgPSBNYXRoLmZsb29yKChpICsgMSkgKiBidWNrZXRXaWR0aCkgKyAxICsgc3RhcnQ7XG4gICAgY29uc3QgYXZnUmFuZ2VFbmQgPSBNYXRoLm1pbihNYXRoLmZsb29yKChpICsgMikgKiBidWNrZXRXaWR0aCkgKyAxLCBjb3VudCkgKyBzdGFydDtcbiAgICBjb25zdCBhdmdSYW5nZUxlbmd0aCA9IGF2Z1JhbmdlRW5kIC0gYXZnUmFuZ2VTdGFydDtcblxuICAgIGZvciAoaiA9IGF2Z1JhbmdlU3RhcnQ7IGogPCBhdmdSYW5nZUVuZDsgaisrKSB7XG4gICAgICBhdmdYICs9IGRhdGFbal0ueDtcbiAgICAgIGF2Z1kgKz0gZGF0YVtqXS55O1xuICAgIH1cblxuICAgIGF2Z1ggLz0gYXZnUmFuZ2VMZW5ndGg7XG4gICAgYXZnWSAvPSBhdmdSYW5nZUxlbmd0aDtcblxuICAgIC8vIEFkZGluZyBvZmZzZXRcbiAgICBjb25zdCByYW5nZU9mZnMgPSBNYXRoLmZsb29yKGkgKiBidWNrZXRXaWR0aCkgKyAxICsgc3RhcnQ7XG4gICAgY29uc3QgcmFuZ2VUbyA9IE1hdGgubWluKE1hdGguZmxvb3IoKGkgKyAxKSAqIGJ1Y2tldFdpZHRoKSArIDEsIGNvdW50KSArIHN0YXJ0O1xuICAgIGNvbnN0IHt4OiBwb2ludEF4LCB5OiBwb2ludEF5fSA9IGRhdGFbYV07XG5cbiAgICAvLyBOb3RlIHRoYXQgdGhpcyBpcyBjaGFuZ2VkIGZyb20gdGhlIG9yaWdpbmFsIGFsZ29yaXRobSB3aGljaCBpbml0aWFsaXplcyB0aGVzZVxuICAgIC8vIHZhbHVlcyB0byAxLiBUaGUgcmVhc29uIGZvciB0aGlzIGNoYW5nZSBpcyB0aGF0IGlmIHRoZSBhcmVhIGlzIHNtYWxsLCBuZXh0QVxuICAgIC8vIHdvdWxkIG5ldmVyIGJlIHNldCBhbmQgdGh1cyBhIGNyYXNoIHdvdWxkIG9jY3VyIGluIHRoZSBuZXh0IGxvb3AgYXMgYGFgIHdvdWxkIGJlY29tZVxuICAgIC8vIGB1bmRlZmluZWRgLiBTaW5jZSB0aGUgYXJlYSBpcyBhbHdheXMgcG9zaXRpdmUsIGJ1dCBjb3VsZCBiZSAwIGluIHRoZSBjYXNlIG9mIGEgZmxhdCB0cmFjZSxcbiAgICAvLyBpbml0aWFsaXppbmcgd2l0aCBhIG5lZ2F0aXZlIG51bWJlciBpcyB0aGUgY29ycmVjdCBzb2x1dGlvbi5cbiAgICBtYXhBcmVhID0gYXJlYSA9IC0xO1xuXG4gICAgZm9yIChqID0gcmFuZ2VPZmZzOyBqIDwgcmFuZ2VUbzsgaisrKSB7XG4gICAgICBhcmVhID0gMC41ICogTWF0aC5hYnMoXG4gICAgICAgIChwb2ludEF4IC0gYXZnWCkgKiAoZGF0YVtqXS55IC0gcG9pbnRBeSkgLVxuICAgICAgICAocG9pbnRBeCAtIGRhdGFbal0ueCkgKiAoYXZnWSAtIHBvaW50QXkpXG4gICAgICApO1xuXG4gICAgICBpZiAoYXJlYSA+IG1heEFyZWEpIHtcbiAgICAgICAgbWF4QXJlYSA9IGFyZWE7XG4gICAgICAgIG1heEFyZWFQb2ludCA9IGRhdGFbal07XG4gICAgICAgIG5leHRBID0gajtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBkZWNpbWF0ZWRbc2FtcGxlZEluZGV4KytdID0gbWF4QXJlYVBvaW50O1xuICAgIGEgPSBuZXh0QTtcbiAgfVxuXG4gIC8vIEluY2x1ZGUgdGhlIGxhc3QgcG9pbnRcbiAgZGVjaW1hdGVkW3NhbXBsZWRJbmRleCsrXSA9IGRhdGFbZW5kSW5kZXhdO1xuXG4gIHJldHVybiBkZWNpbWF0ZWQ7XG59XG5cbmZ1bmN0aW9uIG1pbk1heERlY2ltYXRpb24oZGF0YSwgc3RhcnQsIGNvdW50LCBhdmFpbGFibGVXaWR0aCkge1xuICBsZXQgYXZnWCA9IDA7XG4gIGxldCBjb3VudFggPSAwO1xuICBsZXQgaSwgcG9pbnQsIHgsIHksIHByZXZYLCBtaW5JbmRleCwgbWF4SW5kZXgsIHN0YXJ0SW5kZXgsIG1pblksIG1heFk7XG4gIGNvbnN0IGRlY2ltYXRlZCA9IFtdO1xuICBjb25zdCBlbmRJbmRleCA9IHN0YXJ0ICsgY291bnQgLSAxO1xuXG4gIGNvbnN0IHhNaW4gPSBkYXRhW3N0YXJ0XS54O1xuICBjb25zdCB4TWF4ID0gZGF0YVtlbmRJbmRleF0ueDtcbiAgY29uc3QgZHggPSB4TWF4IC0geE1pbjtcblxuICBmb3IgKGkgPSBzdGFydDsgaSA8IHN0YXJ0ICsgY291bnQ7ICsraSkge1xuICAgIHBvaW50ID0gZGF0YVtpXTtcbiAgICB4ID0gKHBvaW50LnggLSB4TWluKSAvIGR4ICogYXZhaWxhYmxlV2lkdGg7XG4gICAgeSA9IHBvaW50Lnk7XG4gICAgY29uc3QgdHJ1bmNYID0geCB8IDA7XG5cbiAgICBpZiAodHJ1bmNYID09PSBwcmV2WCkge1xuICAgICAgLy8gRGV0ZXJtaW5lIGBtaW5ZYCAvIGBtYXhZYCBhbmQgYGF2Z1hgIHdoaWxlIHdlIHN0YXkgd2l0aGluIHNhbWUgeC1wb3NpdGlvblxuICAgICAgaWYgKHkgPCBtaW5ZKSB7XG4gICAgICAgIG1pblkgPSB5O1xuICAgICAgICBtaW5JbmRleCA9IGk7XG4gICAgICB9IGVsc2UgaWYgKHkgPiBtYXhZKSB7XG4gICAgICAgIG1heFkgPSB5O1xuICAgICAgICBtYXhJbmRleCA9IGk7XG4gICAgICB9XG4gICAgICAvLyBGb3IgZmlyc3QgcG9pbnQgaW4gZ3JvdXAsIGNvdW50WCBpcyBgMGAsIHNvIGF2ZXJhZ2Ugd2lsbCBiZSBgeGAgLyAxLlxuICAgICAgLy8gVXNlIHBvaW50LnggaGVyZSBiZWNhdXNlIHdlJ3JlIGNvbXB1dGluZyB0aGUgYXZlcmFnZSBkYXRhIGB4YCB2YWx1ZVxuICAgICAgYXZnWCA9IChjb3VudFggKiBhdmdYICsgcG9pbnQueCkgLyArK2NvdW50WDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUHVzaCB1cCB0byA0IHBvaW50cywgMyBmb3IgdGhlIGxhc3QgaW50ZXJ2YWwgYW5kIHRoZSBmaXJzdCBwb2ludCBmb3IgdGhpcyBpbnRlcnZhbFxuICAgICAgY29uc3QgbGFzdEluZGV4ID0gaSAtIDE7XG5cbiAgICAgIGlmICghaXNOdWxsT3JVbmRlZihtaW5JbmRleCkgJiYgIWlzTnVsbE9yVW5kZWYobWF4SW5kZXgpKSB7XG4gICAgICAgIC8vIFRoZSBpbnRlcnZhbCBpcyBkZWZpbmVkIGJ5IDQgcG9pbnRzOiBzdGFydCwgbWluLCBtYXgsIGVuZC5cbiAgICAgICAgLy8gVGhlIHN0YXJ0aW5nIHBvaW50IGlzIGFscmVhZHkgY29uc2lkZXJlZCBhdCB0aGlzIHBvaW50LCBzbyB3ZSBuZWVkIHRvIGRldGVybWluZSB3aGljaFxuICAgICAgICAvLyBvZiB0aGUgb3RoZXIgcG9pbnRzIHRvIGFkZC4gV2UgbmVlZCB0byBzb3J0IHRoZXNlIHBvaW50cyB0byBlbnN1cmUgdGhlIGRlY2ltYXRlZCBkYXRhXG4gICAgICAgIC8vIGlzIHN0aWxsIHNvcnRlZCBhbmQgdGhlbiBlbnN1cmUgdGhlcmUgYXJlIG5vIGR1cGxpY2F0ZXMuXG4gICAgICAgIGNvbnN0IGludGVybWVkaWF0ZUluZGV4MSA9IE1hdGgubWluKG1pbkluZGV4LCBtYXhJbmRleCk7XG4gICAgICAgIGNvbnN0IGludGVybWVkaWF0ZUluZGV4MiA9IE1hdGgubWF4KG1pbkluZGV4LCBtYXhJbmRleCk7XG5cbiAgICAgICAgaWYgKGludGVybWVkaWF0ZUluZGV4MSAhPT0gc3RhcnRJbmRleCAmJiBpbnRlcm1lZGlhdGVJbmRleDEgIT09IGxhc3RJbmRleCkge1xuICAgICAgICAgIGRlY2ltYXRlZC5wdXNoKHtcbiAgICAgICAgICAgIC4uLmRhdGFbaW50ZXJtZWRpYXRlSW5kZXgxXSxcbiAgICAgICAgICAgIHg6IGF2Z1gsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGludGVybWVkaWF0ZUluZGV4MiAhPT0gc3RhcnRJbmRleCAmJiBpbnRlcm1lZGlhdGVJbmRleDIgIT09IGxhc3RJbmRleCkge1xuICAgICAgICAgIGRlY2ltYXRlZC5wdXNoKHtcbiAgICAgICAgICAgIC4uLmRhdGFbaW50ZXJtZWRpYXRlSW5kZXgyXSxcbiAgICAgICAgICAgIHg6IGF2Z1hcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBsYXN0SW5kZXggPT09IHN0YXJ0SW5kZXggd2lsbCBvY2N1ciB3aGVuIGEgcmFuZ2UgaGFzIG9ubHkgMSBwb2ludCB3aGljaCBjb3VsZFxuICAgICAgLy8gaGFwcGVuIHdpdGggdmVyeSB1bmV2ZW4gZGF0YVxuICAgICAgaWYgKGkgPiAwICYmIGxhc3RJbmRleCAhPT0gc3RhcnRJbmRleCkge1xuICAgICAgICAvLyBMYXN0IHBvaW50IGluIHRoZSBwcmV2aW91cyBpbnRlcnZhbFxuICAgICAgICBkZWNpbWF0ZWQucHVzaChkYXRhW2xhc3RJbmRleF0pO1xuICAgICAgfVxuXG4gICAgICAvLyBTdGFydCBvZiB0aGUgbmV3IGludGVydmFsXG4gICAgICBkZWNpbWF0ZWQucHVzaChwb2ludCk7XG4gICAgICBwcmV2WCA9IHRydW5jWDtcbiAgICAgIGNvdW50WCA9IDA7XG4gICAgICBtaW5ZID0gbWF4WSA9IHk7XG4gICAgICBtaW5JbmRleCA9IG1heEluZGV4ID0gc3RhcnRJbmRleCA9IGk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRlY2ltYXRlZDtcbn1cblxuZnVuY3Rpb24gY2xlYW5EZWNpbWF0ZWREYXRhc2V0KGRhdGFzZXQpIHtcbiAgaWYgKGRhdGFzZXQuX2RlY2ltYXRlZCkge1xuICAgIGNvbnN0IGRhdGEgPSBkYXRhc2V0Ll9kYXRhO1xuICAgIGRlbGV0ZSBkYXRhc2V0Ll9kZWNpbWF0ZWQ7XG4gICAgZGVsZXRlIGRhdGFzZXQuX2RhdGE7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGRhdGFzZXQsICdkYXRhJywge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IGRhdGEsXG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2xlYW5EZWNpbWF0ZWREYXRhKGNoYXJ0KSB7XG4gIGNoYXJ0LmRhdGEuZGF0YXNldHMuZm9yRWFjaCgoZGF0YXNldCkgPT4ge1xuICAgIGNsZWFuRGVjaW1hdGVkRGF0YXNldChkYXRhc2V0KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHNTaW1wbGlmaWVkKG1ldGEsIHBvaW50cykge1xuICBjb25zdCBwb2ludENvdW50ID0gcG9pbnRzLmxlbmd0aDtcblxuICBsZXQgc3RhcnQgPSAwO1xuICBsZXQgY291bnQ7XG5cbiAgY29uc3Qge2lTY2FsZX0gPSBtZXRhO1xuICBjb25zdCB7bWluLCBtYXgsIG1pbkRlZmluZWQsIG1heERlZmluZWR9ID0gaVNjYWxlLmdldFVzZXJCb3VuZHMoKTtcblxuICBpZiAobWluRGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gX2xpbWl0VmFsdWUoX2xvb2t1cEJ5S2V5KHBvaW50cywgaVNjYWxlLmF4aXMsIG1pbikubG8sIDAsIHBvaW50Q291bnQgLSAxKTtcbiAgfVxuICBpZiAobWF4RGVmaW5lZCkge1xuICAgIGNvdW50ID0gX2xpbWl0VmFsdWUoX2xvb2t1cEJ5S2V5KHBvaW50cywgaVNjYWxlLmF4aXMsIG1heCkuaGkgKyAxLCBzdGFydCwgcG9pbnRDb3VudCkgLSBzdGFydDtcbiAgfSBlbHNlIHtcbiAgICBjb3VudCA9IHBvaW50Q291bnQgLSBzdGFydDtcbiAgfVxuXG4gIHJldHVybiB7c3RhcnQsIGNvdW50fTtcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICBpZDogJ2RlY2ltYXRpb24nLFxuXG4gIGRlZmF1bHRzOiB7XG4gICAgYWxnb3JpdGhtOiAnbWluLW1heCcsXG4gICAgZW5hYmxlZDogZmFsc2UsXG4gIH0sXG5cbiAgYmVmb3JlRWxlbWVudHNVcGRhdGU6IChjaGFydCwgYXJncywgb3B0aW9ucykgPT4ge1xuICAgIGlmICghb3B0aW9ucy5lbmFibGVkKSB7XG4gICAgICAvLyBUaGUgZGVjaW1hdGlvbiBwbHVnaW4gbWF5IGhhdmUgYmVlbiBwcmV2aW91c2x5IGVuYWJsZWQuIE5lZWQgdG8gcmVtb3ZlIG9sZCBgZGF0YXNldC5fZGF0YWAgaGFuZGxlcnNcbiAgICAgIGNsZWFuRGVjaW1hdGVkRGF0YShjaGFydCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQXNzdW1lIHRoZSBlbnRpcmUgY2hhcnQgaXMgYXZhaWxhYmxlIHRvIHNob3cgYSBmZXcgbW9yZSBwb2ludHMgdGhhbiBuZWVkZWRcbiAgICBjb25zdCBhdmFpbGFibGVXaWR0aCA9IGNoYXJ0LndpZHRoO1xuXG4gICAgY2hhcnQuZGF0YS5kYXRhc2V0cy5mb3JFYWNoKChkYXRhc2V0LCBkYXRhc2V0SW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHtfZGF0YSwgaW5kZXhBeGlzfSA9IGRhdGFzZXQ7XG4gICAgICBjb25zdCBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcbiAgICAgIGNvbnN0IGRhdGEgPSBfZGF0YSB8fCBkYXRhc2V0LmRhdGE7XG5cbiAgICAgIGlmIChyZXNvbHZlKFtpbmRleEF4aXMsIGNoYXJ0Lm9wdGlvbnMuaW5kZXhBeGlzXSkgPT09ICd5Jykge1xuICAgICAgICAvLyBEZWNpbWF0aW9uIGlzIG9ubHkgc3VwcG9ydGVkIGZvciBsaW5lcyB0aGF0IGhhdmUgYW4gWCBpbmRleEF4aXNcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoIW1ldGEuY29udHJvbGxlci5zdXBwb3J0c0RlY2ltYXRpb24pIHtcbiAgICAgICAgLy8gT25seSBsaW5lIGRhdGFzZXRzIGFyZSBzdXBwb3J0ZWRcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB4QXhpcyA9IGNoYXJ0LnNjYWxlc1ttZXRhLnhBeGlzSURdO1xuICAgICAgaWYgKHhBeGlzLnR5cGUgIT09ICdsaW5lYXInICYmIHhBeGlzLnR5cGUgIT09ICd0aW1lJykge1xuICAgICAgICAvLyBPbmx5IGxpbmVhciBpbnRlcnBvbGF0aW9uIGlzIHN1cHBvcnRlZFxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFydC5vcHRpb25zLnBhcnNpbmcpIHtcbiAgICAgICAgLy8gUGx1Z2luIG9ubHkgc3VwcG9ydHMgZGF0YSB0aGF0IGRvZXMgbm90IG5lZWQgcGFyc2luZ1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCB7c3RhcnQsIGNvdW50fSA9IGdldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHNTaW1wbGlmaWVkKG1ldGEsIGRhdGEpO1xuICAgICAgY29uc3QgdGhyZXNob2xkID0gb3B0aW9ucy50aHJlc2hvbGQgfHwgNCAqIGF2YWlsYWJsZVdpZHRoO1xuICAgICAgaWYgKGNvdW50IDw9IHRocmVzaG9sZCkge1xuICAgICAgICAvLyBObyBkZWNpbWF0aW9uIGlzIHJlcXVpcmVkIHVudGlsIHdlIGFyZSBhYm92ZSB0aGlzIHRocmVzaG9sZFxuICAgICAgICBjbGVhbkRlY2ltYXRlZERhdGFzZXQoZGF0YXNldCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTnVsbE9yVW5kZWYoX2RhdGEpKSB7XG4gICAgICAgIC8vIEZpcnN0IHRpbWUgd2UgYXJlIHNlZWluZyB0aGlzIGRhdGFzZXRcbiAgICAgICAgLy8gV2Ugb3ZlcnJpZGUgdGhlICdkYXRhJyBwcm9wZXJ0eSB3aXRoIGEgc2V0dGVyIHRoYXQgc3RvcmVzIHRoZVxuICAgICAgICAvLyByYXcgZGF0YSBpbiBfZGF0YSwgYnV0IHJlYWRzIHRoZSBkZWNpbWF0ZWQgZGF0YSBmcm9tIF9kZWNpbWF0ZWRcbiAgICAgICAgZGF0YXNldC5fZGF0YSA9IGRhdGE7XG4gICAgICAgIGRlbGV0ZSBkYXRhc2V0LmRhdGE7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkYXRhc2V0LCAnZGF0YScsIHtcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlY2ltYXRlZDtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNldDogZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgdGhpcy5fZGF0YSA9IGQ7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gUG9pbnQgdGhlIGNoYXJ0IHRvIHRoZSBkZWNpbWF0ZWQgZGF0YVxuICAgICAgbGV0IGRlY2ltYXRlZDtcbiAgICAgIHN3aXRjaCAob3B0aW9ucy5hbGdvcml0aG0pIHtcbiAgICAgIGNhc2UgJ2x0dGInOlxuICAgICAgICBkZWNpbWF0ZWQgPSBsdHRiRGVjaW1hdGlvbihkYXRhLCBzdGFydCwgY291bnQsIGF2YWlsYWJsZVdpZHRoLCBvcHRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtaW4tbWF4JzpcbiAgICAgICAgZGVjaW1hdGVkID0gbWluTWF4RGVjaW1hdGlvbihkYXRhLCBzdGFydCwgY291bnQsIGF2YWlsYWJsZVdpZHRoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGRlY2ltYXRpb24gYWxnb3JpdGhtICcke29wdGlvbnMuYWxnb3JpdGhtfSdgKTtcbiAgICAgIH1cblxuICAgICAgZGF0YXNldC5fZGVjaW1hdGVkID0gZGVjaW1hdGVkO1xuICAgIH0pO1xuICB9LFxuXG4gIGRlc3Ryb3koY2hhcnQpIHtcbiAgICBjbGVhbkRlY2ltYXRlZERhdGEoY2hhcnQpO1xuICB9XG59O1xuIiwgImltcG9ydCB7X2JvdW5kU2VnbWVudCwgX2JvdW5kU2VnbWVudHMsIF9ub3JtYWxpemVBbmdsZX0gZnJvbSAnLi4vLi4vaGVscGVycy9pbmRleC5qcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBfc2VnbWVudHMobGluZSwgdGFyZ2V0LCBwcm9wZXJ0eSkge1xuICBjb25zdCBzZWdtZW50cyA9IGxpbmUuc2VnbWVudHM7XG4gIGNvbnN0IHBvaW50cyA9IGxpbmUucG9pbnRzO1xuICBjb25zdCB0cG9pbnRzID0gdGFyZ2V0LnBvaW50cztcbiAgY29uc3QgcGFydHMgPSBbXTtcblxuICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpIHtcbiAgICBsZXQge3N0YXJ0LCBlbmR9ID0gc2VnbWVudDtcbiAgICBlbmQgPSBfZmluZFNlZ21lbnRFbmQoc3RhcnQsIGVuZCwgcG9pbnRzKTtcblxuICAgIGNvbnN0IGJvdW5kcyA9IF9nZXRCb3VuZHMocHJvcGVydHksIHBvaW50c1tzdGFydF0sIHBvaW50c1tlbmRdLCBzZWdtZW50Lmxvb3ApO1xuXG4gICAgaWYgKCF0YXJnZXQuc2VnbWVudHMpIHtcbiAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgYm91bmRhcnkgbm90IHN1cHBvcnRpbmcgYHNlZ21lbnRzYCAoc2ltcGxlQXJjKVxuICAgICAgLy8gQm91bmRzIGFyZSBwcm92aWRlZCBhcyBgdGFyZ2V0YCBmb3IgcGFydGlhbCBjaXJjbGUsIG9yIHVuZGVmaW5lZCBmb3IgZnVsbCBjaXJjbGVcbiAgICAgIHBhcnRzLnB1c2goe1xuICAgICAgICBzb3VyY2U6IHNlZ21lbnQsXG4gICAgICAgIHRhcmdldDogYm91bmRzLFxuICAgICAgICBzdGFydDogcG9pbnRzW3N0YXJ0XSxcbiAgICAgICAgZW5kOiBwb2ludHNbZW5kXVxuICAgICAgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBHZXQgYWxsIHNlZ21lbnRzIGZyb20gYHRhcmdldGAgdGhhdCBpbnRlcnNlY3QgdGhlIGJvdW5kcyBvZiBjdXJyZW50IHNlZ21lbnQgb2YgYGxpbmVgXG4gICAgY29uc3QgdGFyZ2V0U2VnbWVudHMgPSBfYm91bmRTZWdtZW50cyh0YXJnZXQsIGJvdW5kcyk7XG5cbiAgICBmb3IgKGNvbnN0IHRndCBvZiB0YXJnZXRTZWdtZW50cykge1xuICAgICAgY29uc3Qgc3ViQm91bmRzID0gX2dldEJvdW5kcyhwcm9wZXJ0eSwgdHBvaW50c1t0Z3Quc3RhcnRdLCB0cG9pbnRzW3RndC5lbmRdLCB0Z3QubG9vcCk7XG4gICAgICBjb25zdCBmaWxsU291cmNlcyA9IF9ib3VuZFNlZ21lbnQoc2VnbWVudCwgcG9pbnRzLCBzdWJCb3VuZHMpO1xuXG4gICAgICBmb3IgKGNvbnN0IGZpbGxTb3VyY2Ugb2YgZmlsbFNvdXJjZXMpIHtcbiAgICAgICAgcGFydHMucHVzaCh7XG4gICAgICAgICAgc291cmNlOiBmaWxsU291cmNlLFxuICAgICAgICAgIHRhcmdldDogdGd0LFxuICAgICAgICAgIHN0YXJ0OiB7XG4gICAgICAgICAgICBbcHJvcGVydHldOiBfZ2V0RWRnZShib3VuZHMsIHN1YkJvdW5kcywgJ3N0YXJ0JywgTWF0aC5tYXgpXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbmQ6IHtcbiAgICAgICAgICAgIFtwcm9wZXJ0eV06IF9nZXRFZGdlKGJvdW5kcywgc3ViQm91bmRzLCAnZW5kJywgTWF0aC5taW4pXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHBhcnRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX2dldEJvdW5kcyhwcm9wZXJ0eSwgZmlyc3QsIGxhc3QsIGxvb3ApIHtcbiAgaWYgKGxvb3ApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IHN0YXJ0ID0gZmlyc3RbcHJvcGVydHldO1xuICBsZXQgZW5kID0gbGFzdFtwcm9wZXJ0eV07XG5cbiAgaWYgKHByb3BlcnR5ID09PSAnYW5nbGUnKSB7XG4gICAgc3RhcnQgPSBfbm9ybWFsaXplQW5nbGUoc3RhcnQpO1xuICAgIGVuZCA9IF9ub3JtYWxpemVBbmdsZShlbmQpO1xuICB9XG4gIHJldHVybiB7cHJvcGVydHksIHN0YXJ0LCBlbmR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX3BvaW50c0Zyb21TZWdtZW50cyhib3VuZGFyeSwgbGluZSkge1xuICBjb25zdCB7eCA9IG51bGwsIHkgPSBudWxsfSA9IGJvdW5kYXJ5IHx8IHt9O1xuICBjb25zdCBsaW5lUG9pbnRzID0gbGluZS5wb2ludHM7XG4gIGNvbnN0IHBvaW50cyA9IFtdO1xuICBsaW5lLnNlZ21lbnRzLmZvckVhY2goKHtzdGFydCwgZW5kfSkgPT4ge1xuICAgIGVuZCA9IF9maW5kU2VnbWVudEVuZChzdGFydCwgZW5kLCBsaW5lUG9pbnRzKTtcbiAgICBjb25zdCBmaXJzdCA9IGxpbmVQb2ludHNbc3RhcnRdO1xuICAgIGNvbnN0IGxhc3QgPSBsaW5lUG9pbnRzW2VuZF07XG4gICAgaWYgKHkgIT09IG51bGwpIHtcbiAgICAgIHBvaW50cy5wdXNoKHt4OiBmaXJzdC54LCB5fSk7XG4gICAgICBwb2ludHMucHVzaCh7eDogbGFzdC54LCB5fSk7XG4gICAgfSBlbHNlIGlmICh4ICE9PSBudWxsKSB7XG4gICAgICBwb2ludHMucHVzaCh7eCwgeTogZmlyc3QueX0pO1xuICAgICAgcG9pbnRzLnB1c2goe3gsIHk6IGxhc3QueX0pO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBwb2ludHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfZmluZFNlZ21lbnRFbmQoc3RhcnQsIGVuZCwgcG9pbnRzKSB7XG4gIGZvciAoO2VuZCA+IHN0YXJ0OyBlbmQtLSkge1xuICAgIGNvbnN0IHBvaW50ID0gcG9pbnRzW2VuZF07XG4gICAgaWYgKCFpc05hTihwb2ludC54KSAmJiAhaXNOYU4ocG9pbnQueSkpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZW5kO1xufVxuXG5mdW5jdGlvbiBfZ2V0RWRnZShhLCBiLCBwcm9wLCBmbikge1xuICBpZiAoYSAmJiBiKSB7XG4gICAgcmV0dXJuIGZuKGFbcHJvcF0sIGJbcHJvcF0pO1xuICB9XG4gIHJldHVybiBhID8gYVtwcm9wXSA6IGIgPyBiW3Byb3BdIDogMDtcbn1cbiIsICIvKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi9jb3JlL2NvcmUuY29udHJvbGxlci5qcycpLmRlZmF1bHQgfSBDaGFydFxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uLy4uL2NvcmUvY29yZS5zY2FsZS5qcycpLmRlZmF1bHQgfSBTY2FsZVxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uLy4uL2VsZW1lbnRzL2VsZW1lbnQucG9pbnQuanMnKS5kZWZhdWx0IH0gUG9pbnRFbGVtZW50XG4gKi9cblxuaW1wb3J0IHtMaW5lRWxlbWVudH0gZnJvbSAnLi4vLi4vZWxlbWVudHMvaW5kZXguanMnO1xuaW1wb3J0IHtpc0FycmF5fSBmcm9tICcuLi8uLi9oZWxwZXJzL2luZGV4LmpzJztcbmltcG9ydCB7X3BvaW50c0Zyb21TZWdtZW50c30gZnJvbSAnLi9maWxsZXIuc2VnbWVudC5qcyc7XG5cbi8qKlxuICogQHBhcmFtIHtQb2ludEVsZW1lbnRbXSB8IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IH19IGJvdW5kYXJ5XG4gKiBAcGFyYW0ge0xpbmVFbGVtZW50fSBsaW5lXG4gKiBAcmV0dXJuIHtMaW5lRWxlbWVudD99XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfY3JlYXRlQm91bmRhcnlMaW5lKGJvdW5kYXJ5LCBsaW5lKSB7XG4gIGxldCBwb2ludHMgPSBbXTtcbiAgbGV0IF9sb29wID0gZmFsc2U7XG5cbiAgaWYgKGlzQXJyYXkoYm91bmRhcnkpKSB7XG4gICAgX2xvb3AgPSB0cnVlO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBwb2ludHMgPSBib3VuZGFyeTtcbiAgfSBlbHNlIHtcbiAgICBwb2ludHMgPSBfcG9pbnRzRnJvbVNlZ21lbnRzKGJvdW5kYXJ5LCBsaW5lKTtcbiAgfVxuXG4gIHJldHVybiBwb2ludHMubGVuZ3RoID8gbmV3IExpbmVFbGVtZW50KHtcbiAgICBwb2ludHMsXG4gICAgb3B0aW9uczoge3RlbnNpb246IDB9LFxuICAgIF9sb29wLFxuICAgIF9mdWxsTG9vcDogX2xvb3BcbiAgfSkgOiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX3Nob3VsZEFwcGx5RmlsbChzb3VyY2UpIHtcbiAgcmV0dXJuIHNvdXJjZSAmJiBzb3VyY2UuZmlsbCAhPT0gZmFsc2U7XG59XG4iLCAiaW1wb3J0IHtpc09iamVjdCwgaXNGaW5pdGUsIHZhbHVlT3JEZWZhdWx0fSBmcm9tICcuLi8uLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uLy4uL2NvcmUvY29yZS5zY2FsZS5qcycpLmRlZmF1bHQgfSBTY2FsZVxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uLy4uL2VsZW1lbnRzL2VsZW1lbnQubGluZS5qcycpLmRlZmF1bHQgfSBMaW5lRWxlbWVudFxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uLy4uL3R5cGVzL2luZGV4LmpzJykuRmlsbFRhcmdldCB9IEZpbGxUYXJnZXRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi90eXBlcy9pbmRleC5qcycpLkNvbXBsZXhGaWxsVGFyZ2V0IH0gQ29tcGxleEZpbGxUYXJnZXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gX3Jlc29sdmVUYXJnZXQoc291cmNlcywgaW5kZXgsIHByb3BhZ2F0ZSkge1xuICBjb25zdCBzb3VyY2UgPSBzb3VyY2VzW2luZGV4XTtcbiAgbGV0IGZpbGwgPSBzb3VyY2UuZmlsbDtcbiAgY29uc3QgdmlzaXRlZCA9IFtpbmRleF07XG4gIGxldCB0YXJnZXQ7XG5cbiAgaWYgKCFwcm9wYWdhdGUpIHtcbiAgICByZXR1cm4gZmlsbDtcbiAgfVxuXG4gIHdoaWxlIChmaWxsICE9PSBmYWxzZSAmJiB2aXNpdGVkLmluZGV4T2YoZmlsbCkgPT09IC0xKSB7XG4gICAgaWYgKCFpc0Zpbml0ZShmaWxsKSkge1xuICAgICAgcmV0dXJuIGZpbGw7XG4gICAgfVxuXG4gICAgdGFyZ2V0ID0gc291cmNlc1tmaWxsXTtcbiAgICBpZiAoIXRhcmdldCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0YXJnZXQudmlzaWJsZSkge1xuICAgICAgcmV0dXJuIGZpbGw7XG4gICAgfVxuXG4gICAgdmlzaXRlZC5wdXNoKGZpbGwpO1xuICAgIGZpbGwgPSB0YXJnZXQuZmlsbDtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0xpbmVFbGVtZW50fSBsaW5lXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAqIEBwYXJhbSB7bnVtYmVyfSBjb3VudFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2RlY29kZUZpbGwobGluZSwgaW5kZXgsIGNvdW50KSB7XG4gIC8qKiBAdHlwZSB7c3RyaW5nIHwge3ZhbHVlOiBudW1iZXJ9fSAqL1xuICBjb25zdCBmaWxsID0gcGFyc2VGaWxsT3B0aW9uKGxpbmUpO1xuXG4gIGlmIChpc09iamVjdChmaWxsKSkge1xuICAgIHJldHVybiBpc05hTihmaWxsLnZhbHVlKSA/IGZhbHNlIDogZmlsbDtcbiAgfVxuXG4gIGxldCB0YXJnZXQgPSBwYXJzZUZsb2F0KGZpbGwpO1xuXG4gIGlmIChpc0Zpbml0ZSh0YXJnZXQpICYmIE1hdGguZmxvb3IodGFyZ2V0KSA9PT0gdGFyZ2V0KSB7XG4gICAgcmV0dXJuIGRlY29kZVRhcmdldEluZGV4KGZpbGxbMF0sIGluZGV4LCB0YXJnZXQsIGNvdW50KTtcbiAgfVxuXG4gIHJldHVybiBbJ29yaWdpbicsICdzdGFydCcsICdlbmQnLCAnc3RhY2snLCAnc2hhcGUnXS5pbmRleE9mKGZpbGwpID49IDAgJiYgZmlsbDtcbn1cblxuZnVuY3Rpb24gZGVjb2RlVGFyZ2V0SW5kZXgoZmlyc3RDaCwgaW5kZXgsIHRhcmdldCwgY291bnQpIHtcbiAgaWYgKGZpcnN0Q2ggPT09ICctJyB8fCBmaXJzdENoID09PSAnKycpIHtcbiAgICB0YXJnZXQgPSBpbmRleCArIHRhcmdldDtcbiAgfVxuXG4gIGlmICh0YXJnZXQgPT09IGluZGV4IHx8IHRhcmdldCA8IDAgfHwgdGFyZ2V0ID49IGNvdW50KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0ZpbGxUYXJnZXQgfCBDb21wbGV4RmlsbFRhcmdldH0gZmlsbFxuICogQHBhcmFtIHtTY2FsZX0gc2NhbGVcbiAqIEByZXR1cm5zIHtudW1iZXIgfCBudWxsfVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2dldFRhcmdldFBpeGVsKGZpbGwsIHNjYWxlKSB7XG4gIGxldCBwaXhlbCA9IG51bGw7XG4gIGlmIChmaWxsID09PSAnc3RhcnQnKSB7XG4gICAgcGl4ZWwgPSBzY2FsZS5ib3R0b207XG4gIH0gZWxzZSBpZiAoZmlsbCA9PT0gJ2VuZCcpIHtcbiAgICBwaXhlbCA9IHNjYWxlLnRvcDtcbiAgfSBlbHNlIGlmIChpc09iamVjdChmaWxsKSkge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBwaXhlbCA9IHNjYWxlLmdldFBpeGVsRm9yVmFsdWUoZmlsbC52YWx1ZSk7XG4gIH0gZWxzZSBpZiAoc2NhbGUuZ2V0QmFzZVBpeGVsKSB7XG4gICAgcGl4ZWwgPSBzY2FsZS5nZXRCYXNlUGl4ZWwoKTtcbiAgfVxuICByZXR1cm4gcGl4ZWw7XG59XG5cbi8qKlxuICogQHBhcmFtIHtGaWxsVGFyZ2V0IHwgQ29tcGxleEZpbGxUYXJnZXR9IGZpbGxcbiAqIEBwYXJhbSB7U2NhbGV9IHNjYWxlXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnRWYWx1ZVxuICogQHJldHVybnMge251bWJlciB8IHVuZGVmaW5lZH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9nZXRUYXJnZXRWYWx1ZShmaWxsLCBzY2FsZSwgc3RhcnRWYWx1ZSkge1xuICBsZXQgdmFsdWU7XG5cbiAgaWYgKGZpbGwgPT09ICdzdGFydCcpIHtcbiAgICB2YWx1ZSA9IHN0YXJ0VmFsdWU7XG4gIH0gZWxzZSBpZiAoZmlsbCA9PT0gJ2VuZCcpIHtcbiAgICB2YWx1ZSA9IHNjYWxlLm9wdGlvbnMucmV2ZXJzZSA/IHNjYWxlLm1pbiA6IHNjYWxlLm1heDtcbiAgfSBlbHNlIGlmIChpc09iamVjdChmaWxsKSkge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICB2YWx1ZSA9IGZpbGwudmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgdmFsdWUgPSBzY2FsZS5nZXRCYXNlVmFsdWUoKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogQHBhcmFtIHtMaW5lRWxlbWVudH0gbGluZVxuICovXG5mdW5jdGlvbiBwYXJzZUZpbGxPcHRpb24obGluZSkge1xuICBjb25zdCBvcHRpb25zID0gbGluZS5vcHRpb25zO1xuICBjb25zdCBmaWxsT3B0aW9uID0gb3B0aW9ucy5maWxsO1xuICBsZXQgZmlsbCA9IHZhbHVlT3JEZWZhdWx0KGZpbGxPcHRpb24gJiYgZmlsbE9wdGlvbi50YXJnZXQsIGZpbGxPcHRpb24pO1xuXG4gIGlmIChmaWxsID09PSB1bmRlZmluZWQpIHtcbiAgICBmaWxsID0gISFvcHRpb25zLmJhY2tncm91bmRDb2xvcjtcbiAgfVxuXG4gIGlmIChmaWxsID09PSBmYWxzZSB8fCBmaWxsID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGZpbGwgPT09IHRydWUpIHtcbiAgICByZXR1cm4gJ29yaWdpbic7XG4gIH1cbiAgcmV0dXJuIGZpbGw7XG59XG4iLCAiLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vLi4vY29yZS9jb3JlLmNvbnRyb2xsZXIuanMnKS5kZWZhdWx0IH0gQ2hhcnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi9jb3JlL2NvcmUuc2NhbGUuanMnKS5kZWZhdWx0IH0gU2NhbGVcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi9lbGVtZW50cy9lbGVtZW50LnBvaW50LmpzJykuZGVmYXVsdCB9IFBvaW50RWxlbWVudFxuICovXG5cbmltcG9ydCB7TGluZUVsZW1lbnR9IGZyb20gJy4uLy4uL2VsZW1lbnRzL2luZGV4LmpzJztcbmltcG9ydCB7X2lzQmV0d2Vlbn0gZnJvbSAnLi4vLi4vaGVscGVycy9pbmRleC5qcyc7XG5pbXBvcnQge19jcmVhdGVCb3VuZGFyeUxpbmV9IGZyb20gJy4vZmlsbGVyLmhlbHBlci5qcyc7XG5cbi8qKlxuICogQHBhcmFtIHt7IGNoYXJ0OiBDaGFydDsgc2NhbGU6IFNjYWxlOyBpbmRleDogbnVtYmVyOyBsaW5lOiBMaW5lRWxlbWVudDsgfX0gc291cmNlXG4gKiBAcmV0dXJuIHtMaW5lRWxlbWVudH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9idWlsZFN0YWNrTGluZShzb3VyY2UpIHtcbiAgY29uc3Qge3NjYWxlLCBpbmRleCwgbGluZX0gPSBzb3VyY2U7XG4gIGNvbnN0IHBvaW50cyA9IFtdO1xuICBjb25zdCBzZWdtZW50cyA9IGxpbmUuc2VnbWVudHM7XG4gIGNvbnN0IHNvdXJjZVBvaW50cyA9IGxpbmUucG9pbnRzO1xuICBjb25zdCBsaW5lc0JlbG93ID0gZ2V0TGluZXNCZWxvdyhzY2FsZSwgaW5kZXgpO1xuICBsaW5lc0JlbG93LnB1c2goX2NyZWF0ZUJvdW5kYXJ5TGluZSh7eDogbnVsbCwgeTogc2NhbGUuYm90dG9tfSwgbGluZSkpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzZWdtZW50ID0gc2VnbWVudHNbaV07XG4gICAgZm9yIChsZXQgaiA9IHNlZ21lbnQuc3RhcnQ7IGogPD0gc2VnbWVudC5lbmQ7IGorKykge1xuICAgICAgYWRkUG9pbnRzQmVsb3cocG9pbnRzLCBzb3VyY2VQb2ludHNbal0sIGxpbmVzQmVsb3cpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3IExpbmVFbGVtZW50KHtwb2ludHMsIG9wdGlvbnM6IHt9fSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtTY2FsZX0gc2NhbGVcbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICogQHJldHVybiB7TGluZUVsZW1lbnRbXX1cbiAqL1xuZnVuY3Rpb24gZ2V0TGluZXNCZWxvdyhzY2FsZSwgaW5kZXgpIHtcbiAgY29uc3QgYmVsb3cgPSBbXTtcbiAgY29uc3QgbWV0YXMgPSBzY2FsZS5nZXRNYXRjaGluZ1Zpc2libGVNZXRhcygnbGluZScpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbWV0YXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBtZXRhID0gbWV0YXNbaV07XG4gICAgaWYgKG1ldGEuaW5kZXggPT09IGluZGV4KSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKCFtZXRhLmhpZGRlbikge1xuICAgICAgYmVsb3cudW5zaGlmdChtZXRhLmRhdGFzZXQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYmVsb3c7XG59XG5cbi8qKlxuICogQHBhcmFtIHtQb2ludEVsZW1lbnRbXX0gcG9pbnRzXG4gKiBAcGFyYW0ge1BvaW50RWxlbWVudH0gc291cmNlUG9pbnRcbiAqIEBwYXJhbSB7TGluZUVsZW1lbnRbXX0gbGluZXNCZWxvd1xuICovXG5mdW5jdGlvbiBhZGRQb2ludHNCZWxvdyhwb2ludHMsIHNvdXJjZVBvaW50LCBsaW5lc0JlbG93KSB7XG4gIGNvbnN0IHBvc3Rwb25lZCA9IFtdO1xuICBmb3IgKGxldCBqID0gMDsgaiA8IGxpbmVzQmVsb3cubGVuZ3RoOyBqKyspIHtcbiAgICBjb25zdCBsaW5lID0gbGluZXNCZWxvd1tqXTtcbiAgICBjb25zdCB7Zmlyc3QsIGxhc3QsIHBvaW50fSA9IGZpbmRQb2ludChsaW5lLCBzb3VyY2VQb2ludCwgJ3gnKTtcblxuICAgIGlmICghcG9pbnQgfHwgKGZpcnN0ICYmIGxhc3QpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGZpcnN0KSB7XG4gICAgICAvLyBGaXJzdCBwb2ludCBvZiBhbiBzZWdtZW50IC0+IG5lZWQgdG8gYWRkIGFub3RoZXIgcG9pbnQgYmVmb3JlIHRoaXMsXG4gICAgICAvLyBmcm9tIG5leHQgbGluZSBiZWxvdy5cbiAgICAgIHBvc3Rwb25lZC51bnNoaWZ0KHBvaW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcG9pbnRzLnB1c2gocG9pbnQpO1xuICAgICAgaWYgKCFsYXN0KSB7XG4gICAgICAgIC8vIEluIHRoZSBtaWRkbGUgb2YgYW4gc2VnbWVudCwgbm8gbmVlZCB0byBhZGQgbW9yZSBwb2ludHMuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBwb2ludHMucHVzaCguLi5wb3N0cG9uZWQpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7TGluZUVsZW1lbnR9IGxpbmVcbiAqIEBwYXJhbSB7UG9pbnRFbGVtZW50fSBzb3VyY2VQb2ludFxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BlcnR5XG4gKiBAcmV0dXJucyB7e3BvaW50PzogUG9pbnRFbGVtZW50LCBmaXJzdD86IGJvb2xlYW4sIGxhc3Q/OiBib29sZWFufX1cbiAqL1xuZnVuY3Rpb24gZmluZFBvaW50KGxpbmUsIHNvdXJjZVBvaW50LCBwcm9wZXJ0eSkge1xuICBjb25zdCBwb2ludCA9IGxpbmUuaW50ZXJwb2xhdGUoc291cmNlUG9pbnQsIHByb3BlcnR5KTtcbiAgaWYgKCFwb2ludCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGNvbnN0IHBvaW50VmFsdWUgPSBwb2ludFtwcm9wZXJ0eV07XG4gIGNvbnN0IHNlZ21lbnRzID0gbGluZS5zZWdtZW50cztcbiAgY29uc3QgbGluZVBvaW50cyA9IGxpbmUucG9pbnRzO1xuICBsZXQgZmlyc3QgPSBmYWxzZTtcbiAgbGV0IGxhc3QgPSBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHNlZ21lbnQgPSBzZWdtZW50c1tpXTtcbiAgICBjb25zdCBmaXJzdFZhbHVlID0gbGluZVBvaW50c1tzZWdtZW50LnN0YXJ0XVtwcm9wZXJ0eV07XG4gICAgY29uc3QgbGFzdFZhbHVlID0gbGluZVBvaW50c1tzZWdtZW50LmVuZF1bcHJvcGVydHldO1xuICAgIGlmIChfaXNCZXR3ZWVuKHBvaW50VmFsdWUsIGZpcnN0VmFsdWUsIGxhc3RWYWx1ZSkpIHtcbiAgICAgIGZpcnN0ID0gcG9pbnRWYWx1ZSA9PT0gZmlyc3RWYWx1ZTtcbiAgICAgIGxhc3QgPSBwb2ludFZhbHVlID09PSBsYXN0VmFsdWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHtmaXJzdCwgbGFzdCwgcG9pbnR9O1xufVxuIiwgImltcG9ydCB7VEFVfSBmcm9tICcuLi8uLi9oZWxwZXJzL2luZGV4LmpzJztcblxuLy8gVE9ETzogdXNlIGVsZW1lbnRzLkFyY0VsZW1lbnQgaW5zdGVhZFxuZXhwb3J0IGNsYXNzIHNpbXBsZUFyYyB7XG4gIGNvbnN0cnVjdG9yKG9wdHMpIHtcbiAgICB0aGlzLnggPSBvcHRzLng7XG4gICAgdGhpcy55ID0gb3B0cy55O1xuICAgIHRoaXMucmFkaXVzID0gb3B0cy5yYWRpdXM7XG4gIH1cblxuICBwYXRoU2VnbWVudChjdHgsIGJvdW5kcywgb3B0cykge1xuICAgIGNvbnN0IHt4LCB5LCByYWRpdXN9ID0gdGhpcztcbiAgICBib3VuZHMgPSBib3VuZHMgfHwge3N0YXJ0OiAwLCBlbmQ6IFRBVX07XG4gICAgY3R4LmFyYyh4LCB5LCByYWRpdXMsIGJvdW5kcy5lbmQsIGJvdW5kcy5zdGFydCwgdHJ1ZSk7XG4gICAgcmV0dXJuICFvcHRzLmJvdW5kcztcbiAgfVxuXG4gIGludGVycG9sYXRlKHBvaW50KSB7XG4gICAgY29uc3Qge3gsIHksIHJhZGl1c30gPSB0aGlzO1xuICAgIGNvbnN0IGFuZ2xlID0gcG9pbnQuYW5nbGU7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHggKyBNYXRoLmNvcyhhbmdsZSkgKiByYWRpdXMsXG4gICAgICB5OiB5ICsgTWF0aC5zaW4oYW5nbGUpICogcmFkaXVzLFxuICAgICAgYW5nbGVcbiAgICB9O1xuICB9XG59XG4iLCAiaW1wb3J0IHtpc0Zpbml0ZX0gZnJvbSAnLi4vLi4vaGVscGVycy9pbmRleC5qcyc7XG5pbXBvcnQge19jcmVhdGVCb3VuZGFyeUxpbmV9IGZyb20gJy4vZmlsbGVyLmhlbHBlci5qcyc7XG5pbXBvcnQge19nZXRUYXJnZXRQaXhlbCwgX2dldFRhcmdldFZhbHVlfSBmcm9tICcuL2ZpbGxlci5vcHRpb25zLmpzJztcbmltcG9ydCB7X2J1aWxkU3RhY2tMaW5lfSBmcm9tICcuL2ZpbGxlci50YXJnZXQuc3RhY2suanMnO1xuaW1wb3J0IHtzaW1wbGVBcmN9IGZyb20gJy4vc2ltcGxlQXJjLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vLi4vY29yZS9jb3JlLmNvbnRyb2xsZXIuanMnKS5kZWZhdWx0IH0gQ2hhcnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi9jb3JlL2NvcmUuc2NhbGUuanMnKS5kZWZhdWx0IH0gU2NhbGVcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi9lbGVtZW50cy9lbGVtZW50LnBvaW50LmpzJykuZGVmYXVsdCB9IFBvaW50RWxlbWVudFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBfZ2V0VGFyZ2V0KHNvdXJjZSkge1xuICBjb25zdCB7Y2hhcnQsIGZpbGwsIGxpbmV9ID0gc291cmNlO1xuXG4gIGlmIChpc0Zpbml0ZShmaWxsKSkge1xuICAgIHJldHVybiBnZXRMaW5lQnlJbmRleChjaGFydCwgZmlsbCk7XG4gIH1cblxuICBpZiAoZmlsbCA9PT0gJ3N0YWNrJykge1xuICAgIHJldHVybiBfYnVpbGRTdGFja0xpbmUoc291cmNlKTtcbiAgfVxuXG4gIGlmIChmaWxsID09PSAnc2hhcGUnKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBib3VuZGFyeSA9IGNvbXB1dGVCb3VuZGFyeShzb3VyY2UpO1xuXG4gIGlmIChib3VuZGFyeSBpbnN0YW5jZW9mIHNpbXBsZUFyYykge1xuICAgIHJldHVybiBib3VuZGFyeTtcbiAgfVxuXG4gIHJldHVybiBfY3JlYXRlQm91bmRhcnlMaW5lKGJvdW5kYXJ5LCBsaW5lKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0NoYXJ0fSBjaGFydFxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gKi9cbmZ1bmN0aW9uIGdldExpbmVCeUluZGV4KGNoYXJ0LCBpbmRleCkge1xuICBjb25zdCBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoaW5kZXgpO1xuICBjb25zdCB2aXNpYmxlID0gbWV0YSAmJiBjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGluZGV4KTtcbiAgcmV0dXJuIHZpc2libGUgPyBtZXRhLmRhdGFzZXQgOiBudWxsO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlQm91bmRhcnkoc291cmNlKSB7XG4gIGNvbnN0IHNjYWxlID0gc291cmNlLnNjYWxlIHx8IHt9O1xuXG4gIGlmIChzY2FsZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUpIHtcbiAgICByZXR1cm4gY29tcHV0ZUNpcmN1bGFyQm91bmRhcnkoc291cmNlKTtcbiAgfVxuICByZXR1cm4gY29tcHV0ZUxpbmVhckJvdW5kYXJ5KHNvdXJjZSk7XG59XG5cblxuZnVuY3Rpb24gY29tcHV0ZUxpbmVhckJvdW5kYXJ5KHNvdXJjZSkge1xuICBjb25zdCB7c2NhbGUgPSB7fSwgZmlsbH0gPSBzb3VyY2U7XG4gIGNvbnN0IHBpeGVsID0gX2dldFRhcmdldFBpeGVsKGZpbGwsIHNjYWxlKTtcblxuICBpZiAoaXNGaW5pdGUocGl4ZWwpKSB7XG4gICAgY29uc3QgaG9yaXpvbnRhbCA9IHNjYWxlLmlzSG9yaXpvbnRhbCgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IGhvcml6b250YWwgPyBwaXhlbCA6IG51bGwsXG4gICAgICB5OiBob3Jpem9udGFsID8gbnVsbCA6IHBpeGVsXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlQ2lyY3VsYXJCb3VuZGFyeShzb3VyY2UpIHtcbiAgY29uc3Qge3NjYWxlLCBmaWxsfSA9IHNvdXJjZTtcbiAgY29uc3Qgb3B0aW9ucyA9IHNjYWxlLm9wdGlvbnM7XG4gIGNvbnN0IGxlbmd0aCA9IHNjYWxlLmdldExhYmVscygpLmxlbmd0aDtcbiAgY29uc3Qgc3RhcnQgPSBvcHRpb25zLnJldmVyc2UgPyBzY2FsZS5tYXggOiBzY2FsZS5taW47XG4gIGNvbnN0IHZhbHVlID0gX2dldFRhcmdldFZhbHVlKGZpbGwsIHNjYWxlLCBzdGFydCk7XG4gIGNvbnN0IHRhcmdldCA9IFtdO1xuXG4gIGlmIChvcHRpb25zLmdyaWQuY2lyY3VsYXIpIHtcbiAgICBjb25zdCBjZW50ZXIgPSBzY2FsZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUoMCwgc3RhcnQpO1xuICAgIHJldHVybiBuZXcgc2ltcGxlQXJjKHtcbiAgICAgIHg6IGNlbnRlci54LFxuICAgICAgeTogY2VudGVyLnksXG4gICAgICByYWRpdXM6IHNjYWxlLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKHZhbHVlKVxuICAgIH0pO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHRhcmdldC5wdXNoKHNjYWxlLmdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZShpLCB2YWx1ZSkpO1xuICB9XG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbiIsICJpbXBvcnQge2NsaXBBcmVhLCB1bmNsaXBBcmVhfSBmcm9tICcuLi8uLi9oZWxwZXJzL2luZGV4LmpzJztcbmltcG9ydCB7X2ZpbmRTZWdtZW50RW5kLCBfZ2V0Qm91bmRzLCBfc2VnbWVudHN9IGZyb20gJy4vZmlsbGVyLnNlZ21lbnQuanMnO1xuaW1wb3J0IHtfZ2V0VGFyZ2V0fSBmcm9tICcuL2ZpbGxlci50YXJnZXQuanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gX2RyYXdmaWxsKGN0eCwgc291cmNlLCBhcmVhKSB7XG4gIGNvbnN0IHRhcmdldCA9IF9nZXRUYXJnZXQoc291cmNlKTtcbiAgY29uc3Qge2xpbmUsIHNjYWxlLCBheGlzfSA9IHNvdXJjZTtcbiAgY29uc3QgbGluZU9wdHMgPSBsaW5lLm9wdGlvbnM7XG4gIGNvbnN0IGZpbGxPcHRpb24gPSBsaW5lT3B0cy5maWxsO1xuICBjb25zdCBjb2xvciA9IGxpbmVPcHRzLmJhY2tncm91bmRDb2xvcjtcbiAgY29uc3Qge2Fib3ZlID0gY29sb3IsIGJlbG93ID0gY29sb3J9ID0gZmlsbE9wdGlvbiB8fCB7fTtcbiAgaWYgKHRhcmdldCAmJiBsaW5lLnBvaW50cy5sZW5ndGgpIHtcbiAgICBjbGlwQXJlYShjdHgsIGFyZWEpO1xuICAgIGRvRmlsbChjdHgsIHtsaW5lLCB0YXJnZXQsIGFib3ZlLCBiZWxvdywgYXJlYSwgc2NhbGUsIGF4aXN9KTtcbiAgICB1bmNsaXBBcmVhKGN0eCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZG9GaWxsKGN0eCwgY2ZnKSB7XG4gIGNvbnN0IHtsaW5lLCB0YXJnZXQsIGFib3ZlLCBiZWxvdywgYXJlYSwgc2NhbGV9ID0gY2ZnO1xuICBjb25zdCBwcm9wZXJ0eSA9IGxpbmUuX2xvb3AgPyAnYW5nbGUnIDogY2ZnLmF4aXM7XG5cbiAgY3R4LnNhdmUoKTtcblxuICBpZiAocHJvcGVydHkgPT09ICd4JyAmJiBiZWxvdyAhPT0gYWJvdmUpIHtcbiAgICBjbGlwVmVydGljYWwoY3R4LCB0YXJnZXQsIGFyZWEudG9wKTtcbiAgICBmaWxsKGN0eCwge2xpbmUsIHRhcmdldCwgY29sb3I6IGFib3ZlLCBzY2FsZSwgcHJvcGVydHl9KTtcbiAgICBjdHgucmVzdG9yZSgpO1xuICAgIGN0eC5zYXZlKCk7XG4gICAgY2xpcFZlcnRpY2FsKGN0eCwgdGFyZ2V0LCBhcmVhLmJvdHRvbSk7XG4gIH1cbiAgZmlsbChjdHgsIHtsaW5lLCB0YXJnZXQsIGNvbG9yOiBiZWxvdywgc2NhbGUsIHByb3BlcnR5fSk7XG5cbiAgY3R4LnJlc3RvcmUoKTtcbn1cblxuZnVuY3Rpb24gY2xpcFZlcnRpY2FsKGN0eCwgdGFyZ2V0LCBjbGlwWSkge1xuICBjb25zdCB7c2VnbWVudHMsIHBvaW50c30gPSB0YXJnZXQ7XG4gIGxldCBmaXJzdCA9IHRydWU7XG4gIGxldCBsaW5lTG9vcCA9IGZhbHNlO1xuXG4gIGN0eC5iZWdpblBhdGgoKTtcbiAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgY29uc3Qge3N0YXJ0LCBlbmR9ID0gc2VnbWVudDtcbiAgICBjb25zdCBmaXJzdFBvaW50ID0gcG9pbnRzW3N0YXJ0XTtcbiAgICBjb25zdCBsYXN0UG9pbnQgPSBwb2ludHNbX2ZpbmRTZWdtZW50RW5kKHN0YXJ0LCBlbmQsIHBvaW50cyldO1xuICAgIGlmIChmaXJzdCkge1xuICAgICAgY3R4Lm1vdmVUbyhmaXJzdFBvaW50LngsIGZpcnN0UG9pbnQueSk7XG4gICAgICBmaXJzdCA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdHgubGluZVRvKGZpcnN0UG9pbnQueCwgY2xpcFkpO1xuICAgICAgY3R4LmxpbmVUbyhmaXJzdFBvaW50LngsIGZpcnN0UG9pbnQueSk7XG4gICAgfVxuICAgIGxpbmVMb29wID0gISF0YXJnZXQucGF0aFNlZ21lbnQoY3R4LCBzZWdtZW50LCB7bW92ZTogbGluZUxvb3B9KTtcbiAgICBpZiAobGluZUxvb3ApIHtcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3R4LmxpbmVUbyhsYXN0UG9pbnQueCwgY2xpcFkpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5saW5lVG8odGFyZ2V0LmZpcnN0KCkueCwgY2xpcFkpO1xuICBjdHguY2xvc2VQYXRoKCk7XG4gIGN0eC5jbGlwKCk7XG59XG5cbmZ1bmN0aW9uIGZpbGwoY3R4LCBjZmcpIHtcbiAgY29uc3Qge2xpbmUsIHRhcmdldCwgcHJvcGVydHksIGNvbG9yLCBzY2FsZX0gPSBjZmc7XG4gIGNvbnN0IHNlZ21lbnRzID0gX3NlZ21lbnRzKGxpbmUsIHRhcmdldCwgcHJvcGVydHkpO1xuXG4gIGZvciAoY29uc3Qge3NvdXJjZTogc3JjLCB0YXJnZXQ6IHRndCwgc3RhcnQsIGVuZH0gb2Ygc2VnbWVudHMpIHtcbiAgICBjb25zdCB7c3R5bGU6IHtiYWNrZ3JvdW5kQ29sb3IgPSBjb2xvcn0gPSB7fX0gPSBzcmM7XG4gICAgY29uc3Qgbm90U2hhcGUgPSB0YXJnZXQgIT09IHRydWU7XG5cbiAgICBjdHguc2F2ZSgpO1xuICAgIGN0eC5maWxsU3R5bGUgPSBiYWNrZ3JvdW5kQ29sb3I7XG5cbiAgICBjbGlwQm91bmRzKGN0eCwgc2NhbGUsIG5vdFNoYXBlICYmIF9nZXRCb3VuZHMocHJvcGVydHksIHN0YXJ0LCBlbmQpKTtcblxuICAgIGN0eC5iZWdpblBhdGgoKTtcblxuICAgIGNvbnN0IGxpbmVMb29wID0gISFsaW5lLnBhdGhTZWdtZW50KGN0eCwgc3JjKTtcblxuICAgIGxldCBsb29wO1xuICAgIGlmIChub3RTaGFwZSkge1xuICAgICAgaWYgKGxpbmVMb29wKSB7XG4gICAgICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGludGVycG9sYXRlZExpbmVUbyhjdHgsIHRhcmdldCwgZW5kLCBwcm9wZXJ0eSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRhcmdldExvb3AgPSAhIXRhcmdldC5wYXRoU2VnbWVudChjdHgsIHRndCwge21vdmU6IGxpbmVMb29wLCByZXZlcnNlOiB0cnVlfSk7XG4gICAgICBsb29wID0gbGluZUxvb3AgJiYgdGFyZ2V0TG9vcDtcbiAgICAgIGlmICghbG9vcCkge1xuICAgICAgICBpbnRlcnBvbGF0ZWRMaW5lVG8oY3R4LCB0YXJnZXQsIHN0YXJ0LCBwcm9wZXJ0eSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgIGN0eC5maWxsKGxvb3AgPyAnZXZlbm9kZCcgOiAnbm9uemVybycpO1xuXG4gICAgY3R4LnJlc3RvcmUoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjbGlwQm91bmRzKGN0eCwgc2NhbGUsIGJvdW5kcykge1xuICBjb25zdCB7dG9wLCBib3R0b219ID0gc2NhbGUuY2hhcnQuY2hhcnRBcmVhO1xuICBjb25zdCB7cHJvcGVydHksIHN0YXJ0LCBlbmR9ID0gYm91bmRzIHx8IHt9O1xuICBpZiAocHJvcGVydHkgPT09ICd4Jykge1xuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHgucmVjdChzdGFydCwgdG9wLCBlbmQgLSBzdGFydCwgYm90dG9tIC0gdG9wKTtcbiAgICBjdHguY2xpcCgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludGVycG9sYXRlZExpbmVUbyhjdHgsIHRhcmdldCwgcG9pbnQsIHByb3BlcnR5KSB7XG4gIGNvbnN0IGludGVycG9sYXRlZFBvaW50ID0gdGFyZ2V0LmludGVycG9sYXRlKHBvaW50LCBwcm9wZXJ0eSk7XG4gIGlmIChpbnRlcnBvbGF0ZWRQb2ludCkge1xuICAgIGN0eC5saW5lVG8oaW50ZXJwb2xhdGVkUG9pbnQueCwgaW50ZXJwb2xhdGVkUG9pbnQueSk7XG4gIH1cbn1cblxuIiwgIi8qKlxuICogUGx1Z2luIGJhc2VkIG9uIGRpc2N1c3Npb24gZnJvbSB0aGUgZm9sbG93aW5nIENoYXJ0LmpzIGlzc3VlczpcbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzIzODAjaXNzdWVjb21tZW50LTI3OTk2MTU2OVxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMjQ0MCNpc3N1ZWNvbW1lbnQtMjU2NDYxODk3XG4gKi9cblxuaW1wb3J0IExpbmVFbGVtZW50IGZyb20gJy4uLy4uL2VsZW1lbnRzL2VsZW1lbnQubGluZS5qcyc7XG5pbXBvcnQge19kcmF3ZmlsbH0gZnJvbSAnLi9maWxsZXIuZHJhd2luZy5qcyc7XG5pbXBvcnQge19zaG91bGRBcHBseUZpbGx9IGZyb20gJy4vZmlsbGVyLmhlbHBlci5qcyc7XG5pbXBvcnQge19kZWNvZGVGaWxsLCBfcmVzb2x2ZVRhcmdldH0gZnJvbSAnLi9maWxsZXIub3B0aW9ucy5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgaWQ6ICdmaWxsZXInLFxuXG4gIGFmdGVyRGF0YXNldHNVcGRhdGUoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgY29uc3QgY291bnQgPSAoY2hhcnQuZGF0YS5kYXRhc2V0cyB8fCBbXSkubGVuZ3RoO1xuICAgIGNvbnN0IHNvdXJjZXMgPSBbXTtcbiAgICBsZXQgbWV0YSwgaSwgbGluZSwgc291cmNlO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcbiAgICAgIG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShpKTtcbiAgICAgIGxpbmUgPSBtZXRhLmRhdGFzZXQ7XG4gICAgICBzb3VyY2UgPSBudWxsO1xuXG4gICAgICBpZiAobGluZSAmJiBsaW5lLm9wdGlvbnMgJiYgbGluZSBpbnN0YW5jZW9mIExpbmVFbGVtZW50KSB7XG4gICAgICAgIHNvdXJjZSA9IHtcbiAgICAgICAgICB2aXNpYmxlOiBjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpLFxuICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgIGZpbGw6IF9kZWNvZGVGaWxsKGxpbmUsIGksIGNvdW50KSxcbiAgICAgICAgICBjaGFydCxcbiAgICAgICAgICBheGlzOiBtZXRhLmNvbnRyb2xsZXIub3B0aW9ucy5pbmRleEF4aXMsXG4gICAgICAgICAgc2NhbGU6IG1ldGEudlNjYWxlLFxuICAgICAgICAgIGxpbmUsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIG1ldGEuJGZpbGxlciA9IHNvdXJjZTtcbiAgICAgIHNvdXJjZXMucHVzaChzb3VyY2UpO1xuICAgIH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7XG4gICAgICBzb3VyY2UgPSBzb3VyY2VzW2ldO1xuICAgICAgaWYgKCFzb3VyY2UgfHwgc291cmNlLmZpbGwgPT09IGZhbHNlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBzb3VyY2UuZmlsbCA9IF9yZXNvbHZlVGFyZ2V0KHNvdXJjZXMsIGksIG9wdGlvbnMucHJvcGFnYXRlKTtcbiAgICB9XG4gIH0sXG5cbiAgYmVmb3JlRHJhdyhjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBkcmF3ID0gb3B0aW9ucy5kcmF3VGltZSA9PT0gJ2JlZm9yZURyYXcnO1xuICAgIGNvbnN0IG1ldGFzZXRzID0gY2hhcnQuZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpO1xuICAgIGNvbnN0IGFyZWEgPSBjaGFydC5jaGFydEFyZWE7XG4gICAgZm9yIChsZXQgaSA9IG1ldGFzZXRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBtZXRhc2V0c1tpXS4kZmlsbGVyO1xuICAgICAgaWYgKCFzb3VyY2UpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHNvdXJjZS5saW5lLnVwZGF0ZUNvbnRyb2xQb2ludHMoYXJlYSwgc291cmNlLmF4aXMpO1xuICAgICAgaWYgKGRyYXcgJiYgc291cmNlLmZpbGwpIHtcbiAgICAgICAgX2RyYXdmaWxsKGNoYXJ0LmN0eCwgc291cmNlLCBhcmVhKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgYmVmb3JlRGF0YXNldHNEcmF3KGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgIGlmIChvcHRpb25zLmRyYXdUaW1lICE9PSAnYmVmb3JlRGF0YXNldHNEcmF3Jykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG1ldGFzZXRzID0gY2hhcnQuZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpO1xuICAgIGZvciAobGV0IGkgPSBtZXRhc2V0cy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgY29uc3Qgc291cmNlID0gbWV0YXNldHNbaV0uJGZpbGxlcjtcblxuICAgICAgaWYgKF9zaG91bGRBcHBseUZpbGwoc291cmNlKSkge1xuICAgICAgICBfZHJhd2ZpbGwoY2hhcnQuY3R4LCBzb3VyY2UsIGNoYXJ0LmNoYXJ0QXJlYSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGJlZm9yZURhdGFzZXREcmF3KGNoYXJ0LCBhcmdzLCBvcHRpb25zKSB7XG4gICAgY29uc3Qgc291cmNlID0gYXJncy5tZXRhLiRmaWxsZXI7XG5cbiAgICBpZiAoIV9zaG91bGRBcHBseUZpbGwoc291cmNlKSB8fCBvcHRpb25zLmRyYXdUaW1lICE9PSAnYmVmb3JlRGF0YXNldERyYXcnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgX2RyYXdmaWxsKGNoYXJ0LmN0eCwgc291cmNlLCBjaGFydC5jaGFydEFyZWEpO1xuICB9LFxuXG4gIGRlZmF1bHRzOiB7XG4gICAgcHJvcGFnYXRlOiB0cnVlLFxuICAgIGRyYXdUaW1lOiAnYmVmb3JlRGF0YXNldERyYXcnXG4gIH1cbn07XG4iLCAiaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uL2NvcmUvY29yZS5kZWZhdWx0cy5qcyc7XG5pbXBvcnQgRWxlbWVudCBmcm9tICcuLi9jb3JlL2NvcmUuZWxlbWVudC5qcyc7XG5pbXBvcnQgbGF5b3V0cyBmcm9tICcuLi9jb3JlL2NvcmUubGF5b3V0cy5qcyc7XG5pbXBvcnQge2FkZFJvdW5kZWRSZWN0UGF0aCwgZHJhd1BvaW50TGVnZW5kLCByZW5kZXJUZXh0fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY2FudmFzLmpzJztcbmltcG9ydCB7XG4gIF9pc0JldHdlZW4sXG4gIGNhbGxiYWNrIGFzIGNhbGwsXG4gIGNsaXBBcmVhLFxuICBnZXRSdGxBZGFwdGVyLFxuICBvdmVycmlkZVRleHREaXJlY3Rpb24sXG4gIHJlc3RvcmVUZXh0RGlyZWN0aW9uLFxuICB0b0ZvbnQsXG4gIHRvUGFkZGluZyxcbiAgdW5jbGlwQXJlYSxcbiAgdmFsdWVPckRlZmF1bHQsXG59IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuaW1wb3J0IHtfYWxpZ25TdGFydEVuZCwgX3RleHRYLCBfdG9MZWZ0UmlnaHRDZW50ZXJ9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5leHRyYXMuanMnO1xuaW1wb3J0IHt0b1RSQkxDb3JuZXJzfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMub3B0aW9ucy5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL3R5cGVzL2luZGV4LmpzJykuQ2hhcnRFdmVudCB9IENoYXJ0RXZlbnRcbiAqL1xuXG5jb25zdCBnZXRCb3hTaXplID0gKGxhYmVsT3B0cywgZm9udFNpemUpID0+IHtcbiAgbGV0IHtib3hIZWlnaHQgPSBmb250U2l6ZSwgYm94V2lkdGggPSBmb250U2l6ZX0gPSBsYWJlbE9wdHM7XG5cbiAgaWYgKGxhYmVsT3B0cy51c2VQb2ludFN0eWxlKSB7XG4gICAgYm94SGVpZ2h0ID0gTWF0aC5taW4oYm94SGVpZ2h0LCBmb250U2l6ZSk7XG4gICAgYm94V2lkdGggPSBsYWJlbE9wdHMucG9pbnRTdHlsZVdpZHRoIHx8IE1hdGgubWluKGJveFdpZHRoLCBmb250U2l6ZSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJveFdpZHRoLFxuICAgIGJveEhlaWdodCxcbiAgICBpdGVtSGVpZ2h0OiBNYXRoLm1heChmb250U2l6ZSwgYm94SGVpZ2h0KVxuICB9O1xufTtcblxuY29uc3QgaXRlbXNFcXVhbCA9IChhLCBiKSA9PiBhICE9PSBudWxsICYmIGIgIT09IG51bGwgJiYgYS5kYXRhc2V0SW5kZXggPT09IGIuZGF0YXNldEluZGV4ICYmIGEuaW5kZXggPT09IGIuaW5kZXg7XG5cbmV4cG9ydCBjbGFzcyBMZWdlbmQgZXh0ZW5kcyBFbGVtZW50IHtcblxuICAvKipcblx0ICogQHBhcmFtIHt7IGN0eDogYW55OyBvcHRpb25zOiBhbnk7IGNoYXJ0OiBhbnk7IH19IGNvbmZpZ1xuXHQgKi9cbiAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2FkZGVkID0gZmFsc2U7XG5cbiAgICAvLyBDb250YWlucyBoaXQgYm94ZXMgZm9yIGVhY2ggZGF0YXNldCAoaW4gZGF0YXNldCBvcmRlcilcbiAgICB0aGlzLmxlZ2VuZEhpdEJveGVzID0gW107XG5cbiAgICAvKipcbiBcdFx0ICogQHByaXZhdGVcbiBcdFx0ICovXG4gICAgdGhpcy5faG92ZXJlZEl0ZW0gPSBudWxsO1xuXG4gICAgLy8gQXJlIHdlIGluIGRvdWdobnV0IG1vZGUgd2hpY2ggaGFzIGEgZGlmZmVyZW50IGRhdGEgdHlwZVxuICAgIHRoaXMuZG91Z2hudXRNb2RlID0gZmFsc2U7XG5cbiAgICB0aGlzLmNoYXJ0ID0gY29uZmlnLmNoYXJ0O1xuICAgIHRoaXMub3B0aW9ucyA9IGNvbmZpZy5vcHRpb25zO1xuICAgIHRoaXMuY3R4ID0gY29uZmlnLmN0eDtcbiAgICB0aGlzLmxlZ2VuZEl0ZW1zID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY29sdW1uU2l6ZXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5saW5lV2lkdGhzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWF4SGVpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWF4V2lkdGggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy50b3AgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5ib3R0b20gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sZWZ0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMucmlnaHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5oZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy53aWR0aCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9tYXJnaW5zID0gdW5kZWZpbmVkO1xuICAgIHRoaXMucG9zaXRpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy53ZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5mdWxsU2l6ZSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHVwZGF0ZShtYXhXaWR0aCwgbWF4SGVpZ2h0LCBtYXJnaW5zKSB7XG4gICAgdGhpcy5tYXhXaWR0aCA9IG1heFdpZHRoO1xuICAgIHRoaXMubWF4SGVpZ2h0ID0gbWF4SGVpZ2h0O1xuICAgIHRoaXMuX21hcmdpbnMgPSBtYXJnaW5zO1xuXG4gICAgdGhpcy5zZXREaW1lbnNpb25zKCk7XG4gICAgdGhpcy5idWlsZExhYmVscygpO1xuICAgIHRoaXMuZml0KCk7XG4gIH1cblxuICBzZXREaW1lbnNpb25zKCkge1xuICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICB0aGlzLndpZHRoID0gdGhpcy5tYXhXaWR0aDtcbiAgICAgIHRoaXMubGVmdCA9IHRoaXMuX21hcmdpbnMubGVmdDtcbiAgICAgIHRoaXMucmlnaHQgPSB0aGlzLndpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhlaWdodCA9IHRoaXMubWF4SGVpZ2h0O1xuICAgICAgdGhpcy50b3AgPSB0aGlzLl9tYXJnaW5zLnRvcDtcbiAgICAgIHRoaXMuYm90dG9tID0gdGhpcy5oZWlnaHQ7XG4gICAgfVxuICB9XG5cbiAgYnVpbGRMYWJlbHMoKSB7XG4gICAgY29uc3QgbGFiZWxPcHRzID0gdGhpcy5vcHRpb25zLmxhYmVscyB8fCB7fTtcbiAgICBsZXQgbGVnZW5kSXRlbXMgPSBjYWxsKGxhYmVsT3B0cy5nZW5lcmF0ZUxhYmVscywgW3RoaXMuY2hhcnRdLCB0aGlzKSB8fCBbXTtcblxuICAgIGlmIChsYWJlbE9wdHMuZmlsdGVyKSB7XG4gICAgICBsZWdlbmRJdGVtcyA9IGxlZ2VuZEl0ZW1zLmZpbHRlcigoaXRlbSkgPT4gbGFiZWxPcHRzLmZpbHRlcihpdGVtLCB0aGlzLmNoYXJ0LmRhdGEpKTtcbiAgICB9XG5cbiAgICBpZiAobGFiZWxPcHRzLnNvcnQpIHtcbiAgICAgIGxlZ2VuZEl0ZW1zID0gbGVnZW5kSXRlbXMuc29ydCgoYSwgYikgPT4gbGFiZWxPcHRzLnNvcnQoYSwgYiwgdGhpcy5jaGFydC5kYXRhKSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5yZXZlcnNlKSB7XG4gICAgICBsZWdlbmRJdGVtcy5yZXZlcnNlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5sZWdlbmRJdGVtcyA9IGxlZ2VuZEl0ZW1zO1xuICB9XG5cbiAgZml0KCkge1xuICAgIGNvbnN0IHtvcHRpb25zLCBjdHh9ID0gdGhpcztcblxuICAgIC8vIFRoZSBsZWdlbmQgbWF5IG5vdCBiZSBkaXNwbGF5ZWQgZm9yIGEgdmFyaWV0eSBvZiByZWFzb25zIGluY2x1ZGluZ1xuICAgIC8vIHRoZSBmYWN0IHRoYXQgdGhlIGRlZmF1bHRzIGdvdCBzZXQgdG8gYGZhbHNlYC5cbiAgICAvLyBXaGVuIHRoZSBsZWdlbmQgaXMgbm90IGRpc3BsYXllZCwgdGhlcmUgYXJlIG5vIGd1YXJhbnRlZXMgdGhhdCB0aGUgb3B0aW9uc1xuICAgIC8vIGFyZSBjb3JyZWN0bHkgZm9ybWF0dGVkIHNvIHdlIG5lZWQgdG8gYmFpbCBvdXQgYXMgZWFybHkgYXMgcG9zc2libGUuXG4gICAgaWYgKCFvcHRpb25zLmRpc3BsYXkpIHtcbiAgICAgIHRoaXMud2lkdGggPSB0aGlzLmhlaWdodCA9IDA7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbGFiZWxPcHRzID0gb3B0aW9ucy5sYWJlbHM7XG4gICAgY29uc3QgbGFiZWxGb250ID0gdG9Gb250KGxhYmVsT3B0cy5mb250KTtcbiAgICBjb25zdCBmb250U2l6ZSA9IGxhYmVsRm9udC5zaXplO1xuICAgIGNvbnN0IHRpdGxlSGVpZ2h0ID0gdGhpcy5fY29tcHV0ZVRpdGxlSGVpZ2h0KCk7XG4gICAgY29uc3Qge2JveFdpZHRoLCBpdGVtSGVpZ2h0fSA9IGdldEJveFNpemUobGFiZWxPcHRzLCBmb250U2l6ZSk7XG5cbiAgICBsZXQgd2lkdGgsIGhlaWdodDtcblxuICAgIGN0eC5mb250ID0gbGFiZWxGb250LnN0cmluZztcblxuICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICB3aWR0aCA9IHRoaXMubWF4V2lkdGg7IC8vIGZpbGwgYWxsIHRoZSB3aWR0aFxuICAgICAgaGVpZ2h0ID0gdGhpcy5fZml0Um93cyh0aXRsZUhlaWdodCwgZm9udFNpemUsIGJveFdpZHRoLCBpdGVtSGVpZ2h0KSArIDEwO1xuICAgIH0gZWxzZSB7XG4gICAgICBoZWlnaHQgPSB0aGlzLm1heEhlaWdodDsgLy8gZmlsbCBhbGwgdGhlIGhlaWdodFxuICAgICAgd2lkdGggPSB0aGlzLl9maXRDb2xzKHRpdGxlSGVpZ2h0LCBsYWJlbEZvbnQsIGJveFdpZHRoLCBpdGVtSGVpZ2h0KSArIDEwO1xuICAgIH1cblxuICAgIHRoaXMud2lkdGggPSBNYXRoLm1pbih3aWR0aCwgb3B0aW9ucy5tYXhXaWR0aCB8fCB0aGlzLm1heFdpZHRoKTtcbiAgICB0aGlzLmhlaWdodCA9IE1hdGgubWluKGhlaWdodCwgb3B0aW9ucy5tYXhIZWlnaHQgfHwgdGhpcy5tYXhIZWlnaHQpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZml0Um93cyh0aXRsZUhlaWdodCwgZm9udFNpemUsIGJveFdpZHRoLCBpdGVtSGVpZ2h0KSB7XG4gICAgY29uc3Qge2N0eCwgbWF4V2lkdGgsIG9wdGlvbnM6IHtsYWJlbHM6IHtwYWRkaW5nfX19ID0gdGhpcztcbiAgICBjb25zdCBoaXRib3hlcyA9IHRoaXMubGVnZW5kSGl0Qm94ZXMgPSBbXTtcbiAgICAvLyBXaWR0aCBvZiBlYWNoIGxpbmUgb2YgbGVnZW5kIGJveGVzLiBMYWJlbHMgd3JhcCBvbnRvIG11bHRpcGxlIGxpbmVzIHdoZW4gdGhlcmUgYXJlIHRvbyBtYW55IHRvIGZpdCBvbiBvbmVcbiAgICBjb25zdCBsaW5lV2lkdGhzID0gdGhpcy5saW5lV2lkdGhzID0gWzBdO1xuICAgIGNvbnN0IGxpbmVIZWlnaHQgPSBpdGVtSGVpZ2h0ICsgcGFkZGluZztcbiAgICBsZXQgdG90YWxIZWlnaHQgPSB0aXRsZUhlaWdodDtcblxuICAgIGN0eC50ZXh0QWxpZ24gPSAnbGVmdCc7XG4gICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuXG4gICAgbGV0IHJvdyA9IC0xO1xuICAgIGxldCB0b3AgPSAtbGluZUhlaWdodDtcbiAgICB0aGlzLmxlZ2VuZEl0ZW1zLmZvckVhY2goKGxlZ2VuZEl0ZW0sIGkpID0+IHtcbiAgICAgIGNvbnN0IGl0ZW1XaWR0aCA9IGJveFdpZHRoICsgKGZvbnRTaXplIC8gMikgKyBjdHgubWVhc3VyZVRleHQobGVnZW5kSXRlbS50ZXh0KS53aWR0aDtcblxuICAgICAgaWYgKGkgPT09IDAgfHwgbGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aCAtIDFdICsgaXRlbVdpZHRoICsgMiAqIHBhZGRpbmcgPiBtYXhXaWR0aCkge1xuICAgICAgICB0b3RhbEhlaWdodCArPSBsaW5lSGVpZ2h0O1xuICAgICAgICBsaW5lV2lkdGhzW2xpbmVXaWR0aHMubGVuZ3RoIC0gKGkgPiAwID8gMCA6IDEpXSA9IDA7XG4gICAgICAgIHRvcCArPSBsaW5lSGVpZ2h0O1xuICAgICAgICByb3crKztcbiAgICAgIH1cblxuICAgICAgaGl0Ym94ZXNbaV0gPSB7bGVmdDogMCwgdG9wLCByb3csIHdpZHRoOiBpdGVtV2lkdGgsIGhlaWdodDogaXRlbUhlaWdodH07XG5cbiAgICAgIGxpbmVXaWR0aHNbbGluZVdpZHRocy5sZW5ndGggLSAxXSArPSBpdGVtV2lkdGggKyBwYWRkaW5nO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRvdGFsSGVpZ2h0O1xuICB9XG5cbiAgX2ZpdENvbHModGl0bGVIZWlnaHQsIGxhYmVsRm9udCwgYm94V2lkdGgsIF9pdGVtSGVpZ2h0KSB7XG4gICAgY29uc3Qge2N0eCwgbWF4SGVpZ2h0LCBvcHRpb25zOiB7bGFiZWxzOiB7cGFkZGluZ319fSA9IHRoaXM7XG4gICAgY29uc3QgaGl0Ym94ZXMgPSB0aGlzLmxlZ2VuZEhpdEJveGVzID0gW107XG4gICAgY29uc3QgY29sdW1uU2l6ZXMgPSB0aGlzLmNvbHVtblNpemVzID0gW107XG4gICAgY29uc3QgaGVpZ2h0TGltaXQgPSBtYXhIZWlnaHQgLSB0aXRsZUhlaWdodDtcblxuICAgIGxldCB0b3RhbFdpZHRoID0gcGFkZGluZztcbiAgICBsZXQgY3VycmVudENvbFdpZHRoID0gMDtcbiAgICBsZXQgY3VycmVudENvbEhlaWdodCA9IDA7XG5cbiAgICBsZXQgbGVmdCA9IDA7XG4gICAgbGV0IGNvbCA9IDA7XG5cbiAgICB0aGlzLmxlZ2VuZEl0ZW1zLmZvckVhY2goKGxlZ2VuZEl0ZW0sIGkpID0+IHtcbiAgICAgIGNvbnN0IHtpdGVtV2lkdGgsIGl0ZW1IZWlnaHR9ID0gY2FsY3VsYXRlSXRlbVNpemUoYm94V2lkdGgsIGxhYmVsRm9udCwgY3R4LCBsZWdlbmRJdGVtLCBfaXRlbUhlaWdodCk7XG5cbiAgICAgIC8vIElmIHRvbyB0YWxsLCBnbyB0byBuZXcgY29sdW1uXG4gICAgICBpZiAoaSA+IDAgJiYgY3VycmVudENvbEhlaWdodCArIGl0ZW1IZWlnaHQgKyAyICogcGFkZGluZyA+IGhlaWdodExpbWl0KSB7XG4gICAgICAgIHRvdGFsV2lkdGggKz0gY3VycmVudENvbFdpZHRoICsgcGFkZGluZztcbiAgICAgICAgY29sdW1uU2l6ZXMucHVzaCh7d2lkdGg6IGN1cnJlbnRDb2xXaWR0aCwgaGVpZ2h0OiBjdXJyZW50Q29sSGVpZ2h0fSk7IC8vIHByZXZpb3VzIGNvbHVtbiBzaXplXG4gICAgICAgIGxlZnQgKz0gY3VycmVudENvbFdpZHRoICsgcGFkZGluZztcbiAgICAgICAgY29sKys7XG4gICAgICAgIGN1cnJlbnRDb2xXaWR0aCA9IGN1cnJlbnRDb2xIZWlnaHQgPSAwO1xuICAgICAgfVxuXG4gICAgICAvLyBTdG9yZSB0aGUgaGl0Ym94IHdpZHRoIGFuZCBoZWlnaHQgaGVyZS4gRmluYWwgcG9zaXRpb24gd2lsbCBiZSB1cGRhdGVkIGluIGBkcmF3YFxuICAgICAgaGl0Ym94ZXNbaV0gPSB7bGVmdCwgdG9wOiBjdXJyZW50Q29sSGVpZ2h0LCBjb2wsIHdpZHRoOiBpdGVtV2lkdGgsIGhlaWdodDogaXRlbUhlaWdodH07XG5cbiAgICAgIC8vIEdldCBtYXggd2lkdGhcbiAgICAgIGN1cnJlbnRDb2xXaWR0aCA9IE1hdGgubWF4KGN1cnJlbnRDb2xXaWR0aCwgaXRlbVdpZHRoKTtcbiAgICAgIGN1cnJlbnRDb2xIZWlnaHQgKz0gaXRlbUhlaWdodCArIHBhZGRpbmc7XG4gICAgfSk7XG5cbiAgICB0b3RhbFdpZHRoICs9IGN1cnJlbnRDb2xXaWR0aDtcbiAgICBjb2x1bW5TaXplcy5wdXNoKHt3aWR0aDogY3VycmVudENvbFdpZHRoLCBoZWlnaHQ6IGN1cnJlbnRDb2xIZWlnaHR9KTsgLy8gcHJldmlvdXMgY29sdW1uIHNpemVcblxuICAgIHJldHVybiB0b3RhbFdpZHRoO1xuICB9XG5cbiAgYWRqdXN0SGl0Qm94ZXMoKSB7XG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuZGlzcGxheSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0aXRsZUhlaWdodCA9IHRoaXMuX2NvbXB1dGVUaXRsZUhlaWdodCgpO1xuICAgIGNvbnN0IHtsZWdlbmRIaXRCb3hlczogaGl0Ym94ZXMsIG9wdGlvbnM6IHthbGlnbiwgbGFiZWxzOiB7cGFkZGluZ30sIHJ0bH19ID0gdGhpcztcbiAgICBjb25zdCBydGxIZWxwZXIgPSBnZXRSdGxBZGFwdGVyKHJ0bCwgdGhpcy5sZWZ0LCB0aGlzLndpZHRoKTtcbiAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgbGV0IHJvdyA9IDA7XG4gICAgICBsZXQgbGVmdCA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0aGlzLmxlZnQgKyBwYWRkaW5nLCB0aGlzLnJpZ2h0IC0gdGhpcy5saW5lV2lkdGhzW3Jvd10pO1xuICAgICAgZm9yIChjb25zdCBoaXRib3ggb2YgaGl0Ym94ZXMpIHtcbiAgICAgICAgaWYgKHJvdyAhPT0gaGl0Ym94LnJvdykge1xuICAgICAgICAgIHJvdyA9IGhpdGJveC5yb3c7XG4gICAgICAgICAgbGVmdCA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0aGlzLmxlZnQgKyBwYWRkaW5nLCB0aGlzLnJpZ2h0IC0gdGhpcy5saW5lV2lkdGhzW3Jvd10pO1xuICAgICAgICB9XG4gICAgICAgIGhpdGJveC50b3AgKz0gdGhpcy50b3AgKyB0aXRsZUhlaWdodCArIHBhZGRpbmc7XG4gICAgICAgIGhpdGJveC5sZWZ0ID0gcnRsSGVscGVyLmxlZnRGb3JMdHIocnRsSGVscGVyLngobGVmdCksIGhpdGJveC53aWR0aCk7XG4gICAgICAgIGxlZnQgKz0gaGl0Ym94LndpZHRoICsgcGFkZGluZztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGNvbCA9IDA7XG4gICAgICBsZXQgdG9wID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIHRoaXMudG9wICsgdGl0bGVIZWlnaHQgKyBwYWRkaW5nLCB0aGlzLmJvdHRvbSAtIHRoaXMuY29sdW1uU2l6ZXNbY29sXS5oZWlnaHQpO1xuICAgICAgZm9yIChjb25zdCBoaXRib3ggb2YgaGl0Ym94ZXMpIHtcbiAgICAgICAgaWYgKGhpdGJveC5jb2wgIT09IGNvbCkge1xuICAgICAgICAgIGNvbCA9IGhpdGJveC5jb2w7XG4gICAgICAgICAgdG9wID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIHRoaXMudG9wICsgdGl0bGVIZWlnaHQgKyBwYWRkaW5nLCB0aGlzLmJvdHRvbSAtIHRoaXMuY29sdW1uU2l6ZXNbY29sXS5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIGhpdGJveC50b3AgPSB0b3A7XG4gICAgICAgIGhpdGJveC5sZWZ0ICs9IHRoaXMubGVmdCArIHBhZGRpbmc7XG4gICAgICAgIGhpdGJveC5sZWZ0ID0gcnRsSGVscGVyLmxlZnRGb3JMdHIocnRsSGVscGVyLngoaGl0Ym94LmxlZnQpLCBoaXRib3gud2lkdGgpO1xuICAgICAgICB0b3AgKz0gaGl0Ym94LmhlaWdodCArIHBhZGRpbmc7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaXNIb3Jpem9udGFsKCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMucG9zaXRpb24gPT09ICd0b3AnIHx8IHRoaXMub3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2JvdHRvbSc7XG4gIH1cblxuICBkcmF3KCkge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZGlzcGxheSkge1xuICAgICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgICBjbGlwQXJlYShjdHgsIHRoaXMpO1xuXG4gICAgICB0aGlzLl9kcmF3KCk7XG5cbiAgICAgIHVuY2xpcEFyZWEoY3R4KTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9kcmF3KCkge1xuICAgIGNvbnN0IHtvcHRpb25zOiBvcHRzLCBjb2x1bW5TaXplcywgbGluZVdpZHRocywgY3R4fSA9IHRoaXM7XG4gICAgY29uc3Qge2FsaWduLCBsYWJlbHM6IGxhYmVsT3B0c30gPSBvcHRzO1xuICAgIGNvbnN0IGRlZmF1bHRDb2xvciA9IGRlZmF1bHRzLmNvbG9yO1xuICAgIGNvbnN0IHJ0bEhlbHBlciA9IGdldFJ0bEFkYXB0ZXIob3B0cy5ydGwsIHRoaXMubGVmdCwgdGhpcy53aWR0aCk7XG4gICAgY29uc3QgbGFiZWxGb250ID0gdG9Gb250KGxhYmVsT3B0cy5mb250KTtcbiAgICBjb25zdCB7cGFkZGluZ30gPSBsYWJlbE9wdHM7XG4gICAgY29uc3QgZm9udFNpemUgPSBsYWJlbEZvbnQuc2l6ZTtcbiAgICBjb25zdCBoYWxmRm9udFNpemUgPSBmb250U2l6ZSAvIDI7XG4gICAgbGV0IGN1cnNvcjtcblxuICAgIHRoaXMuZHJhd1RpdGxlKCk7XG5cbiAgICAvLyBDYW52YXMgc2V0dXBcbiAgICBjdHgudGV4dEFsaWduID0gcnRsSGVscGVyLnRleHRBbGlnbignbGVmdCcpO1xuICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcbiAgICBjdHgubGluZVdpZHRoID0gMC41O1xuICAgIGN0eC5mb250ID0gbGFiZWxGb250LnN0cmluZztcblxuICAgIGNvbnN0IHtib3hXaWR0aCwgYm94SGVpZ2h0LCBpdGVtSGVpZ2h0fSA9IGdldEJveFNpemUobGFiZWxPcHRzLCBmb250U2l6ZSk7XG5cbiAgICAvLyBjdXJyZW50IHBvc2l0aW9uXG4gICAgY29uc3QgZHJhd0xlZ2VuZEJveCA9IGZ1bmN0aW9uKHgsIHksIGxlZ2VuZEl0ZW0pIHtcbiAgICAgIGlmIChpc05hTihib3hXaWR0aCkgfHwgYm94V2lkdGggPD0gMCB8fCBpc05hTihib3hIZWlnaHQpIHx8IGJveEhlaWdodCA8IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTZXQgdGhlIGN0eCBmb3IgdGhlIGJveFxuICAgICAgY3R4LnNhdmUoKTtcblxuICAgICAgY29uc3QgbGluZVdpZHRoID0gdmFsdWVPckRlZmF1bHQobGVnZW5kSXRlbS5saW5lV2lkdGgsIDEpO1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IHZhbHVlT3JEZWZhdWx0KGxlZ2VuZEl0ZW0uZmlsbFN0eWxlLCBkZWZhdWx0Q29sb3IpO1xuICAgICAgY3R4LmxpbmVDYXAgPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmxpbmVDYXAsICdidXR0Jyk7XG4gICAgICBjdHgubGluZURhc2hPZmZzZXQgPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmxpbmVEYXNoT2Zmc2V0LCAwKTtcbiAgICAgIGN0eC5saW5lSm9pbiA9IHZhbHVlT3JEZWZhdWx0KGxlZ2VuZEl0ZW0ubGluZUpvaW4sICdtaXRlcicpO1xuICAgICAgY3R4LmxpbmVXaWR0aCA9IGxpbmVXaWR0aDtcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IHZhbHVlT3JEZWZhdWx0KGxlZ2VuZEl0ZW0uc3Ryb2tlU3R5bGUsIGRlZmF1bHRDb2xvcik7XG5cbiAgICAgIGN0eC5zZXRMaW5lRGFzaCh2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmxpbmVEYXNoLCBbXSkpO1xuXG4gICAgICBpZiAobGFiZWxPcHRzLnVzZVBvaW50U3R5bGUpIHtcbiAgICAgICAgLy8gUmVjYWxjdWxhdGUgeCBhbmQgeSBmb3IgZHJhd1BvaW50KCkgYmVjYXVzZSBpdHMgZXhwZWN0aW5nXG4gICAgICAgIC8vIHggYW5kIHkgdG8gYmUgY2VudGVyIG9mIGZpZ3VyZSAoaW5zdGVhZCBvZiB0b3AgbGVmdClcbiAgICAgICAgY29uc3QgZHJhd09wdGlvbnMgPSB7XG4gICAgICAgICAgcmFkaXVzOiBib3hIZWlnaHQgKiBNYXRoLlNRUlQyIC8gMixcbiAgICAgICAgICBwb2ludFN0eWxlOiBsZWdlbmRJdGVtLnBvaW50U3R5bGUsXG4gICAgICAgICAgcm90YXRpb246IGxlZ2VuZEl0ZW0ucm90YXRpb24sXG4gICAgICAgICAgYm9yZGVyV2lkdGg6IGxpbmVXaWR0aFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjZW50ZXJYID0gcnRsSGVscGVyLnhQbHVzKHgsIGJveFdpZHRoIC8gMik7XG4gICAgICAgIGNvbnN0IGNlbnRlclkgPSB5ICsgaGFsZkZvbnRTaXplO1xuXG4gICAgICAgIC8vIERyYXcgcG9pbnRTdHlsZSBhcyBsZWdlbmQgc3ltYm9sXG4gICAgICAgIGRyYXdQb2ludExlZ2VuZChjdHgsIGRyYXdPcHRpb25zLCBjZW50ZXJYLCBjZW50ZXJZLCBsYWJlbE9wdHMucG9pbnRTdHlsZVdpZHRoICYmIGJveFdpZHRoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIERyYXcgYm94IGFzIGxlZ2VuZCBzeW1ib2xcbiAgICAgICAgLy8gQWRqdXN0IHBvc2l0aW9uIHdoZW4gYm94SGVpZ2h0IDwgZm9udFNpemUgKHdhbnQgaXQgY2VudGVyZWQpXG4gICAgICAgIGNvbnN0IHlCb3hUb3AgPSB5ICsgTWF0aC5tYXgoKGZvbnRTaXplIC0gYm94SGVpZ2h0KSAvIDIsIDApO1xuICAgICAgICBjb25zdCB4Qm94TGVmdCA9IHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHgsIGJveFdpZHRoKTtcbiAgICAgICAgY29uc3QgYm9yZGVyUmFkaXVzID0gdG9UUkJMQ29ybmVycyhsZWdlbmRJdGVtLmJvcmRlclJhZGl1cyk7XG5cbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuXG4gICAgICAgIGlmIChPYmplY3QudmFsdWVzKGJvcmRlclJhZGl1cykuc29tZSh2ID0+IHYgIT09IDApKSB7XG4gICAgICAgICAgYWRkUm91bmRlZFJlY3RQYXRoKGN0eCwge1xuICAgICAgICAgICAgeDogeEJveExlZnQsXG4gICAgICAgICAgICB5OiB5Qm94VG9wLFxuICAgICAgICAgICAgdzogYm94V2lkdGgsXG4gICAgICAgICAgICBoOiBib3hIZWlnaHQsXG4gICAgICAgICAgICByYWRpdXM6IGJvcmRlclJhZGl1cyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdHgucmVjdCh4Qm94TGVmdCwgeUJveFRvcCwgYm94V2lkdGgsIGJveEhlaWdodCk7XG4gICAgICAgIH1cblxuICAgICAgICBjdHguZmlsbCgpO1xuICAgICAgICBpZiAobGluZVdpZHRoICE9PSAwKSB7XG4gICAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGZpbGxUZXh0ID0gZnVuY3Rpb24oeCwgeSwgbGVnZW5kSXRlbSkge1xuICAgICAgcmVuZGVyVGV4dChjdHgsIGxlZ2VuZEl0ZW0udGV4dCwgeCwgeSArIChpdGVtSGVpZ2h0IC8gMiksIGxhYmVsRm9udCwge1xuICAgICAgICBzdHJpa2V0aHJvdWdoOiBsZWdlbmRJdGVtLmhpZGRlbixcbiAgICAgICAgdGV4dEFsaWduOiBydGxIZWxwZXIudGV4dEFsaWduKGxlZ2VuZEl0ZW0udGV4dEFsaWduKVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEhvcml6b250YWxcbiAgICBjb25zdCBpc0hvcml6b250YWwgPSB0aGlzLmlzSG9yaXpvbnRhbCgpO1xuICAgIGNvbnN0IHRpdGxlSGVpZ2h0ID0gdGhpcy5fY29tcHV0ZVRpdGxlSGVpZ2h0KCk7XG4gICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgY3Vyc29yID0ge1xuICAgICAgICB4OiBfYWxpZ25TdGFydEVuZChhbGlnbiwgdGhpcy5sZWZ0ICsgcGFkZGluZywgdGhpcy5yaWdodCAtIGxpbmVXaWR0aHNbMF0pLFxuICAgICAgICB5OiB0aGlzLnRvcCArIHBhZGRpbmcgKyB0aXRsZUhlaWdodCxcbiAgICAgICAgbGluZTogMFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3Vyc29yID0ge1xuICAgICAgICB4OiB0aGlzLmxlZnQgKyBwYWRkaW5nLFxuICAgICAgICB5OiBfYWxpZ25TdGFydEVuZChhbGlnbiwgdGhpcy50b3AgKyB0aXRsZUhlaWdodCArIHBhZGRpbmcsIHRoaXMuYm90dG9tIC0gY29sdW1uU2l6ZXNbMF0uaGVpZ2h0KSxcbiAgICAgICAgbGluZTogMFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBvdmVycmlkZVRleHREaXJlY3Rpb24odGhpcy5jdHgsIG9wdHMudGV4dERpcmVjdGlvbik7XG5cbiAgICBjb25zdCBsaW5lSGVpZ2h0ID0gaXRlbUhlaWdodCArIHBhZGRpbmc7XG4gICAgdGhpcy5sZWdlbmRJdGVtcy5mb3JFYWNoKChsZWdlbmRJdGVtLCBpKSA9PiB7XG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSBsZWdlbmRJdGVtLmZvbnRDb2xvcjsgLy8gZm9yIHN0cmlrZXRocm91Z2ggZWZmZWN0XG4gICAgICBjdHguZmlsbFN0eWxlID0gbGVnZW5kSXRlbS5mb250Q29sb3I7IC8vIHJlbmRlciBpbiBjb3JyZWN0IGNvbG91clxuXG4gICAgICBjb25zdCB0ZXh0V2lkdGggPSBjdHgubWVhc3VyZVRleHQobGVnZW5kSXRlbS50ZXh0KS53aWR0aDtcbiAgICAgIGNvbnN0IHRleHRBbGlnbiA9IHJ0bEhlbHBlci50ZXh0QWxpZ24obGVnZW5kSXRlbS50ZXh0QWxpZ24gfHwgKGxlZ2VuZEl0ZW0udGV4dEFsaWduID0gbGFiZWxPcHRzLnRleHRBbGlnbikpO1xuICAgICAgY29uc3Qgd2lkdGggPSBib3hXaWR0aCArIGhhbGZGb250U2l6ZSArIHRleHRXaWR0aDtcbiAgICAgIGxldCB4ID0gY3Vyc29yLng7XG4gICAgICBsZXQgeSA9IGN1cnNvci55O1xuXG4gICAgICBydGxIZWxwZXIuc2V0V2lkdGgodGhpcy53aWR0aCk7XG5cbiAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgaWYgKGkgPiAwICYmIHggKyB3aWR0aCArIHBhZGRpbmcgPiB0aGlzLnJpZ2h0KSB7XG4gICAgICAgICAgeSA9IGN1cnNvci55ICs9IGxpbmVIZWlnaHQ7XG4gICAgICAgICAgY3Vyc29yLmxpbmUrKztcbiAgICAgICAgICB4ID0gY3Vyc29yLnggPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgdGhpcy5sZWZ0ICsgcGFkZGluZywgdGhpcy5yaWdodCAtIGxpbmVXaWR0aHNbY3Vyc29yLmxpbmVdKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpID4gMCAmJiB5ICsgbGluZUhlaWdodCA+IHRoaXMuYm90dG9tKSB7XG4gICAgICAgIHggPSBjdXJzb3IueCA9IHggKyBjb2x1bW5TaXplc1tjdXJzb3IubGluZV0ud2lkdGggKyBwYWRkaW5nO1xuICAgICAgICBjdXJzb3IubGluZSsrO1xuICAgICAgICB5ID0gY3Vyc29yLnkgPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgdGhpcy50b3AgKyB0aXRsZUhlaWdodCArIHBhZGRpbmcsIHRoaXMuYm90dG9tIC0gY29sdW1uU2l6ZXNbY3Vyc29yLmxpbmVdLmhlaWdodCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlYWxYID0gcnRsSGVscGVyLngoeCk7XG5cbiAgICAgIGRyYXdMZWdlbmRCb3gocmVhbFgsIHksIGxlZ2VuZEl0ZW0pO1xuXG4gICAgICB4ID0gX3RleHRYKHRleHRBbGlnbiwgeCArIGJveFdpZHRoICsgaGFsZkZvbnRTaXplLCBpc0hvcml6b250YWwgPyB4ICsgd2lkdGggOiB0aGlzLnJpZ2h0LCBvcHRzLnJ0bCk7XG5cbiAgICAgIC8vIEZpbGwgdGhlIGFjdHVhbCBsYWJlbFxuICAgICAgZmlsbFRleHQocnRsSGVscGVyLngoeCksIHksIGxlZ2VuZEl0ZW0pO1xuXG4gICAgICBpZiAoaXNIb3Jpem9udGFsKSB7XG4gICAgICAgIGN1cnNvci54ICs9IHdpZHRoICsgcGFkZGluZztcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxlZ2VuZEl0ZW0udGV4dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgZm9udExpbmVIZWlnaHQgPSBsYWJlbEZvbnQubGluZUhlaWdodDtcbiAgICAgICAgY3Vyc29yLnkgKz0gY2FsY3VsYXRlTGVnZW5kSXRlbUhlaWdodChsZWdlbmRJdGVtLCBmb250TGluZUhlaWdodCkgKyBwYWRkaW5nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3Vyc29yLnkgKz0gbGluZUhlaWdodDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJlc3RvcmVUZXh0RGlyZWN0aW9uKHRoaXMuY3R4LCBvcHRzLnRleHREaXJlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGRyYXdUaXRsZSgpIHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHRpdGxlT3B0cyA9IG9wdHMudGl0bGU7XG4gICAgY29uc3QgdGl0bGVGb250ID0gdG9Gb250KHRpdGxlT3B0cy5mb250KTtcbiAgICBjb25zdCB0aXRsZVBhZGRpbmcgPSB0b1BhZGRpbmcodGl0bGVPcHRzLnBhZGRpbmcpO1xuXG4gICAgaWYgKCF0aXRsZU9wdHMuZGlzcGxheSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJ0bEhlbHBlciA9IGdldFJ0bEFkYXB0ZXIob3B0cy5ydGwsIHRoaXMubGVmdCwgdGhpcy53aWR0aCk7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3QgcG9zaXRpb24gPSB0aXRsZU9wdHMucG9zaXRpb247XG4gICAgY29uc3QgaGFsZkZvbnRTaXplID0gdGl0bGVGb250LnNpemUgLyAyO1xuICAgIGNvbnN0IHRvcFBhZGRpbmdQbHVzSGFsZkZvbnRTaXplID0gdGl0bGVQYWRkaW5nLnRvcCArIGhhbGZGb250U2l6ZTtcbiAgICBsZXQgeTtcblxuICAgIC8vIFRoZXNlIGRlZmF1bHRzIGFyZSB1c2VkIHdoZW4gdGhlIGxlZ2VuZCBpcyB2ZXJ0aWNhbC5cbiAgICAvLyBXaGVuIGhvcml6b250YWwsIHRoZXkgYXJlIGNvbXB1dGVkIGJlbG93LlxuICAgIGxldCBsZWZ0ID0gdGhpcy5sZWZ0O1xuICAgIGxldCBtYXhXaWR0aCA9IHRoaXMud2lkdGg7XG5cbiAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgLy8gTW92ZSBsZWZ0IC8gcmlnaHQgc28gdGhhdCB0aGUgdGl0bGUgaXMgYWJvdmUgdGhlIGxlZ2VuZCBsaW5lc1xuICAgICAgbWF4V2lkdGggPSBNYXRoLm1heCguLi50aGlzLmxpbmVXaWR0aHMpO1xuICAgICAgeSA9IHRoaXMudG9wICsgdG9wUGFkZGluZ1BsdXNIYWxmRm9udFNpemU7XG4gICAgICBsZWZ0ID0gX2FsaWduU3RhcnRFbmQob3B0cy5hbGlnbiwgbGVmdCwgdGhpcy5yaWdodCAtIG1heFdpZHRoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTW92ZSBkb3duIHNvIHRoYXQgdGhlIHRpdGxlIGlzIGFib3ZlIHRoZSBsZWdlbmQgc3RhY2sgaW4gZXZlcnkgYWxpZ25tZW50XG4gICAgICBjb25zdCBtYXhIZWlnaHQgPSB0aGlzLmNvbHVtblNpemVzLnJlZHVjZSgoYWNjLCBzaXplKSA9PiBNYXRoLm1heChhY2MsIHNpemUuaGVpZ2h0KSwgMCk7XG4gICAgICB5ID0gdG9wUGFkZGluZ1BsdXNIYWxmRm9udFNpemUgKyBfYWxpZ25TdGFydEVuZChvcHRzLmFsaWduLCB0aGlzLnRvcCwgdGhpcy5ib3R0b20gLSBtYXhIZWlnaHQgLSBvcHRzLmxhYmVscy5wYWRkaW5nIC0gdGhpcy5fY29tcHV0ZVRpdGxlSGVpZ2h0KCkpO1xuICAgIH1cblxuICAgIC8vIE5vdyB0aGF0IHdlIGtub3cgdGhlIGxlZnQgZWRnZSBvZiB0aGUgaW5uZXIgbGVnZW5kIGJveCwgY29tcHV0ZSB0aGUgY29ycmVjdFxuICAgIC8vIFggY29vcmRpbmF0ZSBmcm9tIHRoZSB0aXRsZSBhbGlnbm1lbnRcbiAgICBjb25zdCB4ID0gX2FsaWduU3RhcnRFbmQocG9zaXRpb24sIGxlZnQsIGxlZnQgKyBtYXhXaWR0aCk7XG5cbiAgICAvLyBDYW52YXMgc2V0dXBcbiAgICBjdHgudGV4dEFsaWduID0gcnRsSGVscGVyLnRleHRBbGlnbihfdG9MZWZ0UmlnaHRDZW50ZXIocG9zaXRpb24pKTtcbiAgICBjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG4gICAgY3R4LnN0cm9rZVN0eWxlID0gdGl0bGVPcHRzLmNvbG9yO1xuICAgIGN0eC5maWxsU3R5bGUgPSB0aXRsZU9wdHMuY29sb3I7XG4gICAgY3R4LmZvbnQgPSB0aXRsZUZvbnQuc3RyaW5nO1xuXG4gICAgcmVuZGVyVGV4dChjdHgsIHRpdGxlT3B0cy50ZXh0LCB4LCB5LCB0aXRsZUZvbnQpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfY29tcHV0ZVRpdGxlSGVpZ2h0KCkge1xuICAgIGNvbnN0IHRpdGxlT3B0cyA9IHRoaXMub3B0aW9ucy50aXRsZTtcbiAgICBjb25zdCB0aXRsZUZvbnQgPSB0b0ZvbnQodGl0bGVPcHRzLmZvbnQpO1xuICAgIGNvbnN0IHRpdGxlUGFkZGluZyA9IHRvUGFkZGluZyh0aXRsZU9wdHMucGFkZGluZyk7XG4gICAgcmV0dXJuIHRpdGxlT3B0cy5kaXNwbGF5ID8gdGl0bGVGb250LmxpbmVIZWlnaHQgKyB0aXRsZVBhZGRpbmcuaGVpZ2h0IDogMDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldExlZ2VuZEl0ZW1BdCh4LCB5KSB7XG4gICAgbGV0IGksIGhpdEJveCwgbGg7XG5cbiAgICBpZiAoX2lzQmV0d2Vlbih4LCB0aGlzLmxlZnQsIHRoaXMucmlnaHQpXG4gICAgICAmJiBfaXNCZXR3ZWVuKHksIHRoaXMudG9wLCB0aGlzLmJvdHRvbSkpIHtcbiAgICAgIC8vIFNlZSBpZiB3ZSBhcmUgdG91Y2hpbmcgb25lIG9mIHRoZSBkYXRhc2V0IGJveGVzXG4gICAgICBsaCA9IHRoaXMubGVnZW5kSGl0Qm94ZXM7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGgubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaGl0Qm94ID0gbGhbaV07XG5cbiAgICAgICAgaWYgKF9pc0JldHdlZW4oeCwgaGl0Qm94LmxlZnQsIGhpdEJveC5sZWZ0ICsgaGl0Qm94LndpZHRoKVxuICAgICAgICAgICYmIF9pc0JldHdlZW4oeSwgaGl0Qm94LnRvcCwgaGl0Qm94LnRvcCArIGhpdEJveC5oZWlnaHQpKSB7XG4gICAgICAgICAgLy8gVG91Y2hpbmcgYW4gZWxlbWVudFxuICAgICAgICAgIHJldHVybiB0aGlzLmxlZ2VuZEl0ZW1zW2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcblx0ICogSGFuZGxlIGFuIGV2ZW50XG5cdCAqIEBwYXJhbSB7Q2hhcnRFdmVudH0gZSAtIFRoZSBldmVudCB0byBoYW5kbGVcblx0ICovXG4gIGhhbmRsZUV2ZW50KGUpIHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgIGlmICghaXNMaXN0ZW5lZChlLnR5cGUsIG9wdHMpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2hhcnQgZXZlbnQgYWxyZWFkeSBoYXMgcmVsYXRpdmUgcG9zaXRpb24gaW4gaXRcbiAgICBjb25zdCBob3ZlcmVkSXRlbSA9IHRoaXMuX2dldExlZ2VuZEl0ZW1BdChlLngsIGUueSk7XG5cbiAgICBpZiAoZS50eXBlID09PSAnbW91c2Vtb3ZlJyB8fCBlLnR5cGUgPT09ICdtb3VzZW91dCcpIHtcbiAgICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy5faG92ZXJlZEl0ZW07XG4gICAgICBjb25zdCBzYW1lSXRlbSA9IGl0ZW1zRXF1YWwocHJldmlvdXMsIGhvdmVyZWRJdGVtKTtcbiAgICAgIGlmIChwcmV2aW91cyAmJiAhc2FtZUl0ZW0pIHtcbiAgICAgICAgY2FsbChvcHRzLm9uTGVhdmUsIFtlLCBwcmV2aW91cywgdGhpc10sIHRoaXMpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9ob3ZlcmVkSXRlbSA9IGhvdmVyZWRJdGVtO1xuXG4gICAgICBpZiAoaG92ZXJlZEl0ZW0gJiYgIXNhbWVJdGVtKSB7XG4gICAgICAgIGNhbGwob3B0cy5vbkhvdmVyLCBbZSwgaG92ZXJlZEl0ZW0sIHRoaXNdLCB0aGlzKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGhvdmVyZWRJdGVtKSB7XG4gICAgICBjYWxsKG9wdHMub25DbGljaywgW2UsIGhvdmVyZWRJdGVtLCB0aGlzXSwgdGhpcyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZUl0ZW1TaXplKGJveFdpZHRoLCBsYWJlbEZvbnQsIGN0eCwgbGVnZW5kSXRlbSwgX2l0ZW1IZWlnaHQpIHtcbiAgY29uc3QgaXRlbVdpZHRoID0gY2FsY3VsYXRlSXRlbVdpZHRoKGxlZ2VuZEl0ZW0sIGJveFdpZHRoLCBsYWJlbEZvbnQsIGN0eCk7XG4gIGNvbnN0IGl0ZW1IZWlnaHQgPSBjYWxjdWxhdGVJdGVtSGVpZ2h0KF9pdGVtSGVpZ2h0LCBsZWdlbmRJdGVtLCBsYWJlbEZvbnQubGluZUhlaWdodCk7XG4gIHJldHVybiB7aXRlbVdpZHRoLCBpdGVtSGVpZ2h0fTtcbn1cblxuZnVuY3Rpb24gY2FsY3VsYXRlSXRlbVdpZHRoKGxlZ2VuZEl0ZW0sIGJveFdpZHRoLCBsYWJlbEZvbnQsIGN0eCkge1xuICBsZXQgbGVnZW5kSXRlbVRleHQgPSBsZWdlbmRJdGVtLnRleHQ7XG4gIGlmIChsZWdlbmRJdGVtVGV4dCAmJiB0eXBlb2YgbGVnZW5kSXRlbVRleHQgIT09ICdzdHJpbmcnKSB7XG4gICAgbGVnZW5kSXRlbVRleHQgPSBsZWdlbmRJdGVtVGV4dC5yZWR1Y2UoKGEsIGIpID0+IGEubGVuZ3RoID4gYi5sZW5ndGggPyBhIDogYik7XG4gIH1cbiAgcmV0dXJuIGJveFdpZHRoICsgKGxhYmVsRm9udC5zaXplIC8gMikgKyBjdHgubWVhc3VyZVRleHQobGVnZW5kSXRlbVRleHQpLndpZHRoO1xufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVJdGVtSGVpZ2h0KF9pdGVtSGVpZ2h0LCBsZWdlbmRJdGVtLCBmb250TGluZUhlaWdodCkge1xuICBsZXQgaXRlbUhlaWdodCA9IF9pdGVtSGVpZ2h0O1xuICBpZiAodHlwZW9mIGxlZ2VuZEl0ZW0udGV4dCAhPT0gJ3N0cmluZycpIHtcbiAgICBpdGVtSGVpZ2h0ID0gY2FsY3VsYXRlTGVnZW5kSXRlbUhlaWdodChsZWdlbmRJdGVtLCBmb250TGluZUhlaWdodCk7XG4gIH1cbiAgcmV0dXJuIGl0ZW1IZWlnaHQ7XG59XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZUxlZ2VuZEl0ZW1IZWlnaHQobGVnZW5kSXRlbSwgZm9udExpbmVIZWlnaHQpIHtcbiAgY29uc3QgbGFiZWxIZWlnaHQgPSBsZWdlbmRJdGVtLnRleHQgPyBsZWdlbmRJdGVtLnRleHQubGVuZ3RoIDogMDtcbiAgcmV0dXJuIGZvbnRMaW5lSGVpZ2h0ICogbGFiZWxIZWlnaHQ7XG59XG5cbmZ1bmN0aW9uIGlzTGlzdGVuZWQodHlwZSwgb3B0cykge1xuICBpZiAoKHR5cGUgPT09ICdtb3VzZW1vdmUnIHx8IHR5cGUgPT09ICdtb3VzZW91dCcpICYmIChvcHRzLm9uSG92ZXIgfHwgb3B0cy5vbkxlYXZlKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChvcHRzLm9uQ2xpY2sgJiYgKHR5cGUgPT09ICdjbGljaycgfHwgdHlwZSA9PT0gJ21vdXNldXAnKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGRlZmF1bHQge1xuICBpZDogJ2xlZ2VuZCcsXG5cbiAgLyoqXG5cdCAqIEZvciB0ZXN0c1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2VsZW1lbnQ6IExlZ2VuZCxcblxuICBzdGFydChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBsZWdlbmQgPSBjaGFydC5sZWdlbmQgPSBuZXcgTGVnZW5kKHtjdHg6IGNoYXJ0LmN0eCwgb3B0aW9ucywgY2hhcnR9KTtcbiAgICBsYXlvdXRzLmNvbmZpZ3VyZShjaGFydCwgbGVnZW5kLCBvcHRpb25zKTtcbiAgICBsYXlvdXRzLmFkZEJveChjaGFydCwgbGVnZW5kKTtcbiAgfSxcblxuICBzdG9wKGNoYXJ0KSB7XG4gICAgbGF5b3V0cy5yZW1vdmVCb3goY2hhcnQsIGNoYXJ0LmxlZ2VuZCk7XG4gICAgZGVsZXRlIGNoYXJ0LmxlZ2VuZDtcbiAgfSxcblxuICAvLyBEdXJpbmcgdGhlIGJlZm9yZVVwZGF0ZSBzdGVwLCB0aGUgbGF5b3V0IGNvbmZpZ3VyYXRpb24gbmVlZHMgdG8gcnVuXG4gIC8vIFRoaXMgZW5zdXJlcyB0aGF0IGlmIHRoZSBsZWdlbmQgcG9zaXRpb24gY2hhbmdlcyAodmlhIGFuIG9wdGlvbiB1cGRhdGUpXG4gIC8vIHRoZSBsYXlvdXQgc3lzdGVtIHJlc3BlY3RzIHRoZSBjaGFuZ2UuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNzUyN1xuICBiZWZvcmVVcGRhdGUoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgY29uc3QgbGVnZW5kID0gY2hhcnQubGVnZW5kO1xuICAgIGxheW91dHMuY29uZmlndXJlKGNoYXJ0LCBsZWdlbmQsIG9wdGlvbnMpO1xuICAgIGxlZ2VuZC5vcHRpb25zID0gb3B0aW9ucztcbiAgfSxcblxuICAvLyBUaGUgbGFiZWxzIG5lZWQgdG8gYmUgYnVpbHQgYWZ0ZXIgZGF0YXNldHMgYXJlIHVwZGF0ZWQgdG8gZW5zdXJlIHRoYXQgY29sb3JzXG4gIC8vIGFuZCBvdGhlciBzdHlsaW5nIGFyZSBjb3JyZWN0LiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzY5NjhcbiAgYWZ0ZXJVcGRhdGUoY2hhcnQpIHtcbiAgICBjb25zdCBsZWdlbmQgPSBjaGFydC5sZWdlbmQ7XG4gICAgbGVnZW5kLmJ1aWxkTGFiZWxzKCk7XG4gICAgbGVnZW5kLmFkanVzdEhpdEJveGVzKCk7XG4gIH0sXG5cblxuICBhZnRlckV2ZW50KGNoYXJ0LCBhcmdzKSB7XG4gICAgaWYgKCFhcmdzLnJlcGxheSkge1xuICAgICAgY2hhcnQubGVnZW5kLmhhbmRsZUV2ZW50KGFyZ3MuZXZlbnQpO1xuICAgIH1cbiAgfSxcblxuICBkZWZhdWx0czoge1xuICAgIGRpc3BsYXk6IHRydWUsXG4gICAgcG9zaXRpb246ICd0b3AnLFxuICAgIGFsaWduOiAnY2VudGVyJyxcbiAgICBmdWxsU2l6ZTogdHJ1ZSxcbiAgICByZXZlcnNlOiBmYWxzZSxcbiAgICB3ZWlnaHQ6IDEwMDAsXG5cbiAgICAvLyBhIGNhbGxiYWNrIHRoYXQgd2lsbCBoYW5kbGVcbiAgICBvbkNsaWNrKGUsIGxlZ2VuZEl0ZW0sIGxlZ2VuZCkge1xuICAgICAgY29uc3QgaW5kZXggPSBsZWdlbmRJdGVtLmRhdGFzZXRJbmRleDtcbiAgICAgIGNvbnN0IGNpID0gbGVnZW5kLmNoYXJ0O1xuICAgICAgaWYgKGNpLmlzRGF0YXNldFZpc2libGUoaW5kZXgpKSB7XG4gICAgICAgIGNpLmhpZGUoaW5kZXgpO1xuICAgICAgICBsZWdlbmRJdGVtLmhpZGRlbiA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaS5zaG93KGluZGV4KTtcbiAgICAgICAgbGVnZW5kSXRlbS5oaWRkZW4gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgb25Ib3ZlcjogbnVsbCxcbiAgICBvbkxlYXZlOiBudWxsLFxuXG4gICAgbGFiZWxzOiB7XG4gICAgICBjb2xvcjogKGN0eCkgPT4gY3R4LmNoYXJ0Lm9wdGlvbnMuY29sb3IsXG4gICAgICBib3hXaWR0aDogNDAsXG4gICAgICBwYWRkaW5nOiAxMCxcbiAgICAgIC8vIEdlbmVyYXRlcyBsYWJlbHMgc2hvd24gaW4gdGhlIGxlZ2VuZFxuICAgICAgLy8gVmFsaWQgcHJvcGVydGllcyB0byByZXR1cm46XG4gICAgICAvLyB0ZXh0IDogdGV4dCB0byBkaXNwbGF5XG4gICAgICAvLyBmaWxsU3R5bGUgOiBmaWxsIG9mIGNvbG91cmVkIGJveFxuICAgICAgLy8gc3Ryb2tlU3R5bGU6IHN0cm9rZSBvZiBjb2xvdXJlZCBib3hcbiAgICAgIC8vIGhpZGRlbiA6IGlmIHRoaXMgbGVnZW5kIGl0ZW0gcmVmZXJzIHRvIGEgaGlkZGVuIGl0ZW1cbiAgICAgIC8vIGxpbmVDYXAgOiBjYXAgc3R5bGUgZm9yIGxpbmVcbiAgICAgIC8vIGxpbmVEYXNoXG4gICAgICAvLyBsaW5lRGFzaE9mZnNldCA6XG4gICAgICAvLyBsaW5lSm9pbiA6XG4gICAgICAvLyBsaW5lV2lkdGggOlxuICAgICAgZ2VuZXJhdGVMYWJlbHMoY2hhcnQpIHtcbiAgICAgICAgY29uc3QgZGF0YXNldHMgPSBjaGFydC5kYXRhLmRhdGFzZXRzO1xuICAgICAgICBjb25zdCB7bGFiZWxzOiB7dXNlUG9pbnRTdHlsZSwgcG9pbnRTdHlsZSwgdGV4dEFsaWduLCBjb2xvciwgdXNlQm9yZGVyUmFkaXVzLCBib3JkZXJSYWRpdXN9fSA9IGNoYXJ0LmxlZ2VuZC5vcHRpb25zO1xuXG4gICAgICAgIHJldHVybiBjaGFydC5fZ2V0U29ydGVkRGF0YXNldE1ldGFzKCkubWFwKChtZXRhKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc3R5bGUgPSBtZXRhLmNvbnRyb2xsZXIuZ2V0U3R5bGUodXNlUG9pbnRTdHlsZSA/IDAgOiB1bmRlZmluZWQpO1xuICAgICAgICAgIGNvbnN0IGJvcmRlcldpZHRoID0gdG9QYWRkaW5nKHN0eWxlLmJvcmRlcldpZHRoKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0ZXh0OiBkYXRhc2V0c1ttZXRhLmluZGV4XS5sYWJlbCxcbiAgICAgICAgICAgIGZpbGxTdHlsZTogc3R5bGUuYmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICAgZm9udENvbG9yOiBjb2xvcixcbiAgICAgICAgICAgIGhpZGRlbjogIW1ldGEudmlzaWJsZSxcbiAgICAgICAgICAgIGxpbmVDYXA6IHN0eWxlLmJvcmRlckNhcFN0eWxlLFxuICAgICAgICAgICAgbGluZURhc2g6IHN0eWxlLmJvcmRlckRhc2gsXG4gICAgICAgICAgICBsaW5lRGFzaE9mZnNldDogc3R5bGUuYm9yZGVyRGFzaE9mZnNldCxcbiAgICAgICAgICAgIGxpbmVKb2luOiBzdHlsZS5ib3JkZXJKb2luU3R5bGUsXG4gICAgICAgICAgICBsaW5lV2lkdGg6IChib3JkZXJXaWR0aC53aWR0aCArIGJvcmRlcldpZHRoLmhlaWdodCkgLyA0LFxuICAgICAgICAgICAgc3Ryb2tlU3R5bGU6IHN0eWxlLmJvcmRlckNvbG9yLFxuICAgICAgICAgICAgcG9pbnRTdHlsZTogcG9pbnRTdHlsZSB8fCBzdHlsZS5wb2ludFN0eWxlLFxuICAgICAgICAgICAgcm90YXRpb246IHN0eWxlLnJvdGF0aW9uLFxuICAgICAgICAgICAgdGV4dEFsaWduOiB0ZXh0QWxpZ24gfHwgc3R5bGUudGV4dEFsaWduLFxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiB1c2VCb3JkZXJSYWRpdXMgJiYgKGJvcmRlclJhZGl1cyB8fCBzdHlsZS5ib3JkZXJSYWRpdXMpLFxuXG4gICAgICAgICAgICAvLyBCZWxvdyBpcyBleHRyYSBkYXRhIHVzZWQgZm9yIHRvZ2dsaW5nIHRoZSBkYXRhc2V0c1xuICAgICAgICAgICAgZGF0YXNldEluZGV4OiBtZXRhLmluZGV4XG4gICAgICAgICAgfTtcbiAgICAgICAgfSwgdGhpcyk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIHRpdGxlOiB7XG4gICAgICBjb2xvcjogKGN0eCkgPT4gY3R4LmNoYXJ0Lm9wdGlvbnMuY29sb3IsXG4gICAgICBkaXNwbGF5OiBmYWxzZSxcbiAgICAgIHBvc2l0aW9uOiAnY2VudGVyJyxcbiAgICAgIHRleHQ6ICcnLFxuICAgIH1cbiAgfSxcblxuICBkZXNjcmlwdG9yczoge1xuICAgIF9zY3JpcHRhYmxlOiAobmFtZSkgPT4gIW5hbWUuc3RhcnRzV2l0aCgnb24nKSxcbiAgICBsYWJlbHM6IHtcbiAgICAgIF9zY3JpcHRhYmxlOiAobmFtZSkgPT4gIVsnZ2VuZXJhdGVMYWJlbHMnLCAnZmlsdGVyJywgJ3NvcnQnXS5pbmNsdWRlcyhuYW1lKSxcbiAgICB9XG4gIH0sXG59O1xuIiwgImltcG9ydCBFbGVtZW50IGZyb20gJy4uL2NvcmUvY29yZS5lbGVtZW50LmpzJztcbmltcG9ydCBsYXlvdXRzIGZyb20gJy4uL2NvcmUvY29yZS5sYXlvdXRzLmpzJztcbmltcG9ydCB7UEksIGlzQXJyYXksIHRvUGFkZGluZywgdG9Gb250fSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcbmltcG9ydCB7X3RvTGVmdFJpZ2h0Q2VudGVyLCBfYWxpZ25TdGFydEVuZH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmV4dHJhcy5qcyc7XG5pbXBvcnQge3JlbmRlclRleHR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jYW52YXMuanMnO1xuXG5leHBvcnQgY2xhc3MgVGl0bGUgZXh0ZW5kcyBFbGVtZW50IHtcbiAgLyoqXG5cdCAqIEBwYXJhbSB7eyBjdHg6IGFueTsgb3B0aW9uczogYW55OyBjaGFydDogYW55OyB9fSBjb25maWdcblx0ICovXG4gIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLmNoYXJ0ID0gY29uZmlnLmNoYXJ0O1xuICAgIHRoaXMub3B0aW9ucyA9IGNvbmZpZy5vcHRpb25zO1xuICAgIHRoaXMuY3R4ID0gY29uZmlnLmN0eDtcbiAgICB0aGlzLl9wYWRkaW5nID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudG9wID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuYm90dG9tID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubGVmdCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMud2lkdGggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5oZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5wb3NpdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLndlaWdodCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmZ1bGxTaXplID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgdXBkYXRlKG1heFdpZHRoLCBtYXhIZWlnaHQpIHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuXG4gICAgdGhpcy5sZWZ0ID0gMDtcbiAgICB0aGlzLnRvcCA9IDA7XG5cbiAgICBpZiAoIW9wdHMuZGlzcGxheSkge1xuICAgICAgdGhpcy53aWR0aCA9IHRoaXMuaGVpZ2h0ID0gdGhpcy5yaWdodCA9IHRoaXMuYm90dG9tID0gMDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLndpZHRoID0gdGhpcy5yaWdodCA9IG1heFdpZHRoO1xuICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5ib3R0b20gPSBtYXhIZWlnaHQ7XG5cbiAgICBjb25zdCBsaW5lQ291bnQgPSBpc0FycmF5KG9wdHMudGV4dCkgPyBvcHRzLnRleHQubGVuZ3RoIDogMTtcbiAgICB0aGlzLl9wYWRkaW5nID0gdG9QYWRkaW5nKG9wdHMucGFkZGluZyk7XG4gICAgY29uc3QgdGV4dFNpemUgPSBsaW5lQ291bnQgKiB0b0ZvbnQob3B0cy5mb250KS5saW5lSGVpZ2h0ICsgdGhpcy5fcGFkZGluZy5oZWlnaHQ7XG5cbiAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgdGhpcy5oZWlnaHQgPSB0ZXh0U2l6ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy53aWR0aCA9IHRleHRTaXplO1xuICAgIH1cbiAgfVxuXG4gIGlzSG9yaXpvbnRhbCgpIHtcbiAgICBjb25zdCBwb3MgPSB0aGlzLm9wdGlvbnMucG9zaXRpb247XG4gICAgcmV0dXJuIHBvcyA9PT0gJ3RvcCcgfHwgcG9zID09PSAnYm90dG9tJztcbiAgfVxuXG4gIF9kcmF3QXJncyhvZmZzZXQpIHtcbiAgICBjb25zdCB7dG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0LCBvcHRpb25zfSA9IHRoaXM7XG4gICAgY29uc3QgYWxpZ24gPSBvcHRpb25zLmFsaWduO1xuICAgIGxldCByb3RhdGlvbiA9IDA7XG4gICAgbGV0IG1heFdpZHRoLCB0aXRsZVgsIHRpdGxlWTtcblxuICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICB0aXRsZVggPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgbGVmdCwgcmlnaHQpO1xuICAgICAgdGl0bGVZID0gdG9wICsgb2Zmc2V0O1xuICAgICAgbWF4V2lkdGggPSByaWdodCAtIGxlZnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChvcHRpb25zLnBvc2l0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgICAgdGl0bGVYID0gbGVmdCArIG9mZnNldDtcbiAgICAgICAgdGl0bGVZID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIGJvdHRvbSwgdG9wKTtcbiAgICAgICAgcm90YXRpb24gPSBQSSAqIC0wLjU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aXRsZVggPSByaWdodCAtIG9mZnNldDtcbiAgICAgICAgdGl0bGVZID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIHRvcCwgYm90dG9tKTtcbiAgICAgICAgcm90YXRpb24gPSBQSSAqIDAuNTtcbiAgICAgIH1cbiAgICAgIG1heFdpZHRoID0gYm90dG9tIC0gdG9wO1xuICAgIH1cbiAgICByZXR1cm4ge3RpdGxlWCwgdGl0bGVZLCBtYXhXaWR0aCwgcm90YXRpb259O1xuICB9XG5cbiAgZHJhdygpIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuXG4gICAgaWYgKCFvcHRzLmRpc3BsYXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBmb250T3B0cyA9IHRvRm9udChvcHRzLmZvbnQpO1xuICAgIGNvbnN0IGxpbmVIZWlnaHQgPSBmb250T3B0cy5saW5lSGVpZ2h0O1xuICAgIGNvbnN0IG9mZnNldCA9IGxpbmVIZWlnaHQgLyAyICsgdGhpcy5fcGFkZGluZy50b3A7XG4gICAgY29uc3Qge3RpdGxlWCwgdGl0bGVZLCBtYXhXaWR0aCwgcm90YXRpb259ID0gdGhpcy5fZHJhd0FyZ3Mob2Zmc2V0KTtcblxuICAgIHJlbmRlclRleHQoY3R4LCBvcHRzLnRleHQsIDAsIDAsIGZvbnRPcHRzLCB7XG4gICAgICBjb2xvcjogb3B0cy5jb2xvcixcbiAgICAgIG1heFdpZHRoLFxuICAgICAgcm90YXRpb24sXG4gICAgICB0ZXh0QWxpZ246IF90b0xlZnRSaWdodENlbnRlcihvcHRzLmFsaWduKSxcbiAgICAgIHRleHRCYXNlbGluZTogJ21pZGRsZScsXG4gICAgICB0cmFuc2xhdGlvbjogW3RpdGxlWCwgdGl0bGVZXSxcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVUaXRsZShjaGFydCwgdGl0bGVPcHRzKSB7XG4gIGNvbnN0IHRpdGxlID0gbmV3IFRpdGxlKHtcbiAgICBjdHg6IGNoYXJ0LmN0eCxcbiAgICBvcHRpb25zOiB0aXRsZU9wdHMsXG4gICAgY2hhcnRcbiAgfSk7XG5cbiAgbGF5b3V0cy5jb25maWd1cmUoY2hhcnQsIHRpdGxlLCB0aXRsZU9wdHMpO1xuICBsYXlvdXRzLmFkZEJveChjaGFydCwgdGl0bGUpO1xuICBjaGFydC50aXRsZUJsb2NrID0gdGl0bGU7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgaWQ6ICd0aXRsZScsXG5cbiAgLyoqXG5cdCAqIEZvciB0ZXN0c1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2VsZW1lbnQ6IFRpdGxlLFxuXG4gIHN0YXJ0KGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgIGNyZWF0ZVRpdGxlKGNoYXJ0LCBvcHRpb25zKTtcbiAgfSxcblxuICBzdG9wKGNoYXJ0KSB7XG4gICAgY29uc3QgdGl0bGVCbG9jayA9IGNoYXJ0LnRpdGxlQmxvY2s7XG4gICAgbGF5b3V0cy5yZW1vdmVCb3goY2hhcnQsIHRpdGxlQmxvY2spO1xuICAgIGRlbGV0ZSBjaGFydC50aXRsZUJsb2NrO1xuICB9LFxuXG4gIGJlZm9yZVVwZGF0ZShjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICBjb25zdCB0aXRsZSA9IGNoYXJ0LnRpdGxlQmxvY2s7XG4gICAgbGF5b3V0cy5jb25maWd1cmUoY2hhcnQsIHRpdGxlLCBvcHRpb25zKTtcbiAgICB0aXRsZS5vcHRpb25zID0gb3B0aW9ucztcbiAgfSxcblxuICBkZWZhdWx0czoge1xuICAgIGFsaWduOiAnY2VudGVyJyxcbiAgICBkaXNwbGF5OiBmYWxzZSxcbiAgICBmb250OiB7XG4gICAgICB3ZWlnaHQ6ICdib2xkJyxcbiAgICB9LFxuICAgIGZ1bGxTaXplOiB0cnVlLFxuICAgIHBhZGRpbmc6IDEwLFxuICAgIHBvc2l0aW9uOiAndG9wJyxcbiAgICB0ZXh0OiAnJyxcbiAgICB3ZWlnaHQ6IDIwMDAgICAgICAgICAvLyBieSBkZWZhdWx0IGdyZWF0ZXIgdGhhbiBsZWdlbmQgKDEwMDApIHRvIGJlIGFib3ZlXG4gIH0sXG5cbiAgZGVmYXVsdFJvdXRlczoge1xuICAgIGNvbG9yOiAnY29sb3InXG4gIH0sXG5cbiAgZGVzY3JpcHRvcnM6IHtcbiAgICBfc2NyaXB0YWJsZTogdHJ1ZSxcbiAgICBfaW5kZXhhYmxlOiBmYWxzZSxcbiAgfSxcbn07XG4iLCAiaW1wb3J0IHtUaXRsZX0gZnJvbSAnLi9wbHVnaW4udGl0bGUuanMnO1xuaW1wb3J0IGxheW91dHMgZnJvbSAnLi4vY29yZS9jb3JlLmxheW91dHMuanMnO1xuXG5jb25zdCBtYXAgPSBuZXcgV2Vha01hcCgpO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGlkOiAnc3VidGl0bGUnLFxuXG4gIHN0YXJ0KGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgIGNvbnN0IHRpdGxlID0gbmV3IFRpdGxlKHtcbiAgICAgIGN0eDogY2hhcnQuY3R4LFxuICAgICAgb3B0aW9ucyxcbiAgICAgIGNoYXJ0XG4gICAgfSk7XG5cbiAgICBsYXlvdXRzLmNvbmZpZ3VyZShjaGFydCwgdGl0bGUsIG9wdGlvbnMpO1xuICAgIGxheW91dHMuYWRkQm94KGNoYXJ0LCB0aXRsZSk7XG4gICAgbWFwLnNldChjaGFydCwgdGl0bGUpO1xuICB9LFxuXG4gIHN0b3AoY2hhcnQpIHtcbiAgICBsYXlvdXRzLnJlbW92ZUJveChjaGFydCwgbWFwLmdldChjaGFydCkpO1xuICAgIG1hcC5kZWxldGUoY2hhcnQpO1xuICB9LFxuXG4gIGJlZm9yZVVwZGF0ZShjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICBjb25zdCB0aXRsZSA9IG1hcC5nZXQoY2hhcnQpO1xuICAgIGxheW91dHMuY29uZmlndXJlKGNoYXJ0LCB0aXRsZSwgb3B0aW9ucyk7XG4gICAgdGl0bGUub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH0sXG5cbiAgZGVmYXVsdHM6IHtcbiAgICBhbGlnbjogJ2NlbnRlcicsXG4gICAgZGlzcGxheTogZmFsc2UsXG4gICAgZm9udDoge1xuICAgICAgd2VpZ2h0OiAnbm9ybWFsJyxcbiAgICB9LFxuICAgIGZ1bGxTaXplOiB0cnVlLFxuICAgIHBhZGRpbmc6IDAsXG4gICAgcG9zaXRpb246ICd0b3AnLFxuICAgIHRleHQ6ICcnLFxuICAgIHdlaWdodDogMTUwMCAgICAgICAgIC8vIGJ5IGRlZmF1bHQgZ3JlYXRlciB0aGFuIGxlZ2VuZCAoMTAwMCkgYW5kIHNtYWxsZXIgdGhhbiB0aXRsZSAoMjAwMClcbiAgfSxcblxuICBkZWZhdWx0Um91dGVzOiB7XG4gICAgY29sb3I6ICdjb2xvcidcbiAgfSxcblxuICBkZXNjcmlwdG9yczoge1xuICAgIF9zY3JpcHRhYmxlOiB0cnVlLFxuICAgIF9pbmRleGFibGU6IGZhbHNlLFxuICB9LFxufTtcbiIsICJpbXBvcnQgQW5pbWF0aW9ucyBmcm9tICcuLi9jb3JlL2NvcmUuYW5pbWF0aW9ucy5qcyc7XG5pbXBvcnQgRWxlbWVudCBmcm9tICcuLi9jb3JlL2NvcmUuZWxlbWVudC5qcyc7XG5pbXBvcnQge2FkZFJvdW5kZWRSZWN0UGF0aH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNhbnZhcy5qcyc7XG5pbXBvcnQge2VhY2gsIG5vb3AsIGlzTnVsbE9yVW5kZWYsIGlzQXJyYXksIF9lbGVtZW50c0VxdWFsLCBpc09iamVjdH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuaW1wb3J0IHt0b0ZvbnQsIHRvUGFkZGluZywgdG9UUkJMQ29ybmVyc30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm9wdGlvbnMuanMnO1xuaW1wb3J0IHtnZXRSdGxBZGFwdGVyLCBvdmVycmlkZVRleHREaXJlY3Rpb24sIHJlc3RvcmVUZXh0RGlyZWN0aW9ufSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMucnRsLmpzJztcbmltcG9ydCB7ZGlzdGFuY2VCZXR3ZWVuUG9pbnRzLCBfbGltaXRWYWx1ZX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IHtjcmVhdGVDb250ZXh0LCBkcmF3UG9pbnR9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi9wbGF0Zm9ybS9wbGF0Zm9ybS5iYXNlLmpzJykuQ2hhcnQgfSBDaGFydFxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL3R5cGVzL2luZGV4LmpzJykuQ2hhcnRFdmVudCB9IENoYXJ0RXZlbnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi90eXBlcy9pbmRleC5qcycpLkFjdGl2ZUVsZW1lbnQgfSBBY3RpdmVFbGVtZW50XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vY29yZS9jb3JlLmludGVyYWN0aW9uLmpzJykuSW50ZXJhY3Rpb25JdGVtIH0gSW50ZXJhY3Rpb25JdGVtXG4gKi9cblxuY29uc3QgcG9zaXRpb25lcnMgPSB7XG4gIC8qKlxuXHQgKiBBdmVyYWdlIG1vZGUgcGxhY2VzIHRoZSB0b29sdGlwIGF0IHRoZSBhdmVyYWdlIHBvc2l0aW9uIG9mIHRoZSBlbGVtZW50cyBzaG93blxuXHQgKi9cbiAgYXZlcmFnZShpdGVtcykge1xuICAgIGlmICghaXRlbXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbGV0IGksIGxlbjtcbiAgICBsZXQgeFNldCA9IG5ldyBTZXQoKTtcbiAgICBsZXQgeSA9IDA7XG4gICAgbGV0IGNvdW50ID0gMDtcblxuICAgIGZvciAoaSA9IDAsIGxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICBjb25zdCBlbCA9IGl0ZW1zW2ldLmVsZW1lbnQ7XG4gICAgICBpZiAoZWwgJiYgZWwuaGFzVmFsdWUoKSkge1xuICAgICAgICBjb25zdCBwb3MgPSBlbC50b29sdGlwUG9zaXRpb24oKTtcbiAgICAgICAgeFNldC5hZGQocG9zLngpO1xuICAgICAgICB5ICs9IHBvcy55O1xuICAgICAgICArK2NvdW50O1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHhBdmVyYWdlID0gWy4uLnhTZXRdLnJlZHVjZSgoYSwgYikgPT4gYSArIGIpIC8geFNldC5zaXplO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHhBdmVyYWdlLFxuICAgICAgeTogeSAvIGNvdW50XG4gICAgfTtcbiAgfSxcblxuICAvKipcblx0ICogR2V0cyB0aGUgdG9vbHRpcCBwb3NpdGlvbiBuZWFyZXN0IG9mIHRoZSBpdGVtIG5lYXJlc3QgdG8gdGhlIGV2ZW50IHBvc2l0aW9uXG5cdCAqL1xuICBuZWFyZXN0KGl0ZW1zLCBldmVudFBvc2l0aW9uKSB7XG4gICAgaWYgKCFpdGVtcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgeCA9IGV2ZW50UG9zaXRpb24ueDtcbiAgICBsZXQgeSA9IGV2ZW50UG9zaXRpb24ueTtcbiAgICBsZXQgbWluRGlzdGFuY2UgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgbGV0IGksIGxlbiwgbmVhcmVzdEVsZW1lbnQ7XG5cbiAgICBmb3IgKGkgPSAwLCBsZW4gPSBpdGVtcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY29uc3QgZWwgPSBpdGVtc1tpXS5lbGVtZW50O1xuICAgICAgaWYgKGVsICYmIGVsLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgY29uc3QgY2VudGVyID0gZWwuZ2V0Q2VudGVyUG9pbnQoKTtcbiAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlQmV0d2VlblBvaW50cyhldmVudFBvc2l0aW9uLCBjZW50ZXIpO1xuXG4gICAgICAgIGlmIChkIDwgbWluRGlzdGFuY2UpIHtcbiAgICAgICAgICBtaW5EaXN0YW5jZSA9IGQ7XG4gICAgICAgICAgbmVhcmVzdEVsZW1lbnQgPSBlbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChuZWFyZXN0RWxlbWVudCkge1xuICAgICAgY29uc3QgdHAgPSBuZWFyZXN0RWxlbWVudC50b29sdGlwUG9zaXRpb24oKTtcbiAgICAgIHggPSB0cC54O1xuICAgICAgeSA9IHRwLnk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHgsXG4gICAgICB5XG4gICAgfTtcbiAgfVxufTtcblxuLy8gSGVscGVyIHRvIHB1c2ggb3IgY29uY2F0IGJhc2VkIG9uIGlmIHRoZSAybmQgcGFyYW1ldGVyIGlzIGFuIGFycmF5IG9yIG5vdFxuZnVuY3Rpb24gcHVzaE9yQ29uY2F0KGJhc2UsIHRvUHVzaCkge1xuICBpZiAodG9QdXNoKSB7XG4gICAgaWYgKGlzQXJyYXkodG9QdXNoKSkge1xuICAgICAgLy8gYmFzZSA9IGJhc2UuY29uY2F0KHRvUHVzaCk7XG4gICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShiYXNlLCB0b1B1c2gpO1xuICAgIH0gZWxzZSB7XG4gICAgICBiYXNlLnB1c2godG9QdXNoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYmFzZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFycmF5IG9mIHN0cmluZ3Mgc3BsaXQgYnkgbmV3bGluZVxuICogQHBhcmFtIHsqfSBzdHIgLSBUaGUgdmFsdWUgdG8gc3BsaXQgYnkgbmV3bGluZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd8c3RyaW5nW119IHZhbHVlIGlmIG5ld2xpbmUgcHJlc2VudCAtIFJldHVybmVkIGZyb20gU3RyaW5nIHNwbGl0KCkgbWV0aG9kXG4gKiBAZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gc3BsaXROZXdsaW5lcyhzdHIpIHtcbiAgaWYgKCh0eXBlb2Ygc3RyID09PSAnc3RyaW5nJyB8fCBzdHIgaW5zdGFuY2VvZiBTdHJpbmcpICYmIHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgcmV0dXJuIHN0ci5zcGxpdCgnXFxuJyk7XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn1cblxuXG4vKipcbiAqIFByaXZhdGUgaGVscGVyIHRvIGNyZWF0ZSBhIHRvb2x0aXAgaXRlbSBtb2RlbFxuICogQHBhcmFtIHtDaGFydH0gY2hhcnRcbiAqIEBwYXJhbSB7QWN0aXZlRWxlbWVudH0gaXRlbSAtIHtlbGVtZW50LCBpbmRleCwgZGF0YXNldEluZGV4fSB0byBjcmVhdGUgdGhlIHRvb2x0aXAgaXRlbSBmb3JcbiAqIEByZXR1cm4gbmV3IHRvb2x0aXAgaXRlbVxuICovXG5mdW5jdGlvbiBjcmVhdGVUb29sdGlwSXRlbShjaGFydCwgaXRlbSkge1xuICBjb25zdCB7ZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleH0gPSBpdGVtO1xuICBjb25zdCBjb250cm9sbGVyID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KS5jb250cm9sbGVyO1xuICBjb25zdCB7bGFiZWwsIHZhbHVlfSA9IGNvbnRyb2xsZXIuZ2V0TGFiZWxBbmRWYWx1ZShpbmRleCk7XG5cbiAgcmV0dXJuIHtcbiAgICBjaGFydCxcbiAgICBsYWJlbCxcbiAgICBwYXJzZWQ6IGNvbnRyb2xsZXIuZ2V0UGFyc2VkKGluZGV4KSxcbiAgICByYXc6IGNoYXJ0LmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XS5kYXRhW2luZGV4XSxcbiAgICBmb3JtYXR0ZWRWYWx1ZTogdmFsdWUsXG4gICAgZGF0YXNldDogY29udHJvbGxlci5nZXREYXRhc2V0KCksXG4gICAgZGF0YUluZGV4OiBpbmRleCxcbiAgICBkYXRhc2V0SW5kZXgsXG4gICAgZWxlbWVudFxuICB9O1xufVxuXG4vKipcbiAqIEdldCB0aGUgc2l6ZSBvZiB0aGUgdG9vbHRpcFxuICovXG5mdW5jdGlvbiBnZXRUb29sdGlwU2l6ZSh0b29sdGlwLCBvcHRpb25zKSB7XG4gIGNvbnN0IGN0eCA9IHRvb2x0aXAuY2hhcnQuY3R4O1xuICBjb25zdCB7Ym9keSwgZm9vdGVyLCB0aXRsZX0gPSB0b29sdGlwO1xuICBjb25zdCB7Ym94V2lkdGgsIGJveEhlaWdodH0gPSBvcHRpb25zO1xuICBjb25zdCBib2R5Rm9udCA9IHRvRm9udChvcHRpb25zLmJvZHlGb250KTtcbiAgY29uc3QgdGl0bGVGb250ID0gdG9Gb250KG9wdGlvbnMudGl0bGVGb250KTtcbiAgY29uc3QgZm9vdGVyRm9udCA9IHRvRm9udChvcHRpb25zLmZvb3RlckZvbnQpO1xuICBjb25zdCB0aXRsZUxpbmVDb3VudCA9IHRpdGxlLmxlbmd0aDtcbiAgY29uc3QgZm9vdGVyTGluZUNvdW50ID0gZm9vdGVyLmxlbmd0aDtcbiAgY29uc3QgYm9keUxpbmVJdGVtQ291bnQgPSBib2R5Lmxlbmd0aDtcblxuICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKG9wdGlvbnMucGFkZGluZyk7XG4gIGxldCBoZWlnaHQgPSBwYWRkaW5nLmhlaWdodDtcbiAgbGV0IHdpZHRoID0gMDtcblxuICAvLyBDb3VudCBvZiBhbGwgbGluZXMgaW4gdGhlIGJvZHlcbiAgbGV0IGNvbWJpbmVkQm9keUxlbmd0aCA9IGJvZHkucmVkdWNlKChjb3VudCwgYm9keUl0ZW0pID0+IGNvdW50ICsgYm9keUl0ZW0uYmVmb3JlLmxlbmd0aCArIGJvZHlJdGVtLmxpbmVzLmxlbmd0aCArIGJvZHlJdGVtLmFmdGVyLmxlbmd0aCwgMCk7XG4gIGNvbWJpbmVkQm9keUxlbmd0aCArPSB0b29sdGlwLmJlZm9yZUJvZHkubGVuZ3RoICsgdG9vbHRpcC5hZnRlckJvZHkubGVuZ3RoO1xuXG4gIGlmICh0aXRsZUxpbmVDb3VudCkge1xuICAgIGhlaWdodCArPSB0aXRsZUxpbmVDb3VudCAqIHRpdGxlRm9udC5saW5lSGVpZ2h0XG5cdFx0XHQrICh0aXRsZUxpbmVDb3VudCAtIDEpICogb3B0aW9ucy50aXRsZVNwYWNpbmdcblx0XHRcdCsgb3B0aW9ucy50aXRsZU1hcmdpbkJvdHRvbTtcbiAgfVxuICBpZiAoY29tYmluZWRCb2R5TGVuZ3RoKSB7XG4gICAgLy8gQm9keSBsaW5lcyBtYXkgaW5jbHVkZSBzb21lIGV4dHJhIGhlaWdodCBkZXBlbmRpbmcgb24gYm94SGVpZ2h0XG4gICAgY29uc3QgYm9keUxpbmVIZWlnaHQgPSBvcHRpb25zLmRpc3BsYXlDb2xvcnMgPyBNYXRoLm1heChib3hIZWlnaHQsIGJvZHlGb250LmxpbmVIZWlnaHQpIDogYm9keUZvbnQubGluZUhlaWdodDtcbiAgICBoZWlnaHQgKz0gYm9keUxpbmVJdGVtQ291bnQgKiBib2R5TGluZUhlaWdodFxuXHRcdFx0KyAoY29tYmluZWRCb2R5TGVuZ3RoIC0gYm9keUxpbmVJdGVtQ291bnQpICogYm9keUZvbnQubGluZUhlaWdodFxuXHRcdFx0KyAoY29tYmluZWRCb2R5TGVuZ3RoIC0gMSkgKiBvcHRpb25zLmJvZHlTcGFjaW5nO1xuICB9XG4gIGlmIChmb290ZXJMaW5lQ291bnQpIHtcbiAgICBoZWlnaHQgKz0gb3B0aW9ucy5mb290ZXJNYXJnaW5Ub3Bcblx0XHRcdCsgZm9vdGVyTGluZUNvdW50ICogZm9vdGVyRm9udC5saW5lSGVpZ2h0XG5cdFx0XHQrIChmb290ZXJMaW5lQ291bnQgLSAxKSAqIG9wdGlvbnMuZm9vdGVyU3BhY2luZztcbiAgfVxuXG4gIC8vIFRpdGxlIHdpZHRoXG4gIGxldCB3aWR0aFBhZGRpbmcgPSAwO1xuICBjb25zdCBtYXhMaW5lV2lkdGggPSBmdW5jdGlvbihsaW5lKSB7XG4gICAgd2lkdGggPSBNYXRoLm1heCh3aWR0aCwgY3R4Lm1lYXN1cmVUZXh0KGxpbmUpLndpZHRoICsgd2lkdGhQYWRkaW5nKTtcbiAgfTtcblxuICBjdHguc2F2ZSgpO1xuXG4gIGN0eC5mb250ID0gdGl0bGVGb250LnN0cmluZztcbiAgZWFjaCh0b29sdGlwLnRpdGxlLCBtYXhMaW5lV2lkdGgpO1xuXG4gIC8vIEJvZHkgd2lkdGhcbiAgY3R4LmZvbnQgPSBib2R5Rm9udC5zdHJpbmc7XG4gIGVhY2godG9vbHRpcC5iZWZvcmVCb2R5LmNvbmNhdCh0b29sdGlwLmFmdGVyQm9keSksIG1heExpbmVXaWR0aCk7XG5cbiAgLy8gQm9keSBsaW5lcyBtYXkgaW5jbHVkZSBzb21lIGV4dHJhIHdpZHRoIGR1ZSB0byB0aGUgY29sb3IgYm94XG4gIHdpZHRoUGFkZGluZyA9IG9wdGlvbnMuZGlzcGxheUNvbG9ycyA/IChib3hXaWR0aCArIDIgKyBvcHRpb25zLmJveFBhZGRpbmcpIDogMDtcbiAgZWFjaChib2R5LCAoYm9keUl0ZW0pID0+IHtcbiAgICBlYWNoKGJvZHlJdGVtLmJlZm9yZSwgbWF4TGluZVdpZHRoKTtcbiAgICBlYWNoKGJvZHlJdGVtLmxpbmVzLCBtYXhMaW5lV2lkdGgpO1xuICAgIGVhY2goYm9keUl0ZW0uYWZ0ZXIsIG1heExpbmVXaWR0aCk7XG4gIH0pO1xuXG4gIC8vIFJlc2V0IGJhY2sgdG8gMFxuICB3aWR0aFBhZGRpbmcgPSAwO1xuXG4gIC8vIEZvb3RlciB3aWR0aFxuICBjdHguZm9udCA9IGZvb3RlckZvbnQuc3RyaW5nO1xuICBlYWNoKHRvb2x0aXAuZm9vdGVyLCBtYXhMaW5lV2lkdGgpO1xuXG4gIGN0eC5yZXN0b3JlKCk7XG5cbiAgLy8gQWRkIHBhZGRpbmdcbiAgd2lkdGggKz0gcGFkZGluZy53aWR0aDtcblxuICByZXR1cm4ge3dpZHRoLCBoZWlnaHR9O1xufVxuXG5mdW5jdGlvbiBkZXRlcm1pbmVZQWxpZ24oY2hhcnQsIHNpemUpIHtcbiAgY29uc3Qge3ksIGhlaWdodH0gPSBzaXplO1xuXG4gIGlmICh5IDwgaGVpZ2h0IC8gMikge1xuICAgIHJldHVybiAndG9wJztcbiAgfSBlbHNlIGlmICh5ID4gKGNoYXJ0LmhlaWdodCAtIGhlaWdodCAvIDIpKSB7XG4gICAgcmV0dXJuICdib3R0b20nO1xuICB9XG4gIHJldHVybiAnY2VudGVyJztcbn1cblxuZnVuY3Rpb24gZG9lc05vdEZpdFdpdGhBbGlnbih4QWxpZ24sIGNoYXJ0LCBvcHRpb25zLCBzaXplKSB7XG4gIGNvbnN0IHt4LCB3aWR0aH0gPSBzaXplO1xuICBjb25zdCBjYXJldCA9IG9wdGlvbnMuY2FyZXRTaXplICsgb3B0aW9ucy5jYXJldFBhZGRpbmc7XG4gIGlmICh4QWxpZ24gPT09ICdsZWZ0JyAmJiB4ICsgd2lkdGggKyBjYXJldCA+IGNoYXJ0LndpZHRoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAoeEFsaWduID09PSAncmlnaHQnICYmIHggLSB3aWR0aCAtIGNhcmV0IDwgMCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRldGVybWluZVhBbGlnbihjaGFydCwgb3B0aW9ucywgc2l6ZSwgeUFsaWduKSB7XG4gIGNvbnN0IHt4LCB3aWR0aH0gPSBzaXplO1xuICBjb25zdCB7d2lkdGg6IGNoYXJ0V2lkdGgsIGNoYXJ0QXJlYToge2xlZnQsIHJpZ2h0fX0gPSBjaGFydDtcbiAgbGV0IHhBbGlnbiA9ICdjZW50ZXInO1xuXG4gIGlmICh5QWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgeEFsaWduID0geCA8PSAobGVmdCArIHJpZ2h0KSAvIDIgPyAnbGVmdCcgOiAncmlnaHQnO1xuICB9IGVsc2UgaWYgKHggPD0gd2lkdGggLyAyKSB7XG4gICAgeEFsaWduID0gJ2xlZnQnO1xuICB9IGVsc2UgaWYgKHggPj0gY2hhcnRXaWR0aCAtIHdpZHRoIC8gMikge1xuICAgIHhBbGlnbiA9ICdyaWdodCc7XG4gIH1cblxuICBpZiAoZG9lc05vdEZpdFdpdGhBbGlnbih4QWxpZ24sIGNoYXJ0LCBvcHRpb25zLCBzaXplKSkge1xuICAgIHhBbGlnbiA9ICdjZW50ZXInO1xuICB9XG5cbiAgcmV0dXJuIHhBbGlnbjtcbn1cblxuLyoqXG4gKiBIZWxwZXIgdG8gZ2V0IHRoZSBhbGlnbm1lbnQgb2YgYSB0b29sdGlwIGdpdmVuIHRoZSBzaXplXG4gKi9cbmZ1bmN0aW9uIGRldGVybWluZUFsaWdubWVudChjaGFydCwgb3B0aW9ucywgc2l6ZSkge1xuICBjb25zdCB5QWxpZ24gPSBzaXplLnlBbGlnbiB8fCBvcHRpb25zLnlBbGlnbiB8fCBkZXRlcm1pbmVZQWxpZ24oY2hhcnQsIHNpemUpO1xuXG4gIHJldHVybiB7XG4gICAgeEFsaWduOiBzaXplLnhBbGlnbiB8fCBvcHRpb25zLnhBbGlnbiB8fCBkZXRlcm1pbmVYQWxpZ24oY2hhcnQsIG9wdGlvbnMsIHNpemUsIHlBbGlnbiksXG4gICAgeUFsaWduXG4gIH07XG59XG5cbmZ1bmN0aW9uIGFsaWduWChzaXplLCB4QWxpZ24pIHtcbiAgbGV0IHt4LCB3aWR0aH0gPSBzaXplO1xuICBpZiAoeEFsaWduID09PSAncmlnaHQnKSB7XG4gICAgeCAtPSB3aWR0aDtcbiAgfSBlbHNlIGlmICh4QWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgeCAtPSAod2lkdGggLyAyKTtcbiAgfVxuICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24gYWxpZ25ZKHNpemUsIHlBbGlnbiwgcGFkZGluZ0FuZFNpemUpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICBsZXQge3ksIGhlaWdodH0gPSBzaXplO1xuICBpZiAoeUFsaWduID09PSAndG9wJykge1xuICAgIHkgKz0gcGFkZGluZ0FuZFNpemU7XG4gIH0gZWxzZSBpZiAoeUFsaWduID09PSAnYm90dG9tJykge1xuICAgIHkgLT0gaGVpZ2h0ICsgcGFkZGluZ0FuZFNpemU7XG4gIH0gZWxzZSB7XG4gICAgeSAtPSAoaGVpZ2h0IC8gMik7XG4gIH1cbiAgcmV0dXJuIHk7XG59XG5cbi8qKlxuICogSGVscGVyIHRvIGdldCB0aGUgbG9jYXRpb24gYSB0b29sdGlwIG5lZWRzIHRvIGJlIHBsYWNlZCBhdCBnaXZlbiB0aGUgaW5pdGlhbCBwb3NpdGlvbiAodmlhIHRoZSB2bSkgYW5kIHRoZSBzaXplIGFuZCBhbGlnbm1lbnRcbiAqL1xuZnVuY3Rpb24gZ2V0QmFja2dyb3VuZFBvaW50KG9wdGlvbnMsIHNpemUsIGFsaWdubWVudCwgY2hhcnQpIHtcbiAgY29uc3Qge2NhcmV0U2l6ZSwgY2FyZXRQYWRkaW5nLCBjb3JuZXJSYWRpdXN9ID0gb3B0aW9ucztcbiAgY29uc3Qge3hBbGlnbiwgeUFsaWdufSA9IGFsaWdubWVudDtcbiAgY29uc3QgcGFkZGluZ0FuZFNpemUgPSBjYXJldFNpemUgKyBjYXJldFBhZGRpbmc7XG4gIGNvbnN0IHt0b3BMZWZ0LCB0b3BSaWdodCwgYm90dG9tTGVmdCwgYm90dG9tUmlnaHR9ID0gdG9UUkJMQ29ybmVycyhjb3JuZXJSYWRpdXMpO1xuXG4gIGxldCB4ID0gYWxpZ25YKHNpemUsIHhBbGlnbik7XG4gIGNvbnN0IHkgPSBhbGlnblkoc2l6ZSwgeUFsaWduLCBwYWRkaW5nQW5kU2l6ZSk7XG5cbiAgaWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICBpZiAoeEFsaWduID09PSAnbGVmdCcpIHtcbiAgICAgIHggKz0gcGFkZGluZ0FuZFNpemU7XG4gICAgfSBlbHNlIGlmICh4QWxpZ24gPT09ICdyaWdodCcpIHtcbiAgICAgIHggLT0gcGFkZGluZ0FuZFNpemU7XG4gICAgfVxuICB9IGVsc2UgaWYgKHhBbGlnbiA9PT0gJ2xlZnQnKSB7XG4gICAgeCAtPSBNYXRoLm1heCh0b3BMZWZ0LCBib3R0b21MZWZ0KSArIGNhcmV0U2l6ZTtcbiAgfSBlbHNlIGlmICh4QWxpZ24gPT09ICdyaWdodCcpIHtcbiAgICB4ICs9IE1hdGgubWF4KHRvcFJpZ2h0LCBib3R0b21SaWdodCkgKyBjYXJldFNpemU7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHg6IF9saW1pdFZhbHVlKHgsIDAsIGNoYXJ0LndpZHRoIC0gc2l6ZS53aWR0aCksXG4gICAgeTogX2xpbWl0VmFsdWUoeSwgMCwgY2hhcnQuaGVpZ2h0IC0gc2l6ZS5oZWlnaHQpXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldEFsaWduZWRYKHRvb2x0aXAsIGFsaWduLCBvcHRpb25zKSB7XG4gIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcob3B0aW9ucy5wYWRkaW5nKTtcblxuICByZXR1cm4gYWxpZ24gPT09ICdjZW50ZXInXG4gICAgPyB0b29sdGlwLnggKyB0b29sdGlwLndpZHRoIC8gMlxuICAgIDogYWxpZ24gPT09ICdyaWdodCdcbiAgICAgID8gdG9vbHRpcC54ICsgdG9vbHRpcC53aWR0aCAtIHBhZGRpbmcucmlnaHRcbiAgICAgIDogdG9vbHRpcC54ICsgcGFkZGluZy5sZWZ0O1xufVxuXG4vKipcbiAqIEhlbHBlciB0byBidWlsZCBiZWZvcmUgYW5kIGFmdGVyIGJvZHkgbGluZXNcbiAqL1xuZnVuY3Rpb24gZ2V0QmVmb3JlQWZ0ZXJCb2R5TGluZXMoY2FsbGJhY2spIHtcbiAgcmV0dXJuIHB1c2hPckNvbmNhdChbXSwgc3BsaXROZXdsaW5lcyhjYWxsYmFjaykpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUb29sdGlwQ29udGV4dChwYXJlbnQsIHRvb2x0aXAsIHRvb2x0aXBJdGVtcykge1xuICByZXR1cm4gY3JlYXRlQ29udGV4dChwYXJlbnQsIHtcbiAgICB0b29sdGlwLFxuICAgIHRvb2x0aXBJdGVtcyxcbiAgICB0eXBlOiAndG9vbHRpcCdcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG92ZXJyaWRlQ2FsbGJhY2tzKGNhbGxiYWNrcywgY29udGV4dCkge1xuICBjb25zdCBvdmVycmlkZSA9IGNvbnRleHQgJiYgY29udGV4dC5kYXRhc2V0ICYmIGNvbnRleHQuZGF0YXNldC50b29sdGlwICYmIGNvbnRleHQuZGF0YXNldC50b29sdGlwLmNhbGxiYWNrcztcbiAgcmV0dXJuIG92ZXJyaWRlID8gY2FsbGJhY2tzLm92ZXJyaWRlKG92ZXJyaWRlKSA6IGNhbGxiYWNrcztcbn1cblxuY29uc3QgZGVmYXVsdENhbGxiYWNrcyA9IHtcbiAgLy8gQXJncyBhcmU6ICh0b29sdGlwSXRlbXMsIGRhdGEpXG4gIGJlZm9yZVRpdGxlOiBub29wLFxuICB0aXRsZSh0b29sdGlwSXRlbXMpIHtcbiAgICBpZiAodG9vbHRpcEl0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSB0b29sdGlwSXRlbXNbMF07XG4gICAgICBjb25zdCBsYWJlbHMgPSBpdGVtLmNoYXJ0LmRhdGEubGFiZWxzO1xuICAgICAgY29uc3QgbGFiZWxDb3VudCA9IGxhYmVscyA/IGxhYmVscy5sZW5ndGggOiAwO1xuXG4gICAgICBpZiAodGhpcyAmJiB0aGlzLm9wdGlvbnMgJiYgdGhpcy5vcHRpb25zLm1vZGUgPT09ICdkYXRhc2V0Jykge1xuICAgICAgICByZXR1cm4gaXRlbS5kYXRhc2V0LmxhYmVsIHx8ICcnO1xuICAgICAgfSBlbHNlIGlmIChpdGVtLmxhYmVsKSB7XG4gICAgICAgIHJldHVybiBpdGVtLmxhYmVsO1xuICAgICAgfSBlbHNlIGlmIChsYWJlbENvdW50ID4gMCAmJiBpdGVtLmRhdGFJbmRleCA8IGxhYmVsQ291bnQpIHtcbiAgICAgICAgcmV0dXJuIGxhYmVsc1tpdGVtLmRhdGFJbmRleF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICcnO1xuICB9LFxuICBhZnRlclRpdGxlOiBub29wLFxuXG4gIC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW1zLCBkYXRhKVxuICBiZWZvcmVCb2R5OiBub29wLFxuXG4gIC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW0sIGRhdGEpXG4gIGJlZm9yZUxhYmVsOiBub29wLFxuICBsYWJlbCh0b29sdGlwSXRlbSkge1xuICAgIGlmICh0aGlzICYmIHRoaXMub3B0aW9ucyAmJiB0aGlzLm9wdGlvbnMubW9kZSA9PT0gJ2RhdGFzZXQnKSB7XG4gICAgICByZXR1cm4gdG9vbHRpcEl0ZW0ubGFiZWwgKyAnOiAnICsgdG9vbHRpcEl0ZW0uZm9ybWF0dGVkVmFsdWUgfHwgdG9vbHRpcEl0ZW0uZm9ybWF0dGVkVmFsdWU7XG4gICAgfVxuXG4gICAgbGV0IGxhYmVsID0gdG9vbHRpcEl0ZW0uZGF0YXNldC5sYWJlbCB8fCAnJztcblxuICAgIGlmIChsYWJlbCkge1xuICAgICAgbGFiZWwgKz0gJzogJztcbiAgICB9XG4gICAgY29uc3QgdmFsdWUgPSB0b29sdGlwSXRlbS5mb3JtYXR0ZWRWYWx1ZTtcbiAgICBpZiAoIWlzTnVsbE9yVW5kZWYodmFsdWUpKSB7XG4gICAgICBsYWJlbCArPSB2YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGxhYmVsO1xuICB9LFxuICBsYWJlbENvbG9yKHRvb2x0aXBJdGVtKSB7XG4gICAgY29uc3QgbWV0YSA9IHRvb2x0aXBJdGVtLmNoYXJ0LmdldERhdGFzZXRNZXRhKHRvb2x0aXBJdGVtLmRhdGFzZXRJbmRleCk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IG1ldGEuY29udHJvbGxlci5nZXRTdHlsZSh0b29sdGlwSXRlbS5kYXRhSW5kZXgpO1xuICAgIHJldHVybiB7XG4gICAgICBib3JkZXJDb2xvcjogb3B0aW9ucy5ib3JkZXJDb2xvcixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBib3JkZXJXaWR0aDogb3B0aW9ucy5ib3JkZXJXaWR0aCxcbiAgICAgIGJvcmRlckRhc2g6IG9wdGlvbnMuYm9yZGVyRGFzaCxcbiAgICAgIGJvcmRlckRhc2hPZmZzZXQ6IG9wdGlvbnMuYm9yZGVyRGFzaE9mZnNldCxcbiAgICAgIGJvcmRlclJhZGl1czogMCxcbiAgICB9O1xuICB9LFxuICBsYWJlbFRleHRDb2xvcigpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmJvZHlDb2xvcjtcbiAgfSxcbiAgbGFiZWxQb2ludFN0eWxlKHRvb2x0aXBJdGVtKSB7XG4gICAgY29uc3QgbWV0YSA9IHRvb2x0aXBJdGVtLmNoYXJ0LmdldERhdGFzZXRNZXRhKHRvb2x0aXBJdGVtLmRhdGFzZXRJbmRleCk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IG1ldGEuY29udHJvbGxlci5nZXRTdHlsZSh0b29sdGlwSXRlbS5kYXRhSW5kZXgpO1xuICAgIHJldHVybiB7XG4gICAgICBwb2ludFN0eWxlOiBvcHRpb25zLnBvaW50U3R5bGUsXG4gICAgICByb3RhdGlvbjogb3B0aW9ucy5yb3RhdGlvbixcbiAgICB9O1xuICB9LFxuICBhZnRlckxhYmVsOiBub29wLFxuXG4gIC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW1zLCBkYXRhKVxuICBhZnRlckJvZHk6IG5vb3AsXG5cbiAgLy8gQXJncyBhcmU6ICh0b29sdGlwSXRlbXMsIGRhdGEpXG4gIGJlZm9yZUZvb3Rlcjogbm9vcCxcbiAgZm9vdGVyOiBub29wLFxuICBhZnRlckZvb3Rlcjogbm9vcFxufTtcblxuLyoqXG4gKiBJbnZva2UgY2FsbGJhY2sgZnJvbSBvYmplY3Qgd2l0aCBjb250ZXh0IGFuZCBhcmd1bWVudHMuXG4gKiBJZiBjYWxsYmFjayByZXR1cm5zIGB1bmRlZmluZWRgLCB0aGVuIHdpbGwgYmUgaW52b2tlZCBkZWZhdWx0IGNhbGxiYWNrLlxuICogQHBhcmFtIHtSZWNvcmQ8a2V5b2YgdHlwZW9mIGRlZmF1bHRDYWxsYmFja3MsIEZ1bmN0aW9uPn0gY2FsbGJhY2tzXG4gKiBAcGFyYW0ge2tleW9mIHR5cGVvZiBkZWZhdWx0Q2FsbGJhY2tzfSBuYW1lXG4gKiBAcGFyYW0geyp9IGN0eFxuICogQHBhcmFtIHsqfSBhcmdcbiAqIEByZXR1cm5zIHthbnl9XG4gKi9cbmZ1bmN0aW9uIGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKGNhbGxiYWNrcywgbmFtZSwgY3R4LCBhcmcpIHtcbiAgY29uc3QgcmVzdWx0ID0gY2FsbGJhY2tzW25hbWVdLmNhbGwoY3R4LCBhcmcpO1xuXG4gIGlmICh0eXBlb2YgcmVzdWx0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBkZWZhdWx0Q2FsbGJhY2tzW25hbWVdLmNhbGwoY3R4LCBhcmcpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGNsYXNzIFRvb2x0aXAgZXh0ZW5kcyBFbGVtZW50IHtcblxuICAvKipcbiAgICogQG5hbWVzcGFjZSBDaGFydC5Ub29sdGlwLnBvc2l0aW9uZXJzXG4gICAqL1xuICBzdGF0aWMgcG9zaXRpb25lcnMgPSBwb3NpdGlvbmVycztcblxuICBjb25zdHJ1Y3Rvcihjb25maWcpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5vcGFjaXR5ID0gMDtcbiAgICB0aGlzLl9hY3RpdmUgPSBbXTtcbiAgICB0aGlzLl9ldmVudFBvc2l0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3NpemUgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fY2FjaGVkQW5pbWF0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl90b29sdGlwSXRlbXMgPSBbXTtcbiAgICB0aGlzLiRhbmltYXRpb25zID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuJGNvbnRleHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jaGFydCA9IGNvbmZpZy5jaGFydDtcbiAgICB0aGlzLm9wdGlvbnMgPSBjb25maWcub3B0aW9ucztcbiAgICB0aGlzLmRhdGFQb2ludHMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy50aXRsZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmJlZm9yZUJvZHkgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5ib2R5ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuYWZ0ZXJCb2R5ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZm9vdGVyID0gdW5kZWZpbmVkO1xuICAgIHRoaXMueEFsaWduID0gdW5kZWZpbmVkO1xuICAgIHRoaXMueUFsaWduID0gdW5kZWZpbmVkO1xuICAgIHRoaXMueCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnkgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5oZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy53aWR0aCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmNhcmV0WCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmNhcmV0WSA9IHVuZGVmaW5lZDtcbiAgICAvLyBUT0RPOiBWNCwgbWFrZSB0aGlzIHByaXZhdGUsIHJlbmFtZSB0byBgX2xhYmVsU3R5bGVzYCwgYW5kIGNvbWJpbmUgd2l0aCBgbGFiZWxQb2ludFN0eWxlc2BcbiAgICAvLyBhbmQgYGxhYmVsVGV4dENvbG9yc2AgdG8gY3JlYXRlIGEgc2luZ2xlIHZhcmlhYmxlXG4gICAgdGhpcy5sYWJlbENvbG9ycyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmxhYmVsUG9pbnRTdHlsZXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sYWJlbFRleHRDb2xvcnMgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpbml0aWFsaXplKG9wdGlvbnMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMuX2NhY2hlZEFuaW1hdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy4kY29udGV4dCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3Jlc29sdmVBbmltYXRpb25zKCkge1xuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMuX2NhY2hlZEFuaW1hdGlvbnM7XG5cbiAgICBpZiAoY2FjaGVkKSB7XG4gICAgICByZXR1cm4gY2FjaGVkO1xuICAgIH1cblxuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KCkpO1xuICAgIGNvbnN0IG9wdHMgPSBvcHRpb25zLmVuYWJsZWQgJiYgY2hhcnQub3B0aW9ucy5hbmltYXRpb24gJiYgb3B0aW9ucy5hbmltYXRpb25zO1xuICAgIGNvbnN0IGFuaW1hdGlvbnMgPSBuZXcgQW5pbWF0aW9ucyh0aGlzLmNoYXJ0LCBvcHRzKTtcbiAgICBpZiAob3B0cy5fY2FjaGVhYmxlKSB7XG4gICAgICB0aGlzLl9jYWNoZWRBbmltYXRpb25zID0gT2JqZWN0LmZyZWV6ZShhbmltYXRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYW5pbWF0aW9ucztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRDb250ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLiRjb250ZXh0IHx8XG5cdFx0XHQodGhpcy4kY29udGV4dCA9IGNyZWF0ZVRvb2x0aXBDb250ZXh0KHRoaXMuY2hhcnQuZ2V0Q29udGV4dCgpLCB0aGlzLCB0aGlzLl90b29sdGlwSXRlbXMpKTtcbiAgfVxuXG4gIGdldFRpdGxlKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICBjb25zdCB7Y2FsbGJhY2tzfSA9IG9wdGlvbnM7XG5cbiAgICBjb25zdCBiZWZvcmVUaXRsZSA9IGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKGNhbGxiYWNrcywgJ2JlZm9yZVRpdGxlJywgdGhpcywgY29udGV4dCk7XG4gICAgY29uc3QgdGl0bGUgPSBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhjYWxsYmFja3MsICd0aXRsZScsIHRoaXMsIGNvbnRleHQpO1xuICAgIGNvbnN0IGFmdGVyVGl0bGUgPSBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhjYWxsYmFja3MsICdhZnRlclRpdGxlJywgdGhpcywgY29udGV4dCk7XG5cbiAgICBsZXQgbGluZXMgPSBbXTtcbiAgICBsaW5lcyA9IHB1c2hPckNvbmNhdChsaW5lcywgc3BsaXROZXdsaW5lcyhiZWZvcmVUaXRsZSkpO1xuICAgIGxpbmVzID0gcHVzaE9yQ29uY2F0KGxpbmVzLCBzcGxpdE5ld2xpbmVzKHRpdGxlKSk7XG4gICAgbGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYWZ0ZXJUaXRsZSkpO1xuXG4gICAgcmV0dXJuIGxpbmVzO1xuICB9XG5cbiAgZ2V0QmVmb3JlQm9keSh0b29sdGlwSXRlbXMsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gZ2V0QmVmb3JlQWZ0ZXJCb2R5TGluZXMoXG4gICAgICBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhvcHRpb25zLmNhbGxiYWNrcywgJ2JlZm9yZUJvZHknLCB0aGlzLCB0b29sdGlwSXRlbXMpXG4gICAgKTtcbiAgfVxuXG4gIGdldEJvZHkodG9vbHRpcEl0ZW1zLCBvcHRpb25zKSB7XG4gICAgY29uc3Qge2NhbGxiYWNrc30gPSBvcHRpb25zO1xuICAgIGNvbnN0IGJvZHlJdGVtcyA9IFtdO1xuXG4gICAgZWFjaCh0b29sdGlwSXRlbXMsIChjb250ZXh0KSA9PiB7XG4gICAgICBjb25zdCBib2R5SXRlbSA9IHtcbiAgICAgICAgYmVmb3JlOiBbXSxcbiAgICAgICAgbGluZXM6IFtdLFxuICAgICAgICBhZnRlcjogW11cbiAgICAgIH07XG4gICAgICBjb25zdCBzY29wZWQgPSBvdmVycmlkZUNhbGxiYWNrcyhjYWxsYmFja3MsIGNvbnRleHQpO1xuICAgICAgcHVzaE9yQ29uY2F0KGJvZHlJdGVtLmJlZm9yZSwgc3BsaXROZXdsaW5lcyhpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhzY29wZWQsICdiZWZvcmVMYWJlbCcsIHRoaXMsIGNvbnRleHQpKSk7XG4gICAgICBwdXNoT3JDb25jYXQoYm9keUl0ZW0ubGluZXMsIGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKHNjb3BlZCwgJ2xhYmVsJywgdGhpcywgY29udGV4dCkpO1xuICAgICAgcHVzaE9yQ29uY2F0KGJvZHlJdGVtLmFmdGVyLCBzcGxpdE5ld2xpbmVzKGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKHNjb3BlZCwgJ2FmdGVyTGFiZWwnLCB0aGlzLCBjb250ZXh0KSkpO1xuXG4gICAgICBib2R5SXRlbXMucHVzaChib2R5SXRlbSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gYm9keUl0ZW1zO1xuICB9XG5cbiAgZ2V0QWZ0ZXJCb2R5KHRvb2x0aXBJdGVtcywgb3B0aW9ucykge1xuICAgIHJldHVybiBnZXRCZWZvcmVBZnRlckJvZHlMaW5lcyhcbiAgICAgIGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKG9wdGlvbnMuY2FsbGJhY2tzLCAnYWZ0ZXJCb2R5JywgdGhpcywgdG9vbHRpcEl0ZW1zKVxuICAgICk7XG4gIH1cblxuICAvLyBHZXQgdGhlIGZvb3RlciBhbmQgYmVmb3JlRm9vdGVyIGFuZCBhZnRlckZvb3RlciBsaW5lc1xuICBnZXRGb290ZXIodG9vbHRpcEl0ZW1zLCBvcHRpb25zKSB7XG4gICAgY29uc3Qge2NhbGxiYWNrc30gPSBvcHRpb25zO1xuXG4gICAgY29uc3QgYmVmb3JlRm9vdGVyID0gaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soY2FsbGJhY2tzLCAnYmVmb3JlRm9vdGVyJywgdGhpcywgdG9vbHRpcEl0ZW1zKTtcbiAgICBjb25zdCBmb290ZXIgPSBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhjYWxsYmFja3MsICdmb290ZXInLCB0aGlzLCB0b29sdGlwSXRlbXMpO1xuICAgIGNvbnN0IGFmdGVyRm9vdGVyID0gaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soY2FsbGJhY2tzLCAnYWZ0ZXJGb290ZXInLCB0aGlzLCB0b29sdGlwSXRlbXMpO1xuXG4gICAgbGV0IGxpbmVzID0gW107XG4gICAgbGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYmVmb3JlRm9vdGVyKSk7XG4gICAgbGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoZm9vdGVyKSk7XG4gICAgbGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYWZ0ZXJGb290ZXIpKTtcblxuICAgIHJldHVybiBsaW5lcztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2NyZWF0ZUl0ZW1zKG9wdGlvbnMpIHtcbiAgICBjb25zdCBhY3RpdmUgPSB0aGlzLl9hY3RpdmU7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuY2hhcnQuZGF0YTtcbiAgICBjb25zdCBsYWJlbENvbG9ycyA9IFtdO1xuICAgIGNvbnN0IGxhYmVsUG9pbnRTdHlsZXMgPSBbXTtcbiAgICBjb25zdCBsYWJlbFRleHRDb2xvcnMgPSBbXTtcbiAgICBsZXQgdG9vbHRpcEl0ZW1zID0gW107XG4gICAgbGV0IGksIGxlbjtcblxuICAgIGZvciAoaSA9IDAsIGxlbiA9IGFjdGl2ZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgdG9vbHRpcEl0ZW1zLnB1c2goY3JlYXRlVG9vbHRpcEl0ZW0odGhpcy5jaGFydCwgYWN0aXZlW2ldKSk7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHVzZXIgcHJvdmlkZWQgYSBmaWx0ZXIgZnVuY3Rpb24sIHVzZSBpdCB0byBtb2RpZnkgdGhlIHRvb2x0aXAgaXRlbXNcbiAgICBpZiAob3B0aW9ucy5maWx0ZXIpIHtcbiAgICAgIHRvb2x0aXBJdGVtcyA9IHRvb2x0aXBJdGVtcy5maWx0ZXIoKGVsZW1lbnQsIGluZGV4LCBhcnJheSkgPT4gb3B0aW9ucy5maWx0ZXIoZWxlbWVudCwgaW5kZXgsIGFycmF5LCBkYXRhKSk7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHVzZXIgcHJvdmlkZWQgYSBzb3J0aW5nIGZ1bmN0aW9uLCB1c2UgaXQgdG8gbW9kaWZ5IHRoZSB0b29sdGlwIGl0ZW1zXG4gICAgaWYgKG9wdGlvbnMuaXRlbVNvcnQpIHtcbiAgICAgIHRvb2x0aXBJdGVtcyA9IHRvb2x0aXBJdGVtcy5zb3J0KChhLCBiKSA9PiBvcHRpb25zLml0ZW1Tb3J0KGEsIGIsIGRhdGEpKTtcbiAgICB9XG5cbiAgICAvLyBEZXRlcm1pbmUgY29sb3JzIGZvciBib3hlc1xuICAgIGVhY2godG9vbHRpcEl0ZW1zLCAoY29udGV4dCkgPT4ge1xuICAgICAgY29uc3Qgc2NvcGVkID0gb3ZlcnJpZGVDYWxsYmFja3Mob3B0aW9ucy5jYWxsYmFja3MsIGNvbnRleHQpO1xuICAgICAgbGFiZWxDb2xvcnMucHVzaChpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhzY29wZWQsICdsYWJlbENvbG9yJywgdGhpcywgY29udGV4dCkpO1xuICAgICAgbGFiZWxQb2ludFN0eWxlcy5wdXNoKGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKHNjb3BlZCwgJ2xhYmVsUG9pbnRTdHlsZScsIHRoaXMsIGNvbnRleHQpKTtcbiAgICAgIGxhYmVsVGV4dENvbG9ycy5wdXNoKGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKHNjb3BlZCwgJ2xhYmVsVGV4dENvbG9yJywgdGhpcywgY29udGV4dCkpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5sYWJlbENvbG9ycyA9IGxhYmVsQ29sb3JzO1xuICAgIHRoaXMubGFiZWxQb2ludFN0eWxlcyA9IGxhYmVsUG9pbnRTdHlsZXM7XG4gICAgdGhpcy5sYWJlbFRleHRDb2xvcnMgPSBsYWJlbFRleHRDb2xvcnM7XG4gICAgdGhpcy5kYXRhUG9pbnRzID0gdG9vbHRpcEl0ZW1zO1xuICAgIHJldHVybiB0b29sdGlwSXRlbXM7XG4gIH1cblxuICB1cGRhdGUoY2hhbmdlZCwgcmVwbGF5KSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucy5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICBjb25zdCBhY3RpdmUgPSB0aGlzLl9hY3RpdmU7XG4gICAgbGV0IHByb3BlcnRpZXM7XG4gICAgbGV0IHRvb2x0aXBJdGVtcyA9IFtdO1xuXG4gICAgaWYgKCFhY3RpdmUubGVuZ3RoKSB7XG4gICAgICBpZiAodGhpcy5vcGFjaXR5ICE9PSAwKSB7XG4gICAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgICAgb3BhY2l0eTogMFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IHBvc2l0aW9uZXJzW29wdGlvbnMucG9zaXRpb25dLmNhbGwodGhpcywgYWN0aXZlLCB0aGlzLl9ldmVudFBvc2l0aW9uKTtcbiAgICAgIHRvb2x0aXBJdGVtcyA9IHRoaXMuX2NyZWF0ZUl0ZW1zKG9wdGlvbnMpO1xuXG4gICAgICB0aGlzLnRpdGxlID0gdGhpcy5nZXRUaXRsZSh0b29sdGlwSXRlbXMsIG9wdGlvbnMpO1xuICAgICAgdGhpcy5iZWZvcmVCb2R5ID0gdGhpcy5nZXRCZWZvcmVCb2R5KHRvb2x0aXBJdGVtcywgb3B0aW9ucyk7XG4gICAgICB0aGlzLmJvZHkgPSB0aGlzLmdldEJvZHkodG9vbHRpcEl0ZW1zLCBvcHRpb25zKTtcbiAgICAgIHRoaXMuYWZ0ZXJCb2R5ID0gdGhpcy5nZXRBZnRlckJvZHkodG9vbHRpcEl0ZW1zLCBvcHRpb25zKTtcbiAgICAgIHRoaXMuZm9vdGVyID0gdGhpcy5nZXRGb290ZXIodG9vbHRpcEl0ZW1zLCBvcHRpb25zKTtcblxuICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuX3NpemUgPSBnZXRUb29sdGlwU2l6ZSh0aGlzLCBvcHRpb25zKTtcbiAgICAgIGNvbnN0IHBvc2l0aW9uQW5kU2l6ZSA9IE9iamVjdC5hc3NpZ24oe30sIHBvc2l0aW9uLCBzaXplKTtcbiAgICAgIGNvbnN0IGFsaWdubWVudCA9IGRldGVybWluZUFsaWdubWVudCh0aGlzLmNoYXJ0LCBvcHRpb25zLCBwb3NpdGlvbkFuZFNpemUpO1xuICAgICAgY29uc3QgYmFja2dyb3VuZFBvaW50ID0gZ2V0QmFja2dyb3VuZFBvaW50KG9wdGlvbnMsIHBvc2l0aW9uQW5kU2l6ZSwgYWxpZ25tZW50LCB0aGlzLmNoYXJ0KTtcblxuICAgICAgdGhpcy54QWxpZ24gPSBhbGlnbm1lbnQueEFsaWduO1xuICAgICAgdGhpcy55QWxpZ24gPSBhbGlnbm1lbnQueUFsaWduO1xuXG4gICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICB4OiBiYWNrZ3JvdW5kUG9pbnQueCxcbiAgICAgICAgeTogYmFja2dyb3VuZFBvaW50LnksXG4gICAgICAgIHdpZHRoOiBzaXplLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IHNpemUuaGVpZ2h0LFxuICAgICAgICBjYXJldFg6IHBvc2l0aW9uLngsXG4gICAgICAgIGNhcmV0WTogcG9zaXRpb24ueVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLl90b29sdGlwSXRlbXMgPSB0b29sdGlwSXRlbXM7XG4gICAgdGhpcy4kY29udGV4dCA9IHVuZGVmaW5lZDtcblxuICAgIGlmIChwcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLl9yZXNvbHZlQW5pbWF0aW9ucygpLnVwZGF0ZSh0aGlzLCBwcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlZCAmJiBvcHRpb25zLmV4dGVybmFsKSB7XG4gICAgICBvcHRpb25zLmV4dGVybmFsLmNhbGwodGhpcywge2NoYXJ0OiB0aGlzLmNoYXJ0LCB0b29sdGlwOiB0aGlzLCByZXBsYXl9KTtcbiAgICB9XG4gIH1cblxuICBkcmF3Q2FyZXQodG9vbHRpcFBvaW50LCBjdHgsIHNpemUsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBjYXJldFBvc2l0aW9uID0gdGhpcy5nZXRDYXJldFBvc2l0aW9uKHRvb2x0aXBQb2ludCwgc2l6ZSwgb3B0aW9ucyk7XG5cbiAgICBjdHgubGluZVRvKGNhcmV0UG9zaXRpb24ueDEsIGNhcmV0UG9zaXRpb24ueTEpO1xuICAgIGN0eC5saW5lVG8oY2FyZXRQb3NpdGlvbi54MiwgY2FyZXRQb3NpdGlvbi55Mik7XG4gICAgY3R4LmxpbmVUbyhjYXJldFBvc2l0aW9uLngzLCBjYXJldFBvc2l0aW9uLnkzKTtcbiAgfVxuXG4gIGdldENhcmV0UG9zaXRpb24odG9vbHRpcFBvaW50LCBzaXplLCBvcHRpb25zKSB7XG4gICAgY29uc3Qge3hBbGlnbiwgeUFsaWdufSA9IHRoaXM7XG4gICAgY29uc3Qge2NhcmV0U2l6ZSwgY29ybmVyUmFkaXVzfSA9IG9wdGlvbnM7XG4gICAgY29uc3Qge3RvcExlZnQsIHRvcFJpZ2h0LCBib3R0b21MZWZ0LCBib3R0b21SaWdodH0gPSB0b1RSQkxDb3JuZXJzKGNvcm5lclJhZGl1cyk7XG4gICAgY29uc3Qge3g6IHB0WCwgeTogcHRZfSA9IHRvb2x0aXBQb2ludDtcbiAgICBjb25zdCB7d2lkdGgsIGhlaWdodH0gPSBzaXplO1xuICAgIGxldCB4MSwgeDIsIHgzLCB5MSwgeTIsIHkzO1xuXG4gICAgaWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgIHkyID0gcHRZICsgKGhlaWdodCAvIDIpO1xuXG4gICAgICBpZiAoeEFsaWduID09PSAnbGVmdCcpIHtcbiAgICAgICAgeDEgPSBwdFg7XG4gICAgICAgIHgyID0geDEgLSBjYXJldFNpemU7XG5cbiAgICAgICAgLy8gTGVmdCBkcmF3cyBib3R0b20gLT4gdG9wLCB0aGlzIHkxIGlzIG9uIHRoZSBib3R0b21cbiAgICAgICAgeTEgPSB5MiArIGNhcmV0U2l6ZTtcbiAgICAgICAgeTMgPSB5MiAtIGNhcmV0U2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHgxID0gcHRYICsgd2lkdGg7XG4gICAgICAgIHgyID0geDEgKyBjYXJldFNpemU7XG5cbiAgICAgICAgLy8gUmlnaHQgZHJhd3MgdG9wIC0+IGJvdHRvbSwgdGh1cyB5MSBpcyBvbiB0aGUgdG9wXG4gICAgICAgIHkxID0geTIgLSBjYXJldFNpemU7XG4gICAgICAgIHkzID0geTIgKyBjYXJldFNpemU7XG4gICAgICB9XG5cbiAgICAgIHgzID0geDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh4QWxpZ24gPT09ICdsZWZ0Jykge1xuICAgICAgICB4MiA9IHB0WCArIE1hdGgubWF4KHRvcExlZnQsIGJvdHRvbUxlZnQpICsgKGNhcmV0U2l6ZSk7XG4gICAgICB9IGVsc2UgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICB4MiA9IHB0WCArIHdpZHRoIC0gTWF0aC5tYXgodG9wUmlnaHQsIGJvdHRvbVJpZ2h0KSAtIGNhcmV0U2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHgyID0gdGhpcy5jYXJldFg7XG4gICAgICB9XG5cbiAgICAgIGlmICh5QWxpZ24gPT09ICd0b3AnKSB7XG4gICAgICAgIHkxID0gcHRZO1xuICAgICAgICB5MiA9IHkxIC0gY2FyZXRTaXplO1xuXG4gICAgICAgIC8vIFRvcCBkcmF3cyBsZWZ0IC0+IHJpZ2h0LCB0aHVzIHgxIGlzIG9uIHRoZSBsZWZ0XG4gICAgICAgIHgxID0geDIgLSBjYXJldFNpemU7XG4gICAgICAgIHgzID0geDIgKyBjYXJldFNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB5MSA9IHB0WSArIGhlaWdodDtcbiAgICAgICAgeTIgPSB5MSArIGNhcmV0U2l6ZTtcblxuICAgICAgICAvLyBCb3R0b20gZHJhd3MgcmlnaHQgLT4gbGVmdCwgdGh1cyB4MSBpcyBvbiB0aGUgcmlnaHRcbiAgICAgICAgeDEgPSB4MiArIGNhcmV0U2l6ZTtcbiAgICAgICAgeDMgPSB4MiAtIGNhcmV0U2l6ZTtcbiAgICAgIH1cbiAgICAgIHkzID0geTE7XG4gICAgfVxuICAgIHJldHVybiB7eDEsIHgyLCB4MywgeTEsIHkyLCB5M307XG4gIH1cblxuICBkcmF3VGl0bGUocHQsIGN0eCwgb3B0aW9ucykge1xuICAgIGNvbnN0IHRpdGxlID0gdGhpcy50aXRsZTtcbiAgICBjb25zdCBsZW5ndGggPSB0aXRsZS5sZW5ndGg7XG4gICAgbGV0IHRpdGxlRm9udCwgdGl0bGVTcGFjaW5nLCBpO1xuXG4gICAgaWYgKGxlbmd0aCkge1xuICAgICAgY29uc3QgcnRsSGVscGVyID0gZ2V0UnRsQWRhcHRlcihvcHRpb25zLnJ0bCwgdGhpcy54LCB0aGlzLndpZHRoKTtcblxuICAgICAgcHQueCA9IGdldEFsaWduZWRYKHRoaXMsIG9wdGlvbnMudGl0bGVBbGlnbiwgb3B0aW9ucyk7XG5cbiAgICAgIGN0eC50ZXh0QWxpZ24gPSBydGxIZWxwZXIudGV4dEFsaWduKG9wdGlvbnMudGl0bGVBbGlnbik7XG4gICAgICBjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG5cbiAgICAgIHRpdGxlRm9udCA9IHRvRm9udChvcHRpb25zLnRpdGxlRm9udCk7XG4gICAgICB0aXRsZVNwYWNpbmcgPSBvcHRpb25zLnRpdGxlU3BhY2luZztcblxuICAgICAgY3R4LmZpbGxTdHlsZSA9IG9wdGlvbnMudGl0bGVDb2xvcjtcbiAgICAgIGN0eC5mb250ID0gdGl0bGVGb250LnN0cmluZztcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICAgIGN0eC5maWxsVGV4dCh0aXRsZVtpXSwgcnRsSGVscGVyLngocHQueCksIHB0LnkgKyB0aXRsZUZvbnQubGluZUhlaWdodCAvIDIpO1xuICAgICAgICBwdC55ICs9IHRpdGxlRm9udC5saW5lSGVpZ2h0ICsgdGl0bGVTcGFjaW5nOyAvLyBMaW5lIEhlaWdodCBhbmQgc3BhY2luZ1xuXG4gICAgICAgIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgcHQueSArPSBvcHRpb25zLnRpdGxlTWFyZ2luQm90dG9tIC0gdGl0bGVTcGFjaW5nOyAvLyBJZiBMYXN0LCBhZGQgbWFyZ2luLCByZW1vdmUgc3BhY2luZ1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZHJhd0NvbG9yQm94KGN0eCwgcHQsIGksIHJ0bEhlbHBlciwgb3B0aW9ucykge1xuICAgIGNvbnN0IGxhYmVsQ29sb3IgPSB0aGlzLmxhYmVsQ29sb3JzW2ldO1xuICAgIGNvbnN0IGxhYmVsUG9pbnRTdHlsZSA9IHRoaXMubGFiZWxQb2ludFN0eWxlc1tpXTtcbiAgICBjb25zdCB7Ym94SGVpZ2h0LCBib3hXaWR0aH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IGJvZHlGb250ID0gdG9Gb250KG9wdGlvbnMuYm9keUZvbnQpO1xuICAgIGNvbnN0IGNvbG9yWCA9IGdldEFsaWduZWRYKHRoaXMsICdsZWZ0Jywgb3B0aW9ucyk7XG4gICAgY29uc3QgcnRsQ29sb3JYID0gcnRsSGVscGVyLngoY29sb3JYKTtcbiAgICBjb25zdCB5T2ZmU2V0ID0gYm94SGVpZ2h0IDwgYm9keUZvbnQubGluZUhlaWdodCA/IChib2R5Rm9udC5saW5lSGVpZ2h0IC0gYm94SGVpZ2h0KSAvIDIgOiAwO1xuICAgIGNvbnN0IGNvbG9yWSA9IHB0LnkgKyB5T2ZmU2V0O1xuXG4gICAgaWYgKG9wdGlvbnMudXNlUG9pbnRTdHlsZSkge1xuICAgICAgY29uc3QgZHJhd09wdGlvbnMgPSB7XG4gICAgICAgIHJhZGl1czogTWF0aC5taW4oYm94V2lkdGgsIGJveEhlaWdodCkgLyAyLCAvLyBmaXQgdGhlIGNpcmNsZSBpbiB0aGUgYm94XG4gICAgICAgIHBvaW50U3R5bGU6IGxhYmVsUG9pbnRTdHlsZS5wb2ludFN0eWxlLFxuICAgICAgICByb3RhdGlvbjogbGFiZWxQb2ludFN0eWxlLnJvdGF0aW9uLFxuICAgICAgICBib3JkZXJXaWR0aDogMVxuICAgICAgfTtcbiAgICAgIC8vIFJlY2FsY3VsYXRlIHggYW5kIHkgZm9yIGRyYXdQb2ludCgpIGJlY2F1c2UgaXRzIGV4cGVjdGluZ1xuICAgICAgLy8geCBhbmQgeSB0byBiZSBjZW50ZXIgb2YgZmlndXJlIChpbnN0ZWFkIG9mIHRvcCBsZWZ0KVxuICAgICAgY29uc3QgY2VudGVyWCA9IHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHJ0bENvbG9yWCwgYm94V2lkdGgpICsgYm94V2lkdGggLyAyO1xuICAgICAgY29uc3QgY2VudGVyWSA9IGNvbG9yWSArIGJveEhlaWdodCAvIDI7XG5cbiAgICAgIC8vIEZpbGwgdGhlIHBvaW50IHdpdGggd2hpdGUgc28gdGhhdCBjb2xvdXJzIG1lcmdlIG5pY2VseSBpZiB0aGUgb3BhY2l0eSBpcyA8IDFcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IG9wdGlvbnMubXVsdGlLZXlCYWNrZ3JvdW5kO1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IG9wdGlvbnMubXVsdGlLZXlCYWNrZ3JvdW5kO1xuICAgICAgZHJhd1BvaW50KGN0eCwgZHJhd09wdGlvbnMsIGNlbnRlclgsIGNlbnRlclkpO1xuXG4gICAgICAvLyBEcmF3IHRoZSBwb2ludFxuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gbGFiZWxDb2xvci5ib3JkZXJDb2xvcjtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBsYWJlbENvbG9yLmJhY2tncm91bmRDb2xvcjtcbiAgICAgIGRyYXdQb2ludChjdHgsIGRyYXdPcHRpb25zLCBjZW50ZXJYLCBjZW50ZXJZKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQm9yZGVyXG4gICAgICBjdHgubGluZVdpZHRoID0gaXNPYmplY3QobGFiZWxDb2xvci5ib3JkZXJXaWR0aCkgPyBNYXRoLm1heCguLi5PYmplY3QudmFsdWVzKGxhYmVsQ29sb3IuYm9yZGVyV2lkdGgpKSA6IChsYWJlbENvbG9yLmJvcmRlcldpZHRoIHx8IDEpOyAvLyBUT0RPLCB2NCByZW1vdmUgZmFsbGJhY2tcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IGxhYmVsQ29sb3IuYm9yZGVyQ29sb3I7XG4gICAgICBjdHguc2V0TGluZURhc2gobGFiZWxDb2xvci5ib3JkZXJEYXNoIHx8IFtdKTtcbiAgICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IGxhYmVsQ29sb3IuYm9yZGVyRGFzaE9mZnNldCB8fCAwO1xuXG4gICAgICAvLyBGaWxsIGEgd2hpdGUgcmVjdCBzbyB0aGF0IGNvbG91cnMgbWVyZ2UgbmljZWx5IGlmIHRoZSBvcGFjaXR5IGlzIDwgMVxuICAgICAgY29uc3Qgb3V0ZXJYID0gcnRsSGVscGVyLmxlZnRGb3JMdHIocnRsQ29sb3JYLCBib3hXaWR0aCk7XG4gICAgICBjb25zdCBpbm5lclggPSBydGxIZWxwZXIubGVmdEZvckx0cihydGxIZWxwZXIueFBsdXMocnRsQ29sb3JYLCAxKSwgYm94V2lkdGggLSAyKTtcbiAgICAgIGNvbnN0IGJvcmRlclJhZGl1cyA9IHRvVFJCTENvcm5lcnMobGFiZWxDb2xvci5ib3JkZXJSYWRpdXMpO1xuXG4gICAgICBpZiAoT2JqZWN0LnZhbHVlcyhib3JkZXJSYWRpdXMpLnNvbWUodiA9PiB2ICE9PSAwKSkge1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLm11bHRpS2V5QmFja2dyb3VuZDtcbiAgICAgICAgYWRkUm91bmRlZFJlY3RQYXRoKGN0eCwge1xuICAgICAgICAgIHg6IG91dGVyWCxcbiAgICAgICAgICB5OiBjb2xvclksXG4gICAgICAgICAgdzogYm94V2lkdGgsXG4gICAgICAgICAgaDogYm94SGVpZ2h0LFxuICAgICAgICAgIHJhZGl1czogYm9yZGVyUmFkaXVzLFxuICAgICAgICB9KTtcbiAgICAgICAgY3R4LmZpbGwoKTtcbiAgICAgICAgY3R4LnN0cm9rZSgpO1xuXG4gICAgICAgIC8vIElubmVyIHNxdWFyZVxuICAgICAgICBjdHguZmlsbFN0eWxlID0gbGFiZWxDb2xvci5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgYWRkUm91bmRlZFJlY3RQYXRoKGN0eCwge1xuICAgICAgICAgIHg6IGlubmVyWCxcbiAgICAgICAgICB5OiBjb2xvclkgKyAxLFxuICAgICAgICAgIHc6IGJveFdpZHRoIC0gMixcbiAgICAgICAgICBoOiBib3hIZWlnaHQgLSAyLFxuICAgICAgICAgIHJhZGl1czogYm9yZGVyUmFkaXVzLFxuICAgICAgICB9KTtcbiAgICAgICAgY3R4LmZpbGwoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE5vcm1hbCByZWN0XG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLm11bHRpS2V5QmFja2dyb3VuZDtcbiAgICAgICAgY3R4LmZpbGxSZWN0KG91dGVyWCwgY29sb3JZLCBib3hXaWR0aCwgYm94SGVpZ2h0KTtcbiAgICAgICAgY3R4LnN0cm9rZVJlY3Qob3V0ZXJYLCBjb2xvclksIGJveFdpZHRoLCBib3hIZWlnaHQpO1xuICAgICAgICAvLyBJbm5lciBzcXVhcmVcbiAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGxhYmVsQ29sb3IuYmFja2dyb3VuZENvbG9yO1xuICAgICAgICBjdHguZmlsbFJlY3QoaW5uZXJYLCBjb2xvclkgKyAxLCBib3hXaWR0aCAtIDIsIGJveEhlaWdodCAtIDIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHJlc3RvcmUgZmlsbFN0eWxlXG4gICAgY3R4LmZpbGxTdHlsZSA9IHRoaXMubGFiZWxUZXh0Q29sb3JzW2ldO1xuICB9XG5cbiAgZHJhd0JvZHkocHQsIGN0eCwgb3B0aW9ucykge1xuICAgIGNvbnN0IHtib2R5fSA9IHRoaXM7XG4gICAgY29uc3Qge2JvZHlTcGFjaW5nLCBib2R5QWxpZ24sIGRpc3BsYXlDb2xvcnMsIGJveEhlaWdodCwgYm94V2lkdGgsIGJveFBhZGRpbmd9ID0gb3B0aW9ucztcbiAgICBjb25zdCBib2R5Rm9udCA9IHRvRm9udChvcHRpb25zLmJvZHlGb250KTtcbiAgICBsZXQgYm9keUxpbmVIZWlnaHQgPSBib2R5Rm9udC5saW5lSGVpZ2h0O1xuICAgIGxldCB4TGluZVBhZGRpbmcgPSAwO1xuXG4gICAgY29uc3QgcnRsSGVscGVyID0gZ2V0UnRsQWRhcHRlcihvcHRpb25zLnJ0bCwgdGhpcy54LCB0aGlzLndpZHRoKTtcblxuICAgIGNvbnN0IGZpbGxMaW5lT2ZUZXh0ID0gZnVuY3Rpb24obGluZSkge1xuICAgICAgY3R4LmZpbGxUZXh0KGxpbmUsIHJ0bEhlbHBlci54KHB0LnggKyB4TGluZVBhZGRpbmcpLCBwdC55ICsgYm9keUxpbmVIZWlnaHQgLyAyKTtcbiAgICAgIHB0LnkgKz0gYm9keUxpbmVIZWlnaHQgKyBib2R5U3BhY2luZztcbiAgICB9O1xuXG4gICAgY29uc3QgYm9keUFsaWduRm9yQ2FsY3VsYXRpb24gPSBydGxIZWxwZXIudGV4dEFsaWduKGJvZHlBbGlnbik7XG4gICAgbGV0IGJvZHlJdGVtLCB0ZXh0Q29sb3IsIGxpbmVzLCBpLCBqLCBpbGVuLCBqbGVuO1xuXG4gICAgY3R4LnRleHRBbGlnbiA9IGJvZHlBbGlnbjtcbiAgICBjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG4gICAgY3R4LmZvbnQgPSBib2R5Rm9udC5zdHJpbmc7XG5cbiAgICBwdC54ID0gZ2V0QWxpZ25lZFgodGhpcywgYm9keUFsaWduRm9yQ2FsY3VsYXRpb24sIG9wdGlvbnMpO1xuXG4gICAgLy8gQmVmb3JlIGJvZHkgbGluZXNcbiAgICBjdHguZmlsbFN0eWxlID0gb3B0aW9ucy5ib2R5Q29sb3I7XG4gICAgZWFjaCh0aGlzLmJlZm9yZUJvZHksIGZpbGxMaW5lT2ZUZXh0KTtcblxuICAgIHhMaW5lUGFkZGluZyA9IGRpc3BsYXlDb2xvcnMgJiYgYm9keUFsaWduRm9yQ2FsY3VsYXRpb24gIT09ICdyaWdodCdcbiAgICAgID8gYm9keUFsaWduID09PSAnY2VudGVyJyA/IChib3hXaWR0aCAvIDIgKyBib3hQYWRkaW5nKSA6IChib3hXaWR0aCArIDIgKyBib3hQYWRkaW5nKVxuICAgICAgOiAwO1xuXG4gICAgLy8gRHJhdyBib2R5IGxpbmVzIG5vd1xuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBib2R5Lmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgYm9keUl0ZW0gPSBib2R5W2ldO1xuICAgICAgdGV4dENvbG9yID0gdGhpcy5sYWJlbFRleHRDb2xvcnNbaV07XG5cbiAgICAgIGN0eC5maWxsU3R5bGUgPSB0ZXh0Q29sb3I7XG4gICAgICBlYWNoKGJvZHlJdGVtLmJlZm9yZSwgZmlsbExpbmVPZlRleHQpO1xuXG4gICAgICBsaW5lcyA9IGJvZHlJdGVtLmxpbmVzO1xuICAgICAgLy8gRHJhdyBMZWdlbmQtbGlrZSBib3hlcyBpZiBuZWVkZWRcbiAgICAgIGlmIChkaXNwbGF5Q29sb3JzICYmIGxpbmVzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLl9kcmF3Q29sb3JCb3goY3R4LCBwdCwgaSwgcnRsSGVscGVyLCBvcHRpb25zKTtcbiAgICAgICAgYm9keUxpbmVIZWlnaHQgPSBNYXRoLm1heChib2R5Rm9udC5saW5lSGVpZ2h0LCBib3hIZWlnaHQpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGogPSAwLCBqbGVuID0gbGluZXMubGVuZ3RoOyBqIDwgamxlbjsgKytqKSB7XG4gICAgICAgIGZpbGxMaW5lT2ZUZXh0KGxpbmVzW2pdKTtcbiAgICAgICAgLy8gUmVzZXQgZm9yIGFueSBsaW5lcyB0aGF0IGRvbid0IGluY2x1ZGUgY29sb3Jib3hcbiAgICAgICAgYm9keUxpbmVIZWlnaHQgPSBib2R5Rm9udC5saW5lSGVpZ2h0O1xuICAgICAgfVxuXG4gICAgICBlYWNoKGJvZHlJdGVtLmFmdGVyLCBmaWxsTGluZU9mVGV4dCk7XG4gICAgfVxuXG4gICAgLy8gUmVzZXQgYmFjayB0byAwIGZvciBhZnRlciBib2R5XG4gICAgeExpbmVQYWRkaW5nID0gMDtcbiAgICBib2R5TGluZUhlaWdodCA9IGJvZHlGb250LmxpbmVIZWlnaHQ7XG5cbiAgICAvLyBBZnRlciBib2R5IGxpbmVzXG4gICAgZWFjaCh0aGlzLmFmdGVyQm9keSwgZmlsbExpbmVPZlRleHQpO1xuICAgIHB0LnkgLT0gYm9keVNwYWNpbmc7IC8vIFJlbW92ZSBsYXN0IGJvZHkgc3BhY2luZ1xuICB9XG5cbiAgZHJhd0Zvb3RlcihwdCwgY3R4LCBvcHRpb25zKSB7XG4gICAgY29uc3QgZm9vdGVyID0gdGhpcy5mb290ZXI7XG4gICAgY29uc3QgbGVuZ3RoID0gZm9vdGVyLmxlbmd0aDtcbiAgICBsZXQgZm9vdGVyRm9udCwgaTtcblxuICAgIGlmIChsZW5ndGgpIHtcbiAgICAgIGNvbnN0IHJ0bEhlbHBlciA9IGdldFJ0bEFkYXB0ZXIob3B0aW9ucy5ydGwsIHRoaXMueCwgdGhpcy53aWR0aCk7XG5cbiAgICAgIHB0LnggPSBnZXRBbGlnbmVkWCh0aGlzLCBvcHRpb25zLmZvb3RlckFsaWduLCBvcHRpb25zKTtcbiAgICAgIHB0LnkgKz0gb3B0aW9ucy5mb290ZXJNYXJnaW5Ub3A7XG5cbiAgICAgIGN0eC50ZXh0QWxpZ24gPSBydGxIZWxwZXIudGV4dEFsaWduKG9wdGlvbnMuZm9vdGVyQWxpZ24pO1xuICAgICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuXG4gICAgICBmb290ZXJGb250ID0gdG9Gb250KG9wdGlvbnMuZm9vdGVyRm9udCk7XG5cbiAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLmZvb3RlckNvbG9yO1xuICAgICAgY3R4LmZvbnQgPSBmb290ZXJGb250LnN0cmluZztcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICAgIGN0eC5maWxsVGV4dChmb290ZXJbaV0sIHJ0bEhlbHBlci54KHB0LngpLCBwdC55ICsgZm9vdGVyRm9udC5saW5lSGVpZ2h0IC8gMik7XG4gICAgICAgIHB0LnkgKz0gZm9vdGVyRm9udC5saW5lSGVpZ2h0ICsgb3B0aW9ucy5mb290ZXJTcGFjaW5nO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGRyYXdCYWNrZ3JvdW5kKHB0LCBjdHgsIHRvb2x0aXBTaXplLCBvcHRpb25zKSB7XG4gICAgY29uc3Qge3hBbGlnbiwgeUFsaWdufSA9IHRoaXM7XG4gICAgY29uc3Qge3gsIHl9ID0gcHQ7XG4gICAgY29uc3Qge3dpZHRoLCBoZWlnaHR9ID0gdG9vbHRpcFNpemU7XG4gICAgY29uc3Qge3RvcExlZnQsIHRvcFJpZ2h0LCBib3R0b21MZWZ0LCBib3R0b21SaWdodH0gPSB0b1RSQkxDb3JuZXJzKG9wdGlvbnMuY29ybmVyUmFkaXVzKTtcblxuICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLmJhY2tncm91bmRDb2xvcjtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBvcHRpb25zLmJvcmRlckNvbG9yO1xuICAgIGN0eC5saW5lV2lkdGggPSBvcHRpb25zLmJvcmRlcldpZHRoO1xuXG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGN0eC5tb3ZlVG8oeCArIHRvcExlZnQsIHkpO1xuICAgIGlmICh5QWxpZ24gPT09ICd0b3AnKSB7XG4gICAgICB0aGlzLmRyYXdDYXJldChwdCwgY3R4LCB0b29sdGlwU2l6ZSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIGN0eC5saW5lVG8oeCArIHdpZHRoIC0gdG9wUmlnaHQsIHkpO1xuICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHggKyB3aWR0aCwgeSwgeCArIHdpZHRoLCB5ICsgdG9wUmlnaHQpO1xuICAgIGlmICh5QWxpZ24gPT09ICdjZW50ZXInICYmIHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgdGhpcy5kcmF3Q2FyZXQocHQsIGN0eCwgdG9vbHRpcFNpemUsIG9wdGlvbnMpO1xuICAgIH1cbiAgICBjdHgubGluZVRvKHggKyB3aWR0aCwgeSArIGhlaWdodCAtIGJvdHRvbVJpZ2h0KTtcbiAgICBjdHgucXVhZHJhdGljQ3VydmVUbyh4ICsgd2lkdGgsIHkgKyBoZWlnaHQsIHggKyB3aWR0aCAtIGJvdHRvbVJpZ2h0LCB5ICsgaGVpZ2h0KTtcbiAgICBpZiAoeUFsaWduID09PSAnYm90dG9tJykge1xuICAgICAgdGhpcy5kcmF3Q2FyZXQocHQsIGN0eCwgdG9vbHRpcFNpemUsIG9wdGlvbnMpO1xuICAgIH1cbiAgICBjdHgubGluZVRvKHggKyBib3R0b21MZWZ0LCB5ICsgaGVpZ2h0KTtcbiAgICBjdHgucXVhZHJhdGljQ3VydmVUbyh4LCB5ICsgaGVpZ2h0LCB4LCB5ICsgaGVpZ2h0IC0gYm90dG9tTGVmdCk7XG4gICAgaWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicgJiYgeEFsaWduID09PSAnbGVmdCcpIHtcbiAgICAgIHRoaXMuZHJhd0NhcmV0KHB0LCBjdHgsIHRvb2x0aXBTaXplLCBvcHRpb25zKTtcbiAgICB9XG4gICAgY3R4LmxpbmVUbyh4LCB5ICsgdG9wTGVmdCk7XG4gICAgY3R4LnF1YWRyYXRpY0N1cnZlVG8oeCwgeSwgeCArIHRvcExlZnQsIHkpO1xuICAgIGN0eC5jbG9zZVBhdGgoKTtcblxuICAgIGN0eC5maWxsKCk7XG5cbiAgICBpZiAob3B0aW9ucy5ib3JkZXJXaWR0aCA+IDApIHtcbiAgICAgIGN0eC5zdHJva2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogVXBkYXRlIHgveSBhbmltYXRpb24gdGFyZ2V0cyB3aGVuIF9hY3RpdmUgZWxlbWVudHMgYXJlIGFuaW1hdGluZyB0b29cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF91cGRhdGVBbmltYXRpb25UYXJnZXQob3B0aW9ucykge1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBhbmltcyA9IHRoaXMuJGFuaW1hdGlvbnM7XG4gICAgY29uc3QgYW5pbVggPSBhbmltcyAmJiBhbmltcy54O1xuICAgIGNvbnN0IGFuaW1ZID0gYW5pbXMgJiYgYW5pbXMueTtcbiAgICBpZiAoYW5pbVggfHwgYW5pbVkpIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gcG9zaXRpb25lcnNbb3B0aW9ucy5wb3NpdGlvbl0uY2FsbCh0aGlzLCB0aGlzLl9hY3RpdmUsIHRoaXMuX2V2ZW50UG9zaXRpb24pO1xuICAgICAgaWYgKCFwb3NpdGlvbikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBzaXplID0gdGhpcy5fc2l6ZSA9IGdldFRvb2x0aXBTaXplKHRoaXMsIG9wdGlvbnMpO1xuICAgICAgY29uc3QgcG9zaXRpb25BbmRTaXplID0gT2JqZWN0LmFzc2lnbih7fSwgcG9zaXRpb24sIHRoaXMuX3NpemUpO1xuICAgICAgY29uc3QgYWxpZ25tZW50ID0gZGV0ZXJtaW5lQWxpZ25tZW50KGNoYXJ0LCBvcHRpb25zLCBwb3NpdGlvbkFuZFNpemUpO1xuICAgICAgY29uc3QgcG9pbnQgPSBnZXRCYWNrZ3JvdW5kUG9pbnQob3B0aW9ucywgcG9zaXRpb25BbmRTaXplLCBhbGlnbm1lbnQsIGNoYXJ0KTtcbiAgICAgIGlmIChhbmltWC5fdG8gIT09IHBvaW50LnggfHwgYW5pbVkuX3RvICE9PSBwb2ludC55KSB7XG4gICAgICAgIHRoaXMueEFsaWduID0gYWxpZ25tZW50LnhBbGlnbjtcbiAgICAgICAgdGhpcy55QWxpZ24gPSBhbGlnbm1lbnQueUFsaWduO1xuICAgICAgICB0aGlzLndpZHRoID0gc2l6ZS53aWR0aDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBzaXplLmhlaWdodDtcbiAgICAgICAgdGhpcy5jYXJldFggPSBwb3NpdGlvbi54O1xuICAgICAgICB0aGlzLmNhcmV0WSA9IHBvc2l0aW9uLnk7XG4gICAgICAgIHRoaXMuX3Jlc29sdmVBbmltYXRpb25zKCkudXBkYXRlKHRoaXMsIHBvaW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIHRoZSB0b29sdGlwIHdpbGwgZHJhdyBhbnl0aGluZ1xuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdG9vbHRpcCB3aWxsIHJlbmRlclxuICAgKi9cbiAgX3dpbGxSZW5kZXIoKSB7XG4gICAgcmV0dXJuICEhdGhpcy5vcGFjaXR5O1xuICB9XG5cbiAgZHJhdyhjdHgpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KCkpO1xuICAgIGxldCBvcGFjaXR5ID0gdGhpcy5vcGFjaXR5O1xuXG4gICAgaWYgKCFvcGFjaXR5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlQW5pbWF0aW9uVGFyZ2V0KG9wdGlvbnMpO1xuXG4gICAgY29uc3QgdG9vbHRpcFNpemUgPSB7XG4gICAgICB3aWR0aDogdGhpcy53aWR0aCxcbiAgICAgIGhlaWdodDogdGhpcy5oZWlnaHRcbiAgICB9O1xuICAgIGNvbnN0IHB0ID0ge1xuICAgICAgeDogdGhpcy54LFxuICAgICAgeTogdGhpcy55XG4gICAgfTtcblxuICAgIC8vIElFMTEvRWRnZSBkb2VzIG5vdCBsaWtlIHZlcnkgc21hbGwgb3BhY2l0aWVzLCBzbyBzbmFwIHRvIDBcbiAgICBvcGFjaXR5ID0gTWF0aC5hYnMob3BhY2l0eSkgPCAxZS0zID8gMCA6IG9wYWNpdHk7XG5cbiAgICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKG9wdGlvbnMucGFkZGluZyk7XG5cbiAgICAvLyBUcnV0aHkvZmFsc2V5IHZhbHVlIGZvciBlbXB0eSB0b29sdGlwXG4gICAgY29uc3QgaGFzVG9vbHRpcENvbnRlbnQgPSB0aGlzLnRpdGxlLmxlbmd0aCB8fCB0aGlzLmJlZm9yZUJvZHkubGVuZ3RoIHx8IHRoaXMuYm9keS5sZW5ndGggfHwgdGhpcy5hZnRlckJvZHkubGVuZ3RoIHx8IHRoaXMuZm9vdGVyLmxlbmd0aDtcblxuICAgIGlmIChvcHRpb25zLmVuYWJsZWQgJiYgaGFzVG9vbHRpcENvbnRlbnQpIHtcbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICBjdHguZ2xvYmFsQWxwaGEgPSBvcGFjaXR5O1xuXG4gICAgICAvLyBEcmF3IEJhY2tncm91bmRcbiAgICAgIHRoaXMuZHJhd0JhY2tncm91bmQocHQsIGN0eCwgdG9vbHRpcFNpemUsIG9wdGlvbnMpO1xuXG4gICAgICBvdmVycmlkZVRleHREaXJlY3Rpb24oY3R4LCBvcHRpb25zLnRleHREaXJlY3Rpb24pO1xuXG4gICAgICBwdC55ICs9IHBhZGRpbmcudG9wO1xuXG4gICAgICAvLyBUaXRsZXNcbiAgICAgIHRoaXMuZHJhd1RpdGxlKHB0LCBjdHgsIG9wdGlvbnMpO1xuXG4gICAgICAvLyBCb2R5XG4gICAgICB0aGlzLmRyYXdCb2R5KHB0LCBjdHgsIG9wdGlvbnMpO1xuXG4gICAgICAvLyBGb290ZXJcbiAgICAgIHRoaXMuZHJhd0Zvb3RlcihwdCwgY3R4LCBvcHRpb25zKTtcblxuICAgICAgcmVzdG9yZVRleHREaXJlY3Rpb24oY3R4LCBvcHRpb25zLnRleHREaXJlY3Rpb24pO1xuXG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBHZXQgYWN0aXZlIGVsZW1lbnRzIGluIHRoZSB0b29sdGlwXG5cdCAqIEByZXR1cm5zIHtBcnJheX0gQXJyYXkgb2YgZWxlbWVudHMgdGhhdCBhcmUgYWN0aXZlIGluIHRoZSB0b29sdGlwXG5cdCAqL1xuICBnZXRBY3RpdmVFbGVtZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy5fYWN0aXZlIHx8IFtdO1xuICB9XG5cbiAgLyoqXG5cdCAqIFNldCBhY3RpdmUgZWxlbWVudHMgaW4gdGhlIHRvb2x0aXBcblx0ICogQHBhcmFtIHthcnJheX0gYWN0aXZlRWxlbWVudHMgQXJyYXkgb2YgYWN0aXZlIGRhdGFzZXRJbmRleC9pbmRleCBwYWlycy5cblx0ICogQHBhcmFtIHtvYmplY3R9IGV2ZW50UG9zaXRpb24gU3ludGhldGljIGV2ZW50IHBvc2l0aW9uIHVzZWQgaW4gcG9zaXRpb25pbmdcblx0ICovXG4gIHNldEFjdGl2ZUVsZW1lbnRzKGFjdGl2ZUVsZW1lbnRzLCBldmVudFBvc2l0aW9uKSB7XG4gICAgY29uc3QgbGFzdEFjdGl2ZSA9IHRoaXMuX2FjdGl2ZTtcbiAgICBjb25zdCBhY3RpdmUgPSBhY3RpdmVFbGVtZW50cy5tYXAoKHtkYXRhc2V0SW5kZXgsIGluZGV4fSkgPT4ge1xuICAgICAgY29uc3QgbWV0YSA9IHRoaXMuY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcblxuICAgICAgaWYgKCFtZXRhKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgYSBkYXRhc2V0IGF0IGluZGV4ICcgKyBkYXRhc2V0SW5kZXgpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXRhc2V0SW5kZXgsXG4gICAgICAgIGVsZW1lbnQ6IG1ldGEuZGF0YVtpbmRleF0sXG4gICAgICAgIGluZGV4LFxuICAgICAgfTtcbiAgICB9KTtcbiAgICBjb25zdCBjaGFuZ2VkID0gIV9lbGVtZW50c0VxdWFsKGxhc3RBY3RpdmUsIGFjdGl2ZSk7XG4gICAgY29uc3QgcG9zaXRpb25DaGFuZ2VkID0gdGhpcy5fcG9zaXRpb25DaGFuZ2VkKGFjdGl2ZSwgZXZlbnRQb3NpdGlvbik7XG5cbiAgICBpZiAoY2hhbmdlZCB8fCBwb3NpdGlvbkNoYW5nZWQpIHtcbiAgICAgIHRoaXMuX2FjdGl2ZSA9IGFjdGl2ZTtcbiAgICAgIHRoaXMuX2V2ZW50UG9zaXRpb24gPSBldmVudFBvc2l0aW9uO1xuICAgICAgdGhpcy5faWdub3JlUmVwbGF5RXZlbnRzID0gdHJ1ZTtcbiAgICAgIHRoaXMudXBkYXRlKHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBIYW5kbGUgYW4gZXZlbnRcblx0ICogQHBhcmFtIHtDaGFydEV2ZW50fSBlIC0gVGhlIGV2ZW50IHRvIGhhbmRsZVxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXBsYXldIC0gVGhpcyBpcyBhIHJlcGxheWVkIGV2ZW50IChmcm9tIHVwZGF0ZSlcblx0ICogQHBhcmFtIHtib29sZWFufSBbaW5DaGFydEFyZWFdIC0gVGhlIGV2ZW50IGlzIGluc2lkZSBjaGFydEFyZWFcblx0ICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgdGhlIHRvb2x0aXAgY2hhbmdlZFxuXHQgKi9cbiAgaGFuZGxlRXZlbnQoZSwgcmVwbGF5LCBpbkNoYXJ0QXJlYSA9IHRydWUpIHtcbiAgICBpZiAocmVwbGF5ICYmIHRoaXMuX2lnbm9yZVJlcGxheUV2ZW50cykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLl9pZ25vcmVSZXBsYXlFdmVudHMgPSBmYWxzZTtcblxuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgbGFzdEFjdGl2ZSA9IHRoaXMuX2FjdGl2ZSB8fCBbXTtcbiAgICBjb25zdCBhY3RpdmUgPSB0aGlzLl9nZXRBY3RpdmVFbGVtZW50cyhlLCBsYXN0QWN0aXZlLCByZXBsYXksIGluQ2hhcnRBcmVhKTtcblxuICAgIC8vIFdoZW4gdGhlcmUgYXJlIG11bHRpcGxlIGl0ZW1zIHNob3duLCBidXQgdGhlIHRvb2x0aXAgcG9zaXRpb24gaXMgbmVhcmVzdCBtb2RlXG4gICAgLy8gYW4gdXBkYXRlIG1heSBuZWVkIHRvIGJlIG1hZGUgYmVjYXVzZSBvdXIgcG9zaXRpb24gbWF5IGhhdmUgY2hhbmdlZCBldmVuIHRob3VnaFxuICAgIC8vIHRoZSBpdGVtcyBhcmUgdGhlIHNhbWUgYXMgYmVmb3JlLlxuICAgIGNvbnN0IHBvc2l0aW9uQ2hhbmdlZCA9IHRoaXMuX3Bvc2l0aW9uQ2hhbmdlZChhY3RpdmUsIGUpO1xuXG4gICAgLy8gUmVtZW1iZXIgTGFzdCBBY3RpdmVzXG4gICAgY29uc3QgY2hhbmdlZCA9IHJlcGxheSB8fCAhX2VsZW1lbnRzRXF1YWwoYWN0aXZlLCBsYXN0QWN0aXZlKSB8fCBwb3NpdGlvbkNoYW5nZWQ7XG5cbiAgICAvLyBPbmx5IGhhbmRsZSB0YXJnZXQgZXZlbnQgb24gdG9vbHRpcCBjaGFuZ2VcbiAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgdGhpcy5fYWN0aXZlID0gYWN0aXZlO1xuXG4gICAgICBpZiAob3B0aW9ucy5lbmFibGVkIHx8IG9wdGlvbnMuZXh0ZXJuYWwpIHtcbiAgICAgICAgdGhpcy5fZXZlbnRQb3NpdGlvbiA9IHtcbiAgICAgICAgICB4OiBlLngsXG4gICAgICAgICAgeTogZS55XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy51cGRhdGUodHJ1ZSwgcmVwbGF5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY2hhbmdlZDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBIZWxwZXIgZm9yIGRldGVybWluaW5nIHRoZSBhY3RpdmUgZWxlbWVudHMgZm9yIGV2ZW50XG5cdCAqIEBwYXJhbSB7Q2hhcnRFdmVudH0gZSAtIFRoZSBldmVudCB0byBoYW5kbGVcblx0ICogQHBhcmFtIHtJbnRlcmFjdGlvbkl0ZW1bXX0gbGFzdEFjdGl2ZSAtIFByZXZpb3VzbHkgYWN0aXZlIGVsZW1lbnRzXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JlcGxheV0gLSBUaGlzIGlzIGEgcmVwbGF5ZWQgZXZlbnQgKGZyb20gdXBkYXRlKVxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IFtpbkNoYXJ0QXJlYV0gLSBUaGUgZXZlbnQgaXMgaW5zaWRlIGNoYXJ0QXJlYVxuXHQgKiBAcmV0dXJucyB7SW50ZXJhY3Rpb25JdGVtW119IC0gQWN0aXZlIGVsZW1lbnRzXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0QWN0aXZlRWxlbWVudHMoZSwgbGFzdEFjdGl2ZSwgcmVwbGF5LCBpbkNoYXJ0QXJlYSkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG5cbiAgICBpZiAoZS50eXBlID09PSAnbW91c2VvdXQnKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgaWYgKCFpbkNoYXJ0QXJlYSkge1xuICAgICAgLy8gTGV0IHVzZXIgY29udHJvbCB0aGUgYWN0aXZlIGVsZW1lbnRzIG91dHNpZGUgY2hhcnRBcmVhLiBFZy4gdXNpbmcgTGVnZW5kLlxuICAgICAgLy8gQnV0IG1ha2Ugc3VyZSB0aGF0IGFjdGl2ZSBlbGVtZW50cyBhcmUgc3RpbGwgdmFsaWQuXG4gICAgICByZXR1cm4gbGFzdEFjdGl2ZS5maWx0ZXIoaSA9PlxuICAgICAgICB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbaS5kYXRhc2V0SW5kZXhdICYmXG4gICAgICAgIHRoaXMuY2hhcnQuZ2V0RGF0YXNldE1ldGEoaS5kYXRhc2V0SW5kZXgpLmNvbnRyb2xsZXIuZ2V0UGFyc2VkKGkuaW5kZXgpICE9PSB1bmRlZmluZWRcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gRmluZCBBY3RpdmUgRWxlbWVudHMgZm9yIHRvb2x0aXBzXG4gICAgY29uc3QgYWN0aXZlID0gdGhpcy5jaGFydC5nZXRFbGVtZW50c0F0RXZlbnRGb3JNb2RlKGUsIG9wdGlvbnMubW9kZSwgb3B0aW9ucywgcmVwbGF5KTtcblxuICAgIGlmIChvcHRpb25zLnJldmVyc2UpIHtcbiAgICAgIGFjdGl2ZS5yZXZlcnNlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFjdGl2ZTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBEZXRlcm1pbmUgaWYgdGhlIGFjdGl2ZSBlbGVtZW50cyArIGV2ZW50IGNvbWJpbmF0aW9uIGNoYW5nZXMgdGhlXG5cdCAqIHRvb2x0aXAgcG9zaXRpb25cblx0ICogQHBhcmFtIHthcnJheX0gYWN0aXZlIC0gQWN0aXZlIGVsZW1lbnRzXG5cdCAqIEBwYXJhbSB7Q2hhcnRFdmVudH0gZSAtIEV2ZW50IHRoYXQgdHJpZ2dlcmVkIHRoZSBwb3NpdGlvbiBjaGFuZ2Vcblx0ICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHBvc2l0aW9uIGhhcyBjaGFuZ2VkXG5cdCAqL1xuICBfcG9zaXRpb25DaGFuZ2VkKGFjdGl2ZSwgZSkge1xuICAgIGNvbnN0IHtjYXJldFgsIGNhcmV0WSwgb3B0aW9uc30gPSB0aGlzO1xuICAgIGNvbnN0IHBvc2l0aW9uID0gcG9zaXRpb25lcnNbb3B0aW9ucy5wb3NpdGlvbl0uY2FsbCh0aGlzLCBhY3RpdmUsIGUpO1xuICAgIHJldHVybiBwb3NpdGlvbiAhPT0gZmFsc2UgJiYgKGNhcmV0WCAhPT0gcG9zaXRpb24ueCB8fCBjYXJldFkgIT09IHBvc2l0aW9uLnkpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgaWQ6ICd0b29sdGlwJyxcbiAgX2VsZW1lbnQ6IFRvb2x0aXAsXG4gIHBvc2l0aW9uZXJzLFxuXG4gIGFmdGVySW5pdChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgY2hhcnQudG9vbHRpcCA9IG5ldyBUb29sdGlwKHtjaGFydCwgb3B0aW9uc30pO1xuICAgIH1cbiAgfSxcblxuICBiZWZvcmVVcGRhdGUoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgaWYgKGNoYXJ0LnRvb2x0aXApIHtcbiAgICAgIGNoYXJ0LnRvb2x0aXAuaW5pdGlhbGl6ZShvcHRpb25zKTtcbiAgICB9XG4gIH0sXG5cbiAgcmVzZXQoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgaWYgKGNoYXJ0LnRvb2x0aXApIHtcbiAgICAgIGNoYXJ0LnRvb2x0aXAuaW5pdGlhbGl6ZShvcHRpb25zKTtcbiAgICB9XG4gIH0sXG5cbiAgYWZ0ZXJEcmF3KGNoYXJ0KSB7XG4gICAgY29uc3QgdG9vbHRpcCA9IGNoYXJ0LnRvb2x0aXA7XG5cbiAgICBpZiAodG9vbHRpcCAmJiB0b29sdGlwLl93aWxsUmVuZGVyKCkpIHtcbiAgICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICAgIHRvb2x0aXBcbiAgICAgIH07XG5cbiAgICAgIGlmIChjaGFydC5ub3RpZnlQbHVnaW5zKCdiZWZvcmVUb29sdGlwRHJhdycsIHsuLi5hcmdzLCBjYW5jZWxhYmxlOiB0cnVlfSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdG9vbHRpcC5kcmF3KGNoYXJ0LmN0eCk7XG5cbiAgICAgIGNoYXJ0Lm5vdGlmeVBsdWdpbnMoJ2FmdGVyVG9vbHRpcERyYXcnLCBhcmdzKTtcbiAgICB9XG4gIH0sXG5cbiAgYWZ0ZXJFdmVudChjaGFydCwgYXJncykge1xuICAgIGlmIChjaGFydC50b29sdGlwKSB7XG4gICAgICAvLyBJZiB0aGUgZXZlbnQgaXMgcmVwbGF5ZWQgZnJvbSBgdXBkYXRlYCwgd2Ugc2hvdWxkIGV2YWx1YXRlIHdpdGggdGhlIGZpbmFsIHBvc2l0aW9ucy5cbiAgICAgIGNvbnN0IHVzZUZpbmFsUG9zaXRpb24gPSBhcmdzLnJlcGxheTtcbiAgICAgIGlmIChjaGFydC50b29sdGlwLmhhbmRsZUV2ZW50KGFyZ3MuZXZlbnQsIHVzZUZpbmFsUG9zaXRpb24sIGFyZ3MuaW5DaGFydEFyZWEpKSB7XG4gICAgICAgIC8vIG5vdGlmeSBjaGFydCBhYm91dCB0aGUgY2hhbmdlLCBzbyBpdCB3aWxsIHJlbmRlclxuICAgICAgICBhcmdzLmNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBkZWZhdWx0czoge1xuICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgZXh0ZXJuYWw6IG51bGwsXG4gICAgcG9zaXRpb246ICdhdmVyYWdlJyxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6ICdyZ2JhKDAsMCwwLDAuOCknLFxuICAgIHRpdGxlQ29sb3I6ICcjZmZmJyxcbiAgICB0aXRsZUZvbnQ6IHtcbiAgICAgIHdlaWdodDogJ2JvbGQnLFxuICAgIH0sXG4gICAgdGl0bGVTcGFjaW5nOiAyLFxuICAgIHRpdGxlTWFyZ2luQm90dG9tOiA2LFxuICAgIHRpdGxlQWxpZ246ICdsZWZ0JyxcbiAgICBib2R5Q29sb3I6ICcjZmZmJyxcbiAgICBib2R5U3BhY2luZzogMixcbiAgICBib2R5Rm9udDoge1xuICAgIH0sXG4gICAgYm9keUFsaWduOiAnbGVmdCcsXG4gICAgZm9vdGVyQ29sb3I6ICcjZmZmJyxcbiAgICBmb290ZXJTcGFjaW5nOiAyLFxuICAgIGZvb3Rlck1hcmdpblRvcDogNixcbiAgICBmb290ZXJGb250OiB7XG4gICAgICB3ZWlnaHQ6ICdib2xkJyxcbiAgICB9LFxuICAgIGZvb3RlckFsaWduOiAnbGVmdCcsXG4gICAgcGFkZGluZzogNixcbiAgICBjYXJldFBhZGRpbmc6IDIsXG4gICAgY2FyZXRTaXplOiA1LFxuICAgIGNvcm5lclJhZGl1czogNixcbiAgICBib3hIZWlnaHQ6IChjdHgsIG9wdHMpID0+IG9wdHMuYm9keUZvbnQuc2l6ZSxcbiAgICBib3hXaWR0aDogKGN0eCwgb3B0cykgPT4gb3B0cy5ib2R5Rm9udC5zaXplLFxuICAgIG11bHRpS2V5QmFja2dyb3VuZDogJyNmZmYnLFxuICAgIGRpc3BsYXlDb2xvcnM6IHRydWUsXG4gICAgYm94UGFkZGluZzogMCxcbiAgICBib3JkZXJDb2xvcjogJ3JnYmEoMCwwLDAsMCknLFxuICAgIGJvcmRlcldpZHRoOiAwLFxuICAgIGFuaW1hdGlvbjoge1xuICAgICAgZHVyYXRpb246IDQwMCxcbiAgICAgIGVhc2luZzogJ2Vhc2VPdXRRdWFydCcsXG4gICAgfSxcbiAgICBhbmltYXRpb25zOiB7XG4gICAgICBudW1iZXJzOiB7XG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBwcm9wZXJ0aWVzOiBbJ3gnLCAneScsICd3aWR0aCcsICdoZWlnaHQnLCAnY2FyZXRYJywgJ2NhcmV0WSddLFxuICAgICAgfSxcbiAgICAgIG9wYWNpdHk6IHtcbiAgICAgICAgZWFzaW5nOiAnbGluZWFyJyxcbiAgICAgICAgZHVyYXRpb246IDIwMFxuICAgICAgfVxuICAgIH0sXG4gICAgY2FsbGJhY2tzOiBkZWZhdWx0Q2FsbGJhY2tzXG4gIH0sXG5cbiAgZGVmYXVsdFJvdXRlczoge1xuICAgIGJvZHlGb250OiAnZm9udCcsXG4gICAgZm9vdGVyRm9udDogJ2ZvbnQnLFxuICAgIHRpdGxlRm9udDogJ2ZvbnQnXG4gIH0sXG5cbiAgZGVzY3JpcHRvcnM6IHtcbiAgICBfc2NyaXB0YWJsZTogKG5hbWUpID0+IG5hbWUgIT09ICdmaWx0ZXInICYmIG5hbWUgIT09ICdpdGVtU29ydCcgJiYgbmFtZSAhPT0gJ2V4dGVybmFsJyxcbiAgICBfaW5kZXhhYmxlOiBmYWxzZSxcbiAgICBjYWxsYmFja3M6IHtcbiAgICAgIF9zY3JpcHRhYmxlOiBmYWxzZSxcbiAgICAgIF9pbmRleGFibGU6IGZhbHNlLFxuICAgIH0sXG4gICAgYW5pbWF0aW9uOiB7XG4gICAgICBfZmFsbGJhY2s6IGZhbHNlXG4gICAgfSxcbiAgICBhbmltYXRpb25zOiB7XG4gICAgICBfZmFsbGJhY2s6ICdhbmltYXRpb24nXG4gICAgfVxuICB9LFxuXG4gIC8vIFJlc29sdmUgYWRkaXRpb25hbGx5IGZyb20gYGludGVyYWN0aW9uYCBvcHRpb25zIGFuZCBkZWZhdWx0cy5cbiAgYWRkaXRpb25hbE9wdGlvblNjb3BlczogWydpbnRlcmFjdGlvbiddXG59O1xuIiwgImltcG9ydCBTY2FsZSBmcm9tICcuLi9jb3JlL2NvcmUuc2NhbGUuanMnO1xuaW1wb3J0IHtpc051bGxPclVuZGVmLCB2YWx1ZU9yRGVmYXVsdCwgX2xpbWl0VmFsdWV9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuXG5jb25zdCBhZGRJZlN0cmluZyA9IChsYWJlbHMsIHJhdywgaW5kZXgsIGFkZGVkTGFiZWxzKSA9PiB7XG4gIGlmICh0eXBlb2YgcmF3ID09PSAnc3RyaW5nJykge1xuICAgIGluZGV4ID0gbGFiZWxzLnB1c2gocmF3KSAtIDE7XG4gICAgYWRkZWRMYWJlbHMudW5zaGlmdCh7aW5kZXgsIGxhYmVsOiByYXd9KTtcbiAgfSBlbHNlIGlmIChpc05hTihyYXcpKSB7XG4gICAgaW5kZXggPSBudWxsO1xuICB9XG4gIHJldHVybiBpbmRleDtcbn07XG5cbmZ1bmN0aW9uIGZpbmRPckFkZExhYmVsKGxhYmVscywgcmF3LCBpbmRleCwgYWRkZWRMYWJlbHMpIHtcbiAgY29uc3QgZmlyc3QgPSBsYWJlbHMuaW5kZXhPZihyYXcpO1xuICBpZiAoZmlyc3QgPT09IC0xKSB7XG4gICAgcmV0dXJuIGFkZElmU3RyaW5nKGxhYmVscywgcmF3LCBpbmRleCwgYWRkZWRMYWJlbHMpO1xuICB9XG4gIGNvbnN0IGxhc3QgPSBsYWJlbHMubGFzdEluZGV4T2YocmF3KTtcbiAgcmV0dXJuIGZpcnN0ICE9PSBsYXN0ID8gaW5kZXggOiBmaXJzdDtcbn1cblxuY29uc3QgdmFsaWRJbmRleCA9IChpbmRleCwgbWF4KSA9PiBpbmRleCA9PT0gbnVsbCA/IG51bGwgOiBfbGltaXRWYWx1ZShNYXRoLnJvdW5kKGluZGV4KSwgMCwgbWF4KTtcblxuZnVuY3Rpb24gX2dldExhYmVsRm9yVmFsdWUodmFsdWUpIHtcbiAgY29uc3QgbGFiZWxzID0gdGhpcy5nZXRMYWJlbHMoKTtcblxuICBpZiAodmFsdWUgPj0gMCAmJiB2YWx1ZSA8IGxhYmVscy5sZW5ndGgpIHtcbiAgICByZXR1cm4gbGFiZWxzW3ZhbHVlXTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENhdGVnb3J5U2NhbGUgZXh0ZW5kcyBTY2FsZSB7XG5cbiAgc3RhdGljIGlkID0gJ2NhdGVnb3J5JztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICB0aWNrczoge1xuICAgICAgY2FsbGJhY2s6IF9nZXRMYWJlbEZvclZhbHVlXG4gICAgfVxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKGNmZykge1xuICAgIHN1cGVyKGNmZyk7XG5cbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLl9zdGFydFZhbHVlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3ZhbHVlUmFuZ2UgPSAwO1xuICAgIHRoaXMuX2FkZGVkTGFiZWxzID0gW107XG4gIH1cblxuICBpbml0KHNjYWxlT3B0aW9ucykge1xuICAgIGNvbnN0IGFkZGVkID0gdGhpcy5fYWRkZWRMYWJlbHM7XG4gICAgaWYgKGFkZGVkLmxlbmd0aCkge1xuICAgICAgY29uc3QgbGFiZWxzID0gdGhpcy5nZXRMYWJlbHMoKTtcbiAgICAgIGZvciAoY29uc3Qge2luZGV4LCBsYWJlbH0gb2YgYWRkZWQpIHtcbiAgICAgICAgaWYgKGxhYmVsc1tpbmRleF0gPT09IGxhYmVsKSB7XG4gICAgICAgICAgbGFiZWxzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuX2FkZGVkTGFiZWxzID0gW107XG4gICAgfVxuICAgIHN1cGVyLmluaXQoc2NhbGVPcHRpb25zKTtcbiAgfVxuXG4gIHBhcnNlKHJhdywgaW5kZXgpIHtcbiAgICBpZiAoaXNOdWxsT3JVbmRlZihyYXcpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgbGFiZWxzID0gdGhpcy5nZXRMYWJlbHMoKTtcbiAgICBpbmRleCA9IGlzRmluaXRlKGluZGV4KSAmJiBsYWJlbHNbaW5kZXhdID09PSByYXcgPyBpbmRleFxuICAgICAgOiBmaW5kT3JBZGRMYWJlbChsYWJlbHMsIHJhdywgdmFsdWVPckRlZmF1bHQoaW5kZXgsIHJhdyksIHRoaXMuX2FkZGVkTGFiZWxzKTtcbiAgICByZXR1cm4gdmFsaWRJbmRleChpbmRleCwgbGFiZWxzLmxlbmd0aCAtIDEpO1xuICB9XG5cbiAgZGV0ZXJtaW5lRGF0YUxpbWl0cygpIHtcbiAgICBjb25zdCB7bWluRGVmaW5lZCwgbWF4RGVmaW5lZH0gPSB0aGlzLmdldFVzZXJCb3VuZHMoKTtcbiAgICBsZXQge21pbiwgbWF4fSA9IHRoaXMuZ2V0TWluTWF4KHRydWUpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5ib3VuZHMgPT09ICd0aWNrcycpIHtcbiAgICAgIGlmICghbWluRGVmaW5lZCkge1xuICAgICAgICBtaW4gPSAwO1xuICAgICAgfVxuICAgICAgaWYgKCFtYXhEZWZpbmVkKSB7XG4gICAgICAgIG1heCA9IHRoaXMuZ2V0TGFiZWxzKCkubGVuZ3RoIC0gMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICB0aGlzLm1heCA9IG1heDtcbiAgfVxuXG4gIGJ1aWxkVGlja3MoKSB7XG4gICAgY29uc3QgbWluID0gdGhpcy5taW47XG4gICAgY29uc3QgbWF4ID0gdGhpcy5tYXg7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5vcHRpb25zLm9mZnNldDtcbiAgICBjb25zdCB0aWNrcyA9IFtdO1xuICAgIGxldCBsYWJlbHMgPSB0aGlzLmdldExhYmVscygpO1xuXG4gICAgLy8gSWYgd2UgYXJlIHZpZXdpbmcgc29tZSBzdWJzZXQgb2YgbGFiZWxzLCBzbGljZSB0aGUgb3JpZ2luYWwgYXJyYXlcbiAgICBsYWJlbHMgPSAobWluID09PSAwICYmIG1heCA9PT0gbGFiZWxzLmxlbmd0aCAtIDEpID8gbGFiZWxzIDogbGFiZWxzLnNsaWNlKG1pbiwgbWF4ICsgMSk7XG5cbiAgICB0aGlzLl92YWx1ZVJhbmdlID0gTWF0aC5tYXgobGFiZWxzLmxlbmd0aCAtIChvZmZzZXQgPyAwIDogMSksIDEpO1xuICAgIHRoaXMuX3N0YXJ0VmFsdWUgPSB0aGlzLm1pbiAtIChvZmZzZXQgPyAwLjUgOiAwKTtcblxuICAgIGZvciAobGV0IHZhbHVlID0gbWluOyB2YWx1ZSA8PSBtYXg7IHZhbHVlKyspIHtcbiAgICAgIHRpY2tzLnB1c2goe3ZhbHVlfSk7XG4gICAgfVxuICAgIHJldHVybiB0aWNrcztcbiAgfVxuXG4gIGdldExhYmVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICByZXR1cm4gX2dldExhYmVsRm9yVmFsdWUuY2FsbCh0aGlzLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgY29uZmlndXJlKCkge1xuICAgIHN1cGVyLmNvbmZpZ3VyZSgpO1xuXG4gICAgaWYgKCF0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAvLyBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdmVydGljYWwgY2F0ZWdvcnkgc2NhbGUgcmV2ZXJzZSBpcyBpbnZlcnRlZC5cbiAgICAgIHRoaXMuX3JldmVyc2VQaXhlbHMgPSAhdGhpcy5fcmV2ZXJzZVBpeGVscztcbiAgICB9XG4gIH1cblxuICAvLyBVc2VkIHRvIGdldCBkYXRhIHZhbHVlIGxvY2F0aW9ucy4gVmFsdWUgY2FuIGVpdGhlciBiZSBhbiBpbmRleCBvciBhIG51bWVyaWNhbCB2YWx1ZVxuICBnZXRQaXhlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicpIHtcbiAgICAgIHZhbHVlID0gdGhpcy5wYXJzZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlID09PSBudWxsID8gTmFOIDogdGhpcy5nZXRQaXhlbEZvckRlY2ltYWwoKHZhbHVlIC0gdGhpcy5fc3RhcnRWYWx1ZSkgLyB0aGlzLl92YWx1ZVJhbmdlKTtcbiAgfVxuXG4gIC8vIE11c3Qgb3ZlcnJpZGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBiZWNhdXNlIGl0IGNhbGxzIGdldFBpeGVsRm9yVmFsdWVcbiAgLy8gYW5kIGNhdGVnb3J5IHNjYWxlIGNhbiBoYXZlIGR1cGxpY2F0ZSB2YWx1ZXNcbiAgZ2V0UGl4ZWxGb3JUaWNrKGluZGV4KSB7XG4gICAgY29uc3QgdGlja3MgPSB0aGlzLnRpY2tzO1xuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPiB0aWNrcy5sZW5ndGggLSAxKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JWYWx1ZSh0aWNrc1tpbmRleF0udmFsdWUpO1xuICB9XG5cbiAgZ2V0VmFsdWVGb3JQaXhlbChwaXhlbCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKHRoaXMuX3N0YXJ0VmFsdWUgKyB0aGlzLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkgKiB0aGlzLl92YWx1ZVJhbmdlKTtcbiAgfVxuXG4gIGdldEJhc2VQaXhlbCgpIHtcbiAgICByZXR1cm4gdGhpcy5ib3R0b207XG4gIH1cbn1cbiIsICJpbXBvcnQge2lzTnVsbE9yVW5kZWZ9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7YWxtb3N0RXF1YWxzLCBhbG1vc3RXaG9sZSwgbmljZU51bSwgX2RlY2ltYWxQbGFjZXMsIF9zZXRNaW5BbmRNYXhCeUtleSwgc2lnbiwgdG9SYWRpYW5zfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMubWF0aC5qcyc7XG5pbXBvcnQgU2NhbGUgZnJvbSAnLi4vY29yZS9jb3JlLnNjYWxlLmpzJztcbmltcG9ydCB7Zm9ybWF0TnVtYmVyfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuaW50bC5qcyc7XG5cbi8qKlxuICogR2VuZXJhdGUgYSBzZXQgb2YgbGluZWFyIHRpY2tzIGZvciBhbiBheGlzXG4gKiAxLiBJZiBnZW5lcmF0aW9uT3B0aW9ucy5taW4sIGdlbmVyYXRpb25PcHRpb25zLm1heCwgYW5kIGdlbmVyYXRpb25PcHRpb25zLnN0ZXAgYXJlIGRlZmluZWQ6XG4gKiAgICBpZiAobWF4IC0gbWluKSAvIHN0ZXAgaXMgYW4gaW50ZWdlciwgdGlja3MgYXJlIGdlbmVyYXRlZCBhcyBbbWluLCBtaW4gKyBzdGVwLCAuLi4sIG1heF1cbiAqICAgIE5vdGUgdGhhdCB0aGUgZ2VuZXJhdGlvbk9wdGlvbnMubWF4Q291bnQgc2V0dGluZyBpcyByZXNwZWN0ZWQgaW4gdGhpcyBzY2VuYXJpb1xuICpcbiAqIDIuIElmIGdlbmVyYXRpb25PcHRpb25zLm1pbiwgZ2VuZXJhdGlvbk9wdGlvbnMubWF4LCBhbmQgZ2VuZXJhdGlvbk9wdGlvbnMuY291bnQgaXMgZGVmaW5lZFxuICogICAgc3BhY2luZyA9IChtYXggLSBtaW4pIC8gY291bnRcbiAqICAgIFRpY2tzIGFyZSBnZW5lcmF0ZWQgYXMgW21pbiwgbWluICsgc3BhY2luZywgLi4uLCBtYXhdXG4gKlxuICogMy4gSWYgZ2VuZXJhdGlvbk9wdGlvbnMuY291bnQgaXMgZGVmaW5lZFxuICogICAgc3BhY2luZyA9IChuaWNlTWF4IC0gbmljZU1pbikgLyBjb3VudFxuICpcbiAqIDQuIENvbXB1dGUgb3B0aW1hbCBzcGFjaW5nIG9mIHRpY2tzIHVzaW5nIG5pY2VOdW0gYWxnb3JpdGhtXG4gKlxuICogQHBhcmFtIGdlbmVyYXRpb25PcHRpb25zIHRoZSBvcHRpb25zIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIHRpY2tzXG4gKiBAcGFyYW0gZGF0YVJhbmdlIHRoZSByYW5nZSBvZiB0aGUgZGF0YVxuICogQHJldHVybnMge29iamVjdFtdfSBhcnJheSBvZiB0aWNrIG9iamVjdHNcbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVUaWNrcyhnZW5lcmF0aW9uT3B0aW9ucywgZGF0YVJhbmdlKSB7XG4gIGNvbnN0IHRpY2tzID0gW107XG4gIC8vIFRvIGdldCBhIFwibmljZVwiIHZhbHVlIGZvciB0aGUgdGljayBzcGFjaW5nLCB3ZSB3aWxsIHVzZSB0aGUgYXBwcm9wcmlhdGVseSBuYW1lZFxuICAvLyBcIm5pY2UgbnVtYmVyXCIgYWxnb3JpdGhtLiBTZWUgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvODUwNjg4MS9uaWNlLWxhYmVsLWFsZ29yaXRobS1mb3ItY2hhcnRzLXdpdGgtbWluaW11bS10aWNrc1xuICAvLyBmb3IgZGV0YWlscy5cblxuICBjb25zdCBNSU5fU1BBQ0lORyA9IDFlLTE0O1xuICBjb25zdCB7Ym91bmRzLCBzdGVwLCBtaW4sIG1heCwgcHJlY2lzaW9uLCBjb3VudCwgbWF4VGlja3MsIG1heERpZ2l0cywgaW5jbHVkZUJvdW5kc30gPSBnZW5lcmF0aW9uT3B0aW9ucztcbiAgY29uc3QgdW5pdCA9IHN0ZXAgfHwgMTtcbiAgY29uc3QgbWF4U3BhY2VzID0gbWF4VGlja3MgLSAxO1xuICBjb25zdCB7bWluOiBybWluLCBtYXg6IHJtYXh9ID0gZGF0YVJhbmdlO1xuICBjb25zdCBtaW5EZWZpbmVkID0gIWlzTnVsbE9yVW5kZWYobWluKTtcbiAgY29uc3QgbWF4RGVmaW5lZCA9ICFpc051bGxPclVuZGVmKG1heCk7XG4gIGNvbnN0IGNvdW50RGVmaW5lZCA9ICFpc051bGxPclVuZGVmKGNvdW50KTtcbiAgY29uc3QgbWluU3BhY2luZyA9IChybWF4IC0gcm1pbikgLyAobWF4RGlnaXRzICsgMSk7XG4gIGxldCBzcGFjaW5nID0gbmljZU51bSgocm1heCAtIHJtaW4pIC8gbWF4U3BhY2VzIC8gdW5pdCkgKiB1bml0O1xuICBsZXQgZmFjdG9yLCBuaWNlTWluLCBuaWNlTWF4LCBudW1TcGFjZXM7XG5cbiAgLy8gQmV5b25kIE1JTl9TUEFDSU5HIGZsb2F0aW5nIHBvaW50IG51bWJlcnMgYmVpbmcgdG8gbG9zZSBwcmVjaXNpb25cbiAgLy8gc3VjaCB0aGF0IHdlIGNhbid0IGRvIHRoZSBtYXRoIG5lY2Vzc2FyeSB0byBnZW5lcmF0ZSB0aWNrc1xuICBpZiAoc3BhY2luZyA8IE1JTl9TUEFDSU5HICYmICFtaW5EZWZpbmVkICYmICFtYXhEZWZpbmVkKSB7XG4gICAgcmV0dXJuIFt7dmFsdWU6IHJtaW59LCB7dmFsdWU6IHJtYXh9XTtcbiAgfVxuXG4gIG51bVNwYWNlcyA9IE1hdGguY2VpbChybWF4IC8gc3BhY2luZykgLSBNYXRoLmZsb29yKHJtaW4gLyBzcGFjaW5nKTtcbiAgaWYgKG51bVNwYWNlcyA+IG1heFNwYWNlcykge1xuICAgIC8vIElmIHRoZSBjYWxjdWxhdGVkIG51bSBvZiBzcGFjZXMgZXhjZWVkcyBtYXhOdW1TcGFjZXMsIHJlY2FsY3VsYXRlIGl0XG4gICAgc3BhY2luZyA9IG5pY2VOdW0obnVtU3BhY2VzICogc3BhY2luZyAvIG1heFNwYWNlcyAvIHVuaXQpICogdW5pdDtcbiAgfVxuXG4gIGlmICghaXNOdWxsT3JVbmRlZihwcmVjaXNpb24pKSB7XG4gICAgLy8gSWYgdGhlIHVzZXIgc3BlY2lmaWVkIGEgcHJlY2lzaW9uLCByb3VuZCB0byB0aGF0IG51bWJlciBvZiBkZWNpbWFsIHBsYWNlc1xuICAgIGZhY3RvciA9IE1hdGgucG93KDEwLCBwcmVjaXNpb24pO1xuICAgIHNwYWNpbmcgPSBNYXRoLmNlaWwoc3BhY2luZyAqIGZhY3RvcikgLyBmYWN0b3I7XG4gIH1cblxuICBpZiAoYm91bmRzID09PSAndGlja3MnKSB7XG4gICAgbmljZU1pbiA9IE1hdGguZmxvb3Iocm1pbiAvIHNwYWNpbmcpICogc3BhY2luZztcbiAgICBuaWNlTWF4ID0gTWF0aC5jZWlsKHJtYXggLyBzcGFjaW5nKSAqIHNwYWNpbmc7XG4gIH0gZWxzZSB7XG4gICAgbmljZU1pbiA9IHJtaW47XG4gICAgbmljZU1heCA9IHJtYXg7XG4gIH1cblxuICBpZiAobWluRGVmaW5lZCAmJiBtYXhEZWZpbmVkICYmIHN0ZXAgJiYgYWxtb3N0V2hvbGUoKG1heCAtIG1pbikgLyBzdGVwLCBzcGFjaW5nIC8gMTAwMCkpIHtcbiAgICAvLyBDYXNlIDE6IElmIG1pbiwgbWF4IGFuZCBzdGVwU2l6ZSBhcmUgc2V0IGFuZCB0aGV5IG1ha2UgYW4gZXZlbmx5IHNwYWNlZCBzY2FsZSB1c2UgaXQuXG4gICAgLy8gc3BhY2luZyA9IHN0ZXA7XG4gICAgLy8gbnVtU3BhY2VzID0gKG1heCAtIG1pbikgLyBzcGFjaW5nO1xuICAgIC8vIE5vdGUgdGhhdCB3ZSByb3VuZCBoZXJlIHRvIGhhbmRsZSB0aGUgY2FzZSB3aGVyZSBhbG1vc3RXaG9sZSB0cmFuc2xhdGVkIGFuIEZQIGVycm9yXG4gICAgbnVtU3BhY2VzID0gTWF0aC5yb3VuZChNYXRoLm1pbigobWF4IC0gbWluKSAvIHNwYWNpbmcsIG1heFRpY2tzKSk7XG4gICAgc3BhY2luZyA9IChtYXggLSBtaW4pIC8gbnVtU3BhY2VzO1xuICAgIG5pY2VNaW4gPSBtaW47XG4gICAgbmljZU1heCA9IG1heDtcbiAgfSBlbHNlIGlmIChjb3VudERlZmluZWQpIHtcbiAgICAvLyBDYXNlcyAyICYgMywgd2UgaGF2ZSBhIGNvdW50IHNwZWNpZmllZC4gSGFuZGxlIG9wdGlvbmFsIHVzZXIgZGVmaW5lZCBlZGdlcyB0byB0aGUgcmFuZ2UuXG4gICAgLy8gU29tZXRpbWVzIHRoZXNlIGFyZSBuby1vcHMsIGJ1dCBpdCBtYWtlcyB0aGUgY29kZSBhIGxvdCBjbGVhcmVyXG4gICAgLy8gYW5kIHdoZW4gYSB1c2VyIGRlZmluZWQgcmFuZ2UgaXMgc3BlY2lmaWVkLCB3ZSB3YW50IHRoZSBjb3JyZWN0IHRpY2tzXG4gICAgbmljZU1pbiA9IG1pbkRlZmluZWQgPyBtaW4gOiBuaWNlTWluO1xuICAgIG5pY2VNYXggPSBtYXhEZWZpbmVkID8gbWF4IDogbmljZU1heDtcbiAgICBudW1TcGFjZXMgPSBjb3VudCAtIDE7XG4gICAgc3BhY2luZyA9IChuaWNlTWF4IC0gbmljZU1pbikgLyBudW1TcGFjZXM7XG4gIH0gZWxzZSB7XG4gICAgLy8gQ2FzZSA0XG4gICAgbnVtU3BhY2VzID0gKG5pY2VNYXggLSBuaWNlTWluKSAvIHNwYWNpbmc7XG5cbiAgICAvLyBJZiB2ZXJ5IGNsb3NlIHRvIG91ciByb3VuZGVkIHZhbHVlLCB1c2UgaXQuXG4gICAgaWYgKGFsbW9zdEVxdWFscyhudW1TcGFjZXMsIE1hdGgucm91bmQobnVtU3BhY2VzKSwgc3BhY2luZyAvIDEwMDApKSB7XG4gICAgICBudW1TcGFjZXMgPSBNYXRoLnJvdW5kKG51bVNwYWNlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG51bVNwYWNlcyA9IE1hdGguY2VpbChudW1TcGFjZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSBzcGFjaW5nIHdpbGwgaGF2ZSBjaGFuZ2VkIGluIGNhc2VzIDEsIDIsIGFuZCAzIHNvIHRoZSBmYWN0b3IgY2Fubm90IGJlIGNvbXB1dGVkXG4gIC8vIHVudGlsIHRoaXMgcG9pbnRcbiAgY29uc3QgZGVjaW1hbFBsYWNlcyA9IE1hdGgubWF4KFxuICAgIF9kZWNpbWFsUGxhY2VzKHNwYWNpbmcpLFxuICAgIF9kZWNpbWFsUGxhY2VzKG5pY2VNaW4pXG4gICk7XG4gIGZhY3RvciA9IE1hdGgucG93KDEwLCBpc051bGxPclVuZGVmKHByZWNpc2lvbikgPyBkZWNpbWFsUGxhY2VzIDogcHJlY2lzaW9uKTtcbiAgbmljZU1pbiA9IE1hdGgucm91bmQobmljZU1pbiAqIGZhY3RvcikgLyBmYWN0b3I7XG4gIG5pY2VNYXggPSBNYXRoLnJvdW5kKG5pY2VNYXggKiBmYWN0b3IpIC8gZmFjdG9yO1xuXG4gIGxldCBqID0gMDtcbiAgaWYgKG1pbkRlZmluZWQpIHtcbiAgICBpZiAoaW5jbHVkZUJvdW5kcyAmJiBuaWNlTWluICE9PSBtaW4pIHtcbiAgICAgIHRpY2tzLnB1c2goe3ZhbHVlOiBtaW59KTtcblxuICAgICAgaWYgKG5pY2VNaW4gPCBtaW4pIHtcbiAgICAgICAgaisrOyAvLyBTa2lwIG5pY2VNaW5cbiAgICAgIH1cbiAgICAgIC8vIElmIHRoZSBuZXh0IG5pY2UgdGljayBpcyBjbG9zZSB0byBtaW4sIHNraXAgaXRcbiAgICAgIGlmIChhbG1vc3RFcXVhbHMoTWF0aC5yb3VuZCgobmljZU1pbiArIGogKiBzcGFjaW5nKSAqIGZhY3RvcikgLyBmYWN0b3IsIG1pbiwgcmVsYXRpdmVMYWJlbFNpemUobWluLCBtaW5TcGFjaW5nLCBnZW5lcmF0aW9uT3B0aW9ucykpKSB7XG4gICAgICAgIGorKztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5pY2VNaW4gPCBtaW4pIHtcbiAgICAgIGorKztcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgaiA8IG51bVNwYWNlczsgKytqKSB7XG4gICAgY29uc3QgdGlja1ZhbHVlID0gTWF0aC5yb3VuZCgobmljZU1pbiArIGogKiBzcGFjaW5nKSAqIGZhY3RvcikgLyBmYWN0b3I7XG4gICAgaWYgKG1heERlZmluZWQgJiYgdGlja1ZhbHVlID4gbWF4KSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgdGlja3MucHVzaCh7dmFsdWU6IHRpY2tWYWx1ZX0pO1xuICB9XG5cbiAgaWYgKG1heERlZmluZWQgJiYgaW5jbHVkZUJvdW5kcyAmJiBuaWNlTWF4ICE9PSBtYXgpIHtcbiAgICAvLyBJZiB0aGUgcHJldmlvdXMgdGljayBpcyB0b28gY2xvc2UgdG8gbWF4LCByZXBsYWNlIGl0IHdpdGggbWF4LCBlbHNlIGFkZCBtYXhcbiAgICBpZiAodGlja3MubGVuZ3RoICYmIGFsbW9zdEVxdWFscyh0aWNrc1t0aWNrcy5sZW5ndGggLSAxXS52YWx1ZSwgbWF4LCByZWxhdGl2ZUxhYmVsU2l6ZShtYXgsIG1pblNwYWNpbmcsIGdlbmVyYXRpb25PcHRpb25zKSkpIHtcbiAgICAgIHRpY2tzW3RpY2tzLmxlbmd0aCAtIDFdLnZhbHVlID0gbWF4O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aWNrcy5wdXNoKHt2YWx1ZTogbWF4fSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFtYXhEZWZpbmVkIHx8IG5pY2VNYXggPT09IG1heCkge1xuICAgIHRpY2tzLnB1c2goe3ZhbHVlOiBuaWNlTWF4fSk7XG4gIH1cblxuICByZXR1cm4gdGlja3M7XG59XG5cbmZ1bmN0aW9uIHJlbGF0aXZlTGFiZWxTaXplKHZhbHVlLCBtaW5TcGFjaW5nLCB7aG9yaXpvbnRhbCwgbWluUm90YXRpb259KSB7XG4gIGNvbnN0IHJhZCA9IHRvUmFkaWFucyhtaW5Sb3RhdGlvbik7XG4gIGNvbnN0IHJhdGlvID0gKGhvcml6b250YWwgPyBNYXRoLnNpbihyYWQpIDogTWF0aC5jb3MocmFkKSkgfHwgMC4wMDE7XG4gIGNvbnN0IGxlbmd0aCA9IDAuNzUgKiBtaW5TcGFjaW5nICogKCcnICsgdmFsdWUpLmxlbmd0aDtcbiAgcmV0dXJuIE1hdGgubWluKG1pblNwYWNpbmcgLyByYXRpbywgbGVuZ3RoKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGluZWFyU2NhbGVCYXNlIGV4dGVuZHMgU2NhbGUge1xuXG4gIGNvbnN0cnVjdG9yKGNmZykge1xuICAgIHN1cGVyKGNmZyk7XG5cbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLnN0YXJ0ID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuZW5kID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuX3N0YXJ0VmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5fZW5kVmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fdmFsdWVSYW5nZSA9IDA7XG4gIH1cblxuICBwYXJzZShyYXcsIGluZGV4KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICBpZiAoaXNOdWxsT3JVbmRlZihyYXcpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKCh0eXBlb2YgcmF3ID09PSAnbnVtYmVyJyB8fCByYXcgaW5zdGFuY2VvZiBOdW1iZXIpICYmICFpc0Zpbml0ZSgrcmF3KSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuICtyYXc7XG4gIH1cblxuICBoYW5kbGVUaWNrUmFuZ2VPcHRpb25zKCkge1xuICAgIGNvbnN0IHtiZWdpbkF0WmVyb30gPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3Qge21pbkRlZmluZWQsIG1heERlZmluZWR9ID0gdGhpcy5nZXRVc2VyQm91bmRzKCk7XG4gICAgbGV0IHttaW4sIG1heH0gPSB0aGlzO1xuXG4gICAgY29uc3Qgc2V0TWluID0gdiA9PiAobWluID0gbWluRGVmaW5lZCA/IG1pbiA6IHYpO1xuICAgIGNvbnN0IHNldE1heCA9IHYgPT4gKG1heCA9IG1heERlZmluZWQgPyBtYXggOiB2KTtcblxuICAgIGlmIChiZWdpbkF0WmVybykge1xuICAgICAgY29uc3QgbWluU2lnbiA9IHNpZ24obWluKTtcbiAgICAgIGNvbnN0IG1heFNpZ24gPSBzaWduKG1heCk7XG5cbiAgICAgIGlmIChtaW5TaWduIDwgMCAmJiBtYXhTaWduIDwgMCkge1xuICAgICAgICBzZXRNYXgoMCk7XG4gICAgICB9IGVsc2UgaWYgKG1pblNpZ24gPiAwICYmIG1heFNpZ24gPiAwKSB7XG4gICAgICAgIHNldE1pbigwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWluID09PSBtYXgpIHtcbiAgICAgIGxldCBvZmZzZXQgPSBtYXggPT09IDAgPyAxIDogTWF0aC5hYnMobWF4ICogMC4wNSk7XG5cbiAgICAgIHNldE1heChtYXggKyBvZmZzZXQpO1xuXG4gICAgICBpZiAoIWJlZ2luQXRaZXJvKSB7XG4gICAgICAgIHNldE1pbihtaW4gLSBvZmZzZXQpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLm1pbiA9IG1pbjtcbiAgICB0aGlzLm1heCA9IG1heDtcbiAgfVxuXG4gIGdldFRpY2tMaW1pdCgpIHtcbiAgICBjb25zdCB0aWNrT3B0cyA9IHRoaXMub3B0aW9ucy50aWNrcztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgbGV0IHttYXhUaWNrc0xpbWl0LCBzdGVwU2l6ZX0gPSB0aWNrT3B0cztcbiAgICBsZXQgbWF4VGlja3M7XG5cbiAgICBpZiAoc3RlcFNpemUpIHtcbiAgICAgIG1heFRpY2tzID0gTWF0aC5jZWlsKHRoaXMubWF4IC8gc3RlcFNpemUpIC0gTWF0aC5mbG9vcih0aGlzLm1pbiAvIHN0ZXBTaXplKSArIDE7XG4gICAgICBpZiAobWF4VGlja3MgPiAxMDAwKSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihgc2NhbGVzLiR7dGhpcy5pZH0udGlja3Muc3RlcFNpemU6ICR7c3RlcFNpemV9IHdvdWxkIHJlc3VsdCBnZW5lcmF0aW5nIHVwIHRvICR7bWF4VGlja3N9IHRpY2tzLiBMaW1pdGluZyB0byAxMDAwLmApO1xuICAgICAgICBtYXhUaWNrcyA9IDEwMDA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG1heFRpY2tzID0gdGhpcy5jb21wdXRlVGlja0xpbWl0KCk7XG4gICAgICBtYXhUaWNrc0xpbWl0ID0gbWF4VGlja3NMaW1pdCB8fCAxMTtcbiAgICB9XG5cbiAgICBpZiAobWF4VGlja3NMaW1pdCkge1xuICAgICAgbWF4VGlja3MgPSBNYXRoLm1pbihtYXhUaWNrc0xpbWl0LCBtYXhUaWNrcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1heFRpY2tzO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGNvbXB1dGVUaWNrTGltaXQoKSB7XG4gICAgcmV0dXJuIE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbiAgfVxuXG4gIGJ1aWxkVGlja3MoKSB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB0aWNrT3B0cyA9IG9wdHMudGlja3M7XG5cbiAgICAvLyBGaWd1cmUgb3V0IHdoYXQgdGhlIG1heCBudW1iZXIgb2YgdGlja3Mgd2UgY2FuIHN1cHBvcnQgaXQgaXMgYmFzZWQgb24gdGhlIHNpemUgb2ZcbiAgICAvLyB0aGUgYXhpcyBhcmVhLiBGb3Igbm93LCB3ZSBzYXkgdGhhdCB0aGUgbWluaW11bSB0aWNrIHNwYWNpbmcgaW4gcGl4ZWxzIG11c3QgYmUgNDBcbiAgICAvLyBXZSBhbHNvIGxpbWl0IHRoZSBtYXhpbXVtIG51bWJlciBvZiB0aWNrcyB0byAxMSB3aGljaCBnaXZlcyBhIG5pY2UgMTAgc3F1YXJlcyBvblxuICAgIC8vIHRoZSBncmFwaC4gTWFrZSBzdXJlIHdlIGFsd2F5cyBoYXZlIGF0IGxlYXN0IDIgdGlja3NcbiAgICBsZXQgbWF4VGlja3MgPSB0aGlzLmdldFRpY2tMaW1pdCgpO1xuICAgIG1heFRpY2tzID0gTWF0aC5tYXgoMiwgbWF4VGlja3MpO1xuXG4gICAgY29uc3QgbnVtZXJpY0dlbmVyYXRvck9wdGlvbnMgPSB7XG4gICAgICBtYXhUaWNrcyxcbiAgICAgIGJvdW5kczogb3B0cy5ib3VuZHMsXG4gICAgICBtaW46IG9wdHMubWluLFxuICAgICAgbWF4OiBvcHRzLm1heCxcbiAgICAgIHByZWNpc2lvbjogdGlja09wdHMucHJlY2lzaW9uLFxuICAgICAgc3RlcDogdGlja09wdHMuc3RlcFNpemUsXG4gICAgICBjb3VudDogdGlja09wdHMuY291bnQsXG4gICAgICBtYXhEaWdpdHM6IHRoaXMuX21heERpZ2l0cygpLFxuICAgICAgaG9yaXpvbnRhbDogdGhpcy5pc0hvcml6b250YWwoKSxcbiAgICAgIG1pblJvdGF0aW9uOiB0aWNrT3B0cy5taW5Sb3RhdGlvbiB8fCAwLFxuICAgICAgaW5jbHVkZUJvdW5kczogdGlja09wdHMuaW5jbHVkZUJvdW5kcyAhPT0gZmFsc2VcbiAgICB9O1xuICAgIGNvbnN0IGRhdGFSYW5nZSA9IHRoaXMuX3JhbmdlIHx8IHRoaXM7XG4gICAgY29uc3QgdGlja3MgPSBnZW5lcmF0ZVRpY2tzKG51bWVyaWNHZW5lcmF0b3JPcHRpb25zLCBkYXRhUmFuZ2UpO1xuXG4gICAgLy8gQXQgdGhpcyBwb2ludCwgd2UgbmVlZCB0byB1cGRhdGUgb3VyIG1heCBhbmQgbWluIGdpdmVuIHRoZSB0aWNrIHZhbHVlcyxcbiAgICAvLyBzaW5jZSB3ZSBwcm9iYWJseSBoYXZlIGV4cGFuZGVkIHRoZSByYW5nZSBvZiB0aGUgc2NhbGVcbiAgICBpZiAob3B0cy5ib3VuZHMgPT09ICd0aWNrcycpIHtcbiAgICAgIF9zZXRNaW5BbmRNYXhCeUtleSh0aWNrcywgdGhpcywgJ3ZhbHVlJyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdHMucmV2ZXJzZSkge1xuICAgICAgdGlja3MucmV2ZXJzZSgpO1xuXG4gICAgICB0aGlzLnN0YXJ0ID0gdGhpcy5tYXg7XG4gICAgICB0aGlzLmVuZCA9IHRoaXMubWluO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXJ0ID0gdGhpcy5taW47XG4gICAgICB0aGlzLmVuZCA9IHRoaXMubWF4O1xuICAgIH1cblxuICAgIHJldHVybiB0aWNrcztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBjb25maWd1cmUoKSB7XG4gICAgY29uc3QgdGlja3MgPSB0aGlzLnRpY2tzO1xuICAgIGxldCBzdGFydCA9IHRoaXMubWluO1xuICAgIGxldCBlbmQgPSB0aGlzLm1heDtcblxuICAgIHN1cGVyLmNvbmZpZ3VyZSgpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5vZmZzZXQgJiYgdGlja3MubGVuZ3RoKSB7XG4gICAgICBjb25zdCBvZmZzZXQgPSAoZW5kIC0gc3RhcnQpIC8gTWF0aC5tYXgodGlja3MubGVuZ3RoIC0gMSwgMSkgLyAyO1xuICAgICAgc3RhcnQgLT0gb2Zmc2V0O1xuICAgICAgZW5kICs9IG9mZnNldDtcbiAgICB9XG4gICAgdGhpcy5fc3RhcnRWYWx1ZSA9IHN0YXJ0O1xuICAgIHRoaXMuX2VuZFZhbHVlID0gZW5kO1xuICAgIHRoaXMuX3ZhbHVlUmFuZ2UgPSBlbmQgLSBzdGFydDtcbiAgfVxuXG4gIGdldExhYmVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICByZXR1cm4gZm9ybWF0TnVtYmVyKHZhbHVlLCB0aGlzLmNoYXJ0Lm9wdGlvbnMubG9jYWxlLCB0aGlzLm9wdGlvbnMudGlja3MuZm9ybWF0KTtcbiAgfVxufVxuIiwgImltcG9ydCB7aXNGaW5pdGV9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCBMaW5lYXJTY2FsZUJhc2UgZnJvbSAnLi9zY2FsZS5saW5lYXJiYXNlLmpzJztcbmltcG9ydCBUaWNrcyBmcm9tICcuLi9jb3JlL2NvcmUudGlja3MuanMnO1xuaW1wb3J0IHt0b1JhZGlhbnN9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaW5lYXJTY2FsZSBleHRlbmRzIExpbmVhclNjYWxlQmFzZSB7XG5cbiAgc3RhdGljIGlkID0gJ2xpbmVhcic7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgdGlja3M6IHtcbiAgICAgIGNhbGxiYWNrOiBUaWNrcy5mb3JtYXR0ZXJzLm51bWVyaWNcbiAgICB9XG4gIH07XG5cblxuICBkZXRlcm1pbmVEYXRhTGltaXRzKCkge1xuICAgIGNvbnN0IHttaW4sIG1heH0gPSB0aGlzLmdldE1pbk1heCh0cnVlKTtcblxuICAgIHRoaXMubWluID0gaXNGaW5pdGUobWluKSA/IG1pbiA6IDA7XG4gICAgdGhpcy5tYXggPSBpc0Zpbml0ZShtYXgpID8gbWF4IDogMTtcblxuICAgIC8vIENvbW1vbiBiYXNlIGltcGxlbWVudGF0aW9uIHRvIGhhbmRsZSBtaW4sIG1heCwgYmVnaW5BdFplcm9cbiAgICB0aGlzLmhhbmRsZVRpY2tSYW5nZU9wdGlvbnMoKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiB0aWNrcyBiYXNlZCBvbiB0aGUgc2NhbGUgZGltZW5zaW9uXG5cdCAqIEBwcm90ZWN0ZWRcbiBcdCAqL1xuICBjb21wdXRlVGlja0xpbWl0KCkge1xuICAgIGNvbnN0IGhvcml6b250YWwgPSB0aGlzLmlzSG9yaXpvbnRhbCgpO1xuICAgIGNvbnN0IGxlbmd0aCA9IGhvcml6b250YWwgPyB0aGlzLndpZHRoIDogdGhpcy5oZWlnaHQ7XG4gICAgY29uc3QgbWluUm90YXRpb24gPSB0b1JhZGlhbnModGhpcy5vcHRpb25zLnRpY2tzLm1pblJvdGF0aW9uKTtcbiAgICBjb25zdCByYXRpbyA9IChob3Jpem9udGFsID8gTWF0aC5zaW4obWluUm90YXRpb24pIDogTWF0aC5jb3MobWluUm90YXRpb24pKSB8fCAwLjAwMTtcbiAgICBjb25zdCB0aWNrRm9udCA9IHRoaXMuX3Jlc29sdmVUaWNrRm9udE9wdGlvbnMoMCk7XG4gICAgcmV0dXJuIE1hdGguY2VpbChsZW5ndGggLyBNYXRoLm1pbig0MCwgdGlja0ZvbnQubGluZUhlaWdodCAvIHJhdGlvKSk7XG4gIH1cblxuICAvLyBVdGlsc1xuICBnZXRQaXhlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBudWxsID8gTmFOIDogdGhpcy5nZXRQaXhlbEZvckRlY2ltYWwoKHZhbHVlIC0gdGhpcy5fc3RhcnRWYWx1ZSkgLyB0aGlzLl92YWx1ZVJhbmdlKTtcbiAgfVxuXG4gIGdldFZhbHVlRm9yUGl4ZWwocGl4ZWwpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhcnRWYWx1ZSArIHRoaXMuZ2V0RGVjaW1hbEZvclBpeGVsKHBpeGVsKSAqIHRoaXMuX3ZhbHVlUmFuZ2U7XG4gIH1cbn1cbiIsICJpbXBvcnQge2Zpbml0ZU9yRGVmYXVsdCwgaXNGaW5pdGV9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7Zm9ybWF0TnVtYmVyfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuaW50bC5qcyc7XG5pbXBvcnQge19zZXRNaW5BbmRNYXhCeUtleSwgbG9nMTB9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCBTY2FsZSBmcm9tICcuLi9jb3JlL2NvcmUuc2NhbGUuanMnO1xuaW1wb3J0IExpbmVhclNjYWxlQmFzZSBmcm9tICcuL3NjYWxlLmxpbmVhcmJhc2UuanMnO1xuaW1wb3J0IFRpY2tzIGZyb20gJy4uL2NvcmUvY29yZS50aWNrcy5qcyc7XG5cbmNvbnN0IGxvZzEwRmxvb3IgPSB2ID0+IE1hdGguZmxvb3IobG9nMTAodikpO1xuY29uc3QgY2hhbmdlRXhwb25lbnQgPSAodiwgbSkgPT4gTWF0aC5wb3coMTAsIGxvZzEwRmxvb3IodikgKyBtKTtcblxuZnVuY3Rpb24gaXNNYWpvcih0aWNrVmFsKSB7XG4gIGNvbnN0IHJlbWFpbiA9IHRpY2tWYWwgLyAoTWF0aC5wb3coMTAsIGxvZzEwRmxvb3IodGlja1ZhbCkpKTtcbiAgcmV0dXJuIHJlbWFpbiA9PT0gMTtcbn1cblxuZnVuY3Rpb24gc3RlcHMobWluLCBtYXgsIHJhbmdlRXhwKSB7XG4gIGNvbnN0IHJhbmdlU3RlcCA9IE1hdGgucG93KDEwLCByYW5nZUV4cCk7XG4gIGNvbnN0IHN0YXJ0ID0gTWF0aC5mbG9vcihtaW4gLyByYW5nZVN0ZXApO1xuICBjb25zdCBlbmQgPSBNYXRoLmNlaWwobWF4IC8gcmFuZ2VTdGVwKTtcbiAgcmV0dXJuIGVuZCAtIHN0YXJ0O1xufVxuXG5mdW5jdGlvbiBzdGFydEV4cChtaW4sIG1heCkge1xuICBjb25zdCByYW5nZSA9IG1heCAtIG1pbjtcbiAgbGV0IHJhbmdlRXhwID0gbG9nMTBGbG9vcihyYW5nZSk7XG4gIHdoaWxlIChzdGVwcyhtaW4sIG1heCwgcmFuZ2VFeHApID4gMTApIHtcbiAgICByYW5nZUV4cCsrO1xuICB9XG4gIHdoaWxlIChzdGVwcyhtaW4sIG1heCwgcmFuZ2VFeHApIDwgMTApIHtcbiAgICByYW5nZUV4cC0tO1xuICB9XG4gIHJldHVybiBNYXRoLm1pbihyYW5nZUV4cCwgbG9nMTBGbG9vcihtaW4pKTtcbn1cblxuXG4vKipcbiAqIEdlbmVyYXRlIGEgc2V0IG9mIGxvZ2FyaXRobWljIHRpY2tzXG4gKiBAcGFyYW0gZ2VuZXJhdGlvbk9wdGlvbnMgdGhlIG9wdGlvbnMgdXNlZCB0byBnZW5lcmF0ZSB0aGUgdGlja3NcbiAqIEBwYXJhbSBkYXRhUmFuZ2UgdGhlIHJhbmdlIG9mIHRoZSBkYXRhXG4gKiBAcmV0dXJucyB7b2JqZWN0W119IGFycmF5IG9mIHRpY2sgb2JqZWN0c1xuICovXG5mdW5jdGlvbiBnZW5lcmF0ZVRpY2tzKGdlbmVyYXRpb25PcHRpb25zLCB7bWluLCBtYXh9KSB7XG4gIG1pbiA9IGZpbml0ZU9yRGVmYXVsdChnZW5lcmF0aW9uT3B0aW9ucy5taW4sIG1pbik7XG4gIGNvbnN0IHRpY2tzID0gW107XG4gIGNvbnN0IG1pbkV4cCA9IGxvZzEwRmxvb3IobWluKTtcbiAgbGV0IGV4cCA9IHN0YXJ0RXhwKG1pbiwgbWF4KTtcbiAgbGV0IHByZWNpc2lvbiA9IGV4cCA8IDAgPyBNYXRoLnBvdygxMCwgTWF0aC5hYnMoZXhwKSkgOiAxO1xuICBjb25zdCBzdGVwU2l6ZSA9IE1hdGgucG93KDEwLCBleHApO1xuICBjb25zdCBiYXNlID0gbWluRXhwID4gZXhwID8gTWF0aC5wb3coMTAsIG1pbkV4cCkgOiAwO1xuICBjb25zdCBzdGFydCA9IE1hdGgucm91bmQoKG1pbiAtIGJhc2UpICogcHJlY2lzaW9uKSAvIHByZWNpc2lvbjtcbiAgY29uc3Qgb2Zmc2V0ID0gTWF0aC5mbG9vcigobWluIC0gYmFzZSkgLyBzdGVwU2l6ZSAvIDEwKSAqIHN0ZXBTaXplICogMTA7XG4gIGxldCBzaWduaWZpY2FuZCA9IE1hdGguZmxvb3IoKHN0YXJ0IC0gb2Zmc2V0KSAvIE1hdGgucG93KDEwLCBleHApKTtcbiAgbGV0IHZhbHVlID0gZmluaXRlT3JEZWZhdWx0KGdlbmVyYXRpb25PcHRpb25zLm1pbiwgTWF0aC5yb3VuZCgoYmFzZSArIG9mZnNldCArIHNpZ25pZmljYW5kICogTWF0aC5wb3coMTAsIGV4cCkpICogcHJlY2lzaW9uKSAvIHByZWNpc2lvbik7XG4gIHdoaWxlICh2YWx1ZSA8IG1heCkge1xuICAgIHRpY2tzLnB1c2goe3ZhbHVlLCBtYWpvcjogaXNNYWpvcih2YWx1ZSksIHNpZ25pZmljYW5kfSk7XG4gICAgaWYgKHNpZ25pZmljYW5kID49IDEwKSB7XG4gICAgICBzaWduaWZpY2FuZCA9IHNpZ25pZmljYW5kIDwgMTUgPyAxNSA6IDIwO1xuICAgIH0gZWxzZSB7XG4gICAgICBzaWduaWZpY2FuZCsrO1xuICAgIH1cbiAgICBpZiAoc2lnbmlmaWNhbmQgPj0gMjApIHtcbiAgICAgIGV4cCsrO1xuICAgICAgc2lnbmlmaWNhbmQgPSAyO1xuICAgICAgcHJlY2lzaW9uID0gZXhwID49IDAgPyAxIDogcHJlY2lzaW9uO1xuICAgIH1cbiAgICB2YWx1ZSA9IE1hdGgucm91bmQoKGJhc2UgKyBvZmZzZXQgKyBzaWduaWZpY2FuZCAqIE1hdGgucG93KDEwLCBleHApKSAqIHByZWNpc2lvbikgLyBwcmVjaXNpb247XG4gIH1cbiAgY29uc3QgbGFzdFRpY2sgPSBmaW5pdGVPckRlZmF1bHQoZ2VuZXJhdGlvbk9wdGlvbnMubWF4LCB2YWx1ZSk7XG4gIHRpY2tzLnB1c2goe3ZhbHVlOiBsYXN0VGljaywgbWFqb3I6IGlzTWFqb3IobGFzdFRpY2spLCBzaWduaWZpY2FuZH0pO1xuXG4gIHJldHVybiB0aWNrcztcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTG9nYXJpdGhtaWNTY2FsZSBleHRlbmRzIFNjYWxlIHtcblxuICBzdGF0aWMgaWQgPSAnbG9nYXJpdGhtaWMnO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIHRpY2tzOiB7XG4gICAgICBjYWxsYmFjazogVGlja3MuZm9ybWF0dGVycy5sb2dhcml0aG1pYyxcbiAgICAgIG1ham9yOiB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cblxuICBjb25zdHJ1Y3RvcihjZmcpIHtcbiAgICBzdXBlcihjZmcpO1xuXG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5zdGFydCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLmVuZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLl9zdGFydFZhbHVlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3ZhbHVlUmFuZ2UgPSAwO1xuICB9XG5cbiAgcGFyc2UocmF3LCBpbmRleCkge1xuICAgIGNvbnN0IHZhbHVlID0gTGluZWFyU2NhbGVCYXNlLnByb3RvdHlwZS5wYXJzZS5hcHBseSh0aGlzLCBbcmF3LCBpbmRleF0pO1xuICAgIGlmICh2YWx1ZSA9PT0gMCkge1xuICAgICAgdGhpcy5femVybyA9IHRydWU7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gaXNGaW5pdGUodmFsdWUpICYmIHZhbHVlID4gMCA/IHZhbHVlIDogbnVsbDtcbiAgfVxuXG4gIGRldGVybWluZURhdGFMaW1pdHMoKSB7XG4gICAgY29uc3Qge21pbiwgbWF4fSA9IHRoaXMuZ2V0TWluTWF4KHRydWUpO1xuXG4gICAgdGhpcy5taW4gPSBpc0Zpbml0ZShtaW4pID8gTWF0aC5tYXgoMCwgbWluKSA6IG51bGw7XG4gICAgdGhpcy5tYXggPSBpc0Zpbml0ZShtYXgpID8gTWF0aC5tYXgoMCwgbWF4KSA6IG51bGw7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmJlZ2luQXRaZXJvKSB7XG4gICAgICB0aGlzLl96ZXJvID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBpZiBkYXRhIGhhcyBgMGAgaW4gaXQgb3IgYGJlZ2luQXRaZXJvYCBpcyB0cnVlLCBtaW4gKG5vbiB6ZXJvKSB2YWx1ZSBpcyBhdCBib3R0b21cbiAgICAvLyBvZiBzY2FsZSwgYW5kIGl0IGRvZXMgbm90IGVxdWFsIHN1Z2dlc3RlZE1pbiwgbG93ZXIgdGhlIG1pbiBib3VuZCBieSBvbmUgZXhwLlxuICAgIGlmICh0aGlzLl96ZXJvICYmIHRoaXMubWluICE9PSB0aGlzLl9zdWdnZXN0ZWRNaW4gJiYgIWlzRmluaXRlKHRoaXMuX3VzZXJNaW4pKSB7XG4gICAgICB0aGlzLm1pbiA9IG1pbiA9PT0gY2hhbmdlRXhwb25lbnQodGhpcy5taW4sIDApID8gY2hhbmdlRXhwb25lbnQodGhpcy5taW4sIC0xKSA6IGNoYW5nZUV4cG9uZW50KHRoaXMubWluLCAwKTtcbiAgICB9XG5cbiAgICB0aGlzLmhhbmRsZVRpY2tSYW5nZU9wdGlvbnMoKTtcbiAgfVxuXG4gIGhhbmRsZVRpY2tSYW5nZU9wdGlvbnMoKSB7XG4gICAgY29uc3Qge21pbkRlZmluZWQsIG1heERlZmluZWR9ID0gdGhpcy5nZXRVc2VyQm91bmRzKCk7XG4gICAgbGV0IG1pbiA9IHRoaXMubWluO1xuICAgIGxldCBtYXggPSB0aGlzLm1heDtcblxuICAgIGNvbnN0IHNldE1pbiA9IHYgPT4gKG1pbiA9IG1pbkRlZmluZWQgPyBtaW4gOiB2KTtcbiAgICBjb25zdCBzZXRNYXggPSB2ID0+IChtYXggPSBtYXhEZWZpbmVkID8gbWF4IDogdik7XG5cbiAgICBpZiAobWluID09PSBtYXgpIHtcbiAgICAgIGlmIChtaW4gPD0gMCkgeyAvLyBpbmNsdWRlcyBudWxsXG4gICAgICAgIHNldE1pbigxKTtcbiAgICAgICAgc2V0TWF4KDEwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldE1pbihjaGFuZ2VFeHBvbmVudChtaW4sIC0xKSk7XG4gICAgICAgIHNldE1heChjaGFuZ2VFeHBvbmVudChtYXgsICsxKSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChtaW4gPD0gMCkge1xuICAgICAgc2V0TWluKGNoYW5nZUV4cG9uZW50KG1heCwgLTEpKTtcbiAgICB9XG4gICAgaWYgKG1heCA8PSAwKSB7XG5cbiAgICAgIHNldE1heChjaGFuZ2VFeHBvbmVudChtaW4sICsxKSk7XG4gICAgfVxuXG4gICAgdGhpcy5taW4gPSBtaW47XG4gICAgdGhpcy5tYXggPSBtYXg7XG4gIH1cblxuICBidWlsZFRpY2tzKCkge1xuICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnM7XG5cbiAgICBjb25zdCBnZW5lcmF0aW9uT3B0aW9ucyA9IHtcbiAgICAgIG1pbjogdGhpcy5fdXNlck1pbixcbiAgICAgIG1heDogdGhpcy5fdXNlck1heFxuICAgIH07XG4gICAgY29uc3QgdGlja3MgPSBnZW5lcmF0ZVRpY2tzKGdlbmVyYXRpb25PcHRpb25zLCB0aGlzKTtcblxuICAgIC8vIEF0IHRoaXMgcG9pbnQsIHdlIG5lZWQgdG8gdXBkYXRlIG91ciBtYXggYW5kIG1pbiBnaXZlbiB0aGUgdGljayB2YWx1ZXMsXG4gICAgLy8gc2luY2Ugd2UgcHJvYmFibHkgaGF2ZSBleHBhbmRlZCB0aGUgcmFuZ2Ugb2YgdGhlIHNjYWxlXG4gICAgaWYgKG9wdHMuYm91bmRzID09PSAndGlja3MnKSB7XG4gICAgICBfc2V0TWluQW5kTWF4QnlLZXkodGlja3MsIHRoaXMsICd2YWx1ZScpO1xuICAgIH1cblxuICAgIGlmIChvcHRzLnJldmVyc2UpIHtcbiAgICAgIHRpY2tzLnJldmVyc2UoKTtcblxuICAgICAgdGhpcy5zdGFydCA9IHRoaXMubWF4O1xuICAgICAgdGhpcy5lbmQgPSB0aGlzLm1pbjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zdGFydCA9IHRoaXMubWluO1xuICAgICAgdGhpcy5lbmQgPSB0aGlzLm1heDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGlja3M7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG4gIGdldExhYmVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZFxuICAgICAgPyAnMCdcbiAgICAgIDogZm9ybWF0TnVtYmVyKHZhbHVlLCB0aGlzLmNoYXJ0Lm9wdGlvbnMubG9jYWxlLCB0aGlzLm9wdGlvbnMudGlja3MuZm9ybWF0KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBjb25maWd1cmUoKSB7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLm1pbjtcblxuICAgIHN1cGVyLmNvbmZpZ3VyZSgpO1xuXG4gICAgdGhpcy5fc3RhcnRWYWx1ZSA9IGxvZzEwKHN0YXJ0KTtcbiAgICB0aGlzLl92YWx1ZVJhbmdlID0gbG9nMTAodGhpcy5tYXgpIC0gbG9nMTAoc3RhcnQpO1xuICB9XG5cbiAgZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAwKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMubWluO1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgaXNOYU4odmFsdWUpKSB7XG4gICAgICByZXR1cm4gTmFOO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5nZXRQaXhlbEZvckRlY2ltYWwodmFsdWUgPT09IHRoaXMubWluXG4gICAgICA/IDBcbiAgICAgIDogKGxvZzEwKHZhbHVlKSAtIHRoaXMuX3N0YXJ0VmFsdWUpIC8gdGhpcy5fdmFsdWVSYW5nZSk7XG4gIH1cblxuICBnZXRWYWx1ZUZvclBpeGVsKHBpeGVsKSB7XG4gICAgY29uc3QgZGVjaW1hbCA9IHRoaXMuZ2V0RGVjaW1hbEZvclBpeGVsKHBpeGVsKTtcbiAgICByZXR1cm4gTWF0aC5wb3coMTAsIHRoaXMuX3N0YXJ0VmFsdWUgKyBkZWNpbWFsICogdGhpcy5fdmFsdWVSYW5nZSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vY29yZS9jb3JlLmRlZmF1bHRzLmpzJztcbmltcG9ydCB7X2xvbmdlc3RUZXh0LCBhZGRSb3VuZGVkUmVjdFBhdGgsIHJlbmRlclRleHQsIF9pc1BvaW50SW5BcmVhfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY2FudmFzLmpzJztcbmltcG9ydCB7SEFMRl9QSSwgVEFVLCB0b0RlZ3JlZXMsIHRvUmFkaWFucywgX25vcm1hbGl6ZUFuZ2xlLCBQSX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IExpbmVhclNjYWxlQmFzZSBmcm9tICcuL3NjYWxlLmxpbmVhcmJhc2UuanMnO1xuaW1wb3J0IFRpY2tzIGZyb20gJy4uL2NvcmUvY29yZS50aWNrcy5qcyc7XG5pbXBvcnQge3ZhbHVlT3JEZWZhdWx0LCBpc0FycmF5LCBpc0Zpbml0ZSwgY2FsbGJhY2sgYXMgY2FsbENhbGxiYWNrLCBpc051bGxPclVuZGVmfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge2NyZWF0ZUNvbnRleHQsIHRvRm9udCwgdG9QYWRkaW5nLCB0b1RSQkxDb3JuZXJzfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMub3B0aW9ucy5qcyc7XG5cbmZ1bmN0aW9uIGdldFRpY2tCYWNrZHJvcEhlaWdodChvcHRzKSB7XG4gIGNvbnN0IHRpY2tPcHRzID0gb3B0cy50aWNrcztcblxuICBpZiAodGlja09wdHMuZGlzcGxheSAmJiBvcHRzLmRpc3BsYXkpIHtcbiAgICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKHRpY2tPcHRzLmJhY2tkcm9wUGFkZGluZyk7XG4gICAgcmV0dXJuIHZhbHVlT3JEZWZhdWx0KHRpY2tPcHRzLmZvbnQgJiYgdGlja09wdHMuZm9udC5zaXplLCBkZWZhdWx0cy5mb250LnNpemUpICsgcGFkZGluZy5oZWlnaHQ7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbmZ1bmN0aW9uIG1lYXN1cmVMYWJlbFNpemUoY3R4LCBmb250LCBsYWJlbCkge1xuICBsYWJlbCA9IGlzQXJyYXkobGFiZWwpID8gbGFiZWwgOiBbbGFiZWxdO1xuICByZXR1cm4ge1xuICAgIHc6IF9sb25nZXN0VGV4dChjdHgsIGZvbnQuc3RyaW5nLCBsYWJlbCksXG4gICAgaDogbGFiZWwubGVuZ3RoICogZm9udC5saW5lSGVpZ2h0XG4gIH07XG59XG5cbmZ1bmN0aW9uIGRldGVybWluZUxpbWl0cyhhbmdsZSwgcG9zLCBzaXplLCBtaW4sIG1heCkge1xuICBpZiAoYW5nbGUgPT09IG1pbiB8fCBhbmdsZSA9PT0gbWF4KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXJ0OiBwb3MgLSAoc2l6ZSAvIDIpLFxuICAgICAgZW5kOiBwb3MgKyAoc2l6ZSAvIDIpXG4gICAgfTtcbiAgfSBlbHNlIGlmIChhbmdsZSA8IG1pbiB8fCBhbmdsZSA+IG1heCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGFydDogcG9zIC0gc2l6ZSxcbiAgICAgIGVuZDogcG9zXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IHBvcyxcbiAgICBlbmQ6IHBvcyArIHNpemVcbiAgfTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZml0IGEgcmFkaWFsIGxpbmVhciBzY2FsZSB3aXRoIHBvaW50IGxhYmVsc1xuICovXG5mdW5jdGlvbiBmaXRXaXRoUG9pbnRMYWJlbHMoc2NhbGUpIHtcblxuICAvLyBSaWdodCwgdGhpcyBpcyByZWFsbHkgY29uZnVzaW5nIGFuZCB0aGVyZSBpcyBhIGxvdCBvZiBtYXRocyBnb2luZyBvbiBoZXJlXG4gIC8vIFRoZSBnaXN0IG9mIHRoZSBwcm9ibGVtIGlzIGhlcmU6IGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL25ubmljay82OTZjYzljNTVmNGIwYmViOGZlOVxuICAvL1xuICAvLyBSZWFjdGlvbjogaHR0cHM6Ly9kbC5kcm9wYm94dXNlcmNvbnRlbnQuY29tL3UvMzQ2MDEzNjMvdG9vbXVjaHNjaWVuY2UuZ2lmXG4gIC8vXG4gIC8vIFNvbHV0aW9uOlxuICAvL1xuICAvLyBXZSBhc3N1bWUgdGhlIHJhZGl1cyBvZiB0aGUgcG9seWdvbiBpcyBoYWxmIHRoZSBzaXplIG9mIHRoZSBjYW52YXMgYXQgZmlyc3RcbiAgLy8gYXQgZWFjaCBpbmRleCB3ZSBjaGVjayBpZiB0aGUgdGV4dCBvdmVybGFwcy5cbiAgLy9cbiAgLy8gV2hlcmUgaXQgZG9lcywgd2Ugc3RvcmUgdGhhdCBhbmdsZSBhbmQgdGhhdCBpbmRleC5cbiAgLy9cbiAgLy8gQWZ0ZXIgZmluZGluZyB0aGUgbGFyZ2VzdCBpbmRleCBhbmQgYW5nbGUgd2UgY2FsY3VsYXRlIGhvdyBtdWNoIHdlIG5lZWQgdG8gcmVtb3ZlXG4gIC8vIGZyb20gdGhlIHNoYXBlIHJhZGl1cyB0byBtb3ZlIHRoZSBwb2ludCBpbndhcmRzIGJ5IHRoYXQgeC5cbiAgLy9cbiAgLy8gV2UgYXZlcmFnZSB0aGUgbGVmdCBhbmQgcmlnaHQgZGlzdGFuY2VzIHRvIGdldCB0aGUgbWF4aW11bSBzaGFwZSByYWRpdXMgdGhhdCBjYW4gZml0IGluIHRoZSBib3hcbiAgLy8gYWxvbmcgd2l0aCBsYWJlbHMuXG4gIC8vXG4gIC8vIE9uY2Ugd2UgaGF2ZSB0aGF0LCB3ZSBjYW4gZmluZCB0aGUgY2VudHJlIHBvaW50IGZvciB0aGUgY2hhcnQsIGJ5IHRha2luZyB0aGUgeCB0ZXh0IHByb3RydXNpb25cbiAgLy8gb24gZWFjaCBzaWRlLCByZW1vdmluZyB0aGF0IGZyb20gdGhlIHNpemUsIGhhbHZpbmcgaXQgYW5kIGFkZGluZyB0aGUgbGVmdCB4IHByb3RydXNpb24gd2lkdGguXG4gIC8vXG4gIC8vIFRoaXMgd2lsbCBtZWFuIHdlIGhhdmUgYSBzaGFwZSBmaXR0ZWQgdG8gdGhlIGNhbnZhcywgYXMgbGFyZ2UgYXMgaXQgY2FuIGJlIHdpdGggdGhlIGxhYmVsc1xuICAvLyBhbmQgcG9zaXRpb24gaXQgaW4gdGhlIG1vc3Qgc3BhY2UgZWZmaWNpZW50IG1hbm5lclxuICAvL1xuICAvLyBodHRwczovL2RsLmRyb3Bib3h1c2VyY29udGVudC5jb20vdS8zNDYwMTM2My95ZWFoc2NpZW5jZS5naWZcblxuICAvLyBHZXQgbWF4aW11bSByYWRpdXMgb2YgdGhlIHBvbHlnb24uIEVpdGhlciBoYWxmIHRoZSBoZWlnaHQgKG1pbnVzIHRoZSB0ZXh0IHdpZHRoKSBvciBoYWxmIHRoZSB3aWR0aC5cbiAgLy8gVXNlIHRoaXMgdG8gY2FsY3VsYXRlIHRoZSBvZmZzZXQgKyBjaGFuZ2UuIC0gTWFrZSBzdXJlIEwvUiBwcm90cnVzaW9uIGlzIGF0IGxlYXN0IDAgdG8gc3RvcCBpc3N1ZXMgd2l0aCBjZW50cmUgcG9pbnRzXG4gIGNvbnN0IG9yaWcgPSB7XG4gICAgbDogc2NhbGUubGVmdCArIHNjYWxlLl9wYWRkaW5nLmxlZnQsXG4gICAgcjogc2NhbGUucmlnaHQgLSBzY2FsZS5fcGFkZGluZy5yaWdodCxcbiAgICB0OiBzY2FsZS50b3AgKyBzY2FsZS5fcGFkZGluZy50b3AsXG4gICAgYjogc2NhbGUuYm90dG9tIC0gc2NhbGUuX3BhZGRpbmcuYm90dG9tXG4gIH07XG4gIGNvbnN0IGxpbWl0cyA9IE9iamVjdC5hc3NpZ24oe30sIG9yaWcpO1xuICBjb25zdCBsYWJlbFNpemVzID0gW107XG4gIGNvbnN0IHBhZGRpbmcgPSBbXTtcbiAgY29uc3QgdmFsdWVDb3VudCA9IHNjYWxlLl9wb2ludExhYmVscy5sZW5ndGg7XG4gIGNvbnN0IHBvaW50TGFiZWxPcHRzID0gc2NhbGUub3B0aW9ucy5wb2ludExhYmVscztcbiAgY29uc3QgYWRkaXRpb25hbEFuZ2xlID0gcG9pbnRMYWJlbE9wdHMuY2VudGVyUG9pbnRMYWJlbHMgPyBQSSAvIHZhbHVlQ291bnQgOiAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVDb3VudDsgaSsrKSB7XG4gICAgY29uc3Qgb3B0cyA9IHBvaW50TGFiZWxPcHRzLnNldENvbnRleHQoc2NhbGUuZ2V0UG9pbnRMYWJlbENvbnRleHQoaSkpO1xuICAgIHBhZGRpbmdbaV0gPSBvcHRzLnBhZGRpbmc7XG4gICAgY29uc3QgcG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb24oaSwgc2NhbGUuZHJhd2luZ0FyZWEgKyBwYWRkaW5nW2ldLCBhZGRpdGlvbmFsQW5nbGUpO1xuICAgIGNvbnN0IHBsRm9udCA9IHRvRm9udChvcHRzLmZvbnQpO1xuICAgIGNvbnN0IHRleHRTaXplID0gbWVhc3VyZUxhYmVsU2l6ZShzY2FsZS5jdHgsIHBsRm9udCwgc2NhbGUuX3BvaW50TGFiZWxzW2ldKTtcbiAgICBsYWJlbFNpemVzW2ldID0gdGV4dFNpemU7XG5cbiAgICBjb25zdCBhbmdsZVJhZGlhbnMgPSBfbm9ybWFsaXplQW5nbGUoc2NhbGUuZ2V0SW5kZXhBbmdsZShpKSArIGFkZGl0aW9uYWxBbmdsZSk7XG4gICAgY29uc3QgYW5nbGUgPSBNYXRoLnJvdW5kKHRvRGVncmVlcyhhbmdsZVJhZGlhbnMpKTtcbiAgICBjb25zdCBoTGltaXRzID0gZGV0ZXJtaW5lTGltaXRzKGFuZ2xlLCBwb2ludFBvc2l0aW9uLngsIHRleHRTaXplLncsIDAsIDE4MCk7XG4gICAgY29uc3QgdkxpbWl0cyA9IGRldGVybWluZUxpbWl0cyhhbmdsZSwgcG9pbnRQb3NpdGlvbi55LCB0ZXh0U2l6ZS5oLCA5MCwgMjcwKTtcbiAgICB1cGRhdGVMaW1pdHMobGltaXRzLCBvcmlnLCBhbmdsZVJhZGlhbnMsIGhMaW1pdHMsIHZMaW1pdHMpO1xuICB9XG5cbiAgc2NhbGUuc2V0Q2VudGVyUG9pbnQoXG4gICAgb3JpZy5sIC0gbGltaXRzLmwsXG4gICAgbGltaXRzLnIgLSBvcmlnLnIsXG4gICAgb3JpZy50IC0gbGltaXRzLnQsXG4gICAgbGltaXRzLmIgLSBvcmlnLmJcbiAgKTtcblxuICAvLyBOb3cgdGhhdCB0ZXh0IHNpemUgaXMgZGV0ZXJtaW5lZCwgY29tcHV0ZSB0aGUgZnVsbCBwb3NpdGlvbnNcbiAgc2NhbGUuX3BvaW50TGFiZWxJdGVtcyA9IGJ1aWxkUG9pbnRMYWJlbEl0ZW1zKHNjYWxlLCBsYWJlbFNpemVzLCBwYWRkaW5nKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTGltaXRzKGxpbWl0cywgb3JpZywgYW5nbGUsIGhMaW1pdHMsIHZMaW1pdHMpIHtcbiAgY29uc3Qgc2luID0gTWF0aC5hYnMoTWF0aC5zaW4oYW5nbGUpKTtcbiAgY29uc3QgY29zID0gTWF0aC5hYnMoTWF0aC5jb3MoYW5nbGUpKTtcbiAgbGV0IHggPSAwO1xuICBsZXQgeSA9IDA7XG4gIGlmIChoTGltaXRzLnN0YXJ0IDwgb3JpZy5sKSB7XG4gICAgeCA9IChvcmlnLmwgLSBoTGltaXRzLnN0YXJ0KSAvIHNpbjtcbiAgICBsaW1pdHMubCA9IE1hdGgubWluKGxpbWl0cy5sLCBvcmlnLmwgLSB4KTtcbiAgfSBlbHNlIGlmIChoTGltaXRzLmVuZCA+IG9yaWcucikge1xuICAgIHggPSAoaExpbWl0cy5lbmQgLSBvcmlnLnIpIC8gc2luO1xuICAgIGxpbWl0cy5yID0gTWF0aC5tYXgobGltaXRzLnIsIG9yaWcuciArIHgpO1xuICB9XG4gIGlmICh2TGltaXRzLnN0YXJ0IDwgb3JpZy50KSB7XG4gICAgeSA9IChvcmlnLnQgLSB2TGltaXRzLnN0YXJ0KSAvIGNvcztcbiAgICBsaW1pdHMudCA9IE1hdGgubWluKGxpbWl0cy50LCBvcmlnLnQgLSB5KTtcbiAgfSBlbHNlIGlmICh2TGltaXRzLmVuZCA+IG9yaWcuYikge1xuICAgIHkgPSAodkxpbWl0cy5lbmQgLSBvcmlnLmIpIC8gY29zO1xuICAgIGxpbWl0cy5iID0gTWF0aC5tYXgobGltaXRzLmIsIG9yaWcuYiArIHkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVBvaW50TGFiZWxJdGVtKHNjYWxlLCBpbmRleCwgaXRlbU9wdHMpIHtcbiAgY29uc3Qgb3V0ZXJEaXN0YW5jZSA9IHNjYWxlLmRyYXdpbmdBcmVhO1xuICBjb25zdCB7ZXh0cmEsIGFkZGl0aW9uYWxBbmdsZSwgcGFkZGluZywgc2l6ZX0gPSBpdGVtT3B0cztcbiAgY29uc3QgcG9pbnRMYWJlbFBvc2l0aW9uID0gc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbihpbmRleCwgb3V0ZXJEaXN0YW5jZSArIGV4dHJhICsgcGFkZGluZywgYWRkaXRpb25hbEFuZ2xlKTtcbiAgY29uc3QgYW5nbGUgPSBNYXRoLnJvdW5kKHRvRGVncmVlcyhfbm9ybWFsaXplQW5nbGUocG9pbnRMYWJlbFBvc2l0aW9uLmFuZ2xlICsgSEFMRl9QSSkpKTtcbiAgY29uc3QgeSA9IHlGb3JBbmdsZShwb2ludExhYmVsUG9zaXRpb24ueSwgc2l6ZS5oLCBhbmdsZSk7XG4gIGNvbnN0IHRleHRBbGlnbiA9IGdldFRleHRBbGlnbkZvckFuZ2xlKGFuZ2xlKTtcbiAgY29uc3QgbGVmdCA9IGxlZnRGb3JUZXh0QWxpZ24ocG9pbnRMYWJlbFBvc2l0aW9uLngsIHNpemUudywgdGV4dEFsaWduKTtcbiAgcmV0dXJuIHtcbiAgICAvLyBpZiB0byBkcmF3IG9yIG92ZXJsYXBwZWRcbiAgICB2aXNpYmxlOiB0cnVlLFxuXG4gICAgLy8gVGV4dCBwb3NpdGlvblxuICAgIHg6IHBvaW50TGFiZWxQb3NpdGlvbi54LFxuICAgIHksXG5cbiAgICAvLyBUZXh0IHJlbmRlcmluZyBkYXRhXG4gICAgdGV4dEFsaWduLFxuXG4gICAgLy8gQm91bmRpbmcgYm94XG4gICAgbGVmdCxcbiAgICB0b3A6IHksXG4gICAgcmlnaHQ6IGxlZnQgKyBzaXplLncsXG4gICAgYm90dG9tOiB5ICsgc2l6ZS5oXG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzTm90T3ZlcmxhcHBlZChpdGVtLCBhcmVhKSB7XG4gIGlmICghYXJlYSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGNvbnN0IHtsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b219ID0gaXRlbTtcbiAgY29uc3QgYXBleGVzSW5BcmVhID0gX2lzUG9pbnRJbkFyZWEoe3g6IGxlZnQsIHk6IHRvcH0sIGFyZWEpIHx8IF9pc1BvaW50SW5BcmVhKHt4OiBsZWZ0LCB5OiBib3R0b219LCBhcmVhKSB8fFxuICAgIF9pc1BvaW50SW5BcmVhKHt4OiByaWdodCwgeTogdG9wfSwgYXJlYSkgfHwgX2lzUG9pbnRJbkFyZWEoe3g6IHJpZ2h0LCB5OiBib3R0b219LCBhcmVhKTtcbiAgcmV0dXJuICFhcGV4ZXNJbkFyZWE7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkUG9pbnRMYWJlbEl0ZW1zKHNjYWxlLCBsYWJlbFNpemVzLCBwYWRkaW5nKSB7XG4gIGNvbnN0IGl0ZW1zID0gW107XG4gIGNvbnN0IHZhbHVlQ291bnQgPSBzY2FsZS5fcG9pbnRMYWJlbHMubGVuZ3RoO1xuICBjb25zdCBvcHRzID0gc2NhbGUub3B0aW9ucztcbiAgY29uc3Qge2NlbnRlclBvaW50TGFiZWxzLCBkaXNwbGF5fSA9IG9wdHMucG9pbnRMYWJlbHM7XG4gIGNvbnN0IGl0ZW1PcHRzID0ge1xuICAgIGV4dHJhOiBnZXRUaWNrQmFja2Ryb3BIZWlnaHQob3B0cykgLyAyLFxuICAgIGFkZGl0aW9uYWxBbmdsZTogY2VudGVyUG9pbnRMYWJlbHMgPyBQSSAvIHZhbHVlQ291bnQgOiAwXG4gIH07XG4gIGxldCBhcmVhO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVDb3VudDsgaSsrKSB7XG4gICAgaXRlbU9wdHMucGFkZGluZyA9IHBhZGRpbmdbaV07XG4gICAgaXRlbU9wdHMuc2l6ZSA9IGxhYmVsU2l6ZXNbaV07XG5cbiAgICBjb25zdCBpdGVtID0gY3JlYXRlUG9pbnRMYWJlbEl0ZW0oc2NhbGUsIGksIGl0ZW1PcHRzKTtcbiAgICBpdGVtcy5wdXNoKGl0ZW0pO1xuICAgIGlmIChkaXNwbGF5ID09PSAnYXV0bycpIHtcbiAgICAgIGl0ZW0udmlzaWJsZSA9IGlzTm90T3ZlcmxhcHBlZChpdGVtLCBhcmVhKTtcbiAgICAgIGlmIChpdGVtLnZpc2libGUpIHtcbiAgICAgICAgYXJlYSA9IGl0ZW07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBpdGVtcztcbn1cblxuZnVuY3Rpb24gZ2V0VGV4dEFsaWduRm9yQW5nbGUoYW5nbGUpIHtcbiAgaWYgKGFuZ2xlID09PSAwIHx8IGFuZ2xlID09PSAxODApIHtcbiAgICByZXR1cm4gJ2NlbnRlcic7XG4gIH0gZWxzZSBpZiAoYW5nbGUgPCAxODApIHtcbiAgICByZXR1cm4gJ2xlZnQnO1xuICB9XG5cbiAgcmV0dXJuICdyaWdodCc7XG59XG5cbmZ1bmN0aW9uIGxlZnRGb3JUZXh0QWxpZ24oeCwgdywgYWxpZ24pIHtcbiAgaWYgKGFsaWduID09PSAncmlnaHQnKSB7XG4gICAgeCAtPSB3O1xuICB9IGVsc2UgaWYgKGFsaWduID09PSAnY2VudGVyJykge1xuICAgIHggLT0gKHcgLyAyKTtcbiAgfVxuICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24geUZvckFuZ2xlKHksIGgsIGFuZ2xlKSB7XG4gIGlmIChhbmdsZSA9PT0gOTAgfHwgYW5nbGUgPT09IDI3MCkge1xuICAgIHkgLT0gKGggLyAyKTtcbiAgfSBlbHNlIGlmIChhbmdsZSA+IDI3MCB8fCBhbmdsZSA8IDkwKSB7XG4gICAgeSAtPSBoO1xuICB9XG4gIHJldHVybiB5O1xufVxuXG5mdW5jdGlvbiBkcmF3UG9pbnRMYWJlbEJveChjdHgsIG9wdHMsIGl0ZW0pIHtcbiAgY29uc3Qge2xlZnQsIHRvcCwgcmlnaHQsIGJvdHRvbX0gPSBpdGVtO1xuICBjb25zdCB7YmFja2Ryb3BDb2xvcn0gPSBvcHRzO1xuXG4gIGlmICghaXNOdWxsT3JVbmRlZihiYWNrZHJvcENvbG9yKSkge1xuICAgIGNvbnN0IGJvcmRlclJhZGl1cyA9IHRvVFJCTENvcm5lcnMob3B0cy5ib3JkZXJSYWRpdXMpO1xuICAgIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcob3B0cy5iYWNrZHJvcFBhZGRpbmcpO1xuICAgIGN0eC5maWxsU3R5bGUgPSBiYWNrZHJvcENvbG9yO1xuXG4gICAgY29uc3QgYmFja2Ryb3BMZWZ0ID0gbGVmdCAtIHBhZGRpbmcubGVmdDtcbiAgICBjb25zdCBiYWNrZHJvcFRvcCA9IHRvcCAtIHBhZGRpbmcudG9wO1xuICAgIGNvbnN0IGJhY2tkcm9wV2lkdGggPSByaWdodCAtIGxlZnQgKyBwYWRkaW5nLndpZHRoO1xuICAgIGNvbnN0IGJhY2tkcm9wSGVpZ2h0ID0gYm90dG9tIC0gdG9wICsgcGFkZGluZy5oZWlnaHQ7XG5cbiAgICBpZiAoT2JqZWN0LnZhbHVlcyhib3JkZXJSYWRpdXMpLnNvbWUodiA9PiB2ICE9PSAwKSkge1xuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgYWRkUm91bmRlZFJlY3RQYXRoKGN0eCwge1xuICAgICAgICB4OiBiYWNrZHJvcExlZnQsXG4gICAgICAgIHk6IGJhY2tkcm9wVG9wLFxuICAgICAgICB3OiBiYWNrZHJvcFdpZHRoLFxuICAgICAgICBoOiBiYWNrZHJvcEhlaWdodCxcbiAgICAgICAgcmFkaXVzOiBib3JkZXJSYWRpdXMsXG4gICAgICB9KTtcbiAgICAgIGN0eC5maWxsKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN0eC5maWxsUmVjdChiYWNrZHJvcExlZnQsIGJhY2tkcm9wVG9wLCBiYWNrZHJvcFdpZHRoLCBiYWNrZHJvcEhlaWdodCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGRyYXdQb2ludExhYmVscyhzY2FsZSwgbGFiZWxDb3VudCkge1xuICBjb25zdCB7Y3R4LCBvcHRpb25zOiB7cG9pbnRMYWJlbHN9fSA9IHNjYWxlO1xuXG4gIGZvciAobGV0IGkgPSBsYWJlbENvdW50IC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBjb25zdCBpdGVtID0gc2NhbGUuX3BvaW50TGFiZWxJdGVtc1tpXTtcbiAgICBpZiAoIWl0ZW0udmlzaWJsZSkge1xuICAgICAgLy8gb3ZlcmxhcHBpbmdcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBvcHRzQXRJbmRleCA9IHBvaW50TGFiZWxzLnNldENvbnRleHQoc2NhbGUuZ2V0UG9pbnRMYWJlbENvbnRleHQoaSkpO1xuICAgIGRyYXdQb2ludExhYmVsQm94KGN0eCwgb3B0c0F0SW5kZXgsIGl0ZW0pO1xuICAgIGNvbnN0IHBsRm9udCA9IHRvRm9udChvcHRzQXRJbmRleC5mb250KTtcbiAgICBjb25zdCB7eCwgeSwgdGV4dEFsaWdufSA9IGl0ZW07XG5cbiAgICByZW5kZXJUZXh0KFxuICAgICAgY3R4LFxuICAgICAgc2NhbGUuX3BvaW50TGFiZWxzW2ldLFxuICAgICAgeCxcbiAgICAgIHkgKyAocGxGb250LmxpbmVIZWlnaHQgLyAyKSxcbiAgICAgIHBsRm9udCxcbiAgICAgIHtcbiAgICAgICAgY29sb3I6IG9wdHNBdEluZGV4LmNvbG9yLFxuICAgICAgICB0ZXh0QWxpZ246IHRleHRBbGlnbixcbiAgICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJ1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGF0aFJhZGl1c0xpbmUoc2NhbGUsIHJhZGl1cywgY2lyY3VsYXIsIGxhYmVsQ291bnQpIHtcbiAgY29uc3Qge2N0eH0gPSBzY2FsZTtcbiAgaWYgKGNpcmN1bGFyKSB7XG4gICAgLy8gRHJhdyBjaXJjdWxhciBhcmNzIGJldHdlZW4gdGhlIHBvaW50c1xuICAgIGN0eC5hcmMoc2NhbGUueENlbnRlciwgc2NhbGUueUNlbnRlciwgcmFkaXVzLCAwLCBUQVUpO1xuICB9IGVsc2Uge1xuICAgIC8vIERyYXcgc3RyYWlnaHQgbGluZXMgY29ubmVjdGluZyBlYWNoIGluZGV4XG4gICAgbGV0IHBvaW50UG9zaXRpb24gPSBzY2FsZS5nZXRQb2ludFBvc2l0aW9uKDAsIHJhZGl1cyk7XG4gICAgY3R4Lm1vdmVUbyhwb2ludFBvc2l0aW9uLngsIHBvaW50UG9zaXRpb24ueSk7XG5cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IGxhYmVsQ291bnQ7IGkrKykge1xuICAgICAgcG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb24oaSwgcmFkaXVzKTtcbiAgICAgIGN0eC5saW5lVG8ocG9pbnRQb3NpdGlvbi54LCBwb2ludFBvc2l0aW9uLnkpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkcmF3UmFkaXVzTGluZShzY2FsZSwgZ3JpZExpbmVPcHRzLCByYWRpdXMsIGxhYmVsQ291bnQsIGJvcmRlck9wdHMpIHtcbiAgY29uc3QgY3R4ID0gc2NhbGUuY3R4O1xuICBjb25zdCBjaXJjdWxhciA9IGdyaWRMaW5lT3B0cy5jaXJjdWxhcjtcblxuICBjb25zdCB7Y29sb3IsIGxpbmVXaWR0aH0gPSBncmlkTGluZU9wdHM7XG5cbiAgaWYgKCghY2lyY3VsYXIgJiYgIWxhYmVsQ291bnQpIHx8ICFjb2xvciB8fCAhbGluZVdpZHRoIHx8IHJhZGl1cyA8IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjdHguc2F2ZSgpO1xuICBjdHguc3Ryb2tlU3R5bGUgPSBjb2xvcjtcbiAgY3R4LmxpbmVXaWR0aCA9IGxpbmVXaWR0aDtcbiAgY3R4LnNldExpbmVEYXNoKGJvcmRlck9wdHMuZGFzaCk7XG4gIGN0eC5saW5lRGFzaE9mZnNldCA9IGJvcmRlck9wdHMuZGFzaE9mZnNldDtcblxuICBjdHguYmVnaW5QYXRoKCk7XG4gIHBhdGhSYWRpdXNMaW5lKHNjYWxlLCByYWRpdXMsIGNpcmN1bGFyLCBsYWJlbENvdW50KTtcbiAgY3R4LmNsb3NlUGF0aCgpO1xuICBjdHguc3Ryb2tlKCk7XG4gIGN0eC5yZXN0b3JlKCk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVBvaW50TGFiZWxDb250ZXh0KHBhcmVudCwgaW5kZXgsIGxhYmVsKSB7XG4gIHJldHVybiBjcmVhdGVDb250ZXh0KHBhcmVudCwge1xuICAgIGxhYmVsLFxuICAgIGluZGV4LFxuICAgIHR5cGU6ICdwb2ludExhYmVsJ1xuICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmFkaWFsTGluZWFyU2NhbGUgZXh0ZW5kcyBMaW5lYXJTY2FsZUJhc2Uge1xuXG4gIHN0YXRpYyBpZCA9ICdyYWRpYWxMaW5lYXInO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIGRpc3BsYXk6IHRydWUsXG5cbiAgICAvLyBCb29sZWFuIC0gV2hldGhlciB0byBhbmltYXRlIHNjYWxpbmcgdGhlIGNoYXJ0IGZyb20gdGhlIGNlbnRyZVxuICAgIGFuaW1hdGU6IHRydWUsXG4gICAgcG9zaXRpb246ICdjaGFydEFyZWEnLFxuXG4gICAgYW5nbGVMaW5lczoge1xuICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgIGxpbmVXaWR0aDogMSxcbiAgICAgIGJvcmRlckRhc2g6IFtdLFxuICAgICAgYm9yZGVyRGFzaE9mZnNldDogMC4wXG4gICAgfSxcblxuICAgIGdyaWQ6IHtcbiAgICAgIGNpcmN1bGFyOiBmYWxzZVxuICAgIH0sXG5cbiAgICBzdGFydEFuZ2xlOiAwLFxuXG4gICAgLy8gbGFiZWwgc2V0dGluZ3NcbiAgICB0aWNrczoge1xuICAgICAgLy8gQm9vbGVhbiAtIFNob3cgYSBiYWNrZHJvcCB0byB0aGUgc2NhbGUgbGFiZWxcbiAgICAgIHNob3dMYWJlbEJhY2tkcm9wOiB0cnVlLFxuXG4gICAgICBjYWxsYmFjazogVGlja3MuZm9ybWF0dGVycy5udW1lcmljXG4gICAgfSxcblxuICAgIHBvaW50TGFiZWxzOiB7XG4gICAgICBiYWNrZHJvcENvbG9yOiB1bmRlZmluZWQsXG5cbiAgICAgIC8vIE51bWJlciAtIFRoZSBiYWNrZHJvcCBwYWRkaW5nIGFib3ZlICYgYmVsb3cgdGhlIGxhYmVsIGluIHBpeGVsc1xuICAgICAgYmFja2Ryb3BQYWRkaW5nOiAyLFxuXG4gICAgICAvLyBCb29sZWFuIC0gaWYgdHJ1ZSwgc2hvdyBwb2ludCBsYWJlbHNcbiAgICAgIGRpc3BsYXk6IHRydWUsXG5cbiAgICAgIC8vIE51bWJlciAtIFBvaW50IGxhYmVsIGZvbnQgc2l6ZSBpbiBwaXhlbHNcbiAgICAgIGZvbnQ6IHtcbiAgICAgICAgc2l6ZTogMTBcbiAgICAgIH0sXG5cbiAgICAgIC8vIEZ1bmN0aW9uIC0gVXNlZCB0byBjb252ZXJ0IHBvaW50IGxhYmVsc1xuICAgICAgY2FsbGJhY2sobGFiZWwpIHtcbiAgICAgICAgcmV0dXJuIGxhYmVsO1xuICAgICAgfSxcblxuICAgICAgLy8gTnVtYmVyIC0gQWRkaXRpb25sIHBhZGRpbmcgYmV0d2VlbiBzY2FsZSBhbmQgcG9pbnRMYWJlbFxuICAgICAgcGFkZGluZzogNSxcblxuICAgICAgLy8gQm9vbGVhbiAtIGlmIHRydWUsIGNlbnRlciBwb2ludCBsYWJlbHMgdG8gc2xpY2VzIGluIHBvbGFyIGNoYXJ0XG4gICAgICBjZW50ZXJQb2ludExhYmVsczogZmFsc2VcbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGRlZmF1bHRSb3V0ZXMgPSB7XG4gICAgJ2FuZ2xlTGluZXMuY29sb3InOiAnYm9yZGVyQ29sb3InLFxuICAgICdwb2ludExhYmVscy5jb2xvcic6ICdjb2xvcicsXG4gICAgJ3RpY2tzLmNvbG9yJzogJ2NvbG9yJ1xuICB9O1xuXG4gIHN0YXRpYyBkZXNjcmlwdG9ycyA9IHtcbiAgICBhbmdsZUxpbmVzOiB7XG4gICAgICBfZmFsbGJhY2s6ICdncmlkJ1xuICAgIH1cbiAgfTtcblxuICBjb25zdHJ1Y3RvcihjZmcpIHtcbiAgICBzdXBlcihjZmcpO1xuXG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy54Q2VudGVyID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMueUNlbnRlciA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLmRyYXdpbmdBcmVhID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgdGhpcy5fcG9pbnRMYWJlbHMgPSBbXTtcbiAgICB0aGlzLl9wb2ludExhYmVsSXRlbXMgPSBbXTtcbiAgfVxuXG4gIHNldERpbWVuc2lvbnMoKSB7XG4gICAgLy8gU2V0IHRoZSB1bmNvbnN0cmFpbmVkIGRpbWVuc2lvbiBiZWZvcmUgbGFiZWwgcm90YXRpb25cbiAgICBjb25zdCBwYWRkaW5nID0gdGhpcy5fcGFkZGluZyA9IHRvUGFkZGluZyhnZXRUaWNrQmFja2Ryb3BIZWlnaHQodGhpcy5vcHRpb25zKSAvIDIpO1xuICAgIGNvbnN0IHcgPSB0aGlzLndpZHRoID0gdGhpcy5tYXhXaWR0aCAtIHBhZGRpbmcud2lkdGg7XG4gICAgY29uc3QgaCA9IHRoaXMuaGVpZ2h0ID0gdGhpcy5tYXhIZWlnaHQgLSBwYWRkaW5nLmhlaWdodDtcbiAgICB0aGlzLnhDZW50ZXIgPSBNYXRoLmZsb29yKHRoaXMubGVmdCArIHcgLyAyICsgcGFkZGluZy5sZWZ0KTtcbiAgICB0aGlzLnlDZW50ZXIgPSBNYXRoLmZsb29yKHRoaXMudG9wICsgaCAvIDIgKyBwYWRkaW5nLnRvcCk7XG4gICAgdGhpcy5kcmF3aW5nQXJlYSA9IE1hdGguZmxvb3IoTWF0aC5taW4odywgaCkgLyAyKTtcbiAgfVxuXG4gIGRldGVybWluZURhdGFMaW1pdHMoKSB7XG4gICAgY29uc3Qge21pbiwgbWF4fSA9IHRoaXMuZ2V0TWluTWF4KGZhbHNlKTtcblxuICAgIHRoaXMubWluID0gaXNGaW5pdGUobWluKSAmJiAhaXNOYU4obWluKSA/IG1pbiA6IDA7XG4gICAgdGhpcy5tYXggPSBpc0Zpbml0ZShtYXgpICYmICFpc05hTihtYXgpID8gbWF4IDogMDtcblxuICAgIC8vIENvbW1vbiBiYXNlIGltcGxlbWVudGF0aW9uIHRvIGhhbmRsZSBtaW4sIG1heCwgYmVnaW5BdFplcm9cbiAgICB0aGlzLmhhbmRsZVRpY2tSYW5nZU9wdGlvbnMoKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiB0aWNrcyBiYXNlZCBvbiB0aGUgc2NhbGUgZGltZW5zaW9uXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGNvbXB1dGVUaWNrTGltaXQoKSB7XG4gICAgcmV0dXJuIE1hdGguY2VpbCh0aGlzLmRyYXdpbmdBcmVhIC8gZ2V0VGlja0JhY2tkcm9wSGVpZ2h0KHRoaXMub3B0aW9ucykpO1xuICB9XG5cbiAgZ2VuZXJhdGVUaWNrTGFiZWxzKHRpY2tzKSB7XG4gICAgTGluZWFyU2NhbGVCYXNlLnByb3RvdHlwZS5nZW5lcmF0ZVRpY2tMYWJlbHMuY2FsbCh0aGlzLCB0aWNrcyk7XG5cbiAgICAvLyBQb2ludCBsYWJlbHNcbiAgICB0aGlzLl9wb2ludExhYmVscyA9IHRoaXMuZ2V0TGFiZWxzKClcbiAgICAgIC5tYXAoKHZhbHVlLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBsYWJlbCA9IGNhbGxDYWxsYmFjayh0aGlzLm9wdGlvbnMucG9pbnRMYWJlbHMuY2FsbGJhY2ssIFt2YWx1ZSwgaW5kZXhdLCB0aGlzKTtcbiAgICAgICAgcmV0dXJuIGxhYmVsIHx8IGxhYmVsID09PSAwID8gbGFiZWwgOiAnJztcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKCh2LCBpKSA9PiB0aGlzLmNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGkpKTtcbiAgfVxuXG4gIGZpdCgpIHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuXG4gICAgaWYgKG9wdHMuZGlzcGxheSAmJiBvcHRzLnBvaW50TGFiZWxzLmRpc3BsYXkpIHtcbiAgICAgIGZpdFdpdGhQb2ludExhYmVscyh0aGlzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRDZW50ZXJQb2ludCgwLCAwLCAwLCAwKTtcbiAgICB9XG4gIH1cblxuICBzZXRDZW50ZXJQb2ludChsZWZ0TW92ZW1lbnQsIHJpZ2h0TW92ZW1lbnQsIHRvcE1vdmVtZW50LCBib3R0b21Nb3ZlbWVudCkge1xuICAgIHRoaXMueENlbnRlciArPSBNYXRoLmZsb29yKChsZWZ0TW92ZW1lbnQgLSByaWdodE1vdmVtZW50KSAvIDIpO1xuICAgIHRoaXMueUNlbnRlciArPSBNYXRoLmZsb29yKCh0b3BNb3ZlbWVudCAtIGJvdHRvbU1vdmVtZW50KSAvIDIpO1xuICAgIHRoaXMuZHJhd2luZ0FyZWEgLT0gTWF0aC5taW4odGhpcy5kcmF3aW5nQXJlYSAvIDIsIE1hdGgubWF4KGxlZnRNb3ZlbWVudCwgcmlnaHRNb3ZlbWVudCwgdG9wTW92ZW1lbnQsIGJvdHRvbU1vdmVtZW50KSk7XG4gIH1cblxuICBnZXRJbmRleEFuZ2xlKGluZGV4KSB7XG4gICAgY29uc3QgYW5nbGVNdWx0aXBsaWVyID0gVEFVIC8gKHRoaXMuX3BvaW50TGFiZWxzLmxlbmd0aCB8fCAxKTtcbiAgICBjb25zdCBzdGFydEFuZ2xlID0gdGhpcy5vcHRpb25zLnN0YXJ0QW5nbGUgfHwgMDtcblxuICAgIHJldHVybiBfbm9ybWFsaXplQW5nbGUoaW5kZXggKiBhbmdsZU11bHRpcGxpZXIgKyB0b1JhZGlhbnMoc3RhcnRBbmdsZSkpO1xuICB9XG5cbiAgZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUodmFsdWUpIHtcbiAgICBpZiAoaXNOdWxsT3JVbmRlZih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBOYU47XG4gICAgfVxuXG4gICAgLy8gVGFrZSBpbnRvIGFjY291bnQgaGFsZiBmb250IHNpemUgKyB0aGUgeVBhZGRpbmcgb2YgdGhlIHRvcCB2YWx1ZVxuICAgIGNvbnN0IHNjYWxpbmdGYWN0b3IgPSB0aGlzLmRyYXdpbmdBcmVhIC8gKHRoaXMubWF4IC0gdGhpcy5taW4pO1xuICAgIGlmICh0aGlzLm9wdGlvbnMucmV2ZXJzZSkge1xuICAgICAgcmV0dXJuICh0aGlzLm1heCAtIHZhbHVlKSAqIHNjYWxpbmdGYWN0b3I7XG4gICAgfVxuICAgIHJldHVybiAodmFsdWUgLSB0aGlzLm1pbikgKiBzY2FsaW5nRmFjdG9yO1xuICB9XG5cbiAgZ2V0VmFsdWVGb3JEaXN0YW5jZUZyb21DZW50ZXIoZGlzdGFuY2UpIHtcbiAgICBpZiAoaXNOdWxsT3JVbmRlZihkaXN0YW5jZSkpIHtcbiAgICAgIHJldHVybiBOYU47XG4gICAgfVxuXG4gICAgY29uc3Qgc2NhbGVkRGlzdGFuY2UgPSBkaXN0YW5jZSAvICh0aGlzLmRyYXdpbmdBcmVhIC8gKHRoaXMubWF4IC0gdGhpcy5taW4pKTtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnJldmVyc2UgPyB0aGlzLm1heCAtIHNjYWxlZERpc3RhbmNlIDogdGhpcy5taW4gKyBzY2FsZWREaXN0YW5jZTtcbiAgfVxuXG4gIGdldFBvaW50TGFiZWxDb250ZXh0KGluZGV4KSB7XG4gICAgY29uc3QgcG9pbnRMYWJlbHMgPSB0aGlzLl9wb2ludExhYmVscyB8fCBbXTtcblxuICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgcG9pbnRMYWJlbHMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBwb2ludExhYmVsID0gcG9pbnRMYWJlbHNbaW5kZXhdO1xuICAgICAgcmV0dXJuIGNyZWF0ZVBvaW50TGFiZWxDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpLCBpbmRleCwgcG9pbnRMYWJlbCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0UG9pbnRQb3NpdGlvbihpbmRleCwgZGlzdGFuY2VGcm9tQ2VudGVyLCBhZGRpdGlvbmFsQW5nbGUgPSAwKSB7XG4gICAgY29uc3QgYW5nbGUgPSB0aGlzLmdldEluZGV4QW5nbGUoaW5kZXgpIC0gSEFMRl9QSSArIGFkZGl0aW9uYWxBbmdsZTtcbiAgICByZXR1cm4ge1xuICAgICAgeDogTWF0aC5jb3MoYW5nbGUpICogZGlzdGFuY2VGcm9tQ2VudGVyICsgdGhpcy54Q2VudGVyLFxuICAgICAgeTogTWF0aC5zaW4oYW5nbGUpICogZGlzdGFuY2VGcm9tQ2VudGVyICsgdGhpcy55Q2VudGVyLFxuICAgICAgYW5nbGVcbiAgICB9O1xuICB9XG5cbiAgZ2V0UG9pbnRQb3NpdGlvbkZvclZhbHVlKGluZGV4LCB2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLmdldFBvaW50UG9zaXRpb24oaW5kZXgsIHRoaXMuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUodmFsdWUpKTtcbiAgfVxuXG4gIGdldEJhc2VQb3NpdGlvbihpbmRleCkge1xuICAgIHJldHVybiB0aGlzLmdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZShpbmRleCB8fCAwLCB0aGlzLmdldEJhc2VWYWx1ZSgpKTtcbiAgfVxuXG4gIGdldFBvaW50TGFiZWxQb3NpdGlvbihpbmRleCkge1xuICAgIGNvbnN0IHtsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b219ID0gdGhpcy5fcG9pbnRMYWJlbEl0ZW1zW2luZGV4XTtcbiAgICByZXR1cm4ge1xuICAgICAgbGVmdCxcbiAgICAgIHRvcCxcbiAgICAgIHJpZ2h0LFxuICAgICAgYm90dG9tLFxuICAgIH07XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZHJhd0JhY2tncm91bmQoKSB7XG4gICAgY29uc3Qge2JhY2tncm91bmRDb2xvciwgZ3JpZDoge2NpcmN1bGFyfX0gPSB0aGlzLm9wdGlvbnM7XG4gICAgaWYgKGJhY2tncm91bmRDb2xvcikge1xuICAgICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgcGF0aFJhZGl1c0xpbmUodGhpcywgdGhpcy5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZSh0aGlzLl9lbmRWYWx1ZSksIGNpcmN1bGFyLCB0aGlzLl9wb2ludExhYmVscy5sZW5ndGgpO1xuICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IGJhY2tncm91bmRDb2xvcjtcbiAgICAgIGN0eC5maWxsKCk7XG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBkcmF3R3JpZCgpIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHthbmdsZUxpbmVzLCBncmlkLCBib3JkZXJ9ID0gb3B0cztcbiAgICBjb25zdCBsYWJlbENvdW50ID0gdGhpcy5fcG9pbnRMYWJlbHMubGVuZ3RoO1xuXG4gICAgbGV0IGksIG9mZnNldCwgcG9zaXRpb247XG5cbiAgICBpZiAob3B0cy5wb2ludExhYmVscy5kaXNwbGF5KSB7XG4gICAgICBkcmF3UG9pbnRMYWJlbHModGhpcywgbGFiZWxDb3VudCk7XG4gICAgfVxuXG4gICAgaWYgKGdyaWQuZGlzcGxheSkge1xuICAgICAgdGhpcy50aWNrcy5mb3JFYWNoKCh0aWNrLCBpbmRleCkgPT4ge1xuICAgICAgICBpZiAoaW5kZXggIT09IDAgfHwgKGluZGV4ID09PSAwICYmIHRoaXMubWluIDwgMCkpIHtcbiAgICAgICAgICBvZmZzZXQgPSB0aGlzLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKHRpY2sudmFsdWUpO1xuICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmdldENvbnRleHQoaW5kZXgpO1xuICAgICAgICAgIGNvbnN0IG9wdHNBdEluZGV4ID0gZ3JpZC5zZXRDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgIGNvbnN0IG9wdHNBdEluZGV4Qm9yZGVyID0gYm9yZGVyLnNldENvbnRleHQoY29udGV4dCk7XG5cbiAgICAgICAgICBkcmF3UmFkaXVzTGluZSh0aGlzLCBvcHRzQXRJbmRleCwgb2Zmc2V0LCBsYWJlbENvdW50LCBvcHRzQXRJbmRleEJvcmRlcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChhbmdsZUxpbmVzLmRpc3BsYXkpIHtcbiAgICAgIGN0eC5zYXZlKCk7XG5cbiAgICAgIGZvciAoaSA9IGxhYmVsQ291bnQgLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBjb25zdCBvcHRzQXRJbmRleCA9IGFuZ2xlTGluZXMuc2V0Q29udGV4dCh0aGlzLmdldFBvaW50TGFiZWxDb250ZXh0KGkpKTtcbiAgICAgICAgY29uc3Qge2NvbG9yLCBsaW5lV2lkdGh9ID0gb3B0c0F0SW5kZXg7XG5cbiAgICAgICAgaWYgKCFsaW5lV2lkdGggfHwgIWNvbG9yKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjdHgubGluZVdpZHRoID0gbGluZVdpZHRoO1xuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBjb2xvcjtcblxuICAgICAgICBjdHguc2V0TGluZURhc2gob3B0c0F0SW5kZXguYm9yZGVyRGFzaCk7XG4gICAgICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IG9wdHNBdEluZGV4LmJvcmRlckRhc2hPZmZzZXQ7XG5cbiAgICAgICAgb2Zmc2V0ID0gdGhpcy5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZShvcHRzLnRpY2tzLnJldmVyc2UgPyB0aGlzLm1pbiA6IHRoaXMubWF4KTtcbiAgICAgICAgcG9zaXRpb24gPSB0aGlzLmdldFBvaW50UG9zaXRpb24oaSwgb2Zmc2V0KTtcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBjdHgubW92ZVRvKHRoaXMueENlbnRlciwgdGhpcy55Q2VudGVyKTtcbiAgICAgICAgY3R4LmxpbmVUbyhwb3NpdGlvbi54LCBwb3NpdGlvbi55KTtcbiAgICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgfVxuXG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBkcmF3Qm9yZGVyKCkge31cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZHJhd0xhYmVscygpIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHRpY2tPcHRzID0gb3B0cy50aWNrcztcblxuICAgIGlmICghdGlja09wdHMuZGlzcGxheSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0QW5nbGUgPSB0aGlzLmdldEluZGV4QW5nbGUoMCk7XG4gICAgbGV0IG9mZnNldCwgd2lkdGg7XG5cbiAgICBjdHguc2F2ZSgpO1xuICAgIGN0eC50cmFuc2xhdGUodGhpcy54Q2VudGVyLCB0aGlzLnlDZW50ZXIpO1xuICAgIGN0eC5yb3RhdGUoc3RhcnRBbmdsZSk7XG4gICAgY3R4LnRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcblxuICAgIHRoaXMudGlja3MuZm9yRWFjaCgodGljaywgaW5kZXgpID0+IHtcbiAgICAgIGlmICgoaW5kZXggPT09IDAgJiYgdGhpcy5taW4gPj0gMCkgJiYgIW9wdHMucmV2ZXJzZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9wdHNBdEluZGV4ID0gdGlja09wdHMuc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoaW5kZXgpKTtcbiAgICAgIGNvbnN0IHRpY2tGb250ID0gdG9Gb250KG9wdHNBdEluZGV4LmZvbnQpO1xuICAgICAgb2Zmc2V0ID0gdGhpcy5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZSh0aGlzLnRpY2tzW2luZGV4XS52YWx1ZSk7XG5cbiAgICAgIGlmIChvcHRzQXRJbmRleC5zaG93TGFiZWxCYWNrZHJvcCkge1xuICAgICAgICBjdHguZm9udCA9IHRpY2tGb250LnN0cmluZztcbiAgICAgICAgd2lkdGggPSBjdHgubWVhc3VyZVRleHQodGljay5sYWJlbCkud2lkdGg7XG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRzQXRJbmRleC5iYWNrZHJvcENvbG9yO1xuXG4gICAgICAgIGNvbnN0IHBhZGRpbmcgPSB0b1BhZGRpbmcob3B0c0F0SW5kZXguYmFja2Ryb3BQYWRkaW5nKTtcbiAgICAgICAgY3R4LmZpbGxSZWN0KFxuICAgICAgICAgIC13aWR0aCAvIDIgLSBwYWRkaW5nLmxlZnQsXG4gICAgICAgICAgLW9mZnNldCAtIHRpY2tGb250LnNpemUgLyAyIC0gcGFkZGluZy50b3AsXG4gICAgICAgICAgd2lkdGggKyBwYWRkaW5nLndpZHRoLFxuICAgICAgICAgIHRpY2tGb250LnNpemUgKyBwYWRkaW5nLmhlaWdodFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZW5kZXJUZXh0KGN0eCwgdGljay5sYWJlbCwgMCwgLW9mZnNldCwgdGlja0ZvbnQsIHtcbiAgICAgICAgY29sb3I6IG9wdHNBdEluZGV4LmNvbG9yLFxuICAgICAgICBzdHJva2VDb2xvcjogb3B0c0F0SW5kZXgudGV4dFN0cm9rZUNvbG9yLFxuICAgICAgICBzdHJva2VXaWR0aDogb3B0c0F0SW5kZXgudGV4dFN0cm9rZVdpZHRoLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGRyYXdUaXRsZSgpIHt9XG59XG4iLCAiaW1wb3J0IGFkYXB0ZXJzIGZyb20gJy4uL2NvcmUvY29yZS5hZGFwdGVycy5qcyc7XG5pbXBvcnQge2NhbGxiYWNrIGFzIGNhbGwsIGlzRmluaXRlLCBpc051bGxPclVuZGVmLCBtZXJnZUlmLCB2YWx1ZU9yRGVmYXVsdH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuaW1wb3J0IHt0b1JhZGlhbnMsIGlzTnVtYmVyLCBfbGltaXRWYWx1ZX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IFNjYWxlIGZyb20gJy4uL2NvcmUvY29yZS5zY2FsZS5qcyc7XG5pbXBvcnQge19hcnJheVVuaXF1ZSwgX2ZpbHRlckJldHdlZW4sIF9sb29rdXB9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb2xsZWN0aW9uLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vY29yZS9jb3JlLmFkYXB0ZXJzLmpzJykuVGltZVVuaXQgfSBVbml0XG4gKiBAdHlwZWRlZiB7e2NvbW1vbjogYm9vbGVhbiwgc2l6ZTogbnVtYmVyLCBzdGVwcz86IG51bWJlcn19IEludGVydmFsXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vY29yZS9jb3JlLmFkYXB0ZXJzLmpzJykuRGF0ZUFkYXB0ZXIgfSBEYXRlQWRhcHRlclxuICovXG5cbi8qKlxuICogQHR5cGUge09iamVjdDxVbml0LCBJbnRlcnZhbD59XG4gKi9cbmNvbnN0IElOVEVSVkFMUyA9IHtcbiAgbWlsbGlzZWNvbmQ6IHtjb21tb246IHRydWUsIHNpemU6IDEsIHN0ZXBzOiAxMDAwfSxcbiAgc2Vjb25kOiB7Y29tbW9uOiB0cnVlLCBzaXplOiAxMDAwLCBzdGVwczogNjB9LFxuICBtaW51dGU6IHtjb21tb246IHRydWUsIHNpemU6IDYwMDAwLCBzdGVwczogNjB9LFxuICBob3VyOiB7Y29tbW9uOiB0cnVlLCBzaXplOiAzNjAwMDAwLCBzdGVwczogMjR9LFxuICBkYXk6IHtjb21tb246IHRydWUsIHNpemU6IDg2NDAwMDAwLCBzdGVwczogMzB9LFxuICB3ZWVrOiB7Y29tbW9uOiBmYWxzZSwgc2l6ZTogNjA0ODAwMDAwLCBzdGVwczogNH0sXG4gIG1vbnRoOiB7Y29tbW9uOiB0cnVlLCBzaXplOiAyLjYyOGU5LCBzdGVwczogMTJ9LFxuICBxdWFydGVyOiB7Y29tbW9uOiBmYWxzZSwgc2l6ZTogNy44ODRlOSwgc3RlcHM6IDR9LFxuICB5ZWFyOiB7Y29tbW9uOiB0cnVlLCBzaXplOiAzLjE1NGUxMH1cbn07XG5cbi8qKlxuICogQHR5cGUge1VuaXRbXX1cbiAqL1xuY29uc3QgVU5JVFMgPSAvKiogQHR5cGUgVW5pdFtdICovIC8qICNfX1BVUkVfXyAqLyAoT2JqZWN0LmtleXMoSU5URVJWQUxTKSk7XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IGFcbiAqIEBwYXJhbSB7bnVtYmVyfSBiXG4gKi9cbmZ1bmN0aW9uIHNvcnRlcihhLCBiKSB7XG4gIHJldHVybiBhIC0gYjtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1RpbWVTY2FsZX0gc2NhbGVcbiAqIEBwYXJhbSB7Kn0gaW5wdXRcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZnVuY3Rpb24gcGFyc2Uoc2NhbGUsIGlucHV0KSB7XG4gIGlmIChpc051bGxPclVuZGVmKGlucHV0KSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgYWRhcHRlciA9IHNjYWxlLl9hZGFwdGVyO1xuICBjb25zdCB7cGFyc2VyLCByb3VuZCwgaXNvV2Vla2RheX0gPSBzY2FsZS5fcGFyc2VPcHRzO1xuICBsZXQgdmFsdWUgPSBpbnB1dDtcblxuICBpZiAodHlwZW9mIHBhcnNlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHZhbHVlID0gcGFyc2VyKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE9ubHkgcGFyc2UgaWYgaXQncyBub3QgYSB0aW1lc3RhbXAgYWxyZWFkeVxuICBpZiAoIWlzRmluaXRlKHZhbHVlKSkge1xuICAgIHZhbHVlID0gdHlwZW9mIHBhcnNlciA9PT0gJ3N0cmluZydcbiAgICAgID8gYWRhcHRlci5wYXJzZSh2YWx1ZSwgLyoqIEB0eXBlIHtVbml0fSAqLyAocGFyc2VyKSlcbiAgICAgIDogYWRhcHRlci5wYXJzZSh2YWx1ZSk7XG4gIH1cblxuICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChyb3VuZCkge1xuICAgIHZhbHVlID0gcm91bmQgPT09ICd3ZWVrJyAmJiAoaXNOdW1iZXIoaXNvV2Vla2RheSkgfHwgaXNvV2Vla2RheSA9PT0gdHJ1ZSlcbiAgICAgID8gYWRhcHRlci5zdGFydE9mKHZhbHVlLCAnaXNvV2VlaycsIGlzb1dlZWtkYXkpXG4gICAgICA6IGFkYXB0ZXIuc3RhcnRPZih2YWx1ZSwgcm91bmQpO1xuICB9XG5cbiAgcmV0dXJuICt2YWx1ZTtcbn1cblxuLyoqXG4gKiBGaWd1cmVzIG91dCB3aGF0IHVuaXQgcmVzdWx0cyBpbiBhbiBhcHByb3ByaWF0ZSBudW1iZXIgb2YgYXV0by1nZW5lcmF0ZWQgdGlja3NcbiAqIEBwYXJhbSB7VW5pdH0gbWluVW5pdFxuICogQHBhcmFtIHtudW1iZXJ9IG1pblxuICogQHBhcmFtIHtudW1iZXJ9IG1heFxuICogQHBhcmFtIHtudW1iZXJ9IGNhcGFjaXR5XG4gKiBAcmV0dXJuIHtvYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGRldGVybWluZVVuaXRGb3JBdXRvVGlja3MobWluVW5pdCwgbWluLCBtYXgsIGNhcGFjaXR5KSB7XG4gIGNvbnN0IGlsZW4gPSBVTklUUy5sZW5ndGg7XG5cbiAgZm9yIChsZXQgaSA9IFVOSVRTLmluZGV4T2YobWluVW5pdCk7IGkgPCBpbGVuIC0gMTsgKytpKSB7XG4gICAgY29uc3QgaW50ZXJ2YWwgPSBJTlRFUlZBTFNbVU5JVFNbaV1dO1xuICAgIGNvbnN0IGZhY3RvciA9IGludGVydmFsLnN0ZXBzID8gaW50ZXJ2YWwuc3RlcHMgOiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcblxuICAgIGlmIChpbnRlcnZhbC5jb21tb24gJiYgTWF0aC5jZWlsKChtYXggLSBtaW4pIC8gKGZhY3RvciAqIGludGVydmFsLnNpemUpKSA8PSBjYXBhY2l0eSkge1xuICAgICAgcmV0dXJuIFVOSVRTW2ldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBVTklUU1tpbGVuIC0gMV07XG59XG5cbi8qKlxuICogRmlndXJlcyBvdXQgd2hhdCB1bml0IHRvIGZvcm1hdCBhIHNldCBvZiB0aWNrcyB3aXRoXG4gKiBAcGFyYW0ge1RpbWVTY2FsZX0gc2NhbGVcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW1UaWNrc1xuICogQHBhcmFtIHtVbml0fSBtaW5Vbml0XG4gKiBAcGFyYW0ge251bWJlcn0gbWluXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4XG4gKiBAcmV0dXJuIHtVbml0fVxuICovXG5mdW5jdGlvbiBkZXRlcm1pbmVVbml0Rm9yRm9ybWF0dGluZyhzY2FsZSwgbnVtVGlja3MsIG1pblVuaXQsIG1pbiwgbWF4KSB7XG4gIGZvciAobGV0IGkgPSBVTklUUy5sZW5ndGggLSAxOyBpID49IFVOSVRTLmluZGV4T2YobWluVW5pdCk7IGktLSkge1xuICAgIGNvbnN0IHVuaXQgPSBVTklUU1tpXTtcbiAgICBpZiAoSU5URVJWQUxTW3VuaXRdLmNvbW1vbiAmJiBzY2FsZS5fYWRhcHRlci5kaWZmKG1heCwgbWluLCB1bml0KSA+PSBudW1UaWNrcyAtIDEpIHtcbiAgICAgIHJldHVybiB1bml0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBVTklUU1ttaW5Vbml0ID8gVU5JVFMuaW5kZXhPZihtaW5Vbml0KSA6IDBdO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7VW5pdH0gdW5pdFxuICogQHJldHVybiB7b2JqZWN0fVxuICovXG5mdW5jdGlvbiBkZXRlcm1pbmVNYWpvclVuaXQodW5pdCkge1xuICBmb3IgKGxldCBpID0gVU5JVFMuaW5kZXhPZih1bml0KSArIDEsIGlsZW4gPSBVTklUUy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBpZiAoSU5URVJWQUxTW1VOSVRTW2ldXS5jb21tb24pIHtcbiAgICAgIHJldHVybiBVTklUU1tpXTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gdGlja3NcbiAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lXG4gKiBAcGFyYW0ge251bWJlcltdfSBbdGltZXN0YW1wc10gLSBpZiBkZWZpbmVkLCBzbmFwIHRvIHRoZXNlIHRpbWVzdGFtcHNcbiAqL1xuZnVuY3Rpb24gYWRkVGljayh0aWNrcywgdGltZSwgdGltZXN0YW1wcykge1xuICBpZiAoIXRpbWVzdGFtcHMpIHtcbiAgICB0aWNrc1t0aW1lXSA9IHRydWU7XG4gIH0gZWxzZSBpZiAodGltZXN0YW1wcy5sZW5ndGgpIHtcbiAgICBjb25zdCB7bG8sIGhpfSA9IF9sb29rdXAodGltZXN0YW1wcywgdGltZSk7XG4gICAgY29uc3QgdGltZXN0YW1wID0gdGltZXN0YW1wc1tsb10gPj0gdGltZSA/IHRpbWVzdGFtcHNbbG9dIDogdGltZXN0YW1wc1toaV07XG4gICAgdGlja3NbdGltZXN0YW1wXSA9IHRydWU7XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1RpbWVTY2FsZX0gc2NhbGVcbiAqIEBwYXJhbSB7b2JqZWN0W119IHRpY2tzXG4gKiBAcGFyYW0ge29iamVjdH0gbWFwXG4gKiBAcGFyYW0ge1VuaXR9IG1ham9yVW5pdFxuICogQHJldHVybiB7b2JqZWN0W119XG4gKi9cbmZ1bmN0aW9uIHNldE1ham9yVGlja3Moc2NhbGUsIHRpY2tzLCBtYXAsIG1ham9yVW5pdCkge1xuICBjb25zdCBhZGFwdGVyID0gc2NhbGUuX2FkYXB0ZXI7XG4gIGNvbnN0IGZpcnN0ID0gK2FkYXB0ZXIuc3RhcnRPZih0aWNrc1swXS52YWx1ZSwgbWFqb3JVbml0KTtcbiAgY29uc3QgbGFzdCA9IHRpY2tzW3RpY2tzLmxlbmd0aCAtIDFdLnZhbHVlO1xuICBsZXQgbWFqb3IsIGluZGV4O1xuXG4gIGZvciAobWFqb3IgPSBmaXJzdDsgbWFqb3IgPD0gbGFzdDsgbWFqb3IgPSArYWRhcHRlci5hZGQobWFqb3IsIDEsIG1ham9yVW5pdCkpIHtcbiAgICBpbmRleCA9IG1hcFttYWpvcl07XG4gICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgIHRpY2tzW2luZGV4XS5tYWpvciA9IHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aWNrcztcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1RpbWVTY2FsZX0gc2NhbGVcbiAqIEBwYXJhbSB7bnVtYmVyW119IHZhbHVlc1xuICogQHBhcmFtIHtVbml0fHVuZGVmaW5lZH0gW21ham9yVW5pdF1cbiAqIEByZXR1cm4ge29iamVjdFtdfVxuICovXG5mdW5jdGlvbiB0aWNrc0Zyb21UaW1lc3RhbXBzKHNjYWxlLCB2YWx1ZXMsIG1ham9yVW5pdCkge1xuICBjb25zdCB0aWNrcyA9IFtdO1xuICAvKiogQHR5cGUge09iamVjdDxudW1iZXIsb2JqZWN0Pn0gKi9cbiAgY29uc3QgbWFwID0ge307XG4gIGNvbnN0IGlsZW4gPSB2YWx1ZXMubGVuZ3RoO1xuICBsZXQgaSwgdmFsdWU7XG5cbiAgZm9yIChpID0gMDsgaSA8IGlsZW47ICsraSkge1xuICAgIHZhbHVlID0gdmFsdWVzW2ldO1xuICAgIG1hcFt2YWx1ZV0gPSBpO1xuXG4gICAgdGlja3MucHVzaCh7XG4gICAgICB2YWx1ZSxcbiAgICAgIG1ham9yOiBmYWxzZVxuICAgIH0pO1xuICB9XG5cbiAgLy8gV2Ugc2V0IHRoZSBtYWpvciB0aWNrcyBzZXBhcmF0ZWx5IGZyb20gdGhlIGFib3ZlIGxvb3AgYmVjYXVzZSBjYWxsaW5nIHN0YXJ0T2YgZm9yIGV2ZXJ5IHRpY2tcbiAgLy8gaXMgZXhwZW5zaXZlIHdoZW4gdGhlcmUgaXMgYSBsYXJnZSBudW1iZXIgb2YgdGlja3NcbiAgcmV0dXJuIChpbGVuID09PSAwIHx8ICFtYWpvclVuaXQpID8gdGlja3MgOiBzZXRNYWpvclRpY2tzKHNjYWxlLCB0aWNrcywgbWFwLCBtYWpvclVuaXQpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaW1lU2NhbGUgZXh0ZW5kcyBTY2FsZSB7XG5cbiAgc3RhdGljIGlkID0gJ3RpbWUnO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIC8qKlxuICAgICAqIFNjYWxlIGJvdW5kYXJ5IHN0cmF0ZWd5IChieXBhc3NlZCBieSBtaW4vbWF4IHRpbWUgb3B0aW9ucylcbiAgICAgKiAtIGBkYXRhYDogbWFrZSBzdXJlIGRhdGEgYXJlIGZ1bGx5IHZpc2libGUsIHRpY2tzIG91dHNpZGUgYXJlIHJlbW92ZWRcbiAgICAgKiAtIGB0aWNrc2A6IG1ha2Ugc3VyZSB0aWNrcyBhcmUgZnVsbHkgdmlzaWJsZSwgZGF0YSBvdXRzaWRlIGFyZSB0cnVuY2F0ZWRcbiAgICAgKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL3B1bGwvNDU1NlxuICAgICAqIEBzaW5jZSAyLjcuMFxuICAgICAqL1xuICAgIGJvdW5kczogJ2RhdGEnLFxuXG4gICAgYWRhcHRlcnM6IHt9LFxuICAgIHRpbWU6IHtcbiAgICAgIHBhcnNlcjogZmFsc2UsIC8vIGZhbHNlID09IGEgcGF0dGVybiBzdHJpbmcgZnJvbSBvciBhIGN1c3RvbSBjYWxsYmFjayB0aGF0IGNvbnZlcnRzIGl0cyBhcmd1bWVudCB0byBhIHRpbWVzdGFtcFxuICAgICAgdW5pdDogZmFsc2UsIC8vIGZhbHNlID09IGF1dG9tYXRpYyBvciBvdmVycmlkZSB3aXRoIHdlZWssIG1vbnRoLCB5ZWFyLCBldGMuXG4gICAgICByb3VuZDogZmFsc2UsIC8vIG5vbmUsIG9yIG92ZXJyaWRlIHdpdGggd2VlaywgbW9udGgsIHllYXIsIGV0Yy5cbiAgICAgIGlzb1dlZWtkYXk6IGZhbHNlLCAvLyBvdmVycmlkZSB3ZWVrIHN0YXJ0IGRheVxuICAgICAgbWluVW5pdDogJ21pbGxpc2Vjb25kJyxcbiAgICAgIGRpc3BsYXlGb3JtYXRzOiB7fVxuICAgIH0sXG4gICAgdGlja3M6IHtcbiAgICAgIC8qKlxuICAgICAgICogVGlja3MgZ2VuZXJhdGlvbiBpbnB1dCB2YWx1ZXM6XG4gICAgICAgKiAtICdhdXRvJzogZ2VuZXJhdGVzIFwib3B0aW1hbFwiIHRpY2tzIGJhc2VkIG9uIHNjYWxlIHNpemUgYW5kIHRpbWUgb3B0aW9ucy5cbiAgICAgICAqIC0gJ2RhdGEnOiBnZW5lcmF0ZXMgdGlja3MgZnJvbSBkYXRhIChpbmNsdWRpbmcgbGFiZWxzIGZyb20gZGF0YSB7dHx4fHl9IG9iamVjdHMpLlxuICAgICAgICogLSAnbGFiZWxzJzogZ2VuZXJhdGVzIHRpY2tzIGZyb20gdXNlciBnaXZlbiBgZGF0YS5sYWJlbHNgIHZhbHVlcyBPTkxZLlxuICAgICAgICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9wdWxsLzQ1MDdcbiAgICAgICAqIEBzaW5jZSAyLjcuMFxuICAgICAgICovXG4gICAgICBzb3VyY2U6ICdhdXRvJyxcblxuICAgICAgY2FsbGJhY2s6IGZhbHNlLFxuXG4gICAgICBtYWpvcjoge1xuICAgICAgICBlbmFibGVkOiBmYWxzZVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcblx0ICogQHBhcmFtIHtvYmplY3R9IHByb3BzXG5cdCAqL1xuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcblxuICAgIC8qKiBAdHlwZSB7e2RhdGE6IG51bWJlcltdLCBsYWJlbHM6IG51bWJlcltdLCBhbGw6IG51bWJlcltdfX0gKi9cbiAgICB0aGlzLl9jYWNoZSA9IHtcbiAgICAgIGRhdGE6IFtdLFxuICAgICAgbGFiZWxzOiBbXSxcbiAgICAgIGFsbDogW11cbiAgICB9O1xuXG4gICAgLyoqIEB0eXBlIHtVbml0fSAqL1xuICAgIHRoaXMuX3VuaXQgPSAnZGF5JztcbiAgICAvKiogQHR5cGUge1VuaXQ9fSAqL1xuICAgIHRoaXMuX21ham9yVW5pdCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9vZmZzZXRzID0ge307XG4gICAgdGhpcy5fbm9ybWFsaXplZCA9IGZhbHNlO1xuICAgIHRoaXMuX3BhcnNlT3B0cyA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGluaXQoc2NhbGVPcHRzLCBvcHRzID0ge30pIHtcbiAgICBjb25zdCB0aW1lID0gc2NhbGVPcHRzLnRpbWUgfHwgKHNjYWxlT3B0cy50aW1lID0ge30pO1xuICAgIC8qKiBAdHlwZSB7RGF0ZUFkYXB0ZXJ9ICovXG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMuX2FkYXB0ZXIgPSBuZXcgYWRhcHRlcnMuX2RhdGUoc2NhbGVPcHRzLmFkYXB0ZXJzLmRhdGUpO1xuXG4gICAgYWRhcHRlci5pbml0KG9wdHMpO1xuXG4gICAgLy8gQmFja3dhcmQgY29tcGF0aWJpbGl0eTogYmVmb3JlIGludHJvZHVjaW5nIGFkYXB0ZXIsIGBkaXNwbGF5Rm9ybWF0c2Agd2FzXG4gICAgLy8gc3VwcG9zZWQgdG8gY29udGFpbiAqYWxsKiB1bml0L3N0cmluZyBwYWlycyBidXQgdGhpcyBjYW4ndCBiZSByZXNvbHZlZFxuICAgIC8vIHdoZW4gbG9hZGluZyB0aGUgc2NhbGUgKGFkYXB0ZXJzIGFyZSBsb2FkZWQgYWZ0ZXJ3YXJkKSwgc28gbGV0J3MgcG9wdWxhdGVcbiAgICAvLyBtaXNzaW5nIGZvcm1hdHMgb24gdXBkYXRlXG4gICAgbWVyZ2VJZih0aW1lLmRpc3BsYXlGb3JtYXRzLCBhZGFwdGVyLmZvcm1hdHMoKSk7XG5cbiAgICB0aGlzLl9wYXJzZU9wdHMgPSB7XG4gICAgICBwYXJzZXI6IHRpbWUucGFyc2VyLFxuICAgICAgcm91bmQ6IHRpbWUucm91bmQsXG4gICAgICBpc29XZWVrZGF5OiB0aW1lLmlzb1dlZWtkYXlcbiAgICB9O1xuXG4gICAgc3VwZXIuaW5pdChzY2FsZU9wdHMpO1xuXG4gICAgdGhpcy5fbm9ybWFsaXplZCA9IG9wdHMubm9ybWFsaXplZDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0geyp9IHJhd1xuXHQgKiBAcGFyYW0ge251bWJlcj99IFtpbmRleF1cblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgcGFyc2UocmF3LCBpbmRleCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlKHRoaXMsIHJhdyk7XG4gIH1cblxuICBiZWZvcmVMYXlvdXQoKSB7XG4gICAgc3VwZXIuYmVmb3JlTGF5b3V0KCk7XG4gICAgdGhpcy5fY2FjaGUgPSB7XG4gICAgICBkYXRhOiBbXSxcbiAgICAgIGxhYmVsczogW10sXG4gICAgICBhbGw6IFtdXG4gICAgfTtcbiAgfVxuXG4gIGRldGVybWluZURhdGFMaW1pdHMoKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5fYWRhcHRlcjtcbiAgICBjb25zdCB1bml0ID0gb3B0aW9ucy50aW1lLnVuaXQgfHwgJ2RheSc7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICAgIGxldCB7bWluLCBtYXgsIG1pbkRlZmluZWQsIG1heERlZmluZWR9ID0gdGhpcy5nZXRVc2VyQm91bmRzKCk7XG5cbiAgICAvKipcblx0XHQgKiBAcGFyYW0ge29iamVjdH0gYm91bmRzXG5cdFx0ICovXG4gICAgZnVuY3Rpb24gX2FwcGx5Qm91bmRzKGJvdW5kcykge1xuICAgICAgaWYgKCFtaW5EZWZpbmVkICYmICFpc05hTihib3VuZHMubWluKSkge1xuICAgICAgICBtaW4gPSBNYXRoLm1pbihtaW4sIGJvdW5kcy5taW4pO1xuICAgICAgfVxuICAgICAgaWYgKCFtYXhEZWZpbmVkICYmICFpc05hTihib3VuZHMubWF4KSkge1xuICAgICAgICBtYXggPSBNYXRoLm1heChtYXgsIGJvdW5kcy5tYXgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIHdlIGhhdmUgdXNlciBwcm92aWRlZCBgbWluYCBhbmQgYG1heGAgbGFiZWxzIC8gZGF0YSBib3VuZHMgY2FuIGJlIGlnbm9yZWRcbiAgICBpZiAoIW1pbkRlZmluZWQgfHwgIW1heERlZmluZWQpIHtcbiAgICAgIC8vIExhYmVscyBhcmUgYWx3YXlzIGNvbnNpZGVyZWQsIHdoZW4gdXNlciBkaWQgbm90IGZvcmNlIGJvdW5kc1xuICAgICAgX2FwcGx5Qm91bmRzKHRoaXMuX2dldExhYmVsQm91bmRzKCkpO1xuXG4gICAgICAvLyBJZiBgYm91bmRzYCBpcyBgJ3RpY2tzJ2AgYW5kIGB0aWNrcy5zb3VyY2VgIGlzIGAnbGFiZWxzJ2AsXG4gICAgICAvLyBkYXRhIGJvdW5kcyBhcmUgaWdub3JlZCAoYW5kIGRvbid0IG5lZWQgdG8gYmUgZGV0ZXJtaW5lZClcbiAgICAgIGlmIChvcHRpb25zLmJvdW5kcyAhPT0gJ3RpY2tzJyB8fCBvcHRpb25zLnRpY2tzLnNvdXJjZSAhPT0gJ2xhYmVscycpIHtcbiAgICAgICAgX2FwcGx5Qm91bmRzKHRoaXMuZ2V0TWluTWF4KGZhbHNlKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbWluID0gaXNGaW5pdGUobWluKSAmJiAhaXNOYU4obWluKSA/IG1pbiA6ICthZGFwdGVyLnN0YXJ0T2YoRGF0ZS5ub3coKSwgdW5pdCk7XG4gICAgbWF4ID0gaXNGaW5pdGUobWF4KSAmJiAhaXNOYU4obWF4KSA/IG1heCA6ICthZGFwdGVyLmVuZE9mKERhdGUubm93KCksIHVuaXQpICsgMTtcblxuICAgIC8vIE1ha2Ugc3VyZSB0aGF0IG1heCBpcyBzdHJpY3RseSBoaWdoZXIgdGhhbiBtaW4gKHJlcXVpcmVkIGJ5IHRoZSB0aW1lc2VyaWVzIGxvb2t1cCB0YWJsZSlcbiAgICB0aGlzLm1pbiA9IE1hdGgubWluKG1pbiwgbWF4IC0gMSk7XG4gICAgdGhpcy5tYXggPSBNYXRoLm1heChtaW4gKyAxLCBtYXgpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0TGFiZWxCb3VuZHMoKSB7XG4gICAgY29uc3QgYXJyID0gdGhpcy5nZXRMYWJlbFRpbWVzdGFtcHMoKTtcbiAgICBsZXQgbWluID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgIGxldCBtYXggPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XG5cbiAgICBpZiAoYXJyLmxlbmd0aCkge1xuICAgICAgbWluID0gYXJyWzBdO1xuICAgICAgbWF4ID0gYXJyW2Fyci5sZW5ndGggLSAxXTtcbiAgICB9XG4gICAgcmV0dXJuIHttaW4sIG1heH07XG4gIH1cblxuICAvKipcblx0ICogQHJldHVybiB7b2JqZWN0W119XG5cdCAqL1xuICBidWlsZFRpY2tzKCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgdGltZU9wdHMgPSBvcHRpb25zLnRpbWU7XG4gICAgY29uc3QgdGlja09wdHMgPSBvcHRpb25zLnRpY2tzO1xuICAgIGNvbnN0IHRpbWVzdGFtcHMgPSB0aWNrT3B0cy5zb3VyY2UgPT09ICdsYWJlbHMnID8gdGhpcy5nZXRMYWJlbFRpbWVzdGFtcHMoKSA6IHRoaXMuX2dlbmVyYXRlKCk7XG5cbiAgICBpZiAob3B0aW9ucy5ib3VuZHMgPT09ICd0aWNrcycgJiYgdGltZXN0YW1wcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMubWluID0gdGhpcy5fdXNlck1pbiB8fCB0aW1lc3RhbXBzWzBdO1xuICAgICAgdGhpcy5tYXggPSB0aGlzLl91c2VyTWF4IHx8IHRpbWVzdGFtcHNbdGltZXN0YW1wcy5sZW5ndGggLSAxXTtcbiAgICB9XG5cbiAgICBjb25zdCBtaW4gPSB0aGlzLm1pbjtcbiAgICBjb25zdCBtYXggPSB0aGlzLm1heDtcblxuICAgIGNvbnN0IHRpY2tzID0gX2ZpbHRlckJldHdlZW4odGltZXN0YW1wcywgbWluLCBtYXgpO1xuXG4gICAgLy8gUFJJVkFURVxuICAgIC8vIGRldGVybWluZVVuaXRGb3JGb3JtYXR0aW5nIHJlbGllcyBvbiB0aGUgbnVtYmVyIG9mIHRpY2tzIHNvIHdlIGRvbid0IHVzZSBpdCB3aGVuXG4gICAgLy8gYXV0b1NraXAgaXMgZW5hYmxlZCBiZWNhdXNlIHdlIGRvbid0IHlldCBrbm93IHdoYXQgdGhlIGZpbmFsIG51bWJlciBvZiB0aWNrcyB3aWxsIGJlXG4gICAgdGhpcy5fdW5pdCA9IHRpbWVPcHRzLnVuaXQgfHwgKHRpY2tPcHRzLmF1dG9Ta2lwXG4gICAgICA/IGRldGVybWluZVVuaXRGb3JBdXRvVGlja3ModGltZU9wdHMubWluVW5pdCwgdGhpcy5taW4sIHRoaXMubWF4LCB0aGlzLl9nZXRMYWJlbENhcGFjaXR5KG1pbikpXG4gICAgICA6IGRldGVybWluZVVuaXRGb3JGb3JtYXR0aW5nKHRoaXMsIHRpY2tzLmxlbmd0aCwgdGltZU9wdHMubWluVW5pdCwgdGhpcy5taW4sIHRoaXMubWF4KSk7XG4gICAgdGhpcy5fbWFqb3JVbml0ID0gIXRpY2tPcHRzLm1ham9yLmVuYWJsZWQgfHwgdGhpcy5fdW5pdCA9PT0gJ3llYXInID8gdW5kZWZpbmVkXG4gICAgICA6IGRldGVybWluZU1ham9yVW5pdCh0aGlzLl91bml0KTtcbiAgICB0aGlzLmluaXRPZmZzZXRzKHRpbWVzdGFtcHMpO1xuXG4gICAgaWYgKG9wdGlvbnMucmV2ZXJzZSkge1xuICAgICAgdGlja3MucmV2ZXJzZSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aWNrc0Zyb21UaW1lc3RhbXBzKHRoaXMsIHRpY2tzLCB0aGlzLl9tYWpvclVuaXQpO1xuICB9XG5cbiAgYWZ0ZXJBdXRvU2tpcCgpIHtcbiAgICAvLyBPZmZzZXRzIGZvciBiYXIgY2hhcnRzIG5lZWQgdG8gYmUgaGFuZGxlZCB3aXRoIHRoZSBhdXRvIHNraXBwZWRcbiAgICAvLyB0aWNrcy4gT25jZSB0aWNrcyBoYXZlIGJlZW4gc2tpcHBlZCwgd2UgcmUtY29tcHV0ZSB0aGUgb2Zmc2V0cy5cbiAgICBpZiAodGhpcy5vcHRpb25zLm9mZnNldEFmdGVyQXV0b3NraXApIHtcbiAgICAgIHRoaXMuaW5pdE9mZnNldHModGhpcy50aWNrcy5tYXAodGljayA9PiArdGljay52YWx1ZSkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBzdGFydCBhbmQgZW5kIG9mZnNldHMgZnJvbSBlZGdlcyBpbiB0aGUgZm9ybSBvZiB7c3RhcnQsIGVuZH1cblx0ICogd2hlcmUgZWFjaCB2YWx1ZSBpcyBhIHJlbGF0aXZlIHdpZHRoIHRvIHRoZSBzY2FsZSBhbmQgcmFuZ2VzIGJldHdlZW4gMCBhbmQgMS5cblx0ICogVGhleSBhZGQgZXh0cmEgbWFyZ2lucyBvbiB0aGUgYm90aCBzaWRlcyBieSBzY2FsaW5nIGRvd24gdGhlIG9yaWdpbmFsIHNjYWxlLlxuXHQgKiBPZmZzZXRzIGFyZSBhZGRlZCB3aGVuIHRoZSBgb2Zmc2V0YCBvcHRpb24gaXMgdHJ1ZS5cblx0ICogQHBhcmFtIHtudW1iZXJbXX0gdGltZXN0YW1wc1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBpbml0T2Zmc2V0cyh0aW1lc3RhbXBzID0gW10pIHtcbiAgICBsZXQgc3RhcnQgPSAwO1xuICAgIGxldCBlbmQgPSAwO1xuICAgIGxldCBmaXJzdCwgbGFzdDtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMub2Zmc2V0ICYmIHRpbWVzdGFtcHMubGVuZ3RoKSB7XG4gICAgICBmaXJzdCA9IHRoaXMuZ2V0RGVjaW1hbEZvclZhbHVlKHRpbWVzdGFtcHNbMF0pO1xuICAgICAgaWYgKHRpbWVzdGFtcHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHN0YXJ0ID0gMSAtIGZpcnN0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhcnQgPSAodGhpcy5nZXREZWNpbWFsRm9yVmFsdWUodGltZXN0YW1wc1sxXSkgLSBmaXJzdCkgLyAyO1xuICAgICAgfVxuICAgICAgbGFzdCA9IHRoaXMuZ2V0RGVjaW1hbEZvclZhbHVlKHRpbWVzdGFtcHNbdGltZXN0YW1wcy5sZW5ndGggLSAxXSk7XG4gICAgICBpZiAodGltZXN0YW1wcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgZW5kID0gbGFzdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVuZCA9IChsYXN0IC0gdGhpcy5nZXREZWNpbWFsRm9yVmFsdWUodGltZXN0YW1wc1t0aW1lc3RhbXBzLmxlbmd0aCAtIDJdKSkgLyAyO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBsaW1pdCA9IHRpbWVzdGFtcHMubGVuZ3RoIDwgMyA/IDAuNSA6IDAuMjU7XG4gICAgc3RhcnQgPSBfbGltaXRWYWx1ZShzdGFydCwgMCwgbGltaXQpO1xuICAgIGVuZCA9IF9saW1pdFZhbHVlKGVuZCwgMCwgbGltaXQpO1xuXG4gICAgdGhpcy5fb2Zmc2V0cyA9IHtzdGFydCwgZW5kLCBmYWN0b3I6IDEgLyAoc3RhcnQgKyAxICsgZW5kKX07XG4gIH1cblxuICAvKipcblx0ICogR2VuZXJhdGVzIGEgbWF4aW11bSBvZiBgY2FwYWNpdHlgIHRpbWVzdGFtcHMgYmV0d2VlbiBtaW4gYW5kIG1heCwgcm91bmRlZCB0byB0aGVcblx0ICogYG1pbm9yYCB1bml0IHVzaW5nIHRoZSBnaXZlbiBzY2FsZSB0aW1lIGBvcHRpb25zYC5cblx0ICogSW1wb3J0YW50OiB0aGlzIG1ldGhvZCBjYW4gcmV0dXJuIHRpY2tzIG91dHNpZGUgdGhlIG1pbiBhbmQgbWF4IHJhbmdlLCBpdCdzIHRoZVxuXHQgKiByZXNwb25zaWJpbGl0eSBvZiB0aGUgY2FsbGluZyBjb2RlIHRvIGNsYW1wIHZhbHVlcyBpZiBuZWVkZWQuXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIF9nZW5lcmF0ZSgpIHtcbiAgICBjb25zdCBhZGFwdGVyID0gdGhpcy5fYWRhcHRlcjtcbiAgICBjb25zdCBtaW4gPSB0aGlzLm1pbjtcbiAgICBjb25zdCBtYXggPSB0aGlzLm1heDtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHRpbWVPcHRzID0gb3B0aW9ucy50aW1lO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBjb25zdCBtaW5vciA9IHRpbWVPcHRzLnVuaXQgfHwgZGV0ZXJtaW5lVW5pdEZvckF1dG9UaWNrcyh0aW1lT3B0cy5taW5Vbml0LCBtaW4sIG1heCwgdGhpcy5fZ2V0TGFiZWxDYXBhY2l0eShtaW4pKTtcbiAgICBjb25zdCBzdGVwU2l6ZSA9IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMudGlja3Muc3RlcFNpemUsIDEpO1xuICAgIGNvbnN0IHdlZWtkYXkgPSBtaW5vciA9PT0gJ3dlZWsnID8gdGltZU9wdHMuaXNvV2Vla2RheSA6IGZhbHNlO1xuICAgIGNvbnN0IGhhc1dlZWtkYXkgPSBpc051bWJlcih3ZWVrZGF5KSB8fCB3ZWVrZGF5ID09PSB0cnVlO1xuICAgIGNvbnN0IHRpY2tzID0ge307XG4gICAgbGV0IGZpcnN0ID0gbWluO1xuICAgIGxldCB0aW1lLCBjb3VudDtcblxuICAgIC8vIEZvciAnd2VlaycgdW5pdCwgaGFuZGxlIHRoZSBmaXJzdCBkYXkgb2Ygd2VlayBvcHRpb25cbiAgICBpZiAoaGFzV2Vla2RheSkge1xuICAgICAgZmlyc3QgPSArYWRhcHRlci5zdGFydE9mKGZpcnN0LCAnaXNvV2VlaycsIHdlZWtkYXkpO1xuICAgIH1cblxuICAgIC8vIEFsaWduIGZpcnN0IHRpY2tzIG9uIHVuaXRcbiAgICBmaXJzdCA9ICthZGFwdGVyLnN0YXJ0T2YoZmlyc3QsIGhhc1dlZWtkYXkgPyAnZGF5JyA6IG1pbm9yKTtcblxuICAgIC8vIFByZXZlbnQgYnJvd3NlciBmcm9tIGZyZWV6aW5nIGluIGNhc2UgdXNlciBvcHRpb25zIHJlcXVlc3QgbWlsbGlvbnMgb2YgbWlsbGlzZWNvbmRzXG4gICAgaWYgKGFkYXB0ZXIuZGlmZihtYXgsIG1pbiwgbWlub3IpID4gMTAwMDAwICogc3RlcFNpemUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihtaW4gKyAnIGFuZCAnICsgbWF4ICsgJyBhcmUgdG9vIGZhciBhcGFydCB3aXRoIHN0ZXBTaXplIG9mICcgKyBzdGVwU2l6ZSArICcgJyArIG1pbm9yKTtcbiAgICB9XG5cbiAgICBjb25zdCB0aW1lc3RhbXBzID0gb3B0aW9ucy50aWNrcy5zb3VyY2UgPT09ICdkYXRhJyAmJiB0aGlzLmdldERhdGFUaW1lc3RhbXBzKCk7XG4gICAgZm9yICh0aW1lID0gZmlyc3QsIGNvdW50ID0gMDsgdGltZSA8IG1heDsgdGltZSA9ICthZGFwdGVyLmFkZCh0aW1lLCBzdGVwU2l6ZSwgbWlub3IpLCBjb3VudCsrKSB7XG4gICAgICBhZGRUaWNrKHRpY2tzLCB0aW1lLCB0aW1lc3RhbXBzKTtcbiAgICB9XG5cbiAgICBpZiAodGltZSA9PT0gbWF4IHx8IG9wdGlvbnMuYm91bmRzID09PSAndGlja3MnIHx8IGNvdW50ID09PSAxKSB7XG4gICAgICBhZGRUaWNrKHRpY2tzLCB0aW1lLCB0aW1lc3RhbXBzKTtcbiAgICB9XG5cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRpY2tzKS5zb3J0KHNvcnRlcikubWFwKHggPT4gK3gpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuICBnZXRMYWJlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMuX2FkYXB0ZXI7XG4gICAgY29uc3QgdGltZU9wdHMgPSB0aGlzLm9wdGlvbnMudGltZTtcblxuICAgIGlmICh0aW1lT3B0cy50b29sdGlwRm9ybWF0KSB7XG4gICAgICByZXR1cm4gYWRhcHRlci5mb3JtYXQodmFsdWUsIHRpbWVPcHRzLnRvb2x0aXBGb3JtYXQpO1xuICAgIH1cbiAgICByZXR1cm4gYWRhcHRlci5mb3JtYXQodmFsdWUsIHRpbWVPcHRzLmRpc3BsYXlGb3JtYXRzLmRhdGV0aW1lKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcblx0ICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBmb3JtYXRcblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cbiAgZm9ybWF0KHZhbHVlLCBmb3JtYXQpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IGZvcm1hdHMgPSBvcHRpb25zLnRpbWUuZGlzcGxheUZvcm1hdHM7XG4gICAgY29uc3QgdW5pdCA9IHRoaXMuX3VuaXQ7XG4gICAgY29uc3QgZm10ID0gZm9ybWF0IHx8IGZvcm1hdHNbdW5pdF07XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0ZXIuZm9ybWF0KHZhbHVlLCBmbXQpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEZ1bmN0aW9uIHRvIGZvcm1hdCBhbiBpbmRpdmlkdWFsIHRpY2sgbWFya1xuXHQgKiBAcGFyYW0ge251bWJlcn0gdGltZVxuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcblx0ICogQHBhcmFtIHtvYmplY3RbXX0gdGlja3Ncblx0ICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBbZm9ybWF0XVxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdGlja0Zvcm1hdEZ1bmN0aW9uKHRpbWUsIGluZGV4LCB0aWNrcywgZm9ybWF0KSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBmb3JtYXR0ZXIgPSBvcHRpb25zLnRpY2tzLmNhbGxiYWNrO1xuXG4gICAgaWYgKGZvcm1hdHRlcikge1xuICAgICAgcmV0dXJuIGNhbGwoZm9ybWF0dGVyLCBbdGltZSwgaW5kZXgsIHRpY2tzXSwgdGhpcyk7XG4gICAgfVxuXG4gICAgY29uc3QgZm9ybWF0cyA9IG9wdGlvbnMudGltZS5kaXNwbGF5Rm9ybWF0cztcbiAgICBjb25zdCB1bml0ID0gdGhpcy5fdW5pdDtcbiAgICBjb25zdCBtYWpvclVuaXQgPSB0aGlzLl9tYWpvclVuaXQ7XG4gICAgY29uc3QgbWlub3JGb3JtYXQgPSB1bml0ICYmIGZvcm1hdHNbdW5pdF07XG4gICAgY29uc3QgbWFqb3JGb3JtYXQgPSBtYWpvclVuaXQgJiYgZm9ybWF0c1ttYWpvclVuaXRdO1xuICAgIGNvbnN0IHRpY2sgPSB0aWNrc1tpbmRleF07XG4gICAgY29uc3QgbWFqb3IgPSBtYWpvclVuaXQgJiYgbWFqb3JGb3JtYXQgJiYgdGljayAmJiB0aWNrLm1ham9yO1xuXG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0ZXIuZm9ybWF0KHRpbWUsIGZvcm1hdCB8fCAobWFqb3IgPyBtYWpvckZvcm1hdCA6IG1pbm9yRm9ybWF0KSk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtvYmplY3RbXX0gdGlja3Ncblx0ICovXG4gIGdlbmVyYXRlVGlja0xhYmVscyh0aWNrcykge1xuICAgIGxldCBpLCBpbGVuLCB0aWNrO1xuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IHRpY2tzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgdGljayA9IHRpY2tzW2ldO1xuICAgICAgdGljay5sYWJlbCA9IHRoaXMuX3RpY2tGb3JtYXRGdW5jdGlvbih0aWNrLnZhbHVlLCBpLCB0aWNrcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSAtIE1pbGxpc2Vjb25kcyBzaW5jZSBlcG9jaCAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuICBnZXREZWNpbWFsRm9yVmFsdWUodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgPyBOYU4gOiAodmFsdWUgLSB0aGlzLm1pbikgLyAodGhpcy5tYXggLSB0aGlzLm1pbik7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gTWlsbGlzZWNvbmRzIHNpbmNlIGVwb2NoICgxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVEMpXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG4gIGdldFBpeGVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICBjb25zdCBvZmZzZXRzID0gdGhpcy5fb2Zmc2V0cztcbiAgICBjb25zdCBwb3MgPSB0aGlzLmdldERlY2ltYWxGb3JWYWx1ZSh2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JEZWNpbWFsKChvZmZzZXRzLnN0YXJ0ICsgcG9zKSAqIG9mZnNldHMuZmFjdG9yKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgZ2V0VmFsdWVGb3JQaXhlbChwaXhlbCkge1xuICAgIGNvbnN0IG9mZnNldHMgPSB0aGlzLl9vZmZzZXRzO1xuICAgIGNvbnN0IHBvcyA9IHRoaXMuZ2V0RGVjaW1hbEZvclBpeGVsKHBpeGVsKSAvIG9mZnNldHMuZmFjdG9yIC0gb2Zmc2V0cy5lbmQ7XG4gICAgcmV0dXJuIHRoaXMubWluICsgcG9zICogKHRoaXMubWF4IC0gdGhpcy5taW4pO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBsYWJlbFxuXHQgKiBAcmV0dXJuIHt7dzpudW1iZXIsIGg6bnVtYmVyfX1cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRMYWJlbFNpemUobGFiZWwpIHtcbiAgICBjb25zdCB0aWNrc09wdHMgPSB0aGlzLm9wdGlvbnMudGlja3M7XG4gICAgY29uc3QgdGlja0xhYmVsV2lkdGggPSB0aGlzLmN0eC5tZWFzdXJlVGV4dChsYWJlbCkud2lkdGg7XG4gICAgY29uc3QgYW5nbGUgPSB0b1JhZGlhbnModGhpcy5pc0hvcml6b250YWwoKSA/IHRpY2tzT3B0cy5tYXhSb3RhdGlvbiA6IHRpY2tzT3B0cy5taW5Sb3RhdGlvbik7XG4gICAgY29uc3QgY29zUm90YXRpb24gPSBNYXRoLmNvcyhhbmdsZSk7XG4gICAgY29uc3Qgc2luUm90YXRpb24gPSBNYXRoLnNpbihhbmdsZSk7XG4gICAgY29uc3QgdGlja0ZvbnRTaXplID0gdGhpcy5fcmVzb2x2ZVRpY2tGb250T3B0aW9ucygwKS5zaXplO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHc6ICh0aWNrTGFiZWxXaWR0aCAqIGNvc1JvdGF0aW9uKSArICh0aWNrRm9udFNpemUgKiBzaW5Sb3RhdGlvbiksXG4gICAgICBoOiAodGlja0xhYmVsV2lkdGggKiBzaW5Sb3RhdGlvbikgKyAodGlja0ZvbnRTaXplICogY29zUm90YXRpb24pXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gZXhhbXBsZVRpbWVcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldExhYmVsQ2FwYWNpdHkoZXhhbXBsZVRpbWUpIHtcbiAgICBjb25zdCB0aW1lT3B0cyA9IHRoaXMub3B0aW9ucy50aW1lO1xuICAgIGNvbnN0IGRpc3BsYXlGb3JtYXRzID0gdGltZU9wdHMuZGlzcGxheUZvcm1hdHM7XG5cbiAgICAvLyBwaWNrIHRoZSBsb25nZXN0IGZvcm1hdCAobWlsbGlzZWNvbmRzKSBmb3IgZ3Vlc3N0aW1hdGlvblxuICAgIGNvbnN0IGZvcm1hdCA9IGRpc3BsYXlGb3JtYXRzW3RpbWVPcHRzLnVuaXRdIHx8IGRpc3BsYXlGb3JtYXRzLm1pbGxpc2Vjb25kO1xuICAgIGNvbnN0IGV4YW1wbGVMYWJlbCA9IHRoaXMuX3RpY2tGb3JtYXRGdW5jdGlvbihleGFtcGxlVGltZSwgMCwgdGlja3NGcm9tVGltZXN0YW1wcyh0aGlzLCBbZXhhbXBsZVRpbWVdLCB0aGlzLl9tYWpvclVuaXQpLCBmb3JtYXQpO1xuICAgIGNvbnN0IHNpemUgPSB0aGlzLl9nZXRMYWJlbFNpemUoZXhhbXBsZUxhYmVsKTtcbiAgICAvLyBzdWJ0cmFjdCAxIC0gaWYgb2Zmc2V0IHRoZW4gdGhlcmUncyBvbmUgbGVzcyBsYWJlbCB0aGFuIHRpY2tcbiAgICAvLyBpZiBub3Qgb2Zmc2V0IHRoZW4gb25lIGhhbGYgbGFiZWwgcGFkZGluZyBpcyBhZGRlZCB0byBlYWNoIGVuZCBsZWF2aW5nIHJvb20gZm9yIG9uZSBsZXNzIGxhYmVsXG4gICAgY29uc3QgY2FwYWNpdHkgPSBNYXRoLmZsb29yKHRoaXMuaXNIb3Jpem9udGFsKCkgPyB0aGlzLndpZHRoIC8gc2l6ZS53IDogdGhpcy5oZWlnaHQgLyBzaXplLmgpIC0gMTtcbiAgICByZXR1cm4gY2FwYWNpdHkgPiAwID8gY2FwYWNpdHkgOiAxO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldERhdGFUaW1lc3RhbXBzKCkge1xuICAgIGxldCB0aW1lc3RhbXBzID0gdGhpcy5fY2FjaGUuZGF0YSB8fCBbXTtcbiAgICBsZXQgaSwgaWxlbjtcblxuICAgIGlmICh0aW1lc3RhbXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRpbWVzdGFtcHM7XG4gICAgfVxuXG4gICAgY29uc3QgbWV0YXMgPSB0aGlzLmdldE1hdGNoaW5nVmlzaWJsZU1ldGFzKCk7XG5cbiAgICBpZiAodGhpcy5fbm9ybWFsaXplZCAmJiBtZXRhcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiAodGhpcy5fY2FjaGUuZGF0YSA9IG1ldGFzWzBdLmNvbnRyb2xsZXIuZ2V0QWxsUGFyc2VkVmFsdWVzKHRoaXMpKTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gbWV0YXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICB0aW1lc3RhbXBzID0gdGltZXN0YW1wcy5jb25jYXQobWV0YXNbaV0uY29udHJvbGxlci5nZXRBbGxQYXJzZWRWYWx1ZXModGhpcykpO1xuICAgIH1cblxuICAgIHJldHVybiAodGhpcy5fY2FjaGUuZGF0YSA9IHRoaXMubm9ybWFsaXplKHRpbWVzdGFtcHMpKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRMYWJlbFRpbWVzdGFtcHMoKSB7XG4gICAgY29uc3QgdGltZXN0YW1wcyA9IHRoaXMuX2NhY2hlLmxhYmVscyB8fCBbXTtcbiAgICBsZXQgaSwgaWxlbjtcblxuICAgIGlmICh0aW1lc3RhbXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRpbWVzdGFtcHM7XG4gICAgfVxuXG4gICAgY29uc3QgbGFiZWxzID0gdGhpcy5nZXRMYWJlbHMoKTtcbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gbGFiZWxzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgdGltZXN0YW1wcy5wdXNoKHBhcnNlKHRoaXMsIGxhYmVsc1tpXSkpO1xuICAgIH1cblxuICAgIHJldHVybiAodGhpcy5fY2FjaGUubGFiZWxzID0gdGhpcy5fbm9ybWFsaXplZCA/IHRpbWVzdGFtcHMgOiB0aGlzLm5vcm1hbGl6ZSh0aW1lc3RhbXBzKSk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJbXX0gdmFsdWVzXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIG5vcm1hbGl6ZSh2YWx1ZXMpIHtcbiAgICAvLyBJdCBzZWVtcyB0byBiZSBzb21ld2hhdCBmYXN0ZXIgdG8gZG8gc29ydGluZyBmaXJzdFxuICAgIHJldHVybiBfYXJyYXlVbmlxdWUodmFsdWVzLnNvcnQoc29ydGVyKSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgVGltZVNjYWxlIGZyb20gJy4vc2NhbGUudGltZS5qcyc7XG5pbXBvcnQge19sb29rdXBCeUtleX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvbGxlY3Rpb24uanMnO1xuXG4vKipcbiAqIExpbmVhcmx5IGludGVycG9sYXRlcyB0aGUgZ2l2ZW4gc291cmNlIGB2YWxgIHVzaW5nIHRoZSB0YWJsZS4gSWYgdmFsdWUgaXMgb3V0IG9mIGJvdW5kcywgdmFsdWVzXG4gKiBhdCBlZGdlcyBhcmUgdXNlZCBmb3IgdGhlIGludGVycG9sYXRpb24uXG4gKiBAcGFyYW0ge29iamVjdH0gdGFibGVcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWxcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldmVyc2VdIGxvb2t1cCB0aW1lIGJhc2VkIG9uIHBvc2l0aW9uIGluc3RlYWQgb2YgdmljZSB2ZXJzYVxuICogQHJldHVybiB7b2JqZWN0fVxuICovXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZSh0YWJsZSwgdmFsLCByZXZlcnNlKSB7XG4gIGxldCBsbyA9IDA7XG4gIGxldCBoaSA9IHRhYmxlLmxlbmd0aCAtIDE7XG4gIGxldCBwcmV2U291cmNlLCBuZXh0U291cmNlLCBwcmV2VGFyZ2V0LCBuZXh0VGFyZ2V0O1xuICBpZiAocmV2ZXJzZSkge1xuICAgIGlmICh2YWwgPj0gdGFibGVbbG9dLnBvcyAmJiB2YWwgPD0gdGFibGVbaGldLnBvcykge1xuICAgICAgKHtsbywgaGl9ID0gX2xvb2t1cEJ5S2V5KHRhYmxlLCAncG9zJywgdmFsKSk7XG4gICAgfVxuICAgICh7cG9zOiBwcmV2U291cmNlLCB0aW1lOiBwcmV2VGFyZ2V0fSA9IHRhYmxlW2xvXSk7XG4gICAgKHtwb3M6IG5leHRTb3VyY2UsIHRpbWU6IG5leHRUYXJnZXR9ID0gdGFibGVbaGldKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAodmFsID49IHRhYmxlW2xvXS50aW1lICYmIHZhbCA8PSB0YWJsZVtoaV0udGltZSkge1xuICAgICAgKHtsbywgaGl9ID0gX2xvb2t1cEJ5S2V5KHRhYmxlLCAndGltZScsIHZhbCkpO1xuICAgIH1cbiAgICAoe3RpbWU6IHByZXZTb3VyY2UsIHBvczogcHJldlRhcmdldH0gPSB0YWJsZVtsb10pO1xuICAgICh7dGltZTogbmV4dFNvdXJjZSwgcG9zOiBuZXh0VGFyZ2V0fSA9IHRhYmxlW2hpXSk7XG4gIH1cblxuICBjb25zdCBzcGFuID0gbmV4dFNvdXJjZSAtIHByZXZTb3VyY2U7XG4gIHJldHVybiBzcGFuID8gcHJldlRhcmdldCArIChuZXh0VGFyZ2V0IC0gcHJldlRhcmdldCkgKiAodmFsIC0gcHJldlNvdXJjZSkgLyBzcGFuIDogcHJldlRhcmdldDtcbn1cblxuY2xhc3MgVGltZVNlcmllc1NjYWxlIGV4dGVuZHMgVGltZVNjYWxlIHtcblxuICBzdGF0aWMgaWQgPSAndGltZXNlcmllcyc7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSBUaW1lU2NhbGUuZGVmYXVsdHM7XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBwcm9wc1xuXHQgKi9cbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG5cbiAgICAvKiogQHR5cGUge29iamVjdFtdfSAqL1xuICAgIHRoaXMuX3RhYmxlID0gW107XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5fbWluUG9zID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuX3RhYmxlUmFuZ2UgPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgaW5pdE9mZnNldHMoKSB7XG4gICAgY29uc3QgdGltZXN0YW1wcyA9IHRoaXMuX2dldFRpbWVzdGFtcHNGb3JUYWJsZSgpO1xuICAgIGNvbnN0IHRhYmxlID0gdGhpcy5fdGFibGUgPSB0aGlzLmJ1aWxkTG9va3VwVGFibGUodGltZXN0YW1wcyk7XG4gICAgdGhpcy5fbWluUG9zID0gaW50ZXJwb2xhdGUodGFibGUsIHRoaXMubWluKTtcbiAgICB0aGlzLl90YWJsZVJhbmdlID0gaW50ZXJwb2xhdGUodGFibGUsIHRoaXMubWF4KSAtIHRoaXMuX21pblBvcztcbiAgICBzdXBlci5pbml0T2Zmc2V0cyh0aW1lc3RhbXBzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHt0aW1lLCBwb3N9IG9iamVjdHMgdXNlZCB0byBpbnRlcnBvbGF0ZSBhIHNwZWNpZmljIGB0aW1lYCBvciBwb3NpdGlvblxuXHQgKiAoYHBvc2ApIG9uIHRoZSBzY2FsZSwgYnkgc2VhcmNoaW5nIGVudHJpZXMgYmVmb3JlIGFuZCBhZnRlciB0aGUgcmVxdWVzdGVkIHZhbHVlLiBgcG9zYCBpc1xuXHQgKiBhIGRlY2ltYWwgYmV0d2VlbiAwIGFuZCAxOiAwIGJlaW5nIHRoZSBzdGFydCBvZiB0aGUgc2NhbGUgKGxlZnQgb3IgdG9wKSBhbmQgMSB0aGUgb3RoZXJcblx0ICogZXh0cmVtaXR5IChsZWZ0ICsgd2lkdGggb3IgdG9wICsgaGVpZ2h0KS4gTm90ZSB0aGF0IGl0IHdvdWxkIGJlIG1vcmUgb3B0aW1pemVkIHRvIGRpcmVjdGx5XG5cdCAqIHN0b3JlIHByZS1jb21wdXRlZCBwaXhlbHMsIGJ1dCB0aGUgc2NhbGUgZGltZW5zaW9ucyBhcmUgbm90IGd1YXJhbnRlZWQgYXQgdGhlIHRpbWUgd2UgbmVlZFxuXHQgKiB0byBjcmVhdGUgdGhlIGxvb2t1cCB0YWJsZS4gVGhlIHRhYmxlIEFMV0FZUyBjb250YWlucyBhdCBsZWFzdCB0d28gaXRlbXM6IG1pbiBhbmQgbWF4LlxuXHQgKiBAcGFyYW0ge251bWJlcltdfSB0aW1lc3RhbXBzXG5cdCAqIEByZXR1cm4ge29iamVjdFtdfVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBidWlsZExvb2t1cFRhYmxlKHRpbWVzdGFtcHMpIHtcbiAgICBjb25zdCB7bWluLCBtYXh9ID0gdGhpcztcbiAgICBjb25zdCBpdGVtcyA9IFtdO1xuICAgIGNvbnN0IHRhYmxlID0gW107XG4gICAgbGV0IGksIGlsZW4sIHByZXYsIGN1cnIsIG5leHQ7XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gdGltZXN0YW1wcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIGN1cnIgPSB0aW1lc3RhbXBzW2ldO1xuICAgICAgaWYgKGN1cnIgPj0gbWluICYmIGN1cnIgPD0gbWF4KSB7XG4gICAgICAgIGl0ZW1zLnB1c2goY3Vycik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGl0ZW1zLmxlbmd0aCA8IDIpIHtcbiAgICAgIC8vIEluIGNhc2UgdGhlcmUgaXMgbGVzcyB0aGF0IDIgdGltZXN0YW1wcyBiZXR3ZWVuIG1pbiBhbmQgbWF4LCB0aGUgc2NhbGUgaXMgZGVmaW5lZCBieSBtaW4gYW5kIG1heFxuICAgICAgcmV0dXJuIFtcbiAgICAgICAge3RpbWU6IG1pbiwgcG9zOiAwfSxcbiAgICAgICAge3RpbWU6IG1heCwgcG9zOiAxfVxuICAgICAgXTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gaXRlbXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBuZXh0ID0gaXRlbXNbaSArIDFdO1xuICAgICAgcHJldiA9IGl0ZW1zW2kgLSAxXTtcbiAgICAgIGN1cnIgPSBpdGVtc1tpXTtcblxuICAgICAgLy8gb25seSBhZGQgcG9pbnRzIHRoYXQgYnJlYWtzIHRoZSBzY2FsZSBsaW5lYXJpdHlcbiAgICAgIGlmIChNYXRoLnJvdW5kKChuZXh0ICsgcHJldikgLyAyKSAhPT0gY3Vycikge1xuICAgICAgICB0YWJsZS5wdXNoKHt0aW1lOiBjdXJyLCBwb3M6IGkgLyAoaWxlbiAtIDEpfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YWJsZTtcbiAgfVxuXG4gIC8qKlxuICAgICogR2VuZXJhdGVzIGFsbCB0aW1lc3RhbXBzIGRlZmluZWQgaW4gdGhlIGRhdGEuXG4gICAgKiBJbXBvcnRhbnQ6IHRoaXMgbWV0aG9kIGNhbiByZXR1cm4gdGlja3Mgb3V0c2lkZSB0aGUgbWluIGFuZCBtYXggcmFuZ2UsIGl0J3MgdGhlXG4gICAgKiByZXNwb25zaWJpbGl0eSBvZiB0aGUgY2FsbGluZyBjb2RlIHRvIGNsYW1wIHZhbHVlcyBpZiBuZWVkZWQuXG4gICAgKiBAcHJvdGVjdGVkXG4gICAgKi9cbiAgX2dlbmVyYXRlKCkge1xuICAgIGNvbnN0IG1pbiA9IHRoaXMubWluO1xuICAgIGNvbnN0IG1heCA9IHRoaXMubWF4O1xuICAgIGxldCB0aW1lc3RhbXBzID0gc3VwZXIuZ2V0RGF0YVRpbWVzdGFtcHMoKTtcbiAgICBpZiAoIXRpbWVzdGFtcHMuaW5jbHVkZXMobWluKSB8fCAhdGltZXN0YW1wcy5sZW5ndGgpIHtcbiAgICAgIHRpbWVzdGFtcHMuc3BsaWNlKDAsIDAsIG1pbik7XG4gICAgfVxuICAgIGlmICghdGltZXN0YW1wcy5pbmNsdWRlcyhtYXgpIHx8IHRpbWVzdGFtcHMubGVuZ3RoID09PSAxKSB7XG4gICAgICB0aW1lc3RhbXBzLnB1c2gobWF4KTtcbiAgICB9XG4gICAgcmV0dXJuIHRpbWVzdGFtcHMuc29ydCgoYSwgYikgPT4gYSAtIGIpO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJldHVybnMgYWxsIHRpbWVzdGFtcHNcblx0ICogQHJldHVybiB7bnVtYmVyW119XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0VGltZXN0YW1wc0ZvclRhYmxlKCkge1xuICAgIGxldCB0aW1lc3RhbXBzID0gdGhpcy5fY2FjaGUuYWxsIHx8IFtdO1xuXG4gICAgaWYgKHRpbWVzdGFtcHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGltZXN0YW1wcztcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gdGhpcy5nZXREYXRhVGltZXN0YW1wcygpO1xuICAgIGNvbnN0IGxhYmVsID0gdGhpcy5nZXRMYWJlbFRpbWVzdGFtcHMoKTtcbiAgICBpZiAoZGF0YS5sZW5ndGggJiYgbGFiZWwubGVuZ3RoKSB7XG4gICAgICAvLyBJZiBjb21iaW5pbmcgbGFiZWxzIGFuZCBkYXRhIChkYXRhIG1pZ2h0IG5vdCBjb250YWluIGFsbCBsYWJlbHMpLFxuICAgICAgLy8gd2UgbmVlZCB0byByZWNoZWNrIHVuaXF1ZW5lc3MgYW5kIHNvcnRcbiAgICAgIHRpbWVzdGFtcHMgPSB0aGlzLm5vcm1hbGl6ZShkYXRhLmNvbmNhdChsYWJlbCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aW1lc3RhbXBzID0gZGF0YS5sZW5ndGggPyBkYXRhIDogbGFiZWw7XG4gICAgfVxuICAgIHRpbWVzdGFtcHMgPSB0aGlzLl9jYWNoZS5hbGwgPSB0aW1lc3RhbXBzO1xuXG4gICAgcmV0dXJuIHRpbWVzdGFtcHM7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gTWlsbGlzZWNvbmRzIHNpbmNlIGVwb2NoICgxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVEMpXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG4gIGdldERlY2ltYWxGb3JWYWx1ZSh2YWx1ZSkge1xuICAgIHJldHVybiAoaW50ZXJwb2xhdGUodGhpcy5fdGFibGUsIHZhbHVlKSAtIHRoaXMuX21pblBvcykgLyB0aGlzLl90YWJsZVJhbmdlO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuICBnZXRWYWx1ZUZvclBpeGVsKHBpeGVsKSB7XG4gICAgY29uc3Qgb2Zmc2V0cyA9IHRoaXMuX29mZnNldHM7XG4gICAgY29uc3QgZGVjaW1hbCA9IHRoaXMuZ2V0RGVjaW1hbEZvclBpeGVsKHBpeGVsKSAvIG9mZnNldHMuZmFjdG9yIC0gb2Zmc2V0cy5lbmQ7XG4gICAgcmV0dXJuIGludGVycG9sYXRlKHRoaXMuX3RhYmxlLCBkZWNpbWFsICogdGhpcy5fdGFibGVSYW5nZSArIHRoaXMuX21pblBvcywgdHJ1ZSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVGltZVNlcmllc1NjYWxlO1xuIiwgImV4cG9ydCAqIGZyb20gJy4vY29udHJvbGxlcnMvaW5kZXguanMnO1xuZXhwb3J0ICogZnJvbSAnLi9jb3JlL2luZGV4LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vZWxlbWVudHMvaW5kZXguanMnO1xuZXhwb3J0ICogZnJvbSAnLi9wbGF0Zm9ybS9pbmRleC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3BsdWdpbnMvaW5kZXguanMnO1xuZXhwb3J0ICogZnJvbSAnLi9zY2FsZXMvaW5kZXguanMnO1xuXG5pbXBvcnQgKiBhcyBjb250cm9sbGVycyBmcm9tICcuL2NvbnRyb2xsZXJzL2luZGV4LmpzJztcbmltcG9ydCAqIGFzIGVsZW1lbnRzIGZyb20gJy4vZWxlbWVudHMvaW5kZXguanMnO1xuaW1wb3J0ICogYXMgcGx1Z2lucyBmcm9tICcuL3BsdWdpbnMvaW5kZXguanMnO1xuaW1wb3J0ICogYXMgc2NhbGVzIGZyb20gJy4vc2NhbGVzL2luZGV4LmpzJztcblxuZXhwb3J0IHtcbiAgY29udHJvbGxlcnMsXG4gIGVsZW1lbnRzLFxuICBwbHVnaW5zLFxuICBzY2FsZXMsXG59O1xuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJhYmxlcyA9IFtcbiAgY29udHJvbGxlcnMsXG4gIGVsZW1lbnRzLFxuICBwbHVnaW5zLFxuICBzY2FsZXMsXG5dO1xuIiwgImltcG9ydCB7Q2hhcnQsIHJlZ2lzdGVyYWJsZXN9IGZyb20gJy4uL2Rpc3QvY2hhcnQuanMnO1xuXG5DaGFydC5yZWdpc3RlciguLi5yZWdpc3RlcmFibGVzKTtcblxuZXhwb3J0ICogZnJvbSAnLi4vZGlzdC9jaGFydC5qcyc7XG5leHBvcnQgZGVmYXVsdCBDaGFydDtcbiIsICIvKiFcbiAqIEBrdXJrbGUvY29sb3IgdjAuMy4yXG4gKiBodHRwczovL2dpdGh1Yi5jb20va3Vya2xlL2NvbG9yI3JlYWRtZVxuICogKGMpIDIwMjMgSnVra2EgS3Vya2VsYVxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlXG4gKi9cbmZ1bmN0aW9uIHJvdW5kKHYpIHtcbiAgcmV0dXJuIHYgKyAwLjUgfCAwO1xufVxuY29uc3QgbGltID0gKHYsIGwsIGgpID0+IE1hdGgubWF4KE1hdGgubWluKHYsIGgpLCBsKTtcbmZ1bmN0aW9uIHAyYih2KSB7XG4gIHJldHVybiBsaW0ocm91bmQodiAqIDIuNTUpLCAwLCAyNTUpO1xufVxuZnVuY3Rpb24gYjJwKHYpIHtcbiAgcmV0dXJuIGxpbShyb3VuZCh2IC8gMi41NSksIDAsIDEwMCk7XG59XG5mdW5jdGlvbiBuMmIodikge1xuICByZXR1cm4gbGltKHJvdW5kKHYgKiAyNTUpLCAwLCAyNTUpO1xufVxuZnVuY3Rpb24gYjJuKHYpIHtcbiAgcmV0dXJuIGxpbShyb3VuZCh2IC8gMi41NSkgLyAxMDAsIDAsIDEpO1xufVxuZnVuY3Rpb24gbjJwKHYpIHtcbiAgcmV0dXJuIGxpbShyb3VuZCh2ICogMTAwKSwgMCwgMTAwKTtcbn1cblxuY29uc3QgbWFwJDEgPSB7MDogMCwgMTogMSwgMjogMiwgMzogMywgNDogNCwgNTogNSwgNjogNiwgNzogNywgODogOCwgOTogOSwgQTogMTAsIEI6IDExLCBDOiAxMiwgRDogMTMsIEU6IDE0LCBGOiAxNSwgYTogMTAsIGI6IDExLCBjOiAxMiwgZDogMTMsIGU6IDE0LCBmOiAxNX07XG5jb25zdCBoZXggPSBbLi4uJzAxMjM0NTY3ODlBQkNERUYnXTtcbmNvbnN0IGgxID0gYiA9PiBoZXhbYiAmIDB4Rl07XG5jb25zdCBoMiA9IGIgPT4gaGV4WyhiICYgMHhGMCkgPj4gNF0gKyBoZXhbYiAmIDB4Rl07XG5jb25zdCBlcSA9IGIgPT4gKChiICYgMHhGMCkgPj4gNCkgPT09IChiICYgMHhGKTtcbmNvbnN0IGlzU2hvcnQgPSB2ID0+IGVxKHYucikgJiYgZXEodi5nKSAmJiBlcSh2LmIpICYmIGVxKHYuYSk7XG5mdW5jdGlvbiBoZXhQYXJzZShzdHIpIHtcbiAgdmFyIGxlbiA9IHN0ci5sZW5ndGg7XG4gIHZhciByZXQ7XG4gIGlmIChzdHJbMF0gPT09ICcjJykge1xuICAgIGlmIChsZW4gPT09IDQgfHwgbGVuID09PSA1KSB7XG4gICAgICByZXQgPSB7XG4gICAgICAgIHI6IDI1NSAmIG1hcCQxW3N0clsxXV0gKiAxNyxcbiAgICAgICAgZzogMjU1ICYgbWFwJDFbc3RyWzJdXSAqIDE3LFxuICAgICAgICBiOiAyNTUgJiBtYXAkMVtzdHJbM11dICogMTcsXG4gICAgICAgIGE6IGxlbiA9PT0gNSA/IG1hcCQxW3N0cls0XV0gKiAxNyA6IDI1NVxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGxlbiA9PT0gNyB8fCBsZW4gPT09IDkpIHtcbiAgICAgIHJldCA9IHtcbiAgICAgICAgcjogbWFwJDFbc3RyWzFdXSA8PCA0IHwgbWFwJDFbc3RyWzJdXSxcbiAgICAgICAgZzogbWFwJDFbc3RyWzNdXSA8PCA0IHwgbWFwJDFbc3RyWzRdXSxcbiAgICAgICAgYjogbWFwJDFbc3RyWzVdXSA8PCA0IHwgbWFwJDFbc3RyWzZdXSxcbiAgICAgICAgYTogbGVuID09PSA5ID8gKG1hcCQxW3N0cls3XV0gPDwgNCB8IG1hcCQxW3N0cls4XV0pIDogMjU1XG4gICAgICB9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmV0O1xufVxuY29uc3QgYWxwaGEgPSAoYSwgZikgPT4gYSA8IDI1NSA/IGYoYSkgOiAnJztcbmZ1bmN0aW9uIGhleFN0cmluZyh2KSB7XG4gIHZhciBmID0gaXNTaG9ydCh2KSA/IGgxIDogaDI7XG4gIHJldHVybiB2XG4gICAgPyAnIycgKyBmKHYucikgKyBmKHYuZykgKyBmKHYuYikgKyBhbHBoYSh2LmEsIGYpXG4gICAgOiB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IEhVRV9SRSA9IC9eKGhzbGE/fGh3Ynxoc3YpXFwoXFxzKihbLSsuZVxcZF0rKSg/OmRlZyk/W1xccyxdKyhbLSsuZVxcZF0rKSVbXFxzLF0rKFstKy5lXFxkXSspJSg/OltcXHMsXSsoWy0rLmVcXGRdKykoJSk/KT9cXHMqXFwpJC87XG5mdW5jdGlvbiBoc2wycmdibihoLCBzLCBsKSB7XG4gIGNvbnN0IGEgPSBzICogTWF0aC5taW4obCwgMSAtIGwpO1xuICBjb25zdCBmID0gKG4sIGsgPSAobiArIGggLyAzMCkgJSAxMikgPT4gbCAtIGEgKiBNYXRoLm1heChNYXRoLm1pbihrIC0gMywgOSAtIGssIDEpLCAtMSk7XG4gIHJldHVybiBbZigwKSwgZig4KSwgZig0KV07XG59XG5mdW5jdGlvbiBoc3YycmdibihoLCBzLCB2KSB7XG4gIGNvbnN0IGYgPSAobiwgayA9IChuICsgaCAvIDYwKSAlIDYpID0+IHYgLSB2ICogcyAqIE1hdGgubWF4KE1hdGgubWluKGssIDQgLSBrLCAxKSwgMCk7XG4gIHJldHVybiBbZig1KSwgZigzKSwgZigxKV07XG59XG5mdW5jdGlvbiBod2IycmdibihoLCB3LCBiKSB7XG4gIGNvbnN0IHJnYiA9IGhzbDJyZ2JuKGgsIDEsIDAuNSk7XG4gIGxldCBpO1xuICBpZiAodyArIGIgPiAxKSB7XG4gICAgaSA9IDEgLyAodyArIGIpO1xuICAgIHcgKj0gaTtcbiAgICBiICo9IGk7XG4gIH1cbiAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykge1xuICAgIHJnYltpXSAqPSAxIC0gdyAtIGI7XG4gICAgcmdiW2ldICs9IHc7XG4gIH1cbiAgcmV0dXJuIHJnYjtcbn1cbmZ1bmN0aW9uIGh1ZVZhbHVlKHIsIGcsIGIsIGQsIG1heCkge1xuICBpZiAociA9PT0gbWF4KSB7XG4gICAgcmV0dXJuICgoZyAtIGIpIC8gZCkgKyAoZyA8IGIgPyA2IDogMCk7XG4gIH1cbiAgaWYgKGcgPT09IG1heCkge1xuICAgIHJldHVybiAoYiAtIHIpIC8gZCArIDI7XG4gIH1cbiAgcmV0dXJuIChyIC0gZykgLyBkICsgNDtcbn1cbmZ1bmN0aW9uIHJnYjJoc2wodikge1xuICBjb25zdCByYW5nZSA9IDI1NTtcbiAgY29uc3QgciA9IHYuciAvIHJhbmdlO1xuICBjb25zdCBnID0gdi5nIC8gcmFuZ2U7XG4gIGNvbnN0IGIgPSB2LmIgLyByYW5nZTtcbiAgY29uc3QgbWF4ID0gTWF0aC5tYXgociwgZywgYik7XG4gIGNvbnN0IG1pbiA9IE1hdGgubWluKHIsIGcsIGIpO1xuICBjb25zdCBsID0gKG1heCArIG1pbikgLyAyO1xuICBsZXQgaCwgcywgZDtcbiAgaWYgKG1heCAhPT0gbWluKSB7XG4gICAgZCA9IG1heCAtIG1pbjtcbiAgICBzID0gbCA+IDAuNSA/IGQgLyAoMiAtIG1heCAtIG1pbikgOiBkIC8gKG1heCArIG1pbik7XG4gICAgaCA9IGh1ZVZhbHVlKHIsIGcsIGIsIGQsIG1heCk7XG4gICAgaCA9IGggKiA2MCArIDAuNTtcbiAgfVxuICByZXR1cm4gW2ggfCAwLCBzIHx8IDAsIGxdO1xufVxuZnVuY3Rpb24gY2FsbG4oZiwgYSwgYiwgYykge1xuICByZXR1cm4gKFxuICAgIEFycmF5LmlzQXJyYXkoYSlcbiAgICAgID8gZihhWzBdLCBhWzFdLCBhWzJdKVxuICAgICAgOiBmKGEsIGIsIGMpXG4gICkubWFwKG4yYik7XG59XG5mdW5jdGlvbiBoc2wycmdiKGgsIHMsIGwpIHtcbiAgcmV0dXJuIGNhbGxuKGhzbDJyZ2JuLCBoLCBzLCBsKTtcbn1cbmZ1bmN0aW9uIGh3YjJyZ2IoaCwgdywgYikge1xuICByZXR1cm4gY2FsbG4oaHdiMnJnYm4sIGgsIHcsIGIpO1xufVxuZnVuY3Rpb24gaHN2MnJnYihoLCBzLCB2KSB7XG4gIHJldHVybiBjYWxsbihoc3YycmdibiwgaCwgcywgdik7XG59XG5mdW5jdGlvbiBodWUoaCkge1xuICByZXR1cm4gKGggJSAzNjAgKyAzNjApICUgMzYwO1xufVxuZnVuY3Rpb24gaHVlUGFyc2Uoc3RyKSB7XG4gIGNvbnN0IG0gPSBIVUVfUkUuZXhlYyhzdHIpO1xuICBsZXQgYSA9IDI1NTtcbiAgbGV0IHY7XG4gIGlmICghbSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAobVs1XSAhPT0gdikge1xuICAgIGEgPSBtWzZdID8gcDJiKCttWzVdKSA6IG4yYigrbVs1XSk7XG4gIH1cbiAgY29uc3QgaCA9IGh1ZSgrbVsyXSk7XG4gIGNvbnN0IHAxID0gK21bM10gLyAxMDA7XG4gIGNvbnN0IHAyID0gK21bNF0gLyAxMDA7XG4gIGlmIChtWzFdID09PSAnaHdiJykge1xuICAgIHYgPSBod2IycmdiKGgsIHAxLCBwMik7XG4gIH0gZWxzZSBpZiAobVsxXSA9PT0gJ2hzdicpIHtcbiAgICB2ID0gaHN2MnJnYihoLCBwMSwgcDIpO1xuICB9IGVsc2Uge1xuICAgIHYgPSBoc2wycmdiKGgsIHAxLCBwMik7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICByOiB2WzBdLFxuICAgIGc6IHZbMV0sXG4gICAgYjogdlsyXSxcbiAgICBhOiBhXG4gIH07XG59XG5mdW5jdGlvbiByb3RhdGUodiwgZGVnKSB7XG4gIHZhciBoID0gcmdiMmhzbCh2KTtcbiAgaFswXSA9IGh1ZShoWzBdICsgZGVnKTtcbiAgaCA9IGhzbDJyZ2IoaCk7XG4gIHYuciA9IGhbMF07XG4gIHYuZyA9IGhbMV07XG4gIHYuYiA9IGhbMl07XG59XG5mdW5jdGlvbiBoc2xTdHJpbmcodikge1xuICBpZiAoIXYpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgYSA9IHJnYjJoc2wodik7XG4gIGNvbnN0IGggPSBhWzBdO1xuICBjb25zdCBzID0gbjJwKGFbMV0pO1xuICBjb25zdCBsID0gbjJwKGFbMl0pO1xuICByZXR1cm4gdi5hIDwgMjU1XG4gICAgPyBgaHNsYSgke2h9LCAke3N9JSwgJHtsfSUsICR7YjJuKHYuYSl9KWBcbiAgICA6IGBoc2woJHtofSwgJHtzfSUsICR7bH0lKWA7XG59XG5cbmNvbnN0IG1hcCA9IHtcbiAgeDogJ2RhcmsnLFxuICBaOiAnbGlnaHQnLFxuICBZOiAncmUnLFxuICBYOiAnYmx1JyxcbiAgVzogJ2dyJyxcbiAgVjogJ21lZGl1bScsXG4gIFU6ICdzbGF0ZScsXG4gIEE6ICdlZScsXG4gIFQ6ICdvbCcsXG4gIFM6ICdvcicsXG4gIEI6ICdyYScsXG4gIEM6ICdsYXRlZycsXG4gIEQ6ICdpZ2h0cycsXG4gIFI6ICdpbicsXG4gIFE6ICd0dXJxdW9pcycsXG4gIEU6ICdoaScsXG4gIFA6ICdybycsXG4gIE86ICdhbCcsXG4gIE46ICdsZScsXG4gIE06ICdkZScsXG4gIEw6ICd5ZWxsbycsXG4gIEY6ICdlbicsXG4gIEs6ICdjaCcsXG4gIEc6ICdhcmtzJyxcbiAgSDogJ2VhJyxcbiAgSTogJ2lnaHRnJyxcbiAgSjogJ3doJ1xufTtcbmNvbnN0IG5hbWVzJDEgPSB7XG4gIE9pY2VYZTogJ2YwZjhmZicsXG4gIGFudGlxdWV3RXRlOiAnZmFlYmQ3JyxcbiAgYXF1YTogJ2ZmZmYnLFxuICBhcXVhbWFyUmU6ICc3ZmZmZDQnLFxuICBhenVZOiAnZjBmZmZmJyxcbiAgYmVpZ2U6ICdmNWY1ZGMnLFxuICBiaXNxdWU6ICdmZmU0YzQnLFxuICBibGFjazogJzAnLFxuICBibGFuS2VkT21vbmQ6ICdmZmViY2QnLFxuICBYZTogJ2ZmJyxcbiAgWGV2aVRldDogJzhhMmJlMicsXG4gIGJQd246ICdhNTJhMmEnLFxuICBidXJseXdvb2Q6ICdkZWI4ODcnLFxuICBjYU10WGU6ICc1ZjllYTAnLFxuICBLYXJ0WXVzZTogJzdmZmYwMCcsXG4gIEtvY1RhdGU6ICdkMjY5MWUnLFxuICBjU086ICdmZjdmNTAnLFxuICBjU25mbG93ZXJYZTogJzY0OTVlZCcsXG4gIGNTbnNpbGs6ICdmZmY4ZGMnLFxuICBjcmltc29uOiAnZGMxNDNjJyxcbiAgY3lhbjogJ2ZmZmYnLFxuICB4WGU6ICc4YicsXG4gIHhjeWFuOiAnOGI4YicsXG4gIHhnVE1uUGQ6ICdiODg2MGInLFxuICB4V2F5OiAnYTlhOWE5JyxcbiAgeGdZRjogJzY0MDAnLFxuICB4Z1l5OiAnYTlhOWE5JyxcbiAgeGtoYWtpOiAnYmRiNzZiJyxcbiAgeG1hZ0Z0YTogJzhiMDA4YicsXG4gIHhUaXZlZ1lGOiAnNTU2YjJmJyxcbiAgeFNhbmdlOiAnZmY4YzAwJyxcbiAgeFNjRWQ6ICc5OTMyY2MnLFxuICB4WWQ6ICc4YjAwMDAnLFxuICB4c09tb246ICdlOTk2N2EnLFxuICB4c0hnWUY6ICc4ZmJjOGYnLFxuICB4VVhlOiAnNDgzZDhiJyxcbiAgeFVXYXk6ICcyZjRmNGYnLFxuICB4VWdZeTogJzJmNGY0ZicsXG4gIHhRZTogJ2NlZDEnLFxuICB4dmlUZXQ6ICc5NDAwZDMnLFxuICBkQXBwUms6ICdmZjE0OTMnLFxuICBkQXBza3lYZTogJ2JmZmYnLFxuICBkaW1XYXk6ICc2OTY5NjknLFxuICBkaW1nWXk6ICc2OTY5NjknLFxuICBkb2RnZXJYZTogJzFlOTBmZicsXG4gIGZpWWJyaWNrOiAnYjIyMjIyJyxcbiAgZmxTT3dFdGU6ICdmZmZhZjAnLFxuICBmb1lzdFdBbjogJzIyOGIyMicsXG4gIGZ1S3NpYTogJ2ZmMDBmZicsXG4gIGdhUnNiU286ICdkY2RjZGMnLFxuICBnaG9zdHdFdGU6ICdmOGY4ZmYnLFxuICBnVGQ6ICdmZmQ3MDAnLFxuICBnVE1uUGQ6ICdkYWE1MjAnLFxuICBXYXk6ICc4MDgwODAnLFxuICBnWUY6ICc4MDAwJyxcbiAgZ1lGTHc6ICdhZGZmMmYnLFxuICBnWXk6ICc4MDgwODAnLFxuICBob25leU13OiAnZjBmZmYwJyxcbiAgaG90cFJrOiAnZmY2OWI0JyxcbiAgUmRpYW5ZZDogJ2NkNWM1YycsXG4gIFJkaWdvOiAnNGIwMDgyJyxcbiAgaXZTeTogJ2ZmZmZmMCcsXG4gIGtoYWtpOiAnZjBlNjhjJyxcbiAgbGF2Rk1yOiAnZTZlNmZhJyxcbiAgbGF2Rk1yWHNoOiAnZmZmMGY1JyxcbiAgbGF3bmdZRjogJzdjZmMwMCcsXG4gIE5tb25jRWZmb246ICdmZmZhY2QnLFxuICBaWGU6ICdhZGQ4ZTYnLFxuICBaY1NPOiAnZjA4MDgwJyxcbiAgWmN5YW46ICdlMGZmZmYnLFxuICBaZ1RNblBkTHc6ICdmYWZhZDInLFxuICBaV2F5OiAnZDNkM2QzJyxcbiAgWmdZRjogJzkwZWU5MCcsXG4gIFpnWXk6ICdkM2QzZDMnLFxuICBacFJrOiAnZmZiNmMxJyxcbiAgWnNPbW9uOiAnZmZhMDdhJyxcbiAgWnNIZ1lGOiAnMjBiMmFhJyxcbiAgWnNreVhlOiAnODdjZWZhJyxcbiAgWlVXYXk6ICc3Nzg4OTknLFxuICBaVWdZeTogJzc3ODg5OScsXG4gIFpzdEFsWGU6ICdiMGM0ZGUnLFxuICBaTHc6ICdmZmZmZTAnLFxuICBsaW1lOiAnZmYwMCcsXG4gIGxpbWVnWUY6ICczMmNkMzInLFxuICBsUkY6ICdmYWYwZTYnLFxuICBtYWdGdGE6ICdmZjAwZmYnLFxuICBtYVBvbjogJzgwMDAwMCcsXG4gIFZhcXVhbWFyUmU6ICc2NmNkYWEnLFxuICBWWGU6ICdjZCcsXG4gIFZTY0VkOiAnYmE1NWQzJyxcbiAgVnB1cnBOOiAnOTM3MGRiJyxcbiAgVnNIZ1lGOiAnM2NiMzcxJyxcbiAgVlVYZTogJzdiNjhlZScsXG4gIFZzcHJSZ2dZRjogJ2ZhOWEnLFxuICBWUWU6ICc0OGQxY2MnLFxuICBWdmlUZXRZZDogJ2M3MTU4NScsXG4gIG1pZG5pZ2h0WGU6ICcxOTE5NzAnLFxuICBtUnRjWWFtOiAnZjVmZmZhJyxcbiAgbWlzdHlQc2U6ICdmZmU0ZTEnLFxuICBtb2NjYXNSOiAnZmZlNGI1JyxcbiAgbmF2YWpvd0V0ZTogJ2ZmZGVhZCcsXG4gIG5hdnk6ICc4MCcsXG4gIFRkbGFjZTogJ2ZkZjVlNicsXG4gIFRpdmU6ICc4MDgwMDAnLFxuICBUaXZlZEJiOiAnNmI4ZTIzJyxcbiAgU2FuZ2U6ICdmZmE1MDAnLFxuICBTYW5nZVlkOiAnZmY0NTAwJyxcbiAgU2NFZDogJ2RhNzBkNicsXG4gIHBPZWdUTW5QZDogJ2VlZThhYScsXG4gIHBPZWdZRjogJzk4ZmI5OCcsXG4gIHBPZVFlOiAnYWZlZWVlJyxcbiAgcE9ldmlUZXRZZDogJ2RiNzA5MycsXG4gIHBhcGF5YXdFcDogJ2ZmZWZkNScsXG4gIHBIS3B1ZmY6ICdmZmRhYjknLFxuICBwZXJ1OiAnY2Q4NTNmJyxcbiAgcFJrOiAnZmZjMGNiJyxcbiAgcGx1bTogJ2RkYTBkZCcsXG4gIHBvd01yWGU6ICdiMGUwZTYnLFxuICBwdXJwTjogJzgwMDA4MCcsXG4gIFliZWNjYXB1cnBOOiAnNjYzMzk5JyxcbiAgWWQ6ICdmZjAwMDAnLFxuICBQc3licm93bjogJ2JjOGY4ZicsXG4gIFB5T1hlOiAnNDE2OWUxJyxcbiAgc2FkZE5iUHduOiAnOGI0NTEzJyxcbiAgc09tb246ICdmYTgwNzInLFxuICBzYW5keWJQd246ICdmNGE0NjAnLFxuICBzSGdZRjogJzJlOGI1NycsXG4gIHNIc2hlbGw6ICdmZmY1ZWUnLFxuICBzaUZuYTogJ2EwNTIyZCcsXG4gIHNpbHZlcjogJ2MwYzBjMCcsXG4gIHNreVhlOiAnODdjZWViJyxcbiAgVVhlOiAnNmE1YWNkJyxcbiAgVVdheTogJzcwODA5MCcsXG4gIFVnWXk6ICc3MDgwOTAnLFxuICBzbm93OiAnZmZmYWZhJyxcbiAgc3ByUmdnWUY6ICdmZjdmJyxcbiAgc3RBbFhlOiAnNDY4MmI0JyxcbiAgdGFuOiAnZDJiNDhjJyxcbiAgdGVPOiAnODA4MCcsXG4gIHRFc3ROOiAnZDhiZmQ4JyxcbiAgdG9tYXRvOiAnZmY2MzQ3JyxcbiAgUWU6ICc0MGUwZDAnLFxuICB2aVRldDogJ2VlODJlZScsXG4gIEpIdDogJ2Y1ZGViMycsXG4gIHdFdGU6ICdmZmZmZmYnLFxuICB3RXRlc21va2U6ICdmNWY1ZjUnLFxuICBMdzogJ2ZmZmYwMCcsXG4gIEx3Z1lGOiAnOWFjZDMyJ1xufTtcbmZ1bmN0aW9uIHVucGFjaygpIHtcbiAgY29uc3QgdW5wYWNrZWQgPSB7fTtcbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKG5hbWVzJDEpO1xuICBjb25zdCB0a2V5cyA9IE9iamVjdC5rZXlzKG1hcCk7XG4gIGxldCBpLCBqLCBrLCBvaywgbms7XG4gIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgb2sgPSBuayA9IGtleXNbaV07XG4gICAgZm9yIChqID0gMDsgaiA8IHRrZXlzLmxlbmd0aDsgaisrKSB7XG4gICAgICBrID0gdGtleXNbal07XG4gICAgICBuayA9IG5rLnJlcGxhY2UoaywgbWFwW2tdKTtcbiAgICB9XG4gICAgayA9IHBhcnNlSW50KG5hbWVzJDFbb2tdLCAxNik7XG4gICAgdW5wYWNrZWRbbmtdID0gW2sgPj4gMTYgJiAweEZGLCBrID4+IDggJiAweEZGLCBrICYgMHhGRl07XG4gIH1cbiAgcmV0dXJuIHVucGFja2VkO1xufVxuXG5sZXQgbmFtZXM7XG5mdW5jdGlvbiBuYW1lUGFyc2Uoc3RyKSB7XG4gIGlmICghbmFtZXMpIHtcbiAgICBuYW1lcyA9IHVucGFjaygpO1xuICAgIG5hbWVzLnRyYW5zcGFyZW50ID0gWzAsIDAsIDAsIDBdO1xuICB9XG4gIGNvbnN0IGEgPSBuYW1lc1tzdHIudG9Mb3dlckNhc2UoKV07XG4gIHJldHVybiBhICYmIHtcbiAgICByOiBhWzBdLFxuICAgIGc6IGFbMV0sXG4gICAgYjogYVsyXSxcbiAgICBhOiBhLmxlbmd0aCA9PT0gNCA/IGFbM10gOiAyNTVcbiAgfTtcbn1cblxuY29uc3QgUkdCX1JFID0gL15yZ2JhP1xcKFxccyooWy0rLlxcZF0rKSglKT9bXFxzLF0rKFstKy5lXFxkXSspKCUpP1tcXHMsXSsoWy0rLmVcXGRdKykoJSk/KD86W1xccywvXSsoWy0rLmVcXGRdKykoJSk/KT9cXHMqXFwpJC87XG5mdW5jdGlvbiByZ2JQYXJzZShzdHIpIHtcbiAgY29uc3QgbSA9IFJHQl9SRS5leGVjKHN0cik7XG4gIGxldCBhID0gMjU1O1xuICBsZXQgciwgZywgYjtcbiAgaWYgKCFtKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChtWzddICE9PSByKSB7XG4gICAgY29uc3QgdiA9ICttWzddO1xuICAgIGEgPSBtWzhdID8gcDJiKHYpIDogbGltKHYgKiAyNTUsIDAsIDI1NSk7XG4gIH1cbiAgciA9ICttWzFdO1xuICBnID0gK21bM107XG4gIGIgPSArbVs1XTtcbiAgciA9IDI1NSAmIChtWzJdID8gcDJiKHIpIDogbGltKHIsIDAsIDI1NSkpO1xuICBnID0gMjU1ICYgKG1bNF0gPyBwMmIoZykgOiBsaW0oZywgMCwgMjU1KSk7XG4gIGIgPSAyNTUgJiAobVs2XSA/IHAyYihiKSA6IGxpbShiLCAwLCAyNTUpKTtcbiAgcmV0dXJuIHtcbiAgICByOiByLFxuICAgIGc6IGcsXG4gICAgYjogYixcbiAgICBhOiBhXG4gIH07XG59XG5mdW5jdGlvbiByZ2JTdHJpbmcodikge1xuICByZXR1cm4gdiAmJiAoXG4gICAgdi5hIDwgMjU1XG4gICAgICA/IGByZ2JhKCR7di5yfSwgJHt2Lmd9LCAke3YuYn0sICR7YjJuKHYuYSl9KWBcbiAgICAgIDogYHJnYigke3Yucn0sICR7di5nfSwgJHt2LmJ9KWBcbiAgKTtcbn1cblxuY29uc3QgdG8gPSB2ID0+IHYgPD0gMC4wMDMxMzA4ID8gdiAqIDEyLjkyIDogTWF0aC5wb3codiwgMS4wIC8gMi40KSAqIDEuMDU1IC0gMC4wNTU7XG5jb25zdCBmcm9tID0gdiA9PiB2IDw9IDAuMDQwNDUgPyB2IC8gMTIuOTIgOiBNYXRoLnBvdygodiArIDAuMDU1KSAvIDEuMDU1LCAyLjQpO1xuZnVuY3Rpb24gaW50ZXJwb2xhdGUocmdiMSwgcmdiMiwgdCkge1xuICBjb25zdCByID0gZnJvbShiMm4ocmdiMS5yKSk7XG4gIGNvbnN0IGcgPSBmcm9tKGIybihyZ2IxLmcpKTtcbiAgY29uc3QgYiA9IGZyb20oYjJuKHJnYjEuYikpO1xuICByZXR1cm4ge1xuICAgIHI6IG4yYih0byhyICsgdCAqIChmcm9tKGIybihyZ2IyLnIpKSAtIHIpKSksXG4gICAgZzogbjJiKHRvKGcgKyB0ICogKGZyb20oYjJuKHJnYjIuZykpIC0gZykpKSxcbiAgICBiOiBuMmIodG8oYiArIHQgKiAoZnJvbShiMm4ocmdiMi5iKSkgLSBiKSkpLFxuICAgIGE6IHJnYjEuYSArIHQgKiAocmdiMi5hIC0gcmdiMS5hKVxuICB9O1xufVxuXG5mdW5jdGlvbiBtb2RIU0wodiwgaSwgcmF0aW8pIHtcbiAgaWYgKHYpIHtcbiAgICBsZXQgdG1wID0gcmdiMmhzbCh2KTtcbiAgICB0bXBbaV0gPSBNYXRoLm1heCgwLCBNYXRoLm1pbih0bXBbaV0gKyB0bXBbaV0gKiByYXRpbywgaSA9PT0gMCA/IDM2MCA6IDEpKTtcbiAgICB0bXAgPSBoc2wycmdiKHRtcCk7XG4gICAgdi5yID0gdG1wWzBdO1xuICAgIHYuZyA9IHRtcFsxXTtcbiAgICB2LmIgPSB0bXBbMl07XG4gIH1cbn1cbmZ1bmN0aW9uIGNsb25lKHYsIHByb3RvKSB7XG4gIHJldHVybiB2ID8gT2JqZWN0LmFzc2lnbihwcm90byB8fCB7fSwgdikgOiB2O1xufVxuZnVuY3Rpb24gZnJvbU9iamVjdChpbnB1dCkge1xuICB2YXIgdiA9IHtyOiAwLCBnOiAwLCBiOiAwLCBhOiAyNTV9O1xuICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dCkpIHtcbiAgICBpZiAoaW5wdXQubGVuZ3RoID49IDMpIHtcbiAgICAgIHYgPSB7cjogaW5wdXRbMF0sIGc6IGlucHV0WzFdLCBiOiBpbnB1dFsyXSwgYTogMjU1fTtcbiAgICAgIGlmIChpbnB1dC5sZW5ndGggPiAzKSB7XG4gICAgICAgIHYuYSA9IG4yYihpbnB1dFszXSk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHYgPSBjbG9uZShpbnB1dCwge3I6IDAsIGc6IDAsIGI6IDAsIGE6IDF9KTtcbiAgICB2LmEgPSBuMmIodi5hKTtcbiAgfVxuICByZXR1cm4gdjtcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uUGFyc2Uoc3RyKSB7XG4gIGlmIChzdHIuY2hhckF0KDApID09PSAncicpIHtcbiAgICByZXR1cm4gcmdiUGFyc2Uoc3RyKTtcbiAgfVxuICByZXR1cm4gaHVlUGFyc2Uoc3RyKTtcbn1cbmNsYXNzIENvbG9yIHtcbiAgY29uc3RydWN0b3IoaW5wdXQpIHtcbiAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBDb2xvcikge1xuICAgICAgcmV0dXJuIGlucHV0O1xuICAgIH1cbiAgICBjb25zdCB0eXBlID0gdHlwZW9mIGlucHV0O1xuICAgIGxldCB2O1xuICAgIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgdiA9IGZyb21PYmplY3QoaW5wdXQpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHYgPSBoZXhQYXJzZShpbnB1dCkgfHwgbmFtZVBhcnNlKGlucHV0KSB8fCBmdW5jdGlvblBhcnNlKGlucHV0KTtcbiAgICB9XG4gICAgdGhpcy5fcmdiID0gdjtcbiAgICB0aGlzLl92YWxpZCA9ICEhdjtcbiAgfVxuICBnZXQgdmFsaWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbGlkO1xuICB9XG4gIGdldCByZ2IoKSB7XG4gICAgdmFyIHYgPSBjbG9uZSh0aGlzLl9yZ2IpO1xuICAgIGlmICh2KSB7XG4gICAgICB2LmEgPSBiMm4odi5hKTtcbiAgICB9XG4gICAgcmV0dXJuIHY7XG4gIH1cbiAgc2V0IHJnYihvYmopIHtcbiAgICB0aGlzLl9yZ2IgPSBmcm9tT2JqZWN0KG9iaik7XG4gIH1cbiAgcmdiU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLl92YWxpZCA/IHJnYlN0cmluZyh0aGlzLl9yZ2IpIDogdW5kZWZpbmVkO1xuICB9XG4gIGhleFN0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsaWQgPyBoZXhTdHJpbmcodGhpcy5fcmdiKSA6IHVuZGVmaW5lZDtcbiAgfVxuICBoc2xTdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbGlkID8gaHNsU3RyaW5nKHRoaXMuX3JnYikgOiB1bmRlZmluZWQ7XG4gIH1cbiAgbWl4KGNvbG9yLCB3ZWlnaHQpIHtcbiAgICBpZiAoY29sb3IpIHtcbiAgICAgIGNvbnN0IGMxID0gdGhpcy5yZ2I7XG4gICAgICBjb25zdCBjMiA9IGNvbG9yLnJnYjtcbiAgICAgIGxldCB3MjtcbiAgICAgIGNvbnN0IHAgPSB3ZWlnaHQgPT09IHcyID8gMC41IDogd2VpZ2h0O1xuICAgICAgY29uc3QgdyA9IDIgKiBwIC0gMTtcbiAgICAgIGNvbnN0IGEgPSBjMS5hIC0gYzIuYTtcbiAgICAgIGNvbnN0IHcxID0gKCh3ICogYSA9PT0gLTEgPyB3IDogKHcgKyBhKSAvICgxICsgdyAqIGEpKSArIDEpIC8gMi4wO1xuICAgICAgdzIgPSAxIC0gdzE7XG4gICAgICBjMS5yID0gMHhGRiAmIHcxICogYzEuciArIHcyICogYzIuciArIDAuNTtcbiAgICAgIGMxLmcgPSAweEZGICYgdzEgKiBjMS5nICsgdzIgKiBjMi5nICsgMC41O1xuICAgICAgYzEuYiA9IDB4RkYgJiB3MSAqIGMxLmIgKyB3MiAqIGMyLmIgKyAwLjU7XG4gICAgICBjMS5hID0gcCAqIGMxLmEgKyAoMSAtIHApICogYzIuYTtcbiAgICAgIHRoaXMucmdiID0gYzE7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIGludGVycG9sYXRlKGNvbG9yLCB0KSB7XG4gICAgaWYgKGNvbG9yKSB7XG4gICAgICB0aGlzLl9yZ2IgPSBpbnRlcnBvbGF0ZSh0aGlzLl9yZ2IsIGNvbG9yLl9yZ2IsIHQpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBjbG9uZSgpIHtcbiAgICByZXR1cm4gbmV3IENvbG9yKHRoaXMucmdiKTtcbiAgfVxuICBhbHBoYShhKSB7XG4gICAgdGhpcy5fcmdiLmEgPSBuMmIoYSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgY2xlYXJlcihyYXRpbykge1xuICAgIGNvbnN0IHJnYiA9IHRoaXMuX3JnYjtcbiAgICByZ2IuYSAqPSAxIC0gcmF0aW87XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgZ3JleXNjYWxlKCkge1xuICAgIGNvbnN0IHJnYiA9IHRoaXMuX3JnYjtcbiAgICBjb25zdCB2YWwgPSByb3VuZChyZ2IuciAqIDAuMyArIHJnYi5nICogMC41OSArIHJnYi5iICogMC4xMSk7XG4gICAgcmdiLnIgPSByZ2IuZyA9IHJnYi5iID0gdmFsO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIG9wYXF1ZXIocmF0aW8pIHtcbiAgICBjb25zdCByZ2IgPSB0aGlzLl9yZ2I7XG4gICAgcmdiLmEgKj0gMSArIHJhdGlvO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIG5lZ2F0ZSgpIHtcbiAgICBjb25zdCB2ID0gdGhpcy5fcmdiO1xuICAgIHYuciA9IDI1NSAtIHYucjtcbiAgICB2LmcgPSAyNTUgLSB2Lmc7XG4gICAgdi5iID0gMjU1IC0gdi5iO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIGxpZ2h0ZW4ocmF0aW8pIHtcbiAgICBtb2RIU0wodGhpcy5fcmdiLCAyLCByYXRpbyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgZGFya2VuKHJhdGlvKSB7XG4gICAgbW9kSFNMKHRoaXMuX3JnYiwgMiwgLXJhdGlvKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBzYXR1cmF0ZShyYXRpbykge1xuICAgIG1vZEhTTCh0aGlzLl9yZ2IsIDEsIHJhdGlvKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICBkZXNhdHVyYXRlKHJhdGlvKSB7XG4gICAgbW9kSFNMKHRoaXMuX3JnYiwgMSwgLXJhdGlvKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICByb3RhdGUoZGVnKSB7XG4gICAgcm90YXRlKHRoaXMuX3JnYiwgZGVnKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuXG5mdW5jdGlvbiBpbmRleF9lc20oaW5wdXQpIHtcbiAgcmV0dXJuIG5ldyBDb2xvcihpbnB1dCk7XG59XG5cbmV4cG9ydCB7IENvbG9yLCBiMm4sIGIycCwgaW5kZXhfZXNtIGFzIGRlZmF1bHQsIGhleFBhcnNlLCBoZXhTdHJpbmcsIGhzbDJyZ2IsIGhzbFN0cmluZywgaHN2MnJnYiwgaHVlUGFyc2UsIGh3YjJyZ2IsIGxpbSwgbjJiLCBuMnAsIG5hbWVQYXJzZSwgcDJiLCByZ2IyaHNsLCByZ2JQYXJzZSwgcmdiU3RyaW5nLCByb3RhdGUsIHJvdW5kIH07XG4iLCAiLyoqXG4gKiBAbmFtZXNwYWNlIENoYXJ0LmhlbHBlcnNcbiAqL1xuXG5pbXBvcnQgdHlwZSB7QW55T2JqZWN0fSBmcm9tICcuLi90eXBlcy9iYXNpYy5qcyc7XG5pbXBvcnQgdHlwZSB7QWN0aXZlRGF0YVBvaW50LCBDaGFydEV2ZW50fSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5cbi8qKlxuICogQW4gZW1wdHkgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCwgZm9yIGV4YW1wbGUsIGZvciBvcHRpb25hbCBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vb3AoKSB7XG4gIC8qIG5vb3AgKi9cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgdW5pcXVlIGlkLCBzZXF1ZW50aWFsbHkgZ2VuZXJhdGVkIGZyb20gYSBnbG9iYWwgdmFyaWFibGUuXG4gKi9cbmV4cG9ydCBjb25zdCB1aWQgPSAoKCkgPT4ge1xuICBsZXQgaWQgPSAwO1xuICByZXR1cm4gKCkgPT4gaWQrKztcbn0pKCk7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIGB2YWx1ZWAgaXMgbmVpdGhlciBudWxsIG5vciB1bmRlZmluZWQsIGVsc2UgcmV0dXJucyBmYWxzZS5cbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB0ZXN0LlxuICogQHNpbmNlIDIuNy4wXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bGxPclVuZGVmKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgbnVsbCB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBgdmFsdWVgIGlzIGFuIGFycmF5IChpbmNsdWRpbmcgdHlwZWQgYXJyYXlzKSwgZWxzZSByZXR1cm5zIGZhbHNlLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHRlc3QuXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXJyYXk8VCA9IHVua25vd24+KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgVFtdIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkgJiYgQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBjb25zdCB0eXBlID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgaWYgKHR5cGUuc2xpY2UoMCwgNykgPT09ICdbb2JqZWN0JyAmJiB0eXBlLnNsaWNlKC02KSA9PT0gJ0FycmF5XScpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0IChleGNsdWRpbmcgbnVsbCksIGVsc2UgcmV0dXJucyBmYWxzZS5cbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB0ZXN0LlxuICogQHNpbmNlIDIuNy4wXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09iamVjdCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEFueU9iamVjdCB7XG4gIHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpID09PSAnW29iamVjdCBPYmplY3RdJztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBudW1iZXIsIGVsc2UgcmV0dXJucyBmYWxzZVxuICogQHBhcmFtIHZhbHVlICAtIFRoZSB2YWx1ZSB0byB0ZXN0LlxuICovXG5mdW5jdGlvbiBpc051bWJlckZpbml0ZSh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB7XG4gIHJldHVybiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fCB2YWx1ZSBpbnN0YW5jZW9mIE51bWJlcikgJiYgaXNGaW5pdGUoK3ZhbHVlKTtcbn1cbmV4cG9ydCB7XG4gIGlzTnVtYmVyRmluaXRlIGFzIGlzRmluaXRlLFxufTtcblxuLyoqXG4gKiBSZXR1cm5zIGB2YWx1ZWAgaWYgZmluaXRlLCBlbHNlIHJldHVybnMgYGRlZmF1bHRWYWx1ZWAuXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIGRlZmluZWQuXG4gKiBAcGFyYW0gZGVmYXVsdFZhbHVlIC0gVGhlIHZhbHVlIHRvIHJldHVybiBpZiBgdmFsdWVgIGlzIG5vdCBmaW5pdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5pdGVPckRlZmF1bHQodmFsdWU6IHVua25vd24sIGRlZmF1bHRWYWx1ZTogbnVtYmVyKSB7XG4gIHJldHVybiBpc051bWJlckZpbml0ZSh2YWx1ZSkgPyB2YWx1ZSA6IGRlZmF1bHRWYWx1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGB2YWx1ZWAgaWYgZGVmaW5lZCwgZWxzZSByZXR1cm5zIGBkZWZhdWx0VmFsdWVgLlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHJldHVybiBpZiBkZWZpbmVkLlxuICogQHBhcmFtIGRlZmF1bHRWYWx1ZSAtIFRoZSB2YWx1ZSB0byByZXR1cm4gaWYgYHZhbHVlYCBpcyB1bmRlZmluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWx1ZU9yRGVmYXVsdDxUPih2YWx1ZTogVCB8IHVuZGVmaW5lZCwgZGVmYXVsdFZhbHVlOiBUKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnID8gZGVmYXVsdFZhbHVlIDogdmFsdWU7XG59XG5cbmV4cG9ydCBjb25zdCB0b1BlcmNlbnRhZ2UgPSAodmFsdWU6IG51bWJlciB8IHN0cmluZywgZGltZW5zaW9uOiBudW1iZXIpID0+XG4gIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUuZW5kc1dpdGgoJyUnKSA/XG4gICAgcGFyc2VGbG9hdCh2YWx1ZSkgLyAxMDBcbiAgICA6ICt2YWx1ZSAvIGRpbWVuc2lvbjtcblxuZXhwb3J0IGNvbnN0IHRvRGltZW5zaW9uID0gKHZhbHVlOiBudW1iZXIgfCBzdHJpbmcsIGRpbWVuc2lvbjogbnVtYmVyKSA9PlxuICB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlLmVuZHNXaXRoKCclJykgP1xuICAgIHBhcnNlRmxvYXQodmFsdWUpIC8gMTAwICogZGltZW5zaW9uXG4gICAgOiArdmFsdWU7XG5cbi8qKlxuICogQ2FsbHMgYGZuYCB3aXRoIHRoZSBnaXZlbiBgYXJnc2AgaW4gdGhlIHNjb3BlIGRlZmluZWQgYnkgYHRoaXNBcmdgIGFuZCByZXR1cm5zIHRoZVxuICogdmFsdWUgcmV0dXJuZWQgYnkgYGZuYC4gSWYgYGZuYCBpcyBub3QgYSBmdW5jdGlvbiwgdGhpcyBtZXRob2QgcmV0dXJucyB1bmRlZmluZWQuXG4gKiBAcGFyYW0gZm4gLSBUaGUgZnVuY3Rpb24gdG8gY2FsbC5cbiAqIEBwYXJhbSBhcmdzIC0gVGhlIGFyZ3VtZW50cyB3aXRoIHdoaWNoIGBmbmAgc2hvdWxkIGJlIGNhbGxlZC5cbiAqIEBwYXJhbSBbdGhpc0FyZ10gLSBUaGUgdmFsdWUgb2YgYHRoaXNgIHByb3ZpZGVkIGZvciB0aGUgY2FsbCB0byBgZm5gLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsbGJhY2s8VCBleHRlbmRzICh0aGlzOiBUQSwgLi4ucmVzdEFyZ3M6IHVua25vd25bXSkgPT4gUiwgVEEsIFI+KFxuICBmbjogVCB8IHVuZGVmaW5lZCxcbiAgYXJnczogdW5rbm93bltdLFxuICB0aGlzQXJnPzogVEFcbik6IFIgfCB1bmRlZmluZWQge1xuICBpZiAoZm4gJiYgdHlwZW9mIGZuLmNhbGwgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJncyk7XG4gIH1cbn1cblxuLyoqXG4gKiBOb3RlKFNCKSBmb3IgcGVyZm9ybWFuY2Ugc2FrZSwgdGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgdXNlZCB3aGVuIGxvb3BhYmxlIHR5cGVcbiAqIGlzIHVua25vd24gb3IgaW4gbm9uZSBpbnRlbnNpdmUgY29kZSAobm90IGNhbGxlZCBvZnRlbiBhbmQgc21hbGwgbG9vcGFibGUpLiBFbHNlXG4gKiBpdCdzIHByZWZlcmFibGUgdG8gdXNlIGEgcmVndWxhciBmb3IoKSBsb29wIGFuZCBzYXZlIGV4dHJhIGZ1bmN0aW9uIGNhbGxzLlxuICogQHBhcmFtIGxvb3BhYmxlIC0gVGhlIG9iamVjdCBvciBhcnJheSB0byBiZSBpdGVyYXRlZC5cbiAqIEBwYXJhbSBmbiAtIFRoZSBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGl0ZW0uXG4gKiBAcGFyYW0gW3RoaXNBcmddIC0gVGhlIHZhbHVlIG9mIGB0aGlzYCBwcm92aWRlZCBmb3IgdGhlIGNhbGwgdG8gYGZuYC5cbiAqIEBwYXJhbSBbcmV2ZXJzZV0gLSBJZiB0cnVlLCBpdGVyYXRlcyBiYWNrd2FyZCBvbiB0aGUgbG9vcGFibGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlYWNoPFQsIFRBPihcbiAgbG9vcGFibGU6IFJlY29yZDxzdHJpbmcsIFQ+LFxuICBmbjogKHRoaXM6IFRBLCB2OiBULCBpOiBzdHJpbmcpID0+IHZvaWQsXG4gIHRoaXNBcmc/OiBUQSxcbiAgcmV2ZXJzZT86IGJvb2xlYW5cbik6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gZWFjaDxULCBUQT4oXG4gIGxvb3BhYmxlOiBUW10sXG4gIGZuOiAodGhpczogVEEsIHY6IFQsIGk6IG51bWJlcikgPT4gdm9pZCxcbiAgdGhpc0FyZz86IFRBLFxuICByZXZlcnNlPzogYm9vbGVhblxuKTogdm9pZDtcbmV4cG9ydCBmdW5jdGlvbiBlYWNoPFQsIFRBPihcbiAgbG9vcGFibGU6IFRbXSB8IFJlY29yZDxzdHJpbmcsIFQ+LFxuICBmbjogKHRoaXM6IFRBLCB2OiBULCBpOiBhbnkpID0+IHZvaWQsXG4gIHRoaXNBcmc/OiBUQSxcbiAgcmV2ZXJzZT86IGJvb2xlYW5cbikge1xuICBsZXQgaTogbnVtYmVyLCBsZW46IG51bWJlciwga2V5czogc3RyaW5nW107XG4gIGlmIChpc0FycmF5KGxvb3BhYmxlKSkge1xuICAgIGxlbiA9IGxvb3BhYmxlLmxlbmd0aDtcbiAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgZm4uY2FsbCh0aGlzQXJnLCBsb29wYWJsZVtpXSwgaSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBmbi5jYWxsKHRoaXNBcmcsIGxvb3BhYmxlW2ldLCBpKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobG9vcGFibGUpKSB7XG4gICAga2V5cyA9IE9iamVjdC5rZXlzKGxvb3BhYmxlKTtcbiAgICBsZW4gPSBrZXlzLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGZuLmNhbGwodGhpc0FyZywgbG9vcGFibGVba2V5c1tpXV0sIGtleXNbaV0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYGEwYCBhbmQgYGExYCBhcnJheXMgaGF2ZSB0aGUgc2FtZSBjb250ZW50LCBlbHNlIHJldHVybnMgZmFsc2UuXG4gKiBAcGFyYW0gYTAgLSBUaGUgYXJyYXkgdG8gY29tcGFyZVxuICogQHBhcmFtIGExIC0gVGhlIGFycmF5IHRvIGNvbXBhcmVcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfZWxlbWVudHNFcXVhbChhMDogQWN0aXZlRGF0YVBvaW50W10sIGExOiBBY3RpdmVEYXRhUG9pbnRbXSkge1xuICBsZXQgaTogbnVtYmVyLCBpbGVuOiBudW1iZXIsIHYwOiBBY3RpdmVEYXRhUG9pbnQsIHYxOiBBY3RpdmVEYXRhUG9pbnQ7XG5cbiAgaWYgKCFhMCB8fCAhYTEgfHwgYTAubGVuZ3RoICE9PSBhMS5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3IgKGkgPSAwLCBpbGVuID0gYTAubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgdjAgPSBhMFtpXTtcbiAgICB2MSA9IGExW2ldO1xuXG4gICAgaWYgKHYwLmRhdGFzZXRJbmRleCAhPT0gdjEuZGF0YXNldEluZGV4IHx8IHYwLmluZGV4ICE9PSB2MS5pbmRleCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBkZWVwIGNvcHkgb2YgYHNvdXJjZWAgd2l0aG91dCBrZWVwaW5nIHJlZmVyZW5jZXMgb24gb2JqZWN0cyBhbmQgYXJyYXlzLlxuICogQHBhcmFtIHNvdXJjZSAtIFRoZSB2YWx1ZSB0byBjbG9uZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lPFQ+KHNvdXJjZTogVCk6IFQge1xuICBpZiAoaXNBcnJheShzb3VyY2UpKSB7XG4gICAgcmV0dXJuIHNvdXJjZS5tYXAoY2xvbmUpIGFzIHVua25vd24gYXMgVDtcbiAgfVxuXG4gIGlmIChpc09iamVjdChzb3VyY2UpKSB7XG4gICAgY29uc3QgdGFyZ2V0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcbiAgICBjb25zdCBrbGVuID0ga2V5cy5sZW5ndGg7XG4gICAgbGV0IGsgPSAwO1xuXG4gICAgZm9yICg7IGsgPCBrbGVuOyArK2spIHtcbiAgICAgIHRhcmdldFtrZXlzW2tdXSA9IGNsb25lKHNvdXJjZVtrZXlzW2tdXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxuXG4gIHJldHVybiBzb3VyY2U7XG59XG5cbmZ1bmN0aW9uIGlzVmFsaWRLZXkoa2V5OiBzdHJpbmcpIHtcbiAgcmV0dXJuIFsnX19wcm90b19fJywgJ3Byb3RvdHlwZScsICdjb25zdHJ1Y3RvciddLmluZGV4T2Yoa2V5KSA9PT0gLTE7XG59XG5cbi8qKlxuICogVGhlIGRlZmF1bHQgbWVyZ2VyIHdoZW4gQ2hhcnQuaGVscGVycy5tZXJnZSBpcyBjYWxsZWQgd2l0aG91dCBtZXJnZXIgb3B0aW9uLlxuICogTm90ZShTQik6IGFsc28gdXNlZCBieSBtZXJnZUNvbmZpZyBhbmQgbWVyZ2VTY2FsZUNvbmZpZyBhcyBmYWxsYmFjay5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfbWVyZ2VyKGtleTogc3RyaW5nLCB0YXJnZXQ6IEFueU9iamVjdCwgc291cmNlOiBBbnlPYmplY3QsIG9wdGlvbnM6IEFueU9iamVjdCkge1xuICBpZiAoIWlzVmFsaWRLZXkoa2V5KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHR2YWwgPSB0YXJnZXRba2V5XTtcbiAgY29uc3Qgc3ZhbCA9IHNvdXJjZVtrZXldO1xuXG4gIGlmIChpc09iamVjdCh0dmFsKSAmJiBpc09iamVjdChzdmFsKSkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgICBtZXJnZSh0dmFsLCBzdmFsLCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICB0YXJnZXRba2V5XSA9IGNsb25lKHN2YWwpO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVyZ2VPcHRpb25zIHtcbiAgbWVyZ2VyPzogKGtleTogc3RyaW5nLCB0YXJnZXQ6IEFueU9iamVjdCwgc291cmNlOiBBbnlPYmplY3QsIG9wdGlvbnM/OiBBbnlPYmplY3QpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgZGVlcCBjb3BpZXMgYHNvdXJjZWAgcHJvcGVydGllcyBpbnRvIGB0YXJnZXRgIHdpdGggdGhlIGdpdmVuIGBvcHRpb25zYC5cbiAqIElNUE9SVEFOVDogYHRhcmdldGAgaXMgbm90IGNsb25lZCBhbmQgd2lsbCBiZSB1cGRhdGVkIHdpdGggYHNvdXJjZWAgcHJvcGVydGllcy5cbiAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgdGFyZ2V0IG9iamVjdCBpbiB3aGljaCBhbGwgc291cmNlcyBhcmUgbWVyZ2VkIGludG8uXG4gKiBAcGFyYW0gc291cmNlIC0gT2JqZWN0KHMpIHRvIG1lcmdlIGludG8gYHRhcmdldGAuXG4gKiBAcGFyYW0gW29wdGlvbnNdIC0gTWVyZ2luZyBvcHRpb25zOlxuICogQHBhcmFtIFtvcHRpb25zLm1lcmdlcl0gLSBUaGUgbWVyZ2UgbWV0aG9kIChrZXksIHRhcmdldCwgc291cmNlLCBvcHRpb25zKVxuICogQHJldHVybnMgVGhlIGB0YXJnZXRgIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlPFQ+KHRhcmdldDogVCwgc291cmNlOiBbXSwgb3B0aW9ucz86IE1lcmdlT3B0aW9ucyk6IFQ7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2U8VCwgUzE+KHRhcmdldDogVCwgc291cmNlOiBTMSwgb3B0aW9ucz86IE1lcmdlT3B0aW9ucyk6IFQgJiBTMTtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZTxULCBTMT4odGFyZ2V0OiBULCBzb3VyY2U6IFtTMV0sIG9wdGlvbnM/OiBNZXJnZU9wdGlvbnMpOiBUICYgUzE7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2U8VCwgUzEsIFMyPih0YXJnZXQ6IFQsIHNvdXJjZTogW1MxLCBTMl0sIG9wdGlvbnM/OiBNZXJnZU9wdGlvbnMpOiBUICYgUzEgJiBTMjtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZTxULCBTMSwgUzIsIFMzPih0YXJnZXQ6IFQsIHNvdXJjZTogW1MxLCBTMiwgUzNdLCBvcHRpb25zPzogTWVyZ2VPcHRpb25zKTogVCAmIFMxICYgUzIgJiBTMztcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZTxULCBTMSwgUzIsIFMzLCBTND4oXG4gIHRhcmdldDogVCxcbiAgc291cmNlOiBbUzEsIFMyLCBTMywgUzRdLFxuICBvcHRpb25zPzogTWVyZ2VPcHRpb25zXG4pOiBUICYgUzEgJiBTMiAmIFMzICYgUzQ7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2U8VD4odGFyZ2V0OiBULCBzb3VyY2U6IEFueU9iamVjdFtdLCBvcHRpb25zPzogTWVyZ2VPcHRpb25zKTogQW55T2JqZWN0O1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlPFQ+KHRhcmdldDogVCwgc291cmNlOiBBbnlPYmplY3RbXSwgb3B0aW9ucz86IE1lcmdlT3B0aW9ucyk6IEFueU9iamVjdCB7XG4gIGNvbnN0IHNvdXJjZXMgPSBpc0FycmF5KHNvdXJjZSkgPyBzb3VyY2UgOiBbc291cmNlXTtcbiAgY29uc3QgaWxlbiA9IHNvdXJjZXMubGVuZ3RoO1xuXG4gIGlmICghaXNPYmplY3QodGFyZ2V0KSkge1xuICAgIHJldHVybiB0YXJnZXQgYXMgQW55T2JqZWN0O1xuICB9XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGNvbnN0IG1lcmdlciA9IG9wdGlvbnMubWVyZ2VyIHx8IF9tZXJnZXI7XG4gIGxldCBjdXJyZW50OiBBbnlPYmplY3Q7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBjdXJyZW50ID0gc291cmNlc1tpXTtcbiAgICBpZiAoIWlzT2JqZWN0KGN1cnJlbnQpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoY3VycmVudCk7XG4gICAgZm9yIChsZXQgayA9IDAsIGtsZW4gPSBrZXlzLmxlbmd0aDsgayA8IGtsZW47ICsraykge1xuICAgICAgbWVyZ2VyKGtleXNba10sIHRhcmdldCwgY3VycmVudCwgb3B0aW9ucyBhcyBBbnlPYmplY3QpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgZGVlcCBjb3BpZXMgYHNvdXJjZWAgcHJvcGVydGllcyBpbnRvIGB0YXJnZXRgICpvbmx5KiBpZiBub3QgZGVmaW5lZCBpbiB0YXJnZXQuXG4gKiBJTVBPUlRBTlQ6IGB0YXJnZXRgIGlzIG5vdCBjbG9uZWQgYW5kIHdpbGwgYmUgdXBkYXRlZCB3aXRoIGBzb3VyY2VgIHByb3BlcnRpZXMuXG4gKiBAcGFyYW0gdGFyZ2V0IC0gVGhlIHRhcmdldCBvYmplY3QgaW4gd2hpY2ggYWxsIHNvdXJjZXMgYXJlIG1lcmdlZCBpbnRvLlxuICogQHBhcmFtIHNvdXJjZSAtIE9iamVjdChzKSB0byBtZXJnZSBpbnRvIGB0YXJnZXRgLlxuICogQHJldHVybnMgVGhlIGB0YXJnZXRgIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlSWY8VD4odGFyZ2V0OiBULCBzb3VyY2U6IFtdKTogVDtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUlmPFQsIFMxPih0YXJnZXQ6IFQsIHNvdXJjZTogUzEpOiBUICYgUzE7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VJZjxULCBTMT4odGFyZ2V0OiBULCBzb3VyY2U6IFtTMV0pOiBUICYgUzE7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VJZjxULCBTMSwgUzI+KHRhcmdldDogVCwgc291cmNlOiBbUzEsIFMyXSk6IFQgJiBTMSAmIFMyO1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlSWY8VCwgUzEsIFMyLCBTMz4odGFyZ2V0OiBULCBzb3VyY2U6IFtTMSwgUzIsIFMzXSk6IFQgJiBTMSAmIFMyICYgUzM7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VJZjxULCBTMSwgUzIsIFMzLCBTND4odGFyZ2V0OiBULCBzb3VyY2U6IFtTMSwgUzIsIFMzLCBTNF0pOiBUICYgUzEgJiBTMiAmIFMzICYgUzQ7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VJZjxUPih0YXJnZXQ6IFQsIHNvdXJjZTogQW55T2JqZWN0W10pOiBBbnlPYmplY3Q7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VJZjxUPih0YXJnZXQ6IFQsIHNvdXJjZTogQW55T2JqZWN0W10pOiBBbnlPYmplY3Qge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVzZS1iZWZvcmUtZGVmaW5lXG4gIHJldHVybiBtZXJnZTxUPih0YXJnZXQsIHNvdXJjZSwge21lcmdlcjogX21lcmdlcklmfSk7XG59XG5cbi8qKlxuICogTWVyZ2VzIHNvdXJjZVtrZXldIGluIHRhcmdldFtrZXldIG9ubHkgaWYgdGFyZ2V0W2tleV0gaXMgdW5kZWZpbmVkLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9tZXJnZXJJZihrZXk6IHN0cmluZywgdGFyZ2V0OiBBbnlPYmplY3QsIHNvdXJjZTogQW55T2JqZWN0KSB7XG4gIGlmICghaXNWYWxpZEtleShrZXkpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgdHZhbCA9IHRhcmdldFtrZXldO1xuICBjb25zdCBzdmFsID0gc291cmNlW2tleV07XG5cbiAgaWYgKGlzT2JqZWN0KHR2YWwpICYmIGlzT2JqZWN0KHN2YWwpKSB7XG4gICAgbWVyZ2VJZih0dmFsLCBzdmFsKTtcbiAgfSBlbHNlIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRhcmdldCwga2V5KSkge1xuICAgIHRhcmdldFtrZXldID0gY2xvbmUoc3ZhbCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2RlcHJlY2F0ZWQoc2NvcGU6IHN0cmluZywgdmFsdWU6IHVua25vd24sIHByZXZpb3VzOiBzdHJpbmcsIGN1cnJlbnQ6IHN0cmluZykge1xuICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnNvbGUud2FybihzY29wZSArICc6IFwiJyArIHByZXZpb3VzICtcbiAgICAgICdcIiBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIFwiJyArIGN1cnJlbnQgKyAnXCIgaW5zdGVhZCcpO1xuICB9XG59XG5cbi8vIHJlc29sdmVPYmplY3RLZXkgcmVzb2x2ZXIgY2FjaGVcbmNvbnN0IGtleVJlc29sdmVycyA9IHtcbiAgLy8gQ2hhcnQuaGVscGVycy5jb3JlIHJlc29sdmVPYmplY3RLZXkgc2hvdWxkIHJlc29sdmUgZW1wdHkga2V5IHRvIHJvb3Qgb2JqZWN0XG4gICcnOiB2ID0+IHYsXG4gIC8vIGRlZmF1bHQgcmVzb2x2ZXJzXG4gIHg6IG8gPT4gby54LFxuICB5OiBvID0+IG8ueVxufTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX3NwbGl0S2V5KGtleTogc3RyaW5nKSB7XG4gIGNvbnN0IHBhcnRzID0ga2V5LnNwbGl0KCcuJyk7XG4gIGNvbnN0IGtleXM6IHN0cmluZ1tdID0gW107XG4gIGxldCB0bXAgPSAnJztcbiAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgdG1wICs9IHBhcnQ7XG4gICAgaWYgKHRtcC5lbmRzV2l0aCgnXFxcXCcpKSB7XG4gICAgICB0bXAgPSB0bXAuc2xpY2UoMCwgLTEpICsgJy4nO1xuICAgIH0gZWxzZSB7XG4gICAgICBrZXlzLnB1c2godG1wKTtcbiAgICAgIHRtcCA9ICcnO1xuICAgIH1cbiAgfVxuICByZXR1cm4ga2V5cztcbn1cblxuZnVuY3Rpb24gX2dldEtleVJlc29sdmVyKGtleTogc3RyaW5nKSB7XG4gIGNvbnN0IGtleXMgPSBfc3BsaXRLZXkoa2V5KTtcbiAgcmV0dXJuIG9iaiA9PiB7XG4gICAgZm9yIChjb25zdCBrIG9mIGtleXMpIHtcbiAgICAgIGlmIChrID09PSAnJykge1xuICAgICAgICAvLyBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eTpcbiAgICAgICAgLy8gQ2hhcnQuaGVscGVycy5jb3JlIHJlc29sdmVPYmplY3RLZXkgc2hvdWxkIGJyZWFrIGF0IGVtcHR5IGtleVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIG9iaiA9IG9iaiAmJiBvYmpba107XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlT2JqZWN0S2V5KG9iajogQW55T2JqZWN0LCBrZXk6IHN0cmluZyk6IGFueSB7XG4gIGNvbnN0IHJlc29sdmVyID0ga2V5UmVzb2x2ZXJzW2tleV0gfHwgKGtleVJlc29sdmVyc1trZXldID0gX2dldEtleVJlc29sdmVyKGtleSkpO1xuICByZXR1cm4gcmVzb2x2ZXIob2JqKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2NhcGl0YWxpemUoc3RyOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKTtcbn1cblxuXG5leHBvcnQgY29uc3QgZGVmaW5lZCA9ICh2YWx1ZTogdW5rbm93bikgPT4gdHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJztcblxuZXhwb3J0IGNvbnN0IGlzRnVuY3Rpb24gPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyAoLi4uYXJnczogYW55W10pID0+IGFueSA9PiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbic7XG5cbi8vIEFkYXB0ZWQgZnJvbSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zMTEyODg1NS9jb21wYXJpbmctZWNtYTYtc2V0cy1mb3ItZXF1YWxpdHkjMzExMjkzODRcbmV4cG9ydCBjb25zdCBzZXRzRXF1YWwgPSA8VD4oYTogU2V0PFQ+LCBiOiBTZXQ8VD4pID0+IHtcbiAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yIChjb25zdCBpdGVtIG9mIGEpIHtcbiAgICBpZiAoIWIuaGFzKGl0ZW0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIEBwYXJhbSBlIC0gVGhlIGV2ZW50XG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2lzQ2xpY2tFdmVudChlOiBDaGFydEV2ZW50KSB7XG4gIHJldHVybiBlLnR5cGUgPT09ICdtb3VzZXVwJyB8fCBlLnR5cGUgPT09ICdjbGljaycgfHwgZS50eXBlID09PSAnY29udGV4dG1lbnUnO1xufVxuIiwgImltcG9ydCB0eXBlIHtQb2ludH0gZnJvbSAnLi4vdHlwZXMvZ2VvbWV0cmljLmpzJztcbmltcG9ydCB7aXNGaW5pdGUgYXMgaXNGaW5pdGVOdW1iZXJ9IGZyb20gJy4vaGVscGVycy5jb3JlLmpzJztcblxuLyoqXG4gKiBAYWxpYXMgQ2hhcnQuaGVscGVycy5tYXRoXG4gKiBAbmFtZXNwYWNlXG4gKi9cblxuZXhwb3J0IGNvbnN0IFBJID0gTWF0aC5QSTtcbmV4cG9ydCBjb25zdCBUQVUgPSAyICogUEk7XG5leHBvcnQgY29uc3QgUElUQVUgPSBUQVUgKyBQSTtcbmV4cG9ydCBjb25zdCBJTkZJTklUWSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbmV4cG9ydCBjb25zdCBSQURfUEVSX0RFRyA9IFBJIC8gMTgwO1xuZXhwb3J0IGNvbnN0IEhBTEZfUEkgPSBQSSAvIDI7XG5leHBvcnQgY29uc3QgUVVBUlRFUl9QSSA9IFBJIC8gNDtcbmV4cG9ydCBjb25zdCBUV09fVEhJUkRTX1BJID0gUEkgKiAyIC8gMztcblxuZXhwb3J0IGNvbnN0IGxvZzEwID0gTWF0aC5sb2cxMDtcbmV4cG9ydCBjb25zdCBzaWduID0gTWF0aC5zaWduO1xuXG5leHBvcnQgZnVuY3Rpb24gYWxtb3N0RXF1YWxzKHg6IG51bWJlciwgeTogbnVtYmVyLCBlcHNpbG9uOiBudW1iZXIpIHtcbiAgcmV0dXJuIE1hdGguYWJzKHggLSB5KSA8IGVwc2lsb247XG59XG5cbi8qKlxuICogSW1wbGVtZW50YXRpb24gb2YgdGhlIG5pY2UgbnVtYmVyIGFsZ29yaXRobSB1c2VkIGluIGRldGVybWluaW5nIHdoZXJlIGF4aXMgbGFiZWxzIHdpbGwgZ29cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5pY2VOdW0ocmFuZ2U6IG51bWJlcikge1xuICBjb25zdCByb3VuZGVkUmFuZ2UgPSBNYXRoLnJvdW5kKHJhbmdlKTtcbiAgcmFuZ2UgPSBhbG1vc3RFcXVhbHMocmFuZ2UsIHJvdW5kZWRSYW5nZSwgcmFuZ2UgLyAxMDAwKSA/IHJvdW5kZWRSYW5nZSA6IHJhbmdlO1xuICBjb25zdCBuaWNlUmFuZ2UgPSBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihsb2cxMChyYW5nZSkpKTtcbiAgY29uc3QgZnJhY3Rpb24gPSByYW5nZSAvIG5pY2VSYW5nZTtcbiAgY29uc3QgbmljZUZyYWN0aW9uID0gZnJhY3Rpb24gPD0gMSA/IDEgOiBmcmFjdGlvbiA8PSAyID8gMiA6IGZyYWN0aW9uIDw9IDUgPyA1IDogMTA7XG4gIHJldHVybiBuaWNlRnJhY3Rpb24gKiBuaWNlUmFuZ2U7XG59XG5cbi8qKlxuICogUmV0dXJucyBhbiBhcnJheSBvZiBmYWN0b3JzIHNvcnRlZCBmcm9tIDEgdG8gc3FydCh2YWx1ZSlcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfZmFjdG9yaXplKHZhbHVlOiBudW1iZXIpIHtcbiAgY29uc3QgcmVzdWx0OiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBzcXJ0ID0gTWF0aC5zcXJ0KHZhbHVlKTtcbiAgbGV0IGk6IG51bWJlcjtcblxuICBmb3IgKGkgPSAxOyBpIDwgc3FydDsgaSsrKSB7XG4gICAgaWYgKHZhbHVlICUgaSA9PT0gMCkge1xuICAgICAgcmVzdWx0LnB1c2goaSk7XG4gICAgICByZXN1bHQucHVzaCh2YWx1ZSAvIGkpO1xuICAgIH1cbiAgfVxuICBpZiAoc3FydCA9PT0gKHNxcnQgfCAwKSkgeyAvLyBpZiB2YWx1ZSBpcyBhIHNxdWFyZSBudW1iZXJcbiAgICByZXN1bHQucHVzaChzcXJ0KTtcbiAgfVxuXG4gIHJlc3VsdC5zb3J0KChhLCBiKSA9PiBhIC0gYikucG9wKCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcihuOiB1bmtub3duKTogbiBpcyBudW1iZXIge1xuICByZXR1cm4gIWlzTmFOKHBhcnNlRmxvYXQobiBhcyBzdHJpbmcpKSAmJiBpc0Zpbml0ZShuIGFzIG51bWJlcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbG1vc3RXaG9sZSh4OiBudW1iZXIsIGVwc2lsb246IG51bWJlcikge1xuICBjb25zdCByb3VuZGVkID0gTWF0aC5yb3VuZCh4KTtcbiAgcmV0dXJuICgocm91bmRlZCAtIGVwc2lsb24pIDw9IHgpICYmICgocm91bmRlZCArIGVwc2lsb24pID49IHgpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc2V0TWluQW5kTWF4QnlLZXkoXG4gIGFycmF5OiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+W10sXG4gIHRhcmdldDogeyBtaW46IG51bWJlciwgbWF4OiBudW1iZXIgfSxcbiAgcHJvcGVydHk6IHN0cmluZ1xuKSB7XG4gIGxldCBpOiBudW1iZXIsIGlsZW46IG51bWJlciwgdmFsdWU6IG51bWJlcjtcblxuICBmb3IgKGkgPSAwLCBpbGVuID0gYXJyYXkubGVuZ3RoOyBpIDwgaWxlbjsgaSsrKSB7XG4gICAgdmFsdWUgPSBhcnJheVtpXVtwcm9wZXJ0eV07XG4gICAgaWYgKCFpc05hTih2YWx1ZSkpIHtcbiAgICAgIHRhcmdldC5taW4gPSBNYXRoLm1pbih0YXJnZXQubWluLCB2YWx1ZSk7XG4gICAgICB0YXJnZXQubWF4ID0gTWF0aC5tYXgodGFyZ2V0Lm1heCwgdmFsdWUpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9SYWRpYW5zKGRlZ3JlZXM6IG51bWJlcikge1xuICByZXR1cm4gZGVncmVlcyAqIChQSSAvIDE4MCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b0RlZ3JlZXMocmFkaWFuczogbnVtYmVyKSB7XG4gIHJldHVybiByYWRpYW5zICogKDE4MCAvIFBJKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXNcbiAqIGkuZS4gdGhlIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQsIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIE51bWJlci5cbiAqIEBwYXJhbSB4IC0gQSBudW1iZXIuXG4gKiBAcmV0dXJucyBUaGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9kZWNpbWFsUGxhY2VzKHg6IG51bWJlcikge1xuICBpZiAoIWlzRmluaXRlTnVtYmVyKHgpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBlID0gMTtcbiAgbGV0IHAgPSAwO1xuICB3aGlsZSAoTWF0aC5yb3VuZCh4ICogZSkgLyBlICE9PSB4KSB7XG4gICAgZSAqPSAxMDtcbiAgICBwKys7XG4gIH1cbiAgcmV0dXJuIHA7XG59XG5cbi8vIEdldHMgdGhlIGFuZ2xlIGZyb20gdmVydGljYWwgdXByaWdodCB0byB0aGUgcG9pbnQgYWJvdXQgYSBjZW50cmUuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QW5nbGVGcm9tUG9pbnQoXG4gIGNlbnRyZVBvaW50OiBQb2ludCxcbiAgYW5nbGVQb2ludDogUG9pbnRcbikge1xuICBjb25zdCBkaXN0YW5jZUZyb21YQ2VudGVyID0gYW5nbGVQb2ludC54IC0gY2VudHJlUG9pbnQueDtcbiAgY29uc3QgZGlzdGFuY2VGcm9tWUNlbnRlciA9IGFuZ2xlUG9pbnQueSAtIGNlbnRyZVBvaW50Lnk7XG4gIGNvbnN0IHJhZGlhbERpc3RhbmNlRnJvbUNlbnRlciA9IE1hdGguc3FydChkaXN0YW5jZUZyb21YQ2VudGVyICogZGlzdGFuY2VGcm9tWENlbnRlciArIGRpc3RhbmNlRnJvbVlDZW50ZXIgKiBkaXN0YW5jZUZyb21ZQ2VudGVyKTtcblxuICBsZXQgYW5nbGUgPSBNYXRoLmF0YW4yKGRpc3RhbmNlRnJvbVlDZW50ZXIsIGRpc3RhbmNlRnJvbVhDZW50ZXIpO1xuXG4gIGlmIChhbmdsZSA8ICgtMC41ICogUEkpKSB7XG4gICAgYW5nbGUgKz0gVEFVOyAvLyBtYWtlIHN1cmUgdGhlIHJldHVybmVkIGFuZ2xlIGlzIGluIHRoZSByYW5nZSBvZiAoLVBJLzIsIDNQSS8yXVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBhbmdsZSxcbiAgICBkaXN0YW5jZTogcmFkaWFsRGlzdGFuY2VGcm9tQ2VudGVyXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkaXN0YW5jZUJldHdlZW5Qb2ludHMocHQxOiBQb2ludCwgcHQyOiBQb2ludCkge1xuICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHB0Mi54IC0gcHQxLngsIDIpICsgTWF0aC5wb3cocHQyLnkgLSBwdDEueSwgMikpO1xufVxuXG4vKipcbiAqIFNob3J0ZXN0IGRpc3RhbmNlIGJldHdlZW4gYW5nbGVzLCBpbiBlaXRoZXIgZGlyZWN0aW9uLlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9hbmdsZURpZmYoYTogbnVtYmVyLCBiOiBudW1iZXIpIHtcbiAgcmV0dXJuIChhIC0gYiArIFBJVEFVKSAlIFRBVSAtIFBJO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBhbmdsZSB0byBiZSBiZXR3ZWVuIDAgYW5kIDIqUElcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfbm9ybWFsaXplQW5nbGUoYTogbnVtYmVyKSB7XG4gIHJldHVybiAoYSAlIFRBVSArIFRBVSkgJSBUQVU7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9hbmdsZUJldHdlZW4oYW5nbGU6IG51bWJlciwgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIsIHNhbWVBbmdsZUlzRnVsbENpcmNsZT86IGJvb2xlYW4pIHtcbiAgY29uc3QgYSA9IF9ub3JtYWxpemVBbmdsZShhbmdsZSk7XG4gIGNvbnN0IHMgPSBfbm9ybWFsaXplQW5nbGUoc3RhcnQpO1xuICBjb25zdCBlID0gX25vcm1hbGl6ZUFuZ2xlKGVuZCk7XG4gIGNvbnN0IGFuZ2xlVG9TdGFydCA9IF9ub3JtYWxpemVBbmdsZShzIC0gYSk7XG4gIGNvbnN0IGFuZ2xlVG9FbmQgPSBfbm9ybWFsaXplQW5nbGUoZSAtIGEpO1xuICBjb25zdCBzdGFydFRvQW5nbGUgPSBfbm9ybWFsaXplQW5nbGUoYSAtIHMpO1xuICBjb25zdCBlbmRUb0FuZ2xlID0gX25vcm1hbGl6ZUFuZ2xlKGEgLSBlKTtcbiAgcmV0dXJuIGEgPT09IHMgfHwgYSA9PT0gZSB8fCAoc2FtZUFuZ2xlSXNGdWxsQ2lyY2xlICYmIHMgPT09IGUpXG4gICAgfHwgKGFuZ2xlVG9TdGFydCA+IGFuZ2xlVG9FbmQgJiYgc3RhcnRUb0FuZ2xlIDwgZW5kVG9BbmdsZSk7XG59XG5cbi8qKlxuICogTGltaXQgYHZhbHVlYCBiZXR3ZWVuIGBtaW5gIGFuZCBgbWF4YFxuICogQHBhcmFtIHZhbHVlXG4gKiBAcGFyYW0gbWluXG4gKiBAcGFyYW0gbWF4XG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2xpbWl0VmFsdWUodmFsdWU6IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKSB7XG4gIHJldHVybiBNYXRoLm1heChtaW4sIE1hdGgubWluKG1heCwgdmFsdWUpKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfaW50MTZSYW5nZSh2YWx1ZTogbnVtYmVyKSB7XG4gIHJldHVybiBfbGltaXRWYWx1ZSh2YWx1ZSwgLTMyNzY4LCAzMjc2Nyk7XG59XG5cbi8qKlxuICogQHBhcmFtIHZhbHVlXG4gKiBAcGFyYW0gc3RhcnRcbiAqIEBwYXJhbSBlbmRcbiAqIEBwYXJhbSBbZXBzaWxvbl1cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfaXNCZXR3ZWVuKHZhbHVlOiBudW1iZXIsIHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyLCBlcHNpbG9uID0gMWUtNikge1xuICByZXR1cm4gdmFsdWUgPj0gTWF0aC5taW4oc3RhcnQsIGVuZCkgLSBlcHNpbG9uICYmIHZhbHVlIDw9IE1hdGgubWF4KHN0YXJ0LCBlbmQpICsgZXBzaWxvbjtcbn1cbiIsICJpbXBvcnQge19jYXBpdGFsaXplfSBmcm9tICcuL2hlbHBlcnMuY29yZS5qcyc7XG5cbi8qKlxuICogQmluYXJ5IHNlYXJjaFxuICogQHBhcmFtIHRhYmxlIC0gdGhlIHRhYmxlIHNlYXJjaC4gbXVzdCBiZSBzb3J0ZWQhXG4gKiBAcGFyYW0gdmFsdWUgLSB2YWx1ZSB0byBmaW5kXG4gKiBAcGFyYW0gY21wXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2xvb2t1cChcbiAgdGFibGU6IG51bWJlcltdLFxuICB2YWx1ZTogbnVtYmVyLFxuICBjbXA/OiAodmFsdWU6IG51bWJlcikgPT4gYm9vbGVhblxuKToge2xvOiBudW1iZXIsIGhpOiBudW1iZXJ9O1xuZXhwb3J0IGZ1bmN0aW9uIF9sb29rdXA8VD4oXG4gIHRhYmxlOiBUW10sXG4gIHZhbHVlOiBudW1iZXIsXG4gIGNtcDogKHZhbHVlOiBudW1iZXIpID0+IGJvb2xlYW5cbik6IHtsbzogbnVtYmVyLCBoaTogbnVtYmVyfTtcbmV4cG9ydCBmdW5jdGlvbiBfbG9va3VwKFxuICB0YWJsZTogdW5rbm93bltdLFxuICB2YWx1ZTogbnVtYmVyLFxuICBjbXA/OiAodmFsdWU6IG51bWJlcikgPT4gYm9vbGVhblxuKSB7XG4gIGNtcCA9IGNtcCB8fCAoKGluZGV4KSA9PiB0YWJsZVtpbmRleF0gPCB2YWx1ZSk7XG4gIGxldCBoaSA9IHRhYmxlLmxlbmd0aCAtIDE7XG4gIGxldCBsbyA9IDA7XG4gIGxldCBtaWQ6IG51bWJlcjtcblxuICB3aGlsZSAoaGkgLSBsbyA+IDEpIHtcbiAgICBtaWQgPSAobG8gKyBoaSkgPj4gMTtcbiAgICBpZiAoY21wKG1pZCkpIHtcbiAgICAgIGxvID0gbWlkO1xuICAgIH0gZWxzZSB7XG4gICAgICBoaSA9IG1pZDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge2xvLCBoaX07XG59XG5cbi8qKlxuICogQmluYXJ5IHNlYXJjaFxuICogQHBhcmFtIHRhYmxlIC0gdGhlIHRhYmxlIHNlYXJjaC4gbXVzdCBiZSBzb3J0ZWQhXG4gKiBAcGFyYW0ga2V5IC0gcHJvcGVydHkgbmFtZSBmb3IgdGhlIHZhbHVlIGluIGVhY2ggZW50cnlcbiAqIEBwYXJhbSB2YWx1ZSAtIHZhbHVlIHRvIGZpbmRcbiAqIEBwYXJhbSBsYXN0IC0gbG9va3VwIGxhc3QgaW5kZXhcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjb25zdCBfbG9va3VwQnlLZXkgPSAoXG4gIHRhYmxlOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+W10sXG4gIGtleTogc3RyaW5nLFxuICB2YWx1ZTogbnVtYmVyLFxuICBsYXN0PzogYm9vbGVhblxuKSA9PlxuICBfbG9va3VwKHRhYmxlLCB2YWx1ZSwgbGFzdFxuICAgID8gaW5kZXggPT4ge1xuICAgICAgY29uc3QgdGkgPSB0YWJsZVtpbmRleF1ba2V5XTtcbiAgICAgIHJldHVybiB0aSA8IHZhbHVlIHx8IHRpID09PSB2YWx1ZSAmJiB0YWJsZVtpbmRleCArIDFdW2tleV0gPT09IHZhbHVlO1xuICAgIH1cbiAgICA6IGluZGV4ID0+IHRhYmxlW2luZGV4XVtrZXldIDwgdmFsdWUpO1xuXG4vKipcbiAqIFJldmVyc2UgYmluYXJ5IHNlYXJjaFxuICogQHBhcmFtIHRhYmxlIC0gdGhlIHRhYmxlIHNlYXJjaC4gbXVzdCBiZSBzb3J0ZWQhXG4gKiBAcGFyYW0ga2V5IC0gcHJvcGVydHkgbmFtZSBmb3IgdGhlIHZhbHVlIGluIGVhY2ggZW50cnlcbiAqIEBwYXJhbSB2YWx1ZSAtIHZhbHVlIHRvIGZpbmRcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjb25zdCBfcmxvb2t1cEJ5S2V5ID0gKFxuICB0YWJsZTogUmVjb3JkPHN0cmluZywgbnVtYmVyPltdLFxuICBrZXk6IHN0cmluZyxcbiAgdmFsdWU6IG51bWJlclxuKSA9PlxuICBfbG9va3VwKHRhYmxlLCB2YWx1ZSwgaW5kZXggPT4gdGFibGVbaW5kZXhdW2tleV0gPj0gdmFsdWUpO1xuXG4vKipcbiAqIFJldHVybiBzdWJzZXQgb2YgYHZhbHVlc2AgYmV0d2VlbiBgbWluYCBhbmQgYG1heGAgaW5jbHVzaXZlLlxuICogVmFsdWVzIGFyZSBhc3N1bWVkIHRvIGJlIGluIHNvcnRlZCBvcmRlci5cbiAqIEBwYXJhbSB2YWx1ZXMgLSBzb3J0ZWQgYXJyYXkgb2YgdmFsdWVzXG4gKiBAcGFyYW0gbWluIC0gbWluIHZhbHVlXG4gKiBAcGFyYW0gbWF4IC0gbWF4IHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfZmlsdGVyQmV0d2Vlbih2YWx1ZXM6IG51bWJlcltdLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIpIHtcbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGVuZCA9IHZhbHVlcy5sZW5ndGg7XG5cbiAgd2hpbGUgKHN0YXJ0IDwgZW5kICYmIHZhbHVlc1tzdGFydF0gPCBtaW4pIHtcbiAgICBzdGFydCsrO1xuICB9XG4gIHdoaWxlIChlbmQgPiBzdGFydCAmJiB2YWx1ZXNbZW5kIC0gMV0gPiBtYXgpIHtcbiAgICBlbmQtLTtcbiAgfVxuXG4gIHJldHVybiBzdGFydCA+IDAgfHwgZW5kIDwgdmFsdWVzLmxlbmd0aFxuICAgID8gdmFsdWVzLnNsaWNlKHN0YXJ0LCBlbmQpXG4gICAgOiB2YWx1ZXM7XG59XG5cbmNvbnN0IGFycmF5RXZlbnRzID0gWydwdXNoJywgJ3BvcCcsICdzaGlmdCcsICdzcGxpY2UnLCAndW5zaGlmdCddIGFzIGNvbnN0O1xuXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5TGlzdGVuZXI8VD4ge1xuICBfb25EYXRhUHVzaD8oLi4uaXRlbTogVFtdKTogdm9pZDtcbiAgX29uRGF0YVBvcD8oKTogdm9pZDtcbiAgX29uRGF0YVNoaWZ0PygpOiB2b2lkO1xuICBfb25EYXRhU3BsaWNlPyhpbmRleDogbnVtYmVyLCBkZWxldGVDb3VudDogbnVtYmVyLCAuLi5pdGVtczogVFtdKTogdm9pZDtcbiAgX29uRGF0YVVuc2hpZnQ/KC4uLml0ZW06IFRbXSk6IHZvaWQ7XG59XG5cbi8qKlxuICogSG9va3MgdGhlIGFycmF5IG1ldGhvZHMgdGhhdCBhZGQgb3IgcmVtb3ZlIHZhbHVlcyAoJ3B1c2gnLCBwb3AnLCAnc2hpZnQnLCAnc3BsaWNlJyxcbiAqICd1bnNoaWZ0JykgYW5kIG5vdGlmeSB0aGUgbGlzdGVuZXIgQUZURVIgdGhlIGFycmF5IGhhcyBiZWVuIGFsdGVyZWQuIExpc3RlbmVycyBhcmVcbiAqIGNhbGxlZCBvbiB0aGUgJ19vbkRhdGEqJyBjYWxsYmFja3MgKGUuZy4gX29uRGF0YVB1c2gsIGV0Yy4pIHdpdGggc2FtZSBhcmd1bWVudHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXN0ZW5BcnJheUV2ZW50czxUPihhcnJheTogVFtdLCBsaXN0ZW5lcjogQXJyYXlMaXN0ZW5lcjxUPik6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gbGlzdGVuQXJyYXlFdmVudHMoYXJyYXksIGxpc3RlbmVyKSB7XG4gIGlmIChhcnJheS5fY2hhcnRqcykge1xuICAgIGFycmF5Ll9jaGFydGpzLmxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXJyYXksICdfY2hhcnRqcycsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IHtcbiAgICAgIGxpc3RlbmVyczogW2xpc3RlbmVyXVxuICAgIH1cbiAgfSk7XG5cbiAgYXJyYXlFdmVudHMuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgY29uc3QgbWV0aG9kID0gJ19vbkRhdGEnICsgX2NhcGl0YWxpemUoa2V5KTtcbiAgICBjb25zdCBiYXNlID0gYXJyYXlba2V5XTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcnJheSwga2V5LCB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHZhbHVlKC4uLmFyZ3MpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYmFzZS5hcHBseSh0aGlzLCBhcmdzKTtcblxuICAgICAgICBhcnJheS5fY2hhcnRqcy5saXN0ZW5lcnMuZm9yRWFjaCgob2JqZWN0KSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3RbbWV0aG9kXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgb2JqZWN0W21ldGhvZF0oLi4uYXJncyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIGdpdmVuIGFycmF5IGV2ZW50IGxpc3RlbmVyIGFuZCBjbGVhbnVwIGV4dHJhIGF0dGFjaGVkIHByb3BlcnRpZXMgKHN1Y2ggYXNcbiAqIHRoZSBfY2hhcnRqcyBzdHViIGFuZCBvdmVycmlkZGVuIG1ldGhvZHMpIGlmIGFycmF5IGRvZXNuJ3QgaGF2ZSBhbnkgbW9yZSBsaXN0ZW5lcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bmxpc3RlbkFycmF5RXZlbnRzPFQ+KGFycmF5OiBUW10sIGxpc3RlbmVyOiBBcnJheUxpc3RlbmVyPFQ+KTogdm9pZDtcbmV4cG9ydCBmdW5jdGlvbiB1bmxpc3RlbkFycmF5RXZlbnRzKGFycmF5LCBsaXN0ZW5lcikge1xuICBjb25zdCBzdHViID0gYXJyYXkuX2NoYXJ0anM7XG4gIGlmICghc3R1Yikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGxpc3RlbmVycyA9IHN0dWIubGlzdGVuZXJzO1xuICBjb25zdCBpbmRleCA9IGxpc3RlbmVycy5pbmRleE9mKGxpc3RlbmVyKTtcbiAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgIGxpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuICB9XG5cbiAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgYXJyYXlFdmVudHMuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgZGVsZXRlIGFycmF5W2tleV07XG4gIH0pO1xuXG4gIGRlbGV0ZSBhcnJheS5fY2hhcnRqcztcbn1cblxuLyoqXG4gKiBAcGFyYW0gaXRlbXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9hcnJheVVuaXF1ZTxUPihpdGVtczogVFtdKSB7XG4gIGNvbnN0IHNldCA9IG5ldyBTZXQ8VD4oaXRlbXMpO1xuXG4gIGlmIChzZXQuc2l6ZSA9PT0gaXRlbXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGl0ZW1zO1xuICB9XG5cbiAgcmV0dXJuIEFycmF5LmZyb20oc2V0KTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7Q2hhcnRNZXRhLCBQb2ludEVsZW1lbnR9IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcblxuaW1wb3J0IHtfbGltaXRWYWx1ZX0gZnJvbSAnLi9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IHtfbG9va3VwQnlLZXl9IGZyb20gJy4vaGVscGVycy5jb2xsZWN0aW9uLmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGZvbnRTdHJpbmcocGl4ZWxTaXplOiBudW1iZXIsIGZvbnRTdHlsZTogc3RyaW5nLCBmb250RmFtaWx5OiBzdHJpbmcpIHtcbiAgcmV0dXJuIGZvbnRTdHlsZSArICcgJyArIHBpeGVsU2l6ZSArICdweCAnICsgZm9udEZhbWlseTtcbn1cblxuLyoqXG4qIFJlcXVlc3QgYW5pbWF0aW9uIHBvbHlmaWxsXG4qL1xuZXhwb3J0IGNvbnN0IHJlcXVlc3RBbmltRnJhbWUgPSAoZnVuY3Rpb24oKSB7XG4gIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZTtcbn0oKSk7XG5cbi8qKlxuICogVGhyb3R0bGVzIGNhbGxpbmcgYGZuYCBvbmNlIHBlciBhbmltYXRpb24gZnJhbWVcbiAqIExhdGVzdCBhcmd1bWVudHMgYXJlIHVzZWQgb24gdGhlIGFjdHVhbCBjYWxsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0aHJvdHRsZWQ8VEFyZ3MgZXh0ZW5kcyBBcnJheTxhbnk+PihcbiAgZm46ICguLi5hcmdzOiBUQXJncykgPT4gdm9pZCxcbiAgdGhpc0FyZzogYW55LFxuKSB7XG4gIGxldCBhcmdzVG9Vc2UgPSBbXSBhcyBUQXJncztcbiAgbGV0IHRpY2tpbmcgPSBmYWxzZTtcblxuICByZXR1cm4gZnVuY3Rpb24oLi4uYXJnczogVEFyZ3MpIHtcbiAgICAvLyBTYXZlIHRoZSBhcmdzIGZvciB1c2UgbGF0ZXJcbiAgICBhcmdzVG9Vc2UgPSBhcmdzO1xuICAgIGlmICghdGlja2luZykge1xuICAgICAgdGlja2luZyA9IHRydWU7XG4gICAgICByZXF1ZXN0QW5pbUZyYW1lLmNhbGwod2luZG93LCAoKSA9PiB7XG4gICAgICAgIHRpY2tpbmcgPSBmYWxzZTtcbiAgICAgICAgZm4uYXBwbHkodGhpc0FyZywgYXJnc1RvVXNlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBEZWJvdW5jZXMgY2FsbGluZyBgZm5gIGZvciBgZGVsYXlgIG1zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWJvdW5jZTxUQXJncyBleHRlbmRzIEFycmF5PGFueT4+KGZuOiAoLi4uYXJnczogVEFyZ3MpID0+IHZvaWQsIGRlbGF5OiBudW1iZXIpIHtcbiAgbGV0IHRpbWVvdXQ7XG4gIHJldHVybiBmdW5jdGlvbiguLi5hcmdzOiBUQXJncykge1xuICAgIGlmIChkZWxheSkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQoZm4sIGRlbGF5LCBhcmdzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIHJldHVybiBkZWxheTtcbiAgfTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyAnc3RhcnQnIHRvICdsZWZ0JywgJ2VuZCcgdG8gJ3JpZ2h0JyBhbmQgb3RoZXJzIHRvICdjZW50ZXInXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY29uc3QgX3RvTGVmdFJpZ2h0Q2VudGVyID0gKGFsaWduOiAnc3RhcnQnIHwgJ2VuZCcgfCAnY2VudGVyJykgPT4gYWxpZ24gPT09ICdzdGFydCcgPyAnbGVmdCcgOiBhbGlnbiA9PT0gJ2VuZCcgPyAncmlnaHQnIDogJ2NlbnRlcic7XG5cbi8qKlxuICogUmV0dXJucyBgc3RhcnRgLCBgZW5kYCBvciBgKHN0YXJ0ICsgZW5kKSAvIDJgIGRlcGVuZGluZyBvbiBgYWxpZ25gLiBEZWZhdWx0cyB0byBgY2VudGVyYFxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IF9hbGlnblN0YXJ0RW5kID0gKGFsaWduOiAnc3RhcnQnIHwgJ2VuZCcgfCAnY2VudGVyJywgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIpID0+IGFsaWduID09PSAnc3RhcnQnID8gc3RhcnQgOiBhbGlnbiA9PT0gJ2VuZCcgPyBlbmQgOiAoc3RhcnQgKyBlbmQpIC8gMjtcblxuLyoqXG4gKiBSZXR1cm5zIGBsZWZ0YCwgYHJpZ2h0YCBvciBgKGxlZnQgKyByaWdodCkgLyAyYCBkZXBlbmRpbmcgb24gYGFsaWduYC4gRGVmYXVsdHMgdG8gYGxlZnRgXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY29uc3QgX3RleHRYID0gKGFsaWduOiAnbGVmdCcgfCAncmlnaHQnIHwgJ2NlbnRlcicsIGxlZnQ6IG51bWJlciwgcmlnaHQ6IG51bWJlciwgcnRsOiBib29sZWFuKSA9PiB7XG4gIGNvbnN0IGNoZWNrID0gcnRsID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgcmV0dXJuIGFsaWduID09PSBjaGVjayA/IHJpZ2h0IDogYWxpZ24gPT09ICdjZW50ZXInID8gKGxlZnQgKyByaWdodCkgLyAyIDogbGVmdDtcbn07XG5cbi8qKlxuICogUmV0dXJuIHN0YXJ0IGFuZCBjb3VudCBvZiB2aXNpYmxlIHBvaW50cy5cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfZ2V0U3RhcnRBbmRDb3VudE9mVmlzaWJsZVBvaW50cyhtZXRhOiBDaGFydE1ldGE8J2xpbmUnIHwgJ3NjYXR0ZXInPiwgcG9pbnRzOiBQb2ludEVsZW1lbnRbXSwgYW5pbWF0aW9uc0Rpc2FibGVkOiBib29sZWFuKSB7XG4gIGNvbnN0IHBvaW50Q291bnQgPSBwb2ludHMubGVuZ3RoO1xuXG4gIGxldCBzdGFydCA9IDA7XG4gIGxldCBjb3VudCA9IHBvaW50Q291bnQ7XG5cbiAgaWYgKG1ldGEuX3NvcnRlZCkge1xuICAgIGNvbnN0IHtpU2NhbGUsIF9wYXJzZWR9ID0gbWV0YTtcbiAgICBjb25zdCBheGlzID0gaVNjYWxlLmF4aXM7XG4gICAgY29uc3Qge21pbiwgbWF4LCBtaW5EZWZpbmVkLCBtYXhEZWZpbmVkfSA9IGlTY2FsZS5nZXRVc2VyQm91bmRzKCk7XG5cbiAgICBpZiAobWluRGVmaW5lZCkge1xuICAgICAgc3RhcnQgPSBfbGltaXRWYWx1ZShNYXRoLm1pbihcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBOZWVkIHRvIHR5cGUgX3BhcnNlZFxuICAgICAgICBfbG9va3VwQnlLZXkoX3BhcnNlZCwgYXhpcywgbWluKS5sbyxcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBOZWVkIHRvIGZpeCB0eXBlcyBvbiBfbG9va3VwQnlLZXlcbiAgICAgICAgYW5pbWF0aW9uc0Rpc2FibGVkID8gcG9pbnRDb3VudCA6IF9sb29rdXBCeUtleShwb2ludHMsIGF4aXMsIGlTY2FsZS5nZXRQaXhlbEZvclZhbHVlKG1pbikpLmxvKSxcbiAgICAgIDAsIHBvaW50Q291bnQgLSAxKTtcbiAgICB9XG4gICAgaWYgKG1heERlZmluZWQpIHtcbiAgICAgIGNvdW50ID0gX2xpbWl0VmFsdWUoTWF0aC5tYXgoXG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgTmVlZCB0byB0eXBlIF9wYXJzZWRcbiAgICAgICAgX2xvb2t1cEJ5S2V5KF9wYXJzZWQsIGlTY2FsZS5heGlzLCBtYXgsIHRydWUpLmhpICsgMSxcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBOZWVkIHRvIGZpeCB0eXBlcyBvbiBfbG9va3VwQnlLZXlcbiAgICAgICAgYW5pbWF0aW9uc0Rpc2FibGVkID8gMCA6IF9sb29rdXBCeUtleShwb2ludHMsIGF4aXMsIGlTY2FsZS5nZXRQaXhlbEZvclZhbHVlKG1heCksIHRydWUpLmhpICsgMSksXG4gICAgICBzdGFydCwgcG9pbnRDb3VudCkgLSBzdGFydDtcbiAgICB9IGVsc2Uge1xuICAgICAgY291bnQgPSBwb2ludENvdW50IC0gc3RhcnQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtzdGFydCwgY291bnR9O1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgc2NhbGUgcmFuZ2VzIGhhdmUgY2hhbmdlZC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBtZXRhIC0gZGF0YXNldCBtZXRhLlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX3NjYWxlUmFuZ2VzQ2hhbmdlZChtZXRhKSB7XG4gIGNvbnN0IHt4U2NhbGUsIHlTY2FsZSwgX3NjYWxlUmFuZ2VzfSA9IG1ldGE7XG4gIGNvbnN0IG5ld1JhbmdlcyA9IHtcbiAgICB4bWluOiB4U2NhbGUubWluLFxuICAgIHhtYXg6IHhTY2FsZS5tYXgsXG4gICAgeW1pbjogeVNjYWxlLm1pbixcbiAgICB5bWF4OiB5U2NhbGUubWF4XG4gIH07XG4gIGlmICghX3NjYWxlUmFuZ2VzKSB7XG4gICAgbWV0YS5fc2NhbGVSYW5nZXMgPSBuZXdSYW5nZXM7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgY29uc3QgY2hhbmdlZCA9IF9zY2FsZVJhbmdlcy54bWluICE9PSB4U2NhbGUubWluXG5cdFx0fHwgX3NjYWxlUmFuZ2VzLnhtYXggIT09IHhTY2FsZS5tYXhcblx0XHR8fCBfc2NhbGVSYW5nZXMueW1pbiAhPT0geVNjYWxlLm1pblxuXHRcdHx8IF9zY2FsZVJhbmdlcy55bWF4ICE9PSB5U2NhbGUubWF4O1xuXG4gIE9iamVjdC5hc3NpZ24oX3NjYWxlUmFuZ2VzLCBuZXdSYW5nZXMpO1xuICByZXR1cm4gY2hhbmdlZDtcbn1cbiIsICJpbXBvcnQge1BJLCBUQVUsIEhBTEZfUEl9IGZyb20gJy4vaGVscGVycy5tYXRoLmpzJztcblxuY29uc3QgYXRFZGdlID0gKHQ6IG51bWJlcikgPT4gdCA9PT0gMCB8fCB0ID09PSAxO1xuY29uc3QgZWxhc3RpY0luID0gKHQ6IG51bWJlciwgczogbnVtYmVyLCBwOiBudW1iZXIpID0+IC0oTWF0aC5wb3coMiwgMTAgKiAodCAtPSAxKSkgKiBNYXRoLnNpbigodCAtIHMpICogVEFVIC8gcCkpO1xuY29uc3QgZWxhc3RpY091dCA9ICh0OiBudW1iZXIsIHM6IG51bWJlciwgcDogbnVtYmVyKSA9PiBNYXRoLnBvdygyLCAtMTAgKiB0KSAqIE1hdGguc2luKCh0IC0gcykgKiBUQVUgLyBwKSArIDE7XG5cbi8qKlxuICogRWFzaW5nIGZ1bmN0aW9ucyBhZGFwdGVkIGZyb20gUm9iZXJ0IFBlbm5lcidzIGVhc2luZyBlcXVhdGlvbnMuXG4gKiBAbmFtZXNwYWNlIENoYXJ0LmhlbHBlcnMuZWFzaW5nLmVmZmVjdHNcbiAqIEBzZWUgaHR0cDovL3d3dy5yb2JlcnRwZW5uZXIuY29tL2Vhc2luZy9cbiAqL1xuY29uc3QgZWZmZWN0cyA9IHtcbiAgbGluZWFyOiAodDogbnVtYmVyKSA9PiB0LFxuXG4gIGVhc2VJblF1YWQ6ICh0OiBudW1iZXIpID0+IHQgKiB0LFxuXG4gIGVhc2VPdXRRdWFkOiAodDogbnVtYmVyKSA9PiAtdCAqICh0IC0gMiksXG5cbiAgZWFzZUluT3V0UXVhZDogKHQ6IG51bWJlcikgPT4gKCh0IC89IDAuNSkgPCAxKVxuICAgID8gMC41ICogdCAqIHRcbiAgICA6IC0wLjUgKiAoKC0tdCkgKiAodCAtIDIpIC0gMSksXG5cbiAgZWFzZUluQ3ViaWM6ICh0OiBudW1iZXIpID0+IHQgKiB0ICogdCxcblxuICBlYXNlT3V0Q3ViaWM6ICh0OiBudW1iZXIpID0+ICh0IC09IDEpICogdCAqIHQgKyAxLFxuXG4gIGVhc2VJbk91dEN1YmljOiAodDogbnVtYmVyKSA9PiAoKHQgLz0gMC41KSA8IDEpXG4gICAgPyAwLjUgKiB0ICogdCAqIHRcbiAgICA6IDAuNSAqICgodCAtPSAyKSAqIHQgKiB0ICsgMiksXG5cbiAgZWFzZUluUXVhcnQ6ICh0OiBudW1iZXIpID0+IHQgKiB0ICogdCAqIHQsXG5cbiAgZWFzZU91dFF1YXJ0OiAodDogbnVtYmVyKSA9PiAtKCh0IC09IDEpICogdCAqIHQgKiB0IC0gMSksXG5cbiAgZWFzZUluT3V0UXVhcnQ6ICh0OiBudW1iZXIpID0+ICgodCAvPSAwLjUpIDwgMSlcbiAgICA/IDAuNSAqIHQgKiB0ICogdCAqIHRcbiAgICA6IC0wLjUgKiAoKHQgLT0gMikgKiB0ICogdCAqIHQgLSAyKSxcblxuICBlYXNlSW5RdWludDogKHQ6IG51bWJlcikgPT4gdCAqIHQgKiB0ICogdCAqIHQsXG5cbiAgZWFzZU91dFF1aW50OiAodDogbnVtYmVyKSA9PiAodCAtPSAxKSAqIHQgKiB0ICogdCAqIHQgKyAxLFxuXG4gIGVhc2VJbk91dFF1aW50OiAodDogbnVtYmVyKSA9PiAoKHQgLz0gMC41KSA8IDEpXG4gICAgPyAwLjUgKiB0ICogdCAqIHQgKiB0ICogdFxuICAgIDogMC41ICogKCh0IC09IDIpICogdCAqIHQgKiB0ICogdCArIDIpLFxuXG4gIGVhc2VJblNpbmU6ICh0OiBudW1iZXIpID0+IC1NYXRoLmNvcyh0ICogSEFMRl9QSSkgKyAxLFxuXG4gIGVhc2VPdXRTaW5lOiAodDogbnVtYmVyKSA9PiBNYXRoLnNpbih0ICogSEFMRl9QSSksXG5cbiAgZWFzZUluT3V0U2luZTogKHQ6IG51bWJlcikgPT4gLTAuNSAqIChNYXRoLmNvcyhQSSAqIHQpIC0gMSksXG5cbiAgZWFzZUluRXhwbzogKHQ6IG51bWJlcikgPT4gKHQgPT09IDApID8gMCA6IE1hdGgucG93KDIsIDEwICogKHQgLSAxKSksXG5cbiAgZWFzZU91dEV4cG86ICh0OiBudW1iZXIpID0+ICh0ID09PSAxKSA/IDEgOiAtTWF0aC5wb3coMiwgLTEwICogdCkgKyAxLFxuXG4gIGVhc2VJbk91dEV4cG86ICh0OiBudW1iZXIpID0+IGF0RWRnZSh0KSA/IHQgOiB0IDwgMC41XG4gICAgPyAwLjUgKiBNYXRoLnBvdygyLCAxMCAqICh0ICogMiAtIDEpKVxuICAgIDogMC41ICogKC1NYXRoLnBvdygyLCAtMTAgKiAodCAqIDIgLSAxKSkgKyAyKSxcblxuICBlYXNlSW5DaXJjOiAodDogbnVtYmVyKSA9PiAodCA+PSAxKSA/IHQgOiAtKE1hdGguc3FydCgxIC0gdCAqIHQpIC0gMSksXG5cbiAgZWFzZU91dENpcmM6ICh0OiBudW1iZXIpID0+IE1hdGguc3FydCgxIC0gKHQgLT0gMSkgKiB0KSxcblxuICBlYXNlSW5PdXRDaXJjOiAodDogbnVtYmVyKSA9PiAoKHQgLz0gMC41KSA8IDEpXG4gICAgPyAtMC41ICogKE1hdGguc3FydCgxIC0gdCAqIHQpIC0gMSlcbiAgICA6IDAuNSAqIChNYXRoLnNxcnQoMSAtICh0IC09IDIpICogdCkgKyAxKSxcblxuICBlYXNlSW5FbGFzdGljOiAodDogbnVtYmVyKSA9PiBhdEVkZ2UodCkgPyB0IDogZWxhc3RpY0luKHQsIDAuMDc1LCAwLjMpLFxuXG4gIGVhc2VPdXRFbGFzdGljOiAodDogbnVtYmVyKSA9PiBhdEVkZ2UodCkgPyB0IDogZWxhc3RpY091dCh0LCAwLjA3NSwgMC4zKSxcblxuICBlYXNlSW5PdXRFbGFzdGljKHQ6IG51bWJlcikge1xuICAgIGNvbnN0IHMgPSAwLjExMjU7XG4gICAgY29uc3QgcCA9IDAuNDU7XG4gICAgcmV0dXJuIGF0RWRnZSh0KSA/IHQgOlxuICAgICAgdCA8IDAuNVxuICAgICAgICA/IDAuNSAqIGVsYXN0aWNJbih0ICogMiwgcywgcClcbiAgICAgICAgOiAwLjUgKyAwLjUgKiBlbGFzdGljT3V0KHQgKiAyIC0gMSwgcywgcCk7XG4gIH0sXG5cbiAgZWFzZUluQmFjayh0OiBudW1iZXIpIHtcbiAgICBjb25zdCBzID0gMS43MDE1ODtcbiAgICByZXR1cm4gdCAqIHQgKiAoKHMgKyAxKSAqIHQgLSBzKTtcbiAgfSxcblxuICBlYXNlT3V0QmFjayh0OiBudW1iZXIpIHtcbiAgICBjb25zdCBzID0gMS43MDE1ODtcbiAgICByZXR1cm4gKHQgLT0gMSkgKiB0ICogKChzICsgMSkgKiB0ICsgcykgKyAxO1xuICB9LFxuXG4gIGVhc2VJbk91dEJhY2sodDogbnVtYmVyKSB7XG4gICAgbGV0IHMgPSAxLjcwMTU4O1xuICAgIGlmICgodCAvPSAwLjUpIDwgMSkge1xuICAgICAgcmV0dXJuIDAuNSAqICh0ICogdCAqICgoKHMgKj0gKDEuNTI1KSkgKyAxKSAqIHQgLSBzKSk7XG4gICAgfVxuICAgIHJldHVybiAwLjUgKiAoKHQgLT0gMikgKiB0ICogKCgocyAqPSAoMS41MjUpKSArIDEpICogdCArIHMpICsgMik7XG4gIH0sXG5cbiAgZWFzZUluQm91bmNlOiAodDogbnVtYmVyKSA9PiAxIC0gZWZmZWN0cy5lYXNlT3V0Qm91bmNlKDEgLSB0KSxcblxuICBlYXNlT3V0Qm91bmNlKHQ6IG51bWJlcikge1xuICAgIGNvbnN0IG0gPSA3LjU2MjU7XG4gICAgY29uc3QgZCA9IDIuNzU7XG4gICAgaWYgKHQgPCAoMSAvIGQpKSB7XG4gICAgICByZXR1cm4gbSAqIHQgKiB0O1xuICAgIH1cbiAgICBpZiAodCA8ICgyIC8gZCkpIHtcbiAgICAgIHJldHVybiBtICogKHQgLT0gKDEuNSAvIGQpKSAqIHQgKyAwLjc1O1xuICAgIH1cbiAgICBpZiAodCA8ICgyLjUgLyBkKSkge1xuICAgICAgcmV0dXJuIG0gKiAodCAtPSAoMi4yNSAvIGQpKSAqIHQgKyAwLjkzNzU7XG4gICAgfVxuICAgIHJldHVybiBtICogKHQgLT0gKDIuNjI1IC8gZCkpICogdCArIDAuOTg0Mzc1O1xuICB9LFxuXG4gIGVhc2VJbk91dEJvdW5jZTogKHQ6IG51bWJlcikgPT4gKHQgPCAwLjUpXG4gICAgPyBlZmZlY3RzLmVhc2VJbkJvdW5jZSh0ICogMikgKiAwLjVcbiAgICA6IGVmZmVjdHMuZWFzZU91dEJvdW5jZSh0ICogMiAtIDEpICogMC41ICsgMC41LFxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgRWFzaW5nRnVuY3Rpb24gPSBrZXlvZiB0eXBlb2YgZWZmZWN0c1xuXG5leHBvcnQgZGVmYXVsdCBlZmZlY3RzO1xuIiwgImltcG9ydCB7Q29sb3J9IGZyb20gJ0BrdXJrbGUvY29sb3InO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNQYXR0ZXJuT3JHcmFkaWVudCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIENhbnZhc1BhdHRlcm4gfCBDYW52YXNHcmFkaWVudCB7XG4gIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgY29uc3QgdHlwZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgcmV0dXJuIHR5cGUgPT09ICdbb2JqZWN0IENhbnZhc1BhdHRlcm5dJyB8fCB0eXBlID09PSAnW29iamVjdCBDYW52YXNHcmFkaWVudF0nO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29sb3IodmFsdWU6IENhbnZhc0dyYWRpZW50KTogQ2FudmFzR3JhZGllbnQ7XG5leHBvcnQgZnVuY3Rpb24gY29sb3IodmFsdWU6IENhbnZhc1BhdHRlcm4pOiBDYW52YXNQYXR0ZXJuO1xuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yKFxuICB2YWx1ZTpcbiAgfCBzdHJpbmdcbiAgfCB7IHI6IG51bWJlcjsgZzogbnVtYmVyOyBiOiBudW1iZXI7IGE6IG51bWJlciB9XG4gIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXJdXG4gIHwgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl1cbik6IENvbG9yO1xuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yKHZhbHVlKSB7XG4gIHJldHVybiBpc1BhdHRlcm5PckdyYWRpZW50KHZhbHVlKSA/IHZhbHVlIDogbmV3IENvbG9yKHZhbHVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhvdmVyQ29sb3IodmFsdWU6IENhbnZhc0dyYWRpZW50KTogQ2FudmFzR3JhZGllbnQ7XG5leHBvcnQgZnVuY3Rpb24gZ2V0SG92ZXJDb2xvcih2YWx1ZTogQ2FudmFzUGF0dGVybik6IENhbnZhc1BhdHRlcm47XG5leHBvcnQgZnVuY3Rpb24gZ2V0SG92ZXJDb2xvcih2YWx1ZTogc3RyaW5nKTogc3RyaW5nO1xuZXhwb3J0IGZ1bmN0aW9uIGdldEhvdmVyQ29sb3IodmFsdWUpIHtcbiAgcmV0dXJuIGlzUGF0dGVybk9yR3JhZGllbnQodmFsdWUpXG4gICAgPyB2YWx1ZVxuICAgIDogbmV3IENvbG9yKHZhbHVlKS5zYXR1cmF0ZSgwLjUpLmRhcmtlbigwLjEpLmhleFN0cmluZygpO1xufVxuIiwgImNvbnN0IG51bWJlcnMgPSBbJ3gnLCAneScsICdib3JkZXJXaWR0aCcsICdyYWRpdXMnLCAndGVuc2lvbiddO1xuY29uc3QgY29sb3JzID0gWydjb2xvcicsICdib3JkZXJDb2xvcicsICdiYWNrZ3JvdW5kQ29sb3InXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5QW5pbWF0aW9uc0RlZmF1bHRzKGRlZmF1bHRzKSB7XG4gIGRlZmF1bHRzLnNldCgnYW5pbWF0aW9uJywge1xuICAgIGRlbGF5OiB1bmRlZmluZWQsXG4gICAgZHVyYXRpb246IDEwMDAsXG4gICAgZWFzaW5nOiAnZWFzZU91dFF1YXJ0JyxcbiAgICBmbjogdW5kZWZpbmVkLFxuICAgIGZyb206IHVuZGVmaW5lZCxcbiAgICBsb29wOiB1bmRlZmluZWQsXG4gICAgdG86IHVuZGVmaW5lZCxcbiAgICB0eXBlOiB1bmRlZmluZWQsXG4gIH0pO1xuXG4gIGRlZmF1bHRzLmRlc2NyaWJlKCdhbmltYXRpb24nLCB7XG4gICAgX2ZhbGxiYWNrOiBmYWxzZSxcbiAgICBfaW5kZXhhYmxlOiBmYWxzZSxcbiAgICBfc2NyaXB0YWJsZTogKG5hbWUpID0+IG5hbWUgIT09ICdvblByb2dyZXNzJyAmJiBuYW1lICE9PSAnb25Db21wbGV0ZScgJiYgbmFtZSAhPT0gJ2ZuJyxcbiAgfSk7XG5cbiAgZGVmYXVsdHMuc2V0KCdhbmltYXRpb25zJywge1xuICAgIGNvbG9yczoge1xuICAgICAgdHlwZTogJ2NvbG9yJyxcbiAgICAgIHByb3BlcnRpZXM6IGNvbG9yc1xuICAgIH0sXG4gICAgbnVtYmVyczoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICBwcm9wZXJ0aWVzOiBudW1iZXJzXG4gICAgfSxcbiAgfSk7XG5cbiAgZGVmYXVsdHMuZGVzY3JpYmUoJ2FuaW1hdGlvbnMnLCB7XG4gICAgX2ZhbGxiYWNrOiAnYW5pbWF0aW9uJyxcbiAgfSk7XG5cbiAgZGVmYXVsdHMuc2V0KCd0cmFuc2l0aW9ucycsIHtcbiAgICBhY3RpdmU6IHtcbiAgICAgIGFuaW1hdGlvbjoge1xuICAgICAgICBkdXJhdGlvbjogNDAwXG4gICAgICB9XG4gICAgfSxcbiAgICByZXNpemU6IHtcbiAgICAgIGFuaW1hdGlvbjoge1xuICAgICAgICBkdXJhdGlvbjogMFxuICAgICAgfVxuICAgIH0sXG4gICAgc2hvdzoge1xuICAgICAgYW5pbWF0aW9uczoge1xuICAgICAgICBjb2xvcnM6IHtcbiAgICAgICAgICBmcm9tOiAndHJhbnNwYXJlbnQnXG4gICAgICAgIH0sXG4gICAgICAgIHZpc2libGU6IHtcbiAgICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgICAgZHVyYXRpb246IDAgLy8gc2hvdyBpbW1lZGlhdGVseVxuICAgICAgICB9LFxuICAgICAgfVxuICAgIH0sXG4gICAgaGlkZToge1xuICAgICAgYW5pbWF0aW9uczoge1xuICAgICAgICBjb2xvcnM6IHtcbiAgICAgICAgICB0bzogJ3RyYW5zcGFyZW50J1xuICAgICAgICB9LFxuICAgICAgICB2aXNpYmxlOiB7XG4gICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICAgIGVhc2luZzogJ2xpbmVhcicsXG4gICAgICAgICAgZm46IHYgPT4gdiB8IDAgLy8gZm9yIGtlZXBpbmcgdGhlIGRhdGFzZXQgdmlzaWJsZSBhbGwgdGhlIHdheSB0aHJvdWdoIHRoZSBhbmltYXRpb25cbiAgICAgICAgfSxcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBhcHBseUxheW91dHNEZWZhdWx0cyhkZWZhdWx0cykge1xuICBkZWZhdWx0cy5zZXQoJ2xheW91dCcsIHtcbiAgICBhdXRvUGFkZGluZzogdHJ1ZSxcbiAgICBwYWRkaW5nOiB7XG4gICAgICB0b3A6IDAsXG4gICAgICByaWdodDogMCxcbiAgICAgIGJvdHRvbTogMCxcbiAgICAgIGxlZnQ6IDBcbiAgICB9XG4gIH0pO1xufVxuIiwgIlxuY29uc3QgaW50bENhY2hlID0gbmV3IE1hcDxzdHJpbmcsIEludGwuTnVtYmVyRm9ybWF0PigpO1xuXG5mdW5jdGlvbiBnZXROdW1iZXJGb3JtYXQobG9jYWxlOiBzdHJpbmcsIG9wdGlvbnM/OiBJbnRsLk51bWJlckZvcm1hdE9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGNvbnN0IGNhY2hlS2V5ID0gbG9jYWxlICsgSlNPTi5zdHJpbmdpZnkob3B0aW9ucyk7XG4gIGxldCBmb3JtYXR0ZXIgPSBpbnRsQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgaWYgKCFmb3JtYXR0ZXIpIHtcbiAgICBmb3JtYXR0ZXIgPSBuZXcgSW50bC5OdW1iZXJGb3JtYXQobG9jYWxlLCBvcHRpb25zKTtcbiAgICBpbnRsQ2FjaGUuc2V0KGNhY2hlS2V5LCBmb3JtYXR0ZXIpO1xuICB9XG4gIHJldHVybiBmb3JtYXR0ZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXROdW1iZXIobnVtOiBudW1iZXIsIGxvY2FsZTogc3RyaW5nLCBvcHRpb25zPzogSW50bC5OdW1iZXJGb3JtYXRPcHRpb25zKSB7XG4gIHJldHVybiBnZXROdW1iZXJGb3JtYXQobG9jYWxlLCBvcHRpb25zKS5mb3JtYXQobnVtKTtcbn1cbiIsICJpbXBvcnQge2lzQXJyYXl9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7Zm9ybWF0TnVtYmVyfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuaW50bC5qcyc7XG5pbXBvcnQge2xvZzEwfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMubWF0aC5qcyc7XG5cbi8qKlxuICogTmFtZXNwYWNlIHRvIGhvbGQgZm9ybWF0dGVycyBmb3IgZGlmZmVyZW50IHR5cGVzIG9mIHRpY2tzXG4gKiBAbmFtZXNwYWNlIENoYXJ0LlRpY2tzLmZvcm1hdHRlcnNcbiAqL1xuY29uc3QgZm9ybWF0dGVycyA9IHtcbiAgLyoqXG4gICAqIEZvcm1hdHRlciBmb3IgdmFsdWUgbGFiZWxzXG4gICAqIEBtZXRob2QgQ2hhcnQuVGlja3MuZm9ybWF0dGVycy52YWx1ZXNcbiAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byBkaXNwbGF5XG4gICAqIEByZXR1cm4ge3N0cmluZ3xzdHJpbmdbXX0gdGhlIGxhYmVsIHRvIGRpc3BsYXlcbiAgICovXG4gIHZhbHVlcyh2YWx1ZSkge1xuICAgIHJldHVybiBpc0FycmF5KHZhbHVlKSA/IC8qKiBAdHlwZSB7c3RyaW5nW119ICovICh2YWx1ZSkgOiAnJyArIHZhbHVlO1xuICB9LFxuXG4gIC8qKlxuICAgKiBGb3JtYXR0ZXIgZm9yIG51bWVyaWMgdGlja3NcbiAgICogQG1ldGhvZCBDaGFydC5UaWNrcy5mb3JtYXR0ZXJzLm51bWVyaWNcbiAgICogQHBhcmFtIHRpY2tWYWx1ZSB7bnVtYmVyfSB0aGUgdmFsdWUgdG8gYmUgZm9ybWF0dGVkXG4gICAqIEBwYXJhbSBpbmRleCB7bnVtYmVyfSB0aGUgcG9zaXRpb24gb2YgdGhlIHRpY2tWYWx1ZSBwYXJhbWV0ZXIgaW4gdGhlIHRpY2tzIGFycmF5XG4gICAqIEBwYXJhbSB0aWNrcyB7b2JqZWN0W119IHRoZSBsaXN0IG9mIHRpY2tzIGJlaW5nIGNvbnZlcnRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGlja1ZhbHVlIHBhcmFtZXRlclxuICAgKi9cbiAgbnVtZXJpYyh0aWNrVmFsdWUsIGluZGV4LCB0aWNrcykge1xuICAgIGlmICh0aWNrVmFsdWUgPT09IDApIHtcbiAgICAgIHJldHVybiAnMCc7IC8vIG5ldmVyIHNob3cgZGVjaW1hbCBwbGFjZXMgZm9yIDBcbiAgICB9XG5cbiAgICBjb25zdCBsb2NhbGUgPSB0aGlzLmNoYXJ0Lm9wdGlvbnMubG9jYWxlO1xuICAgIGxldCBub3RhdGlvbjtcbiAgICBsZXQgZGVsdGEgPSB0aWNrVmFsdWU7IC8vIFRoaXMgaXMgdXNlZCB3aGVuIHRoZXJlIGFyZSBsZXNzIHRoYW4gMiB0aWNrcyBhcyB0aGUgdGljayBpbnRlcnZhbC5cblxuICAgIGlmICh0aWNrcy5sZW5ndGggPiAxKSB7XG4gICAgICAvLyBhbGwgdGlja3MgYXJlIHNtYWxsIG9yIHRoZXJlIGh1Z2UgbnVtYmVyczsgdXNlIHNjaWVudGlmaWMgbm90YXRpb25cbiAgICAgIGNvbnN0IG1heFRpY2sgPSBNYXRoLm1heChNYXRoLmFicyh0aWNrc1swXS52YWx1ZSksIE1hdGguYWJzKHRpY2tzW3RpY2tzLmxlbmd0aCAtIDFdLnZhbHVlKSk7XG4gICAgICBpZiAobWF4VGljayA8IDFlLTQgfHwgbWF4VGljayA+IDFlKzE1KSB7XG4gICAgICAgIG5vdGF0aW9uID0gJ3NjaWVudGlmaWMnO1xuICAgICAgfVxuXG4gICAgICBkZWx0YSA9IGNhbGN1bGF0ZURlbHRhKHRpY2tWYWx1ZSwgdGlja3MpO1xuICAgIH1cblxuICAgIGNvbnN0IGxvZ0RlbHRhID0gbG9nMTAoTWF0aC5hYnMoZGVsdGEpKTtcblxuICAgIC8vIFdoZW4gZGF0YXNldHMgaGF2ZSB2YWx1ZXMgYXBwcm9hY2hpbmcgTnVtYmVyLk1BWF9WQUxVRSwgdGhlIHRpY2sgY2FsY3VsYXRpb25zIG1pZ2h0IHJlc3VsdCBpblxuICAgIC8vIGluZmluaXR5IGFuZCBldmVudHVhbGx5IE5hTi4gUGFzc2luZyBOYU4gZm9yIG1pbmltdW1GcmFjdGlvbkRpZ2l0cyBvciBtYXhpbXVtRnJhY3Rpb25EaWdpdHNcbiAgICAvLyB3aWxsIG1ha2UgdGhlIG51bWJlciBmb3JtYXR0ZXIgdGhyb3cuIFNvIGluc3RlYWQgd2UgY2hlY2sgZm9yIGlzTmFOIGFuZCB1c2UgYSBmYWxsYmFjayB2YWx1ZS5cbiAgICAvL1xuICAgIC8vIHRvRml4ZWQgaGFzIGEgbWF4IG9mIDIwIGRlY2ltYWwgcGxhY2VzXG4gICAgY29uc3QgbnVtRGVjaW1hbCA9IGlzTmFOKGxvZ0RlbHRhKSA/IDEgOiBNYXRoLm1heChNYXRoLm1pbigtMSAqIE1hdGguZmxvb3IobG9nRGVsdGEpLCAyMCksIDApO1xuXG4gICAgY29uc3Qgb3B0aW9ucyA9IHtub3RhdGlvbiwgbWluaW11bUZyYWN0aW9uRGlnaXRzOiBudW1EZWNpbWFsLCBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IG51bURlY2ltYWx9O1xuICAgIE9iamVjdC5hc3NpZ24ob3B0aW9ucywgdGhpcy5vcHRpb25zLnRpY2tzLmZvcm1hdCk7XG5cbiAgICByZXR1cm4gZm9ybWF0TnVtYmVyKHRpY2tWYWx1ZSwgbG9jYWxlLCBvcHRpb25zKTtcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBGb3JtYXR0ZXIgZm9yIGxvZ2FyaXRobWljIHRpY2tzXG4gICAqIEBtZXRob2QgQ2hhcnQuVGlja3MuZm9ybWF0dGVycy5sb2dhcml0aG1pY1xuICAgKiBAcGFyYW0gdGlja1ZhbHVlIHtudW1iZXJ9IHRoZSB2YWx1ZSB0byBiZSBmb3JtYXR0ZWRcbiAgICogQHBhcmFtIGluZGV4IHtudW1iZXJ9IHRoZSBwb3NpdGlvbiBvZiB0aGUgdGlja1ZhbHVlIHBhcmFtZXRlciBpbiB0aGUgdGlja3MgYXJyYXlcbiAgICogQHBhcmFtIHRpY2tzIHtvYmplY3RbXX0gdGhlIGxpc3Qgb2YgdGlja3MgYmVpbmcgY29udmVydGVkXG4gICAqIEByZXR1cm4ge3N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0aWNrVmFsdWUgcGFyYW1ldGVyXG4gICAqL1xuICBsb2dhcml0aG1pYyh0aWNrVmFsdWUsIGluZGV4LCB0aWNrcykge1xuICAgIGlmICh0aWNrVmFsdWUgPT09IDApIHtcbiAgICAgIHJldHVybiAnMCc7XG4gICAgfVxuICAgIGNvbnN0IHJlbWFpbiA9IHRpY2tzW2luZGV4XS5zaWduaWZpY2FuZCB8fCAodGlja1ZhbHVlIC8gKE1hdGgucG93KDEwLCBNYXRoLmZsb29yKGxvZzEwKHRpY2tWYWx1ZSkpKSkpO1xuICAgIGlmIChbMSwgMiwgMywgNSwgMTAsIDE1XS5pbmNsdWRlcyhyZW1haW4pIHx8IGluZGV4ID4gMC44ICogdGlja3MubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZm9ybWF0dGVycy5udW1lcmljLmNhbGwodGhpcywgdGlja1ZhbHVlLCBpbmRleCwgdGlja3MpO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG4gIH1cblxufTtcblxuXG5mdW5jdGlvbiBjYWxjdWxhdGVEZWx0YSh0aWNrVmFsdWUsIHRpY2tzKSB7XG4gIC8vIEZpZ3VyZSBvdXQgaG93IG1hbnkgZGlnaXRzIHRvIHNob3dcbiAgLy8gVGhlIHNwYWNlIGJldHdlZW4gdGhlIGZpcnN0IHR3byB0aWNrcyBtaWdodCBiZSBzbWFsbGVyIHRoYW4gbm9ybWFsIHNwYWNpbmdcbiAgbGV0IGRlbHRhID0gdGlja3MubGVuZ3RoID4gMyA/IHRpY2tzWzJdLnZhbHVlIC0gdGlja3NbMV0udmFsdWUgOiB0aWNrc1sxXS52YWx1ZSAtIHRpY2tzWzBdLnZhbHVlO1xuXG4gIC8vIElmIHdlIGhhdmUgYSBudW1iZXIgbGlrZSAyLjUgYXMgdGhlIGRlbHRhLCBmaWd1cmUgb3V0IGhvdyBtYW55IGRlY2ltYWwgcGxhY2VzIHdlIG5lZWRcbiAgaWYgKE1hdGguYWJzKGRlbHRhKSA+PSAxICYmIHRpY2tWYWx1ZSAhPT0gTWF0aC5mbG9vcih0aWNrVmFsdWUpKSB7XG4gICAgLy8gbm90IGFuIGludGVnZXJcbiAgICBkZWx0YSA9IHRpY2tWYWx1ZSAtIE1hdGguZmxvb3IodGlja1ZhbHVlKTtcbiAgfVxuICByZXR1cm4gZGVsdGE7XG59XG5cbi8qKlxuICogTmFtZXNwYWNlIHRvIGhvbGQgc3RhdGljIHRpY2sgZ2VuZXJhdGlvbiBmdW5jdGlvbnNcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuVGlja3NcbiAqL1xuZXhwb3J0IGRlZmF1bHQge2Zvcm1hdHRlcnN9O1xuIiwgImltcG9ydCBUaWNrcyBmcm9tICcuL2NvcmUudGlja3MuanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlTY2FsZURlZmF1bHRzKGRlZmF1bHRzKSB7XG4gIGRlZmF1bHRzLnNldCgnc2NhbGUnLCB7XG4gICAgZGlzcGxheTogdHJ1ZSxcbiAgICBvZmZzZXQ6IGZhbHNlLFxuICAgIHJldmVyc2U6IGZhbHNlLFxuICAgIGJlZ2luQXRaZXJvOiBmYWxzZSxcblxuICAgIC8qKlxuICAgICAqIFNjYWxlIGJvdW5kYXJ5IHN0cmF0ZWd5IChieXBhc3NlZCBieSBtaW4vbWF4IHRpbWUgb3B0aW9ucylcbiAgICAgKiAtIGBkYXRhYDogbWFrZSBzdXJlIGRhdGEgYXJlIGZ1bGx5IHZpc2libGUsIHRpY2tzIG91dHNpZGUgYXJlIHJlbW92ZWRcbiAgICAgKiAtIGB0aWNrc2A6IG1ha2Ugc3VyZSB0aWNrcyBhcmUgZnVsbHkgdmlzaWJsZSwgZGF0YSBvdXRzaWRlIGFyZSB0cnVuY2F0ZWRcbiAgICAgKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL3B1bGwvNDU1NlxuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqL1xuICAgIGJvdW5kczogJ3RpY2tzJyxcblxuICAgIGNsaXA6IHRydWUsXG5cbiAgICAvKipcbiAgICAgKiBBZGRpdGlvbiBncmFjZSBhZGRlZCB0byBtYXggYW5kIHJlZHVjZWQgZnJvbSBtaW4gZGF0YSB2YWx1ZS5cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKi9cbiAgICBncmFjZTogMCxcblxuICAgIC8vIGdyaWQgbGluZSBzZXR0aW5nc1xuICAgIGdyaWQ6IHtcbiAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICBkcmF3T25DaGFydEFyZWE6IHRydWUsXG4gICAgICBkcmF3VGlja3M6IHRydWUsXG4gICAgICB0aWNrTGVuZ3RoOiA4LFxuICAgICAgdGlja1dpZHRoOiAoX2N0eCwgb3B0aW9ucykgPT4gb3B0aW9ucy5saW5lV2lkdGgsXG4gICAgICB0aWNrQ29sb3I6IChfY3R4LCBvcHRpb25zKSA9PiBvcHRpb25zLmNvbG9yLFxuICAgICAgb2Zmc2V0OiBmYWxzZSxcbiAgICB9LFxuXG4gICAgYm9yZGVyOiB7XG4gICAgICBkaXNwbGF5OiB0cnVlLFxuICAgICAgZGFzaDogW10sXG4gICAgICBkYXNoT2Zmc2V0OiAwLjAsXG4gICAgICB3aWR0aDogMVxuICAgIH0sXG5cbiAgICAvLyBzY2FsZSB0aXRsZVxuICAgIHRpdGxlOiB7XG4gICAgICAvLyBkaXNwbGF5IHByb3BlcnR5XG4gICAgICBkaXNwbGF5OiBmYWxzZSxcblxuICAgICAgLy8gYWN0dWFsIGxhYmVsXG4gICAgICB0ZXh0OiAnJyxcblxuICAgICAgLy8gdG9wL2JvdHRvbSBwYWRkaW5nXG4gICAgICBwYWRkaW5nOiB7XG4gICAgICAgIHRvcDogNCxcbiAgICAgICAgYm90dG9tOiA0XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8vIGxhYmVsIHNldHRpbmdzXG4gICAgdGlja3M6IHtcbiAgICAgIG1pblJvdGF0aW9uOiAwLFxuICAgICAgbWF4Um90YXRpb246IDUwLFxuICAgICAgbWlycm9yOiBmYWxzZSxcbiAgICAgIHRleHRTdHJva2VXaWR0aDogMCxcbiAgICAgIHRleHRTdHJva2VDb2xvcjogJycsXG4gICAgICBwYWRkaW5nOiAzLFxuICAgICAgZGlzcGxheTogdHJ1ZSxcbiAgICAgIGF1dG9Ta2lwOiB0cnVlLFxuICAgICAgYXV0b1NraXBQYWRkaW5nOiAzLFxuICAgICAgbGFiZWxPZmZzZXQ6IDAsXG4gICAgICAvLyBXZSBwYXNzIHRocm91Z2ggYXJyYXlzIHRvIGJlIHJlbmRlcmVkIGFzIG11bHRpbGluZSBsYWJlbHMsIHdlIGNvbnZlcnQgT3RoZXJzIHRvIHN0cmluZ3MgaGVyZS5cbiAgICAgIGNhbGxiYWNrOiBUaWNrcy5mb3JtYXR0ZXJzLnZhbHVlcyxcbiAgICAgIG1pbm9yOiB7fSxcbiAgICAgIG1ham9yOiB7fSxcbiAgICAgIGFsaWduOiAnY2VudGVyJyxcbiAgICAgIGNyb3NzQWxpZ246ICduZWFyJyxcblxuICAgICAgc2hvd0xhYmVsQmFja2Ryb3A6IGZhbHNlLFxuICAgICAgYmFja2Ryb3BDb2xvcjogJ3JnYmEoMjU1LCAyNTUsIDI1NSwgMC43NSknLFxuICAgICAgYmFja2Ryb3BQYWRkaW5nOiAyLFxuICAgIH1cbiAgfSk7XG5cbiAgZGVmYXVsdHMucm91dGUoJ3NjYWxlLnRpY2tzJywgJ2NvbG9yJywgJycsICdjb2xvcicpO1xuICBkZWZhdWx0cy5yb3V0ZSgnc2NhbGUuZ3JpZCcsICdjb2xvcicsICcnLCAnYm9yZGVyQ29sb3InKTtcbiAgZGVmYXVsdHMucm91dGUoJ3NjYWxlLmJvcmRlcicsICdjb2xvcicsICcnLCAnYm9yZGVyQ29sb3InKTtcbiAgZGVmYXVsdHMucm91dGUoJ3NjYWxlLnRpdGxlJywgJ2NvbG9yJywgJycsICdjb2xvcicpO1xuXG4gIGRlZmF1bHRzLmRlc2NyaWJlKCdzY2FsZScsIHtcbiAgICBfZmFsbGJhY2s6IGZhbHNlLFxuICAgIF9zY3JpcHRhYmxlOiAobmFtZSkgPT4gIW5hbWUuc3RhcnRzV2l0aCgnYmVmb3JlJykgJiYgIW5hbWUuc3RhcnRzV2l0aCgnYWZ0ZXInKSAmJiBuYW1lICE9PSAnY2FsbGJhY2snICYmIG5hbWUgIT09ICdwYXJzZXInLFxuICAgIF9pbmRleGFibGU6IChuYW1lKSA9PiBuYW1lICE9PSAnYm9yZGVyRGFzaCcgJiYgbmFtZSAhPT0gJ3RpY2tCb3JkZXJEYXNoJyAmJiBuYW1lICE9PSAnZGFzaCcsXG4gIH0pO1xuXG4gIGRlZmF1bHRzLmRlc2NyaWJlKCdzY2FsZXMnLCB7XG4gICAgX2ZhbGxiYWNrOiAnc2NhbGUnLFxuICB9KTtcblxuICBkZWZhdWx0cy5kZXNjcmliZSgnc2NhbGUudGlja3MnLCB7XG4gICAgX3NjcmlwdGFibGU6IChuYW1lKSA9PiBuYW1lICE9PSAnYmFja2Ryb3BQYWRkaW5nJyAmJiBuYW1lICE9PSAnY2FsbGJhY2snLFxuICAgIF9pbmRleGFibGU6IChuYW1lKSA9PiBuYW1lICE9PSAnYmFja2Ryb3BQYWRkaW5nJyxcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHtnZXRIb3ZlckNvbG9yfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29sb3IuanMnO1xuaW1wb3J0IHtpc09iamVjdCwgbWVyZ2UsIHZhbHVlT3JEZWZhdWx0fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge2FwcGx5QW5pbWF0aW9uc0RlZmF1bHRzfSBmcm9tICcuL2NvcmUuYW5pbWF0aW9ucy5kZWZhdWx0cy5qcyc7XG5pbXBvcnQge2FwcGx5TGF5b3V0c0RlZmF1bHRzfSBmcm9tICcuL2NvcmUubGF5b3V0cy5kZWZhdWx0cy5qcyc7XG5pbXBvcnQge2FwcGx5U2NhbGVEZWZhdWx0c30gZnJvbSAnLi9jb3JlLnNjYWxlLmRlZmF1bHRzLmpzJztcblxuZXhwb3J0IGNvbnN0IG92ZXJyaWRlcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5leHBvcnQgY29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4vKipcbiAqIEBwYXJhbSB7b2JqZWN0fSBub2RlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcmV0dXJuIHtvYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGdldFNjb3BlKG5vZGUsIGtleSkge1xuICBpZiAoIWtleSkge1xuICAgIHJldHVybiBub2RlO1xuICB9XG4gIGNvbnN0IGtleXMgPSBrZXkuc3BsaXQoJy4nKTtcbiAgZm9yIChsZXQgaSA9IDAsIG4gPSBrZXlzLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgIGNvbnN0IGsgPSBrZXlzW2ldO1xuICAgIG5vZGUgPSBub2RlW2tdIHx8IChub2RlW2tdID0gT2JqZWN0LmNyZWF0ZShudWxsKSk7XG4gIH1cbiAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIHNldChyb290LCBzY29wZSwgdmFsdWVzKSB7XG4gIGlmICh0eXBlb2Ygc2NvcGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG1lcmdlKGdldFNjb3BlKHJvb3QsIHNjb3BlKSwgdmFsdWVzKTtcbiAgfVxuICByZXR1cm4gbWVyZ2UoZ2V0U2NvcGUocm9vdCwgJycpLCBzY29wZSk7XG59XG5cbi8qKlxuICogUGxlYXNlIHVzZSB0aGUgbW9kdWxlJ3MgZGVmYXVsdCBleHBvcnQgd2hpY2ggcHJvdmlkZXMgYSBzaW5nbGV0b24gaW5zdGFuY2VcbiAqIE5vdGU6IGNsYXNzIGlzIGV4cG9ydGVkIGZvciB0eXBlZG9jXG4gKi9cbmV4cG9ydCBjbGFzcyBEZWZhdWx0cyB7XG4gIGNvbnN0cnVjdG9yKF9kZXNjcmlwdG9ycywgX2FwcGxpZXJzKSB7XG4gICAgdGhpcy5hbmltYXRpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5iYWNrZ3JvdW5kQ29sb3IgPSAncmdiYSgwLDAsMCwwLjEpJztcbiAgICB0aGlzLmJvcmRlckNvbG9yID0gJ3JnYmEoMCwwLDAsMC4xKSc7XG4gICAgdGhpcy5jb2xvciA9ICcjNjY2JztcbiAgICB0aGlzLmRhdGFzZXRzID0ge307XG4gICAgdGhpcy5kZXZpY2VQaXhlbFJhdGlvID0gKGNvbnRleHQpID0+IGNvbnRleHQuY2hhcnQucGxhdGZvcm0uZ2V0RGV2aWNlUGl4ZWxSYXRpbygpO1xuICAgIHRoaXMuZWxlbWVudHMgPSB7fTtcbiAgICB0aGlzLmV2ZW50cyA9IFtcbiAgICAgICdtb3VzZW1vdmUnLFxuICAgICAgJ21vdXNlb3V0JyxcbiAgICAgICdjbGljaycsXG4gICAgICAndG91Y2hzdGFydCcsXG4gICAgICAndG91Y2htb3ZlJ1xuICAgIF07XG4gICAgdGhpcy5mb250ID0ge1xuICAgICAgZmFtaWx5OiBcIidIZWx2ZXRpY2EgTmV1ZScsICdIZWx2ZXRpY2EnLCAnQXJpYWwnLCBzYW5zLXNlcmlmXCIsXG4gICAgICBzaXplOiAxMixcbiAgICAgIHN0eWxlOiAnbm9ybWFsJyxcbiAgICAgIGxpbmVIZWlnaHQ6IDEuMixcbiAgICAgIHdlaWdodDogbnVsbFxuICAgIH07XG4gICAgdGhpcy5ob3ZlciA9IHt9O1xuICAgIHRoaXMuaG92ZXJCYWNrZ3JvdW5kQ29sb3IgPSAoY3R4LCBvcHRpb25zKSA9PiBnZXRIb3ZlckNvbG9yKG9wdGlvbnMuYmFja2dyb3VuZENvbG9yKTtcbiAgICB0aGlzLmhvdmVyQm9yZGVyQ29sb3IgPSAoY3R4LCBvcHRpb25zKSA9PiBnZXRIb3ZlckNvbG9yKG9wdGlvbnMuYm9yZGVyQ29sb3IpO1xuICAgIHRoaXMuaG92ZXJDb2xvciA9IChjdHgsIG9wdGlvbnMpID0+IGdldEhvdmVyQ29sb3Iob3B0aW9ucy5jb2xvcik7XG4gICAgdGhpcy5pbmRleEF4aXMgPSAneCc7XG4gICAgdGhpcy5pbnRlcmFjdGlvbiA9IHtcbiAgICAgIG1vZGU6ICduZWFyZXN0JyxcbiAgICAgIGludGVyc2VjdDogdHJ1ZSxcbiAgICAgIGluY2x1ZGVJbnZpc2libGU6IGZhbHNlXG4gICAgfTtcbiAgICB0aGlzLm1haW50YWluQXNwZWN0UmF0aW8gPSB0cnVlO1xuICAgIHRoaXMub25Ib3ZlciA9IG51bGw7XG4gICAgdGhpcy5vbkNsaWNrID0gbnVsbDtcbiAgICB0aGlzLnBhcnNpbmcgPSB0cnVlO1xuICAgIHRoaXMucGx1Z2lucyA9IHt9O1xuICAgIHRoaXMucmVzcG9uc2l2ZSA9IHRydWU7XG4gICAgdGhpcy5zY2FsZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnNjYWxlcyA9IHt9O1xuICAgIHRoaXMuc2hvd0xpbmUgPSB0cnVlO1xuICAgIHRoaXMuZHJhd0FjdGl2ZUVsZW1lbnRzT25Ub3AgPSB0cnVlO1xuXG4gICAgdGhpcy5kZXNjcmliZShfZGVzY3JpcHRvcnMpO1xuICAgIHRoaXMuYXBwbHkoX2FwcGxpZXJzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHNjb3BlXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbdmFsdWVzXVxuXHQgKi9cbiAgc2V0KHNjb3BlLCB2YWx1ZXMpIHtcbiAgICByZXR1cm4gc2V0KHRoaXMsIHNjb3BlLCB2YWx1ZXMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzY29wZVxuXHQgKi9cbiAgZ2V0KHNjb3BlKSB7XG4gICAgcmV0dXJuIGdldFNjb3BlKHRoaXMsIHNjb3BlKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHNjb3BlXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbdmFsdWVzXVxuXHQgKi9cbiAgZGVzY3JpYmUoc2NvcGUsIHZhbHVlcykge1xuICAgIHJldHVybiBzZXQoZGVzY3JpcHRvcnMsIHNjb3BlLCB2YWx1ZXMpO1xuICB9XG5cbiAgb3ZlcnJpZGUoc2NvcGUsIHZhbHVlcykge1xuICAgIHJldHVybiBzZXQob3ZlcnJpZGVzLCBzY29wZSwgdmFsdWVzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBSb3V0ZXMgdGhlIG5hbWVkIGRlZmF1bHRzIHRvIGZhbGxiYWNrIHRvIGFub3RoZXIgc2NvcGUvbmFtZS5cblx0ICogVGhpcyByb3V0aW5nIGlzIHVzZWZ1bCB3aGVuIHRob3NlIHRhcmdldCB2YWx1ZXMsIGxpa2UgZGVmYXVsdHMuY29sb3IsIGFyZSBjaGFuZ2VkIHJ1bnRpbWUuXG5cdCAqIElmIHRoZSB2YWx1ZXMgd291bGQgYmUgY29waWVkLCB0aGUgcnVudGltZSBjaGFuZ2Ugd291bGQgbm90IHRha2UgZWZmZWN0LiBCeSByb3V0aW5nLCB0aGVcblx0ICogZmFsbGJhY2sgaXMgZXZhbHVhdGVkIGF0IGVhY2ggYWNjZXNzLCBzbyBpdHMgYWx3YXlzIHVwIHRvIGRhdGUuXG5cdCAqXG5cdCAqIEV4YW1wbGU6XG5cdCAqXG5cdCAqIFx0ZGVmYXVsdHMucm91dGUoJ2VsZW1lbnRzLmFyYycsICdiYWNrZ3JvdW5kQ29sb3InLCAnJywgJ2NvbG9yJylcblx0ICogICAtIHJlYWRzIHRoZSBiYWNrZ3JvdW5kQ29sb3IgZnJvbSBkZWZhdWx0cy5jb2xvciB3aGVuIHVuZGVmaW5lZCBsb2NhbGx5XG5cdCAqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzY29wZSBTY29wZSB0aGlzIHJvdXRlIGFwcGxpZXMgdG8uXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIFByb3BlcnR5IG5hbWUgdGhhdCBzaG91bGQgYmUgcm91dGVkIHRvIGRpZmZlcmVudCBuYW1lc3BhY2Ugd2hlbiBub3QgZGVmaW5lZCBoZXJlLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGFyZ2V0U2NvcGUgVGhlIG5hbWVzcGFjZSB3aGVyZSB0aG9zZSBwcm9wZXJ0aWVzIHNob3VsZCBiZSByb3V0ZWQgdG8uXG5cdCAqIEVtcHR5IHN0cmluZyAoJycpIGlzIHRoZSByb290IG9mIGRlZmF1bHRzLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGFyZ2V0TmFtZSBUaGUgdGFyZ2V0IG5hbWUgaW4gdGhlIHRhcmdldCBzY29wZSB0aGUgcHJvcGVydHkgc2hvdWxkIGJlIHJvdXRlZCB0by5cblx0ICovXG4gIHJvdXRlKHNjb3BlLCBuYW1lLCB0YXJnZXRTY29wZSwgdGFyZ2V0TmFtZSkge1xuICAgIGNvbnN0IHNjb3BlT2JqZWN0ID0gZ2V0U2NvcGUodGhpcywgc2NvcGUpO1xuICAgIGNvbnN0IHRhcmdldFNjb3BlT2JqZWN0ID0gZ2V0U2NvcGUodGhpcywgdGFyZ2V0U2NvcGUpO1xuICAgIGNvbnN0IHByaXZhdGVOYW1lID0gJ18nICsgbmFtZTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHNjb3BlT2JqZWN0LCB7XG4gICAgICAvLyBBIHByaXZhdGUgcHJvcGVydHkgaXMgZGVmaW5lZCB0byBob2xkIHRoZSBhY3R1YWwgdmFsdWUsIHdoZW4gdGhpcyBwcm9wZXJ0eSBpcyBzZXQgaW4gaXRzIHNjb3BlIChzZXQgaW4gdGhlIHNldHRlcilcbiAgICAgIFtwcml2YXRlTmFtZV06IHtcbiAgICAgICAgdmFsdWU6IHNjb3BlT2JqZWN0W25hbWVdLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgfSxcbiAgICAgIC8vIFRoZSBhY3R1YWwgcHJvcGVydHkgaXMgZGVmaW5lZCBhcyBnZXR0ZXIvc2V0dGVyIHNvIHdlIGNhbiBkbyB0aGUgcm91dGluZyB3aGVuIHZhbHVlIGlzIG5vdCBsb2NhbGx5IHNldC5cbiAgICAgIFtuYW1lXToge1xuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgY29uc3QgbG9jYWwgPSB0aGlzW3ByaXZhdGVOYW1lXTtcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSB0YXJnZXRTY29wZU9iamVjdFt0YXJnZXROYW1lXTtcbiAgICAgICAgICBpZiAoaXNPYmplY3QobG9jYWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgdGFyZ2V0LCBsb2NhbCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZU9yRGVmYXVsdChsb2NhbCwgdGFyZ2V0KTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0KHZhbHVlKSB7XG4gICAgICAgICAgdGhpc1twcml2YXRlTmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgYXBwbHkoYXBwbGllcnMpIHtcbiAgICBhcHBsaWVycy5mb3JFYWNoKChhcHBseSkgPT4gYXBwbHkodGhpcykpO1xuICB9XG59XG5cbi8vIHNpbmdsZXRvbiBpbnN0YW5jZVxuZXhwb3J0IGRlZmF1bHQgLyogI19fUFVSRV9fICovIG5ldyBEZWZhdWx0cyh7XG4gIF9zY3JpcHRhYmxlOiAobmFtZSkgPT4gIW5hbWUuc3RhcnRzV2l0aCgnb24nKSxcbiAgX2luZGV4YWJsZTogKG5hbWUpID0+IG5hbWUgIT09ICdldmVudHMnLFxuICBob3Zlcjoge1xuICAgIF9mYWxsYmFjazogJ2ludGVyYWN0aW9uJ1xuICB9LFxuICBpbnRlcmFjdGlvbjoge1xuICAgIF9zY3JpcHRhYmxlOiBmYWxzZSxcbiAgICBfaW5kZXhhYmxlOiBmYWxzZSxcbiAgfVxufSwgW2FwcGx5QW5pbWF0aW9uc0RlZmF1bHRzLCBhcHBseUxheW91dHNEZWZhdWx0cywgYXBwbHlTY2FsZURlZmF1bHRzXSk7XG4iLCAiaW1wb3J0IHR5cGUge1xuICBDaGFydCxcbiAgUG9pbnQsXG4gIEZvbnRTcGVjLFxuICBDYW52YXNGb250U3BlYyxcbiAgUG9pbnRTdHlsZSxcbiAgUmVuZGVyVGV4dE9wdHMsXG4gIEJhY2tkcm9wT3B0aW9uc1xufSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIFRSQkwsXG4gIFNwbGluZVBvaW50LFxuICBSb3VuZGVkUmVjdCxcbiAgVFJCTENvcm5lcnNcbn0gZnJvbSAnLi4vdHlwZXMvZ2VvbWV0cmljLmpzJztcbmltcG9ydCB7aXNBcnJheSwgaXNOdWxsT3JVbmRlZn0gZnJvbSAnLi9oZWxwZXJzLmNvcmUuanMnO1xuaW1wb3J0IHtQSSwgVEFVLCBIQUxGX1BJLCBRVUFSVEVSX1BJLCBUV09fVEhJUkRTX1BJLCBSQURfUEVSX0RFR30gZnJvbSAnLi9oZWxwZXJzLm1hdGguanMnO1xuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiBmb250IG9iamVjdCBpbnRvIGEgQ1NTIGZvbnQgc3RyaW5nLlxuICogQHBhcmFtIGZvbnQgLSBBIGZvbnQgb2JqZWN0LlxuICogQHJldHVybiBUaGUgQ1NTIGZvbnQgc3RyaW5nLiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL2ZvbnRcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0ZvbnRTdHJpbmcoZm9udDogRm9udFNwZWMpIHtcbiAgaWYgKCFmb250IHx8IGlzTnVsbE9yVW5kZWYoZm9udC5zaXplKSB8fCBpc051bGxPclVuZGVmKGZvbnQuZmFtaWx5KSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIChmb250LnN0eWxlID8gZm9udC5zdHlsZSArICcgJyA6ICcnKVxuXHRcdCsgKGZvbnQud2VpZ2h0ID8gZm9udC53ZWlnaHQgKyAnICcgOiAnJylcblx0XHQrIGZvbnQuc2l6ZSArICdweCAnXG5cdFx0KyBmb250LmZhbWlseTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX21lYXN1cmVUZXh0KFxuICBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCxcbiAgZGF0YTogUmVjb3JkPHN0cmluZywgbnVtYmVyPixcbiAgZ2M6IHN0cmluZ1tdLFxuICBsb25nZXN0OiBudW1iZXIsXG4gIHN0cmluZzogc3RyaW5nXG4pIHtcbiAgbGV0IHRleHRXaWR0aCA9IGRhdGFbc3RyaW5nXTtcbiAgaWYgKCF0ZXh0V2lkdGgpIHtcbiAgICB0ZXh0V2lkdGggPSBkYXRhW3N0cmluZ10gPSBjdHgubWVhc3VyZVRleHQoc3RyaW5nKS53aWR0aDtcbiAgICBnYy5wdXNoKHN0cmluZyk7XG4gIH1cbiAgaWYgKHRleHRXaWR0aCA+IGxvbmdlc3QpIHtcbiAgICBsb25nZXN0ID0gdGV4dFdpZHRoO1xuICB9XG4gIHJldHVybiBsb25nZXN0O1xufVxuXG50eXBlIFRoaW5nID0gc3RyaW5nIHwgdW5kZWZpbmVkIHwgbnVsbFxudHlwZSBUaGluZ3MgPSAoVGhpbmcgfCBUaGluZ1tdKVtdXG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbXBsZXhpdHlcbmV4cG9ydCBmdW5jdGlvbiBfbG9uZ2VzdFRleHQoXG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICBmb250OiBzdHJpbmcsXG4gIGFycmF5T2ZUaGluZ3M6IFRoaW5ncyxcbiAgY2FjaGU/OiB7ZGF0YT86IFJlY29yZDxzdHJpbmcsIG51bWJlcj4sIGdhcmJhZ2VDb2xsZWN0Pzogc3RyaW5nW10sIGZvbnQ/OiBzdHJpbmd9XG4pIHtcbiAgY2FjaGUgPSBjYWNoZSB8fCB7fTtcbiAgbGV0IGRhdGEgPSBjYWNoZS5kYXRhID0gY2FjaGUuZGF0YSB8fCB7fTtcbiAgbGV0IGdjID0gY2FjaGUuZ2FyYmFnZUNvbGxlY3QgPSBjYWNoZS5nYXJiYWdlQ29sbGVjdCB8fCBbXTtcblxuICBpZiAoY2FjaGUuZm9udCAhPT0gZm9udCkge1xuICAgIGRhdGEgPSBjYWNoZS5kYXRhID0ge307XG4gICAgZ2MgPSBjYWNoZS5nYXJiYWdlQ29sbGVjdCA9IFtdO1xuICAgIGNhY2hlLmZvbnQgPSBmb250O1xuICB9XG5cbiAgY3R4LnNhdmUoKTtcblxuICBjdHguZm9udCA9IGZvbnQ7XG4gIGxldCBsb25nZXN0ID0gMDtcbiAgY29uc3QgaWxlbiA9IGFycmF5T2ZUaGluZ3MubGVuZ3RoO1xuICBsZXQgaTogbnVtYmVyLCBqOiBudW1iZXIsIGpsZW46IG51bWJlciwgdGhpbmc6IFRoaW5nIHwgVGhpbmdbXSwgbmVzdGVkVGhpbmc6IFRoaW5nIHwgVGhpbmdbXTtcbiAgZm9yIChpID0gMDsgaSA8IGlsZW47IGkrKykge1xuICAgIHRoaW5nID0gYXJyYXlPZlRoaW5nc1tpXTtcblxuICAgIC8vIFVuZGVmaW5lZCBzdHJpbmdzIGFuZCBhcnJheXMgc2hvdWxkIG5vdCBiZSBtZWFzdXJlZFxuICAgIGlmICh0aGluZyAhPT0gdW5kZWZpbmVkICYmIHRoaW5nICE9PSBudWxsICYmICFpc0FycmF5KHRoaW5nKSkge1xuICAgICAgbG9uZ2VzdCA9IF9tZWFzdXJlVGV4dChjdHgsIGRhdGEsIGdjLCBsb25nZXN0LCB0aGluZyk7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KHRoaW5nKSkge1xuICAgICAgLy8gaWYgaXQgaXMgYW4gYXJyYXkgbGV0cyBtZWFzdXJlIGVhY2ggZWxlbWVudFxuICAgICAgLy8gdG8gZG8gbWF5YmUgc2ltcGxpZnkgdGhpcyBmdW5jdGlvbiBhIGJpdCBzbyB3ZSBjYW4gZG8gdGhpcyBtb3JlIHJlY3Vyc2l2ZWx5P1xuICAgICAgZm9yIChqID0gMCwgamxlbiA9IHRoaW5nLmxlbmd0aDsgaiA8IGpsZW47IGorKykge1xuICAgICAgICBuZXN0ZWRUaGluZyA9IHRoaW5nW2pdO1xuICAgICAgICAvLyBVbmRlZmluZWQgc3RyaW5ncyBhbmQgYXJyYXlzIHNob3VsZCBub3QgYmUgbWVhc3VyZWRcbiAgICAgICAgaWYgKG5lc3RlZFRoaW5nICE9PSB1bmRlZmluZWQgJiYgbmVzdGVkVGhpbmcgIT09IG51bGwgJiYgIWlzQXJyYXkobmVzdGVkVGhpbmcpKSB7XG4gICAgICAgICAgbG9uZ2VzdCA9IF9tZWFzdXJlVGV4dChjdHgsIGRhdGEsIGdjLCBsb25nZXN0LCBuZXN0ZWRUaGluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjdHgucmVzdG9yZSgpO1xuXG4gIGNvbnN0IGdjTGVuID0gZ2MubGVuZ3RoIC8gMjtcbiAgaWYgKGdjTGVuID4gYXJyYXlPZlRoaW5ncy5sZW5ndGgpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgZ2NMZW47IGkrKykge1xuICAgICAgZGVsZXRlIGRhdGFbZ2NbaV1dO1xuICAgIH1cbiAgICBnYy5zcGxpY2UoMCwgZ2NMZW4pO1xuICB9XG4gIHJldHVybiBsb25nZXN0O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGFsaWduZWQgcGl4ZWwgdmFsdWUgdG8gYXZvaWQgYW50aS1hbGlhc2luZyBibHVyXG4gKiBAcGFyYW0gY2hhcnQgLSBUaGUgY2hhcnQgaW5zdGFuY2UuXG4gKiBAcGFyYW0gcGl4ZWwgLSBBIHBpeGVsIHZhbHVlLlxuICogQHBhcmFtIHdpZHRoIC0gVGhlIHdpZHRoIG9mIHRoZSBlbGVtZW50LlxuICogQHJldHVybnMgVGhlIGFsaWduZWQgcGl4ZWwgdmFsdWUuXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2FsaWduUGl4ZWwoY2hhcnQ6IENoYXJ0LCBwaXhlbDogbnVtYmVyLCB3aWR0aDogbnVtYmVyKSB7XG4gIGNvbnN0IGRldmljZVBpeGVsUmF0aW8gPSBjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbztcbiAgY29uc3QgaGFsZldpZHRoID0gd2lkdGggIT09IDAgPyBNYXRoLm1heCh3aWR0aCAvIDIsIDAuNSkgOiAwO1xuICByZXR1cm4gTWF0aC5yb3VuZCgocGl4ZWwgLSBoYWxmV2lkdGgpICogZGV2aWNlUGl4ZWxSYXRpbykgLyBkZXZpY2VQaXhlbFJhdGlvICsgaGFsZldpZHRoO1xufVxuXG4vKipcbiAqIENsZWFycyB0aGUgZW50aXJlIGNhbnZhcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyQ2FudmFzKGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsIGN0eD86IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCkge1xuICBjdHggPSBjdHggfHwgY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG5cbiAgY3R4LnNhdmUoKTtcbiAgLy8gY2FudmFzLndpZHRoIGFuZCBjYW52YXMuaGVpZ2h0IGRvIG5vdCBjb25zaWRlciB0aGUgY2FudmFzIHRyYW5zZm9ybSxcbiAgLy8gd2hpbGUgY2xlYXJSZWN0IGRvZXNcbiAgY3R4LnJlc2V0VHJhbnNmb3JtKCk7XG4gIGN0eC5jbGVhclJlY3QoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgY3R4LnJlc3RvcmUoKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEcmF3UG9pbnRPcHRpb25zIHtcbiAgcG9pbnRTdHlsZTogUG9pbnRTdHlsZTtcbiAgcm90YXRpb24/OiBudW1iZXI7XG4gIHJhZGl1czogbnVtYmVyO1xuICBib3JkZXJXaWR0aDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZHJhd1BvaW50KFxuICBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCxcbiAgb3B0aW9uczogRHJhd1BvaW50T3B0aW9ucyxcbiAgeDogbnVtYmVyLFxuICB5OiBudW1iZXJcbikge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVzZS1iZWZvcmUtZGVmaW5lXG4gIGRyYXdQb2ludExlZ2VuZChjdHgsIG9wdGlvbnMsIHgsIHksIG51bGwpO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuZXhwb3J0IGZ1bmN0aW9uIGRyYXdQb2ludExlZ2VuZChcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIG9wdGlvbnM6IERyYXdQb2ludE9wdGlvbnMsXG4gIHg6IG51bWJlcixcbiAgeTogbnVtYmVyLFxuICB3OiBudW1iZXJcbikge1xuICBsZXQgdHlwZTogc3RyaW5nLCB4T2Zmc2V0OiBudW1iZXIsIHlPZmZzZXQ6IG51bWJlciwgc2l6ZTogbnVtYmVyLCBjb3JuZXJSYWRpdXM6IG51bWJlciwgd2lkdGg6IG51bWJlciwgeE9mZnNldFc6IG51bWJlciwgeU9mZnNldFc6IG51bWJlcjtcbiAgY29uc3Qgc3R5bGUgPSBvcHRpb25zLnBvaW50U3R5bGU7XG4gIGNvbnN0IHJvdGF0aW9uID0gb3B0aW9ucy5yb3RhdGlvbjtcbiAgY29uc3QgcmFkaXVzID0gb3B0aW9ucy5yYWRpdXM7XG4gIGxldCByYWQgPSAocm90YXRpb24gfHwgMCkgKiBSQURfUEVSX0RFRztcblxuICBpZiAoc3R5bGUgJiYgdHlwZW9mIHN0eWxlID09PSAnb2JqZWN0Jykge1xuICAgIHR5cGUgPSBzdHlsZS50b1N0cmluZygpO1xuICAgIGlmICh0eXBlID09PSAnW29iamVjdCBIVE1MSW1hZ2VFbGVtZW50XScgfHwgdHlwZSA9PT0gJ1tvYmplY3QgSFRNTENhbnZhc0VsZW1lbnRdJykge1xuICAgICAgY3R4LnNhdmUoKTtcbiAgICAgIGN0eC50cmFuc2xhdGUoeCwgeSk7XG4gICAgICBjdHgucm90YXRlKHJhZCk7XG4gICAgICBjdHguZHJhd0ltYWdlKHN0eWxlLCAtc3R5bGUud2lkdGggLyAyLCAtc3R5bGUuaGVpZ2h0IC8gMiwgc3R5bGUud2lkdGgsIHN0eWxlLmhlaWdodCk7XG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc05hTihyYWRpdXMpIHx8IHJhZGl1cyA8PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY3R4LmJlZ2luUGF0aCgpO1xuXG4gIHN3aXRjaCAoc3R5bGUpIHtcbiAgLy8gRGVmYXVsdCBpbmNsdWRlcyBjaXJjbGVcbiAgICBkZWZhdWx0OlxuICAgICAgaWYgKHcpIHtcbiAgICAgICAgY3R4LmVsbGlwc2UoeCwgeSwgdyAvIDIsIHJhZGl1cywgMCwgMCwgVEFVKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN0eC5hcmMoeCwgeSwgcmFkaXVzLCAwLCBUQVUpO1xuICAgICAgfVxuICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndHJpYW5nbGUnOlxuICAgICAgd2lkdGggPSB3ID8gdyAvIDIgOiByYWRpdXM7XG4gICAgICBjdHgubW92ZVRvKHggKyBNYXRoLnNpbihyYWQpICogd2lkdGgsIHkgLSBNYXRoLmNvcyhyYWQpICogcmFkaXVzKTtcbiAgICAgIHJhZCArPSBUV09fVEhJUkRTX1BJO1xuICAgICAgY3R4LmxpbmVUbyh4ICsgTWF0aC5zaW4ocmFkKSAqIHdpZHRoLCB5IC0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cyk7XG4gICAgICByYWQgKz0gVFdPX1RISVJEU19QSTtcbiAgICAgIGN0eC5saW5lVG8oeCArIE1hdGguc2luKHJhZCkgKiB3aWR0aCwgeSAtIE1hdGguY29zKHJhZCkgKiByYWRpdXMpO1xuICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAncmVjdFJvdW5kZWQnOlxuICAgIC8vIE5PVEU6IHRoZSByb3VuZGVkIHJlY3QgaW1wbGVtZW50YXRpb24gY2hhbmdlZCB0byB1c2UgYGFyY2AgaW5zdGVhZCBvZlxuICAgIC8vIGBxdWFkcmF0aWNDdXJ2ZVRvYCBzaW5jZSBpdCBnZW5lcmF0ZXMgYmV0dGVyIHJlc3VsdHMgd2hlbiByZWN0IGlzXG4gICAgLy8gYWxtb3N0IGEgY2lyY2xlLiAwLjUxNiAoaW5zdGVhZCBvZiAwLjUpIHByb2R1Y2VzIHJlc3VsdHMgd2l0aCB2aXN1YWxseVxuICAgIC8vIGNsb3NlciBwcm9wb3J0aW9uIHRvIHRoZSBwcmV2aW91cyBpbXBsIGFuZCBpdCBpcyBpbnNjcmliZWQgaW4gdGhlXG4gICAgLy8gY2lyY2xlIHdpdGggYHJhZGl1c2AuIEZvciBtb3JlIGRldGFpbHMsIHNlZSB0aGUgZm9sbG93aW5nIFBSczpcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNTU5N1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy81ODU4XG4gICAgICBjb3JuZXJSYWRpdXMgPSByYWRpdXMgKiAwLjUxNjtcbiAgICAgIHNpemUgPSByYWRpdXMgLSBjb3JuZXJSYWRpdXM7XG4gICAgICB4T2Zmc2V0ID0gTWF0aC5jb3MocmFkICsgUVVBUlRFUl9QSSkgKiBzaXplO1xuICAgICAgeE9mZnNldFcgPSBNYXRoLmNvcyhyYWQgKyBRVUFSVEVSX1BJKSAqICh3ID8gdyAvIDIgLSBjb3JuZXJSYWRpdXMgOiBzaXplKTtcbiAgICAgIHlPZmZzZXQgPSBNYXRoLnNpbihyYWQgKyBRVUFSVEVSX1BJKSAqIHNpemU7XG4gICAgICB5T2Zmc2V0VyA9IE1hdGguc2luKHJhZCArIFFVQVJURVJfUEkpICogKHcgPyB3IC8gMiAtIGNvcm5lclJhZGl1cyA6IHNpemUpO1xuICAgICAgY3R4LmFyYyh4IC0geE9mZnNldFcsIHkgLSB5T2Zmc2V0LCBjb3JuZXJSYWRpdXMsIHJhZCAtIFBJLCByYWQgLSBIQUxGX1BJKTtcbiAgICAgIGN0eC5hcmMoeCArIHlPZmZzZXRXLCB5IC0geE9mZnNldCwgY29ybmVyUmFkaXVzLCByYWQgLSBIQUxGX1BJLCByYWQpO1xuICAgICAgY3R4LmFyYyh4ICsgeE9mZnNldFcsIHkgKyB5T2Zmc2V0LCBjb3JuZXJSYWRpdXMsIHJhZCwgcmFkICsgSEFMRl9QSSk7XG4gICAgICBjdHguYXJjKHggLSB5T2Zmc2V0VywgeSArIHhPZmZzZXQsIGNvcm5lclJhZGl1cywgcmFkICsgSEFMRl9QSSwgcmFkICsgUEkpO1xuICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAncmVjdCc6XG4gICAgICBpZiAoIXJvdGF0aW9uKSB7XG4gICAgICAgIHNpemUgPSBNYXRoLlNRUlQxXzIgKiByYWRpdXM7XG4gICAgICAgIHdpZHRoID0gdyA/IHcgLyAyIDogc2l6ZTtcbiAgICAgICAgY3R4LnJlY3QoeCAtIHdpZHRoLCB5IC0gc2l6ZSwgMiAqIHdpZHRoLCAyICogc2l6ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgcmFkICs9IFFVQVJURVJfUEk7XG4gICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgJ3JlY3RSb3QnOlxuICAgICAgeE9mZnNldFcgPSBNYXRoLmNvcyhyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICB4T2Zmc2V0ID0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cztcbiAgICAgIHlPZmZzZXQgPSBNYXRoLnNpbihyYWQpICogcmFkaXVzO1xuICAgICAgeU9mZnNldFcgPSBNYXRoLnNpbihyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICBjdHgubW92ZVRvKHggLSB4T2Zmc2V0VywgeSAtIHlPZmZzZXQpO1xuICAgICAgY3R4LmxpbmVUbyh4ICsgeU9mZnNldFcsIHkgLSB4T2Zmc2V0KTtcbiAgICAgIGN0eC5saW5lVG8oeCArIHhPZmZzZXRXLCB5ICsgeU9mZnNldCk7XG4gICAgICBjdHgubGluZVRvKHggLSB5T2Zmc2V0VywgeSArIHhPZmZzZXQpO1xuICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnY3Jvc3NSb3QnOlxuICAgICAgcmFkICs9IFFVQVJURVJfUEk7XG4gICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgIGNhc2UgJ2Nyb3NzJzpcbiAgICAgIHhPZmZzZXRXID0gTWF0aC5jb3MocmFkKSAqICh3ID8gdyAvIDIgOiByYWRpdXMpO1xuICAgICAgeE9mZnNldCA9IE1hdGguY29zKHJhZCkgKiByYWRpdXM7XG4gICAgICB5T2Zmc2V0ID0gTWF0aC5zaW4ocmFkKSAqIHJhZGl1cztcbiAgICAgIHlPZmZzZXRXID0gTWF0aC5zaW4ocmFkKSAqICh3ID8gdyAvIDIgOiByYWRpdXMpO1xuICAgICAgY3R4Lm1vdmVUbyh4IC0geE9mZnNldFcsIHkgLSB5T2Zmc2V0KTtcbiAgICAgIGN0eC5saW5lVG8oeCArIHhPZmZzZXRXLCB5ICsgeU9mZnNldCk7XG4gICAgICBjdHgubW92ZVRvKHggKyB5T2Zmc2V0VywgeSAtIHhPZmZzZXQpO1xuICAgICAgY3R4LmxpbmVUbyh4IC0geU9mZnNldFcsIHkgKyB4T2Zmc2V0KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3N0YXInOlxuICAgICAgeE9mZnNldFcgPSBNYXRoLmNvcyhyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICB4T2Zmc2V0ID0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cztcbiAgICAgIHlPZmZzZXQgPSBNYXRoLnNpbihyYWQpICogcmFkaXVzO1xuICAgICAgeU9mZnNldFcgPSBNYXRoLnNpbihyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyk7XG4gICAgICBjdHgubW92ZVRvKHggLSB4T2Zmc2V0VywgeSAtIHlPZmZzZXQpO1xuICAgICAgY3R4LmxpbmVUbyh4ICsgeE9mZnNldFcsIHkgKyB5T2Zmc2V0KTtcbiAgICAgIGN0eC5tb3ZlVG8oeCArIHlPZmZzZXRXLCB5IC0geE9mZnNldCk7XG4gICAgICBjdHgubGluZVRvKHggLSB5T2Zmc2V0VywgeSArIHhPZmZzZXQpO1xuICAgICAgcmFkICs9IFFVQVJURVJfUEk7XG4gICAgICB4T2Zmc2V0VyA9IE1hdGguY29zKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgIHhPZmZzZXQgPSBNYXRoLmNvcyhyYWQpICogcmFkaXVzO1xuICAgICAgeU9mZnNldCA9IE1hdGguc2luKHJhZCkgKiByYWRpdXM7XG4gICAgICB5T2Zmc2V0VyA9IE1hdGguc2luKHJhZCkgKiAodyA/IHcgLyAyIDogcmFkaXVzKTtcbiAgICAgIGN0eC5tb3ZlVG8oeCAtIHhPZmZzZXRXLCB5IC0geU9mZnNldCk7XG4gICAgICBjdHgubGluZVRvKHggKyB4T2Zmc2V0VywgeSArIHlPZmZzZXQpO1xuICAgICAgY3R4Lm1vdmVUbyh4ICsgeU9mZnNldFcsIHkgLSB4T2Zmc2V0KTtcbiAgICAgIGN0eC5saW5lVG8oeCAtIHlPZmZzZXRXLCB5ICsgeE9mZnNldCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdsaW5lJzpcbiAgICAgIHhPZmZzZXQgPSB3ID8gdyAvIDIgOiBNYXRoLmNvcyhyYWQpICogcmFkaXVzO1xuICAgICAgeU9mZnNldCA9IE1hdGguc2luKHJhZCkgKiByYWRpdXM7XG4gICAgICBjdHgubW92ZVRvKHggLSB4T2Zmc2V0LCB5IC0geU9mZnNldCk7XG4gICAgICBjdHgubGluZVRvKHggKyB4T2Zmc2V0LCB5ICsgeU9mZnNldCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdkYXNoJzpcbiAgICAgIGN0eC5tb3ZlVG8oeCwgeSk7XG4gICAgICBjdHgubGluZVRvKHggKyBNYXRoLmNvcyhyYWQpICogKHcgPyB3IC8gMiA6IHJhZGl1cyksIHkgKyBNYXRoLnNpbihyYWQpICogcmFkaXVzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgZmFsc2U6XG4gICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIGN0eC5maWxsKCk7XG4gIGlmIChvcHRpb25zLmJvcmRlcldpZHRoID4gMCkge1xuICAgIGN0eC5zdHJva2UoKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcG9pbnQgaXMgaW5zaWRlIHRoZSByZWN0YW5nbGVcbiAqIEBwYXJhbSBwb2ludCAtIFRoZSBwb2ludCB0byB0ZXN0XG4gKiBAcGFyYW0gYXJlYSAtIFRoZSByZWN0YW5nbGVcbiAqIEBwYXJhbSBtYXJnaW4gLSBhbGxvd2VkIG1hcmdpblxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9pc1BvaW50SW5BcmVhKFxuICBwb2ludDogUG9pbnQsXG4gIGFyZWE6IFRSQkwsXG4gIG1hcmdpbj86IG51bWJlclxuKSB7XG4gIG1hcmdpbiA9IG1hcmdpbiB8fCAwLjU7IC8vIG1hcmdpbiAtIGRlZmF1bHQgaXMgdG8gbWF0Y2ggcm91bmRlZCBkZWNpbWFsc1xuXG4gIHJldHVybiAhYXJlYSB8fCAocG9pbnQgJiYgcG9pbnQueCA+IGFyZWEubGVmdCAtIG1hcmdpbiAmJiBwb2ludC54IDwgYXJlYS5yaWdodCArIG1hcmdpbiAmJlxuXHRcdHBvaW50LnkgPiBhcmVhLnRvcCAtIG1hcmdpbiAmJiBwb2ludC55IDwgYXJlYS5ib3R0b20gKyBtYXJnaW4pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2xpcEFyZWEoY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsIGFyZWE6IFRSQkwpIHtcbiAgY3R4LnNhdmUoKTtcbiAgY3R4LmJlZ2luUGF0aCgpO1xuICBjdHgucmVjdChhcmVhLmxlZnQsIGFyZWEudG9wLCBhcmVhLnJpZ2h0IC0gYXJlYS5sZWZ0LCBhcmVhLmJvdHRvbSAtIGFyZWEudG9wKTtcbiAgY3R4LmNsaXAoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVuY2xpcEFyZWEoY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQpIHtcbiAgY3R4LnJlc3RvcmUoKTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX3N0ZXBwZWRMaW5lVG8oXG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICBwcmV2aW91czogUG9pbnQsXG4gIHRhcmdldDogUG9pbnQsXG4gIGZsaXA/OiBib29sZWFuLFxuICBtb2RlPzogc3RyaW5nXG4pIHtcbiAgaWYgKCFwcmV2aW91cykge1xuICAgIHJldHVybiBjdHgubGluZVRvKHRhcmdldC54LCB0YXJnZXQueSk7XG4gIH1cbiAgaWYgKG1vZGUgPT09ICdtaWRkbGUnKSB7XG4gICAgY29uc3QgbWlkcG9pbnQgPSAocHJldmlvdXMueCArIHRhcmdldC54KSAvIDIuMDtcbiAgICBjdHgubGluZVRvKG1pZHBvaW50LCBwcmV2aW91cy55KTtcbiAgICBjdHgubGluZVRvKG1pZHBvaW50LCB0YXJnZXQueSk7XG4gIH0gZWxzZSBpZiAobW9kZSA9PT0gJ2FmdGVyJyAhPT0gISFmbGlwKSB7XG4gICAgY3R4LmxpbmVUbyhwcmV2aW91cy54LCB0YXJnZXQueSk7XG4gIH0gZWxzZSB7XG4gICAgY3R4LmxpbmVUbyh0YXJnZXQueCwgcHJldmlvdXMueSk7XG4gIH1cbiAgY3R4LmxpbmVUbyh0YXJnZXQueCwgdGFyZ2V0LnkpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYmV6aWVyQ3VydmVUbyhcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIHByZXZpb3VzOiBTcGxpbmVQb2ludCxcbiAgdGFyZ2V0OiBTcGxpbmVQb2ludCxcbiAgZmxpcD86IGJvb2xlYW5cbikge1xuICBpZiAoIXByZXZpb3VzKSB7XG4gICAgcmV0dXJuIGN0eC5saW5lVG8odGFyZ2V0LngsIHRhcmdldC55KTtcbiAgfVxuICBjdHguYmV6aWVyQ3VydmVUbyhcbiAgICBmbGlwID8gcHJldmlvdXMuY3AxeCA6IHByZXZpb3VzLmNwMngsXG4gICAgZmxpcCA/IHByZXZpb3VzLmNwMXkgOiBwcmV2aW91cy5jcDJ5LFxuICAgIGZsaXAgPyB0YXJnZXQuY3AyeCA6IHRhcmdldC5jcDF4LFxuICAgIGZsaXAgPyB0YXJnZXQuY3AyeSA6IHRhcmdldC5jcDF5LFxuICAgIHRhcmdldC54LFxuICAgIHRhcmdldC55KTtcbn1cblxuZnVuY3Rpb24gc2V0UmVuZGVyT3B0cyhjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgb3B0czogUmVuZGVyVGV4dE9wdHMpIHtcbiAgaWYgKG9wdHMudHJhbnNsYXRpb24pIHtcbiAgICBjdHgudHJhbnNsYXRlKG9wdHMudHJhbnNsYXRpb25bMF0sIG9wdHMudHJhbnNsYXRpb25bMV0pO1xuICB9XG5cbiAgaWYgKCFpc051bGxPclVuZGVmKG9wdHMucm90YXRpb24pKSB7XG4gICAgY3R4LnJvdGF0ZShvcHRzLnJvdGF0aW9uKTtcbiAgfVxuXG4gIGlmIChvcHRzLmNvbG9yKSB7XG4gICAgY3R4LmZpbGxTdHlsZSA9IG9wdHMuY29sb3I7XG4gIH1cblxuICBpZiAob3B0cy50ZXh0QWxpZ24pIHtcbiAgICBjdHgudGV4dEFsaWduID0gb3B0cy50ZXh0QWxpZ247XG4gIH1cblxuICBpZiAob3B0cy50ZXh0QmFzZWxpbmUpIHtcbiAgICBjdHgudGV4dEJhc2VsaW5lID0gb3B0cy50ZXh0QmFzZWxpbmU7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVjb3JhdGVUZXh0KFxuICBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCxcbiAgeDogbnVtYmVyLFxuICB5OiBudW1iZXIsXG4gIGxpbmU6IHN0cmluZyxcbiAgb3B0czogUmVuZGVyVGV4dE9wdHNcbikge1xuICBpZiAob3B0cy5zdHJpa2V0aHJvdWdoIHx8IG9wdHMudW5kZXJsaW5lKSB7XG4gICAgLyoqXG4gICAgICogTm93IHRoYXQgSUUxMSBzdXBwb3J0IGhhcyBiZWVuIGRyb3BwZWQsIHdlIGNhbiB1c2UgbW9yZVxuICAgICAqIG9mIHRoZSBUZXh0TWV0cmljcyBvYmplY3QuIFRoZSBhY3R1YWwgYm91bmRpbmcgYm94ZXNcbiAgICAgKiBhcmUgdW5mbGFnZ2VkIGluIENocm9tZSwgRmlyZWZveCwgRWRnZSwgYW5kIFNhZmFyaSBzbyB0aGV5XG4gICAgICogY2FuIGJlIHNhZmVseSB1c2VkLlxuICAgICAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvVGV4dE1ldHJpY3MjQnJvd3Nlcl9jb21wYXRpYmlsaXR5XG4gICAgICovXG4gICAgY29uc3QgbWV0cmljcyA9IGN0eC5tZWFzdXJlVGV4dChsaW5lKTtcbiAgICBjb25zdCBsZWZ0ID0geCAtIG1ldHJpY3MuYWN0dWFsQm91bmRpbmdCb3hMZWZ0O1xuICAgIGNvbnN0IHJpZ2h0ID0geCArIG1ldHJpY3MuYWN0dWFsQm91bmRpbmdCb3hSaWdodDtcbiAgICBjb25zdCB0b3AgPSB5IC0gbWV0cmljcy5hY3R1YWxCb3VuZGluZ0JveEFzY2VudDtcbiAgICBjb25zdCBib3R0b20gPSB5ICsgbWV0cmljcy5hY3R1YWxCb3VuZGluZ0JveERlc2NlbnQ7XG4gICAgY29uc3QgeURlY29yYXRpb24gPSBvcHRzLnN0cmlrZXRocm91Z2ggPyAodG9wICsgYm90dG9tKSAvIDIgOiBib3R0b207XG5cbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBjdHguZmlsbFN0eWxlO1xuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHgubGluZVdpZHRoID0gb3B0cy5kZWNvcmF0aW9uV2lkdGggfHwgMjtcbiAgICBjdHgubW92ZVRvKGxlZnQsIHlEZWNvcmF0aW9uKTtcbiAgICBjdHgubGluZVRvKHJpZ2h0LCB5RGVjb3JhdGlvbik7XG4gICAgY3R4LnN0cm9rZSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRyYXdCYWNrZHJvcChjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgb3B0czogQmFja2Ryb3BPcHRpb25zKSB7XG4gIGNvbnN0IG9sZENvbG9yID0gY3R4LmZpbGxTdHlsZTtcblxuICBjdHguZmlsbFN0eWxlID0gb3B0cy5jb2xvciBhcyBzdHJpbmc7XG4gIGN0eC5maWxsUmVjdChvcHRzLmxlZnQsIG9wdHMudG9wLCBvcHRzLndpZHRoLCBvcHRzLmhlaWdodCk7XG4gIGN0eC5maWxsU3R5bGUgPSBvbGRDb2xvcjtcbn1cblxuLyoqXG4gKiBSZW5kZXIgdGV4dCBvbnRvIHRoZSBjYW52YXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlclRleHQoXG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICB0ZXh0OiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgeDogbnVtYmVyLFxuICB5OiBudW1iZXIsXG4gIGZvbnQ6IENhbnZhc0ZvbnRTcGVjLFxuICBvcHRzOiBSZW5kZXJUZXh0T3B0cyA9IHt9XG4pIHtcbiAgY29uc3QgbGluZXMgPSBpc0FycmF5KHRleHQpID8gdGV4dCA6IFt0ZXh0XTtcbiAgY29uc3Qgc3Ryb2tlID0gb3B0cy5zdHJva2VXaWR0aCA+IDAgJiYgb3B0cy5zdHJva2VDb2xvciAhPT0gJyc7XG4gIGxldCBpOiBudW1iZXIsIGxpbmU6IHN0cmluZztcblxuICBjdHguc2F2ZSgpO1xuICBjdHguZm9udCA9IGZvbnQuc3RyaW5nO1xuICBzZXRSZW5kZXJPcHRzKGN0eCwgb3B0cyk7XG5cbiAgZm9yIChpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgKytpKSB7XG4gICAgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgaWYgKG9wdHMuYmFja2Ryb3ApIHtcbiAgICAgIGRyYXdCYWNrZHJvcChjdHgsIG9wdHMuYmFja2Ryb3ApO1xuICAgIH1cblxuICAgIGlmIChzdHJva2UpIHtcbiAgICAgIGlmIChvcHRzLnN0cm9rZUNvbG9yKSB7XG4gICAgICAgIGN0eC5zdHJva2VTdHlsZSA9IG9wdHMuc3Ryb2tlQ29sb3I7XG4gICAgICB9XG5cbiAgICAgIGlmICghaXNOdWxsT3JVbmRlZihvcHRzLnN0cm9rZVdpZHRoKSkge1xuICAgICAgICBjdHgubGluZVdpZHRoID0gb3B0cy5zdHJva2VXaWR0aDtcbiAgICAgIH1cblxuICAgICAgY3R4LnN0cm9rZVRleHQobGluZSwgeCwgeSwgb3B0cy5tYXhXaWR0aCk7XG4gICAgfVxuXG4gICAgY3R4LmZpbGxUZXh0KGxpbmUsIHgsIHksIG9wdHMubWF4V2lkdGgpO1xuICAgIGRlY29yYXRlVGV4dChjdHgsIHgsIHksIGxpbmUsIG9wdHMpO1xuXG4gICAgeSArPSBOdW1iZXIoZm9udC5saW5lSGVpZ2h0KTtcbiAgfVxuXG4gIGN0eC5yZXN0b3JlKCk7XG59XG5cbi8qKlxuICogQWRkIGEgcGF0aCBvZiBhIHJlY3RhbmdsZSB3aXRoIHJvdW5kZWQgY29ybmVycyB0byB0aGUgY3VycmVudCBzdWItcGF0aFxuICogQHBhcmFtIGN0eCAtIENvbnRleHRcbiAqIEBwYXJhbSByZWN0IC0gQm91bmRpbmcgcmVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkUm91bmRlZFJlY3RQYXRoKFxuICBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCxcbiAgcmVjdDogUm91bmRlZFJlY3QgJiB7IHJhZGl1czogVFJCTENvcm5lcnMgfVxuKSB7XG4gIGNvbnN0IHt4LCB5LCB3LCBoLCByYWRpdXN9ID0gcmVjdDtcblxuICAvLyB0b3AgbGVmdCBhcmNcbiAgY3R4LmFyYyh4ICsgcmFkaXVzLnRvcExlZnQsIHkgKyByYWRpdXMudG9wTGVmdCwgcmFkaXVzLnRvcExlZnQsIDEuNSAqIFBJLCBQSSwgdHJ1ZSk7XG5cbiAgLy8gbGluZSBmcm9tIHRvcCBsZWZ0IHRvIGJvdHRvbSBsZWZ0XG4gIGN0eC5saW5lVG8oeCwgeSArIGggLSByYWRpdXMuYm90dG9tTGVmdCk7XG5cbiAgLy8gYm90dG9tIGxlZnQgYXJjXG4gIGN0eC5hcmMoeCArIHJhZGl1cy5ib3R0b21MZWZ0LCB5ICsgaCAtIHJhZGl1cy5ib3R0b21MZWZ0LCByYWRpdXMuYm90dG9tTGVmdCwgUEksIEhBTEZfUEksIHRydWUpO1xuXG4gIC8vIGxpbmUgZnJvbSBib3R0b20gbGVmdCB0byBib3R0b20gcmlnaHRcbiAgY3R4LmxpbmVUbyh4ICsgdyAtIHJhZGl1cy5ib3R0b21SaWdodCwgeSArIGgpO1xuXG4gIC8vIGJvdHRvbSByaWdodCBhcmNcbiAgY3R4LmFyYyh4ICsgdyAtIHJhZGl1cy5ib3R0b21SaWdodCwgeSArIGggLSByYWRpdXMuYm90dG9tUmlnaHQsIHJhZGl1cy5ib3R0b21SaWdodCwgSEFMRl9QSSwgMCwgdHJ1ZSk7XG5cbiAgLy8gbGluZSBmcm9tIGJvdHRvbSByaWdodCB0byB0b3AgcmlnaHRcbiAgY3R4LmxpbmVUbyh4ICsgdywgeSArIHJhZGl1cy50b3BSaWdodCk7XG5cbiAgLy8gdG9wIHJpZ2h0IGFyY1xuICBjdHguYXJjKHggKyB3IC0gcmFkaXVzLnRvcFJpZ2h0LCB5ICsgcmFkaXVzLnRvcFJpZ2h0LCByYWRpdXMudG9wUmlnaHQsIDAsIC1IQUxGX1BJLCB0cnVlKTtcblxuICAvLyBsaW5lIGZyb20gdG9wIHJpZ2h0IHRvIHRvcCBsZWZ0XG4gIGN0eC5saW5lVG8oeCArIHJhZGl1cy50b3BMZWZ0LCB5KTtcbn1cbiIsICJpbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vY29yZS9jb3JlLmRlZmF1bHRzLmpzJztcbmltcG9ydCB7aXNBcnJheSwgaXNPYmplY3QsIHRvRGltZW5zaW9uLCB2YWx1ZU9yRGVmYXVsdH0gZnJvbSAnLi9oZWxwZXJzLmNvcmUuanMnO1xuaW1wb3J0IHt0b0ZvbnRTdHJpbmd9IGZyb20gJy4vaGVscGVycy5jYW52YXMuanMnO1xuaW1wb3J0IHR5cGUge0NoYXJ0QXJlYSwgRm9udFNwZWMsIFBvaW50fSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7VFJCTCwgVFJCTENvcm5lcnN9IGZyb20gJy4uL3R5cGVzL2dlb21ldHJpYy5qcyc7XG5cbmNvbnN0IExJTkVfSEVJR0hUID0gL14obm9ybWFsfChcXGQrKD86XFwuXFxkKyk/KShweHxlbXwlKT8pJC87XG5jb25zdCBGT05UX1NUWUxFID0gL14obm9ybWFsfGl0YWxpY3xpbml0aWFsfGluaGVyaXR8dW5zZXR8KG9ibGlxdWUoIC0/WzAtOV0/WzAtOV1kZWcpPykpJC87XG5cbi8qKlxuICogQGFsaWFzIENoYXJ0LmhlbHBlcnMub3B0aW9uc1xuICogQG5hbWVzcGFjZVxuICovXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiBsaW5lIGhlaWdodCBgdmFsdWVgIGluIHBpeGVscyBmb3IgYSBzcGVjaWZpYyBmb250IGBzaXplYC5cbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBsaW5lSGVpZ2h0IHRvIHBhcnNlIChlZy4gMS42LCAnMTRweCcsICc3NSUnLCAnMS42ZW0nKS5cbiAqIEBwYXJhbSBzaXplIC0gVGhlIGZvbnQgc2l6ZSAoaW4gcGl4ZWxzKSB1c2VkIHRvIHJlc29sdmUgcmVsYXRpdmUgYHZhbHVlYC5cbiAqIEByZXR1cm5zIFRoZSBlZmZlY3RpdmUgbGluZSBoZWlnaHQgaW4gcGl4ZWxzIChzaXplICogMS4yIGlmIHZhbHVlIGlzIGludmFsaWQpLlxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvbGluZS1oZWlnaHRcbiAqIEBzaW5jZSAyLjcuMFxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9MaW5lSGVpZ2h0KHZhbHVlOiBudW1iZXIgfCBzdHJpbmcsIHNpemU6IG51bWJlcik6IG51bWJlciB7XG4gIGNvbnN0IG1hdGNoZXMgPSAoJycgKyB2YWx1ZSkubWF0Y2goTElORV9IRUlHSFQpO1xuICBpZiAoIW1hdGNoZXMgfHwgbWF0Y2hlc1sxXSA9PT0gJ25vcm1hbCcpIHtcbiAgICByZXR1cm4gc2l6ZSAqIDEuMjtcbiAgfVxuXG4gIHZhbHVlID0gK21hdGNoZXNbMl07XG5cbiAgc3dpdGNoIChtYXRjaGVzWzNdKSB7XG4gICAgY2FzZSAncHgnOlxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIGNhc2UgJyUnOlxuICAgICAgdmFsdWUgLz0gMTAwO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIHNpemUgKiB2YWx1ZTtcbn1cblxuY29uc3QgbnVtYmVyT3JaZXJvID0gKHY6IHVua25vd24pID0+ICt2IHx8IDA7XG5cbi8qKlxuICogQHBhcmFtIHZhbHVlXG4gKiBAcGFyYW0gcHJvcHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9yZWFkVmFsdWVUb1Byb3BzPEsgZXh0ZW5kcyBzdHJpbmc+KHZhbHVlOiBudW1iZXIgfCBSZWNvcmQ8SywgbnVtYmVyPiwgcHJvcHM6IEtbXSk6IFJlY29yZDxLLCBudW1iZXI+O1xuZXhwb3J0IGZ1bmN0aW9uIF9yZWFkVmFsdWVUb1Byb3BzPEsgZXh0ZW5kcyBzdHJpbmcsIFQgZXh0ZW5kcyBzdHJpbmc+KHZhbHVlOiBudW1iZXIgfCBSZWNvcmQ8SyAmIFQsIG51bWJlcj4sIHByb3BzOiBSZWNvcmQ8VCwgSz4pOiBSZWNvcmQ8VCwgbnVtYmVyPjtcbmV4cG9ydCBmdW5jdGlvbiBfcmVhZFZhbHVlVG9Qcm9wcyh2YWx1ZTogbnVtYmVyIHwgUmVjb3JkPHN0cmluZywgbnVtYmVyPiwgcHJvcHM6IHN0cmluZ1tdIHwgUmVjb3JkPHN0cmluZywgc3RyaW5nPikge1xuICBjb25zdCByZXQgPSB7fTtcbiAgY29uc3Qgb2JqUHJvcHMgPSBpc09iamVjdChwcm9wcyk7XG4gIGNvbnN0IGtleXMgPSBvYmpQcm9wcyA/IE9iamVjdC5rZXlzKHByb3BzKSA6IHByb3BzO1xuICBjb25zdCByZWFkID0gaXNPYmplY3QodmFsdWUpXG4gICAgPyBvYmpQcm9wc1xuICAgICAgPyBwcm9wID0+IHZhbHVlT3JEZWZhdWx0KHZhbHVlW3Byb3BdLCB2YWx1ZVtwcm9wc1twcm9wXV0pXG4gICAgICA6IHByb3AgPT4gdmFsdWVbcHJvcF1cbiAgICA6ICgpID0+IHZhbHVlO1xuXG4gIGZvciAoY29uc3QgcHJvcCBvZiBrZXlzKSB7XG4gICAgcmV0W3Byb3BdID0gbnVtYmVyT3JaZXJvKHJlYWQocHJvcCkpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIHZhbHVlIGludG8gYSBUUkJMIG9iamVjdC5cbiAqIEBwYXJhbSB2YWx1ZSAtIElmIGEgbnVtYmVyLCBzZXQgdGhlIHZhbHVlIHRvIGFsbCBUUkJMIGNvbXBvbmVudCxcbiAqICBlbHNlLCBpZiBhbiBvYmplY3QsIHVzZSBkZWZpbmVkIHByb3BlcnRpZXMgYW5kIHNldHMgdW5kZWZpbmVkIG9uZXMgdG8gMC5cbiAqICB4IC8geSBhcmUgc2hvcnRoYW5kcyBmb3Igc2FtZSB2YWx1ZSBmb3IgbGVmdC9yaWdodCBhbmQgdG9wL2JvdHRvbS5cbiAqIEByZXR1cm5zIFRoZSBwYWRkaW5nIHZhbHVlcyAodG9wLCByaWdodCwgYm90dG9tLCBsZWZ0KVxuICogQHNpbmNlIDMuMC4wXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1RSQkwodmFsdWU6IG51bWJlciB8IFRSQkwgfCBQb2ludCkge1xuICByZXR1cm4gX3JlYWRWYWx1ZVRvUHJvcHModmFsdWUsIHt0b3A6ICd5JywgcmlnaHQ6ICd4JywgYm90dG9tOiAneScsIGxlZnQ6ICd4J30pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiB2YWx1ZSBpbnRvIGEgVFJCTCBjb3JuZXJzIG9iamVjdCAoc2ltaWxhciB3aXRoIGNzcyBib3JkZXItcmFkaXVzKS5cbiAqIEBwYXJhbSB2YWx1ZSAtIElmIGEgbnVtYmVyLCBzZXQgdGhlIHZhbHVlIHRvIGFsbCBUUkJMIGNvcm5lciBjb21wb25lbnRzLFxuICogIGVsc2UsIGlmIGFuIG9iamVjdCwgdXNlIGRlZmluZWQgcHJvcGVydGllcyBhbmQgc2V0cyB1bmRlZmluZWQgb25lcyB0byAwLlxuICogQHJldHVybnMgVGhlIFRSQkwgY29ybmVyIHZhbHVlcyAodG9wTGVmdCwgdG9wUmlnaHQsIGJvdHRvbUxlZnQsIGJvdHRvbVJpZ2h0KVxuICogQHNpbmNlIDMuMC4wXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b1RSQkxDb3JuZXJzKHZhbHVlOiBudW1iZXIgfCBUUkJMQ29ybmVycykge1xuICByZXR1cm4gX3JlYWRWYWx1ZVRvUHJvcHModmFsdWUsIFsndG9wTGVmdCcsICd0b3BSaWdodCcsICdib3R0b21MZWZ0JywgJ2JvdHRvbVJpZ2h0J10pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiB2YWx1ZSBpbnRvIGEgcGFkZGluZyBvYmplY3Qgd2l0aCBwcmUtY29tcHV0ZWQgd2lkdGgvaGVpZ2h0LlxuICogQHBhcmFtIHZhbHVlIC0gSWYgYSBudW1iZXIsIHNldCB0aGUgdmFsdWUgdG8gYWxsIFRSQkwgY29tcG9uZW50LFxuICogIGVsc2UsIGlmIGFuIG9iamVjdCwgdXNlIGRlZmluZWQgcHJvcGVydGllcyBhbmQgc2V0cyB1bmRlZmluZWQgb25lcyB0byAwLlxuICogIHggLyB5IGFyZSBzaG9ydGhhbmRzIGZvciBzYW1lIHZhbHVlIGZvciBsZWZ0L3JpZ2h0IGFuZCB0b3AvYm90dG9tLlxuICogQHJldHVybnMgVGhlIHBhZGRpbmcgdmFsdWVzICh0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQsIHdpZHRoLCBoZWlnaHQpXG4gKiBAc2luY2UgMi43LjBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvUGFkZGluZyh2YWx1ZT86IG51bWJlciB8IFRSQkwpOiBDaGFydEFyZWEge1xuICBjb25zdCBvYmogPSB0b1RSQkwodmFsdWUpIGFzIENoYXJ0QXJlYTtcblxuICBvYmoud2lkdGggPSBvYmoubGVmdCArIG9iai5yaWdodDtcbiAgb2JqLmhlaWdodCA9IG9iai50b3AgKyBvYmouYm90dG9tO1xuXG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogUGFyc2VzIGZvbnQgb3B0aW9ucyBhbmQgcmV0dXJucyB0aGUgZm9udCBvYmplY3QuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEEgb2JqZWN0IHRoYXQgY29udGFpbnMgZm9udCBvcHRpb25zIHRvIGJlIHBhcnNlZC5cbiAqIEBwYXJhbSBmYWxsYmFjayAtIEEgb2JqZWN0IHRoYXQgY29udGFpbnMgZmFsbGJhY2sgZm9udCBvcHRpb25zLlxuICogQHJldHVybiBUaGUgZm9udCBvYmplY3QuXG4gKiBAcHJpdmF0ZVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0b0ZvbnQob3B0aW9uczogUGFydGlhbDxGb250U3BlYz4sIGZhbGxiYWNrPzogUGFydGlhbDxGb250U3BlYz4pIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGZhbGxiYWNrID0gZmFsbGJhY2sgfHwgZGVmYXVsdHMuZm9udCBhcyBGb250U3BlYztcblxuICBsZXQgc2l6ZSA9IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMuc2l6ZSwgZmFsbGJhY2suc2l6ZSk7XG5cbiAgaWYgKHR5cGVvZiBzaXplID09PSAnc3RyaW5nJykge1xuICAgIHNpemUgPSBwYXJzZUludChzaXplLCAxMCk7XG4gIH1cbiAgbGV0IHN0eWxlID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy5zdHlsZSwgZmFsbGJhY2suc3R5bGUpO1xuICBpZiAoc3R5bGUgJiYgISgnJyArIHN0eWxlKS5tYXRjaChGT05UX1NUWUxFKSkge1xuICAgIGNvbnNvbGUud2FybignSW52YWxpZCBmb250IHN0eWxlIHNwZWNpZmllZDogXCInICsgc3R5bGUgKyAnXCInKTtcbiAgICBzdHlsZSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGZvbnQgPSB7XG4gICAgZmFtaWx5OiB2YWx1ZU9yRGVmYXVsdChvcHRpb25zLmZhbWlseSwgZmFsbGJhY2suZmFtaWx5KSxcbiAgICBsaW5lSGVpZ2h0OiB0b0xpbmVIZWlnaHQodmFsdWVPckRlZmF1bHQob3B0aW9ucy5saW5lSGVpZ2h0LCBmYWxsYmFjay5saW5lSGVpZ2h0KSwgc2l6ZSksXG4gICAgc2l6ZSxcbiAgICBzdHlsZSxcbiAgICB3ZWlnaHQ6IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMud2VpZ2h0LCBmYWxsYmFjay53ZWlnaHQpLFxuICAgIHN0cmluZzogJydcbiAgfTtcblxuICBmb250LnN0cmluZyA9IHRvRm9udFN0cmluZyhmb250KTtcbiAgcmV0dXJuIGZvbnQ7XG59XG5cbi8qKlxuICogRXZhbHVhdGVzIHRoZSBnaXZlbiBgaW5wdXRzYCBzZXF1ZW50aWFsbHkgYW5kIHJldHVybnMgdGhlIGZpcnN0IGRlZmluZWQgdmFsdWUuXG4gKiBAcGFyYW0gaW5wdXRzIC0gQW4gYXJyYXkgb2YgdmFsdWVzLCBmYWxsaW5nIGJhY2sgdG8gdGhlIGxhc3QgdmFsdWUuXG4gKiBAcGFyYW0gY29udGV4dCAtIElmIGRlZmluZWQgYW5kIHRoZSBjdXJyZW50IHZhbHVlIGlzIGEgZnVuY3Rpb24sIHRoZSB2YWx1ZVxuICogaXMgY2FsbGVkIHdpdGggYGNvbnRleHRgIGFzIGZpcnN0IGFyZ3VtZW50IGFuZCB0aGUgcmVzdWx0IGJlY29tZXMgdGhlIG5ldyBpbnB1dC5cbiAqIEBwYXJhbSBpbmRleCAtIElmIGRlZmluZWQgYW5kIHRoZSBjdXJyZW50IHZhbHVlIGlzIGFuIGFycmF5LCB0aGUgdmFsdWVcbiAqIGF0IGBpbmRleGAgYmVjb21lIHRoZSBuZXcgaW5wdXQuXG4gKiBAcGFyYW0gaW5mbyAtIG9iamVjdCB0byByZXR1cm4gaW5mb3JtYXRpb24gYWJvdXQgcmVzb2x1dGlvbiBpblxuICogQHBhcmFtIGluZm8uY2FjaGVhYmxlIC0gV2lsbCBiZSBzZXQgdG8gYGZhbHNlYCBpZiBvcHRpb24gaXMgbm90IGNhY2hlYWJsZS5cbiAqIEBzaW5jZSAyLjcuMFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZShpbnB1dHM6IEFycmF5PHVua25vd24+LCBjb250ZXh0Pzogb2JqZWN0LCBpbmRleD86IG51bWJlciwgaW5mbz86IHsgY2FjaGVhYmxlOiBib29sZWFuIH0pIHtcbiAgbGV0IGNhY2hlYWJsZSA9IHRydWU7XG4gIGxldCBpOiBudW1iZXIsIGlsZW46IG51bWJlciwgdmFsdWU6IHVua25vd247XG5cbiAgZm9yIChpID0gMCwgaWxlbiA9IGlucHV0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICB2YWx1ZSA9IGlucHV0c1tpXTtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChjb250ZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlKGNvbnRleHQpO1xuICAgICAgY2FjaGVhYmxlID0gZmFsc2U7XG4gICAgfVxuICAgIGlmIChpbmRleCAhPT0gdW5kZWZpbmVkICYmIGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlW2luZGV4ICUgdmFsdWUubGVuZ3RoXTtcbiAgICAgIGNhY2hlYWJsZSA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGluZm8gJiYgIWNhY2hlYWJsZSkge1xuICAgICAgICBpbmZvLmNhY2hlYWJsZSA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSBtaW5tYXhcbiAqIEBwYXJhbSBncmFjZVxuICogQHBhcmFtIGJlZ2luQXRaZXJvXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2FkZEdyYWNlKG1pbm1heDogeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXI7IH0sIGdyYWNlOiBudW1iZXIgfCBzdHJpbmcsIGJlZ2luQXRaZXJvOiBib29sZWFuKSB7XG4gIGNvbnN0IHttaW4sIG1heH0gPSBtaW5tYXg7XG4gIGNvbnN0IGNoYW5nZSA9IHRvRGltZW5zaW9uKGdyYWNlLCAobWF4IC0gbWluKSAvIDIpO1xuICBjb25zdCBrZWVwWmVybyA9ICh2YWx1ZTogbnVtYmVyLCBhZGQ6IG51bWJlcikgPT4gYmVnaW5BdFplcm8gJiYgdmFsdWUgPT09IDAgPyAwIDogdmFsdWUgKyBhZGQ7XG4gIHJldHVybiB7XG4gICAgbWluOiBrZWVwWmVybyhtaW4sIC1NYXRoLmFicyhjaGFuZ2UpKSxcbiAgICBtYXg6IGtlZXBaZXJvKG1heCwgY2hhbmdlKVxuICB9O1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGNvbnRleHQgaW5oZXJpdGluZyBwYXJlbnRDb250ZXh0XG4gKiBAcGFyYW0gcGFyZW50Q29udGV4dFxuICogQHBhcmFtIGNvbnRleHRcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDb250ZXh0PFQgZXh0ZW5kcyBvYmplY3Q+KHBhcmVudENvbnRleHQ6IG51bGwsIGNvbnRleHQ6IFQpOiBUO1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbnRleHQ8VCBleHRlbmRzIG9iamVjdCwgUCBleHRlbmRzIFQ+KHBhcmVudENvbnRleHQ6IFAsIGNvbnRleHQ6IFQpOiBQICYgVDtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDb250ZXh0KHBhcmVudENvbnRleHQ6IG9iamVjdCwgY29udGV4dDogb2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5jcmVhdGUocGFyZW50Q29udGV4dCksIGNvbnRleHQpO1xufVxuIiwgIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11c2UtYmVmb3JlLWRlZmluZSAqL1xuaW1wb3J0IHR5cGUge0FueU9iamVjdH0gZnJvbSAnLi4vdHlwZXMvYmFzaWMuanMnO1xuaW1wb3J0IHR5cGUge0NoYXJ0TWV0YX0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge1xuICBSZXNvbHZlck9iamVjdEtleSxcbiAgUmVzb2x2ZXJDYWNoZSxcbiAgUmVzb2x2ZXJQcm94eSxcbiAgRGVzY3JpcHRvckRlZmF1bHRzLFxuICBEZXNjcmlwdG9yLFxuICBDb250ZXh0Q2FjaGUsXG4gIENvbnRleHRQcm94eVxufSBmcm9tICcuL2hlbHBlcnMuY29uZmlnLnR5cGVzLmpzJztcbmltcG9ydCB7aXNBcnJheSwgaXNGdW5jdGlvbiwgaXNPYmplY3QsIHJlc29sdmVPYmplY3RLZXksIF9jYXBpdGFsaXplfSBmcm9tICcuL2hlbHBlcnMuY29yZS5qcyc7XG5cbmV4cG9ydCAqIGZyb20gJy4vaGVscGVycy5jb25maWcudHlwZXMuanMnO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBQcm94eSBmb3IgcmVzb2x2aW5nIHJhdyB2YWx1ZXMgZm9yIG9wdGlvbnMuXG4gKiBAcGFyYW0gc2NvcGVzIC0gVGhlIG9wdGlvbiBzY29wZXMgdG8gbG9vayBmb3IgdmFsdWVzLCBpbiByZXNvbHV0aW9uIG9yZGVyXG4gKiBAcGFyYW0gcHJlZml4ZXMgLSBUaGUgcHJlZml4ZXMgZm9yIHZhbHVlcywgaW4gcmVzb2x1dGlvbiBvcmRlci5cbiAqIEBwYXJhbSByb290U2NvcGVzIC0gVGhlIHJvb3Qgb3B0aW9uIHNjb3Blc1xuICogQHBhcmFtIGZhbGxiYWNrIC0gUGFyZW50IHNjb3BlcyBmYWxsYmFja1xuICogQHBhcmFtIGdldFRhcmdldCAtIGNhbGxiYWNrIGZvciBnZXR0aW5nIHRoZSB0YXJnZXQgZm9yIGNoYW5nZWQgdmFsdWVzXG4gKiBAcmV0dXJucyBQcm94eVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jcmVhdGVSZXNvbHZlcjxcbiAgVCBleHRlbmRzIEFueU9iamVjdFtdID0gQW55T2JqZWN0W10sXG4gIFIgZXh0ZW5kcyBBbnlPYmplY3RbXSA9IFRcbj4oXG4gIHNjb3BlczogVCxcbiAgcHJlZml4ZXMgPSBbJyddLFxuICByb290U2NvcGVzPzogUixcbiAgZmFsbGJhY2s/OiBSZXNvbHZlck9iamVjdEtleSxcbiAgZ2V0VGFyZ2V0ID0gKCkgPT4gc2NvcGVzWzBdXG4pIHtcbiAgY29uc3QgZmluYWxSb290U2NvcGVzID0gcm9vdFNjb3BlcyB8fCBzY29wZXM7XG4gIGlmICh0eXBlb2YgZmFsbGJhY2sgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgZmFsbGJhY2sgPSBfcmVzb2x2ZSgnX2ZhbGxiYWNrJywgc2NvcGVzKTtcbiAgfVxuICBjb25zdCBjYWNoZTogUmVzb2x2ZXJDYWNoZTxULCBSPiA9IHtcbiAgICBbU3ltYm9sLnRvU3RyaW5nVGFnXTogJ09iamVjdCcsXG4gICAgX2NhY2hlYWJsZTogdHJ1ZSxcbiAgICBfc2NvcGVzOiBzY29wZXMsXG4gICAgX3Jvb3RTY29wZXM6IGZpbmFsUm9vdFNjb3BlcyxcbiAgICBfZmFsbGJhY2s6IGZhbGxiYWNrLFxuICAgIF9nZXRUYXJnZXQ6IGdldFRhcmdldCxcbiAgICBvdmVycmlkZTogKHNjb3BlOiBBbnlPYmplY3QpID0+IF9jcmVhdGVSZXNvbHZlcihbc2NvcGUsIC4uLnNjb3Blc10sIHByZWZpeGVzLCBmaW5hbFJvb3RTY29wZXMsIGZhbGxiYWNrKSxcbiAgfTtcbiAgcmV0dXJuIG5ldyBQcm94eShjYWNoZSwge1xuICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgdGhlIGRlbGV0ZSBvcGVyYXRvci5cbiAgICAgKi9cbiAgICBkZWxldGVQcm9wZXJ0eSh0YXJnZXQsIHByb3A6IHN0cmluZykge1xuICAgICAgZGVsZXRlIHRhcmdldFtwcm9wXTsgLy8gcmVtb3ZlIGZyb20gY2FjaGVcbiAgICAgIGRlbGV0ZSB0YXJnZXQuX2tleXM7IC8vIHJlbW92ZSBjYWNoZWQga2V5c1xuICAgICAgZGVsZXRlIHNjb3Blc1swXVtwcm9wXTsgLy8gcmVtb3ZlIGZyb20gdG9wIGxldmVsIHNjb3BlXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBnZXR0aW5nIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKi9cbiAgICBnZXQodGFyZ2V0LCBwcm9wOiBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBfY2FjaGVkKHRhcmdldCwgcHJvcCxcbiAgICAgICAgKCkgPT4gX3Jlc29sdmVXaXRoUHJlZml4ZXMocHJvcCwgcHJlZml4ZXMsIHNjb3BlcywgdGFyZ2V0KSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvci5cbiAgICAgKiBBbHNvIHVzZWQgYnkgT2JqZWN0Lmhhc093blByb3BlcnR5LlxuICAgICAqL1xuICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIHByb3ApIHtcbiAgICAgIHJldHVybiBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQuX3Njb3Blc1swXSwgcHJvcCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mLlxuICAgICAqL1xuICAgIGdldFByb3RvdHlwZU9mKCkge1xuICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0UHJvdG90eXBlT2Yoc2NvcGVzWzBdKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciB0aGUgaW4gb3BlcmF0b3IuXG4gICAgICovXG4gICAgaGFzKHRhcmdldCwgcHJvcDogc3RyaW5nKSB7XG4gICAgICByZXR1cm4gZ2V0S2V5c0Zyb21BbGxTY29wZXModGFyZ2V0KS5pbmNsdWRlcyhwcm9wKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyBhbmQgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scy5cbiAgICAgKi9cbiAgICBvd25LZXlzKHRhcmdldCkge1xuICAgICAgcmV0dXJuIGdldEtleXNGcm9tQWxsU2NvcGVzKHRhcmdldCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3Igc2V0dGluZyBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICovXG4gICAgc2V0KHRhcmdldCwgcHJvcDogc3RyaW5nLCB2YWx1ZSkge1xuICAgICAgY29uc3Qgc3RvcmFnZSA9IHRhcmdldC5fc3RvcmFnZSB8fCAodGFyZ2V0Ll9zdG9yYWdlID0gZ2V0VGFyZ2V0KCkpO1xuICAgICAgdGFyZ2V0W3Byb3BdID0gc3RvcmFnZVtwcm9wXSA9IHZhbHVlOyAvLyBzZXQgdG8gdG9wIGxldmVsIHNjb3BlICsgY2FjaGVcbiAgICAgIGRlbGV0ZSB0YXJnZXQuX2tleXM7IC8vIHJlbW92ZSBjYWNoZWQga2V5c1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9KSBhcyBSZXNvbHZlclByb3h5PFQsIFI+O1xufVxuXG4vKipcbiAqIFJldHVybnMgYW4gUHJveHkgZm9yIHJlc29sdmluZyBvcHRpb24gdmFsdWVzIHdpdGggY29udGV4dC5cbiAqIEBwYXJhbSBwcm94eSAtIFRoZSBQcm94eSByZXR1cm5lZCBieSBgX2NyZWF0ZVJlc29sdmVyYFxuICogQHBhcmFtIGNvbnRleHQgLSBDb250ZXh0IG9iamVjdCBmb3Igc2NyaXB0YWJsZS9pbmRleGFibGUgb3B0aW9uc1xuICogQHBhcmFtIHN1YlByb3h5IC0gVGhlIHByb3h5IHByb3ZpZGVkIGZvciBzY3JpcHRhYmxlIG9wdGlvbnNcbiAqIEBwYXJhbSBkZXNjcmlwdG9yRGVmYXVsdHMgLSBEZWZhdWx0cyBmb3IgZGVzY3JpcHRvcnNcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYXR0YWNoQ29udGV4dDxcbiAgVCBleHRlbmRzIEFueU9iamVjdFtdID0gQW55T2JqZWN0W10sXG4gIFIgZXh0ZW5kcyBBbnlPYmplY3RbXSA9IFRcbj4oXG4gIHByb3h5OiBSZXNvbHZlclByb3h5PFQsIFI+LFxuICBjb250ZXh0OiBBbnlPYmplY3QsXG4gIHN1YlByb3h5PzogUmVzb2x2ZXJQcm94eTxULCBSPixcbiAgZGVzY3JpcHRvckRlZmF1bHRzPzogRGVzY3JpcHRvckRlZmF1bHRzXG4pIHtcbiAgY29uc3QgY2FjaGU6IENvbnRleHRDYWNoZTxULCBSPiA9IHtcbiAgICBfY2FjaGVhYmxlOiBmYWxzZSxcbiAgICBfcHJveHk6IHByb3h5LFxuICAgIF9jb250ZXh0OiBjb250ZXh0LFxuICAgIF9zdWJQcm94eTogc3ViUHJveHksXG4gICAgX3N0YWNrOiBuZXcgU2V0KCksXG4gICAgX2Rlc2NyaXB0b3JzOiBfZGVzY3JpcHRvcnMocHJveHksIGRlc2NyaXB0b3JEZWZhdWx0cyksXG4gICAgc2V0Q29udGV4dDogKGN0eDogQW55T2JqZWN0KSA9PiBfYXR0YWNoQ29udGV4dChwcm94eSwgY3R4LCBzdWJQcm94eSwgZGVzY3JpcHRvckRlZmF1bHRzKSxcbiAgICBvdmVycmlkZTogKHNjb3BlOiBBbnlPYmplY3QpID0+IF9hdHRhY2hDb250ZXh0KHByb3h5Lm92ZXJyaWRlKHNjb3BlKSwgY29udGV4dCwgc3ViUHJveHksIGRlc2NyaXB0b3JEZWZhdWx0cylcbiAgfTtcbiAgcmV0dXJuIG5ldyBQcm94eShjYWNoZSwge1xuICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgdGhlIGRlbGV0ZSBvcGVyYXRvci5cbiAgICAgKi9cbiAgICBkZWxldGVQcm9wZXJ0eSh0YXJnZXQsIHByb3ApIHtcbiAgICAgIGRlbGV0ZSB0YXJnZXRbcHJvcF07IC8vIHJlbW92ZSBmcm9tIGNhY2hlXG4gICAgICBkZWxldGUgcHJveHlbcHJvcF07IC8vIHJlbW92ZSBmcm9tIHByb3h5XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBnZXR0aW5nIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKi9cbiAgICBnZXQodGFyZ2V0LCBwcm9wOiBzdHJpbmcsIHJlY2VpdmVyKSB7XG4gICAgICByZXR1cm4gX2NhY2hlZCh0YXJnZXQsIHByb3AsXG4gICAgICAgICgpID0+IF9yZXNvbHZlV2l0aENvbnRleHQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcikpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IuXG4gICAgICogQWxzbyB1c2VkIGJ5IE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wKSB7XG4gICAgICByZXR1cm4gdGFyZ2V0Ll9kZXNjcmlwdG9ycy5hbGxLZXlzXG4gICAgICAgID8gUmVmbGVjdC5oYXMocHJveHksIHByb3ApID8ge2VudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZX0gOiB1bmRlZmluZWRcbiAgICAgICAgOiBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwcm94eSwgcHJvcCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEEgdHJhcCBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mLlxuICAgICAqL1xuICAgIGdldFByb3RvdHlwZU9mKCkge1xuICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0UHJvdG90eXBlT2YocHJveHkpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIHRoZSBpbiBvcGVyYXRvci5cbiAgICAgKi9cbiAgICBoYXModGFyZ2V0LCBwcm9wKSB7XG4gICAgICByZXR1cm4gUmVmbGVjdC5oYXMocHJveHksIHByb3ApO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBIHRyYXAgZm9yIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIGFuZCBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzLlxuICAgICAqL1xuICAgIG93bktleXMoKSB7XG4gICAgICByZXR1cm4gUmVmbGVjdC5vd25LZXlzKHByb3h5KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQSB0cmFwIGZvciBzZXR0aW5nIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKi9cbiAgICBzZXQodGFyZ2V0LCBwcm9wLCB2YWx1ZSkge1xuICAgICAgcHJveHlbcHJvcF0gPSB2YWx1ZTsgLy8gc2V0IHRvIHByb3h5XG4gICAgICBkZWxldGUgdGFyZ2V0W3Byb3BdOyAvLyByZW1vdmUgZnJvbSBjYWNoZVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9KSBhcyBDb250ZXh0UHJveHk8VCwgUj47XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9kZXNjcmlwdG9ycyhcbiAgcHJveHk6IFJlc29sdmVyQ2FjaGUsXG4gIGRlZmF1bHRzOiBEZXNjcmlwdG9yRGVmYXVsdHMgPSB7c2NyaXB0YWJsZTogdHJ1ZSwgaW5kZXhhYmxlOiB0cnVlfVxuKTogRGVzY3JpcHRvciB7XG4gIGNvbnN0IHtfc2NyaXB0YWJsZSA9IGRlZmF1bHRzLnNjcmlwdGFibGUsIF9pbmRleGFibGUgPSBkZWZhdWx0cy5pbmRleGFibGUsIF9hbGxLZXlzID0gZGVmYXVsdHMuYWxsS2V5c30gPSBwcm94eTtcbiAgcmV0dXJuIHtcbiAgICBhbGxLZXlzOiBfYWxsS2V5cyxcbiAgICBzY3JpcHRhYmxlOiBfc2NyaXB0YWJsZSxcbiAgICBpbmRleGFibGU6IF9pbmRleGFibGUsXG4gICAgaXNTY3JpcHRhYmxlOiBpc0Z1bmN0aW9uKF9zY3JpcHRhYmxlKSA/IF9zY3JpcHRhYmxlIDogKCkgPT4gX3NjcmlwdGFibGUsXG4gICAgaXNJbmRleGFibGU6IGlzRnVuY3Rpb24oX2luZGV4YWJsZSkgPyBfaW5kZXhhYmxlIDogKCkgPT4gX2luZGV4YWJsZVxuICB9O1xufVxuXG5jb25zdCByZWFkS2V5ID0gKHByZWZpeDogc3RyaW5nLCBuYW1lOiBzdHJpbmcpID0+IHByZWZpeCA/IHByZWZpeCArIF9jYXBpdGFsaXplKG5hbWUpIDogbmFtZTtcbmNvbnN0IG5lZWRzU3ViUmVzb2x2ZXIgPSAocHJvcDogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikgPT4gaXNPYmplY3QodmFsdWUpICYmIHByb3AgIT09ICdhZGFwdGVycycgJiZcbiAgKE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgPT09IG51bGwgfHwgdmFsdWUuY29uc3RydWN0b3IgPT09IE9iamVjdCk7XG5cbmZ1bmN0aW9uIF9jYWNoZWQoXG4gIHRhcmdldDogQW55T2JqZWN0LFxuICBwcm9wOiBzdHJpbmcsXG4gIHJlc29sdmU6ICgpID0+IHVua25vd25cbikge1xuICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRhcmdldCwgcHJvcCkpIHtcbiAgICByZXR1cm4gdGFyZ2V0W3Byb3BdO1xuICB9XG5cbiAgY29uc3QgdmFsdWUgPSByZXNvbHZlKCk7XG4gIC8vIGNhY2hlIHRoZSByZXNvbHZlZCB2YWx1ZVxuICB0YXJnZXRbcHJvcF0gPSB2YWx1ZTtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBfcmVzb2x2ZVdpdGhDb250ZXh0KFxuICB0YXJnZXQ6IENvbnRleHRDYWNoZSxcbiAgcHJvcDogc3RyaW5nLFxuICByZWNlaXZlcjogQW55T2JqZWN0XG4pIHtcbiAgY29uc3Qge19wcm94eSwgX2NvbnRleHQsIF9zdWJQcm94eSwgX2Rlc2NyaXB0b3JzOiBkZXNjcmlwdG9yc30gPSB0YXJnZXQ7XG4gIGxldCB2YWx1ZSA9IF9wcm94eVtwcm9wXTsgLy8gcmVzb2x2ZSBmcm9tIHByb3h5XG5cbiAgLy8gcmVzb2x2ZSB3aXRoIGNvbnRleHRcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpICYmIGRlc2NyaXB0b3JzLmlzU2NyaXB0YWJsZShwcm9wKSkge1xuICAgIHZhbHVlID0gX3Jlc29sdmVTY3JpcHRhYmxlKHByb3AsIHZhbHVlLCB0YXJnZXQsIHJlY2VpdmVyKTtcbiAgfVxuICBpZiAoaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoKSB7XG4gICAgdmFsdWUgPSBfcmVzb2x2ZUFycmF5KHByb3AsIHZhbHVlLCB0YXJnZXQsIGRlc2NyaXB0b3JzLmlzSW5kZXhhYmxlKTtcbiAgfVxuICBpZiAobmVlZHNTdWJSZXNvbHZlcihwcm9wLCB2YWx1ZSkpIHtcbiAgICAvLyBpZiB0aGUgcmVzb2x2ZWQgdmFsdWUgaXMgYW4gb2JqZWN0LCBjcmVhdGUgYSBzdWIgcmVzb2x2ZXIgZm9yIGl0XG4gICAgdmFsdWUgPSBfYXR0YWNoQ29udGV4dCh2YWx1ZSwgX2NvbnRleHQsIF9zdWJQcm94eSAmJiBfc3ViUHJveHlbcHJvcF0sIGRlc2NyaXB0b3JzKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIF9yZXNvbHZlU2NyaXB0YWJsZShcbiAgcHJvcDogc3RyaW5nLFxuICBnZXRWYWx1ZTogKGN0eDogQW55T2JqZWN0LCBzdWI6IEFueU9iamVjdCkgPT4gdW5rbm93bixcbiAgdGFyZ2V0OiBDb250ZXh0Q2FjaGUsXG4gIHJlY2VpdmVyOiBBbnlPYmplY3Rcbikge1xuICBjb25zdCB7X3Byb3h5LCBfY29udGV4dCwgX3N1YlByb3h5LCBfc3RhY2t9ID0gdGFyZ2V0O1xuICBpZiAoX3N0YWNrLmhhcyhwcm9wKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUmVjdXJzaW9uIGRldGVjdGVkOiAnICsgQXJyYXkuZnJvbShfc3RhY2spLmpvaW4oJy0+JykgKyAnLT4nICsgcHJvcCk7XG4gIH1cbiAgX3N0YWNrLmFkZChwcm9wKTtcbiAgbGV0IHZhbHVlID0gZ2V0VmFsdWUoX2NvbnRleHQsIF9zdWJQcm94eSB8fCByZWNlaXZlcik7XG4gIF9zdGFjay5kZWxldGUocHJvcCk7XG4gIGlmIChuZWVkc1N1YlJlc29sdmVyKHByb3AsIHZhbHVlKSkge1xuICAgIC8vIFdoZW4gc2NyaXB0YWJsZSBvcHRpb24gcmV0dXJucyBhbiBvYmplY3QsIGNyZWF0ZSBhIHJlc29sdmVyIG9uIHRoYXQuXG4gICAgdmFsdWUgPSBjcmVhdGVTdWJSZXNvbHZlcihfcHJveHkuX3Njb3BlcywgX3Byb3h5LCBwcm9wLCB2YWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBfcmVzb2x2ZUFycmF5KFxuICBwcm9wOiBzdHJpbmcsXG4gIHZhbHVlOiB1bmtub3duW10sXG4gIHRhcmdldDogQ29udGV4dENhY2hlLFxuICBpc0luZGV4YWJsZTogKGtleTogc3RyaW5nKSA9PiBib29sZWFuXG4pIHtcbiAgY29uc3Qge19wcm94eSwgX2NvbnRleHQsIF9zdWJQcm94eSwgX2Rlc2NyaXB0b3JzOiBkZXNjcmlwdG9yc30gPSB0YXJnZXQ7XG5cbiAgaWYgKHR5cGVvZiBfY29udGV4dC5pbmRleCAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNJbmRleGFibGUocHJvcCkpIHtcbiAgICByZXR1cm4gdmFsdWVbX2NvbnRleHQuaW5kZXggJSB2YWx1ZS5sZW5ndGhdO1xuICB9IGVsc2UgaWYgKGlzT2JqZWN0KHZhbHVlWzBdKSkge1xuICAgIC8vIEFycmF5IG9mIG9iamVjdHMsIHJldHVybiBhcnJheSBvciByZXNvbHZlcnNcbiAgICBjb25zdCBhcnIgPSB2YWx1ZTtcbiAgICBjb25zdCBzY29wZXMgPSBfcHJveHkuX3Njb3Blcy5maWx0ZXIocyA9PiBzICE9PSBhcnIpO1xuICAgIHZhbHVlID0gW107XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGFycikge1xuICAgICAgY29uc3QgcmVzb2x2ZXIgPSBjcmVhdGVTdWJSZXNvbHZlcihzY29wZXMsIF9wcm94eSwgcHJvcCwgaXRlbSk7XG4gICAgICB2YWx1ZS5wdXNoKF9hdHRhY2hDb250ZXh0KHJlc29sdmVyLCBfY29udGV4dCwgX3N1YlByb3h5ICYmIF9zdWJQcm94eVtwcm9wXSwgZGVzY3JpcHRvcnMpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlRmFsbGJhY2soXG4gIGZhbGxiYWNrOiBSZXNvbHZlck9iamVjdEtleSB8ICgocHJvcDogUmVzb2x2ZXJPYmplY3RLZXksIHZhbHVlOiB1bmtub3duKSA9PiBSZXNvbHZlck9iamVjdEtleSksXG4gIHByb3A6IFJlc29sdmVyT2JqZWN0S2V5LFxuICB2YWx1ZTogdW5rbm93blxuKSB7XG4gIHJldHVybiBpc0Z1bmN0aW9uKGZhbGxiYWNrKSA/IGZhbGxiYWNrKHByb3AsIHZhbHVlKSA6IGZhbGxiYWNrO1xufVxuXG5jb25zdCBnZXRTY29wZSA9IChrZXk6IFJlc29sdmVyT2JqZWN0S2V5LCBwYXJlbnQ6IEFueU9iamVjdCkgPT4ga2V5ID09PSB0cnVlID8gcGFyZW50XG4gIDogdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgPyByZXNvbHZlT2JqZWN0S2V5KHBhcmVudCwga2V5KSA6IHVuZGVmaW5lZDtcblxuZnVuY3Rpb24gYWRkU2NvcGVzKFxuICBzZXQ6IFNldDxBbnlPYmplY3Q+LFxuICBwYXJlbnRTY29wZXM6IEFueU9iamVjdFtdLFxuICBrZXk6IFJlc29sdmVyT2JqZWN0S2V5LFxuICBwYXJlbnRGYWxsYmFjazogUmVzb2x2ZXJPYmplY3RLZXksXG4gIHZhbHVlOiB1bmtub3duXG4pIHtcbiAgZm9yIChjb25zdCBwYXJlbnQgb2YgcGFyZW50U2NvcGVzKSB7XG4gICAgY29uc3Qgc2NvcGUgPSBnZXRTY29wZShrZXksIHBhcmVudCk7XG4gICAgaWYgKHNjb3BlKSB7XG4gICAgICBzZXQuYWRkKHNjb3BlKTtcbiAgICAgIGNvbnN0IGZhbGxiYWNrID0gcmVzb2x2ZUZhbGxiYWNrKHNjb3BlLl9mYWxsYmFjaywga2V5LCB2YWx1ZSk7XG4gICAgICBpZiAodHlwZW9mIGZhbGxiYWNrICE9PSAndW5kZWZpbmVkJyAmJiBmYWxsYmFjayAhPT0ga2V5ICYmIGZhbGxiYWNrICE9PSBwYXJlbnRGYWxsYmFjaykge1xuICAgICAgICAvLyBXaGVuIHdlIHJlYWNoIHRoZSBkZXNjcmlwdG9yIHRoYXQgZGVmaW5lcyBhIG5ldyBfZmFsbGJhY2ssIHJldHVybiB0aGF0LlxuICAgICAgICAvLyBUaGUgZmFsbGJhY2sgd2lsbCByZXN1bWUgdG8gdGhhdCBuZXcgc2NvcGUuXG4gICAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNjb3BlID09PSBmYWxzZSAmJiB0eXBlb2YgcGFyZW50RmFsbGJhY2sgIT09ICd1bmRlZmluZWQnICYmIGtleSAhPT0gcGFyZW50RmFsbGJhY2spIHtcbiAgICAgIC8vIEZhbGxiYWNrIHRvIGBmYWxzZWAgcmVzdWx0cyB0byBgZmFsc2VgLCB3aGVuIGZhbGxpbmcgYmFjayB0byBkaWZmZXJlbnQga2V5LlxuICAgICAgLy8gRm9yIGV4YW1wbGUgYGludGVyYWN0aW9uYCBmcm9tIGBob3ZlcmAgb3IgYHBsdWdpbnMudG9vbHRpcGAgYW5kIGBhbmltYXRpb25gIGZyb20gYGFuaW1hdGlvbnNgXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdWJSZXNvbHZlcihcbiAgcGFyZW50U2NvcGVzOiBBbnlPYmplY3RbXSxcbiAgcmVzb2x2ZXI6IFJlc29sdmVyQ2FjaGUsXG4gIHByb3A6IFJlc29sdmVyT2JqZWN0S2V5LFxuICB2YWx1ZTogdW5rbm93blxuKSB7XG4gIGNvbnN0IHJvb3RTY29wZXMgPSByZXNvbHZlci5fcm9vdFNjb3BlcztcbiAgY29uc3QgZmFsbGJhY2sgPSByZXNvbHZlRmFsbGJhY2socmVzb2x2ZXIuX2ZhbGxiYWNrLCBwcm9wLCB2YWx1ZSk7XG4gIGNvbnN0IGFsbFNjb3BlcyA9IFsuLi5wYXJlbnRTY29wZXMsIC4uLnJvb3RTY29wZXNdO1xuICBjb25zdCBzZXQgPSBuZXcgU2V0PEFueU9iamVjdD4oKTtcbiAgc2V0LmFkZCh2YWx1ZSk7XG4gIGxldCBrZXkgPSBhZGRTY29wZXNGcm9tS2V5KHNldCwgYWxsU2NvcGVzLCBwcm9wLCBmYWxsYmFjayB8fCBwcm9wLCB2YWx1ZSk7XG4gIGlmIChrZXkgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBmYWxsYmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgZmFsbGJhY2sgIT09IHByb3ApIHtcbiAgICBrZXkgPSBhZGRTY29wZXNGcm9tS2V5KHNldCwgYWxsU2NvcGVzLCBmYWxsYmFjaywga2V5LCB2YWx1ZSk7XG4gICAgaWYgKGtleSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gX2NyZWF0ZVJlc29sdmVyKEFycmF5LmZyb20oc2V0KSwgWycnXSwgcm9vdFNjb3BlcywgZmFsbGJhY2ssXG4gICAgKCkgPT4gc3ViR2V0VGFyZ2V0KHJlc29sdmVyLCBwcm9wIGFzIHN0cmluZywgdmFsdWUpKTtcbn1cblxuZnVuY3Rpb24gYWRkU2NvcGVzRnJvbUtleShcbiAgc2V0OiBTZXQ8QW55T2JqZWN0PixcbiAgYWxsU2NvcGVzOiBBbnlPYmplY3RbXSxcbiAga2V5OiBSZXNvbHZlck9iamVjdEtleSxcbiAgZmFsbGJhY2s6IFJlc29sdmVyT2JqZWN0S2V5LFxuICBpdGVtOiB1bmtub3duXG4pIHtcbiAgd2hpbGUgKGtleSkge1xuICAgIGtleSA9IGFkZFNjb3BlcyhzZXQsIGFsbFNjb3Blcywga2V5LCBmYWxsYmFjaywgaXRlbSk7XG4gIH1cbiAgcmV0dXJuIGtleTtcbn1cblxuZnVuY3Rpb24gc3ViR2V0VGFyZ2V0KFxuICByZXNvbHZlcjogUmVzb2x2ZXJDYWNoZSxcbiAgcHJvcDogc3RyaW5nLFxuICB2YWx1ZTogdW5rbm93blxuKSB7XG4gIGNvbnN0IHBhcmVudCA9IHJlc29sdmVyLl9nZXRUYXJnZXQoKTtcbiAgaWYgKCEocHJvcCBpbiBwYXJlbnQpKSB7XG4gICAgcGFyZW50W3Byb3BdID0ge307XG4gIH1cbiAgY29uc3QgdGFyZ2V0ID0gcGFyZW50W3Byb3BdO1xuICBpZiAoaXNBcnJheSh0YXJnZXQpICYmIGlzT2JqZWN0KHZhbHVlKSkge1xuICAgIC8vIEZvciBhcnJheSBvZiBvYmplY3RzLCB0aGUgb2JqZWN0IGlzIHVzZWQgdG8gc3RvcmUgdXBkYXRlZCB2YWx1ZXNcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIHRhcmdldCB8fCB7fTtcbn1cblxuZnVuY3Rpb24gX3Jlc29sdmVXaXRoUHJlZml4ZXMoXG4gIHByb3A6IHN0cmluZyxcbiAgcHJlZml4ZXM6IHN0cmluZ1tdLFxuICBzY29wZXM6IEFueU9iamVjdFtdLFxuICBwcm94eTogUmVzb2x2ZXJQcm94eVxuKSB7XG4gIGxldCB2YWx1ZTogdW5rbm93bjtcbiAgZm9yIChjb25zdCBwcmVmaXggb2YgcHJlZml4ZXMpIHtcbiAgICB2YWx1ZSA9IF9yZXNvbHZlKHJlYWRLZXkocHJlZml4LCBwcm9wKSwgc2NvcGVzKTtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIG5lZWRzU3ViUmVzb2x2ZXIocHJvcCwgdmFsdWUpXG4gICAgICAgID8gY3JlYXRlU3ViUmVzb2x2ZXIoc2NvcGVzLCBwcm94eSwgcHJvcCwgdmFsdWUpXG4gICAgICAgIDogdmFsdWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9yZXNvbHZlKGtleTogc3RyaW5nLCBzY29wZXM6IEFueU9iamVjdFtdKSB7XG4gIGZvciAoY29uc3Qgc2NvcGUgb2Ygc2NvcGVzKSB7XG4gICAgaWYgKCFzY29wZSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHZhbHVlID0gc2NvcGVba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRLZXlzRnJvbUFsbFNjb3Blcyh0YXJnZXQ6IFJlc29sdmVyQ2FjaGUpIHtcbiAgbGV0IGtleXMgPSB0YXJnZXQuX2tleXM7XG4gIGlmICgha2V5cykge1xuICAgIGtleXMgPSB0YXJnZXQuX2tleXMgPSByZXNvbHZlS2V5c0Zyb21BbGxTY29wZXModGFyZ2V0Ll9zY29wZXMpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlS2V5c0Zyb21BbGxTY29wZXMoc2NvcGVzOiBBbnlPYmplY3RbXSkge1xuICBjb25zdCBzZXQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCBzY29wZSBvZiBzY29wZXMpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzY29wZSkuZmlsdGVyKGsgPT4gIWsuc3RhcnRzV2l0aCgnXycpKSkge1xuICAgICAgc2V0LmFkZChrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gQXJyYXkuZnJvbShzZXQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX3BhcnNlT2JqZWN0RGF0YVJhZGlhbFNjYWxlKFxuICBtZXRhOiBDaGFydE1ldGE8J2xpbmUnIHwgJ3NjYXR0ZXInPixcbiAgZGF0YTogQW55T2JqZWN0W10sXG4gIHN0YXJ0OiBudW1iZXIsXG4gIGNvdW50OiBudW1iZXJcbikge1xuICBjb25zdCB7aVNjYWxlfSA9IG1ldGE7XG4gIGNvbnN0IHtrZXkgPSAncid9ID0gdGhpcy5fcGFyc2luZztcbiAgY29uc3QgcGFyc2VkID0gbmV3IEFycmF5PHtyOiB1bmtub3dufT4oY291bnQpO1xuICBsZXQgaTogbnVtYmVyLCBpbGVuOiBudW1iZXIsIGluZGV4OiBudW1iZXIsIGl0ZW06IEFueU9iamVjdDtcblxuICBmb3IgKGkgPSAwLCBpbGVuID0gY291bnQ7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBpbmRleCA9IGkgKyBzdGFydDtcbiAgICBpdGVtID0gZGF0YVtpbmRleF07XG4gICAgcGFyc2VkW2ldID0ge1xuICAgICAgcjogaVNjYWxlLnBhcnNlKHJlc29sdmVPYmplY3RLZXkoaXRlbSwga2V5KSwgaW5kZXgpXG4gICAgfTtcbiAgfVxuICByZXR1cm4gcGFyc2VkO1xufVxuIiwgImltcG9ydCB7YWxtb3N0RXF1YWxzLCBkaXN0YW5jZUJldHdlZW5Qb2ludHMsIHNpZ259IGZyb20gJy4vaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCB7X2lzUG9pbnRJbkFyZWF9IGZyb20gJy4vaGVscGVycy5jYW52YXMuanMnO1xuaW1wb3J0IHR5cGUge0NoYXJ0QXJlYX0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuaW1wb3J0IHR5cGUge1NwbGluZVBvaW50fSBmcm9tICcuLi90eXBlcy9nZW9tZXRyaWMuanMnO1xuXG5jb25zdCBFUFNJTE9OID0gTnVtYmVyLkVQU0lMT04gfHwgMWUtMTQ7XG5cbnR5cGUgT3B0aW9uYWxTcGxpbmVQb2ludCA9IFNwbGluZVBvaW50IHwgZmFsc2VcbmNvbnN0IGdldFBvaW50ID0gKHBvaW50czogU3BsaW5lUG9pbnRbXSwgaTogbnVtYmVyKTogT3B0aW9uYWxTcGxpbmVQb2ludCA9PiBpIDwgcG9pbnRzLmxlbmd0aCAmJiAhcG9pbnRzW2ldLnNraXAgJiYgcG9pbnRzW2ldO1xuY29uc3QgZ2V0VmFsdWVBeGlzID0gKGluZGV4QXhpczogJ3gnIHwgJ3knKSA9PiBpbmRleEF4aXMgPT09ICd4JyA/ICd5JyA6ICd4JztcblxuZXhwb3J0IGZ1bmN0aW9uIHNwbGluZUN1cnZlKFxuICBmaXJzdFBvaW50OiBTcGxpbmVQb2ludCxcbiAgbWlkZGxlUG9pbnQ6IFNwbGluZVBvaW50LFxuICBhZnRlclBvaW50OiBTcGxpbmVQb2ludCxcbiAgdDogbnVtYmVyXG4pOiB7XG4gICAgcHJldmlvdXM6IFNwbGluZVBvaW50XG4gICAgbmV4dDogU3BsaW5lUG9pbnRcbiAgfSB7XG4gIC8vIFByb3BzIHRvIFJvYiBTcGVuY2VyIGF0IHNjYWxlZCBpbm5vdmF0aW9uIGZvciBoaXMgcG9zdCBvbiBzcGxpbmluZyBiZXR3ZWVuIHBvaW50c1xuICAvLyBodHRwOi8vc2NhbGVkaW5ub3ZhdGlvbi5jb20vYW5hbHl0aWNzL3NwbGluZXMvYWJvdXRTcGxpbmVzLmh0bWxcblxuICAvLyBUaGlzIGZ1bmN0aW9uIG11c3QgYWxzbyByZXNwZWN0IFwic2tpcHBlZFwiIHBvaW50c1xuXG4gIGNvbnN0IHByZXZpb3VzID0gZmlyc3RQb2ludC5za2lwID8gbWlkZGxlUG9pbnQgOiBmaXJzdFBvaW50O1xuICBjb25zdCBjdXJyZW50ID0gbWlkZGxlUG9pbnQ7XG4gIGNvbnN0IG5leHQgPSBhZnRlclBvaW50LnNraXAgPyBtaWRkbGVQb2ludCA6IGFmdGVyUG9pbnQ7XG4gIGNvbnN0IGQwMSA9IGRpc3RhbmNlQmV0d2VlblBvaW50cyhjdXJyZW50LCBwcmV2aW91cyk7XG4gIGNvbnN0IGQxMiA9IGRpc3RhbmNlQmV0d2VlblBvaW50cyhuZXh0LCBjdXJyZW50KTtcblxuICBsZXQgczAxID0gZDAxIC8gKGQwMSArIGQxMik7XG4gIGxldCBzMTIgPSBkMTIgLyAoZDAxICsgZDEyKTtcblxuICAvLyBJZiBhbGwgcG9pbnRzIGFyZSB0aGUgc2FtZSwgczAxICYgczAyIHdpbGwgYmUgaW5mXG4gIHMwMSA9IGlzTmFOKHMwMSkgPyAwIDogczAxO1xuICBzMTIgPSBpc05hTihzMTIpID8gMCA6IHMxMjtcblxuICBjb25zdCBmYSA9IHQgKiBzMDE7IC8vIHNjYWxpbmcgZmFjdG9yIGZvciB0cmlhbmdsZSBUYVxuICBjb25zdCBmYiA9IHQgKiBzMTI7XG5cbiAgcmV0dXJuIHtcbiAgICBwcmV2aW91czoge1xuICAgICAgeDogY3VycmVudC54IC0gZmEgKiAobmV4dC54IC0gcHJldmlvdXMueCksXG4gICAgICB5OiBjdXJyZW50LnkgLSBmYSAqIChuZXh0LnkgLSBwcmV2aW91cy55KVxuICAgIH0sXG4gICAgbmV4dDoge1xuICAgICAgeDogY3VycmVudC54ICsgZmIgKiAobmV4dC54IC0gcHJldmlvdXMueCksXG4gICAgICB5OiBjdXJyZW50LnkgKyBmYiAqIChuZXh0LnkgLSBwcmV2aW91cy55KVxuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBBZGp1c3QgdGFuZ2VudHMgdG8gZW5zdXJlIG1vbm90b25pYyBwcm9wZXJ0aWVzXG4gKi9cbmZ1bmN0aW9uIG1vbm90b25lQWRqdXN0KHBvaW50czogU3BsaW5lUG9pbnRbXSwgZGVsdGFLOiBudW1iZXJbXSwgbUs6IG51bWJlcltdKSB7XG4gIGNvbnN0IHBvaW50c0xlbiA9IHBvaW50cy5sZW5ndGg7XG5cbiAgbGV0IGFscGhhSzogbnVtYmVyLCBiZXRhSzogbnVtYmVyLCB0YXVLOiBudW1iZXIsIHNxdWFyZWRNYWduaXR1ZGU6IG51bWJlciwgcG9pbnRDdXJyZW50OiBPcHRpb25hbFNwbGluZVBvaW50O1xuICBsZXQgcG9pbnRBZnRlciA9IGdldFBvaW50KHBvaW50cywgMCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzTGVuIC0gMTsgKytpKSB7XG4gICAgcG9pbnRDdXJyZW50ID0gcG9pbnRBZnRlcjtcbiAgICBwb2ludEFmdGVyID0gZ2V0UG9pbnQocG9pbnRzLCBpICsgMSk7XG4gICAgaWYgKCFwb2ludEN1cnJlbnQgfHwgIXBvaW50QWZ0ZXIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChhbG1vc3RFcXVhbHMoZGVsdGFLW2ldLCAwLCBFUFNJTE9OKSkge1xuICAgICAgbUtbaV0gPSBtS1tpICsgMV0gPSAwO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgYWxwaGFLID0gbUtbaV0gLyBkZWx0YUtbaV07XG4gICAgYmV0YUsgPSBtS1tpICsgMV0gLyBkZWx0YUtbaV07XG4gICAgc3F1YXJlZE1hZ25pdHVkZSA9IE1hdGgucG93KGFscGhhSywgMikgKyBNYXRoLnBvdyhiZXRhSywgMik7XG4gICAgaWYgKHNxdWFyZWRNYWduaXR1ZGUgPD0gOSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdGF1SyA9IDMgLyBNYXRoLnNxcnQoc3F1YXJlZE1hZ25pdHVkZSk7XG4gICAgbUtbaV0gPSBhbHBoYUsgKiB0YXVLICogZGVsdGFLW2ldO1xuICAgIG1LW2kgKyAxXSA9IGJldGFLICogdGF1SyAqIGRlbHRhS1tpXTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtb25vdG9uZUNvbXB1dGUocG9pbnRzOiBTcGxpbmVQb2ludFtdLCBtSzogbnVtYmVyW10sIGluZGV4QXhpczogJ3gnIHwgJ3knID0gJ3gnKSB7XG4gIGNvbnN0IHZhbHVlQXhpcyA9IGdldFZhbHVlQXhpcyhpbmRleEF4aXMpO1xuICBjb25zdCBwb2ludHNMZW4gPSBwb2ludHMubGVuZ3RoO1xuICBsZXQgZGVsdGE6IG51bWJlciwgcG9pbnRCZWZvcmU6IE9wdGlvbmFsU3BsaW5lUG9pbnQsIHBvaW50Q3VycmVudDogT3B0aW9uYWxTcGxpbmVQb2ludDtcbiAgbGV0IHBvaW50QWZ0ZXIgPSBnZXRQb2ludChwb2ludHMsIDApO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzTGVuOyArK2kpIHtcbiAgICBwb2ludEJlZm9yZSA9IHBvaW50Q3VycmVudDtcbiAgICBwb2ludEN1cnJlbnQgPSBwb2ludEFmdGVyO1xuICAgIHBvaW50QWZ0ZXIgPSBnZXRQb2ludChwb2ludHMsIGkgKyAxKTtcbiAgICBpZiAoIXBvaW50Q3VycmVudCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgaVBpeGVsID0gcG9pbnRDdXJyZW50W2luZGV4QXhpc107XG4gICAgY29uc3QgdlBpeGVsID0gcG9pbnRDdXJyZW50W3ZhbHVlQXhpc107XG4gICAgaWYgKHBvaW50QmVmb3JlKSB7XG4gICAgICBkZWx0YSA9IChpUGl4ZWwgLSBwb2ludEJlZm9yZVtpbmRleEF4aXNdKSAvIDM7XG4gICAgICBwb2ludEN1cnJlbnRbYGNwMSR7aW5kZXhBeGlzfWBdID0gaVBpeGVsIC0gZGVsdGE7XG4gICAgICBwb2ludEN1cnJlbnRbYGNwMSR7dmFsdWVBeGlzfWBdID0gdlBpeGVsIC0gZGVsdGEgKiBtS1tpXTtcbiAgICB9XG4gICAgaWYgKHBvaW50QWZ0ZXIpIHtcbiAgICAgIGRlbHRhID0gKHBvaW50QWZ0ZXJbaW5kZXhBeGlzXSAtIGlQaXhlbCkgLyAzO1xuICAgICAgcG9pbnRDdXJyZW50W2BjcDIke2luZGV4QXhpc31gXSA9IGlQaXhlbCArIGRlbHRhO1xuICAgICAgcG9pbnRDdXJyZW50W2BjcDIke3ZhbHVlQXhpc31gXSA9IHZQaXhlbCArIGRlbHRhICogbUtbaV07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIELDqXppZXIgY29udHJvbCBwb2ludHMgaW4gYSBzaW1pbGFyIHdheSB0aGFuIHxzcGxpbmVDdXJ2ZXwsXG4gKiBidXQgcHJlc2VydmVzIG1vbm90b25pY2l0eSBvZiB0aGUgcHJvdmlkZWQgZGF0YSBhbmQgZW5zdXJlcyBubyBsb2NhbCBleHRyZW11bXMgYXJlIGFkZGVkXG4gKiBiZXR3ZWVuIHRoZSBkYXRhc2V0IGRpc2NyZXRlIHBvaW50cyBkdWUgdG8gdGhlIGludGVycG9sYXRpb24uXG4gKiBTZWUgOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Nb25vdG9uZV9jdWJpY19pbnRlcnBvbGF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcGxpbmVDdXJ2ZU1vbm90b25lKHBvaW50czogU3BsaW5lUG9pbnRbXSwgaW5kZXhBeGlzOiAneCcgfCAneScgPSAneCcpIHtcbiAgY29uc3QgdmFsdWVBeGlzID0gZ2V0VmFsdWVBeGlzKGluZGV4QXhpcyk7XG4gIGNvbnN0IHBvaW50c0xlbiA9IHBvaW50cy5sZW5ndGg7XG4gIGNvbnN0IGRlbHRhSzogbnVtYmVyW10gPSBBcnJheShwb2ludHNMZW4pLmZpbGwoMCk7XG4gIGNvbnN0IG1LOiBudW1iZXJbXSA9IEFycmF5KHBvaW50c0xlbik7XG5cbiAgLy8gQ2FsY3VsYXRlIHNsb3BlcyAoZGVsdGFLKSBhbmQgaW5pdGlhbGl6ZSB0YW5nZW50cyAobUspXG4gIGxldCBpLCBwb2ludEJlZm9yZTogT3B0aW9uYWxTcGxpbmVQb2ludCwgcG9pbnRDdXJyZW50OiBPcHRpb25hbFNwbGluZVBvaW50O1xuICBsZXQgcG9pbnRBZnRlciA9IGdldFBvaW50KHBvaW50cywgMCk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHBvaW50c0xlbjsgKytpKSB7XG4gICAgcG9pbnRCZWZvcmUgPSBwb2ludEN1cnJlbnQ7XG4gICAgcG9pbnRDdXJyZW50ID0gcG9pbnRBZnRlcjtcbiAgICBwb2ludEFmdGVyID0gZ2V0UG9pbnQocG9pbnRzLCBpICsgMSk7XG4gICAgaWYgKCFwb2ludEN1cnJlbnQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChwb2ludEFmdGVyKSB7XG4gICAgICBjb25zdCBzbG9wZURlbHRhID0gcG9pbnRBZnRlcltpbmRleEF4aXNdIC0gcG9pbnRDdXJyZW50W2luZGV4QXhpc107XG5cbiAgICAgIC8vIEluIHRoZSBjYXNlIG9mIHR3byBwb2ludHMgdGhhdCBhcHBlYXIgYXQgdGhlIHNhbWUgeCBwaXhlbCwgc2xvcGVEZWx0YVggaXMgMFxuICAgICAgZGVsdGFLW2ldID0gc2xvcGVEZWx0YSAhPT0gMCA/IChwb2ludEFmdGVyW3ZhbHVlQXhpc10gLSBwb2ludEN1cnJlbnRbdmFsdWVBeGlzXSkgLyBzbG9wZURlbHRhIDogMDtcbiAgICB9XG4gICAgbUtbaV0gPSAhcG9pbnRCZWZvcmUgPyBkZWx0YUtbaV1cbiAgICAgIDogIXBvaW50QWZ0ZXIgPyBkZWx0YUtbaSAtIDFdXG4gICAgICAgIDogKHNpZ24oZGVsdGFLW2kgLSAxXSkgIT09IHNpZ24oZGVsdGFLW2ldKSkgPyAwXG4gICAgICAgICAgOiAoZGVsdGFLW2kgLSAxXSArIGRlbHRhS1tpXSkgLyAyO1xuICB9XG5cbiAgbW9ub3RvbmVBZGp1c3QocG9pbnRzLCBkZWx0YUssIG1LKTtcblxuICBtb25vdG9uZUNvbXB1dGUocG9pbnRzLCBtSywgaW5kZXhBeGlzKTtcbn1cblxuZnVuY3Rpb24gY2FwQ29udHJvbFBvaW50KHB0OiBudW1iZXIsIG1pbjogbnVtYmVyLCBtYXg6IG51bWJlcikge1xuICByZXR1cm4gTWF0aC5tYXgoTWF0aC5taW4ocHQsIG1heCksIG1pbik7XG59XG5cbmZ1bmN0aW9uIGNhcEJlemllclBvaW50cyhwb2ludHM6IFNwbGluZVBvaW50W10sIGFyZWE6IENoYXJ0QXJlYSkge1xuICBsZXQgaSwgaWxlbiwgcG9pbnQsIGluQXJlYSwgaW5BcmVhUHJldjtcbiAgbGV0IGluQXJlYU5leHQgPSBfaXNQb2ludEluQXJlYShwb2ludHNbMF0sIGFyZWEpO1xuICBmb3IgKGkgPSAwLCBpbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIGluQXJlYVByZXYgPSBpbkFyZWE7XG4gICAgaW5BcmVhID0gaW5BcmVhTmV4dDtcbiAgICBpbkFyZWFOZXh0ID0gaSA8IGlsZW4gLSAxICYmIF9pc1BvaW50SW5BcmVhKHBvaW50c1tpICsgMV0sIGFyZWEpO1xuICAgIGlmICghaW5BcmVhKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgaWYgKGluQXJlYVByZXYpIHtcbiAgICAgIHBvaW50LmNwMXggPSBjYXBDb250cm9sUG9pbnQocG9pbnQuY3AxeCwgYXJlYS5sZWZ0LCBhcmVhLnJpZ2h0KTtcbiAgICAgIHBvaW50LmNwMXkgPSBjYXBDb250cm9sUG9pbnQocG9pbnQuY3AxeSwgYXJlYS50b3AsIGFyZWEuYm90dG9tKTtcbiAgICB9XG4gICAgaWYgKGluQXJlYU5leHQpIHtcbiAgICAgIHBvaW50LmNwMnggPSBjYXBDb250cm9sUG9pbnQocG9pbnQuY3AyeCwgYXJlYS5sZWZ0LCBhcmVhLnJpZ2h0KTtcbiAgICAgIHBvaW50LmNwMnkgPSBjYXBDb250cm9sUG9pbnQocG9pbnQuY3AyeSwgYXJlYS50b3AsIGFyZWEuYm90dG9tKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX3VwZGF0ZUJlemllckNvbnRyb2xQb2ludHMoXG4gIHBvaW50czogU3BsaW5lUG9pbnRbXSxcbiAgb3B0aW9ucyxcbiAgYXJlYTogQ2hhcnRBcmVhLFxuICBsb29wOiBib29sZWFuLFxuICBpbmRleEF4aXM6ICd4JyB8ICd5J1xuKSB7XG4gIGxldCBpOiBudW1iZXIsIGlsZW46IG51bWJlciwgcG9pbnQ6IFNwbGluZVBvaW50LCBjb250cm9sUG9pbnRzOiBSZXR1cm5UeXBlPHR5cGVvZiBzcGxpbmVDdXJ2ZT47XG5cbiAgLy8gT25seSBjb25zaWRlciBwb2ludHMgdGhhdCBhcmUgZHJhd24gaW4gY2FzZSB0aGUgc3BhbkdhcHMgb3B0aW9uIGlzIHVzZWRcbiAgaWYgKG9wdGlvbnMuc3BhbkdhcHMpIHtcbiAgICBwb2ludHMgPSBwb2ludHMuZmlsdGVyKChwdCkgPT4gIXB0LnNraXApO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSA9PT0gJ21vbm90b25lJykge1xuICAgIHNwbGluZUN1cnZlTW9ub3RvbmUocG9pbnRzLCBpbmRleEF4aXMpO1xuICB9IGVsc2Uge1xuICAgIGxldCBwcmV2ID0gbG9vcCA/IHBvaW50c1twb2ludHMubGVuZ3RoIC0gMV0gOiBwb2ludHNbMF07XG4gICAgZm9yIChpID0gMCwgaWxlbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgY29udHJvbFBvaW50cyA9IHNwbGluZUN1cnZlKFxuICAgICAgICBwcmV2LFxuICAgICAgICBwb2ludCxcbiAgICAgICAgcG9pbnRzW01hdGgubWluKGkgKyAxLCBpbGVuIC0gKGxvb3AgPyAwIDogMSkpICUgaWxlbl0sXG4gICAgICAgIG9wdGlvbnMudGVuc2lvblxuICAgICAgKTtcbiAgICAgIHBvaW50LmNwMXggPSBjb250cm9sUG9pbnRzLnByZXZpb3VzLng7XG4gICAgICBwb2ludC5jcDF5ID0gY29udHJvbFBvaW50cy5wcmV2aW91cy55O1xuICAgICAgcG9pbnQuY3AyeCA9IGNvbnRyb2xQb2ludHMubmV4dC54O1xuICAgICAgcG9pbnQuY3AyeSA9IGNvbnRyb2xQb2ludHMubmV4dC55O1xuICAgICAgcHJldiA9IHBvaW50O1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRpb25zLmNhcEJlemllclBvaW50cykge1xuICAgIGNhcEJlemllclBvaW50cyhwb2ludHMsIGFyZWEpO1xuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUge0NoYXJ0QXJlYSwgU2NhbGV9IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcbmltcG9ydCB0eXBlIENoYXJ0IGZyb20gJy4uL2NvcmUvY29yZS5jb250cm9sbGVyLmpzJztcbmltcG9ydCB0eXBlIHtDaGFydEV2ZW50fSBmcm9tICcuLi90eXBlcy5qcyc7XG5pbXBvcnQge0lORklOSVRZfSBmcm9tICcuL2hlbHBlcnMubWF0aC5qcyc7XG5cbi8qKlxuICogTm90ZTogdHlwZWRlZnMgYXJlIGF1dG8tZXhwb3J0ZWQsIHNvIHVzZSBhIG1hZGUtdXAgYGRvbWAgbmFtZXNwYWNlIHdoZXJlXG4gKiBuZWNlc3NhcnkgdG8gYXZvaWQgZHVwbGljYXRlcyB3aXRoIGBleHBvcnQgKiBmcm9tICcuL2hlbHBlcnNgOyBzZWVcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvVHlwZVNjcmlwdC9pc3N1ZXMvNDYwMTFcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi9jb3JlL2NvcmUuY29udHJvbGxlci5qcycpLmRlZmF1bHQgfSBkb20uQ2hhcnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi90eXBlcycpLkNoYXJ0RXZlbnQgfSBDaGFydEV2ZW50XG4gKi9cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2lzRG9tU3VwcG9ydGVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJztcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2dldFBhcmVudE5vZGUoZG9tTm9kZTogSFRNTENhbnZhc0VsZW1lbnQpOiBIVE1MQ2FudmFzRWxlbWVudCB7XG4gIGxldCBwYXJlbnQgPSBkb21Ob2RlLnBhcmVudE5vZGU7XG4gIGlmIChwYXJlbnQgJiYgcGFyZW50LnRvU3RyaW5nKCkgPT09ICdbb2JqZWN0IFNoYWRvd1Jvb3RdJykge1xuICAgIHBhcmVudCA9IChwYXJlbnQgYXMgU2hhZG93Um9vdCkuaG9zdDtcbiAgfVxuICByZXR1cm4gcGFyZW50IGFzIEhUTUxDYW52YXNFbGVtZW50O1xufVxuXG4vKipcbiAqIGNvbnZlcnQgbWF4LXdpZHRoL21heC1oZWlnaHQgdmFsdWVzIHRoYXQgbWF5IGJlIHBlcmNlbnRhZ2VzIGludG8gYSBudW1iZXJcbiAqIEBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcGFyc2VNYXhTdHlsZShzdHlsZVZhbHVlOiBzdHJpbmcgfCBudW1iZXIsIG5vZGU6IEhUTUxFbGVtZW50LCBwYXJlbnRQcm9wZXJ0eTogc3RyaW5nKSB7XG4gIGxldCB2YWx1ZUluUGl4ZWxzOiBudW1iZXI7XG4gIGlmICh0eXBlb2Ygc3R5bGVWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWx1ZUluUGl4ZWxzID0gcGFyc2VJbnQoc3R5bGVWYWx1ZSwgMTApO1xuXG4gICAgaWYgKHN0eWxlVmFsdWUuaW5kZXhPZignJScpICE9PSAtMSkge1xuICAgICAgLy8gcGVyY2VudGFnZSAqIHNpemUgaW4gZGltZW5zaW9uXG4gICAgICB2YWx1ZUluUGl4ZWxzID0gKHZhbHVlSW5QaXhlbHMgLyAxMDApICogbm9kZS5wYXJlbnROb2RlW3BhcmVudFByb3BlcnR5XTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFsdWVJblBpeGVscyA9IHN0eWxlVmFsdWU7XG4gIH1cblxuICByZXR1cm4gdmFsdWVJblBpeGVscztcbn1cblxuY29uc3QgZ2V0Q29tcHV0ZWRTdHlsZSA9IChlbGVtZW50OiBIVE1MRWxlbWVudCk6IENTU1N0eWxlRGVjbGFyYXRpb24gPT5cbiAgZWxlbWVudC5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCwgbnVsbCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdHlsZShlbDogSFRNTEVsZW1lbnQsIHByb3BlcnR5OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gZ2V0Q29tcHV0ZWRTdHlsZShlbCkuZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eSk7XG59XG5cbmNvbnN0IHBvc2l0aW9ucyA9IFsndG9wJywgJ3JpZ2h0JywgJ2JvdHRvbScsICdsZWZ0J107XG5mdW5jdGlvbiBnZXRQb3NpdGlvbmVkU3R5bGUoc3R5bGVzOiBDU1NTdHlsZURlY2xhcmF0aW9uLCBzdHlsZTogc3RyaW5nLCBzdWZmaXg/OiBzdHJpbmcpOiBDaGFydEFyZWEge1xuICBjb25zdCByZXN1bHQgPSB7fSBhcyBDaGFydEFyZWE7XG4gIHN1ZmZpeCA9IHN1ZmZpeCA/ICctJyArIHN1ZmZpeCA6ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIGNvbnN0IHBvcyA9IHBvc2l0aW9uc1tpXTtcbiAgICByZXN1bHRbcG9zXSA9IHBhcnNlRmxvYXQoc3R5bGVzW3N0eWxlICsgJy0nICsgcG9zICsgc3VmZml4XSkgfHwgMDtcbiAgfVxuICByZXN1bHQud2lkdGggPSByZXN1bHQubGVmdCArIHJlc3VsdC5yaWdodDtcbiAgcmVzdWx0LmhlaWdodCA9IHJlc3VsdC50b3AgKyByZXN1bHQuYm90dG9tO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5jb25zdCB1c2VPZmZzZXRQb3MgPSAoeDogbnVtYmVyLCB5OiBudW1iZXIsIHRhcmdldDogSFRNTEVsZW1lbnQgfCBFdmVudFRhcmdldCkgPT5cbiAgKHggPiAwIHx8IHkgPiAwKSAmJiAoIXRhcmdldCB8fCAhKHRhcmdldCBhcyBIVE1MRWxlbWVudCkuc2hhZG93Um9vdCk7XG5cbi8qKlxuICogQHBhcmFtIGVcbiAqIEBwYXJhbSBjYW52YXNcbiAqIEByZXR1cm5zIENhbnZhcyBwb3NpdGlvblxuICovXG5mdW5jdGlvbiBnZXRDYW52YXNQb3NpdGlvbihcbiAgZTogRXZlbnQgfCBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCxcbiAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudFxuKToge1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gICAgYm94OiBib29sZWFuO1xuICB9IHtcbiAgY29uc3QgdG91Y2hlcyA9IChlIGFzIFRvdWNoRXZlbnQpLnRvdWNoZXM7XG4gIGNvbnN0IHNvdXJjZSA9ICh0b3VjaGVzICYmIHRvdWNoZXMubGVuZ3RoID8gdG91Y2hlc1swXSA6IGUpIGFzIE1vdXNlRXZlbnQ7XG4gIGNvbnN0IHtvZmZzZXRYLCBvZmZzZXRZfSA9IHNvdXJjZSBhcyBNb3VzZUV2ZW50O1xuICBsZXQgYm94ID0gZmFsc2U7XG4gIGxldCB4LCB5O1xuICBpZiAodXNlT2Zmc2V0UG9zKG9mZnNldFgsIG9mZnNldFksIGUudGFyZ2V0KSkge1xuICAgIHggPSBvZmZzZXRYO1xuICAgIHkgPSBvZmZzZXRZO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHJlY3QgPSBjYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgeCA9IHNvdXJjZS5jbGllbnRYIC0gcmVjdC5sZWZ0O1xuICAgIHkgPSBzb3VyY2UuY2xpZW50WSAtIHJlY3QudG9wO1xuICAgIGJveCA9IHRydWU7XG4gIH1cbiAgcmV0dXJuIHt4LCB5LCBib3h9O1xufVxuXG4vKipcbiAqIEdldHMgYW4gZXZlbnQncyB4LCB5IGNvb3JkaW5hdGVzLCByZWxhdGl2ZSB0byB0aGUgY2hhcnQgYXJlYVxuICogQHBhcmFtIGV2ZW50XG4gKiBAcGFyYW0gY2hhcnRcbiAqIEByZXR1cm5zIHggYW5kIHkgY29vcmRpbmF0ZXMgb2YgdGhlIGV2ZW50XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlbGF0aXZlUG9zaXRpb24oXG4gIGV2ZW50OiBFdmVudCB8IENoYXJ0RXZlbnQgfCBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCxcbiAgY2hhcnQ6IENoYXJ0XG4pOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0ge1xuICBpZiAoJ25hdGl2ZScgaW4gZXZlbnQpIHtcbiAgICByZXR1cm4gZXZlbnQ7XG4gIH1cblxuICBjb25zdCB7Y2FudmFzLCBjdXJyZW50RGV2aWNlUGl4ZWxSYXRpb30gPSBjaGFydDtcbiAgY29uc3Qgc3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGNhbnZhcyk7XG4gIGNvbnN0IGJvcmRlckJveCA9IHN0eWxlLmJveFNpemluZyA9PT0gJ2JvcmRlci1ib3gnO1xuICBjb25zdCBwYWRkaW5ncyA9IGdldFBvc2l0aW9uZWRTdHlsZShzdHlsZSwgJ3BhZGRpbmcnKTtcbiAgY29uc3QgYm9yZGVycyA9IGdldFBvc2l0aW9uZWRTdHlsZShzdHlsZSwgJ2JvcmRlcicsICd3aWR0aCcpO1xuICBjb25zdCB7eCwgeSwgYm94fSA9IGdldENhbnZhc1Bvc2l0aW9uKGV2ZW50LCBjYW52YXMpO1xuICBjb25zdCB4T2Zmc2V0ID0gcGFkZGluZ3MubGVmdCArIChib3ggJiYgYm9yZGVycy5sZWZ0KTtcbiAgY29uc3QgeU9mZnNldCA9IHBhZGRpbmdzLnRvcCArIChib3ggJiYgYm9yZGVycy50b3ApO1xuXG4gIGxldCB7d2lkdGgsIGhlaWdodH0gPSBjaGFydDtcbiAgaWYgKGJvcmRlckJveCkge1xuICAgIHdpZHRoIC09IHBhZGRpbmdzLndpZHRoICsgYm9yZGVycy53aWR0aDtcbiAgICBoZWlnaHQgLT0gcGFkZGluZ3MuaGVpZ2h0ICsgYm9yZGVycy5oZWlnaHQ7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICB4OiBNYXRoLnJvdW5kKCh4IC0geE9mZnNldCkgLyB3aWR0aCAqIGNhbnZhcy53aWR0aCAvIGN1cnJlbnREZXZpY2VQaXhlbFJhdGlvKSxcbiAgICB5OiBNYXRoLnJvdW5kKCh5IC0geU9mZnNldCkgLyBoZWlnaHQgKiBjYW52YXMuaGVpZ2h0IC8gY3VycmVudERldmljZVBpeGVsUmF0aW8pXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldENvbnRhaW5lclNpemUoY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBQYXJ0aWFsPFNjYWxlPiB7XG4gIGxldCBtYXhXaWR0aDogbnVtYmVyLCBtYXhIZWlnaHQ6IG51bWJlcjtcblxuICBpZiAod2lkdGggPT09IHVuZGVmaW5lZCB8fCBoZWlnaHQgPT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IF9nZXRQYXJlbnROb2RlKGNhbnZhcyk7XG4gICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgIHdpZHRoID0gY2FudmFzLmNsaWVudFdpZHRoO1xuICAgICAgaGVpZ2h0ID0gY2FudmFzLmNsaWVudEhlaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcmVjdCA9IGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsgLy8gdGhpcyBpcyB0aGUgYm9yZGVyIGJveCBvZiB0aGUgY29udGFpbmVyXG4gICAgICBjb25zdCBjb250YWluZXJTdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoY29udGFpbmVyKTtcbiAgICAgIGNvbnN0IGNvbnRhaW5lckJvcmRlciA9IGdldFBvc2l0aW9uZWRTdHlsZShjb250YWluZXJTdHlsZSwgJ2JvcmRlcicsICd3aWR0aCcpO1xuICAgICAgY29uc3QgY29udGFpbmVyUGFkZGluZyA9IGdldFBvc2l0aW9uZWRTdHlsZShjb250YWluZXJTdHlsZSwgJ3BhZGRpbmcnKTtcbiAgICAgIHdpZHRoID0gcmVjdC53aWR0aCAtIGNvbnRhaW5lclBhZGRpbmcud2lkdGggLSBjb250YWluZXJCb3JkZXIud2lkdGg7XG4gICAgICBoZWlnaHQgPSByZWN0LmhlaWdodCAtIGNvbnRhaW5lclBhZGRpbmcuaGVpZ2h0IC0gY29udGFpbmVyQm9yZGVyLmhlaWdodDtcbiAgICAgIG1heFdpZHRoID0gcGFyc2VNYXhTdHlsZShjb250YWluZXJTdHlsZS5tYXhXaWR0aCwgY29udGFpbmVyLCAnY2xpZW50V2lkdGgnKTtcbiAgICAgIG1heEhlaWdodCA9IHBhcnNlTWF4U3R5bGUoY29udGFpbmVyU3R5bGUubWF4SGVpZ2h0LCBjb250YWluZXIsICdjbGllbnRIZWlnaHQnKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHtcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgbWF4V2lkdGg6IG1heFdpZHRoIHx8IElORklOSVRZLFxuICAgIG1heEhlaWdodDogbWF4SGVpZ2h0IHx8IElORklOSVRZXG4gIH07XG59XG5cbmNvbnN0IHJvdW5kMSA9ICh2OiBudW1iZXIpID0+IE1hdGgucm91bmQodiAqIDEwKSAvIDEwO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuZXhwb3J0IGZ1bmN0aW9uIGdldE1heGltdW1TaXplKFxuICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50LFxuICBiYldpZHRoPzogbnVtYmVyLFxuICBiYkhlaWdodD86IG51bWJlcixcbiAgYXNwZWN0UmF0aW8/OiBudW1iZXJcbik6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfSB7XG4gIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShjYW52YXMpO1xuICBjb25zdCBtYXJnaW5zID0gZ2V0UG9zaXRpb25lZFN0eWxlKHN0eWxlLCAnbWFyZ2luJyk7XG4gIGNvbnN0IG1heFdpZHRoID0gcGFyc2VNYXhTdHlsZShzdHlsZS5tYXhXaWR0aCwgY2FudmFzLCAnY2xpZW50V2lkdGgnKSB8fCBJTkZJTklUWTtcbiAgY29uc3QgbWF4SGVpZ2h0ID0gcGFyc2VNYXhTdHlsZShzdHlsZS5tYXhIZWlnaHQsIGNhbnZhcywgJ2NsaWVudEhlaWdodCcpIHx8IElORklOSVRZO1xuICBjb25zdCBjb250YWluZXJTaXplID0gZ2V0Q29udGFpbmVyU2l6ZShjYW52YXMsIGJiV2lkdGgsIGJiSGVpZ2h0KTtcbiAgbGV0IHt3aWR0aCwgaGVpZ2h0fSA9IGNvbnRhaW5lclNpemU7XG5cbiAgaWYgKHN0eWxlLmJveFNpemluZyA9PT0gJ2NvbnRlbnQtYm94Jykge1xuICAgIGNvbnN0IGJvcmRlcnMgPSBnZXRQb3NpdGlvbmVkU3R5bGUoc3R5bGUsICdib3JkZXInLCAnd2lkdGgnKTtcbiAgICBjb25zdCBwYWRkaW5ncyA9IGdldFBvc2l0aW9uZWRTdHlsZShzdHlsZSwgJ3BhZGRpbmcnKTtcbiAgICB3aWR0aCAtPSBwYWRkaW5ncy53aWR0aCArIGJvcmRlcnMud2lkdGg7XG4gICAgaGVpZ2h0IC09IHBhZGRpbmdzLmhlaWdodCArIGJvcmRlcnMuaGVpZ2h0O1xuICB9XG4gIHdpZHRoID0gTWF0aC5tYXgoMCwgd2lkdGggLSBtYXJnaW5zLndpZHRoKTtcbiAgaGVpZ2h0ID0gTWF0aC5tYXgoMCwgYXNwZWN0UmF0aW8gPyB3aWR0aCAvIGFzcGVjdFJhdGlvIDogaGVpZ2h0IC0gbWFyZ2lucy5oZWlnaHQpO1xuICB3aWR0aCA9IHJvdW5kMShNYXRoLm1pbih3aWR0aCwgbWF4V2lkdGgsIGNvbnRhaW5lclNpemUubWF4V2lkdGgpKTtcbiAgaGVpZ2h0ID0gcm91bmQxKE1hdGgubWluKGhlaWdodCwgbWF4SGVpZ2h0LCBjb250YWluZXJTaXplLm1heEhlaWdodCkpO1xuICBpZiAod2lkdGggJiYgIWhlaWdodCkge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy80NjU5XG4gICAgLy8gSWYgdGhlIGNhbnZhcyBoYXMgd2lkdGgsIGJ1dCBubyBoZWlnaHQsIGRlZmF1bHQgdG8gYXNwZWN0UmF0aW8gb2YgMiAoY2FudmFzIGRlZmF1bHQpXG4gICAgaGVpZ2h0ID0gcm91bmQxKHdpZHRoIC8gMik7XG4gIH1cblxuICBjb25zdCBtYWludGFpbkhlaWdodCA9IGJiV2lkdGggIT09IHVuZGVmaW5lZCB8fCBiYkhlaWdodCAhPT0gdW5kZWZpbmVkO1xuXG4gIGlmIChtYWludGFpbkhlaWdodCAmJiBhc3BlY3RSYXRpbyAmJiBjb250YWluZXJTaXplLmhlaWdodCAmJiBoZWlnaHQgPiBjb250YWluZXJTaXplLmhlaWdodCkge1xuICAgIGhlaWdodCA9IGNvbnRhaW5lclNpemUuaGVpZ2h0O1xuICAgIHdpZHRoID0gcm91bmQxKE1hdGguZmxvb3IoaGVpZ2h0ICogYXNwZWN0UmF0aW8pKTtcbiAgfVxuXG4gIHJldHVybiB7d2lkdGgsIGhlaWdodH07XG59XG5cbi8qKlxuICogQHBhcmFtIGNoYXJ0XG4gKiBAcGFyYW0gZm9yY2VSYXRpb1xuICogQHBhcmFtIGZvcmNlU3R5bGVcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGNhbnZhcyBjb250ZXh0IHNpemUgb3IgdHJhbnNmb3JtYXRpb24gaGFzIGNoYW5nZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXRpbmFTY2FsZShcbiAgY2hhcnQ6IENoYXJ0LFxuICBmb3JjZVJhdGlvOiBudW1iZXIsXG4gIGZvcmNlU3R5bGU/OiBib29sZWFuXG4pOiBib29sZWFuIHwgdm9pZCB7XG4gIGNvbnN0IHBpeGVsUmF0aW8gPSBmb3JjZVJhdGlvIHx8IDE7XG4gIGNvbnN0IGRldmljZUhlaWdodCA9IE1hdGguZmxvb3IoY2hhcnQuaGVpZ2h0ICogcGl4ZWxSYXRpbyk7XG4gIGNvbnN0IGRldmljZVdpZHRoID0gTWF0aC5mbG9vcihjaGFydC53aWR0aCAqIHBpeGVsUmF0aW8pO1xuXG4gIGNoYXJ0LmhlaWdodCA9IE1hdGguZmxvb3IoY2hhcnQuaGVpZ2h0KTtcbiAgY2hhcnQud2lkdGggPSBNYXRoLmZsb29yKGNoYXJ0LndpZHRoKTtcblxuICBjb25zdCBjYW52YXMgPSBjaGFydC5jYW52YXM7XG5cbiAgLy8gSWYgbm8gc3R5bGUgaGFzIGJlZW4gc2V0IG9uIHRoZSBjYW52YXMsIHRoZSByZW5kZXIgc2l6ZSBpcyB1c2VkIGFzIGRpc3BsYXkgc2l6ZSxcbiAgLy8gbWFraW5nIHRoZSBjaGFydCB2aXN1YWxseSBiaWdnZXIsIHNvIGxldCdzIGVuZm9yY2UgaXQgdG8gdGhlIFwiY29ycmVjdFwiIHZhbHVlcy5cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8zNTc1XG4gIGlmIChjYW52YXMuc3R5bGUgJiYgKGZvcmNlU3R5bGUgfHwgKCFjYW52YXMuc3R5bGUuaGVpZ2h0ICYmICFjYW52YXMuc3R5bGUud2lkdGgpKSkge1xuICAgIGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBgJHtjaGFydC5oZWlnaHR9cHhgO1xuICAgIGNhbnZhcy5zdHlsZS53aWR0aCA9IGAke2NoYXJ0LndpZHRofXB4YDtcbiAgfVxuXG4gIGlmIChjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyAhPT0gcGl4ZWxSYXRpb1xuICAgICAgfHwgY2FudmFzLmhlaWdodCAhPT0gZGV2aWNlSGVpZ2h0XG4gICAgICB8fCBjYW52YXMud2lkdGggIT09IGRldmljZVdpZHRoKSB7XG4gICAgY2hhcnQuY3VycmVudERldmljZVBpeGVsUmF0aW8gPSBwaXhlbFJhdGlvO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBkZXZpY2VIZWlnaHQ7XG4gICAgY2FudmFzLndpZHRoID0gZGV2aWNlV2lkdGg7XG4gICAgY2hhcnQuY3R4LnNldFRyYW5zZm9ybShwaXhlbFJhdGlvLCAwLCAwLCBwaXhlbFJhdGlvLCAwLCAwKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogRGV0ZWN0cyBzdXBwb3J0IGZvciBvcHRpb25zIG9iamVjdCBhcmd1bWVudCBpbiBhZGRFdmVudExpc3RlbmVyLlxuICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0V2ZW50VGFyZ2V0L2FkZEV2ZW50TGlzdGVuZXIjU2FmZWx5X2RldGVjdGluZ19vcHRpb25fc3VwcG9ydFxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IHN1cHBvcnRzRXZlbnRMaXN0ZW5lck9wdGlvbnMgPSAoZnVuY3Rpb24oKSB7XG4gIGxldCBwYXNzaXZlU3VwcG9ydGVkID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgIGdldCBwYXNzaXZlKCkgeyAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIGJyb3dzZXIgYXR0ZW1wdHMgdG8gYWNjZXNzIHRoZSBwYXNzaXZlIHByb3BlcnR5LlxuICAgICAgICBwYXNzaXZlU3VwcG9ydGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gYXMgRXZlbnRMaXN0ZW5lck9wdGlvbnM7XG5cbiAgICBpZiAoX2lzRG9tU3VwcG9ydGVkKCkpIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd0ZXN0JywgbnVsbCwgb3B0aW9ucyk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigndGVzdCcsIG51bGwsIG9wdGlvbnMpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIGNvbnRpbnVlIHJlZ2FyZGxlc3Mgb2YgZXJyb3JcbiAgfVxuICByZXR1cm4gcGFzc2l2ZVN1cHBvcnRlZDtcbn0oKSk7XG5cbi8qKlxuICogVGhlIFwidXNlZFwiIHNpemUgaXMgdGhlIGZpbmFsIHZhbHVlIG9mIGEgZGltZW5zaW9uIHByb3BlcnR5IGFmdGVyIGFsbCBjYWxjdWxhdGlvbnMgaGF2ZVxuICogYmVlbiBwZXJmb3JtZWQuIFRoaXMgbWV0aG9kIHVzZXMgdGhlIGNvbXB1dGVkIHN0eWxlIG9mIGBlbGVtZW50YCBidXQgcmV0dXJucyB1bmRlZmluZWRcbiAqIGlmIHRoZSBjb21wdXRlZCBzdHlsZSBpcyBub3QgZXhwcmVzc2VkIGluIHBpeGVscy4gVGhhdCBjYW4gaGFwcGVuIGluIHNvbWUgY2FzZXMgd2hlcmVcbiAqIGBlbGVtZW50YCBoYXMgYSBzaXplIHJlbGF0aXZlIHRvIGl0cyBwYXJlbnQgYW5kIHRoaXMgbGFzdCBvbmUgaXMgbm90IHlldCBkaXNwbGF5ZWQsXG4gKiBmb3IgZXhhbXBsZSBiZWNhdXNlIG9mIGBkaXNwbGF5OiBub25lYCBvbiBhIHBhcmVudCBub2RlLlxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvdXNlZF92YWx1ZVxuICogQHJldHVybnMgU2l6ZSBpbiBwaXhlbHMgb3IgdW5kZWZpbmVkIGlmIHVua25vd24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJlYWRVc2VkU2l6ZShcbiAgZWxlbWVudDogSFRNTEVsZW1lbnQsXG4gIHByb3BlcnR5OiAnd2lkdGgnIHwgJ2hlaWdodCdcbik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHZhbHVlID0gZ2V0U3R5bGUoZWxlbWVudCwgcHJvcGVydHkpO1xuICBjb25zdCBtYXRjaGVzID0gdmFsdWUgJiYgdmFsdWUubWF0Y2goL14oXFxkKykoXFwuXFxkKyk/cHgkLyk7XG4gIHJldHVybiBtYXRjaGVzID8gK21hdGNoZXNbMV0gOiB1bmRlZmluZWQ7XG59XG4iLCAiaW1wb3J0IHR5cGUge1BvaW50LCBTcGxpbmVQb2ludH0gZnJvbSAnLi4vdHlwZXMvZ2VvbWV0cmljLmpzJztcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX3BvaW50SW5MaW5lKHAxOiBQb2ludCwgcDI6IFBvaW50LCB0OiBudW1iZXIsIG1vZGU/KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIHJldHVybiB7XG4gICAgeDogcDEueCArIHQgKiAocDIueCAtIHAxLngpLFxuICAgIHk6IHAxLnkgKyB0ICogKHAyLnkgLSBwMS55KVxuICB9O1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfc3RlcHBlZEludGVycG9sYXRpb24oXG4gIHAxOiBQb2ludCxcbiAgcDI6IFBvaW50LFxuICB0OiBudW1iZXIsIG1vZGU6ICdtaWRkbGUnIHwgJ2FmdGVyJyB8IHVua25vd25cbikge1xuICByZXR1cm4ge1xuICAgIHg6IHAxLnggKyB0ICogKHAyLnggLSBwMS54KSxcbiAgICB5OiBtb2RlID09PSAnbWlkZGxlJyA/IHQgPCAwLjUgPyBwMS55IDogcDIueVxuICAgICAgOiBtb2RlID09PSAnYWZ0ZXInID8gdCA8IDEgPyBwMS55IDogcDIueVxuICAgICAgICA6IHQgPiAwID8gcDIueSA6IHAxLnlcbiAgfTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2JlemllckludGVycG9sYXRpb24ocDE6IFNwbGluZVBvaW50LCBwMjogU3BsaW5lUG9pbnQsIHQ6IG51bWJlciwgbW9kZT8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgY29uc3QgY3AxID0ge3g6IHAxLmNwMngsIHk6IHAxLmNwMnl9O1xuICBjb25zdCBjcDIgPSB7eDogcDIuY3AxeCwgeTogcDIuY3AxeX07XG4gIGNvbnN0IGEgPSBfcG9pbnRJbkxpbmUocDEsIGNwMSwgdCk7XG4gIGNvbnN0IGIgPSBfcG9pbnRJbkxpbmUoY3AxLCBjcDIsIHQpO1xuICBjb25zdCBjID0gX3BvaW50SW5MaW5lKGNwMiwgcDIsIHQpO1xuICBjb25zdCBkID0gX3BvaW50SW5MaW5lKGEsIGIsIHQpO1xuICBjb25zdCBlID0gX3BvaW50SW5MaW5lKGIsIGMsIHQpO1xuICByZXR1cm4gX3BvaW50SW5MaW5lKGQsIGUsIHQpO1xufVxuIiwgImV4cG9ydCBpbnRlcmZhY2UgUlRMQWRhcHRlciB7XG4gIHgoeDogbnVtYmVyKTogbnVtYmVyO1xuICBzZXRXaWR0aCh3OiBudW1iZXIpOiB2b2lkO1xuICB0ZXh0QWxpZ24oYWxpZ246ICdjZW50ZXInIHwgJ2xlZnQnIHwgJ3JpZ2h0Jyk6ICdjZW50ZXInIHwgJ2xlZnQnIHwgJ3JpZ2h0JztcbiAgeFBsdXMoeDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKTogbnVtYmVyO1xuICBsZWZ0Rm9yTHRyKHg6IG51bWJlciwgaXRlbVdpZHRoOiBudW1iZXIpOiBudW1iZXI7XG59XG5cbmNvbnN0IGdldFJpZ2h0VG9MZWZ0QWRhcHRlciA9IGZ1bmN0aW9uKHJlY3RYOiBudW1iZXIsIHdpZHRoOiBudW1iZXIpOiBSVExBZGFwdGVyIHtcbiAgcmV0dXJuIHtcbiAgICB4KHgpIHtcbiAgICAgIHJldHVybiByZWN0WCArIHJlY3RYICsgd2lkdGggLSB4O1xuICAgIH0sXG4gICAgc2V0V2lkdGgodykge1xuICAgICAgd2lkdGggPSB3O1xuICAgIH0sXG4gICAgdGV4dEFsaWduKGFsaWduKSB7XG4gICAgICBpZiAoYWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgIHJldHVybiBhbGlnbjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhbGlnbiA9PT0gJ3JpZ2h0JyA/ICdsZWZ0JyA6ICdyaWdodCc7XG4gICAgfSxcbiAgICB4UGx1cyh4LCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHggLSB2YWx1ZTtcbiAgICB9LFxuICAgIGxlZnRGb3JMdHIoeCwgaXRlbVdpZHRoKSB7XG4gICAgICByZXR1cm4geCAtIGl0ZW1XaWR0aDtcbiAgICB9LFxuICB9O1xufTtcblxuY29uc3QgZ2V0TGVmdFRvUmlnaHRBZGFwdGVyID0gZnVuY3Rpb24oKTogUlRMQWRhcHRlciB7XG4gIHJldHVybiB7XG4gICAgeCh4KSB7XG4gICAgICByZXR1cm4geDtcbiAgICB9LFxuICAgIHNldFdpZHRoKHcpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIH0sXG4gICAgdGV4dEFsaWduKGFsaWduKSB7XG4gICAgICByZXR1cm4gYWxpZ247XG4gICAgfSxcbiAgICB4UGx1cyh4LCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIHggKyB2YWx1ZTtcbiAgICB9LFxuICAgIGxlZnRGb3JMdHIoeCwgX2l0ZW1XaWR0aCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgcmV0dXJuIHg7XG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSdGxBZGFwdGVyKHJ0bDogYm9vbGVhbiwgcmVjdFg6IG51bWJlciwgd2lkdGg6IG51bWJlcikge1xuICByZXR1cm4gcnRsID8gZ2V0UmlnaHRUb0xlZnRBZGFwdGVyKHJlY3RYLCB3aWR0aCkgOiBnZXRMZWZ0VG9SaWdodEFkYXB0ZXIoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG92ZXJyaWRlVGV4dERpcmVjdGlvbihjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgZGlyZWN0aW9uOiAnbHRyJyB8ICdydGwnKSB7XG4gIGxldCBzdHlsZTogQ1NTU3R5bGVEZWNsYXJhdGlvbiwgb3JpZ2luYWw6IFtzdHJpbmcsIHN0cmluZ107XG4gIGlmIChkaXJlY3Rpb24gPT09ICdsdHInIHx8IGRpcmVjdGlvbiA9PT0gJ3J0bCcpIHtcbiAgICBzdHlsZSA9IGN0eC5jYW52YXMuc3R5bGU7XG4gICAgb3JpZ2luYWwgPSBbXG4gICAgICBzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCdkaXJlY3Rpb24nKSxcbiAgICAgIHN0eWxlLmdldFByb3BlcnR5UHJpb3JpdHkoJ2RpcmVjdGlvbicpLFxuICAgIF07XG5cbiAgICBzdHlsZS5zZXRQcm9wZXJ0eSgnZGlyZWN0aW9uJywgZGlyZWN0aW9uLCAnaW1wb3J0YW50Jyk7XG4gICAgKGN0eCBhcyB7IHByZXZUZXh0RGlyZWN0aW9uPzogW3N0cmluZywgc3RyaW5nXSB9KS5wcmV2VGV4dERpcmVjdGlvbiA9IG9yaWdpbmFsO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXN0b3JlVGV4dERpcmVjdGlvbihjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgb3JpZ2luYWw/OiBbc3RyaW5nLCBzdHJpbmddKSB7XG4gIGlmIChvcmlnaW5hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZGVsZXRlIChjdHggYXMgeyBwcmV2VGV4dERpcmVjdGlvbj86IFtzdHJpbmcsIHN0cmluZ10gfSkucHJldlRleHREaXJlY3Rpb247XG4gICAgY3R4LmNhbnZhcy5zdHlsZS5zZXRQcm9wZXJ0eSgnZGlyZWN0aW9uJywgb3JpZ2luYWxbMF0sIG9yaWdpbmFsWzFdKTtcbiAgfVxufVxuIiwgImltcG9ydCB7X2FuZ2xlQmV0d2VlbiwgX2FuZ2xlRGlmZiwgX2lzQmV0d2VlbiwgX25vcm1hbGl6ZUFuZ2xlfSBmcm9tICcuL2hlbHBlcnMubWF0aC5qcyc7XG5pbXBvcnQge2NyZWF0ZUNvbnRleHR9IGZyb20gJy4vaGVscGVycy5vcHRpb25zLmpzJztcbmltcG9ydCB7aXNQYXR0ZXJuT3JHcmFkaWVudH0gZnJvbSAnLi9oZWxwZXJzLmNvbG9yLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vZWxlbWVudHMvZWxlbWVudC5saW5lLmpzJykuZGVmYXVsdCB9IExpbmVFbGVtZW50XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vZWxlbWVudHMvZWxlbWVudC5wb2ludC5qcycpLmRlZmF1bHQgfSBQb2ludEVsZW1lbnRcbiAqIEB0eXBlZGVmIHt7c3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIsIGxvb3A6IGJvb2xlYW4sIHN0eWxlPzogYW55fX0gU2VnbWVudFxuICovXG5cbmZ1bmN0aW9uIHByb3BlcnR5Rm4ocHJvcGVydHkpIHtcbiAgaWYgKHByb3BlcnR5ID09PSAnYW5nbGUnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGJldHdlZW46IF9hbmdsZUJldHdlZW4sXG4gICAgICBjb21wYXJlOiBfYW5nbGVEaWZmLFxuICAgICAgbm9ybWFsaXplOiBfbm9ybWFsaXplQW5nbGUsXG4gICAgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGJldHdlZW46IF9pc0JldHdlZW4sXG4gICAgY29tcGFyZTogKGEsIGIpID0+IGEgLSBiLFxuICAgIG5vcm1hbGl6ZTogeCA9PiB4XG4gIH07XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVNlZ21lbnQoe3N0YXJ0LCBlbmQsIGNvdW50LCBsb29wLCBzdHlsZX0pIHtcbiAgcmV0dXJuIHtcbiAgICBzdGFydDogc3RhcnQgJSBjb3VudCxcbiAgICBlbmQ6IGVuZCAlIGNvdW50LFxuICAgIGxvb3A6IGxvb3AgJiYgKGVuZCAtIHN0YXJ0ICsgMSkgJSBjb3VudCA9PT0gMCxcbiAgICBzdHlsZVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRTZWdtZW50KHNlZ21lbnQsIHBvaW50cywgYm91bmRzKSB7XG4gIGNvbnN0IHtwcm9wZXJ0eSwgc3RhcnQ6IHN0YXJ0Qm91bmQsIGVuZDogZW5kQm91bmR9ID0gYm91bmRzO1xuICBjb25zdCB7YmV0d2Vlbiwgbm9ybWFsaXplfSA9IHByb3BlcnR5Rm4ocHJvcGVydHkpO1xuICBjb25zdCBjb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItY29uc3RcbiAgbGV0IHtzdGFydCwgZW5kLCBsb29wfSA9IHNlZ21lbnQ7XG4gIGxldCBpLCBpbGVuO1xuXG4gIGlmIChsb29wKSB7XG4gICAgc3RhcnQgKz0gY291bnQ7XG4gICAgZW5kICs9IGNvdW50O1xuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBjb3VudDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgaWYgKCFiZXR3ZWVuKG5vcm1hbGl6ZShwb2ludHNbc3RhcnQgJSBjb3VudF1bcHJvcGVydHldKSwgc3RhcnRCb3VuZCwgZW5kQm91bmQpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgc3RhcnQtLTtcbiAgICAgIGVuZC0tO1xuICAgIH1cbiAgICBzdGFydCAlPSBjb3VudDtcbiAgICBlbmQgJT0gY291bnQ7XG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIHtcbiAgICBlbmQgKz0gY291bnQ7XG4gIH1cbiAgcmV0dXJuIHtzdGFydCwgZW5kLCBsb29wLCBzdHlsZTogc2VnbWVudC5zdHlsZX07XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3ViLXNlZ21lbnQocykgb2YgYSBsaW5lIHNlZ21lbnQgdGhhdCBmYWxsIGluIHRoZSBnaXZlbiBib3VuZHNcbiAqIEBwYXJhbSB7b2JqZWN0fSBzZWdtZW50XG4gKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudC5zdGFydCAtIHN0YXJ0IGluZGV4IG9mIHRoZSBzZWdtZW50LCByZWZlcnJpbmcgdGhlIHBvaW50cyBhcnJheVxuICogQHBhcmFtIHtudW1iZXJ9IHNlZ21lbnQuZW5kIC0gZW5kIGluZGV4IG9mIHRoZSBzZWdtZW50LCByZWZlcnJpbmcgdGhlIHBvaW50cyBhcnJheVxuICogQHBhcmFtIHtib29sZWFufSBzZWdtZW50Lmxvb3AgLSBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VnbWVudCBpcyBhIGxvb3BcbiAqIEBwYXJhbSB7b2JqZWN0fSBbc2VnbWVudC5zdHlsZV0gLSBzZWdtZW50IHN0eWxlXG4gKiBAcGFyYW0ge1BvaW50RWxlbWVudFtdfSBwb2ludHMgLSB0aGUgcG9pbnRzIHRoYXQgdGhpcyBzZWdtZW50IHJlZmVycyB0b1xuICogQHBhcmFtIHtvYmplY3R9IFtib3VuZHNdXG4gKiBAcGFyYW0ge3N0cmluZ30gYm91bmRzLnByb3BlcnR5IC0gdGhlIHByb3BlcnR5IG9mIGEgYFBvaW50RWxlbWVudGAgd2UgYXJlIGJvdW5kaW5nLiBgeGAsIGB5YCBvciBgYW5nbGVgLlxuICogQHBhcmFtIHtudW1iZXJ9IGJvdW5kcy5zdGFydCAtIHN0YXJ0IHZhbHVlIG9mIHRoZSBwcm9wZXJ0eVxuICogQHBhcmFtIHtudW1iZXJ9IGJvdW5kcy5lbmQgLSBlbmQgdmFsdWUgb2YgdGhlIHByb3BlcnR5XG4gKiBAcHJpdmF0ZVxuICoqL1xuZXhwb3J0IGZ1bmN0aW9uIF9ib3VuZFNlZ21lbnQoc2VnbWVudCwgcG9pbnRzLCBib3VuZHMpIHtcbiAgaWYgKCFib3VuZHMpIHtcbiAgICByZXR1cm4gW3NlZ21lbnRdO1xuICB9XG5cbiAgY29uc3Qge3Byb3BlcnR5LCBzdGFydDogc3RhcnRCb3VuZCwgZW5kOiBlbmRCb3VuZH0gPSBib3VuZHM7XG4gIGNvbnN0IGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgY29uc3Qge2NvbXBhcmUsIGJldHdlZW4sIG5vcm1hbGl6ZX0gPSBwcm9wZXJ0eUZuKHByb3BlcnR5KTtcbiAgY29uc3Qge3N0YXJ0LCBlbmQsIGxvb3AsIHN0eWxlfSA9IGdldFNlZ21lbnQoc2VnbWVudCwgcG9pbnRzLCBib3VuZHMpO1xuXG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBsZXQgaW5zaWRlID0gZmFsc2U7XG4gIGxldCBzdWJTdGFydCA9IG51bGw7XG4gIGxldCB2YWx1ZSwgcG9pbnQsIHByZXZWYWx1ZTtcblxuICBjb25zdCBzdGFydElzQmVmb3JlID0gKCkgPT4gYmV0d2VlbihzdGFydEJvdW5kLCBwcmV2VmFsdWUsIHZhbHVlKSAmJiBjb21wYXJlKHN0YXJ0Qm91bmQsIHByZXZWYWx1ZSkgIT09IDA7XG4gIGNvbnN0IGVuZElzQmVmb3JlID0gKCkgPT4gY29tcGFyZShlbmRCb3VuZCwgdmFsdWUpID09PSAwIHx8IGJldHdlZW4oZW5kQm91bmQsIHByZXZWYWx1ZSwgdmFsdWUpO1xuICBjb25zdCBzaG91bGRTdGFydCA9ICgpID0+IGluc2lkZSB8fCBzdGFydElzQmVmb3JlKCk7XG4gIGNvbnN0IHNob3VsZFN0b3AgPSAoKSA9PiAhaW5zaWRlIHx8IGVuZElzQmVmb3JlKCk7XG5cbiAgZm9yIChsZXQgaSA9IHN0YXJ0LCBwcmV2ID0gc3RhcnQ7IGkgPD0gZW5kOyArK2kpIHtcbiAgICBwb2ludCA9IHBvaW50c1tpICUgY291bnRdO1xuXG4gICAgaWYgKHBvaW50LnNraXApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhbHVlID0gbm9ybWFsaXplKHBvaW50W3Byb3BlcnR5XSk7XG5cbiAgICBpZiAodmFsdWUgPT09IHByZXZWYWx1ZSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaW5zaWRlID0gYmV0d2Vlbih2YWx1ZSwgc3RhcnRCb3VuZCwgZW5kQm91bmQpO1xuXG4gICAgaWYgKHN1YlN0YXJ0ID09PSBudWxsICYmIHNob3VsZFN0YXJ0KCkpIHtcbiAgICAgIHN1YlN0YXJ0ID0gY29tcGFyZSh2YWx1ZSwgc3RhcnRCb3VuZCkgPT09IDAgPyBpIDogcHJldjtcbiAgICB9XG5cbiAgICBpZiAoc3ViU3RhcnQgIT09IG51bGwgJiYgc2hvdWxkU3RvcCgpKSB7XG4gICAgICByZXN1bHQucHVzaChub3JtYWxpemVTZWdtZW50KHtzdGFydDogc3ViU3RhcnQsIGVuZDogaSwgbG9vcCwgY291bnQsIHN0eWxlfSkpO1xuICAgICAgc3ViU3RhcnQgPSBudWxsO1xuICAgIH1cbiAgICBwcmV2ID0gaTtcbiAgICBwcmV2VmFsdWUgPSB2YWx1ZTtcbiAgfVxuXG4gIGlmIChzdWJTdGFydCAhPT0gbnVsbCkge1xuICAgIHJlc3VsdC5wdXNoKG5vcm1hbGl6ZVNlZ21lbnQoe3N0YXJ0OiBzdWJTdGFydCwgZW5kLCBsb29wLCBjb3VudCwgc3R5bGV9KSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgc2VnbWVudHMgb2YgdGhlIGxpbmUgdGhhdCBhcmUgaW5zaWRlIGdpdmVuIGJvdW5kc1xuICogQHBhcmFtIHtMaW5lRWxlbWVudH0gbGluZVxuICogQHBhcmFtIHtvYmplY3R9IFtib3VuZHNdXG4gKiBAcGFyYW0ge3N0cmluZ30gYm91bmRzLnByb3BlcnR5IC0gdGhlIHByb3BlcnR5IHdlIGFyZSBib3VuZGluZyB3aXRoLiBgeGAsIGB5YCBvciBgYW5nbGVgLlxuICogQHBhcmFtIHtudW1iZXJ9IGJvdW5kcy5zdGFydCAtIHN0YXJ0IHZhbHVlIG9mIHRoZSBgcHJvcGVydHlgXG4gKiBAcGFyYW0ge251bWJlcn0gYm91bmRzLmVuZCAtIGVuZCB2YWx1ZSBvZiB0aGUgYHByb3BlcnR5YFxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9ib3VuZFNlZ21lbnRzKGxpbmUsIGJvdW5kcykge1xuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgY29uc3Qgc2VnbWVudHMgPSBsaW5lLnNlZ21lbnRzO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzdWIgPSBfYm91bmRTZWdtZW50KHNlZ21lbnRzW2ldLCBsaW5lLnBvaW50cywgYm91bmRzKTtcbiAgICBpZiAoc3ViLmxlbmd0aCkge1xuICAgICAgcmVzdWx0LnB1c2goLi4uc3ViKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBGaW5kIHN0YXJ0IGFuZCBlbmQgaW5kZXggb2YgYSBsaW5lLlxuICovXG5mdW5jdGlvbiBmaW5kU3RhcnRBbmRFbmQocG9pbnRzLCBjb3VudCwgbG9vcCwgc3BhbkdhcHMpIHtcbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGVuZCA9IGNvdW50IC0gMTtcblxuICBpZiAobG9vcCAmJiAhc3BhbkdhcHMpIHtcbiAgICAvLyBsb29wIGFuZCBub3Qgc3Bhbm5pbmcgZ2FwcywgZmlyc3QgZmluZCBhIGdhcCB0byBzdGFydCBmcm9tXG4gICAgd2hpbGUgKHN0YXJ0IDwgY291bnQgJiYgIXBvaW50c1tzdGFydF0uc2tpcCkge1xuICAgICAgc3RhcnQrKztcbiAgICB9XG4gIH1cblxuICAvLyBmaW5kIGZpcnN0IG5vbiBza2lwcGVkIHBvaW50IChhZnRlciB0aGUgZmlyc3QgZ2FwIHBvc3NpYmx5KVxuICB3aGlsZSAoc3RhcnQgPCBjb3VudCAmJiBwb2ludHNbc3RhcnRdLnNraXApIHtcbiAgICBzdGFydCsrO1xuICB9XG5cbiAgLy8gaWYgd2UgbG9vcGVkIHRvIGNvdW50LCBzdGFydCBuZWVkcyB0byBiZSAwXG4gIHN0YXJ0ICU9IGNvdW50O1xuXG4gIGlmIChsb29wKSB7XG4gICAgLy8gbG9vcCB3aWxsIGdvIHBhc3QgY291bnQsIGlmIHN0YXJ0ID4gMFxuICAgIGVuZCArPSBzdGFydDtcbiAgfVxuXG4gIHdoaWxlIChlbmQgPiBzdGFydCAmJiBwb2ludHNbZW5kICUgY291bnRdLnNraXApIHtcbiAgICBlbmQtLTtcbiAgfVxuXG4gIC8vIGVuZCBjb3VsZCBiZSBtb3JlIHRoYW4gY291bnQsIG5vcm1hbGl6ZVxuICBlbmQgJT0gY291bnQ7XG5cbiAgcmV0dXJuIHtzdGFydCwgZW5kfTtcbn1cblxuLyoqXG4gKiBDb21wdXRlIHNvbGlkIHNlZ21lbnRzIGZyb20gUG9pbnRzLCB3aGVuIHNwYW5HYXBzID09PSBmYWxzZVxuICogQHBhcmFtIHtQb2ludEVsZW1lbnRbXX0gcG9pbnRzIC0gdGhlIHBvaW50c1xuICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IC0gc3RhcnQgaW5kZXhcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXggLSBtYXggaW5kZXggKGNhbiBnbyBwYXN0IGNvdW50IG9uIGEgbG9vcClcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gbG9vcCAtIGJvb2xlYW4gaW5kaWNhdGluZyB0aGF0IHRoaXMgd291bGQgYmUgYSBsb29wIGlmIG5vIGdhcHMgYXJlIGZvdW5kXG4gKi9cbmZ1bmN0aW9uIHNvbGlkU2VnbWVudHMocG9pbnRzLCBzdGFydCwgbWF4LCBsb29wKSB7XG4gIGNvbnN0IGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGxldCBsYXN0ID0gc3RhcnQ7XG4gIGxldCBwcmV2ID0gcG9pbnRzW3N0YXJ0XTtcbiAgbGV0IGVuZDtcblxuICBmb3IgKGVuZCA9IHN0YXJ0ICsgMTsgZW5kIDw9IG1heDsgKytlbmQpIHtcbiAgICBjb25zdCBjdXIgPSBwb2ludHNbZW5kICUgY291bnRdO1xuICAgIGlmIChjdXIuc2tpcCB8fCBjdXIuc3RvcCkge1xuICAgICAgaWYgKCFwcmV2LnNraXApIHtcbiAgICAgICAgbG9vcCA9IGZhbHNlO1xuICAgICAgICByZXN1bHQucHVzaCh7c3RhcnQ6IHN0YXJ0ICUgY291bnQsIGVuZDogKGVuZCAtIDEpICUgY291bnQsIGxvb3B9KTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBzdGFydCA9IGxhc3QgPSBjdXIuc3RvcCA/IGVuZCA6IG51bGw7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxhc3QgPSBlbmQ7XG4gICAgICBpZiAocHJldi5za2lwKSB7XG4gICAgICAgIHN0YXJ0ID0gZW5kO1xuICAgICAgfVxuICAgIH1cbiAgICBwcmV2ID0gY3VyO1xuICB9XG5cbiAgaWYgKGxhc3QgIT09IG51bGwpIHtcbiAgICByZXN1bHQucHVzaCh7c3RhcnQ6IHN0YXJ0ICUgY291bnQsIGVuZDogbGFzdCAlIGNvdW50LCBsb29wfSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIENvbXB1dGUgdGhlIGNvbnRpbnVvdXMgc2VnbWVudHMgdGhhdCBkZWZpbmUgdGhlIHdob2xlIGxpbmVcbiAqIFRoZXJlIGNhbiBiZSBza2lwcGVkIHBvaW50cyB3aXRoaW4gYSBzZWdtZW50LCBpZiBzcGFuR2FwcyBpcyB0cnVlLlxuICogQHBhcmFtIHtMaW5lRWxlbWVudH0gbGluZVxuICogQHBhcmFtIHtvYmplY3R9IFtzZWdtZW50T3B0aW9uc11cbiAqIEByZXR1cm4ge1NlZ21lbnRbXX1cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfY29tcHV0ZVNlZ21lbnRzKGxpbmUsIHNlZ21lbnRPcHRpb25zKSB7XG4gIGNvbnN0IHBvaW50cyA9IGxpbmUucG9pbnRzO1xuICBjb25zdCBzcGFuR2FwcyA9IGxpbmUub3B0aW9ucy5zcGFuR2FwcztcbiAgY29uc3QgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuXG4gIGlmICghY291bnQpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBsb29wID0gISFsaW5lLl9sb29wO1xuICBjb25zdCB7c3RhcnQsIGVuZH0gPSBmaW5kU3RhcnRBbmRFbmQocG9pbnRzLCBjb3VudCwgbG9vcCwgc3BhbkdhcHMpO1xuXG4gIGlmIChzcGFuR2FwcyA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBzcGxpdEJ5U3R5bGVzKGxpbmUsIFt7c3RhcnQsIGVuZCwgbG9vcH1dLCBwb2ludHMsIHNlZ21lbnRPcHRpb25zKTtcbiAgfVxuXG4gIGNvbnN0IG1heCA9IGVuZCA8IHN0YXJ0ID8gZW5kICsgY291bnQgOiBlbmQ7XG4gIGNvbnN0IGNvbXBsZXRlTG9vcCA9ICEhbGluZS5fZnVsbExvb3AgJiYgc3RhcnQgPT09IDAgJiYgZW5kID09PSBjb3VudCAtIDE7XG4gIHJldHVybiBzcGxpdEJ5U3R5bGVzKGxpbmUsIHNvbGlkU2VnbWVudHMocG9pbnRzLCBzdGFydCwgbWF4LCBjb21wbGV0ZUxvb3ApLCBwb2ludHMsIHNlZ21lbnRPcHRpb25zKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1NlZ21lbnRbXX0gc2VnbWVudHNcbiAqIEBwYXJhbSB7UG9pbnRFbGVtZW50W119IHBvaW50c1xuICogQHBhcmFtIHtvYmplY3R9IFtzZWdtZW50T3B0aW9uc11cbiAqIEByZXR1cm4ge1NlZ21lbnRbXX1cbiAqL1xuZnVuY3Rpb24gc3BsaXRCeVN0eWxlcyhsaW5lLCBzZWdtZW50cywgcG9pbnRzLCBzZWdtZW50T3B0aW9ucykge1xuICBpZiAoIXNlZ21lbnRPcHRpb25zIHx8ICFzZWdtZW50T3B0aW9ucy5zZXRDb250ZXh0IHx8ICFwb2ludHMpIHtcbiAgICByZXR1cm4gc2VnbWVudHM7XG4gIH1cbiAgcmV0dXJuIGRvU3BsaXRCeVN0eWxlcyhsaW5lLCBzZWdtZW50cywgcG9pbnRzLCBzZWdtZW50T3B0aW9ucyk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtMaW5lRWxlbWVudH0gbGluZVxuICogQHBhcmFtIHtTZWdtZW50W119IHNlZ21lbnRzXG4gKiBAcGFyYW0ge1BvaW50RWxlbWVudFtdfSBwb2ludHNcbiAqIEBwYXJhbSB7b2JqZWN0fSBbc2VnbWVudE9wdGlvbnNdXG4gKiBAcmV0dXJuIHtTZWdtZW50W119XG4gKi9cbmZ1bmN0aW9uIGRvU3BsaXRCeVN0eWxlcyhsaW5lLCBzZWdtZW50cywgcG9pbnRzLCBzZWdtZW50T3B0aW9ucykge1xuICBjb25zdCBjaGFydENvbnRleHQgPSBsaW5lLl9jaGFydC5nZXRDb250ZXh0KCk7XG4gIGNvbnN0IGJhc2VTdHlsZSA9IHJlYWRTdHlsZShsaW5lLm9wdGlvbnMpO1xuICBjb25zdCB7X2RhdGFzZXRJbmRleDogZGF0YXNldEluZGV4LCBvcHRpb25zOiB7c3BhbkdhcHN9fSA9IGxpbmU7XG4gIGNvbnN0IGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGxldCBwcmV2U3R5bGUgPSBiYXNlU3R5bGU7XG4gIGxldCBzdGFydCA9IHNlZ21lbnRzWzBdLnN0YXJ0O1xuICBsZXQgaSA9IHN0YXJ0O1xuXG4gIGZ1bmN0aW9uIGFkZFN0eWxlKHMsIGUsIGwsIHN0KSB7XG4gICAgY29uc3QgZGlyID0gc3BhbkdhcHMgPyAtMSA6IDE7XG4gICAgaWYgKHMgPT09IGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gU3R5bGUgY2FuIG5vdCBzdGFydC9lbmQgb24gYSBza2lwcGVkIHBvaW50LCBhZGp1c3QgaW5kaWNlcyBhY2NvcmRpbmdseVxuICAgIHMgKz0gY291bnQ7XG4gICAgd2hpbGUgKHBvaW50c1tzICUgY291bnRdLnNraXApIHtcbiAgICAgIHMgLT0gZGlyO1xuICAgIH1cbiAgICB3aGlsZSAocG9pbnRzW2UgJSBjb3VudF0uc2tpcCkge1xuICAgICAgZSArPSBkaXI7XG4gICAgfVxuICAgIGlmIChzICUgY291bnQgIT09IGUgJSBjb3VudCkge1xuICAgICAgcmVzdWx0LnB1c2goe3N0YXJ0OiBzICUgY291bnQsIGVuZDogZSAlIGNvdW50LCBsb29wOiBsLCBzdHlsZTogc3R9KTtcbiAgICAgIHByZXZTdHlsZSA9IHN0O1xuICAgICAgc3RhcnQgPSBlICUgY291bnQ7XG4gICAgfVxuICB9XG5cbiAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgc3RhcnQgPSBzcGFuR2FwcyA/IHN0YXJ0IDogc2VnbWVudC5zdGFydDtcbiAgICBsZXQgcHJldiA9IHBvaW50c1tzdGFydCAlIGNvdW50XTtcbiAgICBsZXQgc3R5bGU7XG4gICAgZm9yIChpID0gc3RhcnQgKyAxOyBpIDw9IHNlZ21lbnQuZW5kOyBpKyspIHtcbiAgICAgIGNvbnN0IHB0ID0gcG9pbnRzW2kgJSBjb3VudF07XG4gICAgICBzdHlsZSA9IHJlYWRTdHlsZShzZWdtZW50T3B0aW9ucy5zZXRDb250ZXh0KGNyZWF0ZUNvbnRleHQoY2hhcnRDb250ZXh0LCB7XG4gICAgICAgIHR5cGU6ICdzZWdtZW50JyxcbiAgICAgICAgcDA6IHByZXYsXG4gICAgICAgIHAxOiBwdCxcbiAgICAgICAgcDBEYXRhSW5kZXg6IChpIC0gMSkgJSBjb3VudCxcbiAgICAgICAgcDFEYXRhSW5kZXg6IGkgJSBjb3VudCxcbiAgICAgICAgZGF0YXNldEluZGV4XG4gICAgICB9KSkpO1xuICAgICAgaWYgKHN0eWxlQ2hhbmdlZChzdHlsZSwgcHJldlN0eWxlKSkge1xuICAgICAgICBhZGRTdHlsZShzdGFydCwgaSAtIDEsIHNlZ21lbnQubG9vcCwgcHJldlN0eWxlKTtcbiAgICAgIH1cbiAgICAgIHByZXYgPSBwdDtcbiAgICAgIHByZXZTdHlsZSA9IHN0eWxlO1xuICAgIH1cbiAgICBpZiAoc3RhcnQgPCBpIC0gMSkge1xuICAgICAgYWRkU3R5bGUoc3RhcnQsIGkgLSAxLCBzZWdtZW50Lmxvb3AsIHByZXZTdHlsZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gcmVhZFN0eWxlKG9wdGlvbnMpIHtcbiAgcmV0dXJuIHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IG9wdGlvbnMuYmFja2dyb3VuZENvbG9yLFxuICAgIGJvcmRlckNhcFN0eWxlOiBvcHRpb25zLmJvcmRlckNhcFN0eWxlLFxuICAgIGJvcmRlckRhc2g6IG9wdGlvbnMuYm9yZGVyRGFzaCxcbiAgICBib3JkZXJEYXNoT2Zmc2V0OiBvcHRpb25zLmJvcmRlckRhc2hPZmZzZXQsXG4gICAgYm9yZGVySm9pblN0eWxlOiBvcHRpb25zLmJvcmRlckpvaW5TdHlsZSxcbiAgICBib3JkZXJXaWR0aDogb3B0aW9ucy5ib3JkZXJXaWR0aCxcbiAgICBib3JkZXJDb2xvcjogb3B0aW9ucy5ib3JkZXJDb2xvclxuICB9O1xufVxuXG5mdW5jdGlvbiBzdHlsZUNoYW5nZWQoc3R5bGUsIHByZXZTdHlsZSkge1xuICBpZiAoIXByZXZTdHlsZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBjYWNoZSA9IFtdO1xuICBjb25zdCByZXBsYWNlciA9IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICBpZiAoIWlzUGF0dGVybk9yR3JhZGllbnQodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGlmICghY2FjaGUuaW5jbHVkZXModmFsdWUpKSB7XG4gICAgICBjYWNoZS5wdXNoKHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIGNhY2hlLmluZGV4T2YodmFsdWUpO1xuICB9O1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc3R5bGUsIHJlcGxhY2VyKSAhPT0gSlNPTi5zdHJpbmdpZnkocHJldlN0eWxlLCByZXBsYWNlcik7XG59XG4iLCAiaW1wb3J0IHtyZXF1ZXN0QW5pbUZyYW1lfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZXh0cmFzLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi9jb3JlLmFuaW1hdGlvbi5qcycpLmRlZmF1bHQgfSBBbmltYXRpb25cbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuL2NvcmUuY29udHJvbGxlci5qcycpLmRlZmF1bHQgfSBDaGFydFxuICovXG5cbi8qKlxuICogUGxlYXNlIHVzZSB0aGUgbW9kdWxlJ3MgZGVmYXVsdCBleHBvcnQgd2hpY2ggcHJvdmlkZXMgYSBzaW5nbGV0b24gaW5zdGFuY2VcbiAqIE5vdGU6IGNsYXNzIGlzIGV4cG9ydCBmb3IgdHlwZWRvY1xuICovXG5leHBvcnQgY2xhc3MgQW5pbWF0b3Ige1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9yZXF1ZXN0ID0gbnVsbDtcbiAgICB0aGlzLl9jaGFydHMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5fcnVubmluZyA9IGZhbHNlO1xuICAgIHRoaXMuX2xhc3REYXRlID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfbm90aWZ5KGNoYXJ0LCBhbmltcywgZGF0ZSwgdHlwZSkge1xuICAgIGNvbnN0IGNhbGxiYWNrcyA9IGFuaW1zLmxpc3RlbmVyc1t0eXBlXTtcbiAgICBjb25zdCBudW1TdGVwcyA9IGFuaW1zLmR1cmF0aW9uO1xuXG4gICAgY2FsbGJhY2tzLmZvckVhY2goZm4gPT4gZm4oe1xuICAgICAgY2hhcnQsXG4gICAgICBpbml0aWFsOiBhbmltcy5pbml0aWFsLFxuICAgICAgbnVtU3RlcHMsXG4gICAgICBjdXJyZW50U3RlcDogTWF0aC5taW4oZGF0ZSAtIGFuaW1zLnN0YXJ0LCBudW1TdGVwcylcbiAgICB9KSk7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9yZWZyZXNoKCkge1xuICAgIGlmICh0aGlzLl9yZXF1ZXN0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX3J1bm5pbmcgPSB0cnVlO1xuXG4gICAgdGhpcy5fcmVxdWVzdCA9IHJlcXVlc3RBbmltRnJhbWUuY2FsbCh3aW5kb3csICgpID0+IHtcbiAgICAgIHRoaXMuX3VwZGF0ZSgpO1xuICAgICAgdGhpcy5fcmVxdWVzdCA9IG51bGw7XG5cbiAgICAgIGlmICh0aGlzLl9ydW5uaW5nKSB7XG4gICAgICAgIHRoaXMuX3JlZnJlc2goKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3VwZGF0ZShkYXRlID0gRGF0ZS5ub3coKSkge1xuICAgIGxldCByZW1haW5pbmcgPSAwO1xuXG4gICAgdGhpcy5fY2hhcnRzLmZvckVhY2goKGFuaW1zLCBjaGFydCkgPT4ge1xuICAgICAgaWYgKCFhbmltcy5ydW5uaW5nIHx8ICFhbmltcy5pdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbXMgPSBhbmltcy5pdGVtcztcbiAgICAgIGxldCBpID0gaXRlbXMubGVuZ3RoIC0gMTtcbiAgICAgIGxldCBkcmF3ID0gZmFsc2U7XG4gICAgICBsZXQgaXRlbTtcblxuICAgICAgZm9yICg7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIGl0ZW0gPSBpdGVtc1tpXTtcblxuICAgICAgICBpZiAoaXRlbS5fYWN0aXZlKSB7XG4gICAgICAgICAgaWYgKGl0ZW0uX3RvdGFsID4gYW5pbXMuZHVyYXRpb24pIHtcbiAgICAgICAgICAgIC8vIGlmIHRoZSBhbmltYXRpb24gaGFzIGJlZW4gdXBkYXRlZCBhbmQgaXRzIGR1cmF0aW9uIHByb2xvbmdlZCxcbiAgICAgICAgICAgIC8vIHVwZGF0ZSB0byB0b3RhbCBkdXJhdGlvbiBvZiBjdXJyZW50IGFuaW1hdGlvbnMgcnVuIChmb3IgcHJvZ3Jlc3MgZXZlbnQpXG4gICAgICAgICAgICBhbmltcy5kdXJhdGlvbiA9IGl0ZW0uX3RvdGFsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpdGVtLnRpY2soZGF0ZSk7XG4gICAgICAgICAgZHJhdyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmVtb3ZlIHRoZSBpdGVtIGJ5IHJlcGxhY2luZyBpdCB3aXRoIGxhc3QgaXRlbSBhbmQgcmVtb3ZpbmcgdGhlIGxhc3RcbiAgICAgICAgICAvLyBBIGxvdCBmYXN0ZXIgdGhhbiBzcGxpY2UuXG4gICAgICAgICAgaXRlbXNbaV0gPSBpdGVtc1tpdGVtcy5sZW5ndGggLSAxXTtcbiAgICAgICAgICBpdGVtcy5wb3AoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZHJhdykge1xuICAgICAgICBjaGFydC5kcmF3KCk7XG4gICAgICAgIHRoaXMuX25vdGlmeShjaGFydCwgYW5pbXMsIGRhdGUsICdwcm9ncmVzcycpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgICBhbmltcy5ydW5uaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX25vdGlmeShjaGFydCwgYW5pbXMsIGRhdGUsICdjb21wbGV0ZScpO1xuICAgICAgICBhbmltcy5pbml0aWFsID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJlbWFpbmluZyArPSBpdGVtcy5sZW5ndGg7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9sYXN0RGF0ZSA9IGRhdGU7XG5cbiAgICBpZiAocmVtYWluaW5nID09PSAwKSB7XG4gICAgICB0aGlzLl9ydW5uaW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0QW5pbXMoY2hhcnQpIHtcbiAgICBjb25zdCBjaGFydHMgPSB0aGlzLl9jaGFydHM7XG4gICAgbGV0IGFuaW1zID0gY2hhcnRzLmdldChjaGFydCk7XG4gICAgaWYgKCFhbmltcykge1xuICAgICAgYW5pbXMgPSB7XG4gICAgICAgIHJ1bm5pbmc6IGZhbHNlLFxuICAgICAgICBpbml0aWFsOiB0cnVlLFxuICAgICAgICBpdGVtczogW10sXG4gICAgICAgIGxpc3RlbmVyczoge1xuICAgICAgICAgIGNvbXBsZXRlOiBbXSxcbiAgICAgICAgICBwcm9ncmVzczogW11cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGNoYXJ0cy5zZXQoY2hhcnQsIGFuaW1zKTtcbiAgICB9XG4gICAgcmV0dXJuIGFuaW1zO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBldmVudCAtIGV2ZW50IG5hbWVcblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gY2IgLSBjYWxsYmFja1xuXHQgKi9cbiAgbGlzdGVuKGNoYXJ0LCBldmVudCwgY2IpIHtcbiAgICB0aGlzLl9nZXRBbmltcyhjaGFydCkubGlzdGVuZXJzW2V2ZW50XS5wdXNoKGNiKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBBZGQgYW5pbWF0aW9uc1xuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydFxuXHQgKiBAcGFyYW0ge0FuaW1hdGlvbltdfSBpdGVtcyAtIGFuaW1hdGlvbnNcblx0ICovXG4gIGFkZChjaGFydCwgaXRlbXMpIHtcbiAgICBpZiAoIWl0ZW1zIHx8ICFpdGVtcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZ2V0QW5pbXMoY2hhcnQpLml0ZW1zLnB1c2goLi4uaXRlbXMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIENvdW50cyBudW1iZXIgb2YgYWN0aXZlIGFuaW1hdGlvbnMgZm9yIHRoZSBjaGFydFxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydFxuXHQgKi9cbiAgaGFzKGNoYXJ0KSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldEFuaW1zKGNoYXJ0KS5pdGVtcy5sZW5ndGggPiAwO1xuICB9XG5cbiAgLyoqXG5cdCAqIFN0YXJ0IGFuaW1hdGluZyAoYWxsIGNoYXJ0cylcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnRcblx0ICovXG4gIHN0YXJ0KGNoYXJ0KSB7XG4gICAgY29uc3QgYW5pbXMgPSB0aGlzLl9jaGFydHMuZ2V0KGNoYXJ0KTtcbiAgICBpZiAoIWFuaW1zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGFuaW1zLnJ1bm5pbmcgPSB0cnVlO1xuICAgIGFuaW1zLnN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICBhbmltcy5kdXJhdGlvbiA9IGFuaW1zLml0ZW1zLnJlZHVjZSgoYWNjLCBjdXIpID0+IE1hdGgubWF4KGFjYywgY3VyLl9kdXJhdGlvbiksIDApO1xuICAgIHRoaXMuX3JlZnJlc2goKTtcbiAgfVxuXG4gIHJ1bm5pbmcoY2hhcnQpIHtcbiAgICBpZiAoIXRoaXMuX3J1bm5pbmcpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgYW5pbXMgPSB0aGlzLl9jaGFydHMuZ2V0KGNoYXJ0KTtcbiAgICBpZiAoIWFuaW1zIHx8ICFhbmltcy5ydW5uaW5nIHx8ICFhbmltcy5pdGVtcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcblx0ICogU3RvcCBhbGwgYW5pbWF0aW9ucyBmb3IgdGhlIGNoYXJ0XG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG5cdCAqL1xuICBzdG9wKGNoYXJ0KSB7XG4gICAgY29uc3QgYW5pbXMgPSB0aGlzLl9jaGFydHMuZ2V0KGNoYXJ0KTtcbiAgICBpZiAoIWFuaW1zIHx8ICFhbmltcy5pdGVtcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaXRlbXMgPSBhbmltcy5pdGVtcztcbiAgICBsZXQgaSA9IGl0ZW1zLmxlbmd0aCAtIDE7XG5cbiAgICBmb3IgKDsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGl0ZW1zW2ldLmNhbmNlbCgpO1xuICAgIH1cbiAgICBhbmltcy5pdGVtcyA9IFtdO1xuICAgIHRoaXMuX25vdGlmeShjaGFydCwgYW5pbXMsIERhdGUubm93KCksICdjb21wbGV0ZScpO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJlbW92ZSBjaGFydCBmcm9tIEFuaW1hdG9yXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG5cdCAqL1xuICByZW1vdmUoY2hhcnQpIHtcbiAgICByZXR1cm4gdGhpcy5fY2hhcnRzLmRlbGV0ZShjaGFydCk7XG4gIH1cbn1cblxuLy8gc2luZ2xldG9uIGluc3RhbmNlXG5leHBvcnQgZGVmYXVsdCAvKiAjX19QVVJFX18gKi8gbmV3IEFuaW1hdG9yKCk7XG4iLCAiaW1wb3J0IGVmZmVjdHMgZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmVhc2luZy5qcyc7XG5pbXBvcnQge3Jlc29sdmV9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5vcHRpb25zLmpzJztcbmltcG9ydCB7Y29sb3IgYXMgaGVscGVyc0NvbG9yfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29sb3IuanMnO1xuXG5jb25zdCB0cmFuc3BhcmVudCA9ICd0cmFuc3BhcmVudCc7XG5jb25zdCBpbnRlcnBvbGF0b3JzID0ge1xuICBib29sZWFuKGZyb20sIHRvLCBmYWN0b3IpIHtcbiAgICByZXR1cm4gZmFjdG9yID4gMC41ID8gdG8gOiBmcm9tO1xuICB9LFxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZyb21cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBmYWN0b3JcbiAgICovXG4gIGNvbG9yKGZyb20sIHRvLCBmYWN0b3IpIHtcbiAgICBjb25zdCBjMCA9IGhlbHBlcnNDb2xvcihmcm9tIHx8IHRyYW5zcGFyZW50KTtcbiAgICBjb25zdCBjMSA9IGMwLnZhbGlkICYmIGhlbHBlcnNDb2xvcih0byB8fCB0cmFuc3BhcmVudCk7XG4gICAgcmV0dXJuIGMxICYmIGMxLnZhbGlkXG4gICAgICA/IGMxLm1peChjMCwgZmFjdG9yKS5oZXhTdHJpbmcoKVxuICAgICAgOiB0bztcbiAgfSxcbiAgbnVtYmVyKGZyb20sIHRvLCBmYWN0b3IpIHtcbiAgICByZXR1cm4gZnJvbSArICh0byAtIGZyb20pICogZmFjdG9yO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBbmltYXRpb24ge1xuICBjb25zdHJ1Y3RvcihjZmcsIHRhcmdldCwgcHJvcCwgdG8pIHtcbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0YXJnZXRbcHJvcF07XG5cbiAgICB0byA9IHJlc29sdmUoW2NmZy50bywgdG8sIGN1cnJlbnRWYWx1ZSwgY2ZnLmZyb21dKTtcbiAgICBjb25zdCBmcm9tID0gcmVzb2x2ZShbY2ZnLmZyb20sIGN1cnJlbnRWYWx1ZSwgdG9dKTtcblxuICAgIHRoaXMuX2FjdGl2ZSA9IHRydWU7XG4gICAgdGhpcy5fZm4gPSBjZmcuZm4gfHwgaW50ZXJwb2xhdG9yc1tjZmcudHlwZSB8fCB0eXBlb2YgZnJvbV07XG4gICAgdGhpcy5fZWFzaW5nID0gZWZmZWN0c1tjZmcuZWFzaW5nXSB8fCBlZmZlY3RzLmxpbmVhcjtcbiAgICB0aGlzLl9zdGFydCA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSArIChjZmcuZGVsYXkgfHwgMCkpO1xuICAgIHRoaXMuX2R1cmF0aW9uID0gdGhpcy5fdG90YWwgPSBNYXRoLmZsb29yKGNmZy5kdXJhdGlvbik7XG4gICAgdGhpcy5fbG9vcCA9ICEhY2ZnLmxvb3A7XG4gICAgdGhpcy5fdGFyZ2V0ID0gdGFyZ2V0O1xuICAgIHRoaXMuX3Byb3AgPSBwcm9wO1xuICAgIHRoaXMuX2Zyb20gPSBmcm9tO1xuICAgIHRoaXMuX3RvID0gdG87XG4gICAgdGhpcy5fcHJvbWlzZXMgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBhY3RpdmUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZTtcbiAgfVxuXG4gIHVwZGF0ZShjZmcsIHRvLCBkYXRlKSB7XG4gICAgaWYgKHRoaXMuX2FjdGl2ZSkge1xuICAgICAgdGhpcy5fbm90aWZ5KGZhbHNlKTtcblxuICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gdGhpcy5fdGFyZ2V0W3RoaXMuX3Byb3BdO1xuICAgICAgY29uc3QgZWxhcHNlZCA9IGRhdGUgLSB0aGlzLl9zdGFydDtcbiAgICAgIGNvbnN0IHJlbWFpbiA9IHRoaXMuX2R1cmF0aW9uIC0gZWxhcHNlZDtcbiAgICAgIHRoaXMuX3N0YXJ0ID0gZGF0ZTtcbiAgICAgIHRoaXMuX2R1cmF0aW9uID0gTWF0aC5mbG9vcihNYXRoLm1heChyZW1haW4sIGNmZy5kdXJhdGlvbikpO1xuICAgICAgdGhpcy5fdG90YWwgKz0gZWxhcHNlZDtcbiAgICAgIHRoaXMuX2xvb3AgPSAhIWNmZy5sb29wO1xuICAgICAgdGhpcy5fdG8gPSByZXNvbHZlKFtjZmcudG8sIHRvLCBjdXJyZW50VmFsdWUsIGNmZy5mcm9tXSk7XG4gICAgICB0aGlzLl9mcm9tID0gcmVzb2x2ZShbY2ZnLmZyb20sIGN1cnJlbnRWYWx1ZSwgdG9dKTtcbiAgICB9XG4gIH1cblxuICBjYW5jZWwoKSB7XG4gICAgaWYgKHRoaXMuX2FjdGl2ZSkge1xuICAgICAgLy8gdXBkYXRlIGN1cnJlbnQgZXZhbHVhdGVkIHZhbHVlLCBmb3Igc21vb3RoZXIgYW5pbWF0aW9uc1xuICAgICAgdGhpcy50aWNrKERhdGUubm93KCkpO1xuICAgICAgdGhpcy5fYWN0aXZlID0gZmFsc2U7XG4gICAgICB0aGlzLl9ub3RpZnkoZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIHRpY2soZGF0ZSkge1xuICAgIGNvbnN0IGVsYXBzZWQgPSBkYXRlIC0gdGhpcy5fc3RhcnQ7XG4gICAgY29uc3QgZHVyYXRpb24gPSB0aGlzLl9kdXJhdGlvbjtcbiAgICBjb25zdCBwcm9wID0gdGhpcy5fcHJvcDtcbiAgICBjb25zdCBmcm9tID0gdGhpcy5fZnJvbTtcbiAgICBjb25zdCBsb29wID0gdGhpcy5fbG9vcDtcbiAgICBjb25zdCB0byA9IHRoaXMuX3RvO1xuICAgIGxldCBmYWN0b3I7XG5cbiAgICB0aGlzLl9hY3RpdmUgPSBmcm9tICE9PSB0byAmJiAobG9vcCB8fCAoZWxhcHNlZCA8IGR1cmF0aW9uKSk7XG5cbiAgICBpZiAoIXRoaXMuX2FjdGl2ZSkge1xuICAgICAgdGhpcy5fdGFyZ2V0W3Byb3BdID0gdG87XG4gICAgICB0aGlzLl9ub3RpZnkodHJ1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGVsYXBzZWQgPCAwKSB7XG4gICAgICB0aGlzLl90YXJnZXRbcHJvcF0gPSBmcm9tO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZhY3RvciA9IChlbGFwc2VkIC8gZHVyYXRpb24pICUgMjtcbiAgICBmYWN0b3IgPSBsb29wICYmIGZhY3RvciA+IDEgPyAyIC0gZmFjdG9yIDogZmFjdG9yO1xuICAgIGZhY3RvciA9IHRoaXMuX2Vhc2luZyhNYXRoLm1pbigxLCBNYXRoLm1heCgwLCBmYWN0b3IpKSk7XG5cbiAgICB0aGlzLl90YXJnZXRbcHJvcF0gPSB0aGlzLl9mbihmcm9tLCB0bywgZmFjdG9yKTtcbiAgfVxuXG4gIHdhaXQoKSB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSB0aGlzLl9wcm9taXNlcyB8fCAodGhpcy5fcHJvbWlzZXMgPSBbXSk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXMsIHJlaikgPT4ge1xuICAgICAgcHJvbWlzZXMucHVzaCh7cmVzLCByZWp9KTtcbiAgICB9KTtcbiAgfVxuXG4gIF9ub3RpZnkocmVzb2x2ZWQpIHtcbiAgICBjb25zdCBtZXRob2QgPSByZXNvbHZlZCA/ICdyZXMnIDogJ3Jlaic7XG4gICAgY29uc3QgcHJvbWlzZXMgPSB0aGlzLl9wcm9taXNlcyB8fCBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb21pc2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBwcm9taXNlc1tpXVttZXRob2RdKCk7XG4gICAgfVxuICB9XG59XG4iLCAiaW1wb3J0IGFuaW1hdG9yIGZyb20gJy4vY29yZS5hbmltYXRvci5qcyc7XG5pbXBvcnQgQW5pbWF0aW9uIGZyb20gJy4vY29yZS5hbmltYXRpb24uanMnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4vY29yZS5kZWZhdWx0cy5qcyc7XG5pbXBvcnQge2lzQXJyYXksIGlzT2JqZWN0fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFuaW1hdGlvbnMge1xuICBjb25zdHJ1Y3RvcihjaGFydCwgY29uZmlnKSB7XG4gICAgdGhpcy5fY2hhcnQgPSBjaGFydDtcbiAgICB0aGlzLl9wcm9wZXJ0aWVzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuY29uZmlndXJlKGNvbmZpZyk7XG4gIH1cblxuICBjb25maWd1cmUoY29uZmlnKSB7XG4gICAgaWYgKCFpc09iamVjdChjb25maWcpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYW5pbWF0aW9uT3B0aW9ucyA9IE9iamVjdC5rZXlzKGRlZmF1bHRzLmFuaW1hdGlvbik7XG4gICAgY29uc3QgYW5pbWF0ZWRQcm9wcyA9IHRoaXMuX3Byb3BlcnRpZXM7XG5cbiAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhjb25maWcpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnN0IGNmZyA9IGNvbmZpZ1trZXldO1xuICAgICAgaWYgKCFpc09iamVjdChjZmcpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlc29sdmVkID0ge307XG4gICAgICBmb3IgKGNvbnN0IG9wdGlvbiBvZiBhbmltYXRpb25PcHRpb25zKSB7XG4gICAgICAgIHJlc29sdmVkW29wdGlvbl0gPSBjZmdbb3B0aW9uXTtcbiAgICAgIH1cblxuICAgICAgKGlzQXJyYXkoY2ZnLnByb3BlcnRpZXMpICYmIGNmZy5wcm9wZXJ0aWVzIHx8IFtrZXldKS5mb3JFYWNoKChwcm9wKSA9PiB7XG4gICAgICAgIGlmIChwcm9wID09PSBrZXkgfHwgIWFuaW1hdGVkUHJvcHMuaGFzKHByb3ApKSB7XG4gICAgICAgICAgYW5pbWF0ZWRQcm9wcy5zZXQocHJvcCwgcmVzb2x2ZWQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBVdGlsaXR5IHRvIGhhbmRsZSBhbmltYXRpb24gb2YgYG9wdGlvbnNgLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2FuaW1hdGVPcHRpb25zKHRhcmdldCwgdmFsdWVzKSB7XG4gICAgY29uc3QgbmV3T3B0aW9ucyA9IHZhbHVlcy5vcHRpb25zO1xuICAgIGNvbnN0IG9wdGlvbnMgPSByZXNvbHZlVGFyZ2V0T3B0aW9ucyh0YXJnZXQsIG5ld09wdGlvbnMpO1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGFuaW1hdGlvbnMgPSB0aGlzLl9jcmVhdGVBbmltYXRpb25zKG9wdGlvbnMsIG5ld09wdGlvbnMpO1xuICAgIGlmIChuZXdPcHRpb25zLiRzaGFyZWQpIHtcbiAgICAgIC8vIEdvaW5nIHRvIHNoYXJlZCBvcHRpb25zOlxuICAgICAgLy8gQWZ0ZXIgYWxsIGFuaW1hdGlvbnMgYXJlIGRvbmUsIGFzc2lnbiB0aGUgc2hhcmVkIG9wdGlvbnMgb2JqZWN0IHRvIHRoZSBlbGVtZW50XG4gICAgICAvLyBTbyBhbnkgbmV3IHVwZGF0ZXMgdG8gdGhlIHNoYXJlZCBvcHRpb25zIGFyZSBvYnNlcnZlZFxuICAgICAgYXdhaXRBbGwodGFyZ2V0Lm9wdGlvbnMuJGFuaW1hdGlvbnMsIG5ld09wdGlvbnMpLnRoZW4oKCkgPT4ge1xuICAgICAgICB0YXJnZXQub3B0aW9ucyA9IG5ld09wdGlvbnM7XG4gICAgICB9LCAoKSA9PiB7XG4gICAgICAgIC8vIHJlamVjdGVkLCBub29wXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYW5pbWF0aW9ucztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2NyZWF0ZUFuaW1hdGlvbnModGFyZ2V0LCB2YWx1ZXMpIHtcbiAgICBjb25zdCBhbmltYXRlZFByb3BzID0gdGhpcy5fcHJvcGVydGllcztcbiAgICBjb25zdCBhbmltYXRpb25zID0gW107XG4gICAgY29uc3QgcnVubmluZyA9IHRhcmdldC4kYW5pbWF0aW9ucyB8fCAodGFyZ2V0LiRhbmltYXRpb25zID0ge30pO1xuICAgIGNvbnN0IHByb3BzID0gT2JqZWN0LmtleXModmFsdWVzKTtcbiAgICBjb25zdCBkYXRlID0gRGF0ZS5ub3coKTtcbiAgICBsZXQgaTtcblxuICAgIGZvciAoaSA9IHByb3BzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBjb25zdCBwcm9wID0gcHJvcHNbaV07XG4gICAgICBpZiAocHJvcC5jaGFyQXQoMCkgPT09ICckJykge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb3AgPT09ICdvcHRpb25zJykge1xuICAgICAgICBhbmltYXRpb25zLnB1c2goLi4udGhpcy5fYW5pbWF0ZU9wdGlvbnModGFyZ2V0LCB2YWx1ZXMpKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCB2YWx1ZSA9IHZhbHVlc1twcm9wXTtcbiAgICAgIGxldCBhbmltYXRpb24gPSBydW5uaW5nW3Byb3BdO1xuICAgICAgY29uc3QgY2ZnID0gYW5pbWF0ZWRQcm9wcy5nZXQocHJvcCk7XG5cbiAgICAgIGlmIChhbmltYXRpb24pIHtcbiAgICAgICAgaWYgKGNmZyAmJiBhbmltYXRpb24uYWN0aXZlKCkpIHtcbiAgICAgICAgICAvLyBUaGVyZSBpcyBhbiBleGlzdGluZyBhY3RpdmUgYW5pbWF0aW9uLCBsZXQncyB1cGRhdGUgdGhhdFxuICAgICAgICAgIGFuaW1hdGlvbi51cGRhdGUoY2ZnLCB2YWx1ZSwgZGF0ZSk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYW5pbWF0aW9uLmNhbmNlbCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWNmZyB8fCAhY2ZnLmR1cmF0aW9uKSB7XG4gICAgICAgIC8vIG5vdCBhbmltYXRlZCwgc2V0IGRpcmVjdGx5IHRvIG5ldyB2YWx1ZVxuICAgICAgICB0YXJnZXRbcHJvcF0gPSB2YWx1ZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHJ1bm5pbmdbcHJvcF0gPSBhbmltYXRpb24gPSBuZXcgQW5pbWF0aW9uKGNmZywgdGFyZ2V0LCBwcm9wLCB2YWx1ZSk7XG4gICAgICBhbmltYXRpb25zLnB1c2goYW5pbWF0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIGFuaW1hdGlvbnM7XG4gIH1cblxuXG4gIC8qKlxuXHQgKiBVcGRhdGUgYHRhcmdldGAgcHJvcGVydGllcyB0byBuZXcgdmFsdWVzLCB1c2luZyBjb25maWd1cmVkIGFuaW1hdGlvbnNcblx0ICogQHBhcmFtIHtvYmplY3R9IHRhcmdldCAtIG9iamVjdCB0byB1cGRhdGVcblx0ICogQHBhcmFtIHtvYmplY3R9IHZhbHVlcyAtIG5ldyB0YXJnZXQgcHJvcGVydGllc1xuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbnx1bmRlZmluZWR9IC0gYHRydWVgIGlmIGFuaW1hdGlvbnMgd2VyZSBzdGFydGVkXG5cdCAqKi9cbiAgdXBkYXRlKHRhcmdldCwgdmFsdWVzKSB7XG4gICAgaWYgKHRoaXMuX3Byb3BlcnRpZXMuc2l6ZSA9PT0gMCkge1xuICAgICAgLy8gTm90aGluZyBpcyBhbmltYXRlZCwganVzdCBhcHBseSB0aGUgbmV3IHZhbHVlcy5cbiAgICAgIE9iamVjdC5hc3NpZ24odGFyZ2V0LCB2YWx1ZXMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGFuaW1hdGlvbnMgPSB0aGlzLl9jcmVhdGVBbmltYXRpb25zKHRhcmdldCwgdmFsdWVzKTtcblxuICAgIGlmIChhbmltYXRpb25zLmxlbmd0aCkge1xuICAgICAgYW5pbWF0b3IuYWRkKHRoaXMuX2NoYXJ0LCBhbmltYXRpb25zKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhd2FpdEFsbChhbmltYXRpb25zLCBwcm9wZXJ0aWVzKSB7XG4gIGNvbnN0IHJ1bm5pbmcgPSBbXTtcbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBhbmltID0gYW5pbWF0aW9uc1trZXlzW2ldXTtcbiAgICBpZiAoYW5pbSAmJiBhbmltLmFjdGl2ZSgpKSB7XG4gICAgICBydW5uaW5nLnB1c2goYW5pbS53YWl0KCkpO1xuICAgIH1cbiAgfVxuICAvLyBAdHMtaWdub3JlXG4gIHJldHVybiBQcm9taXNlLmFsbChydW5uaW5nKTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVRhcmdldE9wdGlvbnModGFyZ2V0LCBuZXdPcHRpb25zKSB7XG4gIGlmICghbmV3T3B0aW9ucykge1xuICAgIHJldHVybjtcbiAgfVxuICBsZXQgb3B0aW9ucyA9IHRhcmdldC5vcHRpb25zO1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICB0YXJnZXQub3B0aW9ucyA9IG5ld09wdGlvbnM7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChvcHRpb25zLiRzaGFyZWQpIHtcbiAgICAvLyBHb2luZyBmcm9tIHNoYXJlZCBvcHRpb25zIHRvIGRpc3RpbmN0IG9uZTpcbiAgICAvLyBDcmVhdGUgbmV3IG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIG9sZCBzaGFyZWQgdmFsdWVzIGFuZCBzdGFydCB1cGRhdGluZyB0aGF0LlxuICAgIHRhcmdldC5vcHRpb25zID0gb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMsIHskc2hhcmVkOiBmYWxzZSwgJGFuaW1hdGlvbnM6IHt9fSk7XG4gIH1cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG4iLCAiaW1wb3J0IEFuaW1hdGlvbnMgZnJvbSAnLi9jb3JlLmFuaW1hdGlvbnMuanMnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4vY29yZS5kZWZhdWx0cy5qcyc7XG5pbXBvcnQge2lzQXJyYXksIGlzRmluaXRlLCBpc09iamVjdCwgdmFsdWVPckRlZmF1bHQsIHJlc29sdmVPYmplY3RLZXksIGRlZmluZWR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7bGlzdGVuQXJyYXlFdmVudHMsIHVubGlzdGVuQXJyYXlFdmVudHN9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb2xsZWN0aW9uLmpzJztcbmltcG9ydCB7Y3JlYXRlQ29udGV4dCwgc2lnbn0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4vY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IENoYXJ0XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi9jb3JlLnNjYWxlLmpzJykuZGVmYXVsdCB9IFNjYWxlXG4gKi9cblxuZnVuY3Rpb24gc2NhbGVDbGlwKHNjYWxlLCBhbGxvd2VkT3ZlcmZsb3cpIHtcbiAgY29uc3Qgb3B0cyA9IHNjYWxlICYmIHNjYWxlLm9wdGlvbnMgfHwge307XG4gIGNvbnN0IHJldmVyc2UgPSBvcHRzLnJldmVyc2U7XG4gIGNvbnN0IG1pbiA9IG9wdHMubWluID09PSB1bmRlZmluZWQgPyBhbGxvd2VkT3ZlcmZsb3cgOiAwO1xuICBjb25zdCBtYXggPSBvcHRzLm1heCA9PT0gdW5kZWZpbmVkID8gYWxsb3dlZE92ZXJmbG93IDogMDtcbiAgcmV0dXJuIHtcbiAgICBzdGFydDogcmV2ZXJzZSA/IG1heCA6IG1pbixcbiAgICBlbmQ6IHJldmVyc2UgPyBtaW4gOiBtYXhcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdENsaXAoeFNjYWxlLCB5U2NhbGUsIGFsbG93ZWRPdmVyZmxvdykge1xuICBpZiAoYWxsb3dlZE92ZXJmbG93ID09PSBmYWxzZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCB4ID0gc2NhbGVDbGlwKHhTY2FsZSwgYWxsb3dlZE92ZXJmbG93KTtcbiAgY29uc3QgeSA9IHNjYWxlQ2xpcCh5U2NhbGUsIGFsbG93ZWRPdmVyZmxvdyk7XG5cbiAgcmV0dXJuIHtcbiAgICB0b3A6IHkuZW5kLFxuICAgIHJpZ2h0OiB4LmVuZCxcbiAgICBib3R0b206IHkuc3RhcnQsXG4gICAgbGVmdDogeC5zdGFydFxuICB9O1xufVxuXG5mdW5jdGlvbiB0b0NsaXAodmFsdWUpIHtcbiAgbGV0IHQsIHIsIGIsIGw7XG5cbiAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHQgPSB2YWx1ZS50b3A7XG4gICAgciA9IHZhbHVlLnJpZ2h0O1xuICAgIGIgPSB2YWx1ZS5ib3R0b207XG4gICAgbCA9IHZhbHVlLmxlZnQ7XG4gIH0gZWxzZSB7XG4gICAgdCA9IHIgPSBiID0gbCA9IHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0b3A6IHQsXG4gICAgcmlnaHQ6IHIsXG4gICAgYm90dG9tOiBiLFxuICAgIGxlZnQ6IGwsXG4gICAgZGlzYWJsZWQ6IHZhbHVlID09PSBmYWxzZVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRTb3J0ZWREYXRhc2V0SW5kaWNlcyhjaGFydCwgZmlsdGVyVmlzaWJsZSkge1xuICBjb25zdCBrZXlzID0gW107XG4gIGNvbnN0IG1ldGFzZXRzID0gY2hhcnQuX2dldFNvcnRlZERhdGFzZXRNZXRhcyhmaWx0ZXJWaXNpYmxlKTtcbiAgbGV0IGksIGlsZW47XG5cbiAgZm9yIChpID0gMCwgaWxlbiA9IG1ldGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIGtleXMucHVzaChtZXRhc2V0c1tpXS5pbmRleCk7XG4gIH1cbiAgcmV0dXJuIGtleXM7XG59XG5cbmZ1bmN0aW9uIGFwcGx5U3RhY2soc3RhY2ssIHZhbHVlLCBkc0luZGV4LCBvcHRpb25zID0ge30pIHtcbiAgY29uc3Qga2V5cyA9IHN0YWNrLmtleXM7XG4gIGNvbnN0IHNpbmdsZU1vZGUgPSBvcHRpb25zLm1vZGUgPT09ICdzaW5nbGUnO1xuICBsZXQgaSwgaWxlbiwgZGF0YXNldEluZGV4LCBvdGhlclZhbHVlO1xuXG4gIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAoaSA9IDAsIGlsZW4gPSBrZXlzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIGRhdGFzZXRJbmRleCA9ICtrZXlzW2ldO1xuICAgIGlmIChkYXRhc2V0SW5kZXggPT09IGRzSW5kZXgpIHtcbiAgICAgIGlmIChvcHRpb25zLmFsbCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBvdGhlclZhbHVlID0gc3RhY2sudmFsdWVzW2RhdGFzZXRJbmRleF07XG4gICAgaWYgKGlzRmluaXRlKG90aGVyVmFsdWUpICYmIChzaW5nbGVNb2RlIHx8ICh2YWx1ZSA9PT0gMCB8fCBzaWduKHZhbHVlKSA9PT0gc2lnbihvdGhlclZhbHVlKSkpKSB7XG4gICAgICB2YWx1ZSArPSBvdGhlclZhbHVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRPYmplY3REYXRhVG9BcnJheShkYXRhKSB7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhkYXRhKTtcbiAgY29uc3QgYWRhdGEgPSBuZXcgQXJyYXkoa2V5cy5sZW5ndGgpO1xuICBsZXQgaSwgaWxlbiwga2V5O1xuICBmb3IgKGkgPSAwLCBpbGVuID0ga2V5cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBrZXkgPSBrZXlzW2ldO1xuICAgIGFkYXRhW2ldID0ge1xuICAgICAgeDoga2V5LFxuICAgICAgeTogZGF0YVtrZXldXG4gICAgfTtcbiAgfVxuICByZXR1cm4gYWRhdGE7XG59XG5cbmZ1bmN0aW9uIGlzU3RhY2tlZChzY2FsZSwgbWV0YSkge1xuICBjb25zdCBzdGFja2VkID0gc2NhbGUgJiYgc2NhbGUub3B0aW9ucy5zdGFja2VkO1xuICByZXR1cm4gc3RhY2tlZCB8fCAoc3RhY2tlZCA9PT0gdW5kZWZpbmVkICYmIG1ldGEuc3RhY2sgIT09IHVuZGVmaW5lZCk7XG59XG5cbmZ1bmN0aW9uIGdldFN0YWNrS2V5KGluZGV4U2NhbGUsIHZhbHVlU2NhbGUsIG1ldGEpIHtcbiAgcmV0dXJuIGAke2luZGV4U2NhbGUuaWR9LiR7dmFsdWVTY2FsZS5pZH0uJHttZXRhLnN0YWNrIHx8IG1ldGEudHlwZX1gO1xufVxuXG5mdW5jdGlvbiBnZXRVc2VyQm91bmRzKHNjYWxlKSB7XG4gIGNvbnN0IHttaW4sIG1heCwgbWluRGVmaW5lZCwgbWF4RGVmaW5lZH0gPSBzY2FsZS5nZXRVc2VyQm91bmRzKCk7XG4gIHJldHVybiB7XG4gICAgbWluOiBtaW5EZWZpbmVkID8gbWluIDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLFxuICAgIG1heDogbWF4RGVmaW5lZCA/IG1heCA6IE51bWJlci5QT1NJVElWRV9JTkZJTklUWVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRPckNyZWF0ZVN0YWNrKHN0YWNrcywgc3RhY2tLZXksIGluZGV4VmFsdWUpIHtcbiAgY29uc3Qgc3ViU3RhY2sgPSBzdGFja3Nbc3RhY2tLZXldIHx8IChzdGFja3Nbc3RhY2tLZXldID0ge30pO1xuICByZXR1cm4gc3ViU3RhY2tbaW5kZXhWYWx1ZV0gfHwgKHN1YlN0YWNrW2luZGV4VmFsdWVdID0ge30pO1xufVxuXG5mdW5jdGlvbiBnZXRMYXN0SW5kZXhJblN0YWNrKHN0YWNrLCB2U2NhbGUsIHBvc2l0aXZlLCB0eXBlKSB7XG4gIGZvciAoY29uc3QgbWV0YSBvZiB2U2NhbGUuZ2V0TWF0Y2hpbmdWaXNpYmxlTWV0YXModHlwZSkucmV2ZXJzZSgpKSB7XG4gICAgY29uc3QgdmFsdWUgPSBzdGFja1ttZXRhLmluZGV4XTtcbiAgICBpZiAoKHBvc2l0aXZlICYmIHZhbHVlID4gMCkgfHwgKCFwb3NpdGl2ZSAmJiB2YWx1ZSA8IDApKSB7XG4gICAgICByZXR1cm4gbWV0YS5pbmRleDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlU3RhY2tzKGNvbnRyb2xsZXIsIHBhcnNlZCkge1xuICBjb25zdCB7Y2hhcnQsIF9jYWNoZWRNZXRhOiBtZXRhfSA9IGNvbnRyb2xsZXI7XG4gIGNvbnN0IHN0YWNrcyA9IGNoYXJ0Ll9zdGFja3MgfHwgKGNoYXJ0Ll9zdGFja3MgPSB7fSk7IC8vIG1hcCBzdHJ1Y3R1cmUgaXMge3N0YWNrS2V5OiB7ZGF0YXNldEluZGV4OiB2YWx1ZX19XG4gIGNvbnN0IHtpU2NhbGUsIHZTY2FsZSwgaW5kZXg6IGRhdGFzZXRJbmRleH0gPSBtZXRhO1xuICBjb25zdCBpQXhpcyA9IGlTY2FsZS5heGlzO1xuICBjb25zdCB2QXhpcyA9IHZTY2FsZS5heGlzO1xuICBjb25zdCBrZXkgPSBnZXRTdGFja0tleShpU2NhbGUsIHZTY2FsZSwgbWV0YSk7XG4gIGNvbnN0IGlsZW4gPSBwYXJzZWQubGVuZ3RoO1xuICBsZXQgc3RhY2s7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBjb25zdCBpdGVtID0gcGFyc2VkW2ldO1xuICAgIGNvbnN0IHtbaUF4aXNdOiBpbmRleCwgW3ZBeGlzXTogdmFsdWV9ID0gaXRlbTtcbiAgICBjb25zdCBpdGVtU3RhY2tzID0gaXRlbS5fc3RhY2tzIHx8IChpdGVtLl9zdGFja3MgPSB7fSk7XG4gICAgc3RhY2sgPSBpdGVtU3RhY2tzW3ZBeGlzXSA9IGdldE9yQ3JlYXRlU3RhY2soc3RhY2tzLCBrZXksIGluZGV4KTtcbiAgICBzdGFja1tkYXRhc2V0SW5kZXhdID0gdmFsdWU7XG5cbiAgICBzdGFjay5fdG9wID0gZ2V0TGFzdEluZGV4SW5TdGFjayhzdGFjaywgdlNjYWxlLCB0cnVlLCBtZXRhLnR5cGUpO1xuICAgIHN0YWNrLl9ib3R0b20gPSBnZXRMYXN0SW5kZXhJblN0YWNrKHN0YWNrLCB2U2NhbGUsIGZhbHNlLCBtZXRhLnR5cGUpO1xuXG4gICAgY29uc3QgdmlzdWFsVmFsdWVzID0gc3RhY2suX3Zpc3VhbFZhbHVlcyB8fCAoc3RhY2suX3Zpc3VhbFZhbHVlcyA9IHt9KTtcbiAgICB2aXN1YWxWYWx1ZXNbZGF0YXNldEluZGV4XSA9IHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldEZpcnN0U2NhbGVJZChjaGFydCwgYXhpcykge1xuICBjb25zdCBzY2FsZXMgPSBjaGFydC5zY2FsZXM7XG4gIHJldHVybiBPYmplY3Qua2V5cyhzY2FsZXMpLmZpbHRlcihrZXkgPT4gc2NhbGVzW2tleV0uYXhpcyA9PT0gYXhpcykuc2hpZnQoKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGF0YXNldENvbnRleHQocGFyZW50LCBpbmRleCkge1xuICByZXR1cm4gY3JlYXRlQ29udGV4dChwYXJlbnQsXG4gICAge1xuICAgICAgYWN0aXZlOiBmYWxzZSxcbiAgICAgIGRhdGFzZXQ6IHVuZGVmaW5lZCxcbiAgICAgIGRhdGFzZXRJbmRleDogaW5kZXgsXG4gICAgICBpbmRleCxcbiAgICAgIG1vZGU6ICdkZWZhdWx0JyxcbiAgICAgIHR5cGU6ICdkYXRhc2V0J1xuICAgIH1cbiAgKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGF0YUNvbnRleHQocGFyZW50LCBpbmRleCwgZWxlbWVudCkge1xuICByZXR1cm4gY3JlYXRlQ29udGV4dChwYXJlbnQsIHtcbiAgICBhY3RpdmU6IGZhbHNlLFxuICAgIGRhdGFJbmRleDogaW5kZXgsXG4gICAgcGFyc2VkOiB1bmRlZmluZWQsXG4gICAgcmF3OiB1bmRlZmluZWQsXG4gICAgZWxlbWVudCxcbiAgICBpbmRleCxcbiAgICBtb2RlOiAnZGVmYXVsdCcsXG4gICAgdHlwZTogJ2RhdGEnXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBjbGVhclN0YWNrcyhtZXRhLCBpdGVtcykge1xuICAvLyBOb3QgdXNpbmcgbWV0YS5pbmRleCBoZXJlLCBiZWNhdXNlIGl0IG1pZ2h0IGJlIGFscmVhZHkgdXBkYXRlZCBpZiB0aGUgZGF0YXNldCBjaGFuZ2VkIGxvY2F0aW9uXG4gIGNvbnN0IGRhdGFzZXRJbmRleCA9IG1ldGEuY29udHJvbGxlci5pbmRleDtcbiAgY29uc3QgYXhpcyA9IG1ldGEudlNjYWxlICYmIG1ldGEudlNjYWxlLmF4aXM7XG4gIGlmICghYXhpcykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGl0ZW1zID0gaXRlbXMgfHwgbWV0YS5fcGFyc2VkO1xuICBmb3IgKGNvbnN0IHBhcnNlZCBvZiBpdGVtcykge1xuICAgIGNvbnN0IHN0YWNrcyA9IHBhcnNlZC5fc3RhY2tzO1xuICAgIGlmICghc3RhY2tzIHx8IHN0YWNrc1theGlzXSA9PT0gdW5kZWZpbmVkIHx8IHN0YWNrc1theGlzXVtkYXRhc2V0SW5kZXhdID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVsZXRlIHN0YWNrc1theGlzXVtkYXRhc2V0SW5kZXhdO1xuICAgIGlmIChzdGFja3NbYXhpc10uX3Zpc3VhbFZhbHVlcyAhPT0gdW5kZWZpbmVkICYmIHN0YWNrc1theGlzXS5fdmlzdWFsVmFsdWVzW2RhdGFzZXRJbmRleF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgZGVsZXRlIHN0YWNrc1theGlzXS5fdmlzdWFsVmFsdWVzW2RhdGFzZXRJbmRleF07XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IGlzRGlyZWN0VXBkYXRlTW9kZSA9IChtb2RlKSA9PiBtb2RlID09PSAncmVzZXQnIHx8IG1vZGUgPT09ICdub25lJztcbmNvbnN0IGNsb25lSWZOb3RTaGFyZWQgPSAoY2FjaGVkLCBzaGFyZWQpID0+IHNoYXJlZCA/IGNhY2hlZCA6IE9iamVjdC5hc3NpZ24oe30sIGNhY2hlZCk7XG5jb25zdCBjcmVhdGVTdGFjayA9IChjYW5TdGFjaywgbWV0YSwgY2hhcnQpID0+IGNhblN0YWNrICYmICFtZXRhLmhpZGRlbiAmJiBtZXRhLl9zdGFja2VkXG4gICYmIHtrZXlzOiBnZXRTb3J0ZWREYXRhc2V0SW5kaWNlcyhjaGFydCwgdHJ1ZSksIHZhbHVlczogbnVsbH07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERhdGFzZXRDb250cm9sbGVyIHtcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHt9O1xuXG4gIC8qKlxuICAgKiBFbGVtZW50IHR5cGUgdXNlZCB0byBnZW5lcmF0ZSBhIG1ldGEgZGF0YXNldCAoZS5nLiBDaGFydC5lbGVtZW50LkxpbmVFbGVtZW50KS5cbiAgICovXG4gIHN0YXRpYyBkYXRhc2V0RWxlbWVudFR5cGUgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBFbGVtZW50IHR5cGUgdXNlZCB0byBnZW5lcmF0ZSBhIG1ldGEgZGF0YSAoZS5nLiBDaGFydC5lbGVtZW50LlBvaW50RWxlbWVudCkuXG4gICAqL1xuICBzdGF0aWMgZGF0YUVsZW1lbnRUeXBlID0gbnVsbDtcblxuICAvKipcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnRcblx0ICogQHBhcmFtIHtudW1iZXJ9IGRhdGFzZXRJbmRleFxuXHQgKi9cbiAgY29uc3RydWN0b3IoY2hhcnQsIGRhdGFzZXRJbmRleCkge1xuICAgIHRoaXMuY2hhcnQgPSBjaGFydDtcbiAgICB0aGlzLl9jdHggPSBjaGFydC5jdHg7XG4gICAgdGhpcy5pbmRleCA9IGRhdGFzZXRJbmRleDtcbiAgICB0aGlzLl9jYWNoZWREYXRhT3B0cyA9IHt9O1xuICAgIHRoaXMuX2NhY2hlZE1ldGEgPSB0aGlzLmdldE1ldGEoKTtcbiAgICB0aGlzLl90eXBlID0gdGhpcy5fY2FjaGVkTWV0YS50eXBlO1xuICAgIHRoaXMub3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge2Jvb2xlYW4gfCBvYmplY3R9ICovXG4gICAgdGhpcy5fcGFyc2luZyA9IGZhbHNlO1xuICAgIHRoaXMuX2RhdGEgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fb2JqZWN0RGF0YSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9zaGFyZWRPcHRpb25zID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2RyYXdTdGFydCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9kcmF3Q291bnQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5lbmFibGVPcHRpb25TaGFyaW5nID0gZmFsc2U7XG4gICAgdGhpcy5zdXBwb3J0c0RlY2ltYXRpb24gPSBmYWxzZTtcbiAgICB0aGlzLiRjb250ZXh0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3N5bmNMaXN0ID0gW107XG4gICAgdGhpcy5kYXRhc2V0RWxlbWVudFR5cGUgPSBuZXcudGFyZ2V0LmRhdGFzZXRFbGVtZW50VHlwZTtcbiAgICB0aGlzLmRhdGFFbGVtZW50VHlwZSA9IG5ldy50YXJnZXQuZGF0YUVsZW1lbnRUeXBlO1xuXG4gICAgdGhpcy5pbml0aWFsaXplKCk7XG4gIH1cblxuICBpbml0aWFsaXplKCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIHRoaXMuY29uZmlndXJlKCk7XG4gICAgdGhpcy5saW5rU2NhbGVzKCk7XG4gICAgbWV0YS5fc3RhY2tlZCA9IGlzU3RhY2tlZChtZXRhLnZTY2FsZSwgbWV0YSk7XG4gICAgdGhpcy5hZGRFbGVtZW50cygpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5maWxsICYmICF0aGlzLmNoYXJ0LmlzUGx1Z2luRW5hYmxlZCgnZmlsbGVyJykpIHtcbiAgICAgIGNvbnNvbGUud2FybihcIlRyaWVkIHRvIHVzZSB0aGUgJ2ZpbGwnIG9wdGlvbiB3aXRob3V0IHRoZSAnRmlsbGVyJyBwbHVnaW4gZW5hYmxlZC4gUGxlYXNlIGltcG9ydCBhbmQgcmVnaXN0ZXIgdGhlICdGaWxsZXInIHBsdWdpbiBhbmQgbWFrZSBzdXJlIGl0IGlzIG5vdCBkaXNhYmxlZCBpbiB0aGUgb3B0aW9uc1wiKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVJbmRleChkYXRhc2V0SW5kZXgpIHtcbiAgICBpZiAodGhpcy5pbmRleCAhPT0gZGF0YXNldEluZGV4KSB7XG4gICAgICBjbGVhclN0YWNrcyh0aGlzLl9jYWNoZWRNZXRhKTtcbiAgICB9XG4gICAgdGhpcy5pbmRleCA9IGRhdGFzZXRJbmRleDtcbiAgfVxuXG4gIGxpbmtTY2FsZXMoKSB7XG4gICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLmdldERhdGFzZXQoKTtcblxuICAgIGNvbnN0IGNob29zZUlkID0gKGF4aXMsIHgsIHksIHIpID0+IGF4aXMgPT09ICd4JyA/IHggOiBheGlzID09PSAncicgPyByIDogeTtcblxuICAgIGNvbnN0IHhpZCA9IG1ldGEueEF4aXNJRCA9IHZhbHVlT3JEZWZhdWx0KGRhdGFzZXQueEF4aXNJRCwgZ2V0Rmlyc3RTY2FsZUlkKGNoYXJ0LCAneCcpKTtcbiAgICBjb25zdCB5aWQgPSBtZXRhLnlBeGlzSUQgPSB2YWx1ZU9yRGVmYXVsdChkYXRhc2V0LnlBeGlzSUQsIGdldEZpcnN0U2NhbGVJZChjaGFydCwgJ3knKSk7XG4gICAgY29uc3QgcmlkID0gbWV0YS5yQXhpc0lEID0gdmFsdWVPckRlZmF1bHQoZGF0YXNldC5yQXhpc0lELCBnZXRGaXJzdFNjYWxlSWQoY2hhcnQsICdyJykpO1xuICAgIGNvbnN0IGluZGV4QXhpcyA9IG1ldGEuaW5kZXhBeGlzO1xuICAgIGNvbnN0IGlpZCA9IG1ldGEuaUF4aXNJRCA9IGNob29zZUlkKGluZGV4QXhpcywgeGlkLCB5aWQsIHJpZCk7XG4gICAgY29uc3QgdmlkID0gbWV0YS52QXhpc0lEID0gY2hvb3NlSWQoaW5kZXhBeGlzLCB5aWQsIHhpZCwgcmlkKTtcbiAgICBtZXRhLnhTY2FsZSA9IHRoaXMuZ2V0U2NhbGVGb3JJZCh4aWQpO1xuICAgIG1ldGEueVNjYWxlID0gdGhpcy5nZXRTY2FsZUZvcklkKHlpZCk7XG4gICAgbWV0YS5yU2NhbGUgPSB0aGlzLmdldFNjYWxlRm9ySWQocmlkKTtcbiAgICBtZXRhLmlTY2FsZSA9IHRoaXMuZ2V0U2NhbGVGb3JJZChpaWQpO1xuICAgIG1ldGEudlNjYWxlID0gdGhpcy5nZXRTY2FsZUZvcklkKHZpZCk7XG4gIH1cblxuICBnZXREYXRhc2V0KCkge1xuICAgIHJldHVybiB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbdGhpcy5pbmRleF07XG4gIH1cblxuICBnZXRNZXRhKCkge1xuICAgIHJldHVybiB0aGlzLmNoYXJ0LmdldERhdGFzZXRNZXRhKHRoaXMuaW5kZXgpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzY2FsZUlEXG5cdCAqIEByZXR1cm4ge1NjYWxlfVxuXHQgKi9cbiAgZ2V0U2NhbGVGb3JJZChzY2FsZUlEKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hhcnQuc2NhbGVzW3NjYWxlSURdO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0T3RoZXJTY2FsZShzY2FsZSkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIHJldHVybiBzY2FsZSA9PT0gbWV0YS5pU2NhbGVcbiAgICAgID8gbWV0YS52U2NhbGVcbiAgICAgIDogbWV0YS5pU2NhbGU7XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLl91cGRhdGUoJ3Jlc2V0Jyk7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9kZXN0cm95KCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGlmICh0aGlzLl9kYXRhKSB7XG4gICAgICB1bmxpc3RlbkFycmF5RXZlbnRzKHRoaXMuX2RhdGEsIHRoaXMpO1xuICAgIH1cbiAgICBpZiAobWV0YS5fc3RhY2tlZCkge1xuICAgICAgY2xlYXJTdGFja3MobWV0YSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZGF0YUNoZWNrKCkge1xuICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLmdldERhdGFzZXQoKTtcbiAgICBjb25zdCBkYXRhID0gZGF0YXNldC5kYXRhIHx8IChkYXRhc2V0LmRhdGEgPSBbXSk7XG4gICAgY29uc3QgX2RhdGEgPSB0aGlzLl9kYXRhO1xuXG4gICAgLy8gSW4gb3JkZXIgdG8gY29ycmVjdGx5IGhhbmRsZSBkYXRhIGFkZGl0aW9uL2RlbGV0aW9uIGFuaW1hdGlvbiAoYW5kIHRodXMgc2ltdWxhdGVcbiAgICAvLyByZWFsLXRpbWUgY2hhcnRzKSwgd2UgbmVlZCB0byBtb25pdG9yIHRoZXNlIGRhdGEgbW9kaWZpY2F0aW9ucyBhbmQgc3luY2hyb25pemVcbiAgICAvLyB0aGUgaW50ZXJuYWwgbWV0YWRhdGEgYWNjb3JkaW5nbHkuXG5cbiAgICBpZiAoaXNPYmplY3QoZGF0YSkpIHtcbiAgICAgIHRoaXMuX2RhdGEgPSBjb252ZXJ0T2JqZWN0RGF0YVRvQXJyYXkoZGF0YSk7XG4gICAgfSBlbHNlIGlmIChfZGF0YSAhPT0gZGF0YSkge1xuICAgICAgaWYgKF9kYXRhKSB7XG4gICAgICAgIC8vIFRoaXMgY2FzZSBoYXBwZW5zIHdoZW4gdGhlIHVzZXIgcmVwbGFjZWQgdGhlIGRhdGEgYXJyYXkgaW5zdGFuY2UuXG4gICAgICAgIHVubGlzdGVuQXJyYXlFdmVudHMoX2RhdGEsIHRoaXMpO1xuICAgICAgICAvLyBEaXNjYXJkIG9sZCBwYXJzZWQgZGF0YSBhbmQgc3RhY2tzXG4gICAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgICAgICBjbGVhclN0YWNrcyhtZXRhKTtcbiAgICAgICAgbWV0YS5fcGFyc2VkID0gW107XG4gICAgICB9XG4gICAgICBpZiAoZGF0YSAmJiBPYmplY3QuaXNFeHRlbnNpYmxlKGRhdGEpKSB7XG4gICAgICAgIGxpc3RlbkFycmF5RXZlbnRzKGRhdGEsIHRoaXMpO1xuICAgICAgfVxuICAgICAgdGhpcy5fc3luY0xpc3QgPSBbXTtcbiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xuICAgIH1cbiAgfVxuXG4gIGFkZEVsZW1lbnRzKCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuXG4gICAgdGhpcy5fZGF0YUNoZWNrKCk7XG5cbiAgICBpZiAodGhpcy5kYXRhc2V0RWxlbWVudFR5cGUpIHtcbiAgICAgIG1ldGEuZGF0YXNldCA9IG5ldyB0aGlzLmRhdGFzZXRFbGVtZW50VHlwZSgpO1xuICAgIH1cbiAgfVxuXG4gIGJ1aWxkT3JVcGRhdGVFbGVtZW50cyhyZXNldE5ld0VsZW1lbnRzKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgZGF0YXNldCA9IHRoaXMuZ2V0RGF0YXNldCgpO1xuICAgIGxldCBzdGFja0NoYW5nZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuX2RhdGFDaGVjaygpO1xuXG4gICAgLy8gbWFrZSBzdXJlIGNhY2hlZCBfc3RhY2tlZCBzdGF0dXMgaXMgY3VycmVudFxuICAgIGNvbnN0IG9sZFN0YWNrZWQgPSBtZXRhLl9zdGFja2VkO1xuICAgIG1ldGEuX3N0YWNrZWQgPSBpc1N0YWNrZWQobWV0YS52U2NhbGUsIG1ldGEpO1xuXG4gICAgLy8gZGV0ZWN0IGNoYW5nZSBpbiBzdGFjayBvcHRpb25cbiAgICBpZiAobWV0YS5zdGFjayAhPT0gZGF0YXNldC5zdGFjaykge1xuICAgICAgc3RhY2tDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIC8vIHJlbW92ZSB2YWx1ZXMgZnJvbSBvbGQgc3RhY2tcbiAgICAgIGNsZWFyU3RhY2tzKG1ldGEpO1xuICAgICAgbWV0YS5zdGFjayA9IGRhdGFzZXQuc3RhY2s7XG4gICAgfVxuXG4gICAgLy8gUmUtc3luYyBtZXRhIGRhdGEgaW4gY2FzZSB0aGUgdXNlciByZXBsYWNlZCB0aGUgZGF0YSBhcnJheSBvciBpZiB3ZSBtaXNzZWRcbiAgICAvLyBhbnkgdXBkYXRlcyBhbmQgc28gbWFrZSBzdXJlIHRoYXQgd2UgaGFuZGxlIG51bWJlciBvZiBkYXRhcG9pbnRzIGNoYW5naW5nLlxuICAgIHRoaXMuX3Jlc3luY0VsZW1lbnRzKHJlc2V0TmV3RWxlbWVudHMpO1xuXG4gICAgLy8gaWYgc3RhY2sgY2hhbmdlZCwgdXBkYXRlIHN0YWNrIHZhbHVlcyBmb3IgdGhlIHdob2xlIGRhdGFzZXRcbiAgICBpZiAoc3RhY2tDaGFuZ2VkIHx8IG9sZFN0YWNrZWQgIT09IG1ldGEuX3N0YWNrZWQpIHtcbiAgICAgIHVwZGF0ZVN0YWNrcyh0aGlzLCBtZXRhLl9wYXJzZWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBNZXJnZXMgdXNlci1zdXBwbGllZCBhbmQgZGVmYXVsdCBkYXRhc2V0LWxldmVsIG9wdGlvbnNcblx0ICogQHByaXZhdGVcblx0ICovXG4gIGNvbmZpZ3VyZSgpIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNoYXJ0LmNvbmZpZztcbiAgICBjb25zdCBzY29wZUtleXMgPSBjb25maWcuZGF0YXNldFNjb3BlS2V5cyh0aGlzLl90eXBlKTtcbiAgICBjb25zdCBzY29wZXMgPSBjb25maWcuZ2V0T3B0aW9uU2NvcGVzKHRoaXMuZ2V0RGF0YXNldCgpLCBzY29wZUtleXMsIHRydWUpO1xuICAgIHRoaXMub3B0aW9ucyA9IGNvbmZpZy5jcmVhdGVSZXNvbHZlcihzY29wZXMsIHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICB0aGlzLl9wYXJzaW5nID0gdGhpcy5vcHRpb25zLnBhcnNpbmc7XG4gICAgdGhpcy5fY2FjaGVkRGF0YU9wdHMgPSB7fTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcblx0ICogQHBhcmFtIHtudW1iZXJ9IGNvdW50XG5cdCAqL1xuICBwYXJzZShzdGFydCwgY291bnQpIHtcbiAgICBjb25zdCB7X2NhY2hlZE1ldGE6IG1ldGEsIF9kYXRhOiBkYXRhfSA9IHRoaXM7XG4gICAgY29uc3Qge2lTY2FsZSwgX3N0YWNrZWR9ID0gbWV0YTtcbiAgICBjb25zdCBpQXhpcyA9IGlTY2FsZS5heGlzO1xuXG4gICAgbGV0IHNvcnRlZCA9IHN0YXJ0ID09PSAwICYmIGNvdW50ID09PSBkYXRhLmxlbmd0aCA/IHRydWUgOiBtZXRhLl9zb3J0ZWQ7XG4gICAgbGV0IHByZXYgPSBzdGFydCA+IDAgJiYgbWV0YS5fcGFyc2VkW3N0YXJ0IC0gMV07XG4gICAgbGV0IGksIGN1ciwgcGFyc2VkO1xuXG4gICAgaWYgKHRoaXMuX3BhcnNpbmcgPT09IGZhbHNlKSB7XG4gICAgICBtZXRhLl9wYXJzZWQgPSBkYXRhO1xuICAgICAgbWV0YS5fc29ydGVkID0gdHJ1ZTtcbiAgICAgIHBhcnNlZCA9IGRhdGE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc0FycmF5KGRhdGFbc3RhcnRdKSkge1xuICAgICAgICBwYXJzZWQgPSB0aGlzLnBhcnNlQXJyYXlEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KGRhdGFbc3RhcnRdKSkge1xuICAgICAgICBwYXJzZWQgPSB0aGlzLnBhcnNlT2JqZWN0RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFyc2VkID0gdGhpcy5wYXJzZVByaW1pdGl2ZURhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXNOb3RJbk9yZGVyQ29tcGFyZWRUb1ByZXYgPSAoKSA9PiBjdXJbaUF4aXNdID09PSBudWxsIHx8IChwcmV2ICYmIGN1cltpQXhpc10gPCBwcmV2W2lBeGlzXSk7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7ICsraSkge1xuICAgICAgICBtZXRhLl9wYXJzZWRbaSArIHN0YXJ0XSA9IGN1ciA9IHBhcnNlZFtpXTtcbiAgICAgICAgaWYgKHNvcnRlZCkge1xuICAgICAgICAgIGlmIChpc05vdEluT3JkZXJDb21wYXJlZFRvUHJldigpKSB7XG4gICAgICAgICAgICBzb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcHJldiA9IGN1cjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbWV0YS5fc29ydGVkID0gc29ydGVkO1xuICAgIH1cblxuICAgIGlmIChfc3RhY2tlZCkge1xuICAgICAgdXBkYXRlU3RhY2tzKHRoaXMsIHBhcnNlZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIFBhcnNlIGFycmF5IG9mIHByaW1pdGl2ZSB2YWx1ZXNcblx0ICogQHBhcmFtIHtvYmplY3R9IG1ldGEgLSBkYXRhc2V0IG1ldGFcblx0ICogQHBhcmFtIHthcnJheX0gZGF0YSAtIGRhdGEgYXJyYXkuIEV4YW1wbGUgWzEsMyw0XVxuXHQgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgLSBzdGFydCBpbmRleFxuXHQgKiBAcGFyYW0ge251bWJlcn0gY291bnQgLSBudW1iZXIgb2YgaXRlbXMgdG8gcGFyc2Vcblx0ICogQHJldHVybnMge29iamVjdH0gcGFyc2VkIGl0ZW0gLSBpdGVtIGNvbnRhaW5pbmcgaW5kZXggYW5kIGEgcGFyc2VkIHZhbHVlXG5cdCAqIGZvciBlYWNoIHNjYWxlIGlkLlxuXHQgKiBFeGFtcGxlOiB7eFNjYWxlMDogMCwgeVNjYWxlMDogMX1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgcGFyc2VQcmltaXRpdmVEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IHtpU2NhbGUsIHZTY2FsZX0gPSBtZXRhO1xuICAgIGNvbnN0IGlBeGlzID0gaVNjYWxlLmF4aXM7XG4gICAgY29uc3QgdkF4aXMgPSB2U2NhbGUuYXhpcztcbiAgICBjb25zdCBsYWJlbHMgPSBpU2NhbGUuZ2V0TGFiZWxzKCk7XG4gICAgY29uc3Qgc2luZ2xlU2NhbGUgPSBpU2NhbGUgPT09IHZTY2FsZTtcbiAgICBjb25zdCBwYXJzZWQgPSBuZXcgQXJyYXkoY291bnQpO1xuICAgIGxldCBpLCBpbGVuLCBpbmRleDtcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBjb3VudDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgaW5kZXggPSBpICsgc3RhcnQ7XG4gICAgICBwYXJzZWRbaV0gPSB7XG4gICAgICAgIFtpQXhpc106IHNpbmdsZVNjYWxlIHx8IGlTY2FsZS5wYXJzZShsYWJlbHNbaW5kZXhdLCBpbmRleCksXG4gICAgICAgIFt2QXhpc106IHZTY2FsZS5wYXJzZShkYXRhW2luZGV4XSwgaW5kZXgpXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VkO1xuICB9XG5cbiAgLyoqXG5cdCAqIFBhcnNlIGFycmF5IG9mIGFycmF5c1xuXHQgKiBAcGFyYW0ge29iamVjdH0gbWV0YSAtIGRhdGFzZXQgbWV0YVxuXHQgKiBAcGFyYW0ge2FycmF5fSBkYXRhIC0gZGF0YSBhcnJheS4gRXhhbXBsZSBbWzEsMl0sWzMsNF1dXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCAtIHN0YXJ0IGluZGV4XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBjb3VudCAtIG51bWJlciBvZiBpdGVtcyB0byBwYXJzZVxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fSBwYXJzZWQgaXRlbSAtIGl0ZW0gY29udGFpbmluZyBpbmRleCBhbmQgYSBwYXJzZWQgdmFsdWVcblx0ICogZm9yIGVhY2ggc2NhbGUgaWQuXG5cdCAqIEV4YW1wbGU6IHt4OiAwLCB5OiAxfVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBwYXJzZUFycmF5RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICBjb25zdCB7eFNjYWxlLCB5U2NhbGV9ID0gbWV0YTtcbiAgICBjb25zdCBwYXJzZWQgPSBuZXcgQXJyYXkoY291bnQpO1xuICAgIGxldCBpLCBpbGVuLCBpbmRleCwgaXRlbTtcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBjb3VudDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgaW5kZXggPSBpICsgc3RhcnQ7XG4gICAgICBpdGVtID0gZGF0YVtpbmRleF07XG4gICAgICBwYXJzZWRbaV0gPSB7XG4gICAgICAgIHg6IHhTY2FsZS5wYXJzZShpdGVtWzBdLCBpbmRleCksXG4gICAgICAgIHk6IHlTY2FsZS5wYXJzZShpdGVtWzFdLCBpbmRleClcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICAvKipcblx0ICogUGFyc2UgYXJyYXkgb2Ygb2JqZWN0c1xuXHQgKiBAcGFyYW0ge29iamVjdH0gbWV0YSAtIGRhdGFzZXQgbWV0YVxuXHQgKiBAcGFyYW0ge2FycmF5fSBkYXRhIC0gZGF0YSBhcnJheS4gRXhhbXBsZSBbe3g6MSwgeTo1fSwge3g6MiwgeToxMH1dXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCAtIHN0YXJ0IGluZGV4XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBjb3VudCAtIG51bWJlciBvZiBpdGVtcyB0byBwYXJzZVxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fSBwYXJzZWQgaXRlbSAtIGl0ZW0gY29udGFpbmluZyBpbmRleCBhbmQgYSBwYXJzZWQgdmFsdWVcblx0ICogZm9yIGVhY2ggc2NhbGUgaWQuIF9jdXN0b20gaXMgb3B0aW9uYWxcblx0ICogRXhhbXBsZToge3hTY2FsZTA6IDAsIHlTY2FsZTA6IDEsIF9jdXN0b206IHtyOiAxMCwgZm9vOiAnYmFyJ319XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHBhcnNlT2JqZWN0RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICBjb25zdCB7eFNjYWxlLCB5U2NhbGV9ID0gbWV0YTtcbiAgICBjb25zdCB7eEF4aXNLZXkgPSAneCcsIHlBeGlzS2V5ID0gJ3knfSA9IHRoaXMuX3BhcnNpbmc7XG4gICAgY29uc3QgcGFyc2VkID0gbmV3IEFycmF5KGNvdW50KTtcbiAgICBsZXQgaSwgaWxlbiwgaW5kZXgsIGl0ZW07XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gY291bnQ7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIGluZGV4ID0gaSArIHN0YXJ0O1xuICAgICAgaXRlbSA9IGRhdGFbaW5kZXhdO1xuICAgICAgcGFyc2VkW2ldID0ge1xuICAgICAgICB4OiB4U2NhbGUucGFyc2UocmVzb2x2ZU9iamVjdEtleShpdGVtLCB4QXhpc0tleSksIGluZGV4KSxcbiAgICAgICAgeTogeVNjYWxlLnBhcnNlKHJlc29sdmVPYmplY3RLZXkoaXRlbSwgeUF4aXNLZXkpLCBpbmRleClcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0UGFyc2VkKGluZGV4KSB7XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlZE1ldGEuX3BhcnNlZFtpbmRleF07XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0RGF0YUVsZW1lbnQoaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpcy5fY2FjaGVkTWV0YS5kYXRhW2luZGV4XTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBhcHBseVN0YWNrKHNjYWxlLCBwYXJzZWQsIG1vZGUpIHtcbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJzZWRbc2NhbGUuYXhpc107XG4gICAgY29uc3Qgc3RhY2sgPSB7XG4gICAgICBrZXlzOiBnZXRTb3J0ZWREYXRhc2V0SW5kaWNlcyhjaGFydCwgdHJ1ZSksXG4gICAgICB2YWx1ZXM6IHBhcnNlZC5fc3RhY2tzW3NjYWxlLmF4aXNdLl92aXN1YWxWYWx1ZXNcbiAgICB9O1xuICAgIHJldHVybiBhcHBseVN0YWNrKHN0YWNrLCB2YWx1ZSwgbWV0YS5pbmRleCwge21vZGV9KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICB1cGRhdGVSYW5nZUZyb21QYXJzZWQocmFuZ2UsIHNjYWxlLCBwYXJzZWQsIHN0YWNrKSB7XG4gICAgY29uc3QgcGFyc2VkVmFsdWUgPSBwYXJzZWRbc2NhbGUuYXhpc107XG4gICAgbGV0IHZhbHVlID0gcGFyc2VkVmFsdWUgPT09IG51bGwgPyBOYU4gOiBwYXJzZWRWYWx1ZTtcbiAgICBjb25zdCB2YWx1ZXMgPSBzdGFjayAmJiBwYXJzZWQuX3N0YWNrc1tzY2FsZS5heGlzXTtcbiAgICBpZiAoc3RhY2sgJiYgdmFsdWVzKSB7XG4gICAgICBzdGFjay52YWx1ZXMgPSB2YWx1ZXM7XG4gICAgICB2YWx1ZSA9IGFwcGx5U3RhY2soc3RhY2ssIHBhcnNlZFZhbHVlLCB0aGlzLl9jYWNoZWRNZXRhLmluZGV4KTtcbiAgICB9XG4gICAgcmFuZ2UubWluID0gTWF0aC5taW4ocmFuZ2UubWluLCB2YWx1ZSk7XG4gICAgcmFuZ2UubWF4ID0gTWF0aC5tYXgocmFuZ2UubWF4LCB2YWx1ZSk7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0TWluTWF4KHNjYWxlLCBjYW5TdGFjaykge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IF9wYXJzZWQgPSBtZXRhLl9wYXJzZWQ7XG4gICAgY29uc3Qgc29ydGVkID0gbWV0YS5fc29ydGVkICYmIHNjYWxlID09PSBtZXRhLmlTY2FsZTtcbiAgICBjb25zdCBpbGVuID0gX3BhcnNlZC5sZW5ndGg7XG4gICAgY29uc3Qgb3RoZXJTY2FsZSA9IHRoaXMuX2dldE90aGVyU2NhbGUoc2NhbGUpO1xuICAgIGNvbnN0IHN0YWNrID0gY3JlYXRlU3RhY2soY2FuU3RhY2ssIG1ldGEsIHRoaXMuY2hhcnQpO1xuICAgIGNvbnN0IHJhbmdlID0ge21pbjogTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLCBtYXg6IE51bWJlci5ORUdBVElWRV9JTkZJTklUWX07XG4gICAgY29uc3Qge21pbjogb3RoZXJNaW4sIG1heDogb3RoZXJNYXh9ID0gZ2V0VXNlckJvdW5kcyhvdGhlclNjYWxlKTtcbiAgICBsZXQgaSwgcGFyc2VkO1xuXG4gICAgZnVuY3Rpb24gX3NraXAoKSB7XG4gICAgICBwYXJzZWQgPSBfcGFyc2VkW2ldO1xuICAgICAgY29uc3Qgb3RoZXJWYWx1ZSA9IHBhcnNlZFtvdGhlclNjYWxlLmF4aXNdO1xuICAgICAgcmV0dXJuICFpc0Zpbml0ZShwYXJzZWRbc2NhbGUuYXhpc10pIHx8IG90aGVyTWluID4gb3RoZXJWYWx1ZSB8fCBvdGhlck1heCA8IG90aGVyVmFsdWU7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgaWYgKF9za2lwKCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB0aGlzLnVwZGF0ZVJhbmdlRnJvbVBhcnNlZChyYW5nZSwgc2NhbGUsIHBhcnNlZCwgc3RhY2spO1xuICAgICAgaWYgKHNvcnRlZCkge1xuICAgICAgICAvLyBpZiB0aGUgZGF0YSBpcyBzb3J0ZWQsIHdlIGRvbid0IG5lZWQgdG8gY2hlY2sgZnVydGhlciBmcm9tIHRoaXMgZW5kIG9mIGFycmF5XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc29ydGVkKSB7XG4gICAgICAvLyBpbiB0aGUgc29ydGVkIGNhc2UsIGZpbmQgZmlyc3Qgbm9uLXNraXBwZWQgdmFsdWUgZnJvbSBvdGhlciBlbmQgb2YgYXJyYXlcbiAgICAgIGZvciAoaSA9IGlsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICBpZiAoX3NraXAoKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlUmFuZ2VGcm9tUGFyc2VkKHJhbmdlLCBzY2FsZSwgcGFyc2VkLCBzdGFjayk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cblxuICBnZXRBbGxQYXJzZWRWYWx1ZXMoc2NhbGUpIHtcbiAgICBjb25zdCBwYXJzZWQgPSB0aGlzLl9jYWNoZWRNZXRhLl9wYXJzZWQ7XG4gICAgY29uc3QgdmFsdWVzID0gW107XG4gICAgbGV0IGksIGlsZW4sIHZhbHVlO1xuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IHBhcnNlZC5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHZhbHVlID0gcGFyc2VkW2ldW3NjYWxlLmF4aXNdO1xuICAgICAgaWYgKGlzRmluaXRlKHZhbHVlKSkge1xuICAgICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZXM7XG4gIH1cblxuICAvKipcblx0ICogQHJldHVybiB7bnVtYmVyfGJvb2xlYW59XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldE1heE92ZXJmbG93KCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRMYWJlbEFuZFZhbHVlKGluZGV4KSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgaVNjYWxlID0gbWV0YS5pU2NhbGU7XG4gICAgY29uc3QgdlNjYWxlID0gbWV0YS52U2NhbGU7XG4gICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaW5kZXgpO1xuICAgIHJldHVybiB7XG4gICAgICBsYWJlbDogaVNjYWxlID8gJycgKyBpU2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWRbaVNjYWxlLmF4aXNdKSA6ICcnLFxuICAgICAgdmFsdWU6IHZTY2FsZSA/ICcnICsgdlNjYWxlLmdldExhYmVsRm9yVmFsdWUocGFyc2VkW3ZTY2FsZS5heGlzXSkgOiAnJ1xuICAgIH07XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF91cGRhdGUobW9kZSkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIHRoaXMudXBkYXRlKG1vZGUgfHwgJ2RlZmF1bHQnKTtcbiAgICBtZXRhLl9jbGlwID0gdG9DbGlwKHZhbHVlT3JEZWZhdWx0KHRoaXMub3B0aW9ucy5jbGlwLCBkZWZhdWx0Q2xpcChtZXRhLnhTY2FsZSwgbWV0YS55U2NhbGUsIHRoaXMuZ2V0TWF4T3ZlcmZsb3coKSkpKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbW9kZVxuXHQgKi9cbiAgdXBkYXRlKG1vZGUpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcblxuICBkcmF3KCkge1xuICAgIGNvbnN0IGN0eCA9IHRoaXMuX2N0eDtcbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgZWxlbWVudHMgPSBtZXRhLmRhdGEgfHwgW107XG4gICAgY29uc3QgYXJlYSA9IGNoYXJ0LmNoYXJ0QXJlYTtcbiAgICBjb25zdCBhY3RpdmUgPSBbXTtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuX2RyYXdTdGFydCB8fCAwO1xuICAgIGNvbnN0IGNvdW50ID0gdGhpcy5fZHJhd0NvdW50IHx8IChlbGVtZW50cy5sZW5ndGggLSBzdGFydCk7XG4gICAgY29uc3QgZHJhd0FjdGl2ZUVsZW1lbnRzT25Ub3AgPSB0aGlzLm9wdGlvbnMuZHJhd0FjdGl2ZUVsZW1lbnRzT25Ub3A7XG4gICAgbGV0IGk7XG5cbiAgICBpZiAobWV0YS5kYXRhc2V0KSB7XG4gICAgICBtZXRhLmRhdGFzZXQuZHJhdyhjdHgsIGFyZWEsIHN0YXJ0LCBjb3VudCk7XG4gICAgfVxuXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBzdGFydCArIGNvdW50OyArK2kpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbGVtZW50c1tpXTtcbiAgICAgIGlmIChlbGVtZW50LmhpZGRlbikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChlbGVtZW50LmFjdGl2ZSAmJiBkcmF3QWN0aXZlRWxlbWVudHNPblRvcCkge1xuICAgICAgICBhY3RpdmUucHVzaChlbGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQuZHJhdyhjdHgsIGFyZWEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCBhY3RpdmUubGVuZ3RoOyArK2kpIHtcbiAgICAgIGFjdGl2ZVtpXS5kcmF3KGN0eCwgYXJlYSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIFJldHVybnMgYSBzZXQgb2YgcHJlZGVmaW5lZCBzdHlsZSBwcm9wZXJ0aWVzIHRoYXQgc2hvdWxkIGJlIHVzZWQgdG8gcmVwcmVzZW50IHRoZSBkYXRhc2V0XG5cdCAqIG9yIHRoZSBkYXRhIGlmIHRoZSBpbmRleCBpcyBzcGVjaWZpZWRcblx0ICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gZGF0YSBpbmRleFxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IFthY3RpdmVdIC0gdHJ1ZSBpZiBob3ZlclxuXHQgKiBAcmV0dXJuIHtvYmplY3R9IHN0eWxlIG9iamVjdFxuXHQgKi9cbiAgZ2V0U3R5bGUoaW5kZXgsIGFjdGl2ZSkge1xuICAgIGNvbnN0IG1vZGUgPSBhY3RpdmUgPyAnYWN0aXZlJyA6ICdkZWZhdWx0JztcbiAgICByZXR1cm4gaW5kZXggPT09IHVuZGVmaW5lZCAmJiB0aGlzLl9jYWNoZWRNZXRhLmRhdGFzZXRcbiAgICAgID8gdGhpcy5yZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zKG1vZGUpXG4gICAgICA6IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpbmRleCB8fCAwLCBtb2RlKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRDb250ZXh0KGluZGV4LCBhY3RpdmUsIG1vZGUpIHtcbiAgICBjb25zdCBkYXRhc2V0ID0gdGhpcy5nZXREYXRhc2V0KCk7XG4gICAgbGV0IGNvbnRleHQ7XG4gICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCB0aGlzLl9jYWNoZWRNZXRhLmRhdGEubGVuZ3RoKSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fY2FjaGVkTWV0YS5kYXRhW2luZGV4XTtcbiAgICAgIGNvbnRleHQgPSBlbGVtZW50LiRjb250ZXh0IHx8XG4gICAgICAgIChlbGVtZW50LiRjb250ZXh0ID0gY3JlYXRlRGF0YUNvbnRleHQodGhpcy5nZXRDb250ZXh0KCksIGluZGV4LCBlbGVtZW50KSk7XG4gICAgICBjb250ZXh0LnBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGluZGV4KTtcbiAgICAgIGNvbnRleHQucmF3ID0gZGF0YXNldC5kYXRhW2luZGV4XTtcbiAgICAgIGNvbnRleHQuaW5kZXggPSBjb250ZXh0LmRhdGFJbmRleCA9IGluZGV4O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZXh0ID0gdGhpcy4kY29udGV4dCB8fFxuICAgICAgICAodGhpcy4kY29udGV4dCA9IGNyZWF0ZURhdGFzZXRDb250ZXh0KHRoaXMuY2hhcnQuZ2V0Q29udGV4dCgpLCB0aGlzLmluZGV4KSk7XG4gICAgICBjb250ZXh0LmRhdGFzZXQgPSBkYXRhc2V0O1xuICAgICAgY29udGV4dC5pbmRleCA9IGNvbnRleHQuZGF0YXNldEluZGV4ID0gdGhpcy5pbmRleDtcbiAgICB9XG5cbiAgICBjb250ZXh0LmFjdGl2ZSA9ICEhYWN0aXZlO1xuICAgIGNvbnRleHQubW9kZSA9IG1vZGU7XG4gICAgcmV0dXJuIGNvbnRleHQ7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IFttb2RlXVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICByZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zKG1vZGUpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZUVsZW1lbnRPcHRpb25zKHRoaXMuZGF0YXNldEVsZW1lbnRUeXBlLmlkLCBtb2RlKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcblx0ICogQHBhcmFtIHtzdHJpbmd9IFttb2RlXVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICByZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGluZGV4LCBtb2RlKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Jlc29sdmVFbGVtZW50T3B0aW9ucyh0aGlzLmRhdGFFbGVtZW50VHlwZS5pZCwgbW9kZSwgaW5kZXgpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfcmVzb2x2ZUVsZW1lbnRPcHRpb25zKGVsZW1lbnRUeXBlLCBtb2RlID0gJ2RlZmF1bHQnLCBpbmRleCkge1xuICAgIGNvbnN0IGFjdGl2ZSA9IG1vZGUgPT09ICdhY3RpdmUnO1xuICAgIGNvbnN0IGNhY2hlID0gdGhpcy5fY2FjaGVkRGF0YU9wdHM7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBlbGVtZW50VHlwZSArICctJyArIG1vZGU7XG4gICAgY29uc3QgY2FjaGVkID0gY2FjaGVbY2FjaGVLZXldO1xuICAgIGNvbnN0IHNoYXJpbmcgPSB0aGlzLmVuYWJsZU9wdGlvblNoYXJpbmcgJiYgZGVmaW5lZChpbmRleCk7XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNsb25lSWZOb3RTaGFyZWQoY2FjaGVkLCBzaGFyaW5nKTtcbiAgICB9XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5jaGFydC5jb25maWc7XG4gICAgY29uc3Qgc2NvcGVLZXlzID0gY29uZmlnLmRhdGFzZXRFbGVtZW50U2NvcGVLZXlzKHRoaXMuX3R5cGUsIGVsZW1lbnRUeXBlKTtcbiAgICBjb25zdCBwcmVmaXhlcyA9IGFjdGl2ZSA/IFtgJHtlbGVtZW50VHlwZX1Ib3ZlcmAsICdob3ZlcicsIGVsZW1lbnRUeXBlLCAnJ10gOiBbZWxlbWVudFR5cGUsICcnXTtcbiAgICBjb25zdCBzY29wZXMgPSBjb25maWcuZ2V0T3B0aW9uU2NvcGVzKHRoaXMuZ2V0RGF0YXNldCgpLCBzY29wZUtleXMpO1xuICAgIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoZGVmYXVsdHMuZWxlbWVudHNbZWxlbWVudFR5cGVdKTtcbiAgICAvLyBjb250ZXh0IGlzIHByb3ZpZGVkIGFzIGEgZnVuY3Rpb24sIGFuZCBpcyBjYWxsZWQgb25seSBpZiBuZWVkZWQsXG4gICAgLy8gc28gd2UgZG9uJ3QgY3JlYXRlIGEgY29udGV4dCBmb3IgZWFjaCBlbGVtZW50IGlmIG5vdCBuZWVkZWQuXG4gICAgY29uc3QgY29udGV4dCA9ICgpID0+IHRoaXMuZ2V0Q29udGV4dChpbmRleCwgYWN0aXZlLCBtb2RlKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBjb25maWcucmVzb2x2ZU5hbWVkT3B0aW9ucyhzY29wZXMsIG5hbWVzLCBjb250ZXh0LCBwcmVmaXhlcyk7XG5cbiAgICBpZiAodmFsdWVzLiRzaGFyZWQpIHtcbiAgICAgIC8vIGAkc2hhcmVkYCBpbmRpY2F0ZXMgdGhpcyBzZXQgb2Ygb3B0aW9ucyBjYW4gYmUgc2hhcmVkIGJldHdlZW4gbXVsdGlwbGUgZWxlbWVudHMuXG4gICAgICAvLyBTaGFyaW5nIGlzIHVzZWQgdG8gcmVkdWNlIG51bWJlciBvZiBwcm9wZXJ0aWVzIHRvIGNoYW5nZSBkdXJpbmcgYW5pbWF0aW9uLlxuICAgICAgdmFsdWVzLiRzaGFyZWQgPSBzaGFyaW5nO1xuXG4gICAgICAvLyBXZSBjYWNoZSBvcHRpb25zIGJ5IGBtb2RlYCwgd2hpY2ggY2FuIGJlICdhY3RpdmUnIGZvciBleGFtcGxlLiBUaGlzIGVuYWJsZXMgdXNcbiAgICAgIC8vIHRvIGhhdmUgdGhlICdhY3RpdmUnIGVsZW1lbnQgb3B0aW9ucyBhbmQgJ2RlZmF1bHQnIG9wdGlvbnMgdG8gc3dpdGNoIGJldHdlZW5cbiAgICAgIC8vIHdoZW4gaW50ZXJhY3RpbmcuXG4gICAgICBjYWNoZVtjYWNoZUtleV0gPSBPYmplY3QuZnJlZXplKGNsb25lSWZOb3RTaGFyZWQodmFsdWVzLCBzaGFyaW5nKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfcmVzb2x2ZUFuaW1hdGlvbnMoaW5kZXgsIHRyYW5zaXRpb24sIGFjdGl2ZSkge1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBjYWNoZSA9IHRoaXMuX2NhY2hlZERhdGFPcHRzO1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gYGFuaW1hdGlvbi0ke3RyYW5zaXRpb259YDtcbiAgICBjb25zdCBjYWNoZWQgPSBjYWNoZVtjYWNoZUtleV07XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG4gICAgbGV0IG9wdGlvbnM7XG4gICAgaWYgKGNoYXJ0Lm9wdGlvbnMuYW5pbWF0aW9uICE9PSBmYWxzZSkge1xuICAgICAgY29uc3QgY29uZmlnID0gdGhpcy5jaGFydC5jb25maWc7XG4gICAgICBjb25zdCBzY29wZUtleXMgPSBjb25maWcuZGF0YXNldEFuaW1hdGlvblNjb3BlS2V5cyh0aGlzLl90eXBlLCB0cmFuc2l0aW9uKTtcbiAgICAgIGNvbnN0IHNjb3BlcyA9IGNvbmZpZy5nZXRPcHRpb25TY29wZXModGhpcy5nZXREYXRhc2V0KCksIHNjb3BlS2V5cyk7XG4gICAgICBvcHRpb25zID0gY29uZmlnLmNyZWF0ZVJlc29sdmVyKHNjb3BlcywgdGhpcy5nZXRDb250ZXh0KGluZGV4LCBhY3RpdmUsIHRyYW5zaXRpb24pKTtcbiAgICB9XG4gICAgY29uc3QgYW5pbWF0aW9ucyA9IG5ldyBBbmltYXRpb25zKGNoYXJ0LCBvcHRpb25zICYmIG9wdGlvbnMuYW5pbWF0aW9ucyk7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5fY2FjaGVhYmxlKSB7XG4gICAgICBjYWNoZVtjYWNoZUtleV0gPSBPYmplY3QuZnJlZXplKGFuaW1hdGlvbnMpO1xuICAgIH1cbiAgICByZXR1cm4gYW5pbWF0aW9ucztcbiAgfVxuXG4gIC8qKlxuXHQgKiBVdGlsaXR5IGZvciBnZXR0aW5nIHRoZSBvcHRpb25zIG9iamVjdCBzaGFyZWQgYmV0d2VlbiBlbGVtZW50c1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRTaGFyZWRPcHRpb25zKG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMuJHNoYXJlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc2hhcmVkT3B0aW9ucyB8fCAodGhpcy5fc2hhcmVkT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMpKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBVdGlsaXR5IGZvciBkZXRlcm1pbmluZyBpZiBgb3B0aW9uc2Agc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoZSB1cGRhdGVkIHByb3BlcnRpZXNcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgaW5jbHVkZU9wdGlvbnMobW9kZSwgc2hhcmVkT3B0aW9ucykge1xuICAgIHJldHVybiAhc2hhcmVkT3B0aW9ucyB8fCBpc0RpcmVjdFVwZGF0ZU1vZGUobW9kZSkgfHwgdGhpcy5jaGFydC5fYW5pbWF0aW9uc0Rpc2FibGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEB0b2RvIHY0LCByZW5hbWUgdG8gZ2V0U2hhcmVkT3B0aW9ucyBhbmQgcmVtb3ZlIGV4Y2VzcyBmdW5jdGlvbnNcbiAgICovXG4gIF9nZXRTaGFyZWRPcHRpb25zKHN0YXJ0LCBtb2RlKSB7XG4gICAgY29uc3QgZmlyc3RPcHRzID0gdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKHN0YXJ0LCBtb2RlKTtcbiAgICBjb25zdCBwcmV2aW91c2x5U2hhcmVkT3B0aW9ucyA9IHRoaXMuX3NoYXJlZE9wdGlvbnM7XG4gICAgY29uc3Qgc2hhcmVkT3B0aW9ucyA9IHRoaXMuZ2V0U2hhcmVkT3B0aW9ucyhmaXJzdE9wdHMpO1xuICAgIGNvbnN0IGluY2x1ZGVPcHRpb25zID0gdGhpcy5pbmNsdWRlT3B0aW9ucyhtb2RlLCBzaGFyZWRPcHRpb25zKSB8fCAoc2hhcmVkT3B0aW9ucyAhPT0gcHJldmlvdXNseVNoYXJlZE9wdGlvbnMpO1xuICAgIHRoaXMudXBkYXRlU2hhcmVkT3B0aW9ucyhzaGFyZWRPcHRpb25zLCBtb2RlLCBmaXJzdE9wdHMpO1xuICAgIHJldHVybiB7c2hhcmVkT3B0aW9ucywgaW5jbHVkZU9wdGlvbnN9O1xuICB9XG5cbiAgLyoqXG5cdCAqIFV0aWxpdHkgZm9yIHVwZGF0aW5nIGFuIGVsZW1lbnQgd2l0aCBuZXcgcHJvcGVydGllcywgdXNpbmcgYW5pbWF0aW9ucyB3aGVuIGFwcHJvcHJpYXRlLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICB1cGRhdGVFbGVtZW50KGVsZW1lbnQsIGluZGV4LCBwcm9wZXJ0aWVzLCBtb2RlKSB7XG4gICAgaWYgKGlzRGlyZWN0VXBkYXRlTW9kZShtb2RlKSkge1xuICAgICAgT2JqZWN0LmFzc2lnbihlbGVtZW50LCBwcm9wZXJ0aWVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcmVzb2x2ZUFuaW1hdGlvbnMoaW5kZXgsIG1vZGUpLnVwZGF0ZShlbGVtZW50LCBwcm9wZXJ0aWVzKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogVXRpbGl0eSB0byBhbmltYXRlIHRoZSBzaGFyZWQgb3B0aW9ucywgdGhhdCBhcmUgcG90ZW50aWFsbHkgYWZmZWN0aW5nIG11bHRpcGxlIGVsZW1lbnRzLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICB1cGRhdGVTaGFyZWRPcHRpb25zKHNoYXJlZE9wdGlvbnMsIG1vZGUsIG5ld09wdGlvbnMpIHtcbiAgICBpZiAoc2hhcmVkT3B0aW9ucyAmJiAhaXNEaXJlY3RVcGRhdGVNb2RlKG1vZGUpKSB7XG4gICAgICB0aGlzLl9yZXNvbHZlQW5pbWF0aW9ucyh1bmRlZmluZWQsIG1vZGUpLnVwZGF0ZShzaGFyZWRPcHRpb25zLCBuZXdPcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9zZXRTdHlsZShlbGVtZW50LCBpbmRleCwgbW9kZSwgYWN0aXZlKSB7XG4gICAgZWxlbWVudC5hY3RpdmUgPSBhY3RpdmU7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZ2V0U3R5bGUoaW5kZXgsIGFjdGl2ZSk7XG4gICAgdGhpcy5fcmVzb2x2ZUFuaW1hdGlvbnMoaW5kZXgsIG1vZGUsIGFjdGl2ZSkudXBkYXRlKGVsZW1lbnQsIHtcbiAgICAgIC8vIFdoZW4gZ29pbmcgZnJvbSBhY3RpdmUgdG8gaW5hY3RpdmUsIHdlIG5lZWQgdG8gdXBkYXRlIHRvIHRoZSBzaGFyZWQgb3B0aW9ucy5cbiAgICAgIC8vIFRoaXMgd2F5IHRoZSBvbmNlIGhvdmVyZWQgZWxlbWVudCB3aWxsIGVuZCB1cCB3aXRoIHRoZSBzYW1lIG9yaWdpbmFsIHNoYXJlZCBvcHRpb25zIGluc3RhbmNlLCBhZnRlciBhbmltYXRpb24uXG4gICAgICBvcHRpb25zOiAoIWFjdGl2ZSAmJiB0aGlzLmdldFNoYXJlZE9wdGlvbnMob3B0aW9ucykpIHx8IG9wdGlvbnNcbiAgICB9KTtcbiAgfVxuXG4gIHJlbW92ZUhvdmVyU3R5bGUoZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleCkge1xuICAgIHRoaXMuX3NldFN0eWxlKGVsZW1lbnQsIGluZGV4LCAnYWN0aXZlJywgZmFsc2UpO1xuICB9XG5cbiAgc2V0SG92ZXJTdHlsZShlbGVtZW50LCBkYXRhc2V0SW5kZXgsIGluZGV4KSB7XG4gICAgdGhpcy5fc2V0U3R5bGUoZWxlbWVudCwgaW5kZXgsICdhY3RpdmUnLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3JlbW92ZURhdGFzZXRIb3ZlclN0eWxlKCkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9jYWNoZWRNZXRhLmRhdGFzZXQ7XG5cbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgdGhpcy5fc2V0U3R5bGUoZWxlbWVudCwgdW5kZWZpbmVkLCAnYWN0aXZlJywgZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3NldERhdGFzZXRIb3ZlclN0eWxlKCkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9jYWNoZWRNZXRhLmRhdGFzZXQ7XG5cbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgdGhpcy5fc2V0U3R5bGUoZWxlbWVudCwgdW5kZWZpbmVkLCAnYWN0aXZlJywgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfcmVzeW5jRWxlbWVudHMocmVzZXROZXdFbGVtZW50cykge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhO1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5fY2FjaGVkTWV0YS5kYXRhO1xuXG4gICAgLy8gQXBwbHkgY2hhbmdlcyBkZXRlY3RlZCB0aHJvdWdoIGFycmF5IGxpc3RlbmVyc1xuICAgIGZvciAoY29uc3QgW21ldGhvZCwgYXJnMSwgYXJnMl0gb2YgdGhpcy5fc3luY0xpc3QpIHtcbiAgICAgIHRoaXNbbWV0aG9kXShhcmcxLCBhcmcyKTtcbiAgICB9XG4gICAgdGhpcy5fc3luY0xpc3QgPSBbXTtcblxuICAgIGNvbnN0IG51bU1ldGEgPSBlbGVtZW50cy5sZW5ndGg7XG4gICAgY29uc3QgbnVtRGF0YSA9IGRhdGEubGVuZ3RoO1xuICAgIGNvbnN0IGNvdW50ID0gTWF0aC5taW4obnVtRGF0YSwgbnVtTWV0YSk7XG5cbiAgICBpZiAoY291bnQpIHtcbiAgICAgIC8vIFRPRE86IEl0IGlzIG5vdCBvcHRpbWFsIHRvIGFsd2F5cyBwYXJzZSB0aGUgb2xkIGRhdGFcbiAgICAgIC8vIFRoaXMgaXMgZG9uZSBiZWNhdXNlIHdlIGFyZSBub3QgZGV0ZWN0aW5nIGRpcmVjdCBhc3NpZ25tZW50czpcbiAgICAgIC8vIGNoYXJ0LmRhdGEuZGF0YXNldHNbMF0uZGF0YVs1XSA9IDEwO1xuICAgICAgLy8gY2hhcnQuZGF0YS5kYXRhc2V0c1swXS5kYXRhWzVdLnkgPSAxMDtcbiAgICAgIHRoaXMucGFyc2UoMCwgY291bnQpO1xuICAgIH1cblxuICAgIGlmIChudW1EYXRhID4gbnVtTWV0YSkge1xuICAgICAgdGhpcy5faW5zZXJ0RWxlbWVudHMobnVtTWV0YSwgbnVtRGF0YSAtIG51bU1ldGEsIHJlc2V0TmV3RWxlbWVudHMpO1xuICAgIH0gZWxzZSBpZiAobnVtRGF0YSA8IG51bU1ldGEpIHtcbiAgICAgIHRoaXMuX3JlbW92ZUVsZW1lbnRzKG51bURhdGEsIG51bU1ldGEgLSBudW1EYXRhKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9pbnNlcnRFbGVtZW50cyhzdGFydCwgY291bnQsIHJlc2V0TmV3RWxlbWVudHMgPSB0cnVlKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgZGF0YSA9IG1ldGEuZGF0YTtcbiAgICBjb25zdCBlbmQgPSBzdGFydCArIGNvdW50O1xuICAgIGxldCBpO1xuXG4gICAgY29uc3QgbW92ZSA9IChhcnIpID0+IHtcbiAgICAgIGFyci5sZW5ndGggKz0gY291bnQ7XG4gICAgICBmb3IgKGkgPSBhcnIubGVuZ3RoIC0gMTsgaSA+PSBlbmQ7IGktLSkge1xuICAgICAgICBhcnJbaV0gPSBhcnJbaSAtIGNvdW50XTtcbiAgICAgIH1cbiAgICB9O1xuICAgIG1vdmUoZGF0YSk7XG5cbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICBkYXRhW2ldID0gbmV3IHRoaXMuZGF0YUVsZW1lbnRUeXBlKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3BhcnNpbmcpIHtcbiAgICAgIG1vdmUobWV0YS5fcGFyc2VkKTtcbiAgICB9XG4gICAgdGhpcy5wYXJzZShzdGFydCwgY291bnQpO1xuXG4gICAgaWYgKHJlc2V0TmV3RWxlbWVudHMpIHtcbiAgICAgIHRoaXMudXBkYXRlRWxlbWVudHMoZGF0YSwgc3RhcnQsIGNvdW50LCAncmVzZXQnKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVFbGVtZW50cyhlbGVtZW50LCBzdGFydCwgY291bnQsIG1vZGUpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9yZW1vdmVFbGVtZW50cyhzdGFydCwgY291bnQpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBpZiAodGhpcy5fcGFyc2luZykge1xuICAgICAgY29uc3QgcmVtb3ZlZCA9IG1ldGEuX3BhcnNlZC5zcGxpY2Uoc3RhcnQsIGNvdW50KTtcbiAgICAgIGlmIChtZXRhLl9zdGFja2VkKSB7XG4gICAgICAgIGNsZWFyU3RhY2tzKG1ldGEsIHJlbW92ZWQpO1xuICAgICAgfVxuICAgIH1cbiAgICBtZXRhLmRhdGEuc3BsaWNlKHN0YXJ0LCBjb3VudCk7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcbiAgICovXG4gIF9zeW5jKGFyZ3MpIHtcbiAgICBpZiAodGhpcy5fcGFyc2luZykge1xuICAgICAgdGhpcy5fc3luY0xpc3QucHVzaChhcmdzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgW21ldGhvZCwgYXJnMSwgYXJnMl0gPSBhcmdzO1xuICAgICAgdGhpc1ttZXRob2RdKGFyZzEsIGFyZzIpO1xuICAgIH1cbiAgICB0aGlzLmNoYXJ0Ll9kYXRhQ2hhbmdlcy5wdXNoKFt0aGlzLmluZGV4LCAuLi5hcmdzXSk7XG4gIH1cblxuICBfb25EYXRhUHVzaCgpIHtcbiAgICBjb25zdCBjb3VudCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdGhpcy5fc3luYyhbJ19pbnNlcnRFbGVtZW50cycsIHRoaXMuZ2V0RGF0YXNldCgpLmRhdGEubGVuZ3RoIC0gY291bnQsIGNvdW50XSk7XG4gIH1cblxuICBfb25EYXRhUG9wKCkge1xuICAgIHRoaXMuX3N5bmMoWydfcmVtb3ZlRWxlbWVudHMnLCB0aGlzLl9jYWNoZWRNZXRhLmRhdGEubGVuZ3RoIC0gMSwgMV0pO1xuICB9XG5cbiAgX29uRGF0YVNoaWZ0KCkge1xuICAgIHRoaXMuX3N5bmMoWydfcmVtb3ZlRWxlbWVudHMnLCAwLCAxXSk7XG4gIH1cblxuICBfb25EYXRhU3BsaWNlKHN0YXJ0LCBjb3VudCkge1xuICAgIGlmIChjb3VudCkge1xuICAgICAgdGhpcy5fc3luYyhbJ19yZW1vdmVFbGVtZW50cycsIHN0YXJ0LCBjb3VudF0pO1xuICAgIH1cbiAgICBjb25zdCBuZXdDb3VudCA9IGFyZ3VtZW50cy5sZW5ndGggLSAyO1xuICAgIGlmIChuZXdDb3VudCkge1xuICAgICAgdGhpcy5fc3luYyhbJ19pbnNlcnRFbGVtZW50cycsIHN0YXJ0LCBuZXdDb3VudF0pO1xuICAgIH1cbiAgfVxuXG4gIF9vbkRhdGFVbnNoaWZ0KCkge1xuICAgIHRoaXMuX3N5bmMoWydfaW5zZXJ0RWxlbWVudHMnLCAwLCBhcmd1bWVudHMubGVuZ3RoXSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgRGF0YXNldENvbnRyb2xsZXIgZnJvbSAnLi4vY29yZS9jb3JlLmRhdGFzZXRDb250cm9sbGVyLmpzJztcbmltcG9ydCB7XG4gIF9hcnJheVVuaXF1ZSwgaXNBcnJheSwgaXNOdWxsT3JVbmRlZixcbiAgdmFsdWVPckRlZmF1bHQsIHJlc29sdmVPYmplY3RLZXksIHNpZ24sIGRlZmluZWRcbn0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5cbmZ1bmN0aW9uIGdldEFsbFNjYWxlVmFsdWVzKHNjYWxlLCB0eXBlKSB7XG4gIGlmICghc2NhbGUuX2NhY2hlLiRiYXIpIHtcbiAgICBjb25zdCB2aXNpYmxlTWV0YXMgPSBzY2FsZS5nZXRNYXRjaGluZ1Zpc2libGVNZXRhcyh0eXBlKTtcbiAgICBsZXQgdmFsdWVzID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMCwgaWxlbiA9IHZpc2libGVNZXRhcy5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcbiAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQodmlzaWJsZU1ldGFzW2ldLmNvbnRyb2xsZXIuZ2V0QWxsUGFyc2VkVmFsdWVzKHNjYWxlKSk7XG4gICAgfVxuICAgIHNjYWxlLl9jYWNoZS4kYmFyID0gX2FycmF5VW5pcXVlKHZhbHVlcy5zb3J0KChhLCBiKSA9PiBhIC0gYikpO1xuICB9XG4gIHJldHVybiBzY2FsZS5fY2FjaGUuJGJhcjtcbn1cblxuLyoqXG4gKiBDb21wdXRlcyB0aGUgXCJvcHRpbWFsXCIgc2FtcGxlIHNpemUgdG8gbWFpbnRhaW4gYmFycyBlcXVhbGx5IHNpemVkIHdoaWxlIHByZXZlbnRpbmcgb3ZlcmxhcC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVNaW5TYW1wbGVTaXplKG1ldGEpIHtcbiAgY29uc3Qgc2NhbGUgPSBtZXRhLmlTY2FsZTtcbiAgY29uc3QgdmFsdWVzID0gZ2V0QWxsU2NhbGVWYWx1ZXMoc2NhbGUsIG1ldGEudHlwZSk7XG4gIGxldCBtaW4gPSBzY2FsZS5fbGVuZ3RoO1xuICBsZXQgaSwgaWxlbiwgY3VyciwgcHJldjtcbiAgY29uc3QgdXBkYXRlTWluQW5kUHJldiA9ICgpID0+IHtcbiAgICBpZiAoY3VyciA9PT0gMzI3NjcgfHwgY3VyciA9PT0gLTMyNzY4KSB7XG4gICAgICAvLyBJZ25vcmUgdHJ1bmNhdGVkIHBpeGVsc1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZGVmaW5lZChwcmV2KSkge1xuICAgICAgLy8gY3VyciAtIHByZXYgPT09IDAgaXMgaWdub3JlZFxuICAgICAgbWluID0gTWF0aC5taW4obWluLCBNYXRoLmFicyhjdXJyIC0gcHJldikgfHwgbWluKTtcbiAgICB9XG4gICAgcHJldiA9IGN1cnI7XG4gIH07XG5cbiAgZm9yIChpID0gMCwgaWxlbiA9IHZhbHVlcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBjdXJyID0gc2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZXNbaV0pO1xuICAgIHVwZGF0ZU1pbkFuZFByZXYoKTtcbiAgfVxuXG4gIHByZXYgPSB1bmRlZmluZWQ7XG4gIGZvciAoaSA9IDAsIGlsZW4gPSBzY2FsZS50aWNrcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBjdXJyID0gc2NhbGUuZ2V0UGl4ZWxGb3JUaWNrKGkpO1xuICAgIHVwZGF0ZU1pbkFuZFByZXYoKTtcbiAgfVxuXG4gIHJldHVybiBtaW47XG59XG5cbi8qKlxuICogQ29tcHV0ZXMgYW4gXCJpZGVhbFwiIGNhdGVnb3J5IGJhc2VkIG9uIHRoZSBhYnNvbHV0ZSBiYXIgdGhpY2tuZXNzIG9yLCBpZiB1bmRlZmluZWQgb3IgbnVsbCxcbiAqIHVzZXMgdGhlIHNtYWxsZXN0IGludGVydmFsIChzZWUgY29tcHV0ZU1pblNhbXBsZVNpemUpIHRoYXQgcHJldmVudHMgYmFyIG92ZXJsYXBwaW5nLiBUaGlzXG4gKiBtb2RlIGN1cnJlbnRseSBhbHdheXMgZ2VuZXJhdGVzIGJhcnMgZXF1YWxseSBzaXplZCAodW50aWwgd2UgaW50cm9kdWNlIHNjcmlwdGFibGUgb3B0aW9ucz8pLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY29tcHV0ZUZpdENhdGVnb3J5VHJhaXRzKGluZGV4LCBydWxlciwgb3B0aW9ucywgc3RhY2tDb3VudCkge1xuICBjb25zdCB0aGlja25lc3MgPSBvcHRpb25zLmJhclRoaWNrbmVzcztcbiAgbGV0IHNpemUsIHJhdGlvO1xuXG4gIGlmIChpc051bGxPclVuZGVmKHRoaWNrbmVzcykpIHtcbiAgICBzaXplID0gcnVsZXIubWluICogb3B0aW9ucy5jYXRlZ29yeVBlcmNlbnRhZ2U7XG4gICAgcmF0aW8gPSBvcHRpb25zLmJhclBlcmNlbnRhZ2U7XG4gIH0gZWxzZSB7XG4gICAgLy8gV2hlbiBiYXIgdGhpY2tuZXNzIGlzIGVuZm9yY2VkLCBjYXRlZ29yeSBhbmQgYmFyIHBlcmNlbnRhZ2VzIGFyZSBpZ25vcmVkLlxuICAgIC8vIE5vdGUoU0IpOiB3ZSBjb3VsZCBhZGQgc3VwcG9ydCBmb3IgcmVsYXRpdmUgYmFyIHRoaWNrbmVzcyAoZS5nLiBiYXJUaGlja25lc3M6ICc1MCUnKVxuICAgIC8vIGFuZCBkZXByZWNhdGUgYmFyUGVyY2VudGFnZSBzaW5jZSB0aGlzIHZhbHVlIGlzIGlnbm9yZWQgd2hlbiB0aGlja25lc3MgaXMgYWJzb2x1dGUuXG4gICAgc2l6ZSA9IHRoaWNrbmVzcyAqIHN0YWNrQ291bnQ7XG4gICAgcmF0aW8gPSAxO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjaHVuazogc2l6ZSAvIHN0YWNrQ291bnQsXG4gICAgcmF0aW8sXG4gICAgc3RhcnQ6IHJ1bGVyLnBpeGVsc1tpbmRleF0gLSAoc2l6ZSAvIDIpXG4gIH07XG59XG5cbi8qKlxuICogQ29tcHV0ZXMgYW4gXCJvcHRpbWFsXCIgY2F0ZWdvcnkgdGhhdCBnbG9iYWxseSBhcnJhbmdlcyBiYXJzIHNpZGUgYnkgc2lkZSAobm8gZ2FwIHdoZW5cbiAqIHBlcmNlbnRhZ2Ugb3B0aW9ucyBhcmUgMSksIGJhc2VkIG9uIHRoZSBwcmV2aW91cyBhbmQgZm9sbG93aW5nIGNhdGVnb3JpZXMuIFRoaXMgbW9kZVxuICogZ2VuZXJhdGVzIGJhcnMgd2l0aCBkaWZmZXJlbnQgd2lkdGhzIHdoZW4gZGF0YSBhcmUgbm90IGV2ZW5seSBzcGFjZWQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjb21wdXRlRmxleENhdGVnb3J5VHJhaXRzKGluZGV4LCBydWxlciwgb3B0aW9ucywgc3RhY2tDb3VudCkge1xuICBjb25zdCBwaXhlbHMgPSBydWxlci5waXhlbHM7XG4gIGNvbnN0IGN1cnIgPSBwaXhlbHNbaW5kZXhdO1xuICBsZXQgcHJldiA9IGluZGV4ID4gMCA/IHBpeGVsc1tpbmRleCAtIDFdIDogbnVsbDtcbiAgbGV0IG5leHQgPSBpbmRleCA8IHBpeGVscy5sZW5ndGggLSAxID8gcGl4ZWxzW2luZGV4ICsgMV0gOiBudWxsO1xuICBjb25zdCBwZXJjZW50ID0gb3B0aW9ucy5jYXRlZ29yeVBlcmNlbnRhZ2U7XG5cbiAgaWYgKHByZXYgPT09IG51bGwpIHtcbiAgICAvLyBmaXJzdCBkYXRhOiBpdHMgc2l6ZSBpcyBkb3VibGUgYmFzZWQgb24gdGhlIG5leHQgcG9pbnQgb3IsXG4gICAgLy8gaWYgaXQncyBhbHNvIHRoZSBsYXN0IGRhdGEsIHdlIHVzZSB0aGUgc2NhbGUgc2l6ZS5cbiAgICBwcmV2ID0gY3VyciAtIChuZXh0ID09PSBudWxsID8gcnVsZXIuZW5kIC0gcnVsZXIuc3RhcnQgOiBuZXh0IC0gY3Vycik7XG4gIH1cblxuICBpZiAobmV4dCA9PT0gbnVsbCkge1xuICAgIC8vIGxhc3QgZGF0YTogaXRzIHNpemUgaXMgYWxzbyBkb3VibGUgYmFzZWQgb24gdGhlIHByZXZpb3VzIHBvaW50LlxuICAgIG5leHQgPSBjdXJyICsgY3VyciAtIHByZXY7XG4gIH1cblxuICBjb25zdCBzdGFydCA9IGN1cnIgLSAoY3VyciAtIE1hdGgubWluKHByZXYsIG5leHQpKSAvIDIgKiBwZXJjZW50O1xuICBjb25zdCBzaXplID0gTWF0aC5hYnMobmV4dCAtIHByZXYpIC8gMiAqIHBlcmNlbnQ7XG5cbiAgcmV0dXJuIHtcbiAgICBjaHVuazogc2l6ZSAvIHN0YWNrQ291bnQsXG4gICAgcmF0aW86IG9wdGlvbnMuYmFyUGVyY2VudGFnZSxcbiAgICBzdGFydFxuICB9O1xufVxuXG5mdW5jdGlvbiBwYXJzZUZsb2F0QmFyKGVudHJ5LCBpdGVtLCB2U2NhbGUsIGkpIHtcbiAgY29uc3Qgc3RhcnRWYWx1ZSA9IHZTY2FsZS5wYXJzZShlbnRyeVswXSwgaSk7XG4gIGNvbnN0IGVuZFZhbHVlID0gdlNjYWxlLnBhcnNlKGVudHJ5WzFdLCBpKTtcbiAgY29uc3QgbWluID0gTWF0aC5taW4oc3RhcnRWYWx1ZSwgZW5kVmFsdWUpO1xuICBjb25zdCBtYXggPSBNYXRoLm1heChzdGFydFZhbHVlLCBlbmRWYWx1ZSk7XG4gIGxldCBiYXJTdGFydCA9IG1pbjtcbiAgbGV0IGJhckVuZCA9IG1heDtcblxuICBpZiAoTWF0aC5hYnMobWluKSA+IE1hdGguYWJzKG1heCkpIHtcbiAgICBiYXJTdGFydCA9IG1heDtcbiAgICBiYXJFbmQgPSBtaW47XG4gIH1cblxuICAvLyBTdG9yZSBgYmFyRW5kYCAoZnVydGhlc3QgYXdheSBmcm9tIG9yaWdpbikgYXMgcGFyc2VkIHZhbHVlLFxuICAvLyB0byBtYWtlIHN0YWNraW5nIHN0cmFpZ2h0IGZvcndhcmRcbiAgaXRlbVt2U2NhbGUuYXhpc10gPSBiYXJFbmQ7XG5cbiAgaXRlbS5fY3VzdG9tID0ge1xuICAgIGJhclN0YXJ0LFxuICAgIGJhckVuZCxcbiAgICBzdGFydDogc3RhcnRWYWx1ZSxcbiAgICBlbmQ6IGVuZFZhbHVlLFxuICAgIG1pbixcbiAgICBtYXhcbiAgfTtcbn1cblxuZnVuY3Rpb24gcGFyc2VWYWx1ZShlbnRyeSwgaXRlbSwgdlNjYWxlLCBpKSB7XG4gIGlmIChpc0FycmF5KGVudHJ5KSkge1xuICAgIHBhcnNlRmxvYXRCYXIoZW50cnksIGl0ZW0sIHZTY2FsZSwgaSk7XG4gIH0gZWxzZSB7XG4gICAgaXRlbVt2U2NhbGUuYXhpc10gPSB2U2NhbGUucGFyc2UoZW50cnksIGkpO1xuICB9XG4gIHJldHVybiBpdGVtO1xufVxuXG5mdW5jdGlvbiBwYXJzZUFycmF5T3JQcmltaXRpdmUobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gIGNvbnN0IGlTY2FsZSA9IG1ldGEuaVNjYWxlO1xuICBjb25zdCB2U2NhbGUgPSBtZXRhLnZTY2FsZTtcbiAgY29uc3QgbGFiZWxzID0gaVNjYWxlLmdldExhYmVscygpO1xuICBjb25zdCBzaW5nbGVTY2FsZSA9IGlTY2FsZSA9PT0gdlNjYWxlO1xuICBjb25zdCBwYXJzZWQgPSBbXTtcbiAgbGV0IGksIGlsZW4sIGl0ZW0sIGVudHJ5O1xuXG4gIGZvciAoaSA9IHN0YXJ0LCBpbGVuID0gc3RhcnQgKyBjb3VudDsgaSA8IGlsZW47ICsraSkge1xuICAgIGVudHJ5ID0gZGF0YVtpXTtcbiAgICBpdGVtID0ge307XG4gICAgaXRlbVtpU2NhbGUuYXhpc10gPSBzaW5nbGVTY2FsZSB8fCBpU2NhbGUucGFyc2UobGFiZWxzW2ldLCBpKTtcbiAgICBwYXJzZWQucHVzaChwYXJzZVZhbHVlKGVudHJ5LCBpdGVtLCB2U2NhbGUsIGkpKTtcbiAgfVxuICByZXR1cm4gcGFyc2VkO1xufVxuXG5mdW5jdGlvbiBpc0Zsb2F0QmFyKGN1c3RvbSkge1xuICByZXR1cm4gY3VzdG9tICYmIGN1c3RvbS5iYXJTdGFydCAhPT0gdW5kZWZpbmVkICYmIGN1c3RvbS5iYXJFbmQgIT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gYmFyU2lnbihzaXplLCB2U2NhbGUsIGFjdHVhbEJhc2UpIHtcbiAgaWYgKHNpemUgIT09IDApIHtcbiAgICByZXR1cm4gc2lnbihzaXplKTtcbiAgfVxuICByZXR1cm4gKHZTY2FsZS5pc0hvcml6b250YWwoKSA/IDEgOiAtMSkgKiAodlNjYWxlLm1pbiA+PSBhY3R1YWxCYXNlID8gMSA6IC0xKTtcbn1cblxuZnVuY3Rpb24gYm9yZGVyUHJvcHMocHJvcGVydGllcykge1xuICBsZXQgcmV2ZXJzZSwgc3RhcnQsIGVuZCwgdG9wLCBib3R0b207XG4gIGlmIChwcm9wZXJ0aWVzLmhvcml6b250YWwpIHtcbiAgICByZXZlcnNlID0gcHJvcGVydGllcy5iYXNlID4gcHJvcGVydGllcy54O1xuICAgIHN0YXJ0ID0gJ2xlZnQnO1xuICAgIGVuZCA9ICdyaWdodCc7XG4gIH0gZWxzZSB7XG4gICAgcmV2ZXJzZSA9IHByb3BlcnRpZXMuYmFzZSA8IHByb3BlcnRpZXMueTtcbiAgICBzdGFydCA9ICdib3R0b20nO1xuICAgIGVuZCA9ICd0b3AnO1xuICB9XG4gIGlmIChyZXZlcnNlKSB7XG4gICAgdG9wID0gJ2VuZCc7XG4gICAgYm90dG9tID0gJ3N0YXJ0JztcbiAgfSBlbHNlIHtcbiAgICB0b3AgPSAnc3RhcnQnO1xuICAgIGJvdHRvbSA9ICdlbmQnO1xuICB9XG4gIHJldHVybiB7c3RhcnQsIGVuZCwgcmV2ZXJzZSwgdG9wLCBib3R0b219O1xufVxuXG5mdW5jdGlvbiBzZXRCb3JkZXJTa2lwcGVkKHByb3BlcnRpZXMsIG9wdGlvbnMsIHN0YWNrLCBpbmRleCkge1xuICBsZXQgZWRnZSA9IG9wdGlvbnMuYm9yZGVyU2tpcHBlZDtcbiAgY29uc3QgcmVzID0ge307XG5cbiAgaWYgKCFlZGdlKSB7XG4gICAgcHJvcGVydGllcy5ib3JkZXJTa2lwcGVkID0gcmVzO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChlZGdlID09PSB0cnVlKSB7XG4gICAgcHJvcGVydGllcy5ib3JkZXJTa2lwcGVkID0ge3RvcDogdHJ1ZSwgcmlnaHQ6IHRydWUsIGJvdHRvbTogdHJ1ZSwgbGVmdDogdHJ1ZX07XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qge3N0YXJ0LCBlbmQsIHJldmVyc2UsIHRvcCwgYm90dG9tfSA9IGJvcmRlclByb3BzKHByb3BlcnRpZXMpO1xuXG4gIGlmIChlZGdlID09PSAnbWlkZGxlJyAmJiBzdGFjaykge1xuICAgIHByb3BlcnRpZXMuZW5hYmxlQm9yZGVyUmFkaXVzID0gdHJ1ZTtcbiAgICBpZiAoKHN0YWNrLl90b3AgfHwgMCkgPT09IGluZGV4KSB7XG4gICAgICBlZGdlID0gdG9wO1xuICAgIH0gZWxzZSBpZiAoKHN0YWNrLl9ib3R0b20gfHwgMCkgPT09IGluZGV4KSB7XG4gICAgICBlZGdlID0gYm90dG9tO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNbcGFyc2VFZGdlKGJvdHRvbSwgc3RhcnQsIGVuZCwgcmV2ZXJzZSldID0gdHJ1ZTtcbiAgICAgIGVkZ2UgPSB0b3A7XG4gICAgfVxuICB9XG5cbiAgcmVzW3BhcnNlRWRnZShlZGdlLCBzdGFydCwgZW5kLCByZXZlcnNlKV0gPSB0cnVlO1xuICBwcm9wZXJ0aWVzLmJvcmRlclNraXBwZWQgPSByZXM7XG59XG5cbmZ1bmN0aW9uIHBhcnNlRWRnZShlZGdlLCBhLCBiLCByZXZlcnNlKSB7XG4gIGlmIChyZXZlcnNlKSB7XG4gICAgZWRnZSA9IHN3YXAoZWRnZSwgYSwgYik7XG4gICAgZWRnZSA9IHN0YXJ0RW5kKGVkZ2UsIGIsIGEpO1xuICB9IGVsc2Uge1xuICAgIGVkZ2UgPSBzdGFydEVuZChlZGdlLCBhLCBiKTtcbiAgfVxuICByZXR1cm4gZWRnZTtcbn1cblxuZnVuY3Rpb24gc3dhcChvcmlnLCB2MSwgdjIpIHtcbiAgcmV0dXJuIG9yaWcgPT09IHYxID8gdjIgOiBvcmlnID09PSB2MiA/IHYxIDogb3JpZztcbn1cblxuZnVuY3Rpb24gc3RhcnRFbmQodiwgc3RhcnQsIGVuZCkge1xuICByZXR1cm4gdiA9PT0gJ3N0YXJ0JyA/IHN0YXJ0IDogdiA9PT0gJ2VuZCcgPyBlbmQgOiB2O1xufVxuXG5mdW5jdGlvbiBzZXRJbmZsYXRlQW1vdW50KHByb3BlcnRpZXMsIHtpbmZsYXRlQW1vdW50fSwgcmF0aW8pIHtcbiAgcHJvcGVydGllcy5pbmZsYXRlQW1vdW50ID0gaW5mbGF0ZUFtb3VudCA9PT0gJ2F1dG8nXG4gICAgPyByYXRpbyA9PT0gMSA/IDAuMzMgOiAwXG4gICAgOiBpbmZsYXRlQW1vdW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYXJDb250cm9sbGVyIGV4dGVuZHMgRGF0YXNldENvbnRyb2xsZXIge1xuXG4gIHN0YXRpYyBpZCA9ICdiYXInO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIGRhdGFzZXRFbGVtZW50VHlwZTogZmFsc2UsXG4gICAgZGF0YUVsZW1lbnRUeXBlOiAnYmFyJyxcblxuICAgIGNhdGVnb3J5UGVyY2VudGFnZTogMC44LFxuICAgIGJhclBlcmNlbnRhZ2U6IDAuOSxcbiAgICBncm91cGVkOiB0cnVlLFxuXG4gICAgYW5pbWF0aW9uczoge1xuICAgICAgbnVtYmVyczoge1xuICAgICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgICAgcHJvcGVydGllczogWyd4JywgJ3knLCAnYmFzZScsICd3aWR0aCcsICdoZWlnaHQnXVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBvdmVycmlkZXMgPSB7XG4gICAgc2NhbGVzOiB7XG4gICAgICBfaW5kZXhfOiB7XG4gICAgICAgIHR5cGU6ICdjYXRlZ29yeScsXG4gICAgICAgIG9mZnNldDogdHJ1ZSxcbiAgICAgICAgZ3JpZDoge1xuICAgICAgICAgIG9mZnNldDogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgX3ZhbHVlXzoge1xuICAgICAgICB0eXBlOiAnbGluZWFyJyxcbiAgICAgICAgYmVnaW5BdFplcm86IHRydWUsXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG5cbiAgLyoqXG5cdCAqIE92ZXJyaWRpbmcgcHJpbWl0aXZlIGRhdGEgcGFyc2luZyBzaW5jZSB3ZSBzdXBwb3J0IG1peGVkIHByaW1pdGl2ZS9hcnJheVxuXHQgKiBkYXRhIGZvciBmbG9hdCBiYXJzXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIHBhcnNlUHJpbWl0aXZlRGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICByZXR1cm4gcGFyc2VBcnJheU9yUHJpbWl0aXZlKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gIH1cblxuICAvKipcblx0ICogT3ZlcnJpZGluZyBhcnJheSBkYXRhIHBhcnNpbmcgc2luY2Ugd2Ugc3VwcG9ydCBtaXhlZCBwcmltaXRpdmUvYXJyYXlcblx0ICogZGF0YSBmb3IgZmxvYXQgYmFyc1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBwYXJzZUFycmF5RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICByZXR1cm4gcGFyc2VBcnJheU9yUHJpbWl0aXZlKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gIH1cblxuICAvKipcblx0ICogT3ZlcnJpZGluZyBvYmplY3QgZGF0YSBwYXJzaW5nIHNpbmNlIHdlIHN1cHBvcnQgbWl4ZWQgcHJpbWl0aXZlL2FycmF5XG5cdCAqIHZhbHVlLXNjYWxlIGRhdGEgZm9yIGZsb2F0IGJhcnNcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgcGFyc2VPYmplY3REYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IHtpU2NhbGUsIHZTY2FsZX0gPSBtZXRhO1xuICAgIGNvbnN0IHt4QXhpc0tleSA9ICd4JywgeUF4aXNLZXkgPSAneSd9ID0gdGhpcy5fcGFyc2luZztcbiAgICBjb25zdCBpQXhpc0tleSA9IGlTY2FsZS5heGlzID09PSAneCcgPyB4QXhpc0tleSA6IHlBeGlzS2V5O1xuICAgIGNvbnN0IHZBeGlzS2V5ID0gdlNjYWxlLmF4aXMgPT09ICd4JyA/IHhBeGlzS2V5IDogeUF4aXNLZXk7XG4gICAgY29uc3QgcGFyc2VkID0gW107XG4gICAgbGV0IGksIGlsZW4sIGl0ZW0sIG9iajtcbiAgICBmb3IgKGkgPSBzdGFydCwgaWxlbiA9IHN0YXJ0ICsgY291bnQ7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIG9iaiA9IGRhdGFbaV07XG4gICAgICBpdGVtID0ge307XG4gICAgICBpdGVtW2lTY2FsZS5heGlzXSA9IGlTY2FsZS5wYXJzZShyZXNvbHZlT2JqZWN0S2V5KG9iaiwgaUF4aXNLZXkpLCBpKTtcbiAgICAgIHBhcnNlZC5wdXNoKHBhcnNlVmFsdWUocmVzb2x2ZU9iamVjdEtleShvYmosIHZBeGlzS2V5KSwgaXRlbSwgdlNjYWxlLCBpKSk7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgdXBkYXRlUmFuZ2VGcm9tUGFyc2VkKHJhbmdlLCBzY2FsZSwgcGFyc2VkLCBzdGFjaykge1xuICAgIHN1cGVyLnVwZGF0ZVJhbmdlRnJvbVBhcnNlZChyYW5nZSwgc2NhbGUsIHBhcnNlZCwgc3RhY2spO1xuICAgIGNvbnN0IGN1c3RvbSA9IHBhcnNlZC5fY3VzdG9tO1xuICAgIGlmIChjdXN0b20gJiYgc2NhbGUgPT09IHRoaXMuX2NhY2hlZE1ldGEudlNjYWxlKSB7XG4gICAgICAvLyBmbG9hdCBiYXI6IG9ubHkgb25lIGVuZCBvZiB0aGUgYmFyIGlzIGNvbnNpZGVyZWQgYnkgYHN1cGVyYFxuICAgICAgcmFuZ2UubWluID0gTWF0aC5taW4ocmFuZ2UubWluLCBjdXN0b20ubWluKTtcbiAgICAgIHJhbmdlLm1heCA9IE1hdGgubWF4KHJhbmdlLm1heCwgY3VzdG9tLm1heCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEByZXR1cm4ge251bWJlcnxib29sZWFufVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRNYXhPdmVyZmxvdygpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRMYWJlbEFuZFZhbHVlKGluZGV4KSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3Qge2lTY2FsZSwgdlNjYWxlfSA9IG1ldGE7XG4gICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaW5kZXgpO1xuICAgIGNvbnN0IGN1c3RvbSA9IHBhcnNlZC5fY3VzdG9tO1xuICAgIGNvbnN0IHZhbHVlID0gaXNGbG9hdEJhcihjdXN0b20pXG4gICAgICA/ICdbJyArIGN1c3RvbS5zdGFydCArICcsICcgKyBjdXN0b20uZW5kICsgJ10nXG4gICAgICA6ICcnICsgdlNjYWxlLmdldExhYmVsRm9yVmFsdWUocGFyc2VkW3ZTY2FsZS5heGlzXSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6ICcnICsgaVNjYWxlLmdldExhYmVsRm9yVmFsdWUocGFyc2VkW2lTY2FsZS5heGlzXSksXG4gICAgICB2YWx1ZVxuICAgIH07XG4gIH1cblxuICBpbml0aWFsaXplKCkge1xuICAgIHRoaXMuZW5hYmxlT3B0aW9uU2hhcmluZyA9IHRydWU7XG5cbiAgICBzdXBlci5pbml0aWFsaXplKCk7XG5cbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBtZXRhLnN0YWNrID0gdGhpcy5nZXREYXRhc2V0KCkuc3RhY2s7XG4gIH1cblxuICB1cGRhdGUobW9kZSkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIHRoaXMudXBkYXRlRWxlbWVudHMobWV0YS5kYXRhLCAwLCBtZXRhLmRhdGEubGVuZ3RoLCBtb2RlKTtcbiAgfVxuXG4gIHVwZGF0ZUVsZW1lbnRzKGJhcnMsIHN0YXJ0LCBjb3VudCwgbW9kZSkge1xuICAgIGNvbnN0IHJlc2V0ID0gbW9kZSA9PT0gJ3Jlc2V0JztcbiAgICBjb25zdCB7aW5kZXgsIF9jYWNoZWRNZXRhOiB7dlNjYWxlfX0gPSB0aGlzO1xuICAgIGNvbnN0IGJhc2UgPSB2U2NhbGUuZ2V0QmFzZVBpeGVsKCk7XG4gICAgY29uc3QgaG9yaXpvbnRhbCA9IHZTY2FsZS5pc0hvcml6b250YWwoKTtcbiAgICBjb25zdCBydWxlciA9IHRoaXMuX2dldFJ1bGVyKCk7XG4gICAgY29uc3Qge3NoYXJlZE9wdGlvbnMsIGluY2x1ZGVPcHRpb25zfSA9IHRoaXMuX2dldFNoYXJlZE9wdGlvbnMoc3RhcnQsIG1vZGUpO1xuXG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBjb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpKTtcbiAgICAgIGNvbnN0IHZwaXhlbHMgPSByZXNldCB8fCBpc051bGxPclVuZGVmKHBhcnNlZFt2U2NhbGUuYXhpc10pID8ge2Jhc2UsIGhlYWQ6IGJhc2V9IDogdGhpcy5fY2FsY3VsYXRlQmFyVmFsdWVQaXhlbHMoaSk7XG4gICAgICBjb25zdCBpcGl4ZWxzID0gdGhpcy5fY2FsY3VsYXRlQmFySW5kZXhQaXhlbHMoaSwgcnVsZXIpO1xuICAgICAgY29uc3Qgc3RhY2sgPSAocGFyc2VkLl9zdGFja3MgfHwge30pW3ZTY2FsZS5heGlzXTtcblxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IHtcbiAgICAgICAgaG9yaXpvbnRhbCxcbiAgICAgICAgYmFzZTogdnBpeGVscy5iYXNlLFxuICAgICAgICBlbmFibGVCb3JkZXJSYWRpdXM6ICFzdGFjayB8fCBpc0Zsb2F0QmFyKHBhcnNlZC5fY3VzdG9tKSB8fCAoaW5kZXggPT09IHN0YWNrLl90b3AgfHwgaW5kZXggPT09IHN0YWNrLl9ib3R0b20pLFxuICAgICAgICB4OiBob3Jpem9udGFsID8gdnBpeGVscy5oZWFkIDogaXBpeGVscy5jZW50ZXIsXG4gICAgICAgIHk6IGhvcml6b250YWwgPyBpcGl4ZWxzLmNlbnRlciA6IHZwaXhlbHMuaGVhZCxcbiAgICAgICAgaGVpZ2h0OiBob3Jpem9udGFsID8gaXBpeGVscy5zaXplIDogTWF0aC5hYnModnBpeGVscy5zaXplKSxcbiAgICAgICAgd2lkdGg6IGhvcml6b250YWwgPyBNYXRoLmFicyh2cGl4ZWxzLnNpemUpIDogaXBpeGVscy5zaXplXG4gICAgICB9O1xuXG4gICAgICBpZiAoaW5jbHVkZU9wdGlvbnMpIHtcbiAgICAgICAgcHJvcGVydGllcy5vcHRpb25zID0gc2hhcmVkT3B0aW9ucyB8fCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgYmFyc1tpXS5hY3RpdmUgPyAnYWN0aXZlJyA6IG1vZGUpO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3B0aW9ucyA9IHByb3BlcnRpZXMub3B0aW9ucyB8fCBiYXJzW2ldLm9wdGlvbnM7XG4gICAgICBzZXRCb3JkZXJTa2lwcGVkKHByb3BlcnRpZXMsIG9wdGlvbnMsIHN0YWNrLCBpbmRleCk7XG4gICAgICBzZXRJbmZsYXRlQW1vdW50KHByb3BlcnRpZXMsIG9wdGlvbnMsIHJ1bGVyLnJhdGlvKTtcbiAgICAgIHRoaXMudXBkYXRlRWxlbWVudChiYXJzW2ldLCBpLCBwcm9wZXJ0aWVzLCBtb2RlKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB0aGUgc3RhY2tzIGJhc2VkIG9uIGdyb3VwcyBhbmQgYmFyIHZpc2liaWxpdHkuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbbGFzdF0gLSBUaGUgZGF0YXNldCBpbmRleFxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2RhdGFJbmRleF0gLSBUaGUgZGF0YSBpbmRleCBvZiB0aGUgcnVsZXJcblx0ICogQHJldHVybnMge3N0cmluZ1tdfSBUaGUgbGlzdCBvZiBzdGFjayBJRHNcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRTdGFja3MobGFzdCwgZGF0YUluZGV4KSB7XG4gICAgY29uc3Qge2lTY2FsZX0gPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IG1ldGFzZXRzID0gaVNjYWxlLmdldE1hdGNoaW5nVmlzaWJsZU1ldGFzKHRoaXMuX3R5cGUpXG4gICAgICAuZmlsdGVyKG1ldGEgPT4gbWV0YS5jb250cm9sbGVyLm9wdGlvbnMuZ3JvdXBlZCk7XG4gICAgY29uc3Qgc3RhY2tlZCA9IGlTY2FsZS5vcHRpb25zLnN0YWNrZWQ7XG4gICAgY29uc3Qgc3RhY2tzID0gW107XG5cbiAgICBjb25zdCBza2lwTnVsbCA9IChtZXRhKSA9PiB7XG4gICAgICBjb25zdCBwYXJzZWQgPSBtZXRhLmNvbnRyb2xsZXIuZ2V0UGFyc2VkKGRhdGFJbmRleCk7XG4gICAgICBjb25zdCB2YWwgPSBwYXJzZWQgJiYgcGFyc2VkW21ldGEudlNjYWxlLmF4aXNdO1xuXG4gICAgICBpZiAoaXNOdWxsT3JVbmRlZih2YWwpIHx8IGlzTmFOKHZhbCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvciAoY29uc3QgbWV0YSBvZiBtZXRhc2V0cykge1xuICAgICAgaWYgKGRhdGFJbmRleCAhPT0gdW5kZWZpbmVkICYmIHNraXBOdWxsKG1ldGEpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBzdGFja2VkICAgfCBtZXRhLnN0YWNrXG4gICAgICAvLyAgICAgICAgICAgfCBmb3VuZCB8IG5vdCBmb3VuZCB8IHVuZGVmaW5lZFxuICAgICAgLy8gZmFsc2UgICAgIHwgICB4ICAgfCAgICAgeCAgICAgfCAgICAgeFxuICAgICAgLy8gdHJ1ZSAgICAgIHwgICAgICAgfCAgICAgeCAgICAgfFxuICAgICAgLy8gdW5kZWZpbmVkIHwgICAgICAgfCAgICAgeCAgICAgfCAgICAgeFxuICAgICAgaWYgKHN0YWNrZWQgPT09IGZhbHNlIHx8IHN0YWNrcy5pbmRleE9mKG1ldGEuc3RhY2spID09PSAtMSB8fFxuXHRcdFx0XHQoc3RhY2tlZCA9PT0gdW5kZWZpbmVkICYmIG1ldGEuc3RhY2sgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgc3RhY2tzLnB1c2gobWV0YS5zdGFjayk7XG4gICAgICB9XG4gICAgICBpZiAobWV0YS5pbmRleCA9PT0gbGFzdCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBObyBzdGFja3M/IHRoYXQgbWVhbnMgdGhlcmUgaXMgbm8gdmlzaWJsZSBkYXRhLiBMZXQncyBzdGlsbCBpbml0aWFsaXplIGFuIGB1bmRlZmluZWRgXG4gICAgLy8gc3RhY2sgd2hlcmUgcG9zc2libGUgaW52aXNpYmxlIGJhcnMgd2lsbCBiZSBsb2NhdGVkLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy82MzY4XG4gICAgaWYgKCFzdGFja3MubGVuZ3RoKSB7XG4gICAgICBzdGFja3MucHVzaCh1bmRlZmluZWQpO1xuICAgIH1cblxuICAgIHJldHVybiBzdGFja3M7XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB0aGUgZWZmZWN0aXZlIG51bWJlciBvZiBzdGFja3MgYmFzZWQgb24gZ3JvdXBzIGFuZCBiYXIgdmlzaWJpbGl0eS5cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRTdGFja0NvdW50KGluZGV4KSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldFN0YWNrcyh1bmRlZmluZWQsIGluZGV4KS5sZW5ndGg7XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB0aGUgc3RhY2sgaW5kZXggZm9yIHRoZSBnaXZlbiBkYXRhc2V0IGJhc2VkIG9uIGdyb3VwcyBhbmQgYmFyIHZpc2liaWxpdHkuXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbZGF0YXNldEluZGV4XSAtIFRoZSBkYXRhc2V0IGluZGV4XG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZV0gLSBUaGUgc3RhY2sgbmFtZSB0byBmaW5kXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGF0YUluZGV4XVxuXHQgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgc3RhY2sgaW5kZXhcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRTdGFja0luZGV4KGRhdGFzZXRJbmRleCwgbmFtZSwgZGF0YUluZGV4KSB7XG4gICAgY29uc3Qgc3RhY2tzID0gdGhpcy5fZ2V0U3RhY2tzKGRhdGFzZXRJbmRleCwgZGF0YUluZGV4KTtcbiAgICBjb25zdCBpbmRleCA9IChuYW1lICE9PSB1bmRlZmluZWQpXG4gICAgICA/IHN0YWNrcy5pbmRleE9mKG5hbWUpXG4gICAgICA6IC0xOyAvLyBpbmRleE9mIHJldHVybnMgLTEgaWYgZWxlbWVudCBpcyBub3QgcHJlc2VudFxuXG4gICAgcmV0dXJuIChpbmRleCA9PT0gLTEpXG4gICAgICA/IHN0YWNrcy5sZW5ndGggLSAxXG4gICAgICA6IGluZGV4O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0UnVsZXIoKSB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBpU2NhbGUgPSBtZXRhLmlTY2FsZTtcbiAgICBjb25zdCBwaXhlbHMgPSBbXTtcbiAgICBsZXQgaSwgaWxlbjtcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBtZXRhLmRhdGEubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBwaXhlbHMucHVzaChpU2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZSh0aGlzLmdldFBhcnNlZChpKVtpU2NhbGUuYXhpc10sIGkpKTtcbiAgICB9XG5cbiAgICBjb25zdCBiYXJUaGlja25lc3MgPSBvcHRzLmJhclRoaWNrbmVzcztcbiAgICBjb25zdCBtaW4gPSBiYXJUaGlja25lc3MgfHwgY29tcHV0ZU1pblNhbXBsZVNpemUobWV0YSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbWluLFxuICAgICAgcGl4ZWxzLFxuICAgICAgc3RhcnQ6IGlTY2FsZS5fc3RhcnRQaXhlbCxcbiAgICAgIGVuZDogaVNjYWxlLl9lbmRQaXhlbCxcbiAgICAgIHN0YWNrQ291bnQ6IHRoaXMuX2dldFN0YWNrQ291bnQoKSxcbiAgICAgIHNjYWxlOiBpU2NhbGUsXG4gICAgICBncm91cGVkOiBvcHRzLmdyb3VwZWQsXG4gICAgICAvLyBiYXIgdGhpY2tuZXNzIHJhdGlvIHVzZWQgZm9yIG5vbi1ncm91cGVkIGJhcnNcbiAgICAgIHJhdGlvOiBiYXJUaGlja25lc3MgPyAxIDogb3B0cy5jYXRlZ29yeVBlcmNlbnRhZ2UgKiBvcHRzLmJhclBlcmNlbnRhZ2VcbiAgICB9O1xuICB9XG5cbiAgLyoqXG5cdCAqIE5vdGU6IHBpeGVsIHZhbHVlcyBhcmUgbm90IGNsYW1wZWQgdG8gdGhlIHNjYWxlIGFyZWEuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfY2FsY3VsYXRlQmFyVmFsdWVQaXhlbHMoaW5kZXgpIHtcbiAgICBjb25zdCB7X2NhY2hlZE1ldGE6IHt2U2NhbGUsIF9zdGFja2VkLCBpbmRleDogZGF0YXNldEluZGV4fSwgb3B0aW9uczoge2Jhc2U6IGJhc2VWYWx1ZSwgbWluQmFyTGVuZ3RofX0gPSB0aGlzO1xuICAgIGNvbnN0IGFjdHVhbEJhc2UgPSBiYXNlVmFsdWUgfHwgMDtcbiAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG4gICAgY29uc3QgY3VzdG9tID0gcGFyc2VkLl9jdXN0b207XG4gICAgY29uc3QgZmxvYXRpbmcgPSBpc0Zsb2F0QmFyKGN1c3RvbSk7XG4gICAgbGV0IHZhbHVlID0gcGFyc2VkW3ZTY2FsZS5heGlzXTtcbiAgICBsZXQgc3RhcnQgPSAwO1xuICAgIGxldCBsZW5ndGggPSBfc3RhY2tlZCA/IHRoaXMuYXBwbHlTdGFjayh2U2NhbGUsIHBhcnNlZCwgX3N0YWNrZWQpIDogdmFsdWU7XG4gICAgbGV0IGhlYWQsIHNpemU7XG5cbiAgICBpZiAobGVuZ3RoICE9PSB2YWx1ZSkge1xuICAgICAgc3RhcnQgPSBsZW5ndGggLSB2YWx1ZTtcbiAgICAgIGxlbmd0aCA9IHZhbHVlO1xuICAgIH1cblxuICAgIGlmIChmbG9hdGluZykge1xuICAgICAgdmFsdWUgPSBjdXN0b20uYmFyU3RhcnQ7XG4gICAgICBsZW5ndGggPSBjdXN0b20uYmFyRW5kIC0gY3VzdG9tLmJhclN0YXJ0O1xuICAgICAgLy8gYmFycyBjcm9zc2luZyBvcmlnaW4gYXJlIG5vdCBzdGFja2VkXG4gICAgICBpZiAodmFsdWUgIT09IDAgJiYgc2lnbih2YWx1ZSkgIT09IHNpZ24oY3VzdG9tLmJhckVuZCkpIHtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgfVxuICAgICAgc3RhcnQgKz0gdmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnRWYWx1ZSA9ICFpc051bGxPclVuZGVmKGJhc2VWYWx1ZSkgJiYgIWZsb2F0aW5nID8gYmFzZVZhbHVlIDogc3RhcnQ7XG4gICAgbGV0IGJhc2UgPSB2U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShzdGFydFZhbHVlKTtcblxuICAgIGlmICh0aGlzLmNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGluZGV4KSkge1xuICAgICAgaGVhZCA9IHZTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHN0YXJ0ICsgbGVuZ3RoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gV2hlbiBub3QgdmlzaWJsZSwgbm8gaGVpZ2h0XG4gICAgICBoZWFkID0gYmFzZTtcbiAgICB9XG5cbiAgICBzaXplID0gaGVhZCAtIGJhc2U7XG5cbiAgICBpZiAoTWF0aC5hYnMoc2l6ZSkgPCBtaW5CYXJMZW5ndGgpIHtcbiAgICAgIHNpemUgPSBiYXJTaWduKHNpemUsIHZTY2FsZSwgYWN0dWFsQmFzZSkgKiBtaW5CYXJMZW5ndGg7XG4gICAgICBpZiAodmFsdWUgPT09IGFjdHVhbEJhc2UpIHtcbiAgICAgICAgYmFzZSAtPSBzaXplIC8gMjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXJ0UGl4ZWwgPSB2U2NhbGUuZ2V0UGl4ZWxGb3JEZWNpbWFsKDApO1xuICAgICAgY29uc3QgZW5kUGl4ZWwgPSB2U2NhbGUuZ2V0UGl4ZWxGb3JEZWNpbWFsKDEpO1xuICAgICAgY29uc3QgbWluID0gTWF0aC5taW4oc3RhcnRQaXhlbCwgZW5kUGl4ZWwpO1xuICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoc3RhcnRQaXhlbCwgZW5kUGl4ZWwpO1xuICAgICAgYmFzZSA9IE1hdGgubWF4KE1hdGgubWluKGJhc2UsIG1heCksIG1pbik7XG4gICAgICBoZWFkID0gYmFzZSArIHNpemU7XG5cbiAgICAgIGlmIChfc3RhY2tlZCAmJiAhZmxvYXRpbmcpIHtcbiAgICAgICAgLy8gdmlzdWFsIGRhdGEgY29vcmRpbmF0ZXMgYWZ0ZXIgYXBwbHlpbmcgbWluQmFyTGVuZ3RoXG4gICAgICAgIHBhcnNlZC5fc3RhY2tzW3ZTY2FsZS5heGlzXS5fdmlzdWFsVmFsdWVzW2RhdGFzZXRJbmRleF0gPSB2U2NhbGUuZ2V0VmFsdWVGb3JQaXhlbChoZWFkKSAtIHZTY2FsZS5nZXRWYWx1ZUZvclBpeGVsKGJhc2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChiYXNlID09PSB2U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShhY3R1YWxCYXNlKSkge1xuICAgICAgY29uc3QgaGFsZkdyaWQgPSBzaWduKHNpemUpICogdlNjYWxlLmdldExpbmVXaWR0aEZvclZhbHVlKGFjdHVhbEJhc2UpIC8gMjtcbiAgICAgIGJhc2UgKz0gaGFsZkdyaWQ7XG4gICAgICBzaXplIC09IGhhbGZHcmlkO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBzaXplLFxuICAgICAgYmFzZSxcbiAgICAgIGhlYWQsXG4gICAgICBjZW50ZXI6IGhlYWQgKyBzaXplIC8gMlxuICAgIH07XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9jYWxjdWxhdGVCYXJJbmRleFBpeGVscyhpbmRleCwgcnVsZXIpIHtcbiAgICBjb25zdCBzY2FsZSA9IHJ1bGVyLnNjYWxlO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3Qgc2tpcE51bGwgPSBvcHRpb25zLnNraXBOdWxsO1xuICAgIGNvbnN0IG1heEJhclRoaWNrbmVzcyA9IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMubWF4QmFyVGhpY2tuZXNzLCBJbmZpbml0eSk7XG4gICAgbGV0IGNlbnRlciwgc2l6ZTtcbiAgICBpZiAocnVsZXIuZ3JvdXBlZCkge1xuICAgICAgY29uc3Qgc3RhY2tDb3VudCA9IHNraXBOdWxsID8gdGhpcy5fZ2V0U3RhY2tDb3VudChpbmRleCkgOiBydWxlci5zdGFja0NvdW50O1xuICAgICAgY29uc3QgcmFuZ2UgPSBvcHRpb25zLmJhclRoaWNrbmVzcyA9PT0gJ2ZsZXgnXG4gICAgICAgID8gY29tcHV0ZUZsZXhDYXRlZ29yeVRyYWl0cyhpbmRleCwgcnVsZXIsIG9wdGlvbnMsIHN0YWNrQ291bnQpXG4gICAgICAgIDogY29tcHV0ZUZpdENhdGVnb3J5VHJhaXRzKGluZGV4LCBydWxlciwgb3B0aW9ucywgc3RhY2tDb3VudCk7XG5cbiAgICAgIGNvbnN0IHN0YWNrSW5kZXggPSB0aGlzLl9nZXRTdGFja0luZGV4KHRoaXMuaW5kZXgsIHRoaXMuX2NhY2hlZE1ldGEuc3RhY2ssIHNraXBOdWxsID8gaW5kZXggOiB1bmRlZmluZWQpO1xuICAgICAgY2VudGVyID0gcmFuZ2Uuc3RhcnQgKyAocmFuZ2UuY2h1bmsgKiBzdGFja0luZGV4KSArIChyYW5nZS5jaHVuayAvIDIpO1xuICAgICAgc2l6ZSA9IE1hdGgubWluKG1heEJhclRoaWNrbmVzcywgcmFuZ2UuY2h1bmsgKiByYW5nZS5yYXRpbyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZvciBub24tZ3JvdXBlZCBiYXIgY2hhcnRzLCBleGFjdCBwaXhlbCB2YWx1ZXMgYXJlIHVzZWRcbiAgICAgIGNlbnRlciA9IHNjYWxlLmdldFBpeGVsRm9yVmFsdWUodGhpcy5nZXRQYXJzZWQoaW5kZXgpW3NjYWxlLmF4aXNdLCBpbmRleCk7XG4gICAgICBzaXplID0gTWF0aC5taW4obWF4QmFyVGhpY2tuZXNzLCBydWxlci5taW4gKiBydWxlci5yYXRpbyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJhc2U6IGNlbnRlciAtIHNpemUgLyAyLFxuICAgICAgaGVhZDogY2VudGVyICsgc2l6ZSAvIDIsXG4gICAgICBjZW50ZXIsXG4gICAgICBzaXplXG4gICAgfTtcbiAgfVxuXG4gIGRyYXcoKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgdlNjYWxlID0gbWV0YS52U2NhbGU7XG4gICAgY29uc3QgcmVjdHMgPSBtZXRhLmRhdGE7XG4gICAgY29uc3QgaWxlbiA9IHJlY3RzLmxlbmd0aDtcbiAgICBsZXQgaSA9IDA7XG5cbiAgICBmb3IgKDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgaWYgKHRoaXMuZ2V0UGFyc2VkKGkpW3ZTY2FsZS5heGlzXSAhPT0gbnVsbCkge1xuICAgICAgICByZWN0c1tpXS5kcmF3KHRoaXMuX2N0eCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbn1cbiIsICJpbXBvcnQgRGF0YXNldENvbnRyb2xsZXIgZnJvbSAnLi4vY29yZS9jb3JlLmRhdGFzZXRDb250cm9sbGVyLmpzJztcbmltcG9ydCB7dmFsdWVPckRlZmF1bHR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnViYmxlQ29udHJvbGxlciBleHRlbmRzIERhdGFzZXRDb250cm9sbGVyIHtcblxuICBzdGF0aWMgaWQgPSAnYnViYmxlJztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICBkYXRhc2V0RWxlbWVudFR5cGU6IGZhbHNlLFxuICAgIGRhdGFFbGVtZW50VHlwZTogJ3BvaW50JyxcblxuICAgIGFuaW1hdGlvbnM6IHtcbiAgICAgIG51bWJlcnM6IHtcbiAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgIHByb3BlcnRpZXM6IFsneCcsICd5JywgJ2JvcmRlcldpZHRoJywgJ3JhZGl1cyddXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIG92ZXJyaWRlcyA9IHtcbiAgICBzY2FsZXM6IHtcbiAgICAgIHg6IHtcbiAgICAgICAgdHlwZTogJ2xpbmVhcidcbiAgICAgIH0sXG4gICAgICB5OiB7XG4gICAgICAgIHR5cGU6ICdsaW5lYXInXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGluaXRpYWxpemUoKSB7XG4gICAgdGhpcy5lbmFibGVPcHRpb25TaGFyaW5nID0gdHJ1ZTtcbiAgICBzdXBlci5pbml0aWFsaXplKCk7XG4gIH1cblxuICAvKipcblx0ICogUGFyc2UgYXJyYXkgb2YgcHJpbWl0aXZlIHZhbHVlc1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBwYXJzZVByaW1pdGl2ZURhdGEobWV0YSwgZGF0YSwgc3RhcnQsIGNvdW50KSB7XG4gICAgY29uc3QgcGFyc2VkID0gc3VwZXIucGFyc2VQcmltaXRpdmVEYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJzZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgIHBhcnNlZFtpXS5fY3VzdG9tID0gdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGkgKyBzdGFydCkucmFkaXVzO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VkO1xuICB9XG5cbiAgLyoqXG5cdCAqIFBhcnNlIGFycmF5IG9mIGFycmF5c1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBwYXJzZUFycmF5RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpIHtcbiAgICBjb25zdCBwYXJzZWQgPSBzdXBlci5wYXJzZUFycmF5RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyc2VkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpdGVtID0gZGF0YVtzdGFydCArIGldO1xuICAgICAgcGFyc2VkW2ldLl9jdXN0b20gPSB2YWx1ZU9yRGVmYXVsdChpdGVtWzJdLCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSArIHN0YXJ0KS5yYWRpdXMpO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VkO1xuICB9XG5cbiAgLyoqXG5cdCAqIFBhcnNlIGFycmF5IG9mIG9iamVjdHNcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgcGFyc2VPYmplY3REYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IHBhcnNlZCA9IHN1cGVyLnBhcnNlT2JqZWN0RGF0YShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyc2VkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpdGVtID0gZGF0YVtzdGFydCArIGldO1xuICAgICAgcGFyc2VkW2ldLl9jdXN0b20gPSB2YWx1ZU9yRGVmYXVsdChpdGVtICYmIGl0ZW0uciAmJiAraXRlbS5yLCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSArIHN0YXJ0KS5yYWRpdXMpO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VkO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldE1heE92ZXJmbG93KCkge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9jYWNoZWRNZXRhLmRhdGE7XG5cbiAgICBsZXQgbWF4ID0gMDtcbiAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgbWF4ID0gTWF0aC5tYXgobWF4LCBkYXRhW2ldLnNpemUodGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGkpKSAvIDIpO1xuICAgIH1cbiAgICByZXR1cm4gbWF4ID4gMCAmJiBtYXg7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0TGFiZWxBbmRWYWx1ZShpbmRleCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGxhYmVscyA9IHRoaXMuY2hhcnQuZGF0YS5sYWJlbHMgfHwgW107XG4gICAgY29uc3Qge3hTY2FsZSwgeVNjYWxlfSA9IG1ldGE7XG4gICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaW5kZXgpO1xuICAgIGNvbnN0IHggPSB4U2NhbGUuZ2V0TGFiZWxGb3JWYWx1ZShwYXJzZWQueCk7XG4gICAgY29uc3QgeSA9IHlTY2FsZS5nZXRMYWJlbEZvclZhbHVlKHBhcnNlZC55KTtcbiAgICBjb25zdCByID0gcGFyc2VkLl9jdXN0b207XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6IGxhYmVsc1tpbmRleF0gfHwgJycsXG4gICAgICB2YWx1ZTogJygnICsgeCArICcsICcgKyB5ICsgKHIgPyAnLCAnICsgciA6ICcnKSArICcpJ1xuICAgIH07XG4gIH1cblxuICB1cGRhdGUobW9kZSkge1xuICAgIGNvbnN0IHBvaW50cyA9IHRoaXMuX2NhY2hlZE1ldGEuZGF0YTtcblxuICAgIC8vIFVwZGF0ZSBQb2ludHNcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKHBvaW50cywgMCwgcG9pbnRzLmxlbmd0aCwgbW9kZSk7XG4gIH1cblxuICB1cGRhdGVFbGVtZW50cyhwb2ludHMsIHN0YXJ0LCBjb3VudCwgbW9kZSkge1xuICAgIGNvbnN0IHJlc2V0ID0gbW9kZSA9PT0gJ3Jlc2V0JztcbiAgICBjb25zdCB7aVNjYWxlLCB2U2NhbGV9ID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCB7c2hhcmVkT3B0aW9ucywgaW5jbHVkZU9wdGlvbnN9ID0gdGhpcy5fZ2V0U2hhcmVkT3B0aW9ucyhzdGFydCwgbW9kZSk7XG4gICAgY29uc3QgaUF4aXMgPSBpU2NhbGUuYXhpcztcbiAgICBjb25zdCB2QXhpcyA9IHZTY2FsZS5heGlzO1xuXG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBjb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgIGNvbnN0IHBhcnNlZCA9ICFyZXNldCAmJiB0aGlzLmdldFBhcnNlZChpKTtcbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB7fTtcbiAgICAgIGNvbnN0IGlQaXhlbCA9IHByb3BlcnRpZXNbaUF4aXNdID0gcmVzZXQgPyBpU2NhbGUuZ2V0UGl4ZWxGb3JEZWNpbWFsKDAuNSkgOiBpU2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShwYXJzZWRbaUF4aXNdKTtcbiAgICAgIGNvbnN0IHZQaXhlbCA9IHByb3BlcnRpZXNbdkF4aXNdID0gcmVzZXQgPyB2U2NhbGUuZ2V0QmFzZVBpeGVsKCkgOiB2U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShwYXJzZWRbdkF4aXNdKTtcblxuICAgICAgcHJvcGVydGllcy5za2lwID0gaXNOYU4oaVBpeGVsKSB8fCBpc05hTih2UGl4ZWwpO1xuXG4gICAgICBpZiAoaW5jbHVkZU9wdGlvbnMpIHtcbiAgICAgICAgcHJvcGVydGllcy5vcHRpb25zID0gc2hhcmVkT3B0aW9ucyB8fCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgcG9pbnQuYWN0aXZlID8gJ2FjdGl2ZScgOiBtb2RlKTtcblxuICAgICAgICBpZiAocmVzZXQpIHtcbiAgICAgICAgICBwcm9wZXJ0aWVzLm9wdGlvbnMucmFkaXVzID0gMDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLnVwZGF0ZUVsZW1lbnQocG9pbnQsIGksIHByb3BlcnRpZXMsIG1vZGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcblx0ICogQHBhcmFtIHtzdHJpbmd9IFttb2RlXVxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICByZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGluZGV4LCBtb2RlKSB7XG4gICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaW5kZXgpO1xuICAgIGxldCB2YWx1ZXMgPSBzdXBlci5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGluZGV4LCBtb2RlKTtcblxuICAgIC8vIEluIGNhc2UgdmFsdWVzIHdlcmUgY2FjaGVkIChhbmQgdGh1cyBmcm96ZW4pLCB3ZSBuZWVkIHRvIGNsb25lIHRoZSB2YWx1ZXNcbiAgICBpZiAodmFsdWVzLiRzaGFyZWQpIHtcbiAgICAgIHZhbHVlcyA9IE9iamVjdC5hc3NpZ24oe30sIHZhbHVlcywgeyRzaGFyZWQ6IGZhbHNlfSk7XG4gICAgfVxuXG4gICAgLy8gQ3VzdG9tIHJhZGl1cyByZXNvbHV0aW9uXG4gICAgY29uc3QgcmFkaXVzID0gdmFsdWVzLnJhZGl1cztcbiAgICBpZiAobW9kZSAhPT0gJ2FjdGl2ZScpIHtcbiAgICAgIHZhbHVlcy5yYWRpdXMgPSAwO1xuICAgIH1cbiAgICB2YWx1ZXMucmFkaXVzICs9IHZhbHVlT3JEZWZhdWx0KHBhcnNlZCAmJiBwYXJzZWQuX2N1c3RvbSwgcmFkaXVzKTtcblxuICAgIHJldHVybiB2YWx1ZXM7XG4gIH1cbn1cbiIsICJpbXBvcnQgRGF0YXNldENvbnRyb2xsZXIgZnJvbSAnLi4vY29yZS9jb3JlLmRhdGFzZXRDb250cm9sbGVyLmpzJztcbmltcG9ydCB7aXNPYmplY3QsIHJlc29sdmVPYmplY3RLZXksIHRvUGVyY2VudGFnZSwgdG9EaW1lbnNpb24sIHZhbHVlT3JEZWZhdWx0fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge2Zvcm1hdE51bWJlcn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmludGwuanMnO1xuaW1wb3J0IHt0b1JhZGlhbnMsIFBJLCBUQVUsIEhBTEZfUEksIF9hbmdsZUJldHdlZW59IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vY29yZS9jb3JlLmNvbnRyb2xsZXIuanMnKS5kZWZhdWx0IH0gQ2hhcnRcbiAqL1xuXG5mdW5jdGlvbiBnZXRSYXRpb0FuZE9mZnNldChyb3RhdGlvbiwgY2lyY3VtZmVyZW5jZSwgY3V0b3V0KSB7XG4gIGxldCByYXRpb1ggPSAxO1xuICBsZXQgcmF0aW9ZID0gMTtcbiAgbGV0IG9mZnNldFggPSAwO1xuICBsZXQgb2Zmc2V0WSA9IDA7XG4gIC8vIElmIHRoZSBjaGFydCdzIGNpcmN1bWZlcmVuY2UgaXNuJ3QgYSBmdWxsIGNpcmNsZSwgY2FsY3VsYXRlIHNpemUgYXMgYSByYXRpbyBvZiB0aGUgd2lkdGgvaGVpZ2h0IG9mIHRoZSBhcmNcbiAgaWYgKGNpcmN1bWZlcmVuY2UgPCBUQVUpIHtcbiAgICBjb25zdCBzdGFydEFuZ2xlID0gcm90YXRpb247XG4gICAgY29uc3QgZW5kQW5nbGUgPSBzdGFydEFuZ2xlICsgY2lyY3VtZmVyZW5jZTtcbiAgICBjb25zdCBzdGFydFggPSBNYXRoLmNvcyhzdGFydEFuZ2xlKTtcbiAgICBjb25zdCBzdGFydFkgPSBNYXRoLnNpbihzdGFydEFuZ2xlKTtcbiAgICBjb25zdCBlbmRYID0gTWF0aC5jb3MoZW5kQW5nbGUpO1xuICAgIGNvbnN0IGVuZFkgPSBNYXRoLnNpbihlbmRBbmdsZSk7XG4gICAgY29uc3QgY2FsY01heCA9IChhbmdsZSwgYSwgYikgPT4gX2FuZ2xlQmV0d2VlbihhbmdsZSwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIHRydWUpID8gMSA6IE1hdGgubWF4KGEsIGEgKiBjdXRvdXQsIGIsIGIgKiBjdXRvdXQpO1xuICAgIGNvbnN0IGNhbGNNaW4gPSAoYW5nbGUsIGEsIGIpID0+IF9hbmdsZUJldHdlZW4oYW5nbGUsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCB0cnVlKSA/IC0xIDogTWF0aC5taW4oYSwgYSAqIGN1dG91dCwgYiwgYiAqIGN1dG91dCk7XG4gICAgY29uc3QgbWF4WCA9IGNhbGNNYXgoMCwgc3RhcnRYLCBlbmRYKTtcbiAgICBjb25zdCBtYXhZID0gY2FsY01heChIQUxGX1BJLCBzdGFydFksIGVuZFkpO1xuICAgIGNvbnN0IG1pblggPSBjYWxjTWluKFBJLCBzdGFydFgsIGVuZFgpO1xuICAgIGNvbnN0IG1pblkgPSBjYWxjTWluKFBJICsgSEFMRl9QSSwgc3RhcnRZLCBlbmRZKTtcbiAgICByYXRpb1ggPSAobWF4WCAtIG1pblgpIC8gMjtcbiAgICByYXRpb1kgPSAobWF4WSAtIG1pblkpIC8gMjtcbiAgICBvZmZzZXRYID0gLShtYXhYICsgbWluWCkgLyAyO1xuICAgIG9mZnNldFkgPSAtKG1heFkgKyBtaW5ZKSAvIDI7XG4gIH1cbiAgcmV0dXJuIHtyYXRpb1gsIHJhdGlvWSwgb2Zmc2V0WCwgb2Zmc2V0WX07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvdWdobnV0Q29udHJvbGxlciBleHRlbmRzIERhdGFzZXRDb250cm9sbGVyIHtcblxuICBzdGF0aWMgaWQgPSAnZG91Z2hudXQnO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIGRhdGFzZXRFbGVtZW50VHlwZTogZmFsc2UsXG4gICAgZGF0YUVsZW1lbnRUeXBlOiAnYXJjJyxcbiAgICBhbmltYXRpb246IHtcbiAgICAgIC8vIEJvb2xlYW4gLSBXaGV0aGVyIHdlIGFuaW1hdGUgdGhlIHJvdGF0aW9uIG9mIHRoZSBEb3VnaG51dFxuICAgICAgYW5pbWF0ZVJvdGF0ZTogdHJ1ZSxcbiAgICAgIC8vIEJvb2xlYW4gLSBXaGV0aGVyIHdlIGFuaW1hdGUgc2NhbGluZyB0aGUgRG91Z2hudXQgZnJvbSB0aGUgY2VudHJlXG4gICAgICBhbmltYXRlU2NhbGU6IGZhbHNlXG4gICAgfSxcbiAgICBhbmltYXRpb25zOiB7XG4gICAgICBudW1iZXJzOiB7XG4gICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICBwcm9wZXJ0aWVzOiBbJ2NpcmN1bWZlcmVuY2UnLCAnZW5kQW5nbGUnLCAnaW5uZXJSYWRpdXMnLCAnb3V0ZXJSYWRpdXMnLCAnc3RhcnRBbmdsZScsICd4JywgJ3knLCAnb2Zmc2V0JywgJ2JvcmRlcldpZHRoJywgJ3NwYWNpbmcnXVxuICAgICAgfSxcbiAgICB9LFxuICAgIC8vIFRoZSBwZXJjZW50YWdlIG9mIHRoZSBjaGFydCB0aGF0IHdlIGN1dCBvdXQgb2YgdGhlIG1pZGRsZS5cbiAgICBjdXRvdXQ6ICc1MCUnLFxuXG4gICAgLy8gVGhlIHJvdGF0aW9uIG9mIHRoZSBjaGFydCwgd2hlcmUgdGhlIGZpcnN0IGRhdGEgYXJjIGJlZ2lucy5cbiAgICByb3RhdGlvbjogMCxcblxuICAgIC8vIFRoZSB0b3RhbCBjaXJjdW1mZXJlbmNlIG9mIHRoZSBjaGFydC5cbiAgICBjaXJjdW1mZXJlbmNlOiAzNjAsXG5cbiAgICAvLyBUaGUgb3V0ZXIgcmFkaXVzIG9mIHRoZSBjaGFydFxuICAgIHJhZGl1czogJzEwMCUnLFxuXG4gICAgLy8gU3BhY2luZyBiZXR3ZWVuIGFyY3NcbiAgICBzcGFjaW5nOiAwLFxuXG4gICAgaW5kZXhBeGlzOiAncicsXG4gIH07XG5cbiAgc3RhdGljIGRlc2NyaXB0b3JzID0ge1xuICAgIF9zY3JpcHRhYmxlOiAobmFtZSkgPT4gbmFtZSAhPT0gJ3NwYWNpbmcnLFxuICAgIF9pbmRleGFibGU6IChuYW1lKSA9PiBuYW1lICE9PSAnc3BhY2luZycgJiYgIW5hbWUuc3RhcnRzV2l0aCgnYm9yZGVyRGFzaCcpICYmICFuYW1lLnN0YXJ0c1dpdGgoJ2hvdmVyQm9yZGVyRGFzaCcpLFxuICB9O1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIG92ZXJyaWRlcyA9IHtcbiAgICBhc3BlY3RSYXRpbzogMSxcblxuICAgIC8vIE5lZWQgdG8gb3ZlcnJpZGUgdGhlc2UgdG8gZ2l2ZSBhIG5pY2UgZGVmYXVsdFxuICAgIHBsdWdpbnM6IHtcbiAgICAgIGxlZ2VuZDoge1xuICAgICAgICBsYWJlbHM6IHtcbiAgICAgICAgICBnZW5lcmF0ZUxhYmVscyhjaGFydCkge1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IGNoYXJ0LmRhdGE7XG4gICAgICAgICAgICBpZiAoZGF0YS5sYWJlbHMubGVuZ3RoICYmIGRhdGEuZGF0YXNldHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHtsYWJlbHM6IHtwb2ludFN0eWxlLCBjb2xvcn19ID0gY2hhcnQubGVnZW5kLm9wdGlvbnM7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIGRhdGEubGFiZWxzLm1hcCgobGFiZWwsIGkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoMCk7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3R5bGUgPSBtZXRhLmNvbnRyb2xsZXIuZ2V0U3R5bGUoaSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgdGV4dDogbGFiZWwsXG4gICAgICAgICAgICAgICAgICBmaWxsU3R5bGU6IHN0eWxlLmJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgICAgICAgIHN0cm9rZVN0eWxlOiBzdHlsZS5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICAgIGZvbnRDb2xvcjogY29sb3IsXG4gICAgICAgICAgICAgICAgICBsaW5lV2lkdGg6IHN0eWxlLmJvcmRlcldpZHRoLFxuICAgICAgICAgICAgICAgICAgcG9pbnRTdHlsZTogcG9pbnRTdHlsZSxcbiAgICAgICAgICAgICAgICAgIGhpZGRlbjogIWNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGkpLFxuXG4gICAgICAgICAgICAgICAgICAvLyBFeHRyYSBkYXRhIHVzZWQgZm9yIHRvZ2dsaW5nIHRoZSBjb3JyZWN0IGl0ZW1cbiAgICAgICAgICAgICAgICAgIGluZGV4OiBpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIG9uQ2xpY2soZSwgbGVnZW5kSXRlbSwgbGVnZW5kKSB7XG4gICAgICAgICAgbGVnZW5kLmNoYXJ0LnRvZ2dsZURhdGFWaXNpYmlsaXR5KGxlZ2VuZEl0ZW0uaW5kZXgpO1xuICAgICAgICAgIGxlZ2VuZC5jaGFydC51cGRhdGUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBjb25zdHJ1Y3RvcihjaGFydCwgZGF0YXNldEluZGV4KSB7XG4gICAgc3VwZXIoY2hhcnQsIGRhdGFzZXRJbmRleCk7XG5cbiAgICB0aGlzLmVuYWJsZU9wdGlvblNoYXJpbmcgPSB0cnVlO1xuICAgIHRoaXMuaW5uZXJSYWRpdXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5vdXRlclJhZGl1cyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm9mZnNldFggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5vZmZzZXRZID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgbGlua1NjYWxlcygpIHt9XG5cbiAgLyoqXG5cdCAqIE92ZXJyaWRlIGRhdGEgcGFyc2luZywgc2luY2Ugd2UgYXJlIG5vdCB1c2luZyBzY2FsZXNcblx0ICovXG4gIHBhcnNlKHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldERhdGFzZXQoKS5kYXRhO1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuXG4gICAgaWYgKHRoaXMuX3BhcnNpbmcgPT09IGZhbHNlKSB7XG4gICAgICBtZXRhLl9wYXJzZWQgPSBkYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgZ2V0dGVyID0gKGkpID0+ICtkYXRhW2ldO1xuXG4gICAgICBpZiAoaXNPYmplY3QoZGF0YVtzdGFydF0pKSB7XG4gICAgICAgIGNvbnN0IHtrZXkgPSAndmFsdWUnfSA9IHRoaXMuX3BhcnNpbmc7XG4gICAgICAgIGdldHRlciA9IChpKSA9PiArcmVzb2x2ZU9iamVjdEtleShkYXRhW2ldLCBrZXkpO1xuICAgICAgfVxuXG4gICAgICBsZXQgaSwgaWxlbjtcbiAgICAgIGZvciAoaSA9IHN0YXJ0LCBpbGVuID0gc3RhcnQgKyBjb3VudDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgICBtZXRhLl9wYXJzZWRbaV0gPSBnZXR0ZXIoaSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0Um90YXRpb24oKSB7XG4gICAgcmV0dXJuIHRvUmFkaWFucyh0aGlzLm9wdGlvbnMucm90YXRpb24gLSA5MCk7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRDaXJjdW1mZXJlbmNlKCkge1xuICAgIHJldHVybiB0b1JhZGlhbnModGhpcy5vcHRpb25zLmNpcmN1bWZlcmVuY2UpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEdldCB0aGUgbWF4aW1hbCByb3RhdGlvbiAmIGNpcmN1bWZlcmVuY2UgZXh0ZW50c1xuXHQgKiBhY3Jvc3MgYWxsIHZpc2libGUgZGF0YXNldHMuXG5cdCAqL1xuICBfZ2V0Um90YXRpb25FeHRlbnRzKCkge1xuICAgIGxldCBtaW4gPSBUQVU7XG4gICAgbGV0IG1heCA9IC1UQVU7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY2hhcnQuZGF0YS5kYXRhc2V0cy5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKHRoaXMuY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShpKSAmJiB0aGlzLmNoYXJ0LmdldERhdGFzZXRNZXRhKGkpLnR5cGUgPT09IHRoaXMuX3R5cGUpIHtcbiAgICAgICAgY29uc3QgY29udHJvbGxlciA9IHRoaXMuY2hhcnQuZ2V0RGF0YXNldE1ldGEoaSkuY29udHJvbGxlcjtcbiAgICAgICAgY29uc3Qgcm90YXRpb24gPSBjb250cm9sbGVyLl9nZXRSb3RhdGlvbigpO1xuICAgICAgICBjb25zdCBjaXJjdW1mZXJlbmNlID0gY29udHJvbGxlci5fZ2V0Q2lyY3VtZmVyZW5jZSgpO1xuXG4gICAgICAgIG1pbiA9IE1hdGgubWluKG1pbiwgcm90YXRpb24pO1xuICAgICAgICBtYXggPSBNYXRoLm1heChtYXgsIHJvdGF0aW9uICsgY2lyY3VtZmVyZW5jZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJvdGF0aW9uOiBtaW4sXG4gICAgICBjaXJjdW1mZXJlbmNlOiBtYXggLSBtaW4sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbW9kZVxuXHQgKi9cbiAgdXBkYXRlKG1vZGUpIHtcbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3Qge2NoYXJ0QXJlYX0gPSBjaGFydDtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBhcmNzID0gbWV0YS5kYXRhO1xuICAgIGNvbnN0IHNwYWNpbmcgPSB0aGlzLmdldE1heEJvcmRlcldpZHRoKCkgKyB0aGlzLmdldE1heE9mZnNldChhcmNzKSArIHRoaXMub3B0aW9ucy5zcGFjaW5nO1xuICAgIGNvbnN0IG1heFNpemUgPSBNYXRoLm1heCgoTWF0aC5taW4oY2hhcnRBcmVhLndpZHRoLCBjaGFydEFyZWEuaGVpZ2h0KSAtIHNwYWNpbmcpIC8gMiwgMCk7XG4gICAgY29uc3QgY3V0b3V0ID0gTWF0aC5taW4odG9QZXJjZW50YWdlKHRoaXMub3B0aW9ucy5jdXRvdXQsIG1heFNpemUpLCAxKTtcbiAgICBjb25zdCBjaGFydFdlaWdodCA9IHRoaXMuX2dldFJpbmdXZWlnaHQodGhpcy5pbmRleCk7XG5cbiAgICAvLyBDb21wdXRlIHRoZSBtYXhpbWFsIHJvdGF0aW9uICYgY2lyY3VtZmVyZW5jZSBsaW1pdHMuXG4gICAgLy8gSWYgd2Ugb25seSBjb25zaWRlciBvdXIgZGF0YXNldCwgdGhpcyBjYW4gY2F1c2UgcHJvYmxlbXMgd2hlbiB0d28gZGF0YXNldHNcbiAgICAvLyBhcmUgYm90aCBsZXNzIHRoYW4gYSBjaXJjbGUgd2l0aCBkaWZmZXJlbnQgcm90YXRpb25zIChzdGFydGluZyBhbmdsZXMpXG4gICAgY29uc3Qge2NpcmN1bWZlcmVuY2UsIHJvdGF0aW9ufSA9IHRoaXMuX2dldFJvdGF0aW9uRXh0ZW50cygpO1xuICAgIGNvbnN0IHtyYXRpb1gsIHJhdGlvWSwgb2Zmc2V0WCwgb2Zmc2V0WX0gPSBnZXRSYXRpb0FuZE9mZnNldChyb3RhdGlvbiwgY2lyY3VtZmVyZW5jZSwgY3V0b3V0KTtcbiAgICBjb25zdCBtYXhXaWR0aCA9IChjaGFydEFyZWEud2lkdGggLSBzcGFjaW5nKSAvIHJhdGlvWDtcbiAgICBjb25zdCBtYXhIZWlnaHQgPSAoY2hhcnRBcmVhLmhlaWdodCAtIHNwYWNpbmcpIC8gcmF0aW9ZO1xuICAgIGNvbnN0IG1heFJhZGl1cyA9IE1hdGgubWF4KE1hdGgubWluKG1heFdpZHRoLCBtYXhIZWlnaHQpIC8gMiwgMCk7XG4gICAgY29uc3Qgb3V0ZXJSYWRpdXMgPSB0b0RpbWVuc2lvbih0aGlzLm9wdGlvbnMucmFkaXVzLCBtYXhSYWRpdXMpO1xuICAgIGNvbnN0IGlubmVyUmFkaXVzID0gTWF0aC5tYXgob3V0ZXJSYWRpdXMgKiBjdXRvdXQsIDApO1xuICAgIGNvbnN0IHJhZGl1c0xlbmd0aCA9IChvdXRlclJhZGl1cyAtIGlubmVyUmFkaXVzKSAvIHRoaXMuX2dldFZpc2libGVEYXRhc2V0V2VpZ2h0VG90YWwoKTtcbiAgICB0aGlzLm9mZnNldFggPSBvZmZzZXRYICogb3V0ZXJSYWRpdXM7XG4gICAgdGhpcy5vZmZzZXRZID0gb2Zmc2V0WSAqIG91dGVyUmFkaXVzO1xuXG4gICAgbWV0YS50b3RhbCA9IHRoaXMuY2FsY3VsYXRlVG90YWwoKTtcblxuICAgIHRoaXMub3V0ZXJSYWRpdXMgPSBvdXRlclJhZGl1cyAtIHJhZGl1c0xlbmd0aCAqIHRoaXMuX2dldFJpbmdXZWlnaHRPZmZzZXQodGhpcy5pbmRleCk7XG4gICAgdGhpcy5pbm5lclJhZGl1cyA9IE1hdGgubWF4KHRoaXMub3V0ZXJSYWRpdXMgLSByYWRpdXNMZW5ndGggKiBjaGFydFdlaWdodCwgMCk7XG5cbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKGFyY3MsIDAsIGFyY3MubGVuZ3RoLCBtb2RlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX2NpcmN1bWZlcmVuY2UoaSwgcmVzZXQpIHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGNpcmN1bWZlcmVuY2UgPSB0aGlzLl9nZXRDaXJjdW1mZXJlbmNlKCk7XG4gICAgaWYgKChyZXNldCAmJiBvcHRzLmFuaW1hdGlvbi5hbmltYXRlUm90YXRlKSB8fCAhdGhpcy5jaGFydC5nZXREYXRhVmlzaWJpbGl0eShpKSB8fCBtZXRhLl9wYXJzZWRbaV0gPT09IG51bGwgfHwgbWV0YS5kYXRhW2ldLmhpZGRlbikge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNhbGN1bGF0ZUNpcmN1bWZlcmVuY2UobWV0YS5fcGFyc2VkW2ldICogY2lyY3VtZmVyZW5jZSAvIFRBVSk7XG4gIH1cblxuICB1cGRhdGVFbGVtZW50cyhhcmNzLCBzdGFydCwgY291bnQsIG1vZGUpIHtcbiAgICBjb25zdCByZXNldCA9IG1vZGUgPT09ICdyZXNldCc7XG4gICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgIGNvbnN0IGNoYXJ0QXJlYSA9IGNoYXJ0LmNoYXJ0QXJlYTtcbiAgICBjb25zdCBvcHRzID0gY2hhcnQub3B0aW9ucztcbiAgICBjb25zdCBhbmltYXRpb25PcHRzID0gb3B0cy5hbmltYXRpb247XG4gICAgY29uc3QgY2VudGVyWCA9IChjaGFydEFyZWEubGVmdCArIGNoYXJ0QXJlYS5yaWdodCkgLyAyO1xuICAgIGNvbnN0IGNlbnRlclkgPSAoY2hhcnRBcmVhLnRvcCArIGNoYXJ0QXJlYS5ib3R0b20pIC8gMjtcbiAgICBjb25zdCBhbmltYXRlU2NhbGUgPSByZXNldCAmJiBhbmltYXRpb25PcHRzLmFuaW1hdGVTY2FsZTtcbiAgICBjb25zdCBpbm5lclJhZGl1cyA9IGFuaW1hdGVTY2FsZSA/IDAgOiB0aGlzLmlubmVyUmFkaXVzO1xuICAgIGNvbnN0IG91dGVyUmFkaXVzID0gYW5pbWF0ZVNjYWxlID8gMCA6IHRoaXMub3V0ZXJSYWRpdXM7XG4gICAgY29uc3Qge3NoYXJlZE9wdGlvbnMsIGluY2x1ZGVPcHRpb25zfSA9IHRoaXMuX2dldFNoYXJlZE9wdGlvbnMoc3RhcnQsIG1vZGUpO1xuICAgIGxldCBzdGFydEFuZ2xlID0gdGhpcy5fZ2V0Um90YXRpb24oKTtcbiAgICBsZXQgaTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBzdGFydDsgKytpKSB7XG4gICAgICBzdGFydEFuZ2xlICs9IHRoaXMuX2NpcmN1bWZlcmVuY2UoaSwgcmVzZXQpO1xuICAgIH1cblxuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBjb3VudDsgKytpKSB7XG4gICAgICBjb25zdCBjaXJjdW1mZXJlbmNlID0gdGhpcy5fY2lyY3VtZmVyZW5jZShpLCByZXNldCk7XG4gICAgICBjb25zdCBhcmMgPSBhcmNzW2ldO1xuICAgICAgY29uc3QgcHJvcGVydGllcyA9IHtcbiAgICAgICAgeDogY2VudGVyWCArIHRoaXMub2Zmc2V0WCxcbiAgICAgICAgeTogY2VudGVyWSArIHRoaXMub2Zmc2V0WSxcbiAgICAgICAgc3RhcnRBbmdsZSxcbiAgICAgICAgZW5kQW5nbGU6IHN0YXJ0QW5nbGUgKyBjaXJjdW1mZXJlbmNlLFxuICAgICAgICBjaXJjdW1mZXJlbmNlLFxuICAgICAgICBvdXRlclJhZGl1cyxcbiAgICAgICAgaW5uZXJSYWRpdXNcbiAgICAgIH07XG4gICAgICBpZiAoaW5jbHVkZU9wdGlvbnMpIHtcbiAgICAgICAgcHJvcGVydGllcy5vcHRpb25zID0gc2hhcmVkT3B0aW9ucyB8fCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgYXJjLmFjdGl2ZSA/ICdhY3RpdmUnIDogbW9kZSk7XG4gICAgICB9XG4gICAgICBzdGFydEFuZ2xlICs9IGNpcmN1bWZlcmVuY2U7XG5cbiAgICAgIHRoaXMudXBkYXRlRWxlbWVudChhcmMsIGksIHByb3BlcnRpZXMsIG1vZGUpO1xuICAgIH1cbiAgfVxuXG4gIGNhbGN1bGF0ZVRvdGFsKCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IG1ldGFEYXRhID0gbWV0YS5kYXRhO1xuICAgIGxldCB0b3RhbCA9IDA7XG4gICAgbGV0IGk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbWV0YURhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gbWV0YS5fcGFyc2VkW2ldO1xuICAgICAgaWYgKHZhbHVlICE9PSBudWxsICYmICFpc05hTih2YWx1ZSkgJiYgdGhpcy5jaGFydC5nZXREYXRhVmlzaWJpbGl0eShpKSAmJiAhbWV0YURhdGFbaV0uaGlkZGVuKSB7XG4gICAgICAgIHRvdGFsICs9IE1hdGguYWJzKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdG90YWw7XG4gIH1cblxuICBjYWxjdWxhdGVDaXJjdW1mZXJlbmNlKHZhbHVlKSB7XG4gICAgY29uc3QgdG90YWwgPSB0aGlzLl9jYWNoZWRNZXRhLnRvdGFsO1xuICAgIGlmICh0b3RhbCA+IDAgJiYgIWlzTmFOKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIFRBVSAqIChNYXRoLmFicyh2YWx1ZSkgLyB0b3RhbCk7XG4gICAgfVxuICAgIHJldHVybiAwO1xuICB9XG5cbiAgZ2V0TGFiZWxBbmRWYWx1ZShpbmRleCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBsYWJlbHMgPSBjaGFydC5kYXRhLmxhYmVscyB8fCBbXTtcbiAgICBjb25zdCB2YWx1ZSA9IGZvcm1hdE51bWJlcihtZXRhLl9wYXJzZWRbaW5kZXhdLCBjaGFydC5vcHRpb25zLmxvY2FsZSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6IGxhYmVsc1tpbmRleF0gfHwgJycsXG4gICAgICB2YWx1ZSxcbiAgICB9O1xuICB9XG5cbiAgZ2V0TWF4Qm9yZGVyV2lkdGgoYXJjcykge1xuICAgIGxldCBtYXggPSAwO1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBsZXQgaSwgaWxlbiwgbWV0YSwgY29udHJvbGxlciwgb3B0aW9ucztcblxuICAgIGlmICghYXJjcykge1xuICAgICAgLy8gRmluZCB0aGUgb3V0bW9zdCB2aXNpYmxlIGRhdGFzZXRcbiAgICAgIGZvciAoaSA9IDAsIGlsZW4gPSBjaGFydC5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgICBpZiAoY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShpKSkge1xuICAgICAgICAgIG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShpKTtcbiAgICAgICAgICBhcmNzID0gbWV0YS5kYXRhO1xuICAgICAgICAgIGNvbnRyb2xsZXIgPSBtZXRhLmNvbnRyb2xsZXI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWFyY3MpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBhcmNzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgb3B0aW9ucyA9IGNvbnRyb2xsZXIucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpKTtcbiAgICAgIGlmIChvcHRpb25zLmJvcmRlckFsaWduICE9PSAnaW5uZXInKSB7XG4gICAgICAgIG1heCA9IE1hdGgubWF4KG1heCwgb3B0aW9ucy5ib3JkZXJXaWR0aCB8fCAwLCBvcHRpb25zLmhvdmVyQm9yZGVyV2lkdGggfHwgMCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXg7XG4gIH1cblxuICBnZXRNYXhPZmZzZXQoYXJjcykge1xuICAgIGxldCBtYXggPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGlsZW4gPSBhcmNzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhpKTtcbiAgICAgIG1heCA9IE1hdGgubWF4KG1heCwgb3B0aW9ucy5vZmZzZXQgfHwgMCwgb3B0aW9ucy5ob3Zlck9mZnNldCB8fCAwKTtcbiAgICB9XG4gICAgcmV0dXJuIG1heDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBHZXQgcmFkaXVzIGxlbmd0aCBvZmZzZXQgb2YgdGhlIGRhdGFzZXQgaW4gcmVsYXRpb24gdG8gdGhlIHZpc2libGUgZGF0YXNldHMgd2VpZ2h0cy4gVGhpcyBhbGxvd3MgZGV0ZXJtaW5pbmcgdGhlIGlubmVyIGFuZCBvdXRlciByYWRpdXMgY29ycmVjdGx5XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0UmluZ1dlaWdodE9mZnNldChkYXRhc2V0SW5kZXgpIHtcbiAgICBsZXQgcmluZ1dlaWdodE9mZnNldCA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGFzZXRJbmRleDsgKytpKSB7XG4gICAgICBpZiAodGhpcy5jaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpKSB7XG4gICAgICAgIHJpbmdXZWlnaHRPZmZzZXQgKz0gdGhpcy5fZ2V0UmluZ1dlaWdodChpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmluZ1dlaWdodE9mZnNldDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldFJpbmdXZWlnaHQoZGF0YXNldEluZGV4KSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KHZhbHVlT3JEZWZhdWx0KHRoaXMuY2hhcnQuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdLndlaWdodCwgMSksIDApO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJldHVybnMgdGhlIHN1bSBvZiBhbGwgdmlzaWJsZSBkYXRhIHNldCB3ZWlnaHRzLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldFZpc2libGVEYXRhc2V0V2VpZ2h0VG90YWwoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldFJpbmdXZWlnaHRPZmZzZXQodGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzLmxlbmd0aCkgfHwgMTtcbiAgfVxufVxuIiwgImltcG9ydCBEYXRhc2V0Q29udHJvbGxlciBmcm9tICcuLi9jb3JlL2NvcmUuZGF0YXNldENvbnRyb2xsZXIuanMnO1xuaW1wb3J0IHtpc051bGxPclVuZGVmfSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcbmltcG9ydCB7aXNOdW1iZXJ9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCB7X2dldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHMsIF9zY2FsZVJhbmdlc0NoYW5nZWR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5leHRyYXMuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaW5lQ29udHJvbGxlciBleHRlbmRzIERhdGFzZXRDb250cm9sbGVyIHtcblxuICBzdGF0aWMgaWQgPSAnbGluZSc7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgZGF0YXNldEVsZW1lbnRUeXBlOiAnbGluZScsXG4gICAgZGF0YUVsZW1lbnRUeXBlOiAncG9pbnQnLFxuXG4gICAgc2hvd0xpbmU6IHRydWUsXG4gICAgc3BhbkdhcHM6IGZhbHNlLFxuICB9O1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIG92ZXJyaWRlcyA9IHtcbiAgICBzY2FsZXM6IHtcbiAgICAgIF9pbmRleF86IHtcbiAgICAgICAgdHlwZTogJ2NhdGVnb3J5JyxcbiAgICAgIH0sXG4gICAgICBfdmFsdWVfOiB7XG4gICAgICAgIHR5cGU6ICdsaW5lYXInLFxuICAgICAgfSxcbiAgICB9XG4gIH07XG5cbiAgaW5pdGlhbGl6ZSgpIHtcbiAgICB0aGlzLmVuYWJsZU9wdGlvblNoYXJpbmcgPSB0cnVlO1xuICAgIHRoaXMuc3VwcG9ydHNEZWNpbWF0aW9uID0gdHJ1ZTtcbiAgICBzdXBlci5pbml0aWFsaXplKCk7XG4gIH1cblxuICB1cGRhdGUobW9kZSkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IHtkYXRhc2V0OiBsaW5lLCBkYXRhOiBwb2ludHMgPSBbXSwgX2RhdGFzZXR9ID0gbWV0YTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY29uc3QgYW5pbWF0aW9uc0Rpc2FibGVkID0gdGhpcy5jaGFydC5fYW5pbWF0aW9uc0Rpc2FibGVkO1xuICAgIGxldCB7c3RhcnQsIGNvdW50fSA9IF9nZXRTdGFydEFuZENvdW50T2ZWaXNpYmxlUG9pbnRzKG1ldGEsIHBvaW50cywgYW5pbWF0aW9uc0Rpc2FibGVkKTtcblxuICAgIHRoaXMuX2RyYXdTdGFydCA9IHN0YXJ0O1xuICAgIHRoaXMuX2RyYXdDb3VudCA9IGNvdW50O1xuXG4gICAgaWYgKF9zY2FsZVJhbmdlc0NoYW5nZWQobWV0YSkpIHtcbiAgICAgIHN0YXJ0ID0gMDtcbiAgICAgIGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgTGluZVxuICAgIGxpbmUuX2NoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBsaW5lLl9kYXRhc2V0SW5kZXggPSB0aGlzLmluZGV4O1xuICAgIGxpbmUuX2RlY2ltYXRlZCA9ICEhX2RhdGFzZXQuX2RlY2ltYXRlZDtcbiAgICBsaW5lLnBvaW50cyA9IHBvaW50cztcblxuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnJlc29sdmVEYXRhc2V0RWxlbWVudE9wdGlvbnMobW9kZSk7XG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuc2hvd0xpbmUpIHtcbiAgICAgIG9wdGlvbnMuYm9yZGVyV2lkdGggPSAwO1xuICAgIH1cbiAgICBvcHRpb25zLnNlZ21lbnQgPSB0aGlzLm9wdGlvbnMuc2VnbWVudDtcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnQobGluZSwgdW5kZWZpbmVkLCB7XG4gICAgICBhbmltYXRlZDogIWFuaW1hdGlvbnNEaXNhYmxlZCxcbiAgICAgIG9wdGlvbnNcbiAgICB9LCBtb2RlKTtcblxuICAgIC8vIFVwZGF0ZSBQb2ludHNcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKHBvaW50cywgc3RhcnQsIGNvdW50LCBtb2RlKTtcbiAgfVxuXG4gIHVwZGF0ZUVsZW1lbnRzKHBvaW50cywgc3RhcnQsIGNvdW50LCBtb2RlKSB7XG4gICAgY29uc3QgcmVzZXQgPSBtb2RlID09PSAncmVzZXQnO1xuICAgIGNvbnN0IHtpU2NhbGUsIHZTY2FsZSwgX3N0YWNrZWQsIF9kYXRhc2V0fSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3Qge3NoYXJlZE9wdGlvbnMsIGluY2x1ZGVPcHRpb25zfSA9IHRoaXMuX2dldFNoYXJlZE9wdGlvbnMoc3RhcnQsIG1vZGUpO1xuICAgIGNvbnN0IGlBeGlzID0gaVNjYWxlLmF4aXM7XG4gICAgY29uc3QgdkF4aXMgPSB2U2NhbGUuYXhpcztcbiAgICBjb25zdCB7c3BhbkdhcHMsIHNlZ21lbnR9ID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IG1heEdhcExlbmd0aCA9IGlzTnVtYmVyKHNwYW5HYXBzKSA/IHNwYW5HYXBzIDogTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgIGNvbnN0IGRpcmVjdFVwZGF0ZSA9IHRoaXMuY2hhcnQuX2FuaW1hdGlvbnNEaXNhYmxlZCB8fCByZXNldCB8fCBtb2RlID09PSAnbm9uZSc7XG4gICAgY29uc3QgZW5kID0gc3RhcnQgKyBjb3VudDtcbiAgICBjb25zdCBwb2ludHNDb3VudCA9IHBvaW50cy5sZW5ndGg7XG4gICAgbGV0IHByZXZQYXJzZWQgPSBzdGFydCA+IDAgJiYgdGhpcy5nZXRQYXJzZWQoc3RhcnQgLSAxKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzQ291bnQ7ICsraSkge1xuICAgICAgY29uc3QgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICBjb25zdCBwcm9wZXJ0aWVzID0gZGlyZWN0VXBkYXRlID8gcG9pbnQgOiB7fTtcblxuICAgICAgaWYgKGkgPCBzdGFydCB8fCBpID49IGVuZCkge1xuICAgICAgICBwcm9wZXJ0aWVzLnNraXAgPSB0cnVlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaSk7XG4gICAgICBjb25zdCBudWxsRGF0YSA9IGlzTnVsbE9yVW5kZWYocGFyc2VkW3ZBeGlzXSk7XG4gICAgICBjb25zdCBpUGl4ZWwgPSBwcm9wZXJ0aWVzW2lBeGlzXSA9IGlTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHBhcnNlZFtpQXhpc10sIGkpO1xuICAgICAgY29uc3QgdlBpeGVsID0gcHJvcGVydGllc1t2QXhpc10gPSByZXNldCB8fCBudWxsRGF0YSA/IHZTY2FsZS5nZXRCYXNlUGl4ZWwoKSA6IHZTY2FsZS5nZXRQaXhlbEZvclZhbHVlKF9zdGFja2VkID8gdGhpcy5hcHBseVN0YWNrKHZTY2FsZSwgcGFyc2VkLCBfc3RhY2tlZCkgOiBwYXJzZWRbdkF4aXNdLCBpKTtcblxuICAgICAgcHJvcGVydGllcy5za2lwID0gaXNOYU4oaVBpeGVsKSB8fCBpc05hTih2UGl4ZWwpIHx8IG51bGxEYXRhO1xuICAgICAgcHJvcGVydGllcy5zdG9wID0gaSA+IDAgJiYgKE1hdGguYWJzKHBhcnNlZFtpQXhpc10gLSBwcmV2UGFyc2VkW2lBeGlzXSkpID4gbWF4R2FwTGVuZ3RoO1xuICAgICAgaWYgKHNlZ21lbnQpIHtcbiAgICAgICAgcHJvcGVydGllcy5wYXJzZWQgPSBwYXJzZWQ7XG4gICAgICAgIHByb3BlcnRpZXMucmF3ID0gX2RhdGFzZXQuZGF0YVtpXTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluY2x1ZGVPcHRpb25zKSB7XG4gICAgICAgIHByb3BlcnRpZXMub3B0aW9ucyA9IHNoYXJlZE9wdGlvbnMgfHwgdGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGksIHBvaW50LmFjdGl2ZSA/ICdhY3RpdmUnIDogbW9kZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghZGlyZWN0VXBkYXRlKSB7XG4gICAgICAgIHRoaXMudXBkYXRlRWxlbWVudChwb2ludCwgaSwgcHJvcGVydGllcywgbW9kZSk7XG4gICAgICB9XG5cbiAgICAgIHByZXZQYXJzZWQgPSBwYXJzZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGdldE1heE92ZXJmbG93KCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGRhdGFzZXQgPSBtZXRhLmRhdGFzZXQ7XG4gICAgY29uc3QgYm9yZGVyID0gZGF0YXNldC5vcHRpb25zICYmIGRhdGFzZXQub3B0aW9ucy5ib3JkZXJXaWR0aCB8fCAwO1xuICAgIGNvbnN0IGRhdGEgPSBtZXRhLmRhdGEgfHwgW107XG4gICAgaWYgKCFkYXRhLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGJvcmRlcjtcbiAgICB9XG4gICAgY29uc3QgZmlyc3RQb2ludCA9IGRhdGFbMF0uc2l6ZSh0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoMCkpO1xuICAgIGNvbnN0IGxhc3RQb2ludCA9IGRhdGFbZGF0YS5sZW5ndGggLSAxXS5zaXplKHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhkYXRhLmxlbmd0aCAtIDEpKTtcbiAgICByZXR1cm4gTWF0aC5tYXgoYm9yZGVyLCBmaXJzdFBvaW50LCBsYXN0UG9pbnQpIC8gMjtcbiAgfVxuXG4gIGRyYXcoKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgbWV0YS5kYXRhc2V0LnVwZGF0ZUNvbnRyb2xQb2ludHModGhpcy5jaGFydC5jaGFydEFyZWEsIG1ldGEuaVNjYWxlLmF4aXMpO1xuICAgIHN1cGVyLmRyYXcoKTtcbiAgfVxufVxuIiwgImltcG9ydCBEYXRhc2V0Q29udHJvbGxlciBmcm9tICcuLi9jb3JlL2NvcmUuZGF0YXNldENvbnRyb2xsZXIuanMnO1xuaW1wb3J0IHt0b1JhZGlhbnMsIFBJLCBmb3JtYXROdW1iZXIsIF9wYXJzZU9iamVjdERhdGFSYWRpYWxTY2FsZX0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBvbGFyQXJlYUNvbnRyb2xsZXIgZXh0ZW5kcyBEYXRhc2V0Q29udHJvbGxlciB7XG5cbiAgc3RhdGljIGlkID0gJ3BvbGFyQXJlYSc7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgZGF0YUVsZW1lbnRUeXBlOiAnYXJjJyxcbiAgICBhbmltYXRpb246IHtcbiAgICAgIGFuaW1hdGVSb3RhdGU6IHRydWUsXG4gICAgICBhbmltYXRlU2NhbGU6IHRydWVcbiAgICB9LFxuICAgIGFuaW1hdGlvbnM6IHtcbiAgICAgIG51bWJlcnM6IHtcbiAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgIHByb3BlcnRpZXM6IFsneCcsICd5JywgJ3N0YXJ0QW5nbGUnLCAnZW5kQW5nbGUnLCAnaW5uZXJSYWRpdXMnLCAnb3V0ZXJSYWRpdXMnXVxuICAgICAgfSxcbiAgICB9LFxuICAgIGluZGV4QXhpczogJ3InLFxuICAgIHN0YXJ0QW5nbGU6IDAsXG4gIH07XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgb3ZlcnJpZGVzID0ge1xuICAgIGFzcGVjdFJhdGlvOiAxLFxuXG4gICAgcGx1Z2luczoge1xuICAgICAgbGVnZW5kOiB7XG4gICAgICAgIGxhYmVsczoge1xuICAgICAgICAgIGdlbmVyYXRlTGFiZWxzKGNoYXJ0KSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0gY2hhcnQuZGF0YTtcbiAgICAgICAgICAgIGlmIChkYXRhLmxhYmVscy5sZW5ndGggJiYgZGF0YS5kYXRhc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3Qge2xhYmVsczoge3BvaW50U3R5bGUsIGNvbG9yfX0gPSBjaGFydC5sZWdlbmQub3B0aW9ucztcblxuICAgICAgICAgICAgICByZXR1cm4gZGF0YS5sYWJlbHMubWFwKChsYWJlbCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YSgwKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHlsZSA9IG1ldGEuY29udHJvbGxlci5nZXRTdHlsZShpKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICB0ZXh0OiBsYWJlbCxcbiAgICAgICAgICAgICAgICAgIGZpbGxTdHlsZTogc3R5bGUuYmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICAgICAgICAgc3Ryb2tlU3R5bGU6IHN0eWxlLmJvcmRlckNvbG9yLFxuICAgICAgICAgICAgICAgICAgZm9udENvbG9yOiBjb2xvcixcbiAgICAgICAgICAgICAgICAgIGxpbmVXaWR0aDogc3R5bGUuYm9yZGVyV2lkdGgsXG4gICAgICAgICAgICAgICAgICBwb2ludFN0eWxlOiBwb2ludFN0eWxlLFxuICAgICAgICAgICAgICAgICAgaGlkZGVuOiAhY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaSksXG5cbiAgICAgICAgICAgICAgICAgIC8vIEV4dHJhIGRhdGEgdXNlZCBmb3IgdG9nZ2xpbmcgdGhlIGNvcnJlY3QgaXRlbVxuICAgICAgICAgICAgICAgICAgaW5kZXg6IGlcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgb25DbGljayhlLCBsZWdlbmRJdGVtLCBsZWdlbmQpIHtcbiAgICAgICAgICBsZWdlbmQuY2hhcnQudG9nZ2xlRGF0YVZpc2liaWxpdHkobGVnZW5kSXRlbS5pbmRleCk7XG4gICAgICAgICAgbGVnZW5kLmNoYXJ0LnVwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIHNjYWxlczoge1xuICAgICAgcjoge1xuICAgICAgICB0eXBlOiAncmFkaWFsTGluZWFyJyxcbiAgICAgICAgYW5nbGVMaW5lczoge1xuICAgICAgICAgIGRpc3BsYXk6IGZhbHNlXG4gICAgICAgIH0sXG4gICAgICAgIGJlZ2luQXRaZXJvOiB0cnVlLFxuICAgICAgICBncmlkOiB7XG4gICAgICAgICAgY2lyY3VsYXI6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgcG9pbnRMYWJlbHM6IHtcbiAgICAgICAgICBkaXNwbGF5OiBmYWxzZVxuICAgICAgICB9LFxuICAgICAgICBzdGFydEFuZ2xlOiAwXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKGNoYXJ0LCBkYXRhc2V0SW5kZXgpIHtcbiAgICBzdXBlcihjaGFydCwgZGF0YXNldEluZGV4KTtcblxuICAgIHRoaXMuaW5uZXJSYWRpdXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5vdXRlclJhZGl1cyA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGdldExhYmVsQW5kVmFsdWUoaW5kZXgpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3QgbGFiZWxzID0gY2hhcnQuZGF0YS5sYWJlbHMgfHwgW107XG4gICAgY29uc3QgdmFsdWUgPSBmb3JtYXROdW1iZXIobWV0YS5fcGFyc2VkW2luZGV4XS5yLCBjaGFydC5vcHRpb25zLmxvY2FsZSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6IGxhYmVsc1tpbmRleF0gfHwgJycsXG4gICAgICB2YWx1ZSxcbiAgICB9O1xuICB9XG5cbiAgcGFyc2VPYmplY3REYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIHJldHVybiBfcGFyc2VPYmplY3REYXRhUmFkaWFsU2NhbGUuYmluZCh0aGlzKShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpO1xuICB9XG5cbiAgdXBkYXRlKG1vZGUpIHtcbiAgICBjb25zdCBhcmNzID0gdGhpcy5fY2FjaGVkTWV0YS5kYXRhO1xuXG4gICAgdGhpcy5fdXBkYXRlUmFkaXVzKCk7XG4gICAgdGhpcy51cGRhdGVFbGVtZW50cyhhcmNzLCAwLCBhcmNzLmxlbmd0aCwgbW9kZSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgZ2V0TWluTWF4KCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IHJhbmdlID0ge21pbjogTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLCBtYXg6IE51bWJlci5ORUdBVElWRV9JTkZJTklUWX07XG5cbiAgICBtZXRhLmRhdGEuZm9yRWFjaCgoZWxlbWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMuZ2V0UGFyc2VkKGluZGV4KS5yO1xuXG4gICAgICBpZiAoIWlzTmFOKHBhcnNlZCkgJiYgdGhpcy5jaGFydC5nZXREYXRhVmlzaWJpbGl0eShpbmRleCkpIHtcbiAgICAgICAgaWYgKHBhcnNlZCA8IHJhbmdlLm1pbikge1xuICAgICAgICAgIHJhbmdlLm1pbiA9IHBhcnNlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJzZWQgPiByYW5nZS5tYXgpIHtcbiAgICAgICAgICByYW5nZS5tYXggPSBwYXJzZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiByYW5nZTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3VwZGF0ZVJhZGl1cygpIHtcbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3QgY2hhcnRBcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xuICAgIGNvbnN0IG9wdHMgPSBjaGFydC5vcHRpb25zO1xuICAgIGNvbnN0IG1pblNpemUgPSBNYXRoLm1pbihjaGFydEFyZWEucmlnaHQgLSBjaGFydEFyZWEubGVmdCwgY2hhcnRBcmVhLmJvdHRvbSAtIGNoYXJ0QXJlYS50b3ApO1xuXG4gICAgY29uc3Qgb3V0ZXJSYWRpdXMgPSBNYXRoLm1heChtaW5TaXplIC8gMiwgMCk7XG4gICAgY29uc3QgaW5uZXJSYWRpdXMgPSBNYXRoLm1heChvcHRzLmN1dG91dFBlcmNlbnRhZ2UgPyAob3V0ZXJSYWRpdXMgLyAxMDApICogKG9wdHMuY3V0b3V0UGVyY2VudGFnZSkgOiAxLCAwKTtcbiAgICBjb25zdCByYWRpdXNMZW5ndGggPSAob3V0ZXJSYWRpdXMgLSBpbm5lclJhZGl1cykgLyBjaGFydC5nZXRWaXNpYmxlRGF0YXNldENvdW50KCk7XG5cbiAgICB0aGlzLm91dGVyUmFkaXVzID0gb3V0ZXJSYWRpdXMgLSAocmFkaXVzTGVuZ3RoICogdGhpcy5pbmRleCk7XG4gICAgdGhpcy5pbm5lclJhZGl1cyA9IHRoaXMub3V0ZXJSYWRpdXMgLSByYWRpdXNMZW5ndGg7XG4gIH1cblxuICB1cGRhdGVFbGVtZW50cyhhcmNzLCBzdGFydCwgY291bnQsIG1vZGUpIHtcbiAgICBjb25zdCByZXNldCA9IG1vZGUgPT09ICdyZXNldCc7XG4gICAgY29uc3QgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgIGNvbnN0IG9wdHMgPSBjaGFydC5vcHRpb25zO1xuICAgIGNvbnN0IGFuaW1hdGlvbk9wdHMgPSBvcHRzLmFuaW1hdGlvbjtcbiAgICBjb25zdCBzY2FsZSA9IHRoaXMuX2NhY2hlZE1ldGEuclNjYWxlO1xuICAgIGNvbnN0IGNlbnRlclggPSBzY2FsZS54Q2VudGVyO1xuICAgIGNvbnN0IGNlbnRlclkgPSBzY2FsZS55Q2VudGVyO1xuICAgIGNvbnN0IGRhdGFzZXRTdGFydEFuZ2xlID0gc2NhbGUuZ2V0SW5kZXhBbmdsZSgwKSAtIDAuNSAqIFBJO1xuICAgIGxldCBhbmdsZSA9IGRhdGFzZXRTdGFydEFuZ2xlO1xuICAgIGxldCBpO1xuXG4gICAgY29uc3QgZGVmYXVsdEFuZ2xlID0gMzYwIC8gdGhpcy5jb3VudFZpc2libGVFbGVtZW50cygpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHN0YXJ0OyArK2kpIHtcbiAgICAgIGFuZ2xlICs9IHRoaXMuX2NvbXB1dGVBbmdsZShpLCBtb2RlLCBkZWZhdWx0QW5nbGUpO1xuICAgIH1cbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IHN0YXJ0ICsgY291bnQ7IGkrKykge1xuICAgICAgY29uc3QgYXJjID0gYXJjc1tpXTtcbiAgICAgIGxldCBzdGFydEFuZ2xlID0gYW5nbGU7XG4gICAgICBsZXQgZW5kQW5nbGUgPSBhbmdsZSArIHRoaXMuX2NvbXB1dGVBbmdsZShpLCBtb2RlLCBkZWZhdWx0QW5nbGUpO1xuICAgICAgbGV0IG91dGVyUmFkaXVzID0gY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaSkgPyBzY2FsZS5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZSh0aGlzLmdldFBhcnNlZChpKS5yKSA6IDA7XG4gICAgICBhbmdsZSA9IGVuZEFuZ2xlO1xuXG4gICAgICBpZiAocmVzZXQpIHtcbiAgICAgICAgaWYgKGFuaW1hdGlvbk9wdHMuYW5pbWF0ZVNjYWxlKSB7XG4gICAgICAgICAgb3V0ZXJSYWRpdXMgPSAwO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhbmltYXRpb25PcHRzLmFuaW1hdGVSb3RhdGUpIHtcbiAgICAgICAgICBzdGFydEFuZ2xlID0gZW5kQW5nbGUgPSBkYXRhc2V0U3RhcnRBbmdsZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBwcm9wZXJ0aWVzID0ge1xuICAgICAgICB4OiBjZW50ZXJYLFxuICAgICAgICB5OiBjZW50ZXJZLFxuICAgICAgICBpbm5lclJhZGl1czogMCxcbiAgICAgICAgb3V0ZXJSYWRpdXMsXG4gICAgICAgIHN0YXJ0QW5nbGUsXG4gICAgICAgIGVuZEFuZ2xlLFxuICAgICAgICBvcHRpb25zOiB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgYXJjLmFjdGl2ZSA/ICdhY3RpdmUnIDogbW9kZSlcbiAgICAgIH07XG5cbiAgICAgIHRoaXMudXBkYXRlRWxlbWVudChhcmMsIGksIHByb3BlcnRpZXMsIG1vZGUpO1xuICAgIH1cbiAgfVxuXG4gIGNvdW50VmlzaWJsZUVsZW1lbnRzKCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGxldCBjb3VudCA9IDA7XG5cbiAgICBtZXRhLmRhdGEuZm9yRWFjaCgoZWxlbWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGlmICghaXNOYU4odGhpcy5nZXRQYXJzZWQoaW5kZXgpLnIpICYmIHRoaXMuY2hhcnQuZ2V0RGF0YVZpc2liaWxpdHkoaW5kZXgpKSB7XG4gICAgICAgIGNvdW50Kys7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY291bnQ7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9jb21wdXRlQW5nbGUoaW5kZXgsIG1vZGUsIGRlZmF1bHRBbmdsZSkge1xuICAgIHJldHVybiB0aGlzLmNoYXJ0LmdldERhdGFWaXNpYmlsaXR5KGluZGV4KVxuICAgICAgPyB0b1JhZGlhbnModGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGluZGV4LCBtb2RlKS5hbmdsZSB8fCBkZWZhdWx0QW5nbGUpXG4gICAgICA6IDA7XG4gIH1cbn1cbiIsICJpbXBvcnQgRG91Z2hudXRDb250cm9sbGVyIGZyb20gJy4vY29udHJvbGxlci5kb3VnaG51dC5qcyc7XG5cbi8vIFBpZSBjaGFydHMgYXJlIERvdWdobnV0IGNoYXJ0IHdpdGggZGlmZmVyZW50IGRlZmF1bHRzXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQaWVDb250cm9sbGVyIGV4dGVuZHMgRG91Z2hudXRDb250cm9sbGVyIHtcblxuICBzdGF0aWMgaWQgPSAncGllJztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICAvLyBUaGUgcGVyY2VudGFnZSBvZiB0aGUgY2hhcnQgdGhhdCB3ZSBjdXQgb3V0IG9mIHRoZSBtaWRkbGUuXG4gICAgY3V0b3V0OiAwLFxuXG4gICAgLy8gVGhlIHJvdGF0aW9uIG9mIHRoZSBjaGFydCwgd2hlcmUgdGhlIGZpcnN0IGRhdGEgYXJjIGJlZ2lucy5cbiAgICByb3RhdGlvbjogMCxcblxuICAgIC8vIFRoZSB0b3RhbCBjaXJjdW1mZXJlbmNlIG9mIHRoZSBjaGFydC5cbiAgICBjaXJjdW1mZXJlbmNlOiAzNjAsXG5cbiAgICAvLyBUaGUgb3V0ZXIgcmFkaXVzIG9mIHRoZSBjaGFydFxuICAgIHJhZGl1czogJzEwMCUnXG4gIH07XG59XG4iLCAiaW1wb3J0IERhdGFzZXRDb250cm9sbGVyIGZyb20gJy4uL2NvcmUvY29yZS5kYXRhc2V0Q29udHJvbGxlci5qcyc7XG5pbXBvcnQge19wYXJzZU9iamVjdERhdGFSYWRpYWxTY2FsZX0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJhZGFyQ29udHJvbGxlciBleHRlbmRzIERhdGFzZXRDb250cm9sbGVyIHtcblxuICBzdGF0aWMgaWQgPSAncmFkYXInO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIGRhdGFzZXRFbGVtZW50VHlwZTogJ2xpbmUnLFxuICAgIGRhdGFFbGVtZW50VHlwZTogJ3BvaW50JyxcbiAgICBpbmRleEF4aXM6ICdyJyxcbiAgICBzaG93TGluZTogdHJ1ZSxcbiAgICBlbGVtZW50czoge1xuICAgICAgbGluZToge1xuICAgICAgICBmaWxsOiAnc3RhcnQnXG4gICAgICB9XG4gICAgfSxcbiAgfTtcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBvdmVycmlkZXMgPSB7XG4gICAgYXNwZWN0UmF0aW86IDEsXG5cbiAgICBzY2FsZXM6IHtcbiAgICAgIHI6IHtcbiAgICAgICAgdHlwZTogJ3JhZGlhbExpbmVhcicsXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRMYWJlbEFuZFZhbHVlKGluZGV4KSB7XG4gICAgY29uc3QgdlNjYWxlID0gdGhpcy5fY2FjaGVkTWV0YS52U2NhbGU7XG4gICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaW5kZXgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGxhYmVsOiB2U2NhbGUuZ2V0TGFiZWxzKClbaW5kZXhdLFxuICAgICAgdmFsdWU6ICcnICsgdlNjYWxlLmdldExhYmVsRm9yVmFsdWUocGFyc2VkW3ZTY2FsZS5heGlzXSlcbiAgICB9O1xuICB9XG5cbiAgcGFyc2VPYmplY3REYXRhKG1ldGEsIGRhdGEsIHN0YXJ0LCBjb3VudCkge1xuICAgIHJldHVybiBfcGFyc2VPYmplY3REYXRhUmFkaWFsU2NhbGUuYmluZCh0aGlzKShtZXRhLCBkYXRhLCBzdGFydCwgY291bnQpO1xuICB9XG5cbiAgdXBkYXRlKG1vZGUpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBsaW5lID0gbWV0YS5kYXRhc2V0O1xuICAgIGNvbnN0IHBvaW50cyA9IG1ldGEuZGF0YSB8fCBbXTtcbiAgICBjb25zdCBsYWJlbHMgPSBtZXRhLmlTY2FsZS5nZXRMYWJlbHMoKTtcblxuICAgIC8vIFVwZGF0ZSBMaW5lXG4gICAgbGluZS5wb2ludHMgPSBwb2ludHM7XG4gICAgLy8gSW4gcmVzaXplIG1vZGUgb25seSBwb2ludCBsb2NhdGlvbnMgY2hhbmdlLCBzbyBubyBuZWVkIHRvIHNldCB0aGUgcG9pbnRzIG9yIG9wdGlvbnMuXG4gICAgaWYgKG1vZGUgIT09ICdyZXNpemUnKSB7XG4gICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5yZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zKG1vZGUpO1xuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuc2hvd0xpbmUpIHtcbiAgICAgICAgb3B0aW9ucy5ib3JkZXJXaWR0aCA9IDA7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB7XG4gICAgICAgIF9sb29wOiB0cnVlLFxuICAgICAgICBfZnVsbExvb3A6IGxhYmVscy5sZW5ndGggPT09IHBvaW50cy5sZW5ndGgsXG4gICAgICAgIG9wdGlvbnNcbiAgICAgIH07XG5cbiAgICAgIHRoaXMudXBkYXRlRWxlbWVudChsaW5lLCB1bmRlZmluZWQsIHByb3BlcnRpZXMsIG1vZGUpO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSBQb2ludHNcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKHBvaW50cywgMCwgcG9pbnRzLmxlbmd0aCwgbW9kZSk7XG4gIH1cblxuICB1cGRhdGVFbGVtZW50cyhwb2ludHMsIHN0YXJ0LCBjb3VudCwgbW9kZSkge1xuICAgIGNvbnN0IHNjYWxlID0gdGhpcy5fY2FjaGVkTWV0YS5yU2NhbGU7XG4gICAgY29uc3QgcmVzZXQgPSBtb2RlID09PSAncmVzZXQnO1xuXG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgc3RhcnQgKyBjb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgcG9pbnQuYWN0aXZlID8gJ2FjdGl2ZScgOiBtb2RlKTtcbiAgICAgIGNvbnN0IHBvaW50UG9zaXRpb24gPSBzY2FsZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUoaSwgdGhpcy5nZXRQYXJzZWQoaSkucik7XG5cbiAgICAgIGNvbnN0IHggPSByZXNldCA/IHNjYWxlLnhDZW50ZXIgOiBwb2ludFBvc2l0aW9uLng7XG4gICAgICBjb25zdCB5ID0gcmVzZXQgPyBzY2FsZS55Q2VudGVyIDogcG9pbnRQb3NpdGlvbi55O1xuXG4gICAgICBjb25zdCBwcm9wZXJ0aWVzID0ge1xuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgICBhbmdsZTogcG9pbnRQb3NpdGlvbi5hbmdsZSxcbiAgICAgICAgc2tpcDogaXNOYU4oeCkgfHwgaXNOYU4oeSksXG4gICAgICAgIG9wdGlvbnNcbiAgICAgIH07XG5cbiAgICAgIHRoaXMudXBkYXRlRWxlbWVudChwb2ludCwgaSwgcHJvcGVydGllcywgbW9kZSk7XG4gICAgfVxuICB9XG59XG4iLCAiaW1wb3J0IERhdGFzZXRDb250cm9sbGVyIGZyb20gJy4uL2NvcmUvY29yZS5kYXRhc2V0Q29udHJvbGxlci5qcyc7XG5pbXBvcnQge2lzTnVsbE9yVW5kZWZ9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuaW1wb3J0IHtpc051bWJlcn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IHtfZ2V0U3RhcnRBbmRDb3VudE9mVmlzaWJsZVBvaW50cywgX3NjYWxlUmFuZ2VzQ2hhbmdlZH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmV4dHJhcy5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNjYXR0ZXJDb250cm9sbGVyIGV4dGVuZHMgRGF0YXNldENvbnRyb2xsZXIge1xuXG4gIHN0YXRpYyBpZCA9ICdzY2F0dGVyJztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICBkYXRhc2V0RWxlbWVudFR5cGU6IGZhbHNlLFxuICAgIGRhdGFFbGVtZW50VHlwZTogJ3BvaW50JyxcbiAgICBzaG93TGluZTogZmFsc2UsXG4gICAgZmlsbDogZmFsc2VcbiAgfTtcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBvdmVycmlkZXMgPSB7XG5cbiAgICBpbnRlcmFjdGlvbjoge1xuICAgICAgbW9kZTogJ3BvaW50J1xuICAgIH0sXG5cbiAgICBzY2FsZXM6IHtcbiAgICAgIHg6IHtcbiAgICAgICAgdHlwZTogJ2xpbmVhcidcbiAgICAgIH0sXG4gICAgICB5OiB7XG4gICAgICAgIHR5cGU6ICdsaW5lYXInXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRMYWJlbEFuZFZhbHVlKGluZGV4KSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuX2NhY2hlZE1ldGE7XG4gICAgY29uc3QgbGFiZWxzID0gdGhpcy5jaGFydC5kYXRhLmxhYmVscyB8fCBbXTtcbiAgICBjb25zdCB7eFNjYWxlLCB5U2NhbGV9ID0gbWV0YTtcbiAgICBjb25zdCBwYXJzZWQgPSB0aGlzLmdldFBhcnNlZChpbmRleCk7XG4gICAgY29uc3QgeCA9IHhTY2FsZS5nZXRMYWJlbEZvclZhbHVlKHBhcnNlZC54KTtcbiAgICBjb25zdCB5ID0geVNjYWxlLmdldExhYmVsRm9yVmFsdWUocGFyc2VkLnkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGxhYmVsOiBsYWJlbHNbaW5kZXhdIHx8ICcnLFxuICAgICAgdmFsdWU6ICcoJyArIHggKyAnLCAnICsgeSArICcpJ1xuICAgIH07XG4gIH1cblxuICB1cGRhdGUobW9kZSkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IHtkYXRhOiBwb2ludHMgPSBbXX0gPSBtZXRhO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBjb25zdCBhbmltYXRpb25zRGlzYWJsZWQgPSB0aGlzLmNoYXJ0Ll9hbmltYXRpb25zRGlzYWJsZWQ7XG4gICAgbGV0IHtzdGFydCwgY291bnR9ID0gX2dldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHMobWV0YSwgcG9pbnRzLCBhbmltYXRpb25zRGlzYWJsZWQpO1xuXG4gICAgdGhpcy5fZHJhd1N0YXJ0ID0gc3RhcnQ7XG4gICAgdGhpcy5fZHJhd0NvdW50ID0gY291bnQ7XG5cbiAgICBpZiAoX3NjYWxlUmFuZ2VzQ2hhbmdlZChtZXRhKSkge1xuICAgICAgc3RhcnQgPSAwO1xuICAgICAgY291bnQgPSBwb2ludHMubGVuZ3RoO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd0xpbmUpIHtcblxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzExMzMzXG4gICAgICBpZiAoIXRoaXMuZGF0YXNldEVsZW1lbnRUeXBlKSB7XG4gICAgICAgIHRoaXMuYWRkRWxlbWVudHMoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHtkYXRhc2V0OiBsaW5lLCBfZGF0YXNldH0gPSBtZXRhO1xuXG4gICAgICAvLyBVcGRhdGUgTGluZVxuICAgICAgbGluZS5fY2hhcnQgPSB0aGlzLmNoYXJ0O1xuICAgICAgbGluZS5fZGF0YXNldEluZGV4ID0gdGhpcy5pbmRleDtcbiAgICAgIGxpbmUuX2RlY2ltYXRlZCA9ICEhX2RhdGFzZXQuX2RlY2ltYXRlZDtcbiAgICAgIGxpbmUucG9pbnRzID0gcG9pbnRzO1xuXG4gICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5yZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zKG1vZGUpO1xuICAgICAgb3B0aW9ucy5zZWdtZW50ID0gdGhpcy5vcHRpb25zLnNlZ21lbnQ7XG4gICAgICB0aGlzLnVwZGF0ZUVsZW1lbnQobGluZSwgdW5kZWZpbmVkLCB7XG4gICAgICAgIGFuaW1hdGVkOiAhYW5pbWF0aW9uc0Rpc2FibGVkLFxuICAgICAgICBvcHRpb25zXG4gICAgICB9LCBtb2RlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZGF0YXNldEVsZW1lbnRUeXBlKSB7XG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMTEzMzNcbiAgICAgIGRlbGV0ZSBtZXRhLmRhdGFzZXQ7XG4gICAgICB0aGlzLmRhdGFzZXRFbGVtZW50VHlwZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSBQb2ludHNcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKHBvaW50cywgc3RhcnQsIGNvdW50LCBtb2RlKTtcbiAgfVxuXG4gIGFkZEVsZW1lbnRzKCkge1xuICAgIGNvbnN0IHtzaG93TGluZX0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICBpZiAoIXRoaXMuZGF0YXNldEVsZW1lbnRUeXBlICYmIHNob3dMaW5lKSB7XG4gICAgICB0aGlzLmRhdGFzZXRFbGVtZW50VHlwZSA9IHRoaXMuY2hhcnQucmVnaXN0cnkuZ2V0RWxlbWVudCgnbGluZScpO1xuICAgIH1cblxuICAgIHN1cGVyLmFkZEVsZW1lbnRzKCk7XG4gIH1cblxuICB1cGRhdGVFbGVtZW50cyhwb2ludHMsIHN0YXJ0LCBjb3VudCwgbW9kZSkge1xuICAgIGNvbnN0IHJlc2V0ID0gbW9kZSA9PT0gJ3Jlc2V0JztcbiAgICBjb25zdCB7aVNjYWxlLCB2U2NhbGUsIF9zdGFja2VkLCBfZGF0YXNldH0gPSB0aGlzLl9jYWNoZWRNZXRhO1xuICAgIGNvbnN0IGZpcnN0T3B0cyA9IHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhzdGFydCwgbW9kZSk7XG4gICAgY29uc3Qgc2hhcmVkT3B0aW9ucyA9IHRoaXMuZ2V0U2hhcmVkT3B0aW9ucyhmaXJzdE9wdHMpO1xuICAgIGNvbnN0IGluY2x1ZGVPcHRpb25zID0gdGhpcy5pbmNsdWRlT3B0aW9ucyhtb2RlLCBzaGFyZWRPcHRpb25zKTtcbiAgICBjb25zdCBpQXhpcyA9IGlTY2FsZS5heGlzO1xuICAgIGNvbnN0IHZBeGlzID0gdlNjYWxlLmF4aXM7XG4gICAgY29uc3Qge3NwYW5HYXBzLCBzZWdtZW50fSA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBtYXhHYXBMZW5ndGggPSBpc051bWJlcihzcGFuR2FwcykgPyBzcGFuR2FwcyA6IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbiAgICBjb25zdCBkaXJlY3RVcGRhdGUgPSB0aGlzLmNoYXJ0Ll9hbmltYXRpb25zRGlzYWJsZWQgfHwgcmVzZXQgfHwgbW9kZSA9PT0gJ25vbmUnO1xuICAgIGxldCBwcmV2UGFyc2VkID0gc3RhcnQgPiAwICYmIHRoaXMuZ2V0UGFyc2VkKHN0YXJ0IC0gMSk7XG5cbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBzdGFydCArIGNvdW50OyArK2kpIHtcbiAgICAgIGNvbnN0IHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5nZXRQYXJzZWQoaSk7XG4gICAgICBjb25zdCBwcm9wZXJ0aWVzID0gZGlyZWN0VXBkYXRlID8gcG9pbnQgOiB7fTtcbiAgICAgIGNvbnN0IG51bGxEYXRhID0gaXNOdWxsT3JVbmRlZihwYXJzZWRbdkF4aXNdKTtcbiAgICAgIGNvbnN0IGlQaXhlbCA9IHByb3BlcnRpZXNbaUF4aXNdID0gaVNjYWxlLmdldFBpeGVsRm9yVmFsdWUocGFyc2VkW2lBeGlzXSwgaSk7XG4gICAgICBjb25zdCB2UGl4ZWwgPSBwcm9wZXJ0aWVzW3ZBeGlzXSA9IHJlc2V0IHx8IG51bGxEYXRhID8gdlNjYWxlLmdldEJhc2VQaXhlbCgpIDogdlNjYWxlLmdldFBpeGVsRm9yVmFsdWUoX3N0YWNrZWQgPyB0aGlzLmFwcGx5U3RhY2sodlNjYWxlLCBwYXJzZWQsIF9zdGFja2VkKSA6IHBhcnNlZFt2QXhpc10sIGkpO1xuXG4gICAgICBwcm9wZXJ0aWVzLnNraXAgPSBpc05hTihpUGl4ZWwpIHx8IGlzTmFOKHZQaXhlbCkgfHwgbnVsbERhdGE7XG4gICAgICBwcm9wZXJ0aWVzLnN0b3AgPSBpID4gMCAmJiAoTWF0aC5hYnMocGFyc2VkW2lBeGlzXSAtIHByZXZQYXJzZWRbaUF4aXNdKSkgPiBtYXhHYXBMZW5ndGg7XG4gICAgICBpZiAoc2VnbWVudCkge1xuICAgICAgICBwcm9wZXJ0aWVzLnBhcnNlZCA9IHBhcnNlZDtcbiAgICAgICAgcHJvcGVydGllcy5yYXcgPSBfZGF0YXNldC5kYXRhW2ldO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5jbHVkZU9wdGlvbnMpIHtcbiAgICAgICAgcHJvcGVydGllcy5vcHRpb25zID0gc2hhcmVkT3B0aW9ucyB8fCB0aGlzLnJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoaSwgcG9pbnQuYWN0aXZlID8gJ2FjdGl2ZScgOiBtb2RlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFkaXJlY3RVcGRhdGUpIHtcbiAgICAgICAgdGhpcy51cGRhdGVFbGVtZW50KHBvaW50LCBpLCBwcm9wZXJ0aWVzLCBtb2RlKTtcbiAgICAgIH1cblxuICAgICAgcHJldlBhcnNlZCA9IHBhcnNlZDtcbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZVNoYXJlZE9wdGlvbnMoc2hhcmVkT3B0aW9ucywgbW9kZSwgZmlyc3RPcHRzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXRNYXhPdmVyZmxvdygpIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5fY2FjaGVkTWV0YTtcbiAgICBjb25zdCBkYXRhID0gbWV0YS5kYXRhIHx8IFtdO1xuXG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuc2hvd0xpbmUpIHtcbiAgICAgIGxldCBtYXggPSAwO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgbWF4ID0gTWF0aC5tYXgobWF4LCBkYXRhW2ldLnNpemUodGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGkpKSAvIDIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1heCA+IDAgJiYgbWF4O1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGFzZXQgPSBtZXRhLmRhdGFzZXQ7XG4gICAgY29uc3QgYm9yZGVyID0gZGF0YXNldC5vcHRpb25zICYmIGRhdGFzZXQub3B0aW9ucy5ib3JkZXJXaWR0aCB8fCAwO1xuXG4gICAgaWYgKCFkYXRhLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGJvcmRlcjtcbiAgICB9XG5cbiAgICBjb25zdCBmaXJzdFBvaW50ID0gZGF0YVswXS5zaXplKHRoaXMucmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucygwKSk7XG4gICAgY29uc3QgbGFzdFBvaW50ID0gZGF0YVtkYXRhLmxlbmd0aCAtIDFdLnNpemUodGhpcy5yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGRhdGEubGVuZ3RoIC0gMSkpO1xuICAgIHJldHVybiBNYXRoLm1heChib3JkZXIsIGZpcnN0UG9pbnQsIGxhc3RQb2ludCkgLyAyO1xuICB9XG59XG4iLCAiLyoqXG4gKiBAbmFtZXNwYWNlIENoYXJ0Ll9hZGFwdGVyc1xuICogQHNpbmNlIDIuOC4wXG4gKiBAcHJpdmF0ZVxuICovXG5cbmltcG9ydCB0eXBlIHtBbnlPYmplY3R9IGZyb20gJy4uL3R5cGVzL2Jhc2ljLmpzJztcbmltcG9ydCB0eXBlIHtDaGFydE9wdGlvbnN9IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcblxuZXhwb3J0IHR5cGUgVGltZVVuaXQgPSAnbWlsbGlzZWNvbmQnIHwgJ3NlY29uZCcgfCAnbWludXRlJyB8ICdob3VyJyB8ICdkYXknIHwgJ3dlZWsnIHwgJ21vbnRoJyB8ICdxdWFydGVyJyB8ICd5ZWFyJztcblxuZXhwb3J0IGludGVyZmFjZSBEYXRlQWRhcHRlcjxUIGV4dGVuZHMgQW55T2JqZWN0ID0gQW55T2JqZWN0PiB7XG4gIHJlYWRvbmx5IG9wdGlvbnM6IFQ7XG4gIC8qKlxuICAgKiBXaWxsIGNhbGxlZCB3aXRoIGNoYXJ0IG9wdGlvbnMgYWZ0ZXIgYWRhcHRlciBjcmVhdGlvbi5cbiAgICovXG4gIGluaXQodGhpczogRGF0ZUFkYXB0ZXI8VD4sIGNoYXJ0T3B0aW9uczogQ2hhcnRPcHRpb25zKTogdm9pZDtcbiAgLyoqXG4gICAqIFJldHVybnMgYSBtYXAgb2YgdGltZSBmb3JtYXRzIGZvciB0aGUgc3VwcG9ydGVkIGZvcm1hdHRpbmcgdW5pdHMgZGVmaW5lZFxuICAgKiBpbiBVbml0IGFzIHdlbGwgYXMgJ2RhdGV0aW1lJyByZXByZXNlbnRpbmcgYSBkZXRhaWxlZCBkYXRlL3RpbWUgc3RyaW5nLlxuICAgKi9cbiAgZm9ybWF0cyh0aGlzOiBEYXRlQWRhcHRlcjxUPik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIC8qKlxuICAgKiBQYXJzZXMgdGhlIGdpdmVuIGB2YWx1ZWAgYW5kIHJldHVybiB0aGUgYXNzb2NpYXRlZCB0aW1lc3RhbXAuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIHRoZSB2YWx1ZSB0byBwYXJzZSAodXN1YWxseSBjb21lcyBmcm9tIHRoZSBkYXRhKVxuICAgKiBAcGFyYW0gW2Zvcm1hdF0gLSB0aGUgZXhwZWN0ZWQgZGF0YSBmb3JtYXRcbiAgICovXG4gIHBhcnNlKHRoaXM6IERhdGVBZGFwdGVyPFQ+LCB2YWx1ZTogdW5rbm93biwgZm9ybWF0PzogVGltZVVuaXQpOiBudW1iZXIgfCBudWxsO1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgZm9ybWF0dGVkIGRhdGUgaW4gdGhlIHNwZWNpZmllZCBgZm9ybWF0YCBmb3IgYSBnaXZlbiBgdGltZXN0YW1wYC5cbiAgICogQHBhcmFtIHRpbWVzdGFtcCAtIHRoZSB0aW1lc3RhbXAgdG8gZm9ybWF0XG4gICAqIEBwYXJhbSBmb3JtYXQgLSB0aGUgZGF0ZS90aW1lIHRva2VuXG4gICAqL1xuICBmb3JtYXQodGhpczogRGF0ZUFkYXB0ZXI8VD4sIHRpbWVzdGFtcDogbnVtYmVyLCBmb3JtYXQ6IFRpbWVVbml0KTogc3RyaW5nO1xuICAvKipcbiAgICogQWRkcyB0aGUgc3BlY2lmaWVkIGBhbW91bnRgIG9mIGB1bml0YCB0byB0aGUgZ2l2ZW4gYHRpbWVzdGFtcGAuXG4gICAqIEBwYXJhbSB0aW1lc3RhbXAgLSB0aGUgaW5wdXQgdGltZXN0YW1wXG4gICAqIEBwYXJhbSBhbW91bnQgLSB0aGUgYW1vdW50IHRvIGFkZFxuICAgKiBAcGFyYW0gdW5pdCAtIHRoZSB1bml0IGFzIHN0cmluZ1xuICAgKi9cbiAgYWRkKHRoaXM6IERhdGVBZGFwdGVyPFQ+LCB0aW1lc3RhbXA6IG51bWJlciwgYW1vdW50OiBudW1iZXIsIHVuaXQ6IFRpbWVVbml0KTogbnVtYmVyO1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGB1bml0YCBiZXR3ZWVuIHRoZSBnaXZlbiB0aW1lc3RhbXBzLlxuICAgKiBAcGFyYW0gYSAtIHRoZSBpbnB1dCB0aW1lc3RhbXAgKHJlZmVyZW5jZSlcbiAgICogQHBhcmFtIGIgLSB0aGUgdGltZXN0YW1wIHRvIHN1YnRyYWN0XG4gICAqIEBwYXJhbSB1bml0IC0gdGhlIHVuaXQgYXMgc3RyaW5nXG4gICAqL1xuICBkaWZmKHRoaXM6IERhdGVBZGFwdGVyPFQ+LCBhOiBudW1iZXIsIGI6IG51bWJlciwgdW5pdDogVGltZVVuaXQpOiBudW1iZXI7XG4gIC8qKlxuICAgKiBSZXR1cm5zIHN0YXJ0IG9mIGB1bml0YCBmb3IgdGhlIGdpdmVuIGB0aW1lc3RhbXBgLlxuICAgKiBAcGFyYW0gdGltZXN0YW1wIC0gdGhlIGlucHV0IHRpbWVzdGFtcFxuICAgKiBAcGFyYW0gdW5pdCAtIHRoZSB1bml0IGFzIHN0cmluZ1xuICAgKiBAcGFyYW0gW3dlZWtkYXldIC0gdGhlIElTTyBkYXkgb2YgdGhlIHdlZWsgd2l0aCAxIGJlaW5nIE1vbmRheVxuICAgKiBhbmQgNyBiZWluZyBTdW5kYXkgKG9ubHkgbmVlZGVkIGlmIHBhcmFtICp1bml0KiBpcyBgaXNvV2Vla2ApLlxuICAgKi9cbiAgc3RhcnRPZih0aGlzOiBEYXRlQWRhcHRlcjxUPiwgdGltZXN0YW1wOiBudW1iZXIsIHVuaXQ6IFRpbWVVbml0IHwgJ2lzb1dlZWsnLCB3ZWVrZGF5PzogbnVtYmVyKTogbnVtYmVyO1xuICAvKipcbiAgICogUmV0dXJucyBlbmQgb2YgYHVuaXRgIGZvciB0aGUgZ2l2ZW4gYHRpbWVzdGFtcGAuXG4gICAqIEBwYXJhbSB0aW1lc3RhbXAgLSB0aGUgaW5wdXQgdGltZXN0YW1wXG4gICAqIEBwYXJhbSB1bml0IC0gdGhlIHVuaXQgYXMgc3RyaW5nXG4gICAqL1xuICBlbmRPZih0aGlzOiBEYXRlQWRhcHRlcjxUPiwgdGltZXN0YW1wOiBudW1iZXIsIHVuaXQ6IFRpbWVVbml0IHwgJ2lzb1dlZWsnKTogbnVtYmVyO1xufVxuXG5mdW5jdGlvbiBhYnN0cmFjdDxUID0gdm9pZD4oKTogVCB7XG4gIHRocm93IG5ldyBFcnJvcignVGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkOiBDaGVjayB0aGF0IGEgY29tcGxldGUgZGF0ZSBhZGFwdGVyIGlzIHByb3ZpZGVkLicpO1xufVxuXG4vKipcbiAqIERhdGUgYWRhcHRlciAoY3VycmVudCB1c2VkIGJ5IHRoZSB0aW1lIHNjYWxlKVxuICogQG5hbWVzcGFjZSBDaGFydC5fYWRhcHRlcnMuX2RhdGVcbiAqIEBtZW1iZXJvZiBDaGFydC5fYWRhcHRlcnNcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIERhdGVBZGFwdGVyQmFzZSBpbXBsZW1lbnRzIERhdGVBZGFwdGVyIHtcblxuICAvKipcbiAgICogT3ZlcnJpZGUgZGVmYXVsdCBkYXRlIGFkYXB0ZXIgbWV0aG9kcy5cbiAgICogQWNjZXB0cyB0eXBlIHBhcmFtZXRlciB0byBkZWZpbmUgb3B0aW9ucyB0eXBlLlxuICAgKiBAZXhhbXBsZVxuICAgKiBDaGFydC5fYWRhcHRlcnMuX2RhdGUub3ZlcnJpZGU8e215QWRhcHRlck9wdGlvbjogc3RyaW5nfT4oe1xuICAgKiAgIGluaXQoKSB7XG4gICAqICAgICBjb25zb2xlLmxvZyh0aGlzLm9wdGlvbnMubXlBZGFwdGVyT3B0aW9uKTtcbiAgICogICB9XG4gICAqIH0pXG4gICAqL1xuICBzdGF0aWMgb3ZlcnJpZGU8VCBleHRlbmRzIEFueU9iamVjdCA9IEFueU9iamVjdD4oXG4gICAgbWVtYmVyczogUGFydGlhbDxPbWl0PERhdGVBZGFwdGVyPFQ+LCAnb3B0aW9ucyc+PlxuICApIHtcbiAgICBPYmplY3QuYXNzaWduKERhdGVBZGFwdGVyQmFzZS5wcm90b3R5cGUsIG1lbWJlcnMpO1xuICB9XG5cbiAgcmVhZG9ubHkgb3B0aW9uczogQW55T2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEFueU9iamVjdCkge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gIGluaXQoKSB7fVxuXG4gIGZvcm1hdHMoKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH1cblxuICBwYXJzZSgpOiBudW1iZXIgfCBudWxsIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfVxuXG4gIGZvcm1hdCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9XG5cbiAgYWRkKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH1cblxuICBkaWZmKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH1cblxuICBzdGFydE9mKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH1cblxuICBlbmRPZigpOiBudW1iZXIge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX2RhdGU6IERhdGVBZGFwdGVyQmFzZVxufTtcbiIsICJpbXBvcnQge19sb29rdXBCeUtleSwgX3Jsb29rdXBCeUtleX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvbGxlY3Rpb24uanMnO1xuaW1wb3J0IHtnZXRSZWxhdGl2ZVBvc2l0aW9ufSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZG9tLmpzJztcbmltcG9ydCB7X2FuZ2xlQmV0d2VlbiwgZ2V0QW5nbGVGcm9tUG9pbnR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCB7X2lzUG9pbnRJbkFyZWF9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuL2NvcmUuY29udHJvbGxlci5qcycpLmRlZmF1bHQgfSBDaGFydFxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL3R5cGVzL2luZGV4LmpzJykuQ2hhcnRFdmVudCB9IENoYXJ0RXZlbnRcbiAqIEB0eXBlZGVmIHt7YXhpcz86IHN0cmluZywgaW50ZXJzZWN0PzogYm9vbGVhbiwgaW5jbHVkZUludmlzaWJsZT86IGJvb2xlYW59fSBJbnRlcmFjdGlvbk9wdGlvbnNcbiAqIEB0eXBlZGVmIHt7ZGF0YXNldEluZGV4OiBudW1iZXIsIGluZGV4OiBudW1iZXIsIGVsZW1lbnQ6IGltcG9ydCgnLi9jb3JlLmVsZW1lbnQuanMnKS5kZWZhdWx0fX0gSW50ZXJhY3Rpb25JdGVtXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vdHlwZXMvaW5kZXguanMnKS5Qb2ludCB9IFBvaW50XG4gKi9cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZG8gYmluYXJ5IHNlYXJjaCB3aGVuIHBvc3NpYmxlXG4gKiBAcGFyYW0ge29iamVjdH0gbWV0YXNldCAtIHRoZSBkYXRhc2V0IG1ldGFcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzIC0gdGhlIGF4aXMgbW9kZS4geHx5fHh5fHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSAtIHRoZSB2YWx1ZSB0byBmaW5kXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpbnRlcnNlY3RdIC0gc2hvdWxkIHRoZSBlbGVtZW50IGludGVyc2VjdFxuICogQHJldHVybnMge3tsbzpudW1iZXIsIGhpOm51bWJlcn19IGluZGljZXMgdG8gc2VhcmNoIGRhdGEgYXJyYXkgYmV0d2VlblxuICovXG5mdW5jdGlvbiBiaW5hcnlTZWFyY2gobWV0YXNldCwgYXhpcywgdmFsdWUsIGludGVyc2VjdCkge1xuICBjb25zdCB7Y29udHJvbGxlciwgZGF0YSwgX3NvcnRlZH0gPSBtZXRhc2V0O1xuICBjb25zdCBpU2NhbGUgPSBjb250cm9sbGVyLl9jYWNoZWRNZXRhLmlTY2FsZTtcbiAgaWYgKGlTY2FsZSAmJiBheGlzID09PSBpU2NhbGUuYXhpcyAmJiBheGlzICE9PSAncicgJiYgX3NvcnRlZCAmJiBkYXRhLmxlbmd0aCkge1xuICAgIGNvbnN0IGxvb2t1cE1ldGhvZCA9IGlTY2FsZS5fcmV2ZXJzZVBpeGVscyA/IF9ybG9va3VwQnlLZXkgOiBfbG9va3VwQnlLZXk7XG4gICAgaWYgKCFpbnRlcnNlY3QpIHtcbiAgICAgIHJldHVybiBsb29rdXBNZXRob2QoZGF0YSwgYXhpcywgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoY29udHJvbGxlci5fc2hhcmVkT3B0aW9ucykge1xuICAgICAgLy8gX3NoYXJlZE9wdGlvbnMgaW5kaWNhdGVzIHRoYXQgZWFjaCBlbGVtZW50IGhhcyBlcXVhbCBvcHRpb25zIC0+IGVxdWFsIHByb3BvcnRpb25zXG4gICAgICAvLyBTbyB3ZSBjYW4gZG8gYSByYW5nZWQgYmluYXJ5IHNlYXJjaCBiYXNlZCBvbiB0aGUgcmFuZ2Ugb2YgZmlyc3QgZWxlbWVudCBhbmRcbiAgICAgIC8vIGJlIGNvbmZpZGVudCB0byBnZXQgdGhlIGZ1bGwgcmFuZ2Ugb2YgaW5kaWNlcyB0aGF0IGNhbiBpbnRlcnNlY3Qgd2l0aCB0aGUgdmFsdWUuXG4gICAgICBjb25zdCBlbCA9IGRhdGFbMF07XG4gICAgICBjb25zdCByYW5nZSA9IHR5cGVvZiBlbC5nZXRSYW5nZSA9PT0gJ2Z1bmN0aW9uJyAmJiBlbC5nZXRSYW5nZShheGlzKTtcbiAgICAgIGlmIChyYW5nZSkge1xuICAgICAgICBjb25zdCBzdGFydCA9IGxvb2t1cE1ldGhvZChkYXRhLCBheGlzLCB2YWx1ZSAtIHJhbmdlKTtcbiAgICAgICAgY29uc3QgZW5kID0gbG9va3VwTWV0aG9kKGRhdGEsIGF4aXMsIHZhbHVlICsgcmFuZ2UpO1xuICAgICAgICByZXR1cm4ge2xvOiBzdGFydC5sbywgaGk6IGVuZC5oaX07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIERlZmF1bHQgdG8gYWxsIGVsZW1lbnRzLCB3aGVuIGJpbmFyeSBzZWFyY2ggY2FuIG5vdCBiZSB1c2VkLlxuICByZXR1cm4ge2xvOiAwLCBoaTogZGF0YS5sZW5ndGggLSAxfTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gc2VsZWN0IGNhbmRpZGF0ZSBlbGVtZW50cyBmb3IgaW50ZXJhY3Rpb25cbiAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0XG4gKiBAcGFyYW0ge3N0cmluZ30gYXhpcyAtIHRoZSBheGlzIG1vZGUuIHh8eXx4eXxyXG4gKiBAcGFyYW0ge1BvaW50fSBwb3NpdGlvbiAtIHRoZSBwb2ludCB0byBiZSBuZWFyZXN0IHRvLCBpbiByZWxhdGl2ZSBjb29yZGluYXRlc1xuICogQHBhcmFtIHtmdW5jdGlvbn0gaGFuZGxlciAtIHRoZSBjYWxsYmFjayB0byBleGVjdXRlIGZvciBlYWNoIHZpc2libGUgaXRlbVxuICogQHBhcmFtIHtib29sZWFufSBbaW50ZXJzZWN0XSAtIGNvbnNpZGVyIGludGVyc2VjdGluZyBpdGVtc1xuICovXG5mdW5jdGlvbiBldmFsdWF0ZUludGVyYWN0aW9uSXRlbXMoY2hhcnQsIGF4aXMsIHBvc2l0aW9uLCBoYW5kbGVyLCBpbnRlcnNlY3QpIHtcbiAgY29uc3QgbWV0YXNldHMgPSBjaGFydC5nZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCk7XG4gIGNvbnN0IHZhbHVlID0gcG9zaXRpb25bYXhpc107XG4gIGZvciAobGV0IGkgPSAwLCBpbGVuID0gbWV0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgY29uc3Qge2luZGV4LCBkYXRhfSA9IG1ldGFzZXRzW2ldO1xuICAgIGNvbnN0IHtsbywgaGl9ID0gYmluYXJ5U2VhcmNoKG1ldGFzZXRzW2ldLCBheGlzLCB2YWx1ZSwgaW50ZXJzZWN0KTtcbiAgICBmb3IgKGxldCBqID0gbG87IGogPD0gaGk7ICsraikge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGRhdGFbal07XG4gICAgICBpZiAoIWVsZW1lbnQuc2tpcCkge1xuICAgICAgICBoYW5kbGVyKGVsZW1lbnQsIGluZGV4LCBqKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgYSBkaXN0YW5jZSBtZXRyaWMgZnVuY3Rpb24gZm9yIHR3byBwb2ludHMgYmFzZWQgb24gdGhlXG4gKiBheGlzIG1vZGUgc2V0dGluZ1xuICogQHBhcmFtIHtzdHJpbmd9IGF4aXMgLSB0aGUgYXhpcyBtb2RlLiB4fHl8eHl8clxuICovXG5mdW5jdGlvbiBnZXREaXN0YW5jZU1ldHJpY0ZvckF4aXMoYXhpcykge1xuICBjb25zdCB1c2VYID0gYXhpcy5pbmRleE9mKCd4JykgIT09IC0xO1xuICBjb25zdCB1c2VZID0gYXhpcy5pbmRleE9mKCd5JykgIT09IC0xO1xuXG4gIHJldHVybiBmdW5jdGlvbihwdDEsIHB0Mikge1xuICAgIGNvbnN0IGRlbHRhWCA9IHVzZVggPyBNYXRoLmFicyhwdDEueCAtIHB0Mi54KSA6IDA7XG4gICAgY29uc3QgZGVsdGFZID0gdXNlWSA/IE1hdGguYWJzKHB0MS55IC0gcHQyLnkpIDogMDtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KGRlbHRhWCwgMikgKyBNYXRoLnBvdyhkZWx0YVksIDIpKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHRoZSBpdGVtcyB0aGF0IGludGVyc2VjdCB0aGUgZXZlbnQgcG9zaXRpb25cbiAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0XG4gKiBAcGFyYW0ge1BvaW50fSBwb3NpdGlvbiAtIHRoZSBwb2ludCB0byBiZSBuZWFyZXN0IHRvLCBpbiByZWxhdGl2ZSBjb29yZGluYXRlc1xuICogQHBhcmFtIHtzdHJpbmd9IGF4aXMgLSB0aGUgYXhpcyBtb2RlLiB4fHl8eHl8clxuICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl0gLSB1c2UgdGhlIGVsZW1lbnQncyBhbmltYXRpb24gdGFyZ2V0IGluc3RlYWQgb2YgY3VycmVudCBwb3NpdGlvblxuICogQHBhcmFtIHtib29sZWFufSBbaW5jbHVkZUludmlzaWJsZV0gLSBpbmNsdWRlIGludmlzaWJsZSBwb2ludHMgdGhhdCBhcmUgb3V0c2lkZSBvZiB0aGUgY2hhcnQgYXJlYVxuICogQHJldHVybiB7SW50ZXJhY3Rpb25JdGVtW119IHRoZSBuZWFyZXN0IGl0ZW1zXG4gKi9cbmZ1bmN0aW9uIGdldEludGVyc2VjdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSkge1xuICBjb25zdCBpdGVtcyA9IFtdO1xuXG4gIGlmICghaW5jbHVkZUludmlzaWJsZSAmJiAhY2hhcnQuaXNQb2ludEluQXJlYShwb3NpdGlvbikpIHtcbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICBjb25zdCBldmFsdWF0aW9uRnVuYyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXgpIHtcbiAgICBpZiAoIWluY2x1ZGVJbnZpc2libGUgJiYgIV9pc1BvaW50SW5BcmVhKGVsZW1lbnQsIGNoYXJ0LmNoYXJ0QXJlYSwgMCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGVsZW1lbnQuaW5SYW5nZShwb3NpdGlvbi54LCBwb3NpdGlvbi55LCB1c2VGaW5hbFBvc2l0aW9uKSkge1xuICAgICAgaXRlbXMucHVzaCh7ZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleH0pO1xuICAgIH1cbiAgfTtcblxuICBldmFsdWF0ZUludGVyYWN0aW9uSXRlbXMoY2hhcnQsIGF4aXMsIHBvc2l0aW9uLCBldmFsdWF0aW9uRnVuYywgdHJ1ZSk7XG4gIHJldHVybiBpdGVtcztcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHRoZSBpdGVtcyBuZWFyZXN0IHRvIHRoZSBldmVudCBwb3NpdGlvbiBmb3IgYSByYWRpYWwgY2hhcnRcbiAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHRvIGxvb2sgYXQgZWxlbWVudHMgZnJvbVxuICogQHBhcmFtIHtQb2ludH0gcG9zaXRpb24gLSB0aGUgcG9pbnQgdG8gYmUgbmVhcmVzdCB0bywgaW4gcmVsYXRpdmUgY29vcmRpbmF0ZXNcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzIC0gdGhlIGF4ZXMgYWxvbmcgd2hpY2ggdG8gbWVhc3VyZSBkaXN0YW5jZVxuICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl0gLSB1c2UgdGhlIGVsZW1lbnQncyBhbmltYXRpb24gdGFyZ2V0IGluc3RlYWQgb2YgY3VycmVudCBwb3NpdGlvblxuICogQHJldHVybiB7SW50ZXJhY3Rpb25JdGVtW119IHRoZSBuZWFyZXN0IGl0ZW1zXG4gKi9cbmZ1bmN0aW9uIGdldE5lYXJlc3RSYWRpYWxJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgbGV0IGl0ZW1zID0gW107XG5cbiAgZnVuY3Rpb24gZXZhbHVhdGlvbkZ1bmMoZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleCkge1xuICAgIGNvbnN0IHtzdGFydEFuZ2xlLCBlbmRBbmdsZX0gPSBlbGVtZW50LmdldFByb3BzKFsnc3RhcnRBbmdsZScsICdlbmRBbmdsZSddLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICBjb25zdCB7YW5nbGV9ID0gZ2V0QW5nbGVGcm9tUG9pbnQoZWxlbWVudCwge3g6IHBvc2l0aW9uLngsIHk6IHBvc2l0aW9uLnl9KTtcblxuICAgIGlmIChfYW5nbGVCZXR3ZWVuKGFuZ2xlLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSkpIHtcbiAgICAgIGl0ZW1zLnB1c2goe2VsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXh9KTtcbiAgICB9XG4gIH1cblxuICBldmFsdWF0ZUludGVyYWN0aW9uSXRlbXMoY2hhcnQsIGF4aXMsIHBvc2l0aW9uLCBldmFsdWF0aW9uRnVuYyk7XG4gIHJldHVybiBpdGVtcztcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHRoZSBpdGVtcyBuZWFyZXN0IHRvIHRoZSBldmVudCBwb3NpdGlvbiBmb3IgYSBjYXJ0ZXNpYW4gY2hhcnRcbiAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHRvIGxvb2sgYXQgZWxlbWVudHMgZnJvbVxuICogQHBhcmFtIHtQb2ludH0gcG9zaXRpb24gLSB0aGUgcG9pbnQgdG8gYmUgbmVhcmVzdCB0bywgaW4gcmVsYXRpdmUgY29vcmRpbmF0ZXNcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzIC0gdGhlIGF4ZXMgYWxvbmcgd2hpY2ggdG8gbWVhc3VyZSBkaXN0YW5jZVxuICogQHBhcmFtIHtib29sZWFufSBbaW50ZXJzZWN0XSAtIGlmIHRydWUsIG9ubHkgY29uc2lkZXIgaXRlbXMgdGhhdCBpbnRlcnNlY3QgdGhlIHBvc2l0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXSAtIHVzZSB0aGUgZWxlbWVudCdzIGFuaW1hdGlvbiB0YXJnZXQgaW5zdGVhZCBvZiBjdXJyZW50IHBvc2l0aW9uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpbmNsdWRlSW52aXNpYmxlXSAtIGluY2x1ZGUgaW52aXNpYmxlIHBvaW50cyB0aGF0IGFyZSBvdXRzaWRlIG9mIHRoZSBjaGFydCBhcmVhXG4gKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gdGhlIG5lYXJlc3QgaXRlbXNcbiAqL1xuZnVuY3Rpb24gZ2V0TmVhcmVzdENhcnRlc2lhbkl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgaW50ZXJzZWN0LCB1c2VGaW5hbFBvc2l0aW9uLCBpbmNsdWRlSW52aXNpYmxlKSB7XG4gIGxldCBpdGVtcyA9IFtdO1xuICBjb25zdCBkaXN0YW5jZU1ldHJpYyA9IGdldERpc3RhbmNlTWV0cmljRm9yQXhpcyhheGlzKTtcbiAgbGV0IG1pbkRpc3RhbmNlID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuXG4gIGZ1bmN0aW9uIGV2YWx1YXRpb25GdW5jKGVsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXgpIHtcbiAgICBjb25zdCBpblJhbmdlID0gZWxlbWVudC5pblJhbmdlKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIGlmIChpbnRlcnNlY3QgJiYgIWluUmFuZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjZW50ZXIgPSBlbGVtZW50LmdldENlbnRlclBvaW50KHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIGNvbnN0IHBvaW50SW5BcmVhID0gISFpbmNsdWRlSW52aXNpYmxlIHx8IGNoYXJ0LmlzUG9pbnRJbkFyZWEoY2VudGVyKTtcbiAgICBpZiAoIXBvaW50SW5BcmVhICYmICFpblJhbmdlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGlzdGFuY2UgPSBkaXN0YW5jZU1ldHJpYyhwb3NpdGlvbiwgY2VudGVyKTtcbiAgICBpZiAoZGlzdGFuY2UgPCBtaW5EaXN0YW5jZSkge1xuICAgICAgaXRlbXMgPSBbe2VsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXh9XTtcbiAgICAgIG1pbkRpc3RhbmNlID0gZGlzdGFuY2U7XG4gICAgfSBlbHNlIGlmIChkaXN0YW5jZSA9PT0gbWluRGlzdGFuY2UpIHtcbiAgICAgIC8vIENhbiBoYXZlIG11bHRpcGxlIGl0ZW1zIGF0IHRoZSBzYW1lIGRpc3RhbmNlIGluIHdoaWNoIGNhc2Ugd2Ugc29ydCBieSBzaXplXG4gICAgICBpdGVtcy5wdXNoKHtlbGVtZW50LCBkYXRhc2V0SW5kZXgsIGluZGV4fSk7XG4gICAgfVxuICB9XG5cbiAgZXZhbHVhdGVJbnRlcmFjdGlvbkl0ZW1zKGNoYXJ0LCBheGlzLCBwb3NpdGlvbiwgZXZhbHVhdGlvbkZ1bmMpO1xuICByZXR1cm4gaXRlbXM7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgaXRlbXMgbmVhcmVzdCB0byB0aGUgZXZlbnQgcG9zaXRpb24gY29uc2lkZXJpbmcgYWxsIHZpc2libGUgaXRlbXMgaW4gdGhlIGNoYXJ0XG4gKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB0byBsb29rIGF0IGVsZW1lbnRzIGZyb21cbiAqIEBwYXJhbSB7UG9pbnR9IHBvc2l0aW9uIC0gdGhlIHBvaW50IHRvIGJlIG5lYXJlc3QgdG8sIGluIHJlbGF0aXZlIGNvb3JkaW5hdGVzXG4gKiBAcGFyYW0ge3N0cmluZ30gYXhpcyAtIHRoZSBheGVzIGFsb25nIHdoaWNoIHRvIG1lYXN1cmUgZGlzdGFuY2VcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2ludGVyc2VjdF0gLSBpZiB0cnVlLCBvbmx5IGNvbnNpZGVyIGl0ZW1zIHRoYXQgaW50ZXJzZWN0IHRoZSBwb3NpdGlvblxuICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl0gLSB1c2UgdGhlIGVsZW1lbnQncyBhbmltYXRpb24gdGFyZ2V0IGluc3RlYWQgb2YgY3VycmVudCBwb3NpdGlvblxuICogQHBhcmFtIHtib29sZWFufSBbaW5jbHVkZUludmlzaWJsZV0gLSBpbmNsdWRlIGludmlzaWJsZSBwb2ludHMgdGhhdCBhcmUgb3V0c2lkZSBvZiB0aGUgY2hhcnQgYXJlYVxuICogQHJldHVybiB7SW50ZXJhY3Rpb25JdGVtW119IHRoZSBuZWFyZXN0IGl0ZW1zXG4gKi9cbmZ1bmN0aW9uIGdldE5lYXJlc3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIGludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbiwgaW5jbHVkZUludmlzaWJsZSkge1xuICBpZiAoIWluY2x1ZGVJbnZpc2libGUgJiYgIWNoYXJ0LmlzUG9pbnRJbkFyZWEocG9zaXRpb24pKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcmV0dXJuIGF4aXMgPT09ICdyJyAmJiAhaW50ZXJzZWN0XG4gICAgPyBnZXROZWFyZXN0UmFkaWFsSXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCB1c2VGaW5hbFBvc2l0aW9uKVxuICAgIDogZ2V0TmVhcmVzdENhcnRlc2lhbkl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgaW50ZXJzZWN0LCB1c2VGaW5hbFBvc2l0aW9uLCBpbmNsdWRlSW52aXNpYmxlKTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHRoZSBpdGVtcyBtYXRjaGluZyBhbG9uZyB0aGUgZ2l2ZW4gWCBvciBZIGF4aXNcbiAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHRvIGxvb2sgYXQgZWxlbWVudHMgZnJvbVxuICogQHBhcmFtIHtQb2ludH0gcG9zaXRpb24gLSB0aGUgcG9pbnQgdG8gYmUgbmVhcmVzdCB0bywgaW4gcmVsYXRpdmUgY29vcmRpbmF0ZXNcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzIC0gdGhlIGF4aXMgdG8gbWF0Y2hcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2ludGVyc2VjdF0gLSBpZiB0cnVlLCBvbmx5IGNvbnNpZGVyIGl0ZW1zIHRoYXQgaW50ZXJzZWN0IHRoZSBwb3NpdGlvblxuICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl0gLSB1c2UgdGhlIGVsZW1lbnQncyBhbmltYXRpb24gdGFyZ2V0IGluc3RlYWQgb2YgY3VycmVudCBwb3NpdGlvblxuICogQHJldHVybiB7SW50ZXJhY3Rpb25JdGVtW119IHRoZSBuZWFyZXN0IGl0ZW1zXG4gKi9cbmZ1bmN0aW9uIGdldEF4aXNJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIGludGVyc2VjdCwgdXNlRmluYWxQb3NpdGlvbikge1xuICBjb25zdCBpdGVtcyA9IFtdO1xuICBjb25zdCByYW5nZU1ldGhvZCA9IGF4aXMgPT09ICd4JyA/ICdpblhSYW5nZScgOiAnaW5ZUmFuZ2UnO1xuICBsZXQgaW50ZXJzZWN0c0l0ZW0gPSBmYWxzZTtcblxuICBldmFsdWF0ZUludGVyYWN0aW9uSXRlbXMoY2hhcnQsIGF4aXMsIHBvc2l0aW9uLCAoZWxlbWVudCwgZGF0YXNldEluZGV4LCBpbmRleCkgPT4ge1xuICAgIGlmIChlbGVtZW50W3JhbmdlTWV0aG9kXShwb3NpdGlvbltheGlzXSwgdXNlRmluYWxQb3NpdGlvbikpIHtcbiAgICAgIGl0ZW1zLnB1c2goe2VsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXh9KTtcbiAgICAgIGludGVyc2VjdHNJdGVtID0gaW50ZXJzZWN0c0l0ZW0gfHwgZWxlbWVudC5pblJhbmdlKHBvc2l0aW9uLngsIHBvc2l0aW9uLnksIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gSWYgd2Ugd2FudCB0byB0cmlnZ2VyIG9uIGFuIGludGVyc2VjdCBhbmQgd2UgZG9uJ3QgaGF2ZSBhbnkgaXRlbXNcbiAgLy8gdGhhdCBpbnRlcnNlY3QgdGhlIHBvc2l0aW9uLCByZXR1cm4gbm90aGluZ1xuICBpZiAoaW50ZXJzZWN0ICYmICFpbnRlcnNlY3RzSXRlbSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICByZXR1cm4gaXRlbXM7XG59XG5cbi8qKlxuICogQ29udGFpbnMgaW50ZXJhY3Rpb24gcmVsYXRlZCBmdW5jdGlvbnNcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuSW50ZXJhY3Rpb25cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICAvLyBQYXJ0IG9mIHRoZSBwdWJsaWMgQVBJIHRvIGZhY2lsaXRhdGUgZGV2ZWxvcGVycyBjcmVhdGluZyB0aGVpciBvd24gbW9kZXNcbiAgZXZhbHVhdGVJbnRlcmFjdGlvbkl0ZW1zLFxuXG4gIC8vIEhlbHBlciBmdW5jdGlvbiBmb3IgZGlmZmVyZW50IG1vZGVzXG4gIG1vZGVzOiB7XG4gICAgLyoqXG5cdFx0ICogUmV0dXJucyBpdGVtcyBhdCB0aGUgc2FtZSBpbmRleC4gSWYgdGhlIG9wdGlvbnMuaW50ZXJzZWN0IHBhcmFtZXRlciBpcyB0cnVlLCB3ZSBvbmx5IHJldHVybiBpdGVtcyBpZiB3ZSBpbnRlcnNlY3Qgc29tZXRoaW5nXG5cdFx0ICogSWYgdGhlIG9wdGlvbnMuaW50ZXJzZWN0IG1vZGUgaXMgZmFsc2UsIHdlIGZpbmQgdGhlIG5lYXJlc3QgaXRlbSBhbmQgcmV0dXJuIHRoZSBpdGVtcyBhdCB0aGUgc2FtZSBpbmRleCBhcyB0aGF0IGl0ZW1cblx0XHQgKiBAZnVuY3Rpb24gQ2hhcnQuSW50ZXJhY3Rpb24ubW9kZXMuaW5kZXhcblx0XHQgKiBAc2luY2UgdjIuNC4wXG5cdFx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgd2UgYXJlIHJldHVybmluZyBpdGVtcyBmcm9tXG5cdFx0ICogQHBhcmFtIHtFdmVudH0gZSAtIHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcblx0XHQgKiBAcGFyYW0ge0ludGVyYWN0aW9uT3B0aW9uc30gb3B0aW9ucyAtIG9wdGlvbnMgdG8gdXNlXG5cdFx0ICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl0gLSB1c2UgZmluYWwgZWxlbWVudCBwb3NpdGlvbiAoYW5pbWF0aW9uIHRhcmdldClcblx0XHQgKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gLSBpdGVtcyB0aGF0IGFyZSBmb3VuZFxuXHRcdCAqL1xuICAgIGluZGV4KGNoYXJ0LCBlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuICAgICAgLy8gRGVmYXVsdCBheGlzIGZvciBpbmRleCBtb2RlIGlzICd4JyB0byBtYXRjaCBvbGQgYmVoYXZpb3VyXG4gICAgICBjb25zdCBheGlzID0gb3B0aW9ucy5heGlzIHx8ICd4JztcbiAgICAgIGNvbnN0IGluY2x1ZGVJbnZpc2libGUgPSBvcHRpb25zLmluY2x1ZGVJbnZpc2libGUgfHwgZmFsc2U7XG4gICAgICBjb25zdCBpdGVtcyA9IG9wdGlvbnMuaW50ZXJzZWN0XG4gICAgICAgID8gZ2V0SW50ZXJzZWN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uLCBheGlzLCB1c2VGaW5hbFBvc2l0aW9uLCBpbmNsdWRlSW52aXNpYmxlKVxuICAgICAgICA6IGdldE5lYXJlc3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIGZhbHNlLCB1c2VGaW5hbFBvc2l0aW9uLCBpbmNsdWRlSW52aXNpYmxlKTtcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gW107XG5cbiAgICAgIGlmICghaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cblxuICAgICAgY2hhcnQuZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpLmZvckVhY2goKG1ldGEpID0+IHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBpdGVtc1swXS5pbmRleDtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IG1ldGEuZGF0YVtpbmRleF07XG5cbiAgICAgICAgLy8gZG9uJ3QgY291bnQgaXRlbXMgdGhhdCBhcmUgc2tpcHBlZCAobnVsbCBkYXRhKVxuICAgICAgICBpZiAoZWxlbWVudCAmJiAhZWxlbWVudC5za2lwKSB7XG4gICAgICAgICAgZWxlbWVudHMucHVzaCh7ZWxlbWVudCwgZGF0YXNldEluZGV4OiBtZXRhLmluZGV4LCBpbmRleH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGVsZW1lbnRzO1xuICAgIH0sXG5cbiAgICAvKipcblx0XHQgKiBSZXR1cm5zIGl0ZW1zIGluIHRoZSBzYW1lIGRhdGFzZXQuIElmIHRoZSBvcHRpb25zLmludGVyc2VjdCBwYXJhbWV0ZXIgaXMgdHJ1ZSwgd2Ugb25seSByZXR1cm4gaXRlbXMgaWYgd2UgaW50ZXJzZWN0IHNvbWV0aGluZ1xuXHRcdCAqIElmIHRoZSBvcHRpb25zLmludGVyc2VjdCBpcyBmYWxzZSwgd2UgZmluZCB0aGUgbmVhcmVzdCBpdGVtIGFuZCByZXR1cm4gdGhlIGl0ZW1zIGluIHRoYXQgZGF0YXNldFxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy5kYXRhc2V0XG5cdFx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgd2UgYXJlIHJldHVybmluZyBpdGVtcyBmcm9tXG5cdFx0ICogQHBhcmFtIHtFdmVudH0gZSAtIHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcblx0XHQgKiBAcGFyYW0ge0ludGVyYWN0aW9uT3B0aW9uc30gb3B0aW9ucyAtIG9wdGlvbnMgdG8gdXNlXG5cdFx0ICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl0gLSB1c2UgZmluYWwgZWxlbWVudCBwb3NpdGlvbiAoYW5pbWF0aW9uIHRhcmdldClcblx0XHQgKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gLSBpdGVtcyB0aGF0IGFyZSBmb3VuZFxuXHRcdCAqL1xuICAgIGRhdGFzZXQoY2hhcnQsIGUsIG9wdGlvbnMsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XG4gICAgICBjb25zdCBheGlzID0gb3B0aW9ucy5heGlzIHx8ICd4eSc7XG4gICAgICBjb25zdCBpbmNsdWRlSW52aXNpYmxlID0gb3B0aW9ucy5pbmNsdWRlSW52aXNpYmxlIHx8IGZhbHNlO1xuICAgICAgbGV0IGl0ZW1zID0gb3B0aW9ucy5pbnRlcnNlY3RcbiAgICAgICAgPyBnZXRJbnRlcnNlY3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIHVzZUZpbmFsUG9zaXRpb24sIGluY2x1ZGVJbnZpc2libGUpIDpcbiAgICAgICAgZ2V0TmVhcmVzdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgZmFsc2UsIHVzZUZpbmFsUG9zaXRpb24sIGluY2x1ZGVJbnZpc2libGUpO1xuXG4gICAgICBpZiAoaXRlbXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBkYXRhc2V0SW5kZXggPSBpdGVtc1swXS5kYXRhc2V0SW5kZXg7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpLmRhdGE7XG4gICAgICAgIGl0ZW1zID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGl0ZW1zLnB1c2goe2VsZW1lbnQ6IGRhdGFbaV0sIGRhdGFzZXRJbmRleCwgaW5kZXg6IGl9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gaXRlbXM7XG4gICAgfSxcblxuICAgIC8qKlxuXHRcdCAqIFBvaW50IG1vZGUgcmV0dXJucyBhbGwgZWxlbWVudHMgdGhhdCBoaXQgdGVzdCBiYXNlZCBvbiB0aGUgZXZlbnQgcG9zaXRpb25cblx0XHQgKiBvZiB0aGUgZXZlbnRcblx0XHQgKiBAZnVuY3Rpb24gQ2hhcnQuSW50ZXJhY3Rpb24ubW9kZXMuaW50ZXJzZWN0XG5cdFx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgd2UgYXJlIHJldHVybmluZyBpdGVtcyBmcm9tXG5cdFx0ICogQHBhcmFtIHtFdmVudH0gZSAtIHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcblx0XHQgKiBAcGFyYW0ge0ludGVyYWN0aW9uT3B0aW9uc30gb3B0aW9ucyAtIG9wdGlvbnMgdG8gdXNlXG5cdFx0ICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl0gLSB1c2UgZmluYWwgZWxlbWVudCBwb3NpdGlvbiAoYW5pbWF0aW9uIHRhcmdldClcblx0XHQgKiBAcmV0dXJuIHtJbnRlcmFjdGlvbkl0ZW1bXX0gLSBpdGVtcyB0aGF0IGFyZSBmb3VuZFxuXHRcdCAqL1xuICAgIHBvaW50KGNoYXJ0LCBlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuICAgICAgY29uc3QgYXhpcyA9IG9wdGlvbnMuYXhpcyB8fCAneHknO1xuICAgICAgY29uc3QgaW5jbHVkZUludmlzaWJsZSA9IG9wdGlvbnMuaW5jbHVkZUludmlzaWJsZSB8fCBmYWxzZTtcbiAgICAgIHJldHVybiBnZXRJbnRlcnNlY3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGF4aXMsIHVzZUZpbmFsUG9zaXRpb24sIGluY2x1ZGVJbnZpc2libGUpO1xuICAgIH0sXG5cbiAgICAvKipcblx0XHQgKiBuZWFyZXN0IG1vZGUgcmV0dXJucyB0aGUgZWxlbWVudCBjbG9zZXN0IHRvIHRoZSBwb2ludFxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy5pbnRlcnNlY3Rcblx0XHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB3ZSBhcmUgcmV0dXJuaW5nIGl0ZW1zIGZyb21cblx0XHQgKiBAcGFyYW0ge0V2ZW50fSBlIC0gdGhlIGV2ZW50IHdlIGFyZSBmaW5kIHRoaW5ncyBhdFxuXHRcdCAqIEBwYXJhbSB7SW50ZXJhY3Rpb25PcHRpb25zfSBvcHRpb25zIC0gb3B0aW9ucyB0byB1c2Vcblx0XHQgKiBAcGFyYW0ge2Jvb2xlYW59IFt1c2VGaW5hbFBvc2l0aW9uXSAtIHVzZSBmaW5hbCBlbGVtZW50IHBvc2l0aW9uIChhbmltYXRpb24gdGFyZ2V0KVxuXHRcdCAqIEByZXR1cm4ge0ludGVyYWN0aW9uSXRlbVtdfSAtIGl0ZW1zIHRoYXQgYXJlIGZvdW5kXG5cdFx0ICovXG4gICAgbmVhcmVzdChjaGFydCwgZSwgb3B0aW9ucywgdXNlRmluYWxQb3NpdGlvbikge1xuICAgICAgY29uc3QgcG9zaXRpb24gPSBnZXRSZWxhdGl2ZVBvc2l0aW9uKGUsIGNoYXJ0KTtcbiAgICAgIGNvbnN0IGF4aXMgPSBvcHRpb25zLmF4aXMgfHwgJ3h5JztcbiAgICAgIGNvbnN0IGluY2x1ZGVJbnZpc2libGUgPSBvcHRpb25zLmluY2x1ZGVJbnZpc2libGUgfHwgZmFsc2U7XG4gICAgICByZXR1cm4gZ2V0TmVhcmVzdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgYXhpcywgb3B0aW9ucy5pbnRlcnNlY3QsIHVzZUZpbmFsUG9zaXRpb24sIGluY2x1ZGVJbnZpc2libGUpO1xuICAgIH0sXG5cbiAgICAvKipcblx0XHQgKiB4IG1vZGUgcmV0dXJucyB0aGUgZWxlbWVudHMgdGhhdCBoaXQtdGVzdCBhdCB0aGUgY3VycmVudCB4IGNvb3JkaW5hdGVcblx0XHQgKiBAZnVuY3Rpb24gQ2hhcnQuSW50ZXJhY3Rpb24ubW9kZXMueFxuXHRcdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHdlIGFyZSByZXR1cm5pbmcgaXRlbXMgZnJvbVxuXHRcdCAqIEBwYXJhbSB7RXZlbnR9IGUgLSB0aGUgZXZlbnQgd2UgYXJlIGZpbmQgdGhpbmdzIGF0XG5cdFx0ICogQHBhcmFtIHtJbnRlcmFjdGlvbk9wdGlvbnN9IG9wdGlvbnMgLSBvcHRpb25zIHRvIHVzZVxuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW3VzZUZpbmFsUG9zaXRpb25dIC0gdXNlIGZpbmFsIGVsZW1lbnQgcG9zaXRpb24gKGFuaW1hdGlvbiB0YXJnZXQpXG5cdFx0ICogQHJldHVybiB7SW50ZXJhY3Rpb25JdGVtW119IC0gaXRlbXMgdGhhdCBhcmUgZm91bmRcblx0XHQgKi9cbiAgICB4KGNoYXJ0LCBlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuICAgICAgcmV0dXJuIGdldEF4aXNJdGVtcyhjaGFydCwgcG9zaXRpb24sICd4Jywgb3B0aW9ucy5pbnRlcnNlY3QsIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIH0sXG5cbiAgICAvKipcblx0XHQgKiB5IG1vZGUgcmV0dXJucyB0aGUgZWxlbWVudHMgdGhhdCBoaXQtdGVzdCBhdCB0aGUgY3VycmVudCB5IGNvb3JkaW5hdGVcblx0XHQgKiBAZnVuY3Rpb24gQ2hhcnQuSW50ZXJhY3Rpb24ubW9kZXMueVxuXHRcdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHdlIGFyZSByZXR1cm5pbmcgaXRlbXMgZnJvbVxuXHRcdCAqIEBwYXJhbSB7RXZlbnR9IGUgLSB0aGUgZXZlbnQgd2UgYXJlIGZpbmQgdGhpbmdzIGF0XG5cdFx0ICogQHBhcmFtIHtJbnRlcmFjdGlvbk9wdGlvbnN9IG9wdGlvbnMgLSBvcHRpb25zIHRvIHVzZVxuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW3VzZUZpbmFsUG9zaXRpb25dIC0gdXNlIGZpbmFsIGVsZW1lbnQgcG9zaXRpb24gKGFuaW1hdGlvbiB0YXJnZXQpXG5cdFx0ICogQHJldHVybiB7SW50ZXJhY3Rpb25JdGVtW119IC0gaXRlbXMgdGhhdCBhcmUgZm91bmRcblx0XHQgKi9cbiAgICB5KGNoYXJ0LCBlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xuICAgICAgcmV0dXJuIGdldEF4aXNJdGVtcyhjaGFydCwgcG9zaXRpb24sICd5Jywgb3B0aW9ucy5pbnRlcnNlY3QsIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIH1cbiAgfVxufTtcbiIsICJpbXBvcnQge2RlZmluZWQsIGVhY2gsIGlzT2JqZWN0fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge3RvUGFkZGluZ30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm9wdGlvbnMuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuL2NvcmUuY29udHJvbGxlci5qcycpLmRlZmF1bHQgfSBDaGFydFxuICovXG5cbmNvbnN0IFNUQVRJQ19QT1NJVElPTlMgPSBbJ2xlZnQnLCAndG9wJywgJ3JpZ2h0JywgJ2JvdHRvbSddO1xuXG5mdW5jdGlvbiBmaWx0ZXJCeVBvc2l0aW9uKGFycmF5LCBwb3NpdGlvbikge1xuICByZXR1cm4gYXJyYXkuZmlsdGVyKHYgPT4gdi5wb3MgPT09IHBvc2l0aW9uKTtcbn1cblxuZnVuY3Rpb24gZmlsdGVyRHluYW1pY1Bvc2l0aW9uQnlBeGlzKGFycmF5LCBheGlzKSB7XG4gIHJldHVybiBhcnJheS5maWx0ZXIodiA9PiBTVEFUSUNfUE9TSVRJT05TLmluZGV4T2Yodi5wb3MpID09PSAtMSAmJiB2LmJveC5heGlzID09PSBheGlzKTtcbn1cblxuZnVuY3Rpb24gc29ydEJ5V2VpZ2h0KGFycmF5LCByZXZlcnNlKSB7XG4gIHJldHVybiBhcnJheS5zb3J0KChhLCBiKSA9PiB7XG4gICAgY29uc3QgdjAgPSByZXZlcnNlID8gYiA6IGE7XG4gICAgY29uc3QgdjEgPSByZXZlcnNlID8gYSA6IGI7XG4gICAgcmV0dXJuIHYwLndlaWdodCA9PT0gdjEud2VpZ2h0ID9cbiAgICAgIHYwLmluZGV4IC0gdjEuaW5kZXggOlxuICAgICAgdjAud2VpZ2h0IC0gdjEud2VpZ2h0O1xuICB9KTtcbn1cblxuZnVuY3Rpb24gd3JhcEJveGVzKGJveGVzKSB7XG4gIGNvbnN0IGxheW91dEJveGVzID0gW107XG4gIGxldCBpLCBpbGVuLCBib3gsIHBvcywgc3RhY2ssIHN0YWNrV2VpZ2h0O1xuXG4gIGZvciAoaSA9IDAsIGlsZW4gPSAoYm94ZXMgfHwgW10pLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgIGJveCA9IGJveGVzW2ldO1xuICAgICh7cG9zaXRpb246IHBvcywgb3B0aW9uczoge3N0YWNrLCBzdGFja1dlaWdodCA9IDF9fSA9IGJveCk7XG4gICAgbGF5b3V0Qm94ZXMucHVzaCh7XG4gICAgICBpbmRleDogaSxcbiAgICAgIGJveCxcbiAgICAgIHBvcyxcbiAgICAgIGhvcml6b250YWw6IGJveC5pc0hvcml6b250YWwoKSxcbiAgICAgIHdlaWdodDogYm94LndlaWdodCxcbiAgICAgIHN0YWNrOiBzdGFjayAmJiAocG9zICsgc3RhY2spLFxuICAgICAgc3RhY2tXZWlnaHRcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gbGF5b3V0Qm94ZXM7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkU3RhY2tzKGxheW91dHMpIHtcbiAgY29uc3Qgc3RhY2tzID0ge307XG4gIGZvciAoY29uc3Qgd3JhcCBvZiBsYXlvdXRzKSB7XG4gICAgY29uc3Qge3N0YWNrLCBwb3MsIHN0YWNrV2VpZ2h0fSA9IHdyYXA7XG4gICAgaWYgKCFzdGFjayB8fCAhU1RBVElDX1BPU0lUSU9OUy5pbmNsdWRlcyhwb3MpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgX3N0YWNrID0gc3RhY2tzW3N0YWNrXSB8fCAoc3RhY2tzW3N0YWNrXSA9IHtjb3VudDogMCwgcGxhY2VkOiAwLCB3ZWlnaHQ6IDAsIHNpemU6IDB9KTtcbiAgICBfc3RhY2suY291bnQrKztcbiAgICBfc3RhY2sud2VpZ2h0ICs9IHN0YWNrV2VpZ2h0O1xuICB9XG4gIHJldHVybiBzdGFja3M7XG59XG5cbi8qKlxuICogc3RvcmUgZGltZW5zaW9ucyB1c2VkIGluc3RlYWQgb2YgYXZhaWxhYmxlIGNoYXJ0QXJlYSBpbiBmaXRCb3hlc1xuICoqL1xuZnVuY3Rpb24gc2V0TGF5b3V0RGltcyhsYXlvdXRzLCBwYXJhbXMpIHtcbiAgY29uc3Qgc3RhY2tzID0gYnVpbGRTdGFja3MobGF5b3V0cyk7XG4gIGNvbnN0IHt2Qm94TWF4V2lkdGgsIGhCb3hNYXhIZWlnaHR9ID0gcGFyYW1zO1xuICBsZXQgaSwgaWxlbiwgbGF5b3V0O1xuICBmb3IgKGkgPSAwLCBpbGVuID0gbGF5b3V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICBsYXlvdXQgPSBsYXlvdXRzW2ldO1xuICAgIGNvbnN0IHtmdWxsU2l6ZX0gPSBsYXlvdXQuYm94O1xuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tzW2xheW91dC5zdGFja107XG4gICAgY29uc3QgZmFjdG9yID0gc3RhY2sgJiYgbGF5b3V0LnN0YWNrV2VpZ2h0IC8gc3RhY2sud2VpZ2h0O1xuICAgIGlmIChsYXlvdXQuaG9yaXpvbnRhbCkge1xuICAgICAgbGF5b3V0LndpZHRoID0gZmFjdG9yID8gZmFjdG9yICogdkJveE1heFdpZHRoIDogZnVsbFNpemUgJiYgcGFyYW1zLmF2YWlsYWJsZVdpZHRoO1xuICAgICAgbGF5b3V0LmhlaWdodCA9IGhCb3hNYXhIZWlnaHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxheW91dC53aWR0aCA9IHZCb3hNYXhXaWR0aDtcbiAgICAgIGxheW91dC5oZWlnaHQgPSBmYWN0b3IgPyBmYWN0b3IgKiBoQm94TWF4SGVpZ2h0IDogZnVsbFNpemUgJiYgcGFyYW1zLmF2YWlsYWJsZUhlaWdodDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0YWNrcztcbn1cblxuZnVuY3Rpb24gYnVpbGRMYXlvdXRCb3hlcyhib3hlcykge1xuICBjb25zdCBsYXlvdXRCb3hlcyA9IHdyYXBCb3hlcyhib3hlcyk7XG4gIGNvbnN0IGZ1bGxTaXplID0gc29ydEJ5V2VpZ2h0KGxheW91dEJveGVzLmZpbHRlcih3cmFwID0+IHdyYXAuYm94LmZ1bGxTaXplKSwgdHJ1ZSk7XG4gIGNvbnN0IGxlZnQgPSBzb3J0QnlXZWlnaHQoZmlsdGVyQnlQb3NpdGlvbihsYXlvdXRCb3hlcywgJ2xlZnQnKSwgdHJ1ZSk7XG4gIGNvbnN0IHJpZ2h0ID0gc29ydEJ5V2VpZ2h0KGZpbHRlckJ5UG9zaXRpb24obGF5b3V0Qm94ZXMsICdyaWdodCcpKTtcbiAgY29uc3QgdG9wID0gc29ydEJ5V2VpZ2h0KGZpbHRlckJ5UG9zaXRpb24obGF5b3V0Qm94ZXMsICd0b3AnKSwgdHJ1ZSk7XG4gIGNvbnN0IGJvdHRvbSA9IHNvcnRCeVdlaWdodChmaWx0ZXJCeVBvc2l0aW9uKGxheW91dEJveGVzLCAnYm90dG9tJykpO1xuICBjb25zdCBjZW50ZXJIb3Jpem9udGFsID0gZmlsdGVyRHluYW1pY1Bvc2l0aW9uQnlBeGlzKGxheW91dEJveGVzLCAneCcpO1xuICBjb25zdCBjZW50ZXJWZXJ0aWNhbCA9IGZpbHRlckR5bmFtaWNQb3NpdGlvbkJ5QXhpcyhsYXlvdXRCb3hlcywgJ3knKTtcblxuICByZXR1cm4ge1xuICAgIGZ1bGxTaXplLFxuICAgIGxlZnRBbmRUb3A6IGxlZnQuY29uY2F0KHRvcCksXG4gICAgcmlnaHRBbmRCb3R0b206IHJpZ2h0LmNvbmNhdChjZW50ZXJWZXJ0aWNhbCkuY29uY2F0KGJvdHRvbSkuY29uY2F0KGNlbnRlckhvcml6b250YWwpLFxuICAgIGNoYXJ0QXJlYTogZmlsdGVyQnlQb3NpdGlvbihsYXlvdXRCb3hlcywgJ2NoYXJ0QXJlYScpLFxuICAgIHZlcnRpY2FsOiBsZWZ0LmNvbmNhdChyaWdodCkuY29uY2F0KGNlbnRlclZlcnRpY2FsKSxcbiAgICBob3Jpem9udGFsOiB0b3AuY29uY2F0KGJvdHRvbSkuY29uY2F0KGNlbnRlckhvcml6b250YWwpXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldENvbWJpbmVkTWF4KG1heFBhZGRpbmcsIGNoYXJ0QXJlYSwgYSwgYikge1xuICByZXR1cm4gTWF0aC5tYXgobWF4UGFkZGluZ1thXSwgY2hhcnRBcmVhW2FdKSArIE1hdGgubWF4KG1heFBhZGRpbmdbYl0sIGNoYXJ0QXJlYVtiXSk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZU1heFBhZGRpbmcobWF4UGFkZGluZywgYm94UGFkZGluZykge1xuICBtYXhQYWRkaW5nLnRvcCA9IE1hdGgubWF4KG1heFBhZGRpbmcudG9wLCBib3hQYWRkaW5nLnRvcCk7XG4gIG1heFBhZGRpbmcubGVmdCA9IE1hdGgubWF4KG1heFBhZGRpbmcubGVmdCwgYm94UGFkZGluZy5sZWZ0KTtcbiAgbWF4UGFkZGluZy5ib3R0b20gPSBNYXRoLm1heChtYXhQYWRkaW5nLmJvdHRvbSwgYm94UGFkZGluZy5ib3R0b20pO1xuICBtYXhQYWRkaW5nLnJpZ2h0ID0gTWF0aC5tYXgobWF4UGFkZGluZy5yaWdodCwgYm94UGFkZGluZy5yaWdodCk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZURpbXMoY2hhcnRBcmVhLCBwYXJhbXMsIGxheW91dCwgc3RhY2tzKSB7XG4gIGNvbnN0IHtwb3MsIGJveH0gPSBsYXlvdXQ7XG4gIGNvbnN0IG1heFBhZGRpbmcgPSBjaGFydEFyZWEubWF4UGFkZGluZztcblxuICAvLyBkeW5hbWljYWxseSBwbGFjZWQgYm94ZXMgc2l6ZSBpcyBub3QgY29uc2lkZXJlZFxuICBpZiAoIWlzT2JqZWN0KHBvcykpIHtcbiAgICBpZiAobGF5b3V0LnNpemUpIHtcbiAgICAgIC8vIHRoaXMgbGF5b3V0IHdhcyBhbHJlYWR5IGNvdW50ZWQgZm9yLCBsZXRzIGZpcnN0IHJlZHVjZSBvbGQgc2l6ZVxuICAgICAgY2hhcnRBcmVhW3Bvc10gLT0gbGF5b3V0LnNpemU7XG4gICAgfVxuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tzW2xheW91dC5zdGFja10gfHwge3NpemU6IDAsIGNvdW50OiAxfTtcbiAgICBzdGFjay5zaXplID0gTWF0aC5tYXgoc3RhY2suc2l6ZSwgbGF5b3V0Lmhvcml6b250YWwgPyBib3guaGVpZ2h0IDogYm94LndpZHRoKTtcbiAgICBsYXlvdXQuc2l6ZSA9IHN0YWNrLnNpemUgLyBzdGFjay5jb3VudDtcbiAgICBjaGFydEFyZWFbcG9zXSArPSBsYXlvdXQuc2l6ZTtcbiAgfVxuXG4gIGlmIChib3guZ2V0UGFkZGluZykge1xuICAgIHVwZGF0ZU1heFBhZGRpbmcobWF4UGFkZGluZywgYm94LmdldFBhZGRpbmcoKSk7XG4gIH1cblxuICBjb25zdCBuZXdXaWR0aCA9IE1hdGgubWF4KDAsIHBhcmFtcy5vdXRlcldpZHRoIC0gZ2V0Q29tYmluZWRNYXgobWF4UGFkZGluZywgY2hhcnRBcmVhLCAnbGVmdCcsICdyaWdodCcpKTtcbiAgY29uc3QgbmV3SGVpZ2h0ID0gTWF0aC5tYXgoMCwgcGFyYW1zLm91dGVySGVpZ2h0IC0gZ2V0Q29tYmluZWRNYXgobWF4UGFkZGluZywgY2hhcnRBcmVhLCAndG9wJywgJ2JvdHRvbScpKTtcbiAgY29uc3Qgd2lkdGhDaGFuZ2VkID0gbmV3V2lkdGggIT09IGNoYXJ0QXJlYS53O1xuICBjb25zdCBoZWlnaHRDaGFuZ2VkID0gbmV3SGVpZ2h0ICE9PSBjaGFydEFyZWEuaDtcbiAgY2hhcnRBcmVhLncgPSBuZXdXaWR0aDtcbiAgY2hhcnRBcmVhLmggPSBuZXdIZWlnaHQ7XG5cbiAgLy8gcmV0dXJuIGJvb2xlYW5zIG9uIHRoZSBjaGFuZ2VzIHBlciBkaXJlY3Rpb25cbiAgcmV0dXJuIGxheW91dC5ob3Jpem9udGFsXG4gICAgPyB7c2FtZTogd2lkdGhDaGFuZ2VkLCBvdGhlcjogaGVpZ2h0Q2hhbmdlZH1cbiAgICA6IHtzYW1lOiBoZWlnaHRDaGFuZ2VkLCBvdGhlcjogd2lkdGhDaGFuZ2VkfTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlTWF4UGFkZGluZyhjaGFydEFyZWEpIHtcbiAgY29uc3QgbWF4UGFkZGluZyA9IGNoYXJ0QXJlYS5tYXhQYWRkaW5nO1xuXG4gIGZ1bmN0aW9uIHVwZGF0ZVBvcyhwb3MpIHtcbiAgICBjb25zdCBjaGFuZ2UgPSBNYXRoLm1heChtYXhQYWRkaW5nW3Bvc10gLSBjaGFydEFyZWFbcG9zXSwgMCk7XG4gICAgY2hhcnRBcmVhW3Bvc10gKz0gY2hhbmdlO1xuICAgIHJldHVybiBjaGFuZ2U7XG4gIH1cbiAgY2hhcnRBcmVhLnkgKz0gdXBkYXRlUG9zKCd0b3AnKTtcbiAgY2hhcnRBcmVhLnggKz0gdXBkYXRlUG9zKCdsZWZ0Jyk7XG4gIHVwZGF0ZVBvcygncmlnaHQnKTtcbiAgdXBkYXRlUG9zKCdib3R0b20nKTtcbn1cblxuZnVuY3Rpb24gZ2V0TWFyZ2lucyhob3Jpem9udGFsLCBjaGFydEFyZWEpIHtcbiAgY29uc3QgbWF4UGFkZGluZyA9IGNoYXJ0QXJlYS5tYXhQYWRkaW5nO1xuXG4gIGZ1bmN0aW9uIG1hcmdpbkZvclBvc2l0aW9ucyhwb3NpdGlvbnMpIHtcbiAgICBjb25zdCBtYXJnaW4gPSB7bGVmdDogMCwgdG9wOiAwLCByaWdodDogMCwgYm90dG9tOiAwfTtcbiAgICBwb3NpdGlvbnMuZm9yRWFjaCgocG9zKSA9PiB7XG4gICAgICBtYXJnaW5bcG9zXSA9IE1hdGgubWF4KGNoYXJ0QXJlYVtwb3NdLCBtYXhQYWRkaW5nW3Bvc10pO1xuICAgIH0pO1xuICAgIHJldHVybiBtYXJnaW47XG4gIH1cblxuICByZXR1cm4gaG9yaXpvbnRhbFxuICAgID8gbWFyZ2luRm9yUG9zaXRpb25zKFsnbGVmdCcsICdyaWdodCddKVxuICAgIDogbWFyZ2luRm9yUG9zaXRpb25zKFsndG9wJywgJ2JvdHRvbSddKTtcbn1cblxuZnVuY3Rpb24gZml0Qm94ZXMoYm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpIHtcbiAgY29uc3QgcmVmaXRCb3hlcyA9IFtdO1xuICBsZXQgaSwgaWxlbiwgbGF5b3V0LCBib3gsIHJlZml0LCBjaGFuZ2VkO1xuXG4gIGZvciAoaSA9IDAsIGlsZW4gPSBib3hlcy5sZW5ndGgsIHJlZml0ID0gMDsgaSA8IGlsZW47ICsraSkge1xuICAgIGxheW91dCA9IGJveGVzW2ldO1xuICAgIGJveCA9IGxheW91dC5ib3g7XG5cbiAgICBib3gudXBkYXRlKFxuICAgICAgbGF5b3V0LndpZHRoIHx8IGNoYXJ0QXJlYS53LFxuICAgICAgbGF5b3V0LmhlaWdodCB8fCBjaGFydEFyZWEuaCxcbiAgICAgIGdldE1hcmdpbnMobGF5b3V0Lmhvcml6b250YWwsIGNoYXJ0QXJlYSlcbiAgICApO1xuICAgIGNvbnN0IHtzYW1lLCBvdGhlcn0gPSB1cGRhdGVEaW1zKGNoYXJ0QXJlYSwgcGFyYW1zLCBsYXlvdXQsIHN0YWNrcyk7XG5cbiAgICAvLyBEaW1lbnNpb25zIGNoYW5nZWQgYW5kIHRoZXJlIHdlcmUgbm9uIGZ1bGwgd2lkdGggYm94ZXMgYmVmb3JlIHRoaXNcbiAgICAvLyAtPiB3ZSBoYXZlIHRvIHJlZml0IHRob3NlXG4gICAgcmVmaXQgfD0gc2FtZSAmJiByZWZpdEJveGVzLmxlbmd0aDtcblxuICAgIC8vIENoYXJ0IGFyZWEgY2hhbmdlZCBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uXG4gICAgY2hhbmdlZCA9IGNoYW5nZWQgfHwgb3RoZXI7XG5cbiAgICBpZiAoIWJveC5mdWxsU2l6ZSkgeyAvLyBmdWxsU2l6ZSBib3hlcyBkb24ndCBuZWVkIHRvIGJlIHJlLWZpdHRlZCBpbiBhbnkgY2FzZVxuICAgICAgcmVmaXRCb3hlcy5wdXNoKGxheW91dCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlZml0ICYmIGZpdEJveGVzKHJlZml0Qm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpIHx8IGNoYW5nZWQ7XG59XG5cbmZ1bmN0aW9uIHNldEJveERpbXMoYm94LCBsZWZ0LCB0b3AsIHdpZHRoLCBoZWlnaHQpIHtcbiAgYm94LnRvcCA9IHRvcDtcbiAgYm94LmxlZnQgPSBsZWZ0O1xuICBib3gucmlnaHQgPSBsZWZ0ICsgd2lkdGg7XG4gIGJveC5ib3R0b20gPSB0b3AgKyBoZWlnaHQ7XG4gIGJveC53aWR0aCA9IHdpZHRoO1xuICBib3guaGVpZ2h0ID0gaGVpZ2h0O1xufVxuXG5mdW5jdGlvbiBwbGFjZUJveGVzKGJveGVzLCBjaGFydEFyZWEsIHBhcmFtcywgc3RhY2tzKSB7XG4gIGNvbnN0IHVzZXJQYWRkaW5nID0gcGFyYW1zLnBhZGRpbmc7XG4gIGxldCB7eCwgeX0gPSBjaGFydEFyZWE7XG5cbiAgZm9yIChjb25zdCBsYXlvdXQgb2YgYm94ZXMpIHtcbiAgICBjb25zdCBib3ggPSBsYXlvdXQuYm94O1xuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tzW2xheW91dC5zdGFja10gfHwge2NvdW50OiAxLCBwbGFjZWQ6IDAsIHdlaWdodDogMX07XG4gICAgY29uc3Qgd2VpZ2h0ID0gKGxheW91dC5zdGFja1dlaWdodCAvIHN0YWNrLndlaWdodCkgfHwgMTtcbiAgICBpZiAobGF5b3V0Lmhvcml6b250YWwpIHtcbiAgICAgIGNvbnN0IHdpZHRoID0gY2hhcnRBcmVhLncgKiB3ZWlnaHQ7XG4gICAgICBjb25zdCBoZWlnaHQgPSBzdGFjay5zaXplIHx8IGJveC5oZWlnaHQ7XG4gICAgICBpZiAoZGVmaW5lZChzdGFjay5zdGFydCkpIHtcbiAgICAgICAgeSA9IHN0YWNrLnN0YXJ0O1xuICAgICAgfVxuICAgICAgaWYgKGJveC5mdWxsU2l6ZSkge1xuICAgICAgICBzZXRCb3hEaW1zKGJveCwgdXNlclBhZGRpbmcubGVmdCwgeSwgcGFyYW1zLm91dGVyV2lkdGggLSB1c2VyUGFkZGluZy5yaWdodCAtIHVzZXJQYWRkaW5nLmxlZnQsIGhlaWdodCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRCb3hEaW1zKGJveCwgY2hhcnRBcmVhLmxlZnQgKyBzdGFjay5wbGFjZWQsIHksIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgfVxuICAgICAgc3RhY2suc3RhcnQgPSB5O1xuICAgICAgc3RhY2sucGxhY2VkICs9IHdpZHRoO1xuICAgICAgeSA9IGJveC5ib3R0b207XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGhlaWdodCA9IGNoYXJ0QXJlYS5oICogd2VpZ2h0O1xuICAgICAgY29uc3Qgd2lkdGggPSBzdGFjay5zaXplIHx8IGJveC53aWR0aDtcbiAgICAgIGlmIChkZWZpbmVkKHN0YWNrLnN0YXJ0KSkge1xuICAgICAgICB4ID0gc3RhY2suc3RhcnQ7XG4gICAgICB9XG4gICAgICBpZiAoYm94LmZ1bGxTaXplKSB7XG4gICAgICAgIHNldEJveERpbXMoYm94LCB4LCB1c2VyUGFkZGluZy50b3AsIHdpZHRoLCBwYXJhbXMub3V0ZXJIZWlnaHQgLSB1c2VyUGFkZGluZy5ib3R0b20gLSB1c2VyUGFkZGluZy50b3ApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0Qm94RGltcyhib3gsIHgsIGNoYXJ0QXJlYS50b3AgKyBzdGFjay5wbGFjZWQsIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgfVxuICAgICAgc3RhY2suc3RhcnQgPSB4O1xuICAgICAgc3RhY2sucGxhY2VkICs9IGhlaWdodDtcbiAgICAgIHggPSBib3gucmlnaHQ7XG4gICAgfVxuICB9XG5cbiAgY2hhcnRBcmVhLnggPSB4O1xuICBjaGFydEFyZWEueSA9IHk7XG59XG5cbi8qKlxuICogQGludGVyZmFjZSBMYXlvdXRJdGVtXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBMYXlvdXRJdGVtXG4gKiBAcHJvcCB7c3RyaW5nfSBwb3NpdGlvbiAtIFRoZSBwb3NpdGlvbiBvZiB0aGUgaXRlbSBpbiB0aGUgY2hhcnQgbGF5b3V0LiBQb3NzaWJsZSB2YWx1ZXMgYXJlXG4gKiAnbGVmdCcsICd0b3AnLCAncmlnaHQnLCAnYm90dG9tJywgYW5kICdjaGFydEFyZWEnXG4gKiBAcHJvcCB7bnVtYmVyfSB3ZWlnaHQgLSBUaGUgd2VpZ2h0IHVzZWQgdG8gc29ydCB0aGUgaXRlbS4gSGlnaGVyIHdlaWdodHMgYXJlIGZ1cnRoZXIgYXdheSBmcm9tIHRoZSBjaGFydCBhcmVhXG4gKiBAcHJvcCB7Ym9vbGVhbn0gZnVsbFNpemUgLSBpZiB0cnVlLCBhbmQgdGhlIGl0ZW0gaXMgaG9yaXpvbnRhbCwgdGhlbiBwdXNoIHZlcnRpY2FsIGJveGVzIGRvd25cbiAqIEBwcm9wIHtmdW5jdGlvbn0gaXNIb3Jpem9udGFsIC0gcmV0dXJucyB0cnVlIGlmIHRoZSBsYXlvdXQgaXRlbSBpcyBob3Jpem9udGFsIChpZS4gdG9wIG9yIGJvdHRvbSlcbiAqIEBwcm9wIHtmdW5jdGlvbn0gdXBkYXRlIC0gVGFrZXMgdHdvIHBhcmFtZXRlcnM6IHdpZHRoIGFuZCBoZWlnaHQuIFJldHVybnMgc2l6ZSBvZiBpdGVtXG4gKiBAcHJvcCB7ZnVuY3Rpb259IGRyYXcgLSBEcmF3cyB0aGUgZWxlbWVudFxuICogQHByb3Age2Z1bmN0aW9ufSBbZ2V0UGFkZGluZ10gLSAgUmV0dXJucyBhbiBvYmplY3Qgd2l0aCBwYWRkaW5nIG9uIHRoZSBlZGdlc1xuICogQHByb3Age251bWJlcn0gd2lkdGggLSBXaWR0aCBvZiBpdGVtLiBNdXN0IGJlIHZhbGlkIGFmdGVyIHVwZGF0ZSgpXG4gKiBAcHJvcCB7bnVtYmVyfSBoZWlnaHQgLSBIZWlnaHQgb2YgaXRlbS4gTXVzdCBiZSB2YWxpZCBhZnRlciB1cGRhdGUoKVxuICogQHByb3Age251bWJlcn0gbGVmdCAtIExlZnQgZWRnZSBvZiB0aGUgaXRlbS4gU2V0IGJ5IGxheW91dCBzeXN0ZW0gYW5kIGNhbm5vdCBiZSB1c2VkIGluIHVwZGF0ZVxuICogQHByb3Age251bWJlcn0gdG9wIC0gVG9wIGVkZ2Ugb2YgdGhlIGl0ZW0uIFNldCBieSBsYXlvdXQgc3lzdGVtIGFuZCBjYW5ub3QgYmUgdXNlZCBpbiB1cGRhdGVcbiAqIEBwcm9wIHtudW1iZXJ9IHJpZ2h0IC0gUmlnaHQgZWRnZSBvZiB0aGUgaXRlbS4gU2V0IGJ5IGxheW91dCBzeXN0ZW0gYW5kIGNhbm5vdCBiZSB1c2VkIGluIHVwZGF0ZVxuICogQHByb3Age251bWJlcn0gYm90dG9tIC0gQm90dG9tIGVkZ2Ugb2YgdGhlIGl0ZW0uIFNldCBieSBsYXlvdXQgc3lzdGVtIGFuZCBjYW5ub3QgYmUgdXNlZCBpbiB1cGRhdGVcbiAqL1xuXG4vLyBUaGUgbGF5b3V0IHNlcnZpY2UgaXMgdmVyeSBzZWxmIGV4cGxhbmF0b3J5LiAgSXQncyByZXNwb25zaWJsZSBmb3IgdGhlIGxheW91dCB3aXRoaW4gYSBjaGFydC5cbi8vIFNjYWxlcywgTGVnZW5kcyBhbmQgUGx1Z2lucyBhbGwgcmVseSBvbiB0aGUgbGF5b3V0IHNlcnZpY2UgYW5kIGNhbiBlYXNpbHkgcmVnaXN0ZXIgdG8gYmUgcGxhY2VkIGFueXdoZXJlIHRoZXkgbmVlZFxuLy8gSXQgaXMgdGhpcyBzZXJ2aWNlJ3MgcmVzcG9uc2liaWxpdHkgb2YgY2Fycnlpbmcgb3V0IHRoYXQgbGF5b3V0LlxuZXhwb3J0IGRlZmF1bHQge1xuXG4gIC8qKlxuXHQgKiBSZWdpc3RlciBhIGJveCB0byBhIGNoYXJ0LlxuXHQgKiBBIGJveCBpcyBzaW1wbHkgYSByZWZlcmVuY2UgdG8gYW4gb2JqZWN0IHRoYXQgcmVxdWlyZXMgbGF5b3V0LiBlZy4gU2NhbGVzLCBMZWdlbmQsIFRpdGxlLlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB0byB1c2Vcblx0ICogQHBhcmFtIHtMYXlvdXRJdGVtfSBpdGVtIC0gdGhlIGl0ZW0gdG8gYWRkIHRvIGJlIGxhaWQgb3V0XG5cdCAqL1xuICBhZGRCb3goY2hhcnQsIGl0ZW0pIHtcbiAgICBpZiAoIWNoYXJ0LmJveGVzKSB7XG4gICAgICBjaGFydC5ib3hlcyA9IFtdO1xuICAgIH1cblxuICAgIC8vIGluaXRpYWxpemUgaXRlbSB3aXRoIGRlZmF1bHQgdmFsdWVzXG4gICAgaXRlbS5mdWxsU2l6ZSA9IGl0ZW0uZnVsbFNpemUgfHwgZmFsc2U7XG4gICAgaXRlbS5wb3NpdGlvbiA9IGl0ZW0ucG9zaXRpb24gfHwgJ3RvcCc7XG4gICAgaXRlbS53ZWlnaHQgPSBpdGVtLndlaWdodCB8fCAwO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBpdGVtLl9sYXllcnMgPSBpdGVtLl9sYXllcnMgfHwgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gW3tcbiAgICAgICAgejogMCxcbiAgICAgICAgZHJhdyhjaGFydEFyZWEpIHtcbiAgICAgICAgICBpdGVtLmRyYXcoY2hhcnRBcmVhKTtcbiAgICAgICAgfVxuICAgICAgfV07XG4gICAgfTtcblxuICAgIGNoYXJ0LmJveGVzLnB1c2goaXRlbSk7XG4gIH0sXG5cbiAgLyoqXG5cdCAqIFJlbW92ZSBhIGxheW91dEl0ZW0gZnJvbSBhIGNoYXJ0XG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHRvIHJlbW92ZSB0aGUgYm94IGZyb21cblx0ICogQHBhcmFtIHtMYXlvdXRJdGVtfSBsYXlvdXRJdGVtIC0gdGhlIGl0ZW0gdG8gcmVtb3ZlIGZyb20gdGhlIGxheW91dFxuXHQgKi9cbiAgcmVtb3ZlQm94KGNoYXJ0LCBsYXlvdXRJdGVtKSB7XG4gICAgY29uc3QgaW5kZXggPSBjaGFydC5ib3hlcyA/IGNoYXJ0LmJveGVzLmluZGV4T2YobGF5b3V0SXRlbSkgOiAtMTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBjaGFydC5ib3hlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgfSxcblxuICAvKipcblx0ICogU2V0cyAob3IgdXBkYXRlcykgb3B0aW9ucyBvbiB0aGUgZ2l2ZW4gYGl0ZW1gLlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCBpbiB3aGljaCB0aGUgaXRlbSBsaXZlcyAob3Igd2lsbCBiZSBhZGRlZCB0bylcblx0ICogQHBhcmFtIHtMYXlvdXRJdGVtfSBpdGVtIC0gdGhlIGl0ZW0gdG8gY29uZmlndXJlIHdpdGggdGhlIGdpdmVuIG9wdGlvbnNcblx0ICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnMgLSB0aGUgbmV3IGl0ZW0gb3B0aW9ucy5cblx0ICovXG4gIGNvbmZpZ3VyZShjaGFydCwgaXRlbSwgb3B0aW9ucykge1xuICAgIGl0ZW0uZnVsbFNpemUgPSBvcHRpb25zLmZ1bGxTaXplO1xuICAgIGl0ZW0ucG9zaXRpb24gPSBvcHRpb25zLnBvc2l0aW9uO1xuICAgIGl0ZW0ud2VpZ2h0ID0gb3B0aW9ucy53ZWlnaHQ7XG4gIH0sXG5cbiAgLyoqXG5cdCAqIEZpdHMgYm94ZXMgb2YgdGhlIGdpdmVuIGNoYXJ0IGludG8gdGhlIGdpdmVuIHNpemUgYnkgaGF2aW5nIGVhY2ggYm94IG1lYXN1cmUgaXRzZWxmXG5cdCAqIHRoZW4gcnVubmluZyBhIGZpdHRpbmcgYWxnb3JpdGhtXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aCAtIHRoZSB3aWR0aCB0byBmaXQgaW50b1xuXHQgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gdGhlIGhlaWdodCB0byBmaXQgaW50b1xuICAgKiBAcGFyYW0ge251bWJlcn0gbWluUGFkZGluZyAtIG1pbmltdW0gcGFkZGluZyByZXF1aXJlZCBmb3IgZWFjaCBzaWRlIG9mIGNoYXJ0IGFyZWFcblx0ICovXG4gIHVwZGF0ZShjaGFydCwgd2lkdGgsIGhlaWdodCwgbWluUGFkZGluZykge1xuICAgIGlmICghY2hhcnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKGNoYXJ0Lm9wdGlvbnMubGF5b3V0LnBhZGRpbmcpO1xuICAgIGNvbnN0IGF2YWlsYWJsZVdpZHRoID0gTWF0aC5tYXgod2lkdGggLSBwYWRkaW5nLndpZHRoLCAwKTtcbiAgICBjb25zdCBhdmFpbGFibGVIZWlnaHQgPSBNYXRoLm1heChoZWlnaHQgLSBwYWRkaW5nLmhlaWdodCwgMCk7XG4gICAgY29uc3QgYm94ZXMgPSBidWlsZExheW91dEJveGVzKGNoYXJ0LmJveGVzKTtcbiAgICBjb25zdCB2ZXJ0aWNhbEJveGVzID0gYm94ZXMudmVydGljYWw7XG4gICAgY29uc3QgaG9yaXpvbnRhbEJveGVzID0gYm94ZXMuaG9yaXpvbnRhbDtcblxuICAgIC8vIEJlZm9yZSBhbnkgY2hhbmdlcyBhcmUgbWFkZSwgbm90aWZ5IGJveGVzIHRoYXQgYW4gdXBkYXRlIGlzIGFib3V0IHRvIGJlaW5nXG4gICAgLy8gVGhpcyBpcyB1c2VkIHRvIGNsZWFyIGFueSBjYWNoZWQgZGF0YSAoZS5nLiBzY2FsZSBsaW1pdHMpXG4gICAgZWFjaChjaGFydC5ib3hlcywgYm94ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgYm94LmJlZm9yZUxheW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBib3guYmVmb3JlTGF5b3V0KCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBFc3NlbnRpYWxseSB3ZSBub3cgaGF2ZSBhbnkgbnVtYmVyIG9mIGJveGVzIG9uIGVhY2ggb2YgdGhlIDQgc2lkZXMuXG4gICAgLy8gT3VyIGNhbnZhcyBsb29rcyBsaWtlIHRoZSBmb2xsb3dpbmcuXG4gICAgLy8gVGhlIGFyZWFzIEwxIGFuZCBMMiBhcmUgdGhlIGxlZnQgYXhlcy4gUjEgaXMgdGhlIHJpZ2h0IGF4aXMsIFQxIGlzIHRoZSB0b3AgYXhpcyBhbmRcbiAgICAvLyBCMSBpcyB0aGUgYm90dG9tIGF4aXNcbiAgICAvLyBUaGVyZSBhcmUgYWxzbyA0IHF1YWRyYW50LWxpa2UgbG9jYXRpb25zIChsZWZ0IHRvIHJpZ2h0IGluc3RlYWQgb2YgY2xvY2t3aXNlKSByZXNlcnZlZCBmb3IgY2hhcnQgb3ZlcmxheXNcbiAgICAvLyBUaGVzZSBsb2NhdGlvbnMgYXJlIHNpbmdsZS1ib3ggbG9jYXRpb25zIG9ubHksIHdoZW4gdHJ5aW5nIHRvIHJlZ2lzdGVyIGEgY2hhcnRBcmVhIGxvY2F0aW9uIHRoYXQgaXMgYWxyZWFkeSB0YWtlbixcbiAgICAvLyBhbiBlcnJvciB3aWxsIGJlIHRocm93bi5cbiAgICAvL1xuICAgIC8vIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICAgIC8vIHwgICAgICAgICAgICAgICAgICBUMSAoRnVsbCBXaWR0aCkgICAgICAgICAgICAgICAgICAgfFxuICAgIC8vIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICAgIC8vIHwgICAgfCAgICB8ICAgICAgICAgICAgICAgICBUMiAgICAgICAgICAgICAgICAgIHwgICAgfFxuICAgIC8vIHwgICAgfC0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tfFxuICAgIC8vIHwgICAgfCAgICB8IEMxIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEMyIHwgICAgfFxuICAgIC8vIHwgICAgfCAgICB8LS0tLXwgICAgICAgICAgICAgICAgICAgICAgICAgICB8LS0tLXwgICAgfFxuICAgIC8vIHwgICAgfCAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgfFxuICAgIC8vIHwgTDEgfCBMMiB8ICAgICAgICAgICBDaGFydEFyZWEgKEMwKSAgICAgICAgICAgIHwgUjEgfFxuICAgIC8vIHwgICAgfCAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgfFxuICAgIC8vIHwgICAgfCAgICB8LS0tLXwgICAgICAgICAgICAgICAgICAgICAgICAgICB8LS0tLXwgICAgfFxuICAgIC8vIHwgICAgfCAgICB8IEMzIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEM0IHwgICAgfFxuICAgIC8vIHwgICAgfC0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tfFxuICAgIC8vIHwgICAgfCAgICB8ICAgICAgICAgICAgICAgICBCMSAgICAgICAgICAgICAgICAgIHwgICAgfFxuICAgIC8vIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICAgIC8vIHwgICAgICAgICAgICAgICAgICBCMiAoRnVsbCBXaWR0aCkgICAgICAgICAgICAgICAgICAgfFxuICAgIC8vIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICAgIC8vXG5cbiAgICBjb25zdCB2aXNpYmxlVmVydGljYWxCb3hDb3VudCA9IHZlcnRpY2FsQm94ZXMucmVkdWNlKCh0b3RhbCwgd3JhcCkgPT5cbiAgICAgIHdyYXAuYm94Lm9wdGlvbnMgJiYgd3JhcC5ib3gub3B0aW9ucy5kaXNwbGF5ID09PSBmYWxzZSA/IHRvdGFsIDogdG90YWwgKyAxLCAwKSB8fCAxO1xuXG4gICAgY29uc3QgcGFyYW1zID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgICBvdXRlcldpZHRoOiB3aWR0aCxcbiAgICAgIG91dGVySGVpZ2h0OiBoZWlnaHQsXG4gICAgICBwYWRkaW5nLFxuICAgICAgYXZhaWxhYmxlV2lkdGgsXG4gICAgICBhdmFpbGFibGVIZWlnaHQsXG4gICAgICB2Qm94TWF4V2lkdGg6IGF2YWlsYWJsZVdpZHRoIC8gMiAvIHZpc2libGVWZXJ0aWNhbEJveENvdW50LFxuICAgICAgaEJveE1heEhlaWdodDogYXZhaWxhYmxlSGVpZ2h0IC8gMlxuICAgIH0pO1xuICAgIGNvbnN0IG1heFBhZGRpbmcgPSBPYmplY3QuYXNzaWduKHt9LCBwYWRkaW5nKTtcbiAgICB1cGRhdGVNYXhQYWRkaW5nKG1heFBhZGRpbmcsIHRvUGFkZGluZyhtaW5QYWRkaW5nKSk7XG4gICAgY29uc3QgY2hhcnRBcmVhID0gT2JqZWN0LmFzc2lnbih7XG4gICAgICBtYXhQYWRkaW5nLFxuICAgICAgdzogYXZhaWxhYmxlV2lkdGgsXG4gICAgICBoOiBhdmFpbGFibGVIZWlnaHQsXG4gICAgICB4OiBwYWRkaW5nLmxlZnQsXG4gICAgICB5OiBwYWRkaW5nLnRvcFxuICAgIH0sIHBhZGRpbmcpO1xuXG4gICAgY29uc3Qgc3RhY2tzID0gc2V0TGF5b3V0RGltcyh2ZXJ0aWNhbEJveGVzLmNvbmNhdChob3Jpem9udGFsQm94ZXMpLCBwYXJhbXMpO1xuXG4gICAgLy8gRmlyc3QgZml0IHRoZSBmdWxsU2l6ZSBib3hlcywgdG8gcmVkdWNlIHByb2JhYmlsaXR5IG9mIHJlLWZpdHRpbmcuXG4gICAgZml0Qm94ZXMoYm94ZXMuZnVsbFNpemUsIGNoYXJ0QXJlYSwgcGFyYW1zLCBzdGFja3MpO1xuXG4gICAgLy8gVGhlbiBmaXQgdmVydGljYWwgYm94ZXNcbiAgICBmaXRCb3hlcyh2ZXJ0aWNhbEJveGVzLCBjaGFydEFyZWEsIHBhcmFtcywgc3RhY2tzKTtcblxuICAgIC8vIFRoZW4gZml0IGhvcml6b250YWwgYm94ZXNcbiAgICBpZiAoZml0Qm94ZXMoaG9yaXpvbnRhbEJveGVzLCBjaGFydEFyZWEsIHBhcmFtcywgc3RhY2tzKSkge1xuICAgICAgLy8gaWYgdGhlIGFyZWEgY2hhbmdlZCwgcmUtZml0IHZlcnRpY2FsIGJveGVzXG4gICAgICBmaXRCb3hlcyh2ZXJ0aWNhbEJveGVzLCBjaGFydEFyZWEsIHBhcmFtcywgc3RhY2tzKTtcbiAgICB9XG5cbiAgICBoYW5kbGVNYXhQYWRkaW5nKGNoYXJ0QXJlYSk7XG5cbiAgICAvLyBGaW5hbGx5IHBsYWNlIHRoZSBib3hlcyB0byBjb3JyZWN0IGNvb3JkaW5hdGVzXG4gICAgcGxhY2VCb3hlcyhib3hlcy5sZWZ0QW5kVG9wLCBjaGFydEFyZWEsIHBhcmFtcywgc3RhY2tzKTtcblxuICAgIC8vIE1vdmUgdG8gb3Bwb3NpdGUgc2lkZSBvZiBjaGFydFxuICAgIGNoYXJ0QXJlYS54ICs9IGNoYXJ0QXJlYS53O1xuICAgIGNoYXJ0QXJlYS55ICs9IGNoYXJ0QXJlYS5oO1xuXG4gICAgcGxhY2VCb3hlcyhib3hlcy5yaWdodEFuZEJvdHRvbSwgY2hhcnRBcmVhLCBwYXJhbXMsIHN0YWNrcyk7XG5cbiAgICBjaGFydC5jaGFydEFyZWEgPSB7XG4gICAgICBsZWZ0OiBjaGFydEFyZWEubGVmdCxcbiAgICAgIHRvcDogY2hhcnRBcmVhLnRvcCxcbiAgICAgIHJpZ2h0OiBjaGFydEFyZWEubGVmdCArIGNoYXJ0QXJlYS53LFxuICAgICAgYm90dG9tOiBjaGFydEFyZWEudG9wICsgY2hhcnRBcmVhLmgsXG4gICAgICBoZWlnaHQ6IGNoYXJ0QXJlYS5oLFxuICAgICAgd2lkdGg6IGNoYXJ0QXJlYS53LFxuICAgIH07XG5cbiAgICAvLyBGaW5hbGx5IHVwZGF0ZSBib3hlcyBpbiBjaGFydEFyZWEgKHJhZGlhbCBzY2FsZSBmb3IgZXhhbXBsZSlcbiAgICBlYWNoKGJveGVzLmNoYXJ0QXJlYSwgKGxheW91dCkgPT4ge1xuICAgICAgY29uc3QgYm94ID0gbGF5b3V0LmJveDtcbiAgICAgIE9iamVjdC5hc3NpZ24oYm94LCBjaGFydC5jaGFydEFyZWEpO1xuICAgICAgYm94LnVwZGF0ZShjaGFydEFyZWEudywgY2hhcnRBcmVhLmgsIHtsZWZ0OiAwLCB0b3A6IDAsIHJpZ2h0OiAwLCBib3R0b206IDB9KTtcbiAgICB9KTtcbiAgfVxufTtcbiIsICJcbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL2NvcmUvY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IENoYXJ0XG4gKi9cblxuLyoqXG4gKiBBYnN0cmFjdCBjbGFzcyB0aGF0IGFsbG93cyBhYnN0cmFjdGluZyBwbGF0Zm9ybSBkZXBlbmRlbmNpZXMgYXdheSBmcm9tIHRoZSBjaGFydC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmFzZVBsYXRmb3JtIHtcbiAgLyoqXG5cdCAqIENhbGxlZCBhdCBjaGFydCBjb25zdHJ1Y3Rpb24gdGltZSwgcmV0dXJucyBhIGNvbnRleHQyZCBpbnN0YW5jZSBpbXBsZW1lbnRpbmdcblx0ICogdGhlIFtXM0MgQ2FudmFzIDJEIENvbnRleHQgQVBJIHN0YW5kYXJkXXtAbGluayBodHRwczovL3d3dy53My5vcmcvVFIvMmRjb250ZXh0L30uXG5cdCAqIEBwYXJhbSB7SFRNTENhbnZhc0VsZW1lbnR9IGNhbnZhcyAtIFRoZSBjYW52YXMgZnJvbSB3aGljaCB0byBhY3F1aXJlIGNvbnRleHQgKHBsYXRmb3JtIHNwZWNpZmljKVxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2FzcGVjdFJhdGlvXSAtIFRoZSBjaGFydCBvcHRpb25zXG5cdCAqL1xuICBhY3F1aXJlQ29udGV4dChjYW52YXMsIGFzcGVjdFJhdGlvKSB7fSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG5cbiAgLyoqXG5cdCAqIENhbGxlZCBhdCBjaGFydCBkZXN0cnVjdGlvbiB0aW1lLCByZWxlYXNlcyBhbnkgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIGNvbnRleHRcblx0ICogcHJldmlvdXNseSByZXR1cm5lZCBieSB0aGUgYWNxdWlyZUNvbnRleHQoKSBtZXRob2QuXG5cdCAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IC0gVGhlIGNvbnRleHQyZCBpbnN0YW5jZVxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgbWV0aG9kIHN1Y2NlZWRlZCwgZWxzZSBmYWxzZVxuXHQgKi9cbiAgcmVsZWFzZUNvbnRleHQoY29udGV4dCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJlZ2lzdGVycyB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyIG9uIHRoZSBnaXZlbiBjaGFydC5cblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBDaGFydCBmcm9tIHdoaWNoIHRvIGxpc3RlbiBmb3IgZXZlbnRcblx0ICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgLSBUaGUgKHtAbGluayBDaGFydEV2ZW50fSkgdHlwZSB0byBsaXN0ZW4gZm9yXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIC0gUmVjZWl2ZXMgYSBub3RpZmljYXRpb24gKGFuIG9iamVjdCB0aGF0IGltcGxlbWVudHNcblx0ICogdGhlIHtAbGluayBDaGFydEV2ZW50fSBpbnRlcmZhY2UpIHdoZW4gYW4gZXZlbnQgb2YgdGhlIHNwZWNpZmllZCB0eXBlIG9jY3Vycy5cblx0ICovXG4gIGFkZEV2ZW50TGlzdGVuZXIoY2hhcnQsIHR5cGUsIGxpc3RlbmVyKSB7fSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG5cbiAgLyoqXG5cdCAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBhZGRFdmVudExpc3RlbmVyLlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIENoYXJ0IGZyb20gd2hpY2ggdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSAoe0BsaW5rIENoYXJ0RXZlbnR9KSB0eXBlIHRvIHJlbW92ZVxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsaXN0ZW5lciAtIFRoZSBsaXN0ZW5lciBmdW5jdGlvbiB0byByZW1vdmUgZnJvbSB0aGUgZXZlbnQgdGFyZ2V0LlxuXHQgKi9cbiAgcmVtb3ZlRXZlbnRMaXN0ZW5lcihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcblxuICAvKipcblx0ICogQHJldHVybnMge251bWJlcn0gdGhlIGN1cnJlbnQgZGV2aWNlUGl4ZWxSYXRpbyBvZiB0aGUgZGV2aWNlIHRoaXMgcGxhdGZvcm0gaXMgY29ubmVjdGVkIHRvLlxuXHQgKi9cbiAgZ2V0RGV2aWNlUGl4ZWxSYXRpbygpIHtcbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHNpemUgaW4gcGl4ZWxzIG9mIGdpdmVuIGNhbnZhcyBlbGVtZW50LlxuXHQgKiBAcGFyYW0ge0hUTUxDYW52YXNFbGVtZW50fSBlbGVtZW50XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbd2lkdGhdIC0gY29udGVudCB3aWR0aCBvZiBwYXJlbnQgZWxlbWVudFxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2hlaWdodF0gLSBjb250ZW50IGhlaWdodCBvZiBwYXJlbnQgZWxlbWVudFxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2FzcGVjdFJhdGlvXSAtIGFzcGVjdCByYXRpbyB0byBtYWludGFpblxuXHQgKi9cbiAgZ2V0TWF4aW11bVNpemUoZWxlbWVudCwgd2lkdGgsIGhlaWdodCwgYXNwZWN0UmF0aW8pIHtcbiAgICB3aWR0aCA9IE1hdGgubWF4KDAsIHdpZHRoIHx8IGVsZW1lbnQud2lkdGgpO1xuICAgIGhlaWdodCA9IGhlaWdodCB8fCBlbGVtZW50LmhlaWdodDtcbiAgICByZXR1cm4ge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQ6IE1hdGgubWF4KDAsIGFzcGVjdFJhdGlvID8gTWF0aC5mbG9vcih3aWR0aCAvIGFzcGVjdFJhdGlvKSA6IGhlaWdodClcbiAgICB9O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7SFRNTENhbnZhc0VsZW1lbnR9IGNhbnZhc1xuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgY2FudmFzIGlzIGF0dGFjaGVkIHRvIHRoZSBwbGF0Zm9ybSwgZmFsc2UgaWYgbm90LlxuXHQgKi9cbiAgaXNBdHRhY2hlZChjYW52YXMpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgY29uZmlnIHdpdGggcGxhdGZvcm0gc3BlY2lmaWMgcmVxdWlyZW1lbnRzXG4gICAqIEBwYXJhbSB7aW1wb3J0KCcuLi9jb3JlL2NvcmUuY29uZmlnLmpzJykuZGVmYXVsdH0gY29uZmlnXG4gICAqL1xuICB1cGRhdGVDb25maWcoY29uZmlnKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAvLyBuby1vcFxuICB9XG59XG4iLCAiLyoqXG4gKiBQbGF0Zm9ybSBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbiAobWluaW1hbCkuXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL3B1bGwvNDU5MSNpc3N1ZWNvbW1lbnQtMzE5NTc1OTM5XG4gKi9cblxuaW1wb3J0IEJhc2VQbGF0Zm9ybSBmcm9tICcuL3BsYXRmb3JtLmJhc2UuanMnO1xuXG4vKipcbiAqIFBsYXRmb3JtIGNsYXNzIGZvciBjaGFydHMgd2l0aG91dCBhY2Nlc3MgdG8gdGhlIERPTSBvciB0byBtYW55IGVsZW1lbnQgcHJvcGVydGllc1xuICogVGhpcyBwbGF0Zm9ybSBpcyB1c2VkIGJ5IGRlZmF1bHQgZm9yIGFueSBjaGFydCBwYXNzZWQgYW4gT2Zmc2NyZWVuQ2FudmFzLlxuICogQGV4dGVuZHMgQmFzZVBsYXRmb3JtXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhc2ljUGxhdGZvcm0gZXh0ZW5kcyBCYXNlUGxhdGZvcm0ge1xuICBhY3F1aXJlQ29udGV4dChpdGVtKSB7XG4gICAgLy8gVG8gcHJldmVudCBjYW52YXMgZmluZ2VycHJpbnRpbmcsIHNvbWUgYWRkLW9ucyB1bmRlZmluZSB0aGUgZ2V0Q29udGV4dFxuICAgIC8vIG1ldGhvZCwgZm9yIGV4YW1wbGU6IGh0dHBzOi8vZ2l0aHViLmNvbS9ra2Fwc25lci9DYW52YXNCbG9ja2VyXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzI4MDdcbiAgICByZXR1cm4gaXRlbSAmJiBpdGVtLmdldENvbnRleHQgJiYgaXRlbS5nZXRDb250ZXh0KCcyZCcpIHx8IG51bGw7XG4gIH1cbiAgdXBkYXRlQ29uZmlnKGNvbmZpZykge1xuICAgIGNvbmZpZy5vcHRpb25zLmFuaW1hdGlvbiA9IGZhbHNlO1xuICB9XG59XG4iLCAiLyoqXG4gKiBDaGFydC5QbGF0Zm9ybSBpbXBsZW1lbnRhdGlvbiBmb3IgdGFyZ2V0aW5nIGEgd2ViIGJyb3dzZXJcbiAqL1xuXG5pbXBvcnQgQmFzZVBsYXRmb3JtIGZyb20gJy4vcGxhdGZvcm0uYmFzZS5qcyc7XG5pbXBvcnQge19nZXRQYXJlbnROb2RlLCBnZXRSZWxhdGl2ZVBvc2l0aW9uLCBzdXBwb3J0c0V2ZW50TGlzdGVuZXJPcHRpb25zLCByZWFkVXNlZFNpemUsIGdldE1heGltdW1TaXplfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZG9tLmpzJztcbmltcG9ydCB7dGhyb3R0bGVkfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZXh0cmFzLmpzJztcbmltcG9ydCB7aXNOdWxsT3JVbmRlZn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi9jb3JlL2NvcmUuY29udHJvbGxlci5qcycpLmRlZmF1bHQgfSBDaGFydFxuICovXG5cbmNvbnN0IEVYUEFORE9fS0VZID0gJyRjaGFydGpzJztcblxuLyoqXG4gKiBET00gZXZlbnQgdHlwZXMgLT4gQ2hhcnQuanMgZXZlbnQgdHlwZXMuXG4gKiBOb3RlOiBvbmx5IGV2ZW50cyB3aXRoIGRpZmZlcmVudCB0eXBlcyBhcmUgbWFwcGVkLlxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9FdmVudHNcbiAqL1xuY29uc3QgRVZFTlRfVFlQRVMgPSB7XG4gIHRvdWNoc3RhcnQ6ICdtb3VzZWRvd24nLFxuICB0b3VjaG1vdmU6ICdtb3VzZW1vdmUnLFxuICB0b3VjaGVuZDogJ21vdXNldXAnLFxuICBwb2ludGVyZW50ZXI6ICdtb3VzZWVudGVyJyxcbiAgcG9pbnRlcmRvd246ICdtb3VzZWRvd24nLFxuICBwb2ludGVybW92ZTogJ21vdXNlbW92ZScsXG4gIHBvaW50ZXJ1cDogJ21vdXNldXAnLFxuICBwb2ludGVybGVhdmU6ICdtb3VzZW91dCcsXG4gIHBvaW50ZXJvdXQ6ICdtb3VzZW91dCdcbn07XG5cbmNvbnN0IGlzTnVsbE9yRW1wdHkgPSB2YWx1ZSA9PiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gJyc7XG4vKipcbiAqIEluaXRpYWxpemVzIHRoZSBjYW52YXMgc3R5bGUgYW5kIHJlbmRlciBzaXplIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSBjYW52YXMgZGlzcGxheSBzaXplLFxuICogc2luY2UgcmVzcG9uc2l2ZW5lc3MgaXMgaGFuZGxlZCBieSB0aGUgY29udHJvbGxlci5yZXNpemUoKSBtZXRob2QuIFRoZSBjb25maWcgaXMgdXNlZFxuICogdG8gZGV0ZXJtaW5lIHRoZSBhc3BlY3QgcmF0aW8gdG8gYXBwbHkgaW4gY2FzZSBubyBleHBsaWNpdCBoZWlnaHQgaGFzIGJlZW4gc3BlY2lmaWVkLlxuICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzXG4gKiBAcGFyYW0ge251bWJlcn0gW2FzcGVjdFJhdGlvXVxuICovXG5mdW5jdGlvbiBpbml0Q2FudmFzKGNhbnZhcywgYXNwZWN0UmF0aW8pIHtcbiAgY29uc3Qgc3R5bGUgPSBjYW52YXMuc3R5bGU7XG5cbiAgLy8gTk9URShTQikgY2FudmFzLmdldEF0dHJpYnV0ZSgnd2lkdGgnKSAhPT0gY2FudmFzLndpZHRoOiBpbiB0aGUgZmlyc3QgY2FzZSBpdFxuICAvLyByZXR1cm5zIG51bGwgb3IgJycgaWYgbm8gZXhwbGljaXQgdmFsdWUgaGFzIGJlZW4gc2V0IHRvIHRoZSBjYW52YXMgYXR0cmlidXRlLlxuICBjb25zdCByZW5kZXJIZWlnaHQgPSBjYW52YXMuZ2V0QXR0cmlidXRlKCdoZWlnaHQnKTtcbiAgY29uc3QgcmVuZGVyV2lkdGggPSBjYW52YXMuZ2V0QXR0cmlidXRlKCd3aWR0aCcpO1xuXG4gIC8vIENoYXJ0LmpzIG1vZGlmaWVzIHNvbWUgY2FudmFzIHZhbHVlcyB0aGF0IHdlIHdhbnQgdG8gcmVzdG9yZSBvbiBkZXN0cm95XG4gIGNhbnZhc1tFWFBBTkRPX0tFWV0gPSB7XG4gICAgaW5pdGlhbDoge1xuICAgICAgaGVpZ2h0OiByZW5kZXJIZWlnaHQsXG4gICAgICB3aWR0aDogcmVuZGVyV2lkdGgsXG4gICAgICBzdHlsZToge1xuICAgICAgICBkaXNwbGF5OiBzdHlsZS5kaXNwbGF5LFxuICAgICAgICBoZWlnaHQ6IHN0eWxlLmhlaWdodCxcbiAgICAgICAgd2lkdGg6IHN0eWxlLndpZHRoXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8vIEZvcmNlIGNhbnZhcyB0byBkaXNwbGF5IGFzIGJsb2NrIHRvIGF2b2lkIGV4dHJhIHNwYWNlIGNhdXNlZCBieSBpbmxpbmVcbiAgLy8gZWxlbWVudHMsIHdoaWNoIHdvdWxkIGludGVyZmVyZSB3aXRoIHRoZSByZXNwb25zaXZlIHJlc2l6ZSBwcm9jZXNzLlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMjUzOFxuICBzdHlsZS5kaXNwbGF5ID0gc3R5bGUuZGlzcGxheSB8fCAnYmxvY2snO1xuICAvLyBJbmNsdWRlIHBvc3NpYmxlIGJvcmRlcnMgaW4gdGhlIHNpemVcbiAgc3R5bGUuYm94U2l6aW5nID0gc3R5bGUuYm94U2l6aW5nIHx8ICdib3JkZXItYm94JztcblxuICBpZiAoaXNOdWxsT3JFbXB0eShyZW5kZXJXaWR0aCkpIHtcbiAgICBjb25zdCBkaXNwbGF5V2lkdGggPSByZWFkVXNlZFNpemUoY2FudmFzLCAnd2lkdGgnKTtcbiAgICBpZiAoZGlzcGxheVdpZHRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNhbnZhcy53aWR0aCA9IGRpc3BsYXlXaWR0aDtcbiAgICB9XG4gIH1cblxuICBpZiAoaXNOdWxsT3JFbXB0eShyZW5kZXJIZWlnaHQpKSB7XG4gICAgaWYgKGNhbnZhcy5zdHlsZS5oZWlnaHQgPT09ICcnKSB7XG4gICAgICAvLyBJZiBubyBleHBsaWNpdCByZW5kZXIgaGVpZ2h0IGFuZCBzdHlsZSBoZWlnaHQsIGxldCdzIGFwcGx5IHRoZSBhc3BlY3QgcmF0aW8sXG4gICAgICAvLyB3aGljaCBvbmUgY2FuIGJlIHNwZWNpZmllZCBieSB0aGUgdXNlciBidXQgYWxzbyBieSBjaGFydHMgYXMgZGVmYXVsdCBvcHRpb25cbiAgICAgIC8vIChpLmUuIG9wdGlvbnMuYXNwZWN0UmF0aW8pLiBJZiBub3Qgc3BlY2lmaWVkLCB1c2UgY2FudmFzIGFzcGVjdCByYXRpbyBvZiAyLlxuICAgICAgY2FudmFzLmhlaWdodCA9IGNhbnZhcy53aWR0aCAvIChhc3BlY3RSYXRpbyB8fCAyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZGlzcGxheUhlaWdodCA9IHJlYWRVc2VkU2l6ZShjYW52YXMsICdoZWlnaHQnKTtcbiAgICAgIGlmIChkaXNwbGF5SGVpZ2h0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2FudmFzLmhlaWdodCA9IGRpc3BsYXlIZWlnaHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNhbnZhcztcbn1cblxuLy8gRGVmYXVsdCBwYXNzaXZlIHRvIHRydWUgYXMgZXhwZWN0ZWQgYnkgQ2hyb21lIGZvciAndG91Y2hzdGFydCcgYW5kICd0b3VjaGVuZCcgZXZlbnRzLlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzQyODdcbmNvbnN0IGV2ZW50TGlzdGVuZXJPcHRpb25zID0gc3VwcG9ydHNFdmVudExpc3RlbmVyT3B0aW9ucyA/IHtwYXNzaXZlOiB0cnVlfSA6IGZhbHNlO1xuXG5mdW5jdGlvbiBhZGRMaXN0ZW5lcihub2RlLCB0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAobm9kZSkge1xuICAgIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgZXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoY2hhcnQgJiYgY2hhcnQuY2FudmFzKSB7XG4gICAgY2hhcnQuY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIsIGV2ZW50TGlzdGVuZXJPcHRpb25zKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmcm9tTmF0aXZlRXZlbnQoZXZlbnQsIGNoYXJ0KSB7XG4gIGNvbnN0IHR5cGUgPSBFVkVOVF9UWVBFU1tldmVudC50eXBlXSB8fCBldmVudC50eXBlO1xuICBjb25zdCB7eCwgeX0gPSBnZXRSZWxhdGl2ZVBvc2l0aW9uKGV2ZW50LCBjaGFydCk7XG4gIHJldHVybiB7XG4gICAgdHlwZSxcbiAgICBjaGFydCxcbiAgICBuYXRpdmU6IGV2ZW50LFxuICAgIHg6IHggIT09IHVuZGVmaW5lZCA/IHggOiBudWxsLFxuICAgIHk6IHkgIT09IHVuZGVmaW5lZCA/IHkgOiBudWxsLFxuICB9O1xufVxuXG5mdW5jdGlvbiBub2RlTGlzdENvbnRhaW5zKG5vZGVMaXN0LCBjYW52YXMpIHtcbiAgZm9yIChjb25zdCBub2RlIG9mIG5vZGVMaXN0KSB7XG4gICAgaWYgKG5vZGUgPT09IGNhbnZhcyB8fCBub2RlLmNvbnRhaW5zKGNhbnZhcykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVBdHRhY2hPYnNlcnZlcihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgY29uc3QgY2FudmFzID0gY2hhcnQuY2FudmFzO1xuICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGVudHJpZXMgPT4ge1xuICAgIGxldCB0cmlnZ2VyID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICB0cmlnZ2VyID0gdHJpZ2dlciB8fCBub2RlTGlzdENvbnRhaW5zKGVudHJ5LmFkZGVkTm9kZXMsIGNhbnZhcyk7XG4gICAgICB0cmlnZ2VyID0gdHJpZ2dlciAmJiAhbm9kZUxpc3RDb250YWlucyhlbnRyeS5yZW1vdmVkTm9kZXMsIGNhbnZhcyk7XG4gICAgfVxuICAgIGlmICh0cmlnZ2VyKSB7XG4gICAgICBsaXN0ZW5lcigpO1xuICAgIH1cbiAgfSk7XG4gIG9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQsIHtjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWV9KTtcbiAgcmV0dXJuIG9ic2VydmVyO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVEZXRhY2hPYnNlcnZlcihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgY29uc3QgY2FudmFzID0gY2hhcnQuY2FudmFzO1xuICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGVudHJpZXMgPT4ge1xuICAgIGxldCB0cmlnZ2VyID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICB0cmlnZ2VyID0gdHJpZ2dlciB8fCBub2RlTGlzdENvbnRhaW5zKGVudHJ5LnJlbW92ZWROb2RlcywgY2FudmFzKTtcbiAgICAgIHRyaWdnZXIgPSB0cmlnZ2VyICYmICFub2RlTGlzdENvbnRhaW5zKGVudHJ5LmFkZGVkTm9kZXMsIGNhbnZhcyk7XG4gICAgfVxuICAgIGlmICh0cmlnZ2VyKSB7XG4gICAgICBsaXN0ZW5lcigpO1xuICAgIH1cbiAgfSk7XG4gIG9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQsIHtjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWV9KTtcbiAgcmV0dXJuIG9ic2VydmVyO1xufVxuXG5jb25zdCBkcnBMaXN0ZW5pbmdDaGFydHMgPSBuZXcgTWFwKCk7XG5sZXQgb2xkRGV2aWNlUGl4ZWxSYXRpbyA9IDA7XG5cbmZ1bmN0aW9uIG9uV2luZG93UmVzaXplKCkge1xuICBjb25zdCBkcHIgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgaWYgKGRwciA9PT0gb2xkRGV2aWNlUGl4ZWxSYXRpbykge1xuICAgIHJldHVybjtcbiAgfVxuICBvbGREZXZpY2VQaXhlbFJhdGlvID0gZHByO1xuICBkcnBMaXN0ZW5pbmdDaGFydHMuZm9yRWFjaCgocmVzaXplLCBjaGFydCkgPT4ge1xuICAgIGlmIChjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyAhPT0gZHByKSB7XG4gICAgICByZXNpemUoKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBsaXN0ZW5EZXZpY2VQaXhlbFJhdGlvQ2hhbmdlcyhjaGFydCwgcmVzaXplKSB7XG4gIGlmICghZHJwTGlzdGVuaW5nQ2hhcnRzLnNpemUpIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgb25XaW5kb3dSZXNpemUpO1xuICB9XG4gIGRycExpc3RlbmluZ0NoYXJ0cy5zZXQoY2hhcnQsIHJlc2l6ZSk7XG59XG5cbmZ1bmN0aW9uIHVubGlzdGVuRGV2aWNlUGl4ZWxSYXRpb0NoYW5nZXMoY2hhcnQpIHtcbiAgZHJwTGlzdGVuaW5nQ2hhcnRzLmRlbGV0ZShjaGFydCk7XG4gIGlmICghZHJwTGlzdGVuaW5nQ2hhcnRzLnNpemUpIHtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgb25XaW5kb3dSZXNpemUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVJlc2l6ZU9ic2VydmVyKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge1xuICBjb25zdCBjYW52YXMgPSBjaGFydC5jYW52YXM7XG4gIGNvbnN0IGNvbnRhaW5lciA9IGNhbnZhcyAmJiBfZ2V0UGFyZW50Tm9kZShjYW52YXMpO1xuICBpZiAoIWNvbnRhaW5lcikge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCByZXNpemUgPSB0aHJvdHRsZWQoKHdpZHRoLCBoZWlnaHQpID0+IHtcbiAgICBjb25zdCB3ID0gY29udGFpbmVyLmNsaWVudFdpZHRoO1xuICAgIGxpc3RlbmVyKHdpZHRoLCBoZWlnaHQpO1xuICAgIGlmICh3IDwgY29udGFpbmVyLmNsaWVudFdpZHRoKSB7XG4gICAgICAvLyBJZiB0aGUgY29udGFpbmVyIHNpemUgc2hyYW5rIGR1cmluZyBjaGFydCByZXNpemUsIGxldCdzIGFzc3VtZVxuICAgICAgLy8gc2Nyb2xsYmFyIGFwcGVhcmVkLiBTbyB3ZSByZXNpemUgYWdhaW4gd2l0aCB0aGUgc2Nyb2xsYmFyIHZpc2libGUgLVxuICAgICAgLy8gZWZmZWN0aXZlbHkgbWFraW5nIGNoYXJ0IHNtYWxsZXIgYW5kIHRoZSBzY3JvbGxiYXIgaGlkZGVuIGFnYWluLlxuICAgICAgLy8gQmVjYXVzZSB3ZSBhcmUgaW5zaWRlIGB0aHJvdHRsZWRgLCBhbmQgY3VycmVudGx5IGB0aWNraW5nYCwgc2Nyb2xsXG4gICAgICAvLyBldmVudHMgYXJlIGlnbm9yZWQgZHVyaW5nIHRoaXMgd2hvbGUgMiByZXNpemUgcHJvY2Vzcy5cbiAgICAgIC8vIElmIHdlIGFzc3VtZWQgd3JvbmcgYW5kIHNvbWV0aGluZyBlbHNlIGhhcHBlbmVkLCB3ZSBhcmUgcmVzaXppbmdcbiAgICAgIC8vIHR3aWNlIGluIGEgZnJhbWUgKHBvdGVudGlhbCBwZXJmb3JtYW5jZSBpc3N1ZSlcbiAgICAgIGxpc3RlbmVyKCk7XG4gICAgfVxuICB9LCB3aW5kb3cpO1xuXG4gIC8vIEB0cy1pZ25vcmUgdW50aWwgaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy8zNzg2MSBpbXBsZW1lbnRlZFxuICBjb25zdCBvYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcihlbnRyaWVzID0+IHtcbiAgICBjb25zdCBlbnRyeSA9IGVudHJpZXNbMF07XG4gICAgY29uc3Qgd2lkdGggPSBlbnRyeS5jb250ZW50UmVjdC53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSBlbnRyeS5jb250ZW50UmVjdC5oZWlnaHQ7XG4gICAgLy8gV2hlbiBpdHMgY29udGFpbmVyJ3MgZGlzcGxheSBpcyBzZXQgdG8gJ25vbmUnIHRoZSBjYWxsYmFjayB3aWxsIGJlIGNhbGxlZCB3aXRoIGFcbiAgICAvLyBzaXplIG9mICgwLCAwKSwgd2hpY2ggd2lsbCBjYXVzZSB0aGUgY2hhcnQgdG8gbG9zZSBpdHMgb3JpZ2luYWwgaGVpZ2h0LCBzbyBza2lwXG4gICAgLy8gcmVzaXppbmcgaW4gc3VjaCBjYXNlLlxuICAgIGlmICh3aWR0aCA9PT0gMCAmJiBoZWlnaHQgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmVzaXplKHdpZHRoLCBoZWlnaHQpO1xuICB9KTtcbiAgb2JzZXJ2ZXIub2JzZXJ2ZShjb250YWluZXIpO1xuICBsaXN0ZW5EZXZpY2VQaXhlbFJhdGlvQ2hhbmdlcyhjaGFydCwgcmVzaXplKTtcblxuICByZXR1cm4gb2JzZXJ2ZXI7XG59XG5cbmZ1bmN0aW9uIHJlbGVhc2VPYnNlcnZlcihjaGFydCwgdHlwZSwgb2JzZXJ2ZXIpIHtcbiAgaWYgKG9ic2VydmVyKSB7XG4gICAgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICB9XG4gIGlmICh0eXBlID09PSAncmVzaXplJykge1xuICAgIHVubGlzdGVuRGV2aWNlUGl4ZWxSYXRpb0NoYW5nZXMoY2hhcnQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVByb3h5QW5kTGlzdGVuKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge1xuICBjb25zdCBjYW52YXMgPSBjaGFydC5jYW52YXM7XG4gIGNvbnN0IHByb3h5ID0gdGhyb3R0bGVkKChldmVudCkgPT4ge1xuICAgIC8vIFRoaXMgY2FzZSBjYW4gb2NjdXIgaWYgdGhlIGNoYXJ0IGlzIGRlc3Ryb3llZCB3aGlsZSB3YWl0aW5nXG4gICAgLy8gZm9yIHRoZSB0aHJvdHRsZWQgZnVuY3Rpb24gdG8gb2NjdXIuIFdlIHByZXZlbnQgY3Jhc2hlcyBieSBjaGVja2luZ1xuICAgIC8vIGZvciBhIGRlc3Ryb3llZCBjaGFydFxuICAgIGlmIChjaGFydC5jdHggIT09IG51bGwpIHtcbiAgICAgIGxpc3RlbmVyKGZyb21OYXRpdmVFdmVudChldmVudCwgY2hhcnQpKTtcbiAgICB9XG4gIH0sIGNoYXJ0KTtcblxuICBhZGRMaXN0ZW5lcihjYW52YXMsIHR5cGUsIHByb3h5KTtcblxuICByZXR1cm4gcHJveHk7XG59XG5cbi8qKlxuICogUGxhdGZvcm0gY2xhc3MgZm9yIGNoYXJ0cyB0aGF0IGNhbiBhY2Nlc3MgdGhlIERPTSBhbmQgZ2xvYmFsIHdpbmRvdy9kb2N1bWVudCBwcm9wZXJ0aWVzXG4gKiBAZXh0ZW5kcyBCYXNlUGxhdGZvcm1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRG9tUGxhdGZvcm0gZXh0ZW5kcyBCYXNlUGxhdGZvcm0ge1xuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge0hUTUxDYW52YXNFbGVtZW50fSBjYW52YXNcblx0ICogQHBhcmFtIHtudW1iZXJ9IFthc3BlY3RSYXRpb11cblx0ICogQHJldHVybiB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfG51bGx9XG5cdCAqL1xuICBhY3F1aXJlQ29udGV4dChjYW52YXMsIGFzcGVjdFJhdGlvKSB7XG4gICAgLy8gVG8gcHJldmVudCBjYW52YXMgZmluZ2VycHJpbnRpbmcsIHNvbWUgYWRkLW9ucyB1bmRlZmluZSB0aGUgZ2V0Q29udGV4dFxuICAgIC8vIG1ldGhvZCwgZm9yIGV4YW1wbGU6IGh0dHBzOi8vZ2l0aHViLmNvbS9ra2Fwc25lci9DYW52YXNCbG9ja2VyXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzI4MDdcbiAgICBjb25zdCBjb250ZXh0ID0gY2FudmFzICYmIGNhbnZhcy5nZXRDb250ZXh0ICYmIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuXG4gICAgLy8gYGluc3RhbmNlb2YgSFRNTENhbnZhc0VsZW1lbnQvQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEYCBmYWlscyB3aGVuIHRoZSBjYW52YXMgaXNcbiAgICAvLyBpbnNpZGUgYW4gaWZyYW1lIG9yIHdoZW4gcnVubmluZyBpbiBhIHByb3RlY3RlZCBlbnZpcm9ubWVudC4gV2UgY291bGQgZ3Vlc3MgdGhlXG4gICAgLy8gdHlwZXMgZnJvbSB0aGVpciB0b1N0cmluZygpIHZhbHVlIGJ1dCBsZXQncyBrZWVwIHRoaW5ncyBmbGV4aWJsZSBhbmQgYXNzdW1lIGl0J3NcbiAgICAvLyBhIHN1ZmZpY2llbnQgY29uZGl0aW9uIGlmIHRoZSBjYW52YXMgaGFzIGEgY29udGV4dDJEIHdoaWNoIGhhcyBjYW52YXMgYXMgYGNhbnZhc2AuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzM4ODdcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNDEwMlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy80MTUyXG4gICAgaWYgKGNvbnRleHQgJiYgY29udGV4dC5jYW52YXMgPT09IGNhbnZhcykge1xuICAgICAgLy8gTG9hZCBwbGF0Zm9ybSByZXNvdXJjZXMgb24gZmlyc3QgY2hhcnQgY3JlYXRpb24sIHRvIG1ha2UgaXQgcG9zc2libGUgdG9cbiAgICAgIC8vIGltcG9ydCB0aGUgbGlicmFyeSBiZWZvcmUgc2V0dGluZyBwbGF0Zm9ybSBvcHRpb25zLlxuICAgICAgaW5pdENhbnZhcyhjYW52YXMsIGFzcGVjdFJhdGlvKTtcbiAgICAgIHJldHVybiBjb250ZXh0O1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0XG5cdCAqL1xuICByZWxlYXNlQ29udGV4dChjb250ZXh0KSB7XG4gICAgY29uc3QgY2FudmFzID0gY29udGV4dC5jYW52YXM7XG4gICAgaWYgKCFjYW52YXNbRVhQQU5ET19LRVldKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgaW5pdGlhbCA9IGNhbnZhc1tFWFBBTkRPX0tFWV0uaW5pdGlhbDtcbiAgICBbJ2hlaWdodCcsICd3aWR0aCddLmZvckVhY2goKHByb3ApID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gaW5pdGlhbFtwcm9wXTtcbiAgICAgIGlmIChpc051bGxPclVuZGVmKHZhbHVlKSkge1xuICAgICAgICBjYW52YXMucmVtb3ZlQXR0cmlidXRlKHByb3ApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FudmFzLnNldEF0dHJpYnV0ZShwcm9wLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBzdHlsZSA9IGluaXRpYWwuc3R5bGUgfHwge307XG4gICAgT2JqZWN0LmtleXMoc3R5bGUpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgY2FudmFzLnN0eWxlW2tleV0gPSBzdHlsZVtrZXldO1xuICAgIH0pO1xuXG4gICAgLy8gVGhlIGNhbnZhcyByZW5kZXIgc2l6ZSBtaWdodCBoYXZlIGJlZW4gY2hhbmdlZCAoYW5kIHRodXMgdGhlIHN0YXRlIHN0YWNrIGRpc2NhcmRlZCksXG4gICAgLy8gd2UgY2FuJ3QgdXNlIHNhdmUoKSBhbmQgcmVzdG9yZSgpIHRvIHJlc3RvcmUgdGhlIGluaXRpYWwgc3RhdGUuIFNvIG1ha2Ugc3VyZSB0aGF0IGF0XG4gICAgLy8gbGVhc3QgdGhlIGNhbnZhcyBjb250ZXh0IGlzIHJlc2V0IHRvIHRoZSBkZWZhdWx0IHN0YXRlIGJ5IHNldHRpbmcgdGhlIGNhbnZhcyB3aWR0aC5cbiAgICAvLyBodHRwczovL3d3dy53My5vcmcvVFIvMjAxMS9XRC1odG1sNS0yMDExMDUyNS90aGUtY2FudmFzLWVsZW1lbnQuaHRtbFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWFzc2lnblxuICAgIGNhbnZhcy53aWR0aCA9IGNhbnZhcy53aWR0aDtcblxuICAgIGRlbGV0ZSBjYW52YXNbRVhQQU5ET19LRVldO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG5cdCAqXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyXG5cdCAqL1xuICBhZGRFdmVudExpc3RlbmVyKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge1xuICAgIC8vIENhbiBoYXZlIG9ubHkgb25lIGxpc3RlbmVyIHBlciB0eXBlLCBzbyBtYWtlIHN1cmUgcHJldmlvdXMgaXMgcmVtb3ZlZFxuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihjaGFydCwgdHlwZSk7XG5cbiAgICBjb25zdCBwcm94aWVzID0gY2hhcnQuJHByb3hpZXMgfHwgKGNoYXJ0LiRwcm94aWVzID0ge30pO1xuICAgIGNvbnN0IGhhbmRsZXJzID0ge1xuICAgICAgYXR0YWNoOiBjcmVhdGVBdHRhY2hPYnNlcnZlcixcbiAgICAgIGRldGFjaDogY3JlYXRlRGV0YWNoT2JzZXJ2ZXIsXG4gICAgICByZXNpemU6IGNyZWF0ZVJlc2l6ZU9ic2VydmVyXG4gICAgfTtcbiAgICBjb25zdCBoYW5kbGVyID0gaGFuZGxlcnNbdHlwZV0gfHwgY3JlYXRlUHJveHlBbmRMaXN0ZW47XG4gICAgcHJveGllc1t0eXBlXSA9IGhhbmRsZXIoY2hhcnQsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG5cdCAqL1xuICByZW1vdmVFdmVudExpc3RlbmVyKGNoYXJ0LCB0eXBlKSB7XG4gICAgY29uc3QgcHJveGllcyA9IGNoYXJ0LiRwcm94aWVzIHx8IChjaGFydC4kcHJveGllcyA9IHt9KTtcbiAgICBjb25zdCBwcm94eSA9IHByb3hpZXNbdHlwZV07XG5cbiAgICBpZiAoIXByb3h5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaGFuZGxlcnMgPSB7XG4gICAgICBhdHRhY2g6IHJlbGVhc2VPYnNlcnZlcixcbiAgICAgIGRldGFjaDogcmVsZWFzZU9ic2VydmVyLFxuICAgICAgcmVzaXplOiByZWxlYXNlT2JzZXJ2ZXJcbiAgICB9O1xuICAgIGNvbnN0IGhhbmRsZXIgPSBoYW5kbGVyc1t0eXBlXSB8fCByZW1vdmVMaXN0ZW5lcjtcbiAgICBoYW5kbGVyKGNoYXJ0LCB0eXBlLCBwcm94eSk7XG4gICAgcHJveGllc1t0eXBlXSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGdldERldmljZVBpeGVsUmF0aW8oKSB7XG4gICAgcmV0dXJuIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7SFRNTENhbnZhc0VsZW1lbnR9IGNhbnZhc1xuXHQgKiBAcGFyYW0ge251bWJlcn0gW3dpZHRoXSAtIGNvbnRlbnQgd2lkdGggb2YgcGFyZW50IGVsZW1lbnRcblx0ICogQHBhcmFtIHtudW1iZXJ9IFtoZWlnaHRdIC0gY29udGVudCBoZWlnaHQgb2YgcGFyZW50IGVsZW1lbnRcblx0ICogQHBhcmFtIHtudW1iZXJ9IFthc3BlY3RSYXRpb10gLSBhc3BlY3QgcmF0aW8gdG8gbWFpbnRhaW5cblx0ICovXG4gIGdldE1heGltdW1TaXplKGNhbnZhcywgd2lkdGgsIGhlaWdodCwgYXNwZWN0UmF0aW8pIHtcbiAgICByZXR1cm4gZ2V0TWF4aW11bVNpemUoY2FudmFzLCB3aWR0aCwgaGVpZ2h0LCBhc3BlY3RSYXRpbyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzXG5cdCAqL1xuICBpc0F0dGFjaGVkKGNhbnZhcykge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IF9nZXRQYXJlbnROb2RlKGNhbnZhcyk7XG4gICAgcmV0dXJuICEhKGNvbnRhaW5lciAmJiBjb250YWluZXIuaXNDb25uZWN0ZWQpO1xuICB9XG59XG4iLCAiaW1wb3J0IHtfaXNEb21TdXBwb3J0ZWR9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuaW1wb3J0IEJhc2VQbGF0Zm9ybSBmcm9tICcuL3BsYXRmb3JtLmJhc2UuanMnO1xuaW1wb3J0IEJhc2ljUGxhdGZvcm0gZnJvbSAnLi9wbGF0Zm9ybS5iYXNpYy5qcyc7XG5pbXBvcnQgRG9tUGxhdGZvcm0gZnJvbSAnLi9wbGF0Zm9ybS5kb20uanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gX2RldGVjdFBsYXRmb3JtKGNhbnZhcykge1xuICBpZiAoIV9pc0RvbVN1cHBvcnRlZCgpIHx8ICh0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzICE9PSAndW5kZWZpbmVkJyAmJiBjYW52YXMgaW5zdGFuY2VvZiBPZmZzY3JlZW5DYW52YXMpKSB7XG4gICAgcmV0dXJuIEJhc2ljUGxhdGZvcm07XG4gIH1cbiAgcmV0dXJuIERvbVBsYXRmb3JtO1xufVxuXG5leHBvcnQge0Jhc2VQbGF0Zm9ybSwgQmFzaWNQbGF0Zm9ybSwgRG9tUGxhdGZvcm19O1xuIiwgImltcG9ydCB0eXBlIHtBbnlPYmplY3R9IGZyb20gJy4uL3R5cGVzL2Jhc2ljLmpzJztcbmltcG9ydCB0eXBlIHtQb2ludH0gZnJvbSAnLi4vdHlwZXMvZ2VvbWV0cmljLmpzJztcbmltcG9ydCB0eXBlIHtBbmltYXRpb259IGZyb20gJy4uL3R5cGVzL2FuaW1hdGlvbi5qcyc7XG5pbXBvcnQge2lzTnVtYmVyfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMubWF0aC5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEVsZW1lbnQ8VCA9IEFueU9iamVjdCwgTyA9IEFueU9iamVjdD4ge1xuXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHt9O1xuICBzdGF0aWMgZGVmYXVsdFJvdXRlcyA9IHVuZGVmaW5lZDtcblxuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbiAgYWN0aXZlID0gZmFsc2U7XG4gIG9wdGlvbnM6IE87XG4gICRhbmltYXRpb25zOiBSZWNvcmQ8a2V5b2YgVCwgQW5pbWF0aW9uPjtcblxuICB0b29sdGlwUG9zaXRpb24odXNlRmluYWxQb3NpdGlvbjogYm9vbGVhbik6IFBvaW50IHtcbiAgICBjb25zdCB7eCwgeX0gPSB0aGlzLmdldFByb3BzKFsneCcsICd5J10sIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIHJldHVybiB7eCwgeX0gYXMgUG9pbnQ7XG4gIH1cblxuICBoYXNWYWx1ZSgpIHtcbiAgICByZXR1cm4gaXNOdW1iZXIodGhpcy54KSAmJiBpc051bWJlcih0aGlzLnkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGN1cnJlbnQgb3IgZmluYWwgdmFsdWUgb2YgZWFjaCBwcm9wLiBDYW4gcmV0dXJuIGV4dHJhIHByb3BlcnRpZXMgKHdob2xlIG9iamVjdCkuXG4gICAqIEBwYXJhbSBwcm9wcyAtIHByb3BlcnRpZXMgdG8gZ2V0XG4gICAqIEBwYXJhbSBbZmluYWxdIC0gZ2V0IHRoZSBmaW5hbCB2YWx1ZSAoYW5pbWF0aW9uIHRhcmdldClcbiAgICovXG4gIGdldFByb3BzPFAgZXh0ZW5kcyAoa2V5b2YgVClbXT4ocHJvcHM6IFAsIGZpbmFsPzogYm9vbGVhbik6IFBpY2s8VCwgUFtudW1iZXJdPjtcbiAgZ2V0UHJvcHM8UCBleHRlbmRzIHN0cmluZz4ocHJvcHM6IFBbXSwgZmluYWw/OiBib29sZWFuKTogUGFydGlhbDxSZWNvcmQ8UCwgdW5rbm93bj4+O1xuICBnZXRQcm9wcyhwcm9wczogc3RyaW5nW10sIGZpbmFsPzogYm9vbGVhbik6IFBhcnRpYWw8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgICBjb25zdCBhbmltcyA9IHRoaXMuJGFuaW1hdGlvbnM7XG4gICAgaWYgKCFmaW5hbCB8fCAhYW5pbXMpIHtcbiAgICAgIC8vIGxldCdzIG5vdCBjcmVhdGUgYW4gb2JqZWN0LCBpZiBub3QgbmVlZGVkXG4gICAgICByZXR1cm4gdGhpcyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICB9XG4gICAgY29uc3QgcmV0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgIHByb3BzLmZvckVhY2goKHByb3ApID0+IHtcbiAgICAgIHJldFtwcm9wXSA9IGFuaW1zW3Byb3BdICYmIGFuaW1zW3Byb3BdLmFjdGl2ZSgpID8gYW5pbXNbcHJvcF0uX3RvIDogdGhpc1twcm9wIGFzIHN0cmluZ107XG4gICAgfSk7XG4gICAgcmV0dXJuIHJldDtcbiAgfVxufVxuIiwgImltcG9ydCB7aXNOdWxsT3JVbmRlZiwgdmFsdWVPckRlZmF1bHR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7X2ZhY3Rvcml6ZX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuXG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4vY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IENoYXJ0XG4gKiBAdHlwZWRlZiB7e3ZhbHVlOm51bWJlciB8IHN0cmluZywgbGFiZWw/OnN0cmluZywgbWFqb3I/OmJvb2xlYW4sICRjb250ZXh0Pzphbnl9fSBUaWNrXG4gKi9cblxuLyoqXG4gKiBSZXR1cm5zIGEgc3Vic2V0IG9mIHRpY2tzIHRvIGJlIHBsb3R0ZWQgdG8gYXZvaWQgb3ZlcmxhcHBpbmcgbGFiZWxzLlxuICogQHBhcmFtIHtpbXBvcnQoJy4vY29yZS5zY2FsZS5qcycpLmRlZmF1bHR9IHNjYWxlXG4gKiBAcGFyYW0ge1RpY2tbXX0gdGlja3NcbiAqIEByZXR1cm4ge1RpY2tbXX1cbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhdXRvU2tpcChzY2FsZSwgdGlja3MpIHtcbiAgY29uc3QgdGlja09wdHMgPSBzY2FsZS5vcHRpb25zLnRpY2tzO1xuICBjb25zdCBkZXRlcm1pbmVkTWF4VGlja3MgPSBkZXRlcm1pbmVNYXhUaWNrcyhzY2FsZSk7XG4gIGNvbnN0IHRpY2tzTGltaXQgPSBNYXRoLm1pbih0aWNrT3B0cy5tYXhUaWNrc0xpbWl0IHx8IGRldGVybWluZWRNYXhUaWNrcywgZGV0ZXJtaW5lZE1heFRpY2tzKTtcbiAgY29uc3QgbWFqb3JJbmRpY2VzID0gdGlja09wdHMubWFqb3IuZW5hYmxlZCA/IGdldE1ham9ySW5kaWNlcyh0aWNrcykgOiBbXTtcbiAgY29uc3QgbnVtTWFqb3JJbmRpY2VzID0gbWFqb3JJbmRpY2VzLmxlbmd0aDtcbiAgY29uc3QgZmlyc3QgPSBtYWpvckluZGljZXNbMF07XG4gIGNvbnN0IGxhc3QgPSBtYWpvckluZGljZXNbbnVtTWFqb3JJbmRpY2VzIC0gMV07XG4gIGNvbnN0IG5ld1RpY2tzID0gW107XG5cbiAgLy8gSWYgdGhlcmUgYXJlIHRvbyBtYW55IG1ham9yIHRpY2tzIHRvIGRpc3BsYXkgdGhlbSBhbGxcbiAgaWYgKG51bU1ham9ySW5kaWNlcyA+IHRpY2tzTGltaXQpIHtcbiAgICBza2lwTWFqb3JzKHRpY2tzLCBuZXdUaWNrcywgbWFqb3JJbmRpY2VzLCBudW1NYWpvckluZGljZXMgLyB0aWNrc0xpbWl0KTtcbiAgICByZXR1cm4gbmV3VGlja3M7XG4gIH1cblxuICBjb25zdCBzcGFjaW5nID0gY2FsY3VsYXRlU3BhY2luZyhtYWpvckluZGljZXMsIHRpY2tzLCB0aWNrc0xpbWl0KTtcblxuICBpZiAobnVtTWFqb3JJbmRpY2VzID4gMCkge1xuICAgIGxldCBpLCBpbGVuO1xuICAgIGNvbnN0IGF2Z01ham9yU3BhY2luZyA9IG51bU1ham9ySW5kaWNlcyA+IDEgPyBNYXRoLnJvdW5kKChsYXN0IC0gZmlyc3QpIC8gKG51bU1ham9ySW5kaWNlcyAtIDEpKSA6IG51bGw7XG4gICAgc2tpcCh0aWNrcywgbmV3VGlja3MsIHNwYWNpbmcsIGlzTnVsbE9yVW5kZWYoYXZnTWFqb3JTcGFjaW5nKSA/IDAgOiBmaXJzdCAtIGF2Z01ham9yU3BhY2luZywgZmlyc3QpO1xuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBudW1NYWpvckluZGljZXMgLSAxOyBpIDwgaWxlbjsgaSsrKSB7XG4gICAgICBza2lwKHRpY2tzLCBuZXdUaWNrcywgc3BhY2luZywgbWFqb3JJbmRpY2VzW2ldLCBtYWpvckluZGljZXNbaSArIDFdKTtcbiAgICB9XG4gICAgc2tpcCh0aWNrcywgbmV3VGlja3MsIHNwYWNpbmcsIGxhc3QsIGlzTnVsbE9yVW5kZWYoYXZnTWFqb3JTcGFjaW5nKSA/IHRpY2tzLmxlbmd0aCA6IGxhc3QgKyBhdmdNYWpvclNwYWNpbmcpO1xuICAgIHJldHVybiBuZXdUaWNrcztcbiAgfVxuICBza2lwKHRpY2tzLCBuZXdUaWNrcywgc3BhY2luZyk7XG4gIHJldHVybiBuZXdUaWNrcztcbn1cblxuZnVuY3Rpb24gZGV0ZXJtaW5lTWF4VGlja3Moc2NhbGUpIHtcbiAgY29uc3Qgb2Zmc2V0ID0gc2NhbGUub3B0aW9ucy5vZmZzZXQ7XG4gIGNvbnN0IHRpY2tMZW5ndGggPSBzY2FsZS5fdGlja1NpemUoKTtcbiAgY29uc3QgbWF4U2NhbGUgPSBzY2FsZS5fbGVuZ3RoIC8gdGlja0xlbmd0aCArIChvZmZzZXQgPyAwIDogMSk7XG4gIGNvbnN0IG1heENoYXJ0ID0gc2NhbGUuX21heExlbmd0aCAvIHRpY2tMZW5ndGg7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGgubWluKG1heFNjYWxlLCBtYXhDaGFydCkpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyW119IG1ham9ySW5kaWNlc1xuICogQHBhcmFtIHtUaWNrW119IHRpY2tzXG4gKiBAcGFyYW0ge251bWJlcn0gdGlja3NMaW1pdFxuICovXG5mdW5jdGlvbiBjYWxjdWxhdGVTcGFjaW5nKG1ham9ySW5kaWNlcywgdGlja3MsIHRpY2tzTGltaXQpIHtcbiAgY29uc3QgZXZlbk1ham9yU3BhY2luZyA9IGdldEV2ZW5TcGFjaW5nKG1ham9ySW5kaWNlcyk7XG4gIGNvbnN0IHNwYWNpbmcgPSB0aWNrcy5sZW5ndGggLyB0aWNrc0xpbWl0O1xuXG4gIC8vIElmIHRoZSBtYWpvciB0aWNrcyBhcmUgZXZlbmx5IHNwYWNlZCBhcGFydCwgcGxhY2UgdGhlIG1pbm9yIHRpY2tzXG4gIC8vIHNvIHRoYXQgdGhleSBkaXZpZGUgdGhlIG1ham9yIHRpY2tzIGludG8gZXZlbiBjaHVua3NcbiAgaWYgKCFldmVuTWFqb3JTcGFjaW5nKSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KHNwYWNpbmcsIDEpO1xuICB9XG5cbiAgY29uc3QgZmFjdG9ycyA9IF9mYWN0b3JpemUoZXZlbk1ham9yU3BhY2luZyk7XG4gIGZvciAobGV0IGkgPSAwLCBpbGVuID0gZmFjdG9ycy5sZW5ndGggLSAxOyBpIDwgaWxlbjsgaSsrKSB7XG4gICAgY29uc3QgZmFjdG9yID0gZmFjdG9yc1tpXTtcbiAgICBpZiAoZmFjdG9yID4gc3BhY2luZykge1xuICAgICAgcmV0dXJuIGZhY3RvcjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIE1hdGgubWF4KHNwYWNpbmcsIDEpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7VGlja1tdfSB0aWNrc1xuICovXG5mdW5jdGlvbiBnZXRNYWpvckluZGljZXModGlja3MpIHtcbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGxldCBpLCBpbGVuO1xuICBmb3IgKGkgPSAwLCBpbGVuID0gdGlja3MubGVuZ3RoOyBpIDwgaWxlbjsgaSsrKSB7XG4gICAgaWYgKHRpY2tzW2ldLm1ham9yKSB7XG4gICAgICByZXN1bHQucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1RpY2tbXX0gdGlja3NcbiAqIEBwYXJhbSB7VGlja1tdfSBuZXdUaWNrc1xuICogQHBhcmFtIHtudW1iZXJbXX0gbWFqb3JJbmRpY2VzXG4gKiBAcGFyYW0ge251bWJlcn0gc3BhY2luZ1xuICovXG5mdW5jdGlvbiBza2lwTWFqb3JzKHRpY2tzLCBuZXdUaWNrcywgbWFqb3JJbmRpY2VzLCBzcGFjaW5nKSB7XG4gIGxldCBjb3VudCA9IDA7XG4gIGxldCBuZXh0ID0gbWFqb3JJbmRpY2VzWzBdO1xuICBsZXQgaTtcblxuICBzcGFjaW5nID0gTWF0aC5jZWlsKHNwYWNpbmcpO1xuICBmb3IgKGkgPSAwOyBpIDwgdGlja3MubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaSA9PT0gbmV4dCkge1xuICAgICAgbmV3VGlja3MucHVzaCh0aWNrc1tpXSk7XG4gICAgICBjb3VudCsrO1xuICAgICAgbmV4dCA9IG1ham9ySW5kaWNlc1tjb3VudCAqIHNwYWNpbmddO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VGlja1tdfSB0aWNrc1xuICogQHBhcmFtIHtUaWNrW119IG5ld1RpY2tzXG4gKiBAcGFyYW0ge251bWJlcn0gc3BhY2luZ1xuICogQHBhcmFtIHtudW1iZXJ9IFttYWpvclN0YXJ0XVxuICogQHBhcmFtIHtudW1iZXJ9IFttYWpvckVuZF1cbiAqL1xuZnVuY3Rpb24gc2tpcCh0aWNrcywgbmV3VGlja3MsIHNwYWNpbmcsIG1ham9yU3RhcnQsIG1ham9yRW5kKSB7XG4gIGNvbnN0IHN0YXJ0ID0gdmFsdWVPckRlZmF1bHQobWFqb3JTdGFydCwgMCk7XG4gIGNvbnN0IGVuZCA9IE1hdGgubWluKHZhbHVlT3JEZWZhdWx0KG1ham9yRW5kLCB0aWNrcy5sZW5ndGgpLCB0aWNrcy5sZW5ndGgpO1xuICBsZXQgY291bnQgPSAwO1xuICBsZXQgbGVuZ3RoLCBpLCBuZXh0O1xuXG4gIHNwYWNpbmcgPSBNYXRoLmNlaWwoc3BhY2luZyk7XG4gIGlmIChtYWpvckVuZCkge1xuICAgIGxlbmd0aCA9IG1ham9yRW5kIC0gbWFqb3JTdGFydDtcbiAgICBzcGFjaW5nID0gbGVuZ3RoIC8gTWF0aC5mbG9vcihsZW5ndGggLyBzcGFjaW5nKTtcbiAgfVxuXG4gIG5leHQgPSBzdGFydDtcblxuICB3aGlsZSAobmV4dCA8IDApIHtcbiAgICBjb3VudCsrO1xuICAgIG5leHQgPSBNYXRoLnJvdW5kKHN0YXJ0ICsgY291bnQgKiBzcGFjaW5nKTtcbiAgfVxuXG4gIGZvciAoaSA9IE1hdGgubWF4KHN0YXJ0LCAwKTsgaSA8IGVuZDsgaSsrKSB7XG4gICAgaWYgKGkgPT09IG5leHQpIHtcbiAgICAgIG5ld1RpY2tzLnB1c2godGlja3NbaV0pO1xuICAgICAgY291bnQrKztcbiAgICAgIG5leHQgPSBNYXRoLnJvdW5kKHN0YXJ0ICsgY291bnQgKiBzcGFjaW5nKTtcbiAgICB9XG4gIH1cbn1cblxuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyW119IGFyclxuICovXG5mdW5jdGlvbiBnZXRFdmVuU3BhY2luZyhhcnIpIHtcbiAgY29uc3QgbGVuID0gYXJyLmxlbmd0aDtcbiAgbGV0IGksIGRpZmY7XG5cbiAgaWYgKGxlbiA8IDIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3IgKGRpZmYgPSBhcnJbMF0sIGkgPSAxOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYXJyW2ldIC0gYXJyW2kgLSAxXSAhPT0gZGlmZikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGlmZjtcbn1cbiIsICJpbXBvcnQgRWxlbWVudCBmcm9tICcuL2NvcmUuZWxlbWVudC5qcyc7XG5pbXBvcnQge19hbGlnblBpeGVsLCBfbWVhc3VyZVRleHQsIHJlbmRlclRleHQsIGNsaXBBcmVhLCB1bmNsaXBBcmVhfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY2FudmFzLmpzJztcbmltcG9ydCB7Y2FsbGJhY2sgYXMgY2FsbCwgZWFjaCwgZmluaXRlT3JEZWZhdWx0LCBpc0FycmF5LCBpc0Zpbml0ZSwgaXNOdWxsT3JVbmRlZiwgaXNPYmplY3QsIHZhbHVlT3JEZWZhdWx0fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge3RvRGVncmVlcywgdG9SYWRpYW5zLCBfaW50MTZSYW5nZSwgX2xpbWl0VmFsdWUsIEhBTEZfUEl9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCB7X2FsaWduU3RhcnRFbmQsIF90b0xlZnRSaWdodENlbnRlcn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmV4dHJhcy5qcyc7XG5pbXBvcnQge2NyZWF0ZUNvbnRleHQsIHRvRm9udCwgdG9QYWRkaW5nLCBfYWRkR3JhY2V9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5vcHRpb25zLmpzJztcbmltcG9ydCB7YXV0b1NraXB9IGZyb20gJy4vY29yZS5zY2FsZS5hdXRvc2tpcC5qcyc7XG5cbmNvbnN0IHJldmVyc2VBbGlnbiA9IChhbGlnbikgPT4gYWxpZ24gPT09ICdsZWZ0JyA/ICdyaWdodCcgOiBhbGlnbiA9PT0gJ3JpZ2h0JyA/ICdsZWZ0JyA6IGFsaWduO1xuY29uc3Qgb2Zmc2V0RnJvbUVkZ2UgPSAoc2NhbGUsIGVkZ2UsIG9mZnNldCkgPT4gZWRnZSA9PT0gJ3RvcCcgfHwgZWRnZSA9PT0gJ2xlZnQnID8gc2NhbGVbZWRnZV0gKyBvZmZzZXQgOiBzY2FsZVtlZGdlXSAtIG9mZnNldDtcbmNvbnN0IGdldFRpY2tzTGltaXQgPSAodGlja3NMZW5ndGgsIG1heFRpY2tzTGltaXQpID0+IE1hdGgubWluKG1heFRpY2tzTGltaXQgfHwgdGlja3NMZW5ndGgsIHRpY2tzTGVuZ3RoKTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vdHlwZXMvaW5kZXguanMnKS5DaGFydCB9IENoYXJ0XG4gKiBAdHlwZWRlZiB7e3ZhbHVlOm51bWJlciB8IHN0cmluZywgbGFiZWw/OnN0cmluZywgbWFqb3I/OmJvb2xlYW4sICRjb250ZXh0Pzphbnl9fSBUaWNrXG4gKi9cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IGFycmF5IGNvbnRhaW5pbmcgbnVtSXRlbXMgZnJvbSBhcnJcbiAqIEBwYXJhbSB7YW55W119IGFyclxuICogQHBhcmFtIHtudW1iZXJ9IG51bUl0ZW1zXG4gKi9cbmZ1bmN0aW9uIHNhbXBsZShhcnIsIG51bUl0ZW1zKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBpbmNyZW1lbnQgPSBhcnIubGVuZ3RoIC8gbnVtSXRlbXM7XG4gIGNvbnN0IGxlbiA9IGFyci5sZW5ndGg7XG4gIGxldCBpID0gMDtcblxuICBmb3IgKDsgaSA8IGxlbjsgaSArPSBpbmNyZW1lbnQpIHtcbiAgICByZXN1bHQucHVzaChhcnJbTWF0aC5mbG9vcihpKV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQHBhcmFtIHtTY2FsZX0gc2NhbGVcbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICogQHBhcmFtIHtib29sZWFufSBvZmZzZXRHcmlkTGluZXNcbiAqL1xuZnVuY3Rpb24gZ2V0UGl4ZWxGb3JHcmlkTGluZShzY2FsZSwgaW5kZXgsIG9mZnNldEdyaWRMaW5lcykge1xuICBjb25zdCBsZW5ndGggPSBzY2FsZS50aWNrcy5sZW5ndGg7XG4gIGNvbnN0IHZhbGlkSW5kZXggPSBNYXRoLm1pbihpbmRleCwgbGVuZ3RoIC0gMSk7XG4gIGNvbnN0IHN0YXJ0ID0gc2NhbGUuX3N0YXJ0UGl4ZWw7XG4gIGNvbnN0IGVuZCA9IHNjYWxlLl9lbmRQaXhlbDtcbiAgY29uc3QgZXBzaWxvbiA9IDFlLTY7IC8vIDFlLTYgaXMgbWFyZ2luIGluIHBpeGVscyBmb3IgYWNjdW11bGF0ZWQgZXJyb3IuXG4gIGxldCBsaW5lVmFsdWUgPSBzY2FsZS5nZXRQaXhlbEZvclRpY2sodmFsaWRJbmRleCk7XG4gIGxldCBvZmZzZXQ7XG5cbiAgaWYgKG9mZnNldEdyaWRMaW5lcykge1xuICAgIGlmIChsZW5ndGggPT09IDEpIHtcbiAgICAgIG9mZnNldCA9IE1hdGgubWF4KGxpbmVWYWx1ZSAtIHN0YXJ0LCBlbmQgLSBsaW5lVmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgIG9mZnNldCA9IChzY2FsZS5nZXRQaXhlbEZvclRpY2soMSkgLSBsaW5lVmFsdWUpIC8gMjtcbiAgICB9IGVsc2Uge1xuICAgICAgb2Zmc2V0ID0gKGxpbmVWYWx1ZSAtIHNjYWxlLmdldFBpeGVsRm9yVGljayh2YWxpZEluZGV4IC0gMSkpIC8gMjtcbiAgICB9XG4gICAgbGluZVZhbHVlICs9IHZhbGlkSW5kZXggPCBpbmRleCA/IG9mZnNldCA6IC1vZmZzZXQ7XG5cbiAgICAvLyBSZXR1cm4gdW5kZWZpbmVkIGlmIHRoZSBwaXhlbCBpcyBvdXQgb2YgdGhlIHJhbmdlXG4gICAgaWYgKGxpbmVWYWx1ZSA8IHN0YXJ0IC0gZXBzaWxvbiB8fCBsaW5lVmFsdWUgPiBlbmQgKyBlcHNpbG9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG4gIHJldHVybiBsaW5lVmFsdWU7XG59XG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IGNhY2hlc1xuICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aFxuICovXG5mdW5jdGlvbiBnYXJiYWdlQ29sbGVjdChjYWNoZXMsIGxlbmd0aCkge1xuICBlYWNoKGNhY2hlcywgKGNhY2hlKSA9PiB7XG4gICAgY29uc3QgZ2MgPSBjYWNoZS5nYztcbiAgICBjb25zdCBnY0xlbiA9IGdjLmxlbmd0aCAvIDI7XG4gICAgbGV0IGk7XG4gICAgaWYgKGdjTGVuID4gbGVuZ3RoKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgZ2NMZW47ICsraSkge1xuICAgICAgICBkZWxldGUgY2FjaGUuZGF0YVtnY1tpXV07XG4gICAgICB9XG4gICAgICBnYy5zcGxpY2UoMCwgZ2NMZW4pO1xuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gZ2V0VGlja01hcmtMZW5ndGgob3B0aW9ucykge1xuICByZXR1cm4gb3B0aW9ucy5kcmF3VGlja3MgPyBvcHRpb25zLnRpY2tMZW5ndGggOiAwO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gKi9cbmZ1bmN0aW9uIGdldFRpdGxlSGVpZ2h0KG9wdGlvbnMsIGZhbGxiYWNrKSB7XG4gIGlmICghb3B0aW9ucy5kaXNwbGF5KSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBjb25zdCBmb250ID0gdG9Gb250KG9wdGlvbnMuZm9udCwgZmFsbGJhY2spO1xuICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKG9wdGlvbnMucGFkZGluZyk7XG4gIGNvbnN0IGxpbmVzID0gaXNBcnJheShvcHRpb25zLnRleHQpID8gb3B0aW9ucy50ZXh0Lmxlbmd0aCA6IDE7XG5cbiAgcmV0dXJuIChsaW5lcyAqIGZvbnQubGluZUhlaWdodCkgKyBwYWRkaW5nLmhlaWdodDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlU2NhbGVDb250ZXh0KHBhcmVudCwgc2NhbGUpIHtcbiAgcmV0dXJuIGNyZWF0ZUNvbnRleHQocGFyZW50LCB7XG4gICAgc2NhbGUsXG4gICAgdHlwZTogJ3NjYWxlJ1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVGlja0NvbnRleHQocGFyZW50LCBpbmRleCwgdGljaykge1xuICByZXR1cm4gY3JlYXRlQ29udGV4dChwYXJlbnQsIHtcbiAgICB0aWNrLFxuICAgIGluZGV4LFxuICAgIHR5cGU6ICd0aWNrJ1xuICB9KTtcbn1cblxuZnVuY3Rpb24gdGl0bGVBbGlnbihhbGlnbiwgcG9zaXRpb24sIHJldmVyc2UpIHtcbiAgLyoqIEB0eXBlIHtDYW52YXNUZXh0QWxpZ259ICovXG4gIGxldCByZXQgPSBfdG9MZWZ0UmlnaHRDZW50ZXIoYWxpZ24pO1xuICBpZiAoKHJldmVyc2UgJiYgcG9zaXRpb24gIT09ICdyaWdodCcpIHx8ICghcmV2ZXJzZSAmJiBwb3NpdGlvbiA9PT0gJ3JpZ2h0JykpIHtcbiAgICByZXQgPSByZXZlcnNlQWxpZ24ocmV0KTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiB0aXRsZUFyZ3Moc2NhbGUsIG9mZnNldCwgcG9zaXRpb24sIGFsaWduKSB7XG4gIGNvbnN0IHt0b3AsIGxlZnQsIGJvdHRvbSwgcmlnaHQsIGNoYXJ0fSA9IHNjYWxlO1xuICBjb25zdCB7Y2hhcnRBcmVhLCBzY2FsZXN9ID0gY2hhcnQ7XG4gIGxldCByb3RhdGlvbiA9IDA7XG4gIGxldCBtYXhXaWR0aCwgdGl0bGVYLCB0aXRsZVk7XG4gIGNvbnN0IGhlaWdodCA9IGJvdHRvbSAtIHRvcDtcbiAgY29uc3Qgd2lkdGggPSByaWdodCAtIGxlZnQ7XG5cbiAgaWYgKHNjYWxlLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgdGl0bGVYID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIGxlZnQsIHJpZ2h0KTtcblxuICAgIGlmIChpc09iamVjdChwb3NpdGlvbikpIHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uQXhpc0lEID0gT2JqZWN0LmtleXMocG9zaXRpb24pWzBdO1xuICAgICAgY29uc3QgdmFsdWUgPSBwb3NpdGlvbltwb3NpdGlvbkF4aXNJRF07XG4gICAgICB0aXRsZVkgPSBzY2FsZXNbcG9zaXRpb25BeGlzSURdLmdldFBpeGVsRm9yVmFsdWUodmFsdWUpICsgaGVpZ2h0IC0gb2Zmc2V0O1xuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdjZW50ZXInKSB7XG4gICAgICB0aXRsZVkgPSAoY2hhcnRBcmVhLmJvdHRvbSArIGNoYXJ0QXJlYS50b3ApIC8gMiArIGhlaWdodCAtIG9mZnNldDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGl0bGVZID0gb2Zmc2V0RnJvbUVkZ2Uoc2NhbGUsIHBvc2l0aW9uLCBvZmZzZXQpO1xuICAgIH1cbiAgICBtYXhXaWR0aCA9IHJpZ2h0IC0gbGVmdDtcbiAgfSBlbHNlIHtcbiAgICBpZiAoaXNPYmplY3QocG9zaXRpb24pKSB7XG4gICAgICBjb25zdCBwb3NpdGlvbkF4aXNJRCA9IE9iamVjdC5rZXlzKHBvc2l0aW9uKVswXTtcbiAgICAgIGNvbnN0IHZhbHVlID0gcG9zaXRpb25bcG9zaXRpb25BeGlzSURdO1xuICAgICAgdGl0bGVYID0gc2NhbGVzW3Bvc2l0aW9uQXhpc0lEXS5nZXRQaXhlbEZvclZhbHVlKHZhbHVlKSAtIHdpZHRoICsgb2Zmc2V0O1xuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdjZW50ZXInKSB7XG4gICAgICB0aXRsZVggPSAoY2hhcnRBcmVhLmxlZnQgKyBjaGFydEFyZWEucmlnaHQpIC8gMiAtIHdpZHRoICsgb2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aXRsZVggPSBvZmZzZXRGcm9tRWRnZShzY2FsZSwgcG9zaXRpb24sIG9mZnNldCk7XG4gICAgfVxuICAgIHRpdGxlWSA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCBib3R0b20sIHRvcCk7XG4gICAgcm90YXRpb24gPSBwb3NpdGlvbiA9PT0gJ2xlZnQnID8gLUhBTEZfUEkgOiBIQUxGX1BJO1xuICB9XG4gIHJldHVybiB7dGl0bGVYLCB0aXRsZVksIG1heFdpZHRoLCByb3RhdGlvbn07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNjYWxlIGV4dGVuZHMgRWxlbWVudCB7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1zdGF0ZW1lbnRzXG4gIGNvbnN0cnVjdG9yKGNmZykge1xuICAgIHN1cGVyKCk7XG5cbiAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICB0aGlzLmlkID0gY2ZnLmlkO1xuICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgIHRoaXMudHlwZSA9IGNmZy50eXBlO1xuICAgIC8qKiBAdHlwZSB7YW55fSAqL1xuICAgIHRoaXMub3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gKi9cbiAgICB0aGlzLmN0eCA9IGNmZy5jdHg7XG4gICAgLyoqIEB0eXBlIHtDaGFydH0gKi9cbiAgICB0aGlzLmNoYXJ0ID0gY2ZnLmNoYXJ0O1xuXG4gICAgLy8gaW1wbGVtZW50cyBib3hcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLnRvcCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLmJvdHRvbSA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLmxlZnQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5yaWdodCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLndpZHRoID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuaGVpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX21hcmdpbnMgPSB7XG4gICAgICBsZWZ0OiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICBib3R0b206IDBcbiAgICB9O1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMubWF4V2lkdGggPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5tYXhIZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5wYWRkaW5nVG9wID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMucGFkZGluZ0JvdHRvbSA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLnBhZGRpbmdMZWZ0ID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMucGFkZGluZ1JpZ2h0ID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gc2NhbGUtc3BlY2lmaWMgcHJvcGVydGllc1xuICAgIC8qKiBAdHlwZSB7c3RyaW5nPX0gKi9cbiAgICB0aGlzLmF4aXMgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXI9fSAqL1xuICAgIHRoaXMubGFiZWxSb3RhdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1pbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1heCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yYW5nZSA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge1RpY2tbXX0gKi9cbiAgICB0aGlzLnRpY2tzID0gW107XG4gICAgLyoqIEB0eXBlIHtvYmplY3RbXXxudWxsfSAqL1xuICAgIHRoaXMuX2dyaWRMaW5lSXRlbXMgPSBudWxsO1xuICAgIC8qKiBAdHlwZSB7b2JqZWN0W118bnVsbH0gKi9cbiAgICB0aGlzLl9sYWJlbEl0ZW1zID0gbnVsbDtcbiAgICAvKiogQHR5cGUge29iamVjdHxudWxsfSAqL1xuICAgIHRoaXMuX2xhYmVsU2l6ZXMgPSBudWxsO1xuICAgIHRoaXMuX2xlbmd0aCA9IDA7XG4gICAgdGhpcy5fbWF4TGVuZ3RoID0gMDtcbiAgICB0aGlzLl9sb25nZXN0VGV4dENhY2hlID0ge307XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5fc3RhcnRQaXhlbCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLl9lbmRQaXhlbCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9yZXZlcnNlUGl4ZWxzID0gZmFsc2U7XG4gICAgdGhpcy5fdXNlck1heCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl91c2VyTWluID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3N1Z2dlc3RlZE1heCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9zdWdnZXN0ZWRNaW4gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fdGlja3NMZW5ndGggPSAwO1xuICAgIHRoaXMuX2JvcmRlclZhbHVlID0gMDtcbiAgICB0aGlzLl9jYWNoZSA9IHt9O1xuICAgIHRoaXMuX2RhdGFMaW1pdHNDYWNoZWQgPSBmYWxzZTtcbiAgICB0aGlzLiRjb250ZXh0ID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7YW55fSBvcHRpb25zXG5cdCAqIEBzaW5jZSAzLjBcblx0ICovXG4gIGluaXQob3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMuc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoKSk7XG5cbiAgICB0aGlzLmF4aXMgPSBvcHRpb25zLmF4aXM7XG5cbiAgICAvLyBwYXJzZSBtaW4vbWF4IHZhbHVlLCBzbyB3ZSBjYW4gcHJvcGVybHkgZGV0ZXJtaW5lIG1pbi9tYXggZm9yIG90aGVyIHNjYWxlc1xuICAgIHRoaXMuX3VzZXJNaW4gPSB0aGlzLnBhcnNlKG9wdGlvbnMubWluKTtcbiAgICB0aGlzLl91c2VyTWF4ID0gdGhpcy5wYXJzZShvcHRpb25zLm1heCk7XG4gICAgdGhpcy5fc3VnZ2VzdGVkTWluID0gdGhpcy5wYXJzZShvcHRpb25zLnN1Z2dlc3RlZE1pbik7XG4gICAgdGhpcy5fc3VnZ2VzdGVkTWF4ID0gdGhpcy5wYXJzZShvcHRpb25zLnN1Z2dlc3RlZE1heCk7XG4gIH1cblxuICAvKipcblx0ICogUGFyc2UgYSBzdXBwb3J0ZWQgaW5wdXQgdmFsdWUgdG8gaW50ZXJuYWwgcmVwcmVzZW50YXRpb24uXG5cdCAqIEBwYXJhbSB7Kn0gcmF3XG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbaW5kZXhdXG5cdCAqIEBzaW5jZSAzLjBcblx0ICovXG4gIHBhcnNlKHJhdywgaW5kZXgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIHJldHVybiByYXc7XG4gIH1cblxuICAvKipcblx0ICogQHJldHVybiB7e21pbjogbnVtYmVyLCBtYXg6IG51bWJlciwgbWluRGVmaW5lZDogYm9vbGVhbiwgbWF4RGVmaW5lZDogYm9vbGVhbn19XG5cdCAqIEBwcm90ZWN0ZWRcblx0ICogQHNpbmNlIDMuMFxuXHQgKi9cbiAgZ2V0VXNlckJvdW5kcygpIHtcbiAgICBsZXQge191c2VyTWluLCBfdXNlck1heCwgX3N1Z2dlc3RlZE1pbiwgX3N1Z2dlc3RlZE1heH0gPSB0aGlzO1xuICAgIF91c2VyTWluID0gZmluaXRlT3JEZWZhdWx0KF91c2VyTWluLCBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpO1xuICAgIF91c2VyTWF4ID0gZmluaXRlT3JEZWZhdWx0KF91c2VyTWF4LCBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkpO1xuICAgIF9zdWdnZXN0ZWRNaW4gPSBmaW5pdGVPckRlZmF1bHQoX3N1Z2dlc3RlZE1pbiwgTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKTtcbiAgICBfc3VnZ2VzdGVkTWF4ID0gZmluaXRlT3JEZWZhdWx0KF9zdWdnZXN0ZWRNYXgsIE51bWJlci5ORUdBVElWRV9JTkZJTklUWSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1pbjogZmluaXRlT3JEZWZhdWx0KF91c2VyTWluLCBfc3VnZ2VzdGVkTWluKSxcbiAgICAgIG1heDogZmluaXRlT3JEZWZhdWx0KF91c2VyTWF4LCBfc3VnZ2VzdGVkTWF4KSxcbiAgICAgIG1pbkRlZmluZWQ6IGlzRmluaXRlKF91c2VyTWluKSxcbiAgICAgIG1heERlZmluZWQ6IGlzRmluaXRlKF91c2VyTWF4KVxuICAgIH07XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtib29sZWFufSBjYW5TdGFja1xuXHQgKiBAcmV0dXJuIHt7bWluOiBudW1iZXIsIG1heDogbnVtYmVyfX1cblx0ICogQHByb3RlY3RlZFxuXHQgKiBAc2luY2UgMy4wXG5cdCAqL1xuICBnZXRNaW5NYXgoY2FuU3RhY2spIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgbGV0IHttaW4sIG1heCwgbWluRGVmaW5lZCwgbWF4RGVmaW5lZH0gPSB0aGlzLmdldFVzZXJCb3VuZHMoKTtcbiAgICBsZXQgcmFuZ2U7XG5cbiAgICBpZiAobWluRGVmaW5lZCAmJiBtYXhEZWZpbmVkKSB7XG4gICAgICByZXR1cm4ge21pbiwgbWF4fTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXRhcyA9IHRoaXMuZ2V0TWF0Y2hpbmdWaXNpYmxlTWV0YXMoKTtcbiAgICBmb3IgKGxldCBpID0gMCwgaWxlbiA9IG1ldGFzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgcmFuZ2UgPSBtZXRhc1tpXS5jb250cm9sbGVyLmdldE1pbk1heCh0aGlzLCBjYW5TdGFjayk7XG4gICAgICBpZiAoIW1pbkRlZmluZWQpIHtcbiAgICAgICAgbWluID0gTWF0aC5taW4obWluLCByYW5nZS5taW4pO1xuICAgICAgfVxuICAgICAgaWYgKCFtYXhEZWZpbmVkKSB7XG4gICAgICAgIG1heCA9IE1hdGgubWF4KG1heCwgcmFuZ2UubWF4KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNYWtlIHN1cmUgbWluIDw9IG1heCB3aGVuIG9ubHkgbWluIG9yIG1heCBpcyBkZWZpbmVkIGJ5IHVzZXIgYW5kIHRoZSBkYXRhIGlzIG91dHNpZGUgdGhhdCByYW5nZVxuICAgIG1pbiA9IG1heERlZmluZWQgJiYgbWluID4gbWF4ID8gbWF4IDogbWluO1xuICAgIG1heCA9IG1pbkRlZmluZWQgJiYgbWluID4gbWF4ID8gbWluIDogbWF4O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1pbjogZmluaXRlT3JEZWZhdWx0KG1pbiwgZmluaXRlT3JEZWZhdWx0KG1heCwgbWluKSksXG4gICAgICBtYXg6IGZpbml0ZU9yRGVmYXVsdChtYXgsIGZpbml0ZU9yRGVmYXVsdChtaW4sIG1heCkpXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBHZXQgdGhlIHBhZGRpbmcgbmVlZGVkIGZvciB0aGUgc2NhbGVcblx0ICogQHJldHVybiB7e3RvcDogbnVtYmVyLCBsZWZ0OiBudW1iZXIsIGJvdHRvbTogbnVtYmVyLCByaWdodDogbnVtYmVyfX0gdGhlIG5lY2Vzc2FyeSBwYWRkaW5nXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBnZXRQYWRkaW5nKCkge1xuICAgIHJldHVybiB7XG4gICAgICBsZWZ0OiB0aGlzLnBhZGRpbmdMZWZ0IHx8IDAsXG4gICAgICB0b3A6IHRoaXMucGFkZGluZ1RvcCB8fCAwLFxuICAgICAgcmlnaHQ6IHRoaXMucGFkZGluZ1JpZ2h0IHx8IDAsXG4gICAgICBib3R0b206IHRoaXMucGFkZGluZ0JvdHRvbSB8fCAwXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBzY2FsZSB0aWNrIG9iamVjdHNcblx0ICogQHJldHVybiB7VGlja1tdfVxuXHQgKiBAc2luY2UgMi43XG5cdCAqL1xuICBnZXRUaWNrcygpIHtcbiAgICByZXR1cm4gdGhpcy50aWNrcztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcmV0dXJuIHtzdHJpbmdbXX1cblx0ICovXG4gIGdldExhYmVscygpIHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5jaGFydC5kYXRhO1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMubGFiZWxzIHx8ICh0aGlzLmlzSG9yaXpvbnRhbCgpID8gZGF0YS54TGFiZWxzIDogZGF0YS55TGFiZWxzKSB8fCBkYXRhLmxhYmVscyB8fCBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoJy4uL3R5cGVzLmpzJykuTGFiZWxJdGVtW119XG4gICAqL1xuICBnZXRMYWJlbEl0ZW1zKGNoYXJ0QXJlYSA9IHRoaXMuY2hhcnQuY2hhcnRBcmVhKSB7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLl9sYWJlbEl0ZW1zIHx8ICh0aGlzLl9sYWJlbEl0ZW1zID0gdGhpcy5fY29tcHV0ZUxhYmVsSXRlbXMoY2hhcnRBcmVhKSk7XG4gICAgcmV0dXJuIGl0ZW1zO1xuICB9XG5cbiAgLy8gV2hlbiBhIG5ldyBsYXlvdXQgaXMgY3JlYXRlZCwgcmVzZXQgdGhlIGRhdGEgbGltaXRzIGNhY2hlXG4gIGJlZm9yZUxheW91dCgpIHtcbiAgICB0aGlzLl9jYWNoZSA9IHt9O1xuICAgIHRoaXMuX2RhdGFMaW1pdHNDYWNoZWQgPSBmYWxzZTtcbiAgfVxuXG4gIC8vIFRoZXNlIG1ldGhvZHMgYXJlIG9yZGVyZWQgYnkgbGlmZWN5Y2xlLiBVdGlsaXRpZXMgdGhlbiBmb2xsb3cuXG4gIC8vIEFueSBmdW5jdGlvbiBkZWZpbmVkIGhlcmUgaXMgaW5oZXJpdGVkIGJ5IGFsbCBzY2FsZSB0eXBlcy5cbiAgLy8gQW55IGZ1bmN0aW9uIGNhbiBiZSBleHRlbmRlZCBieSB0aGUgc2NhbGUgdHlwZVxuXG4gIGJlZm9yZVVwZGF0ZSgpIHtcbiAgICBjYWxsKHRoaXMub3B0aW9ucy5iZWZvcmVVcGRhdGUsIFt0aGlzXSk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJ9IG1heFdpZHRoIC0gdGhlIG1heCB3aWR0aCBpbiBwaXhlbHNcblx0ICogQHBhcmFtIHtudW1iZXJ9IG1heEhlaWdodCAtIHRoZSBtYXggaGVpZ2h0IGluIHBpeGVsc1xuXHQgKiBAcGFyYW0ge3t0b3A6IG51bWJlciwgbGVmdDogbnVtYmVyLCBib3R0b206IG51bWJlciwgcmlnaHQ6IG51bWJlcn19IG1hcmdpbnMgLSB0aGUgc3BhY2UgYmV0d2VlbiB0aGUgZWRnZSBvZiB0aGUgb3RoZXIgc2NhbGVzIGFuZCBlZGdlIG9mIHRoZSBjaGFydFxuXHQgKiAgIFRoaXMgc3BhY2UgY29tZXMgZnJvbSB0d28gc291cmNlczpcblx0ICogICAgIC0gcGFkZGluZyAtIHNwYWNlIHRoYXQncyByZXF1aXJlZCB0byBzaG93IHRoZSBsYWJlbHMgYXQgdGhlIGVkZ2VzIG9mIHRoZSBzY2FsZVxuXHQgKiAgICAgLSB0aGlja25lc3Mgb2Ygc2NhbGVzIG9yIGxlZ2VuZHMgaW4gYW5vdGhlciBvcmllbnRhdGlvblxuXHQgKi9cbiAgdXBkYXRlKG1heFdpZHRoLCBtYXhIZWlnaHQsIG1hcmdpbnMpIHtcbiAgICBjb25zdCB7YmVnaW5BdFplcm8sIGdyYWNlLCB0aWNrczogdGlja09wdHN9ID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHNhbXBsZVNpemUgPSB0aWNrT3B0cy5zYW1wbGVTaXplO1xuXG4gICAgLy8gVXBkYXRlIExpZmVjeWNsZSAtIFByb2JhYmx5IGRvbid0IHdhbnQgdG8gZXZlciBleHRlbmQgb3Igb3ZlcndyaXRlIHRoaXMgZnVuY3Rpb24gOylcbiAgICB0aGlzLmJlZm9yZVVwZGF0ZSgpO1xuXG4gICAgLy8gQWJzb3JiIHRoZSBtYXN0ZXIgbWVhc3VyZW1lbnRzXG4gICAgdGhpcy5tYXhXaWR0aCA9IG1heFdpZHRoO1xuICAgIHRoaXMubWF4SGVpZ2h0ID0gbWF4SGVpZ2h0O1xuICAgIHRoaXMuX21hcmdpbnMgPSBtYXJnaW5zID0gT2JqZWN0LmFzc2lnbih7XG4gICAgICBsZWZ0OiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICBib3R0b206IDBcbiAgICB9LCBtYXJnaW5zKTtcblxuICAgIHRoaXMudGlja3MgPSBudWxsO1xuICAgIHRoaXMuX2xhYmVsU2l6ZXMgPSBudWxsO1xuICAgIHRoaXMuX2dyaWRMaW5lSXRlbXMgPSBudWxsO1xuICAgIHRoaXMuX2xhYmVsSXRlbXMgPSBudWxsO1xuXG4gICAgLy8gRGltZW5zaW9uc1xuICAgIHRoaXMuYmVmb3JlU2V0RGltZW5zaW9ucygpO1xuICAgIHRoaXMuc2V0RGltZW5zaW9ucygpO1xuICAgIHRoaXMuYWZ0ZXJTZXREaW1lbnNpb25zKCk7XG5cbiAgICB0aGlzLl9tYXhMZW5ndGggPSB0aGlzLmlzSG9yaXpvbnRhbCgpXG4gICAgICA/IHRoaXMud2lkdGggKyBtYXJnaW5zLmxlZnQgKyBtYXJnaW5zLnJpZ2h0XG4gICAgICA6IHRoaXMuaGVpZ2h0ICsgbWFyZ2lucy50b3AgKyBtYXJnaW5zLmJvdHRvbTtcblxuICAgIC8vIERhdGEgbWluL21heFxuICAgIGlmICghdGhpcy5fZGF0YUxpbWl0c0NhY2hlZCkge1xuICAgICAgdGhpcy5iZWZvcmVEYXRhTGltaXRzKCk7XG4gICAgICB0aGlzLmRldGVybWluZURhdGFMaW1pdHMoKTtcbiAgICAgIHRoaXMuYWZ0ZXJEYXRhTGltaXRzKCk7XG4gICAgICB0aGlzLl9yYW5nZSA9IF9hZGRHcmFjZSh0aGlzLCBncmFjZSwgYmVnaW5BdFplcm8pO1xuICAgICAgdGhpcy5fZGF0YUxpbWl0c0NhY2hlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy5iZWZvcmVCdWlsZFRpY2tzKCk7XG5cbiAgICB0aGlzLnRpY2tzID0gdGhpcy5idWlsZFRpY2tzKCkgfHwgW107XG5cbiAgICAvLyBBbGxvdyBtb2RpZmljYXRpb24gb2YgdGlja3MgaW4gY2FsbGJhY2suXG4gICAgdGhpcy5hZnRlckJ1aWxkVGlja3MoKTtcblxuICAgIC8vIENvbXB1dGUgdGljayByb3RhdGlvbiBhbmQgZml0IHVzaW5nIGEgc2FtcGxlZCBzdWJzZXQgb2YgbGFiZWxzXG4gICAgLy8gV2UgZ2VuZXJhbGx5IGRvbid0IG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiBldmVyeSBzaW5nbGUgbGFiZWwgZm9yIGRldGVybWluaW5nIHNjYWxlIHNpemVcbiAgICBjb25zdCBzYW1wbGluZ0VuYWJsZWQgPSBzYW1wbGVTaXplIDwgdGhpcy50aWNrcy5sZW5ndGg7XG4gICAgdGhpcy5fY29udmVydFRpY2tzVG9MYWJlbHMoc2FtcGxpbmdFbmFibGVkID8gc2FtcGxlKHRoaXMudGlja3MsIHNhbXBsZVNpemUpIDogdGhpcy50aWNrcyk7XG5cbiAgICAvLyBjb25maWd1cmUgaXMgY2FsbGVkIHR3aWNlLCBvbmNlIGhlcmUsIG9uY2UgZnJvbSBjb3JlLmNvbnRyb2xsZXIudXBkYXRlTGF5b3V0LlxuICAgIC8vIEhlcmUgd2UgaGF2ZW4ndCBiZWVuIHBvc2l0aW9uZWQgeWV0LCBidXQgZGltZW5zaW9ucyBhcmUgY29ycmVjdC5cbiAgICAvLyBWYXJpYWJsZXMgc2V0IGluIGNvbmZpZ3VyZSBhcmUgbmVlZGVkIGZvciBjYWxjdWxhdGVMYWJlbFJvdGF0aW9uLCBhbmRcbiAgICAvLyBpdCdzIG9rIHRoYXQgY29vcmRpbmF0ZXMgYXJlIG5vdCBjb3JyZWN0IHRoZXJlLCBvbmx5IGRpbWVuc2lvbnMgbWF0dGVyLlxuICAgIHRoaXMuY29uZmlndXJlKCk7XG5cbiAgICAvLyBUaWNrIFJvdGF0aW9uXG4gICAgdGhpcy5iZWZvcmVDYWxjdWxhdGVMYWJlbFJvdGF0aW9uKCk7XG4gICAgdGhpcy5jYWxjdWxhdGVMYWJlbFJvdGF0aW9uKCk7IC8vIFByZWNvbmRpdGlvbnM6IG51bWJlciBvZiB0aWNrcyBhbmQgc2l6ZXMgb2YgbGFyZ2VzdCBsYWJlbHMgbXVzdCBiZSBjYWxjdWxhdGVkIGJlZm9yZWhhbmRcbiAgICB0aGlzLmFmdGVyQ2FsY3VsYXRlTGFiZWxSb3RhdGlvbigpO1xuXG4gICAgLy8gQXV0by1za2lwXG4gICAgaWYgKHRpY2tPcHRzLmRpc3BsYXkgJiYgKHRpY2tPcHRzLmF1dG9Ta2lwIHx8IHRpY2tPcHRzLnNvdXJjZSA9PT0gJ2F1dG8nKSkge1xuICAgICAgdGhpcy50aWNrcyA9IGF1dG9Ta2lwKHRoaXMsIHRoaXMudGlja3MpO1xuICAgICAgdGhpcy5fbGFiZWxTaXplcyA9IG51bGw7XG4gICAgICB0aGlzLmFmdGVyQXV0b1NraXAoKTtcbiAgICB9XG5cbiAgICBpZiAoc2FtcGxpbmdFbmFibGVkKSB7XG4gICAgICAvLyBHZW5lcmF0ZSBsYWJlbHMgdXNpbmcgYWxsIG5vbi1za2lwcGVkIHRpY2tzXG4gICAgICB0aGlzLl9jb252ZXJ0VGlja3NUb0xhYmVscyh0aGlzLnRpY2tzKTtcbiAgICB9XG5cbiAgICB0aGlzLmJlZm9yZUZpdCgpO1xuICAgIHRoaXMuZml0KCk7IC8vIFByZWNvbmRpdGlvbnM6IGxhYmVsIHJvdGF0aW9uIGFuZCBsYWJlbCBzaXplcyBtdXN0IGJlIGNhbGN1bGF0ZWQgYmVmb3JlaGFuZFxuICAgIHRoaXMuYWZ0ZXJGaXQoKTtcblxuICAgIC8vIElNUE9SVEFOVDogYWZ0ZXIgdGhpcyBwb2ludCwgd2UgY29uc2lkZXIgdGhhdCBgdGhpcy50aWNrc2Agd2lsbCBORVZFUiBjaGFuZ2UhXG5cbiAgICB0aGlzLmFmdGVyVXBkYXRlKCk7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgY29uZmlndXJlKCkge1xuICAgIGxldCByZXZlcnNlUGl4ZWxzID0gdGhpcy5vcHRpb25zLnJldmVyc2U7XG4gICAgbGV0IHN0YXJ0UGl4ZWwsIGVuZFBpeGVsO1xuXG4gICAgaWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgIHN0YXJ0UGl4ZWwgPSB0aGlzLmxlZnQ7XG4gICAgICBlbmRQaXhlbCA9IHRoaXMucmlnaHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXJ0UGl4ZWwgPSB0aGlzLnRvcDtcbiAgICAgIGVuZFBpeGVsID0gdGhpcy5ib3R0b207XG4gICAgICAvLyBieSBkZWZhdWx0IHZlcnRpY2FsIHNjYWxlcyBhcmUgZnJvbSBib3R0b20gdG8gdG9wLCBzbyBwaXhlbHMgYXJlIHJldmVyc2VkXG4gICAgICByZXZlcnNlUGl4ZWxzID0gIXJldmVyc2VQaXhlbHM7XG4gICAgfVxuICAgIHRoaXMuX3N0YXJ0UGl4ZWwgPSBzdGFydFBpeGVsO1xuICAgIHRoaXMuX2VuZFBpeGVsID0gZW5kUGl4ZWw7XG4gICAgdGhpcy5fcmV2ZXJzZVBpeGVscyA9IHJldmVyc2VQaXhlbHM7XG4gICAgdGhpcy5fbGVuZ3RoID0gZW5kUGl4ZWwgLSBzdGFydFBpeGVsO1xuICAgIHRoaXMuX2FsaWduVG9QaXhlbHMgPSB0aGlzLm9wdGlvbnMuYWxpZ25Ub1BpeGVscztcbiAgfVxuXG4gIGFmdGVyVXBkYXRlKCkge1xuICAgIGNhbGwodGhpcy5vcHRpb25zLmFmdGVyVXBkYXRlLCBbdGhpc10pO1xuICB9XG5cbiAgLy9cblxuICBiZWZvcmVTZXREaW1lbnNpb25zKCkge1xuICAgIGNhbGwodGhpcy5vcHRpb25zLmJlZm9yZVNldERpbWVuc2lvbnMsIFt0aGlzXSk7XG4gIH1cbiAgc2V0RGltZW5zaW9ucygpIHtcbiAgICAvLyBTZXQgdGhlIHVuY29uc3RyYWluZWQgZGltZW5zaW9uIGJlZm9yZSBsYWJlbCByb3RhdGlvblxuICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICAvLyBSZXNldCBwb3NpdGlvbiBiZWZvcmUgY2FsY3VsYXRpbmcgcm90YXRpb25cbiAgICAgIHRoaXMud2lkdGggPSB0aGlzLm1heFdpZHRoO1xuICAgICAgdGhpcy5sZWZ0ID0gMDtcbiAgICAgIHRoaXMucmlnaHQgPSB0aGlzLndpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhlaWdodCA9IHRoaXMubWF4SGVpZ2h0O1xuXG4gICAgICAvLyBSZXNldCBwb3NpdGlvbiBiZWZvcmUgY2FsY3VsYXRpbmcgcm90YXRpb25cbiAgICAgIHRoaXMudG9wID0gMDtcbiAgICAgIHRoaXMuYm90dG9tID0gdGhpcy5oZWlnaHQ7XG4gICAgfVxuXG4gICAgLy8gUmVzZXQgcGFkZGluZ1xuICAgIHRoaXMucGFkZGluZ0xlZnQgPSAwO1xuICAgIHRoaXMucGFkZGluZ1RvcCA9IDA7XG4gICAgdGhpcy5wYWRkaW5nUmlnaHQgPSAwO1xuICAgIHRoaXMucGFkZGluZ0JvdHRvbSA9IDA7XG4gIH1cbiAgYWZ0ZXJTZXREaW1lbnNpb25zKCkge1xuICAgIGNhbGwodGhpcy5vcHRpb25zLmFmdGVyU2V0RGltZW5zaW9ucywgW3RoaXNdKTtcbiAgfVxuXG4gIF9jYWxsSG9va3MobmFtZSkge1xuICAgIHRoaXMuY2hhcnQubm90aWZ5UGx1Z2lucyhuYW1lLCB0aGlzLmdldENvbnRleHQoKSk7XG4gICAgY2FsbCh0aGlzLm9wdGlvbnNbbmFtZV0sIFt0aGlzXSk7XG4gIH1cblxuICAvLyBEYXRhIGxpbWl0c1xuICBiZWZvcmVEYXRhTGltaXRzKCkge1xuICAgIHRoaXMuX2NhbGxIb29rcygnYmVmb3JlRGF0YUxpbWl0cycpO1xuICB9XG4gIGRldGVybWluZURhdGFMaW1pdHMoKSB7fVxuICBhZnRlckRhdGFMaW1pdHMoKSB7XG4gICAgdGhpcy5fY2FsbEhvb2tzKCdhZnRlckRhdGFMaW1pdHMnKTtcbiAgfVxuXG4gIC8vXG4gIGJlZm9yZUJ1aWxkVGlja3MoKSB7XG4gICAgdGhpcy5fY2FsbEhvb2tzKCdiZWZvcmVCdWlsZFRpY2tzJyk7XG4gIH1cbiAgLyoqXG5cdCAqIEByZXR1cm4ge29iamVjdFtdfSB0aGUgdGlja3Ncblx0ICovXG4gIGJ1aWxkVGlja3MoKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGFmdGVyQnVpbGRUaWNrcygpIHtcbiAgICB0aGlzLl9jYWxsSG9va3MoJ2FmdGVyQnVpbGRUaWNrcycpO1xuICB9XG5cbiAgYmVmb3JlVGlja1RvTGFiZWxDb252ZXJzaW9uKCkge1xuICAgIGNhbGwodGhpcy5vcHRpb25zLmJlZm9yZVRpY2tUb0xhYmVsQ29udmVyc2lvbiwgW3RoaXNdKTtcbiAgfVxuICAvKipcblx0ICogQ29udmVydCB0aWNrcyB0byBsYWJlbCBzdHJpbmdzXG5cdCAqIEBwYXJhbSB7VGlja1tdfSB0aWNrc1xuXHQgKi9cbiAgZ2VuZXJhdGVUaWNrTGFiZWxzKHRpY2tzKSB7XG4gICAgY29uc3QgdGlja09wdHMgPSB0aGlzLm9wdGlvbnMudGlja3M7XG4gICAgbGV0IGksIGlsZW4sIHRpY2s7XG4gICAgZm9yIChpID0gMCwgaWxlbiA9IHRpY2tzLmxlbmd0aDsgaSA8IGlsZW47IGkrKykge1xuICAgICAgdGljayA9IHRpY2tzW2ldO1xuICAgICAgdGljay5sYWJlbCA9IGNhbGwodGlja09wdHMuY2FsbGJhY2ssIFt0aWNrLnZhbHVlLCBpLCB0aWNrc10sIHRoaXMpO1xuICAgIH1cbiAgfVxuICBhZnRlclRpY2tUb0xhYmVsQ29udmVyc2lvbigpIHtcbiAgICBjYWxsKHRoaXMub3B0aW9ucy5hZnRlclRpY2tUb0xhYmVsQ29udmVyc2lvbiwgW3RoaXNdKTtcbiAgfVxuXG4gIC8vXG5cbiAgYmVmb3JlQ2FsY3VsYXRlTGFiZWxSb3RhdGlvbigpIHtcbiAgICBjYWxsKHRoaXMub3B0aW9ucy5iZWZvcmVDYWxjdWxhdGVMYWJlbFJvdGF0aW9uLCBbdGhpc10pO1xuICB9XG4gIGNhbGN1bGF0ZUxhYmVsUm90YXRpb24oKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB0aWNrT3B0cyA9IG9wdGlvbnMudGlja3M7XG4gICAgY29uc3QgbnVtVGlja3MgPSBnZXRUaWNrc0xpbWl0KHRoaXMudGlja3MubGVuZ3RoLCBvcHRpb25zLnRpY2tzLm1heFRpY2tzTGltaXQpO1xuICAgIGNvbnN0IG1pblJvdGF0aW9uID0gdGlja09wdHMubWluUm90YXRpb24gfHwgMDtcbiAgICBjb25zdCBtYXhSb3RhdGlvbiA9IHRpY2tPcHRzLm1heFJvdGF0aW9uO1xuICAgIGxldCBsYWJlbFJvdGF0aW9uID0gbWluUm90YXRpb247XG4gICAgbGV0IHRpY2tXaWR0aCwgbWF4SGVpZ2h0LCBtYXhMYWJlbERpYWdvbmFsO1xuXG4gICAgaWYgKCF0aGlzLl9pc1Zpc2libGUoKSB8fCAhdGlja09wdHMuZGlzcGxheSB8fCBtaW5Sb3RhdGlvbiA+PSBtYXhSb3RhdGlvbiB8fCBudW1UaWNrcyA8PSAxIHx8ICF0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICB0aGlzLmxhYmVsUm90YXRpb24gPSBtaW5Sb3RhdGlvbjtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsYWJlbFNpemVzID0gdGhpcy5fZ2V0TGFiZWxTaXplcygpO1xuICAgIGNvbnN0IG1heExhYmVsV2lkdGggPSBsYWJlbFNpemVzLndpZGVzdC53aWR0aDtcbiAgICBjb25zdCBtYXhMYWJlbEhlaWdodCA9IGxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQ7XG5cbiAgICAvLyBFc3RpbWF0ZSB0aGUgd2lkdGggb2YgZWFjaCBncmlkIGJhc2VkIG9uIHRoZSBjYW52YXMgd2lkdGgsIHRoZSBtYXhpbXVtXG4gICAgLy8gbGFiZWwgd2lkdGggYW5kIHRoZSBudW1iZXIgb2YgdGljayBpbnRlcnZhbHNcbiAgICBjb25zdCBtYXhXaWR0aCA9IF9saW1pdFZhbHVlKHRoaXMuY2hhcnQud2lkdGggLSBtYXhMYWJlbFdpZHRoLCAwLCB0aGlzLm1heFdpZHRoKTtcbiAgICB0aWNrV2lkdGggPSBvcHRpb25zLm9mZnNldCA/IHRoaXMubWF4V2lkdGggLyBudW1UaWNrcyA6IG1heFdpZHRoIC8gKG51bVRpY2tzIC0gMSk7XG5cbiAgICAvLyBBbGxvdyAzIHBpeGVscyB4MiBwYWRkaW5nIGVpdGhlciBzaWRlIGZvciBsYWJlbCByZWFkYWJpbGl0eVxuICAgIGlmIChtYXhMYWJlbFdpZHRoICsgNiA+IHRpY2tXaWR0aCkge1xuICAgICAgdGlja1dpZHRoID0gbWF4V2lkdGggLyAobnVtVGlja3MgLSAob3B0aW9ucy5vZmZzZXQgPyAwLjUgOiAxKSk7XG4gICAgICBtYXhIZWlnaHQgPSB0aGlzLm1heEhlaWdodCAtIGdldFRpY2tNYXJrTGVuZ3RoKG9wdGlvbnMuZ3JpZClcblx0XHRcdFx0LSB0aWNrT3B0cy5wYWRkaW5nIC0gZ2V0VGl0bGVIZWlnaHQob3B0aW9ucy50aXRsZSwgdGhpcy5jaGFydC5vcHRpb25zLmZvbnQpO1xuICAgICAgbWF4TGFiZWxEaWFnb25hbCA9IE1hdGguc3FydChtYXhMYWJlbFdpZHRoICogbWF4TGFiZWxXaWR0aCArIG1heExhYmVsSGVpZ2h0ICogbWF4TGFiZWxIZWlnaHQpO1xuICAgICAgbGFiZWxSb3RhdGlvbiA9IHRvRGVncmVlcyhNYXRoLm1pbihcbiAgICAgICAgTWF0aC5hc2luKF9saW1pdFZhbHVlKChsYWJlbFNpemVzLmhpZ2hlc3QuaGVpZ2h0ICsgNikgLyB0aWNrV2lkdGgsIC0xLCAxKSksXG4gICAgICAgIE1hdGguYXNpbihfbGltaXRWYWx1ZShtYXhIZWlnaHQgLyBtYXhMYWJlbERpYWdvbmFsLCAtMSwgMSkpIC0gTWF0aC5hc2luKF9saW1pdFZhbHVlKG1heExhYmVsSGVpZ2h0IC8gbWF4TGFiZWxEaWFnb25hbCwgLTEsIDEpKVxuICAgICAgKSk7XG4gICAgICBsYWJlbFJvdGF0aW9uID0gTWF0aC5tYXgobWluUm90YXRpb24sIE1hdGgubWluKG1heFJvdGF0aW9uLCBsYWJlbFJvdGF0aW9uKSk7XG4gICAgfVxuXG4gICAgdGhpcy5sYWJlbFJvdGF0aW9uID0gbGFiZWxSb3RhdGlvbjtcbiAgfVxuICBhZnRlckNhbGN1bGF0ZUxhYmVsUm90YXRpb24oKSB7XG4gICAgY2FsbCh0aGlzLm9wdGlvbnMuYWZ0ZXJDYWxjdWxhdGVMYWJlbFJvdGF0aW9uLCBbdGhpc10pO1xuICB9XG4gIGFmdGVyQXV0b1NraXAoKSB7fVxuXG4gIC8vXG5cbiAgYmVmb3JlRml0KCkge1xuICAgIGNhbGwodGhpcy5vcHRpb25zLmJlZm9yZUZpdCwgW3RoaXNdKTtcbiAgfVxuICBmaXQoKSB7XG4gICAgLy8gUmVzZXRcbiAgICBjb25zdCBtaW5TaXplID0ge1xuICAgICAgd2lkdGg6IDAsXG4gICAgICBoZWlnaHQ6IDBcbiAgICB9O1xuXG4gICAgY29uc3Qge2NoYXJ0LCBvcHRpb25zOiB7dGlja3M6IHRpY2tPcHRzLCB0aXRsZTogdGl0bGVPcHRzLCBncmlkOiBncmlkT3B0c319ID0gdGhpcztcbiAgICBjb25zdCBkaXNwbGF5ID0gdGhpcy5faXNWaXNpYmxlKCk7XG4gICAgY29uc3QgaXNIb3Jpem9udGFsID0gdGhpcy5pc0hvcml6b250YWwoKTtcblxuICAgIGlmIChkaXNwbGF5KSB7XG4gICAgICBjb25zdCB0aXRsZUhlaWdodCA9IGdldFRpdGxlSGVpZ2h0KHRpdGxlT3B0cywgY2hhcnQub3B0aW9ucy5mb250KTtcbiAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgbWluU2l6ZS53aWR0aCA9IHRoaXMubWF4V2lkdGg7XG4gICAgICAgIG1pblNpemUuaGVpZ2h0ID0gZ2V0VGlja01hcmtMZW5ndGgoZ3JpZE9wdHMpICsgdGl0bGVIZWlnaHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtaW5TaXplLmhlaWdodCA9IHRoaXMubWF4SGVpZ2h0OyAvLyBmaWxsIGFsbCB0aGUgaGVpZ2h0XG4gICAgICAgIG1pblNpemUud2lkdGggPSBnZXRUaWNrTWFya0xlbmd0aChncmlkT3B0cykgKyB0aXRsZUhlaWdodDtcbiAgICAgIH1cblxuICAgICAgLy8gRG9uJ3QgYm90aGVyIGZpdHRpbmcgdGhlIHRpY2tzIGlmIHdlIGFyZSBub3Qgc2hvd2luZyB0aGUgbGFiZWxzXG4gICAgICBpZiAodGlja09wdHMuZGlzcGxheSAmJiB0aGlzLnRpY2tzLmxlbmd0aCkge1xuICAgICAgICBjb25zdCB7Zmlyc3QsIGxhc3QsIHdpZGVzdCwgaGlnaGVzdH0gPSB0aGlzLl9nZXRMYWJlbFNpemVzKCk7XG4gICAgICAgIGNvbnN0IHRpY2tQYWRkaW5nID0gdGlja09wdHMucGFkZGluZyAqIDI7XG4gICAgICAgIGNvbnN0IGFuZ2xlUmFkaWFucyA9IHRvUmFkaWFucyh0aGlzLmxhYmVsUm90YXRpb24pO1xuICAgICAgICBjb25zdCBjb3MgPSBNYXRoLmNvcyhhbmdsZVJhZGlhbnMpO1xuICAgICAgICBjb25zdCBzaW4gPSBNYXRoLnNpbihhbmdsZVJhZGlhbnMpO1xuXG4gICAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgLy8gQSBob3Jpem9udGFsIGF4aXMgaXMgbW9yZSBjb25zdHJhaW5lZCBieSB0aGUgaGVpZ2h0LlxuICAgICAgICAgIGNvbnN0IGxhYmVsSGVpZ2h0ID0gdGlja09wdHMubWlycm9yID8gMCA6IHNpbiAqIHdpZGVzdC53aWR0aCArIGNvcyAqIGhpZ2hlc3QuaGVpZ2h0O1xuICAgICAgICAgIG1pblNpemUuaGVpZ2h0ID0gTWF0aC5taW4odGhpcy5tYXhIZWlnaHQsIG1pblNpemUuaGVpZ2h0ICsgbGFiZWxIZWlnaHQgKyB0aWNrUGFkZGluZyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEEgdmVydGljYWwgYXhpcyBpcyBtb3JlIGNvbnN0cmFpbmVkIGJ5IHRoZSB3aWR0aC4gTGFiZWxzIGFyZSB0aGVcbiAgICAgICAgLy8gZG9taW5hbnQgZmFjdG9yIGhlcmUsIHNvIGdldCB0aGF0IGxlbmd0aCBmaXJzdCBhbmQgYWNjb3VudCBmb3IgcGFkZGluZ1xuICAgICAgICAgIGNvbnN0IGxhYmVsV2lkdGggPSB0aWNrT3B0cy5taXJyb3IgPyAwIDogY29zICogd2lkZXN0LndpZHRoICsgc2luICogaGlnaGVzdC5oZWlnaHQ7XG5cbiAgICAgICAgICBtaW5TaXplLndpZHRoID0gTWF0aC5taW4odGhpcy5tYXhXaWR0aCwgbWluU2l6ZS53aWR0aCArIGxhYmVsV2lkdGggKyB0aWNrUGFkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY2FsY3VsYXRlUGFkZGluZyhmaXJzdCwgbGFzdCwgc2luLCBjb3MpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2hhbmRsZU1hcmdpbnMoKTtcblxuICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgIHRoaXMud2lkdGggPSB0aGlzLl9sZW5ndGggPSBjaGFydC53aWR0aCAtIHRoaXMuX21hcmdpbnMubGVmdCAtIHRoaXMuX21hcmdpbnMucmlnaHQ7XG4gICAgICB0aGlzLmhlaWdodCA9IG1pblNpemUuaGVpZ2h0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLndpZHRoID0gbWluU2l6ZS53aWR0aDtcbiAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5fbGVuZ3RoID0gY2hhcnQuaGVpZ2h0IC0gdGhpcy5fbWFyZ2lucy50b3AgLSB0aGlzLl9tYXJnaW5zLmJvdHRvbTtcbiAgICB9XG4gIH1cblxuICBfY2FsY3VsYXRlUGFkZGluZyhmaXJzdCwgbGFzdCwgc2luLCBjb3MpIHtcbiAgICBjb25zdCB7dGlja3M6IHthbGlnbiwgcGFkZGluZ30sIHBvc2l0aW9ufSA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBpc1JvdGF0ZWQgPSB0aGlzLmxhYmVsUm90YXRpb24gIT09IDA7XG4gICAgY29uc3QgbGFiZWxzQmVsb3dUaWNrcyA9IHBvc2l0aW9uICE9PSAndG9wJyAmJiB0aGlzLmF4aXMgPT09ICd4JztcblxuICAgIGlmICh0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XG4gICAgICBjb25zdCBvZmZzZXRMZWZ0ID0gdGhpcy5nZXRQaXhlbEZvclRpY2soMCkgLSB0aGlzLmxlZnQ7XG4gICAgICBjb25zdCBvZmZzZXRSaWdodCA9IHRoaXMucmlnaHQgLSB0aGlzLmdldFBpeGVsRm9yVGljayh0aGlzLnRpY2tzLmxlbmd0aCAtIDEpO1xuICAgICAgbGV0IHBhZGRpbmdMZWZ0ID0gMDtcbiAgICAgIGxldCBwYWRkaW5nUmlnaHQgPSAwO1xuXG4gICAgICAvLyBFbnN1cmUgdGhhdCBvdXIgdGlja3MgYXJlIGFsd2F5cyBpbnNpZGUgdGhlIGNhbnZhcy4gV2hlbiByb3RhdGVkLCB0aWNrcyBhcmUgcmlnaHQgYWxpZ25lZFxuICAgICAgLy8gd2hpY2ggbWVhbnMgdGhhdCB0aGUgcmlnaHQgcGFkZGluZyBpcyBkb21pbmF0ZWQgYnkgdGhlIGZvbnQgaGVpZ2h0XG4gICAgICBpZiAoaXNSb3RhdGVkKSB7XG4gICAgICAgIGlmIChsYWJlbHNCZWxvd1RpY2tzKSB7XG4gICAgICAgICAgcGFkZGluZ0xlZnQgPSBjb3MgKiBmaXJzdC53aWR0aDtcbiAgICAgICAgICBwYWRkaW5nUmlnaHQgPSBzaW4gKiBsYXN0LmhlaWdodDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYWRkaW5nTGVmdCA9IHNpbiAqIGZpcnN0LmhlaWdodDtcbiAgICAgICAgICBwYWRkaW5nUmlnaHQgPSBjb3MgKiBsYXN0LndpZHRoO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGFsaWduID09PSAnc3RhcnQnKSB7XG4gICAgICAgIHBhZGRpbmdSaWdodCA9IGxhc3Qud2lkdGg7XG4gICAgICB9IGVsc2UgaWYgKGFsaWduID09PSAnZW5kJykge1xuICAgICAgICBwYWRkaW5nTGVmdCA9IGZpcnN0LndpZHRoO1xuICAgICAgfSBlbHNlIGlmIChhbGlnbiAhPT0gJ2lubmVyJykge1xuICAgICAgICBwYWRkaW5nTGVmdCA9IGZpcnN0LndpZHRoIC8gMjtcbiAgICAgICAgcGFkZGluZ1JpZ2h0ID0gbGFzdC53aWR0aCAvIDI7XG4gICAgICB9XG5cbiAgICAgIC8vIEFkanVzdCBwYWRkaW5nIHRha2luZyBpbnRvIGFjY291bnQgY2hhbmdlcyBpbiBvZmZzZXRzXG4gICAgICB0aGlzLnBhZGRpbmdMZWZ0ID0gTWF0aC5tYXgoKHBhZGRpbmdMZWZ0IC0gb2Zmc2V0TGVmdCArIHBhZGRpbmcpICogdGhpcy53aWR0aCAvICh0aGlzLndpZHRoIC0gb2Zmc2V0TGVmdCksIDApO1xuICAgICAgdGhpcy5wYWRkaW5nUmlnaHQgPSBNYXRoLm1heCgocGFkZGluZ1JpZ2h0IC0gb2Zmc2V0UmlnaHQgKyBwYWRkaW5nKSAqIHRoaXMud2lkdGggLyAodGhpcy53aWR0aCAtIG9mZnNldFJpZ2h0KSwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBwYWRkaW5nVG9wID0gbGFzdC5oZWlnaHQgLyAyO1xuICAgICAgbGV0IHBhZGRpbmdCb3R0b20gPSBmaXJzdC5oZWlnaHQgLyAyO1xuXG4gICAgICBpZiAoYWxpZ24gPT09ICdzdGFydCcpIHtcbiAgICAgICAgcGFkZGluZ1RvcCA9IDA7XG4gICAgICAgIHBhZGRpbmdCb3R0b20gPSBmaXJzdC5oZWlnaHQ7XG4gICAgICB9IGVsc2UgaWYgKGFsaWduID09PSAnZW5kJykge1xuICAgICAgICBwYWRkaW5nVG9wID0gbGFzdC5oZWlnaHQ7XG4gICAgICAgIHBhZGRpbmdCb3R0b20gPSAwO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnBhZGRpbmdUb3AgPSBwYWRkaW5nVG9wICsgcGFkZGluZztcbiAgICAgIHRoaXMucGFkZGluZ0JvdHRvbSA9IHBhZGRpbmdCb3R0b20gKyBwYWRkaW5nO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBIYW5kbGUgbWFyZ2lucyBhbmQgcGFkZGluZyBpbnRlcmFjdGlvbnNcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9oYW5kbGVNYXJnaW5zKCkge1xuICAgIGlmICh0aGlzLl9tYXJnaW5zKSB7XG4gICAgICB0aGlzLl9tYXJnaW5zLmxlZnQgPSBNYXRoLm1heCh0aGlzLnBhZGRpbmdMZWZ0LCB0aGlzLl9tYXJnaW5zLmxlZnQpO1xuICAgICAgdGhpcy5fbWFyZ2lucy50b3AgPSBNYXRoLm1heCh0aGlzLnBhZGRpbmdUb3AsIHRoaXMuX21hcmdpbnMudG9wKTtcbiAgICAgIHRoaXMuX21hcmdpbnMucmlnaHQgPSBNYXRoLm1heCh0aGlzLnBhZGRpbmdSaWdodCwgdGhpcy5fbWFyZ2lucy5yaWdodCk7XG4gICAgICB0aGlzLl9tYXJnaW5zLmJvdHRvbSA9IE1hdGgubWF4KHRoaXMucGFkZGluZ0JvdHRvbSwgdGhpcy5fbWFyZ2lucy5ib3R0b20pO1xuICAgIH1cbiAgfVxuXG4gIGFmdGVyRml0KCkge1xuICAgIGNhbGwodGhpcy5vcHRpb25zLmFmdGVyRml0LCBbdGhpc10pO1xuICB9XG5cbiAgLy8gU2hhcmVkIE1ldGhvZHNcbiAgLyoqXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuICBpc0hvcml6b250YWwoKSB7XG4gICAgY29uc3Qge2F4aXMsIHBvc2l0aW9ufSA9IHRoaXMub3B0aW9ucztcbiAgICByZXR1cm4gcG9zaXRpb24gPT09ICd0b3AnIHx8IHBvc2l0aW9uID09PSAnYm90dG9tJyB8fCBheGlzID09PSAneCc7XG4gIH1cbiAgLyoqXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59XG5cdCAqL1xuICBpc0Z1bGxTaXplKCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZnVsbFNpemU7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtUaWNrW119IHRpY2tzXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfY29udmVydFRpY2tzVG9MYWJlbHModGlja3MpIHtcbiAgICB0aGlzLmJlZm9yZVRpY2tUb0xhYmVsQ29udmVyc2lvbigpO1xuXG4gICAgdGhpcy5nZW5lcmF0ZVRpY2tMYWJlbHModGlja3MpO1xuXG4gICAgLy8gVGlja3Mgc2hvdWxkIGJlIHNraXBwZWQgd2hlbiBjYWxsYmFjayByZXR1cm5zIG51bGwgb3IgdW5kZWYsIHNvIGxldHMgcmVtb3ZlIHRob3NlLlxuICAgIGxldCBpLCBpbGVuO1xuICAgIGZvciAoaSA9IDAsIGlsZW4gPSB0aWNrcy5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcbiAgICAgIGlmIChpc051bGxPclVuZGVmKHRpY2tzW2ldLmxhYmVsKSkge1xuICAgICAgICB0aWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGlsZW4tLTtcbiAgICAgICAgaS0tO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuYWZ0ZXJUaWNrVG9MYWJlbENvbnZlcnNpb24oKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcmV0dXJuIHt7IGZpcnN0OiBvYmplY3QsIGxhc3Q6IG9iamVjdCwgd2lkZXN0OiBvYmplY3QsIGhpZ2hlc3Q6IG9iamVjdCwgd2lkdGhzOiBBcnJheSwgaGVpZ2h0czogYXJyYXkgfX1cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRMYWJlbFNpemVzKCkge1xuICAgIGxldCBsYWJlbFNpemVzID0gdGhpcy5fbGFiZWxTaXplcztcblxuICAgIGlmICghbGFiZWxTaXplcykge1xuICAgICAgY29uc3Qgc2FtcGxlU2l6ZSA9IHRoaXMub3B0aW9ucy50aWNrcy5zYW1wbGVTaXplO1xuICAgICAgbGV0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICAgIGlmIChzYW1wbGVTaXplIDwgdGlja3MubGVuZ3RoKSB7XG4gICAgICAgIHRpY2tzID0gc2FtcGxlKHRpY2tzLCBzYW1wbGVTaXplKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fbGFiZWxTaXplcyA9IGxhYmVsU2l6ZXMgPSB0aGlzLl9jb21wdXRlTGFiZWxTaXplcyh0aWNrcywgdGlja3MubGVuZ3RoLCB0aGlzLm9wdGlvbnMudGlja3MubWF4VGlja3NMaW1pdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxhYmVsU2l6ZXM7XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB7d2lkdGgsIGhlaWdodCwgb2Zmc2V0fSBvYmplY3RzIGZvciB0aGUgZmlyc3QsIGxhc3QsIHdpZGVzdCwgaGlnaGVzdCB0aWNrXG5cdCAqIGxhYmVscyB3aGVyZSBvZmZzZXQgaW5kaWNhdGVzIHRoZSBhbmNob3IgcG9pbnQgb2Zmc2V0IGZyb20gdGhlIHRvcCBpbiBwaXhlbHMuXG5cdCAqIEByZXR1cm4ge3sgZmlyc3Q6IG9iamVjdCwgbGFzdDogb2JqZWN0LCB3aWRlc3Q6IG9iamVjdCwgaGlnaGVzdDogb2JqZWN0LCB3aWR0aHM6IEFycmF5LCBoZWlnaHRzOiBhcnJheSB9fVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2NvbXB1dGVMYWJlbFNpemVzKHRpY2tzLCBsZW5ndGgsIG1heFRpY2tzTGltaXQpIHtcbiAgICBjb25zdCB7Y3R4LCBfbG9uZ2VzdFRleHRDYWNoZTogY2FjaGVzfSA9IHRoaXM7XG4gICAgY29uc3Qgd2lkdGhzID0gW107XG4gICAgY29uc3QgaGVpZ2h0cyA9IFtdO1xuICAgIGNvbnN0IGluY3JlbWVudCA9IE1hdGguZmxvb3IobGVuZ3RoIC8gZ2V0VGlja3NMaW1pdChsZW5ndGgsIG1heFRpY2tzTGltaXQpKTtcbiAgICBsZXQgd2lkZXN0TGFiZWxTaXplID0gMDtcbiAgICBsZXQgaGlnaGVzdExhYmVsU2l6ZSA9IDA7XG4gICAgbGV0IGksIGosIGpsZW4sIGxhYmVsLCB0aWNrRm9udCwgZm9udFN0cmluZywgY2FjaGUsIGxpbmVIZWlnaHQsIHdpZHRoLCBoZWlnaHQsIG5lc3RlZExhYmVsO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSBpbmNyZW1lbnQpIHtcbiAgICAgIGxhYmVsID0gdGlja3NbaV0ubGFiZWw7XG4gICAgICB0aWNrRm9udCA9IHRoaXMuX3Jlc29sdmVUaWNrRm9udE9wdGlvbnMoaSk7XG4gICAgICBjdHguZm9udCA9IGZvbnRTdHJpbmcgPSB0aWNrRm9udC5zdHJpbmc7XG4gICAgICBjYWNoZSA9IGNhY2hlc1tmb250U3RyaW5nXSA9IGNhY2hlc1tmb250U3RyaW5nXSB8fCB7ZGF0YToge30sIGdjOiBbXX07XG4gICAgICBsaW5lSGVpZ2h0ID0gdGlja0ZvbnQubGluZUhlaWdodDtcbiAgICAgIHdpZHRoID0gaGVpZ2h0ID0gMDtcbiAgICAgIC8vIFVuZGVmaW5lZCBsYWJlbHMgYW5kIGFycmF5cyBzaG91bGQgbm90IGJlIG1lYXN1cmVkXG4gICAgICBpZiAoIWlzTnVsbE9yVW5kZWYobGFiZWwpICYmICFpc0FycmF5KGxhYmVsKSkge1xuICAgICAgICB3aWR0aCA9IF9tZWFzdXJlVGV4dChjdHgsIGNhY2hlLmRhdGEsIGNhY2hlLmdjLCB3aWR0aCwgbGFiZWwpO1xuICAgICAgICBoZWlnaHQgPSBsaW5lSGVpZ2h0O1xuICAgICAgfSBlbHNlIGlmIChpc0FycmF5KGxhYmVsKSkge1xuICAgICAgICAvLyBpZiBpdCBpcyBhbiBhcnJheSBsZXQncyBtZWFzdXJlIGVhY2ggZWxlbWVudFxuICAgICAgICBmb3IgKGogPSAwLCBqbGVuID0gbGFiZWwubGVuZ3RoOyBqIDwgamxlbjsgKytqKSB7XG4gICAgICAgICAgbmVzdGVkTGFiZWwgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKGxhYmVsW2pdKTtcbiAgICAgICAgICAvLyBVbmRlZmluZWQgbGFiZWxzIGFuZCBhcnJheXMgc2hvdWxkIG5vdCBiZSBtZWFzdXJlZFxuICAgICAgICAgIGlmICghaXNOdWxsT3JVbmRlZihuZXN0ZWRMYWJlbCkgJiYgIWlzQXJyYXkobmVzdGVkTGFiZWwpKSB7XG4gICAgICAgICAgICB3aWR0aCA9IF9tZWFzdXJlVGV4dChjdHgsIGNhY2hlLmRhdGEsIGNhY2hlLmdjLCB3aWR0aCwgbmVzdGVkTGFiZWwpO1xuICAgICAgICAgICAgaGVpZ2h0ICs9IGxpbmVIZWlnaHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aWR0aHMucHVzaCh3aWR0aCk7XG4gICAgICBoZWlnaHRzLnB1c2goaGVpZ2h0KTtcbiAgICAgIHdpZGVzdExhYmVsU2l6ZSA9IE1hdGgubWF4KHdpZHRoLCB3aWRlc3RMYWJlbFNpemUpO1xuICAgICAgaGlnaGVzdExhYmVsU2l6ZSA9IE1hdGgubWF4KGhlaWdodCwgaGlnaGVzdExhYmVsU2l6ZSk7XG4gICAgfVxuICAgIGdhcmJhZ2VDb2xsZWN0KGNhY2hlcywgbGVuZ3RoKTtcblxuICAgIGNvbnN0IHdpZGVzdCA9IHdpZHRocy5pbmRleE9mKHdpZGVzdExhYmVsU2l6ZSk7XG4gICAgY29uc3QgaGlnaGVzdCA9IGhlaWdodHMuaW5kZXhPZihoaWdoZXN0TGFiZWxTaXplKTtcblxuICAgIGNvbnN0IHZhbHVlQXQgPSAoaWR4KSA9PiAoe3dpZHRoOiB3aWR0aHNbaWR4XSB8fCAwLCBoZWlnaHQ6IGhlaWdodHNbaWR4XSB8fCAwfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZmlyc3Q6IHZhbHVlQXQoMCksXG4gICAgICBsYXN0OiB2YWx1ZUF0KGxlbmd0aCAtIDEpLFxuICAgICAgd2lkZXN0OiB2YWx1ZUF0KHdpZGVzdCksXG4gICAgICBoaWdoZXN0OiB2YWx1ZUF0KGhpZ2hlc3QpLFxuICAgICAgd2lkdGhzLFxuICAgICAgaGVpZ2h0cyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG5cdCAqIFVzZWQgdG8gZ2V0IHRoZSBsYWJlbCB0byBkaXNwbGF5IGluIHRoZSB0b29sdGlwIGZvciB0aGUgZ2l2ZW4gdmFsdWVcblx0ICogQHBhcmFtIHsqfSB2YWx1ZVxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuICBnZXRMYWJlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJldHVybnMgdGhlIGxvY2F0aW9uIG9mIHRoZSBnaXZlbiBkYXRhIHBvaW50LiBWYWx1ZSBjYW4gZWl0aGVyIGJlIGFuIGluZGV4IG9yIGEgbnVtZXJpY2FsIHZhbHVlXG5cdCAqIFRoZSBjb29yZGluYXRlICgwLCAwKSBpcyBhdCB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlIGNhbnZhc1xuXHQgKiBAcGFyYW0geyp9IHZhbHVlXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbaW5kZXhdXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG4gIGdldFBpeGVsRm9yVmFsdWUodmFsdWUsIGluZGV4KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICByZXR1cm4gTmFOO1xuICB9XG5cbiAgLyoqXG5cdCAqIFVzZWQgdG8gZ2V0IHRoZSBkYXRhIHZhbHVlIGZyb20gYSBnaXZlbiBwaXhlbC4gVGhpcyBpcyB0aGUgaW52ZXJzZSBvZiBnZXRQaXhlbEZvclZhbHVlXG5cdCAqIFRoZSBjb29yZGluYXRlICgwLCAwKSBpcyBhdCB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlIGNhbnZhc1xuXHQgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxcblx0ICogQHJldHVybiB7Kn1cblx0ICovXG4gIGdldFZhbHVlRm9yUGl4ZWwocGl4ZWwpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcblxuICAvKipcblx0ICogUmV0dXJucyB0aGUgbG9jYXRpb24gb2YgdGhlIHRpY2sgYXQgdGhlIGdpdmVuIGluZGV4XG5cdCAqIFRoZSBjb29yZGluYXRlICgwLCAwKSBpcyBhdCB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlIGNhbnZhc1xuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgZ2V0UGl4ZWxGb3JUaWNrKGluZGV4KSB7XG4gICAgY29uc3QgdGlja3MgPSB0aGlzLnRpY2tzO1xuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPiB0aWNrcy5sZW5ndGggLSAxKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JWYWx1ZSh0aWNrc1tpbmRleF0udmFsdWUpO1xuICB9XG5cbiAgLyoqXG5cdCAqIFV0aWxpdHkgZm9yIGdldHRpbmcgdGhlIHBpeGVsIGxvY2F0aW9uIG9mIGEgcGVyY2VudGFnZSBvZiBzY2FsZVxuXHQgKiBUaGUgY29vcmRpbmF0ZSAoMCwgMCkgaXMgYXQgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZSBjYW52YXNcblx0ICogQHBhcmFtIHtudW1iZXJ9IGRlY2ltYWxcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgZ2V0UGl4ZWxGb3JEZWNpbWFsKGRlY2ltYWwpIHtcbiAgICBpZiAodGhpcy5fcmV2ZXJzZVBpeGVscykge1xuICAgICAgZGVjaW1hbCA9IDEgLSBkZWNpbWFsO1xuICAgIH1cblxuICAgIGNvbnN0IHBpeGVsID0gdGhpcy5fc3RhcnRQaXhlbCArIGRlY2ltYWwgKiB0aGlzLl9sZW5ndGg7XG4gICAgcmV0dXJuIF9pbnQxNlJhbmdlKHRoaXMuX2FsaWduVG9QaXhlbHMgPyBfYWxpZ25QaXhlbCh0aGlzLmNoYXJ0LCBwaXhlbCwgMCkgOiBwaXhlbCk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG4gIGdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkge1xuICAgIGNvbnN0IGRlY2ltYWwgPSAocGl4ZWwgLSB0aGlzLl9zdGFydFBpeGVsKSAvIHRoaXMuX2xlbmd0aDtcbiAgICByZXR1cm4gdGhpcy5fcmV2ZXJzZVBpeGVscyA/IDEgLSBkZWNpbWFsIDogZGVjaW1hbDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIHRoZSBwaXhlbCBmb3IgdGhlIG1pbmltdW0gY2hhcnQgdmFsdWVcblx0ICogVGhlIGNvb3JkaW5hdGUgKDAsIDApIGlzIGF0IHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGUgY2FudmFzXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG4gIGdldEJhc2VQaXhlbCgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRQaXhlbEZvclZhbHVlKHRoaXMuZ2V0QmFzZVZhbHVlKCkpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG4gIGdldEJhc2VWYWx1ZSgpIHtcbiAgICBjb25zdCB7bWluLCBtYXh9ID0gdGhpcztcblxuICAgIHJldHVybiBtaW4gPCAwICYmIG1heCA8IDAgPyBtYXggOlxuICAgICAgbWluID4gMCAmJiBtYXggPiAwID8gbWluIDpcbiAgICAgIDA7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0Q29udGV4dChpbmRleCkge1xuICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcyB8fCBbXTtcblxuICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgdGlja3MubGVuZ3RoKSB7XG4gICAgICBjb25zdCB0aWNrID0gdGlja3NbaW5kZXhdO1xuICAgICAgcmV0dXJuIHRpY2suJGNvbnRleHQgfHxcblx0XHRcdFx0KHRpY2suJGNvbnRleHQgPSBjcmVhdGVUaWNrQ29udGV4dCh0aGlzLmdldENvbnRleHQoKSwgaW5kZXgsIHRpY2spKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuJGNvbnRleHQgfHxcblx0XHRcdCh0aGlzLiRjb250ZXh0ID0gY3JlYXRlU2NhbGVDb250ZXh0KHRoaXMuY2hhcnQuZ2V0Q29udGV4dCgpLCB0aGlzKSk7XG4gIH1cblxuICAvKipcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3RpY2tTaXplKCkge1xuICAgIGNvbnN0IG9wdGlvblRpY2tzID0gdGhpcy5vcHRpb25zLnRpY2tzO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHNwYWNlIG5lZWRlZCBieSBsYWJlbCBpbiBheGlzIGRpcmVjdGlvbi5cbiAgICBjb25zdCByb3QgPSB0b1JhZGlhbnModGhpcy5sYWJlbFJvdGF0aW9uKTtcbiAgICBjb25zdCBjb3MgPSBNYXRoLmFicyhNYXRoLmNvcyhyb3QpKTtcbiAgICBjb25zdCBzaW4gPSBNYXRoLmFicyhNYXRoLnNpbihyb3QpKTtcblxuICAgIGNvbnN0IGxhYmVsU2l6ZXMgPSB0aGlzLl9nZXRMYWJlbFNpemVzKCk7XG4gICAgY29uc3QgcGFkZGluZyA9IG9wdGlvblRpY2tzLmF1dG9Ta2lwUGFkZGluZyB8fCAwO1xuICAgIGNvbnN0IHcgPSBsYWJlbFNpemVzID8gbGFiZWxTaXplcy53aWRlc3Qud2lkdGggKyBwYWRkaW5nIDogMDtcbiAgICBjb25zdCBoID0gbGFiZWxTaXplcyA/IGxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQgKyBwYWRkaW5nIDogMDtcblxuICAgIC8vIENhbGN1bGF0ZSBzcGFjZSBuZWVkZWQgZm9yIDEgdGljayBpbiBheGlzIGRpcmVjdGlvbi5cbiAgICByZXR1cm4gdGhpcy5pc0hvcml6b250YWwoKVxuICAgICAgPyBoICogY29zID4gdyAqIHNpbiA/IHcgLyBjb3MgOiBoIC8gc2luXG4gICAgICA6IGggKiBzaW4gPCB3ICogY29zID8gaCAvIGNvcyA6IHcgLyBzaW47XG4gIH1cblxuICAvKipcblx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9pc1Zpc2libGUoKSB7XG4gICAgY29uc3QgZGlzcGxheSA9IHRoaXMub3B0aW9ucy5kaXNwbGF5O1xuXG4gICAgaWYgKGRpc3BsYXkgIT09ICdhdXRvJykge1xuICAgICAgcmV0dXJuICEhZGlzcGxheTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5nZXRNYXRjaGluZ1Zpc2libGVNZXRhcygpLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9jb21wdXRlR3JpZExpbmVJdGVtcyhjaGFydEFyZWEpIHtcbiAgICBjb25zdCBheGlzID0gdGhpcy5heGlzO1xuICAgIGNvbnN0IGNoYXJ0ID0gdGhpcy5jaGFydDtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHtncmlkLCBwb3NpdGlvbiwgYm9yZGVyfSA9IG9wdGlvbnM7XG4gICAgY29uc3Qgb2Zmc2V0ID0gZ3JpZC5vZmZzZXQ7XG4gICAgY29uc3QgaXNIb3Jpem9udGFsID0gdGhpcy5pc0hvcml6b250YWwoKTtcbiAgICBjb25zdCB0aWNrcyA9IHRoaXMudGlja3M7XG4gICAgY29uc3QgdGlja3NMZW5ndGggPSB0aWNrcy5sZW5ndGggKyAob2Zmc2V0ID8gMSA6IDApO1xuICAgIGNvbnN0IHRsID0gZ2V0VGlja01hcmtMZW5ndGgoZ3JpZCk7XG4gICAgY29uc3QgaXRlbXMgPSBbXTtcblxuICAgIGNvbnN0IGJvcmRlck9wdHMgPSBib3JkZXIuc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoKSk7XG4gICAgY29uc3QgYXhpc1dpZHRoID0gYm9yZGVyT3B0cy5kaXNwbGF5ID8gYm9yZGVyT3B0cy53aWR0aCA6IDA7XG4gICAgY29uc3QgYXhpc0hhbGZXaWR0aCA9IGF4aXNXaWR0aCAvIDI7XG4gICAgY29uc3QgYWxpZ25Cb3JkZXJWYWx1ZSA9IGZ1bmN0aW9uKHBpeGVsKSB7XG4gICAgICByZXR1cm4gX2FsaWduUGl4ZWwoY2hhcnQsIHBpeGVsLCBheGlzV2lkdGgpO1xuICAgIH07XG4gICAgbGV0IGJvcmRlclZhbHVlLCBpLCBsaW5lVmFsdWUsIGFsaWduZWRMaW5lVmFsdWU7XG4gICAgbGV0IHR4MSwgdHkxLCB0eDIsIHR5MiwgeDEsIHkxLCB4MiwgeTI7XG5cbiAgICBpZiAocG9zaXRpb24gPT09ICd0b3AnKSB7XG4gICAgICBib3JkZXJWYWx1ZSA9IGFsaWduQm9yZGVyVmFsdWUodGhpcy5ib3R0b20pO1xuICAgICAgdHkxID0gdGhpcy5ib3R0b20gLSB0bDtcbiAgICAgIHR5MiA9IGJvcmRlclZhbHVlIC0gYXhpc0hhbGZXaWR0aDtcbiAgICAgIHkxID0gYWxpZ25Cb3JkZXJWYWx1ZShjaGFydEFyZWEudG9wKSArIGF4aXNIYWxmV2lkdGg7XG4gICAgICB5MiA9IGNoYXJ0QXJlYS5ib3R0b207XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2JvdHRvbScpIHtcbiAgICAgIGJvcmRlclZhbHVlID0gYWxpZ25Cb3JkZXJWYWx1ZSh0aGlzLnRvcCk7XG4gICAgICB5MSA9IGNoYXJ0QXJlYS50b3A7XG4gICAgICB5MiA9IGFsaWduQm9yZGVyVmFsdWUoY2hhcnRBcmVhLmJvdHRvbSkgLSBheGlzSGFsZldpZHRoO1xuICAgICAgdHkxID0gYm9yZGVyVmFsdWUgKyBheGlzSGFsZldpZHRoO1xuICAgICAgdHkyID0gdGhpcy50b3AgKyB0bDtcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcpIHtcbiAgICAgIGJvcmRlclZhbHVlID0gYWxpZ25Cb3JkZXJWYWx1ZSh0aGlzLnJpZ2h0KTtcbiAgICAgIHR4MSA9IHRoaXMucmlnaHQgLSB0bDtcbiAgICAgIHR4MiA9IGJvcmRlclZhbHVlIC0gYXhpc0hhbGZXaWR0aDtcbiAgICAgIHgxID0gYWxpZ25Cb3JkZXJWYWx1ZShjaGFydEFyZWEubGVmdCkgKyBheGlzSGFsZldpZHRoO1xuICAgICAgeDIgPSBjaGFydEFyZWEucmlnaHQ7XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKHRoaXMubGVmdCk7XG4gICAgICB4MSA9IGNoYXJ0QXJlYS5sZWZ0O1xuICAgICAgeDIgPSBhbGlnbkJvcmRlclZhbHVlKGNoYXJ0QXJlYS5yaWdodCkgLSBheGlzSGFsZldpZHRoO1xuICAgICAgdHgxID0gYm9yZGVyVmFsdWUgKyBheGlzSGFsZldpZHRoO1xuICAgICAgdHgyID0gdGhpcy5sZWZ0ICsgdGw7XG4gICAgfSBlbHNlIGlmIChheGlzID09PSAneCcpIHtcbiAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKChjaGFydEFyZWEudG9wICsgY2hhcnRBcmVhLmJvdHRvbSkgLyAyICsgMC41KTtcbiAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QocG9zaXRpb24pKSB7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uQXhpc0lEID0gT2JqZWN0LmtleXMocG9zaXRpb24pWzBdO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHBvc2l0aW9uW3Bvc2l0aW9uQXhpc0lEXTtcbiAgICAgICAgYm9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKHRoaXMuY2hhcnQuc2NhbGVzW3Bvc2l0aW9uQXhpc0lEXS5nZXRQaXhlbEZvclZhbHVlKHZhbHVlKSk7XG4gICAgICB9XG5cbiAgICAgIHkxID0gY2hhcnRBcmVhLnRvcDtcbiAgICAgIHkyID0gY2hhcnRBcmVhLmJvdHRvbTtcbiAgICAgIHR5MSA9IGJvcmRlclZhbHVlICsgYXhpc0hhbGZXaWR0aDtcbiAgICAgIHR5MiA9IHR5MSArIHRsO1xuICAgIH0gZWxzZSBpZiAoYXhpcyA9PT0gJ3knKSB7XG4gICAgICBpZiAocG9zaXRpb24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgIGJvcmRlclZhbHVlID0gYWxpZ25Cb3JkZXJWYWx1ZSgoY2hhcnRBcmVhLmxlZnQgKyBjaGFydEFyZWEucmlnaHQpIC8gMik7XG4gICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHBvc2l0aW9uKSkge1xuICAgICAgICBjb25zdCBwb3NpdGlvbkF4aXNJRCA9IE9iamVjdC5rZXlzKHBvc2l0aW9uKVswXTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBwb3NpdGlvbltwb3NpdGlvbkF4aXNJRF07XG4gICAgICAgIGJvcmRlclZhbHVlID0gYWxpZ25Cb3JkZXJWYWx1ZSh0aGlzLmNoYXJ0LnNjYWxlc1twb3NpdGlvbkF4aXNJRF0uZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSkpO1xuICAgICAgfVxuXG4gICAgICB0eDEgPSBib3JkZXJWYWx1ZSAtIGF4aXNIYWxmV2lkdGg7XG4gICAgICB0eDIgPSB0eDEgLSB0bDtcbiAgICAgIHgxID0gY2hhcnRBcmVhLmxlZnQ7XG4gICAgICB4MiA9IGNoYXJ0QXJlYS5yaWdodDtcbiAgICB9XG5cbiAgICBjb25zdCBsaW1pdCA9IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMudGlja3MubWF4VGlja3NMaW1pdCwgdGlja3NMZW5ndGgpO1xuICAgIGNvbnN0IHN0ZXAgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodGlja3NMZW5ndGggLyBsaW1pdCkpO1xuICAgIGZvciAoaSA9IDA7IGkgPCB0aWNrc0xlbmd0aDsgaSArPSBzdGVwKSB7XG4gICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5nZXRDb250ZXh0KGkpO1xuICAgICAgY29uc3Qgb3B0c0F0SW5kZXggPSBncmlkLnNldENvbnRleHQoY29udGV4dCk7XG4gICAgICBjb25zdCBvcHRzQXRJbmRleEJvcmRlciA9IGJvcmRlci5zZXRDb250ZXh0KGNvbnRleHQpO1xuXG4gICAgICBjb25zdCBsaW5lV2lkdGggPSBvcHRzQXRJbmRleC5saW5lV2lkdGg7XG4gICAgICBjb25zdCBsaW5lQ29sb3IgPSBvcHRzQXRJbmRleC5jb2xvcjtcbiAgICAgIGNvbnN0IGJvcmRlckRhc2ggPSBvcHRzQXRJbmRleEJvcmRlci5kYXNoIHx8IFtdO1xuICAgICAgY29uc3QgYm9yZGVyRGFzaE9mZnNldCA9IG9wdHNBdEluZGV4Qm9yZGVyLmRhc2hPZmZzZXQ7XG5cbiAgICAgIGNvbnN0IHRpY2tXaWR0aCA9IG9wdHNBdEluZGV4LnRpY2tXaWR0aDtcbiAgICAgIGNvbnN0IHRpY2tDb2xvciA9IG9wdHNBdEluZGV4LnRpY2tDb2xvcjtcbiAgICAgIGNvbnN0IHRpY2tCb3JkZXJEYXNoID0gb3B0c0F0SW5kZXgudGlja0JvcmRlckRhc2ggfHwgW107XG4gICAgICBjb25zdCB0aWNrQm9yZGVyRGFzaE9mZnNldCA9IG9wdHNBdEluZGV4LnRpY2tCb3JkZXJEYXNoT2Zmc2V0O1xuXG4gICAgICBsaW5lVmFsdWUgPSBnZXRQaXhlbEZvckdyaWRMaW5lKHRoaXMsIGksIG9mZnNldCk7XG5cbiAgICAgIC8vIFNraXAgaWYgdGhlIHBpeGVsIGlzIG91dCBvZiB0aGUgcmFuZ2VcbiAgICAgIGlmIChsaW5lVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgYWxpZ25lZExpbmVWYWx1ZSA9IF9hbGlnblBpeGVsKGNoYXJ0LCBsaW5lVmFsdWUsIGxpbmVXaWR0aCk7XG5cbiAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgdHgxID0gdHgyID0geDEgPSB4MiA9IGFsaWduZWRMaW5lVmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0eTEgPSB0eTIgPSB5MSA9IHkyID0gYWxpZ25lZExpbmVWYWx1ZTtcbiAgICAgIH1cblxuICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgIHR4MSxcbiAgICAgICAgdHkxLFxuICAgICAgICB0eDIsXG4gICAgICAgIHR5MixcbiAgICAgICAgeDEsXG4gICAgICAgIHkxLFxuICAgICAgICB4MixcbiAgICAgICAgeTIsXG4gICAgICAgIHdpZHRoOiBsaW5lV2lkdGgsXG4gICAgICAgIGNvbG9yOiBsaW5lQ29sb3IsXG4gICAgICAgIGJvcmRlckRhc2gsXG4gICAgICAgIGJvcmRlckRhc2hPZmZzZXQsXG4gICAgICAgIHRpY2tXaWR0aCxcbiAgICAgICAgdGlja0NvbG9yLFxuICAgICAgICB0aWNrQm9yZGVyRGFzaCxcbiAgICAgICAgdGlja0JvcmRlckRhc2hPZmZzZXQsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl90aWNrc0xlbmd0aCA9IHRpY2tzTGVuZ3RoO1xuICAgIHRoaXMuX2JvcmRlclZhbHVlID0gYm9yZGVyVmFsdWU7XG5cbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9jb21wdXRlTGFiZWxJdGVtcyhjaGFydEFyZWEpIHtcbiAgICBjb25zdCBheGlzID0gdGhpcy5heGlzO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3Qge3Bvc2l0aW9uLCB0aWNrczogb3B0aW9uVGlja3N9ID0gb3B0aW9ucztcbiAgICBjb25zdCBpc0hvcml6b250YWwgPSB0aGlzLmlzSG9yaXpvbnRhbCgpO1xuICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICBjb25zdCB7YWxpZ24sIGNyb3NzQWxpZ24sIHBhZGRpbmcsIG1pcnJvcn0gPSBvcHRpb25UaWNrcztcbiAgICBjb25zdCB0bCA9IGdldFRpY2tNYXJrTGVuZ3RoKG9wdGlvbnMuZ3JpZCk7XG4gICAgY29uc3QgdGlja0FuZFBhZGRpbmcgPSB0bCArIHBhZGRpbmc7XG4gICAgY29uc3QgaFRpY2tBbmRQYWRkaW5nID0gbWlycm9yID8gLXBhZGRpbmcgOiB0aWNrQW5kUGFkZGluZztcbiAgICBjb25zdCByb3RhdGlvbiA9IC10b1JhZGlhbnModGhpcy5sYWJlbFJvdGF0aW9uKTtcbiAgICBjb25zdCBpdGVtcyA9IFtdO1xuICAgIGxldCBpLCBpbGVuLCB0aWNrLCBsYWJlbCwgeCwgeSwgdGV4dEFsaWduLCBwaXhlbCwgZm9udCwgbGluZUhlaWdodCwgbGluZUNvdW50LCB0ZXh0T2Zmc2V0O1xuICAgIGxldCB0ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcblxuICAgIGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcpIHtcbiAgICAgIHkgPSB0aGlzLmJvdHRvbSAtIGhUaWNrQW5kUGFkZGluZztcbiAgICAgIHRleHRBbGlnbiA9IHRoaXMuX2dldFhBeGlzTGFiZWxBbGlnbm1lbnQoKTtcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnYm90dG9tJykge1xuICAgICAgeSA9IHRoaXMudG9wICsgaFRpY2tBbmRQYWRkaW5nO1xuICAgICAgdGV4dEFsaWduID0gdGhpcy5fZ2V0WEF4aXNMYWJlbEFsaWdubWVudCgpO1xuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdsZWZ0Jykge1xuICAgICAgY29uc3QgcmV0ID0gdGhpcy5fZ2V0WUF4aXNMYWJlbEFsaWdubWVudCh0bCk7XG4gICAgICB0ZXh0QWxpZ24gPSByZXQudGV4dEFsaWduO1xuICAgICAgeCA9IHJldC54O1xuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdyaWdodCcpIHtcbiAgICAgIGNvbnN0IHJldCA9IHRoaXMuX2dldFlBeGlzTGFiZWxBbGlnbm1lbnQodGwpO1xuICAgICAgdGV4dEFsaWduID0gcmV0LnRleHRBbGlnbjtcbiAgICAgIHggPSByZXQueDtcbiAgICB9IGVsc2UgaWYgKGF4aXMgPT09ICd4Jykge1xuICAgICAgaWYgKHBvc2l0aW9uID09PSAnY2VudGVyJykge1xuICAgICAgICB5ID0gKChjaGFydEFyZWEudG9wICsgY2hhcnRBcmVhLmJvdHRvbSkgLyAyKSArIHRpY2tBbmRQYWRkaW5nO1xuICAgICAgfSBlbHNlIGlmIChpc09iamVjdChwb3NpdGlvbikpIHtcbiAgICAgICAgY29uc3QgcG9zaXRpb25BeGlzSUQgPSBPYmplY3Qua2V5cyhwb3NpdGlvbilbMF07XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcG9zaXRpb25bcG9zaXRpb25BeGlzSURdO1xuICAgICAgICB5ID0gdGhpcy5jaGFydC5zY2FsZXNbcG9zaXRpb25BeGlzSURdLmdldFBpeGVsRm9yVmFsdWUodmFsdWUpICsgdGlja0FuZFBhZGRpbmc7XG4gICAgICB9XG4gICAgICB0ZXh0QWxpZ24gPSB0aGlzLl9nZXRYQXhpc0xhYmVsQWxpZ25tZW50KCk7XG4gICAgfSBlbHNlIGlmIChheGlzID09PSAneScpIHtcbiAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgeCA9ICgoY2hhcnRBcmVhLmxlZnQgKyBjaGFydEFyZWEucmlnaHQpIC8gMikgLSB0aWNrQW5kUGFkZGluZztcbiAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QocG9zaXRpb24pKSB7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uQXhpc0lEID0gT2JqZWN0LmtleXMocG9zaXRpb24pWzBdO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHBvc2l0aW9uW3Bvc2l0aW9uQXhpc0lEXTtcbiAgICAgICAgeCA9IHRoaXMuY2hhcnQuc2NhbGVzW3Bvc2l0aW9uQXhpc0lEXS5nZXRQaXhlbEZvclZhbHVlKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHRleHRBbGlnbiA9IHRoaXMuX2dldFlBeGlzTGFiZWxBbGlnbm1lbnQodGwpLnRleHRBbGlnbjtcbiAgICB9XG5cbiAgICBpZiAoYXhpcyA9PT0gJ3knKSB7XG4gICAgICBpZiAoYWxpZ24gPT09ICdzdGFydCcpIHtcbiAgICAgICAgdGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgICB9IGVsc2UgaWYgKGFsaWduID09PSAnZW5kJykge1xuICAgICAgICB0ZXh0QmFzZWxpbmUgPSAnYm90dG9tJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBsYWJlbFNpemVzID0gdGhpcy5fZ2V0TGFiZWxTaXplcygpO1xuICAgIGZvciAoaSA9IDAsIGlsZW4gPSB0aWNrcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHRpY2sgPSB0aWNrc1tpXTtcbiAgICAgIGxhYmVsID0gdGljay5sYWJlbDtcblxuICAgICAgY29uc3Qgb3B0c0F0SW5kZXggPSBvcHRpb25UaWNrcy5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dChpKSk7XG4gICAgICBwaXhlbCA9IHRoaXMuZ2V0UGl4ZWxGb3JUaWNrKGkpICsgb3B0aW9uVGlja3MubGFiZWxPZmZzZXQ7XG4gICAgICBmb250ID0gdGhpcy5fcmVzb2x2ZVRpY2tGb250T3B0aW9ucyhpKTtcbiAgICAgIGxpbmVIZWlnaHQgPSBmb250LmxpbmVIZWlnaHQ7XG4gICAgICBsaW5lQ291bnQgPSBpc0FycmF5KGxhYmVsKSA/IGxhYmVsLmxlbmd0aCA6IDE7XG4gICAgICBjb25zdCBoYWxmQ291bnQgPSBsaW5lQ291bnQgLyAyO1xuICAgICAgY29uc3QgY29sb3IgPSBvcHRzQXRJbmRleC5jb2xvcjtcbiAgICAgIGNvbnN0IHN0cm9rZUNvbG9yID0gb3B0c0F0SW5kZXgudGV4dFN0cm9rZUNvbG9yO1xuICAgICAgY29uc3Qgc3Ryb2tlV2lkdGggPSBvcHRzQXRJbmRleC50ZXh0U3Ryb2tlV2lkdGg7XG4gICAgICBsZXQgdGlja1RleHRBbGlnbiA9IHRleHRBbGlnbjtcblxuICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICB4ID0gcGl4ZWw7XG5cbiAgICAgICAgaWYgKHRleHRBbGlnbiA9PT0gJ2lubmVyJykge1xuICAgICAgICAgIGlmIChpID09PSBpbGVuIC0gMSkge1xuICAgICAgICAgICAgdGlja1RleHRBbGlnbiA9ICF0aGlzLm9wdGlvbnMucmV2ZXJzZSA/ICdyaWdodCcgOiAnbGVmdCc7XG4gICAgICAgICAgfSBlbHNlIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgICB0aWNrVGV4dEFsaWduID0gIXRoaXMub3B0aW9ucy5yZXZlcnNlID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGlja1RleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcpIHtcbiAgICAgICAgICBpZiAoY3Jvc3NBbGlnbiA9PT0gJ25lYXInIHx8IHJvdGF0aW9uICE9PSAwKSB7XG4gICAgICAgICAgICB0ZXh0T2Zmc2V0ID0gLWxpbmVDb3VudCAqIGxpbmVIZWlnaHQgKyBsaW5lSGVpZ2h0IC8gMjtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNyb3NzQWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgICB0ZXh0T2Zmc2V0ID0gLWxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQgLyAyIC0gaGFsZkNvdW50ICogbGluZUhlaWdodCArIGxpbmVIZWlnaHQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRleHRPZmZzZXQgPSAtbGFiZWxTaXplcy5oaWdoZXN0LmhlaWdodCArIGxpbmVIZWlnaHQgLyAyO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbG9uZWx5LWlmXG4gICAgICAgICAgaWYgKGNyb3NzQWxpZ24gPT09ICduZWFyJyB8fCByb3RhdGlvbiAhPT0gMCkge1xuICAgICAgICAgICAgdGV4dE9mZnNldCA9IGxpbmVIZWlnaHQgLyAyO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY3Jvc3NBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICAgIHRleHRPZmZzZXQgPSBsYWJlbFNpemVzLmhpZ2hlc3QuaGVpZ2h0IC8gMiAtIGhhbGZDb3VudCAqIGxpbmVIZWlnaHQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRleHRPZmZzZXQgPSBsYWJlbFNpemVzLmhpZ2hlc3QuaGVpZ2h0IC0gbGluZUNvdW50ICogbGluZUhlaWdodDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1pcnJvcikge1xuICAgICAgICAgIHRleHRPZmZzZXQgKj0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJvdGF0aW9uICE9PSAwICYmICFvcHRzQXRJbmRleC5zaG93TGFiZWxCYWNrZHJvcCkge1xuICAgICAgICAgIHggKz0gKGxpbmVIZWlnaHQgLyAyKSAqIE1hdGguc2luKHJvdGF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeSA9IHBpeGVsO1xuICAgICAgICB0ZXh0T2Zmc2V0ID0gKDEgLSBsaW5lQ291bnQpICogbGluZUhlaWdodCAvIDI7XG4gICAgICB9XG5cbiAgICAgIGxldCBiYWNrZHJvcDtcblxuICAgICAgaWYgKG9wdHNBdEluZGV4LnNob3dMYWJlbEJhY2tkcm9wKSB7XG4gICAgICAgIGNvbnN0IGxhYmVsUGFkZGluZyA9IHRvUGFkZGluZyhvcHRzQXRJbmRleC5iYWNrZHJvcFBhZGRpbmcpO1xuICAgICAgICBjb25zdCBoZWlnaHQgPSBsYWJlbFNpemVzLmhlaWdodHNbaV07XG4gICAgICAgIGNvbnN0IHdpZHRoID0gbGFiZWxTaXplcy53aWR0aHNbaV07XG5cbiAgICAgICAgbGV0IHRvcCA9IHRleHRPZmZzZXQgLSBsYWJlbFBhZGRpbmcudG9wO1xuICAgICAgICBsZXQgbGVmdCA9IDAgLSBsYWJlbFBhZGRpbmcubGVmdDtcblxuICAgICAgICBzd2l0Y2ggKHRleHRCYXNlbGluZSkge1xuICAgICAgICBjYXNlICdtaWRkbGUnOlxuICAgICAgICAgIHRvcCAtPSBoZWlnaHQgLyAyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgIHRvcCAtPSBoZWlnaHQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBzd2l0Y2ggKHRleHRBbGlnbikge1xuICAgICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgICAgIGxlZnQgLT0gd2lkdGggLyAyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgbGVmdCAtPSB3aWR0aDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnaW5uZXInOlxuICAgICAgICAgIGlmIChpID09PSBpbGVuIC0gMSkge1xuICAgICAgICAgICAgbGVmdCAtPSB3aWR0aDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICBsZWZ0IC09IHdpZHRoIC8gMjtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBiYWNrZHJvcCA9IHtcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIHRvcCxcbiAgICAgICAgICB3aWR0aDogd2lkdGggKyBsYWJlbFBhZGRpbmcud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiBoZWlnaHQgKyBsYWJlbFBhZGRpbmcuaGVpZ2h0LFxuXG4gICAgICAgICAgY29sb3I6IG9wdHNBdEluZGV4LmJhY2tkcm9wQ29sb3IsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICBsYWJlbCxcbiAgICAgICAgZm9udCxcbiAgICAgICAgdGV4dE9mZnNldCxcbiAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgIHJvdGF0aW9uLFxuICAgICAgICAgIGNvbG9yLFxuICAgICAgICAgIHN0cm9rZUNvbG9yLFxuICAgICAgICAgIHN0cm9rZVdpZHRoLFxuICAgICAgICAgIHRleHRBbGlnbjogdGlja1RleHRBbGlnbixcbiAgICAgICAgICB0ZXh0QmFzZWxpbmUsXG4gICAgICAgICAgdHJhbnNsYXRpb246IFt4LCB5XSxcbiAgICAgICAgICBiYWNrZHJvcCxcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGl0ZW1zO1xuICB9XG5cbiAgX2dldFhBeGlzTGFiZWxBbGlnbm1lbnQoKSB7XG4gICAgY29uc3Qge3Bvc2l0aW9uLCB0aWNrc30gPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3Qgcm90YXRpb24gPSAtdG9SYWRpYW5zKHRoaXMubGFiZWxSb3RhdGlvbik7XG5cbiAgICBpZiAocm90YXRpb24pIHtcbiAgICAgIHJldHVybiBwb3NpdGlvbiA9PT0gJ3RvcCcgPyAnbGVmdCcgOiAncmlnaHQnO1xuICAgIH1cblxuICAgIGxldCBhbGlnbiA9ICdjZW50ZXInO1xuXG4gICAgaWYgKHRpY2tzLmFsaWduID09PSAnc3RhcnQnKSB7XG4gICAgICBhbGlnbiA9ICdsZWZ0JztcbiAgICB9IGVsc2UgaWYgKHRpY2tzLmFsaWduID09PSAnZW5kJykge1xuICAgICAgYWxpZ24gPSAncmlnaHQnO1xuICAgIH0gZWxzZSBpZiAodGlja3MuYWxpZ24gPT09ICdpbm5lcicpIHtcbiAgICAgIGFsaWduID0gJ2lubmVyJztcbiAgICB9XG5cbiAgICByZXR1cm4gYWxpZ247XG4gIH1cblxuICBfZ2V0WUF4aXNMYWJlbEFsaWdubWVudCh0bCkge1xuICAgIGNvbnN0IHtwb3NpdGlvbiwgdGlja3M6IHtjcm9zc0FsaWduLCBtaXJyb3IsIHBhZGRpbmd9fSA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBsYWJlbFNpemVzID0gdGhpcy5fZ2V0TGFiZWxTaXplcygpO1xuICAgIGNvbnN0IHRpY2tBbmRQYWRkaW5nID0gdGwgKyBwYWRkaW5nO1xuICAgIGNvbnN0IHdpZGVzdCA9IGxhYmVsU2l6ZXMud2lkZXN0LndpZHRoO1xuXG4gICAgbGV0IHRleHRBbGlnbjtcbiAgICBsZXQgeDtcblxuICAgIGlmIChwb3NpdGlvbiA9PT0gJ2xlZnQnKSB7XG4gICAgICBpZiAobWlycm9yKSB7XG4gICAgICAgIHggPSB0aGlzLnJpZ2h0ICsgcGFkZGluZztcblxuICAgICAgICBpZiAoY3Jvc3NBbGlnbiA9PT0gJ25lYXInKSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ2xlZnQnO1xuICAgICAgICB9IGVsc2UgaWYgKGNyb3NzQWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgICAgICAgeCArPSAod2lkZXN0IC8gMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICB4ICs9IHdpZGVzdDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeCA9IHRoaXMucmlnaHQgLSB0aWNrQW5kUGFkZGluZztcblxuICAgICAgICBpZiAoY3Jvc3NBbGlnbiA9PT0gJ25lYXInKSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgfSBlbHNlIGlmIChjcm9zc0FsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICAgIHRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICAgIHggLT0gKHdpZGVzdCAvIDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRleHRBbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgICB4ID0gdGhpcy5sZWZ0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgaWYgKG1pcnJvcikge1xuICAgICAgICB4ID0gdGhpcy5sZWZ0ICsgcGFkZGluZztcblxuICAgICAgICBpZiAoY3Jvc3NBbGlnbiA9PT0gJ25lYXInKSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgfSBlbHNlIGlmIChjcm9zc0FsaWduID09PSAnY2VudGVyJykge1xuICAgICAgICAgIHRleHRBbGlnbiA9ICdjZW50ZXInO1xuICAgICAgICAgIHggLT0gKHdpZGVzdCAvIDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRleHRBbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgICB4IC09IHdpZGVzdDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeCA9IHRoaXMubGVmdCArIHRpY2tBbmRQYWRkaW5nO1xuXG4gICAgICAgIGlmIChjcm9zc0FsaWduID09PSAnbmVhcicpIHtcbiAgICAgICAgICB0ZXh0QWxpZ24gPSAnbGVmdCc7XG4gICAgICAgIH0gZWxzZSBpZiAoY3Jvc3NBbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICB0ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICAgICAgICB4ICs9IHdpZGVzdCAvIDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGV4dEFsaWduID0gJ3JpZ2h0JztcbiAgICAgICAgICB4ID0gdGhpcy5yaWdodDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0ZXh0QWxpZ24gPSAncmlnaHQnO1xuICAgIH1cblxuICAgIHJldHVybiB7dGV4dEFsaWduLCB4fTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2NvbXB1dGVMYWJlbEFyZWEoKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy50aWNrcy5taXJyb3IpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLm9wdGlvbnMucG9zaXRpb247XG5cbiAgICBpZiAocG9zaXRpb24gPT09ICdsZWZ0JyB8fCBwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgcmV0dXJuIHt0b3A6IDAsIGxlZnQ6IHRoaXMubGVmdCwgYm90dG9tOiBjaGFydC5oZWlnaHQsIHJpZ2h0OiB0aGlzLnJpZ2h0fTtcbiAgICB9IGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcgfHwgcG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICByZXR1cm4ge3RvcDogdGhpcy50b3AsIGxlZnQ6IDAsIGJvdHRvbTogdGhpcy5ib3R0b20sIHJpZ2h0OiBjaGFydC53aWR0aH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIGRyYXdCYWNrZ3JvdW5kKCkge1xuICAgIGNvbnN0IHtjdHgsIG9wdGlvbnM6IHtiYWNrZ3JvdW5kQ29sb3J9LCBsZWZ0LCB0b3AsIHdpZHRoLCBoZWlnaHR9ID0gdGhpcztcbiAgICBpZiAoYmFja2dyb3VuZENvbG9yKSB7XG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IGJhY2tncm91bmRDb2xvcjtcbiAgICAgIGN0eC5maWxsUmVjdChsZWZ0LCB0b3AsIHdpZHRoLCBoZWlnaHQpO1xuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG4gIH1cblxuICBnZXRMaW5lV2lkdGhGb3JWYWx1ZSh2YWx1ZSkge1xuICAgIGNvbnN0IGdyaWQgPSB0aGlzLm9wdGlvbnMuZ3JpZDtcbiAgICBpZiAoIXRoaXMuX2lzVmlzaWJsZSgpIHx8ICFncmlkLmRpc3BsYXkpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjb25zdCB0aWNrcyA9IHRoaXMudGlja3M7XG4gICAgY29uc3QgaW5kZXggPSB0aWNrcy5maW5kSW5kZXgodCA9PiB0LnZhbHVlID09PSB2YWx1ZSk7XG4gICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgIGNvbnN0IG9wdHMgPSBncmlkLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KGluZGV4KSk7XG4gICAgICByZXR1cm4gb3B0cy5saW5lV2lkdGg7XG4gICAgfVxuICAgIHJldHVybiAwO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGRyYXdHcmlkKGNoYXJ0QXJlYSkge1xuICAgIGNvbnN0IGdyaWQgPSB0aGlzLm9wdGlvbnMuZ3JpZDtcbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuX2dyaWRMaW5lSXRlbXMgfHwgKHRoaXMuX2dyaWRMaW5lSXRlbXMgPSB0aGlzLl9jb21wdXRlR3JpZExpbmVJdGVtcyhjaGFydEFyZWEpKTtcbiAgICBsZXQgaSwgaWxlbjtcblxuICAgIGNvbnN0IGRyYXdMaW5lID0gKHAxLCBwMiwgc3R5bGUpID0+IHtcbiAgICAgIGlmICghc3R5bGUud2lkdGggfHwgIXN0eWxlLmNvbG9yKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICBjdHgubGluZVdpZHRoID0gc3R5bGUud2lkdGg7XG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSBzdHlsZS5jb2xvcjtcbiAgICAgIGN0eC5zZXRMaW5lRGFzaChzdHlsZS5ib3JkZXJEYXNoIHx8IFtdKTtcbiAgICAgIGN0eC5saW5lRGFzaE9mZnNldCA9IHN0eWxlLmJvcmRlckRhc2hPZmZzZXQ7XG5cbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGN0eC5tb3ZlVG8ocDEueCwgcDEueSk7XG4gICAgICBjdHgubGluZVRvKHAyLngsIHAyLnkpO1xuICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9O1xuXG4gICAgaWYgKGdyaWQuZGlzcGxheSkge1xuICAgICAgZm9yIChpID0gMCwgaWxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgICBjb25zdCBpdGVtID0gaXRlbXNbaV07XG5cbiAgICAgICAgaWYgKGdyaWQuZHJhd09uQ2hhcnRBcmVhKSB7XG4gICAgICAgICAgZHJhd0xpbmUoXG4gICAgICAgICAgICB7eDogaXRlbS54MSwgeTogaXRlbS55MX0sXG4gICAgICAgICAgICB7eDogaXRlbS54MiwgeTogaXRlbS55Mn0sXG4gICAgICAgICAgICBpdGVtXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChncmlkLmRyYXdUaWNrcykge1xuICAgICAgICAgIGRyYXdMaW5lKFxuICAgICAgICAgICAge3g6IGl0ZW0udHgxLCB5OiBpdGVtLnR5MX0sXG4gICAgICAgICAgICB7eDogaXRlbS50eDIsIHk6IGl0ZW0udHkyfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY29sb3I6IGl0ZW0udGlja0NvbG9yLFxuICAgICAgICAgICAgICB3aWR0aDogaXRlbS50aWNrV2lkdGgsXG4gICAgICAgICAgICAgIGJvcmRlckRhc2g6IGl0ZW0udGlja0JvcmRlckRhc2gsXG4gICAgICAgICAgICAgIGJvcmRlckRhc2hPZmZzZXQ6IGl0ZW0udGlja0JvcmRlckRhc2hPZmZzZXRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGRyYXdCb3JkZXIoKSB7XG4gICAgY29uc3Qge2NoYXJ0LCBjdHgsIG9wdGlvbnM6IHtib3JkZXIsIGdyaWR9fSA9IHRoaXM7XG4gICAgY29uc3QgYm9yZGVyT3B0cyA9IGJvcmRlci5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICBjb25zdCBheGlzV2lkdGggPSBib3JkZXIuZGlzcGxheSA/IGJvcmRlck9wdHMud2lkdGggOiAwO1xuICAgIGlmICghYXhpc1dpZHRoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxhc3RMaW5lV2lkdGggPSBncmlkLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KDApKS5saW5lV2lkdGg7XG4gICAgY29uc3QgYm9yZGVyVmFsdWUgPSB0aGlzLl9ib3JkZXJWYWx1ZTtcbiAgICBsZXQgeDEsIHgyLCB5MSwgeTI7XG5cbiAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgeDEgPSBfYWxpZ25QaXhlbChjaGFydCwgdGhpcy5sZWZ0LCBheGlzV2lkdGgpIC0gYXhpc1dpZHRoIC8gMjtcbiAgICAgIHgyID0gX2FsaWduUGl4ZWwoY2hhcnQsIHRoaXMucmlnaHQsIGxhc3RMaW5lV2lkdGgpICsgbGFzdExpbmVXaWR0aCAvIDI7XG4gICAgICB5MSA9IHkyID0gYm9yZGVyVmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHkxID0gX2FsaWduUGl4ZWwoY2hhcnQsIHRoaXMudG9wLCBheGlzV2lkdGgpIC0gYXhpc1dpZHRoIC8gMjtcbiAgICAgIHkyID0gX2FsaWduUGl4ZWwoY2hhcnQsIHRoaXMuYm90dG9tLCBsYXN0TGluZVdpZHRoKSArIGxhc3RMaW5lV2lkdGggLyAyO1xuICAgICAgeDEgPSB4MiA9IGJvcmRlclZhbHVlO1xuICAgIH1cbiAgICBjdHguc2F2ZSgpO1xuICAgIGN0eC5saW5lV2lkdGggPSBib3JkZXJPcHRzLndpZHRoO1xuICAgIGN0eC5zdHJva2VTdHlsZSA9IGJvcmRlck9wdHMuY29sb3I7XG5cbiAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgY3R4Lm1vdmVUbyh4MSwgeTEpO1xuICAgIGN0eC5saW5lVG8oeDIsIHkyKTtcbiAgICBjdHguc3Ryb2tlKCk7XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGRyYXdMYWJlbHMoY2hhcnRBcmVhKSB7XG4gICAgY29uc3Qgb3B0aW9uVGlja3MgPSB0aGlzLm9wdGlvbnMudGlja3M7XG5cbiAgICBpZiAoIW9wdGlvblRpY2tzLmRpc3BsYXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdHggPSB0aGlzLmN0eDtcblxuICAgIGNvbnN0IGFyZWEgPSB0aGlzLl9jb21wdXRlTGFiZWxBcmVhKCk7XG4gICAgaWYgKGFyZWEpIHtcbiAgICAgIGNsaXBBcmVhKGN0eCwgYXJlYSk7XG4gICAgfVxuXG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLmdldExhYmVsSXRlbXMoY2hhcnRBcmVhKTtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgIGNvbnN0IHJlbmRlclRleHRPcHRpb25zID0gaXRlbS5vcHRpb25zO1xuICAgICAgY29uc3QgdGlja0ZvbnQgPSBpdGVtLmZvbnQ7XG4gICAgICBjb25zdCBsYWJlbCA9IGl0ZW0ubGFiZWw7XG4gICAgICBjb25zdCB5ID0gaXRlbS50ZXh0T2Zmc2V0O1xuICAgICAgcmVuZGVyVGV4dChjdHgsIGxhYmVsLCAwLCB5LCB0aWNrRm9udCwgcmVuZGVyVGV4dE9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmIChhcmVhKSB7XG4gICAgICB1bmNsaXBBcmVhKGN0eCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGRyYXdUaXRsZSgpIHtcbiAgICBjb25zdCB7Y3R4LCBvcHRpb25zOiB7cG9zaXRpb24sIHRpdGxlLCByZXZlcnNlfX0gPSB0aGlzO1xuXG4gICAgaWYgKCF0aXRsZS5kaXNwbGF5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZm9udCA9IHRvRm9udCh0aXRsZS5mb250KTtcbiAgICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKHRpdGxlLnBhZGRpbmcpO1xuICAgIGNvbnN0IGFsaWduID0gdGl0bGUuYWxpZ247XG4gICAgbGV0IG9mZnNldCA9IGZvbnQubGluZUhlaWdodCAvIDI7XG5cbiAgICBpZiAocG9zaXRpb24gPT09ICdib3R0b20nIHx8IHBvc2l0aW9uID09PSAnY2VudGVyJyB8fCBpc09iamVjdChwb3NpdGlvbikpIHtcbiAgICAgIG9mZnNldCArPSBwYWRkaW5nLmJvdHRvbTtcbiAgICAgIGlmIChpc0FycmF5KHRpdGxlLnRleHQpKSB7XG4gICAgICAgIG9mZnNldCArPSBmb250LmxpbmVIZWlnaHQgKiAodGl0bGUudGV4dC5sZW5ndGggLSAxKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgb2Zmc2V0ICs9IHBhZGRpbmcudG9wO1xuICAgIH1cblxuICAgIGNvbnN0IHt0aXRsZVgsIHRpdGxlWSwgbWF4V2lkdGgsIHJvdGF0aW9ufSA9IHRpdGxlQXJncyh0aGlzLCBvZmZzZXQsIHBvc2l0aW9uLCBhbGlnbik7XG5cbiAgICByZW5kZXJUZXh0KGN0eCwgdGl0bGUudGV4dCwgMCwgMCwgZm9udCwge1xuICAgICAgY29sb3I6IHRpdGxlLmNvbG9yLFxuICAgICAgbWF4V2lkdGgsXG4gICAgICByb3RhdGlvbixcbiAgICAgIHRleHRBbGlnbjogdGl0bGVBbGlnbihhbGlnbiwgcG9zaXRpb24sIHJldmVyc2UpLFxuICAgICAgdGV4dEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgIHRyYW5zbGF0aW9uOiBbdGl0bGVYLCB0aXRsZVldLFxuICAgIH0pO1xuICB9XG5cbiAgZHJhdyhjaGFydEFyZWEpIHtcbiAgICBpZiAoIXRoaXMuX2lzVmlzaWJsZSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kcmF3QmFja2dyb3VuZCgpO1xuICAgIHRoaXMuZHJhd0dyaWQoY2hhcnRBcmVhKTtcbiAgICB0aGlzLmRyYXdCb3JkZXIoKTtcbiAgICB0aGlzLmRyYXdUaXRsZSgpO1xuICAgIHRoaXMuZHJhd0xhYmVscyhjaGFydEFyZWEpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEByZXR1cm4ge29iamVjdFtdfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2xheWVycygpIHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHR6ID0gb3B0cy50aWNrcyAmJiBvcHRzLnRpY2tzLnogfHwgMDtcbiAgICBjb25zdCBneiA9IHZhbHVlT3JEZWZhdWx0KG9wdHMuZ3JpZCAmJiBvcHRzLmdyaWQueiwgLTEpO1xuICAgIGNvbnN0IGJ6ID0gdmFsdWVPckRlZmF1bHQob3B0cy5ib3JkZXIgJiYgb3B0cy5ib3JkZXIueiwgMCk7XG5cbiAgICBpZiAoIXRoaXMuX2lzVmlzaWJsZSgpIHx8IHRoaXMuZHJhdyAhPT0gU2NhbGUucHJvdG90eXBlLmRyYXcpIHtcbiAgICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHk6IGRyYXcgaGFzIGJlZW4gb3ZlcnJpZGRlbiBieSBjdXN0b20gc2NhbGVcbiAgICAgIHJldHVybiBbe1xuICAgICAgICB6OiB0eixcbiAgICAgICAgZHJhdzogKGNoYXJ0QXJlYSkgPT4ge1xuICAgICAgICAgIHRoaXMuZHJhdyhjaGFydEFyZWEpO1xuICAgICAgICB9XG4gICAgICB9XTtcbiAgICB9XG5cbiAgICByZXR1cm4gW3tcbiAgICAgIHo6IGd6LFxuICAgICAgZHJhdzogKGNoYXJ0QXJlYSkgPT4ge1xuICAgICAgICB0aGlzLmRyYXdCYWNrZ3JvdW5kKCk7XG4gICAgICAgIHRoaXMuZHJhd0dyaWQoY2hhcnRBcmVhKTtcbiAgICAgICAgdGhpcy5kcmF3VGl0bGUoKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICB6OiBieixcbiAgICAgIGRyYXc6ICgpID0+IHtcbiAgICAgICAgdGhpcy5kcmF3Qm9yZGVyKCk7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAgejogdHosXG4gICAgICBkcmF3OiAoY2hhcnRBcmVhKSA9PiB7XG4gICAgICAgIHRoaXMuZHJhd0xhYmVscyhjaGFydEFyZWEpO1xuICAgICAgfVxuICAgIH1dO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJldHVybnMgdmlzaWJsZSBkYXRhc2V0IG1ldGFzIHRoYXQgYXJlIGF0dGFjaGVkIHRvIHRoaXMgc2NhbGVcblx0ICogQHBhcmFtIHtzdHJpbmd9IFt0eXBlXSAtIGlmIHNwZWNpZmllZCwgYWxzbyBmaWx0ZXIgYnkgZGF0YXNldCB0eXBlXG5cdCAqIEByZXR1cm4ge29iamVjdFtdfVxuXHQgKi9cbiAgZ2V0TWF0Y2hpbmdWaXNpYmxlTWV0YXModHlwZSkge1xuICAgIGNvbnN0IG1ldGFzID0gdGhpcy5jaGFydC5nZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCk7XG4gICAgY29uc3QgYXhpc0lEID0gdGhpcy5heGlzICsgJ0F4aXNJRCc7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgbGV0IGksIGlsZW47XG5cbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gbWV0YXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBjb25zdCBtZXRhID0gbWV0YXNbaV07XG4gICAgICBpZiAobWV0YVtheGlzSURdID09PSB0aGlzLmlkICYmICghdHlwZSB8fCBtZXRhLnR5cGUgPT09IHR5cGUpKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKG1ldGEpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuXHQgKiBAcmV0dXJuIHtvYmplY3R9XG5cdCAqIEBwcm90ZWN0ZWRcbiBcdCAqL1xuICBfcmVzb2x2ZVRpY2tGb250T3B0aW9ucyhpbmRleCkge1xuICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnMudGlja3Muc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoaW5kZXgpKTtcbiAgICByZXR1cm4gdG9Gb250KG9wdHMuZm9udCk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgX21heERpZ2l0cygpIHtcbiAgICBjb25zdCBmb250U2l6ZSA9IHRoaXMuX3Jlc29sdmVUaWNrRm9udE9wdGlvbnMoMCkubGluZUhlaWdodDtcbiAgICByZXR1cm4gKHRoaXMuaXNIb3Jpem9udGFsKCkgPyB0aGlzLndpZHRoIDogdGhpcy5oZWlnaHQpIC8gZm9udFNpemU7XG4gIH1cbn1cbiIsICJpbXBvcnQge21lcmdlfSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcbmltcG9ydCBkZWZhdWx0cywge292ZXJyaWRlc30gZnJvbSAnLi9jb3JlLmRlZmF1bHRzLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7e2lkOiBzdHJpbmcsIGRlZmF1bHRzOiBhbnksIG92ZXJyaWRlcz86IGFueSwgZGVmYXVsdFJvdXRlczogYW55fX0gSUNoYXJ0Q29tcG9uZW50XG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVHlwZWRSZWdpc3RyeSB7XG4gIGNvbnN0cnVjdG9yKHR5cGUsIHNjb3BlLCBvdmVycmlkZSkge1xuICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgdGhpcy5zY29wZSA9IHNjb3BlO1xuICAgIHRoaXMub3ZlcnJpZGUgPSBvdmVycmlkZTtcbiAgICB0aGlzLml0ZW1zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgfVxuXG4gIGlzRm9yVHlwZSh0eXBlKSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaXNQcm90b3R5cGVPZi5jYWxsKHRoaXMudHlwZS5wcm90b3R5cGUsIHR5cGUucHJvdG90eXBlKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge0lDaGFydENvbXBvbmVudH0gaXRlbVxuXHQgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgc2NvcGUgd2hlcmUgaXRlbXMgZGVmYXVsdHMgd2VyZSByZWdpc3RlcmVkIHRvLlxuXHQgKi9cbiAgcmVnaXN0ZXIoaXRlbSkge1xuICAgIGNvbnN0IHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGl0ZW0pO1xuICAgIGxldCBwYXJlbnRTY29wZTtcblxuICAgIGlmIChpc0lDaGFydENvbXBvbmVudChwcm90bykpIHtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgcGFyZW50IGlzIHJlZ2lzdGVyZWQgYW5kIG5vdGUgdGhlIHNjb3BlIHdoZXJlIGl0cyBkZWZhdWx0cyBhcmUuXG4gICAgICBwYXJlbnRTY29wZSA9IHRoaXMucmVnaXN0ZXIocHJvdG8pO1xuICAgIH1cblxuICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5pdGVtcztcbiAgICBjb25zdCBpZCA9IGl0ZW0uaWQ7XG4gICAgY29uc3Qgc2NvcGUgPSB0aGlzLnNjb3BlICsgJy4nICsgaWQ7XG5cbiAgICBpZiAoIWlkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsYXNzIGRvZXMgbm90IGhhdmUgaWQ6ICcgKyBpdGVtKTtcbiAgICB9XG5cbiAgICBpZiAoaWQgaW4gaXRlbXMpIHtcbiAgICAgIC8vIGFscmVhZHkgcmVnaXN0ZXJlZFxuICAgICAgcmV0dXJuIHNjb3BlO1xuICAgIH1cblxuICAgIGl0ZW1zW2lkXSA9IGl0ZW07XG4gICAgcmVnaXN0ZXJEZWZhdWx0cyhpdGVtLCBzY29wZSwgcGFyZW50U2NvcGUpO1xuICAgIGlmICh0aGlzLm92ZXJyaWRlKSB7XG4gICAgICBkZWZhdWx0cy5vdmVycmlkZShpdGVtLmlkLCBpdGVtLm92ZXJyaWRlcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNjb3BlO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuXHQgKiBAcmV0dXJucyB7b2JqZWN0P31cblx0ICovXG4gIGdldChpZCkge1xuICAgIHJldHVybiB0aGlzLml0ZW1zW2lkXTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge0lDaGFydENvbXBvbmVudH0gaXRlbVxuXHQgKi9cbiAgdW5yZWdpc3RlcihpdGVtKSB7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zO1xuICAgIGNvbnN0IGlkID0gaXRlbS5pZDtcbiAgICBjb25zdCBzY29wZSA9IHRoaXMuc2NvcGU7XG5cbiAgICBpZiAoaWQgaW4gaXRlbXMpIHtcbiAgICAgIGRlbGV0ZSBpdGVtc1tpZF07XG4gICAgfVxuXG4gICAgaWYgKHNjb3BlICYmIGlkIGluIGRlZmF1bHRzW3Njb3BlXSkge1xuICAgICAgZGVsZXRlIGRlZmF1bHRzW3Njb3BlXVtpZF07XG4gICAgICBpZiAodGhpcy5vdmVycmlkZSkge1xuICAgICAgICBkZWxldGUgb3ZlcnJpZGVzW2lkXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJEZWZhdWx0cyhpdGVtLCBzY29wZSwgcGFyZW50U2NvcGUpIHtcbiAgLy8gSW5oZXJpdCB0aGUgcGFyZW50J3MgZGVmYXVsdHMgYW5kIGtlZXAgZXhpc3RpbmcgZGVmYXVsdHNcbiAgY29uc3QgaXRlbURlZmF1bHRzID0gbWVyZ2UoT2JqZWN0LmNyZWF0ZShudWxsKSwgW1xuICAgIHBhcmVudFNjb3BlID8gZGVmYXVsdHMuZ2V0KHBhcmVudFNjb3BlKSA6IHt9LFxuICAgIGRlZmF1bHRzLmdldChzY29wZSksXG4gICAgaXRlbS5kZWZhdWx0c1xuICBdKTtcblxuICBkZWZhdWx0cy5zZXQoc2NvcGUsIGl0ZW1EZWZhdWx0cyk7XG5cbiAgaWYgKGl0ZW0uZGVmYXVsdFJvdXRlcykge1xuICAgIHJvdXRlRGVmYXVsdHMoc2NvcGUsIGl0ZW0uZGVmYXVsdFJvdXRlcyk7XG4gIH1cblxuICBpZiAoaXRlbS5kZXNjcmlwdG9ycykge1xuICAgIGRlZmF1bHRzLmRlc2NyaWJlKHNjb3BlLCBpdGVtLmRlc2NyaXB0b3JzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByb3V0ZURlZmF1bHRzKHNjb3BlLCByb3V0ZXMpIHtcbiAgT2JqZWN0LmtleXMocm91dGVzKS5mb3JFYWNoKHByb3BlcnR5ID0+IHtcbiAgICBjb25zdCBwcm9wZXJ0eVBhcnRzID0gcHJvcGVydHkuc3BsaXQoJy4nKTtcbiAgICBjb25zdCBzb3VyY2VOYW1lID0gcHJvcGVydHlQYXJ0cy5wb3AoKTtcbiAgICBjb25zdCBzb3VyY2VTY29wZSA9IFtzY29wZV0uY29uY2F0KHByb3BlcnR5UGFydHMpLmpvaW4oJy4nKTtcbiAgICBjb25zdCBwYXJ0cyA9IHJvdXRlc1twcm9wZXJ0eV0uc3BsaXQoJy4nKTtcbiAgICBjb25zdCB0YXJnZXROYW1lID0gcGFydHMucG9wKCk7XG4gICAgY29uc3QgdGFyZ2V0U2NvcGUgPSBwYXJ0cy5qb2luKCcuJyk7XG4gICAgZGVmYXVsdHMucm91dGUoc291cmNlU2NvcGUsIHNvdXJjZU5hbWUsIHRhcmdldFNjb3BlLCB0YXJnZXROYW1lKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzSUNoYXJ0Q29tcG9uZW50KHByb3RvKSB7XG4gIHJldHVybiAnaWQnIGluIHByb3RvICYmICdkZWZhdWx0cycgaW4gcHJvdG87XG59XG4iLCAiaW1wb3J0IERhdGFzZXRDb250cm9sbGVyIGZyb20gJy4vY29yZS5kYXRhc2V0Q29udHJvbGxlci5qcyc7XG5pbXBvcnQgRWxlbWVudCBmcm9tICcuL2NvcmUuZWxlbWVudC5qcyc7XG5pbXBvcnQgU2NhbGUgZnJvbSAnLi9jb3JlLnNjYWxlLmpzJztcbmltcG9ydCBUeXBlZFJlZ2lzdHJ5IGZyb20gJy4vY29yZS50eXBlZFJlZ2lzdHJ5LmpzJztcbmltcG9ydCB7ZWFjaCwgY2FsbGJhY2sgYXMgY2FsbCwgX2NhcGl0YWxpemV9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcblxuLyoqXG4gKiBQbGVhc2UgdXNlIHRoZSBtb2R1bGUncyBkZWZhdWx0IGV4cG9ydCB3aGljaCBwcm92aWRlcyBhIHNpbmdsZXRvbiBpbnN0YW5jZVxuICogTm90ZTogY2xhc3MgaXMgZXhwb3J0ZWQgZm9yIHR5cGVkb2NcbiAqL1xuZXhwb3J0IGNsYXNzIFJlZ2lzdHJ5IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5jb250cm9sbGVycyA9IG5ldyBUeXBlZFJlZ2lzdHJ5KERhdGFzZXRDb250cm9sbGVyLCAnZGF0YXNldHMnLCB0cnVlKTtcbiAgICB0aGlzLmVsZW1lbnRzID0gbmV3IFR5cGVkUmVnaXN0cnkoRWxlbWVudCwgJ2VsZW1lbnRzJyk7XG4gICAgdGhpcy5wbHVnaW5zID0gbmV3IFR5cGVkUmVnaXN0cnkoT2JqZWN0LCAncGx1Z2lucycpO1xuICAgIHRoaXMuc2NhbGVzID0gbmV3IFR5cGVkUmVnaXN0cnkoU2NhbGUsICdzY2FsZXMnKTtcbiAgICAvLyBPcmRlciBpcyBpbXBvcnRhbnQsIFNjYWxlIGhhcyBFbGVtZW50IGluIHByb3RvdHlwZSBjaGFpbixcbiAgICAvLyBzbyBTY2FsZXMgbXVzdCBiZSBiZWZvcmUgRWxlbWVudHMuIFBsdWdpbnMgYXJlIGEgZmFsbGJhY2ssIHNvIG5vdCBsaXN0ZWQgaGVyZS5cbiAgICB0aGlzLl90eXBlZFJlZ2lzdHJpZXMgPSBbdGhpcy5jb250cm9sbGVycywgdGhpcy5zY2FsZXMsIHRoaXMuZWxlbWVudHNdO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSAgey4uLmFueX0gYXJnc1xuXHQgKi9cbiAgYWRkKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9lYWNoKCdyZWdpc3RlcicsIGFyZ3MpO1xuICB9XG5cbiAgcmVtb3ZlKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9lYWNoKCd1bnJlZ2lzdGVyJywgYXJncyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtICB7Li4udHlwZW9mIERhdGFzZXRDb250cm9sbGVyfSBhcmdzXG5cdCAqL1xuICBhZGRDb250cm9sbGVycyguLi5hcmdzKSB7XG4gICAgdGhpcy5fZWFjaCgncmVnaXN0ZXInLCBhcmdzLCB0aGlzLmNvbnRyb2xsZXJzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0gIHsuLi50eXBlb2YgRWxlbWVudH0gYXJnc1xuXHQgKi9cbiAgYWRkRWxlbWVudHMoLi4uYXJncykge1xuICAgIHRoaXMuX2VhY2goJ3JlZ2lzdGVyJywgYXJncywgdGhpcy5lbGVtZW50cyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtICB7Li4uYW55fSBhcmdzXG5cdCAqL1xuICBhZGRQbHVnaW5zKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9lYWNoKCdyZWdpc3RlcicsIGFyZ3MsIHRoaXMucGx1Z2lucyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtICB7Li4udHlwZW9mIFNjYWxlfSBhcmdzXG5cdCAqL1xuICBhZGRTY2FsZXMoLi4uYXJncykge1xuICAgIHRoaXMuX2VhY2goJ3JlZ2lzdGVyJywgYXJncywgdGhpcy5zY2FsZXMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuXHQgKiBAcmV0dXJucyB7dHlwZW9mIERhdGFzZXRDb250cm9sbGVyfVxuXHQgKi9cbiAgZ2V0Q29udHJvbGxlcihpZCkge1xuICAgIHJldHVybiB0aGlzLl9nZXQoaWQsIHRoaXMuY29udHJvbGxlcnMsICdjb250cm9sbGVyJyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IGlkXG5cdCAqIEByZXR1cm5zIHt0eXBlb2YgRWxlbWVudH1cblx0ICovXG4gIGdldEVsZW1lbnQoaWQpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0KGlkLCB0aGlzLmVsZW1lbnRzLCAnZWxlbWVudCcpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fVxuXHQgKi9cbiAgZ2V0UGx1Z2luKGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldChpZCwgdGhpcy5wbHVnaW5zLCAncGx1Z2luJyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IGlkXG5cdCAqIEByZXR1cm5zIHt0eXBlb2YgU2NhbGV9XG5cdCAqL1xuICBnZXRTY2FsZShpZCkge1xuICAgIHJldHVybiB0aGlzLl9nZXQoaWQsIHRoaXMuc2NhbGVzLCAnc2NhbGUnKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0gIHsuLi50eXBlb2YgRGF0YXNldENvbnRyb2xsZXJ9IGFyZ3Ncblx0ICovXG4gIHJlbW92ZUNvbnRyb2xsZXJzKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9lYWNoKCd1bnJlZ2lzdGVyJywgYXJncywgdGhpcy5jb250cm9sbGVycyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtICB7Li4udHlwZW9mIEVsZW1lbnR9IGFyZ3Ncblx0ICovXG4gIHJlbW92ZUVsZW1lbnRzKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9lYWNoKCd1bnJlZ2lzdGVyJywgYXJncywgdGhpcy5lbGVtZW50cyk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtICB7Li4uYW55fSBhcmdzXG5cdCAqL1xuICByZW1vdmVQbHVnaW5zKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9lYWNoKCd1bnJlZ2lzdGVyJywgYXJncywgdGhpcy5wbHVnaW5zKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0gIHsuLi50eXBlb2YgU2NhbGV9IGFyZ3Ncblx0ICovXG4gIHJlbW92ZVNjYWxlcyguLi5hcmdzKSB7XG4gICAgdGhpcy5fZWFjaCgndW5yZWdpc3RlcicsIGFyZ3MsIHRoaXMuc2NhbGVzKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2VhY2gobWV0aG9kLCBhcmdzLCB0eXBlZFJlZ2lzdHJ5KSB7XG4gICAgWy4uLmFyZ3NdLmZvckVhY2goYXJnID0+IHtcbiAgICAgIGNvbnN0IHJlZyA9IHR5cGVkUmVnaXN0cnkgfHwgdGhpcy5fZ2V0UmVnaXN0cnlGb3JUeXBlKGFyZyk7XG4gICAgICBpZiAodHlwZWRSZWdpc3RyeSB8fCByZWcuaXNGb3JUeXBlKGFyZykgfHwgKHJlZyA9PT0gdGhpcy5wbHVnaW5zICYmIGFyZy5pZCkpIHtcbiAgICAgICAgdGhpcy5fZXhlYyhtZXRob2QsIHJlZywgYXJnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEhhbmRsZSBsb29wYWJsZSBhcmdzXG4gICAgICAgIC8vIFVzZSBjYXNlOlxuICAgICAgICAvLyAgaW1wb3J0ICogYXMgcGx1Z2lucyBmcm9tICcuL3BsdWdpbnMuanMnO1xuICAgICAgICAvLyAgQ2hhcnQucmVnaXN0ZXIocGx1Z2lucyk7XG4gICAgICAgIGVhY2goYXJnLCBpdGVtID0+IHtcbiAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbWl4ZWQgdHlwZXMgaW4gdGhlIGxvb3BhYmxlLCBtYWtlIHN1cmUgdGhvc2UgYXJlXG4gICAgICAgICAgLy8gcmVnaXN0ZXJlZCBpbiBjb3JyZWN0IHJlZ2lzdHJ5XG4gICAgICAgICAgLy8gVXNlIGNhc2U6ICh0cmVlbWFwIGV4cG9ydGluZyBjb250cm9sbGVyLCBlbGVtZW50cyBldGMpXG4gICAgICAgICAgLy8gIGltcG9ydCAqIGFzIHRyZWVtYXAgZnJvbSAnY2hhcnRqcy1jaGFydC10cmVlbWFwLmpzJztcbiAgICAgICAgICAvLyAgQ2hhcnQucmVnaXN0ZXIodHJlZW1hcCk7XG5cbiAgICAgICAgICBjb25zdCBpdGVtUmVnID0gdHlwZWRSZWdpc3RyeSB8fCB0aGlzLl9nZXRSZWdpc3RyeUZvclR5cGUoaXRlbSk7XG4gICAgICAgICAgdGhpcy5fZXhlYyhtZXRob2QsIGl0ZW1SZWcsIGl0ZW0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2V4ZWMobWV0aG9kLCByZWdpc3RyeSwgY29tcG9uZW50KSB7XG4gICAgY29uc3QgY2FtZWxNZXRob2QgPSBfY2FwaXRhbGl6ZShtZXRob2QpO1xuICAgIGNhbGwoY29tcG9uZW50WydiZWZvcmUnICsgY2FtZWxNZXRob2RdLCBbXSwgY29tcG9uZW50KTsgLy8gYmVmb3JlUmVnaXN0ZXIgLyBiZWZvcmVVbnJlZ2lzdGVyXG4gICAgcmVnaXN0cnlbbWV0aG9kXShjb21wb25lbnQpO1xuICAgIGNhbGwoY29tcG9uZW50WydhZnRlcicgKyBjYW1lbE1ldGhvZF0sIFtdLCBjb21wb25lbnQpOyAvLyBhZnRlclJlZ2lzdGVyIC8gYWZ0ZXJVbnJlZ2lzdGVyXG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRSZWdpc3RyeUZvclR5cGUodHlwZSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fdHlwZWRSZWdpc3RyaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByZWcgPSB0aGlzLl90eXBlZFJlZ2lzdHJpZXNbaV07XG4gICAgICBpZiAocmVnLmlzRm9yVHlwZSh0eXBlKSkge1xuICAgICAgICByZXR1cm4gcmVnO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBwbHVnaW5zIGlzIHRoZSBmYWxsYmFjayByZWdpc3RyeVxuICAgIHJldHVybiB0aGlzLnBsdWdpbnM7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXQoaWQsIHR5cGVkUmVnaXN0cnksIHR5cGUpIHtcbiAgICBjb25zdCBpdGVtID0gdHlwZWRSZWdpc3RyeS5nZXQoaWQpO1xuICAgIGlmIChpdGVtID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignXCInICsgaWQgKyAnXCIgaXMgbm90IGEgcmVnaXN0ZXJlZCAnICsgdHlwZSArICcuJyk7XG4gICAgfVxuICAgIHJldHVybiBpdGVtO1xuICB9XG5cbn1cblxuLy8gc2luZ2xldG9uIGluc3RhbmNlXG5leHBvcnQgZGVmYXVsdCAvKiAjX19QVVJFX18gKi8gbmV3IFJlZ2lzdHJ5KCk7XG4iLCAiaW1wb3J0IHJlZ2lzdHJ5IGZyb20gJy4vY29yZS5yZWdpc3RyeS5qcyc7XG5pbXBvcnQge2NhbGxiYWNrIGFzIGNhbGxDYWxsYmFjaywgaXNOdWxsT3JVbmRlZiwgdmFsdWVPckRlZmF1bHR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi9jb3JlLmNvbnRyb2xsZXIuanMnKS5kZWZhdWx0IH0gQ2hhcnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi90eXBlcy9pbmRleC5qcycpLkNoYXJ0RXZlbnQgfSBDaGFydEV2ZW50XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vcGx1Z2lucy9wbHVnaW4udG9vbHRpcC5qcycpLmRlZmF1bHQgfSBUb29sdGlwXG4gKi9cblxuLyoqXG4gKiBAY2FsbGJhY2sgZmlsdGVyQ2FsbGJhY2tcbiAqIEBwYXJhbSB7e3BsdWdpbjogb2JqZWN0LCBvcHRpb25zOiBvYmplY3R9fSB2YWx1ZVxuICogQHBhcmFtIHtudW1iZXJ9IFtpbmRleF1cbiAqIEBwYXJhbSB7YXJyYXl9IFthcnJheV1cbiAqIEBwYXJhbSB7b2JqZWN0fSBbdGhpc0FyZ11cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cblxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQbHVnaW5TZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5faW5pdCA9IFtdO1xuICB9XG5cbiAgLyoqXG5cdCAqIENhbGxzIGVuYWJsZWQgcGx1Z2lucyBmb3IgYGNoYXJ0YCBvbiB0aGUgc3BlY2lmaWVkIGhvb2sgYW5kIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG5cdCAqIFRoaXMgbWV0aG9kIGltbWVkaWF0ZWx5IHJldHVybnMgYXMgc29vbiBhcyBhIHBsdWdpbiBleHBsaWNpdGx5IHJldHVybnMgZmFsc2UuIFRoZVxuXHQgKiByZXR1cm5lZCB2YWx1ZSBjYW4gYmUgdXNlZCwgZm9yIGluc3RhbmNlLCB0byBpbnRlcnJ1cHQgdGhlIGN1cnJlbnQgYWN0aW9uLlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIFRoZSBjaGFydCBpbnN0YW5jZSBmb3Igd2hpY2ggcGx1Z2lucyBzaG91bGQgYmUgY2FsbGVkLlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaG9vayAtIFRoZSBuYW1lIG9mIHRoZSBwbHVnaW4gbWV0aG9kIHRvIGNhbGwgKGUuZy4gJ2JlZm9yZVVwZGF0ZScpLlxuXHQgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gRXh0cmEgYXJndW1lbnRzIHRvIGFwcGx5IHRvIHRoZSBob29rIGNhbGwuXG4gICAqIEBwYXJhbSB7ZmlsdGVyQ2FsbGJhY2t9IFtmaWx0ZXJdIC0gRmlsdGVyaW5nIGZ1bmN0aW9uIGZvciBsaW1pdGluZyB3aGljaCBwbHVnaW5zIGFyZSBub3RpZmllZFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gZmFsc2UgaWYgYW55IG9mIHRoZSBwbHVnaW5zIHJldHVybiBmYWxzZSwgZWxzZSByZXR1cm5zIHRydWUuXG5cdCAqL1xuICBub3RpZnkoY2hhcnQsIGhvb2ssIGFyZ3MsIGZpbHRlcikge1xuICAgIGlmIChob29rID09PSAnYmVmb3JlSW5pdCcpIHtcbiAgICAgIHRoaXMuX2luaXQgPSB0aGlzLl9jcmVhdGVEZXNjcmlwdG9ycyhjaGFydCwgdHJ1ZSk7XG4gICAgICB0aGlzLl9ub3RpZnkodGhpcy5faW5pdCwgY2hhcnQsICdpbnN0YWxsJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVzY3JpcHRvcnMgPSBmaWx0ZXIgPyB0aGlzLl9kZXNjcmlwdG9ycyhjaGFydCkuZmlsdGVyKGZpbHRlcikgOiB0aGlzLl9kZXNjcmlwdG9ycyhjaGFydCk7XG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fbm90aWZ5KGRlc2NyaXB0b3JzLCBjaGFydCwgaG9vaywgYXJncyk7XG5cbiAgICBpZiAoaG9vayA9PT0gJ2FmdGVyRGVzdHJveScpIHtcbiAgICAgIHRoaXMuX25vdGlmeShkZXNjcmlwdG9ycywgY2hhcnQsICdzdG9wJyk7XG4gICAgICB0aGlzLl9ub3RpZnkodGhpcy5faW5pdCwgY2hhcnQsICd1bmluc3RhbGwnKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX25vdGlmeShkZXNjcmlwdG9ycywgY2hhcnQsIGhvb2ssIGFyZ3MpIHtcbiAgICBhcmdzID0gYXJncyB8fCB7fTtcbiAgICBmb3IgKGNvbnN0IGRlc2NyaXB0b3Igb2YgZGVzY3JpcHRvcnMpIHtcbiAgICAgIGNvbnN0IHBsdWdpbiA9IGRlc2NyaXB0b3IucGx1Z2luO1xuICAgICAgY29uc3QgbWV0aG9kID0gcGx1Z2luW2hvb2tdO1xuICAgICAgY29uc3QgcGFyYW1zID0gW2NoYXJ0LCBhcmdzLCBkZXNjcmlwdG9yLm9wdGlvbnNdO1xuICAgICAgaWYgKGNhbGxDYWxsYmFjayhtZXRob2QsIHBhcmFtcywgcGx1Z2luKSA9PT0gZmFsc2UgJiYgYXJncy5jYW5jZWxhYmxlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGludmFsaWRhdGUoKSB7XG4gICAgLy8gV2hlbiBwbHVnaW5zIGFyZSByZWdpc3RlcmVkLCB0aGVyZSBpcyB0aGUgcG9zc2liaWxpdHkgb2YgYSBkb3VibGVcbiAgICAvLyBpbnZhbGlkYXRlIHNpdHVhdGlvbi4gSW4gdGhpcyBjYXNlLCB3ZSBvbmx5IHdhbnQgdG8gaW52YWxpZGF0ZSBvbmNlLlxuICAgIC8vIElmIHdlIGludmFsaWRhdGUgbXVsdGlwbGUgdGltZXMsIHRoZSBgX29sZENhY2hlYCBpcyBsb3N0IGFuZCBhbGwgb2YgdGhlXG4gICAgLy8gcGx1Z2lucyBhcmUgcmVzdGFydGVkIHdpdGhvdXQgYmVpbmcgY29ycmVjdGx5IHN0b3BwZWQuXG4gICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy84MTQ3XG4gICAgaWYgKCFpc051bGxPclVuZGVmKHRoaXMuX2NhY2hlKSkge1xuICAgICAgdGhpcy5fb2xkQ2FjaGUgPSB0aGlzLl9jYWNoZTtcbiAgICAgIHRoaXMuX2NhY2hlID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydFxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2Rlc2NyaXB0b3JzKGNoYXJ0KSB7XG4gICAgaWYgKHRoaXMuX2NhY2hlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGU7XG4gICAgfVxuXG4gICAgY29uc3QgZGVzY3JpcHRvcnMgPSB0aGlzLl9jYWNoZSA9IHRoaXMuX2NyZWF0ZURlc2NyaXB0b3JzKGNoYXJ0KTtcblxuICAgIHRoaXMuX25vdGlmeVN0YXRlQ2hhbmdlcyhjaGFydCk7XG5cbiAgICByZXR1cm4gZGVzY3JpcHRvcnM7XG4gIH1cblxuICBfY3JlYXRlRGVzY3JpcHRvcnMoY2hhcnQsIGFsbCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IGNoYXJ0ICYmIGNoYXJ0LmNvbmZpZztcbiAgICBjb25zdCBvcHRpb25zID0gdmFsdWVPckRlZmF1bHQoY29uZmlnLm9wdGlvbnMgJiYgY29uZmlnLm9wdGlvbnMucGx1Z2lucywge30pO1xuICAgIGNvbnN0IHBsdWdpbnMgPSBhbGxQbHVnaW5zKGNvbmZpZyk7XG4gICAgLy8gb3B0aW9ucyA9PT0gZmFsc2UgPT4gYWxsIHBsdWdpbnMgYXJlIGRpc2FibGVkXG4gICAgcmV0dXJuIG9wdGlvbnMgPT09IGZhbHNlICYmICFhbGwgPyBbXSA6IGNyZWF0ZURlc2NyaXB0b3JzKGNoYXJ0LCBwbHVnaW5zLCBvcHRpb25zLCBhbGwpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfbm90aWZ5U3RhdGVDaGFuZ2VzKGNoYXJ0KSB7XG4gICAgY29uc3QgcHJldmlvdXNEZXNjcmlwdG9ycyA9IHRoaXMuX29sZENhY2hlIHx8IFtdO1xuICAgIGNvbnN0IGRlc2NyaXB0b3JzID0gdGhpcy5fY2FjaGU7XG4gICAgY29uc3QgZGlmZiA9IChhLCBiKSA9PiBhLmZpbHRlcih4ID0+ICFiLnNvbWUoeSA9PiB4LnBsdWdpbi5pZCA9PT0geS5wbHVnaW4uaWQpKTtcbiAgICB0aGlzLl9ub3RpZnkoZGlmZihwcmV2aW91c0Rlc2NyaXB0b3JzLCBkZXNjcmlwdG9ycyksIGNoYXJ0LCAnc3RvcCcpO1xuICAgIHRoaXMuX25vdGlmeShkaWZmKGRlc2NyaXB0b3JzLCBwcmV2aW91c0Rlc2NyaXB0b3JzKSwgY2hhcnQsICdzdGFydCcpO1xuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoJy4vY29yZS5jb25maWcuanMnKS5kZWZhdWx0fSBjb25maWdcbiAqL1xuZnVuY3Rpb24gYWxsUGx1Z2lucyhjb25maWcpIHtcbiAgY29uc3QgbG9jYWxJZHMgPSB7fTtcbiAgY29uc3QgcGx1Z2lucyA9IFtdO1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocmVnaXN0cnkucGx1Z2lucy5pdGVtcyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHBsdWdpbnMucHVzaChyZWdpc3RyeS5nZXRQbHVnaW4oa2V5c1tpXSkpO1xuICB9XG5cbiAgY29uc3QgbG9jYWwgPSBjb25maWcucGx1Z2lucyB8fCBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsb2NhbC5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHBsdWdpbiA9IGxvY2FsW2ldO1xuXG4gICAgaWYgKHBsdWdpbnMuaW5kZXhPZihwbHVnaW4pID09PSAtMSkge1xuICAgICAgcGx1Z2lucy5wdXNoKHBsdWdpbik7XG4gICAgICBsb2NhbElkc1twbHVnaW4uaWRdID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge3BsdWdpbnMsIGxvY2FsSWRzfTtcbn1cblxuZnVuY3Rpb24gZ2V0T3B0cyhvcHRpb25zLCBhbGwpIHtcbiAgaWYgKCFhbGwgJiYgb3B0aW9ucyA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAob3B0aW9ucyA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVzY3JpcHRvcnMoY2hhcnQsIHtwbHVnaW5zLCBsb2NhbElkc30sIG9wdGlvbnMsIGFsbCkge1xuICBjb25zdCByZXN1bHQgPSBbXTtcbiAgY29uc3QgY29udGV4dCA9IGNoYXJ0LmdldENvbnRleHQoKTtcblxuICBmb3IgKGNvbnN0IHBsdWdpbiBvZiBwbHVnaW5zKSB7XG4gICAgY29uc3QgaWQgPSBwbHVnaW4uaWQ7XG4gICAgY29uc3Qgb3B0cyA9IGdldE9wdHMob3B0aW9uc1tpZF0sIGFsbCk7XG4gICAgaWYgKG9wdHMgPT09IG51bGwpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICByZXN1bHQucHVzaCh7XG4gICAgICBwbHVnaW4sXG4gICAgICBvcHRpb25zOiBwbHVnaW5PcHRzKGNoYXJ0LmNvbmZpZywge3BsdWdpbiwgbG9jYWw6IGxvY2FsSWRzW2lkXX0sIG9wdHMsIGNvbnRleHQpXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBwbHVnaW5PcHRzKGNvbmZpZywge3BsdWdpbiwgbG9jYWx9LCBvcHRzLCBjb250ZXh0KSB7XG4gIGNvbnN0IGtleXMgPSBjb25maWcucGx1Z2luU2NvcGVLZXlzKHBsdWdpbik7XG4gIGNvbnN0IHNjb3BlcyA9IGNvbmZpZy5nZXRPcHRpb25TY29wZXMob3B0cywga2V5cyk7XG4gIGlmIChsb2NhbCAmJiBwbHVnaW4uZGVmYXVsdHMpIHtcbiAgICAvLyBtYWtlIHN1cmUgcGx1Z2luIGRlZmF1bHRzIGFyZSBpbiBzY29wZXMgZm9yIGxvY2FsIChub3QgcmVnaXN0ZXJlZCkgcGx1Z2luc1xuICAgIHNjb3Blcy5wdXNoKHBsdWdpbi5kZWZhdWx0cyk7XG4gIH1cbiAgcmV0dXJuIGNvbmZpZy5jcmVhdGVSZXNvbHZlcihzY29wZXMsIGNvbnRleHQsIFsnJ10sIHtcbiAgICAvLyBUaGVzZSBhcmUganVzdCBkZWZhdWx0cyB0aGF0IHBsdWdpbnMgY2FuIG92ZXJyaWRlXG4gICAgc2NyaXB0YWJsZTogZmFsc2UsXG4gICAgaW5kZXhhYmxlOiBmYWxzZSxcbiAgICBhbGxLZXlzOiB0cnVlXG4gIH0pO1xufVxuIiwgImltcG9ydCBkZWZhdWx0cywge292ZXJyaWRlcywgZGVzY3JpcHRvcnN9IGZyb20gJy4vY29yZS5kZWZhdWx0cy5qcyc7XG5pbXBvcnQge21lcmdlSWYsIHJlc29sdmVPYmplY3RLZXksIGlzQXJyYXksIGlzRnVuY3Rpb24sIHZhbHVlT3JEZWZhdWx0LCBpc09iamVjdH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuaW1wb3J0IHtfYXR0YWNoQ29udGV4dCwgX2NyZWF0ZVJlc29sdmVyLCBfZGVzY3JpcHRvcnN9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb25maWcuanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5kZXhBeGlzKHR5cGUsIG9wdGlvbnMpIHtcbiAgY29uc3QgZGF0YXNldERlZmF1bHRzID0gZGVmYXVsdHMuZGF0YXNldHNbdHlwZV0gfHwge307XG4gIGNvbnN0IGRhdGFzZXRPcHRpb25zID0gKG9wdGlvbnMuZGF0YXNldHMgfHwge30pW3R5cGVdIHx8IHt9O1xuICByZXR1cm4gZGF0YXNldE9wdGlvbnMuaW5kZXhBeGlzIHx8IG9wdGlvbnMuaW5kZXhBeGlzIHx8IGRhdGFzZXREZWZhdWx0cy5pbmRleEF4aXMgfHwgJ3gnO1xufVxuXG5mdW5jdGlvbiBnZXRBeGlzRnJvbURlZmF1bHRTY2FsZUlEKGlkLCBpbmRleEF4aXMpIHtcbiAgbGV0IGF4aXMgPSBpZDtcbiAgaWYgKGlkID09PSAnX2luZGV4XycpIHtcbiAgICBheGlzID0gaW5kZXhBeGlzO1xuICB9IGVsc2UgaWYgKGlkID09PSAnX3ZhbHVlXycpIHtcbiAgICBheGlzID0gaW5kZXhBeGlzID09PSAneCcgPyAneScgOiAneCc7XG4gIH1cbiAgcmV0dXJuIGF4aXM7XG59XG5cbmZ1bmN0aW9uIGdldERlZmF1bHRTY2FsZUlERnJvbUF4aXMoYXhpcywgaW5kZXhBeGlzKSB7XG4gIHJldHVybiBheGlzID09PSBpbmRleEF4aXMgPyAnX2luZGV4XycgOiAnX3ZhbHVlXyc7XG59XG5cbmZ1bmN0aW9uIGlkTWF0Y2hlc0F4aXMoaWQpIHtcbiAgaWYgKGlkID09PSAneCcgfHwgaWQgPT09ICd5JyB8fCBpZCA9PT0gJ3InKSB7XG4gICAgcmV0dXJuIGlkO1xuICB9XG59XG5cbmZ1bmN0aW9uIGF4aXNGcm9tUG9zaXRpb24ocG9zaXRpb24pIHtcbiAgaWYgKHBvc2l0aW9uID09PSAndG9wJyB8fCBwb3NpdGlvbiA9PT0gJ2JvdHRvbScpIHtcbiAgICByZXR1cm4gJ3gnO1xuICB9XG4gIGlmIChwb3NpdGlvbiA9PT0gJ2xlZnQnIHx8IHBvc2l0aW9uID09PSAncmlnaHQnKSB7XG4gICAgcmV0dXJuICd5JztcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGV0ZXJtaW5lQXhpcyhpZCwgLi4uc2NhbGVPcHRpb25zKSB7XG4gIGlmIChpZE1hdGNoZXNBeGlzKGlkKSkge1xuICAgIHJldHVybiBpZDtcbiAgfVxuICBmb3IgKGNvbnN0IG9wdHMgb2Ygc2NhbGVPcHRpb25zKSB7XG4gICAgY29uc3QgYXhpcyA9IG9wdHMuYXhpc1xuICAgICAgfHwgYXhpc0Zyb21Qb3NpdGlvbihvcHRzLnBvc2l0aW9uKVxuICAgICAgfHwgaWQubGVuZ3RoID4gMSAmJiBpZE1hdGNoZXNBeGlzKGlkWzBdLnRvTG93ZXJDYXNlKCkpO1xuICAgIGlmIChheGlzKSB7XG4gICAgICByZXR1cm4gYXhpcztcbiAgICB9XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZGV0ZXJtaW5lIHR5cGUgb2YgJyR7aWR9JyBheGlzLiBQbGVhc2UgcHJvdmlkZSAnYXhpcycgb3IgJ3Bvc2l0aW9uJyBvcHRpb24uYCk7XG59XG5cbmZ1bmN0aW9uIGdldEF4aXNGcm9tRGF0YXNldChpZCwgYXhpcywgZGF0YXNldCkge1xuICBpZiAoZGF0YXNldFtheGlzICsgJ0F4aXNJRCddID09PSBpZCkge1xuICAgIHJldHVybiB7YXhpc307XG4gIH1cbn1cblxuZnVuY3Rpb24gcmV0cmlldmVBeGlzRnJvbURhdGFzZXRzKGlkLCBjb25maWcpIHtcbiAgaWYgKGNvbmZpZy5kYXRhICYmIGNvbmZpZy5kYXRhLmRhdGFzZXRzKSB7XG4gICAgY29uc3QgYm91bmREcyA9IGNvbmZpZy5kYXRhLmRhdGFzZXRzLmZpbHRlcigoZCkgPT4gZC54QXhpc0lEID09PSBpZCB8fCBkLnlBeGlzSUQgPT09IGlkKTtcbiAgICBpZiAoYm91bmREcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBnZXRBeGlzRnJvbURhdGFzZXQoaWQsICd4JywgYm91bmREc1swXSkgfHwgZ2V0QXhpc0Zyb21EYXRhc2V0KGlkLCAneScsIGJvdW5kRHNbMF0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge307XG59XG5cbmZ1bmN0aW9uIG1lcmdlU2NhbGVDb25maWcoY29uZmlnLCBvcHRpb25zKSB7XG4gIGNvbnN0IGNoYXJ0RGVmYXVsdHMgPSBvdmVycmlkZXNbY29uZmlnLnR5cGVdIHx8IHtzY2FsZXM6IHt9fTtcbiAgY29uc3QgY29uZmlnU2NhbGVzID0gb3B0aW9ucy5zY2FsZXMgfHwge307XG4gIGNvbnN0IGNoYXJ0SW5kZXhBeGlzID0gZ2V0SW5kZXhBeGlzKGNvbmZpZy50eXBlLCBvcHRpb25zKTtcbiAgY29uc3Qgc2NhbGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAvLyBGaXJzdCBmaWd1cmUgb3V0IGZpcnN0IHNjYWxlIGlkJ3MgcGVyIGF4aXMuXG4gIE9iamVjdC5rZXlzKGNvbmZpZ1NjYWxlcykuZm9yRWFjaChpZCA9PiB7XG4gICAgY29uc3Qgc2NhbGVDb25mID0gY29uZmlnU2NhbGVzW2lkXTtcbiAgICBpZiAoIWlzT2JqZWN0KHNjYWxlQ29uZikpIHtcbiAgICAgIHJldHVybiBjb25zb2xlLmVycm9yKGBJbnZhbGlkIHNjYWxlIGNvbmZpZ3VyYXRpb24gZm9yIHNjYWxlOiAke2lkfWApO1xuICAgIH1cbiAgICBpZiAoc2NhbGVDb25mLl9wcm94eSkge1xuICAgICAgcmV0dXJuIGNvbnNvbGUud2FybihgSWdub3JpbmcgcmVzb2x2ZXIgcGFzc2VkIGFzIG9wdGlvbnMgZm9yIHNjYWxlOiAke2lkfWApO1xuICAgIH1cbiAgICBjb25zdCBheGlzID0gZGV0ZXJtaW5lQXhpcyhpZCwgc2NhbGVDb25mLCByZXRyaWV2ZUF4aXNGcm9tRGF0YXNldHMoaWQsIGNvbmZpZyksIGRlZmF1bHRzLnNjYWxlc1tzY2FsZUNvbmYudHlwZV0pO1xuICAgIGNvbnN0IGRlZmF1bHRJZCA9IGdldERlZmF1bHRTY2FsZUlERnJvbUF4aXMoYXhpcywgY2hhcnRJbmRleEF4aXMpO1xuICAgIGNvbnN0IGRlZmF1bHRTY2FsZU9wdGlvbnMgPSBjaGFydERlZmF1bHRzLnNjYWxlcyB8fCB7fTtcbiAgICBzY2FsZXNbaWRdID0gbWVyZ2VJZihPYmplY3QuY3JlYXRlKG51bGwpLCBbe2F4aXN9LCBzY2FsZUNvbmYsIGRlZmF1bHRTY2FsZU9wdGlvbnNbYXhpc10sIGRlZmF1bHRTY2FsZU9wdGlvbnNbZGVmYXVsdElkXV0pO1xuICB9KTtcblxuICAvLyBUaGVuIG1lcmdlIGRhdGFzZXQgZGVmYXVsdHMgdG8gc2NhbGUgY29uZmlnc1xuICBjb25maWcuZGF0YS5kYXRhc2V0cy5mb3JFYWNoKGRhdGFzZXQgPT4ge1xuICAgIGNvbnN0IHR5cGUgPSBkYXRhc2V0LnR5cGUgfHwgY29uZmlnLnR5cGU7XG4gICAgY29uc3QgaW5kZXhBeGlzID0gZGF0YXNldC5pbmRleEF4aXMgfHwgZ2V0SW5kZXhBeGlzKHR5cGUsIG9wdGlvbnMpO1xuICAgIGNvbnN0IGRhdGFzZXREZWZhdWx0cyA9IG92ZXJyaWRlc1t0eXBlXSB8fCB7fTtcbiAgICBjb25zdCBkZWZhdWx0U2NhbGVPcHRpb25zID0gZGF0YXNldERlZmF1bHRzLnNjYWxlcyB8fCB7fTtcbiAgICBPYmplY3Qua2V5cyhkZWZhdWx0U2NhbGVPcHRpb25zKS5mb3JFYWNoKGRlZmF1bHRJRCA9PiB7XG4gICAgICBjb25zdCBheGlzID0gZ2V0QXhpc0Zyb21EZWZhdWx0U2NhbGVJRChkZWZhdWx0SUQsIGluZGV4QXhpcyk7XG4gICAgICBjb25zdCBpZCA9IGRhdGFzZXRbYXhpcyArICdBeGlzSUQnXSB8fCBheGlzO1xuICAgICAgc2NhbGVzW2lkXSA9IHNjYWxlc1tpZF0gfHwgT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgIG1lcmdlSWYoc2NhbGVzW2lkXSwgW3theGlzfSwgY29uZmlnU2NhbGVzW2lkXSwgZGVmYXVsdFNjYWxlT3B0aW9uc1tkZWZhdWx0SURdXSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIGFwcGx5IHNjYWxlIGRlZmF1bHRzLCBpZiBub3Qgb3ZlcnJpZGRlbiBieSBkYXRhc2V0IGRlZmF1bHRzXG4gIE9iamVjdC5rZXlzKHNjYWxlcykuZm9yRWFjaChrZXkgPT4ge1xuICAgIGNvbnN0IHNjYWxlID0gc2NhbGVzW2tleV07XG4gICAgbWVyZ2VJZihzY2FsZSwgW2RlZmF1bHRzLnNjYWxlc1tzY2FsZS50eXBlXSwgZGVmYXVsdHMuc2NhbGVdKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHNjYWxlcztcbn1cblxuZnVuY3Rpb24gaW5pdE9wdGlvbnMoY29uZmlnKSB7XG4gIGNvbnN0IG9wdGlvbnMgPSBjb25maWcub3B0aW9ucyB8fCAoY29uZmlnLm9wdGlvbnMgPSB7fSk7XG5cbiAgb3B0aW9ucy5wbHVnaW5zID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy5wbHVnaW5zLCB7fSk7XG4gIG9wdGlvbnMuc2NhbGVzID0gbWVyZ2VTY2FsZUNvbmZpZyhjb25maWcsIG9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBpbml0RGF0YShkYXRhKSB7XG4gIGRhdGEgPSBkYXRhIHx8IHt9O1xuICBkYXRhLmRhdGFzZXRzID0gZGF0YS5kYXRhc2V0cyB8fCBbXTtcbiAgZGF0YS5sYWJlbHMgPSBkYXRhLmxhYmVscyB8fCBbXTtcbiAgcmV0dXJuIGRhdGE7XG59XG5cbmZ1bmN0aW9uIGluaXRDb25maWcoY29uZmlnKSB7XG4gIGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcbiAgY29uZmlnLmRhdGEgPSBpbml0RGF0YShjb25maWcuZGF0YSk7XG5cbiAgaW5pdE9wdGlvbnMoY29uZmlnKTtcblxuICByZXR1cm4gY29uZmlnO1xufVxuXG5jb25zdCBrZXlDYWNoZSA9IG5ldyBNYXAoKTtcbmNvbnN0IGtleXNDYWNoZWQgPSBuZXcgU2V0KCk7XG5cbmZ1bmN0aW9uIGNhY2hlZEtleXMoY2FjaGVLZXksIGdlbmVyYXRlKSB7XG4gIGxldCBrZXlzID0ga2V5Q2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgaWYgKCFrZXlzKSB7XG4gICAga2V5cyA9IGdlbmVyYXRlKCk7XG4gICAga2V5Q2FjaGUuc2V0KGNhY2hlS2V5LCBrZXlzKTtcbiAgICBrZXlzQ2FjaGVkLmFkZChrZXlzKTtcbiAgfVxuICByZXR1cm4ga2V5cztcbn1cblxuY29uc3QgYWRkSWZGb3VuZCA9IChzZXQsIG9iaiwga2V5KSA9PiB7XG4gIGNvbnN0IG9wdHMgPSByZXNvbHZlT2JqZWN0S2V5KG9iaiwga2V5KTtcbiAgaWYgKG9wdHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHNldC5hZGQob3B0cyk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENvbmZpZyB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgIHRoaXMuX2NvbmZpZyA9IGluaXRDb25maWcoY29uZmlnKTtcbiAgICB0aGlzLl9zY29wZUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuX3Jlc29sdmVyQ2FjaGUgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBnZXQgcGxhdGZvcm0oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZy5wbGF0Zm9ybTtcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiB0aGlzLl9jb25maWcudHlwZTtcbiAgfVxuXG4gIHNldCB0eXBlKHR5cGUpIHtcbiAgICB0aGlzLl9jb25maWcudHlwZSA9IHR5cGU7XG4gIH1cblxuICBnZXQgZGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGE7XG4gIH1cblxuICBzZXQgZGF0YShkYXRhKSB7XG4gICAgdGhpcy5fY29uZmlnLmRhdGEgPSBpbml0RGF0YShkYXRhKTtcbiAgfVxuXG4gIGdldCBvcHRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLl9jb25maWcub3B0aW9ucztcbiAgfVxuXG4gIHNldCBvcHRpb25zKG9wdGlvbnMpIHtcbiAgICB0aGlzLl9jb25maWcub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICBnZXQgcGx1Z2lucygpIHtcbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLnBsdWdpbnM7XG4gIH1cblxuICB1cGRhdGUoKSB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5fY29uZmlnO1xuICAgIHRoaXMuY2xlYXJDYWNoZSgpO1xuICAgIGluaXRPcHRpb25zKGNvbmZpZyk7XG4gIH1cblxuICBjbGVhckNhY2hlKCkge1xuICAgIHRoaXMuX3Njb3BlQ2FjaGUuY2xlYXIoKTtcbiAgICB0aGlzLl9yZXNvbHZlckNhY2hlLmNsZWFyKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgb3B0aW9uIHNjb3BlIGtleXMgZm9yIHJlc29sdmluZyBkYXRhc2V0IG9wdGlvbnMuXG4gICAqIFRoZXNlIGtleXMgZG8gbm90IGluY2x1ZGUgdGhlIGRhdGFzZXQgaXRzZWxmLCBiZWNhdXNlIGl0IGlzIG5vdCB1bmRlciBvcHRpb25zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YXNldFR5cGVcbiAgICogQHJldHVybiB7c3RyaW5nW11bXX1cbiAgICovXG4gIGRhdGFzZXRTY29wZUtleXMoZGF0YXNldFR5cGUpIHtcbiAgICByZXR1cm4gY2FjaGVkS2V5cyhkYXRhc2V0VHlwZSxcbiAgICAgICgpID0+IFtbXG4gICAgICAgIGBkYXRhc2V0cy4ke2RhdGFzZXRUeXBlfWAsXG4gICAgICAgICcnXG4gICAgICBdXSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgb3B0aW9uIHNjb3BlIGtleXMgZm9yIHJlc29sdmluZyBkYXRhc2V0IGFuaW1hdGlvbiBvcHRpb25zLlxuICAgKiBUaGVzZSBrZXlzIGRvIG5vdCBpbmNsdWRlIHRoZSBkYXRhc2V0IGl0c2VsZiwgYmVjYXVzZSBpdCBpcyBub3QgdW5kZXIgb3B0aW9ucy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGFzZXRUeXBlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0cmFuc2l0aW9uXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdW119XG4gICAqL1xuICBkYXRhc2V0QW5pbWF0aW9uU2NvcGVLZXlzKGRhdGFzZXRUeXBlLCB0cmFuc2l0aW9uKSB7XG4gICAgcmV0dXJuIGNhY2hlZEtleXMoYCR7ZGF0YXNldFR5cGV9LnRyYW5zaXRpb24uJHt0cmFuc2l0aW9ufWAsXG4gICAgICAoKSA9PiBbXG4gICAgICAgIFtcbiAgICAgICAgICBgZGF0YXNldHMuJHtkYXRhc2V0VHlwZX0udHJhbnNpdGlvbnMuJHt0cmFuc2l0aW9ufWAsXG4gICAgICAgICAgYHRyYW5zaXRpb25zLiR7dHJhbnNpdGlvbn1gLFxuICAgICAgICBdLFxuICAgICAgICAvLyBUaGUgZm9sbG93aW5nIGFyZSB1c2VkIGZvciBsb29raW5nIHVwIHRoZSBgYW5pbWF0aW9uc2AgYW5kIGBhbmltYXRpb25gIGtleXNcbiAgICAgICAgW1xuICAgICAgICAgIGBkYXRhc2V0cy4ke2RhdGFzZXRUeXBlfWAsXG4gICAgICAgICAgJydcbiAgICAgICAgXVxuICAgICAgXSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgb3B0aW9ucyBzY29wZSBrZXlzIGZvciByZXNvbHZpbmcgZWxlbWVudCBvcHRpb25zIHRoYXQgYmVsb25nXG4gICAqIHRvIGFuIGRhdGFzZXQuIFRoZXNlIGtleXMgZG8gbm90IGluY2x1ZGUgdGhlIGRhdGFzZXQgaXRzZWxmLCBiZWNhdXNlIGl0XG4gICAqIGlzIG5vdCB1bmRlciBvcHRpb25zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YXNldFR5cGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGVsZW1lbnRUeXBlXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdW119XG4gICAqL1xuICBkYXRhc2V0RWxlbWVudFNjb3BlS2V5cyhkYXRhc2V0VHlwZSwgZWxlbWVudFR5cGUpIHtcbiAgICByZXR1cm4gY2FjaGVkS2V5cyhgJHtkYXRhc2V0VHlwZX0tJHtlbGVtZW50VHlwZX1gLFxuICAgICAgKCkgPT4gW1tcbiAgICAgICAgYGRhdGFzZXRzLiR7ZGF0YXNldFR5cGV9LmVsZW1lbnRzLiR7ZWxlbWVudFR5cGV9YCxcbiAgICAgICAgYGRhdGFzZXRzLiR7ZGF0YXNldFR5cGV9YCxcbiAgICAgICAgYGVsZW1lbnRzLiR7ZWxlbWVudFR5cGV9YCxcbiAgICAgICAgJydcbiAgICAgIF1dKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBvcHRpb25zIHNjb3BlIGtleXMgZm9yIHJlc29sdmluZyBwbHVnaW4gb3B0aW9ucy5cbiAgICogQHBhcmFtIHt7aWQ6IHN0cmluZywgYWRkaXRpb25hbE9wdGlvblNjb3Blcz86IHN0cmluZ1tdfX0gcGx1Z2luXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdW119XG4gICAqL1xuICBwbHVnaW5TY29wZUtleXMocGx1Z2luKSB7XG4gICAgY29uc3QgaWQgPSBwbHVnaW4uaWQ7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMudHlwZTtcbiAgICByZXR1cm4gY2FjaGVkS2V5cyhgJHt0eXBlfS1wbHVnaW4tJHtpZH1gLFxuICAgICAgKCkgPT4gW1tcbiAgICAgICAgYHBsdWdpbnMuJHtpZH1gLFxuICAgICAgICAuLi5wbHVnaW4uYWRkaXRpb25hbE9wdGlvblNjb3BlcyB8fCBbXSxcbiAgICAgIF1dKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX2NhY2hlZFNjb3BlcyhtYWluU2NvcGUsIHJlc2V0Q2FjaGUpIHtcbiAgICBjb25zdCBfc2NvcGVDYWNoZSA9IHRoaXMuX3Njb3BlQ2FjaGU7XG4gICAgbGV0IGNhY2hlID0gX3Njb3BlQ2FjaGUuZ2V0KG1haW5TY29wZSk7XG4gICAgaWYgKCFjYWNoZSB8fCByZXNldENhY2hlKSB7XG4gICAgICBjYWNoZSA9IG5ldyBNYXAoKTtcbiAgICAgIF9zY29wZUNhY2hlLnNldChtYWluU2NvcGUsIGNhY2hlKTtcbiAgICB9XG4gICAgcmV0dXJuIGNhY2hlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSBvYmplY3RzIGZyb20gb3B0aW9ucyBhbmQgZGVmYXVsdHMgZm9yIG9wdGlvbiB2YWx1ZSByZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge29iamVjdH0gbWFpblNjb3BlIC0gVGhlIG1haW4gc2NvcGUgb2JqZWN0IGZvciBvcHRpb25zXG4gICAqIEBwYXJhbSB7c3RyaW5nW11bXX0ga2V5TGlzdHMgLSBUaGUgYXJyYXlzIG9mIGtleXMgaW4gcmVzb2x1dGlvbiBvcmRlclxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXNldENhY2hlXSAtIHJlc2V0IHRoZSBjYWNoZSBmb3IgdGhpcyBtYWluU2NvcGVcbiAgICovXG4gIGdldE9wdGlvblNjb3BlcyhtYWluU2NvcGUsIGtleUxpc3RzLCByZXNldENhY2hlKSB7XG4gICAgY29uc3Qge29wdGlvbnMsIHR5cGV9ID0gdGhpcztcbiAgICBjb25zdCBjYWNoZSA9IHRoaXMuX2NhY2hlZFNjb3BlcyhtYWluU2NvcGUsIHJlc2V0Q2FjaGUpO1xuICAgIGNvbnN0IGNhY2hlZCA9IGNhY2hlLmdldChrZXlMaXN0cyk7XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG5cbiAgICBjb25zdCBzY29wZXMgPSBuZXcgU2V0KCk7XG5cbiAgICBrZXlMaXN0cy5mb3JFYWNoKGtleXMgPT4ge1xuICAgICAgaWYgKG1haW5TY29wZSkge1xuICAgICAgICBzY29wZXMuYWRkKG1haW5TY29wZSk7XG4gICAgICAgIGtleXMuZm9yRWFjaChrZXkgPT4gYWRkSWZGb3VuZChzY29wZXMsIG1haW5TY29wZSwga2V5KSk7XG4gICAgICB9XG4gICAgICBrZXlzLmZvckVhY2goa2V5ID0+IGFkZElmRm91bmQoc2NvcGVzLCBvcHRpb25zLCBrZXkpKTtcbiAgICAgIGtleXMuZm9yRWFjaChrZXkgPT4gYWRkSWZGb3VuZChzY29wZXMsIG92ZXJyaWRlc1t0eXBlXSB8fCB7fSwga2V5KSk7XG4gICAgICBrZXlzLmZvckVhY2goa2V5ID0+IGFkZElmRm91bmQoc2NvcGVzLCBkZWZhdWx0cywga2V5KSk7XG4gICAgICBrZXlzLmZvckVhY2goa2V5ID0+IGFkZElmRm91bmQoc2NvcGVzLCBkZXNjcmlwdG9ycywga2V5KSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBhcnJheSA9IEFycmF5LmZyb20oc2NvcGVzKTtcbiAgICBpZiAoYXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICBhcnJheS5wdXNoKE9iamVjdC5jcmVhdGUobnVsbCkpO1xuICAgIH1cbiAgICBpZiAoa2V5c0NhY2hlZC5oYXMoa2V5TGlzdHMpKSB7XG4gICAgICBjYWNoZS5zZXQoa2V5TGlzdHMsIGFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIG9wdGlvbiBzY29wZXMgZm9yIHJlc29sdmluZyBjaGFydCBvcHRpb25zXG4gICAqIEByZXR1cm4ge29iamVjdFtdfVxuICAgKi9cbiAgY2hhcnRPcHRpb25TY29wZXMoKSB7XG4gICAgY29uc3Qge29wdGlvbnMsIHR5cGV9ID0gdGhpcztcblxuICAgIHJldHVybiBbXG4gICAgICBvcHRpb25zLFxuICAgICAgb3ZlcnJpZGVzW3R5cGVdIHx8IHt9LFxuICAgICAgZGVmYXVsdHMuZGF0YXNldHNbdHlwZV0gfHwge30sIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy84NTMxXG4gICAgICB7dHlwZX0sXG4gICAgICBkZWZhdWx0cyxcbiAgICAgIGRlc2NyaXB0b3JzXG4gICAgXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdFtdfSBzY29wZXNcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gbmFtZXNcbiAgICogQHBhcmFtIHtmdW5jdGlvbnxvYmplY3R9IGNvbnRleHRcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gW3ByZWZpeGVzXVxuICAgKiBAcmV0dXJuIHtvYmplY3R9XG4gICAqL1xuICByZXNvbHZlTmFtZWRPcHRpb25zKHNjb3BlcywgbmFtZXMsIGNvbnRleHQsIHByZWZpeGVzID0gWycnXSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IHskc2hhcmVkOiB0cnVlfTtcbiAgICBjb25zdCB7cmVzb2x2ZXIsIHN1YlByZWZpeGVzfSA9IGdldFJlc29sdmVyKHRoaXMuX3Jlc29sdmVyQ2FjaGUsIHNjb3BlcywgcHJlZml4ZXMpO1xuICAgIGxldCBvcHRpb25zID0gcmVzb2x2ZXI7XG4gICAgaWYgKG5lZWRDb250ZXh0KHJlc29sdmVyLCBuYW1lcykpIHtcbiAgICAgIHJlc3VsdC4kc2hhcmVkID0gZmFsc2U7XG4gICAgICBjb250ZXh0ID0gaXNGdW5jdGlvbihjb250ZXh0KSA/IGNvbnRleHQoKSA6IGNvbnRleHQ7XG4gICAgICAvLyBzdWJSZXNvbHZlciBpcyBwYXNzZWQgdG8gc2NyaXB0YWJsZSBvcHRpb25zLiBJdCBzaG91bGQgbm90IHJlc29sdmUgdG8gaG92ZXIgb3B0aW9ucy5cbiAgICAgIGNvbnN0IHN1YlJlc29sdmVyID0gdGhpcy5jcmVhdGVSZXNvbHZlcihzY29wZXMsIGNvbnRleHQsIHN1YlByZWZpeGVzKTtcbiAgICAgIG9wdGlvbnMgPSBfYXR0YWNoQ29udGV4dChyZXNvbHZlciwgY29udGV4dCwgc3ViUmVzb2x2ZXIpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcHJvcCBvZiBuYW1lcykge1xuICAgICAgcmVzdWx0W3Byb3BdID0gb3B0aW9uc1twcm9wXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdFtdfSBzY29wZXNcbiAgICogQHBhcmFtIHtvYmplY3R9IFtjb250ZXh0XVxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbcHJlZml4ZXNdXG4gICAqIEBwYXJhbSB7e3NjcmlwdGFibGU6IGJvb2xlYW4sIGluZGV4YWJsZTogYm9vbGVhbiwgYWxsS2V5cz86IGJvb2xlYW59fSBbZGVzY3JpcHRvckRlZmF1bHRzXVxuICAgKi9cbiAgY3JlYXRlUmVzb2x2ZXIoc2NvcGVzLCBjb250ZXh0LCBwcmVmaXhlcyA9IFsnJ10sIGRlc2NyaXB0b3JEZWZhdWx0cykge1xuICAgIGNvbnN0IHtyZXNvbHZlcn0gPSBnZXRSZXNvbHZlcih0aGlzLl9yZXNvbHZlckNhY2hlLCBzY29wZXMsIHByZWZpeGVzKTtcbiAgICByZXR1cm4gaXNPYmplY3QoY29udGV4dClcbiAgICAgID8gX2F0dGFjaENvbnRleHQocmVzb2x2ZXIsIGNvbnRleHQsIHVuZGVmaW5lZCwgZGVzY3JpcHRvckRlZmF1bHRzKVxuICAgICAgOiByZXNvbHZlcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRSZXNvbHZlcihyZXNvbHZlckNhY2hlLCBzY29wZXMsIHByZWZpeGVzKSB7XG4gIGxldCBjYWNoZSA9IHJlc29sdmVyQ2FjaGUuZ2V0KHNjb3Blcyk7XG4gIGlmICghY2FjaGUpIHtcbiAgICBjYWNoZSA9IG5ldyBNYXAoKTtcbiAgICByZXNvbHZlckNhY2hlLnNldChzY29wZXMsIGNhY2hlKTtcbiAgfVxuICBjb25zdCBjYWNoZUtleSA9IHByZWZpeGVzLmpvaW4oKTtcbiAgbGV0IGNhY2hlZCA9IGNhY2hlLmdldChjYWNoZUtleSk7XG4gIGlmICghY2FjaGVkKSB7XG4gICAgY29uc3QgcmVzb2x2ZXIgPSBfY3JlYXRlUmVzb2x2ZXIoc2NvcGVzLCBwcmVmaXhlcyk7XG4gICAgY2FjaGVkID0ge1xuICAgICAgcmVzb2x2ZXIsXG4gICAgICBzdWJQcmVmaXhlczogcHJlZml4ZXMuZmlsdGVyKHAgPT4gIXAudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnaG92ZXInKSlcbiAgICB9O1xuICAgIGNhY2hlLnNldChjYWNoZUtleSwgY2FjaGVkKTtcbiAgfVxuICByZXR1cm4gY2FjaGVkO1xufVxuXG5jb25zdCBoYXNGdW5jdGlvbiA9IHZhbHVlID0+IGlzT2JqZWN0KHZhbHVlKVxuICAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh2YWx1ZSkuc29tZSgoa2V5KSA9PiBpc0Z1bmN0aW9uKHZhbHVlW2tleV0pKTtcblxuZnVuY3Rpb24gbmVlZENvbnRleHQocHJveHksIG5hbWVzKSB7XG4gIGNvbnN0IHtpc1NjcmlwdGFibGUsIGlzSW5kZXhhYmxlfSA9IF9kZXNjcmlwdG9ycyhwcm94eSk7XG5cbiAgZm9yIChjb25zdCBwcm9wIG9mIG5hbWVzKSB7XG4gICAgY29uc3Qgc2NyaXB0YWJsZSA9IGlzU2NyaXB0YWJsZShwcm9wKTtcbiAgICBjb25zdCBpbmRleGFibGUgPSBpc0luZGV4YWJsZShwcm9wKTtcbiAgICBjb25zdCB2YWx1ZSA9IChpbmRleGFibGUgfHwgc2NyaXB0YWJsZSkgJiYgcHJveHlbcHJvcF07XG4gICAgaWYgKChzY3JpcHRhYmxlICYmIChpc0Z1bmN0aW9uKHZhbHVlKSB8fCBoYXNGdW5jdGlvbih2YWx1ZSkpKVxuICAgICAgfHwgKGluZGV4YWJsZSAmJiBpc0FycmF5KHZhbHVlKSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG4iLCAiaW1wb3J0IGFuaW1hdG9yIGZyb20gJy4vY29yZS5hbmltYXRvci5qcyc7XG5pbXBvcnQgZGVmYXVsdHMsIHtvdmVycmlkZXN9IGZyb20gJy4vY29yZS5kZWZhdWx0cy5qcyc7XG5pbXBvcnQgSW50ZXJhY3Rpb24gZnJvbSAnLi9jb3JlLmludGVyYWN0aW9uLmpzJztcbmltcG9ydCBsYXlvdXRzIGZyb20gJy4vY29yZS5sYXlvdXRzLmpzJztcbmltcG9ydCB7X2RldGVjdFBsYXRmb3JtfSBmcm9tICcuLi9wbGF0Zm9ybS9pbmRleC5qcyc7XG5pbXBvcnQgUGx1Z2luU2VydmljZSBmcm9tICcuL2NvcmUucGx1Z2lucy5qcyc7XG5pbXBvcnQgcmVnaXN0cnkgZnJvbSAnLi9jb3JlLnJlZ2lzdHJ5LmpzJztcbmltcG9ydCBDb25maWcsIHtkZXRlcm1pbmVBeGlzLCBnZXRJbmRleEF4aXN9IGZyb20gJy4vY29yZS5jb25maWcuanMnO1xuaW1wb3J0IHtyZXRpbmFTY2FsZSwgX2lzRG9tU3VwcG9ydGVkfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZG9tLmpzJztcbmltcG9ydCB7ZWFjaCwgY2FsbGJhY2sgYXMgY2FsbENhbGxiYWNrLCB1aWQsIHZhbHVlT3JEZWZhdWx0LCBfZWxlbWVudHNFcXVhbCwgaXNOdWxsT3JVbmRlZiwgc2V0c0VxdWFsLCBkZWZpbmVkLCBpc0Z1bmN0aW9uLCBfaXNDbGlja0V2ZW50fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge2NsZWFyQ2FudmFzLCBjbGlwQXJlYSwgY3JlYXRlQ29udGV4dCwgdW5jbGlwQXJlYSwgX2lzUG9pbnRJbkFyZWF9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuLy8gQHRzLWlnbm9yZVxuaW1wb3J0IHt2ZXJzaW9ufSBmcm9tICcuLi8uLi9wYWNrYWdlLmpzb24nO1xuaW1wb3J0IHtkZWJvdW5jZX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmV4dHJhcy5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL3R5cGVzL2luZGV4LmpzJykuQ2hhcnRFdmVudCB9IENoYXJ0RXZlbnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi90eXBlcy9pbmRleC5qcycpLlBvaW50IH0gUG9pbnRcbiAqL1xuXG5jb25zdCBLTk9XTl9QT1NJVElPTlMgPSBbJ3RvcCcsICdib3R0b20nLCAnbGVmdCcsICdyaWdodCcsICdjaGFydEFyZWEnXTtcbmZ1bmN0aW9uIHBvc2l0aW9uSXNIb3Jpem9udGFsKHBvc2l0aW9uLCBheGlzKSB7XG4gIHJldHVybiBwb3NpdGlvbiA9PT0gJ3RvcCcgfHwgcG9zaXRpb24gPT09ICdib3R0b20nIHx8IChLTk9XTl9QT1NJVElPTlMuaW5kZXhPZihwb3NpdGlvbikgPT09IC0xICYmIGF4aXMgPT09ICd4Jyk7XG59XG5cbmZ1bmN0aW9uIGNvbXBhcmUyTGV2ZWwobDEsIGwyKSB7XG4gIHJldHVybiBmdW5jdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIGFbbDFdID09PSBiW2wxXVxuICAgICAgPyBhW2wyXSAtIGJbbDJdXG4gICAgICA6IGFbbDFdIC0gYltsMV07XG4gIH07XG59XG5cbmZ1bmN0aW9uIG9uQW5pbWF0aW9uc0NvbXBsZXRlKGNvbnRleHQpIHtcbiAgY29uc3QgY2hhcnQgPSBjb250ZXh0LmNoYXJ0O1xuICBjb25zdCBhbmltYXRpb25PcHRpb25zID0gY2hhcnQub3B0aW9ucy5hbmltYXRpb247XG5cbiAgY2hhcnQubm90aWZ5UGx1Z2lucygnYWZ0ZXJSZW5kZXInKTtcbiAgY2FsbENhbGxiYWNrKGFuaW1hdGlvbk9wdGlvbnMgJiYgYW5pbWF0aW9uT3B0aW9ucy5vbkNvbXBsZXRlLCBbY29udGV4dF0sIGNoYXJ0KTtcbn1cblxuZnVuY3Rpb24gb25BbmltYXRpb25Qcm9ncmVzcyhjb250ZXh0KSB7XG4gIGNvbnN0IGNoYXJ0ID0gY29udGV4dC5jaGFydDtcbiAgY29uc3QgYW5pbWF0aW9uT3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMuYW5pbWF0aW9uO1xuICBjYWxsQ2FsbGJhY2soYW5pbWF0aW9uT3B0aW9ucyAmJiBhbmltYXRpb25PcHRpb25zLm9uUHJvZ3Jlc3MsIFtjb250ZXh0XSwgY2hhcnQpO1xufVxuXG4vKipcbiAqIENoYXJ0LmpzIGNhbiB0YWtlIGEgc3RyaW5nIGlkIG9mIGEgY2FudmFzIGVsZW1lbnQsIGEgMmQgY29udGV4dCwgb3IgYSBjYW52YXMgZWxlbWVudCBpdHNlbGYuXG4gKiBBdHRlbXB0IHRvIHVud3JhcCB0aGUgaXRlbSBwYXNzZWQgaW50byB0aGUgY2hhcnQgY29uc3RydWN0b3Igc28gdGhhdCBpdCBpcyBhIGNhbnZhcyBlbGVtZW50IChpZiBwb3NzaWJsZSkuXG4gKi9cbmZ1bmN0aW9uIGdldENhbnZhcyhpdGVtKSB7XG4gIGlmIChfaXNEb21TdXBwb3J0ZWQoKSAmJiB0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICBpdGVtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaXRlbSk7XG4gIH0gZWxzZSBpZiAoaXRlbSAmJiBpdGVtLmxlbmd0aCkge1xuICAgIC8vIFN1cHBvcnQgZm9yIGFycmF5IGJhc2VkIHF1ZXJpZXMgKHN1Y2ggYXMgalF1ZXJ5KVxuICAgIGl0ZW0gPSBpdGVtWzBdO1xuICB9XG5cbiAgaWYgKGl0ZW0gJiYgaXRlbS5jYW52YXMpIHtcbiAgICAvLyBTdXBwb3J0IGZvciBhbnkgb2JqZWN0IGFzc29jaWF0ZWQgdG8gYSBjYW52YXMgKGluY2x1ZGluZyBhIGNvbnRleHQyZClcbiAgICBpdGVtID0gaXRlbS5jYW52YXM7XG4gIH1cbiAgcmV0dXJuIGl0ZW07XG59XG5cbmNvbnN0IGluc3RhbmNlcyA9IHt9O1xuY29uc3QgZ2V0Q2hhcnQgPSAoa2V5KSA9PiB7XG4gIGNvbnN0IGNhbnZhcyA9IGdldENhbnZhcyhrZXkpO1xuICByZXR1cm4gT2JqZWN0LnZhbHVlcyhpbnN0YW5jZXMpLmZpbHRlcigoYykgPT4gYy5jYW52YXMgPT09IGNhbnZhcykucG9wKCk7XG59O1xuXG5mdW5jdGlvbiBtb3ZlTnVtZXJpY0tleXMob2JqLCBzdGFydCwgbW92ZSkge1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgIGNvbnN0IGludEtleSA9ICtrZXk7XG4gICAgaWYgKGludEtleSA+PSBzdGFydCkge1xuICAgICAgY29uc3QgdmFsdWUgPSBvYmpba2V5XTtcbiAgICAgIGRlbGV0ZSBvYmpba2V5XTtcbiAgICAgIGlmIChtb3ZlID4gMCB8fCBpbnRLZXkgPiBzdGFydCkge1xuICAgICAgICBvYmpbaW50S2V5ICsgbW92ZV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge0NoYXJ0RXZlbnR9IGVcbiAqIEBwYXJhbSB7Q2hhcnRFdmVudHxudWxsfSBsYXN0RXZlbnRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaW5DaGFydEFyZWFcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNDbGlja1xuICogQHJldHVybnMge0NoYXJ0RXZlbnR8bnVsbH1cbiAqL1xuZnVuY3Rpb24gZGV0ZXJtaW5lTGFzdEV2ZW50KGUsIGxhc3RFdmVudCwgaW5DaGFydEFyZWEsIGlzQ2xpY2spIHtcbiAgaWYgKCFpbkNoYXJ0QXJlYSB8fCBlLnR5cGUgPT09ICdtb3VzZW91dCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAoaXNDbGljaykge1xuICAgIHJldHVybiBsYXN0RXZlbnQ7XG4gIH1cbiAgcmV0dXJuIGU7XG59XG5cbmZ1bmN0aW9uIGdldFNpemVGb3JBcmVhKHNjYWxlLCBjaGFydEFyZWEsIGZpZWxkKSB7XG4gIHJldHVybiBzY2FsZS5vcHRpb25zLmNsaXAgPyBzY2FsZVtmaWVsZF0gOiBjaGFydEFyZWFbZmllbGRdO1xufVxuXG5mdW5jdGlvbiBnZXREYXRhc2V0QXJlYShtZXRhLCBjaGFydEFyZWEpIHtcbiAgY29uc3Qge3hTY2FsZSwgeVNjYWxlfSA9IG1ldGE7XG4gIGlmICh4U2NhbGUgJiYgeVNjYWxlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxlZnQ6IGdldFNpemVGb3JBcmVhKHhTY2FsZSwgY2hhcnRBcmVhLCAnbGVmdCcpLFxuICAgICAgcmlnaHQ6IGdldFNpemVGb3JBcmVhKHhTY2FsZSwgY2hhcnRBcmVhLCAncmlnaHQnKSxcbiAgICAgIHRvcDogZ2V0U2l6ZUZvckFyZWEoeVNjYWxlLCBjaGFydEFyZWEsICd0b3AnKSxcbiAgICAgIGJvdHRvbTogZ2V0U2l6ZUZvckFyZWEoeVNjYWxlLCBjaGFydEFyZWEsICdib3R0b20nKVxuICAgIH07XG4gIH1cbiAgcmV0dXJuIGNoYXJ0QXJlYTtcbn1cblxuY2xhc3MgQ2hhcnQge1xuXG4gIHN0YXRpYyBkZWZhdWx0cyA9IGRlZmF1bHRzO1xuICBzdGF0aWMgaW5zdGFuY2VzID0gaW5zdGFuY2VzO1xuICBzdGF0aWMgb3ZlcnJpZGVzID0gb3ZlcnJpZGVzO1xuICBzdGF0aWMgcmVnaXN0cnkgPSByZWdpc3RyeTtcbiAgc3RhdGljIHZlcnNpb24gPSB2ZXJzaW9uO1xuICBzdGF0aWMgZ2V0Q2hhcnQgPSBnZXRDaGFydDtcblxuICBzdGF0aWMgcmVnaXN0ZXIoLi4uaXRlbXMpIHtcbiAgICByZWdpc3RyeS5hZGQoLi4uaXRlbXMpO1xuICAgIGludmFsaWRhdGVQbHVnaW5zKCk7XG4gIH1cblxuICBzdGF0aWMgdW5yZWdpc3RlciguLi5pdGVtcykge1xuICAgIHJlZ2lzdHJ5LnJlbW92ZSguLi5pdGVtcyk7XG4gICAgaW52YWxpZGF0ZVBsdWdpbnMoKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtc3RhdGVtZW50c1xuICBjb25zdHJ1Y3RvcihpdGVtLCB1c2VyQ29uZmlnKSB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWcgPSBuZXcgQ29uZmlnKHVzZXJDb25maWcpO1xuICAgIGNvbnN0IGluaXRpYWxDYW52YXMgPSBnZXRDYW52YXMoaXRlbSk7XG4gICAgY29uc3QgZXhpc3RpbmdDaGFydCA9IGdldENoYXJ0KGluaXRpYWxDYW52YXMpO1xuICAgIGlmIChleGlzdGluZ0NoYXJ0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdDYW52YXMgaXMgYWxyZWFkeSBpbiB1c2UuIENoYXJ0IHdpdGggSUQgXFwnJyArIGV4aXN0aW5nQ2hhcnQuaWQgKyAnXFwnJyArXG5cdFx0XHRcdCcgbXVzdCBiZSBkZXN0cm95ZWQgYmVmb3JlIHRoZSBjYW52YXMgd2l0aCBJRCBcXCcnICsgZXhpc3RpbmdDaGFydC5jYW52YXMuaWQgKyAnXFwnIGNhbiBiZSByZXVzZWQuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25zID0gY29uZmlnLmNyZWF0ZVJlc29sdmVyKGNvbmZpZy5jaGFydE9wdGlvblNjb3BlcygpLCB0aGlzLmdldENvbnRleHQoKSk7XG5cbiAgICB0aGlzLnBsYXRmb3JtID0gbmV3IChjb25maWcucGxhdGZvcm0gfHwgX2RldGVjdFBsYXRmb3JtKGluaXRpYWxDYW52YXMpKSgpO1xuICAgIHRoaXMucGxhdGZvcm0udXBkYXRlQ29uZmlnKGNvbmZpZyk7XG5cbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5wbGF0Zm9ybS5hY3F1aXJlQ29udGV4dChpbml0aWFsQ2FudmFzLCBvcHRpb25zLmFzcGVjdFJhdGlvKTtcbiAgICBjb25zdCBjYW52YXMgPSBjb250ZXh0ICYmIGNvbnRleHQuY2FudmFzO1xuICAgIGNvbnN0IGhlaWdodCA9IGNhbnZhcyAmJiBjYW52YXMuaGVpZ2h0O1xuICAgIGNvbnN0IHdpZHRoID0gY2FudmFzICYmIGNhbnZhcy53aWR0aDtcblxuICAgIHRoaXMuaWQgPSB1aWQoKTtcbiAgICB0aGlzLmN0eCA9IGNvbnRleHQ7XG4gICAgdGhpcy5jYW52YXMgPSBjYW52YXM7XG4gICAgdGhpcy53aWR0aCA9IHdpZHRoO1xuICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zO1xuICAgIC8vIFN0b3JlIHRoZSBwcmV2aW91c2x5IHVzZWQgYXNwZWN0IHJhdGlvIHRvIGRldGVybWluZSBpZiBhIHJlc2l6ZVxuICAgIC8vIGlzIG5lZWRlZCBkdXJpbmcgdXBkYXRlcy4gRG8gdGhpcyBhZnRlciBfb3B0aW9ucyBpcyBzZXQgc2luY2VcbiAgICAvLyBhc3BlY3RSYXRpbyB1c2VzIGEgZ2V0dGVyXG4gICAgdGhpcy5fYXNwZWN0UmF0aW8gPSB0aGlzLmFzcGVjdFJhdGlvO1xuICAgIHRoaXMuX2xheWVycyA9IFtdO1xuICAgIHRoaXMuX21ldGFzZXRzID0gW107XG4gICAgdGhpcy5fc3RhY2tzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuYm94ZXMgPSBbXTtcbiAgICB0aGlzLmN1cnJlbnREZXZpY2VQaXhlbFJhdGlvID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY2hhcnRBcmVhID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2FjdGl2ZSA9IFtdO1xuICAgIHRoaXMuX2xhc3RFdmVudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9saXN0ZW5lcnMgPSB7fTtcbiAgICAvKiogQHR5cGUgez97YXR0YWNoPzogZnVuY3Rpb24sIGRldGFjaD86IGZ1bmN0aW9uLCByZXNpemU/OiBmdW5jdGlvbn19ICovXG4gICAgdGhpcy5fcmVzcG9uc2l2ZUxpc3RlbmVycyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9zb3J0ZWRNZXRhc2V0cyA9IFtdO1xuICAgIHRoaXMuc2NhbGVzID0ge307XG4gICAgdGhpcy5fcGx1Z2lucyA9IG5ldyBQbHVnaW5TZXJ2aWNlKCk7XG4gICAgdGhpcy4kcHJveGllcyA9IHt9O1xuICAgIHRoaXMuX2hpZGRlbkluZGljZXMgPSB7fTtcbiAgICB0aGlzLmF0dGFjaGVkID0gZmFsc2U7XG4gICAgdGhpcy5fYW5pbWF0aW9uc0Rpc2FibGVkID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuJGNvbnRleHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fZG9SZXNpemUgPSBkZWJvdW5jZShtb2RlID0+IHRoaXMudXBkYXRlKG1vZGUpLCBvcHRpb25zLnJlc2l6ZURlbGF5IHx8IDApO1xuICAgIHRoaXMuX2RhdGFDaGFuZ2VzID0gW107XG5cbiAgICAvLyBBZGQgdGhlIGNoYXJ0IGluc3RhbmNlIHRvIHRoZSBnbG9iYWwgbmFtZXNwYWNlXG4gICAgaW5zdGFuY2VzW3RoaXMuaWRdID0gdGhpcztcblxuICAgIGlmICghY29udGV4dCB8fCAhY2FudmFzKSB7XG4gICAgICAvLyBUaGUgZ2l2ZW4gaXRlbSBpcyBub3QgYSBjb21wYXRpYmxlIGNvbnRleHQyZCBlbGVtZW50LCBsZXQncyByZXR1cm4gYmVmb3JlIGZpbmFsaXppbmdcbiAgICAgIC8vIHRoZSBjaGFydCBpbml0aWFsaXphdGlvbiBidXQgYWZ0ZXIgc2V0dGluZyBiYXNpYyBjaGFydCAvIGNvbnRyb2xsZXIgcHJvcGVydGllcyB0aGF0XG4gICAgICAvLyBjYW4gaGVscCB0byBmaWd1cmUgb3V0IHRoYXQgdGhlIGNoYXJ0IGlzIG5vdCB2YWxpZCAoZS5nIGNoYXJ0LmNhbnZhcyAhPT0gbnVsbCk7XG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvMjgwN1xuICAgICAgY29uc29sZS5lcnJvcihcIkZhaWxlZCB0byBjcmVhdGUgY2hhcnQ6IGNhbid0IGFjcXVpcmUgY29udGV4dCBmcm9tIHRoZSBnaXZlbiBpdGVtXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGFuaW1hdG9yLmxpc3Rlbih0aGlzLCAnY29tcGxldGUnLCBvbkFuaW1hdGlvbnNDb21wbGV0ZSk7XG4gICAgYW5pbWF0b3IubGlzdGVuKHRoaXMsICdwcm9ncmVzcycsIG9uQW5pbWF0aW9uUHJvZ3Jlc3MpO1xuXG4gICAgdGhpcy5faW5pdGlhbGl6ZSgpO1xuICAgIGlmICh0aGlzLmF0dGFjaGVkKSB7XG4gICAgICB0aGlzLnVwZGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBhc3BlY3RSYXRpbygpIHtcbiAgICBjb25zdCB7b3B0aW9uczoge2FzcGVjdFJhdGlvLCBtYWludGFpbkFzcGVjdFJhdGlvfSwgd2lkdGgsIGhlaWdodCwgX2FzcGVjdFJhdGlvfSA9IHRoaXM7XG4gICAgaWYgKCFpc051bGxPclVuZGVmKGFzcGVjdFJhdGlvKSkge1xuICAgICAgLy8gSWYgYXNwZWN0UmF0aW8gaXMgZGVmaW5lZCBpbiBvcHRpb25zLCB1c2UgdGhhdC5cbiAgICAgIHJldHVybiBhc3BlY3RSYXRpbztcbiAgICB9XG5cbiAgICBpZiAobWFpbnRhaW5Bc3BlY3RSYXRpbyAmJiBfYXNwZWN0UmF0aW8pIHtcbiAgICAgIC8vIElmIG1haW50YWluQXNwZWN0UmF0aW8gaXMgdHJ1dGhseSBhbmQgd2UgaGFkIHByZXZpb3VzbHkgZGV0ZXJtaW5lZCBfYXNwZWN0UmF0aW8sIHVzZSB0aGF0XG4gICAgICByZXR1cm4gX2FzcGVjdFJhdGlvO1xuICAgIH1cblxuICAgIC8vIENhbGN1bGF0ZVxuICAgIHJldHVybiBoZWlnaHQgPyB3aWR0aCAvIGhlaWdodCA6IG51bGw7XG4gIH1cblxuICBnZXQgZGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YTtcbiAgfVxuXG4gIHNldCBkYXRhKGRhdGEpIHtcbiAgICB0aGlzLmNvbmZpZy5kYXRhID0gZGF0YTtcbiAgfVxuXG4gIGdldCBvcHRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLl9vcHRpb25zO1xuICB9XG5cbiAgc2V0IG9wdGlvbnMob3B0aW9ucykge1xuICAgIHRoaXMuY29uZmlnLm9wdGlvbnMgPSBvcHRpb25zO1xuICB9XG5cbiAgZ2V0IHJlZ2lzdHJ5KCkge1xuICAgIHJldHVybiByZWdpc3RyeTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2luaXRpYWxpemUoKSB7XG4gICAgLy8gQmVmb3JlIGluaXQgcGx1Z2luIG5vdGlmaWNhdGlvblxuICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlSW5pdCcpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5yZXNwb25zaXZlKSB7XG4gICAgICB0aGlzLnJlc2l6ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXRpbmFTY2FsZSh0aGlzLCB0aGlzLm9wdGlvbnMuZGV2aWNlUGl4ZWxSYXRpbyk7XG4gICAgfVxuXG4gICAgdGhpcy5iaW5kRXZlbnRzKCk7XG5cbiAgICAvLyBBZnRlciBpbml0IHBsdWdpbiBub3RpZmljYXRpb25cbiAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVySW5pdCcpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICBjbGVhckNhbnZhcyh0aGlzLmNhbnZhcywgdGhpcy5jdHgpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc3RvcCgpIHtcbiAgICBhbmltYXRvci5zdG9wKHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG5cdCAqIFJlc2l6ZSB0aGUgY2hhcnQgdG8gaXRzIGNvbnRhaW5lciBvciB0byBleHBsaWNpdCBkaW1lbnNpb25zLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gW3dpZHRoXVxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2hlaWdodF1cblx0ICovXG4gIHJlc2l6ZSh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgaWYgKCFhbmltYXRvci5ydW5uaW5nKHRoaXMpKSB7XG4gICAgICB0aGlzLl9yZXNpemUod2lkdGgsIGhlaWdodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3Jlc2l6ZUJlZm9yZURyYXcgPSB7d2lkdGgsIGhlaWdodH07XG4gICAgfVxuICB9XG5cbiAgX3Jlc2l6ZSh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBjYW52YXMgPSB0aGlzLmNhbnZhcztcbiAgICBjb25zdCBhc3BlY3RSYXRpbyA9IG9wdGlvbnMubWFpbnRhaW5Bc3BlY3RSYXRpbyAmJiB0aGlzLmFzcGVjdFJhdGlvO1xuICAgIGNvbnN0IG5ld1NpemUgPSB0aGlzLnBsYXRmb3JtLmdldE1heGltdW1TaXplKGNhbnZhcywgd2lkdGgsIGhlaWdodCwgYXNwZWN0UmF0aW8pO1xuICAgIGNvbnN0IG5ld1JhdGlvID0gb3B0aW9ucy5kZXZpY2VQaXhlbFJhdGlvIHx8IHRoaXMucGxhdGZvcm0uZ2V0RGV2aWNlUGl4ZWxSYXRpbygpO1xuICAgIGNvbnN0IG1vZGUgPSB0aGlzLndpZHRoID8gJ3Jlc2l6ZScgOiAnYXR0YWNoJztcblxuICAgIHRoaXMud2lkdGggPSBuZXdTaXplLndpZHRoO1xuICAgIHRoaXMuaGVpZ2h0ID0gbmV3U2l6ZS5oZWlnaHQ7XG4gICAgdGhpcy5fYXNwZWN0UmF0aW8gPSB0aGlzLmFzcGVjdFJhdGlvO1xuICAgIGlmICghcmV0aW5hU2NhbGUodGhpcywgbmV3UmF0aW8sIHRydWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdyZXNpemUnLCB7c2l6ZTogbmV3U2l6ZX0pO1xuXG4gICAgY2FsbENhbGxiYWNrKG9wdGlvbnMub25SZXNpemUsIFt0aGlzLCBuZXdTaXplXSwgdGhpcyk7XG5cbiAgICBpZiAodGhpcy5hdHRhY2hlZCkge1xuICAgICAgaWYgKHRoaXMuX2RvUmVzaXplKG1vZGUpKSB7XG4gICAgICAgIC8vIFRoZSByZXNpemUgdXBkYXRlIGlzIGRlbGF5ZWQsIG9ubHkgZHJhdyB3aXRob3V0IHVwZGF0aW5nLlxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGVuc3VyZVNjYWxlc0hhdmVJRHMoKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBzY2FsZXNPcHRpb25zID0gb3B0aW9ucy5zY2FsZXMgfHwge307XG5cbiAgICBlYWNoKHNjYWxlc09wdGlvbnMsIChheGlzT3B0aW9ucywgYXhpc0lEKSA9PiB7XG4gICAgICBheGlzT3B0aW9ucy5pZCA9IGF4aXNJRDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBCdWlsZHMgYSBtYXAgb2Ygc2NhbGUgSUQgdG8gc2NhbGUgb2JqZWN0IGZvciBmdXR1cmUgbG9va3VwLlxuXHQgKi9cbiAgYnVpbGRPclVwZGF0ZVNjYWxlcygpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHNjYWxlT3B0cyA9IG9wdGlvbnMuc2NhbGVzO1xuICAgIGNvbnN0IHNjYWxlcyA9IHRoaXMuc2NhbGVzO1xuICAgIGNvbnN0IHVwZGF0ZWQgPSBPYmplY3Qua2V5cyhzY2FsZXMpLnJlZHVjZSgob2JqLCBpZCkgPT4ge1xuICAgICAgb2JqW2lkXSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9LCB7fSk7XG4gICAgbGV0IGl0ZW1zID0gW107XG5cbiAgICBpZiAoc2NhbGVPcHRzKSB7XG4gICAgICBpdGVtcyA9IGl0ZW1zLmNvbmNhdChcbiAgICAgICAgT2JqZWN0LmtleXMoc2NhbGVPcHRzKS5tYXAoKGlkKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc2NhbGVPcHRpb25zID0gc2NhbGVPcHRzW2lkXTtcbiAgICAgICAgICBjb25zdCBheGlzID0gZGV0ZXJtaW5lQXhpcyhpZCwgc2NhbGVPcHRpb25zKTtcbiAgICAgICAgICBjb25zdCBpc1JhZGlhbCA9IGF4aXMgPT09ICdyJztcbiAgICAgICAgICBjb25zdCBpc0hvcml6b250YWwgPSBheGlzID09PSAneCc7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG9wdGlvbnM6IHNjYWxlT3B0aW9ucyxcbiAgICAgICAgICAgIGRwb3NpdGlvbjogaXNSYWRpYWwgPyAnY2hhcnRBcmVhJyA6IGlzSG9yaXpvbnRhbCA/ICdib3R0b20nIDogJ2xlZnQnLFxuICAgICAgICAgICAgZHR5cGU6IGlzUmFkaWFsID8gJ3JhZGlhbExpbmVhcicgOiBpc0hvcml6b250YWwgPyAnY2F0ZWdvcnknIDogJ2xpbmVhcidcbiAgICAgICAgICB9O1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBlYWNoKGl0ZW1zLCAoaXRlbSkgPT4ge1xuICAgICAgY29uc3Qgc2NhbGVPcHRpb25zID0gaXRlbS5vcHRpb25zO1xuICAgICAgY29uc3QgaWQgPSBzY2FsZU9wdGlvbnMuaWQ7XG4gICAgICBjb25zdCBheGlzID0gZGV0ZXJtaW5lQXhpcyhpZCwgc2NhbGVPcHRpb25zKTtcbiAgICAgIGNvbnN0IHNjYWxlVHlwZSA9IHZhbHVlT3JEZWZhdWx0KHNjYWxlT3B0aW9ucy50eXBlLCBpdGVtLmR0eXBlKTtcblxuICAgICAgaWYgKHNjYWxlT3B0aW9ucy5wb3NpdGlvbiA9PT0gdW5kZWZpbmVkIHx8IHBvc2l0aW9uSXNIb3Jpem9udGFsKHNjYWxlT3B0aW9ucy5wb3NpdGlvbiwgYXhpcykgIT09IHBvc2l0aW9uSXNIb3Jpem9udGFsKGl0ZW0uZHBvc2l0aW9uKSkge1xuICAgICAgICBzY2FsZU9wdGlvbnMucG9zaXRpb24gPSBpdGVtLmRwb3NpdGlvbjtcbiAgICAgIH1cblxuICAgICAgdXBkYXRlZFtpZF0gPSB0cnVlO1xuICAgICAgbGV0IHNjYWxlID0gbnVsbDtcbiAgICAgIGlmIChpZCBpbiBzY2FsZXMgJiYgc2NhbGVzW2lkXS50eXBlID09PSBzY2FsZVR5cGUpIHtcbiAgICAgICAgc2NhbGUgPSBzY2FsZXNbaWRdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgc2NhbGVDbGFzcyA9IHJlZ2lzdHJ5LmdldFNjYWxlKHNjYWxlVHlwZSk7XG4gICAgICAgIHNjYWxlID0gbmV3IHNjYWxlQ2xhc3Moe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIHR5cGU6IHNjYWxlVHlwZSxcbiAgICAgICAgICBjdHg6IHRoaXMuY3R4LFxuICAgICAgICAgIGNoYXJ0OiB0aGlzXG4gICAgICAgIH0pO1xuICAgICAgICBzY2FsZXNbc2NhbGUuaWRdID0gc2NhbGU7XG4gICAgICB9XG5cbiAgICAgIHNjYWxlLmluaXQoc2NhbGVPcHRpb25zLCBvcHRpb25zKTtcbiAgICB9KTtcbiAgICAvLyBjbGVhciB1cCBkaXNjYXJkZWQgc2NhbGVzXG4gICAgZWFjaCh1cGRhdGVkLCAoaGFzVXBkYXRlZCwgaWQpID0+IHtcbiAgICAgIGlmICghaGFzVXBkYXRlZCkge1xuICAgICAgICBkZWxldGUgc2NhbGVzW2lkXTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGVhY2goc2NhbGVzLCAoc2NhbGUpID0+IHtcbiAgICAgIGxheW91dHMuY29uZmlndXJlKHRoaXMsIHNjYWxlLCBzY2FsZS5vcHRpb25zKTtcbiAgICAgIGxheW91dHMuYWRkQm94KHRoaXMsIHNjYWxlKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3VwZGF0ZU1ldGFzZXRzKCkge1xuICAgIGNvbnN0IG1ldGFzZXRzID0gdGhpcy5fbWV0YXNldHM7XG4gICAgY29uc3QgbnVtRGF0YSA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7XG4gICAgY29uc3QgbnVtTWV0YSA9IG1ldGFzZXRzLmxlbmd0aDtcblxuICAgIG1ldGFzZXRzLnNvcnQoKGEsIGIpID0+IGEuaW5kZXggLSBiLmluZGV4KTtcbiAgICBpZiAobnVtTWV0YSA+IG51bURhdGEpIHtcbiAgICAgIGZvciAobGV0IGkgPSBudW1EYXRhOyBpIDwgbnVtTWV0YTsgKytpKSB7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3lEYXRhc2V0TWV0YShpKTtcbiAgICAgIH1cbiAgICAgIG1ldGFzZXRzLnNwbGljZShudW1EYXRhLCBudW1NZXRhIC0gbnVtRGF0YSk7XG4gICAgfVxuICAgIHRoaXMuX3NvcnRlZE1ldGFzZXRzID0gbWV0YXNldHMuc2xpY2UoMCkuc29ydChjb21wYXJlMkxldmVsKCdvcmRlcicsICdpbmRleCcpKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3JlbW92ZVVucmVmZXJlbmNlZE1ldGFzZXRzKCkge1xuICAgIGNvbnN0IHtfbWV0YXNldHM6IG1ldGFzZXRzLCBkYXRhOiB7ZGF0YXNldHN9fSA9IHRoaXM7XG4gICAgaWYgKG1ldGFzZXRzLmxlbmd0aCA+IGRhdGFzZXRzLmxlbmd0aCkge1xuICAgICAgZGVsZXRlIHRoaXMuX3N0YWNrcztcbiAgICB9XG4gICAgbWV0YXNldHMuZm9yRWFjaCgobWV0YSwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChkYXRhc2V0cy5maWx0ZXIoeCA9PiB4ID09PSBtZXRhLl9kYXRhc2V0KS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5fZGVzdHJveURhdGFzZXRNZXRhKGluZGV4KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGJ1aWxkT3JVcGRhdGVDb250cm9sbGVycygpIHtcbiAgICBjb25zdCBuZXdDb250cm9sbGVycyA9IFtdO1xuICAgIGNvbnN0IGRhdGFzZXRzID0gdGhpcy5kYXRhLmRhdGFzZXRzO1xuICAgIGxldCBpLCBpbGVuO1xuXG4gICAgdGhpcy5fcmVtb3ZlVW5yZWZlcmVuY2VkTWV0YXNldHMoKTtcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBkYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcbiAgICAgIGNvbnN0IGRhdGFzZXQgPSBkYXRhc2V0c1tpXTtcbiAgICAgIGxldCBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShpKTtcbiAgICAgIGNvbnN0IHR5cGUgPSBkYXRhc2V0LnR5cGUgfHwgdGhpcy5jb25maWcudHlwZTtcblxuICAgICAgaWYgKG1ldGEudHlwZSAmJiBtZXRhLnR5cGUgIT09IHR5cGUpIHtcbiAgICAgICAgdGhpcy5fZGVzdHJveURhdGFzZXRNZXRhKGkpO1xuICAgICAgICBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShpKTtcbiAgICAgIH1cbiAgICAgIG1ldGEudHlwZSA9IHR5cGU7XG4gICAgICBtZXRhLmluZGV4QXhpcyA9IGRhdGFzZXQuaW5kZXhBeGlzIHx8IGdldEluZGV4QXhpcyh0eXBlLCB0aGlzLm9wdGlvbnMpO1xuICAgICAgbWV0YS5vcmRlciA9IGRhdGFzZXQub3JkZXIgfHwgMDtcbiAgICAgIG1ldGEuaW5kZXggPSBpO1xuICAgICAgbWV0YS5sYWJlbCA9ICcnICsgZGF0YXNldC5sYWJlbDtcbiAgICAgIG1ldGEudmlzaWJsZSA9IHRoaXMuaXNEYXRhc2V0VmlzaWJsZShpKTtcblxuICAgICAgaWYgKG1ldGEuY29udHJvbGxlcikge1xuICAgICAgICBtZXRhLmNvbnRyb2xsZXIudXBkYXRlSW5kZXgoaSk7XG4gICAgICAgIG1ldGEuY29udHJvbGxlci5saW5rU2NhbGVzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBDb250cm9sbGVyQ2xhc3MgPSByZWdpc3RyeS5nZXRDb250cm9sbGVyKHR5cGUpO1xuICAgICAgICBjb25zdCB7ZGF0YXNldEVsZW1lbnRUeXBlLCBkYXRhRWxlbWVudFR5cGV9ID0gZGVmYXVsdHMuZGF0YXNldHNbdHlwZV07XG4gICAgICAgIE9iamVjdC5hc3NpZ24oQ29udHJvbGxlckNsYXNzLCB7XG4gICAgICAgICAgZGF0YUVsZW1lbnRUeXBlOiByZWdpc3RyeS5nZXRFbGVtZW50KGRhdGFFbGVtZW50VHlwZSksXG4gICAgICAgICAgZGF0YXNldEVsZW1lbnRUeXBlOiBkYXRhc2V0RWxlbWVudFR5cGUgJiYgcmVnaXN0cnkuZ2V0RWxlbWVudChkYXRhc2V0RWxlbWVudFR5cGUpXG4gICAgICAgIH0pO1xuICAgICAgICBtZXRhLmNvbnRyb2xsZXIgPSBuZXcgQ29udHJvbGxlckNsYXNzKHRoaXMsIGkpO1xuICAgICAgICBuZXdDb250cm9sbGVycy5wdXNoKG1ldGEuY29udHJvbGxlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlTWV0YXNldHMoKTtcbiAgICByZXR1cm4gbmV3Q29udHJvbGxlcnM7XG4gIH1cblxuICAvKipcblx0ICogUmVzZXQgdGhlIGVsZW1lbnRzIG9mIGFsbCBkYXRhc2V0c1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3Jlc2V0RWxlbWVudHMoKSB7XG4gICAgZWFjaCh0aGlzLmRhdGEuZGF0YXNldHMsIChkYXRhc2V0LCBkYXRhc2V0SW5kZXgpID0+IHtcbiAgICAgIHRoaXMuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KS5jb250cm9sbGVyLnJlc2V0KCk7XG4gICAgfSwgdGhpcyk7XG4gIH1cblxuICAvKipcblx0KiBSZXNldHMgdGhlIGNoYXJ0IGJhY2sgdG8gaXRzIHN0YXRlIGJlZm9yZSB0aGUgaW5pdGlhbCBhbmltYXRpb25cblx0Ki9cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5fcmVzZXRFbGVtZW50cygpO1xuICAgIHRoaXMubm90aWZ5UGx1Z2lucygncmVzZXQnKTtcbiAgfVxuXG4gIHVwZGF0ZShtb2RlKSB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWc7XG5cbiAgICBjb25maWcudXBkYXRlKCk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuX29wdGlvbnMgPSBjb25maWcuY3JlYXRlUmVzb2x2ZXIoY29uZmlnLmNoYXJ0T3B0aW9uU2NvcGVzKCksIHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICBjb25zdCBhbmltc0Rpc2FibGVkID0gdGhpcy5fYW5pbWF0aW9uc0Rpc2FibGVkID0gIW9wdGlvbnMuYW5pbWF0aW9uO1xuXG4gICAgdGhpcy5fdXBkYXRlU2NhbGVzKCk7XG4gICAgdGhpcy5fY2hlY2tFdmVudEJpbmRpbmdzKCk7XG4gICAgdGhpcy5fdXBkYXRlSGlkZGVuSW5kaWNlcygpO1xuXG4gICAgLy8gcGx1Z2lucyBvcHRpb25zIHJlZmVyZW5jZXMgbWlnaHQgaGF2ZSBjaGFuZ2UsIGxldCdzIGludmFsaWRhdGUgdGhlIGNhY2hlXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzUxMTEjaXNzdWVjb21tZW50LTM1NTkzNDE2N1xuICAgIHRoaXMuX3BsdWdpbnMuaW52YWxpZGF0ZSgpO1xuXG4gICAgaWYgKHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlVXBkYXRlJywge21vZGUsIGNhbmNlbGFibGU6IHRydWV9KSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBNYWtlIHN1cmUgZGF0YXNldCBjb250cm9sbGVycyBhcmUgdXBkYXRlZCBhbmQgbmV3IGNvbnRyb2xsZXJzIGFyZSByZXNldFxuICAgIGNvbnN0IG5ld0NvbnRyb2xsZXJzID0gdGhpcy5idWlsZE9yVXBkYXRlQ29udHJvbGxlcnMoKTtcblxuICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlRWxlbWVudHNVcGRhdGUnKTtcblxuICAgIC8vIE1ha2Ugc3VyZSBhbGwgZGF0YXNldCBjb250cm9sbGVycyBoYXZlIGNvcnJlY3QgbWV0YSBkYXRhIGNvdW50c1xuICAgIGxldCBtaW5QYWRkaW5nID0gMDtcbiAgICBmb3IgKGxldCBpID0gMCwgaWxlbiA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcbiAgICAgIGNvbnN0IHtjb250cm9sbGVyfSA9IHRoaXMuZ2V0RGF0YXNldE1ldGEoaSk7XG4gICAgICBjb25zdCByZXNldCA9ICFhbmltc0Rpc2FibGVkICYmIG5ld0NvbnRyb2xsZXJzLmluZGV4T2YoY29udHJvbGxlcikgPT09IC0xO1xuICAgICAgLy8gTmV3IGNvbnRyb2xsZXJzIHdpbGwgYmUgcmVzZXQgYWZ0ZXIgdGhlIGxheW91dCBwYXNzLCBzbyB3ZSBvbmx5IHdhbnQgdG8gbW9kaWZ5XG4gICAgICAvLyBlbGVtZW50cyBhZGRlZCB0byBuZXcgZGF0YXNldHNcbiAgICAgIGNvbnRyb2xsZXIuYnVpbGRPclVwZGF0ZUVsZW1lbnRzKHJlc2V0KTtcbiAgICAgIG1pblBhZGRpbmcgPSBNYXRoLm1heCgrY29udHJvbGxlci5nZXRNYXhPdmVyZmxvdygpLCBtaW5QYWRkaW5nKTtcbiAgICB9XG4gICAgbWluUGFkZGluZyA9IHRoaXMuX21pblBhZGRpbmcgPSBvcHRpb25zLmxheW91dC5hdXRvUGFkZGluZyA/IG1pblBhZGRpbmcgOiAwO1xuICAgIHRoaXMuX3VwZGF0ZUxheW91dChtaW5QYWRkaW5nKTtcblxuICAgIC8vIE9ubHkgcmVzZXQgdGhlIGNvbnRyb2xsZXJzIGlmIHdlIGhhdmUgYW5pbWF0aW9uc1xuICAgIGlmICghYW5pbXNEaXNhYmxlZCkge1xuICAgICAgLy8gQ2FuIG9ubHkgcmVzZXQgdGhlIG5ldyBjb250cm9sbGVycyBhZnRlciB0aGUgc2NhbGVzIGhhdmUgYmVlbiB1cGRhdGVkXG4gICAgICAvLyBSZXNldCBpcyBkb25lIHRvIGdldCB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yIHRoZSBpbml0aWFsIGFuaW1hdGlvblxuICAgICAgZWFjaChuZXdDb250cm9sbGVycywgKGNvbnRyb2xsZXIpID0+IHtcbiAgICAgICAgY29udHJvbGxlci5yZXNldCgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlRGF0YXNldHMobW9kZSk7XG5cbiAgICAvLyBEbyB0aGlzIGJlZm9yZSByZW5kZXIgc28gdGhhdCBhbnkgcGx1Z2lucyB0aGF0IG5lZWQgZmluYWwgc2NhbGUgdXBkYXRlcyBjYW4gdXNlIGl0XG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdhZnRlclVwZGF0ZScsIHttb2RlfSk7XG5cbiAgICB0aGlzLl9sYXllcnMuc29ydChjb21wYXJlMkxldmVsKCd6JywgJ19pZHgnKSk7XG5cbiAgICAvLyBSZXBsYXkgbGFzdCBldmVudCBmcm9tIGJlZm9yZSB1cGRhdGUsIG9yIHNldCBob3ZlciBzdHlsZXMgb24gYWN0aXZlIGVsZW1lbnRzXG4gICAgY29uc3Qge19hY3RpdmUsIF9sYXN0RXZlbnR9ID0gdGhpcztcbiAgICBpZiAoX2xhc3RFdmVudCkge1xuICAgICAgdGhpcy5fZXZlbnRIYW5kbGVyKF9sYXN0RXZlbnQsIHRydWUpO1xuICAgIH0gZWxzZSBpZiAoX2FjdGl2ZS5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZUhvdmVyU3R5bGVzKF9hY3RpdmUsIF9hY3RpdmUsIHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF91cGRhdGVTY2FsZXMoKSB7XG4gICAgZWFjaCh0aGlzLnNjYWxlcywgKHNjYWxlKSA9PiB7XG4gICAgICBsYXlvdXRzLnJlbW92ZUJveCh0aGlzLCBzY2FsZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmVuc3VyZVNjYWxlc0hhdmVJRHMoKTtcbiAgICB0aGlzLmJ1aWxkT3JVcGRhdGVTY2FsZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX2NoZWNrRXZlbnRCaW5kaW5ncygpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IGV4aXN0aW5nRXZlbnRzID0gbmV3IFNldChPYmplY3Qua2V5cyh0aGlzLl9saXN0ZW5lcnMpKTtcbiAgICBjb25zdCBuZXdFdmVudHMgPSBuZXcgU2V0KG9wdGlvbnMuZXZlbnRzKTtcblxuICAgIGlmICghc2V0c0VxdWFsKGV4aXN0aW5nRXZlbnRzLCBuZXdFdmVudHMpIHx8ICEhdGhpcy5fcmVzcG9uc2l2ZUxpc3RlbmVycyAhPT0gb3B0aW9ucy5yZXNwb25zaXZlKSB7XG4gICAgICAvLyBUaGUgY29uZmlndXJlZCBldmVudHMgaGF2ZSBjaGFuZ2VkLiBSZWJpbmQuXG4gICAgICB0aGlzLnVuYmluZEV2ZW50cygpO1xuICAgICAgdGhpcy5iaW5kRXZlbnRzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBfdXBkYXRlSGlkZGVuSW5kaWNlcygpIHtcbiAgICBjb25zdCB7X2hpZGRlbkluZGljZXN9ID0gdGhpcztcbiAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5fZ2V0VW5pZm9ybURhdGFDaGFuZ2VzKCkgfHwgW107XG4gICAgZm9yIChjb25zdCB7bWV0aG9kLCBzdGFydCwgY291bnR9IG9mIGNoYW5nZXMpIHtcbiAgICAgIGNvbnN0IG1vdmUgPSBtZXRob2QgPT09ICdfcmVtb3ZlRWxlbWVudHMnID8gLWNvdW50IDogY291bnQ7XG4gICAgICBtb3ZlTnVtZXJpY0tleXMoX2hpZGRlbkluZGljZXMsIHN0YXJ0LCBtb3ZlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9nZXRVbmlmb3JtRGF0YUNoYW5nZXMoKSB7XG4gICAgY29uc3QgX2RhdGFDaGFuZ2VzID0gdGhpcy5fZGF0YUNoYW5nZXM7XG4gICAgaWYgKCFfZGF0YUNoYW5nZXMgfHwgIV9kYXRhQ2hhbmdlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9kYXRhQ2hhbmdlcyA9IFtdO1xuICAgIGNvbnN0IGRhdGFzZXRDb3VudCA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7XG4gICAgY29uc3QgbWFrZVNldCA9IChpZHgpID0+IG5ldyBTZXQoXG4gICAgICBfZGF0YUNoYW5nZXNcbiAgICAgICAgLmZpbHRlcihjID0+IGNbMF0gPT09IGlkeClcbiAgICAgICAgLm1hcCgoYywgaSkgPT4gaSArICcsJyArIGMuc3BsaWNlKDEpLmpvaW4oJywnKSlcbiAgICApO1xuXG4gICAgY29uc3QgY2hhbmdlU2V0ID0gbWFrZVNldCgwKTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IGRhdGFzZXRDb3VudDsgaSsrKSB7XG4gICAgICBpZiAoIXNldHNFcXVhbChjaGFuZ2VTZXQsIG1ha2VTZXQoaSkpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIEFycmF5LmZyb20oY2hhbmdlU2V0KVxuICAgICAgLm1hcChjID0+IGMuc3BsaXQoJywnKSlcbiAgICAgIC5tYXAoYSA9PiAoe21ldGhvZDogYVsxXSwgc3RhcnQ6ICthWzJdLCBjb3VudDogK2FbM119KSk7XG4gIH1cblxuICAvKipcblx0ICogVXBkYXRlcyB0aGUgY2hhcnQgbGF5b3V0IHVubGVzcyBhIHBsdWdpbiByZXR1cm5zIGBmYWxzZWAgdG8gdGhlIGBiZWZvcmVMYXlvdXRgXG5cdCAqIGhvb2ssIGluIHdoaWNoIGNhc2UsIHBsdWdpbnMgd2lsbCBub3QgYmUgY2FsbGVkIG9uIGBhZnRlckxheW91dGAuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdXBkYXRlTGF5b3V0KG1pblBhZGRpbmcpIHtcbiAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVMYXlvdXQnLCB7Y2FuY2VsYWJsZTogdHJ1ZX0pID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxheW91dHMudXBkYXRlKHRoaXMsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0LCBtaW5QYWRkaW5nKTtcblxuICAgIGNvbnN0IGFyZWEgPSB0aGlzLmNoYXJ0QXJlYTtcbiAgICBjb25zdCBub0FyZWEgPSBhcmVhLndpZHRoIDw9IDAgfHwgYXJlYS5oZWlnaHQgPD0gMDtcblxuICAgIHRoaXMuX2xheWVycyA9IFtdO1xuICAgIGVhY2godGhpcy5ib3hlcywgKGJveCkgPT4ge1xuICAgICAgaWYgKG5vQXJlYSAmJiBib3gucG9zaXRpb24gPT09ICdjaGFydEFyZWEnKSB7XG4gICAgICAgIC8vIFNraXAgZHJhd2luZyBhbmQgY29uZmlndXJpbmcgY2hhcnRBcmVhIGJveGVzIHdoZW4gY2hhcnRBcmVhIGlzIHplcm8gb3IgbmVnYXRpdmVcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBjb25maWd1cmUgaXMgY2FsbGVkIHR3aWNlLCBvbmNlIGluIGNvcmUuc2NhbGUudXBkYXRlIGFuZCBvbmNlIGhlcmUuXG4gICAgICAvLyBIZXJlIHRoZSBib3hlcyBhcmUgZnVsbHkgdXBkYXRlZCBhbmQgYXQgdGhlaXIgZmluYWwgcG9zaXRpb25zLlxuICAgICAgaWYgKGJveC5jb25maWd1cmUpIHtcbiAgICAgICAgYm94LmNvbmZpZ3VyZSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5fbGF5ZXJzLnB1c2goLi4uYm94Ll9sYXllcnMoKSk7XG4gICAgfSwgdGhpcyk7XG5cbiAgICB0aGlzLl9sYXllcnMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgIGl0ZW0uX2lkeCA9IGluZGV4O1xuICAgIH0pO1xuXG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdhZnRlckxheW91dCcpO1xuICB9XG5cbiAgLyoqXG5cdCAqIFVwZGF0ZXMgYWxsIGRhdGFzZXRzIHVubGVzcyBhIHBsdWdpbiByZXR1cm5zIGBmYWxzZWAgdG8gdGhlIGBiZWZvcmVEYXRhc2V0c1VwZGF0ZWBcblx0ICogaG9vaywgaW4gd2hpY2ggY2FzZSwgcGx1Z2lucyB3aWxsIG5vdCBiZSBjYWxsZWQgb24gYGFmdGVyRGF0YXNldHNVcGRhdGVgLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3VwZGF0ZURhdGFzZXRzKG1vZGUpIHtcbiAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVEYXRhc2V0c1VwZGF0ZScsIHttb2RlLCBjYW5jZWxhYmxlOiB0cnVlfSkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDAsIGlsZW4gPSB0aGlzLmRhdGEuZGF0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICB0aGlzLmdldERhdGFzZXRNZXRhKGkpLmNvbnRyb2xsZXIuY29uZmlndXJlKCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDAsIGlsZW4gPSB0aGlzLmRhdGEuZGF0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICB0aGlzLl91cGRhdGVEYXRhc2V0KGksIGlzRnVuY3Rpb24obW9kZSkgPyBtb2RlKHtkYXRhc2V0SW5kZXg6IGl9KSA6IG1vZGUpO1xuICAgIH1cblxuICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJEYXRhc2V0c1VwZGF0ZScsIHttb2RlfSk7XG4gIH1cblxuICAvKipcblx0ICogVXBkYXRlcyBkYXRhc2V0IGF0IGluZGV4IHVubGVzcyBhIHBsdWdpbiByZXR1cm5zIGBmYWxzZWAgdG8gdGhlIGBiZWZvcmVEYXRhc2V0VXBkYXRlYFxuXHQgKiBob29rLCBpbiB3aGljaCBjYXNlLCBwbHVnaW5zIHdpbGwgbm90IGJlIGNhbGxlZCBvbiBgYWZ0ZXJEYXRhc2V0VXBkYXRlYC5cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF91cGRhdGVEYXRhc2V0KGluZGV4LCBtb2RlKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuZ2V0RGF0YXNldE1ldGEoaW5kZXgpO1xuICAgIGNvbnN0IGFyZ3MgPSB7bWV0YSwgaW5kZXgsIG1vZGUsIGNhbmNlbGFibGU6IHRydWV9O1xuXG4gICAgaWYgKHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlRGF0YXNldFVwZGF0ZScsIGFyZ3MpID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG1ldGEuY29udHJvbGxlci5fdXBkYXRlKG1vZGUpO1xuXG4gICAgYXJncy5jYW5jZWxhYmxlID0gZmFsc2U7XG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdhZnRlckRhdGFzZXRVcGRhdGUnLCBhcmdzKTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVSZW5kZXInLCB7Y2FuY2VsYWJsZTogdHJ1ZX0pID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChhbmltYXRvci5oYXModGhpcykpIHtcbiAgICAgIGlmICh0aGlzLmF0dGFjaGVkICYmICFhbmltYXRvci5ydW5uaW5nKHRoaXMpKSB7XG4gICAgICAgIGFuaW1hdG9yLnN0YXJ0KHRoaXMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRyYXcoKTtcbiAgICAgIG9uQW5pbWF0aW9uc0NvbXBsZXRlKHtjaGFydDogdGhpc30pO1xuICAgIH1cbiAgfVxuXG4gIGRyYXcoKSB7XG4gICAgbGV0IGk7XG4gICAgaWYgKHRoaXMuX3Jlc2l6ZUJlZm9yZURyYXcpIHtcbiAgICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0fSA9IHRoaXMuX3Jlc2l6ZUJlZm9yZURyYXc7XG4gICAgICB0aGlzLl9yZXNpemUod2lkdGgsIGhlaWdodCk7XG4gICAgICB0aGlzLl9yZXNpemVCZWZvcmVEcmF3ID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5jbGVhcigpO1xuXG4gICAgaWYgKHRoaXMud2lkdGggPD0gMCB8fCB0aGlzLmhlaWdodCA8PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlRHJhdycsIHtjYW5jZWxhYmxlOiB0cnVlfSkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQmVjYXVzZSBvZiBwbHVnaW4gaG9va3MgKGJlZm9yZS9hZnRlckRhdGFzZXRzRHJhdyksIGRhdGFzZXRzIGNhbid0XG4gICAgLy8gY3VycmVudGx5IGJlIHBhcnQgb2YgbGF5ZXJzLiBJbnN0ZWFkLCB3ZSBkcmF3XG4gICAgLy8gbGF5ZXJzIDw9IDAgYmVmb3JlKGRlZmF1bHQsIGJhY2t3YXJkIGNvbXBhdCksIGFuZCB0aGUgcmVzdCBhZnRlclxuICAgIGNvbnN0IGxheWVycyA9IHRoaXMuX2xheWVycztcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGF5ZXJzLmxlbmd0aCAmJiBsYXllcnNbaV0ueiA8PSAwOyArK2kpIHtcbiAgICAgIGxheWVyc1tpXS5kcmF3KHRoaXMuY2hhcnRBcmVhKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kcmF3RGF0YXNldHMoKTtcblxuICAgIC8vIFJlc3Qgb2YgbGF5ZXJzXG4gICAgZm9yICg7IGkgPCBsYXllcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxheWVyc1tpXS5kcmF3KHRoaXMuY2hhcnRBcmVhKTtcbiAgICB9XG5cbiAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyRHJhdycpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0U29ydGVkRGF0YXNldE1ldGFzKGZpbHRlclZpc2libGUpIHtcbiAgICBjb25zdCBtZXRhc2V0cyA9IHRoaXMuX3NvcnRlZE1ldGFzZXRzO1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIGxldCBpLCBpbGVuO1xuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IG1ldGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgY29uc3QgbWV0YSA9IG1ldGFzZXRzW2ldO1xuICAgICAgaWYgKCFmaWx0ZXJWaXNpYmxlIHx8IG1ldGEudmlzaWJsZSkge1xuICAgICAgICByZXN1bHQucHVzaChtZXRhKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG5cdCAqIEdldHMgdGhlIHZpc2libGUgZGF0YXNldCBtZXRhcyBpbiBkcmF3aW5nIG9yZGVyXG5cdCAqIEByZXR1cm4ge29iamVjdFtdfVxuXHQgKi9cbiAgZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0U29ydGVkRGF0YXNldE1ldGFzKHRydWUpO1xuICB9XG5cbiAgLyoqXG5cdCAqIERyYXdzIGFsbCBkYXRhc2V0cyB1bmxlc3MgYSBwbHVnaW4gcmV0dXJucyBgZmFsc2VgIHRvIHRoZSBgYmVmb3JlRGF0YXNldHNEcmF3YFxuXHQgKiBob29rLCBpbiB3aGljaCBjYXNlLCBwbHVnaW5zIHdpbGwgbm90IGJlIGNhbGxlZCBvbiBgYWZ0ZXJEYXRhc2V0c0RyYXdgLlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2RyYXdEYXRhc2V0cygpIHtcbiAgICBpZiAodGhpcy5ub3RpZnlQbHVnaW5zKCdiZWZvcmVEYXRhc2V0c0RyYXcnLCB7Y2FuY2VsYWJsZTogdHJ1ZX0pID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG1ldGFzZXRzID0gdGhpcy5nZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCk7XG4gICAgZm9yIChsZXQgaSA9IG1ldGFzZXRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0aGlzLl9kcmF3RGF0YXNldChtZXRhc2V0c1tpXSk7XG4gICAgfVxuXG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdhZnRlckRhdGFzZXRzRHJhdycpO1xuICB9XG5cbiAgLyoqXG5cdCAqIERyYXdzIGRhdGFzZXQgYXQgaW5kZXggdW5sZXNzIGEgcGx1Z2luIHJldHVybnMgYGZhbHNlYCB0byB0aGUgYGJlZm9yZURhdGFzZXREcmF3YFxuXHQgKiBob29rLCBpbiB3aGljaCBjYXNlLCBwbHVnaW5zIHdpbGwgbm90IGJlIGNhbGxlZCBvbiBgYWZ0ZXJEYXRhc2V0RHJhd2AuXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZHJhd0RhdGFzZXQobWV0YSkge1xuICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgIGNvbnN0IGNsaXAgPSBtZXRhLl9jbGlwO1xuICAgIGNvbnN0IHVzZUNsaXAgPSAhY2xpcC5kaXNhYmxlZDtcbiAgICBjb25zdCBhcmVhID0gZ2V0RGF0YXNldEFyZWEobWV0YSwgdGhpcy5jaGFydEFyZWEpO1xuICAgIGNvbnN0IGFyZ3MgPSB7XG4gICAgICBtZXRhLFxuICAgICAgaW5kZXg6IG1ldGEuaW5kZXgsXG4gICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgfTtcblxuICAgIGlmICh0aGlzLm5vdGlmeVBsdWdpbnMoJ2JlZm9yZURhdGFzZXREcmF3JywgYXJncykgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHVzZUNsaXApIHtcbiAgICAgIGNsaXBBcmVhKGN0eCwge1xuICAgICAgICBsZWZ0OiBjbGlwLmxlZnQgPT09IGZhbHNlID8gMCA6IGFyZWEubGVmdCAtIGNsaXAubGVmdCxcbiAgICAgICAgcmlnaHQ6IGNsaXAucmlnaHQgPT09IGZhbHNlID8gdGhpcy53aWR0aCA6IGFyZWEucmlnaHQgKyBjbGlwLnJpZ2h0LFxuICAgICAgICB0b3A6IGNsaXAudG9wID09PSBmYWxzZSA/IDAgOiBhcmVhLnRvcCAtIGNsaXAudG9wLFxuICAgICAgICBib3R0b206IGNsaXAuYm90dG9tID09PSBmYWxzZSA/IHRoaXMuaGVpZ2h0IDogYXJlYS5ib3R0b20gKyBjbGlwLmJvdHRvbVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbWV0YS5jb250cm9sbGVyLmRyYXcoKTtcblxuICAgIGlmICh1c2VDbGlwKSB7XG4gICAgICB1bmNsaXBBcmVhKGN0eCk7XG4gICAgfVxuXG4gICAgYXJncy5jYW5jZWxhYmxlID0gZmFsc2U7XG4gICAgdGhpcy5ub3RpZnlQbHVnaW5zKCdhZnRlckRhdGFzZXREcmF3JywgYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIHBvaW50IGlzIGluIHRoZSBjaGFydCBhcmVhLlxuICAgKiBAcGFyYW0ge1BvaW50fSBwb2ludCAtIGluIHJlbGF0aXZlIGNvb3JkaW5hdGVzIChzZWUsIGUuZy4sIGdldFJlbGF0aXZlUG9zaXRpb24pXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgaXNQb2ludEluQXJlYShwb2ludCkge1xuICAgIHJldHVybiBfaXNQb2ludEluQXJlYShwb2ludCwgdGhpcy5jaGFydEFyZWEsIHRoaXMuX21pblBhZGRpbmcpO1xuICB9XG5cbiAgZ2V0RWxlbWVudHNBdEV2ZW50Rm9yTW9kZShlLCBtb2RlLCBvcHRpb25zLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgY29uc3QgbWV0aG9kID0gSW50ZXJhY3Rpb24ubW9kZXNbbW9kZV07XG4gICAgaWYgKHR5cGVvZiBtZXRob2QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBtZXRob2QodGhpcywgZSwgb3B0aW9ucywgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KSB7XG4gICAgY29uc3QgZGF0YXNldCA9IHRoaXMuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdO1xuICAgIGNvbnN0IG1ldGFzZXRzID0gdGhpcy5fbWV0YXNldHM7XG4gICAgbGV0IG1ldGEgPSBtZXRhc2V0cy5maWx0ZXIoeCA9PiB4ICYmIHguX2RhdGFzZXQgPT09IGRhdGFzZXQpLnBvcCgpO1xuXG4gICAgaWYgKCFtZXRhKSB7XG4gICAgICBtZXRhID0ge1xuICAgICAgICB0eXBlOiBudWxsLFxuICAgICAgICBkYXRhOiBbXSxcbiAgICAgICAgZGF0YXNldDogbnVsbCxcbiAgICAgICAgY29udHJvbGxlcjogbnVsbCxcbiAgICAgICAgaGlkZGVuOiBudWxsLFx0XHRcdC8vIFNlZSBpc0RhdGFzZXRWaXNpYmxlKCkgY29tbWVudFxuICAgICAgICB4QXhpc0lEOiBudWxsLFxuICAgICAgICB5QXhpc0lEOiBudWxsLFxuICAgICAgICBvcmRlcjogZGF0YXNldCAmJiBkYXRhc2V0Lm9yZGVyIHx8IDAsXG4gICAgICAgIGluZGV4OiBkYXRhc2V0SW5kZXgsXG4gICAgICAgIF9kYXRhc2V0OiBkYXRhc2V0LFxuICAgICAgICBfcGFyc2VkOiBbXSxcbiAgICAgICAgX3NvcnRlZDogZmFsc2VcbiAgICAgIH07XG4gICAgICBtZXRhc2V0cy5wdXNoKG1ldGEpO1xuICAgIH1cblxuICAgIHJldHVybiBtZXRhO1xuICB9XG5cbiAgZ2V0Q29udGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy4kY29udGV4dCB8fCAodGhpcy4kY29udGV4dCA9IGNyZWF0ZUNvbnRleHQobnVsbCwge2NoYXJ0OiB0aGlzLCB0eXBlOiAnY2hhcnQnfSkpO1xuICB9XG5cbiAgZ2V0VmlzaWJsZURhdGFzZXRDb3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCkubGVuZ3RoO1xuICB9XG5cbiAgaXNEYXRhc2V0VmlzaWJsZShkYXRhc2V0SW5kZXgpIHtcbiAgICBjb25zdCBkYXRhc2V0ID0gdGhpcy5kYXRhLmRhdGFzZXRzW2RhdGFzZXRJbmRleF07XG4gICAgaWYgKCFkYXRhc2V0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgbWV0YSA9IHRoaXMuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcblxuICAgIC8vIG1ldGEuaGlkZGVuIGlzIGEgcGVyIGNoYXJ0IGRhdGFzZXQgaGlkZGVuIGZsYWcgb3ZlcnJpZGUgd2l0aCAzIHN0YXRlczogaWYgdHJ1ZSBvciBmYWxzZSxcbiAgICAvLyB0aGUgZGF0YXNldC5oaWRkZW4gdmFsdWUgaXMgaWdub3JlZCwgZWxzZSBpZiBudWxsLCB0aGUgZGF0YXNldCBoaWRkZW4gc3RhdGUgaXMgcmV0dXJuZWQuXG4gICAgcmV0dXJuIHR5cGVvZiBtZXRhLmhpZGRlbiA9PT0gJ2Jvb2xlYW4nID8gIW1ldGEuaGlkZGVuIDogIWRhdGFzZXQuaGlkZGVuO1xuICB9XG5cbiAgc2V0RGF0YXNldFZpc2liaWxpdHkoZGF0YXNldEluZGV4LCB2aXNpYmxlKSB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcbiAgICBtZXRhLmhpZGRlbiA9ICF2aXNpYmxlO1xuICB9XG5cbiAgdG9nZ2xlRGF0YVZpc2liaWxpdHkoaW5kZXgpIHtcbiAgICB0aGlzLl9oaWRkZW5JbmRpY2VzW2luZGV4XSA9ICF0aGlzLl9oaWRkZW5JbmRpY2VzW2luZGV4XTtcbiAgfVxuXG4gIGdldERhdGFWaXNpYmlsaXR5KGluZGV4KSB7XG4gICAgcmV0dXJuICF0aGlzLl9oaWRkZW5JbmRpY2VzW2luZGV4XTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3VwZGF0ZVZpc2liaWxpdHkoZGF0YXNldEluZGV4LCBkYXRhSW5kZXgsIHZpc2libGUpIHtcbiAgICBjb25zdCBtb2RlID0gdmlzaWJsZSA/ICdzaG93JyA6ICdoaWRlJztcbiAgICBjb25zdCBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xuICAgIGNvbnN0IGFuaW1zID0gbWV0YS5jb250cm9sbGVyLl9yZXNvbHZlQW5pbWF0aW9ucyh1bmRlZmluZWQsIG1vZGUpO1xuXG4gICAgaWYgKGRlZmluZWQoZGF0YUluZGV4KSkge1xuICAgICAgbWV0YS5kYXRhW2RhdGFJbmRleF0uaGlkZGVuID0gIXZpc2libGU7XG4gICAgICB0aGlzLnVwZGF0ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldERhdGFzZXRWaXNpYmlsaXR5KGRhdGFzZXRJbmRleCwgdmlzaWJsZSk7XG4gICAgICAvLyBBbmltYXRlIHZpc2libGUgc3RhdGUsIHNvIGhpZGUgYW5pbWF0aW9uIGNhbiBiZSBzZWVuLiBUaGlzIGNvdWxkIGJlIGhhbmRsZWQgYmV0dGVyIGlmIHVwZGF0ZSAvIHVwZGF0ZURhdGFzZXQgcmV0dXJuZWQgYSBQcm9taXNlLlxuICAgICAgYW5pbXMudXBkYXRlKG1ldGEsIHt2aXNpYmxlfSk7XG4gICAgICB0aGlzLnVwZGF0ZSgoY3R4KSA9PiBjdHguZGF0YXNldEluZGV4ID09PSBkYXRhc2V0SW5kZXggPyBtb2RlIDogdW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cblxuICBoaWRlKGRhdGFzZXRJbmRleCwgZGF0YUluZGV4KSB7XG4gICAgdGhpcy5fdXBkYXRlVmlzaWJpbGl0eShkYXRhc2V0SW5kZXgsIGRhdGFJbmRleCwgZmFsc2UpO1xuICB9XG5cbiAgc2hvdyhkYXRhc2V0SW5kZXgsIGRhdGFJbmRleCkge1xuICAgIHRoaXMuX3VwZGF0ZVZpc2liaWxpdHkoZGF0YXNldEluZGV4LCBkYXRhSW5kZXgsIHRydWUpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZGVzdHJveURhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCkge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLl9tZXRhc2V0c1tkYXRhc2V0SW5kZXhdO1xuICAgIGlmIChtZXRhICYmIG1ldGEuY29udHJvbGxlcikge1xuICAgICAgbWV0YS5jb250cm9sbGVyLl9kZXN0cm95KCk7XG4gICAgfVxuICAgIGRlbGV0ZSB0aGlzLl9tZXRhc2V0c1tkYXRhc2V0SW5kZXhdO1xuICB9XG5cbiAgX3N0b3AoKSB7XG4gICAgbGV0IGksIGlsZW47XG4gICAgdGhpcy5zdG9wKCk7XG4gICAgYW5pbWF0b3IucmVtb3ZlKHRoaXMpO1xuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHRoaXMuX2Rlc3Ryb3lEYXRhc2V0TWV0YShpKTtcbiAgICB9XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlRGVzdHJveScpO1xuICAgIGNvbnN0IHtjYW52YXMsIGN0eH0gPSB0aGlzO1xuXG4gICAgdGhpcy5fc3RvcCgpO1xuICAgIHRoaXMuY29uZmlnLmNsZWFyQ2FjaGUoKTtcblxuICAgIGlmIChjYW52YXMpIHtcbiAgICAgIHRoaXMudW5iaW5kRXZlbnRzKCk7XG4gICAgICBjbGVhckNhbnZhcyhjYW52YXMsIGN0eCk7XG4gICAgICB0aGlzLnBsYXRmb3JtLnJlbGVhc2VDb250ZXh0KGN0eCk7XG4gICAgICB0aGlzLmNhbnZhcyA9IG51bGw7XG4gICAgICB0aGlzLmN0eCA9IG51bGw7XG4gICAgfVxuXG4gICAgZGVsZXRlIGluc3RhbmNlc1t0aGlzLmlkXTtcblxuICAgIHRoaXMubm90aWZ5UGx1Z2lucygnYWZ0ZXJEZXN0cm95Jyk7XG4gIH1cblxuICB0b0Jhc2U2NEltYWdlKC4uLmFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXMudG9EYXRhVVJMKC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBiaW5kRXZlbnRzKCkge1xuICAgIHRoaXMuYmluZFVzZXJFdmVudHMoKTtcbiAgICBpZiAodGhpcy5vcHRpb25zLnJlc3BvbnNpdmUpIHtcbiAgICAgIHRoaXMuYmluZFJlc3BvbnNpdmVFdmVudHMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hdHRhY2hlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBiaW5kVXNlckV2ZW50cygpIHtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XG4gICAgY29uc3QgcGxhdGZvcm0gPSB0aGlzLnBsYXRmb3JtO1xuXG4gICAgY29uc3QgX2FkZCA9ICh0eXBlLCBsaXN0ZW5lcikgPT4ge1xuICAgICAgcGxhdGZvcm0uYWRkRXZlbnRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lcik7XG4gICAgICBsaXN0ZW5lcnNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICB9O1xuXG4gICAgY29uc3QgbGlzdGVuZXIgPSAoZSwgeCwgeSkgPT4ge1xuICAgICAgZS5vZmZzZXRYID0geDtcbiAgICAgIGUub2Zmc2V0WSA9IHk7XG4gICAgICB0aGlzLl9ldmVudEhhbmRsZXIoZSk7XG4gICAgfTtcblxuICAgIGVhY2godGhpcy5vcHRpb25zLmV2ZW50cywgKHR5cGUpID0+IF9hZGQodHlwZSwgbGlzdGVuZXIpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgYmluZFJlc3BvbnNpdmVFdmVudHMoKSB7XG4gICAgaWYgKCF0aGlzLl9yZXNwb25zaXZlTGlzdGVuZXJzKSB7XG4gICAgICB0aGlzLl9yZXNwb25zaXZlTGlzdGVuZXJzID0ge307XG4gICAgfVxuICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuX3Jlc3BvbnNpdmVMaXN0ZW5lcnM7XG4gICAgY29uc3QgcGxhdGZvcm0gPSB0aGlzLnBsYXRmb3JtO1xuXG4gICAgY29uc3QgX2FkZCA9ICh0eXBlLCBsaXN0ZW5lcikgPT4ge1xuICAgICAgcGxhdGZvcm0uYWRkRXZlbnRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lcik7XG4gICAgICBsaXN0ZW5lcnNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICB9O1xuICAgIGNvbnN0IF9yZW1vdmUgPSAodHlwZSwgbGlzdGVuZXIpID0+IHtcbiAgICAgIGlmIChsaXN0ZW5lcnNbdHlwZV0pIHtcbiAgICAgICAgcGxhdGZvcm0ucmVtb3ZlRXZlbnRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lcik7XG4gICAgICAgIGRlbGV0ZSBsaXN0ZW5lcnNbdHlwZV07XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IGxpc3RlbmVyID0gKHdpZHRoLCBoZWlnaHQpID0+IHtcbiAgICAgIGlmICh0aGlzLmNhbnZhcykge1xuICAgICAgICB0aGlzLnJlc2l6ZSh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgbGV0IGRldGFjaGVkOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHByZWZlci1jb25zdFxuICAgIGNvbnN0IGF0dGFjaGVkID0gKCkgPT4ge1xuICAgICAgX3JlbW92ZSgnYXR0YWNoJywgYXR0YWNoZWQpO1xuXG4gICAgICB0aGlzLmF0dGFjaGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMucmVzaXplKCk7XG5cbiAgICAgIF9hZGQoJ3Jlc2l6ZScsIGxpc3RlbmVyKTtcbiAgICAgIF9hZGQoJ2RldGFjaCcsIGRldGFjaGVkKTtcbiAgICB9O1xuXG4gICAgZGV0YWNoZWQgPSAoKSA9PiB7XG4gICAgICB0aGlzLmF0dGFjaGVkID0gZmFsc2U7XG5cbiAgICAgIF9yZW1vdmUoJ3Jlc2l6ZScsIGxpc3RlbmVyKTtcblxuICAgICAgLy8gU3RvcCBhbmltYXRpbmcgYW5kIHJlbW92ZSBtZXRhc2V0cywgc28gd2hlbiByZS1hdHRhY2hlZCwgdGhlIGFuaW1hdGlvbnMgc3RhcnQgZnJvbSBiZWdpbm5pbmcuXG4gICAgICB0aGlzLl9zdG9wKCk7XG4gICAgICB0aGlzLl9yZXNpemUoMCwgMCk7XG5cbiAgICAgIF9hZGQoJ2F0dGFjaCcsIGF0dGFjaGVkKTtcbiAgICB9O1xuXG4gICAgaWYgKHBsYXRmb3JtLmlzQXR0YWNoZWQodGhpcy5jYW52YXMpKSB7XG4gICAgICBhdHRhY2hlZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZXRhY2hlZCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgdW5iaW5kRXZlbnRzKCkge1xuICAgIGVhY2godGhpcy5fbGlzdGVuZXJzLCAobGlzdGVuZXIsIHR5cGUpID0+IHtcbiAgICAgIHRoaXMucGxhdGZvcm0ucmVtb3ZlRXZlbnRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lcik7XG4gICAgfSk7XG4gICAgdGhpcy5fbGlzdGVuZXJzID0ge307XG5cbiAgICBlYWNoKHRoaXMuX3Jlc3BvbnNpdmVMaXN0ZW5lcnMsIChsaXN0ZW5lciwgdHlwZSkgPT4ge1xuICAgICAgdGhpcy5wbGF0Zm9ybS5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyKTtcbiAgICB9KTtcbiAgICB0aGlzLl9yZXNwb25zaXZlTGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgdXBkYXRlSG92ZXJTdHlsZShpdGVtcywgbW9kZSwgZW5hYmxlZCkge1xuICAgIGNvbnN0IHByZWZpeCA9IGVuYWJsZWQgPyAnc2V0JyA6ICdyZW1vdmUnO1xuICAgIGxldCBtZXRhLCBpdGVtLCBpLCBpbGVuO1xuXG4gICAgaWYgKG1vZGUgPT09ICdkYXRhc2V0Jykge1xuICAgICAgbWV0YSA9IHRoaXMuZ2V0RGF0YXNldE1ldGEoaXRlbXNbMF0uZGF0YXNldEluZGV4KTtcbiAgICAgIG1ldGEuY29udHJvbGxlclsnXycgKyBwcmVmaXggKyAnRGF0YXNldEhvdmVyU3R5bGUnXSgpO1xuICAgIH1cblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSBpdGVtcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIGl0ZW0gPSBpdGVtc1tpXTtcbiAgICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBpdGVtICYmIHRoaXMuZ2V0RGF0YXNldE1ldGEoaXRlbS5kYXRhc2V0SW5kZXgpLmNvbnRyb2xsZXI7XG4gICAgICBpZiAoY29udHJvbGxlcikge1xuICAgICAgICBjb250cm9sbGVyW3ByZWZpeCArICdIb3ZlclN0eWxlJ10oaXRlbS5lbGVtZW50LCBpdGVtLmRhdGFzZXRJbmRleCwgaXRlbS5pbmRleCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEdldCBhY3RpdmUgKGhvdmVyZWQpIGVsZW1lbnRzXG5cdCAqIEByZXR1cm5zIGFycmF5XG5cdCAqL1xuICBnZXRBY3RpdmVFbGVtZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy5fYWN0aXZlIHx8IFtdO1xuICB9XG5cbiAgLyoqXG5cdCAqIFNldCBhY3RpdmUgKGhvdmVyZWQpIGVsZW1lbnRzXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGFjdGl2ZUVsZW1lbnRzIE5ldyBhY3RpdmUgZGF0YSBwb2ludHNcblx0ICovXG4gIHNldEFjdGl2ZUVsZW1lbnRzKGFjdGl2ZUVsZW1lbnRzKSB7XG4gICAgY29uc3QgbGFzdEFjdGl2ZSA9IHRoaXMuX2FjdGl2ZSB8fCBbXTtcbiAgICBjb25zdCBhY3RpdmUgPSBhY3RpdmVFbGVtZW50cy5tYXAoKHtkYXRhc2V0SW5kZXgsIGluZGV4fSkgPT4ge1xuICAgICAgY29uc3QgbWV0YSA9IHRoaXMuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcbiAgICAgIGlmICghbWV0YSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGRhdGFzZXQgZm91bmQgYXQgaW5kZXggJyArIGRhdGFzZXRJbmRleCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGFzZXRJbmRleCxcbiAgICAgICAgZWxlbWVudDogbWV0YS5kYXRhW2luZGV4XSxcbiAgICAgICAgaW5kZXgsXG4gICAgICB9O1xuICAgIH0pO1xuICAgIGNvbnN0IGNoYW5nZWQgPSAhX2VsZW1lbnRzRXF1YWwoYWN0aXZlLCBsYXN0QWN0aXZlKTtcblxuICAgIGlmIChjaGFuZ2VkKSB7XG4gICAgICB0aGlzLl9hY3RpdmUgPSBhY3RpdmU7XG4gICAgICAvLyBNYWtlIHN1cmUgd2UgZG9uJ3QgdXNlIHRoZSBwcmV2aW91cyBtb3VzZSBldmVudCB0byBvdmVycmlkZSB0aGUgYWN0aXZlIGVsZW1lbnRzIGluIHVwZGF0ZS5cbiAgICAgIHRoaXMuX2xhc3RFdmVudCA9IG51bGw7XG4gICAgICB0aGlzLl91cGRhdGVIb3ZlclN0eWxlcyhhY3RpdmUsIGxhc3RBY3RpdmUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBDYWxscyBlbmFibGVkIHBsdWdpbnMgb24gdGhlIHNwZWNpZmllZCBob29rIGFuZCB3aXRoIHRoZSBnaXZlbiBhcmdzLlxuXHQgKiBUaGlzIG1ldGhvZCBpbW1lZGlhdGVseSByZXR1cm5zIGFzIHNvb24gYXMgYSBwbHVnaW4gZXhwbGljaXRseSByZXR1cm5zIGZhbHNlLiBUaGVcblx0ICogcmV0dXJuZWQgdmFsdWUgY2FuIGJlIHVzZWQsIGZvciBpbnN0YW5jZSwgdG8gaW50ZXJydXB0IHRoZSBjdXJyZW50IGFjdGlvbi5cblx0ICogQHBhcmFtIHtzdHJpbmd9IGhvb2sgLSBUaGUgbmFtZSBvZiB0aGUgcGx1Z2luIG1ldGhvZCB0byBjYWxsIChlLmcuICdiZWZvcmVVcGRhdGUnKS5cblx0ICogQHBhcmFtIHtPYmplY3R9IFthcmdzXSAtIEV4dHJhIGFyZ3VtZW50cyB0byBhcHBseSB0byB0aGUgaG9vayBjYWxsLlxuICAgKiBAcGFyYW0ge2ltcG9ydCgnLi9jb3JlLnBsdWdpbnMuanMnKS5maWx0ZXJDYWxsYmFja30gW2ZpbHRlcl0gLSBGaWx0ZXJpbmcgZnVuY3Rpb24gZm9yIGxpbWl0aW5nIHdoaWNoIHBsdWdpbnMgYXJlIG5vdGlmaWVkXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBmYWxzZSBpZiBhbnkgb2YgdGhlIHBsdWdpbnMgcmV0dXJuIGZhbHNlLCBlbHNlIHJldHVybnMgdHJ1ZS5cblx0ICovXG4gIG5vdGlmeVBsdWdpbnMoaG9vaywgYXJncywgZmlsdGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BsdWdpbnMubm90aWZ5KHRoaXMsIGhvb2ssIGFyZ3MsIGZpbHRlcik7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBwbHVnaW4gd2l0aCB0aGUgc3BlY2lmaWMgSUQgaXMgcmVnaXN0ZXJlZCBhbmQgZW5hYmxlZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGx1Z2luSWQgLSBUaGUgSUQgb2YgdGhlIHBsdWdpbiBvZiB3aGljaCB0byBjaGVjayBpZiBpdCBpcyBlbmFibGVkXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgaXNQbHVnaW5FbmFibGVkKHBsdWdpbklkKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BsdWdpbnMuX2NhY2hlLmZpbHRlcihwID0+IHAucGx1Z2luLmlkID09PSBwbHVnaW5JZCkubGVuZ3RoID09PSAxO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdXBkYXRlSG92ZXJTdHlsZXMoYWN0aXZlLCBsYXN0QWN0aXZlLCByZXBsYXkpIHtcbiAgICBjb25zdCBob3Zlck9wdGlvbnMgPSB0aGlzLm9wdGlvbnMuaG92ZXI7XG4gICAgY29uc3QgZGlmZiA9IChhLCBiKSA9PiBhLmZpbHRlcih4ID0+ICFiLnNvbWUoeSA9PiB4LmRhdGFzZXRJbmRleCA9PT0geS5kYXRhc2V0SW5kZXggJiYgeC5pbmRleCA9PT0geS5pbmRleCkpO1xuICAgIGNvbnN0IGRlYWN0aXZhdGVkID0gZGlmZihsYXN0QWN0aXZlLCBhY3RpdmUpO1xuICAgIGNvbnN0IGFjdGl2YXRlZCA9IHJlcGxheSA/IGFjdGl2ZSA6IGRpZmYoYWN0aXZlLCBsYXN0QWN0aXZlKTtcblxuICAgIGlmIChkZWFjdGl2YXRlZC5sZW5ndGgpIHtcbiAgICAgIHRoaXMudXBkYXRlSG92ZXJTdHlsZShkZWFjdGl2YXRlZCwgaG92ZXJPcHRpb25zLm1vZGUsIGZhbHNlKTtcbiAgICB9XG5cbiAgICBpZiAoYWN0aXZhdGVkLmxlbmd0aCAmJiBob3Zlck9wdGlvbnMubW9kZSkge1xuICAgICAgdGhpcy51cGRhdGVIb3ZlclN0eWxlKGFjdGl2YXRlZCwgaG92ZXJPcHRpb25zLm1vZGUsIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2V2ZW50SGFuZGxlcihlLCByZXBsYXkpIHtcbiAgICBjb25zdCBhcmdzID0ge1xuICAgICAgZXZlbnQ6IGUsXG4gICAgICByZXBsYXksXG4gICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgICAgaW5DaGFydEFyZWE6IHRoaXMuaXNQb2ludEluQXJlYShlKVxuICAgIH07XG4gICAgY29uc3QgZXZlbnRGaWx0ZXIgPSAocGx1Z2luKSA9PiAocGx1Z2luLm9wdGlvbnMuZXZlbnRzIHx8IHRoaXMub3B0aW9ucy5ldmVudHMpLmluY2x1ZGVzKGUubmF0aXZlLnR5cGUpO1xuXG4gICAgaWYgKHRoaXMubm90aWZ5UGx1Z2lucygnYmVmb3JlRXZlbnQnLCBhcmdzLCBldmVudEZpbHRlcikgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY2hhbmdlZCA9IHRoaXMuX2hhbmRsZUV2ZW50KGUsIHJlcGxheSwgYXJncy5pbkNoYXJ0QXJlYSk7XG5cbiAgICBhcmdzLmNhbmNlbGFibGUgPSBmYWxzZTtcbiAgICB0aGlzLm5vdGlmeVBsdWdpbnMoJ2FmdGVyRXZlbnQnLCBhcmdzLCBldmVudEZpbHRlcik7XG5cbiAgICBpZiAoY2hhbmdlZCB8fCBhcmdzLmNoYW5nZWQpIHtcbiAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcblx0ICogSGFuZGxlIGFuIGV2ZW50XG5cdCAqIEBwYXJhbSB7Q2hhcnRFdmVudH0gZSB0aGUgZXZlbnQgdG8gaGFuZGxlXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JlcGxheV0gLSB0cnVlIGlmIHRoZSBldmVudCB3YXMgcmVwbGF5ZWQgYnkgYHVwZGF0ZWBcbiAgICogQHBhcmFtIHtib29sZWFufSBbaW5DaGFydEFyZWFdIC0gdHJ1ZSBpZiB0aGUgZXZlbnQgaXMgaW5zaWRlIGNoYXJ0QXJlYVxuXHQgKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIHRoZSBjaGFydCBuZWVkcyB0byByZS1yZW5kZXJcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9oYW5kbGVFdmVudChlLCByZXBsYXksIGluQ2hhcnRBcmVhKSB7XG4gICAgY29uc3Qge19hY3RpdmU6IGxhc3RBY3RpdmUgPSBbXSwgb3B0aW9uc30gPSB0aGlzO1xuXG4gICAgLy8gSWYgdGhlIGV2ZW50IGlzIHJlcGxheWVkIGZyb20gYHVwZGF0ZWAsIHdlIHNob3VsZCBldmFsdWF0ZSB3aXRoIHRoZSBmaW5hbCBwb3NpdGlvbnMuXG4gICAgLy9cbiAgICAvLyBUaGUgYHJlcGxheWA6XG4gICAgLy8gSXQncyB0aGUgbGFzdCBldmVudCAoZXhjbHVkaW5nIGNsaWNrKSB0aGF0IGhhcyBvY2N1cnJlZCBiZWZvcmUgYHVwZGF0ZWAuXG4gICAgLy8gU28gbW91c2UgaGFzIG5vdCBtb3ZlZC4gSXQncyBhbHNvIG92ZXIgdGhlIGNoYXJ0LCBiZWNhdXNlIHRoZXJlIGlzIGEgYHJlcGxheWAuXG4gICAgLy9cbiAgICAvLyBUaGUgd2h5OlxuICAgIC8vIElmIGFuaW1hdGlvbnMgYXJlIGFjdGl2ZSwgdGhlIGVsZW1lbnRzIGhhdmVuJ3QgbW92ZWQgeWV0IGNvbXBhcmVkIHRvIHN0YXRlIGJlZm9yZSB1cGRhdGUuXG4gICAgLy8gQnV0IGlmIHRoZXkgd2lsbCwgd2UgYXJlIGFjdGl2YXRpbmcgdGhlIGVsZW1lbnRzIHRoYXQgd291bGQgYmUgYWN0aXZlLCBpZiB0aGlzIGNoZWNrXG4gICAgLy8gd2FzIGRvbmUgYWZ0ZXIgdGhlIGFuaW1hdGlvbnMgaGF2ZSBjb21wbGV0ZWQuID0+IFwiZmluYWwgcG9zaXRpb25zXCIuXG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gYW5pbWF0aW9ucywgdGhlIFwiZmluYWxcIiBhbmQgXCJjdXJyZW50XCIgcG9zaXRpb25zIGFyZSBlcXVhbC5cbiAgICAvLyBUaGlzIGlzIGRvbmUgc28gd2UgZG8gbm90IGhhdmUgdG8gZXZhbHVhdGUgdGhlIGFjdGl2ZSBlbGVtZW50cyBlYWNoIGFuaW1hdGlvbiBmcmFtZVxuICAgIC8vIC0gaXQgd291bGQgYmUgZXhwZW5zaXZlLlxuICAgIGNvbnN0IHVzZUZpbmFsUG9zaXRpb24gPSByZXBsYXk7XG4gICAgY29uc3QgYWN0aXZlID0gdGhpcy5fZ2V0QWN0aXZlRWxlbWVudHMoZSwgbGFzdEFjdGl2ZSwgaW5DaGFydEFyZWEsIHVzZUZpbmFsUG9zaXRpb24pO1xuICAgIGNvbnN0IGlzQ2xpY2sgPSBfaXNDbGlja0V2ZW50KGUpO1xuICAgIGNvbnN0IGxhc3RFdmVudCA9IGRldGVybWluZUxhc3RFdmVudChlLCB0aGlzLl9sYXN0RXZlbnQsIGluQ2hhcnRBcmVhLCBpc0NsaWNrKTtcblxuICAgIGlmIChpbkNoYXJ0QXJlYSkge1xuICAgICAgLy8gU2V0IF9sYXN0RXZlbnQgdG8gbnVsbCB3aGlsZSB3ZSBhcmUgcHJvY2Vzc2luZyB0aGUgZXZlbnQgaGFuZGxlcnMuXG4gICAgICAvLyBUaGlzIHByZXZlbnRzIHJlY3Vyc2lvbiBpZiB0aGUgaGFuZGxlciBjYWxscyBjaGFydC51cGRhdGUoKVxuICAgICAgdGhpcy5fbGFzdEV2ZW50ID0gbnVsbDtcblxuICAgICAgLy8gSW52b2tlIG9uSG92ZXIgaG9va1xuICAgICAgY2FsbENhbGxiYWNrKG9wdGlvbnMub25Ib3ZlciwgW2UsIGFjdGl2ZSwgdGhpc10sIHRoaXMpO1xuXG4gICAgICBpZiAoaXNDbGljaykge1xuICAgICAgICBjYWxsQ2FsbGJhY2sob3B0aW9ucy5vbkNsaWNrLCBbZSwgYWN0aXZlLCB0aGlzXSwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgY2hhbmdlZCA9ICFfZWxlbWVudHNFcXVhbChhY3RpdmUsIGxhc3RBY3RpdmUpO1xuICAgIGlmIChjaGFuZ2VkIHx8IHJlcGxheSkge1xuICAgICAgdGhpcy5fYWN0aXZlID0gYWN0aXZlO1xuICAgICAgdGhpcy5fdXBkYXRlSG92ZXJTdHlsZXMoYWN0aXZlLCBsYXN0QWN0aXZlLCByZXBsYXkpO1xuICAgIH1cblxuICAgIHRoaXMuX2xhc3RFdmVudCA9IGxhc3RFdmVudDtcblxuICAgIHJldHVybiBjaGFuZ2VkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Q2hhcnRFdmVudH0gZSAtIFRoZSBldmVudFxuICAgKiBAcGFyYW0ge2ltcG9ydCgnLi4vdHlwZXMvaW5kZXguanMnKS5BY3RpdmVFbGVtZW50W119IGxhc3RBY3RpdmUgLSBQcmV2aW91c2x5IGFjdGl2ZSBlbGVtZW50c1xuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGluQ2hhcnRBcmVhIC0gSXMgdGhlIGVudmVudCBpbnNpZGUgY2hhcnRBcmVhXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNlRmluYWxQb3NpdGlvbiAtIFNob3VsZCB0aGUgZXZhbHVhdGlvbiBiZSBkb25lIHdpdGggY3VycmVudCBvciBmaW5hbCAoYWZ0ZXIgYW5pbWF0aW9uKSBlbGVtZW50IHBvc2l0aW9uc1xuICAgKiBAcmV0dXJucyB7aW1wb3J0KCcuLi90eXBlcy9pbmRleC5qcycpLkFjdGl2ZUVsZW1lbnRbXX0gLSBUaGUgYWN0aXZlIGVsZW1lbnRzXG4gICAqIEBwcmF2YXRlXG4gICAqL1xuICBfZ2V0QWN0aXZlRWxlbWVudHMoZSwgbGFzdEFjdGl2ZSwgaW5DaGFydEFyZWEsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICBpZiAoZS50eXBlID09PSAnbW91c2VvdXQnKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgaWYgKCFpbkNoYXJ0QXJlYSkge1xuICAgICAgLy8gTGV0IHVzZXIgY29udHJvbCB0aGUgYWN0aXZlIGVsZW1lbnRzIG91dHNpZGUgY2hhcnRBcmVhLiBFZy4gdXNpbmcgTGVnZW5kLlxuICAgICAgcmV0dXJuIGxhc3RBY3RpdmU7XG4gICAgfVxuXG4gICAgY29uc3QgaG92ZXJPcHRpb25zID0gdGhpcy5vcHRpb25zLmhvdmVyO1xuICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnRzQXRFdmVudEZvck1vZGUoZSwgaG92ZXJPcHRpb25zLm1vZGUsIGhvdmVyT3B0aW9ucywgdXNlRmluYWxQb3NpdGlvbik7XG4gIH1cbn1cblxuLy8gQHRzLWlnbm9yZVxuZnVuY3Rpb24gaW52YWxpZGF0ZVBsdWdpbnMoKSB7XG4gIHJldHVybiBlYWNoKENoYXJ0Lmluc3RhbmNlcywgKGNoYXJ0KSA9PiBjaGFydC5fcGx1Z2lucy5pbnZhbGlkYXRlKCkpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFydDtcbiIsICJpbXBvcnQgRWxlbWVudCBmcm9tICcuLi9jb3JlL2NvcmUuZWxlbWVudC5qcyc7XG5pbXBvcnQge19hbmdsZUJldHdlZW4sIGdldEFuZ2xlRnJvbVBvaW50LCBUQVUsIEhBTEZfUEksIHZhbHVlT3JEZWZhdWx0fSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcbmltcG9ydCB7UEksIF9pc0JldHdlZW4sIF9saW1pdFZhbHVlfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMubWF0aC5qcyc7XG5pbXBvcnQge19yZWFkVmFsdWVUb1Byb3BzfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMub3B0aW9ucy5qcyc7XG5pbXBvcnQgdHlwZSB7QXJjT3B0aW9ucywgUG9pbnR9IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcblxuXG5mdW5jdGlvbiBjbGlwQXJjKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCBlbGVtZW50OiBBcmNFbGVtZW50LCBlbmRBbmdsZTogbnVtYmVyKSB7XG4gIGNvbnN0IHtzdGFydEFuZ2xlLCBwaXhlbE1hcmdpbiwgeCwgeSwgb3V0ZXJSYWRpdXMsIGlubmVyUmFkaXVzfSA9IGVsZW1lbnQ7XG4gIGxldCBhbmdsZU1hcmdpbiA9IHBpeGVsTWFyZ2luIC8gb3V0ZXJSYWRpdXM7XG5cbiAgLy8gRHJhdyBhbiBpbm5lciBib3JkZXIgYnkgY2xpcHBpbmcgdGhlIGFyYyBhbmQgZHJhd2luZyBhIGRvdWJsZS13aWR0aCBib3JkZXJcbiAgLy8gRW5sYXJnZSB0aGUgY2xpcHBpbmcgYXJjIGJ5IDAuMzMgcGl4ZWxzIHRvIGVsaW1pbmF0ZSBnbGl0Y2hlcyBiZXR3ZWVuIGJvcmRlcnNcbiAgY3R4LmJlZ2luUGF0aCgpO1xuICBjdHguYXJjKHgsIHksIG91dGVyUmFkaXVzLCBzdGFydEFuZ2xlIC0gYW5nbGVNYXJnaW4sIGVuZEFuZ2xlICsgYW5nbGVNYXJnaW4pO1xuICBpZiAoaW5uZXJSYWRpdXMgPiBwaXhlbE1hcmdpbikge1xuICAgIGFuZ2xlTWFyZ2luID0gcGl4ZWxNYXJnaW4gLyBpbm5lclJhZGl1cztcbiAgICBjdHguYXJjKHgsIHksIGlubmVyUmFkaXVzLCBlbmRBbmdsZSArIGFuZ2xlTWFyZ2luLCBzdGFydEFuZ2xlIC0gYW5nbGVNYXJnaW4sIHRydWUpO1xuICB9IGVsc2Uge1xuICAgIGN0eC5hcmMoeCwgeSwgcGl4ZWxNYXJnaW4sIGVuZEFuZ2xlICsgSEFMRl9QSSwgc3RhcnRBbmdsZSAtIEhBTEZfUEkpO1xuICB9XG4gIGN0eC5jbG9zZVBhdGgoKTtcbiAgY3R4LmNsaXAoKTtcbn1cblxuZnVuY3Rpb24gdG9SYWRpdXNDb3JuZXJzKHZhbHVlKSB7XG4gIHJldHVybiBfcmVhZFZhbHVlVG9Qcm9wcyh2YWx1ZSwgWydvdXRlclN0YXJ0JywgJ291dGVyRW5kJywgJ2lubmVyU3RhcnQnLCAnaW5uZXJFbmQnXSk7XG59XG5cbi8qKlxuICogUGFyc2UgYm9yZGVyIHJhZGl1cyBmcm9tIHRoZSBwcm92aWRlZCBvcHRpb25zXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQm9yZGVyUmFkaXVzKGFyYzogQXJjRWxlbWVudCwgaW5uZXJSYWRpdXM6IG51bWJlciwgb3V0ZXJSYWRpdXM6IG51bWJlciwgYW5nbGVEZWx0YTogbnVtYmVyKSB7XG4gIGNvbnN0IG8gPSB0b1JhZGl1c0Nvcm5lcnMoYXJjLm9wdGlvbnMuYm9yZGVyUmFkaXVzKTtcbiAgY29uc3QgaGFsZlRoaWNrbmVzcyA9IChvdXRlclJhZGl1cyAtIGlubmVyUmFkaXVzKSAvIDI7XG4gIGNvbnN0IGlubmVyTGltaXQgPSBNYXRoLm1pbihoYWxmVGhpY2tuZXNzLCBhbmdsZURlbHRhICogaW5uZXJSYWRpdXMgLyAyKTtcblxuICAvLyBPdXRlciBsaW1pdHMgYXJlIGNvbXBsaWNhdGVkLiBXZSB3YW50IHRvIGNvbXB1dGUgdGhlIGF2YWlsYWJsZSBhbmd1bGFyIGRpc3RhbmNlIGF0XG4gIC8vIGEgcmFkaXVzIG9mIG91dGVyUmFkaXVzIC0gYm9yZGVyUmFkaXVzIGJlY2F1c2UgZm9yIHNtYWxsIGFuZ3VsYXIgZGlzdGFuY2VzLCB0aGlzIHRlcm0gbGltaXRzLlxuICAvLyBXZSBjb21wdXRlIGF0IHIgPSBvdXRlclJhZGl1cyAtIGJvcmRlclJhZGl1cyBiZWNhdXNlIHRoaXMgY2lyY2xlIGRlZmluZXMgdGhlIGNlbnRlciBvZiB0aGUgYm9yZGVyIGNvcm5lcnMuXG4gIC8vXG4gIC8vIElmIHRoZSBib3JkZXJSYWRpdXMgaXMgbGFyZ2UsIHRoYXQgdmFsdWUgY2FuIGJlY29tZSBuZWdhdGl2ZS5cbiAgLy8gVGhpcyBjYXVzZXMgdGhlIG91dGVyIGJvcmRlcnMgdG8gbG9zZSB0aGVpciByYWRpdXMgZW50aXJlbHksIHdoaWNoIGlzIHJhdGhlciB1bmV4cGVjdGVkLiBUbyBzb2x2ZSB0aGF0LCBpZiBib3JkZXJSYWRpdXMgPiBvdXRlclJhZGl1c1xuICAvLyB3ZSBrbm93IHRoYXQgdGhlIHRoaWNrbmVzcyB0ZXJtIHdpbGwgZG9taW5hdGUgYW5kIGNvbXB1dGUgdGhlIGxpbWl0cyBhdCB0aGF0IHBvaW50XG4gIGNvbnN0IGNvbXB1dGVPdXRlckxpbWl0ID0gKHZhbCkgPT4ge1xuICAgIGNvbnN0IG91dGVyQXJjTGltaXQgPSAob3V0ZXJSYWRpdXMgLSBNYXRoLm1pbihoYWxmVGhpY2tuZXNzLCB2YWwpKSAqIGFuZ2xlRGVsdGEgLyAyO1xuICAgIHJldHVybiBfbGltaXRWYWx1ZSh2YWwsIDAsIE1hdGgubWluKGhhbGZUaGlja25lc3MsIG91dGVyQXJjTGltaXQpKTtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG91dGVyU3RhcnQ6IGNvbXB1dGVPdXRlckxpbWl0KG8ub3V0ZXJTdGFydCksXG4gICAgb3V0ZXJFbmQ6IGNvbXB1dGVPdXRlckxpbWl0KG8ub3V0ZXJFbmQpLFxuICAgIGlubmVyU3RhcnQ6IF9saW1pdFZhbHVlKG8uaW5uZXJTdGFydCwgMCwgaW5uZXJMaW1pdCksXG4gICAgaW5uZXJFbmQ6IF9saW1pdFZhbHVlKG8uaW5uZXJFbmQsIDAsIGlubmVyTGltaXQpLFxuICB9O1xufVxuXG4vKipcbiAqIENvbnZlcnQgKHIsIPCdnIMpIHRvICh4LCB5KVxuICovXG5mdW5jdGlvbiByVGhldGFUb1hZKHI6IG51bWJlciwgdGhldGE6IG51bWJlciwgeDogbnVtYmVyLCB5OiBudW1iZXIpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiB4ICsgciAqIE1hdGguY29zKHRoZXRhKSxcbiAgICB5OiB5ICsgciAqIE1hdGguc2luKHRoZXRhKSxcbiAgfTtcbn1cblxuXG4vKipcbiAqIFBhdGggdGhlIGFyYywgcmVzcGVjdGluZyBib3JkZXIgcmFkaXVzIGJ5IHNlcGFyYXRpbmcgaW50byBsZWZ0IGFuZCByaWdodCBoYWx2ZXMuXG4gKlxuICogICBTdGFydCAgICAgIEVuZFxuICpcbiAqICAgIDEtLS0+YS0tLT4yICAgIE91dGVyXG4gKiAgIC8gICAgICAgICAgIFxcXG4gKiAgIDggICAgICAgICAgIDNcbiAqICAgfCAgICAgICAgICAgfFxuICogICB8ICAgICAgICAgICB8XG4gKiAgIDcgICAgICAgICAgIDRcbiAqICAgXFwgICAgICAgICAgIC9cbiAqICAgIDY8LS0tYjwtLS01ICAgIElubmVyXG4gKi9cbmZ1bmN0aW9uIHBhdGhBcmMoXG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICBlbGVtZW50OiBBcmNFbGVtZW50LFxuICBvZmZzZXQ6IG51bWJlcixcbiAgc3BhY2luZzogbnVtYmVyLFxuICBlbmQ6IG51bWJlcixcbiAgY2lyY3VsYXI6IGJvb2xlYW4sXG4pIHtcbiAgY29uc3Qge3gsIHksIHN0YXJ0QW5nbGU6IHN0YXJ0LCBwaXhlbE1hcmdpbiwgaW5uZXJSYWRpdXM6IGlubmVyUn0gPSBlbGVtZW50O1xuXG4gIGNvbnN0IG91dGVyUmFkaXVzID0gTWF0aC5tYXgoZWxlbWVudC5vdXRlclJhZGl1cyArIHNwYWNpbmcgKyBvZmZzZXQgLSBwaXhlbE1hcmdpbiwgMCk7XG4gIGNvbnN0IGlubmVyUmFkaXVzID0gaW5uZXJSID4gMCA/IGlubmVyUiArIHNwYWNpbmcgKyBvZmZzZXQgKyBwaXhlbE1hcmdpbiA6IDA7XG5cbiAgbGV0IHNwYWNpbmdPZmZzZXQgPSAwO1xuICBjb25zdCBhbHBoYSA9IGVuZCAtIHN0YXJ0O1xuXG4gIGlmIChzcGFjaW5nKSB7XG4gICAgLy8gV2hlbiBzcGFjaW5nIGlzIHByZXNlbnQsIGl0IGlzIHRoZSBzYW1lIGZvciBhbGwgaXRlbXNcbiAgICAvLyBTbyB3ZSBhZGp1c3QgdGhlIHN0YXJ0IGFuZCBlbmQgYW5nbGUgb2YgdGhlIGFyYyBzdWNoIHRoYXRcbiAgICAvLyB0aGUgZGlzdGFuY2UgaXMgdGhlIHNhbWUgYXMgaXQgd291bGQgYmUgd2l0aG91dCB0aGUgc3BhY2luZ1xuICAgIGNvbnN0IG5vU3BhY2luZ0lubmVyUmFkaXVzID0gaW5uZXJSID4gMCA/IGlubmVyUiAtIHNwYWNpbmcgOiAwO1xuICAgIGNvbnN0IG5vU3BhY2luZ091dGVyUmFkaXVzID0gb3V0ZXJSYWRpdXMgPiAwID8gb3V0ZXJSYWRpdXMgLSBzcGFjaW5nIDogMDtcbiAgICBjb25zdCBhdk5vZ1NwYWNpbmdSYWRpdXMgPSAobm9TcGFjaW5nSW5uZXJSYWRpdXMgKyBub1NwYWNpbmdPdXRlclJhZGl1cykgLyAyO1xuICAgIGNvbnN0IGFkanVzdGVkQW5nbGUgPSBhdk5vZ1NwYWNpbmdSYWRpdXMgIT09IDAgPyAoYWxwaGEgKiBhdk5vZ1NwYWNpbmdSYWRpdXMpIC8gKGF2Tm9nU3BhY2luZ1JhZGl1cyArIHNwYWNpbmcpIDogYWxwaGE7XG4gICAgc3BhY2luZ09mZnNldCA9IChhbHBoYSAtIGFkanVzdGVkQW5nbGUpIC8gMjtcbiAgfVxuXG4gIGNvbnN0IGJldGEgPSBNYXRoLm1heCgwLjAwMSwgYWxwaGEgKiBvdXRlclJhZGl1cyAtIG9mZnNldCAvIFBJKSAvIG91dGVyUmFkaXVzO1xuICBjb25zdCBhbmdsZU9mZnNldCA9IChhbHBoYSAtIGJldGEpIC8gMjtcbiAgY29uc3Qgc3RhcnRBbmdsZSA9IHN0YXJ0ICsgYW5nbGVPZmZzZXQgKyBzcGFjaW5nT2Zmc2V0O1xuICBjb25zdCBlbmRBbmdsZSA9IGVuZCAtIGFuZ2xlT2Zmc2V0IC0gc3BhY2luZ09mZnNldDtcbiAgY29uc3Qge291dGVyU3RhcnQsIG91dGVyRW5kLCBpbm5lclN0YXJ0LCBpbm5lckVuZH0gPSBwYXJzZUJvcmRlclJhZGl1cyhlbGVtZW50LCBpbm5lclJhZGl1cywgb3V0ZXJSYWRpdXMsIGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSk7XG5cbiAgY29uc3Qgb3V0ZXJTdGFydEFkanVzdGVkUmFkaXVzID0gb3V0ZXJSYWRpdXMgLSBvdXRlclN0YXJ0O1xuICBjb25zdCBvdXRlckVuZEFkanVzdGVkUmFkaXVzID0gb3V0ZXJSYWRpdXMgLSBvdXRlckVuZDtcbiAgY29uc3Qgb3V0ZXJTdGFydEFkanVzdGVkQW5nbGUgPSBzdGFydEFuZ2xlICsgb3V0ZXJTdGFydCAvIG91dGVyU3RhcnRBZGp1c3RlZFJhZGl1cztcbiAgY29uc3Qgb3V0ZXJFbmRBZGp1c3RlZEFuZ2xlID0gZW5kQW5nbGUgLSBvdXRlckVuZCAvIG91dGVyRW5kQWRqdXN0ZWRSYWRpdXM7XG5cbiAgY29uc3QgaW5uZXJTdGFydEFkanVzdGVkUmFkaXVzID0gaW5uZXJSYWRpdXMgKyBpbm5lclN0YXJ0O1xuICBjb25zdCBpbm5lckVuZEFkanVzdGVkUmFkaXVzID0gaW5uZXJSYWRpdXMgKyBpbm5lckVuZDtcbiAgY29uc3QgaW5uZXJTdGFydEFkanVzdGVkQW5nbGUgPSBzdGFydEFuZ2xlICsgaW5uZXJTdGFydCAvIGlubmVyU3RhcnRBZGp1c3RlZFJhZGl1cztcbiAgY29uc3QgaW5uZXJFbmRBZGp1c3RlZEFuZ2xlID0gZW5kQW5nbGUgLSBpbm5lckVuZCAvIGlubmVyRW5kQWRqdXN0ZWRSYWRpdXM7XG5cbiAgY3R4LmJlZ2luUGF0aCgpO1xuXG4gIGlmIChjaXJjdWxhcikge1xuICAgIC8vIFRoZSBmaXJzdCBhcmMgc2VnbWVudHMgZnJvbSBwb2ludCAxIHRvIHBvaW50IGEgdG8gcG9pbnQgMlxuICAgIGNvbnN0IG91dGVyTWlkQWRqdXN0ZWRBbmdsZSA9IChvdXRlclN0YXJ0QWRqdXN0ZWRBbmdsZSArIG91dGVyRW5kQWRqdXN0ZWRBbmdsZSkgLyAyO1xuICAgIGN0eC5hcmMoeCwgeSwgb3V0ZXJSYWRpdXMsIG91dGVyU3RhcnRBZGp1c3RlZEFuZ2xlLCBvdXRlck1pZEFkanVzdGVkQW5nbGUpO1xuICAgIGN0eC5hcmMoeCwgeSwgb3V0ZXJSYWRpdXMsIG91dGVyTWlkQWRqdXN0ZWRBbmdsZSwgb3V0ZXJFbmRBZGp1c3RlZEFuZ2xlKTtcblxuICAgIC8vIFRoZSBjb3JuZXIgc2VnbWVudCBmcm9tIHBvaW50IDIgdG8gcG9pbnQgM1xuICAgIGlmIChvdXRlckVuZCA+IDApIHtcbiAgICAgIGNvbnN0IHBDZW50ZXIgPSByVGhldGFUb1hZKG91dGVyRW5kQWRqdXN0ZWRSYWRpdXMsIG91dGVyRW5kQWRqdXN0ZWRBbmdsZSwgeCwgeSk7XG4gICAgICBjdHguYXJjKHBDZW50ZXIueCwgcENlbnRlci55LCBvdXRlckVuZCwgb3V0ZXJFbmRBZGp1c3RlZEFuZ2xlLCBlbmRBbmdsZSArIEhBTEZfUEkpO1xuICAgIH1cblxuICAgIC8vIFRoZSBsaW5lIGZyb20gcG9pbnQgMyB0byBwb2ludCA0XG4gICAgY29uc3QgcDQgPSByVGhldGFUb1hZKGlubmVyRW5kQWRqdXN0ZWRSYWRpdXMsIGVuZEFuZ2xlLCB4LCB5KTtcbiAgICBjdHgubGluZVRvKHA0LngsIHA0LnkpO1xuXG4gICAgLy8gVGhlIGNvcm5lciBzZWdtZW50IGZyb20gcG9pbnQgNCB0byBwb2ludCA1XG4gICAgaWYgKGlubmVyRW5kID4gMCkge1xuICAgICAgY29uc3QgcENlbnRlciA9IHJUaGV0YVRvWFkoaW5uZXJFbmRBZGp1c3RlZFJhZGl1cywgaW5uZXJFbmRBZGp1c3RlZEFuZ2xlLCB4LCB5KTtcbiAgICAgIGN0eC5hcmMocENlbnRlci54LCBwQ2VudGVyLnksIGlubmVyRW5kLCBlbmRBbmdsZSArIEhBTEZfUEksIGlubmVyRW5kQWRqdXN0ZWRBbmdsZSArIE1hdGguUEkpO1xuICAgIH1cblxuICAgIC8vIFRoZSBpbm5lciBhcmMgZnJvbSBwb2ludCA1IHRvIHBvaW50IGIgdG8gcG9pbnQgNlxuICAgIGNvbnN0IGlubmVyTWlkQWRqdXN0ZWRBbmdsZSA9ICgoZW5kQW5nbGUgLSAoaW5uZXJFbmQgLyBpbm5lclJhZGl1cykpICsgKHN0YXJ0QW5nbGUgKyAoaW5uZXJTdGFydCAvIGlubmVyUmFkaXVzKSkpIC8gMjtcbiAgICBjdHguYXJjKHgsIHksIGlubmVyUmFkaXVzLCBlbmRBbmdsZSAtIChpbm5lckVuZCAvIGlubmVyUmFkaXVzKSwgaW5uZXJNaWRBZGp1c3RlZEFuZ2xlLCB0cnVlKTtcbiAgICBjdHguYXJjKHgsIHksIGlubmVyUmFkaXVzLCBpbm5lck1pZEFkanVzdGVkQW5nbGUsIHN0YXJ0QW5nbGUgKyAoaW5uZXJTdGFydCAvIGlubmVyUmFkaXVzKSwgdHJ1ZSk7XG5cbiAgICAvLyBUaGUgY29ybmVyIHNlZ21lbnQgZnJvbSBwb2ludCA2IHRvIHBvaW50IDdcbiAgICBpZiAoaW5uZXJTdGFydCA+IDApIHtcbiAgICAgIGNvbnN0IHBDZW50ZXIgPSByVGhldGFUb1hZKGlubmVyU3RhcnRBZGp1c3RlZFJhZGl1cywgaW5uZXJTdGFydEFkanVzdGVkQW5nbGUsIHgsIHkpO1xuICAgICAgY3R4LmFyYyhwQ2VudGVyLngsIHBDZW50ZXIueSwgaW5uZXJTdGFydCwgaW5uZXJTdGFydEFkanVzdGVkQW5nbGUgKyBNYXRoLlBJLCBzdGFydEFuZ2xlIC0gSEFMRl9QSSk7XG4gICAgfVxuXG4gICAgLy8gVGhlIGxpbmUgZnJvbSBwb2ludCA3IHRvIHBvaW50IDhcbiAgICBjb25zdCBwOCA9IHJUaGV0YVRvWFkob3V0ZXJTdGFydEFkanVzdGVkUmFkaXVzLCBzdGFydEFuZ2xlLCB4LCB5KTtcbiAgICBjdHgubGluZVRvKHA4LngsIHA4LnkpO1xuXG4gICAgLy8gVGhlIGNvcm5lciBzZWdtZW50IGZyb20gcG9pbnQgOCB0byBwb2ludCAxXG4gICAgaWYgKG91dGVyU3RhcnQgPiAwKSB7XG4gICAgICBjb25zdCBwQ2VudGVyID0gclRoZXRhVG9YWShvdXRlclN0YXJ0QWRqdXN0ZWRSYWRpdXMsIG91dGVyU3RhcnRBZGp1c3RlZEFuZ2xlLCB4LCB5KTtcbiAgICAgIGN0eC5hcmMocENlbnRlci54LCBwQ2VudGVyLnksIG91dGVyU3RhcnQsIHN0YXJ0QW5nbGUgLSBIQUxGX1BJLCBvdXRlclN0YXJ0QWRqdXN0ZWRBbmdsZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGN0eC5tb3ZlVG8oeCwgeSk7XG5cbiAgICBjb25zdCBvdXRlclN0YXJ0WCA9IE1hdGguY29zKG91dGVyU3RhcnRBZGp1c3RlZEFuZ2xlKSAqIG91dGVyUmFkaXVzICsgeDtcbiAgICBjb25zdCBvdXRlclN0YXJ0WSA9IE1hdGguc2luKG91dGVyU3RhcnRBZGp1c3RlZEFuZ2xlKSAqIG91dGVyUmFkaXVzICsgeTtcbiAgICBjdHgubGluZVRvKG91dGVyU3RhcnRYLCBvdXRlclN0YXJ0WSk7XG5cbiAgICBjb25zdCBvdXRlckVuZFggPSBNYXRoLmNvcyhvdXRlckVuZEFkanVzdGVkQW5nbGUpICogb3V0ZXJSYWRpdXMgKyB4O1xuICAgIGNvbnN0IG91dGVyRW5kWSA9IE1hdGguc2luKG91dGVyRW5kQWRqdXN0ZWRBbmdsZSkgKiBvdXRlclJhZGl1cyArIHk7XG4gICAgY3R4LmxpbmVUbyhvdXRlckVuZFgsIG91dGVyRW5kWSk7XG4gIH1cblxuICBjdHguY2xvc2VQYXRoKCk7XG59XG5cbmZ1bmN0aW9uIGRyYXdBcmMoXG4gIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICBlbGVtZW50OiBBcmNFbGVtZW50LFxuICBvZmZzZXQ6IG51bWJlcixcbiAgc3BhY2luZzogbnVtYmVyLFxuICBjaXJjdWxhcjogYm9vbGVhbixcbikge1xuICBjb25zdCB7ZnVsbENpcmNsZXMsIHN0YXJ0QW5nbGUsIGNpcmN1bWZlcmVuY2V9ID0gZWxlbWVudDtcbiAgbGV0IGVuZEFuZ2xlID0gZWxlbWVudC5lbmRBbmdsZTtcbiAgaWYgKGZ1bGxDaXJjbGVzKSB7XG4gICAgcGF0aEFyYyhjdHgsIGVsZW1lbnQsIG9mZnNldCwgc3BhY2luZywgZW5kQW5nbGUsIGNpcmN1bGFyKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZ1bGxDaXJjbGVzOyArK2kpIHtcbiAgICAgIGN0eC5maWxsKCk7XG4gICAgfVxuICAgIGlmICghaXNOYU4oY2lyY3VtZmVyZW5jZSkpIHtcbiAgICAgIGVuZEFuZ2xlID0gc3RhcnRBbmdsZSArIChjaXJjdW1mZXJlbmNlICUgVEFVIHx8IFRBVSk7XG4gICAgfVxuICB9XG4gIHBhdGhBcmMoY3R4LCBlbGVtZW50LCBvZmZzZXQsIHNwYWNpbmcsIGVuZEFuZ2xlLCBjaXJjdWxhcik7XG4gIGN0eC5maWxsKCk7XG4gIHJldHVybiBlbmRBbmdsZTtcbn1cblxuZnVuY3Rpb24gZHJhd0JvcmRlcihcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsXG4gIGVsZW1lbnQ6IEFyY0VsZW1lbnQsXG4gIG9mZnNldDogbnVtYmVyLFxuICBzcGFjaW5nOiBudW1iZXIsXG4gIGNpcmN1bGFyOiBib29sZWFuLFxuKSB7XG4gIGNvbnN0IHtmdWxsQ2lyY2xlcywgc3RhcnRBbmdsZSwgY2lyY3VtZmVyZW5jZSwgb3B0aW9uc30gPSBlbGVtZW50O1xuICBjb25zdCB7Ym9yZGVyV2lkdGgsIGJvcmRlckpvaW5TdHlsZSwgYm9yZGVyRGFzaCwgYm9yZGVyRGFzaE9mZnNldH0gPSBvcHRpb25zO1xuICBjb25zdCBpbm5lciA9IG9wdGlvbnMuYm9yZGVyQWxpZ24gPT09ICdpbm5lcic7XG5cbiAgaWYgKCFib3JkZXJXaWR0aCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGN0eC5zZXRMaW5lRGFzaChib3JkZXJEYXNoIHx8IFtdKTtcbiAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gYm9yZGVyRGFzaE9mZnNldDtcblxuICBpZiAoaW5uZXIpIHtcbiAgICBjdHgubGluZVdpZHRoID0gYm9yZGVyV2lkdGggKiAyO1xuICAgIGN0eC5saW5lSm9pbiA9IGJvcmRlckpvaW5TdHlsZSB8fCAncm91bmQnO1xuICB9IGVsc2Uge1xuICAgIGN0eC5saW5lV2lkdGggPSBib3JkZXJXaWR0aDtcbiAgICBjdHgubGluZUpvaW4gPSBib3JkZXJKb2luU3R5bGUgfHwgJ2JldmVsJztcbiAgfVxuXG4gIGxldCBlbmRBbmdsZSA9IGVsZW1lbnQuZW5kQW5nbGU7XG4gIGlmIChmdWxsQ2lyY2xlcykge1xuICAgIHBhdGhBcmMoY3R4LCBlbGVtZW50LCBvZmZzZXQsIHNwYWNpbmcsIGVuZEFuZ2xlLCBjaXJjdWxhcik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmdWxsQ2lyY2xlczsgKytpKSB7XG4gICAgICBjdHguc3Ryb2tlKCk7XG4gICAgfVxuICAgIGlmICghaXNOYU4oY2lyY3VtZmVyZW5jZSkpIHtcbiAgICAgIGVuZEFuZ2xlID0gc3RhcnRBbmdsZSArIChjaXJjdW1mZXJlbmNlICUgVEFVIHx8IFRBVSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlubmVyKSB7XG4gICAgY2xpcEFyYyhjdHgsIGVsZW1lbnQsIGVuZEFuZ2xlKTtcbiAgfVxuXG4gIGlmICghZnVsbENpcmNsZXMpIHtcbiAgICBwYXRoQXJjKGN0eCwgZWxlbWVudCwgb2Zmc2V0LCBzcGFjaW5nLCBlbmRBbmdsZSwgY2lyY3VsYXIpO1xuICAgIGN0eC5zdHJva2UoKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFyY1Byb3BzIGV4dGVuZHMgUG9pbnQge1xuICBzdGFydEFuZ2xlOiBudW1iZXI7XG4gIGVuZEFuZ2xlOiBudW1iZXI7XG4gIGlubmVyUmFkaXVzOiBudW1iZXI7XG4gIG91dGVyUmFkaXVzOiBudW1iZXI7XG4gIGNpcmN1bWZlcmVuY2U6IG51bWJlcjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQXJjRWxlbWVudCBleHRlbmRzIEVsZW1lbnQ8QXJjUHJvcHMsIEFyY09wdGlvbnM+IHtcblxuICBzdGF0aWMgaWQgPSAnYXJjJztcblxuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgYm9yZGVyQWxpZ246ICdjZW50ZXInLFxuICAgIGJvcmRlckNvbG9yOiAnI2ZmZicsXG4gICAgYm9yZGVyRGFzaDogW10sXG4gICAgYm9yZGVyRGFzaE9mZnNldDogMCxcbiAgICBib3JkZXJKb2luU3R5bGU6IHVuZGVmaW5lZCxcbiAgICBib3JkZXJSYWRpdXM6IDAsXG4gICAgYm9yZGVyV2lkdGg6IDIsXG4gICAgb2Zmc2V0OiAwLFxuICAgIHNwYWNpbmc6IDAsXG4gICAgYW5nbGU6IHVuZGVmaW5lZCxcbiAgICBjaXJjdWxhcjogdHJ1ZSxcbiAgfTtcblxuICBzdGF0aWMgZGVmYXVsdFJvdXRlcyA9IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6ICdiYWNrZ3JvdW5kQ29sb3InXG4gIH07XG5cbiAgc3RhdGljIGRlc2NyaXB0b3JzID0ge1xuICAgIF9zY3JpcHRhYmxlOiB0cnVlLFxuICAgIF9pbmRleGFibGU6IChuYW1lKSA9PiBuYW1lICE9PSAnYm9yZGVyRGFzaCdcbiAgfTtcblxuICBjaXJjdW1mZXJlbmNlOiBudW1iZXI7XG4gIGVuZEFuZ2xlOiBudW1iZXI7XG4gIGZ1bGxDaXJjbGVzOiBudW1iZXI7XG4gIGlubmVyUmFkaXVzOiBudW1iZXI7XG4gIG91dGVyUmFkaXVzOiBudW1iZXI7XG4gIHBpeGVsTWFyZ2luOiBudW1iZXI7XG4gIHN0YXJ0QW5nbGU6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihjZmcpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5vcHRpb25zID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY2lyY3VtZmVyZW5jZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnN0YXJ0QW5nbGUgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5lbmRBbmdsZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmlubmVyUmFkaXVzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMub3V0ZXJSYWRpdXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5waXhlbE1hcmdpbiA9IDA7XG4gICAgdGhpcy5mdWxsQ2lyY2xlcyA9IDA7XG5cbiAgICBpZiAoY2ZnKSB7XG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGNmZyk7XG4gICAgfVxuICB9XG5cbiAgaW5SYW5nZShjaGFydFg6IG51bWJlciwgY2hhcnRZOiBudW1iZXIsIHVzZUZpbmFsUG9zaXRpb246IGJvb2xlYW4pIHtcbiAgICBjb25zdCBwb2ludCA9IHRoaXMuZ2V0UHJvcHMoWyd4JywgJ3knXSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgY29uc3Qge2FuZ2xlLCBkaXN0YW5jZX0gPSBnZXRBbmdsZUZyb21Qb2ludChwb2ludCwge3g6IGNoYXJ0WCwgeTogY2hhcnRZfSk7XG4gICAgY29uc3Qge3N0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBpbm5lclJhZGl1cywgb3V0ZXJSYWRpdXMsIGNpcmN1bWZlcmVuY2V9ID0gdGhpcy5nZXRQcm9wcyhbXG4gICAgICAnc3RhcnRBbmdsZScsXG4gICAgICAnZW5kQW5nbGUnLFxuICAgICAgJ2lubmVyUmFkaXVzJyxcbiAgICAgICdvdXRlclJhZGl1cycsXG4gICAgICAnY2lyY3VtZmVyZW5jZSdcbiAgICBdLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICBjb25zdCByQWRqdXN0ID0gKHRoaXMub3B0aW9ucy5zcGFjaW5nICsgdGhpcy5vcHRpb25zLmJvcmRlcldpZHRoKSAvIDI7XG4gICAgY29uc3QgX2NpcmN1bWZlcmVuY2UgPSB2YWx1ZU9yRGVmYXVsdChjaXJjdW1mZXJlbmNlLCBlbmRBbmdsZSAtIHN0YXJ0QW5nbGUpO1xuICAgIGNvbnN0IGJldHdlZW5BbmdsZXMgPSBfY2lyY3VtZmVyZW5jZSA+PSBUQVUgfHwgX2FuZ2xlQmV0d2VlbihhbmdsZSwgc3RhcnRBbmdsZSwgZW5kQW5nbGUpO1xuICAgIGNvbnN0IHdpdGhpblJhZGl1cyA9IF9pc0JldHdlZW4oZGlzdGFuY2UsIGlubmVyUmFkaXVzICsgckFkanVzdCwgb3V0ZXJSYWRpdXMgKyByQWRqdXN0KTtcblxuICAgIHJldHVybiAoYmV0d2VlbkFuZ2xlcyAmJiB3aXRoaW5SYWRpdXMpO1xuICB9XG5cbiAgZ2V0Q2VudGVyUG9pbnQodXNlRmluYWxQb3NpdGlvbjogYm9vbGVhbikge1xuICAgIGNvbnN0IHt4LCB5LCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgaW5uZXJSYWRpdXMsIG91dGVyUmFkaXVzfSA9IHRoaXMuZ2V0UHJvcHMoW1xuICAgICAgJ3gnLFxuICAgICAgJ3knLFxuICAgICAgJ3N0YXJ0QW5nbGUnLFxuICAgICAgJ2VuZEFuZ2xlJyxcbiAgICAgICdpbm5lclJhZGl1cycsXG4gICAgICAnb3V0ZXJSYWRpdXMnXG4gICAgXSwgdXNlRmluYWxQb3NpdGlvbik7XG4gICAgY29uc3Qge29mZnNldCwgc3BhY2luZ30gPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgaGFsZkFuZ2xlID0gKHN0YXJ0QW5nbGUgKyBlbmRBbmdsZSkgLyAyO1xuICAgIGNvbnN0IGhhbGZSYWRpdXMgPSAoaW5uZXJSYWRpdXMgKyBvdXRlclJhZGl1cyArIHNwYWNpbmcgKyBvZmZzZXQpIC8gMjtcbiAgICByZXR1cm4ge1xuICAgICAgeDogeCArIE1hdGguY29zKGhhbGZBbmdsZSkgKiBoYWxmUmFkaXVzLFxuICAgICAgeTogeSArIE1hdGguc2luKGhhbGZBbmdsZSkgKiBoYWxmUmFkaXVzXG4gICAgfTtcbiAgfVxuXG4gIHRvb2x0aXBQb3NpdGlvbih1c2VGaW5hbFBvc2l0aW9uOiBib29sZWFuKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Q2VudGVyUG9pbnQodXNlRmluYWxQb3NpdGlvbik7XG4gIH1cblxuICBkcmF3KGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEKSB7XG4gICAgY29uc3Qge29wdGlvbnMsIGNpcmN1bWZlcmVuY2V9ID0gdGhpcztcbiAgICBjb25zdCBvZmZzZXQgPSAob3B0aW9ucy5vZmZzZXQgfHwgMCkgLyA0O1xuICAgIGNvbnN0IHNwYWNpbmcgPSAob3B0aW9ucy5zcGFjaW5nIHx8IDApIC8gMjtcbiAgICBjb25zdCBjaXJjdWxhciA9IG9wdGlvbnMuY2lyY3VsYXI7XG4gICAgdGhpcy5waXhlbE1hcmdpbiA9IChvcHRpb25zLmJvcmRlckFsaWduID09PSAnaW5uZXInKSA/IDAuMzMgOiAwO1xuICAgIHRoaXMuZnVsbENpcmNsZXMgPSBjaXJjdW1mZXJlbmNlID4gVEFVID8gTWF0aC5mbG9vcihjaXJjdW1mZXJlbmNlIC8gVEFVKSA6IDA7XG5cbiAgICBpZiAoY2lyY3VtZmVyZW5jZSA9PT0gMCB8fCB0aGlzLmlubmVyUmFkaXVzIDwgMCB8fCB0aGlzLm91dGVyUmFkaXVzIDwgMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGN0eC5zYXZlKCk7XG5cbiAgICBjb25zdCBoYWxmQW5nbGUgPSAodGhpcy5zdGFydEFuZ2xlICsgdGhpcy5lbmRBbmdsZSkgLyAyO1xuICAgIGN0eC50cmFuc2xhdGUoTWF0aC5jb3MoaGFsZkFuZ2xlKSAqIG9mZnNldCwgTWF0aC5zaW4oaGFsZkFuZ2xlKSAqIG9mZnNldCk7XG4gICAgY29uc3QgZml4ID0gMSAtIE1hdGguc2luKE1hdGgubWluKFBJLCBjaXJjdW1mZXJlbmNlIHx8IDApKTtcbiAgICBjb25zdCByYWRpdXNPZmZzZXQgPSBvZmZzZXQgKiBmaXg7XG5cbiAgICBjdHguZmlsbFN0eWxlID0gb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgY3R4LnN0cm9rZVN0eWxlID0gb3B0aW9ucy5ib3JkZXJDb2xvcjtcblxuICAgIGRyYXdBcmMoY3R4LCB0aGlzLCByYWRpdXNPZmZzZXQsIHNwYWNpbmcsIGNpcmN1bGFyKTtcbiAgICBkcmF3Qm9yZGVyKGN0eCwgdGhpcywgcmFkaXVzT2Zmc2V0LCBzcGFjaW5nLCBjaXJjdWxhcik7XG5cbiAgICBjdHgucmVzdG9yZSgpO1xuICB9XG59XG4iLCAiaW1wb3J0IEVsZW1lbnQgZnJvbSAnLi4vY29yZS9jb3JlLmVsZW1lbnQuanMnO1xuaW1wb3J0IHtfYmV6aWVySW50ZXJwb2xhdGlvbiwgX3BvaW50SW5MaW5lLCBfc3RlcHBlZEludGVycG9sYXRpb259IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5pbnRlcnBvbGF0aW9uLmpzJztcbmltcG9ydCB7X2NvbXB1dGVTZWdtZW50cywgX2JvdW5kU2VnbWVudHN9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5zZWdtZW50LmpzJztcbmltcG9ydCB7X3N0ZXBwZWRMaW5lVG8sIF9iZXppZXJDdXJ2ZVRvfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY2FudmFzLmpzJztcbmltcG9ydCB7X3VwZGF0ZUJlemllckNvbnRyb2xQb2ludHN9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jdXJ2ZS5qcyc7XG5pbXBvcnQge3ZhbHVlT3JEZWZhdWx0fSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi9lbGVtZW50LnBvaW50LmpzJykuZGVmYXVsdCB9IFBvaW50RWxlbWVudFxuICovXG5cbmZ1bmN0aW9uIHNldFN0eWxlKGN0eCwgb3B0aW9ucywgc3R5bGUgPSBvcHRpb25zKSB7XG4gIGN0eC5saW5lQ2FwID0gdmFsdWVPckRlZmF1bHQoc3R5bGUuYm9yZGVyQ2FwU3R5bGUsIG9wdGlvbnMuYm9yZGVyQ2FwU3R5bGUpO1xuICBjdHguc2V0TGluZURhc2godmFsdWVPckRlZmF1bHQoc3R5bGUuYm9yZGVyRGFzaCwgb3B0aW9ucy5ib3JkZXJEYXNoKSk7XG4gIGN0eC5saW5lRGFzaE9mZnNldCA9IHZhbHVlT3JEZWZhdWx0KHN0eWxlLmJvcmRlckRhc2hPZmZzZXQsIG9wdGlvbnMuYm9yZGVyRGFzaE9mZnNldCk7XG4gIGN0eC5saW5lSm9pbiA9IHZhbHVlT3JEZWZhdWx0KHN0eWxlLmJvcmRlckpvaW5TdHlsZSwgb3B0aW9ucy5ib3JkZXJKb2luU3R5bGUpO1xuICBjdHgubGluZVdpZHRoID0gdmFsdWVPckRlZmF1bHQoc3R5bGUuYm9yZGVyV2lkdGgsIG9wdGlvbnMuYm9yZGVyV2lkdGgpO1xuICBjdHguc3Ryb2tlU3R5bGUgPSB2YWx1ZU9yRGVmYXVsdChzdHlsZS5ib3JkZXJDb2xvciwgb3B0aW9ucy5ib3JkZXJDb2xvcik7XG59XG5cbmZ1bmN0aW9uIGxpbmVUbyhjdHgsIHByZXZpb3VzLCB0YXJnZXQpIHtcbiAgY3R4LmxpbmVUbyh0YXJnZXQueCwgdGFyZ2V0LnkpO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHthbnl9XG4gKi9cbmZ1bmN0aW9uIGdldExpbmVNZXRob2Qob3B0aW9ucykge1xuICBpZiAob3B0aW9ucy5zdGVwcGVkKSB7XG4gICAgcmV0dXJuIF9zdGVwcGVkTGluZVRvO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMudGVuc2lvbiB8fCBvcHRpb25zLmN1YmljSW50ZXJwb2xhdGlvbk1vZGUgPT09ICdtb25vdG9uZScpIHtcbiAgICByZXR1cm4gX2JlemllckN1cnZlVG87XG4gIH1cblxuICByZXR1cm4gbGluZVRvO1xufVxuXG5mdW5jdGlvbiBwYXRoVmFycyhwb2ludHMsIHNlZ21lbnQsIHBhcmFtcyA9IHt9KSB7XG4gIGNvbnN0IGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgY29uc3Qge3N0YXJ0OiBwYXJhbXNTdGFydCA9IDAsIGVuZDogcGFyYW1zRW5kID0gY291bnQgLSAxfSA9IHBhcmFtcztcbiAgY29uc3Qge3N0YXJ0OiBzZWdtZW50U3RhcnQsIGVuZDogc2VnbWVudEVuZH0gPSBzZWdtZW50O1xuICBjb25zdCBzdGFydCA9IE1hdGgubWF4KHBhcmFtc1N0YXJ0LCBzZWdtZW50U3RhcnQpO1xuICBjb25zdCBlbmQgPSBNYXRoLm1pbihwYXJhbXNFbmQsIHNlZ21lbnRFbmQpO1xuICBjb25zdCBvdXRzaWRlID0gcGFyYW1zU3RhcnQgPCBzZWdtZW50U3RhcnQgJiYgcGFyYW1zRW5kIDwgc2VnbWVudFN0YXJ0IHx8IHBhcmFtc1N0YXJ0ID4gc2VnbWVudEVuZCAmJiBwYXJhbXNFbmQgPiBzZWdtZW50RW5kO1xuXG4gIHJldHVybiB7XG4gICAgY291bnQsXG4gICAgc3RhcnQsXG4gICAgbG9vcDogc2VnbWVudC5sb29wLFxuICAgIGlsZW46IGVuZCA8IHN0YXJ0ICYmICFvdXRzaWRlID8gY291bnQgKyBlbmQgLSBzdGFydCA6IGVuZCAtIHN0YXJ0XG4gIH07XG59XG5cbi8qKlxuICogQ3JlYXRlIHBhdGggZnJvbSBwb2ludHMsIGdyb3VwaW5nIGJ5IHRydW5jYXRlZCB4LWNvb3JkaW5hdGVcbiAqIFBvaW50cyBuZWVkIHRvIGJlIGluIG9yZGVyIGJ5IHgtY29vcmRpbmF0ZSBmb3IgdGhpcyB0byB3b3JrIGVmZmljaWVudGx5XG4gKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRHxQYXRoMkR9IGN0eCAtIENvbnRleHRcbiAqIEBwYXJhbSB7TGluZUVsZW1lbnR9IGxpbmVcbiAqIEBwYXJhbSB7b2JqZWN0fSBzZWdtZW50XG4gKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudC5zdGFydCAtIHN0YXJ0IGluZGV4IG9mIHRoZSBzZWdtZW50LCByZWZlcnJpbmcgdGhlIHBvaW50cyBhcnJheVxuICogQHBhcmFtIHtudW1iZXJ9IHNlZ21lbnQuZW5kIC0gZW5kIGluZGV4IG9mIHRoZSBzZWdtZW50LCByZWZlcnJpbmcgdGhlIHBvaW50cyBhcnJheVxuICogQHBhcmFtIHtib29sZWFufSBzZWdtZW50Lmxvb3AgLSBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VnbWVudCBpcyBhIGxvb3BcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gcGFyYW1zLm1vdmUgLSBtb3ZlIHRvIHN0YXJ0aW5nIHBvaW50ICh2cyBsaW5lIHRvIGl0KVxuICogQHBhcmFtIHtib29sZWFufSBwYXJhbXMucmV2ZXJzZSAtIHBhdGggdGhlIHNlZ21lbnQgZnJvbSBlbmQgdG8gc3RhcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBwYXJhbXMuc3RhcnQgLSBsaW1pdCBzZWdtZW50IHRvIHBvaW50cyBzdGFydGluZyBmcm9tIGBzdGFydGAgaW5kZXhcbiAqIEBwYXJhbSB7bnVtYmVyfSBwYXJhbXMuZW5kIC0gbGltaXQgc2VnbWVudCB0byBwb2ludHMgZW5kaW5nIGF0IGBzdGFydGAgKyBgY291bnRgIGluZGV4XG4gKi9cbmZ1bmN0aW9uIHBhdGhTZWdtZW50KGN0eCwgbGluZSwgc2VnbWVudCwgcGFyYW1zKSB7XG4gIGNvbnN0IHtwb2ludHMsIG9wdGlvbnN9ID0gbGluZTtcbiAgY29uc3Qge2NvdW50LCBzdGFydCwgbG9vcCwgaWxlbn0gPSBwYXRoVmFycyhwb2ludHMsIHNlZ21lbnQsIHBhcmFtcyk7XG4gIGNvbnN0IGxpbmVNZXRob2QgPSBnZXRMaW5lTWV0aG9kKG9wdGlvbnMpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gIGxldCB7bW92ZSA9IHRydWUsIHJldmVyc2V9ID0gcGFyYW1zIHx8IHt9O1xuICBsZXQgaSwgcG9pbnQsIHByZXY7XG5cbiAgZm9yIChpID0gMDsgaSA8PSBpbGVuOyArK2kpIHtcbiAgICBwb2ludCA9IHBvaW50c1soc3RhcnQgKyAocmV2ZXJzZSA/IGlsZW4gLSBpIDogaSkpICUgY291bnRdO1xuXG4gICAgaWYgKHBvaW50LnNraXApIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIGEgc2tpcHBlZCBwb2ludCBpbnNpZGUgYSBzZWdtZW50LCBzcGFuR2FwcyBtdXN0IGJlIHRydWVcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gZWxzZSBpZiAobW92ZSkge1xuICAgICAgY3R4Lm1vdmVUbyhwb2ludC54LCBwb2ludC55KTtcbiAgICAgIG1vdmUgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGluZU1ldGhvZChjdHgsIHByZXYsIHBvaW50LCByZXZlcnNlLCBvcHRpb25zLnN0ZXBwZWQpO1xuICAgIH1cblxuICAgIHByZXYgPSBwb2ludDtcbiAgfVxuXG4gIGlmIChsb29wKSB7XG4gICAgcG9pbnQgPSBwb2ludHNbKHN0YXJ0ICsgKHJldmVyc2UgPyBpbGVuIDogMCkpICUgY291bnRdO1xuICAgIGxpbmVNZXRob2QoY3R4LCBwcmV2LCBwb2ludCwgcmV2ZXJzZSwgb3B0aW9ucy5zdGVwcGVkKTtcbiAgfVxuXG4gIHJldHVybiAhIWxvb3A7XG59XG5cbi8qKlxuICogQ3JlYXRlIHBhdGggZnJvbSBwb2ludHMsIGdyb3VwaW5nIGJ5IHRydW5jYXRlZCB4LWNvb3JkaW5hdGVcbiAqIFBvaW50cyBuZWVkIHRvIGJlIGluIG9yZGVyIGJ5IHgtY29vcmRpbmF0ZSBmb3IgdGhpcyB0byB3b3JrIGVmZmljaWVudGx5XG4gKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRHxQYXRoMkR9IGN0eCAtIENvbnRleHRcbiAqIEBwYXJhbSB7TGluZUVsZW1lbnR9IGxpbmVcbiAqIEBwYXJhbSB7b2JqZWN0fSBzZWdtZW50XG4gKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudC5zdGFydCAtIHN0YXJ0IGluZGV4IG9mIHRoZSBzZWdtZW50LCByZWZlcnJpbmcgdGhlIHBvaW50cyBhcnJheVxuICogQHBhcmFtIHtudW1iZXJ9IHNlZ21lbnQuZW5kIC0gZW5kIGluZGV4IG9mIHRoZSBzZWdtZW50LCByZWZlcnJpbmcgdGhlIHBvaW50cyBhcnJheVxuICogQHBhcmFtIHtib29sZWFufSBzZWdtZW50Lmxvb3AgLSBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VnbWVudCBpcyBhIGxvb3BcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gcGFyYW1zLm1vdmUgLSBtb3ZlIHRvIHN0YXJ0aW5nIHBvaW50ICh2cyBsaW5lIHRvIGl0KVxuICogQHBhcmFtIHtib29sZWFufSBwYXJhbXMucmV2ZXJzZSAtIHBhdGggdGhlIHNlZ21lbnQgZnJvbSBlbmQgdG8gc3RhcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBwYXJhbXMuc3RhcnQgLSBsaW1pdCBzZWdtZW50IHRvIHBvaW50cyBzdGFydGluZyBmcm9tIGBzdGFydGAgaW5kZXhcbiAqIEBwYXJhbSB7bnVtYmVyfSBwYXJhbXMuZW5kIC0gbGltaXQgc2VnbWVudCB0byBwb2ludHMgZW5kaW5nIGF0IGBzdGFydGAgKyBgY291bnRgIGluZGV4XG4gKi9cbmZ1bmN0aW9uIGZhc3RQYXRoU2VnbWVudChjdHgsIGxpbmUsIHNlZ21lbnQsIHBhcmFtcykge1xuICBjb25zdCBwb2ludHMgPSBsaW5lLnBvaW50cztcbiAgY29uc3Qge2NvdW50LCBzdGFydCwgaWxlbn0gPSBwYXRoVmFycyhwb2ludHMsIHNlZ21lbnQsIHBhcmFtcyk7XG4gIGNvbnN0IHttb3ZlID0gdHJ1ZSwgcmV2ZXJzZX0gPSBwYXJhbXMgfHwge307XG4gIGxldCBhdmdYID0gMDtcbiAgbGV0IGNvdW50WCA9IDA7XG4gIGxldCBpLCBwb2ludCwgcHJldlgsIG1pblksIG1heFksIGxhc3RZO1xuXG4gIGNvbnN0IHBvaW50SW5kZXggPSAoaW5kZXgpID0+IChzdGFydCArIChyZXZlcnNlID8gaWxlbiAtIGluZGV4IDogaW5kZXgpKSAlIGNvdW50O1xuICBjb25zdCBkcmF3WCA9ICgpID0+IHtcbiAgICBpZiAobWluWSAhPT0gbWF4WSkge1xuICAgICAgLy8gRHJhdyBsaW5lIHRvIG1heFkgYW5kIG1pblksIHVzaW5nIHRoZSBhdmVyYWdlIHgtY29vcmRpbmF0ZVxuICAgICAgY3R4LmxpbmVUbyhhdmdYLCBtYXhZKTtcbiAgICAgIGN0eC5saW5lVG8oYXZnWCwgbWluWSk7XG4gICAgICAvLyBMaW5lIHRvIHktdmFsdWUgb2YgbGFzdCBwb2ludCBpbiBncm91cC4gU28gdGhlIGxpbmUgY29udGludWVzXG4gICAgICAvLyBmcm9tIGNvcnJlY3QgcG9zaXRpb24uIE5vdCB1c2luZyBtb3ZlLCB0byBoYXZlIHNvbGlkIHBhdGguXG4gICAgICBjdHgubGluZVRvKGF2Z1gsIGxhc3RZKTtcbiAgICB9XG4gIH07XG5cbiAgaWYgKG1vdmUpIHtcbiAgICBwb2ludCA9IHBvaW50c1twb2ludEluZGV4KDApXTtcbiAgICBjdHgubW92ZVRvKHBvaW50LngsIHBvaW50LnkpO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8PSBpbGVuOyArK2kpIHtcbiAgICBwb2ludCA9IHBvaW50c1twb2ludEluZGV4KGkpXTtcblxuICAgIGlmIChwb2ludC5za2lwKSB7XG4gICAgICAvLyBJZiB0aGVyZSBpcyBhIHNraXBwZWQgcG9pbnQgaW5zaWRlIGEgc2VnbWVudCwgc3BhbkdhcHMgbXVzdCBiZSB0cnVlXG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCB4ID0gcG9pbnQueDtcbiAgICBjb25zdCB5ID0gcG9pbnQueTtcbiAgICBjb25zdCB0cnVuY1ggPSB4IHwgMDsgLy8gdHJ1bmNhdGVkIHgtY29vcmRpbmF0ZVxuXG4gICAgaWYgKHRydW5jWCA9PT0gcHJldlgpIHtcbiAgICAgIC8vIERldGVybWluZSBgbWluWWAgLyBgbWF4WWAgYW5kIGBhdmdYYCB3aGlsZSB3ZSBzdGF5IHdpdGhpbiBzYW1lIHgtcG9zaXRpb25cbiAgICAgIGlmICh5IDwgbWluWSkge1xuICAgICAgICBtaW5ZID0geTtcbiAgICAgIH0gZWxzZSBpZiAoeSA+IG1heFkpIHtcbiAgICAgICAgbWF4WSA9IHk7XG4gICAgICB9XG4gICAgICAvLyBGb3IgZmlyc3QgcG9pbnQgaW4gZ3JvdXAsIGNvdW50WCBpcyBgMGAsIHNvIGF2ZXJhZ2Ugd2lsbCBiZSBgeGAgLyAxLlxuICAgICAgYXZnWCA9IChjb3VudFggKiBhdmdYICsgeCkgLyArK2NvdW50WDtcbiAgICB9IGVsc2Uge1xuICAgICAgZHJhd1goKTtcbiAgICAgIC8vIERyYXcgbGluZSB0byBuZXh0IHgtcG9zaXRpb24sIHVzaW5nIHRoZSBmaXJzdCAob3Igb25seSlcbiAgICAgIC8vIHktdmFsdWUgaW4gdGhhdCBncm91cFxuICAgICAgY3R4LmxpbmVUbyh4LCB5KTtcblxuICAgICAgcHJldlggPSB0cnVuY1g7XG4gICAgICBjb3VudFggPSAwO1xuICAgICAgbWluWSA9IG1heFkgPSB5O1xuICAgIH1cbiAgICAvLyBLZWVwIHRyYWNrIG9mIHRoZSBsYXN0IHktdmFsdWUgaW4gZ3JvdXBcbiAgICBsYXN0WSA9IHk7XG4gIH1cbiAgZHJhd1goKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0xpbmVFbGVtZW50fSBsaW5lIC0gdGhlIGxpbmVcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIF9nZXRTZWdtZW50TWV0aG9kKGxpbmUpIHtcbiAgY29uc3Qgb3B0cyA9IGxpbmUub3B0aW9ucztcbiAgY29uc3QgYm9yZGVyRGFzaCA9IG9wdHMuYm9yZGVyRGFzaCAmJiBvcHRzLmJvcmRlckRhc2gubGVuZ3RoO1xuICBjb25zdCB1c2VGYXN0UGF0aCA9ICFsaW5lLl9kZWNpbWF0ZWQgJiYgIWxpbmUuX2xvb3AgJiYgIW9wdHMudGVuc2lvbiAmJiBvcHRzLmN1YmljSW50ZXJwb2xhdGlvbk1vZGUgIT09ICdtb25vdG9uZScgJiYgIW9wdHMuc3RlcHBlZCAmJiAhYm9yZGVyRGFzaDtcbiAgcmV0dXJuIHVzZUZhc3RQYXRoID8gZmFzdFBhdGhTZWdtZW50IDogcGF0aFNlZ21lbnQ7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gX2dldEludGVycG9sYXRpb25NZXRob2Qob3B0aW9ucykge1xuICBpZiAob3B0aW9ucy5zdGVwcGVkKSB7XG4gICAgcmV0dXJuIF9zdGVwcGVkSW50ZXJwb2xhdGlvbjtcbiAgfVxuXG4gIGlmIChvcHRpb25zLnRlbnNpb24gfHwgb3B0aW9ucy5jdWJpY0ludGVycG9sYXRpb25Nb2RlID09PSAnbW9ub3RvbmUnKSB7XG4gICAgcmV0dXJuIF9iZXppZXJJbnRlcnBvbGF0aW9uO1xuICB9XG5cbiAgcmV0dXJuIF9wb2ludEluTGluZTtcbn1cblxuZnVuY3Rpb24gc3Ryb2tlUGF0aFdpdGhDYWNoZShjdHgsIGxpbmUsIHN0YXJ0LCBjb3VudCkge1xuICBsZXQgcGF0aCA9IGxpbmUuX3BhdGg7XG4gIGlmICghcGF0aCkge1xuICAgIHBhdGggPSBsaW5lLl9wYXRoID0gbmV3IFBhdGgyRCgpO1xuICAgIGlmIChsaW5lLnBhdGgocGF0aCwgc3RhcnQsIGNvdW50KSkge1xuICAgICAgcGF0aC5jbG9zZVBhdGgoKTtcbiAgICB9XG4gIH1cbiAgc2V0U3R5bGUoY3R4LCBsaW5lLm9wdGlvbnMpO1xuICBjdHguc3Ryb2tlKHBhdGgpO1xufVxuXG5mdW5jdGlvbiBzdHJva2VQYXRoRGlyZWN0KGN0eCwgbGluZSwgc3RhcnQsIGNvdW50KSB7XG4gIGNvbnN0IHtzZWdtZW50cywgb3B0aW9uc30gPSBsaW5lO1xuICBjb25zdCBzZWdtZW50TWV0aG9kID0gX2dldFNlZ21lbnRNZXRob2QobGluZSk7XG5cbiAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgc2V0U3R5bGUoY3R4LCBvcHRpb25zLCBzZWdtZW50LnN0eWxlKTtcbiAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgaWYgKHNlZ21lbnRNZXRob2QoY3R4LCBsaW5lLCBzZWdtZW50LCB7c3RhcnQsIGVuZDogc3RhcnQgKyBjb3VudCAtIDF9KSkge1xuICAgICAgY3R4LmNsb3NlUGF0aCgpO1xuICAgIH1cbiAgICBjdHguc3Ryb2tlKCk7XG4gIH1cbn1cblxuY29uc3QgdXNlUGF0aDJEID0gdHlwZW9mIFBhdGgyRCA9PT0gJ2Z1bmN0aW9uJztcblxuZnVuY3Rpb24gZHJhdyhjdHgsIGxpbmUsIHN0YXJ0LCBjb3VudCkge1xuICBpZiAodXNlUGF0aDJEICYmICFsaW5lLm9wdGlvbnMuc2VnbWVudCkge1xuICAgIHN0cm9rZVBhdGhXaXRoQ2FjaGUoY3R4LCBsaW5lLCBzdGFydCwgY291bnQpO1xuICB9IGVsc2Uge1xuICAgIHN0cm9rZVBhdGhEaXJlY3QoY3R4LCBsaW5lLCBzdGFydCwgY291bnQpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpbmVFbGVtZW50IGV4dGVuZHMgRWxlbWVudCB7XG5cbiAgc3RhdGljIGlkID0gJ2xpbmUnO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIGJvcmRlckNhcFN0eWxlOiAnYnV0dCcsXG4gICAgYm9yZGVyRGFzaDogW10sXG4gICAgYm9yZGVyRGFzaE9mZnNldDogMCxcbiAgICBib3JkZXJKb2luU3R5bGU6ICdtaXRlcicsXG4gICAgYm9yZGVyV2lkdGg6IDMsXG4gICAgY2FwQmV6aWVyUG9pbnRzOiB0cnVlLFxuICAgIGN1YmljSW50ZXJwb2xhdGlvbk1vZGU6ICdkZWZhdWx0JyxcbiAgICBmaWxsOiBmYWxzZSxcbiAgICBzcGFuR2FwczogZmFsc2UsXG4gICAgc3RlcHBlZDogZmFsc2UsXG4gICAgdGVuc2lvbjogMCxcbiAgfTtcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0Um91dGVzID0ge1xuICAgIGJhY2tncm91bmRDb2xvcjogJ2JhY2tncm91bmRDb2xvcicsXG4gICAgYm9yZGVyQ29sb3I6ICdib3JkZXJDb2xvcidcbiAgfTtcblxuXG4gIHN0YXRpYyBkZXNjcmlwdG9ycyA9IHtcbiAgICBfc2NyaXB0YWJsZTogdHJ1ZSxcbiAgICBfaW5kZXhhYmxlOiAobmFtZSkgPT4gbmFtZSAhPT0gJ2JvcmRlckRhc2gnICYmIG5hbWUgIT09ICdmaWxsJyxcbiAgfTtcblxuXG4gIGNvbnN0cnVjdG9yKGNmZykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLmFuaW1hdGVkID0gdHJ1ZTtcbiAgICB0aGlzLm9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fY2hhcnQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fbG9vcCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9mdWxsTG9vcCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9wYXRoID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3BvaW50cyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9zZWdtZW50cyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9kZWNpbWF0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9wb2ludHNVcGRhdGVkID0gZmFsc2U7XG4gICAgdGhpcy5fZGF0YXNldEluZGV4ID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGNmZykge1xuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBjZmcpO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUNvbnRyb2xQb2ludHMoY2hhcnRBcmVhLCBpbmRleEF4aXMpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGlmICgob3B0aW9ucy50ZW5zaW9uIHx8IG9wdGlvbnMuY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSA9PT0gJ21vbm90b25lJykgJiYgIW9wdGlvbnMuc3RlcHBlZCAmJiAhdGhpcy5fcG9pbnRzVXBkYXRlZCkge1xuICAgICAgY29uc3QgbG9vcCA9IG9wdGlvbnMuc3BhbkdhcHMgPyB0aGlzLl9sb29wIDogdGhpcy5fZnVsbExvb3A7XG4gICAgICBfdXBkYXRlQmV6aWVyQ29udHJvbFBvaW50cyh0aGlzLl9wb2ludHMsIG9wdGlvbnMsIGNoYXJ0QXJlYSwgbG9vcCwgaW5kZXhBeGlzKTtcbiAgICAgIHRoaXMuX3BvaW50c1VwZGF0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHNldCBwb2ludHMocG9pbnRzKSB7XG4gICAgdGhpcy5fcG9pbnRzID0gcG9pbnRzO1xuICAgIGRlbGV0ZSB0aGlzLl9zZWdtZW50cztcbiAgICBkZWxldGUgdGhpcy5fcGF0aDtcbiAgICB0aGlzLl9wb2ludHNVcGRhdGVkID0gZmFsc2U7XG4gIH1cblxuICBnZXQgcG9pbnRzKCkge1xuICAgIHJldHVybiB0aGlzLl9wb2ludHM7XG4gIH1cblxuICBnZXQgc2VnbWVudHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NlZ21lbnRzIHx8ICh0aGlzLl9zZWdtZW50cyA9IF9jb21wdXRlU2VnbWVudHModGhpcywgdGhpcy5vcHRpb25zLnNlZ21lbnQpKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBGaXJzdCBub24tc2tpcHBlZCBwb2ludCBvbiB0aGlzIGxpbmVcblx0ICogQHJldHVybnMge1BvaW50RWxlbWVudHx1bmRlZmluZWR9XG5cdCAqL1xuICBmaXJzdCgpIHtcbiAgICBjb25zdCBzZWdtZW50cyA9IHRoaXMuc2VnbWVudHM7XG4gICAgY29uc3QgcG9pbnRzID0gdGhpcy5wb2ludHM7XG4gICAgcmV0dXJuIHNlZ21lbnRzLmxlbmd0aCAmJiBwb2ludHNbc2VnbWVudHNbMF0uc3RhcnRdO1xuICB9XG5cbiAgLyoqXG5cdCAqIExhc3Qgbm9uLXNraXBwZWQgcG9pbnQgb24gdGhpcyBsaW5lXG5cdCAqIEByZXR1cm5zIHtQb2ludEVsZW1lbnR8dW5kZWZpbmVkfVxuXHQgKi9cbiAgbGFzdCgpIHtcbiAgICBjb25zdCBzZWdtZW50cyA9IHRoaXMuc2VnbWVudHM7XG4gICAgY29uc3QgcG9pbnRzID0gdGhpcy5wb2ludHM7XG4gICAgY29uc3QgY291bnQgPSBzZWdtZW50cy5sZW5ndGg7XG4gICAgcmV0dXJuIGNvdW50ICYmIHBvaW50c1tzZWdtZW50c1tjb3VudCAtIDFdLmVuZF07XG4gIH1cblxuICAvKipcblx0ICogSW50ZXJwb2xhdGUgYSBwb2ludCBpbiB0aGlzIGxpbmUgYXQgdGhlIHNhbWUgdmFsdWUgb24gYHByb3BlcnR5YCBhc1xuXHQgKiB0aGUgcmVmZXJlbmNlIGBwb2ludGAgcHJvdmlkZWRcblx0ICogQHBhcmFtIHtQb2ludEVsZW1lbnR9IHBvaW50IC0gdGhlIHJlZmVyZW5jZSBwb2ludFxuXHQgKiBAcGFyYW0ge3N0cmluZ30gcHJvcGVydHkgLSB0aGUgcHJvcGVydHkgdG8gbWF0Y2ggb25cblx0ICogQHJldHVybnMge1BvaW50RWxlbWVudHx1bmRlZmluZWR9XG5cdCAqL1xuICBpbnRlcnBvbGF0ZShwb2ludCwgcHJvcGVydHkpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHZhbHVlID0gcG9pbnRbcHJvcGVydHldO1xuICAgIGNvbnN0IHBvaW50cyA9IHRoaXMucG9pbnRzO1xuICAgIGNvbnN0IHNlZ21lbnRzID0gX2JvdW5kU2VnbWVudHModGhpcywge3Byb3BlcnR5LCBzdGFydDogdmFsdWUsIGVuZDogdmFsdWV9KTtcblxuICAgIGlmICghc2VnbWVudHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgY29uc3QgX2ludGVycG9sYXRlID0gX2dldEludGVycG9sYXRpb25NZXRob2Qob3B0aW9ucyk7XG4gICAgbGV0IGksIGlsZW47XG4gICAgZm9yIChpID0gMCwgaWxlbiA9IHNlZ21lbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgY29uc3Qge3N0YXJ0LCBlbmR9ID0gc2VnbWVudHNbaV07XG4gICAgICBjb25zdCBwMSA9IHBvaW50c1tzdGFydF07XG4gICAgICBjb25zdCBwMiA9IHBvaW50c1tlbmRdO1xuICAgICAgaWYgKHAxID09PSBwMikge1xuICAgICAgICByZXN1bHQucHVzaChwMSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgdCA9IE1hdGguYWJzKCh2YWx1ZSAtIHAxW3Byb3BlcnR5XSkgLyAocDJbcHJvcGVydHldIC0gcDFbcHJvcGVydHldKSk7XG4gICAgICBjb25zdCBpbnRlcnBvbGF0ZWQgPSBfaW50ZXJwb2xhdGUocDEsIHAyLCB0LCBvcHRpb25zLnN0ZXBwZWQpO1xuICAgICAgaW50ZXJwb2xhdGVkW3Byb3BlcnR5XSA9IHBvaW50W3Byb3BlcnR5XTtcbiAgICAgIHJlc3VsdC5wdXNoKGludGVycG9sYXRlZCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQubGVuZ3RoID09PSAxID8gcmVzdWx0WzBdIDogcmVzdWx0O1xuICB9XG5cbiAgLyoqXG5cdCAqIEFwcGVuZCBhIHNlZ21lbnQgb2YgdGhpcyBsaW5lIHRvIGN1cnJlbnQgcGF0aC5cblx0ICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGN0eFxuXHQgKiBAcGFyYW0ge29iamVjdH0gc2VnbWVudFxuXHQgKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudC5zdGFydCAtIHN0YXJ0IGluZGV4IG9mIHRoZSBzZWdtZW50LCByZWZlcnJpbmcgdGhlIHBvaW50cyBhcnJheVxuIFx0ICogQHBhcmFtIHtudW1iZXJ9IHNlZ21lbnQuZW5kIC0gZW5kIGluZGV4IG9mIHRoZSBzZWdtZW50LCByZWZlcnJpbmcgdGhlIHBvaW50cyBhcnJheVxuIFx0ICogQHBhcmFtIHtib29sZWFufSBzZWdtZW50Lmxvb3AgLSBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VnbWVudCBpcyBhIGxvb3Bcblx0ICogQHBhcmFtIHtvYmplY3R9IHBhcmFtc1xuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IHBhcmFtcy5tb3ZlIC0gbW92ZSB0byBzdGFydGluZyBwb2ludCAodnMgbGluZSB0byBpdClcblx0ICogQHBhcmFtIHtib29sZWFufSBwYXJhbXMucmV2ZXJzZSAtIHBhdGggdGhlIHNlZ21lbnQgZnJvbSBlbmQgdG8gc3RhcnRcblx0ICogQHBhcmFtIHtudW1iZXJ9IHBhcmFtcy5zdGFydCAtIGxpbWl0IHNlZ21lbnQgdG8gcG9pbnRzIHN0YXJ0aW5nIGZyb20gYHN0YXJ0YCBpbmRleFxuXHQgKiBAcGFyYW0ge251bWJlcn0gcGFyYW1zLmVuZCAtIGxpbWl0IHNlZ21lbnQgdG8gcG9pbnRzIGVuZGluZyBhdCBgc3RhcnRgICsgYGNvdW50YCBpbmRleFxuXHQgKiBAcmV0dXJucyB7dW5kZWZpbmVkfGJvb2xlYW59IC0gdHJ1ZSBpZiB0aGUgc2VnbWVudCBpcyBhIGZ1bGwgbG9vcCAocGF0aCBzaG91bGQgYmUgY2xvc2VkKVxuXHQgKi9cbiAgcGF0aFNlZ21lbnQoY3R4LCBzZWdtZW50LCBwYXJhbXMpIHtcbiAgICBjb25zdCBzZWdtZW50TWV0aG9kID0gX2dldFNlZ21lbnRNZXRob2QodGhpcyk7XG4gICAgcmV0dXJuIHNlZ21lbnRNZXRob2QoY3R4LCB0aGlzLCBzZWdtZW50LCBwYXJhbXMpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEFwcGVuZCBhbGwgc2VnbWVudHMgb2YgdGhpcyBsaW5lIHRvIGN1cnJlbnQgcGF0aC5cblx0ICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR8UGF0aDJEfSBjdHhcblx0ICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydF1cblx0ICogQHBhcmFtIHtudW1iZXJ9IFtjb3VudF1cblx0ICogQHJldHVybnMge3VuZGVmaW5lZHxib29sZWFufSAtIHRydWUgaWYgbGluZSBpcyBhIGZ1bGwgbG9vcCAocGF0aCBzaG91bGQgYmUgY2xvc2VkKVxuXHQgKi9cbiAgcGF0aChjdHgsIHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IHNlZ21lbnRzID0gdGhpcy5zZWdtZW50cztcbiAgICBjb25zdCBzZWdtZW50TWV0aG9kID0gX2dldFNlZ21lbnRNZXRob2QodGhpcyk7XG4gICAgbGV0IGxvb3AgPSB0aGlzLl9sb29wO1xuXG4gICAgc3RhcnQgPSBzdGFydCB8fCAwO1xuICAgIGNvdW50ID0gY291bnQgfHwgKHRoaXMucG9pbnRzLmxlbmd0aCAtIHN0YXJ0KTtcblxuICAgIGZvciAoY29uc3Qgc2VnbWVudCBvZiBzZWdtZW50cykge1xuICAgICAgbG9vcCAmPSBzZWdtZW50TWV0aG9kKGN0eCwgdGhpcywgc2VnbWVudCwge3N0YXJ0LCBlbmQ6IHN0YXJ0ICsgY291bnQgLSAxfSk7XG4gICAgfVxuICAgIHJldHVybiAhIWxvb3A7XG4gIH1cblxuICAvKipcblx0ICogRHJhd1xuXHQgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY3R4XG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBjaGFydEFyZWFcblx0ICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydF1cblx0ICogQHBhcmFtIHtudW1iZXJ9IFtjb3VudF1cblx0ICovXG4gIGRyYXcoY3R4LCBjaGFydEFyZWEsIHN0YXJ0LCBjb3VudCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMgfHwge307XG4gICAgY29uc3QgcG9pbnRzID0gdGhpcy5wb2ludHMgfHwgW107XG5cbiAgICBpZiAocG9pbnRzLmxlbmd0aCAmJiBvcHRpb25zLmJvcmRlcldpZHRoKSB7XG4gICAgICBjdHguc2F2ZSgpO1xuXG4gICAgICBkcmF3KGN0eCwgdGhpcywgc3RhcnQsIGNvdW50KTtcblxuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hbmltYXRlZCkge1xuICAgICAgLy8gV2hlbiBsaW5lIGlzIGFuaW1hdGVkLCB0aGUgY29udHJvbCBwb2ludHMgYW5kIHBhdGggYXJlIG5vdCBjYWNoZWQuXG4gICAgICB0aGlzLl9wb2ludHNVcGRhdGVkID0gZmFsc2U7XG4gICAgICB0aGlzLl9wYXRoID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufVxuIiwgImltcG9ydCBFbGVtZW50IGZyb20gJy4uL2NvcmUvY29yZS5lbGVtZW50LmpzJztcbmltcG9ydCB7ZHJhd1BvaW50LCBfaXNQb2ludEluQXJlYX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNhbnZhcy5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIENhcnRlc2lhblBhcnNlZERhdGEsXG4gIENoYXJ0QXJlYSxcbiAgUG9pbnQsXG4gIFBvaW50SG92ZXJPcHRpb25zLFxuICBQb2ludE9wdGlvbnMsXG59IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcblxuZnVuY3Rpb24gaW5SYW5nZShlbDogUG9pbnRFbGVtZW50LCBwb3M6IG51bWJlciwgYXhpczogJ3gnIHwgJ3knLCB1c2VGaW5hbFBvc2l0aW9uPzogYm9vbGVhbikge1xuICBjb25zdCBvcHRpb25zID0gZWwub3B0aW9ucztcbiAgY29uc3Qge1theGlzXTogdmFsdWV9ID0gZWwuZ2V0UHJvcHMoW2F4aXNdLCB1c2VGaW5hbFBvc2l0aW9uKTtcblxuICByZXR1cm4gKE1hdGguYWJzKHBvcyAtIHZhbHVlKSA8IG9wdGlvbnMucmFkaXVzICsgb3B0aW9ucy5oaXRSYWRpdXMpO1xufVxuXG5leHBvcnQgdHlwZSBQb2ludFByb3BzID0gUG9pbnRcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUG9pbnRFbGVtZW50IGV4dGVuZHMgRWxlbWVudDxQb2ludFByb3BzLCBQb2ludE9wdGlvbnMgJiBQb2ludEhvdmVyT3B0aW9ucz4ge1xuXG4gIHN0YXRpYyBpZCA9ICdwb2ludCc7XG5cbiAgcGFyc2VkOiBDYXJ0ZXNpYW5QYXJzZWREYXRhO1xuICBza2lwPzogYm9vbGVhbjtcbiAgc3RvcD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgYm9yZGVyV2lkdGg6IDEsXG4gICAgaGl0UmFkaXVzOiAxLFxuICAgIGhvdmVyQm9yZGVyV2lkdGg6IDEsXG4gICAgaG92ZXJSYWRpdXM6IDQsXG4gICAgcG9pbnRTdHlsZTogJ2NpcmNsZScsXG4gICAgcmFkaXVzOiAzLFxuICAgIHJvdGF0aW9uOiAwXG4gIH07XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdFJvdXRlcyA9IHtcbiAgICBiYWNrZ3JvdW5kQ29sb3I6ICdiYWNrZ3JvdW5kQ29sb3InLFxuICAgIGJvcmRlckNvbG9yOiAnYm9yZGVyQ29sb3InXG4gIH07XG5cbiAgY29uc3RydWN0b3IoY2ZnKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMub3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnBhcnNlZCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnNraXAgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5zdG9wID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGNmZykge1xuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBjZmcpO1xuICAgIH1cbiAgfVxuXG4gIGluUmFuZ2UobW91c2VYOiBudW1iZXIsIG1vdXNlWTogbnVtYmVyLCB1c2VGaW5hbFBvc2l0aW9uPzogYm9vbGVhbikge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3Qge3gsIHl9ID0gdGhpcy5nZXRQcm9wcyhbJ3gnLCAneSddLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICByZXR1cm4gKChNYXRoLnBvdyhtb3VzZVggLSB4LCAyKSArIE1hdGgucG93KG1vdXNlWSAtIHksIDIpKSA8IE1hdGgucG93KG9wdGlvbnMuaGl0UmFkaXVzICsgb3B0aW9ucy5yYWRpdXMsIDIpKTtcbiAgfVxuXG4gIGluWFJhbmdlKG1vdXNlWDogbnVtYmVyLCB1c2VGaW5hbFBvc2l0aW9uPzogYm9vbGVhbikge1xuICAgIHJldHVybiBpblJhbmdlKHRoaXMsIG1vdXNlWCwgJ3gnLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgfVxuXG4gIGluWVJhbmdlKG1vdXNlWTogbnVtYmVyLCB1c2VGaW5hbFBvc2l0aW9uPzogYm9vbGVhbikge1xuICAgIHJldHVybiBpblJhbmdlKHRoaXMsIG1vdXNlWSwgJ3knLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgfVxuXG4gIGdldENlbnRlclBvaW50KHVzZUZpbmFsUG9zaXRpb24/OiBib29sZWFuKSB7XG4gICAgY29uc3Qge3gsIHl9ID0gdGhpcy5nZXRQcm9wcyhbJ3gnLCAneSddLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgICByZXR1cm4ge3gsIHl9O1xuICB9XG5cbiAgc2l6ZShvcHRpb25zPzogUGFydGlhbDxQb2ludE9wdGlvbnMgJiBQb2ludEhvdmVyT3B0aW9ucz4pIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB0aGlzLm9wdGlvbnMgfHwge307XG4gICAgbGV0IHJhZGl1cyA9IG9wdGlvbnMucmFkaXVzIHx8IDA7XG4gICAgcmFkaXVzID0gTWF0aC5tYXgocmFkaXVzLCByYWRpdXMgJiYgb3B0aW9ucy5ob3ZlclJhZGl1cyB8fCAwKTtcbiAgICBjb25zdCBib3JkZXJXaWR0aCA9IHJhZGl1cyAmJiBvcHRpb25zLmJvcmRlcldpZHRoIHx8IDA7XG4gICAgcmV0dXJuIChyYWRpdXMgKyBib3JkZXJXaWR0aCkgKiAyO1xuICB9XG5cbiAgZHJhdyhjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgYXJlYTogQ2hhcnRBcmVhKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcblxuICAgIGlmICh0aGlzLnNraXAgfHwgb3B0aW9ucy5yYWRpdXMgPCAwLjEgfHwgIV9pc1BvaW50SW5BcmVhKHRoaXMsIGFyZWEsIHRoaXMuc2l6ZShvcHRpb25zKSAvIDIpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY3R4LnN0cm9rZVN0eWxlID0gb3B0aW9ucy5ib3JkZXJDb2xvcjtcbiAgICBjdHgubGluZVdpZHRoID0gb3B0aW9ucy5ib3JkZXJXaWR0aDtcbiAgICBjdHguZmlsbFN0eWxlID0gb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgZHJhd1BvaW50KGN0eCwgb3B0aW9ucywgdGhpcy54LCB0aGlzLnkpO1xuICB9XG5cbiAgZ2V0UmFuZ2UoKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyB8fCB7fTtcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIEZhbGxiYWNrcyBzaG91bGQgbmV2ZXIgYmUgaGl0IGluIHByYWN0aWNlXG4gICAgcmV0dXJuIG9wdGlvbnMucmFkaXVzICsgb3B0aW9ucy5oaXRSYWRpdXM7XG4gIH1cbn1cbiIsICJpbXBvcnQgRWxlbWVudCBmcm9tICcuLi9jb3JlL2NvcmUuZWxlbWVudC5qcyc7XG5pbXBvcnQge2lzT2JqZWN0LCBfaXNCZXR3ZWVuLCBfbGltaXRWYWx1ZX0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5pbXBvcnQge2FkZFJvdW5kZWRSZWN0UGF0aH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNhbnZhcy5qcyc7XG5pbXBvcnQge3RvVFJCTCwgdG9UUkJMQ29ybmVyc30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm9wdGlvbnMuanMnO1xuXG4vKiogQHR5cGVkZWYge3sgeDogbnVtYmVyLCB5OiBudW1iZXIsIGJhc2U6IG51bWJlciwgaG9yaXpvbnRhbDogYm9vbGVhbiwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIgfX0gQmFyUHJvcHMgKi9cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHRoZSBib3VuZHMgb2YgdGhlIGJhciByZWdhcmRsZXNzIG9mIHRoZSBvcmllbnRhdGlvblxuICogQHBhcmFtIHtCYXJFbGVtZW50fSBiYXIgdGhlIGJhclxuICogQHBhcmFtIHtib29sZWFufSBbdXNlRmluYWxQb3NpdGlvbl1cbiAqIEByZXR1cm4ge29iamVjdH0gYm91bmRzIG9mIHRoZSBiYXJcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGdldEJhckJvdW5kcyhiYXIsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgY29uc3Qge3gsIHksIGJhc2UsIHdpZHRoLCBoZWlnaHR9ID0gLyoqIEB0eXBlIHtCYXJQcm9wc30gKi8gKGJhci5nZXRQcm9wcyhbJ3gnLCAneScsICdiYXNlJywgJ3dpZHRoJywgJ2hlaWdodCddLCB1c2VGaW5hbFBvc2l0aW9uKSk7XG5cbiAgbGV0IGxlZnQsIHJpZ2h0LCB0b3AsIGJvdHRvbSwgaGFsZjtcblxuICBpZiAoYmFyLmhvcml6b250YWwpIHtcbiAgICBoYWxmID0gaGVpZ2h0IC8gMjtcbiAgICBsZWZ0ID0gTWF0aC5taW4oeCwgYmFzZSk7XG4gICAgcmlnaHQgPSBNYXRoLm1heCh4LCBiYXNlKTtcbiAgICB0b3AgPSB5IC0gaGFsZjtcbiAgICBib3R0b20gPSB5ICsgaGFsZjtcbiAgfSBlbHNlIHtcbiAgICBoYWxmID0gd2lkdGggLyAyO1xuICAgIGxlZnQgPSB4IC0gaGFsZjtcbiAgICByaWdodCA9IHggKyBoYWxmO1xuICAgIHRvcCA9IE1hdGgubWluKHksIGJhc2UpO1xuICAgIGJvdHRvbSA9IE1hdGgubWF4KHksIGJhc2UpO1xuICB9XG5cbiAgcmV0dXJuIHtsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b219O1xufVxuXG5mdW5jdGlvbiBza2lwT3JMaW1pdChza2lwLCB2YWx1ZSwgbWluLCBtYXgpIHtcbiAgcmV0dXJuIHNraXAgPyAwIDogX2xpbWl0VmFsdWUodmFsdWUsIG1pbiwgbWF4KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VCb3JkZXJXaWR0aChiYXIsIG1heFcsIG1heEgpIHtcbiAgY29uc3QgdmFsdWUgPSBiYXIub3B0aW9ucy5ib3JkZXJXaWR0aDtcbiAgY29uc3Qgc2tpcCA9IGJhci5ib3JkZXJTa2lwcGVkO1xuICBjb25zdCBvID0gdG9UUkJMKHZhbHVlKTtcblxuICByZXR1cm4ge1xuICAgIHQ6IHNraXBPckxpbWl0KHNraXAudG9wLCBvLnRvcCwgMCwgbWF4SCksXG4gICAgcjogc2tpcE9yTGltaXQoc2tpcC5yaWdodCwgby5yaWdodCwgMCwgbWF4VyksXG4gICAgYjogc2tpcE9yTGltaXQoc2tpcC5ib3R0b20sIG8uYm90dG9tLCAwLCBtYXhIKSxcbiAgICBsOiBza2lwT3JMaW1pdChza2lwLmxlZnQsIG8ubGVmdCwgMCwgbWF4VylcbiAgfTtcbn1cblxuZnVuY3Rpb24gcGFyc2VCb3JkZXJSYWRpdXMoYmFyLCBtYXhXLCBtYXhIKSB7XG4gIGNvbnN0IHtlbmFibGVCb3JkZXJSYWRpdXN9ID0gYmFyLmdldFByb3BzKFsnZW5hYmxlQm9yZGVyUmFkaXVzJ10pO1xuICBjb25zdCB2YWx1ZSA9IGJhci5vcHRpb25zLmJvcmRlclJhZGl1cztcbiAgY29uc3QgbyA9IHRvVFJCTENvcm5lcnModmFsdWUpO1xuICBjb25zdCBtYXhSID0gTWF0aC5taW4obWF4VywgbWF4SCk7XG4gIGNvbnN0IHNraXAgPSBiYXIuYm9yZGVyU2tpcHBlZDtcblxuICAvLyBJZiB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0LCBhc3N1bWUgdGhlIHVzZXIga25vd3Mgd2hhdCB0aGV5IGFyZSBkb2luZ1xuICAvLyBhbmQgYXBwbHkgYXMgZGlyZWN0ZWQuXG4gIGNvbnN0IGVuYWJsZUJvcmRlciA9IGVuYWJsZUJvcmRlclJhZGl1cyB8fCBpc09iamVjdCh2YWx1ZSk7XG5cbiAgcmV0dXJuIHtcbiAgICB0b3BMZWZ0OiBza2lwT3JMaW1pdCghZW5hYmxlQm9yZGVyIHx8IHNraXAudG9wIHx8IHNraXAubGVmdCwgby50b3BMZWZ0LCAwLCBtYXhSKSxcbiAgICB0b3BSaWdodDogc2tpcE9yTGltaXQoIWVuYWJsZUJvcmRlciB8fCBza2lwLnRvcCB8fCBza2lwLnJpZ2h0LCBvLnRvcFJpZ2h0LCAwLCBtYXhSKSxcbiAgICBib3R0b21MZWZ0OiBza2lwT3JMaW1pdCghZW5hYmxlQm9yZGVyIHx8IHNraXAuYm90dG9tIHx8IHNraXAubGVmdCwgby5ib3R0b21MZWZ0LCAwLCBtYXhSKSxcbiAgICBib3R0b21SaWdodDogc2tpcE9yTGltaXQoIWVuYWJsZUJvcmRlciB8fCBza2lwLmJvdHRvbSB8fCBza2lwLnJpZ2h0LCBvLmJvdHRvbVJpZ2h0LCAwLCBtYXhSKVxuICB9O1xufVxuXG5mdW5jdGlvbiBib3VuZGluZ1JlY3RzKGJhcikge1xuICBjb25zdCBib3VuZHMgPSBnZXRCYXJCb3VuZHMoYmFyKTtcbiAgY29uc3Qgd2lkdGggPSBib3VuZHMucmlnaHQgLSBib3VuZHMubGVmdDtcbiAgY29uc3QgaGVpZ2h0ID0gYm91bmRzLmJvdHRvbSAtIGJvdW5kcy50b3A7XG4gIGNvbnN0IGJvcmRlciA9IHBhcnNlQm9yZGVyV2lkdGgoYmFyLCB3aWR0aCAvIDIsIGhlaWdodCAvIDIpO1xuICBjb25zdCByYWRpdXMgPSBwYXJzZUJvcmRlclJhZGl1cyhiYXIsIHdpZHRoIC8gMiwgaGVpZ2h0IC8gMik7XG5cbiAgcmV0dXJuIHtcbiAgICBvdXRlcjoge1xuICAgICAgeDogYm91bmRzLmxlZnQsXG4gICAgICB5OiBib3VuZHMudG9wLFxuICAgICAgdzogd2lkdGgsXG4gICAgICBoOiBoZWlnaHQsXG4gICAgICByYWRpdXNcbiAgICB9LFxuICAgIGlubmVyOiB7XG4gICAgICB4OiBib3VuZHMubGVmdCArIGJvcmRlci5sLFxuICAgICAgeTogYm91bmRzLnRvcCArIGJvcmRlci50LFxuICAgICAgdzogd2lkdGggLSBib3JkZXIubCAtIGJvcmRlci5yLFxuICAgICAgaDogaGVpZ2h0IC0gYm9yZGVyLnQgLSBib3JkZXIuYixcbiAgICAgIHJhZGl1czoge1xuICAgICAgICB0b3BMZWZ0OiBNYXRoLm1heCgwLCByYWRpdXMudG9wTGVmdCAtIE1hdGgubWF4KGJvcmRlci50LCBib3JkZXIubCkpLFxuICAgICAgICB0b3BSaWdodDogTWF0aC5tYXgoMCwgcmFkaXVzLnRvcFJpZ2h0IC0gTWF0aC5tYXgoYm9yZGVyLnQsIGJvcmRlci5yKSksXG4gICAgICAgIGJvdHRvbUxlZnQ6IE1hdGgubWF4KDAsIHJhZGl1cy5ib3R0b21MZWZ0IC0gTWF0aC5tYXgoYm9yZGVyLmIsIGJvcmRlci5sKSksXG4gICAgICAgIGJvdHRvbVJpZ2h0OiBNYXRoLm1heCgwLCByYWRpdXMuYm90dG9tUmlnaHQgLSBNYXRoLm1heChib3JkZXIuYiwgYm9yZGVyLnIpKSxcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIGluUmFuZ2UoYmFyLCB4LCB5LCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gIGNvbnN0IHNraXBYID0geCA9PT0gbnVsbDtcbiAgY29uc3Qgc2tpcFkgPSB5ID09PSBudWxsO1xuICBjb25zdCBza2lwQm90aCA9IHNraXBYICYmIHNraXBZO1xuICBjb25zdCBib3VuZHMgPSBiYXIgJiYgIXNraXBCb3RoICYmIGdldEJhckJvdW5kcyhiYXIsIHVzZUZpbmFsUG9zaXRpb24pO1xuXG4gIHJldHVybiBib3VuZHNcblx0XHQmJiAoc2tpcFggfHwgX2lzQmV0d2Vlbih4LCBib3VuZHMubGVmdCwgYm91bmRzLnJpZ2h0KSlcblx0XHQmJiAoc2tpcFkgfHwgX2lzQmV0d2Vlbih5LCBib3VuZHMudG9wLCBib3VuZHMuYm90dG9tKSk7XG59XG5cbmZ1bmN0aW9uIGhhc1JhZGl1cyhyYWRpdXMpIHtcbiAgcmV0dXJuIHJhZGl1cy50b3BMZWZ0IHx8IHJhZGl1cy50b3BSaWdodCB8fCByYWRpdXMuYm90dG9tTGVmdCB8fCByYWRpdXMuYm90dG9tUmlnaHQ7XG59XG5cbi8qKlxuICogQWRkIGEgcGF0aCBvZiBhIHJlY3RhbmdsZSB0byB0aGUgY3VycmVudCBzdWItcGF0aFxuICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGN0eCBDb250ZXh0XG4gKiBAcGFyYW0geyp9IHJlY3QgQm91bmRpbmcgcmVjdFxuICovXG5mdW5jdGlvbiBhZGROb3JtYWxSZWN0UGF0aChjdHgsIHJlY3QpIHtcbiAgY3R4LnJlY3QocmVjdC54LCByZWN0LnksIHJlY3QudywgcmVjdC5oKTtcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZVJlY3QocmVjdCwgYW1vdW50LCByZWZSZWN0ID0ge30pIHtcbiAgY29uc3QgeCA9IHJlY3QueCAhPT0gcmVmUmVjdC54ID8gLWFtb3VudCA6IDA7XG4gIGNvbnN0IHkgPSByZWN0LnkgIT09IHJlZlJlY3QueSA/IC1hbW91bnQgOiAwO1xuICBjb25zdCB3ID0gKHJlY3QueCArIHJlY3QudyAhPT0gcmVmUmVjdC54ICsgcmVmUmVjdC53ID8gYW1vdW50IDogMCkgLSB4O1xuICBjb25zdCBoID0gKHJlY3QueSArIHJlY3QuaCAhPT0gcmVmUmVjdC55ICsgcmVmUmVjdC5oID8gYW1vdW50IDogMCkgLSB5O1xuICByZXR1cm4ge1xuICAgIHg6IHJlY3QueCArIHgsXG4gICAgeTogcmVjdC55ICsgeSxcbiAgICB3OiByZWN0LncgKyB3LFxuICAgIGg6IHJlY3QuaCArIGgsXG4gICAgcmFkaXVzOiByZWN0LnJhZGl1c1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYXJFbGVtZW50IGV4dGVuZHMgRWxlbWVudCB7XG5cbiAgc3RhdGljIGlkID0gJ2Jhcic7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgYm9yZGVyU2tpcHBlZDogJ3N0YXJ0JyxcbiAgICBib3JkZXJXaWR0aDogMCxcbiAgICBib3JkZXJSYWRpdXM6IDAsXG4gICAgaW5mbGF0ZUFtb3VudDogJ2F1dG8nLFxuICAgIHBvaW50U3R5bGU6IHVuZGVmaW5lZFxuICB9O1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRSb3V0ZXMgPSB7XG4gICAgYmFja2dyb3VuZENvbG9yOiAnYmFja2dyb3VuZENvbG9yJyxcbiAgICBib3JkZXJDb2xvcjogJ2JvcmRlckNvbG9yJ1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKGNmZykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLm9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5ob3Jpem9udGFsID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuYmFzZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLndpZHRoID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaGVpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaW5mbGF0ZUFtb3VudCA9IHVuZGVmaW5lZDtcblxuICAgIGlmIChjZmcpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24odGhpcywgY2ZnKTtcbiAgICB9XG4gIH1cblxuICBkcmF3KGN0eCkge1xuICAgIGNvbnN0IHtpbmZsYXRlQW1vdW50LCBvcHRpb25zOiB7Ym9yZGVyQ29sb3IsIGJhY2tncm91bmRDb2xvcn19ID0gdGhpcztcbiAgICBjb25zdCB7aW5uZXIsIG91dGVyfSA9IGJvdW5kaW5nUmVjdHModGhpcyk7XG4gICAgY29uc3QgYWRkUmVjdFBhdGggPSBoYXNSYWRpdXMob3V0ZXIucmFkaXVzKSA/IGFkZFJvdW5kZWRSZWN0UGF0aCA6IGFkZE5vcm1hbFJlY3RQYXRoO1xuXG4gICAgY3R4LnNhdmUoKTtcblxuICAgIGlmIChvdXRlci53ICE9PSBpbm5lci53IHx8IG91dGVyLmggIT09IGlubmVyLmgpIHtcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGFkZFJlY3RQYXRoKGN0eCwgaW5mbGF0ZVJlY3Qob3V0ZXIsIGluZmxhdGVBbW91bnQsIGlubmVyKSk7XG4gICAgICBjdHguY2xpcCgpO1xuICAgICAgYWRkUmVjdFBhdGgoY3R4LCBpbmZsYXRlUmVjdChpbm5lciwgLWluZmxhdGVBbW91bnQsIG91dGVyKSk7XG4gICAgICBjdHguZmlsbFN0eWxlID0gYm9yZGVyQ29sb3I7XG4gICAgICBjdHguZmlsbCgnZXZlbm9kZCcpO1xuICAgIH1cblxuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBhZGRSZWN0UGF0aChjdHgsIGluZmxhdGVSZWN0KGlubmVyLCBpbmZsYXRlQW1vdW50KSk7XG4gICAgY3R4LmZpbGxTdHlsZSA9IGJhY2tncm91bmRDb2xvcjtcbiAgICBjdHguZmlsbCgpO1xuXG4gICAgY3R4LnJlc3RvcmUoKTtcbiAgfVxuXG4gIGluUmFuZ2UobW91c2VYLCBtb3VzZVksIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICByZXR1cm4gaW5SYW5nZSh0aGlzLCBtb3VzZVgsIG1vdXNlWSwgdXNlRmluYWxQb3NpdGlvbik7XG4gIH1cblxuICBpblhSYW5nZShtb3VzZVgsIHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICByZXR1cm4gaW5SYW5nZSh0aGlzLCBtb3VzZVgsIG51bGwsIHVzZUZpbmFsUG9zaXRpb24pO1xuICB9XG5cbiAgaW5ZUmFuZ2UobW91c2VZLCB1c2VGaW5hbFBvc2l0aW9uKSB7XG4gICAgcmV0dXJuIGluUmFuZ2UodGhpcywgbnVsbCwgbW91c2VZLCB1c2VGaW5hbFBvc2l0aW9uKTtcbiAgfVxuXG4gIGdldENlbnRlclBvaW50KHVzZUZpbmFsUG9zaXRpb24pIHtcbiAgICBjb25zdCB7eCwgeSwgYmFzZSwgaG9yaXpvbnRhbH0gPSAvKiogQHR5cGUge0JhclByb3BzfSAqLyAodGhpcy5nZXRQcm9wcyhbJ3gnLCAneScsICdiYXNlJywgJ2hvcml6b250YWwnXSwgdXNlRmluYWxQb3NpdGlvbikpO1xuICAgIHJldHVybiB7XG4gICAgICB4OiBob3Jpem9udGFsID8gKHggKyBiYXNlKSAvIDIgOiB4LFxuICAgICAgeTogaG9yaXpvbnRhbCA/IHkgOiAoeSArIGJhc2UpIC8gMlxuICAgIH07XG4gIH1cblxuICBnZXRSYW5nZShheGlzKSB7XG4gICAgcmV0dXJuIGF4aXMgPT09ICd4JyA/IHRoaXMud2lkdGggLyAyIDogdGhpcy5oZWlnaHQgLyAyO1xuICB9XG59XG4iLCAiaW1wb3J0IHtEb3VnaG51dENvbnRyb2xsZXIsIFBvbGFyQXJlYUNvbnRyb2xsZXJ9IGZyb20gJy4uL2luZGV4LmpzJztcbmltcG9ydCB0eXBlIHtDaGFydCwgQ2hhcnREYXRhc2V0fSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29sb3JzUGx1Z2luT3B0aW9ucyB7XG4gIGVuYWJsZWQ/OiBib29sZWFuO1xuICBmb3JjZU92ZXJyaWRlPzogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIENvbG9yc0Rlc2NyaXB0b3Ige1xuICBiYWNrZ3JvdW5kQ29sb3I/OiB1bmtub3duO1xuICBib3JkZXJDb2xvcj86IHVua25vd247XG59XG5cbmNvbnN0IEJPUkRFUl9DT0xPUlMgPSBbXG4gICdyZ2IoNTQsIDE2MiwgMjM1KScsIC8vIGJsdWVcbiAgJ3JnYigyNTUsIDk5LCAxMzIpJywgLy8gcmVkXG4gICdyZ2IoMjU1LCAxNTksIDY0KScsIC8vIG9yYW5nZVxuICAncmdiKDI1NSwgMjA1LCA4NiknLCAvLyB5ZWxsb3dcbiAgJ3JnYig3NSwgMTkyLCAxOTIpJywgLy8gZ3JlZW5cbiAgJ3JnYigxNTMsIDEwMiwgMjU1KScsIC8vIHB1cnBsZVxuICAncmdiKDIwMSwgMjAzLCAyMDcpJyAvLyBncmV5XG5dO1xuXG4vLyBCb3JkZXIgY29sb3JzIHdpdGggNTAlIHRyYW5zcGFyZW5jeVxuY29uc3QgQkFDS0dST1VORF9DT0xPUlMgPSAvKiAjX19QVVJFX18gKi8gQk9SREVSX0NPTE9SUy5tYXAoY29sb3IgPT4gY29sb3IucmVwbGFjZSgncmdiKCcsICdyZ2JhKCcpLnJlcGxhY2UoJyknLCAnLCAwLjUpJykpO1xuXG5mdW5jdGlvbiBnZXRCb3JkZXJDb2xvcihpOiBudW1iZXIpIHtcbiAgcmV0dXJuIEJPUkRFUl9DT0xPUlNbaSAlIEJPUkRFUl9DT0xPUlMubGVuZ3RoXTtcbn1cblxuZnVuY3Rpb24gZ2V0QmFja2dyb3VuZENvbG9yKGk6IG51bWJlcikge1xuICByZXR1cm4gQkFDS0dST1VORF9DT0xPUlNbaSAlIEJBQ0tHUk9VTkRfQ09MT1JTLmxlbmd0aF07XG59XG5cbmZ1bmN0aW9uIGNvbG9yaXplRGVmYXVsdERhdGFzZXQoZGF0YXNldDogQ2hhcnREYXRhc2V0LCBpOiBudW1iZXIpIHtcbiAgZGF0YXNldC5ib3JkZXJDb2xvciA9IGdldEJvcmRlckNvbG9yKGkpO1xuICBkYXRhc2V0LmJhY2tncm91bmRDb2xvciA9IGdldEJhY2tncm91bmRDb2xvcihpKTtcblxuICByZXR1cm4gKytpO1xufVxuXG5mdW5jdGlvbiBjb2xvcml6ZURvdWdobnV0RGF0YXNldChkYXRhc2V0OiBDaGFydERhdGFzZXQsIGk6IG51bWJlcikge1xuICBkYXRhc2V0LmJhY2tncm91bmRDb2xvciA9IGRhdGFzZXQuZGF0YS5tYXAoKCkgPT4gZ2V0Qm9yZGVyQ29sb3IoaSsrKSk7XG5cbiAgcmV0dXJuIGk7XG59XG5cbmZ1bmN0aW9uIGNvbG9yaXplUG9sYXJBcmVhRGF0YXNldChkYXRhc2V0OiBDaGFydERhdGFzZXQsIGk6IG51bWJlcikge1xuICBkYXRhc2V0LmJhY2tncm91bmRDb2xvciA9IGRhdGFzZXQuZGF0YS5tYXAoKCkgPT4gZ2V0QmFja2dyb3VuZENvbG9yKGkrKykpO1xuXG4gIHJldHVybiBpO1xufVxuXG5mdW5jdGlvbiBnZXRDb2xvcml6ZXIoY2hhcnQ6IENoYXJ0KSB7XG4gIGxldCBpID0gMDtcblxuICByZXR1cm4gKGRhdGFzZXQ6IENoYXJ0RGF0YXNldCwgZGF0YXNldEluZGV4OiBudW1iZXIpID0+IHtcbiAgICBjb25zdCBjb250cm9sbGVyID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KS5jb250cm9sbGVyO1xuXG4gICAgaWYgKGNvbnRyb2xsZXIgaW5zdGFuY2VvZiBEb3VnaG51dENvbnRyb2xsZXIpIHtcbiAgICAgIGkgPSBjb2xvcml6ZURvdWdobnV0RGF0YXNldChkYXRhc2V0LCBpKTtcbiAgICB9IGVsc2UgaWYgKGNvbnRyb2xsZXIgaW5zdGFuY2VvZiBQb2xhckFyZWFDb250cm9sbGVyKSB7XG4gICAgICBpID0gY29sb3JpemVQb2xhckFyZWFEYXRhc2V0KGRhdGFzZXQsIGkpO1xuICAgIH0gZWxzZSBpZiAoY29udHJvbGxlcikge1xuICAgICAgaSA9IGNvbG9yaXplRGVmYXVsdERhdGFzZXQoZGF0YXNldCwgaSk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBjb250YWluc0NvbG9yc0RlZmluaXRpb25zKFxuICBkZXNjcmlwdG9yczogQ29sb3JzRGVzY3JpcHRvcltdIHwgUmVjb3JkPHN0cmluZywgQ29sb3JzRGVzY3JpcHRvcj5cbikge1xuICBsZXQgazogbnVtYmVyIHwgc3RyaW5nO1xuXG4gIGZvciAoayBpbiBkZXNjcmlwdG9ycykge1xuICAgIGlmIChkZXNjcmlwdG9yc1trXS5ib3JkZXJDb2xvciB8fCBkZXNjcmlwdG9yc1trXS5iYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY29udGFpbnNDb2xvcnNEZWZpbml0aW9uKFxuICBkZXNjcmlwdG9yOiBDb2xvcnNEZXNjcmlwdG9yXG4pIHtcbiAgcmV0dXJuIGRlc2NyaXB0b3IgJiYgKGRlc2NyaXB0b3IuYm9yZGVyQ29sb3IgfHwgZGVzY3JpcHRvci5iYWNrZ3JvdW5kQ29sb3IpO1xufVxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGlkOiAnY29sb3JzJyxcblxuICBkZWZhdWx0czoge1xuICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgZm9yY2VPdmVycmlkZTogZmFsc2VcbiAgfSBhcyBDb2xvcnNQbHVnaW5PcHRpb25zLFxuXG4gIGJlZm9yZUxheW91dChjaGFydDogQ2hhcnQsIF9hcmdzLCBvcHRpb25zOiBDb2xvcnNQbHVnaW5PcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zLmVuYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7XG4gICAgICBkYXRhOiB7ZGF0YXNldHN9LFxuICAgICAgb3B0aW9uczogY2hhcnRPcHRpb25zXG4gICAgfSA9IGNoYXJ0LmNvbmZpZztcbiAgICBjb25zdCB7ZWxlbWVudHN9ID0gY2hhcnRPcHRpb25zO1xuXG4gICAgaWYgKCFvcHRpb25zLmZvcmNlT3ZlcnJpZGUgJiYgKGNvbnRhaW5zQ29sb3JzRGVmaW5pdGlvbnMoZGF0YXNldHMpIHx8IGNvbnRhaW5zQ29sb3JzRGVmaW5pdGlvbihjaGFydE9wdGlvbnMpIHx8IChlbGVtZW50cyAmJiBjb250YWluc0NvbG9yc0RlZmluaXRpb25zKGVsZW1lbnRzKSkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29sb3JpemVyID0gZ2V0Q29sb3JpemVyKGNoYXJ0KTtcblxuICAgIGRhdGFzZXRzLmZvckVhY2goY29sb3JpemVyKTtcbiAgfVxufTtcbiIsICJpbXBvcnQge19saW1pdFZhbHVlLCBfbG9va3VwQnlLZXksIGlzTnVsbE9yVW5kZWYsIHJlc29sdmV9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnO1xuXG5mdW5jdGlvbiBsdHRiRGVjaW1hdGlvbihkYXRhLCBzdGFydCwgY291bnQsIGF2YWlsYWJsZVdpZHRoLCBvcHRpb25zKSB7XG4gIC8qKlxuICAgKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgTGFyZ2VzdCBUcmlhbmdsZSBUaHJlZSBCdWNrZXRzIGFsZ29yaXRobS5cbiAgICpcbiAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBiYXNlZCBvbiB0aGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24gYnkgU3ZlaW5uIFN0ZWluYXJzc29uXG4gICAqIGluIGh0dHBzOi8vZ2l0aHViLmNvbS9zdmVpbm4tc3RlaW5hcnNzb24vZmxvdC1kb3duc2FtcGxlL2Jsb2IvbWFzdGVyL2pxdWVyeS5mbG90LmRvd25zYW1wbGUuanNcbiAgICpcbiAgICogVGhlIG9yaWdpbmFsIGltcGxlbWVudGF0aW9uIGlzIE1JVCBsaWNlbnNlZC5cbiAgICovXG4gIGNvbnN0IHNhbXBsZXMgPSBvcHRpb25zLnNhbXBsZXMgfHwgYXZhaWxhYmxlV2lkdGg7XG4gIC8vIFRoZXJlIGFyZSBsZXNzIHBvaW50cyB0aGFuIHRoZSB0aHJlc2hvbGQsIHJldHVybmluZyB0aGUgd2hvbGUgYXJyYXlcbiAgaWYgKHNhbXBsZXMgPj0gY291bnQpIHtcbiAgICByZXR1cm4gZGF0YS5zbGljZShzdGFydCwgc3RhcnQgKyBjb3VudCk7XG4gIH1cblxuICBjb25zdCBkZWNpbWF0ZWQgPSBbXTtcblxuICBjb25zdCBidWNrZXRXaWR0aCA9IChjb3VudCAtIDIpIC8gKHNhbXBsZXMgLSAyKTtcbiAgbGV0IHNhbXBsZWRJbmRleCA9IDA7XG4gIGNvbnN0IGVuZEluZGV4ID0gc3RhcnQgKyBjb3VudCAtIDE7XG4gIC8vIFN0YXJ0aW5nIGZyb20gb2Zmc2V0XG4gIGxldCBhID0gc3RhcnQ7XG4gIGxldCBpLCBtYXhBcmVhUG9pbnQsIG1heEFyZWEsIGFyZWEsIG5leHRBO1xuXG4gIGRlY2ltYXRlZFtzYW1wbGVkSW5kZXgrK10gPSBkYXRhW2FdO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBzYW1wbGVzIC0gMjsgaSsrKSB7XG4gICAgbGV0IGF2Z1ggPSAwO1xuICAgIGxldCBhdmdZID0gMDtcbiAgICBsZXQgajtcblxuICAgIC8vIEFkZGluZyBvZmZzZXRcbiAgICBjb25zdCBhdmdSYW5nZVN0YXJ0ID0gTWF0aC5mbG9vcigoaSArIDEpICogYnVja2V0V2lkdGgpICsgMSArIHN0YXJ0O1xuICAgIGNvbnN0IGF2Z1JhbmdlRW5kID0gTWF0aC5taW4oTWF0aC5mbG9vcigoaSArIDIpICogYnVja2V0V2lkdGgpICsgMSwgY291bnQpICsgc3RhcnQ7XG4gICAgY29uc3QgYXZnUmFuZ2VMZW5ndGggPSBhdmdSYW5nZUVuZCAtIGF2Z1JhbmdlU3RhcnQ7XG5cbiAgICBmb3IgKGogPSBhdmdSYW5nZVN0YXJ0OyBqIDwgYXZnUmFuZ2VFbmQ7IGorKykge1xuICAgICAgYXZnWCArPSBkYXRhW2pdLng7XG4gICAgICBhdmdZICs9IGRhdGFbal0ueTtcbiAgICB9XG5cbiAgICBhdmdYIC89IGF2Z1JhbmdlTGVuZ3RoO1xuICAgIGF2Z1kgLz0gYXZnUmFuZ2VMZW5ndGg7XG5cbiAgICAvLyBBZGRpbmcgb2Zmc2V0XG4gICAgY29uc3QgcmFuZ2VPZmZzID0gTWF0aC5mbG9vcihpICogYnVja2V0V2lkdGgpICsgMSArIHN0YXJ0O1xuICAgIGNvbnN0IHJhbmdlVG8gPSBNYXRoLm1pbihNYXRoLmZsb29yKChpICsgMSkgKiBidWNrZXRXaWR0aCkgKyAxLCBjb3VudCkgKyBzdGFydDtcbiAgICBjb25zdCB7eDogcG9pbnRBeCwgeTogcG9pbnRBeX0gPSBkYXRhW2FdO1xuXG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgY2hhbmdlZCBmcm9tIHRoZSBvcmlnaW5hbCBhbGdvcml0aG0gd2hpY2ggaW5pdGlhbGl6ZXMgdGhlc2VcbiAgICAvLyB2YWx1ZXMgdG8gMS4gVGhlIHJlYXNvbiBmb3IgdGhpcyBjaGFuZ2UgaXMgdGhhdCBpZiB0aGUgYXJlYSBpcyBzbWFsbCwgbmV4dEFcbiAgICAvLyB3b3VsZCBuZXZlciBiZSBzZXQgYW5kIHRodXMgYSBjcmFzaCB3b3VsZCBvY2N1ciBpbiB0aGUgbmV4dCBsb29wIGFzIGBhYCB3b3VsZCBiZWNvbWVcbiAgICAvLyBgdW5kZWZpbmVkYC4gU2luY2UgdGhlIGFyZWEgaXMgYWx3YXlzIHBvc2l0aXZlLCBidXQgY291bGQgYmUgMCBpbiB0aGUgY2FzZSBvZiBhIGZsYXQgdHJhY2UsXG4gICAgLy8gaW5pdGlhbGl6aW5nIHdpdGggYSBuZWdhdGl2ZSBudW1iZXIgaXMgdGhlIGNvcnJlY3Qgc29sdXRpb24uXG4gICAgbWF4QXJlYSA9IGFyZWEgPSAtMTtcblxuICAgIGZvciAoaiA9IHJhbmdlT2ZmczsgaiA8IHJhbmdlVG87IGorKykge1xuICAgICAgYXJlYSA9IDAuNSAqIE1hdGguYWJzKFxuICAgICAgICAocG9pbnRBeCAtIGF2Z1gpICogKGRhdGFbal0ueSAtIHBvaW50QXkpIC1cbiAgICAgICAgKHBvaW50QXggLSBkYXRhW2pdLngpICogKGF2Z1kgLSBwb2ludEF5KVxuICAgICAgKTtcblxuICAgICAgaWYgKGFyZWEgPiBtYXhBcmVhKSB7XG4gICAgICAgIG1heEFyZWEgPSBhcmVhO1xuICAgICAgICBtYXhBcmVhUG9pbnQgPSBkYXRhW2pdO1xuICAgICAgICBuZXh0QSA9IGo7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZGVjaW1hdGVkW3NhbXBsZWRJbmRleCsrXSA9IG1heEFyZWFQb2ludDtcbiAgICBhID0gbmV4dEE7XG4gIH1cblxuICAvLyBJbmNsdWRlIHRoZSBsYXN0IHBvaW50XG4gIGRlY2ltYXRlZFtzYW1wbGVkSW5kZXgrK10gPSBkYXRhW2VuZEluZGV4XTtcblxuICByZXR1cm4gZGVjaW1hdGVkO1xufVxuXG5mdW5jdGlvbiBtaW5NYXhEZWNpbWF0aW9uKGRhdGEsIHN0YXJ0LCBjb3VudCwgYXZhaWxhYmxlV2lkdGgpIHtcbiAgbGV0IGF2Z1ggPSAwO1xuICBsZXQgY291bnRYID0gMDtcbiAgbGV0IGksIHBvaW50LCB4LCB5LCBwcmV2WCwgbWluSW5kZXgsIG1heEluZGV4LCBzdGFydEluZGV4LCBtaW5ZLCBtYXhZO1xuICBjb25zdCBkZWNpbWF0ZWQgPSBbXTtcbiAgY29uc3QgZW5kSW5kZXggPSBzdGFydCArIGNvdW50IC0gMTtcblxuICBjb25zdCB4TWluID0gZGF0YVtzdGFydF0ueDtcbiAgY29uc3QgeE1heCA9IGRhdGFbZW5kSW5kZXhdLng7XG4gIGNvbnN0IGR4ID0geE1heCAtIHhNaW47XG5cbiAgZm9yIChpID0gc3RhcnQ7IGkgPCBzdGFydCArIGNvdW50OyArK2kpIHtcbiAgICBwb2ludCA9IGRhdGFbaV07XG4gICAgeCA9IChwb2ludC54IC0geE1pbikgLyBkeCAqIGF2YWlsYWJsZVdpZHRoO1xuICAgIHkgPSBwb2ludC55O1xuICAgIGNvbnN0IHRydW5jWCA9IHggfCAwO1xuXG4gICAgaWYgKHRydW5jWCA9PT0gcHJldlgpIHtcbiAgICAgIC8vIERldGVybWluZSBgbWluWWAgLyBgbWF4WWAgYW5kIGBhdmdYYCB3aGlsZSB3ZSBzdGF5IHdpdGhpbiBzYW1lIHgtcG9zaXRpb25cbiAgICAgIGlmICh5IDwgbWluWSkge1xuICAgICAgICBtaW5ZID0geTtcbiAgICAgICAgbWluSW5kZXggPSBpO1xuICAgICAgfSBlbHNlIGlmICh5ID4gbWF4WSkge1xuICAgICAgICBtYXhZID0geTtcbiAgICAgICAgbWF4SW5kZXggPSBpO1xuICAgICAgfVxuICAgICAgLy8gRm9yIGZpcnN0IHBvaW50IGluIGdyb3VwLCBjb3VudFggaXMgYDBgLCBzbyBhdmVyYWdlIHdpbGwgYmUgYHhgIC8gMS5cbiAgICAgIC8vIFVzZSBwb2ludC54IGhlcmUgYmVjYXVzZSB3ZSdyZSBjb21wdXRpbmcgdGhlIGF2ZXJhZ2UgZGF0YSBgeGAgdmFsdWVcbiAgICAgIGF2Z1ggPSAoY291bnRYICogYXZnWCArIHBvaW50LngpIC8gKytjb3VudFg7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFB1c2ggdXAgdG8gNCBwb2ludHMsIDMgZm9yIHRoZSBsYXN0IGludGVydmFsIGFuZCB0aGUgZmlyc3QgcG9pbnQgZm9yIHRoaXMgaW50ZXJ2YWxcbiAgICAgIGNvbnN0IGxhc3RJbmRleCA9IGkgLSAxO1xuXG4gICAgICBpZiAoIWlzTnVsbE9yVW5kZWYobWluSW5kZXgpICYmICFpc051bGxPclVuZGVmKG1heEluZGV4KSkge1xuICAgICAgICAvLyBUaGUgaW50ZXJ2YWwgaXMgZGVmaW5lZCBieSA0IHBvaW50czogc3RhcnQsIG1pbiwgbWF4LCBlbmQuXG4gICAgICAgIC8vIFRoZSBzdGFydGluZyBwb2ludCBpcyBhbHJlYWR5IGNvbnNpZGVyZWQgYXQgdGhpcyBwb2ludCwgc28gd2UgbmVlZCB0byBkZXRlcm1pbmUgd2hpY2hcbiAgICAgICAgLy8gb2YgdGhlIG90aGVyIHBvaW50cyB0byBhZGQuIFdlIG5lZWQgdG8gc29ydCB0aGVzZSBwb2ludHMgdG8gZW5zdXJlIHRoZSBkZWNpbWF0ZWQgZGF0YVxuICAgICAgICAvLyBpcyBzdGlsbCBzb3J0ZWQgYW5kIHRoZW4gZW5zdXJlIHRoZXJlIGFyZSBubyBkdXBsaWNhdGVzLlxuICAgICAgICBjb25zdCBpbnRlcm1lZGlhdGVJbmRleDEgPSBNYXRoLm1pbihtaW5JbmRleCwgbWF4SW5kZXgpO1xuICAgICAgICBjb25zdCBpbnRlcm1lZGlhdGVJbmRleDIgPSBNYXRoLm1heChtaW5JbmRleCwgbWF4SW5kZXgpO1xuXG4gICAgICAgIGlmIChpbnRlcm1lZGlhdGVJbmRleDEgIT09IHN0YXJ0SW5kZXggJiYgaW50ZXJtZWRpYXRlSW5kZXgxICE9PSBsYXN0SW5kZXgpIHtcbiAgICAgICAgICBkZWNpbWF0ZWQucHVzaCh7XG4gICAgICAgICAgICAuLi5kYXRhW2ludGVybWVkaWF0ZUluZGV4MV0sXG4gICAgICAgICAgICB4OiBhdmdYLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbnRlcm1lZGlhdGVJbmRleDIgIT09IHN0YXJ0SW5kZXggJiYgaW50ZXJtZWRpYXRlSW5kZXgyICE9PSBsYXN0SW5kZXgpIHtcbiAgICAgICAgICBkZWNpbWF0ZWQucHVzaCh7XG4gICAgICAgICAgICAuLi5kYXRhW2ludGVybWVkaWF0ZUluZGV4Ml0sXG4gICAgICAgICAgICB4OiBhdmdYXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbGFzdEluZGV4ID09PSBzdGFydEluZGV4IHdpbGwgb2NjdXIgd2hlbiBhIHJhbmdlIGhhcyBvbmx5IDEgcG9pbnQgd2hpY2ggY291bGRcbiAgICAgIC8vIGhhcHBlbiB3aXRoIHZlcnkgdW5ldmVuIGRhdGFcbiAgICAgIGlmIChpID4gMCAmJiBsYXN0SW5kZXggIT09IHN0YXJ0SW5kZXgpIHtcbiAgICAgICAgLy8gTGFzdCBwb2ludCBpbiB0aGUgcHJldmlvdXMgaW50ZXJ2YWxcbiAgICAgICAgZGVjaW1hdGVkLnB1c2goZGF0YVtsYXN0SW5kZXhdKTtcbiAgICAgIH1cblxuICAgICAgLy8gU3RhcnQgb2YgdGhlIG5ldyBpbnRlcnZhbFxuICAgICAgZGVjaW1hdGVkLnB1c2gocG9pbnQpO1xuICAgICAgcHJldlggPSB0cnVuY1g7XG4gICAgICBjb3VudFggPSAwO1xuICAgICAgbWluWSA9IG1heFkgPSB5O1xuICAgICAgbWluSW5kZXggPSBtYXhJbmRleCA9IHN0YXJ0SW5kZXggPSBpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZWNpbWF0ZWQ7XG59XG5cbmZ1bmN0aW9uIGNsZWFuRGVjaW1hdGVkRGF0YXNldChkYXRhc2V0KSB7XG4gIGlmIChkYXRhc2V0Ll9kZWNpbWF0ZWQpIHtcbiAgICBjb25zdCBkYXRhID0gZGF0YXNldC5fZGF0YTtcbiAgICBkZWxldGUgZGF0YXNldC5fZGVjaW1hdGVkO1xuICAgIGRlbGV0ZSBkYXRhc2V0Ll9kYXRhO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkYXRhc2V0LCAnZGF0YScsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIHZhbHVlOiBkYXRhLFxuICAgIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNsZWFuRGVjaW1hdGVkRGF0YShjaGFydCkge1xuICBjaGFydC5kYXRhLmRhdGFzZXRzLmZvckVhY2goKGRhdGFzZXQpID0+IHtcbiAgICBjbGVhbkRlY2ltYXRlZERhdGFzZXQoZGF0YXNldCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRTdGFydEFuZENvdW50T2ZWaXNpYmxlUG9pbnRzU2ltcGxpZmllZChtZXRhLCBwb2ludHMpIHtcbiAgY29uc3QgcG9pbnRDb3VudCA9IHBvaW50cy5sZW5ndGg7XG5cbiAgbGV0IHN0YXJ0ID0gMDtcbiAgbGV0IGNvdW50O1xuXG4gIGNvbnN0IHtpU2NhbGV9ID0gbWV0YTtcbiAgY29uc3Qge21pbiwgbWF4LCBtaW5EZWZpbmVkLCBtYXhEZWZpbmVkfSA9IGlTY2FsZS5nZXRVc2VyQm91bmRzKCk7XG5cbiAgaWYgKG1pbkRlZmluZWQpIHtcbiAgICBzdGFydCA9IF9saW1pdFZhbHVlKF9sb29rdXBCeUtleShwb2ludHMsIGlTY2FsZS5heGlzLCBtaW4pLmxvLCAwLCBwb2ludENvdW50IC0gMSk7XG4gIH1cbiAgaWYgKG1heERlZmluZWQpIHtcbiAgICBjb3VudCA9IF9saW1pdFZhbHVlKF9sb29rdXBCeUtleShwb2ludHMsIGlTY2FsZS5heGlzLCBtYXgpLmhpICsgMSwgc3RhcnQsIHBvaW50Q291bnQpIC0gc3RhcnQ7XG4gIH0gZWxzZSB7XG4gICAgY291bnQgPSBwb2ludENvdW50IC0gc3RhcnQ7XG4gIH1cblxuICByZXR1cm4ge3N0YXJ0LCBjb3VudH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgaWQ6ICdkZWNpbWF0aW9uJyxcblxuICBkZWZhdWx0czoge1xuICAgIGFsZ29yaXRobTogJ21pbi1tYXgnLFxuICAgIGVuYWJsZWQ6IGZhbHNlLFxuICB9LFxuXG4gIGJlZm9yZUVsZW1lbnRzVXBkYXRlOiAoY2hhcnQsIGFyZ3MsIG9wdGlvbnMpID0+IHtcbiAgICBpZiAoIW9wdGlvbnMuZW5hYmxlZCkge1xuICAgICAgLy8gVGhlIGRlY2ltYXRpb24gcGx1Z2luIG1heSBoYXZlIGJlZW4gcHJldmlvdXNseSBlbmFibGVkLiBOZWVkIHRvIHJlbW92ZSBvbGQgYGRhdGFzZXQuX2RhdGFgIGhhbmRsZXJzXG4gICAgICBjbGVhbkRlY2ltYXRlZERhdGEoY2hhcnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEFzc3VtZSB0aGUgZW50aXJlIGNoYXJ0IGlzIGF2YWlsYWJsZSB0byBzaG93IGEgZmV3IG1vcmUgcG9pbnRzIHRoYW4gbmVlZGVkXG4gICAgY29uc3QgYXZhaWxhYmxlV2lkdGggPSBjaGFydC53aWR0aDtcblxuICAgIGNoYXJ0LmRhdGEuZGF0YXNldHMuZm9yRWFjaCgoZGF0YXNldCwgZGF0YXNldEluZGV4KSA9PiB7XG4gICAgICBjb25zdCB7X2RhdGEsIGluZGV4QXhpc30gPSBkYXRhc2V0O1xuICAgICAgY29uc3QgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG4gICAgICBjb25zdCBkYXRhID0gX2RhdGEgfHwgZGF0YXNldC5kYXRhO1xuXG4gICAgICBpZiAocmVzb2x2ZShbaW5kZXhBeGlzLCBjaGFydC5vcHRpb25zLmluZGV4QXhpc10pID09PSAneScpIHtcbiAgICAgICAgLy8gRGVjaW1hdGlvbiBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgbGluZXMgdGhhdCBoYXZlIGFuIFggaW5kZXhBeGlzXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCFtZXRhLmNvbnRyb2xsZXIuc3VwcG9ydHNEZWNpbWF0aW9uKSB7XG4gICAgICAgIC8vIE9ubHkgbGluZSBkYXRhc2V0cyBhcmUgc3VwcG9ydGVkXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeEF4aXMgPSBjaGFydC5zY2FsZXNbbWV0YS54QXhpc0lEXTtcbiAgICAgIGlmICh4QXhpcy50eXBlICE9PSAnbGluZWFyJyAmJiB4QXhpcy50eXBlICE9PSAndGltZScpIHtcbiAgICAgICAgLy8gT25seSBsaW5lYXIgaW50ZXJwb2xhdGlvbiBpcyBzdXBwb3J0ZWRcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhcnQub3B0aW9ucy5wYXJzaW5nKSB7XG4gICAgICAgIC8vIFBsdWdpbiBvbmx5IHN1cHBvcnRzIGRhdGEgdGhhdCBkb2VzIG5vdCBuZWVkIHBhcnNpbmdcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQge3N0YXJ0LCBjb3VudH0gPSBnZXRTdGFydEFuZENvdW50T2ZWaXNpYmxlUG9pbnRzU2ltcGxpZmllZChtZXRhLCBkYXRhKTtcbiAgICAgIGNvbnN0IHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkIHx8IDQgKiBhdmFpbGFibGVXaWR0aDtcbiAgICAgIGlmIChjb3VudCA8PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgLy8gTm8gZGVjaW1hdGlvbiBpcyByZXF1aXJlZCB1bnRpbCB3ZSBhcmUgYWJvdmUgdGhpcyB0aHJlc2hvbGRcbiAgICAgICAgY2xlYW5EZWNpbWF0ZWREYXRhc2V0KGRhdGFzZXQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChpc051bGxPclVuZGVmKF9kYXRhKSkge1xuICAgICAgICAvLyBGaXJzdCB0aW1lIHdlIGFyZSBzZWVpbmcgdGhpcyBkYXRhc2V0XG4gICAgICAgIC8vIFdlIG92ZXJyaWRlIHRoZSAnZGF0YScgcHJvcGVydHkgd2l0aCBhIHNldHRlciB0aGF0IHN0b3JlcyB0aGVcbiAgICAgICAgLy8gcmF3IGRhdGEgaW4gX2RhdGEsIGJ1dCByZWFkcyB0aGUgZGVjaW1hdGVkIGRhdGEgZnJvbSBfZGVjaW1hdGVkXG4gICAgICAgIGRhdGFzZXQuX2RhdGEgPSBkYXRhO1xuICAgICAgICBkZWxldGUgZGF0YXNldC5kYXRhO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGF0YXNldCwgJ2RhdGEnLCB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWNpbWF0ZWQ7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzZXQ6IGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgICAgIHRoaXMuX2RhdGEgPSBkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFBvaW50IHRoZSBjaGFydCB0byB0aGUgZGVjaW1hdGVkIGRhdGFcbiAgICAgIGxldCBkZWNpbWF0ZWQ7XG4gICAgICBzd2l0Y2ggKG9wdGlvbnMuYWxnb3JpdGhtKSB7XG4gICAgICBjYXNlICdsdHRiJzpcbiAgICAgICAgZGVjaW1hdGVkID0gbHR0YkRlY2ltYXRpb24oZGF0YSwgc3RhcnQsIGNvdW50LCBhdmFpbGFibGVXaWR0aCwgb3B0aW9ucyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbWluLW1heCc6XG4gICAgICAgIGRlY2ltYXRlZCA9IG1pbk1heERlY2ltYXRpb24oZGF0YSwgc3RhcnQsIGNvdW50LCBhdmFpbGFibGVXaWR0aCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBkZWNpbWF0aW9uIGFsZ29yaXRobSAnJHtvcHRpb25zLmFsZ29yaXRobX0nYCk7XG4gICAgICB9XG5cbiAgICAgIGRhdGFzZXQuX2RlY2ltYXRlZCA9IGRlY2ltYXRlZDtcbiAgICB9KTtcbiAgfSxcblxuICBkZXN0cm95KGNoYXJ0KSB7XG4gICAgY2xlYW5EZWNpbWF0ZWREYXRhKGNoYXJ0KTtcbiAgfVxufTtcbiIsICJpbXBvcnQge19ib3VuZFNlZ21lbnQsIF9ib3VuZFNlZ21lbnRzLCBfbm9ybWFsaXplQW5nbGV9IGZyb20gJy4uLy4uL2hlbHBlcnMvaW5kZXguanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gX3NlZ21lbnRzKGxpbmUsIHRhcmdldCwgcHJvcGVydHkpIHtcbiAgY29uc3Qgc2VnbWVudHMgPSBsaW5lLnNlZ21lbnRzO1xuICBjb25zdCBwb2ludHMgPSBsaW5lLnBvaW50cztcbiAgY29uc3QgdHBvaW50cyA9IHRhcmdldC5wb2ludHM7XG4gIGNvbnN0IHBhcnRzID0gW107XG5cbiAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgbGV0IHtzdGFydCwgZW5kfSA9IHNlZ21lbnQ7XG4gICAgZW5kID0gX2ZpbmRTZWdtZW50RW5kKHN0YXJ0LCBlbmQsIHBvaW50cyk7XG5cbiAgICBjb25zdCBib3VuZHMgPSBfZ2V0Qm91bmRzKHByb3BlcnR5LCBwb2ludHNbc3RhcnRdLCBwb2ludHNbZW5kXSwgc2VnbWVudC5sb29wKTtcblxuICAgIGlmICghdGFyZ2V0LnNlZ21lbnRzKSB7XG4gICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIGJvdW5kYXJ5IG5vdCBzdXBwb3J0aW5nIGBzZWdtZW50c2AgKHNpbXBsZUFyYylcbiAgICAgIC8vIEJvdW5kcyBhcmUgcHJvdmlkZWQgYXMgYHRhcmdldGAgZm9yIHBhcnRpYWwgY2lyY2xlLCBvciB1bmRlZmluZWQgZm9yIGZ1bGwgY2lyY2xlXG4gICAgICBwYXJ0cy5wdXNoKHtcbiAgICAgICAgc291cmNlOiBzZWdtZW50LFxuICAgICAgICB0YXJnZXQ6IGJvdW5kcyxcbiAgICAgICAgc3RhcnQ6IHBvaW50c1tzdGFydF0sXG4gICAgICAgIGVuZDogcG9pbnRzW2VuZF1cbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gR2V0IGFsbCBzZWdtZW50cyBmcm9tIGB0YXJnZXRgIHRoYXQgaW50ZXJzZWN0IHRoZSBib3VuZHMgb2YgY3VycmVudCBzZWdtZW50IG9mIGBsaW5lYFxuICAgIGNvbnN0IHRhcmdldFNlZ21lbnRzID0gX2JvdW5kU2VnbWVudHModGFyZ2V0LCBib3VuZHMpO1xuXG4gICAgZm9yIChjb25zdCB0Z3Qgb2YgdGFyZ2V0U2VnbWVudHMpIHtcbiAgICAgIGNvbnN0IHN1YkJvdW5kcyA9IF9nZXRCb3VuZHMocHJvcGVydHksIHRwb2ludHNbdGd0LnN0YXJ0XSwgdHBvaW50c1t0Z3QuZW5kXSwgdGd0Lmxvb3ApO1xuICAgICAgY29uc3QgZmlsbFNvdXJjZXMgPSBfYm91bmRTZWdtZW50KHNlZ21lbnQsIHBvaW50cywgc3ViQm91bmRzKTtcblxuICAgICAgZm9yIChjb25zdCBmaWxsU291cmNlIG9mIGZpbGxTb3VyY2VzKSB7XG4gICAgICAgIHBhcnRzLnB1c2goe1xuICAgICAgICAgIHNvdXJjZTogZmlsbFNvdXJjZSxcbiAgICAgICAgICB0YXJnZXQ6IHRndCxcbiAgICAgICAgICBzdGFydDoge1xuICAgICAgICAgICAgW3Byb3BlcnR5XTogX2dldEVkZ2UoYm91bmRzLCBzdWJCb3VuZHMsICdzdGFydCcsIE1hdGgubWF4KVxuICAgICAgICAgIH0sXG4gICAgICAgICAgZW5kOiB7XG4gICAgICAgICAgICBbcHJvcGVydHldOiBfZ2V0RWRnZShib3VuZHMsIHN1YkJvdW5kcywgJ2VuZCcsIE1hdGgubWluKVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBwYXJ0cztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9nZXRCb3VuZHMocHJvcGVydHksIGZpcnN0LCBsYXN0LCBsb29wKSB7XG4gIGlmIChsb29wKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBzdGFydCA9IGZpcnN0W3Byb3BlcnR5XTtcbiAgbGV0IGVuZCA9IGxhc3RbcHJvcGVydHldO1xuXG4gIGlmIChwcm9wZXJ0eSA9PT0gJ2FuZ2xlJykge1xuICAgIHN0YXJ0ID0gX25vcm1hbGl6ZUFuZ2xlKHN0YXJ0KTtcbiAgICBlbmQgPSBfbm9ybWFsaXplQW5nbGUoZW5kKTtcbiAgfVxuICByZXR1cm4ge3Byb3BlcnR5LCBzdGFydCwgZW5kfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9wb2ludHNGcm9tU2VnbWVudHMoYm91bmRhcnksIGxpbmUpIHtcbiAgY29uc3Qge3ggPSBudWxsLCB5ID0gbnVsbH0gPSBib3VuZGFyeSB8fCB7fTtcbiAgY29uc3QgbGluZVBvaW50cyA9IGxpbmUucG9pbnRzO1xuICBjb25zdCBwb2ludHMgPSBbXTtcbiAgbGluZS5zZWdtZW50cy5mb3JFYWNoKCh7c3RhcnQsIGVuZH0pID0+IHtcbiAgICBlbmQgPSBfZmluZFNlZ21lbnRFbmQoc3RhcnQsIGVuZCwgbGluZVBvaW50cyk7XG4gICAgY29uc3QgZmlyc3QgPSBsaW5lUG9pbnRzW3N0YXJ0XTtcbiAgICBjb25zdCBsYXN0ID0gbGluZVBvaW50c1tlbmRdO1xuICAgIGlmICh5ICE9PSBudWxsKSB7XG4gICAgICBwb2ludHMucHVzaCh7eDogZmlyc3QueCwgeX0pO1xuICAgICAgcG9pbnRzLnB1c2goe3g6IGxhc3QueCwgeX0pO1xuICAgIH0gZWxzZSBpZiAoeCAhPT0gbnVsbCkge1xuICAgICAgcG9pbnRzLnB1c2goe3gsIHk6IGZpcnN0Lnl9KTtcbiAgICAgIHBvaW50cy5wdXNoKHt4LCB5OiBsYXN0Lnl9KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcG9pbnRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gX2ZpbmRTZWdtZW50RW5kKHN0YXJ0LCBlbmQsIHBvaW50cykge1xuICBmb3IgKDtlbmQgPiBzdGFydDsgZW5kLS0pIHtcbiAgICBjb25zdCBwb2ludCA9IHBvaW50c1tlbmRdO1xuICAgIGlmICghaXNOYU4ocG9pbnQueCkgJiYgIWlzTmFOKHBvaW50LnkpKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVuZDtcbn1cblxuZnVuY3Rpb24gX2dldEVkZ2UoYSwgYiwgcHJvcCwgZm4pIHtcbiAgaWYgKGEgJiYgYikge1xuICAgIHJldHVybiBmbihhW3Byb3BdLCBiW3Byb3BdKTtcbiAgfVxuICByZXR1cm4gYSA/IGFbcHJvcF0gOiBiID8gYltwcm9wXSA6IDA7XG59XG4iLCAiLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vLi4vY29yZS9jb3JlLmNvbnRyb2xsZXIuanMnKS5kZWZhdWx0IH0gQ2hhcnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi9jb3JlL2NvcmUuc2NhbGUuanMnKS5kZWZhdWx0IH0gU2NhbGVcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi9lbGVtZW50cy9lbGVtZW50LnBvaW50LmpzJykuZGVmYXVsdCB9IFBvaW50RWxlbWVudFxuICovXG5cbmltcG9ydCB7TGluZUVsZW1lbnR9IGZyb20gJy4uLy4uL2VsZW1lbnRzL2luZGV4LmpzJztcbmltcG9ydCB7aXNBcnJheX0gZnJvbSAnLi4vLi4vaGVscGVycy9pbmRleC5qcyc7XG5pbXBvcnQge19wb2ludHNGcm9tU2VnbWVudHN9IGZyb20gJy4vZmlsbGVyLnNlZ21lbnQuanMnO1xuXG4vKipcbiAqIEBwYXJhbSB7UG9pbnRFbGVtZW50W10gfCB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB9fSBib3VuZGFyeVxuICogQHBhcmFtIHtMaW5lRWxlbWVudH0gbGluZVxuICogQHJldHVybiB7TGluZUVsZW1lbnQ/fVxuICovXG5leHBvcnQgZnVuY3Rpb24gX2NyZWF0ZUJvdW5kYXJ5TGluZShib3VuZGFyeSwgbGluZSkge1xuICBsZXQgcG9pbnRzID0gW107XG4gIGxldCBfbG9vcCA9IGZhbHNlO1xuXG4gIGlmIChpc0FycmF5KGJvdW5kYXJ5KSkge1xuICAgIF9sb29wID0gdHJ1ZTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcG9pbnRzID0gYm91bmRhcnk7XG4gIH0gZWxzZSB7XG4gICAgcG9pbnRzID0gX3BvaW50c0Zyb21TZWdtZW50cyhib3VuZGFyeSwgbGluZSk7XG4gIH1cblxuICByZXR1cm4gcG9pbnRzLmxlbmd0aCA/IG5ldyBMaW5lRWxlbWVudCh7XG4gICAgcG9pbnRzLFxuICAgIG9wdGlvbnM6IHt0ZW5zaW9uOiAwfSxcbiAgICBfbG9vcCxcbiAgICBfZnVsbExvb3A6IF9sb29wXG4gIH0pIDogbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9zaG91bGRBcHBseUZpbGwoc291cmNlKSB7XG4gIHJldHVybiBzb3VyY2UgJiYgc291cmNlLmZpbGwgIT09IGZhbHNlO1xufVxuIiwgImltcG9ydCB7aXNPYmplY3QsIGlzRmluaXRlLCB2YWx1ZU9yRGVmYXVsdH0gZnJvbSAnLi4vLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi9jb3JlL2NvcmUuc2NhbGUuanMnKS5kZWZhdWx0IH0gU2NhbGVcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi9lbGVtZW50cy9lbGVtZW50LmxpbmUuanMnKS5kZWZhdWx0IH0gTGluZUVsZW1lbnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi8uLi90eXBlcy9pbmRleC5qcycpLkZpbGxUYXJnZXQgfSBGaWxsVGFyZ2V0XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vLi4vdHlwZXMvaW5kZXguanMnKS5Db21wbGV4RmlsbFRhcmdldCB9IENvbXBsZXhGaWxsVGFyZ2V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIF9yZXNvbHZlVGFyZ2V0KHNvdXJjZXMsIGluZGV4LCBwcm9wYWdhdGUpIHtcbiAgY29uc3Qgc291cmNlID0gc291cmNlc1tpbmRleF07XG4gIGxldCBmaWxsID0gc291cmNlLmZpbGw7XG4gIGNvbnN0IHZpc2l0ZWQgPSBbaW5kZXhdO1xuICBsZXQgdGFyZ2V0O1xuXG4gIGlmICghcHJvcGFnYXRlKSB7XG4gICAgcmV0dXJuIGZpbGw7XG4gIH1cblxuICB3aGlsZSAoZmlsbCAhPT0gZmFsc2UgJiYgdmlzaXRlZC5pbmRleE9mKGZpbGwpID09PSAtMSkge1xuICAgIGlmICghaXNGaW5pdGUoZmlsbCkpIHtcbiAgICAgIHJldHVybiBmaWxsO1xuICAgIH1cblxuICAgIHRhcmdldCA9IHNvdXJjZXNbZmlsbF07XG4gICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodGFyZ2V0LnZpc2libGUpIHtcbiAgICAgIHJldHVybiBmaWxsO1xuICAgIH1cblxuICAgIHZpc2l0ZWQucHVzaChmaWxsKTtcbiAgICBmaWxsID0gdGFyZ2V0LmZpbGw7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQHBhcmFtIHtMaW5lRWxlbWVudH0gbGluZVxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gKiBAcGFyYW0ge251bWJlcn0gY291bnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9kZWNvZGVGaWxsKGxpbmUsIGluZGV4LCBjb3VudCkge1xuICAvKiogQHR5cGUge3N0cmluZyB8IHt2YWx1ZTogbnVtYmVyfX0gKi9cbiAgY29uc3QgZmlsbCA9IHBhcnNlRmlsbE9wdGlvbihsaW5lKTtcblxuICBpZiAoaXNPYmplY3QoZmlsbCkpIHtcbiAgICByZXR1cm4gaXNOYU4oZmlsbC52YWx1ZSkgPyBmYWxzZSA6IGZpbGw7XG4gIH1cblxuICBsZXQgdGFyZ2V0ID0gcGFyc2VGbG9hdChmaWxsKTtcblxuICBpZiAoaXNGaW5pdGUodGFyZ2V0KSAmJiBNYXRoLmZsb29yKHRhcmdldCkgPT09IHRhcmdldCkge1xuICAgIHJldHVybiBkZWNvZGVUYXJnZXRJbmRleChmaWxsWzBdLCBpbmRleCwgdGFyZ2V0LCBjb3VudCk7XG4gIH1cblxuICByZXR1cm4gWydvcmlnaW4nLCAnc3RhcnQnLCAnZW5kJywgJ3N0YWNrJywgJ3NoYXBlJ10uaW5kZXhPZihmaWxsKSA+PSAwICYmIGZpbGw7XG59XG5cbmZ1bmN0aW9uIGRlY29kZVRhcmdldEluZGV4KGZpcnN0Q2gsIGluZGV4LCB0YXJnZXQsIGNvdW50KSB7XG4gIGlmIChmaXJzdENoID09PSAnLScgfHwgZmlyc3RDaCA9PT0gJysnKSB7XG4gICAgdGFyZ2V0ID0gaW5kZXggKyB0YXJnZXQ7XG4gIH1cblxuICBpZiAodGFyZ2V0ID09PSBpbmRleCB8fCB0YXJnZXQgPCAwIHx8IHRhcmdldCA+PSBjb3VudCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbi8qKlxuICogQHBhcmFtIHtGaWxsVGFyZ2V0IHwgQ29tcGxleEZpbGxUYXJnZXR9IGZpbGxcbiAqIEBwYXJhbSB7U2NhbGV9IHNjYWxlXG4gKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVsbH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9nZXRUYXJnZXRQaXhlbChmaWxsLCBzY2FsZSkge1xuICBsZXQgcGl4ZWwgPSBudWxsO1xuICBpZiAoZmlsbCA9PT0gJ3N0YXJ0Jykge1xuICAgIHBpeGVsID0gc2NhbGUuYm90dG9tO1xuICB9IGVsc2UgaWYgKGZpbGwgPT09ICdlbmQnKSB7XG4gICAgcGl4ZWwgPSBzY2FsZS50b3A7XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoZmlsbCkpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcGl4ZWwgPSBzY2FsZS5nZXRQaXhlbEZvclZhbHVlKGZpbGwudmFsdWUpO1xuICB9IGVsc2UgaWYgKHNjYWxlLmdldEJhc2VQaXhlbCkge1xuICAgIHBpeGVsID0gc2NhbGUuZ2V0QmFzZVBpeGVsKCk7XG4gIH1cbiAgcmV0dXJuIHBpeGVsO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7RmlsbFRhcmdldCB8IENvbXBsZXhGaWxsVGFyZ2V0fSBmaWxsXG4gKiBAcGFyYW0ge1NjYWxlfSBzY2FsZVxuICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0VmFsdWVcbiAqIEByZXR1cm5zIHtudW1iZXIgfCB1bmRlZmluZWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfZ2V0VGFyZ2V0VmFsdWUoZmlsbCwgc2NhbGUsIHN0YXJ0VmFsdWUpIHtcbiAgbGV0IHZhbHVlO1xuXG4gIGlmIChmaWxsID09PSAnc3RhcnQnKSB7XG4gICAgdmFsdWUgPSBzdGFydFZhbHVlO1xuICB9IGVsc2UgaWYgKGZpbGwgPT09ICdlbmQnKSB7XG4gICAgdmFsdWUgPSBzY2FsZS5vcHRpb25zLnJldmVyc2UgPyBzY2FsZS5taW4gOiBzY2FsZS5tYXg7XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoZmlsbCkpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdmFsdWUgPSBmaWxsLnZhbHVlO1xuICB9IGVsc2Uge1xuICAgIHZhbHVlID0gc2NhbGUuZ2V0QmFzZVZhbHVlKCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7TGluZUVsZW1lbnR9IGxpbmVcbiAqL1xuZnVuY3Rpb24gcGFyc2VGaWxsT3B0aW9uKGxpbmUpIHtcbiAgY29uc3Qgb3B0aW9ucyA9IGxpbmUub3B0aW9ucztcbiAgY29uc3QgZmlsbE9wdGlvbiA9IG9wdGlvbnMuZmlsbDtcbiAgbGV0IGZpbGwgPSB2YWx1ZU9yRGVmYXVsdChmaWxsT3B0aW9uICYmIGZpbGxPcHRpb24udGFyZ2V0LCBmaWxsT3B0aW9uKTtcblxuICBpZiAoZmlsbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZmlsbCA9ICEhb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3I7XG4gIH1cblxuICBpZiAoZmlsbCA9PT0gZmFsc2UgfHwgZmlsbCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChmaWxsID09PSB0cnVlKSB7XG4gICAgcmV0dXJuICdvcmlnaW4nO1xuICB9XG4gIHJldHVybiBmaWxsO1xufVxuIiwgIi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uLy4uL2NvcmUvY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IENoYXJ0XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vLi4vY29yZS9jb3JlLnNjYWxlLmpzJykuZGVmYXVsdCB9IFNjYWxlXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vLi4vZWxlbWVudHMvZWxlbWVudC5wb2ludC5qcycpLmRlZmF1bHQgfSBQb2ludEVsZW1lbnRcbiAqL1xuXG5pbXBvcnQge0xpbmVFbGVtZW50fSBmcm9tICcuLi8uLi9lbGVtZW50cy9pbmRleC5qcyc7XG5pbXBvcnQge19pc0JldHdlZW59IGZyb20gJy4uLy4uL2hlbHBlcnMvaW5kZXguanMnO1xuaW1wb3J0IHtfY3JlYXRlQm91bmRhcnlMaW5lfSBmcm9tICcuL2ZpbGxlci5oZWxwZXIuanMnO1xuXG4vKipcbiAqIEBwYXJhbSB7eyBjaGFydDogQ2hhcnQ7IHNjYWxlOiBTY2FsZTsgaW5kZXg6IG51bWJlcjsgbGluZTogTGluZUVsZW1lbnQ7IH19IHNvdXJjZVxuICogQHJldHVybiB7TGluZUVsZW1lbnR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfYnVpbGRTdGFja0xpbmUoc291cmNlKSB7XG4gIGNvbnN0IHtzY2FsZSwgaW5kZXgsIGxpbmV9ID0gc291cmNlO1xuICBjb25zdCBwb2ludHMgPSBbXTtcbiAgY29uc3Qgc2VnbWVudHMgPSBsaW5lLnNlZ21lbnRzO1xuICBjb25zdCBzb3VyY2VQb2ludHMgPSBsaW5lLnBvaW50cztcbiAgY29uc3QgbGluZXNCZWxvdyA9IGdldExpbmVzQmVsb3coc2NhbGUsIGluZGV4KTtcbiAgbGluZXNCZWxvdy5wdXNoKF9jcmVhdGVCb3VuZGFyeUxpbmUoe3g6IG51bGwsIHk6IHNjYWxlLmJvdHRvbX0sIGxpbmUpKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgc2VnbWVudCA9IHNlZ21lbnRzW2ldO1xuICAgIGZvciAobGV0IGogPSBzZWdtZW50LnN0YXJ0OyBqIDw9IHNlZ21lbnQuZW5kOyBqKyspIHtcbiAgICAgIGFkZFBvaW50c0JlbG93KHBvaW50cywgc291cmNlUG9pbnRzW2pdLCBsaW5lc0JlbG93KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5ldyBMaW5lRWxlbWVudCh7cG9pbnRzLCBvcHRpb25zOiB7fX0pO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7U2NhbGV9IHNjYWxlXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAqIEByZXR1cm4ge0xpbmVFbGVtZW50W119XG4gKi9cbmZ1bmN0aW9uIGdldExpbmVzQmVsb3coc2NhbGUsIGluZGV4KSB7XG4gIGNvbnN0IGJlbG93ID0gW107XG4gIGNvbnN0IG1ldGFzID0gc2NhbGUuZ2V0TWF0Y2hpbmdWaXNpYmxlTWV0YXMoJ2xpbmUnKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IG1ldGFzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgbWV0YSA9IG1ldGFzW2ldO1xuICAgIGlmIChtZXRhLmluZGV4ID09PSBpbmRleCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGlmICghbWV0YS5oaWRkZW4pIHtcbiAgICAgIGJlbG93LnVuc2hpZnQobWV0YS5kYXRhc2V0KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGJlbG93O1xufVxuXG4vKipcbiAqIEBwYXJhbSB7UG9pbnRFbGVtZW50W119IHBvaW50c1xuICogQHBhcmFtIHtQb2ludEVsZW1lbnR9IHNvdXJjZVBvaW50XG4gKiBAcGFyYW0ge0xpbmVFbGVtZW50W119IGxpbmVzQmVsb3dcbiAqL1xuZnVuY3Rpb24gYWRkUG9pbnRzQmVsb3cocG9pbnRzLCBzb3VyY2VQb2ludCwgbGluZXNCZWxvdykge1xuICBjb25zdCBwb3N0cG9uZWQgPSBbXTtcbiAgZm9yIChsZXQgaiA9IDA7IGogPCBsaW5lc0JlbG93Lmxlbmd0aDsgaisrKSB7XG4gICAgY29uc3QgbGluZSA9IGxpbmVzQmVsb3dbal07XG4gICAgY29uc3Qge2ZpcnN0LCBsYXN0LCBwb2ludH0gPSBmaW5kUG9pbnQobGluZSwgc291cmNlUG9pbnQsICd4Jyk7XG5cbiAgICBpZiAoIXBvaW50IHx8IChmaXJzdCAmJiBsYXN0KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChmaXJzdCkge1xuICAgICAgLy8gRmlyc3QgcG9pbnQgb2YgYW4gc2VnbWVudCAtPiBuZWVkIHRvIGFkZCBhbm90aGVyIHBvaW50IGJlZm9yZSB0aGlzLFxuICAgICAgLy8gZnJvbSBuZXh0IGxpbmUgYmVsb3cuXG4gICAgICBwb3N0cG9uZWQudW5zaGlmdChwb2ludCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBvaW50cy5wdXNoKHBvaW50KTtcbiAgICAgIGlmICghbGFzdCkge1xuICAgICAgICAvLyBJbiB0aGUgbWlkZGxlIG9mIGFuIHNlZ21lbnQsIG5vIG5lZWQgdG8gYWRkIG1vcmUgcG9pbnRzLlxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcG9pbnRzLnB1c2goLi4ucG9zdHBvbmVkKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0xpbmVFbGVtZW50fSBsaW5lXG4gKiBAcGFyYW0ge1BvaW50RWxlbWVudH0gc291cmNlUG9pbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eVxuICogQHJldHVybnMge3twb2ludD86IFBvaW50RWxlbWVudCwgZmlyc3Q/OiBib29sZWFuLCBsYXN0PzogYm9vbGVhbn19XG4gKi9cbmZ1bmN0aW9uIGZpbmRQb2ludChsaW5lLCBzb3VyY2VQb2ludCwgcHJvcGVydHkpIHtcbiAgY29uc3QgcG9pbnQgPSBsaW5lLmludGVycG9sYXRlKHNvdXJjZVBvaW50LCBwcm9wZXJ0eSk7XG4gIGlmICghcG9pbnQpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBjb25zdCBwb2ludFZhbHVlID0gcG9pbnRbcHJvcGVydHldO1xuICBjb25zdCBzZWdtZW50cyA9IGxpbmUuc2VnbWVudHM7XG4gIGNvbnN0IGxpbmVQb2ludHMgPSBsaW5lLnBvaW50cztcbiAgbGV0IGZpcnN0ID0gZmFsc2U7XG4gIGxldCBsYXN0ID0gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzZWdtZW50ID0gc2VnbWVudHNbaV07XG4gICAgY29uc3QgZmlyc3RWYWx1ZSA9IGxpbmVQb2ludHNbc2VnbWVudC5zdGFydF1bcHJvcGVydHldO1xuICAgIGNvbnN0IGxhc3RWYWx1ZSA9IGxpbmVQb2ludHNbc2VnbWVudC5lbmRdW3Byb3BlcnR5XTtcbiAgICBpZiAoX2lzQmV0d2Vlbihwb2ludFZhbHVlLCBmaXJzdFZhbHVlLCBsYXN0VmFsdWUpKSB7XG4gICAgICBmaXJzdCA9IHBvaW50VmFsdWUgPT09IGZpcnN0VmFsdWU7XG4gICAgICBsYXN0ID0gcG9pbnRWYWx1ZSA9PT0gbGFzdFZhbHVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiB7Zmlyc3QsIGxhc3QsIHBvaW50fTtcbn1cbiIsICJpbXBvcnQge1RBVX0gZnJvbSAnLi4vLi4vaGVscGVycy9pbmRleC5qcyc7XG5cbi8vIFRPRE86IHVzZSBlbGVtZW50cy5BcmNFbGVtZW50IGluc3RlYWRcbmV4cG9ydCBjbGFzcyBzaW1wbGVBcmMge1xuICBjb25zdHJ1Y3RvcihvcHRzKSB7XG4gICAgdGhpcy54ID0gb3B0cy54O1xuICAgIHRoaXMueSA9IG9wdHMueTtcbiAgICB0aGlzLnJhZGl1cyA9IG9wdHMucmFkaXVzO1xuICB9XG5cbiAgcGF0aFNlZ21lbnQoY3R4LCBib3VuZHMsIG9wdHMpIHtcbiAgICBjb25zdCB7eCwgeSwgcmFkaXVzfSA9IHRoaXM7XG4gICAgYm91bmRzID0gYm91bmRzIHx8IHtzdGFydDogMCwgZW5kOiBUQVV9O1xuICAgIGN0eC5hcmMoeCwgeSwgcmFkaXVzLCBib3VuZHMuZW5kLCBib3VuZHMuc3RhcnQsIHRydWUpO1xuICAgIHJldHVybiAhb3B0cy5ib3VuZHM7XG4gIH1cblxuICBpbnRlcnBvbGF0ZShwb2ludCkge1xuICAgIGNvbnN0IHt4LCB5LCByYWRpdXN9ID0gdGhpcztcbiAgICBjb25zdCBhbmdsZSA9IHBvaW50LmFuZ2xlO1xuICAgIHJldHVybiB7XG4gICAgICB4OiB4ICsgTWF0aC5jb3MoYW5nbGUpICogcmFkaXVzLFxuICAgICAgeTogeSArIE1hdGguc2luKGFuZ2xlKSAqIHJhZGl1cyxcbiAgICAgIGFuZ2xlXG4gICAgfTtcbiAgfVxufVxuIiwgImltcG9ydCB7aXNGaW5pdGV9IGZyb20gJy4uLy4uL2hlbHBlcnMvaW5kZXguanMnO1xuaW1wb3J0IHtfY3JlYXRlQm91bmRhcnlMaW5lfSBmcm9tICcuL2ZpbGxlci5oZWxwZXIuanMnO1xuaW1wb3J0IHtfZ2V0VGFyZ2V0UGl4ZWwsIF9nZXRUYXJnZXRWYWx1ZX0gZnJvbSAnLi9maWxsZXIub3B0aW9ucy5qcyc7XG5pbXBvcnQge19idWlsZFN0YWNrTGluZX0gZnJvbSAnLi9maWxsZXIudGFyZ2V0LnN0YWNrLmpzJztcbmltcG9ydCB7c2ltcGxlQXJjfSBmcm9tICcuL3NpbXBsZUFyYy5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uLy4uL2NvcmUvY29yZS5jb250cm9sbGVyLmpzJykuZGVmYXVsdCB9IENoYXJ0XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vLi4vY29yZS9jb3JlLnNjYWxlLmpzJykuZGVmYXVsdCB9IFNjYWxlXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vLi4vZWxlbWVudHMvZWxlbWVudC5wb2ludC5qcycpLmRlZmF1bHQgfSBQb2ludEVsZW1lbnRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gX2dldFRhcmdldChzb3VyY2UpIHtcbiAgY29uc3Qge2NoYXJ0LCBmaWxsLCBsaW5lfSA9IHNvdXJjZTtcblxuICBpZiAoaXNGaW5pdGUoZmlsbCkpIHtcbiAgICByZXR1cm4gZ2V0TGluZUJ5SW5kZXgoY2hhcnQsIGZpbGwpO1xuICB9XG5cbiAgaWYgKGZpbGwgPT09ICdzdGFjaycpIHtcbiAgICByZXR1cm4gX2J1aWxkU3RhY2tMaW5lKHNvdXJjZSk7XG4gIH1cblxuICBpZiAoZmlsbCA9PT0gJ3NoYXBlJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgY29uc3QgYm91bmRhcnkgPSBjb21wdXRlQm91bmRhcnkoc291cmNlKTtcblxuICBpZiAoYm91bmRhcnkgaW5zdGFuY2VvZiBzaW1wbGVBcmMpIHtcbiAgICByZXR1cm4gYm91bmRhcnk7XG4gIH1cblxuICByZXR1cm4gX2NyZWF0ZUJvdW5kYXJ5TGluZShib3VuZGFyeSwgbGluZSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtDaGFydH0gY2hhcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICovXG5mdW5jdGlvbiBnZXRMaW5lQnlJbmRleChjaGFydCwgaW5kZXgpIHtcbiAgY29uc3QgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGluZGV4KTtcbiAgY29uc3QgdmlzaWJsZSA9IG1ldGEgJiYgY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShpbmRleCk7XG4gIHJldHVybiB2aXNpYmxlID8gbWV0YS5kYXRhc2V0IDogbnVsbDtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZUJvdW5kYXJ5KHNvdXJjZSkge1xuICBjb25zdCBzY2FsZSA9IHNvdXJjZS5zY2FsZSB8fCB7fTtcblxuICBpZiAoc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbkZvclZhbHVlKSB7XG4gICAgcmV0dXJuIGNvbXB1dGVDaXJjdWxhckJvdW5kYXJ5KHNvdXJjZSk7XG4gIH1cbiAgcmV0dXJuIGNvbXB1dGVMaW5lYXJCb3VuZGFyeShzb3VyY2UpO1xufVxuXG5cbmZ1bmN0aW9uIGNvbXB1dGVMaW5lYXJCb3VuZGFyeShzb3VyY2UpIHtcbiAgY29uc3Qge3NjYWxlID0ge30sIGZpbGx9ID0gc291cmNlO1xuICBjb25zdCBwaXhlbCA9IF9nZXRUYXJnZXRQaXhlbChmaWxsLCBzY2FsZSk7XG5cbiAgaWYgKGlzRmluaXRlKHBpeGVsKSkge1xuICAgIGNvbnN0IGhvcml6b250YWwgPSBzY2FsZS5pc0hvcml6b250YWwoKTtcblxuICAgIHJldHVybiB7XG4gICAgICB4OiBob3Jpem9udGFsID8gcGl4ZWwgOiBudWxsLFxuICAgICAgeTogaG9yaXpvbnRhbCA/IG51bGwgOiBwaXhlbFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZUNpcmN1bGFyQm91bmRhcnkoc291cmNlKSB7XG4gIGNvbnN0IHtzY2FsZSwgZmlsbH0gPSBzb3VyY2U7XG4gIGNvbnN0IG9wdGlvbnMgPSBzY2FsZS5vcHRpb25zO1xuICBjb25zdCBsZW5ndGggPSBzY2FsZS5nZXRMYWJlbHMoKS5sZW5ndGg7XG4gIGNvbnN0IHN0YXJ0ID0gb3B0aW9ucy5yZXZlcnNlID8gc2NhbGUubWF4IDogc2NhbGUubWluO1xuICBjb25zdCB2YWx1ZSA9IF9nZXRUYXJnZXRWYWx1ZShmaWxsLCBzY2FsZSwgc3RhcnQpO1xuICBjb25zdCB0YXJnZXQgPSBbXTtcblxuICBpZiAob3B0aW9ucy5ncmlkLmNpcmN1bGFyKSB7XG4gICAgY29uc3QgY2VudGVyID0gc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbkZvclZhbHVlKDAsIHN0YXJ0KTtcbiAgICByZXR1cm4gbmV3IHNpbXBsZUFyYyh7XG4gICAgICB4OiBjZW50ZXIueCxcbiAgICAgIHk6IGNlbnRlci55LFxuICAgICAgcmFkaXVzOiBzY2FsZS5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZSh2YWx1ZSlcbiAgICB9KTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICB0YXJnZXQucHVzaChzY2FsZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUoaSwgdmFsdWUpKTtcbiAgfVxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG4iLCAiaW1wb3J0IHtjbGlwQXJlYSwgdW5jbGlwQXJlYX0gZnJvbSAnLi4vLi4vaGVscGVycy9pbmRleC5qcyc7XG5pbXBvcnQge19maW5kU2VnbWVudEVuZCwgX2dldEJvdW5kcywgX3NlZ21lbnRzfSBmcm9tICcuL2ZpbGxlci5zZWdtZW50LmpzJztcbmltcG9ydCB7X2dldFRhcmdldH0gZnJvbSAnLi9maWxsZXIudGFyZ2V0LmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIF9kcmF3ZmlsbChjdHgsIHNvdXJjZSwgYXJlYSkge1xuICBjb25zdCB0YXJnZXQgPSBfZ2V0VGFyZ2V0KHNvdXJjZSk7XG4gIGNvbnN0IHtsaW5lLCBzY2FsZSwgYXhpc30gPSBzb3VyY2U7XG4gIGNvbnN0IGxpbmVPcHRzID0gbGluZS5vcHRpb25zO1xuICBjb25zdCBmaWxsT3B0aW9uID0gbGluZU9wdHMuZmlsbDtcbiAgY29uc3QgY29sb3IgPSBsaW5lT3B0cy5iYWNrZ3JvdW5kQ29sb3I7XG4gIGNvbnN0IHthYm92ZSA9IGNvbG9yLCBiZWxvdyA9IGNvbG9yfSA9IGZpbGxPcHRpb24gfHwge307XG4gIGlmICh0YXJnZXQgJiYgbGluZS5wb2ludHMubGVuZ3RoKSB7XG4gICAgY2xpcEFyZWEoY3R4LCBhcmVhKTtcbiAgICBkb0ZpbGwoY3R4LCB7bGluZSwgdGFyZ2V0LCBhYm92ZSwgYmVsb3csIGFyZWEsIHNjYWxlLCBheGlzfSk7XG4gICAgdW5jbGlwQXJlYShjdHgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRvRmlsbChjdHgsIGNmZykge1xuICBjb25zdCB7bGluZSwgdGFyZ2V0LCBhYm92ZSwgYmVsb3csIGFyZWEsIHNjYWxlfSA9IGNmZztcbiAgY29uc3QgcHJvcGVydHkgPSBsaW5lLl9sb29wID8gJ2FuZ2xlJyA6IGNmZy5heGlzO1xuXG4gIGN0eC5zYXZlKCk7XG5cbiAgaWYgKHByb3BlcnR5ID09PSAneCcgJiYgYmVsb3cgIT09IGFib3ZlKSB7XG4gICAgY2xpcFZlcnRpY2FsKGN0eCwgdGFyZ2V0LCBhcmVhLnRvcCk7XG4gICAgZmlsbChjdHgsIHtsaW5lLCB0YXJnZXQsIGNvbG9yOiBhYm92ZSwgc2NhbGUsIHByb3BlcnR5fSk7XG4gICAgY3R4LnJlc3RvcmUoKTtcbiAgICBjdHguc2F2ZSgpO1xuICAgIGNsaXBWZXJ0aWNhbChjdHgsIHRhcmdldCwgYXJlYS5ib3R0b20pO1xuICB9XG4gIGZpbGwoY3R4LCB7bGluZSwgdGFyZ2V0LCBjb2xvcjogYmVsb3csIHNjYWxlLCBwcm9wZXJ0eX0pO1xuXG4gIGN0eC5yZXN0b3JlKCk7XG59XG5cbmZ1bmN0aW9uIGNsaXBWZXJ0aWNhbChjdHgsIHRhcmdldCwgY2xpcFkpIHtcbiAgY29uc3Qge3NlZ21lbnRzLCBwb2ludHN9ID0gdGFyZ2V0O1xuICBsZXQgZmlyc3QgPSB0cnVlO1xuICBsZXQgbGluZUxvb3AgPSBmYWxzZTtcblxuICBjdHguYmVnaW5QYXRoKCk7XG4gIGZvciAoY29uc3Qgc2VnbWVudCBvZiBzZWdtZW50cykge1xuICAgIGNvbnN0IHtzdGFydCwgZW5kfSA9IHNlZ21lbnQ7XG4gICAgY29uc3QgZmlyc3RQb2ludCA9IHBvaW50c1tzdGFydF07XG4gICAgY29uc3QgbGFzdFBvaW50ID0gcG9pbnRzW19maW5kU2VnbWVudEVuZChzdGFydCwgZW5kLCBwb2ludHMpXTtcbiAgICBpZiAoZmlyc3QpIHtcbiAgICAgIGN0eC5tb3ZlVG8oZmlyc3RQb2ludC54LCBmaXJzdFBvaW50LnkpO1xuICAgICAgZmlyc3QgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3R4LmxpbmVUbyhmaXJzdFBvaW50LngsIGNsaXBZKTtcbiAgICAgIGN0eC5saW5lVG8oZmlyc3RQb2ludC54LCBmaXJzdFBvaW50LnkpO1xuICAgIH1cbiAgICBsaW5lTG9vcCA9ICEhdGFyZ2V0LnBhdGhTZWdtZW50KGN0eCwgc2VnbWVudCwge21vdmU6IGxpbmVMb29wfSk7XG4gICAgaWYgKGxpbmVMb29wKSB7XG4gICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN0eC5saW5lVG8obGFzdFBvaW50LngsIGNsaXBZKTtcbiAgICB9XG4gIH1cblxuICBjdHgubGluZVRvKHRhcmdldC5maXJzdCgpLngsIGNsaXBZKTtcbiAgY3R4LmNsb3NlUGF0aCgpO1xuICBjdHguY2xpcCgpO1xufVxuXG5mdW5jdGlvbiBmaWxsKGN0eCwgY2ZnKSB7XG4gIGNvbnN0IHtsaW5lLCB0YXJnZXQsIHByb3BlcnR5LCBjb2xvciwgc2NhbGV9ID0gY2ZnO1xuICBjb25zdCBzZWdtZW50cyA9IF9zZWdtZW50cyhsaW5lLCB0YXJnZXQsIHByb3BlcnR5KTtcblxuICBmb3IgKGNvbnN0IHtzb3VyY2U6IHNyYywgdGFyZ2V0OiB0Z3QsIHN0YXJ0LCBlbmR9IG9mIHNlZ21lbnRzKSB7XG4gICAgY29uc3Qge3N0eWxlOiB7YmFja2dyb3VuZENvbG9yID0gY29sb3J9ID0ge319ID0gc3JjO1xuICAgIGNvbnN0IG5vdFNoYXBlID0gdGFyZ2V0ICE9PSB0cnVlO1xuXG4gICAgY3R4LnNhdmUoKTtcbiAgICBjdHguZmlsbFN0eWxlID0gYmFja2dyb3VuZENvbG9yO1xuXG4gICAgY2xpcEJvdW5kcyhjdHgsIHNjYWxlLCBub3RTaGFwZSAmJiBfZ2V0Qm91bmRzKHByb3BlcnR5LCBzdGFydCwgZW5kKSk7XG5cbiAgICBjdHguYmVnaW5QYXRoKCk7XG5cbiAgICBjb25zdCBsaW5lTG9vcCA9ICEhbGluZS5wYXRoU2VnbWVudChjdHgsIHNyYyk7XG5cbiAgICBsZXQgbG9vcDtcbiAgICBpZiAobm90U2hhcGUpIHtcbiAgICAgIGlmIChsaW5lTG9vcCkge1xuICAgICAgICBjdHguY2xvc2VQYXRoKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbnRlcnBvbGF0ZWRMaW5lVG8oY3R4LCB0YXJnZXQsIGVuZCwgcHJvcGVydHkpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0YXJnZXRMb29wID0gISF0YXJnZXQucGF0aFNlZ21lbnQoY3R4LCB0Z3QsIHttb3ZlOiBsaW5lTG9vcCwgcmV2ZXJzZTogdHJ1ZX0pO1xuICAgICAgbG9vcCA9IGxpbmVMb29wICYmIHRhcmdldExvb3A7XG4gICAgICBpZiAoIWxvb3ApIHtcbiAgICAgICAgaW50ZXJwb2xhdGVkTGluZVRvKGN0eCwgdGFyZ2V0LCBzdGFydCwgcHJvcGVydHkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICBjdHguZmlsbChsb29wID8gJ2V2ZW5vZGQnIDogJ25vbnplcm8nKTtcblxuICAgIGN0eC5yZXN0b3JlKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2xpcEJvdW5kcyhjdHgsIHNjYWxlLCBib3VuZHMpIHtcbiAgY29uc3Qge3RvcCwgYm90dG9tfSA9IHNjYWxlLmNoYXJ0LmNoYXJ0QXJlYTtcbiAgY29uc3Qge3Byb3BlcnR5LCBzdGFydCwgZW5kfSA9IGJvdW5kcyB8fCB7fTtcbiAgaWYgKHByb3BlcnR5ID09PSAneCcpIHtcbiAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgY3R4LnJlY3Qoc3RhcnQsIHRvcCwgZW5kIC0gc3RhcnQsIGJvdHRvbSAtIHRvcCk7XG4gICAgY3R4LmNsaXAoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZWRMaW5lVG8oY3R4LCB0YXJnZXQsIHBvaW50LCBwcm9wZXJ0eSkge1xuICBjb25zdCBpbnRlcnBvbGF0ZWRQb2ludCA9IHRhcmdldC5pbnRlcnBvbGF0ZShwb2ludCwgcHJvcGVydHkpO1xuICBpZiAoaW50ZXJwb2xhdGVkUG9pbnQpIHtcbiAgICBjdHgubGluZVRvKGludGVycG9sYXRlZFBvaW50LngsIGludGVycG9sYXRlZFBvaW50LnkpO1xuICB9XG59XG5cbiIsICIvKipcbiAqIFBsdWdpbiBiYXNlZCBvbiBkaXNjdXNzaW9uIGZyb20gdGhlIGZvbGxvd2luZyBDaGFydC5qcyBpc3N1ZXM6XG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8yMzgwI2lzc3VlY29tbWVudC0yNzk5NjE1NjlcbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzI0NDAjaXNzdWVjb21tZW50LTI1NjQ2MTg5N1xuICovXG5cbmltcG9ydCBMaW5lRWxlbWVudCBmcm9tICcuLi8uLi9lbGVtZW50cy9lbGVtZW50LmxpbmUuanMnO1xuaW1wb3J0IHtfZHJhd2ZpbGx9IGZyb20gJy4vZmlsbGVyLmRyYXdpbmcuanMnO1xuaW1wb3J0IHtfc2hvdWxkQXBwbHlGaWxsfSBmcm9tICcuL2ZpbGxlci5oZWxwZXIuanMnO1xuaW1wb3J0IHtfZGVjb2RlRmlsbCwgX3Jlc29sdmVUYXJnZXR9IGZyb20gJy4vZmlsbGVyLm9wdGlvbnMuanMnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGlkOiAnZmlsbGVyJyxcblxuICBhZnRlckRhdGFzZXRzVXBkYXRlKGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgIGNvbnN0IGNvdW50ID0gKGNoYXJ0LmRhdGEuZGF0YXNldHMgfHwgW10pLmxlbmd0aDtcbiAgICBjb25zdCBzb3VyY2VzID0gW107XG4gICAgbGV0IG1ldGEsIGksIGxpbmUsIHNvdXJjZTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7XG4gICAgICBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoaSk7XG4gICAgICBsaW5lID0gbWV0YS5kYXRhc2V0O1xuICAgICAgc291cmNlID0gbnVsbDtcblxuICAgICAgaWYgKGxpbmUgJiYgbGluZS5vcHRpb25zICYmIGxpbmUgaW5zdGFuY2VvZiBMaW5lRWxlbWVudCkge1xuICAgICAgICBzb3VyY2UgPSB7XG4gICAgICAgICAgdmlzaWJsZTogY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShpKSxcbiAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICBmaWxsOiBfZGVjb2RlRmlsbChsaW5lLCBpLCBjb3VudCksXG4gICAgICAgICAgY2hhcnQsXG4gICAgICAgICAgYXhpczogbWV0YS5jb250cm9sbGVyLm9wdGlvbnMuaW5kZXhBeGlzLFxuICAgICAgICAgIHNjYWxlOiBtZXRhLnZTY2FsZSxcbiAgICAgICAgICBsaW5lLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBtZXRhLiRmaWxsZXIgPSBzb3VyY2U7XG4gICAgICBzb3VyY2VzLnB1c2goc291cmNlKTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7ICsraSkge1xuICAgICAgc291cmNlID0gc291cmNlc1tpXTtcbiAgICAgIGlmICghc291cmNlIHx8IHNvdXJjZS5maWxsID09PSBmYWxzZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgc291cmNlLmZpbGwgPSBfcmVzb2x2ZVRhcmdldChzb3VyY2VzLCBpLCBvcHRpb25zLnByb3BhZ2F0ZSk7XG4gICAgfVxuICB9LFxuXG4gIGJlZm9yZURyYXcoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgY29uc3QgZHJhdyA9IG9wdGlvbnMuZHJhd1RpbWUgPT09ICdiZWZvcmVEcmF3JztcbiAgICBjb25zdCBtZXRhc2V0cyA9IGNoYXJ0LmdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKTtcbiAgICBjb25zdCBhcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xuICAgIGZvciAobGV0IGkgPSBtZXRhc2V0cy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgY29uc3Qgc291cmNlID0gbWV0YXNldHNbaV0uJGZpbGxlcjtcbiAgICAgIGlmICghc291cmNlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBzb3VyY2UubGluZS51cGRhdGVDb250cm9sUG9pbnRzKGFyZWEsIHNvdXJjZS5heGlzKTtcbiAgICAgIGlmIChkcmF3ICYmIHNvdXJjZS5maWxsKSB7XG4gICAgICAgIF9kcmF3ZmlsbChjaGFydC5jdHgsIHNvdXJjZSwgYXJlYSk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGJlZm9yZURhdGFzZXRzRHJhdyhjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucy5kcmF3VGltZSAhPT0gJ2JlZm9yZURhdGFzZXRzRHJhdycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBtZXRhc2V0cyA9IGNoYXJ0LmdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMoKTtcbiAgICBmb3IgKGxldCBpID0gbWV0YXNldHMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IG1ldGFzZXRzW2ldLiRmaWxsZXI7XG5cbiAgICAgIGlmIChfc2hvdWxkQXBwbHlGaWxsKHNvdXJjZSkpIHtcbiAgICAgICAgX2RyYXdmaWxsKGNoYXJ0LmN0eCwgc291cmNlLCBjaGFydC5jaGFydEFyZWEpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBiZWZvcmVEYXRhc2V0RHJhdyhjaGFydCwgYXJncywgb3B0aW9ucykge1xuICAgIGNvbnN0IHNvdXJjZSA9IGFyZ3MubWV0YS4kZmlsbGVyO1xuXG4gICAgaWYgKCFfc2hvdWxkQXBwbHlGaWxsKHNvdXJjZSkgfHwgb3B0aW9ucy5kcmF3VGltZSAhPT0gJ2JlZm9yZURhdGFzZXREcmF3Jykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIF9kcmF3ZmlsbChjaGFydC5jdHgsIHNvdXJjZSwgY2hhcnQuY2hhcnRBcmVhKTtcbiAgfSxcblxuICBkZWZhdWx0czoge1xuICAgIHByb3BhZ2F0ZTogdHJ1ZSxcbiAgICBkcmF3VGltZTogJ2JlZm9yZURhdGFzZXREcmF3J1xuICB9XG59O1xuIiwgImltcG9ydCBkZWZhdWx0cyBmcm9tICcuLi9jb3JlL2NvcmUuZGVmYXVsdHMuanMnO1xuaW1wb3J0IEVsZW1lbnQgZnJvbSAnLi4vY29yZS9jb3JlLmVsZW1lbnQuanMnO1xuaW1wb3J0IGxheW91dHMgZnJvbSAnLi4vY29yZS9jb3JlLmxheW91dHMuanMnO1xuaW1wb3J0IHthZGRSb3VuZGVkUmVjdFBhdGgsIGRyYXdQb2ludExlZ2VuZCwgcmVuZGVyVGV4dH0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNhbnZhcy5qcyc7XG5pbXBvcnQge1xuICBfaXNCZXR3ZWVuLFxuICBjYWxsYmFjayBhcyBjYWxsLFxuICBjbGlwQXJlYSxcbiAgZ2V0UnRsQWRhcHRlcixcbiAgb3ZlcnJpZGVUZXh0RGlyZWN0aW9uLFxuICByZXN0b3JlVGV4dERpcmVjdGlvbixcbiAgdG9Gb250LFxuICB0b1BhZGRpbmcsXG4gIHVuY2xpcEFyZWEsXG4gIHZhbHVlT3JEZWZhdWx0LFxufSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcbmltcG9ydCB7X2FsaWduU3RhcnRFbmQsIF90ZXh0WCwgX3RvTGVmdFJpZ2h0Q2VudGVyfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuZXh0cmFzLmpzJztcbmltcG9ydCB7dG9UUkJMQ29ybmVyc30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm9wdGlvbnMuanMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi90eXBlcy9pbmRleC5qcycpLkNoYXJ0RXZlbnQgfSBDaGFydEV2ZW50XG4gKi9cblxuY29uc3QgZ2V0Qm94U2l6ZSA9IChsYWJlbE9wdHMsIGZvbnRTaXplKSA9PiB7XG4gIGxldCB7Ym94SGVpZ2h0ID0gZm9udFNpemUsIGJveFdpZHRoID0gZm9udFNpemV9ID0gbGFiZWxPcHRzO1xuXG4gIGlmIChsYWJlbE9wdHMudXNlUG9pbnRTdHlsZSkge1xuICAgIGJveEhlaWdodCA9IE1hdGgubWluKGJveEhlaWdodCwgZm9udFNpemUpO1xuICAgIGJveFdpZHRoID0gbGFiZWxPcHRzLnBvaW50U3R5bGVXaWR0aCB8fCBNYXRoLm1pbihib3hXaWR0aCwgZm9udFNpemUpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBib3hXaWR0aCxcbiAgICBib3hIZWlnaHQsXG4gICAgaXRlbUhlaWdodDogTWF0aC5tYXgoZm9udFNpemUsIGJveEhlaWdodClcbiAgfTtcbn07XG5cbmNvbnN0IGl0ZW1zRXF1YWwgPSAoYSwgYikgPT4gYSAhPT0gbnVsbCAmJiBiICE9PSBudWxsICYmIGEuZGF0YXNldEluZGV4ID09PSBiLmRhdGFzZXRJbmRleCAmJiBhLmluZGV4ID09PSBiLmluZGV4O1xuXG5leHBvcnQgY2xhc3MgTGVnZW5kIGV4dGVuZHMgRWxlbWVudCB7XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7eyBjdHg6IGFueTsgb3B0aW9uczogYW55OyBjaGFydDogYW55OyB9fSBjb25maWdcblx0ICovXG4gIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9hZGRlZCA9IGZhbHNlO1xuXG4gICAgLy8gQ29udGFpbnMgaGl0IGJveGVzIGZvciBlYWNoIGRhdGFzZXQgKGluIGRhdGFzZXQgb3JkZXIpXG4gICAgdGhpcy5sZWdlbmRIaXRCb3hlcyA9IFtdO1xuXG4gICAgLyoqXG4gXHRcdCAqIEBwcml2YXRlXG4gXHRcdCAqL1xuICAgIHRoaXMuX2hvdmVyZWRJdGVtID0gbnVsbDtcblxuICAgIC8vIEFyZSB3ZSBpbiBkb3VnaG51dCBtb2RlIHdoaWNoIGhhcyBhIGRpZmZlcmVudCBkYXRhIHR5cGVcbiAgICB0aGlzLmRvdWdobnV0TW9kZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5jaGFydCA9IGNvbmZpZy5jaGFydDtcbiAgICB0aGlzLm9wdGlvbnMgPSBjb25maWcub3B0aW9ucztcbiAgICB0aGlzLmN0eCA9IGNvbmZpZy5jdHg7XG4gICAgdGhpcy5sZWdlbmRJdGVtcyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmNvbHVtblNpemVzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubGluZVdpZHRocyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1heEhlaWdodCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1heFdpZHRoID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudG9wID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuYm90dG9tID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubGVmdCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaGVpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMud2lkdGggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fbWFyZ2lucyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnBvc2l0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMud2VpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZnVsbFNpemUgPSB1bmRlZmluZWQ7XG4gIH1cblxuICB1cGRhdGUobWF4V2lkdGgsIG1heEhlaWdodCwgbWFyZ2lucykge1xuICAgIHRoaXMubWF4V2lkdGggPSBtYXhXaWR0aDtcbiAgICB0aGlzLm1heEhlaWdodCA9IG1heEhlaWdodDtcbiAgICB0aGlzLl9tYXJnaW5zID0gbWFyZ2lucztcblxuICAgIHRoaXMuc2V0RGltZW5zaW9ucygpO1xuICAgIHRoaXMuYnVpbGRMYWJlbHMoKTtcbiAgICB0aGlzLmZpdCgpO1xuICB9XG5cbiAgc2V0RGltZW5zaW9ucygpIHtcbiAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgdGhpcy53aWR0aCA9IHRoaXMubWF4V2lkdGg7XG4gICAgICB0aGlzLmxlZnQgPSB0aGlzLl9tYXJnaW5zLmxlZnQ7XG4gICAgICB0aGlzLnJpZ2h0ID0gdGhpcy53aWR0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLm1heEhlaWdodDtcbiAgICAgIHRoaXMudG9wID0gdGhpcy5fbWFyZ2lucy50b3A7XG4gICAgICB0aGlzLmJvdHRvbSA9IHRoaXMuaGVpZ2h0O1xuICAgIH1cbiAgfVxuXG4gIGJ1aWxkTGFiZWxzKCkge1xuICAgIGNvbnN0IGxhYmVsT3B0cyA9IHRoaXMub3B0aW9ucy5sYWJlbHMgfHwge307XG4gICAgbGV0IGxlZ2VuZEl0ZW1zID0gY2FsbChsYWJlbE9wdHMuZ2VuZXJhdGVMYWJlbHMsIFt0aGlzLmNoYXJ0XSwgdGhpcykgfHwgW107XG5cbiAgICBpZiAobGFiZWxPcHRzLmZpbHRlcikge1xuICAgICAgbGVnZW5kSXRlbXMgPSBsZWdlbmRJdGVtcy5maWx0ZXIoKGl0ZW0pID0+IGxhYmVsT3B0cy5maWx0ZXIoaXRlbSwgdGhpcy5jaGFydC5kYXRhKSk7XG4gICAgfVxuXG4gICAgaWYgKGxhYmVsT3B0cy5zb3J0KSB7XG4gICAgICBsZWdlbmRJdGVtcyA9IGxlZ2VuZEl0ZW1zLnNvcnQoKGEsIGIpID0+IGxhYmVsT3B0cy5zb3J0KGEsIGIsIHRoaXMuY2hhcnQuZGF0YSkpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMucmV2ZXJzZSkge1xuICAgICAgbGVnZW5kSXRlbXMucmV2ZXJzZSgpO1xuICAgIH1cblxuICAgIHRoaXMubGVnZW5kSXRlbXMgPSBsZWdlbmRJdGVtcztcbiAgfVxuXG4gIGZpdCgpIHtcbiAgICBjb25zdCB7b3B0aW9ucywgY3R4fSA9IHRoaXM7XG5cbiAgICAvLyBUaGUgbGVnZW5kIG1heSBub3QgYmUgZGlzcGxheWVkIGZvciBhIHZhcmlldHkgb2YgcmVhc29ucyBpbmNsdWRpbmdcbiAgICAvLyB0aGUgZmFjdCB0aGF0IHRoZSBkZWZhdWx0cyBnb3Qgc2V0IHRvIGBmYWxzZWAuXG4gICAgLy8gV2hlbiB0aGUgbGVnZW5kIGlzIG5vdCBkaXNwbGF5ZWQsIHRoZXJlIGFyZSBubyBndWFyYW50ZWVzIHRoYXQgdGhlIG9wdGlvbnNcbiAgICAvLyBhcmUgY29ycmVjdGx5IGZvcm1hdHRlZCBzbyB3ZSBuZWVkIHRvIGJhaWwgb3V0IGFzIGVhcmx5IGFzIHBvc3NpYmxlLlxuICAgIGlmICghb3B0aW9ucy5kaXNwbGF5KSB7XG4gICAgICB0aGlzLndpZHRoID0gdGhpcy5oZWlnaHQgPSAwO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGxhYmVsT3B0cyA9IG9wdGlvbnMubGFiZWxzO1xuICAgIGNvbnN0IGxhYmVsRm9udCA9IHRvRm9udChsYWJlbE9wdHMuZm9udCk7XG4gICAgY29uc3QgZm9udFNpemUgPSBsYWJlbEZvbnQuc2l6ZTtcbiAgICBjb25zdCB0aXRsZUhlaWdodCA9IHRoaXMuX2NvbXB1dGVUaXRsZUhlaWdodCgpO1xuICAgIGNvbnN0IHtib3hXaWR0aCwgaXRlbUhlaWdodH0gPSBnZXRCb3hTaXplKGxhYmVsT3B0cywgZm9udFNpemUpO1xuXG4gICAgbGV0IHdpZHRoLCBoZWlnaHQ7XG5cbiAgICBjdHguZm9udCA9IGxhYmVsRm9udC5zdHJpbmc7XG5cbiAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgd2lkdGggPSB0aGlzLm1heFdpZHRoOyAvLyBmaWxsIGFsbCB0aGUgd2lkdGhcbiAgICAgIGhlaWdodCA9IHRoaXMuX2ZpdFJvd3ModGl0bGVIZWlnaHQsIGZvbnRTaXplLCBib3hXaWR0aCwgaXRlbUhlaWdodCkgKyAxMDtcbiAgICB9IGVsc2Uge1xuICAgICAgaGVpZ2h0ID0gdGhpcy5tYXhIZWlnaHQ7IC8vIGZpbGwgYWxsIHRoZSBoZWlnaHRcbiAgICAgIHdpZHRoID0gdGhpcy5fZml0Q29scyh0aXRsZUhlaWdodCwgbGFiZWxGb250LCBib3hXaWR0aCwgaXRlbUhlaWdodCkgKyAxMDtcbiAgICB9XG5cbiAgICB0aGlzLndpZHRoID0gTWF0aC5taW4od2lkdGgsIG9wdGlvbnMubWF4V2lkdGggfHwgdGhpcy5tYXhXaWR0aCk7XG4gICAgdGhpcy5oZWlnaHQgPSBNYXRoLm1pbihoZWlnaHQsIG9wdGlvbnMubWF4SGVpZ2h0IHx8IHRoaXMubWF4SGVpZ2h0KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2ZpdFJvd3ModGl0bGVIZWlnaHQsIGZvbnRTaXplLCBib3hXaWR0aCwgaXRlbUhlaWdodCkge1xuICAgIGNvbnN0IHtjdHgsIG1heFdpZHRoLCBvcHRpb25zOiB7bGFiZWxzOiB7cGFkZGluZ319fSA9IHRoaXM7XG4gICAgY29uc3QgaGl0Ym94ZXMgPSB0aGlzLmxlZ2VuZEhpdEJveGVzID0gW107XG4gICAgLy8gV2lkdGggb2YgZWFjaCBsaW5lIG9mIGxlZ2VuZCBib3hlcy4gTGFiZWxzIHdyYXAgb250byBtdWx0aXBsZSBsaW5lcyB3aGVuIHRoZXJlIGFyZSB0b28gbWFueSB0byBmaXQgb24gb25lXG4gICAgY29uc3QgbGluZVdpZHRocyA9IHRoaXMubGluZVdpZHRocyA9IFswXTtcbiAgICBjb25zdCBsaW5lSGVpZ2h0ID0gaXRlbUhlaWdodCArIHBhZGRpbmc7XG4gICAgbGV0IHRvdGFsSGVpZ2h0ID0gdGl0bGVIZWlnaHQ7XG5cbiAgICBjdHgudGV4dEFsaWduID0gJ2xlZnQnO1xuICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcblxuICAgIGxldCByb3cgPSAtMTtcbiAgICBsZXQgdG9wID0gLWxpbmVIZWlnaHQ7XG4gICAgdGhpcy5sZWdlbmRJdGVtcy5mb3JFYWNoKChsZWdlbmRJdGVtLCBpKSA9PiB7XG4gICAgICBjb25zdCBpdGVtV2lkdGggPSBib3hXaWR0aCArIChmb250U2l6ZSAvIDIpICsgY3R4Lm1lYXN1cmVUZXh0KGxlZ2VuZEl0ZW0udGV4dCkud2lkdGg7XG5cbiAgICAgIGlmIChpID09PSAwIHx8IGxpbmVXaWR0aHNbbGluZVdpZHRocy5sZW5ndGggLSAxXSArIGl0ZW1XaWR0aCArIDIgKiBwYWRkaW5nID4gbWF4V2lkdGgpIHtcbiAgICAgICAgdG90YWxIZWlnaHQgKz0gbGluZUhlaWdodDtcbiAgICAgICAgbGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aCAtIChpID4gMCA/IDAgOiAxKV0gPSAwO1xuICAgICAgICB0b3AgKz0gbGluZUhlaWdodDtcbiAgICAgICAgcm93Kys7XG4gICAgICB9XG5cbiAgICAgIGhpdGJveGVzW2ldID0ge2xlZnQ6IDAsIHRvcCwgcm93LCB3aWR0aDogaXRlbVdpZHRoLCBoZWlnaHQ6IGl0ZW1IZWlnaHR9O1xuXG4gICAgICBsaW5lV2lkdGhzW2xpbmVXaWR0aHMubGVuZ3RoIC0gMV0gKz0gaXRlbVdpZHRoICsgcGFkZGluZztcbiAgICB9KTtcblxuICAgIHJldHVybiB0b3RhbEhlaWdodDtcbiAgfVxuXG4gIF9maXRDb2xzKHRpdGxlSGVpZ2h0LCBsYWJlbEZvbnQsIGJveFdpZHRoLCBfaXRlbUhlaWdodCkge1xuICAgIGNvbnN0IHtjdHgsIG1heEhlaWdodCwgb3B0aW9uczoge2xhYmVsczoge3BhZGRpbmd9fX0gPSB0aGlzO1xuICAgIGNvbnN0IGhpdGJveGVzID0gdGhpcy5sZWdlbmRIaXRCb3hlcyA9IFtdO1xuICAgIGNvbnN0IGNvbHVtblNpemVzID0gdGhpcy5jb2x1bW5TaXplcyA9IFtdO1xuICAgIGNvbnN0IGhlaWdodExpbWl0ID0gbWF4SGVpZ2h0IC0gdGl0bGVIZWlnaHQ7XG5cbiAgICBsZXQgdG90YWxXaWR0aCA9IHBhZGRpbmc7XG4gICAgbGV0IGN1cnJlbnRDb2xXaWR0aCA9IDA7XG4gICAgbGV0IGN1cnJlbnRDb2xIZWlnaHQgPSAwO1xuXG4gICAgbGV0IGxlZnQgPSAwO1xuICAgIGxldCBjb2wgPSAwO1xuXG4gICAgdGhpcy5sZWdlbmRJdGVtcy5mb3JFYWNoKChsZWdlbmRJdGVtLCBpKSA9PiB7XG4gICAgICBjb25zdCB7aXRlbVdpZHRoLCBpdGVtSGVpZ2h0fSA9IGNhbGN1bGF0ZUl0ZW1TaXplKGJveFdpZHRoLCBsYWJlbEZvbnQsIGN0eCwgbGVnZW5kSXRlbSwgX2l0ZW1IZWlnaHQpO1xuXG4gICAgICAvLyBJZiB0b28gdGFsbCwgZ28gdG8gbmV3IGNvbHVtblxuICAgICAgaWYgKGkgPiAwICYmIGN1cnJlbnRDb2xIZWlnaHQgKyBpdGVtSGVpZ2h0ICsgMiAqIHBhZGRpbmcgPiBoZWlnaHRMaW1pdCkge1xuICAgICAgICB0b3RhbFdpZHRoICs9IGN1cnJlbnRDb2xXaWR0aCArIHBhZGRpbmc7XG4gICAgICAgIGNvbHVtblNpemVzLnB1c2goe3dpZHRoOiBjdXJyZW50Q29sV2lkdGgsIGhlaWdodDogY3VycmVudENvbEhlaWdodH0pOyAvLyBwcmV2aW91cyBjb2x1bW4gc2l6ZVxuICAgICAgICBsZWZ0ICs9IGN1cnJlbnRDb2xXaWR0aCArIHBhZGRpbmc7XG4gICAgICAgIGNvbCsrO1xuICAgICAgICBjdXJyZW50Q29sV2lkdGggPSBjdXJyZW50Q29sSGVpZ2h0ID0gMDtcbiAgICAgIH1cblxuICAgICAgLy8gU3RvcmUgdGhlIGhpdGJveCB3aWR0aCBhbmQgaGVpZ2h0IGhlcmUuIEZpbmFsIHBvc2l0aW9uIHdpbGwgYmUgdXBkYXRlZCBpbiBgZHJhd2BcbiAgICAgIGhpdGJveGVzW2ldID0ge2xlZnQsIHRvcDogY3VycmVudENvbEhlaWdodCwgY29sLCB3aWR0aDogaXRlbVdpZHRoLCBoZWlnaHQ6IGl0ZW1IZWlnaHR9O1xuXG4gICAgICAvLyBHZXQgbWF4IHdpZHRoXG4gICAgICBjdXJyZW50Q29sV2lkdGggPSBNYXRoLm1heChjdXJyZW50Q29sV2lkdGgsIGl0ZW1XaWR0aCk7XG4gICAgICBjdXJyZW50Q29sSGVpZ2h0ICs9IGl0ZW1IZWlnaHQgKyBwYWRkaW5nO1xuICAgIH0pO1xuXG4gICAgdG90YWxXaWR0aCArPSBjdXJyZW50Q29sV2lkdGg7XG4gICAgY29sdW1uU2l6ZXMucHVzaCh7d2lkdGg6IGN1cnJlbnRDb2xXaWR0aCwgaGVpZ2h0OiBjdXJyZW50Q29sSGVpZ2h0fSk7IC8vIHByZXZpb3VzIGNvbHVtbiBzaXplXG5cbiAgICByZXR1cm4gdG90YWxXaWR0aDtcbiAgfVxuXG4gIGFkanVzdEhpdEJveGVzKCkge1xuICAgIGlmICghdGhpcy5vcHRpb25zLmRpc3BsYXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdGl0bGVIZWlnaHQgPSB0aGlzLl9jb21wdXRlVGl0bGVIZWlnaHQoKTtcbiAgICBjb25zdCB7bGVnZW5kSGl0Qm94ZXM6IGhpdGJveGVzLCBvcHRpb25zOiB7YWxpZ24sIGxhYmVsczoge3BhZGRpbmd9LCBydGx9fSA9IHRoaXM7XG4gICAgY29uc3QgcnRsSGVscGVyID0gZ2V0UnRsQWRhcHRlcihydGwsIHRoaXMubGVmdCwgdGhpcy53aWR0aCk7XG4gICAgaWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgIGxldCByb3cgPSAwO1xuICAgICAgbGV0IGxlZnQgPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgdGhpcy5sZWZ0ICsgcGFkZGluZywgdGhpcy5yaWdodCAtIHRoaXMubGluZVdpZHRoc1tyb3ddKTtcbiAgICAgIGZvciAoY29uc3QgaGl0Ym94IG9mIGhpdGJveGVzKSB7XG4gICAgICAgIGlmIChyb3cgIT09IGhpdGJveC5yb3cpIHtcbiAgICAgICAgICByb3cgPSBoaXRib3gucm93O1xuICAgICAgICAgIGxlZnQgPSBfYWxpZ25TdGFydEVuZChhbGlnbiwgdGhpcy5sZWZ0ICsgcGFkZGluZywgdGhpcy5yaWdodCAtIHRoaXMubGluZVdpZHRoc1tyb3ddKTtcbiAgICAgICAgfVxuICAgICAgICBoaXRib3gudG9wICs9IHRoaXMudG9wICsgdGl0bGVIZWlnaHQgKyBwYWRkaW5nO1xuICAgICAgICBoaXRib3gubGVmdCA9IHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHJ0bEhlbHBlci54KGxlZnQpLCBoaXRib3gud2lkdGgpO1xuICAgICAgICBsZWZ0ICs9IGhpdGJveC53aWR0aCArIHBhZGRpbmc7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBjb2wgPSAwO1xuICAgICAgbGV0IHRvcCA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0aGlzLnRvcCArIHRpdGxlSGVpZ2h0ICsgcGFkZGluZywgdGhpcy5ib3R0b20gLSB0aGlzLmNvbHVtblNpemVzW2NvbF0uaGVpZ2h0KTtcbiAgICAgIGZvciAoY29uc3QgaGl0Ym94IG9mIGhpdGJveGVzKSB7XG4gICAgICAgIGlmIChoaXRib3guY29sICE9PSBjb2wpIHtcbiAgICAgICAgICBjb2wgPSBoaXRib3guY29sO1xuICAgICAgICAgIHRvcCA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0aGlzLnRvcCArIHRpdGxlSGVpZ2h0ICsgcGFkZGluZywgdGhpcy5ib3R0b20gLSB0aGlzLmNvbHVtblNpemVzW2NvbF0uaGVpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICBoaXRib3gudG9wID0gdG9wO1xuICAgICAgICBoaXRib3gubGVmdCArPSB0aGlzLmxlZnQgKyBwYWRkaW5nO1xuICAgICAgICBoaXRib3gubGVmdCA9IHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHJ0bEhlbHBlci54KGhpdGJveC5sZWZ0KSwgaGl0Ym94LndpZHRoKTtcbiAgICAgICAgdG9wICs9IGhpdGJveC5oZWlnaHQgKyBwYWRkaW5nO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlzSG9yaXpvbnRhbCgpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnBvc2l0aW9uID09PSAndG9wJyB8fCB0aGlzLm9wdGlvbnMucG9zaXRpb24gPT09ICdib3R0b20nO1xuICB9XG5cbiAgZHJhdygpIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLmRpc3BsYXkpIHtcbiAgICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgICAgY2xpcEFyZWEoY3R4LCB0aGlzKTtcblxuICAgICAgdGhpcy5fZHJhdygpO1xuXG4gICAgICB1bmNsaXBBcmVhKGN0eCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZHJhdygpIHtcbiAgICBjb25zdCB7b3B0aW9uczogb3B0cywgY29sdW1uU2l6ZXMsIGxpbmVXaWR0aHMsIGN0eH0gPSB0aGlzO1xuICAgIGNvbnN0IHthbGlnbiwgbGFiZWxzOiBsYWJlbE9wdHN9ID0gb3B0cztcbiAgICBjb25zdCBkZWZhdWx0Q29sb3IgPSBkZWZhdWx0cy5jb2xvcjtcbiAgICBjb25zdCBydGxIZWxwZXIgPSBnZXRSdGxBZGFwdGVyKG9wdHMucnRsLCB0aGlzLmxlZnQsIHRoaXMud2lkdGgpO1xuICAgIGNvbnN0IGxhYmVsRm9udCA9IHRvRm9udChsYWJlbE9wdHMuZm9udCk7XG4gICAgY29uc3Qge3BhZGRpbmd9ID0gbGFiZWxPcHRzO1xuICAgIGNvbnN0IGZvbnRTaXplID0gbGFiZWxGb250LnNpemU7XG4gICAgY29uc3QgaGFsZkZvbnRTaXplID0gZm9udFNpemUgLyAyO1xuICAgIGxldCBjdXJzb3I7XG5cbiAgICB0aGlzLmRyYXdUaXRsZSgpO1xuXG4gICAgLy8gQ2FudmFzIHNldHVwXG4gICAgY3R4LnRleHRBbGlnbiA9IHJ0bEhlbHBlci50ZXh0QWxpZ24oJ2xlZnQnKTtcbiAgICBjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG4gICAgY3R4LmxpbmVXaWR0aCA9IDAuNTtcbiAgICBjdHguZm9udCA9IGxhYmVsRm9udC5zdHJpbmc7XG5cbiAgICBjb25zdCB7Ym94V2lkdGgsIGJveEhlaWdodCwgaXRlbUhlaWdodH0gPSBnZXRCb3hTaXplKGxhYmVsT3B0cywgZm9udFNpemUpO1xuXG4gICAgLy8gY3VycmVudCBwb3NpdGlvblxuICAgIGNvbnN0IGRyYXdMZWdlbmRCb3ggPSBmdW5jdGlvbih4LCB5LCBsZWdlbmRJdGVtKSB7XG4gICAgICBpZiAoaXNOYU4oYm94V2lkdGgpIHx8IGJveFdpZHRoIDw9IDAgfHwgaXNOYU4oYm94SGVpZ2h0KSB8fCBib3hIZWlnaHQgPCAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gU2V0IHRoZSBjdHggZm9yIHRoZSBib3hcbiAgICAgIGN0eC5zYXZlKCk7XG5cbiAgICAgIGNvbnN0IGxpbmVXaWR0aCA9IHZhbHVlT3JEZWZhdWx0KGxlZ2VuZEl0ZW0ubGluZVdpZHRoLCAxKTtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmZpbGxTdHlsZSwgZGVmYXVsdENvbG9yKTtcbiAgICAgIGN0eC5saW5lQ2FwID0gdmFsdWVPckRlZmF1bHQobGVnZW5kSXRlbS5saW5lQ2FwLCAnYnV0dCcpO1xuICAgICAgY3R4LmxpbmVEYXNoT2Zmc2V0ID0gdmFsdWVPckRlZmF1bHQobGVnZW5kSXRlbS5saW5lRGFzaE9mZnNldCwgMCk7XG4gICAgICBjdHgubGluZUpvaW4gPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLmxpbmVKb2luLCAnbWl0ZXInKTtcbiAgICAgIGN0eC5saW5lV2lkdGggPSBsaW5lV2lkdGg7XG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSB2YWx1ZU9yRGVmYXVsdChsZWdlbmRJdGVtLnN0cm9rZVN0eWxlLCBkZWZhdWx0Q29sb3IpO1xuXG4gICAgICBjdHguc2V0TGluZURhc2godmFsdWVPckRlZmF1bHQobGVnZW5kSXRlbS5saW5lRGFzaCwgW10pKTtcblxuICAgICAgaWYgKGxhYmVsT3B0cy51c2VQb2ludFN0eWxlKSB7XG4gICAgICAgIC8vIFJlY2FsY3VsYXRlIHggYW5kIHkgZm9yIGRyYXdQb2ludCgpIGJlY2F1c2UgaXRzIGV4cGVjdGluZ1xuICAgICAgICAvLyB4IGFuZCB5IHRvIGJlIGNlbnRlciBvZiBmaWd1cmUgKGluc3RlYWQgb2YgdG9wIGxlZnQpXG4gICAgICAgIGNvbnN0IGRyYXdPcHRpb25zID0ge1xuICAgICAgICAgIHJhZGl1czogYm94SGVpZ2h0ICogTWF0aC5TUVJUMiAvIDIsXG4gICAgICAgICAgcG9pbnRTdHlsZTogbGVnZW5kSXRlbS5wb2ludFN0eWxlLFxuICAgICAgICAgIHJvdGF0aW9uOiBsZWdlbmRJdGVtLnJvdGF0aW9uLFxuICAgICAgICAgIGJvcmRlcldpZHRoOiBsaW5lV2lkdGhcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY2VudGVyWCA9IHJ0bEhlbHBlci54UGx1cyh4LCBib3hXaWR0aCAvIDIpO1xuICAgICAgICBjb25zdCBjZW50ZXJZID0geSArIGhhbGZGb250U2l6ZTtcblxuICAgICAgICAvLyBEcmF3IHBvaW50U3R5bGUgYXMgbGVnZW5kIHN5bWJvbFxuICAgICAgICBkcmF3UG9pbnRMZWdlbmQoY3R4LCBkcmF3T3B0aW9ucywgY2VudGVyWCwgY2VudGVyWSwgbGFiZWxPcHRzLnBvaW50U3R5bGVXaWR0aCAmJiBib3hXaWR0aCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBEcmF3IGJveCBhcyBsZWdlbmQgc3ltYm9sXG4gICAgICAgIC8vIEFkanVzdCBwb3NpdGlvbiB3aGVuIGJveEhlaWdodCA8IGZvbnRTaXplICh3YW50IGl0IGNlbnRlcmVkKVxuICAgICAgICBjb25zdCB5Qm94VG9wID0geSArIE1hdGgubWF4KChmb250U2l6ZSAtIGJveEhlaWdodCkgLyAyLCAwKTtcbiAgICAgICAgY29uc3QgeEJveExlZnQgPSBydGxIZWxwZXIubGVmdEZvckx0cih4LCBib3hXaWR0aCk7XG4gICAgICAgIGNvbnN0IGJvcmRlclJhZGl1cyA9IHRvVFJCTENvcm5lcnMobGVnZW5kSXRlbS5ib3JkZXJSYWRpdXMpO1xuXG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcblxuICAgICAgICBpZiAoT2JqZWN0LnZhbHVlcyhib3JkZXJSYWRpdXMpLnNvbWUodiA9PiB2ICE9PSAwKSkge1xuICAgICAgICAgIGFkZFJvdW5kZWRSZWN0UGF0aChjdHgsIHtcbiAgICAgICAgICAgIHg6IHhCb3hMZWZ0LFxuICAgICAgICAgICAgeTogeUJveFRvcCxcbiAgICAgICAgICAgIHc6IGJveFdpZHRoLFxuICAgICAgICAgICAgaDogYm94SGVpZ2h0LFxuICAgICAgICAgICAgcmFkaXVzOiBib3JkZXJSYWRpdXMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3R4LnJlY3QoeEJveExlZnQsIHlCb3hUb3AsIGJveFdpZHRoLCBib3hIZWlnaHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY3R4LmZpbGwoKTtcbiAgICAgICAgaWYgKGxpbmVXaWR0aCAhPT0gMCkge1xuICAgICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjdHgucmVzdG9yZSgpO1xuICAgIH07XG5cbiAgICBjb25zdCBmaWxsVGV4dCA9IGZ1bmN0aW9uKHgsIHksIGxlZ2VuZEl0ZW0pIHtcbiAgICAgIHJlbmRlclRleHQoY3R4LCBsZWdlbmRJdGVtLnRleHQsIHgsIHkgKyAoaXRlbUhlaWdodCAvIDIpLCBsYWJlbEZvbnQsIHtcbiAgICAgICAgc3RyaWtldGhyb3VnaDogbGVnZW5kSXRlbS5oaWRkZW4sXG4gICAgICAgIHRleHRBbGlnbjogcnRsSGVscGVyLnRleHRBbGlnbihsZWdlbmRJdGVtLnRleHRBbGlnbilcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvLyBIb3Jpem9udGFsXG4gICAgY29uc3QgaXNIb3Jpem9udGFsID0gdGhpcy5pc0hvcml6b250YWwoKTtcbiAgICBjb25zdCB0aXRsZUhlaWdodCA9IHRoaXMuX2NvbXB1dGVUaXRsZUhlaWdodCgpO1xuICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgIGN1cnNvciA9IHtcbiAgICAgICAgeDogX2FsaWduU3RhcnRFbmQoYWxpZ24sIHRoaXMubGVmdCArIHBhZGRpbmcsIHRoaXMucmlnaHQgLSBsaW5lV2lkdGhzWzBdKSxcbiAgICAgICAgeTogdGhpcy50b3AgKyBwYWRkaW5nICsgdGl0bGVIZWlnaHQsXG4gICAgICAgIGxpbmU6IDBcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnNvciA9IHtcbiAgICAgICAgeDogdGhpcy5sZWZ0ICsgcGFkZGluZyxcbiAgICAgICAgeTogX2FsaWduU3RhcnRFbmQoYWxpZ24sIHRoaXMudG9wICsgdGl0bGVIZWlnaHQgKyBwYWRkaW5nLCB0aGlzLmJvdHRvbSAtIGNvbHVtblNpemVzWzBdLmhlaWdodCksXG4gICAgICAgIGxpbmU6IDBcbiAgICAgIH07XG4gICAgfVxuXG4gICAgb3ZlcnJpZGVUZXh0RGlyZWN0aW9uKHRoaXMuY3R4LCBvcHRzLnRleHREaXJlY3Rpb24pO1xuXG4gICAgY29uc3QgbGluZUhlaWdodCA9IGl0ZW1IZWlnaHQgKyBwYWRkaW5nO1xuICAgIHRoaXMubGVnZW5kSXRlbXMuZm9yRWFjaCgobGVnZW5kSXRlbSwgaSkgPT4ge1xuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gbGVnZW5kSXRlbS5mb250Q29sb3I7IC8vIGZvciBzdHJpa2V0aHJvdWdoIGVmZmVjdFxuICAgICAgY3R4LmZpbGxTdHlsZSA9IGxlZ2VuZEl0ZW0uZm9udENvbG9yOyAvLyByZW5kZXIgaW4gY29ycmVjdCBjb2xvdXJcblxuICAgICAgY29uc3QgdGV4dFdpZHRoID0gY3R4Lm1lYXN1cmVUZXh0KGxlZ2VuZEl0ZW0udGV4dCkud2lkdGg7XG4gICAgICBjb25zdCB0ZXh0QWxpZ24gPSBydGxIZWxwZXIudGV4dEFsaWduKGxlZ2VuZEl0ZW0udGV4dEFsaWduIHx8IChsZWdlbmRJdGVtLnRleHRBbGlnbiA9IGxhYmVsT3B0cy50ZXh0QWxpZ24pKTtcbiAgICAgIGNvbnN0IHdpZHRoID0gYm94V2lkdGggKyBoYWxmRm9udFNpemUgKyB0ZXh0V2lkdGg7XG4gICAgICBsZXQgeCA9IGN1cnNvci54O1xuICAgICAgbGV0IHkgPSBjdXJzb3IueTtcblxuICAgICAgcnRsSGVscGVyLnNldFdpZHRoKHRoaXMud2lkdGgpO1xuXG4gICAgICBpZiAoaXNIb3Jpem9udGFsKSB7XG4gICAgICAgIGlmIChpID4gMCAmJiB4ICsgd2lkdGggKyBwYWRkaW5nID4gdGhpcy5yaWdodCkge1xuICAgICAgICAgIHkgPSBjdXJzb3IueSArPSBsaW5lSGVpZ2h0O1xuICAgICAgICAgIGN1cnNvci5saW5lKys7XG4gICAgICAgICAgeCA9IGN1cnNvci54ID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIHRoaXMubGVmdCArIHBhZGRpbmcsIHRoaXMucmlnaHQgLSBsaW5lV2lkdGhzW2N1cnNvci5saW5lXSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaSA+IDAgJiYgeSArIGxpbmVIZWlnaHQgPiB0aGlzLmJvdHRvbSkge1xuICAgICAgICB4ID0gY3Vyc29yLnggPSB4ICsgY29sdW1uU2l6ZXNbY3Vyc29yLmxpbmVdLndpZHRoICsgcGFkZGluZztcbiAgICAgICAgY3Vyc29yLmxpbmUrKztcbiAgICAgICAgeSA9IGN1cnNvci55ID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIHRoaXMudG9wICsgdGl0bGVIZWlnaHQgKyBwYWRkaW5nLCB0aGlzLmJvdHRvbSAtIGNvbHVtblNpemVzW2N1cnNvci5saW5lXS5oZWlnaHQpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWFsWCA9IHJ0bEhlbHBlci54KHgpO1xuXG4gICAgICBkcmF3TGVnZW5kQm94KHJlYWxYLCB5LCBsZWdlbmRJdGVtKTtcblxuICAgICAgeCA9IF90ZXh0WCh0ZXh0QWxpZ24sIHggKyBib3hXaWR0aCArIGhhbGZGb250U2l6ZSwgaXNIb3Jpem9udGFsID8geCArIHdpZHRoIDogdGhpcy5yaWdodCwgb3B0cy5ydGwpO1xuXG4gICAgICAvLyBGaWxsIHRoZSBhY3R1YWwgbGFiZWxcbiAgICAgIGZpbGxUZXh0KHJ0bEhlbHBlci54KHgpLCB5LCBsZWdlbmRJdGVtKTtcblxuICAgICAgaWYgKGlzSG9yaXpvbnRhbCkge1xuICAgICAgICBjdXJzb3IueCArPSB3aWR0aCArIHBhZGRpbmc7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsZWdlbmRJdGVtLnRleHQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnN0IGZvbnRMaW5lSGVpZ2h0ID0gbGFiZWxGb250LmxpbmVIZWlnaHQ7XG4gICAgICAgIGN1cnNvci55ICs9IGNhbGN1bGF0ZUxlZ2VuZEl0ZW1IZWlnaHQobGVnZW5kSXRlbSwgZm9udExpbmVIZWlnaHQpICsgcGFkZGluZztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnNvci55ICs9IGxpbmVIZWlnaHQ7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXN0b3JlVGV4dERpcmVjdGlvbih0aGlzLmN0eCwgb3B0cy50ZXh0RGlyZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBkcmF3VGl0bGUoKSB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB0aXRsZU9wdHMgPSBvcHRzLnRpdGxlO1xuICAgIGNvbnN0IHRpdGxlRm9udCA9IHRvRm9udCh0aXRsZU9wdHMuZm9udCk7XG4gICAgY29uc3QgdGl0bGVQYWRkaW5nID0gdG9QYWRkaW5nKHRpdGxlT3B0cy5wYWRkaW5nKTtcblxuICAgIGlmICghdGl0bGVPcHRzLmRpc3BsYXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBydGxIZWxwZXIgPSBnZXRSdGxBZGFwdGVyKG9wdHMucnRsLCB0aGlzLmxlZnQsIHRoaXMud2lkdGgpO1xuICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgIGNvbnN0IHBvc2l0aW9uID0gdGl0bGVPcHRzLnBvc2l0aW9uO1xuICAgIGNvbnN0IGhhbGZGb250U2l6ZSA9IHRpdGxlRm9udC5zaXplIC8gMjtcbiAgICBjb25zdCB0b3BQYWRkaW5nUGx1c0hhbGZGb250U2l6ZSA9IHRpdGxlUGFkZGluZy50b3AgKyBoYWxmRm9udFNpemU7XG4gICAgbGV0IHk7XG5cbiAgICAvLyBUaGVzZSBkZWZhdWx0cyBhcmUgdXNlZCB3aGVuIHRoZSBsZWdlbmQgaXMgdmVydGljYWwuXG4gICAgLy8gV2hlbiBob3Jpem9udGFsLCB0aGV5IGFyZSBjb21wdXRlZCBiZWxvdy5cbiAgICBsZXQgbGVmdCA9IHRoaXMubGVmdDtcbiAgICBsZXQgbWF4V2lkdGggPSB0aGlzLndpZHRoO1xuXG4gICAgaWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgIC8vIE1vdmUgbGVmdCAvIHJpZ2h0IHNvIHRoYXQgdGhlIHRpdGxlIGlzIGFib3ZlIHRoZSBsZWdlbmQgbGluZXNcbiAgICAgIG1heFdpZHRoID0gTWF0aC5tYXgoLi4udGhpcy5saW5lV2lkdGhzKTtcbiAgICAgIHkgPSB0aGlzLnRvcCArIHRvcFBhZGRpbmdQbHVzSGFsZkZvbnRTaXplO1xuICAgICAgbGVmdCA9IF9hbGlnblN0YXJ0RW5kKG9wdHMuYWxpZ24sIGxlZnQsIHRoaXMucmlnaHQgLSBtYXhXaWR0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE1vdmUgZG93biBzbyB0aGF0IHRoZSB0aXRsZSBpcyBhYm92ZSB0aGUgbGVnZW5kIHN0YWNrIGluIGV2ZXJ5IGFsaWdubWVudFxuICAgICAgY29uc3QgbWF4SGVpZ2h0ID0gdGhpcy5jb2x1bW5TaXplcy5yZWR1Y2UoKGFjYywgc2l6ZSkgPT4gTWF0aC5tYXgoYWNjLCBzaXplLmhlaWdodCksIDApO1xuICAgICAgeSA9IHRvcFBhZGRpbmdQbHVzSGFsZkZvbnRTaXplICsgX2FsaWduU3RhcnRFbmQob3B0cy5hbGlnbiwgdGhpcy50b3AsIHRoaXMuYm90dG9tIC0gbWF4SGVpZ2h0IC0gb3B0cy5sYWJlbHMucGFkZGluZyAtIHRoaXMuX2NvbXB1dGVUaXRsZUhlaWdodCgpKTtcbiAgICB9XG5cbiAgICAvLyBOb3cgdGhhdCB3ZSBrbm93IHRoZSBsZWZ0IGVkZ2Ugb2YgdGhlIGlubmVyIGxlZ2VuZCBib3gsIGNvbXB1dGUgdGhlIGNvcnJlY3RcbiAgICAvLyBYIGNvb3JkaW5hdGUgZnJvbSB0aGUgdGl0bGUgYWxpZ25tZW50XG4gICAgY29uc3QgeCA9IF9hbGlnblN0YXJ0RW5kKHBvc2l0aW9uLCBsZWZ0LCBsZWZ0ICsgbWF4V2lkdGgpO1xuXG4gICAgLy8gQ2FudmFzIHNldHVwXG4gICAgY3R4LnRleHRBbGlnbiA9IHJ0bEhlbHBlci50ZXh0QWxpZ24oX3RvTGVmdFJpZ2h0Q2VudGVyKHBvc2l0aW9uKSk7XG4gICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuICAgIGN0eC5zdHJva2VTdHlsZSA9IHRpdGxlT3B0cy5jb2xvcjtcbiAgICBjdHguZmlsbFN0eWxlID0gdGl0bGVPcHRzLmNvbG9yO1xuICAgIGN0eC5mb250ID0gdGl0bGVGb250LnN0cmluZztcblxuICAgIHJlbmRlclRleHQoY3R4LCB0aXRsZU9wdHMudGV4dCwgeCwgeSwgdGl0bGVGb250KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2NvbXB1dGVUaXRsZUhlaWdodCgpIHtcbiAgICBjb25zdCB0aXRsZU9wdHMgPSB0aGlzLm9wdGlvbnMudGl0bGU7XG4gICAgY29uc3QgdGl0bGVGb250ID0gdG9Gb250KHRpdGxlT3B0cy5mb250KTtcbiAgICBjb25zdCB0aXRsZVBhZGRpbmcgPSB0b1BhZGRpbmcodGl0bGVPcHRzLnBhZGRpbmcpO1xuICAgIHJldHVybiB0aXRsZU9wdHMuZGlzcGxheSA/IHRpdGxlRm9udC5saW5lSGVpZ2h0ICsgdGl0bGVQYWRkaW5nLmhlaWdodCA6IDA7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRMZWdlbmRJdGVtQXQoeCwgeSkge1xuICAgIGxldCBpLCBoaXRCb3gsIGxoO1xuXG4gICAgaWYgKF9pc0JldHdlZW4oeCwgdGhpcy5sZWZ0LCB0aGlzLnJpZ2h0KVxuICAgICAgJiYgX2lzQmV0d2Vlbih5LCB0aGlzLnRvcCwgdGhpcy5ib3R0b20pKSB7XG4gICAgICAvLyBTZWUgaWYgd2UgYXJlIHRvdWNoaW5nIG9uZSBvZiB0aGUgZGF0YXNldCBib3hlc1xuICAgICAgbGggPSB0aGlzLmxlZ2VuZEhpdEJveGVzO1xuICAgICAgZm9yIChpID0gMDsgaSA8IGxoLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGhpdEJveCA9IGxoW2ldO1xuXG4gICAgICAgIGlmIChfaXNCZXR3ZWVuKHgsIGhpdEJveC5sZWZ0LCBoaXRCb3gubGVmdCArIGhpdEJveC53aWR0aClcbiAgICAgICAgICAmJiBfaXNCZXR3ZWVuKHksIGhpdEJveC50b3AsIGhpdEJveC50b3AgKyBoaXRCb3guaGVpZ2h0KSkge1xuICAgICAgICAgIC8vIFRvdWNoaW5nIGFuIGVsZW1lbnRcbiAgICAgICAgICByZXR1cm4gdGhpcy5sZWdlbmRJdGVtc1tpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG5cdCAqIEhhbmRsZSBhbiBldmVudFxuXHQgKiBAcGFyYW0ge0NoYXJ0RXZlbnR9IGUgLSBUaGUgZXZlbnQgdG8gaGFuZGxlXG5cdCAqL1xuICBoYW5kbGVFdmVudChlKSB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcbiAgICBpZiAoIWlzTGlzdGVuZWQoZS50eXBlLCBvcHRzKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENoYXJ0IGV2ZW50IGFscmVhZHkgaGFzIHJlbGF0aXZlIHBvc2l0aW9uIGluIGl0XG4gICAgY29uc3QgaG92ZXJlZEl0ZW0gPSB0aGlzLl9nZXRMZWdlbmRJdGVtQXQoZS54LCBlLnkpO1xuXG4gICAgaWYgKGUudHlwZSA9PT0gJ21vdXNlbW92ZScgfHwgZS50eXBlID09PSAnbW91c2VvdXQnKSB7XG4gICAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMuX2hvdmVyZWRJdGVtO1xuICAgICAgY29uc3Qgc2FtZUl0ZW0gPSBpdGVtc0VxdWFsKHByZXZpb3VzLCBob3ZlcmVkSXRlbSk7XG4gICAgICBpZiAocHJldmlvdXMgJiYgIXNhbWVJdGVtKSB7XG4gICAgICAgIGNhbGwob3B0cy5vbkxlYXZlLCBbZSwgcHJldmlvdXMsIHRoaXNdLCB0aGlzKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5faG92ZXJlZEl0ZW0gPSBob3ZlcmVkSXRlbTtcblxuICAgICAgaWYgKGhvdmVyZWRJdGVtICYmICFzYW1lSXRlbSkge1xuICAgICAgICBjYWxsKG9wdHMub25Ib3ZlciwgW2UsIGhvdmVyZWRJdGVtLCB0aGlzXSwgdGhpcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChob3ZlcmVkSXRlbSkge1xuICAgICAgY2FsbChvcHRzLm9uQ2xpY2ssIFtlLCBob3ZlcmVkSXRlbSwgdGhpc10sIHRoaXMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVJdGVtU2l6ZShib3hXaWR0aCwgbGFiZWxGb250LCBjdHgsIGxlZ2VuZEl0ZW0sIF9pdGVtSGVpZ2h0KSB7XG4gIGNvbnN0IGl0ZW1XaWR0aCA9IGNhbGN1bGF0ZUl0ZW1XaWR0aChsZWdlbmRJdGVtLCBib3hXaWR0aCwgbGFiZWxGb250LCBjdHgpO1xuICBjb25zdCBpdGVtSGVpZ2h0ID0gY2FsY3VsYXRlSXRlbUhlaWdodChfaXRlbUhlaWdodCwgbGVnZW5kSXRlbSwgbGFiZWxGb250LmxpbmVIZWlnaHQpO1xuICByZXR1cm4ge2l0ZW1XaWR0aCwgaXRlbUhlaWdodH07XG59XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZUl0ZW1XaWR0aChsZWdlbmRJdGVtLCBib3hXaWR0aCwgbGFiZWxGb250LCBjdHgpIHtcbiAgbGV0IGxlZ2VuZEl0ZW1UZXh0ID0gbGVnZW5kSXRlbS50ZXh0O1xuICBpZiAobGVnZW5kSXRlbVRleHQgJiYgdHlwZW9mIGxlZ2VuZEl0ZW1UZXh0ICE9PSAnc3RyaW5nJykge1xuICAgIGxlZ2VuZEl0ZW1UZXh0ID0gbGVnZW5kSXRlbVRleHQucmVkdWNlKChhLCBiKSA9PiBhLmxlbmd0aCA+IGIubGVuZ3RoID8gYSA6IGIpO1xuICB9XG4gIHJldHVybiBib3hXaWR0aCArIChsYWJlbEZvbnQuc2l6ZSAvIDIpICsgY3R4Lm1lYXN1cmVUZXh0KGxlZ2VuZEl0ZW1UZXh0KS53aWR0aDtcbn1cblxuZnVuY3Rpb24gY2FsY3VsYXRlSXRlbUhlaWdodChfaXRlbUhlaWdodCwgbGVnZW5kSXRlbSwgZm9udExpbmVIZWlnaHQpIHtcbiAgbGV0IGl0ZW1IZWlnaHQgPSBfaXRlbUhlaWdodDtcbiAgaWYgKHR5cGVvZiBsZWdlbmRJdGVtLnRleHQgIT09ICdzdHJpbmcnKSB7XG4gICAgaXRlbUhlaWdodCA9IGNhbGN1bGF0ZUxlZ2VuZEl0ZW1IZWlnaHQobGVnZW5kSXRlbSwgZm9udExpbmVIZWlnaHQpO1xuICB9XG4gIHJldHVybiBpdGVtSGVpZ2h0O1xufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVMZWdlbmRJdGVtSGVpZ2h0KGxlZ2VuZEl0ZW0sIGZvbnRMaW5lSGVpZ2h0KSB7XG4gIGNvbnN0IGxhYmVsSGVpZ2h0ID0gbGVnZW5kSXRlbS50ZXh0ID8gbGVnZW5kSXRlbS50ZXh0Lmxlbmd0aCA6IDA7XG4gIHJldHVybiBmb250TGluZUhlaWdodCAqIGxhYmVsSGVpZ2h0O1xufVxuXG5mdW5jdGlvbiBpc0xpc3RlbmVkKHR5cGUsIG9wdHMpIHtcbiAgaWYgKCh0eXBlID09PSAnbW91c2Vtb3ZlJyB8fCB0eXBlID09PSAnbW91c2VvdXQnKSAmJiAob3B0cy5vbkhvdmVyIHx8IG9wdHMub25MZWF2ZSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAob3B0cy5vbkNsaWNrICYmICh0eXBlID09PSAnY2xpY2snIHx8IHR5cGUgPT09ICdtb3VzZXVwJykpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgaWQ6ICdsZWdlbmQnLFxuXG4gIC8qKlxuXHQgKiBGb3IgdGVzdHNcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9lbGVtZW50OiBMZWdlbmQsXG5cbiAgc3RhcnQoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgY29uc3QgbGVnZW5kID0gY2hhcnQubGVnZW5kID0gbmV3IExlZ2VuZCh7Y3R4OiBjaGFydC5jdHgsIG9wdGlvbnMsIGNoYXJ0fSk7XG4gICAgbGF5b3V0cy5jb25maWd1cmUoY2hhcnQsIGxlZ2VuZCwgb3B0aW9ucyk7XG4gICAgbGF5b3V0cy5hZGRCb3goY2hhcnQsIGxlZ2VuZCk7XG4gIH0sXG5cbiAgc3RvcChjaGFydCkge1xuICAgIGxheW91dHMucmVtb3ZlQm94KGNoYXJ0LCBjaGFydC5sZWdlbmQpO1xuICAgIGRlbGV0ZSBjaGFydC5sZWdlbmQ7XG4gIH0sXG5cbiAgLy8gRHVyaW5nIHRoZSBiZWZvcmVVcGRhdGUgc3RlcCwgdGhlIGxheW91dCBjb25maWd1cmF0aW9uIG5lZWRzIHRvIHJ1blxuICAvLyBUaGlzIGVuc3VyZXMgdGhhdCBpZiB0aGUgbGVnZW5kIHBvc2l0aW9uIGNoYW5nZXMgKHZpYSBhbiBvcHRpb24gdXBkYXRlKVxuICAvLyB0aGUgbGF5b3V0IHN5c3RlbSByZXNwZWN0cyB0aGUgY2hhbmdlLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzc1MjdcbiAgYmVmb3JlVXBkYXRlKGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgIGNvbnN0IGxlZ2VuZCA9IGNoYXJ0LmxlZ2VuZDtcbiAgICBsYXlvdXRzLmNvbmZpZ3VyZShjaGFydCwgbGVnZW5kLCBvcHRpb25zKTtcbiAgICBsZWdlbmQub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH0sXG5cbiAgLy8gVGhlIGxhYmVscyBuZWVkIHRvIGJlIGJ1aWx0IGFmdGVyIGRhdGFzZXRzIGFyZSB1cGRhdGVkIHRvIGVuc3VyZSB0aGF0IGNvbG9yc1xuICAvLyBhbmQgb3RoZXIgc3R5bGluZyBhcmUgY29ycmVjdC4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy82OTY4XG4gIGFmdGVyVXBkYXRlKGNoYXJ0KSB7XG4gICAgY29uc3QgbGVnZW5kID0gY2hhcnQubGVnZW5kO1xuICAgIGxlZ2VuZC5idWlsZExhYmVscygpO1xuICAgIGxlZ2VuZC5hZGp1c3RIaXRCb3hlcygpO1xuICB9LFxuXG5cbiAgYWZ0ZXJFdmVudChjaGFydCwgYXJncykge1xuICAgIGlmICghYXJncy5yZXBsYXkpIHtcbiAgICAgIGNoYXJ0LmxlZ2VuZC5oYW5kbGVFdmVudChhcmdzLmV2ZW50KTtcbiAgICB9XG4gIH0sXG5cbiAgZGVmYXVsdHM6IHtcbiAgICBkaXNwbGF5OiB0cnVlLFxuICAgIHBvc2l0aW9uOiAndG9wJyxcbiAgICBhbGlnbjogJ2NlbnRlcicsXG4gICAgZnVsbFNpemU6IHRydWUsXG4gICAgcmV2ZXJzZTogZmFsc2UsXG4gICAgd2VpZ2h0OiAxMDAwLFxuXG4gICAgLy8gYSBjYWxsYmFjayB0aGF0IHdpbGwgaGFuZGxlXG4gICAgb25DbGljayhlLCBsZWdlbmRJdGVtLCBsZWdlbmQpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gbGVnZW5kSXRlbS5kYXRhc2V0SW5kZXg7XG4gICAgICBjb25zdCBjaSA9IGxlZ2VuZC5jaGFydDtcbiAgICAgIGlmIChjaS5pc0RhdGFzZXRWaXNpYmxlKGluZGV4KSkge1xuICAgICAgICBjaS5oaWRlKGluZGV4KTtcbiAgICAgICAgbGVnZW5kSXRlbS5oaWRkZW4gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2kuc2hvdyhpbmRleCk7XG4gICAgICAgIGxlZ2VuZEl0ZW0uaGlkZGVuID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSxcblxuICAgIG9uSG92ZXI6IG51bGwsXG4gICAgb25MZWF2ZTogbnVsbCxcblxuICAgIGxhYmVsczoge1xuICAgICAgY29sb3I6IChjdHgpID0+IGN0eC5jaGFydC5vcHRpb25zLmNvbG9yLFxuICAgICAgYm94V2lkdGg6IDQwLFxuICAgICAgcGFkZGluZzogMTAsXG4gICAgICAvLyBHZW5lcmF0ZXMgbGFiZWxzIHNob3duIGluIHRoZSBsZWdlbmRcbiAgICAgIC8vIFZhbGlkIHByb3BlcnRpZXMgdG8gcmV0dXJuOlxuICAgICAgLy8gdGV4dCA6IHRleHQgdG8gZGlzcGxheVxuICAgICAgLy8gZmlsbFN0eWxlIDogZmlsbCBvZiBjb2xvdXJlZCBib3hcbiAgICAgIC8vIHN0cm9rZVN0eWxlOiBzdHJva2Ugb2YgY29sb3VyZWQgYm94XG4gICAgICAvLyBoaWRkZW4gOiBpZiB0aGlzIGxlZ2VuZCBpdGVtIHJlZmVycyB0byBhIGhpZGRlbiBpdGVtXG4gICAgICAvLyBsaW5lQ2FwIDogY2FwIHN0eWxlIGZvciBsaW5lXG4gICAgICAvLyBsaW5lRGFzaFxuICAgICAgLy8gbGluZURhc2hPZmZzZXQgOlxuICAgICAgLy8gbGluZUpvaW4gOlxuICAgICAgLy8gbGluZVdpZHRoIDpcbiAgICAgIGdlbmVyYXRlTGFiZWxzKGNoYXJ0KSB7XG4gICAgICAgIGNvbnN0IGRhdGFzZXRzID0gY2hhcnQuZGF0YS5kYXRhc2V0cztcbiAgICAgICAgY29uc3Qge2xhYmVsczoge3VzZVBvaW50U3R5bGUsIHBvaW50U3R5bGUsIHRleHRBbGlnbiwgY29sb3IsIHVzZUJvcmRlclJhZGl1cywgYm9yZGVyUmFkaXVzfX0gPSBjaGFydC5sZWdlbmQub3B0aW9ucztcblxuICAgICAgICByZXR1cm4gY2hhcnQuX2dldFNvcnRlZERhdGFzZXRNZXRhcygpLm1hcCgobWV0YSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHN0eWxlID0gbWV0YS5jb250cm9sbGVyLmdldFN0eWxlKHVzZVBvaW50U3R5bGUgPyAwIDogdW5kZWZpbmVkKTtcbiAgICAgICAgICBjb25zdCBib3JkZXJXaWR0aCA9IHRvUGFkZGluZyhzdHlsZS5ib3JkZXJXaWR0aCk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGV4dDogZGF0YXNldHNbbWV0YS5pbmRleF0ubGFiZWwsXG4gICAgICAgICAgICBmaWxsU3R5bGU6IHN0eWxlLmJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgIGZvbnRDb2xvcjogY29sb3IsXG4gICAgICAgICAgICBoaWRkZW46ICFtZXRhLnZpc2libGUsXG4gICAgICAgICAgICBsaW5lQ2FwOiBzdHlsZS5ib3JkZXJDYXBTdHlsZSxcbiAgICAgICAgICAgIGxpbmVEYXNoOiBzdHlsZS5ib3JkZXJEYXNoLFxuICAgICAgICAgICAgbGluZURhc2hPZmZzZXQ6IHN0eWxlLmJvcmRlckRhc2hPZmZzZXQsXG4gICAgICAgICAgICBsaW5lSm9pbjogc3R5bGUuYm9yZGVySm9pblN0eWxlLFxuICAgICAgICAgICAgbGluZVdpZHRoOiAoYm9yZGVyV2lkdGgud2lkdGggKyBib3JkZXJXaWR0aC5oZWlnaHQpIC8gNCxcbiAgICAgICAgICAgIHN0cm9rZVN0eWxlOiBzdHlsZS5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgIHBvaW50U3R5bGU6IHBvaW50U3R5bGUgfHwgc3R5bGUucG9pbnRTdHlsZSxcbiAgICAgICAgICAgIHJvdGF0aW9uOiBzdHlsZS5yb3RhdGlvbixcbiAgICAgICAgICAgIHRleHRBbGlnbjogdGV4dEFsaWduIHx8IHN0eWxlLnRleHRBbGlnbixcbiAgICAgICAgICAgIGJvcmRlclJhZGl1czogdXNlQm9yZGVyUmFkaXVzICYmIChib3JkZXJSYWRpdXMgfHwgc3R5bGUuYm9yZGVyUmFkaXVzKSxcblxuICAgICAgICAgICAgLy8gQmVsb3cgaXMgZXh0cmEgZGF0YSB1c2VkIGZvciB0b2dnbGluZyB0aGUgZGF0YXNldHNcbiAgICAgICAgICAgIGRhdGFzZXRJbmRleDogbWV0YS5pbmRleFxuICAgICAgICAgIH07XG4gICAgICAgIH0sIHRoaXMpO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICB0aXRsZToge1xuICAgICAgY29sb3I6IChjdHgpID0+IGN0eC5jaGFydC5vcHRpb25zLmNvbG9yLFxuICAgICAgZGlzcGxheTogZmFsc2UsXG4gICAgICBwb3NpdGlvbjogJ2NlbnRlcicsXG4gICAgICB0ZXh0OiAnJyxcbiAgICB9XG4gIH0sXG5cbiAgZGVzY3JpcHRvcnM6IHtcbiAgICBfc2NyaXB0YWJsZTogKG5hbWUpID0+ICFuYW1lLnN0YXJ0c1dpdGgoJ29uJyksXG4gICAgbGFiZWxzOiB7XG4gICAgICBfc2NyaXB0YWJsZTogKG5hbWUpID0+ICFbJ2dlbmVyYXRlTGFiZWxzJywgJ2ZpbHRlcicsICdzb3J0J10uaW5jbHVkZXMobmFtZSksXG4gICAgfVxuICB9LFxufTtcbiIsICJpbXBvcnQgRWxlbWVudCBmcm9tICcuLi9jb3JlL2NvcmUuZWxlbWVudC5qcyc7XG5pbXBvcnQgbGF5b3V0cyBmcm9tICcuLi9jb3JlL2NvcmUubGF5b3V0cy5qcyc7XG5pbXBvcnQge1BJLCBpc0FycmF5LCB0b1BhZGRpbmcsIHRvRm9udH0gZnJvbSAnLi4vaGVscGVycy9pbmRleC5qcyc7XG5pbXBvcnQge190b0xlZnRSaWdodENlbnRlciwgX2FsaWduU3RhcnRFbmR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5leHRyYXMuanMnO1xuaW1wb3J0IHtyZW5kZXJUZXh0fSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY2FudmFzLmpzJztcblxuZXhwb3J0IGNsYXNzIFRpdGxlIGV4dGVuZHMgRWxlbWVudCB7XG4gIC8qKlxuXHQgKiBAcGFyYW0ge3sgY3R4OiBhbnk7IG9wdGlvbnM6IGFueTsgY2hhcnQ6IGFueTsgfX0gY29uZmlnXG5cdCAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWcpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5jaGFydCA9IGNvbmZpZy5jaGFydDtcbiAgICB0aGlzLm9wdGlvbnMgPSBjb25maWcub3B0aW9ucztcbiAgICB0aGlzLmN0eCA9IGNvbmZpZy5jdHg7XG4gICAgdGhpcy5fcGFkZGluZyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnRvcCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmJvdHRvbSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmxlZnQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5yaWdodCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLndpZHRoID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaGVpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMucG9zaXRpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy53ZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5mdWxsU2l6ZSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHVwZGF0ZShtYXhXaWR0aCwgbWF4SGVpZ2h0KSB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcblxuICAgIHRoaXMubGVmdCA9IDA7XG4gICAgdGhpcy50b3AgPSAwO1xuXG4gICAgaWYgKCFvcHRzLmRpc3BsYXkpIHtcbiAgICAgIHRoaXMud2lkdGggPSB0aGlzLmhlaWdodCA9IHRoaXMucmlnaHQgPSB0aGlzLmJvdHRvbSA9IDA7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy53aWR0aCA9IHRoaXMucmlnaHQgPSBtYXhXaWR0aDtcbiAgICB0aGlzLmhlaWdodCA9IHRoaXMuYm90dG9tID0gbWF4SGVpZ2h0O1xuXG4gICAgY29uc3QgbGluZUNvdW50ID0gaXNBcnJheShvcHRzLnRleHQpID8gb3B0cy50ZXh0Lmxlbmd0aCA6IDE7XG4gICAgdGhpcy5fcGFkZGluZyA9IHRvUGFkZGluZyhvcHRzLnBhZGRpbmcpO1xuICAgIGNvbnN0IHRleHRTaXplID0gbGluZUNvdW50ICogdG9Gb250KG9wdHMuZm9udCkubGluZUhlaWdodCArIHRoaXMuX3BhZGRpbmcuaGVpZ2h0O1xuXG4gICAgaWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcbiAgICAgIHRoaXMuaGVpZ2h0ID0gdGV4dFNpemU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMud2lkdGggPSB0ZXh0U2l6ZTtcbiAgICB9XG4gIH1cblxuICBpc0hvcml6b250YWwoKSB7XG4gICAgY29uc3QgcG9zID0gdGhpcy5vcHRpb25zLnBvc2l0aW9uO1xuICAgIHJldHVybiBwb3MgPT09ICd0b3AnIHx8IHBvcyA9PT0gJ2JvdHRvbSc7XG4gIH1cblxuICBfZHJhd0FyZ3Mob2Zmc2V0KSB7XG4gICAgY29uc3Qge3RvcCwgbGVmdCwgYm90dG9tLCByaWdodCwgb3B0aW9uc30gPSB0aGlzO1xuICAgIGNvbnN0IGFsaWduID0gb3B0aW9ucy5hbGlnbjtcbiAgICBsZXQgcm90YXRpb24gPSAwO1xuICAgIGxldCBtYXhXaWR0aCwgdGl0bGVYLCB0aXRsZVk7XG5cbiAgICBpZiAodGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgdGl0bGVYID0gX2FsaWduU3RhcnRFbmQoYWxpZ24sIGxlZnQsIHJpZ2h0KTtcbiAgICAgIHRpdGxlWSA9IHRvcCArIG9mZnNldDtcbiAgICAgIG1heFdpZHRoID0gcmlnaHQgLSBsZWZ0O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAob3B0aW9ucy5wb3NpdGlvbiA9PT0gJ2xlZnQnKSB7XG4gICAgICAgIHRpdGxlWCA9IGxlZnQgKyBvZmZzZXQ7XG4gICAgICAgIHRpdGxlWSA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCBib3R0b20sIHRvcCk7XG4gICAgICAgIHJvdGF0aW9uID0gUEkgKiAtMC41O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGl0bGVYID0gcmlnaHQgLSBvZmZzZXQ7XG4gICAgICAgIHRpdGxlWSA9IF9hbGlnblN0YXJ0RW5kKGFsaWduLCB0b3AsIGJvdHRvbSk7XG4gICAgICAgIHJvdGF0aW9uID0gUEkgKiAwLjU7XG4gICAgICB9XG4gICAgICBtYXhXaWR0aCA9IGJvdHRvbSAtIHRvcDtcbiAgICB9XG4gICAgcmV0dXJuIHt0aXRsZVgsIHRpdGxlWSwgbWF4V2lkdGgsIHJvdGF0aW9ufTtcbiAgfVxuXG4gIGRyYXcoKSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcblxuICAgIGlmICghb3B0cy5kaXNwbGF5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZm9udE9wdHMgPSB0b0ZvbnQob3B0cy5mb250KTtcbiAgICBjb25zdCBsaW5lSGVpZ2h0ID0gZm9udE9wdHMubGluZUhlaWdodDtcbiAgICBjb25zdCBvZmZzZXQgPSBsaW5lSGVpZ2h0IC8gMiArIHRoaXMuX3BhZGRpbmcudG9wO1xuICAgIGNvbnN0IHt0aXRsZVgsIHRpdGxlWSwgbWF4V2lkdGgsIHJvdGF0aW9ufSA9IHRoaXMuX2RyYXdBcmdzKG9mZnNldCk7XG5cbiAgICByZW5kZXJUZXh0KGN0eCwgb3B0cy50ZXh0LCAwLCAwLCBmb250T3B0cywge1xuICAgICAgY29sb3I6IG9wdHMuY29sb3IsXG4gICAgICBtYXhXaWR0aCxcbiAgICAgIHJvdGF0aW9uLFxuICAgICAgdGV4dEFsaWduOiBfdG9MZWZ0UmlnaHRDZW50ZXIob3B0cy5hbGlnbiksXG4gICAgICB0ZXh0QmFzZWxpbmU6ICdtaWRkbGUnLFxuICAgICAgdHJhbnNsYXRpb246IFt0aXRsZVgsIHRpdGxlWV0sXG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlVGl0bGUoY2hhcnQsIHRpdGxlT3B0cykge1xuICBjb25zdCB0aXRsZSA9IG5ldyBUaXRsZSh7XG4gICAgY3R4OiBjaGFydC5jdHgsXG4gICAgb3B0aW9uczogdGl0bGVPcHRzLFxuICAgIGNoYXJ0XG4gIH0pO1xuXG4gIGxheW91dHMuY29uZmlndXJlKGNoYXJ0LCB0aXRsZSwgdGl0bGVPcHRzKTtcbiAgbGF5b3V0cy5hZGRCb3goY2hhcnQsIHRpdGxlKTtcbiAgY2hhcnQudGl0bGVCbG9jayA9IHRpdGxlO1xufVxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGlkOiAndGl0bGUnLFxuXG4gIC8qKlxuXHQgKiBGb3IgdGVzdHNcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9lbGVtZW50OiBUaXRsZSxcblxuICBzdGFydChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICBjcmVhdGVUaXRsZShjaGFydCwgb3B0aW9ucyk7XG4gIH0sXG5cbiAgc3RvcChjaGFydCkge1xuICAgIGNvbnN0IHRpdGxlQmxvY2sgPSBjaGFydC50aXRsZUJsb2NrO1xuICAgIGxheW91dHMucmVtb3ZlQm94KGNoYXJ0LCB0aXRsZUJsb2NrKTtcbiAgICBkZWxldGUgY2hhcnQudGl0bGVCbG9jaztcbiAgfSxcblxuICBiZWZvcmVVcGRhdGUoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgY29uc3QgdGl0bGUgPSBjaGFydC50aXRsZUJsb2NrO1xuICAgIGxheW91dHMuY29uZmlndXJlKGNoYXJ0LCB0aXRsZSwgb3B0aW9ucyk7XG4gICAgdGl0bGUub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH0sXG5cbiAgZGVmYXVsdHM6IHtcbiAgICBhbGlnbjogJ2NlbnRlcicsXG4gICAgZGlzcGxheTogZmFsc2UsXG4gICAgZm9udDoge1xuICAgICAgd2VpZ2h0OiAnYm9sZCcsXG4gICAgfSxcbiAgICBmdWxsU2l6ZTogdHJ1ZSxcbiAgICBwYWRkaW5nOiAxMCxcbiAgICBwb3NpdGlvbjogJ3RvcCcsXG4gICAgdGV4dDogJycsXG4gICAgd2VpZ2h0OiAyMDAwICAgICAgICAgLy8gYnkgZGVmYXVsdCBncmVhdGVyIHRoYW4gbGVnZW5kICgxMDAwKSB0byBiZSBhYm92ZVxuICB9LFxuXG4gIGRlZmF1bHRSb3V0ZXM6IHtcbiAgICBjb2xvcjogJ2NvbG9yJ1xuICB9LFxuXG4gIGRlc2NyaXB0b3JzOiB7XG4gICAgX3NjcmlwdGFibGU6IHRydWUsXG4gICAgX2luZGV4YWJsZTogZmFsc2UsXG4gIH0sXG59O1xuIiwgImltcG9ydCB7VGl0bGV9IGZyb20gJy4vcGx1Z2luLnRpdGxlLmpzJztcbmltcG9ydCBsYXlvdXRzIGZyb20gJy4uL2NvcmUvY29yZS5sYXlvdXRzLmpzJztcblxuY29uc3QgbWFwID0gbmV3IFdlYWtNYXAoKTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBpZDogJ3N1YnRpdGxlJyxcblxuICBzdGFydChjaGFydCwgX2FyZ3MsIG9wdGlvbnMpIHtcbiAgICBjb25zdCB0aXRsZSA9IG5ldyBUaXRsZSh7XG4gICAgICBjdHg6IGNoYXJ0LmN0eCxcbiAgICAgIG9wdGlvbnMsXG4gICAgICBjaGFydFxuICAgIH0pO1xuXG4gICAgbGF5b3V0cy5jb25maWd1cmUoY2hhcnQsIHRpdGxlLCBvcHRpb25zKTtcbiAgICBsYXlvdXRzLmFkZEJveChjaGFydCwgdGl0bGUpO1xuICAgIG1hcC5zZXQoY2hhcnQsIHRpdGxlKTtcbiAgfSxcblxuICBzdG9wKGNoYXJ0KSB7XG4gICAgbGF5b3V0cy5yZW1vdmVCb3goY2hhcnQsIG1hcC5nZXQoY2hhcnQpKTtcbiAgICBtYXAuZGVsZXRlKGNoYXJ0KTtcbiAgfSxcblxuICBiZWZvcmVVcGRhdGUoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgY29uc3QgdGl0bGUgPSBtYXAuZ2V0KGNoYXJ0KTtcbiAgICBsYXlvdXRzLmNvbmZpZ3VyZShjaGFydCwgdGl0bGUsIG9wdGlvbnMpO1xuICAgIHRpdGxlLm9wdGlvbnMgPSBvcHRpb25zO1xuICB9LFxuXG4gIGRlZmF1bHRzOiB7XG4gICAgYWxpZ246ICdjZW50ZXInLFxuICAgIGRpc3BsYXk6IGZhbHNlLFxuICAgIGZvbnQ6IHtcbiAgICAgIHdlaWdodDogJ25vcm1hbCcsXG4gICAgfSxcbiAgICBmdWxsU2l6ZTogdHJ1ZSxcbiAgICBwYWRkaW5nOiAwLFxuICAgIHBvc2l0aW9uOiAndG9wJyxcbiAgICB0ZXh0OiAnJyxcbiAgICB3ZWlnaHQ6IDE1MDAgICAgICAgICAvLyBieSBkZWZhdWx0IGdyZWF0ZXIgdGhhbiBsZWdlbmQgKDEwMDApIGFuZCBzbWFsbGVyIHRoYW4gdGl0bGUgKDIwMDApXG4gIH0sXG5cbiAgZGVmYXVsdFJvdXRlczoge1xuICAgIGNvbG9yOiAnY29sb3InXG4gIH0sXG5cbiAgZGVzY3JpcHRvcnM6IHtcbiAgICBfc2NyaXB0YWJsZTogdHJ1ZSxcbiAgICBfaW5kZXhhYmxlOiBmYWxzZSxcbiAgfSxcbn07XG4iLCAiaW1wb3J0IEFuaW1hdGlvbnMgZnJvbSAnLi4vY29yZS9jb3JlLmFuaW1hdGlvbnMuanMnO1xuaW1wb3J0IEVsZW1lbnQgZnJvbSAnLi4vY29yZS9jb3JlLmVsZW1lbnQuanMnO1xuaW1wb3J0IHthZGRSb3VuZGVkUmVjdFBhdGh9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jYW52YXMuanMnO1xuaW1wb3J0IHtlYWNoLCBub29wLCBpc051bGxPclVuZGVmLCBpc0FycmF5LCBfZWxlbWVudHNFcXVhbCwgaXNPYmplY3R9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7dG9Gb250LCB0b1BhZGRpbmcsIHRvVFJCTENvcm5lcnN9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5vcHRpb25zLmpzJztcbmltcG9ydCB7Z2V0UnRsQWRhcHRlciwgb3ZlcnJpZGVUZXh0RGlyZWN0aW9uLCByZXN0b3JlVGV4dERpcmVjdGlvbn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLnJ0bC5qcyc7XG5pbXBvcnQge2Rpc3RhbmNlQmV0d2VlblBvaW50cywgX2xpbWl0VmFsdWV9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCB7Y3JlYXRlQ29udGV4dCwgZHJhd1BvaW50fSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vcGxhdGZvcm0vcGxhdGZvcm0uYmFzZS5qcycpLkNoYXJ0IH0gQ2hhcnRcbiAqIEB0eXBlZGVmIHsgaW1wb3J0KCcuLi90eXBlcy9pbmRleC5qcycpLkNoYXJ0RXZlbnQgfSBDaGFydEV2ZW50XG4gKiBAdHlwZWRlZiB7IGltcG9ydCgnLi4vdHlwZXMvaW5kZXguanMnKS5BY3RpdmVFbGVtZW50IH0gQWN0aXZlRWxlbWVudFxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL2NvcmUvY29yZS5pbnRlcmFjdGlvbi5qcycpLkludGVyYWN0aW9uSXRlbSB9IEludGVyYWN0aW9uSXRlbVxuICovXG5cbmNvbnN0IHBvc2l0aW9uZXJzID0ge1xuICAvKipcblx0ICogQXZlcmFnZSBtb2RlIHBsYWNlcyB0aGUgdG9vbHRpcCBhdCB0aGUgYXZlcmFnZSBwb3NpdGlvbiBvZiB0aGUgZWxlbWVudHMgc2hvd25cblx0ICovXG4gIGF2ZXJhZ2UoaXRlbXMpIHtcbiAgICBpZiAoIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGxldCBpLCBsZW47XG4gICAgbGV0IHhTZXQgPSBuZXcgU2V0KCk7XG4gICAgbGV0IHkgPSAwO1xuICAgIGxldCBjb3VudCA9IDA7XG5cbiAgICBmb3IgKGkgPSAwLCBsZW4gPSBpdGVtcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY29uc3QgZWwgPSBpdGVtc1tpXS5lbGVtZW50O1xuICAgICAgaWYgKGVsICYmIGVsLmhhc1ZhbHVlKCkpIHtcbiAgICAgICAgY29uc3QgcG9zID0gZWwudG9vbHRpcFBvc2l0aW9uKCk7XG4gICAgICAgIHhTZXQuYWRkKHBvcy54KTtcbiAgICAgICAgeSArPSBwb3MueTtcbiAgICAgICAgKytjb3VudDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB4QXZlcmFnZSA9IFsuLi54U2V0XS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiKSAvIHhTZXQuc2l6ZTtcblxuICAgIHJldHVybiB7XG4gICAgICB4OiB4QXZlcmFnZSxcbiAgICAgIHk6IHkgLyBjb3VudFxuICAgIH07XG4gIH0sXG5cbiAgLyoqXG5cdCAqIEdldHMgdGhlIHRvb2x0aXAgcG9zaXRpb24gbmVhcmVzdCBvZiB0aGUgaXRlbSBuZWFyZXN0IHRvIHRoZSBldmVudCBwb3NpdGlvblxuXHQgKi9cbiAgbmVhcmVzdChpdGVtcywgZXZlbnRQb3NpdGlvbikge1xuICAgIGlmICghaXRlbXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbGV0IHggPSBldmVudFBvc2l0aW9uLng7XG4gICAgbGV0IHkgPSBldmVudFBvc2l0aW9uLnk7XG4gICAgbGV0IG1pbkRpc3RhbmNlID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xuICAgIGxldCBpLCBsZW4sIG5lYXJlc3RFbGVtZW50O1xuXG4gICAgZm9yIChpID0gMCwgbGVuID0gaXRlbXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIGNvbnN0IGVsID0gaXRlbXNbaV0uZWxlbWVudDtcbiAgICAgIGlmIChlbCAmJiBlbC5oYXNWYWx1ZSgpKSB7XG4gICAgICAgIGNvbnN0IGNlbnRlciA9IGVsLmdldENlbnRlclBvaW50KCk7XG4gICAgICAgIGNvbnN0IGQgPSBkaXN0YW5jZUJldHdlZW5Qb2ludHMoZXZlbnRQb3NpdGlvbiwgY2VudGVyKTtcblxuICAgICAgICBpZiAoZCA8IG1pbkRpc3RhbmNlKSB7XG4gICAgICAgICAgbWluRGlzdGFuY2UgPSBkO1xuICAgICAgICAgIG5lYXJlc3RFbGVtZW50ID0gZWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobmVhcmVzdEVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHRwID0gbmVhcmVzdEVsZW1lbnQudG9vbHRpcFBvc2l0aW9uKCk7XG4gICAgICB4ID0gdHAueDtcbiAgICAgIHkgPSB0cC55O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB4LFxuICAgICAgeVxuICAgIH07XG4gIH1cbn07XG5cbi8vIEhlbHBlciB0byBwdXNoIG9yIGNvbmNhdCBiYXNlZCBvbiBpZiB0aGUgMm5kIHBhcmFtZXRlciBpcyBhbiBhcnJheSBvciBub3RcbmZ1bmN0aW9uIHB1c2hPckNvbmNhdChiYXNlLCB0b1B1c2gpIHtcbiAgaWYgKHRvUHVzaCkge1xuICAgIGlmIChpc0FycmF5KHRvUHVzaCkpIHtcbiAgICAgIC8vIGJhc2UgPSBiYXNlLmNvbmNhdCh0b1B1c2gpO1xuICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoYmFzZSwgdG9QdXNoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYmFzZS5wdXNoKHRvUHVzaCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJhc2U7XG59XG5cbi8qKlxuICogUmV0dXJucyBhcnJheSBvZiBzdHJpbmdzIHNwbGl0IGJ5IG5ld2xpbmVcbiAqIEBwYXJhbSB7Kn0gc3RyIC0gVGhlIHZhbHVlIHRvIHNwbGl0IGJ5IG5ld2xpbmUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfHN0cmluZ1tdfSB2YWx1ZSBpZiBuZXdsaW5lIHByZXNlbnQgLSBSZXR1cm5lZCBmcm9tIFN0cmluZyBzcGxpdCgpIG1ldGhvZFxuICogQGZ1bmN0aW9uXG4gKi9cbmZ1bmN0aW9uIHNwbGl0TmV3bGluZXMoc3RyKSB7XG4gIGlmICgodHlwZW9mIHN0ciA9PT0gJ3N0cmluZycgfHwgc3RyIGluc3RhbmNlb2YgU3RyaW5nKSAmJiBzdHIuaW5kZXhPZignXFxuJykgPiAtMSkge1xuICAgIHJldHVybiBzdHIuc3BsaXQoJ1xcbicpO1xuICB9XG4gIHJldHVybiBzdHI7XG59XG5cblxuLyoqXG4gKiBQcml2YXRlIGhlbHBlciB0byBjcmVhdGUgYSB0b29sdGlwIGl0ZW0gbW9kZWxcbiAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0XG4gKiBAcGFyYW0ge0FjdGl2ZUVsZW1lbnR9IGl0ZW0gLSB7ZWxlbWVudCwgaW5kZXgsIGRhdGFzZXRJbmRleH0gdG8gY3JlYXRlIHRoZSB0b29sdGlwIGl0ZW0gZm9yXG4gKiBAcmV0dXJuIG5ldyB0b29sdGlwIGl0ZW1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlVG9vbHRpcEl0ZW0oY2hhcnQsIGl0ZW0pIHtcbiAgY29uc3Qge2VsZW1lbnQsIGRhdGFzZXRJbmRleCwgaW5kZXh9ID0gaXRlbTtcbiAgY29uc3QgY29udHJvbGxlciA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCkuY29udHJvbGxlcjtcbiAgY29uc3Qge2xhYmVsLCB2YWx1ZX0gPSBjb250cm9sbGVyLmdldExhYmVsQW5kVmFsdWUoaW5kZXgpO1xuXG4gIHJldHVybiB7XG4gICAgY2hhcnQsXG4gICAgbGFiZWwsXG4gICAgcGFyc2VkOiBjb250cm9sbGVyLmdldFBhcnNlZChpbmRleCksXG4gICAgcmF3OiBjaGFydC5kYXRhLmRhdGFzZXRzW2RhdGFzZXRJbmRleF0uZGF0YVtpbmRleF0sXG4gICAgZm9ybWF0dGVkVmFsdWU6IHZhbHVlLFxuICAgIGRhdGFzZXQ6IGNvbnRyb2xsZXIuZ2V0RGF0YXNldCgpLFxuICAgIGRhdGFJbmRleDogaW5kZXgsXG4gICAgZGF0YXNldEluZGV4LFxuICAgIGVsZW1lbnRcbiAgfTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHNpemUgb2YgdGhlIHRvb2x0aXBcbiAqL1xuZnVuY3Rpb24gZ2V0VG9vbHRpcFNpemUodG9vbHRpcCwgb3B0aW9ucykge1xuICBjb25zdCBjdHggPSB0b29sdGlwLmNoYXJ0LmN0eDtcbiAgY29uc3Qge2JvZHksIGZvb3RlciwgdGl0bGV9ID0gdG9vbHRpcDtcbiAgY29uc3Qge2JveFdpZHRoLCBib3hIZWlnaHR9ID0gb3B0aW9ucztcbiAgY29uc3QgYm9keUZvbnQgPSB0b0ZvbnQob3B0aW9ucy5ib2R5Rm9udCk7XG4gIGNvbnN0IHRpdGxlRm9udCA9IHRvRm9udChvcHRpb25zLnRpdGxlRm9udCk7XG4gIGNvbnN0IGZvb3RlckZvbnQgPSB0b0ZvbnQob3B0aW9ucy5mb290ZXJGb250KTtcbiAgY29uc3QgdGl0bGVMaW5lQ291bnQgPSB0aXRsZS5sZW5ndGg7XG4gIGNvbnN0IGZvb3RlckxpbmVDb3VudCA9IGZvb3Rlci5sZW5ndGg7XG4gIGNvbnN0IGJvZHlMaW5lSXRlbUNvdW50ID0gYm9keS5sZW5ndGg7XG5cbiAgY29uc3QgcGFkZGluZyA9IHRvUGFkZGluZyhvcHRpb25zLnBhZGRpbmcpO1xuICBsZXQgaGVpZ2h0ID0gcGFkZGluZy5oZWlnaHQ7XG4gIGxldCB3aWR0aCA9IDA7XG5cbiAgLy8gQ291bnQgb2YgYWxsIGxpbmVzIGluIHRoZSBib2R5XG4gIGxldCBjb21iaW5lZEJvZHlMZW5ndGggPSBib2R5LnJlZHVjZSgoY291bnQsIGJvZHlJdGVtKSA9PiBjb3VudCArIGJvZHlJdGVtLmJlZm9yZS5sZW5ndGggKyBib2R5SXRlbS5saW5lcy5sZW5ndGggKyBib2R5SXRlbS5hZnRlci5sZW5ndGgsIDApO1xuICBjb21iaW5lZEJvZHlMZW5ndGggKz0gdG9vbHRpcC5iZWZvcmVCb2R5Lmxlbmd0aCArIHRvb2x0aXAuYWZ0ZXJCb2R5Lmxlbmd0aDtcblxuICBpZiAodGl0bGVMaW5lQ291bnQpIHtcbiAgICBoZWlnaHQgKz0gdGl0bGVMaW5lQ291bnQgKiB0aXRsZUZvbnQubGluZUhlaWdodFxuXHRcdFx0KyAodGl0bGVMaW5lQ291bnQgLSAxKSAqIG9wdGlvbnMudGl0bGVTcGFjaW5nXG5cdFx0XHQrIG9wdGlvbnMudGl0bGVNYXJnaW5Cb3R0b207XG4gIH1cbiAgaWYgKGNvbWJpbmVkQm9keUxlbmd0aCkge1xuICAgIC8vIEJvZHkgbGluZXMgbWF5IGluY2x1ZGUgc29tZSBleHRyYSBoZWlnaHQgZGVwZW5kaW5nIG9uIGJveEhlaWdodFxuICAgIGNvbnN0IGJvZHlMaW5lSGVpZ2h0ID0gb3B0aW9ucy5kaXNwbGF5Q29sb3JzID8gTWF0aC5tYXgoYm94SGVpZ2h0LCBib2R5Rm9udC5saW5lSGVpZ2h0KSA6IGJvZHlGb250LmxpbmVIZWlnaHQ7XG4gICAgaGVpZ2h0ICs9IGJvZHlMaW5lSXRlbUNvdW50ICogYm9keUxpbmVIZWlnaHRcblx0XHRcdCsgKGNvbWJpbmVkQm9keUxlbmd0aCAtIGJvZHlMaW5lSXRlbUNvdW50KSAqIGJvZHlGb250LmxpbmVIZWlnaHRcblx0XHRcdCsgKGNvbWJpbmVkQm9keUxlbmd0aCAtIDEpICogb3B0aW9ucy5ib2R5U3BhY2luZztcbiAgfVxuICBpZiAoZm9vdGVyTGluZUNvdW50KSB7XG4gICAgaGVpZ2h0ICs9IG9wdGlvbnMuZm9vdGVyTWFyZ2luVG9wXG5cdFx0XHQrIGZvb3RlckxpbmVDb3VudCAqIGZvb3RlckZvbnQubGluZUhlaWdodFxuXHRcdFx0KyAoZm9vdGVyTGluZUNvdW50IC0gMSkgKiBvcHRpb25zLmZvb3RlclNwYWNpbmc7XG4gIH1cblxuICAvLyBUaXRsZSB3aWR0aFxuICBsZXQgd2lkdGhQYWRkaW5nID0gMDtcbiAgY29uc3QgbWF4TGluZVdpZHRoID0gZnVuY3Rpb24obGluZSkge1xuICAgIHdpZHRoID0gTWF0aC5tYXgod2lkdGgsIGN0eC5tZWFzdXJlVGV4dChsaW5lKS53aWR0aCArIHdpZHRoUGFkZGluZyk7XG4gIH07XG5cbiAgY3R4LnNhdmUoKTtcblxuICBjdHguZm9udCA9IHRpdGxlRm9udC5zdHJpbmc7XG4gIGVhY2godG9vbHRpcC50aXRsZSwgbWF4TGluZVdpZHRoKTtcblxuICAvLyBCb2R5IHdpZHRoXG4gIGN0eC5mb250ID0gYm9keUZvbnQuc3RyaW5nO1xuICBlYWNoKHRvb2x0aXAuYmVmb3JlQm9keS5jb25jYXQodG9vbHRpcC5hZnRlckJvZHkpLCBtYXhMaW5lV2lkdGgpO1xuXG4gIC8vIEJvZHkgbGluZXMgbWF5IGluY2x1ZGUgc29tZSBleHRyYSB3aWR0aCBkdWUgdG8gdGhlIGNvbG9yIGJveFxuICB3aWR0aFBhZGRpbmcgPSBvcHRpb25zLmRpc3BsYXlDb2xvcnMgPyAoYm94V2lkdGggKyAyICsgb3B0aW9ucy5ib3hQYWRkaW5nKSA6IDA7XG4gIGVhY2goYm9keSwgKGJvZHlJdGVtKSA9PiB7XG4gICAgZWFjaChib2R5SXRlbS5iZWZvcmUsIG1heExpbmVXaWR0aCk7XG4gICAgZWFjaChib2R5SXRlbS5saW5lcywgbWF4TGluZVdpZHRoKTtcbiAgICBlYWNoKGJvZHlJdGVtLmFmdGVyLCBtYXhMaW5lV2lkdGgpO1xuICB9KTtcblxuICAvLyBSZXNldCBiYWNrIHRvIDBcbiAgd2lkdGhQYWRkaW5nID0gMDtcblxuICAvLyBGb290ZXIgd2lkdGhcbiAgY3R4LmZvbnQgPSBmb290ZXJGb250LnN0cmluZztcbiAgZWFjaCh0b29sdGlwLmZvb3RlciwgbWF4TGluZVdpZHRoKTtcblxuICBjdHgucmVzdG9yZSgpO1xuXG4gIC8vIEFkZCBwYWRkaW5nXG4gIHdpZHRoICs9IHBhZGRpbmcud2lkdGg7XG5cbiAgcmV0dXJuIHt3aWR0aCwgaGVpZ2h0fTtcbn1cblxuZnVuY3Rpb24gZGV0ZXJtaW5lWUFsaWduKGNoYXJ0LCBzaXplKSB7XG4gIGNvbnN0IHt5LCBoZWlnaHR9ID0gc2l6ZTtcblxuICBpZiAoeSA8IGhlaWdodCAvIDIpIHtcbiAgICByZXR1cm4gJ3RvcCc7XG4gIH0gZWxzZSBpZiAoeSA+IChjaGFydC5oZWlnaHQgLSBoZWlnaHQgLyAyKSkge1xuICAgIHJldHVybiAnYm90dG9tJztcbiAgfVxuICByZXR1cm4gJ2NlbnRlcic7XG59XG5cbmZ1bmN0aW9uIGRvZXNOb3RGaXRXaXRoQWxpZ24oeEFsaWduLCBjaGFydCwgb3B0aW9ucywgc2l6ZSkge1xuICBjb25zdCB7eCwgd2lkdGh9ID0gc2l6ZTtcbiAgY29uc3QgY2FyZXQgPSBvcHRpb25zLmNhcmV0U2l6ZSArIG9wdGlvbnMuY2FyZXRQYWRkaW5nO1xuICBpZiAoeEFsaWduID09PSAnbGVmdCcgJiYgeCArIHdpZHRoICsgY2FyZXQgPiBjaGFydC53aWR0aCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0JyAmJiB4IC0gd2lkdGggLSBjYXJldCA8IDApIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZXRlcm1pbmVYQWxpZ24oY2hhcnQsIG9wdGlvbnMsIHNpemUsIHlBbGlnbikge1xuICBjb25zdCB7eCwgd2lkdGh9ID0gc2l6ZTtcbiAgY29uc3Qge3dpZHRoOiBjaGFydFdpZHRoLCBjaGFydEFyZWE6IHtsZWZ0LCByaWdodH19ID0gY2hhcnQ7XG4gIGxldCB4QWxpZ24gPSAnY2VudGVyJztcblxuICBpZiAoeUFsaWduID09PSAnY2VudGVyJykge1xuICAgIHhBbGlnbiA9IHggPD0gKGxlZnQgKyByaWdodCkgLyAyID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgfSBlbHNlIGlmICh4IDw9IHdpZHRoIC8gMikge1xuICAgIHhBbGlnbiA9ICdsZWZ0JztcbiAgfSBlbHNlIGlmICh4ID49IGNoYXJ0V2lkdGggLSB3aWR0aCAvIDIpIHtcbiAgICB4QWxpZ24gPSAncmlnaHQnO1xuICB9XG5cbiAgaWYgKGRvZXNOb3RGaXRXaXRoQWxpZ24oeEFsaWduLCBjaGFydCwgb3B0aW9ucywgc2l6ZSkpIHtcbiAgICB4QWxpZ24gPSAnY2VudGVyJztcbiAgfVxuXG4gIHJldHVybiB4QWxpZ247XG59XG5cbi8qKlxuICogSGVscGVyIHRvIGdldCB0aGUgYWxpZ25tZW50IG9mIGEgdG9vbHRpcCBnaXZlbiB0aGUgc2l6ZVxuICovXG5mdW5jdGlvbiBkZXRlcm1pbmVBbGlnbm1lbnQoY2hhcnQsIG9wdGlvbnMsIHNpemUpIHtcbiAgY29uc3QgeUFsaWduID0gc2l6ZS55QWxpZ24gfHwgb3B0aW9ucy55QWxpZ24gfHwgZGV0ZXJtaW5lWUFsaWduKGNoYXJ0LCBzaXplKTtcblxuICByZXR1cm4ge1xuICAgIHhBbGlnbjogc2l6ZS54QWxpZ24gfHwgb3B0aW9ucy54QWxpZ24gfHwgZGV0ZXJtaW5lWEFsaWduKGNoYXJ0LCBvcHRpb25zLCBzaXplLCB5QWxpZ24pLFxuICAgIHlBbGlnblxuICB9O1xufVxuXG5mdW5jdGlvbiBhbGlnblgoc2l6ZSwgeEFsaWduKSB7XG4gIGxldCB7eCwgd2lkdGh9ID0gc2l6ZTtcbiAgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgIHggLT0gd2lkdGg7XG4gIH0gZWxzZSBpZiAoeEFsaWduID09PSAnY2VudGVyJykge1xuICAgIHggLT0gKHdpZHRoIC8gMik7XG4gIH1cbiAgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIGFsaWduWShzaXplLCB5QWxpZ24sIHBhZGRpbmdBbmRTaXplKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItY29uc3RcbiAgbGV0IHt5LCBoZWlnaHR9ID0gc2l6ZTtcbiAgaWYgKHlBbGlnbiA9PT0gJ3RvcCcpIHtcbiAgICB5ICs9IHBhZGRpbmdBbmRTaXplO1xuICB9IGVsc2UgaWYgKHlBbGlnbiA9PT0gJ2JvdHRvbScpIHtcbiAgICB5IC09IGhlaWdodCArIHBhZGRpbmdBbmRTaXplO1xuICB9IGVsc2Uge1xuICAgIHkgLT0gKGhlaWdodCAvIDIpO1xuICB9XG4gIHJldHVybiB5O1xufVxuXG4vKipcbiAqIEhlbHBlciB0byBnZXQgdGhlIGxvY2F0aW9uIGEgdG9vbHRpcCBuZWVkcyB0byBiZSBwbGFjZWQgYXQgZ2l2ZW4gdGhlIGluaXRpYWwgcG9zaXRpb24gKHZpYSB0aGUgdm0pIGFuZCB0aGUgc2l6ZSBhbmQgYWxpZ25tZW50XG4gKi9cbmZ1bmN0aW9uIGdldEJhY2tncm91bmRQb2ludChvcHRpb25zLCBzaXplLCBhbGlnbm1lbnQsIGNoYXJ0KSB7XG4gIGNvbnN0IHtjYXJldFNpemUsIGNhcmV0UGFkZGluZywgY29ybmVyUmFkaXVzfSA9IG9wdGlvbnM7XG4gIGNvbnN0IHt4QWxpZ24sIHlBbGlnbn0gPSBhbGlnbm1lbnQ7XG4gIGNvbnN0IHBhZGRpbmdBbmRTaXplID0gY2FyZXRTaXplICsgY2FyZXRQYWRkaW5nO1xuICBjb25zdCB7dG9wTGVmdCwgdG9wUmlnaHQsIGJvdHRvbUxlZnQsIGJvdHRvbVJpZ2h0fSA9IHRvVFJCTENvcm5lcnMoY29ybmVyUmFkaXVzKTtcblxuICBsZXQgeCA9IGFsaWduWChzaXplLCB4QWxpZ24pO1xuICBjb25zdCB5ID0gYWxpZ25ZKHNpemUsIHlBbGlnbiwgcGFkZGluZ0FuZFNpemUpO1xuXG4gIGlmICh5QWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgaWYgKHhBbGlnbiA9PT0gJ2xlZnQnKSB7XG4gICAgICB4ICs9IHBhZGRpbmdBbmRTaXplO1xuICAgIH0gZWxzZSBpZiAoeEFsaWduID09PSAncmlnaHQnKSB7XG4gICAgICB4IC09IHBhZGRpbmdBbmRTaXplO1xuICAgIH1cbiAgfSBlbHNlIGlmICh4QWxpZ24gPT09ICdsZWZ0Jykge1xuICAgIHggLT0gTWF0aC5tYXgodG9wTGVmdCwgYm90dG9tTGVmdCkgKyBjYXJldFNpemU7XG4gIH0gZWxzZSBpZiAoeEFsaWduID09PSAncmlnaHQnKSB7XG4gICAgeCArPSBNYXRoLm1heCh0b3BSaWdodCwgYm90dG9tUmlnaHQpICsgY2FyZXRTaXplO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBfbGltaXRWYWx1ZSh4LCAwLCBjaGFydC53aWR0aCAtIHNpemUud2lkdGgpLFxuICAgIHk6IF9saW1pdFZhbHVlKHksIDAsIGNoYXJ0LmhlaWdodCAtIHNpemUuaGVpZ2h0KVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRBbGlnbmVkWCh0b29sdGlwLCBhbGlnbiwgb3B0aW9ucykge1xuICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKG9wdGlvbnMucGFkZGluZyk7XG5cbiAgcmV0dXJuIGFsaWduID09PSAnY2VudGVyJ1xuICAgID8gdG9vbHRpcC54ICsgdG9vbHRpcC53aWR0aCAvIDJcbiAgICA6IGFsaWduID09PSAncmlnaHQnXG4gICAgICA/IHRvb2x0aXAueCArIHRvb2x0aXAud2lkdGggLSBwYWRkaW5nLnJpZ2h0XG4gICAgICA6IHRvb2x0aXAueCArIHBhZGRpbmcubGVmdDtcbn1cblxuLyoqXG4gKiBIZWxwZXIgdG8gYnVpbGQgYmVmb3JlIGFuZCBhZnRlciBib2R5IGxpbmVzXG4gKi9cbmZ1bmN0aW9uIGdldEJlZm9yZUFmdGVyQm9keUxpbmVzKGNhbGxiYWNrKSB7XG4gIHJldHVybiBwdXNoT3JDb25jYXQoW10sIHNwbGl0TmV3bGluZXMoY2FsbGJhY2spKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVG9vbHRpcENvbnRleHQocGFyZW50LCB0b29sdGlwLCB0b29sdGlwSXRlbXMpIHtcbiAgcmV0dXJuIGNyZWF0ZUNvbnRleHQocGFyZW50LCB7XG4gICAgdG9vbHRpcCxcbiAgICB0b29sdGlwSXRlbXMsXG4gICAgdHlwZTogJ3Rvb2x0aXAnXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBvdmVycmlkZUNhbGxiYWNrcyhjYWxsYmFja3MsIGNvbnRleHQpIHtcbiAgY29uc3Qgb3ZlcnJpZGUgPSBjb250ZXh0ICYmIGNvbnRleHQuZGF0YXNldCAmJiBjb250ZXh0LmRhdGFzZXQudG9vbHRpcCAmJiBjb250ZXh0LmRhdGFzZXQudG9vbHRpcC5jYWxsYmFja3M7XG4gIHJldHVybiBvdmVycmlkZSA/IGNhbGxiYWNrcy5vdmVycmlkZShvdmVycmlkZSkgOiBjYWxsYmFja3M7XG59XG5cbmNvbnN0IGRlZmF1bHRDYWxsYmFja3MgPSB7XG4gIC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW1zLCBkYXRhKVxuICBiZWZvcmVUaXRsZTogbm9vcCxcbiAgdGl0bGUodG9vbHRpcEl0ZW1zKSB7XG4gICAgaWYgKHRvb2x0aXBJdGVtcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBpdGVtID0gdG9vbHRpcEl0ZW1zWzBdO1xuICAgICAgY29uc3QgbGFiZWxzID0gaXRlbS5jaGFydC5kYXRhLmxhYmVscztcbiAgICAgIGNvbnN0IGxhYmVsQ291bnQgPSBsYWJlbHMgPyBsYWJlbHMubGVuZ3RoIDogMDtcblxuICAgICAgaWYgKHRoaXMgJiYgdGhpcy5vcHRpb25zICYmIHRoaXMub3B0aW9ucy5tb2RlID09PSAnZGF0YXNldCcpIHtcbiAgICAgICAgcmV0dXJuIGl0ZW0uZGF0YXNldC5sYWJlbCB8fCAnJztcbiAgICAgIH0gZWxzZSBpZiAoaXRlbS5sYWJlbCkge1xuICAgICAgICByZXR1cm4gaXRlbS5sYWJlbDtcbiAgICAgIH0gZWxzZSBpZiAobGFiZWxDb3VudCA+IDAgJiYgaXRlbS5kYXRhSW5kZXggPCBsYWJlbENvdW50KSB7XG4gICAgICAgIHJldHVybiBsYWJlbHNbaXRlbS5kYXRhSW5kZXhdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAnJztcbiAgfSxcbiAgYWZ0ZXJUaXRsZTogbm9vcCxcblxuICAvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtcywgZGF0YSlcbiAgYmVmb3JlQm9keTogbm9vcCxcblxuICAvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtLCBkYXRhKVxuICBiZWZvcmVMYWJlbDogbm9vcCxcbiAgbGFiZWwodG9vbHRpcEl0ZW0pIHtcbiAgICBpZiAodGhpcyAmJiB0aGlzLm9wdGlvbnMgJiYgdGhpcy5vcHRpb25zLm1vZGUgPT09ICdkYXRhc2V0Jykge1xuICAgICAgcmV0dXJuIHRvb2x0aXBJdGVtLmxhYmVsICsgJzogJyArIHRvb2x0aXBJdGVtLmZvcm1hdHRlZFZhbHVlIHx8IHRvb2x0aXBJdGVtLmZvcm1hdHRlZFZhbHVlO1xuICAgIH1cblxuICAgIGxldCBsYWJlbCA9IHRvb2x0aXBJdGVtLmRhdGFzZXQubGFiZWwgfHwgJyc7XG5cbiAgICBpZiAobGFiZWwpIHtcbiAgICAgIGxhYmVsICs9ICc6ICc7XG4gICAgfVxuICAgIGNvbnN0IHZhbHVlID0gdG9vbHRpcEl0ZW0uZm9ybWF0dGVkVmFsdWU7XG4gICAgaWYgKCFpc051bGxPclVuZGVmKHZhbHVlKSkge1xuICAgICAgbGFiZWwgKz0gdmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBsYWJlbDtcbiAgfSxcbiAgbGFiZWxDb2xvcih0b29sdGlwSXRlbSkge1xuICAgIGNvbnN0IG1ldGEgPSB0b29sdGlwSXRlbS5jaGFydC5nZXREYXRhc2V0TWV0YSh0b29sdGlwSXRlbS5kYXRhc2V0SW5kZXgpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSBtZXRhLmNvbnRyb2xsZXIuZ2V0U3R5bGUodG9vbHRpcEl0ZW0uZGF0YUluZGV4KTtcbiAgICByZXR1cm4ge1xuICAgICAgYm9yZGVyQ29sb3I6IG9wdGlvbnMuYm9yZGVyQ29sb3IsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IG9wdGlvbnMuYmFja2dyb3VuZENvbG9yLFxuICAgICAgYm9yZGVyV2lkdGg6IG9wdGlvbnMuYm9yZGVyV2lkdGgsXG4gICAgICBib3JkZXJEYXNoOiBvcHRpb25zLmJvcmRlckRhc2gsXG4gICAgICBib3JkZXJEYXNoT2Zmc2V0OiBvcHRpb25zLmJvcmRlckRhc2hPZmZzZXQsXG4gICAgICBib3JkZXJSYWRpdXM6IDAsXG4gICAgfTtcbiAgfSxcbiAgbGFiZWxUZXh0Q29sb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5ib2R5Q29sb3I7XG4gIH0sXG4gIGxhYmVsUG9pbnRTdHlsZSh0b29sdGlwSXRlbSkge1xuICAgIGNvbnN0IG1ldGEgPSB0b29sdGlwSXRlbS5jaGFydC5nZXREYXRhc2V0TWV0YSh0b29sdGlwSXRlbS5kYXRhc2V0SW5kZXgpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSBtZXRhLmNvbnRyb2xsZXIuZ2V0U3R5bGUodG9vbHRpcEl0ZW0uZGF0YUluZGV4KTtcbiAgICByZXR1cm4ge1xuICAgICAgcG9pbnRTdHlsZTogb3B0aW9ucy5wb2ludFN0eWxlLFxuICAgICAgcm90YXRpb246IG9wdGlvbnMucm90YXRpb24sXG4gICAgfTtcbiAgfSxcbiAgYWZ0ZXJMYWJlbDogbm9vcCxcblxuICAvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtcywgZGF0YSlcbiAgYWZ0ZXJCb2R5OiBub29wLFxuXG4gIC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW1zLCBkYXRhKVxuICBiZWZvcmVGb290ZXI6IG5vb3AsXG4gIGZvb3Rlcjogbm9vcCxcbiAgYWZ0ZXJGb290ZXI6IG5vb3Bcbn07XG5cbi8qKlxuICogSW52b2tlIGNhbGxiYWNrIGZyb20gb2JqZWN0IHdpdGggY29udGV4dCBhbmQgYXJndW1lbnRzLlxuICogSWYgY2FsbGJhY2sgcmV0dXJucyBgdW5kZWZpbmVkYCwgdGhlbiB3aWxsIGJlIGludm9rZWQgZGVmYXVsdCBjYWxsYmFjay5cbiAqIEBwYXJhbSB7UmVjb3JkPGtleW9mIHR5cGVvZiBkZWZhdWx0Q2FsbGJhY2tzLCBGdW5jdGlvbj59IGNhbGxiYWNrc1xuICogQHBhcmFtIHtrZXlvZiB0eXBlb2YgZGVmYXVsdENhbGxiYWNrc30gbmFtZVxuICogQHBhcmFtIHsqfSBjdHhcbiAqIEBwYXJhbSB7Kn0gYXJnXG4gKiBAcmV0dXJucyB7YW55fVxuICovXG5mdW5jdGlvbiBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhjYWxsYmFja3MsIG5hbWUsIGN0eCwgYXJnKSB7XG4gIGNvbnN0IHJlc3VsdCA9IGNhbGxiYWNrc1tuYW1lXS5jYWxsKGN0eCwgYXJnKTtcblxuICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gZGVmYXVsdENhbGxiYWNrc1tuYW1lXS5jYWxsKGN0eCwgYXJnKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBjbGFzcyBUb29sdGlwIGV4dGVuZHMgRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBuYW1lc3BhY2UgQ2hhcnQuVG9vbHRpcC5wb3NpdGlvbmVyc1xuICAgKi9cbiAgc3RhdGljIHBvc2l0aW9uZXJzID0gcG9zaXRpb25lcnM7XG5cbiAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMub3BhY2l0eSA9IDA7XG4gICAgdGhpcy5fYWN0aXZlID0gW107XG4gICAgdGhpcy5fZXZlbnRQb3NpdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9zaXplID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2NhY2hlZEFuaW1hdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fdG9vbHRpcEl0ZW1zID0gW107XG4gICAgdGhpcy4kYW5pbWF0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLiRjb250ZXh0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY2hhcnQgPSBjb25maWcuY2hhcnQ7XG4gICAgdGhpcy5vcHRpb25zID0gY29uZmlnLm9wdGlvbnM7XG4gICAgdGhpcy5kYXRhUG9pbnRzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudGl0bGUgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5iZWZvcmVCb2R5ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuYm9keSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmFmdGVyQm9keSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmZvb3RlciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnhBbGlnbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnlBbGlnbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy55ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuaGVpZ2h0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMud2lkdGggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jYXJldFggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jYXJldFkgPSB1bmRlZmluZWQ7XG4gICAgLy8gVE9ETzogVjQsIG1ha2UgdGhpcyBwcml2YXRlLCByZW5hbWUgdG8gYF9sYWJlbFN0eWxlc2AsIGFuZCBjb21iaW5lIHdpdGggYGxhYmVsUG9pbnRTdHlsZXNgXG4gICAgLy8gYW5kIGBsYWJlbFRleHRDb2xvcnNgIHRvIGNyZWF0ZSBhIHNpbmdsZSB2YXJpYWJsZVxuICAgIHRoaXMubGFiZWxDb2xvcnMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sYWJlbFBvaW50U3R5bGVzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubGFiZWxUZXh0Q29sb3JzID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaW5pdGlhbGl6ZShvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLl9jYWNoZWRBbmltYXRpb25zID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuJGNvbnRleHQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9yZXNvbHZlQW5pbWF0aW9ucygpIHtcbiAgICBjb25zdCBjYWNoZWQgPSB0aGlzLl9jYWNoZWRBbmltYXRpb25zO1xuXG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG5cbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucy5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICBjb25zdCBvcHRzID0gb3B0aW9ucy5lbmFibGVkICYmIGNoYXJ0Lm9wdGlvbnMuYW5pbWF0aW9uICYmIG9wdGlvbnMuYW5pbWF0aW9ucztcbiAgICBjb25zdCBhbmltYXRpb25zID0gbmV3IEFuaW1hdGlvbnModGhpcy5jaGFydCwgb3B0cyk7XG4gICAgaWYgKG9wdHMuX2NhY2hlYWJsZSkge1xuICAgICAgdGhpcy5fY2FjaGVkQW5pbWF0aW9ucyA9IE9iamVjdC5mcmVlemUoYW5pbWF0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFuaW1hdGlvbnM7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0Q29udGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy4kY29udGV4dCB8fFxuXHRcdFx0KHRoaXMuJGNvbnRleHQgPSBjcmVhdGVUb29sdGlwQ29udGV4dCh0aGlzLmNoYXJ0LmdldENvbnRleHQoKSwgdGhpcywgdGhpcy5fdG9vbHRpcEl0ZW1zKSk7XG4gIH1cblxuICBnZXRUaXRsZShjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgY29uc3Qge2NhbGxiYWNrc30gPSBvcHRpb25zO1xuXG4gICAgY29uc3QgYmVmb3JlVGl0bGUgPSBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhjYWxsYmFja3MsICdiZWZvcmVUaXRsZScsIHRoaXMsIGNvbnRleHQpO1xuICAgIGNvbnN0IHRpdGxlID0gaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soY2FsbGJhY2tzLCAndGl0bGUnLCB0aGlzLCBjb250ZXh0KTtcbiAgICBjb25zdCBhZnRlclRpdGxlID0gaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soY2FsbGJhY2tzLCAnYWZ0ZXJUaXRsZScsIHRoaXMsIGNvbnRleHQpO1xuXG4gICAgbGV0IGxpbmVzID0gW107XG4gICAgbGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYmVmb3JlVGl0bGUpKTtcbiAgICBsaW5lcyA9IHB1c2hPckNvbmNhdChsaW5lcywgc3BsaXROZXdsaW5lcyh0aXRsZSkpO1xuICAgIGxpbmVzID0gcHVzaE9yQ29uY2F0KGxpbmVzLCBzcGxpdE5ld2xpbmVzKGFmdGVyVGl0bGUpKTtcblxuICAgIHJldHVybiBsaW5lcztcbiAgfVxuXG4gIGdldEJlZm9yZUJvZHkodG9vbHRpcEl0ZW1zLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIGdldEJlZm9yZUFmdGVyQm9keUxpbmVzKFxuICAgICAgaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2sob3B0aW9ucy5jYWxsYmFja3MsICdiZWZvcmVCb2R5JywgdGhpcywgdG9vbHRpcEl0ZW1zKVxuICAgICk7XG4gIH1cblxuICBnZXRCb2R5KHRvb2x0aXBJdGVtcywgb3B0aW9ucykge1xuICAgIGNvbnN0IHtjYWxsYmFja3N9ID0gb3B0aW9ucztcbiAgICBjb25zdCBib2R5SXRlbXMgPSBbXTtcblxuICAgIGVhY2godG9vbHRpcEl0ZW1zLCAoY29udGV4dCkgPT4ge1xuICAgICAgY29uc3QgYm9keUl0ZW0gPSB7XG4gICAgICAgIGJlZm9yZTogW10sXG4gICAgICAgIGxpbmVzOiBbXSxcbiAgICAgICAgYWZ0ZXI6IFtdXG4gICAgICB9O1xuICAgICAgY29uc3Qgc2NvcGVkID0gb3ZlcnJpZGVDYWxsYmFja3MoY2FsbGJhY2tzLCBjb250ZXh0KTtcbiAgICAgIHB1c2hPckNvbmNhdChib2R5SXRlbS5iZWZvcmUsIHNwbGl0TmV3bGluZXMoaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soc2NvcGVkLCAnYmVmb3JlTGFiZWwnLCB0aGlzLCBjb250ZXh0KSkpO1xuICAgICAgcHVzaE9yQ29uY2F0KGJvZHlJdGVtLmxpbmVzLCBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhzY29wZWQsICdsYWJlbCcsIHRoaXMsIGNvbnRleHQpKTtcbiAgICAgIHB1c2hPckNvbmNhdChib2R5SXRlbS5hZnRlciwgc3BsaXROZXdsaW5lcyhpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhzY29wZWQsICdhZnRlckxhYmVsJywgdGhpcywgY29udGV4dCkpKTtcblxuICAgICAgYm9keUl0ZW1zLnB1c2goYm9keUl0ZW0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGJvZHlJdGVtcztcbiAgfVxuXG4gIGdldEFmdGVyQm9keSh0b29sdGlwSXRlbXMsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gZ2V0QmVmb3JlQWZ0ZXJCb2R5TGluZXMoXG4gICAgICBpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhvcHRpb25zLmNhbGxiYWNrcywgJ2FmdGVyQm9keScsIHRoaXMsIHRvb2x0aXBJdGVtcylcbiAgICApO1xuICB9XG5cbiAgLy8gR2V0IHRoZSBmb290ZXIgYW5kIGJlZm9yZUZvb3RlciBhbmQgYWZ0ZXJGb290ZXIgbGluZXNcbiAgZ2V0Rm9vdGVyKHRvb2x0aXBJdGVtcywgb3B0aW9ucykge1xuICAgIGNvbnN0IHtjYWxsYmFja3N9ID0gb3B0aW9ucztcblxuICAgIGNvbnN0IGJlZm9yZUZvb3RlciA9IGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKGNhbGxiYWNrcywgJ2JlZm9yZUZvb3RlcicsIHRoaXMsIHRvb2x0aXBJdGVtcyk7XG4gICAgY29uc3QgZm9vdGVyID0gaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soY2FsbGJhY2tzLCAnZm9vdGVyJywgdGhpcywgdG9vbHRpcEl0ZW1zKTtcbiAgICBjb25zdCBhZnRlckZvb3RlciA9IGludm9rZUNhbGxiYWNrV2l0aEZhbGxiYWNrKGNhbGxiYWNrcywgJ2FmdGVyRm9vdGVyJywgdGhpcywgdG9vbHRpcEl0ZW1zKTtcblxuICAgIGxldCBsaW5lcyA9IFtdO1xuICAgIGxpbmVzID0gcHVzaE9yQ29uY2F0KGxpbmVzLCBzcGxpdE5ld2xpbmVzKGJlZm9yZUZvb3RlcikpO1xuICAgIGxpbmVzID0gcHVzaE9yQ29uY2F0KGxpbmVzLCBzcGxpdE5ld2xpbmVzKGZvb3RlcikpO1xuICAgIGxpbmVzID0gcHVzaE9yQ29uY2F0KGxpbmVzLCBzcGxpdE5ld2xpbmVzKGFmdGVyRm9vdGVyKSk7XG5cbiAgICByZXR1cm4gbGluZXM7XG4gIH1cblxuICAvKipcblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9jcmVhdGVJdGVtcyhvcHRpb25zKSB7XG4gICAgY29uc3QgYWN0aXZlID0gdGhpcy5fYWN0aXZlO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmNoYXJ0LmRhdGE7XG4gICAgY29uc3QgbGFiZWxDb2xvcnMgPSBbXTtcbiAgICBjb25zdCBsYWJlbFBvaW50U3R5bGVzID0gW107XG4gICAgY29uc3QgbGFiZWxUZXh0Q29sb3JzID0gW107XG4gICAgbGV0IHRvb2x0aXBJdGVtcyA9IFtdO1xuICAgIGxldCBpLCBsZW47XG5cbiAgICBmb3IgKGkgPSAwLCBsZW4gPSBhY3RpdmUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHRvb2x0aXBJdGVtcy5wdXNoKGNyZWF0ZVRvb2x0aXBJdGVtKHRoaXMuY2hhcnQsIGFjdGl2ZVtpXSkpO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSB1c2VyIHByb3ZpZGVkIGEgZmlsdGVyIGZ1bmN0aW9uLCB1c2UgaXQgdG8gbW9kaWZ5IHRoZSB0b29sdGlwIGl0ZW1zXG4gICAgaWYgKG9wdGlvbnMuZmlsdGVyKSB7XG4gICAgICB0b29sdGlwSXRlbXMgPSB0b29sdGlwSXRlbXMuZmlsdGVyKChlbGVtZW50LCBpbmRleCwgYXJyYXkpID0+IG9wdGlvbnMuZmlsdGVyKGVsZW1lbnQsIGluZGV4LCBhcnJheSwgZGF0YSkpO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSB1c2VyIHByb3ZpZGVkIGEgc29ydGluZyBmdW5jdGlvbiwgdXNlIGl0IHRvIG1vZGlmeSB0aGUgdG9vbHRpcCBpdGVtc1xuICAgIGlmIChvcHRpb25zLml0ZW1Tb3J0KSB7XG4gICAgICB0b29sdGlwSXRlbXMgPSB0b29sdGlwSXRlbXMuc29ydCgoYSwgYikgPT4gb3B0aW9ucy5pdGVtU29ydChhLCBiLCBkYXRhKSk7XG4gICAgfVxuXG4gICAgLy8gRGV0ZXJtaW5lIGNvbG9ycyBmb3IgYm94ZXNcbiAgICBlYWNoKHRvb2x0aXBJdGVtcywgKGNvbnRleHQpID0+IHtcbiAgICAgIGNvbnN0IHNjb3BlZCA9IG92ZXJyaWRlQ2FsbGJhY2tzKG9wdGlvbnMuY2FsbGJhY2tzLCBjb250ZXh0KTtcbiAgICAgIGxhYmVsQ29sb3JzLnB1c2goaW52b2tlQ2FsbGJhY2tXaXRoRmFsbGJhY2soc2NvcGVkLCAnbGFiZWxDb2xvcicsIHRoaXMsIGNvbnRleHQpKTtcbiAgICAgIGxhYmVsUG9pbnRTdHlsZXMucHVzaChpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhzY29wZWQsICdsYWJlbFBvaW50U3R5bGUnLCB0aGlzLCBjb250ZXh0KSk7XG4gICAgICBsYWJlbFRleHRDb2xvcnMucHVzaChpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayhzY29wZWQsICdsYWJlbFRleHRDb2xvcicsIHRoaXMsIGNvbnRleHQpKTtcbiAgICB9KTtcblxuICAgIHRoaXMubGFiZWxDb2xvcnMgPSBsYWJlbENvbG9ycztcbiAgICB0aGlzLmxhYmVsUG9pbnRTdHlsZXMgPSBsYWJlbFBvaW50U3R5bGVzO1xuICAgIHRoaXMubGFiZWxUZXh0Q29sb3JzID0gbGFiZWxUZXh0Q29sb3JzO1xuICAgIHRoaXMuZGF0YVBvaW50cyA9IHRvb2x0aXBJdGVtcztcbiAgICByZXR1cm4gdG9vbHRpcEl0ZW1zO1xuICB9XG5cbiAgdXBkYXRlKGNoYW5nZWQsIHJlcGxheSkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMuc2V0Q29udGV4dCh0aGlzLmdldENvbnRleHQoKSk7XG4gICAgY29uc3QgYWN0aXZlID0gdGhpcy5fYWN0aXZlO1xuICAgIGxldCBwcm9wZXJ0aWVzO1xuICAgIGxldCB0b29sdGlwSXRlbXMgPSBbXTtcblxuICAgIGlmICghYWN0aXZlLmxlbmd0aCkge1xuICAgICAgaWYgKHRoaXMub3BhY2l0eSAhPT0gMCkge1xuICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgIG9wYWNpdHk6IDBcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcG9zaXRpb24gPSBwb3NpdGlvbmVyc1tvcHRpb25zLnBvc2l0aW9uXS5jYWxsKHRoaXMsIGFjdGl2ZSwgdGhpcy5fZXZlbnRQb3NpdGlvbik7XG4gICAgICB0b29sdGlwSXRlbXMgPSB0aGlzLl9jcmVhdGVJdGVtcyhvcHRpb25zKTtcblxuICAgICAgdGhpcy50aXRsZSA9IHRoaXMuZ2V0VGl0bGUodG9vbHRpcEl0ZW1zLCBvcHRpb25zKTtcbiAgICAgIHRoaXMuYmVmb3JlQm9keSA9IHRoaXMuZ2V0QmVmb3JlQm9keSh0b29sdGlwSXRlbXMsIG9wdGlvbnMpO1xuICAgICAgdGhpcy5ib2R5ID0gdGhpcy5nZXRCb2R5KHRvb2x0aXBJdGVtcywgb3B0aW9ucyk7XG4gICAgICB0aGlzLmFmdGVyQm9keSA9IHRoaXMuZ2V0QWZ0ZXJCb2R5KHRvb2x0aXBJdGVtcywgb3B0aW9ucyk7XG4gICAgICB0aGlzLmZvb3RlciA9IHRoaXMuZ2V0Rm9vdGVyKHRvb2x0aXBJdGVtcywgb3B0aW9ucyk7XG5cbiAgICAgIGNvbnN0IHNpemUgPSB0aGlzLl9zaXplID0gZ2V0VG9vbHRpcFNpemUodGhpcywgb3B0aW9ucyk7XG4gICAgICBjb25zdCBwb3NpdGlvbkFuZFNpemUgPSBPYmplY3QuYXNzaWduKHt9LCBwb3NpdGlvbiwgc2l6ZSk7XG4gICAgICBjb25zdCBhbGlnbm1lbnQgPSBkZXRlcm1pbmVBbGlnbm1lbnQodGhpcy5jaGFydCwgb3B0aW9ucywgcG9zaXRpb25BbmRTaXplKTtcbiAgICAgIGNvbnN0IGJhY2tncm91bmRQb2ludCA9IGdldEJhY2tncm91bmRQb2ludChvcHRpb25zLCBwb3NpdGlvbkFuZFNpemUsIGFsaWdubWVudCwgdGhpcy5jaGFydCk7XG5cbiAgICAgIHRoaXMueEFsaWduID0gYWxpZ25tZW50LnhBbGlnbjtcbiAgICAgIHRoaXMueUFsaWduID0gYWxpZ25tZW50LnlBbGlnbjtcblxuICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgb3BhY2l0eTogMSxcbiAgICAgICAgeDogYmFja2dyb3VuZFBvaW50LngsXG4gICAgICAgIHk6IGJhY2tncm91bmRQb2ludC55LFxuICAgICAgICB3aWR0aDogc2l6ZS53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBzaXplLmhlaWdodCxcbiAgICAgICAgY2FyZXRYOiBwb3NpdGlvbi54LFxuICAgICAgICBjYXJldFk6IHBvc2l0aW9uLnlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5fdG9vbHRpcEl0ZW1zID0gdG9vbHRpcEl0ZW1zO1xuICAgIHRoaXMuJGNvbnRleHQgPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAocHJvcGVydGllcykge1xuICAgICAgdGhpcy5fcmVzb2x2ZUFuaW1hdGlvbnMoKS51cGRhdGUodGhpcywgcHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZWQgJiYgb3B0aW9ucy5leHRlcm5hbCkge1xuICAgICAgb3B0aW9ucy5leHRlcm5hbC5jYWxsKHRoaXMsIHtjaGFydDogdGhpcy5jaGFydCwgdG9vbHRpcDogdGhpcywgcmVwbGF5fSk7XG4gICAgfVxuICB9XG5cbiAgZHJhd0NhcmV0KHRvb2x0aXBQb2ludCwgY3R4LCBzaXplLCBvcHRpb25zKSB7XG4gICAgY29uc3QgY2FyZXRQb3NpdGlvbiA9IHRoaXMuZ2V0Q2FyZXRQb3NpdGlvbih0b29sdGlwUG9pbnQsIHNpemUsIG9wdGlvbnMpO1xuXG4gICAgY3R4LmxpbmVUbyhjYXJldFBvc2l0aW9uLngxLCBjYXJldFBvc2l0aW9uLnkxKTtcbiAgICBjdHgubGluZVRvKGNhcmV0UG9zaXRpb24ueDIsIGNhcmV0UG9zaXRpb24ueTIpO1xuICAgIGN0eC5saW5lVG8oY2FyZXRQb3NpdGlvbi54MywgY2FyZXRQb3NpdGlvbi55Myk7XG4gIH1cblxuICBnZXRDYXJldFBvc2l0aW9uKHRvb2x0aXBQb2ludCwgc2l6ZSwgb3B0aW9ucykge1xuICAgIGNvbnN0IHt4QWxpZ24sIHlBbGlnbn0gPSB0aGlzO1xuICAgIGNvbnN0IHtjYXJldFNpemUsIGNvcm5lclJhZGl1c30gPSBvcHRpb25zO1xuICAgIGNvbnN0IHt0b3BMZWZ0LCB0b3BSaWdodCwgYm90dG9tTGVmdCwgYm90dG9tUmlnaHR9ID0gdG9UUkJMQ29ybmVycyhjb3JuZXJSYWRpdXMpO1xuICAgIGNvbnN0IHt4OiBwdFgsIHk6IHB0WX0gPSB0b29sdGlwUG9pbnQ7XG4gICAgY29uc3Qge3dpZHRoLCBoZWlnaHR9ID0gc2l6ZTtcbiAgICBsZXQgeDEsIHgyLCB4MywgeTEsIHkyLCB5MztcblxuICAgIGlmICh5QWxpZ24gPT09ICdjZW50ZXInKSB7XG4gICAgICB5MiA9IHB0WSArIChoZWlnaHQgLyAyKTtcblxuICAgICAgaWYgKHhBbGlnbiA9PT0gJ2xlZnQnKSB7XG4gICAgICAgIHgxID0gcHRYO1xuICAgICAgICB4MiA9IHgxIC0gY2FyZXRTaXplO1xuXG4gICAgICAgIC8vIExlZnQgZHJhd3MgYm90dG9tIC0+IHRvcCwgdGhpcyB5MSBpcyBvbiB0aGUgYm90dG9tXG4gICAgICAgIHkxID0geTIgKyBjYXJldFNpemU7XG4gICAgICAgIHkzID0geTIgLSBjYXJldFNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4MSA9IHB0WCArIHdpZHRoO1xuICAgICAgICB4MiA9IHgxICsgY2FyZXRTaXplO1xuXG4gICAgICAgIC8vIFJpZ2h0IGRyYXdzIHRvcCAtPiBib3R0b20sIHRodXMgeTEgaXMgb24gdGhlIHRvcFxuICAgICAgICB5MSA9IHkyIC0gY2FyZXRTaXplO1xuICAgICAgICB5MyA9IHkyICsgY2FyZXRTaXplO1xuICAgICAgfVxuXG4gICAgICB4MyA9IHgxO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoeEFsaWduID09PSAnbGVmdCcpIHtcbiAgICAgICAgeDIgPSBwdFggKyBNYXRoLm1heCh0b3BMZWZ0LCBib3R0b21MZWZ0KSArIChjYXJldFNpemUpO1xuICAgICAgfSBlbHNlIGlmICh4QWxpZ24gPT09ICdyaWdodCcpIHtcbiAgICAgICAgeDIgPSBwdFggKyB3aWR0aCAtIE1hdGgubWF4KHRvcFJpZ2h0LCBib3R0b21SaWdodCkgLSBjYXJldFNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4MiA9IHRoaXMuY2FyZXRYO1xuICAgICAgfVxuXG4gICAgICBpZiAoeUFsaWduID09PSAndG9wJykge1xuICAgICAgICB5MSA9IHB0WTtcbiAgICAgICAgeTIgPSB5MSAtIGNhcmV0U2l6ZTtcblxuICAgICAgICAvLyBUb3AgZHJhd3MgbGVmdCAtPiByaWdodCwgdGh1cyB4MSBpcyBvbiB0aGUgbGVmdFxuICAgICAgICB4MSA9IHgyIC0gY2FyZXRTaXplO1xuICAgICAgICB4MyA9IHgyICsgY2FyZXRTaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeTEgPSBwdFkgKyBoZWlnaHQ7XG4gICAgICAgIHkyID0geTEgKyBjYXJldFNpemU7XG5cbiAgICAgICAgLy8gQm90dG9tIGRyYXdzIHJpZ2h0IC0+IGxlZnQsIHRodXMgeDEgaXMgb24gdGhlIHJpZ2h0XG4gICAgICAgIHgxID0geDIgKyBjYXJldFNpemU7XG4gICAgICAgIHgzID0geDIgLSBjYXJldFNpemU7XG4gICAgICB9XG4gICAgICB5MyA9IHkxO1xuICAgIH1cbiAgICByZXR1cm4ge3gxLCB4MiwgeDMsIHkxLCB5MiwgeTN9O1xuICB9XG5cbiAgZHJhd1RpdGxlKHB0LCBjdHgsIG9wdGlvbnMpIHtcbiAgICBjb25zdCB0aXRsZSA9IHRoaXMudGl0bGU7XG4gICAgY29uc3QgbGVuZ3RoID0gdGl0bGUubGVuZ3RoO1xuICAgIGxldCB0aXRsZUZvbnQsIHRpdGxlU3BhY2luZywgaTtcblxuICAgIGlmIChsZW5ndGgpIHtcbiAgICAgIGNvbnN0IHJ0bEhlbHBlciA9IGdldFJ0bEFkYXB0ZXIob3B0aW9ucy5ydGwsIHRoaXMueCwgdGhpcy53aWR0aCk7XG5cbiAgICAgIHB0LnggPSBnZXRBbGlnbmVkWCh0aGlzLCBvcHRpb25zLnRpdGxlQWxpZ24sIG9wdGlvbnMpO1xuXG4gICAgICBjdHgudGV4dEFsaWduID0gcnRsSGVscGVyLnRleHRBbGlnbihvcHRpb25zLnRpdGxlQWxpZ24pO1xuICAgICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuXG4gICAgICB0aXRsZUZvbnQgPSB0b0ZvbnQob3B0aW9ucy50aXRsZUZvbnQpO1xuICAgICAgdGl0bGVTcGFjaW5nID0gb3B0aW9ucy50aXRsZVNwYWNpbmc7XG5cbiAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLnRpdGxlQ29sb3I7XG4gICAgICBjdHguZm9udCA9IHRpdGxlRm9udC5zdHJpbmc7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgICAgICBjdHguZmlsbFRleHQodGl0bGVbaV0sIHJ0bEhlbHBlci54KHB0LngpLCBwdC55ICsgdGl0bGVGb250LmxpbmVIZWlnaHQgLyAyKTtcbiAgICAgICAgcHQueSArPSB0aXRsZUZvbnQubGluZUhlaWdodCArIHRpdGxlU3BhY2luZzsgLy8gTGluZSBIZWlnaHQgYW5kIHNwYWNpbmdcblxuICAgICAgICBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIHB0LnkgKz0gb3B0aW9ucy50aXRsZU1hcmdpbkJvdHRvbSAtIHRpdGxlU3BhY2luZzsgLy8gSWYgTGFzdCwgYWRkIG1hcmdpbiwgcmVtb3ZlIHNwYWNpbmdcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2RyYXdDb2xvckJveChjdHgsIHB0LCBpLCBydGxIZWxwZXIsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBsYWJlbENvbG9yID0gdGhpcy5sYWJlbENvbG9yc1tpXTtcbiAgICBjb25zdCBsYWJlbFBvaW50U3R5bGUgPSB0aGlzLmxhYmVsUG9pbnRTdHlsZXNbaV07XG4gICAgY29uc3Qge2JveEhlaWdodCwgYm94V2lkdGh9ID0gb3B0aW9ucztcbiAgICBjb25zdCBib2R5Rm9udCA9IHRvRm9udChvcHRpb25zLmJvZHlGb250KTtcbiAgICBjb25zdCBjb2xvclggPSBnZXRBbGlnbmVkWCh0aGlzLCAnbGVmdCcsIG9wdGlvbnMpO1xuICAgIGNvbnN0IHJ0bENvbG9yWCA9IHJ0bEhlbHBlci54KGNvbG9yWCk7XG4gICAgY29uc3QgeU9mZlNldCA9IGJveEhlaWdodCA8IGJvZHlGb250LmxpbmVIZWlnaHQgPyAoYm9keUZvbnQubGluZUhlaWdodCAtIGJveEhlaWdodCkgLyAyIDogMDtcbiAgICBjb25zdCBjb2xvclkgPSBwdC55ICsgeU9mZlNldDtcblxuICAgIGlmIChvcHRpb25zLnVzZVBvaW50U3R5bGUpIHtcbiAgICAgIGNvbnN0IGRyYXdPcHRpb25zID0ge1xuICAgICAgICByYWRpdXM6IE1hdGgubWluKGJveFdpZHRoLCBib3hIZWlnaHQpIC8gMiwgLy8gZml0IHRoZSBjaXJjbGUgaW4gdGhlIGJveFxuICAgICAgICBwb2ludFN0eWxlOiBsYWJlbFBvaW50U3R5bGUucG9pbnRTdHlsZSxcbiAgICAgICAgcm90YXRpb246IGxhYmVsUG9pbnRTdHlsZS5yb3RhdGlvbixcbiAgICAgICAgYm9yZGVyV2lkdGg6IDFcbiAgICAgIH07XG4gICAgICAvLyBSZWNhbGN1bGF0ZSB4IGFuZCB5IGZvciBkcmF3UG9pbnQoKSBiZWNhdXNlIGl0cyBleHBlY3RpbmdcbiAgICAgIC8vIHggYW5kIHkgdG8gYmUgY2VudGVyIG9mIGZpZ3VyZSAoaW5zdGVhZCBvZiB0b3AgbGVmdClcbiAgICAgIGNvbnN0IGNlbnRlclggPSBydGxIZWxwZXIubGVmdEZvckx0cihydGxDb2xvclgsIGJveFdpZHRoKSArIGJveFdpZHRoIC8gMjtcbiAgICAgIGNvbnN0IGNlbnRlclkgPSBjb2xvclkgKyBib3hIZWlnaHQgLyAyO1xuXG4gICAgICAvLyBGaWxsIHRoZSBwb2ludCB3aXRoIHdoaXRlIHNvIHRoYXQgY29sb3VycyBtZXJnZSBuaWNlbHkgaWYgdGhlIG9wYWNpdHkgaXMgPCAxXG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSBvcHRpb25zLm11bHRpS2V5QmFja2dyb3VuZDtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBvcHRpb25zLm11bHRpS2V5QmFja2dyb3VuZDtcbiAgICAgIGRyYXdQb2ludChjdHgsIGRyYXdPcHRpb25zLCBjZW50ZXJYLCBjZW50ZXJZKTtcblxuICAgICAgLy8gRHJhdyB0aGUgcG9pbnRcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IGxhYmVsQ29sb3IuYm9yZGVyQ29sb3I7XG4gICAgICBjdHguZmlsbFN0eWxlID0gbGFiZWxDb2xvci5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICBkcmF3UG9pbnQoY3R4LCBkcmF3T3B0aW9ucywgY2VudGVyWCwgY2VudGVyWSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEJvcmRlclxuICAgICAgY3R4LmxpbmVXaWR0aCA9IGlzT2JqZWN0KGxhYmVsQ29sb3IuYm9yZGVyV2lkdGgpID8gTWF0aC5tYXgoLi4uT2JqZWN0LnZhbHVlcyhsYWJlbENvbG9yLmJvcmRlcldpZHRoKSkgOiAobGFiZWxDb2xvci5ib3JkZXJXaWR0aCB8fCAxKTsgLy8gVE9ETywgdjQgcmVtb3ZlIGZhbGxiYWNrXG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSBsYWJlbENvbG9yLmJvcmRlckNvbG9yO1xuICAgICAgY3R4LnNldExpbmVEYXNoKGxhYmVsQ29sb3IuYm9yZGVyRGFzaCB8fCBbXSk7XG4gICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBsYWJlbENvbG9yLmJvcmRlckRhc2hPZmZzZXQgfHwgMDtcblxuICAgICAgLy8gRmlsbCBhIHdoaXRlIHJlY3Qgc28gdGhhdCBjb2xvdXJzIG1lcmdlIG5pY2VseSBpZiB0aGUgb3BhY2l0eSBpcyA8IDFcbiAgICAgIGNvbnN0IG91dGVyWCA9IHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHJ0bENvbG9yWCwgYm94V2lkdGgpO1xuICAgICAgY29uc3QgaW5uZXJYID0gcnRsSGVscGVyLmxlZnRGb3JMdHIocnRsSGVscGVyLnhQbHVzKHJ0bENvbG9yWCwgMSksIGJveFdpZHRoIC0gMik7XG4gICAgICBjb25zdCBib3JkZXJSYWRpdXMgPSB0b1RSQkxDb3JuZXJzKGxhYmVsQ29sb3IuYm9yZGVyUmFkaXVzKTtcblxuICAgICAgaWYgKE9iamVjdC52YWx1ZXMoYm9yZGVyUmFkaXVzKS5zb21lKHYgPT4gdiAhPT0gMCkpIHtcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBjdHguZmlsbFN0eWxlID0gb3B0aW9ucy5tdWx0aUtleUJhY2tncm91bmQ7XG4gICAgICAgIGFkZFJvdW5kZWRSZWN0UGF0aChjdHgsIHtcbiAgICAgICAgICB4OiBvdXRlclgsXG4gICAgICAgICAgeTogY29sb3JZLFxuICAgICAgICAgIHc6IGJveFdpZHRoLFxuICAgICAgICAgIGg6IGJveEhlaWdodCxcbiAgICAgICAgICByYWRpdXM6IGJvcmRlclJhZGl1cyxcbiAgICAgICAgfSk7XG4gICAgICAgIGN0eC5maWxsKCk7XG4gICAgICAgIGN0eC5zdHJva2UoKTtcblxuICAgICAgICAvLyBJbm5lciBzcXVhcmVcbiAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGxhYmVsQ29sb3IuYmFja2dyb3VuZENvbG9yO1xuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIGFkZFJvdW5kZWRSZWN0UGF0aChjdHgsIHtcbiAgICAgICAgICB4OiBpbm5lclgsXG4gICAgICAgICAgeTogY29sb3JZICsgMSxcbiAgICAgICAgICB3OiBib3hXaWR0aCAtIDIsXG4gICAgICAgICAgaDogYm94SGVpZ2h0IC0gMixcbiAgICAgICAgICByYWRpdXM6IGJvcmRlclJhZGl1cyxcbiAgICAgICAgfSk7XG4gICAgICAgIGN0eC5maWxsKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBOb3JtYWwgcmVjdFxuICAgICAgICBjdHguZmlsbFN0eWxlID0gb3B0aW9ucy5tdWx0aUtleUJhY2tncm91bmQ7XG4gICAgICAgIGN0eC5maWxsUmVjdChvdXRlclgsIGNvbG9yWSwgYm94V2lkdGgsIGJveEhlaWdodCk7XG4gICAgICAgIGN0eC5zdHJva2VSZWN0KG91dGVyWCwgY29sb3JZLCBib3hXaWR0aCwgYm94SGVpZ2h0KTtcbiAgICAgICAgLy8gSW5uZXIgc3F1YXJlXG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSBsYWJlbENvbG9yLmJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgY3R4LmZpbGxSZWN0KGlubmVyWCwgY29sb3JZICsgMSwgYm94V2lkdGggLSAyLCBib3hIZWlnaHQgLSAyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyByZXN0b3JlIGZpbGxTdHlsZVxuICAgIGN0eC5maWxsU3R5bGUgPSB0aGlzLmxhYmVsVGV4dENvbG9yc1tpXTtcbiAgfVxuXG4gIGRyYXdCb2R5KHB0LCBjdHgsIG9wdGlvbnMpIHtcbiAgICBjb25zdCB7Ym9keX0gPSB0aGlzO1xuICAgIGNvbnN0IHtib2R5U3BhY2luZywgYm9keUFsaWduLCBkaXNwbGF5Q29sb3JzLCBib3hIZWlnaHQsIGJveFdpZHRoLCBib3hQYWRkaW5nfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgYm9keUZvbnQgPSB0b0ZvbnQob3B0aW9ucy5ib2R5Rm9udCk7XG4gICAgbGV0IGJvZHlMaW5lSGVpZ2h0ID0gYm9keUZvbnQubGluZUhlaWdodDtcbiAgICBsZXQgeExpbmVQYWRkaW5nID0gMDtcblxuICAgIGNvbnN0IHJ0bEhlbHBlciA9IGdldFJ0bEFkYXB0ZXIob3B0aW9ucy5ydGwsIHRoaXMueCwgdGhpcy53aWR0aCk7XG5cbiAgICBjb25zdCBmaWxsTGluZU9mVGV4dCA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgIGN0eC5maWxsVGV4dChsaW5lLCBydGxIZWxwZXIueChwdC54ICsgeExpbmVQYWRkaW5nKSwgcHQueSArIGJvZHlMaW5lSGVpZ2h0IC8gMik7XG4gICAgICBwdC55ICs9IGJvZHlMaW5lSGVpZ2h0ICsgYm9keVNwYWNpbmc7XG4gICAgfTtcblxuICAgIGNvbnN0IGJvZHlBbGlnbkZvckNhbGN1bGF0aW9uID0gcnRsSGVscGVyLnRleHRBbGlnbihib2R5QWxpZ24pO1xuICAgIGxldCBib2R5SXRlbSwgdGV4dENvbG9yLCBsaW5lcywgaSwgaiwgaWxlbiwgamxlbjtcblxuICAgIGN0eC50ZXh0QWxpZ24gPSBib2R5QWxpZ247XG4gICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuICAgIGN0eC5mb250ID0gYm9keUZvbnQuc3RyaW5nO1xuXG4gICAgcHQueCA9IGdldEFsaWduZWRYKHRoaXMsIGJvZHlBbGlnbkZvckNhbGN1bGF0aW9uLCBvcHRpb25zKTtcblxuICAgIC8vIEJlZm9yZSBib2R5IGxpbmVzXG4gICAgY3R4LmZpbGxTdHlsZSA9IG9wdGlvbnMuYm9keUNvbG9yO1xuICAgIGVhY2godGhpcy5iZWZvcmVCb2R5LCBmaWxsTGluZU9mVGV4dCk7XG5cbiAgICB4TGluZVBhZGRpbmcgPSBkaXNwbGF5Q29sb3JzICYmIGJvZHlBbGlnbkZvckNhbGN1bGF0aW9uICE9PSAncmlnaHQnXG4gICAgICA/IGJvZHlBbGlnbiA9PT0gJ2NlbnRlcicgPyAoYm94V2lkdGggLyAyICsgYm94UGFkZGluZykgOiAoYm94V2lkdGggKyAyICsgYm94UGFkZGluZylcbiAgICAgIDogMDtcblxuICAgIC8vIERyYXcgYm9keSBsaW5lcyBub3dcbiAgICBmb3IgKGkgPSAwLCBpbGVuID0gYm9keS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIGJvZHlJdGVtID0gYm9keVtpXTtcbiAgICAgIHRleHRDb2xvciA9IHRoaXMubGFiZWxUZXh0Q29sb3JzW2ldO1xuXG4gICAgICBjdHguZmlsbFN0eWxlID0gdGV4dENvbG9yO1xuICAgICAgZWFjaChib2R5SXRlbS5iZWZvcmUsIGZpbGxMaW5lT2ZUZXh0KTtcblxuICAgICAgbGluZXMgPSBib2R5SXRlbS5saW5lcztcbiAgICAgIC8vIERyYXcgTGVnZW5kLWxpa2UgYm94ZXMgaWYgbmVlZGVkXG4gICAgICBpZiAoZGlzcGxheUNvbG9ycyAmJiBsaW5lcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5fZHJhd0NvbG9yQm94KGN0eCwgcHQsIGksIHJ0bEhlbHBlciwgb3B0aW9ucyk7XG4gICAgICAgIGJvZHlMaW5lSGVpZ2h0ID0gTWF0aC5tYXgoYm9keUZvbnQubGluZUhlaWdodCwgYm94SGVpZ2h0KTtcbiAgICAgIH1cblxuICAgICAgZm9yIChqID0gMCwgamxlbiA9IGxpbmVzLmxlbmd0aDsgaiA8IGpsZW47ICsraikge1xuICAgICAgICBmaWxsTGluZU9mVGV4dChsaW5lc1tqXSk7XG4gICAgICAgIC8vIFJlc2V0IGZvciBhbnkgbGluZXMgdGhhdCBkb24ndCBpbmNsdWRlIGNvbG9yYm94XG4gICAgICAgIGJvZHlMaW5lSGVpZ2h0ID0gYm9keUZvbnQubGluZUhlaWdodDtcbiAgICAgIH1cblxuICAgICAgZWFjaChib2R5SXRlbS5hZnRlciwgZmlsbExpbmVPZlRleHQpO1xuICAgIH1cblxuICAgIC8vIFJlc2V0IGJhY2sgdG8gMCBmb3IgYWZ0ZXIgYm9keVxuICAgIHhMaW5lUGFkZGluZyA9IDA7XG4gICAgYm9keUxpbmVIZWlnaHQgPSBib2R5Rm9udC5saW5lSGVpZ2h0O1xuXG4gICAgLy8gQWZ0ZXIgYm9keSBsaW5lc1xuICAgIGVhY2godGhpcy5hZnRlckJvZHksIGZpbGxMaW5lT2ZUZXh0KTtcbiAgICBwdC55IC09IGJvZHlTcGFjaW5nOyAvLyBSZW1vdmUgbGFzdCBib2R5IHNwYWNpbmdcbiAgfVxuXG4gIGRyYXdGb290ZXIocHQsIGN0eCwgb3B0aW9ucykge1xuICAgIGNvbnN0IGZvb3RlciA9IHRoaXMuZm9vdGVyO1xuICAgIGNvbnN0IGxlbmd0aCA9IGZvb3Rlci5sZW5ndGg7XG4gICAgbGV0IGZvb3RlckZvbnQsIGk7XG5cbiAgICBpZiAobGVuZ3RoKSB7XG4gICAgICBjb25zdCBydGxIZWxwZXIgPSBnZXRSdGxBZGFwdGVyKG9wdGlvbnMucnRsLCB0aGlzLngsIHRoaXMud2lkdGgpO1xuXG4gICAgICBwdC54ID0gZ2V0QWxpZ25lZFgodGhpcywgb3B0aW9ucy5mb290ZXJBbGlnbiwgb3B0aW9ucyk7XG4gICAgICBwdC55ICs9IG9wdGlvbnMuZm9vdGVyTWFyZ2luVG9wO1xuXG4gICAgICBjdHgudGV4dEFsaWduID0gcnRsSGVscGVyLnRleHRBbGlnbihvcHRpb25zLmZvb3RlckFsaWduKTtcbiAgICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcblxuICAgICAgZm9vdGVyRm9udCA9IHRvRm9udChvcHRpb25zLmZvb3RlckZvbnQpO1xuXG4gICAgICBjdHguZmlsbFN0eWxlID0gb3B0aW9ucy5mb290ZXJDb2xvcjtcbiAgICAgIGN0eC5mb250ID0gZm9vdGVyRm9udC5zdHJpbmc7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgICAgICBjdHguZmlsbFRleHQoZm9vdGVyW2ldLCBydGxIZWxwZXIueChwdC54KSwgcHQueSArIGZvb3RlckZvbnQubGluZUhlaWdodCAvIDIpO1xuICAgICAgICBwdC55ICs9IGZvb3RlckZvbnQubGluZUhlaWdodCArIG9wdGlvbnMuZm9vdGVyU3BhY2luZztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBkcmF3QmFja2dyb3VuZChwdCwgY3R4LCB0b29sdGlwU2l6ZSwgb3B0aW9ucykge1xuICAgIGNvbnN0IHt4QWxpZ24sIHlBbGlnbn0gPSB0aGlzO1xuICAgIGNvbnN0IHt4LCB5fSA9IHB0O1xuICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0fSA9IHRvb2x0aXBTaXplO1xuICAgIGNvbnN0IHt0b3BMZWZ0LCB0b3BSaWdodCwgYm90dG9tTGVmdCwgYm90dG9tUmlnaHR9ID0gdG9UUkJMQ29ybmVycyhvcHRpb25zLmNvcm5lclJhZGl1cyk7XG5cbiAgICBjdHguZmlsbFN0eWxlID0gb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgY3R4LnN0cm9rZVN0eWxlID0gb3B0aW9ucy5ib3JkZXJDb2xvcjtcbiAgICBjdHgubGluZVdpZHRoID0gb3B0aW9ucy5ib3JkZXJXaWR0aDtcblxuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHgubW92ZVRvKHggKyB0b3BMZWZ0LCB5KTtcbiAgICBpZiAoeUFsaWduID09PSAndG9wJykge1xuICAgICAgdGhpcy5kcmF3Q2FyZXQocHQsIGN0eCwgdG9vbHRpcFNpemUsIG9wdGlvbnMpO1xuICAgIH1cbiAgICBjdHgubGluZVRvKHggKyB3aWR0aCAtIHRvcFJpZ2h0LCB5KTtcbiAgICBjdHgucXVhZHJhdGljQ3VydmVUbyh4ICsgd2lkdGgsIHksIHggKyB3aWR0aCwgeSArIHRvcFJpZ2h0KTtcbiAgICBpZiAoeUFsaWduID09PSAnY2VudGVyJyAmJiB4QWxpZ24gPT09ICdyaWdodCcpIHtcbiAgICAgIHRoaXMuZHJhd0NhcmV0KHB0LCBjdHgsIHRvb2x0aXBTaXplLCBvcHRpb25zKTtcbiAgICB9XG4gICAgY3R4LmxpbmVUbyh4ICsgd2lkdGgsIHkgKyBoZWlnaHQgLSBib3R0b21SaWdodCk7XG4gICAgY3R4LnF1YWRyYXRpY0N1cnZlVG8oeCArIHdpZHRoLCB5ICsgaGVpZ2h0LCB4ICsgd2lkdGggLSBib3R0b21SaWdodCwgeSArIGhlaWdodCk7XG4gICAgaWYgKHlBbGlnbiA9PT0gJ2JvdHRvbScpIHtcbiAgICAgIHRoaXMuZHJhd0NhcmV0KHB0LCBjdHgsIHRvb2x0aXBTaXplLCBvcHRpb25zKTtcbiAgICB9XG4gICAgY3R4LmxpbmVUbyh4ICsgYm90dG9tTGVmdCwgeSArIGhlaWdodCk7XG4gICAgY3R4LnF1YWRyYXRpY0N1cnZlVG8oeCwgeSArIGhlaWdodCwgeCwgeSArIGhlaWdodCAtIGJvdHRvbUxlZnQpO1xuICAgIGlmICh5QWxpZ24gPT09ICdjZW50ZXInICYmIHhBbGlnbiA9PT0gJ2xlZnQnKSB7XG4gICAgICB0aGlzLmRyYXdDYXJldChwdCwgY3R4LCB0b29sdGlwU2l6ZSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIGN0eC5saW5lVG8oeCwgeSArIHRvcExlZnQpO1xuICAgIGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHgsIHksIHggKyB0b3BMZWZ0LCB5KTtcbiAgICBjdHguY2xvc2VQYXRoKCk7XG5cbiAgICBjdHguZmlsbCgpO1xuXG4gICAgaWYgKG9wdGlvbnMuYm9yZGVyV2lkdGggPiAwKSB7XG4gICAgICBjdHguc3Ryb2tlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG5cdCAqIFVwZGF0ZSB4L3kgYW5pbWF0aW9uIHRhcmdldHMgd2hlbiBfYWN0aXZlIGVsZW1lbnRzIGFyZSBhbmltYXRpbmcgdG9vXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfdXBkYXRlQW5pbWF0aW9uVGFyZ2V0KG9wdGlvbnMpIHtcbiAgICBjb25zdCBjaGFydCA9IHRoaXMuY2hhcnQ7XG4gICAgY29uc3QgYW5pbXMgPSB0aGlzLiRhbmltYXRpb25zO1xuICAgIGNvbnN0IGFuaW1YID0gYW5pbXMgJiYgYW5pbXMueDtcbiAgICBjb25zdCBhbmltWSA9IGFuaW1zICYmIGFuaW1zLnk7XG4gICAgaWYgKGFuaW1YIHx8IGFuaW1ZKSB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IHBvc2l0aW9uZXJzW29wdGlvbnMucG9zaXRpb25dLmNhbGwodGhpcywgdGhpcy5fYWN0aXZlLCB0aGlzLl9ldmVudFBvc2l0aW9uKTtcbiAgICAgIGlmICghcG9zaXRpb24pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuX3NpemUgPSBnZXRUb29sdGlwU2l6ZSh0aGlzLCBvcHRpb25zKTtcbiAgICAgIGNvbnN0IHBvc2l0aW9uQW5kU2l6ZSA9IE9iamVjdC5hc3NpZ24oe30sIHBvc2l0aW9uLCB0aGlzLl9zaXplKTtcbiAgICAgIGNvbnN0IGFsaWdubWVudCA9IGRldGVybWluZUFsaWdubWVudChjaGFydCwgb3B0aW9ucywgcG9zaXRpb25BbmRTaXplKTtcbiAgICAgIGNvbnN0IHBvaW50ID0gZ2V0QmFja2dyb3VuZFBvaW50KG9wdGlvbnMsIHBvc2l0aW9uQW5kU2l6ZSwgYWxpZ25tZW50LCBjaGFydCk7XG4gICAgICBpZiAoYW5pbVguX3RvICE9PSBwb2ludC54IHx8IGFuaW1ZLl90byAhPT0gcG9pbnQueSkge1xuICAgICAgICB0aGlzLnhBbGlnbiA9IGFsaWdubWVudC54QWxpZ247XG4gICAgICAgIHRoaXMueUFsaWduID0gYWxpZ25tZW50LnlBbGlnbjtcbiAgICAgICAgdGhpcy53aWR0aCA9IHNpemUud2lkdGg7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gc2l6ZS5oZWlnaHQ7XG4gICAgICAgIHRoaXMuY2FyZXRYID0gcG9zaXRpb24ueDtcbiAgICAgICAgdGhpcy5jYXJldFkgPSBwb3NpdGlvbi55O1xuICAgICAgICB0aGlzLl9yZXNvbHZlQW5pbWF0aW9ucygpLnVwZGF0ZSh0aGlzLCBwb2ludCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSBpZiB0aGUgdG9vbHRpcCB3aWxsIGRyYXcgYW55dGhpbmdcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHRvb2x0aXAgd2lsbCByZW5kZXJcbiAgICovXG4gIF93aWxsUmVuZGVyKCkge1xuICAgIHJldHVybiAhIXRoaXMub3BhY2l0eTtcbiAgfVxuXG4gIGRyYXcoY3R4KSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucy5zZXRDb250ZXh0KHRoaXMuZ2V0Q29udGV4dCgpKTtcbiAgICBsZXQgb3BhY2l0eSA9IHRoaXMub3BhY2l0eTtcblxuICAgIGlmICghb3BhY2l0eSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3VwZGF0ZUFuaW1hdGlvblRhcmdldChvcHRpb25zKTtcblxuICAgIGNvbnN0IHRvb2x0aXBTaXplID0ge1xuICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0XG4gICAgfTtcbiAgICBjb25zdCBwdCA9IHtcbiAgICAgIHg6IHRoaXMueCxcbiAgICAgIHk6IHRoaXMueVxuICAgIH07XG5cbiAgICAvLyBJRTExL0VkZ2UgZG9lcyBub3QgbGlrZSB2ZXJ5IHNtYWxsIG9wYWNpdGllcywgc28gc25hcCB0byAwXG4gICAgb3BhY2l0eSA9IE1hdGguYWJzKG9wYWNpdHkpIDwgMWUtMyA/IDAgOiBvcGFjaXR5O1xuXG4gICAgY29uc3QgcGFkZGluZyA9IHRvUGFkZGluZyhvcHRpb25zLnBhZGRpbmcpO1xuXG4gICAgLy8gVHJ1dGh5L2ZhbHNleSB2YWx1ZSBmb3IgZW1wdHkgdG9vbHRpcFxuICAgIGNvbnN0IGhhc1Rvb2x0aXBDb250ZW50ID0gdGhpcy50aXRsZS5sZW5ndGggfHwgdGhpcy5iZWZvcmVCb2R5Lmxlbmd0aCB8fCB0aGlzLmJvZHkubGVuZ3RoIHx8IHRoaXMuYWZ0ZXJCb2R5Lmxlbmd0aCB8fCB0aGlzLmZvb3Rlci5sZW5ndGg7XG5cbiAgICBpZiAob3B0aW9ucy5lbmFibGVkICYmIGhhc1Rvb2x0aXBDb250ZW50KSB7XG4gICAgICBjdHguc2F2ZSgpO1xuICAgICAgY3R4Lmdsb2JhbEFscGhhID0gb3BhY2l0eTtcblxuICAgICAgLy8gRHJhdyBCYWNrZ3JvdW5kXG4gICAgICB0aGlzLmRyYXdCYWNrZ3JvdW5kKHB0LCBjdHgsIHRvb2x0aXBTaXplLCBvcHRpb25zKTtcblxuICAgICAgb3ZlcnJpZGVUZXh0RGlyZWN0aW9uKGN0eCwgb3B0aW9ucy50ZXh0RGlyZWN0aW9uKTtcblxuICAgICAgcHQueSArPSBwYWRkaW5nLnRvcDtcblxuICAgICAgLy8gVGl0bGVzXG4gICAgICB0aGlzLmRyYXdUaXRsZShwdCwgY3R4LCBvcHRpb25zKTtcblxuICAgICAgLy8gQm9keVxuICAgICAgdGhpcy5kcmF3Qm9keShwdCwgY3R4LCBvcHRpb25zKTtcblxuICAgICAgLy8gRm9vdGVyXG4gICAgICB0aGlzLmRyYXdGb290ZXIocHQsIGN0eCwgb3B0aW9ucyk7XG5cbiAgICAgIHJlc3RvcmVUZXh0RGlyZWN0aW9uKGN0eCwgb3B0aW9ucy50ZXh0RGlyZWN0aW9uKTtcblxuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogR2V0IGFjdGl2ZSBlbGVtZW50cyBpbiB0aGUgdG9vbHRpcFxuXHQgKiBAcmV0dXJucyB7QXJyYXl9IEFycmF5IG9mIGVsZW1lbnRzIHRoYXQgYXJlIGFjdGl2ZSBpbiB0aGUgdG9vbHRpcFxuXHQgKi9cbiAgZ2V0QWN0aXZlRWxlbWVudHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZSB8fCBbXTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBTZXQgYWN0aXZlIGVsZW1lbnRzIGluIHRoZSB0b29sdGlwXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGFjdGl2ZUVsZW1lbnRzIEFycmF5IG9mIGFjdGl2ZSBkYXRhc2V0SW5kZXgvaW5kZXggcGFpcnMuXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBldmVudFBvc2l0aW9uIFN5bnRoZXRpYyBldmVudCBwb3NpdGlvbiB1c2VkIGluIHBvc2l0aW9uaW5nXG5cdCAqL1xuICBzZXRBY3RpdmVFbGVtZW50cyhhY3RpdmVFbGVtZW50cywgZXZlbnRQb3NpdGlvbikge1xuICAgIGNvbnN0IGxhc3RBY3RpdmUgPSB0aGlzLl9hY3RpdmU7XG4gICAgY29uc3QgYWN0aXZlID0gYWN0aXZlRWxlbWVudHMubWFwKCh7ZGF0YXNldEluZGV4LCBpbmRleH0pID0+IHtcbiAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLmNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XG5cbiAgICAgIGlmICghbWV0YSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIGEgZGF0YXNldCBhdCBpbmRleCAnICsgZGF0YXNldEluZGV4KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YXNldEluZGV4LFxuICAgICAgICBlbGVtZW50OiBtZXRhLmRhdGFbaW5kZXhdLFxuICAgICAgICBpbmRleCxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgY29uc3QgY2hhbmdlZCA9ICFfZWxlbWVudHNFcXVhbChsYXN0QWN0aXZlLCBhY3RpdmUpO1xuICAgIGNvbnN0IHBvc2l0aW9uQ2hhbmdlZCA9IHRoaXMuX3Bvc2l0aW9uQ2hhbmdlZChhY3RpdmUsIGV2ZW50UG9zaXRpb24pO1xuXG4gICAgaWYgKGNoYW5nZWQgfHwgcG9zaXRpb25DaGFuZ2VkKSB7XG4gICAgICB0aGlzLl9hY3RpdmUgPSBhY3RpdmU7XG4gICAgICB0aGlzLl9ldmVudFBvc2l0aW9uID0gZXZlbnRQb3NpdGlvbjtcbiAgICAgIHRoaXMuX2lnbm9yZVJlcGxheUV2ZW50cyA9IHRydWU7XG4gICAgICB0aGlzLnVwZGF0ZSh0cnVlKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogSGFuZGxlIGFuIGV2ZW50XG5cdCAqIEBwYXJhbSB7Q2hhcnRFdmVudH0gZSAtIFRoZSBldmVudCB0byBoYW5kbGVcblx0ICogQHBhcmFtIHtib29sZWFufSBbcmVwbGF5XSAtIFRoaXMgaXMgYSByZXBsYXllZCBldmVudCAoZnJvbSB1cGRhdGUpXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW2luQ2hhcnRBcmVhXSAtIFRoZSBldmVudCBpcyBpbnNpZGUgY2hhcnRBcmVhXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSB0b29sdGlwIGNoYW5nZWRcblx0ICovXG4gIGhhbmRsZUV2ZW50KGUsIHJlcGxheSwgaW5DaGFydEFyZWEgPSB0cnVlKSB7XG4gICAgaWYgKHJlcGxheSAmJiB0aGlzLl9pZ25vcmVSZXBsYXlFdmVudHMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5faWdub3JlUmVwbGF5RXZlbnRzID0gZmFsc2U7XG5cbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IGxhc3RBY3RpdmUgPSB0aGlzLl9hY3RpdmUgfHwgW107XG4gICAgY29uc3QgYWN0aXZlID0gdGhpcy5fZ2V0QWN0aXZlRWxlbWVudHMoZSwgbGFzdEFjdGl2ZSwgcmVwbGF5LCBpbkNoYXJ0QXJlYSk7XG5cbiAgICAvLyBXaGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBpdGVtcyBzaG93biwgYnV0IHRoZSB0b29sdGlwIHBvc2l0aW9uIGlzIG5lYXJlc3QgbW9kZVxuICAgIC8vIGFuIHVwZGF0ZSBtYXkgbmVlZCB0byBiZSBtYWRlIGJlY2F1c2Ugb3VyIHBvc2l0aW9uIG1heSBoYXZlIGNoYW5nZWQgZXZlbiB0aG91Z2hcbiAgICAvLyB0aGUgaXRlbXMgYXJlIHRoZSBzYW1lIGFzIGJlZm9yZS5cbiAgICBjb25zdCBwb3NpdGlvbkNoYW5nZWQgPSB0aGlzLl9wb3NpdGlvbkNoYW5nZWQoYWN0aXZlLCBlKTtcblxuICAgIC8vIFJlbWVtYmVyIExhc3QgQWN0aXZlc1xuICAgIGNvbnN0IGNoYW5nZWQgPSByZXBsYXkgfHwgIV9lbGVtZW50c0VxdWFsKGFjdGl2ZSwgbGFzdEFjdGl2ZSkgfHwgcG9zaXRpb25DaGFuZ2VkO1xuXG4gICAgLy8gT25seSBoYW5kbGUgdGFyZ2V0IGV2ZW50IG9uIHRvb2x0aXAgY2hhbmdlXG4gICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgIHRoaXMuX2FjdGl2ZSA9IGFjdGl2ZTtcblxuICAgICAgaWYgKG9wdGlvbnMuZW5hYmxlZCB8fCBvcHRpb25zLmV4dGVybmFsKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50UG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogZS54LFxuICAgICAgICAgIHk6IGUueVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMudXBkYXRlKHRydWUsIHJlcGxheSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNoYW5nZWQ7XG4gIH1cblxuICAvKipcblx0ICogSGVscGVyIGZvciBkZXRlcm1pbmluZyB0aGUgYWN0aXZlIGVsZW1lbnRzIGZvciBldmVudFxuXHQgKiBAcGFyYW0ge0NoYXJ0RXZlbnR9IGUgLSBUaGUgZXZlbnQgdG8gaGFuZGxlXG5cdCAqIEBwYXJhbSB7SW50ZXJhY3Rpb25JdGVtW119IGxhc3RBY3RpdmUgLSBQcmV2aW91c2x5IGFjdGl2ZSBlbGVtZW50c1xuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXBsYXldIC0gVGhpcyBpcyBhIHJlcGxheWVkIGV2ZW50IChmcm9tIHVwZGF0ZSlcblx0ICogQHBhcmFtIHtib29sZWFufSBbaW5DaGFydEFyZWFdIC0gVGhlIGV2ZW50IGlzIGluc2lkZSBjaGFydEFyZWFcblx0ICogQHJldHVybnMge0ludGVyYWN0aW9uSXRlbVtdfSAtIEFjdGl2ZSBlbGVtZW50c1xuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldEFjdGl2ZUVsZW1lbnRzKGUsIGxhc3RBY3RpdmUsIHJlcGxheSwgaW5DaGFydEFyZWEpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuXG4gICAgaWYgKGUudHlwZSA9PT0gJ21vdXNlb3V0Jykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGlmICghaW5DaGFydEFyZWEpIHtcbiAgICAgIC8vIExldCB1c2VyIGNvbnRyb2wgdGhlIGFjdGl2ZSBlbGVtZW50cyBvdXRzaWRlIGNoYXJ0QXJlYS4gRWcuIHVzaW5nIExlZ2VuZC5cbiAgICAgIC8vIEJ1dCBtYWtlIHN1cmUgdGhhdCBhY3RpdmUgZWxlbWVudHMgYXJlIHN0aWxsIHZhbGlkLlxuICAgICAgcmV0dXJuIGxhc3RBY3RpdmUuZmlsdGVyKGkgPT5cbiAgICAgICAgdGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzW2kuZGF0YXNldEluZGV4XSAmJlxuICAgICAgICB0aGlzLmNoYXJ0LmdldERhdGFzZXRNZXRhKGkuZGF0YXNldEluZGV4KS5jb250cm9sbGVyLmdldFBhcnNlZChpLmluZGV4KSAhPT0gdW5kZWZpbmVkXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEZpbmQgQWN0aXZlIEVsZW1lbnRzIGZvciB0b29sdGlwc1xuICAgIGNvbnN0IGFjdGl2ZSA9IHRoaXMuY2hhcnQuZ2V0RWxlbWVudHNBdEV2ZW50Rm9yTW9kZShlLCBvcHRpb25zLm1vZGUsIG9wdGlvbnMsIHJlcGxheSk7XG5cbiAgICBpZiAob3B0aW9ucy5yZXZlcnNlKSB7XG4gICAgICBhY3RpdmUucmV2ZXJzZSgpO1xuICAgIH1cblxuICAgIHJldHVybiBhY3RpdmU7XG4gIH1cblxuICAvKipcblx0ICogRGV0ZXJtaW5lIGlmIHRoZSBhY3RpdmUgZWxlbWVudHMgKyBldmVudCBjb21iaW5hdGlvbiBjaGFuZ2VzIHRoZVxuXHQgKiB0b29sdGlwIHBvc2l0aW9uXG5cdCAqIEBwYXJhbSB7YXJyYXl9IGFjdGl2ZSAtIEFjdGl2ZSBlbGVtZW50c1xuXHQgKiBAcGFyYW0ge0NoYXJ0RXZlbnR9IGUgLSBFdmVudCB0aGF0IHRyaWdnZXJlZCB0aGUgcG9zaXRpb24gY2hhbmdlXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwb3NpdGlvbiBoYXMgY2hhbmdlZFxuXHQgKi9cbiAgX3Bvc2l0aW9uQ2hhbmdlZChhY3RpdmUsIGUpIHtcbiAgICBjb25zdCB7Y2FyZXRYLCBjYXJldFksIG9wdGlvbnN9ID0gdGhpcztcbiAgICBjb25zdCBwb3NpdGlvbiA9IHBvc2l0aW9uZXJzW29wdGlvbnMucG9zaXRpb25dLmNhbGwodGhpcywgYWN0aXZlLCBlKTtcbiAgICByZXR1cm4gcG9zaXRpb24gIT09IGZhbHNlICYmIChjYXJldFggIT09IHBvc2l0aW9uLnggfHwgY2FyZXRZICE9PSBwb3NpdGlvbi55KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIGlkOiAndG9vbHRpcCcsXG4gIF9lbGVtZW50OiBUb29sdGlwLFxuICBwb3NpdGlvbmVycyxcblxuICBhZnRlckluaXQoY2hhcnQsIF9hcmdzLCBvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgIGNoYXJ0LnRvb2x0aXAgPSBuZXcgVG9vbHRpcCh7Y2hhcnQsIG9wdGlvbnN9KTtcbiAgICB9XG4gIH0sXG5cbiAgYmVmb3JlVXBkYXRlKGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgIGlmIChjaGFydC50b29sdGlwKSB7XG4gICAgICBjaGFydC50b29sdGlwLmluaXRpYWxpemUob3B0aW9ucyk7XG4gICAgfVxuICB9LFxuXG4gIHJlc2V0KGNoYXJ0LCBfYXJncywgb3B0aW9ucykge1xuICAgIGlmIChjaGFydC50b29sdGlwKSB7XG4gICAgICBjaGFydC50b29sdGlwLmluaXRpYWxpemUob3B0aW9ucyk7XG4gICAgfVxuICB9LFxuXG4gIGFmdGVyRHJhdyhjaGFydCkge1xuICAgIGNvbnN0IHRvb2x0aXAgPSBjaGFydC50b29sdGlwO1xuXG4gICAgaWYgKHRvb2x0aXAgJiYgdG9vbHRpcC5fd2lsbFJlbmRlcigpKSB7XG4gICAgICBjb25zdCBhcmdzID0ge1xuICAgICAgICB0b29sdGlwXG4gICAgICB9O1xuXG4gICAgICBpZiAoY2hhcnQubm90aWZ5UGx1Z2lucygnYmVmb3JlVG9vbHRpcERyYXcnLCB7Li4uYXJncywgY2FuY2VsYWJsZTogdHJ1ZX0pID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRvb2x0aXAuZHJhdyhjaGFydC5jdHgpO1xuXG4gICAgICBjaGFydC5ub3RpZnlQbHVnaW5zKCdhZnRlclRvb2x0aXBEcmF3JywgYXJncyk7XG4gICAgfVxuICB9LFxuXG4gIGFmdGVyRXZlbnQoY2hhcnQsIGFyZ3MpIHtcbiAgICBpZiAoY2hhcnQudG9vbHRpcCkge1xuICAgICAgLy8gSWYgdGhlIGV2ZW50IGlzIHJlcGxheWVkIGZyb20gYHVwZGF0ZWAsIHdlIHNob3VsZCBldmFsdWF0ZSB3aXRoIHRoZSBmaW5hbCBwb3NpdGlvbnMuXG4gICAgICBjb25zdCB1c2VGaW5hbFBvc2l0aW9uID0gYXJncy5yZXBsYXk7XG4gICAgICBpZiAoY2hhcnQudG9vbHRpcC5oYW5kbGVFdmVudChhcmdzLmV2ZW50LCB1c2VGaW5hbFBvc2l0aW9uLCBhcmdzLmluQ2hhcnRBcmVhKSkge1xuICAgICAgICAvLyBub3RpZnkgY2hhcnQgYWJvdXQgdGhlIGNoYW5nZSwgc28gaXQgd2lsbCByZW5kZXJcbiAgICAgICAgYXJncy5jaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgZGVmYXVsdHM6IHtcbiAgICBlbmFibGVkOiB0cnVlLFxuICAgIGV4dGVybmFsOiBudWxsLFxuICAgIHBvc2l0aW9uOiAnYXZlcmFnZScsXG4gICAgYmFja2dyb3VuZENvbG9yOiAncmdiYSgwLDAsMCwwLjgpJyxcbiAgICB0aXRsZUNvbG9yOiAnI2ZmZicsXG4gICAgdGl0bGVGb250OiB7XG4gICAgICB3ZWlnaHQ6ICdib2xkJyxcbiAgICB9LFxuICAgIHRpdGxlU3BhY2luZzogMixcbiAgICB0aXRsZU1hcmdpbkJvdHRvbTogNixcbiAgICB0aXRsZUFsaWduOiAnbGVmdCcsXG4gICAgYm9keUNvbG9yOiAnI2ZmZicsXG4gICAgYm9keVNwYWNpbmc6IDIsXG4gICAgYm9keUZvbnQ6IHtcbiAgICB9LFxuICAgIGJvZHlBbGlnbjogJ2xlZnQnLFxuICAgIGZvb3RlckNvbG9yOiAnI2ZmZicsXG4gICAgZm9vdGVyU3BhY2luZzogMixcbiAgICBmb290ZXJNYXJnaW5Ub3A6IDYsXG4gICAgZm9vdGVyRm9udDoge1xuICAgICAgd2VpZ2h0OiAnYm9sZCcsXG4gICAgfSxcbiAgICBmb290ZXJBbGlnbjogJ2xlZnQnLFxuICAgIHBhZGRpbmc6IDYsXG4gICAgY2FyZXRQYWRkaW5nOiAyLFxuICAgIGNhcmV0U2l6ZTogNSxcbiAgICBjb3JuZXJSYWRpdXM6IDYsXG4gICAgYm94SGVpZ2h0OiAoY3R4LCBvcHRzKSA9PiBvcHRzLmJvZHlGb250LnNpemUsXG4gICAgYm94V2lkdGg6IChjdHgsIG9wdHMpID0+IG9wdHMuYm9keUZvbnQuc2l6ZSxcbiAgICBtdWx0aUtleUJhY2tncm91bmQ6ICcjZmZmJyxcbiAgICBkaXNwbGF5Q29sb3JzOiB0cnVlLFxuICAgIGJveFBhZGRpbmc6IDAsXG4gICAgYm9yZGVyQ29sb3I6ICdyZ2JhKDAsMCwwLDApJyxcbiAgICBib3JkZXJXaWR0aDogMCxcbiAgICBhbmltYXRpb246IHtcbiAgICAgIGR1cmF0aW9uOiA0MDAsXG4gICAgICBlYXNpbmc6ICdlYXNlT3V0UXVhcnQnLFxuICAgIH0sXG4gICAgYW5pbWF0aW9uczoge1xuICAgICAgbnVtYmVyczoge1xuICAgICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICAgICAgcHJvcGVydGllczogWyd4JywgJ3knLCAnd2lkdGgnLCAnaGVpZ2h0JywgJ2NhcmV0WCcsICdjYXJldFknXSxcbiAgICAgIH0sXG4gICAgICBvcGFjaXR5OiB7XG4gICAgICAgIGVhc2luZzogJ2xpbmVhcicsXG4gICAgICAgIGR1cmF0aW9uOiAyMDBcbiAgICAgIH1cbiAgICB9LFxuICAgIGNhbGxiYWNrczogZGVmYXVsdENhbGxiYWNrc1xuICB9LFxuXG4gIGRlZmF1bHRSb3V0ZXM6IHtcbiAgICBib2R5Rm9udDogJ2ZvbnQnLFxuICAgIGZvb3RlckZvbnQ6ICdmb250JyxcbiAgICB0aXRsZUZvbnQ6ICdmb250J1xuICB9LFxuXG4gIGRlc2NyaXB0b3JzOiB7XG4gICAgX3NjcmlwdGFibGU6IChuYW1lKSA9PiBuYW1lICE9PSAnZmlsdGVyJyAmJiBuYW1lICE9PSAnaXRlbVNvcnQnICYmIG5hbWUgIT09ICdleHRlcm5hbCcsXG4gICAgX2luZGV4YWJsZTogZmFsc2UsXG4gICAgY2FsbGJhY2tzOiB7XG4gICAgICBfc2NyaXB0YWJsZTogZmFsc2UsXG4gICAgICBfaW5kZXhhYmxlOiBmYWxzZSxcbiAgICB9LFxuICAgIGFuaW1hdGlvbjoge1xuICAgICAgX2ZhbGxiYWNrOiBmYWxzZVxuICAgIH0sXG4gICAgYW5pbWF0aW9uczoge1xuICAgICAgX2ZhbGxiYWNrOiAnYW5pbWF0aW9uJ1xuICAgIH1cbiAgfSxcblxuICAvLyBSZXNvbHZlIGFkZGl0aW9uYWxseSBmcm9tIGBpbnRlcmFjdGlvbmAgb3B0aW9ucyBhbmQgZGVmYXVsdHMuXG4gIGFkZGl0aW9uYWxPcHRpb25TY29wZXM6IFsnaW50ZXJhY3Rpb24nXVxufTtcbiIsICJpbXBvcnQgU2NhbGUgZnJvbSAnLi4vY29yZS9jb3JlLnNjYWxlLmpzJztcbmltcG9ydCB7aXNOdWxsT3JVbmRlZiwgdmFsdWVPckRlZmF1bHQsIF9saW1pdFZhbHVlfSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcblxuY29uc3QgYWRkSWZTdHJpbmcgPSAobGFiZWxzLCByYXcsIGluZGV4LCBhZGRlZExhYmVscykgPT4ge1xuICBpZiAodHlwZW9mIHJhdyA9PT0gJ3N0cmluZycpIHtcbiAgICBpbmRleCA9IGxhYmVscy5wdXNoKHJhdykgLSAxO1xuICAgIGFkZGVkTGFiZWxzLnVuc2hpZnQoe2luZGV4LCBsYWJlbDogcmF3fSk7XG4gIH0gZWxzZSBpZiAoaXNOYU4ocmF3KSkge1xuICAgIGluZGV4ID0gbnVsbDtcbiAgfVxuICByZXR1cm4gaW5kZXg7XG59O1xuXG5mdW5jdGlvbiBmaW5kT3JBZGRMYWJlbChsYWJlbHMsIHJhdywgaW5kZXgsIGFkZGVkTGFiZWxzKSB7XG4gIGNvbnN0IGZpcnN0ID0gbGFiZWxzLmluZGV4T2YocmF3KTtcbiAgaWYgKGZpcnN0ID09PSAtMSkge1xuICAgIHJldHVybiBhZGRJZlN0cmluZyhsYWJlbHMsIHJhdywgaW5kZXgsIGFkZGVkTGFiZWxzKTtcbiAgfVxuICBjb25zdCBsYXN0ID0gbGFiZWxzLmxhc3RJbmRleE9mKHJhdyk7XG4gIHJldHVybiBmaXJzdCAhPT0gbGFzdCA/IGluZGV4IDogZmlyc3Q7XG59XG5cbmNvbnN0IHZhbGlkSW5kZXggPSAoaW5kZXgsIG1heCkgPT4gaW5kZXggPT09IG51bGwgPyBudWxsIDogX2xpbWl0VmFsdWUoTWF0aC5yb3VuZChpbmRleCksIDAsIG1heCk7XG5cbmZ1bmN0aW9uIF9nZXRMYWJlbEZvclZhbHVlKHZhbHVlKSB7XG4gIGNvbnN0IGxhYmVscyA9IHRoaXMuZ2V0TGFiZWxzKCk7XG5cbiAgaWYgKHZhbHVlID49IDAgJiYgdmFsdWUgPCBsYWJlbHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGxhYmVsc1t2YWx1ZV07XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDYXRlZ29yeVNjYWxlIGV4dGVuZHMgU2NhbGUge1xuXG4gIHN0YXRpYyBpZCA9ICdjYXRlZ29yeSc7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBzdGF0aWMgZGVmYXVsdHMgPSB7XG4gICAgdGlja3M6IHtcbiAgICAgIGNhbGxiYWNrOiBfZ2V0TGFiZWxGb3JWYWx1ZVxuICAgIH1cbiAgfTtcblxuICBjb25zdHJ1Y3RvcihjZmcpIHtcbiAgICBzdXBlcihjZmcpO1xuXG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5fc3RhcnRWYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl92YWx1ZVJhbmdlID0gMDtcbiAgICB0aGlzLl9hZGRlZExhYmVscyA9IFtdO1xuICB9XG5cbiAgaW5pdChzY2FsZU9wdGlvbnMpIHtcbiAgICBjb25zdCBhZGRlZCA9IHRoaXMuX2FkZGVkTGFiZWxzO1xuICAgIGlmIChhZGRlZC5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IGxhYmVscyA9IHRoaXMuZ2V0TGFiZWxzKCk7XG4gICAgICBmb3IgKGNvbnN0IHtpbmRleCwgbGFiZWx9IG9mIGFkZGVkKSB7XG4gICAgICAgIGlmIChsYWJlbHNbaW5kZXhdID09PSBsYWJlbCkge1xuICAgICAgICAgIGxhYmVscy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLl9hZGRlZExhYmVscyA9IFtdO1xuICAgIH1cbiAgICBzdXBlci5pbml0KHNjYWxlT3B0aW9ucyk7XG4gIH1cblxuICBwYXJzZShyYXcsIGluZGV4KSB7XG4gICAgaWYgKGlzTnVsbE9yVW5kZWYocmF3KSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IGxhYmVscyA9IHRoaXMuZ2V0TGFiZWxzKCk7XG4gICAgaW5kZXggPSBpc0Zpbml0ZShpbmRleCkgJiYgbGFiZWxzW2luZGV4XSA9PT0gcmF3ID8gaW5kZXhcbiAgICAgIDogZmluZE9yQWRkTGFiZWwobGFiZWxzLCByYXcsIHZhbHVlT3JEZWZhdWx0KGluZGV4LCByYXcpLCB0aGlzLl9hZGRlZExhYmVscyk7XG4gICAgcmV0dXJuIHZhbGlkSW5kZXgoaW5kZXgsIGxhYmVscy5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIGRldGVybWluZURhdGFMaW1pdHMoKSB7XG4gICAgY29uc3Qge21pbkRlZmluZWQsIG1heERlZmluZWR9ID0gdGhpcy5nZXRVc2VyQm91bmRzKCk7XG4gICAgbGV0IHttaW4sIG1heH0gPSB0aGlzLmdldE1pbk1heCh0cnVlKTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMuYm91bmRzID09PSAndGlja3MnKSB7XG4gICAgICBpZiAoIW1pbkRlZmluZWQpIHtcbiAgICAgICAgbWluID0gMDtcbiAgICAgIH1cbiAgICAgIGlmICghbWF4RGVmaW5lZCkge1xuICAgICAgICBtYXggPSB0aGlzLmdldExhYmVscygpLmxlbmd0aCAtIDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5taW4gPSBtaW47XG4gICAgdGhpcy5tYXggPSBtYXg7XG4gIH1cblxuICBidWlsZFRpY2tzKCkge1xuICAgIGNvbnN0IG1pbiA9IHRoaXMubWluO1xuICAgIGNvbnN0IG1heCA9IHRoaXMubWF4O1xuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMub3B0aW9ucy5vZmZzZXQ7XG4gICAgY29uc3QgdGlja3MgPSBbXTtcbiAgICBsZXQgbGFiZWxzID0gdGhpcy5nZXRMYWJlbHMoKTtcblxuICAgIC8vIElmIHdlIGFyZSB2aWV3aW5nIHNvbWUgc3Vic2V0IG9mIGxhYmVscywgc2xpY2UgdGhlIG9yaWdpbmFsIGFycmF5XG4gICAgbGFiZWxzID0gKG1pbiA9PT0gMCAmJiBtYXggPT09IGxhYmVscy5sZW5ndGggLSAxKSA/IGxhYmVscyA6IGxhYmVscy5zbGljZShtaW4sIG1heCArIDEpO1xuXG4gICAgdGhpcy5fdmFsdWVSYW5nZSA9IE1hdGgubWF4KGxhYmVscy5sZW5ndGggLSAob2Zmc2V0ID8gMCA6IDEpLCAxKTtcbiAgICB0aGlzLl9zdGFydFZhbHVlID0gdGhpcy5taW4gLSAob2Zmc2V0ID8gMC41IDogMCk7XG5cbiAgICBmb3IgKGxldCB2YWx1ZSA9IG1pbjsgdmFsdWUgPD0gbWF4OyB2YWx1ZSsrKSB7XG4gICAgICB0aWNrcy5wdXNoKHt2YWx1ZX0pO1xuICAgIH1cbiAgICByZXR1cm4gdGlja3M7XG4gIH1cblxuICBnZXRMYWJlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgcmV0dXJuIF9nZXRMYWJlbEZvclZhbHVlLmNhbGwodGhpcywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGNvbmZpZ3VyZSgpIHtcbiAgICBzdXBlci5jb25maWd1cmUoKTtcblxuICAgIGlmICghdGhpcy5pc0hvcml6b250YWwoKSkge1xuICAgICAgLy8gRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHZlcnRpY2FsIGNhdGVnb3J5IHNjYWxlIHJldmVyc2UgaXMgaW52ZXJ0ZWQuXG4gICAgICB0aGlzLl9yZXZlcnNlUGl4ZWxzID0gIXRoaXMuX3JldmVyc2VQaXhlbHM7XG4gICAgfVxuICB9XG5cbiAgLy8gVXNlZCB0byBnZXQgZGF0YSB2YWx1ZSBsb2NhdGlvbnMuIFZhbHVlIGNhbiBlaXRoZXIgYmUgYW4gaW5kZXggb3IgYSBudW1lcmljYWwgdmFsdWVcbiAgZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMucGFyc2UodmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCA/IE5hTiA6IHRoaXMuZ2V0UGl4ZWxGb3JEZWNpbWFsKCh2YWx1ZSAtIHRoaXMuX3N0YXJ0VmFsdWUpIC8gdGhpcy5fdmFsdWVSYW5nZSk7XG4gIH1cblxuICAvLyBNdXN0IG92ZXJyaWRlIGJhc2UgaW1wbGVtZW50YXRpb24gYmVjYXVzZSBpdCBjYWxscyBnZXRQaXhlbEZvclZhbHVlXG4gIC8vIGFuZCBjYXRlZ29yeSBzY2FsZSBjYW4gaGF2ZSBkdXBsaWNhdGUgdmFsdWVzXG4gIGdldFBpeGVsRm9yVGljayhpbmRleCkge1xuICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID4gdGlja3MubGVuZ3RoIC0gMSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdldFBpeGVsRm9yVmFsdWUodGlja3NbaW5kZXhdLnZhbHVlKTtcbiAgfVxuXG4gIGdldFZhbHVlRm9yUGl4ZWwocGl4ZWwpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzLl9zdGFydFZhbHVlICsgdGhpcy5nZXREZWNpbWFsRm9yUGl4ZWwocGl4ZWwpICogdGhpcy5fdmFsdWVSYW5nZSk7XG4gIH1cblxuICBnZXRCYXNlUGl4ZWwoKSB7XG4gICAgcmV0dXJuIHRoaXMuYm90dG9tO1xuICB9XG59XG4iLCAiaW1wb3J0IHtpc051bGxPclVuZGVmfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge2FsbW9zdEVxdWFscywgYWxtb3N0V2hvbGUsIG5pY2VOdW0sIF9kZWNpbWFsUGxhY2VzLCBfc2V0TWluQW5kTWF4QnlLZXksIHNpZ24sIHRvUmFkaWFuc30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm1hdGguanMnO1xuaW1wb3J0IFNjYWxlIGZyb20gJy4uL2NvcmUvY29yZS5zY2FsZS5qcyc7XG5pbXBvcnQge2Zvcm1hdE51bWJlcn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmludGwuanMnO1xuXG4vKipcbiAqIEdlbmVyYXRlIGEgc2V0IG9mIGxpbmVhciB0aWNrcyBmb3IgYW4gYXhpc1xuICogMS4gSWYgZ2VuZXJhdGlvbk9wdGlvbnMubWluLCBnZW5lcmF0aW9uT3B0aW9ucy5tYXgsIGFuZCBnZW5lcmF0aW9uT3B0aW9ucy5zdGVwIGFyZSBkZWZpbmVkOlxuICogICAgaWYgKG1heCAtIG1pbikgLyBzdGVwIGlzIGFuIGludGVnZXIsIHRpY2tzIGFyZSBnZW5lcmF0ZWQgYXMgW21pbiwgbWluICsgc3RlcCwgLi4uLCBtYXhdXG4gKiAgICBOb3RlIHRoYXQgdGhlIGdlbmVyYXRpb25PcHRpb25zLm1heENvdW50IHNldHRpbmcgaXMgcmVzcGVjdGVkIGluIHRoaXMgc2NlbmFyaW9cbiAqXG4gKiAyLiBJZiBnZW5lcmF0aW9uT3B0aW9ucy5taW4sIGdlbmVyYXRpb25PcHRpb25zLm1heCwgYW5kIGdlbmVyYXRpb25PcHRpb25zLmNvdW50IGlzIGRlZmluZWRcbiAqICAgIHNwYWNpbmcgPSAobWF4IC0gbWluKSAvIGNvdW50XG4gKiAgICBUaWNrcyBhcmUgZ2VuZXJhdGVkIGFzIFttaW4sIG1pbiArIHNwYWNpbmcsIC4uLiwgbWF4XVxuICpcbiAqIDMuIElmIGdlbmVyYXRpb25PcHRpb25zLmNvdW50IGlzIGRlZmluZWRcbiAqICAgIHNwYWNpbmcgPSAobmljZU1heCAtIG5pY2VNaW4pIC8gY291bnRcbiAqXG4gKiA0LiBDb21wdXRlIG9wdGltYWwgc3BhY2luZyBvZiB0aWNrcyB1c2luZyBuaWNlTnVtIGFsZ29yaXRobVxuICpcbiAqIEBwYXJhbSBnZW5lcmF0aW9uT3B0aW9ucyB0aGUgb3B0aW9ucyB1c2VkIHRvIGdlbmVyYXRlIHRoZSB0aWNrc1xuICogQHBhcmFtIGRhdGFSYW5nZSB0aGUgcmFuZ2Ugb2YgdGhlIGRhdGFcbiAqIEByZXR1cm5zIHtvYmplY3RbXX0gYXJyYXkgb2YgdGljayBvYmplY3RzXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlVGlja3MoZ2VuZXJhdGlvbk9wdGlvbnMsIGRhdGFSYW5nZSkge1xuICBjb25zdCB0aWNrcyA9IFtdO1xuICAvLyBUbyBnZXQgYSBcIm5pY2VcIiB2YWx1ZSBmb3IgdGhlIHRpY2sgc3BhY2luZywgd2Ugd2lsbCB1c2UgdGhlIGFwcHJvcHJpYXRlbHkgbmFtZWRcbiAgLy8gXCJuaWNlIG51bWJlclwiIGFsZ29yaXRobS4gU2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzg1MDY4ODEvbmljZS1sYWJlbC1hbGdvcml0aG0tZm9yLWNoYXJ0cy13aXRoLW1pbmltdW0tdGlja3NcbiAgLy8gZm9yIGRldGFpbHMuXG5cbiAgY29uc3QgTUlOX1NQQUNJTkcgPSAxZS0xNDtcbiAgY29uc3Qge2JvdW5kcywgc3RlcCwgbWluLCBtYXgsIHByZWNpc2lvbiwgY291bnQsIG1heFRpY2tzLCBtYXhEaWdpdHMsIGluY2x1ZGVCb3VuZHN9ID0gZ2VuZXJhdGlvbk9wdGlvbnM7XG4gIGNvbnN0IHVuaXQgPSBzdGVwIHx8IDE7XG4gIGNvbnN0IG1heFNwYWNlcyA9IG1heFRpY2tzIC0gMTtcbiAgY29uc3Qge21pbjogcm1pbiwgbWF4OiBybWF4fSA9IGRhdGFSYW5nZTtcbiAgY29uc3QgbWluRGVmaW5lZCA9ICFpc051bGxPclVuZGVmKG1pbik7XG4gIGNvbnN0IG1heERlZmluZWQgPSAhaXNOdWxsT3JVbmRlZihtYXgpO1xuICBjb25zdCBjb3VudERlZmluZWQgPSAhaXNOdWxsT3JVbmRlZihjb3VudCk7XG4gIGNvbnN0IG1pblNwYWNpbmcgPSAocm1heCAtIHJtaW4pIC8gKG1heERpZ2l0cyArIDEpO1xuICBsZXQgc3BhY2luZyA9IG5pY2VOdW0oKHJtYXggLSBybWluKSAvIG1heFNwYWNlcyAvIHVuaXQpICogdW5pdDtcbiAgbGV0IGZhY3RvciwgbmljZU1pbiwgbmljZU1heCwgbnVtU3BhY2VzO1xuXG4gIC8vIEJleW9uZCBNSU5fU1BBQ0lORyBmbG9hdGluZyBwb2ludCBudW1iZXJzIGJlaW5nIHRvIGxvc2UgcHJlY2lzaW9uXG4gIC8vIHN1Y2ggdGhhdCB3ZSBjYW4ndCBkbyB0aGUgbWF0aCBuZWNlc3NhcnkgdG8gZ2VuZXJhdGUgdGlja3NcbiAgaWYgKHNwYWNpbmcgPCBNSU5fU1BBQ0lORyAmJiAhbWluRGVmaW5lZCAmJiAhbWF4RGVmaW5lZCkge1xuICAgIHJldHVybiBbe3ZhbHVlOiBybWlufSwge3ZhbHVlOiBybWF4fV07XG4gIH1cblxuICBudW1TcGFjZXMgPSBNYXRoLmNlaWwocm1heCAvIHNwYWNpbmcpIC0gTWF0aC5mbG9vcihybWluIC8gc3BhY2luZyk7XG4gIGlmIChudW1TcGFjZXMgPiBtYXhTcGFjZXMpIHtcbiAgICAvLyBJZiB0aGUgY2FsY3VsYXRlZCBudW0gb2Ygc3BhY2VzIGV4Y2VlZHMgbWF4TnVtU3BhY2VzLCByZWNhbGN1bGF0ZSBpdFxuICAgIHNwYWNpbmcgPSBuaWNlTnVtKG51bVNwYWNlcyAqIHNwYWNpbmcgLyBtYXhTcGFjZXMgLyB1bml0KSAqIHVuaXQ7XG4gIH1cblxuICBpZiAoIWlzTnVsbE9yVW5kZWYocHJlY2lzaW9uKSkge1xuICAgIC8vIElmIHRoZSB1c2VyIHNwZWNpZmllZCBhIHByZWNpc2lvbiwgcm91bmQgdG8gdGhhdCBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXNcbiAgICBmYWN0b3IgPSBNYXRoLnBvdygxMCwgcHJlY2lzaW9uKTtcbiAgICBzcGFjaW5nID0gTWF0aC5jZWlsKHNwYWNpbmcgKiBmYWN0b3IpIC8gZmFjdG9yO1xuICB9XG5cbiAgaWYgKGJvdW5kcyA9PT0gJ3RpY2tzJykge1xuICAgIG5pY2VNaW4gPSBNYXRoLmZsb29yKHJtaW4gLyBzcGFjaW5nKSAqIHNwYWNpbmc7XG4gICAgbmljZU1heCA9IE1hdGguY2VpbChybWF4IC8gc3BhY2luZykgKiBzcGFjaW5nO1xuICB9IGVsc2Uge1xuICAgIG5pY2VNaW4gPSBybWluO1xuICAgIG5pY2VNYXggPSBybWF4O1xuICB9XG5cbiAgaWYgKG1pbkRlZmluZWQgJiYgbWF4RGVmaW5lZCAmJiBzdGVwICYmIGFsbW9zdFdob2xlKChtYXggLSBtaW4pIC8gc3RlcCwgc3BhY2luZyAvIDEwMDApKSB7XG4gICAgLy8gQ2FzZSAxOiBJZiBtaW4sIG1heCBhbmQgc3RlcFNpemUgYXJlIHNldCBhbmQgdGhleSBtYWtlIGFuIGV2ZW5seSBzcGFjZWQgc2NhbGUgdXNlIGl0LlxuICAgIC8vIHNwYWNpbmcgPSBzdGVwO1xuICAgIC8vIG51bVNwYWNlcyA9IChtYXggLSBtaW4pIC8gc3BhY2luZztcbiAgICAvLyBOb3RlIHRoYXQgd2Ugcm91bmQgaGVyZSB0byBoYW5kbGUgdGhlIGNhc2Ugd2hlcmUgYWxtb3N0V2hvbGUgdHJhbnNsYXRlZCBhbiBGUCBlcnJvclxuICAgIG51bVNwYWNlcyA9IE1hdGgucm91bmQoTWF0aC5taW4oKG1heCAtIG1pbikgLyBzcGFjaW5nLCBtYXhUaWNrcykpO1xuICAgIHNwYWNpbmcgPSAobWF4IC0gbWluKSAvIG51bVNwYWNlcztcbiAgICBuaWNlTWluID0gbWluO1xuICAgIG5pY2VNYXggPSBtYXg7XG4gIH0gZWxzZSBpZiAoY291bnREZWZpbmVkKSB7XG4gICAgLy8gQ2FzZXMgMiAmIDMsIHdlIGhhdmUgYSBjb3VudCBzcGVjaWZpZWQuIEhhbmRsZSBvcHRpb25hbCB1c2VyIGRlZmluZWQgZWRnZXMgdG8gdGhlIHJhbmdlLlxuICAgIC8vIFNvbWV0aW1lcyB0aGVzZSBhcmUgbm8tb3BzLCBidXQgaXQgbWFrZXMgdGhlIGNvZGUgYSBsb3QgY2xlYXJlclxuICAgIC8vIGFuZCB3aGVuIGEgdXNlciBkZWZpbmVkIHJhbmdlIGlzIHNwZWNpZmllZCwgd2Ugd2FudCB0aGUgY29ycmVjdCB0aWNrc1xuICAgIG5pY2VNaW4gPSBtaW5EZWZpbmVkID8gbWluIDogbmljZU1pbjtcbiAgICBuaWNlTWF4ID0gbWF4RGVmaW5lZCA/IG1heCA6IG5pY2VNYXg7XG4gICAgbnVtU3BhY2VzID0gY291bnQgLSAxO1xuICAgIHNwYWNpbmcgPSAobmljZU1heCAtIG5pY2VNaW4pIC8gbnVtU3BhY2VzO1xuICB9IGVsc2Uge1xuICAgIC8vIENhc2UgNFxuICAgIG51bVNwYWNlcyA9IChuaWNlTWF4IC0gbmljZU1pbikgLyBzcGFjaW5nO1xuXG4gICAgLy8gSWYgdmVyeSBjbG9zZSB0byBvdXIgcm91bmRlZCB2YWx1ZSwgdXNlIGl0LlxuICAgIGlmIChhbG1vc3RFcXVhbHMobnVtU3BhY2VzLCBNYXRoLnJvdW5kKG51bVNwYWNlcyksIHNwYWNpbmcgLyAxMDAwKSkge1xuICAgICAgbnVtU3BhY2VzID0gTWF0aC5yb3VuZChudW1TcGFjZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBudW1TcGFjZXMgPSBNYXRoLmNlaWwobnVtU3BhY2VzKTtcbiAgICB9XG4gIH1cblxuICAvLyBUaGUgc3BhY2luZyB3aWxsIGhhdmUgY2hhbmdlZCBpbiBjYXNlcyAxLCAyLCBhbmQgMyBzbyB0aGUgZmFjdG9yIGNhbm5vdCBiZSBjb21wdXRlZFxuICAvLyB1bnRpbCB0aGlzIHBvaW50XG4gIGNvbnN0IGRlY2ltYWxQbGFjZXMgPSBNYXRoLm1heChcbiAgICBfZGVjaW1hbFBsYWNlcyhzcGFjaW5nKSxcbiAgICBfZGVjaW1hbFBsYWNlcyhuaWNlTWluKVxuICApO1xuICBmYWN0b3IgPSBNYXRoLnBvdygxMCwgaXNOdWxsT3JVbmRlZihwcmVjaXNpb24pID8gZGVjaW1hbFBsYWNlcyA6IHByZWNpc2lvbik7XG4gIG5pY2VNaW4gPSBNYXRoLnJvdW5kKG5pY2VNaW4gKiBmYWN0b3IpIC8gZmFjdG9yO1xuICBuaWNlTWF4ID0gTWF0aC5yb3VuZChuaWNlTWF4ICogZmFjdG9yKSAvIGZhY3RvcjtcblxuICBsZXQgaiA9IDA7XG4gIGlmIChtaW5EZWZpbmVkKSB7XG4gICAgaWYgKGluY2x1ZGVCb3VuZHMgJiYgbmljZU1pbiAhPT0gbWluKSB7XG4gICAgICB0aWNrcy5wdXNoKHt2YWx1ZTogbWlufSk7XG5cbiAgICAgIGlmIChuaWNlTWluIDwgbWluKSB7XG4gICAgICAgIGorKzsgLy8gU2tpcCBuaWNlTWluXG4gICAgICB9XG4gICAgICAvLyBJZiB0aGUgbmV4dCBuaWNlIHRpY2sgaXMgY2xvc2UgdG8gbWluLCBza2lwIGl0XG4gICAgICBpZiAoYWxtb3N0RXF1YWxzKE1hdGgucm91bmQoKG5pY2VNaW4gKyBqICogc3BhY2luZykgKiBmYWN0b3IpIC8gZmFjdG9yLCBtaW4sIHJlbGF0aXZlTGFiZWxTaXplKG1pbiwgbWluU3BhY2luZywgZ2VuZXJhdGlvbk9wdGlvbnMpKSkge1xuICAgICAgICBqKys7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChuaWNlTWluIDwgbWluKSB7XG4gICAgICBqKys7XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IGogPCBudW1TcGFjZXM7ICsraikge1xuICAgIGNvbnN0IHRpY2tWYWx1ZSA9IE1hdGgucm91bmQoKG5pY2VNaW4gKyBqICogc3BhY2luZykgKiBmYWN0b3IpIC8gZmFjdG9yO1xuICAgIGlmIChtYXhEZWZpbmVkICYmIHRpY2tWYWx1ZSA+IG1heCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHRpY2tzLnB1c2goe3ZhbHVlOiB0aWNrVmFsdWV9KTtcbiAgfVxuXG4gIGlmIChtYXhEZWZpbmVkICYmIGluY2x1ZGVCb3VuZHMgJiYgbmljZU1heCAhPT0gbWF4KSB7XG4gICAgLy8gSWYgdGhlIHByZXZpb3VzIHRpY2sgaXMgdG9vIGNsb3NlIHRvIG1heCwgcmVwbGFjZSBpdCB3aXRoIG1heCwgZWxzZSBhZGQgbWF4XG4gICAgaWYgKHRpY2tzLmxlbmd0aCAmJiBhbG1vc3RFcXVhbHModGlja3NbdGlja3MubGVuZ3RoIC0gMV0udmFsdWUsIG1heCwgcmVsYXRpdmVMYWJlbFNpemUobWF4LCBtaW5TcGFjaW5nLCBnZW5lcmF0aW9uT3B0aW9ucykpKSB7XG4gICAgICB0aWNrc1t0aWNrcy5sZW5ndGggLSAxXS52YWx1ZSA9IG1heDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGlja3MucHVzaCh7dmFsdWU6IG1heH0pO1xuICAgIH1cbiAgfSBlbHNlIGlmICghbWF4RGVmaW5lZCB8fCBuaWNlTWF4ID09PSBtYXgpIHtcbiAgICB0aWNrcy5wdXNoKHt2YWx1ZTogbmljZU1heH0pO1xuICB9XG5cbiAgcmV0dXJuIHRpY2tzO1xufVxuXG5mdW5jdGlvbiByZWxhdGl2ZUxhYmVsU2l6ZSh2YWx1ZSwgbWluU3BhY2luZywge2hvcml6b250YWwsIG1pblJvdGF0aW9ufSkge1xuICBjb25zdCByYWQgPSB0b1JhZGlhbnMobWluUm90YXRpb24pO1xuICBjb25zdCByYXRpbyA9IChob3Jpem9udGFsID8gTWF0aC5zaW4ocmFkKSA6IE1hdGguY29zKHJhZCkpIHx8IDAuMDAxO1xuICBjb25zdCBsZW5ndGggPSAwLjc1ICogbWluU3BhY2luZyAqICgnJyArIHZhbHVlKS5sZW5ndGg7XG4gIHJldHVybiBNYXRoLm1pbihtaW5TcGFjaW5nIC8gcmF0aW8sIGxlbmd0aCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpbmVhclNjYWxlQmFzZSBleHRlbmRzIFNjYWxlIHtcblxuICBjb25zdHJ1Y3RvcihjZmcpIHtcbiAgICBzdXBlcihjZmcpO1xuXG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5zdGFydCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLmVuZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLl9zdGFydFZhbHVlID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuX2VuZFZhbHVlID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX3ZhbHVlUmFuZ2UgPSAwO1xuICB9XG5cbiAgcGFyc2UocmF3LCBpbmRleCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgaWYgKGlzTnVsbE9yVW5kZWYocmF3KSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICgodHlwZW9mIHJhdyA9PT0gJ251bWJlcicgfHwgcmF3IGluc3RhbmNlb2YgTnVtYmVyKSAmJiAhaXNGaW5pdGUoK3JhdykpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiArcmF3O1xuICB9XG5cbiAgaGFuZGxlVGlja1JhbmdlT3B0aW9ucygpIHtcbiAgICBjb25zdCB7YmVnaW5BdFplcm99ID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHttaW5EZWZpbmVkLCBtYXhEZWZpbmVkfSA9IHRoaXMuZ2V0VXNlckJvdW5kcygpO1xuICAgIGxldCB7bWluLCBtYXh9ID0gdGhpcztcblxuICAgIGNvbnN0IHNldE1pbiA9IHYgPT4gKG1pbiA9IG1pbkRlZmluZWQgPyBtaW4gOiB2KTtcbiAgICBjb25zdCBzZXRNYXggPSB2ID0+IChtYXggPSBtYXhEZWZpbmVkID8gbWF4IDogdik7XG5cbiAgICBpZiAoYmVnaW5BdFplcm8pIHtcbiAgICAgIGNvbnN0IG1pblNpZ24gPSBzaWduKG1pbik7XG4gICAgICBjb25zdCBtYXhTaWduID0gc2lnbihtYXgpO1xuXG4gICAgICBpZiAobWluU2lnbiA8IDAgJiYgbWF4U2lnbiA8IDApIHtcbiAgICAgICAgc2V0TWF4KDApO1xuICAgICAgfSBlbHNlIGlmIChtaW5TaWduID4gMCAmJiBtYXhTaWduID4gMCkge1xuICAgICAgICBzZXRNaW4oMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1pbiA9PT0gbWF4KSB7XG4gICAgICBsZXQgb2Zmc2V0ID0gbWF4ID09PSAwID8gMSA6IE1hdGguYWJzKG1heCAqIDAuMDUpO1xuXG4gICAgICBzZXRNYXgobWF4ICsgb2Zmc2V0KTtcblxuICAgICAgaWYgKCFiZWdpbkF0WmVybykge1xuICAgICAgICBzZXRNaW4obWluIC0gb2Zmc2V0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5taW4gPSBtaW47XG4gICAgdGhpcy5tYXggPSBtYXg7XG4gIH1cblxuICBnZXRUaWNrTGltaXQoKSB7XG4gICAgY29uc3QgdGlja09wdHMgPSB0aGlzLm9wdGlvbnMudGlja3M7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICAgIGxldCB7bWF4VGlja3NMaW1pdCwgc3RlcFNpemV9ID0gdGlja09wdHM7XG4gICAgbGV0IG1heFRpY2tzO1xuXG4gICAgaWYgKHN0ZXBTaXplKSB7XG4gICAgICBtYXhUaWNrcyA9IE1hdGguY2VpbCh0aGlzLm1heCAvIHN0ZXBTaXplKSAtIE1hdGguZmxvb3IodGhpcy5taW4gLyBzdGVwU2l6ZSkgKyAxO1xuICAgICAgaWYgKG1heFRpY2tzID4gMTAwMCkge1xuICAgICAgICBjb25zb2xlLndhcm4oYHNjYWxlcy4ke3RoaXMuaWR9LnRpY2tzLnN0ZXBTaXplOiAke3N0ZXBTaXplfSB3b3VsZCByZXN1bHQgZ2VuZXJhdGluZyB1cCB0byAke21heFRpY2tzfSB0aWNrcy4gTGltaXRpbmcgdG8gMTAwMC5gKTtcbiAgICAgICAgbWF4VGlja3MgPSAxMDAwO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBtYXhUaWNrcyA9IHRoaXMuY29tcHV0ZVRpY2tMaW1pdCgpO1xuICAgICAgbWF4VGlja3NMaW1pdCA9IG1heFRpY2tzTGltaXQgfHwgMTE7XG4gICAgfVxuXG4gICAgaWYgKG1heFRpY2tzTGltaXQpIHtcbiAgICAgIG1heFRpY2tzID0gTWF0aC5taW4obWF4VGlja3NMaW1pdCwgbWF4VGlja3MpO1xuICAgIH1cblxuICAgIHJldHVybiBtYXhUaWNrcztcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBjb21wdXRlVGlja0xpbWl0KCkge1xuICAgIHJldHVybiBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gIH1cblxuICBidWlsZFRpY2tzKCkge1xuICAgIGNvbnN0IG9wdHMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgdGlja09wdHMgPSBvcHRzLnRpY2tzO1xuXG4gICAgLy8gRmlndXJlIG91dCB3aGF0IHRoZSBtYXggbnVtYmVyIG9mIHRpY2tzIHdlIGNhbiBzdXBwb3J0IGl0IGlzIGJhc2VkIG9uIHRoZSBzaXplIG9mXG4gICAgLy8gdGhlIGF4aXMgYXJlYS4gRm9yIG5vdywgd2Ugc2F5IHRoYXQgdGhlIG1pbmltdW0gdGljayBzcGFjaW5nIGluIHBpeGVscyBtdXN0IGJlIDQwXG4gICAgLy8gV2UgYWxzbyBsaW1pdCB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGlja3MgdG8gMTEgd2hpY2ggZ2l2ZXMgYSBuaWNlIDEwIHNxdWFyZXMgb25cbiAgICAvLyB0aGUgZ3JhcGguIE1ha2Ugc3VyZSB3ZSBhbHdheXMgaGF2ZSBhdCBsZWFzdCAyIHRpY2tzXG4gICAgbGV0IG1heFRpY2tzID0gdGhpcy5nZXRUaWNrTGltaXQoKTtcbiAgICBtYXhUaWNrcyA9IE1hdGgubWF4KDIsIG1heFRpY2tzKTtcblxuICAgIGNvbnN0IG51bWVyaWNHZW5lcmF0b3JPcHRpb25zID0ge1xuICAgICAgbWF4VGlja3MsXG4gICAgICBib3VuZHM6IG9wdHMuYm91bmRzLFxuICAgICAgbWluOiBvcHRzLm1pbixcbiAgICAgIG1heDogb3B0cy5tYXgsXG4gICAgICBwcmVjaXNpb246IHRpY2tPcHRzLnByZWNpc2lvbixcbiAgICAgIHN0ZXA6IHRpY2tPcHRzLnN0ZXBTaXplLFxuICAgICAgY291bnQ6IHRpY2tPcHRzLmNvdW50LFxuICAgICAgbWF4RGlnaXRzOiB0aGlzLl9tYXhEaWdpdHMoKSxcbiAgICAgIGhvcml6b250YWw6IHRoaXMuaXNIb3Jpem9udGFsKCksXG4gICAgICBtaW5Sb3RhdGlvbjogdGlja09wdHMubWluUm90YXRpb24gfHwgMCxcbiAgICAgIGluY2x1ZGVCb3VuZHM6IHRpY2tPcHRzLmluY2x1ZGVCb3VuZHMgIT09IGZhbHNlXG4gICAgfTtcbiAgICBjb25zdCBkYXRhUmFuZ2UgPSB0aGlzLl9yYW5nZSB8fCB0aGlzO1xuICAgIGNvbnN0IHRpY2tzID0gZ2VuZXJhdGVUaWNrcyhudW1lcmljR2VuZXJhdG9yT3B0aW9ucywgZGF0YVJhbmdlKTtcblxuICAgIC8vIEF0IHRoaXMgcG9pbnQsIHdlIG5lZWQgdG8gdXBkYXRlIG91ciBtYXggYW5kIG1pbiBnaXZlbiB0aGUgdGljayB2YWx1ZXMsXG4gICAgLy8gc2luY2Ugd2UgcHJvYmFibHkgaGF2ZSBleHBhbmRlZCB0aGUgcmFuZ2Ugb2YgdGhlIHNjYWxlXG4gICAgaWYgKG9wdHMuYm91bmRzID09PSAndGlja3MnKSB7XG4gICAgICBfc2V0TWluQW5kTWF4QnlLZXkodGlja3MsIHRoaXMsICd2YWx1ZScpO1xuICAgIH1cblxuICAgIGlmIChvcHRzLnJldmVyc2UpIHtcbiAgICAgIHRpY2tzLnJldmVyc2UoKTtcblxuICAgICAgdGhpcy5zdGFydCA9IHRoaXMubWF4O1xuICAgICAgdGhpcy5lbmQgPSB0aGlzLm1pbjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zdGFydCA9IHRoaXMubWluO1xuICAgICAgdGhpcy5lbmQgPSB0aGlzLm1heDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGlja3M7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgY29uZmlndXJlKCkge1xuICAgIGNvbnN0IHRpY2tzID0gdGhpcy50aWNrcztcbiAgICBsZXQgc3RhcnQgPSB0aGlzLm1pbjtcbiAgICBsZXQgZW5kID0gdGhpcy5tYXg7XG5cbiAgICBzdXBlci5jb25maWd1cmUoKTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMub2Zmc2V0ICYmIHRpY2tzLmxlbmd0aCkge1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gKGVuZCAtIHN0YXJ0KSAvIE1hdGgubWF4KHRpY2tzLmxlbmd0aCAtIDEsIDEpIC8gMjtcbiAgICAgIHN0YXJ0IC09IG9mZnNldDtcbiAgICAgIGVuZCArPSBvZmZzZXQ7XG4gICAgfVxuICAgIHRoaXMuX3N0YXJ0VmFsdWUgPSBzdGFydDtcbiAgICB0aGlzLl9lbmRWYWx1ZSA9IGVuZDtcbiAgICB0aGlzLl92YWx1ZVJhbmdlID0gZW5kIC0gc3RhcnQ7XG4gIH1cblxuICBnZXRMYWJlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgcmV0dXJuIGZvcm1hdE51bWJlcih2YWx1ZSwgdGhpcy5jaGFydC5vcHRpb25zLmxvY2FsZSwgdGhpcy5vcHRpb25zLnRpY2tzLmZvcm1hdCk7XG4gIH1cbn1cbiIsICJpbXBvcnQge2lzRmluaXRlfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQgTGluZWFyU2NhbGVCYXNlIGZyb20gJy4vc2NhbGUubGluZWFyYmFzZS5qcyc7XG5pbXBvcnQgVGlja3MgZnJvbSAnLi4vY29yZS9jb3JlLnRpY2tzLmpzJztcbmltcG9ydCB7dG9SYWRpYW5zfSBmcm9tICcuLi9oZWxwZXJzL2luZGV4LmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGluZWFyU2NhbGUgZXh0ZW5kcyBMaW5lYXJTY2FsZUJhc2Uge1xuXG4gIHN0YXRpYyBpZCA9ICdsaW5lYXInO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0ge1xuICAgIHRpY2tzOiB7XG4gICAgICBjYWxsYmFjazogVGlja3MuZm9ybWF0dGVycy5udW1lcmljXG4gICAgfVxuICB9O1xuXG5cbiAgZGV0ZXJtaW5lRGF0YUxpbWl0cygpIHtcbiAgICBjb25zdCB7bWluLCBtYXh9ID0gdGhpcy5nZXRNaW5NYXgodHJ1ZSk7XG5cbiAgICB0aGlzLm1pbiA9IGlzRmluaXRlKG1pbikgPyBtaW4gOiAwO1xuICAgIHRoaXMubWF4ID0gaXNGaW5pdGUobWF4KSA/IG1heCA6IDE7XG5cbiAgICAvLyBDb21tb24gYmFzZSBpbXBsZW1lbnRhdGlvbiB0byBoYW5kbGUgbWluLCBtYXgsIGJlZ2luQXRaZXJvXG4gICAgdGhpcy5oYW5kbGVUaWNrUmFuZ2VPcHRpb25zKCk7XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGlja3MgYmFzZWQgb24gdGhlIHNjYWxlIGRpbWVuc2lvblxuXHQgKiBAcHJvdGVjdGVkXG4gXHQgKi9cbiAgY29tcHV0ZVRpY2tMaW1pdCgpIHtcbiAgICBjb25zdCBob3Jpem9udGFsID0gdGhpcy5pc0hvcml6b250YWwoKTtcbiAgICBjb25zdCBsZW5ndGggPSBob3Jpem9udGFsID8gdGhpcy53aWR0aCA6IHRoaXMuaGVpZ2h0O1xuICAgIGNvbnN0IG1pblJvdGF0aW9uID0gdG9SYWRpYW5zKHRoaXMub3B0aW9ucy50aWNrcy5taW5Sb3RhdGlvbik7XG4gICAgY29uc3QgcmF0aW8gPSAoaG9yaXpvbnRhbCA/IE1hdGguc2luKG1pblJvdGF0aW9uKSA6IE1hdGguY29zKG1pblJvdGF0aW9uKSkgfHwgMC4wMDE7XG4gICAgY29uc3QgdGlja0ZvbnQgPSB0aGlzLl9yZXNvbHZlVGlja0ZvbnRPcHRpb25zKDApO1xuICAgIHJldHVybiBNYXRoLmNlaWwobGVuZ3RoIC8gTWF0aC5taW4oNDAsIHRpY2tGb250LmxpbmVIZWlnaHQgLyByYXRpbykpO1xuICB9XG5cbiAgLy8gVXRpbHNcbiAgZ2V0UGl4ZWxGb3JWYWx1ZSh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCA/IE5hTiA6IHRoaXMuZ2V0UGl4ZWxGb3JEZWNpbWFsKCh2YWx1ZSAtIHRoaXMuX3N0YXJ0VmFsdWUpIC8gdGhpcy5fdmFsdWVSYW5nZSk7XG4gIH1cblxuICBnZXRWYWx1ZUZvclBpeGVsKHBpeGVsKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXJ0VmFsdWUgKyB0aGlzLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkgKiB0aGlzLl92YWx1ZVJhbmdlO1xuICB9XG59XG4iLCAiaW1wb3J0IHtmaW5pdGVPckRlZmF1bHQsIGlzRmluaXRlfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29yZS5qcyc7XG5pbXBvcnQge2Zvcm1hdE51bWJlcn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmludGwuanMnO1xuaW1wb3J0IHtfc2V0TWluQW5kTWF4QnlLZXksIGxvZzEwfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMubWF0aC5qcyc7XG5pbXBvcnQgU2NhbGUgZnJvbSAnLi4vY29yZS9jb3JlLnNjYWxlLmpzJztcbmltcG9ydCBMaW5lYXJTY2FsZUJhc2UgZnJvbSAnLi9zY2FsZS5saW5lYXJiYXNlLmpzJztcbmltcG9ydCBUaWNrcyBmcm9tICcuLi9jb3JlL2NvcmUudGlja3MuanMnO1xuXG5jb25zdCBsb2cxMEZsb29yID0gdiA9PiBNYXRoLmZsb29yKGxvZzEwKHYpKTtcbmNvbnN0IGNoYW5nZUV4cG9uZW50ID0gKHYsIG0pID0+IE1hdGgucG93KDEwLCBsb2cxMEZsb29yKHYpICsgbSk7XG5cbmZ1bmN0aW9uIGlzTWFqb3IodGlja1ZhbCkge1xuICBjb25zdCByZW1haW4gPSB0aWNrVmFsIC8gKE1hdGgucG93KDEwLCBsb2cxMEZsb29yKHRpY2tWYWwpKSk7XG4gIHJldHVybiByZW1haW4gPT09IDE7XG59XG5cbmZ1bmN0aW9uIHN0ZXBzKG1pbiwgbWF4LCByYW5nZUV4cCkge1xuICBjb25zdCByYW5nZVN0ZXAgPSBNYXRoLnBvdygxMCwgcmFuZ2VFeHApO1xuICBjb25zdCBzdGFydCA9IE1hdGguZmxvb3IobWluIC8gcmFuZ2VTdGVwKTtcbiAgY29uc3QgZW5kID0gTWF0aC5jZWlsKG1heCAvIHJhbmdlU3RlcCk7XG4gIHJldHVybiBlbmQgLSBzdGFydDtcbn1cblxuZnVuY3Rpb24gc3RhcnRFeHAobWluLCBtYXgpIHtcbiAgY29uc3QgcmFuZ2UgPSBtYXggLSBtaW47XG4gIGxldCByYW5nZUV4cCA9IGxvZzEwRmxvb3IocmFuZ2UpO1xuICB3aGlsZSAoc3RlcHMobWluLCBtYXgsIHJhbmdlRXhwKSA+IDEwKSB7XG4gICAgcmFuZ2VFeHArKztcbiAgfVxuICB3aGlsZSAoc3RlcHMobWluLCBtYXgsIHJhbmdlRXhwKSA8IDEwKSB7XG4gICAgcmFuZ2VFeHAtLTtcbiAgfVxuICByZXR1cm4gTWF0aC5taW4ocmFuZ2VFeHAsIGxvZzEwRmxvb3IobWluKSk7XG59XG5cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIHNldCBvZiBsb2dhcml0aG1pYyB0aWNrc1xuICogQHBhcmFtIGdlbmVyYXRpb25PcHRpb25zIHRoZSBvcHRpb25zIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIHRpY2tzXG4gKiBAcGFyYW0gZGF0YVJhbmdlIHRoZSByYW5nZSBvZiB0aGUgZGF0YVxuICogQHJldHVybnMge29iamVjdFtdfSBhcnJheSBvZiB0aWNrIG9iamVjdHNcbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVUaWNrcyhnZW5lcmF0aW9uT3B0aW9ucywge21pbiwgbWF4fSkge1xuICBtaW4gPSBmaW5pdGVPckRlZmF1bHQoZ2VuZXJhdGlvbk9wdGlvbnMubWluLCBtaW4pO1xuICBjb25zdCB0aWNrcyA9IFtdO1xuICBjb25zdCBtaW5FeHAgPSBsb2cxMEZsb29yKG1pbik7XG4gIGxldCBleHAgPSBzdGFydEV4cChtaW4sIG1heCk7XG4gIGxldCBwcmVjaXNpb24gPSBleHAgPCAwID8gTWF0aC5wb3coMTAsIE1hdGguYWJzKGV4cCkpIDogMTtcbiAgY29uc3Qgc3RlcFNpemUgPSBNYXRoLnBvdygxMCwgZXhwKTtcbiAgY29uc3QgYmFzZSA9IG1pbkV4cCA+IGV4cCA/IE1hdGgucG93KDEwLCBtaW5FeHApIDogMDtcbiAgY29uc3Qgc3RhcnQgPSBNYXRoLnJvdW5kKChtaW4gLSBiYXNlKSAqIHByZWNpc2lvbikgLyBwcmVjaXNpb247XG4gIGNvbnN0IG9mZnNldCA9IE1hdGguZmxvb3IoKG1pbiAtIGJhc2UpIC8gc3RlcFNpemUgLyAxMCkgKiBzdGVwU2l6ZSAqIDEwO1xuICBsZXQgc2lnbmlmaWNhbmQgPSBNYXRoLmZsb29yKChzdGFydCAtIG9mZnNldCkgLyBNYXRoLnBvdygxMCwgZXhwKSk7XG4gIGxldCB2YWx1ZSA9IGZpbml0ZU9yRGVmYXVsdChnZW5lcmF0aW9uT3B0aW9ucy5taW4sIE1hdGgucm91bmQoKGJhc2UgKyBvZmZzZXQgKyBzaWduaWZpY2FuZCAqIE1hdGgucG93KDEwLCBleHApKSAqIHByZWNpc2lvbikgLyBwcmVjaXNpb24pO1xuICB3aGlsZSAodmFsdWUgPCBtYXgpIHtcbiAgICB0aWNrcy5wdXNoKHt2YWx1ZSwgbWFqb3I6IGlzTWFqb3IodmFsdWUpLCBzaWduaWZpY2FuZH0pO1xuICAgIGlmIChzaWduaWZpY2FuZCA+PSAxMCkge1xuICAgICAgc2lnbmlmaWNhbmQgPSBzaWduaWZpY2FuZCA8IDE1ID8gMTUgOiAyMDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2lnbmlmaWNhbmQrKztcbiAgICB9XG4gICAgaWYgKHNpZ25pZmljYW5kID49IDIwKSB7XG4gICAgICBleHArKztcbiAgICAgIHNpZ25pZmljYW5kID0gMjtcbiAgICAgIHByZWNpc2lvbiA9IGV4cCA+PSAwID8gMSA6IHByZWNpc2lvbjtcbiAgICB9XG4gICAgdmFsdWUgPSBNYXRoLnJvdW5kKChiYXNlICsgb2Zmc2V0ICsgc2lnbmlmaWNhbmQgKiBNYXRoLnBvdygxMCwgZXhwKSkgKiBwcmVjaXNpb24pIC8gcHJlY2lzaW9uO1xuICB9XG4gIGNvbnN0IGxhc3RUaWNrID0gZmluaXRlT3JEZWZhdWx0KGdlbmVyYXRpb25PcHRpb25zLm1heCwgdmFsdWUpO1xuICB0aWNrcy5wdXNoKHt2YWx1ZTogbGFzdFRpY2ssIG1ham9yOiBpc01ham9yKGxhc3RUaWNrKSwgc2lnbmlmaWNhbmR9KTtcblxuICByZXR1cm4gdGlja3M7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExvZ2FyaXRobWljU2NhbGUgZXh0ZW5kcyBTY2FsZSB7XG5cbiAgc3RhdGljIGlkID0gJ2xvZ2FyaXRobWljJztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICB0aWNrczoge1xuICAgICAgY2FsbGJhY2s6IFRpY2tzLmZvcm1hdHRlcnMubG9nYXJpdGhtaWMsXG4gICAgICBtYWpvcjoge1xuICAgICAgICBlbmFibGVkOiB0cnVlXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG5cbiAgY29uc3RydWN0b3IoY2ZnKSB7XG4gICAgc3VwZXIoY2ZnKTtcblxuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuc3RhcnQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5lbmQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5fc3RhcnRWYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl92YWx1ZVJhbmdlID0gMDtcbiAgfVxuXG4gIHBhcnNlKHJhdywgaW5kZXgpIHtcbiAgICBjb25zdCB2YWx1ZSA9IExpbmVhclNjYWxlQmFzZS5wcm90b3R5cGUucGFyc2UuYXBwbHkodGhpcywgW3JhdywgaW5kZXhdKTtcbiAgICBpZiAodmFsdWUgPT09IDApIHtcbiAgICAgIHRoaXMuX3plcm8gPSB0cnVlO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+IDAgPyB2YWx1ZSA6IG51bGw7XG4gIH1cblxuICBkZXRlcm1pbmVEYXRhTGltaXRzKCkge1xuICAgIGNvbnN0IHttaW4sIG1heH0gPSB0aGlzLmdldE1pbk1heCh0cnVlKTtcblxuICAgIHRoaXMubWluID0gaXNGaW5pdGUobWluKSA/IE1hdGgubWF4KDAsIG1pbikgOiBudWxsO1xuICAgIHRoaXMubWF4ID0gaXNGaW5pdGUobWF4KSA/IE1hdGgubWF4KDAsIG1heCkgOiBudWxsO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5iZWdpbkF0WmVybykge1xuICAgICAgdGhpcy5femVybyA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gaWYgZGF0YSBoYXMgYDBgIGluIGl0IG9yIGBiZWdpbkF0WmVyb2AgaXMgdHJ1ZSwgbWluIChub24gemVybykgdmFsdWUgaXMgYXQgYm90dG9tXG4gICAgLy8gb2Ygc2NhbGUsIGFuZCBpdCBkb2VzIG5vdCBlcXVhbCBzdWdnZXN0ZWRNaW4sIGxvd2VyIHRoZSBtaW4gYm91bmQgYnkgb25lIGV4cC5cbiAgICBpZiAodGhpcy5femVybyAmJiB0aGlzLm1pbiAhPT0gdGhpcy5fc3VnZ2VzdGVkTWluICYmICFpc0Zpbml0ZSh0aGlzLl91c2VyTWluKSkge1xuICAgICAgdGhpcy5taW4gPSBtaW4gPT09IGNoYW5nZUV4cG9uZW50KHRoaXMubWluLCAwKSA/IGNoYW5nZUV4cG9uZW50KHRoaXMubWluLCAtMSkgOiBjaGFuZ2VFeHBvbmVudCh0aGlzLm1pbiwgMCk7XG4gICAgfVxuXG4gICAgdGhpcy5oYW5kbGVUaWNrUmFuZ2VPcHRpb25zKCk7XG4gIH1cblxuICBoYW5kbGVUaWNrUmFuZ2VPcHRpb25zKCkge1xuICAgIGNvbnN0IHttaW5EZWZpbmVkLCBtYXhEZWZpbmVkfSA9IHRoaXMuZ2V0VXNlckJvdW5kcygpO1xuICAgIGxldCBtaW4gPSB0aGlzLm1pbjtcbiAgICBsZXQgbWF4ID0gdGhpcy5tYXg7XG5cbiAgICBjb25zdCBzZXRNaW4gPSB2ID0+IChtaW4gPSBtaW5EZWZpbmVkID8gbWluIDogdik7XG4gICAgY29uc3Qgc2V0TWF4ID0gdiA9PiAobWF4ID0gbWF4RGVmaW5lZCA/IG1heCA6IHYpO1xuXG4gICAgaWYgKG1pbiA9PT0gbWF4KSB7XG4gICAgICBpZiAobWluIDw9IDApIHsgLy8gaW5jbHVkZXMgbnVsbFxuICAgICAgICBzZXRNaW4oMSk7XG4gICAgICAgIHNldE1heCgxMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRNaW4oY2hhbmdlRXhwb25lbnQobWluLCAtMSkpO1xuICAgICAgICBzZXRNYXgoY2hhbmdlRXhwb25lbnQobWF4LCArMSkpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobWluIDw9IDApIHtcbiAgICAgIHNldE1pbihjaGFuZ2VFeHBvbmVudChtYXgsIC0xKSk7XG4gICAgfVxuICAgIGlmIChtYXggPD0gMCkge1xuXG4gICAgICBzZXRNYXgoY2hhbmdlRXhwb25lbnQobWluLCArMSkpO1xuICAgIH1cblxuICAgIHRoaXMubWluID0gbWluO1xuICAgIHRoaXMubWF4ID0gbWF4O1xuICB9XG5cbiAgYnVpbGRUaWNrcygpIHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5vcHRpb25zO1xuXG4gICAgY29uc3QgZ2VuZXJhdGlvbk9wdGlvbnMgPSB7XG4gICAgICBtaW46IHRoaXMuX3VzZXJNaW4sXG4gICAgICBtYXg6IHRoaXMuX3VzZXJNYXhcbiAgICB9O1xuICAgIGNvbnN0IHRpY2tzID0gZ2VuZXJhdGVUaWNrcyhnZW5lcmF0aW9uT3B0aW9ucywgdGhpcyk7XG5cbiAgICAvLyBBdCB0aGlzIHBvaW50LCB3ZSBuZWVkIHRvIHVwZGF0ZSBvdXIgbWF4IGFuZCBtaW4gZ2l2ZW4gdGhlIHRpY2sgdmFsdWVzLFxuICAgIC8vIHNpbmNlIHdlIHByb2JhYmx5IGhhdmUgZXhwYW5kZWQgdGhlIHJhbmdlIG9mIHRoZSBzY2FsZVxuICAgIGlmIChvcHRzLmJvdW5kcyA9PT0gJ3RpY2tzJykge1xuICAgICAgX3NldE1pbkFuZE1heEJ5S2V5KHRpY2tzLCB0aGlzLCAndmFsdWUnKTtcbiAgICB9XG5cbiAgICBpZiAob3B0cy5yZXZlcnNlKSB7XG4gICAgICB0aWNrcy5yZXZlcnNlKCk7XG5cbiAgICAgIHRoaXMuc3RhcnQgPSB0aGlzLm1heDtcbiAgICAgIHRoaXMuZW5kID0gdGhpcy5taW47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RhcnQgPSB0aGlzLm1pbjtcbiAgICAgIHRoaXMuZW5kID0gdGhpcy5tYXg7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRpY2tzO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdCAqL1xuICBnZXRMYWJlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWRcbiAgICAgID8gJzAnXG4gICAgICA6IGZvcm1hdE51bWJlcih2YWx1ZSwgdGhpcy5jaGFydC5vcHRpb25zLmxvY2FsZSwgdGhpcy5vcHRpb25zLnRpY2tzLmZvcm1hdCk7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgY29uZmlndXJlKCkge1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5taW47XG5cbiAgICBzdXBlci5jb25maWd1cmUoKTtcblxuICAgIHRoaXMuX3N0YXJ0VmFsdWUgPSBsb2cxMChzdGFydCk7XG4gICAgdGhpcy5fdmFsdWVSYW5nZSA9IGxvZzEwKHRoaXMubWF4KSAtIGxvZzEwKHN0YXJ0KTtcbiAgfVxuXG4gIGdldFBpeGVsRm9yVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gMCkge1xuICAgICAgdmFsdWUgPSB0aGlzLm1pbjtcbiAgICB9XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IGlzTmFOKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIE5hTjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JEZWNpbWFsKHZhbHVlID09PSB0aGlzLm1pblxuICAgICAgPyAwXG4gICAgICA6IChsb2cxMCh2YWx1ZSkgLSB0aGlzLl9zdGFydFZhbHVlKSAvIHRoaXMuX3ZhbHVlUmFuZ2UpO1xuICB9XG5cbiAgZ2V0VmFsdWVGb3JQaXhlbChwaXhlbCkge1xuICAgIGNvbnN0IGRlY2ltYWwgPSB0aGlzLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCk7XG4gICAgcmV0dXJuIE1hdGgucG93KDEwLCB0aGlzLl9zdGFydFZhbHVlICsgZGVjaW1hbCAqIHRoaXMuX3ZhbHVlUmFuZ2UpO1xuICB9XG59XG4iLCAiaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uL2NvcmUvY29yZS5kZWZhdWx0cy5qcyc7XG5pbXBvcnQge19sb25nZXN0VGV4dCwgYWRkUm91bmRlZFJlY3RQYXRoLCByZW5kZXJUZXh0LCBfaXNQb2ludEluQXJlYX0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNhbnZhcy5qcyc7XG5pbXBvcnQge0hBTEZfUEksIFRBVSwgdG9EZWdyZWVzLCB0b1JhZGlhbnMsIF9ub3JtYWxpemVBbmdsZSwgUEl9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCBMaW5lYXJTY2FsZUJhc2UgZnJvbSAnLi9zY2FsZS5saW5lYXJiYXNlLmpzJztcbmltcG9ydCBUaWNrcyBmcm9tICcuLi9jb3JlL2NvcmUudGlja3MuanMnO1xuaW1wb3J0IHt2YWx1ZU9yRGVmYXVsdCwgaXNBcnJheSwgaXNGaW5pdGUsIGNhbGxiYWNrIGFzIGNhbGxDYWxsYmFjaywgaXNOdWxsT3JVbmRlZn0gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLmNvcmUuanMnO1xuaW1wb3J0IHtjcmVhdGVDb250ZXh0LCB0b0ZvbnQsIHRvUGFkZGluZywgdG9UUkJMQ29ybmVyc30gZnJvbSAnLi4vaGVscGVycy9oZWxwZXJzLm9wdGlvbnMuanMnO1xuXG5mdW5jdGlvbiBnZXRUaWNrQmFja2Ryb3BIZWlnaHQob3B0cykge1xuICBjb25zdCB0aWNrT3B0cyA9IG9wdHMudGlja3M7XG5cbiAgaWYgKHRpY2tPcHRzLmRpc3BsYXkgJiYgb3B0cy5kaXNwbGF5KSB7XG4gICAgY29uc3QgcGFkZGluZyA9IHRvUGFkZGluZyh0aWNrT3B0cy5iYWNrZHJvcFBhZGRpbmcpO1xuICAgIHJldHVybiB2YWx1ZU9yRGVmYXVsdCh0aWNrT3B0cy5mb250ICYmIHRpY2tPcHRzLmZvbnQuc2l6ZSwgZGVmYXVsdHMuZm9udC5zaXplKSArIHBhZGRpbmcuaGVpZ2h0O1xuICB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBtZWFzdXJlTGFiZWxTaXplKGN0eCwgZm9udCwgbGFiZWwpIHtcbiAgbGFiZWwgPSBpc0FycmF5KGxhYmVsKSA/IGxhYmVsIDogW2xhYmVsXTtcbiAgcmV0dXJuIHtcbiAgICB3OiBfbG9uZ2VzdFRleHQoY3R4LCBmb250LnN0cmluZywgbGFiZWwpLFxuICAgIGg6IGxhYmVsLmxlbmd0aCAqIGZvbnQubGluZUhlaWdodFxuICB9O1xufVxuXG5mdW5jdGlvbiBkZXRlcm1pbmVMaW1pdHMoYW5nbGUsIHBvcywgc2l6ZSwgbWluLCBtYXgpIHtcbiAgaWYgKGFuZ2xlID09PSBtaW4gfHwgYW5nbGUgPT09IG1heCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGFydDogcG9zIC0gKHNpemUgLyAyKSxcbiAgICAgIGVuZDogcG9zICsgKHNpemUgLyAyKVxuICAgIH07XG4gIH0gZWxzZSBpZiAoYW5nbGUgPCBtaW4gfHwgYW5nbGUgPiBtYXgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhcnQ6IHBvcyAtIHNpemUsXG4gICAgICBlbmQ6IHBvc1xuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHN0YXJ0OiBwb3MsXG4gICAgZW5kOiBwb3MgKyBzaXplXG4gIH07XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGZpdCBhIHJhZGlhbCBsaW5lYXIgc2NhbGUgd2l0aCBwb2ludCBsYWJlbHNcbiAqL1xuZnVuY3Rpb24gZml0V2l0aFBvaW50TGFiZWxzKHNjYWxlKSB7XG5cbiAgLy8gUmlnaHQsIHRoaXMgaXMgcmVhbGx5IGNvbmZ1c2luZyBhbmQgdGhlcmUgaXMgYSBsb3Qgb2YgbWF0aHMgZ29pbmcgb24gaGVyZVxuICAvLyBUaGUgZ2lzdCBvZiB0aGUgcHJvYmxlbSBpcyBoZXJlOiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9ubm5pY2svNjk2Y2M5YzU1ZjRiMGJlYjhmZTlcbiAgLy9cbiAgLy8gUmVhY3Rpb246IGh0dHBzOi8vZGwuZHJvcGJveHVzZXJjb250ZW50LmNvbS91LzM0NjAxMzYzL3Rvb211Y2hzY2llbmNlLmdpZlxuICAvL1xuICAvLyBTb2x1dGlvbjpcbiAgLy9cbiAgLy8gV2UgYXNzdW1lIHRoZSByYWRpdXMgb2YgdGhlIHBvbHlnb24gaXMgaGFsZiB0aGUgc2l6ZSBvZiB0aGUgY2FudmFzIGF0IGZpcnN0XG4gIC8vIGF0IGVhY2ggaW5kZXggd2UgY2hlY2sgaWYgdGhlIHRleHQgb3ZlcmxhcHMuXG4gIC8vXG4gIC8vIFdoZXJlIGl0IGRvZXMsIHdlIHN0b3JlIHRoYXQgYW5nbGUgYW5kIHRoYXQgaW5kZXguXG4gIC8vXG4gIC8vIEFmdGVyIGZpbmRpbmcgdGhlIGxhcmdlc3QgaW5kZXggYW5kIGFuZ2xlIHdlIGNhbGN1bGF0ZSBob3cgbXVjaCB3ZSBuZWVkIHRvIHJlbW92ZVxuICAvLyBmcm9tIHRoZSBzaGFwZSByYWRpdXMgdG8gbW92ZSB0aGUgcG9pbnQgaW53YXJkcyBieSB0aGF0IHguXG4gIC8vXG4gIC8vIFdlIGF2ZXJhZ2UgdGhlIGxlZnQgYW5kIHJpZ2h0IGRpc3RhbmNlcyB0byBnZXQgdGhlIG1heGltdW0gc2hhcGUgcmFkaXVzIHRoYXQgY2FuIGZpdCBpbiB0aGUgYm94XG4gIC8vIGFsb25nIHdpdGggbGFiZWxzLlxuICAvL1xuICAvLyBPbmNlIHdlIGhhdmUgdGhhdCwgd2UgY2FuIGZpbmQgdGhlIGNlbnRyZSBwb2ludCBmb3IgdGhlIGNoYXJ0LCBieSB0YWtpbmcgdGhlIHggdGV4dCBwcm90cnVzaW9uXG4gIC8vIG9uIGVhY2ggc2lkZSwgcmVtb3ZpbmcgdGhhdCBmcm9tIHRoZSBzaXplLCBoYWx2aW5nIGl0IGFuZCBhZGRpbmcgdGhlIGxlZnQgeCBwcm90cnVzaW9uIHdpZHRoLlxuICAvL1xuICAvLyBUaGlzIHdpbGwgbWVhbiB3ZSBoYXZlIGEgc2hhcGUgZml0dGVkIHRvIHRoZSBjYW52YXMsIGFzIGxhcmdlIGFzIGl0IGNhbiBiZSB3aXRoIHRoZSBsYWJlbHNcbiAgLy8gYW5kIHBvc2l0aW9uIGl0IGluIHRoZSBtb3N0IHNwYWNlIGVmZmljaWVudCBtYW5uZXJcbiAgLy9cbiAgLy8gaHR0cHM6Ly9kbC5kcm9wYm94dXNlcmNvbnRlbnQuY29tL3UvMzQ2MDEzNjMveWVhaHNjaWVuY2UuZ2lmXG5cbiAgLy8gR2V0IG1heGltdW0gcmFkaXVzIG9mIHRoZSBwb2x5Z29uLiBFaXRoZXIgaGFsZiB0aGUgaGVpZ2h0IChtaW51cyB0aGUgdGV4dCB3aWR0aCkgb3IgaGFsZiB0aGUgd2lkdGguXG4gIC8vIFVzZSB0aGlzIHRvIGNhbGN1bGF0ZSB0aGUgb2Zmc2V0ICsgY2hhbmdlLiAtIE1ha2Ugc3VyZSBML1IgcHJvdHJ1c2lvbiBpcyBhdCBsZWFzdCAwIHRvIHN0b3AgaXNzdWVzIHdpdGggY2VudHJlIHBvaW50c1xuICBjb25zdCBvcmlnID0ge1xuICAgIGw6IHNjYWxlLmxlZnQgKyBzY2FsZS5fcGFkZGluZy5sZWZ0LFxuICAgIHI6IHNjYWxlLnJpZ2h0IC0gc2NhbGUuX3BhZGRpbmcucmlnaHQsXG4gICAgdDogc2NhbGUudG9wICsgc2NhbGUuX3BhZGRpbmcudG9wLFxuICAgIGI6IHNjYWxlLmJvdHRvbSAtIHNjYWxlLl9wYWRkaW5nLmJvdHRvbVxuICB9O1xuICBjb25zdCBsaW1pdHMgPSBPYmplY3QuYXNzaWduKHt9LCBvcmlnKTtcbiAgY29uc3QgbGFiZWxTaXplcyA9IFtdO1xuICBjb25zdCBwYWRkaW5nID0gW107XG4gIGNvbnN0IHZhbHVlQ291bnQgPSBzY2FsZS5fcG9pbnRMYWJlbHMubGVuZ3RoO1xuICBjb25zdCBwb2ludExhYmVsT3B0cyA9IHNjYWxlLm9wdGlvbnMucG9pbnRMYWJlbHM7XG4gIGNvbnN0IGFkZGl0aW9uYWxBbmdsZSA9IHBvaW50TGFiZWxPcHRzLmNlbnRlclBvaW50TGFiZWxzID8gUEkgLyB2YWx1ZUNvdW50IDogMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlQ291bnQ7IGkrKykge1xuICAgIGNvbnN0IG9wdHMgPSBwb2ludExhYmVsT3B0cy5zZXRDb250ZXh0KHNjYWxlLmdldFBvaW50TGFiZWxDb250ZXh0KGkpKTtcbiAgICBwYWRkaW5nW2ldID0gb3B0cy5wYWRkaW5nO1xuICAgIGNvbnN0IHBvaW50UG9zaXRpb24gPSBzY2FsZS5nZXRQb2ludFBvc2l0aW9uKGksIHNjYWxlLmRyYXdpbmdBcmVhICsgcGFkZGluZ1tpXSwgYWRkaXRpb25hbEFuZ2xlKTtcbiAgICBjb25zdCBwbEZvbnQgPSB0b0ZvbnQob3B0cy5mb250KTtcbiAgICBjb25zdCB0ZXh0U2l6ZSA9IG1lYXN1cmVMYWJlbFNpemUoc2NhbGUuY3R4LCBwbEZvbnQsIHNjYWxlLl9wb2ludExhYmVsc1tpXSk7XG4gICAgbGFiZWxTaXplc1tpXSA9IHRleHRTaXplO1xuXG4gICAgY29uc3QgYW5nbGVSYWRpYW5zID0gX25vcm1hbGl6ZUFuZ2xlKHNjYWxlLmdldEluZGV4QW5nbGUoaSkgKyBhZGRpdGlvbmFsQW5nbGUpO1xuICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5yb3VuZCh0b0RlZ3JlZXMoYW5nbGVSYWRpYW5zKSk7XG4gICAgY29uc3QgaExpbWl0cyA9IGRldGVybWluZUxpbWl0cyhhbmdsZSwgcG9pbnRQb3NpdGlvbi54LCB0ZXh0U2l6ZS53LCAwLCAxODApO1xuICAgIGNvbnN0IHZMaW1pdHMgPSBkZXRlcm1pbmVMaW1pdHMoYW5nbGUsIHBvaW50UG9zaXRpb24ueSwgdGV4dFNpemUuaCwgOTAsIDI3MCk7XG4gICAgdXBkYXRlTGltaXRzKGxpbWl0cywgb3JpZywgYW5nbGVSYWRpYW5zLCBoTGltaXRzLCB2TGltaXRzKTtcbiAgfVxuXG4gIHNjYWxlLnNldENlbnRlclBvaW50KFxuICAgIG9yaWcubCAtIGxpbWl0cy5sLFxuICAgIGxpbWl0cy5yIC0gb3JpZy5yLFxuICAgIG9yaWcudCAtIGxpbWl0cy50LFxuICAgIGxpbWl0cy5iIC0gb3JpZy5iXG4gICk7XG5cbiAgLy8gTm93IHRoYXQgdGV4dCBzaXplIGlzIGRldGVybWluZWQsIGNvbXB1dGUgdGhlIGZ1bGwgcG9zaXRpb25zXG4gIHNjYWxlLl9wb2ludExhYmVsSXRlbXMgPSBidWlsZFBvaW50TGFiZWxJdGVtcyhzY2FsZSwgbGFiZWxTaXplcywgcGFkZGluZyk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUxpbWl0cyhsaW1pdHMsIG9yaWcsIGFuZ2xlLCBoTGltaXRzLCB2TGltaXRzKSB7XG4gIGNvbnN0IHNpbiA9IE1hdGguYWJzKE1hdGguc2luKGFuZ2xlKSk7XG4gIGNvbnN0IGNvcyA9IE1hdGguYWJzKE1hdGguY29zKGFuZ2xlKSk7XG4gIGxldCB4ID0gMDtcbiAgbGV0IHkgPSAwO1xuICBpZiAoaExpbWl0cy5zdGFydCA8IG9yaWcubCkge1xuICAgIHggPSAob3JpZy5sIC0gaExpbWl0cy5zdGFydCkgLyBzaW47XG4gICAgbGltaXRzLmwgPSBNYXRoLm1pbihsaW1pdHMubCwgb3JpZy5sIC0geCk7XG4gIH0gZWxzZSBpZiAoaExpbWl0cy5lbmQgPiBvcmlnLnIpIHtcbiAgICB4ID0gKGhMaW1pdHMuZW5kIC0gb3JpZy5yKSAvIHNpbjtcbiAgICBsaW1pdHMuciA9IE1hdGgubWF4KGxpbWl0cy5yLCBvcmlnLnIgKyB4KTtcbiAgfVxuICBpZiAodkxpbWl0cy5zdGFydCA8IG9yaWcudCkge1xuICAgIHkgPSAob3JpZy50IC0gdkxpbWl0cy5zdGFydCkgLyBjb3M7XG4gICAgbGltaXRzLnQgPSBNYXRoLm1pbihsaW1pdHMudCwgb3JpZy50IC0geSk7XG4gIH0gZWxzZSBpZiAodkxpbWl0cy5lbmQgPiBvcmlnLmIpIHtcbiAgICB5ID0gKHZMaW1pdHMuZW5kIC0gb3JpZy5iKSAvIGNvcztcbiAgICBsaW1pdHMuYiA9IE1hdGgubWF4KGxpbWl0cy5iLCBvcmlnLmIgKyB5KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVQb2ludExhYmVsSXRlbShzY2FsZSwgaW5kZXgsIGl0ZW1PcHRzKSB7XG4gIGNvbnN0IG91dGVyRGlzdGFuY2UgPSBzY2FsZS5kcmF3aW5nQXJlYTtcbiAgY29uc3Qge2V4dHJhLCBhZGRpdGlvbmFsQW5nbGUsIHBhZGRpbmcsIHNpemV9ID0gaXRlbU9wdHM7XG4gIGNvbnN0IHBvaW50TGFiZWxQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb24oaW5kZXgsIG91dGVyRGlzdGFuY2UgKyBleHRyYSArIHBhZGRpbmcsIGFkZGl0aW9uYWxBbmdsZSk7XG4gIGNvbnN0IGFuZ2xlID0gTWF0aC5yb3VuZCh0b0RlZ3JlZXMoX25vcm1hbGl6ZUFuZ2xlKHBvaW50TGFiZWxQb3NpdGlvbi5hbmdsZSArIEhBTEZfUEkpKSk7XG4gIGNvbnN0IHkgPSB5Rm9yQW5nbGUocG9pbnRMYWJlbFBvc2l0aW9uLnksIHNpemUuaCwgYW5nbGUpO1xuICBjb25zdCB0ZXh0QWxpZ24gPSBnZXRUZXh0QWxpZ25Gb3JBbmdsZShhbmdsZSk7XG4gIGNvbnN0IGxlZnQgPSBsZWZ0Rm9yVGV4dEFsaWduKHBvaW50TGFiZWxQb3NpdGlvbi54LCBzaXplLncsIHRleHRBbGlnbik7XG4gIHJldHVybiB7XG4gICAgLy8gaWYgdG8gZHJhdyBvciBvdmVybGFwcGVkXG4gICAgdmlzaWJsZTogdHJ1ZSxcblxuICAgIC8vIFRleHQgcG9zaXRpb25cbiAgICB4OiBwb2ludExhYmVsUG9zaXRpb24ueCxcbiAgICB5LFxuXG4gICAgLy8gVGV4dCByZW5kZXJpbmcgZGF0YVxuICAgIHRleHRBbGlnbixcblxuICAgIC8vIEJvdW5kaW5nIGJveFxuICAgIGxlZnQsXG4gICAgdG9wOiB5LFxuICAgIHJpZ2h0OiBsZWZ0ICsgc2l6ZS53LFxuICAgIGJvdHRvbTogeSArIHNpemUuaFxuICB9O1xufVxuXG5mdW5jdGlvbiBpc05vdE92ZXJsYXBwZWQoaXRlbSwgYXJlYSkge1xuICBpZiAoIWFyZWEpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBjb25zdCB7bGVmdCwgdG9wLCByaWdodCwgYm90dG9tfSA9IGl0ZW07XG4gIGNvbnN0IGFwZXhlc0luQXJlYSA9IF9pc1BvaW50SW5BcmVhKHt4OiBsZWZ0LCB5OiB0b3B9LCBhcmVhKSB8fCBfaXNQb2ludEluQXJlYSh7eDogbGVmdCwgeTogYm90dG9tfSwgYXJlYSkgfHxcbiAgICBfaXNQb2ludEluQXJlYSh7eDogcmlnaHQsIHk6IHRvcH0sIGFyZWEpIHx8IF9pc1BvaW50SW5BcmVhKHt4OiByaWdodCwgeTogYm90dG9tfSwgYXJlYSk7XG4gIHJldHVybiAhYXBleGVzSW5BcmVhO1xufVxuXG5mdW5jdGlvbiBidWlsZFBvaW50TGFiZWxJdGVtcyhzY2FsZSwgbGFiZWxTaXplcywgcGFkZGluZykge1xuICBjb25zdCBpdGVtcyA9IFtdO1xuICBjb25zdCB2YWx1ZUNvdW50ID0gc2NhbGUuX3BvaW50TGFiZWxzLmxlbmd0aDtcbiAgY29uc3Qgb3B0cyA9IHNjYWxlLm9wdGlvbnM7XG4gIGNvbnN0IHtjZW50ZXJQb2ludExhYmVscywgZGlzcGxheX0gPSBvcHRzLnBvaW50TGFiZWxzO1xuICBjb25zdCBpdGVtT3B0cyA9IHtcbiAgICBleHRyYTogZ2V0VGlja0JhY2tkcm9wSGVpZ2h0KG9wdHMpIC8gMixcbiAgICBhZGRpdGlvbmFsQW5nbGU6IGNlbnRlclBvaW50TGFiZWxzID8gUEkgLyB2YWx1ZUNvdW50IDogMFxuICB9O1xuICBsZXQgYXJlYTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlQ291bnQ7IGkrKykge1xuICAgIGl0ZW1PcHRzLnBhZGRpbmcgPSBwYWRkaW5nW2ldO1xuICAgIGl0ZW1PcHRzLnNpemUgPSBsYWJlbFNpemVzW2ldO1xuXG4gICAgY29uc3QgaXRlbSA9IGNyZWF0ZVBvaW50TGFiZWxJdGVtKHNjYWxlLCBpLCBpdGVtT3B0cyk7XG4gICAgaXRlbXMucHVzaChpdGVtKTtcbiAgICBpZiAoZGlzcGxheSA9PT0gJ2F1dG8nKSB7XG4gICAgICBpdGVtLnZpc2libGUgPSBpc05vdE92ZXJsYXBwZWQoaXRlbSwgYXJlYSk7XG4gICAgICBpZiAoaXRlbS52aXNpYmxlKSB7XG4gICAgICAgIGFyZWEgPSBpdGVtO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gaXRlbXM7XG59XG5cbmZ1bmN0aW9uIGdldFRleHRBbGlnbkZvckFuZ2xlKGFuZ2xlKSB7XG4gIGlmIChhbmdsZSA9PT0gMCB8fCBhbmdsZSA9PT0gMTgwKSB7XG4gICAgcmV0dXJuICdjZW50ZXInO1xuICB9IGVsc2UgaWYgKGFuZ2xlIDwgMTgwKSB7XG4gICAgcmV0dXJuICdsZWZ0JztcbiAgfVxuXG4gIHJldHVybiAncmlnaHQnO1xufVxuXG5mdW5jdGlvbiBsZWZ0Rm9yVGV4dEFsaWduKHgsIHcsIGFsaWduKSB7XG4gIGlmIChhbGlnbiA9PT0gJ3JpZ2h0Jykge1xuICAgIHggLT0gdztcbiAgfSBlbHNlIGlmIChhbGlnbiA9PT0gJ2NlbnRlcicpIHtcbiAgICB4IC09ICh3IC8gMik7XG4gIH1cbiAgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIHlGb3JBbmdsZSh5LCBoLCBhbmdsZSkge1xuICBpZiAoYW5nbGUgPT09IDkwIHx8IGFuZ2xlID09PSAyNzApIHtcbiAgICB5IC09IChoIC8gMik7XG4gIH0gZWxzZSBpZiAoYW5nbGUgPiAyNzAgfHwgYW5nbGUgPCA5MCkge1xuICAgIHkgLT0gaDtcbiAgfVxuICByZXR1cm4geTtcbn1cblxuZnVuY3Rpb24gZHJhd1BvaW50TGFiZWxCb3goY3R4LCBvcHRzLCBpdGVtKSB7XG4gIGNvbnN0IHtsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b219ID0gaXRlbTtcbiAgY29uc3Qge2JhY2tkcm9wQ29sb3J9ID0gb3B0cztcblxuICBpZiAoIWlzTnVsbE9yVW5kZWYoYmFja2Ryb3BDb2xvcikpIHtcbiAgICBjb25zdCBib3JkZXJSYWRpdXMgPSB0b1RSQkxDb3JuZXJzKG9wdHMuYm9yZGVyUmFkaXVzKTtcbiAgICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKG9wdHMuYmFja2Ryb3BQYWRkaW5nKTtcbiAgICBjdHguZmlsbFN0eWxlID0gYmFja2Ryb3BDb2xvcjtcblxuICAgIGNvbnN0IGJhY2tkcm9wTGVmdCA9IGxlZnQgLSBwYWRkaW5nLmxlZnQ7XG4gICAgY29uc3QgYmFja2Ryb3BUb3AgPSB0b3AgLSBwYWRkaW5nLnRvcDtcbiAgICBjb25zdCBiYWNrZHJvcFdpZHRoID0gcmlnaHQgLSBsZWZ0ICsgcGFkZGluZy53aWR0aDtcbiAgICBjb25zdCBiYWNrZHJvcEhlaWdodCA9IGJvdHRvbSAtIHRvcCArIHBhZGRpbmcuaGVpZ2h0O1xuXG4gICAgaWYgKE9iamVjdC52YWx1ZXMoYm9yZGVyUmFkaXVzKS5zb21lKHYgPT4gdiAhPT0gMCkpIHtcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGFkZFJvdW5kZWRSZWN0UGF0aChjdHgsIHtcbiAgICAgICAgeDogYmFja2Ryb3BMZWZ0LFxuICAgICAgICB5OiBiYWNrZHJvcFRvcCxcbiAgICAgICAgdzogYmFja2Ryb3BXaWR0aCxcbiAgICAgICAgaDogYmFja2Ryb3BIZWlnaHQsXG4gICAgICAgIHJhZGl1czogYm9yZGVyUmFkaXVzLFxuICAgICAgfSk7XG4gICAgICBjdHguZmlsbCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdHguZmlsbFJlY3QoYmFja2Ryb3BMZWZ0LCBiYWNrZHJvcFRvcCwgYmFja2Ryb3BXaWR0aCwgYmFja2Ryb3BIZWlnaHQpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkcmF3UG9pbnRMYWJlbHMoc2NhbGUsIGxhYmVsQ291bnQpIHtcbiAgY29uc3Qge2N0eCwgb3B0aW9uczoge3BvaW50TGFiZWxzfX0gPSBzY2FsZTtcblxuICBmb3IgKGxldCBpID0gbGFiZWxDb3VudCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3QgaXRlbSA9IHNjYWxlLl9wb2ludExhYmVsSXRlbXNbaV07XG4gICAgaWYgKCFpdGVtLnZpc2libGUpIHtcbiAgICAgIC8vIG92ZXJsYXBwaW5nXG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3Qgb3B0c0F0SW5kZXggPSBwb2ludExhYmVscy5zZXRDb250ZXh0KHNjYWxlLmdldFBvaW50TGFiZWxDb250ZXh0KGkpKTtcbiAgICBkcmF3UG9pbnRMYWJlbEJveChjdHgsIG9wdHNBdEluZGV4LCBpdGVtKTtcbiAgICBjb25zdCBwbEZvbnQgPSB0b0ZvbnQob3B0c0F0SW5kZXguZm9udCk7XG4gICAgY29uc3Qge3gsIHksIHRleHRBbGlnbn0gPSBpdGVtO1xuXG4gICAgcmVuZGVyVGV4dChcbiAgICAgIGN0eCxcbiAgICAgIHNjYWxlLl9wb2ludExhYmVsc1tpXSxcbiAgICAgIHgsXG4gICAgICB5ICsgKHBsRm9udC5saW5lSGVpZ2h0IC8gMiksXG4gICAgICBwbEZvbnQsXG4gICAgICB7XG4gICAgICAgIGNvbG9yOiBvcHRzQXRJbmRleC5jb2xvcixcbiAgICAgICAgdGV4dEFsaWduOiB0ZXh0QWxpZ24sXG4gICAgICAgIHRleHRCYXNlbGluZTogJ21pZGRsZSdcbiAgICAgIH1cbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhdGhSYWRpdXNMaW5lKHNjYWxlLCByYWRpdXMsIGNpcmN1bGFyLCBsYWJlbENvdW50KSB7XG4gIGNvbnN0IHtjdHh9ID0gc2NhbGU7XG4gIGlmIChjaXJjdWxhcikge1xuICAgIC8vIERyYXcgY2lyY3VsYXIgYXJjcyBiZXR3ZWVuIHRoZSBwb2ludHNcbiAgICBjdHguYXJjKHNjYWxlLnhDZW50ZXIsIHNjYWxlLnlDZW50ZXIsIHJhZGl1cywgMCwgVEFVKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBEcmF3IHN0cmFpZ2h0IGxpbmVzIGNvbm5lY3RpbmcgZWFjaCBpbmRleFxuICAgIGxldCBwb2ludFBvc2l0aW9uID0gc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbigwLCByYWRpdXMpO1xuICAgIGN0eC5tb3ZlVG8ocG9pbnRQb3NpdGlvbi54LCBwb2ludFBvc2l0aW9uLnkpO1xuXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBsYWJlbENvdW50OyBpKyspIHtcbiAgICAgIHBvaW50UG9zaXRpb24gPSBzY2FsZS5nZXRQb2ludFBvc2l0aW9uKGksIHJhZGl1cyk7XG4gICAgICBjdHgubGluZVRvKHBvaW50UG9zaXRpb24ueCwgcG9pbnRQb3NpdGlvbi55KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZHJhd1JhZGl1c0xpbmUoc2NhbGUsIGdyaWRMaW5lT3B0cywgcmFkaXVzLCBsYWJlbENvdW50LCBib3JkZXJPcHRzKSB7XG4gIGNvbnN0IGN0eCA9IHNjYWxlLmN0eDtcbiAgY29uc3QgY2lyY3VsYXIgPSBncmlkTGluZU9wdHMuY2lyY3VsYXI7XG5cbiAgY29uc3Qge2NvbG9yLCBsaW5lV2lkdGh9ID0gZ3JpZExpbmVPcHRzO1xuXG4gIGlmICgoIWNpcmN1bGFyICYmICFsYWJlbENvdW50KSB8fCAhY29sb3IgfHwgIWxpbmVXaWR0aCB8fCByYWRpdXMgPCAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY3R4LnNhdmUoKTtcbiAgY3R4LnN0cm9rZVN0eWxlID0gY29sb3I7XG4gIGN0eC5saW5lV2lkdGggPSBsaW5lV2lkdGg7XG4gIGN0eC5zZXRMaW5lRGFzaChib3JkZXJPcHRzLmRhc2gpO1xuICBjdHgubGluZURhc2hPZmZzZXQgPSBib3JkZXJPcHRzLmRhc2hPZmZzZXQ7XG5cbiAgY3R4LmJlZ2luUGF0aCgpO1xuICBwYXRoUmFkaXVzTGluZShzY2FsZSwgcmFkaXVzLCBjaXJjdWxhciwgbGFiZWxDb3VudCk7XG4gIGN0eC5jbG9zZVBhdGgoKTtcbiAgY3R4LnN0cm9rZSgpO1xuICBjdHgucmVzdG9yZSgpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVQb2ludExhYmVsQ29udGV4dChwYXJlbnQsIGluZGV4LCBsYWJlbCkge1xuICByZXR1cm4gY3JlYXRlQ29udGV4dChwYXJlbnQsIHtcbiAgICBsYWJlbCxcbiAgICBpbmRleCxcbiAgICB0eXBlOiAncG9pbnRMYWJlbCdcbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJhZGlhbExpbmVhclNjYWxlIGV4dGVuZHMgTGluZWFyU2NhbGVCYXNlIHtcblxuICBzdGF0aWMgaWQgPSAncmFkaWFsTGluZWFyJztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICBkaXNwbGF5OiB0cnVlLFxuXG4gICAgLy8gQm9vbGVhbiAtIFdoZXRoZXIgdG8gYW5pbWF0ZSBzY2FsaW5nIHRoZSBjaGFydCBmcm9tIHRoZSBjZW50cmVcbiAgICBhbmltYXRlOiB0cnVlLFxuICAgIHBvc2l0aW9uOiAnY2hhcnRBcmVhJyxcblxuICAgIGFuZ2xlTGluZXM6IHtcbiAgICAgIGRpc3BsYXk6IHRydWUsXG4gICAgICBsaW5lV2lkdGg6IDEsXG4gICAgICBib3JkZXJEYXNoOiBbXSxcbiAgICAgIGJvcmRlckRhc2hPZmZzZXQ6IDAuMFxuICAgIH0sXG5cbiAgICBncmlkOiB7XG4gICAgICBjaXJjdWxhcjogZmFsc2VcbiAgICB9LFxuXG4gICAgc3RhcnRBbmdsZTogMCxcblxuICAgIC8vIGxhYmVsIHNldHRpbmdzXG4gICAgdGlja3M6IHtcbiAgICAgIC8vIEJvb2xlYW4gLSBTaG93IGEgYmFja2Ryb3AgdG8gdGhlIHNjYWxlIGxhYmVsXG4gICAgICBzaG93TGFiZWxCYWNrZHJvcDogdHJ1ZSxcblxuICAgICAgY2FsbGJhY2s6IFRpY2tzLmZvcm1hdHRlcnMubnVtZXJpY1xuICAgIH0sXG5cbiAgICBwb2ludExhYmVsczoge1xuICAgICAgYmFja2Ryb3BDb2xvcjogdW5kZWZpbmVkLFxuXG4gICAgICAvLyBOdW1iZXIgLSBUaGUgYmFja2Ryb3AgcGFkZGluZyBhYm92ZSAmIGJlbG93IHRoZSBsYWJlbCBpbiBwaXhlbHNcbiAgICAgIGJhY2tkcm9wUGFkZGluZzogMixcblxuICAgICAgLy8gQm9vbGVhbiAtIGlmIHRydWUsIHNob3cgcG9pbnQgbGFiZWxzXG4gICAgICBkaXNwbGF5OiB0cnVlLFxuXG4gICAgICAvLyBOdW1iZXIgLSBQb2ludCBsYWJlbCBmb250IHNpemUgaW4gcGl4ZWxzXG4gICAgICBmb250OiB7XG4gICAgICAgIHNpemU6IDEwXG4gICAgICB9LFxuXG4gICAgICAvLyBGdW5jdGlvbiAtIFVzZWQgdG8gY29udmVydCBwb2ludCBsYWJlbHNcbiAgICAgIGNhbGxiYWNrKGxhYmVsKSB7XG4gICAgICAgIHJldHVybiBsYWJlbDtcbiAgICAgIH0sXG5cbiAgICAgIC8vIE51bWJlciAtIEFkZGl0aW9ubCBwYWRkaW5nIGJldHdlZW4gc2NhbGUgYW5kIHBvaW50TGFiZWxcbiAgICAgIHBhZGRpbmc6IDUsXG5cbiAgICAgIC8vIEJvb2xlYW4gLSBpZiB0cnVlLCBjZW50ZXIgcG9pbnQgbGFiZWxzIHRvIHNsaWNlcyBpbiBwb2xhciBjaGFydFxuICAgICAgY2VudGVyUG9pbnRMYWJlbHM6IGZhbHNlXG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBkZWZhdWx0Um91dGVzID0ge1xuICAgICdhbmdsZUxpbmVzLmNvbG9yJzogJ2JvcmRlckNvbG9yJyxcbiAgICAncG9pbnRMYWJlbHMuY29sb3InOiAnY29sb3InLFxuICAgICd0aWNrcy5jb2xvcic6ICdjb2xvcidcbiAgfTtcblxuICBzdGF0aWMgZGVzY3JpcHRvcnMgPSB7XG4gICAgYW5nbGVMaW5lczoge1xuICAgICAgX2ZhbGxiYWNrOiAnZ3JpZCdcbiAgICB9XG4gIH07XG5cbiAgY29uc3RydWN0b3IoY2ZnKSB7XG4gICAgc3VwZXIoY2ZnKTtcblxuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMueENlbnRlciA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLnlDZW50ZXIgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5kcmF3aW5nQXJlYSA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge3N0cmluZ1tdfSAqL1xuICAgIHRoaXMuX3BvaW50TGFiZWxzID0gW107XG4gICAgdGhpcy5fcG9pbnRMYWJlbEl0ZW1zID0gW107XG4gIH1cblxuICBzZXREaW1lbnNpb25zKCkge1xuICAgIC8vIFNldCB0aGUgdW5jb25zdHJhaW5lZCBkaW1lbnNpb24gYmVmb3JlIGxhYmVsIHJvdGF0aW9uXG4gICAgY29uc3QgcGFkZGluZyA9IHRoaXMuX3BhZGRpbmcgPSB0b1BhZGRpbmcoZ2V0VGlja0JhY2tkcm9wSGVpZ2h0KHRoaXMub3B0aW9ucykgLyAyKTtcbiAgICBjb25zdCB3ID0gdGhpcy53aWR0aCA9IHRoaXMubWF4V2lkdGggLSBwYWRkaW5nLndpZHRoO1xuICAgIGNvbnN0IGggPSB0aGlzLmhlaWdodCA9IHRoaXMubWF4SGVpZ2h0IC0gcGFkZGluZy5oZWlnaHQ7XG4gICAgdGhpcy54Q2VudGVyID0gTWF0aC5mbG9vcih0aGlzLmxlZnQgKyB3IC8gMiArIHBhZGRpbmcubGVmdCk7XG4gICAgdGhpcy55Q2VudGVyID0gTWF0aC5mbG9vcih0aGlzLnRvcCArIGggLyAyICsgcGFkZGluZy50b3ApO1xuICAgIHRoaXMuZHJhd2luZ0FyZWEgPSBNYXRoLmZsb29yKE1hdGgubWluKHcsIGgpIC8gMik7XG4gIH1cblxuICBkZXRlcm1pbmVEYXRhTGltaXRzKCkge1xuICAgIGNvbnN0IHttaW4sIG1heH0gPSB0aGlzLmdldE1pbk1heChmYWxzZSk7XG5cbiAgICB0aGlzLm1pbiA9IGlzRmluaXRlKG1pbikgJiYgIWlzTmFOKG1pbikgPyBtaW4gOiAwO1xuICAgIHRoaXMubWF4ID0gaXNGaW5pdGUobWF4KSAmJiAhaXNOYU4obWF4KSA/IG1heCA6IDA7XG5cbiAgICAvLyBDb21tb24gYmFzZSBpbXBsZW1lbnRhdGlvbiB0byBoYW5kbGUgbWluLCBtYXgsIGJlZ2luQXRaZXJvXG4gICAgdGhpcy5oYW5kbGVUaWNrUmFuZ2VPcHRpb25zKCk7XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGlja3MgYmFzZWQgb24gdGhlIHNjYWxlIGRpbWVuc2lvblxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBjb21wdXRlVGlja0xpbWl0KCkge1xuICAgIHJldHVybiBNYXRoLmNlaWwodGhpcy5kcmF3aW5nQXJlYSAvIGdldFRpY2tCYWNrZHJvcEhlaWdodCh0aGlzLm9wdGlvbnMpKTtcbiAgfVxuXG4gIGdlbmVyYXRlVGlja0xhYmVscyh0aWNrcykge1xuICAgIExpbmVhclNjYWxlQmFzZS5wcm90b3R5cGUuZ2VuZXJhdGVUaWNrTGFiZWxzLmNhbGwodGhpcywgdGlja3MpO1xuXG4gICAgLy8gUG9pbnQgbGFiZWxzXG4gICAgdGhpcy5fcG9pbnRMYWJlbHMgPSB0aGlzLmdldExhYmVscygpXG4gICAgICAubWFwKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgbGFiZWwgPSBjYWxsQ2FsbGJhY2sodGhpcy5vcHRpb25zLnBvaW50TGFiZWxzLmNhbGxiYWNrLCBbdmFsdWUsIGluZGV4XSwgdGhpcyk7XG4gICAgICAgIHJldHVybiBsYWJlbCB8fCBsYWJlbCA9PT0gMCA/IGxhYmVsIDogJyc7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigodiwgaSkgPT4gdGhpcy5jaGFydC5nZXREYXRhVmlzaWJpbGl0eShpKSk7XG4gIH1cblxuICBmaXQoKSB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcblxuICAgIGlmIChvcHRzLmRpc3BsYXkgJiYgb3B0cy5wb2ludExhYmVscy5kaXNwbGF5KSB7XG4gICAgICBmaXRXaXRoUG9pbnRMYWJlbHModGhpcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0Q2VudGVyUG9pbnQoMCwgMCwgMCwgMCk7XG4gICAgfVxuICB9XG5cbiAgc2V0Q2VudGVyUG9pbnQobGVmdE1vdmVtZW50LCByaWdodE1vdmVtZW50LCB0b3BNb3ZlbWVudCwgYm90dG9tTW92ZW1lbnQpIHtcbiAgICB0aGlzLnhDZW50ZXIgKz0gTWF0aC5mbG9vcigobGVmdE1vdmVtZW50IC0gcmlnaHRNb3ZlbWVudCkgLyAyKTtcbiAgICB0aGlzLnlDZW50ZXIgKz0gTWF0aC5mbG9vcigodG9wTW92ZW1lbnQgLSBib3R0b21Nb3ZlbWVudCkgLyAyKTtcbiAgICB0aGlzLmRyYXdpbmdBcmVhIC09IE1hdGgubWluKHRoaXMuZHJhd2luZ0FyZWEgLyAyLCBNYXRoLm1heChsZWZ0TW92ZW1lbnQsIHJpZ2h0TW92ZW1lbnQsIHRvcE1vdmVtZW50LCBib3R0b21Nb3ZlbWVudCkpO1xuICB9XG5cbiAgZ2V0SW5kZXhBbmdsZShpbmRleCkge1xuICAgIGNvbnN0IGFuZ2xlTXVsdGlwbGllciA9IFRBVSAvICh0aGlzLl9wb2ludExhYmVscy5sZW5ndGggfHwgMSk7XG4gICAgY29uc3Qgc3RhcnRBbmdsZSA9IHRoaXMub3B0aW9ucy5zdGFydEFuZ2xlIHx8IDA7XG5cbiAgICByZXR1cm4gX25vcm1hbGl6ZUFuZ2xlKGluZGV4ICogYW5nbGVNdWx0aXBsaWVyICsgdG9SYWRpYW5zKHN0YXJ0QW5nbGUpKTtcbiAgfVxuXG4gIGdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKHZhbHVlKSB7XG4gICAgaWYgKGlzTnVsbE9yVW5kZWYodmFsdWUpKSB7XG4gICAgICByZXR1cm4gTmFOO1xuICAgIH1cblxuICAgIC8vIFRha2UgaW50byBhY2NvdW50IGhhbGYgZm9udCBzaXplICsgdGhlIHlQYWRkaW5nIG9mIHRoZSB0b3AgdmFsdWVcbiAgICBjb25zdCBzY2FsaW5nRmFjdG9yID0gdGhpcy5kcmF3aW5nQXJlYSAvICh0aGlzLm1heCAtIHRoaXMubWluKTtcbiAgICBpZiAodGhpcy5vcHRpb25zLnJldmVyc2UpIHtcbiAgICAgIHJldHVybiAodGhpcy5tYXggLSB2YWx1ZSkgKiBzY2FsaW5nRmFjdG9yO1xuICAgIH1cbiAgICByZXR1cm4gKHZhbHVlIC0gdGhpcy5taW4pICogc2NhbGluZ0ZhY3RvcjtcbiAgfVxuXG4gIGdldFZhbHVlRm9yRGlzdGFuY2VGcm9tQ2VudGVyKGRpc3RhbmNlKSB7XG4gICAgaWYgKGlzTnVsbE9yVW5kZWYoZGlzdGFuY2UpKSB7XG4gICAgICByZXR1cm4gTmFOO1xuICAgIH1cblxuICAgIGNvbnN0IHNjYWxlZERpc3RhbmNlID0gZGlzdGFuY2UgLyAodGhpcy5kcmF3aW5nQXJlYSAvICh0aGlzLm1heCAtIHRoaXMubWluKSk7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5yZXZlcnNlID8gdGhpcy5tYXggLSBzY2FsZWREaXN0YW5jZSA6IHRoaXMubWluICsgc2NhbGVkRGlzdGFuY2U7XG4gIH1cblxuICBnZXRQb2ludExhYmVsQ29udGV4dChpbmRleCkge1xuICAgIGNvbnN0IHBvaW50TGFiZWxzID0gdGhpcy5fcG9pbnRMYWJlbHMgfHwgW107XG5cbiAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHBvaW50TGFiZWxzLmxlbmd0aCkge1xuICAgICAgY29uc3QgcG9pbnRMYWJlbCA9IHBvaW50TGFiZWxzW2luZGV4XTtcbiAgICAgIHJldHVybiBjcmVhdGVQb2ludExhYmVsQ29udGV4dCh0aGlzLmdldENvbnRleHQoKSwgaW5kZXgsIHBvaW50TGFiZWwpO1xuICAgIH1cbiAgfVxuXG4gIGdldFBvaW50UG9zaXRpb24oaW5kZXgsIGRpc3RhbmNlRnJvbUNlbnRlciwgYWRkaXRpb25hbEFuZ2xlID0gMCkge1xuICAgIGNvbnN0IGFuZ2xlID0gdGhpcy5nZXRJbmRleEFuZ2xlKGluZGV4KSAtIEhBTEZfUEkgKyBhZGRpdGlvbmFsQW5nbGU7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IE1hdGguY29zKGFuZ2xlKSAqIGRpc3RhbmNlRnJvbUNlbnRlciArIHRoaXMueENlbnRlcixcbiAgICAgIHk6IE1hdGguc2luKGFuZ2xlKSAqIGRpc3RhbmNlRnJvbUNlbnRlciArIHRoaXMueUNlbnRlcixcbiAgICAgIGFuZ2xlXG4gICAgfTtcbiAgfVxuXG4gIGdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZShpbmRleCwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRQb2ludFBvc2l0aW9uKGluZGV4LCB0aGlzLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKHZhbHVlKSk7XG4gIH1cblxuICBnZXRCYXNlUG9zaXRpb24oaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUoaW5kZXggfHwgMCwgdGhpcy5nZXRCYXNlVmFsdWUoKSk7XG4gIH1cblxuICBnZXRQb2ludExhYmVsUG9zaXRpb24oaW5kZXgpIHtcbiAgICBjb25zdCB7bGVmdCwgdG9wLCByaWdodCwgYm90dG9tfSA9IHRoaXMuX3BvaW50TGFiZWxJdGVtc1tpbmRleF07XG4gICAgcmV0dXJuIHtcbiAgICAgIGxlZnQsXG4gICAgICB0b3AsXG4gICAgICByaWdodCxcbiAgICAgIGJvdHRvbSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGRyYXdCYWNrZ3JvdW5kKCkge1xuICAgIGNvbnN0IHtiYWNrZ3JvdW5kQ29sb3IsIGdyaWQ6IHtjaXJjdWxhcn19ID0gdGhpcy5vcHRpb25zO1xuICAgIGlmIChiYWNrZ3JvdW5kQ29sb3IpIHtcbiAgICAgIGNvbnN0IGN0eCA9IHRoaXMuY3R4O1xuICAgICAgY3R4LnNhdmUoKTtcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIHBhdGhSYWRpdXNMaW5lKHRoaXMsIHRoaXMuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUodGhpcy5fZW5kVmFsdWUpLCBjaXJjdWxhciwgdGhpcy5fcG9pbnRMYWJlbHMubGVuZ3RoKTtcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBiYWNrZ3JvdW5kQ29sb3I7XG4gICAgICBjdHguZmlsbCgpO1xuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZHJhd0dyaWQoKSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB7YW5nbGVMaW5lcywgZ3JpZCwgYm9yZGVyfSA9IG9wdHM7XG4gICAgY29uc3QgbGFiZWxDb3VudCA9IHRoaXMuX3BvaW50TGFiZWxzLmxlbmd0aDtcblxuICAgIGxldCBpLCBvZmZzZXQsIHBvc2l0aW9uO1xuXG4gICAgaWYgKG9wdHMucG9pbnRMYWJlbHMuZGlzcGxheSkge1xuICAgICAgZHJhd1BvaW50TGFiZWxzKHRoaXMsIGxhYmVsQ291bnQpO1xuICAgIH1cblxuICAgIGlmIChncmlkLmRpc3BsYXkpIHtcbiAgICAgIHRoaXMudGlja3MuZm9yRWFjaCgodGljaywgaW5kZXgpID0+IHtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAwIHx8IChpbmRleCA9PT0gMCAmJiB0aGlzLm1pbiA8IDApKSB7XG4gICAgICAgICAgb2Zmc2V0ID0gdGhpcy5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZSh0aWNrLnZhbHVlKTtcbiAgICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5nZXRDb250ZXh0KGluZGV4KTtcbiAgICAgICAgICBjb25zdCBvcHRzQXRJbmRleCA9IGdyaWQuc2V0Q29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICBjb25zdCBvcHRzQXRJbmRleEJvcmRlciA9IGJvcmRlci5zZXRDb250ZXh0KGNvbnRleHQpO1xuXG4gICAgICAgICAgZHJhd1JhZGl1c0xpbmUodGhpcywgb3B0c0F0SW5kZXgsIG9mZnNldCwgbGFiZWxDb3VudCwgb3B0c0F0SW5kZXhCb3JkZXIpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoYW5nbGVMaW5lcy5kaXNwbGF5KSB7XG4gICAgICBjdHguc2F2ZSgpO1xuXG4gICAgICBmb3IgKGkgPSBsYWJlbENvdW50IC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgY29uc3Qgb3B0c0F0SW5kZXggPSBhbmdsZUxpbmVzLnNldENvbnRleHQodGhpcy5nZXRQb2ludExhYmVsQ29udGV4dChpKSk7XG4gICAgICAgIGNvbnN0IHtjb2xvciwgbGluZVdpZHRofSA9IG9wdHNBdEluZGV4O1xuXG4gICAgICAgIGlmICghbGluZVdpZHRoIHx8ICFjb2xvcikge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IGxpbmVXaWR0aDtcbiAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gY29sb3I7XG5cbiAgICAgICAgY3R4LnNldExpbmVEYXNoKG9wdHNBdEluZGV4LmJvcmRlckRhc2gpO1xuICAgICAgICBjdHgubGluZURhc2hPZmZzZXQgPSBvcHRzQXRJbmRleC5ib3JkZXJEYXNoT2Zmc2V0O1xuXG4gICAgICAgIG9mZnNldCA9IHRoaXMuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUob3B0cy50aWNrcy5yZXZlcnNlID8gdGhpcy5taW4gOiB0aGlzLm1heCk7XG4gICAgICAgIHBvc2l0aW9uID0gdGhpcy5nZXRQb2ludFBvc2l0aW9uKGksIG9mZnNldCk7XG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgY3R4Lm1vdmVUbyh0aGlzLnhDZW50ZXIsIHRoaXMueUNlbnRlcik7XG4gICAgICAgIGN0eC5saW5lVG8ocG9zaXRpb24ueCwgcG9zaXRpb24ueSk7XG4gICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICAgIH1cblxuICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZHJhd0JvcmRlcigpIHt9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGRyYXdMYWJlbHMoKSB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jdHg7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB0aWNrT3B0cyA9IG9wdHMudGlja3M7XG5cbiAgICBpZiAoIXRpY2tPcHRzLmRpc3BsYXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFydEFuZ2xlID0gdGhpcy5nZXRJbmRleEFuZ2xlKDApO1xuICAgIGxldCBvZmZzZXQsIHdpZHRoO1xuXG4gICAgY3R4LnNhdmUoKTtcbiAgICBjdHgudHJhbnNsYXRlKHRoaXMueENlbnRlciwgdGhpcy55Q2VudGVyKTtcbiAgICBjdHgucm90YXRlKHN0YXJ0QW5nbGUpO1xuICAgIGN0eC50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICBjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG5cbiAgICB0aGlzLnRpY2tzLmZvckVhY2goKHRpY2ssIGluZGV4KSA9PiB7XG4gICAgICBpZiAoKGluZGV4ID09PSAwICYmIHRoaXMubWluID49IDApICYmICFvcHRzLnJldmVyc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvcHRzQXRJbmRleCA9IHRpY2tPcHRzLnNldENvbnRleHQodGhpcy5nZXRDb250ZXh0KGluZGV4KSk7XG4gICAgICBjb25zdCB0aWNrRm9udCA9IHRvRm9udChvcHRzQXRJbmRleC5mb250KTtcbiAgICAgIG9mZnNldCA9IHRoaXMuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUodGhpcy50aWNrc1tpbmRleF0udmFsdWUpO1xuXG4gICAgICBpZiAob3B0c0F0SW5kZXguc2hvd0xhYmVsQmFja2Ryb3ApIHtcbiAgICAgICAgY3R4LmZvbnQgPSB0aWNrRm9udC5zdHJpbmc7XG4gICAgICAgIHdpZHRoID0gY3R4Lm1lYXN1cmVUZXh0KHRpY2subGFiZWwpLndpZHRoO1xuICAgICAgICBjdHguZmlsbFN0eWxlID0gb3B0c0F0SW5kZXguYmFja2Ryb3BDb2xvcjtcblxuICAgICAgICBjb25zdCBwYWRkaW5nID0gdG9QYWRkaW5nKG9wdHNBdEluZGV4LmJhY2tkcm9wUGFkZGluZyk7XG4gICAgICAgIGN0eC5maWxsUmVjdChcbiAgICAgICAgICAtd2lkdGggLyAyIC0gcGFkZGluZy5sZWZ0LFxuICAgICAgICAgIC1vZmZzZXQgLSB0aWNrRm9udC5zaXplIC8gMiAtIHBhZGRpbmcudG9wLFxuICAgICAgICAgIHdpZHRoICsgcGFkZGluZy53aWR0aCxcbiAgICAgICAgICB0aWNrRm9udC5zaXplICsgcGFkZGluZy5oZWlnaHRcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmVuZGVyVGV4dChjdHgsIHRpY2subGFiZWwsIDAsIC1vZmZzZXQsIHRpY2tGb250LCB7XG4gICAgICAgIGNvbG9yOiBvcHRzQXRJbmRleC5jb2xvcixcbiAgICAgICAgc3Ryb2tlQ29sb3I6IG9wdHNBdEluZGV4LnRleHRTdHJva2VDb2xvcixcbiAgICAgICAgc3Ryb2tlV2lkdGg6IG9wdHNBdEluZGV4LnRleHRTdHJva2VXaWR0aCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgY3R4LnJlc3RvcmUoKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBkcmF3VGl0bGUoKSB7fVxufVxuIiwgImltcG9ydCBhZGFwdGVycyBmcm9tICcuLi9jb3JlL2NvcmUuYWRhcHRlcnMuanMnO1xuaW1wb3J0IHtjYWxsYmFjayBhcyBjYWxsLCBpc0Zpbml0ZSwgaXNOdWxsT3JVbmRlZiwgbWVyZ2VJZiwgdmFsdWVPckRlZmF1bHR9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb3JlLmpzJztcbmltcG9ydCB7dG9SYWRpYW5zLCBpc051bWJlciwgX2xpbWl0VmFsdWV9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5tYXRoLmpzJztcbmltcG9ydCBTY2FsZSBmcm9tICcuLi9jb3JlL2NvcmUuc2NhbGUuanMnO1xuaW1wb3J0IHtfYXJyYXlVbmlxdWUsIF9maWx0ZXJCZXR3ZWVuLCBfbG9va3VwfSBmcm9tICcuLi9oZWxwZXJzL2hlbHBlcnMuY29sbGVjdGlvbi5qcyc7XG5cbi8qKlxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL2NvcmUvY29yZS5hZGFwdGVycy5qcycpLlRpbWVVbml0IH0gVW5pdFxuICogQHR5cGVkZWYge3tjb21tb246IGJvb2xlYW4sIHNpemU6IG51bWJlciwgc3RlcHM/OiBudW1iZXJ9fSBJbnRlcnZhbFxuICogQHR5cGVkZWYgeyBpbXBvcnQoJy4uL2NvcmUvY29yZS5hZGFwdGVycy5qcycpLkRhdGVBZGFwdGVyIH0gRGF0ZUFkYXB0ZXJcbiAqL1xuXG4vKipcbiAqIEB0eXBlIHtPYmplY3Q8VW5pdCwgSW50ZXJ2YWw+fVxuICovXG5jb25zdCBJTlRFUlZBTFMgPSB7XG4gIG1pbGxpc2Vjb25kOiB7Y29tbW9uOiB0cnVlLCBzaXplOiAxLCBzdGVwczogMTAwMH0sXG4gIHNlY29uZDoge2NvbW1vbjogdHJ1ZSwgc2l6ZTogMTAwMCwgc3RlcHM6IDYwfSxcbiAgbWludXRlOiB7Y29tbW9uOiB0cnVlLCBzaXplOiA2MDAwMCwgc3RlcHM6IDYwfSxcbiAgaG91cjoge2NvbW1vbjogdHJ1ZSwgc2l6ZTogMzYwMDAwMCwgc3RlcHM6IDI0fSxcbiAgZGF5OiB7Y29tbW9uOiB0cnVlLCBzaXplOiA4NjQwMDAwMCwgc3RlcHM6IDMwfSxcbiAgd2Vlazoge2NvbW1vbjogZmFsc2UsIHNpemU6IDYwNDgwMDAwMCwgc3RlcHM6IDR9LFxuICBtb250aDoge2NvbW1vbjogdHJ1ZSwgc2l6ZTogMi42MjhlOSwgc3RlcHM6IDEyfSxcbiAgcXVhcnRlcjoge2NvbW1vbjogZmFsc2UsIHNpemU6IDcuODg0ZTksIHN0ZXBzOiA0fSxcbiAgeWVhcjoge2NvbW1vbjogdHJ1ZSwgc2l6ZTogMy4xNTRlMTB9XG59O1xuXG4vKipcbiAqIEB0eXBlIHtVbml0W119XG4gKi9cbmNvbnN0IFVOSVRTID0gLyoqIEB0eXBlIFVuaXRbXSAqLyAvKiAjX19QVVJFX18gKi8gKE9iamVjdC5rZXlzKElOVEVSVkFMUykpO1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYlxuICovXG5mdW5jdGlvbiBzb3J0ZXIoYSwgYikge1xuICByZXR1cm4gYSAtIGI7XG59XG5cbi8qKlxuICogQHBhcmFtIHtUaW1lU2NhbGV9IHNjYWxlXG4gKiBAcGFyYW0geyp9IGlucHV0XG4gKiBAcmV0dXJuIHtudW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIHBhcnNlKHNjYWxlLCBpbnB1dCkge1xuICBpZiAoaXNOdWxsT3JVbmRlZihpbnB1dCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGFkYXB0ZXIgPSBzY2FsZS5fYWRhcHRlcjtcbiAgY29uc3Qge3BhcnNlciwgcm91bmQsIGlzb1dlZWtkYXl9ID0gc2NhbGUuX3BhcnNlT3B0cztcbiAgbGV0IHZhbHVlID0gaW5wdXQ7XG5cbiAgaWYgKHR5cGVvZiBwYXJzZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICB2YWx1ZSA9IHBhcnNlcih2YWx1ZSk7XG4gIH1cblxuICAvLyBPbmx5IHBhcnNlIGlmIGl0J3Mgbm90IGEgdGltZXN0YW1wIGFscmVhZHlcbiAgaWYgKCFpc0Zpbml0ZSh2YWx1ZSkpIHtcbiAgICB2YWx1ZSA9IHR5cGVvZiBwYXJzZXIgPT09ICdzdHJpbmcnXG4gICAgICA/IGFkYXB0ZXIucGFyc2UodmFsdWUsIC8qKiBAdHlwZSB7VW5pdH0gKi8gKHBhcnNlcikpXG4gICAgICA6IGFkYXB0ZXIucGFyc2UodmFsdWUpO1xuICB9XG5cbiAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAocm91bmQpIHtcbiAgICB2YWx1ZSA9IHJvdW5kID09PSAnd2VlaycgJiYgKGlzTnVtYmVyKGlzb1dlZWtkYXkpIHx8IGlzb1dlZWtkYXkgPT09IHRydWUpXG4gICAgICA/IGFkYXB0ZXIuc3RhcnRPZih2YWx1ZSwgJ2lzb1dlZWsnLCBpc29XZWVrZGF5KVxuICAgICAgOiBhZGFwdGVyLnN0YXJ0T2YodmFsdWUsIHJvdW5kKTtcbiAgfVxuXG4gIHJldHVybiArdmFsdWU7XG59XG5cbi8qKlxuICogRmlndXJlcyBvdXQgd2hhdCB1bml0IHJlc3VsdHMgaW4gYW4gYXBwcm9wcmlhdGUgbnVtYmVyIG9mIGF1dG8tZ2VuZXJhdGVkIHRpY2tzXG4gKiBAcGFyYW0ge1VuaXR9IG1pblVuaXRcbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhcbiAqIEBwYXJhbSB7bnVtYmVyfSBjYXBhY2l0eVxuICogQHJldHVybiB7b2JqZWN0fVxuICovXG5mdW5jdGlvbiBkZXRlcm1pbmVVbml0Rm9yQXV0b1RpY2tzKG1pblVuaXQsIG1pbiwgbWF4LCBjYXBhY2l0eSkge1xuICBjb25zdCBpbGVuID0gVU5JVFMubGVuZ3RoO1xuXG4gIGZvciAobGV0IGkgPSBVTklUUy5pbmRleE9mKG1pblVuaXQpOyBpIDwgaWxlbiAtIDE7ICsraSkge1xuICAgIGNvbnN0IGludGVydmFsID0gSU5URVJWQUxTW1VOSVRTW2ldXTtcbiAgICBjb25zdCBmYWN0b3IgPSBpbnRlcnZhbC5zdGVwcyA/IGludGVydmFsLnN0ZXBzIDogTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI7XG5cbiAgICBpZiAoaW50ZXJ2YWwuY29tbW9uICYmIE1hdGguY2VpbCgobWF4IC0gbWluKSAvIChmYWN0b3IgKiBpbnRlcnZhbC5zaXplKSkgPD0gY2FwYWNpdHkpIHtcbiAgICAgIHJldHVybiBVTklUU1tpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gVU5JVFNbaWxlbiAtIDFdO1xufVxuXG4vKipcbiAqIEZpZ3VyZXMgb3V0IHdoYXQgdW5pdCB0byBmb3JtYXQgYSBzZXQgb2YgdGlja3Mgd2l0aFxuICogQHBhcmFtIHtUaW1lU2NhbGV9IHNjYWxlXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtVGlja3NcbiAqIEBwYXJhbSB7VW5pdH0gbWluVW5pdFxuICogQHBhcmFtIHtudW1iZXJ9IG1pblxuICogQHBhcmFtIHtudW1iZXJ9IG1heFxuICogQHJldHVybiB7VW5pdH1cbiAqL1xuZnVuY3Rpb24gZGV0ZXJtaW5lVW5pdEZvckZvcm1hdHRpbmcoc2NhbGUsIG51bVRpY2tzLCBtaW5Vbml0LCBtaW4sIG1heCkge1xuICBmb3IgKGxldCBpID0gVU5JVFMubGVuZ3RoIC0gMTsgaSA+PSBVTklUUy5pbmRleE9mKG1pblVuaXQpOyBpLS0pIHtcbiAgICBjb25zdCB1bml0ID0gVU5JVFNbaV07XG4gICAgaWYgKElOVEVSVkFMU1t1bml0XS5jb21tb24gJiYgc2NhbGUuX2FkYXB0ZXIuZGlmZihtYXgsIG1pbiwgdW5pdCkgPj0gbnVtVGlja3MgLSAxKSB7XG4gICAgICByZXR1cm4gdW5pdDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gVU5JVFNbbWluVW5pdCA/IFVOSVRTLmluZGV4T2YobWluVW5pdCkgOiAwXTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VuaXR9IHVuaXRcbiAqIEByZXR1cm4ge29iamVjdH1cbiAqL1xuZnVuY3Rpb24gZGV0ZXJtaW5lTWFqb3JVbml0KHVuaXQpIHtcbiAgZm9yIChsZXQgaSA9IFVOSVRTLmluZGV4T2YodW5pdCkgKyAxLCBpbGVuID0gVU5JVFMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgaWYgKElOVEVSVkFMU1tVTklUU1tpXV0uY29tbW9uKSB7XG4gICAgICByZXR1cm4gVU5JVFNbaV07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IHRpY2tzXG4gKiBAcGFyYW0ge251bWJlcn0gdGltZVxuICogQHBhcmFtIHtudW1iZXJbXX0gW3RpbWVzdGFtcHNdIC0gaWYgZGVmaW5lZCwgc25hcCB0byB0aGVzZSB0aW1lc3RhbXBzXG4gKi9cbmZ1bmN0aW9uIGFkZFRpY2sodGlja3MsIHRpbWUsIHRpbWVzdGFtcHMpIHtcbiAgaWYgKCF0aW1lc3RhbXBzKSB7XG4gICAgdGlja3NbdGltZV0gPSB0cnVlO1xuICB9IGVsc2UgaWYgKHRpbWVzdGFtcHMubGVuZ3RoKSB7XG4gICAgY29uc3Qge2xvLCBoaX0gPSBfbG9va3VwKHRpbWVzdGFtcHMsIHRpbWUpO1xuICAgIGNvbnN0IHRpbWVzdGFtcCA9IHRpbWVzdGFtcHNbbG9dID49IHRpbWUgPyB0aW1lc3RhbXBzW2xvXSA6IHRpbWVzdGFtcHNbaGldO1xuICAgIHRpY2tzW3RpbWVzdGFtcF0gPSB0cnVlO1xuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtUaW1lU2NhbGV9IHNjYWxlXG4gKiBAcGFyYW0ge29iamVjdFtdfSB0aWNrc1xuICogQHBhcmFtIHtvYmplY3R9IG1hcFxuICogQHBhcmFtIHtVbml0fSBtYWpvclVuaXRcbiAqIEByZXR1cm4ge29iamVjdFtdfVxuICovXG5mdW5jdGlvbiBzZXRNYWpvclRpY2tzKHNjYWxlLCB0aWNrcywgbWFwLCBtYWpvclVuaXQpIHtcbiAgY29uc3QgYWRhcHRlciA9IHNjYWxlLl9hZGFwdGVyO1xuICBjb25zdCBmaXJzdCA9ICthZGFwdGVyLnN0YXJ0T2YodGlja3NbMF0udmFsdWUsIG1ham9yVW5pdCk7XG4gIGNvbnN0IGxhc3QgPSB0aWNrc1t0aWNrcy5sZW5ndGggLSAxXS52YWx1ZTtcbiAgbGV0IG1ham9yLCBpbmRleDtcblxuICBmb3IgKG1ham9yID0gZmlyc3Q7IG1ham9yIDw9IGxhc3Q7IG1ham9yID0gK2FkYXB0ZXIuYWRkKG1ham9yLCAxLCBtYWpvclVuaXQpKSB7XG4gICAgaW5kZXggPSBtYXBbbWFqb3JdO1xuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICB0aWNrc1tpbmRleF0ubWFqb3IgPSB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGlja3M7XG59XG5cbi8qKlxuICogQHBhcmFtIHtUaW1lU2NhbGV9IHNjYWxlXG4gKiBAcGFyYW0ge251bWJlcltdfSB2YWx1ZXNcbiAqIEBwYXJhbSB7VW5pdHx1bmRlZmluZWR9IFttYWpvclVuaXRdXG4gKiBAcmV0dXJuIHtvYmplY3RbXX1cbiAqL1xuZnVuY3Rpb24gdGlja3NGcm9tVGltZXN0YW1wcyhzY2FsZSwgdmFsdWVzLCBtYWpvclVuaXQpIHtcbiAgY29uc3QgdGlja3MgPSBbXTtcbiAgLyoqIEB0eXBlIHtPYmplY3Q8bnVtYmVyLG9iamVjdD59ICovXG4gIGNvbnN0IG1hcCA9IHt9O1xuICBjb25zdCBpbGVuID0gdmFsdWVzLmxlbmd0aDtcbiAgbGV0IGksIHZhbHVlO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBpbGVuOyArK2kpIHtcbiAgICB2YWx1ZSA9IHZhbHVlc1tpXTtcbiAgICBtYXBbdmFsdWVdID0gaTtcblxuICAgIHRpY2tzLnB1c2goe1xuICAgICAgdmFsdWUsXG4gICAgICBtYWpvcjogZmFsc2VcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFdlIHNldCB0aGUgbWFqb3IgdGlja3Mgc2VwYXJhdGVseSBmcm9tIHRoZSBhYm92ZSBsb29wIGJlY2F1c2UgY2FsbGluZyBzdGFydE9mIGZvciBldmVyeSB0aWNrXG4gIC8vIGlzIGV4cGVuc2l2ZSB3aGVuIHRoZXJlIGlzIGEgbGFyZ2UgbnVtYmVyIG9mIHRpY2tzXG4gIHJldHVybiAoaWxlbiA9PT0gMCB8fCAhbWFqb3JVbml0KSA/IHRpY2tzIDogc2V0TWFqb3JUaWNrcyhzY2FsZSwgdGlja3MsIG1hcCwgbWFqb3JVbml0KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGltZVNjYWxlIGV4dGVuZHMgU2NhbGUge1xuXG4gIHN0YXRpYyBpZCA9ICd0aW1lJztcblxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIHN0YXRpYyBkZWZhdWx0cyA9IHtcbiAgICAvKipcbiAgICAgKiBTY2FsZSBib3VuZGFyeSBzdHJhdGVneSAoYnlwYXNzZWQgYnkgbWluL21heCB0aW1lIG9wdGlvbnMpXG4gICAgICogLSBgZGF0YWA6IG1ha2Ugc3VyZSBkYXRhIGFyZSBmdWxseSB2aXNpYmxlLCB0aWNrcyBvdXRzaWRlIGFyZSByZW1vdmVkXG4gICAgICogLSBgdGlja3NgOiBtYWtlIHN1cmUgdGlja3MgYXJlIGZ1bGx5IHZpc2libGUsIGRhdGEgb3V0c2lkZSBhcmUgdHJ1bmNhdGVkXG4gICAgICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9wdWxsLzQ1NTZcbiAgICAgKiBAc2luY2UgMi43LjBcbiAgICAgKi9cbiAgICBib3VuZHM6ICdkYXRhJyxcblxuICAgIGFkYXB0ZXJzOiB7fSxcbiAgICB0aW1lOiB7XG4gICAgICBwYXJzZXI6IGZhbHNlLCAvLyBmYWxzZSA9PSBhIHBhdHRlcm4gc3RyaW5nIGZyb20gb3IgYSBjdXN0b20gY2FsbGJhY2sgdGhhdCBjb252ZXJ0cyBpdHMgYXJndW1lbnQgdG8gYSB0aW1lc3RhbXBcbiAgICAgIHVuaXQ6IGZhbHNlLCAvLyBmYWxzZSA9PSBhdXRvbWF0aWMgb3Igb3ZlcnJpZGUgd2l0aCB3ZWVrLCBtb250aCwgeWVhciwgZXRjLlxuICAgICAgcm91bmQ6IGZhbHNlLCAvLyBub25lLCBvciBvdmVycmlkZSB3aXRoIHdlZWssIG1vbnRoLCB5ZWFyLCBldGMuXG4gICAgICBpc29XZWVrZGF5OiBmYWxzZSwgLy8gb3ZlcnJpZGUgd2VlayBzdGFydCBkYXlcbiAgICAgIG1pblVuaXQ6ICdtaWxsaXNlY29uZCcsXG4gICAgICBkaXNwbGF5Rm9ybWF0czoge31cbiAgICB9LFxuICAgIHRpY2tzOiB7XG4gICAgICAvKipcbiAgICAgICAqIFRpY2tzIGdlbmVyYXRpb24gaW5wdXQgdmFsdWVzOlxuICAgICAgICogLSAnYXV0byc6IGdlbmVyYXRlcyBcIm9wdGltYWxcIiB0aWNrcyBiYXNlZCBvbiBzY2FsZSBzaXplIGFuZCB0aW1lIG9wdGlvbnMuXG4gICAgICAgKiAtICdkYXRhJzogZ2VuZXJhdGVzIHRpY2tzIGZyb20gZGF0YSAoaW5jbHVkaW5nIGxhYmVscyBmcm9tIGRhdGEge3R8eHx5fSBvYmplY3RzKS5cbiAgICAgICAqIC0gJ2xhYmVscyc6IGdlbmVyYXRlcyB0aWNrcyBmcm9tIHVzZXIgZ2l2ZW4gYGRhdGEubGFiZWxzYCB2YWx1ZXMgT05MWS5cbiAgICAgICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvcHVsbC80NTA3XG4gICAgICAgKiBAc2luY2UgMi43LjBcbiAgICAgICAqL1xuICAgICAgc291cmNlOiAnYXV0bycsXG5cbiAgICAgIGNhbGxiYWNrOiBmYWxzZSxcblxuICAgICAgbWFqb3I6IHtcbiAgICAgICAgZW5hYmxlZDogZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBwcm9wc1xuXHQgKi9cbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG5cbiAgICAvKiogQHR5cGUge3tkYXRhOiBudW1iZXJbXSwgbGFiZWxzOiBudW1iZXJbXSwgYWxsOiBudW1iZXJbXX19ICovXG4gICAgdGhpcy5fY2FjaGUgPSB7XG4gICAgICBkYXRhOiBbXSxcbiAgICAgIGxhYmVsczogW10sXG4gICAgICBhbGw6IFtdXG4gICAgfTtcblxuICAgIC8qKiBAdHlwZSB7VW5pdH0gKi9cbiAgICB0aGlzLl91bml0ID0gJ2RheSc7XG4gICAgLyoqIEB0eXBlIHtVbml0PX0gKi9cbiAgICB0aGlzLl9tYWpvclVuaXQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fb2Zmc2V0cyA9IHt9O1xuICAgIHRoaXMuX25vcm1hbGl6ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9wYXJzZU9wdHMgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBpbml0KHNjYWxlT3B0cywgb3B0cyA9IHt9KSB7XG4gICAgY29uc3QgdGltZSA9IHNjYWxlT3B0cy50aW1lIHx8IChzY2FsZU9wdHMudGltZSA9IHt9KTtcbiAgICAvKiogQHR5cGUge0RhdGVBZGFwdGVyfSAqL1xuICAgIGNvbnN0IGFkYXB0ZXIgPSB0aGlzLl9hZGFwdGVyID0gbmV3IGFkYXB0ZXJzLl9kYXRlKHNjYWxlT3B0cy5hZGFwdGVycy5kYXRlKTtcblxuICAgIGFkYXB0ZXIuaW5pdChvcHRzKTtcblxuICAgIC8vIEJhY2t3YXJkIGNvbXBhdGliaWxpdHk6IGJlZm9yZSBpbnRyb2R1Y2luZyBhZGFwdGVyLCBgZGlzcGxheUZvcm1hdHNgIHdhc1xuICAgIC8vIHN1cHBvc2VkIHRvIGNvbnRhaW4gKmFsbCogdW5pdC9zdHJpbmcgcGFpcnMgYnV0IHRoaXMgY2FuJ3QgYmUgcmVzb2x2ZWRcbiAgICAvLyB3aGVuIGxvYWRpbmcgdGhlIHNjYWxlIChhZGFwdGVycyBhcmUgbG9hZGVkIGFmdGVyd2FyZCksIHNvIGxldCdzIHBvcHVsYXRlXG4gICAgLy8gbWlzc2luZyBmb3JtYXRzIG9uIHVwZGF0ZVxuICAgIG1lcmdlSWYodGltZS5kaXNwbGF5Rm9ybWF0cywgYWRhcHRlci5mb3JtYXRzKCkpO1xuXG4gICAgdGhpcy5fcGFyc2VPcHRzID0ge1xuICAgICAgcGFyc2VyOiB0aW1lLnBhcnNlcixcbiAgICAgIHJvdW5kOiB0aW1lLnJvdW5kLFxuICAgICAgaXNvV2Vla2RheTogdGltZS5pc29XZWVrZGF5XG4gICAgfTtcblxuICAgIHN1cGVyLmluaXQoc2NhbGVPcHRzKTtcblxuICAgIHRoaXMuX25vcm1hbGl6ZWQgPSBvcHRzLm5vcm1hbGl6ZWQ7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHsqfSByYXdcblx0ICogQHBhcmFtIHtudW1iZXI/fSBbaW5kZXhdXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG4gIHBhcnNlKHJhdywgaW5kZXgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIGlmIChyYXcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBwYXJzZSh0aGlzLCByYXcpO1xuICB9XG5cbiAgYmVmb3JlTGF5b3V0KCkge1xuICAgIHN1cGVyLmJlZm9yZUxheW91dCgpO1xuICAgIHRoaXMuX2NhY2hlID0ge1xuICAgICAgZGF0YTogW10sXG4gICAgICBsYWJlbHM6IFtdLFxuICAgICAgYWxsOiBbXVxuICAgIH07XG4gIH1cblxuICBkZXRlcm1pbmVEYXRhTGltaXRzKCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMuX2FkYXB0ZXI7XG4gICAgY29uc3QgdW5pdCA9IG9wdGlvbnMudGltZS51bml0IHx8ICdkYXknO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItY29uc3RcbiAgICBsZXQge21pbiwgbWF4LCBtaW5EZWZpbmVkLCBtYXhEZWZpbmVkfSA9IHRoaXMuZ2V0VXNlckJvdW5kcygpO1xuXG4gICAgLyoqXG5cdFx0ICogQHBhcmFtIHtvYmplY3R9IGJvdW5kc1xuXHRcdCAqL1xuICAgIGZ1bmN0aW9uIF9hcHBseUJvdW5kcyhib3VuZHMpIHtcbiAgICAgIGlmICghbWluRGVmaW5lZCAmJiAhaXNOYU4oYm91bmRzLm1pbikpIHtcbiAgICAgICAgbWluID0gTWF0aC5taW4obWluLCBib3VuZHMubWluKTtcbiAgICAgIH1cbiAgICAgIGlmICghbWF4RGVmaW5lZCAmJiAhaXNOYU4oYm91bmRzLm1heCkpIHtcbiAgICAgICAgbWF4ID0gTWF0aC5tYXgobWF4LCBib3VuZHMubWF4KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiB3ZSBoYXZlIHVzZXIgcHJvdmlkZWQgYG1pbmAgYW5kIGBtYXhgIGxhYmVscyAvIGRhdGEgYm91bmRzIGNhbiBiZSBpZ25vcmVkXG4gICAgaWYgKCFtaW5EZWZpbmVkIHx8ICFtYXhEZWZpbmVkKSB7XG4gICAgICAvLyBMYWJlbHMgYXJlIGFsd2F5cyBjb25zaWRlcmVkLCB3aGVuIHVzZXIgZGlkIG5vdCBmb3JjZSBib3VuZHNcbiAgICAgIF9hcHBseUJvdW5kcyh0aGlzLl9nZXRMYWJlbEJvdW5kcygpKTtcblxuICAgICAgLy8gSWYgYGJvdW5kc2AgaXMgYCd0aWNrcydgIGFuZCBgdGlja3Muc291cmNlYCBpcyBgJ2xhYmVscydgLFxuICAgICAgLy8gZGF0YSBib3VuZHMgYXJlIGlnbm9yZWQgKGFuZCBkb24ndCBuZWVkIHRvIGJlIGRldGVybWluZWQpXG4gICAgICBpZiAob3B0aW9ucy5ib3VuZHMgIT09ICd0aWNrcycgfHwgb3B0aW9ucy50aWNrcy5zb3VyY2UgIT09ICdsYWJlbHMnKSB7XG4gICAgICAgIF9hcHBseUJvdW5kcyh0aGlzLmdldE1pbk1heChmYWxzZSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIG1pbiA9IGlzRmluaXRlKG1pbikgJiYgIWlzTmFOKG1pbikgPyBtaW4gOiArYWRhcHRlci5zdGFydE9mKERhdGUubm93KCksIHVuaXQpO1xuICAgIG1heCA9IGlzRmluaXRlKG1heCkgJiYgIWlzTmFOKG1heCkgPyBtYXggOiArYWRhcHRlci5lbmRPZihEYXRlLm5vdygpLCB1bml0KSArIDE7XG5cbiAgICAvLyBNYWtlIHN1cmUgdGhhdCBtYXggaXMgc3RyaWN0bHkgaGlnaGVyIHRoYW4gbWluIChyZXF1aXJlZCBieSB0aGUgdGltZXNlcmllcyBsb29rdXAgdGFibGUpXG4gICAgdGhpcy5taW4gPSBNYXRoLm1pbihtaW4sIG1heCAtIDEpO1xuICAgIHRoaXMubWF4ID0gTWF0aC5tYXgobWluICsgMSwgbWF4KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldExhYmVsQm91bmRzKCkge1xuICAgIGNvbnN0IGFyciA9IHRoaXMuZ2V0TGFiZWxUaW1lc3RhbXBzKCk7XG4gICAgbGV0IG1pbiA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbiAgICBsZXQgbWF4ID0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xuXG4gICAgaWYgKGFyci5sZW5ndGgpIHtcbiAgICAgIG1pbiA9IGFyclswXTtcbiAgICAgIG1heCA9IGFyclthcnIubGVuZ3RoIC0gMV07XG4gICAgfVxuICAgIHJldHVybiB7bWluLCBtYXh9O1xuICB9XG5cbiAgLyoqXG5cdCAqIEByZXR1cm4ge29iamVjdFtdfVxuXHQgKi9cbiAgYnVpbGRUaWNrcygpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIGNvbnN0IHRpbWVPcHRzID0gb3B0aW9ucy50aW1lO1xuICAgIGNvbnN0IHRpY2tPcHRzID0gb3B0aW9ucy50aWNrcztcbiAgICBjb25zdCB0aW1lc3RhbXBzID0gdGlja09wdHMuc291cmNlID09PSAnbGFiZWxzJyA/IHRoaXMuZ2V0TGFiZWxUaW1lc3RhbXBzKCkgOiB0aGlzLl9nZW5lcmF0ZSgpO1xuXG4gICAgaWYgKG9wdGlvbnMuYm91bmRzID09PSAndGlja3MnICYmIHRpbWVzdGFtcHMubGVuZ3RoKSB7XG4gICAgICB0aGlzLm1pbiA9IHRoaXMuX3VzZXJNaW4gfHwgdGltZXN0YW1wc1swXTtcbiAgICAgIHRoaXMubWF4ID0gdGhpcy5fdXNlck1heCB8fCB0aW1lc3RhbXBzW3RpbWVzdGFtcHMubGVuZ3RoIC0gMV07XG4gICAgfVxuXG4gICAgY29uc3QgbWluID0gdGhpcy5taW47XG4gICAgY29uc3QgbWF4ID0gdGhpcy5tYXg7XG5cbiAgICBjb25zdCB0aWNrcyA9IF9maWx0ZXJCZXR3ZWVuKHRpbWVzdGFtcHMsIG1pbiwgbWF4KTtcblxuICAgIC8vIFBSSVZBVEVcbiAgICAvLyBkZXRlcm1pbmVVbml0Rm9yRm9ybWF0dGluZyByZWxpZXMgb24gdGhlIG51bWJlciBvZiB0aWNrcyBzbyB3ZSBkb24ndCB1c2UgaXQgd2hlblxuICAgIC8vIGF1dG9Ta2lwIGlzIGVuYWJsZWQgYmVjYXVzZSB3ZSBkb24ndCB5ZXQga25vdyB3aGF0IHRoZSBmaW5hbCBudW1iZXIgb2YgdGlja3Mgd2lsbCBiZVxuICAgIHRoaXMuX3VuaXQgPSB0aW1lT3B0cy51bml0IHx8ICh0aWNrT3B0cy5hdXRvU2tpcFxuICAgICAgPyBkZXRlcm1pbmVVbml0Rm9yQXV0b1RpY2tzKHRpbWVPcHRzLm1pblVuaXQsIHRoaXMubWluLCB0aGlzLm1heCwgdGhpcy5fZ2V0TGFiZWxDYXBhY2l0eShtaW4pKVxuICAgICAgOiBkZXRlcm1pbmVVbml0Rm9yRm9ybWF0dGluZyh0aGlzLCB0aWNrcy5sZW5ndGgsIHRpbWVPcHRzLm1pblVuaXQsIHRoaXMubWluLCB0aGlzLm1heCkpO1xuICAgIHRoaXMuX21ham9yVW5pdCA9ICF0aWNrT3B0cy5tYWpvci5lbmFibGVkIHx8IHRoaXMuX3VuaXQgPT09ICd5ZWFyJyA/IHVuZGVmaW5lZFxuICAgICAgOiBkZXRlcm1pbmVNYWpvclVuaXQodGhpcy5fdW5pdCk7XG4gICAgdGhpcy5pbml0T2Zmc2V0cyh0aW1lc3RhbXBzKTtcblxuICAgIGlmIChvcHRpb25zLnJldmVyc2UpIHtcbiAgICAgIHRpY2tzLnJldmVyc2UoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGlja3NGcm9tVGltZXN0YW1wcyh0aGlzLCB0aWNrcywgdGhpcy5fbWFqb3JVbml0KTtcbiAgfVxuXG4gIGFmdGVyQXV0b1NraXAoKSB7XG4gICAgLy8gT2Zmc2V0cyBmb3IgYmFyIGNoYXJ0cyBuZWVkIHRvIGJlIGhhbmRsZWQgd2l0aCB0aGUgYXV0byBza2lwcGVkXG4gICAgLy8gdGlja3MuIE9uY2UgdGlja3MgaGF2ZSBiZWVuIHNraXBwZWQsIHdlIHJlLWNvbXB1dGUgdGhlIG9mZnNldHMuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5vZmZzZXRBZnRlckF1dG9za2lwKSB7XG4gICAgICB0aGlzLmluaXRPZmZzZXRzKHRoaXMudGlja3MubWFwKHRpY2sgPT4gK3RpY2sudmFsdWUpKTtcbiAgICB9XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyB0aGUgc3RhcnQgYW5kIGVuZCBvZmZzZXRzIGZyb20gZWRnZXMgaW4gdGhlIGZvcm0gb2Yge3N0YXJ0LCBlbmR9XG5cdCAqIHdoZXJlIGVhY2ggdmFsdWUgaXMgYSByZWxhdGl2ZSB3aWR0aCB0byB0aGUgc2NhbGUgYW5kIHJhbmdlcyBiZXR3ZWVuIDAgYW5kIDEuXG5cdCAqIFRoZXkgYWRkIGV4dHJhIG1hcmdpbnMgb24gdGhlIGJvdGggc2lkZXMgYnkgc2NhbGluZyBkb3duIHRoZSBvcmlnaW5hbCBzY2FsZS5cblx0ICogT2Zmc2V0cyBhcmUgYWRkZWQgd2hlbiB0aGUgYG9mZnNldGAgb3B0aW9uIGlzIHRydWUuXG5cdCAqIEBwYXJhbSB7bnVtYmVyW119IHRpbWVzdGFtcHNcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgaW5pdE9mZnNldHModGltZXN0YW1wcyA9IFtdKSB7XG4gICAgbGV0IHN0YXJ0ID0gMDtcbiAgICBsZXQgZW5kID0gMDtcbiAgICBsZXQgZmlyc3QsIGxhc3Q7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm9mZnNldCAmJiB0aW1lc3RhbXBzLmxlbmd0aCkge1xuICAgICAgZmlyc3QgPSB0aGlzLmdldERlY2ltYWxGb3JWYWx1ZSh0aW1lc3RhbXBzWzBdKTtcbiAgICAgIGlmICh0aW1lc3RhbXBzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBzdGFydCA9IDEgLSBmaXJzdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXJ0ID0gKHRoaXMuZ2V0RGVjaW1hbEZvclZhbHVlKHRpbWVzdGFtcHNbMV0pIC0gZmlyc3QpIC8gMjtcbiAgICAgIH1cbiAgICAgIGxhc3QgPSB0aGlzLmdldERlY2ltYWxGb3JWYWx1ZSh0aW1lc3RhbXBzW3RpbWVzdGFtcHMubGVuZ3RoIC0gMV0pO1xuICAgICAgaWYgKHRpbWVzdGFtcHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGVuZCA9IGxhc3Q7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbmQgPSAobGFzdCAtIHRoaXMuZ2V0RGVjaW1hbEZvclZhbHVlKHRpbWVzdGFtcHNbdGltZXN0YW1wcy5sZW5ndGggLSAyXSkpIC8gMjtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgbGltaXQgPSB0aW1lc3RhbXBzLmxlbmd0aCA8IDMgPyAwLjUgOiAwLjI1O1xuICAgIHN0YXJ0ID0gX2xpbWl0VmFsdWUoc3RhcnQsIDAsIGxpbWl0KTtcbiAgICBlbmQgPSBfbGltaXRWYWx1ZShlbmQsIDAsIGxpbWl0KTtcblxuICAgIHRoaXMuX29mZnNldHMgPSB7c3RhcnQsIGVuZCwgZmFjdG9yOiAxIC8gKHN0YXJ0ICsgMSArIGVuZCl9O1xuICB9XG5cbiAgLyoqXG5cdCAqIEdlbmVyYXRlcyBhIG1heGltdW0gb2YgYGNhcGFjaXR5YCB0aW1lc3RhbXBzIGJldHdlZW4gbWluIGFuZCBtYXgsIHJvdW5kZWQgdG8gdGhlXG5cdCAqIGBtaW5vcmAgdW5pdCB1c2luZyB0aGUgZ2l2ZW4gc2NhbGUgdGltZSBgb3B0aW9uc2AuXG5cdCAqIEltcG9ydGFudDogdGhpcyBtZXRob2QgY2FuIHJldHVybiB0aWNrcyBvdXRzaWRlIHRoZSBtaW4gYW5kIG1heCByYW5nZSwgaXQncyB0aGVcblx0ICogcmVzcG9uc2liaWxpdHkgb2YgdGhlIGNhbGxpbmcgY29kZSB0byBjbGFtcCB2YWx1ZXMgaWYgbmVlZGVkLlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBfZ2VuZXJhdGUoKSB7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMuX2FkYXB0ZXI7XG4gICAgY29uc3QgbWluID0gdGhpcy5taW47XG4gICAgY29uc3QgbWF4ID0gdGhpcy5tYXg7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB0aW1lT3B0cyA9IG9wdGlvbnMudGltZTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY29uc3QgbWlub3IgPSB0aW1lT3B0cy51bml0IHx8IGRldGVybWluZVVuaXRGb3JBdXRvVGlja3ModGltZU9wdHMubWluVW5pdCwgbWluLCBtYXgsIHRoaXMuX2dldExhYmVsQ2FwYWNpdHkobWluKSk7XG4gICAgY29uc3Qgc3RlcFNpemUgPSB2YWx1ZU9yRGVmYXVsdChvcHRpb25zLnRpY2tzLnN0ZXBTaXplLCAxKTtcbiAgICBjb25zdCB3ZWVrZGF5ID0gbWlub3IgPT09ICd3ZWVrJyA/IHRpbWVPcHRzLmlzb1dlZWtkYXkgOiBmYWxzZTtcbiAgICBjb25zdCBoYXNXZWVrZGF5ID0gaXNOdW1iZXIod2Vla2RheSkgfHwgd2Vla2RheSA9PT0gdHJ1ZTtcbiAgICBjb25zdCB0aWNrcyA9IHt9O1xuICAgIGxldCBmaXJzdCA9IG1pbjtcbiAgICBsZXQgdGltZSwgY291bnQ7XG5cbiAgICAvLyBGb3IgJ3dlZWsnIHVuaXQsIGhhbmRsZSB0aGUgZmlyc3QgZGF5IG9mIHdlZWsgb3B0aW9uXG4gICAgaWYgKGhhc1dlZWtkYXkpIHtcbiAgICAgIGZpcnN0ID0gK2FkYXB0ZXIuc3RhcnRPZihmaXJzdCwgJ2lzb1dlZWsnLCB3ZWVrZGF5KTtcbiAgICB9XG5cbiAgICAvLyBBbGlnbiBmaXJzdCB0aWNrcyBvbiB1bml0XG4gICAgZmlyc3QgPSArYWRhcHRlci5zdGFydE9mKGZpcnN0LCBoYXNXZWVrZGF5ID8gJ2RheScgOiBtaW5vcik7XG5cbiAgICAvLyBQcmV2ZW50IGJyb3dzZXIgZnJvbSBmcmVlemluZyBpbiBjYXNlIHVzZXIgb3B0aW9ucyByZXF1ZXN0IG1pbGxpb25zIG9mIG1pbGxpc2Vjb25kc1xuICAgIGlmIChhZGFwdGVyLmRpZmYobWF4LCBtaW4sIG1pbm9yKSA+IDEwMDAwMCAqIHN0ZXBTaXplKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IobWluICsgJyBhbmQgJyArIG1heCArICcgYXJlIHRvbyBmYXIgYXBhcnQgd2l0aCBzdGVwU2l6ZSBvZiAnICsgc3RlcFNpemUgKyAnICcgKyBtaW5vcik7XG4gICAgfVxuXG4gICAgY29uc3QgdGltZXN0YW1wcyA9IG9wdGlvbnMudGlja3Muc291cmNlID09PSAnZGF0YScgJiYgdGhpcy5nZXREYXRhVGltZXN0YW1wcygpO1xuICAgIGZvciAodGltZSA9IGZpcnN0LCBjb3VudCA9IDA7IHRpbWUgPCBtYXg7IHRpbWUgPSArYWRhcHRlci5hZGQodGltZSwgc3RlcFNpemUsIG1pbm9yKSwgY291bnQrKykge1xuICAgICAgYWRkVGljayh0aWNrcywgdGltZSwgdGltZXN0YW1wcyk7XG4gICAgfVxuXG4gICAgaWYgKHRpbWUgPT09IG1heCB8fCBvcHRpb25zLmJvdW5kcyA9PT0gJ3RpY2tzJyB8fCBjb3VudCA9PT0gMSkge1xuICAgICAgYWRkVGljayh0aWNrcywgdGltZSwgdGltZXN0YW1wcyk7XG4gICAgfVxuXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aWNrcykuc29ydChzb3J0ZXIpLm1hcCh4ID0+ICt4KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKi9cbiAgZ2V0TGFiZWxGb3JWYWx1ZSh2YWx1ZSkge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSB0aGlzLl9hZGFwdGVyO1xuICAgIGNvbnN0IHRpbWVPcHRzID0gdGhpcy5vcHRpb25zLnRpbWU7XG5cbiAgICBpZiAodGltZU9wdHMudG9vbHRpcEZvcm1hdCkge1xuICAgICAgcmV0dXJuIGFkYXB0ZXIuZm9ybWF0KHZhbHVlLCB0aW1lT3B0cy50b29sdGlwRm9ybWF0KTtcbiAgICB9XG4gICAgcmV0dXJuIGFkYXB0ZXIuZm9ybWF0KHZhbHVlLCB0aW1lT3B0cy5kaXNwbGF5Rm9ybWF0cy5kYXRldGltZSk7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG5cdCAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gZm9ybWF0XG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICovXG4gIGZvcm1hdCh2YWx1ZSwgZm9ybWF0KSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCBmb3JtYXRzID0gb3B0aW9ucy50aW1lLmRpc3BsYXlGb3JtYXRzO1xuICAgIGNvbnN0IHVuaXQgPSB0aGlzLl91bml0O1xuICAgIGNvbnN0IGZtdCA9IGZvcm1hdCB8fCBmb3JtYXRzW3VuaXRdO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGVyLmZvcm1hdCh2YWx1ZSwgZm10KTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBGdW5jdGlvbiB0byBmb3JtYXQgYW4gaW5kaXZpZHVhbCB0aWNrIG1hcmtcblx0ICogQHBhcmFtIHtudW1iZXJ9IHRpbWVcblx0ICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG5cdCAqIEBwYXJhbSB7b2JqZWN0W119IHRpY2tzXG5cdCAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gW2Zvcm1hdF1cblx0ICogQHJldHVybiB7c3RyaW5nfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX3RpY2tGb3JtYXRGdW5jdGlvbih0aW1lLCBpbmRleCwgdGlja3MsIGZvcm1hdCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgY29uc3QgZm9ybWF0dGVyID0gb3B0aW9ucy50aWNrcy5jYWxsYmFjaztcblxuICAgIGlmIChmb3JtYXR0ZXIpIHtcbiAgICAgIHJldHVybiBjYWxsKGZvcm1hdHRlciwgW3RpbWUsIGluZGV4LCB0aWNrc10sIHRoaXMpO1xuICAgIH1cblxuICAgIGNvbnN0IGZvcm1hdHMgPSBvcHRpb25zLnRpbWUuZGlzcGxheUZvcm1hdHM7XG4gICAgY29uc3QgdW5pdCA9IHRoaXMuX3VuaXQ7XG4gICAgY29uc3QgbWFqb3JVbml0ID0gdGhpcy5fbWFqb3JVbml0O1xuICAgIGNvbnN0IG1pbm9yRm9ybWF0ID0gdW5pdCAmJiBmb3JtYXRzW3VuaXRdO1xuICAgIGNvbnN0IG1ham9yRm9ybWF0ID0gbWFqb3JVbml0ICYmIGZvcm1hdHNbbWFqb3JVbml0XTtcbiAgICBjb25zdCB0aWNrID0gdGlja3NbaW5kZXhdO1xuICAgIGNvbnN0IG1ham9yID0gbWFqb3JVbml0ICYmIG1ham9yRm9ybWF0ICYmIHRpY2sgJiYgdGljay5tYWpvcjtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGVyLmZvcm1hdCh0aW1lLCBmb3JtYXQgfHwgKG1ham9yID8gbWFqb3JGb3JtYXQgOiBtaW5vckZvcm1hdCkpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7b2JqZWN0W119IHRpY2tzXG5cdCAqL1xuICBnZW5lcmF0ZVRpY2tMYWJlbHModGlja3MpIHtcbiAgICBsZXQgaSwgaWxlbiwgdGljaztcblxuICAgIGZvciAoaSA9IDAsIGlsZW4gPSB0aWNrcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHRpY2sgPSB0aWNrc1tpXTtcbiAgICAgIHRpY2subGFiZWwgPSB0aGlzLl90aWNrRm9ybWF0RnVuY3Rpb24odGljay52YWx1ZSwgaSwgdGlja3MpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgLSBNaWxsaXNlY29uZHMgc2luY2UgZXBvY2ggKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQylcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgZ2V0RGVjaW1hbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBudWxsID8gTmFOIDogKHZhbHVlIC0gdGhpcy5taW4pIC8gKHRoaXMubWF4IC0gdGhpcy5taW4pO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSAtIE1pbGxpc2Vjb25kcyBzaW5jZSBlcG9jaCAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuICBnZXRQaXhlbEZvclZhbHVlKHZhbHVlKSB7XG4gICAgY29uc3Qgb2Zmc2V0cyA9IHRoaXMuX29mZnNldHM7XG4gICAgY29uc3QgcG9zID0gdGhpcy5nZXREZWNpbWFsRm9yVmFsdWUodmFsdWUpO1xuICAgIHJldHVybiB0aGlzLmdldFBpeGVsRm9yRGVjaW1hbCgob2Zmc2V0cy5zdGFydCArIHBvcykgKiBvZmZzZXRzLmZhY3Rvcik7XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICovXG4gIGdldFZhbHVlRm9yUGl4ZWwocGl4ZWwpIHtcbiAgICBjb25zdCBvZmZzZXRzID0gdGhpcy5fb2Zmc2V0cztcbiAgICBjb25zdCBwb3MgPSB0aGlzLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkgLyBvZmZzZXRzLmZhY3RvciAtIG9mZnNldHMuZW5kO1xuICAgIHJldHVybiB0aGlzLm1pbiArIHBvcyAqICh0aGlzLm1heCAtIHRoaXMubWluKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbGFiZWxcblx0ICogQHJldHVybiB7e3c6bnVtYmVyLCBoOm51bWJlcn19XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuICBfZ2V0TGFiZWxTaXplKGxhYmVsKSB7XG4gICAgY29uc3QgdGlja3NPcHRzID0gdGhpcy5vcHRpb25zLnRpY2tzO1xuICAgIGNvbnN0IHRpY2tMYWJlbFdpZHRoID0gdGhpcy5jdHgubWVhc3VyZVRleHQobGFiZWwpLndpZHRoO1xuICAgIGNvbnN0IGFuZ2xlID0gdG9SYWRpYW5zKHRoaXMuaXNIb3Jpem9udGFsKCkgPyB0aWNrc09wdHMubWF4Um90YXRpb24gOiB0aWNrc09wdHMubWluUm90YXRpb24pO1xuICAgIGNvbnN0IGNvc1JvdGF0aW9uID0gTWF0aC5jb3MoYW5nbGUpO1xuICAgIGNvbnN0IHNpblJvdGF0aW9uID0gTWF0aC5zaW4oYW5nbGUpO1xuICAgIGNvbnN0IHRpY2tGb250U2l6ZSA9IHRoaXMuX3Jlc29sdmVUaWNrRm9udE9wdGlvbnMoMCkuc2l6ZTtcblxuICAgIHJldHVybiB7XG4gICAgICB3OiAodGlja0xhYmVsV2lkdGggKiBjb3NSb3RhdGlvbikgKyAodGlja0ZvbnRTaXplICogc2luUm90YXRpb24pLFxuICAgICAgaDogKHRpY2tMYWJlbFdpZHRoICogc2luUm90YXRpb24pICsgKHRpY2tGb250U2l6ZSAqIGNvc1JvdGF0aW9uKVxuICAgIH07XG4gIH1cblxuICAvKipcblx0ICogQHBhcmFtIHtudW1iZXJ9IGV4YW1wbGVUaW1lXG5cdCAqIEByZXR1cm4ge251bWJlcn1cblx0ICogQHByaXZhdGVcblx0ICovXG4gIF9nZXRMYWJlbENhcGFjaXR5KGV4YW1wbGVUaW1lKSB7XG4gICAgY29uc3QgdGltZU9wdHMgPSB0aGlzLm9wdGlvbnMudGltZTtcbiAgICBjb25zdCBkaXNwbGF5Rm9ybWF0cyA9IHRpbWVPcHRzLmRpc3BsYXlGb3JtYXRzO1xuXG4gICAgLy8gcGljayB0aGUgbG9uZ2VzdCBmb3JtYXQgKG1pbGxpc2Vjb25kcykgZm9yIGd1ZXNzdGltYXRpb25cbiAgICBjb25zdCBmb3JtYXQgPSBkaXNwbGF5Rm9ybWF0c1t0aW1lT3B0cy51bml0XSB8fCBkaXNwbGF5Rm9ybWF0cy5taWxsaXNlY29uZDtcbiAgICBjb25zdCBleGFtcGxlTGFiZWwgPSB0aGlzLl90aWNrRm9ybWF0RnVuY3Rpb24oZXhhbXBsZVRpbWUsIDAsIHRpY2tzRnJvbVRpbWVzdGFtcHModGhpcywgW2V4YW1wbGVUaW1lXSwgdGhpcy5fbWFqb3JVbml0KSwgZm9ybWF0KTtcbiAgICBjb25zdCBzaXplID0gdGhpcy5fZ2V0TGFiZWxTaXplKGV4YW1wbGVMYWJlbCk7XG4gICAgLy8gc3VidHJhY3QgMSAtIGlmIG9mZnNldCB0aGVuIHRoZXJlJ3Mgb25lIGxlc3MgbGFiZWwgdGhhbiB0aWNrXG4gICAgLy8gaWYgbm90IG9mZnNldCB0aGVuIG9uZSBoYWxmIGxhYmVsIHBhZGRpbmcgaXMgYWRkZWQgdG8gZWFjaCBlbmQgbGVhdmluZyByb29tIGZvciBvbmUgbGVzcyBsYWJlbFxuICAgIGNvbnN0IGNhcGFjaXR5ID0gTWF0aC5mbG9vcih0aGlzLmlzSG9yaXpvbnRhbCgpID8gdGhpcy53aWR0aCAvIHNpemUudyA6IHRoaXMuaGVpZ2h0IC8gc2l6ZS5oKSAtIDE7XG4gICAgcmV0dXJuIGNhcGFjaXR5ID4gMCA/IGNhcGFjaXR5IDogMTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBnZXREYXRhVGltZXN0YW1wcygpIHtcbiAgICBsZXQgdGltZXN0YW1wcyA9IHRoaXMuX2NhY2hlLmRhdGEgfHwgW107XG4gICAgbGV0IGksIGlsZW47XG5cbiAgICBpZiAodGltZXN0YW1wcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aW1lc3RhbXBzO1xuICAgIH1cblxuICAgIGNvbnN0IG1ldGFzID0gdGhpcy5nZXRNYXRjaGluZ1Zpc2libGVNZXRhcygpO1xuXG4gICAgaWYgKHRoaXMuX25vcm1hbGl6ZWQgJiYgbWV0YXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gKHRoaXMuX2NhY2hlLmRhdGEgPSBtZXRhc1swXS5jb250cm9sbGVyLmdldEFsbFBhcnNlZFZhbHVlcyh0aGlzKSk7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IG1ldGFzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgdGltZXN0YW1wcyA9IHRpbWVzdGFtcHMuY29uY2F0KG1ldGFzW2ldLmNvbnRyb2xsZXIuZ2V0QWxsUGFyc2VkVmFsdWVzKHRoaXMpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gKHRoaXMuX2NhY2hlLmRhdGEgPSB0aGlzLm5vcm1hbGl6ZSh0aW1lc3RhbXBzKSk7XG4gIH1cblxuICAvKipcblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgZ2V0TGFiZWxUaW1lc3RhbXBzKCkge1xuICAgIGNvbnN0IHRpbWVzdGFtcHMgPSB0aGlzLl9jYWNoZS5sYWJlbHMgfHwgW107XG4gICAgbGV0IGksIGlsZW47XG5cbiAgICBpZiAodGltZXN0YW1wcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aW1lc3RhbXBzO1xuICAgIH1cblxuICAgIGNvbnN0IGxhYmVscyA9IHRoaXMuZ2V0TGFiZWxzKCk7XG4gICAgZm9yIChpID0gMCwgaWxlbiA9IGxhYmVscy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcbiAgICAgIHRpbWVzdGFtcHMucHVzaChwYXJzZSh0aGlzLCBsYWJlbHNbaV0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gKHRoaXMuX2NhY2hlLmxhYmVscyA9IHRoaXMuX25vcm1hbGl6ZWQgPyB0aW1lc3RhbXBzIDogdGhpcy5ub3JtYWxpemUodGltZXN0YW1wcykpO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyW119IHZhbHVlc1xuXHQgKiBAcHJvdGVjdGVkXG5cdCAqL1xuICBub3JtYWxpemUodmFsdWVzKSB7XG4gICAgLy8gSXQgc2VlbXMgdG8gYmUgc29tZXdoYXQgZmFzdGVyIHRvIGRvIHNvcnRpbmcgZmlyc3RcbiAgICByZXR1cm4gX2FycmF5VW5pcXVlKHZhbHVlcy5zb3J0KHNvcnRlcikpO1xuICB9XG59XG4iLCAiaW1wb3J0IFRpbWVTY2FsZSBmcm9tICcuL3NjYWxlLnRpbWUuanMnO1xuaW1wb3J0IHtfbG9va3VwQnlLZXl9IGZyb20gJy4uL2hlbHBlcnMvaGVscGVycy5jb2xsZWN0aW9uLmpzJztcblxuLyoqXG4gKiBMaW5lYXJseSBpbnRlcnBvbGF0ZXMgdGhlIGdpdmVuIHNvdXJjZSBgdmFsYCB1c2luZyB0aGUgdGFibGUuIElmIHZhbHVlIGlzIG91dCBvZiBib3VuZHMsIHZhbHVlc1xuICogYXQgZWRnZXMgYXJlIHVzZWQgZm9yIHRoZSBpbnRlcnBvbGF0aW9uLlxuICogQHBhcmFtIHtvYmplY3R9IHRhYmxlXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXZlcnNlXSBsb29rdXAgdGltZSBiYXNlZCBvbiBwb3NpdGlvbiBpbnN0ZWFkIG9mIHZpY2UgdmVyc2FcbiAqIEByZXR1cm4ge29iamVjdH1cbiAqL1xuZnVuY3Rpb24gaW50ZXJwb2xhdGUodGFibGUsIHZhbCwgcmV2ZXJzZSkge1xuICBsZXQgbG8gPSAwO1xuICBsZXQgaGkgPSB0YWJsZS5sZW5ndGggLSAxO1xuICBsZXQgcHJldlNvdXJjZSwgbmV4dFNvdXJjZSwgcHJldlRhcmdldCwgbmV4dFRhcmdldDtcbiAgaWYgKHJldmVyc2UpIHtcbiAgICBpZiAodmFsID49IHRhYmxlW2xvXS5wb3MgJiYgdmFsIDw9IHRhYmxlW2hpXS5wb3MpIHtcbiAgICAgICh7bG8sIGhpfSA9IF9sb29rdXBCeUtleSh0YWJsZSwgJ3BvcycsIHZhbCkpO1xuICAgIH1cbiAgICAoe3BvczogcHJldlNvdXJjZSwgdGltZTogcHJldlRhcmdldH0gPSB0YWJsZVtsb10pO1xuICAgICh7cG9zOiBuZXh0U291cmNlLCB0aW1lOiBuZXh0VGFyZ2V0fSA9IHRhYmxlW2hpXSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHZhbCA+PSB0YWJsZVtsb10udGltZSAmJiB2YWwgPD0gdGFibGVbaGldLnRpbWUpIHtcbiAgICAgICh7bG8sIGhpfSA9IF9sb29rdXBCeUtleSh0YWJsZSwgJ3RpbWUnLCB2YWwpKTtcbiAgICB9XG4gICAgKHt0aW1lOiBwcmV2U291cmNlLCBwb3M6IHByZXZUYXJnZXR9ID0gdGFibGVbbG9dKTtcbiAgICAoe3RpbWU6IG5leHRTb3VyY2UsIHBvczogbmV4dFRhcmdldH0gPSB0YWJsZVtoaV0pO1xuICB9XG5cbiAgY29uc3Qgc3BhbiA9IG5leHRTb3VyY2UgLSBwcmV2U291cmNlO1xuICByZXR1cm4gc3BhbiA/IHByZXZUYXJnZXQgKyAobmV4dFRhcmdldCAtIHByZXZUYXJnZXQpICogKHZhbCAtIHByZXZTb3VyY2UpIC8gc3BhbiA6IHByZXZUYXJnZXQ7XG59XG5cbmNsYXNzIFRpbWVTZXJpZXNTY2FsZSBleHRlbmRzIFRpbWVTY2FsZSB7XG5cbiAgc3RhdGljIGlkID0gJ3RpbWVzZXJpZXMnO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgc3RhdGljIGRlZmF1bHRzID0gVGltZVNjYWxlLmRlZmF1bHRzO1xuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge29iamVjdH0gcHJvcHNcblx0ICovXG4gIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuXG4gICAgLyoqIEB0eXBlIHtvYmplY3RbXX0gKi9cbiAgICB0aGlzLl90YWJsZSA9IFtdO1xuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHRoaXMuX21pblBvcyA9IHVuZGVmaW5lZDtcbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLl90YWJsZVJhbmdlID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwcm90ZWN0ZWRcblx0ICovXG4gIGluaXRPZmZzZXRzKCkge1xuICAgIGNvbnN0IHRpbWVzdGFtcHMgPSB0aGlzLl9nZXRUaW1lc3RhbXBzRm9yVGFibGUoKTtcbiAgICBjb25zdCB0YWJsZSA9IHRoaXMuX3RhYmxlID0gdGhpcy5idWlsZExvb2t1cFRhYmxlKHRpbWVzdGFtcHMpO1xuICAgIHRoaXMuX21pblBvcyA9IGludGVycG9sYXRlKHRhYmxlLCB0aGlzLm1pbik7XG4gICAgdGhpcy5fdGFibGVSYW5nZSA9IGludGVycG9sYXRlKHRhYmxlLCB0aGlzLm1heCkgLSB0aGlzLl9taW5Qb3M7XG4gICAgc3VwZXIuaW5pdE9mZnNldHModGltZXN0YW1wcyk7XG4gIH1cblxuICAvKipcblx0ICogUmV0dXJucyBhbiBhcnJheSBvZiB7dGltZSwgcG9zfSBvYmplY3RzIHVzZWQgdG8gaW50ZXJwb2xhdGUgYSBzcGVjaWZpYyBgdGltZWAgb3IgcG9zaXRpb25cblx0ICogKGBwb3NgKSBvbiB0aGUgc2NhbGUsIGJ5IHNlYXJjaGluZyBlbnRyaWVzIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIHJlcXVlc3RlZCB2YWx1ZS4gYHBvc2AgaXNcblx0ICogYSBkZWNpbWFsIGJldHdlZW4gMCBhbmQgMTogMCBiZWluZyB0aGUgc3RhcnQgb2YgdGhlIHNjYWxlIChsZWZ0IG9yIHRvcCkgYW5kIDEgdGhlIG90aGVyXG5cdCAqIGV4dHJlbWl0eSAobGVmdCArIHdpZHRoIG9yIHRvcCArIGhlaWdodCkuIE5vdGUgdGhhdCBpdCB3b3VsZCBiZSBtb3JlIG9wdGltaXplZCB0byBkaXJlY3RseVxuXHQgKiBzdG9yZSBwcmUtY29tcHV0ZWQgcGl4ZWxzLCBidXQgdGhlIHNjYWxlIGRpbWVuc2lvbnMgYXJlIG5vdCBndWFyYW50ZWVkIGF0IHRoZSB0aW1lIHdlIG5lZWRcblx0ICogdG8gY3JlYXRlIHRoZSBsb29rdXAgdGFibGUuIFRoZSB0YWJsZSBBTFdBWVMgY29udGFpbnMgYXQgbGVhc3QgdHdvIGl0ZW1zOiBtaW4gYW5kIG1heC5cblx0ICogQHBhcmFtIHtudW1iZXJbXX0gdGltZXN0YW1wc1xuXHQgKiBAcmV0dXJuIHtvYmplY3RbXX1cblx0ICogQHByb3RlY3RlZFxuXHQgKi9cbiAgYnVpbGRMb29rdXBUYWJsZSh0aW1lc3RhbXBzKSB7XG4gICAgY29uc3Qge21pbiwgbWF4fSA9IHRoaXM7XG4gICAgY29uc3QgaXRlbXMgPSBbXTtcbiAgICBjb25zdCB0YWJsZSA9IFtdO1xuICAgIGxldCBpLCBpbGVuLCBwcmV2LCBjdXJyLCBuZXh0O1xuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IHRpbWVzdGFtcHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XG4gICAgICBjdXJyID0gdGltZXN0YW1wc1tpXTtcbiAgICAgIGlmIChjdXJyID49IG1pbiAmJiBjdXJyIDw9IG1heCkge1xuICAgICAgICBpdGVtcy5wdXNoKGN1cnIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpdGVtcy5sZW5ndGggPCAyKSB7XG4gICAgICAvLyBJbiBjYXNlIHRoZXJlIGlzIGxlc3MgdGhhdCAyIHRpbWVzdGFtcHMgYmV0d2VlbiBtaW4gYW5kIG1heCwgdGhlIHNjYWxlIGlzIGRlZmluZWQgYnkgbWluIGFuZCBtYXhcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHt0aW1lOiBtaW4sIHBvczogMH0sXG4gICAgICAgIHt0aW1lOiBtYXgsIHBvczogMX1cbiAgICAgIF07XG4gICAgfVxuXG4gICAgZm9yIChpID0gMCwgaWxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xuICAgICAgbmV4dCA9IGl0ZW1zW2kgKyAxXTtcbiAgICAgIHByZXYgPSBpdGVtc1tpIC0gMV07XG4gICAgICBjdXJyID0gaXRlbXNbaV07XG5cbiAgICAgIC8vIG9ubHkgYWRkIHBvaW50cyB0aGF0IGJyZWFrcyB0aGUgc2NhbGUgbGluZWFyaXR5XG4gICAgICBpZiAoTWF0aC5yb3VuZCgobmV4dCArIHByZXYpIC8gMikgIT09IGN1cnIpIHtcbiAgICAgICAgdGFibGUucHVzaCh7dGltZTogY3VyciwgcG9zOiBpIC8gKGlsZW4gLSAxKX0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGFibGU7XG4gIH1cblxuICAvKipcbiAgICAqIEdlbmVyYXRlcyBhbGwgdGltZXN0YW1wcyBkZWZpbmVkIGluIHRoZSBkYXRhLlxuICAgICogSW1wb3J0YW50OiB0aGlzIG1ldGhvZCBjYW4gcmV0dXJuIHRpY2tzIG91dHNpZGUgdGhlIG1pbiBhbmQgbWF4IHJhbmdlLCBpdCdzIHRoZVxuICAgICogcmVzcG9uc2liaWxpdHkgb2YgdGhlIGNhbGxpbmcgY29kZSB0byBjbGFtcCB2YWx1ZXMgaWYgbmVlZGVkLlxuICAgICogQHByb3RlY3RlZFxuICAgICovXG4gIF9nZW5lcmF0ZSgpIHtcbiAgICBjb25zdCBtaW4gPSB0aGlzLm1pbjtcbiAgICBjb25zdCBtYXggPSB0aGlzLm1heDtcbiAgICBsZXQgdGltZXN0YW1wcyA9IHN1cGVyLmdldERhdGFUaW1lc3RhbXBzKCk7XG4gICAgaWYgKCF0aW1lc3RhbXBzLmluY2x1ZGVzKG1pbikgfHwgIXRpbWVzdGFtcHMubGVuZ3RoKSB7XG4gICAgICB0aW1lc3RhbXBzLnNwbGljZSgwLCAwLCBtaW4pO1xuICAgIH1cbiAgICBpZiAoIXRpbWVzdGFtcHMuaW5jbHVkZXMobWF4KSB8fCB0aW1lc3RhbXBzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdGltZXN0YW1wcy5wdXNoKG1heCk7XG4gICAgfVxuICAgIHJldHVybiB0aW1lc3RhbXBzLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBSZXR1cm5zIGFsbCB0aW1lc3RhbXBzXG5cdCAqIEByZXR1cm4ge251bWJlcltdfVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cbiAgX2dldFRpbWVzdGFtcHNGb3JUYWJsZSgpIHtcbiAgICBsZXQgdGltZXN0YW1wcyA9IHRoaXMuX2NhY2hlLmFsbCB8fCBbXTtcblxuICAgIGlmICh0aW1lc3RhbXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRpbWVzdGFtcHM7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZ2V0RGF0YVRpbWVzdGFtcHMoKTtcbiAgICBjb25zdCBsYWJlbCA9IHRoaXMuZ2V0TGFiZWxUaW1lc3RhbXBzKCk7XG4gICAgaWYgKGRhdGEubGVuZ3RoICYmIGxhYmVsLmxlbmd0aCkge1xuICAgICAgLy8gSWYgY29tYmluaW5nIGxhYmVscyBhbmQgZGF0YSAoZGF0YSBtaWdodCBub3QgY29udGFpbiBhbGwgbGFiZWxzKSxcbiAgICAgIC8vIHdlIG5lZWQgdG8gcmVjaGVjayB1bmlxdWVuZXNzIGFuZCBzb3J0XG4gICAgICB0aW1lc3RhbXBzID0gdGhpcy5ub3JtYWxpemUoZGF0YS5jb25jYXQobGFiZWwpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGltZXN0YW1wcyA9IGRhdGEubGVuZ3RoID8gZGF0YSA6IGxhYmVsO1xuICAgIH1cbiAgICB0aW1lc3RhbXBzID0gdGhpcy5fY2FjaGUuYWxsID0gdGltZXN0YW1wcztcblxuICAgIHJldHVybiB0aW1lc3RhbXBzO1xuICB9XG5cbiAgLyoqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSAtIE1pbGxpc2Vjb25kcyBzaW5jZSBlcG9jaCAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqL1xuICBnZXREZWNpbWFsRm9yVmFsdWUodmFsdWUpIHtcbiAgICByZXR1cm4gKGludGVycG9sYXRlKHRoaXMuX3RhYmxlLCB2YWx1ZSkgLSB0aGlzLl9taW5Qb3MpIC8gdGhpcy5fdGFibGVSYW5nZTtcbiAgfVxuXG4gIC8qKlxuXHQgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKi9cbiAgZ2V0VmFsdWVGb3JQaXhlbChwaXhlbCkge1xuICAgIGNvbnN0IG9mZnNldHMgPSB0aGlzLl9vZmZzZXRzO1xuICAgIGNvbnN0IGRlY2ltYWwgPSB0aGlzLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkgLyBvZmZzZXRzLmZhY3RvciAtIG9mZnNldHMuZW5kO1xuICAgIHJldHVybiBpbnRlcnBvbGF0ZSh0aGlzLl90YWJsZSwgZGVjaW1hbCAqIHRoaXMuX3RhYmxlUmFuZ2UgKyB0aGlzLl9taW5Qb3MsIHRydWUpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFRpbWVTZXJpZXNTY2FsZTtcbiIsICJleHBvcnQgKiBmcm9tICcuL2NvbnRyb2xsZXJzL2luZGV4LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vY29yZS9pbmRleC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2VsZW1lbnRzL2luZGV4LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vcGxhdGZvcm0vaW5kZXguanMnO1xuZXhwb3J0ICogZnJvbSAnLi9wbHVnaW5zL2luZGV4LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vc2NhbGVzL2luZGV4LmpzJztcblxuaW1wb3J0ICogYXMgY29udHJvbGxlcnMgZnJvbSAnLi9jb250cm9sbGVycy9pbmRleC5qcyc7XG5pbXBvcnQgKiBhcyBlbGVtZW50cyBmcm9tICcuL2VsZW1lbnRzL2luZGV4LmpzJztcbmltcG9ydCAqIGFzIHBsdWdpbnMgZnJvbSAnLi9wbHVnaW5zL2luZGV4LmpzJztcbmltcG9ydCAqIGFzIHNjYWxlcyBmcm9tICcuL3NjYWxlcy9pbmRleC5qcyc7XG5cbmV4cG9ydCB7XG4gIGNvbnRyb2xsZXJzLFxuICBlbGVtZW50cyxcbiAgcGx1Z2lucyxcbiAgc2NhbGVzLFxufTtcblxuZXhwb3J0IGNvbnN0IHJlZ2lzdGVyYWJsZXMgPSBbXG4gIGNvbnRyb2xsZXJzLFxuICBlbGVtZW50cyxcbiAgcGx1Z2lucyxcbiAgc2NhbGVzLFxuXTtcbiIsICIvLyB0aGVzZSBhcmVuJ3QgcmVhbGx5IHByaXZhdGUsIGJ1dCBub3IgYXJlIHRoZXkgcmVhbGx5IHVzZWZ1bCB0byBkb2N1bWVudFxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIEx1eG9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7fVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnZhbGlkRGF0ZVRpbWVFcnJvciBleHRlbmRzIEx1eG9uRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihyZWFzb24pIHtcbiAgICBzdXBlcihgSW52YWxpZCBEYXRlVGltZTogJHtyZWFzb24udG9NZXNzYWdlKCl9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgSW52YWxpZEludGVydmFsRXJyb3IgZXh0ZW5kcyBMdXhvbkVycm9yIHtcbiAgY29uc3RydWN0b3IocmVhc29uKSB7XG4gICAgc3VwZXIoYEludmFsaWQgSW50ZXJ2YWw6ICR7cmVhc29uLnRvTWVzc2FnZSgpfWApO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIEludmFsaWREdXJhdGlvbkVycm9yIGV4dGVuZHMgTHV4b25FcnJvciB7XG4gIGNvbnN0cnVjdG9yKHJlYXNvbikge1xuICAgIHN1cGVyKGBJbnZhbGlkIER1cmF0aW9uOiAke3JlYXNvbi50b01lc3NhZ2UoKX1gKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25mbGljdGluZ1NwZWNpZmljYXRpb25FcnJvciBleHRlbmRzIEx1eG9uRXJyb3Ige31cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgSW52YWxpZFVuaXRFcnJvciBleHRlbmRzIEx1eG9uRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcih1bml0KSB7XG4gICAgc3VwZXIoYEludmFsaWQgdW5pdCAke3VuaXR9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgSW52YWxpZEFyZ3VtZW50RXJyb3IgZXh0ZW5kcyBMdXhvbkVycm9yIHt9XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIFpvbmVJc0Fic3RyYWN0RXJyb3IgZXh0ZW5kcyBMdXhvbkVycm9yIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoXCJab25lIGlzIGFuIGFic3RyYWN0IGNsYXNzXCIpO1xuICB9XG59XG4iLCAiLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cbmNvbnN0IG4gPSBcIm51bWVyaWNcIixcbiAgcyA9IFwic2hvcnRcIixcbiAgbCA9IFwibG9uZ1wiO1xuXG5leHBvcnQgY29uc3QgREFURV9TSE9SVCA9IHtcbiAgeWVhcjogbixcbiAgbW9udGg6IG4sXG4gIGRheTogbixcbn07XG5cbmV4cG9ydCBjb25zdCBEQVRFX01FRCA9IHtcbiAgeWVhcjogbixcbiAgbW9udGg6IHMsXG4gIGRheTogbixcbn07XG5cbmV4cG9ydCBjb25zdCBEQVRFX01FRF9XSVRIX1dFRUtEQVkgPSB7XG4gIHllYXI6IG4sXG4gIG1vbnRoOiBzLFxuICBkYXk6IG4sXG4gIHdlZWtkYXk6IHMsXG59O1xuXG5leHBvcnQgY29uc3QgREFURV9GVUxMID0ge1xuICB5ZWFyOiBuLFxuICBtb250aDogbCxcbiAgZGF5OiBuLFxufTtcblxuZXhwb3J0IGNvbnN0IERBVEVfSFVHRSA9IHtcbiAgeWVhcjogbixcbiAgbW9udGg6IGwsXG4gIGRheTogbixcbiAgd2Vla2RheTogbCxcbn07XG5cbmV4cG9ydCBjb25zdCBUSU1FX1NJTVBMRSA9IHtcbiAgaG91cjogbixcbiAgbWludXRlOiBuLFxufTtcblxuZXhwb3J0IGNvbnN0IFRJTUVfV0lUSF9TRUNPTkRTID0ge1xuICBob3VyOiBuLFxuICBtaW51dGU6IG4sXG4gIHNlY29uZDogbixcbn07XG5cbmV4cG9ydCBjb25zdCBUSU1FX1dJVEhfU0hPUlRfT0ZGU0VUID0ge1xuICBob3VyOiBuLFxuICBtaW51dGU6IG4sXG4gIHNlY29uZDogbixcbiAgdGltZVpvbmVOYW1lOiBzLFxufTtcblxuZXhwb3J0IGNvbnN0IFRJTUVfV0lUSF9MT05HX09GRlNFVCA9IHtcbiAgaG91cjogbixcbiAgbWludXRlOiBuLFxuICBzZWNvbmQ6IG4sXG4gIHRpbWVab25lTmFtZTogbCxcbn07XG5cbmV4cG9ydCBjb25zdCBUSU1FXzI0X1NJTVBMRSA9IHtcbiAgaG91cjogbixcbiAgbWludXRlOiBuLFxuICBob3VyQ3ljbGU6IFwiaDIzXCIsXG59O1xuXG5leHBvcnQgY29uc3QgVElNRV8yNF9XSVRIX1NFQ09ORFMgPSB7XG4gIGhvdXI6IG4sXG4gIG1pbnV0ZTogbixcbiAgc2Vjb25kOiBuLFxuICBob3VyQ3ljbGU6IFwiaDIzXCIsXG59O1xuXG5leHBvcnQgY29uc3QgVElNRV8yNF9XSVRIX1NIT1JUX09GRlNFVCA9IHtcbiAgaG91cjogbixcbiAgbWludXRlOiBuLFxuICBzZWNvbmQ6IG4sXG4gIGhvdXJDeWNsZTogXCJoMjNcIixcbiAgdGltZVpvbmVOYW1lOiBzLFxufTtcblxuZXhwb3J0IGNvbnN0IFRJTUVfMjRfV0lUSF9MT05HX09GRlNFVCA9IHtcbiAgaG91cjogbixcbiAgbWludXRlOiBuLFxuICBzZWNvbmQ6IG4sXG4gIGhvdXJDeWNsZTogXCJoMjNcIixcbiAgdGltZVpvbmVOYW1lOiBsLFxufTtcblxuZXhwb3J0IGNvbnN0IERBVEVUSU1FX1NIT1JUID0ge1xuICB5ZWFyOiBuLFxuICBtb250aDogbixcbiAgZGF5OiBuLFxuICBob3VyOiBuLFxuICBtaW51dGU6IG4sXG59O1xuXG5leHBvcnQgY29uc3QgREFURVRJTUVfU0hPUlRfV0lUSF9TRUNPTkRTID0ge1xuICB5ZWFyOiBuLFxuICBtb250aDogbixcbiAgZGF5OiBuLFxuICBob3VyOiBuLFxuICBtaW51dGU6IG4sXG4gIHNlY29uZDogbixcbn07XG5cbmV4cG9ydCBjb25zdCBEQVRFVElNRV9NRUQgPSB7XG4gIHllYXI6IG4sXG4gIG1vbnRoOiBzLFxuICBkYXk6IG4sXG4gIGhvdXI6IG4sXG4gIG1pbnV0ZTogbixcbn07XG5cbmV4cG9ydCBjb25zdCBEQVRFVElNRV9NRURfV0lUSF9TRUNPTkRTID0ge1xuICB5ZWFyOiBuLFxuICBtb250aDogcyxcbiAgZGF5OiBuLFxuICBob3VyOiBuLFxuICBtaW51dGU6IG4sXG4gIHNlY29uZDogbixcbn07XG5cbmV4cG9ydCBjb25zdCBEQVRFVElNRV9NRURfV0lUSF9XRUVLREFZID0ge1xuICB5ZWFyOiBuLFxuICBtb250aDogcyxcbiAgZGF5OiBuLFxuICB3ZWVrZGF5OiBzLFxuICBob3VyOiBuLFxuICBtaW51dGU6IG4sXG59O1xuXG5leHBvcnQgY29uc3QgREFURVRJTUVfRlVMTCA9IHtcbiAgeWVhcjogbixcbiAgbW9udGg6IGwsXG4gIGRheTogbixcbiAgaG91cjogbixcbiAgbWludXRlOiBuLFxuICB0aW1lWm9uZU5hbWU6IHMsXG59O1xuXG5leHBvcnQgY29uc3QgREFURVRJTUVfRlVMTF9XSVRIX1NFQ09ORFMgPSB7XG4gIHllYXI6IG4sXG4gIG1vbnRoOiBsLFxuICBkYXk6IG4sXG4gIGhvdXI6IG4sXG4gIG1pbnV0ZTogbixcbiAgc2Vjb25kOiBuLFxuICB0aW1lWm9uZU5hbWU6IHMsXG59O1xuXG5leHBvcnQgY29uc3QgREFURVRJTUVfSFVHRSA9IHtcbiAgeWVhcjogbixcbiAgbW9udGg6IGwsXG4gIGRheTogbixcbiAgd2Vla2RheTogbCxcbiAgaG91cjogbixcbiAgbWludXRlOiBuLFxuICB0aW1lWm9uZU5hbWU6IGwsXG59O1xuXG5leHBvcnQgY29uc3QgREFURVRJTUVfSFVHRV9XSVRIX1NFQ09ORFMgPSB7XG4gIHllYXI6IG4sXG4gIG1vbnRoOiBsLFxuICBkYXk6IG4sXG4gIHdlZWtkYXk6IGwsXG4gIGhvdXI6IG4sXG4gIG1pbnV0ZTogbixcbiAgc2Vjb25kOiBuLFxuICB0aW1lWm9uZU5hbWU6IGwsXG59O1xuIiwgImltcG9ydCB7IFpvbmVJc0Fic3RyYWN0RXJyb3IgfSBmcm9tIFwiLi9lcnJvcnMuanNcIjtcblxuLyoqXG4gKiBAaW50ZXJmYWNlXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFpvbmUge1xuICAvKipcbiAgICogVGhlIHR5cGUgb2Ygem9uZVxuICAgKiBAYWJzdHJhY3RcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICovXG4gIGdldCB0eXBlKCkge1xuICAgIHRocm93IG5ldyBab25lSXNBYnN0cmFjdEVycm9yKCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhpcyB6b25lLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICovXG4gIGdldCBuYW1lKCkge1xuICAgIHRocm93IG5ldyBab25lSXNBYnN0cmFjdEVycm9yKCk7XG4gIH1cblxuICBnZXQgaWFuYU5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMubmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIG9mZnNldCBpcyBrbm93biB0byBiZSBmaXhlZCBmb3IgdGhlIHdob2xlIHllYXIuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIGdldCBpc1VuaXZlcnNhbCgpIHtcbiAgICB0aHJvdyBuZXcgWm9uZUlzQWJzdHJhY3RFcnJvcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIG9mZnNldCdzIGNvbW1vbiBuYW1lIChzdWNoIGFzIEVTVCkgYXQgdGhlIHNwZWNpZmllZCB0aW1lc3RhbXBcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0cyAtIEVwb2NoIG1pbGxpc2Vjb25kcyBmb3Igd2hpY2ggdG8gZ2V0IHRoZSBuYW1lXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gT3B0aW9ucyB0byBhZmZlY3QgdGhlIGZvcm1hdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0cy5mb3JtYXQgLSBXaGF0IHN0eWxlIG9mIG9mZnNldCB0byByZXR1cm4uIEFjY2VwdHMgJ2xvbmcnIG9yICdzaG9ydCcuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLmxvY2FsZSAtIFdoYXQgbG9jYWxlIHRvIHJldHVybiB0aGUgb2Zmc2V0IG5hbWUgaW4uXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICovXG4gIG9mZnNldE5hbWUodHMsIG9wdHMpIHtcbiAgICB0aHJvdyBuZXcgWm9uZUlzQWJzdHJhY3RFcnJvcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIG9mZnNldCdzIHZhbHVlIGFzIGEgc3RyaW5nXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge251bWJlcn0gdHMgLSBFcG9jaCBtaWxsaXNlY29uZHMgZm9yIHdoaWNoIHRvIGdldCB0aGUgb2Zmc2V0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtYXQgLSBXaGF0IHN0eWxlIG9mIG9mZnNldCB0byByZXR1cm4uXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBBY2NlcHRzICduYXJyb3cnLCAnc2hvcnQnLCBvciAndGVjaGllJy4gUmV0dXJuaW5nICcrNicsICcrMDY6MDAnLCBvciAnKzA2MDAnIHJlc3BlY3RpdmVseVxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICBmb3JtYXRPZmZzZXQodHMsIGZvcm1hdCkge1xuICAgIHRocm93IG5ldyBab25lSXNBYnN0cmFjdEVycm9yKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBvZmZzZXQgaW4gbWludXRlcyBmb3IgdGhpcyB6b25lIGF0IHRoZSBzcGVjaWZpZWQgdGltZXN0YW1wLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRzIC0gRXBvY2ggbWlsbGlzZWNvbmRzIGZvciB3aGljaCB0byBjb21wdXRlIHRoZSBvZmZzZXRcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgb2Zmc2V0KHRzKSB7XG4gICAgdGhyb3cgbmV3IFpvbmVJc0Fic3RyYWN0RXJyb3IoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gd2hldGhlciB0aGlzIFpvbmUgaXMgZXF1YWwgdG8gYW5vdGhlciB6b25lXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge1pvbmV9IG90aGVyWm9uZSAtIHRoZSB6b25lIHRvIGNvbXBhcmVcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGVxdWFscyhvdGhlclpvbmUpIHtcbiAgICB0aHJvdyBuZXcgWm9uZUlzQWJzdHJhY3RFcnJvcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB3aGV0aGVyIHRoaXMgWm9uZSBpcyB2YWxpZC5cbiAgICogQGFic3RyYWN0XG4gICAqIEB0eXBlIHtib29sZWFufVxuICAgKi9cbiAgZ2V0IGlzVmFsaWQoKSB7XG4gICAgdGhyb3cgbmV3IFpvbmVJc0Fic3RyYWN0RXJyb3IoKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IGZvcm1hdE9mZnNldCwgcGFyc2Vab25lSW5mbyB9IGZyb20gXCIuLi9pbXBsL3V0aWwuanNcIjtcbmltcG9ydCBab25lIGZyb20gXCIuLi96b25lLmpzXCI7XG5cbmxldCBzaW5nbGV0b24gPSBudWxsO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIGxvY2FsIHpvbmUgZm9yIHRoaXMgSmF2YVNjcmlwdCBlbnZpcm9ubWVudC5cbiAqIEBpbXBsZW1lbnRzIHtab25lfVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTeXN0ZW1ab25lIGV4dGVuZHMgWm9uZSB7XG4gIC8qKlxuICAgKiBHZXQgYSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIGxvY2FsIHpvbmVcbiAgICogQHJldHVybiB7U3lzdGVtWm9uZX1cbiAgICovXG4gIHN0YXRpYyBnZXQgaW5zdGFuY2UoKSB7XG4gICAgaWYgKHNpbmdsZXRvbiA9PT0gbnVsbCkge1xuICAgICAgc2luZ2xldG9uID0gbmV3IFN5c3RlbVpvbmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHNpbmdsZXRvbjtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiBcInN5c3RlbVwiO1xuICB9XG5cbiAgLyoqIEBvdmVycmlkZSAqKi9cbiAgZ2V0IG5hbWUoKSB7XG4gICAgcmV0dXJuIG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KCkucmVzb2x2ZWRPcHRpb25zKCkudGltZVpvbmU7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBnZXQgaXNVbml2ZXJzYWwoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqIEBvdmVycmlkZSAqKi9cbiAgb2Zmc2V0TmFtZSh0cywgeyBmb3JtYXQsIGxvY2FsZSB9KSB7XG4gICAgcmV0dXJuIHBhcnNlWm9uZUluZm8odHMsIGZvcm1hdCwgbG9jYWxlKTtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGZvcm1hdE9mZnNldCh0cywgZm9ybWF0KSB7XG4gICAgcmV0dXJuIGZvcm1hdE9mZnNldCh0aGlzLm9mZnNldCh0cyksIGZvcm1hdCk7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBvZmZzZXQodHMpIHtcbiAgICByZXR1cm4gLW5ldyBEYXRlKHRzKS5nZXRUaW1lem9uZU9mZnNldCgpO1xuICB9XG5cbiAgLyoqIEBvdmVycmlkZSAqKi9cbiAgZXF1YWxzKG90aGVyWm9uZSkge1xuICAgIHJldHVybiBvdGhlclpvbmUudHlwZSA9PT0gXCJzeXN0ZW1cIjtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGdldCBpc1ZhbGlkKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgZm9ybWF0T2Zmc2V0LCBwYXJzZVpvbmVJbmZvLCBpc1VuZGVmaW5lZCwgb2JqVG9Mb2NhbFRTIH0gZnJvbSBcIi4uL2ltcGwvdXRpbC5qc1wiO1xuaW1wb3J0IFpvbmUgZnJvbSBcIi4uL3pvbmUuanNcIjtcblxubGV0IGR0ZkNhY2hlID0ge307XG5mdW5jdGlvbiBtYWtlRFRGKHpvbmUpIHtcbiAgaWYgKCFkdGZDYWNoZVt6b25lXSkge1xuICAgIGR0ZkNhY2hlW3pvbmVdID0gbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQoXCJlbi1VU1wiLCB7XG4gICAgICBob3VyMTI6IGZhbHNlLFxuICAgICAgdGltZVpvbmU6IHpvbmUsXG4gICAgICB5ZWFyOiBcIm51bWVyaWNcIixcbiAgICAgIG1vbnRoOiBcIjItZGlnaXRcIixcbiAgICAgIGRheTogXCIyLWRpZ2l0XCIsXG4gICAgICBob3VyOiBcIjItZGlnaXRcIixcbiAgICAgIG1pbnV0ZTogXCIyLWRpZ2l0XCIsXG4gICAgICBzZWNvbmQ6IFwiMi1kaWdpdFwiLFxuICAgICAgZXJhOiBcInNob3J0XCIsXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGR0ZkNhY2hlW3pvbmVdO1xufVxuXG5jb25zdCB0eXBlVG9Qb3MgPSB7XG4gIHllYXI6IDAsXG4gIG1vbnRoOiAxLFxuICBkYXk6IDIsXG4gIGVyYTogMyxcbiAgaG91cjogNCxcbiAgbWludXRlOiA1LFxuICBzZWNvbmQ6IDYsXG59O1xuXG5mdW5jdGlvbiBoYWNreU9mZnNldChkdGYsIGRhdGUpIHtcbiAgY29uc3QgZm9ybWF0dGVkID0gZHRmLmZvcm1hdChkYXRlKS5yZXBsYWNlKC9cXHUyMDBFL2csIFwiXCIpLFxuICAgIHBhcnNlZCA9IC8oXFxkKylcXC8oXFxkKylcXC8oXFxkKykgKEFEfEJDKSw/IChcXGQrKTooXFxkKyk6KFxcZCspLy5leGVjKGZvcm1hdHRlZCksXG4gICAgWywgZk1vbnRoLCBmRGF5LCBmWWVhciwgZmFkT3JCYywgZkhvdXIsIGZNaW51dGUsIGZTZWNvbmRdID0gcGFyc2VkO1xuICByZXR1cm4gW2ZZZWFyLCBmTW9udGgsIGZEYXksIGZhZE9yQmMsIGZIb3VyLCBmTWludXRlLCBmU2Vjb25kXTtcbn1cblxuZnVuY3Rpb24gcGFydHNPZmZzZXQoZHRmLCBkYXRlKSB7XG4gIGNvbnN0IGZvcm1hdHRlZCA9IGR0Zi5mb3JtYXRUb1BhcnRzKGRhdGUpO1xuICBjb25zdCBmaWxsZWQgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBmb3JtYXR0ZWQubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCB7IHR5cGUsIHZhbHVlIH0gPSBmb3JtYXR0ZWRbaV07XG4gICAgY29uc3QgcG9zID0gdHlwZVRvUG9zW3R5cGVdO1xuXG4gICAgaWYgKHR5cGUgPT09IFwiZXJhXCIpIHtcbiAgICAgIGZpbGxlZFtwb3NdID0gdmFsdWU7XG4gICAgfSBlbHNlIGlmICghaXNVbmRlZmluZWQocG9zKSkge1xuICAgICAgZmlsbGVkW3Bvc10gPSBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmlsbGVkO1xufVxuXG5sZXQgaWFuYVpvbmVDYWNoZSA9IHt9O1xuLyoqXG4gKiBBIHpvbmUgaWRlbnRpZmllZCBieSBhbiBJQU5BIGlkZW50aWZpZXIsIGxpa2UgQW1lcmljYS9OZXdfWW9ya1xuICogQGltcGxlbWVudHMge1pvbmV9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIElBTkFab25lIGV4dGVuZHMgWm9uZSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFpvbmUgbmFtZVxuICAgKiBAcmV0dXJuIHtJQU5BWm9uZX1cbiAgICovXG4gIHN0YXRpYyBjcmVhdGUobmFtZSkge1xuICAgIGlmICghaWFuYVpvbmVDYWNoZVtuYW1lXSkge1xuICAgICAgaWFuYVpvbmVDYWNoZVtuYW1lXSA9IG5ldyBJQU5BWm9uZShuYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuIGlhbmFab25lQ2FjaGVbbmFtZV07XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgbG9jYWwgY2FjaGVzLiBTaG91bGQgb25seSBiZSBuZWNlc3NhcnkgaW4gdGVzdGluZyBzY2VuYXJpb3MuXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgcmVzZXRDYWNoZSgpIHtcbiAgICBpYW5hWm9uZUNhY2hlID0ge307XG4gICAgZHRmQ2FjaGUgPSB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHByb3ZpZGVkIHN0cmluZyBpcyBhIHZhbGlkIHNwZWNpZmllci4gVGhpcyBvbmx5IGNoZWNrcyB0aGUgc3RyaW5nJ3MgZm9ybWF0LCBub3QgdGhhdCB0aGUgc3BlY2lmaWVyIGlkZW50aWZpZXMgYSBrbm93biB6b25lOyBzZWUgaXNWYWxpZFpvbmUgZm9yIHRoYXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzIC0gVGhlIHN0cmluZyB0byBjaGVjayB2YWxpZGl0eSBvblxuICAgKiBAZXhhbXBsZSBJQU5BWm9uZS5pc1ZhbGlkU3BlY2lmaWVyKFwiQW1lcmljYS9OZXdfWW9ya1wiKSAvLz0+IHRydWVcbiAgICogQGV4YW1wbGUgSUFOQVpvbmUuaXNWYWxpZFNwZWNpZmllcihcIlNwb3J0fn5ibG9ycFwiKSAvLz0+IGZhbHNlXG4gICAqIEBkZXByZWNhdGVkIFRoaXMgbWV0aG9kIHJldHVybnMgZmFsc2UgZm9yIHNvbWUgdmFsaWQgSUFOQSBuYW1lcy4gVXNlIGlzVmFsaWRab25lIGluc3RlYWQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBzdGF0aWMgaXNWYWxpZFNwZWNpZmllcihzKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZFpvbmUocyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBwcm92aWRlZCBzdHJpbmcgaWRlbnRpZmllcyBhIHJlYWwgem9uZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gem9uZSAtIFRoZSBzdHJpbmcgdG8gY2hlY2tcbiAgICogQGV4YW1wbGUgSUFOQVpvbmUuaXNWYWxpZFpvbmUoXCJBbWVyaWNhL05ld19Zb3JrXCIpIC8vPT4gdHJ1ZVxuICAgKiBAZXhhbXBsZSBJQU5BWm9uZS5pc1ZhbGlkWm9uZShcIkZhbnRhc2lhL0Nhc3RsZVwiKSAvLz0+IGZhbHNlXG4gICAqIEBleGFtcGxlIElBTkFab25lLmlzVmFsaWRab25lKFwiU3BvcnR+fmJsb3JwXCIpIC8vPT4gZmFsc2VcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIHN0YXRpYyBpc1ZhbGlkWm9uZSh6b25lKSB7XG4gICAgaWYgKCF6b25lKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBuZXcgSW50bC5EYXRlVGltZUZvcm1hdChcImVuLVVTXCIsIHsgdGltZVpvbmU6IHpvbmUgfSkuZm9ybWF0KCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IobmFtZSkge1xuICAgIHN1cGVyKCk7XG4gICAgLyoqIEBwcml2YXRlICoqL1xuICAgIHRoaXMuem9uZU5hbWUgPSBuYW1lO1xuICAgIC8qKiBAcHJpdmF0ZSAqKi9cbiAgICB0aGlzLnZhbGlkID0gSUFOQVpvbmUuaXNWYWxpZFpvbmUobmFtZSk7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBnZXQgdHlwZSgpIHtcbiAgICByZXR1cm4gXCJpYW5hXCI7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBnZXQgbmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy56b25lTmFtZTtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGdldCBpc1VuaXZlcnNhbCgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBvZmZzZXROYW1lKHRzLCB7IGZvcm1hdCwgbG9jYWxlIH0pIHtcbiAgICByZXR1cm4gcGFyc2Vab25lSW5mbyh0cywgZm9ybWF0LCBsb2NhbGUsIHRoaXMubmFtZSk7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBmb3JtYXRPZmZzZXQodHMsIGZvcm1hdCkge1xuICAgIHJldHVybiBmb3JtYXRPZmZzZXQodGhpcy5vZmZzZXQodHMpLCBmb3JtYXQpO1xuICB9XG5cbiAgLyoqIEBvdmVycmlkZSAqKi9cbiAgb2Zmc2V0KHRzKSB7XG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHRzKTtcblxuICAgIGlmIChpc05hTihkYXRlKSkgcmV0dXJuIE5hTjtcblxuICAgIGNvbnN0IGR0ZiA9IG1ha2VEVEYodGhpcy5uYW1lKTtcbiAgICBsZXQgW3llYXIsIG1vbnRoLCBkYXksIGFkT3JCYywgaG91ciwgbWludXRlLCBzZWNvbmRdID0gZHRmLmZvcm1hdFRvUGFydHNcbiAgICAgID8gcGFydHNPZmZzZXQoZHRmLCBkYXRlKVxuICAgICAgOiBoYWNreU9mZnNldChkdGYsIGRhdGUpO1xuXG4gICAgaWYgKGFkT3JCYyA9PT0gXCJCQ1wiKSB7XG4gICAgICB5ZWFyID0gLU1hdGguYWJzKHllYXIpICsgMTtcbiAgICB9XG5cbiAgICAvLyBiZWNhdXNlIHdlJ3JlIHVzaW5nIGhvdXIxMiBhbmQgaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9MTAyNTU2NCZjYW49MiZxPSUyMjI0JTNBMDAlMjIlMjBkYXRldGltZWZvcm1hdFxuICAgIGNvbnN0IGFkanVzdGVkSG91ciA9IGhvdXIgPT09IDI0ID8gMCA6IGhvdXI7XG5cbiAgICBjb25zdCBhc1VUQyA9IG9ialRvTG9jYWxUUyh7XG4gICAgICB5ZWFyLFxuICAgICAgbW9udGgsXG4gICAgICBkYXksXG4gICAgICBob3VyOiBhZGp1c3RlZEhvdXIsXG4gICAgICBtaW51dGUsXG4gICAgICBzZWNvbmQsXG4gICAgICBtaWxsaXNlY29uZDogMCxcbiAgICB9KTtcblxuICAgIGxldCBhc1RTID0gK2RhdGU7XG4gICAgY29uc3Qgb3ZlciA9IGFzVFMgJSAxMDAwO1xuICAgIGFzVFMgLT0gb3ZlciA+PSAwID8gb3ZlciA6IDEwMDAgKyBvdmVyO1xuICAgIHJldHVybiAoYXNVVEMgLSBhc1RTKSAvICg2MCAqIDEwMDApO1xuICB9XG5cbiAgLyoqIEBvdmVycmlkZSAqKi9cbiAgZXF1YWxzKG90aGVyWm9uZSkge1xuICAgIHJldHVybiBvdGhlclpvbmUudHlwZSA9PT0gXCJpYW5hXCIgJiYgb3RoZXJab25lLm5hbWUgPT09IHRoaXMubmFtZTtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGdldCBpc1ZhbGlkKCkge1xuICAgIHJldHVybiB0aGlzLnZhbGlkO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgaGFzTG9jYWxlV2Vla0luZm8sIGhhc1JlbGF0aXZlLCBwYWRTdGFydCwgcm91bmRUbywgdmFsaWRhdGVXZWVrU2V0dGluZ3MgfSBmcm9tIFwiLi91dGlsLmpzXCI7XG5pbXBvcnQgKiBhcyBFbmdsaXNoIGZyb20gXCIuL2VuZ2xpc2guanNcIjtcbmltcG9ydCBTZXR0aW5ncyBmcm9tIFwiLi4vc2V0dGluZ3MuanNcIjtcbmltcG9ydCBEYXRlVGltZSBmcm9tIFwiLi4vZGF0ZXRpbWUuanNcIjtcbmltcG9ydCBJQU5BWm9uZSBmcm9tIFwiLi4vem9uZXMvSUFOQVpvbmUuanNcIjtcblxuLy8gdG9kbyAtIHJlbWFwIGNhY2hpbmdcblxubGV0IGludGxMRkNhY2hlID0ge307XG5mdW5jdGlvbiBnZXRDYWNoZWRMRihsb2NTdHJpbmcsIG9wdHMgPSB7fSkge1xuICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShbbG9jU3RyaW5nLCBvcHRzXSk7XG4gIGxldCBkdGYgPSBpbnRsTEZDYWNoZVtrZXldO1xuICBpZiAoIWR0Zikge1xuICAgIGR0ZiA9IG5ldyBJbnRsLkxpc3RGb3JtYXQobG9jU3RyaW5nLCBvcHRzKTtcbiAgICBpbnRsTEZDYWNoZVtrZXldID0gZHRmO1xuICB9XG4gIHJldHVybiBkdGY7XG59XG5cbmxldCBpbnRsRFRDYWNoZSA9IHt9O1xuZnVuY3Rpb24gZ2V0Q2FjaGVkRFRGKGxvY1N0cmluZywgb3B0cyA9IHt9KSB7XG4gIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KFtsb2NTdHJpbmcsIG9wdHNdKTtcbiAgbGV0IGR0ZiA9IGludGxEVENhY2hlW2tleV07XG4gIGlmICghZHRmKSB7XG4gICAgZHRmID0gbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQobG9jU3RyaW5nLCBvcHRzKTtcbiAgICBpbnRsRFRDYWNoZVtrZXldID0gZHRmO1xuICB9XG4gIHJldHVybiBkdGY7XG59XG5cbmxldCBpbnRsTnVtQ2FjaGUgPSB7fTtcbmZ1bmN0aW9uIGdldENhY2hlZElORihsb2NTdHJpbmcsIG9wdHMgPSB7fSkge1xuICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShbbG9jU3RyaW5nLCBvcHRzXSk7XG4gIGxldCBpbmYgPSBpbnRsTnVtQ2FjaGVba2V5XTtcbiAgaWYgKCFpbmYpIHtcbiAgICBpbmYgPSBuZXcgSW50bC5OdW1iZXJGb3JtYXQobG9jU3RyaW5nLCBvcHRzKTtcbiAgICBpbnRsTnVtQ2FjaGVba2V5XSA9IGluZjtcbiAgfVxuICByZXR1cm4gaW5mO1xufVxuXG5sZXQgaW50bFJlbENhY2hlID0ge307XG5mdW5jdGlvbiBnZXRDYWNoZWRSVEYobG9jU3RyaW5nLCBvcHRzID0ge30pIHtcbiAgY29uc3QgeyBiYXNlLCAuLi5jYWNoZUtleU9wdHMgfSA9IG9wdHM7IC8vIGV4Y2x1ZGUgYGJhc2VgIGZyb20gdGhlIG9wdGlvbnNcbiAgY29uc3Qga2V5ID0gSlNPTi5zdHJpbmdpZnkoW2xvY1N0cmluZywgY2FjaGVLZXlPcHRzXSk7XG4gIGxldCBpbmYgPSBpbnRsUmVsQ2FjaGVba2V5XTtcbiAgaWYgKCFpbmYpIHtcbiAgICBpbmYgPSBuZXcgSW50bC5SZWxhdGl2ZVRpbWVGb3JtYXQobG9jU3RyaW5nLCBvcHRzKTtcbiAgICBpbnRsUmVsQ2FjaGVba2V5XSA9IGluZjtcbiAgfVxuICByZXR1cm4gaW5mO1xufVxuXG5sZXQgc3lzTG9jYWxlQ2FjaGUgPSBudWxsO1xuZnVuY3Rpb24gc3lzdGVtTG9jYWxlKCkge1xuICBpZiAoc3lzTG9jYWxlQ2FjaGUpIHtcbiAgICByZXR1cm4gc3lzTG9jYWxlQ2FjaGU7XG4gIH0gZWxzZSB7XG4gICAgc3lzTG9jYWxlQ2FjaGUgPSBuZXcgSW50bC5EYXRlVGltZUZvcm1hdCgpLnJlc29sdmVkT3B0aW9ucygpLmxvY2FsZTtcbiAgICByZXR1cm4gc3lzTG9jYWxlQ2FjaGU7XG4gIH1cbn1cblxubGV0IHdlZWtJbmZvQ2FjaGUgPSB7fTtcbmZ1bmN0aW9uIGdldENhY2hlZFdlZWtJbmZvKGxvY1N0cmluZykge1xuICBsZXQgZGF0YSA9IHdlZWtJbmZvQ2FjaGVbbG9jU3RyaW5nXTtcbiAgaWYgKCFkYXRhKSB7XG4gICAgY29uc3QgbG9jYWxlID0gbmV3IEludGwuTG9jYWxlKGxvY1N0cmluZyk7XG4gICAgLy8gYnJvd3NlcnMgY3VycmVudGx5IGltcGxlbWVudCB0aGlzIGFzIGEgcHJvcGVydHksIGJ1dCBzcGVjIHNheXMgaXQgc2hvdWxkIGJlIGEgZ2V0dGVyIGZ1bmN0aW9uXG4gICAgZGF0YSA9IFwiZ2V0V2Vla0luZm9cIiBpbiBsb2NhbGUgPyBsb2NhbGUuZ2V0V2Vla0luZm8oKSA6IGxvY2FsZS53ZWVrSW5mbztcbiAgICB3ZWVrSW5mb0NhY2hlW2xvY1N0cmluZ10gPSBkYXRhO1xuICB9XG4gIHJldHVybiBkYXRhO1xufVxuXG5mdW5jdGlvbiBwYXJzZUxvY2FsZVN0cmluZyhsb2NhbGVTdHIpIHtcbiAgLy8gSSByZWFsbHkgd2FudCB0byBhdm9pZCB3cml0aW5nIGEgQkNQIDQ3IHBhcnNlclxuICAvLyBzZWUsIGUuZy4gaHR0cHM6Ly9naXRodWIuY29tL3dvb29ybS9iY3AtNDdcbiAgLy8gSW5zdGVhZCwgd2UnbGwgZG8gdGhpczpcblxuICAvLyBhKSBpZiB0aGUgc3RyaW5nIGhhcyBubyAtdSBleHRlbnNpb25zLCBqdXN0IGxlYXZlIGl0IGFsb25lXG4gIC8vIGIpIGlmIGl0IGRvZXMsIHVzZSBJbnRsIHRvIHJlc29sdmUgZXZlcnl0aGluZ1xuICAvLyBjKSBpZiBJbnRsIGZhaWxzLCB0cnkgYWdhaW4gd2l0aG91dCB0aGUgLXVcblxuICAvLyBwcml2YXRlIHN1YnRhZ3MgYW5kIHVuaWNvZGUgc3VidGFncyBoYXZlIG9yZGVyaW5nIHJlcXVpcmVtZW50cyxcbiAgLy8gYW5kIHdlJ3JlIG5vdCBwcm9wZXJseSBwYXJzaW5nIHRoaXMsIHNvIGp1c3Qgc3RyaXAgb3V0IHRoZVxuICAvLyBwcml2YXRlIG9uZXMgaWYgdGhleSBleGlzdC5cbiAgY29uc3QgeEluZGV4ID0gbG9jYWxlU3RyLmluZGV4T2YoXCIteC1cIik7XG4gIGlmICh4SW5kZXggIT09IC0xKSB7XG4gICAgbG9jYWxlU3RyID0gbG9jYWxlU3RyLnN1YnN0cmluZygwLCB4SW5kZXgpO1xuICB9XG5cbiAgY29uc3QgdUluZGV4ID0gbG9jYWxlU3RyLmluZGV4T2YoXCItdS1cIik7XG4gIGlmICh1SW5kZXggPT09IC0xKSB7XG4gICAgcmV0dXJuIFtsb2NhbGVTdHJdO1xuICB9IGVsc2Uge1xuICAgIGxldCBvcHRpb25zO1xuICAgIGxldCBzZWxlY3RlZFN0cjtcbiAgICB0cnkge1xuICAgICAgb3B0aW9ucyA9IGdldENhY2hlZERURihsb2NhbGVTdHIpLnJlc29sdmVkT3B0aW9ucygpO1xuICAgICAgc2VsZWN0ZWRTdHIgPSBsb2NhbGVTdHI7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc3Qgc21hbGxlciA9IGxvY2FsZVN0ci5zdWJzdHJpbmcoMCwgdUluZGV4KTtcbiAgICAgIG9wdGlvbnMgPSBnZXRDYWNoZWREVEYoc21hbGxlcikucmVzb2x2ZWRPcHRpb25zKCk7XG4gICAgICBzZWxlY3RlZFN0ciA9IHNtYWxsZXI7XG4gICAgfVxuXG4gICAgY29uc3QgeyBudW1iZXJpbmdTeXN0ZW0sIGNhbGVuZGFyIH0gPSBvcHRpb25zO1xuICAgIHJldHVybiBbc2VsZWN0ZWRTdHIsIG51bWJlcmluZ1N5c3RlbSwgY2FsZW5kYXJdO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludGxDb25maWdTdHJpbmcobG9jYWxlU3RyLCBudW1iZXJpbmdTeXN0ZW0sIG91dHB1dENhbGVuZGFyKSB7XG4gIGlmIChvdXRwdXRDYWxlbmRhciB8fCBudW1iZXJpbmdTeXN0ZW0pIHtcbiAgICBpZiAoIWxvY2FsZVN0ci5pbmNsdWRlcyhcIi11LVwiKSkge1xuICAgICAgbG9jYWxlU3RyICs9IFwiLXVcIjtcbiAgICB9XG5cbiAgICBpZiAob3V0cHV0Q2FsZW5kYXIpIHtcbiAgICAgIGxvY2FsZVN0ciArPSBgLWNhLSR7b3V0cHV0Q2FsZW5kYXJ9YDtcbiAgICB9XG5cbiAgICBpZiAobnVtYmVyaW5nU3lzdGVtKSB7XG4gICAgICBsb2NhbGVTdHIgKz0gYC1udS0ke251bWJlcmluZ1N5c3RlbX1gO1xuICAgIH1cbiAgICByZXR1cm4gbG9jYWxlU3RyO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsb2NhbGVTdHI7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFwTW9udGhzKGYpIHtcbiAgY29uc3QgbXMgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPD0gMTI7IGkrKykge1xuICAgIGNvbnN0IGR0ID0gRGF0ZVRpbWUudXRjKDIwMDksIGksIDEpO1xuICAgIG1zLnB1c2goZihkdCkpO1xuICB9XG4gIHJldHVybiBtcztcbn1cblxuZnVuY3Rpb24gbWFwV2Vla2RheXMoZikge1xuICBjb25zdCBtcyA9IFtdO1xuICBmb3IgKGxldCBpID0gMTsgaSA8PSA3OyBpKyspIHtcbiAgICBjb25zdCBkdCA9IERhdGVUaW1lLnV0YygyMDE2LCAxMSwgMTMgKyBpKTtcbiAgICBtcy5wdXNoKGYoZHQpKTtcbiAgfVxuICByZXR1cm4gbXM7XG59XG5cbmZ1bmN0aW9uIGxpc3RTdHVmZihsb2MsIGxlbmd0aCwgZW5nbGlzaEZuLCBpbnRsRm4pIHtcbiAgY29uc3QgbW9kZSA9IGxvYy5saXN0aW5nTW9kZSgpO1xuXG4gIGlmIChtb2RlID09PSBcImVycm9yXCIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSBlbHNlIGlmIChtb2RlID09PSBcImVuXCIpIHtcbiAgICByZXR1cm4gZW5nbGlzaEZuKGxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGludGxGbihsZW5ndGgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN1cHBvcnRzRmFzdE51bWJlcnMobG9jKSB7XG4gIGlmIChsb2MubnVtYmVyaW5nU3lzdGVtICYmIGxvYy5udW1iZXJpbmdTeXN0ZW0gIT09IFwibGF0blwiKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAoXG4gICAgICBsb2MubnVtYmVyaW5nU3lzdGVtID09PSBcImxhdG5cIiB8fFxuICAgICAgIWxvYy5sb2NhbGUgfHxcbiAgICAgIGxvYy5sb2NhbGUuc3RhcnRzV2l0aChcImVuXCIpIHx8XG4gICAgICBuZXcgSW50bC5EYXRlVGltZUZvcm1hdChsb2MuaW50bCkucmVzb2x2ZWRPcHRpb25zKCkubnVtYmVyaW5nU3lzdGVtID09PSBcImxhdG5cIlxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cbmNsYXNzIFBvbHlOdW1iZXJGb3JtYXR0ZXIge1xuICBjb25zdHJ1Y3RvcihpbnRsLCBmb3JjZVNpbXBsZSwgb3B0cykge1xuICAgIHRoaXMucGFkVG8gPSBvcHRzLnBhZFRvIHx8IDA7XG4gICAgdGhpcy5mbG9vciA9IG9wdHMuZmxvb3IgfHwgZmFsc2U7XG5cbiAgICBjb25zdCB7IHBhZFRvLCBmbG9vciwgLi4ub3RoZXJPcHRzIH0gPSBvcHRzO1xuXG4gICAgaWYgKCFmb3JjZVNpbXBsZSB8fCBPYmplY3Qua2V5cyhvdGhlck9wdHMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGludGxPcHRzID0geyB1c2VHcm91cGluZzogZmFsc2UsIC4uLm9wdHMgfTtcbiAgICAgIGlmIChvcHRzLnBhZFRvID4gMCkgaW50bE9wdHMubWluaW11bUludGVnZXJEaWdpdHMgPSBvcHRzLnBhZFRvO1xuICAgICAgdGhpcy5pbmYgPSBnZXRDYWNoZWRJTkYoaW50bCwgaW50bE9wdHMpO1xuICAgIH1cbiAgfVxuXG4gIGZvcm1hdChpKSB7XG4gICAgaWYgKHRoaXMuaW5mKSB7XG4gICAgICBjb25zdCBmaXhlZCA9IHRoaXMuZmxvb3IgPyBNYXRoLmZsb29yKGkpIDogaTtcbiAgICAgIHJldHVybiB0aGlzLmluZi5mb3JtYXQoZml4ZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyB0byBtYXRjaCB0aGUgYnJvd3NlcidzIG51bWJlcmZvcm1hdHRlciBkZWZhdWx0c1xuICAgICAgY29uc3QgZml4ZWQgPSB0aGlzLmZsb29yID8gTWF0aC5mbG9vcihpKSA6IHJvdW5kVG8oaSwgMyk7XG4gICAgICByZXR1cm4gcGFkU3RhcnQoZml4ZWQsIHRoaXMucGFkVG8pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cblxuY2xhc3MgUG9seURhdGVGb3JtYXR0ZXIge1xuICBjb25zdHJ1Y3RvcihkdCwgaW50bCwgb3B0cykge1xuICAgIHRoaXMub3B0cyA9IG9wdHM7XG4gICAgdGhpcy5vcmlnaW5hbFpvbmUgPSB1bmRlZmluZWQ7XG5cbiAgICBsZXQgeiA9IHVuZGVmaW5lZDtcbiAgICBpZiAodGhpcy5vcHRzLnRpbWVab25lKSB7XG4gICAgICAvLyBEb24ndCBhcHBseSBhbnkgd29ya2Fyb3VuZHMgaWYgYSB0aW1lWm9uZSBpcyBleHBsaWNpdGx5IHByb3ZpZGVkIGluIG9wdHNcbiAgICAgIHRoaXMuZHQgPSBkdDtcbiAgICB9IGVsc2UgaWYgKGR0LnpvbmUudHlwZSA9PT0gXCJmaXhlZFwiKSB7XG4gICAgICAvLyBVVEMtOCBvciBFdGMvVVRDLTggYXJlIG5vdCBwYXJ0IG9mIHR6ZGF0YSwgb25seSBFdGMvR01UKzggYW5kIHRoZSBsaWtlLlxuICAgICAgLy8gVGhhdCBpcyB3aHkgZml4ZWQtb2Zmc2V0IFRaIGlzIHNldCB0byB0aGF0IHVubGVzcyBpdCBpczpcbiAgICAgIC8vIDEuIFJlcHJlc2VudGluZyBvZmZzZXQgMCB3aGVuIFVUQyBpcyB1c2VkIHRvIG1haW50YWluIHByZXZpb3VzIGJlaGF2aW9yIGFuZCBkb2VzIG5vdCBiZWNvbWUgR01ULlxuICAgICAgLy8gMi4gVW5zdXBwb3J0ZWQgYnkgdGhlIGJyb3dzZXI6XG4gICAgICAvLyAgICAtIHNvbWUgZG8gbm90IHN1cHBvcnQgRXRjL1xuICAgICAgLy8gICAgLSA8IEV0Yy9HTVQtMTQsID4gRXRjL0dNVCsxMiwgYW5kIDMwLW1pbnV0ZSBvciA0NS1taW51dGUgb2Zmc2V0cyBhcmUgbm90IHBhcnQgb2YgdHpkYXRhXG4gICAgICBjb25zdCBnbXRPZmZzZXQgPSAtMSAqIChkdC5vZmZzZXQgLyA2MCk7XG4gICAgICBjb25zdCBvZmZzZXRaID0gZ210T2Zmc2V0ID49IDAgPyBgRXRjL0dNVCske2dtdE9mZnNldH1gIDogYEV0Yy9HTVQke2dtdE9mZnNldH1gO1xuICAgICAgaWYgKGR0Lm9mZnNldCAhPT0gMCAmJiBJQU5BWm9uZS5jcmVhdGUob2Zmc2V0WikudmFsaWQpIHtcbiAgICAgICAgeiA9IG9mZnNldFo7XG4gICAgICAgIHRoaXMuZHQgPSBkdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE5vdCBhbGwgZml4ZWQtb2Zmc2V0IHpvbmVzIGxpa2UgRXRjLys0OjMwIGFyZSBwcmVzZW50IGluIHR6ZGF0YSBzb1xuICAgICAgICAvLyB3ZSBtYW51YWxseSBhcHBseSB0aGUgb2Zmc2V0IGFuZCBzdWJzdGl0dXRlIHRoZSB6b25lIGFzIG5lZWRlZC5cbiAgICAgICAgeiA9IFwiVVRDXCI7XG4gICAgICAgIHRoaXMuZHQgPSBkdC5vZmZzZXQgPT09IDAgPyBkdCA6IGR0LnNldFpvbmUoXCJVVENcIikucGx1cyh7IG1pbnV0ZXM6IGR0Lm9mZnNldCB9KTtcbiAgICAgICAgdGhpcy5vcmlnaW5hbFpvbmUgPSBkdC56b25lO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZHQuem9uZS50eXBlID09PSBcInN5c3RlbVwiKSB7XG4gICAgICB0aGlzLmR0ID0gZHQ7XG4gICAgfSBlbHNlIGlmIChkdC56b25lLnR5cGUgPT09IFwiaWFuYVwiKSB7XG4gICAgICB0aGlzLmR0ID0gZHQ7XG4gICAgICB6ID0gZHQuem9uZS5uYW1lO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDdXN0b20gem9uZXMgY2FuIGhhdmUgYW55IG9mZnNldCAvIG9mZnNldE5hbWUgc28gd2UganVzdCBtYW51YWxseVxuICAgICAgLy8gYXBwbHkgdGhlIG9mZnNldCBhbmQgc3Vic3RpdHV0ZSB0aGUgem9uZSBhcyBuZWVkZWQuXG4gICAgICB6ID0gXCJVVENcIjtcbiAgICAgIHRoaXMuZHQgPSBkdC5zZXRab25lKFwiVVRDXCIpLnBsdXMoeyBtaW51dGVzOiBkdC5vZmZzZXQgfSk7XG4gICAgICB0aGlzLm9yaWdpbmFsWm9uZSA9IGR0LnpvbmU7XG4gICAgfVxuXG4gICAgY29uc3QgaW50bE9wdHMgPSB7IC4uLnRoaXMub3B0cyB9O1xuICAgIGludGxPcHRzLnRpbWVab25lID0gaW50bE9wdHMudGltZVpvbmUgfHwgejtcbiAgICB0aGlzLmR0ZiA9IGdldENhY2hlZERURihpbnRsLCBpbnRsT3B0cyk7XG4gIH1cblxuICBmb3JtYXQoKSB7XG4gICAgaWYgKHRoaXMub3JpZ2luYWxab25lKSB7XG4gICAgICAvLyBJZiB3ZSBoYXZlIHRvIHN1YnN0aXR1dGUgaW4gdGhlIGFjdHVhbCB6b25lIG5hbWUsIHdlIGhhdmUgdG8gdXNlXG4gICAgICAvLyBmb3JtYXRUb1BhcnRzIHNvIHRoYXQgdGhlIHRpbWV6b25lIGNhbiBiZSByZXBsYWNlZC5cbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdFRvUGFydHMoKVxuICAgICAgICAubWFwKCh7IHZhbHVlIH0pID0+IHZhbHVlKVxuICAgICAgICAuam9pbihcIlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZHRmLmZvcm1hdCh0aGlzLmR0LnRvSlNEYXRlKCkpO1xuICB9XG5cbiAgZm9ybWF0VG9QYXJ0cygpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMuZHRmLmZvcm1hdFRvUGFydHModGhpcy5kdC50b0pTRGF0ZSgpKTtcbiAgICBpZiAodGhpcy5vcmlnaW5hbFpvbmUpIHtcbiAgICAgIHJldHVybiBwYXJ0cy5tYXAoKHBhcnQpID0+IHtcbiAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gXCJ0aW1lWm9uZU5hbWVcIikge1xuICAgICAgICAgIGNvbnN0IG9mZnNldE5hbWUgPSB0aGlzLm9yaWdpbmFsWm9uZS5vZmZzZXROYW1lKHRoaXMuZHQudHMsIHtcbiAgICAgICAgICAgIGxvY2FsZTogdGhpcy5kdC5sb2NhbGUsXG4gICAgICAgICAgICBmb3JtYXQ6IHRoaXMub3B0cy50aW1lWm9uZU5hbWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLnBhcnQsXG4gICAgICAgICAgICB2YWx1ZTogb2Zmc2V0TmFtZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBwYXJ0O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnRzO1xuICB9XG5cbiAgcmVzb2x2ZWRPcHRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLmR0Zi5yZXNvbHZlZE9wdGlvbnMoKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmNsYXNzIFBvbHlSZWxGb3JtYXR0ZXIge1xuICBjb25zdHJ1Y3RvcihpbnRsLCBpc0VuZ2xpc2gsIG9wdHMpIHtcbiAgICB0aGlzLm9wdHMgPSB7IHN0eWxlOiBcImxvbmdcIiwgLi4ub3B0cyB9O1xuICAgIGlmICghaXNFbmdsaXNoICYmIGhhc1JlbGF0aXZlKCkpIHtcbiAgICAgIHRoaXMucnRmID0gZ2V0Q2FjaGVkUlRGKGludGwsIG9wdHMpO1xuICAgIH1cbiAgfVxuXG4gIGZvcm1hdChjb3VudCwgdW5pdCkge1xuICAgIGlmICh0aGlzLnJ0Zikge1xuICAgICAgcmV0dXJuIHRoaXMucnRmLmZvcm1hdChjb3VudCwgdW5pdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBFbmdsaXNoLmZvcm1hdFJlbGF0aXZlVGltZSh1bml0LCBjb3VudCwgdGhpcy5vcHRzLm51bWVyaWMsIHRoaXMub3B0cy5zdHlsZSAhPT0gXCJsb25nXCIpO1xuICAgIH1cbiAgfVxuXG4gIGZvcm1hdFRvUGFydHMoY291bnQsIHVuaXQpIHtcbiAgICBpZiAodGhpcy5ydGYpIHtcbiAgICAgIHJldHVybiB0aGlzLnJ0Zi5mb3JtYXRUb1BhcnRzKGNvdW50LCB1bml0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfVxufVxuXG5jb25zdCBmYWxsYmFja1dlZWtTZXR0aW5ncyA9IHtcbiAgZmlyc3REYXk6IDEsXG4gIG1pbmltYWxEYXlzOiA0LFxuICB3ZWVrZW5kOiBbNiwgN10sXG59O1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTG9jYWxlIHtcbiAgc3RhdGljIGZyb21PcHRzKG9wdHMpIHtcbiAgICByZXR1cm4gTG9jYWxlLmNyZWF0ZShcbiAgICAgIG9wdHMubG9jYWxlLFxuICAgICAgb3B0cy5udW1iZXJpbmdTeXN0ZW0sXG4gICAgICBvcHRzLm91dHB1dENhbGVuZGFyLFxuICAgICAgb3B0cy53ZWVrU2V0dGluZ3MsXG4gICAgICBvcHRzLmRlZmF1bHRUb0VOXG4gICAgKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGUobG9jYWxlLCBudW1iZXJpbmdTeXN0ZW0sIG91dHB1dENhbGVuZGFyLCB3ZWVrU2V0dGluZ3MsIGRlZmF1bHRUb0VOID0gZmFsc2UpIHtcbiAgICBjb25zdCBzcGVjaWZpZWRMb2NhbGUgPSBsb2NhbGUgfHwgU2V0dGluZ3MuZGVmYXVsdExvY2FsZTtcbiAgICAvLyB0aGUgc3lzdGVtIGxvY2FsZSBpcyB1c2VmdWwgZm9yIGh1bWFuIHJlYWRhYmxlIHN0cmluZ3MgYnV0IGFubm95aW5nIGZvciBwYXJzaW5nL2Zvcm1hdHRpbmcga25vd24gZm9ybWF0c1xuICAgIGNvbnN0IGxvY2FsZVIgPSBzcGVjaWZpZWRMb2NhbGUgfHwgKGRlZmF1bHRUb0VOID8gXCJlbi1VU1wiIDogc3lzdGVtTG9jYWxlKCkpO1xuICAgIGNvbnN0IG51bWJlcmluZ1N5c3RlbVIgPSBudW1iZXJpbmdTeXN0ZW0gfHwgU2V0dGluZ3MuZGVmYXVsdE51bWJlcmluZ1N5c3RlbTtcbiAgICBjb25zdCBvdXRwdXRDYWxlbmRhclIgPSBvdXRwdXRDYWxlbmRhciB8fCBTZXR0aW5ncy5kZWZhdWx0T3V0cHV0Q2FsZW5kYXI7XG4gICAgY29uc3Qgd2Vla1NldHRpbmdzUiA9IHZhbGlkYXRlV2Vla1NldHRpbmdzKHdlZWtTZXR0aW5ncykgfHwgU2V0dGluZ3MuZGVmYXVsdFdlZWtTZXR0aW5ncztcbiAgICByZXR1cm4gbmV3IExvY2FsZShsb2NhbGVSLCBudW1iZXJpbmdTeXN0ZW1SLCBvdXRwdXRDYWxlbmRhclIsIHdlZWtTZXR0aW5nc1IsIHNwZWNpZmllZExvY2FsZSk7XG4gIH1cblxuICBzdGF0aWMgcmVzZXRDYWNoZSgpIHtcbiAgICBzeXNMb2NhbGVDYWNoZSA9IG51bGw7XG4gICAgaW50bERUQ2FjaGUgPSB7fTtcbiAgICBpbnRsTnVtQ2FjaGUgPSB7fTtcbiAgICBpbnRsUmVsQ2FjaGUgPSB7fTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tT2JqZWN0KHsgbG9jYWxlLCBudW1iZXJpbmdTeXN0ZW0sIG91dHB1dENhbGVuZGFyLCB3ZWVrU2V0dGluZ3MgfSA9IHt9KSB7XG4gICAgcmV0dXJuIExvY2FsZS5jcmVhdGUobG9jYWxlLCBudW1iZXJpbmdTeXN0ZW0sIG91dHB1dENhbGVuZGFyLCB3ZWVrU2V0dGluZ3MpO1xuICB9XG5cbiAgY29uc3RydWN0b3IobG9jYWxlLCBudW1iZXJpbmcsIG91dHB1dENhbGVuZGFyLCB3ZWVrU2V0dGluZ3MsIHNwZWNpZmllZExvY2FsZSkge1xuICAgIGNvbnN0IFtwYXJzZWRMb2NhbGUsIHBhcnNlZE51bWJlcmluZ1N5c3RlbSwgcGFyc2VkT3V0cHV0Q2FsZW5kYXJdID0gcGFyc2VMb2NhbGVTdHJpbmcobG9jYWxlKTtcblxuICAgIHRoaXMubG9jYWxlID0gcGFyc2VkTG9jYWxlO1xuICAgIHRoaXMubnVtYmVyaW5nU3lzdGVtID0gbnVtYmVyaW5nIHx8IHBhcnNlZE51bWJlcmluZ1N5c3RlbSB8fCBudWxsO1xuICAgIHRoaXMub3V0cHV0Q2FsZW5kYXIgPSBvdXRwdXRDYWxlbmRhciB8fCBwYXJzZWRPdXRwdXRDYWxlbmRhciB8fCBudWxsO1xuICAgIHRoaXMud2Vla1NldHRpbmdzID0gd2Vla1NldHRpbmdzO1xuICAgIHRoaXMuaW50bCA9IGludGxDb25maWdTdHJpbmcodGhpcy5sb2NhbGUsIHRoaXMubnVtYmVyaW5nU3lzdGVtLCB0aGlzLm91dHB1dENhbGVuZGFyKTtcblxuICAgIHRoaXMud2Vla2RheXNDYWNoZSA9IHsgZm9ybWF0OiB7fSwgc3RhbmRhbG9uZToge30gfTtcbiAgICB0aGlzLm1vbnRoc0NhY2hlID0geyBmb3JtYXQ6IHt9LCBzdGFuZGFsb25lOiB7fSB9O1xuICAgIHRoaXMubWVyaWRpZW1DYWNoZSA9IG51bGw7XG4gICAgdGhpcy5lcmFDYWNoZSA9IHt9O1xuXG4gICAgdGhpcy5zcGVjaWZpZWRMb2NhbGUgPSBzcGVjaWZpZWRMb2NhbGU7XG4gICAgdGhpcy5mYXN0TnVtYmVyc0NhY2hlZCA9IG51bGw7XG4gIH1cblxuICBnZXQgZmFzdE51bWJlcnMoKSB7XG4gICAgaWYgKHRoaXMuZmFzdE51bWJlcnNDYWNoZWQgPT0gbnVsbCkge1xuICAgICAgdGhpcy5mYXN0TnVtYmVyc0NhY2hlZCA9IHN1cHBvcnRzRmFzdE51bWJlcnModGhpcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZmFzdE51bWJlcnNDYWNoZWQ7XG4gIH1cblxuICBsaXN0aW5nTW9kZSgpIHtcbiAgICBjb25zdCBpc0FjdHVhbGx5RW4gPSB0aGlzLmlzRW5nbGlzaCgpO1xuICAgIGNvbnN0IGhhc05vV2VpcmRuZXNzID1cbiAgICAgICh0aGlzLm51bWJlcmluZ1N5c3RlbSA9PT0gbnVsbCB8fCB0aGlzLm51bWJlcmluZ1N5c3RlbSA9PT0gXCJsYXRuXCIpICYmXG4gICAgICAodGhpcy5vdXRwdXRDYWxlbmRhciA9PT0gbnVsbCB8fCB0aGlzLm91dHB1dENhbGVuZGFyID09PSBcImdyZWdvcnlcIik7XG4gICAgcmV0dXJuIGlzQWN0dWFsbHlFbiAmJiBoYXNOb1dlaXJkbmVzcyA/IFwiZW5cIiA6IFwiaW50bFwiO1xuICB9XG5cbiAgY2xvbmUoYWx0cykge1xuICAgIGlmICghYWx0cyB8fCBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhhbHRzKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gTG9jYWxlLmNyZWF0ZShcbiAgICAgICAgYWx0cy5sb2NhbGUgfHwgdGhpcy5zcGVjaWZpZWRMb2NhbGUsXG4gICAgICAgIGFsdHMubnVtYmVyaW5nU3lzdGVtIHx8IHRoaXMubnVtYmVyaW5nU3lzdGVtLFxuICAgICAgICBhbHRzLm91dHB1dENhbGVuZGFyIHx8IHRoaXMub3V0cHV0Q2FsZW5kYXIsXG4gICAgICAgIHZhbGlkYXRlV2Vla1NldHRpbmdzKGFsdHMud2Vla1NldHRpbmdzKSB8fCB0aGlzLndlZWtTZXR0aW5ncyxcbiAgICAgICAgYWx0cy5kZWZhdWx0VG9FTiB8fCBmYWxzZVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICByZWRlZmF1bHRUb0VOKGFsdHMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKHsgLi4uYWx0cywgZGVmYXVsdFRvRU46IHRydWUgfSk7XG4gIH1cblxuICByZWRlZmF1bHRUb1N5c3RlbShhbHRzID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSh7IC4uLmFsdHMsIGRlZmF1bHRUb0VOOiBmYWxzZSB9KTtcbiAgfVxuXG4gIG1vbnRocyhsZW5ndGgsIGZvcm1hdCA9IGZhbHNlKSB7XG4gICAgcmV0dXJuIGxpc3RTdHVmZih0aGlzLCBsZW5ndGgsIEVuZ2xpc2gubW9udGhzLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbnRsID0gZm9ybWF0ID8geyBtb250aDogbGVuZ3RoLCBkYXk6IFwibnVtZXJpY1wiIH0gOiB7IG1vbnRoOiBsZW5ndGggfSxcbiAgICAgICAgZm9ybWF0U3RyID0gZm9ybWF0ID8gXCJmb3JtYXRcIiA6IFwic3RhbmRhbG9uZVwiO1xuICAgICAgaWYgKCF0aGlzLm1vbnRoc0NhY2hlW2Zvcm1hdFN0cl1bbGVuZ3RoXSkge1xuICAgICAgICB0aGlzLm1vbnRoc0NhY2hlW2Zvcm1hdFN0cl1bbGVuZ3RoXSA9IG1hcE1vbnRocygoZHQpID0+IHRoaXMuZXh0cmFjdChkdCwgaW50bCwgXCJtb250aFwiKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5tb250aHNDYWNoZVtmb3JtYXRTdHJdW2xlbmd0aF07XG4gICAgfSk7XG4gIH1cblxuICB3ZWVrZGF5cyhsZW5ndGgsIGZvcm1hdCA9IGZhbHNlKSB7XG4gICAgcmV0dXJuIGxpc3RTdHVmZih0aGlzLCBsZW5ndGgsIEVuZ2xpc2gud2Vla2RheXMsICgpID0+IHtcbiAgICAgIGNvbnN0IGludGwgPSBmb3JtYXRcbiAgICAgICAgICA/IHsgd2Vla2RheTogbGVuZ3RoLCB5ZWFyOiBcIm51bWVyaWNcIiwgbW9udGg6IFwibG9uZ1wiLCBkYXk6IFwibnVtZXJpY1wiIH1cbiAgICAgICAgICA6IHsgd2Vla2RheTogbGVuZ3RoIH0sXG4gICAgICAgIGZvcm1hdFN0ciA9IGZvcm1hdCA/IFwiZm9ybWF0XCIgOiBcInN0YW5kYWxvbmVcIjtcbiAgICAgIGlmICghdGhpcy53ZWVrZGF5c0NhY2hlW2Zvcm1hdFN0cl1bbGVuZ3RoXSkge1xuICAgICAgICB0aGlzLndlZWtkYXlzQ2FjaGVbZm9ybWF0U3RyXVtsZW5ndGhdID0gbWFwV2Vla2RheXMoKGR0KSA9PlxuICAgICAgICAgIHRoaXMuZXh0cmFjdChkdCwgaW50bCwgXCJ3ZWVrZGF5XCIpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy53ZWVrZGF5c0NhY2hlW2Zvcm1hdFN0cl1bbGVuZ3RoXTtcbiAgICB9KTtcbiAgfVxuXG4gIG1lcmlkaWVtcygpIHtcbiAgICByZXR1cm4gbGlzdFN0dWZmKFxuICAgICAgdGhpcyxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgICgpID0+IEVuZ2xpc2gubWVyaWRpZW1zLFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBJbiB0aGVvcnkgdGhlcmUgY291bGQgYmUgYXJpYml0cmFyeSBkYXkgcGVyaW9kcy4gV2UncmUgZ29ubmEgYXNzdW1lIHRoZXJlIGFyZSBleGFjdGx5IHR3b1xuICAgICAgICAvLyBmb3IgQU0gYW5kIFBNLiBUaGlzIGlzIHByb2JhYmx5IHdyb25nLCBidXQgaXQncyBtYWtlcyBwYXJzaW5nIHdheSBlYXNpZXIuXG4gICAgICAgIGlmICghdGhpcy5tZXJpZGllbUNhY2hlKSB7XG4gICAgICAgICAgY29uc3QgaW50bCA9IHsgaG91cjogXCJudW1lcmljXCIsIGhvdXJDeWNsZTogXCJoMTJcIiB9O1xuICAgICAgICAgIHRoaXMubWVyaWRpZW1DYWNoZSA9IFtEYXRlVGltZS51dGMoMjAxNiwgMTEsIDEzLCA5KSwgRGF0ZVRpbWUudXRjKDIwMTYsIDExLCAxMywgMTkpXS5tYXAoXG4gICAgICAgICAgICAoZHQpID0+IHRoaXMuZXh0cmFjdChkdCwgaW50bCwgXCJkYXlwZXJpb2RcIilcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMubWVyaWRpZW1DYWNoZTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgZXJhcyhsZW5ndGgpIHtcbiAgICByZXR1cm4gbGlzdFN0dWZmKHRoaXMsIGxlbmd0aCwgRW5nbGlzaC5lcmFzLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbnRsID0geyBlcmE6IGxlbmd0aCB9O1xuXG4gICAgICAvLyBUaGlzIGlzIHByb2JsZW1hdGljLiBEaWZmZXJlbnQgY2FsZW5kYXJzIGFyZSBnb2luZyB0byBkZWZpbmUgZXJhcyB0b3RhbGx5IGRpZmZlcmVudGx5LiBXaGF0IEkgbmVlZCBpcyB0aGUgbWluaW11bSBzZXQgb2YgZGF0ZXNcbiAgICAgIC8vIHRvIGRlZmluaXRlbHkgZW51bWVyYXRlIHRoZW0uXG4gICAgICBpZiAoIXRoaXMuZXJhQ2FjaGVbbGVuZ3RoXSkge1xuICAgICAgICB0aGlzLmVyYUNhY2hlW2xlbmd0aF0gPSBbRGF0ZVRpbWUudXRjKC00MCwgMSwgMSksIERhdGVUaW1lLnV0YygyMDE3LCAxLCAxKV0ubWFwKChkdCkgPT5cbiAgICAgICAgICB0aGlzLmV4dHJhY3QoZHQsIGludGwsIFwiZXJhXCIpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmVyYUNhY2hlW2xlbmd0aF07XG4gICAgfSk7XG4gIH1cblxuICBleHRyYWN0KGR0LCBpbnRsT3B0cywgZmllbGQpIHtcbiAgICBjb25zdCBkZiA9IHRoaXMuZHRGb3JtYXR0ZXIoZHQsIGludGxPcHRzKSxcbiAgICAgIHJlc3VsdHMgPSBkZi5mb3JtYXRUb1BhcnRzKCksXG4gICAgICBtYXRjaGluZyA9IHJlc3VsdHMuZmluZCgobSkgPT4gbS50eXBlLnRvTG93ZXJDYXNlKCkgPT09IGZpZWxkKTtcbiAgICByZXR1cm4gbWF0Y2hpbmcgPyBtYXRjaGluZy52YWx1ZSA6IG51bGw7XG4gIH1cblxuICBudW1iZXJGb3JtYXR0ZXIob3B0cyA9IHt9KSB7XG4gICAgLy8gdGhpcyBmb3JjZXNpbXBsZSBvcHRpb24gaXMgbmV2ZXIgdXNlZCAodGhlIG9ubHkgY2FsbGVyIHNob3J0LWNpcmN1aXRzIG9uIGl0LCBidXQgaXQgc2VlbXMgc2FmZXIgdG8gbGVhdmUpXG4gICAgLy8gKGluIGNvbnRyYXN0LCB0aGUgcmVzdCBvZiB0aGUgY29uZGl0aW9uIGlzIHVzZWQgaGVhdmlseSlcbiAgICByZXR1cm4gbmV3IFBvbHlOdW1iZXJGb3JtYXR0ZXIodGhpcy5pbnRsLCBvcHRzLmZvcmNlU2ltcGxlIHx8IHRoaXMuZmFzdE51bWJlcnMsIG9wdHMpO1xuICB9XG5cbiAgZHRGb3JtYXR0ZXIoZHQsIGludGxPcHRzID0ge30pIHtcbiAgICByZXR1cm4gbmV3IFBvbHlEYXRlRm9ybWF0dGVyKGR0LCB0aGlzLmludGwsIGludGxPcHRzKTtcbiAgfVxuXG4gIHJlbEZvcm1hdHRlcihvcHRzID0ge30pIHtcbiAgICByZXR1cm4gbmV3IFBvbHlSZWxGb3JtYXR0ZXIodGhpcy5pbnRsLCB0aGlzLmlzRW5nbGlzaCgpLCBvcHRzKTtcbiAgfVxuXG4gIGxpc3RGb3JtYXR0ZXIob3B0cyA9IHt9KSB7XG4gICAgcmV0dXJuIGdldENhY2hlZExGKHRoaXMuaW50bCwgb3B0cyk7XG4gIH1cblxuICBpc0VuZ2xpc2goKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMubG9jYWxlID09PSBcImVuXCIgfHxcbiAgICAgIHRoaXMubG9jYWxlLnRvTG93ZXJDYXNlKCkgPT09IFwiZW4tdXNcIiB8fFxuICAgICAgbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQodGhpcy5pbnRsKS5yZXNvbHZlZE9wdGlvbnMoKS5sb2NhbGUuc3RhcnRzV2l0aChcImVuLXVzXCIpXG4gICAgKTtcbiAgfVxuXG4gIGdldFdlZWtTZXR0aW5ncygpIHtcbiAgICBpZiAodGhpcy53ZWVrU2V0dGluZ3MpIHtcbiAgICAgIHJldHVybiB0aGlzLndlZWtTZXR0aW5ncztcbiAgICB9IGVsc2UgaWYgKCFoYXNMb2NhbGVXZWVrSW5mbygpKSB7XG4gICAgICByZXR1cm4gZmFsbGJhY2tXZWVrU2V0dGluZ3M7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBnZXRDYWNoZWRXZWVrSW5mbyh0aGlzLmxvY2FsZSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0U3RhcnRPZldlZWsoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0V2Vla1NldHRpbmdzKCkuZmlyc3REYXk7XG4gIH1cblxuICBnZXRNaW5EYXlzSW5GaXJzdFdlZWsoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0V2Vla1NldHRpbmdzKCkubWluaW1hbERheXM7XG4gIH1cblxuICBnZXRXZWVrZW5kRGF5cygpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRXZWVrU2V0dGluZ3MoKS53ZWVrZW5kO1xuICB9XG5cbiAgZXF1YWxzKG90aGVyKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMubG9jYWxlID09PSBvdGhlci5sb2NhbGUgJiZcbiAgICAgIHRoaXMubnVtYmVyaW5nU3lzdGVtID09PSBvdGhlci5udW1iZXJpbmdTeXN0ZW0gJiZcbiAgICAgIHRoaXMub3V0cHV0Q2FsZW5kYXIgPT09IG90aGVyLm91dHB1dENhbGVuZGFyXG4gICAgKTtcbiAgfVxufVxuIiwgImltcG9ydCB7IGZvcm1hdE9mZnNldCwgc2lnbmVkT2Zmc2V0IH0gZnJvbSBcIi4uL2ltcGwvdXRpbC5qc1wiO1xuaW1wb3J0IFpvbmUgZnJvbSBcIi4uL3pvbmUuanNcIjtcblxubGV0IHNpbmdsZXRvbiA9IG51bGw7XG5cbi8qKlxuICogQSB6b25lIHdpdGggYSBmaXhlZCBvZmZzZXQgKG1lYW5pbmcgbm8gRFNUKVxuICogQGltcGxlbWVudHMge1pvbmV9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZpeGVkT2Zmc2V0Wm9uZSBleHRlbmRzIFpvbmUge1xuICAvKipcbiAgICogR2V0IGEgc2luZ2xldG9uIGluc3RhbmNlIG9mIFVUQ1xuICAgKiBAcmV0dXJuIHtGaXhlZE9mZnNldFpvbmV9XG4gICAqL1xuICBzdGF0aWMgZ2V0IHV0Y0luc3RhbmNlKCkge1xuICAgIGlmIChzaW5nbGV0b24gPT09IG51bGwpIHtcbiAgICAgIHNpbmdsZXRvbiA9IG5ldyBGaXhlZE9mZnNldFpvbmUoMCk7XG4gICAgfVxuICAgIHJldHVybiBzaW5nbGV0b247XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFuIGluc3RhbmNlIHdpdGggYSBzcGVjaWZpZWQgb2Zmc2V0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgLSBUaGUgb2Zmc2V0IGluIG1pbnV0ZXNcbiAgICogQHJldHVybiB7Rml4ZWRPZmZzZXRab25lfVxuICAgKi9cbiAgc3RhdGljIGluc3RhbmNlKG9mZnNldCkge1xuICAgIHJldHVybiBvZmZzZXQgPT09IDAgPyBGaXhlZE9mZnNldFpvbmUudXRjSW5zdGFuY2UgOiBuZXcgRml4ZWRPZmZzZXRab25lKG9mZnNldCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFuIGluc3RhbmNlIG9mIEZpeGVkT2Zmc2V0Wm9uZSBmcm9tIGEgVVRDIG9mZnNldCBzdHJpbmcsIGxpa2UgXCJVVEMrNlwiXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzIC0gVGhlIG9mZnNldCBzdHJpbmcgdG8gcGFyc2VcbiAgICogQGV4YW1wbGUgRml4ZWRPZmZzZXRab25lLnBhcnNlU3BlY2lmaWVyKFwiVVRDKzZcIilcbiAgICogQGV4YW1wbGUgRml4ZWRPZmZzZXRab25lLnBhcnNlU3BlY2lmaWVyKFwiVVRDKzA2XCIpXG4gICAqIEBleGFtcGxlIEZpeGVkT2Zmc2V0Wm9uZS5wYXJzZVNwZWNpZmllcihcIlVUQy02OjAwXCIpXG4gICAqIEByZXR1cm4ge0ZpeGVkT2Zmc2V0Wm9uZX1cbiAgICovXG4gIHN0YXRpYyBwYXJzZVNwZWNpZmllcihzKSB7XG4gICAgaWYgKHMpIHtcbiAgICAgIGNvbnN0IHIgPSBzLm1hdGNoKC9edXRjKD86KFsrLV1cXGR7MSwyfSkoPzo6KFxcZHsyfSkpPyk/JC9pKTtcbiAgICAgIGlmIChyKSB7XG4gICAgICAgIHJldHVybiBuZXcgRml4ZWRPZmZzZXRab25lKHNpZ25lZE9mZnNldChyWzFdLCByWzJdKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3RydWN0b3Iob2Zmc2V0KSB7XG4gICAgc3VwZXIoKTtcbiAgICAvKiogQHByaXZhdGUgKiovXG4gICAgdGhpcy5maXhlZCA9IG9mZnNldDtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiBcImZpeGVkXCI7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBnZXQgbmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5maXhlZCA9PT0gMCA/IFwiVVRDXCIgOiBgVVRDJHtmb3JtYXRPZmZzZXQodGhpcy5maXhlZCwgXCJuYXJyb3dcIil9YDtcbiAgfVxuXG4gIGdldCBpYW5hTmFtZSgpIHtcbiAgICBpZiAodGhpcy5maXhlZCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFwiRXRjL1VUQ1wiO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYEV0Yy9HTVQke2Zvcm1hdE9mZnNldCgtdGhpcy5maXhlZCwgXCJuYXJyb3dcIil9YDtcbiAgICB9XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBvZmZzZXROYW1lKCkge1xuICAgIHJldHVybiB0aGlzLm5hbWU7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBmb3JtYXRPZmZzZXQodHMsIGZvcm1hdCkge1xuICAgIHJldHVybiBmb3JtYXRPZmZzZXQodGhpcy5maXhlZCwgZm9ybWF0KTtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGdldCBpc1VuaXZlcnNhbCgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIG9mZnNldCgpIHtcbiAgICByZXR1cm4gdGhpcy5maXhlZDtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGVxdWFscyhvdGhlclpvbmUpIHtcbiAgICByZXR1cm4gb3RoZXJab25lLnR5cGUgPT09IFwiZml4ZWRcIiAmJiBvdGhlclpvbmUuZml4ZWQgPT09IHRoaXMuZml4ZWQ7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBnZXQgaXNWYWxpZCgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuIiwgImltcG9ydCBab25lIGZyb20gXCIuLi96b25lLmpzXCI7XG5cbi8qKlxuICogQSB6b25lIHRoYXQgZmFpbGVkIHRvIHBhcnNlLiBZb3Ugc2hvdWxkIG5ldmVyIG5lZWQgdG8gaW5zdGFudGlhdGUgdGhpcy5cbiAqIEBpbXBsZW1lbnRzIHtab25lfVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJbnZhbGlkWm9uZSBleHRlbmRzIFpvbmUge1xuICBjb25zdHJ1Y3Rvcih6b25lTmFtZSkge1xuICAgIHN1cGVyKCk7XG4gICAgLyoqICBAcHJpdmF0ZSAqL1xuICAgIHRoaXMuem9uZU5hbWUgPSB6b25lTmFtZTtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiBcImludmFsaWRcIjtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGdldCBuYW1lKCkge1xuICAgIHJldHVybiB0aGlzLnpvbmVOYW1lO1xuICB9XG5cbiAgLyoqIEBvdmVycmlkZSAqKi9cbiAgZ2V0IGlzVW5pdmVyc2FsKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIG9mZnNldE5hbWUoKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBmb3JtYXRPZmZzZXQoKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBvZmZzZXQoKSB7XG4gICAgcmV0dXJuIE5hTjtcbiAgfVxuXG4gIC8qKiBAb3ZlcnJpZGUgKiovXG4gIGVxdWFscygpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKiogQG92ZXJyaWRlICoqL1xuICBnZXQgaXNWYWxpZCgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiIsICIvKipcbiAqIEBwcml2YXRlXG4gKi9cblxuaW1wb3J0IFpvbmUgZnJvbSBcIi4uL3pvbmUuanNcIjtcbmltcG9ydCBJQU5BWm9uZSBmcm9tIFwiLi4vem9uZXMvSUFOQVpvbmUuanNcIjtcbmltcG9ydCBGaXhlZE9mZnNldFpvbmUgZnJvbSBcIi4uL3pvbmVzL2ZpeGVkT2Zmc2V0Wm9uZS5qc1wiO1xuaW1wb3J0IEludmFsaWRab25lIGZyb20gXCIuLi96b25lcy9pbnZhbGlkWm9uZS5qc1wiO1xuXG5pbXBvcnQgeyBpc1VuZGVmaW5lZCwgaXNTdHJpbmcsIGlzTnVtYmVyIH0gZnJvbSBcIi4vdXRpbC5qc1wiO1xuaW1wb3J0IFN5c3RlbVpvbmUgZnJvbSBcIi4uL3pvbmVzL3N5c3RlbVpvbmUuanNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVpvbmUoaW5wdXQsIGRlZmF1bHRab25lKSB7XG4gIGxldCBvZmZzZXQ7XG4gIGlmIChpc1VuZGVmaW5lZChpbnB1dCkgfHwgaW5wdXQgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZGVmYXVsdFpvbmU7XG4gIH0gZWxzZSBpZiAoaW5wdXQgaW5zdGFuY2VvZiBab25lKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9IGVsc2UgaWYgKGlzU3RyaW5nKGlucHV0KSkge1xuICAgIGNvbnN0IGxvd2VyZWQgPSBpbnB1dC50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChsb3dlcmVkID09PSBcImRlZmF1bHRcIikgcmV0dXJuIGRlZmF1bHRab25lO1xuICAgIGVsc2UgaWYgKGxvd2VyZWQgPT09IFwibG9jYWxcIiB8fCBsb3dlcmVkID09PSBcInN5c3RlbVwiKSByZXR1cm4gU3lzdGVtWm9uZS5pbnN0YW5jZTtcbiAgICBlbHNlIGlmIChsb3dlcmVkID09PSBcInV0Y1wiIHx8IGxvd2VyZWQgPT09IFwiZ210XCIpIHJldHVybiBGaXhlZE9mZnNldFpvbmUudXRjSW5zdGFuY2U7XG4gICAgZWxzZSByZXR1cm4gRml4ZWRPZmZzZXRab25lLnBhcnNlU3BlY2lmaWVyKGxvd2VyZWQpIHx8IElBTkFab25lLmNyZWF0ZShpbnB1dCk7XG4gIH0gZWxzZSBpZiAoaXNOdW1iZXIoaW5wdXQpKSB7XG4gICAgcmV0dXJuIEZpeGVkT2Zmc2V0Wm9uZS5pbnN0YW5jZShpbnB1dCk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGlucHV0ID09PSBcIm9iamVjdFwiICYmIFwib2Zmc2V0XCIgaW4gaW5wdXQgJiYgdHlwZW9mIGlucHV0Lm9mZnNldCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgLy8gVGhpcyBpcyBkdW1iLCBidXQgdGhlIGluc3RhbmNlb2YgY2hlY2sgYWJvdmUgZG9lc24ndCBzZWVtIHRvIHJlYWxseSB3b3JrXG4gICAgLy8gc28gd2UncmUgZHVjayBjaGVja2luZyBpdFxuICAgIHJldHVybiBpbnB1dDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IEludmFsaWRab25lKGlucHV0KTtcbiAgfVxufVxuIiwgImltcG9ydCBTeXN0ZW1ab25lIGZyb20gXCIuL3pvbmVzL3N5c3RlbVpvbmUuanNcIjtcbmltcG9ydCBJQU5BWm9uZSBmcm9tIFwiLi96b25lcy9JQU5BWm9uZS5qc1wiO1xuaW1wb3J0IExvY2FsZSBmcm9tIFwiLi9pbXBsL2xvY2FsZS5qc1wiO1xuXG5pbXBvcnQgeyBub3JtYWxpemVab25lIH0gZnJvbSBcIi4vaW1wbC96b25lVXRpbC5qc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGVXZWVrU2V0dGluZ3MgfSBmcm9tIFwiLi9pbXBsL3V0aWwuanNcIjtcblxubGV0IG5vdyA9ICgpID0+IERhdGUubm93KCksXG4gIGRlZmF1bHRab25lID0gXCJzeXN0ZW1cIixcbiAgZGVmYXVsdExvY2FsZSA9IG51bGwsXG4gIGRlZmF1bHROdW1iZXJpbmdTeXN0ZW0gPSBudWxsLFxuICBkZWZhdWx0T3V0cHV0Q2FsZW5kYXIgPSBudWxsLFxuICB0d29EaWdpdEN1dG9mZlllYXIgPSA2MCxcbiAgdGhyb3dPbkludmFsaWQsXG4gIGRlZmF1bHRXZWVrU2V0dGluZ3MgPSBudWxsO1xuXG4vKipcbiAqIFNldHRpbmdzIGNvbnRhaW5zIHN0YXRpYyBnZXR0ZXJzIGFuZCBzZXR0ZXJzIHRoYXQgY29udHJvbCBMdXhvbidzIG92ZXJhbGwgYmVoYXZpb3IuIEx1eG9uIGlzIGEgc2ltcGxlIGxpYnJhcnkgd2l0aCBmZXcgb3B0aW9ucywgYnV0IHRoZSBvbmVzIGl0IGRvZXMgaGF2ZSBsaXZlIGhlcmUuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNldHRpbmdzIHtcbiAgLyoqXG4gICAqIEdldCB0aGUgY2FsbGJhY2sgZm9yIHJldHVybmluZyB0aGUgY3VycmVudCB0aW1lc3RhbXAuXG4gICAqIEB0eXBlIHtmdW5jdGlvbn1cbiAgICovXG4gIHN0YXRpYyBnZXQgbm93KCkge1xuICAgIHJldHVybiBub3c7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBjYWxsYmFjayBmb3IgcmV0dXJuaW5nIHRoZSBjdXJyZW50IHRpbWVzdGFtcC5cbiAgICogVGhlIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gYSBudW1iZXIsIHdoaWNoIHdpbGwgYmUgaW50ZXJwcmV0ZWQgYXMgYW4gRXBvY2ggbWlsbGlzZWNvbmQgY291bnRcbiAgICogQHR5cGUge2Z1bmN0aW9ufVxuICAgKiBAZXhhbXBsZSBTZXR0aW5ncy5ub3cgPSAoKSA9PiBEYXRlLm5vdygpICsgMzAwMCAvLyBwcmV0ZW5kIGl0IGlzIDMgc2Vjb25kcyBpbiB0aGUgZnV0dXJlXG4gICAqIEBleGFtcGxlIFNldHRpbmdzLm5vdyA9ICgpID0+IDAgLy8gYWx3YXlzIHByZXRlbmQgaXQncyBKYW4gMSwgMTk3MCBhdCBtaWRuaWdodCBpbiBVVEMgdGltZVxuICAgKi9cbiAgc3RhdGljIHNldCBub3cobikge1xuICAgIG5vdyA9IG47XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBkZWZhdWx0IHRpbWUgem9uZSB0byBjcmVhdGUgRGF0ZVRpbWVzIGluLiBEb2VzIG5vdCBhZmZlY3QgZXhpc3RpbmcgaW5zdGFuY2VzLlxuICAgKiBVc2UgdGhlIHZhbHVlIFwic3lzdGVtXCIgdG8gcmVzZXQgdGhpcyB2YWx1ZSB0byB0aGUgc3lzdGVtJ3MgdGltZSB6b25lLlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgc3RhdGljIHNldCBkZWZhdWx0Wm9uZSh6b25lKSB7XG4gICAgZGVmYXVsdFpvbmUgPSB6b25lO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZGVmYXVsdCB0aW1lIHpvbmUgb2JqZWN0IGN1cnJlbnRseSB1c2VkIHRvIGNyZWF0ZSBEYXRlVGltZXMuIERvZXMgbm90IGFmZmVjdCBleGlzdGluZyBpbnN0YW5jZXMuXG4gICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIHRoZSBzeXN0ZW0ncyB0aW1lIHpvbmUgKHRoZSBvbmUgc2V0IG9uIHRoZSBtYWNoaW5lIHRoYXQgcnVucyB0aGlzIGNvZGUpLlxuICAgKiBAdHlwZSB7Wm9uZX1cbiAgICovXG4gIHN0YXRpYyBnZXQgZGVmYXVsdFpvbmUoKSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZVpvbmUoZGVmYXVsdFpvbmUsIFN5c3RlbVpvbmUuaW5zdGFuY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZGVmYXVsdCBsb2NhbGUgdG8gY3JlYXRlIERhdGVUaW1lcyB3aXRoLiBEb2VzIG5vdCBhZmZlY3QgZXhpc3RpbmcgaW5zdGFuY2VzLlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgc3RhdGljIGdldCBkZWZhdWx0TG9jYWxlKCkge1xuICAgIHJldHVybiBkZWZhdWx0TG9jYWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgZGVmYXVsdCBsb2NhbGUgdG8gY3JlYXRlIERhdGVUaW1lcyB3aXRoLiBEb2VzIG5vdCBhZmZlY3QgZXhpc3RpbmcgaW5zdGFuY2VzLlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgc3RhdGljIHNldCBkZWZhdWx0TG9jYWxlKGxvY2FsZSkge1xuICAgIGRlZmF1bHRMb2NhbGUgPSBsb2NhbGU7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBkZWZhdWx0IG51bWJlcmluZyBzeXN0ZW0gdG8gY3JlYXRlIERhdGVUaW1lcyB3aXRoLiBEb2VzIG5vdCBhZmZlY3QgZXhpc3RpbmcgaW5zdGFuY2VzLlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgc3RhdGljIGdldCBkZWZhdWx0TnVtYmVyaW5nU3lzdGVtKCkge1xuICAgIHJldHVybiBkZWZhdWx0TnVtYmVyaW5nU3lzdGVtO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgZGVmYXVsdCBudW1iZXJpbmcgc3lzdGVtIHRvIGNyZWF0ZSBEYXRlVGltZXMgd2l0aC4gRG9lcyBub3QgYWZmZWN0IGV4aXN0aW5nIGluc3RhbmNlcy5cbiAgICogQHR5cGUge3N0cmluZ31cbiAgICovXG4gIHN0YXRpYyBzZXQgZGVmYXVsdE51bWJlcmluZ1N5c3RlbShudW1iZXJpbmdTeXN0ZW0pIHtcbiAgICBkZWZhdWx0TnVtYmVyaW5nU3lzdGVtID0gbnVtYmVyaW5nU3lzdGVtO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZGVmYXVsdCBvdXRwdXQgY2FsZW5kYXIgdG8gY3JlYXRlIERhdGVUaW1lcyB3aXRoLiBEb2VzIG5vdCBhZmZlY3QgZXhpc3RpbmcgaW5zdGFuY2VzLlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgc3RhdGljIGdldCBkZWZhdWx0T3V0cHV0Q2FsZW5kYXIoKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRPdXRwdXRDYWxlbmRhcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGRlZmF1bHQgb3V0cHV0IGNhbGVuZGFyIHRvIGNyZWF0ZSBEYXRlVGltZXMgd2l0aC4gRG9lcyBub3QgYWZmZWN0IGV4aXN0aW5nIGluc3RhbmNlcy5cbiAgICogQHR5cGUge3N0cmluZ31cbiAgICovXG4gIHN0YXRpYyBzZXQgZGVmYXVsdE91dHB1dENhbGVuZGFyKG91dHB1dENhbGVuZGFyKSB7XG4gICAgZGVmYXVsdE91dHB1dENhbGVuZGFyID0gb3V0cHV0Q2FsZW5kYXI7XG4gIH1cblxuICAvKipcbiAgICogQHR5cGVkZWYge09iamVjdH0gV2Vla1NldHRpbmdzXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBmaXJzdERheVxuICAgKiBAcHJvcGVydHkge251bWJlcn0gbWluaW1hbERheXNcbiAgICogQHByb3BlcnR5IHtudW1iZXJbXX0gd2Vla2VuZFxuICAgKi9cblxuICAvKipcbiAgICogQHJldHVybiB7V2Vla1NldHRpbmdzfG51bGx9XG4gICAqL1xuICBzdGF0aWMgZ2V0IGRlZmF1bHRXZWVrU2V0dGluZ3MoKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRXZWVrU2V0dGluZ3M7XG4gIH1cblxuICAvKipcbiAgICogQWxsb3dzIG92ZXJyaWRpbmcgdGhlIGRlZmF1bHQgbG9jYWxlIHdlZWsgc2V0dGluZ3MsIGkuZS4gdGhlIHN0YXJ0IG9mIHRoZSB3ZWVrLCB0aGUgd2Vla2VuZCBhbmRcbiAgICogaG93IG1hbnkgZGF5cyBhcmUgcmVxdWlyZWQgaW4gdGhlIGZpcnN0IHdlZWsgb2YgYSB5ZWFyLlxuICAgKiBEb2VzIG5vdCBhZmZlY3QgZXhpc3RpbmcgaW5zdGFuY2VzLlxuICAgKlxuICAgKiBAcGFyYW0ge1dlZWtTZXR0aW5nc3xudWxsfSB3ZWVrU2V0dGluZ3NcbiAgICovXG4gIHN0YXRpYyBzZXQgZGVmYXVsdFdlZWtTZXR0aW5ncyh3ZWVrU2V0dGluZ3MpIHtcbiAgICBkZWZhdWx0V2Vla1NldHRpbmdzID0gdmFsaWRhdGVXZWVrU2V0dGluZ3Mod2Vla1NldHRpbmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1dG9mZiB5ZWFyIGFmdGVyIHdoaWNoIGEgc3RyaW5nIGVuY29kaW5nIGEgeWVhciBhcyB0d28gZGlnaXRzIGlzIGludGVycHJldGVkIHRvIG9jY3VyIGluIHRoZSBjdXJyZW50IGNlbnR1cnkuXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBzdGF0aWMgZ2V0IHR3b0RpZ2l0Q3V0b2ZmWWVhcigpIHtcbiAgICByZXR1cm4gdHdvRGlnaXRDdXRvZmZZZWFyO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgY3V0b2ZmIHllYXIgYWZ0ZXIgd2hpY2ggYSBzdHJpbmcgZW5jb2RpbmcgYSB5ZWFyIGFzIHR3byBkaWdpdHMgaXMgaW50ZXJwcmV0ZWQgdG8gb2NjdXIgaW4gdGhlIGN1cnJlbnQgY2VudHVyeS5cbiAgICogQHR5cGUge251bWJlcn1cbiAgICogQGV4YW1wbGUgU2V0dGluZ3MudHdvRGlnaXRDdXRvZmZZZWFyID0gMCAvLyBjdXQtb2ZmIHllYXIgaXMgMCwgc28gYWxsICd5eScgYXJlIGludGVycHJldGVkIGFzIGN1cnJlbnQgY2VudHVyeVxuICAgKiBAZXhhbXBsZSBTZXR0aW5ncy50d29EaWdpdEN1dG9mZlllYXIgPSA1MCAvLyAnNDknIC0+IDE5NDk7ICc1MCcgLT4gMjA1MFxuICAgKiBAZXhhbXBsZSBTZXR0aW5ncy50d29EaWdpdEN1dG9mZlllYXIgPSAxOTUwIC8vIGludGVycHJldGVkIGFzIDUwXG4gICAqIEBleGFtcGxlIFNldHRpbmdzLnR3b0RpZ2l0Q3V0b2ZmWWVhciA9IDIwNTAgLy8gQUxTTyBpbnRlcnByZXRlZCBhcyA1MFxuICAgKi9cbiAgc3RhdGljIHNldCB0d29EaWdpdEN1dG9mZlllYXIoY3V0b2ZmWWVhcikge1xuICAgIHR3b0RpZ2l0Q3V0b2ZmWWVhciA9IGN1dG9mZlllYXIgJSAxMDA7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHdoZXRoZXIgTHV4b24gd2lsbCB0aHJvdyB3aGVuIGl0IGVuY291bnRlcnMgaW52YWxpZCBEYXRlVGltZXMsIER1cmF0aW9ucywgb3IgSW50ZXJ2YWxzXG4gICAqIEB0eXBlIHtib29sZWFufVxuICAgKi9cbiAgc3RhdGljIGdldCB0aHJvd09uSW52YWxpZCgpIHtcbiAgICByZXR1cm4gdGhyb3dPbkludmFsaWQ7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHdoZXRoZXIgTHV4b24gd2lsbCB0aHJvdyB3aGVuIGl0IGVuY291bnRlcnMgaW52YWxpZCBEYXRlVGltZXMsIER1cmF0aW9ucywgb3IgSW50ZXJ2YWxzXG4gICAqIEB0eXBlIHtib29sZWFufVxuICAgKi9cbiAgc3RhdGljIHNldCB0aHJvd09uSW52YWxpZCh0KSB7XG4gICAgdGhyb3dPbkludmFsaWQgPSB0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IEx1eG9uJ3MgZ2xvYmFsIGNhY2hlcy4gU2hvdWxkIG9ubHkgYmUgbmVjZXNzYXJ5IGluIHRlc3Rpbmcgc2NlbmFyaW9zLlxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHJlc2V0Q2FjaGVzKCkge1xuICAgIExvY2FsZS5yZXNldENhY2hlKCk7XG4gICAgSUFOQVpvbmUucmVzZXRDYWNoZSgpO1xuICB9XG59XG4iLCAiZXhwb3J0IGRlZmF1bHQgY2xhc3MgSW52YWxpZCB7XG4gIGNvbnN0cnVjdG9yKHJlYXNvbiwgZXhwbGFuYXRpb24pIHtcbiAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB0aGlzLmV4cGxhbmF0aW9uID0gZXhwbGFuYXRpb247XG4gIH1cblxuICB0b01lc3NhZ2UoKSB7XG4gICAgaWYgKHRoaXMuZXhwbGFuYXRpb24pIHtcbiAgICAgIHJldHVybiBgJHt0aGlzLnJlYXNvbn06ICR7dGhpcy5leHBsYW5hdGlvbn1gO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWFzb247XG4gICAgfVxuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgaW50ZWdlckJldHdlZW4sXG4gIGlzTGVhcFllYXIsXG4gIHRpbWVPYmplY3QsXG4gIGRheXNJblllYXIsXG4gIGRheXNJbk1vbnRoLFxuICB3ZWVrc0luV2Vla1llYXIsXG4gIGlzSW50ZWdlcixcbiAgaXNVbmRlZmluZWQsXG59IGZyb20gXCIuL3V0aWwuanNcIjtcbmltcG9ydCBJbnZhbGlkIGZyb20gXCIuL2ludmFsaWQuanNcIjtcbmltcG9ydCB7IENvbmZsaWN0aW5nU3BlY2lmaWNhdGlvbkVycm9yIH0gZnJvbSBcIi4uL2Vycm9ycy5qc1wiO1xuXG5jb25zdCBub25MZWFwTGFkZGVyID0gWzAsIDMxLCA1OSwgOTAsIDEyMCwgMTUxLCAxODEsIDIxMiwgMjQzLCAyNzMsIDMwNCwgMzM0XSxcbiAgbGVhcExhZGRlciA9IFswLCAzMSwgNjAsIDkxLCAxMjEsIDE1MiwgMTgyLCAyMTMsIDI0NCwgMjc0LCAzMDUsIDMzNV07XG5cbmZ1bmN0aW9uIHVuaXRPdXRPZlJhbmdlKHVuaXQsIHZhbHVlKSB7XG4gIHJldHVybiBuZXcgSW52YWxpZChcbiAgICBcInVuaXQgb3V0IG9mIHJhbmdlXCIsXG4gICAgYHlvdSBzcGVjaWZpZWQgJHt2YWx1ZX0gKG9mIHR5cGUgJHt0eXBlb2YgdmFsdWV9KSBhcyBhICR7dW5pdH0sIHdoaWNoIGlzIGludmFsaWRgXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkYXlPZldlZWsoeWVhciwgbW9udGgsIGRheSkge1xuICBjb25zdCBkID0gbmV3IERhdGUoRGF0ZS5VVEMoeWVhciwgbW9udGggLSAxLCBkYXkpKTtcblxuICBpZiAoeWVhciA8IDEwMCAmJiB5ZWFyID49IDApIHtcbiAgICBkLnNldFVUQ0Z1bGxZZWFyKGQuZ2V0VVRDRnVsbFllYXIoKSAtIDE5MDApO1xuICB9XG5cbiAgY29uc3QganMgPSBkLmdldFVUQ0RheSgpO1xuXG4gIHJldHVybiBqcyA9PT0gMCA/IDcgOiBqcztcbn1cblxuZnVuY3Rpb24gY29tcHV0ZU9yZGluYWwoeWVhciwgbW9udGgsIGRheSkge1xuICByZXR1cm4gZGF5ICsgKGlzTGVhcFllYXIoeWVhcikgPyBsZWFwTGFkZGVyIDogbm9uTGVhcExhZGRlcilbbW9udGggLSAxXTtcbn1cblxuZnVuY3Rpb24gdW5jb21wdXRlT3JkaW5hbCh5ZWFyLCBvcmRpbmFsKSB7XG4gIGNvbnN0IHRhYmxlID0gaXNMZWFwWWVhcih5ZWFyKSA/IGxlYXBMYWRkZXIgOiBub25MZWFwTGFkZGVyLFxuICAgIG1vbnRoMCA9IHRhYmxlLmZpbmRJbmRleCgoaSkgPT4gaSA8IG9yZGluYWwpLFxuICAgIGRheSA9IG9yZGluYWwgLSB0YWJsZVttb250aDBdO1xuICByZXR1cm4geyBtb250aDogbW9udGgwICsgMSwgZGF5IH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc29XZWVrZGF5VG9Mb2NhbChpc29XZWVrZGF5LCBzdGFydE9mV2Vlaykge1xuICByZXR1cm4gKChpc29XZWVrZGF5IC0gc3RhcnRPZldlZWsgKyA3KSAlIDcpICsgMTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBncmVnb3JpYW5Ub1dlZWsoZ3JlZ09iaiwgbWluRGF5c0luRmlyc3RXZWVrID0gNCwgc3RhcnRPZldlZWsgPSAxKSB7XG4gIGNvbnN0IHsgeWVhciwgbW9udGgsIGRheSB9ID0gZ3JlZ09iaixcbiAgICBvcmRpbmFsID0gY29tcHV0ZU9yZGluYWwoeWVhciwgbW9udGgsIGRheSksXG4gICAgd2Vla2RheSA9IGlzb1dlZWtkYXlUb0xvY2FsKGRheU9mV2Vlayh5ZWFyLCBtb250aCwgZGF5KSwgc3RhcnRPZldlZWspO1xuXG4gIGxldCB3ZWVrTnVtYmVyID0gTWF0aC5mbG9vcigob3JkaW5hbCAtIHdlZWtkYXkgKyAxNCAtIG1pbkRheXNJbkZpcnN0V2VlaykgLyA3KSxcbiAgICB3ZWVrWWVhcjtcblxuICBpZiAod2Vla051bWJlciA8IDEpIHtcbiAgICB3ZWVrWWVhciA9IHllYXIgLSAxO1xuICAgIHdlZWtOdW1iZXIgPSB3ZWVrc0luV2Vla1llYXIod2Vla1llYXIsIG1pbkRheXNJbkZpcnN0V2Vlaywgc3RhcnRPZldlZWspO1xuICB9IGVsc2UgaWYgKHdlZWtOdW1iZXIgPiB3ZWVrc0luV2Vla1llYXIoeWVhciwgbWluRGF5c0luRmlyc3RXZWVrLCBzdGFydE9mV2VlaykpIHtcbiAgICB3ZWVrWWVhciA9IHllYXIgKyAxO1xuICAgIHdlZWtOdW1iZXIgPSAxO1xuICB9IGVsc2Uge1xuICAgIHdlZWtZZWFyID0geWVhcjtcbiAgfVxuXG4gIHJldHVybiB7IHdlZWtZZWFyLCB3ZWVrTnVtYmVyLCB3ZWVrZGF5LCAuLi50aW1lT2JqZWN0KGdyZWdPYmopIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3ZWVrVG9HcmVnb3JpYW4od2Vla0RhdGEsIG1pbkRheXNJbkZpcnN0V2VlayA9IDQsIHN0YXJ0T2ZXZWVrID0gMSkge1xuICBjb25zdCB7IHdlZWtZZWFyLCB3ZWVrTnVtYmVyLCB3ZWVrZGF5IH0gPSB3ZWVrRGF0YSxcbiAgICB3ZWVrZGF5T2ZKYW40ID0gaXNvV2Vla2RheVRvTG9jYWwoZGF5T2ZXZWVrKHdlZWtZZWFyLCAxLCBtaW5EYXlzSW5GaXJzdFdlZWspLCBzdGFydE9mV2VlayksXG4gICAgeWVhckluRGF5cyA9IGRheXNJblllYXIod2Vla1llYXIpO1xuXG4gIGxldCBvcmRpbmFsID0gd2Vla051bWJlciAqIDcgKyB3ZWVrZGF5IC0gd2Vla2RheU9mSmFuNCAtIDcgKyBtaW5EYXlzSW5GaXJzdFdlZWssXG4gICAgeWVhcjtcblxuICBpZiAob3JkaW5hbCA8IDEpIHtcbiAgICB5ZWFyID0gd2Vla1llYXIgLSAxO1xuICAgIG9yZGluYWwgKz0gZGF5c0luWWVhcih5ZWFyKTtcbiAgfSBlbHNlIGlmIChvcmRpbmFsID4geWVhckluRGF5cykge1xuICAgIHllYXIgPSB3ZWVrWWVhciArIDE7XG4gICAgb3JkaW5hbCAtPSBkYXlzSW5ZZWFyKHdlZWtZZWFyKTtcbiAgfSBlbHNlIHtcbiAgICB5ZWFyID0gd2Vla1llYXI7XG4gIH1cblxuICBjb25zdCB7IG1vbnRoLCBkYXkgfSA9IHVuY29tcHV0ZU9yZGluYWwoeWVhciwgb3JkaW5hbCk7XG4gIHJldHVybiB7IHllYXIsIG1vbnRoLCBkYXksIC4uLnRpbWVPYmplY3Qod2Vla0RhdGEpIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBncmVnb3JpYW5Ub09yZGluYWwoZ3JlZ0RhdGEpIHtcbiAgY29uc3QgeyB5ZWFyLCBtb250aCwgZGF5IH0gPSBncmVnRGF0YTtcbiAgY29uc3Qgb3JkaW5hbCA9IGNvbXB1dGVPcmRpbmFsKHllYXIsIG1vbnRoLCBkYXkpO1xuICByZXR1cm4geyB5ZWFyLCBvcmRpbmFsLCAuLi50aW1lT2JqZWN0KGdyZWdEYXRhKSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gb3JkaW5hbFRvR3JlZ29yaWFuKG9yZGluYWxEYXRhKSB7XG4gIGNvbnN0IHsgeWVhciwgb3JkaW5hbCB9ID0gb3JkaW5hbERhdGE7XG4gIGNvbnN0IHsgbW9udGgsIGRheSB9ID0gdW5jb21wdXRlT3JkaW5hbCh5ZWFyLCBvcmRpbmFsKTtcbiAgcmV0dXJuIHsgeWVhciwgbW9udGgsIGRheSwgLi4udGltZU9iamVjdChvcmRpbmFsRGF0YSkgfTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBsb2NhbCB3ZWVrIHVuaXRzIGxpa2UgbG9jYWxXZWVrZGF5IGFyZSB1c2VkIGluIG9iai5cbiAqIElmIHNvLCB2YWxpZGF0ZXMgdGhhdCB0aGV5IGFyZSBub3QgbWl4ZWQgd2l0aCBJU08gd2VlayB1bml0cyBhbmQgdGhlbiBjb3BpZXMgdGhlbSB0byB0aGUgbm9ybWFsIHdlZWsgdW5pdCBwcm9wZXJ0aWVzLlxuICogTW9kaWZpZXMgb2JqIGluLXBsYWNlIVxuICogQHBhcmFtIG9iaiB0aGUgb2JqZWN0IHZhbHVlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlc0xvY2FsV2Vla1ZhbHVlcyhvYmosIGxvYykge1xuICBjb25zdCBoYXNMb2NhbGVXZWVrRGF0YSA9XG4gICAgIWlzVW5kZWZpbmVkKG9iai5sb2NhbFdlZWtkYXkpIHx8XG4gICAgIWlzVW5kZWZpbmVkKG9iai5sb2NhbFdlZWtOdW1iZXIpIHx8XG4gICAgIWlzVW5kZWZpbmVkKG9iai5sb2NhbFdlZWtZZWFyKTtcbiAgaWYgKGhhc0xvY2FsZVdlZWtEYXRhKSB7XG4gICAgY29uc3QgaGFzSXNvV2Vla0RhdGEgPVxuICAgICAgIWlzVW5kZWZpbmVkKG9iai53ZWVrZGF5KSB8fCAhaXNVbmRlZmluZWQob2JqLndlZWtOdW1iZXIpIHx8ICFpc1VuZGVmaW5lZChvYmoud2Vla1llYXIpO1xuXG4gICAgaWYgKGhhc0lzb1dlZWtEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgQ29uZmxpY3RpbmdTcGVjaWZpY2F0aW9uRXJyb3IoXG4gICAgICAgIFwiQ2Fubm90IG1peCBsb2NhbGUtYmFzZWQgd2VlayBmaWVsZHMgd2l0aCBJU08tYmFzZWQgd2VlayBmaWVsZHNcIlxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKCFpc1VuZGVmaW5lZChvYmoubG9jYWxXZWVrZGF5KSkgb2JqLndlZWtkYXkgPSBvYmoubG9jYWxXZWVrZGF5O1xuICAgIGlmICghaXNVbmRlZmluZWQob2JqLmxvY2FsV2Vla051bWJlcikpIG9iai53ZWVrTnVtYmVyID0gb2JqLmxvY2FsV2Vla051bWJlcjtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKG9iai5sb2NhbFdlZWtZZWFyKSkgb2JqLndlZWtZZWFyID0gb2JqLmxvY2FsV2Vla1llYXI7XG4gICAgZGVsZXRlIG9iai5sb2NhbFdlZWtkYXk7XG4gICAgZGVsZXRlIG9iai5sb2NhbFdlZWtOdW1iZXI7XG4gICAgZGVsZXRlIG9iai5sb2NhbFdlZWtZZWFyO1xuICAgIHJldHVybiB7XG4gICAgICBtaW5EYXlzSW5GaXJzdFdlZWs6IGxvYy5nZXRNaW5EYXlzSW5GaXJzdFdlZWsoKSxcbiAgICAgIHN0YXJ0T2ZXZWVrOiBsb2MuZ2V0U3RhcnRPZldlZWsoKSxcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB7IG1pbkRheXNJbkZpcnN0V2VlazogNCwgc3RhcnRPZldlZWs6IDEgfTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzSW52YWxpZFdlZWtEYXRhKG9iaiwgbWluRGF5c0luRmlyc3RXZWVrID0gNCwgc3RhcnRPZldlZWsgPSAxKSB7XG4gIGNvbnN0IHZhbGlkWWVhciA9IGlzSW50ZWdlcihvYmoud2Vla1llYXIpLFxuICAgIHZhbGlkV2VlayA9IGludGVnZXJCZXR3ZWVuKFxuICAgICAgb2JqLndlZWtOdW1iZXIsXG4gICAgICAxLFxuICAgICAgd2Vla3NJbldlZWtZZWFyKG9iai53ZWVrWWVhciwgbWluRGF5c0luRmlyc3RXZWVrLCBzdGFydE9mV2VlaylcbiAgICApLFxuICAgIHZhbGlkV2Vla2RheSA9IGludGVnZXJCZXR3ZWVuKG9iai53ZWVrZGF5LCAxLCA3KTtcblxuICBpZiAoIXZhbGlkWWVhcikge1xuICAgIHJldHVybiB1bml0T3V0T2ZSYW5nZShcIndlZWtZZWFyXCIsIG9iai53ZWVrWWVhcik7XG4gIH0gZWxzZSBpZiAoIXZhbGlkV2Vlaykge1xuICAgIHJldHVybiB1bml0T3V0T2ZSYW5nZShcIndlZWtcIiwgb2JqLndlZWtOdW1iZXIpO1xuICB9IGVsc2UgaWYgKCF2YWxpZFdlZWtkYXkpIHtcbiAgICByZXR1cm4gdW5pdE91dE9mUmFuZ2UoXCJ3ZWVrZGF5XCIsIG9iai53ZWVrZGF5KTtcbiAgfSBlbHNlIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0ludmFsaWRPcmRpbmFsRGF0YShvYmopIHtcbiAgY29uc3QgdmFsaWRZZWFyID0gaXNJbnRlZ2VyKG9iai55ZWFyKSxcbiAgICB2YWxpZE9yZGluYWwgPSBpbnRlZ2VyQmV0d2VlbihvYmoub3JkaW5hbCwgMSwgZGF5c0luWWVhcihvYmoueWVhcikpO1xuXG4gIGlmICghdmFsaWRZZWFyKSB7XG4gICAgcmV0dXJuIHVuaXRPdXRPZlJhbmdlKFwieWVhclwiLCBvYmoueWVhcik7XG4gIH0gZWxzZSBpZiAoIXZhbGlkT3JkaW5hbCkge1xuICAgIHJldHVybiB1bml0T3V0T2ZSYW5nZShcIm9yZGluYWxcIiwgb2JqLm9yZGluYWwpO1xuICB9IGVsc2UgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzSW52YWxpZEdyZWdvcmlhbkRhdGEob2JqKSB7XG4gIGNvbnN0IHZhbGlkWWVhciA9IGlzSW50ZWdlcihvYmoueWVhciksXG4gICAgdmFsaWRNb250aCA9IGludGVnZXJCZXR3ZWVuKG9iai5tb250aCwgMSwgMTIpLFxuICAgIHZhbGlkRGF5ID0gaW50ZWdlckJldHdlZW4ob2JqLmRheSwgMSwgZGF5c0luTW9udGgob2JqLnllYXIsIG9iai5tb250aCkpO1xuXG4gIGlmICghdmFsaWRZZWFyKSB7XG4gICAgcmV0dXJuIHVuaXRPdXRPZlJhbmdlKFwieWVhclwiLCBvYmoueWVhcik7XG4gIH0gZWxzZSBpZiAoIXZhbGlkTW9udGgpIHtcbiAgICByZXR1cm4gdW5pdE91dE9mUmFuZ2UoXCJtb250aFwiLCBvYmoubW9udGgpO1xuICB9IGVsc2UgaWYgKCF2YWxpZERheSkge1xuICAgIHJldHVybiB1bml0T3V0T2ZSYW5nZShcImRheVwiLCBvYmouZGF5KTtcbiAgfSBlbHNlIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0ludmFsaWRUaW1lRGF0YShvYmopIHtcbiAgY29uc3QgeyBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmQgfSA9IG9iajtcbiAgY29uc3QgdmFsaWRIb3VyID1cbiAgICAgIGludGVnZXJCZXR3ZWVuKGhvdXIsIDAsIDIzKSB8fFxuICAgICAgKGhvdXIgPT09IDI0ICYmIG1pbnV0ZSA9PT0gMCAmJiBzZWNvbmQgPT09IDAgJiYgbWlsbGlzZWNvbmQgPT09IDApLFxuICAgIHZhbGlkTWludXRlID0gaW50ZWdlckJldHdlZW4obWludXRlLCAwLCA1OSksXG4gICAgdmFsaWRTZWNvbmQgPSBpbnRlZ2VyQmV0d2VlbihzZWNvbmQsIDAsIDU5KSxcbiAgICB2YWxpZE1pbGxpc2Vjb25kID0gaW50ZWdlckJldHdlZW4obWlsbGlzZWNvbmQsIDAsIDk5OSk7XG5cbiAgaWYgKCF2YWxpZEhvdXIpIHtcbiAgICByZXR1cm4gdW5pdE91dE9mUmFuZ2UoXCJob3VyXCIsIGhvdXIpO1xuICB9IGVsc2UgaWYgKCF2YWxpZE1pbnV0ZSkge1xuICAgIHJldHVybiB1bml0T3V0T2ZSYW5nZShcIm1pbnV0ZVwiLCBtaW51dGUpO1xuICB9IGVsc2UgaWYgKCF2YWxpZFNlY29uZCkge1xuICAgIHJldHVybiB1bml0T3V0T2ZSYW5nZShcInNlY29uZFwiLCBzZWNvbmQpO1xuICB9IGVsc2UgaWYgKCF2YWxpZE1pbGxpc2Vjb25kKSB7XG4gICAgcmV0dXJuIHVuaXRPdXRPZlJhbmdlKFwibWlsbGlzZWNvbmRcIiwgbWlsbGlzZWNvbmQpO1xuICB9IGVsc2UgcmV0dXJuIGZhbHNlO1xufVxuIiwgIi8qXG4gIFRoaXMgaXMganVzdCBhIGp1bmsgZHJhd2VyLCBjb250YWluaW5nIGFueXRoaW5nIHVzZWQgYWNyb3NzIG11bHRpcGxlIGNsYXNzZXMuXG4gIEJlY2F1c2UgTHV4b24gaXMgc21hbGwoaXNoKSwgdGhpcyBzaG91bGQgc3RheSBzbWFsbCBhbmQgd2Ugd29uJ3Qgd29ycnkgYWJvdXQgc3BsaXR0aW5nXG4gIGl0IHVwIGludG8sIHNheSwgcGFyc2luZ1V0aWwuanMgYW5kIGJhc2ljVXRpbC5qcyBhbmQgc28gb24uIEJ1dCB0aGV5IGFyZSBkaXZpZGVkIHVwIGJ5IGZlYXR1cmUgYXJlYS5cbiovXG5cbmltcG9ydCB7IEludmFsaWRBcmd1bWVudEVycm9yIH0gZnJvbSBcIi4uL2Vycm9ycy5qc1wiO1xuaW1wb3J0IFNldHRpbmdzIGZyb20gXCIuLi9zZXR0aW5ncy5qc1wiO1xuaW1wb3J0IHsgZGF5T2ZXZWVrLCBpc29XZWVrZGF5VG9Mb2NhbCB9IGZyb20gXCIuL2NvbnZlcnNpb25zLmpzXCI7XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuXG4vLyBUWVBFU1xuXG5leHBvcnQgZnVuY3Rpb24gaXNVbmRlZmluZWQobykge1xuICByZXR1cm4gdHlwZW9mIG8gPT09IFwidW5kZWZpbmVkXCI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcihvKSB7XG4gIHJldHVybiB0eXBlb2YgbyA9PT0gXCJudW1iZXJcIjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzSW50ZWdlcihvKSB7XG4gIHJldHVybiB0eXBlb2YgbyA9PT0gXCJudW1iZXJcIiAmJiBvICUgMSA9PT0gMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKG8pIHtcbiAgcmV0dXJuIHR5cGVvZiBvID09PSBcInN0cmluZ1wiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRlKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKSA9PT0gXCJbb2JqZWN0IERhdGVdXCI7XG59XG5cbi8vIENBUEFCSUxJVElFU1xuXG5leHBvcnQgZnVuY3Rpb24gaGFzUmVsYXRpdmUoKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHR5cGVvZiBJbnRsICE9PSBcInVuZGVmaW5lZFwiICYmICEhSW50bC5SZWxhdGl2ZVRpbWVGb3JtYXQ7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0xvY2FsZVdlZWtJbmZvKCkge1xuICB0cnkge1xuICAgIHJldHVybiAoXG4gICAgICB0eXBlb2YgSW50bCAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgISFJbnRsLkxvY2FsZSAmJlxuICAgICAgKFwid2Vla0luZm9cIiBpbiBJbnRsLkxvY2FsZS5wcm90b3R5cGUgfHwgXCJnZXRXZWVrSW5mb1wiIGluIEludGwuTG9jYWxlLnByb3RvdHlwZSlcbiAgICApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8vIE9CSkVDVFMgQU5EIEFSUkFZU1xuXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVBcnJheSh0aGluZykge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh0aGluZykgPyB0aGluZyA6IFt0aGluZ107XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBiZXN0QnkoYXJyLCBieSwgY29tcGFyZSkge1xuICBpZiAoYXJyLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIGFyci5yZWR1Y2UoKGJlc3QsIG5leHQpID0+IHtcbiAgICBjb25zdCBwYWlyID0gW2J5KG5leHQpLCBuZXh0XTtcbiAgICBpZiAoIWJlc3QpIHtcbiAgICAgIHJldHVybiBwYWlyO1xuICAgIH0gZWxzZSBpZiAoY29tcGFyZShiZXN0WzBdLCBwYWlyWzBdKSA9PT0gYmVzdFswXSkge1xuICAgICAgcmV0dXJuIGJlc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwYWlyO1xuICAgIH1cbiAgfSwgbnVsbClbMV07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwaWNrKG9iaiwga2V5cykge1xuICByZXR1cm4ga2V5cy5yZWR1Y2UoKGEsIGspID0+IHtcbiAgICBhW2tdID0gb2JqW2tdO1xuICAgIHJldHVybiBhO1xuICB9LCB7fSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVXZWVrU2V0dGluZ3Moc2V0dGluZ3MpIHtcbiAgaWYgKHNldHRpbmdzID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygc2V0dGluZ3MgIT09IFwib2JqZWN0XCIpIHtcbiAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3IoXCJXZWVrIHNldHRpbmdzIG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuICB9IGVsc2Uge1xuICAgIGlmIChcbiAgICAgICFpbnRlZ2VyQmV0d2VlbihzZXR0aW5ncy5maXJzdERheSwgMSwgNykgfHxcbiAgICAgICFpbnRlZ2VyQmV0d2VlbihzZXR0aW5ncy5taW5pbWFsRGF5cywgMSwgNykgfHxcbiAgICAgICFBcnJheS5pc0FycmF5KHNldHRpbmdzLndlZWtlbmQpIHx8XG4gICAgICBzZXR0aW5ncy53ZWVrZW5kLnNvbWUoKHYpID0+ICFpbnRlZ2VyQmV0d2Vlbih2LCAxLCA3KSlcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcihcIkludmFsaWQgd2VlayBzZXR0aW5nc1wiKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGZpcnN0RGF5OiBzZXR0aW5ncy5maXJzdERheSxcbiAgICAgIG1pbmltYWxEYXlzOiBzZXR0aW5ncy5taW5pbWFsRGF5cyxcbiAgICAgIHdlZWtlbmQ6IEFycmF5LmZyb20oc2V0dGluZ3Mud2Vla2VuZCksXG4gICAgfTtcbiAgfVxufVxuXG4vLyBOVU1CRVJTIEFORCBTVFJJTkdTXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnRlZ2VyQmV0d2Vlbih0aGluZywgYm90dG9tLCB0b3ApIHtcbiAgcmV0dXJuIGlzSW50ZWdlcih0aGluZykgJiYgdGhpbmcgPj0gYm90dG9tICYmIHRoaW5nIDw9IHRvcDtcbn1cblxuLy8geCAlIG4gYnV0IHRha2VzIHRoZSBzaWduIG9mIG4gaW5zdGVhZCBvZiB4XG5leHBvcnQgZnVuY3Rpb24gZmxvb3JNb2QoeCwgbikge1xuICByZXR1cm4geCAtIG4gKiBNYXRoLmZsb29yKHggLyBuKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhZFN0YXJ0KGlucHV0LCBuID0gMikge1xuICBjb25zdCBpc05lZyA9IGlucHV0IDwgMDtcbiAgbGV0IHBhZGRlZDtcbiAgaWYgKGlzTmVnKSB7XG4gICAgcGFkZGVkID0gXCItXCIgKyAoXCJcIiArIC1pbnB1dCkucGFkU3RhcnQobiwgXCIwXCIpO1xuICB9IGVsc2Uge1xuICAgIHBhZGRlZCA9IChcIlwiICsgaW5wdXQpLnBhZFN0YXJ0KG4sIFwiMFwiKTtcbiAgfVxuICByZXR1cm4gcGFkZGVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VJbnRlZ2VyKHN0cmluZykge1xuICBpZiAoaXNVbmRlZmluZWQoc3RyaW5nKSB8fCBzdHJpbmcgPT09IG51bGwgfHwgc3RyaW5nID09PSBcIlwiKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcGFyc2VJbnQoc3RyaW5nLCAxMCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRmxvYXRpbmcoc3RyaW5nKSB7XG4gIGlmIChpc1VuZGVmaW5lZChzdHJpbmcpIHx8IHN0cmluZyA9PT0gbnVsbCB8fCBzdHJpbmcgPT09IFwiXCIpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBwYXJzZUZsb2F0KHN0cmluZyk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTWlsbGlzKGZyYWN0aW9uKSB7XG4gIC8vIFJldHVybiB1bmRlZmluZWQgKGluc3RlYWQgb2YgMCkgaW4gdGhlc2UgY2FzZXMsIHdoZXJlIGZyYWN0aW9uIGlzIG5vdCBzZXRcbiAgaWYgKGlzVW5kZWZpbmVkKGZyYWN0aW9uKSB8fCBmcmFjdGlvbiA9PT0gbnVsbCB8fCBmcmFjdGlvbiA9PT0gXCJcIikge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgZiA9IHBhcnNlRmxvYXQoXCIwLlwiICsgZnJhY3Rpb24pICogMTAwMDtcbiAgICByZXR1cm4gTWF0aC5mbG9vcihmKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcm91bmRUbyhudW1iZXIsIGRpZ2l0cywgdG93YXJkWmVybyA9IGZhbHNlKSB7XG4gIGNvbnN0IGZhY3RvciA9IDEwICoqIGRpZ2l0cyxcbiAgICByb3VuZGVyID0gdG93YXJkWmVybyA/IE1hdGgudHJ1bmMgOiBNYXRoLnJvdW5kO1xuICByZXR1cm4gcm91bmRlcihudW1iZXIgKiBmYWN0b3IpIC8gZmFjdG9yO1xufVxuXG4vLyBEQVRFIEJBU0lDU1xuXG5leHBvcnQgZnVuY3Rpb24gaXNMZWFwWWVhcih5ZWFyKSB7XG4gIHJldHVybiB5ZWFyICUgNCA9PT0gMCAmJiAoeWVhciAlIDEwMCAhPT0gMCB8fCB5ZWFyICUgNDAwID09PSAwKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRheXNJblllYXIoeWVhcikge1xuICByZXR1cm4gaXNMZWFwWWVhcih5ZWFyKSA/IDM2NiA6IDM2NTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRheXNJbk1vbnRoKHllYXIsIG1vbnRoKSB7XG4gIGNvbnN0IG1vZE1vbnRoID0gZmxvb3JNb2QobW9udGggLSAxLCAxMikgKyAxLFxuICAgIG1vZFllYXIgPSB5ZWFyICsgKG1vbnRoIC0gbW9kTW9udGgpIC8gMTI7XG5cbiAgaWYgKG1vZE1vbnRoID09PSAyKSB7XG4gICAgcmV0dXJuIGlzTGVhcFllYXIobW9kWWVhcikgPyAyOSA6IDI4O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbMzEsIG51bGwsIDMxLCAzMCwgMzEsIDMwLCAzMSwgMzEsIDMwLCAzMSwgMzAsIDMxXVttb2RNb250aCAtIDFdO1xuICB9XG59XG5cbi8vIGNvbnZlcnQgYSBjYWxlbmRhciBvYmplY3QgdG8gYSBsb2NhbCB0aW1lc3RhbXAgKGVwb2NoLCBidXQgd2l0aCB0aGUgb2Zmc2V0IGJha2VkIGluKVxuZXhwb3J0IGZ1bmN0aW9uIG9ialRvTG9jYWxUUyhvYmopIHtcbiAgbGV0IGQgPSBEYXRlLlVUQyhcbiAgICBvYmoueWVhcixcbiAgICBvYmoubW9udGggLSAxLFxuICAgIG9iai5kYXksXG4gICAgb2JqLmhvdXIsXG4gICAgb2JqLm1pbnV0ZSxcbiAgICBvYmouc2Vjb25kLFxuICAgIG9iai5taWxsaXNlY29uZFxuICApO1xuXG4gIC8vIGZvciBsZWdhY3kgcmVhc29ucywgeWVhcnMgYmV0d2VlbiAwIGFuZCA5OSBhcmUgaW50ZXJwcmV0ZWQgYXMgMTlYWDsgcmV2ZXJ0IHRoYXRcbiAgaWYgKG9iai55ZWFyIDwgMTAwICYmIG9iai55ZWFyID49IDApIHtcbiAgICBkID0gbmV3IERhdGUoZCk7XG4gICAgLy8gc2V0IHRoZSBtb250aCBhbmQgZGF5IGFnYWluLCB0aGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHllYXIgMjAwMCBpcyBhIGxlYXAgeWVhciwgYnV0IHllYXIgMTAwIGlzIG5vdFxuICAgIC8vIHNvIGlmIG9iai55ZWFyIGlzIGluIDk5LCBidXQgb2JqLmRheSBtYWtlcyBpdCByb2xsIG92ZXIgaW50byB5ZWFyIDEwMCxcbiAgICAvLyB0aGUgY2FsY3VsYXRpb25zIGRvbmUgYnkgRGF0ZS5VVEMgYXJlIHVzaW5nIHllYXIgMjAwMCAtIHdoaWNoIGlzIGluY29ycmVjdFxuICAgIGQuc2V0VVRDRnVsbFllYXIob2JqLnllYXIsIG9iai5tb250aCAtIDEsIG9iai5kYXkpO1xuICB9XG4gIHJldHVybiArZDtcbn1cblxuLy8gYWRhcHRlZCBmcm9tIG1vbWVudC5qczogaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvYmxvYi8wMDBhYzE4MDBlNjIwZjc3MGY0ZWIzMWI1YWU5MDhmNjE2N2IwYWIyL3NyYy9saWIvdW5pdHMvd2Vlay1jYWxlbmRhci11dGlscy5qc1xuZnVuY3Rpb24gZmlyc3RXZWVrT2Zmc2V0KHllYXIsIG1pbkRheXNJbkZpcnN0V2Vlaywgc3RhcnRPZldlZWspIHtcbiAgY29uc3QgZndkbHcgPSBpc29XZWVrZGF5VG9Mb2NhbChkYXlPZldlZWsoeWVhciwgMSwgbWluRGF5c0luRmlyc3RXZWVrKSwgc3RhcnRPZldlZWspO1xuICByZXR1cm4gLWZ3ZGx3ICsgbWluRGF5c0luRmlyc3RXZWVrIC0gMTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdlZWtzSW5XZWVrWWVhcih3ZWVrWWVhciwgbWluRGF5c0luRmlyc3RXZWVrID0gNCwgc3RhcnRPZldlZWsgPSAxKSB7XG4gIGNvbnN0IHdlZWtPZmZzZXQgPSBmaXJzdFdlZWtPZmZzZXQod2Vla1llYXIsIG1pbkRheXNJbkZpcnN0V2Vlaywgc3RhcnRPZldlZWspO1xuICBjb25zdCB3ZWVrT2Zmc2V0TmV4dCA9IGZpcnN0V2Vla09mZnNldCh3ZWVrWWVhciArIDEsIG1pbkRheXNJbkZpcnN0V2Vlaywgc3RhcnRPZldlZWspO1xuICByZXR1cm4gKGRheXNJblllYXIod2Vla1llYXIpIC0gd2Vla09mZnNldCArIHdlZWtPZmZzZXROZXh0KSAvIDc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bnRydW5jYXRlWWVhcih5ZWFyKSB7XG4gIGlmICh5ZWFyID4gOTkpIHtcbiAgICByZXR1cm4geWVhcjtcbiAgfSBlbHNlIHJldHVybiB5ZWFyID4gU2V0dGluZ3MudHdvRGlnaXRDdXRvZmZZZWFyID8gMTkwMCArIHllYXIgOiAyMDAwICsgeWVhcjtcbn1cblxuLy8gUEFSU0lOR1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2Vab25lSW5mbyh0cywgb2Zmc2V0Rm9ybWF0LCBsb2NhbGUsIHRpbWVab25lID0gbnVsbCkge1xuICBjb25zdCBkYXRlID0gbmV3IERhdGUodHMpLFxuICAgIGludGxPcHRzID0ge1xuICAgICAgaG91ckN5Y2xlOiBcImgyM1wiLFxuICAgICAgeWVhcjogXCJudW1lcmljXCIsXG4gICAgICBtb250aDogXCIyLWRpZ2l0XCIsXG4gICAgICBkYXk6IFwiMi1kaWdpdFwiLFxuICAgICAgaG91cjogXCIyLWRpZ2l0XCIsXG4gICAgICBtaW51dGU6IFwiMi1kaWdpdFwiLFxuICAgIH07XG5cbiAgaWYgKHRpbWVab25lKSB7XG4gICAgaW50bE9wdHMudGltZVpvbmUgPSB0aW1lWm9uZTtcbiAgfVxuXG4gIGNvbnN0IG1vZGlmaWVkID0geyB0aW1lWm9uZU5hbWU6IG9mZnNldEZvcm1hdCwgLi4uaW50bE9wdHMgfTtcblxuICBjb25zdCBwYXJzZWQgPSBuZXcgSW50bC5EYXRlVGltZUZvcm1hdChsb2NhbGUsIG1vZGlmaWVkKVxuICAgIC5mb3JtYXRUb1BhcnRzKGRhdGUpXG4gICAgLmZpbmQoKG0pID0+IG0udHlwZS50b0xvd2VyQ2FzZSgpID09PSBcInRpbWV6b25lbmFtZVwiKTtcbiAgcmV0dXJuIHBhcnNlZCA/IHBhcnNlZC52YWx1ZSA6IG51bGw7XG59XG5cbi8vIHNpZ25lZE9mZnNldCgnLTUnLCAnMzAnKSAtPiAtMzMwXG5leHBvcnQgZnVuY3Rpb24gc2lnbmVkT2Zmc2V0KG9mZkhvdXJTdHIsIG9mZk1pbnV0ZVN0cikge1xuICBsZXQgb2ZmSG91ciA9IHBhcnNlSW50KG9mZkhvdXJTdHIsIDEwKTtcblxuICAvLyBkb24ndCB8fCB0aGlzIGJlY2F1c2Ugd2Ugd2FudCB0byBwcmVzZXJ2ZSAtMFxuICBpZiAoTnVtYmVyLmlzTmFOKG9mZkhvdXIpKSB7XG4gICAgb2ZmSG91ciA9IDA7XG4gIH1cblxuICBjb25zdCBvZmZNaW4gPSBwYXJzZUludChvZmZNaW51dGVTdHIsIDEwKSB8fCAwLFxuICAgIG9mZk1pblNpZ25lZCA9IG9mZkhvdXIgPCAwIHx8IE9iamVjdC5pcyhvZmZIb3VyLCAtMCkgPyAtb2ZmTWluIDogb2ZmTWluO1xuICByZXR1cm4gb2ZmSG91ciAqIDYwICsgb2ZmTWluU2lnbmVkO1xufVxuXG4vLyBDT0VSQ0lPTlxuXG5leHBvcnQgZnVuY3Rpb24gYXNOdW1iZXIodmFsdWUpIHtcbiAgY29uc3QgbnVtZXJpY1ZhbHVlID0gTnVtYmVyKHZhbHVlKTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJib29sZWFuXCIgfHwgdmFsdWUgPT09IFwiXCIgfHwgTnVtYmVyLmlzTmFOKG51bWVyaWNWYWx1ZSkpXG4gICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKGBJbnZhbGlkIHVuaXQgdmFsdWUgJHt2YWx1ZX1gKTtcbiAgcmV0dXJuIG51bWVyaWNWYWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZU9iamVjdChvYmosIG5vcm1hbGl6ZXIpIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHt9O1xuICBmb3IgKGNvbnN0IHUgaW4gb2JqKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5KG9iaiwgdSkpIHtcbiAgICAgIGNvbnN0IHYgPSBvYmpbdV07XG4gICAgICBpZiAodiA9PT0gdW5kZWZpbmVkIHx8IHYgPT09IG51bGwpIGNvbnRpbnVlO1xuICAgICAgbm9ybWFsaXplZFtub3JtYWxpemVyKHUpXSA9IGFzTnVtYmVyKHYpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbm9ybWFsaXplZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdE9mZnNldChvZmZzZXQsIGZvcm1hdCkge1xuICBjb25zdCBob3VycyA9IE1hdGgudHJ1bmMoTWF0aC5hYnMob2Zmc2V0IC8gNjApKSxcbiAgICBtaW51dGVzID0gTWF0aC50cnVuYyhNYXRoLmFicyhvZmZzZXQgJSA2MCkpLFxuICAgIHNpZ24gPSBvZmZzZXQgPj0gMCA/IFwiK1wiIDogXCItXCI7XG5cbiAgc3dpdGNoIChmb3JtYXQpIHtcbiAgICBjYXNlIFwic2hvcnRcIjpcbiAgICAgIHJldHVybiBgJHtzaWdufSR7cGFkU3RhcnQoaG91cnMsIDIpfToke3BhZFN0YXJ0KG1pbnV0ZXMsIDIpfWA7XG4gICAgY2FzZSBcIm5hcnJvd1wiOlxuICAgICAgcmV0dXJuIGAke3NpZ259JHtob3Vyc30ke21pbnV0ZXMgPiAwID8gYDoke21pbnV0ZXN9YCA6IFwiXCJ9YDtcbiAgICBjYXNlIFwidGVjaGllXCI6XG4gICAgICByZXR1cm4gYCR7c2lnbn0ke3BhZFN0YXJ0KGhvdXJzLCAyKX0ke3BhZFN0YXJ0KG1pbnV0ZXMsIDIpfWA7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBWYWx1ZSBmb3JtYXQgJHtmb3JtYXR9IGlzIG91dCBvZiByYW5nZSBmb3IgcHJvcGVydHkgZm9ybWF0YCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRpbWVPYmplY3Qob2JqKSB7XG4gIHJldHVybiBwaWNrKG9iaiwgW1wiaG91clwiLCBcIm1pbnV0ZVwiLCBcInNlY29uZFwiLCBcIm1pbGxpc2Vjb25kXCJdKTtcbn1cbiIsICJpbXBvcnQgKiBhcyBGb3JtYXRzIGZyb20gXCIuL2Zvcm1hdHMuanNcIjtcbmltcG9ydCB7IHBpY2sgfSBmcm9tIFwiLi91dGlsLmpzXCI7XG5cbmZ1bmN0aW9uIHN0cmluZ2lmeShvYmopIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG9iaiwgT2JqZWN0LmtleXMob2JqKS5zb3J0KCkpO1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cblxuZXhwb3J0IGNvbnN0IG1vbnRoc0xvbmcgPSBbXG4gIFwiSmFudWFyeVwiLFxuICBcIkZlYnJ1YXJ5XCIsXG4gIFwiTWFyY2hcIixcbiAgXCJBcHJpbFwiLFxuICBcIk1heVwiLFxuICBcIkp1bmVcIixcbiAgXCJKdWx5XCIsXG4gIFwiQXVndXN0XCIsXG4gIFwiU2VwdGVtYmVyXCIsXG4gIFwiT2N0b2JlclwiLFxuICBcIk5vdmVtYmVyXCIsXG4gIFwiRGVjZW1iZXJcIixcbl07XG5cbmV4cG9ydCBjb25zdCBtb250aHNTaG9ydCA9IFtcbiAgXCJKYW5cIixcbiAgXCJGZWJcIixcbiAgXCJNYXJcIixcbiAgXCJBcHJcIixcbiAgXCJNYXlcIixcbiAgXCJKdW5cIixcbiAgXCJKdWxcIixcbiAgXCJBdWdcIixcbiAgXCJTZXBcIixcbiAgXCJPY3RcIixcbiAgXCJOb3ZcIixcbiAgXCJEZWNcIixcbl07XG5cbmV4cG9ydCBjb25zdCBtb250aHNOYXJyb3cgPSBbXCJKXCIsIFwiRlwiLCBcIk1cIiwgXCJBXCIsIFwiTVwiLCBcIkpcIiwgXCJKXCIsIFwiQVwiLCBcIlNcIiwgXCJPXCIsIFwiTlwiLCBcIkRcIl07XG5cbmV4cG9ydCBmdW5jdGlvbiBtb250aHMobGVuZ3RoKSB7XG4gIHN3aXRjaCAobGVuZ3RoKSB7XG4gICAgY2FzZSBcIm5hcnJvd1wiOlxuICAgICAgcmV0dXJuIFsuLi5tb250aHNOYXJyb3ddO1xuICAgIGNhc2UgXCJzaG9ydFwiOlxuICAgICAgcmV0dXJuIFsuLi5tb250aHNTaG9ydF07XG4gICAgY2FzZSBcImxvbmdcIjpcbiAgICAgIHJldHVybiBbLi4ubW9udGhzTG9uZ107XG4gICAgY2FzZSBcIm51bWVyaWNcIjpcbiAgICAgIHJldHVybiBbXCIxXCIsIFwiMlwiLCBcIjNcIiwgXCI0XCIsIFwiNVwiLCBcIjZcIiwgXCI3XCIsIFwiOFwiLCBcIjlcIiwgXCIxMFwiLCBcIjExXCIsIFwiMTJcIl07XG4gICAgY2FzZSBcIjItZGlnaXRcIjpcbiAgICAgIHJldHVybiBbXCIwMVwiLCBcIjAyXCIsIFwiMDNcIiwgXCIwNFwiLCBcIjA1XCIsIFwiMDZcIiwgXCIwN1wiLCBcIjA4XCIsIFwiMDlcIiwgXCIxMFwiLCBcIjExXCIsIFwiMTJcIl07XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCB3ZWVrZGF5c0xvbmcgPSBbXG4gIFwiTW9uZGF5XCIsXG4gIFwiVHVlc2RheVwiLFxuICBcIldlZG5lc2RheVwiLFxuICBcIlRodXJzZGF5XCIsXG4gIFwiRnJpZGF5XCIsXG4gIFwiU2F0dXJkYXlcIixcbiAgXCJTdW5kYXlcIixcbl07XG5cbmV4cG9ydCBjb25zdCB3ZWVrZGF5c1Nob3J0ID0gW1wiTW9uXCIsIFwiVHVlXCIsIFwiV2VkXCIsIFwiVGh1XCIsIFwiRnJpXCIsIFwiU2F0XCIsIFwiU3VuXCJdO1xuXG5leHBvcnQgY29uc3Qgd2Vla2RheXNOYXJyb3cgPSBbXCJNXCIsIFwiVFwiLCBcIldcIiwgXCJUXCIsIFwiRlwiLCBcIlNcIiwgXCJTXCJdO1xuXG5leHBvcnQgZnVuY3Rpb24gd2Vla2RheXMobGVuZ3RoKSB7XG4gIHN3aXRjaCAobGVuZ3RoKSB7XG4gICAgY2FzZSBcIm5hcnJvd1wiOlxuICAgICAgcmV0dXJuIFsuLi53ZWVrZGF5c05hcnJvd107XG4gICAgY2FzZSBcInNob3J0XCI6XG4gICAgICByZXR1cm4gWy4uLndlZWtkYXlzU2hvcnRdO1xuICAgIGNhc2UgXCJsb25nXCI6XG4gICAgICByZXR1cm4gWy4uLndlZWtkYXlzTG9uZ107XG4gICAgY2FzZSBcIm51bWVyaWNcIjpcbiAgICAgIHJldHVybiBbXCIxXCIsIFwiMlwiLCBcIjNcIiwgXCI0XCIsIFwiNVwiLCBcIjZcIiwgXCI3XCJdO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgbWVyaWRpZW1zID0gW1wiQU1cIiwgXCJQTVwiXTtcblxuZXhwb3J0IGNvbnN0IGVyYXNMb25nID0gW1wiQmVmb3JlIENocmlzdFwiLCBcIkFubm8gRG9taW5pXCJdO1xuXG5leHBvcnQgY29uc3QgZXJhc1Nob3J0ID0gW1wiQkNcIiwgXCJBRFwiXTtcblxuZXhwb3J0IGNvbnN0IGVyYXNOYXJyb3cgPSBbXCJCXCIsIFwiQVwiXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGVyYXMobGVuZ3RoKSB7XG4gIHN3aXRjaCAobGVuZ3RoKSB7XG4gICAgY2FzZSBcIm5hcnJvd1wiOlxuICAgICAgcmV0dXJuIFsuLi5lcmFzTmFycm93XTtcbiAgICBjYXNlIFwic2hvcnRcIjpcbiAgICAgIHJldHVybiBbLi4uZXJhc1Nob3J0XTtcbiAgICBjYXNlIFwibG9uZ1wiOlxuICAgICAgcmV0dXJuIFsuLi5lcmFzTG9uZ107XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJpZGllbUZvckRhdGVUaW1lKGR0KSB7XG4gIHJldHVybiBtZXJpZGllbXNbZHQuaG91ciA8IDEyID8gMCA6IDFdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2Vla2RheUZvckRhdGVUaW1lKGR0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIHdlZWtkYXlzKGxlbmd0aClbZHQud2Vla2RheSAtIDFdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbW9udGhGb3JEYXRlVGltZShkdCwgbGVuZ3RoKSB7XG4gIHJldHVybiBtb250aHMobGVuZ3RoKVtkdC5tb250aCAtIDFdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXJhRm9yRGF0ZVRpbWUoZHQsIGxlbmd0aCkge1xuICByZXR1cm4gZXJhcyhsZW5ndGgpW2R0LnllYXIgPCAwID8gMCA6IDFdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0UmVsYXRpdmVUaW1lKHVuaXQsIGNvdW50LCBudW1lcmljID0gXCJhbHdheXNcIiwgbmFycm93ID0gZmFsc2UpIHtcbiAgY29uc3QgdW5pdHMgPSB7XG4gICAgeWVhcnM6IFtcInllYXJcIiwgXCJ5ci5cIl0sXG4gICAgcXVhcnRlcnM6IFtcInF1YXJ0ZXJcIiwgXCJxdHIuXCJdLFxuICAgIG1vbnRoczogW1wibW9udGhcIiwgXCJtby5cIl0sXG4gICAgd2Vla3M6IFtcIndlZWtcIiwgXCJ3ay5cIl0sXG4gICAgZGF5czogW1wiZGF5XCIsIFwiZGF5XCIsIFwiZGF5c1wiXSxcbiAgICBob3VyczogW1wiaG91clwiLCBcImhyLlwiXSxcbiAgICBtaW51dGVzOiBbXCJtaW51dGVcIiwgXCJtaW4uXCJdLFxuICAgIHNlY29uZHM6IFtcInNlY29uZFwiLCBcInNlYy5cIl0sXG4gIH07XG5cbiAgY29uc3QgbGFzdGFibGUgPSBbXCJob3Vyc1wiLCBcIm1pbnV0ZXNcIiwgXCJzZWNvbmRzXCJdLmluZGV4T2YodW5pdCkgPT09IC0xO1xuXG4gIGlmIChudW1lcmljID09PSBcImF1dG9cIiAmJiBsYXN0YWJsZSkge1xuICAgIGNvbnN0IGlzRGF5ID0gdW5pdCA9PT0gXCJkYXlzXCI7XG4gICAgc3dpdGNoIChjb3VudCkge1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gaXNEYXkgPyBcInRvbW9ycm93XCIgOiBgbmV4dCAke3VuaXRzW3VuaXRdWzBdfWA7XG4gICAgICBjYXNlIC0xOlxuICAgICAgICByZXR1cm4gaXNEYXkgPyBcInllc3RlcmRheVwiIDogYGxhc3QgJHt1bml0c1t1bml0XVswXX1gO1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gaXNEYXkgPyBcInRvZGF5XCIgOiBgdGhpcyAke3VuaXRzW3VuaXRdWzBdfWA7XG4gICAgICBkZWZhdWx0OiAvLyBmYWxsIHRocm91Z2hcbiAgICB9XG4gIH1cblxuICBjb25zdCBpc0luUGFzdCA9IE9iamVjdC5pcyhjb3VudCwgLTApIHx8IGNvdW50IDwgMCxcbiAgICBmbXRWYWx1ZSA9IE1hdGguYWJzKGNvdW50KSxcbiAgICBzaW5ndWxhciA9IGZtdFZhbHVlID09PSAxLFxuICAgIGxpbFVuaXRzID0gdW5pdHNbdW5pdF0sXG4gICAgZm10VW5pdCA9IG5hcnJvd1xuICAgICAgPyBzaW5ndWxhclxuICAgICAgICA/IGxpbFVuaXRzWzFdXG4gICAgICAgIDogbGlsVW5pdHNbMl0gfHwgbGlsVW5pdHNbMV1cbiAgICAgIDogc2luZ3VsYXJcbiAgICAgID8gdW5pdHNbdW5pdF1bMF1cbiAgICAgIDogdW5pdDtcbiAgcmV0dXJuIGlzSW5QYXN0ID8gYCR7Zm10VmFsdWV9ICR7Zm10VW5pdH0gYWdvYCA6IGBpbiAke2ZtdFZhbHVlfSAke2ZtdFVuaXR9YDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFN0cmluZyhrbm93bkZvcm1hdCkge1xuICAvLyB0aGVzZSBhbGwgaGF2ZSB0aGUgb2Zmc2V0cyByZW1vdmVkIGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSBhY2Nlc3MgdG8gdGhlbVxuICAvLyB3aXRob3V0IGFsbCB0aGUgaW50bCBzdHVmZiB0aGlzIGlzIGJhY2tmaWxsaW5nXG4gIGNvbnN0IGZpbHRlcmVkID0gcGljayhrbm93bkZvcm1hdCwgW1xuICAgICAgXCJ3ZWVrZGF5XCIsXG4gICAgICBcImVyYVwiLFxuICAgICAgXCJ5ZWFyXCIsXG4gICAgICBcIm1vbnRoXCIsXG4gICAgICBcImRheVwiLFxuICAgICAgXCJob3VyXCIsXG4gICAgICBcIm1pbnV0ZVwiLFxuICAgICAgXCJzZWNvbmRcIixcbiAgICAgIFwidGltZVpvbmVOYW1lXCIsXG4gICAgICBcImhvdXJDeWNsZVwiLFxuICAgIF0pLFxuICAgIGtleSA9IHN0cmluZ2lmeShmaWx0ZXJlZCksXG4gICAgZGF0ZVRpbWVIdWdlID0gXCJFRUVFLCBMTExMIGQsIHl5eXksIGg6bW0gYVwiO1xuICBzd2l0Y2ggKGtleSkge1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuREFURV9TSE9SVCk6XG4gICAgICByZXR1cm4gXCJNL2QveXl5eVwiO1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuREFURV9NRUQpOlxuICAgICAgcmV0dXJuIFwiTExMIGQsIHl5eXlcIjtcbiAgICBjYXNlIHN0cmluZ2lmeShGb3JtYXRzLkRBVEVfTUVEX1dJVEhfV0VFS0RBWSk6XG4gICAgICByZXR1cm4gXCJFRUUsIExMTCBkLCB5eXl5XCI7XG4gICAgY2FzZSBzdHJpbmdpZnkoRm9ybWF0cy5EQVRFX0ZVTEwpOlxuICAgICAgcmV0dXJuIFwiTExMTCBkLCB5eXl5XCI7XG4gICAgY2FzZSBzdHJpbmdpZnkoRm9ybWF0cy5EQVRFX0hVR0UpOlxuICAgICAgcmV0dXJuIFwiRUVFRSwgTExMTCBkLCB5eXl5XCI7XG4gICAgY2FzZSBzdHJpbmdpZnkoRm9ybWF0cy5USU1FX1NJTVBMRSk6XG4gICAgICByZXR1cm4gXCJoOm1tIGFcIjtcbiAgICBjYXNlIHN0cmluZ2lmeShGb3JtYXRzLlRJTUVfV0lUSF9TRUNPTkRTKTpcbiAgICAgIHJldHVybiBcImg6bW06c3MgYVwiO1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuVElNRV9XSVRIX1NIT1JUX09GRlNFVCk6XG4gICAgICByZXR1cm4gXCJoOm1tIGFcIjtcbiAgICBjYXNlIHN0cmluZ2lmeShGb3JtYXRzLlRJTUVfV0lUSF9MT05HX09GRlNFVCk6XG4gICAgICByZXR1cm4gXCJoOm1tIGFcIjtcbiAgICBjYXNlIHN0cmluZ2lmeShGb3JtYXRzLlRJTUVfMjRfU0lNUExFKTpcbiAgICAgIHJldHVybiBcIkhIOm1tXCI7XG4gICAgY2FzZSBzdHJpbmdpZnkoRm9ybWF0cy5USU1FXzI0X1dJVEhfU0VDT05EUyk6XG4gICAgICByZXR1cm4gXCJISDptbTpzc1wiO1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuVElNRV8yNF9XSVRIX1NIT1JUX09GRlNFVCk6XG4gICAgICByZXR1cm4gXCJISDptbVwiO1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuVElNRV8yNF9XSVRIX0xPTkdfT0ZGU0VUKTpcbiAgICAgIHJldHVybiBcIkhIOm1tXCI7XG4gICAgY2FzZSBzdHJpbmdpZnkoRm9ybWF0cy5EQVRFVElNRV9TSE9SVCk6XG4gICAgICByZXR1cm4gXCJNL2QveXl5eSwgaDptbSBhXCI7XG4gICAgY2FzZSBzdHJpbmdpZnkoRm9ybWF0cy5EQVRFVElNRV9NRUQpOlxuICAgICAgcmV0dXJuIFwiTExMIGQsIHl5eXksIGg6bW0gYVwiO1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuREFURVRJTUVfRlVMTCk6XG4gICAgICByZXR1cm4gXCJMTExMIGQsIHl5eXksIGg6bW0gYVwiO1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuREFURVRJTUVfSFVHRSk6XG4gICAgICByZXR1cm4gZGF0ZVRpbWVIdWdlO1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuREFURVRJTUVfU0hPUlRfV0lUSF9TRUNPTkRTKTpcbiAgICAgIHJldHVybiBcIk0vZC95eXl5LCBoOm1tOnNzIGFcIjtcbiAgICBjYXNlIHN0cmluZ2lmeShGb3JtYXRzLkRBVEVUSU1FX01FRF9XSVRIX1NFQ09ORFMpOlxuICAgICAgcmV0dXJuIFwiTExMIGQsIHl5eXksIGg6bW06c3MgYVwiO1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuREFURVRJTUVfTUVEX1dJVEhfV0VFS0RBWSk6XG4gICAgICByZXR1cm4gXCJFRUUsIGQgTExMIHl5eXksIGg6bW0gYVwiO1xuICAgIGNhc2Ugc3RyaW5naWZ5KEZvcm1hdHMuREFURVRJTUVfRlVMTF9XSVRIX1NFQ09ORFMpOlxuICAgICAgcmV0dXJuIFwiTExMTCBkLCB5eXl5LCBoOm1tOnNzIGFcIjtcbiAgICBjYXNlIHN0cmluZ2lmeShGb3JtYXRzLkRBVEVUSU1FX0hVR0VfV0lUSF9TRUNPTkRTKTpcbiAgICAgIHJldHVybiBcIkVFRUUsIExMTEwgZCwgeXl5eSwgaDptbTpzcyBhXCI7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBkYXRlVGltZUh1Z2U7XG4gIH1cbn1cbiIsICJpbXBvcnQgKiBhcyBFbmdsaXNoIGZyb20gXCIuL2VuZ2xpc2guanNcIjtcbmltcG9ydCAqIGFzIEZvcm1hdHMgZnJvbSBcIi4vZm9ybWF0cy5qc1wiO1xuaW1wb3J0IHsgcGFkU3RhcnQgfSBmcm9tIFwiLi91dGlsLmpzXCI7XG5cbmZ1bmN0aW9uIHN0cmluZ2lmeVRva2VucyhzcGxpdHMsIHRva2VuVG9TdHJpbmcpIHtcbiAgbGV0IHMgPSBcIlwiO1xuICBmb3IgKGNvbnN0IHRva2VuIG9mIHNwbGl0cykge1xuICAgIGlmICh0b2tlbi5saXRlcmFsKSB7XG4gICAgICBzICs9IHRva2VuLnZhbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcyArPSB0b2tlblRvU3RyaW5nKHRva2VuLnZhbCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzO1xufVxuXG5jb25zdCBtYWNyb1Rva2VuVG9Gb3JtYXRPcHRzID0ge1xuICBEOiBGb3JtYXRzLkRBVEVfU0hPUlQsXG4gIEREOiBGb3JtYXRzLkRBVEVfTUVELFxuICBEREQ6IEZvcm1hdHMuREFURV9GVUxMLFxuICBEREREOiBGb3JtYXRzLkRBVEVfSFVHRSxcbiAgdDogRm9ybWF0cy5USU1FX1NJTVBMRSxcbiAgdHQ6IEZvcm1hdHMuVElNRV9XSVRIX1NFQ09ORFMsXG4gIHR0dDogRm9ybWF0cy5USU1FX1dJVEhfU0hPUlRfT0ZGU0VULFxuICB0dHR0OiBGb3JtYXRzLlRJTUVfV0lUSF9MT05HX09GRlNFVCxcbiAgVDogRm9ybWF0cy5USU1FXzI0X1NJTVBMRSxcbiAgVFQ6IEZvcm1hdHMuVElNRV8yNF9XSVRIX1NFQ09ORFMsXG4gIFRUVDogRm9ybWF0cy5USU1FXzI0X1dJVEhfU0hPUlRfT0ZGU0VULFxuICBUVFRUOiBGb3JtYXRzLlRJTUVfMjRfV0lUSF9MT05HX09GRlNFVCxcbiAgZjogRm9ybWF0cy5EQVRFVElNRV9TSE9SVCxcbiAgZmY6IEZvcm1hdHMuREFURVRJTUVfTUVELFxuICBmZmY6IEZvcm1hdHMuREFURVRJTUVfRlVMTCxcbiAgZmZmZjogRm9ybWF0cy5EQVRFVElNRV9IVUdFLFxuICBGOiBGb3JtYXRzLkRBVEVUSU1FX1NIT1JUX1dJVEhfU0VDT05EUyxcbiAgRkY6IEZvcm1hdHMuREFURVRJTUVfTUVEX1dJVEhfU0VDT05EUyxcbiAgRkZGOiBGb3JtYXRzLkRBVEVUSU1FX0ZVTExfV0lUSF9TRUNPTkRTLFxuICBGRkZGOiBGb3JtYXRzLkRBVEVUSU1FX0hVR0VfV0lUSF9TRUNPTkRTLFxufTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZvcm1hdHRlciB7XG4gIHN0YXRpYyBjcmVhdGUobG9jYWxlLCBvcHRzID0ge30pIHtcbiAgICByZXR1cm4gbmV3IEZvcm1hdHRlcihsb2NhbGUsIG9wdHMpO1xuICB9XG5cbiAgc3RhdGljIHBhcnNlRm9ybWF0KGZtdCkge1xuICAgIC8vIHdoaXRlLXNwYWNlIGlzIGFsd2F5cyBjb25zaWRlcmVkIGEgbGl0ZXJhbCBpbiB1c2VyLXByb3ZpZGVkIGZvcm1hdHNcbiAgICAvLyB0aGUgXCIgXCIgdG9rZW4gaGFzIGEgc3BlY2lhbCBtZWFuaW5nIChzZWUgdW5pdEZvclRva2VuKVxuXG4gICAgbGV0IGN1cnJlbnQgPSBudWxsLFxuICAgICAgY3VycmVudEZ1bGwgPSBcIlwiLFxuICAgICAgYnJhY2tldGVkID0gZmFsc2U7XG4gICAgY29uc3Qgc3BsaXRzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmbXQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGMgPSBmbXQuY2hhckF0KGkpO1xuICAgICAgaWYgKGMgPT09IFwiJ1wiKSB7XG4gICAgICAgIGlmIChjdXJyZW50RnVsbC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgc3BsaXRzLnB1c2goeyBsaXRlcmFsOiBicmFja2V0ZWQgfHwgL15cXHMrJC8udGVzdChjdXJyZW50RnVsbCksIHZhbDogY3VycmVudEZ1bGwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudCA9IG51bGw7XG4gICAgICAgIGN1cnJlbnRGdWxsID0gXCJcIjtcbiAgICAgICAgYnJhY2tldGVkID0gIWJyYWNrZXRlZDtcbiAgICAgIH0gZWxzZSBpZiAoYnJhY2tldGVkKSB7XG4gICAgICAgIGN1cnJlbnRGdWxsICs9IGM7XG4gICAgICB9IGVsc2UgaWYgKGMgPT09IGN1cnJlbnQpIHtcbiAgICAgICAgY3VycmVudEZ1bGwgKz0gYztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjdXJyZW50RnVsbC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgc3BsaXRzLnB1c2goeyBsaXRlcmFsOiAvXlxccyskLy50ZXN0KGN1cnJlbnRGdWxsKSwgdmFsOiBjdXJyZW50RnVsbCB9KTtcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50RnVsbCA9IGM7XG4gICAgICAgIGN1cnJlbnQgPSBjO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjdXJyZW50RnVsbC5sZW5ndGggPiAwKSB7XG4gICAgICBzcGxpdHMucHVzaCh7IGxpdGVyYWw6IGJyYWNrZXRlZCB8fCAvXlxccyskLy50ZXN0KGN1cnJlbnRGdWxsKSwgdmFsOiBjdXJyZW50RnVsbCB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3BsaXRzO1xuICB9XG5cbiAgc3RhdGljIG1hY3JvVG9rZW5Ub0Zvcm1hdE9wdHModG9rZW4pIHtcbiAgICByZXR1cm4gbWFjcm9Ub2tlblRvRm9ybWF0T3B0c1t0b2tlbl07XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihsb2NhbGUsIGZvcm1hdE9wdHMpIHtcbiAgICB0aGlzLm9wdHMgPSBmb3JtYXRPcHRzO1xuICAgIHRoaXMubG9jID0gbG9jYWxlO1xuICAgIHRoaXMuc3lzdGVtTG9jID0gbnVsbDtcbiAgfVxuXG4gIGZvcm1hdFdpdGhTeXN0ZW1EZWZhdWx0KGR0LCBvcHRzKSB7XG4gICAgaWYgKHRoaXMuc3lzdGVtTG9jID09PSBudWxsKSB7XG4gICAgICB0aGlzLnN5c3RlbUxvYyA9IHRoaXMubG9jLnJlZGVmYXVsdFRvU3lzdGVtKCk7XG4gICAgfVxuICAgIGNvbnN0IGRmID0gdGhpcy5zeXN0ZW1Mb2MuZHRGb3JtYXR0ZXIoZHQsIHsgLi4udGhpcy5vcHRzLCAuLi5vcHRzIH0pO1xuICAgIHJldHVybiBkZi5mb3JtYXQoKTtcbiAgfVxuXG4gIGR0Rm9ybWF0dGVyKGR0LCBvcHRzID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5sb2MuZHRGb3JtYXR0ZXIoZHQsIHsgLi4udGhpcy5vcHRzLCAuLi5vcHRzIH0pO1xuICB9XG5cbiAgZm9ybWF0RGF0ZVRpbWUoZHQsIG9wdHMpIHtcbiAgICByZXR1cm4gdGhpcy5kdEZvcm1hdHRlcihkdCwgb3B0cykuZm9ybWF0KCk7XG4gIH1cblxuICBmb3JtYXREYXRlVGltZVBhcnRzKGR0LCBvcHRzKSB7XG4gICAgcmV0dXJuIHRoaXMuZHRGb3JtYXR0ZXIoZHQsIG9wdHMpLmZvcm1hdFRvUGFydHMoKTtcbiAgfVxuXG4gIGZvcm1hdEludGVydmFsKGludGVydmFsLCBvcHRzKSB7XG4gICAgY29uc3QgZGYgPSB0aGlzLmR0Rm9ybWF0dGVyKGludGVydmFsLnN0YXJ0LCBvcHRzKTtcbiAgICByZXR1cm4gZGYuZHRmLmZvcm1hdFJhbmdlKGludGVydmFsLnN0YXJ0LnRvSlNEYXRlKCksIGludGVydmFsLmVuZC50b0pTRGF0ZSgpKTtcbiAgfVxuXG4gIHJlc29sdmVkT3B0aW9ucyhkdCwgb3B0cykge1xuICAgIHJldHVybiB0aGlzLmR0Rm9ybWF0dGVyKGR0LCBvcHRzKS5yZXNvbHZlZE9wdGlvbnMoKTtcbiAgfVxuXG4gIG51bShuLCBwID0gMCkge1xuICAgIC8vIHdlIGdldCBzb21lIHBlcmYgb3V0IG9mIGRvaW5nIHRoaXMgaGVyZSwgYW5ub3lpbmdseVxuICAgIGlmICh0aGlzLm9wdHMuZm9yY2VTaW1wbGUpIHtcbiAgICAgIHJldHVybiBwYWRTdGFydChuLCBwKTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRzID0geyAuLi50aGlzLm9wdHMgfTtcblxuICAgIGlmIChwID4gMCkge1xuICAgICAgb3B0cy5wYWRUbyA9IHA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubG9jLm51bWJlckZvcm1hdHRlcihvcHRzKS5mb3JtYXQobik7XG4gIH1cblxuICBmb3JtYXREYXRlVGltZUZyb21TdHJpbmcoZHQsIGZtdCkge1xuICAgIGNvbnN0IGtub3duRW5nbGlzaCA9IHRoaXMubG9jLmxpc3RpbmdNb2RlKCkgPT09IFwiZW5cIixcbiAgICAgIHVzZURhdGVUaW1lRm9ybWF0dGVyID0gdGhpcy5sb2Mub3V0cHV0Q2FsZW5kYXIgJiYgdGhpcy5sb2Mub3V0cHV0Q2FsZW5kYXIgIT09IFwiZ3JlZ29yeVwiLFxuICAgICAgc3RyaW5nID0gKG9wdHMsIGV4dHJhY3QpID0+IHRoaXMubG9jLmV4dHJhY3QoZHQsIG9wdHMsIGV4dHJhY3QpLFxuICAgICAgZm9ybWF0T2Zmc2V0ID0gKG9wdHMpID0+IHtcbiAgICAgICAgaWYgKGR0LmlzT2Zmc2V0Rml4ZWQgJiYgZHQub2Zmc2V0ID09PSAwICYmIG9wdHMuYWxsb3daKSB7XG4gICAgICAgICAgcmV0dXJuIFwiWlwiO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGR0LmlzVmFsaWQgPyBkdC56b25lLmZvcm1hdE9mZnNldChkdC50cywgb3B0cy5mb3JtYXQpIDogXCJcIjtcbiAgICAgIH0sXG4gICAgICBtZXJpZGllbSA9ICgpID0+XG4gICAgICAgIGtub3duRW5nbGlzaFxuICAgICAgICAgID8gRW5nbGlzaC5tZXJpZGllbUZvckRhdGVUaW1lKGR0KVxuICAgICAgICAgIDogc3RyaW5nKHsgaG91cjogXCJudW1lcmljXCIsIGhvdXJDeWNsZTogXCJoMTJcIiB9LCBcImRheXBlcmlvZFwiKSxcbiAgICAgIG1vbnRoID0gKGxlbmd0aCwgc3RhbmRhbG9uZSkgPT5cbiAgICAgICAga25vd25FbmdsaXNoXG4gICAgICAgICAgPyBFbmdsaXNoLm1vbnRoRm9yRGF0ZVRpbWUoZHQsIGxlbmd0aClcbiAgICAgICAgICA6IHN0cmluZyhzdGFuZGFsb25lID8geyBtb250aDogbGVuZ3RoIH0gOiB7IG1vbnRoOiBsZW5ndGgsIGRheTogXCJudW1lcmljXCIgfSwgXCJtb250aFwiKSxcbiAgICAgIHdlZWtkYXkgPSAobGVuZ3RoLCBzdGFuZGFsb25lKSA9PlxuICAgICAgICBrbm93bkVuZ2xpc2hcbiAgICAgICAgICA/IEVuZ2xpc2gud2Vla2RheUZvckRhdGVUaW1lKGR0LCBsZW5ndGgpXG4gICAgICAgICAgOiBzdHJpbmcoXG4gICAgICAgICAgICAgIHN0YW5kYWxvbmUgPyB7IHdlZWtkYXk6IGxlbmd0aCB9IDogeyB3ZWVrZGF5OiBsZW5ndGgsIG1vbnRoOiBcImxvbmdcIiwgZGF5OiBcIm51bWVyaWNcIiB9LFxuICAgICAgICAgICAgICBcIndlZWtkYXlcIlxuICAgICAgICAgICAgKSxcbiAgICAgIG1heWJlTWFjcm8gPSAodG9rZW4pID0+IHtcbiAgICAgICAgY29uc3QgZm9ybWF0T3B0cyA9IEZvcm1hdHRlci5tYWNyb1Rva2VuVG9Gb3JtYXRPcHRzKHRva2VuKTtcbiAgICAgICAgaWYgKGZvcm1hdE9wdHMpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRXaXRoU3lzdGVtRGVmYXVsdChkdCwgZm9ybWF0T3B0cyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRva2VuO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJhID0gKGxlbmd0aCkgPT5cbiAgICAgICAga25vd25FbmdsaXNoID8gRW5nbGlzaC5lcmFGb3JEYXRlVGltZShkdCwgbGVuZ3RoKSA6IHN0cmluZyh7IGVyYTogbGVuZ3RoIH0sIFwiZXJhXCIpLFxuICAgICAgdG9rZW5Ub1N0cmluZyA9ICh0b2tlbikgPT4ge1xuICAgICAgICAvLyBXaGVyZSBwb3NzaWJsZTogaHR0cHM6Ly9jbGRyLnVuaWNvZGUub3JnL3RyYW5zbGF0aW9uL2RhdGUtdGltZS9kYXRlLXRpbWUtc3ltYm9sc1xuICAgICAgICBzd2l0Y2ggKHRva2VuKSB7XG4gICAgICAgICAgLy8gbXNcbiAgICAgICAgICBjYXNlIFwiU1wiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKGR0Lm1pbGxpc2Vjb25kKTtcbiAgICAgICAgICBjYXNlIFwidVwiOlxuICAgICAgICAgIC8vIGZhbGxzIHRocm91Z2hcbiAgICAgICAgICBjYXNlIFwiU1NTXCI6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5udW0oZHQubWlsbGlzZWNvbmQsIDMpO1xuICAgICAgICAgIC8vIHNlY29uZHNcbiAgICAgICAgICBjYXNlIFwic1wiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKGR0LnNlY29uZCk7XG4gICAgICAgICAgY2FzZSBcInNzXCI6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5udW0oZHQuc2Vjb25kLCAyKTtcbiAgICAgICAgICAvLyBmcmFjdGlvbmFsIHNlY29uZHNcbiAgICAgICAgICBjYXNlIFwidXVcIjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShNYXRoLmZsb29yKGR0Lm1pbGxpc2Vjb25kIC8gMTApLCAyKTtcbiAgICAgICAgICBjYXNlIFwidXV1XCI6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5udW0oTWF0aC5mbG9vcihkdC5taWxsaXNlY29uZCAvIDEwMCkpO1xuICAgICAgICAgIC8vIG1pbnV0ZXNcbiAgICAgICAgICBjYXNlIFwibVwiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKGR0Lm1pbnV0ZSk7XG4gICAgICAgICAgY2FzZSBcIm1tXCI6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5udW0oZHQubWludXRlLCAyKTtcbiAgICAgICAgICAvLyBob3Vyc1xuICAgICAgICAgIGNhc2UgXCJoXCI6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5udW0oZHQuaG91ciAlIDEyID09PSAwID8gMTIgOiBkdC5ob3VyICUgMTIpO1xuICAgICAgICAgIGNhc2UgXCJoaFwiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKGR0LmhvdXIgJSAxMiA9PT0gMCA/IDEyIDogZHQuaG91ciAlIDEyLCAyKTtcbiAgICAgICAgICBjYXNlIFwiSFwiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKGR0LmhvdXIpO1xuICAgICAgICAgIGNhc2UgXCJISFwiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKGR0LmhvdXIsIDIpO1xuICAgICAgICAgIC8vIG9mZnNldFxuICAgICAgICAgIGNhc2UgXCJaXCI6XG4gICAgICAgICAgICAvLyBsaWtlICs2XG4gICAgICAgICAgICByZXR1cm4gZm9ybWF0T2Zmc2V0KHsgZm9ybWF0OiBcIm5hcnJvd1wiLCBhbGxvd1o6IHRoaXMub3B0cy5hbGxvd1ogfSk7XG4gICAgICAgICAgY2FzZSBcIlpaXCI6XG4gICAgICAgICAgICAvLyBsaWtlICswNjowMFxuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdE9mZnNldCh7IGZvcm1hdDogXCJzaG9ydFwiLCBhbGxvd1o6IHRoaXMub3B0cy5hbGxvd1ogfSk7XG4gICAgICAgICAgY2FzZSBcIlpaWlwiOlxuICAgICAgICAgICAgLy8gbGlrZSArMDYwMFxuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdE9mZnNldCh7IGZvcm1hdDogXCJ0ZWNoaWVcIiwgYWxsb3daOiB0aGlzLm9wdHMuYWxsb3daIH0pO1xuICAgICAgICAgIGNhc2UgXCJaWlpaXCI6XG4gICAgICAgICAgICAvLyBsaWtlIEVTVFxuICAgICAgICAgICAgcmV0dXJuIGR0LnpvbmUub2Zmc2V0TmFtZShkdC50cywgeyBmb3JtYXQ6IFwic2hvcnRcIiwgbG9jYWxlOiB0aGlzLmxvYy5sb2NhbGUgfSk7XG4gICAgICAgICAgY2FzZSBcIlpaWlpaXCI6XG4gICAgICAgICAgICAvLyBsaWtlIEVhc3Rlcm4gU3RhbmRhcmQgVGltZVxuICAgICAgICAgICAgcmV0dXJuIGR0LnpvbmUub2Zmc2V0TmFtZShkdC50cywgeyBmb3JtYXQ6IFwibG9uZ1wiLCBsb2NhbGU6IHRoaXMubG9jLmxvY2FsZSB9KTtcbiAgICAgICAgICAvLyB6b25lXG4gICAgICAgICAgY2FzZSBcInpcIjpcbiAgICAgICAgICAgIC8vIGxpa2UgQW1lcmljYS9OZXdfWW9ya1xuICAgICAgICAgICAgcmV0dXJuIGR0LnpvbmVOYW1lO1xuICAgICAgICAgIC8vIG1lcmlkaWVtc1xuICAgICAgICAgIGNhc2UgXCJhXCI6XG4gICAgICAgICAgICByZXR1cm4gbWVyaWRpZW0oKTtcbiAgICAgICAgICAvLyBkYXRlc1xuICAgICAgICAgIGNhc2UgXCJkXCI6XG4gICAgICAgICAgICByZXR1cm4gdXNlRGF0ZVRpbWVGb3JtYXR0ZXIgPyBzdHJpbmcoeyBkYXk6IFwibnVtZXJpY1wiIH0sIFwiZGF5XCIpIDogdGhpcy5udW0oZHQuZGF5KTtcbiAgICAgICAgICBjYXNlIFwiZGRcIjpcbiAgICAgICAgICAgIHJldHVybiB1c2VEYXRlVGltZUZvcm1hdHRlciA/IHN0cmluZyh7IGRheTogXCIyLWRpZ2l0XCIgfSwgXCJkYXlcIikgOiB0aGlzLm51bShkdC5kYXksIDIpO1xuICAgICAgICAgIC8vIHdlZWtkYXlzIC0gc3RhbmRhbG9uZVxuICAgICAgICAgIGNhc2UgXCJjXCI6XG4gICAgICAgICAgICAvLyBsaWtlIDFcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC53ZWVrZGF5KTtcbiAgICAgICAgICBjYXNlIFwiY2NjXCI6XG4gICAgICAgICAgICAvLyBsaWtlICdUdWVzJ1xuICAgICAgICAgICAgcmV0dXJuIHdlZWtkYXkoXCJzaG9ydFwiLCB0cnVlKTtcbiAgICAgICAgICBjYXNlIFwiY2NjY1wiOlxuICAgICAgICAgICAgLy8gbGlrZSAnVHVlc2RheSdcbiAgICAgICAgICAgIHJldHVybiB3ZWVrZGF5KFwibG9uZ1wiLCB0cnVlKTtcbiAgICAgICAgICBjYXNlIFwiY2NjY2NcIjpcbiAgICAgICAgICAgIC8vIGxpa2UgJ1QnXG4gICAgICAgICAgICByZXR1cm4gd2Vla2RheShcIm5hcnJvd1wiLCB0cnVlKTtcbiAgICAgICAgICAvLyB3ZWVrZGF5cyAtIGZvcm1hdFxuICAgICAgICAgIGNhc2UgXCJFXCI6XG4gICAgICAgICAgICAvLyBsaWtlIDFcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC53ZWVrZGF5KTtcbiAgICAgICAgICBjYXNlIFwiRUVFXCI6XG4gICAgICAgICAgICAvLyBsaWtlICdUdWVzJ1xuICAgICAgICAgICAgcmV0dXJuIHdlZWtkYXkoXCJzaG9ydFwiLCBmYWxzZSk7XG4gICAgICAgICAgY2FzZSBcIkVFRUVcIjpcbiAgICAgICAgICAgIC8vIGxpa2UgJ1R1ZXNkYXknXG4gICAgICAgICAgICByZXR1cm4gd2Vla2RheShcImxvbmdcIiwgZmFsc2UpO1xuICAgICAgICAgIGNhc2UgXCJFRUVFRVwiOlxuICAgICAgICAgICAgLy8gbGlrZSAnVCdcbiAgICAgICAgICAgIHJldHVybiB3ZWVrZGF5KFwibmFycm93XCIsIGZhbHNlKTtcbiAgICAgICAgICAvLyBtb250aHMgLSBzdGFuZGFsb25lXG4gICAgICAgICAgY2FzZSBcIkxcIjpcbiAgICAgICAgICAgIC8vIGxpa2UgMVxuICAgICAgICAgICAgcmV0dXJuIHVzZURhdGVUaW1lRm9ybWF0dGVyXG4gICAgICAgICAgICAgID8gc3RyaW5nKHsgbW9udGg6IFwibnVtZXJpY1wiLCBkYXk6IFwibnVtZXJpY1wiIH0sIFwibW9udGhcIilcbiAgICAgICAgICAgICAgOiB0aGlzLm51bShkdC5tb250aCk7XG4gICAgICAgICAgY2FzZSBcIkxMXCI6XG4gICAgICAgICAgICAvLyBsaWtlIDAxLCBkb2Vzbid0IHNlZW0gdG8gd29ya1xuICAgICAgICAgICAgcmV0dXJuIHVzZURhdGVUaW1lRm9ybWF0dGVyXG4gICAgICAgICAgICAgID8gc3RyaW5nKHsgbW9udGg6IFwiMi1kaWdpdFwiLCBkYXk6IFwibnVtZXJpY1wiIH0sIFwibW9udGhcIilcbiAgICAgICAgICAgICAgOiB0aGlzLm51bShkdC5tb250aCwgMik7XG4gICAgICAgICAgY2FzZSBcIkxMTFwiOlxuICAgICAgICAgICAgLy8gbGlrZSBKYW5cbiAgICAgICAgICAgIHJldHVybiBtb250aChcInNob3J0XCIsIHRydWUpO1xuICAgICAgICAgIGNhc2UgXCJMTExMXCI6XG4gICAgICAgICAgICAvLyBsaWtlIEphbnVhcnlcbiAgICAgICAgICAgIHJldHVybiBtb250aChcImxvbmdcIiwgdHJ1ZSk7XG4gICAgICAgICAgY2FzZSBcIkxMTExMXCI6XG4gICAgICAgICAgICAvLyBsaWtlIEpcbiAgICAgICAgICAgIHJldHVybiBtb250aChcIm5hcnJvd1wiLCB0cnVlKTtcbiAgICAgICAgICAvLyBtb250aHMgLSBmb3JtYXRcbiAgICAgICAgICBjYXNlIFwiTVwiOlxuICAgICAgICAgICAgLy8gbGlrZSAxXG4gICAgICAgICAgICByZXR1cm4gdXNlRGF0ZVRpbWVGb3JtYXR0ZXJcbiAgICAgICAgICAgICAgPyBzdHJpbmcoeyBtb250aDogXCJudW1lcmljXCIgfSwgXCJtb250aFwiKVxuICAgICAgICAgICAgICA6IHRoaXMubnVtKGR0Lm1vbnRoKTtcbiAgICAgICAgICBjYXNlIFwiTU1cIjpcbiAgICAgICAgICAgIC8vIGxpa2UgMDFcbiAgICAgICAgICAgIHJldHVybiB1c2VEYXRlVGltZUZvcm1hdHRlclxuICAgICAgICAgICAgICA/IHN0cmluZyh7IG1vbnRoOiBcIjItZGlnaXRcIiB9LCBcIm1vbnRoXCIpXG4gICAgICAgICAgICAgIDogdGhpcy5udW0oZHQubW9udGgsIDIpO1xuICAgICAgICAgIGNhc2UgXCJNTU1cIjpcbiAgICAgICAgICAgIC8vIGxpa2UgSmFuXG4gICAgICAgICAgICByZXR1cm4gbW9udGgoXCJzaG9ydFwiLCBmYWxzZSk7XG4gICAgICAgICAgY2FzZSBcIk1NTU1cIjpcbiAgICAgICAgICAgIC8vIGxpa2UgSmFudWFyeVxuICAgICAgICAgICAgcmV0dXJuIG1vbnRoKFwibG9uZ1wiLCBmYWxzZSk7XG4gICAgICAgICAgY2FzZSBcIk1NTU1NXCI6XG4gICAgICAgICAgICAvLyBsaWtlIEpcbiAgICAgICAgICAgIHJldHVybiBtb250aChcIm5hcnJvd1wiLCBmYWxzZSk7XG4gICAgICAgICAgLy8geWVhcnNcbiAgICAgICAgICBjYXNlIFwieVwiOlxuICAgICAgICAgICAgLy8gbGlrZSAyMDE0XG4gICAgICAgICAgICByZXR1cm4gdXNlRGF0ZVRpbWVGb3JtYXR0ZXIgPyBzdHJpbmcoeyB5ZWFyOiBcIm51bWVyaWNcIiB9LCBcInllYXJcIikgOiB0aGlzLm51bShkdC55ZWFyKTtcbiAgICAgICAgICBjYXNlIFwieXlcIjpcbiAgICAgICAgICAgIC8vIGxpa2UgMTRcbiAgICAgICAgICAgIHJldHVybiB1c2VEYXRlVGltZUZvcm1hdHRlclxuICAgICAgICAgICAgICA/IHN0cmluZyh7IHllYXI6IFwiMi1kaWdpdFwiIH0sIFwieWVhclwiKVxuICAgICAgICAgICAgICA6IHRoaXMubnVtKGR0LnllYXIudG9TdHJpbmcoKS5zbGljZSgtMiksIDIpO1xuICAgICAgICAgIGNhc2UgXCJ5eXl5XCI6XG4gICAgICAgICAgICAvLyBsaWtlIDAwMTJcbiAgICAgICAgICAgIHJldHVybiB1c2VEYXRlVGltZUZvcm1hdHRlclxuICAgICAgICAgICAgICA/IHN0cmluZyh7IHllYXI6IFwibnVtZXJpY1wiIH0sIFwieWVhclwiKVxuICAgICAgICAgICAgICA6IHRoaXMubnVtKGR0LnllYXIsIDQpO1xuICAgICAgICAgIGNhc2UgXCJ5eXl5eXlcIjpcbiAgICAgICAgICAgIC8vIGxpa2UgMDAwMDEyXG4gICAgICAgICAgICByZXR1cm4gdXNlRGF0ZVRpbWVGb3JtYXR0ZXJcbiAgICAgICAgICAgICAgPyBzdHJpbmcoeyB5ZWFyOiBcIm51bWVyaWNcIiB9LCBcInllYXJcIilcbiAgICAgICAgICAgICAgOiB0aGlzLm51bShkdC55ZWFyLCA2KTtcbiAgICAgICAgICAvLyBlcmFzXG4gICAgICAgICAgY2FzZSBcIkdcIjpcbiAgICAgICAgICAgIC8vIGxpa2UgQURcbiAgICAgICAgICAgIHJldHVybiBlcmEoXCJzaG9ydFwiKTtcbiAgICAgICAgICBjYXNlIFwiR0dcIjpcbiAgICAgICAgICAgIC8vIGxpa2UgQW5ubyBEb21pbmlcbiAgICAgICAgICAgIHJldHVybiBlcmEoXCJsb25nXCIpO1xuICAgICAgICAgIGNhc2UgXCJHR0dHR1wiOlxuICAgICAgICAgICAgcmV0dXJuIGVyYShcIm5hcnJvd1wiKTtcbiAgICAgICAgICBjYXNlIFwia2tcIjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC53ZWVrWWVhci50b1N0cmluZygpLnNsaWNlKC0yKSwgMik7XG4gICAgICAgICAgY2FzZSBcImtra2tcIjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC53ZWVrWWVhciwgNCk7XG4gICAgICAgICAgY2FzZSBcIldcIjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC53ZWVrTnVtYmVyKTtcbiAgICAgICAgICBjYXNlIFwiV1dcIjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC53ZWVrTnVtYmVyLCAyKTtcbiAgICAgICAgICBjYXNlIFwiblwiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKGR0LmxvY2FsV2Vla051bWJlcik7XG4gICAgICAgICAgY2FzZSBcIm5uXCI6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5udW0oZHQubG9jYWxXZWVrTnVtYmVyLCAyKTtcbiAgICAgICAgICBjYXNlIFwiaWlcIjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC5sb2NhbFdlZWtZZWFyLnRvU3RyaW5nKCkuc2xpY2UoLTIpLCAyKTtcbiAgICAgICAgICBjYXNlIFwiaWlpaVwiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKGR0LmxvY2FsV2Vla1llYXIsIDQpO1xuICAgICAgICAgIGNhc2UgXCJvXCI6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5udW0oZHQub3JkaW5hbCk7XG4gICAgICAgICAgY2FzZSBcIm9vb1wiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKGR0Lm9yZGluYWwsIDMpO1xuICAgICAgICAgIGNhc2UgXCJxXCI6XG4gICAgICAgICAgICAvLyBsaWtlIDFcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC5xdWFydGVyKTtcbiAgICAgICAgICBjYXNlIFwicXFcIjpcbiAgICAgICAgICAgIC8vIGxpa2UgMDFcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC5xdWFydGVyLCAyKTtcbiAgICAgICAgICBjYXNlIFwiWFwiOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubnVtKE1hdGguZmxvb3IoZHQudHMgLyAxMDAwKSk7XG4gICAgICAgICAgY2FzZSBcInhcIjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm51bShkdC50cyk7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBtYXliZU1hY3JvKHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgIHJldHVybiBzdHJpbmdpZnlUb2tlbnMoRm9ybWF0dGVyLnBhcnNlRm9ybWF0KGZtdCksIHRva2VuVG9TdHJpbmcpO1xuICB9XG5cbiAgZm9ybWF0RHVyYXRpb25Gcm9tU3RyaW5nKGR1ciwgZm10KSB7XG4gICAgY29uc3QgdG9rZW5Ub0ZpZWxkID0gKHRva2VuKSA9PiB7XG4gICAgICAgIHN3aXRjaCAodG9rZW5bMF0pIHtcbiAgICAgICAgICBjYXNlIFwiU1wiOlxuICAgICAgICAgICAgcmV0dXJuIFwibWlsbGlzZWNvbmRcIjtcbiAgICAgICAgICBjYXNlIFwic1wiOlxuICAgICAgICAgICAgcmV0dXJuIFwic2Vjb25kXCI7XG4gICAgICAgICAgY2FzZSBcIm1cIjpcbiAgICAgICAgICAgIHJldHVybiBcIm1pbnV0ZVwiO1xuICAgICAgICAgIGNhc2UgXCJoXCI6XG4gICAgICAgICAgICByZXR1cm4gXCJob3VyXCI7XG4gICAgICAgICAgY2FzZSBcImRcIjpcbiAgICAgICAgICAgIHJldHVybiBcImRheVwiO1xuICAgICAgICAgIGNhc2UgXCJ3XCI6XG4gICAgICAgICAgICByZXR1cm4gXCJ3ZWVrXCI7XG4gICAgICAgICAgY2FzZSBcIk1cIjpcbiAgICAgICAgICAgIHJldHVybiBcIm1vbnRoXCI7XG4gICAgICAgICAgY2FzZSBcInlcIjpcbiAgICAgICAgICAgIHJldHVybiBcInllYXJcIjtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB0b2tlblRvU3RyaW5nID0gKGxpbGR1cikgPT4gKHRva2VuKSA9PiB7XG4gICAgICAgIGNvbnN0IG1hcHBlZCA9IHRva2VuVG9GaWVsZCh0b2tlbik7XG4gICAgICAgIGlmIChtYXBwZWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5udW0obGlsZHVyLmdldChtYXBwZWQpLCB0b2tlbi5sZW5ndGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0b2tlbjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHRva2VucyA9IEZvcm1hdHRlci5wYXJzZUZvcm1hdChmbXQpLFxuICAgICAgcmVhbFRva2VucyA9IHRva2Vucy5yZWR1Y2UoXG4gICAgICAgIChmb3VuZCwgeyBsaXRlcmFsLCB2YWwgfSkgPT4gKGxpdGVyYWwgPyBmb3VuZCA6IGZvdW5kLmNvbmNhdCh2YWwpKSxcbiAgICAgICAgW11cbiAgICAgICksXG4gICAgICBjb2xsYXBzZWQgPSBkdXIuc2hpZnRUbyguLi5yZWFsVG9rZW5zLm1hcCh0b2tlblRvRmllbGQpLmZpbHRlcigodCkgPT4gdCkpO1xuICAgIHJldHVybiBzdHJpbmdpZnlUb2tlbnModG9rZW5zLCB0b2tlblRvU3RyaW5nKGNvbGxhcHNlZCkpO1xuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgdW50cnVuY2F0ZVllYXIsXG4gIHNpZ25lZE9mZnNldCxcbiAgcGFyc2VJbnRlZ2VyLFxuICBwYXJzZU1pbGxpcyxcbiAgaXNVbmRlZmluZWQsXG4gIHBhcnNlRmxvYXRpbmcsXG59IGZyb20gXCIuL3V0aWwuanNcIjtcbmltcG9ydCAqIGFzIEVuZ2xpc2ggZnJvbSBcIi4vZW5nbGlzaC5qc1wiO1xuaW1wb3J0IEZpeGVkT2Zmc2V0Wm9uZSBmcm9tIFwiLi4vem9uZXMvZml4ZWRPZmZzZXRab25lLmpzXCI7XG5pbXBvcnQgSUFOQVpvbmUgZnJvbSBcIi4uL3pvbmVzL0lBTkFab25lLmpzXCI7XG5cbi8qXG4gKiBUaGlzIGZpbGUgaGFuZGxlcyBwYXJzaW5nIGZvciB3ZWxsLXNwZWNpZmllZCBmb3JtYXRzLiBIZXJlJ3MgaG93IGl0IHdvcmtzOlxuICogVHdvIHRoaW5ncyBnbyBpbnRvIHBhcnNpbmc6IGEgcmVnZXggdG8gbWF0Y2ggd2l0aCBhbmQgYW4gZXh0cmFjdG9yIHRvIHRha2UgYXBhcnQgdGhlIGdyb3VwcyBpbiB0aGUgbWF0Y2guXG4gKiBBbiBleHRyYWN0b3IgaXMganVzdCBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYSByZWdleCBtYXRjaCBhcnJheSBhbmQgcmV0dXJucyBhIHsgeWVhcjogLi4uLCBtb250aDogLi4uIH0gb2JqZWN0XG4gKiBwYXJzZSgpIGRvZXMgdGhlIHdvcmsgb2YgZXhlY3V0aW5nIHRoZSByZWdleCBhbmQgYXBwbHlpbmcgdGhlIGV4dHJhY3Rvci4gSXQgdGFrZXMgbXVsdGlwbGUgcmVnZXgvZXh0cmFjdG9yIHBhaXJzIHRvIHRyeSBpbiBzZXF1ZW5jZS5cbiAqIEV4dHJhY3RvcnMgY2FuIHRha2UgYSBcImN1cnNvclwiIHJlcHJlc2VudGluZyB0aGUgb2Zmc2V0IGluIHRoZSBtYXRjaCB0byBsb29rIGF0LiBUaGlzIG1ha2VzIGl0IGVhc3kgdG8gY29tYmluZSBleHRyYWN0b3JzLlxuICogY29tYmluZUV4dHJhY3RvcnMoKSBkb2VzIHRoZSB3b3JrIG9mIGNvbWJpbmluZyB0aGVtLCBrZWVwaW5nIHRyYWNrIG9mIHRoZSBjdXJzb3IgdGhyb3VnaCBtdWx0aXBsZSBleHRyYWN0aW9ucy5cbiAqIFNvbWUgZXh0cmFjdGlvbnMgYXJlIHN1cGVyIGR1bWIgYW5kIHNpbXBsZVBhcnNlIGFuZCBmcm9tU3RyaW5ncyBoZWxwIERSWSB0aGVtLlxuICovXG5cbmNvbnN0IGlhbmFSZWdleCA9IC9bQS1aYS16XystXXsxLDI1Nn0oPzo6P1xcL1tBLVphLXowLTlfKy1dezEsMjU2fSg/OlxcL1tBLVphLXowLTlfKy1dezEsMjU2fSk/KT8vO1xuXG5mdW5jdGlvbiBjb21iaW5lUmVnZXhlcyguLi5yZWdleGVzKSB7XG4gIGNvbnN0IGZ1bGwgPSByZWdleGVzLnJlZHVjZSgoZiwgcikgPT4gZiArIHIuc291cmNlLCBcIlwiKTtcbiAgcmV0dXJuIFJlZ0V4cChgXiR7ZnVsbH0kYCk7XG59XG5cbmZ1bmN0aW9uIGNvbWJpbmVFeHRyYWN0b3JzKC4uLmV4dHJhY3RvcnMpIHtcbiAgcmV0dXJuIChtKSA9PlxuICAgIGV4dHJhY3RvcnNcbiAgICAgIC5yZWR1Y2UoXG4gICAgICAgIChbbWVyZ2VkVmFscywgbWVyZ2VkWm9uZSwgY3Vyc29yXSwgZXgpID0+IHtcbiAgICAgICAgICBjb25zdCBbdmFsLCB6b25lLCBuZXh0XSA9IGV4KG0sIGN1cnNvcik7XG4gICAgICAgICAgcmV0dXJuIFt7IC4uLm1lcmdlZFZhbHMsIC4uLnZhbCB9LCB6b25lIHx8IG1lcmdlZFpvbmUsIG5leHRdO1xuICAgICAgICB9LFxuICAgICAgICBbe30sIG51bGwsIDFdXG4gICAgICApXG4gICAgICAuc2xpY2UoMCwgMik7XG59XG5cbmZ1bmN0aW9uIHBhcnNlKHMsIC4uLnBhdHRlcm5zKSB7XG4gIGlmIChzID09IG51bGwpIHtcbiAgICByZXR1cm4gW251bGwsIG51bGxdO1xuICB9XG5cbiAgZm9yIChjb25zdCBbcmVnZXgsIGV4dHJhY3Rvcl0gb2YgcGF0dGVybnMpIHtcbiAgICBjb25zdCBtID0gcmVnZXguZXhlYyhzKTtcbiAgICBpZiAobSkge1xuICAgICAgcmV0dXJuIGV4dHJhY3RvcihtKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIFtudWxsLCBudWxsXTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlUGFyc2UoLi4ua2V5cykge1xuICByZXR1cm4gKG1hdGNoLCBjdXJzb3IpID0+IHtcbiAgICBjb25zdCByZXQgPSB7fTtcbiAgICBsZXQgaTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXRba2V5c1tpXV0gPSBwYXJzZUludGVnZXIobWF0Y2hbY3Vyc29yICsgaV0pO1xuICAgIH1cbiAgICByZXR1cm4gW3JldCwgbnVsbCwgY3Vyc29yICsgaV07XG4gIH07XG59XG5cbi8vIElTTyBhbmQgU1FMIHBhcnNpbmdcbmNvbnN0IG9mZnNldFJlZ2V4ID0gLyg/OihaKXwoWystXVxcZFxcZCkoPzo6PyhcXGRcXGQpKT8pLztcbmNvbnN0IGlzb0V4dGVuZGVkWm9uZSA9IGAoPzoke29mZnNldFJlZ2V4LnNvdXJjZX0/KD86XFxcXFsoJHtpYW5hUmVnZXguc291cmNlfSlcXFxcXSk/KT9gO1xuY29uc3QgaXNvVGltZUJhc2VSZWdleCA9IC8oXFxkXFxkKSg/Ojo/KFxcZFxcZCkoPzo6PyhcXGRcXGQpKD86Wy4sXShcXGR7MSwzMH0pKT8pPyk/LztcbmNvbnN0IGlzb1RpbWVSZWdleCA9IFJlZ0V4cChgJHtpc29UaW1lQmFzZVJlZ2V4LnNvdXJjZX0ke2lzb0V4dGVuZGVkWm9uZX1gKTtcbmNvbnN0IGlzb1RpbWVFeHRlbnNpb25SZWdleCA9IFJlZ0V4cChgKD86VCR7aXNvVGltZVJlZ2V4LnNvdXJjZX0pP2ApO1xuY29uc3QgaXNvWW1kUmVnZXggPSAvKFsrLV1cXGR7Nn18XFxkezR9KSg/Oi0/KFxcZFxcZCkoPzotPyhcXGRcXGQpKT8pPy87XG5jb25zdCBpc29XZWVrUmVnZXggPSAvKFxcZHs0fSktP1coXFxkXFxkKSg/Oi0/KFxcZCkpPy87XG5jb25zdCBpc29PcmRpbmFsUmVnZXggPSAvKFxcZHs0fSktPyhcXGR7M30pLztcbmNvbnN0IGV4dHJhY3RJU09XZWVrRGF0YSA9IHNpbXBsZVBhcnNlKFwid2Vla1llYXJcIiwgXCJ3ZWVrTnVtYmVyXCIsIFwid2Vla0RheVwiKTtcbmNvbnN0IGV4dHJhY3RJU09PcmRpbmFsRGF0YSA9IHNpbXBsZVBhcnNlKFwieWVhclwiLCBcIm9yZGluYWxcIik7XG5jb25zdCBzcWxZbWRSZWdleCA9IC8oXFxkezR9KS0oXFxkXFxkKS0oXFxkXFxkKS87IC8vIGR1bWJlZC1kb3duIHZlcnNpb24gb2YgdGhlIElTTyBvbmVcbmNvbnN0IHNxbFRpbWVSZWdleCA9IFJlZ0V4cChcbiAgYCR7aXNvVGltZUJhc2VSZWdleC5zb3VyY2V9ID8oPzoke29mZnNldFJlZ2V4LnNvdXJjZX18KCR7aWFuYVJlZ2V4LnNvdXJjZX0pKT9gXG4pO1xuY29uc3Qgc3FsVGltZUV4dGVuc2lvblJlZ2V4ID0gUmVnRXhwKGAoPzogJHtzcWxUaW1lUmVnZXguc291cmNlfSk/YCk7XG5cbmZ1bmN0aW9uIGludChtYXRjaCwgcG9zLCBmYWxsYmFjaykge1xuICBjb25zdCBtID0gbWF0Y2hbcG9zXTtcbiAgcmV0dXJuIGlzVW5kZWZpbmVkKG0pID8gZmFsbGJhY2sgOiBwYXJzZUludGVnZXIobSk7XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RJU09ZbWQobWF0Y2gsIGN1cnNvcikge1xuICBjb25zdCBpdGVtID0ge1xuICAgIHllYXI6IGludChtYXRjaCwgY3Vyc29yKSxcbiAgICBtb250aDogaW50KG1hdGNoLCBjdXJzb3IgKyAxLCAxKSxcbiAgICBkYXk6IGludChtYXRjaCwgY3Vyc29yICsgMiwgMSksXG4gIH07XG5cbiAgcmV0dXJuIFtpdGVtLCBudWxsLCBjdXJzb3IgKyAzXTtcbn1cblxuZnVuY3Rpb24gZXh0cmFjdElTT1RpbWUobWF0Y2gsIGN1cnNvcikge1xuICBjb25zdCBpdGVtID0ge1xuICAgIGhvdXJzOiBpbnQobWF0Y2gsIGN1cnNvciwgMCksXG4gICAgbWludXRlczogaW50KG1hdGNoLCBjdXJzb3IgKyAxLCAwKSxcbiAgICBzZWNvbmRzOiBpbnQobWF0Y2gsIGN1cnNvciArIDIsIDApLFxuICAgIG1pbGxpc2Vjb25kczogcGFyc2VNaWxsaXMobWF0Y2hbY3Vyc29yICsgM10pLFxuICB9O1xuXG4gIHJldHVybiBbaXRlbSwgbnVsbCwgY3Vyc29yICsgNF07XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RJU09PZmZzZXQobWF0Y2gsIGN1cnNvcikge1xuICBjb25zdCBsb2NhbCA9ICFtYXRjaFtjdXJzb3JdICYmICFtYXRjaFtjdXJzb3IgKyAxXSxcbiAgICBmdWxsT2Zmc2V0ID0gc2lnbmVkT2Zmc2V0KG1hdGNoW2N1cnNvciArIDFdLCBtYXRjaFtjdXJzb3IgKyAyXSksXG4gICAgem9uZSA9IGxvY2FsID8gbnVsbCA6IEZpeGVkT2Zmc2V0Wm9uZS5pbnN0YW5jZShmdWxsT2Zmc2V0KTtcbiAgcmV0dXJuIFt7fSwgem9uZSwgY3Vyc29yICsgM107XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RJQU5BWm9uZShtYXRjaCwgY3Vyc29yKSB7XG4gIGNvbnN0IHpvbmUgPSBtYXRjaFtjdXJzb3JdID8gSUFOQVpvbmUuY3JlYXRlKG1hdGNoW2N1cnNvcl0pIDogbnVsbDtcbiAgcmV0dXJuIFt7fSwgem9uZSwgY3Vyc29yICsgMV07XG59XG5cbi8vIElTTyB0aW1lIHBhcnNpbmdcblxuY29uc3QgaXNvVGltZU9ubHkgPSBSZWdFeHAoYF5UPyR7aXNvVGltZUJhc2VSZWdleC5zb3VyY2V9JGApO1xuXG4vLyBJU08gZHVyYXRpb24gcGFyc2luZ1xuXG5jb25zdCBpc29EdXJhdGlvbiA9XG4gIC9eLT9QKD86KD86KC0/XFxkezEsMjB9KD86XFwuXFxkezEsMjB9KT8pWSk/KD86KC0/XFxkezEsMjB9KD86XFwuXFxkezEsMjB9KT8pTSk/KD86KC0/XFxkezEsMjB9KD86XFwuXFxkezEsMjB9KT8pVyk/KD86KC0/XFxkezEsMjB9KD86XFwuXFxkezEsMjB9KT8pRCk/KD86VCg/OigtP1xcZHsxLDIwfSg/OlxcLlxcZHsxLDIwfSk/KUgpPyg/OigtP1xcZHsxLDIwfSg/OlxcLlxcZHsxLDIwfSk/KU0pPyg/OigtP1xcZHsxLDIwfSkoPzpbLixdKC0/XFxkezEsMjB9KSk/Uyk/KT8pJC87XG5cbmZ1bmN0aW9uIGV4dHJhY3RJU09EdXJhdGlvbihtYXRjaCkge1xuICBjb25zdCBbcywgeWVhclN0ciwgbW9udGhTdHIsIHdlZWtTdHIsIGRheVN0ciwgaG91clN0ciwgbWludXRlU3RyLCBzZWNvbmRTdHIsIG1pbGxpc2Vjb25kc1N0cl0gPVxuICAgIG1hdGNoO1xuXG4gIGNvbnN0IGhhc05lZ2F0aXZlUHJlZml4ID0gc1swXSA9PT0gXCItXCI7XG4gIGNvbnN0IG5lZ2F0aXZlU2Vjb25kcyA9IHNlY29uZFN0ciAmJiBzZWNvbmRTdHJbMF0gPT09IFwiLVwiO1xuXG4gIGNvbnN0IG1heWJlTmVnYXRlID0gKG51bSwgZm9yY2UgPSBmYWxzZSkgPT5cbiAgICBudW0gIT09IHVuZGVmaW5lZCAmJiAoZm9yY2UgfHwgKG51bSAmJiBoYXNOZWdhdGl2ZVByZWZpeCkpID8gLW51bSA6IG51bTtcblxuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIHllYXJzOiBtYXliZU5lZ2F0ZShwYXJzZUZsb2F0aW5nKHllYXJTdHIpKSxcbiAgICAgIG1vbnRoczogbWF5YmVOZWdhdGUocGFyc2VGbG9hdGluZyhtb250aFN0cikpLFxuICAgICAgd2Vla3M6IG1heWJlTmVnYXRlKHBhcnNlRmxvYXRpbmcod2Vla1N0cikpLFxuICAgICAgZGF5czogbWF5YmVOZWdhdGUocGFyc2VGbG9hdGluZyhkYXlTdHIpKSxcbiAgICAgIGhvdXJzOiBtYXliZU5lZ2F0ZShwYXJzZUZsb2F0aW5nKGhvdXJTdHIpKSxcbiAgICAgIG1pbnV0ZXM6IG1heWJlTmVnYXRlKHBhcnNlRmxvYXRpbmcobWludXRlU3RyKSksXG4gICAgICBzZWNvbmRzOiBtYXliZU5lZ2F0ZShwYXJzZUZsb2F0aW5nKHNlY29uZFN0ciksIHNlY29uZFN0ciA9PT0gXCItMFwiKSxcbiAgICAgIG1pbGxpc2Vjb25kczogbWF5YmVOZWdhdGUocGFyc2VNaWxsaXMobWlsbGlzZWNvbmRzU3RyKSwgbmVnYXRpdmVTZWNvbmRzKSxcbiAgICB9LFxuICBdO1xufVxuXG4vLyBUaGVzZSBhcmUgYSBsaXR0bGUgYnJhaW5kZWFkLiBFRFQgKnNob3VsZCogdGVsbCB1cyB0aGF0IHdlJ3JlIGluLCBzYXksIEFtZXJpY2EvTmV3X1lvcmtcbi8vIGFuZCBub3QganVzdCB0aGF0IHdlJ3JlIGluIC0yNDAgKnJpZ2h0IG5vdyouIEJ1dCBzaW5jZSBJIGRvbid0IHRoaW5rIHRoZXNlIGFyZSB1c2VkIHRoYXQgb2Z0ZW5cbi8vIEknbSBqdXN0IGdvaW5nIHRvIGlnbm9yZSB0aGF0XG5jb25zdCBvYnNPZmZzZXRzID0ge1xuICBHTVQ6IDAsXG4gIEVEVDogLTQgKiA2MCxcbiAgRVNUOiAtNSAqIDYwLFxuICBDRFQ6IC01ICogNjAsXG4gIENTVDogLTYgKiA2MCxcbiAgTURUOiAtNiAqIDYwLFxuICBNU1Q6IC03ICogNjAsXG4gIFBEVDogLTcgKiA2MCxcbiAgUFNUOiAtOCAqIDYwLFxufTtcblxuZnVuY3Rpb24gZnJvbVN0cmluZ3Mod2Vla2RheVN0ciwgeWVhclN0ciwgbW9udGhTdHIsIGRheVN0ciwgaG91clN0ciwgbWludXRlU3RyLCBzZWNvbmRTdHIpIHtcbiAgY29uc3QgcmVzdWx0ID0ge1xuICAgIHllYXI6IHllYXJTdHIubGVuZ3RoID09PSAyID8gdW50cnVuY2F0ZVllYXIocGFyc2VJbnRlZ2VyKHllYXJTdHIpKSA6IHBhcnNlSW50ZWdlcih5ZWFyU3RyKSxcbiAgICBtb250aDogRW5nbGlzaC5tb250aHNTaG9ydC5pbmRleE9mKG1vbnRoU3RyKSArIDEsXG4gICAgZGF5OiBwYXJzZUludGVnZXIoZGF5U3RyKSxcbiAgICBob3VyOiBwYXJzZUludGVnZXIoaG91clN0ciksXG4gICAgbWludXRlOiBwYXJzZUludGVnZXIobWludXRlU3RyKSxcbiAgfTtcblxuICBpZiAoc2Vjb25kU3RyKSByZXN1bHQuc2Vjb25kID0gcGFyc2VJbnRlZ2VyKHNlY29uZFN0cik7XG4gIGlmICh3ZWVrZGF5U3RyKSB7XG4gICAgcmVzdWx0LndlZWtkYXkgPVxuICAgICAgd2Vla2RheVN0ci5sZW5ndGggPiAzXG4gICAgICAgID8gRW5nbGlzaC53ZWVrZGF5c0xvbmcuaW5kZXhPZih3ZWVrZGF5U3RyKSArIDFcbiAgICAgICAgOiBFbmdsaXNoLndlZWtkYXlzU2hvcnQuaW5kZXhPZih3ZWVrZGF5U3RyKSArIDE7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vLyBSRkMgMjgyMi81MzIyXG5jb25zdCByZmMyODIyID1cbiAgL14oPzooTW9ufFR1ZXxXZWR8VGh1fEZyaXxTYXR8U3VuKSxcXHMpPyhcXGR7MSwyfSlcXHMoSmFufEZlYnxNYXJ8QXByfE1heXxKdW58SnVsfEF1Z3xTZXB8T2N0fE5vdnxEZWMpXFxzKFxcZHsyLDR9KVxccyhcXGRcXGQpOihcXGRcXGQpKD86OihcXGRcXGQpKT9cXHMoPzooVVR8R01UfFtFQ01QXVtTRF1UKXwoW1p6XSl8KD86KFsrLV1cXGRcXGQpKFxcZFxcZCkpKSQvO1xuXG5mdW5jdGlvbiBleHRyYWN0UkZDMjgyMihtYXRjaCkge1xuICBjb25zdCBbXG4gICAgICAsXG4gICAgICB3ZWVrZGF5U3RyLFxuICAgICAgZGF5U3RyLFxuICAgICAgbW9udGhTdHIsXG4gICAgICB5ZWFyU3RyLFxuICAgICAgaG91clN0cixcbiAgICAgIG1pbnV0ZVN0cixcbiAgICAgIHNlY29uZFN0cixcbiAgICAgIG9ic09mZnNldCxcbiAgICAgIG1pbE9mZnNldCxcbiAgICAgIG9mZkhvdXJTdHIsXG4gICAgICBvZmZNaW51dGVTdHIsXG4gICAgXSA9IG1hdGNoLFxuICAgIHJlc3VsdCA9IGZyb21TdHJpbmdzKHdlZWtkYXlTdHIsIHllYXJTdHIsIG1vbnRoU3RyLCBkYXlTdHIsIGhvdXJTdHIsIG1pbnV0ZVN0ciwgc2Vjb25kU3RyKTtcblxuICBsZXQgb2Zmc2V0O1xuICBpZiAob2JzT2Zmc2V0KSB7XG4gICAgb2Zmc2V0ID0gb2JzT2Zmc2V0c1tvYnNPZmZzZXRdO1xuICB9IGVsc2UgaWYgKG1pbE9mZnNldCkge1xuICAgIG9mZnNldCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgb2Zmc2V0ID0gc2lnbmVkT2Zmc2V0KG9mZkhvdXJTdHIsIG9mZk1pbnV0ZVN0cik7XG4gIH1cblxuICByZXR1cm4gW3Jlc3VsdCwgbmV3IEZpeGVkT2Zmc2V0Wm9uZShvZmZzZXQpXTtcbn1cblxuZnVuY3Rpb24gcHJlcHJvY2Vzc1JGQzI4MjIocykge1xuICAvLyBSZW1vdmUgY29tbWVudHMgYW5kIGZvbGRpbmcgd2hpdGVzcGFjZSBhbmQgcmVwbGFjZSBtdWx0aXBsZS1zcGFjZXMgd2l0aCBhIHNpbmdsZSBzcGFjZVxuICByZXR1cm4gc1xuICAgIC5yZXBsYWNlKC9cXChbXigpXSpcXCl8W1xcblxcdF0vZywgXCIgXCIpXG4gICAgLnJlcGxhY2UoLyhcXHNcXHMrKS9nLCBcIiBcIilcbiAgICAudHJpbSgpO1xufVxuXG4vLyBodHRwIGRhdGVcblxuY29uc3QgcmZjMTEyMyA9XG4gICAgL14oTW9ufFR1ZXxXZWR8VGh1fEZyaXxTYXR8U3VuKSwgKFxcZFxcZCkgKEphbnxGZWJ8TWFyfEFwcnxNYXl8SnVufEp1bHxBdWd8U2VwfE9jdHxOb3Z8RGVjKSAoXFxkezR9KSAoXFxkXFxkKTooXFxkXFxkKTooXFxkXFxkKSBHTVQkLyxcbiAgcmZjODUwID1cbiAgICAvXihNb25kYXl8VHVlc2RheXxXZWRuZXNkYXl8VGh1cnNkYXl8RnJpZGF5fFNhdHVyZGF5fFN1bmRheSksIChcXGRcXGQpLShKYW58RmVifE1hcnxBcHJ8TWF5fEp1bnxKdWx8QXVnfFNlcHxPY3R8Tm92fERlYyktKFxcZFxcZCkgKFxcZFxcZCk6KFxcZFxcZCk6KFxcZFxcZCkgR01UJC8sXG4gIGFzY2lpID1cbiAgICAvXihNb258VHVlfFdlZHxUaHV8RnJpfFNhdHxTdW4pIChKYW58RmVifE1hcnxBcHJ8TWF5fEp1bnxKdWx8QXVnfFNlcHxPY3R8Tm92fERlYykgKCBcXGR8XFxkXFxkKSAoXFxkXFxkKTooXFxkXFxkKTooXFxkXFxkKSAoXFxkezR9KSQvO1xuXG5mdW5jdGlvbiBleHRyYWN0UkZDMTEyM09yODUwKG1hdGNoKSB7XG4gIGNvbnN0IFssIHdlZWtkYXlTdHIsIGRheVN0ciwgbW9udGhTdHIsIHllYXJTdHIsIGhvdXJTdHIsIG1pbnV0ZVN0ciwgc2Vjb25kU3RyXSA9IG1hdGNoLFxuICAgIHJlc3VsdCA9IGZyb21TdHJpbmdzKHdlZWtkYXlTdHIsIHllYXJTdHIsIG1vbnRoU3RyLCBkYXlTdHIsIGhvdXJTdHIsIG1pbnV0ZVN0ciwgc2Vjb25kU3RyKTtcbiAgcmV0dXJuIFtyZXN1bHQsIEZpeGVkT2Zmc2V0Wm9uZS51dGNJbnN0YW5jZV07XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RBU0NJSShtYXRjaCkge1xuICBjb25zdCBbLCB3ZWVrZGF5U3RyLCBtb250aFN0ciwgZGF5U3RyLCBob3VyU3RyLCBtaW51dGVTdHIsIHNlY29uZFN0ciwgeWVhclN0cl0gPSBtYXRjaCxcbiAgICByZXN1bHQgPSBmcm9tU3RyaW5ncyh3ZWVrZGF5U3RyLCB5ZWFyU3RyLCBtb250aFN0ciwgZGF5U3RyLCBob3VyU3RyLCBtaW51dGVTdHIsIHNlY29uZFN0cik7XG4gIHJldHVybiBbcmVzdWx0LCBGaXhlZE9mZnNldFpvbmUudXRjSW5zdGFuY2VdO1xufVxuXG5jb25zdCBpc29ZbWRXaXRoVGltZUV4dGVuc2lvblJlZ2V4ID0gY29tYmluZVJlZ2V4ZXMoaXNvWW1kUmVnZXgsIGlzb1RpbWVFeHRlbnNpb25SZWdleCk7XG5jb25zdCBpc29XZWVrV2l0aFRpbWVFeHRlbnNpb25SZWdleCA9IGNvbWJpbmVSZWdleGVzKGlzb1dlZWtSZWdleCwgaXNvVGltZUV4dGVuc2lvblJlZ2V4KTtcbmNvbnN0IGlzb09yZGluYWxXaXRoVGltZUV4dGVuc2lvblJlZ2V4ID0gY29tYmluZVJlZ2V4ZXMoaXNvT3JkaW5hbFJlZ2V4LCBpc29UaW1lRXh0ZW5zaW9uUmVnZXgpO1xuY29uc3QgaXNvVGltZUNvbWJpbmVkUmVnZXggPSBjb21iaW5lUmVnZXhlcyhpc29UaW1lUmVnZXgpO1xuXG5jb25zdCBleHRyYWN0SVNPWW1kVGltZUFuZE9mZnNldCA9IGNvbWJpbmVFeHRyYWN0b3JzKFxuICBleHRyYWN0SVNPWW1kLFxuICBleHRyYWN0SVNPVGltZSxcbiAgZXh0cmFjdElTT09mZnNldCxcbiAgZXh0cmFjdElBTkFab25lXG4pO1xuY29uc3QgZXh0cmFjdElTT1dlZWtUaW1lQW5kT2Zmc2V0ID0gY29tYmluZUV4dHJhY3RvcnMoXG4gIGV4dHJhY3RJU09XZWVrRGF0YSxcbiAgZXh0cmFjdElTT1RpbWUsXG4gIGV4dHJhY3RJU09PZmZzZXQsXG4gIGV4dHJhY3RJQU5BWm9uZVxuKTtcbmNvbnN0IGV4dHJhY3RJU09PcmRpbmFsRGF0ZUFuZFRpbWUgPSBjb21iaW5lRXh0cmFjdG9ycyhcbiAgZXh0cmFjdElTT09yZGluYWxEYXRhLFxuICBleHRyYWN0SVNPVGltZSxcbiAgZXh0cmFjdElTT09mZnNldCxcbiAgZXh0cmFjdElBTkFab25lXG4pO1xuY29uc3QgZXh0cmFjdElTT1RpbWVBbmRPZmZzZXQgPSBjb21iaW5lRXh0cmFjdG9ycyhcbiAgZXh0cmFjdElTT1RpbWUsXG4gIGV4dHJhY3RJU09PZmZzZXQsXG4gIGV4dHJhY3RJQU5BWm9uZVxuKTtcblxuLypcbiAqIEBwcml2YXRlXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlSVNPRGF0ZShzKSB7XG4gIHJldHVybiBwYXJzZShcbiAgICBzLFxuICAgIFtpc29ZbWRXaXRoVGltZUV4dGVuc2lvblJlZ2V4LCBleHRyYWN0SVNPWW1kVGltZUFuZE9mZnNldF0sXG4gICAgW2lzb1dlZWtXaXRoVGltZUV4dGVuc2lvblJlZ2V4LCBleHRyYWN0SVNPV2Vla1RpbWVBbmRPZmZzZXRdLFxuICAgIFtpc29PcmRpbmFsV2l0aFRpbWVFeHRlbnNpb25SZWdleCwgZXh0cmFjdElTT09yZGluYWxEYXRlQW5kVGltZV0sXG4gICAgW2lzb1RpbWVDb21iaW5lZFJlZ2V4LCBleHRyYWN0SVNPVGltZUFuZE9mZnNldF1cbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUkZDMjgyMkRhdGUocykge1xuICByZXR1cm4gcGFyc2UocHJlcHJvY2Vzc1JGQzI4MjIocyksIFtyZmMyODIyLCBleHRyYWN0UkZDMjgyMl0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VIVFRQRGF0ZShzKSB7XG4gIHJldHVybiBwYXJzZShcbiAgICBzLFxuICAgIFtyZmMxMTIzLCBleHRyYWN0UkZDMTEyM09yODUwXSxcbiAgICBbcmZjODUwLCBleHRyYWN0UkZDMTEyM09yODUwXSxcbiAgICBbYXNjaWksIGV4dHJhY3RBU0NJSV1cbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlSVNPRHVyYXRpb24ocykge1xuICByZXR1cm4gcGFyc2UocywgW2lzb0R1cmF0aW9uLCBleHRyYWN0SVNPRHVyYXRpb25dKTtcbn1cblxuY29uc3QgZXh0cmFjdElTT1RpbWVPbmx5ID0gY29tYmluZUV4dHJhY3RvcnMoZXh0cmFjdElTT1RpbWUpO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VJU09UaW1lT25seShzKSB7XG4gIHJldHVybiBwYXJzZShzLCBbaXNvVGltZU9ubHksIGV4dHJhY3RJU09UaW1lT25seV0pO1xufVxuXG5jb25zdCBzcWxZbWRXaXRoVGltZUV4dGVuc2lvblJlZ2V4ID0gY29tYmluZVJlZ2V4ZXMoc3FsWW1kUmVnZXgsIHNxbFRpbWVFeHRlbnNpb25SZWdleCk7XG5jb25zdCBzcWxUaW1lQ29tYmluZWRSZWdleCA9IGNvbWJpbmVSZWdleGVzKHNxbFRpbWVSZWdleCk7XG5cbmNvbnN0IGV4dHJhY3RJU09UaW1lT2Zmc2V0QW5kSUFOQVpvbmUgPSBjb21iaW5lRXh0cmFjdG9ycyhcbiAgZXh0cmFjdElTT1RpbWUsXG4gIGV4dHJhY3RJU09PZmZzZXQsXG4gIGV4dHJhY3RJQU5BWm9uZVxuKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU1FMKHMpIHtcbiAgcmV0dXJuIHBhcnNlKFxuICAgIHMsXG4gICAgW3NxbFltZFdpdGhUaW1lRXh0ZW5zaW9uUmVnZXgsIGV4dHJhY3RJU09ZbWRUaW1lQW5kT2Zmc2V0XSxcbiAgICBbc3FsVGltZUNvbWJpbmVkUmVnZXgsIGV4dHJhY3RJU09UaW1lT2Zmc2V0QW5kSUFOQVpvbmVdXG4gICk7XG59XG4iLCAiaW1wb3J0IHsgSW52YWxpZEFyZ3VtZW50RXJyb3IsIEludmFsaWREdXJhdGlvbkVycm9yLCBJbnZhbGlkVW5pdEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5pbXBvcnQgRm9ybWF0dGVyIGZyb20gXCIuL2ltcGwvZm9ybWF0dGVyLmpzXCI7XG5pbXBvcnQgSW52YWxpZCBmcm9tIFwiLi9pbXBsL2ludmFsaWQuanNcIjtcbmltcG9ydCBMb2NhbGUgZnJvbSBcIi4vaW1wbC9sb2NhbGUuanNcIjtcbmltcG9ydCB7IHBhcnNlSVNPRHVyYXRpb24sIHBhcnNlSVNPVGltZU9ubHkgfSBmcm9tIFwiLi9pbXBsL3JlZ2V4UGFyc2VyLmpzXCI7XG5pbXBvcnQge1xuICBhc051bWJlcixcbiAgaGFzT3duUHJvcGVydHksXG4gIGlzTnVtYmVyLFxuICBpc1VuZGVmaW5lZCxcbiAgbm9ybWFsaXplT2JqZWN0LFxuICByb3VuZFRvLFxufSBmcm9tIFwiLi9pbXBsL3V0aWwuanNcIjtcbmltcG9ydCBTZXR0aW5ncyBmcm9tIFwiLi9zZXR0aW5ncy5qc1wiO1xuaW1wb3J0IERhdGVUaW1lIGZyb20gXCIuL2RhdGV0aW1lLmpzXCI7XG5cbmNvbnN0IElOVkFMSUQgPSBcIkludmFsaWQgRHVyYXRpb25cIjtcblxuLy8gdW5pdCBjb252ZXJzaW9uIGNvbnN0YW50c1xuZXhwb3J0IGNvbnN0IGxvd09yZGVyTWF0cml4ID0ge1xuICAgIHdlZWtzOiB7XG4gICAgICBkYXlzOiA3LFxuICAgICAgaG91cnM6IDcgKiAyNCxcbiAgICAgIG1pbnV0ZXM6IDcgKiAyNCAqIDYwLFxuICAgICAgc2Vjb25kczogNyAqIDI0ICogNjAgKiA2MCxcbiAgICAgIG1pbGxpc2Vjb25kczogNyAqIDI0ICogNjAgKiA2MCAqIDEwMDAsXG4gICAgfSxcbiAgICBkYXlzOiB7XG4gICAgICBob3VyczogMjQsXG4gICAgICBtaW51dGVzOiAyNCAqIDYwLFxuICAgICAgc2Vjb25kczogMjQgKiA2MCAqIDYwLFxuICAgICAgbWlsbGlzZWNvbmRzOiAyNCAqIDYwICogNjAgKiAxMDAwLFxuICAgIH0sXG4gICAgaG91cnM6IHsgbWludXRlczogNjAsIHNlY29uZHM6IDYwICogNjAsIG1pbGxpc2Vjb25kczogNjAgKiA2MCAqIDEwMDAgfSxcbiAgICBtaW51dGVzOiB7IHNlY29uZHM6IDYwLCBtaWxsaXNlY29uZHM6IDYwICogMTAwMCB9LFxuICAgIHNlY29uZHM6IHsgbWlsbGlzZWNvbmRzOiAxMDAwIH0sXG4gIH0sXG4gIGNhc3VhbE1hdHJpeCA9IHtcbiAgICB5ZWFyczoge1xuICAgICAgcXVhcnRlcnM6IDQsXG4gICAgICBtb250aHM6IDEyLFxuICAgICAgd2Vla3M6IDUyLFxuICAgICAgZGF5czogMzY1LFxuICAgICAgaG91cnM6IDM2NSAqIDI0LFxuICAgICAgbWludXRlczogMzY1ICogMjQgKiA2MCxcbiAgICAgIHNlY29uZHM6IDM2NSAqIDI0ICogNjAgKiA2MCxcbiAgICAgIG1pbGxpc2Vjb25kczogMzY1ICogMjQgKiA2MCAqIDYwICogMTAwMCxcbiAgICB9LFxuICAgIHF1YXJ0ZXJzOiB7XG4gICAgICBtb250aHM6IDMsXG4gICAgICB3ZWVrczogMTMsXG4gICAgICBkYXlzOiA5MSxcbiAgICAgIGhvdXJzOiA5MSAqIDI0LFxuICAgICAgbWludXRlczogOTEgKiAyNCAqIDYwLFxuICAgICAgc2Vjb25kczogOTEgKiAyNCAqIDYwICogNjAsXG4gICAgICBtaWxsaXNlY29uZHM6IDkxICogMjQgKiA2MCAqIDYwICogMTAwMCxcbiAgICB9LFxuICAgIG1vbnRoczoge1xuICAgICAgd2Vla3M6IDQsXG4gICAgICBkYXlzOiAzMCxcbiAgICAgIGhvdXJzOiAzMCAqIDI0LFxuICAgICAgbWludXRlczogMzAgKiAyNCAqIDYwLFxuICAgICAgc2Vjb25kczogMzAgKiAyNCAqIDYwICogNjAsXG4gICAgICBtaWxsaXNlY29uZHM6IDMwICogMjQgKiA2MCAqIDYwICogMTAwMCxcbiAgICB9LFxuXG4gICAgLi4ubG93T3JkZXJNYXRyaXgsXG4gIH0sXG4gIGRheXNJblllYXJBY2N1cmF0ZSA9IDE0NjA5Ny4wIC8gNDAwLFxuICBkYXlzSW5Nb250aEFjY3VyYXRlID0gMTQ2MDk3LjAgLyA0ODAwLFxuICBhY2N1cmF0ZU1hdHJpeCA9IHtcbiAgICB5ZWFyczoge1xuICAgICAgcXVhcnRlcnM6IDQsXG4gICAgICBtb250aHM6IDEyLFxuICAgICAgd2Vla3M6IGRheXNJblllYXJBY2N1cmF0ZSAvIDcsXG4gICAgICBkYXlzOiBkYXlzSW5ZZWFyQWNjdXJhdGUsXG4gICAgICBob3VyczogZGF5c0luWWVhckFjY3VyYXRlICogMjQsXG4gICAgICBtaW51dGVzOiBkYXlzSW5ZZWFyQWNjdXJhdGUgKiAyNCAqIDYwLFxuICAgICAgc2Vjb25kczogZGF5c0luWWVhckFjY3VyYXRlICogMjQgKiA2MCAqIDYwLFxuICAgICAgbWlsbGlzZWNvbmRzOiBkYXlzSW5ZZWFyQWNjdXJhdGUgKiAyNCAqIDYwICogNjAgKiAxMDAwLFxuICAgIH0sXG4gICAgcXVhcnRlcnM6IHtcbiAgICAgIG1vbnRoczogMyxcbiAgICAgIHdlZWtzOiBkYXlzSW5ZZWFyQWNjdXJhdGUgLyAyOCxcbiAgICAgIGRheXM6IGRheXNJblllYXJBY2N1cmF0ZSAvIDQsXG4gICAgICBob3VyczogKGRheXNJblllYXJBY2N1cmF0ZSAqIDI0KSAvIDQsXG4gICAgICBtaW51dGVzOiAoZGF5c0luWWVhckFjY3VyYXRlICogMjQgKiA2MCkgLyA0LFxuICAgICAgc2Vjb25kczogKGRheXNJblllYXJBY2N1cmF0ZSAqIDI0ICogNjAgKiA2MCkgLyA0LFxuICAgICAgbWlsbGlzZWNvbmRzOiAoZGF5c0luWWVhckFjY3VyYXRlICogMjQgKiA2MCAqIDYwICogMTAwMCkgLyA0LFxuICAgIH0sXG4gICAgbW9udGhzOiB7XG4gICAgICB3ZWVrczogZGF5c0luTW9udGhBY2N1cmF0ZSAvIDcsXG4gICAgICBkYXlzOiBkYXlzSW5Nb250aEFjY3VyYXRlLFxuICAgICAgaG91cnM6IGRheXNJbk1vbnRoQWNjdXJhdGUgKiAyNCxcbiAgICAgIG1pbnV0ZXM6IGRheXNJbk1vbnRoQWNjdXJhdGUgKiAyNCAqIDYwLFxuICAgICAgc2Vjb25kczogZGF5c0luTW9udGhBY2N1cmF0ZSAqIDI0ICogNjAgKiA2MCxcbiAgICAgIG1pbGxpc2Vjb25kczogZGF5c0luTW9udGhBY2N1cmF0ZSAqIDI0ICogNjAgKiA2MCAqIDEwMDAsXG4gICAgfSxcbiAgICAuLi5sb3dPcmRlck1hdHJpeCxcbiAgfTtcblxuLy8gdW5pdHMgb3JkZXJlZCBieSBzaXplXG5jb25zdCBvcmRlcmVkVW5pdHMgPSBbXG4gIFwieWVhcnNcIixcbiAgXCJxdWFydGVyc1wiLFxuICBcIm1vbnRoc1wiLFxuICBcIndlZWtzXCIsXG4gIFwiZGF5c1wiLFxuICBcImhvdXJzXCIsXG4gIFwibWludXRlc1wiLFxuICBcInNlY29uZHNcIixcbiAgXCJtaWxsaXNlY29uZHNcIixcbl07XG5cbmNvbnN0IHJldmVyc2VVbml0cyA9IG9yZGVyZWRVbml0cy5zbGljZSgwKS5yZXZlcnNlKCk7XG5cbi8vIGNsb25lIHJlYWxseSBtZWFucyBcImNyZWF0ZSBhbm90aGVyIGluc3RhbmNlIGp1c3QgbGlrZSB0aGlzIG9uZSwgYnV0IHdpdGggdGhlc2UgY2hhbmdlc1wiXG5mdW5jdGlvbiBjbG9uZShkdXIsIGFsdHMsIGNsZWFyID0gZmFsc2UpIHtcbiAgLy8gZGVlcCBtZXJnZSBmb3IgdmFsc1xuICBjb25zdCBjb25mID0ge1xuICAgIHZhbHVlczogY2xlYXIgPyBhbHRzLnZhbHVlcyA6IHsgLi4uZHVyLnZhbHVlcywgLi4uKGFsdHMudmFsdWVzIHx8IHt9KSB9LFxuICAgIGxvYzogZHVyLmxvYy5jbG9uZShhbHRzLmxvYyksXG4gICAgY29udmVyc2lvbkFjY3VyYWN5OiBhbHRzLmNvbnZlcnNpb25BY2N1cmFjeSB8fCBkdXIuY29udmVyc2lvbkFjY3VyYWN5LFxuICAgIG1hdHJpeDogYWx0cy5tYXRyaXggfHwgZHVyLm1hdHJpeCxcbiAgfTtcbiAgcmV0dXJuIG5ldyBEdXJhdGlvbihjb25mKTtcbn1cblxuZnVuY3Rpb24gZHVyYXRpb25Ub01pbGxpcyhtYXRyaXgsIHZhbHMpIHtcbiAgbGV0IHN1bSA9IHZhbHMubWlsbGlzZWNvbmRzID8/IDA7XG4gIGZvciAoY29uc3QgdW5pdCBvZiByZXZlcnNlVW5pdHMuc2xpY2UoMSkpIHtcbiAgICBpZiAodmFsc1t1bml0XSkge1xuICAgICAgc3VtICs9IHZhbHNbdW5pdF0gKiBtYXRyaXhbdW5pdF1bXCJtaWxsaXNlY29uZHNcIl07XG4gICAgfVxuICB9XG4gIHJldHVybiBzdW07XG59XG5cbi8vIE5COiBtdXRhdGVzIHBhcmFtZXRlcnNcbmZ1bmN0aW9uIG5vcm1hbGl6ZVZhbHVlcyhtYXRyaXgsIHZhbHMpIHtcbiAgLy8gdGhlIGxvZ2ljIGJlbG93IGFzc3VtZXMgdGhlIG92ZXJhbGwgdmFsdWUgb2YgdGhlIGR1cmF0aW9uIGlzIHBvc2l0aXZlXG4gIC8vIGlmIHRoaXMgaXMgbm90IHRoZSBjYXNlLCBmYWN0b3IgaXMgdXNlZCB0byBtYWtlIGl0IHNvXG4gIGNvbnN0IGZhY3RvciA9IGR1cmF0aW9uVG9NaWxsaXMobWF0cml4LCB2YWxzKSA8IDAgPyAtMSA6IDE7XG5cbiAgb3JkZXJlZFVuaXRzLnJlZHVjZVJpZ2h0KChwcmV2aW91cywgY3VycmVudCkgPT4ge1xuICAgIGlmICghaXNVbmRlZmluZWQodmFsc1tjdXJyZW50XSkpIHtcbiAgICAgIGlmIChwcmV2aW91cykge1xuICAgICAgICBjb25zdCBwcmV2aW91c1ZhbCA9IHZhbHNbcHJldmlvdXNdICogZmFjdG9yO1xuICAgICAgICBjb25zdCBjb252ID0gbWF0cml4W2N1cnJlbnRdW3ByZXZpb3VzXTtcblxuICAgICAgICAvLyBpZiAocHJldmlvdXNWYWwgPCAwKTpcbiAgICAgICAgLy8gbG93ZXIgb3JkZXIgdW5pdCBpcyBuZWdhdGl2ZSAoZS5nLiB7IHllYXJzOiAyLCBkYXlzOiAtMiB9KVxuICAgICAgICAvLyBub3JtYWxpemUgdGhpcyBieSByZWR1Y2luZyB0aGUgaGlnaGVyIG9yZGVyIHVuaXQgYnkgdGhlIGFwcHJvcHJpYXRlIGFtb3VudFxuICAgICAgICAvLyBhbmQgaW5jcmVhc2luZyB0aGUgbG93ZXIgb3JkZXIgdW5pdFxuICAgICAgICAvLyB0aGlzIGNhbiBuZXZlciBtYWtlIHRoZSBoaWdoZXIgb3JkZXIgdW5pdCBuZWdhdGl2ZSwgYmVjYXVzZSB0aGlzIGZ1bmN0aW9uIG9ubHkgb3BlcmF0ZXNcbiAgICAgICAgLy8gb24gcG9zaXRpdmUgZHVyYXRpb25zLCBzbyB0aGUgYW1vdW50IG9mIHRpbWUgcmVwcmVzZW50ZWQgYnkgdGhlIGxvd2VyIG9yZGVyIHVuaXQgY2Fubm90XG4gICAgICAgIC8vIGJlIGxhcmdlciB0aGFuIHRoZSBoaWdoZXIgb3JkZXIgdW5pdFxuICAgICAgICAvLyBlbHNlOlxuICAgICAgICAvLyBsb3dlciBvcmRlciB1bml0IGlzIHBvc2l0aXZlIChlLmcuIHsgeWVhcnM6IDIsIGRheXM6IDQ1MCB9IG9yIHsgeWVhcnM6IC0yLCBkYXlzOiA0NTAgfSlcbiAgICAgICAgLy8gaW4gdGhpcyBjYXNlIHdlIGF0dGVtcHQgdG8gY29udmVydCBhcyBtdWNoIGFzIHBvc3NpYmxlIGZyb20gdGhlIGxvd2VyIG9yZGVyIHVuaXQgaW50b1xuICAgICAgICAvLyB0aGUgaGlnaGVyIG9yZGVyIG9uZVxuICAgICAgICAvL1xuICAgICAgICAvLyBNYXRoLmZsb29yIHRha2VzIGNhcmUgb2YgYm90aCBvZiB0aGVzZSBjYXNlcywgcm91bmRpbmcgYXdheSBmcm9tIDBcbiAgICAgICAgLy8gaWYgcHJldmlvdXNWYWwgPCAwIGl0IG1ha2VzIHRoZSBhYnNvbHV0ZSB2YWx1ZSBsYXJnZXJcbiAgICAgICAgLy8gaWYgcHJldmlvdXNWYWwgPj0gaXQgbWFrZXMgdGhlIGFic29sdXRlIHZhbHVlIHNtYWxsZXJcbiAgICAgICAgY29uc3Qgcm9sbFVwID0gTWF0aC5mbG9vcihwcmV2aW91c1ZhbCAvIGNvbnYpO1xuICAgICAgICB2YWxzW2N1cnJlbnRdICs9IHJvbGxVcCAqIGZhY3RvcjtcbiAgICAgICAgdmFsc1twcmV2aW91c10gLT0gcm9sbFVwICogY29udiAqIGZhY3RvcjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjdXJyZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcHJldmlvdXM7XG4gICAgfVxuICB9LCBudWxsKTtcblxuICAvLyB0cnkgdG8gY29udmVydCBhbnkgZGVjaW1hbHMgaW50byBzbWFsbGVyIHVuaXRzIGlmIHBvc3NpYmxlXG4gIC8vIGZvciBleGFtcGxlIGZvciB7IHllYXJzOiAyLjUsIGRheXM6IDAsIHNlY29uZHM6IDAgfSB3ZSB3YW50IHRvIGdldCB7IHllYXJzOiAyLCBkYXlzOiAxODIsIGhvdXJzOiAxMiB9XG4gIG9yZGVyZWRVbml0cy5yZWR1Y2UoKHByZXZpb3VzLCBjdXJyZW50KSA9PiB7XG4gICAgaWYgKCFpc1VuZGVmaW5lZCh2YWxzW2N1cnJlbnRdKSkge1xuICAgICAgaWYgKHByZXZpb3VzKSB7XG4gICAgICAgIGNvbnN0IGZyYWN0aW9uID0gdmFsc1twcmV2aW91c10gJSAxO1xuICAgICAgICB2YWxzW3ByZXZpb3VzXSAtPSBmcmFjdGlvbjtcbiAgICAgICAgdmFsc1tjdXJyZW50XSArPSBmcmFjdGlvbiAqIG1hdHJpeFtwcmV2aW91c11bY3VycmVudF07XG4gICAgICB9XG4gICAgICByZXR1cm4gY3VycmVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHByZXZpb3VzO1xuICAgIH1cbiAgfSwgbnVsbCk7XG59XG5cbi8vIFJlbW92ZSBhbGwgcHJvcGVydGllcyB3aXRoIGEgdmFsdWUgb2YgMCBmcm9tIGFuIG9iamVjdFxuZnVuY3Rpb24gcmVtb3ZlWmVyb2VzKHZhbHMpIHtcbiAgY29uc3QgbmV3VmFscyA9IHt9O1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh2YWxzKSkge1xuICAgIGlmICh2YWx1ZSAhPT0gMCkge1xuICAgICAgbmV3VmFsc1trZXldID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXdWYWxzO1xufVxuXG4vKipcbiAqIEEgRHVyYXRpb24gb2JqZWN0IHJlcHJlc2VudHMgYSBwZXJpb2Qgb2YgdGltZSwgbGlrZSBcIjIgbW9udGhzXCIgb3IgXCIxIGRheSwgMSBob3VyXCIuIENvbmNlcHR1YWxseSwgaXQncyBqdXN0IGEgbWFwIG9mIHVuaXRzIHRvIHRoZWlyIHF1YW50aXRpZXMsIGFjY29tcGFuaWVkIGJ5IHNvbWUgYWRkaXRpb25hbCBjb25maWd1cmF0aW9uIGFuZCBtZXRob2RzIGZvciBjcmVhdGluZywgcGFyc2luZywgaW50ZXJyb2dhdGluZywgdHJhbnNmb3JtaW5nLCBhbmQgZm9ybWF0dGluZyB0aGVtLiBUaGV5IGNhbiBiZSB1c2VkIG9uIHRoZWlyIG93biBvciBpbiBjb25qdW5jdGlvbiB3aXRoIG90aGVyIEx1eG9uIHR5cGVzOyBmb3IgZXhhbXBsZSwgeW91IGNhbiB1c2Uge0BsaW5rIERhdGVUaW1lI3BsdXN9IHRvIGFkZCBhIER1cmF0aW9uIG9iamVjdCB0byBhIERhdGVUaW1lLCBwcm9kdWNpbmcgYW5vdGhlciBEYXRlVGltZS5cbiAqXG4gKiBIZXJlIGlzIGEgYnJpZWYgb3ZlcnZpZXcgb2YgY29tbW9ubHkgdXNlZCBtZXRob2RzIGFuZCBnZXR0ZXJzIGluIER1cmF0aW9uOlxuICpcbiAqICogKipDcmVhdGlvbioqIFRvIGNyZWF0ZSBhIER1cmF0aW9uLCB1c2Uge0BsaW5rIER1cmF0aW9uLmZyb21NaWxsaXN9LCB7QGxpbmsgRHVyYXRpb24uZnJvbU9iamVjdH0sIG9yIHtAbGluayBEdXJhdGlvbi5mcm9tSVNPfS5cbiAqICogKipVbml0IHZhbHVlcyoqIFNlZSB0aGUge0BsaW5rIER1cmF0aW9uI3llYXJzfSwge0BsaW5rIER1cmF0aW9uI21vbnRoc30sIHtAbGluayBEdXJhdGlvbiN3ZWVrc30sIHtAbGluayBEdXJhdGlvbiNkYXlzfSwge0BsaW5rIER1cmF0aW9uI2hvdXJzfSwge0BsaW5rIER1cmF0aW9uI21pbnV0ZXN9LCB7QGxpbmsgRHVyYXRpb24jc2Vjb25kc30sIHtAbGluayBEdXJhdGlvbiNtaWxsaXNlY29uZHN9IGFjY2Vzc29ycy5cbiAqICogKipDb25maWd1cmF0aW9uKiogU2VlICB7QGxpbmsgRHVyYXRpb24jbG9jYWxlfSBhbmQge0BsaW5rIER1cmF0aW9uI251bWJlcmluZ1N5c3RlbX0gYWNjZXNzb3JzLlxuICogKiAqKlRyYW5zZm9ybWF0aW9uKiogVG8gY3JlYXRlIG5ldyBEdXJhdGlvbnMgb3V0IG9mIG9sZCBvbmVzIHVzZSB7QGxpbmsgRHVyYXRpb24jcGx1c30sIHtAbGluayBEdXJhdGlvbiNtaW51c30sIHtAbGluayBEdXJhdGlvbiNub3JtYWxpemV9LCB7QGxpbmsgRHVyYXRpb24jc2V0fSwge0BsaW5rIER1cmF0aW9uI3JlY29uZmlndXJlfSwge0BsaW5rIER1cmF0aW9uI3NoaWZ0VG99LCBhbmQge0BsaW5rIER1cmF0aW9uI25lZ2F0ZX0uXG4gKiAqICoqT3V0cHV0KiogVG8gY29udmVydCB0aGUgRHVyYXRpb24gaW50byBvdGhlciByZXByZXNlbnRhdGlvbnMsIHNlZSB7QGxpbmsgRHVyYXRpb24jYXN9LCB7QGxpbmsgRHVyYXRpb24jdG9JU099LCB7QGxpbmsgRHVyYXRpb24jdG9Gb3JtYXR9LCBhbmQge0BsaW5rIER1cmF0aW9uI3RvSlNPTn1cbiAqXG4gKiBUaGVyZSdzIGFyZSBtb3JlIG1ldGhvZHMgZG9jdW1lbnRlZCBiZWxvdy4gSW4gYWRkaXRpb24sIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHN1YnRsZXIgdG9waWNzIGxpa2UgaW50ZXJuYXRpb25hbGl6YXRpb24gYW5kIHZhbGlkaXR5LCBzZWUgdGhlIGV4dGVybmFsIGRvY3VtZW50YXRpb24uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIER1cmF0aW9uIHtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWcpIHtcbiAgICBjb25zdCBhY2N1cmF0ZSA9IGNvbmZpZy5jb252ZXJzaW9uQWNjdXJhY3kgPT09IFwibG9uZ3Rlcm1cIiB8fCBmYWxzZTtcbiAgICBsZXQgbWF0cml4ID0gYWNjdXJhdGUgPyBhY2N1cmF0ZU1hdHJpeCA6IGNhc3VhbE1hdHJpeDtcblxuICAgIGlmIChjb25maWcubWF0cml4KSB7XG4gICAgICBtYXRyaXggPSBjb25maWcubWF0cml4O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMudmFsdWVzID0gY29uZmlnLnZhbHVlcztcbiAgICAvKipcbiAgICAgKiBAYWNjZXNzIHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLmxvYyA9IGNvbmZpZy5sb2MgfHwgTG9jYWxlLmNyZWF0ZSgpO1xuICAgIC8qKlxuICAgICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMuY29udmVyc2lvbkFjY3VyYWN5ID0gYWNjdXJhdGUgPyBcImxvbmd0ZXJtXCIgOiBcImNhc3VhbFwiO1xuICAgIC8qKlxuICAgICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMuaW52YWxpZCA9IGNvbmZpZy5pbnZhbGlkIHx8IG51bGw7XG4gICAgLyoqXG4gICAgICogQGFjY2VzcyBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5tYXRyaXggPSBtYXRyaXg7XG4gICAgLyoqXG4gICAgICogQGFjY2VzcyBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5pc0x1eG9uRHVyYXRpb24gPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBEdXJhdGlvbiBmcm9tIGEgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IG9mIG1pbGxpc2Vjb25kc1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnMgZm9yIHBhcnNpbmdcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY2FsZT0nZW4tVVMnXSAtIHRoZSBsb2NhbGUgdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLm51bWJlcmluZ1N5c3RlbSAtIHRoZSBudW1iZXJpbmcgc3lzdGVtIHRvIHVzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuY29udmVyc2lvbkFjY3VyYWN5PSdjYXN1YWwnXSAtIHRoZSBjb252ZXJzaW9uIHN5c3RlbSB0byB1c2VcbiAgICogQHJldHVybiB7RHVyYXRpb259XG4gICAqL1xuICBzdGF0aWMgZnJvbU1pbGxpcyhjb3VudCwgb3B0cykge1xuICAgIHJldHVybiBEdXJhdGlvbi5mcm9tT2JqZWN0KHsgbWlsbGlzZWNvbmRzOiBjb3VudCB9LCBvcHRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBEdXJhdGlvbiBmcm9tIGEgSmF2YVNjcmlwdCBvYmplY3Qgd2l0aCBrZXlzIGxpa2UgJ3llYXJzJyBhbmQgJ2hvdXJzJy5cbiAgICogSWYgdGhpcyBvYmplY3QgaXMgZW1wdHkgdGhlbiBhIHplcm8gbWlsbGlzZWNvbmRzIGR1cmF0aW9uIGlzIHJldHVybmVkLlxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqIC0gdGhlIG9iamVjdCB0byBjcmVhdGUgdGhlIERhdGVUaW1lIGZyb21cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9iai55ZWFyc1xuICAgKiBAcGFyYW0ge251bWJlcn0gb2JqLnF1YXJ0ZXJzXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoubW9udGhzXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoud2Vla3NcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9iai5kYXlzXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmouaG91cnNcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9iai5taW51dGVzXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmouc2Vjb25kc1xuICAgKiBAcGFyYW0ge251bWJlcn0gb2JqLm1pbGxpc2Vjb25kc1xuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdHM9W11dIC0gb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGhpcyBEdXJhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubG9jYWxlPSdlbi1VUyddIC0gdGhlIGxvY2FsZSB0byB1c2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wdHMubnVtYmVyaW5nU3lzdGVtIC0gdGhlIG51bWJlcmluZyBzeXN0ZW0gdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5jb252ZXJzaW9uQWNjdXJhY3k9J2Nhc3VhbCddIC0gdGhlIHByZXNldCBjb252ZXJzaW9uIHN5c3RlbSB0byB1c2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLm1hdHJpeD1PYmplY3RdIC0gdGhlIGN1c3RvbSBjb252ZXJzaW9uIHN5c3RlbSB0byB1c2VcbiAgICogQHJldHVybiB7RHVyYXRpb259XG4gICAqL1xuICBzdGF0aWMgZnJvbU9iamVjdChvYmosIG9wdHMgPSB7fSkge1xuICAgIGlmIChvYmogPT0gbnVsbCB8fCB0eXBlb2Ygb2JqICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3IoXG4gICAgICAgIGBEdXJhdGlvbi5mcm9tT2JqZWN0OiBhcmd1bWVudCBleHBlY3RlZCB0byBiZSBhbiBvYmplY3QsIGdvdCAke1xuICAgICAgICAgIG9iaiA9PT0gbnVsbCA/IFwibnVsbFwiIDogdHlwZW9mIG9ialxuICAgICAgICB9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IER1cmF0aW9uKHtcbiAgICAgIHZhbHVlczogbm9ybWFsaXplT2JqZWN0KG9iaiwgRHVyYXRpb24ubm9ybWFsaXplVW5pdCksXG4gICAgICBsb2M6IExvY2FsZS5mcm9tT2JqZWN0KG9wdHMpLFxuICAgICAgY29udmVyc2lvbkFjY3VyYWN5OiBvcHRzLmNvbnZlcnNpb25BY2N1cmFjeSxcbiAgICAgIG1hdHJpeDogb3B0cy5tYXRyaXgsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRHVyYXRpb24gZnJvbSBEdXJhdGlvbkxpa2UuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0IHwgbnVtYmVyIHwgRHVyYXRpb259IGR1cmF0aW9uTGlrZVxuICAgKiBPbmUgb2Y6XG4gICAqIC0gb2JqZWN0IHdpdGgga2V5cyBsaWtlICd5ZWFycycgYW5kICdob3VycycuXG4gICAqIC0gbnVtYmVyIHJlcHJlc2VudGluZyBtaWxsaXNlY29uZHNcbiAgICogLSBEdXJhdGlvbiBpbnN0YW5jZVxuICAgKiBAcmV0dXJuIHtEdXJhdGlvbn1cbiAgICovXG4gIHN0YXRpYyBmcm9tRHVyYXRpb25MaWtlKGR1cmF0aW9uTGlrZSkge1xuICAgIGlmIChpc051bWJlcihkdXJhdGlvbkxpa2UpKSB7XG4gICAgICByZXR1cm4gRHVyYXRpb24uZnJvbU1pbGxpcyhkdXJhdGlvbkxpa2UpO1xuICAgIH0gZWxzZSBpZiAoRHVyYXRpb24uaXNEdXJhdGlvbihkdXJhdGlvbkxpa2UpKSB7XG4gICAgICByZXR1cm4gZHVyYXRpb25MaWtlO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGR1cmF0aW9uTGlrZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIER1cmF0aW9uLmZyb21PYmplY3QoZHVyYXRpb25MaWtlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKFxuICAgICAgICBgVW5rbm93biBkdXJhdGlvbiBhcmd1bWVudCAke2R1cmF0aW9uTGlrZX0gb2YgdHlwZSAke3R5cGVvZiBkdXJhdGlvbkxpa2V9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRHVyYXRpb24gZnJvbSBhbiBJU08gODYwMSBkdXJhdGlvbiBzdHJpbmcuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gdGV4dCB0byBwYXJzZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnMgZm9yIHBhcnNpbmdcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY2FsZT0nZW4tVVMnXSAtIHRoZSBsb2NhbGUgdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLm51bWJlcmluZ1N5c3RlbSAtIHRoZSBudW1iZXJpbmcgc3lzdGVtIHRvIHVzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuY29udmVyc2lvbkFjY3VyYWN5PSdjYXN1YWwnXSAtIHRoZSBwcmVzZXQgY29udmVyc2lvbiBzeXN0ZW0gdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5tYXRyaXg9T2JqZWN0XSAtIHRoZSBwcmVzZXQgY29udmVyc2lvbiBzeXN0ZW0gdG8gdXNlXG4gICAqIEBzZWUgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPXzg2MDEjRHVyYXRpb25zXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21JU08oJ1AzWTZNMVc0RFQxMkgzME01UycpLnRvT2JqZWN0KCkgLy89PiB7IHllYXJzOiAzLCBtb250aHM6IDYsIHdlZWtzOiAxLCBkYXlzOiA0LCBob3VyczogMTIsIG1pbnV0ZXM6IDMwLCBzZWNvbmRzOiA1IH1cbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbUlTTygnUFQyM0gnKS50b09iamVjdCgpIC8vPT4geyBob3VyczogMjMgfVxuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tSVNPKCdQNVkzTScpLnRvT2JqZWN0KCkgLy89PiB7IHllYXJzOiA1LCBtb250aHM6IDMgfVxuICAgKiBAcmV0dXJuIHtEdXJhdGlvbn1cbiAgICovXG4gIHN0YXRpYyBmcm9tSVNPKHRleHQsIG9wdHMpIHtcbiAgICBjb25zdCBbcGFyc2VkXSA9IHBhcnNlSVNPRHVyYXRpb24odGV4dCk7XG4gICAgaWYgKHBhcnNlZCkge1xuICAgICAgcmV0dXJuIER1cmF0aW9uLmZyb21PYmplY3QocGFyc2VkLCBvcHRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIER1cmF0aW9uLmludmFsaWQoXCJ1bnBhcnNhYmxlXCIsIGB0aGUgaW5wdXQgXCIke3RleHR9XCIgY2FuJ3QgYmUgcGFyc2VkIGFzIElTTyA4NjAxYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIER1cmF0aW9uIGZyb20gYW4gSVNPIDg2MDEgdGltZSBzdHJpbmcuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gdGV4dCB0byBwYXJzZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnMgZm9yIHBhcnNpbmdcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY2FsZT0nZW4tVVMnXSAtIHRoZSBsb2NhbGUgdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLm51bWJlcmluZ1N5c3RlbSAtIHRoZSBudW1iZXJpbmcgc3lzdGVtIHRvIHVzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuY29udmVyc2lvbkFjY3VyYWN5PSdjYXN1YWwnXSAtIHRoZSBwcmVzZXQgY29udmVyc2lvbiBzeXN0ZW0gdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5tYXRyaXg9T2JqZWN0XSAtIHRoZSBjb252ZXJzaW9uIHN5c3RlbSB0byB1c2VcbiAgICogQHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSNUaW1lc1xuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tSVNPVGltZSgnMTE6MjI6MzMuNDQ0JykudG9PYmplY3QoKSAvLz0+IHsgaG91cnM6IDExLCBtaW51dGVzOiAyMiwgc2Vjb25kczogMzMsIG1pbGxpc2Vjb25kczogNDQ0IH1cbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbUlTT1RpbWUoJzExOjAwJykudG9PYmplY3QoKSAvLz0+IHsgaG91cnM6IDExLCBtaW51dGVzOiAwLCBzZWNvbmRzOiAwIH1cbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbUlTT1RpbWUoJ1QxMTowMCcpLnRvT2JqZWN0KCkgLy89PiB7IGhvdXJzOiAxMSwgbWludXRlczogMCwgc2Vjb25kczogMCB9XG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21JU09UaW1lKCcxMTAwJykudG9PYmplY3QoKSAvLz0+IHsgaG91cnM6IDExLCBtaW51dGVzOiAwLCBzZWNvbmRzOiAwIH1cbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbUlTT1RpbWUoJ1QxMTAwJykudG9PYmplY3QoKSAvLz0+IHsgaG91cnM6IDExLCBtaW51dGVzOiAwLCBzZWNvbmRzOiAwIH1cbiAgICogQHJldHVybiB7RHVyYXRpb259XG4gICAqL1xuICBzdGF0aWMgZnJvbUlTT1RpbWUodGV4dCwgb3B0cykge1xuICAgIGNvbnN0IFtwYXJzZWRdID0gcGFyc2VJU09UaW1lT25seSh0ZXh0KTtcbiAgICBpZiAocGFyc2VkKSB7XG4gICAgICByZXR1cm4gRHVyYXRpb24uZnJvbU9iamVjdChwYXJzZWQsIG9wdHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gRHVyYXRpb24uaW52YWxpZChcInVucGFyc2FibGVcIiwgYHRoZSBpbnB1dCBcIiR7dGV4dH1cIiBjYW4ndCBiZSBwYXJzZWQgYXMgSVNPIDg2MDFgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIGludmFsaWQgRHVyYXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBzaW1wbGUgc3RyaW5nIG9mIHdoeSB0aGlzIGRhdGV0aW1lIGlzIGludmFsaWQuIFNob3VsZCBub3QgY29udGFpbiBwYXJhbWV0ZXJzIG9yIGFueXRoaW5nIGVsc2UgZGF0YS1kZXBlbmRlbnRcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtleHBsYW5hdGlvbj1udWxsXSAtIGxvbmdlciBleHBsYW5hdGlvbiwgbWF5IGluY2x1ZGUgcGFyYW1ldGVycyBhbmQgb3RoZXIgdXNlZnVsIGRlYnVnZ2luZyBpbmZvcm1hdGlvblxuICAgKiBAcmV0dXJuIHtEdXJhdGlvbn1cbiAgICovXG4gIHN0YXRpYyBpbnZhbGlkKHJlYXNvbiwgZXhwbGFuYXRpb24gPSBudWxsKSB7XG4gICAgaWYgKCFyZWFzb24pIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcihcIm5lZWQgdG8gc3BlY2lmeSBhIHJlYXNvbiB0aGUgRHVyYXRpb24gaXMgaW52YWxpZFwiKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbnZhbGlkID0gcmVhc29uIGluc3RhbmNlb2YgSW52YWxpZCA/IHJlYXNvbiA6IG5ldyBJbnZhbGlkKHJlYXNvbiwgZXhwbGFuYXRpb24pO1xuXG4gICAgaWYgKFNldHRpbmdzLnRocm93T25JbnZhbGlkKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZER1cmF0aW9uRXJyb3IoaW52YWxpZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgRHVyYXRpb24oeyBpbnZhbGlkIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgc3RhdGljIG5vcm1hbGl6ZVVuaXQodW5pdCkge1xuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSB7XG4gICAgICB5ZWFyOiBcInllYXJzXCIsXG4gICAgICB5ZWFyczogXCJ5ZWFyc1wiLFxuICAgICAgcXVhcnRlcjogXCJxdWFydGVyc1wiLFxuICAgICAgcXVhcnRlcnM6IFwicXVhcnRlcnNcIixcbiAgICAgIG1vbnRoOiBcIm1vbnRoc1wiLFxuICAgICAgbW9udGhzOiBcIm1vbnRoc1wiLFxuICAgICAgd2VlazogXCJ3ZWVrc1wiLFxuICAgICAgd2Vla3M6IFwid2Vla3NcIixcbiAgICAgIGRheTogXCJkYXlzXCIsXG4gICAgICBkYXlzOiBcImRheXNcIixcbiAgICAgIGhvdXI6IFwiaG91cnNcIixcbiAgICAgIGhvdXJzOiBcImhvdXJzXCIsXG4gICAgICBtaW51dGU6IFwibWludXRlc1wiLFxuICAgICAgbWludXRlczogXCJtaW51dGVzXCIsXG4gICAgICBzZWNvbmQ6IFwic2Vjb25kc1wiLFxuICAgICAgc2Vjb25kczogXCJzZWNvbmRzXCIsXG4gICAgICBtaWxsaXNlY29uZDogXCJtaWxsaXNlY29uZHNcIixcbiAgICAgIG1pbGxpc2Vjb25kczogXCJtaWxsaXNlY29uZHNcIixcbiAgICB9W3VuaXQgPyB1bml0LnRvTG93ZXJDYXNlKCkgOiB1bml0XTtcblxuICAgIGlmICghbm9ybWFsaXplZCkgdGhyb3cgbmV3IEludmFsaWRVbml0RXJyb3IodW5pdCk7XG5cbiAgICByZXR1cm4gbm9ybWFsaXplZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhbiBvYmplY3QgaXMgYSBEdXJhdGlvbi4gV29ya3MgYWNyb3NzIGNvbnRleHQgYm91bmRhcmllc1xuICAgKiBAcGFyYW0ge29iamVjdH0gb1xuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgc3RhdGljIGlzRHVyYXRpb24obykge1xuICAgIHJldHVybiAobyAmJiBvLmlzTHV4b25EdXJhdGlvbikgfHwgZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogR2V0ICB0aGUgbG9jYWxlIG9mIGEgRHVyYXRpb24sIHN1Y2ggJ2VuLUdCJ1xuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgZ2V0IGxvY2FsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy5sb2MubG9jYWxlIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG51bWJlcmluZyBzeXN0ZW0gb2YgYSBEdXJhdGlvbiwgc3VjaCAnYmVuZycuIFRoZSBudW1iZXJpbmcgc3lzdGVtIGlzIHVzZWQgd2hlbiBmb3JtYXR0aW5nIHRoZSBEdXJhdGlvblxuICAgKlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgZ2V0IG51bWJlcmluZ1N5c3RlbSgpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy5sb2MubnVtYmVyaW5nU3lzdGVtIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRHVyYXRpb24gZm9ybWF0dGVkIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGZvcm1hdCBzdHJpbmcuIFlvdSBtYXkgdXNlIHRoZXNlIHRva2VuczpcbiAgICogKiBgU2AgZm9yIG1pbGxpc2Vjb25kc1xuICAgKiAqIGBzYCBmb3Igc2Vjb25kc1xuICAgKiAqIGBtYCBmb3IgbWludXRlc1xuICAgKiAqIGBoYCBmb3IgaG91cnNcbiAgICogKiBgZGAgZm9yIGRheXNcbiAgICogKiBgd2AgZm9yIHdlZWtzXG4gICAqICogYE1gIGZvciBtb250aHNcbiAgICogKiBgeWAgZm9yIHllYXJzXG4gICAqIE5vdGVzOlxuICAgKiAqIEFkZCBwYWRkaW5nIGJ5IHJlcGVhdGluZyB0aGUgdG9rZW4sIGUuZy4gXCJ5eVwiIHBhZHMgdGhlIHllYXJzIHRvIHR3byBkaWdpdHMsIFwiaGhoaFwiIHBhZHMgdGhlIGhvdXJzIG91dCB0byBmb3VyIGRpZ2l0c1xuICAgKiAqIFRva2VucyBjYW4gYmUgZXNjYXBlZCBieSB3cmFwcGluZyB3aXRoIHNpbmdsZSBxdW90ZXMuXG4gICAqICogVGhlIGR1cmF0aW9uIHdpbGwgYmUgY29udmVydGVkIHRvIHRoZSBzZXQgb2YgdW5pdHMgaW4gdGhlIGZvcm1hdCBzdHJpbmcgdXNpbmcge0BsaW5rIER1cmF0aW9uI3NoaWZ0VG99IGFuZCB0aGUgRHVyYXRpb25zJ3MgY29udmVyc2lvbiBhY2N1cmFjeSBzZXR0aW5nLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZm10IC0gdGhlIGZvcm1hdCBzdHJpbmdcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuZmxvb3I9dHJ1ZV0gLSBmbG9vciBudW1lcmljYWwgdmFsdWVzXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyB5ZWFyczogMSwgZGF5czogNiwgc2Vjb25kczogMiB9KS50b0Zvcm1hdChcInkgZCBzXCIpIC8vPT4gXCIxIDYgMlwiXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyB5ZWFyczogMSwgZGF5czogNiwgc2Vjb25kczogMiB9KS50b0Zvcm1hdChcInl5IGRkIHNzc1wiKSAvLz0+IFwiMDEgMDYgMDAyXCJcbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbU9iamVjdCh7IHllYXJzOiAxLCBkYXlzOiA2LCBzZWNvbmRzOiAyIH0pLnRvRm9ybWF0KFwiTSBTXCIpIC8vPT4gXCIxMiA1MTg0MDIwMDBcIlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b0Zvcm1hdChmbXQsIG9wdHMgPSB7fSkge1xuICAgIC8vIHJldmVyc2UtY29tcGF0IHNpbmNlIDEuMjsgd2UgYWx3YXlzIHJvdW5kIGRvd24gbm93LCBuZXZlciB1cCwgYW5kIHdlIGRvIGl0IGJ5IGRlZmF1bHRcbiAgICBjb25zdCBmbXRPcHRzID0ge1xuICAgICAgLi4ub3B0cyxcbiAgICAgIGZsb29yOiBvcHRzLnJvdW5kICE9PSBmYWxzZSAmJiBvcHRzLmZsb29yICE9PSBmYWxzZSxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWRcbiAgICAgID8gRm9ybWF0dGVyLmNyZWF0ZSh0aGlzLmxvYywgZm10T3B0cykuZm9ybWF0RHVyYXRpb25Gcm9tU3RyaW5nKHRoaXMsIGZtdClcbiAgICAgIDogSU5WQUxJRDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgRHVyYXRpb24gd2l0aCBhbGwgdW5pdHMgaW5jbHVkZWQuXG4gICAqIFRvIG1vZGlmeSBpdHMgYmVoYXZpb3IsIHVzZSBgbGlzdFN0eWxlYCBhbmQgYW55IEludGwuTnVtYmVyRm9ybWF0IG9wdGlvbiwgdGhvdWdoIGB1bml0RGlzcGxheWAgaXMgZXNwZWNpYWxseSByZWxldmFudC5cbiAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9JbnRsL051bWJlckZvcm1hdC9OdW1iZXJGb3JtYXQjb3B0aW9uc1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIEZvcm1hdHRpbmcgb3B0aW9ucy4gQWNjZXB0cyB0aGUgc2FtZSBrZXlzIGFzIHRoZSBvcHRpb25zIHBhcmFtZXRlciBvZiB0aGUgbmF0aXZlIGBJbnRsLk51bWJlckZvcm1hdGAgY29uc3RydWN0b3IsIGFzIHdlbGwgYXMgYGxpc3RTdHlsZWAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5saXN0U3R5bGU9J25hcnJvdyddIC0gSG93IHRvIGZvcm1hdCB0aGUgbWVyZ2VkIGxpc3QuIENvcnJlc3BvbmRzIHRvIHRoZSBgc3R5bGVgIHByb3BlcnR5IG9mIHRoZSBvcHRpb25zIHBhcmFtZXRlciBvZiB0aGUgbmF0aXZlIGBJbnRsLkxpc3RGb3JtYXRgIGNvbnN0cnVjdG9yLlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGBqc1xuICAgKiB2YXIgZHVyID0gRHVyYXRpb24uZnJvbU9iamVjdCh7IGRheXM6IDEsIGhvdXJzOiA1LCBtaW51dGVzOiA2IH0pXG4gICAqIGR1ci50b0h1bWFuKCkgLy89PiAnMSBkYXksIDUgaG91cnMsIDYgbWludXRlcydcbiAgICogZHVyLnRvSHVtYW4oeyBsaXN0U3R5bGU6IFwibG9uZ1wiIH0pIC8vPT4gJzEgZGF5LCA1IGhvdXJzLCBhbmQgNiBtaW51dGVzJ1xuICAgKiBkdXIudG9IdW1hbih7IHVuaXREaXNwbGF5OiBcInNob3J0XCIgfSkgLy89PiAnMSBkYXksIDUgaHIsIDYgbWluJ1xuICAgKiBgYGBcbiAgICovXG4gIHRvSHVtYW4ob3B0cyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBJTlZBTElEO1xuXG4gICAgY29uc3QgbCA9IG9yZGVyZWRVbml0c1xuICAgICAgLm1hcCgodW5pdCkgPT4ge1xuICAgICAgICBjb25zdCB2YWwgPSB0aGlzLnZhbHVlc1t1bml0XTtcbiAgICAgICAgaWYgKGlzVW5kZWZpbmVkKHZhbCkpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5sb2NcbiAgICAgICAgICAubnVtYmVyRm9ybWF0dGVyKHsgc3R5bGU6IFwidW5pdFwiLCB1bml0RGlzcGxheTogXCJsb25nXCIsIC4uLm9wdHMsIHVuaXQ6IHVuaXQuc2xpY2UoMCwgLTEpIH0pXG4gICAgICAgICAgLmZvcm1hdCh2YWwpO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKG4pID0+IG4pO1xuXG4gICAgcmV0dXJuIHRoaXMubG9jXG4gICAgICAubGlzdEZvcm1hdHRlcih7IHR5cGU6IFwiY29uanVuY3Rpb25cIiwgc3R5bGU6IG9wdHMubGlzdFN0eWxlIHx8IFwibmFycm93XCIsIC4uLm9wdHMgfSlcbiAgICAgIC5mb3JtYXQobCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIEphdmFTY3JpcHQgb2JqZWN0IHdpdGggdGhpcyBEdXJhdGlvbidzIHZhbHVlcy5cbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbU9iamVjdCh7IHllYXJzOiAxLCBkYXlzOiA2LCBzZWNvbmRzOiAyIH0pLnRvT2JqZWN0KCkgLy89PiB7IHllYXJzOiAxLCBkYXlzOiA2LCBzZWNvbmRzOiAyIH1cbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgdG9PYmplY3QoKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB7fTtcbiAgICByZXR1cm4geyAuLi50aGlzLnZhbHVlcyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gSVNPIDg2MDEtY29tcGxpYW50IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIER1cmF0aW9uLlxuICAgKiBAc2VlIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT184NjAxI0R1cmF0aW9uc1xuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHsgeWVhcnM6IDMsIHNlY29uZHM6IDQ1IH0pLnRvSVNPKCkgLy89PiAnUDNZVDQ1UydcbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbU9iamVjdCh7IG1vbnRoczogNCwgc2Vjb25kczogNDUgfSkudG9JU08oKSAvLz0+ICdQNE1UNDVTJ1xuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHsgbW9udGhzOiA1IH0pLnRvSVNPKCkgLy89PiAnUDVNJ1xuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHsgbWludXRlczogNSB9KS50b0lTTygpIC8vPT4gJ1BUNU0nXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyBtaWxsaXNlY29uZHM6IDYgfSkudG9JU08oKSAvLz0+ICdQVDAuMDA2UydcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9JU08oKSB7XG4gICAgLy8gd2UgY291bGQgdXNlIHRoZSBmb3JtYXR0ZXIsIGJ1dCB0aGlzIGlzIGFuIGVhc2llciB3YXkgdG8gZ2V0IHRoZSBtaW5pbXVtIHN0cmluZ1xuICAgIGlmICghdGhpcy5pc1ZhbGlkKSByZXR1cm4gbnVsbDtcblxuICAgIGxldCBzID0gXCJQXCI7XG4gICAgaWYgKHRoaXMueWVhcnMgIT09IDApIHMgKz0gdGhpcy55ZWFycyArIFwiWVwiO1xuICAgIGlmICh0aGlzLm1vbnRocyAhPT0gMCB8fCB0aGlzLnF1YXJ0ZXJzICE9PSAwKSBzICs9IHRoaXMubW9udGhzICsgdGhpcy5xdWFydGVycyAqIDMgKyBcIk1cIjtcbiAgICBpZiAodGhpcy53ZWVrcyAhPT0gMCkgcyArPSB0aGlzLndlZWtzICsgXCJXXCI7XG4gICAgaWYgKHRoaXMuZGF5cyAhPT0gMCkgcyArPSB0aGlzLmRheXMgKyBcIkRcIjtcbiAgICBpZiAodGhpcy5ob3VycyAhPT0gMCB8fCB0aGlzLm1pbnV0ZXMgIT09IDAgfHwgdGhpcy5zZWNvbmRzICE9PSAwIHx8IHRoaXMubWlsbGlzZWNvbmRzICE9PSAwKVxuICAgICAgcyArPSBcIlRcIjtcbiAgICBpZiAodGhpcy5ob3VycyAhPT0gMCkgcyArPSB0aGlzLmhvdXJzICsgXCJIXCI7XG4gICAgaWYgKHRoaXMubWludXRlcyAhPT0gMCkgcyArPSB0aGlzLm1pbnV0ZXMgKyBcIk1cIjtcbiAgICBpZiAodGhpcy5zZWNvbmRzICE9PSAwIHx8IHRoaXMubWlsbGlzZWNvbmRzICE9PSAwKVxuICAgICAgLy8gdGhpcyB3aWxsIGhhbmRsZSBcImZsb2F0aW5nIHBvaW50IG1hZG5lc3NcIiBieSByZW1vdmluZyBleHRyYSBkZWNpbWFsIHBsYWNlc1xuICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTg4MDA0L2lzLWZsb2F0aW5nLXBvaW50LW1hdGgtYnJva2VuXG4gICAgICBzICs9IHJvdW5kVG8odGhpcy5zZWNvbmRzICsgdGhpcy5taWxsaXNlY29uZHMgLyAxMDAwLCAzKSArIFwiU1wiO1xuICAgIGlmIChzID09PSBcIlBcIikgcyArPSBcIlQwU1wiO1xuICAgIHJldHVybiBzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gSVNPIDg2MDEtY29tcGxpYW50IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIER1cmF0aW9uLCBmb3JtYXR0ZWQgYXMgYSB0aW1lIG9mIGRheS5cbiAgICogTm90ZSB0aGF0IHRoaXMgd2lsbCByZXR1cm4gbnVsbCBpZiB0aGUgZHVyYXRpb24gaXMgaW52YWxpZCwgbmVnYXRpdmUsIG9yIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiAyNCBob3Vycy5cbiAgICogQHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSNUaW1lc1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnNcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5zdXBwcmVzc01pbGxpc2Vjb25kcz1mYWxzZV0gLSBleGNsdWRlIG1pbGxpc2Vjb25kcyBmcm9tIHRoZSBmb3JtYXQgaWYgdGhleSdyZSAwXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuc3VwcHJlc3NTZWNvbmRzPWZhbHNlXSAtIGV4Y2x1ZGUgc2Vjb25kcyBmcm9tIHRoZSBmb3JtYXQgaWYgdGhleSdyZSAwXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuaW5jbHVkZVByZWZpeD1mYWxzZV0gLSBpbmNsdWRlIHRoZSBgVGAgcHJlZml4XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5mb3JtYXQ9J2V4dGVuZGVkJ10gLSBjaG9vc2UgYmV0d2VlbiB0aGUgYmFzaWMgYW5kIGV4dGVuZGVkIGZvcm1hdFxuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHsgaG91cnM6IDExIH0pLnRvSVNPVGltZSgpIC8vPT4gJzExOjAwOjAwLjAwMCdcbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbU9iamVjdCh7IGhvdXJzOiAxMSB9KS50b0lTT1RpbWUoeyBzdXBwcmVzc01pbGxpc2Vjb25kczogdHJ1ZSB9KSAvLz0+ICcxMTowMDowMCdcbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbU9iamVjdCh7IGhvdXJzOiAxMSB9KS50b0lTT1RpbWUoeyBzdXBwcmVzc1NlY29uZHM6IHRydWUgfSkgLy89PiAnMTE6MDAnXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyBob3VyczogMTEgfSkudG9JU09UaW1lKHsgaW5jbHVkZVByZWZpeDogdHJ1ZSB9KSAvLz0+ICdUMTE6MDA6MDAuMDAwJ1xuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHsgaG91cnM6IDExIH0pLnRvSVNPVGltZSh7IGZvcm1hdDogJ2Jhc2ljJyB9KSAvLz0+ICcxMTAwMDAuMDAwJ1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b0lTT1RpbWUob3B0cyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgbWlsbGlzID0gdGhpcy50b01pbGxpcygpO1xuICAgIGlmIChtaWxsaXMgPCAwIHx8IG1pbGxpcyA+PSA4NjQwMDAwMCkgcmV0dXJuIG51bGw7XG5cbiAgICBvcHRzID0ge1xuICAgICAgc3VwcHJlc3NNaWxsaXNlY29uZHM6IGZhbHNlLFxuICAgICAgc3VwcHJlc3NTZWNvbmRzOiBmYWxzZSxcbiAgICAgIGluY2x1ZGVQcmVmaXg6IGZhbHNlLFxuICAgICAgZm9ybWF0OiBcImV4dGVuZGVkXCIsXG4gICAgICAuLi5vcHRzLFxuICAgICAgaW5jbHVkZU9mZnNldDogZmFsc2UsXG4gICAgfTtcblxuICAgIGNvbnN0IGRhdGVUaW1lID0gRGF0ZVRpbWUuZnJvbU1pbGxpcyhtaWxsaXMsIHsgem9uZTogXCJVVENcIiB9KTtcbiAgICByZXR1cm4gZGF0ZVRpbWUudG9JU09UaW1lKG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gSVNPIDg2MDEgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBEdXJhdGlvbiBhcHByb3ByaWF0ZSBmb3IgdXNlIGluIEpTT04uXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICovXG4gIHRvSlNPTigpIHtcbiAgICByZXR1cm4gdGhpcy50b0lTTygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gSVNPIDg2MDEgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBEdXJhdGlvbiBhcHByb3ByaWF0ZSBmb3IgdXNlIGluIGRlYnVnZ2luZy5cbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9JU08oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRHVyYXRpb24gYXBwcm9wcmlhdGUgZm9yIHRoZSBSRVBMLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICBbU3ltYm9sLmZvcihcIm5vZGVqcy51dGlsLmluc3BlY3QuY3VzdG9tXCIpXSgpIHtcbiAgICBpZiAodGhpcy5pc1ZhbGlkKSB7XG4gICAgICByZXR1cm4gYER1cmF0aW9uIHsgdmFsdWVzOiAke0pTT04uc3RyaW5naWZ5KHRoaXMudmFsdWVzKX0gfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBgRHVyYXRpb24geyBJbnZhbGlkLCByZWFzb246ICR7dGhpcy5pbnZhbGlkUmVhc29ufSB9YDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBtaWxsaXNlY29uZHMgdmFsdWUgb2YgdGhpcyBEdXJhdGlvbi5cbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgdG9NaWxsaXMoKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBOYU47XG5cbiAgICByZXR1cm4gZHVyYXRpb25Ub01pbGxpcyh0aGlzLm1hdHJpeCwgdGhpcy52YWx1ZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gbWlsbGlzZWNvbmRzIHZhbHVlIG9mIHRoaXMgRHVyYXRpb24uIEFsaWFzIG9mIHtAbGluayB0b01pbGxpc31cbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgdmFsdWVPZigpIHtcbiAgICByZXR1cm4gdGhpcy50b01pbGxpcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgdGhpcyBEdXJhdGlvbiBsb25nZXIgYnkgdGhlIHNwZWNpZmllZCBhbW91bnQuIFJldHVybiBhIG5ld2x5LWNvbnN0cnVjdGVkIER1cmF0aW9uLlxuICAgKiBAcGFyYW0ge0R1cmF0aW9ufE9iamVjdHxudW1iZXJ9IGR1cmF0aW9uIC0gVGhlIGFtb3VudCB0byBhZGQuIEVpdGhlciBhIEx1eG9uIER1cmF0aW9uLCBhIG51bWJlciBvZiBtaWxsaXNlY29uZHMsIHRoZSBvYmplY3QgYXJndW1lbnQgdG8gRHVyYXRpb24uZnJvbU9iamVjdCgpXG4gICAqIEByZXR1cm4ge0R1cmF0aW9ufVxuICAgKi9cbiAgcGx1cyhkdXJhdGlvbikge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkKSByZXR1cm4gdGhpcztcblxuICAgIGNvbnN0IGR1ciA9IER1cmF0aW9uLmZyb21EdXJhdGlvbkxpa2UoZHVyYXRpb24pLFxuICAgICAgcmVzdWx0ID0ge307XG5cbiAgICBmb3IgKGNvbnN0IGsgb2Ygb3JkZXJlZFVuaXRzKSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkoZHVyLnZhbHVlcywgaykgfHwgaGFzT3duUHJvcGVydHkodGhpcy52YWx1ZXMsIGspKSB7XG4gICAgICAgIHJlc3VsdFtrXSA9IGR1ci5nZXQoaykgKyB0aGlzLmdldChrKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY2xvbmUodGhpcywgeyB2YWx1ZXM6IHJlc3VsdCB9LCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlIHRoaXMgRHVyYXRpb24gc2hvcnRlciBieSB0aGUgc3BlY2lmaWVkIGFtb3VudC4gUmV0dXJuIGEgbmV3bHktY29uc3RydWN0ZWQgRHVyYXRpb24uXG4gICAqIEBwYXJhbSB7RHVyYXRpb258T2JqZWN0fG51bWJlcn0gZHVyYXRpb24gLSBUaGUgYW1vdW50IHRvIHN1YnRyYWN0LiBFaXRoZXIgYSBMdXhvbiBEdXJhdGlvbiwgYSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLCB0aGUgb2JqZWN0IGFyZ3VtZW50IHRvIER1cmF0aW9uLmZyb21PYmplY3QoKVxuICAgKiBAcmV0dXJuIHtEdXJhdGlvbn1cbiAgICovXG4gIG1pbnVzKGR1cmF0aW9uKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB0aGlzO1xuXG4gICAgY29uc3QgZHVyID0gRHVyYXRpb24uZnJvbUR1cmF0aW9uTGlrZShkdXJhdGlvbik7XG4gICAgcmV0dXJuIHRoaXMucGx1cyhkdXIubmVnYXRlKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNjYWxlIHRoaXMgRHVyYXRpb24gYnkgdGhlIHNwZWNpZmllZCBhbW91bnQuIFJldHVybiBhIG5ld2x5LWNvbnN0cnVjdGVkIER1cmF0aW9uLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBmbiAtIFRoZSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIHVuaXQuIEFyaXR5IGlzIDEgb3IgMjogdGhlIHZhbHVlIG9mIHRoZSB1bml0IGFuZCwgb3B0aW9uYWxseSwgdGhlIHVuaXQgbmFtZS4gTXVzdCByZXR1cm4gYSBudW1iZXIuXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyBob3VyczogMSwgbWludXRlczogMzAgfSkubWFwVW5pdHMoeCA9PiB4ICogMikgLy89PiB7IGhvdXJzOiAyLCBtaW51dGVzOiA2MCB9XG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyBob3VyczogMSwgbWludXRlczogMzAgfSkubWFwVW5pdHMoKHgsIHUpID0+IHUgPT09IFwiaG91cnNcIiA/IHggKiAyIDogeCkgLy89PiB7IGhvdXJzOiAyLCBtaW51dGVzOiAzMCB9XG4gICAqIEByZXR1cm4ge0R1cmF0aW9ufVxuICAgKi9cbiAgbWFwVW5pdHMoZm4pIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIHRoaXM7XG4gICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgZm9yIChjb25zdCBrIG9mIE9iamVjdC5rZXlzKHRoaXMudmFsdWVzKSkge1xuICAgICAgcmVzdWx0W2tdID0gYXNOdW1iZXIoZm4odGhpcy52YWx1ZXNba10sIGspKTtcbiAgICB9XG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIHsgdmFsdWVzOiByZXN1bHQgfSwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB2YWx1ZSBvZiB1bml0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdW5pdCAtIGEgdW5pdCBzdWNoIGFzICdtaW51dGUnIG9yICdkYXknXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3Qoe3llYXJzOiAyLCBkYXlzOiAzfSkuZ2V0KCd5ZWFycycpIC8vPT4gMlxuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHt5ZWFyczogMiwgZGF5czogM30pLmdldCgnbW9udGhzJykgLy89PiAwXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3Qoe3llYXJzOiAyLCBkYXlzOiAzfSkuZ2V0KCdkYXlzJykgLy89PiAzXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldCh1bml0KSB7XG4gICAgcmV0dXJuIHRoaXNbRHVyYXRpb24ubm9ybWFsaXplVW5pdCh1bml0KV07XG4gIH1cblxuICAvKipcbiAgICogXCJTZXRcIiB0aGUgdmFsdWVzIG9mIHNwZWNpZmllZCB1bml0cy4gUmV0dXJuIGEgbmV3bHktY29uc3RydWN0ZWQgRHVyYXRpb24uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZXMgLSBhIG1hcHBpbmcgb2YgdW5pdHMgdG8gbnVtYmVyc1xuICAgKiBAZXhhbXBsZSBkdXIuc2V0KHsgeWVhcnM6IDIwMTcgfSlcbiAgICogQGV4YW1wbGUgZHVyLnNldCh7IGhvdXJzOiA4LCBtaW51dGVzOiAzMCB9KVxuICAgKiBAcmV0dXJuIHtEdXJhdGlvbn1cbiAgICovXG4gIHNldCh2YWx1ZXMpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIHRoaXM7XG5cbiAgICBjb25zdCBtaXhlZCA9IHsgLi4udGhpcy52YWx1ZXMsIC4uLm5vcm1hbGl6ZU9iamVjdCh2YWx1ZXMsIER1cmF0aW9uLm5vcm1hbGl6ZVVuaXQpIH07XG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIHsgdmFsdWVzOiBtaXhlZCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBcIlNldFwiIHRoZSBsb2NhbGUgYW5kL29yIG51bWJlcmluZ1N5c3RlbS4gIFJldHVybnMgYSBuZXdseS1jb25zdHJ1Y3RlZCBEdXJhdGlvbi5cbiAgICogQGV4YW1wbGUgZHVyLnJlY29uZmlndXJlKHsgbG9jYWxlOiAnZW4tR0InIH0pXG4gICAqIEByZXR1cm4ge0R1cmF0aW9ufVxuICAgKi9cbiAgcmVjb25maWd1cmUoeyBsb2NhbGUsIG51bWJlcmluZ1N5c3RlbSwgY29udmVyc2lvbkFjY3VyYWN5LCBtYXRyaXggfSA9IHt9KSB7XG4gICAgY29uc3QgbG9jID0gdGhpcy5sb2MuY2xvbmUoeyBsb2NhbGUsIG51bWJlcmluZ1N5c3RlbSB9KTtcbiAgICBjb25zdCBvcHRzID0geyBsb2MsIG1hdHJpeCwgY29udmVyc2lvbkFjY3VyYWN5IH07XG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBkdXJhdGlvbiBpbiB0aGUgc3BlY2lmaWVkIHVuaXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1bml0IC0gYSB1bml0IHN1Y2ggYXMgJ21pbnV0ZXMnIG9yICdkYXlzJ1xuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHt5ZWFyczogMX0pLmFzKCdkYXlzJykgLy89PiAzNjVcbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbU9iamVjdCh7eWVhcnM6IDF9KS5hcygnbW9udGhzJykgLy89PiAxMlxuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHtob3VyczogNjB9KS5hcygnZGF5cycpIC8vPT4gMi41XG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGFzKHVuaXQpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy5zaGlmdFRvKHVuaXQpLmdldCh1bml0KSA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWR1Y2UgdGhpcyBEdXJhdGlvbiB0byBpdHMgY2Fub25pY2FsIHJlcHJlc2VudGF0aW9uIGluIGl0cyBjdXJyZW50IHVuaXRzLlxuICAgKiBBc3N1bWluZyB0aGUgb3ZlcmFsbCB2YWx1ZSBvZiB0aGUgRHVyYXRpb24gaXMgcG9zaXRpdmUsIHRoaXMgbWVhbnM6XG4gICAqIC0gZXhjZXNzaXZlIHZhbHVlcyBmb3IgbG93ZXItb3JkZXIgdW5pdHMgYXJlIGNvbnZlcnRlZCB0byBoaWdoZXItb3JkZXIgdW5pdHMgKGlmIHBvc3NpYmxlLCBzZWUgZmlyc3QgYW5kIHNlY29uZCBleGFtcGxlKVxuICAgKiAtIG5lZ2F0aXZlIGxvd2VyLW9yZGVyIHVuaXRzIGFyZSBjb252ZXJ0ZWQgdG8gaGlnaGVyIG9yZGVyIHVuaXRzICh0aGVyZSBtdXN0IGJlIHN1Y2ggYSBoaWdoZXIgb3JkZXIgdW5pdCwgb3RoZXJ3aXNlXG4gICAqICAgdGhlIG92ZXJhbGwgdmFsdWUgd291bGQgYmUgbmVnYXRpdmUsIHNlZSB0aGlyZCBleGFtcGxlKVxuICAgKiAtIGZyYWN0aW9uYWwgdmFsdWVzIGZvciBoaWdoZXItb3JkZXIgdW5pdHMgYXJlIGNvbnZlcnRlZCB0byBsb3dlci1vcmRlciB1bml0cyAoaWYgcG9zc2libGUsIHNlZSBmb3VydGggZXhhbXBsZSlcbiAgICpcbiAgICogSWYgdGhlIG92ZXJhbGwgdmFsdWUgaXMgbmVnYXRpdmUsIHRoZSByZXN1bHQgb2YgdGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBgdGhpcy5uZWdhdGUoKS5ub3JtYWxpemUoKS5uZWdhdGUoKWAuXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyB5ZWFyczogMiwgZGF5czogNTAwMCB9KS5ub3JtYWxpemUoKS50b09iamVjdCgpIC8vPT4geyB5ZWFyczogMTUsIGRheXM6IDI1NSB9XG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyBkYXlzOiA1MDAwIH0pLm5vcm1hbGl6ZSgpLnRvT2JqZWN0KCkgLy89PiB7IGRheXM6IDUwMDAgfVxuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHsgaG91cnM6IDEyLCBtaW51dGVzOiAtNDUgfSkubm9ybWFsaXplKCkudG9PYmplY3QoKSAvLz0+IHsgaG91cnM6IDExLCBtaW51dGVzOiAxNSB9XG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyB5ZWFyczogMi41LCBkYXlzOiAwLCBob3VyczogMCB9KS5ub3JtYWxpemUoKS50b09iamVjdCgpIC8vPT4geyB5ZWFyczogMiwgZGF5czogMTgyLCBob3VyczogMTIgfVxuICAgKiBAcmV0dXJuIHtEdXJhdGlvbn1cbiAgICovXG4gIG5vcm1hbGl6ZSgpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIHRoaXM7XG4gICAgY29uc3QgdmFscyA9IHRoaXMudG9PYmplY3QoKTtcbiAgICBub3JtYWxpemVWYWx1ZXModGhpcy5tYXRyaXgsIHZhbHMpO1xuICAgIHJldHVybiBjbG9uZSh0aGlzLCB7IHZhbHVlczogdmFscyB9LCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNjYWxlIHVuaXRzIHRvIGl0cyBsYXJnZXN0IHJlcHJlc2VudGF0aW9uXG4gICAqIEBleGFtcGxlIER1cmF0aW9uLmZyb21PYmplY3QoeyBtaWxsaXNlY29uZHM6IDkwMDAwIH0pLnJlc2NhbGUoKS50b09iamVjdCgpIC8vPT4geyBtaW51dGVzOiAxLCBzZWNvbmRzOiAzMCB9XG4gICAqIEByZXR1cm4ge0R1cmF0aW9ufVxuICAgKi9cbiAgcmVzY2FsZSgpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIHRoaXM7XG4gICAgY29uc3QgdmFscyA9IHJlbW92ZVplcm9lcyh0aGlzLm5vcm1hbGl6ZSgpLnNoaWZ0VG9BbGwoKS50b09iamVjdCgpKTtcbiAgICByZXR1cm4gY2xvbmUodGhpcywgeyB2YWx1ZXM6IHZhbHMgfSwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCB0aGlzIER1cmF0aW9uIGludG8gaXRzIHJlcHJlc2VudGF0aW9uIGluIGEgZGlmZmVyZW50IHNldCBvZiB1bml0cy5cbiAgICogQGV4YW1wbGUgRHVyYXRpb24uZnJvbU9iamVjdCh7IGhvdXJzOiAxLCBzZWNvbmRzOiAzMCB9KS5zaGlmdFRvKCdtaW51dGVzJywgJ21pbGxpc2Vjb25kcycpLnRvT2JqZWN0KCkgLy89PiB7IG1pbnV0ZXM6IDYwLCBtaWxsaXNlY29uZHM6IDMwMDAwIH1cbiAgICogQHJldHVybiB7RHVyYXRpb259XG4gICAqL1xuICBzaGlmdFRvKC4uLnVuaXRzKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKHVuaXRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdW5pdHMgPSB1bml0cy5tYXAoKHUpID0+IER1cmF0aW9uLm5vcm1hbGl6ZVVuaXQodSkpO1xuXG4gICAgY29uc3QgYnVpbHQgPSB7fSxcbiAgICAgIGFjY3VtdWxhdGVkID0ge30sXG4gICAgICB2YWxzID0gdGhpcy50b09iamVjdCgpO1xuICAgIGxldCBsYXN0VW5pdDtcblxuICAgIGZvciAoY29uc3QgayBvZiBvcmRlcmVkVW5pdHMpIHtcbiAgICAgIGlmICh1bml0cy5pbmRleE9mKGspID49IDApIHtcbiAgICAgICAgbGFzdFVuaXQgPSBrO1xuXG4gICAgICAgIGxldCBvd24gPSAwO1xuXG4gICAgICAgIC8vIGFueXRoaW5nIHdlIGhhdmVuJ3QgYm9pbGVkIGRvd24geWV0IHNob3VsZCBnZXQgYm9pbGVkIHRvIHRoaXMgdW5pdFxuICAgICAgICBmb3IgKGNvbnN0IGFrIGluIGFjY3VtdWxhdGVkKSB7XG4gICAgICAgICAgb3duICs9IHRoaXMubWF0cml4W2FrXVtrXSAqIGFjY3VtdWxhdGVkW2FrXTtcbiAgICAgICAgICBhY2N1bXVsYXRlZFtha10gPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcGx1cyBhbnl0aGluZyB0aGF0J3MgYWxyZWFkeSBpbiB0aGlzIHVuaXRcbiAgICAgICAgaWYgKGlzTnVtYmVyKHZhbHNba10pKSB7XG4gICAgICAgICAgb3duICs9IHZhbHNba107XG4gICAgICAgIH1cblxuICAgICAgICAvLyBvbmx5IGtlZXAgdGhlIGludGVnZXIgcGFydCBmb3Igbm93IGluIHRoZSBob3BlcyBvZiBwdXR0aW5nIGFueSBkZWNpbWFsIHBhcnRcbiAgICAgICAgLy8gaW50byBhIHNtYWxsZXIgdW5pdCBsYXRlclxuICAgICAgICBjb25zdCBpID0gTWF0aC50cnVuYyhvd24pO1xuICAgICAgICBidWlsdFtrXSA9IGk7XG4gICAgICAgIGFjY3VtdWxhdGVkW2tdID0gKG93biAqIDEwMDAgLSBpICogMTAwMCkgLyAxMDAwO1xuXG4gICAgICAgIC8vIG90aGVyd2lzZSwga2VlcCBpdCBpbiB0aGUgd2luZ3MgdG8gYm9pbCBpdCBsYXRlclxuICAgICAgfSBlbHNlIGlmIChpc051bWJlcih2YWxzW2tdKSkge1xuICAgICAgICBhY2N1bXVsYXRlZFtrXSA9IHZhbHNba107XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYW55dGhpbmcgbGVmdG92ZXIgYmVjb21lcyB0aGUgZGVjaW1hbCBmb3IgdGhlIGxhc3QgdW5pdFxuICAgIC8vIGxhc3RVbml0IG11c3QgYmUgZGVmaW5lZCBzaW5jZSB1bml0cyBpcyBub3QgZW1wdHlcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBhY2N1bXVsYXRlZCkge1xuICAgICAgaWYgKGFjY3VtdWxhdGVkW2tleV0gIT09IDApIHtcbiAgICAgICAgYnVpbHRbbGFzdFVuaXRdICs9XG4gICAgICAgICAga2V5ID09PSBsYXN0VW5pdCA/IGFjY3VtdWxhdGVkW2tleV0gOiBhY2N1bXVsYXRlZFtrZXldIC8gdGhpcy5tYXRyaXhbbGFzdFVuaXRdW2tleV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgbm9ybWFsaXplVmFsdWVzKHRoaXMubWF0cml4LCBidWlsdCk7XG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIHsgdmFsdWVzOiBidWlsdCB9LCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaGlmdCB0aGlzIER1cmF0aW9uIHRvIGFsbCBhdmFpbGFibGUgdW5pdHMuXG4gICAqIFNhbWUgYXMgc2hpZnRUbyhcInllYXJzXCIsIFwibW9udGhzXCIsIFwid2Vla3NcIiwgXCJkYXlzXCIsIFwiaG91cnNcIiwgXCJtaW51dGVzXCIsIFwic2Vjb25kc1wiLCBcIm1pbGxpc2Vjb25kc1wiKVxuICAgKiBAcmV0dXJuIHtEdXJhdGlvbn1cbiAgICovXG4gIHNoaWZ0VG9BbGwoKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB0aGlzO1xuICAgIHJldHVybiB0aGlzLnNoaWZ0VG8oXG4gICAgICBcInllYXJzXCIsXG4gICAgICBcIm1vbnRoc1wiLFxuICAgICAgXCJ3ZWVrc1wiLFxuICAgICAgXCJkYXlzXCIsXG4gICAgICBcImhvdXJzXCIsXG4gICAgICBcIm1pbnV0ZXNcIixcbiAgICAgIFwic2Vjb25kc1wiLFxuICAgICAgXCJtaWxsaXNlY29uZHNcIlxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBuZWdhdGl2ZSBvZiB0aGlzIER1cmF0aW9uLlxuICAgKiBAZXhhbXBsZSBEdXJhdGlvbi5mcm9tT2JqZWN0KHsgaG91cnM6IDEsIHNlY29uZHM6IDMwIH0pLm5lZ2F0ZSgpLnRvT2JqZWN0KCkgLy89PiB7IGhvdXJzOiAtMSwgc2Vjb25kczogLTMwIH1cbiAgICogQHJldHVybiB7RHVyYXRpb259XG4gICAqL1xuICBuZWdhdGUoKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB0aGlzO1xuICAgIGNvbnN0IG5lZ2F0ZWQgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGsgb2YgT2JqZWN0LmtleXModGhpcy52YWx1ZXMpKSB7XG4gICAgICBuZWdhdGVkW2tdID0gdGhpcy52YWx1ZXNba10gPT09IDAgPyAwIDogLXRoaXMudmFsdWVzW2tdO1xuICAgIH1cbiAgICByZXR1cm4gY2xvbmUodGhpcywgeyB2YWx1ZXM6IG5lZ2F0ZWQgfSwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB5ZWFycy5cbiAgICogQHR5cGUge251bWJlcn1cbiAgICovXG4gIGdldCB5ZWFycygpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy52YWx1ZXMueWVhcnMgfHwgMCA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHF1YXJ0ZXJzLlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IHF1YXJ0ZXJzKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLnZhbHVlcy5xdWFydGVycyB8fCAwIDogTmFOO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbW9udGhzLlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IG1vbnRocygpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy52YWx1ZXMubW9udGhzIHx8IDAgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB3ZWVrc1xuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IHdlZWtzKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLnZhbHVlcy53ZWVrcyB8fCAwIDogTmFOO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZGF5cy5cbiAgICogQHR5cGUge251bWJlcn1cbiAgICovXG4gIGdldCBkYXlzKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLnZhbHVlcy5kYXlzIHx8IDAgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBob3Vycy5cbiAgICogQHR5cGUge251bWJlcn1cbiAgICovXG4gIGdldCBob3VycygpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy52YWx1ZXMuaG91cnMgfHwgMCA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1pbnV0ZXMuXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgbWludXRlcygpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy52YWx1ZXMubWludXRlcyB8fCAwIDogTmFOO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgc2Vjb25kcy5cbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IHNlY29uZHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IHRoaXMudmFsdWVzLnNlY29uZHMgfHwgMCA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1pbGxpc2Vjb25kcy5cbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IG1pbGxpc2Vjb25kcygpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy52YWx1ZXMubWlsbGlzZWNvbmRzIHx8IDAgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBEdXJhdGlvbiBpcyBpbnZhbGlkLiBJbnZhbGlkIGR1cmF0aW9ucyBhcmUgcmV0dXJuZWQgYnkgZGlmZiBvcGVyYXRpb25zXG4gICAqIG9uIGludmFsaWQgRGF0ZVRpbWVzIG9yIEludGVydmFscy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGdldCBpc1ZhbGlkKCkge1xuICAgIHJldHVybiB0aGlzLmludmFsaWQgPT09IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBlcnJvciBjb2RlIGlmIHRoaXMgRHVyYXRpb24gYmVjYW1lIGludmFsaWQsIG9yIG51bGwgaWYgdGhlIER1cmF0aW9uIGlzIHZhbGlkXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICovXG4gIGdldCBpbnZhbGlkUmVhc29uKCkge1xuICAgIHJldHVybiB0aGlzLmludmFsaWQgPyB0aGlzLmludmFsaWQucmVhc29uIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGV4cGxhbmF0aW9uIG9mIHdoeSB0aGlzIER1cmF0aW9uIGJlY2FtZSBpbnZhbGlkLCBvciBudWxsIGlmIHRoZSBEdXJhdGlvbiBpcyB2YWxpZFxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgZ2V0IGludmFsaWRFeHBsYW5hdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5pbnZhbGlkID8gdGhpcy5pbnZhbGlkLmV4cGxhbmF0aW9uIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFcXVhbGl0eSBjaGVja1xuICAgKiBUd28gRHVyYXRpb25zIGFyZSBlcXVhbCBpZmYgdGhleSBoYXZlIHRoZSBzYW1lIHVuaXRzIGFuZCB0aGUgc2FtZSB2YWx1ZXMgZm9yIGVhY2ggdW5pdC5cbiAgICogQHBhcmFtIHtEdXJhdGlvbn0gb3RoZXJcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGVxdWFscyhvdGhlcikge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkIHx8ICFvdGhlci5pc1ZhbGlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmxvYy5lcXVhbHMob3RoZXIubG9jKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGVxKHYxLCB2Mikge1xuICAgICAgLy8gQ29uc2lkZXIgMCBhbmQgdW5kZWZpbmVkIGFzIGVxdWFsXG4gICAgICBpZiAodjEgPT09IHVuZGVmaW5lZCB8fCB2MSA9PT0gMCkgcmV0dXJuIHYyID09PSB1bmRlZmluZWQgfHwgdjIgPT09IDA7XG4gICAgICByZXR1cm4gdjEgPT09IHYyO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgdSBvZiBvcmRlcmVkVW5pdHMpIHtcbiAgICAgIGlmICghZXEodGhpcy52YWx1ZXNbdV0sIG90aGVyLnZhbHVlc1t1XSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuIiwgImltcG9ydCBEYXRlVGltZSwgeyBmcmllbmRseURhdGVUaW1lIH0gZnJvbSBcIi4vZGF0ZXRpbWUuanNcIjtcbmltcG9ydCBEdXJhdGlvbiBmcm9tIFwiLi9kdXJhdGlvbi5qc1wiO1xuaW1wb3J0IFNldHRpbmdzIGZyb20gXCIuL3NldHRpbmdzLmpzXCI7XG5pbXBvcnQgeyBJbnZhbGlkQXJndW1lbnRFcnJvciwgSW52YWxpZEludGVydmFsRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnMuanNcIjtcbmltcG9ydCBJbnZhbGlkIGZyb20gXCIuL2ltcGwvaW52YWxpZC5qc1wiO1xuaW1wb3J0IEZvcm1hdHRlciBmcm9tIFwiLi9pbXBsL2Zvcm1hdHRlci5qc1wiO1xuaW1wb3J0ICogYXMgRm9ybWF0cyBmcm9tIFwiLi9pbXBsL2Zvcm1hdHMuanNcIjtcblxuY29uc3QgSU5WQUxJRCA9IFwiSW52YWxpZCBJbnRlcnZhbFwiO1xuXG4vLyBjaGVja3MgaWYgdGhlIHN0YXJ0IGlzIGVxdWFsIHRvIG9yIGJlZm9yZSB0aGUgZW5kXG5mdW5jdGlvbiB2YWxpZGF0ZVN0YXJ0RW5kKHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCB8fCAhc3RhcnQuaXNWYWxpZCkge1xuICAgIHJldHVybiBJbnRlcnZhbC5pbnZhbGlkKFwibWlzc2luZyBvciBpbnZhbGlkIHN0YXJ0XCIpO1xuICB9IGVsc2UgaWYgKCFlbmQgfHwgIWVuZC5pc1ZhbGlkKSB7XG4gICAgcmV0dXJuIEludGVydmFsLmludmFsaWQoXCJtaXNzaW5nIG9yIGludmFsaWQgZW5kXCIpO1xuICB9IGVsc2UgaWYgKGVuZCA8IHN0YXJ0KSB7XG4gICAgcmV0dXJuIEludGVydmFsLmludmFsaWQoXG4gICAgICBcImVuZCBiZWZvcmUgc3RhcnRcIixcbiAgICAgIGBUaGUgZW5kIG9mIGFuIGludGVydmFsIG11c3QgYmUgYWZ0ZXIgaXRzIHN0YXJ0LCBidXQgeW91IGhhZCBzdGFydD0ke3N0YXJ0LnRvSVNPKCl9IGFuZCBlbmQ9JHtlbmQudG9JU08oKX1gXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vKipcbiAqIEFuIEludGVydmFsIG9iamVjdCByZXByZXNlbnRzIGEgaGFsZi1vcGVuIGludGVydmFsIG9mIHRpbWUsIHdoZXJlIGVhY2ggZW5kcG9pbnQgaXMgYSB7QGxpbmsgRGF0ZVRpbWV9LiBDb25jZXB0dWFsbHksIGl0J3MgYSBjb250YWluZXIgZm9yIHRob3NlIHR3byBlbmRwb2ludHMsIGFjY29tcGFuaWVkIGJ5IG1ldGhvZHMgZm9yIGNyZWF0aW5nLCBwYXJzaW5nLCBpbnRlcnJvZ2F0aW5nLCBjb21wYXJpbmcsIHRyYW5zZm9ybWluZywgYW5kIGZvcm1hdHRpbmcgdGhlbS5cbiAqXG4gKiBIZXJlIGlzIGEgYnJpZWYgb3ZlcnZpZXcgb2YgdGhlIG1vc3QgY29tbW9ubHkgdXNlZCBtZXRob2RzIGFuZCBnZXR0ZXJzIGluIEludGVydmFsOlxuICpcbiAqICogKipDcmVhdGlvbioqIFRvIGNyZWF0ZSBhbiBJbnRlcnZhbCwgdXNlIHtAbGluayBJbnRlcnZhbC5mcm9tRGF0ZVRpbWVzfSwge0BsaW5rIEludGVydmFsLmFmdGVyfSwge0BsaW5rIEludGVydmFsLmJlZm9yZX0sIG9yIHtAbGluayBJbnRlcnZhbC5mcm9tSVNPfS5cbiAqICogKipBY2Nlc3NvcnMqKiBVc2Uge0BsaW5rIEludGVydmFsI3N0YXJ0fSBhbmQge0BsaW5rIEludGVydmFsI2VuZH0gdG8gZ2V0IHRoZSBzdGFydCBhbmQgZW5kLlxuICogKiAqKkludGVycm9nYXRpb24qKiBUbyBhbmFseXplIHRoZSBJbnRlcnZhbCwgdXNlIHtAbGluayBJbnRlcnZhbCNjb3VudH0sIHtAbGluayBJbnRlcnZhbCNsZW5ndGh9LCB7QGxpbmsgSW50ZXJ2YWwjaGFzU2FtZX0sIHtAbGluayBJbnRlcnZhbCNjb250YWluc30sIHtAbGluayBJbnRlcnZhbCNpc0FmdGVyfSwgb3Ige0BsaW5rIEludGVydmFsI2lzQmVmb3JlfS5cbiAqICogKipUcmFuc2Zvcm1hdGlvbioqIFRvIGNyZWF0ZSBvdGhlciBJbnRlcnZhbHMgb3V0IG9mIHRoaXMgb25lLCB1c2Uge0BsaW5rIEludGVydmFsI3NldH0sIHtAbGluayBJbnRlcnZhbCNzcGxpdEF0fSwge0BsaW5rIEludGVydmFsI3NwbGl0Qnl9LCB7QGxpbmsgSW50ZXJ2YWwjZGl2aWRlRXF1YWxseX0sIHtAbGluayBJbnRlcnZhbC5tZXJnZX0sIHtAbGluayBJbnRlcnZhbC54b3J9LCB7QGxpbmsgSW50ZXJ2YWwjdW5pb259LCB7QGxpbmsgSW50ZXJ2YWwjaW50ZXJzZWN0aW9ufSwgb3Ige0BsaW5rIEludGVydmFsI2RpZmZlcmVuY2V9LlxuICogKiAqKkNvbXBhcmlzb24qKiBUbyBjb21wYXJlIHRoaXMgSW50ZXJ2YWwgdG8gYW5vdGhlciBvbmUsIHVzZSB7QGxpbmsgSW50ZXJ2YWwjZXF1YWxzfSwge0BsaW5rIEludGVydmFsI292ZXJsYXBzfSwge0BsaW5rIEludGVydmFsI2FidXRzU3RhcnR9LCB7QGxpbmsgSW50ZXJ2YWwjYWJ1dHNFbmR9LCB7QGxpbmsgSW50ZXJ2YWwjZW5ndWxmc31cbiAqICogKipPdXRwdXQqKiBUbyBjb252ZXJ0IHRoZSBJbnRlcnZhbCBpbnRvIG90aGVyIHJlcHJlc2VudGF0aW9ucywgc2VlIHtAbGluayBJbnRlcnZhbCN0b1N0cmluZ30sIHtAbGluayBJbnRlcnZhbCN0b0xvY2FsZVN0cmluZ30sIHtAbGluayBJbnRlcnZhbCN0b0lTT30sIHtAbGluayBJbnRlcnZhbCN0b0lTT0RhdGV9LCB7QGxpbmsgSW50ZXJ2YWwjdG9JU09UaW1lfSwge0BsaW5rIEludGVydmFsI3RvRm9ybWF0fSwgYW5kIHtAbGluayBJbnRlcnZhbCN0b0R1cmF0aW9ufS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSW50ZXJ2YWwge1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgIC8qKlxuICAgICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMucyA9IGNvbmZpZy5zdGFydDtcbiAgICAvKipcbiAgICAgKiBAYWNjZXNzIHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLmUgPSBjb25maWcuZW5kO1xuICAgIC8qKlxuICAgICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMuaW52YWxpZCA9IGNvbmZpZy5pbnZhbGlkIHx8IG51bGw7XG4gICAgLyoqXG4gICAgICogQGFjY2VzcyBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5pc0x1eG9uSW50ZXJ2YWwgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBpbnZhbGlkIEludGVydmFsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uIC0gc2ltcGxlIHN0cmluZyBvZiB3aHkgdGhpcyBJbnRlcnZhbCBpcyBpbnZhbGlkLiBTaG91bGQgbm90IGNvbnRhaW4gcGFyYW1ldGVycyBvciBhbnl0aGluZyBlbHNlIGRhdGEtZGVwZW5kZW50XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZXhwbGFuYXRpb249bnVsbF0gLSBsb25nZXIgZXhwbGFuYXRpb24sIG1heSBpbmNsdWRlIHBhcmFtZXRlcnMgYW5kIG90aGVyIHVzZWZ1bCBkZWJ1Z2dpbmcgaW5mb3JtYXRpb25cbiAgICogQHJldHVybiB7SW50ZXJ2YWx9XG4gICAqL1xuICBzdGF0aWMgaW52YWxpZChyZWFzb24sIGV4cGxhbmF0aW9uID0gbnVsbCkge1xuICAgIGlmICghcmVhc29uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3IoXCJuZWVkIHRvIHNwZWNpZnkgYSByZWFzb24gdGhlIEludGVydmFsIGlzIGludmFsaWRcIik7XG4gICAgfVxuXG4gICAgY29uc3QgaW52YWxpZCA9IHJlYXNvbiBpbnN0YW5jZW9mIEludmFsaWQgPyByZWFzb24gOiBuZXcgSW52YWxpZChyZWFzb24sIGV4cGxhbmF0aW9uKTtcblxuICAgIGlmIChTZXR0aW5ncy50aHJvd09uSW52YWxpZCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRJbnRlcnZhbEVycm9yKGludmFsaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IEludGVydmFsKHsgaW52YWxpZCB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIEludGVydmFsIGZyb20gYSBzdGFydCBEYXRlVGltZSBhbmQgYW4gZW5kIERhdGVUaW1lLiBJbmNsdXNpdmUgb2YgdGhlIHN0YXJ0IGJ1dCBub3QgdGhlIGVuZC5cbiAgICogQHBhcmFtIHtEYXRlVGltZXxEYXRlfE9iamVjdH0gc3RhcnRcbiAgICogQHBhcmFtIHtEYXRlVGltZXxEYXRlfE9iamVjdH0gZW5kXG4gICAqIEByZXR1cm4ge0ludGVydmFsfVxuICAgKi9cbiAgc3RhdGljIGZyb21EYXRlVGltZXMoc3RhcnQsIGVuZCkge1xuICAgIGNvbnN0IGJ1aWx0U3RhcnQgPSBmcmllbmRseURhdGVUaW1lKHN0YXJ0KSxcbiAgICAgIGJ1aWx0RW5kID0gZnJpZW5kbHlEYXRlVGltZShlbmQpO1xuXG4gICAgY29uc3QgdmFsaWRhdGVFcnJvciA9IHZhbGlkYXRlU3RhcnRFbmQoYnVpbHRTdGFydCwgYnVpbHRFbmQpO1xuXG4gICAgaWYgKHZhbGlkYXRlRXJyb3IgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG5ldyBJbnRlcnZhbCh7XG4gICAgICAgIHN0YXJ0OiBidWlsdFN0YXJ0LFxuICAgICAgICBlbmQ6IGJ1aWx0RW5kLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB2YWxpZGF0ZUVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gSW50ZXJ2YWwgZnJvbSBhIHN0YXJ0IERhdGVUaW1lIGFuZCBhIER1cmF0aW9uIHRvIGV4dGVuZCB0by5cbiAgICogQHBhcmFtIHtEYXRlVGltZXxEYXRlfE9iamVjdH0gc3RhcnRcbiAgICogQHBhcmFtIHtEdXJhdGlvbnxPYmplY3R8bnVtYmVyfSBkdXJhdGlvbiAtIHRoZSBsZW5ndGggb2YgdGhlIEludGVydmFsLlxuICAgKiBAcmV0dXJuIHtJbnRlcnZhbH1cbiAgICovXG4gIHN0YXRpYyBhZnRlcihzdGFydCwgZHVyYXRpb24pIHtcbiAgICBjb25zdCBkdXIgPSBEdXJhdGlvbi5mcm9tRHVyYXRpb25MaWtlKGR1cmF0aW9uKSxcbiAgICAgIGR0ID0gZnJpZW5kbHlEYXRlVGltZShzdGFydCk7XG4gICAgcmV0dXJuIEludGVydmFsLmZyb21EYXRlVGltZXMoZHQsIGR0LnBsdXMoZHVyKSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIEludGVydmFsIGZyb20gYW4gZW5kIERhdGVUaW1lIGFuZCBhIER1cmF0aW9uIHRvIGV4dGVuZCBiYWNrd2FyZHMgdG8uXG4gICAqIEBwYXJhbSB7RGF0ZVRpbWV8RGF0ZXxPYmplY3R9IGVuZFxuICAgKiBAcGFyYW0ge0R1cmF0aW9ufE9iamVjdHxudW1iZXJ9IGR1cmF0aW9uIC0gdGhlIGxlbmd0aCBvZiB0aGUgSW50ZXJ2YWwuXG4gICAqIEByZXR1cm4ge0ludGVydmFsfVxuICAgKi9cbiAgc3RhdGljIGJlZm9yZShlbmQsIGR1cmF0aW9uKSB7XG4gICAgY29uc3QgZHVyID0gRHVyYXRpb24uZnJvbUR1cmF0aW9uTGlrZShkdXJhdGlvbiksXG4gICAgICBkdCA9IGZyaWVuZGx5RGF0ZVRpbWUoZW5kKTtcbiAgICByZXR1cm4gSW50ZXJ2YWwuZnJvbURhdGVUaW1lcyhkdC5taW51cyhkdXIpLCBkdCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIEludGVydmFsIGZyb20gYW4gSVNPIDg2MDEgc3RyaW5nLlxuICAgKiBBY2NlcHRzIGA8c3RhcnQ+LzxlbmQ+YCwgYDxzdGFydD4vPGR1cmF0aW9uPmAsIGFuZCBgPGR1cmF0aW9uPi88ZW5kPmAgZm9ybWF0cy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSB0aGUgSVNPIHN0cmluZyB0byBwYXJzZVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdHNdIC0gb3B0aW9ucyB0byBwYXNzIHtAbGluayBEYXRlVGltZSNmcm9tSVNPfSBhbmQgb3B0aW9uYWxseSB7QGxpbmsgRHVyYXRpb24jZnJvbUlTT31cbiAgICogQHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSNUaW1lX2ludGVydmFsc1xuICAgKiBAcmV0dXJuIHtJbnRlcnZhbH1cbiAgICovXG4gIHN0YXRpYyBmcm9tSVNPKHRleHQsIG9wdHMpIHtcbiAgICBjb25zdCBbcywgZV0gPSAodGV4dCB8fCBcIlwiKS5zcGxpdChcIi9cIiwgMik7XG4gICAgaWYgKHMgJiYgZSkge1xuICAgICAgbGV0IHN0YXJ0LCBzdGFydElzVmFsaWQ7XG4gICAgICB0cnkge1xuICAgICAgICBzdGFydCA9IERhdGVUaW1lLmZyb21JU08ocywgb3B0cyk7XG4gICAgICAgIHN0YXJ0SXNWYWxpZCA9IHN0YXJ0LmlzVmFsaWQ7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHN0YXJ0SXNWYWxpZCA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBsZXQgZW5kLCBlbmRJc1ZhbGlkO1xuICAgICAgdHJ5IHtcbiAgICAgICAgZW5kID0gRGF0ZVRpbWUuZnJvbUlTTyhlLCBvcHRzKTtcbiAgICAgICAgZW5kSXNWYWxpZCA9IGVuZC5pc1ZhbGlkO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlbmRJc1ZhbGlkID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGFydElzVmFsaWQgJiYgZW5kSXNWYWxpZCkge1xuICAgICAgICByZXR1cm4gSW50ZXJ2YWwuZnJvbURhdGVUaW1lcyhzdGFydCwgZW5kKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXJ0SXNWYWxpZCkge1xuICAgICAgICBjb25zdCBkdXIgPSBEdXJhdGlvbi5mcm9tSVNPKGUsIG9wdHMpO1xuICAgICAgICBpZiAoZHVyLmlzVmFsaWQpIHtcbiAgICAgICAgICByZXR1cm4gSW50ZXJ2YWwuYWZ0ZXIoc3RhcnQsIGR1cik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZW5kSXNWYWxpZCkge1xuICAgICAgICBjb25zdCBkdXIgPSBEdXJhdGlvbi5mcm9tSVNPKHMsIG9wdHMpO1xuICAgICAgICBpZiAoZHVyLmlzVmFsaWQpIHtcbiAgICAgICAgICByZXR1cm4gSW50ZXJ2YWwuYmVmb3JlKGVuZCwgZHVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gSW50ZXJ2YWwuaW52YWxpZChcInVucGFyc2FibGVcIiwgYHRoZSBpbnB1dCBcIiR7dGV4dH1cIiBjYW4ndCBiZSBwYXJzZWQgYXMgSVNPIDg2MDFgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhbiBvYmplY3QgaXMgYW4gSW50ZXJ2YWwuIFdvcmtzIGFjcm9zcyBjb250ZXh0IGJvdW5kYXJpZXNcbiAgICogQHBhcmFtIHtvYmplY3R9IG9cbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIHN0YXRpYyBpc0ludGVydmFsKG8pIHtcbiAgICByZXR1cm4gKG8gJiYgby5pc0x1eG9uSW50ZXJ2YWwpIHx8IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHN0YXJ0IG9mIHRoZSBJbnRlcnZhbFxuICAgKiBAdHlwZSB7RGF0ZVRpbWV9XG4gICAqL1xuICBnZXQgc3RhcnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IHRoaXMucyA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZW5kIG9mIHRoZSBJbnRlcnZhbFxuICAgKiBAdHlwZSB7RGF0ZVRpbWV9XG4gICAqL1xuICBnZXQgZW5kKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLmUgOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciB0aGlzIEludGVydmFsJ3MgZW5kIGlzIGF0IGxlYXN0IGl0cyBzdGFydCwgbWVhbmluZyB0aGF0IHRoZSBJbnRlcnZhbCBpc24ndCAnYmFja3dhcmRzJy5cbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqL1xuICBnZXQgaXNWYWxpZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnZhbGlkUmVhc29uID09PSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gZXJyb3IgY29kZSBpZiB0aGlzIEludGVydmFsIGlzIGludmFsaWQsIG9yIG51bGwgaWYgdGhlIEludGVydmFsIGlzIHZhbGlkXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqL1xuICBnZXQgaW52YWxpZFJlYXNvbigpIHtcbiAgICByZXR1cm4gdGhpcy5pbnZhbGlkID8gdGhpcy5pbnZhbGlkLnJlYXNvbiA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBleHBsYW5hdGlvbiBvZiB3aHkgdGhpcyBJbnRlcnZhbCBiZWNhbWUgaW52YWxpZCwgb3IgbnVsbCBpZiB0aGUgSW50ZXJ2YWwgaXMgdmFsaWRcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICovXG4gIGdldCBpbnZhbGlkRXhwbGFuYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuaW52YWxpZCA/IHRoaXMuaW52YWxpZC5leHBsYW5hdGlvbiA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBJbnRlcnZhbCBpbiB0aGUgc3BlY2lmaWVkIHVuaXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1bml0IC0gdGhlIHVuaXQgKHN1Y2ggYXMgJ2hvdXJzJyBvciAnZGF5cycpIHRvIHJldHVybiB0aGUgbGVuZ3RoIGluLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICBsZW5ndGgodW5pdCA9IFwibWlsbGlzZWNvbmRzXCIpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy50b0R1cmF0aW9uKC4uLlt1bml0XSkuZ2V0KHVuaXQpIDogTmFOO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGNvdW50IG9mIG1pbnV0ZXMsIGhvdXJzLCBkYXlzLCBtb250aHMsIG9yIHllYXJzIGluY2x1ZGVkIGluIHRoZSBJbnRlcnZhbCwgZXZlbiBpbiBwYXJ0LlxuICAgKiBVbmxpa2Uge0BsaW5rIEludGVydmFsI2xlbmd0aH0gdGhpcyBjb3VudHMgc2VjdGlvbnMgb2YgdGhlIGNhbGVuZGFyLCBub3QgcGVyaW9kcyBvZiB0aW1lLCBlLmcuIHNwZWNpZnlpbmcgJ2RheSdcbiAgICogYXNrcyAnd2hhdCBkYXRlcyBhcmUgaW5jbHVkZWQgaW4gdGhpcyBpbnRlcnZhbD8nLCBub3QgJ2hvdyBtYW55IGRheXMgbG9uZyBpcyB0aGlzIGludGVydmFsPydcbiAgICogQHBhcmFtIHtzdHJpbmd9IFt1bml0PSdtaWxsaXNlY29uZHMnXSAtIHRoZSB1bml0IG9mIHRpbWUgdG8gY291bnQuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0aW9uc1xuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLnVzZUxvY2FsZVdlZWtzPWZhbHNlXSAtIElmIHRydWUsIHVzZSB3ZWVrcyBiYXNlZCBvbiB0aGUgbG9jYWxlLCBpLmUuIHVzZSB0aGUgbG9jYWxlLWRlcGVuZGVudCBzdGFydCBvZiB0aGUgd2VlazsgdGhpcyBvcGVyYXRpb24gd2lsbCBhbHdheXMgdXNlIHRoZSBsb2NhbGUgb2YgdGhlIHN0YXJ0IERhdGVUaW1lXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGNvdW50KHVuaXQgPSBcIm1pbGxpc2Vjb25kc1wiLCBvcHRzKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBOYU47XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLnN0YXJ0LnN0YXJ0T2YodW5pdCwgb3B0cyk7XG4gICAgbGV0IGVuZDtcbiAgICBpZiAob3B0cz8udXNlTG9jYWxlV2Vla3MpIHtcbiAgICAgIGVuZCA9IHRoaXMuZW5kLnJlY29uZmlndXJlKHsgbG9jYWxlOiBzdGFydC5sb2NhbGUgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVuZCA9IHRoaXMuZW5kO1xuICAgIH1cbiAgICBlbmQgPSBlbmQuc3RhcnRPZih1bml0LCBvcHRzKTtcbiAgICByZXR1cm4gTWF0aC5mbG9vcihlbmQuZGlmZihzdGFydCwgdW5pdCkuZ2V0KHVuaXQpKSArIChlbmQudmFsdWVPZigpICE9PSB0aGlzLmVuZC52YWx1ZU9mKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciB0aGlzIEludGVydmFsJ3Mgc3RhcnQgYW5kIGVuZCBhcmUgYm90aCBpbiB0aGUgc2FtZSB1bml0IG9mIHRpbWVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVuaXQgLSB0aGUgdW5pdCBvZiB0aW1lIHRvIGNoZWNrIHNhbWVuZXNzIG9uXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBoYXNTYW1lKHVuaXQpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy5pc0VtcHR5KCkgfHwgdGhpcy5lLm1pbnVzKDEpLmhhc1NhbWUodGhpcy5zLCB1bml0KSA6IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB3aGV0aGVyIHRoaXMgSW50ZXJ2YWwgaGFzIHRoZSBzYW1lIHN0YXJ0IGFuZCBlbmQgRGF0ZVRpbWVzLlxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaXNFbXB0eSgpIHtcbiAgICByZXR1cm4gdGhpcy5zLnZhbHVlT2YoKSA9PT0gdGhpcy5lLnZhbHVlT2YoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gd2hldGhlciB0aGlzIEludGVydmFsJ3Mgc3RhcnQgaXMgYWZ0ZXIgdGhlIHNwZWNpZmllZCBEYXRlVGltZS5cbiAgICogQHBhcmFtIHtEYXRlVGltZX0gZGF0ZVRpbWVcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGlzQWZ0ZXIoZGF0ZVRpbWUpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0aGlzLnMgPiBkYXRlVGltZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gd2hldGhlciB0aGlzIEludGVydmFsJ3MgZW5kIGlzIGJlZm9yZSB0aGUgc3BlY2lmaWVkIERhdGVUaW1lLlxuICAgKiBAcGFyYW0ge0RhdGVUaW1lfSBkYXRlVGltZVxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaXNCZWZvcmUoZGF0ZVRpbWUpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0aGlzLmUgPD0gZGF0ZVRpbWU7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHdoZXRoZXIgdGhpcyBJbnRlcnZhbCBjb250YWlucyB0aGUgc3BlY2lmaWVkIERhdGVUaW1lLlxuICAgKiBAcGFyYW0ge0RhdGVUaW1lfSBkYXRlVGltZVxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgY29udGFpbnMoZGF0ZVRpbWUpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0aGlzLnMgPD0gZGF0ZVRpbWUgJiYgdGhpcy5lID4gZGF0ZVRpbWU7XG4gIH1cblxuICAvKipcbiAgICogXCJTZXRzXCIgdGhlIHN0YXJ0IGFuZC9vciBlbmQgZGF0ZXMuIFJldHVybnMgYSBuZXdseS1jb25zdHJ1Y3RlZCBJbnRlcnZhbC5cbiAgICogQHBhcmFtIHtPYmplY3R9IHZhbHVlcyAtIHRoZSB2YWx1ZXMgdG8gc2V0XG4gICAqIEBwYXJhbSB7RGF0ZVRpbWV9IHZhbHVlcy5zdGFydCAtIHRoZSBzdGFydGluZyBEYXRlVGltZVxuICAgKiBAcGFyYW0ge0RhdGVUaW1lfSB2YWx1ZXMuZW5kIC0gdGhlIGVuZGluZyBEYXRlVGltZVxuICAgKiBAcmV0dXJuIHtJbnRlcnZhbH1cbiAgICovXG4gIHNldCh7IHN0YXJ0LCBlbmQgfSA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB0aGlzO1xuICAgIHJldHVybiBJbnRlcnZhbC5mcm9tRGF0ZVRpbWVzKHN0YXJ0IHx8IHRoaXMucywgZW5kIHx8IHRoaXMuZSk7XG4gIH1cblxuICAvKipcbiAgICogU3BsaXQgdGhpcyBJbnRlcnZhbCBhdCBlYWNoIG9mIHRoZSBzcGVjaWZpZWQgRGF0ZVRpbWVzXG4gICAqIEBwYXJhbSB7Li4uRGF0ZVRpbWV9IGRhdGVUaW1lcyAtIHRoZSB1bml0IG9mIHRpbWUgdG8gY291bnQuXG4gICAqIEByZXR1cm4ge0FycmF5fVxuICAgKi9cbiAgc3BsaXRBdCguLi5kYXRlVGltZXMpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IHNvcnRlZCA9IGRhdGVUaW1lc1xuICAgICAgICAubWFwKGZyaWVuZGx5RGF0ZVRpbWUpXG4gICAgICAgIC5maWx0ZXIoKGQpID0+IHRoaXMuY29udGFpbnMoZCkpXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhLnRvTWlsbGlzKCkgLSBiLnRvTWlsbGlzKCkpLFxuICAgICAgcmVzdWx0cyA9IFtdO1xuICAgIGxldCB7IHMgfSA9IHRoaXMsXG4gICAgICBpID0gMDtcblxuICAgIHdoaWxlIChzIDwgdGhpcy5lKSB7XG4gICAgICBjb25zdCBhZGRlZCA9IHNvcnRlZFtpXSB8fCB0aGlzLmUsXG4gICAgICAgIG5leHQgPSArYWRkZWQgPiArdGhpcy5lID8gdGhpcy5lIDogYWRkZWQ7XG4gICAgICByZXN1bHRzLnB1c2goSW50ZXJ2YWwuZnJvbURhdGVUaW1lcyhzLCBuZXh0KSk7XG4gICAgICBzID0gbmV4dDtcbiAgICAgIGkgKz0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGxpdCB0aGlzIEludGVydmFsIGludG8gc21hbGxlciBJbnRlcnZhbHMsIGVhY2ggb2YgdGhlIHNwZWNpZmllZCBsZW5ndGguXG4gICAqIExlZnQgb3ZlciB0aW1lIGlzIGdyb3VwZWQgaW50byBhIHNtYWxsZXIgaW50ZXJ2YWxcbiAgICogQHBhcmFtIHtEdXJhdGlvbnxPYmplY3R8bnVtYmVyfSBkdXJhdGlvbiAtIFRoZSBsZW5ndGggb2YgZWFjaCByZXN1bHRpbmcgaW50ZXJ2YWwuXG4gICAqIEByZXR1cm4ge0FycmF5fVxuICAgKi9cbiAgc3BsaXRCeShkdXJhdGlvbikge1xuICAgIGNvbnN0IGR1ciA9IER1cmF0aW9uLmZyb21EdXJhdGlvbkxpa2UoZHVyYXRpb24pO1xuXG4gICAgaWYgKCF0aGlzLmlzVmFsaWQgfHwgIWR1ci5pc1ZhbGlkIHx8IGR1ci5hcyhcIm1pbGxpc2Vjb25kc1wiKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGxldCB7IHMgfSA9IHRoaXMsXG4gICAgICBpZHggPSAxLFxuICAgICAgbmV4dDtcblxuICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICB3aGlsZSAocyA8IHRoaXMuZSkge1xuICAgICAgY29uc3QgYWRkZWQgPSB0aGlzLnN0YXJ0LnBsdXMoZHVyLm1hcFVuaXRzKCh4KSA9PiB4ICogaWR4KSk7XG4gICAgICBuZXh0ID0gK2FkZGVkID4gK3RoaXMuZSA/IHRoaXMuZSA6IGFkZGVkO1xuICAgICAgcmVzdWx0cy5wdXNoKEludGVydmFsLmZyb21EYXRlVGltZXMocywgbmV4dCkpO1xuICAgICAgcyA9IG5leHQ7XG4gICAgICBpZHggKz0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGxpdCB0aGlzIEludGVydmFsIGludG8gdGhlIHNwZWNpZmllZCBudW1iZXIgb2Ygc21hbGxlciBpbnRlcnZhbHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXJPZlBhcnRzIC0gVGhlIG51bWJlciBvZiBJbnRlcnZhbHMgdG8gZGl2aWRlIHRoZSBJbnRlcnZhbCBpbnRvLlxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICovXG4gIGRpdmlkZUVxdWFsbHkobnVtYmVyT2ZQYXJ0cykge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkKSByZXR1cm4gW107XG4gICAgcmV0dXJuIHRoaXMuc3BsaXRCeSh0aGlzLmxlbmd0aCgpIC8gbnVtYmVyT2ZQYXJ0cykuc2xpY2UoMCwgbnVtYmVyT2ZQYXJ0cyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHdoZXRoZXIgdGhpcyBJbnRlcnZhbCBvdmVybGFwcyB3aXRoIHRoZSBzcGVjaWZpZWQgSW50ZXJ2YWxcbiAgICogQHBhcmFtIHtJbnRlcnZhbH0gb3RoZXJcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIG92ZXJsYXBzKG90aGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuZSA+IG90aGVyLnMgJiYgdGhpcy5zIDwgb3RoZXIuZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gd2hldGhlciB0aGlzIEludGVydmFsJ3MgZW5kIGlzIGFkamFjZW50IHRvIHRoZSBzcGVjaWZpZWQgSW50ZXJ2YWwncyBzdGFydC5cbiAgICogQHBhcmFtIHtJbnRlcnZhbH0gb3RoZXJcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGFidXRzU3RhcnQob3RoZXIpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiArdGhpcy5lID09PSArb3RoZXIucztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gd2hldGhlciB0aGlzIEludGVydmFsJ3Mgc3RhcnQgaXMgYWRqYWNlbnQgdG8gdGhlIHNwZWNpZmllZCBJbnRlcnZhbCdzIGVuZC5cbiAgICogQHBhcmFtIHtJbnRlcnZhbH0gb3RoZXJcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGFidXRzRW5kKG90aGVyKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gK290aGVyLmUgPT09ICt0aGlzLnM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHdoZXRoZXIgdGhpcyBJbnRlcnZhbCBlbmd1bGZzIHRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBzcGVjaWZpZWQgSW50ZXJ2YWwuXG4gICAqIEBwYXJhbSB7SW50ZXJ2YWx9IG90aGVyXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBlbmd1bGZzKG90aGVyKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5zIDw9IG90aGVyLnMgJiYgdGhpcy5lID49IG90aGVyLmU7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHdoZXRoZXIgdGhpcyBJbnRlcnZhbCBoYXMgdGhlIHNhbWUgc3RhcnQgYW5kIGVuZCBhcyB0aGUgc3BlY2lmaWVkIEludGVydmFsLlxuICAgKiBAcGFyYW0ge0ludGVydmFsfSBvdGhlclxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgZXF1YWxzKG90aGVyKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQgfHwgIW90aGVyLmlzVmFsaWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zLmVxdWFscyhvdGhlci5zKSAmJiB0aGlzLmUuZXF1YWxzKG90aGVyLmUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbiBJbnRlcnZhbCByZXByZXNlbnRpbmcgdGhlIGludGVyc2VjdGlvbiBvZiB0aGlzIEludGVydmFsIGFuZCB0aGUgc3BlY2lmaWVkIEludGVydmFsLlxuICAgKiBTcGVjaWZpY2FsbHksIHRoZSByZXN1bHRpbmcgSW50ZXJ2YWwgaGFzIHRoZSBtYXhpbXVtIHN0YXJ0IHRpbWUgYW5kIHRoZSBtaW5pbXVtIGVuZCB0aW1lIG9mIHRoZSB0d28gSW50ZXJ2YWxzLlxuICAgKiBSZXR1cm5zIG51bGwgaWYgdGhlIGludGVyc2VjdGlvbiBpcyBlbXB0eSwgbWVhbmluZywgdGhlIGludGVydmFscyBkb24ndCBpbnRlcnNlY3QuXG4gICAqIEBwYXJhbSB7SW50ZXJ2YWx9IG90aGVyXG4gICAqIEByZXR1cm4ge0ludGVydmFsfVxuICAgKi9cbiAgaW50ZXJzZWN0aW9uKG90aGVyKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB0aGlzO1xuICAgIGNvbnN0IHMgPSB0aGlzLnMgPiBvdGhlci5zID8gdGhpcy5zIDogb3RoZXIucyxcbiAgICAgIGUgPSB0aGlzLmUgPCBvdGhlci5lID8gdGhpcy5lIDogb3RoZXIuZTtcblxuICAgIGlmIChzID49IGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gSW50ZXJ2YWwuZnJvbURhdGVUaW1lcyhzLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGFuIEludGVydmFsIHJlcHJlc2VudGluZyB0aGUgdW5pb24gb2YgdGhpcyBJbnRlcnZhbCBhbmQgdGhlIHNwZWNpZmllZCBJbnRlcnZhbC5cbiAgICogU3BlY2lmaWNhbGx5LCB0aGUgcmVzdWx0aW5nIEludGVydmFsIGhhcyB0aGUgbWluaW11bSBzdGFydCB0aW1lIGFuZCB0aGUgbWF4aW11bSBlbmQgdGltZSBvZiB0aGUgdHdvIEludGVydmFscy5cbiAgICogQHBhcmFtIHtJbnRlcnZhbH0gb3RoZXJcbiAgICogQHJldHVybiB7SW50ZXJ2YWx9XG4gICAqL1xuICB1bmlvbihvdGhlcikge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkKSByZXR1cm4gdGhpcztcbiAgICBjb25zdCBzID0gdGhpcy5zIDwgb3RoZXIucyA/IHRoaXMucyA6IG90aGVyLnMsXG4gICAgICBlID0gdGhpcy5lID4gb3RoZXIuZSA/IHRoaXMuZSA6IG90aGVyLmU7XG4gICAgcmV0dXJuIEludGVydmFsLmZyb21EYXRlVGltZXMocywgZSk7XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2UgYW4gYXJyYXkgb2YgSW50ZXJ2YWxzIGludG8gYSBlcXVpdmFsZW50IG1pbmltYWwgc2V0IG9mIEludGVydmFscy5cbiAgICogQ29tYmluZXMgb3ZlcmxhcHBpbmcgYW5kIGFkamFjZW50IEludGVydmFscy5cbiAgICogQHBhcmFtIHtBcnJheX0gaW50ZXJ2YWxzXG4gICAqIEByZXR1cm4ge0FycmF5fVxuICAgKi9cbiAgc3RhdGljIG1lcmdlKGludGVydmFscykge1xuICAgIGNvbnN0IFtmb3VuZCwgZmluYWxdID0gaW50ZXJ2YWxzXG4gICAgICAuc29ydCgoYSwgYikgPT4gYS5zIC0gYi5zKVxuICAgICAgLnJlZHVjZShcbiAgICAgICAgKFtzb2ZhciwgY3VycmVudF0sIGl0ZW0pID0+IHtcbiAgICAgICAgICBpZiAoIWN1cnJlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBbc29mYXIsIGl0ZW1dO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudC5vdmVybGFwcyhpdGVtKSB8fCBjdXJyZW50LmFidXRzU3RhcnQoaXRlbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBbc29mYXIsIGN1cnJlbnQudW5pb24oaXRlbSldO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gW3NvZmFyLmNvbmNhdChbY3VycmVudF0pLCBpdGVtXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFtbXSwgbnVsbF1cbiAgICAgICk7XG4gICAgaWYgKGZpbmFsKSB7XG4gICAgICBmb3VuZC5wdXNoKGZpbmFsKTtcbiAgICB9XG4gICAgcmV0dXJuIGZvdW5kO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbiBhcnJheSBvZiBJbnRlcnZhbHMgcmVwcmVzZW50aW5nIHRoZSBzcGFucyBvZiB0aW1lIHRoYXQgb25seSBhcHBlYXIgaW4gb25lIG9mIHRoZSBzcGVjaWZpZWQgSW50ZXJ2YWxzLlxuICAgKiBAcGFyYW0ge0FycmF5fSBpbnRlcnZhbHNcbiAgICogQHJldHVybiB7QXJyYXl9XG4gICAqL1xuICBzdGF0aWMgeG9yKGludGVydmFscykge1xuICAgIGxldCBzdGFydCA9IG51bGwsXG4gICAgICBjdXJyZW50Q291bnQgPSAwO1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXSxcbiAgICAgIGVuZHMgPSBpbnRlcnZhbHMubWFwKChpKSA9PiBbXG4gICAgICAgIHsgdGltZTogaS5zLCB0eXBlOiBcInNcIiB9LFxuICAgICAgICB7IHRpbWU6IGkuZSwgdHlwZTogXCJlXCIgfSxcbiAgICAgIF0pLFxuICAgICAgZmxhdHRlbmVkID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdCguLi5lbmRzKSxcbiAgICAgIGFyciA9IGZsYXR0ZW5lZC5zb3J0KChhLCBiKSA9PiBhLnRpbWUgLSBiLnRpbWUpO1xuXG4gICAgZm9yIChjb25zdCBpIG9mIGFycikge1xuICAgICAgY3VycmVudENvdW50ICs9IGkudHlwZSA9PT0gXCJzXCIgPyAxIDogLTE7XG5cbiAgICAgIGlmIChjdXJyZW50Q291bnQgPT09IDEpIHtcbiAgICAgICAgc3RhcnQgPSBpLnRpbWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoc3RhcnQgJiYgK3N0YXJ0ICE9PSAraS50aW1lKSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKEludGVydmFsLmZyb21EYXRlVGltZXMoc3RhcnQsIGkudGltZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhcnQgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBJbnRlcnZhbC5tZXJnZShyZXN1bHRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYW4gSW50ZXJ2YWwgcmVwcmVzZW50aW5nIHRoZSBzcGFuIG9mIHRpbWUgaW4gdGhpcyBJbnRlcnZhbCB0aGF0IGRvZXNuJ3Qgb3ZlcmxhcCB3aXRoIGFueSBvZiB0aGUgc3BlY2lmaWVkIEludGVydmFscy5cbiAgICogQHBhcmFtIHsuLi5JbnRlcnZhbH0gaW50ZXJ2YWxzXG4gICAqIEByZXR1cm4ge0FycmF5fVxuICAgKi9cbiAgZGlmZmVyZW5jZSguLi5pbnRlcnZhbHMpIHtcbiAgICByZXR1cm4gSW50ZXJ2YWwueG9yKFt0aGlzXS5jb25jYXQoaW50ZXJ2YWxzKSlcbiAgICAgIC5tYXAoKGkpID0+IHRoaXMuaW50ZXJzZWN0aW9uKGkpKVxuICAgICAgLmZpbHRlcigoaSkgPT4gaSAmJiAhaS5pc0VtcHR5KCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBJbnRlcnZhbCBhcHByb3ByaWF0ZSBmb3IgZGVidWdnaW5nLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b1N0cmluZygpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIElOVkFMSUQ7XG4gICAgcmV0dXJuIGBbJHt0aGlzLnMudG9JU08oKX0gXHUyMDEzICR7dGhpcy5lLnRvSVNPKCl9KWA7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEludGVydmFsIGFwcHJvcHJpYXRlIGZvciB0aGUgUkVQTC5cbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgW1N5bWJvbC5mb3IoXCJub2RlanMudXRpbC5pbnNwZWN0LmN1c3RvbVwiKV0oKSB7XG4gICAgaWYgKHRoaXMuaXNWYWxpZCkge1xuICAgICAgcmV0dXJuIGBJbnRlcnZhbCB7IHN0YXJ0OiAke3RoaXMucy50b0lTTygpfSwgZW5kOiAke3RoaXMuZS50b0lTTygpfSB9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGBJbnRlcnZhbCB7IEludmFsaWQsIHJlYXNvbjogJHt0aGlzLmludmFsaWRSZWFzb259IH1gO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbG9jYWxpemVkIHN0cmluZyByZXByZXNlbnRpbmcgdGhpcyBJbnRlcnZhbC4gQWNjZXB0cyB0aGUgc2FtZSBvcHRpb25zIGFzIHRoZVxuICAgKiBJbnRsLkRhdGVUaW1lRm9ybWF0IGNvbnN0cnVjdG9yIGFuZCBhbnkgcHJlc2V0cyBkZWZpbmVkIGJ5IEx1eG9uLCBzdWNoIGFzXG4gICAqIHtAbGluayBEYXRlVGltZS5EQVRFX0ZVTEx9IG9yIHtAbGluayBEYXRlVGltZS5USU1FX1NJTVBMRX0uIFRoZSBleGFjdCBiZWhhdmlvciBvZiB0aGlzIG1ldGhvZFxuICAgKiBpcyBicm93c2VyLXNwZWNpZmljLCBidXQgaW4gZ2VuZXJhbCBpdCB3aWxsIHJldHVybiBhbiBhcHByb3ByaWF0ZSByZXByZXNlbnRhdGlvbiBvZiB0aGVcbiAgICogSW50ZXJ2YWwgaW4gdGhlIGFzc2lnbmVkIGxvY2FsZS4gRGVmYXVsdHMgdG8gdGhlIHN5c3RlbSdzIGxvY2FsZSBpZiBubyBsb2NhbGUgaGFzIGJlZW5cbiAgICogc3BlY2lmaWVkLlxuICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0RhdGVUaW1lRm9ybWF0XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbZm9ybWF0T3B0cz1EYXRlVGltZS5EQVRFX1NIT1JUXSAtIEVpdGhlciBhIERhdGVUaW1lIHByZXNldCBvclxuICAgKiBJbnRsLkRhdGVUaW1lRm9ybWF0IGNvbnN0cnVjdG9yIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gT3B0aW9ucyB0byBvdmVycmlkZSB0aGUgY29uZmlndXJhdGlvbiBvZiB0aGUgc3RhcnQgRGF0ZVRpbWUuXG4gICAqIEBleGFtcGxlIEludGVydmFsLmZyb21JU08oJzIwMjItMTEtMDdUMDk6MDBaLzIwMjItMTEtMDhUMDk6MDBaJykudG9Mb2NhbGVTdHJpbmcoKTsgLy89PiAxMS83LzIwMjIgXHUyMDEzIDExLzgvMjAyMlxuICAgKiBAZXhhbXBsZSBJbnRlcnZhbC5mcm9tSVNPKCcyMDIyLTExLTA3VDA5OjAwWi8yMDIyLTExLTA4VDA5OjAwWicpLnRvTG9jYWxlU3RyaW5nKERhdGVUaW1lLkRBVEVfRlVMTCk7IC8vPT4gTm92ZW1iZXIgNyBcdTIwMTMgOCwgMjAyMlxuICAgKiBAZXhhbXBsZSBJbnRlcnZhbC5mcm9tSVNPKCcyMDIyLTExLTA3VDA5OjAwWi8yMDIyLTExLTA4VDA5OjAwWicpLnRvTG9jYWxlU3RyaW5nKERhdGVUaW1lLkRBVEVfRlVMTCwgeyBsb2NhbGU6ICdmci1GUicgfSk7IC8vPT4gN1x1MjAxMzggbm92ZW1icmUgMjAyMlxuICAgKiBAZXhhbXBsZSBJbnRlcnZhbC5mcm9tSVNPKCcyMDIyLTExLTA3VDE3OjAwWi8yMDIyLTExLTA3VDE5OjAwWicpLnRvTG9jYWxlU3RyaW5nKERhdGVUaW1lLlRJTUVfU0lNUExFKTsgLy89PiA2OjAwIFx1MjAxMyA4OjAwIFBNXG4gICAqIEBleGFtcGxlIEludGVydmFsLmZyb21JU08oJzIwMjItMTEtMDdUMTc6MDBaLzIwMjItMTEtMDdUMTk6MDBaJykudG9Mb2NhbGVTdHJpbmcoeyB3ZWVrZGF5OiAnc2hvcnQnLCBtb250aDogJ3Nob3J0JywgZGF5OiAnMi1kaWdpdCcsIGhvdXI6ICcyLWRpZ2l0JywgbWludXRlOiAnMi1kaWdpdCcgfSk7IC8vPT4gTW9uLCBOb3YgMDcsIDY6MDAgXHUyMDEzIDg6MDAgcFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b0xvY2FsZVN0cmluZyhmb3JtYXRPcHRzID0gRm9ybWF0cy5EQVRFX1NIT1JULCBvcHRzID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkXG4gICAgICA/IEZvcm1hdHRlci5jcmVhdGUodGhpcy5zLmxvYy5jbG9uZShvcHRzKSwgZm9ybWF0T3B0cykuZm9ybWF0SW50ZXJ2YWwodGhpcylcbiAgICAgIDogSU5WQUxJRDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIElTTyA4NjAxLWNvbXBsaWFudCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBJbnRlcnZhbC5cbiAgICogQHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSNUaW1lX2ludGVydmFsc1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIFRoZSBzYW1lIG9wdGlvbnMgYXMge0BsaW5rIERhdGVUaW1lI3RvSVNPfVxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b0lTTyhvcHRzKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBJTlZBTElEO1xuICAgIHJldHVybiBgJHt0aGlzLnMudG9JU08ob3B0cyl9LyR7dGhpcy5lLnRvSVNPKG9wdHMpfWA7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBJU08gODYwMS1jb21wbGlhbnQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGRhdGUgb2YgdGhpcyBJbnRlcnZhbC5cbiAgICogVGhlIHRpbWUgY29tcG9uZW50cyBhcmUgaWdub3JlZC5cbiAgICogQHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSNUaW1lX2ludGVydmFsc1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b0lTT0RhdGUoKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBJTlZBTElEO1xuICAgIHJldHVybiBgJHt0aGlzLnMudG9JU09EYXRlKCl9LyR7dGhpcy5lLnRvSVNPRGF0ZSgpfWA7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBJU08gODYwMS1jb21wbGlhbnQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRpbWUgb2YgdGhpcyBJbnRlcnZhbC5cbiAgICogVGhlIGRhdGUgY29tcG9uZW50cyBhcmUgaWdub3JlZC5cbiAgICogQHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSNUaW1lX2ludGVydmFsc1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIFRoZSBzYW1lIG9wdGlvbnMgYXMge0BsaW5rIERhdGVUaW1lI3RvSVNPfVxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b0lTT1RpbWUob3B0cykge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkKSByZXR1cm4gSU5WQUxJRDtcbiAgICByZXR1cm4gYCR7dGhpcy5zLnRvSVNPVGltZShvcHRzKX0vJHt0aGlzLmUudG9JU09UaW1lKG9wdHMpfWA7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIEludGVydmFsIGZvcm1hdHRlZCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBmb3JtYXRcbiAgICogc3RyaW5nLiAqKllvdSBtYXkgbm90IHdhbnQgdGhpcy4qKiBTZWUge0BsaW5rIEludGVydmFsI3RvTG9jYWxlU3RyaW5nfSBmb3IgYSBtb3JlIGZsZXhpYmxlXG4gICAqIGZvcm1hdHRpbmcgdG9vbC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGVGb3JtYXQgLSBUaGUgZm9ybWF0IHN0cmluZy4gVGhpcyBzdHJpbmcgZm9ybWF0cyB0aGUgc3RhcnQgYW5kIGVuZCB0aW1lLlxuICAgKiBTZWUge0BsaW5rIERhdGVUaW1lI3RvRm9ybWF0fSBmb3IgZGV0YWlscy5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBPcHRpb25zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuc2VwYXJhdG9yID0gICcgXHUyMDEzICddIC0gQSBzZXBhcmF0b3IgdG8gcGxhY2UgYmV0d2VlbiB0aGUgc3RhcnQgYW5kIGVuZFxuICAgKiByZXByZXNlbnRhdGlvbnMuXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICovXG4gIHRvRm9ybWF0KGRhdGVGb3JtYXQsIHsgc2VwYXJhdG9yID0gXCIgXHUyMDEzIFwiIH0gPSB7fSkge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkKSByZXR1cm4gSU5WQUxJRDtcbiAgICByZXR1cm4gYCR7dGhpcy5zLnRvRm9ybWF0KGRhdGVGb3JtYXQpfSR7c2VwYXJhdG9yfSR7dGhpcy5lLnRvRm9ybWF0KGRhdGVGb3JtYXQpfWA7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgRHVyYXRpb24gcmVwcmVzZW50aW5nIHRoZSB0aW1lIHNwYW5uZWQgYnkgdGhpcyBpbnRlcnZhbC5cbiAgICogQHBhcmFtIHtzdHJpbmd8c3RyaW5nW119IFt1bml0PVsnbWlsbGlzZWNvbmRzJ11dIC0gdGhlIHVuaXQgb3IgdW5pdHMgKHN1Y2ggYXMgJ2hvdXJzJyBvciAnZGF5cycpIHRvIGluY2x1ZGUgaW4gdGhlIGR1cmF0aW9uLlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnMgdGhhdCBhZmZlY3QgdGhlIGNyZWF0aW9uIG9mIHRoZSBEdXJhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuY29udmVyc2lvbkFjY3VyYWN5PSdjYXN1YWwnXSAtIHRoZSBjb252ZXJzaW9uIHN5c3RlbSB0byB1c2VcbiAgICogQGV4YW1wbGUgSW50ZXJ2YWwuZnJvbURhdGVUaW1lcyhkdDEsIGR0MikudG9EdXJhdGlvbigpLnRvT2JqZWN0KCkgLy89PiB7IG1pbGxpc2Vjb25kczogODg0ODkyNTcgfVxuICAgKiBAZXhhbXBsZSBJbnRlcnZhbC5mcm9tRGF0ZVRpbWVzKGR0MSwgZHQyKS50b0R1cmF0aW9uKCdkYXlzJykudG9PYmplY3QoKSAvLz0+IHsgZGF5czogMS4wMjQxODEyMTUyNzc3Nzc4IH1cbiAgICogQGV4YW1wbGUgSW50ZXJ2YWwuZnJvbURhdGVUaW1lcyhkdDEsIGR0MikudG9EdXJhdGlvbihbJ2hvdXJzJywgJ21pbnV0ZXMnXSkudG9PYmplY3QoKSAvLz0+IHsgaG91cnM6IDI0LCBtaW51dGVzOiAzNC44MjA5NSB9XG4gICAqIEBleGFtcGxlIEludGVydmFsLmZyb21EYXRlVGltZXMoZHQxLCBkdDIpLnRvRHVyYXRpb24oWydob3VycycsICdtaW51dGVzJywgJ3NlY29uZHMnXSkudG9PYmplY3QoKSAvLz0+IHsgaG91cnM6IDI0LCBtaW51dGVzOiAzNCwgc2Vjb25kczogNDkuMjU3IH1cbiAgICogQGV4YW1wbGUgSW50ZXJ2YWwuZnJvbURhdGVUaW1lcyhkdDEsIGR0MikudG9EdXJhdGlvbignc2Vjb25kcycpLnRvT2JqZWN0KCkgLy89PiB7IHNlY29uZHM6IDg4NDg5LjI1NyB9XG4gICAqIEByZXR1cm4ge0R1cmF0aW9ufVxuICAgKi9cbiAgdG9EdXJhdGlvbih1bml0LCBvcHRzKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHtcbiAgICAgIHJldHVybiBEdXJhdGlvbi5pbnZhbGlkKHRoaXMuaW52YWxpZFJlYXNvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmUuZGlmZih0aGlzLnMsIHVuaXQsIG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1biBtYXBGbiBvbiB0aGUgaW50ZXJ2YWwgc3RhcnQgYW5kIGVuZCwgcmV0dXJuaW5nIGEgbmV3IEludGVydmFsIGZyb20gdGhlIHJlc3VsdGluZyBEYXRlVGltZXNcbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gbWFwRm5cbiAgICogQHJldHVybiB7SW50ZXJ2YWx9XG4gICAqIEBleGFtcGxlIEludGVydmFsLmZyb21EYXRlVGltZXMoZHQxLCBkdDIpLm1hcEVuZHBvaW50cyhlbmRwb2ludCA9PiBlbmRwb2ludC50b1VUQygpKVxuICAgKiBAZXhhbXBsZSBJbnRlcnZhbC5mcm9tRGF0ZVRpbWVzKGR0MSwgZHQyKS5tYXBFbmRwb2ludHMoZW5kcG9pbnQgPT4gZW5kcG9pbnQucGx1cyh7IGhvdXJzOiAyIH0pKVxuICAgKi9cbiAgbWFwRW5kcG9pbnRzKG1hcEZuKSB7XG4gICAgcmV0dXJuIEludGVydmFsLmZyb21EYXRlVGltZXMobWFwRm4odGhpcy5zKSwgbWFwRm4odGhpcy5lKSk7XG4gIH1cbn1cbiIsICJpbXBvcnQgRGF0ZVRpbWUgZnJvbSBcIi4vZGF0ZXRpbWUuanNcIjtcbmltcG9ydCBTZXR0aW5ncyBmcm9tIFwiLi9zZXR0aW5ncy5qc1wiO1xuaW1wb3J0IExvY2FsZSBmcm9tIFwiLi9pbXBsL2xvY2FsZS5qc1wiO1xuaW1wb3J0IElBTkFab25lIGZyb20gXCIuL3pvbmVzL0lBTkFab25lLmpzXCI7XG5pbXBvcnQgeyBub3JtYWxpemVab25lIH0gZnJvbSBcIi4vaW1wbC96b25lVXRpbC5qc1wiO1xuXG5pbXBvcnQgeyBoYXNMb2NhbGVXZWVrSW5mbywgaGFzUmVsYXRpdmUgfSBmcm9tIFwiLi9pbXBsL3V0aWwuanNcIjtcblxuLyoqXG4gKiBUaGUgSW5mbyBjbGFzcyBjb250YWlucyBzdGF0aWMgbWV0aG9kcyBmb3IgcmV0cmlldmluZyBnZW5lcmFsIHRpbWUgYW5kIGRhdGUgcmVsYXRlZCBkYXRhLiBGb3IgZXhhbXBsZSwgaXQgaGFzIG1ldGhvZHMgZm9yIGZpbmRpbmcgb3V0IGlmIGEgdGltZSB6b25lIGhhcyBhIERTVCwgZm9yIGxpc3RpbmcgdGhlIG1vbnRocyBpbiBhbnkgc3VwcG9ydGVkIGxvY2FsZSwgYW5kIGZvciBkaXNjb3ZlcmluZyB3aGljaCBvZiBMdXhvbiBmZWF0dXJlcyBhcmUgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50LlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJbmZvIHtcbiAgLyoqXG4gICAqIFJldHVybiB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgem9uZSBjb250YWlucyBhIERTVC5cbiAgICogQHBhcmFtIHtzdHJpbmd8Wm9uZX0gW3pvbmU9J2xvY2FsJ10gLSBab25lIHRvIGNoZWNrLiBEZWZhdWx0cyB0byB0aGUgZW52aXJvbm1lbnQncyBsb2NhbCB6b25lLlxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgc3RhdGljIGhhc0RTVCh6b25lID0gU2V0dGluZ3MuZGVmYXVsdFpvbmUpIHtcbiAgICBjb25zdCBwcm90byA9IERhdGVUaW1lLm5vdygpLnNldFpvbmUoem9uZSkuc2V0KHsgbW9udGg6IDEyIH0pO1xuXG4gICAgcmV0dXJuICF6b25lLmlzVW5pdmVyc2FsICYmIHByb3RvLm9mZnNldCAhPT0gcHJvdG8uc2V0KHsgbW9udGg6IDYgfSkub2Zmc2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgem9uZSBpcyBhIHZhbGlkIElBTkEgc3BlY2lmaWVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gem9uZSAtIFpvbmUgdG8gY2hlY2tcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIHN0YXRpYyBpc1ZhbGlkSUFOQVpvbmUoem9uZSkge1xuICAgIHJldHVybiBJQU5BWm9uZS5pc1ZhbGlkWm9uZSh6b25lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgaW5wdXQgaW50byBhIHtAbGluayBab25lfSBpbnN0YW5jZS5cbiAgICpcbiAgICogKiBJZiBgaW5wdXRgIGlzIGFscmVhZHkgYSBab25lIGluc3RhbmNlLCBpdCBpcyByZXR1cm5lZCB1bmNoYW5nZWQuXG4gICAqICogSWYgYGlucHV0YCBpcyBhIHN0cmluZyBjb250YWluaW5nIGEgdmFsaWQgdGltZSB6b25lIG5hbWUsIGEgWm9uZSBpbnN0YW5jZVxuICAgKiAgIHdpdGggdGhhdCBuYW1lIGlzIHJldHVybmVkLlxuICAgKiAqIElmIGBpbnB1dGAgaXMgYSBzdHJpbmcgdGhhdCBkb2Vzbid0IHJlZmVyIHRvIGEga25vd24gdGltZSB6b25lLCBhIFpvbmVcbiAgICogICBpbnN0YW5jZSB3aXRoIHtAbGluayBab25lI2lzVmFsaWR9ID09IGZhbHNlIGlzIHJldHVybmVkLlxuICAgKiAqIElmIGBpbnB1dCBpcyBhIG51bWJlciwgYSBab25lIGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBmaXhlZCBvZmZzZXRcbiAgICogICBpbiBtaW51dGVzIGlzIHJldHVybmVkLlxuICAgKiAqIElmIGBpbnB1dGAgaXMgYG51bGxgIG9yIGB1bmRlZmluZWRgLCB0aGUgZGVmYXVsdCB6b25lIGlzIHJldHVybmVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ3xab25lfG51bWJlcn0gW2lucHV0XSAtIHRoZSB2YWx1ZSB0byBiZSBjb252ZXJ0ZWRcbiAgICogQHJldHVybiB7Wm9uZX1cbiAgICovXG4gIHN0YXRpYyBub3JtYWxpemVab25lKGlucHV0KSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZVpvbmUoaW5wdXQsIFNldHRpbmdzLmRlZmF1bHRab25lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHdlZWtkYXkgb24gd2hpY2ggdGhlIHdlZWsgc3RhcnRzIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gbG9jYWxlLlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnNcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY2FsZV0gLSB0aGUgbG9jYWxlIGNvZGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY09iaj1udWxsXSAtIGFuIGV4aXN0aW5nIGxvY2FsZSBvYmplY3QgdG8gdXNlXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IHRoZSBzdGFydCBvZiB0aGUgd2VlaywgMSBmb3IgTW9uZGF5IHRocm91Z2ggNyBmb3IgU3VuZGF5XG4gICAqL1xuICBzdGF0aWMgZ2V0U3RhcnRPZldlZWsoeyBsb2NhbGUgPSBudWxsLCBsb2NPYmogPSBudWxsIH0gPSB7fSkge1xuICAgIHJldHVybiAobG9jT2JqIHx8IExvY2FsZS5jcmVhdGUobG9jYWxlKSkuZ2V0U3RhcnRPZldlZWsoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGRheXMgbmVjZXNzYXJ5IGluIGEgd2VlayBiZWZvcmUgaXQgaXMgY29uc2lkZXJlZCBwYXJ0IG9mIHRoZSBuZXh0IHllYXIgYWNjb3JkaW5nXG4gICAqIHRvIHRoZSBnaXZlbiBsb2NhbGUuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0aW9uc1xuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubG9jYWxlXSAtIHRoZSBsb2NhbGUgY29kZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubG9jT2JqPW51bGxdIC0gYW4gZXhpc3RpbmcgbG9jYWxlIG9iamVjdCB0byB1c2VcbiAgICogQHJldHVybnMge251bWJlcn1cbiAgICovXG4gIHN0YXRpYyBnZXRNaW5pbXVtRGF5c0luRmlyc3RXZWVrKHsgbG9jYWxlID0gbnVsbCwgbG9jT2JqID0gbnVsbCB9ID0ge30pIHtcbiAgICByZXR1cm4gKGxvY09iaiB8fCBMb2NhbGUuY3JlYXRlKGxvY2FsZSkpLmdldE1pbkRheXNJbkZpcnN0V2VlaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgd2Vla2RheXMsIHdoaWNoIGFyZSBjb25zaWRlcmVkIHRoZSB3ZWVrZW5kIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gbG9jYWxlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0aW9uc1xuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubG9jYWxlXSAtIHRoZSBsb2NhbGUgY29kZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubG9jT2JqPW51bGxdIC0gYW4gZXhpc3RpbmcgbG9jYWxlIG9iamVjdCB0byB1c2VcbiAgICogQHJldHVybnMge251bWJlcltdfSBhbiBhcnJheSBvZiB3ZWVrZGF5cywgMSBmb3IgTW9uZGF5IHRocm91Z2ggNyBmb3IgU3VuZGF5XG4gICAqL1xuICBzdGF0aWMgZ2V0V2Vla2VuZFdlZWtkYXlzKHsgbG9jYWxlID0gbnVsbCwgbG9jT2JqID0gbnVsbCB9ID0ge30pIHtcbiAgICAvLyBjb3B5IHRoZSBhcnJheSwgYmVjYXVzZSB3ZSBjYWNoZSBpdCBpbnRlcm5hbGx5XG4gICAgcmV0dXJuIChsb2NPYmogfHwgTG9jYWxlLmNyZWF0ZShsb2NhbGUpKS5nZXRXZWVrZW5kRGF5cygpLnNsaWNlKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGFuIGFycmF5IG9mIHN0YW5kYWxvbmUgbW9udGggbmFtZXMuXG4gICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRGF0ZVRpbWVGb3JtYXRcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtsZW5ndGg9J2xvbmcnXSAtIHRoZSBsZW5ndGggb2YgdGhlIG1vbnRoIHJlcHJlc2VudGF0aW9uLCBzdWNoIGFzIFwibnVtZXJpY1wiLCBcIjItZGlnaXRcIiwgXCJuYXJyb3dcIiwgXCJzaG9ydFwiLCBcImxvbmdcIlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnNcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY2FsZV0gLSB0aGUgbG9jYWxlIGNvZGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLm51bWJlcmluZ1N5c3RlbT1udWxsXSAtIHRoZSBudW1iZXJpbmcgc3lzdGVtXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5sb2NPYmo9bnVsbF0gLSBhbiBleGlzdGluZyBsb2NhbGUgb2JqZWN0IHRvIHVzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMub3V0cHV0Q2FsZW5kYXI9J2dyZWdvcnknXSAtIHRoZSBjYWxlbmRhclxuICAgKiBAZXhhbXBsZSBJbmZvLm1vbnRocygpWzBdIC8vPT4gJ0phbnVhcnknXG4gICAqIEBleGFtcGxlIEluZm8ubW9udGhzKCdzaG9ydCcpWzBdIC8vPT4gJ0phbidcbiAgICogQGV4YW1wbGUgSW5mby5tb250aHMoJ251bWVyaWMnKVswXSAvLz0+ICcxJ1xuICAgKiBAZXhhbXBsZSBJbmZvLm1vbnRocygnc2hvcnQnLCB7IGxvY2FsZTogJ2ZyLUNBJyB9IClbMF0gLy89PiAnamFudi4nXG4gICAqIEBleGFtcGxlIEluZm8ubW9udGhzKCdudW1lcmljJywgeyBsb2NhbGU6ICdhcicgfSlbMF0gLy89PiAnXHUwNjYxJ1xuICAgKiBAZXhhbXBsZSBJbmZvLm1vbnRocygnbG9uZycsIHsgb3V0cHV0Q2FsZW5kYXI6ICdpc2xhbWljJyB9KVswXSAvLz0+ICdSYWJpXHUwMkJCIEknXG4gICAqIEByZXR1cm4ge0FycmF5fVxuICAgKi9cbiAgc3RhdGljIG1vbnRocyhcbiAgICBsZW5ndGggPSBcImxvbmdcIixcbiAgICB7IGxvY2FsZSA9IG51bGwsIG51bWJlcmluZ1N5c3RlbSA9IG51bGwsIGxvY09iaiA9IG51bGwsIG91dHB1dENhbGVuZGFyID0gXCJncmVnb3J5XCIgfSA9IHt9XG4gICkge1xuICAgIHJldHVybiAobG9jT2JqIHx8IExvY2FsZS5jcmVhdGUobG9jYWxlLCBudW1iZXJpbmdTeXN0ZW0sIG91dHB1dENhbGVuZGFyKSkubW9udGhzKGxlbmd0aCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGFuIGFycmF5IG9mIGZvcm1hdCBtb250aCBuYW1lcy5cbiAgICogRm9ybWF0IG1vbnRocyBkaWZmZXIgZnJvbSBzdGFuZGFsb25lIG1vbnRocyBpbiB0aGF0IHRoZXkncmUgbWVhbnQgdG8gYXBwZWFyIG5leHQgdG8gdGhlIGRheSBvZiB0aGUgbW9udGguIEluIHNvbWUgbGFuZ3VhZ2VzLCB0aGF0XG4gICAqIGNoYW5nZXMgdGhlIHN0cmluZy5cbiAgICogU2VlIHtAbGluayBJbmZvI21vbnRoc31cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtsZW5ndGg9J2xvbmcnXSAtIHRoZSBsZW5ndGggb2YgdGhlIG1vbnRoIHJlcHJlc2VudGF0aW9uLCBzdWNoIGFzIFwibnVtZXJpY1wiLCBcIjItZGlnaXRcIiwgXCJuYXJyb3dcIiwgXCJzaG9ydFwiLCBcImxvbmdcIlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnNcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY2FsZV0gLSB0aGUgbG9jYWxlIGNvZGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLm51bWJlcmluZ1N5c3RlbT1udWxsXSAtIHRoZSBudW1iZXJpbmcgc3lzdGVtXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5sb2NPYmo9bnVsbF0gLSBhbiBleGlzdGluZyBsb2NhbGUgb2JqZWN0IHRvIHVzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMub3V0cHV0Q2FsZW5kYXI9J2dyZWdvcnknXSAtIHRoZSBjYWxlbmRhclxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICovXG4gIHN0YXRpYyBtb250aHNGb3JtYXQoXG4gICAgbGVuZ3RoID0gXCJsb25nXCIsXG4gICAgeyBsb2NhbGUgPSBudWxsLCBudW1iZXJpbmdTeXN0ZW0gPSBudWxsLCBsb2NPYmogPSBudWxsLCBvdXRwdXRDYWxlbmRhciA9IFwiZ3JlZ29yeVwiIH0gPSB7fVxuICApIHtcbiAgICByZXR1cm4gKGxvY09iaiB8fCBMb2NhbGUuY3JlYXRlKGxvY2FsZSwgbnVtYmVyaW5nU3lzdGVtLCBvdXRwdXRDYWxlbmRhcikpLm1vbnRocyhsZW5ndGgsIHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbiBhcnJheSBvZiBzdGFuZGFsb25lIHdlZWsgbmFtZXMuXG4gICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRGF0ZVRpbWVGb3JtYXRcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtsZW5ndGg9J2xvbmcnXSAtIHRoZSBsZW5ndGggb2YgdGhlIHdlZWtkYXkgcmVwcmVzZW50YXRpb24sIHN1Y2ggYXMgXCJuYXJyb3dcIiwgXCJzaG9ydFwiLCBcImxvbmdcIi5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5sb2NhbGVdIC0gdGhlIGxvY2FsZSBjb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5udW1iZXJpbmdTeXN0ZW09bnVsbF0gLSB0aGUgbnVtYmVyaW5nIHN5c3RlbVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubG9jT2JqPW51bGxdIC0gYW4gZXhpc3RpbmcgbG9jYWxlIG9iamVjdCB0byB1c2VcbiAgICogQGV4YW1wbGUgSW5mby53ZWVrZGF5cygpWzBdIC8vPT4gJ01vbmRheSdcbiAgICogQGV4YW1wbGUgSW5mby53ZWVrZGF5cygnc2hvcnQnKVswXSAvLz0+ICdNb24nXG4gICAqIEBleGFtcGxlIEluZm8ud2Vla2RheXMoJ3Nob3J0JywgeyBsb2NhbGU6ICdmci1DQScgfSlbMF0gLy89PiAnbHVuLidcbiAgICogQGV4YW1wbGUgSW5mby53ZWVrZGF5cygnc2hvcnQnLCB7IGxvY2FsZTogJ2FyJyB9KVswXSAvLz0+ICdcdTA2MjdcdTA2NDRcdTA2MjdcdTA2MkJcdTA2NDZcdTA2NEFcdTA2NDYnXG4gICAqIEByZXR1cm4ge0FycmF5fVxuICAgKi9cbiAgc3RhdGljIHdlZWtkYXlzKGxlbmd0aCA9IFwibG9uZ1wiLCB7IGxvY2FsZSA9IG51bGwsIG51bWJlcmluZ1N5c3RlbSA9IG51bGwsIGxvY09iaiA9IG51bGwgfSA9IHt9KSB7XG4gICAgcmV0dXJuIChsb2NPYmogfHwgTG9jYWxlLmNyZWF0ZShsb2NhbGUsIG51bWJlcmluZ1N5c3RlbSwgbnVsbCkpLndlZWtkYXlzKGxlbmd0aCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGFuIGFycmF5IG9mIGZvcm1hdCB3ZWVrIG5hbWVzLlxuICAgKiBGb3JtYXQgd2Vla2RheXMgZGlmZmVyIGZyb20gc3RhbmRhbG9uZSB3ZWVrZGF5cyBpbiB0aGF0IHRoZXkncmUgbWVhbnQgdG8gYXBwZWFyIG5leHQgdG8gbW9yZSBkYXRlIGluZm9ybWF0aW9uLiBJbiBzb21lIGxhbmd1YWdlcywgdGhhdFxuICAgKiBjaGFuZ2VzIHRoZSBzdHJpbmcuXG4gICAqIFNlZSB7QGxpbmsgSW5mbyN3ZWVrZGF5c31cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtsZW5ndGg9J2xvbmcnXSAtIHRoZSBsZW5ndGggb2YgdGhlIG1vbnRoIHJlcHJlc2VudGF0aW9uLCBzdWNoIGFzIFwibmFycm93XCIsIFwic2hvcnRcIiwgXCJsb25nXCIuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0aW9uc1xuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubG9jYWxlPW51bGxdIC0gdGhlIGxvY2FsZSBjb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5udW1iZXJpbmdTeXN0ZW09bnVsbF0gLSB0aGUgbnVtYmVyaW5nIHN5c3RlbVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubG9jT2JqPW51bGxdIC0gYW4gZXhpc3RpbmcgbG9jYWxlIG9iamVjdCB0byB1c2VcbiAgICogQHJldHVybiB7QXJyYXl9XG4gICAqL1xuICBzdGF0aWMgd2Vla2RheXNGb3JtYXQoXG4gICAgbGVuZ3RoID0gXCJsb25nXCIsXG4gICAgeyBsb2NhbGUgPSBudWxsLCBudW1iZXJpbmdTeXN0ZW0gPSBudWxsLCBsb2NPYmogPSBudWxsIH0gPSB7fVxuICApIHtcbiAgICByZXR1cm4gKGxvY09iaiB8fCBMb2NhbGUuY3JlYXRlKGxvY2FsZSwgbnVtYmVyaW5nU3lzdGVtLCBudWxsKSkud2Vla2RheXMobGVuZ3RoLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYW4gYXJyYXkgb2YgbWVyaWRpZW1zLlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnNcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY2FsZV0gLSB0aGUgbG9jYWxlIGNvZGVcbiAgICogQGV4YW1wbGUgSW5mby5tZXJpZGllbXMoKSAvLz0+IFsgJ0FNJywgJ1BNJyBdXG4gICAqIEBleGFtcGxlIEluZm8ubWVyaWRpZW1zKHsgbG9jYWxlOiAnbXknIH0pIC8vPT4gWyAnXHUxMDE0XHUxMDM2XHUxMDE0XHUxMDAwXHUxMDNBJywgJ1x1MTAwQVx1MTAxNFx1MTAzMScgXVxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICovXG4gIHN0YXRpYyBtZXJpZGllbXMoeyBsb2NhbGUgPSBudWxsIH0gPSB7fSkge1xuICAgIHJldHVybiBMb2NhbGUuY3JlYXRlKGxvY2FsZSkubWVyaWRpZW1zKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGFuIGFycmF5IG9mIGVyYXMsIHN1Y2ggYXMgWydCQycsICdBRCddLiBUaGUgbG9jYWxlIGNhbiBiZSBzcGVjaWZpZWQsIGJ1dCB0aGUgY2FsZW5kYXIgc3lzdGVtIGlzIGFsd2F5cyBHcmVnb3JpYW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbbGVuZ3RoPSdzaG9ydCddIC0gdGhlIGxlbmd0aCBvZiB0aGUgZXJhIHJlcHJlc2VudGF0aW9uLCBzdWNoIGFzIFwic2hvcnRcIiBvciBcImxvbmdcIi5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5sb2NhbGVdIC0gdGhlIGxvY2FsZSBjb2RlXG4gICAqIEBleGFtcGxlIEluZm8uZXJhcygpIC8vPT4gWyAnQkMnLCAnQUQnIF1cbiAgICogQGV4YW1wbGUgSW5mby5lcmFzKCdsb25nJykgLy89PiBbICdCZWZvcmUgQ2hyaXN0JywgJ0Fubm8gRG9taW5pJyBdXG4gICAqIEBleGFtcGxlIEluZm8uZXJhcygnbG9uZycsIHsgbG9jYWxlOiAnZnInIH0pIC8vPT4gWyAnYXZhbnQgSlx1MDBFOXN1cy1DaHJpc3QnLCAnYXByXHUwMEU4cyBKXHUwMEU5c3VzLUNocmlzdCcgXVxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICovXG4gIHN0YXRpYyBlcmFzKGxlbmd0aCA9IFwic2hvcnRcIiwgeyBsb2NhbGUgPSBudWxsIH0gPSB7fSkge1xuICAgIHJldHVybiBMb2NhbGUuY3JlYXRlKGxvY2FsZSwgbnVsbCwgXCJncmVnb3J5XCIpLmVyYXMobGVuZ3RoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHNldCBvZiBhdmFpbGFibGUgZmVhdHVyZXMgaW4gdGhpcyBlbnZpcm9ubWVudC5cbiAgICogU29tZSBmZWF0dXJlcyBvZiBMdXhvbiBhcmUgbm90IGF2YWlsYWJsZSBpbiBhbGwgZW52aXJvbm1lbnRzLiBGb3IgZXhhbXBsZSwgb24gb2xkZXIgYnJvd3NlcnMsIHJlbGF0aXZlIHRpbWUgZm9ybWF0dGluZyBzdXBwb3J0IGlzIG5vdCBhdmFpbGFibGUuIFVzZSB0aGlzIGZ1bmN0aW9uIHRvIGZpZ3VyZSBvdXQgaWYgdGhhdCdzIHRoZSBjYXNlLlxuICAgKiBLZXlzOlxuICAgKiAqIGByZWxhdGl2ZWA6IHdoZXRoZXIgdGhpcyBlbnZpcm9ubWVudCBzdXBwb3J0cyByZWxhdGl2ZSB0aW1lIGZvcm1hdHRpbmdcbiAgICogKiBgbG9jYWxlV2Vla2A6IHdoZXRoZXIgdGhpcyBlbnZpcm9ubWVudCBzdXBwb3J0cyBkaWZmZXJlbnQgd2Vla2RheXMgZm9yIHRoZSBzdGFydCBvZiB0aGUgd2VlayBiYXNlZCBvbiB0aGUgbG9jYWxlXG4gICAqIEBleGFtcGxlIEluZm8uZmVhdHVyZXMoKSAvLz0+IHsgcmVsYXRpdmU6IGZhbHNlLCBsb2NhbGVXZWVrOiB0cnVlIH1cbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGZlYXR1cmVzKCkge1xuICAgIHJldHVybiB7IHJlbGF0aXZlOiBoYXNSZWxhdGl2ZSgpLCBsb2NhbGVXZWVrOiBoYXNMb2NhbGVXZWVrSW5mbygpIH07XG4gIH1cbn1cbiIsICJpbXBvcnQgRHVyYXRpb24gZnJvbSBcIi4uL2R1cmF0aW9uLmpzXCI7XG5cbmZ1bmN0aW9uIGRheURpZmYoZWFybGllciwgbGF0ZXIpIHtcbiAgY29uc3QgdXRjRGF5U3RhcnQgPSAoZHQpID0+IGR0LnRvVVRDKDAsIHsga2VlcExvY2FsVGltZTogdHJ1ZSB9KS5zdGFydE9mKFwiZGF5XCIpLnZhbHVlT2YoKSxcbiAgICBtcyA9IHV0Y0RheVN0YXJ0KGxhdGVyKSAtIHV0Y0RheVN0YXJ0KGVhcmxpZXIpO1xuICByZXR1cm4gTWF0aC5mbG9vcihEdXJhdGlvbi5mcm9tTWlsbGlzKG1zKS5hcyhcImRheXNcIikpO1xufVxuXG5mdW5jdGlvbiBoaWdoT3JkZXJEaWZmcyhjdXJzb3IsIGxhdGVyLCB1bml0cykge1xuICBjb25zdCBkaWZmZXJzID0gW1xuICAgIFtcInllYXJzXCIsIChhLCBiKSA9PiBiLnllYXIgLSBhLnllYXJdLFxuICAgIFtcInF1YXJ0ZXJzXCIsIChhLCBiKSA9PiBiLnF1YXJ0ZXIgLSBhLnF1YXJ0ZXIgKyAoYi55ZWFyIC0gYS55ZWFyKSAqIDRdLFxuICAgIFtcIm1vbnRoc1wiLCAoYSwgYikgPT4gYi5tb250aCAtIGEubW9udGggKyAoYi55ZWFyIC0gYS55ZWFyKSAqIDEyXSxcbiAgICBbXG4gICAgICBcIndlZWtzXCIsXG4gICAgICAoYSwgYikgPT4ge1xuICAgICAgICBjb25zdCBkYXlzID0gZGF5RGlmZihhLCBiKTtcbiAgICAgICAgcmV0dXJuIChkYXlzIC0gKGRheXMgJSA3KSkgLyA3O1xuICAgICAgfSxcbiAgICBdLFxuICAgIFtcImRheXNcIiwgZGF5RGlmZl0sXG4gIF07XG5cbiAgY29uc3QgcmVzdWx0cyA9IHt9O1xuICBjb25zdCBlYXJsaWVyID0gY3Vyc29yO1xuICBsZXQgbG93ZXN0T3JkZXIsIGhpZ2hXYXRlcjtcblxuICAvKiBUaGlzIGxvb3AgdHJpZXMgdG8gZGlmZiB1c2luZyBsYXJnZXIgdW5pdHMgZmlyc3QuXG4gICAgIElmIHdlIG92ZXJzaG9vdCwgd2UgYmFja3RyYWNrIGFuZCB0cnkgdGhlIG5leHQgc21hbGxlciB1bml0LlxuICAgICBcImN1cnNvclwiIHN0YXJ0cyBvdXQgYXQgdGhlIGVhcmxpZXIgdGltZXN0YW1wIGFuZCBtb3ZlcyBjbG9zZXIgYW5kIGNsb3NlciB0byBcImxhdGVyXCJcbiAgICAgYXMgd2UgdXNlIHNtYWxsZXIgYW5kIHNtYWxsZXIgdW5pdHMuXG4gICAgIGhpZ2hXYXRlciBrZWVwcyB0cmFjayBvZiB3aGVyZSB3ZSB3b3VsZCBiZSBpZiB3ZSBhZGRlZCBvbmUgbW9yZSBvZiB0aGUgc21hbGxlc3QgdW5pdCxcbiAgICAgdGhpcyBpcyB1c2VkIGxhdGVyIHRvIHBvdGVudGlhbGx5IGNvbnZlcnQgYW55IGRpZmZlcmVuY2Ugc21hbGxlciB0aGFuIHRoZSBzbWFsbGVzdCBoaWdoZXIgb3JkZXIgdW5pdFxuICAgICBpbnRvIGEgZnJhY3Rpb24gb2YgdGhhdCBzbWFsbGVzdCBoaWdoZXIgb3JkZXIgdW5pdFxuICAqL1xuICBmb3IgKGNvbnN0IFt1bml0LCBkaWZmZXJdIG9mIGRpZmZlcnMpIHtcbiAgICBpZiAodW5pdHMuaW5kZXhPZih1bml0KSA+PSAwKSB7XG4gICAgICBsb3dlc3RPcmRlciA9IHVuaXQ7XG5cbiAgICAgIHJlc3VsdHNbdW5pdF0gPSBkaWZmZXIoY3Vyc29yLCBsYXRlcik7XG4gICAgICBoaWdoV2F0ZXIgPSBlYXJsaWVyLnBsdXMocmVzdWx0cyk7XG5cbiAgICAgIGlmIChoaWdoV2F0ZXIgPiBsYXRlcikge1xuICAgICAgICAvLyB3ZSBvdmVyc2hvdCB0aGUgZW5kIHBvaW50LCBiYWNrdHJhY2sgY3Vyc29yIGJ5IDFcbiAgICAgICAgcmVzdWx0c1t1bml0XS0tO1xuICAgICAgICBjdXJzb3IgPSBlYXJsaWVyLnBsdXMocmVzdWx0cyk7XG5cbiAgICAgICAgLy8gaWYgd2UgYXJlIHN0aWxsIG92ZXJzaG9vdGluZyBub3csIHdlIG5lZWQgdG8gYmFja3RyYWNrIGFnYWluXG4gICAgICAgIC8vIHRoaXMgaGFwcGVucyBpbiBjZXJ0YWluIHNpdHVhdGlvbnMgd2hlbiBkaWZmaW5nIHRpbWVzIGluIGRpZmZlcmVudCB6b25lcyxcbiAgICAgICAgLy8gYmVjYXVzZSB0aGlzIGNhbGN1bGF0aW9uIGlnbm9yZXMgdGltZSB6b25lc1xuICAgICAgICBpZiAoY3Vyc29yID4gbGF0ZXIpIHtcbiAgICAgICAgICAvLyBrZWVwIHRoZSBcIm92ZXJzaG90IGJ5IDFcIiBhcm91bmQgYXMgaGlnaFdhdGVyXG4gICAgICAgICAgaGlnaFdhdGVyID0gY3Vyc29yO1xuICAgICAgICAgIC8vIGJhY2t0cmFjayBjdXJzb3IgYnkgMVxuICAgICAgICAgIHJlc3VsdHNbdW5pdF0tLTtcbiAgICAgICAgICBjdXJzb3IgPSBlYXJsaWVyLnBsdXMocmVzdWx0cyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnNvciA9IGhpZ2hXYXRlcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gW2N1cnNvciwgcmVzdWx0cywgaGlnaFdhdGVyLCBsb3dlc3RPcmRlcl07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChlYXJsaWVyLCBsYXRlciwgdW5pdHMsIG9wdHMpIHtcbiAgbGV0IFtjdXJzb3IsIHJlc3VsdHMsIGhpZ2hXYXRlciwgbG93ZXN0T3JkZXJdID0gaGlnaE9yZGVyRGlmZnMoZWFybGllciwgbGF0ZXIsIHVuaXRzKTtcblxuICBjb25zdCByZW1haW5pbmdNaWxsaXMgPSBsYXRlciAtIGN1cnNvcjtcblxuICBjb25zdCBsb3dlck9yZGVyVW5pdHMgPSB1bml0cy5maWx0ZXIoXG4gICAgKHUpID0+IFtcImhvdXJzXCIsIFwibWludXRlc1wiLCBcInNlY29uZHNcIiwgXCJtaWxsaXNlY29uZHNcIl0uaW5kZXhPZih1KSA+PSAwXG4gICk7XG5cbiAgaWYgKGxvd2VyT3JkZXJVbml0cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaGlnaFdhdGVyIDwgbGF0ZXIpIHtcbiAgICAgIGhpZ2hXYXRlciA9IGN1cnNvci5wbHVzKHsgW2xvd2VzdE9yZGVyXTogMSB9KTtcbiAgICB9XG5cbiAgICBpZiAoaGlnaFdhdGVyICE9PSBjdXJzb3IpIHtcbiAgICAgIHJlc3VsdHNbbG93ZXN0T3JkZXJdID0gKHJlc3VsdHNbbG93ZXN0T3JkZXJdIHx8IDApICsgcmVtYWluaW5nTWlsbGlzIC8gKGhpZ2hXYXRlciAtIGN1cnNvcik7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZHVyYXRpb24gPSBEdXJhdGlvbi5mcm9tT2JqZWN0KHJlc3VsdHMsIG9wdHMpO1xuXG4gIGlmIChsb3dlck9yZGVyVW5pdHMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBEdXJhdGlvbi5mcm9tTWlsbGlzKHJlbWFpbmluZ01pbGxpcywgb3B0cylcbiAgICAgIC5zaGlmdFRvKC4uLmxvd2VyT3JkZXJVbml0cylcbiAgICAgIC5wbHVzKGR1cmF0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZHVyYXRpb247XG4gIH1cbn1cbiIsICJjb25zdCBudW1iZXJpbmdTeXN0ZW1zID0ge1xuICBhcmFiOiBcIltcXHUwNjYwLVxcdTA2NjldXCIsXG4gIGFyYWJleHQ6IFwiW1xcdTA2RjAtXFx1MDZGOV1cIixcbiAgYmFsaTogXCJbXFx1MUI1MC1cXHUxQjU5XVwiLFxuICBiZW5nOiBcIltcXHUwOUU2LVxcdTA5RUZdXCIsXG4gIGRldmE6IFwiW1xcdTA5NjYtXFx1MDk2Rl1cIixcbiAgZnVsbHdpZGU6IFwiW1xcdUZGMTAtXFx1RkYxOV1cIixcbiAgZ3VqcjogXCJbXFx1MEFFNi1cXHUwQUVGXVwiLFxuICBoYW5pZGVjOiBcIltcdTMwMDd8XHU0RTAwfFx1NEU4Q3xcdTRFMDl8XHU1NkRCfFx1NEU5NHxcdTUxNkR8XHU0RTAzfFx1NTE2QnxcdTRFNURdXCIsXG4gIGtobXI6IFwiW1xcdTE3RTAtXFx1MTdFOV1cIixcbiAga25kYTogXCJbXFx1MENFNi1cXHUwQ0VGXVwiLFxuICBsYW9vOiBcIltcXHUwRUQwLVxcdTBFRDldXCIsXG4gIGxpbWI6IFwiW1xcdTE5NDYtXFx1MTk0Rl1cIixcbiAgbWx5bTogXCJbXFx1MEQ2Ni1cXHUwRDZGXVwiLFxuICBtb25nOiBcIltcXHUxODEwLVxcdTE4MTldXCIsXG4gIG15bXI6IFwiW1xcdTEwNDAtXFx1MTA0OV1cIixcbiAgb3J5YTogXCJbXFx1MEI2Ni1cXHUwQjZGXVwiLFxuICB0YW1sZGVjOiBcIltcXHUwQkU2LVxcdTBCRUZdXCIsXG4gIHRlbHU6IFwiW1xcdTBDNjYtXFx1MEM2Rl1cIixcbiAgdGhhaTogXCJbXFx1MEU1MC1cXHUwRTU5XVwiLFxuICB0aWJ0OiBcIltcXHUwRjIwLVxcdTBGMjldXCIsXG4gIGxhdG46IFwiXFxcXGRcIixcbn07XG5cbmNvbnN0IG51bWJlcmluZ1N5c3RlbXNVVEYxNiA9IHtcbiAgYXJhYjogWzE2MzIsIDE2NDFdLFxuICBhcmFiZXh0OiBbMTc3NiwgMTc4NV0sXG4gIGJhbGk6IFs2OTkyLCA3MDAxXSxcbiAgYmVuZzogWzI1MzQsIDI1NDNdLFxuICBkZXZhOiBbMjQwNiwgMjQxNV0sXG4gIGZ1bGx3aWRlOiBbNjUyOTYsIDY1MzAzXSxcbiAgZ3VqcjogWzI3OTAsIDI3OTldLFxuICBraG1yOiBbNjExMiwgNjEyMV0sXG4gIGtuZGE6IFszMzAyLCAzMzExXSxcbiAgbGFvbzogWzM3OTIsIDM4MDFdLFxuICBsaW1iOiBbNjQ3MCwgNjQ3OV0sXG4gIG1seW06IFszNDMwLCAzNDM5XSxcbiAgbW9uZzogWzYxNjAsIDYxNjldLFxuICBteW1yOiBbNDE2MCwgNDE2OV0sXG4gIG9yeWE6IFsyOTE4LCAyOTI3XSxcbiAgdGFtbGRlYzogWzMwNDYsIDMwNTVdLFxuICB0ZWx1OiBbMzE3NCwgMzE4M10sXG4gIHRoYWk6IFszNjY0LCAzNjczXSxcbiAgdGlidDogWzM4NzIsIDM4ODFdLFxufTtcblxuY29uc3QgaGFuaWRlY0NoYXJzID0gbnVtYmVyaW5nU3lzdGVtcy5oYW5pZGVjLnJlcGxhY2UoL1tcXFt8XFxdXS9nLCBcIlwiKS5zcGxpdChcIlwiKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRGlnaXRzKHN0cikge1xuICBsZXQgdmFsdWUgPSBwYXJzZUludChzdHIsIDEwKTtcbiAgaWYgKGlzTmFOKHZhbHVlKSkge1xuICAgIHZhbHVlID0gXCJcIjtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgY29kZSA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuXG4gICAgICBpZiAoc3RyW2ldLnNlYXJjaChudW1iZXJpbmdTeXN0ZW1zLmhhbmlkZWMpICE9PSAtMSkge1xuICAgICAgICB2YWx1ZSArPSBoYW5pZGVjQ2hhcnMuaW5kZXhPZihzdHJbaV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbnVtYmVyaW5nU3lzdGVtc1VURjE2KSB7XG4gICAgICAgICAgY29uc3QgW21pbiwgbWF4XSA9IG51bWJlcmluZ1N5c3RlbXNVVEYxNltrZXldO1xuICAgICAgICAgIGlmIChjb2RlID49IG1pbiAmJiBjb2RlIDw9IG1heCkge1xuICAgICAgICAgICAgdmFsdWUgKz0gY29kZSAtIG1pbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWdpdFJlZ2V4KHsgbnVtYmVyaW5nU3lzdGVtIH0sIGFwcGVuZCA9IFwiXCIpIHtcbiAgcmV0dXJuIG5ldyBSZWdFeHAoYCR7bnVtYmVyaW5nU3lzdGVtc1tudW1iZXJpbmdTeXN0ZW0gfHwgXCJsYXRuXCJdfSR7YXBwZW5kfWApO1xufVxuIiwgImltcG9ydCB7IHBhcnNlTWlsbGlzLCBpc1VuZGVmaW5lZCwgdW50cnVuY2F0ZVllYXIsIHNpZ25lZE9mZnNldCwgaGFzT3duUHJvcGVydHkgfSBmcm9tIFwiLi91dGlsLmpzXCI7XG5pbXBvcnQgRm9ybWF0dGVyIGZyb20gXCIuL2Zvcm1hdHRlci5qc1wiO1xuaW1wb3J0IEZpeGVkT2Zmc2V0Wm9uZSBmcm9tIFwiLi4vem9uZXMvZml4ZWRPZmZzZXRab25lLmpzXCI7XG5pbXBvcnQgSUFOQVpvbmUgZnJvbSBcIi4uL3pvbmVzL0lBTkFab25lLmpzXCI7XG5pbXBvcnQgRGF0ZVRpbWUgZnJvbSBcIi4uL2RhdGV0aW1lLmpzXCI7XG5pbXBvcnQgeyBkaWdpdFJlZ2V4LCBwYXJzZURpZ2l0cyB9IGZyb20gXCIuL2RpZ2l0cy5qc1wiO1xuaW1wb3J0IHsgQ29uZmxpY3RpbmdTcGVjaWZpY2F0aW9uRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3JzLmpzXCI7XG5cbmNvbnN0IE1JU1NJTkdfRlRQID0gXCJtaXNzaW5nIEludGwuRGF0ZVRpbWVGb3JtYXQuZm9ybWF0VG9QYXJ0cyBzdXBwb3J0XCI7XG5cbmZ1bmN0aW9uIGludFVuaXQocmVnZXgsIHBvc3QgPSAoaSkgPT4gaSkge1xuICByZXR1cm4geyByZWdleCwgZGVzZXI6IChbc10pID0+IHBvc3QocGFyc2VEaWdpdHMocykpIH07XG59XG5cbmNvbnN0IE5CU1AgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDE2MCk7XG5jb25zdCBzcGFjZU9yTkJTUCA9IGBbICR7TkJTUH1dYDtcbmNvbnN0IHNwYWNlT3JOQlNQUmVnRXhwID0gbmV3IFJlZ0V4cChzcGFjZU9yTkJTUCwgXCJnXCIpO1xuXG5mdW5jdGlvbiBmaXhMaXN0UmVnZXgocykge1xuICAvLyBtYWtlIGRvdHMgb3B0aW9uYWwgYW5kIGFsc28gbWFrZSB0aGVtIGxpdGVyYWxcbiAgLy8gbWFrZSBzcGFjZSBhbmQgbm9uIGJyZWFrYWJsZSBzcGFjZSBjaGFyYWN0ZXJzIGludGVyY2hhbmdlYWJsZVxuICByZXR1cm4gcy5yZXBsYWNlKC9cXC4vZywgXCJcXFxcLj9cIikucmVwbGFjZShzcGFjZU9yTkJTUFJlZ0V4cCwgc3BhY2VPck5CU1ApO1xufVxuXG5mdW5jdGlvbiBzdHJpcEluc2Vuc2l0aXZpdGllcyhzKSB7XG4gIHJldHVybiBzXG4gICAgLnJlcGxhY2UoL1xcLi9nLCBcIlwiKSAvLyBpZ25vcmUgZG90cyB0aGF0IHdlcmUgbWFkZSBvcHRpb25hbFxuICAgIC5yZXBsYWNlKHNwYWNlT3JOQlNQUmVnRXhwLCBcIiBcIikgLy8gaW50ZXJjaGFuZ2Ugc3BhY2UgYW5kIG5ic3BcbiAgICAudG9Mb3dlckNhc2UoKTtcbn1cblxuZnVuY3Rpb24gb25lT2Yoc3RyaW5ncywgc3RhcnRJbmRleCkge1xuICBpZiAoc3RyaW5ncyA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB7XG4gICAgICByZWdleDogUmVnRXhwKHN0cmluZ3MubWFwKGZpeExpc3RSZWdleCkuam9pbihcInxcIikpLFxuICAgICAgZGVzZXI6IChbc10pID0+XG4gICAgICAgIHN0cmluZ3MuZmluZEluZGV4KChpKSA9PiBzdHJpcEluc2Vuc2l0aXZpdGllcyhzKSA9PT0gc3RyaXBJbnNlbnNpdGl2aXRpZXMoaSkpICsgc3RhcnRJbmRleCxcbiAgICB9O1xuICB9XG59XG5cbmZ1bmN0aW9uIG9mZnNldChyZWdleCwgZ3JvdXBzKSB7XG4gIHJldHVybiB7IHJlZ2V4LCBkZXNlcjogKFssIGgsIG1dKSA9PiBzaWduZWRPZmZzZXQoaCwgbSksIGdyb3VwcyB9O1xufVxuXG5mdW5jdGlvbiBzaW1wbGUocmVnZXgpIHtcbiAgcmV0dXJuIHsgcmVnZXgsIGRlc2VyOiAoW3NdKSA9PiBzIH07XG59XG5cbmZ1bmN0aW9uIGVzY2FwZVRva2VuKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZS5yZXBsYWNlKC9bXFwtXFxbXFxde30oKSorPy4sXFxcXFxcXiR8I1xcc10vZywgXCJcXFxcJCZcIik7XG59XG5cbi8qKlxuICogQHBhcmFtIHRva2VuXG4gKiBAcGFyYW0ge0xvY2FsZX0gbG9jXG4gKi9cbmZ1bmN0aW9uIHVuaXRGb3JUb2tlbih0b2tlbiwgbG9jKSB7XG4gIGNvbnN0IG9uZSA9IGRpZ2l0UmVnZXgobG9jKSxcbiAgICB0d28gPSBkaWdpdFJlZ2V4KGxvYywgXCJ7Mn1cIiksXG4gICAgdGhyZWUgPSBkaWdpdFJlZ2V4KGxvYywgXCJ7M31cIiksXG4gICAgZm91ciA9IGRpZ2l0UmVnZXgobG9jLCBcIns0fVwiKSxcbiAgICBzaXggPSBkaWdpdFJlZ2V4KGxvYywgXCJ7Nn1cIiksXG4gICAgb25lT3JUd28gPSBkaWdpdFJlZ2V4KGxvYywgXCJ7MSwyfVwiKSxcbiAgICBvbmVUb1RocmVlID0gZGlnaXRSZWdleChsb2MsIFwiezEsM31cIiksXG4gICAgb25lVG9TaXggPSBkaWdpdFJlZ2V4KGxvYywgXCJ7MSw2fVwiKSxcbiAgICBvbmVUb05pbmUgPSBkaWdpdFJlZ2V4KGxvYywgXCJ7MSw5fVwiKSxcbiAgICB0d29Ub0ZvdXIgPSBkaWdpdFJlZ2V4KGxvYywgXCJ7Miw0fVwiKSxcbiAgICBmb3VyVG9TaXggPSBkaWdpdFJlZ2V4KGxvYywgXCJ7NCw2fVwiKSxcbiAgICBsaXRlcmFsID0gKHQpID0+ICh7IHJlZ2V4OiBSZWdFeHAoZXNjYXBlVG9rZW4odC52YWwpKSwgZGVzZXI6IChbc10pID0+IHMsIGxpdGVyYWw6IHRydWUgfSksXG4gICAgdW5pdGF0ZSA9ICh0KSA9PiB7XG4gICAgICBpZiAodG9rZW4ubGl0ZXJhbCkge1xuICAgICAgICByZXR1cm4gbGl0ZXJhbCh0KTtcbiAgICAgIH1cbiAgICAgIHN3aXRjaCAodC52YWwpIHtcbiAgICAgICAgLy8gZXJhXG4gICAgICAgIGNhc2UgXCJHXCI6XG4gICAgICAgICAgcmV0dXJuIG9uZU9mKGxvYy5lcmFzKFwic2hvcnRcIiksIDApO1xuICAgICAgICBjYXNlIFwiR0dcIjpcbiAgICAgICAgICByZXR1cm4gb25lT2YobG9jLmVyYXMoXCJsb25nXCIpLCAwKTtcbiAgICAgICAgLy8geWVhcnNcbiAgICAgICAgY2FzZSBcInlcIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdChvbmVUb1NpeCk7XG4gICAgICAgIGNhc2UgXCJ5eVwiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KHR3b1RvRm91ciwgdW50cnVuY2F0ZVllYXIpO1xuICAgICAgICBjYXNlIFwieXl5eVwiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KGZvdXIpO1xuICAgICAgICBjYXNlIFwieXl5eXlcIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdChmb3VyVG9TaXgpO1xuICAgICAgICBjYXNlIFwieXl5eXl5XCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQoc2l4KTtcbiAgICAgICAgLy8gbW9udGhzXG4gICAgICAgIGNhc2UgXCJNXCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQob25lT3JUd28pO1xuICAgICAgICBjYXNlIFwiTU1cIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdCh0d28pO1xuICAgICAgICBjYXNlIFwiTU1NXCI6XG4gICAgICAgICAgcmV0dXJuIG9uZU9mKGxvYy5tb250aHMoXCJzaG9ydFwiLCB0cnVlKSwgMSk7XG4gICAgICAgIGNhc2UgXCJNTU1NXCI6XG4gICAgICAgICAgcmV0dXJuIG9uZU9mKGxvYy5tb250aHMoXCJsb25nXCIsIHRydWUpLCAxKTtcbiAgICAgICAgY2FzZSBcIkxcIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdChvbmVPclR3byk7XG4gICAgICAgIGNhc2UgXCJMTFwiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KHR3byk7XG4gICAgICAgIGNhc2UgXCJMTExcIjpcbiAgICAgICAgICByZXR1cm4gb25lT2YobG9jLm1vbnRocyhcInNob3J0XCIsIGZhbHNlKSwgMSk7XG4gICAgICAgIGNhc2UgXCJMTExMXCI6XG4gICAgICAgICAgcmV0dXJuIG9uZU9mKGxvYy5tb250aHMoXCJsb25nXCIsIGZhbHNlKSwgMSk7XG4gICAgICAgIC8vIGRhdGVzXG4gICAgICAgIGNhc2UgXCJkXCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQob25lT3JUd28pO1xuICAgICAgICBjYXNlIFwiZGRcIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdCh0d28pO1xuICAgICAgICAvLyBvcmRpbmFsc1xuICAgICAgICBjYXNlIFwib1wiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KG9uZVRvVGhyZWUpO1xuICAgICAgICBjYXNlIFwib29vXCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQodGhyZWUpO1xuICAgICAgICAvLyB0aW1lXG4gICAgICAgIGNhc2UgXCJISFwiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KHR3byk7XG4gICAgICAgIGNhc2UgXCJIXCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQob25lT3JUd28pO1xuICAgICAgICBjYXNlIFwiaGhcIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdCh0d28pO1xuICAgICAgICBjYXNlIFwiaFwiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KG9uZU9yVHdvKTtcbiAgICAgICAgY2FzZSBcIm1tXCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQodHdvKTtcbiAgICAgICAgY2FzZSBcIm1cIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdChvbmVPclR3byk7XG4gICAgICAgIGNhc2UgXCJxXCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQob25lT3JUd28pO1xuICAgICAgICBjYXNlIFwicXFcIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdCh0d28pO1xuICAgICAgICBjYXNlIFwic1wiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KG9uZU9yVHdvKTtcbiAgICAgICAgY2FzZSBcInNzXCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQodHdvKTtcbiAgICAgICAgY2FzZSBcIlNcIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdChvbmVUb1RocmVlKTtcbiAgICAgICAgY2FzZSBcIlNTU1wiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KHRocmVlKTtcbiAgICAgICAgY2FzZSBcInVcIjpcbiAgICAgICAgICByZXR1cm4gc2ltcGxlKG9uZVRvTmluZSk7XG4gICAgICAgIGNhc2UgXCJ1dVwiOlxuICAgICAgICAgIHJldHVybiBzaW1wbGUob25lT3JUd28pO1xuICAgICAgICBjYXNlIFwidXV1XCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQob25lKTtcbiAgICAgICAgLy8gbWVyaWRpZW1cbiAgICAgICAgY2FzZSBcImFcIjpcbiAgICAgICAgICByZXR1cm4gb25lT2YobG9jLm1lcmlkaWVtcygpLCAwKTtcbiAgICAgICAgLy8gd2Vla1llYXIgKGspXG4gICAgICAgIGNhc2UgXCJra2trXCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQoZm91cik7XG4gICAgICAgIGNhc2UgXCJra1wiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KHR3b1RvRm91ciwgdW50cnVuY2F0ZVllYXIpO1xuICAgICAgICAvLyB3ZWVrTnVtYmVyIChXKVxuICAgICAgICBjYXNlIFwiV1wiOlxuICAgICAgICAgIHJldHVybiBpbnRVbml0KG9uZU9yVHdvKTtcbiAgICAgICAgY2FzZSBcIldXXCI6XG4gICAgICAgICAgcmV0dXJuIGludFVuaXQodHdvKTtcbiAgICAgICAgLy8gd2Vla2RheXNcbiAgICAgICAgY2FzZSBcIkVcIjpcbiAgICAgICAgY2FzZSBcImNcIjpcbiAgICAgICAgICByZXR1cm4gaW50VW5pdChvbmUpO1xuICAgICAgICBjYXNlIFwiRUVFXCI6XG4gICAgICAgICAgcmV0dXJuIG9uZU9mKGxvYy53ZWVrZGF5cyhcInNob3J0XCIsIGZhbHNlKSwgMSk7XG4gICAgICAgIGNhc2UgXCJFRUVFXCI6XG4gICAgICAgICAgcmV0dXJuIG9uZU9mKGxvYy53ZWVrZGF5cyhcImxvbmdcIiwgZmFsc2UpLCAxKTtcbiAgICAgICAgY2FzZSBcImNjY1wiOlxuICAgICAgICAgIHJldHVybiBvbmVPZihsb2Mud2Vla2RheXMoXCJzaG9ydFwiLCB0cnVlKSwgMSk7XG4gICAgICAgIGNhc2UgXCJjY2NjXCI6XG4gICAgICAgICAgcmV0dXJuIG9uZU9mKGxvYy53ZWVrZGF5cyhcImxvbmdcIiwgdHJ1ZSksIDEpO1xuICAgICAgICAvLyBvZmZzZXQvem9uZVxuICAgICAgICBjYXNlIFwiWlwiOlxuICAgICAgICBjYXNlIFwiWlpcIjpcbiAgICAgICAgICByZXR1cm4gb2Zmc2V0KG5ldyBSZWdFeHAoYChbKy1dJHtvbmVPclR3by5zb3VyY2V9KSg/OjooJHt0d28uc291cmNlfSkpP2ApLCAyKTtcbiAgICAgICAgY2FzZSBcIlpaWlwiOlxuICAgICAgICAgIHJldHVybiBvZmZzZXQobmV3IFJlZ0V4cChgKFsrLV0ke29uZU9yVHdvLnNvdXJjZX0pKCR7dHdvLnNvdXJjZX0pP2ApLCAyKTtcbiAgICAgICAgLy8gd2UgZG9uJ3Qgc3VwcG9ydCBaWlpaIChQU1QpIG9yIFpaWlpaIChQYWNpZmljIFN0YW5kYXJkIFRpbWUpIGluIHBhcnNpbmdcbiAgICAgICAgLy8gYmVjYXVzZSB3ZSBkb24ndCBoYXZlIGFueSB3YXkgdG8gZmlndXJlIG91dCB3aGF0IHRoZXkgYXJlXG4gICAgICAgIGNhc2UgXCJ6XCI6XG4gICAgICAgICAgcmV0dXJuIHNpbXBsZSgvW2Etel8rLS9dezEsMjU2fT8vaSk7XG4gICAgICAgIC8vIHRoaXMgc3BlY2lhbC1jYXNlIFwidG9rZW5cIiByZXByZXNlbnRzIGEgcGxhY2Ugd2hlcmUgYSBtYWNyby10b2tlbiBleHBhbmRlZCBpbnRvIGEgd2hpdGUtc3BhY2UgbGl0ZXJhbFxuICAgICAgICAvLyBpbiB0aGlzIGNhc2Ugd2UgYWNjZXB0IGFueSBub24tbmV3bGluZSB3aGl0ZS1zcGFjZVxuICAgICAgICBjYXNlIFwiIFwiOlxuICAgICAgICAgIHJldHVybiBzaW1wbGUoL1teXFxTXFxuXFxyXS8pO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBsaXRlcmFsKHQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgY29uc3QgdW5pdCA9IHVuaXRhdGUodG9rZW4pIHx8IHtcbiAgICBpbnZhbGlkUmVhc29uOiBNSVNTSU5HX0ZUUCxcbiAgfTtcblxuICB1bml0LnRva2VuID0gdG9rZW47XG5cbiAgcmV0dXJuIHVuaXQ7XG59XG5cbmNvbnN0IHBhcnRUeXBlU3R5bGVUb1Rva2VuVmFsID0ge1xuICB5ZWFyOiB7XG4gICAgXCIyLWRpZ2l0XCI6IFwieXlcIixcbiAgICBudW1lcmljOiBcInl5eXl5XCIsXG4gIH0sXG4gIG1vbnRoOiB7XG4gICAgbnVtZXJpYzogXCJNXCIsXG4gICAgXCIyLWRpZ2l0XCI6IFwiTU1cIixcbiAgICBzaG9ydDogXCJNTU1cIixcbiAgICBsb25nOiBcIk1NTU1cIixcbiAgfSxcbiAgZGF5OiB7XG4gICAgbnVtZXJpYzogXCJkXCIsXG4gICAgXCIyLWRpZ2l0XCI6IFwiZGRcIixcbiAgfSxcbiAgd2Vla2RheToge1xuICAgIHNob3J0OiBcIkVFRVwiLFxuICAgIGxvbmc6IFwiRUVFRVwiLFxuICB9LFxuICBkYXlwZXJpb2Q6IFwiYVwiLFxuICBkYXlQZXJpb2Q6IFwiYVwiLFxuICBob3VyMTI6IHtcbiAgICBudW1lcmljOiBcImhcIixcbiAgICBcIjItZGlnaXRcIjogXCJoaFwiLFxuICB9LFxuICBob3VyMjQ6IHtcbiAgICBudW1lcmljOiBcIkhcIixcbiAgICBcIjItZGlnaXRcIjogXCJISFwiLFxuICB9LFxuICBtaW51dGU6IHtcbiAgICBudW1lcmljOiBcIm1cIixcbiAgICBcIjItZGlnaXRcIjogXCJtbVwiLFxuICB9LFxuICBzZWNvbmQ6IHtcbiAgICBudW1lcmljOiBcInNcIixcbiAgICBcIjItZGlnaXRcIjogXCJzc1wiLFxuICB9LFxuICB0aW1lWm9uZU5hbWU6IHtcbiAgICBsb25nOiBcIlpaWlpaXCIsXG4gICAgc2hvcnQ6IFwiWlpaXCIsXG4gIH0sXG59O1xuXG5mdW5jdGlvbiB0b2tlbkZvclBhcnQocGFydCwgZm9ybWF0T3B0cywgcmVzb2x2ZWRPcHRzKSB7XG4gIGNvbnN0IHsgdHlwZSwgdmFsdWUgfSA9IHBhcnQ7XG5cbiAgaWYgKHR5cGUgPT09IFwibGl0ZXJhbFwiKSB7XG4gICAgY29uc3QgaXNTcGFjZSA9IC9eXFxzKyQvLnRlc3QodmFsdWUpO1xuICAgIHJldHVybiB7XG4gICAgICBsaXRlcmFsOiAhaXNTcGFjZSxcbiAgICAgIHZhbDogaXNTcGFjZSA/IFwiIFwiIDogdmFsdWUsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IHN0eWxlID0gZm9ybWF0T3B0c1t0eXBlXTtcblxuICAvLyBUaGUgdXNlciBtaWdodCBoYXZlIGV4cGxpY2l0bHkgc3BlY2lmaWVkIGhvdXIxMiBvciBob3VyQ3ljbGVcbiAgLy8gaWYgc28sIHJlc3BlY3QgdGhlaXIgZGVjaXNpb25cbiAgLy8gaWYgbm90LCByZWZlciBiYWNrIHRvIHRoZSByZXNvbHZlZE9wdHMsIHdoaWNoIGFyZSBiYXNlZCBvbiB0aGUgbG9jYWxlXG4gIGxldCBhY3R1YWxUeXBlID0gdHlwZTtcbiAgaWYgKHR5cGUgPT09IFwiaG91clwiKSB7XG4gICAgaWYgKGZvcm1hdE9wdHMuaG91cjEyICE9IG51bGwpIHtcbiAgICAgIGFjdHVhbFR5cGUgPSBmb3JtYXRPcHRzLmhvdXIxMiA/IFwiaG91cjEyXCIgOiBcImhvdXIyNFwiO1xuICAgIH0gZWxzZSBpZiAoZm9ybWF0T3B0cy5ob3VyQ3ljbGUgIT0gbnVsbCkge1xuICAgICAgaWYgKGZvcm1hdE9wdHMuaG91ckN5Y2xlID09PSBcImgxMVwiIHx8IGZvcm1hdE9wdHMuaG91ckN5Y2xlID09PSBcImgxMlwiKSB7XG4gICAgICAgIGFjdHVhbFR5cGUgPSBcImhvdXIxMlwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWN0dWFsVHlwZSA9IFwiaG91cjI0XCI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHRva2VucyBvbmx5IGRpZmZlcmVudGlhdGUgYmV0d2VlbiAyNCBob3VycyBvciBub3QsXG4gICAgICAvLyBzbyB3ZSBkbyBub3QgbmVlZCB0byBjaGVjayBob3VyQ3ljbGUgaGVyZSwgd2hpY2ggaXMgbGVzcyBzdXBwb3J0ZWQgYW55d2F5c1xuICAgICAgYWN0dWFsVHlwZSA9IHJlc29sdmVkT3B0cy5ob3VyMTIgPyBcImhvdXIxMlwiIDogXCJob3VyMjRcIjtcbiAgICB9XG4gIH1cbiAgbGV0IHZhbCA9IHBhcnRUeXBlU3R5bGVUb1Rva2VuVmFsW2FjdHVhbFR5cGVdO1xuICBpZiAodHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIikge1xuICAgIHZhbCA9IHZhbFtzdHlsZV07XG4gIH1cblxuICBpZiAodmFsKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxpdGVyYWw6IGZhbHNlLFxuICAgICAgdmFsLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBidWlsZFJlZ2V4KHVuaXRzKSB7XG4gIGNvbnN0IHJlID0gdW5pdHMubWFwKCh1KSA9PiB1LnJlZ2V4KS5yZWR1Y2UoKGYsIHIpID0+IGAke2Z9KCR7ci5zb3VyY2V9KWAsIFwiXCIpO1xuICByZXR1cm4gW2BeJHtyZX0kYCwgdW5pdHNdO1xufVxuXG5mdW5jdGlvbiBtYXRjaChpbnB1dCwgcmVnZXgsIGhhbmRsZXJzKSB7XG4gIGNvbnN0IG1hdGNoZXMgPSBpbnB1dC5tYXRjaChyZWdleCk7XG5cbiAgaWYgKG1hdGNoZXMpIHtcbiAgICBjb25zdCBhbGwgPSB7fTtcbiAgICBsZXQgbWF0Y2hJbmRleCA9IDE7XG4gICAgZm9yIChjb25zdCBpIGluIGhhbmRsZXJzKSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkoaGFuZGxlcnMsIGkpKSB7XG4gICAgICAgIGNvbnN0IGggPSBoYW5kbGVyc1tpXSxcbiAgICAgICAgICBncm91cHMgPSBoLmdyb3VwcyA/IGguZ3JvdXBzICsgMSA6IDE7XG4gICAgICAgIGlmICghaC5saXRlcmFsICYmIGgudG9rZW4pIHtcbiAgICAgICAgICBhbGxbaC50b2tlbi52YWxbMF1dID0gaC5kZXNlcihtYXRjaGVzLnNsaWNlKG1hdGNoSW5kZXgsIG1hdGNoSW5kZXggKyBncm91cHMpKTtcbiAgICAgICAgfVxuICAgICAgICBtYXRjaEluZGV4ICs9IGdyb3VwcztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFttYXRjaGVzLCBhbGxdO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbbWF0Y2hlcywge31dO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRhdGVUaW1lRnJvbU1hdGNoZXMobWF0Y2hlcykge1xuICBjb25zdCB0b0ZpZWxkID0gKHRva2VuKSA9PiB7XG4gICAgc3dpdGNoICh0b2tlbikge1xuICAgICAgY2FzZSBcIlNcIjpcbiAgICAgICAgcmV0dXJuIFwibWlsbGlzZWNvbmRcIjtcbiAgICAgIGNhc2UgXCJzXCI6XG4gICAgICAgIHJldHVybiBcInNlY29uZFwiO1xuICAgICAgY2FzZSBcIm1cIjpcbiAgICAgICAgcmV0dXJuIFwibWludXRlXCI7XG4gICAgICBjYXNlIFwiaFwiOlxuICAgICAgY2FzZSBcIkhcIjpcbiAgICAgICAgcmV0dXJuIFwiaG91clwiO1xuICAgICAgY2FzZSBcImRcIjpcbiAgICAgICAgcmV0dXJuIFwiZGF5XCI7XG4gICAgICBjYXNlIFwib1wiOlxuICAgICAgICByZXR1cm4gXCJvcmRpbmFsXCI7XG4gICAgICBjYXNlIFwiTFwiOlxuICAgICAgY2FzZSBcIk1cIjpcbiAgICAgICAgcmV0dXJuIFwibW9udGhcIjtcbiAgICAgIGNhc2UgXCJ5XCI6XG4gICAgICAgIHJldHVybiBcInllYXJcIjtcbiAgICAgIGNhc2UgXCJFXCI6XG4gICAgICBjYXNlIFwiY1wiOlxuICAgICAgICByZXR1cm4gXCJ3ZWVrZGF5XCI7XG4gICAgICBjYXNlIFwiV1wiOlxuICAgICAgICByZXR1cm4gXCJ3ZWVrTnVtYmVyXCI7XG4gICAgICBjYXNlIFwia1wiOlxuICAgICAgICByZXR1cm4gXCJ3ZWVrWWVhclwiO1xuICAgICAgY2FzZSBcInFcIjpcbiAgICAgICAgcmV0dXJuIFwicXVhcnRlclwiO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9O1xuXG4gIGxldCB6b25lID0gbnVsbDtcbiAgbGV0IHNwZWNpZmljT2Zmc2V0O1xuICBpZiAoIWlzVW5kZWZpbmVkKG1hdGNoZXMueikpIHtcbiAgICB6b25lID0gSUFOQVpvbmUuY3JlYXRlKG1hdGNoZXMueik7XG4gIH1cblxuICBpZiAoIWlzVW5kZWZpbmVkKG1hdGNoZXMuWikpIHtcbiAgICBpZiAoIXpvbmUpIHtcbiAgICAgIHpvbmUgPSBuZXcgRml4ZWRPZmZzZXRab25lKG1hdGNoZXMuWik7XG4gICAgfVxuICAgIHNwZWNpZmljT2Zmc2V0ID0gbWF0Y2hlcy5aO1xuICB9XG5cbiAgaWYgKCFpc1VuZGVmaW5lZChtYXRjaGVzLnEpKSB7XG4gICAgbWF0Y2hlcy5NID0gKG1hdGNoZXMucSAtIDEpICogMyArIDE7XG4gIH1cblxuICBpZiAoIWlzVW5kZWZpbmVkKG1hdGNoZXMuaCkpIHtcbiAgICBpZiAobWF0Y2hlcy5oIDwgMTIgJiYgbWF0Y2hlcy5hID09PSAxKSB7XG4gICAgICBtYXRjaGVzLmggKz0gMTI7XG4gICAgfSBlbHNlIGlmIChtYXRjaGVzLmggPT09IDEyICYmIG1hdGNoZXMuYSA9PT0gMCkge1xuICAgICAgbWF0Y2hlcy5oID0gMDtcbiAgICB9XG4gIH1cblxuICBpZiAobWF0Y2hlcy5HID09PSAwICYmIG1hdGNoZXMueSkge1xuICAgIG1hdGNoZXMueSA9IC1tYXRjaGVzLnk7XG4gIH1cblxuICBpZiAoIWlzVW5kZWZpbmVkKG1hdGNoZXMudSkpIHtcbiAgICBtYXRjaGVzLlMgPSBwYXJzZU1pbGxpcyhtYXRjaGVzLnUpO1xuICB9XG5cbiAgY29uc3QgdmFscyA9IE9iamVjdC5rZXlzKG1hdGNoZXMpLnJlZHVjZSgociwgaykgPT4ge1xuICAgIGNvbnN0IGYgPSB0b0ZpZWxkKGspO1xuICAgIGlmIChmKSB7XG4gICAgICByW2ZdID0gbWF0Y2hlc1trXTtcbiAgICB9XG5cbiAgICByZXR1cm4gcjtcbiAgfSwge30pO1xuXG4gIHJldHVybiBbdmFscywgem9uZSwgc3BlY2lmaWNPZmZzZXRdO1xufVxuXG5sZXQgZHVtbXlEYXRlVGltZUNhY2hlID0gbnVsbDtcblxuZnVuY3Rpb24gZ2V0RHVtbXlEYXRlVGltZSgpIHtcbiAgaWYgKCFkdW1teURhdGVUaW1lQ2FjaGUpIHtcbiAgICBkdW1teURhdGVUaW1lQ2FjaGUgPSBEYXRlVGltZS5mcm9tTWlsbGlzKDE1NTU1NTU1NTU1NTUpO1xuICB9XG5cbiAgcmV0dXJuIGR1bW15RGF0ZVRpbWVDYWNoZTtcbn1cblxuZnVuY3Rpb24gbWF5YmVFeHBhbmRNYWNyb1Rva2VuKHRva2VuLCBsb2NhbGUpIHtcbiAgaWYgKHRva2VuLmxpdGVyYWwpIHtcbiAgICByZXR1cm4gdG9rZW47XG4gIH1cblxuICBjb25zdCBmb3JtYXRPcHRzID0gRm9ybWF0dGVyLm1hY3JvVG9rZW5Ub0Zvcm1hdE9wdHModG9rZW4udmFsKTtcbiAgY29uc3QgdG9rZW5zID0gZm9ybWF0T3B0c1RvVG9rZW5zKGZvcm1hdE9wdHMsIGxvY2FsZSk7XG5cbiAgaWYgKHRva2VucyA9PSBudWxsIHx8IHRva2Vucy5pbmNsdWRlcyh1bmRlZmluZWQpKSB7XG4gICAgcmV0dXJuIHRva2VuO1xuICB9XG5cbiAgcmV0dXJuIHRva2Vucztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGFuZE1hY3JvVG9rZW5zKHRva2VucywgbG9jYWxlKSB7XG4gIHJldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0KC4uLnRva2Vucy5tYXAoKHQpID0+IG1heWJlRXhwYW5kTWFjcm9Ub2tlbih0LCBsb2NhbGUpKSk7XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXhwbGFpbkZyb21Ub2tlbnMobG9jYWxlLCBpbnB1dCwgZm9ybWF0KSB7XG4gIGNvbnN0IHRva2VucyA9IGV4cGFuZE1hY3JvVG9rZW5zKEZvcm1hdHRlci5wYXJzZUZvcm1hdChmb3JtYXQpLCBsb2NhbGUpLFxuICAgIHVuaXRzID0gdG9rZW5zLm1hcCgodCkgPT4gdW5pdEZvclRva2VuKHQsIGxvY2FsZSkpLFxuICAgIGRpc3F1YWxpZnlpbmdVbml0ID0gdW5pdHMuZmluZCgodCkgPT4gdC5pbnZhbGlkUmVhc29uKTtcblxuICBpZiAoZGlzcXVhbGlmeWluZ1VuaXQpIHtcbiAgICByZXR1cm4geyBpbnB1dCwgdG9rZW5zLCBpbnZhbGlkUmVhc29uOiBkaXNxdWFsaWZ5aW5nVW5pdC5pbnZhbGlkUmVhc29uIH07XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgW3JlZ2V4U3RyaW5nLCBoYW5kbGVyc10gPSBidWlsZFJlZ2V4KHVuaXRzKSxcbiAgICAgIHJlZ2V4ID0gUmVnRXhwKHJlZ2V4U3RyaW5nLCBcImlcIiksXG4gICAgICBbcmF3TWF0Y2hlcywgbWF0Y2hlc10gPSBtYXRjaChpbnB1dCwgcmVnZXgsIGhhbmRsZXJzKSxcbiAgICAgIFtyZXN1bHQsIHpvbmUsIHNwZWNpZmljT2Zmc2V0XSA9IG1hdGNoZXNcbiAgICAgICAgPyBkYXRlVGltZUZyb21NYXRjaGVzKG1hdGNoZXMpXG4gICAgICAgIDogW251bGwsIG51bGwsIHVuZGVmaW5lZF07XG4gICAgaWYgKGhhc093blByb3BlcnR5KG1hdGNoZXMsIFwiYVwiKSAmJiBoYXNPd25Qcm9wZXJ0eShtYXRjaGVzLCBcIkhcIikpIHtcbiAgICAgIHRocm93IG5ldyBDb25mbGljdGluZ1NwZWNpZmljYXRpb25FcnJvcihcbiAgICAgICAgXCJDYW4ndCBpbmNsdWRlIG1lcmlkaWVtIHdoZW4gc3BlY2lmeWluZyAyNC1ob3VyIGZvcm1hdFwiXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4geyBpbnB1dCwgdG9rZW5zLCByZWdleCwgcmF3TWF0Y2hlcywgbWF0Y2hlcywgcmVzdWx0LCB6b25lLCBzcGVjaWZpY09mZnNldCB9O1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUZyb21Ub2tlbnMobG9jYWxlLCBpbnB1dCwgZm9ybWF0KSB7XG4gIGNvbnN0IHsgcmVzdWx0LCB6b25lLCBzcGVjaWZpY09mZnNldCwgaW52YWxpZFJlYXNvbiB9ID0gZXhwbGFpbkZyb21Ub2tlbnMobG9jYWxlLCBpbnB1dCwgZm9ybWF0KTtcbiAgcmV0dXJuIFtyZXN1bHQsIHpvbmUsIHNwZWNpZmljT2Zmc2V0LCBpbnZhbGlkUmVhc29uXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdE9wdHNUb1Rva2Vucyhmb3JtYXRPcHRzLCBsb2NhbGUpIHtcbiAgaWYgKCFmb3JtYXRPcHRzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBmb3JtYXR0ZXIgPSBGb3JtYXR0ZXIuY3JlYXRlKGxvY2FsZSwgZm9ybWF0T3B0cyk7XG4gIGNvbnN0IGRmID0gZm9ybWF0dGVyLmR0Rm9ybWF0dGVyKGdldER1bW15RGF0ZVRpbWUoKSk7XG4gIGNvbnN0IHBhcnRzID0gZGYuZm9ybWF0VG9QYXJ0cygpO1xuICBjb25zdCByZXNvbHZlZE9wdHMgPSBkZi5yZXNvbHZlZE9wdGlvbnMoKTtcbiAgcmV0dXJuIHBhcnRzLm1hcCgocCkgPT4gdG9rZW5Gb3JQYXJ0KHAsIGZvcm1hdE9wdHMsIHJlc29sdmVkT3B0cykpO1xufVxuIiwgImltcG9ydCBEdXJhdGlvbiBmcm9tIFwiLi9kdXJhdGlvbi5qc1wiO1xuaW1wb3J0IEludGVydmFsIGZyb20gXCIuL2ludGVydmFsLmpzXCI7XG5pbXBvcnQgU2V0dGluZ3MgZnJvbSBcIi4vc2V0dGluZ3MuanNcIjtcbmltcG9ydCBJbmZvIGZyb20gXCIuL2luZm8uanNcIjtcbmltcG9ydCBGb3JtYXR0ZXIgZnJvbSBcIi4vaW1wbC9mb3JtYXR0ZXIuanNcIjtcbmltcG9ydCBGaXhlZE9mZnNldFpvbmUgZnJvbSBcIi4vem9uZXMvZml4ZWRPZmZzZXRab25lLmpzXCI7XG5pbXBvcnQgTG9jYWxlIGZyb20gXCIuL2ltcGwvbG9jYWxlLmpzXCI7XG5pbXBvcnQge1xuICBpc1VuZGVmaW5lZCxcbiAgbWF5YmVBcnJheSxcbiAgaXNEYXRlLFxuICBpc051bWJlcixcbiAgYmVzdEJ5LFxuICBkYXlzSW5Nb250aCxcbiAgZGF5c0luWWVhcixcbiAgaXNMZWFwWWVhcixcbiAgd2Vla3NJbldlZWtZZWFyLFxuICBub3JtYWxpemVPYmplY3QsXG4gIHJvdW5kVG8sXG4gIG9ialRvTG9jYWxUUyxcbiAgcGFkU3RhcnQsXG59IGZyb20gXCIuL2ltcGwvdXRpbC5qc1wiO1xuaW1wb3J0IHsgbm9ybWFsaXplWm9uZSB9IGZyb20gXCIuL2ltcGwvem9uZVV0aWwuanNcIjtcbmltcG9ydCBkaWZmIGZyb20gXCIuL2ltcGwvZGlmZi5qc1wiO1xuaW1wb3J0IHsgcGFyc2VSRkMyODIyRGF0ZSwgcGFyc2VJU09EYXRlLCBwYXJzZUhUVFBEYXRlLCBwYXJzZVNRTCB9IGZyb20gXCIuL2ltcGwvcmVnZXhQYXJzZXIuanNcIjtcbmltcG9ydCB7XG4gIHBhcnNlRnJvbVRva2VucyxcbiAgZXhwbGFpbkZyb21Ub2tlbnMsXG4gIGZvcm1hdE9wdHNUb1Rva2VucyxcbiAgZXhwYW5kTWFjcm9Ub2tlbnMsXG59IGZyb20gXCIuL2ltcGwvdG9rZW5QYXJzZXIuanNcIjtcbmltcG9ydCB7XG4gIGdyZWdvcmlhblRvV2VlayxcbiAgd2Vla1RvR3JlZ29yaWFuLFxuICBncmVnb3JpYW5Ub09yZGluYWwsXG4gIG9yZGluYWxUb0dyZWdvcmlhbixcbiAgaGFzSW52YWxpZEdyZWdvcmlhbkRhdGEsXG4gIGhhc0ludmFsaWRXZWVrRGF0YSxcbiAgaGFzSW52YWxpZE9yZGluYWxEYXRhLFxuICBoYXNJbnZhbGlkVGltZURhdGEsXG4gIHVzZXNMb2NhbFdlZWtWYWx1ZXMsXG4gIGlzb1dlZWtkYXlUb0xvY2FsLFxufSBmcm9tIFwiLi9pbXBsL2NvbnZlcnNpb25zLmpzXCI7XG5pbXBvcnQgKiBhcyBGb3JtYXRzIGZyb20gXCIuL2ltcGwvZm9ybWF0cy5qc1wiO1xuaW1wb3J0IHtcbiAgSW52YWxpZEFyZ3VtZW50RXJyb3IsXG4gIENvbmZsaWN0aW5nU3BlY2lmaWNhdGlvbkVycm9yLFxuICBJbnZhbGlkVW5pdEVycm9yLFxuICBJbnZhbGlkRGF0ZVRpbWVFcnJvcixcbn0gZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5pbXBvcnQgSW52YWxpZCBmcm9tIFwiLi9pbXBsL2ludmFsaWQuanNcIjtcblxuY29uc3QgSU5WQUxJRCA9IFwiSW52YWxpZCBEYXRlVGltZVwiO1xuY29uc3QgTUFYX0RBVEUgPSA4LjY0ZTE1O1xuXG5mdW5jdGlvbiB1bnN1cHBvcnRlZFpvbmUoem9uZSkge1xuICByZXR1cm4gbmV3IEludmFsaWQoXCJ1bnN1cHBvcnRlZCB6b25lXCIsIGB0aGUgem9uZSBcIiR7em9uZS5uYW1lfVwiIGlzIG5vdCBzdXBwb3J0ZWRgKTtcbn1cblxuLy8gd2UgY2FjaGUgd2VlayBkYXRhIG9uIHRoZSBEVCBvYmplY3QgYW5kIHRoaXMgaW50ZXJtZWRpYXRlcyB0aGUgY2FjaGVcbi8qKlxuICogQHBhcmFtIHtEYXRlVGltZX0gZHRcbiAqL1xuZnVuY3Rpb24gcG9zc2libHlDYWNoZWRXZWVrRGF0YShkdCkge1xuICBpZiAoZHQud2Vla0RhdGEgPT09IG51bGwpIHtcbiAgICBkdC53ZWVrRGF0YSA9IGdyZWdvcmlhblRvV2VlayhkdC5jKTtcbiAgfVxuICByZXR1cm4gZHQud2Vla0RhdGE7XG59XG5cbi8qKlxuICogQHBhcmFtIHtEYXRlVGltZX0gZHRcbiAqL1xuZnVuY3Rpb24gcG9zc2libHlDYWNoZWRMb2NhbFdlZWtEYXRhKGR0KSB7XG4gIGlmIChkdC5sb2NhbFdlZWtEYXRhID09PSBudWxsKSB7XG4gICAgZHQubG9jYWxXZWVrRGF0YSA9IGdyZWdvcmlhblRvV2VlayhcbiAgICAgIGR0LmMsXG4gICAgICBkdC5sb2MuZ2V0TWluRGF5c0luRmlyc3RXZWVrKCksXG4gICAgICBkdC5sb2MuZ2V0U3RhcnRPZldlZWsoKVxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGR0LmxvY2FsV2Vla0RhdGE7XG59XG5cbi8vIGNsb25lIHJlYWxseSBtZWFucywgXCJtYWtlIGEgbmV3IG9iamVjdCB3aXRoIHRoZXNlIG1vZGlmaWNhdGlvbnNcIi4gYWxsIFwic2V0dGVyc1wiIHJlYWxseSB1c2UgdGhpc1xuLy8gdG8gY3JlYXRlIGEgbmV3IG9iamVjdCB3aGlsZSBvbmx5IGNoYW5naW5nIHNvbWUgb2YgdGhlIHByb3BlcnRpZXNcbmZ1bmN0aW9uIGNsb25lKGluc3QsIGFsdHMpIHtcbiAgY29uc3QgY3VycmVudCA9IHtcbiAgICB0czogaW5zdC50cyxcbiAgICB6b25lOiBpbnN0LnpvbmUsXG4gICAgYzogaW5zdC5jLFxuICAgIG86IGluc3QubyxcbiAgICBsb2M6IGluc3QubG9jLFxuICAgIGludmFsaWQ6IGluc3QuaW52YWxpZCxcbiAgfTtcbiAgcmV0dXJuIG5ldyBEYXRlVGltZSh7IC4uLmN1cnJlbnQsIC4uLmFsdHMsIG9sZDogY3VycmVudCB9KTtcbn1cblxuLy8gZmluZCB0aGUgcmlnaHQgb2Zmc2V0IGEgZ2l2ZW4gbG9jYWwgdGltZS4gVGhlIG8gaW5wdXQgaXMgb3VyIGd1ZXNzLCB3aGljaCBkZXRlcm1pbmVzIHdoaWNoXG4vLyBvZmZzZXQgd2UnbGwgcGljayBpbiBhbWJpZ3VvdXMgY2FzZXMgKGUuZy4gdGhlcmUgYXJlIHR3byAzIEFNcyBiL2MgRmFsbGJhY2sgRFNUKVxuZnVuY3Rpb24gZml4T2Zmc2V0KGxvY2FsVFMsIG8sIHR6KSB7XG4gIC8vIE91ciBVVEMgdGltZSBpcyBqdXN0IGEgZ3Vlc3MgYmVjYXVzZSBvdXIgb2Zmc2V0IGlzIGp1c3QgYSBndWVzc1xuICBsZXQgdXRjR3Vlc3MgPSBsb2NhbFRTIC0gbyAqIDYwICogMTAwMDtcblxuICAvLyBUZXN0IHdoZXRoZXIgdGhlIHpvbmUgbWF0Y2hlcyB0aGUgb2Zmc2V0IGZvciB0aGlzIHRzXG4gIGNvbnN0IG8yID0gdHoub2Zmc2V0KHV0Y0d1ZXNzKTtcblxuICAvLyBJZiBzbywgb2Zmc2V0IGRpZG4ndCBjaGFuZ2UgYW5kIHdlJ3JlIGRvbmVcbiAgaWYgKG8gPT09IG8yKSB7XG4gICAgcmV0dXJuIFt1dGNHdWVzcywgb107XG4gIH1cblxuICAvLyBJZiBub3QsIGNoYW5nZSB0aGUgdHMgYnkgdGhlIGRpZmZlcmVuY2UgaW4gdGhlIG9mZnNldFxuICB1dGNHdWVzcyAtPSAobzIgLSBvKSAqIDYwICogMTAwMDtcblxuICAvLyBJZiB0aGF0IGdpdmVzIHVzIHRoZSBsb2NhbCB0aW1lIHdlIHdhbnQsIHdlJ3JlIGRvbmVcbiAgY29uc3QgbzMgPSB0ei5vZmZzZXQodXRjR3Vlc3MpO1xuICBpZiAobzIgPT09IG8zKSB7XG4gICAgcmV0dXJuIFt1dGNHdWVzcywgbzJdO1xuICB9XG5cbiAgLy8gSWYgaXQncyBkaWZmZXJlbnQsIHdlJ3JlIGluIGEgaG9sZSB0aW1lLiBUaGUgb2Zmc2V0IGhhcyBjaGFuZ2VkLCBidXQgdGhlIHdlIGRvbid0IGFkanVzdCB0aGUgdGltZVxuICByZXR1cm4gW2xvY2FsVFMgLSBNYXRoLm1pbihvMiwgbzMpICogNjAgKiAxMDAwLCBNYXRoLm1heChvMiwgbzMpXTtcbn1cblxuLy8gY29udmVydCBhbiBlcG9jaCB0aW1lc3RhbXAgaW50byBhIGNhbGVuZGFyIG9iamVjdCB3aXRoIHRoZSBnaXZlbiBvZmZzZXRcbmZ1bmN0aW9uIHRzVG9PYmoodHMsIG9mZnNldCkge1xuICB0cyArPSBvZmZzZXQgKiA2MCAqIDEwMDA7XG5cbiAgY29uc3QgZCA9IG5ldyBEYXRlKHRzKTtcblxuICByZXR1cm4ge1xuICAgIHllYXI6IGQuZ2V0VVRDRnVsbFllYXIoKSxcbiAgICBtb250aDogZC5nZXRVVENNb250aCgpICsgMSxcbiAgICBkYXk6IGQuZ2V0VVRDRGF0ZSgpLFxuICAgIGhvdXI6IGQuZ2V0VVRDSG91cnMoKSxcbiAgICBtaW51dGU6IGQuZ2V0VVRDTWludXRlcygpLFxuICAgIHNlY29uZDogZC5nZXRVVENTZWNvbmRzKCksXG4gICAgbWlsbGlzZWNvbmQ6IGQuZ2V0VVRDTWlsbGlzZWNvbmRzKCksXG4gIH07XG59XG5cbi8vIGNvbnZlcnQgYSBjYWxlbmRhciBvYmplY3QgdG8gYSBlcG9jaCB0aW1lc3RhbXBcbmZ1bmN0aW9uIG9ialRvVFMob2JqLCBvZmZzZXQsIHpvbmUpIHtcbiAgcmV0dXJuIGZpeE9mZnNldChvYmpUb0xvY2FsVFMob2JqKSwgb2Zmc2V0LCB6b25lKTtcbn1cblxuLy8gY3JlYXRlIGEgbmV3IERUIGluc3RhbmNlIGJ5IGFkZGluZyBhIGR1cmF0aW9uLCBhZGp1c3RpbmcgZm9yIERTVHNcbmZ1bmN0aW9uIGFkanVzdFRpbWUoaW5zdCwgZHVyKSB7XG4gIGNvbnN0IG9QcmUgPSBpbnN0Lm8sXG4gICAgeWVhciA9IGluc3QuYy55ZWFyICsgTWF0aC50cnVuYyhkdXIueWVhcnMpLFxuICAgIG1vbnRoID0gaW5zdC5jLm1vbnRoICsgTWF0aC50cnVuYyhkdXIubW9udGhzKSArIE1hdGgudHJ1bmMoZHVyLnF1YXJ0ZXJzKSAqIDMsXG4gICAgYyA9IHtcbiAgICAgIC4uLmluc3QuYyxcbiAgICAgIHllYXIsXG4gICAgICBtb250aCxcbiAgICAgIGRheTpcbiAgICAgICAgTWF0aC5taW4oaW5zdC5jLmRheSwgZGF5c0luTW9udGgoeWVhciwgbW9udGgpKSArXG4gICAgICAgIE1hdGgudHJ1bmMoZHVyLmRheXMpICtcbiAgICAgICAgTWF0aC50cnVuYyhkdXIud2Vla3MpICogNyxcbiAgICB9LFxuICAgIG1pbGxpc1RvQWRkID0gRHVyYXRpb24uZnJvbU9iamVjdCh7XG4gICAgICB5ZWFyczogZHVyLnllYXJzIC0gTWF0aC50cnVuYyhkdXIueWVhcnMpLFxuICAgICAgcXVhcnRlcnM6IGR1ci5xdWFydGVycyAtIE1hdGgudHJ1bmMoZHVyLnF1YXJ0ZXJzKSxcbiAgICAgIG1vbnRoczogZHVyLm1vbnRocyAtIE1hdGgudHJ1bmMoZHVyLm1vbnRocyksXG4gICAgICB3ZWVrczogZHVyLndlZWtzIC0gTWF0aC50cnVuYyhkdXIud2Vla3MpLFxuICAgICAgZGF5czogZHVyLmRheXMgLSBNYXRoLnRydW5jKGR1ci5kYXlzKSxcbiAgICAgIGhvdXJzOiBkdXIuaG91cnMsXG4gICAgICBtaW51dGVzOiBkdXIubWludXRlcyxcbiAgICAgIHNlY29uZHM6IGR1ci5zZWNvbmRzLFxuICAgICAgbWlsbGlzZWNvbmRzOiBkdXIubWlsbGlzZWNvbmRzLFxuICAgIH0pLmFzKFwibWlsbGlzZWNvbmRzXCIpLFxuICAgIGxvY2FsVFMgPSBvYmpUb0xvY2FsVFMoYyk7XG5cbiAgbGV0IFt0cywgb10gPSBmaXhPZmZzZXQobG9jYWxUUywgb1ByZSwgaW5zdC56b25lKTtcblxuICBpZiAobWlsbGlzVG9BZGQgIT09IDApIHtcbiAgICB0cyArPSBtaWxsaXNUb0FkZDtcbiAgICAvLyB0aGF0IGNvdWxkIGhhdmUgY2hhbmdlZCB0aGUgb2Zmc2V0IGJ5IGdvaW5nIG92ZXIgYSBEU1QsIGJ1dCB3ZSB3YW50IHRvIGtlZXAgdGhlIHRzIHRoZSBzYW1lXG4gICAgbyA9IGluc3Quem9uZS5vZmZzZXQodHMpO1xuICB9XG5cbiAgcmV0dXJuIHsgdHMsIG8gfTtcbn1cblxuLy8gaGVscGVyIHVzZWZ1bCBpbiB0dXJuaW5nIHRoZSByZXN1bHRzIG9mIHBhcnNpbmcgaW50byByZWFsIGRhdGVzXG4vLyBieSBoYW5kbGluZyB0aGUgem9uZSBvcHRpb25zXG5mdW5jdGlvbiBwYXJzZURhdGFUb0RhdGVUaW1lKHBhcnNlZCwgcGFyc2VkWm9uZSwgb3B0cywgZm9ybWF0LCB0ZXh0LCBzcGVjaWZpY09mZnNldCkge1xuICBjb25zdCB7IHNldFpvbmUsIHpvbmUgfSA9IG9wdHM7XG4gIGlmICgocGFyc2VkICYmIE9iamVjdC5rZXlzKHBhcnNlZCkubGVuZ3RoICE9PSAwKSB8fCBwYXJzZWRab25lKSB7XG4gICAgY29uc3QgaW50ZXJwcmV0YXRpb25ab25lID0gcGFyc2VkWm9uZSB8fCB6b25lLFxuICAgICAgaW5zdCA9IERhdGVUaW1lLmZyb21PYmplY3QocGFyc2VkLCB7XG4gICAgICAgIC4uLm9wdHMsXG4gICAgICAgIHpvbmU6IGludGVycHJldGF0aW9uWm9uZSxcbiAgICAgICAgc3BlY2lmaWNPZmZzZXQsXG4gICAgICB9KTtcbiAgICByZXR1cm4gc2V0Wm9uZSA/IGluc3QgOiBpbnN0LnNldFpvbmUoem9uZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIERhdGVUaW1lLmludmFsaWQoXG4gICAgICBuZXcgSW52YWxpZChcInVucGFyc2FibGVcIiwgYHRoZSBpbnB1dCBcIiR7dGV4dH1cIiBjYW4ndCBiZSBwYXJzZWQgYXMgJHtmb3JtYXR9YClcbiAgICApO1xuICB9XG59XG5cbi8vIGlmIHlvdSB3YW50IHRvIG91dHB1dCBhIHRlY2huaWNhbCBmb3JtYXQgKGUuZy4gUkZDIDI4MjIpLCB0aGlzIGhlbHBlclxuLy8gaGVscHMgaGFuZGxlIHRoZSBkZXRhaWxzXG5mdW5jdGlvbiB0b1RlY2hGb3JtYXQoZHQsIGZvcm1hdCwgYWxsb3daID0gdHJ1ZSkge1xuICByZXR1cm4gZHQuaXNWYWxpZFxuICAgID8gRm9ybWF0dGVyLmNyZWF0ZShMb2NhbGUuY3JlYXRlKFwiZW4tVVNcIiksIHtcbiAgICAgICAgYWxsb3daLFxuICAgICAgICBmb3JjZVNpbXBsZTogdHJ1ZSxcbiAgICAgIH0pLmZvcm1hdERhdGVUaW1lRnJvbVN0cmluZyhkdCwgZm9ybWF0KVxuICAgIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gdG9JU09EYXRlKG8sIGV4dGVuZGVkKSB7XG4gIGNvbnN0IGxvbmdGb3JtYXQgPSBvLmMueWVhciA+IDk5OTkgfHwgby5jLnllYXIgPCAwO1xuICBsZXQgYyA9IFwiXCI7XG4gIGlmIChsb25nRm9ybWF0ICYmIG8uYy55ZWFyID49IDApIGMgKz0gXCIrXCI7XG4gIGMgKz0gcGFkU3RhcnQoby5jLnllYXIsIGxvbmdGb3JtYXQgPyA2IDogNCk7XG5cbiAgaWYgKGV4dGVuZGVkKSB7XG4gICAgYyArPSBcIi1cIjtcbiAgICBjICs9IHBhZFN0YXJ0KG8uYy5tb250aCk7XG4gICAgYyArPSBcIi1cIjtcbiAgICBjICs9IHBhZFN0YXJ0KG8uYy5kYXkpO1xuICB9IGVsc2Uge1xuICAgIGMgKz0gcGFkU3RhcnQoby5jLm1vbnRoKTtcbiAgICBjICs9IHBhZFN0YXJ0KG8uYy5kYXkpO1xuICB9XG4gIHJldHVybiBjO1xufVxuXG5mdW5jdGlvbiB0b0lTT1RpbWUoXG4gIG8sXG4gIGV4dGVuZGVkLFxuICBzdXBwcmVzc1NlY29uZHMsXG4gIHN1cHByZXNzTWlsbGlzZWNvbmRzLFxuICBpbmNsdWRlT2Zmc2V0LFxuICBleHRlbmRlZFpvbmVcbikge1xuICBsZXQgYyA9IHBhZFN0YXJ0KG8uYy5ob3VyKTtcbiAgaWYgKGV4dGVuZGVkKSB7XG4gICAgYyArPSBcIjpcIjtcbiAgICBjICs9IHBhZFN0YXJ0KG8uYy5taW51dGUpO1xuICAgIGlmIChvLmMubWlsbGlzZWNvbmQgIT09IDAgfHwgby5jLnNlY29uZCAhPT0gMCB8fCAhc3VwcHJlc3NTZWNvbmRzKSB7XG4gICAgICBjICs9IFwiOlwiO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBjICs9IHBhZFN0YXJ0KG8uYy5taW51dGUpO1xuICB9XG5cbiAgaWYgKG8uYy5taWxsaXNlY29uZCAhPT0gMCB8fCBvLmMuc2Vjb25kICE9PSAwIHx8ICFzdXBwcmVzc1NlY29uZHMpIHtcbiAgICBjICs9IHBhZFN0YXJ0KG8uYy5zZWNvbmQpO1xuXG4gICAgaWYgKG8uYy5taWxsaXNlY29uZCAhPT0gMCB8fCAhc3VwcHJlc3NNaWxsaXNlY29uZHMpIHtcbiAgICAgIGMgKz0gXCIuXCI7XG4gICAgICBjICs9IHBhZFN0YXJ0KG8uYy5taWxsaXNlY29uZCwgMyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGluY2x1ZGVPZmZzZXQpIHtcbiAgICBpZiAoby5pc09mZnNldEZpeGVkICYmIG8ub2Zmc2V0ID09PSAwICYmICFleHRlbmRlZFpvbmUpIHtcbiAgICAgIGMgKz0gXCJaXCI7XG4gICAgfSBlbHNlIGlmIChvLm8gPCAwKSB7XG4gICAgICBjICs9IFwiLVwiO1xuICAgICAgYyArPSBwYWRTdGFydChNYXRoLnRydW5jKC1vLm8gLyA2MCkpO1xuICAgICAgYyArPSBcIjpcIjtcbiAgICAgIGMgKz0gcGFkU3RhcnQoTWF0aC50cnVuYygtby5vICUgNjApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYyArPSBcIitcIjtcbiAgICAgIGMgKz0gcGFkU3RhcnQoTWF0aC50cnVuYyhvLm8gLyA2MCkpO1xuICAgICAgYyArPSBcIjpcIjtcbiAgICAgIGMgKz0gcGFkU3RhcnQoTWF0aC50cnVuYyhvLm8gJSA2MCkpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChleHRlbmRlZFpvbmUpIHtcbiAgICBjICs9IFwiW1wiICsgby56b25lLmlhbmFOYW1lICsgXCJdXCI7XG4gIH1cbiAgcmV0dXJuIGM7XG59XG5cbi8vIGRlZmF1bHRzIGZvciB1bnNwZWNpZmllZCB1bml0cyBpbiB0aGUgc3VwcG9ydGVkIGNhbGVuZGFyc1xuY29uc3QgZGVmYXVsdFVuaXRWYWx1ZXMgPSB7XG4gICAgbW9udGg6IDEsXG4gICAgZGF5OiAxLFxuICAgIGhvdXI6IDAsXG4gICAgbWludXRlOiAwLFxuICAgIHNlY29uZDogMCxcbiAgICBtaWxsaXNlY29uZDogMCxcbiAgfSxcbiAgZGVmYXVsdFdlZWtVbml0VmFsdWVzID0ge1xuICAgIHdlZWtOdW1iZXI6IDEsXG4gICAgd2Vla2RheTogMSxcbiAgICBob3VyOiAwLFxuICAgIG1pbnV0ZTogMCxcbiAgICBzZWNvbmQ6IDAsXG4gICAgbWlsbGlzZWNvbmQ6IDAsXG4gIH0sXG4gIGRlZmF1bHRPcmRpbmFsVW5pdFZhbHVlcyA9IHtcbiAgICBvcmRpbmFsOiAxLFxuICAgIGhvdXI6IDAsXG4gICAgbWludXRlOiAwLFxuICAgIHNlY29uZDogMCxcbiAgICBtaWxsaXNlY29uZDogMCxcbiAgfTtcblxuLy8gVW5pdHMgaW4gdGhlIHN1cHBvcnRlZCBjYWxlbmRhcnMsIHNvcnRlZCBieSBiaWduZXNzXG5jb25zdCBvcmRlcmVkVW5pdHMgPSBbXCJ5ZWFyXCIsIFwibW9udGhcIiwgXCJkYXlcIiwgXCJob3VyXCIsIFwibWludXRlXCIsIFwic2Vjb25kXCIsIFwibWlsbGlzZWNvbmRcIl0sXG4gIG9yZGVyZWRXZWVrVW5pdHMgPSBbXG4gICAgXCJ3ZWVrWWVhclwiLFxuICAgIFwid2Vla051bWJlclwiLFxuICAgIFwid2Vla2RheVwiLFxuICAgIFwiaG91clwiLFxuICAgIFwibWludXRlXCIsXG4gICAgXCJzZWNvbmRcIixcbiAgICBcIm1pbGxpc2Vjb25kXCIsXG4gIF0sXG4gIG9yZGVyZWRPcmRpbmFsVW5pdHMgPSBbXCJ5ZWFyXCIsIFwib3JkaW5hbFwiLCBcImhvdXJcIiwgXCJtaW51dGVcIiwgXCJzZWNvbmRcIiwgXCJtaWxsaXNlY29uZFwiXTtcblxuLy8gc3RhbmRhcmRpemUgY2FzZSBhbmQgcGx1cmFsaXR5IGluIHVuaXRzXG5mdW5jdGlvbiBub3JtYWxpemVVbml0KHVuaXQpIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHtcbiAgICB5ZWFyOiBcInllYXJcIixcbiAgICB5ZWFyczogXCJ5ZWFyXCIsXG4gICAgbW9udGg6IFwibW9udGhcIixcbiAgICBtb250aHM6IFwibW9udGhcIixcbiAgICBkYXk6IFwiZGF5XCIsXG4gICAgZGF5czogXCJkYXlcIixcbiAgICBob3VyOiBcImhvdXJcIixcbiAgICBob3VyczogXCJob3VyXCIsXG4gICAgbWludXRlOiBcIm1pbnV0ZVwiLFxuICAgIG1pbnV0ZXM6IFwibWludXRlXCIsXG4gICAgcXVhcnRlcjogXCJxdWFydGVyXCIsXG4gICAgcXVhcnRlcnM6IFwicXVhcnRlclwiLFxuICAgIHNlY29uZDogXCJzZWNvbmRcIixcbiAgICBzZWNvbmRzOiBcInNlY29uZFwiLFxuICAgIG1pbGxpc2Vjb25kOiBcIm1pbGxpc2Vjb25kXCIsXG4gICAgbWlsbGlzZWNvbmRzOiBcIm1pbGxpc2Vjb25kXCIsXG4gICAgd2Vla2RheTogXCJ3ZWVrZGF5XCIsXG4gICAgd2Vla2RheXM6IFwid2Vla2RheVwiLFxuICAgIHdlZWtudW1iZXI6IFwid2Vla051bWJlclwiLFxuICAgIHdlZWtzbnVtYmVyOiBcIndlZWtOdW1iZXJcIixcbiAgICB3ZWVrbnVtYmVyczogXCJ3ZWVrTnVtYmVyXCIsXG4gICAgd2Vla3llYXI6IFwid2Vla1llYXJcIixcbiAgICB3ZWVreWVhcnM6IFwid2Vla1llYXJcIixcbiAgICBvcmRpbmFsOiBcIm9yZGluYWxcIixcbiAgfVt1bml0LnRvTG93ZXJDYXNlKCldO1xuXG4gIGlmICghbm9ybWFsaXplZCkgdGhyb3cgbmV3IEludmFsaWRVbml0RXJyb3IodW5pdCk7XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWQ7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVVuaXRXaXRoTG9jYWxXZWVrcyh1bml0KSB7XG4gIHN3aXRjaCAodW5pdC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSBcImxvY2Fsd2Vla2RheVwiOlxuICAgIGNhc2UgXCJsb2NhbHdlZWtkYXlzXCI6XG4gICAgICByZXR1cm4gXCJsb2NhbFdlZWtkYXlcIjtcbiAgICBjYXNlIFwibG9jYWx3ZWVrbnVtYmVyXCI6XG4gICAgY2FzZSBcImxvY2Fsd2Vla251bWJlcnNcIjpcbiAgICAgIHJldHVybiBcImxvY2FsV2Vla051bWJlclwiO1xuICAgIGNhc2UgXCJsb2NhbHdlZWt5ZWFyXCI6XG4gICAgY2FzZSBcImxvY2Fsd2Vla3llYXJzXCI6XG4gICAgICByZXR1cm4gXCJsb2NhbFdlZWtZZWFyXCI7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBub3JtYWxpemVVbml0KHVuaXQpO1xuICB9XG59XG5cbi8vIHRoaXMgaXMgYSBkdW1iZWQgZG93biB2ZXJzaW9uIG9mIGZyb21PYmplY3QoKSB0aGF0IHJ1bnMgYWJvdXQgNjAlIGZhc3RlclxuLy8gYnV0IGRvZXNuJ3QgZG8gYW55IHZhbGlkYXRpb24sIG1ha2VzIGEgYnVuY2ggb2YgYXNzdW1wdGlvbnMgYWJvdXQgd2hhdCB1bml0c1xuLy8gYXJlIHByZXNlbnQsIGFuZCBzbyBvbi5cbmZ1bmN0aW9uIHF1aWNrRFQob2JqLCBvcHRzKSB7XG4gIGNvbnN0IHpvbmUgPSBub3JtYWxpemVab25lKG9wdHMuem9uZSwgU2V0dGluZ3MuZGVmYXVsdFpvbmUpLFxuICAgIGxvYyA9IExvY2FsZS5mcm9tT2JqZWN0KG9wdHMpLFxuICAgIHRzTm93ID0gU2V0dGluZ3Mubm93KCk7XG5cbiAgbGV0IHRzLCBvO1xuXG4gIC8vIGFzc3VtZSB3ZSBoYXZlIHRoZSBoaWdoZXItb3JkZXIgdW5pdHNcbiAgaWYgKCFpc1VuZGVmaW5lZChvYmoueWVhcikpIHtcbiAgICBmb3IgKGNvbnN0IHUgb2Ygb3JkZXJlZFVuaXRzKSB7XG4gICAgICBpZiAoaXNVbmRlZmluZWQob2JqW3VdKSkge1xuICAgICAgICBvYmpbdV0gPSBkZWZhdWx0VW5pdFZhbHVlc1t1XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBpbnZhbGlkID0gaGFzSW52YWxpZEdyZWdvcmlhbkRhdGEob2JqKSB8fCBoYXNJbnZhbGlkVGltZURhdGEob2JqKTtcbiAgICBpZiAoaW52YWxpZCkge1xuICAgICAgcmV0dXJuIERhdGVUaW1lLmludmFsaWQoaW52YWxpZCk7XG4gICAgfVxuXG4gICAgY29uc3Qgb2Zmc2V0UHJvdmlzID0gem9uZS5vZmZzZXQodHNOb3cpO1xuICAgIFt0cywgb10gPSBvYmpUb1RTKG9iaiwgb2Zmc2V0UHJvdmlzLCB6b25lKTtcbiAgfSBlbHNlIHtcbiAgICB0cyA9IHRzTm93O1xuICB9XG5cbiAgcmV0dXJuIG5ldyBEYXRlVGltZSh7IHRzLCB6b25lLCBsb2MsIG8gfSk7XG59XG5cbmZ1bmN0aW9uIGRpZmZSZWxhdGl2ZShzdGFydCwgZW5kLCBvcHRzKSB7XG4gIGNvbnN0IHJvdW5kID0gaXNVbmRlZmluZWQob3B0cy5yb3VuZCkgPyB0cnVlIDogb3B0cy5yb3VuZCxcbiAgICBmb3JtYXQgPSAoYywgdW5pdCkgPT4ge1xuICAgICAgYyA9IHJvdW5kVG8oYywgcm91bmQgfHwgb3B0cy5jYWxlbmRhcnkgPyAwIDogMiwgdHJ1ZSk7XG4gICAgICBjb25zdCBmb3JtYXR0ZXIgPSBlbmQubG9jLmNsb25lKG9wdHMpLnJlbEZvcm1hdHRlcihvcHRzKTtcbiAgICAgIHJldHVybiBmb3JtYXR0ZXIuZm9ybWF0KGMsIHVuaXQpO1xuICAgIH0sXG4gICAgZGlmZmVyID0gKHVuaXQpID0+IHtcbiAgICAgIGlmIChvcHRzLmNhbGVuZGFyeSkge1xuICAgICAgICBpZiAoIWVuZC5oYXNTYW1lKHN0YXJ0LCB1bml0KSkge1xuICAgICAgICAgIHJldHVybiBlbmQuc3RhcnRPZih1bml0KS5kaWZmKHN0YXJ0LnN0YXJ0T2YodW5pdCksIHVuaXQpLmdldCh1bml0KTtcbiAgICAgICAgfSBlbHNlIHJldHVybiAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGVuZC5kaWZmKHN0YXJ0LCB1bml0KS5nZXQodW5pdCk7XG4gICAgICB9XG4gICAgfTtcblxuICBpZiAob3B0cy51bml0KSB7XG4gICAgcmV0dXJuIGZvcm1hdChkaWZmZXIob3B0cy51bml0KSwgb3B0cy51bml0KTtcbiAgfVxuXG4gIGZvciAoY29uc3QgdW5pdCBvZiBvcHRzLnVuaXRzKSB7XG4gICAgY29uc3QgY291bnQgPSBkaWZmZXIodW5pdCk7XG4gICAgaWYgKE1hdGguYWJzKGNvdW50KSA+PSAxKSB7XG4gICAgICByZXR1cm4gZm9ybWF0KGNvdW50LCB1bml0KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZvcm1hdChzdGFydCA+IGVuZCA/IC0wIDogMCwgb3B0cy51bml0c1tvcHRzLnVuaXRzLmxlbmd0aCAtIDFdKTtcbn1cblxuZnVuY3Rpb24gbGFzdE9wdHMoYXJnTGlzdCkge1xuICBsZXQgb3B0cyA9IHt9LFxuICAgIGFyZ3M7XG4gIGlmIChhcmdMaXN0Lmxlbmd0aCA+IDAgJiYgdHlwZW9mIGFyZ0xpc3RbYXJnTGlzdC5sZW5ndGggLSAxXSA9PT0gXCJvYmplY3RcIikge1xuICAgIG9wdHMgPSBhcmdMaXN0W2FyZ0xpc3QubGVuZ3RoIC0gMV07XG4gICAgYXJncyA9IEFycmF5LmZyb20oYXJnTGlzdCkuc2xpY2UoMCwgYXJnTGlzdC5sZW5ndGggLSAxKTtcbiAgfSBlbHNlIHtcbiAgICBhcmdzID0gQXJyYXkuZnJvbShhcmdMaXN0KTtcbiAgfVxuICByZXR1cm4gW29wdHMsIGFyZ3NdO1xufVxuXG4vKipcbiAqIEEgRGF0ZVRpbWUgaXMgYW4gaW1tdXRhYmxlIGRhdGEgc3RydWN0dXJlIHJlcHJlc2VudGluZyBhIHNwZWNpZmljIGRhdGUgYW5kIHRpbWUgYW5kIGFjY29tcGFueWluZyBtZXRob2RzLiBJdCBjb250YWlucyBjbGFzcyBhbmQgaW5zdGFuY2UgbWV0aG9kcyBmb3IgY3JlYXRpbmcsIHBhcnNpbmcsIGludGVycm9nYXRpbmcsIHRyYW5zZm9ybWluZywgYW5kIGZvcm1hdHRpbmcgdGhlbS5cbiAqXG4gKiBBIERhdGVUaW1lIGNvbXByaXNlcyBvZjpcbiAqICogQSB0aW1lc3RhbXAuIEVhY2ggRGF0ZVRpbWUgaW5zdGFuY2UgcmVmZXJzIHRvIGEgc3BlY2lmaWMgbWlsbGlzZWNvbmQgb2YgdGhlIFVuaXggZXBvY2guXG4gKiAqIEEgdGltZSB6b25lLiBFYWNoIGluc3RhbmNlIGlzIGNvbnNpZGVyZWQgaW4gdGhlIGNvbnRleHQgb2YgYSBzcGVjaWZpYyB6b25lIChieSBkZWZhdWx0IHRoZSBsb2NhbCBzeXN0ZW0ncyB6b25lKS5cbiAqICogQ29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzIHRoYXQgZWZmZWN0IGhvdyBvdXRwdXQgc3RyaW5ncyBhcmUgZm9ybWF0dGVkLCBzdWNoIGFzIGBsb2NhbGVgLCBgbnVtYmVyaW5nU3lzdGVtYCwgYW5kIGBvdXRwdXRDYWxlbmRhcmAuXG4gKlxuICogSGVyZSBpcyBhIGJyaWVmIG92ZXJ2aWV3IG9mIHRoZSBtb3N0IGNvbW1vbmx5IHVzZWQgZnVuY3Rpb25hbGl0eSBpdCBwcm92aWRlczpcbiAqXG4gKiAqICoqQ3JlYXRpb24qKjogVG8gY3JlYXRlIGEgRGF0ZVRpbWUgZnJvbSBpdHMgY29tcG9uZW50cywgdXNlIG9uZSBvZiBpdHMgZmFjdG9yeSBjbGFzcyBtZXRob2RzOiB7QGxpbmsgRGF0ZVRpbWUubG9jYWx9LCB7QGxpbmsgRGF0ZVRpbWUudXRjfSwgYW5kIChtb3N0IGZsZXhpYmx5KSB7QGxpbmsgRGF0ZVRpbWUuZnJvbU9iamVjdH0uIFRvIGNyZWF0ZSBvbmUgZnJvbSBhIHN0YW5kYXJkIHN0cmluZyBmb3JtYXQsIHVzZSB7QGxpbmsgRGF0ZVRpbWUuZnJvbUlTT30sIHtAbGluayBEYXRlVGltZS5mcm9tSFRUUH0sIGFuZCB7QGxpbmsgRGF0ZVRpbWUuZnJvbVJGQzI4MjJ9LiBUbyBjcmVhdGUgb25lIGZyb20gYSBjdXN0b20gc3RyaW5nIGZvcm1hdCwgdXNlIHtAbGluayBEYXRlVGltZS5mcm9tRm9ybWF0fS4gVG8gY3JlYXRlIG9uZSBmcm9tIGEgbmF0aXZlIEpTIGRhdGUsIHVzZSB7QGxpbmsgRGF0ZVRpbWUuZnJvbUpTRGF0ZX0uXG4gKiAqICoqR3JlZ29yaWFuIGNhbGVuZGFyIGFuZCB0aW1lKio6IFRvIGV4YW1pbmUgdGhlIEdyZWdvcmlhbiBwcm9wZXJ0aWVzIG9mIGEgRGF0ZVRpbWUgaW5kaXZpZHVhbGx5IChpLmUgYXMgb3Bwb3NlZCB0byBjb2xsZWN0aXZlbHkgdGhyb3VnaCB7QGxpbmsgRGF0ZVRpbWUjdG9PYmplY3R9KSwgdXNlIHRoZSB7QGxpbmsgRGF0ZVRpbWUjeWVhcn0sIHtAbGluayBEYXRlVGltZSNtb250aH0sXG4gKiB7QGxpbmsgRGF0ZVRpbWUjZGF5fSwge0BsaW5rIERhdGVUaW1lI2hvdXJ9LCB7QGxpbmsgRGF0ZVRpbWUjbWludXRlfSwge0BsaW5rIERhdGVUaW1lI3NlY29uZH0sIHtAbGluayBEYXRlVGltZSNtaWxsaXNlY29uZH0gYWNjZXNzb3JzLlxuICogKiAqKldlZWsgY2FsZW5kYXIqKjogRm9yIElTTyB3ZWVrIGNhbGVuZGFyIGF0dHJpYnV0ZXMsIHNlZSB0aGUge0BsaW5rIERhdGVUaW1lI3dlZWtZZWFyfSwge0BsaW5rIERhdGVUaW1lI3dlZWtOdW1iZXJ9LCBhbmQge0BsaW5rIERhdGVUaW1lI3dlZWtkYXl9IGFjY2Vzc29ycy5cbiAqICogKipDb25maWd1cmF0aW9uKiogU2VlIHRoZSB7QGxpbmsgRGF0ZVRpbWUjbG9jYWxlfSBhbmQge0BsaW5rIERhdGVUaW1lI251bWJlcmluZ1N5c3RlbX0gYWNjZXNzb3JzLlxuICogKiAqKlRyYW5zZm9ybWF0aW9uKio6IFRvIHRyYW5zZm9ybSB0aGUgRGF0ZVRpbWUgaW50byBvdGhlciBEYXRlVGltZXMsIHVzZSB7QGxpbmsgRGF0ZVRpbWUjc2V0fSwge0BsaW5rIERhdGVUaW1lI3JlY29uZmlndXJlfSwge0BsaW5rIERhdGVUaW1lI3NldFpvbmV9LCB7QGxpbmsgRGF0ZVRpbWUjc2V0TG9jYWxlfSwge0BsaW5rIERhdGVUaW1lLnBsdXN9LCB7QGxpbmsgRGF0ZVRpbWUjbWludXN9LCB7QGxpbmsgRGF0ZVRpbWUjZW5kT2Z9LCB7QGxpbmsgRGF0ZVRpbWUjc3RhcnRPZn0sIHtAbGluayBEYXRlVGltZSN0b1VUQ30sIGFuZCB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbH0uXG4gKiAqICoqT3V0cHV0Kio6IFRvIGNvbnZlcnQgdGhlIERhdGVUaW1lIHRvIG90aGVyIHJlcHJlc2VudGF0aW9ucywgdXNlIHRoZSB7QGxpbmsgRGF0ZVRpbWUjdG9SZWxhdGl2ZX0sIHtAbGluayBEYXRlVGltZSN0b1JlbGF0aXZlQ2FsZW5kYXJ9LCB7QGxpbmsgRGF0ZVRpbWUjdG9KU09OfSwge0BsaW5rIERhdGVUaW1lI3RvSVNPfSwge0BsaW5rIERhdGVUaW1lI3RvSFRUUH0sIHtAbGluayBEYXRlVGltZSN0b09iamVjdH0sIHtAbGluayBEYXRlVGltZSN0b1JGQzI4MjJ9LCB7QGxpbmsgRGF0ZVRpbWUjdG9TdHJpbmd9LCB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9LCB7QGxpbmsgRGF0ZVRpbWUjdG9Gb3JtYXR9LCB7QGxpbmsgRGF0ZVRpbWUjdG9NaWxsaXN9IGFuZCB7QGxpbmsgRGF0ZVRpbWUjdG9KU0RhdGV9LlxuICpcbiAqIFRoZXJlJ3MgcGxlbnR5IG90aGVycyBkb2N1bWVudGVkIGJlbG93LiBJbiBhZGRpdGlvbiwgZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gc3VidGxlciB0b3BpY3MgbGlrZSBpbnRlcm5hdGlvbmFsaXphdGlvbiwgdGltZSB6b25lcywgYWx0ZXJuYXRpdmUgY2FsZW5kYXJzLCB2YWxpZGl0eSwgYW5kIHNvIG9uLCBzZWUgdGhlIGV4dGVybmFsIGRvY3VtZW50YXRpb24uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERhdGVUaW1lIHtcbiAgLyoqXG4gICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgKi9cbiAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgY29uc3Qgem9uZSA9IGNvbmZpZy56b25lIHx8IFNldHRpbmdzLmRlZmF1bHRab25lO1xuXG4gICAgbGV0IGludmFsaWQgPVxuICAgICAgY29uZmlnLmludmFsaWQgfHxcbiAgICAgIChOdW1iZXIuaXNOYU4oY29uZmlnLnRzKSA/IG5ldyBJbnZhbGlkKFwiaW52YWxpZCBpbnB1dFwiKSA6IG51bGwpIHx8XG4gICAgICAoIXpvbmUuaXNWYWxpZCA/IHVuc3VwcG9ydGVkWm9uZSh6b25lKSA6IG51bGwpO1xuICAgIC8qKlxuICAgICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMudHMgPSBpc1VuZGVmaW5lZChjb25maWcudHMpID8gU2V0dGluZ3Mubm93KCkgOiBjb25maWcudHM7XG5cbiAgICBsZXQgYyA9IG51bGwsXG4gICAgICBvID0gbnVsbDtcbiAgICBpZiAoIWludmFsaWQpIHtcbiAgICAgIGNvbnN0IHVuY2hhbmdlZCA9IGNvbmZpZy5vbGQgJiYgY29uZmlnLm9sZC50cyA9PT0gdGhpcy50cyAmJiBjb25maWcub2xkLnpvbmUuZXF1YWxzKHpvbmUpO1xuXG4gICAgICBpZiAodW5jaGFuZ2VkKSB7XG4gICAgICAgIFtjLCBvXSA9IFtjb25maWcub2xkLmMsIGNvbmZpZy5vbGQub107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBvdCA9IHpvbmUub2Zmc2V0KHRoaXMudHMpO1xuICAgICAgICBjID0gdHNUb09iaih0aGlzLnRzLCBvdCk7XG4gICAgICAgIGludmFsaWQgPSBOdW1iZXIuaXNOYU4oYy55ZWFyKSA/IG5ldyBJbnZhbGlkKFwiaW52YWxpZCBpbnB1dFwiKSA6IG51bGw7XG4gICAgICAgIGMgPSBpbnZhbGlkID8gbnVsbCA6IGM7XG4gICAgICAgIG8gPSBpbnZhbGlkID8gbnVsbCA6IG90O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMuX3pvbmUgPSB6b25lO1xuICAgIC8qKlxuICAgICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMubG9jID0gY29uZmlnLmxvYyB8fCBMb2NhbGUuY3JlYXRlKCk7XG4gICAgLyoqXG4gICAgICogQGFjY2VzcyBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5pbnZhbGlkID0gaW52YWxpZDtcbiAgICAvKipcbiAgICAgKiBAYWNjZXNzIHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLndlZWtEYXRhID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAYWNjZXNzIHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLmxvY2FsV2Vla0RhdGEgPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBhY2Nlc3MgcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMuYyA9IGM7XG4gICAgLyoqXG4gICAgICogQGFjY2VzcyBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5vID0gbztcbiAgICAvKipcbiAgICAgKiBAYWNjZXNzIHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLmlzTHV4b25EYXRlVGltZSA9IHRydWU7XG4gIH1cblxuICAvLyBDT05TVFJVQ1RcblxuICAvKipcbiAgICogQ3JlYXRlIGEgRGF0ZVRpbWUgZm9yIHRoZSBjdXJyZW50IGluc3RhbnQsIGluIHRoZSBzeXN0ZW0ncyB0aW1lIHpvbmUuXG4gICAqXG4gICAqIFVzZSBTZXR0aW5ncyB0byBvdmVycmlkZSB0aGVzZSBkZWZhdWx0IHZhbHVlcyBpZiBuZWVkZWQuXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnRvSVNPKCkgLy9+PiBub3cgaW4gdGhlIElTTyBmb3JtYXRcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGF0aWMgbm93KCkge1xuICAgIHJldHVybiBuZXcgRGF0ZVRpbWUoe30pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGxvY2FsIERhdGVUaW1lXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbeWVhcl0gLSBUaGUgY2FsZW5kYXIgeWVhci4gSWYgb21pdHRlZCAoYXMgaW4sIGNhbGwgYGxvY2FsKClgIHdpdGggbm8gYXJndW1lbnRzKSwgdGhlIGN1cnJlbnQgdGltZSB3aWxsIGJlIHVzZWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IFttb250aD0xXSAtIFRoZSBtb250aCwgMS1pbmRleGVkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbZGF5PTFdIC0gVGhlIGRheSBvZiB0aGUgbW9udGgsIDEtaW5kZXhlZFxuICAgKiBAcGFyYW0ge251bWJlcn0gW2hvdXI9MF0gLSBUaGUgaG91ciBvZiB0aGUgZGF5LCBpbiAyNC1ob3VyIHRpbWVcbiAgICogQHBhcmFtIHtudW1iZXJ9IFttaW51dGU9MF0gLSBUaGUgbWludXRlIG9mIHRoZSBob3VyLCBtZWFuaW5nIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgNTlcbiAgICogQHBhcmFtIHtudW1iZXJ9IFtzZWNvbmQ9MF0gLSBUaGUgc2Vjb25kIG9mIHRoZSBtaW51dGUsIG1lYW5pbmcgYSBudW1iZXIgYmV0d2VlbiAwIGFuZCA1OVxuICAgKiBAcGFyYW0ge251bWJlcn0gW21pbGxpc2Vjb25kPTBdIC0gVGhlIG1pbGxpc2Vjb25kIG9mIHRoZSBzZWNvbmQsIG1lYW5pbmcgYSBudW1iZXIgYmV0d2VlbiAwIGFuZCA5OTlcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL34+IG5vd1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCh7IHpvbmU6IFwiQW1lcmljYS9OZXdfWW9ya1wiIH0pICAgICAgLy9+PiBub3csIGluIFVTIGVhc3QgY29hc3QgdGltZVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE3KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vfj4gMjAxNy0wMS0wMVQwMDowMDowMFxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE3LCAzKSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vfj4gMjAxNy0wMy0wMVQwMDowMDowMFxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE3LCAzLCAxMiwgeyBsb2NhbGU6IFwiZnJcIiB9KSAgICAgLy9+PiAyMDE3LTAzLTEyVDAwOjAwOjAwLCB3aXRoIGEgRnJlbmNoIGxvY2FsZVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE3LCAzLCAxMiwgNSkgICAgICAgICAgICAgICAgICAgIC8vfj4gMjAxNy0wMy0xMlQwNTowMDowMFxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE3LCAzLCAxMiwgNSwgeyB6b25lOiBcInV0Y1wiIH0pICAgLy9+PiAyMDE3LTAzLTEyVDA1OjAwOjAwLCBpbiBVVENcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgMywgMTIsIDUsIDQ1KSAgICAgICAgICAgICAgICAvL34+IDIwMTctMDMtMTJUMDU6NDU6MDBcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgMywgMTIsIDUsIDQ1LCAxMCkgICAgICAgICAgICAvL34+IDIwMTctMDMtMTJUMDU6NDU6MTBcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgMywgMTIsIDUsIDQ1LCAxMCwgNzY1KSAgICAgICAvL34+IDIwMTctMDMtMTJUMDU6NDU6MTAuNzY1XG4gICAqIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgKi9cbiAgc3RhdGljIGxvY2FsKCkge1xuICAgIGNvbnN0IFtvcHRzLCBhcmdzXSA9IGxhc3RPcHRzKGFyZ3VtZW50cyksXG4gICAgICBbeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIG1pbGxpc2Vjb25kXSA9IGFyZ3M7XG4gICAgcmV0dXJuIHF1aWNrRFQoeyB5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmQgfSwgb3B0cyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRGF0ZVRpbWUgaW4gVVRDXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbeWVhcl0gLSBUaGUgY2FsZW5kYXIgeWVhci4gSWYgb21pdHRlZCAoYXMgaW4sIGNhbGwgYHV0YygpYCB3aXRoIG5vIGFyZ3VtZW50cyksIHRoZSBjdXJyZW50IHRpbWUgd2lsbCBiZSB1c2VkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbbW9udGg9MV0gLSBUaGUgbW9udGgsIDEtaW5kZXhlZFxuICAgKiBAcGFyYW0ge251bWJlcn0gW2RheT0xXSAtIFRoZSBkYXkgb2YgdGhlIG1vbnRoXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbaG91cj0wXSAtIFRoZSBob3VyIG9mIHRoZSBkYXksIGluIDI0LWhvdXIgdGltZVxuICAgKiBAcGFyYW0ge251bWJlcn0gW21pbnV0ZT0wXSAtIFRoZSBtaW51dGUgb2YgdGhlIGhvdXIsIG1lYW5pbmcgYSBudW1iZXIgYmV0d2VlbiAwIGFuZCA1OVxuICAgKiBAcGFyYW0ge251bWJlcn0gW3NlY29uZD0wXSAtIFRoZSBzZWNvbmQgb2YgdGhlIG1pbnV0ZSwgbWVhbmluZyBhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDU5XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbbWlsbGlzZWNvbmQ9MF0gLSBUaGUgbWlsbGlzZWNvbmQgb2YgdGhlIHNlY29uZCwgbWVhbmluZyBhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDk5OVxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIERhdGVUaW1lXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5sb2NhbGVdIC0gYSBsb2NhbGUgdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLm91dHB1dENhbGVuZGFyXSAtIHRoZSBvdXRwdXQgY2FsZW5kYXIgdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLm51bWJlcmluZ1N5c3RlbV0gLSB0aGUgbnVtYmVyaW5nIHN5c3RlbSB0byBzZXQgb24gdGhlIHJlc3VsdGluZyBEYXRlVGltZSBpbnN0YW5jZVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS51dGMoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL34+IG5vd1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS51dGMoMjAxNykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL34+IDIwMTctMDEtMDFUMDA6MDA6MDBaXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygyMDE3LCAzKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vfj4gMjAxNy0wMy0wMVQwMDowMDowMFpcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUudXRjKDIwMTcsIDMsIDEyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9+PiAyMDE3LTAzLTEyVDAwOjAwOjAwWlxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS51dGMoMjAxNywgMywgMTIsIDUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL34+IDIwMTctMDMtMTJUMDU6MDA6MDBaXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygyMDE3LCAzLCAxMiwgNSwgNDUpICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vfj4gMjAxNy0wMy0xMlQwNTo0NTowMFpcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUudXRjKDIwMTcsIDMsIDEyLCA1LCA0NSwgeyBsb2NhbGU6IFwiZnJcIiB9KSAgICAgICAgICAvL34+IDIwMTctMDMtMTJUMDU6NDU6MDBaIHdpdGggYSBGcmVuY2ggbG9jYWxlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygyMDE3LCAzLCAxMiwgNSwgNDUsIDEwKSAgICAgICAgICAgICAgICAgICAgICAgIC8vfj4gMjAxNy0wMy0xMlQwNTo0NToxMFpcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUudXRjKDIwMTcsIDMsIDEyLCA1LCA0NSwgMTAsIDc2NSwgeyBsb2NhbGU6IFwiZnJcIiB9KSAvL34+IDIwMTctMDMtMTJUMDU6NDU6MTAuNzY1WiB3aXRoIGEgRnJlbmNoIGxvY2FsZVxuICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICovXG4gIHN0YXRpYyB1dGMoKSB7XG4gICAgY29uc3QgW29wdHMsIGFyZ3NdID0gbGFzdE9wdHMoYXJndW1lbnRzKSxcbiAgICAgIFt5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmRdID0gYXJncztcblxuICAgIG9wdHMuem9uZSA9IEZpeGVkT2Zmc2V0Wm9uZS51dGNJbnN0YW5jZTtcbiAgICByZXR1cm4gcXVpY2tEVCh7IHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBtaWxsaXNlY29uZCB9LCBvcHRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBEYXRlVGltZSBmcm9tIGEgSmF2YVNjcmlwdCBEYXRlIG9iamVjdC4gVXNlcyB0aGUgZGVmYXVsdCB6b25lLlxuICAgKiBAcGFyYW0ge0RhdGV9IGRhdGUgLSBhIEphdmFTY3JpcHQgRGF0ZSBvYmplY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBjb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHRoZSBEYXRlVGltZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xab25lfSBbb3B0aW9ucy56b25lPSdsb2NhbCddIC0gdGhlIHpvbmUgdG8gcGxhY2UgdGhlIERhdGVUaW1lIGludG9cbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGF0aWMgZnJvbUpTRGF0ZShkYXRlLCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB0cyA9IGlzRGF0ZShkYXRlKSA/IGRhdGUudmFsdWVPZigpIDogTmFOO1xuICAgIGlmIChOdW1iZXIuaXNOYU4odHMpKSB7XG4gICAgICByZXR1cm4gRGF0ZVRpbWUuaW52YWxpZChcImludmFsaWQgaW5wdXRcIik7XG4gICAgfVxuXG4gICAgY29uc3Qgem9uZVRvVXNlID0gbm9ybWFsaXplWm9uZShvcHRpb25zLnpvbmUsIFNldHRpbmdzLmRlZmF1bHRab25lKTtcbiAgICBpZiAoIXpvbmVUb1VzZS5pc1ZhbGlkKSB7XG4gICAgICByZXR1cm4gRGF0ZVRpbWUuaW52YWxpZCh1bnN1cHBvcnRlZFpvbmUoem9uZVRvVXNlKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBEYXRlVGltZSh7XG4gICAgICB0czogdHMsXG4gICAgICB6b25lOiB6b25lVG9Vc2UsXG4gICAgICBsb2M6IExvY2FsZS5mcm9tT2JqZWN0KG9wdGlvbnMpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIERhdGVUaW1lIGZyb20gYSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHNpbmNlIHRoZSBlcG9jaCAobWVhbmluZyBzaW5jZSAxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVEMpLiBVc2VzIHRoZSBkZWZhdWx0IHpvbmUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtaWxsaXNlY29uZHMgLSBhIG51bWJlciBvZiBtaWxsaXNlY29uZHMgc2luY2UgMTk3MCBVVENcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBjb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHRoZSBEYXRlVGltZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xab25lfSBbb3B0aW9ucy56b25lPSdsb2NhbCddIC0gdGhlIHpvbmUgdG8gcGxhY2UgdGhlIERhdGVUaW1lIGludG9cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmxvY2FsZV0gLSBhIGxvY2FsZSB0byBzZXQgb24gdGhlIHJlc3VsdGluZyBEYXRlVGltZSBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5vdXRwdXRDYWxlbmRhciAtIHRoZSBvdXRwdXQgY2FsZW5kYXIgdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMubnVtYmVyaW5nU3lzdGVtIC0gdGhlIG51bWJlcmluZyBzeXN0ZW0gdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGF0aWMgZnJvbU1pbGxpcyhtaWxsaXNlY29uZHMsIG9wdGlvbnMgPSB7fSkge1xuICAgIGlmICghaXNOdW1iZXIobWlsbGlzZWNvbmRzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKFxuICAgICAgICBgZnJvbU1pbGxpcyByZXF1aXJlcyBhIG51bWVyaWNhbCBpbnB1dCwgYnV0IHJlY2VpdmVkIGEgJHt0eXBlb2YgbWlsbGlzZWNvbmRzfSB3aXRoIHZhbHVlICR7bWlsbGlzZWNvbmRzfWBcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChtaWxsaXNlY29uZHMgPCAtTUFYX0RBVEUgfHwgbWlsbGlzZWNvbmRzID4gTUFYX0RBVEUpIHtcbiAgICAgIC8vIHRoaXMgaXNuJ3QgcGVyZmVjdCBiZWNhdXNlIGJlY2F1c2Ugd2UgY2FuIHN0aWxsIGVuZCB1cCBvdXQgb2YgcmFuZ2UgYmVjYXVzZSBvZiBhZGRpdGlvbmFsIHNoaWZ0aW5nLCBidXQgaXQncyBhIHN0YXJ0XG4gICAgICByZXR1cm4gRGF0ZVRpbWUuaW52YWxpZChcIlRpbWVzdGFtcCBvdXQgb2YgcmFuZ2VcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgRGF0ZVRpbWUoe1xuICAgICAgICB0czogbWlsbGlzZWNvbmRzLFxuICAgICAgICB6b25lOiBub3JtYWxpemVab25lKG9wdGlvbnMuem9uZSwgU2V0dGluZ3MuZGVmYXVsdFpvbmUpLFxuICAgICAgICBsb2M6IExvY2FsZS5mcm9tT2JqZWN0KG9wdGlvbnMpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIERhdGVUaW1lIGZyb20gYSBudW1iZXIgb2Ygc2Vjb25kcyBzaW5jZSB0aGUgZXBvY2ggKG1lYW5pbmcgc2luY2UgMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKS4gVXNlcyB0aGUgZGVmYXVsdCB6b25lLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc2Vjb25kcyAtIGEgbnVtYmVyIG9mIHNlY29uZHMgc2luY2UgMTk3MCBVVENcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBjb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHRoZSBEYXRlVGltZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xab25lfSBbb3B0aW9ucy56b25lPSdsb2NhbCddIC0gdGhlIHpvbmUgdG8gcGxhY2UgdGhlIERhdGVUaW1lIGludG9cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLmxvY2FsZV0gLSBhIGxvY2FsZSB0byBzZXQgb24gdGhlIHJlc3VsdGluZyBEYXRlVGltZSBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5vdXRwdXRDYWxlbmRhciAtIHRoZSBvdXRwdXQgY2FsZW5kYXIgdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMubnVtYmVyaW5nU3lzdGVtIC0gdGhlIG51bWJlcmluZyBzeXN0ZW0gdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGF0aWMgZnJvbVNlY29uZHMoc2Vjb25kcywgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCFpc051bWJlcihzZWNvbmRzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKFwiZnJvbVNlY29uZHMgcmVxdWlyZXMgYSBudW1lcmljYWwgaW5wdXRcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgRGF0ZVRpbWUoe1xuICAgICAgICB0czogc2Vjb25kcyAqIDEwMDAsXG4gICAgICAgIHpvbmU6IG5vcm1hbGl6ZVpvbmUob3B0aW9ucy56b25lLCBTZXR0aW5ncy5kZWZhdWx0Wm9uZSksXG4gICAgICAgIGxvYzogTG9jYWxlLmZyb21PYmplY3Qob3B0aW9ucyksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRGF0ZVRpbWUgZnJvbSBhIEphdmFTY3JpcHQgb2JqZWN0IHdpdGgga2V5cyBsaWtlICd5ZWFyJyBhbmQgJ2hvdXInIHdpdGggcmVhc29uYWJsZSBkZWZhdWx0cy5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iaiAtIHRoZSBvYmplY3QgdG8gY3JlYXRlIHRoZSBEYXRlVGltZSBmcm9tXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoueWVhciAtIGEgeWVhciwgc3VjaCBhcyAxOTg3XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoubW9udGggLSBhIG1vbnRoLCAxLTEyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmouZGF5IC0gYSBkYXkgb2YgdGhlIG1vbnRoLCAxLTMxLCBkZXBlbmRpbmcgb24gdGhlIG1vbnRoXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoub3JkaW5hbCAtIGRheSBvZiB0aGUgeWVhciwgMS0zNjUgb3IgMzY2XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoud2Vla1llYXIgLSBhbiBJU08gd2VlayB5ZWFyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoud2Vla051bWJlciAtIGFuIElTTyB3ZWVrIG51bWJlciwgYmV0d2VlbiAxIGFuZCA1MiBvciA1MywgZGVwZW5kaW5nIG9uIHRoZSB5ZWFyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoud2Vla2RheSAtIGFuIElTTyB3ZWVrZGF5LCAxLTcsIHdoZXJlIDEgaXMgTW9uZGF5IGFuZCA3IGlzIFN1bmRheVxuICAgKiBAcGFyYW0ge251bWJlcn0gb2JqLmxvY2FsV2Vla1llYXIgLSBhIHdlZWsgeWVhciwgYWNjb3JkaW5nIHRvIHRoZSBsb2NhbGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9iai5sb2NhbFdlZWtOdW1iZXIgLSBhIHdlZWsgbnVtYmVyLCBiZXR3ZWVuIDEgYW5kIDUyIG9yIDUzLCBkZXBlbmRpbmcgb24gdGhlIHllYXIsIGFjY29yZGluZyB0byB0aGUgbG9jYWxlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoubG9jYWxXZWVrZGF5IC0gYSB3ZWVrZGF5LCAxLTcsIHdoZXJlIDEgaXMgdGhlIGZpcnN0IGFuZCA3IGlzIHRoZSBsYXN0IGRheSBvZiB0aGUgd2VlaywgYWNjb3JkaW5nIHRvIHRoZSBsb2NhbGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9iai5ob3VyIC0gaG91ciBvZiB0aGUgZGF5LCAwLTIzXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmoubWludXRlIC0gbWludXRlIG9mIHRoZSBob3VyLCAwLTU5XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYmouc2Vjb25kIC0gc2Vjb25kIG9mIHRoZSBtaW51dGUsIDAtNTlcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9iai5taWxsaXNlY29uZCAtIG1pbGxpc2Vjb25kIG9mIHRoZSBzZWNvbmQsIDAtOTk5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0aW9ucyBmb3IgY3JlYXRpbmcgdGhpcyBEYXRlVGltZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xab25lfSBbb3B0cy56b25lPSdsb2NhbCddIC0gaW50ZXJwcmV0IHRoZSBudW1iZXJzIGluIHRoZSBjb250ZXh0IG9mIGEgcGFydGljdWxhciB6b25lLiBDYW4gdGFrZSBhbnkgdmFsdWUgdGFrZW4gYXMgdGhlIGZpcnN0IGFyZ3VtZW50IHRvIHNldFpvbmUoKVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubG9jYWxlPSdzeXN0ZW1cXCdzIGxvY2FsZSddIC0gYSBsb2NhbGUgdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wdHMub3V0cHV0Q2FsZW5kYXIgLSB0aGUgb3V0cHV0IGNhbGVuZGFyIHRvIHNldCBvbiB0aGUgcmVzdWx0aW5nIERhdGVUaW1lIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLm51bWJlcmluZ1N5c3RlbSAtIHRoZSBudW1iZXJpbmcgc3lzdGVtIHRvIHNldCBvbiB0aGUgcmVzdWx0aW5nIERhdGVUaW1lIGluc3RhbmNlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21PYmplY3QoeyB5ZWFyOiAxOTgyLCBtb250aDogNSwgZGF5OiAyNX0pLnRvSVNPRGF0ZSgpIC8vPT4gJzE5ODItMDUtMjUnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21PYmplY3QoeyB5ZWFyOiAxOTgyIH0pLnRvSVNPRGF0ZSgpIC8vPT4gJzE5ODItMDEtMDEnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21PYmplY3QoeyBob3VyOiAxMCwgbWludXRlOiAyNiwgc2Vjb25kOiA2IH0pIC8vfj4gdG9kYXkgYXQgMTA6MjY6MDZcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUuZnJvbU9iamVjdCh7IGhvdXI6IDEwLCBtaW51dGU6IDI2LCBzZWNvbmQ6IDYgfSwgeyB6b25lOiAndXRjJyB9KSxcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUuZnJvbU9iamVjdCh7IGhvdXI6IDEwLCBtaW51dGU6IDI2LCBzZWNvbmQ6IDYgfSwgeyB6b25lOiAnbG9jYWwnIH0pXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21PYmplY3QoeyBob3VyOiAxMCwgbWludXRlOiAyNiwgc2Vjb25kOiA2IH0sIHsgem9uZTogJ0FtZXJpY2EvTmV3X1lvcmsnIH0pXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21PYmplY3QoeyB3ZWVrWWVhcjogMjAxNiwgd2Vla051bWJlcjogMiwgd2Vla2RheTogMyB9KS50b0lTT0RhdGUoKSAvLz0+ICcyMDE2LTAxLTEzJ1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5mcm9tT2JqZWN0KHsgbG9jYWxXZWVrWWVhcjogMjAyMiwgbG9jYWxXZWVrTnVtYmVyOiAxLCBsb2NhbFdlZWtkYXk6IDEgfSwgeyBsb2NhbGU6IFwiZW4tVVNcIiB9KS50b0lTT0RhdGUoKSAvLz0+ICcyMDIxLTEyLTI2J1xuICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICovXG4gIHN0YXRpYyBmcm9tT2JqZWN0KG9iaiwgb3B0cyA9IHt9KSB7XG4gICAgb2JqID0gb2JqIHx8IHt9O1xuICAgIGNvbnN0IHpvbmVUb1VzZSA9IG5vcm1hbGl6ZVpvbmUob3B0cy56b25lLCBTZXR0aW5ncy5kZWZhdWx0Wm9uZSk7XG4gICAgaWYgKCF6b25lVG9Vc2UuaXNWYWxpZCkge1xuICAgICAgcmV0dXJuIERhdGVUaW1lLmludmFsaWQodW5zdXBwb3J0ZWRab25lKHpvbmVUb1VzZSkpO1xuICAgIH1cblxuICAgIGNvbnN0IGxvYyA9IExvY2FsZS5mcm9tT2JqZWN0KG9wdHMpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVPYmplY3Qob2JqLCBub3JtYWxpemVVbml0V2l0aExvY2FsV2Vla3MpO1xuICAgIGNvbnN0IHsgbWluRGF5c0luRmlyc3RXZWVrLCBzdGFydE9mV2VlayB9ID0gdXNlc0xvY2FsV2Vla1ZhbHVlcyhub3JtYWxpemVkLCBsb2MpO1xuXG4gICAgY29uc3QgdHNOb3cgPSBTZXR0aW5ncy5ub3coKSxcbiAgICAgIG9mZnNldFByb3ZpcyA9ICFpc1VuZGVmaW5lZChvcHRzLnNwZWNpZmljT2Zmc2V0KVxuICAgICAgICA/IG9wdHMuc3BlY2lmaWNPZmZzZXRcbiAgICAgICAgOiB6b25lVG9Vc2Uub2Zmc2V0KHRzTm93KSxcbiAgICAgIGNvbnRhaW5zT3JkaW5hbCA9ICFpc1VuZGVmaW5lZChub3JtYWxpemVkLm9yZGluYWwpLFxuICAgICAgY29udGFpbnNHcmVnb3JZZWFyID0gIWlzVW5kZWZpbmVkKG5vcm1hbGl6ZWQueWVhciksXG4gICAgICBjb250YWluc0dyZWdvck1EID0gIWlzVW5kZWZpbmVkKG5vcm1hbGl6ZWQubW9udGgpIHx8ICFpc1VuZGVmaW5lZChub3JtYWxpemVkLmRheSksXG4gICAgICBjb250YWluc0dyZWdvciA9IGNvbnRhaW5zR3JlZ29yWWVhciB8fCBjb250YWluc0dyZWdvck1ELFxuICAgICAgZGVmaW5pdGVXZWVrRGVmID0gbm9ybWFsaXplZC53ZWVrWWVhciB8fCBub3JtYWxpemVkLndlZWtOdW1iZXI7XG5cbiAgICAvLyBjYXNlczpcbiAgICAvLyBqdXN0IGEgd2Vla2RheSAtPiB0aGlzIHdlZWsncyBpbnN0YW5jZSBvZiB0aGF0IHdlZWtkYXksIG5vIHdvcnJpZXNcbiAgICAvLyAoZ3JlZ29yaWFuIGRhdGEgb3Igb3JkaW5hbCkgKyAod2Vla1llYXIgb3Igd2Vla051bWJlcikgLT4gZXJyb3JcbiAgICAvLyAoZ3JlZ29yaWFuIG1vbnRoIG9yIGRheSkgKyBvcmRpbmFsIC0+IGVycm9yXG4gICAgLy8gb3RoZXJ3aXNlIGp1c3QgdXNlIHdlZWtzIG9yIG9yZGluYWxzIG9yIGdyZWdvcmlhbiwgZGVwZW5kaW5nIG9uIHdoYXQncyBzcGVjaWZpZWRcblxuICAgIGlmICgoY29udGFpbnNHcmVnb3IgfHwgY29udGFpbnNPcmRpbmFsKSAmJiBkZWZpbml0ZVdlZWtEZWYpIHtcbiAgICAgIHRocm93IG5ldyBDb25mbGljdGluZ1NwZWNpZmljYXRpb25FcnJvcihcbiAgICAgICAgXCJDYW4ndCBtaXggd2Vla1llYXIvd2Vla051bWJlciB1bml0cyB3aXRoIHllYXIvbW9udGgvZGF5IG9yIG9yZGluYWxzXCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRhaW5zR3JlZ29yTUQgJiYgY29udGFpbnNPcmRpbmFsKSB7XG4gICAgICB0aHJvdyBuZXcgQ29uZmxpY3RpbmdTcGVjaWZpY2F0aW9uRXJyb3IoXCJDYW4ndCBtaXggb3JkaW5hbCBkYXRlcyB3aXRoIG1vbnRoL2RheVwiKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VXZWVrRGF0YSA9IGRlZmluaXRlV2Vla0RlZiB8fCAobm9ybWFsaXplZC53ZWVrZGF5ICYmICFjb250YWluc0dyZWdvcik7XG5cbiAgICAvLyBjb25maWd1cmUgb3Vyc2VsdmVzIHRvIGRlYWwgd2l0aCBncmVnb3JpYW4gZGF0ZXMgb3Igd2VlayBzdHVmZlxuICAgIGxldCB1bml0cyxcbiAgICAgIGRlZmF1bHRWYWx1ZXMsXG4gICAgICBvYmpOb3cgPSB0c1RvT2JqKHRzTm93LCBvZmZzZXRQcm92aXMpO1xuICAgIGlmICh1c2VXZWVrRGF0YSkge1xuICAgICAgdW5pdHMgPSBvcmRlcmVkV2Vla1VuaXRzO1xuICAgICAgZGVmYXVsdFZhbHVlcyA9IGRlZmF1bHRXZWVrVW5pdFZhbHVlcztcbiAgICAgIG9iak5vdyA9IGdyZWdvcmlhblRvV2VlayhvYmpOb3csIG1pbkRheXNJbkZpcnN0V2Vlaywgc3RhcnRPZldlZWspO1xuICAgIH0gZWxzZSBpZiAoY29udGFpbnNPcmRpbmFsKSB7XG4gICAgICB1bml0cyA9IG9yZGVyZWRPcmRpbmFsVW5pdHM7XG4gICAgICBkZWZhdWx0VmFsdWVzID0gZGVmYXVsdE9yZGluYWxVbml0VmFsdWVzO1xuICAgICAgb2JqTm93ID0gZ3JlZ29yaWFuVG9PcmRpbmFsKG9iak5vdyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuaXRzID0gb3JkZXJlZFVuaXRzO1xuICAgICAgZGVmYXVsdFZhbHVlcyA9IGRlZmF1bHRVbml0VmFsdWVzO1xuICAgIH1cblxuICAgIC8vIHNldCBkZWZhdWx0IHZhbHVlcyBmb3IgbWlzc2luZyBzdHVmZlxuICAgIGxldCBmb3VuZEZpcnN0ID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCB1IG9mIHVuaXRzKSB7XG4gICAgICBjb25zdCB2ID0gbm9ybWFsaXplZFt1XTtcbiAgICAgIGlmICghaXNVbmRlZmluZWQodikpIHtcbiAgICAgICAgZm91bmRGaXJzdCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGZvdW5kRmlyc3QpIHtcbiAgICAgICAgbm9ybWFsaXplZFt1XSA9IGRlZmF1bHRWYWx1ZXNbdV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub3JtYWxpemVkW3VdID0gb2JqTm93W3VdO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGUgdmFsdWVzIHdlIGhhdmUgYXJlIGluIHJhbmdlXG4gICAgY29uc3QgaGlnaGVyT3JkZXJJbnZhbGlkID0gdXNlV2Vla0RhdGFcbiAgICAgICAgPyBoYXNJbnZhbGlkV2Vla0RhdGEobm9ybWFsaXplZCwgbWluRGF5c0luRmlyc3RXZWVrLCBzdGFydE9mV2VlaylcbiAgICAgICAgOiBjb250YWluc09yZGluYWxcbiAgICAgICAgPyBoYXNJbnZhbGlkT3JkaW5hbERhdGEobm9ybWFsaXplZClcbiAgICAgICAgOiBoYXNJbnZhbGlkR3JlZ29yaWFuRGF0YShub3JtYWxpemVkKSxcbiAgICAgIGludmFsaWQgPSBoaWdoZXJPcmRlckludmFsaWQgfHwgaGFzSW52YWxpZFRpbWVEYXRhKG5vcm1hbGl6ZWQpO1xuXG4gICAgaWYgKGludmFsaWQpIHtcbiAgICAgIHJldHVybiBEYXRlVGltZS5pbnZhbGlkKGludmFsaWQpO1xuICAgIH1cblxuICAgIC8vIGNvbXB1dGUgdGhlIGFjdHVhbCB0aW1lXG4gICAgY29uc3QgZ3JlZ29yaWFuID0gdXNlV2Vla0RhdGFcbiAgICAgICAgPyB3ZWVrVG9HcmVnb3JpYW4obm9ybWFsaXplZCwgbWluRGF5c0luRmlyc3RXZWVrLCBzdGFydE9mV2VlaylcbiAgICAgICAgOiBjb250YWluc09yZGluYWxcbiAgICAgICAgPyBvcmRpbmFsVG9HcmVnb3JpYW4obm9ybWFsaXplZClcbiAgICAgICAgOiBub3JtYWxpemVkLFxuICAgICAgW3RzRmluYWwsIG9mZnNldEZpbmFsXSA9IG9ialRvVFMoZ3JlZ29yaWFuLCBvZmZzZXRQcm92aXMsIHpvbmVUb1VzZSksXG4gICAgICBpbnN0ID0gbmV3IERhdGVUaW1lKHtcbiAgICAgICAgdHM6IHRzRmluYWwsXG4gICAgICAgIHpvbmU6IHpvbmVUb1VzZSxcbiAgICAgICAgbzogb2Zmc2V0RmluYWwsXG4gICAgICAgIGxvYyxcbiAgICAgIH0pO1xuXG4gICAgLy8gZ3JlZ29yaWFuIGRhdGEgKyB3ZWVrZGF5IHNlcnZlcyBvbmx5IHRvIHZhbGlkYXRlXG4gICAgaWYgKG5vcm1hbGl6ZWQud2Vla2RheSAmJiBjb250YWluc0dyZWdvciAmJiBvYmoud2Vla2RheSAhPT0gaW5zdC53ZWVrZGF5KSB7XG4gICAgICByZXR1cm4gRGF0ZVRpbWUuaW52YWxpZChcbiAgICAgICAgXCJtaXNtYXRjaGVkIHdlZWtkYXlcIixcbiAgICAgICAgYHlvdSBjYW4ndCBzcGVjaWZ5IGJvdGggYSB3ZWVrZGF5IG9mICR7bm9ybWFsaXplZC53ZWVrZGF5fSBhbmQgYSBkYXRlIG9mICR7aW5zdC50b0lTTygpfWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGluc3Q7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRGF0ZVRpbWUgZnJvbSBhbiBJU08gODYwMSBzdHJpbmdcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSB0aGUgSVNPIHN0cmluZ1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnMgdG8gYWZmZWN0IHRoZSBjcmVhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ3xab25lfSBbb3B0cy56b25lPSdsb2NhbCddIC0gdXNlIHRoaXMgem9uZSBpZiBubyBvZmZzZXQgaXMgc3BlY2lmaWVkIGluIHRoZSBpbnB1dCBzdHJpbmcgaXRzZWxmLiBXaWxsIGFsc28gY29udmVydCB0aGUgdGltZSB0byB0aGlzIHpvbmVcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5zZXRab25lPWZhbHNlXSAtIG92ZXJyaWRlIHRoZSB6b25lIHdpdGggYSBmaXhlZC1vZmZzZXQgem9uZSBzcGVjaWZpZWQgaW4gdGhlIHN0cmluZyBpdHNlbGYsIGlmIGl0IHNwZWNpZmllcyBvbmVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY2FsZT0nc3lzdGVtJ3MgbG9jYWxlJ10gLSBhIGxvY2FsZSB0byBzZXQgb24gdGhlIHJlc3VsdGluZyBEYXRlVGltZSBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMub3V0cHV0Q2FsZW5kYXJdIC0gdGhlIG91dHB1dCBjYWxlbmRhciB0byBzZXQgb24gdGhlIHJlc3VsdGluZyBEYXRlVGltZSBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMubnVtYmVyaW5nU3lzdGVtXSAtIHRoZSBudW1iZXJpbmcgc3lzdGVtIHRvIHNldCBvbiB0aGUgcmVzdWx0aW5nIERhdGVUaW1lIGluc3RhbmNlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21JU08oJzIwMTYtMDUtMjVUMDk6MDg6MzQuMTIzJylcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUuZnJvbUlTTygnMjAxNi0wNS0yNVQwOTowODozNC4xMjMrMDY6MDAnKVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5mcm9tSVNPKCcyMDE2LTA1LTI1VDA5OjA4OjM0LjEyMyswNjowMCcsIHtzZXRab25lOiB0cnVlfSlcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUuZnJvbUlTTygnMjAxNi0wNS0yNVQwOTowODozNC4xMjMnLCB7em9uZTogJ3V0Yyd9KVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5mcm9tSVNPKCcyMDE2LVcwNS00JylcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGF0aWMgZnJvbUlTTyh0ZXh0LCBvcHRzID0ge30pIHtcbiAgICBjb25zdCBbdmFscywgcGFyc2VkWm9uZV0gPSBwYXJzZUlTT0RhdGUodGV4dCk7XG4gICAgcmV0dXJuIHBhcnNlRGF0YVRvRGF0ZVRpbWUodmFscywgcGFyc2VkWm9uZSwgb3B0cywgXCJJU08gODYwMVwiLCB0ZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBEYXRlVGltZSBmcm9tIGFuIFJGQyAyODIyIHN0cmluZ1xuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIHRoZSBSRkMgMjgyMiBzdHJpbmdcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zIHRvIGFmZmVjdCB0aGUgY3JlYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd8Wm9uZX0gW29wdHMuem9uZT0nbG9jYWwnXSAtIGNvbnZlcnQgdGhlIHRpbWUgdG8gdGhpcyB6b25lLiBTaW5jZSB0aGUgb2Zmc2V0IGlzIGFsd2F5cyBzcGVjaWZpZWQgaW4gdGhlIHN0cmluZyBpdHNlbGYsIHRoaXMgaGFzIG5vIGVmZmVjdCBvbiB0aGUgaW50ZXJwcmV0YXRpb24gb2Ygc3RyaW5nLCBtZXJlbHkgdGhlIHpvbmUgdGhlIHJlc3VsdGluZyBEYXRlVGltZSBpcyBleHByZXNzZWQgaW4uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuc2V0Wm9uZT1mYWxzZV0gLSBvdmVycmlkZSB0aGUgem9uZSB3aXRoIGEgZml4ZWQtb2Zmc2V0IHpvbmUgc3BlY2lmaWVkIGluIHRoZSBzdHJpbmcgaXRzZWxmLCBpZiBpdCBzcGVjaWZpZXMgb25lXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5sb2NhbGU9J3N5c3RlbSdzIGxvY2FsZSddIC0gYSBsb2NhbGUgdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wdHMub3V0cHV0Q2FsZW5kYXIgLSB0aGUgb3V0cHV0IGNhbGVuZGFyIHRvIHNldCBvbiB0aGUgcmVzdWx0aW5nIERhdGVUaW1lIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLm51bWJlcmluZ1N5c3RlbSAtIHRoZSBudW1iZXJpbmcgc3lzdGVtIHRvIHNldCBvbiB0aGUgcmVzdWx0aW5nIERhdGVUaW1lIGluc3RhbmNlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21SRkMyODIyKCcyNSBOb3YgMjAxNiAxMzoyMzoxMiBHTVQnKVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5mcm9tUkZDMjgyMignRnJpLCAyNSBOb3YgMjAxNiAxMzoyMzoxMiArMDYwMCcpXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21SRkMyODIyKCcyNSBOb3YgMjAxNiAxMzoyMyBaJylcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGF0aWMgZnJvbVJGQzI4MjIodGV4dCwgb3B0cyA9IHt9KSB7XG4gICAgY29uc3QgW3ZhbHMsIHBhcnNlZFpvbmVdID0gcGFyc2VSRkMyODIyRGF0ZSh0ZXh0KTtcbiAgICByZXR1cm4gcGFyc2VEYXRhVG9EYXRlVGltZSh2YWxzLCBwYXJzZWRab25lLCBvcHRzLCBcIlJGQyAyODIyXCIsIHRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIERhdGVUaW1lIGZyb20gYW4gSFRUUCBoZWFkZXIgZGF0ZVxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9Qcm90b2NvbHMvcmZjMjYxNi9yZmMyNjE2LXNlYzMuaHRtbCNzZWMzLjMuMVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIHRoZSBIVFRQIGhlYWRlciBkYXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0aW9ucyB0byBhZmZlY3QgdGhlIGNyZWF0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfFpvbmV9IFtvcHRzLnpvbmU9J2xvY2FsJ10gLSBjb252ZXJ0IHRoZSB0aW1lIHRvIHRoaXMgem9uZS4gU2luY2UgSFRUUCBkYXRlcyBhcmUgYWx3YXlzIGluIFVUQywgdGhpcyBoYXMgbm8gZWZmZWN0IG9uIHRoZSBpbnRlcnByZXRhdGlvbiBvZiBzdHJpbmcsIG1lcmVseSB0aGUgem9uZSB0aGUgcmVzdWx0aW5nIERhdGVUaW1lIGlzIGV4cHJlc3NlZCBpbi5cbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5zZXRab25lPWZhbHNlXSAtIG92ZXJyaWRlIHRoZSB6b25lIHdpdGggdGhlIGZpeGVkLW9mZnNldCB6b25lIHNwZWNpZmllZCBpbiB0aGUgc3RyaW5nLiBGb3IgSFRUUCBkYXRlcywgdGhpcyBpcyBhbHdheXMgVVRDLCBzbyB0aGlzIG9wdGlvbiBpcyBlcXVpdmFsZW50IHRvIHNldHRpbmcgdGhlIGB6b25lYCBvcHRpb24gdG8gJ3V0YycsIGJ1dCB0aGlzIG9wdGlvbiBpcyBpbmNsdWRlZCBmb3IgY29uc2lzdGVuY3kgd2l0aCBzaW1pbGFyIG1ldGhvZHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5sb2NhbGU9J3N5c3RlbSdzIGxvY2FsZSddIC0gYSBsb2NhbGUgdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wdHMub3V0cHV0Q2FsZW5kYXIgLSB0aGUgb3V0cHV0IGNhbGVuZGFyIHRvIHNldCBvbiB0aGUgcmVzdWx0aW5nIERhdGVUaW1lIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLm51bWJlcmluZ1N5c3RlbSAtIHRoZSBudW1iZXJpbmcgc3lzdGVtIHRvIHNldCBvbiB0aGUgcmVzdWx0aW5nIERhdGVUaW1lIGluc3RhbmNlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21IVFRQKCdTdW4sIDA2IE5vdiAxOTk0IDA4OjQ5OjM3IEdNVCcpXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21IVFRQKCdTdW5kYXksIDA2LU5vdi05NCAwODo0OTozNyBHTVQnKVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5mcm9tSFRUUCgnU3VuIE5vdiAgNiAwODo0OTozNyAxOTk0JylcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGF0aWMgZnJvbUhUVFAodGV4dCwgb3B0cyA9IHt9KSB7XG4gICAgY29uc3QgW3ZhbHMsIHBhcnNlZFpvbmVdID0gcGFyc2VIVFRQRGF0ZSh0ZXh0KTtcbiAgICByZXR1cm4gcGFyc2VEYXRhVG9EYXRlVGltZSh2YWxzLCBwYXJzZWRab25lLCBvcHRzLCBcIkhUVFBcIiwgb3B0cyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRGF0ZVRpbWUgZnJvbSBhbiBpbnB1dCBzdHJpbmcgYW5kIGZvcm1hdCBzdHJpbmcuXG4gICAqIERlZmF1bHRzIHRvIGVuLVVTIGlmIG5vIGxvY2FsZSBoYXMgYmVlbiBzcGVjaWZpZWQsIHJlZ2FyZGxlc3Mgb2YgdGhlIHN5c3RlbSdzIGxvY2FsZS4gRm9yIGEgdGFibGUgb2YgdG9rZW5zIGFuZCB0aGVpciBpbnRlcnByZXRhdGlvbnMsIHNlZSBbaGVyZV0oaHR0cHM6Ly9tb21lbnQuZ2l0aHViLmlvL2x1eG9uLyMvcGFyc2luZz9pZD10YWJsZS1vZi10b2tlbnMpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIHRoZSBzdHJpbmcgdG8gcGFyc2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZtdCAtIHRoZSBmb3JtYXQgdGhlIHN0cmluZyBpcyBleHBlY3RlZCB0byBiZSBpbiAoc2VlIHRoZSBsaW5rIGJlbG93IGZvciB0aGUgZm9ybWF0cylcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zIHRvIGFmZmVjdCB0aGUgY3JlYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd8Wm9uZX0gW29wdHMuem9uZT0nbG9jYWwnXSAtIHVzZSB0aGlzIHpvbmUgaWYgbm8gb2Zmc2V0IGlzIHNwZWNpZmllZCBpbiB0aGUgaW5wdXQgc3RyaW5nIGl0c2VsZi4gV2lsbCBhbHNvIGNvbnZlcnQgdGhlIERhdGVUaW1lIHRvIHRoaXMgem9uZVxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLnNldFpvbmU9ZmFsc2VdIC0gb3ZlcnJpZGUgdGhlIHpvbmUgd2l0aCBhIHpvbmUgc3BlY2lmaWVkIGluIHRoZSBzdHJpbmcgaXRzZWxmLCBpZiBpdCBzcGVjaWZpZXMgb25lXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5sb2NhbGU9J2VuLVVTJ10gLSBhIGxvY2FsZSBzdHJpbmcgdG8gdXNlIHdoZW4gcGFyc2luZy4gV2lsbCBhbHNvIHNldCB0aGUgRGF0ZVRpbWUgdG8gdGhpcyBsb2NhbGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wdHMubnVtYmVyaW5nU3lzdGVtIC0gdGhlIG51bWJlcmluZyBzeXN0ZW0gdG8gdXNlIHdoZW4gcGFyc2luZy4gV2lsbCBhbHNvIHNldCB0aGUgcmVzdWx0aW5nIERhdGVUaW1lIHRvIHRoaXMgbnVtYmVyaW5nIHN5c3RlbVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0cy5vdXRwdXRDYWxlbmRhciAtIHRoZSBvdXRwdXQgY2FsZW5kYXIgdG8gc2V0IG9uIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgaW5zdGFuY2VcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGF0aWMgZnJvbUZvcm1hdCh0ZXh0LCBmbXQsIG9wdHMgPSB7fSkge1xuICAgIGlmIChpc1VuZGVmaW5lZCh0ZXh0KSB8fCBpc1VuZGVmaW5lZChmbXQpKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3IoXCJmcm9tRm9ybWF0IHJlcXVpcmVzIGFuIGlucHV0IHN0cmluZyBhbmQgYSBmb3JtYXRcIik7XG4gICAgfVxuXG4gICAgY29uc3QgeyBsb2NhbGUgPSBudWxsLCBudW1iZXJpbmdTeXN0ZW0gPSBudWxsIH0gPSBvcHRzLFxuICAgICAgbG9jYWxlVG9Vc2UgPSBMb2NhbGUuZnJvbU9wdHMoe1xuICAgICAgICBsb2NhbGUsXG4gICAgICAgIG51bWJlcmluZ1N5c3RlbSxcbiAgICAgICAgZGVmYXVsdFRvRU46IHRydWUsXG4gICAgICB9KSxcbiAgICAgIFt2YWxzLCBwYXJzZWRab25lLCBzcGVjaWZpY09mZnNldCwgaW52YWxpZF0gPSBwYXJzZUZyb21Ub2tlbnMobG9jYWxlVG9Vc2UsIHRleHQsIGZtdCk7XG4gICAgaWYgKGludmFsaWQpIHtcbiAgICAgIHJldHVybiBEYXRlVGltZS5pbnZhbGlkKGludmFsaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcGFyc2VEYXRhVG9EYXRlVGltZSh2YWxzLCBwYXJzZWRab25lLCBvcHRzLCBgZm9ybWF0ICR7Zm10fWAsIHRleHQsIHNwZWNpZmljT2Zmc2V0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgdXNlIGZyb21Gb3JtYXQgaW5zdGVhZFxuICAgKi9cbiAgc3RhdGljIGZyb21TdHJpbmcodGV4dCwgZm10LCBvcHRzID0ge30pIHtcbiAgICByZXR1cm4gRGF0ZVRpbWUuZnJvbUZvcm1hdCh0ZXh0LCBmbXQsIG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIERhdGVUaW1lIGZyb20gYSBTUUwgZGF0ZSwgdGltZSwgb3IgZGF0ZXRpbWVcbiAgICogRGVmYXVsdHMgdG8gZW4tVVMgaWYgbm8gbG9jYWxlIGhhcyBiZWVuIHNwZWNpZmllZCwgcmVnYXJkbGVzcyBvZiB0aGUgc3lzdGVtJ3MgbG9jYWxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gdGhlIHN0cmluZyB0byBwYXJzZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnMgdG8gYWZmZWN0IHRoZSBjcmVhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ3xab25lfSBbb3B0cy56b25lPSdsb2NhbCddIC0gdXNlIHRoaXMgem9uZSBpZiBubyBvZmZzZXQgaXMgc3BlY2lmaWVkIGluIHRoZSBpbnB1dCBzdHJpbmcgaXRzZWxmLiBXaWxsIGFsc28gY29udmVydCB0aGUgRGF0ZVRpbWUgdG8gdGhpcyB6b25lXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuc2V0Wm9uZT1mYWxzZV0gLSBvdmVycmlkZSB0aGUgem9uZSB3aXRoIGEgem9uZSBzcGVjaWZpZWQgaW4gdGhlIHN0cmluZyBpdHNlbGYsIGlmIGl0IHNwZWNpZmllcyBvbmVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmxvY2FsZT0nZW4tVVMnXSAtIGEgbG9jYWxlIHN0cmluZyB0byB1c2Ugd2hlbiBwYXJzaW5nLiBXaWxsIGFsc28gc2V0IHRoZSBEYXRlVGltZSB0byB0aGlzIGxvY2FsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0cy5udW1iZXJpbmdTeXN0ZW0gLSB0aGUgbnVtYmVyaW5nIHN5c3RlbSB0byB1c2Ugd2hlbiBwYXJzaW5nLiBXaWxsIGFsc28gc2V0IHRoZSByZXN1bHRpbmcgRGF0ZVRpbWUgdG8gdGhpcyBudW1iZXJpbmcgc3lzdGVtXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRzLm91dHB1dENhbGVuZGFyIC0gdGhlIG91dHB1dCBjYWxlbmRhciB0byBzZXQgb24gdGhlIHJlc3VsdGluZyBEYXRlVGltZSBpbnN0YW5jZVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5mcm9tU1FMKCcyMDE3LTA1LTE1JylcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUuZnJvbVNRTCgnMjAxNy0wNS0xNSAwOToxMjozNCcpXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21TUUwoJzIwMTctMDUtMTUgMDk6MTI6MzQuMzQyJylcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUuZnJvbVNRTCgnMjAxNy0wNS0xNSAwOToxMjozNC4zNDIrMDY6MDAnKVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5mcm9tU1FMKCcyMDE3LTA1LTE1IDA5OjEyOjM0LjM0MiBBbWVyaWNhL0xvc19BbmdlbGVzJylcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUuZnJvbVNRTCgnMjAxNy0wNS0xNSAwOToxMjozNC4zNDIgQW1lcmljYS9Mb3NfQW5nZWxlcycsIHsgc2V0Wm9uZTogdHJ1ZSB9KVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5mcm9tU1FMKCcyMDE3LTA1LTE1IDA5OjEyOjM0LjM0MicsIHsgem9uZTogJ0FtZXJpY2EvTG9zX0FuZ2VsZXMnIH0pXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmZyb21TUUwoJzA5OjEyOjM0LjM0MicpXG4gICAqIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgKi9cbiAgc3RhdGljIGZyb21TUUwodGV4dCwgb3B0cyA9IHt9KSB7XG4gICAgY29uc3QgW3ZhbHMsIHBhcnNlZFpvbmVdID0gcGFyc2VTUUwodGV4dCk7XG4gICAgcmV0dXJuIHBhcnNlRGF0YVRvRGF0ZVRpbWUodmFscywgcGFyc2VkWm9uZSwgb3B0cywgXCJTUUxcIiwgdGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIGludmFsaWQgRGF0ZVRpbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBzaW1wbGUgc3RyaW5nIG9mIHdoeSB0aGlzIERhdGVUaW1lIGlzIGludmFsaWQuIFNob3VsZCBub3QgY29udGFpbiBwYXJhbWV0ZXJzIG9yIGFueXRoaW5nIGVsc2UgZGF0YS1kZXBlbmRlbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZXhwbGFuYXRpb249bnVsbF0gLSBsb25nZXIgZXhwbGFuYXRpb24sIG1heSBpbmNsdWRlIHBhcmFtZXRlcnMgYW5kIG90aGVyIHVzZWZ1bCBkZWJ1Z2dpbmcgaW5mb3JtYXRpb25cbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGF0aWMgaW52YWxpZChyZWFzb24sIGV4cGxhbmF0aW9uID0gbnVsbCkge1xuICAgIGlmICghcmVhc29uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3IoXCJuZWVkIHRvIHNwZWNpZnkgYSByZWFzb24gdGhlIERhdGVUaW1lIGlzIGludmFsaWRcIik7XG4gICAgfVxuXG4gICAgY29uc3QgaW52YWxpZCA9IHJlYXNvbiBpbnN0YW5jZW9mIEludmFsaWQgPyByZWFzb24gOiBuZXcgSW52YWxpZChyZWFzb24sIGV4cGxhbmF0aW9uKTtcblxuICAgIGlmIChTZXR0aW5ncy50aHJvd09uSW52YWxpZCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRlVGltZUVycm9yKGludmFsaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IERhdGVUaW1lKHsgaW52YWxpZCB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYW4gb2JqZWN0IGlzIGFuIGluc3RhbmNlIG9mIERhdGVUaW1lLiBXb3JrcyBhY3Jvc3MgY29udGV4dCBib3VuZGFyaWVzXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBzdGF0aWMgaXNEYXRlVGltZShvKSB7XG4gICAgcmV0dXJuIChvICYmIG8uaXNMdXhvbkRhdGVUaW1lKSB8fCBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlIHRoZSBmb3JtYXQgc3RyaW5nIGZvciBhIHNldCBvZiBvcHRpb25zXG4gICAqIEBwYXJhbSBmb3JtYXRPcHRzXG4gICAqIEBwYXJhbSBsb2NhbGVPcHRzXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBzdGF0aWMgcGFyc2VGb3JtYXRGb3JPcHRzKGZvcm1hdE9wdHMsIGxvY2FsZU9wdHMgPSB7fSkge1xuICAgIGNvbnN0IHRva2VuTGlzdCA9IGZvcm1hdE9wdHNUb1Rva2Vucyhmb3JtYXRPcHRzLCBMb2NhbGUuZnJvbU9iamVjdChsb2NhbGVPcHRzKSk7XG4gICAgcmV0dXJuICF0b2tlbkxpc3QgPyBudWxsIDogdG9rZW5MaXN0Lm1hcCgodCkgPT4gKHQgPyB0LnZhbCA6IG51bGwpKS5qb2luKFwiXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2UgdGhlIHRoZSBmdWxseSBleHBhbmRlZCBmb3JtYXQgdG9rZW4gZm9yIHRoZSBsb2NhbGVcbiAgICogRG9lcyBOT1QgcXVvdGUgY2hhcmFjdGVycywgc28gcXVvdGVkIHRva2VucyB3aWxsIG5vdCByb3VuZCB0cmlwIGNvcnJlY3RseVxuICAgKiBAcGFyYW0gZm10XG4gICAqIEBwYXJhbSBsb2NhbGVPcHRzXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBzdGF0aWMgZXhwYW5kRm9ybWF0KGZtdCwgbG9jYWxlT3B0cyA9IHt9KSB7XG4gICAgY29uc3QgZXhwYW5kZWQgPSBleHBhbmRNYWNyb1Rva2VucyhGb3JtYXR0ZXIucGFyc2VGb3JtYXQoZm10KSwgTG9jYWxlLmZyb21PYmplY3QobG9jYWxlT3B0cykpO1xuICAgIHJldHVybiBleHBhbmRlZC5tYXAoKHQpID0+IHQudmFsKS5qb2luKFwiXCIpO1xuICB9XG5cbiAgLy8gSU5GT1xuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHZhbHVlIG9mIHVuaXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1bml0IC0gYSB1bml0IHN1Y2ggYXMgJ21pbnV0ZScgb3IgJ2RheSdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNywgNCkuZ2V0KCdtb250aCcpOyAvLz0+IDdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNywgNCkuZ2V0KCdkYXknKTsgLy89PiA0XG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldCh1bml0KSB7XG4gICAgcmV0dXJuIHRoaXNbdW5pdF07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBEYXRlVGltZSBpcyB2YWxpZC4gSW52YWxpZCBEYXRlVGltZXMgb2NjdXIgd2hlbjpcbiAgICogKiBUaGUgRGF0ZVRpbWUgd2FzIGNyZWF0ZWQgZnJvbSBpbnZhbGlkIGNhbGVuZGFyIGluZm9ybWF0aW9uLCBzdWNoIGFzIHRoZSAxM3RoIG1vbnRoIG9yIEZlYnJ1YXJ5IDMwXG4gICAqICogVGhlIERhdGVUaW1lIHdhcyBjcmVhdGVkIGJ5IGFuIG9wZXJhdGlvbiBvbiBhbm90aGVyIGludmFsaWQgZGF0ZVxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIGdldCBpc1ZhbGlkKCkge1xuICAgIHJldHVybiB0aGlzLmludmFsaWQgPT09IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBlcnJvciBjb2RlIGlmIHRoaXMgRGF0ZVRpbWUgaXMgaW52YWxpZCwgb3IgbnVsbCBpZiB0aGUgRGF0ZVRpbWUgaXMgdmFsaWRcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICovXG4gIGdldCBpbnZhbGlkUmVhc29uKCkge1xuICAgIHJldHVybiB0aGlzLmludmFsaWQgPyB0aGlzLmludmFsaWQucmVhc29uIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGV4cGxhbmF0aW9uIG9mIHdoeSB0aGlzIERhdGVUaW1lIGJlY2FtZSBpbnZhbGlkLCBvciBudWxsIGlmIHRoZSBEYXRlVGltZSBpcyB2YWxpZFxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgZ2V0IGludmFsaWRFeHBsYW5hdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5pbnZhbGlkID8gdGhpcy5pbnZhbGlkLmV4cGxhbmF0aW9uIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGxvY2FsZSBvZiBhIERhdGVUaW1lLCBzdWNoICdlbi1HQicuIFRoZSBsb2NhbGUgaXMgdXNlZCB3aGVuIGZvcm1hdHRpbmcgdGhlIERhdGVUaW1lXG4gICAqXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqL1xuICBnZXQgbG9jYWxlKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLmxvYy5sb2NhbGUgOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbnVtYmVyaW5nIHN5c3RlbSBvZiBhIERhdGVUaW1lLCBzdWNoICdiZW5nJy4gVGhlIG51bWJlcmluZyBzeXN0ZW0gaXMgdXNlZCB3aGVuIGZvcm1hdHRpbmcgdGhlIERhdGVUaW1lXG4gICAqXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqL1xuICBnZXQgbnVtYmVyaW5nU3lzdGVtKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLmxvYy5udW1iZXJpbmdTeXN0ZW0gOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgb3V0cHV0IGNhbGVuZGFyIG9mIGEgRGF0ZVRpbWUsIHN1Y2ggJ2lzbGFtaWMnLiBUaGUgb3V0cHV0IGNhbGVuZGFyIGlzIHVzZWQgd2hlbiBmb3JtYXR0aW5nIHRoZSBEYXRlVGltZVxuICAgKlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgZ2V0IG91dHB1dENhbGVuZGFyKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLmxvYy5vdXRwdXRDYWxlbmRhciA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB0aW1lIHpvbmUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRGF0ZVRpbWUuXG4gICAqIEB0eXBlIHtab25lfVxuICAgKi9cbiAgZ2V0IHpvbmUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3pvbmU7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBuYW1lIG9mIHRoZSB0aW1lIHpvbmUuXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqL1xuICBnZXQgem9uZU5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IHRoaXMuem9uZS5uYW1lIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHllYXJcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNSwgMjUpLnllYXIgLy89PiAyMDE3XG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgeWVhcigpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy5jLnllYXIgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBxdWFydGVyXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTcsIDUsIDI1KS5xdWFydGVyIC8vPT4gMlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IHF1YXJ0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IE1hdGguY2VpbCh0aGlzLmMubW9udGggLyAzKSA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1vbnRoICgxLTEyKS5cbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNSwgMjUpLm1vbnRoIC8vPT4gNVxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IG1vbnRoKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLmMubW9udGggOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBkYXkgb2YgdGhlIG1vbnRoICgxLTMwaXNoKS5cbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNSwgMjUpLmRheSAvLz0+IDI1XG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgZGF5KCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLmMuZGF5IDogTmFOO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgaG91ciBvZiB0aGUgZGF5ICgwLTIzKS5cbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNSwgMjUsIDkpLmhvdXIgLy89PiA5XG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgaG91cigpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy5jLmhvdXIgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBtaW51dGUgb2YgdGhlIGhvdXIgKDAtNTkpLlxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE3LCA1LCAyNSwgOSwgMzApLm1pbnV0ZSAvLz0+IDMwXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgbWludXRlKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLmMubWludXRlIDogTmFOO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgc2Vjb25kIG9mIHRoZSBtaW51dGUgKDAtNTkpLlxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE3LCA1LCAyNSwgOSwgMzAsIDUyKS5zZWNvbmQgLy89PiA1MlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IHNlY29uZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gdGhpcy5jLnNlY29uZCA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1pbGxpc2Vjb25kIG9mIHRoZSBzZWNvbmQgKDAtOTk5KS5cbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNSwgMjUsIDksIDMwLCA1MiwgNjU0KS5taWxsaXNlY29uZCAvLz0+IDY1NFxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IG1pbGxpc2Vjb25kKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLmMubWlsbGlzZWNvbmQgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB3ZWVrIHllYXJcbiAgICogQHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTQsIDEyLCAzMSkud2Vla1llYXIgLy89PiAyMDE1XG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgd2Vla1llYXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IHBvc3NpYmx5Q2FjaGVkV2Vla0RhdGEodGhpcykud2Vla1llYXIgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB3ZWVrIG51bWJlciBvZiB0aGUgd2VlayB5ZWFyICgxLTUyaXNoKS5cbiAgICogQHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTcsIDUsIDI1KS53ZWVrTnVtYmVyIC8vPT4gMjFcbiAgICogQHR5cGUge251bWJlcn1cbiAgICovXG4gIGdldCB3ZWVrTnVtYmVyKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyBwb3NzaWJseUNhY2hlZFdlZWtEYXRhKHRoaXMpLndlZWtOdW1iZXIgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBkYXkgb2YgdGhlIHdlZWsuXG4gICAqIDEgaXMgTW9uZGF5IGFuZCA3IGlzIFN1bmRheVxuICAgKiBAc2VlIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT193ZWVrX2RhdGVcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNCwgMTEsIDMxKS53ZWVrZGF5IC8vPT4gNFxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IHdlZWtkYXkoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IHBvc3NpYmx5Q2FjaGVkV2Vla0RhdGEodGhpcykud2Vla2RheSA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBkYXRlIGlzIG9uIGEgd2Vla2VuZCBhY2NvcmRpbmcgdG8gdGhlIGxvY2FsZSwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgZ2V0IGlzV2Vla2VuZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkICYmIHRoaXMubG9jLmdldFdlZWtlbmREYXlzKCkuaW5jbHVkZXModGhpcy53ZWVrZGF5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGRheSBvZiB0aGUgd2VlayBhY2NvcmRpbmcgdG8gdGhlIGxvY2FsZS5cbiAgICogMSBpcyB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrIGFuZCA3IGlzIHRoZSBsYXN0IGRheSBvZiB0aGUgd2Vlay5cbiAgICogSWYgdGhlIGxvY2FsZSBhc3NpZ25zIFN1bmRheSBhcyB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrLCB0aGVuIGEgZGF0ZSB3aGljaCBpcyBhIFN1bmRheSB3aWxsIHJldHVybiAxLFxuICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IGxvY2FsV2Vla2RheSgpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkID8gcG9zc2libHlDYWNoZWRMb2NhbFdlZWtEYXRhKHRoaXMpLndlZWtkYXkgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB3ZWVrIG51bWJlciBvZiB0aGUgd2VlayB5ZWFyIGFjY29yZGluZyB0byB0aGUgbG9jYWxlLiBEaWZmZXJlbnQgbG9jYWxlcyBhc3NpZ24gd2VlayBudW1iZXJzIGRpZmZlcmVudGx5LFxuICAgKiBiZWNhdXNlIHRoZSB3ZWVrIGNhbiBzdGFydCBvbiBkaWZmZXJlbnQgZGF5cyBvZiB0aGUgd2VlayAoc2VlIGxvY2FsV2Vla2RheSkgYW5kIGJlY2F1c2UgYSBkaWZmZXJlbnQgbnVtYmVyIG9mIGRheXNcbiAgICogaXMgcmVxdWlyZWQgZm9yIGEgd2VlayB0byBjb3VudCBhcyB0aGUgZmlyc3Qgd2VlayBvZiBhIHllYXIuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgbG9jYWxXZWVrTnVtYmVyKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyBwb3NzaWJseUNhY2hlZExvY2FsV2Vla0RhdGEodGhpcykud2Vla051bWJlciA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHdlZWsgeWVhciBhY2NvcmRpbmcgdG8gdGhlIGxvY2FsZS4gRGlmZmVyZW50IGxvY2FsZXMgYXNzaWduIHdlZWsgbnVtYmVycyAoYW5kIHRoZXJlZm9yIHdlZWsgeWVhcnMpXG4gICAqIGRpZmZlcmVudGx5LCBzZWUgbG9jYWxXZWVrTnVtYmVyLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IGxvY2FsV2Vla1llYXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IHBvc3NpYmx5Q2FjaGVkTG9jYWxXZWVrRGF0YSh0aGlzKS53ZWVrWWVhciA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG9yZGluYWwgKG1lYW5pbmcgdGhlIGRheSBvZiB0aGUgeWVhcilcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNSwgMjUpLm9yZGluYWwgLy89PiAxNDVcbiAgICogQHR5cGUge251bWJlcnxEYXRlVGltZX1cbiAgICovXG4gIGdldCBvcmRpbmFsKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyBncmVnb3JpYW5Ub09yZGluYWwodGhpcy5jKS5vcmRpbmFsIDogTmFOO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgaHVtYW4gcmVhZGFibGUgc2hvcnQgbW9udGggbmFtZSwgc3VjaCBhcyAnT2N0Jy5cbiAgICogRGVmYXVsdHMgdG8gdGhlIHN5c3RlbSdzIGxvY2FsZSBpZiBubyBsb2NhbGUgaGFzIGJlZW4gc3BlY2lmaWVkXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTcsIDEwLCAzMCkubW9udGhTaG9ydCAvLz0+IE9jdFxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgZ2V0IG1vbnRoU2hvcnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IEluZm8ubW9udGhzKFwic2hvcnRcIiwgeyBsb2NPYmo6IHRoaXMubG9jIH0pW3RoaXMubW9udGggLSAxXSA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBodW1hbiByZWFkYWJsZSBsb25nIG1vbnRoIG5hbWUsIHN1Y2ggYXMgJ09jdG9iZXInLlxuICAgKiBEZWZhdWx0cyB0byB0aGUgc3lzdGVtJ3MgbG9jYWxlIGlmIG5vIGxvY2FsZSBoYXMgYmVlbiBzcGVjaWZpZWRcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgMTAsIDMwKS5tb250aExvbmcgLy89PiBPY3RvYmVyXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqL1xuICBnZXQgbW9udGhMb25nKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyBJbmZvLm1vbnRocyhcImxvbmdcIiwgeyBsb2NPYmo6IHRoaXMubG9jIH0pW3RoaXMubW9udGggLSAxXSA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBodW1hbiByZWFkYWJsZSBzaG9ydCB3ZWVrZGF5LCBzdWNoIGFzICdNb24nLlxuICAgKiBEZWZhdWx0cyB0byB0aGUgc3lzdGVtJ3MgbG9jYWxlIGlmIG5vIGxvY2FsZSBoYXMgYmVlbiBzcGVjaWZpZWRcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgMTAsIDMwKS53ZWVrZGF5U2hvcnQgLy89PiBNb25cbiAgICogQHR5cGUge3N0cmluZ31cbiAgICovXG4gIGdldCB3ZWVrZGF5U2hvcnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IEluZm8ud2Vla2RheXMoXCJzaG9ydFwiLCB7IGxvY09iajogdGhpcy5sb2MgfSlbdGhpcy53ZWVrZGF5IC0gMV0gOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgaHVtYW4gcmVhZGFibGUgbG9uZyB3ZWVrZGF5LCBzdWNoIGFzICdNb25kYXknLlxuICAgKiBEZWZhdWx0cyB0byB0aGUgc3lzdGVtJ3MgbG9jYWxlIGlmIG5vIGxvY2FsZSBoYXMgYmVlbiBzcGVjaWZpZWRcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgMTAsIDMwKS53ZWVrZGF5TG9uZyAvLz0+IE1vbmRheVxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgZ2V0IHdlZWtkYXlMb25nKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyBJbmZvLndlZWtkYXlzKFwibG9uZ1wiLCB7IGxvY09iajogdGhpcy5sb2MgfSlbdGhpcy53ZWVrZGF5IC0gMV0gOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgVVRDIG9mZnNldCBvZiB0aGlzIERhdGVUaW1lIGluIG1pbnV0ZXNcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkub2Zmc2V0IC8vPT4gLTI0MFxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS51dGMoKS5vZmZzZXQgLy89PiAwXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgb2Zmc2V0KCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyArdGhpcy5vIDogTmFOO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgc2hvcnQgaHVtYW4gbmFtZSBmb3IgdGhlIHpvbmUncyBjdXJyZW50IG9mZnNldCwgZm9yIGV4YW1wbGUgXCJFU1RcIiBvciBcIkVEVFwiLlxuICAgKiBEZWZhdWx0cyB0byB0aGUgc3lzdGVtJ3MgbG9jYWxlIGlmIG5vIGxvY2FsZSBoYXMgYmVlbiBzcGVjaWZpZWRcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICovXG4gIGdldCBvZmZzZXROYW1lU2hvcnQoKSB7XG4gICAgaWYgKHRoaXMuaXNWYWxpZCkge1xuICAgICAgcmV0dXJuIHRoaXMuem9uZS5vZmZzZXROYW1lKHRoaXMudHMsIHtcbiAgICAgICAgZm9ybWF0OiBcInNob3J0XCIsXG4gICAgICAgIGxvY2FsZTogdGhpcy5sb2NhbGUsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbG9uZyBodW1hbiBuYW1lIGZvciB0aGUgem9uZSdzIGN1cnJlbnQgb2Zmc2V0LCBmb3IgZXhhbXBsZSBcIkVhc3Rlcm4gU3RhbmRhcmQgVGltZVwiIG9yIFwiRWFzdGVybiBEYXlsaWdodCBUaW1lXCIuXG4gICAqIERlZmF1bHRzIHRvIHRoZSBzeXN0ZW0ncyBsb2NhbGUgaWYgbm8gbG9jYWxlIGhhcyBiZWVuIHNwZWNpZmllZFxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKi9cbiAgZ2V0IG9mZnNldE5hbWVMb25nKCkge1xuICAgIGlmICh0aGlzLmlzVmFsaWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnpvbmUub2Zmc2V0TmFtZSh0aGlzLnRzLCB7XG4gICAgICAgIGZvcm1hdDogXCJsb25nXCIsXG4gICAgICAgIGxvY2FsZTogdGhpcy5sb2NhbGUsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB3aGV0aGVyIHRoaXMgem9uZSdzIG9mZnNldCBldmVyIGNoYW5nZXMsIGFzIGluIGEgRFNULlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIGdldCBpc09mZnNldEZpeGVkKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB0aGlzLnpvbmUuaXNVbml2ZXJzYWwgOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB3aGV0aGVyIHRoZSBEYXRlVGltZSBpcyBpbiBhIERTVC5cbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqL1xuICBnZXQgaXNJbkRTVCgpIHtcbiAgICBpZiAodGhpcy5pc09mZnNldEZpeGVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIHRoaXMub2Zmc2V0ID4gdGhpcy5zZXQoeyBtb250aDogMSwgZGF5OiAxIH0pLm9mZnNldCB8fFxuICAgICAgICB0aGlzLm9mZnNldCA+IHRoaXMuc2V0KHsgbW9udGg6IDUgfSkub2Zmc2V0XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhvc2UgRGF0ZVRpbWVzIHdoaWNoIGhhdmUgdGhlIHNhbWUgbG9jYWwgdGltZSBhcyB0aGlzIERhdGVUaW1lLCBidXQgYSBkaWZmZXJlbnQgb2Zmc2V0IGZyb20gVVRDXG4gICAqIGluIHRoaXMgRGF0ZVRpbWUncyB6b25lLiBEdXJpbmcgRFNUIGNoYW5nZXMgbG9jYWwgdGltZSBjYW4gYmUgYW1iaWd1b3VzLCBmb3IgZXhhbXBsZVxuICAgKiBgMjAyMy0xMC0yOVQwMjozMDowMGAgaW4gYEV1cm9wZS9CZXJsaW5gIGNhbiBoYXZlIG9mZnNldCBgKzAxOjAwYCBvciBgKzAyOjAwYC5cbiAgICogVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gYm90aCBwb3NzaWJsZSBEYXRlVGltZXMgaWYgdGhpcyBEYXRlVGltZSdzIGxvY2FsIHRpbWUgaXMgYW1iaWd1b3VzLlxuICAgKiBAcmV0dXJucyB7RGF0ZVRpbWVbXX1cbiAgICovXG4gIGdldFBvc3NpYmxlT2Zmc2V0cygpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCB8fCB0aGlzLmlzT2Zmc2V0Rml4ZWQpIHtcbiAgICAgIHJldHVybiBbdGhpc107XG4gICAgfVxuICAgIGNvbnN0IGRheU1zID0gODY0MDAwMDA7XG4gICAgY29uc3QgbWludXRlTXMgPSA2MDAwMDtcbiAgICBjb25zdCBsb2NhbFRTID0gb2JqVG9Mb2NhbFRTKHRoaXMuYyk7XG4gICAgY29uc3Qgb0VhcmxpZXIgPSB0aGlzLnpvbmUub2Zmc2V0KGxvY2FsVFMgLSBkYXlNcyk7XG4gICAgY29uc3Qgb0xhdGVyID0gdGhpcy56b25lLm9mZnNldChsb2NhbFRTICsgZGF5TXMpO1xuXG4gICAgY29uc3QgbzEgPSB0aGlzLnpvbmUub2Zmc2V0KGxvY2FsVFMgLSBvRWFybGllciAqIG1pbnV0ZU1zKTtcbiAgICBjb25zdCBvMiA9IHRoaXMuem9uZS5vZmZzZXQobG9jYWxUUyAtIG9MYXRlciAqIG1pbnV0ZU1zKTtcbiAgICBpZiAobzEgPT09IG8yKSB7XG4gICAgICByZXR1cm4gW3RoaXNdO1xuICAgIH1cbiAgICBjb25zdCB0czEgPSBsb2NhbFRTIC0gbzEgKiBtaW51dGVNcztcbiAgICBjb25zdCB0czIgPSBsb2NhbFRTIC0gbzIgKiBtaW51dGVNcztcbiAgICBjb25zdCBjMSA9IHRzVG9PYmoodHMxLCBvMSk7XG4gICAgY29uc3QgYzIgPSB0c1RvT2JqKHRzMiwgbzIpO1xuICAgIGlmIChcbiAgICAgIGMxLmhvdXIgPT09IGMyLmhvdXIgJiZcbiAgICAgIGMxLm1pbnV0ZSA9PT0gYzIubWludXRlICYmXG4gICAgICBjMS5zZWNvbmQgPT09IGMyLnNlY29uZCAmJlxuICAgICAgYzEubWlsbGlzZWNvbmQgPT09IGMyLm1pbGxpc2Vjb25kXG4gICAgKSB7XG4gICAgICByZXR1cm4gW2Nsb25lKHRoaXMsIHsgdHM6IHRzMSB9KSwgY2xvbmUodGhpcywgeyB0czogdHMyIH0pXTtcbiAgICB9XG4gICAgcmV0dXJuIFt0aGlzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBEYXRlVGltZSBpcyBpbiBhIGxlYXAgeWVhciwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTYpLmlzSW5MZWFwWWVhciAvLz0+IHRydWVcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxMykuaXNJbkxlYXBZZWFyIC8vPT4gZmFsc2VcbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqL1xuICBnZXQgaXNJbkxlYXBZZWFyKCkge1xuICAgIHJldHVybiBpc0xlYXBZZWFyKHRoaXMueWVhcik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGRheXMgaW4gdGhpcyBEYXRlVGltZSdzIG1vbnRoXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTYsIDIpLmRheXNJbk1vbnRoIC8vPT4gMjlcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNiwgMykuZGF5c0luTW9udGggLy89PiAzMVxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IGRheXNJbk1vbnRoKCkge1xuICAgIHJldHVybiBkYXlzSW5Nb250aCh0aGlzLnllYXIsIHRoaXMubW9udGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBkYXlzIGluIHRoaXMgRGF0ZVRpbWUncyB5ZWFyXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTYpLmRheXNJblllYXIgLy89PiAzNjZcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxMykuZGF5c0luWWVhciAvLz0+IDM2NVxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0IGRheXNJblllYXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IGRheXNJblllYXIodGhpcy55ZWFyKSA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygd2Vla3MgaW4gdGhpcyBEYXRlVGltZSdzIHllYXJcbiAgICogQHNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMDQpLndlZWtzSW5XZWVrWWVhciAvLz0+IDUzXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTMpLndlZWtzSW5XZWVrWWVhciAvLz0+IDUyXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgd2Vla3NJbldlZWtZZWFyKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyB3ZWVrc0luV2Vla1llYXIodGhpcy53ZWVrWWVhcikgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHdlZWtzIGluIHRoaXMgRGF0ZVRpbWUncyBsb2NhbCB3ZWVrIHllYXJcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAyMCwgNiwge2xvY2FsZTogJ2VuLVVTJ30pLndlZWtzSW5Mb2NhbFdlZWtZZWFyIC8vPT4gNTJcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAyMCwgNiwge2xvY2FsZTogJ2RlLURFJ30pLndlZWtzSW5Mb2NhbFdlZWtZZWFyIC8vPT4gNTNcbiAgICogQHR5cGUge251bWJlcn1cbiAgICovXG4gIGdldCB3ZWVrc0luTG9jYWxXZWVrWWVhcigpIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkXG4gICAgICA/IHdlZWtzSW5XZWVrWWVhcihcbiAgICAgICAgICB0aGlzLmxvY2FsV2Vla1llYXIsXG4gICAgICAgICAgdGhpcy5sb2MuZ2V0TWluRGF5c0luRmlyc3RXZWVrKCksXG4gICAgICAgICAgdGhpcy5sb2MuZ2V0U3RhcnRPZldlZWsoKVxuICAgICAgICApXG4gICAgICA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSByZXNvbHZlZCBJbnRsIG9wdGlvbnMgZm9yIHRoaXMgRGF0ZVRpbWUuXG4gICAqIFRoaXMgaXMgdXNlZnVsIGluIHVuZGVyc3RhbmRpbmcgdGhlIGJlaGF2aW9yIG9mIGZvcm1hdHRpbmcgbWV0aG9kc1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIHRoZSBzYW1lIG9wdGlvbnMgYXMgdG9Mb2NhbGVTdHJpbmdcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgcmVzb2x2ZWRMb2NhbGVPcHRpb25zKG9wdHMgPSB7fSkge1xuICAgIGNvbnN0IHsgbG9jYWxlLCBudW1iZXJpbmdTeXN0ZW0sIGNhbGVuZGFyIH0gPSBGb3JtYXR0ZXIuY3JlYXRlKFxuICAgICAgdGhpcy5sb2MuY2xvbmUob3B0cyksXG4gICAgICBvcHRzXG4gICAgKS5yZXNvbHZlZE9wdGlvbnModGhpcyk7XG4gICAgcmV0dXJuIHsgbG9jYWxlLCBudW1iZXJpbmdTeXN0ZW0sIG91dHB1dENhbGVuZGFyOiBjYWxlbmRhciB9O1xuICB9XG5cbiAgLy8gVFJBTlNGT1JNXG5cbiAgLyoqXG4gICAqIFwiU2V0XCIgdGhlIERhdGVUaW1lJ3Mgem9uZSB0byBVVEMuIFJldHVybnMgYSBuZXdseS1jb25zdHJ1Y3RlZCBEYXRlVGltZS5cbiAgICpcbiAgICogRXF1aXZhbGVudCB0byB7QGxpbmsgRGF0ZVRpbWUjc2V0Wm9uZX0oJ3V0YycpXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbb2Zmc2V0PTBdIC0gb3B0aW9uYWxseSwgYW4gb2Zmc2V0IGZyb20gVVRDIGluIG1pbnV0ZXNcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRzPXt9XSAtIG9wdGlvbnMgdG8gcGFzcyB0byBgc2V0Wm9uZSgpYFxuICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICovXG4gIHRvVVRDKG9mZnNldCA9IDAsIG9wdHMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLnNldFpvbmUoRml4ZWRPZmZzZXRab25lLmluc3RhbmNlKG9mZnNldCksIG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFwiU2V0XCIgdGhlIERhdGVUaW1lJ3Mgem9uZSB0byB0aGUgaG9zdCdzIGxvY2FsIHpvbmUuIFJldHVybnMgYSBuZXdseS1jb25zdHJ1Y3RlZCBEYXRlVGltZS5cbiAgICpcbiAgICogRXF1aXZhbGVudCB0byBgc2V0Wm9uZSgnbG9jYWwnKWBcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICB0b0xvY2FsKCkge1xuICAgIHJldHVybiB0aGlzLnNldFpvbmUoU2V0dGluZ3MuZGVmYXVsdFpvbmUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFwiU2V0XCIgdGhlIERhdGVUaW1lJ3Mgem9uZSB0byBzcGVjaWZpZWQgem9uZS4gUmV0dXJucyBhIG5ld2x5LWNvbnN0cnVjdGVkIERhdGVUaW1lLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0LCB0aGUgc2V0dGVyIGtlZXBzIHRoZSB1bmRlcmx5aW5nIHRpbWUgdGhlIHNhbWUgKGFzIGluLCB0aGUgc2FtZSB0aW1lc3RhbXApLCBidXQgdGhlIG5ldyBpbnN0YW5jZSB3aWxsIHJlcG9ydCBkaWZmZXJlbnQgbG9jYWwgdGltZXMgYW5kIGNvbnNpZGVyIERTVHMgd2hlbiBtYWtpbmcgY29tcHV0YXRpb25zLCBhcyB3aXRoIHtAbGluayBEYXRlVGltZSNwbHVzfS4gWW91IG1heSB3aXNoIHRvIHVzZSB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbH0gYW5kIHtAbGluayBEYXRlVGltZSN0b1VUQ30gd2hpY2ggcHJvdmlkZSBzaW1wbGUgY29udmVuaWVuY2Ugd3JhcHBlcnMgZm9yIGNvbW1vbmx5IHVzZWQgem9uZXMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfFpvbmV9IFt6b25lPSdsb2NhbCddIC0gYSB6b25lIGlkZW50aWZpZXIuIEFzIGEgc3RyaW5nLCB0aGF0IGNhbiBiZSBhbnkgSUFOQSB6b25lIHN1cHBvcnRlZCBieSB0aGUgaG9zdCBlbnZpcm9ubWVudCwgb3IgYSBmaXhlZC1vZmZzZXQgbmFtZSBvZiB0aGUgZm9ybSAnVVRDKzMnLCBvciB0aGUgc3RyaW5ncyAnbG9jYWwnIG9yICd1dGMnLiBZb3UgbWF5IGFsc28gc3VwcGx5IGFuIGluc3RhbmNlIG9mIGEge0BsaW5rIERhdGVUaW1lI1pvbmV9IGNsYXNzLlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnNcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5rZWVwTG9jYWxUaW1lPWZhbHNlXSAtIElmIHRydWUsIGFkanVzdCB0aGUgdW5kZXJseWluZyB0aW1lIHNvIHRoYXQgdGhlIGxvY2FsIHRpbWUgc3RheXMgdGhlIHNhbWUsIGJ1dCBpbiB0aGUgdGFyZ2V0IHpvbmUuIFlvdSBzaG91bGQgcmFyZWx5IG5lZWQgdGhpcy5cbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzZXRab25lKHpvbmUsIHsga2VlcExvY2FsVGltZSA9IGZhbHNlLCBrZWVwQ2FsZW5kYXJUaW1lID0gZmFsc2UgfSA9IHt9KSB7XG4gICAgem9uZSA9IG5vcm1hbGl6ZVpvbmUoem9uZSwgU2V0dGluZ3MuZGVmYXVsdFpvbmUpO1xuICAgIGlmICh6b25lLmVxdWFscyh0aGlzLnpvbmUpKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IGVsc2UgaWYgKCF6b25lLmlzVmFsaWQpIHtcbiAgICAgIHJldHVybiBEYXRlVGltZS5pbnZhbGlkKHVuc3VwcG9ydGVkWm9uZSh6b25lKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBuZXdUUyA9IHRoaXMudHM7XG4gICAgICBpZiAoa2VlcExvY2FsVGltZSB8fCBrZWVwQ2FsZW5kYXJUaW1lKSB7XG4gICAgICAgIGNvbnN0IG9mZnNldEd1ZXNzID0gem9uZS5vZmZzZXQodGhpcy50cyk7XG4gICAgICAgIGNvbnN0IGFzT2JqID0gdGhpcy50b09iamVjdCgpO1xuICAgICAgICBbbmV3VFNdID0gb2JqVG9UUyhhc09iaiwgb2Zmc2V0R3Vlc3MsIHpvbmUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNsb25lKHRoaXMsIHsgdHM6IG5ld1RTLCB6b25lIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBcIlNldFwiIHRoZSBsb2NhbGUsIG51bWJlcmluZ1N5c3RlbSwgb3Igb3V0cHV0Q2FsZW5kYXIuIFJldHVybnMgYSBuZXdseS1jb25zdHJ1Y3RlZCBEYXRlVGltZS5cbiAgICogQHBhcmFtIHtPYmplY3R9IHByb3BlcnRpZXMgLSB0aGUgcHJvcGVydGllcyB0byBzZXRcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNSwgMjUpLnJlY29uZmlndXJlKHsgbG9jYWxlOiAnZW4tR0InIH0pXG4gICAqIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgKi9cbiAgcmVjb25maWd1cmUoeyBsb2NhbGUsIG51bWJlcmluZ1N5c3RlbSwgb3V0cHV0Q2FsZW5kYXIgfSA9IHt9KSB7XG4gICAgY29uc3QgbG9jID0gdGhpcy5sb2MuY2xvbmUoeyBsb2NhbGUsIG51bWJlcmluZ1N5c3RlbSwgb3V0cHV0Q2FsZW5kYXIgfSk7XG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIHsgbG9jIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFwiU2V0XCIgdGhlIGxvY2FsZS4gUmV0dXJucyBhIG5ld2x5LWNvbnN0cnVjdGVkIERhdGVUaW1lLlxuICAgKiBKdXN0IGEgY29udmVuaWVudCBhbGlhcyBmb3IgcmVjb25maWd1cmUoeyBsb2NhbGUgfSlcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNywgNSwgMjUpLnNldExvY2FsZSgnZW4tR0InKVxuICAgKiBAcmV0dXJuIHtEYXRlVGltZX1cbiAgICovXG4gIHNldExvY2FsZShsb2NhbGUpIHtcbiAgICByZXR1cm4gdGhpcy5yZWNvbmZpZ3VyZSh7IGxvY2FsZSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBcIlNldFwiIHRoZSB2YWx1ZXMgb2Ygc3BlY2lmaWVkIHVuaXRzLiBSZXR1cm5zIGEgbmV3bHktY29uc3RydWN0ZWQgRGF0ZVRpbWUuXG4gICAqIFlvdSBjYW4gb25seSBzZXQgdW5pdHMgd2l0aCB0aGlzIG1ldGhvZDsgZm9yIFwic2V0dGluZ1wiIG1ldGFkYXRhLCBzZWUge0BsaW5rIERhdGVUaW1lI3JlY29uZmlndXJlfSBhbmQge0BsaW5rIERhdGVUaW1lI3NldFpvbmV9LlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBhbHNvIHN1cHBvcnRzIHNldHRpbmcgbG9jYWxlLWJhc2VkIHdlZWsgdW5pdHMsIGkuZS4gYGxvY2FsV2Vla2RheWAsIGBsb2NhbFdlZWtOdW1iZXJgIGFuZCBgbG9jYWxXZWVrWWVhcmAuXG4gICAqIFRoZXkgY2Fubm90IGJlIG1peGVkIHdpdGggSVNPLXdlZWsgdW5pdHMgbGlrZSBgd2Vla2RheWAuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZXMgLSBhIG1hcHBpbmcgb2YgdW5pdHMgdG8gbnVtYmVyc1xuICAgKiBAZXhhbXBsZSBkdC5zZXQoeyB5ZWFyOiAyMDE3IH0pXG4gICAqIEBleGFtcGxlIGR0LnNldCh7IGhvdXI6IDgsIG1pbnV0ZTogMzAgfSlcbiAgICogQGV4YW1wbGUgZHQuc2V0KHsgd2Vla2RheTogNSB9KVxuICAgKiBAZXhhbXBsZSBkdC5zZXQoeyB5ZWFyOiAyMDA1LCBvcmRpbmFsOiAyMzQgfSlcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzZXQodmFsdWVzKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB0aGlzO1xuXG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZU9iamVjdCh2YWx1ZXMsIG5vcm1hbGl6ZVVuaXRXaXRoTG9jYWxXZWVrcyk7XG4gICAgY29uc3QgeyBtaW5EYXlzSW5GaXJzdFdlZWssIHN0YXJ0T2ZXZWVrIH0gPSB1c2VzTG9jYWxXZWVrVmFsdWVzKG5vcm1hbGl6ZWQsIHRoaXMubG9jKTtcblxuICAgIGNvbnN0IHNldHRpbmdXZWVrU3R1ZmYgPVxuICAgICAgICAhaXNVbmRlZmluZWQobm9ybWFsaXplZC53ZWVrWWVhcikgfHxcbiAgICAgICAgIWlzVW5kZWZpbmVkKG5vcm1hbGl6ZWQud2Vla051bWJlcikgfHxcbiAgICAgICAgIWlzVW5kZWZpbmVkKG5vcm1hbGl6ZWQud2Vla2RheSksXG4gICAgICBjb250YWluc09yZGluYWwgPSAhaXNVbmRlZmluZWQobm9ybWFsaXplZC5vcmRpbmFsKSxcbiAgICAgIGNvbnRhaW5zR3JlZ29yWWVhciA9ICFpc1VuZGVmaW5lZChub3JtYWxpemVkLnllYXIpLFxuICAgICAgY29udGFpbnNHcmVnb3JNRCA9ICFpc1VuZGVmaW5lZChub3JtYWxpemVkLm1vbnRoKSB8fCAhaXNVbmRlZmluZWQobm9ybWFsaXplZC5kYXkpLFxuICAgICAgY29udGFpbnNHcmVnb3IgPSBjb250YWluc0dyZWdvclllYXIgfHwgY29udGFpbnNHcmVnb3JNRCxcbiAgICAgIGRlZmluaXRlV2Vla0RlZiA9IG5vcm1hbGl6ZWQud2Vla1llYXIgfHwgbm9ybWFsaXplZC53ZWVrTnVtYmVyO1xuXG4gICAgaWYgKChjb250YWluc0dyZWdvciB8fCBjb250YWluc09yZGluYWwpICYmIGRlZmluaXRlV2Vla0RlZikge1xuICAgICAgdGhyb3cgbmV3IENvbmZsaWN0aW5nU3BlY2lmaWNhdGlvbkVycm9yKFxuICAgICAgICBcIkNhbid0IG1peCB3ZWVrWWVhci93ZWVrTnVtYmVyIHVuaXRzIHdpdGggeWVhci9tb250aC9kYXkgb3Igb3JkaW5hbHNcIlxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGFpbnNHcmVnb3JNRCAmJiBjb250YWluc09yZGluYWwpIHtcbiAgICAgIHRocm93IG5ldyBDb25mbGljdGluZ1NwZWNpZmljYXRpb25FcnJvcihcIkNhbid0IG1peCBvcmRpbmFsIGRhdGVzIHdpdGggbW9udGgvZGF5XCIpO1xuICAgIH1cblxuICAgIGxldCBtaXhlZDtcbiAgICBpZiAoc2V0dGluZ1dlZWtTdHVmZikge1xuICAgICAgbWl4ZWQgPSB3ZWVrVG9HcmVnb3JpYW4oXG4gICAgICAgIHsgLi4uZ3JlZ29yaWFuVG9XZWVrKHRoaXMuYywgbWluRGF5c0luRmlyc3RXZWVrLCBzdGFydE9mV2VlayksIC4uLm5vcm1hbGl6ZWQgfSxcbiAgICAgICAgbWluRGF5c0luRmlyc3RXZWVrLFxuICAgICAgICBzdGFydE9mV2Vla1xuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKCFpc1VuZGVmaW5lZChub3JtYWxpemVkLm9yZGluYWwpKSB7XG4gICAgICBtaXhlZCA9IG9yZGluYWxUb0dyZWdvcmlhbih7IC4uLmdyZWdvcmlhblRvT3JkaW5hbCh0aGlzLmMpLCAuLi5ub3JtYWxpemVkIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBtaXhlZCA9IHsgLi4udGhpcy50b09iamVjdCgpLCAuLi5ub3JtYWxpemVkIH07XG5cbiAgICAgIC8vIGlmIHdlIGRpZG4ndCBzZXQgdGhlIGRheSBidXQgd2UgZW5kZWQgdXAgb24gYW4gb3ZlcmZsb3cgZGF0ZSxcbiAgICAgIC8vIHVzZSB0aGUgbGFzdCBkYXkgb2YgdGhlIHJpZ2h0IG1vbnRoXG4gICAgICBpZiAoaXNVbmRlZmluZWQobm9ybWFsaXplZC5kYXkpKSB7XG4gICAgICAgIG1peGVkLmRheSA9IE1hdGgubWluKGRheXNJbk1vbnRoKG1peGVkLnllYXIsIG1peGVkLm1vbnRoKSwgbWl4ZWQuZGF5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBbdHMsIG9dID0gb2JqVG9UUyhtaXhlZCwgdGhpcy5vLCB0aGlzLnpvbmUpO1xuICAgIHJldHVybiBjbG9uZSh0aGlzLCB7IHRzLCBvIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIHBlcmlvZCBvZiB0aW1lIHRvIHRoaXMgRGF0ZVRpbWUgYW5kIHJldHVybiB0aGUgcmVzdWx0aW5nIERhdGVUaW1lXG4gICAqXG4gICAqIEFkZGluZyBob3VycywgbWludXRlcywgc2Vjb25kcywgb3IgbWlsbGlzZWNvbmRzIGluY3JlYXNlcyB0aGUgdGltZXN0YW1wIGJ5IHRoZSByaWdodCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLiBBZGRpbmcgZGF5cywgbW9udGhzLCBvciB5ZWFycyBzaGlmdHMgdGhlIGNhbGVuZGFyLCBhY2NvdW50aW5nIGZvciBEU1RzIGFuZCBsZWFwIHllYXJzIGFsb25nIHRoZSB3YXkuIFRodXMsIGBkdC5wbHVzKHsgaG91cnM6IDI0IH0pYCBtYXkgcmVzdWx0IGluIGEgZGlmZmVyZW50IHRpbWUgdGhhbiBgZHQucGx1cyh7IGRheXM6IDEgfSlgIGlmIHRoZXJlJ3MgYSBEU1Qgc2hpZnQgaW4gYmV0d2Vlbi5cbiAgICogQHBhcmFtIHtEdXJhdGlvbnxPYmplY3R8bnVtYmVyfSBkdXJhdGlvbiAtIFRoZSBhbW91bnQgdG8gYWRkLiBFaXRoZXIgYSBMdXhvbiBEdXJhdGlvbiwgYSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLCB0aGUgb2JqZWN0IGFyZ3VtZW50IHRvIER1cmF0aW9uLmZyb21PYmplY3QoKVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS5wbHVzKDEyMykgLy9+PiBpbiAxMjMgbWlsbGlzZWNvbmRzXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnBsdXMoeyBtaW51dGVzOiAxNSB9KSAvL34+IGluIDE1IG1pbnV0ZXNcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkucGx1cyh7IGRheXM6IDEgfSkgLy9+PiB0aGlzIHRpbWUgdG9tb3Jyb3dcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkucGx1cyh7IGRheXM6IC0xIH0pIC8vfj4gdGhpcyB0aW1lIHllc3RlcmRheVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS5wbHVzKHsgaG91cnM6IDMsIG1pbnV0ZXM6IDEzIH0pIC8vfj4gaW4gMyBociwgMTMgbWluXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnBsdXMoRHVyYXRpb24uZnJvbU9iamVjdCh7IGhvdXJzOiAzLCBtaW51dGVzOiAxMyB9KSkgLy9+PiBpbiAzIGhyLCAxMyBtaW5cbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBwbHVzKGR1cmF0aW9uKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB0aGlzO1xuICAgIGNvbnN0IGR1ciA9IER1cmF0aW9uLmZyb21EdXJhdGlvbkxpa2UoZHVyYXRpb24pO1xuICAgIHJldHVybiBjbG9uZSh0aGlzLCBhZGp1c3RUaW1lKHRoaXMsIGR1cikpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1YnRyYWN0IGEgcGVyaW9kIG9mIHRpbWUgdG8gdGhpcyBEYXRlVGltZSBhbmQgcmV0dXJuIHRoZSByZXN1bHRpbmcgRGF0ZVRpbWVcbiAgICogU2VlIHtAbGluayBEYXRlVGltZSNwbHVzfVxuICAgKiBAcGFyYW0ge0R1cmF0aW9ufE9iamVjdHxudW1iZXJ9IGR1cmF0aW9uIC0gVGhlIGFtb3VudCB0byBzdWJ0cmFjdC4gRWl0aGVyIGEgTHV4b24gRHVyYXRpb24sIGEgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcywgdGhlIG9iamVjdCBhcmd1bWVudCB0byBEdXJhdGlvbi5mcm9tT2JqZWN0KClcbiAgIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgKi9cbiAgbWludXMoZHVyYXRpb24pIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIHRoaXM7XG4gICAgY29uc3QgZHVyID0gRHVyYXRpb24uZnJvbUR1cmF0aW9uTGlrZShkdXJhdGlvbikubmVnYXRlKCk7XG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIGFkanVzdFRpbWUodGhpcywgZHVyKSk7XG4gIH1cblxuICAvKipcbiAgICogXCJTZXRcIiB0aGlzIERhdGVUaW1lIHRvIHRoZSBiZWdpbm5pbmcgb2YgYSB1bml0IG9mIHRpbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1bml0IC0gVGhlIHVuaXQgdG8gZ28gdG8gdGhlIGJlZ2lubmluZyBvZi4gQ2FuIGJlICd5ZWFyJywgJ3F1YXJ0ZXInLCAnbW9udGgnLCAnd2VlaycsICdkYXknLCAnaG91cicsICdtaW51dGUnLCAnc2Vjb25kJywgb3IgJ21pbGxpc2Vjb25kJy5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMudXNlTG9jYWxlV2Vla3M9ZmFsc2VdIC0gSWYgdHJ1ZSwgdXNlIHdlZWtzIGJhc2VkIG9uIHRoZSBsb2NhbGUsIGkuZS4gdXNlIHRoZSBsb2NhbGUtZGVwZW5kZW50IHN0YXJ0IG9mIHRoZSB3ZWVrXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTQsIDMsIDMpLnN0YXJ0T2YoJ21vbnRoJykudG9JU09EYXRlKCk7IC8vPT4gJzIwMTQtMDMtMDEnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTQsIDMsIDMpLnN0YXJ0T2YoJ3llYXInKS50b0lTT0RhdGUoKTsgLy89PiAnMjAxNC0wMS0wMSdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNCwgMywgMykuc3RhcnRPZignd2VlaycpLnRvSVNPRGF0ZSgpOyAvLz0+ICcyMDE0LTAzLTAzJywgd2Vla3MgYWx3YXlzIHN0YXJ0IG9uIE1vbmRheXNcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNCwgMywgMywgNSwgMzApLnN0YXJ0T2YoJ2RheScpLnRvSVNPVGltZSgpOyAvLz0+ICcwMDowMC4wMDAtMDU6MDAnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTQsIDMsIDMsIDUsIDMwKS5zdGFydE9mKCdob3VyJykudG9JU09UaW1lKCk7IC8vPT4gJzA1OjAwOjAwLjAwMC0wNTowMCdcbiAgICogQHJldHVybiB7RGF0ZVRpbWV9XG4gICAqL1xuICBzdGFydE9mKHVuaXQsIHsgdXNlTG9jYWxlV2Vla3MgPSBmYWxzZSB9ID0ge30pIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIHRoaXM7XG5cbiAgICBjb25zdCBvID0ge30sXG4gICAgICBub3JtYWxpemVkVW5pdCA9IER1cmF0aW9uLm5vcm1hbGl6ZVVuaXQodW5pdCk7XG4gICAgc3dpdGNoIChub3JtYWxpemVkVW5pdCkge1xuICAgICAgY2FzZSBcInllYXJzXCI6XG4gICAgICAgIG8ubW9udGggPSAxO1xuICAgICAgLy8gZmFsbHMgdGhyb3VnaFxuICAgICAgY2FzZSBcInF1YXJ0ZXJzXCI6XG4gICAgICBjYXNlIFwibW9udGhzXCI6XG4gICAgICAgIG8uZGF5ID0gMTtcbiAgICAgIC8vIGZhbGxzIHRocm91Z2hcbiAgICAgIGNhc2UgXCJ3ZWVrc1wiOlxuICAgICAgY2FzZSBcImRheXNcIjpcbiAgICAgICAgby5ob3VyID0gMDtcbiAgICAgIC8vIGZhbGxzIHRocm91Z2hcbiAgICAgIGNhc2UgXCJob3Vyc1wiOlxuICAgICAgICBvLm1pbnV0ZSA9IDA7XG4gICAgICAvLyBmYWxscyB0aHJvdWdoXG4gICAgICBjYXNlIFwibWludXRlc1wiOlxuICAgICAgICBvLnNlY29uZCA9IDA7XG4gICAgICAvLyBmYWxscyB0aHJvdWdoXG4gICAgICBjYXNlIFwic2Vjb25kc1wiOlxuICAgICAgICBvLm1pbGxpc2Vjb25kID0gMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwibWlsbGlzZWNvbmRzXCI6XG4gICAgICAgIGJyZWFrO1xuICAgICAgLy8gbm8gZGVmYXVsdCwgaW52YWxpZCB1bml0cyB0aHJvdyBpbiBub3JtYWxpemVVbml0KClcbiAgICB9XG5cbiAgICBpZiAobm9ybWFsaXplZFVuaXQgPT09IFwid2Vla3NcIikge1xuICAgICAgaWYgKHVzZUxvY2FsZVdlZWtzKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0T2ZXZWVrID0gdGhpcy5sb2MuZ2V0U3RhcnRPZldlZWsoKTtcbiAgICAgICAgY29uc3QgeyB3ZWVrZGF5IH0gPSB0aGlzO1xuICAgICAgICBpZiAod2Vla2RheSA8IHN0YXJ0T2ZXZWVrKSB7XG4gICAgICAgICAgby53ZWVrTnVtYmVyID0gdGhpcy53ZWVrTnVtYmVyIC0gMTtcbiAgICAgICAgfVxuICAgICAgICBvLndlZWtkYXkgPSBzdGFydE9mV2VlaztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG8ud2Vla2RheSA9IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5vcm1hbGl6ZWRVbml0ID09PSBcInF1YXJ0ZXJzXCIpIHtcbiAgICAgIGNvbnN0IHEgPSBNYXRoLmNlaWwodGhpcy5tb250aCAvIDMpO1xuICAgICAgby5tb250aCA9IChxIC0gMSkgKiAzICsgMTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zZXQobyk7XG4gIH1cblxuICAvKipcbiAgICogXCJTZXRcIiB0aGlzIERhdGVUaW1lIHRvIHRoZSBlbmQgKG1lYW5pbmcgdGhlIGxhc3QgbWlsbGlzZWNvbmQpIG9mIGEgdW5pdCBvZiB0aW1lXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1bml0IC0gVGhlIHVuaXQgdG8gZ28gdG8gdGhlIGVuZCBvZi4gQ2FuIGJlICd5ZWFyJywgJ3F1YXJ0ZXInLCAnbW9udGgnLCAnd2VlaycsICdkYXknLCAnaG91cicsICdtaW51dGUnLCAnc2Vjb25kJywgb3IgJ21pbGxpc2Vjb25kJy5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMudXNlTG9jYWxlV2Vla3M9ZmFsc2VdIC0gSWYgdHJ1ZSwgdXNlIHdlZWtzIGJhc2VkIG9uIHRoZSBsb2NhbGUsIGkuZS4gdXNlIHRoZSBsb2NhbGUtZGVwZW5kZW50IHN0YXJ0IG9mIHRoZSB3ZWVrXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLmxvY2FsKDIwMTQsIDMsIDMpLmVuZE9mKCdtb250aCcpLnRvSVNPKCk7IC8vPT4gJzIwMTQtMDMtMzFUMjM6NTk6NTkuOTk5LTA1OjAwJ1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE0LCAzLCAzKS5lbmRPZigneWVhcicpLnRvSVNPKCk7IC8vPT4gJzIwMTQtMTItMzFUMjM6NTk6NTkuOTk5LTA1OjAwJ1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE0LCAzLCAzKS5lbmRPZignd2VlaycpLnRvSVNPKCk7IC8vID0+ICcyMDE0LTAzLTA5VDIzOjU5OjU5Ljk5OS0wNTowMCcsIHdlZWtzIHN0YXJ0IG9uIE1vbmRheXNcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNCwgMywgMywgNSwgMzApLmVuZE9mKCdkYXknKS50b0lTTygpOyAvLz0+ICcyMDE0LTAzLTAzVDIzOjU5OjU5Ljk5OS0wNTowMCdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNCwgMywgMywgNSwgMzApLmVuZE9mKCdob3VyJykudG9JU08oKTsgLy89PiAnMjAxNC0wMy0wM1QwNTo1OTo1OS45OTktMDU6MDAnXG4gICAqIEByZXR1cm4ge0RhdGVUaW1lfVxuICAgKi9cbiAgZW5kT2YodW5pdCwgb3B0cykge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWRcbiAgICAgID8gdGhpcy5wbHVzKHsgW3VuaXRdOiAxIH0pXG4gICAgICAgICAgLnN0YXJ0T2YodW5pdCwgb3B0cylcbiAgICAgICAgICAubWludXMoMSlcbiAgICAgIDogdGhpcztcbiAgfVxuXG4gIC8vIE9VVFBVVFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRGF0ZVRpbWUgZm9ybWF0dGVkIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGZvcm1hdCBzdHJpbmcuXG4gICAqICoqWW91IG1heSBub3Qgd2FudCB0aGlzLioqIFNlZSB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvciBhIG1vcmUgZmxleGlibGUgZm9ybWF0dGluZyB0b29sLiBGb3IgYSB0YWJsZSBvZiB0b2tlbnMgYW5kIHRoZWlyIGludGVycHJldGF0aW9ucywgc2VlIFtoZXJlXShodHRwczovL21vbWVudC5naXRodWIuaW8vbHV4b24vIy9mb3JtYXR0aW5nP2lkPXRhYmxlLW9mLXRva2VucykuXG4gICAqIERlZmF1bHRzIHRvIGVuLVVTIGlmIG5vIGxvY2FsZSBoYXMgYmVlbiBzcGVjaWZpZWQsIHJlZ2FyZGxlc3Mgb2YgdGhlIHN5c3RlbSdzIGxvY2FsZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZtdCAtIHRoZSBmb3JtYXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0cyB0byBvdmVycmlkZSB0aGUgY29uZmlndXJhdGlvbiBvcHRpb25zIG9uIHRoaXMgRGF0ZVRpbWVcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkudG9Gb3JtYXQoJ3l5eXkgTExMIGRkJykgLy89PiAnMjAxNyBBcHIgMjInXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnNldExvY2FsZSgnZnInKS50b0Zvcm1hdCgneXl5eSBMTEwgZGQnKSAvLz0+ICcyMDE3IGF2ci4gMjInXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnRvRm9ybWF0KCd5eXl5IExMTCBkZCcsIHsgbG9jYWxlOiBcImZyXCIgfSkgLy89PiAnMjAxNyBhdnIuIDIyJ1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS50b0Zvcm1hdChcIkhIICdob3VycyBhbmQnIG1tICdtaW51dGVzJ1wiKSAvLz0+ICcyMCBob3VycyBhbmQgNTUgbWludXRlcydcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9Gb3JtYXQoZm10LCBvcHRzID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkXG4gICAgICA/IEZvcm1hdHRlci5jcmVhdGUodGhpcy5sb2MucmVkZWZhdWx0VG9FTihvcHRzKSkuZm9ybWF0RGF0ZVRpbWVGcm9tU3RyaW5nKHRoaXMsIGZtdClcbiAgICAgIDogSU5WQUxJRDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbG9jYWxpemVkIHN0cmluZyByZXByZXNlbnRpbmcgdGhpcyBkYXRlLiBBY2NlcHRzIHRoZSBzYW1lIG9wdGlvbnMgYXMgdGhlIEludGwuRGF0ZVRpbWVGb3JtYXQgY29uc3RydWN0b3IgYW5kIGFueSBwcmVzZXRzIGRlZmluZWQgYnkgTHV4b24sIHN1Y2ggYXMgYERhdGVUaW1lLkRBVEVfRlVMTGAgb3IgYERhdGVUaW1lLlRJTUVfU0lNUExFYC5cbiAgICogVGhlIGV4YWN0IGJlaGF2aW9yIG9mIHRoaXMgbWV0aG9kIGlzIGJyb3dzZXItc3BlY2lmaWMsIGJ1dCBpbiBnZW5lcmFsIGl0IHdpbGwgcmV0dXJuIGFuIGFwcHJvcHJpYXRlIHJlcHJlc2VudGF0aW9uXG4gICAqIG9mIHRoZSBEYXRlVGltZSBpbiB0aGUgYXNzaWduZWQgbG9jYWxlLlxuICAgKiBEZWZhdWx0cyB0byB0aGUgc3lzdGVtJ3MgbG9jYWxlIGlmIG5vIGxvY2FsZSBoYXMgYmVlbiBzcGVjaWZpZWRcbiAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9EYXRlVGltZUZvcm1hdFxuICAgKiBAcGFyYW0gZm9ybWF0T3B0cyB7T2JqZWN0fSAtIEludGwuRGF0ZVRpbWVGb3JtYXQgY29uc3RydWN0b3Igb3B0aW9ucyBhbmQgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0cyB0byBvdmVycmlkZSB0aGUgY29uZmlndXJhdGlvbiBvcHRpb25zIG9uIHRoaXMgRGF0ZVRpbWVcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkudG9Mb2NhbGVTdHJpbmcoKTsgLy89PiA0LzIwLzIwMTdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkuc2V0TG9jYWxlKCdlbi1nYicpLnRvTG9jYWxlU3RyaW5nKCk7IC8vPT4gJzIwLzA0LzIwMTcnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnRvTG9jYWxlU3RyaW5nKERhdGVUaW1lLkRBVEVfRlVMTCk7IC8vPT4gJ0FwcmlsIDIwLCAyMDE3J1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS50b0xvY2FsZVN0cmluZyhEYXRlVGltZS5EQVRFX0ZVTEwsIHsgbG9jYWxlOiAnZnInIH0pOyAvLz0+ICcyOCBhb1x1MDBGQnQgMjAyMidcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkudG9Mb2NhbGVTdHJpbmcoRGF0ZVRpbWUuVElNRV9TSU1QTEUpOyAvLz0+ICcxMTozMiBBTSdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkudG9Mb2NhbGVTdHJpbmcoRGF0ZVRpbWUuREFURVRJTUVfU0hPUlQpOyAvLz0+ICc0LzIwLzIwMTcsIDExOjMyIEFNJ1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS50b0xvY2FsZVN0cmluZyh7IHdlZWtkYXk6ICdsb25nJywgbW9udGg6ICdsb25nJywgZGF5OiAnMi1kaWdpdCcgfSk7IC8vPT4gJ1RodXJzZGF5LCBBcHJpbCAyMCdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkudG9Mb2NhbGVTdHJpbmcoeyB3ZWVrZGF5OiAnc2hvcnQnLCBtb250aDogJ3Nob3J0JywgZGF5OiAnMi1kaWdpdCcsIGhvdXI6ICcyLWRpZ2l0JywgbWludXRlOiAnMi1kaWdpdCcgfSk7IC8vPT4gJ1RodSwgQXByIDIwLCAxMToyNyBBTSdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkudG9Mb2NhbGVTdHJpbmcoeyBob3VyOiAnMi1kaWdpdCcsIG1pbnV0ZTogJzItZGlnaXQnLCBob3VyQ3ljbGU6ICdoMjMnIH0pOyAvLz0+ICcxMTozMidcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9Mb2NhbGVTdHJpbmcoZm9ybWF0T3B0cyA9IEZvcm1hdHMuREFURV9TSE9SVCwgb3B0cyA9IHt9KSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZFxuICAgICAgPyBGb3JtYXR0ZXIuY3JlYXRlKHRoaXMubG9jLmNsb25lKG9wdHMpLCBmb3JtYXRPcHRzKS5mb3JtYXREYXRlVGltZSh0aGlzKVxuICAgICAgOiBJTlZBTElEO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gYXJyYXkgb2YgZm9ybWF0IFwicGFydHNcIiwgbWVhbmluZyBpbmRpdmlkdWFsIHRva2VucyBhbG9uZyB3aXRoIG1ldGFkYXRhLiBUaGlzIGlzIGFsbG93cyBjYWxsZXJzIHRvIHBvc3QtcHJvY2VzcyBpbmRpdmlkdWFsIHNlY3Rpb25zIG9mIHRoZSBmb3JtYXR0ZWQgb3V0cHV0LlxuICAgKiBEZWZhdWx0cyB0byB0aGUgc3lzdGVtJ3MgbG9jYWxlIGlmIG5vIGxvY2FsZSBoYXMgYmVlbiBzcGVjaWZpZWRcbiAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9EYXRlVGltZUZvcm1hdC9mb3JtYXRUb1BhcnRzXG4gICAqIEBwYXJhbSBvcHRzIHtPYmplY3R9IC0gSW50bC5EYXRlVGltZUZvcm1hdCBjb25zdHJ1Y3RvciBvcHRpb25zLCBzYW1lIGFzIGB0b0xvY2FsZVN0cmluZ2AuXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnRvTG9jYWxlUGFydHMoKTsgLy89PiBbXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLz0+ICAgeyB0eXBlOiAnZGF5JywgdmFsdWU6ICcyNScgfSxcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vPT4gICB7IHR5cGU6ICdsaXRlcmFsJywgdmFsdWU6ICcvJyB9LFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy89PiAgIHsgdHlwZTogJ21vbnRoJywgdmFsdWU6ICcwNScgfSxcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vPT4gICB7IHR5cGU6ICdsaXRlcmFsJywgdmFsdWU6ICcvJyB9LFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy89PiAgIHsgdHlwZTogJ3llYXInLCB2YWx1ZTogJzE5ODInIH1cbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vPT4gXVxuICAgKi9cbiAgdG9Mb2NhbGVQYXJ0cyhvcHRzID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbGlkXG4gICAgICA/IEZvcm1hdHRlci5jcmVhdGUodGhpcy5sb2MuY2xvbmUob3B0cyksIG9wdHMpLmZvcm1hdERhdGVUaW1lUGFydHModGhpcylcbiAgICAgIDogW107XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBJU08gODYwMS1jb21wbGlhbnQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRGF0ZVRpbWVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuc3VwcHJlc3NNaWxsaXNlY29uZHM9ZmFsc2VdIC0gZXhjbHVkZSBtaWxsaXNlY29uZHMgZnJvbSB0aGUgZm9ybWF0IGlmIHRoZXkncmUgMFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLnN1cHByZXNzU2Vjb25kcz1mYWxzZV0gLSBleGNsdWRlIHNlY29uZHMgZnJvbSB0aGUgZm9ybWF0IGlmIHRoZXkncmUgMFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmluY2x1ZGVPZmZzZXQ9dHJ1ZV0gLSBpbmNsdWRlIHRoZSBvZmZzZXQsIHN1Y2ggYXMgJ1onIG9yICctMDQ6MDAnXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuZXh0ZW5kZWRab25lPWZhbHNlXSAtIGFkZCB0aGUgdGltZSB6b25lIGZvcm1hdCBleHRlbnNpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmZvcm1hdD0nZXh0ZW5kZWQnXSAtIGNob29zZSBiZXR3ZWVuIHRoZSBiYXNpYyBhbmQgZXh0ZW5kZWQgZm9ybWF0XG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygxOTgzLCA1LCAyNSkudG9JU08oKSAvLz0+ICcxOTgyLTA1LTI1VDAwOjAwOjAwLjAwMFonXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnRvSVNPKCkgLy89PiAnMjAxNy0wNC0yMlQyMDo0NzowNS4zMzUtMDQ6MDAnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnRvSVNPKHsgaW5jbHVkZU9mZnNldDogZmFsc2UgfSkgLy89PiAnMjAxNy0wNC0yMlQyMDo0NzowNS4zMzUnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnRvSVNPKHsgZm9ybWF0OiAnYmFzaWMnIH0pIC8vPT4gJzIwMTcwNDIyVDIwNDcwNS4zMzUtMDQwMCdcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9JU08oe1xuICAgIGZvcm1hdCA9IFwiZXh0ZW5kZWRcIixcbiAgICBzdXBwcmVzc1NlY29uZHMgPSBmYWxzZSxcbiAgICBzdXBwcmVzc01pbGxpc2Vjb25kcyA9IGZhbHNlLFxuICAgIGluY2x1ZGVPZmZzZXQgPSB0cnVlLFxuICAgIGV4dGVuZGVkWm9uZSA9IGZhbHNlLFxuICB9ID0ge30pIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgZXh0ID0gZm9ybWF0ID09PSBcImV4dGVuZGVkXCI7XG5cbiAgICBsZXQgYyA9IHRvSVNPRGF0ZSh0aGlzLCBleHQpO1xuICAgIGMgKz0gXCJUXCI7XG4gICAgYyArPSB0b0lTT1RpbWUodGhpcywgZXh0LCBzdXBwcmVzc1NlY29uZHMsIHN1cHByZXNzTWlsbGlzZWNvbmRzLCBpbmNsdWRlT2Zmc2V0LCBleHRlbmRlZFpvbmUpO1xuICAgIHJldHVybiBjO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gSVNPIDg2MDEtY29tcGxpYW50IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIERhdGVUaW1lJ3MgZGF0ZSBjb21wb25lbnRcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5mb3JtYXQ9J2V4dGVuZGVkJ10gLSBjaG9vc2UgYmV0d2VlbiB0aGUgYmFzaWMgYW5kIGV4dGVuZGVkIGZvcm1hdFxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS51dGMoMTk4MiwgNSwgMjUpLnRvSVNPRGF0ZSgpIC8vPT4gJzE5ODItMDUtMjUnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygxOTgyLCA1LCAyNSkudG9JU09EYXRlKHsgZm9ybWF0OiAnYmFzaWMnIH0pIC8vPT4gJzE5ODIwNTI1J1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b0lTT0RhdGUoeyBmb3JtYXQgPSBcImV4dGVuZGVkXCIgfSA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0b0lTT0RhdGUodGhpcywgZm9ybWF0ID09PSBcImV4dGVuZGVkXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gSVNPIDg2MDEtY29tcGxpYW50IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIERhdGVUaW1lJ3Mgd2VlayBkYXRlXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygxOTgyLCA1LCAyNSkudG9JU09XZWVrRGF0ZSgpIC8vPT4gJzE5ODItVzIxLTInXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICovXG4gIHRvSVNPV2Vla0RhdGUoKSB7XG4gICAgcmV0dXJuIHRvVGVjaEZvcm1hdCh0aGlzLCBcImtra2stJ1cnV1ctY1wiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIElTTyA4NjAxLWNvbXBsaWFudCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBEYXRlVGltZSdzIHRpbWUgY29tcG9uZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0aW9uc1xuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLnN1cHByZXNzTWlsbGlzZWNvbmRzPWZhbHNlXSAtIGV4Y2x1ZGUgbWlsbGlzZWNvbmRzIGZyb20gdGhlIGZvcm1hdCBpZiB0aGV5J3JlIDBcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5zdXBwcmVzc1NlY29uZHM9ZmFsc2VdIC0gZXhjbHVkZSBzZWNvbmRzIGZyb20gdGhlIGZvcm1hdCBpZiB0aGV5J3JlIDBcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5pbmNsdWRlT2Zmc2V0PXRydWVdIC0gaW5jbHVkZSB0aGUgb2Zmc2V0LCBzdWNoIGFzICdaJyBvciAnLTA0OjAwJ1xuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmV4dGVuZGVkWm9uZT10cnVlXSAtIGFkZCB0aGUgdGltZSB6b25lIGZvcm1hdCBleHRlbnNpb25cbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5pbmNsdWRlUHJlZml4PWZhbHNlXSAtIGluY2x1ZGUgdGhlIGBUYCBwcmVmaXhcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmZvcm1hdD0nZXh0ZW5kZWQnXSAtIGNob29zZSBiZXR3ZWVuIHRoZSBiYXNpYyBhbmQgZXh0ZW5kZWQgZm9ybWF0XG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygpLnNldCh7IGhvdXI6IDcsIG1pbnV0ZTogMzQgfSkudG9JU09UaW1lKCkgLy89PiAnMDc6MzQ6MTkuMzYxWidcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUudXRjKCkuc2V0KHsgaG91cjogNywgbWludXRlOiAzNCwgc2Vjb25kczogMCwgbWlsbGlzZWNvbmRzOiAwIH0pLnRvSVNPVGltZSh7IHN1cHByZXNzU2Vjb25kczogdHJ1ZSB9KSAvLz0+ICcwNzozNFonXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygpLnNldCh7IGhvdXI6IDcsIG1pbnV0ZTogMzQgfSkudG9JU09UaW1lKHsgZm9ybWF0OiAnYmFzaWMnIH0pIC8vPT4gJzA3MzQxOS4zNjFaJ1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS51dGMoKS5zZXQoeyBob3VyOiA3LCBtaW51dGU6IDM0IH0pLnRvSVNPVGltZSh7IGluY2x1ZGVQcmVmaXg6IHRydWUgfSkgLy89PiAnVDA3OjM0OjE5LjM2MVonXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICovXG4gIHRvSVNPVGltZSh7XG4gICAgc3VwcHJlc3NNaWxsaXNlY29uZHMgPSBmYWxzZSxcbiAgICBzdXBwcmVzc1NlY29uZHMgPSBmYWxzZSxcbiAgICBpbmNsdWRlT2Zmc2V0ID0gdHJ1ZSxcbiAgICBpbmNsdWRlUHJlZml4ID0gZmFsc2UsXG4gICAgZXh0ZW5kZWRab25lID0gZmFsc2UsXG4gICAgZm9ybWF0ID0gXCJleHRlbmRlZFwiLFxuICB9ID0ge30pIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbGV0IGMgPSBpbmNsdWRlUHJlZml4ID8gXCJUXCIgOiBcIlwiO1xuICAgIHJldHVybiAoXG4gICAgICBjICtcbiAgICAgIHRvSVNPVGltZShcbiAgICAgICAgdGhpcyxcbiAgICAgICAgZm9ybWF0ID09PSBcImV4dGVuZGVkXCIsXG4gICAgICAgIHN1cHByZXNzU2Vjb25kcyxcbiAgICAgICAgc3VwcHJlc3NNaWxsaXNlY29uZHMsXG4gICAgICAgIGluY2x1ZGVPZmZzZXQsXG4gICAgICAgIGV4dGVuZGVkWm9uZVxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBSRkMgMjgyMi1jb21wYXRpYmxlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIERhdGVUaW1lXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygyMDE0LCA3LCAxMykudG9SRkMyODIyKCkgLy89PiAnU3VuLCAxMyBKdWwgMjAxNCAwMDowMDowMCArMDAwMCdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNCwgNywgMTMpLnRvUkZDMjgyMigpIC8vPT4gJ1N1biwgMTMgSnVsIDIwMTQgMDA6MDA6MDAgLTA0MDAnXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICovXG4gIHRvUkZDMjgyMigpIHtcbiAgICByZXR1cm4gdG9UZWNoRm9ybWF0KHRoaXMsIFwiRUVFLCBkZCBMTEwgeXl5eSBISDptbTpzcyBaWlpcIiwgZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBEYXRlVGltZSBhcHByb3ByaWF0ZSBmb3IgdXNlIGluIEhUVFAgaGVhZGVycy4gVGhlIG91dHB1dCBpcyBhbHdheXMgZXhwcmVzc2VkIGluIEdNVC5cbiAgICogU3BlY2lmaWNhbGx5LCB0aGUgc3RyaW5nIGNvbmZvcm1zIHRvIFJGQyAxMTIzLlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9Qcm90b2NvbHMvcmZjMjYxNi9yZmMyNjE2LXNlYzMuaHRtbCNzZWMzLjMuMVxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS51dGMoMjAxNCwgNywgMTMpLnRvSFRUUCgpIC8vPT4gJ1N1biwgMTMgSnVsIDIwMTQgMDA6MDA6MDAgR01UJ1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS51dGMoMjAxNCwgNywgMTMsIDE5KS50b0hUVFAoKSAvLz0+ICdTdW4sIDEzIEp1bCAyMDE0IDE5OjAwOjAwIEdNVCdcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9IVFRQKCkge1xuICAgIHJldHVybiB0b1RlY2hGb3JtYXQodGhpcy50b1VUQygpLCBcIkVFRSwgZGQgTExMIHl5eXkgSEg6bW06c3MgJ0dNVCdcIik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIERhdGVUaW1lIGFwcHJvcHJpYXRlIGZvciB1c2UgaW4gU1FMIERhdGVcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUudXRjKDIwMTQsIDcsIDEzKS50b1NRTERhdGUoKSAvLz0+ICcyMDE0LTA3LTEzJ1xuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b1NRTERhdGUoKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gdG9JU09EYXRlKHRoaXMsIHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBEYXRlVGltZSBhcHByb3ByaWF0ZSBmb3IgdXNlIGluIFNRTCBUaW1lXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0aW9uc1xuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmluY2x1ZGVab25lPWZhbHNlXSAtIGluY2x1ZGUgdGhlIHpvbmUsIHN1Y2ggYXMgJ0FtZXJpY2EvTmV3X1lvcmsnLiBPdmVycmlkZXMgaW5jbHVkZU9mZnNldC5cbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5pbmNsdWRlT2Zmc2V0PXRydWVdIC0gaW5jbHVkZSB0aGUgb2Zmc2V0LCBzdWNoIGFzICdaJyBvciAnLTA0OjAwJ1xuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmluY2x1ZGVPZmZzZXRTcGFjZT10cnVlXSAtIGluY2x1ZGUgdGhlIHNwYWNlIGJldHdlZW4gdGhlIHRpbWUgYW5kIHRoZSBvZmZzZXQsIHN1Y2ggYXMgJzA1OjE1OjE2LjM0NSAtMDQ6MDAnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLnV0YygpLnRvU1FMKCkgLy89PiAnMDU6MTU6MTYuMzQ1J1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS50b1NRTCgpIC8vPT4gJzA1OjE1OjE2LjM0NSAtMDQ6MDAnXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnRvU1FMKHsgaW5jbHVkZU9mZnNldDogZmFsc2UgfSkgLy89PiAnMDU6MTU6MTYuMzQ1J1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS50b1NRTCh7IGluY2x1ZGVab25lOiBmYWxzZSB9KSAvLz0+ICcwNToxNToxNi4zNDUgQW1lcmljYS9OZXdfWW9yaydcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9TUUxUaW1lKHsgaW5jbHVkZU9mZnNldCA9IHRydWUsIGluY2x1ZGVab25lID0gZmFsc2UsIGluY2x1ZGVPZmZzZXRTcGFjZSA9IHRydWUgfSA9IHt9KSB7XG4gICAgbGV0IGZtdCA9IFwiSEg6bW06c3MuU1NTXCI7XG5cbiAgICBpZiAoaW5jbHVkZVpvbmUgfHwgaW5jbHVkZU9mZnNldCkge1xuICAgICAgaWYgKGluY2x1ZGVPZmZzZXRTcGFjZSkge1xuICAgICAgICBmbXQgKz0gXCIgXCI7XG4gICAgICB9XG4gICAgICBpZiAoaW5jbHVkZVpvbmUpIHtcbiAgICAgICAgZm10ICs9IFwielwiO1xuICAgICAgfSBlbHNlIGlmIChpbmNsdWRlT2Zmc2V0KSB7XG4gICAgICAgIGZtdCArPSBcIlpaXCI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRvVGVjaEZvcm1hdCh0aGlzLCBmbXQsIHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBEYXRlVGltZSBhcHByb3ByaWF0ZSBmb3IgdXNlIGluIFNRTCBEYXRlVGltZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnNcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5pbmNsdWRlWm9uZT1mYWxzZV0gLSBpbmNsdWRlIHRoZSB6b25lLCBzdWNoIGFzICdBbWVyaWNhL05ld19Zb3JrJy4gT3ZlcnJpZGVzIGluY2x1ZGVPZmZzZXQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuaW5jbHVkZU9mZnNldD10cnVlXSAtIGluY2x1ZGUgdGhlIG9mZnNldCwgc3VjaCBhcyAnWicgb3IgJy0wNDowMCdcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5pbmNsdWRlT2Zmc2V0U3BhY2U9dHJ1ZV0gLSBpbmNsdWRlIHRoZSBzcGFjZSBiZXR3ZWVuIHRoZSB0aW1lIGFuZCB0aGUgb2Zmc2V0LCBzdWNoIGFzICcwNToxNToxNi4zNDUgLTA0OjAwJ1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS51dGMoMjAxNCwgNywgMTMpLnRvU1FMKCkgLy89PiAnMjAxNC0wNy0xMyAwMDowMDowMC4wMDAgWidcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNCwgNywgMTMpLnRvU1FMKCkgLy89PiAnMjAxNC0wNy0xMyAwMDowMDowMC4wMDAgLTA0OjAwJ1xuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5sb2NhbCgyMDE0LCA3LCAxMykudG9TUUwoeyBpbmNsdWRlT2Zmc2V0OiBmYWxzZSB9KSAvLz0+ICcyMDE0LTA3LTEzIDAwOjAwOjAwLjAwMCdcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubG9jYWwoMjAxNCwgNywgMTMpLnRvU1FMKHsgaW5jbHVkZVpvbmU6IHRydWUgfSkgLy89PiAnMjAxNC0wNy0xMyAwMDowMDowMC4wMDAgQW1lcmljYS9OZXdfWW9yaydcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9TUUwob3B0cyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBgJHt0aGlzLnRvU1FMRGF0ZSgpfSAke3RoaXMudG9TUUxUaW1lKG9wdHMpfWA7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIERhdGVUaW1lIGFwcHJvcHJpYXRlIGZvciBkZWJ1Z2dpbmdcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IHRoaXMudG9JU08oKSA6IElOVkFMSUQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIERhdGVUaW1lIGFwcHJvcHJpYXRlIGZvciB0aGUgUkVQTC5cbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgW1N5bWJvbC5mb3IoXCJub2RlanMudXRpbC5pbnNwZWN0LmN1c3RvbVwiKV0oKSB7XG4gICAgaWYgKHRoaXMuaXNWYWxpZCkge1xuICAgICAgcmV0dXJuIGBEYXRlVGltZSB7IHRzOiAke3RoaXMudG9JU08oKX0sIHpvbmU6ICR7dGhpcy56b25lLm5hbWV9LCBsb2NhbGU6ICR7dGhpcy5sb2NhbGV9IH1gO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYERhdGVUaW1lIHsgSW52YWxpZCwgcmVhc29uOiAke3RoaXMuaW52YWxpZFJlYXNvbn0gfWA7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGVwb2NoIG1pbGxpc2Vjb25kcyBvZiB0aGlzIERhdGVUaW1lLiBBbGlhcyBvZiB7QGxpbmsgRGF0ZVRpbWUjdG9NaWxsaXN9XG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIHZhbHVlT2YoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9NaWxsaXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBlcG9jaCBtaWxsaXNlY29uZHMgb2YgdGhpcyBEYXRlVGltZS5cbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgdG9NaWxsaXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IHRoaXMudHMgOiBOYU47XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZXBvY2ggc2Vjb25kcyBvZiB0aGlzIERhdGVUaW1lLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICB0b1NlY29uZHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZCA/IHRoaXMudHMgLyAxMDAwIDogTmFOO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGVwb2NoIHNlY29uZHMgKGFzIGEgd2hvbGUgbnVtYmVyKSBvZiB0aGlzIERhdGVUaW1lLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICB0b1VuaXhJbnRlZ2VyKCkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyBNYXRoLmZsb29yKHRoaXMudHMgLyAxMDAwKSA6IE5hTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIElTTyA4NjAxIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRGF0ZVRpbWUgYXBwcm9wcmlhdGUgZm9yIHVzZSBpbiBKU09OLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b0pTT04oKSB7XG4gICAgcmV0dXJuIHRoaXMudG9JU08oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgQlNPTiBzZXJpYWxpemFibGUgZXF1aXZhbGVudCB0byB0aGlzIERhdGVUaW1lLlxuICAgKiBAcmV0dXJuIHtEYXRlfVxuICAgKi9cbiAgdG9CU09OKCkge1xuICAgIHJldHVybiB0aGlzLnRvSlNEYXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIEphdmFTY3JpcHQgb2JqZWN0IHdpdGggdGhpcyBEYXRlVGltZSdzIHllYXIsIG1vbnRoLCBkYXksIGFuZCBzbyBvbi5cbiAgICogQHBhcmFtIG9wdHMgLSBvcHRpb25zIGZvciBnZW5lcmF0aW5nIHRoZSBvYmplY3RcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5pbmNsdWRlQ29uZmlnPWZhbHNlXSAtIGluY2x1ZGUgY29uZmlndXJhdGlvbiBhdHRyaWJ1dGVzIGluIHRoZSBvdXRwdXRcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkudG9PYmplY3QoKSAvLz0+IHsgeWVhcjogMjAxNywgbW9udGg6IDQsIGRheTogMjIsIGhvdXI6IDIwLCBtaW51dGU6IDQ5LCBzZWNvbmQ6IDQyLCBtaWxsaXNlY29uZDogMjY4IH1cbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgdG9PYmplY3Qob3B0cyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiB7fTtcblxuICAgIGNvbnN0IGJhc2UgPSB7IC4uLnRoaXMuYyB9O1xuXG4gICAgaWYgKG9wdHMuaW5jbHVkZUNvbmZpZykge1xuICAgICAgYmFzZS5vdXRwdXRDYWxlbmRhciA9IHRoaXMub3V0cHV0Q2FsZW5kYXI7XG4gICAgICBiYXNlLm51bWJlcmluZ1N5c3RlbSA9IHRoaXMubG9jLm51bWJlcmluZ1N5c3RlbTtcbiAgICAgIGJhc2UubG9jYWxlID0gdGhpcy5sb2MubG9jYWxlO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgSmF2YVNjcmlwdCBEYXRlIGVxdWl2YWxlbnQgdG8gdGhpcyBEYXRlVGltZS5cbiAgICogQHJldHVybiB7RGF0ZX1cbiAgICovXG4gIHRvSlNEYXRlKCkge1xuICAgIHJldHVybiBuZXcgRGF0ZSh0aGlzLmlzVmFsaWQgPyB0aGlzLnRzIDogTmFOKTtcbiAgfVxuXG4gIC8vIENPTVBBUkVcblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIERhdGVUaW1lcyBhcyBhIER1cmF0aW9uLlxuICAgKiBAcGFyYW0ge0RhdGVUaW1lfSBvdGhlckRhdGVUaW1lIC0gdGhlIERhdGVUaW1lIHRvIGNvbXBhcmUgdGhpcyBvbmUgdG9cbiAgICogQHBhcmFtIHtzdHJpbmd8c3RyaW5nW119IFt1bml0PVsnbWlsbGlzZWNvbmRzJ11dIC0gdGhlIHVuaXQgb3IgYXJyYXkgb2YgdW5pdHMgKHN1Y2ggYXMgJ2hvdXJzJyBvciAnZGF5cycpIHRvIGluY2x1ZGUgaW4gdGhlIGR1cmF0aW9uLlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cyAtIG9wdGlvbnMgdGhhdCBhZmZlY3QgdGhlIGNyZWF0aW9uIG9mIHRoZSBEdXJhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuY29udmVyc2lvbkFjY3VyYWN5PSdjYXN1YWwnXSAtIHRoZSBjb252ZXJzaW9uIHN5c3RlbSB0byB1c2VcbiAgICogQGV4YW1wbGVcbiAgICogdmFyIGkxID0gRGF0ZVRpbWUuZnJvbUlTTygnMTk4Mi0wNS0yNVQwOTo0NScpLFxuICAgKiAgICAgaTIgPSBEYXRlVGltZS5mcm9tSVNPKCcxOTgzLTEwLTE0VDEwOjMwJyk7XG4gICAqIGkyLmRpZmYoaTEpLnRvT2JqZWN0KCkgLy89PiB7IG1pbGxpc2Vjb25kczogNDM4MDc1MDAwMDAgfVxuICAgKiBpMi5kaWZmKGkxLCAnaG91cnMnKS50b09iamVjdCgpIC8vPT4geyBob3VyczogMTIxNjguNzUgfVxuICAgKiBpMi5kaWZmKGkxLCBbJ21vbnRocycsICdkYXlzJ10pLnRvT2JqZWN0KCkgLy89PiB7IG1vbnRoczogMTYsIGRheXM6IDE5LjAzMTI1IH1cbiAgICogaTIuZGlmZihpMSwgWydtb250aHMnLCAnZGF5cycsICdob3VycyddKS50b09iamVjdCgpIC8vPT4geyBtb250aHM6IDE2LCBkYXlzOiAxOSwgaG91cnM6IDAuNzUgfVxuICAgKiBAcmV0dXJuIHtEdXJhdGlvbn1cbiAgICovXG4gIGRpZmYob3RoZXJEYXRlVGltZSwgdW5pdCA9IFwibWlsbGlzZWNvbmRzXCIsIG9wdHMgPSB7fSkge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkIHx8ICFvdGhlckRhdGVUaW1lLmlzVmFsaWQpIHtcbiAgICAgIHJldHVybiBEdXJhdGlvbi5pbnZhbGlkKFwiY3JlYXRlZCBieSBkaWZmaW5nIGFuIGludmFsaWQgRGF0ZVRpbWVcIik7XG4gICAgfVxuXG4gICAgY29uc3QgZHVyT3B0cyA9IHsgbG9jYWxlOiB0aGlzLmxvY2FsZSwgbnVtYmVyaW5nU3lzdGVtOiB0aGlzLm51bWJlcmluZ1N5c3RlbSwgLi4ub3B0cyB9O1xuXG4gICAgY29uc3QgdW5pdHMgPSBtYXliZUFycmF5KHVuaXQpLm1hcChEdXJhdGlvbi5ub3JtYWxpemVVbml0KSxcbiAgICAgIG90aGVySXNMYXRlciA9IG90aGVyRGF0ZVRpbWUudmFsdWVPZigpID4gdGhpcy52YWx1ZU9mKCksXG4gICAgICBlYXJsaWVyID0gb3RoZXJJc0xhdGVyID8gdGhpcyA6IG90aGVyRGF0ZVRpbWUsXG4gICAgICBsYXRlciA9IG90aGVySXNMYXRlciA/IG90aGVyRGF0ZVRpbWUgOiB0aGlzLFxuICAgICAgZGlmZmVkID0gZGlmZihlYXJsaWVyLCBsYXRlciwgdW5pdHMsIGR1ck9wdHMpO1xuXG4gICAgcmV0dXJuIG90aGVySXNMYXRlciA/IGRpZmZlZC5uZWdhdGUoKSA6IGRpZmZlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGlzIERhdGVUaW1lIGFuZCByaWdodCBub3cuXG4gICAqIFNlZSB7QGxpbmsgRGF0ZVRpbWUjZGlmZn1cbiAgICogQHBhcmFtIHtzdHJpbmd8c3RyaW5nW119IFt1bml0PVsnbWlsbGlzZWNvbmRzJ11dIC0gdGhlIHVuaXQgb3IgdW5pdHMgdW5pdHMgKHN1Y2ggYXMgJ2hvdXJzJyBvciAnZGF5cycpIHRvIGluY2x1ZGUgaW4gdGhlIGR1cmF0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gb3B0aW9ucyB0aGF0IGFmZmVjdCB0aGUgY3JlYXRpb24gb2YgdGhlIER1cmF0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5jb252ZXJzaW9uQWNjdXJhY3k9J2Nhc3VhbCddIC0gdGhlIGNvbnZlcnNpb24gc3lzdGVtIHRvIHVzZVxuICAgKiBAcmV0dXJuIHtEdXJhdGlvbn1cbiAgICovXG4gIGRpZmZOb3codW5pdCA9IFwibWlsbGlzZWNvbmRzXCIsIG9wdHMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLmRpZmYoRGF0ZVRpbWUubm93KCksIHVuaXQsIG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbiBJbnRlcnZhbCBzcGFubmluZyBiZXR3ZWVuIHRoaXMgRGF0ZVRpbWUgYW5kIGFub3RoZXIgRGF0ZVRpbWVcbiAgICogQHBhcmFtIHtEYXRlVGltZX0gb3RoZXJEYXRlVGltZSAtIHRoZSBvdGhlciBlbmQgcG9pbnQgb2YgdGhlIEludGVydmFsXG4gICAqIEByZXR1cm4ge0ludGVydmFsfVxuICAgKi9cbiAgdW50aWwob3RoZXJEYXRlVGltZSkge1xuICAgIHJldHVybiB0aGlzLmlzVmFsaWQgPyBJbnRlcnZhbC5mcm9tRGF0ZVRpbWVzKHRoaXMsIG90aGVyRGF0ZVRpbWUpIDogdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gd2hldGhlciB0aGlzIERhdGVUaW1lIGlzIGluIHRoZSBzYW1lIHVuaXQgb2YgdGltZSBhcyBhbm90aGVyIERhdGVUaW1lLlxuICAgKiBIaWdoZXItb3JkZXIgdW5pdHMgbXVzdCBhbHNvIGJlIGlkZW50aWNhbCBmb3IgdGhpcyBmdW5jdGlvbiB0byByZXR1cm4gYHRydWVgLlxuICAgKiBOb3RlIHRoYXQgdGltZSB6b25lcyBhcmUgKippZ25vcmVkKiogaW4gdGhpcyBjb21wYXJpc29uLCB3aGljaCBjb21wYXJlcyB0aGUgKipsb2NhbCoqIGNhbGVuZGFyIHRpbWUuIFVzZSB7QGxpbmsgRGF0ZVRpbWUjc2V0Wm9uZX0gdG8gY29udmVydCBvbmUgb2YgdGhlIGRhdGVzIGlmIG5lZWRlZC5cbiAgICogQHBhcmFtIHtEYXRlVGltZX0gb3RoZXJEYXRlVGltZSAtIHRoZSBvdGhlciBEYXRlVGltZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdW5pdCAtIHRoZSB1bml0IG9mIHRpbWUgdG8gY2hlY2sgc2FtZW5lc3Mgb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdHMgLSBvcHRpb25zXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMudXNlTG9jYWxlV2Vla3M9ZmFsc2VdIC0gSWYgdHJ1ZSwgdXNlIHdlZWtzIGJhc2VkIG9uIHRoZSBsb2NhbGUsIGkuZS4gdXNlIHRoZSBsb2NhbGUtZGVwZW5kZW50IHN0YXJ0IG9mIHRoZSB3ZWVrOyBvbmx5IHRoZSBsb2NhbGUgb2YgdGhpcyBEYXRlVGltZSBpcyB1c2VkXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLmhhc1NhbWUob3RoZXJEVCwgJ2RheScpOyAvL34+IHRydWUgaWYgb3RoZXJEVCBpcyBpbiB0aGUgc2FtZSBjdXJyZW50IGNhbGVuZGFyIGRheVxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaGFzU2FtZShvdGhlckRhdGVUaW1lLCB1bml0LCBvcHRzKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBmYWxzZTtcblxuICAgIGNvbnN0IGlucHV0TXMgPSBvdGhlckRhdGVUaW1lLnZhbHVlT2YoKTtcbiAgICBjb25zdCBhZGp1c3RlZFRvWm9uZSA9IHRoaXMuc2V0Wm9uZShvdGhlckRhdGVUaW1lLnpvbmUsIHsga2VlcExvY2FsVGltZTogdHJ1ZSB9KTtcbiAgICByZXR1cm4gKFxuICAgICAgYWRqdXN0ZWRUb1pvbmUuc3RhcnRPZih1bml0LCBvcHRzKSA8PSBpbnB1dE1zICYmIGlucHV0TXMgPD0gYWRqdXN0ZWRUb1pvbmUuZW5kT2YodW5pdCwgb3B0cylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEVxdWFsaXR5IGNoZWNrXG4gICAqIFR3byBEYXRlVGltZXMgYXJlIGVxdWFsIGlmIGFuZCBvbmx5IGlmIHRoZXkgcmVwcmVzZW50IHRoZSBzYW1lIG1pbGxpc2Vjb25kLCBoYXZlIHRoZSBzYW1lIHpvbmUgYW5kIGxvY2F0aW9uLCBhbmQgYXJlIGJvdGggdmFsaWQuXG4gICAqIFRvIGNvbXBhcmUganVzdCB0aGUgbWlsbGlzZWNvbmQgdmFsdWVzLCB1c2UgYCtkdDEgPT09ICtkdDJgLlxuICAgKiBAcGFyYW0ge0RhdGVUaW1lfSBvdGhlciAtIHRoZSBvdGhlciBEYXRlVGltZVxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgZXF1YWxzKG90aGVyKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuaXNWYWxpZCAmJlxuICAgICAgb3RoZXIuaXNWYWxpZCAmJlxuICAgICAgdGhpcy52YWx1ZU9mKCkgPT09IG90aGVyLnZhbHVlT2YoKSAmJlxuICAgICAgdGhpcy56b25lLmVxdWFscyhvdGhlci56b25lKSAmJlxuICAgICAgdGhpcy5sb2MuZXF1YWxzKG90aGVyLmxvYylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSB0aGlzIHRpbWUgcmVsYXRpdmUgdG8gbm93LCBzdWNoIGFzIFwiaW4gdHdvIGRheXNcIi4gQ2FuIG9ubHkgaW50ZXJuYXRpb25hbGl6ZSBpZiB5b3VyXG4gICAqIHBsYXRmb3JtIHN1cHBvcnRzIEludGwuUmVsYXRpdmVUaW1lRm9ybWF0LiBSb3VuZHMgZG93biBieSBkZWZhdWx0LlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIG9wdGlvbnMgdGhhdCBhZmZlY3QgdGhlIG91dHB1dFxuICAgKiBAcGFyYW0ge0RhdGVUaW1lfSBbb3B0aW9ucy5iYXNlPURhdGVUaW1lLm5vdygpXSAtIHRoZSBEYXRlVGltZSB0byB1c2UgYXMgdGhlIGJhc2lzIHRvIHdoaWNoIHRoaXMgdGltZSBpcyBjb21wYXJlZC4gRGVmYXVsdHMgdG8gbm93LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMuc3R5bGU9XCJsb25nXCJdIC0gdGhlIHN0eWxlIG9mIHVuaXRzLCBtdXN0IGJlIFwibG9uZ1wiLCBcInNob3J0XCIsIG9yIFwibmFycm93XCJcbiAgICogQHBhcmFtIHtzdHJpbmd8c3RyaW5nW119IG9wdGlvbnMudW5pdCAtIHVzZSBhIHNwZWNpZmljIHVuaXQgb3IgYXJyYXkgb2YgdW5pdHM7IGlmIG9taXR0ZWQsIG9yIGFuIGFycmF5LCB0aGUgbWV0aG9kIHdpbGwgcGljayB0aGUgYmVzdCB1bml0LiBVc2UgYW4gYXJyYXkgb3Igb25lIG9mIFwieWVhcnNcIiwgXCJxdWFydGVyc1wiLCBcIm1vbnRoc1wiLCBcIndlZWtzXCIsIFwiZGF5c1wiLCBcImhvdXJzXCIsIFwibWludXRlc1wiLCBvciBcInNlY29uZHNcIlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnJvdW5kPXRydWVdIC0gd2hldGhlciB0byByb3VuZCB0aGUgbnVtYmVycyBpbiB0aGUgb3V0cHV0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMucGFkZGluZz0wXSAtIHBhZGRpbmcgaW4gbWlsbGlzZWNvbmRzLiBUaGlzIGFsbG93cyB5b3UgdG8gcm91bmQgdXAgdGhlIHJlc3VsdCBpZiBpdCBmaXRzIGluc2lkZSB0aGUgdGhyZXNob2xkLiBEb24ndCB1c2UgaW4gY29tYmluYXRpb24gd2l0aCB7cm91bmQ6IGZhbHNlfSBiZWNhdXNlIHRoZSBkZWNpbWFsIG91dHB1dCB3aWxsIGluY2x1ZGUgdGhlIHBhZGRpbmcuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmxvY2FsZSAtIG92ZXJyaWRlIHRoZSBsb2NhbGUgb2YgdGhpcyBEYXRlVGltZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5udW1iZXJpbmdTeXN0ZW0gLSBvdmVycmlkZSB0aGUgbnVtYmVyaW5nU3lzdGVtIG9mIHRoaXMgRGF0ZVRpbWUuIFRoZSBJbnRsIHN5c3RlbSBtYXkgY2hvb3NlIG5vdCB0byBob25vciB0aGlzXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLnBsdXMoeyBkYXlzOiAxIH0pLnRvUmVsYXRpdmUoKSAvLz0+IFwiaW4gMSBkYXlcIlxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS5zZXRMb2NhbGUoXCJlc1wiKS50b1JlbGF0aXZlKHsgZGF5czogMSB9KSAvLz0+IFwiZGVudHJvIGRlIDEgZFx1MDBFRGFcIlxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS5wbHVzKHsgZGF5czogMSB9KS50b1JlbGF0aXZlKHsgbG9jYWxlOiBcImZyXCIgfSkgLy89PiBcImRhbnMgMjMgaGV1cmVzXCJcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkubWludXMoeyBkYXlzOiAyIH0pLnRvUmVsYXRpdmUoKSAvLz0+IFwiMiBkYXlzIGFnb1wiXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLm1pbnVzKHsgZGF5czogMiB9KS50b1JlbGF0aXZlKHsgdW5pdDogXCJob3Vyc1wiIH0pIC8vPT4gXCI0OCBob3VycyBhZ29cIlxuICAgKiBAZXhhbXBsZSBEYXRlVGltZS5ub3coKS5taW51cyh7IGhvdXJzOiAzNiB9KS50b1JlbGF0aXZlKHsgcm91bmQ6IGZhbHNlIH0pIC8vPT4gXCIxLjUgZGF5cyBhZ29cIlxuICAgKi9cbiAgdG9SZWxhdGl2ZShvcHRpb25zID0ge30pIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgYmFzZSA9IG9wdGlvbnMuYmFzZSB8fCBEYXRlVGltZS5mcm9tT2JqZWN0KHt9LCB7IHpvbmU6IHRoaXMuem9uZSB9KSxcbiAgICAgIHBhZGRpbmcgPSBvcHRpb25zLnBhZGRpbmcgPyAodGhpcyA8IGJhc2UgPyAtb3B0aW9ucy5wYWRkaW5nIDogb3B0aW9ucy5wYWRkaW5nKSA6IDA7XG4gICAgbGV0IHVuaXRzID0gW1wieWVhcnNcIiwgXCJtb250aHNcIiwgXCJkYXlzXCIsIFwiaG91cnNcIiwgXCJtaW51dGVzXCIsIFwic2Vjb25kc1wiXTtcbiAgICBsZXQgdW5pdCA9IG9wdGlvbnMudW5pdDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zLnVuaXQpKSB7XG4gICAgICB1bml0cyA9IG9wdGlvbnMudW5pdDtcbiAgICAgIHVuaXQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBkaWZmUmVsYXRpdmUoYmFzZSwgdGhpcy5wbHVzKHBhZGRpbmcpLCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgbnVtZXJpYzogXCJhbHdheXNcIixcbiAgICAgIHVuaXRzLFxuICAgICAgdW5pdCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgZGF0ZSByZWxhdGl2ZSB0byB0b2RheSwgc3VjaCBhcyBcInllc3RlcmRheVwiIG9yIFwibmV4dCBtb250aFwiLlxuICAgKiBPbmx5IGludGVybmF0aW9uYWxpemVzIG9uIHBsYXRmb3JtcyB0aGF0IHN1cHBvcnRzIEludGwuUmVsYXRpdmVUaW1lRm9ybWF0LlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIG9wdGlvbnMgdGhhdCBhZmZlY3QgdGhlIG91dHB1dFxuICAgKiBAcGFyYW0ge0RhdGVUaW1lfSBbb3B0aW9ucy5iYXNlPURhdGVUaW1lLm5vdygpXSAtIHRoZSBEYXRlVGltZSB0byB1c2UgYXMgdGhlIGJhc2lzIHRvIHdoaWNoIHRoaXMgdGltZSBpcyBjb21wYXJlZC4gRGVmYXVsdHMgdG8gbm93LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5sb2NhbGUgLSBvdmVycmlkZSB0aGUgbG9jYWxlIG9mIHRoaXMgRGF0ZVRpbWVcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMudW5pdCAtIHVzZSBhIHNwZWNpZmljIHVuaXQ7IGlmIG9taXR0ZWQsIHRoZSBtZXRob2Qgd2lsbCBwaWNrIHRoZSB1bml0LiBVc2Ugb25lIG9mIFwieWVhcnNcIiwgXCJxdWFydGVyc1wiLCBcIm1vbnRoc1wiLCBcIndlZWtzXCIsIG9yIFwiZGF5c1wiXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLm51bWJlcmluZ1N5c3RlbSAtIG92ZXJyaWRlIHRoZSBudW1iZXJpbmdTeXN0ZW0gb2YgdGhpcyBEYXRlVGltZS4gVGhlIEludGwgc3lzdGVtIG1heSBjaG9vc2Ugbm90IHRvIGhvbm9yIHRoaXNcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkucGx1cyh7IGRheXM6IDEgfSkudG9SZWxhdGl2ZUNhbGVuZGFyKCkgLy89PiBcInRvbW9ycm93XCJcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkuc2V0TG9jYWxlKFwiZXNcIikucGx1cyh7IGRheXM6IDEgfSkudG9SZWxhdGl2ZSgpIC8vPT4gXCJcIm1hXHUwMEYxYW5hXCJcbiAgICogQGV4YW1wbGUgRGF0ZVRpbWUubm93KCkucGx1cyh7IGRheXM6IDEgfSkudG9SZWxhdGl2ZUNhbGVuZGFyKHsgbG9jYWxlOiBcImZyXCIgfSkgLy89PiBcImRlbWFpblwiXG4gICAqIEBleGFtcGxlIERhdGVUaW1lLm5vdygpLm1pbnVzKHsgZGF5czogMiB9KS50b1JlbGF0aXZlQ2FsZW5kYXIoKSAvLz0+IFwiMiBkYXlzIGFnb1wiXG4gICAqL1xuICB0b1JlbGF0aXZlQ2FsZW5kYXIob3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQpIHJldHVybiBudWxsO1xuXG4gICAgcmV0dXJuIGRpZmZSZWxhdGl2ZShvcHRpb25zLmJhc2UgfHwgRGF0ZVRpbWUuZnJvbU9iamVjdCh7fSwgeyB6b25lOiB0aGlzLnpvbmUgfSksIHRoaXMsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBudW1lcmljOiBcImF1dG9cIixcbiAgICAgIHVuaXRzOiBbXCJ5ZWFyc1wiLCBcIm1vbnRoc1wiLCBcImRheXNcIl0sXG4gICAgICBjYWxlbmRhcnk6IHRydWUsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBtaW4gb2Ygc2V2ZXJhbCBkYXRlIHRpbWVzXG4gICAqIEBwYXJhbSB7Li4uRGF0ZVRpbWV9IGRhdGVUaW1lcyAtIHRoZSBEYXRlVGltZXMgZnJvbSB3aGljaCB0byBjaG9vc2UgdGhlIG1pbmltdW1cbiAgICogQHJldHVybiB7RGF0ZVRpbWV9IHRoZSBtaW4gRGF0ZVRpbWUsIG9yIHVuZGVmaW5lZCBpZiBjYWxsZWQgd2l0aCBubyBhcmd1bWVudFxuICAgKi9cbiAgc3RhdGljIG1pbiguLi5kYXRlVGltZXMpIHtcbiAgICBpZiAoIWRhdGVUaW1lcy5ldmVyeShEYXRlVGltZS5pc0RhdGVUaW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKFwibWluIHJlcXVpcmVzIGFsbCBhcmd1bWVudHMgYmUgRGF0ZVRpbWVzXCIpO1xuICAgIH1cbiAgICByZXR1cm4gYmVzdEJ5KGRhdGVUaW1lcywgKGkpID0+IGkudmFsdWVPZigpLCBNYXRoLm1pbik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBtYXggb2Ygc2V2ZXJhbCBkYXRlIHRpbWVzXG4gICAqIEBwYXJhbSB7Li4uRGF0ZVRpbWV9IGRhdGVUaW1lcyAtIHRoZSBEYXRlVGltZXMgZnJvbSB3aGljaCB0byBjaG9vc2UgdGhlIG1heGltdW1cbiAgICogQHJldHVybiB7RGF0ZVRpbWV9IHRoZSBtYXggRGF0ZVRpbWUsIG9yIHVuZGVmaW5lZCBpZiBjYWxsZWQgd2l0aCBubyBhcmd1bWVudFxuICAgKi9cbiAgc3RhdGljIG1heCguLi5kYXRlVGltZXMpIHtcbiAgICBpZiAoIWRhdGVUaW1lcy5ldmVyeShEYXRlVGltZS5pc0RhdGVUaW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKFwibWF4IHJlcXVpcmVzIGFsbCBhcmd1bWVudHMgYmUgRGF0ZVRpbWVzXCIpO1xuICAgIH1cbiAgICByZXR1cm4gYmVzdEJ5KGRhdGVUaW1lcywgKGkpID0+IGkudmFsdWVPZigpLCBNYXRoLm1heCk7XG4gIH1cblxuICAvLyBNSVNDXG5cbiAgLyoqXG4gICAqIEV4cGxhaW4gaG93IGEgc3RyaW5nIHdvdWxkIGJlIHBhcnNlZCBieSBmcm9tRm9ybWF0KClcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSB0aGUgc3RyaW5nIHRvIHBhcnNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmbXQgLSB0aGUgZm9ybWF0IHRoZSBzdHJpbmcgaXMgZXhwZWN0ZWQgdG8gYmUgaW4gKHNlZSBkZXNjcmlwdGlvbilcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBvcHRpb25zIHRha2VuIGJ5IGZyb21Gb3JtYXQoKVxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZnJvbUZvcm1hdEV4cGxhaW4odGV4dCwgZm10LCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB7IGxvY2FsZSA9IG51bGwsIG51bWJlcmluZ1N5c3RlbSA9IG51bGwgfSA9IG9wdGlvbnMsXG4gICAgICBsb2NhbGVUb1VzZSA9IExvY2FsZS5mcm9tT3B0cyh7XG4gICAgICAgIGxvY2FsZSxcbiAgICAgICAgbnVtYmVyaW5nU3lzdGVtLFxuICAgICAgICBkZWZhdWx0VG9FTjogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIHJldHVybiBleHBsYWluRnJvbVRva2Vucyhsb2NhbGVUb1VzZSwgdGV4dCwgZm10KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB1c2UgZnJvbUZvcm1hdEV4cGxhaW4gaW5zdGVhZFxuICAgKi9cbiAgc3RhdGljIGZyb21TdHJpbmdFeHBsYWluKHRleHQsIGZtdCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgcmV0dXJuIERhdGVUaW1lLmZyb21Gb3JtYXRFeHBsYWluKHRleHQsIGZtdCwgb3B0aW9ucyk7XG4gIH1cblxuICAvLyBGT1JNQVQgUFJFU0VUU1xuXG4gIC8qKlxuICAgKiB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvcm1hdCBsaWtlIDEwLzE0LzE5ODNcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgREFURV9TSE9SVCgpIHtcbiAgICByZXR1cm4gRm9ybWF0cy5EQVRFX1NIT1JUO1xuICB9XG5cbiAgLyoqXG4gICAqIHtAbGluayBEYXRlVGltZSN0b0xvY2FsZVN0cmluZ30gZm9ybWF0IGxpa2UgJ09jdCAxNCwgMTk4MydcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgREFURV9NRUQoKSB7XG4gICAgcmV0dXJuIEZvcm1hdHMuREFURV9NRUQ7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIERhdGVUaW1lI3RvTG9jYWxlU3RyaW5nfSBmb3JtYXQgbGlrZSAnRnJpLCBPY3QgMTQsIDE5ODMnXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IERBVEVfTUVEX1dJVEhfV0VFS0RBWSgpIHtcbiAgICByZXR1cm4gRm9ybWF0cy5EQVRFX01FRF9XSVRIX1dFRUtEQVk7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIERhdGVUaW1lI3RvTG9jYWxlU3RyaW5nfSBmb3JtYXQgbGlrZSAnT2N0b2JlciAxNCwgMTk4MydcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgREFURV9GVUxMKCkge1xuICAgIHJldHVybiBGb3JtYXRzLkRBVEVfRlVMTDtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvcm1hdCBsaWtlICdUdWVzZGF5LCBPY3RvYmVyIDE0LCAxOTgzJ1xuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBEQVRFX0hVR0UoKSB7XG4gICAgcmV0dXJuIEZvcm1hdHMuREFURV9IVUdFO1xuICB9XG5cbiAgLyoqXG4gICAqIHtAbGluayBEYXRlVGltZSN0b0xvY2FsZVN0cmluZ30gZm9ybWF0IGxpa2UgJzA5OjMwIEFNJy4gT25seSAxMi1ob3VyIGlmIHRoZSBsb2NhbGUgaXMuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IFRJTUVfU0lNUExFKCkge1xuICAgIHJldHVybiBGb3JtYXRzLlRJTUVfU0lNUExFO1xuICB9XG5cbiAgLyoqXG4gICAqIHtAbGluayBEYXRlVGltZSN0b0xvY2FsZVN0cmluZ30gZm9ybWF0IGxpa2UgJzA5OjMwOjIzIEFNJy4gT25seSAxMi1ob3VyIGlmIHRoZSBsb2NhbGUgaXMuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IFRJTUVfV0lUSF9TRUNPTkRTKCkge1xuICAgIHJldHVybiBGb3JtYXRzLlRJTUVfV0lUSF9TRUNPTkRTO1xuICB9XG5cbiAgLyoqXG4gICAqIHtAbGluayBEYXRlVGltZSN0b0xvY2FsZVN0cmluZ30gZm9ybWF0IGxpa2UgJzA5OjMwOjIzIEFNIEVEVCcuIE9ubHkgMTItaG91ciBpZiB0aGUgbG9jYWxlIGlzLlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBUSU1FX1dJVEhfU0hPUlRfT0ZGU0VUKCkge1xuICAgIHJldHVybiBGb3JtYXRzLlRJTUVfV0lUSF9TSE9SVF9PRkZTRVQ7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIERhdGVUaW1lI3RvTG9jYWxlU3RyaW5nfSBmb3JtYXQgbGlrZSAnMDk6MzA6MjMgQU0gRWFzdGVybiBEYXlsaWdodCBUaW1lJy4gT25seSAxMi1ob3VyIGlmIHRoZSBsb2NhbGUgaXMuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IFRJTUVfV0lUSF9MT05HX09GRlNFVCgpIHtcbiAgICByZXR1cm4gRm9ybWF0cy5USU1FX1dJVEhfTE9OR19PRkZTRVQ7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIERhdGVUaW1lI3RvTG9jYWxlU3RyaW5nfSBmb3JtYXQgbGlrZSAnMDk6MzAnLCBhbHdheXMgMjQtaG91ci5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgVElNRV8yNF9TSU1QTEUoKSB7XG4gICAgcmV0dXJuIEZvcm1hdHMuVElNRV8yNF9TSU1QTEU7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIERhdGVUaW1lI3RvTG9jYWxlU3RyaW5nfSBmb3JtYXQgbGlrZSAnMDk6MzA6MjMnLCBhbHdheXMgMjQtaG91ci5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgVElNRV8yNF9XSVRIX1NFQ09ORFMoKSB7XG4gICAgcmV0dXJuIEZvcm1hdHMuVElNRV8yNF9XSVRIX1NFQ09ORFM7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIERhdGVUaW1lI3RvTG9jYWxlU3RyaW5nfSBmb3JtYXQgbGlrZSAnMDk6MzA6MjMgRURUJywgYWx3YXlzIDI0LWhvdXIuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IFRJTUVfMjRfV0lUSF9TSE9SVF9PRkZTRVQoKSB7XG4gICAgcmV0dXJuIEZvcm1hdHMuVElNRV8yNF9XSVRIX1NIT1JUX09GRlNFVDtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvcm1hdCBsaWtlICcwOTozMDoyMyBFYXN0ZXJuIERheWxpZ2h0IFRpbWUnLCBhbHdheXMgMjQtaG91ci5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgVElNRV8yNF9XSVRIX0xPTkdfT0ZGU0VUKCkge1xuICAgIHJldHVybiBGb3JtYXRzLlRJTUVfMjRfV0lUSF9MT05HX09GRlNFVDtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvcm1hdCBsaWtlICcxMC8xNC8xOTgzLCA5OjMwIEFNJy4gT25seSAxMi1ob3VyIGlmIHRoZSBsb2NhbGUgaXMuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IERBVEVUSU1FX1NIT1JUKCkge1xuICAgIHJldHVybiBGb3JtYXRzLkRBVEVUSU1FX1NIT1JUO1xuICB9XG5cbiAgLyoqXG4gICAqIHtAbGluayBEYXRlVGltZSN0b0xvY2FsZVN0cmluZ30gZm9ybWF0IGxpa2UgJzEwLzE0LzE5ODMsIDk6MzA6MzMgQU0nLiBPbmx5IDEyLWhvdXIgaWYgdGhlIGxvY2FsZSBpcy5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgREFURVRJTUVfU0hPUlRfV0lUSF9TRUNPTkRTKCkge1xuICAgIHJldHVybiBGb3JtYXRzLkRBVEVUSU1FX1NIT1JUX1dJVEhfU0VDT05EUztcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvcm1hdCBsaWtlICdPY3QgMTQsIDE5ODMsIDk6MzAgQU0nLiBPbmx5IDEyLWhvdXIgaWYgdGhlIGxvY2FsZSBpcy5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgREFURVRJTUVfTUVEKCkge1xuICAgIHJldHVybiBGb3JtYXRzLkRBVEVUSU1FX01FRDtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvcm1hdCBsaWtlICdPY3QgMTQsIDE5ODMsIDk6MzA6MzMgQU0nLiBPbmx5IDEyLWhvdXIgaWYgdGhlIGxvY2FsZSBpcy5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgREFURVRJTUVfTUVEX1dJVEhfU0VDT05EUygpIHtcbiAgICByZXR1cm4gRm9ybWF0cy5EQVRFVElNRV9NRURfV0lUSF9TRUNPTkRTO1xuICB9XG5cbiAgLyoqXG4gICAqIHtAbGluayBEYXRlVGltZSN0b0xvY2FsZVN0cmluZ30gZm9ybWF0IGxpa2UgJ0ZyaSwgMTQgT2N0IDE5ODMsIDk6MzAgQU0nLiBPbmx5IDEyLWhvdXIgaWYgdGhlIGxvY2FsZSBpcy5cbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgREFURVRJTUVfTUVEX1dJVEhfV0VFS0RBWSgpIHtcbiAgICByZXR1cm4gRm9ybWF0cy5EQVRFVElNRV9NRURfV0lUSF9XRUVLREFZO1xuICB9XG5cbiAgLyoqXG4gICAqIHtAbGluayBEYXRlVGltZSN0b0xvY2FsZVN0cmluZ30gZm9ybWF0IGxpa2UgJ09jdG9iZXIgMTQsIDE5ODMsIDk6MzAgQU0gRURUJy4gT25seSAxMi1ob3VyIGlmIHRoZSBsb2NhbGUgaXMuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IERBVEVUSU1FX0ZVTEwoKSB7XG4gICAgcmV0dXJuIEZvcm1hdHMuREFURVRJTUVfRlVMTDtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvcm1hdCBsaWtlICdPY3RvYmVyIDE0LCAxOTgzLCA5OjMwOjMzIEFNIEVEVCcuIE9ubHkgMTItaG91ciBpZiB0aGUgbG9jYWxlIGlzLlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBEQVRFVElNRV9GVUxMX1dJVEhfU0VDT05EUygpIHtcbiAgICByZXR1cm4gRm9ybWF0cy5EQVRFVElNRV9GVUxMX1dJVEhfU0VDT05EUztcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvcm1hdCBsaWtlICdGcmlkYXksIE9jdG9iZXIgMTQsIDE5ODMsIDk6MzAgQU0gRWFzdGVybiBEYXlsaWdodCBUaW1lJy4gT25seSAxMi1ob3VyIGlmIHRoZSBsb2NhbGUgaXMuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IERBVEVUSU1FX0hVR0UoKSB7XG4gICAgcmV0dXJuIEZvcm1hdHMuREFURVRJTUVfSFVHRTtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgRGF0ZVRpbWUjdG9Mb2NhbGVTdHJpbmd9IGZvcm1hdCBsaWtlICdGcmlkYXksIE9jdG9iZXIgMTQsIDE5ODMsIDk6MzA6MzMgQU0gRWFzdGVybiBEYXlsaWdodCBUaW1lJy4gT25seSAxMi1ob3VyIGlmIHRoZSBsb2NhbGUgaXMuXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICBzdGF0aWMgZ2V0IERBVEVUSU1FX0hVR0VfV0lUSF9TRUNPTkRTKCkge1xuICAgIHJldHVybiBGb3JtYXRzLkRBVEVUSU1FX0hVR0VfV0lUSF9TRUNPTkRTO1xuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZyaWVuZGx5RGF0ZVRpbWUoZGF0ZVRpbWVpc2gpIHtcbiAgaWYgKERhdGVUaW1lLmlzRGF0ZVRpbWUoZGF0ZVRpbWVpc2gpKSB7XG4gICAgcmV0dXJuIGRhdGVUaW1laXNoO1xuICB9IGVsc2UgaWYgKGRhdGVUaW1laXNoICYmIGRhdGVUaW1laXNoLnZhbHVlT2YgJiYgaXNOdW1iZXIoZGF0ZVRpbWVpc2gudmFsdWVPZigpKSkge1xuICAgIHJldHVybiBEYXRlVGltZS5mcm9tSlNEYXRlKGRhdGVUaW1laXNoKTtcbiAgfSBlbHNlIGlmIChkYXRlVGltZWlzaCAmJiB0eXBlb2YgZGF0ZVRpbWVpc2ggPT09IFwib2JqZWN0XCIpIHtcbiAgICByZXR1cm4gRGF0ZVRpbWUuZnJvbU9iamVjdChkYXRlVGltZWlzaCk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKFxuICAgICAgYFVua25vd24gZGF0ZXRpbWUgYXJndW1lbnQ6ICR7ZGF0ZVRpbWVpc2h9LCBvZiB0eXBlICR7dHlwZW9mIGRhdGVUaW1laXNofWBcbiAgICApO1xuICB9XG59XG4iLCAiLyohXG4gKiBjaGFydGpzLWFkYXB0ZXItbHV4b24gdjEuMy4xXG4gKiBodHRwczovL3d3dy5jaGFydGpzLm9yZ1xuICogKGMpIDIwMjMgY2hhcnRqcy1hZGFwdGVyLWx1eG9uIENvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKi9cbmltcG9ydCB7IF9hZGFwdGVycyB9IGZyb20gJ2NoYXJ0LmpzJztcbmltcG9ydCB7IERhdGVUaW1lIH0gZnJvbSAnbHV4b24nO1xuXG5jb25zdCBGT1JNQVRTID0ge1xuICBkYXRldGltZTogRGF0ZVRpbWUuREFURVRJTUVfTUVEX1dJVEhfU0VDT05EUyxcbiAgbWlsbGlzZWNvbmQ6ICdoOm1tOnNzLlNTUyBhJyxcbiAgc2Vjb25kOiBEYXRlVGltZS5USU1FX1dJVEhfU0VDT05EUyxcbiAgbWludXRlOiBEYXRlVGltZS5USU1FX1NJTVBMRSxcbiAgaG91cjoge2hvdXI6ICdudW1lcmljJ30sXG4gIGRheToge2RheTogJ251bWVyaWMnLCBtb250aDogJ3Nob3J0J30sXG4gIHdlZWs6ICdERCcsXG4gIG1vbnRoOiB7bW9udGg6ICdzaG9ydCcsIHllYXI6ICdudW1lcmljJ30sXG4gIHF1YXJ0ZXI6IFwiJ1EncSAtIHl5eXlcIixcbiAgeWVhcjoge3llYXI6ICdudW1lcmljJ31cbn07XG5cbl9hZGFwdGVycy5fZGF0ZS5vdmVycmlkZSh7XG4gIF9pZDogJ2x1eG9uJywgLy8gREVCVUdcblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9jcmVhdGU6IGZ1bmN0aW9uKHRpbWUpIHtcbiAgICByZXR1cm4gRGF0ZVRpbWUuZnJvbU1pbGxpcyh0aW1lLCB0aGlzLm9wdGlvbnMpO1xuICB9LFxuXG4gIGluaXQoY2hhcnRPcHRpb25zKSB7XG4gICAgaWYgKCF0aGlzLm9wdGlvbnMubG9jYWxlKSB7XG4gICAgICB0aGlzLm9wdGlvbnMubG9jYWxlID0gY2hhcnRPcHRpb25zLmxvY2FsZTtcbiAgICB9XG4gIH0sXG5cbiAgZm9ybWF0czogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIEZPUk1BVFM7XG4gIH0sXG5cbiAgcGFyc2U6IGZ1bmN0aW9uKHZhbHVlLCBmb3JtYXQpIHtcbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuXG4gICAgY29uc3QgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgdmFsdWUgPSB0aGlzLl9jcmVhdGUodmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmICh0eXBlb2YgZm9ybWF0ID09PSAnc3RyaW5nJykge1xuICAgICAgICB2YWx1ZSA9IERhdGVUaW1lLmZyb21Gb3JtYXQodmFsdWUsIGZvcm1hdCwgb3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWx1ZSA9IERhdGVUaW1lLmZyb21JU08odmFsdWUsIG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICB2YWx1ZSA9IERhdGVUaW1lLmZyb21KU0RhdGUodmFsdWUsIG9wdGlvbnMpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIERhdGVUaW1lKSkge1xuICAgICAgdmFsdWUgPSBEYXRlVGltZS5mcm9tT2JqZWN0KHZhbHVlLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUuaXNWYWxpZCA/IHZhbHVlLnZhbHVlT2YoKSA6IG51bGw7XG4gIH0sXG5cbiAgZm9ybWF0OiBmdW5jdGlvbih0aW1lLCBmb3JtYXQpIHtcbiAgICBjb25zdCBkYXRldGltZSA9IHRoaXMuX2NyZWF0ZSh0aW1lKTtcbiAgICByZXR1cm4gdHlwZW9mIGZvcm1hdCA9PT0gJ3N0cmluZydcbiAgICAgID8gZGF0ZXRpbWUudG9Gb3JtYXQoZm9ybWF0KVxuICAgICAgOiBkYXRldGltZS50b0xvY2FsZVN0cmluZyhmb3JtYXQpO1xuICB9LFxuXG4gIGFkZDogZnVuY3Rpb24odGltZSwgYW1vdW50LCB1bml0KSB7XG4gICAgY29uc3QgYXJncyA9IHt9O1xuICAgIGFyZ3NbdW5pdF0gPSBhbW91bnQ7XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZSh0aW1lKS5wbHVzKGFyZ3MpLnZhbHVlT2YoKTtcbiAgfSxcblxuICBkaWZmOiBmdW5jdGlvbihtYXgsIG1pbiwgdW5pdCkge1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGUobWF4KS5kaWZmKHRoaXMuX2NyZWF0ZShtaW4pKS5hcyh1bml0KS52YWx1ZU9mKCk7XG4gIH0sXG5cbiAgc3RhcnRPZjogZnVuY3Rpb24odGltZSwgdW5pdCwgd2Vla2RheSkge1xuICAgIGlmICh1bml0ID09PSAnaXNvV2VlaycpIHtcbiAgICAgIHdlZWtkYXkgPSBNYXRoLnRydW5jKE1hdGgubWluKE1hdGgubWF4KDAsIHdlZWtkYXkpLCA2KSk7XG4gICAgICBjb25zdCBkYXRlVGltZSA9IHRoaXMuX2NyZWF0ZSh0aW1lKTtcbiAgICAgIHJldHVybiBkYXRlVGltZS5taW51cyh7ZGF5czogKGRhdGVUaW1lLndlZWtkYXkgLSB3ZWVrZGF5ICsgNykgJSA3fSkuc3RhcnRPZignZGF5JykudmFsdWVPZigpO1xuICAgIH1cbiAgICByZXR1cm4gdW5pdCA/IHRoaXMuX2NyZWF0ZSh0aW1lKS5zdGFydE9mKHVuaXQpLnZhbHVlT2YoKSA6IHRpbWU7XG4gIH0sXG5cbiAgZW5kT2Y6IGZ1bmN0aW9uKHRpbWUsIHVuaXQpIHtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlKHRpbWUpLmVuZE9mKHVuaXQpLnZhbHVlT2YoKTtcbiAgfVxufSk7XG4iLCAiaW1wb3J0IHsgQ2hhcnQgfSBmcm9tIFwiY2hhcnQuanMvYXV0b1wiO1xuaW1wb3J0IFwiY2hhcnRqcy1hZGFwdGVyLWx1eG9uXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGR1Y2tGZWVkZXJXaWRnZXQoZGF0YSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGh1bmdlckxldmVsOiAxMDAsXG4gICAgICAgIGR1Y2tzTXVyZGVyZWQ6IDAsXG4gICAgICAgIGF1ZGlvUGxheWVkOiBmYWxzZSxcbiAgICAgICAgaW5pdCgpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdENoYXJ0KCk7XG5cbiAgICAgICAgICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmh1bmdlckxldmVsLS07XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5odW5nZXJMZXZlbCA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5odW5nZXJMZXZlbCA9IDEwMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kdWNrc011cmRlcmVkKys7IFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUNoYXJ0KCk7XG4gICAgICAgICAgICB9LCAxMDAwKTtcblxuICAgICAgICAgICAgLy8gUHJldmVudCBhdWRpbyBzcGFtXG4gICAgICAgICAgICBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hdWRpb1BsYXllZCA9IGZhbHNlO1xuICAgICAgICAgICAgfSwgMzAwMClcbiAgICAgICAgfSxcbiAgICAgICAgZmVlZER1Y2soKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuYXVkaW9QbGF5ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRyZWZzLmR1Y2ttb2RlQXVkaW8ucGxheSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuYXVkaW9QbGF5ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLmh1bmdlckxldmVsICs9NTtcbiAgICAgICAgICAgIGlmICh0aGlzLmh1bmdlckxldmVsID4gMTAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5odW5nZXJMZXZlbCA9IDEwMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ2hhcnQoKTtcbiAgICAgICAgfSxcblxuICAgICAgICBpbml0Q2hhcnQoKSB7XG5cbiAgICAgICAgICAgIENoYXJ0LmRlZmF1bHRzLnBsdWdpbnMudG9vbHRpcC5lbmFibGVkID0gZmFsc2U7XG4gICAgICAgICAgICBDaGFydC5kZWZhdWx0cy5wbHVnaW5zLmxlZ2VuZC5kaXNwbGF5ID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4gbmV3IENoYXJ0KHRoaXMuJHJlZnMuY2FudmFzLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogZGF0YS5jaGFydC50eXBlLFxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEuY2hhcnQuY2FjaGVkRGF0YSxcbiAgICAgICAgICAgICAgICBvcHRpb25zOiBkYXRhLmNoYXJ0Lm9wdGlvbnMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgdXBkYXRlQ2hhcnQoKSB7XG4gICAgICAgICAgICBsZXQgY2hhcnQgPSB0aGlzLmdldENoYXJ0KClcbiAgICAgICAgICAgIGNoYXJ0LmRhdGEgPSB7XG4gICAgICAgICAgICAgICAgZGF0YXNldHM6W3tcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogW3RoaXMuaHVuZ2VyTGV2ZWwsIDEwMCAtIHRoaXMuaHVuZ2VyTGV2ZWxdLFxuICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IFt0aGlzLmdldFN0YXRlQ29sb3VyKCksIFwiR3JheVwiXVxuICAgICAgICAgICAgICAgIH1dXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjaGFydC51cGRhdGUoJ3Jlc2l6ZScpXG4gICAgICAgIH0sXG4gICAgICAgIGdldFN0YXRlQ29sb3VyKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaHVuZ2VyTGV2ZWwgPj01MCA/IFwiR3JlZW5cIjogdGhpcy5odW5nZXJMZXZlbCA+PSAxNSA/IFwiT3JhbmdlXCI6IFwiUmVkXCI7XG4gICAgICAgIH0sXG4gICAgICAgIGdldENoYXJ0KCkge1xuICAgICAgICAgICAgcmV0dXJuIENoYXJ0LmdldENoYXJ0KHRoaXMuJHJlZnMuY2FudmFzKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7O0FBTUEsU0FBUyxNQUFNLEdBQUc7QUFDaEIsU0FBTyxJQUFJLE1BQU07QUFDbkI7QUFDQSxJQUFNLE1BQU0sQ0FBQyxHQUFHQSxJQUFHLE1BQU0sS0FBSyxJQUFJLEtBQUssSUFBSSxHQUFHLENBQUMsR0FBR0EsRUFBQztBQUNuRCxTQUFTLElBQUksR0FBRztBQUNkLFNBQU8sSUFBSSxNQUFNLElBQUksSUFBSSxHQUFHLEdBQUcsR0FBRztBQUNwQztBQUlBLFNBQVMsSUFBSSxHQUFHO0FBQ2QsU0FBTyxJQUFJLE1BQU0sSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHO0FBQ25DO0FBQ0EsU0FBUyxJ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T0FDbkMsT0FBTyxNQUFNRCxRQUFPQztBQUMxQjtBQUVBLElBQU0sTUFBTTtBQUFBLEVBQ1YsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUFBLEVBQ0gsR0FBRztBQUNMO0FBQ0EsSUFBTSxVQUFVO0FBQUEsRUFDZCxRQUFRO0FBQUEsRUFDUixhQUFhO0FBQUEsRUFDYixNQUFNO0FBQUEsRUFDTixXQUFXO0FBQUEsRUFDWCxNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxRQUFRO0FBQUEsRUFDUixPQUFPO0FBQUEsRUFDUCxjQUFjO0FBQUEsRUFDZCxJQUFJO0FBQUEsRUFDSixTQUFTO0FBQUEsRUFDVCxNQUFNO0FBQUEsRUFDTixXQUFXO0FBQUEsRUFDWCxRQUFRO0FBQUEsRUFDUixVQUFVO0FBQUEsRUFDVixTQUFTO0FBQUEsRUFDVCxLQUFLO0FBQUEsRUFDTCxhQUFhO0FBQUEsRUFDYixTQUFTO0FBQUEsRUFDVCxTQUFTO0FBQUEsRUFDVCxNQUFNO0FBQUEsRUFDTixLQUFLO0FBQUEsRUFDTCxPQUFPO0FBQUEsRUFDUCxTQUFTO0FBQUEsRUFDVCxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsRUFDTixRQUFRO0FBQUEsRUFDUixTQUFTO0FBQUEsRUFDVCxVQUFVO0FBQUEsRUFDVixRQUFRO0FBQUEsRUFDUixPQUFPO0FBQUEsRUFDUCxLQUFLO0FBQUEsRUFDTCxRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxPQUFPO0FBQUEsRUFDUCxLQUFLO0FBQUEsRUFDTCxRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixVQUFVO0FBQUEsRUFDVixRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixVQUFVO0FBQUEsRUFDVixVQUFVO0FBQUEsRUFDVixVQUFVO0FBQUEsRUFDVixVQUFVO0FBQUEsRUFDVixRQUFRO0FBQUEsRUFDUixTQUFTO0FBQUEsRUFDVCxXQUFXO0FBQUEsRUFDWCxLQUFLO0FBQUEsRUFDTCxRQUFRO0FBQUEsRUFDUixLQUFLO0FBQUEsRUFDTCxLQUFLO0FBQUEsRUFDTCxPQUFPO0FBQUEsRUFDUCxLQUFLO0FBQUEsRUFDTCxTQUFTO0FBQUEsRUFDVCxRQUFRO0FBQUEsRUFDUixTQUFTO0FBQUEsRUFDVCxPQUFPO0FBQUEsRUFDUCxNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxRQUFRO0FBQUEsRUFDUixXQUFXO0FBQUEsRUFDWCxTQUFTO0FBQUEsRUFDVCxZQUFZO0FBQUEsRUFDWixLQUFLO0FBQUEsRUFDTCxNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxXQUFXO0FBQUEsRUFDWCxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsRUFDTixRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixPQUFPO0FBQUEsRUFDUCxPQUFPO0FBQUEsRUFDUCxTQUFTO0FBQUEsRUFDVCxLQUFLO0FBQUEsRUFDTCxNQUFNO0FBQUEsRUFDTixTQUFTO0FBQUEsRUFDVCxLQUFLO0FBQUEsRUFDTCxRQUFRO0FBQUEsRUFDUixPQUFPO0FBQUEsRUFDUCxZQUFZO0FBQUEsRUFDWixLQUFLO0FBQUEsRUFDTCxPQUFPO0FBQUEsRUFDUCxRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixNQUFNO0FBQUEsRUFDTixXQUFXO0FBQUEsRUFDWCxLQUFLO0FBQUEsRUFDTCxVQUFVO0FBQUEsRUFDVixZQUFZO0FBQUEsRUFDWixTQUFTO0FBQUEsRUFDVCxVQUFVO0FBQUEsRUFDVixTQUFTO0FBQUEsRUFDVCxZQUFZO0FBQUEsRUFDWixNQUFNO0FBQUEsRUFDTixRQUFRO0FBQUEsRUFDUixNQUFNO0FBQUEsRUFDTixTQUFTO0FBQUEsRUFDVCxPQUFPO0FBQUEsRUFDUCxTQUFTO0FBQUEsRUFDVCxNQUFNO0FBQUEsRUFDTixXQUFXO0FBQUEsRUFDWCxRQUFRO0FBQUEsRUFDUixPQUFPO0FBQUEsRUFDUCxZQUFZO0FBQUEsRUFDWixXQUFXO0FBQUEsRUFDWCxTQUFTO0FBQUEsRUFDVCxNQUFNO0FBQUEsRUFDTixLQUFLO0FBQUEsRUFDTCxNQUFNO0FBQUEsRUFDTixTQUFTO0FBQUEsRUFDVCxPQUFPO0FBQUEsRUFDUCxhQUFhO0FBQUEsRUFDYixJQUFJO0FBQUEsRUFDSixVQUFVO0FBQUEsRUFDVixPQUFPO0FBQUEsRUFDUCxXQUFXO0FBQUEsRUFDWCxPQUFPO0FBQUEsRUFDUCxXQUFXO0FBQUEsRUFDWCxPQUFPO0FBQUEsRUFDUCxTQUFTO0FBQUEsRUFDVCxPQUFPO0FBQUEsRUFDUCxRQUFRO0FBQUEsRUFDUixPQUFPO0FBQUEsRUFDUCxLQUFLO0FBQUEsRUFDTCxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsRUFDTixVQUFVO0FBQUEsRUFDVixRQUFRO0FBQUEsRUFDUixLQUFLO0FBQUEsRUFDTCxLQUFLO0FBQUEsRUFDTCxPQUFPO0FBQUEsRUFDUCxRQUFRO0FBQUEsRUFDUixJQUFJO0FBQUEsRUFDSixPQUFPO0FBQUEsRUFDUCxLQUFLO0FBQUEsRUFDTCxNQUFNO0FBQUEsRUFDTixXQUFXO0FBQUEsRUFDWCxJQUFJO0FBQUEsRUFDSixPQUFPO0FBQ1Q7QUFDQSxT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QUc7QUFDTDtBQUNBLElBQU1DLFdBQVU7QUFBQSxFQUNkLFFBQVE7QUFBQSxFQUNSLGFBQWE7QUFBQSxFQUNiLE1BQU07QUFBQSxFQUNOLFdBQVc7QUFBQSxFQUNYLE1BQU07QUFBQSxFQUNOLE9BQU87QUFBQSxFQUNQLFFBQVE7QUFBQSxFQUNSLE9BQU87QUFBQSxFQUNQLGNBQWM7QUFBQSxFQUNkLElBQUk7QUFBQSxFQUNKLFNBQVM7QUFBQSxFQUNULE1BQU07QUFBQSxFQUNOLFdBQVc7QUFBQSxFQUNYLFFBQVE7QUFBQSxFQUNSLFVBQVU7QUFBQSxFQUNWLFNBQVM7QUFBQSxFQUNULEtBQUs7QUFBQSxFQUNMLGFBQWE7QUFBQSxFQUNiLFNBQVM7QUFBQSxFQUNULFNBQVM7QUFBQSxFQUNULE1BQU07QUFBQSxFQUNOLEtBQUs7QUFBQSxFQUNMLE9BQU87QUFBQSxFQUNQLFNBQVM7QUFBQSxFQUNULE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxFQUNOLFFBQVE7QUFBQSxFQUNSLFNBQVM7QUFBQSxFQUNULFVBQVU7QUFBQSxFQUNWLFFBQVE7QUFBQSxFQUNSLE9BQU87QUFBQSxFQUNQLEtBQUs7QUFBQSxFQUNMLFFBQVE7QUFBQSxFQUNSLFFBQVE7QUFBQSxFQUNSLE1BQU07QUFBQSxFQUNOLE9BQU87QUFBQSxFQUNQLE9BQU87QUFBQSxFQUNQLEtBQUs7QUFBQSxFQUNMLFFBQVE7QUFBQSxFQUNSLFFBQVE7QUFBQSxFQUNSLFVBQVU7QUFBQSxFQUNWLFFBQVE7QUFBQSxFQUNSLFFBQVE7QUFBQSxFQUNSLFVBQVU7QUFBQSxFQUNWLFVBQVU7QUFBQSxFQUNWLFVBQVU7QUFBQSxFQUNWLFVBQVU7QUFBQSxFQUNWLFFBQVE7QUFBQSxFQUNSLFNBQVM7QUFBQSxFQUNULFdBQVc7QUFBQSxFQUNYLEtBQUs7QUFBQSxFQUNMLFFBQVE7QUFBQSxFQUNSLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLE9BQU87QUFBQSxFQUNQLEtBQUs7QUFBQSxFQUNMLFNBQVM7QUFBQSxFQUNULFFBQVE7QUFBQSxFQUNSLFNBQVM7QUFBQSxFQUNULE9BQU87QUFBQSxFQUNQLE1BQU07QUFBQSxFQUNOLE9BQU87QUFBQSxFQUNQLFFBQVE7QUFBQSxFQUNSLFdBQVc7QUFBQSxFQUNYLFNBQVM7QUFBQSxFQUNULFlBQVk7QUFBQSxFQUNaLEtBQUs7QUFBQSxFQUNMLE1BQU07QUFBQSxFQUNOLE9BQU87QUFBQSxFQUNQLFdBQVc7QUFBQSxFQUNYLE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxFQUNOLE1BQU07QUFBQSxFQUNOLFFBQVE7QUFBQSxFQUNSLFFBQVE7QUFBQSxFQUNSLFFBQVE7QUFBQSxFQUNSLE9BQU87QUFBQSxFQUNQLE9BQU87QUFBQSxFQUNQLFNBQVM7QUFBQSxFQUNULEtBQUs7QUFBQSxFQUNMLE1BQU07QUFBQSxFQUNOLFNBQVM7QUFBQSxFQUNULEtBQUs7QUFBQSxFQUNMLFFBQVE7QUFBQSxFQUNSLE9BQU87QUFBQSxFQUNQLFlBQVk7QUFBQSxFQUNaLEtBQUs7QUFBQSxFQUNMLE9BQU87QUFBQSxFQUNQLFFBQVE7QUFBQSxFQUNSLFFBQVE7QUFBQSxFQUNSLE1BQU07QUFBQSxFQUNOLFdBQVc7QUFBQSxFQUNYLEtBQUs7QUFBQSxFQUNMLFVBQVU7QUFBQSxFQUNWLFlBQVk7QUFBQSxFQUNaLFNBQVM7QUFBQSxFQUNULFVBQVU7QUFBQSxFQUNWLFNBQVM7QUFBQSxFQUNULFlBQVk7QUFBQSxFQUNaLE1BQU07QUFBQSxFQUNOLFFBQVE7QUFBQSxFQUNSLE1BQU07QUFBQSxFQUNOLFNBQVM7QUFBQSxFQUNULE9BQU87QUFBQSxFQUNQLFNBQVM7QUFBQSxFQUNULE1BQU07QUFBQSxFQUNOLFdBQVc7QUFBQSxFQUNYLFFBQVE7QUFBQSxFQUNSLE9BQU87QUFBQSxFQUNQLFlBQVk7QUFBQSxFQUNaLFdBQVc7QUFBQSxFQUNYLFNBQVM7QUFBQSxFQUNULE1BQU07QUFBQSxFQUNOLEtBQUs7QUFBQSxFQUNMLE1BQU07QUFBQSxFQUNOLFNBQVM7QUFBQSxF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QWM7QUFBQSxNQUN2QixHQUFHLEdBQUk7QUFBQSxJQUNYO0FBQUEsSUFDQSxXQUFXO0FBQ1AsVUFBSSxDQUFDLEtBQUssYUFBYTtBQUNuQixhQUFLLE1BQU0sY0FBYyxLQUFLO0FBQzlCLGFBQUssY0FBYztBQUFBLE1BQ3ZCO0FBRUEsV0FBSyxlQUFjO0FBQ25CLFVBQUksS0FBSyxjQUFjLEtBQUs7QUFDeEIsYUFBSyxjQUFjO0FBQUEsTUFDdkI7QUFDQSxXQUFLLFlBQVk7QUFBQSxJQUNyQjtBQUFBLElBRUEsWUFBWTtBQUVSLFlBQU0sU0FBUyxRQUFRLFFBQVEsVUFBVTtBQUN6QyxZQUFNLFNBQVMsUUFBUSxPQUFPLFVBQVU7QUFDeEMsYUFBTyxJQUFJLE1BQU0sS0FBSyxNQUFNLFFBQVE7QUFBQSxRQUNoQyxNQUFNLEtBQUssTUFBTTtBQUFBLFFBQ2pCLE1BQU0sS0FBSyxNQUFNO0FBQUEsUUFDakIsU0FBUyxLQUFLLE1BQU07QUFBQSxNQUN4QixDQUFDO0FBQUEsSUFDTDtBQUFBLElBQ0EsY0FBYztBQUNWLFVBQUksUUFBUSxLQUFLLFNBQVM7QUFDMUIsWUFBTSxPQUFPO0FBQUEsUUFDVCxVQUFTLENBQUM7QUFBQSxVQUNOLE1BQU0sQ0FBQyxLQUFLLGFBQWEsTUFBTSxLQUFLLFdBQVc7QUFBQSxVQUMvQyxpQkFBaUIsQ0FBQyxLQUFLLGVBQWUsR0FBRyxNQUFNO0FBQUEsUUFDbkQsQ0FBQztBQUFBLE1BQ0w7QUFDQSxZQUFNLE9BQU8sUUFBUTtBQUFBLElBQ3pCO0FBQUEsSUFDQSxpQkFBaUI7QUFDYixhQUFPLEtBQUssZUFBYyxLQUFLLFVBQVMsS0FBSyxlQUFlLEtBQUssV0FBVTtBQUFBLElBQy9FO0FBQUEsSUFDQSxXQUFXO0FBQ1AsYUFBTyxNQUFNLFNBQVMsS0FBSyxNQUFNLE1BQU07QUFBQSxJQUMzQztBQUFBLEVBQ0o7QUFDSjsiLAogICJuYW1lcyI6IFsibCIsICJzIiwgImwiLCAibiIsICJjb2xvciIsICJub29wIiwgInVpZCIsICJpZCIsICJpc051bGxPclVuZGVmIiwgInZhbHVlIiwgImlzQXJyYXkiLCAiQXJyYXkiLCAidHlwZSIsICJPYmplY3QiLCAicHJvdG90eXBlIiwgInRvU3RyaW5nIiwgImNhbGwiLCAic2xpY2UiLCAiaXNPYmplY3QiLCAiaXNOdW1iZXJGaW5pdGUiLCAiTnVtYmVyIiwgImlzRmluaXRlIiwgImZpbml0ZU9yRGVmYXVsdCIsICJkZWZhdWx0VmFsdWUiLCAidmFsdWVPckRlZmF1bHQiLCAidG9QZXJjZW50YWdlIiwgImRpbWVuc2lvbiIsICJlbmRzV2l0aCIsICJwYXJzZUZsb2F0IiwgInRvRGltZW5zaW9uIiwgImNhbGxiYWNrIiwgImZuIiwgImFyZ3MiLCAidGhpc0FyZyIsICJhcHBseSIsICJlYWNoIiwgImxvb3BhYmxlIiwgInJldmVyc2UiLCAiaSIsICJsZW4iLCAia2V5cyIsICJsZW5ndGgiLCAiX2VsZW1lbnRzRXF1YWwiLCAiYTAiLCAiYTEiLCAiaWxlbiIsICJ2MCIsICJ2MSIsICJkYXRhc2V0SW5kZXgiLCAiaW5kZXgiLCAiY2xvbmUiLCAic291cmNlIiwgIm1hcCIsICJ0YXJnZXQiLCAiY3JlYXRlIiwgImtsZW4iLCAiayIsICJpc1ZhbGlkS2V5IiwgImtleSIsICJpbmRleE9mIiwgIl9tZXJnZXIiLCAib3B0aW9ucyIsICJ0dmFsIiwgInN2YWwiLCAibWVyZ2UiLCAic291cmNlcyIsICJtZXJnZXIiLCAiY3VycmVudCIsICJtZXJnZUlmIiwgIl9tZXJnZXJJZiIsICJoYXNPd25Qcm9wZXJ0eSIsICJrZXlSZXNvbHZlcnMiLCAidiIsICJ4IiwgIm8iLCAieSIsICJfc3BsaXRLZXkiLCAia2V5IiwgInBhcnRzIiwgInNwbGl0IiwgImtleXMiLCAidG1wIiwgInBhcnQiLCAiZW5kc1dpdGgiLCAic2xpY2UiLCAicHVzaCIsICJfZ2V0S2V5UmVzb2x2ZXIiLCAib2JqIiwgImsiLCAicmVzb2x2ZU9iamVjdEtleSIsICJyZXNvbHZlciIsICJfY2FwaXRhbGl6ZSIsICJzdHIiLCAiY2hhckF0IiwgInRvVXBwZXJDYXNlIiwgImRlZmluZWQiLCAidmFsdWUiLCAiaXNGdW5jdGlvbiIsICJzZXRzRXF1YWwiLCAiYSIsICJiIiwgInNpemUiLCAiaXRlbSIsICJoYXMiLCAiX2lzQ2xpY2tFdmVudCIsICJlIiwgInR5cGUiLCAiUEkiLCAiTWF0aCIsICJUQVUiLCAiUElUQVUiLCAiSU5GSU5JVFkiLCAiTnVtYmVyIiwgIlBPU0lUSVZFX0lORklOSVRZIiwgIlJBRF9QRVJfREVHIiwgIkhBTEZfUEkiLCAiUVVBUlRFUl9QSSIsICJUV09fVEhJUkRTX1BJIiwgImxvZzEwIiwgInNpZ24iLCAiYWxtb3N0RXF1YWxzIiwgImVwc2lsb24iLCAiYWJzIiwgIm5pY2VOdW0iLCAicmFuZ2UiLCAicm91bmRlZFJhbmdlIiwgInJvdW5kIiwgIm5pY2VSYW5nZSIsICJwb3ciLCAiZmxvb3IiLCAiZnJhY3Rpb24iLCAibmljZUZyYWN0aW9uIiwgIl9mYWN0b3JpemUiLCAicmVzdWx0IiwgInNxcnQiLCAiaSIsICJzb3J0IiwgInBvcCIsICJpc051bWJlciIsICJuIiwgImlzTmFOIiwgInBhcnNlRmxvYXQiLCAiaXNGaW5pdGUiLCAiYWxtb3N0V2hvbGUiLCAicm91bmRlZCIsICJfc2V0TWluQW5kTWF4QnlLZXkiLCAiYXJyYXkiLCAidGFyZ2V0IiwgInByb3BlcnR5IiwgImlsZW4iLCAibGVuZ3RoIiwgIm1pbiIsICJtYXgiLCAidG9SYWRpYW5zIiwgImRlZ3JlZXMiLCAidG9EZWdyZWVzIiwgInJhZGlhbnMiLCAiX2RlY2ltYWxQbGFjZXMiLCAiaXNGaW5pdGVOdW1iZXIiLCAicCIsICJnZXRBbmdsZUZyb21Qb2ludCIsICJjZW50cmVQb2ludCIsICJhbmdsZVBvaW50IiwgImRpc3RhbmNlRnJvbVhDZW50ZXIiLCAiZGlzdGFuY2VGcm9tWUNlbnRlciIsICJyYWRpYWxEaXN0YW5jZUZyb21DZW50ZXIiLCAiYW5nbGUiLCAiYXRhbjIiLCAiZGlzdGFuY2UiLCAiZGlzdGFuY2VCZXR3ZWVuUG9pbnRzIiwgInB0MSIsICJwdDIiLCAiX2FuZ2xlRGlmZiIsICJfbm9ybWFsaXplQW5nbGUiLCAiX2FuZ2xlQmV0d2VlbiIsICJzdGFydCIsICJlbmQiLCAic2FtZUFuZ2xlSXNGdWxsQ2lyY2xlIiwgInMiLCAiYW5nbGVUb1N0YXJ0IiwgImFuZ2xlVG9FbmQiLCAic3RhcnRUb0FuZ2xlIiwgImVuZFRvQW5nbGUiLCAiX2xpbWl0VmFsdWUiLCAiX2ludDE2UmFuZ2UiLCAiX2lzQmV0d2VlbiIsICJfbG9va3VwIiwgInRhYmxlIiwgImNtcCIsICJpbmRleCIsICJoaSIsICJsbyIsICJtaWQiLCAiX2xvb2t1cEJ5S2V5IiwgImxhc3QiLCAidGkiLCAiX3Jsb29rdXBCeUtleSIsICJfZmlsdGVyQmV0d2VlbiIsICJ2YWx1ZXMiLCAiYXJyYXlFdmVudHMiLCAibGlzdGVuQXJyYXlFdmVudHMiLCAibGlzdGVuZXIiLCAiX2NoYXJ0anMiLCAibGlzdGVuZXJzIiwgIk9iamVjdCIsICJkZWZpbmVQcm9wZXJ0eSIsICJjb25maWd1cmFibGUiLCAiZW51bWVyYWJsZSIsICJmb3JFYWNoIiwgIm1ldGhvZCIsICJiYXNlIiwgImFyZ3MiLCAicmVzIiwgImFwcGx5IiwgIm9iamVjdCIsICJ1bmxpc3RlbkFycmF5RXZlbnRzIiwgInN0dWIiLCAiaW5kZXhPZiIsICJzcGxpY2UiLCAiX2FycmF5VW5pcXVlIiwgIml0ZW1zIiwgInNldCIsICJTZXQiLCAiQXJyYXkiLCAiZnJvbSIsICJyZXF1ZXN0QW5pbUZyYW1lIiwgIndpbmRvdyIsICJjYWxsYmFjayIsICJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCAidGhyb3R0bGVkIiwgImZuIiwgInRoaXNBcmciLCAiYXJnc1RvVXNlIiwgInRpY2tpbmciLCAiYXJncyIsICJjYWxsIiwgImFwcGx5IiwgImRlYm91bmNlIiwgImRlbGF5IiwgInRpbWVvdXQiLCAiY2xlYXJUaW1lb3V0IiwgInNldFRpbWVvdXQiLCAiX3RvTGVmdFJpZ2h0Q2VudGVyIiwgImFsaWduIiwgIl9hbGlnblN0YXJ0RW5kIiwgInN0YXJ0IiwgImVuZCIsICJfdGV4dFgiLCAibGVmdCIsICJyaWdodCIsICJydGwiLCAiY2hlY2siLCAiX2dldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHMiLCAibWV0YSIsICJwb2ludHMiLCAiYW5pbWF0aW9uc0Rpc2FibGVkIiwgInBvaW50Q291bnQiLCAibGVuZ3RoIiwgImNvdW50IiwgIl9zb3J0ZWQiLCAiaVNjYWxlIiwgIl9wYXJzZWQiLCAiYXhpcyIsICJtaW4iLCAibWF4IiwgIm1pbkRlZmluZWQiLCAibWF4RGVmaW5lZCIsICJnZXRVc2VyQm91bmRzIiwgIl9saW1pdFZhbHVlIiwgIk1hdGgiLCAiX2xvb2t1cEJ5S2V5IiwgImxvIiwgImdldFBpeGVsRm9yVmFsdWUiLCAiaGkiLCAiX3NjYWxlUmFuZ2VzQ2hhbmdlZCIsICJ4U2NhbGUiLCAieVNjYWxlIiwgIl9zY2FsZVJhbmdlcyIsICJuZXdSYW5nZXMiLCAieG1pbiIsICJ4bWF4IiwgInltaW4iLCAieW1heCIsICJjaGFuZ2VkIiwgIk9iamVjdCIsICJhc3NpZ24iLCAiYXRFZGdlIiwgInQiLCAiZWxhc3RpY0luIiwgInMiLCAicCIsICJwb3ciLCAic2luIiwgIlRBVSIsICJlbGFzdGljT3V0IiwgImVmZmVjdHMiLCAibGluZWFyIiwgImVhc2VJblF1YWQiLCAiZWFzZU91dFF1YWQiLCAiZWFzZUluT3V0UXVhZCIsICJlYXNlSW5DdWJpYyIsICJlYXNlT3V0Q3ViaWMiLCAiZWFzZUluT3V0Q3ViaWMiLCAiZWFzZUluUXVhcnQiLCAiZWFzZU91dFF1YXJ0IiwgImVhc2VJbk91dFF1YXJ0IiwgImVhc2VJblF1aW50IiwgImVhc2VPdXRRdWludCIsICJlYXNlSW5PdXRRdWludCIsICJlYXNlSW5TaW5lIiwgImNvcyIsICJIQUxGX1BJIiwgImVhc2VPdXRTaW5lIiwgImVhc2VJbk91dFNpbmUiLCAiUEkiLCAiZWFzZUluRXhwbyIsICJlYXNlT3V0RXhwbyIsICJlYXNlSW5PdXRFeHBvIiwgImVhc2VJbkNpcmMiLCAic3FydCIsICJlYXNlT3V0Q2lyYyIsICJlYXNlSW5PdXRDaXJjIiwgImVhc2VJbkVsYXN0aWMiLCAiZWFzZU91dEVsYXN0aWMiLCAiZWFzZUluT3V0RWxhc3RpYyIsICJlYXNlSW5CYWNrIiwgImVhc2VPdXRCYWNrIiwgImVhc2VJbk91dEJhY2siLCAiZWFzZUluQm91bmNlIiwgImVhc2VPdXRCb3VuY2UiLCAibSIsICJkIiwgImVhc2VJbk91dEJvdW5jZSIsICJpc1BhdHRlcm5PckdyYWRpZW50IiwgInZhbHVlIiwgInR5cGUiLCAidG9TdHJpbmciLCAiY29sb3IiLCAiQ29sb3IiLCAiZ2V0SG92ZXJDb2xvciIsICJzYXR1cmF0ZSIsICJkYXJrZW4iLCAiaGV4U3RyaW5nIiwgIm51bWJlcnMiLCAiY29sb3JzIiwgImFwcGx5QW5pbWF0aW9uc0RlZmF1bHRzIiwgImRlZmF1bHRzIiwgInNldCIsICJ1bmRlZmluZWQiLCAiZHVyYXRpb24iLCAiZWFzaW5nIiwgImZyb20iLCAibG9vcCIsICJ0byIsICJkZXNjcmliZSIsICJfZmFsbGJhY2siLCAiX2luZGV4YWJsZSIsICJfc2NyaXB0YWJsZSIsICJuYW1lIiwgInByb3BlcnRpZXMiLCAiYWN0aXZlIiwgImFuaW1hdGlvbiIsICJyZXNpemUiLCAic2hvdyIsICJhbmltYXRpb25zIiwgInZpc2libGUiLCAiaGlkZSIsICJ2IiwgImFwcGx5TGF5b3V0c0RlZmF1bHRzIiwgImF1dG9QYWRkaW5nIiwgInBhZGRpbmciLCAidG9wIiwgImJvdHRvbSIsICJpbnRsQ2FjaGUiLCAiTWFwIiwgImdldE51bWJlckZvcm1hdCIsICJsb2NhbGUiLCAib3B0aW9ucyIsICJjYWNoZUtleSIsICJKU09OIiwgInN0cmluZ2lmeSIsICJmb3JtYXR0ZXIiLCAiZ2V0IiwgIkludGwiLCAiTnVtYmVyRm9ybWF0IiwgImZvcm1hdE51bWJlciIsICJudW0iLCAiZm9ybWF0IiwgImZvcm1hdHRlcnMiLCAidmFsdWVzIiwgImlzQXJyYXkiLCAibnVtZXJpYyIsICJ0aWNrVmFsdWUiLCAiaW5kZXgiLCAidGlja3MiLCAiY2hhcnQiLCAibm90YXRpb24iLCAiZGVsdGEiLCAibWF4VGljayIsICJhYnMiLCAiY2FsY3VsYXRlRGVsdGEiLCAibG9nRGVsdGEiLCAibG9nMTAiLCAibnVtRGVjaW1hbCIsICJpc05hTiIsICJmbG9vciIsICJtaW5pbXVtRnJhY3Rpb25EaWdpdHMiLCAibWF4aW11bUZyYWN0aW9uRGlnaXRzIiwgImxvZ2FyaXRobWljIiwgInJlbWFpbiIsICJzaWduaWZpY2FuZCIsICJpbmNsdWRlcyIsICJhcHBseVNjYWxlRGVmYXVsdHMiLCAiZGlzcGxheSIsICJvZmZzZXQiLCAicmV2ZXJzZSIsICJiZWdpbkF0WmVybyIsICJib3VuZHMiLCAiY2xpcCIsICJncmFjZSIsICJncmlkIiwgImxpbmVXaWR0aCIsICJkcmF3T25DaGFydEFyZWEiLCAiZHJhd1RpY2tzIiwgInRpY2tMZW5ndGgiLCAidGlja1dpZHRoIiwgIl9jdHgiLCAidGlja0NvbG9yIiwgImJvcmRlciIsICJkYXNoIiwgImRhc2hPZmZzZXQiLCAid2lkdGgiLCAidGl0bGUiLCAidGV4dCIsICJtaW5Sb3RhdGlvbiIsICJtYXhSb3RhdGlvbiIsICJtaXJyb3IiLCAidGV4dFN0cm9rZVdpZHRoIiwgInRleHRTdHJva2VDb2xvciIsICJhdXRvU2tpcCIsICJhdXRvU2tpcFBhZGRpbmciLCAibGFiZWxPZmZzZXQiLCAiVGlja3MiLCAibWlub3IiLCAibWFqb3IiLCAiY3Jvc3NBbGlnbiIsICJzaG93TGFiZWxCYWNrZHJvcCIsICJiYWNrZHJvcENvbG9yIiwgImJhY2tkcm9wUGFkZGluZyIsICJyb3V0ZSIsICJzdGFydHNXaXRoIiwgIm92ZXJyaWRlcyIsICJjcmVhdGUiLCAiZGVzY3JpcHRvcnMiLCAiZ2V0U2NvcGUiLCAibm9kZSIsICJrZXkiLCAia2V5cyIsICJzcGxpdCIsICJpIiwgIm4iLCAiayIsICJyb290IiwgInNjb3BlIiwgIm1lcmdlIiwgIkRlZmF1bHRzIiwgImNvbnN0cnVjdG9yIiwgIl9kZXNjcmlwdG9ycyIsICJfYXBwbGllcnMiLCAiYmFja2dyb3VuZENvbG9yIiwgImJvcmRlckNvbG9yIiwgImRhdGFzZXRzIiwgImRldmljZVBpeGVsUmF0aW8iLCAiY29udGV4dCIsICJwbGF0Zm9ybSIsICJnZXREZXZpY2VQaXhlbFJhdGlvIiwgImVsZW1lbnRzIiwgImV2ZW50cyIsICJmb250IiwgImZhbWlseSIsICJzaXplIiwgInN0eWxlIiwgImxpbmVIZWlnaHQiLCAid2VpZ2h0IiwgImhvdmVyIiwgImhvdmVyQmFja2dyb3VuZENvbG9yIiwgImN0eCIsICJob3ZlckJvcmRlckNvbG9yIiwgImhvdmVyQ29sb3IiLCAiaW5kZXhBeGlzIiwgImludGVyYWN0aW9uIiwgIm1vZGUiLCAiaW50ZXJzZWN0IiwgImluY2x1ZGVJbnZpc2libGUiLCAibWFpbnRhaW5Bc3BlY3RSYXRpbyIsICJvbkhvdmVyIiwgIm9uQ2xpY2siLCAicGFyc2luZyIsICJwbHVnaW5zIiwgInJlc3BvbnNpdmUiLCAic2NhbGUiLCAic2NhbGVzIiwgInNob3dMaW5lIiwgImRyYXdBY3RpdmVFbGVtZW50c09uVG9wIiwgIm92ZXJyaWRlIiwgInRhcmdldFNjb3BlIiwgInRhcmdldE5hbWUiLCAic2NvcGVPYmplY3QiLCAidGFyZ2V0U2NvcGVPYmplY3QiLCAicHJpdmF0ZU5hbWUiLCAiZGVmaW5lUHJvcGVydGllcyIsICJ3cml0YWJsZSIsICJlbnVtZXJhYmxlIiwgImxvY2FsIiwgInRhcmdldCIsICJpc09iamVjdCIsICJ2YWx1ZU9yRGVmYXVsdCIsICJhcHBsaWVycyIsICJmb3JFYWNoIiwgInRvRm9udFN0cmluZyIsICJpc051bGxPclVuZGVmIiwgIl9tZWFzdXJlVGV4dCIsICJkYXRhIiwgImdjIiwgImxvbmdlc3QiLCAic3RyaW5nIiwgInRleHRXaWR0aCIsICJtZWFzdXJlVGV4dCIsICJwdXNoIiwgIl9sb25nZXN0VGV4dCIsICJhcnJheU9mVGhpbmdzIiwgImNhY2hlIiwgImdhcmJhZ2VDb2xsZWN0IiwgInNhdmUiLCAiaWxlbiIsICJqIiwgImpsZW4iLCAidGhpbmciLCAibmVzdGVkVGhpbmciLCAicmVzdG9yZSIsICJnY0xlbiIsICJzcGxpY2UiLCAiX2FsaWduUGl4ZWwiLCAicGl4ZWwiLCAiY3VycmVudERldmljZVBpeGVsUmF0aW8iLCAiaGFsZldpZHRoIiwgInJvdW5kIiwgImNsZWFyQ2FudmFzIiwgImNhbnZhcyIsICJnZXRDb250ZXh0IiwgInJlc2V0VHJhbnNmb3JtIiwgImNsZWFyUmVjdCIsICJoZWlnaHQiLCAiZHJhd1BvaW50IiwgIngiLCAieSIsICJkcmF3UG9pbnRMZWdlbmQiLCAidyIsICJ4T2Zmc2V0IiwgInlPZmZzZXQiLCAiY29ybmVyUmFkaXVzIiwgInhPZmZzZXRXIiwgInlPZmZzZXRXIiwgInBvaW50U3R5bGUiLCAicm90YXRpb24iLCAicmFkaXVzIiwgInJhZCIsICJSQURfUEVSX0RFRyIsICJ0cmFuc2xhdGUiLCAicm90YXRlIiwgImRyYXdJbWFnZSIsICJiZWdpblBhdGgiLCAiZWxsaXBzZSIsICJhcmMiLCAiY2xvc2VQYXRoIiwgIm1vdmVUbyIsICJUV09fVEhJUkRTX1BJIiwgImxpbmVUbyIsICJRVUFSVEVSX1BJIiwgIlNRUlQxXzIiLCAicmVjdCIsICJmaWxsIiwgImJvcmRlcldpZHRoIiwgInN0cm9rZSIsICJfaXNQb2ludEluQXJlYSIsICJwb2ludCIsICJhcmVhIiwgIm1hcmdpbiIsICJjbGlwQXJlYSIsICJ1bmNsaXBBcmVhIiwgIl9zdGVwcGVkTGluZVRvIiwgInByZXZpb3VzIiwgImZsaXAiLCAibWlkcG9pbnQiLCAiX2JlemllckN1cnZlVG8iLCAiYmV6aWVyQ3VydmVUbyIsICJjcDF4IiwgImNwMngiLCAiY3AxeSIsICJjcDJ5IiwgInNldFJlbmRlck9wdHMiLCAib3B0cyIsICJ0cmFuc2xhdGlvbiIsICJmaWxsU3R5bGUiLCAidGV4dEFsaWduIiwgInRleHRCYXNlbGluZSIsICJkZWNvcmF0ZVRleHQiLCAibGluZSIsICJzdHJpa2V0aHJvdWdoIiwgInVuZGVybGluZSIsICJtZXRyaWNzIiwgImFjdHVhbEJvdW5kaW5nQm94TGVmdCIsICJhY3R1YWxCb3VuZGluZ0JveFJpZ2h0IiwgImFjdHVhbEJvdW5kaW5nQm94QXNjZW50IiwgImFjdHVhbEJvdW5kaW5nQm94RGVzY2VudCIsICJ5RGVjb3JhdGlvbiIsICJzdHJva2VTdHlsZSIsICJkZWNvcmF0aW9uV2lkdGgiLCAiZHJhd0JhY2tkcm9wIiwgIm9sZENvbG9yIiwgImZpbGxSZWN0IiwgInJlbmRlclRleHQiLCAibGluZXMiLCAic3Ryb2tlV2lkdGgiLCAic3Ryb2tlQ29sb3IiLCAiYmFja2Ryb3AiLCAic3Ryb2tlVGV4dCIsICJtYXhXaWR0aCIsICJmaWxsVGV4dCIsICJOdW1iZXIiLCAiYWRkUm91bmRlZFJlY3RQYXRoIiwgImgiLCAidG9wTGVmdCIsICJib3R0b21MZWZ0IiwgImJvdHRvbVJpZ2h0IiwgInRvcFJpZ2h0IiwgIkxJTkVfSEVJR0hUIiwgIkZPTlRfU1RZTEUiLCAidG9MaW5lSGVpZ2h0IiwgIm1hdGNoZXMiLCAibWF0Y2giLCAibnVtYmVyT3JaZXJvIiwgIl9yZWFkVmFsdWVUb1Byb3BzIiwgInByb3BzIiwgInJldCIsICJvYmpQcm9wcyIsICJyZWFkIiwgInByb3AiLCAidG9UUkJMIiwgInRvVFJCTENvcm5lcnMiLCAidG9QYWRkaW5nIiwgIm9iaiIsICJ0b0ZvbnQiLCAiZmFsbGJhY2siLCAicGFyc2VJbnQiLCAiY29uc29sZSIsICJ3YXJuIiwgInJlc29sdmUiLCAiaW5wdXRzIiwgImluZm8iLCAiY2FjaGVhYmxlIiwgIl9hZGRHcmFjZSIsICJtaW5tYXgiLCAiY2hhbmdlIiwgInRvRGltZW5zaW9uIiwgImtlZXBaZXJvIiwgImFkZCIsICJjcmVhdGVDb250ZXh0IiwgInBhcmVudENvbnRleHQiLCAiX2NyZWF0ZVJlc29sdmVyIiwgInNjb3BlcyIsICJwcmVmaXhlcyIsICJyb290U2NvcGVzIiwgImdldFRhcmdldCIsICJmaW5hbFJvb3RTY29wZXMiLCAiX3Jlc29sdmUiLCAiU3ltYm9sIiwgInRvU3RyaW5nVGFnIiwgIl9jYWNoZWFibGUiLCAiX3Njb3BlcyIsICJfcm9vdFNjb3BlcyIsICJfZ2V0VGFyZ2V0IiwgIlByb3h5IiwgImRlbGV0ZVByb3BlcnR5IiwgIl9rZXlzIiwgIl9jYWNoZWQiLCAiX3Jlc29sdmVXaXRoUHJlZml4ZXMiLCAiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwgIlJlZmxlY3QiLCAiZ2V0UHJvdG90eXBlT2YiLCAiaGFzIiwgImdldEtleXNGcm9tQWxsU2NvcGVzIiwgIm93bktleXMiLCAic3RvcmFnZSIsICJfc3RvcmFnZSIsICJfYXR0YWNoQ29udGV4dCIsICJwcm94eSIsICJzdWJQcm94eSIsICJkZXNjcmlwdG9yRGVmYXVsdHMiLCAiX3Byb3h5IiwgIl9jb250ZXh0IiwgIl9zdWJQcm94eSIsICJfc3RhY2siLCAiU2V0IiwgInNldENvbnRleHQiLCAicmVjZWl2ZXIiLCAiX3Jlc29sdmVXaXRoQ29udGV4dCIsICJhbGxLZXlzIiwgImNvbmZpZ3VyYWJsZSIsICJzY3JpcHRhYmxlIiwgImluZGV4YWJsZSIsICJfYWxsS2V5cyIsICJpc1NjcmlwdGFibGUiLCAiaXNGdW5jdGlvbiIsICJpc0luZGV4YWJsZSIsICJyZWFkS2V5IiwgInByZWZpeCIsICJfY2FwaXRhbGl6ZSIsICJuZWVkc1N1YlJlc29sdmVyIiwgInByb3RvdHlwZSIsICJoYXNPd25Qcm9wZXJ0eSIsICJfcmVzb2x2ZVNjcmlwdGFibGUiLCAiX3Jlc29sdmVBcnJheSIsICJnZXRWYWx1ZSIsICJFcnJvciIsICJBcnJheSIsICJqb2luIiwgImRlbGV0ZSIsICJjcmVhdGVTdWJSZXNvbHZlciIsICJhcnIiLCAiZmlsdGVyIiwgIml0ZW0iLCAicmVzb2x2ZXIiLCAicmVzb2x2ZUZhbGxiYWNrIiwgInBhcmVudCIsICJyZXNvbHZlT2JqZWN0S2V5IiwgImFkZFNjb3BlcyIsICJwYXJlbnRTY29wZXMiLCAicGFyZW50RmFsbGJhY2siLCAiYWxsU2NvcGVzIiwgImFkZFNjb3Blc0Zyb21LZXkiLCAic3ViR2V0VGFyZ2V0IiwgInJlc29sdmVLZXlzRnJvbUFsbFNjb3BlcyIsICJfcGFyc2VPYmplY3REYXRhUmFkaWFsU2NhbGUiLCAiX3BhcnNpbmciLCAicGFyc2VkIiwgInIiLCAicGFyc2UiLCAiRVBTSUxPTiIsICJnZXRQb2ludCIsICJza2lwIiwgImdldFZhbHVlQXhpcyIsICJzcGxpbmVDdXJ2ZSIsICJmaXJzdFBvaW50IiwgIm1pZGRsZVBvaW50IiwgImFmdGVyUG9pbnQiLCAiY3VycmVudCIsICJuZXh0IiwgImQwMSIsICJkaXN0YW5jZUJldHdlZW5Qb2ludHMiLCAiZDEyIiwgInMwMSIsICJzMTIiLCAiZmEiLCAiZmIiLCAibW9ub3RvbmVBZGp1c3QiLCAiZGVsdGFLIiwgIm1LIiwgInBvaW50c0xlbiIsICJhbHBoYUsiLCAiYmV0YUsiLCAidGF1SyIsICJzcXVhcmVkTWFnbml0dWRlIiwgInBvaW50Q3VycmVudCIsICJwb2ludEFmdGVyIiwgImFsbW9zdEVxdWFscyIsICJtb25vdG9uZUNvbXB1dGUiLCAidmFsdWVBeGlzIiwgInBvaW50QmVmb3JlIiwgImlQaXhlbCIsICJ2UGl4ZWwiLCAic3BsaW5lQ3VydmVNb25vdG9uZSIsICJzbG9wZURlbHRhIiwgInNpZ24iLCAiY2FwQ29udHJvbFBvaW50IiwgInB0IiwgImNhcEJlemllclBvaW50cyIsICJpbkFyZWEiLCAiaW5BcmVhUHJldiIsICJpbkFyZWFOZXh0IiwgIl91cGRhdGVCZXppZXJDb250cm9sUG9pbnRzIiwgImNvbnRyb2xQb2ludHMiLCAic3BhbkdhcHMiLCAiY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSIsICJwcmV2IiwgInRlbnNpb24iLCAiX2lzRG9tU3VwcG9ydGVkIiwgImRvY3VtZW50IiwgIl9nZXRQYXJlbnROb2RlIiwgImRvbU5vZGUiLCAicGFyZW50Tm9kZSIsICJob3N0IiwgInBhcnNlTWF4U3R5bGUiLCAic3R5bGVWYWx1ZSIsICJwYXJlbnRQcm9wZXJ0eSIsICJ2YWx1ZUluUGl4ZWxzIiwgImluZGV4T2YiLCAiZ2V0Q29tcHV0ZWRTdHlsZSIsICJlbGVtZW50IiwgIm93bmVyRG9jdW1lbnQiLCAiZGVmYXVsdFZpZXciLCAiZ2V0U3R5bGUiLCAiZWwiLCAicHJvcGVydHkiLCAiZ2V0UHJvcGVydHlWYWx1ZSIsICJwb3NpdGlvbnMiLCAiZ2V0UG9zaXRpb25lZFN0eWxlIiwgInN0eWxlcyIsICJzdWZmaXgiLCAicmVzdWx0IiwgInBvcyIsICJwYXJzZUZsb2F0IiwgInVzZU9mZnNldFBvcyIsICJzaGFkb3dSb290IiwgImdldENhbnZhc1Bvc2l0aW9uIiwgImUiLCAidG91Y2hlcyIsICJzb3VyY2UiLCAib2Zmc2V0WCIsICJvZmZzZXRZIiwgImJveCIsICJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCAiY2xpZW50WCIsICJjbGllbnRZIiwgImdldFJlbGF0aXZlUG9zaXRpb24iLCAiZXZlbnQiLCAiYm9yZGVyQm94IiwgImJveFNpemluZyIsICJwYWRkaW5ncyIsICJib3JkZXJzIiwgImdldENvbnRhaW5lclNpemUiLCAibWF4SGVpZ2h0IiwgImNvbnRhaW5lciIsICJjbGllbnRXaWR0aCIsICJjbGllbnRIZWlnaHQiLCAiY29udGFpbmVyU3R5bGUiLCAiY29udGFpbmVyQm9yZGVyIiwgImNvbnRhaW5lclBhZGRpbmciLCAiSU5GSU5JVFkiLCAicm91bmQxIiwgImdldE1heGltdW1TaXplIiwgImJiV2lkdGgiLCAiYmJIZWlnaHQiLCAiYXNwZWN0UmF0aW8iLCAibWFyZ2lucyIsICJjb250YWluZXJTaXplIiwgIm1haW50YWluSGVpZ2h0IiwgInJldGluYVNjYWxlIiwgImZvcmNlUmF0aW8iLCAiZm9yY2VTdHlsZSIsICJwaXhlbFJhdGlvIiwgImRldmljZUhlaWdodCIsICJkZXZpY2VXaWR0aCIsICJzZXRUcmFuc2Zvcm0iLCAic3VwcG9ydHNFdmVudExpc3RlbmVyT3B0aW9ucyIsICJwYXNzaXZlU3VwcG9ydGVkIiwgInBhc3NpdmUiLCAiYWRkRXZlbnRMaXN0ZW5lciIsICJyZW1vdmVFdmVudExpc3RlbmVyIiwgInJlYWRVc2VkU2l6ZSIsICJfcG9pbnRJbkxpbmUiLCAicDEiLCAicDIiLCAiX3N0ZXBwZWRJbnRlcnBvbGF0aW9uIiwgIl9iZXppZXJJbnRlcnBvbGF0aW9uIiwgImNwMSIsICJjcDIiLCAiYSIsICJiIiwgImMiLCAiZ2V0UmlnaHRUb0xlZnRBZGFwdGVyIiwgInJlY3RYIiwgInNldFdpZHRoIiwgInhQbHVzIiwgImxlZnRGb3JMdHIiLCAiaXRlbVdpZHRoIiwgImdldExlZnRUb1JpZ2h0QWRhcHRlciIsICJfaXRlbVdpZHRoIiwgImdldFJ0bEFkYXB0ZXIiLCAib3ZlcnJpZGVUZXh0RGlyZWN0aW9uIiwgImRpcmVjdGlvbiIsICJvcmlnaW5hbCIsICJnZXRQcm9wZXJ0eVByaW9yaXR5IiwgInNldFByb3BlcnR5IiwgInByZXZUZXh0RGlyZWN0aW9uIiwgInJlc3RvcmVUZXh0RGlyZWN0aW9uIiwgInByb3BlcnR5Rm4iLCAiYmV0d2VlbiIsICJfYW5nbGVCZXR3ZWVuIiwgImNvbXBhcmUiLCAiX2FuZ2xlRGlmZiIsICJub3JtYWxpemUiLCAiX25vcm1hbGl6ZUFuZ2xlIiwgIl9pc0JldHdlZW4iLCAibm9ybWFsaXplU2VnbWVudCIsICJnZXRTZWdtZW50IiwgInNlZ21lbnQiLCAic3RhcnRCb3VuZCIsICJlbmRCb3VuZCIsICJfYm91bmRTZWdtZW50IiwgImluc2lkZSIsICJzdWJTdGFydCIsICJwcmV2VmFsdWUiLCAic3RhcnRJc0JlZm9yZSIsICJlbmRJc0JlZm9yZSIsICJzaG91bGRTdGFydCIsICJzaG91bGRTdG9wIiwgIl9ib3VuZFNlZ21lbnRzIiwgInNlZ21lbnRzIiwgInN1YiIsICJmaW5kU3RhcnRBbmRFbmQiLCAic29saWRTZWdtZW50cyIsICJsYXN0IiwgImN1ciIsICJzdG9wIiwgIl9jb21wdXRlU2VnbWVudHMiLCAic2VnbWVudE9wdGlvbnMiLCAiX2xvb3AiLCAic3BsaXRCeVN0eWxlcyIsICJjb21wbGV0ZUxvb3AiLCAiX2Z1bGxMb29wIiwgImRvU3BsaXRCeVN0eWxlcyIsICJjaGFydENvbnRleHQiLCAiX2NoYXJ0IiwgImJhc2VTdHlsZSIsICJyZWFkU3R5bGUiLCAiX2RhdGFzZXRJbmRleCIsICJkYXRhc2V0SW5kZXgiLCAicHJldlN0eWxlIiwgImFkZFN0eWxlIiwgImwiLCAic3QiLCAiZGlyIiwgInAwIiwgInAwRGF0YUluZGV4IiwgInAxRGF0YUluZGV4IiwgInN0eWxlQ2hhbmdlZCIsICJib3JkZXJDYXBTdHlsZSIsICJib3JkZXJEYXNoIiwgImJvcmRlckRhc2hPZmZzZXQiLCAiYm9yZGVySm9pblN0eWxlIiwgInJlcGxhY2VyIiwgIkFuaW1hdG9yIiwgImNvbnN0cnVjdG9yIiwgIl9yZXF1ZXN0IiwgIl9jaGFydHMiLCAiTWFwIiwgIl9ydW5uaW5nIiwgIl9sYXN0RGF0ZSIsICJ1bmRlZmluZWQiLCAiX25vdGlmeSIsICJjaGFydCIsICJhbmltcyIsICJkYXRlIiwgInR5cGUiLCAiY2FsbGJhY2tzIiwgImxpc3RlbmVycyIsICJudW1TdGVwcyIsICJkdXJhdGlvbiIsICJmb3JFYWNoIiwgImZuIiwgImluaXRpYWwiLCAiY3VycmVudFN0ZXAiLCAiTWF0aCIsICJtaW4iLCAic3RhcnQiLCAiX3JlZnJlc2giLCAicmVxdWVzdEFuaW1GcmFtZSIsICJjYWxsIiwgIndpbmRvdyIsICJfdXBkYXRlIiwgIkRhdGUiLCAibm93IiwgInJlbWFpbmluZyIsICJydW5uaW5nIiwgIml0ZW1zIiwgImxlbmd0aCIsICJpIiwgImRyYXciLCAiaXRlbSIsICJfYWN0aXZlIiwgIl90b3RhbCIsICJ0aWNrIiwgInBvcCIsICJfZ2V0QW5pbXMiLCAiY2hhcnRzIiwgImdldCIsICJjb21wbGV0ZSIsICJwcm9ncmVzcyIsICJzZXQiLCAibGlzdGVuIiwgImV2ZW50IiwgImNiIiwgInB1c2giLCAiYWRkIiwgImhhcyIsICJyZWR1Y2UiLCAiYWNjIiwgImN1ciIsICJtYXgiLCAiX2R1cmF0aW9uIiwgInN0b3AiLCAiY2FuY2VsIiwgInJlbW92ZSIsICJkZWxldGUiLCAidHJhbnNwYXJlbnQiLCAiaW50ZXJwb2xhdG9ycyIsICJib29sZWFuIiwgImZyb20iLCAidG8iLCAiZmFjdG9yIiwgImNvbG9yIiwgImMwIiwgImhlbHBlcnNDb2xvciIsICJjMSIsICJ2YWxpZCIsICJtaXgiLCAiaGV4U3RyaW5nIiwgIm51bWJlciIsICJBbmltYXRpb24iLCAiY2ZnIiwgInRhcmdldCIsICJwcm9wIiwgImN1cnJlbnRWYWx1ZSIsICJyZXNvbHZlIiwgIl9mbiIsICJfZWFzaW5nIiwgImVmZmVjdHMiLCAiZWFzaW5nIiwgImxpbmVhciIsICJfc3RhcnQiLCAiZmxvb3IiLCAiZGVsYXkiLCAiX2xvb3AiLCAibG9vcCIsICJfdGFyZ2V0IiwgIl9wcm9wIiwgIl9mcm9tIiwgIl90byIsICJfcHJvbWlzZXMiLCAiYWN0aXZlIiwgInVwZGF0ZSIsICJlbGFwc2VkIiwgInJlbWFpbiIsICJ3YWl0IiwgInByb21pc2VzIiwgIlByb21pc2UiLCAicmVzIiwgInJlaiIsICJyZXNvbHZlZCIsICJtZXRob2QiLCAiQW5pbWF0aW9ucyIsICJjb25maWciLCAiX2NoYXJ0IiwgIl9wcm9wZXJ0aWVzIiwgImNvbmZpZ3VyZSIsICJpc09iamVjdCIsICJhbmltYXRpb25PcHRpb25zIiwgIk9iamVjdCIsICJrZXlzIiwgImRlZmF1bHRzIiwgImFuaW1hdGlvbiIsICJhbmltYXRlZFByb3BzIiwgImdldE93blByb3BlcnR5TmFtZXMiLCAia2V5IiwgIm9wdGlvbiIsICJpc0FycmF5IiwgInByb3BlcnRpZXMiLCAiX2FuaW1hdGVPcHRpb25zIiwgInZhbHVlcyIsICJuZXdPcHRpb25zIiwgIm9wdGlvbnMiLCAicmVzb2x2ZVRhcmdldE9wdGlvbnMiLCAiYW5pbWF0aW9ucyIsICJfY3JlYXRlQW5pbWF0aW9ucyIsICIkc2hhcmVkIiwgImF3YWl0QWxsIiwgIiRhbmltYXRpb25zIiwgInRoZW4iLCAicHJvcHMiLCAiY2hhckF0IiwgInZhbHVlIiwgInNpemUiLCAiYXNzaWduIiwgImFuaW1hdG9yIiwgImFuaW0iLCAiYWxsIiwgInNjYWxlQ2xpcCIsICJzY2FsZSIsICJhbGxvd2VkT3ZlcmZsb3ciLCAib3B0cyIsICJyZXZlcnNlIiwgImVuZCIsICJkZWZhdWx0Q2xpcCIsICJ4U2NhbGUiLCAieVNjYWxlIiwgIngiLCAieSIsICJ0b3AiLCAicmlnaHQiLCAiYm90dG9tIiwgImxlZnQiLCAidG9DbGlwIiwgInQiLCAiciIsICJiIiwgImwiLCAiZGlzYWJsZWQiLCAiZ2V0U29ydGVkRGF0YXNldEluZGljZXMiLCAiZmlsdGVyVmlzaWJsZSIsICJtZXRhc2V0cyIsICJfZ2V0U29ydGVkRGF0YXNldE1ldGFzIiwgImlsZW4iLCAiaW5kZXgiLCAiYXBwbHlTdGFjayIsICJzdGFjayIsICJkc0luZGV4IiwgInNpbmdsZU1vZGUiLCAibW9kZSIsICJkYXRhc2V0SW5kZXgiLCAib3RoZXJWYWx1ZSIsICJpc0Zpbml0ZSIsICJzaWduIiwgImNvbnZlcnRPYmplY3REYXRhVG9BcnJheSIsICJkYXRhIiwgImFkYXRhIiwgIkFycmF5IiwgImlzU3RhY2tlZCIsICJtZXRhIiwgInN0YWNrZWQiLCAiZ2V0U3RhY2tLZXkiLCAiaW5kZXhTY2FsZSIsICJ2YWx1ZVNjYWxlIiwgImlkIiwgImdldFVzZXJCb3VuZHMiLCAibWluRGVmaW5lZCIsICJtYXhEZWZpbmVkIiwgIk51bWJlciIsICJORUdBVElWRV9JTkZJTklUWSIsICJQT1NJVElWRV9JTkZJTklUWSIsICJnZXRPckNyZWF0ZVN0YWNrIiwgInN0YWNrcyIsICJzdGFja0tleSIsICJpbmRleFZhbHVlIiwgInN1YlN0YWNrIiwgImdldExhc3RJbmRleEluU3RhY2siLCAidlNjYWxlIiwgInBvc2l0aXZlIiwgImdldE1hdGNoaW5nVmlzaWJsZU1ldGFzIiwgInVwZGF0ZVN0YWNrcyIsICJjb250cm9sbGVyIiwgInBhcnNlZCIsICJfY2FjaGVkTWV0YSIsICJfc3RhY2tzIiwgImlTY2FsZSIsICJpQXhpcyIsICJheGlzIiwgInZBeGlzIiwgIml0ZW1TdGFja3MiLCAiX3RvcCIsICJfYm90dG9tIiwgInZpc3VhbFZhbHVlcyIsICJfdmlzdWFsVmFsdWVzIiwgImdldEZpcnN0U2NhbGVJZCIsICJzY2FsZXMiLCAiZmlsdGVyIiwgInNoaWZ0IiwgImNyZWF0ZURhdGFzZXRDb250ZXh0IiwgInBhcmVudCIsICJjcmVhdGVDb250ZXh0IiwgImRhdGFzZXQiLCAiY3JlYXRlRGF0YUNvbnRleHQiLCAiZWxlbWVudCIsICJkYXRhSW5kZXgiLCAicmF3IiwgImNsZWFyU3RhY2tzIiwgIl9wYXJzZWQiLCAiaXNEaXJlY3RVcGRhdGVNb2RlIiwgImNsb25lSWZOb3RTaGFyZWQiLCAiY2FjaGVkIiwgInNoYXJlZCIsICJjcmVhdGVTdGFjayIsICJjYW5TdGFjayIsICJoaWRkZW4iLCAiX3N0YWNrZWQiLCAiRGF0YXNldENvbnRyb2xsZXIiLCAiX2N0eCIsICJjdHgiLCAiX2NhY2hlZERhdGFPcHRzIiwgImdldE1ldGEiLCAiX3R5cGUiLCAiX3BhcnNpbmciLCAiX2RhdGEiLCAiX29iamVjdERhdGEiLCAiX3NoYXJlZE9wdGlvbnMiLCAiX2RyYXdTdGFydCIsICJfZHJhd0NvdW50IiwgImVuYWJsZU9wdGlvblNoYXJpbmciLCAic3VwcG9ydHNEZWNpbWF0aW9uIiwgIiRjb250ZXh0IiwgIl9zeW5jTGlzdCIsICJkYXRhc2V0RWxlbWVudFR5cGUiLCAiZGF0YUVsZW1lbnRUeXBlIiwgImluaXRpYWxpemUiLCAibGlua1NjYWxlcyIsICJhZGRFbGVtZW50cyIsICJmaWxsIiwgImlzUGx1Z2luRW5hYmxlZCIsICJjb25zb2xlIiwgIndhcm4iLCAidXBkYXRlSW5kZXgiLCAiZ2V0RGF0YXNldCIsICJjaG9vc2VJZCIsICJ4aWQiLCAieEF4aXNJRCIsICJ2YWx1ZU9yRGVmYXVsdCIsICJ5aWQiLCAieUF4aXNJRCIsICJyaWQiLCAickF4aXNJRCIsICJpbmRleEF4aXMiLCAiaWlkIiwgImlBeGlzSUQiLCAidmlkIiwgInZBeGlzSUQiLCAiZ2V0U2NhbGVGb3JJZCIsICJyU2NhbGUiLCAiZGF0YXNldHMiLCAiZ2V0RGF0YXNldE1ldGEiLCAic2NhbGVJRCIsICJfZ2V0T3RoZXJTY2FsZSIsICJyZXNldCIsICJfZGVzdHJveSIsICJ1bmxpc3RlbkFycmF5RXZlbnRzIiwgIl9kYXRhQ2hlY2siLCAiaXNFeHRlbnNpYmxlIiwgImxpc3RlbkFycmF5RXZlbnRzIiwgImJ1aWxkT3JVcGRhdGVFbGVtZW50cyIsICJyZXNldE5ld0VsZW1lbnRzIiwgInN0YWNrQ2hhbmdlZCIsICJvbGRTdGFja2VkIiwgIl9yZXN5bmNFbGVtZW50cyIsICJzY29wZUtleXMiLCAiZGF0YXNldFNjb3BlS2V5cyIsICJzY29wZXMiLCAiZ2V0T3B0aW9uU2NvcGVzIiwgImNyZWF0ZVJlc29sdmVyIiwgImdldENvbnRleHQiLCAicGFyc2luZyIsICJwYXJzZSIsICJjb3VudCIsICJzb3J0ZWQiLCAiX3NvcnRlZCIsICJwcmV2IiwgInBhcnNlQXJyYXlEYXRhIiwgInBhcnNlT2JqZWN0RGF0YSIsICJwYXJzZVByaW1pdGl2ZURhdGEiLCAiaXNOb3RJbk9yZGVyQ29tcGFyZWRUb1ByZXYiLCAibGFiZWxzIiwgImdldExhYmVscyIsICJzaW5nbGVTY2FsZSIsICJ4QXhpc0tleSIsICJ5QXhpc0tleSIsICJyZXNvbHZlT2JqZWN0S2V5IiwgImdldFBhcnNlZCIsICJnZXREYXRhRWxlbWVudCIsICJ1cGRhdGVSYW5nZUZyb21QYXJzZWQiLCAicmFuZ2UiLCAicGFyc2VkVmFsdWUiLCAiTmFOIiwgImdldE1pbk1heCIsICJvdGhlclNjYWxlIiwgIm90aGVyTWluIiwgIm90aGVyTWF4IiwgIl9za2lwIiwgImdldEFsbFBhcnNlZFZhbHVlcyIsICJnZXRNYXhPdmVyZmxvdyIsICJnZXRMYWJlbEFuZFZhbHVlIiwgImxhYmVsIiwgImdldExhYmVsRm9yVmFsdWUiLCAiX2NsaXAiLCAiY2xpcCIsICJlbGVtZW50cyIsICJhcmVhIiwgImNoYXJ0QXJlYSIsICJkcmF3QWN0aXZlRWxlbWVudHNPblRvcCIsICJnZXRTdHlsZSIsICJyZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zIiwgInJlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMiLCAiY29udGV4dCIsICJfcmVzb2x2ZUVsZW1lbnRPcHRpb25zIiwgImVsZW1lbnRUeXBlIiwgImNhY2hlIiwgImNhY2hlS2V5IiwgInNoYXJpbmciLCAiZGVmaW5lZCIsICJkYXRhc2V0RWxlbWVudFNjb3BlS2V5cyIsICJwcmVmaXhlcyIsICJuYW1lcyIsICJyZXNvbHZlTmFtZWRPcHRpb25zIiwgImZyZWV6ZSIsICJfcmVzb2x2ZUFuaW1hdGlvbnMiLCAidHJhbnNpdGlvbiIsICJkYXRhc2V0QW5pbWF0aW9uU2NvcGVLZXlzIiwgIl9jYWNoZWFibGUiLCAiZ2V0U2hhcmVkT3B0aW9ucyIsICJpbmNsdWRlT3B0aW9ucyIsICJzaGFyZWRPcHRpb25zIiwgIl9hbmltYXRpb25zRGlzYWJsZWQiLCAiX2dldFNoYXJlZE9wdGlvbnMiLCAiZmlyc3RPcHRzIiwgInByZXZpb3VzbHlTaGFyZWRPcHRpb25zIiwgInVwZGF0ZVNoYXJlZE9wdGlvbnMiLCAidXBkYXRlRWxlbWVudCIsICJfc2V0U3R5bGUiLCAicmVtb3ZlSG92ZXJTdHlsZSIsICJzZXRIb3ZlclN0eWxlIiwgIl9yZW1vdmVEYXRhc2V0SG92ZXJTdHlsZSIsICJfc2V0RGF0YXNldEhvdmVyU3R5bGUiLCAiYXJnMSIsICJhcmcyIiwgIm51bU1ldGEiLCAibnVtRGF0YSIsICJfaW5zZXJ0RWxlbWVudHMiLCAiX3JlbW92ZUVsZW1lbnRzIiwgIm1vdmUiLCAiYXJyIiwgInVwZGF0ZUVsZW1lbnRzIiwgInJlbW92ZWQiLCAic3BsaWNlIiwgIl9zeW5jIiwgImFyZ3MiLCAiX2RhdGFDaGFuZ2VzIiwgIl9vbkRhdGFQdXNoIiwgImFyZ3VtZW50cyIsICJfb25EYXRhUG9wIiwgIl9vbkRhdGFTaGlmdCIsICJfb25EYXRhU3BsaWNlIiwgIm5ld0NvdW50IiwgIl9vbkRhdGFVbnNoaWZ0IiwgImdldEFsbFNjYWxlVmFsdWVzIiwgIl9jYWNoZSIsICIkYmFyIiwgInZpc2libGVNZXRhcyIsICJjb25jYXQiLCAiX2FycmF5VW5pcXVlIiwgInNvcnQiLCAiYSIsICJjb21wdXRlTWluU2FtcGxlU2l6ZSIsICJfbGVuZ3RoIiwgImN1cnIiLCAidXBkYXRlTWluQW5kUHJldiIsICJhYnMiLCAiZ2V0UGl4ZWxGb3JWYWx1ZSIsICJ0aWNrcyIsICJnZXRQaXhlbEZvclRpY2siLCAiY29tcHV0ZUZpdENhdGVnb3J5VHJhaXRzIiwgInJ1bGVyIiwgInN0YWNrQ291bnQiLCAidGhpY2tuZXNzIiwgImJhclRoaWNrbmVzcyIsICJyYXRpbyIsICJpc051bGxPclVuZGVmIiwgImNhdGVnb3J5UGVyY2VudGFnZSIsICJiYXJQZXJjZW50YWdlIiwgImNodW5rIiwgInBpeGVscyIsICJjb21wdXRlRmxleENhdGVnb3J5VHJhaXRzIiwgIm5leHQiLCAicGVyY2VudCIsICJwYXJzZUZsb2F0QmFyIiwgImVudHJ5IiwgInN0YXJ0VmFsdWUiLCAiZW5kVmFsdWUiLCAiYmFyU3RhcnQiLCAiYmFyRW5kIiwgIl9jdXN0b20iLCAicGFyc2VWYWx1ZSIsICJwYXJzZUFycmF5T3JQcmltaXRpdmUiLCAiaXNGbG9hdEJhciIsICJjdXN0b20iLCAiYmFyU2lnbiIsICJhY3R1YWxCYXNlIiwgImlzSG9yaXpvbnRhbCIsICJib3JkZXJQcm9wcyIsICJob3Jpem9udGFsIiwgImJhc2UiLCAic2V0Qm9yZGVyU2tpcHBlZCIsICJlZGdlIiwgImJvcmRlclNraXBwZWQiLCAiZW5hYmxlQm9yZGVyUmFkaXVzIiwgInBhcnNlRWRnZSIsICJzd2FwIiwgInN0YXJ0RW5kIiwgIm9yaWciLCAidjEiLCAidjIiLCAidiIsICJzZXRJbmZsYXRlQW1vdW50IiwgImluZmxhdGVBbW91bnQiLCAiQmFyQ29udHJvbGxlciIsICJpQXhpc0tleSIsICJ2QXhpc0tleSIsICJvYmoiLCAiYmFycyIsICJnZXRCYXNlUGl4ZWwiLCAiX2dldFJ1bGVyIiwgInZwaXhlbHMiLCAiaGVhZCIsICJfY2FsY3VsYXRlQmFyVmFsdWVQaXhlbHMiLCAiaXBpeGVscyIsICJfY2FsY3VsYXRlQmFySW5kZXhQaXhlbHMiLCAiY2VudGVyIiwgImhlaWdodCIsICJ3aWR0aCIsICJfZ2V0U3RhY2tzIiwgImxhc3QiLCAiZ3JvdXBlZCIsICJza2lwTnVsbCIsICJ2YWwiLCAiaXNOYU4iLCAiaW5kZXhPZiIsICJfZ2V0U3RhY2tDb3VudCIsICJfZ2V0U3RhY2tJbmRleCIsICJuYW1lIiwgIl9zdGFydFBpeGVsIiwgIl9lbmRQaXhlbCIsICJiYXNlVmFsdWUiLCAibWluQmFyTGVuZ3RoIiwgImZsb2F0aW5nIiwgImdldERhdGFWaXNpYmlsaXR5IiwgInN0YXJ0UGl4ZWwiLCAiZ2V0UGl4ZWxGb3JEZWNpbWFsIiwgImVuZFBpeGVsIiwgImdldFZhbHVlRm9yUGl4ZWwiLCAiaGFsZkdyaWQiLCAiZ2V0TGluZVdpZHRoRm9yVmFsdWUiLCAibWF4QmFyVGhpY2tuZXNzIiwgIkluZmluaXR5IiwgInN0YWNrSW5kZXgiLCAicmVjdHMiLCAibnVtYmVycyIsICJvdmVycmlkZXMiLCAiX2luZGV4XyIsICJvZmZzZXQiLCAiZ3JpZCIsICJfdmFsdWVfIiwgImJlZ2luQXRaZXJvIiwgIkJ1YmJsZUNvbnRyb2xsZXIiLCAicmFkaXVzIiwgInBvaW50cyIsICJwb2ludCIsICJpUGl4ZWwiLCAidlBpeGVsIiwgInNraXAiLCAiZ2V0UmF0aW9BbmRPZmZzZXQiLCAicm90YXRpb24iLCAiY2lyY3VtZmVyZW5jZSIsICJjdXRvdXQiLCAicmF0aW9YIiwgInJhdGlvWSIsICJvZmZzZXRYIiwgIm9mZnNldFkiLCAiVEFVIiwgInN0YXJ0QW5nbGUiLCAiZW5kQW5nbGUiLCAic3RhcnRYIiwgImNvcyIsICJzdGFydFkiLCAic2luIiwgImVuZFgiLCAiZW5kWSIsICJjYWxjTWF4IiwgImFuZ2xlIiwgIl9hbmdsZUJldHdlZW4iLCAiY2FsY01pbiIsICJtYXhYIiwgIm1heFkiLCAiSEFMRl9QSSIsICJtaW5YIiwgIlBJIiwgIm1pblkiLCAiRG91Z2hudXRDb250cm9sbGVyIiwgImlubmVyUmFkaXVzIiwgIm91dGVyUmFkaXVzIiwgImdldHRlciIsICJfZ2V0Um90YXRpb24iLCAidG9SYWRpYW5zIiwgIl9nZXRDaXJjdW1mZXJlbmNlIiwgIl9nZXRSb3RhdGlvbkV4dGVudHMiLCAiaXNEYXRhc2V0VmlzaWJsZSIsICJhcmNzIiwgInNwYWNpbmciLCAiZ2V0TWF4Qm9yZGVyV2lkdGgiLCAiZ2V0TWF4T2Zmc2V0IiwgIm1heFNpemUiLCAidG9QZXJjZW50YWdlIiwgImNoYXJ0V2VpZ2h0IiwgIl9nZXRSaW5nV2VpZ2h0IiwgIm1heFdpZHRoIiwgIm1heEhlaWdodCIsICJtYXhSYWRpdXMiLCAidG9EaW1lbnNpb24iLCAicmFkaXVzTGVuZ3RoIiwgIl9nZXRWaXNpYmxlRGF0YXNldFdlaWdodFRvdGFsIiwgInRvdGFsIiwgImNhbGN1bGF0ZVRvdGFsIiwgIl9nZXRSaW5nV2VpZ2h0T2Zmc2V0IiwgIl9jaXJjdW1mZXJlbmNlIiwgImFuaW1hdGVSb3RhdGUiLCAiY2FsY3VsYXRlQ2lyY3VtZmVyZW5jZSIsICJhbmltYXRpb25PcHRzIiwgImNlbnRlclgiLCAiY2VudGVyWSIsICJhbmltYXRlU2NhbGUiLCAiYXJjIiwgIm1ldGFEYXRhIiwgImZvcm1hdE51bWJlciIsICJsb2NhbGUiLCAiYm9yZGVyQWxpZ24iLCAiYm9yZGVyV2lkdGgiLCAiaG92ZXJCb3JkZXJXaWR0aCIsICJob3Zlck9mZnNldCIsICJyaW5nV2VpZ2h0T2Zmc2V0IiwgIndlaWdodCIsICJkZXNjcmlwdG9ycyIsICJfc2NyaXB0YWJsZSIsICJfaW5kZXhhYmxlIiwgInN0YXJ0c1dpdGgiLCAiYXNwZWN0UmF0aW8iLCAicGx1Z2lucyIsICJsZWdlbmQiLCAiZ2VuZXJhdGVMYWJlbHMiLCAicG9pbnRTdHlsZSIsICJtYXAiLCAic3R5bGUiLCAidGV4dCIsICJmaWxsU3R5bGUiLCAiYmFja2dyb3VuZENvbG9yIiwgInN0cm9rZVN0eWxlIiwgImJvcmRlckNvbG9yIiwgImZvbnRDb2xvciIsICJsaW5lV2lkdGgiLCAib25DbGljayIsICJlIiwgImxlZ2VuZEl0ZW0iLCAidG9nZ2xlRGF0YVZpc2liaWxpdHkiLCAiTGluZUNvbnRyb2xsZXIiLCAibGluZSIsICJfZGF0YXNldCIsICJhbmltYXRpb25zRGlzYWJsZWQiLCAiX2dldFN0YXJ0QW5kQ291bnRPZlZpc2libGVQb2ludHMiLCAiX3NjYWxlUmFuZ2VzQ2hhbmdlZCIsICJfZGF0YXNldEluZGV4IiwgIl9kZWNpbWF0ZWQiLCAic2hvd0xpbmUiLCAic2VnbWVudCIsICJhbmltYXRlZCIsICJzcGFuR2FwcyIsICJtYXhHYXBMZW5ndGgiLCAiaXNOdW1iZXIiLCAiZGlyZWN0VXBkYXRlIiwgInBvaW50c0NvdW50IiwgInByZXZQYXJzZWQiLCAibnVsbERhdGEiLCAiYm9yZGVyIiwgImZpcnN0UG9pbnQiLCAibGFzdFBvaW50IiwgInVwZGF0ZUNvbnRyb2xQb2ludHMiLCAiUG9sYXJBcmVhQ29udHJvbGxlciIsICJfcGFyc2VPYmplY3REYXRhUmFkaWFsU2NhbGUiLCAiYmluZCIsICJfdXBkYXRlUmFkaXVzIiwgIm1pblNpemUiLCAiY3V0b3V0UGVyY2VudGFnZSIsICJnZXRWaXNpYmxlRGF0YXNldENvdW50IiwgInhDZW50ZXIiLCAieUNlbnRlciIsICJkYXRhc2V0U3RhcnRBbmdsZSIsICJnZXRJbmRleEFuZ2xlIiwgImRlZmF1bHRBbmdsZSIsICJjb3VudFZpc2libGVFbGVtZW50cyIsICJfY29tcHV0ZUFuZ2xlIiwgImdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlIiwgImFuZ2xlTGluZXMiLCAiZGlzcGxheSIsICJjaXJjdWxhciIsICJwb2ludExhYmVscyIsICJQaWVDb250cm9sbGVyIiwgIlJhZGFyQ29udHJvbGxlciIsICJfZnVsbExvb3AiLCAicG9pbnRQb3NpdGlvbiIsICJnZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUiLCAiU2NhdHRlckNvbnRyb2xsZXIiLCAicmVnaXN0cnkiLCAiZ2V0RWxlbWVudCIsICJpbnRlcmFjdGlvbiIsICJhYnN0cmFjdCIsICJFcnJvciIsICJEYXRlQWRhcHRlckJhc2UiLCAib3ZlcnJpZGUiLCAibWVtYmVycyIsICJwcm90b3R5cGUiLCAiaW5pdCIsICJmb3JtYXRzIiwgImZvcm1hdCIsICJkaWZmIiwgInN0YXJ0T2YiLCAiZW5kT2YiLCAiX2RhdGUiLCAiYmluYXJ5U2VhcmNoIiwgIm1ldGFzZXQiLCAiaW50ZXJzZWN0IiwgImxvb2t1cE1ldGhvZCIsICJfcmV2ZXJzZVBpeGVscyIsICJfcmxvb2t1cEJ5S2V5IiwgIl9sb29rdXBCeUtleSIsICJlbCIsICJnZXRSYW5nZSIsICJsbyIsICJoaSIsICJldmFsdWF0ZUludGVyYWN0aW9uSXRlbXMiLCAicG9zaXRpb24iLCAiaGFuZGxlciIsICJnZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzIiwgImoiLCAiZ2V0RGlzdGFuY2VNZXRyaWNGb3JBeGlzIiwgInVzZVgiLCAidXNlWSIsICJwdDEiLCAicHQyIiwgImRlbHRhWCIsICJkZWx0YVkiLCAic3FydCIsICJwb3ciLCAiZ2V0SW50ZXJzZWN0SXRlbXMiLCAidXNlRmluYWxQb3NpdGlvbiIsICJpbmNsdWRlSW52aXNpYmxlIiwgImlzUG9pbnRJbkFyZWEiLCAiZXZhbHVhdGlvbkZ1bmMiLCAiX2lzUG9pbnRJbkFyZWEiLCAiaW5SYW5nZSIsICJnZXROZWFyZXN0UmFkaWFsSXRlbXMiLCAiZ2V0UHJvcHMiLCAiZ2V0QW5nbGVGcm9tUG9pbnQiLCAiZ2V0TmVhcmVzdENhcnRlc2lhbkl0ZW1zIiwgImRpc3RhbmNlTWV0cmljIiwgIm1pbkRpc3RhbmNlIiwgImdldENlbnRlclBvaW50IiwgInBvaW50SW5BcmVhIiwgImRpc3RhbmNlIiwgImdldE5lYXJlc3RJdGVtcyIsICJnZXRBeGlzSXRlbXMiLCAicmFuZ2VNZXRob2QiLCAiaW50ZXJzZWN0c0l0ZW0iLCAibW9kZXMiLCAiZ2V0UmVsYXRpdmVQb3NpdGlvbiIsICJuZWFyZXN0IiwgIlNUQVRJQ19QT1NJVElPTlMiLCAiZmlsdGVyQnlQb3NpdGlvbiIsICJhcnJheSIsICJwb3MiLCAiZmlsdGVyRHluYW1pY1Bvc2l0aW9uQnlBeGlzIiwgImJveCIsICJzb3J0QnlXZWlnaHQiLCAidjAiLCAid3JhcEJveGVzIiwgImJveGVzIiwgImxheW91dEJveGVzIiwgInN0YWNrV2VpZ2h0IiwgImJ1aWxkU3RhY2tzIiwgImxheW91dHMiLCAid3JhcCIsICJpbmNsdWRlcyIsICJfc3RhY2siLCAicGxhY2VkIiwgInNldExheW91dERpbXMiLCAicGFyYW1zIiwgInZCb3hNYXhXaWR0aCIsICJoQm94TWF4SGVpZ2h0IiwgImxheW91dCIsICJmdWxsU2l6ZSIsICJhdmFpbGFibGVXaWR0aCIsICJhdmFpbGFibGVIZWlnaHQiLCAiYnVpbGRMYXlvdXRCb3hlcyIsICJjZW50ZXJIb3Jpem9udGFsIiwgImNlbnRlclZlcnRpY2FsIiwgImxlZnRBbmRUb3AiLCAicmlnaHRBbmRCb3R0b20iLCAidmVydGljYWwiLCAiZ2V0Q29tYmluZWRNYXgiLCAibWF4UGFkZGluZyIsICJ1cGRhdGVNYXhQYWRkaW5nIiwgImJveFBhZGRpbmciLCAidXBkYXRlRGltcyIsICJnZXRQYWRkaW5nIiwgIm5ld1dpZHRoIiwgIm91dGVyV2lkdGgiLCAibmV3SGVpZ2h0IiwgIm91dGVySGVpZ2h0IiwgIndpZHRoQ2hhbmdlZCIsICJ3IiwgImhlaWdodENoYW5nZWQiLCAiaCIsICJzYW1lIiwgIm90aGVyIiwgImhhbmRsZU1heFBhZGRpbmciLCAidXBkYXRlUG9zIiwgImNoYW5nZSIsICJnZXRNYXJnaW5zIiwgIm1hcmdpbkZvclBvc2l0aW9ucyIsICJwb3NpdGlvbnMiLCAibWFyZ2luIiwgImZpdEJveGVzIiwgInJlZml0Qm94ZXMiLCAicmVmaXQiLCAiY2hhbmdlZCIsICJzZXRCb3hEaW1zIiwgInBsYWNlQm94ZXMiLCAidXNlclBhZGRpbmciLCAicGFkZGluZyIsICJhZGRCb3giLCAiX2xheWVycyIsICJ6IiwgInJlbW92ZUJveCIsICJsYXlvdXRJdGVtIiwgIm1pblBhZGRpbmciLCAidG9QYWRkaW5nIiwgInZlcnRpY2FsQm94ZXMiLCAiaG9yaXpvbnRhbEJveGVzIiwgImVhY2giLCAiYmVmb3JlTGF5b3V0IiwgInZpc2libGVWZXJ0aWNhbEJveENvdW50IiwgIkJhc2VQbGF0Zm9ybSIsICJhY3F1aXJlQ29udGV4dCIsICJjYW52YXMiLCAicmVsZWFzZUNvbnRleHQiLCAiYWRkRXZlbnRMaXN0ZW5lciIsICJsaXN0ZW5lciIsICJyZW1vdmVFdmVudExpc3RlbmVyIiwgImdldERldmljZVBpeGVsUmF0aW8iLCAiZ2V0TWF4aW11bVNpemUiLCAiaXNBdHRhY2hlZCIsICJ1cGRhdGVDb25maWciLCAiQmFzaWNQbGF0Zm9ybSIsICJFWFBBTkRPX0tFWSIsICJFVkVOVF9UWVBFUyIsICJ0b3VjaHN0YXJ0IiwgInRvdWNobW92ZSIsICJ0b3VjaGVuZCIsICJwb2ludGVyZW50ZXIiLCAicG9pbnRlcmRvd24iLCAicG9pbnRlcm1vdmUiLCAicG9pbnRlcnVwIiwgInBvaW50ZXJsZWF2ZSIsICJwb2ludGVyb3V0IiwgImlzTnVsbE9yRW1wdHkiLCAiaW5pdENhbnZhcyIsICJyZW5kZXJIZWlnaHQiLCAiZ2V0QXR0cmlidXRlIiwgInJlbmRlcldpZHRoIiwgImJveFNpemluZyIsICJkaXNwbGF5V2lkdGgiLCAicmVhZFVzZWRTaXplIiwgImRpc3BsYXlIZWlnaHQiLCAiZXZlbnRMaXN0ZW5lck9wdGlvbnMiLCAic3VwcG9ydHNFdmVudExpc3RlbmVyT3B0aW9ucyIsICJwYXNzaXZlIiwgImFkZExpc3RlbmVyIiwgIm5vZGUiLCAicmVtb3ZlTGlzdGVuZXIiLCAiZnJvbU5hdGl2ZUV2ZW50IiwgIm5hdGl2ZSIsICJub2RlTGlzdENvbnRhaW5zIiwgIm5vZGVMaXN0IiwgImNvbnRhaW5zIiwgImNyZWF0ZUF0dGFjaE9ic2VydmVyIiwgIm9ic2VydmVyIiwgIk11dGF0aW9uT2JzZXJ2ZXIiLCAiZW50cmllcyIsICJ0cmlnZ2VyIiwgImFkZGVkTm9kZXMiLCAicmVtb3ZlZE5vZGVzIiwgIm9ic2VydmUiLCAiZG9jdW1lbnQiLCAiY2hpbGRMaXN0IiwgInN1YnRyZWUiLCAiY3JlYXRlRGV0YWNoT2JzZXJ2ZXIiLCAiZHJwTGlzdGVuaW5nQ2hhcnRzIiwgIm9sZERldmljZVBpeGVsUmF0aW8iLCAib25XaW5kb3dSZXNpemUiLCAiZHByIiwgImRldmljZVBpeGVsUmF0aW8iLCAicmVzaXplIiwgImN1cnJlbnREZXZpY2VQaXhlbFJhdGlvIiwgImxpc3RlbkRldmljZVBpeGVsUmF0aW9DaGFuZ2VzIiwgInVubGlzdGVuRGV2aWNlUGl4ZWxSYXRpb0NoYW5nZXMiLCAiY3JlYXRlUmVzaXplT2JzZXJ2ZXIiLCAiY29udGFpbmVyIiwgIl9nZXRQYXJlbnROb2RlIiwgInRocm90dGxlZCIsICJjbGllbnRXaWR0aCIsICJSZXNpemVPYnNlcnZlciIsICJjb250ZW50UmVjdCIsICJyZWxlYXNlT2JzZXJ2ZXIiLCAiZGlzY29ubmVjdCIsICJjcmVhdGVQcm94eUFuZExpc3RlbiIsICJwcm94eSIsICJEb21QbGF0Zm9ybSIsICJyZW1vdmVBdHRyaWJ1dGUiLCAic2V0QXR0cmlidXRlIiwgInByb3hpZXMiLCAiJHByb3hpZXMiLCAiaGFuZGxlcnMiLCAiYXR0YWNoIiwgImRldGFjaCIsICJpc0Nvbm5lY3RlZCIsICJfZGV0ZWN0UGxhdGZvcm0iLCAiX2lzRG9tU3VwcG9ydGVkIiwgIk9mZnNjcmVlbkNhbnZhcyIsICJFbGVtZW50IiwgInRvb2x0aXBQb3NpdGlvbiIsICJoYXNWYWx1ZSIsICJmaW5hbCIsICJyZXQiLCAiZGVmYXVsdFJvdXRlcyIsICJhdXRvU2tpcCIsICJ0aWNrT3B0cyIsICJkZXRlcm1pbmVkTWF4VGlja3MiLCAiZGV0ZXJtaW5lTWF4VGlja3MiLCAidGlja3NMaW1pdCIsICJtYXhUaWNrc0xpbWl0IiwgIm1ham9ySW5kaWNlcyIsICJtYWpvciIsICJlbmFibGVkIiwgImdldE1ham9ySW5kaWNlcyIsICJudW1NYWpvckluZGljZXMiLCAiZmlyc3QiLCAibmV3VGlja3MiLCAic2tpcE1ham9ycyIsICJjYWxjdWxhdGVTcGFjaW5nIiwgImF2Z01ham9yU3BhY2luZyIsICJyb3VuZCIsICJ0aWNrTGVuZ3RoIiwgIl90aWNrU2l6ZSIsICJtYXhTY2FsZSIsICJtYXhDaGFydCIsICJfbWF4TGVuZ3RoIiwgImV2ZW5NYWpvclNwYWNpbmciLCAiZ2V0RXZlblNwYWNpbmciLCAiZmFjdG9ycyIsICJfZmFjdG9yaXplIiwgInJlc3VsdCIsICJjZWlsIiwgIm1ham9yU3RhcnQiLCAibWFqb3JFbmQiLCAibGVuIiwgInJldmVyc2VBbGlnbiIsICJhbGlnbiIsICJvZmZzZXRGcm9tRWRnZSIsICJnZXRUaWNrc0xpbWl0IiwgInRpY2tzTGVuZ3RoIiwgInNhbXBsZSIsICJudW1JdGVtcyIsICJpbmNyZW1lbnQiLCAiZ2V0UGl4ZWxGb3JHcmlkTGluZSIsICJvZmZzZXRHcmlkTGluZXMiLCAidmFsaWRJbmRleCIsICJlcHNpbG9uIiwgImxpbmVWYWx1ZSIsICJnYXJiYWdlQ29sbGVjdCIsICJjYWNoZXMiLCAiZ2MiLCAiZ2NMZW4iLCAiZ2V0VGlja01hcmtMZW5ndGgiLCAiZHJhd1RpY2tzIiwgImdldFRpdGxlSGVpZ2h0IiwgImZhbGxiYWNrIiwgImZvbnQiLCAidG9Gb250IiwgImxpbmVzIiwgImxpbmVIZWlnaHQiLCAiY3JlYXRlU2NhbGVDb250ZXh0IiwgImNyZWF0ZVRpY2tDb250ZXh0IiwgInRpdGxlQWxpZ24iLCAiX3RvTGVmdFJpZ2h0Q2VudGVyIiwgInRpdGxlQXJncyIsICJ0aXRsZVgiLCAidGl0bGVZIiwgIl9hbGlnblN0YXJ0RW5kIiwgInBvc2l0aW9uQXhpc0lEIiwgIlNjYWxlIiwgIl9tYXJnaW5zIiwgInBhZGRpbmdUb3AiLCAicGFkZGluZ0JvdHRvbSIsICJwYWRkaW5nTGVmdCIsICJwYWRkaW5nUmlnaHQiLCAibGFiZWxSb3RhdGlvbiIsICJfcmFuZ2UiLCAiX2dyaWRMaW5lSXRlbXMiLCAiX2xhYmVsSXRlbXMiLCAiX2xhYmVsU2l6ZXMiLCAiX2xvbmdlc3RUZXh0Q2FjaGUiLCAiX3VzZXJNYXgiLCAiX3VzZXJNaW4iLCAiX3N1Z2dlc3RlZE1heCIsICJfc3VnZ2VzdGVkTWluIiwgIl90aWNrc0xlbmd0aCIsICJfYm9yZGVyVmFsdWUiLCAiX2RhdGFMaW1pdHNDYWNoZWQiLCAic2V0Q29udGV4dCIsICJzdWdnZXN0ZWRNaW4iLCAic3VnZ2VzdGVkTWF4IiwgImZpbml0ZU9yRGVmYXVsdCIsICJtZXRhcyIsICJnZXRUaWNrcyIsICJ4TGFiZWxzIiwgInlMYWJlbHMiLCAiZ2V0TGFiZWxJdGVtcyIsICJfY29tcHV0ZUxhYmVsSXRlbXMiLCAiYmVmb3JlVXBkYXRlIiwgIm1hcmdpbnMiLCAiZ3JhY2UiLCAic2FtcGxlU2l6ZSIsICJiZWZvcmVTZXREaW1lbnNpb25zIiwgInNldERpbWVuc2lvbnMiLCAiYWZ0ZXJTZXREaW1lbnNpb25zIiwgImJlZm9yZURhdGFMaW1pdHMiLCAiZGV0ZXJtaW5lRGF0YUxpbWl0cyIsICJhZnRlckRhdGFMaW1pdHMiLCAiX2FkZEdyYWNlIiwgImJlZm9yZUJ1aWxkVGlja3MiLCAiYnVpbGRUaWNrcyIsICJhZnRlckJ1aWxkVGlja3MiLCAic2FtcGxpbmdFbmFibGVkIiwgIl9jb252ZXJ0VGlja3NUb0xhYmVscyIsICJiZWZvcmVDYWxjdWxhdGVMYWJlbFJvdGF0aW9uIiwgImNhbGN1bGF0ZUxhYmVsUm90YXRpb24iLCAiYWZ0ZXJDYWxjdWxhdGVMYWJlbFJvdGF0aW9uIiwgInNvdXJjZSIsICJhZnRlckF1dG9Ta2lwIiwgImJlZm9yZUZpdCIsICJmaXQiLCAiYWZ0ZXJGaXQiLCAiYWZ0ZXJVcGRhdGUiLCAicmV2ZXJzZVBpeGVscyIsICJfYWxpZ25Ub1BpeGVscyIsICJhbGlnblRvUGl4ZWxzIiwgIl9jYWxsSG9va3MiLCAibm90aWZ5UGx1Z2lucyIsICJiZWZvcmVUaWNrVG9MYWJlbENvbnZlcnNpb24iLCAiZ2VuZXJhdGVUaWNrTGFiZWxzIiwgImNhbGxiYWNrIiwgImFmdGVyVGlja1RvTGFiZWxDb252ZXJzaW9uIiwgIm51bVRpY2tzIiwgIm1pblJvdGF0aW9uIiwgIm1heFJvdGF0aW9uIiwgInRpY2tXaWR0aCIsICJtYXhMYWJlbERpYWdvbmFsIiwgIl9pc1Zpc2libGUiLCAibGFiZWxTaXplcyIsICJfZ2V0TGFiZWxTaXplcyIsICJtYXhMYWJlbFdpZHRoIiwgIndpZGVzdCIsICJtYXhMYWJlbEhlaWdodCIsICJoaWdoZXN0IiwgIl9saW1pdFZhbHVlIiwgInRpdGxlIiwgInRvRGVncmVlcyIsICJhc2luIiwgInRpdGxlT3B0cyIsICJncmlkT3B0cyIsICJ0aXRsZUhlaWdodCIsICJ0aWNrUGFkZGluZyIsICJhbmdsZVJhZGlhbnMiLCAibGFiZWxIZWlnaHQiLCAibWlycm9yIiwgImxhYmVsV2lkdGgiLCAiX2NhbGN1bGF0ZVBhZGRpbmciLCAiX2hhbmRsZU1hcmdpbnMiLCAiaXNSb3RhdGVkIiwgImxhYmVsc0JlbG93VGlja3MiLCAib2Zmc2V0TGVmdCIsICJvZmZzZXRSaWdodCIsICJpc0Z1bGxTaXplIiwgIl9jb21wdXRlTGFiZWxTaXplcyIsICJ3aWR0aHMiLCAiaGVpZ2h0cyIsICJ3aWRlc3RMYWJlbFNpemUiLCAiaGlnaGVzdExhYmVsU2l6ZSIsICJqbGVuIiwgInRpY2tGb250IiwgImZvbnRTdHJpbmciLCAibmVzdGVkTGFiZWwiLCAiX3Jlc29sdmVUaWNrRm9udE9wdGlvbnMiLCAic3RyaW5nIiwgIl9tZWFzdXJlVGV4dCIsICJ2YWx1ZUF0IiwgImlkeCIsICJwaXhlbCIsICJkZWNpbWFsIiwgIl9pbnQxNlJhbmdlIiwgIl9hbGlnblBpeGVsIiwgImdldERlY2ltYWxGb3JQaXhlbCIsICJnZXRCYXNlVmFsdWUiLCAib3B0aW9uVGlja3MiLCAicm90IiwgImF1dG9Ta2lwUGFkZGluZyIsICJfY29tcHV0ZUdyaWRMaW5lSXRlbXMiLCAidGwiLCAiYm9yZGVyT3B0cyIsICJheGlzV2lkdGgiLCAiYXhpc0hhbGZXaWR0aCIsICJhbGlnbkJvcmRlclZhbHVlIiwgImJvcmRlclZhbHVlIiwgImFsaWduZWRMaW5lVmFsdWUiLCAidHgxIiwgInR5MSIsICJ0eDIiLCAidHkyIiwgIngxIiwgInkxIiwgIngyIiwgInkyIiwgImxpbWl0IiwgInN0ZXAiLCAib3B0c0F0SW5kZXgiLCAib3B0c0F0SW5kZXhCb3JkZXIiLCAibGluZUNvbG9yIiwgImJvcmRlckRhc2giLCAiZGFzaCIsICJib3JkZXJEYXNoT2Zmc2V0IiwgImRhc2hPZmZzZXQiLCAidGlja0NvbG9yIiwgInRpY2tCb3JkZXJEYXNoIiwgInRpY2tCb3JkZXJEYXNoT2Zmc2V0IiwgImNyb3NzQWxpZ24iLCAidGlja0FuZFBhZGRpbmciLCAiaFRpY2tBbmRQYWRkaW5nIiwgInRleHRBbGlnbiIsICJsaW5lQ291bnQiLCAidGV4dE9mZnNldCIsICJ0ZXh0QmFzZWxpbmUiLCAiX2dldFhBeGlzTGFiZWxBbGlnbm1lbnQiLCAiX2dldFlBeGlzTGFiZWxBbGlnbm1lbnQiLCAibGFiZWxPZmZzZXQiLCAiaGFsZkNvdW50IiwgInN0cm9rZUNvbG9yIiwgInRleHRTdHJva2VDb2xvciIsICJzdHJva2VXaWR0aCIsICJ0ZXh0U3Ryb2tlV2lkdGgiLCAidGlja1RleHRBbGlnbiIsICJzaG93TGFiZWxCYWNrZHJvcCIsICJiYWNrZHJvcCIsICJsYWJlbFBhZGRpbmciLCAiYmFja2Ryb3BQYWRkaW5nIiwgImJhY2tkcm9wQ29sb3IiLCAidHJhbnNsYXRpb24iLCAiX2NvbXB1dGVMYWJlbEFyZWEiLCAiZHJhd0JhY2tncm91bmQiLCAic2F2ZSIsICJmaWxsUmVjdCIsICJyZXN0b3JlIiwgImZpbmRJbmRleCIsICJkcmF3R3JpZCIsICJkcmF3TGluZSIsICJwMSIsICJwMiIsICJzZXRMaW5lRGFzaCIsICJsaW5lRGFzaE9mZnNldCIsICJiZWdpblBhdGgiLCAibW92ZVRvIiwgImxpbmVUbyIsICJzdHJva2UiLCAiZHJhd09uQ2hhcnRBcmVhIiwgImRyYXdCb3JkZXIiLCAibGFzdExpbmVXaWR0aCIsICJkcmF3TGFiZWxzIiwgImNsaXBBcmVhIiwgInJlbmRlclRleHRPcHRpb25zIiwgInJlbmRlclRleHQiLCAidW5jbGlwQXJlYSIsICJkcmF3VGl0bGUiLCAidHoiLCAiZ3oiLCAiYnoiLCAiYXhpc0lEIiwgIl9tYXhEaWdpdHMiLCAiZm9udFNpemUiLCAiVHlwZWRSZWdpc3RyeSIsICJzY29wZSIsICJjcmVhdGUiLCAiaXNGb3JUeXBlIiwgImlzUHJvdG90eXBlT2YiLCAicmVnaXN0ZXIiLCAicHJvdG8iLCAiZ2V0UHJvdG90eXBlT2YiLCAicGFyZW50U2NvcGUiLCAiaXNJQ2hhcnRDb21wb25lbnQiLCAicmVnaXN0ZXJEZWZhdWx0cyIsICJ1bnJlZ2lzdGVyIiwgIml0ZW1EZWZhdWx0cyIsICJtZXJnZSIsICJyb3V0ZURlZmF1bHRzIiwgImRlc2NyaWJlIiwgInJvdXRlcyIsICJwcm9wZXJ0eSIsICJwcm9wZXJ0eVBhcnRzIiwgInNwbGl0IiwgInNvdXJjZU5hbWUiLCAic291cmNlU2NvcGUiLCAiam9pbiIsICJwYXJ0cyIsICJ0YXJnZXROYW1lIiwgInRhcmdldFNjb3BlIiwgInJvdXRlIiwgIlJlZ2lzdHJ5IiwgImNvbnRyb2xsZXJzIiwgIl90eXBlZFJlZ2lzdHJpZXMiLCAiX2VhY2giLCAiYWRkQ29udHJvbGxlcnMiLCAiYWRkUGx1Z2lucyIsICJhZGRTY2FsZXMiLCAiZ2V0Q29udHJvbGxlciIsICJfZ2V0IiwgImdldFBsdWdpbiIsICJnZXRTY2FsZSIsICJyZW1vdmVDb250cm9sbGVycyIsICJyZW1vdmVFbGVtZW50cyIsICJyZW1vdmVQbHVnaW5zIiwgInJlbW92ZVNjYWxlcyIsICJ0eXBlZFJlZ2lzdHJ5IiwgImFyZyIsICJyZWciLCAiX2dldFJlZ2lzdHJ5Rm9yVHlwZSIsICJfZXhlYyIsICJpdGVtUmVnIiwgImNvbXBvbmVudCIsICJjYW1lbE1ldGhvZCIsICJfY2FwaXRhbGl6ZSIsICJQbHVnaW5TZXJ2aWNlIiwgIl9pbml0IiwgIm5vdGlmeSIsICJob29rIiwgIl9jcmVhdGVEZXNjcmlwdG9ycyIsICJfZGVzY3JpcHRvcnMiLCAiZGVzY3JpcHRvciIsICJwbHVnaW4iLCAiY2FsbENhbGxiYWNrIiwgImNhbmNlbGFibGUiLCAiaW52YWxpZGF0ZSIsICJfb2xkQ2FjaGUiLCAiX25vdGlmeVN0YXRlQ2hhbmdlcyIsICJhbGxQbHVnaW5zIiwgImNyZWF0ZURlc2NyaXB0b3JzIiwgInByZXZpb3VzRGVzY3JpcHRvcnMiLCAic29tZSIsICJsb2NhbElkcyIsICJsb2NhbCIsICJnZXRPcHRzIiwgInBsdWdpbk9wdHMiLCAicGx1Z2luU2NvcGVLZXlzIiwgInNjcmlwdGFibGUiLCAiaW5kZXhhYmxlIiwgImFsbEtleXMiLCAiZ2V0SW5kZXhBeGlzIiwgImRhdGFzZXREZWZhdWx0cyIsICJkYXRhc2V0T3B0aW9ucyIsICJnZXRBeGlzRnJvbURlZmF1bHRTY2FsZUlEIiwgImdldERlZmF1bHRTY2FsZUlERnJvbUF4aXMiLCAiaWRNYXRjaGVzQXhpcyIsICJheGlzRnJvbVBvc2l0aW9uIiwgImRldGVybWluZUF4aXMiLCAic2NhbGVPcHRpb25zIiwgInRvTG93ZXJDYXNlIiwgImdldEF4aXNGcm9tRGF0YXNldCIsICJyZXRyaWV2ZUF4aXNGcm9tRGF0YXNldHMiLCAiYm91bmREcyIsICJkIiwgIm1lcmdlU2NhbGVDb25maWciLCAiY2hhcnREZWZhdWx0cyIsICJjb25maWdTY2FsZXMiLCAiY2hhcnRJbmRleEF4aXMiLCAic2NhbGVDb25mIiwgImVycm9yIiwgIl9wcm94eSIsICJkZWZhdWx0SWQiLCAiZGVmYXVsdFNjYWxlT3B0aW9ucyIsICJtZXJnZUlmIiwgImRlZmF1bHRJRCIsICJpbml0T3B0aW9ucyIsICJpbml0RGF0YSIsICJpbml0Q29uZmlnIiwgImtleUNhY2hlIiwgImtleXNDYWNoZWQiLCAiU2V0IiwgImNhY2hlZEtleXMiLCAiZ2VuZXJhdGUiLCAiYWRkSWZGb3VuZCIsICJDb25maWciLCAiX2NvbmZpZyIsICJfc2NvcGVDYWNoZSIsICJfcmVzb2x2ZXJDYWNoZSIsICJwbGF0Zm9ybSIsICJjbGVhckNhY2hlIiwgImNsZWFyIiwgImRhdGFzZXRUeXBlIiwgImFkZGl0aW9uYWxPcHRpb25TY29wZXMiLCAiX2NhY2hlZFNjb3BlcyIsICJtYWluU2NvcGUiLCAicmVzZXRDYWNoZSIsICJrZXlMaXN0cyIsICJjaGFydE9wdGlvblNjb3BlcyIsICJyZXNvbHZlciIsICJzdWJQcmVmaXhlcyIsICJnZXRSZXNvbHZlciIsICJuZWVkQ29udGV4dCIsICJpc0Z1bmN0aW9uIiwgInN1YlJlc29sdmVyIiwgIl9hdHRhY2hDb250ZXh0IiwgImRlc2NyaXB0b3JEZWZhdWx0cyIsICJyZXNvbHZlckNhY2hlIiwgIl9jcmVhdGVSZXNvbHZlciIsICJwIiwgImhhc0Z1bmN0aW9uIiwgImlzU2NyaXB0YWJsZSIsICJpc0luZGV4YWJsZSIsICJLTk9XTl9QT1NJVElPTlMiLCAicG9zaXRpb25Jc0hvcml6b250YWwiLCAiY29tcGFyZTJMZXZlbCIsICJsMSIsICJsMiIsICJvbkFuaW1hdGlvbnNDb21wbGV0ZSIsICJvbkNvbXBsZXRlIiwgIm9uQW5pbWF0aW9uUHJvZ3Jlc3MiLCAib25Qcm9ncmVzcyIsICJnZXRDYW52YXMiLCAiZ2V0RWxlbWVudEJ5SWQiLCAiaW5zdGFuY2VzIiwgImdldENoYXJ0IiwgImMiLCAibW92ZU51bWVyaWNLZXlzIiwgImludEtleSIsICJkZXRlcm1pbmVMYXN0RXZlbnQiLCAibGFzdEV2ZW50IiwgImluQ2hhcnRBcmVhIiwgImlzQ2xpY2siLCAiZ2V0U2l6ZUZvckFyZWEiLCAiZmllbGQiLCAiZ2V0RGF0YXNldEFyZWEiLCAiQ2hhcnQiLCAiaW52YWxpZGF0ZVBsdWdpbnMiLCAidXNlckNvbmZpZyIsICJpbml0aWFsQ2FudmFzIiwgImV4aXN0aW5nQ2hhcnQiLCAidWlkIiwgIl9vcHRpb25zIiwgIl9hc3BlY3RSYXRpbyIsICJfbWV0YXNldHMiLCAiX2xhc3RFdmVudCIsICJfbGlzdGVuZXJzIiwgIl9yZXNwb25zaXZlTGlzdGVuZXJzIiwgIl9zb3J0ZWRNZXRhc2V0cyIsICJfcGx1Z2lucyIsICJfaGlkZGVuSW5kaWNlcyIsICJhdHRhY2hlZCIsICJfZG9SZXNpemUiLCAiZGVib3VuY2UiLCAicmVzaXplRGVsYXkiLCAiX2luaXRpYWxpemUiLCAibWFpbnRhaW5Bc3BlY3RSYXRpbyIsICJyZXNwb25zaXZlIiwgInJldGluYVNjYWxlIiwgImJpbmRFdmVudHMiLCAiY2xlYXJDYW52YXMiLCAiX3Jlc2l6ZSIsICJfcmVzaXplQmVmb3JlRHJhdyIsICJuZXdTaXplIiwgIm5ld1JhdGlvIiwgIm9uUmVzaXplIiwgInJlbmRlciIsICJlbnN1cmVTY2FsZXNIYXZlSURzIiwgInNjYWxlc09wdGlvbnMiLCAiYXhpc09wdGlvbnMiLCAiYnVpbGRPclVwZGF0ZVNjYWxlcyIsICJzY2FsZU9wdHMiLCAidXBkYXRlZCIsICJpc1JhZGlhbCIsICJkcG9zaXRpb24iLCAiZHR5cGUiLCAic2NhbGVUeXBlIiwgInNjYWxlQ2xhc3MiLCAiaGFzVXBkYXRlZCIsICJfdXBkYXRlTWV0YXNldHMiLCAiX2Rlc3Ryb3lEYXRhc2V0TWV0YSIsICJzbGljZSIsICJfcmVtb3ZlVW5yZWZlcmVuY2VkTWV0YXNldHMiLCAiYnVpbGRPclVwZGF0ZUNvbnRyb2xsZXJzIiwgIm5ld0NvbnRyb2xsZXJzIiwgIm9yZGVyIiwgInZpc2libGUiLCAiQ29udHJvbGxlckNsYXNzIiwgIl9yZXNldEVsZW1lbnRzIiwgImFuaW1zRGlzYWJsZWQiLCAiX3VwZGF0ZVNjYWxlcyIsICJfY2hlY2tFdmVudEJpbmRpbmdzIiwgIl91cGRhdGVIaWRkZW5JbmRpY2VzIiwgIl9taW5QYWRkaW5nIiwgImF1dG9QYWRkaW5nIiwgIl91cGRhdGVMYXlvdXQiLCAiX3VwZGF0ZURhdGFzZXRzIiwgIl9ldmVudEhhbmRsZXIiLCAiX3VwZGF0ZUhvdmVyU3R5bGVzIiwgImV4aXN0aW5nRXZlbnRzIiwgIm5ld0V2ZW50cyIsICJldmVudHMiLCAic2V0c0VxdWFsIiwgInVuYmluZEV2ZW50cyIsICJjaGFuZ2VzIiwgIl9nZXRVbmlmb3JtRGF0YUNoYW5nZXMiLCAiZGF0YXNldENvdW50IiwgIm1ha2VTZXQiLCAiY2hhbmdlU2V0IiwgIm5vQXJlYSIsICJfaWR4IiwgIl91cGRhdGVEYXRhc2V0IiwgImxheWVycyIsICJfZHJhd0RhdGFzZXRzIiwgIl9kcmF3RGF0YXNldCIsICJ1c2VDbGlwIiwgImdldEVsZW1lbnRzQXRFdmVudEZvck1vZGUiLCAiSW50ZXJhY3Rpb24iLCAic2V0RGF0YXNldFZpc2liaWxpdHkiLCAiX3VwZGF0ZVZpc2liaWxpdHkiLCAiaGlkZSIsICJzaG93IiwgIl9zdG9wIiwgImRlc3Ryb3kiLCAidG9CYXNlNjRJbWFnZSIsICJ0b0RhdGFVUkwiLCAiYmluZFVzZXJFdmVudHMiLCAiYmluZFJlc3BvbnNpdmVFdmVudHMiLCAiX2FkZCIsICJfcmVtb3ZlIiwgImRldGFjaGVkIiwgInVwZGF0ZUhvdmVyU3R5bGUiLCAicHJlZml4IiwgImdldEFjdGl2ZUVsZW1lbnRzIiwgInNldEFjdGl2ZUVsZW1lbnRzIiwgImFjdGl2ZUVsZW1lbnRzIiwgImxhc3RBY3RpdmUiLCAiX2VsZW1lbnRzRXF1YWwiLCAicGx1Z2luSWQiLCAicmVwbGF5IiwgImhvdmVyT3B0aW9ucyIsICJob3ZlciIsICJkZWFjdGl2YXRlZCIsICJhY3RpdmF0ZWQiLCAiZXZlbnRGaWx0ZXIiLCAiX2hhbmRsZUV2ZW50IiwgIl9nZXRBY3RpdmVFbGVtZW50cyIsICJfaXNDbGlja0V2ZW50IiwgIm9uSG92ZXIiLCAidmVyc2lvbiIsICJjbGlwQXJjIiwgInBpeGVsTWFyZ2luIiwgImFuZ2xlTWFyZ2luIiwgImNsb3NlUGF0aCIsICJ0b1JhZGl1c0Nvcm5lcnMiLCAiX3JlYWRWYWx1ZVRvUHJvcHMiLCAicGFyc2VCb3JkZXJSYWRpdXMiLCAiYW5nbGVEZWx0YSIsICJvIiwgImJvcmRlclJhZGl1cyIsICJoYWxmVGhpY2tuZXNzIiwgImlubmVyTGltaXQiLCAiY29tcHV0ZU91dGVyTGltaXQiLCAib3V0ZXJBcmNMaW1pdCIsICJvdXRlclN0YXJ0IiwgIm91dGVyRW5kIiwgImlubmVyU3RhcnQiLCAiaW5uZXJFbmQiLCAiclRoZXRhVG9YWSIsICJ0aGV0YSIsICJwYXRoQXJjIiwgImlubmVyUiIsICJzcGFjaW5nT2Zmc2V0IiwgImFscGhhIiwgIm5vU3BhY2luZ0lubmVyUmFkaXVzIiwgIm5vU3BhY2luZ091dGVyUmFkaXVzIiwgImF2Tm9nU3BhY2luZ1JhZGl1cyIsICJhZGp1c3RlZEFuZ2xlIiwgImJldGEiLCAiYW5nbGVPZmZzZXQiLCAib3V0ZXJTdGFydEFkanVzdGVkUmFkaXVzIiwgIm91dGVyRW5kQWRqdXN0ZWRSYWRpdXMiLCAib3V0ZXJTdGFydEFkanVzdGVkQW5nbGUiLCAib3V0ZXJFbmRBZGp1c3RlZEFuZ2xlIiwgImlubmVyU3RhcnRBZGp1c3RlZFJhZGl1cyIsICJpbm5lckVuZEFkanVzdGVkUmFkaXVzIiwgImlubmVyU3RhcnRBZGp1c3RlZEFuZ2xlIiwgImlubmVyRW5kQWRqdXN0ZWRBbmdsZSIsICJvdXRlck1pZEFkanVzdGVkQW5nbGUiLCAicENlbnRlciIsICJwNCIsICJpbm5lck1pZEFkanVzdGVkQW5nbGUiLCAicDgiLCAib3V0ZXJTdGFydFgiLCAib3V0ZXJTdGFydFkiLCAib3V0ZXJFbmRYIiwgIm91dGVyRW5kWSIsICJkcmF3QXJjIiwgImZ1bGxDaXJjbGVzIiwgImJvcmRlckpvaW5TdHlsZSIsICJpbm5lciIsICJsaW5lSm9pbiIsICJBcmNFbGVtZW50IiwgImNoYXJ0WCIsICJjaGFydFkiLCAickFkanVzdCIsICJiZXR3ZWVuQW5nbGVzIiwgIndpdGhpblJhZGl1cyIsICJfaXNCZXR3ZWVuIiwgImhhbGZBbmdsZSIsICJoYWxmUmFkaXVzIiwgInRyYW5zbGF0ZSIsICJmaXgiLCAicmFkaXVzT2Zmc2V0IiwgInNldFN0eWxlIiwgImxpbmVDYXAiLCAiYm9yZGVyQ2FwU3R5bGUiLCAicHJldmlvdXMiLCAiZ2V0TGluZU1ldGhvZCIsICJzdGVwcGVkIiwgIl9zdGVwcGVkTGluZVRvIiwgInRlbnNpb24iLCAiY3ViaWNJbnRlcnBvbGF0aW9uTW9kZSIsICJfYmV6aWVyQ3VydmVUbyIsICJwYXRoVmFycyIsICJwYXJhbXNTdGFydCIsICJwYXJhbXNFbmQiLCAic2VnbWVudFN0YXJ0IiwgInNlZ21lbnRFbmQiLCAib3V0c2lkZSIsICJwYXRoU2VnbWVudCIsICJsaW5lTWV0aG9kIiwgImZhc3RQYXRoU2VnbWVudCIsICJhdmdYIiwgImNvdW50WCIsICJwcmV2WCIsICJsYXN0WSIsICJwb2ludEluZGV4IiwgImRyYXdYIiwgInRydW5jWCIsICJfZ2V0U2VnbWVudE1ldGhvZCIsICJ1c2VGYXN0UGF0aCIsICJfZ2V0SW50ZXJwb2xhdGlvbk1ldGhvZCIsICJfc3RlcHBlZEludGVycG9sYXRpb24iLCAiX2JlemllckludGVycG9sYXRpb24iLCAiX3BvaW50SW5MaW5lIiwgInN0cm9rZVBhdGhXaXRoQ2FjaGUiLCAicGF0aCIsICJfcGF0aCIsICJQYXRoMkQiLCAic3Ryb2tlUGF0aERpcmVjdCIsICJzZWdtZW50cyIsICJzZWdtZW50TWV0aG9kIiwgInVzZVBhdGgyRCIsICJMaW5lRWxlbWVudCIsICJfcG9pbnRzIiwgIl9zZWdtZW50cyIsICJfcG9pbnRzVXBkYXRlZCIsICJfdXBkYXRlQmV6aWVyQ29udHJvbFBvaW50cyIsICJfY29tcHV0ZVNlZ21lbnRzIiwgImludGVycG9sYXRlIiwgIl9ib3VuZFNlZ21lbnRzIiwgIl9pbnRlcnBvbGF0ZSIsICJpbnRlcnBvbGF0ZWQiLCAiY2FwQmV6aWVyUG9pbnRzIiwgImhpdFJhZGl1cyIsICJQb2ludEVsZW1lbnQiLCAibW91c2VYIiwgIm1vdXNlWSIsICJpblhSYW5nZSIsICJpbllSYW5nZSIsICJob3ZlclJhZGl1cyIsICJkcmF3UG9pbnQiLCAiZ2V0QmFyQm91bmRzIiwgImJhciIsICJoYWxmIiwgInNraXBPckxpbWl0IiwgInBhcnNlQm9yZGVyV2lkdGgiLCAibWF4VyIsICJtYXhIIiwgInRvVFJCTCIsICJ0b1RSQkxDb3JuZXJzIiwgIm1heFIiLCAiZW5hYmxlQm9yZGVyIiwgInRvcExlZnQiLCAidG9wUmlnaHQiLCAiYm90dG9tTGVmdCIsICJib3R0b21SaWdodCIsICJib3VuZGluZ1JlY3RzIiwgImJvdW5kcyIsICJvdXRlciIsICJza2lwWCIsICJza2lwWSIsICJza2lwQm90aCIsICJoYXNSYWRpdXMiLCAiYWRkTm9ybWFsUmVjdFBhdGgiLCAicmVjdCIsICJpbmZsYXRlUmVjdCIsICJhbW91bnQiLCAicmVmUmVjdCIsICJCYXJFbGVtZW50IiwgImFkZFJlY3RQYXRoIiwgImFkZFJvdW5kZWRSZWN0UGF0aCIsICJCT1JERVJfQ09MT1JTIiwgIkJBQ0tHUk9VTkRfQ09MT1JTIiwgInJlcGxhY2UiLCAiZ2V0Qm9yZGVyQ29sb3IiLCAiZ2V0QmFja2dyb3VuZENvbG9yIiwgImNvbG9yaXplRGVmYXVsdERhdGFzZXQiLCAiY29sb3JpemVEb3VnaG51dERhdGFzZXQiLCAiY29sb3JpemVQb2xhckFyZWFEYXRhc2V0IiwgImdldENvbG9yaXplciIsICJjb250YWluc0NvbG9yc0RlZmluaXRpb25zIiwgImsiLCAiY29udGFpbnNDb2xvcnNEZWZpbml0aW9uIiwgImZvcmNlT3ZlcnJpZGUiLCAiX2FyZ3MiLCAiY2hhcnRPcHRpb25zIiwgImNvbG9yaXplciIsICJsdHRiRGVjaW1hdGlvbiIsICJzYW1wbGVzIiwgImRlY2ltYXRlZCIsICJidWNrZXRXaWR0aCIsICJzYW1wbGVkSW5kZXgiLCAiZW5kSW5kZXgiLCAibWF4QXJlYVBvaW50IiwgIm1heEFyZWEiLCAibmV4dEEiLCAiYXZnWSIsICJhdmdSYW5nZVN0YXJ0IiwgImF2Z1JhbmdlRW5kIiwgImF2Z1JhbmdlTGVuZ3RoIiwgInJhbmdlT2ZmcyIsICJyYW5nZVRvIiwgInBvaW50QXgiLCAicG9pbnRBeSIsICJtaW5NYXhEZWNpbWF0aW9uIiwgIm1pbkluZGV4IiwgIm1heEluZGV4IiwgInN0YXJ0SW5kZXgiLCAieE1pbiIsICJ4TWF4IiwgImR4IiwgImxhc3RJbmRleCIsICJpbnRlcm1lZGlhdGVJbmRleDEiLCAiaW50ZXJtZWRpYXRlSW5kZXgyIiwgImNsZWFuRGVjaW1hdGVkRGF0YXNldCIsICJkZWZpbmVQcm9wZXJ0eSIsICJjb25maWd1cmFibGUiLCAiZW51bWVyYWJsZSIsICJ3cml0YWJsZSIsICJjbGVhbkRlY2ltYXRlZERhdGEiLCAiZ2V0U3RhcnRBbmRDb3VudE9mVmlzaWJsZVBvaW50c1NpbXBsaWZpZWQiLCAicG9pbnRDb3VudCIsICJhbGdvcml0aG0iLCAiYmVmb3JlRWxlbWVudHNVcGRhdGUiLCAieEF4aXMiLCAidGhyZXNob2xkIiwgInRwb2ludHMiLCAiX2ZpbmRTZWdtZW50RW5kIiwgIl9nZXRCb3VuZHMiLCAidGFyZ2V0U2VnbWVudHMiLCAidGd0IiwgInN1YkJvdW5kcyIsICJmaWxsU291cmNlcyIsICJfYm91bmRTZWdtZW50IiwgImZpbGxTb3VyY2UiLCAiX2dldEVkZ2UiLCAiX25vcm1hbGl6ZUFuZ2xlIiwgIl9wb2ludHNGcm9tU2VnbWVudHMiLCAiYm91bmRhcnkiLCAibGluZVBvaW50cyIsICJfY3JlYXRlQm91bmRhcnlMaW5lIiwgIl9zaG91bGRBcHBseUZpbGwiLCAiX3Jlc29sdmVUYXJnZXQiLCAic291cmNlcyIsICJwcm9wYWdhdGUiLCAidmlzaXRlZCIsICJfZGVjb2RlRmlsbCIsICJwYXJzZUZpbGxPcHRpb24iLCAicGFyc2VGbG9hdCIsICJkZWNvZGVUYXJnZXRJbmRleCIsICJmaXJzdENoIiwgIl9nZXRUYXJnZXRQaXhlbCIsICJfZ2V0VGFyZ2V0VmFsdWUiLCAiZmlsbE9wdGlvbiIsICJfYnVpbGRTdGFja0xpbmUiLCAic291cmNlUG9pbnRzIiwgImxpbmVzQmVsb3ciLCAiZ2V0TGluZXNCZWxvdyIsICJhZGRQb2ludHNCZWxvdyIsICJiZWxvdyIsICJ1bnNoaWZ0IiwgInNvdXJjZVBvaW50IiwgInBvc3Rwb25lZCIsICJmaW5kUG9pbnQiLCAicG9pbnRWYWx1ZSIsICJmaXJzdFZhbHVlIiwgImxhc3RWYWx1ZSIsICJzaW1wbGVBcmMiLCAiX2dldFRhcmdldCIsICJnZXRMaW5lQnlJbmRleCIsICJjb21wdXRlQm91bmRhcnkiLCAiY29tcHV0ZUNpcmN1bGFyQm91bmRhcnkiLCAiY29tcHV0ZUxpbmVhckJvdW5kYXJ5IiwgIl9kcmF3ZmlsbCIsICJsaW5lT3B0cyIsICJhYm92ZSIsICJkb0ZpbGwiLCAiY2xpcFZlcnRpY2FsIiwgImNsaXBZIiwgImxpbmVMb29wIiwgInNyYyIsICJub3RTaGFwZSIsICJjbGlwQm91bmRzIiwgImludGVycG9sYXRlZExpbmVUbyIsICJ0YXJnZXRMb29wIiwgImludGVycG9sYXRlZFBvaW50IiwgImFmdGVyRGF0YXNldHNVcGRhdGUiLCAiJGZpbGxlciIsICJiZWZvcmVEcmF3IiwgImRyYXdUaW1lIiwgImJlZm9yZURhdGFzZXRzRHJhdyIsICJiZWZvcmVEYXRhc2V0RHJhdyIsICJnZXRCb3hTaXplIiwgImxhYmVsT3B0cyIsICJib3hIZWlnaHQiLCAiYm94V2lkdGgiLCAidXNlUG9pbnRTdHlsZSIsICJwb2ludFN0eWxlV2lkdGgiLCAiaXRlbUhlaWdodCIsICJpdGVtc0VxdWFsIiwgIkxlZ2VuZCIsICJfYWRkZWQiLCAibGVnZW5kSGl0Qm94ZXMiLCAiX2hvdmVyZWRJdGVtIiwgImRvdWdobnV0TW9kZSIsICJsZWdlbmRJdGVtcyIsICJjb2x1bW5TaXplcyIsICJsaW5lV2lkdGhzIiwgImJ1aWxkTGFiZWxzIiwgImxhYmVsRm9udCIsICJfY29tcHV0ZVRpdGxlSGVpZ2h0IiwgIl9maXRSb3dzIiwgIl9maXRDb2xzIiwgImhpdGJveGVzIiwgInRvdGFsSGVpZ2h0IiwgInJvdyIsICJpdGVtV2lkdGgiLCAibWVhc3VyZVRleHQiLCAiX2l0ZW1IZWlnaHQiLCAiaGVpZ2h0TGltaXQiLCAidG90YWxXaWR0aCIsICJjdXJyZW50Q29sV2lkdGgiLCAiY3VycmVudENvbEhlaWdodCIsICJjb2wiLCAiY2FsY3VsYXRlSXRlbVNpemUiLCAiYWRqdXN0SGl0Qm94ZXMiLCAicnRsIiwgInJ0bEhlbHBlciIsICJnZXRSdGxBZGFwdGVyIiwgImhpdGJveCIsICJsZWZ0Rm9yTHRyIiwgIl9kcmF3IiwgImRlZmF1bHRDb2xvciIsICJoYWxmRm9udFNpemUiLCAiY3Vyc29yIiwgImRyYXdMZWdlbmRCb3giLCAibGluZURhc2giLCAiZHJhd09wdGlvbnMiLCAiU1FSVDIiLCAieFBsdXMiLCAiZHJhd1BvaW50TGVnZW5kIiwgInlCb3hUb3AiLCAieEJveExlZnQiLCAiZmlsbFRleHQiLCAic3RyaWtldGhyb3VnaCIsICJvdmVycmlkZVRleHREaXJlY3Rpb24iLCAidGV4dERpcmVjdGlvbiIsICJ0ZXh0V2lkdGgiLCAic2V0V2lkdGgiLCAicmVhbFgiLCAiX3RleHRYIiwgImZvbnRMaW5lSGVpZ2h0IiwgImNhbGN1bGF0ZUxlZ2VuZEl0ZW1IZWlnaHQiLCAicmVzdG9yZVRleHREaXJlY3Rpb24iLCAidGl0bGVGb250IiwgInRpdGxlUGFkZGluZyIsICJ0b3BQYWRkaW5nUGx1c0hhbGZGb250U2l6ZSIsICJfZ2V0TGVnZW5kSXRlbUF0IiwgImhpdEJveCIsICJsaCIsICJoYW5kbGVFdmVudCIsICJpc0xpc3RlbmVkIiwgImhvdmVyZWRJdGVtIiwgInNhbWVJdGVtIiwgIm9uTGVhdmUiLCAiY2FsY3VsYXRlSXRlbVdpZHRoIiwgImNhbGN1bGF0ZUl0ZW1IZWlnaHQiLCAibGVnZW5kSXRlbVRleHQiLCAiX2VsZW1lbnQiLCAiYWZ0ZXJFdmVudCIsICJjaSIsICJ1c2VCb3JkZXJSYWRpdXMiLCAiVGl0bGUiLCAiX3BhZGRpbmciLCAidGV4dFNpemUiLCAiX2RyYXdBcmdzIiwgImZvbnRPcHRzIiwgImNyZWF0ZVRpdGxlIiwgInRpdGxlQmxvY2siLCAiV2Vha01hcCIsICJwb3NpdGlvbmVycyIsICJhdmVyYWdlIiwgInhTZXQiLCAieEF2ZXJhZ2UiLCAiZXZlbnRQb3NpdGlvbiIsICJuZWFyZXN0RWxlbWVudCIsICJkaXN0YW5jZUJldHdlZW5Qb2ludHMiLCAidHAiLCAicHVzaE9yQ29uY2F0IiwgInRvUHVzaCIsICJhcHBseSIsICJzcGxpdE5ld2xpbmVzIiwgInN0ciIsICJTdHJpbmciLCAiY3JlYXRlVG9vbHRpcEl0ZW0iLCAiZm9ybWF0dGVkVmFsdWUiLCAiZ2V0VG9vbHRpcFNpemUiLCAidG9vbHRpcCIsICJib2R5IiwgImZvb3RlciIsICJib2R5Rm9udCIsICJmb290ZXJGb250IiwgInRpdGxlTGluZUNvdW50IiwgImZvb3RlckxpbmVDb3VudCIsICJib2R5TGluZUl0ZW1Db3VudCIsICJjb21iaW5lZEJvZHlMZW5ndGgiLCAiYm9keUl0ZW0iLCAiYmVmb3JlIiwgImFmdGVyIiwgImJlZm9yZUJvZHkiLCAiYWZ0ZXJCb2R5IiwgInRpdGxlU3BhY2luZyIsICJ0aXRsZU1hcmdpbkJvdHRvbSIsICJib2R5TGluZUhlaWdodCIsICJkaXNwbGF5Q29sb3JzIiwgImJvZHlTcGFjaW5nIiwgImZvb3Rlck1hcmdpblRvcCIsICJmb290ZXJTcGFjaW5nIiwgIndpZHRoUGFkZGluZyIsICJtYXhMaW5lV2lkdGgiLCAiZGV0ZXJtaW5lWUFsaWduIiwgImRvZXNOb3RGaXRXaXRoQWxpZ24iLCAieEFsaWduIiwgImNhcmV0IiwgImNhcmV0U2l6ZSIsICJjYXJldFBhZGRpbmciLCAiZGV0ZXJtaW5lWEFsaWduIiwgInlBbGlnbiIsICJjaGFydFdpZHRoIiwgImRldGVybWluZUFsaWdubWVudCIsICJhbGlnblgiLCAiYWxpZ25ZIiwgInBhZGRpbmdBbmRTaXplIiwgImdldEJhY2tncm91bmRQb2ludCIsICJhbGlnbm1lbnQiLCAiY29ybmVyUmFkaXVzIiwgImdldEFsaWduZWRYIiwgImdldEJlZm9yZUFmdGVyQm9keUxpbmVzIiwgImNyZWF0ZVRvb2x0aXBDb250ZXh0IiwgInRvb2x0aXBJdGVtcyIsICJvdmVycmlkZUNhbGxiYWNrcyIsICJkZWZhdWx0Q2FsbGJhY2tzIiwgImJlZm9yZVRpdGxlIiwgIm5vb3AiLCAibGFiZWxDb3VudCIsICJhZnRlclRpdGxlIiwgImJlZm9yZUxhYmVsIiwgInRvb2x0aXBJdGVtIiwgImxhYmVsQ29sb3IiLCAibGFiZWxUZXh0Q29sb3IiLCAiYm9keUNvbG9yIiwgImxhYmVsUG9pbnRTdHlsZSIsICJhZnRlckxhYmVsIiwgImJlZm9yZUZvb3RlciIsICJhZnRlckZvb3RlciIsICJpbnZva2VDYWxsYmFja1dpdGhGYWxsYmFjayIsICJUb29sdGlwIiwgIm9wYWNpdHkiLCAiX2V2ZW50UG9zaXRpb24iLCAiX3NpemUiLCAiX2NhY2hlZEFuaW1hdGlvbnMiLCAiX3Rvb2x0aXBJdGVtcyIsICJkYXRhUG9pbnRzIiwgImNhcmV0WCIsICJjYXJldFkiLCAibGFiZWxDb2xvcnMiLCAibGFiZWxQb2ludFN0eWxlcyIsICJsYWJlbFRleHRDb2xvcnMiLCAiZ2V0VGl0bGUiLCAiZ2V0QmVmb3JlQm9keSIsICJnZXRCb2R5IiwgImJvZHlJdGVtcyIsICJzY29wZWQiLCAiZ2V0QWZ0ZXJCb2R5IiwgImdldEZvb3RlciIsICJfY3JlYXRlSXRlbXMiLCAiaXRlbVNvcnQiLCAicG9zaXRpb25BbmRTaXplIiwgImJhY2tncm91bmRQb2ludCIsICJleHRlcm5hbCIsICJkcmF3Q2FyZXQiLCAidG9vbHRpcFBvaW50IiwgImNhcmV0UG9zaXRpb24iLCAiZ2V0Q2FyZXRQb3NpdGlvbiIsICJ4MyIsICJ5MyIsICJwdFgiLCAicHRZIiwgInB0IiwgInRpdGxlQ29sb3IiLCAiX2RyYXdDb2xvckJveCIsICJjb2xvclgiLCAicnRsQ29sb3JYIiwgInlPZmZTZXQiLCAiY29sb3JZIiwgIm11bHRpS2V5QmFja2dyb3VuZCIsICJvdXRlclgiLCAiaW5uZXJYIiwgInN0cm9rZVJlY3QiLCAiZHJhd0JvZHkiLCAiYm9keUFsaWduIiwgInhMaW5lUGFkZGluZyIsICJmaWxsTGluZU9mVGV4dCIsICJib2R5QWxpZ25Gb3JDYWxjdWxhdGlvbiIsICJ0ZXh0Q29sb3IiLCAiZHJhd0Zvb3RlciIsICJmb290ZXJBbGlnbiIsICJmb290ZXJDb2xvciIsICJ0b29sdGlwU2l6ZSIsICJxdWFkcmF0aWNDdXJ2ZVRvIiwgIl91cGRhdGVBbmltYXRpb25UYXJnZXQiLCAiYW5pbVgiLCAiYW5pbVkiLCAiX3dpbGxSZW5kZXIiLCAiaGFzVG9vbHRpcENvbnRlbnQiLCAiZ2xvYmFsQWxwaGEiLCAicG9zaXRpb25DaGFuZ2VkIiwgIl9wb3NpdGlvbkNoYW5nZWQiLCAiX2lnbm9yZVJlcGxheUV2ZW50cyIsICJhZnRlckluaXQiLCAiYWZ0ZXJEcmF3IiwgIl9mYWxsYmFjayIsICJhZGRJZlN0cmluZyIsICJhZGRlZExhYmVscyIsICJmaW5kT3JBZGRMYWJlbCIsICJsYXN0SW5kZXhPZiIsICJfZ2V0TGFiZWxGb3JWYWx1ZSIsICJDYXRlZ29yeVNjYWxlIiwgIl9zdGFydFZhbHVlIiwgIl92YWx1ZVJhbmdlIiwgIl9hZGRlZExhYmVscyIsICJhZGRlZCIsICJnZW5lcmF0ZVRpY2tzIiwgImdlbmVyYXRpb25PcHRpb25zIiwgImRhdGFSYW5nZSIsICJNSU5fU1BBQ0lORyIsICJwcmVjaXNpb24iLCAibWF4VGlja3MiLCAibWF4RGlnaXRzIiwgImluY2x1ZGVCb3VuZHMiLCAidW5pdCIsICJtYXhTcGFjZXMiLCAicm1pbiIsICJybWF4IiwgImNvdW50RGVmaW5lZCIsICJtaW5TcGFjaW5nIiwgIm5pY2VOdW0iLCAibmljZU1pbiIsICJuaWNlTWF4IiwgIm51bVNwYWNlcyIsICJhbG1vc3RXaG9sZSIsICJhbG1vc3RFcXVhbHMiLCAiZGVjaW1hbFBsYWNlcyIsICJfZGVjaW1hbFBsYWNlcyIsICJyZWxhdGl2ZUxhYmVsU2l6ZSIsICJ0aWNrVmFsdWUiLCAicmFkIiwgIkxpbmVhclNjYWxlQmFzZSIsICJfZW5kVmFsdWUiLCAiaGFuZGxlVGlja1JhbmdlT3B0aW9ucyIsICJzZXRNaW4iLCAic2V0TWF4IiwgIm1pblNpZ24iLCAibWF4U2lnbiIsICJnZXRUaWNrTGltaXQiLCAic3RlcFNpemUiLCAiY29tcHV0ZVRpY2tMaW1pdCIsICJudW1lcmljR2VuZXJhdG9yT3B0aW9ucyIsICJfc2V0TWluQW5kTWF4QnlLZXkiLCAiTGluZWFyU2NhbGUiLCAiVGlja3MiLCAiZm9ybWF0dGVycyIsICJudW1lcmljIiwgImxvZzEwRmxvb3IiLCAibG9nMTAiLCAiY2hhbmdlRXhwb25lbnQiLCAibSIsICJpc01ham9yIiwgInRpY2tWYWwiLCAic3RlcHMiLCAicmFuZ2VFeHAiLCAicmFuZ2VTdGVwIiwgInN0YXJ0RXhwIiwgIm1pbkV4cCIsICJleHAiLCAic2lnbmlmaWNhbmQiLCAibGFzdFRpY2siLCAiTG9nYXJpdGhtaWNTY2FsZSIsICJfemVybyIsICJsb2dhcml0aG1pYyIsICJnZXRUaWNrQmFja2Ryb3BIZWlnaHQiLCAibWVhc3VyZUxhYmVsU2l6ZSIsICJfbG9uZ2VzdFRleHQiLCAiZGV0ZXJtaW5lTGltaXRzIiwgImZpdFdpdGhQb2ludExhYmVscyIsICJsaW1pdHMiLCAidmFsdWVDb3VudCIsICJfcG9pbnRMYWJlbHMiLCAicG9pbnRMYWJlbE9wdHMiLCAiYWRkaXRpb25hbEFuZ2xlIiwgImNlbnRlclBvaW50TGFiZWxzIiwgImdldFBvaW50TGFiZWxDb250ZXh0IiwgImdldFBvaW50UG9zaXRpb24iLCAiZHJhd2luZ0FyZWEiLCAicGxGb250IiwgImhMaW1pdHMiLCAidkxpbWl0cyIsICJ1cGRhdGVMaW1pdHMiLCAic2V0Q2VudGVyUG9pbnQiLCAiX3BvaW50TGFiZWxJdGVtcyIsICJidWlsZFBvaW50TGFiZWxJdGVtcyIsICJjcmVhdGVQb2ludExhYmVsSXRlbSIsICJpdGVtT3B0cyIsICJvdXRlckRpc3RhbmNlIiwgImV4dHJhIiwgInBvaW50TGFiZWxQb3NpdGlvbiIsICJ5Rm9yQW5nbGUiLCAiZ2V0VGV4dEFsaWduRm9yQW5nbGUiLCAibGVmdEZvclRleHRBbGlnbiIsICJpc05vdE92ZXJsYXBwZWQiLCAiYXBleGVzSW5BcmVhIiwgImRyYXdQb2ludExhYmVsQm94IiwgImJhY2tkcm9wTGVmdCIsICJiYWNrZHJvcFRvcCIsICJiYWNrZHJvcFdpZHRoIiwgImJhY2tkcm9wSGVpZ2h0IiwgImRyYXdQb2ludExhYmVscyIsICJwYXRoUmFkaXVzTGluZSIsICJkcmF3UmFkaXVzTGluZSIsICJncmlkTGluZU9wdHMiLCAiY3JlYXRlUG9pbnRMYWJlbENvbnRleHQiLCAiUmFkaWFsTGluZWFyU2NhbGUiLCAibGVmdE1vdmVtZW50IiwgInJpZ2h0TW92ZW1lbnQiLCAidG9wTW92ZW1lbnQiLCAiYm90dG9tTW92ZW1lbnQiLCAiYW5nbGVNdWx0aXBsaWVyIiwgInNjYWxpbmdGYWN0b3IiLCAiZ2V0VmFsdWVGb3JEaXN0YW5jZUZyb21DZW50ZXIiLCAic2NhbGVkRGlzdGFuY2UiLCAicG9pbnRMYWJlbCIsICJkaXN0YW5jZUZyb21DZW50ZXIiLCAiZ2V0QmFzZVBvc2l0aW9uIiwgImdldFBvaW50TGFiZWxQb3NpdGlvbiIsICJyb3RhdGUiLCAiYW5pbWF0ZSIsICJJTlRFUlZBTFMiLCAibWlsbGlzZWNvbmQiLCAiY29tbW9uIiwgInNlY29uZCIsICJtaW51dGUiLCAiaG91ciIsICJkYXkiLCAid2VlayIsICJtb250aCIsICJxdWFydGVyIiwgInllYXIiLCAiVU5JVFMiLCAic29ydGVyIiwgImlucHV0IiwgImFkYXB0ZXIiLCAiX2FkYXB0ZXIiLCAicGFyc2VyIiwgImlzb1dlZWtkYXkiLCAiX3BhcnNlT3B0cyIsICJkZXRlcm1pbmVVbml0Rm9yQXV0b1RpY2tzIiwgIm1pblVuaXQiLCAiY2FwYWNpdHkiLCAiaW50ZXJ2YWwiLCAiTUFYX1NBRkVfSU5URUdFUiIsICJkZXRlcm1pbmVVbml0Rm9yRm9ybWF0dGluZyIsICJkZXRlcm1pbmVNYWpvclVuaXQiLCAiYWRkVGljayIsICJ0aW1lIiwgInRpbWVzdGFtcHMiLCAiX2xvb2t1cCIsICJ0aW1lc3RhbXAiLCAic2V0TWFqb3JUaWNrcyIsICJtYWpvclVuaXQiLCAidGlja3NGcm9tVGltZXN0YW1wcyIsICJUaW1lU2NhbGUiLCAiX3VuaXQiLCAiX21ham9yVW5pdCIsICJfb2Zmc2V0cyIsICJfbm9ybWFsaXplZCIsICJhZGFwdGVycyIsICJkaXNwbGF5Rm9ybWF0cyIsICJub3JtYWxpemVkIiwgIl9hcHBseUJvdW5kcyIsICJfZ2V0TGFiZWxCb3VuZHMiLCAiZ2V0TGFiZWxUaW1lc3RhbXBzIiwgInRpbWVPcHRzIiwgIl9nZW5lcmF0ZSIsICJfZmlsdGVyQmV0d2VlbiIsICJfZ2V0TGFiZWxDYXBhY2l0eSIsICJpbml0T2Zmc2V0cyIsICJvZmZzZXRBZnRlckF1dG9za2lwIiwgImdldERlY2ltYWxGb3JWYWx1ZSIsICJtaW5vciIsICJ3ZWVrZGF5IiwgImhhc1dlZWtkYXkiLCAiZ2V0RGF0YVRpbWVzdGFtcHMiLCAidG9vbHRpcEZvcm1hdCIsICJkYXRldGltZSIsICJmbXQiLCAiX3RpY2tGb3JtYXRGdW5jdGlvbiIsICJmb3JtYXR0ZXIiLCAibWlub3JGb3JtYXQiLCAibWFqb3JGb3JtYXQiLCAib2Zmc2V0cyIsICJfZ2V0TGFiZWxTaXplIiwgInRpY2tzT3B0cyIsICJ0aWNrTGFiZWxXaWR0aCIsICJjb3NSb3RhdGlvbiIsICJzaW5Sb3RhdGlvbiIsICJ0aWNrRm9udFNpemUiLCAiZXhhbXBsZVRpbWUiLCAiZXhhbXBsZUxhYmVsIiwgIm5vcm1hbGl6ZSIsICJ0YWJsZSIsICJwcmV2U291cmNlIiwgIm5leHRTb3VyY2UiLCAicHJldlRhcmdldCIsICJuZXh0VGFyZ2V0IiwgInNwYW4iLCAiVGltZVNlcmllc1NjYWxlIiwgIl90YWJsZSIsICJfbWluUG9zIiwgIl90YWJsZVJhbmdlIiwgIl9nZXRUaW1lc3RhbXBzRm9yVGFibGUiLCAiYnVpbGRMb29rdXBUYWJsZSIsICJyZWdpc3RlcmFibGVzIiwgInJvdW5kIiwgImxpbSIsICJsIiwgInAyYiIsICJuMmIiLCAibGltIiwgInJvdW5kIiwgImIybiIsICJuMnAiLCAibWFwJDEiLCAiaGV4IiwgImgxIiwgImgyIiwgImVxIiwgImlzU2hvcnQiLCAiaGV4UGFyc2UiLCAiYWxwaGEiLCAiaGV4U3RyaW5nIiwgIkhVRV9SRSIsICJoc2wycmdibiIsICJzIiwgImwiLCAibiIsICJoc3YycmdibiIsICJod2IycmdibiIsICJodWVWYWx1ZSIsICJyZ2IyaHNsIiwgImNhbGxuIiwgImhzbDJyZ2IiLCAiaHdiMnJnYiIsICJoc3YycmdiIiwgImh1ZSIsICJodWVQYXJzZSIsICJwMmIiLCAicm90YXRlIiwgImhzbFN0cmluZyIsICJtYXAiLCAibmFtZXMkMSIsICJ1bnBhY2siLCAibmFtZXMiLCAibmFtZVBhcnNlIiwgIlJHQl9SRSIsICJyZ2JQYXJzZSIsICJyZ2JTdHJpbmciLCAidG8iLCAiZnJvbSIsICJpbnRlcnBvbGF0ZSIsICJtb2RIU0wiLCAiY2xvbmUiLCAiZnJvbU9iamVjdCIsICJmdW5jdGlvblBhcnNlIiwgIkNvbG9yIiwgImNvbG9yIiwgInVpZCIsICJpZCIsICJpc051bGxPclVuZGVmIiwgInZhbHVlIiwgImlzQXJyYXkiLCAiQXJyYXkiLCAidHlwZSIsICJPYmplY3QiLCAicHJvdG90eXBlIiwgInRvU3RyaW5nIiwgImNhbGwiLCAic2xpY2UiLCAiaXNPYmplY3QiLCAiaXNOdW1iZXJGaW5pdGUiLCAiTnVtYmVyIiwgImlzRmluaXRlIiwgImZpbml0ZU9yRGVmYXVsdCIsICJkZWZhdWx0VmFsdWUiLCAidmFsdWVPckRlZmF1bHQiLCAidG9EaW1lbnNpb24iLCAidmFsdWUiLCAiZGltZW5zaW9uIiwgImVuZHNXaXRoIiwgInBhcnNlRmxvYXQiLCAiY2FsbGJhY2siLCAiZm4iLCAiYXJncyIsICJ0aGlzQXJnIiwgImNhbGwiLCAiYXBwbHkiLCAiZWFjaCIsICJsb29wYWJsZSIsICJyZXZlcnNlIiwgImkiLCAibGVuIiwgImtleXMiLCAiaXNBcnJheSIsICJsZW5ndGgiLCAiaXNPYmplY3QiLCAiT2JqZWN0IiwgImNsb25lIiwgInNvdXJjZSIsICJpc0FycmF5IiwgIm1hcCIsICJpc09iamVjdCIsICJ0YXJnZXQiLCAiT2JqZWN0IiwgImNyZWF0ZSIsICJrZXlzIiwgImtsZW4iLCAibGVuZ3RoIiwgImsiLCAiaXNWYWxpZEtleSIsICJrZXkiLCAiaW5kZXhPZiIsICJfbWVyZ2VyIiwgIm9wdGlvbnMiLCAidHZhbCIsICJzdmFsIiwgIm1lcmdlIiwgInNvdXJjZXMiLCAiaWxlbiIsICJtZXJnZXIiLCAiY3VycmVudCIsICJpIiwgIm1lcmdlSWYiLCAiX21lcmdlcklmIiwgInByb3RvdHlwZSIsICJoYXNPd25Qcm9wZXJ0eSIsICJjYWxsIiwgIlBJIiwgIk1hdGgiLCAiVEFVIiwgIlBJVEFVIiwgIklORklOSVRZIiwgIk51bWJlciIsICJQT1NJVElWRV9JTkZJTklUWSIsICJSQURfUEVSX0RFRyIsICJIQUxGX1BJIiwgIlFVQVJURVJfUEkiLCAiVFdPX1RISVJEU19QSSIsICJsb2cxMCIsICJzaWduIiwgImFsbW9zdEVxdWFscyIsICJ4IiwgInkiLCAiZXBzaWxvbiIsICJhYnMiLCAibmljZU51bSIsICJyYW5nZSIsICJyb3VuZGVkUmFuZ2UiLCAicm91bmQiLCAibmljZVJhbmdlIiwgInBvdyIsICJmbG9vciIsICJmcmFjdGlvbiIsICJuaWNlRnJhY3Rpb24iLCAiX2ZhY3Rvcml6ZSIsICJ2YWx1ZSIsICJyZXN1bHQiLCAic3FydCIsICJpIiwgInB1c2giLCAic29ydCIsICJhIiwgImIiLCAicG9wIiwgImlzTnVtYmVyIiwgIm4iLCAiaXNOYU4iLCAicGFyc2VGbG9hdCIsICJpc0Zpbml0ZSIsICJhbG1vc3RXaG9sZSIsICJyb3VuZGVkIiwgIl9zZXRNaW5BbmRNYXhCeUtleSIsICJhcnJheSIsICJ0YXJnZXQiLCAicHJvcGVydHkiLCAiaWxlbiIsICJsZW5ndGgiLCAibWluIiwgIm1heCIsICJ0b1JhZGlhbnMiLCAiZGVncmVlcyIsICJ0b0RlZ3JlZXMiLCAicmFkaWFucyIsICJfZGVjaW1hbFBsYWNlcyIsICJpc0Zpbml0ZU51bWJlciIsICJlIiwgInAiLCAiX25vcm1hbGl6ZUFuZ2xlIiwgImEiLCAiVEFVIiwgIl9saW1pdFZhbHVlIiwgInZhbHVlIiwgIm1pbiIsICJtYXgiLCAiTWF0aCIsICJfaW50MTZSYW5nZSIsICJfbG9va3VwIiwgInRhYmxlIiwgInZhbHVlIiwgImNtcCIsICJpbmRleCIsICJoaSIsICJsZW5ndGgiLCAibG8iLCAibWlkIiwgIl9sb29rdXBCeUtleSIsICJrZXkiLCAibGFzdCIsICJ0aSIsICJfZmlsdGVyQmV0d2VlbiIsICJ2YWx1ZXMiLCAibWluIiwgIm1heCIsICJzdGFydCIsICJlbmQiLCAibGVuZ3RoIiwgInNsaWNlIiwgIl9hcnJheVVuaXF1ZSIsICJpdGVtcyIsICJzZXQiLCAiU2V0IiwgInNpemUiLCAibGVuZ3RoIiwgIkFycmF5IiwgImZyb20iLCAicmVxdWVzdEFuaW1GcmFtZSIsICJ3aW5kb3ciLCAiY2FsbGJhY2siLCAicmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwgIl90b0xlZnRSaWdodENlbnRlciIsICJhbGlnbiIsICJfYWxpZ25TdGFydEVuZCIsICJzdGFydCIsICJlbmQiLCAiaXNQYXR0ZXJuT3JHcmFkaWVudCIsICJ2YWx1ZSIsICJ0eXBlIiwgInRvU3RyaW5nIiwgImdldEhvdmVyQ29sb3IiLCAidmFsdWUiLCAiaXNQYXR0ZXJuT3JHcmFkaWVudCIsICJDb2xvciIsICJzYXR1cmF0ZSIsICJkYXJrZW4iLCAiaGV4U3RyaW5nIiwgIm51bWJlcnMiLCAiY29sb3JzIiwgImFwcGx5QW5pbWF0aW9uc0RlZmF1bHRzIiwgImRlZmF1bHRzIiwgInNldCIsICJkZWxheSIsICJ1bmRlZmluZWQiLCAiZHVyYXRpb24iLCAiZWFzaW5nIiwgImZuIiwgImZyb20iLCAibG9vcCIsICJ0byIsICJ0eXBlIiwgImRlc2NyaWJlIiwgIl9mYWxsYmFjayIsICJfaW5kZXhhYmxlIiwgIl9zY3JpcHRhYmxlIiwgIm5hbWUiLCAicHJvcGVydGllcyIsICJhY3RpdmUiLCAiYW5pbWF0aW9uIiwgInJlc2l6ZSIsICJzaG93IiwgImFuaW1hdGlvbnMiLCAidmlzaWJsZSIsICJoaWRlIiwgInYiLCAiYXBwbHlMYXlvdXRzRGVmYXVsdHMiLCAiYXV0b1BhZGRpbmciLCAicGFkZGluZyIsICJ0b3AiLCAicmlnaHQiLCAiYm90dG9tIiwgImxlZnQiLCAiaW50bENhY2hlIiwgIk1hcCIsICJnZXROdW1iZXJGb3JtYXQiLCAibG9jYWxlIiwgIm9wdGlvbnMiLCAiY2FjaGVLZXkiLCAiSlNPTiIsICJzdHJpbmdpZnkiLCAiZm9ybWF0dGVyIiwgImdldCIsICJJbnRsIiwgIk51bWJlckZvcm1hdCIsICJmb3JtYXROdW1iZXIiLCAibnVtIiwgImZvcm1hdCIsICJmb3JtYXR0ZXJzIiwgInZhbHVlcyIsICJpc0FycmF5IiwgIm51bWVyaWMiLCAidGlja1ZhbHVlIiwgImluZGV4IiwgInRpY2tzIiwgImNoYXJ0IiwgIm5vdGF0aW9uIiwgImRlbHRhIiwgImxlbmd0aCIsICJtYXhUaWNrIiwgIk1hdGgiLCAibWF4IiwgImFicyIsICJjYWxjdWxhdGVEZWx0YSIsICJsb2dEZWx0YSIsICJsb2cxMCIsICJudW1EZWNpbWFsIiwgImlzTmFOIiwgIm1pbiIsICJmbG9vciIsICJtaW5pbXVtRnJhY3Rpb25EaWdpdHMiLCAibWF4aW11bUZyYWN0aW9uRGlnaXRzIiwgIk9iamVjdCIsICJhc3NpZ24iLCAibG9nYXJpdGhtaWMiLCAicmVtYWluIiwgInNpZ25pZmljYW5kIiwgInBvdyIsICJpbmNsdWRlcyIsICJjYWxsIiwgIlRpY2tzIiwgImFwcGx5U2NhbGVEZWZhdWx0cyIsICJkaXNwbGF5IiwgIm9mZnNldCIsICJyZXZlcnNlIiwgImJlZ2luQXRaZXJvIiwgImJvdW5kcyIsICJjbGlwIiwgImdyYWNlIiwgImdyaWQiLCAibGluZVdpZHRoIiwgImRyYXdPbkNoYXJ0QXJlYSIsICJkcmF3VGlja3MiLCAidGlja0xlbmd0aCIsICJ0aWNrV2lkdGgiLCAiX2N0eCIsICJ0aWNrQ29sb3IiLCAiY29sb3IiLCAiYm9yZGVyIiwgImRhc2giLCAiZGFzaE9mZnNldCIsICJ3aWR0aCIsICJ0aXRsZSIsICJ0ZXh0IiwgIm1pblJvdGF0aW9uIiwgIm1heFJvdGF0aW9uIiwgIm1pcnJvciIsICJ0ZXh0U3Ryb2tlV2lkdGgiLCAidGV4dFN0cm9rZUNvbG9yIiwgImF1dG9Ta2lwIiwgImF1dG9Ta2lwUGFkZGluZyIsICJsYWJlbE9mZnNldCIsICJjYWxsYmFjayIsICJtaW5vciIsICJtYWpvciIsICJhbGlnbiIsICJjcm9zc0FsaWduIiwgInNob3dMYWJlbEJhY2tkcm9wIiwgImJhY2tkcm9wQ29sb3IiLCAiYmFja2Ryb3BQYWRkaW5nIiwgInJvdXRlIiwgInN0YXJ0c1dpdGgiLCAib3ZlcnJpZGVzIiwgImNyZWF0ZSIsICJkZXNjcmlwdG9ycyIsICJnZXRTY29wZSIsICJub2RlIiwgImtleSIsICJrZXlzIiwgInNwbGl0IiwgImkiLCAibiIsICJrIiwgInJvb3QiLCAic2NvcGUiLCAibWVyZ2UiLCAiRGVmYXVsdHMiLCAiY29uc3RydWN0b3IiLCAiX2Rlc2NyaXB0b3JzIiwgIl9hcHBsaWVycyIsICJiYWNrZ3JvdW5kQ29sb3IiLCAiYm9yZGVyQ29sb3IiLCAiZGF0YXNldHMiLCAiZGV2aWNlUGl4ZWxSYXRpbyIsICJjb250ZXh0IiwgInBsYXRmb3JtIiwgImdldERldmljZVBpeGVsUmF0aW8iLCAiZWxlbWVudHMiLCAiZXZlbnRzIiwgImZvbnQiLCAiZmFtaWx5IiwgInNpemUiLCAic3R5bGUiLCAibGluZUhlaWdodCIsICJ3ZWlnaHQiLCAiaG92ZXIiLCAiaG92ZXJCYWNrZ3JvdW5kQ29sb3IiLCAiY3R4IiwgImhvdmVyQm9yZGVyQ29sb3IiLCAiaG92ZXJDb2xvciIsICJpbmRleEF4aXMiLCAiaW50ZXJhY3Rpb24iLCAibW9kZSIsICJpbnRlcnNlY3QiLCAiaW5jbHVkZUludmlzaWJsZSIsICJtYWludGFpbkFzcGVjdFJhdGlvIiwgIm9uSG92ZXIiLCAib25DbGljayIsICJwYXJzaW5nIiwgInBsdWdpbnMiLCAicmVzcG9uc2l2ZSIsICJzY2FsZSIsICJzY2FsZXMiLCAic2hvd0xpbmUiLCAiZHJhd0FjdGl2ZUVsZW1lbnRzT25Ub3AiLCAiYXBwbHkiLCAib3ZlcnJpZGUiLCAidGFyZ2V0U2NvcGUiLCAidGFyZ2V0TmFtZSIsICJzY29wZU9iamVjdCIsICJ0YXJnZXRTY29wZU9iamVjdCIsICJwcml2YXRlTmFtZSIsICJkZWZpbmVQcm9wZXJ0aWVzIiwgIndyaXRhYmxlIiwgImVudW1lcmFibGUiLCAibG9jYWwiLCAidGFyZ2V0IiwgImlzT2JqZWN0IiwgInZhbHVlT3JEZWZhdWx0IiwgImFwcGxpZXJzIiwgImZvckVhY2giLCAidG9Gb250U3RyaW5nIiwgImlzTnVsbE9yVW5kZWYiLCAiX21lYXN1cmVUZXh0IiwgImRhdGEiLCAiZ2MiLCAibG9uZ2VzdCIsICJzdHJpbmciLCAidGV4dFdpZHRoIiwgIm1lYXN1cmVUZXh0IiwgInB1c2giLCAiX2xvbmdlc3RUZXh0IiwgImFycmF5T2ZUaGluZ3MiLCAiY2FjaGUiLCAiZ2FyYmFnZUNvbGxlY3QiLCAic2F2ZSIsICJpbGVuIiwgImoiLCAiamxlbiIsICJ0aGluZyIsICJuZXN0ZWRUaGluZyIsICJyZXN0b3JlIiwgImdjTGVuIiwgInNwbGljZSIsICJfYWxpZ25QaXhlbCIsICJwaXhlbCIsICJjdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyIsICJoYWxmV2lkdGgiLCAicm91bmQiLCAiX2lzUG9pbnRJbkFyZWEiLCAicG9pbnQiLCAiYXJlYSIsICJtYXJnaW4iLCAieCIsICJsZWZ0IiwgInJpZ2h0IiwgInkiLCAidG9wIiwgImJvdHRvbSIsICJjbGlwQXJlYSIsICJjdHgiLCAic2F2ZSIsICJiZWdpblBhdGgiLCAicmVjdCIsICJjbGlwIiwgInVuY2xpcEFyZWEiLCAicmVzdG9yZSIsICJzZXRSZW5kZXJPcHRzIiwgImN0eCIsICJvcHRzIiwgInRyYW5zbGF0aW9uIiwgInRyYW5zbGF0ZSIsICJpc051bGxPclVuZGVmIiwgInJvdGF0aW9uIiwgInJvdGF0ZSIsICJjb2xvciIsICJmaWxsU3R5bGUiLCAidGV4dEFsaWduIiwgInRleHRCYXNlbGluZSIsICJkZWNvcmF0ZVRleHQiLCAieCIsICJ5IiwgImxpbmUiLCAic3RyaWtldGhyb3VnaCIsICJ1bmRlcmxpbmUiLCAibWV0cmljcyIsICJtZWFzdXJlVGV4dCIsICJsZWZ0IiwgImFjdHVhbEJvdW5kaW5nQm94TGVmdCIsICJyaWdodCIsICJhY3R1YWxCb3VuZGluZ0JveFJpZ2h0IiwgInRvcCIsICJhY3R1YWxCb3VuZGluZ0JveEFzY2VudCIsICJib3R0b20iLCAiYWN0dWFsQm91bmRpbmdCb3hEZXNjZW50IiwgInlEZWNvcmF0aW9uIiwgInN0cm9rZVN0eWxlIiwgImJlZ2luUGF0aCIsICJsaW5lV2lkdGgiLCAiZGVjb3JhdGlvbldpZHRoIiwgIm1vdmVUbyIsICJsaW5lVG8iLCAic3Ryb2tlIiwgImRyYXdCYWNrZHJvcCIsICJvbGRDb2xvciIsICJmaWxsUmVjdCIsICJ3aWR0aCIsICJoZWlnaHQiLCAicmVuZGVyVGV4dCIsICJ0ZXh0IiwgImZvbnQiLCAibGluZXMiLCAiaXNBcnJheSIsICJzdHJva2VXaWR0aCIsICJzdHJva2VDb2xvciIsICJpIiwgInNhdmUiLCAic3RyaW5nIiwgImxlbmd0aCIsICJiYWNrZHJvcCIsICJzdHJva2VUZXh0IiwgIm1heFdpZHRoIiwgImZpbGxUZXh0IiwgIk51bWJlciIsICJsaW5lSGVpZ2h0IiwgInJlc3RvcmUiLCAiYWRkUm91bmRlZFJlY3RQYXRoIiwgInJlY3QiLCAidyIsICJoIiwgInJhZGl1cyIsICJhcmMiLCAidG9wTGVmdCIsICJQSSIsICJib3R0b21MZWZ0IiwgIkhBTEZfUEkiLCAiYm90dG9tUmlnaHQiLCAidG9wUmlnaHQiLCAiTElORV9IRUlHSFQiLCAiRk9OVF9TVFlMRSIsICJ0b0xpbmVIZWlnaHQiLCAidmFsdWUiLCAic2l6ZSIsICJtYXRjaGVzIiwgIm1hdGNoIiwgIm51bWJlck9yWmVybyIsICJ2IiwgIl9yZWFkVmFsdWVUb1Byb3BzIiwgInByb3BzIiwgInJldCIsICJvYmpQcm9wcyIsICJpc09iamVjdCIsICJrZXlzIiwgIk9iamVjdCIsICJyZWFkIiwgInByb3AiLCAidmFsdWVPckRlZmF1bHQiLCAidG9UUkJMIiwgInRvVFJCTENvcm5lcnMiLCAidG9QYWRkaW5nIiwgIm9iaiIsICJ0b0ZvbnQiLCAib3B0aW9ucyIsICJmYWxsYmFjayIsICJkZWZhdWx0cyIsICJwYXJzZUludCIsICJzdHlsZSIsICJjb25zb2xlIiwgIndhcm4iLCAidW5kZWZpbmVkIiwgImZhbWlseSIsICJ3ZWlnaHQiLCAidG9Gb250U3RyaW5nIiwgIl9hZGRHcmFjZSIsICJtaW5tYXgiLCAiZ3JhY2UiLCAiYmVnaW5BdFplcm8iLCAibWluIiwgIm1heCIsICJjaGFuZ2UiLCAidG9EaW1lbnNpb24iLCAia2VlcFplcm8iLCAidmFsdWUiLCAiYWRkIiwgIk1hdGgiLCAiYWJzIiwgImNyZWF0ZUNvbnRleHQiLCAicGFyZW50Q29udGV4dCIsICJjb250ZXh0IiwgIk9iamVjdCIsICJhc3NpZ24iLCAiY3JlYXRlIiwgIkVQU0lMT04iLCAiTnVtYmVyIiwgIl9pc0RvbVN1cHBvcnRlZCIsICJ3aW5kb3ciLCAiZG9jdW1lbnQiLCAic3VwcG9ydHNFdmVudExpc3RlbmVyT3B0aW9ucyIsICJwYXNzaXZlU3VwcG9ydGVkIiwgIm9wdGlvbnMiLCAicGFzc2l2ZSIsICJfaXNEb21TdXBwb3J0ZWQiLCAid2luZG93IiwgImFkZEV2ZW50TGlzdGVuZXIiLCAicmVtb3ZlRXZlbnRMaXN0ZW5lciIsICJlIiwgImFic3RyYWN0IiwgIkVycm9yIiwgIkRhdGVBZGFwdGVyQmFzZSIsICJjb25zdHJ1Y3RvciIsICJvcHRpb25zIiwgIm92ZXJyaWRlIiwgIm1lbWJlcnMiLCAiT2JqZWN0IiwgImFzc2lnbiIsICJwcm90b3R5cGUiLCAiaW5pdCIsICJmb3JtYXRzIiwgInBhcnNlIiwgImZvcm1hdCIsICJhZGQiLCAiZGlmZiIsICJzdGFydE9mIiwgImVuZE9mIiwgImFkYXB0ZXJzIiwgIl9kYXRlIiwgIkVsZW1lbnQiLCAieCIsICJ5IiwgImFjdGl2ZSIsICJvcHRpb25zIiwgIiRhbmltYXRpb25zIiwgInRvb2x0aXBQb3NpdGlvbiIsICJ1c2VGaW5hbFBvc2l0aW9uIiwgImdldFByb3BzIiwgImhhc1ZhbHVlIiwgImlzTnVtYmVyIiwgInByb3BzIiwgImZpbmFsIiwgImFuaW1zIiwgInJldCIsICJmb3JFYWNoIiwgInByb3AiLCAiX3RvIiwgImRlZmF1bHRzIiwgImRlZmF1bHRSb3V0ZXMiLCAiYXV0b1NraXAiLCAic2NhbGUiLCAidGlja3MiLCAidGlja09wdHMiLCAiZGV0ZXJtaW5lZE1heFRpY2tzIiwgImRldGVybWluZU1heFRpY2tzIiwgInRpY2tzTGltaXQiLCAiTWF0aCIsICJtaW4iLCAibWF4VGlja3NMaW1pdCIsICJtYWpvckluZGljZXMiLCAibWFqb3IiLCAiZW5hYmxlZCIsICJnZXRNYWpvckluZGljZXMiLCAibnVtTWFqb3JJbmRpY2VzIiwgImxlbmd0aCIsICJmaXJzdCIsICJsYXN0IiwgIm5ld1RpY2tzIiwgInNraXBNYWpvcnMiLCAic3BhY2luZyIsICJjYWxjdWxhdGVTcGFjaW5nIiwgImkiLCAiaWxlbiIsICJhdmdNYWpvclNwYWNpbmciLCAicm91bmQiLCAic2tpcCIsICJpc051bGxPclVuZGVmIiwgIm9mZnNldCIsICJ0aWNrTGVuZ3RoIiwgIl90aWNrU2l6ZSIsICJtYXhTY2FsZSIsICJfbGVuZ3RoIiwgIm1heENoYXJ0IiwgIl9tYXhMZW5ndGgiLCAiZmxvb3IiLCAiZXZlbk1ham9yU3BhY2luZyIsICJnZXRFdmVuU3BhY2luZyIsICJtYXgiLCAiZmFjdG9ycyIsICJfZmFjdG9yaXplIiwgImZhY3RvciIsICJyZXN1bHQiLCAicHVzaCIsICJjb3VudCIsICJuZXh0IiwgImNlaWwiLCAibWFqb3JTdGFydCIsICJtYWpvckVuZCIsICJzdGFydCIsICJ2YWx1ZU9yRGVmYXVsdCIsICJlbmQiLCAiYXJyIiwgImxlbiIsICJkaWZmIiwgInJldmVyc2VBbGlnbiIsICJhbGlnbiIsICJvZmZzZXRGcm9tRWRnZSIsICJlZGdlIiwgImdldFRpY2tzTGltaXQiLCAidGlja3NMZW5ndGgiLCAic2FtcGxlIiwgIm51bUl0ZW1zIiwgImluY3JlbWVudCIsICJnZXRQaXhlbEZvckdyaWRMaW5lIiwgImluZGV4IiwgIm9mZnNldEdyaWRMaW5lcyIsICJ2YWxpZEluZGV4IiwgIl9zdGFydFBpeGVsIiwgIl9lbmRQaXhlbCIsICJlcHNpbG9uIiwgImxpbmVWYWx1ZSIsICJnZXRQaXhlbEZvclRpY2siLCAiZ2FyYmFnZUNvbGxlY3QiLCAiY2FjaGVzIiwgImVhY2giLCAiY2FjaGUiLCAiZ2MiLCAiZ2NMZW4iLCAiZGF0YSIsICJzcGxpY2UiLCAiZ2V0VGlja01hcmtMZW5ndGgiLCAiZHJhd1RpY2tzIiwgImdldFRpdGxlSGVpZ2h0IiwgImZhbGxiYWNrIiwgImRpc3BsYXkiLCAiZm9udCIsICJ0b0ZvbnQiLCAicGFkZGluZyIsICJ0b1BhZGRpbmciLCAibGluZXMiLCAiaXNBcnJheSIsICJ0ZXh0IiwgImxpbmVIZWlnaHQiLCAiaGVpZ2h0IiwgImNyZWF0ZVNjYWxlQ29udGV4dCIsICJwYXJlbnQiLCAiY3JlYXRlQ29udGV4dCIsICJ0eXBlIiwgImNyZWF0ZVRpY2tDb250ZXh0IiwgInRpY2siLCAidGl0bGVBbGlnbiIsICJwb3NpdGlvbiIsICJyZXZlcnNlIiwgIl90b0xlZnRSaWdodENlbnRlciIsICJ0aXRsZUFyZ3MiLCAidG9wIiwgImxlZnQiLCAiYm90dG9tIiwgInJpZ2h0IiwgImNoYXJ0IiwgImNoYXJ0QXJlYSIsICJzY2FsZXMiLCAicm90YXRpb24iLCAibWF4V2lkdGgiLCAidGl0bGVYIiwgInRpdGxlWSIsICJ3aWR0aCIsICJpc0hvcml6b250YWwiLCAiX2FsaWduU3RhcnRFbmQiLCAiaXNPYmplY3QiLCAicG9zaXRpb25BeGlzSUQiLCAiT2JqZWN0IiwgImtleXMiLCAidmFsdWUiLCAiZ2V0UGl4ZWxGb3JWYWx1ZSIsICJIQUxGX1BJIiwgIlNjYWxlIiwgImNvbnN0cnVjdG9yIiwgImNmZyIsICJpZCIsICJ1bmRlZmluZWQiLCAiY3R4IiwgIl9tYXJnaW5zIiwgIm1heEhlaWdodCIsICJwYWRkaW5nVG9wIiwgInBhZGRpbmdCb3R0b20iLCAicGFkZGluZ0xlZnQiLCAicGFkZGluZ1JpZ2h0IiwgImF4aXMiLCAibGFiZWxSb3RhdGlvbiIsICJfcmFuZ2UiLCAiX2dyaWRMaW5lSXRlbXMiLCAiX2xhYmVsSXRlbXMiLCAiX2xhYmVsU2l6ZXMiLCAiX2xvbmdlc3RUZXh0Q2FjaGUiLCAiX3JldmVyc2VQaXhlbHMiLCAiX3VzZXJNYXgiLCAiX3VzZXJNaW4iLCAiX3N1Z2dlc3RlZE1heCIsICJfc3VnZ2VzdGVkTWluIiwgIl90aWNrc0xlbmd0aCIsICJfYm9yZGVyVmFsdWUiLCAiX2NhY2hlIiwgIl9kYXRhTGltaXRzQ2FjaGVkIiwgIiRjb250ZXh0IiwgImluaXQiLCAic2V0Q29udGV4dCIsICJnZXRDb250ZXh0IiwgInBhcnNlIiwgInN1Z2dlc3RlZE1pbiIsICJzdWdnZXN0ZWRNYXgiLCAicmF3IiwgImdldFVzZXJCb3VuZHMiLCAiZmluaXRlT3JEZWZhdWx0IiwgIk51bWJlciIsICJQT1NJVElWRV9JTkZJTklUWSIsICJORUdBVElWRV9JTkZJTklUWSIsICJtaW5EZWZpbmVkIiwgImlzRmluaXRlIiwgIm1heERlZmluZWQiLCAiZ2V0TWluTWF4IiwgImNhblN0YWNrIiwgInJhbmdlIiwgIm1ldGFzIiwgImdldE1hdGNoaW5nVmlzaWJsZU1ldGFzIiwgImNvbnRyb2xsZXIiLCAiZ2V0UGFkZGluZyIsICJnZXRUaWNrcyIsICJnZXRMYWJlbHMiLCAibGFiZWxzIiwgInhMYWJlbHMiLCAieUxhYmVscyIsICJnZXRMYWJlbEl0ZW1zIiwgIml0ZW1zIiwgIl9jb21wdXRlTGFiZWxJdGVtcyIsICJiZWZvcmVMYXlvdXQiLCAiYmVmb3JlVXBkYXRlIiwgImNhbGwiLCAidXBkYXRlIiwgIm1hcmdpbnMiLCAiYmVnaW5BdFplcm8iLCAiZ3JhY2UiLCAic2FtcGxlU2l6ZSIsICJhc3NpZ24iLCAiYmVmb3JlU2V0RGltZW5zaW9ucyIsICJzZXREaW1lbnNpb25zIiwgImFmdGVyU2V0RGltZW5zaW9ucyIsICJiZWZvcmVEYXRhTGltaXRzIiwgImRldGVybWluZURhdGFMaW1pdHMiLCAiYWZ0ZXJEYXRhTGltaXRzIiwgIl9hZGRHcmFjZSIsICJiZWZvcmVCdWlsZFRpY2tzIiwgImJ1aWxkVGlja3MiLCAiYWZ0ZXJCdWlsZFRpY2tzIiwgInNhbXBsaW5nRW5hYmxlZCIsICJfY29udmVydFRpY2tzVG9MYWJlbHMiLCAiY29uZmlndXJlIiwgImJlZm9yZUNhbGN1bGF0ZUxhYmVsUm90YXRpb24iLCAiY2FsY3VsYXRlTGFiZWxSb3RhdGlvbiIsICJhZnRlckNhbGN1bGF0ZUxhYmVsUm90YXRpb24iLCAic291cmNlIiwgImFmdGVyQXV0b1NraXAiLCAiYmVmb3JlRml0IiwgImZpdCIsICJhZnRlckZpdCIsICJhZnRlclVwZGF0ZSIsICJyZXZlcnNlUGl4ZWxzIiwgInN0YXJ0UGl4ZWwiLCAiZW5kUGl4ZWwiLCAiX2FsaWduVG9QaXhlbHMiLCAiYWxpZ25Ub1BpeGVscyIsICJfY2FsbEhvb2tzIiwgIm5hbWUiLCAibm90aWZ5UGx1Z2lucyIsICJiZWZvcmVUaWNrVG9MYWJlbENvbnZlcnNpb24iLCAiZ2VuZXJhdGVUaWNrTGFiZWxzIiwgImxhYmVsIiwgImNhbGxiYWNrIiwgImFmdGVyVGlja1RvTGFiZWxDb252ZXJzaW9uIiwgIm51bVRpY2tzIiwgIm1pblJvdGF0aW9uIiwgIm1heFJvdGF0aW9uIiwgInRpY2tXaWR0aCIsICJtYXhMYWJlbERpYWdvbmFsIiwgIl9pc1Zpc2libGUiLCAibGFiZWxTaXplcyIsICJfZ2V0TGFiZWxTaXplcyIsICJtYXhMYWJlbFdpZHRoIiwgIndpZGVzdCIsICJtYXhMYWJlbEhlaWdodCIsICJoaWdoZXN0IiwgIl9saW1pdFZhbHVlIiwgImdyaWQiLCAidGl0bGUiLCAic3FydCIsICJ0b0RlZ3JlZXMiLCAiYXNpbiIsICJtaW5TaXplIiwgInRpdGxlT3B0cyIsICJncmlkT3B0cyIsICJ0aXRsZUhlaWdodCIsICJ0aWNrUGFkZGluZyIsICJhbmdsZVJhZGlhbnMiLCAidG9SYWRpYW5zIiwgImNvcyIsICJzaW4iLCAibGFiZWxIZWlnaHQiLCAibWlycm9yIiwgImxhYmVsV2lkdGgiLCAiX2NhbGN1bGF0ZVBhZGRpbmciLCAiX2hhbmRsZU1hcmdpbnMiLCAiaXNSb3RhdGVkIiwgImxhYmVsc0JlbG93VGlja3MiLCAib2Zmc2V0TGVmdCIsICJvZmZzZXRSaWdodCIsICJpc0Z1bGxTaXplIiwgImZ1bGxTaXplIiwgIl9jb21wdXRlTGFiZWxTaXplcyIsICJ3aWR0aHMiLCAiaGVpZ2h0cyIsICJ3aWRlc3RMYWJlbFNpemUiLCAiaGlnaGVzdExhYmVsU2l6ZSIsICJqIiwgImpsZW4iLCAidGlja0ZvbnQiLCAiZm9udFN0cmluZyIsICJuZXN0ZWRMYWJlbCIsICJfcmVzb2x2ZVRpY2tGb250T3B0aW9ucyIsICJzdHJpbmciLCAiX21lYXN1cmVUZXh0IiwgImluZGV4T2YiLCAidmFsdWVBdCIsICJpZHgiLCAiZ2V0TGFiZWxGb3JWYWx1ZSIsICJOYU4iLCAiZ2V0VmFsdWVGb3JQaXhlbCIsICJwaXhlbCIsICJnZXRQaXhlbEZvckRlY2ltYWwiLCAiZGVjaW1hbCIsICJfaW50MTZSYW5nZSIsICJfYWxpZ25QaXhlbCIsICJnZXREZWNpbWFsRm9yUGl4ZWwiLCAiZ2V0QmFzZVBpeGVsIiwgImdldEJhc2VWYWx1ZSIsICJvcHRpb25UaWNrcyIsICJyb3QiLCAiYWJzIiwgImF1dG9Ta2lwUGFkZGluZyIsICJ3IiwgImgiLCAiX2NvbXB1dGVHcmlkTGluZUl0ZW1zIiwgImJvcmRlciIsICJ0bCIsICJib3JkZXJPcHRzIiwgImF4aXNXaWR0aCIsICJheGlzSGFsZldpZHRoIiwgImFsaWduQm9yZGVyVmFsdWUiLCAiYm9yZGVyVmFsdWUiLCAiYWxpZ25lZExpbmVWYWx1ZSIsICJ0eDEiLCAidHkxIiwgInR4MiIsICJ0eTIiLCAieDEiLCAieTEiLCAieDIiLCAieTIiLCAibGltaXQiLCAic3RlcCIsICJjb250ZXh0IiwgIm9wdHNBdEluZGV4IiwgIm9wdHNBdEluZGV4Qm9yZGVyIiwgImxpbmVXaWR0aCIsICJsaW5lQ29sb3IiLCAiY29sb3IiLCAiYm9yZGVyRGFzaCIsICJkYXNoIiwgImJvcmRlckRhc2hPZmZzZXQiLCAiZGFzaE9mZnNldCIsICJ0aWNrQ29sb3IiLCAidGlja0JvcmRlckRhc2giLCAidGlja0JvcmRlckRhc2hPZmZzZXQiLCAiY3Jvc3NBbGlnbiIsICJ0aWNrQW5kUGFkZGluZyIsICJoVGlja0FuZFBhZGRpbmciLCAidGV4dEFsaWduIiwgImxpbmVDb3VudCIsICJ0ZXh0T2Zmc2V0IiwgInRleHRCYXNlbGluZSIsICJfZ2V0WEF4aXNMYWJlbEFsaWdubWVudCIsICJfZ2V0WUF4aXNMYWJlbEFsaWdubWVudCIsICJsYWJlbE9mZnNldCIsICJoYWxmQ291bnQiLCAic3Ryb2tlQ29sb3IiLCAidGV4dFN0cm9rZUNvbG9yIiwgInN0cm9rZVdpZHRoIiwgInRleHRTdHJva2VXaWR0aCIsICJ0aWNrVGV4dEFsaWduIiwgInNob3dMYWJlbEJhY2tkcm9wIiwgImJhY2tkcm9wIiwgImxhYmVsUGFkZGluZyIsICJiYWNrZHJvcFBhZGRpbmciLCAiYmFja2Ryb3BDb2xvciIsICJ0cmFuc2xhdGlvbiIsICJfY29tcHV0ZUxhYmVsQXJlYSIsICJkcmF3QmFja2dyb3VuZCIsICJiYWNrZ3JvdW5kQ29sb3IiLCAic2F2ZSIsICJmaWxsU3R5bGUiLCAiZmlsbFJlY3QiLCAicmVzdG9yZSIsICJnZXRMaW5lV2lkdGhGb3JWYWx1ZSIsICJmaW5kSW5kZXgiLCAidCIsICJvcHRzIiwgImRyYXdHcmlkIiwgImRyYXdMaW5lIiwgInAxIiwgInAyIiwgInN0eWxlIiwgInN0cm9rZVN0eWxlIiwgInNldExpbmVEYXNoIiwgImxpbmVEYXNoT2Zmc2V0IiwgImJlZ2luUGF0aCIsICJtb3ZlVG8iLCAibGluZVRvIiwgInN0cm9rZSIsICJpdGVtIiwgImRyYXdPbkNoYXJ0QXJlYSIsICJkcmF3Qm9yZGVyIiwgImxhc3RMaW5lV2lkdGgiLCAiZHJhd0xhYmVscyIsICJhcmVhIiwgImNsaXBBcmVhIiwgInJlbmRlclRleHRPcHRpb25zIiwgInJlbmRlclRleHQiLCAidW5jbGlwQXJlYSIsICJkcmF3VGl0bGUiLCAiZHJhdyIsICJfbGF5ZXJzIiwgInR6IiwgInoiLCAiZ3oiLCAiYnoiLCAicHJvdG90eXBlIiwgImdldFNvcnRlZFZpc2libGVEYXRhc2V0TWV0YXMiLCAiYXhpc0lEIiwgIm1ldGEiLCAiX21heERpZ2l0cyIsICJmb250U2l6ZSIsICJnZW5lcmF0ZVRpY2tzIiwgImdlbmVyYXRpb25PcHRpb25zIiwgImRhdGFSYW5nZSIsICJ0aWNrcyIsICJNSU5fU1BBQ0lORyIsICJib3VuZHMiLCAic3RlcCIsICJtaW4iLCAibWF4IiwgInByZWNpc2lvbiIsICJjb3VudCIsICJtYXhUaWNrcyIsICJtYXhEaWdpdHMiLCAiaW5jbHVkZUJvdW5kcyIsICJ1bml0IiwgIm1heFNwYWNlcyIsICJybWluIiwgInJtYXgiLCAibWluRGVmaW5lZCIsICJpc051bGxPclVuZGVmIiwgIm1heERlZmluZWQiLCAiY291bnREZWZpbmVkIiwgIm1pblNwYWNpbmciLCAic3BhY2luZyIsICJuaWNlTnVtIiwgImZhY3RvciIsICJuaWNlTWluIiwgIm5pY2VNYXgiLCAibnVtU3BhY2VzIiwgInZhbHVlIiwgIk1hdGgiLCAiY2VpbCIsICJmbG9vciIsICJwb3ciLCAiYWxtb3N0V2hvbGUiLCAicm91bmQiLCAiYWxtb3N0RXF1YWxzIiwgImRlY2ltYWxQbGFjZXMiLCAiX2RlY2ltYWxQbGFjZXMiLCAiaiIsICJwdXNoIiwgInJlbGF0aXZlTGFiZWxTaXplIiwgInRpY2tWYWx1ZSIsICJsZW5ndGgiLCAiaG9yaXpvbnRhbCIsICJtaW5Sb3RhdGlvbiIsICJyYWQiLCAidG9SYWRpYW5zIiwgInJhdGlvIiwgInNpbiIsICJjb3MiLCAiTGluZWFyU2NhbGVCYXNlIiwgIlNjYWxlIiwgImNvbnN0cnVjdG9yIiwgImNmZyIsICJzdGFydCIsICJ1bmRlZmluZWQiLCAiZW5kIiwgIl9zdGFydFZhbHVlIiwgIl9lbmRWYWx1ZSIsICJfdmFsdWVSYW5nZSIsICJwYXJzZSIsICJyYXciLCAiaW5kZXgiLCAiTnVtYmVyIiwgImlzRmluaXRlIiwgImhhbmRsZVRpY2tSYW5nZU9wdGlvbnMiLCAiYmVnaW5BdFplcm8iLCAib3B0aW9ucyIsICJnZXRVc2VyQm91bmRzIiwgInNldE1pbiIsICJ2IiwgInNldE1heCIsICJtaW5TaWduIiwgInNpZ24iLCAibWF4U2lnbiIsICJvZmZzZXQiLCAiYWJzIiwgImdldFRpY2tMaW1pdCIsICJ0aWNrT3B0cyIsICJtYXhUaWNrc0xpbWl0IiwgInN0ZXBTaXplIiwgImNvbnNvbGUiLCAid2FybiIsICJpZCIsICJjb21wdXRlVGlja0xpbWl0IiwgIlBPU0lUSVZFX0lORklOSVRZIiwgImJ1aWxkVGlja3MiLCAib3B0cyIsICJudW1lcmljR2VuZXJhdG9yT3B0aW9ucyIsICJfbWF4RGlnaXRzIiwgImlzSG9yaXpvbnRhbCIsICJfcmFuZ2UiLCAiX3NldE1pbkFuZE1heEJ5S2V5IiwgInJldmVyc2UiLCAiY29uZmlndXJlIiwgImdldExhYmVsRm9yVmFsdWUiLCAiZm9ybWF0TnVtYmVyIiwgImNoYXJ0IiwgImxvY2FsZSIsICJmb3JtYXQiLCAiTGluZWFyU2NhbGUiLCAiZGV0ZXJtaW5lRGF0YUxpbWl0cyIsICJnZXRNaW5NYXgiLCAid2lkdGgiLCAiaGVpZ2h0IiwgInRpY2tGb250IiwgIl9yZXNvbHZlVGlja0ZvbnRPcHRpb25zIiwgImxpbmVIZWlnaHQiLCAiZ2V0UGl4ZWxGb3JWYWx1ZSIsICJOYU4iLCAiZ2V0UGl4ZWxGb3JEZWNpbWFsIiwgImdldFZhbHVlRm9yUGl4ZWwiLCAicGl4ZWwiLCAiZ2V0RGVjaW1hbEZvclBpeGVsIiwgImRlZmF1bHRzIiwgImNhbGxiYWNrIiwgIlRpY2tzIiwgImZvcm1hdHRlcnMiLCAibnVtZXJpYyIsICJsb2cxMEZsb29yIiwgImxvZzEwIiwgImNoYW5nZUV4cG9uZW50IiwgIm0iLCAiaXNNYWpvciIsICJ0aWNrVmFsIiwgInJlbWFpbiIsICJzdGVwcyIsICJyYW5nZUV4cCIsICJyYW5nZVN0ZXAiLCAic3RhcnRFeHAiLCAicmFuZ2UiLCAiZmluaXRlT3JEZWZhdWx0IiwgIm1pbkV4cCIsICJleHAiLCAiYmFzZSIsICJzaWduaWZpY2FuZCIsICJtYWpvciIsICJsYXN0VGljayIsICJMb2dhcml0aG1pY1NjYWxlIiwgInByb3RvdHlwZSIsICJhcHBseSIsICJfemVybyIsICJfc3VnZ2VzdGVkTWluIiwgIl91c2VyTWluIiwgIl91c2VyTWF4IiwgImlzTmFOIiwgImRlY2ltYWwiLCAibG9nYXJpdGhtaWMiLCAiZW5hYmxlZCIsICJnZXRUaWNrQmFja2Ryb3BIZWlnaHQiLCAiZGlzcGxheSIsICJwYWRkaW5nIiwgInRvUGFkZGluZyIsICJiYWNrZHJvcFBhZGRpbmciLCAidmFsdWVPckRlZmF1bHQiLCAiZm9udCIsICJzaXplIiwgIm1lYXN1cmVMYWJlbFNpemUiLCAiY3R4IiwgImxhYmVsIiwgImlzQXJyYXkiLCAidyIsICJfbG9uZ2VzdFRleHQiLCAic3RyaW5nIiwgImgiLCAiZGV0ZXJtaW5lTGltaXRzIiwgImFuZ2xlIiwgInBvcyIsICJmaXRXaXRoUG9pbnRMYWJlbHMiLCAic2NhbGUiLCAib3JpZyIsICJsIiwgImxlZnQiLCAiX3BhZGRpbmciLCAiciIsICJyaWdodCIsICJ0IiwgInRvcCIsICJiIiwgImJvdHRvbSIsICJsaW1pdHMiLCAiT2JqZWN0IiwgImFzc2lnbiIsICJsYWJlbFNpemVzIiwgInZhbHVlQ291bnQiLCAiX3BvaW50TGFiZWxzIiwgInBvaW50TGFiZWxPcHRzIiwgInBvaW50TGFiZWxzIiwgImFkZGl0aW9uYWxBbmdsZSIsICJjZW50ZXJQb2ludExhYmVscyIsICJQSSIsICJpIiwgInNldENvbnRleHQiLCAiZ2V0UG9pbnRMYWJlbENvbnRleHQiLCAicG9pbnRQb3NpdGlvbiIsICJnZXRQb2ludFBvc2l0aW9uIiwgImRyYXdpbmdBcmVhIiwgInBsRm9udCIsICJ0b0ZvbnQiLCAidGV4dFNpemUiLCAiYW5nbGVSYWRpYW5zIiwgIl9ub3JtYWxpemVBbmdsZSIsICJnZXRJbmRleEFuZ2xlIiwgInRvRGVncmVlcyIsICJoTGltaXRzIiwgIngiLCAidkxpbWl0cyIsICJ5IiwgInVwZGF0ZUxpbWl0cyIsICJzZXRDZW50ZXJQb2ludCIsICJfcG9pbnRMYWJlbEl0ZW1zIiwgImJ1aWxkUG9pbnRMYWJlbEl0ZW1zIiwgImNyZWF0ZVBvaW50TGFiZWxJdGVtIiwgIml0ZW1PcHRzIiwgIm91dGVyRGlzdGFuY2UiLCAiZXh0cmEiLCAicG9pbnRMYWJlbFBvc2l0aW9uIiwgIkhBTEZfUEkiLCAieUZvckFuZ2xlIiwgInRleHRBbGlnbiIsICJnZXRUZXh0QWxpZ25Gb3JBbmdsZSIsICJsZWZ0Rm9yVGV4dEFsaWduIiwgInZpc2libGUiLCAiaXNOb3RPdmVybGFwcGVkIiwgIml0ZW0iLCAiYXJlYSIsICJhcGV4ZXNJbkFyZWEiLCAiX2lzUG9pbnRJbkFyZWEiLCAiaXRlbXMiLCAiYWxpZ24iLCAiZHJhd1BvaW50TGFiZWxCb3giLCAiYmFja2Ryb3BDb2xvciIsICJib3JkZXJSYWRpdXMiLCAidG9UUkJMQ29ybmVycyIsICJmaWxsU3R5bGUiLCAiYmFja2Ryb3BMZWZ0IiwgImJhY2tkcm9wVG9wIiwgImJhY2tkcm9wV2lkdGgiLCAiYmFja2Ryb3BIZWlnaHQiLCAidmFsdWVzIiwgInNvbWUiLCAiYmVnaW5QYXRoIiwgImFkZFJvdW5kZWRSZWN0UGF0aCIsICJyYWRpdXMiLCAiZmlsbCIsICJmaWxsUmVjdCIsICJkcmF3UG9pbnRMYWJlbHMiLCAibGFiZWxDb3VudCIsICJvcHRzQXRJbmRleCIsICJyZW5kZXJUZXh0IiwgImNvbG9yIiwgInRleHRCYXNlbGluZSIsICJwYXRoUmFkaXVzTGluZSIsICJjaXJjdWxhciIsICJhcmMiLCAieENlbnRlciIsICJ5Q2VudGVyIiwgIlRBVSIsICJtb3ZlVG8iLCAibGluZVRvIiwgImRyYXdSYWRpdXNMaW5lIiwgImdyaWRMaW5lT3B0cyIsICJib3JkZXJPcHRzIiwgImxpbmVXaWR0aCIsICJzYXZlIiwgInN0cm9rZVN0eWxlIiwgInNldExpbmVEYXNoIiwgImRhc2giLCAibGluZURhc2hPZmZzZXQiLCAiZGFzaE9mZnNldCIsICJjbG9zZVBhdGgiLCAic3Ryb2tlIiwgInJlc3RvcmUiLCAiY3JlYXRlUG9pbnRMYWJlbENvbnRleHQiLCAicGFyZW50IiwgImNyZWF0ZUNvbnRleHQiLCAidHlwZSIsICJSYWRpYWxMaW5lYXJTY2FsZSIsICJzZXREaW1lbnNpb25zIiwgIm1heFdpZHRoIiwgIm1heEhlaWdodCIsICJnZW5lcmF0ZVRpY2tMYWJlbHMiLCAiY2FsbCIsICJnZXRMYWJlbHMiLCAibWFwIiwgImNhbGxDYWxsYmFjayIsICJmaWx0ZXIiLCAiZ2V0RGF0YVZpc2liaWxpdHkiLCAiZml0IiwgImxlZnRNb3ZlbWVudCIsICJyaWdodE1vdmVtZW50IiwgInRvcE1vdmVtZW50IiwgImJvdHRvbU1vdmVtZW50IiwgImFuZ2xlTXVsdGlwbGllciIsICJzdGFydEFuZ2xlIiwgImdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlIiwgInNjYWxpbmdGYWN0b3IiLCAiZ2V0VmFsdWVGb3JEaXN0YW5jZUZyb21DZW50ZXIiLCAiZGlzdGFuY2UiLCAic2NhbGVkRGlzdGFuY2UiLCAicG9pbnRMYWJlbCIsICJnZXRDb250ZXh0IiwgImRpc3RhbmNlRnJvbUNlbnRlciIsICJnZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUiLCAiZ2V0QmFzZVBvc2l0aW9uIiwgImdldEJhc2VWYWx1ZSIsICJnZXRQb2ludExhYmVsUG9zaXRpb24iLCAiZHJhd0JhY2tncm91bmQiLCAiYmFja2dyb3VuZENvbG9yIiwgImdyaWQiLCAiZHJhd0dyaWQiLCAiYW5nbGVMaW5lcyIsICJib3JkZXIiLCAicG9zaXRpb24iLCAiZm9yRWFjaCIsICJ0aWNrIiwgImNvbnRleHQiLCAib3B0c0F0SW5kZXhCb3JkZXIiLCAiYm9yZGVyRGFzaCIsICJib3JkZXJEYXNoT2Zmc2V0IiwgImRyYXdCb3JkZXIiLCAiZHJhd0xhYmVscyIsICJ0cmFuc2xhdGUiLCAicm90YXRlIiwgInNob3dMYWJlbEJhY2tkcm9wIiwgIm1lYXN1cmVUZXh0IiwgInN0cm9rZUNvbG9yIiwgInRleHRTdHJva2VDb2xvciIsICJzdHJva2VXaWR0aCIsICJ0ZXh0U3Ryb2tlV2lkdGgiLCAiZHJhd1RpdGxlIiwgImFuaW1hdGUiLCAiZGVmYXVsdFJvdXRlcyIsICJkZXNjcmlwdG9ycyIsICJfZmFsbGJhY2siLCAiSU5URVJWQUxTIiwgIm1pbGxpc2Vjb25kIiwgImNvbW1vbiIsICJzZWNvbmQiLCAibWludXRlIiwgImhvdXIiLCAiZGF5IiwgIndlZWsiLCAibW9udGgiLCAicXVhcnRlciIsICJ5ZWFyIiwgIlVOSVRTIiwgImtleXMiLCAic29ydGVyIiwgImEiLCAiaW5wdXQiLCAiYWRhcHRlciIsICJfYWRhcHRlciIsICJwYXJzZXIiLCAiaXNvV2Vla2RheSIsICJfcGFyc2VPcHRzIiwgImlzTnVtYmVyIiwgInN0YXJ0T2YiLCAiZGV0ZXJtaW5lVW5pdEZvckF1dG9UaWNrcyIsICJtaW5Vbml0IiwgImNhcGFjaXR5IiwgImlsZW4iLCAiaW5kZXhPZiIsICJpbnRlcnZhbCIsICJNQVhfU0FGRV9JTlRFR0VSIiwgImRldGVybWluZVVuaXRGb3JGb3JtYXR0aW5nIiwgIm51bVRpY2tzIiwgImRpZmYiLCAiZGV0ZXJtaW5lTWFqb3JVbml0IiwgImFkZFRpY2siLCAidGltZSIsICJ0aW1lc3RhbXBzIiwgImxvIiwgImhpIiwgIl9sb29rdXAiLCAidGltZXN0YW1wIiwgInNldE1ham9yVGlja3MiLCAibWFqb3JVbml0IiwgImZpcnN0IiwgImxhc3QiLCAiYWRkIiwgInRpY2tzRnJvbVRpbWVzdGFtcHMiLCAiVGltZVNjYWxlIiwgInByb3BzIiwgIl9jYWNoZSIsICJkYXRhIiwgImxhYmVscyIsICJhbGwiLCAiX3VuaXQiLCAiX21ham9yVW5pdCIsICJfb2Zmc2V0cyIsICJfbm9ybWFsaXplZCIsICJpbml0IiwgInNjYWxlT3B0cyIsICJhZGFwdGVycyIsICJfZGF0ZSIsICJkYXRlIiwgIm1lcmdlSWYiLCAiZGlzcGxheUZvcm1hdHMiLCAiZm9ybWF0cyIsICJub3JtYWxpemVkIiwgImJlZm9yZUxheW91dCIsICJfYXBwbHlCb3VuZHMiLCAiX2dldExhYmVsQm91bmRzIiwgInNvdXJjZSIsICJEYXRlIiwgIm5vdyIsICJlbmRPZiIsICJhcnIiLCAiZ2V0TGFiZWxUaW1lc3RhbXBzIiwgIk5FR0FUSVZFX0lORklOSVRZIiwgInRpbWVPcHRzIiwgIl9nZW5lcmF0ZSIsICJfZmlsdGVyQmV0d2VlbiIsICJhdXRvU2tpcCIsICJfZ2V0TGFiZWxDYXBhY2l0eSIsICJpbml0T2Zmc2V0cyIsICJhZnRlckF1dG9Ta2lwIiwgIm9mZnNldEFmdGVyQXV0b3NraXAiLCAiZ2V0RGVjaW1hbEZvclZhbHVlIiwgImxpbWl0IiwgIl9saW1pdFZhbHVlIiwgIm1pbm9yIiwgIndlZWtkYXkiLCAiaGFzV2Vla2RheSIsICJFcnJvciIsICJnZXREYXRhVGltZXN0YW1wcyIsICJzb3J0IiwgInRvb2x0aXBGb3JtYXQiLCAiZGF0ZXRpbWUiLCAiZm10IiwgIl90aWNrRm9ybWF0RnVuY3Rpb24iLCAiZm9ybWF0dGVyIiwgIm1pbm9yRm9ybWF0IiwgIm1ham9yRm9ybWF0IiwgIm9mZnNldHMiLCAiX2dldExhYmVsU2l6ZSIsICJ0aWNrc09wdHMiLCAidGlja0xhYmVsV2lkdGgiLCAibWF4Um90YXRpb24iLCAiY29zUm90YXRpb24iLCAic2luUm90YXRpb24iLCAidGlja0ZvbnRTaXplIiwgImV4YW1wbGVUaW1lIiwgImV4YW1wbGVMYWJlbCIsICJtZXRhcyIsICJnZXRNYXRjaGluZ1Zpc2libGVNZXRhcyIsICJjb250cm9sbGVyIiwgImdldEFsbFBhcnNlZFZhbHVlcyIsICJjb25jYXQiLCAibm9ybWFsaXplIiwgIl9hcnJheVVuaXF1ZSIsICJpbnRlcnBvbGF0ZSIsICJ0YWJsZSIsICJ2YWwiLCAicHJldlNvdXJjZSIsICJuZXh0U291cmNlIiwgInByZXZUYXJnZXQiLCAibmV4dFRhcmdldCIsICJfbG9va3VwQnlLZXkiLCAic3BhbiIsICJUaW1lU2VyaWVzU2NhbGUiLCAiX3RhYmxlIiwgIl9taW5Qb3MiLCAiX3RhYmxlUmFuZ2UiLCAiX2dldFRpbWVzdGFtcHNGb3JUYWJsZSIsICJidWlsZExvb2t1cFRhYmxlIiwgInByZXYiLCAiY3VyciIsICJuZXh0IiwgImluY2x1ZGVzIiwgInNwbGljZSIsICJzIiwgInNpbmdsZXRvbiIsICJvZmZzZXQiLCAicyIsICJkZWZhdWx0Wm9uZSIsICJvZmZzZXQiLCAiaXNOdW1iZXIiLCAibiIsICJpc051bWJlciIsICJuIiwgIm9mZnNldCIsICJzaWduIiwgInMiLCAibiIsICJmb3JtYXRPZmZzZXQiLCAicGFyc2UiLCAicyIsICJtYXRjaCIsICJvZmZzZXQiLCAiY2xvbmUiLCAiaXNOdW1iZXIiLCAibCIsICJuIiwgInMiLCAiZXEiLCAiSU5WQUxJRCIsICJzIiwgImUiLCAicyIsICJJTlZBTElEIiwgImNsb25lIiwgIm9mZnNldCIsICJvcmRlcmVkVW5pdHMiLCAicm91bmQiLCAiaXNOdW1iZXIiLCAiYWRhcHRlcnMiXQp9Cg== diff --git a/resources/js/components/feeder.js b/resources/js/components/feeder.js index e552a17..57d5d98 100644 --- a/resources/js/components/feeder.js +++ b/resources/js/components/feeder.js @@ -1,15 +1,22 @@ -export default function duckFeederWidget() { +import { Chart } from "chart.js/auto"; +import "chartjs-adapter-luxon"; + +export default function duckFeederWidget(data) { return { hungerLevel: 100, ducksMurdered: 0, audioPlayed: false, init() { + this.initChart(); + setInterval(() => { this.hungerLevel--; + if (this.hungerLevel < 0) { this.hungerLevel = 100; this.ducksMurdered++; } + this.updateChart(); }, 1000); // Prevent audio spam @@ -27,6 +34,34 @@ export default function duckFeederWidget() { if (this.hungerLevel > 100) { this.hungerLevel = 100; } + this.updateChart(); + }, + + initChart() { + + Chart.defaults.plugins.tooltip.enabled = false; + Chart.defaults.plugins.legend.display = false; + return new Chart(this.$refs.canvas, { + type: data.chart.type, + data: data.chart.cachedData, + options: data.chart.options, + }); + }, + updateChart() { + let chart = this.getChart() + chart.data = { + datasets:[{ + data: [this.hungerLevel, 100 - this.hungerLevel], + backgroundColor: [this.getStateColour(), "Gray"] + }] + } + chart.update('resize') + }, + getStateColour() { + return this.hungerLevel >=50 ? "Green": this.hungerLevel >= 15 ? "Orange": "Red"; + }, + getChart() { + return Chart.getChart(this.$refs.canvas); } } } diff --git a/resources/views/feeder-widget.blade.php b/resources/views/feeder-widget.blade.php index 1d23745..990e548 100644 --- a/resources/views/feeder-widget.blade.php +++ b/resources/views/feeder-widget.blade.php @@ -4,7 +4,13 @@ x-ignore ax-load ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('duckmode-feeder', 'sonjaturo/duckmode-filament') }}" - x-data="duckFeederWidget()" + x-data="duckFeederWidget({ + chart: { + cachedData: @js($this->getChartData()), + options: @js($this->getChartOptions()), + type: @js($this->getChartType()), + } + })" class="flex items-center gap-x-3" >
@@ -25,10 +31,10 @@ class="grid flex-1 text-base font-semibold leading-6 text-gray-950 dark:text-whi
-

- - - +
diff --git a/src/FeederWidget.php b/src/FeederWidget.php index fbb3e94..08f6919 100644 --- a/src/FeederWidget.php +++ b/src/FeederWidget.php @@ -12,10 +12,37 @@ class FeederWidget extends Widget public string $audioAsset = ''; + protected static ?array $options = [ + 'rotation'=> 270, // start angle in degrees + 'circumference' => 180, // sweep angle in degrees + 'height' => 60, + 'width' => 60, + ]; + public function __construct() { $this->audioAsset = filament('duckmode-filament') ->getAudioAssetsPath()."/{$this->assetName}.mp3"; } + protected function getChartData(): array + { + return [ + 'datasets' =>[[ + 'data'=> [100, 0], + 'backgroundColor'=> ["Green", "Gray"] + ]] + ]; + } + + protected function getChartOptions(): ?array + { + return static::$options; + } + + protected function getChartType(): string + { + return 'doughnut'; + } + } diff --git a/src/Livewire/HungerChart.php b/src/Livewire/HungerChart.php new file mode 100644 index 0000000..0f24082 --- /dev/null +++ b/src/Livewire/HungerChart.php @@ -0,0 +1,34 @@ + 270, // start angle in degrees + 'circumference' => 180, // sweep angle in degrees + 'height' => 60, + 'width' => 60, + ]; + + protected function getData(): array + { + return [ + 'labels' => ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], + 'datasets' =>[[ + 'label'=> '# of Votes', + 'data'=> [12, 19, 3, 5, 2, 3], + 'backgroundColor'=> ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"] + ]] + ]; + } + + protected function getType(): string + { + return 'doughnut'; + } +}