ontimize-web-ngx
Version:
Ontimize Web framework using Angular 15
242 lines • 47.4 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Injector, ViewEncapsulation } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { BooleanInputConverter } from '../../../decorators/input-converter';
import { AppMenuService } from '../../../services/app-menu.service';
import { AuthService } from '../../../services/auth.service';
import { DialogService } from '../../../services/dialog.service';
import { OUserInfoService } from '../../../services/o-user-info.service';
import { PermissionsService } from '../../../services/permissions/permissions.service';
import { OTranslateService } from '../../../services/translate/o-translate.service';
import { PermissionsUtils } from '../../../util/permissions';
import { Util } from '../../../util/util';
import { OAppSidenavBase } from '../o-app-sidenav-base.class';
import { OAppLayoutBase } from '../../../layouts/app-layout/o-app-layout-base.class';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/flex-layout/flex";
import * as i3 from "@angular/material/button";
import * as i4 from "@angular/material/icon";
import * as i5 from "@angular/material/tooltip";
import * as i6 from "../../language-selector/o-language-selector.component";
import * as i7 from "../../../pipes/o-translate.pipe";
export const DEFAULT_INPUTS_O_APP_SIDENAV_MENU_ITEM = [
'menuItem : menu-item',
'menuItemType : menu-item-type',
'sidenavOpened : sidenav-opened',
'disabled'
];
export const DEFAULT_OUTPUTS_O_APP_SIDENAV_MENU_ITEM = [
'onClick'
];
export class OAppSidenavMenuItemComponent {
constructor(injector, elRef, cd) {
this.injector = injector;
this.elRef = elRef;
this.cd = cd;
this.onClick = new EventEmitter();
this.sidenavOpened = true;
this.disabled = false;
this.appSidenavToggleSubscription = new Subscription();
this.translateService = this.injector.get(OTranslateService);
this.authService = this.injector.get(AuthService);
this.dialogService = this.injector.get(DialogService);
this.permissionsService = this.injector.get(PermissionsService);
this.oUserInfoService = this.injector.get(OUserInfoService);
this.sidenav = this.injector.get(OAppSidenavBase);
this.oAppLayoutComponent = this.injector.get(OAppLayoutBase);
this.router = this.injector.get(Router);
this.appMenuService = this.injector.get(AppMenuService);
this.routerSubscription = this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd && this.appMenuService.isRouteItem(this.menuItem)) {
this.active = this.appMenuService.isItemActive(this.menuItem);
this.cd.detectChanges();
}
});
}
ngOnInit() {
this.parsePermissions();
this.active = this.appMenuService.isItemActive(this.menuItem);
}
get shouldShowTooltip() {
switch (this.oAppLayoutComponent.tooltipDisplayMode) {
case 'always':
return true;
case 'never':
return false;
case 'only-collapsed':
return !this.sidenavOpened;
case 'only-expanded':
return this.sidenavOpened;
default:
return false;
}
}
ngAfterViewInit() {
if (this.isUserInfoItem() && this.sidenav) {
this.setUserInfoImage();
this.appSidenavToggleSubscription.add(this.sidenav.onSidenavOpenedChange.subscribe(() => {
if (this.sidenav.sidenav.opened) {
this.setUserInfoImage();
}
}));
this.userInfoSubscription = this.oUserInfoService.getUserInfoObservable().subscribe(res => {
if (Util.isDefined(res.avatar) && this.sidenav.sidenav.opened) {
this.menuItem.avatar = res.avatar;
this.setUserInfoImage();
}
});
}
}
ngOnDestroy() {
if (this.appSidenavToggleSubscription) {
this.appSidenavToggleSubscription.unsubscribe();
}
if (this.routerSubscription) {
this.routerSubscription.unsubscribe();
}
if (this.mutationObserver) {
this.mutationObserver.disconnect();
}
if (this.userInfoSubscription) {
this.userInfoSubscription.unsubscribe();
}
}
parsePermissions() {
this.permissions = this.permissionsService.getMenuPermissions(this.menuItem.id);
if (!Util.isDefined(this.permissions)) {
return;
}
this.hidden = this.permissions.visible === false;
if (!this.disabled) {
this.disabled = this.permissions.enabled === false;
}
if (this.disabled) {
this.mutationObserver = PermissionsUtils.registerDisabledChangesInDom(this.elRef.nativeElement, {
checkStringValue: true
});
}
}
setUserInfoImage() {
const imgEl = this.elRef.nativeElement.getElementsByClassName('o-user-info-image')[0];
if (imgEl !== undefined) {
const item = this.menuItem;
imgEl.setAttribute('style', 'background-image: url(\'' + item.avatar + '\')');
}
this.cd.detectChanges();
}
executeItemAction() {
const actionItem = this.menuItem;
if (Util.parseBoolean(actionItem.confirm, false)) {
this.dialogService.confirm('CONFIRM', actionItem.confirmText || 'MESSAGES.CONFIRM_ACTION').then(result => result ? actionItem.action() : null);
}
else {
actionItem.action();
}
}
configureI18n() {
const localeItem = this.menuItem;
if (this.isConfiguredLang()) {
return;
}
if (this.translateService) {
this.translateService.use(localeItem.locale);
}
}
isConfiguredLang() {
const localeItem = this.menuItem;
if (this.translateService) {
return (this.translateService.getCurrentLang() === localeItem.locale);
}
return false;
}
logout() {
const menuItem = this.menuItem;
if (Util.parseBoolean(menuItem.confirm, true)) {
this.authService.logoutWithConfirmation();
}
else {
this.authService.logout();
}
}
navigate() {
const route = this.menuItem.route;
if (this.router.url !== route) {
this.router.navigate([route]);
}
}
triggerClick(e) {
if (this.disabled) {
return;
}
this.appMenuService.onClick.next({ idMenu: this.menuItem.id });
switch (this.menuItemType) {
case 'action':
this.executeItemAction();
break;
case 'locale':
this.configureI18n();
break;
case 'logout':
this.logout();
break;
default:
if (this.appMenuService.isRouteItem(this.menuItem)) {
this.navigate();
}
break;
}
this.onClick.emit(e);
}
isActionItem() {
return this.menuItemType === 'action';
}
isLocaleItem() {
return this.menuItemType === 'locale';
}
isLogoutItem() {
return this.menuItemType === 'logout';
}
isUserInfoItem() {
return this.menuItemType === 'user-info';
}
isDefaultItem() {
return this.menuItemType === 'default';
}
get useFlagIcons() {
return this.oAppLayoutComponent && this.oAppLayoutComponent.useFlagIcons;
}
get tooltip() {
let result = this.translateService.get(this.menuItem.name);
if (Util.isDefined(this.menuItem.tooltip)) {
result += ': ' + this.translateService.get(this.menuItem.tooltip);
}
return result;
}
getClass() {
let className = 'o-app-sidenav-menu-item';
if (this.menuItem.class) {
className += ' ' + this.menuItem.class;
}
return className;
}
}
OAppSidenavMenuItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OAppSidenavMenuItemComponent, deps: [{ token: i0.Injector }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
OAppSidenavMenuItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OAppSidenavMenuItemComponent, selector: "o-app-sidenav-menu-item", inputs: { menuItem: ["menu-item", "menuItem"], menuItemType: ["menu-item-type", "menuItemType"], sidenavOpened: ["sidenav-opened", "sidenavOpened"], disabled: "disabled" }, outputs: { onClick: "onClick" }, host: { properties: { "class": "getClass()", "attr.disabled": "disabled" } }, ngImport: i0, template: "<ng-container *ngIf=\"sidenavOpened\">\n <ng-container *ngIf=\"shouldShowTooltip; else noTooltipOpened\">\n <li *ngIf=\"!hidden\" class=\"o-app-sidenav-menuitem o-app-sidenav-item\" [matTooltip]=\"tooltip\" matTooltipClass=\"menugroup-tooltip\"\n matTooltipPosition=\"right\" matTooltipShowDelay=\"500\" [class.o-user-info]=\"isUserInfoItem()\" [id]=\"menuItem.id\">\n <ng-container *ngTemplateOutlet=\"contentOpened\"></ng-container>\n </li>\n </ng-container>\n</ng-container>\n\n<ng-container *ngIf=\"!sidenavOpened\">\n <li *ngIf=\"!hidden\" class=\"o-app-sidenav-menuitem o-app-sidenav-item\">\n <ng-container *ngIf=\"shouldShowTooltip; else noTooltipClosed\">\n\n <a [matTooltip]=\"tooltip\" matTooltipClass=\"menuitem-tooltip\" matTooltipPosition=\"right\" mat-button (click)=\"triggerClick($event)\"\n [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\">\n <mat-icon *ngIf=\"menuItem.svgIcon\" [svgIcon]=\"menuItem.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuItem.icon\">{{ menuItem.icon }}</mat-icon>\n </a>\n </ng-container>\n <ng-template #noTooltipClosed>\n <a mat-button (click)=\"triggerClick($event)\" [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\">\n <mat-icon *ngIf=\"menuItem.svgIcon\" [svgIcon]=\"menuItem.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuItem.icon\">{{ menuItem.icon }}</mat-icon>\n </a>\n </ng-template>\n </li>\n</ng-container>\n\n<ng-template #noTooltipOpened>\n <li *ngIf=\"!hidden\" class=\"o-app-sidenav-menuitem o-app-sidenav-item\" [class.o-user-info]=\"isUserInfoItem()\" [id]=\"menuItem.id\">\n <ng-container *ngTemplateOutlet=\"contentOpened\"></ng-container>\n </li>\n</ng-template>\n\n<ng-template #contentOpened>\n <a mat-button *ngIf=\"!isUserInfoItem() && !isLocaleItem()\" (click)=\"triggerClick($event)\"\n [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-icon *ngIf=\"menuItem.svgIcon\" [svgIcon]=\"menuItem.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuItem.icon\">{{ menuItem.icon }}</mat-icon>\n <span class=\"o-app-sidenav-menuitem-title\">{{\n menuItem.name | oTranslate\n }}</span>\n </div>\n </a>\n\n <a mat-button *ngIf=\"isLocaleItem()\" (click)=\"triggerClick($event)\">\n <div fxLayout=\"row\" fxLayoutAlign=\"space-between center\">\n <mat-icon *ngIf=\"menuItem.svgIcon\" [svgIcon]=\"menuItem.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuItem.icon\">{{ menuItem.icon }}</mat-icon>\n {{ menuItem.name | oTranslate }}\n <mat-icon *ngIf=\"isConfiguredLang()\" class=\"configured-lang\">check_circle</mat-icon>\n </div>\n </a>\n\n <div *ngIf=\"isUserInfoItem()\" fxLayout=\"column\" fxLayoutAlign=\"center center\" class=\"o-user-info-menu-item\">\n <div class=\"o-user-info-image\" fxFlexFill></div>\n <div class=\"o-user-info-item\" fxLayout=\"row\" fxLayoutAlign=\"space-between center\" fxFlexFill>\n <div class=\"o-user-info-name\">{{ menuItem.user }}</div>\n <o-language-selector [use-flag-icons]=\"useFlagIcons\"></o-language-selector>\n </div>\n </div>\n</ng-template>\n", styles: [".o-app-sidenav-menu-item .o-user-info-menu-item{cursor:default}.o-app-sidenav-menu-item .o-user-info-menu-item .o-user-info-image{background-repeat:no-repeat;background-position:center;background-size:cover;width:100%;height:200px!important}.o-app-sidenav-menu-item .o-user-info-menu-item .o-user-info-item{padding:0 8px 0 16px}.o-app-sidenav-menu-item .o-user-info-menu-item .o-user-info-name{text-transform:uppercase;font-weight:600}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i2.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i2.FlexFillDirective, selector: "[fxFill], [fxFlexFill]" }, { kind: "component", type: i3.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i6.OLanguageSelectorComponent, selector: "o-language-selector", inputs: ["use-flag-icons"], outputs: ["onChange"] }, { kind: "pipe", type: i7.OTranslatePipe, name: "oTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
__decorate([
BooleanInputConverter(),
__metadata("design:type", Boolean)
], OAppSidenavMenuItemComponent.prototype, "sidenavOpened", void 0);
__decorate([
BooleanInputConverter(),
__metadata("design:type", Boolean)
], OAppSidenavMenuItemComponent.prototype, "disabled", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OAppSidenavMenuItemComponent, decorators: [{
type: Component,
args: [{ selector: 'o-app-sidenav-menu-item', inputs: DEFAULT_INPUTS_O_APP_SIDENAV_MENU_ITEM, outputs: DEFAULT_OUTPUTS_O_APP_SIDENAV_MENU_ITEM, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
'[class]': 'getClass()',
'[attr.disabled]': 'disabled'
}, template: "<ng-container *ngIf=\"sidenavOpened\">\n <ng-container *ngIf=\"shouldShowTooltip; else noTooltipOpened\">\n <li *ngIf=\"!hidden\" class=\"o-app-sidenav-menuitem o-app-sidenav-item\" [matTooltip]=\"tooltip\" matTooltipClass=\"menugroup-tooltip\"\n matTooltipPosition=\"right\" matTooltipShowDelay=\"500\" [class.o-user-info]=\"isUserInfoItem()\" [id]=\"menuItem.id\">\n <ng-container *ngTemplateOutlet=\"contentOpened\"></ng-container>\n </li>\n </ng-container>\n</ng-container>\n\n<ng-container *ngIf=\"!sidenavOpened\">\n <li *ngIf=\"!hidden\" class=\"o-app-sidenav-menuitem o-app-sidenav-item\">\n <ng-container *ngIf=\"shouldShowTooltip; else noTooltipClosed\">\n\n <a [matTooltip]=\"tooltip\" matTooltipClass=\"menuitem-tooltip\" matTooltipPosition=\"right\" mat-button (click)=\"triggerClick($event)\"\n [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\">\n <mat-icon *ngIf=\"menuItem.svgIcon\" [svgIcon]=\"menuItem.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuItem.icon\">{{ menuItem.icon }}</mat-icon>\n </a>\n </ng-container>\n <ng-template #noTooltipClosed>\n <a mat-button (click)=\"triggerClick($event)\" [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\">\n <mat-icon *ngIf=\"menuItem.svgIcon\" [svgIcon]=\"menuItem.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuItem.icon\">{{ menuItem.icon }}</mat-icon>\n </a>\n </ng-template>\n </li>\n</ng-container>\n\n<ng-template #noTooltipOpened>\n <li *ngIf=\"!hidden\" class=\"o-app-sidenav-menuitem o-app-sidenav-item\" [class.o-user-info]=\"isUserInfoItem()\" [id]=\"menuItem.id\">\n <ng-container *ngTemplateOutlet=\"contentOpened\"></ng-container>\n </li>\n</ng-template>\n\n<ng-template #contentOpened>\n <a mat-button *ngIf=\"!isUserInfoItem() && !isLocaleItem()\" (click)=\"triggerClick($event)\"\n [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-icon *ngIf=\"menuItem.svgIcon\" [svgIcon]=\"menuItem.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuItem.icon\">{{ menuItem.icon }}</mat-icon>\n <span class=\"o-app-sidenav-menuitem-title\">{{\n menuItem.name | oTranslate\n }}</span>\n </div>\n </a>\n\n <a mat-button *ngIf=\"isLocaleItem()\" (click)=\"triggerClick($event)\">\n <div fxLayout=\"row\" fxLayoutAlign=\"space-between center\">\n <mat-icon *ngIf=\"menuItem.svgIcon\" [svgIcon]=\"menuItem.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuItem.icon\">{{ menuItem.icon }}</mat-icon>\n {{ menuItem.name | oTranslate }}\n <mat-icon *ngIf=\"isConfiguredLang()\" class=\"configured-lang\">check_circle</mat-icon>\n </div>\n </a>\n\n <div *ngIf=\"isUserInfoItem()\" fxLayout=\"column\" fxLayoutAlign=\"center center\" class=\"o-user-info-menu-item\">\n <div class=\"o-user-info-image\" fxFlexFill></div>\n <div class=\"o-user-info-item\" fxLayout=\"row\" fxLayoutAlign=\"space-between center\" fxFlexFill>\n <div class=\"o-user-info-name\">{{ menuItem.user }}</div>\n <o-language-selector [use-flag-icons]=\"useFlagIcons\"></o-language-selector>\n </div>\n </div>\n</ng-template>\n", styles: [".o-app-sidenav-menu-item .o-user-info-menu-item{cursor:default}.o-app-sidenav-menu-item .o-user-info-menu-item .o-user-info-image{background-repeat:no-repeat;background-position:center;background-size:cover;width:100%;height:200px!important}.o-app-sidenav-menu-item .o-user-info-menu-item .o-user-info-item{padding:0 8px 0 16px}.o-app-sidenav-menu-item .o-user-info-menu-item .o-user-info-name{text-transform:uppercase;font-weight:600}\n"] }]
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { sidenavOpened: [], disabled: [] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby1hcHAtc2lkZW5hdi1tZW51LWl0ZW0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb250aW1pemUtd2ViLW5neC9zcmMvbGliL2NvbXBvbmVudHMvYXBwLXNpZGVuYXYvbWVudS1pdGVtL28tYXBwLXNpZGVuYXYtbWVudS1pdGVtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL2FwcC1zaWRlbmF2L21lbnUtaXRlbS9vLWFwcC1zaWRlbmF2LW1lbnUtaXRlbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osUUFBUSxFQUlSLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFcEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFFNUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM3RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDekUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbURBQW1ELENBQUM7QUFDdkYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saURBQWlELENBQUM7QUFFcEYsT0FBTyxFQUFFLGdCQUFnQixFQUFF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SUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTtZQUN2QixTQUFTLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1NBQ3hDO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQzs7MEhBblBVLDRCQUE0Qjs4R0FBNUIsNEJBQTRCLDJWQ3REekMseXBHQStEQTtBRFFFO0lBQUMscUJBQXFCLEVBQUU7O21FQUNNO0FBQzlCO0lBQUMscUJBQXFCLEVBQUU7OzhEQUNFOzRGQXBCZiw0QkFBNEI7a0JBYnhDLFNBQVM7K0JBQ0UseUJBQXlCLFVBQzNCLHNDQUFzQyxXQUNyQyx1Q0FBdUMsaUJBR2pDLGlCQUFpQixDQUFDLElBQUksbUJBQ3BCLHVCQUF1QixDQUFDLE1BQU0sUUFDekM7d0JBQ0osU0FBUyxFQUFFLFlBQVk7d0JBQ3ZCLGlCQUFpQixFQUFFLFVBQVU7cUJBQzlCO3dKQW9CRCxhQUFhLE1BRWIsUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdG9yLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVHlwZSxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uRW5kLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEJvb2xlYW5JbnB1dENvbnZlcnRlciB9IGZyb20gJy4uLy4uLy4uL2RlY29yYXRvcnMvaW5wdXQtY29udmVydGVyJztcbmltcG9ydCB7IE1lbnVJdGVtQWN0aW9uLCBNZW51SXRlbUxvY2FsZSwgTWVudUl0ZW1Mb2dvdXQsIE1lbnVJdGVtUm91dGUsIE1lbnVJdGVtVXNlckluZm8gfSBmcm9tICcuLi8uLi8uLi9pbnRlcmZhY2VzL2FwcC1tZW51LmludGVyZmFjZSc7XG5pbXBvcnQgeyBBcHBNZW51U2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2FwcC1tZW51LnNlcnZpY2UnO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgRGlhbG9nU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2RpYWxvZy5zZXJ2aWNlJztcbmltcG9ydCB7IE9Vc2VySW5mb1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9vLXVzZXItaW5mby5zZXJ2aWNlJztcbmltcG9ydCB7IFBlcm1pc3Npb25zU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL3Blcm1pc3Npb25zL3Blcm1pc3Npb25zLnNlcnZpY2UnO1xuaW1wb3J0IHsgT1RyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy90cmFuc2xhdGUvby10cmFuc2xhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBPUGVybWlzc2lvbnMgfSBmcm9tICcuLi8uLi8uLi90eXBlcy9vLXBlcm1pc3Npb25zLnR5cGUnO1xuaW1wb3J0IHsgUGVybWlzc2lvbnNVdGlscyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvcGVybWlzc2lvbnMnO1xuaW1wb3J0IHsgVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwvdXRpbCc7XG5pbXBvcnQgeyBPQXBwU2lkZW5hdkJhc2UgfSBmcm9tICcuLi9vLWFwcC1zaWRlbmF2LWJhc2UuY2xhc3MnO1xuaW1wb3J0IHsgT0FwcExheW91dEJhc2UgfSBmcm9tICcuLi8uLi8uLi9sYXlvdXRzL2FwcC1sYXlvdXQvby1hcHAtbGF5b3V0LWJhc2UuY2xhc3MnO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9JTlBVVFNfT19BUFBfU0lERU5BVl9NRU5VX0lURU0gPSBbXG4gICdtZW51SXRlbSA6IG1lbnUtaXRlbScsXG4gICdtZW51SXRlbVR5cGUgOiBtZW51LWl0ZW0tdHlwZScsXG4gICdzaWRlbmF2T3BlbmVkIDogc2lkZW5hdi1vcGVuZWQnLFxuICAnZGlzYWJsZWQnXG5dO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9PVVRQVVRTX09fQVBQX1NJREVOQVZfTUVOVV9JVEVNID0gW1xuICAnb25DbGljaydcbl07XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ28tYXBwLXNpZGVuYXYtbWVudS1pdGVtJyxcbiAgaW5wdXRzOiBERUZBVUxUX0lOUFVUU19PX0FQUF9TSURFTkFWX01FTlVfSVRFTSxcbiAgb3V0cHV0czogREVGQVVMVF9PVVRQVVRTX09fQVBQX1NJREVOQVZfTUVOVV9JVEVNLFxuICB0ZW1wbGF0ZVVybDogJy4vby1hcHAtc2lkZW5hdi1tZW51LWl0ZW0uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9vLWFwcC1zaWRlbmF2LW1lbnUtaXRlbS5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaG9zdDoge1xuICAgICdbY2xhc3NdJzogJ2dldENsYXNzKCknLFxuICAgICdbYXR0ci5kaXNhYmxlZF0nOiAnZGlzYWJsZWQnXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgT0FwcFNpZGVuYXZNZW51SXRlbUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICBwdWJsaWMgb25DbGljazogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBwcm90ZWN0ZWQgdHJhbnNsYXRlU2VydmljZTogT1RyYW5zbGF0ZVNlcnZpY2U7XG4gIHByb3RlY3RlZCBhdXRoU2VydmljZTogQXV0aFNlcnZpY2U7XG4gIHByb3RlY3RlZCBkaWFsb2dTZXJ2aWNlOiBEaWFsb2dTZXJ2aWNlO1xuICBwcm90ZWN0ZWQgcGVybWlzc2lvbnNTZXJ2aWNlOiBQZXJtaXNzaW9uc1NlcnZpY2U7XG4gIHByb3RlY3RlZCBvVXNlckluZm9TZXJ2aWNlOiBPVXNlckluZm9TZXJ2aWNlO1xuICBwcm90ZWN0ZWQgYXBwTWVudVNlcnZpY2U6IEFwcE1lbnVTZXJ2aWNlO1xuICBwcm90ZWN0ZWQgdXNlckluZm9TdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcblxuICBwcm90ZWN0ZWQgc2lkZW5hdjogT0FwcFNpZGVuYXZCYXNlO1xuICBwcm90ZWN0ZWQgcm91dGVyOiBSb3V0ZXI7XG5cbiAgbWVudUl0ZW06IGFueTsgLy8gVE9ETyBNZW51Um9vdEl0ZW07XG4gIG1lbnVJdGVtVHlwZTogc3RyaW5nO1xuICBAQm9vbGVhbklucHV0Q29udmVydGVyKClcbiAgc2lkZW5hdk9wZW5lZDogYm9vbGVhbiA9IHRydWU7XG4gIEBCb29sZWFuSW5wdXRDb252ZXJ0ZXIoKVxuICBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBhcHBTaWRlbmF2VG9nZ2xlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByb3RlY3RlZCByb3V0ZXJTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgcHJvdGVjdGVkIG9BcHBMYXlvdXRDb21wb25lbnQ6IE9BcHBMYXlvdXRCYXNlO1xuXG4gIHByb3RlY3RlZCBwZXJtaXNzaW9uczogT1Blcm1pc3Npb25zO1xuICBwcm90ZWN0ZWQgbXV0YXRpb25PYnNlcnZlcjogTXV0YXRpb25PYnNlcnZlcjtcblxuICBoaWRkZW46IGJvb2xlYW47XG4gIGFjdGl2ZTogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByb3RlY3RlZCBlbFJlZjogRWxlbWVudFJlZixcbiAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmXG4gICkge1xuICAgIHRoaXMudHJhbnNsYXRlU2VydmljZSA9IHRoaXMuaW5qZWN0b3IuZ2V0PE9UcmFuc2xhdGVTZXJ2aWNlPihPVHJhbnNsYXRlU2VydmljZSBhcyBUeXBlPE9UcmFuc2xhdGVTZXJ2aWNlPik7XG4gICAgdGhpcy5hdXRoU2VydmljZSA9IHRoaXMuaW5qZWN0b3IuZ2V0PEF1dGhTZXJ2aWNlPihBdXRoU2VydmljZSBhcyBUeXBlPEF1dGhTZXJ2aWNlPik7XG4gICAgdGhpcy5kaWFsb2dTZXJ2aWNlID0gdGhpcy5pbmplY3Rvci5nZXQ8RGlhbG9nU2VydmljZT4oRGlhbG9nU2VydmljZSBhcyBUeXBlPERpYWxvZ1NlcnZpY2U+KTtcbiAgICB0aGlzLnBlcm1pc3Npb25zU2VydmljZSA9IHRoaXMuaW5qZWN0b3IuZ2V0PFBlcm1pc3Npb25zU2VydmljZT4oUGVybWlzc2lvbnNTZXJ2aWNlIGFzIFR5cGU8UGVybWlzc2lvbnNTZXJ2aWNlPik7XG4gICAgdGhpcy5vVXNlckluZm9TZXJ2aWNlID0gdGhpcy5pbmplY3Rvci5nZXQ8T1VzZXJJbmZvU2VydmljZT4oT1VzZXJJbmZvU2VydmljZSBhcyBUeXBlPE9Vc2VySW5mb1NlcnZpY2U+KTtcbiAgICB0aGlzLnNpZGVuYXYgPSB0aGlzLmluamVjdG9yLmdldDxPQXBwU2lkZW5hdkJhc2U+KE9BcHBTaWRlbmF2QmFzZSBhcyBUeXBlPE9BcHBTaWRlbmF2QmFzZT4pO1xuICAgIHRoaXMub0FwcExheW91dENvbXBvbmVudCA9IHRoaXMuaW5qZWN0b3IuZ2V0PE9BcHBMYXlvdXRCYXNlPihPQXBwTGF5b3V0QmFzZSBhcyBUeXBlPE9BcHBMYXlvdXRCYXNlPik7XG4gICAgdGhpcy5yb3V0ZXIgPSB0aGlzLmluamVjdG9yLmdldDxSb3V0ZXI+KFJvdXRlciBhcyBUeXBlPFJvdXRlcj4pO1xuICAgIHRoaXMuYXBwTWVudVNlcnZpY2UgPSB0aGlzLmluamVjdG9yLmdldDxBcHBNZW51U2VydmljZT4oQXBwTWVudVNlcnZpY2UgYXMgVHlwZTxBcHBNZW51U2VydmljZT4pO1xuXG4gICAgdGhpcy5yb3V0ZXJTdWJzY3JpcHRpb24gPSB0aGlzLnJvdXRlci5ldmVudHMuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCAmJiB0aGlzLmFwcE1lbnVTZXJ2aWNlLmlzUm91dGVJdGVtKHRoaXMubWVudUl0ZW0pKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlID0gdGhpcy5hcHBNZW51U2VydmljZS5pc0l0ZW1BY3RpdmUodGhpcy5tZW51SXRlbSBhcyBNZW51SXRlbVJvdXRlKTtcbiAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnBhcnNlUGVybWlzc2lvbnMoKTtcbiAgICB0aGlzLmFjdGl2ZSA9IHRoaXMuYXBwTWVudVNlcnZpY2UuaXNJdGVtQWN0aXZlKHRoaXMubWVudUl0ZW0gYXMgTWVudUl0ZW1Sb3V0ZSk7XG4gIH1cblxuICBnZXQgc2hvdWxkU2hvd1Rvb2x0aXAoKSB7XG4gICAgc3dpdGNoICh0aGlzLm9BcHBMYXlvdXRDb21wb25lbnQudG9vbHRpcERpc3BsYXlNb2RlKSB7XG4gICAgICBjYXNlICdhbHdheXMnOlxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIGNhc2UgJ25ldmVyJzpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgY2FzZSAnb25seS1jb2xsYXBzZWQnOlxuICAgICAgICByZXR1cm4gIXRoaXMuc2lkZW5hdk9wZW5lZDtcbiAgICAgIGNhc2UgJ29ubHktZXhwYW5kZWQnOlxuICAgICAgICByZXR1cm4gdGhpcy5zaWRlbmF2T3BlbmVkO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBpZiAodGhpcy5pc1VzZXJJbmZvSXRlbSgpICYmIHRoaXMuc2lkZW5hdikge1xuICAgICAgdGhpcy5zZXRVc2VySW5mb0ltYWdlKCk7XG4gICAgICB0aGlzLmFwcFNpZGVuYXZUb2dnbGVTdWJzY3JpcHRpb24uYWRkKHRoaXMuc2lkZW5hdi5vblNpZGVuYXZPcGVuZWRDaGFuZ2Uuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuc2lkZW5hdi5zaWRlbmF2Lm9wZW5lZCkge1xuICAgICAgICAgIHRoaXMuc2V0VXNlckluZm9JbWFnZSgpO1xuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgICB0aGlzLnVzZXJJbmZvU3Vic2NyaXB0aW9uID0gdGhpcy5vVXNlckluZm9TZXJ2aWNlLmdldFVzZXJJbmZvT2JzZXJ2YWJsZSgpLnN1YnNjcmliZShyZXMgPT4ge1xuICAgICAgICBpZiAoVXRpbC5pc0RlZmluZWQocmVzLmF2YXRhcikgJiYgdGhpcy5zaWRlbmF2LnNpZGVuYXYub3BlbmVkKSB7XG4gICAgICAgICAgKHRoaXMubWVudUl0ZW0gYXMgTWVudUl0ZW1Vc2VySW5mbykuYXZhdGFyID0gcmVzLmF2YXRhcjtcbiAgICAgICAgICB0aGlzLnNldFVzZXJJbmZvSW1hZ2UoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuYXBwU2lkZW5hdlRvZ2dsZVN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5hcHBTaWRlbmF2VG9nZ2xlU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnJvdXRlclN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5yb3V0ZXJTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMubXV0YXRpb25PYnNlcnZlcikge1xuICAgICAgdGhpcy5tdXRhdGlvbk9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudXNlckluZm9TdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMudXNlckluZm9TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgcGFyc2VQZXJtaXNzaW9ucygpIHtcbiAgICAvLyBpZiBvYXR0ciBpbiBmb3JtLCBpdCBjYW4gaGF2ZSBwZXJtaXNzaW9uc1xuICAgIHRoaXMucGVybWlzc2lvbnMgPSB0aGlzLnBlcm1pc3Npb25zU2VydmljZS5nZXRNZW51UGVybWlzc2lvbnModGhpcy5tZW51SXRlbS5pZCk7XG4gICAgaWYgKCFVdGlsLmlzRGVmaW5lZCh0aGlzLnBlcm1pc3Npb25zKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmhpZGRlbiA9IHRoaXMucGVybWlzc2lvbnMudmlzaWJsZSA9PT0gZmFsc2U7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVkKSB7XG4gICAgICAvLyBpZiB0aGUgZGlzYWJsZWQgaW5wdXQgaXMgdHJ1ZSBpdCBtZWFucyB0aGF0IGl0cyBwYXJlbnQgaXMgZGlzYWJsZWQgdXNpbmcgcGVybWlzc2lvbnNcbiAgICAgIHRoaXMuZGlzYWJsZWQgPSB0aGlzLnBlcm1pc3Npb25zLmVuYWJsZWQgPT09IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICB0aGlzLm11dGF0aW9uT2JzZXJ2ZXIgPSBQZXJtaXNzaW9uc1V0aWxzLnJlZ2lzdGVyRGlzYWJsZWRDaGFuZ2VzSW5Eb20odGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LCB7XG4gICAgICAgIGNoZWNrU3RyaW5nVmFsdWU6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRVc2VySW5mb0ltYWdlKCkge1xuICAgIGNvbnN0IGltZ0VsID0gdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ28tdXNlci1pbmZvLWltYWdlJylbMF07XG4gICAgaWYgKGltZ0VsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLm1lbnVJdGVtIGFzIE1lbnVJdGVtVXNlckluZm87XG4gICAgICBpbWdFbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJ2JhY2tncm91bmQtaW1hZ2U6IHVybChcXCcnICsgaXRlbS5hdmF0YXIgKyAnXFwnKScpO1xuICAgIH1cbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIGV4ZWN1dGVJdGVtQWN0aW9uKCkge1xuICAgIGNvbnN0IGFjdGlvbkl0ZW0gPSAodGhpcy5tZW51SXRlbSBhcyBNZW51SXRlbUFjdGlvbik7XG4gICAgaWYgKFV0aWwucGFyc2VCb29sZWFuKGFjdGlvbkl0ZW0uY29uZmlybSwgZmFsc2UpKSB7XG4gICAgICB0aGlzLmRpYWxvZ1NlcnZpY2UuY29uZmlybSgnQ09ORklSTScsIGFjdGlvbkl0ZW0uY29uZmlybVRleHQgfHwgJ01FU1NBR0VTLkNPTkZJUk1fQUNUSU9OJykudGhlbihyZXN1bHQgPT4gcmVzdWx0ID8gYWN0aW9uSXRlbS5hY3Rpb24oKSA6IG51bGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhY3Rpb25JdGVtLmFjdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIGNvbmZpZ3VyZUkxOG4oKSB7XG4gICAgY29uc3QgbG9jYWxlSXRlbSA9ICh0aGlzLm1lbnVJdGVtIGFzIE1lbnVJdGVtTG9jYWxlKTtcbiAgICBpZiAodGhpcy5pc0NvbmZpZ3VyZWRMYW5nKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMudHJhbnNsYXRlU2VydmljZSkge1xuICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLnVzZShsb2NhbGVJdGVtLmxvY2FsZSk7XG4gICAgfVxuICB9XG5cbiAgaXNDb25maWd1cmVkTGFuZygpIHtcbiAgICBjb25zdCBsb2NhbGVJdGVtID0gKHRoaXMubWVudUl0ZW0gYXMgTWVudUl0ZW1Mb2NhbGUpO1xuICAgIGlmICh0aGlzLnRyYW5zbGF0ZVNlcnZpY2UpIHtcbiAgICAgIHJldHVybiAodGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldEN1cnJlbnRMYW5nKCkgPT09IGxvY2FsZUl0ZW0ubG9jYWxlKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgbG9nb3V0KCkge1xuICAgIGNvbnN0IG1lbnVJdGVtID0gKHRoaXMubWVudUl0ZW0gYXMgTWVudUl0ZW1Mb2dvdXQpO1xuICAgIGlmIChVdGlsLnBhcnNlQm9vbGVhbihtZW51SXRlbS5jb25maXJtLCB0cnVlKSkge1xuICAgICAgdGhpcy5hdXRoU2VydmljZS5sb2dvdXRXaXRoQ29uZmlybWF0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXV0aFNlcnZpY2UubG9nb3V0KCk7XG4gICAgfVxuICB9XG5cbiAgbmF2aWdhdGUoKSB7XG4gICAgY29uc3Qgcm91dGUgPSAodGhpcy5tZW51SXRlbSBhcyBNZW51SXRlbVJvdXRlKS5yb3V0ZTtcbiAgICBpZiAodGhpcy5yb3V0ZXIudXJsICE9PSByb3V0ZSkge1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW3JvdXRlXSk7XG4gICAgfVxuICB9XG5cbiAgdHJpZ2dlckNsaWNrKGU6IEV2ZW50KSB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5hcHBNZW51U2VydmljZS5vbkNsaWNrLm5leHQoeyBpZE1lbnU6IHRoaXMubWVudUl0ZW0uaWQgfSk7XG5cbiAgICBzd2l0Y2ggKHRoaXMubWVudUl0ZW1UeXBlKSB7XG4gICAgICBjYXNlICdhY3Rpb24nOlxuICAgICAgICB0aGlzLmV4ZWN1dGVJdGVtQWN0aW9uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbG9jYWxlJzpcbiAgICAgICAgdGhpcy5jb25maWd1cmVJMThuKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbG9nb3V0JzpcbiAgICAgICAgdGhpcy5sb2dvdXQoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAodGhpcy5hcHBNZW51U2VydmljZS5pc1JvdXRlSXRlbSh0aGlzLm1lbnVJdGVtKSkge1xuICAgICAgICAgIHRoaXMubmF2aWdhdGUoKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgdGhpcy5vbkNsaWNrLmVtaXQoZSk7XG4gIH1cblxuXG5cbiAgaXNBY3Rpb25JdGVtKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm1lbnVJdGVtVHlwZSA9PT0gJ2FjdGlvbic7XG4gIH1cblxuICBpc0xvY2FsZUl0ZW0oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubWVudUl0ZW1UeXBlID09PSAnbG9jYWxlJztcbiAgfVxuXG4gIGlzTG9nb3V0SXRlbSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tZW51SXRlbVR5cGUgPT09ICdsb2dvdXQnO1xuICB9XG5cbiAgaXNVc2VySW5mb0l0ZW0oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubWVudUl0ZW1UeXBlID09PSAndXNlci1pbmZvJztcbiAgfVxuXG4gIGlzRGVmYXVsdEl0ZW0oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubWVudUl0ZW1UeXBlID09PSAnZGVmYXVsdCc7XG4gIH1cblxuICBnZXQgdXNlRmxhZ0ljb25zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm9BcHBMYXlvdXRDb21wb25lbnQgJiYgdGhpcy5vQXBwTGF5b3V0Q29tcG9uZW50LnVzZUZsYWdJY29ucztcbiAgfVxuXG4gIGdldCB0b29sdGlwKCk6IHN0cmluZyB7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMudHJhbnNsYXRlU2VydmljZS5nZXQodGhpcy5tZW51SXRlbS5uYW1lKTtcbiAgICBpZiAoVXRpbC5pc0RlZmluZWQodGhpcy5tZW51SXRlbS50b29sdGlwKSkge1xuICAgICAgcmVzdWx0ICs9ICc6ICcgKyB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuZ2V0KHRoaXMubWVudUl0ZW0udG9vbHRpcCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBnZXRDbGFzcygpIHtcbiAgICBsZXQgY2xhc3NOYW1lID0gJ28tYXBwLXNpZGVuYXYtbWVudS1pdGVtJztcbiAgICBpZiAodGhpcy5tZW51SXRlbS5jbGFzcykge1xuICAgICAgY2xhc3NOYW1lICs9ICcgJyArIHRoaXMubWVudUl0ZW0uY2xhc3M7XG4gICAgfVxuICAgIHJldHVybiBjbGFzc05hbWU7XG4gIH1cblxufVxuIiwiPG5nLWNvbnRhaW5lciAqbmdJZj1cInNpZGVuYXZPcGVuZWRcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNob3VsZFNob3dUb29sdGlwOyBlbHNlIG5vVG9vbHRpcE9wZW5lZFwiPlxuICAgIDxsaSAqbmdJZj1cIiFoaWRkZW5cIiBjbGFzcz1cIm8tYXBwLXNpZGVuYXYtbWVudWl0ZW0gby1hcHAtc2lkZW5hdi1pdGVtXCIgW21hdFRvb2x0aXBdPVwidG9vbHRpcFwiIG1hdFRvb2x0aXBDbGFzcz1cIm1lbnVncm91cC10b29sdGlwXCJcbiAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cInJpZ2h0XCIgbWF0VG9vbHRpcFNob3dEZWxheT1cIjUwMFwiIFtjbGFzcy5vLXVzZXItaW5mb109XCJpc1VzZXJJbmZvSXRlbSgpXCIgW2lkXT1cIm1lbnVJdGVtLmlkXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiY29udGVudE9wZW5lZFwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvbGk+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy1jb250YWluZXI+XG5cbjxuZy1jb250YWluZXIgKm5nSWY9XCIhc2lkZW5hdk9wZW5lZFwiPlxuICA8bGkgKm5nSWY9XCIhaGlkZGVuXCIgY2xhc3M9XCJvLWFwcC1zaWRlbmF2LW1lbnVpdGVtIG8tYXBwLXNpZGVuYXYtaXRlbVwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzaG91bGRTaG93VG9vbHRpcDsgZWxzZSBub1Rvb2x0aXBDbG9zZWRcIj5cblxuICAgICAgPGEgW21hdFRvb2x0aXBdPVwidG9vbHRpcFwiIG1hdFRvb2x0aXBDbGFzcz1cIm1lbnVpdGVtLXRvb2x0aXBcIiBtYXRUb29sdGlwUG9zaXRpb249XCJyaWdodFwiIG1hdC1idXR0b24gKGNsaWNrKT1cInRyaWdnZXJDbGljaygkZXZlbnQpXCJcbiAgICAgICAgW2NsYXNzLm8tYXBwLXNpZGVuYXYtdmlld2VyLXNpZGVuYXYtaXRlbS1zZWxlY3RlZF09XCJhY3RpdmVcIj5cbiAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwibWVudUl0ZW0uc3ZnSWNvblwiIFtzdmdJY29uXT1cIm1lbnVJdGVtLnN2Z0ljb25cIj48L21hdC1pY29uPlxuICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJtZW51SXRlbS5pY29uXCI+e3sgbWVudUl0ZW0uaWNvbiB9fTwvbWF0LWljb24+XG4gICAgICA8L2E+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLXRlbXBsYXRlICNub1Rvb2x0aXBDbG9zZWQ+XG4gICAgICA8YSBtYXQtYnV0dG9uIChjbGljayk9XCJ0cmlnZ2VyQ2xpY2soJGV2ZW50KVwiIFtjbGFzcy5vLWFwcC1zaWRlbmF2LXZpZXdlci1zaWRlbmF2LWl0ZW0tc2VsZWN0ZWRdPVwiYWN0aXZlXCI+XG4gICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIm1lbnVJdGVtLnN2Z0ljb25cIiBbc3ZnSWNvbl09XCJtZW51SXRlbS5zdmdJY29uXCI+PC9tYXQtaWNvbj5cbiAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwibWVudUl0ZW0uaWNvblwiPnt7IG1lbnVJdGVtLmljb24gfX08L21hdC1pY29uPlxuICAgICAgPC9hPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvbGk+XG48L25nLWNvbnRhaW5lcj5cblxuPG5nLXRlbXBsYXRlICNub1Rvb2x0aXBPcGVuZWQ+XG4gIDxsaSAqbmdJZj1cIiFoaWRkZW5cIiBjbGFzcz1cIm8tYXBwLXNpZGVuYXYtbWVudWl0ZW0gby1hcHAtc2lkZW5hdi1pdGVtXCIgW2NsYXNzLm8tdXNlci1pbmZvXT1cImlzVXNlckluZm9JdGVtKClcIiBbaWRdPVwibWVudUl0ZW0uaWRcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiY29udGVudE9wZW5lZFwiPjwvbmctY29udGFpbmVyPlxuICA8L2xpPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNjb250ZW50T3BlbmVkPlxuICA8YSBtYXQtYnV0dG9uICpuZ0lmPVwiIWlzVXNlckluZm9JdGVtKCkgJiYgIWlzTG9jYWxlSXRlbSgpXCIgKGNsaWNrKT1cInRyaWdnZXJDbGljaygkZXZlbnQpXCJcbiAgICBbY2xhc3Muby1hcHAtc2lkZW5hdi12aWV3ZXItc2lkZW5hdi1pdGVtLXNlbGVjdGVkXT1cImFjdGl2ZVwiPlxuICAgIDxkaXYgZnhMYXlvdXQ9XCJyb3dcIiBmeExheW91dEFsaWduPVwic3RhcnQgY2VudGVyXCI+XG4gICAgICA8bWF0LWljb24gKm5nSWY9XCJtZW51SXRlbS5zdmdJY29uXCIgW3N2Z0ljb25dPVwibWVudUl0ZW0uc3ZnSWNvblwiPjwvbWF0LWljb24+XG4gICAgICA8bWF0LWljb24gKm5nSWY9XCJtZW51SXRlbS5pY29uXCI+e3sgbWVudUl0ZW0uaWNvbiB9fTwvbWF0LWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cIm8tYXBwLXNpZGVuYXYtbWVudWl0ZW0tdGl0bGVcIj57e1xuICAgICAgICBtZW51SXRlbS5uYW1lIHwgb1RyYW5zbGF0ZVxuICAgICAgICB9fTwvc3Bhbj5cbiAgICA8L2Rpdj5cbiAgPC9hPlxuXG4gIDxhIG1hdC1idXR0b24gKm5nSWY9XCJpc0xvY2FsZUl0ZW0oKVwiIChjbGljayk9XCJ0cmlnZ2VyQ2xpY2soJGV2ZW50KVwiPlxuICAgIDxkaXYgZnhMYXlvdXQ9XCJyb3dcIiBmeExheW91dEFsaWduPVwic3BhY2UtYmV0d2VlbiBjZW50ZXJcIj5cbiAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIm1lbnVJdGVtLnN2Z0ljb25cIiBbc3ZnSWNvbl09XCJtZW51SXRlbS5zdmdJY29uXCI+PC9tYXQtaWNvbj5cbiAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIm1lbnVJdGVtLmljb25cIj57eyBtZW51SXRlbS5pY29uIH19PC9tYXQtaWNvbj5cbiAgICAgIHt7IG1lbnVJdGVtLm5hbWUgfCBvVHJhbnNsYXRlIH19XG4gICAgICA8bWF0LWljb24gKm5nSWY9XCJpc0NvbmZpZ3VyZWRMYW5nKClcIiBjbGFzcz1cImNvbmZpZ3VyZWQtbGFuZ1wiPmNoZWNrX2NpcmNsZTwvbWF0LWljb24+XG4gICAgPC9kaXY+XG4gIDwvYT5cblxuICA8ZGl2ICpuZ0lmPVwiaXNVc2VySW5mb0l0ZW0oKVwiIGZ4TGF5b3V0PVwiY29sdW1uXCIgZnhMYXlvdXRBbGlnbj1cImNlbnRlciBjZW50ZXJcIiBjbGFzcz1cIm8tdXNlci1pbmZvLW1lbnUtaXRlbVwiPlxuICAgIDxkaXYgY2xhc3M9XCJvLXVzZXItaW5mby1pbWFnZVwiIGZ4RmxleEZpbGw+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm8tdXNlci1pbmZvLWl0ZW1cIiBmeExheW91dD1cInJvd1wiIGZ4TGF5b3V0QWxpZ249XCJzcGFjZS1iZXR3ZWVuIGNlbnRlclwiIGZ4RmxleEZpbGw+XG4gICAgICA8ZGl2IGNsYXNzPVwiby11c2VyLWluZm8tbmFtZVwiPnt7IG1lbnVJdGVtLnVzZXIgfX08L2Rpdj5cbiAgICAgIDxvLWxhbmd1YWdlLXNlbGVjdG9yIFt1c2UtZmxhZy1pY29uc109XCJ1c2VGbGFnSWNvbnNcIj48L28tbGFuZ3VhZ2Utc2VsZWN0b3I+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==