design-angular-kit
Version:
Un toolkit Angular conforme alle linee guida di design per i servizi web della PA
97 lines • 24.8 kB
JavaScript
import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Input, Output, ViewChildren, } from '@angular/core';
import { ItTabItemComponent } from '../tab-item/tab-item.component';
import { of, startWith, switchMap, tap } from 'rxjs';
import { Tab } from 'bootstrap-italia';
import { ItAbstractComponent } from '../../../../abstracts/abstract.component';
import { NgTemplateOutlet } from '@angular/common';
import { ItIconComponent } from '../../../utils/icon/icon.component';
import { inputToBoolean } from '../../../../utils/coercion';
import * as i0 from "@angular/core";
export class ItTabContainerComponent extends ItAbstractComponent {
constructor() {
super();
this.tabSelected = new EventEmitter();
this.tabClosed = new EventEmitter();
this.tabAdded = new EventEmitter();
}
ngAfterViewInit() {
super.ngAfterViewInit();
this.tabs?.changes
.pipe(
// When tabs changes (dynamic add/remove)
startWith(undefined), tap(() => {
this.tabSubscriptions?.forEach(sub => sub.unsubscribe()); // Remove old subscriptions
this.tabSubscriptions = this.tabs?.map(tab => tab.valueChanges.subscribe(() => {
this._changeDetectorRef.detectChanges(); // DetectChanges when tab-item attributes changes
}));
this._changeDetectorRef.detectChanges(); // Force update html render
}), switchMap(() => this.tabNavLinks?.changes.pipe(startWith(undefined)) || of(undefined)))
.subscribe(() => {
// Init tabs from bootstrap-italia
this.tabNavLinks?.forEach(tabNavLink => {
const triggerEl = tabNavLink.nativeElement, tabTrigger = Tab.getOrCreateInstance(triggerEl);
if (triggerEl.getAttribute('tab-listener') !== 'true') {
triggerEl.addEventListener('click', event => {
event.preventDefault();
tabTrigger.show();
this._changeDetectorRef.detectChanges();
});
triggerEl.setAttribute('tab-listener', 'true'); // Prevents multiple insertion of the listener
}
});
});
}
ngOnDestroy() {
this.tabSubscriptions?.forEach(sub => sub.unsubscribe());
}
onTab(tab) {
this.tabSelected.emit(tab);
}
clickToClose(index) {
this.tabClosed.emit(index);
}
clickToAdd($event) {
$event.preventDefault();
this.tabAdded.emit();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: ItTabContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.6", type: ItTabContainerComponent, isStandalone: true, selector: "it-tab-container", inputs: { auto: ["auto", "auto", inputToBoolean], iconText: ["iconText", "iconText", inputToBoolean], dark: ["dark", "dark", inputToBoolean], cards: ["cards", "cards", inputToBoolean], vertical: ["vertical", "vertical", inputToBoolean], inverted: ["inverted", "inverted", inputToBoolean], editable: ["editable", "editable", inputToBoolean] }, outputs: { tabSelected: "tabSelected", tabClosed: "tabClosed", tabAdded: "tabAdded" }, queries: [{ propertyName: "tabs", predicate: ItTabItemComponent }], viewQueries: [{ propertyName: "tabNavLinks", predicate: ["tabNavLinks"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div\n [class.row]=\"vertical\"\n [class.flex-row-reverse]=\"inverted && vertical\"\n [class.d-flex]=\"inverted && !vertical\"\n [class.flex-column-reverse]=\"inverted && !vertical\">\n <div\n [class.col-5]=\"inverted && vertical\"\n [class.col-md-4]=\"inverted && vertical\"\n [class.col-lg-3]=\"inverted && vertical\"\n [class.col-4]=\"!inverted && vertical\"\n [class.col-md-3]=\"!inverted && vertical\">\n @if (tabs) {\n <ul\n class=\"nav nav-tabs\"\n [class.nav-tabs-editable]=\"editable\"\n [class.nav-tabs-cards]=\"cards\"\n [class.nav-tabs-vertical]=\"vertical\"\n [class.auto]=\"auto\"\n [class.nav-tabs-icon-text]=\"iconText\"\n [class.nav-dark]=\"dark\"\n role=\"tablist\">\n @for (tab of tabs; track tab.id; let i = $index) {\n <li class=\"nav-item\">\n <a\n #tabNavLinks\n [id]=\"tab.id + '-tab-link'\"\n role=\"tab\"\n class=\"nav-link\"\n [class.active]=\"tab.active\"\n [class.disabled]=\"tab.disabled\"\n [attr.href]=\"'#' + tab.id + '-tab'\"\n [attr.aria-controls]=\"tab.id + '-tab'\"\n (click)=\"onTab(tab)\">\n @if (tab.icon) {\n <it-icon [name]=\"tab.icon\" class=\"me-2\"></it-icon>\n }\n {{ tab.label }}\n </a>\n @if (editable) {\n <a class=\"nav-link-close\" (click)=\"clickToClose(i)\" (keypress)=\"clickToClose(i)\" [attr.disabled]=\"tab.disabled\">\n <it-icon name=\"close\"></it-icon>\n </a>\n }\n </li>\n }\n @if (editable) {\n <li class=\"nav-item\">\n <a href=\"#\" class=\"nav-tab-add\" (click)=\"clickToAdd($event)\" (keypress)=\"clickToAdd($event)\"\n ><span class=\"visually-hidden\"> Aggiungi un tab</span></a\n >\n </li>\n }\n </ul>\n }\n </div>\n <div\n [class.col-7]=\"inverted && vertical\"\n [class.col-md-8]=\"inverted && vertical\"\n [class.col-lg-9]=\"inverted && vertical\"\n [class.col-8]=\"!inverted && vertical\"\n [class.col-md-9]=\"!inverted && vertical\">\n @if (tabs) {\n <div class=\"tab-content\">\n @for (tab of tabs; track tab.id) {\n <div\n [id]=\"tab.id + '-tab'\"\n class=\"tab-pane p-4 fade {{ tab.class ?? '' }}\"\n [class.active]=\"tab.active\"\n [class.show]=\"tab.active\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"tab.id + '-tab-link'\">\n <ng-container *ngTemplateOutlet=\"tab.htmlContent\"></ng-container>\n </div>\n }\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ItIconComponent, selector: "it-icon", inputs: ["name", "size", "color", "padded", "svgClass", "title", "labelWaria"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: ItTabContainerComponent, decorators: [{
type: Component,
args: [{ standalone: true, selector: 'it-tab-container', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ItIconComponent, NgTemplateOutlet], template: "<div\n [class.row]=\"vertical\"\n [class.flex-row-reverse]=\"inverted && vertical\"\n [class.d-flex]=\"inverted && !vertical\"\n [class.flex-column-reverse]=\"inverted && !vertical\">\n <div\n [class.col-5]=\"inverted && vertical\"\n [class.col-md-4]=\"inverted && vertical\"\n [class.col-lg-3]=\"inverted && vertical\"\n [class.col-4]=\"!inverted && vertical\"\n [class.col-md-3]=\"!inverted && vertical\">\n @if (tabs) {\n <ul\n class=\"nav nav-tabs\"\n [class.nav-tabs-editable]=\"editable\"\n [class.nav-tabs-cards]=\"cards\"\n [class.nav-tabs-vertical]=\"vertical\"\n [class.auto]=\"auto\"\n [class.nav-tabs-icon-text]=\"iconText\"\n [class.nav-dark]=\"dark\"\n role=\"tablist\">\n @for (tab of tabs; track tab.id; let i = $index) {\n <li class=\"nav-item\">\n <a\n #tabNavLinks\n [id]=\"tab.id + '-tab-link'\"\n role=\"tab\"\n class=\"nav-link\"\n [class.active]=\"tab.active\"\n [class.disabled]=\"tab.disabled\"\n [attr.href]=\"'#' + tab.id + '-tab'\"\n [attr.aria-controls]=\"tab.id + '-tab'\"\n (click)=\"onTab(tab)\">\n @if (tab.icon) {\n <it-icon [name]=\"tab.icon\" class=\"me-2\"></it-icon>\n }\n {{ tab.label }}\n </a>\n @if (editable) {\n <a class=\"nav-link-close\" (click)=\"clickToClose(i)\" (keypress)=\"clickToClose(i)\" [attr.disabled]=\"tab.disabled\">\n <it-icon name=\"close\"></it-icon>\n </a>\n }\n </li>\n }\n @if (editable) {\n <li class=\"nav-item\">\n <a href=\"#\" class=\"nav-tab-add\" (click)=\"clickToAdd($event)\" (keypress)=\"clickToAdd($event)\"\n ><span class=\"visually-hidden\"> Aggiungi un tab</span></a\n >\n </li>\n }\n </ul>\n }\n </div>\n <div\n [class.col-7]=\"inverted && vertical\"\n [class.col-md-8]=\"inverted && vertical\"\n [class.col-lg-9]=\"inverted && vertical\"\n [class.col-8]=\"!inverted && vertical\"\n [class.col-md-9]=\"!inverted && vertical\">\n @if (tabs) {\n <div class=\"tab-content\">\n @for (tab of tabs; track tab.id) {\n <div\n [id]=\"tab.id + '-tab'\"\n class=\"tab-pane p-4 fade {{ tab.class ?? '' }}\"\n [class.active]=\"tab.active\"\n [class.show]=\"tab.active\"\n role=\"tabpanel\"\n [attr.aria-labelledby]=\"tab.id + '-tab-link'\">\n <ng-container *ngTemplateOutlet=\"tab.htmlContent\"></ng-container>\n </div>\n }\n </div>\n }\n </div>\n</div>\n" }]
}], ctorParameters: () => [], propDecorators: { auto: [{
type: Input,
args: [{ transform: inputToBoolean }]
}], iconText: [{
type: Input,
args: [{ transform: inputToBoolean }]
}], dark: [{
type: Input,
args: [{ transform: inputToBoolean }]
}], cards: [{
type: Input,
args: [{ transform: inputToBoolean }]
}], vertical: [{
type: Input,
args: [{ transform: inputToBoolean }]
}], inverted: [{
type: Input,
args: [{ transform: inputToBoolean }]
}], editable: [{
type: Input,
args: [{ transform: inputToBoolean }]
}], tabs: [{
type: ContentChildren,
args: [ItTabItemComponent]
}], tabNavLinks: [{
type: ViewChildren,
args: ['tabNavLinks']
}], tabSelected: [{
type: Output
}], tabClosed: [{
type: Output
}], tabAdded: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLWNvbnRhaW5lci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kZXNpZ24tYW5ndWxhci1raXQvc3JjL2xpYi9jb21wb25lbnRzL2NvcmUvdGFiL3RhYi1jb250YWluZXIvdGFiLWNvbnRhaW5lci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kZXNpZ24tYW5ndWxhci1raXQvc3JjL2xpYi9jb21wb25lbnRzL2NvcmUvdGFiL3RhYi1jb250YWluZXIvdGFiLWNvbnRhaW5lci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxlQUFlLEVBRWYsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBRU4sWUFBWSxHQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFnQixTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ25FLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUMvRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDckUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRCQUE0QixDQUFDOztBQVM1RCxNQUFNLE9BQU8sdUJBQXdCLFNBQVEsbUJBQW1CO0lBb0Q5RDtRQUNFLEtBQUssRUFBRSxDQUFDO1FBVEEsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBc0IsQ0FBQztRQUVyRCxjQUFTLEdB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Qjs7MkZBRWhDLHVCQUF1QjtrQkFQbkMsU0FBUztpQ0FDSSxJQUFJLFlBQ04sa0JBQWtCLG1CQUVYLHVCQUF1QixDQUFDLE1BQU0sV0FDdEMsQ0FBQyxlQUFlLEVBQUUsZ0JBQWdCLENBQUM7d0RBT04sSUFBSTtzQkFBekMsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUU7Z0JBS0UsUUFBUTtzQkFBN0MsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUU7Z0JBS0UsSUFBSTtzQkFBekMsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUU7Z0JBS0UsS0FBSztzQkFBMUMsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUU7Z0JBS0UsUUFBUTtzQkFBN0MsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUU7Z0JBS0UsUUFBUTtzQkFBN0MsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUU7Z0JBS0UsUUFBUTtzQkFBN0MsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUU7Z0JBS0MsSUFBSTtzQkFBeEMsZUFBZTt1QkFBQyxrQkFBa0I7Z0JBRUUsV0FBVztzQkFBL0MsWUFBWTt1QkFBQyxhQUFhO2dCQUVqQixXQUFXO3NCQUFwQixNQUFNO2dCQUVHLFNBQVM7c0JBQWxCLE1BQU07Z0JBRUcsUUFBUTtzQkFBakIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgVmlld0NoaWxkcmVuLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEl0VGFiSXRlbUNvbXBvbmVudCB9IGZyb20gJy4uL3RhYi1pdGVtL3RhYi1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBvZiwgc3RhcnRXaXRoLCBTdWJzY3JpcHRpb24sIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBUYWIgfSBmcm9tICdib290c3RyYXAtaXRhbGlhJztcbmltcG9ydCB7IEl0QWJzdHJhY3RDb21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9hYnN0cmFjdHMvYWJzdHJhY3QuY29tcG9uZW50JztcbmltcG9ydCB7IE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSXRJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvaWNvbi9pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBpbnB1dFRvQm9vbGVhbiB9IGZyb20gJy4uLy4uLy4uLy4uL3V0aWxzL2NvZXJjaW9uJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiAnaXQtdGFiLWNvbnRhaW5lcicsXG4gIHRlbXBsYXRlVXJsOiAnLi90YWItY29udGFpbmVyLmNvbXBvbmVudC5odG1sJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGltcG9ydHM6IFtJdEljb25Db21wb25lbnQsIE5nVGVtcGxhdGVPdXRsZXRdLFxufSlcbmV4cG9ydCBjbGFzcyBJdFRhYkNvbnRhaW5lckNvbXBvbmVudCBleHRlbmRzIEl0QWJzdHJhY3RDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuICAvKipcbiAgICogVGFicyBhdXRvbWF0aWNhbGx5IG9jY3VweSB0aGUgZW50aXJlIGF2YWlsYWJsZSB3aWR0aFxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBpbnB1dFRvQm9vbGVhbiB9KSBhdXRvPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVG8gb2J0YWluIHRoZSBjb3JyZWN0IG1hcmdpbiBiZXR3ZWVuIHRleHQgYW5kIGljb24gaW4gdGhlIGhvcml6b250YWxseSBkZXZlbG9wZWQgdGFiXG4gICAqL1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGlucHV0VG9Cb29sZWFuIH0pIGljb25UZXh0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRGFyayBzdHlsZVxuICAgKi9cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBpbnB1dFRvQm9vbGVhbiB9KSBkYXJrPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogU2hvdyBpdGVtcyBhcyBjYXJkc1xuICAgKi9cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBpbnB1dFRvQm9vbGVhbiB9KSBjYXJkcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFNob3cgdmVydGljYWwgbmF2aWdhdGlvblxuICAgKi9cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBpbnB1dFRvQm9vbGVhbiB9KSB2ZXJ0aWNhbD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSB0YWIgcG9zaXRpb25cbiAgICovXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogaW5wdXRUb0Jvb2xlYW4gfSkgaW52ZXJ0ZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJZiB0YWJzIGFyZSBlZGl0YWJsZVxuICAgKi9cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBpbnB1dFRvQm9vbGVhbiB9KSBlZGl0YWJsZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSB0YWIgaXRlbXNcbiAgICovXG4gIEBDb250ZW50Q2hpbGRyZW4oSXRUYWJJdGVtQ29tcG9uZW50KSB0YWJzPzogUXVlcnlMaXN0PEl0VGFiSXRlbUNvbXBvbmVudD47XG5cbiAgQFZpZXdDaGlsZHJlbigndGFiTmF2TGlua3MnKSBwcml2YXRlIHRhYk5hdkxpbmtzPzogUXVlcnlMaXN0PEVsZW1lbnRSZWY8SFRNTEFuY2hvckVsZW1lbnQ+PjtcblxuICBAT3V0cHV0KCkgdGFiU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEl0VGFiSXRlbUNvbXBvbmVudD4oKTtcblxuICBAT3V0cHV0KCkgdGFiQ2xvc2VkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBPdXRwdXQoKSB0YWJBZGRlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBwcml2YXRlIHRhYlN1YnNjcmlwdGlvbnM/OiBBcnJheTxTdWJzY3JpcHRpb24+O1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBvdmVycmlkZSBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgc3VwZXIubmdBZnRlclZpZXdJbml0KCk7XG5cbiAgICB0aGlzLnRhYnM/LmNoYW5nZXNcbiAgICAgIC5waXBlKFxuICAgICAgICAvLyBXaGVuIHRhYnMgY2hhbmdlcyAoZHluYW1pYyBhZGQvcmVtb3ZlKVxuICAgICAgICBzdGFydFdpdGgodW5kZWZpbmVkKSxcbiAgICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnRhYlN1YnNjcmlwdGlvbnM/LmZvckVhY2goc3ViID0+IHN1Yi51bnN1YnNjcmliZSgpKTsgLy8gUmVtb3ZlIG9sZCBzdWJzY3JpcHRpb25zXG4gICAgICAgICAgdGhpcy50YWJTdWJzY3JpcHRpb25zID0gdGhpcy50YWJzPy5tYXAodGFiID0+XG4gICAgICAgICAgICB0YWIudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTsgLy8gRGV0ZWN0Q2hhbmdlcyB3aGVuIHRhYi1pdGVtIGF0dHJpYnV0ZXMgY2hhbmdlc1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTsgLy8gRm9yY2UgdXBkYXRlIGh0bWwgcmVuZGVyXG4gICAgICAgIH0pLFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy50YWJOYXZMaW5rcz8uY2hhbmdlcy5waXBlKHN0YXJ0V2l0aCh1bmRlZmluZWQpKSB8fCBvZih1bmRlZmluZWQpKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIC8vIEluaXQgdGFicyBmcm9tIGJvb3RzdHJhcC1pdGFsaWFcbiAgICAgICAgdGhpcy50YWJOYXZMaW5rcz8uZm9yRWFjaCh0YWJOYXZMaW5rID0+IHtcbiAgICAgICAgICBjb25zdCB0cmlnZ2VyRWwgPSB0YWJOYXZMaW5rLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgICB0YWJUcmlnZ2VyID0gVGFiLmdldE9yQ3JlYXRlSW5zdGFuY2UodHJpZ2dlckVsKTtcblxuICAgICAgICAgIGlmICh0cmlnZ2VyRWwuZ2V0QXR0cmlidXRlKCd0YWItbGlzdGVuZXInKSAhPT0gJ3RydWUnKSB7XG4gICAgICAgICAgICB0cmlnZ2VyRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBldmVudCA9PiB7XG4gICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgIHRhYlRyaWdnZXIuc2hvdygpO1xuICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRyaWdnZXJFbC5zZXRBdHRyaWJ1dGUoJ3RhYi1saXN0ZW5lcicsICd0cnVlJyk7IC8vIFByZXZlbnRzIG11bHRpcGxlIGluc2VydGlvbiBvZiB0aGUgbGlzdGVuZXJcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnRhYlN1YnNjcmlwdGlvbnM/LmZvckVhY2goc3ViID0+IHN1Yi51bnN1YnNjcmliZSgpKTtcbiAgfVxuXG4gIG9uVGFiKHRhYjogSXRUYWJJdGVtQ29tcG9uZW50KSB7XG4gICAgdGhpcy50YWJTZWxlY3RlZC5lbWl0KHRhYik7XG4gIH1cblxuICBjbGlja1RvQ2xvc2UoaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMudGFiQ2xvc2VkLmVtaXQoaW5kZXgpO1xuICB9XG5cbiAgY2xpY2tUb0FkZCgkZXZlbnQ6IEV2ZW50KSB7XG4gICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy50YWJBZGRlZC5lbWl0KCk7XG4gIH1cbn1cbiIsIjxkaXZcbiAgW2NsYXNzLnJvd109XCJ2ZXJ0aWNhbFwiXG4gIFtjbGFzcy5mbGV4LXJvdy1yZXZlcnNlXT1cImludmVydGVkICYmIHZlcnRpY2FsXCJcbiAgW2NsYXNzLmQtZmxleF09XCJpbnZlcnRlZCAmJiAhdmVydGljYWxcIlxuICBbY2xhc3MuZmxleC1jb2x1bW4tcmV2ZXJzZV09XCJpbnZlcnRlZCAmJiAhdmVydGljYWxcIj5cbiAgPGRpdlxuICAgIFtjbGFzcy5jb2wtNV09XCJpbnZlcnRlZCAmJiB2ZXJ0aWNhbFwiXG4gICAgW2NsYXNzLmNvbC1tZC00XT1cImludmVydGVkICYmIHZlcnRpY2FsXCJcbiAgICBbY2xhc3MuY29sLWxnLTNdPVwiaW52ZXJ0ZWQgJiYgdmVydGljYWxcIlxuICAgIFtjbGFzcy5jb2wtNF09XCIhaW52ZXJ0ZWQgJiYgdmVydGljYWxcIlxuICAgIFtjbGFzcy5jb2wtbWQtM109XCIhaW52ZXJ0ZWQgJiYgdmVydGljYWxcIj5cbiAgICBAaWYgKHRhYnMpIHtcbiAgICAgIDx1bFxuICAgICAgICBjbGFzcz1cIm5hdiBuYXYtdGFic1wiXG4gICAgICAgIFtjbGFzcy5uYXYtdGFicy1lZGl0YWJsZV09XCJlZGl0YWJsZVwiXG4gICAgICAgIFtjbGFzcy5uYXYtdGFicy1jYXJkc109XCJjYXJkc1wiXG4gICAgICAgIFtjbGFzcy5uYXYtdGFicy12ZXJ0aWNhbF09XCJ2ZXJ0aWNhbFwiXG4gICAgICAgIFtjbGFzcy5hdXRvXT1cImF1dG9cIlxuICAgICAgICBbY2xhc3MubmF2LXRhYnMtaWNvbi10ZXh0XT1cImljb25UZXh0XCJcbiAgICAgICAgW2NsYXNzLm5hdi1kYXJrXT1cImRhcmtcIlxuICAgICAgICByb2xlPVwidGFibGlzdFwiPlxuICAgICAgICBAZm9yICh0YWIgb2YgdGFiczsgdHJhY2sgdGFiLmlkOyBsZXQgaSA9ICRpbmRleCkge1xuICAgICAgICAgIDxsaSBjbGFzcz1cIm5hdi1pdGVtXCI+XG4gICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAjdGFiTmF2TGlua3NcbiAgICAgICAgICAgICAgW2lkXT1cInRhYi5pZCArICctdGFiLWxpbmsnXCJcbiAgICAgICAgICAgICAgcm9sZT1cInRhYlwiXG4gICAgICAgICAgICAgIGNsYXNzPVwibmF2LWxpbmtcIlxuICAgICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cInRhYi5hY3RpdmVcIlxuICAgICAgICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwidGFiLmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgW2F0dHIuaHJlZl09XCInIycgKyB0YWIuaWQgKyAnLXRhYidcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cInRhYi5pZCArICctdGFiJ1wiXG4gICAgICAgICAgICAgIChjbGljayk9XCJvblRhYih0YWIpXCI+XG4gICAgICAgICAgICAgIEBpZiAodGFiLmljb24pIHtcbiAgICAgICAgICAgICAgICA8aXQtaWNvbiBbbmFtZV09XCJ0YWIuaWNvblwiIGNsYXNzPVwibWUtMlwiPjwvaXQtaWNvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB7eyB0YWIubGFiZWwgfX1cbiAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIEBpZiAoZWRpdGFibGUpIHtcbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJuYXYtbGluay1jbG9zZVwiIChjbGljayk9XCJjbGlja1RvQ2xvc2UoaSlcIiAoa2V5cHJlc3MpPVwiY2xpY2tUb0Nsb3NlKGkpXCIgW2F0dHIuZGlzYWJsZWRdPVwidGFiLmRpc2FibGVkXCI+XG4gICAgICAgICAgICAgICAgPGl0LWljb24gbmFtZT1cImNsb3NlXCI+PC9pdC1pY29uPlxuICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9saT5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGVkaXRhYmxlKSB7XG4gICAgICAgICAgPGxpIGNsYXNzPVwibmF2LWl0ZW1cIj5cbiAgICAgICAgICAgIDxhIGhyZWY9XCIjXCIgY2xhc3M9XCJuYXYtdGFiLWFkZFwiIChjbGljayk9XCJjbGlja1RvQWRkKCRldmVudClcIiAoa2V5cHJlc3MpPVwiY2xpY2tUb0FkZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgPjxzcGFuIGNsYXNzPVwidmlzdWFsbHktaGlkZGVuXCI+IEFnZ2l1bmdpIHVuIHRhYjwvc3Bhbj48L2FcbiAgICAgICAgICAgID5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICB9XG4gICAgICA8L3VsPlxuICAgIH1cbiAgPC9kaXY+XG4gIDxkaXZcbiAgICBbY2xhc3MuY29sLTddPVwiaW52ZXJ0ZWQgJiYgdmVydGljYWxcIlxuICAgIFtjbGFzcy5jb2wtbWQtOF09XCJpbnZlcnRlZCAmJiB2ZXJ0aWNhbFwiXG4gICAgW2NsYXNzLmNvbC1sZy05XT1cImludmVydGVkICYmIHZlcnRpY2FsXCJcbiAgICBbY2xhc3MuY29sLThdPVwiIWludmVydGVkICYmIHZlcnRpY2FsXCJcbiAgICBbY2xhc3MuY29sLW1kLTldPVwiIWludmVydGVkICYmIHZlcnRpY2FsXCI+XG4gICAgQGlmICh0YWJzKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwidGFiLWNvbnRlbnRcIj5cbiAgICAgICAgQGZvciAodGFiIG9mIHRhYnM7IHRyYWNrIHRhYi5pZCkge1xuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIFtpZF09XCJ0YWIuaWQgKyAnLXRhYidcIlxuICAgICAgICAgICAgY2xhc3M9XCJ0YWItcGFuZSBwLTQgZmFkZSB7eyB0YWIuY2xhc3MgPz8gJycgfX1cIlxuICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJ0YWIuYWN0aXZlXCJcbiAgICAgICAgICAgIFtjbGFzcy5zaG93XT1cInRhYi5hY3RpdmVcIlxuICAgICAgICAgICAgcm9sZT1cInRhYnBhbmVsXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxsZWRieV09XCJ0YWIuaWQgKyAnLXRhYi1saW5rJ1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRhYi5odG1sQ29udGVudFwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=