@coreui/angular
Version:
CoreUI Components Library for Angular
230 lines • 41.6 kB
JavaScript
import { animate, state, style, transition, trigger } from '@angular/animations';
import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
import { booleanAttribute, Component, ElementRef, forwardRef, HostBinding, Input, Optional, ViewChild } from '@angular/core';
import { NavigationEnd, RouterModule } from '@angular/router';
import { filter } from 'rxjs/operators';
import { SidebarNavHelper } from './sidebar-nav.service';
import { SidebarNavGroupService } from './sidebar-nav-group.service';
import { HtmlAttributesDirective } from '../../shared';
import { SidebarNavIconPipe } from './sidebar-nav-icon.pipe';
import { SidebarNavBadgePipe } from './sidebar-nav-badge.pipe';
import { SidebarNavLinkComponent } from './sidebar-nav-link.component';
import { SidebarNavLabelComponent } from './sidebar-nav-label.component';
import { SidebarNavTitleComponent } from './sidebar-nav-title.component';
import { SidebarNavDividerComponent } from './sidebar-nav-divider.component';
import { SidebarNavItemClassPipe } from './sidebar-nav-item-class.pipe';
import { IconDirective } from '@coreui/icons-angular';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "./sidebar-nav.service";
import * as i3 from "./sidebar-nav-group.service";
import * as i4 from "../sidebar/sidebar.component";
import * as i5 from "../sidebar.service";
export class SidebarNavGroupComponent {
constructor(router, renderer, hostElement, helper, sidebarNavGroupService) {
this.router = router;
this.renderer = renderer;
this.hostElement = hostElement;
this.helper = helper;
this.sidebarNavGroupService = sidebarNavGroupService;
this.dropdownMode = 'path';
this.navItems = [];
this.display = { display: 'block' };
this.navigationEndObservable = router.events.pipe(filter((event) => event instanceof NavigationEnd));
}
get hostClasses() {
return {
'nav-group': true,
show: this.open
};
}
ngOnInit() {
this.navItems = [...this.item.children];
this.navSubscription = this.navigationEndObservable.subscribe((event) => {
if (this.dropdownMode !== 'none') {
const samePath = this.samePath(event.url);
this.openGroup(samePath);
}
});
if (this.samePath(this.router.routerState.snapshot.url)) {
this.openGroup(true);
}
this.navGroupSubscription = this.sidebarNavGroupService.sidebarNavGroupState$.subscribe((next) => {
if (this.dropdownMode === 'close' && next.sidebarNavGroup && next.sidebarNavGroup !== this) {
if (next.sidebarNavGroup.item.url.startsWith(this.item.url)) {
return;
}
if (this.samePath(this.router.routerState.snapshot.url)) {
this.openGroup(true);
return;
}
this.openGroup(false);
}
});
}
samePath(url) {
// console.log('item:', this.item.name, this.item.url, 'url:', url);
const itemArray = this.item.url?.split('/');
const urlArray = url.split('/');
return itemArray?.every((value, index) => {
// console.log(value === urlArray[index], 'value:', value, 'index:', index, urlArray[index], url);
return value === urlArray[index];
});
}
openGroup(open) {
this.open = open;
}
toggleGroup($event) {
$event.preventDefault();
this.openGroup(!this.open);
if (this.open) {
this.sidebarNavGroupService.toggle({ open: this.open, sidebarNavGroup: this });
}
}
ngOnDestroy() {
this.navSubscription?.unsubscribe();
}
onAnimationStart($event) {
this.display = { display: 'block' };
setTimeout(() => {
const host = this.sidebarNav?.nativeElement;
if ($event.toState === 'open' && host) {
this.renderer.setStyle(host, 'height', `${host['scrollHeight']}px`);
}
});
}
onAnimationDone($event) {
setTimeout(() => {
const host = this.sidebarNav?.nativeElement;
if ($event.toState === 'open' && host) {
this.renderer.setStyle(host, 'height', 'auto');
}
if ($event.toState === 'closed') {
setTimeout(() => {
this.display = null;
});
}
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SidebarNavGroupComponent, deps: [{ token: i1.Router }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i2.SidebarNavHelper }, { token: i3.SidebarNavGroupService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: SidebarNavGroupComponent, isStandalone: true, selector: "c-sidebar-nav-group", inputs: { item: "item", dropdownMode: "dropdownMode", show: "show", compact: ["compact", "compact", booleanAttribute] }, host: { properties: { "class": "this.hostClasses" } }, providers: [SidebarNavHelper, SidebarNavGroupService], viewQueries: [{ propertyName: "sidebarNav", first: true, predicate: i0.forwardRef(() => SidebarNavComponent), descendants: true, read: ElementRef }], ngImport: i0, template: "<a (click)=\"toggleGroup($event)\"\n [cHtmlAttr]=\"item.attributes\"\n class=\"nav-link nav-group-toggle\"\n href>\n <ng-container *ngTemplateOutlet=\"iconTemplate ; context: {$implicit: item}\" />\n <ng-container>{{ item.name }}</ng-container>\n @if (helper.hasBadge(item)) {\n <span [ngClass]=\"item | cSidebarNavBadge\">{{ item.badge.text }}</span>\n }\n</a>\n<c-sidebar-nav\n (@openClose.done)=\"onAnimationDone($event)\"\n (@openClose.start)=\"onAnimationStart($event)\"\n [@openClose]=\"open ? 'open' : 'closed'\"\n [compact]=\"compact\"\n [dropdownMode]=\"dropdownMode\"\n [groupItems]=\"true\"\n [navItems]=\"navItems\"\n [ngStyle]=\"display\"\n/>\n\n<ng-template #iconTemplate let-item>\n <!-- <i *ngIf=\"item?.icon\" [ngClass]=\"item | cSidebarNavIcon\"></i>-->\n @if (item?.icon) {\n <span class=\"nav-icon\">\n <span [ngClass]=\"item.icon ?? ''\"></span>\n </span>\n }\n @if (item?.iconComponent) {\n <svg\n [cIcon]=\"item.iconComponent?.content\"\n [customClasses]=\"item | cSidebarNavIcon\"\n [name]=\"item.iconComponent?.name\"\n />\n }\n @if (!item?.icon && !item?.iconComponent) {\n <span [ngClass]=\"item | cSidebarNavIcon\"></span>\n }\n</ng-template>\n", styles: [".nav-group-toggle{cursor:pointer}.nav-group-items{display:block}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(() => HtmlAttributesDirective), selector: "[cHtmlAttr]", inputs: ["cHtmlAttr"], exportAs: ["cHtmlAttr"] }, { kind: "directive", type: i0.forwardRef(() => IconDirective), selector: "svg[cIcon]", inputs: ["cIcon", "customClasses", "size", "title", "height", "width", "name", "viewBox", "xmlns", "pointer-events", "role"], exportAs: ["cIcon"] }, { kind: "directive", type: i0.forwardRef(() => NgTemplateOutlet), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(() => NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i0.forwardRef(() => SidebarNavIconPipe), name: "cSidebarNavIcon" }, { kind: "pipe", type: i0.forwardRef(() => SidebarNavBadgePipe), name: "cSidebarNavBadge" }, { kind: "component", type: i0.forwardRef(() => SidebarNavComponent), selector: "c-sidebar-nav", inputs: ["navItems", "dropdownMode", "groupItems", "compact", "role"] }, { kind: "directive", type: i0.forwardRef(() => NgStyle), selector: "[ngStyle]", inputs: ["ngStyle"] }], animations: [
trigger('openClose', [
state('open', style({
height: '*'
})),
state('closed', style({
height: '0px'
})),
transition('open <=> closed', [animate('.15s ease')])
])
] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SidebarNavGroupComponent, decorators: [{
type: Component,
args: [{ selector: 'c-sidebar-nav-group', providers: [SidebarNavHelper, SidebarNavGroupService], standalone: true, imports: [
HtmlAttributesDirective,
IconDirective,
NgTemplateOutlet,
NgClass,
SidebarNavIconPipe,
SidebarNavBadgePipe,
forwardRef(() => SidebarNavComponent),
NgStyle
], animations: [
trigger('openClose', [
state('open', style({
height: '*'
})),
state('closed', style({
height: '0px'
})),
transition('open <=> closed', [animate('.15s ease')])
])
], template: "<a (click)=\"toggleGroup($event)\"\n [cHtmlAttr]=\"item.attributes\"\n class=\"nav-link nav-group-toggle\"\n href>\n <ng-container *ngTemplateOutlet=\"iconTemplate ; context: {$implicit: item}\" />\n <ng-container>{{ item.name }}</ng-container>\n @if (helper.hasBadge(item)) {\n <span [ngClass]=\"item | cSidebarNavBadge\">{{ item.badge.text }}</span>\n }\n</a>\n<c-sidebar-nav\n (@openClose.done)=\"onAnimationDone($event)\"\n (@openClose.start)=\"onAnimationStart($event)\"\n [@openClose]=\"open ? 'open' : 'closed'\"\n [compact]=\"compact\"\n [dropdownMode]=\"dropdownMode\"\n [groupItems]=\"true\"\n [navItems]=\"navItems\"\n [ngStyle]=\"display\"\n/>\n\n<ng-template #iconTemplate let-item>\n <!-- <i *ngIf=\"item?.icon\" [ngClass]=\"item | cSidebarNavIcon\"></i>-->\n @if (item?.icon) {\n <span class=\"nav-icon\">\n <span [ngClass]=\"item.icon ?? ''\"></span>\n </span>\n }\n @if (item?.iconComponent) {\n <svg\n [cIcon]=\"item.iconComponent?.content\"\n [customClasses]=\"item | cSidebarNavIcon\"\n [name]=\"item.iconComponent?.name\"\n />\n }\n @if (!item?.icon && !item?.iconComponent) {\n <span [ngClass]=\"item | cSidebarNavIcon\"></span>\n }\n</ng-template>\n", styles: [".nav-group-toggle{cursor:pointer}.nav-group-items{display:block}\n"] }]
}], ctorParameters: () => [{ type: i1.Router }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i2.SidebarNavHelper }, { type: i3.SidebarNavGroupService }], propDecorators: { item: [{
type: Input
}], dropdownMode: [{
type: Input
}], show: [{
type: Input
}], compact: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], hostClasses: [{
type: HostBinding,
args: ['class']
}], sidebarNav: [{
type: ViewChild,
args: [forwardRef(() => SidebarNavComponent), { read: ElementRef }]
}] } });
export class SidebarNavComponent {
constructor(sidebar, helper, router, renderer, hostElement, sidebarService) {
this.sidebar = sidebar;
this.helper = helper;
this.router = router;
this.renderer = renderer;
this.hostElement = hostElement;
this.sidebarService = sidebarService;
this.navItems = [];
this.dropdownMode = 'path';
// @HostBinding('class.nav-group-items')
// get sidebarNavGroupItemsClass(): boolean {
// return !!this.groupItems;
// }
this.role = 'navigation';
this.navItemsArray = [];
}
get hostClasses() {
return {
'sidebar-nav': !this.groupItems,
'nav-group-items': this.groupItems,
compact: this.groupItems && this.compact
};
}
ngOnChanges(changes) {
this.navItemsArray = Array.isArray(this.navItems) ? this.navItems.slice() : [];
}
hideMobile() {
// todo: proper scrollIntoView() after NavigationEnd
if (this.sidebar && this.sidebar.sidebarState.mobile) {
this.sidebarService.toggle({ toggle: 'visible', sidebar: this.sidebar });
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SidebarNavComponent, deps: [{ token: i4.SidebarComponent, optional: true }, { token: i2.SidebarNavHelper }, { token: i1.Router }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i5.SidebarService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: SidebarNavComponent, isStandalone: true, selector: "c-sidebar-nav", inputs: { navItems: "navItems", dropdownMode: "dropdownMode", groupItems: ["groupItems", "groupItems", booleanAttribute], compact: ["compact", "compact", booleanAttribute], role: "role" }, host: { properties: { "class": "this.hostClasses", "attr.role": "this.role" } }, usesOnChanges: true, ngImport: i0, template: "@for (item of navItemsArray; track item) {\n @switch (helper.itemType(item)) {\n @case ('group') {\n <c-sidebar-nav-group\n #rla=\"routerLinkActive\"\n [dropdownMode]=\"dropdownMode\"\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n [routerLinkActiveOptions]=\"{exact: true}\"\n routerLinkActive=\"show\"\n [compact]=\"compact\"\n />\n }\n @case ('divider') {\n <c-sidebar-nav-divider\n [cHtmlAttr]=\"item.attributes ?? {}\"\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n />\n }\n @case ('title') {\n <c-sidebar-nav-title\n [cHtmlAttr]=\"item.attributes ?? {}\"\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n />\n }\n @case ('label') {\n <c-sidebar-nav-label\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n />\n }\n @case ('empty') {\n <ng-container />\n }\n @default {\n <c-sidebar-nav-link\n (linkClick)=\"hideMobile()\"\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n />\n }\n }\n}\n<ng-content />\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: HtmlAttributesDirective, selector: "[cHtmlAttr]", inputs: ["cHtmlAttr"], exportAs: ["cHtmlAttr"] }, { kind: "component", type: SidebarNavLinkComponent, selector: "c-sidebar-nav-link", inputs: ["item"], outputs: ["linkClick"] }, { kind: "component", type: SidebarNavLabelComponent, selector: "c-sidebar-nav-label", inputs: ["item"] }, { kind: "component", type: SidebarNavTitleComponent, selector: "c-sidebar-nav-title", inputs: ["item"] }, { kind: "component", type: SidebarNavDividerComponent, selector: "c-sidebar-nav-divider", inputs: ["item"] }, { kind: "component", type: SidebarNavGroupComponent, selector: "c-sidebar-nav-group", inputs: ["item", "dropdownMode", "show", "compact"] }, { kind: "pipe", type: SidebarNavItemClassPipe, name: "cSidebarNavItemClass" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SidebarNavComponent, decorators: [{
type: Component,
args: [{ selector: 'c-sidebar-nav', standalone: true, imports: [
NgClass,
HtmlAttributesDirective,
SidebarNavLinkComponent,
SidebarNavLabelComponent,
SidebarNavTitleComponent,
SidebarNavDividerComponent,
SidebarNavGroupComponent,
SidebarNavItemClassPipe,
RouterModule
], template: "@for (item of navItemsArray; track item) {\n @switch (helper.itemType(item)) {\n @case ('group') {\n <c-sidebar-nav-group\n #rla=\"routerLinkActive\"\n [dropdownMode]=\"dropdownMode\"\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n [routerLinkActiveOptions]=\"{exact: true}\"\n routerLinkActive=\"show\"\n [compact]=\"compact\"\n />\n }\n @case ('divider') {\n <c-sidebar-nav-divider\n [cHtmlAttr]=\"item.attributes ?? {}\"\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n />\n }\n @case ('title') {\n <c-sidebar-nav-title\n [cHtmlAttr]=\"item.attributes ?? {}\"\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n />\n }\n @case ('label') {\n <c-sidebar-nav-label\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n />\n }\n @case ('empty') {\n <ng-container />\n }\n @default {\n <c-sidebar-nav-link\n (linkClick)=\"hideMobile()\"\n [item]=\"item\"\n [ngClass]=\"item | cSidebarNavItemClass\"\n />\n }\n }\n}\n<ng-content />\n" }]
}], ctorParameters: () => [{ type: i4.SidebarComponent, decorators: [{
type: Optional
}] }, { type: i2.SidebarNavHelper }, { type: i1.Router }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i5.SidebarService }], propDecorators: { navItems: [{
type: Input
}], dropdownMode: [{
type: Input
}], groupItems: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], compact: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], hostClasses: [{
type: HostBinding,
args: ['class']
}], role: [{
type: HostBinding,
args: ['attr.role']
}, {
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lkZWJhci1uYXYuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29yZXVpLWFuZ3VsYXIvc3JjL2xpYi9zaWRlYmFyL3NpZGViYXItbmF2L3NpZGViYXItbmF2LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmV1aS1hbmd1bGFyL3NyYy9saWIvc2lkZWJhci9zaWRlYmFyLW5hdi9zaWRlYmFyLW5hdi1ncm91cC5jb21wb25lbnQuaHRtbCIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmV1aS1hbmd1bGFyL3NyYy9saWIvc2lkZWJhci9zaWRlYmFyLW5hdi9zaWRlYmFyLW5hdi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFrQixLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRyxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JFLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsU0FBUyxFQUNULFVBQVUsRUFDVixVQUFVLEVBQ1YsV0FBVyxFQUNYLEtBQUssRUFJTCxRQUFRLEVBR1IsU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxhQUFhLEVBQVUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFdEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBS3hDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3JFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN2RCxPQUFP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bnQsIHN0YXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgTmdDbGFzcywgTmdTdHlsZSwgTmdUZW1wbGF0ZU91dGxldCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBib29sZWFuQXR0cmlidXRlLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIGZvcndhcmRSZWYsXG4gIEhvc3RCaW5kaW5nLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIFJlbmRlcmVyMixcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmF2aWdhdGlvbkVuZCwgUm91dGVyLCBSb3V0ZXJNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFNpZGViYXJTZXJ2aWNlIH0gZnJvbSAnLi4vc2lkZWJhci5zZXJ2aWNlJztcbmltcG9ydCB7IFNpZGViYXJDb21wb25lbnQgfSBmcm9tICcuLi9zaWRlYmFyL3NpZGViYXIuY29tcG9uZW50JztcbmltcG9ydCB7IElOYXZEYXRhIH0gZnJvbSAnLi9zaWRlYmFyLW5hdic7XG5pbXBvcnQgeyBTaWRlYmFyTmF2SGVscGVyIH0gZnJvbSAnLi9zaWRlYmFyLW5hdi5zZXJ2aWNlJztcbmltcG9ydCB7IFNpZGViYXJOYXZHcm91cFNlcnZpY2UgfSBmcm9tICcuL3NpZGViYXItbmF2LWdyb3VwLnNlcnZpY2UnO1xuaW1wb3J0IHsgSHRtbEF0dHJpYnV0ZXNEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuaW1wb3J0IHsgU2lkZWJhck5hdkljb25QaXBlIH0gZnJvbSAnLi9zaWRlYmFyLW5hdi1pY29uLnBpcGUnO1xuaW1wb3J0IHsgU2lkZWJhck5hdkJhZGdlUGlwZSB9IGZyb20gJy4vc2lkZWJhci1uYXYtYmFkZ2UucGlwZSc7XG5pbXBvcnQgeyBTaWRlYmFyTmF2TGlua0NvbXBvbmVudCB9IGZyb20gJy4vc2lkZWJhci1uYXYtbGluay5jb21wb25lbnQnO1xuaW1wb3J0IHsgU2lkZWJhck5hdkxhYmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zaWRlYmFyLW5hdi1sYWJlbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgU2lkZWJhck5hdlRpdGxlQ29tcG9uZW50IH0gZnJvbSAnLi9zaWRlYmFyLW5hdi10aXRsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgU2lkZWJhck5hdkRpdmlkZXJDb21wb25lbnQgfSBmcm9tICcuL3NpZGViYXItbmF2LWRpdmlkZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFNpZGViYXJOYXZJdGVtQ2xhc3NQaXBlIH0gZnJvbSAnLi9zaWRlYmFyLW5hdi1pdGVtLWNsYXNzLnBpcGUnO1xuaW1wb3J0IHsgSWNvbkRpcmVjdGl2ZSB9IGZyb20gJ0Bjb3JldWkvaWNvbnMtYW5ndWxhcic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2Mtc2lkZWJhci1uYXYtZ3JvdXAnLFxuICB0ZW1wbGF0ZVVybDogJy4vc2lkZWJhci1uYXYtZ3JvdXAuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zaWRlYmFyLW5hdi1ncm91cC5jb21wb25lbnQuc2NzcyddLFxuICBwcm92aWRlcnM6IFtTaWRlYmFyTmF2SGVscGVyLCBTaWRlYmFyTmF2R3JvdXBTZXJ2aWNlXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIEh0bWxBdHRyaWJ1dGVzRGlyZWN0aXZlLFxuICAgIEljb25EaXJlY3RpdmUsXG4gICAgTmdUZW1wbGF0ZU91dGxldCxcbiAgICBOZ0NsYXNzLFxuICAgIFNpZGViYXJOYXZJY29uUGlwZSxcbiAgICBTaWRlYmFyTmF2QmFkZ2VQaXBlLFxuICAgIGZvcndhcmRSZWYoKCkgPT4gU2lkZWJhck5hdkNvbXBvbmVudCksXG4gICAgTmdTdHlsZVxuICBdLFxuICBhbmltYXRpb25zOiBbXG4gICAgdHJpZ2dlcignb3BlbkNsb3NlJywgW1xuICAgICAgc3RhdGUoXG4gICAgICAgICdvcGVuJyxcbiAgICAgICAgc3R5bGUoe1xuICAgICAgICAgIGhlaWdodDogJyonXG4gICAgICAgIH0pXG4gICAgICApLFxuICAgICAgc3RhdGUoXG4gICAgICAgICdjbG9zZWQnLFxuICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgaGVpZ2h0OiAnMHB4J1xuICAgICAgICB9KVxuICAgICAgKSxcbiAgICAgIHRyYW5zaXRpb24oJ29wZW4gPD0+IGNsb3NlZCcsIFthbmltYXRlKCcuMTVzIGVhc2UnKV0pXG4gICAgXSlcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBTaWRlYmFyTmF2R3JvdXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgaG9zdEVsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgcHVibGljIGhlbHBlcjogU2lkZWJhck5hdkhlbHBlcixcbiAgICBwcml2YXRlIHNpZGViYXJOYXZHcm91cFNlcnZpY2U6IFNpZGViYXJOYXZHcm91cFNlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5uYXZpZ2F0aW9uRW5kT2JzZXJ2YWJsZSA9IHJvdXRlci5ldmVudHMucGlwZShcbiAgICAgIGZpbHRlcigoZXZlbnQ6IGFueSkgPT4gZXZlbnQgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRW5kKVxuICAgICkgYXMgT2JzZXJ2YWJsZTxOYXZpZ2F0aW9uRW5kPjtcbiAgfVxuXG4gIEBJbnB1dCgpIGl0ZW06IGFueTtcbiAgQElucHV0KCkgZHJvcGRvd25Nb2RlOiAncGF0aCcgfCAnbm9uZScgfCAnY2xvc2UnID0gJ3BhdGgnO1xuICBASW5wdXQoKSBzaG93PzogYm9vbGVhbjtcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIGNvbXBhY3Q/OiBib29sZWFuO1xuXG4gIEBIb3N0QmluZGluZygnY2xhc3MnKVxuICBnZXQgaG9zdENsYXNzZXMoKTogYW55IHtcbiAgICByZXR1cm4ge1xuICAgICAgJ25hdi1ncm91cCc6IHRydWUsXG4gICAgICBzaG93OiB0aGlzLm9wZW5cbiAgICB9O1xuICB9XG5cbiAgQFZpZXdDaGlsZChmb3J3YXJkUmVmKCgpID0+IFNpZGViYXJOYXZDb21wb25lbnQpLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSkgc2lkZWJhck5hdiE6IEVsZW1lbnRSZWY7XG5cbiAgbmF2aWdhdGlvbkVuZE9ic2VydmFibGU6IE9ic2VydmFibGU8TmF2aWdhdGlvbkVuZD47XG4gIG5hdlN1YnNjcmlwdGlvbiE6IFN1YnNjcmlwdGlvbjtcbiAgbmF2R3JvdXBTdWJzY3JpcHRpb24hOiBTdWJzY3JpcHRpb247XG5cbiAgcHVibGljIG9wZW4hOiBib29sZWFuO1xuICBwdWJsaWMgbmF2SXRlbXM6IElOYXZEYXRhW10gPSBbXTtcbiAgcHVibGljIGRpc3BsYXk6IGFueSA9IHsgZGlzcGxheTogJ2Jsb2NrJyB9O1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubmF2SXRlbXMgPSBbLi4udGhpcy5pdGVtLmNoaWxkcmVuXTtcblxuICAgIHRoaXMubmF2U3Vic2NyaXB0aW9uID0gdGhpcy5uYXZpZ2F0aW9uRW5kT2JzZXJ2YWJsZS5zdWJzY3JpYmUoKGV2ZW50OiBOYXZpZ2F0aW9uRW5kKSA9PiB7XG4gICAgICBpZiAodGhpcy5kcm9wZG93bk1vZGUgIT09ICdub25lJykge1xuICAgICAgICBjb25zdCBzYW1lUGF0aCA9IHRoaXMuc2FtZVBhdGgoZXZlbnQudXJsKTtcbiAgICAgICAgdGhpcy5vcGVuR3JvdXAoc2FtZVBhdGgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuc2FtZVBhdGgodGhpcy5yb3V0ZXIucm91dGVyU3RhdGUuc25hcHNob3QudXJsKSkge1xuICAgICAgdGhpcy5vcGVuR3JvdXAodHJ1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5uYXZHcm91cFN1YnNjcmlwdGlvbiA9IHRoaXMuc2lkZWJhck5hdkdyb3VwU2VydmljZS5zaWRlYmFyTmF2R3JvdXBTdGF0ZSQuc3Vic2NyaWJlKChuZXh0KSA9PiB7XG4gICAgICBpZiAodGhpcy5kcm9wZG93bk1vZGUgPT09ICdjbG9zZScgJiYgbmV4dC5zaWRlYmFyTmF2R3JvdXAgJiYgbmV4dC5zaWRlYmFyTmF2R3JvdXAgIT09IHRoaXMpIHtcbiAgICAgICAgaWYgKG5leHQuc2lkZWJhck5hdkdyb3VwLml0ZW0udXJsLnN0YXJ0c1dpdGgodGhpcy5pdGVtLnVybCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc2FtZVBhdGgodGhpcy5yb3V0ZXIucm91dGVyU3RhdGUuc25hcHNob3QudXJsKSkge1xuICAgICAgICAgIHRoaXMub3Blbkdyb3VwKHRydWUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wZW5Hcm91cChmYWxzZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzYW1lUGF0aCh1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIC8vIGNvbnNvbGUubG9nKCdpdGVtOicsIHRoaXMuaXRlbS5uYW1lLCB0aGlzLml0ZW0udXJsLCAndXJsOicsIHVybCk7XG4gICAgY29uc3QgaXRlbUFycmF5ID0gdGhpcy5pdGVtLnVybD8uc3BsaXQoJy8nKTtcbiAgICBjb25zdCB1cmxBcnJheSA9IHVybC5zcGxpdCgnLycpO1xuICAgIHJldHVybiBpdGVtQXJyYXk/LmV2ZXJ5KCh2YWx1ZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAvLyBjb25zb2xlLmxvZyh2YWx1ZSA9PT0gdXJsQXJyYXlbaW5kZXhdLCAndmFsdWU6JywgdmFsdWUsICdpbmRleDonLCBpbmRleCwgdXJsQXJyYXlbaW5kZXhdLCB1cmwpO1xuICAgICAgcmV0dXJuIHZhbHVlID09PSB1cmxBcnJheVtpbmRleF07XG4gICAgfSk7XG4gIH1cblxuICBvcGVuR3JvdXAob3BlbjogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMub3BlbiA9IG9wZW47XG4gIH1cblxuICB0b2dnbGVHcm91cCgkZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgICRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMub3Blbkdyb3VwKCF0aGlzLm9wZW4pO1xuICAgIGlmICh0aGlzLm9wZW4pIHtcbiAgICAgIHRoaXMuc2lkZWJhck5hdkdyb3VwU2VydmljZS50b2dnbGUoeyBvcGVuOiB0aGlzLm9wZW4sIHNpZGViYXJOYXZHcm91cDogdGhpcyB9KTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLm5hdlN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIG9uQW5pbWF0aW9uU3RhcnQoJGV2ZW50OiBBbmltYXRpb25FdmVudCkge1xuICAgIHRoaXMuZGlzcGxheSA9IHsgZGlzcGxheTogJ2Jsb2NrJyB9O1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY29uc3QgaG9zdCA9IHRoaXMuc2lkZWJhck5hdj8ubmF0aXZlRWxlbWVudDtcbiAgICAgIGlmICgkZXZlbnQudG9TdGF0ZSA9PT0gJ29wZW4nICYmIGhvc3QpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShob3N0LCAnaGVpZ2h0JywgYCR7aG9zdFsnc2Nyb2xsSGVpZ2h0J119cHhgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG9uQW5pbWF0aW9uRG9uZSgkZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCBob3N0ID0gdGhpcy5zaWRlYmFyTmF2Py5uYXRpdmVFbGVtZW50O1xuICAgICAgaWYgKCRldmVudC50b1N0YXRlID09PSAnb3BlbicgJiYgaG9zdCkge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKGhvc3QsICdoZWlnaHQnLCAnYXV0bycpO1xuICAgICAgfVxuICAgICAgaWYgKCRldmVudC50b1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLmRpc3BsYXkgPSBudWxsO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjLXNpZGViYXItbmF2JyxcbiAgdGVtcGxhdGVVcmw6ICcuL3NpZGViYXItbmF2LmNvbXBvbmVudC5odG1sJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE5nQ2xhc3MsXG4gICAgSHRtbEF0dHJpYnV0ZXNEaXJlY3RpdmUsXG4gICAgU2lkZWJhck5hdkxpbmtDb21wb25lbnQsXG4gICAgU2lkZWJhck5hdkxhYmVsQ29tcG9uZW50LFxuICAgIFNpZGViYXJOYXZUaXRsZUNvbXBvbmVudCxcbiAgICBTaWRlYmFyTmF2RGl2aWRlckNvbXBvbmVudCxcbiAgICBTaWRlYmFyTmF2R3JvdXBDb21wb25lbnQsXG4gICAgU2lkZWJhck5hdkl0ZW1DbGFzc1BpcGUsXG4gICAgUm91dGVyTW9kdWxlXG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgU2lkZWJhck5hdkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIEBPcHRpb25hbCgpIHB1YmxpYyBzaWRlYmFyOiBTaWRlYmFyQ29tcG9uZW50LFxuICAgIHB1YmxpYyBoZWxwZXI6IFNpZGViYXJOYXZIZWxwZXIsXG4gICAgcHVibGljIHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIGhvc3RFbGVtZW50OiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgc2lkZWJhclNlcnZpY2U6IFNpZGViYXJTZXJ2aWNlXG4gICkge31cblxuICBASW5wdXQoKSBuYXZJdGVtcz86IElOYXZEYXRhW10gPSBbXTtcbiAgQElucHV0KCkgZHJvcGRvd25Nb2RlOiAncGF0aCcgfCAnbm9uZScgfCAnY2xvc2UnID0gJ3BhdGgnO1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgZ3JvdXBJdGVtcz86IGJvb2xlYW47XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBjb21wYWN0PzogYm9vbGVhbjtcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzJylcbiAgZ2V0IGhvc3RDbGFzc2VzKCk6IGFueSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdzaWRlYmFyLW5hdic6ICF0aGlzLmdyb3VwSXRlbXMsXG4gICAgICAnbmF2LWdyb3VwLWl0ZW1zJzogdGhpcy5ncm91cEl0ZW1zLFxuICAgICAgY29tcGFjdDogdGhpcy5ncm91cEl0ZW1zICYmIHRoaXMuY29tcGFjdFxuICAgIH07XG4gIH1cblxuICAvLyBASG9zdEJpbmRpbmcoJ2NsYXNzLm5hdi1ncm91cC1pdGVtcycpXG4gIC8vIGdldCBzaWRlYmFyTmF2R3JvdXBJdGVtc0NsYXNzKCk6IGJvb2xlYW4ge1xuICAvLyAgIHJldHVybiAhIXRoaXMuZ3JvdXBJdGVtcztcbiAgLy8gfVxuXG4gIEBIb3N0QmluZGluZygnYXR0ci5yb2xlJylcbiAgQElucHV0KClcbiAgcm9sZSA9ICduYXZpZ2F0aW9uJztcblxuICBwdWJsaWMgbmF2SXRlbXNBcnJheTogSU5hdkRhdGFbXSA9IFtdO1xuXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgdGhpcy5uYXZJdGVtc0FycmF5ID0gQXJyYXkuaXNBcnJheSh0aGlzLm5hdkl0ZW1zKSA/IHRoaXMubmF2SXRlbXMuc2xpY2UoKSA6IFtdO1xuICB9XG5cbiAgcHVibGljIGhpZGVNb2JpbGUoKTogdm9pZCB7XG4gICAgLy8gdG9kbzogcHJvcGVyIHNjcm9sbEludG9WaWV3KCkgYWZ0ZXIgTmF2aWdhdGlvbkVuZFxuICAgIGlmICh0aGlzLnNpZGViYXIgJiYgdGhpcy5zaWRlYmFyLnNpZGViYXJTdGF0ZS5tb2JpbGUpIHtcbiAgICAgIHRoaXMuc2lkZWJhclNlcnZpY2UudG9nZ2xlKHsgdG9nZ2xlOiAndmlzaWJsZScsIHNpZGViYXI6IHRoaXMuc2lkZWJhciB9KTtcbiAgICB9XG4gIH1cbn1cbiIsIjxhIChjbGljayk9XCJ0b2dnbGVHcm91cCgkZXZlbnQpXCJcbiAgIFtjSHRtbEF0dHJdPVwiaXRlbS5hdHRyaWJ1dGVzXCJcbiAgIGNsYXNzPVwibmF2LWxpbmsgbmF2LWdyb3VwLXRvZ2dsZVwiXG4gICBocmVmPlxuICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaWNvblRlbXBsYXRlIDsgY29udGV4dDogeyRpbXBsaWNpdDogaXRlbX1cIiAvPlxuICA8bmctY29udGFpbmVyPnt7IGl0ZW0ubmFtZSB9fTwvbmctY29udGFpbmVyPlxuICBAaWYgKGhlbHBlci5oYXNCYWRnZShpdGVtKSkge1xuICAgIDxzcGFuIFtuZ0NsYXNzXT1cIml0ZW0gfCBjU2lkZWJhck5hdkJhZGdlXCI+e3sgaXRlbS5iYWRnZS50ZXh0IH19PC9zcGFuPlxuICB9XG48L2E+XG48Yy1zaWRlYmFyLW5hdlxuICAoQG9wZW5DbG9zZS5kb25lKT1cIm9uQW5pbWF0aW9uRG9uZSgkZXZlbnQpXCJcbiAgKEBvcGVuQ2xvc2Uuc3RhcnQpPVwib25BbmltYXRpb25TdGFydCgkZXZlbnQpXCJcbiAgW0BvcGVuQ2xvc2VdPVwib3BlbiA/ICdvcGVuJyA6ICdjbG9zZWQnXCJcbiAgW2NvbXBhY3RdPVwiY29tcGFjdFwiXG4gIFtkcm9wZG93bk1vZGVdPVwiZHJvcGRvd25Nb2RlXCJcbiAgW2dyb3VwSXRlbXNdPVwidHJ1ZVwiXG4gIFtuYXZJdGVtc109XCJuYXZJdGVtc1wiXG4gIFtuZ1N0eWxlXT1cImRpc3BsYXlcIlxuLz5cblxuPG5nLXRlbXBsYXRlICNpY29uVGVtcGxhdGUgbGV0LWl0ZW0+XG4gIDwhLS0gIDxpICpuZ0lmPVwiaXRlbT8uaWNvblwiIFtuZ0NsYXNzXT1cIml0ZW0gfCBjU2lkZWJhck5hdkljb25cIj48L2k+LS0+XG4gIEBpZiAoaXRlbT8uaWNvbikge1xuICAgIDxzcGFuIGNsYXNzPVwibmF2LWljb25cIj5cbiAgICA8c3BhbiBbbmdDbGFzc109XCJpdGVtLmljb24gPz8gJydcIj48L3NwYW4+XG4gIDwvc3Bhbj5cbiAgfVxuICBAaWYgKGl0ZW0/Lmljb25Db21wb25lbnQpIHtcbiAgICA8c3ZnXG4gICAgICBbY0ljb25dPVwiaXRlbS5pY29uQ29tcG9uZW50Py5jb250ZW50XCJcbiAgICAgIFtjdXN0b21DbGFzc2VzXT1cIml0ZW0gfCBjU2lkZWJhck5hdkljb25cIlxuICAgICAgW25hbWVdPVwiaXRlbS5pY29uQ29tcG9uZW50Py5uYW1lXCJcbiAgICAvPlxuICB9XG4gIEBpZiAoIWl0ZW0/Lmljb24gJiYgIWl0ZW0/Lmljb25Db21wb25lbnQpIHtcbiAgICA8c3BhbiBbbmdDbGFzc109XCJpdGVtIHwgY1NpZGViYXJOYXZJY29uXCI+PC9zcGFuPlxuICB9XG48L25nLXRlbXBsYXRlPlxuIiwiQGZvciAoaXRlbSBvZiBuYXZJdGVtc0FycmF5OyB0cmFjayBpdGVtKSB7XG4gIEBzd2l0Y2ggKGhlbHBlci5pdGVtVHlwZShpdGVtKSkge1xuICAgIEBjYXNlICgnZ3JvdXAnKSB7XG4gICAgICA8Yy1zaWRlYmFyLW5hdi1ncm91cFxuICAgICAgICAjcmxhPVwicm91dGVyTGlua0FjdGl2ZVwiXG4gICAgICAgIFtkcm9wZG93bk1vZGVdPVwiZHJvcGRvd25Nb2RlXCJcbiAgICAgICAgW2l0ZW1dPVwiaXRlbVwiXG4gICAgICAgIFtuZ0NsYXNzXT1cIml0ZW0gfCBjU2lkZWJhck5hdkl0ZW1DbGFzc1wiXG4gICAgICAgIFtyb3V0ZXJMaW5rQWN0aXZlT3B0aW9uc109XCJ7ZXhhY3Q6IHRydWV9XCJcbiAgICAgICAgcm91dGVyTGlua0FjdGl2ZT1cInNob3dcIlxuICAgICAgICBbY29tcGFjdF09XCJjb21wYWN0XCJcbiAgICAgIC8+XG4gICAgfVxuICAgIEBjYXNlICgnZGl2aWRlcicpIHtcbiAgICAgIDxjLXNpZGViYXItbmF2LWRpdmlkZXJcbiAgICAgICAgW2NIdG1sQXR0cl09XCJpdGVtLmF0dHJpYnV0ZXMgPz8ge31cIlxuICAgICAgICBbaXRlbV09XCJpdGVtXCJcbiAgICAgICAgW25nQ2xhc3NdPVwiaXRlbSB8IGNTaWRlYmFyTmF2SXRlbUNsYXNzXCJcbiAgICAgIC8+XG4gICAgfVxuICAgIEBjYXNlICgndGl0bGUnKSB7XG4gICAgICA8Yy1zaWRlYmFyLW5hdi10aXRsZVxuICAgICAgICBbY0h0bWxBdHRyXT1cIml0ZW0uYXR0cmlidXRlcyA/PyB7fVwiXG4gICAgICAgIFtpdGVtXT1cIml0ZW1cIlxuICAgICAgICBbbmdDbGFzc109XCJpdGVtIHwgY1NpZGViYXJOYXZJdGVtQ2xhc3NcIlxuICAgICAgLz5cbiAgICB9XG4gICAgQGNhc2UgKCdsYWJlbCcpIHtcbiAgICAgIDxjLXNpZGViYXItbmF2LWxhYmVsXG4gICAgICAgIFtpdGVtXT1cIml0ZW1cIlxuICAgICAgICBbbmdDbGFzc109XCJpdGVtIHwgY1NpZGViYXJOYXZJdGVtQ2xhc3NcIlxuICAgICAgLz5cbiAgICB9XG4gICAgQGNhc2UgKCdlbXB0eScpIHtcbiAgICAgIDxuZy1jb250YWluZXIgLz5cbiAgICB9XG4gICAgQGRlZmF1bHQge1xuICAgICAgPGMtc2lkZWJhci1uYXYtbGlua1xuICAgICAgICAobGlua0NsaWNrKT1cImhpZGVNb2JpbGUoKVwiXG4gICAgICAgIFtpdGVtXT1cIml0ZW1cIlxuICAgICAgICBbbmdDbGFzc109XCJpdGVtIHwgY1NpZGViYXJOYXZJdGVtQ2xhc3NcIlxuICAgICAgLz5cbiAgICB9XG4gIH1cbn1cbjxuZy1jb250ZW50IC8+XG4iXX0=