UNPKG

@dotglitch/ngx-common

Version:

Angular components and utilities that are commonly used.

209 lines 36 kB
import { Injectable } from '@angular/core'; import { ConsoleLogger, LogIcon } from '../utils'; import { CommandPaletteComponent } from '../components/command-palette/command-palette.component'; import * as i0 from "@angular/core"; import * as i1 from "@angular/material/dialog"; import * as i2 from "../components/lazy-loader/lazy-loader.service"; const { log, warn, err } = ConsoleLogger("CommandPalette", "#2196f3"); export class CommandPaletteService { constructor(dialog, lazyLoader) { this.dialog = dialog; this.lazyLoader = lazyLoader; this.commandBlocks = []; window.addEventListener("keydown", (evt) => this.onKeyDown(evt)); this.interval = setInterval(() => { // Go backwards since we're splicing items out of the array. for (let i = this.commandBlocks.length; i >= 0; i--) { let commandBlock = this.commandBlocks[i]; // If the current index is somehow null, rip it out of // the array and wait for cleanup to trigger again // for the rest of the array. // TODO: Could this lead to leaks where things at the end // never get cleaned? if (commandBlock == null) { this.commandBlocks.splice(i, 1); return; } // If the element has been disconnected from the DOM, we will // treat it as having been permanently removed. // TODO: Could this ever cause unintended consequences? if (!commandBlock?.element.isConnected) this.commandBlocks.splice(i, 1); } }, 5 * 60 * 1000); } ngOnDestroy() { clearInterval(this.interval); } getCommandBlocks(element = document.body) { const elementPath = [element]; let currentTarget = element; do { elementPath.unshift(currentTarget = currentTarget.parentElement); } while (currentTarget.parentElement); // Ordered matching command blocks, closest first const matchingCommandBlocks = []; for (const element of elementPath) { const commandBlock = this.commandBlocks.find(cb => cb.element == element); if (commandBlock) { matchingCommandBlocks.unshift(commandBlock); } } return matchingCommandBlocks; } /** * Handle keydown events * * If an event has been removed from the DOM tree, we don't need * to explicitly remove the bindings, as they will never fire * * We periodically check and remove unconnected command blocks */ onKeyDown(evt) { const matchingCommandBlocks = this.getCommandBlocks(evt.target); // String in format `ctrl+alt+F`, `ctrl+F` etc. const key = [ evt.ctrlKey ? "ctrl" : undefined, evt.altKey ? "alt" : undefined, evt.shiftKey ? "shift" : undefined, evt.metaKey ? "meta" : undefined, evt.code.startsWith("Key") ? evt.key : evt.code ].filter(a => a).join('+').toLowerCase(); for (const commandBlock of matchingCommandBlocks) { const action = commandBlock.actions.find(a => { return Array.isArray(a.shortcutKey) ? a.shortcutKey.includes(key) : a.shortcutKey == key; }); if (action) { evt.stopPropagation(); evt.preventDefault(); this.invokeAction(action); // Execute the action and move on. return; } // Keep checking for matching actions } // If execution reaches this point, there were no matching actions on the // path of elements that were registered. } addCommand(element, action) { const commandBlock = this.commandBlocks.find(b => b.element == element) ?? (() => { const cb = { element, actions: [] }; this.commandBlocks.push(cb); return cb; })(); // This is likely a duplicate entry if (commandBlock.actions.find(a => a.shortcutKey && a.shortcutKey == action.shortcutKey)) { warn(`Inserting duplicate action on element`, { element, action }); } else { // log(LogIcon.circle_blue, `Inserted action`, action) } // Make the shortcut keys lowercase so case sensitivity doesn't scalp someone if (action.shortcutKey) { if (Array.isArray(action.shortcutKey)) action.shortcutKey = action.shortcutKey.map(k => k.toLowerCase()); else action.shortcutKey = action.shortcutKey.toLowerCase(); } commandBlock.actions.push(action); } removeCommand(element, action) { const commandBlock = this.commandBlocks.find(b => b.element == element) ?? { element, actions: [] }; const actionIndex = commandBlock?.actions.findIndex(a => typeof action == "string" ? a.shortcutKey == action : a == action); if (!commandBlock) { err(LogIcon.warning, `Cannot remove command: element does not have any commands registered`, { element, action }); } else if (actionIndex == -1) { warn(LogIcon.warning, `Cannot remove command: not present in list`, { element, action }); } else { commandBlock.actions.splice(actionIndex, 1); } } /** * */ initialize(options) { this.attachElementCommands([ { shortcutKey: options.keybind, action: () => this.openPalette(), description: "Open the command palette", keywords: ["command", "prompt", "console", "actions"], label: "Command Palette", visibleInList: false } ]); } /** * Open the command palette */ openPalette() { return this.dialog.open(CommandPaletteComponent, { position: { top: "8px" }, data: { contextElement: document.activeElement }, panelClass: ['ngx-command-palette'], backdropClass: ['ngx-command-palette'], restoreFocus: true, role: 'dialog' }); } /** * Public helper to invoke an action. */ invokeAction(action, args) { const fn = action.action; if (typeof fn == 'function') { try { const res = fn(args); // Handle promises so that the GUI can show spinners for them if (res instanceof Promise) { // TODO } else { // TODO } } catch (ex) { err(LogIcon.bomb, `Executing action threw an error`, { action }, ex); } } else { warn(LogIcon.warning, `Cannot execute action, type is not "function"`, { action }); } } attachElementCommands(element = document.body, actions = []) { if (Array.isArray(element)) { actions = element; element = document.body; } actions.forEach(a => this.addCommand(element, a)); } /** * Detach specified commands from an Element subtree */ detachElementCommands(element = document.body, actions = []) { actions.forEach(a => this.removeCommand(element, a)); } /** * Return the list of registered commands under a given element */ getRegisteredCommands(element = document.body) { return this.getCommandBlocks(element).map(c => c.actions).flat(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CommandPaletteService, deps: [{ token: i1.MatDialog }, { token: i2.LazyLoaderService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CommandPaletteService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CommandPaletteService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.MatDialog }, { type: i2.LazyLoaderService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC1wYWxldHRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21tb24vc3JjL3NlcnZpY2VzL2NvbW1hbmQtcGFsZXR0ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQWlDLE1BQU0sZUFBZSxDQUFDO0FBRTFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRWxELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHlEQUF5RCxDQUFDOzs7O0FBRWxHLE1BQU0sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsQ0FBQztBQWtKdEUsTUFBTSxPQUFPLHFCQUFxQjtJQUs5QixZQUNxQixNQUFpQixFQUNqQixVQUE2QjtRQUQ3QixXQUFNLEdBQU4sTUFBTSxDQUFXO1FBQ2pCLGVBQVUsR0FBVixVQUFVLENBQW1CO1FBTDFDLGtCQUFhLEdBQW1CLEVBQUUsQ0FBQztRQU92QyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFakUsSUFBSSxDQUFDLFFBQVEsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1lBQzdCLDREQUE0RDtZQUM1RCxLQUFLLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDbEQsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFekMsc0RBQXNEO2dCQUN0RCxrREFBa0Q7Z0JBQ2xELDZCQUE2QjtnQkFDN0IseURB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QU8sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JFLENBQUM7OEdBck9RLHFCQUFxQjtrSEFBckIscUJBQXFCLGNBRmxCLE1BQU07OzJGQUVULHFCQUFxQjtrQkFIakMsVUFBVTttQkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBIb3N0TGlzdGVuZXIsIFR5cGUsIGlzRGV2TW9kZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IENvbnNvbGVMb2dnZXIsIExvZ0ljb24gfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgeyBMYXp5TG9hZGVyU2VydmljZSB9IGZyb20gJy4uL2NvbXBvbmVudHMvbGF6eS1sb2FkZXIvbGF6eS1sb2FkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBDb21tYW5kUGFsZXR0ZUNvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudHMvY29tbWFuZC1wYWxldHRlL2NvbW1hbmQtcGFsZXR0ZS5jb21wb25lbnQnO1xuXG5jb25zdCB7IGxvZywgd2FybiwgZXJyIH0gPSBDb25zb2xlTG9nZ2VyKFwiQ29tbWFuZFBhbGV0dGVcIiwgXCIjMjE5NmYzXCIpO1xuXG50eXBlIEtleUNvZGUgPSBcIkJhY2tzcGFjZVwiIHwgXCJUYWJcIiB8IFwiRW50ZXJcIiB8IFwiU2hpZnRMZWZ0XCIgfCBcIlNoaWZ0UmlnaHRcIlxuICAgIHwgXCJDb250cm9sTGVmdFwiIHwgXCJDb250cm9sUmlnaHRcIiB8IFwiQWx0TGVmdFwiIHwgXCJBbHRSaWdodFwiIHwgXCJQYXVzZVwiIHwgXCJDYXBzTG9ja1wiXG4gICAgfCBcIkVzY2FwZVwiIHwgXCJTcGFjZVwiIHwgXCJQYWdlVXBcIiB8IFwiUGFnZURvd25cIiB8IFwiRW5kXCIgfCBcIkhvbWVcIiB8IFwiQXJyb3dMZWZ0XCJcbiAgICB8IFwiQXJyb3dVcFwiIHwgXCJBcnJvd1JpZ2h0XCIgfCBcIkFycm93RG93blwiIHwgXCJQcmludFNjcmVlblwiIHwgXCJJbnNlcnRcIiB8IFwiRGVsZXRlXCJcbiAgICB8IFwiTWV0YUxlZnRcIiB8IFwiTWV0YVJpZ2h0XCIgfCBcIkNvbnRleHRNZW51XCIgfCBcIk51bXBhZDBcIiB8IFwiTnVtcGFkMVwiIHwgXCJOdW1wYWQyXCJcbiAgICB8IFwiTnVtcGFkM1wiIHwgXCJOdW1wYWQ0XCIgfCBcIk51bXBhZDVcIiB8IFwiTnVtcGFkNlwiIHwgXCJOdW1wYWQ3XCIgfCBcIk51bXBhZDhcIlxuICAgIHwgXCJOdW1wYWQ5XCIgfCBcIk51bXBhZE11bHRpcGx5XCIgfCBcIk51bXBhZEFkZFwiIHwgXCJOdW1wYWRTdWJ0cmFjdFwiXG4gICAgfCBcIk51bXBhZERlY2ltYWxcIiB8IFwiTnVtcGFkRGl2aWRlXCJcbiAgICB8IFwiRjFcIiB8IFwiRjJcIiB8IFwiRjNcIiB8IFwiRjRcIiB8IFwiRjVcIiB8IFwiRjZcIiB8IFwiRjdcIiB8IFwiRjhcIiB8IFwiRjlcIiB8IFwiRjEwXCIgfCBcIkYxMVwiIHwgXCJGMTJcIlxuICAgIHwgXCJOdW1Mb2NrXCIgfCBcIlNjcm9sbExvY2tcIiB8IFwiU2VtaWNvbG9uXCIgfCBcIkVxdWFsXCIgfCBcIkNvbW1hXCIgfCBcIk1pbnVzXCJcbiAgICB8IFwiUGVyaW9kXCIgfCBcIlNsYXNoXCIgfCBcIkJhY2txdW90ZVwiIHwgXCJCcmFja2V0TGVmdFwiIHwgXCJCYWNrc2xhc2hcIlxuICAgIHwgXCJCcmFja2V0UmlnaHRcIiB8IFwiUXVvdGVcIiB8IFwiYmFja3NwYWNlXCIgfCBcInRhYlwiIHwgXCJlbnRlclwiIHwgXCJzaGlmdGxlZnRcIlxuICAgIHwgXCJzaGlmdHJpZ2h0XCIgfCBcImNvbnRyb2xsZWZ0XCIgfCBcImNvbnRyb2xyaWdodFwiIHwgXCJhbHRsZWZ0XCIgfCBcImFsdHJpZ2h0XCJcbiAgICB8IFwicGF1c2VcIiB8IFwiY2Fwc2xvY2tcIiB8IFwiZXNjYXBlXCIgfCBcInNwYWNlXCIgfCBcInBhZ2V1cFwiIHwgXCJwYWdlZG93blwiIHwgXCJlbmRcIlxuICAgIHwgXCJob21lXCIgfCBcImFycm93bGVmdFwiIHwgXCJhcnJvd3VwXCIgfCBcImFycm93cmlnaHRcIiB8IFwiYXJyb3dkb3duXCIgfCBcInByaW50c2NyZWVuXCJcbiAgICB8IFwiaW5zZXJ0XCIgfCBcImRlbGV0ZVwiIHwgXCJtZXRhbGVmdFwiIHwgXCJtZXRhcmlnaHRcIiB8IFwiY29udGV4dG1lbnVcIlxuICAgIHwgXCJudW1wYWQwXCIgfCBcIm51bXBhZDFcIiB8IFwibnVtcGFkMlwiIHwgXCJudW1wYWQzXCIgfCBcIm51bXBhZDRcIiB8IFwibnVtcGFkNVwiXG4gICAgfCBcIm51bXBhZDZcIiB8IFwibnVtcGFkN1wiIHwgXCJudW1wYWQ4XCIgfCBcIm51bXBhZDlcIiB8IFwibnVtcGFkbXVsdGlwbHlcIiB8IFwibnVtcGFkYWRkXCJcbiAgICB8IFwibnVtcGFkc3VidHJhY3RcIiB8IFwibnVtcGFkZGVjaW1hbFwiIHwgXCJudW1wYWRkaXZpZGVcIlxuICAgIHwgXCJmMVwiIHwgXCJmMlwiIHwgXCJmM1wiIHwgXCJmNFwiIHwgXCJmNVwiIHwgXCJmNlwiIHwgXCJmN1wiIHwgXCJmOFwiIHwgXCJmOVwiIHwgXCJmMTBcIiB8IFwiZjExXCIgfCBcImYxMlwiXG4gICAgfCBcIm51bWxvY2tcIiB8IFwic2Nyb2xsbG9ja1wiIHwgXCJzZW1pY29sb25cIiB8IFwiZXF1YWxcIiB8IFwiY29tbWFcIiB8IFwibWludXNcIiB8IFwicGVyaW9kXCJcbiAgICB8IFwic2xhc2hcIiB8IFwiYmFja3F1b3RlXCIgfCBcImJyYWNrZXRsZWZ0XCIgfCBcImJhY2tzbGFzaFwiIHwgXCJicmFja2V0cmlnaHRcIiB8IFwicXVvdGVcIlxuICAgIHwgXCJBXCIgfCBcIkJcIiB8IFwiQ1wiIHwgXCJEXCIgfCBcIkVcIiB8IFwiRlwiIHwgXCJHXCIgfCBcIkhcIiB8IFwiSVwiIHwgXCJKXCIgfCBcIktcIiB8IFwiTFwiIHwgXCJNXCJcbiAgICB8IFwiTlwiIHwgXCJPXCIgfCBcIlBcIiB8IFwiUVwiIHwgXCJSXCIgfCBcIlNcIiB8IFwiVFwiIHwgXCJVXCIgfCBcIlZcIiB8IFwiV1wiIHwgXCJYXCIgfCBcIllcIiB8IFwiWlwiXG4gICAgfCBcImFcIiB8IFwiYlwiIHwgXCJjXCIgfCBcImRcIiB8IFwiZVwiIHwgXCJmXCIgfCBcImdcIiB8IFwiaFwiIHwgXCJpXCIgfCBcImpcIiB8IFwia1wiIHwgXCJsXCIgfCBcIm1cIlxuICAgIHwgXCJuXCIgfCBcIm9cIiB8IFwicFwiIHwgXCJxXCIgfCBcInJcIiB8IFwic1wiIHwgXCJ0XCIgfCBcInVcIiB8IFwidlwiIHwgXCJ3XCIgfCBcInhcIiB8IFwieVwiIHwgXCJ6XCI7XG5cbi8vIGN0cmwrYWx0K21ldGErc2hpZnRcbnR5cGUgS2V5UHJlZml4ID1cbiAgICBgY3RybGAgfFxuICAgIGBjdHJsK2FsdGAgfFxuICAgIGBjdHJsK2FsdCtzaGlmdGAgfFxuICAgIGBjdHJsK2FsdCtzaGlmdCttZXRhYCB8XG4gICAgYGN0cmwrYWx0K21ldGFgIHxcbiAgICBgY3RybCtzaGlmdGAgfFxuICAgIGBjdHJsK3NoaWZ0K21ldGFgIHxcbiAgICBgY3RybCttZXRhYCB8XG4gICAgYGFsdGAgfFxuICAgIGBhbHQrc2hpZnRgIHxcbiAgICBgYWx0K3NoaWZ0K21ldGFgIHxcbiAgICBgYWx0K21ldGFgIHxcbiAgICBgc2hpZnRgIHxcbiAgICBgc2hpZnQrbWV0YWAgfFxuICAgIGBtZXRhYFxuXG5leHBvcnQgdHlwZSBLZXliaW5kRXZlbnQgPSAoZTogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZDtcbmV4cG9ydCB0eXBlIEtleWJpbmRDb2RlID0gYCR7S2V5UHJlZml4fSske0tleUNvZGV9YCB8IEtleUNvZGU7XG5cblxuXG5leHBvcnQgdHlwZSBDb21tYW5kQWN0aW9uPFQgPSBhbnk+ID0ge1xuICAgIC8qKlxuICAgICAqIFRoZSBub24tbW9kaWZpZXIga2V5KHMpIHRoYXQgbXVzdCBiZSBwcmVzc2VkIGZvciB0aGUgZXZlbnQgdG8gZmlyZS5cbiAgICAgKi9cbiAgICBzaG9ydGN1dEtleT86IEtleWJpbmRDb2RlIHwgS2V5YmluZENvZGVbXSxcblxuICAgIC8qKlxuICAgICAqIEFjdGlvbiB0aGF0IGlzIGludm9rZWQgd2hlbiB0aGUga2V5Ym9hcmQgc2hvcnRjdXQgaXMgcHJlc3NlZCBvciB0aGUgaXRlbVxuICAgICAqIGlzIGFjdGl2YXRlZCBpbiB0aGUgR1VJIG1lbnVcbiAgICAgKiBJZiB0aGUgR1VJIG1lbnUgaXMgb3BlbiwgaXQgd2lsbCBzaG93IGEgc3Bpbm5lciBpZiB0aGUgYWN0aW9uIHJldHVybnMgYSBgUHJvbWlzZWBcbiAgICAgKi9cbiAgICBhY3Rpb24/OiAoZXZ0OiBLZXlib2FyZEV2ZW50LCBkYXRhPzogVCkgPT4gUHJvbWlzZTxhbnk+IHwgYW55LFxuXG4gICAgLyoqXG4gICAgICogQXJiaXRyYXJ5IGRhdGEgb2JqZWN0IHRvIGJlIHBhc3NlZCBpbnRvIHRoZSBhY3Rpb25cbiAgICAgKi9cbiAgICBkYXRhPzogVCxcblxuICAgIC8qKlxuICAgICAqIExhYmVsIGluIHRoZSBjb21tYW5kIHBhbGV0dGUgcG9wdXBcbiAgICAgKi9cbiAgICBsYWJlbD86IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIEhpbnQgdGhhdCBmb2xsb3dzIHRoZSBsYWJlbCwgc3VidGx5XG4gICAgICovXG4gICAgaGludD86IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIEljb24gZm9yIHRoZSBlbnRyeVxuICAgICAqIENhbiBiZSBhIG1hdC1pY29uXG4gICAgICogV2lsbCBiZSBhIG1hdC1pY29uIGlmIHRoZSBzdHJpbmcgaXMgc2ltcGxlXG4gICAgICogSWYgdGhlIHN0cmluZyBjb250YWlucyBhIHNsYXNoIG9yIGNvbG9uLCBpdCB3aWxsIGJlIGxvYWRlZCBhc1xuICAgICAqIGFuIGltYWdlIHNvdXJjZVxuICAgICAqL1xuICAgIGljb24/OiBzdHJpbmcsXG5cbiAgICAvKipcbiAgICAgKiBLZXl3b3JkcyB0aGF0IGNhbiBoZWxwIHBpY2sgdGhpcyBjb21tYW5kXG4gICAgICovXG4gICAga2V5d29yZHM/OiBzdHJpbmcgfCBzdHJpbmdbXSxcblxuICAgIC8qKlxuICAgICAqIERlc2NyaXB0aW9uIGZvciB0aGUgcG9wdXBcbiAgICAgKiBXSVBcbiAgICAgKi9cbiAgICBkZXNjcmlwdGlvbj86IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIFRoZSByb290IGFuY2VzdG9yIGVsZW1lbnQgb2YgdGhlIGFjdGlvblxuICAgICAqIChUaGlzIGFsbG93cyBzY29waW5nIGNvbW1hbmRzIHRvIHNwZWNpZmljIEhUTUwgZWxlbWVudHMpXG4gICAgICogVGhpcyByZXF1aXJlcyB0aGF0IHRoZSBldmVudCB0YXJnZXQgbXVzdCBiZSBhIGRlc2NlbmRhbnRcbiAgICAgKlxuICAgICAqIElmIHRoZXJlIGFyZSBtdWx0aXBsZSBtYXRjaGluZyBkZXNjZW5kYW50cywgb25seVxuICAgICAqIHRoZSBmdXJ0aGVzdCBkZXNjZW5kYW50IHdpbGwgYmUgZmlyZWRcbiAgICAgKlxuICAgICAqIEZvciBjb21tYW5kIHNjb3BpbmcsIHdlIHJlYWQgdGhlIGRhdGEtbGFiZWwgYXR0cmlidXRlXG4gICAgICogQWx0ZXJuYXRpdmVseSwgeW91IGNhbiBzZXQgbGFiZWwgYW5kIGVsZW1lbnQgYXMgYW4gb2JqZWN0IGhlcmUuXG4gICAgICovXG4gICAgcm9vdEVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IHN0cmluZyB8IHtcbiAgICAgICAgZWxlbWVudDogSFRNTEVsZW1lbnQgfCBzdHJpbmcsXG4gICAgICAgIGxhYmVsOiBzdHJpbmdcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIGxhYmVsIGZvciB0aGUgcm9vdC4gVXNlZCBmb3IgdGhlIFVJIGNvbnRyb2wgYW5kIGRlYnVnZ2luZy5cbiAgICAgKi9cbiAgICByb290TmFtZT86IHN0cmluZyxcblxuICAgIC8qKlxuICAgICAqIENvbnRyb2wgd2hldGhlciB0aGlzIGNvbW1hbmQgYWN0aW9uIGlzIHZpc2libGUgaW4gdGhlIHBvcHVwIGNvbW1hbmRcbiAgICAgKiBwYWxldHRlIEdVSS5cbiAgICAgKi9cbiAgICB2aXNpYmxlSW5MaXN0PzogYm9vbGVhbixcblxuICAgIC8qKlxuICAgICAqIEVuYWJsZSBzZWxlY3RpbmcgYW4gaXRlbSB0byBzaG93IGEgbGlzdCBvZiBzdWItaXRlbXNcbiAgICAgKi9cbiAgICBzdWJNZW51PzogQ29tbWFuZEFjdGlvbjxUPltdIHwgKCgpID0+IFByb21pc2U8Q29tbWFuZEFjdGlvbjxUPltdPikgfCAoKCkgPT4gQ29tbWFuZEFjdGlvbjxUPltdKVxuXG59O1xuXG50eXBlIENvbW1hbmRCbG9jayA9IHtcbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICBhY3Rpb25zOiBDb21tYW5kQWN0aW9uW107XG59O1xuXG5leHBvcnQgdHlwZSBDb21tYW5kUGFsZXR0ZU9wdGlvbnMgPSB7XG4gICAga2V5YmluZDogS2V5YmluZENvZGVcbn1cblxuQEluamVjdGFibGUoe1xuICAgIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBDb21tYW5kUGFsZXR0ZVNlcnZpY2Uge1xuXG4gICAgcHJpdmF0ZSBjb21tYW5kQmxvY2tzOiBDb21tYW5kQmxvY2tbXSA9IFtdO1xuICAgIHByaXZhdGUgaW50ZXJ2YWw7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBkaWFsb2c6IE1hdERpYWxvZyxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBsYXp5TG9hZGVyOiBMYXp5TG9hZGVyU2VydmljZVxuICAgICkge1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwgKGV2dCkgPT4gdGhpcy5vbktleURvd24oZXZ0KSk7XG5cbiAgICAgICAgdGhpcy5pbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgIC8vIEdvIGJhY2t3YXJkcyBzaW5jZSB3ZSdyZSBzcGxpY2luZyBpdGVtcyBvdXQgb2YgdGhlIGFycmF5LlxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuY29tbWFuZEJsb2Nrcy5sZW5ndGg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNvbW1hbmRCbG9jayA9IHRoaXMuY29tbWFuZEJsb2Nrc1tpXTtcblxuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBjdXJyZW50IGluZGV4IGlzIHNvbWVob3cgbnVsbCwgcmlwIGl0IG91dCBvZlxuICAgICAgICAgICAgICAgIC8vIHRoZSBhcnJheSBhbmQgd2FpdCBmb3IgY2xlYW51cCB0byB0cmlnZ2VyIGFnYWluXG4gICAgICAgICAgICAgICAgLy8gZm9yIHRoZSByZXN0IG9mIHRoZSBhcnJheS5cbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBDb3VsZCB0aGlzIGxlYWQgdG8gbGVha3Mgd2hlcmUgdGhpbmdzIGF0IHRoZSBlbmRcbiAgICAgICAgICAgICAgICAvLyBuZXZlciBnZXQgY2xlYW5lZD9cbiAgICAgICAgICAgICAgICBpZiAoY29tbWFuZEJsb2NrID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21tYW5kQmxvY2tzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBlbGVtZW50IGhhcyBiZWVuIGRpc2Nvbm5lY3RlZCBmcm9tIHRoZSBET00sIHdlIHdpbGxcbiAgICAgICAgICAgICAgICAvLyB0cmVhdCBpdCBhcyBoYXZpbmcgYmVlbiBwZXJtYW5lbnRseSByZW1vdmVkLlxuICAgICAgICAgICAgICAgIC8vIFRPRE86IENvdWxkIHRoaXMgZXZlciBjYXVzZSB1bmludGVuZGVkIGNvbnNlcXVlbmNlcz9cbiAgICAgICAgICAgICAgICBpZiAoIWNvbW1hbmRCbG9jaz8uZWxlbWVudC5pc0Nvbm5lY3RlZClcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21tYW5kQmxvY2tzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgNSAqIDYwICogMTAwMCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmludGVydmFsKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbW1hbmRCbG9ja3MoZWxlbWVudDogSFRNTEVsZW1lbnQgPSBkb2N1bWVudC5ib2R5KSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRQYXRoOiBIVE1MRWxlbWVudFtdID0gW2VsZW1lbnRdO1xuICAgICAgICBsZXQgY3VycmVudFRhcmdldDogSFRNTEVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBlbGVtZW50UGF0aC51bnNoaWZ0KGN1cnJlbnRUYXJnZXQgPSBjdXJyZW50VGFyZ2V0LnBhcmVudEVsZW1lbnQpO1xuICAgICAgICB9IHdoaWxlIChjdXJyZW50VGFyZ2V0LnBhcmVudEVsZW1lbnQpO1xuXG4gICAgICAgIC8vIE9yZGVyZWQgbWF0Y2hpbmcgY29tbWFuZCBibG9ja3MsIGNsb3Nlc3QgZmlyc3RcbiAgICAgICAgY29uc3QgbWF0Y2hpbmdDb21tYW5kQmxvY2tzOiBDb21tYW5kQmxvY2tbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZWxlbWVudFBhdGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1hbmRCbG9jayA9IHRoaXMuY29tbWFuZEJsb2Nrcy5maW5kKGNiID0+IGNiLmVsZW1lbnQgPT0gZWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoY29tbWFuZEJsb2NrKSB7XG4gICAgICAgICAgICAgICAgbWF0Y2hpbmdDb21tYW5kQmxvY2tzLnVuc2hpZnQoY29tbWFuZEJsb2NrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtYXRjaGluZ0NvbW1hbmRCbG9ja3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlIGtleWRvd24gZXZlbnRzXG4gICAgICpcbiAgICAgKiBJZiBhbiBldmVudCBoYXMgYmVlbiByZW1vdmVkIGZyb20gdGhlIERPTSB0cmVlLCB3ZSBkb24ndCBuZWVkXG4gICAgICogdG8gZXhwbGljaXRseSByZW1vdmUgdGhlIGJpbmRpbmdzLCBhcyB0aGV5IHdpbGwgbmV2ZXIgZmlyZVxuICAgICAqXG4gICAgICogV2UgcGVyaW9kaWNhbGx5IGNoZWNrIGFuZCByZW1vdmUgdW5jb25uZWN0ZWQgY29tbWFuZCBibG9ja3NcbiAgICAgKi9cbiAgICBwcml2YXRlIG9uS2V5RG93bihldnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgY29uc3QgbWF0Y2hpbmdDb21tYW5kQmxvY2tzID0gdGhpcy5nZXRDb21tYW5kQmxvY2tzKGV2dC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpO1xuXG4gICAgICAgIC8vIFN0cmluZyBpbiBmb3JtYXQgYGN0cmwrYWx0K0ZgLCBgY3RybCtGYCBldGMuXG4gICAgICAgIGNvbnN0IGtleSA9IFtcbiAgICAgICAgICAgIGV2dC5jdHJsS2V5ID8gXCJjdHJsXCIgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBldnQuYWx0S2V5ID8gXCJhbHRcIiA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGV2dC5zaGlmdEtleSA/IFwic2hpZnRcIiA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGV2dC5tZXRhS2V5ID8gXCJtZXRhXCIgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBldnQuY29kZS5zdGFydHNXaXRoKFwiS2V5XCIpID8gZXZ0LmtleSA6IGV2dC5jb2RlXG4gICAgICAgIF0uZmlsdGVyKGEgPT4gYSkuam9pbignKycpLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgZm9yIChjb25zdCBjb21tYW5kQmxvY2sgb2YgbWF0Y2hpbmdDb21tYW5kQmxvY2tzKSB7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb24gPSBjb21tYW5kQmxvY2suYWN0aW9ucy5maW5kKGEgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBBcnJheS5pc0FycmF5KGEuc2hvcnRjdXRLZXkpXG4gICAgICAgICAgICAgICAgICAgID8gYS5zaG9ydGN1dEtleS5pbmNsdWRlcyhrZXkgYXMgYW55KVxuICAgICAgICAgICAgICAgICAgICA6IGEuc2hvcnRjdXRLZXkgPT0ga2V5IGFzIGFueVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChhY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmludm9rZUFjdGlvbihhY3Rpb24pO1xuXG4gICAgICAgICAgICAgICAgLy8gRXhlY3V0ZSB0aGUgYWN0aW9uIGFuZCBtb3ZlIG9uLlxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEtlZXAgY2hlY2tpbmcgZm9yIG1hdGNoaW5nIGFjdGlvbnNcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIGV4ZWN1dGlvbiByZWFjaGVzIHRoaXMgcG9pbnQsIHRoZXJlIHdlcmUgbm8gbWF0Y2hpbmcgYWN0aW9ucyBvbiB0aGVcbiAgICAgICAgLy8gcGF0aCBvZiBlbGVtZW50cyB0aGF0IHdlcmUgcmVnaXN0ZXJlZC5cbiAgICB9XG5cbiAgICBwcml2YXRlIGFkZENvbW1hbmQoZWxlbWVudDogSFRNTEVsZW1lbnQsIGFjdGlvbjogQ29tbWFuZEFjdGlvbikge1xuICAgICAgICBjb25zdCBjb21tYW5kQmxvY2sgPSB0aGlzLmNvbW1hbmRCbG9ja3MuZmluZChiID0+IGIuZWxlbWVudCA9PSBlbGVtZW50KSA/PyAoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2IgPSB7IGVsZW1lbnQsIGFjdGlvbnM6IFtdIH07XG4gICAgICAgICAgICB0aGlzLmNvbW1hbmRCbG9ja3MucHVzaChjYik7XG4gICAgICAgICAgICByZXR1cm4gY2I7XG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgLy8gVGhpcyBpcyBsaWtlbHkgYSBkdXBsaWNhdGUgZW50cnlcbiAgICAgICAgaWYgKGNvbW1hbmRCbG9jay5hY3Rpb25zLmZpbmQoYSA9PiBhLnNob3J0Y3V0S2V5ICYmIGEuc2hvcnRjdXRLZXkgPT0gYWN0aW9uLnNob3J0Y3V0S2V5KSkge1xuICAgICAgICAgICAgd2FybihgSW5zZXJ0aW5nIGR1cGxpY2F0ZSBhY3Rpb24gb24gZWxlbWVudGAsIHsgZWxlbWVudCwgYWN0aW9uIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gbG9nKExvZ0ljb24uY2lyY2xlX2JsdWUsIGBJbnNlcnRlZCBhY3Rpb25gLCBhY3Rpb24pXG4gICAgICAgIH1cblxuICAgICAgICAvLyBNYWtlIHRoZSBzaG9ydGN1dCBrZXlzIGxvd2VyY2FzZSBzbyBjYXNlIHNlbnNpdGl2aXR5IGRvZXNuJ3Qgc2NhbHAgc29tZW9uZVxuICAgICAgICBpZiAoYWN0aW9uLnNob3J0Y3V0S2V5KSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhY3Rpb24uc2hvcnRjdXRLZXkpKVxuICAgICAgICAgICAgICAgIGFjdGlvbi5zaG9ydGN1dEtleSA9IGFjdGlvbi5zaG9ydGN1dEtleS5tYXAoayA9PiBrLnRvTG93ZXJDYXNlKCkpIGFzIGFueTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBhY3Rpb24uc2hvcnRjdXRLZXkgPSBhY3Rpb24uc2hvcnRjdXRLZXkudG9Mb3dlckNhc2UoKSBhcyBhbnk7XG4gICAgICAgIH1cblxuICAgICAgICBjb21tYW5kQmxvY2suYWN0aW9ucy5wdXNoKGFjdGlvbik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW1vdmVDb21tYW5kKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBhY3Rpb246IENvbW1hbmRBY3Rpb24gfCBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgY29tbWFuZEJsb2NrID0gdGhpcy5jb21tYW5kQmxvY2tzLmZpbmQoYiA9PiBiLmVsZW1lbnQgPT0gZWxlbWVudCkgPz8geyBlbGVtZW50LCBhY3Rpb25zOiBbXSB9O1xuICAgICAgICBjb25zdCBhY3Rpb25JbmRleCA9IGNvbW1hbmRCbG9jaz8uYWN0aW9ucy5maW5kSW5kZXgoYSA9PiB0eXBlb2YgYWN0aW9uID09IFwic3RyaW5nXCIgPyBhLnNob3J0Y3V0S2V5ID09IGFjdGlvbiA6IGEgPT0gYWN0aW9uKTtcblxuICAgICAgICBpZiAoIWNvbW1hbmRCbG9jaykge1xuICAgICAgICAgICAgZXJyKExvZ0ljb24ud2FybmluZywgYENhbm5vdCByZW1vdmUgY29tbWFuZDogZWxlbWVudCBkb2VzIG5vdCBoYXZlIGFueSBjb21tYW5kcyByZWdpc3RlcmVkYCwgeyBlbGVtZW50LCBhY3Rpb24gfSlcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChhY3Rpb25JbmRleCA9PSAtMSkge1xuICAgICAgICAgICAgd2FybihMb2dJY29uLndhcm5pbmcsIGBDYW5ub3QgcmVtb3ZlIGNvbW1hbmQ6IG5vdCBwcmVzZW50IGluIGxpc3RgLCB7IGVsZW1lbnQsIGFjdGlvbiB9KVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29tbWFuZEJsb2NrLmFjdGlvbnMuc3BsaWNlKGFjdGlvbkluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZShvcHRpb25zOiBDb21tYW5kUGFsZXR0ZU9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5hdHRhY2hFbGVtZW50Q29tbWFuZHMoW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHNob3J0Y3V0S2V5OiBvcHRpb25zLmtleWJpbmQsXG4gICAgICAgICAgICAgICAgYWN0aW9uOiAoKSA9PiB0aGlzLm9wZW5QYWxldHRlKCksXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiT3BlbiB0aGUgY29tbWFuZCBwYWxldHRlXCIsXG4gICAgICAgICAgICAgICAga2V5d29yZHM6IFtcImNvbW1hbmRcIiwgXCJwcm9tcHRcIiwgXCJjb25zb2xlXCIsIFwiYWN0aW9uc1wiXSxcbiAgICAgICAgICAgICAgICBsYWJlbDogXCJDb21tYW5kIFBhbGV0dGVcIixcbiAgICAgICAgICAgICAgICB2aXNpYmxlSW5MaXN0OiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICBdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcGVuIHRoZSBjb21tYW5kIHBhbGV0dGVcbiAgICAgKi9cbiAgICBvcGVuUGFsZXR0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlhbG9nLm9wZW4oQ29tbWFuZFBhbGV0dGVDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgICAgICAgdG9wOiBcIjhweFwiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIGNvbnRleHRFbGVtZW50OiBkb2N1bWVudC5hY3RpdmVFbGVtZW50XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGFuZWxDbGFzczogWyduZ3gtY29tbWFuZC1wYWxldHRlJ10sXG4gICAgICAgICAgICBiYWNrZHJvcENsYXNzOiBbJ25neC1jb21tYW5kLXBhbGV0dGUnXSxcbiAgICAgICAgICAgIHJlc3RvcmVGb2N1czogdHJ1ZSxcbiAgICAgICAgICAgIHJvbGU6ICdkaWFsb2cnXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFB1YmxpYyBoZWxwZXIgdG8gaW52b2tlIGFuIGFjdGlvbi5cbiAgICAgKi9cbiAgICBpbnZva2VBY3Rpb24oYWN0aW9uOiBDb21tYW5kQWN0aW9uLCBhcmdzPykge1xuICAgICAgICBjb25zdCBmbiA9IGFjdGlvbi5hY3Rpb247XG4gICAgICAgIGlmICh0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJykge1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcyA9IGZuKGFyZ3MpO1xuXG4gICAgICAgICAgICAgICAgLy8gSGFuZGxlIHByb21pc2VzIHNvIHRoYXQgdGhlIEdVSSBjYW4gc2hvdyBzcGlubmVycyBmb3IgdGhlbVxuICAgICAgICAgICAgICAgIGlmIChyZXMgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgICAgICBlcnIoTG9nSWNvbi5ib21iLCBgRXhlY3V0aW5nIGFjdGlvbiB0aHJldyBhbiBlcnJvcmAsIHsgYWN0aW9uIH0sIGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHdhcm4oTG9nSWNvbi53YXJuaW5nLCBgQ2Fubm90IGV4ZWN1dGUgYWN0aW9uLCB0eXBlIGlzIG5vdCBcImZ1bmN0aW9uXCJgLCB7IGFjdGlvbiB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEF0dGFjaCBjb21tYW5kcyB0byBhbiBFbGVtZW50IGFuZCBpdCdzIHN1YnRyZWVcbiAgICAgKi9cbiAgICBhdHRhY2hFbGVtZW50Q29tbWFuZHMoYWN0aW9uczogQ29tbWFuZEFjdGlvbltdKVxuICAgIGF0dGFjaEVsZW1lbnRDb21tYW5kcyhlbGVtZW50OiBIVE1MRWxlbWVudCwgYWN0aW9uczogQ29tbWFuZEFjdGlvbltdKVxuICAgIGF0dGFjaEVsZW1lbnRDb21tYW5kcyhlbGVtZW50OiBDb21tYW5kQWN0aW9uW10gfCBIVE1MRWxlbWVudCA9IGRvY3VtZW50LmJvZHksIGFjdGlvbnM6IENvbW1hbmRBY3Rpb25bXSA9IFtdKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBhY3Rpb25zID0gZWxlbWVudDtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5ib2R5O1xuICAgICAgICB9XG5cbiAgICAgICAgYWN0aW9ucy5mb3JFYWNoKGEgPT4gdGhpcy5hZGRDb21tYW5kKGVsZW1lbnQgYXMgYW55LCBhKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0YWNoIHNwZWNpZmllZCBjb21tYW5kcyBmcm9tIGFuIEVsZW1lbnQgc3VidHJlZVxuICAgICAqL1xuICAgIGRldGFjaEVsZW1lbnRDb21tYW5kcyhlbGVtZW50OiBIVE1MRWxlbWVudCA9IGRvY3VtZW50LmJvZHksIGFjdGlvbnM6IENvbW1hbmRBY3Rpb25bXSA9IFtdKSB7XG4gICAgICAgIGFjdGlvbnMuZm9yRWFjaChhID0+IHRoaXMucmVtb3ZlQ29tbWFuZChlbGVtZW50LCBhKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBsaXN0IG9mIHJlZ2lzdGVyZWQgY29tbWFuZHMgdW5kZXIgYSBnaXZlbiBlbGVtZW50XG4gICAgICovXG4gICAgZ2V0UmVnaXN0ZXJlZENvbW1hbmRzKGVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gZG9jdW1lbnQuYm9keSkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDb21tYW5kQmxvY2tzKGVsZW1lbnQpLm1hcChjID0+IGMuYWN0aW9ucykuZmxhdCgpO1xuICAgIH1cbn1cbiJdfQ==