ng-prime-tools
Version:
An advanced PrimeNG table for Angular
212 lines • 41 kB
JavaScript
import { Component, Input, } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { BadgeType } from '../enums';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/router";
import * as i3 from "../pt-card/pt-card.component";
import * as i4 from "../pt-text-input/pt-text-input.component";
export class PTSideBarMenuComponent {
constructor(renderer, el) {
this.renderer = renderer;
this.el = el;
this.menuConfig = {
menus: [],
isVisible: true,
searchable: true,
width: '250px',
height: '100vh',
scrollable: true,
backgroundColor: 'white',
fontColor: '#333',
fontColorSubMenu: '#666',
hoverColor: '#f1f1f1',
hoverColorSubMenu: '#e0e0e0',
};
this.searchCardConfig = {
alignContent: 'center',
alignBodyContent: 'center',
identifier: 'pt-side-bar-menu/search',
backgroundColor: 'white',
height: '72px',
padding: '0',
};
this.cardConfig = {
identifier: 'pt-side-bar-menu',
backgroundColor: '',
width: '',
height: '',
scrollableVertical: false,
};
this.formGroup = new FormGroup({
search: new FormControl(''),
});
this.searchField = {
name: 'search',
placeholder: 'Search...',
iconClass: 'pi pi-search',
};
this.filteredMenus = [];
}
ngOnInit() {
this.cardConfig = {
identifier: 'pt-side-bar-menu',
backgroundColor: this.menuConfig.backgroundColor,
width: this.menuConfig.width,
height: this.menuConfig.height,
scrollableVertical: this.menuConfig.scrollable,
pattern: this.menuConfig.pattern,
};
this.filteredMenus = this.menuConfig.menus;
const cardWidth = this.menuConfig.width
? parseInt(this.menuConfig.width)
: 250;
this.searchField.width = `${cardWidth - 60}px`;
this.searchCardConfig.width = this.menuConfig.width;
this.searchCardConfig.pattern = this.menuConfig.pattern;
if (this.menuConfig.searchable) {
this.formGroup
.get('search')
?.valueChanges.subscribe((searchTerm) => {
this.onSearch(searchTerm);
});
}
}
toggleMenu(item, event) {
item.isExpanded = !item.isExpanded;
event.preventDefault();
}
getChevronClass(item) {
return item.isExpanded ? 'fa fa-chevron-down' : 'fa fa-chevron-right';
}
getBadgeStyles(badge) {
const defaultColors = this.getDefaultBadgeColors(badge.type || BadgeType.Info);
return {
color: badge.color || defaultColors.color,
backgroundColor: badge.backgroundColor || defaultColors.backgroundColor,
padding: '2px 8px',
borderRadius: '5px',
fontSize: '12px',
};
}
getDefaultBadgeColors(type) {
switch (type) {
case BadgeType.Info:
return { color: 'white', backgroundColor: '#17a2b8' };
case BadgeType.Danger:
return { color: 'white', backgroundColor: '#dc3545' };
case BadgeType.Warning:
return { color: 'white', backgroundColor: '#ffc107' };
default:
return { color: 'white', backgroundColor: '#6c757d' };
}
}
onSearch(searchTerm) {
if (searchTerm.trim() === '') {
this.filteredMenus = this.menuConfig.menus;
this.collapseAllMenus();
}
else {
const lowerCaseSearch = searchTerm.toLowerCase();
this.filteredMenus = this.menuConfig.menus
.map((menu) => this.searchInMenu({ ...menu }, lowerCaseSearch))
.filter(Boolean);
}
}
searchInMenu(menu, searchTerm) {
const isMatch = menu.label.toLowerCase().includes(searchTerm);
if (menu.children) {
const matchingChildren = menu.children
.map((child) => this.searchInMenu(child, searchTerm))
.filter(Boolean);
if (matchingChildren.length > 0) {
menu.children = matchingChildren;
menu.isExpanded = true;
return menu;
}
}
return isMatch ? menu : null;
}
collapseAllMenus() {
this.menuConfig.menus.forEach((menu) => {
menu.isExpanded = false;
});
}
getMenuItemStyles() {
return {
color: this.menuConfig.fontColor || '#333', // Set default font color if not specified in config
};
}
getMenuLinkStyles() {
return {
color: this.menuConfig.fontColor || '#333',
'text-decoration': 'none',
'border-radius': '8px',
padding: '10px 15px',
'font-size': '16px',
transition: 'background-color 0.2s, color 0.2s',
display: 'flex',
'align-items': 'center',
':hover': {
backgroundColor: this.menuConfig.hoverColor || '#f1f1f1',
color: '#111',
},
};
}
getSubMenuLinkStyles() {
return {
color: this.menuConfig.fontColorSubMenu || this.menuConfig.fontColor || '#666',
'text-decoration': 'none',
'border-radius': '5px',
padding: '5px 10px',
transition: 'background-color 0.2s, color 0.2s',
':hover': {
backgroundColor: this.menuConfig.hoverColorSubMenu || '#e0e0e0',
},
};
}
ngAfterViewInit() {
this.applyHoverEffects();
}
applyHoverEffects() {
const menuLinks = this.el.nativeElement.querySelectorAll('a.menu-link');
const subMenuLinks = this.el.nativeElement.querySelectorAll('a.submenu-link');
// Apply hover effects for main menu links
menuLinks.forEach((link) => {
this.renderer.listen(link, 'mouseenter', () => {
this.renderer.setStyle(link, 'background-color', this.menuConfig.hoverColor || '#f1f1f1');
this.renderer.setStyle(link, 'color', this.menuConfig.hoverFontColor || 'white');
});
this.renderer.listen(link, 'mouseleave', () => {
this.renderer.removeStyle(link, 'background-color');
this.renderer.setStyle(link, 'color', this.menuConfig.fontColor || '#333');
});
});
// Apply hover effects for submenu links
subMenuLinks.forEach((link) => {
this.renderer.listen(link, 'mouseenter', () => {
this.renderer.setStyle(link, 'background-color', this.menuConfig.hoverColorSubMenu ||
this.menuConfig.hoverColor ||
'#f1f1f1');
this.renderer.setStyle(link, 'color', this.menuConfig.hoverFontColorSubMenu ||
this.menuConfig.hoverFontColor ||
'#fff');
});
this.renderer.listen(link, 'mouseleave', () => {
this.renderer.removeStyle(link, 'background-color');
this.renderer.setStyle(link, 'color', this.menuConfig.fontColorSubMenu ||
this.menuConfig.fontColor ||
'#666');
});
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTSideBarMenuComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTSideBarMenuComponent, selector: "pt-side-bar-menu", inputs: { menuConfig: "menuConfig" }, ngImport: i0, template: "<div class=\"pt-side-bar-menu\">\n <pt-card\n *ngIf=\"menuConfig.searchable\"\n [config]=\"searchCardConfig\"\n [ngClass]=\"{ 'sidebar-hidden': !menuConfig.isVisible }\"\n >\n <div class=\"search-input\">\n <pt-text-input [formGroup]=\"formGroup\" [formField]=\"searchField\">\n </pt-text-input>\n </div>\n </pt-card>\n\n <pt-card\n [config]=\"cardConfig\"\n [ngClass]=\"{ 'sidebar-hidden': !menuConfig.isVisible }\"\n >\n <ul class=\"menu-list\">\n <li\n *ngFor=\"let item of filteredMenus\"\n class=\"menu-item\"\n [ngClass]=\"{ 'menu-item-expanded': item.isExpanded }\"\n [ngStyle]=\"getMenuItemStyles()\"\n >\n <!-- Main menu items without children -->\n <a\n *ngIf=\"!item.children?.length\"\n [routerLink]=\"item.url\"\n class=\"menu-link\"\n [ngStyle]=\"getMenuLinkStyles()\"\n >\n <i [ngClass]=\"item.icon\"></i>\n <span>{{ item.label }}</span>\n <span\n *ngIf=\"item.badge\"\n [ngStyle]=\"getBadgeStyles(item.badge)\"\n class=\"badge\"\n >\n {{ item.badge.count }}\n </span>\n </a>\n\n <!-- Menu items with children -->\n <a\n *ngIf=\"item.children?.length\"\n class=\"menu-link\"\n (click)=\"toggleMenu(item, $event)\"\n [ngStyle]=\"getMenuLinkStyles()\"\n >\n <i [ngClass]=\"item.icon\"></i>\n <span>{{ item.label }}</span>\n <span\n *ngIf=\"item.badge\"\n [ngStyle]=\"getBadgeStyles(item.badge)\"\n class=\"badge\"\n >\n {{ item.badge.count }}\n </span>\n <i [ngClass]=\"getChevronClass(item)\" class=\"chevron\"></i>\n </a>\n\n <!-- Submenu -->\n <ul class=\"submenu-list\">\n <li *ngFor=\"let child of item.children\" class=\"submenu-item\">\n <a\n [routerLink]=\"child.url\"\n class=\"submenu-link\"\n [ngStyle]=\"getSubMenuLinkStyles()\"\n >\n <i [ngClass]=\"child.icon\"></i>\n <span class=\"submenu-title\">{{ child.label }}</span>\n <span\n *ngIf=\"child.badge\"\n [ngStyle]=\"getBadgeStyles(child.badge)\"\n class=\"badge\"\n >\n {{ child.badge.count }}\n </span>\n </a>\n </li>\n </ul>\n </li>\n </ul>\n </pt-card>\n</div>\n", styles: [".pt-side-bar-menu .badge{background-color:#38bdf8;border-radius:5px;color:#fff;font-size:12px;margin-left:auto;padding:2px 8px}.pt-side-bar-menu .chevron{color:#8c8c8c;cursor:pointer;margin-left:auto}.pt-side-bar-menu .menu-item{position:relative}.pt-side-bar-menu .menu-item-expanded .submenu-list{max-height:500px;padding-bottom:5px;padding-top:5px}.pt-side-bar-menu .menu-link{align-items:center;border-radius:8px;color:#333;cursor:pointer;display:flex;font-size:16px;margin-bottom:15px;padding:10px 15px;text-decoration:none;transition:background-color .2s,color .2s}.pt-side-bar-menu .menu-link:hover{background-color:#f1f1f1;color:#111}.pt-side-bar-menu .menu-link i{margin-right:10px}.pt-side-bar-menu .menu-list{list-style-type:none;padding:0}.pt-side-bar-menu pt-card{transition:transform .3s ease-in-out,opacity .3s ease-in-out;display:block}.pt-side-bar-menu .sidebar-hidden{transform:translate(-100%);opacity:0}.pt-side-bar-menu .sidebar-menu{margin:0;padding:0;transition:transform .3s ease-in-out;width:250px}.pt-side-bar-menu .submenu-item{padding:5px 0;position:relative}.pt-side-bar-menu .submenu-item:before{background-color:#e5e7eb;content:\"\";height:1px;left:-25px;position:absolute;top:50%;transform:translateY(-50%);width:25px}.pt-side-bar-menu .submenu-item:last-child:after{content:none}.pt-side-bar-menu .submenu-link{align-items:center;border-radius:5px;color:#666;display:flex;font-size:14px;padding:5px 10px;text-decoration:none;transition:background-color .2s,color .2s}.pt-side-bar-menu .submenu-link:hover{background-color:#f1f1f1;color:#000}.pt-side-bar-menu .submenu-list{border-left:1px solid #e5e7eb;list-style-type:none;margin-left:23px;margin-top:5px;max-height:0;overflow:hidden;padding-left:25px;position:relative;transition:max-height .3s ease-out,padding .3s ease-out}.pt-side-bar-menu .submenu-list:after{background-color:#e5e7eb;bottom:0;content:\"\";left:-1px;position:absolute;top:0;width:1px}.pt-side-bar-menu .submenu-title{margin-left:5px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i3.PTCardComponent, selector: "pt-card", inputs: ["config"] }, { kind: "component", type: i4.PTTextInputComponent, selector: "pt-text-input", inputs: ["formGroup", "formField"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTSideBarMenuComponent, decorators: [{
type: Component,
args: [{ selector: 'pt-side-bar-menu', template: "<div class=\"pt-side-bar-menu\">\n <pt-card\n *ngIf=\"menuConfig.searchable\"\n [config]=\"searchCardConfig\"\n [ngClass]=\"{ 'sidebar-hidden': !menuConfig.isVisible }\"\n >\n <div class=\"search-input\">\n <pt-text-input [formGroup]=\"formGroup\" [formField]=\"searchField\">\n </pt-text-input>\n </div>\n </pt-card>\n\n <pt-card\n [config]=\"cardConfig\"\n [ngClass]=\"{ 'sidebar-hidden': !menuConfig.isVisible }\"\n >\n <ul class=\"menu-list\">\n <li\n *ngFor=\"let item of filteredMenus\"\n class=\"menu-item\"\n [ngClass]=\"{ 'menu-item-expanded': item.isExpanded }\"\n [ngStyle]=\"getMenuItemStyles()\"\n >\n <!-- Main menu items without children -->\n <a\n *ngIf=\"!item.children?.length\"\n [routerLink]=\"item.url\"\n class=\"menu-link\"\n [ngStyle]=\"getMenuLinkStyles()\"\n >\n <i [ngClass]=\"item.icon\"></i>\n <span>{{ item.label }}</span>\n <span\n *ngIf=\"item.badge\"\n [ngStyle]=\"getBadgeStyles(item.badge)\"\n class=\"badge\"\n >\n {{ item.badge.count }}\n </span>\n </a>\n\n <!-- Menu items with children -->\n <a\n *ngIf=\"item.children?.length\"\n class=\"menu-link\"\n (click)=\"toggleMenu(item, $event)\"\n [ngStyle]=\"getMenuLinkStyles()\"\n >\n <i [ngClass]=\"item.icon\"></i>\n <span>{{ item.label }}</span>\n <span\n *ngIf=\"item.badge\"\n [ngStyle]=\"getBadgeStyles(item.badge)\"\n class=\"badge\"\n >\n {{ item.badge.count }}\n </span>\n <i [ngClass]=\"getChevronClass(item)\" class=\"chevron\"></i>\n </a>\n\n <!-- Submenu -->\n <ul class=\"submenu-list\">\n <li *ngFor=\"let child of item.children\" class=\"submenu-item\">\n <a\n [routerLink]=\"child.url\"\n class=\"submenu-link\"\n [ngStyle]=\"getSubMenuLinkStyles()\"\n >\n <i [ngClass]=\"child.icon\"></i>\n <span class=\"submenu-title\">{{ child.label }}</span>\n <span\n *ngIf=\"child.badge\"\n [ngStyle]=\"getBadgeStyles(child.badge)\"\n class=\"badge\"\n >\n {{ child.badge.count }}\n </span>\n </a>\n </li>\n </ul>\n </li>\n </ul>\n </pt-card>\n</div>\n", styles: [".pt-side-bar-menu .badge{background-color:#38bdf8;border-radius:5px;color:#fff;font-size:12px;margin-left:auto;padding:2px 8px}.pt-side-bar-menu .chevron{color:#8c8c8c;cursor:pointer;margin-left:auto}.pt-side-bar-menu .menu-item{position:relative}.pt-side-bar-menu .menu-item-expanded .submenu-list{max-height:500px;padding-bottom:5px;padding-top:5px}.pt-side-bar-menu .menu-link{align-items:center;border-radius:8px;color:#333;cursor:pointer;display:flex;font-size:16px;margin-bottom:15px;padding:10px 15px;text-decoration:none;transition:background-color .2s,color .2s}.pt-side-bar-menu .menu-link:hover{background-color:#f1f1f1;color:#111}.pt-side-bar-menu .menu-link i{margin-right:10px}.pt-side-bar-menu .menu-list{list-style-type:none;padding:0}.pt-side-bar-menu pt-card{transition:transform .3s ease-in-out,opacity .3s ease-in-out;display:block}.pt-side-bar-menu .sidebar-hidden{transform:translate(-100%);opacity:0}.pt-side-bar-menu .sidebar-menu{margin:0;padding:0;transition:transform .3s ease-in-out;width:250px}.pt-side-bar-menu .submenu-item{padding:5px 0;position:relative}.pt-side-bar-menu .submenu-item:before{background-color:#e5e7eb;content:\"\";height:1px;left:-25px;position:absolute;top:50%;transform:translateY(-50%);width:25px}.pt-side-bar-menu .submenu-item:last-child:after{content:none}.pt-side-bar-menu .submenu-link{align-items:center;border-radius:5px;color:#666;display:flex;font-size:14px;padding:5px 10px;text-decoration:none;transition:background-color .2s,color .2s}.pt-side-bar-menu .submenu-link:hover{background-color:#f1f1f1;color:#000}.pt-side-bar-menu .submenu-list{border-left:1px solid #e5e7eb;list-style-type:none;margin-left:23px;margin-top:5px;max-height:0;overflow:hidden;padding-left:25px;position:relative;transition:max-height .3s ease-out,padding .3s ease-out}.pt-side-bar-menu .submenu-list:after{background-color:#e5e7eb;bottom:0;content:\"\";left:-1px;position:absolute;top:0;width:1px}.pt-side-bar-menu .submenu-title{margin-left:5px}\n"] }]
}], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { menuConfig: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHQtc2lkZS1iYXItbWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1wcmltZS10b29scy9zcmMvbGliL3B0LXNpZGUtYmFyLW1lbnUvcHQtc2lkZS1iYXItbWVudS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1wcmltZS10b29scy9zcmMvbGliL3B0LXNpZGUtYmFyLW1lbnUvcHQtc2lkZS1iYXItbWVudS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsU0FBUyxFQUVULEtBQUssR0FHTixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBUXhELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxVQUFVLENBQUM7Ozs7OztBQU9yQyxNQUFNLE9BQU8sc0JBQXNCO0lBZWpDLFlBQW9CLFFBQW1CLEVBQVUsRUFBYztRQUEzQyxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQVUsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQWR0RCxlQUFVLEdBQXNCO1lBQ3ZDLEtBQUssRUFBRSxFQUFFO1lBQ1QsU0FBUyxFQUFFLElBQUk7WUFDZixVQUFVLEVBQUUsSUFBSTtZQUNoQixLQUFLLEVBQUUsT0FBTztZQUNkLE1BQU0sRUFBRSxPQUFPO1lBQ2YsVUFBVSxFQUFFLElBQUk7WUFDaEIsZUFBZSxFQUFFLE9BQU87WUFDeEIsU0FBUyxFQUFFLE1BQU07WUFDakIsZ0JBQWdCLEVBQUUsTUFBTTtZQUN4QixVQUFVLEVBQUUsU0FBUztZQUNyQixpQkFBaUIsRUFBRSxTQUFTO1NBQzdCLENBQUM7UUFJRixxQkFBZ0IsR0FBZTtZQUM3QixZQUFZLEVBQUUsUUFBUTtZQUN0QixnQkFBZ0IsRUFBRSxRQUFRO1lBQzFCLFVBQVUsRUFBRSx5QkFBeUI7WUFDckMsZUFB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QUFFLFlBQVksRUFBRSxHQUFHLEVBQUU7Z0JBQzVDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO2dCQUNwRCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FDcEIsSUFBSSxFQUNKLE9BQU8sRUFDUCxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQjtvQkFDOUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTO29CQUN6QixNQUFNLENBQ1QsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDOytHQXRQVSxzQkFBc0I7bUdBQXRCLHNCQUFzQiw4RkN2Qm5DLHdoRkFvRkE7OzRGRDdEYSxzQkFBc0I7a0JBTGxDLFNBQVM7K0JBQ0Usa0JBQWtCO3VHQUtuQixVQUFVO3NCQUFsQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBSZW5kZXJlcjIsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwLCBGb3JtQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIE1lbnUsXG4gIEZvcm1UZXh0RmllbGQsXG4gIFNpZGVNZW51QmFyQ29uZmlnLFxuICBDYXJkQ29uZmlnLFxuICBCYWRnZSxcbn0gZnJvbSAnLi4vbW9kZWxzJztcbmltcG9ydCB7IEJhZGdlVHlwZSB9IGZyb20gJy4uL2VudW1zJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncHQtc2lkZS1iYXItbWVudScsXG4gIHRlbXBsYXRlVXJsOiAnLi9wdC1zaWRlLWJhci1tZW51LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcHQtc2lkZS1iYXItbWVudS5jb21wb25lbnQuY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFBUU2lkZUJhck1lbnVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQge1xuICBASW5wdXQoKSBtZW51Q29uZmlnOiBTaWRlTWVudUJhckNvbmZpZyA9IHtcbiAgICBtZW51czogW10sXG4gICAgaXNWaXNpYmxlOiB0cnVlLFxuICAgIHNlYXJjaGFibGU6IHRydWUsXG4gICAgd2lkdGg6ICcyNTBweCcsXG4gICAgaGVpZ2h0OiAnMTAwdmgnLFxuICAgIHNjcm9sbGFibGU6IHRydWUsXG4gICAgYmFja2dyb3VuZENvbG9yOiAnd2hpdGUnLFxuICAgIGZvbnRDb2xvcjogJyMzMzMnLFxuICAgIGZvbnRDb2xvclN1Yk1lbnU6ICcjNjY2JyxcbiAgICBob3ZlckNvbG9yOiAnI2YxZjFmMScsXG4gICAgaG92ZXJDb2xvclN1Yk1lbnU6ICcjZTBlMGUwJyxcbiAgfTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYpIHt9XG5cbiAgc2VhcmNoQ2FyZENvbmZpZzogQ2FyZENvbmZpZyA9IHtcbiAgICBhbGlnbkNvbnRlbnQ6ICdjZW50ZXInLFxuICAgIGFsaWduQm9keUNvbnRlbnQ6ICdjZW50ZXInLFxuICAgIGlkZW50aWZpZXI6ICdwdC1zaWRlLWJhci1tZW51L3NlYXJjaCcsXG4gICAgYmFja2dyb3VuZENvbG9yOiAnd2hpdGUnLFxuICAgIGhlaWdodDogJzcycHgnLFxuICAgIHBhZGRpbmc6ICcwJyxcbiAgfTtcblxuICBjYXJkQ29uZmlnOiBDYXJkQ29uZmlnID0ge1xuICAgIGlkZW50aWZpZXI6ICdwdC1zaWRlLWJhci1tZW51JyxcbiAgICBiYWNrZ3JvdW5kQ29sb3I6ICcnLFxuICAgIHdpZHRoOiAnJyxcbiAgICBoZWlnaHQ6ICcnLFxuICAgIHNjcm9sbGFibGVWZXJ0aWNhbDogZmFsc2UsXG4gIH07XG5cbiAgZm9ybUdyb3VwOiBGb3JtR3JvdXAgPSBuZXcgRm9ybUdyb3VwKHtcbiAgICBzZWFyY2g6IG5ldyBGb3JtQ29udHJvbCgnJyksXG4gIH0pO1xuXG4gIHNlYXJjaEZpZWxkOiBGb3JtVGV4dEZpZWxkID0ge1xuICAgIG5hbWU6ICdzZWFyY2gnLFxuICAgIHBsYWNlaG9sZGVyOiAnU2VhcmNoLi4uJyxcbiAgICBpY29uQ2xhc3M6ICdwaSBwaS1zZWFyY2gnLFxuICB9O1xuXG4gIGZpbHRlcmVkTWVudXM6IE1lbnVbXSA9IFtdO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuY2FyZENvbmZpZyA9IHtcbiAgICAgIGlkZW50aWZpZXI6ICdwdC1zaWRlLWJhci1tZW51JyxcbiAgICAgIGJhY2tncm91bmRDb2xvcjogdGhpcy5tZW51Q29uZmlnLmJhY2tncm91bmRDb2xvcixcbiAgICAgIHdpZHRoOiB0aGlzLm1lbnVDb25maWcud2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMubWVudUNvbmZpZy5oZWlnaHQsXG4gICAgICBzY3JvbGxhYmxlVmVydGljYWw6IHRoaXMubWVudUNvbmZpZy5zY3JvbGxhYmxlLFxuICAgICAgcGF0dGVybjogdGhpcy5tZW51Q29uZmlnLnBhdHRlcm4sXG4gICAgfTtcblxuICAgIHRoaXMuZmlsdGVyZWRNZW51cyA9IHRoaXMubWVudUNvbmZpZy5tZW51cztcblxuICAgIGNvbnN0IGNhcmRXaWR0aCA9IHRoaXMubWVudUNvbmZpZy53aWR0aFxuICAgICAgPyBwYXJzZUludCh0aGlzLm1lbnVDb25maWcud2lkdGgpXG4gICAgICA6IDI1MDtcbiAgICB0aGlzLnNlYXJjaEZpZWxkLndpZHRoID0gYCR7Y2FyZFdpZHRoIC0gNjB9cHhgO1xuICAgIHRoaXMuc2VhcmNoQ2FyZENvbmZpZy53aWR0aCA9IHRoaXMubWVudUNvbmZpZy53aWR0aDtcbiAgICB0aGlzLnNlYXJjaENhcmRDb25maWcucGF0dGVybiA9IHRoaXMubWVudUNvbmZpZy5wYXR0ZXJuO1xuXG4gICAgaWYgKHRoaXMubWVudUNvbmZpZy5zZWFyY2hhYmxlKSB7XG4gICAgICB0aGlzLmZvcm1Hcm91cFxuICAgICAgICAuZ2V0KCdzZWFyY2gnKVxuICAgICAgICA/LnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKHNlYXJjaFRlcm06IHN0cmluZykgPT4ge1xuICAgICAgICAgIHRoaXMub25TZWFyY2goc2VhcmNoVGVybSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZU1lbnUoaXRlbTogTWVudSwgZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgaXRlbS5pc0V4cGFuZGVkID0gIWl0ZW0uaXNFeHBhbmRlZDtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgZ2V0Q2hldnJvbkNsYXNzKGl0ZW06IE1lbnUpOiBzdHJpbmcge1xuICAgIHJldHVybiBpdGVtLmlzRXhwYW5kZWQgPyAnZmEgZmEtY2hldnJvbi1kb3duJyA6ICdmYSBmYS1jaGV2cm9uLXJpZ2h0JztcbiAgfVxuXG4gIGdldEJhZGdlU3R5bGVzKGJhZGdlOiBCYWRnZSkge1xuICAgIGNvbnN0IGRlZmF1bHRDb2xvcnMgPSB0aGlzLmdldERlZmF1bHRCYWRnZUNvbG9ycyhcbiAgICAgIGJhZGdlLnR5cGUgfHwgQmFkZ2VUeXBlLkluZm9cbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbG9yOiBiYWRnZS5jb2xvciB8fCBkZWZhdWx0Q29sb3JzLmNvbG9yLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiBiYWRnZS5iYWNrZ3JvdW5kQ29sb3IgfHwgZGVmYXVsdENvbG9ycy5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBwYWRkaW5nOiAnMnB4IDhweCcsXG4gICAgICBib3JkZXJSYWRpdXM6ICc1cHgnLFxuICAgICAgZm9udFNpemU6ICcxMnB4JyxcbiAgICB9O1xuICB9XG5cbiAgZ2V0RGVmYXVsdEJhZGdlQ29sb3JzKHR5cGU6IEJhZGdlVHlwZSkge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBCYWRnZVR5cGUuSW5mbzpcbiAgICAgICAgcmV0dXJuIHsgY29sb3I6ICd3aGl0ZScsIGJhY2tncm91bmRDb2xvcjogJyMxN2EyYjgnIH07XG4gICAgICBjYXNlIEJhZGdlVHlwZS5EYW5nZXI6XG4gICAgICAgIHJldHVybiB7IGNvbG9yOiAnd2hpdGUnLCBiYWNrZ3JvdW5kQ29sb3I6ICcjZGMzNTQ1JyB9O1xuICAgICAgY2FzZSBCYWRnZVR5cGUuV2FybmluZzpcbiAgICAgICAgcmV0dXJuIHsgY29sb3I6ICd3aGl0ZScsIGJhY2tncm91bmRDb2xvcjogJyNmZmMxMDcnIH07XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4geyBjb2xvcjogJ3doaXRlJywgYmFja2dyb3VuZENvbG9yOiAnIzZjNzU3ZCcgfTtcbiAgICB9XG4gIH1cblxuICBvblNlYXJjaChzZWFyY2hUZXJtOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoc2VhcmNoVGVybS50cmltKCkgPT09ICcnKSB7XG4gICAgICB0aGlzLmZpbHRlcmVkTWVudXMgPSB0aGlzLm1lbnVDb25maWcubWVudXM7XG4gICAgICB0aGlzLmNvbGxhcHNlQWxsTWVudXMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbG93ZXJDYXNlU2VhcmNoID0gc2VhcmNoVGVybS50b0xvd2VyQ2FzZSgpO1xuICAgICAgdGhpcy5maWx0ZXJlZE1lbnVzID0gdGhpcy5tZW51Q29uZmlnLm1lbnVzXG4gICAgICAgIC5tYXAoKG1lbnUpID0+IHRoaXMuc2VhcmNoSW5NZW51KHsgLi4ubWVudSB9LCBsb3dlckNhc2VTZWFyY2gpKVxuICAgICAgICAuZmlsdGVyKEJvb2xlYW4pIGFzIE1lbnVbXTtcbiAgICB9XG4gIH1cblxuICBzZWFyY2hJbk1lbnUobWVudTogTWVudSwgc2VhcmNoVGVybTogc3RyaW5nKTogTWVudSB8IG51bGwge1xuICAgIGNvbnN0IGlzTWF0Y2ggPSBtZW51LmxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoc2VhcmNoVGVybSk7XG5cbiAgICBpZiAobWVudS5jaGlsZHJlbikge1xuICAgICAgY29uc3QgbWF0Y2hpbmdDaGlsZHJlbiA9IG1lbnUuY2hpbGRyZW5cbiAgICAgICAgLm1hcCgoY2hpbGQpID0+IHRoaXMuc2VhcmNoSW5NZW51KGNoaWxkLCBzZWFyY2hUZXJtKSlcbiAgICAgICAgLmZpbHRlcihCb29sZWFuKSBhcyBNZW51W107XG5cbiAgICAgIGlmIChtYXRjaGluZ0NoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbWVudS5jaGlsZHJlbiA9IG1hdGNoaW5nQ2hpbGRyZW47XG4gICAgICAgIG1lbnUuaXNFeHBhbmRlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiBtZW51O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpc01hdGNoID8gbWVudSA6IG51bGw7XG4gIH1cblxuICBjb2xsYXBzZUFsbE1lbnVzKCk6IHZvaWQge1xuICAgIHRoaXMubWVudUNvbmZpZy5tZW51cy5mb3JFYWNoKChtZW51KSA9PiB7XG4gICAgICBtZW51LmlzRXhwYW5kZWQgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldE1lbnVJdGVtU3R5bGVzKCk6IGFueSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbG9yOiB0aGlzLm1lbnVDb25maWcuZm9udENvbG9yIHx8ICcjMzMzJywgLy8gU2V0IGRlZmF1bHQgZm9udCBjb2xvciBpZiBub3Qgc3BlY2lmaWVkIGluIGNvbmZpZ1xuICAgIH07XG4gIH1cblxuICBnZXRNZW51TGlua1N0eWxlcygpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICBjb2xvcjogdGhpcy5tZW51Q29uZmlnLmZvbnRDb2xvciB8fCAnIzMzMycsXG4gICAgICAndGV4dC1kZWNvcmF0aW9uJzogJ25vbmUnLFxuICAgICAgJ2JvcmRlci1yYWRpdXMnOiAnOHB4JyxcbiAgICAgIHBhZGRpbmc6ICcxMHB4IDE1cHgnLFxuICAgICAgJ2ZvbnQtc2l6ZSc6ICcxNnB4JyxcbiAgICAgIHRyYW5zaXRpb246ICdiYWNrZ3JvdW5kLWNvbG9yIDAuMnMsIGNvbG9yIDAuMnMnLFxuICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgJ2FsaWduLWl0ZW1zJzogJ2NlbnRlcicsXG4gICAgICAnOmhvdmVyJzoge1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMubWVudUNvbmZpZy5ob3ZlckNvbG9yIHx8ICcjZjFmMWYxJyxcbiAgICAgICAgY29sb3I6ICcjMTExJyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGdldFN1Yk1lbnVMaW5rU3R5bGVzKCk6IGFueSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbG9yOlxuICAgICAgICB0aGlzLm1lbnVDb25maWcuZm9udENvbG9yU3ViTWVudSB8fCB0aGlzLm1lbnVDb25maWcuZm9udENvbG9yIHx8ICcjNjY2JyxcbiAgICAgICd0ZXh0LWRlY29yYXRpb24nOiAnbm9uZScsXG4gICAgICAnYm9yZGVyLXJhZGl1cyc6ICc1cHgnLFxuICAgICAgcGFkZGluZzogJzVweCAxMHB4JyxcbiAgICAgIHRyYW5zaXRpb246ICdiYWNrZ3JvdW5kLWNvbG9yIDAuMnMsIGNvbG9yIDAuMnMnLFxuICAgICAgJzpob3Zlcic6IHtcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLm1lbnVDb25maWcuaG92ZXJDb2xvclN1Yk1lbnUgfHwgJyNlMGUwZTAnLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmFwcGx5SG92ZXJFZmZlY3RzKCk7XG4gIH1cblxuICBhcHBseUhvdmVyRWZmZWN0cygpOiB2b2lkIHtcbiAgICBjb25zdCBtZW51TGlua3MgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnYS5tZW51LWxpbmsnKTtcbiAgICBjb25zdCBzdWJNZW51TGlua3MgPVxuICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2Euc3VibWVudS1saW5rJyk7XG5cbiAgICAvLyBBcHBseSBob3ZlciBlZmZlY3RzIGZvciBtYWluIG1lbnUgbGlua3NcbiAgICBtZW51TGlua3MuZm9yRWFjaCgobGluazogSFRNTEVsZW1lbnQpID0+IHtcbiAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGxpbmssICdtb3VzZWVudGVyJywgKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICAgIGxpbmssXG4gICAgICAgICAgJ2JhY2tncm91bmQtY29sb3InLFxuICAgICAgICAgIHRoaXMubWVudUNvbmZpZy5ob3ZlckNvbG9yIHx8ICcjZjFmMWYxJ1xuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICAgIGxpbmssXG4gICAgICAgICAgJ2NvbG9yJyxcbiAgICAgICAgICB0aGlzLm1lbnVDb25maWcuaG92ZXJGb250Q29sb3IgfHwgJ3doaXRlJ1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGxpbmssICdtb3VzZWxlYXZlJywgKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZVN0eWxlKGxpbmssICdiYWNrZ3JvdW5kLWNvbG9yJyk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICAgICAgbGluayxcbiAgICAgICAgICAnY29sb3InLFxuICAgICAgICAgIHRoaXMubWVudUNvbmZpZy5mb250Q29sb3IgfHwgJyMzMzMnXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIEFwcGx5IGhvdmVyIGVmZmVjdHMgZm9yIHN1Ym1lbnUgbGlua3NcbiAgICBzdWJNZW51TGlua3MuZm9yRWFjaCgobGluazogSFRNTEVsZW1lbnQpID0+IHtcbiAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGxpbmssICdtb3VzZWVudGVyJywgKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICAgIGxpbmssXG4gICAgICAgICAgJ2JhY2tncm91bmQtY29sb3InLFxuICAgICAgICAgIHRoaXMubWVudUNvbmZpZy5ob3ZlckNvbG9yU3ViTWVudSB8fFxuICAgICAgICAgICAgdGhpcy5tZW51Q29uZmlnLmhvdmVyQ29sb3IgfHxcbiAgICAgICAgICAgICcjZjFmMWYxJ1xuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICAgIGxpbmssXG4gICAgICAgICAgJ2NvbG9yJyxcbiAgICAgICAgICB0aGlzLm1lbnVDb25maWcuaG92ZXJGb250Q29sb3JTdWJNZW51IHx8XG4gICAgICAgICAgICB0aGlzLm1lbnVDb25maWcuaG92ZXJGb250Q29sb3IgfHxcbiAgICAgICAgICAgICcjZmZmJ1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGxpbmssICdtb3VzZWxlYXZlJywgKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZVN0eWxlKGxpbmssICdiYWNrZ3JvdW5kLWNvbG9yJyk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICAgICAgbGluayxcbiAgICAgICAgICAnY29sb3InLFxuICAgICAgICAgIHRoaXMubWVudUNvbmZpZy5mb250Q29sb3JTdWJNZW51IHx8XG4gICAgICAgICAgICB0aGlzLm1lbnVDb25maWcuZm9udENvbG9yIHx8XG4gICAgICAgICAgICAnIzY2NidcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwicHQtc2lkZS1iYXItbWVudVwiPlxuICA8cHQtY2FyZFxuICAgICpuZ0lmPVwibWVudUNvbmZpZy5zZWFyY2hhYmxlXCJcbiAgICBbY29uZmlnXT1cInNlYXJjaENhcmRDb25maWdcIlxuICAgIFtuZ0NsYXNzXT1cInsgJ3NpZGViYXItaGlkZGVuJzogIW1lbnVDb25maWcuaXNWaXNpYmxlIH1cIlxuICA+XG4gICAgPGRpdiBjbGFzcz1cInNlYXJjaC1pbnB1dFwiPlxuICAgICAgPHB0LXRleHQtaW5wdXQgW2Zvcm1Hcm91cF09XCJmb3JtR3JvdXBcIiBbZm9ybUZpZWxkXT1cInNlYXJjaEZpZWxkXCI+XG4gICAgICA8L3B0LXRleHQtaW5wdXQ+XG4gICAgPC9kaXY+XG4gIDwvcHQtY2FyZD5cblxuICA8cHQtY2FyZFxuICAgIFtjb25maWddPVwiY2FyZENvbmZpZ1wiXG4gICAgW25nQ2xhc3NdPVwieyAnc2lkZWJhci1oaWRkZW4nOiAhbWVudUNvbmZpZy5pc1Zpc2libGUgfVwiXG4gID5cbiAgICA8dWwgY2xhc3M9XCJtZW51LWxpc3RcIj5cbiAgICAgIDxsaVxuICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBmaWx0ZXJlZE1lbnVzXCJcbiAgICAgICAgY2xhc3M9XCJtZW51LWl0ZW1cIlxuICAgICAgICBbbmdDbGFzc109XCJ7ICdtZW51LWl0ZW0tZXhwYW5kZWQnOiBpdGVtLmlzRXhwYW5kZWQgfVwiXG4gICAgICAgIFtuZ1N0eWxlXT1cImdldE1lbnVJdGVtU3R5bGVzKClcIlxuICAgICAgPlxuICAgICAgICA8IS0tIE1haW4gbWVudSBpdGVtcyB3aXRob3V0IGNoaWxkcmVuIC0tPlxuICAgICAgICA8YVxuICAgICAgICAgICpuZ0lmPVwiIWl0ZW0uY2hpbGRyZW4/Lmxlbmd0aFwiXG4gICAgICAgICAgW3JvdXRlckxpbmtdPVwiaXRlbS51cmxcIlxuICAgICAgICAgIGNsYXNzPVwibWVudS1saW5rXCJcbiAgICAgICAgICBbbmdTdHlsZV09XCJnZXRNZW51TGlua1N0eWxlcygpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxpIFtuZ0NsYXNzXT1cIml0ZW0uaWNvblwiPjwvaT5cbiAgICAgICAgICA8c3Bhbj57eyBpdGVtLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAqbmdJZj1cIml0ZW0uYmFkZ2VcIlxuICAgICAgICAgICAgW25nU3R5bGVdPVwiZ2V0QmFkZ2VTdHlsZXMoaXRlbS5iYWRnZSlcIlxuICAgICAgICAgICAgY2xhc3M9XCJiYWRnZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgaXRlbS5iYWRnZS5jb3VudCB9fVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9hPlxuXG4gICAgICAgIDwhLS0gTWVudSBpdGVtcyB3aXRoIGNoaWxkcmVuIC0tPlxuICAgICAgICA8YVxuICAgICAgICAgICpuZ0lmPVwiaXRlbS5jaGlsZHJlbj8ubGVuZ3RoXCJcbiAgICAgICAgICBjbGFzcz1cIm1lbnUtbGlua1wiXG4gICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZU1lbnUoaXRlbSwgJGV2ZW50KVwiXG4gICAgICAgICAgW25nU3R5bGVdPVwiZ2V0TWVudUxpbmtTdHlsZXMoKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8aSBbbmdDbGFzc109XCJpdGVtLmljb25cIj48L2k+XG4gICAgICAgICAgPHNwYW4+e3sgaXRlbS5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgKm5nSWY9XCJpdGVtLmJhZGdlXCJcbiAgICAgICAgICAgIFtuZ1N0eWxlXT1cImdldEJhZGdlU3R5bGVzKGl0ZW0uYmFkZ2UpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiYmFkZ2VcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt7IGl0ZW0uYmFkZ2UuY291bnQgfX1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPGkgW25nQ2xhc3NdPVwiZ2V0Q2hldnJvbkNsYXNzKGl0ZW0pXCIgY2xhc3M9XCJjaGV2cm9uXCI+PC9pPlxuICAgICAgICA8L2E+XG5cbiAgICAgICAgPCEtLSBTdWJtZW51IC0tPlxuICAgICAgICA8dWwgY2xhc3M9XCJzdWJtZW51LWxpc3RcIj5cbiAgICAgICAgICA8bGkgKm5nRm9yPVwibGV0IGNoaWxkIG9mIGl0ZW0uY2hpbGRyZW5cIiBjbGFzcz1cInN1Ym1lbnUtaXRlbVwiPlxuICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgW3JvdXRlckxpbmtdPVwiY2hpbGQudXJsXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJzdWJtZW51LWxpbmtcIlxuICAgICAgICAgICAgICBbbmdTdHlsZV09XCJnZXRTdWJNZW51TGlua1N0eWxlcygpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGkgW25nQ2xhc3NdPVwiY2hpbGQuaWNvblwiPjwvaT5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdWJtZW51LXRpdGxlXCI+e3sgY2hpbGQubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJjaGlsZC5iYWRnZVwiXG4gICAgICAgICAgICAgICAgW25nU3R5bGVdPVwiZ2V0QmFkZ2VTdHlsZXMoY2hpbGQuYmFkZ2UpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImJhZGdlXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IGNoaWxkLmJhZGdlLmNvdW50IH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICA8L3VsPlxuICAgICAgPC9saT5cbiAgICA8L3VsPlxuICA8L3B0LWNhcmQ+XG48L2Rpdj5cbiJdfQ==