UNPKG

@nova-ui/bits

Version:

SolarWinds Nova Framework

330 lines (328 loc) 43.5 kB
// © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import { DOCUMENT, isPlatformBrowser } from "@angular/common"; import { Inject, Injectable, PLATFORM_ID } from "@angular/core"; import forOwn from "lodash/forOwn"; import includes from "lodash/includes"; import isBoolean from "lodash/isBoolean"; import isDate from "lodash/isDate"; import isFunction from "lodash/isFunction"; import isNil from "lodash/isNil"; import isNumber from "lodash/isNumber"; import isObject from "lodash/isObject"; import isString from "lodash/isString"; import * as i0 from "@angular/core"; /** @ignore */ var ByteCount; (function (ByteCount) { ByteCount[ByteCount["String"] = 2] = "String"; ByteCount[ByteCount["Boolean"] = 4] = "Boolean"; ByteCount[ByteCount["Number"] = 8] = "Number"; })(ByteCount || (ByteCount = {})); /** @ignore */ export var BrowserName; (function (BrowserName) { BrowserName["Chrome"] = "Chrome"; BrowserName["Edge"] = "Edge"; BrowserName["Firefox"] = "Firefox"; BrowserName["Opera"] = "Opera"; BrowserName["Safari"] = "Safari"; })(BrowserName || (BrowserName = {})); /** * Service providing common utilities */ /** * @dynamic * @ignore */ export class UtilService { static getSvgFromString(s) { const div = document.createElementNS("http://www.w3.org/1999/xhtml", "div"); div.innerHTML = `<svg xmlns='http://www.w3.org/2000/svg'>${s}</svg>`; const frag = document.createDocumentFragment(); while (div.firstChild?.firstChild) { frag.appendChild(div.firstChild.firstChild); } return frag; } static getEventPath(event) { if (isFunction(event.composedPath)) { return event.composedPath(); } let element = event.target; // Hack for EDGE if (!element.path) { element = event.currentTarget; } const path = []; while (element) { path.push(element); if (element.tagName === "HTML") { path.push(document); path.push(window); return path; } element = element.parentElement; } return []; } isBrowser() { return isPlatformBrowser(this.platformId); } /** * Object for getting information about the browser */ get browser() { if (this.isBrowser()) { return { name: () => this.browserName, version: () => this.getBrowserVersion(), isChrome: () => this.browserName === BrowserName.Chrome, isEdge: () => this.browserName === BrowserName.Edge, isFirefox: () => this.browserName === BrowserName.Firefox, isOpera: () => this.browserName === BrowserName.Opera, isSafari: () => this.browserName === BrowserName.Safari, mobileDevice: { isAndroid: () => this.document.defaultView?.navigator.userAgent.match(/Android/i) !== null, isBlackberry: () => this.document.defaultView?.navigator.userAgent.match(/BlackBerry|BB10/i) !== null, isIOS: () => this.document.defaultView?.navigator.userAgent.match(/iPhone|iPad|iPod/i) !== null, isOpera: () => this.document.defaultView?.navigator.userAgent.match(/Opera Mini/i) !== null, isAny: () => !!(this.browser?.mobileDevice.isIOS() || this.browser?.mobileDevice.isAndroid() || this.browser?.mobileDevice.isBlackberry() || this.browser?.mobileDevice.isOpera()), }, }; } } constructor(document, platformId) { this.document = document; this.platformId = platformId; this.nextUniqueId = ["0", "0", "0"]; /** * Returns the approximate memory footprint (byte count) of the object specified */ this.sizeof = (object) => { const visitedObjects = []; return this.calculateSizeof(object, visitedObjects); }; this.calculateSizeof = (object, visitedObjects) => { if (isString(object)) { return object.length * ByteCount.String; } else if (isBoolean(object)) { return ByteCount.Boolean; } else if (isNumber(object)) { return ByteCount.Number; } else if (isObject(object)) { visitedObjects.push(object); let bytes = 0; forOwn(object, (value, key) => { bytes += this.calculateSizeof(key, visitedObjects); // short-circuit circular refs if (!includes(visitedObjects, value)) { bytes += this.calculateSizeof(value, visitedObjects); } }); return bytes; } else { return 0; } }; this.browserName = this.getBrowser(); } /** * Formats the target string in the same way as .NET's String.format * @param target the target string * @param params one or more numbers, booleans, or strings to insert * into the target string at the specified location(s) * @returns the formatted string */ formatString(target, ...params) { const toString = (obj, format) => { const ctor = ((o) => { if (typeof o === "number") { return Number; } else if (typeof o === "boolean") { return Boolean; } else if (typeof o === "string") { return String; } else { return o.constructor; } })(obj); const proto = ctor.prototype; const formatter = typeof obj !== "string" ? proto ? proto.format || proto.toString : obj.format || obj.toString : obj.toString; if (formatter) { if (typeof format === "undefined" || format === "") { return formatter.call(obj); } else { return formatter.call(obj, format); } } else { return ""; } }; target = target.replace(/\{\{|\}\}|\{([^}: ]+?)(?::([^}]*?))?\}/g, (match, num, format) => { if (match === "{{") { return "{"; } if (match === "}}") { return "}"; } if (typeof params[num] !== "undefined" && params[num] !== null) { return toString(params[num], format); } else { return ""; } }); return target; } getBrowser() { if (isPlatformBrowser(this.platformId)) { const ua = this.document.defaultView?.navigator.userAgent; if (isNil(ua)) { throw new Error("UserAgent is not available"); } let tem; let M = ua.match(/(edge|opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if (M[1] === "Chrome") { tem = ua.match(/\bOPR\/(\d+)/); if (tem != null) { return BrowserName.Opera; } tem = ua.match(/\bEdge\/(\d+)/); if (tem != null) { return BrowserName.Edge; } } M = ((M[2] ? [M[1], M[2]] : [ this.document.defaultView?.navigator.appName, this.document.defaultView?.navigator.appVersion, "-?", ])); if ((tem = ua.match(/version\/(\d+)/i)) != null) { M.splice(1, 1, tem[1]); } return M[0]; } } getBrowserVersion() { if (isPlatformBrowser(this.platformId)) { const ua = this.document.defaultView?.navigator.userAgent; if (isNil(ua)) { throw new Error("UserAgent is not available"); } let tem, M = ua.match(/(edge|opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if (/trident/i.test(M[1])) { tem = /\brv[ :]+(\d+)/g.exec(ua) || []; return tem[1] || ""; } if (M[1] === "Chrome") { tem = ua.match(/\bOPR\/(\d+)/); if (tem != null) { return tem[1]; } tem = ua.match(/\bEdge\/(\d+)/); if (tem != null) { return tem[1]; } } M = ((M[2] ? [M[1], M[2]] : [ this.document.defaultView?.navigator.appName, this.document.defaultView?.navigator.appVersion, "-?", ])); if ((tem = ua.match(/version\/(\d+)/i)) != null) { M.splice(1, 1, tem[1]); } return M[1]; } } /** * nextUid, from angular.js. * A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric * characters such as "012ABC". The reason why we are not using simply a number counter is that * the number string gets longer over time, and it can also overflow, where as the nextId * will grow much slower, it is a string, and it will never overflow. * */ nextUid() { let index = this.nextUniqueId.length; let digit; while (index) { index--; digit = this.nextUniqueId[index].charCodeAt(0); if (digit === 57 /* "9" */) { this.nextUniqueId[index] = "A"; return this.nextUniqueId.join(""); } if (digit === 90 /* "Z" */) { this.nextUniqueId[index] = "0"; } else { this.nextUniqueId[index] = String.fromCharCode(digit + 1); return this.nextUniqueId.join(""); } } this.nextUniqueId.unshift("0"); return this.nextUniqueId.join(""); } dateEquals(date1, date2) { if (isNil(date1) && isNil(date2)) { return date1 === date2; } if (!isDate(date1) || !isDate(date2)) { return false; } return date1?.valueOf() === date2?.valueOf(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UtilService, deps: [{ token: DOCUMENT }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UtilService, providedIn: "root" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UtilService, decorators: [{ type: Injectable, args: [{ providedIn: "root" }] }], ctorParameters: () => [{ type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlcnZpY2VzL3V0aWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5REFBeUQ7QUFDekQsRUFBRTtBQUNGLCtFQUErRTtBQUMvRSw0RUFBNEU7QUFDNUUsOEVBQThFO0FBQzlFLCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsNERBQTREO0FBQzVELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsdURBQXVEO0FBQ3ZELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsNEVBQTRFO0FBQzVFLCtFQUErRTtBQUMvRSwwRUFBMEU7QUFDMUUsaUZBQWlGO0FBQ2pGLDZFQUE2RTtBQUM3RSxpQkFBaUI7QUFFakIsT0FBTyxFQUFFLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlELE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRSxPQUFPLE1BQU0sTUFBTSxlQUFlLENBQUM7QUFDbkMsT0FBTyxRQUFRLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxTQUFTLE1BQU0sa0JBQWtCLENBQUM7QUFDekMsT0FBTyxNQUFNLE1BQU0sZUFBZSxDQUFDO0FBQ25DLE9BQU8sVUFBVSxNQUFNLG1CQUFtQixDQUFDO0FBQzNDLE9BQU8sS0FBSyxNQUFNLGNBQWMsQ0FBQztBQUNqQyxPQUFPLFFBQVEsTUFBTSxpQkFBaUIsQ0FBQztBQUN2QyxPQUFPLFFBQVEsTUFBTSxpQkFBaUIsQ0FBQztBQUN2QyxPQUFPLFFBQVEsTUFBTSxpQkFBaUIsQ0FBQzs7QUFFdkMsY0FBYztBQUNkLElBQUssU0FJSjtBQUpELFdBQUssU0FBUztJQUNWLDZDQUFVLENBQUE7SUFDViwrQ0FBVyxDQUFBO0lBQ1gsNkNBQVUsQ0FBQTtBQUNkLENBQUMsRUFKSSxTQUFTLEtBQVQsU0FBUyxRQUliO0FB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Q0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDbEMsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFFRCxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDakQsQ0FBQzsrR0E1VFEsV0FBVyxrQkEwRlIsUUFBUSxhQUNSLFdBQVc7bUhBM0ZkLFdBQVcsY0FERSxNQUFNOzs0RkFDbkIsV0FBVztrQkFEdkIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7OzBCQTJGekIsTUFBTTsyQkFBQyxRQUFROzswQkFDZixNQUFNOzJCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyIvLyDCqSAyMDIyIFNvbGFyV2luZHMgV29ybGR3aWRlLCBMTEMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4vLyAgZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vICByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Jcbi8vICBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHsgRE9DVU1FTlQsIGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBQTEFURk9STV9JRCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgZm9yT3duIGZyb20gXCJsb2Rhc2gvZm9yT3duXCI7XG5pbXBvcnQgaW5jbHVkZXMgZnJvbSBcImxvZGFzaC9pbmNsdWRlc1wiO1xuaW1wb3J0IGlzQm9vbGVhbiBmcm9tIFwibG9kYXNoL2lzQm9vbGVhblwiO1xuaW1wb3J0IGlzRGF0ZSBmcm9tIFwibG9kYXNoL2lzRGF0ZVwiO1xuaW1wb3J0IGlzRnVuY3Rpb24gZnJvbSBcImxvZGFzaC9pc0Z1bmN0aW9uXCI7XG5pbXBvcnQgaXNOaWwgZnJvbSBcImxvZGFzaC9pc05pbFwiO1xuaW1wb3J0IGlzTnVtYmVyIGZyb20gXCJsb2Rhc2gvaXNOdW1iZXJcIjtcbmltcG9ydCBpc09iamVjdCBmcm9tIFwibG9kYXNoL2lzT2JqZWN0XCI7XG5pbXBvcnQgaXNTdHJpbmcgZnJvbSBcImxvZGFzaC9pc1N0cmluZ1wiO1xuXG4vKiogQGlnbm9yZSAqL1xuZW51bSBCeXRlQ291bnQge1xuICAgIFN0cmluZyA9IDIsXG4gICAgQm9vbGVhbiA9IDQsXG4gICAgTnVtYmVyID0gOCxcbn1cblxuLyoqIEBpZ25vcmUgKi9cbmV4cG9ydCBlbnVtIEJyb3dzZXJOYW1lIHtcbiAgICBDaHJvbWUgPSBcIkNocm9tZVwiLFxuICAgIEVkZ2UgPSBcIkVkZ2VcIixcbiAgICBGaXJlZm94ID0gXCJGaXJlZm94XCIsXG4gICAgT3BlcmEgPSBcIk9wZXJhXCIsXG4gICAgU2FmYXJpID0gXCJTYWZhcmlcIixcbn1cblxuLyoqIEBpZ25vcmUgKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnJvd3NlckluZm8ge1xuICAgIG5hbWUoKTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIHZlcnNpb24oKTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlzQ2hyb21lKCk6IGJvb2xlYW47XG4gICAgaXNFZGdlKCk6IGJvb2xlYW47XG4gICAgaXNGaXJlZm94KCk6IGJvb2xlYW47XG4gICAgaXNPcGVyYSgpOiBib29sZWFuO1xuICAgIGlzU2FmYXJpKCk6IGJvb2xlYW47XG4gICAgbW9iaWxlRGV2aWNlOiB7XG4gICAgICAgIGlzQW5kcm9pZCgpOiBib29sZWFuO1xuICAgICAgICBpc0JsYWNrYmVycnkoKTogYm9vbGVhbjtcbiAgICAgICAgaXNJT1MoKTogYm9vbGVhbjtcbiAgICAgICAgaXNPcGVyYSgpOiBib29sZWFuO1xuICAgICAgICBpc0FueSgpOiBib29sZWFuO1xuICAgIH07XG59XG5cbi8qKlxuICogU2VydmljZSBwcm92aWRpbmcgY29tbW9uIHV0aWxpdGllc1xuICovXG5cbi8qKlxuICogQGR5bmFtaWNcbiAqIEBpZ25vcmVcbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiBcInJvb3RcIiB9KVxuZXhwb3J0IGNsYXNzIFV0aWxTZXJ2aWNlIHtcbiAgICBwdWJsaWMgc3RhdGljIGdldFN2Z0Zyb21TdHJpbmcoczogc3RyaW5nKTogRG9jdW1lbnRGcmFnbWVudCB7XG4gICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgIFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiLFxuICAgICAgICAgICAgXCJkaXZcIlxuICAgICAgICApO1xuICAgICAgICBkaXYuaW5uZXJIVE1MID0gYDxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJz4ke3N9PC9zdmc+YDtcbiAgICAgICAgY29uc3QgZnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgd2hpbGUgKGRpdi5maXJzdENoaWxkPy5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICBmcmFnLmFwcGVuZENoaWxkKGRpdi5maXJzdENoaWxkLmZpcnN0Q2hpbGQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmcmFnO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0RXZlbnRQYXRoKGV2ZW50OiBNb3VzZUV2ZW50KTogRXZlbnRUYXJnZXRbXSB7XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGV2ZW50LmNvbXBvc2VkUGF0aCkpIHtcbiAgICAgICAgICAgIHJldHVybiBldmVudC5jb21wb3NlZFBhdGgoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBlbGVtZW50OiBIVE1MRWxlbWVudCB8IG51bGwgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAgICAgLy8gSGFjayBmb3IgRURHRVxuICAgICAgICBpZiAoIShlbGVtZW50IGFzIGFueSkucGF0aCkge1xuICAgICAgICAgICAgZWxlbWVudCA9IGV2ZW50LmN1cnJlbnRUYXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXRoID0gW107XG4gICAgICAgIHdoaWxlIChlbGVtZW50KSB7XG4gICAgICAgICAgICBwYXRoLnB1c2goZWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoZWxlbWVudC50YWdOYW1lID09PSBcIkhUTUxcIikge1xuICAgICAgICAgICAgICAgIHBhdGgucHVzaChkb2N1bWVudCk7XG4gICAgICAgICAgICAgICAgcGF0aC5wdXNoKHdpbmRvdyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHByaXZhdGUgbmV4dFVuaXF1ZUlkID0gW1wiMFwiLCBcIjBcIiwgXCIwXCJdO1xuICAgIHByaXZhdGUgYnJvd3Nlck5hbWU/OiBzdHJpbmc7XG5cbiAgICBwdWJsaWMgaXNCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPYmplY3QgZm9yIGdldHRpbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGJyb3dzZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGJyb3dzZXIoKTogQnJvd3NlckluZm8gfCB1bmRlZmluZWQge1xuICAgICAgICBpZiAodGhpcy5pc0Jyb3dzZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBuYW1lOiAoKSA9PiB0aGlzLmJyb3dzZXJOYW1lLFxuICAgICAgICAgICAgICAgIHZlcnNpb246ICgpID0+IHRoaXMuZ2V0QnJvd3NlclZlcnNpb24oKSxcbiAgICAgICAgICAgICAgICBpc0Nocm9tZTogKCkgPT4gdGhpcy5icm93c2VyTmFtZSA9PT0gQnJvd3Nlck5hbWUuQ2hyb21lLFxuICAgICAgICAgICAgICAgIGlzRWRnZTogKCkgPT4gdGhpcy5icm93c2VyTmFtZSA9PT0gQnJvd3Nlck5hbWUuRWRnZSxcbiAgICAgICAgICAgICAgICBpc0ZpcmVmb3g6ICgpID0+IHRoaXMuYnJvd3Nlck5hbWUgPT09IEJyb3dzZXJOYW1lLkZpcmVmb3gsXG4gICAgICAgICAgICAgICAgaXNPcGVyYTogKCkgPT4gdGhpcy5icm93c2VyTmFtZSA9PT0gQnJvd3Nlck5hbWUuT3BlcmEsXG4gICAgICAgICAgICAgICAgaXNTYWZhcmk6ICgpID0+IHRoaXMuYnJvd3Nlck5hbWUgPT09IEJyb3dzZXJOYW1lLlNhZmFyaSxcbiAgICAgICAgICAgICAgICBtb2JpbGVEZXZpY2U6IHtcbiAgICAgICAgICAgICAgICAgICAgaXNBbmRyb2lkOiAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5kZWZhdWx0Vmlldz8ubmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvQW5kcm9pZC9pXG4gICAgICAgICAgICAgICAgICAgICAgICApICE9PSBudWxsLFxuICAgICAgICAgICAgICAgICAgICBpc0JsYWNrYmVycnk6ICgpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3Py5uYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC9CbGFja0JlcnJ5fEJCMTAvaVxuICAgICAgICAgICAgICAgICAgICAgICAgKSAhPT0gbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgaXNJT1M6ICgpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3Py5uYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC9pUGhvbmV8aVBhZHxpUG9kL2lcbiAgICAgICAgICAgICAgICAgICAgICAgICkgIT09IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGlzT3BlcmE6ICgpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3Py5uYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC9PcGVyYSBNaW5pL2lcbiAgICAgICAgICAgICAgICAgICAgICAgICkgIT09IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGlzQW55OiAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgISEoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5icm93c2VyPy5tb2JpbGVEZXZpY2UuaXNJT1MoKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnJvd3Nlcj8ubW9iaWxlRGV2aWNlLmlzQW5kcm9pZCgpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5icm93c2VyPy5tb2JpbGVEZXZpY2UuaXNCbGFja2JlcnJ5KCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJyb3dzZXI/Lm1vYmlsZURldmljZS5pc09wZXJhKClcbiAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2N1bWVudDogRG9jdW1lbnQsXG4gICAgICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogb2JqZWN0XG4gICAgKSB7XG4gICAgICAgIHRoaXMuYnJvd3Nlck5hbWUgPSB0aGlzLmdldEJyb3dzZXIoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JtYXRzIHRoZSB0YXJnZXQgc3RyaW5nIGluIHRoZSBzYW1lIHdheSBhcyAuTkVUJ3MgU3RyaW5nLmZvcm1hdFxuICAgICAqIEBwYXJhbSAgdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nXG4gICAgICogQHBhcmFtICBwYXJhbXMgb25lIG9yIG1vcmUgbnVtYmVycywgYm9vbGVhbnMsIG9yIHN0cmluZ3MgdG8gaW5zZXJ0XG4gICAgICogICAgIGludG8gdGhlIHRhcmdldCBzdHJpbmcgYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbihzKVxuICAgICAqIEByZXR1cm5zIHRoZSBmb3JtYXR0ZWQgc3RyaW5nXG4gICAgICovXG4gICAgcHVibGljIGZvcm1hdFN0cmluZyh0YXJnZXQ6IHN0cmluZywgLi4ucGFyYW1zOiBBcnJheTxhbnk+KTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgdG9TdHJpbmcgPSAob2JqOiBhbnksIGZvcm1hdDogYW55KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjdG9yID0gKChvOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG8gPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlcjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvID09PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gQm9vbGVhbjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG8uY29uc3RydWN0b3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkob2JqKTtcbiAgICAgICAgICAgIGNvbnN0IHByb3RvID0gY3Rvci5wcm90b3R5cGU7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZXIgPVxuICAgICAgICAgICAgICAgIHR5cGVvZiBvYmogIT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgPyBwcm90b1xuICAgICAgICAgICAgICAgICAgICAgICAgPyBwcm90by5mb3JtYXQgfHwgcHJvdG8udG9TdHJpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgIDogb2JqLmZvcm1hdCB8fCBvYmoudG9TdHJpbmdcbiAgICAgICAgICAgICAgICAgICAgOiBvYmoudG9TdHJpbmc7XG4gICAgICAgICAgICBpZiAoZm9ybWF0dGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmb3JtYXQgPT09IFwidW5kZWZpbmVkXCIgfHwgZm9ybWF0ID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXR0ZXIuY2FsbChvYmopO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXR0ZXIuY2FsbChvYmosIGZvcm1hdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0YXJnZXQgPSB0YXJnZXQucmVwbGFjZShcbiAgICAgICAgICAgIC9cXHtcXHt8XFx9XFx9fFxceyhbXn06IF0rPykoPzo6KFtefV0qPykpP1xcfS9nLFxuICAgICAgICAgICAgKG1hdGNoLCBudW0sIGZvcm1hdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCA9PT0gXCJ7e1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIntcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoID09PSBcIn19XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwifVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBwYXJhbXNbbnVtXSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgICBwYXJhbXNbbnVtXSAhPT0gbnVsbFxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdG9TdHJpbmcocGFyYW1zW251bV0sIGZvcm1hdCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRCcm93c2VyKCkge1xuICAgICAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgICAgICAgY29uc3QgdWEgPSB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3Py5uYXZpZ2F0b3IudXNlckFnZW50O1xuXG4gICAgICAgICAgICBpZiAoaXNOaWwodWEpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVXNlckFnZW50IGlzIG5vdCBhdmFpbGFibGVcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCB0ZW07XG4gICAgICAgICAgICBsZXQgTTogUmVnRXhwTWF0Y2hBcnJheSB8IFtdID1cbiAgICAgICAgICAgICAgICB1YS5tYXRjaChcbiAgICAgICAgICAgICAgICAgICAgLyhlZGdlfG9wZXJhfGNocm9tZXxzYWZhcml8ZmlyZWZveHxtc2llfHRyaWRlbnQoPz1cXC8pKVxcLz9cXHMqKFxcZCspL2lcbiAgICAgICAgICAgICAgICApIHx8IFtdO1xuICAgICAgICAgICAgaWYgKE1bMV0gPT09IFwiQ2hyb21lXCIpIHtcbiAgICAgICAgICAgICAgICB0ZW0gPSB1YS5tYXRjaCgvXFxiT1BSXFwvKFxcZCspLyk7XG4gICAgICAgICAgICAgICAgaWYgKHRlbSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBCcm93c2VyTmFtZS5PcGVyYTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGVtID0gdWEubWF0Y2goL1xcYkVkZ2VcXC8oXFxkKykvKTtcbiAgICAgICAgICAgICAgICBpZiAodGVtICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJyb3dzZXJOYW1lLkVkZ2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgTSA9IDxSZWdFeHBNYXRjaEFycmF5PihcbiAgICAgICAgICAgICAgICAoTVsyXVxuICAgICAgICAgICAgICAgICAgICA/IFtNWzFdLCBNWzJdXVxuICAgICAgICAgICAgICAgICAgICA6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5kZWZhdWx0Vmlldz8ubmF2aWdhdG9yLmFwcE5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXc/Lm5hdmlnYXRvci5hcHBWZXJzaW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBcIi0/XCIsXG4gICAgICAgICAgICAgICAgICAgICAgXSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoKHRlbSA9IHVhLm1hdGNoKC92ZXJzaW9uXFwvKFxcZCspL2kpKSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgTS5zcGxpY2UoMSwgMSwgdGVtWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBNWzBdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRCcm93c2VyVmVyc2lvbigpIHtcbiAgICAgICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHVhID0gdGhpcy5kb2N1bWVudC5kZWZhdWx0Vmlldz8ubmF2aWdhdG9yLnVzZXJBZ2VudDtcblxuICAgICAgICAgICAgaWYgKGlzTmlsKHVhKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVzZXJBZ2VudCBpcyBub3QgYXZhaWxhYmxlXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgdGVtLFxuICAgICAgICAgICAgICAgIE0gPVxuICAgICAgICAgICAgICAgICAgICB1YS5tYXRjaChcbiAgICAgICAgICAgICAgICAgICAgICAgIC8oZWRnZXxvcGVyYXxjaHJvbWV8c2FmYXJpfGZpcmVmb3h8bXNpZXx0cmlkZW50KD89XFwvKSlcXC8/XFxzKihcXGQrKS9pXG4gICAgICAgICAgICAgICAgICAgICkgfHwgW107XG4gICAgICAgICAgICBpZiAoL3RyaWRlbnQvaS50ZXN0KE1bMV0pKSB7XG4gICAgICAgICAgICAgICAgdGVtID0gL1xcYnJ2WyA6XSsoXFxkKykvZy5leGVjKHVhKSB8fCBbXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGVtWzFdIHx8IFwiXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoTVsxXSA9PT0gXCJDaHJvbWVcIikge1xuICAgICAgICAgICAgICAgIHRlbSA9IHVhLm1hdGNoKC9cXGJPUFJcXC8oXFxkKykvKTtcbiAgICAgICAgICAgICAgICBpZiAodGVtICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRlbVsxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGVtID0gdWEubWF0Y2goL1xcYkVkZ2VcXC8oXFxkKykvKTtcbiAgICAgICAgICAgICAgICBpZiAodGVtICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRlbVsxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBNID0gPFJlZ0V4cE1hdGNoQXJyYXk+KFxuICAgICAgICAgICAgICAgIChNWzJdXG4gICAgICAgICAgICAgICAgICAgID8gW01bMV0sIE1bMl1dXG4gICAgICAgICAgICAgICAgICAgIDogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3Py5uYXZpZ2F0b3IuYXBwTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5kZWZhdWx0Vmlldz8ubmF2aWdhdG9yLmFwcFZlcnNpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiLT9cIixcbiAgICAgICAgICAgICAgICAgICAgICBdKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICgodGVtID0gdWEubWF0Y2goL3ZlcnNpb25cXC8oXFxkKykvaSkpICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBNLnNwbGljZSgxLCAxLCB0ZW1bMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIE1bMV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBuZXh0VWlkLCBmcm9tIGFuZ3VsYXIuanMuXG4gICAgICogQSBjb25zaXN0ZW50IHdheSBvZiBjcmVhdGluZyB1bmlxdWUgSURzIGluIGFuZ3VsYXIuIFRoZSBJRCBpcyBhIHNlcXVlbmNlIG9mIGFscGhhIG51bWVyaWNcbiAgICAgKiBjaGFyYWN0ZXJzIHN1Y2ggYXMgXCIwMTJBQkNcIi4gVGhlIHJlYXNvbiB3aHkgd2UgYXJlIG5vdCB1c2luZyBzaW1wbHkgYSBudW1iZXIgY291bnRlciBpcyB0aGF0XG4gICAgICogdGhlIG51bWJlciBzdHJpbmcgZ2V0cyBsb25nZXIgb3ZlciB0aW1lLCBhbmQgaXQgY2FuIGFsc28gb3ZlcmZsb3csIHdoZXJlIGFzIHRoZSBuZXh0SWRcbiAgICAgKiB3aWxsIGdyb3cgbXVjaCBzbG93ZXIsIGl0IGlzIGEgc3RyaW5nLCBhbmQgaXQgd2lsbCBuZXZlciBvdmVyZmxvdy5cbiAgICAgKlxuXG4gICAgICovXG4gICAgcHVibGljIG5leHRVaWQoKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5uZXh0VW5pcXVlSWQubGVuZ3RoO1xuICAgICAgICBsZXQgZGlnaXQ6IG51bWJlcjtcblxuICAgICAgICB3aGlsZSAoaW5kZXgpIHtcbiAgICAgICAgICAgIGluZGV4LS07XG4gICAgICAgICAgICBkaWdpdCA9IHRoaXMubmV4dFVuaXF1ZUlkW2luZGV4XS5jaGFyQ29kZUF0KDApO1xuXG4gICAgICAgICAgICBpZiAoZGlnaXQgPT09IDU3IC8qIFwiOVwiICovKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5uZXh0VW5pcXVlSWRbaW5kZXhdID0gXCJBXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmV4dFVuaXF1ZUlkLmpvaW4oXCJcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGlnaXQgPT09IDkwIC8qIFwiWlwiICovKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5uZXh0VW5pcXVlSWRbaW5kZXhdID0gXCIwXCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubmV4dFVuaXF1ZUlkW2luZGV4XSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoZGlnaXQgKyAxKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZXh0VW5pcXVlSWQuam9pbihcIlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubmV4dFVuaXF1ZUlkLnVuc2hpZnQoXCIwXCIpO1xuICAgICAgICByZXR1cm4gdGhpcy5uZXh0VW5pcXVlSWQuam9pbihcIlwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBhcHByb3hpbWF0ZSBtZW1vcnkgZm9vdHByaW50IChieXRlIGNvdW50KSBvZiB0aGUgb2JqZWN0IHNwZWNpZmllZFxuXG4gICAgICovXG4gICAgcHVibGljIHNpemVvZiA9IChvYmplY3Q6IGFueSk6IG51bWJlciA9PiB7XG4gICAgICAgIGNvbnN0IHZpc2l0ZWRPYmplY3RzOiBhbnlbXSA9IFtdO1xuICAgICAgICByZXR1cm4gdGhpcy5jYWxjdWxhdGVTaXplb2Yob2JqZWN0LCB2aXNpdGVkT2JqZWN0cyk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgY2FsY3VsYXRlU2l6ZW9mID0gKG9iamVjdDogYW55LCB2aXNpdGVkT2JqZWN0czogYW55W10pOiBudW1iZXIgPT4ge1xuICAgICAgICBpZiAoaXNTdHJpbmcob2JqZWN0KSkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdC5sZW5ndGggKiBCeXRlQ291bnQuU3RyaW5nO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQm9vbGVhbihvYmplY3QpKSB7XG4gICAgICAgICAgICByZXR1cm4gQnl0ZUNvdW50LkJvb2xlYW47XG4gICAgICAgIH0gZWxzZSBpZiAoaXNOdW1iZXIob2JqZWN0KSkge1xuICAgICAgICAgICAgcmV0dXJuIEJ5dGVDb3VudC5OdW1iZXI7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICAgICAgdmlzaXRlZE9iamVjdHMucHVzaChvYmplY3QpO1xuICAgICAgICAgICAgbGV0IGJ5dGVzID0gMDtcblxuICAgICAgICAgICAgZm9yT3duKG9iamVjdCwgKHZhbHVlOiBhbnksIGtleTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgYnl0ZXMgKz0gdGhpcy5jYWxjdWxhdGVTaXplb2Yoa2V5LCB2aXNpdGVkT2JqZWN0cyk7XG4gICAgICAgICAgICAgICAgLy8gc2hvcnQtY2lyY3VpdCBjaXJjdWxhciByZWZzXG4gICAgICAgICAgICAgICAgaWYgKCFpbmNsdWRlcyh2aXNpdGVkT2JqZWN0cywgdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJ5dGVzICs9IHRoaXMuY2FsY3VsYXRlU2l6ZW9mKHZhbHVlLCB2aXNpdGVkT2JqZWN0cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiBieXRlcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHB1YmxpYyBkYXRlRXF1YWxzKGRhdGUxPzogRGF0ZSwgZGF0ZTI/OiBEYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChpc05pbChkYXRlMSkgJiYgaXNOaWwoZGF0ZTIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZTEgPT09IGRhdGUyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc0RhdGUoZGF0ZTEpIHx8ICFpc0RhdGUoZGF0ZTIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZGF0ZTE/LnZhbHVlT2YoKSA9PT0gZGF0ZTI/LnZhbHVlT2YoKTtcbiAgICB9XG59XG4iXX0=