UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

577 lines 67 kB
import { __decorate } from "tslib"; /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ /** get some code from https://github.com/angular/material2 */ import { A11yModule } from '@angular/cdk/a11y'; import { coerceNumberProperty } from '@angular/cdk/coercion'; import { NgForOf, NgIf, NgStyle } from '@angular/common'; import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Input, Optional, Output, QueryList, ViewChild, ViewEncapsulation } from '@angular/core'; import { NavigationEnd } from '@angular/router'; import { merge, of, Subject, Subscription } from 'rxjs'; import { delay, filter, first, startWith, takeUntil } from 'rxjs/operators'; import { WithConfig } from 'ng-zorro-antd/core/config'; import { PREFIX } from 'ng-zorro-antd/core/logger'; import { NzOutletModule } from 'ng-zorro-antd/core/outlet'; import { InputBoolean, wrapIntoObservable } from 'ng-zorro-antd/core/util'; import { NzTabChangeEvent } from './interfaces'; import { NzTabBodyComponent } from './tab-body.component'; import { NzTabCloseButtonComponent } from './tab-close-button.component'; import { NzTabNavBarComponent } from './tab-nav-bar.component'; import { NzTabNavItemDirective } from './tab-nav-item.directive'; import { NZ_TAB_SET, NzTabComponent } from './tab.component'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd/core/config"; import * as i2 from "@angular/cdk/bidi"; import * as i3 from "@angular/router"; import * as i4 from "@angular/cdk/a11y"; import * as i5 from "ng-zorro-antd/core/outlet"; const NZ_CONFIG_MODULE_NAME = 'tabs'; let nextId = 0; export class NzTabSetComponent { get nzSelectedIndex() { return this.selectedIndex; } set nzSelectedIndex(value) { this.indexToSelect = coerceNumberProperty(value, null); } get position() { return ['top', 'bottom'].indexOf(this.nzTabPosition) === -1 ? 'vertical' : 'horizontal'; } get addable() { return this.nzType === 'editable-card' && !this.nzHideAdd; } get closable() { return this.nzType === 'editable-card'; } get line() { return this.nzType === 'line'; } get inkBarAnimated() { return this.line && (typeof this.nzAnimated === 'boolean' ? this.nzAnimated : this.nzAnimated.inkBar); } get tabPaneAnimated() { return typeof this.nzAnimated === 'boolean' ? this.nzAnimated : this.nzAnimated.tabPane; } constructor(nzConfigService, ngZone, cdr, directionality, router) { this.nzConfigService = nzConfigService; this.ngZone = ngZone; this.cdr = cdr; this.directionality = directionality; this.router = router; this._nzModuleName = NZ_CONFIG_MODULE_NAME; this.nzTabPosition = 'top'; this.nzCanDeactivate = null; this.nzAddIcon = 'plus'; this.nzTabBarStyle = null; this.nzType = 'line'; this.nzSize = 'default'; this.nzAnimated = true; this.nzTabBarGutter = undefined; this.nzHideAdd = false; this.nzCentered = false; this.nzHideAll = false; this.nzLinkRouter = false; this.nzLinkExact = true; this.nzSelectChange = new EventEmitter(true); this.nzSelectedIndexChange = new EventEmitter(); this.nzTabListScroll = new EventEmitter(); this.nzClose = new EventEmitter(); this.nzAdd = new EventEmitter(); // Pick up only direct descendants under ivy rendering engine // We filter out only the tabs that belong to this tab set in `tabs`. this.allTabs = new QueryList(); // All the direct tabs for this tab set this.tabs = new QueryList(); this.dir = 'ltr'; this.destroy$ = new Subject(); this.indexToSelect = 0; this.selectedIndex = null; this.tabLabelSubscription = Subscription.EMPTY; this.tabsSubscription = Subscription.EMPTY; this.canDeactivateSubscription = Subscription.EMPTY; this.tabSetId = nextId++; } ngOnInit() { this.dir = this.directionality.value; this.directionality.change?.pipe(takeUntil(this.destroy$)).subscribe((direction) => { this.dir = direction; this.cdr.detectChanges(); }); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); this.tabs.destroy(); this.tabLabelSubscription.unsubscribe(); this.tabsSubscription.unsubscribe(); this.canDeactivateSubscription.unsubscribe(); } ngAfterContentInit() { this.ngZone.runOutsideAngular(() => { Promise.resolve().then(() => this.setUpRouter()); }); this.subscribeToTabLabels(); this.subscribeToAllTabChanges(); // Subscribe to changes in the amount of tabs, in order to be // able to re-render the content as new tabs are added or removed. this.tabsSubscription = this.tabs.changes.subscribe(() => { const indexToSelect = this.clampTabIndex(this.indexToSelect); // Maintain the previously-selected tab if a new tab is added or removed and there is no // explicit change that selects a different tab. if (indexToSelect === this.selectedIndex) { const tabs = this.tabs.toArray(); for (let i = 0; i < tabs.length; i++) { if (tabs[i].isActive) { // Assign both to the `indexToSelect` and `selectedIndex` so we don't fire a changed // event, otherwise the consumer may end up in an infinite loop in some edge cases like // adding a tab within the `nzSelectedIndexChange` event. this.indexToSelect = this.selectedIndex = i; break; } } } this.subscribeToTabLabels(); this.cdr.markForCheck(); }); } ngAfterContentChecked() { // Don't clamp the `indexToSelect` immediately in the setter because it can happen that // the amount of tabs changes before the actual change detection runs. const indexToSelect = (this.indexToSelect = this.clampTabIndex(this.indexToSelect)); // If there is a change in selected index, emit a change event. Should not trigger if // the selected index has not yet been initialized. if (this.selectedIndex !== indexToSelect) { const isFirstRun = this.selectedIndex == null; if (!isFirstRun) { this.nzSelectChange.emit(this.createChangeEvent(indexToSelect)); } // Changing these values after change detection has run // since the checked content may contain references to them. Promise.resolve().then(() => { this.tabs.forEach((tab, index) => (tab.isActive = index === indexToSelect)); if (!isFirstRun) { this.nzSelectedIndexChange.emit(indexToSelect); } }); } // Setup the position for each tab and optionally setup an origin on the next selected tab. this.tabs.forEach((tab, index) => { tab.position = index - indexToSelect; // If there is already a selected tab, then set up an origin for the next selected tab // if it doesn't have one already. if (this.selectedIndex != null && tab.position === 0 && !tab.origin) { tab.origin = indexToSelect - this.selectedIndex; } }); if (this.selectedIndex !== indexToSelect) { this.selectedIndex = indexToSelect; this.cdr.markForCheck(); } } onClose(index, e) { e.preventDefault(); e.stopPropagation(); this.nzClose.emit({ index }); } onAdd() { this.nzAdd.emit(); } clampTabIndex(index) { return Math.min(this.tabs.length - 1, Math.max(index || 0, 0)); } createChangeEvent(index) { const event = new NzTabChangeEvent(); event.index = index; if (this.tabs && this.tabs.length) { event.tab = this.tabs.toArray()[index]; this.tabs.forEach((tab, i) => { if (i !== index) { tab.nzDeselect.emit(); } }); event.tab.nzSelect.emit(); } return event; } subscribeToTabLabels() { if (this.tabLabelSubscription) { this.tabLabelSubscription.unsubscribe(); } this.tabLabelSubscription = merge(...this.tabs.map(tab => tab.stateChanges)).subscribe(() => this.cdr.markForCheck()); } subscribeToAllTabChanges() { this.allTabs.changes.pipe(startWith(this.allTabs)).subscribe((tabs) => { this.tabs.reset(tabs.filter(tab => tab.closestTabSet === this)); this.tabs.notifyOnChanges(); }); } canDeactivateFun(pre, next) { if (typeof this.nzCanDeactivate === 'function') { const observable = wrapIntoObservable(this.nzCanDeactivate(pre, next)); return observable.pipe(first(), takeUntil(this.destroy$)); } else { return of(true); } } clickNavItem(tab, index, e) { if (!tab.nzDisabled) { // ignore nzCanDeactivate tab.nzClick.emit(); if (!this.isRouterLinkClickEvent(index, e)) { this.setSelectedIndex(index); } } } isRouterLinkClickEvent(index, event) { const target = event.target; if (this.nzLinkRouter) { return !!this.tabs.toArray()[index]?.linkDirective?.elementRef.nativeElement.contains(target); } else { return false; } } contextmenuNavItem(tab, e) { if (!tab.nzDisabled) { // ignore nzCanDeactivate tab.nzContextmenu.emit(e); } } setSelectedIndex(index) { this.canDeactivateSubscription.unsubscribe(); this.canDeactivateSubscription = this.canDeactivateFun(this.selectedIndex, index).subscribe(can => { if (can) { this.nzSelectedIndex = index; this.tabNavBarRef.focusIndex = index; this.cdr.markForCheck(); } }); } getTabIndex(tab, index) { if (tab.nzDisabled) { return null; } return this.selectedIndex === index ? 0 : -1; } getTabContentId(i) { return `nz-tabs-${this.tabSetId}-tab-${i}`; } setUpRouter() { if (this.nzLinkRouter) { if (!this.router) { throw new Error(`${PREFIX} you should import 'RouterModule' if you want to use 'nzLinkRouter'!`); } this.router.events .pipe(takeUntil(this.destroy$), filter(e => e instanceof NavigationEnd), startWith(true), delay(0)) .subscribe(() => { this.updateRouterActive(); this.cdr.markForCheck(); }); } } updateRouterActive() { if (this.router.navigated) { const index = this.findShouldActiveTabIndex(); if (index !== this.selectedIndex) { this.setSelectedIndex(index); } this.nzHideAll = index === -1; } } findShouldActiveTabIndex() { const tabs = this.tabs.toArray(); const isActive = this.isLinkActive(this.router); return tabs.findIndex(tab => { const c = tab.linkDirective; return c ? isActive(c.routerLink) : false; }); } isLinkActive(router) { return (link) => link ? router.isActive(link.urlTree || '', { paths: this.nzLinkExact ? 'exact' : 'subset', queryParams: this.nzLinkExact ? 'exact' : 'subset', fragment: 'ignored', matrixParams: 'ignored' }) : false; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: NzTabSetComponent, deps: [{ token: i1.NzConfigService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i2.Directionality, optional: true }, { token: i3.Router, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: NzTabSetComponent, isStandalone: true, selector: "nz-tabset", inputs: { nzSelectedIndex: "nzSelectedIndex", nzTabPosition: "nzTabPosition", nzTabBarExtraContent: "nzTabBarExtraContent", nzCanDeactivate: "nzCanDeactivate", nzAddIcon: "nzAddIcon", nzTabBarStyle: "nzTabBarStyle", nzType: "nzType", nzSize: "nzSize", nzAnimated: "nzAnimated", nzTabBarGutter: "nzTabBarGutter", nzHideAdd: "nzHideAdd", nzCentered: "nzCentered", nzHideAll: "nzHideAll", nzLinkRouter: "nzLinkRouter", nzLinkExact: "nzLinkExact" }, outputs: { nzSelectChange: "nzSelectChange", nzSelectedIndexChange: "nzSelectedIndexChange", nzTabListScroll: "nzTabListScroll", nzClose: "nzClose", nzAdd: "nzAdd" }, host: { properties: { "class.ant-tabs-card": "nzType === 'card' || nzType === 'editable-card'", "class.ant-tabs-editable": "nzType === 'editable-card'", "class.ant-tabs-editable-card": "nzType === 'editable-card'", "class.ant-tabs-centered": "nzCentered", "class.ant-tabs-rtl": "dir === 'rtl'", "class.ant-tabs-top": "nzTabPosition === 'top'", "class.ant-tabs-bottom": "nzTabPosition === 'bottom'", "class.ant-tabs-left": "nzTabPosition === 'left'", "class.ant-tabs-right": "nzTabPosition === 'right'", "class.ant-tabs-default": "nzSize === 'default'", "class.ant-tabs-small": "nzSize === 'small'", "class.ant-tabs-large": "nzSize === 'large'" }, classAttribute: "ant-tabs" }, providers: [ { provide: NZ_TAB_SET, useExisting: NzTabSetComponent } ], queries: [{ propertyName: "allTabs", predicate: NzTabComponent, descendants: true }], viewQueries: [{ propertyName: "tabNavBarRef", first: true, predicate: NzTabNavBarComponent, descendants: true }], exportAs: ["nzTabset"], ngImport: i0, template: ` <nz-tabs-nav *ngIf="tabs.length || addable" [ngStyle]="nzTabBarStyle" [selectedIndex]="nzSelectedIndex || 0" [inkBarAnimated]="inkBarAnimated" [addable]="addable" [addIcon]="nzAddIcon" [hideBar]="nzHideAll" [position]="position" [extraTemplate]="nzTabBarExtraContent" (tabScroll)="nzTabListScroll.emit($event)" (selectFocusedIndex)="setSelectedIndex($event)" (addClicked)="onAdd()" > <div class="ant-tabs-tab" [style.margin-right.px]="position === 'horizontal' ? nzTabBarGutter : null" [style.margin-bottom.px]="position === 'vertical' ? nzTabBarGutter : null" [class.ant-tabs-tab-active]="nzSelectedIndex === i" [class.ant-tabs-tab-disabled]="tab.nzDisabled" (click)="clickNavItem(tab, i, $event)" (contextmenu)="contextmenuNavItem(tab, $event)" *ngFor="let tab of tabs; let i = index" > <button type="button" role="tab" [id]="getTabContentId(i)" [attr.tabIndex]="getTabIndex(tab, i)" [attr.aria-disabled]="tab.nzDisabled" [attr.aria-selected]="nzSelectedIndex === i && !nzHideAll" [attr.aria-controls]="getTabContentId(i)" [disabled]="tab.nzDisabled" [tab]="tab" [active]="nzSelectedIndex === i" class="ant-tabs-tab-btn" nzTabNavItem cdkMonitorElementFocus > <ng-container *nzStringTemplateOutlet="tab.label; context: { visible: true }">{{ tab.label }}</ng-container> <button type="button" nz-tab-close-button *ngIf="tab.nzClosable && closable && !tab.nzDisabled" [closeIcon]="tab.nzCloseIcon" (click)="onClose(i, $event)" ></button> </button> </div> </nz-tabs-nav> <div class="ant-tabs-content-holder"> <div class="ant-tabs-content" [class.ant-tabs-content-top]="nzTabPosition === 'top'" [class.ant-tabs-content-bottom]="nzTabPosition === 'bottom'" [class.ant-tabs-content-left]="nzTabPosition === 'left'" [class.ant-tabs-content-right]="nzTabPosition === 'right'" [class.ant-tabs-content-animated]="tabPaneAnimated" > <div role="tabpanel" [id]="getTabContentId(i)" [attr.aria-labelledby]="getTabContentId(i)" nz-tab-body *ngFor="let tab of tabs; let i = index" [active]="nzSelectedIndex === i && !nzHideAll" [content]="tab.content" [forceRender]="tab.nzForceRender" [animated]="tabPaneAnimated" ></div> </div> </div> `, isInline: true, dependencies: [{ kind: "component", type: NzTabNavBarComponent, selector: "nz-tabs-nav", inputs: ["position", "addable", "hideBar", "addIcon", "inkBarAnimated", "extraTemplate", "selectedIndex"], outputs: ["indexFocused", "selectFocusedIndex", "addClicked", "tabScroll"], exportAs: ["nzTabsNav"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NzTabNavItemDirective, selector: "[nzTabNavItem]", inputs: ["disabled", "tab", "active"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i4.CdkMonitorFocus, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: ["cdkFocusChange"], exportAs: ["cdkMonitorFocus"] }, { kind: "ngmodule", type: NzOutletModule }, { kind: "directive", type: i5.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }, { kind: "component", type: NzTabCloseButtonComponent, selector: "nz-tab-close-button, button[nz-tab-close-button]", inputs: ["closeIcon"] }, { kind: "component", type: NzTabBodyComponent, selector: "[nz-tab-body]", inputs: ["content", "active", "animated", "forceRender"], exportAs: ["nzTabBody"] }], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None }); } } __decorate([ WithConfig() ], NzTabSetComponent.prototype, "nzType", void 0); __decorate([ WithConfig() ], NzTabSetComponent.prototype, "nzSize", void 0); __decorate([ WithConfig() ], NzTabSetComponent.prototype, "nzAnimated", void 0); __decorate([ WithConfig() ], NzTabSetComponent.prototype, "nzTabBarGutter", void 0); __decorate([ InputBoolean() ], NzTabSetComponent.prototype, "nzHideAdd", void 0); __decorate([ InputBoolean() ], NzTabSetComponent.prototype, "nzCentered", void 0); __decorate([ InputBoolean() ], NzTabSetComponent.prototype, "nzHideAll", void 0); __decorate([ InputBoolean() ], NzTabSetComponent.prototype, "nzLinkRouter", void 0); __decorate([ InputBoolean() ], NzTabSetComponent.prototype, "nzLinkExact", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: NzTabSetComponent, decorators: [{ type: Component, args: [{ selector: 'nz-tabset', exportAs: 'nzTabset', preserveWhitespaces: false, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [ { provide: NZ_TAB_SET, useExisting: NzTabSetComponent } ], template: ` <nz-tabs-nav *ngIf="tabs.length || addable" [ngStyle]="nzTabBarStyle" [selectedIndex]="nzSelectedIndex || 0" [inkBarAnimated]="inkBarAnimated" [addable]="addable" [addIcon]="nzAddIcon" [hideBar]="nzHideAll" [position]="position" [extraTemplate]="nzTabBarExtraContent" (tabScroll)="nzTabListScroll.emit($event)" (selectFocusedIndex)="setSelectedIndex($event)" (addClicked)="onAdd()" > <div class="ant-tabs-tab" [style.margin-right.px]="position === 'horizontal' ? nzTabBarGutter : null" [style.margin-bottom.px]="position === 'vertical' ? nzTabBarGutter : null" [class.ant-tabs-tab-active]="nzSelectedIndex === i" [class.ant-tabs-tab-disabled]="tab.nzDisabled" (click)="clickNavItem(tab, i, $event)" (contextmenu)="contextmenuNavItem(tab, $event)" *ngFor="let tab of tabs; let i = index" > <button type="button" role="tab" [id]="getTabContentId(i)" [attr.tabIndex]="getTabIndex(tab, i)" [attr.aria-disabled]="tab.nzDisabled" [attr.aria-selected]="nzSelectedIndex === i && !nzHideAll" [attr.aria-controls]="getTabContentId(i)" [disabled]="tab.nzDisabled" [tab]="tab" [active]="nzSelectedIndex === i" class="ant-tabs-tab-btn" nzTabNavItem cdkMonitorElementFocus > <ng-container *nzStringTemplateOutlet="tab.label; context: { visible: true }">{{ tab.label }}</ng-container> <button type="button" nz-tab-close-button *ngIf="tab.nzClosable && closable && !tab.nzDisabled" [closeIcon]="tab.nzCloseIcon" (click)="onClose(i, $event)" ></button> </button> </div> </nz-tabs-nav> <div class="ant-tabs-content-holder"> <div class="ant-tabs-content" [class.ant-tabs-content-top]="nzTabPosition === 'top'" [class.ant-tabs-content-bottom]="nzTabPosition === 'bottom'" [class.ant-tabs-content-left]="nzTabPosition === 'left'" [class.ant-tabs-content-right]="nzTabPosition === 'right'" [class.ant-tabs-content-animated]="tabPaneAnimated" > <div role="tabpanel" [id]="getTabContentId(i)" [attr.aria-labelledby]="getTabContentId(i)" nz-tab-body *ngFor="let tab of tabs; let i = index" [active]="nzSelectedIndex === i && !nzHideAll" [content]="tab.content" [forceRender]="tab.nzForceRender" [animated]="tabPaneAnimated" ></div> </div> </div> `, host: { class: 'ant-tabs', '[class.ant-tabs-card]': `nzType === 'card' || nzType === 'editable-card'`, '[class.ant-tabs-editable]': `nzType === 'editable-card'`, '[class.ant-tabs-editable-card]': `nzType === 'editable-card'`, '[class.ant-tabs-centered]': `nzCentered`, '[class.ant-tabs-rtl]': `dir === 'rtl'`, '[class.ant-tabs-top]': `nzTabPosition === 'top'`, '[class.ant-tabs-bottom]': `nzTabPosition === 'bottom'`, '[class.ant-tabs-left]': `nzTabPosition === 'left'`, '[class.ant-tabs-right]': `nzTabPosition === 'right'`, '[class.ant-tabs-default]': `nzSize === 'default'`, '[class.ant-tabs-small]': `nzSize === 'small'`, '[class.ant-tabs-large]': `nzSize === 'large'` }, imports: [ NzTabNavBarComponent, NgIf, NgStyle, NgForOf, NzTabNavItemDirective, A11yModule, NzOutletModule, NzTabCloseButtonComponent, NzTabBodyComponent ], standalone: true }] }], ctorParameters: () => [{ type: i1.NzConfigService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i2.Directionality, decorators: [{ type: Optional }] }, { type: i3.Router, decorators: [{ type: Optional }] }], propDecorators: { nzSelectedIndex: [{ type: Input }], nzTabPosition: [{ type: Input }], nzTabBarExtraContent: [{ type: Input }], nzCanDeactivate: [{ type: Input }], nzAddIcon: [{ type: Input }], nzTabBarStyle: [{ type: Input }], nzType: [{ type: Input }], nzSize: [{ type: Input }], nzAnimated: [{ type: Input }], nzTabBarGutter: [{ type: Input }], nzHideAdd: [{ type: Input }], nzCentered: [{ type: Input }], nzHideAll: [{ type: Input }], nzLinkRouter: [{ type: Input }], nzLinkExact: [{ type: Input }], nzSelectChange: [{ type: Output }], nzSelectedIndexChange: [{ type: Output }], nzTabListScroll: [{ type: Output }], nzClose: [{ type: Output }], nzAdd: [{ type: Output }], allTabs: [{ type: ContentChildren, args: [NzTabComponent, { descendants: true }] }], tabNavBarRef: [{ type: ViewChild, args: [NzTabNavBarComponent, { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFic2V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvdGFicy90YWJzZXQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7QUFFSCw4REFBOEQ7QUFFOUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRS9DLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdELE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFHTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULGVBQWUsRUFDZixZQUFZLEVBQ1osS0FBSyxFQUlMLFFBQVEsRUFDUixNQUFNLEVBQ04sU0FBUyxFQUVULFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGFBQWEsRUFBc0IsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsS0FBSyxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFNUUsT0FBTyxFQUFnQyxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUUzRSxPQUFPLEVBRUwsZ0JBQWdCLEVBTWpCLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFBRSxrQkFB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QUFTO3VCQUFDLG9CQUFvQixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbi8qKiBnZXQgc29tZSBjb2RlIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvbWF0ZXJpYWwyICovXG5cbmltcG9ydCB7IEExMXlNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyBEaXJlY3Rpb24sIERpcmVjdGlvbmFsaXR5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2JpZGknO1xuaW1wb3J0IHsgY29lcmNlTnVtYmVyUHJvcGVydHkgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHsgTmdGb3JPZiwgTmdJZiwgTmdTdHlsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRDaGVja2VkLFxuICBBZnRlckNvbnRlbnRJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmF2aWdhdGlvbkVuZCwgUm91dGVyLCBSb3V0ZXJMaW5rIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IG1lcmdlLCBPYnNlcnZhYmxlLCBvZiwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWxheSwgZmlsdGVyLCBmaXJzdCwgc3RhcnRXaXRoLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE56Q29uZmlnS2V5LCBOekNvbmZpZ1NlcnZpY2UsIFdpdGhDb25maWcgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvY29uZmlnJztcbmltcG9ydCB7IFBSRUZJWCB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9sb2dnZXInO1xuaW1wb3J0IHsgTnpPdXRsZXRNb2R1bGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvb3V0bGV0JztcbmltcG9ydCB7IEJvb2xlYW5JbnB1dCwgTnVtYmVySW5wdXQsIE56U2FmZUFueSwgTnpTaXplTERTVHlwZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBJbnB1dEJvb2xlYW4sIHdyYXBJbnRvT2JzZXJ2YWJsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS91dGlsJztcblxuaW1wb3J0IHtcbiAgTnpBbmltYXRlZEludGVyZmFjZSxcbiAgTnpUYWJDaGFuZ2VFdmVudCxcbiAgTnpUYWJQb3NpdGlvbixcbiAgTnpUYWJQb3NpdGlvbk1vZGUsXG4gIE56VGFic0NhbkRlYWN0aXZhdGVGbixcbiAgTnpUYWJTY3JvbGxFdmVudCxcbiAgTnpUYWJUeXBlXG59IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBOelRhYkJvZHlDb21wb25lbnQgfSBmcm9tICcuL3RhYi1ib2R5LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOelRhYkNsb3NlQnV0dG9uQ29tcG9uZW50IH0gZnJvbSAnLi90YWItY2xvc2UtYnV0dG9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOelRhYk5hdkJhckNvbXBvbmVudCB9IGZyb20gJy4vdGFiLW5hdi1iYXIuY29tcG9uZW50JztcbmltcG9ydCB7IE56VGFiTmF2SXRlbURpcmVjdGl2ZSB9IGZyb20gJy4vdGFiLW5hdi1pdGVtLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBOWl9UQUJfU0VULCBOelRhYkNvbXBvbmVudCB9IGZyb20gJy4vdGFiLmNvbXBvbmVudCc7XG5cbmNvbnN0IE5aX0NPTkZJR19NT0RVTEVfTkFNRTogTnpDb25maWdLZXkgPSAndGFicyc7XG5cbmxldCBuZXh0SWQgPSAwO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei10YWJzZXQnLFxuICBleHBvcnRBczogJ256VGFic2V0JyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuRGVmYXVsdCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTlpfVEFCX1NFVCxcbiAgICAgIHVzZUV4aXN0aW5nOiBOelRhYlNldENvbXBvbmVudFxuICAgIH1cbiAgXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8bnotdGFicy1uYXZcbiAgICAgICpuZ0lmPVwidGFicy5sZW5ndGggfHwgYWRkYWJsZVwiXG4gICAgICBbbmdTdHlsZV09XCJuelRhYkJhclN0eWxlXCJcbiAgICAgIFtzZWxlY3RlZEluZGV4XT1cIm56U2VsZWN0ZWRJbmRleCB8fCAwXCJcbiAgICAgIFtpbmtCYXJBbmltYXRlZF09XCJpbmtCYXJBbmltYXRlZFwiXG4gICAgICBbYWRkYWJsZV09XCJhZGRhYmxlXCJcbiAgICAgIFthZGRJY29uXT1cIm56QWRkSWNvblwiXG4gICAgICBbaGlkZUJhcl09XCJuekhpZGVBbGxcIlxuICAgICAgW3Bvc2l0aW9uXT1cInBvc2l0aW9uXCJcbiAgICAgIFtleHRyYVRlbXBsYXRlXT1cIm56VGFiQmFyRXh0cmFDb250ZW50XCJcbiAgICAgICh0YWJTY3JvbGwpPVwibnpUYWJMaXN0U2Nyb2xsLmVtaXQoJGV2ZW50KVwiXG4gICAgICAoc2VsZWN0Rm9jdXNlZEluZGV4KT1cInNldFNlbGVjdGVkSW5kZXgoJGV2ZW50KVwiXG4gICAgICAoYWRkQ2xpY2tlZCk9XCJvbkFkZCgpXCJcbiAgICA+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiYW50LXRhYnMtdGFiXCJcbiAgICAgICAgW3N0eWxlLm1hcmdpbi1yaWdodC5weF09XCJwb3NpdGlvbiA9PT0gJ2hvcml6b250YWwnID8gbnpUYWJCYXJHdXR0ZXIgOiBudWxsXCJcbiAgICAgICAgW3N0eWxlLm1hcmdpbi1ib3R0b20ucHhdPVwicG9zaXRpb24gPT09ICd2ZXJ0aWNhbCcgPyBuelRhYkJhckd1dHRlciA6IG51bGxcIlxuICAgICAgICBbY2xhc3MuYW50LXRhYnMtdGFiLWFjdGl2ZV09XCJuelNlbGVjdGVkSW5kZXggPT09IGlcIlxuICAgICAgICBbY2xhc3MuYW50LXRhYnMtdGFiLWRpc2FibGVkXT1cInRhYi5uekRpc2FibGVkXCJcbiAgICAgICAgKGNsaWNrKT1cImNsaWNrTmF2SXRlbSh0YWIsIGksICRldmVudClcIlxuICAgICAgICAoY29udGV4dG1lbnUpPVwiY29udGV4dG1lbnVOYXZJdGVtKHRhYiwgJGV2ZW50KVwiXG4gICAgICAgICpuZ0Zvcj1cImxldCB0YWIgb2YgdGFiczsgbGV0IGkgPSBpbmRleFwiXG4gICAgICA+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICByb2xlPVwidGFiXCJcbiAgICAgICAgICBbaWRdPVwiZ2V0VGFiQ29udGVudElkKGkpXCJcbiAgICAgICAgICBbYXR0ci50YWJJbmRleF09XCJnZXRUYWJJbmRleCh0YWIsIGkpXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWRpc2FibGVkXT1cInRhYi5uekRpc2FibGVkXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLXNlbGVjdGVkXT1cIm56U2VsZWN0ZWRJbmRleCA9PT0gaSAmJiAhbnpIaWRlQWxsXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cImdldFRhYkNvbnRlbnRJZChpKVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cInRhYi5uekRpc2FibGVkXCJcbiAgICAgICAgICBbdGFiXT1cInRhYlwiXG4gICAgICAgICAgW2FjdGl2ZV09XCJuelNlbGVjdGVkSW5kZXggPT09IGlcIlxuICAgICAgICAgIGNsYXNzPVwiYW50LXRhYnMtdGFiLWJ0blwiXG4gICAgICAgICAgbnpUYWJOYXZJdGVtXG4gICAgICAgICAgY2RrTW9uaXRvckVsZW1lbnRGb2N1c1xuICAgICAgICA+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbnpTdHJpbmdUZW1wbGF0ZU91dGxldD1cInRhYi5sYWJlbDsgY29udGV4dDogeyB2aXNpYmxlOiB0cnVlIH1cIj57eyB0YWIubGFiZWwgfX08L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIG56LXRhYi1jbG9zZS1idXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwidGFiLm56Q2xvc2FibGUgJiYgY2xvc2FibGUgJiYgIXRhYi5uekRpc2FibGVkXCJcbiAgICAgICAgICAgIFtjbG9zZUljb25dPVwidGFiLm56Q2xvc2VJY29uXCJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkNsb3NlKGksICRldmVudClcIlxuICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L256LXRhYnMtbmF2PlxuICAgIDxkaXYgY2xhc3M9XCJhbnQtdGFicy1jb250ZW50LWhvbGRlclwiPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImFudC10YWJzLWNvbnRlbnRcIlxuICAgICAgICBbY2xhc3MuYW50LXRhYnMtY29udGVudC10b3BdPVwibnpUYWJQb3NpdGlvbiA9PT0gJ3RvcCdcIlxuICAgICAgICBbY2xhc3MuYW50LXRhYnMtY29udGVudC1ib3R0b21dPVwibnpUYWJQb3NpdGlvbiA9PT0gJ2JvdHRvbSdcIlxuICAgICAgICBbY2xhc3MuYW50LXRhYnMtY29udGVudC1sZWZ0XT1cIm56VGFiUG9zaXRpb24gPT09ICdsZWZ0J1wiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy1jb250ZW50LXJpZ2h0XT1cIm56VGFiUG9zaXRpb24gPT09ICdyaWdodCdcIlxuICAgICAgICBbY2xhc3MuYW50LXRhYnMtY29udGVudC1hbmltYXRlZF09XCJ0YWJQYW5lQW5pbWF0ZWRcIlxuICAgICAgPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgcm9sZT1cInRhYnBhbmVsXCJcbiAgICAgICAgICBbaWRdPVwiZ2V0VGFiQ29udGVudElkKGkpXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsbGVkYnldPVwiZ2V0VGFiQ29udGVudElkKGkpXCJcbiAgICAgICAgICBuei10YWItYm9keVxuICAgICAgICAgICpuZ0Zvcj1cImxldCB0YWIgb2YgdGFiczsgbGV0IGkgPSBpbmRleFwiXG4gICAgICAgICAgW2FjdGl2ZV09XCJuelNlbGVjdGVkSW5kZXggPT09IGkgJiYgIW56SGlkZUFsbFwiXG4gICAgICAgICAgW2NvbnRlbnRdPVwidGFiLmNvbnRlbnRcIlxuICAgICAgICAgIFtmb3JjZVJlbmRlcl09XCJ0YWIubnpGb3JjZVJlbmRlclwiXG4gICAgICAgICAgW2FuaW1hdGVkXT1cInRhYlBhbmVBbmltYXRlZFwiXG4gICAgICAgID48L2Rp