UNPKG

@nova-ui/bits

Version:

SolarWinds Nova Framework

273 lines 38.7 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 { Injectable, Injector, SecurityContext } from "@angular/core"; import { DomSanitizer } from "@angular/platform-browser"; import _assign from "lodash/assign"; import _cloneDeep from "lodash/cloneDeep"; import _isArray from "lodash/isArray"; import _toInteger from "lodash/toInteger"; import { take } from "rxjs/operators"; import { ToastContainerService } from "./toast-container.service"; import { ToastInjector } from "./toast-injector"; import { ToastPackage } from "./toast-package"; import { ToastRef } from "./toast-ref"; import { ToastComponent } from "./toast.component"; import { SwitchState } from "../../services/notification-args"; import { NotificationService } from "../../services/notification-service"; import * as i0 from "@angular/core"; import * as i1 from "../../services/notification-service"; import * as i2 from "./toast-container.service"; import * as i3 from "@angular/platform-browser"; /** * __Name : __ * Toast Service * * __Usage :__ * Used to show toast messages and to trigger highlight of items */ /** * @ignore */ export class ToastService { constructor(notificationService, toastContainerService, _injector, sanitizer) { this.notificationService = notificationService; this.toastContainerService = toastContainerService; this._injector = _injector; this.sanitizer = sanitizer; this.index = 0; this.currentlyActive = 0; this.toasts = []; this.defaultToastConfig = { maxOpened: 0, autoDismiss: false, newestOnTop: true, preventDuplicates: false, positionClass: "nui-toast--top-right" /* ToastPositionClass.TOP_RIGHT */, progressAnimation: "decreasing", timeOut: 5000, progressBar: true, toastClass: "nui-toast", extendedTimeOut: 2000, closeButton: true, clickToDismiss: false, enableHtml: true, stickyError: false, }; this.notifyHighlights = (itemsToHighlight, status) => { if (itemsToHighlight) { this.notificationService.post("Highlight", { highlightState: SwitchState.on, status: status, items: itemsToHighlight, itemIdentificator: this.itemIdentificator, }); } }; this.toastConfig = _assign({}, this.defaultToastConfig); } /** * * __Description:__ set global config for all kind of toasts and itemIdentificator that is * used for identification of item in nuiToast directive * @param config * @param itemIdentificator * @return void */ setConfig(config, itemIdentificator) { _assign(this.toastConfig, config); this.itemIdentificator = itemIdentificator; } /** * * __Description:__ show success toast trigger highlight of items and trigger fade out of highlighting when * toast is gone * * @param toastDeclaration * @return void */ success(toastDeclaration) { const toastInstance = this.buildNotification("success", toastDeclaration.message, toastDeclaration.title, this.applyConfig(toastDeclaration.options)); this.notifyHighlights(toastDeclaration.itemsToHighlight, "success"); this.toastRemoveHighlight(toastInstance, toastDeclaration.itemsToHighlight); return toastInstance; } warning(toastDeclaration) { const toastInstance = this.buildNotification("warning", toastDeclaration.message, toastDeclaration.title, this.applyConfig(toastDeclaration.options)); this.notifyHighlights(toastDeclaration.itemsToHighlight, "warning"); this.toastRemoveHighlight(toastInstance, toastDeclaration.itemsToHighlight); return toastInstance; } error(toastDeclaration) { const config = _cloneDeep(toastDeclaration.options); if (toastDeclaration.options && toastDeclaration.options.stickyError && config) { config.timeOut = 0; config.extendedTimeOut = 0; config.progressBar = false; config.closeButton = false; } const toastInstance = this.buildNotification("error", toastDeclaration.message, toastDeclaration.title, this.applyConfig(config)); this.notifyHighlights(toastDeclaration.itemsToHighlight, "error"); this.toastRemoveHighlight(toastInstance, toastDeclaration.itemsToHighlight); return toastInstance; } info(toastDeclaration) { const toastInstance = this.buildNotification("info", toastDeclaration.message, toastDeclaration.title, this.applyConfig(toastDeclaration.options)); this.notifyHighlights(toastDeclaration.itemsToHighlight, "info"); this.toastRemoveHighlight(toastInstance, toastDeclaration.itemsToHighlight); return toastInstance; } /** * * __Description:__ calls toasts' close methods to close them * * @param toastId * @return void */ clear(toastId) { for (const toast of this.toasts) { if (toastId !== undefined) { if (toast.toastId === toastId) { toast.toastRef.manualClose(); return; } } else { toast.toastRef.manualClose(); } } } /** * * __Description:__ removes toast by id and activates next toast in queue (when maxOpened !== 0) * * @param toastId * @return boolean */ remove(toastId) { const toastInstance = this.findToast(toastId); if (!toastInstance) { return false; } toastInstance.activeToast.toastRef.close(); this.toasts.splice(toastInstance.index, 1); this.currentlyActive = this.currentlyActive - 1; if (!this.toastConfig.maxOpened || !this.toasts.length) { return false; } if (this.currentlyActive <= +this.toastConfig.maxOpened && this.toasts[this.currentlyActive]) { const activeToastRef = this.toasts[this.currentlyActive].toastRef; if (!activeToastRef.isInactive()) { this.currentlyActive = this.currentlyActive + 1; activeToastRef.activate(); } } return true; } toastRemoveHighlight(toastInstance, itemsToRemoveHighlight) { if (toastInstance) { toastInstance?.onHidden?.pipe(take(1)).subscribe(() => { if (_isArray(itemsToRemoveHighlight) && itemsToRemoveHighlight.length > 0) { this.notificationService.post("Highlight", { highlightState: SwitchState.off, items: itemsToRemoveHighlight, }); } }); } } applyConfig(override = {}) { const resultConfig = _assign({}, this.toastConfig, override); resultConfig.timeOut = _toInteger(resultConfig.timeOut); resultConfig.extendedTimeOut = _toInteger(resultConfig.extendedTimeOut); return resultConfig; } buildNotification(toastType, body, title, config) { // max opened and auto dismiss = true if (body && config.preventDuplicates && this.isDuplicate(body)) { // TODO: Update buildNotification return type in V10 in the scope of NUI-5824 // @ts-ignore: Suppressing error until v10 to prevent API breaking changes return null; } this.toastContainerService.getContainerElement(config.positionClass); let keepInactive = false; let sanitizedBody = body; if (this.toastConfig.maxOpened && this.currentlyActive >= this.toastConfig.maxOpened) { keepInactive = true; if (this.toastConfig.autoDismiss) { this.clear(this.toasts[this.toasts.length - 1].toastId); } } this.index = this.index + 1; if (body && config.enableHtml) { sanitizedBody = (this.sanitizer.sanitize(SecurityContext.HTML, body)); } const toastRef = new ToastRef(this.toastContainerService); const toastPackage = new ToastPackage(this.index, config, sanitizedBody, title, toastType, toastRef); const toastInjector = new ToastInjector(toastPackage, this._injector); toastRef.componentInstance = this.toastContainerService.attachToast(ToastComponent, toastInjector, !!config.newestOnTop); const toastInstance = { toastId: this.index, body: sanitizedBody, toastRef, onShown: toastRef.afterActivate(), onHidden: toastRef.afterClosed(), onClick: toastPackage.onClick(), }; if (!keepInactive) { setTimeout(() => { toastInstance.toastRef.activate(); this.currentlyActive = this.currentlyActive + 1; }); } this.toasts.push(toastInstance); return toastInstance; } /** * Determines if toast message is already shown */ isDuplicate(body) { for (let i = 0; i < this.toasts.length; i++) { if (this.toasts[i].body === body) { return true; } } return false; } findToast(toastId) { for (let i = 0; i < this.toasts.length; i++) { if (this.toasts[i].toastId === toastId) { return { index: i, activeToast: this.toasts[i] }; } } return null; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ToastService, deps: [{ token: i1.NotificationService }, { token: i2.ToastContainerService }, { token: i0.Injector }, { token: i3.DomSanitizer }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ToastService, providedIn: "root" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ToastService, decorators: [{ type: Injectable, args: [{ providedIn: "root" }] }], ctorParameters: () => [{ type: i1.NotificationService }, { type: i2.ToastContainerService }, { type: i0.Injector }, { type: i3.DomSanitizer }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9hc3Quc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdG9hc3QvdG9hc3Quc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5REFBeUQ7QUFDekQsRUFBRTtBQUNGLCtFQUErRTtBQUMvRSw0RUFBNEU7QUFDNUUsOEVBQThFO0FBQzlFLCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsNERBQTREO0FBQzVELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsdURBQXVEO0FBQ3ZELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsNEVBQTRFO0FBQzVFLCtFQUErRTtBQUMvRSwwRUFBMEU7QUFDMUUsaUZBQWlGO0FBQ2pGLDZFQUE2RTtBQUM3RSxpQkFBaUI7QUFFakIsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN6RCxPQUFPLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDcEMsT0FBTyxVQUFVLE1BQU0sa0JBQWtCLENBQUM7QUFDMUMsT0FBTyxRQUFRLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEMsT0FBTyxVQUFVLE1BQU0sa0JBQWtCLENBQUM7QUFDMUMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBU3RDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGtDQUFr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SUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxFQUFFO2dCQUM5QixPQUFPLElBQUksQ0FBQzthQUNmO1NBQ0o7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRU8sU0FBUyxDQUNiLE9BQWU7UUFFZixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDekMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxPQUFPLEVBQUU7Z0JBQ3BDLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDcEQ7U0FDSjtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7K0dBN1NRLFlBQVk7bUhBQVosWUFBWSxjQURDLE1BQU07OzRGQUNuQixZQUFZO2tCQUR4QixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8vIMKpIDIwMjIgU29sYXJXaW5kcyBXb3JsZHdpZGUsIExMQy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbi8vICBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vICBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vICBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyAgVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3RvciwgU2VjdXJpdHlDb250ZXh0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gXCJAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyXCI7XG5pbXBvcnQgX2Fzc2lnbiBmcm9tIFwibG9kYXNoL2Fzc2lnblwiO1xuaW1wb3J0IF9jbG9uZURlZXAgZnJvbSBcImxvZGFzaC9jbG9uZURlZXBcIjtcbmltcG9ydCBfaXNBcnJheSBmcm9tIFwibG9kYXNoL2lzQXJyYXlcIjtcbmltcG9ydCBfdG9JbnRlZ2VyIGZyb20gXCJsb2Rhc2gvdG9JbnRlZ2VyXCI7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbmltcG9ydCB7XG4gICAgSUFjdGl2ZVRvYXN0LFxuICAgIElUb2FzdENvbmZpZyxcbiAgICBJVG9hc3REZWNsYXJhdGlvbixcbiAgICBJVG9hc3RTZXJ2aWNlLFxuICAgIFRvYXN0UG9zaXRpb25DbGFzcyxcbn0gZnJvbSBcIi4vcHVibGljLWFwaVwiO1xuaW1wb3J0IHsgVG9hc3RDb250YWluZXJTZXJ2aWNlIH0gZnJvbSBcIi4vdG9hc3QtY29udGFpbmVyLnNlcnZpY2VcIjtcbmltcG9ydCB7IFRvYXN0SW5qZWN0b3IgfSBmcm9tIFwiLi90b2FzdC1pbmplY3RvclwiO1xuaW1wb3J0IHsgVG9hc3RQYWNrYWdlIH0gZnJvbSBcIi4vdG9hc3QtcGFja2FnZVwiO1xuaW1wb3J0IHsgVG9hc3RSZWYgfSBmcm9tIFwiLi90b2FzdC1yZWZcIjtcbmltcG9ydCB7IFRvYXN0Q29tcG9uZW50IH0gZnJvbSBcIi4vdG9hc3QuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBTd2l0Y2hTdGF0ZSB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9ub3RpZmljYXRpb24tYXJnc1wiO1xuaW1wb3J0IHsgTm90aWZpY2F0aW9uU2VydmljZSB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9ub3RpZmljYXRpb24tc2VydmljZVwiO1xuXG4vKipcbiAqIF9fTmFtZSA6IF9fXG4gKiBUb2FzdCBTZXJ2aWNlXG4gKlxuICogX19Vc2FnZSA6X19cbiAqIFVzZWQgdG8gc2hvdyB0b2FzdCBtZXNzYWdlcyBhbmQgdG8gdHJpZ2dlciBoaWdobGlnaHQgb2YgaXRlbXNcbiAqL1xuLyoqXG4gKiBAaWdub3JlXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogXCJyb290XCIgfSlcbmV4cG9ydCBjbGFzcyBUb2FzdFNlcnZpY2UgaW1wbGVtZW50cyBJVG9hc3RTZXJ2aWNlIHtcbiAgICBwcml2YXRlIGluZGV4ID0gMDtcbiAgICBwcml2YXRlIGN1cnJlbnRseUFjdGl2ZSA9IDA7XG4gICAgcHJpdmF0ZSB0b2FzdHM6IElBY3RpdmVUb2FzdFtdID0gW107XG4gICAgcHJpdmF0ZSBkZWZhdWx0VG9hc3RDb25maWc6IElUb2FzdENvbmZpZyA9IHtcbiAgICAgICAgbWF4T3BlbmVkOiAwLFxuICAgICAgICBhdXRvRGlzbWlzczogZmFsc2UsXG4gICAgICAgIG5ld2VzdE9uVG9wOiB0cnVlLFxuICAgICAgICBwcmV2ZW50RHVwbGljYXRlczogZmFsc2UsXG4gICAgICAgIHBvc2l0aW9uQ2xhc3M6IFRvYXN0UG9zaXRpb25DbGFzcy5UT1BfUklHSFQsXG4gICAgICAgIHByb2dyZXNzQW5pbWF0aW9uOiBcImRlY3JlYXNpbmdcIixcbiAgICAgICAgdGltZU91dDogNTAwMCxcbiAgICAgICAgcHJvZ3Jlc3NCYXI6IHRydWUsXG4gICAgICAgIHRvYXN0Q2xhc3M6IFwibnVpLXRvYXN0XCIsXG4gICAgICAgIGV4dGVuZGVkVGltZU91dDogMjAwMCxcbiAgICAgICAgY2xvc2VCdXR0b246IHRydWUsXG4gICAgICAgIGNsaWNrVG9EaXNtaXNzOiBmYWxzZSxcbiAgICAgICAgZW5hYmxlSHRtbDogdHJ1ZSxcbiAgICAgICAgc3RpY2t5RXJyb3I6IGZhbHNlLFxuICAgIH07XG4gICAgcHJpdmF0ZSB0b2FzdENvbmZpZzogSVRvYXN0Q29uZmlnO1xuICAgIHByaXZhdGUgaXRlbUlkZW50aWZpY2F0b3I6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIG5vdGlmaWNhdGlvblNlcnZpY2U6IE5vdGlmaWNhdGlvblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgdG9hc3RDb250YWluZXJTZXJ2aWNlOiBUb2FzdENvbnRhaW5lclNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgX2luamVjdG9yOiBJbmplY3RvcixcbiAgICAgICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplclxuICAgICkge1xuICAgICAgICB0aGlzLnRvYXN0Q29uZmlnID0gX2Fzc2lnbih7fSwgdGhpcy5kZWZhdWx0VG9hc3RDb25maWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBzZXQgZ2xvYmFsIGNvbmZpZyBmb3IgYWxsIGtpbmQgb2YgdG9hc3RzIGFuZCBpdGVtSWRlbnRpZmljYXRvciB0aGF0IGlzXG4gICAgICogdXNlZCBmb3IgaWRlbnRpZmljYXRpb24gb2YgaXRlbSBpbiBudWlUb2FzdCBkaXJlY3RpdmVcbiAgICAgKiBAcGFyYW0gY29uZmlnXG4gICAgICogQHBhcmFtIGl0ZW1JZGVudGlmaWNhdG9yXG4gICAgICogQHJldHVybiB2b2lkXG4gICAgICovXG4gICAgcHVibGljIHNldENvbmZpZyhjb25maWc6IElUb2FzdENvbmZpZywgaXRlbUlkZW50aWZpY2F0b3I/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgX2Fzc2lnbih0aGlzLnRvYXN0Q29uZmlnLCBjb25maWcpO1xuICAgICAgICB0aGlzLml0ZW1JZGVudGlmaWNhdG9yID0gaXRlbUlkZW50aWZpY2F0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBfX0Rlc2NyaXB0aW9uOl9fIHNob3cgc3VjY2VzcyB0b2FzdCB0cmlnZ2VyIGhpZ2hsaWdodCBvZiBpdGVtcyBhbmQgdHJpZ2dlciBmYWRlIG91dCBvZiBoaWdobGlnaHRpbmcgd2hlblxuICAgICAqIHRvYXN0IGlzIGdvbmVcbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2FzdERlY2xhcmF0aW9uXG4gICAgICogQHJldHVybiB2b2lkXG4gICAgICovXG4gICAgcHVibGljIHN1Y2Nlc3ModG9hc3REZWNsYXJhdGlvbjogSVRvYXN0RGVjbGFyYXRpb24pOiBJQWN0aXZlVG9hc3Qge1xuICAgICAgICBjb25zdCB0b2FzdEluc3RhbmNlID0gdGhpcy5idWlsZE5vdGlmaWNhdGlvbihcbiAgICAgICAgICAgIFwic3VjY2Vzc1wiLFxuICAgICAgICAgICAgdG9hc3REZWNsYXJhdGlvbi5tZXNzYWdlLFxuICAgICAgICAgICAgdG9hc3REZWNsYXJhdGlvbi50aXRsZSxcbiAgICAgICAgICAgIHRoaXMuYXBwbHlDb25maWcodG9hc3REZWNsYXJhdGlvbi5vcHRpb25zKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLm5vdGlmeUhpZ2hsaWdodHModG9hc3REZWNsYXJhdGlvbi5pdGVtc1RvSGlnaGxpZ2h0LCBcInN1Y2Nlc3NcIik7XG4gICAgICAgIHRoaXMudG9hc3RSZW1vdmVIaWdobGlnaHQoXG4gICAgICAgICAgICB0b2FzdEluc3RhbmNlLFxuICAgICAgICAgICAgdG9hc3REZWNsYXJhdGlvbi5pdGVtc1RvSGlnaGxpZ2h0XG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB0b2FzdEluc3RhbmNlO1xuICAgIH1cblxuICAgIHB1YmxpYyB3YXJuaW5nKHRvYXN0RGVjbGFyYXRpb246IElUb2FzdERlY2xhcmF0aW9uKTogSUFjdGl2ZVRvYXN0IHtcbiAgICAgICAgY29uc3QgdG9hc3RJbnN0YW5jZSA9IHRoaXMuYnVpbGROb3RpZmljYXRpb24oXG4gICAgICAgICAgICBcIndhcm5pbmdcIixcbiAgICAgICAgICAgIHRvYXN0RGVjbGFyYXRpb24ubWVzc2FnZSxcbiAgICAgICAgICAgIHRvYXN0RGVjbGFyYXRpb24udGl0bGUsXG4gICAgICAgICAgICB0aGlzLmFwcGx5Q29uZmlnKHRvYXN0RGVjbGFyYXRpb24ub3B0aW9ucylcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5ub3RpZnlIaWdobGlnaHRzKHRvYXN0RGVjbGFyYXRpb24uaXRlbXNUb0hpZ2hsaWdodCwgXCJ3YXJuaW5nXCIpO1xuICAgICAgICB0aGlzLnRvYXN0UmVtb3ZlSGlnaGxpZ2h0KFxuICAgICAgICAgICAgdG9hc3RJbnN0YW5jZSxcbiAgICAgICAgICAgIHRvYXN0RGVjbGFyYXRpb24uaXRlbXNUb0hpZ2hsaWdodFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gdG9hc3RJbnN0YW5jZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZXJyb3IodG9hc3REZWNsYXJhdGlvbjogSVRvYXN0RGVjbGFyYXRpb24pOiBJQWN0aXZlVG9hc3Qge1xuICAgICAgICBjb25zdCBjb25maWcgPSBfY2xvbmVEZWVwKHRvYXN0RGVjbGFyYXRpb24ub3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdG9hc3REZWNsYXJhdGlvbi5vcHRpb25zICYmXG4gICAgICAgICAgICB0b2FzdERlY2xhcmF0aW9uLm9wdGlvbnMuc3RpY2t5RXJyb3IgJiZcbiAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbmZpZy50aW1lT3V0ID0gMDtcbiAgICAgICAgICAgIGNvbmZpZy5leHRlbmRlZFRpbWVPdXQgPSAwO1xuICAgICAgICAgICAgY29uZmlnLnByb2dyZXNzQmFyID0gZmFsc2U7XG4gICAgICAgICAgICBjb25maWcuY2xvc2VCdXR0b24gPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvYXN0SW5zdGFuY2UgPSB0aGlzLmJ1aWxkTm90aWZpY2F0aW9uKFxuICAgICAgICAgICAgXCJlcnJvclwiLFxuICAgICAgICAgICAgdG9hc3REZWNsYXJhdGlvbi5tZXNzYWdlLFxuICAgICAgICAgICAgdG9hc3REZWNsYXJhdGlvbi50aXRsZSxcbiAgICAgICAgICAgIHRoaXMuYXBwbHlDb25maWcoY29uZmlnKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLm5vdGlmeUhpZ2hsaWdodHModG9hc3REZWNsYXJhdGlvbi5pdGVtc1RvSGlnaGxpZ2h0LCBcImVycm9yXCIpO1xuICAgICAgICB0aGlzLnRvYXN0UmVtb3ZlSGlnaGxpZ2h0KFxuICAgICAgICAgICAgdG9hc3RJbnN0YW5jZSxcbiAgICAgICAgICAgIHRvYXN0RGVjbGFyYXRpb24uaXRlbXNUb0hpZ2hsaWdodFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gdG9hc3RJbnN0YW5jZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaW5mbyh0b2FzdERlY2xhcmF0aW9uOiBJVG9hc3REZWNsYXJhdGlvbik6IElBY3RpdmVUb2FzdCB7XG4gICAgICAgIGNvbnN0IHRvYXN0SW5zdGFuY2UgPSB0aGlzLmJ1aWxkTm90aWZpY2F0aW9uKFxuICAgICAgICAgICAgXCJpbmZvXCIsXG4gICAgICAgICAgICB0b2FzdERlY2xhcmF0aW9uLm1lc3NhZ2UsXG4gICAgICAgICAgICB0b2FzdERlY2xhcmF0aW9uLnRpdGxlLFxuICAgICAgICAgICAgdGhpcy5hcHBseUNvbmZpZyh0b2FzdERlY2xhcmF0aW9uLm9wdGlvbnMpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMubm90aWZ5SGlnaGxpZ2h0cyh0b2FzdERlY2xhcmF0aW9uLml0ZW1zVG9IaWdobGlnaHQsIFwiaW5mb1wiKTtcbiAgICAgICAgdGhpcy50b2FzdFJlbW92ZUhpZ2hsaWdodChcbiAgICAgICAgICAgIHRvYXN0SW5zdGFuY2UsXG4gICAgICAgICAgICB0b2FzdERlY2xhcmF0aW9uLml0ZW1zVG9IaWdobGlnaHRcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHRvYXN0SW5zdGFuY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBfX0Rlc2NyaXB0aW9uOl9fIGNhbGxzIHRvYXN0cycgY2xvc2UgbWV0aG9kcyB0byBjbG9zZSB0aGVtXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9hc3RJZFxuICAgICAqIEByZXR1cm4gdm9pZFxuICAgICAqL1xuICAgIHB1YmxpYyBjbGVhcih0b2FzdElkPzogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGZvciAoY29uc3QgdG9hc3Qgb2YgdGhpcy50b2FzdHMpIHtcbiAgICAgICAgICAgIGlmICh0b2FzdElkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAodG9hc3QudG9hc3RJZCA9PT0gdG9hc3RJZCkge1xuICAgICAgICAgICAgICAgICAgICB0b2FzdC50b2FzdFJlZi5tYW51YWxDbG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0b2FzdC50b2FzdFJlZi5tYW51YWxDbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBfX0Rlc2NyaXB0aW9uOl9fIHJlbW92ZXMgdG9hc3QgYnkgaWQgYW5kIGFjdGl2YXRlcyBuZXh0IHRvYXN0IGluIHF1ZXVlICh3aGVuIG1heE9wZW5lZCAhPT0gMClcbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2FzdElkXG4gICAgICogQHJldHVybiBib29sZWFuXG4gICAgICovXG4gICAgcHVibGljIHJlbW92ZSh0b2FzdElkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdG9hc3RJbnN0YW5jZSA9IHRoaXMuZmluZFRvYXN0KHRvYXN0SWQpO1xuXG4gICAgICAgIGlmICghdG9hc3RJbnN0YW5jZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdG9hc3RJbnN0YW5jZS5hY3RpdmVUb2FzdC50b2FzdFJlZi5jbG9zZSgpO1xuICAgICAgICB0aGlzLnRvYXN0cy5zcGxpY2UodG9hc3RJbnN0YW5jZS5pbmRleCwgMSk7XG4gICAgICAgIHRoaXMuY3VycmVudGx5QWN0aXZlID0gdGhpcy5jdXJyZW50bHlBY3RpdmUgLSAxO1xuXG4gICAgICAgIGlmICghdGhpcy50b2FzdENvbmZpZy5tYXhPcGVuZWQgfHwgIXRoaXMudG9hc3RzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5jdXJyZW50bHlBY3RpdmUgPD0gK3RoaXMudG9hc3RDb25maWcubWF4T3BlbmVkICYmXG4gICAgICAgICAgICB0aGlzLnRvYXN0c1t0aGlzLmN1cnJlbnRseUFjdGl2ZV1cbiAgICAgICAgKSB7XG4gICAgICAgICAgICBjb25zdCBhY3RpdmVUb2FzdFJlZiA9IHRoaXMudG9hc3RzW3RoaXMuY3VycmVudGx5QWN0aXZlXS50b2FzdFJlZjtcbiAgICAgICAgICAgIGlmICghYWN0aXZlVG9hc3RSZWYuaXNJbmFjdGl2ZSgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50bHlBY3RpdmUgPSB0aGlzLmN1cnJlbnRseUFjdGl2ZSArIDE7XG4gICAgICAgICAgICAgICAgYWN0aXZlVG9hc3RSZWYuYWN0aXZhdGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgdG9hc3RSZW1vdmVIaWdobGlnaHQoXG4gICAgICAgIHRvYXN0SW5zdGFuY2U6IElBY3RpdmVUb2FzdCB8IG51bGwsXG4gICAgICAgIGl0ZW1zVG9SZW1vdmVIaWdobGlnaHQ/OiBhbnlbXVxuICAgICk6IHZvaWQge1xuICAgICAgICBpZiAodG9hc3RJbnN0YW5jZSkge1xuICAgICAgICAgICAgdG9hc3RJbnN0YW5jZT8ub25IaWRkZW4/LnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIF9pc0FycmF5KGl0ZW1zVG9SZW1vdmVIaWdobGlnaHQpICYmXG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zVG9SZW1vdmVIaWdobGlnaHQubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2UucG9zdChcIkhpZ2hsaWdodFwiLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoaWdobGlnaHRTdGF0ZTogU3dpdGNoU3RhdGUub2ZmLFxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXM6IGl0ZW1zVG9SZW1vdmVIaWdobGlnaHQsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhcHBseUNvbmZpZyhvdmVycmlkZTogSVRvYXN0Q29uZmlnID0ge30pOiBJVG9hc3RDb25maWcge1xuICAgICAgICBjb25zdCByZXN1bHRDb25maWcgPSBfYXNzaWduKHt9LCB0aGlzLnRvYXN0Q29uZmlnLCBvdmVycmlkZSk7XG4gICAgICAgIHJlc3VsdENvbmZpZy50aW1lT3V0ID0gX3RvSW50ZWdlcihyZXN1bHRDb25maWcudGltZU91dCk7XG4gICAgICAgIHJlc3VsdENvbmZpZy5leHRlbmRlZFRpbWVPdXQgPSBfdG9JbnRlZ2VyKHJlc3VsdENvbmZpZy5leHRlbmRlZFRpbWVPdXQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0Q29uZmlnO1xuICAgIH1cblxuICAgIHByaXZhdGUgYnVpbGROb3RpZmljYXRpb24oXG4gICAgICAgIHRvYXN0VHlwZTogc3RyaW5nLFxuICAgICAgICBib2R5OiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICAgIHRpdGxlOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICAgIGNvbmZpZzogSVRvYXN0Q29uZmlnXG4gICAgKTogSUFjdGl2ZVRvYXN0IHtcbiAgICAgICAgLy8gbWF4IG9wZW5lZCBhbmQgYXV0byBkaXNtaXNzID0gdHJ1ZVxuICAgICAgICBpZiAoYm9keSAmJiBjb25maWcucHJldmVudER1cGxpY2F0ZXMgJiYgdGhpcy5pc0R1cGxpY2F0ZShib2R5KSkge1xuICAgICAgICAgICAgLy8gVE9ETzogVXBkYXRlIGJ1aWxkTm90aWZpY2F0aW9uIHJldHVybiB0eXBlIGluIFYxMCBpbiB0aGUgc2NvcGUgb2YgTlVJLTU4MjRcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmU6IFN1cHByZXNzaW5nIGVycm9yIHVudGlsIHYxMCB0byBwcmV2ZW50IEFQSSBicmVha2luZyBjaGFuZ2VzXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudG9hc3RDb250YWluZXJTZXJ2aWNlLmdldENvbnRhaW5lckVsZW1lbnQoY29uZmlnLnBvc2l0aW9uQ2xhc3MpO1xuICAgICAgICBsZXQga2VlcEluYWN0aXZlID0gZmFsc2U7XG4gICAgICAgIGxldCBzYW5pdGl6ZWRCb2R5OiBzdHJpbmcgfCB1bmRlZmluZWQgPSBib2R5O1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMudG9hc3RDb25maWcubWF4T3BlbmVkICYmXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRseUFjdGl2ZSA+PSB0aGlzLnRvYXN0Q29uZmlnLm1heE9wZW5lZFxuICAgICAgICApIHtcbiAgICAgICAgICAgIGtlZXBJbmFjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICBpZiAodGhpcy50b2FzdENvbmZpZy5hdXRvRGlzbWlzcykge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xlYXIodGhpcy50b2FzdHNbdGhpcy50b2FzdHMubGVuZ3RoIC0gMV0udG9hc3RJZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmluZGV4ID0gdGhpcy5pbmRleCArIDE7XG5cbiAgICAgICAgaWYgKGJvZHkgJiYgY29uZmlnLmVuYWJsZUh0bWwpIHtcbiAgICAgICAgICAgIHNhbml0aXplZEJvZHkgPSA8c3RyaW5nPihcbiAgICAgICAgICAgICAgICB0aGlzLnNhbml0aXplci5zYW5pdGl6ZShTZWN1cml0eUNvbnRleHQuSFRNTCwgYm9keSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0b2FzdFJlZiA9IG5ldyBUb2FzdFJlZih0aGlzLnRvYXN0Q29udGFpbmVyU2VydmljZSk7XG4gICAgICAgIGNvbnN0IHRvYXN0UGFja2FnZSA9IG5ldyBUb2FzdFBhY2thZ2UoXG4gICAgICAgICAgICB0aGlzLmluZGV4LFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgc2FuaXRpemVkQm9keSxcbiAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgdG9hc3RUeXBlLFxuICAgICAgICAgICAgdG9hc3RSZWZcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgdG9hc3RJbmplY3RvciA9IG5ldyBUb2FzdEluamVjdG9yKHRvYXN0UGFja2FnZSwgdGhpcy5faW5qZWN0b3IpO1xuICAgICAgICB0b2FzdFJlZi5jb21wb25lbnRJbnN0YW5jZSA9IHRoaXMudG9hc3RDb250YWluZXJTZXJ2aWNlLmF0dGFjaFRvYXN0KFxuICAgICAgICAgICAgVG9hc3RDb21wb25lbnQsXG4gICAgICAgICAgICB0b2FzdEluamVjdG9yLFxuICAgICAgICAgICAgISFjb25maWcubmV3ZXN0T25Ub3BcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgdG9hc3RJbnN0YW5jZSA9IHtcbiAgICAgICAgICAgIHRvYXN0SWQ6IHRoaXMuaW5kZXgsXG4gICAgICAgICAgICBib2R5OiBzYW5pdGl6ZWRCb2R5LFxuICAgICAgICAgICAgdG9hc3RSZWYsXG4gICAgICAgICAgICBvblNob3duOiB0b2FzdFJlZi5hZnRlckFjdGl2YXRlKCksXG4gICAgICAgICAgICBvbkhpZGRlbjogdG9hc3RSZWYuYWZ0ZXJDbG9zZWQoKSxcbiAgICAgICAgICAgIG9uQ2xpY2s6IHRvYXN0UGFja2FnZS5vbkNsaWNrKCksXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCFrZWVwSW5hY3RpdmUpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRvYXN0SW5zdGFuY2UudG9hc3RSZWYuYWN0aXZhdGUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRseUFjdGl2ZSA9IHRoaXMuY3VycmVudGx5QWN0aXZlICsgMTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy50b2FzdHMucHVzaCh0b2FzdEluc3RhbmNlKTtcbiAgICAgICAgcmV0dXJuIHRvYXN0SW5zdGFuY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5lcyBpZiB0b2FzdCBtZXNzYWdlIGlzIGFscmVhZHkgc2hvd25cbiAgICAgKi9cbiAgICBwcml2YXRlIGlzRHVwbGljYXRlKGJvZHk6IHN0cmluZykge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudG9hc3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50b2FzdHNbaV0uYm9keSA9PT0gYm9keSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgZmluZFRvYXN0KFxuICAgICAgICB0b2FzdElkOiBudW1iZXJcbiAgICApOiB7IGluZGV4OiBudW1iZXI7IGFjdGl2ZVRvYXN0OiBJQWN0aXZlVG9hc3QgfSB8IG51bGwge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudG9hc3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50b2FzdHNbaV0udG9hc3RJZCA9PT0gdG9hc3RJZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IGluZGV4OiBpLCBhY3RpdmVUb2FzdDogdGhpcy50b2FzdHNbaV0gfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgbm90aWZ5SGlnaGxpZ2h0cyA9IChcbiAgICAgICAgaXRlbXNUb0hpZ2hsaWdodDogYW55W10gfCBudWxsIHwgdW5kZWZpbmVkLFxuICAgICAgICBzdGF0dXM6IHN0cmluZ1xuICAgICk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoaXRlbXNUb0hpZ2hsaWdodCkge1xuICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25TZXJ2aWNlLnBvc3QoXCJIaWdobGlnaHRcIiwge1xuICAgICAgICAgICAgICAgIGhpZ2hsaWdodFN0YXRlOiBTd2l0Y2hTdGF0ZS5vbixcbiAgICAgICAgICAgICAgICBzdGF0dXM6IHN0YXR1cyxcbiAgICAgICAgICAgICAgICBpdGVtczogaXRlbXNUb0hpZ2hsaWdodCxcbiAgICAgICAgICAgICAgICBpdGVtSWRlbnRpZmljYXRvcjogdGhpcy5pdGVtSWRlbnRpZmljYXRvcixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbn1cbiJdfQ==