@coreui/angular
Version:
CoreUI for Angular UI components library
175 lines • 32.9 kB
JavaScript
import { Component, HostBinding, Input, Optional } from '@angular/core';
import { NavigationEnd } from '@angular/router';
import { SidebarNavHelper } from './sidebar-nav.service';
import { filter } from 'rxjs/operators';
import { animate, state, style, transition, trigger } from '@angular/animations';
import * as i0 from "@angular/core";
import * as i1 from "../sidebar/sidebar.component";
import * as i2 from "./sidebar-nav.service";
import * as i3 from "@angular/router";
import * as i4 from "../sidebar.service";
import * as i5 from "@angular/common";
import * as i6 from "../../shared/html-attr.directive";
import * as i7 from "./sidebar-nav-divider.component";
import * as i8 from "./sidebar-nav-label.component";
import * as i9 from "./sidebar-nav-link.component";
import * as i10 from "./sidebar-nav-title.component";
import * as i11 from "./sidebar-nav-item-class.pipe";
import * as i12 from "@coreui/icons-angular";
import * as i13 from "./sidebar-nav-badge.pipe";
import * as i14 from "./sidebar-nav-icon.pipe";
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 = 'closeInactive';
this.role = 'nav';
this.navItemsArray = [];
}
get hostClasses() {
return {
'sidebar-nav': !this.groupItems,
compact: !this.groupItems && !!this.compact
};
}
get sidebarNavGroupItemsClass() {
return !!this.groupItems;
}
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 });
}
}
}
SidebarNavComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: SidebarNavComponent, deps: [{ token: i1.SidebarComponent, optional: true }, { token: i2.SidebarNavHelper }, { token: i3.Router }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i4.SidebarService }], target: i0.ɵɵFactoryTarget.Component });
SidebarNavComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: SidebarNavComponent, selector: "c-sidebar-nav", inputs: { navItems: "navItems", dropdownMode: "dropdownMode", groupItems: "groupItems", compact: "compact" }, host: { properties: { "class": "this.hostClasses", "class.nav-group-items": "this.sidebarNavGroupItemsClass", "attr.role": "this.role" } }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngFor=\"let item of navItemsArray\">\r\n <ng-container [ngSwitch]=\"helper.itemType(item)\">\r\n <c-sidebar-nav-group\r\n *ngSwitchCase=\"'group'\"\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\"\r\n routerLinkActive=\"show\"\r\n #rla=\"routerLinkActive\"\r\n [routerLinkActiveOptions]=\"{exact: true}\"\r\n >\r\n </c-sidebar-nav-group>\r\n <c-sidebar-nav-divider\r\n *ngSwitchCase=\"'divider'\"\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\"\r\n [cHtmlAttr]=\"item.attributes ?? {}\">\r\n </c-sidebar-nav-divider>\r\n <c-sidebar-nav-title\r\n *ngSwitchCase=\"'title'\"\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\"\r\n [cHtmlAttr]=\"item.attributes ?? {}\">\r\n </c-sidebar-nav-title>\r\n <c-sidebar-nav-label\r\n *ngSwitchCase=\"'label'\"\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\">\r\n </c-sidebar-nav-label>\r\n <ng-container\r\n *ngSwitchCase=\"'empty'\">\r\n </ng-container>\r\n <c-sidebar-nav-link\r\n *ngSwitchDefault\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\"\r\n (linkClick)=\"hideMobile()\"\r\n >\r\n </c-sidebar-nav-link>\r\n </ng-container>\r\n</ng-container>\r\n<ng-content></ng-content>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i5.NgClass; }), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(function () { return i5.NgForOf; }), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i0.forwardRef(function () { return i5.NgSwitch; }), selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i0.forwardRef(function () { return i5.NgSwitchCase; }), selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i0.forwardRef(function () { return i5.NgSwitchDefault; }), selector: "[ngSwitchDefault]" }, { kind: "directive", type: i0.forwardRef(function () { return i3.RouterLinkActive; }), selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: i0.forwardRef(function () { return i6.HtmlAttributesDirective; }), selector: "[cHtmlAttr]", inputs: ["cHtmlAttr"], exportAs: ["cHtmlAttr"] }, { kind: "component", type: i0.forwardRef(function () { return i7.SidebarNavDividerComponent; }), selector: "c-sidebar-nav-divider", inputs: ["item"] }, { kind: "component", type: i0.forwardRef(function () { return SidebarNavGroupComponent; }), selector: "c-sidebar-nav-group", inputs: ["item", "dropdownMode", "show"] }, { kind: "component", type: i0.forwardRef(function () { return i8.SidebarNavLabelComponent; }), selector: "c-sidebar-nav-label", inputs: ["item"] }, { kind: "component", type: i0.forwardRef(function () { return i9.SidebarNavLinkComponent; }), selector: "c-sidebar-nav-link", inputs: ["item"], outputs: ["linkClick"] }, { kind: "component", type: i0.forwardRef(function () { return i10.SidebarNavTitleComponent; }), selector: "c-sidebar-nav-title", inputs: ["item"] }, { kind: "pipe", type: i0.forwardRef(function () { return i11.SidebarNavItemClassPipe; }), name: "cSidebarNavItemClass" }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: SidebarNavComponent, decorators: [{
type: Component,
args: [{ selector: 'c-sidebar-nav', template: "<ng-container *ngFor=\"let item of navItemsArray\">\r\n <ng-container [ngSwitch]=\"helper.itemType(item)\">\r\n <c-sidebar-nav-group\r\n *ngSwitchCase=\"'group'\"\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\"\r\n routerLinkActive=\"show\"\r\n #rla=\"routerLinkActive\"\r\n [routerLinkActiveOptions]=\"{exact: true}\"\r\n >\r\n </c-sidebar-nav-group>\r\n <c-sidebar-nav-divider\r\n *ngSwitchCase=\"'divider'\"\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\"\r\n [cHtmlAttr]=\"item.attributes ?? {}\">\r\n </c-sidebar-nav-divider>\r\n <c-sidebar-nav-title\r\n *ngSwitchCase=\"'title'\"\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\"\r\n [cHtmlAttr]=\"item.attributes ?? {}\">\r\n </c-sidebar-nav-title>\r\n <c-sidebar-nav-label\r\n *ngSwitchCase=\"'label'\"\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\">\r\n </c-sidebar-nav-label>\r\n <ng-container\r\n *ngSwitchCase=\"'empty'\">\r\n </ng-container>\r\n <c-sidebar-nav-link\r\n *ngSwitchDefault\r\n [item]=\"item\"\r\n [ngClass]=\"item | cSidebarNavItemClass\"\r\n (linkClick)=\"hideMobile()\"\r\n >\r\n </c-sidebar-nav-link>\r\n </ng-container>\r\n</ng-container>\r\n<ng-content></ng-content>\r\n" }]
}], ctorParameters: function () { return [{ type: i1.SidebarComponent, decorators: [{
type: Optional
}] }, { type: i2.SidebarNavHelper }, { type: i3.Router }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i4.SidebarService }]; }, propDecorators: { navItems: [{
type: Input
}], dropdownMode: [{
type: Input
}], groupItems: [{
type: Input
}], compact: [{
type: Input
}], hostClasses: [{
type: HostBinding,
args: ['class']
}], sidebarNavGroupItemsClass: [{
type: HostBinding,
args: ['class.nav-group-items']
}], role: [{
type: HostBinding,
args: ['attr.role']
}] } });
export class SidebarNavGroupComponent {
constructor(router, helper, hostElement) {
this.router = router;
this.helper = helper;
this.hostElement = hostElement;
this.dropdownMode = 'closeInactive';
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) => {
const samePath = this.samePath(event.url);
this.openGroup(samePath);
});
if (this.samePath(this.router.routerState.snapshot.url)) {
this.openGroup(true);
}
}
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.open = !this.open;
}
ngOnDestroy() {
this.navSubscription.unsubscribe();
}
onAnimationStart($event) {
setTimeout(() => {
this.display = { display: 'block' };
});
}
onAnimationDone($event) {
if ($event.toState === 'closed') {
setTimeout(() => {
this.display = null;
});
}
}
}
SidebarNavGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.8", ngImport: i0, type: SidebarNavGroupComponent, deps: [{ token: i3.Router }, { token: i2.SidebarNavHelper }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
SidebarNavGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.8", type: SidebarNavGroupComponent, selector: "c-sidebar-nav-group", inputs: { item: "item", dropdownMode: "dropdownMode", show: "show" }, host: { properties: { "class": "this.hostClasses" } }, providers: [SidebarNavHelper], ngImport: i0, template: "<a class=\"nav-link nav-group-toggle\"\r\n href\r\n (click)=\"toggleGroup($event)\"\r\n [cHtmlAttr]=\"item.attributes\">\r\n <ng-container *ngTemplateOutlet=\"iconTemplate ; context: {$implicit: item}\"></ng-container>\r\n <ng-container>{{ item.name }}</ng-container>\r\n <span *ngIf=\"helper.hasBadge(item)\" [ngClass]=\"item | cSidebarNavBadge\">{{ item.badge.text }}</span>\r\n</a>\r\n<c-sidebar-nav\r\n [groupItems]=\"true\"\r\n [navItems]=\"navItems\"\r\n [@openClose]=\"open ? 'open' : 'closed'\"\r\n (@openClose.start)=\"onAnimationStart($event)\"\r\n (@openClose.done)=\"onAnimationDone($event)\"\r\n [ngStyle]=\"display\"\r\n>\r\n</c-sidebar-nav>\r\n\r\n<ng-template #iconTemplate let-item>\r\n <i *ngIf=\"item?.icon\" [ngClass]=\"item | cSidebarNavIcon\"></i>\r\n <ng-template [ngIf]=\"item?.iconComponent\">\r\n <svg\r\n [cIcon]=\"item.iconComponent?.content\"\r\n [name]=\"item.iconComponent?.name\"\r\n [customClasses]=\"item | cSidebarNavIcon\"\r\n ></svg>\r\n </ng-template>\r\n <span *ngIf=\"!item?.icon && !item?.iconComponent\" [ngClass]=\"item | cSidebarNavIcon\"></span>\r\n</ng-template>\r\n", styles: [".nav-group-toggle{cursor:pointer}.nav-group-items{display:block}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.HtmlAttributesDirective, selector: "[cHtmlAttr]", inputs: ["cHtmlAttr"], exportAs: ["cHtmlAttr"] }, { kind: "directive", type: i12.IconDirective, selector: "svg[cIcon]", inputs: ["cIcon", "size", "title", "customClasses", "width", "height", "name", "viewBox", "xmlns", "pointer-events", "role"], exportAs: ["cIcon"] }, { kind: "component", type: SidebarNavComponent, selector: "c-sidebar-nav", inputs: ["navItems", "dropdownMode", "groupItems", "compact"] }, { kind: "pipe", type: i13.SidebarNavBadgePipe, name: "cSidebarNavBadge" }, { kind: "pipe", type: i14.SidebarNavIconPipe, name: "cSidebarNavIcon" }], 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: "14.2.8", ngImport: i0, type: SidebarNavGroupComponent, decorators: [{
type: Component,
args: [{ selector: 'c-sidebar-nav-group', providers: [SidebarNavHelper], animations: [
trigger('openClose', [
state('open', style({
height: '*'
})),
state('closed', style({
height: '0px'
})),
transition('open <=> closed', [
animate('.15s ease')
])
])
], template: "<a class=\"nav-link nav-group-toggle\"\r\n href\r\n (click)=\"toggleGroup($event)\"\r\n [cHtmlAttr]=\"item.attributes\">\r\n <ng-container *ngTemplateOutlet=\"iconTemplate ; context: {$implicit: item}\"></ng-container>\r\n <ng-container>{{ item.name }}</ng-container>\r\n <span *ngIf=\"helper.hasBadge(item)\" [ngClass]=\"item | cSidebarNavBadge\">{{ item.badge.text }}</span>\r\n</a>\r\n<c-sidebar-nav\r\n [groupItems]=\"true\"\r\n [navItems]=\"navItems\"\r\n [@openClose]=\"open ? 'open' : 'closed'\"\r\n (@openClose.start)=\"onAnimationStart($event)\"\r\n (@openClose.done)=\"onAnimationDone($event)\"\r\n [ngStyle]=\"display\"\r\n>\r\n</c-sidebar-nav>\r\n\r\n<ng-template #iconTemplate let-item>\r\n <i *ngIf=\"item?.icon\" [ngClass]=\"item | cSidebarNavIcon\"></i>\r\n <ng-template [ngIf]=\"item?.iconComponent\">\r\n <svg\r\n [cIcon]=\"item.iconComponent?.content\"\r\n [name]=\"item.iconComponent?.name\"\r\n [customClasses]=\"item | cSidebarNavIcon\"\r\n ></svg>\r\n </ng-template>\r\n <span *ngIf=\"!item?.icon && !item?.iconComponent\" [ngClass]=\"item | cSidebarNavIcon\"></span>\r\n</ng-template>\r\n", styles: [".nav-group-toggle{cursor:pointer}.nav-group-items{display:block}\n"] }]
}], ctorParameters: function () { return [{ type: i3.Router }, { type: i2.SidebarNavHelper }, { type: i0.ElementRef }]; }, propDecorators: { item: [{
type: Input
}], dropdownMode: [{
type: Input
}], show: [{
type: Input
}], hostClasses: [{
type: HostBinding,
args: ['class']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lkZWJhci1uYXYuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29yZXVpLWFuZ3VsYXIvc3JjL2xpYi9zaWRlYmFyL3NpZGViYXItbmF2L3NpZGViYXItbmF2LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmV1aS1hbmd1bGFyL3NyYy9saWIvc2lkZWJhci9zaWRlYmFyLW5hdi9zaWRlYmFyLW5hdi5jb21wb25lbnQuaHRtbCIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmV1aS1hbmd1bGFyL3NyYy9saWIvc2lkZWJhci9zaWRlYmFyLW5hdi9zaWRlYmFyLW5hdi1ncm91cC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFdBQVcsRUFDWCxLQUFLLEVBSUwsUUFBUSxFQUdULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxhQUFhLEVBQVUsTUFBTSxpQkFBaUIsQ0FBQztBQUd4RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUl6RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxFQUFFLE9BQU8sRUFBa0IsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7QUFPakcsTUFBTSxPQUFPLG1CQUFtQjtJQXVCOUIsWUFDcUIsT0FBeUIsRUFDckMsTUFBd0IsRUFDeEIsTUFBYyxFQUNiLFFBQW1CLEVBQ25CLFdBQXVCLEVBQ3ZCLGNBQThCO1FBTG5CLFlBQU8sR0FBUCxPQUFPLENBQWtCO1FBQ3JDLFdBQU0sR0FBTixNQUFNLENBQWtCO1FBQ3hCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDYixhQUFRLEdBQVIsUUFBUSxD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QUFXO3VCQUFDLE9BQU8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEhvc3RCaW5kaW5nLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT25Jbml0LFxyXG4gIE9wdGlvbmFsLFxyXG4gIFJlbmRlcmVyMixcclxuICBTaW1wbGVDaGFuZ2VzXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IE5hdmlnYXRpb25FbmQsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcblxyXG5pbXBvcnQgeyBJTmF2RGF0YSB9IGZyb20gJy4vc2lkZWJhci1uYXYnO1xyXG5pbXBvcnQgeyBTaWRlYmFyTmF2SGVscGVyIH0gZnJvbSAnLi9zaWRlYmFyLW5hdi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgU2lkZWJhclNlcnZpY2UgfSBmcm9tICcuLi9zaWRlYmFyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTaWRlYmFyQ29tcG9uZW50IH0gZnJvbSAnLi4vc2lkZWJhci9zaWRlYmFyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IGFuaW1hdGUsIEFuaW1hdGlvbkV2ZW50LCBzdGF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYy1zaWRlYmFyLW5hdicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3NpZGViYXItbmF2LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9zaWRlYmFyLW5hdi5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTaWRlYmFyTmF2Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcclxuICBASW5wdXQoKSBuYXZJdGVtcz86IElOYXZEYXRhW10gPSBbXTtcclxuICBASW5wdXQoKSBkcm9wZG93bk1vZGU/OiAnY2xvc2VJbmFjdGl2ZScgfCAnbm9BY3Rpb24nIHwgJ29wZW5BY3RpdmUnID0gJ2Nsb3NlSW5hY3RpdmUnO1xyXG4gIEBJbnB1dCgpIGdyb3VwSXRlbXM/OiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGNvbXBhY3Q/OiBib29sZWFuO1xyXG5cclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzJylcclxuICBnZXQgaG9zdENsYXNzZXMoKTogYW55IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICdzaWRlYmFyLW5hdic6ICF0aGlzLmdyb3VwSXRlbXMsXHJcbiAgICAgIGNvbXBhY3Q6ICF0aGlzLmdyb3VwSXRlbXMgJiYgISF0aGlzLmNvbXBhY3RcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLm5hdi1ncm91cC1pdGVtcycpXHJcbiAgZ2V0IHNpZGViYXJOYXZHcm91cEl0ZW1zQ2xhc3MoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gISF0aGlzLmdyb3VwSXRlbXM7XHJcbiAgfVxyXG5cclxuICBASG9zdEJpbmRpbmcoJ2F0dHIucm9sZScpIHJvbGUgPSAnbmF2JztcclxuXHJcbiAgcHVibGljIG5hdkl0ZW1zQXJyYXk6IElOYXZEYXRhW10gPSBbXTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBAT3B0aW9uYWwoKSBwdWJsaWMgc2lkZWJhcjogU2lkZWJhckNvbXBvbmVudCxcclxuICAgIHB1YmxpYyBoZWxwZXI6IFNpZGViYXJOYXZIZWxwZXIsXHJcbiAgICBwdWJsaWMgcm91dGVyOiBSb3V0ZXIsXHJcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcbiAgICBwcml2YXRlIGhvc3RFbGVtZW50OiBFbGVtZW50UmVmLFxyXG4gICAgcHJpdmF0ZSBzaWRlYmFyU2VydmljZTogU2lkZWJhclNlcnZpY2VcclxuICApIHsgfVxyXG5cclxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgdGhpcy5uYXZJdGVtc0FycmF5ID0gQXJyYXkuaXNBcnJheSh0aGlzLm5hdkl0ZW1zKSA/IHRoaXMubmF2SXRlbXMuc2xpY2UoKSA6IFtdO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGhpZGVNb2JpbGUoKTogdm9pZCB7XHJcbiAgICAvLyB0b2RvOiBwcm9wZXIgc2Nyb2xsSW50b1ZpZXcoKSBhZnRlciBOYXZpZ2F0aW9uRW5kXHJcbiAgICBpZiAodGhpcy5zaWRlYmFyICYmIHRoaXMuc2lkZWJhci5zaWRlYmFyU3RhdGUubW9iaWxlKSB7XHJcbiAgICAgIHRoaXMuc2lkZWJhclNlcnZpY2UudG9nZ2xlKHsgdG9nZ2xlOiAndmlzaWJsZScsIHNpZGViYXI6IHRoaXMuc2lkZWJhciB9KTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYy1zaWRlYmFyLW5hdi1ncm91cCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3NpZGViYXItbmF2LWdyb3VwLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9zaWRlYmFyLW5hdi1ncm91cC5jb21wb25lbnQuc2NzcyddLFxyXG4gIHByb3ZpZGVyczogW1NpZGViYXJOYXZIZWxwZXJdLFxyXG4gIGFuaW1hdGlvbnM6IFtcclxuICAgIHRyaWdnZXIoJ29wZW5DbG9zZScsIFtcclxuICAgICAgc3RhdGUoJ29wZW4nLCBzdHlsZSh7XHJcbiAgICAgICAgaGVpZ2h0OiAnKidcclxuICAgICAgfSkpLFxyXG4gICAgICBzdGF0ZSgnY2xvc2VkJywgc3R5bGUoe1xyXG4gICAgICAgIGhlaWdodDogJzBweCdcclxuICAgICAgfSkpLFxyXG4gICAgICB0cmFuc2l0aW9uKCdvcGVuIDw9PiBjbG9zZWQnLCBbXHJcbiAgICAgICAgYW5pbWF0ZSgnLjE1cyBlYXNlJylcclxuICAgICAgXSlcclxuICAgIF0pXHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2lkZWJhck5hdkdyb3VwQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBJbnB1dCgpIGl0ZW06IGFueTtcclxuICBASW5wdXQoKSBkcm9wZG93bk1vZGU6ICdjbG9zZUluYWN0aXZlJyB8ICdub0FjdGlvbicgfCAnb3BlbkFjdGl2ZScgPSAnY2xvc2VJbmFjdGl2ZSc7XHJcbiAgLy8gQHRzLWlnbm9yZVxyXG4gIEBJbnB1dCgpIHNob3c6IGJvb2xlYW47XHJcblxyXG4gIEBIb3N0QmluZGluZygnY2xhc3MnKVxyXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp0eXBlZGVmXHJcbiAgZ2V0IGhvc3RDbGFzc2VzKCk6IGFueSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAnbmF2LWdyb3VwJzogdHJ1ZSxcclxuICAgICAgc2hvdzogdGhpcy5vcGVuXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLy8gdG9kbzogZHJvcGRvd25Nb2RlXHJcblxyXG4gIG5hdmlnYXRpb25FbmRPYnNlcnZhYmxlOiBPYnNlcnZhYmxlPE5hdmlnYXRpb25FbmQ+O1xyXG4gIC8vIEB0cy1pZ25vcmVcclxuICBuYXZTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuXHJcbiAgLy8gQHRzLWlnbm9yZVxyXG4gIHB1YmxpYyBvcGVuOiBib29sZWFuO1xyXG4gIHB1YmxpYyBuYXZJdGVtczogSU5hdkRhdGFbXSA9IFtdO1xyXG4gIHB1YmxpYyBkaXNwbGF5OiBhbnkgPSB7IGRpc3BsYXk6ICdibG9jaycgfTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxyXG4gICAgcHVibGljIGhlbHBlcjogU2lkZWJhck5hdkhlbHBlcixcclxuICAgIHByaXZhdGUgaG9zdEVsZW1lbnQ6IEVsZW1lbnRSZWZcclxuICApIHtcclxuICAgIHRoaXMubmF2aWdhdGlvbkVuZE9ic2VydmFibGUgPSByb3V0ZXIuZXZlbnRzLnBpcGUoXHJcbiAgICAgIGZpbHRlcigoZXZlbnQ6IGFueSkgPT4gZXZlbnQgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRW5kKVxyXG4gICAgKSBhcyBPYnNlcnZhYmxlPE5hdmlnYXRpb25FbmQ+O1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcblxyXG4gICAgdGhpcy5uYXZJdGVtcyA9IFsuLi50aGlzLml0ZW0uY2hpbGRyZW5dO1xyXG5cclxuICAgIHRoaXMubmF2U3Vic2NyaXB0aW9uID0gdGhpcy5uYXZpZ2F0aW9uRW5kT2JzZXJ2YWJsZS5zdWJzY3JpYmUoKGV2ZW50OiBOYXZpZ2F0aW9uRW5kKSA9PiB7XHJcbiAgICAgIGNvbnN0IHNhbWVQYXRoID0gdGhpcy5zYW1lUGF0aChldmVudC51cmwpO1xyXG4gICAgICB0aGlzLm9wZW5Hcm91cChzYW1lUGF0aCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAodGhpcy5zYW1lUGF0aCh0aGlzLnJvdXRlci5yb3V0ZXJTdGF0ZS5zbmFwc2hvdC51cmwpKSB7XHJcbiAgICAgIHRoaXMub3Blbkdyb3VwKHRydWUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2FtZVBhdGgodXJsOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIC8vIGNvbnNvbGUubG9nKCdpdGVtOicsIHRoaXMuaXRlbS5uYW1lLCB0aGlzLml0ZW0udXJsLCAndXJsOicsIHVybCk7XHJcbiAgICBjb25zdCBpdGVtQXJyYXkgPSB0aGlzLml0ZW0udXJsPy5zcGxpdCgnLycpO1xyXG4gICAgY29uc3QgdXJsQXJyYXkgPSB1cmwuc3BsaXQoJy8nKTtcclxuICAgIHJldHVybiBpdGVtQXJyYXk/LmV2ZXJ5KCh2YWx1ZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XHJcbiAgICAgIC8vIGNvbnNvbGUubG9nKHZhbHVlID09PSB1cmxBcnJheVtpbmRleF0sICd2YWx1ZTonLCB2YWx1ZSwgJ2luZGV4OicsIGluZGV4LCB1cmxBcnJheVtpbmRleF0sIHVybCk7XHJcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdXJsQXJyYXlbaW5kZXhdO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBvcGVuR3JvdXAob3BlbjogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5vcGVuID0gb3BlbjtcclxuICB9XHJcblxyXG4gIHRvZ2dsZUdyb3VwKCRldmVudDogYW55KTogdm9pZCB7XHJcbiAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIHRoaXMub3BlbiA9ICF0aGlzLm9wZW47XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMubmF2U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICBvbkFuaW1hdGlvblN0YXJ0KCRldmVudDogQW5pbWF0aW9uRXZlbnQpIHtcclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICB0aGlzLmRpc3BsYXkgPSB7IGRpc3BsYXk6ICdibG9jaycgfTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgb25BbmltYXRpb25Eb25lKCRldmVudDogQW5pbWF0aW9uRXZlbnQpIHtcclxuICAgIGlmICgkZXZlbnQudG9TdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5kaXNwbGF5ID0gbnVsbDtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgbmF2SXRlbXNBcnJheVwiPlxyXG4gIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cImhlbHBlci5pdGVtVHlwZShpdGVtKVwiPlxyXG4gICAgPGMtc2lkZWJhci1uYXYtZ3JvdXBcclxuICAgICAgKm5nU3dpdGNoQ2FzZT1cIidncm91cCdcIlxyXG4gICAgICBbaXRlbV09XCJpdGVtXCJcclxuICAgICAgW25nQ2xhc3NdPVwiaXRlbSB8IGNTaWRlYmFyTmF2SXRlbUNsYXNzXCJcclxuICAgICAgcm91dGVyTGlua0FjdGl2ZT1cInNob3dcIlxyXG4gICAgICAjcmxhPVwicm91dGVyTGlua0FjdGl2ZVwiXHJcbiAgICAgIFtyb3V0ZXJMaW5rQWN0aXZlT3B0aW9uc109XCJ7ZXhhY3Q6IHRydWV9XCJcclxuICAgID5cclxuICAgIDwvYy1zaWRlYmFyLW5hdi1ncm91cD5cclxuICAgIDxjLXNpZGViYXItbmF2LWRpdmlkZXJcclxuICAgICAgKm5nU3dpdGNoQ2FzZT1cIidkaXZpZGVyJ1wiXHJcbiAgICAgIFtpdGVtXT1cIml0ZW1cIlxyXG4gICAgICBbbmdDbGFzc109XCJpdGVtIHwgY1NpZGViYXJOYXZJdGVtQ2xhc3NcIlxyXG4gICAgICBbY0h0bWxBdHRyXT1cIml0ZW0uYXR0cmlidXRlcyA/PyB7fVwiPlxyXG4gICAgPC9jLXNpZGViYXItbmF2LWRpdmlkZXI+XHJcbiAgICA8Yy1zaWRlYmFyLW5hdi10aXRsZVxyXG4gICAgICAqbmdTd2l0Y2hDYXNlPVwiJ3RpdGxlJ1wiXHJcbiAgICAgIFtpdGVtXT1cIml0ZW1cIlxyXG4gICAgICBbbmdDbGFzc109XCJpdGVtIHwgY1NpZGViYXJOYXZJdGVtQ2xhc3NcIlxyXG4gICAgICBbY0h0bWxBdHRyXT1cIml0ZW0uYXR0cmlidXRlcyA/PyB7fVwiPlxyXG4gICAgPC9jLXNpZGViYXItbmF2LXRpdGxlPlxyXG4gICAgPGMtc2lkZWJhci1uYXYtbGFiZWxcclxuICAgICAgKm5nU3dpdGNoQ2FzZT1cIidsYWJlbCdcIlxyXG4gICAgICBbaXRlbV09XCJpdGVtXCJcclxuICAgICAgW25nQ2xhc3NdPVwiaXRlbSB8IGNTaWRlYmFyTmF2SXRlbUNsYXNzXCI+XHJcbiAgICA8L2Mtc2lkZWJhci1uYXYtbGFiZWw+XHJcbiAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICpuZ1N3aXRjaENhc2U9XCInZW1wdHknXCI+XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDxjLXNpZGViYXItbmF2LWxpbmtcclxuICAgICAgKm5nU3dpdGNoRGVmYXVsdFxyXG4gICAgICBbaXRlbV09XCJpdGVtXCJcclxuICAgICAgW25nQ2xhc3NdPVwiaXRlbSB8IGNTaWRlYmFyTmF2SXRlbUNsYXNzXCJcclxuICAgICAgKGxpbmtDbGljayk9XCJoaWRlTW9iaWxlKClcIlxyXG4gICAgPlxyXG4gICAgPC9jLXNpZGViYXItbmF2LWxpbms+XHJcbiAgPC9uZy1jb250YWluZXI+XHJcbjwvbmctY29udGFpbmVyPlxyXG48bmctY29udGVudD48L25nLWNvbnRlbnQ+XHJcbiIsIjxhIGNsYXNzPVwibmF2LWxpbmsgbmF2LWdyb3VwLXRvZ2dsZVwiXHJcbiAgIGhyZWZcclxuICAgKGNsaWNrKT1cInRvZ2dsZUdyb3VwKCRldmVudClcIlxyXG4gICBbY0h0bWxBdHRyXT1cIml0ZW0uYXR0cmlidXRlc1wiPlxyXG4gIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJpY29uVGVtcGxhdGUgOyBjb250ZXh0OiB7JGltcGxpY2l0OiBpdGVtfVwiPjwvbmctY29udGFpbmVyPlxyXG4gIDxuZy1jb250YWluZXI+e3sgaXRlbS5uYW1lIH19PC9uZy1jb250YWluZXI+XHJcbiAgPHNwYW4gKm5nSWY9XCJoZWxwZXIuaGFzQmFkZ2UoaXRlbSlcIiBbbmdDbGFzc109XCJpdGVtIHwgY1NpZGViYXJOYXZCYWRnZVwiPnt7IGl0ZW0uYmFkZ2UudGV4dCB9fTwvc3Bhbj5cclxuPC9hPlxyXG48Yy1zaWRlYmFyLW5hdlxyXG4gIFtncm91cEl0ZW1zXT1cInRydWVcIlxyXG4gIFtuYXZJdGVtc109XCJuYXZJdGVtc1wiXHJcbiAgW0BvcGVuQ2xvc2VdPVwib3BlbiA/ICdvcGVuJyA6ICdjbG9zZWQnXCJcclxuICAoQG9wZW5DbG9zZS5zdGFydCk9XCJvbkFuaW1hdGlvblN0YXJ0KCRldmVudClcIlxyXG4gIChAb3BlbkNsb3NlLmRvbmUpPVwib25BbmltYXRpb25Eb25lKCRldmVudClcIlxyXG4gIFtuZ1N0eWxlXT1cImRpc3BsYXlcIlxyXG4+XHJcbjwvYy1zaWRlYmFyLW5hdj5cclxuXHJcbjxuZy10ZW1wbGF0ZSAjaWNvblRlbXBsYXRlIGxldC1pdGVtPlxyXG4gIDxpICpuZ0lmPVwiaXRlbT8uaWNvblwiIFtuZ0NsYXNzXT1cIml0ZW0gfCBjU2lkZWJhck5hdkljb25cIj48L2k+XHJcbiAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIml0ZW0/Lmljb25Db21wb25lbnRcIj5cclxuICAgIDxzdmdcclxuICAgICAgW2NJY29uXT1cIml0ZW0uaWNvbkNvbXBvbmVudD8uY29udGVudFwiXHJcbiAgICAgIFtuYW1lXT1cIml0ZW0uaWNvbkNvbXBvbmVudD8ubmFtZVwiXHJcbiAgICAgIFtjdXN0b21DbGFzc2VzXT1cIml0ZW0gfCBjU2lkZWJhck5hdkljb25cIlxyXG4gICAgPjwvc3ZnPlxyXG4gIDwvbmctdGVtcGxhdGU+XHJcbiAgPHNwYW4gKm5nSWY9XCIhaXRlbT8uaWNvbiAmJiAhaXRlbT8uaWNvbkNvbXBvbmVudFwiIFtuZ0NsYXNzXT1cIml0ZW0gfCBjU2lkZWJhck5hdkljb25cIj48L3NwYW4+XHJcbjwvbmctdGVtcGxhdGU+XHJcbiJdfQ==