ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
572 lines • 65.9 kB
JavaScript
import { __decorate } from "tslib";
import { coerceNumberProperty } from '@angular/cdk/coercion';
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 { InputBoolean, wrapIntoObservable } from 'ng-zorro-antd/core/util';
import { NzTabChangeEvent } from './interfaces';
import { NzTabNavBarComponent } from './tab-nav-bar.component';
import { NzTabComponent, NZ_TAB_SET } 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 "./tab-nav-bar.component";
import * as i5 from "./tab-close-button.component";
import * as i6 from "./tab-body.component";
import * as i7 from "@angular/common";
import * as i8 from "./tab-nav-item.directive";
import * as i9 from "@angular/cdk/a11y";
import * as i10 from "ng-zorro-antd/core/outlet";
const NZ_CONFIG_MODULE_NAME = 'tabs';
let nextId = 0;
export class NzTabSetComponent {
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++;
}
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 (this.position === 'horizontal' &&
this.line &&
(typeof this.nzAnimated === 'boolean' ? this.nzAnimated : this.nzAnimated.tabPane));
}
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) || isActive(c.routerLinkWithHref) : 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;
}
getTabContentMarginValue() {
return -(this.nzSelectedIndex || 0) * 100;
}
getTabContentMarginLeft() {
if (this.tabPaneAnimated) {
if (this.dir !== 'rtl') {
return `${this.getTabContentMarginValue()}%`;
}
}
return '';
}
getTabContentMarginRight() {
if (this.tabPaneAnimated) {
if (this.dir === 'rtl') {
return `${this.getTabContentMarginValue()}%`;
}
}
return '';
}
}
NzTabSetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", 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 });
NzTabSetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: NzTabSetComponent, 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"
>
<div
role="tab"
[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
nz-tab-close-button
*ngIf="tab.nzClosable && closable && !tab.nzDisabled"
[closeIcon]="tab.nzCloseIcon"
(click)="onClose(i, $event)"
></button>
</div>
</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"
[style.margin-left]="getTabContentMarginLeft()"
[style.margin-right]="getTabContentMarginRight()"
>
<div
nz-tab-body
*ngFor="let tab of tabs; let i = index"
[active]="nzSelectedIndex === i && !nzHideAll"
[content]="tab.content"
[forceRender]="tab.nzForceRender"
[tabPaneAnimated]="tabPaneAnimated"
></div>
</div>
</div>
`, isInline: true, components: [{ type: i4.NzTabNavBarComponent, selector: "nz-tabs-nav", inputs: ["position", "addable", "hideBar", "addIcon", "inkBarAnimated", "extraTemplate", "selectedIndex"], outputs: ["indexFocused", "selectFocusedIndex", "addClicked", "tabScroll"], exportAs: ["nzTabsNav"] }, { type: i5.NzTabCloseButtonComponent, selector: "nz-tab-close-button, button[nz-tab-close-button]", inputs: ["closeIcon"] }, { type: i6.NzTabBodyComponent, selector: "[nz-tab-body]", inputs: ["content", "active", "tabPaneAnimated", "forceRender"], exportAs: ["nzTabBody"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i8.NzTabNavItemDirective, selector: "[nzTabNavItem]", inputs: ["disabled", "tab", "active"] }, { type: i9.CdkMonitorFocus, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: ["cdkFocusChange"] }, { type: i10.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], 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: "13.2.5", 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"
>
<div
role="tab"
[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
nz-tab-close-button
*ngIf="tab.nzClosable && closable && !tab.nzDisabled"
[closeIcon]="tab.nzCloseIcon"
(click)="onClose(i, $event)"
></button>
</div>
</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"
[style.margin-left]="getTabContentMarginLeft()"
[style.margin-right]="getTabContentMarginRight()"
>
<div
nz-tab-body
*ngFor="let tab of tabs; let i = index"
[active]="nzSelectedIndex === i && !nzHideAll"
[content]="tab.content"
[forceRender]="tab.nzForceRender"
[tabPaneAnimated]="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'`
}
}]
}], ctorParameters: function () { return [{ 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFic2V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvdGFicy90YWJzZXQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFRQSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM3RCxPQUFPLEVBR0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxlQUFlLEVBQ2YsWUFBWSxFQUNaLEtBQUssRUFJTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFFVCxTQUFTLEVBQ1QsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxhQUFhLEVBQTBDLE1BQU0saUJBQWlCLENBQUM7QUFDeEYsT0FBTyxFQUFFLEtBQUssRUFBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVFLE9BQU8sRUFBZ0MsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDckYsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRW5ELE9BQU8sRUFBRSxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUUzRSxPQUFPLEVBRUwsZ0JBQWdCLEVBTWpCLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxjQUFjLEVBQUUsVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7Ozs7Ozs7OztBQUU3RCxNQUFNLHFCQUFxQixHQUFnQixNQUFNLENBQUM7QUFFbEQsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBb0dmLE1BQU0sT0FBTyxpQkFB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QW9CO3dCQUM5Qyx3QkFBd0IsRUFBRSxvQkFBb0I7cUJBQy9DO2lCQUNGOzswQkF5RkksUUFBUTs7MEJBQ1IsUUFBUTs0Q0E5RVAsZUFBZTtzQkFEbEIsS0FBSztnQkFPRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLG9CQUFvQjtzQkFBNUIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDaUIsTUFBTTtzQkFBNUIsS0FBSztnQkFDaUIsTUFBTTtzQkFBNUIsS0FBSztnQkFDaUIsVUFBVTtzQkFBaEMsS0FBSztnQkFDaUIsY0FBYztzQkFBcEMsS0FBSztnQkFDbUIsU0FBUztzQkFBakMsS0FBSztnQkFDbUIsVUFBVTtzQkFBbEMsS0FBSztnQkFDbUIsU0FBUztzQkFBakMsS0FBSztnQkFDbUIsWUFBWTtzQkFBcEMsS0FBSztnQkFDbUIsV0FBVztzQkFBbkMsS0FBSztnQkFFYSxjQUFjO3NCQUFoQyxNQUFNO2dCQUNZLHFCQUFxQjtzQkFBdkMsTUFBTTtnQkFDWSxlQUFlO3NCQUFqQyxNQUFNO2dCQUNZLE9BQU87c0JBQXpCLE1BQU07Z0JBQ1ksS0FBSztzQkFBdkIsTUFBTTtnQkFpQ1AsT0FBTztzQkFETixlQUFlO3VCQUFDLGNBQWMsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUU7Z0JBRUYsWUFBWTtzQkFBL0QsU0FBUzt1QkFBQyxvQkFBb0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG4vKiogZ2V0IHNvbWUgY29kZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL21hdGVyaWFsMiAqL1xuXG5pbXBvcnQgeyBEaXJlY3Rpb24sIERpcmVjdGlvbmFsaXR5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2JpZGknO1xuaW1wb3J0IHsgY29lcmNlTnVtYmVyUHJvcGVydHkgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50Q2hlY2tlZCxcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5hdmlnYXRpb25FbmQsIFJvdXRlciwgUm91dGVyTGluaywgUm91dGVyTGlua1dpdGhIcmVmIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IG1lcmdlLCBPYnNlcnZhYmxlLCBvZiwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWxheSwgZmlsdGVyLCBmaXJzdCwgc3RhcnRXaXRoLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE56Q29uZmlnS2V5LCBOekNvbmZpZ1NlcnZpY2UsIFdpdGhDb25maWcgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvY29uZmlnJztcbmltcG9ydCB7IFBSRUZJWCB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9sb2dnZXInO1xuaW1wb3J0IHsgQm9vbGVhbklucHV0LCBOdW1iZXJJbnB1dCwgTnpTYWZlQW55LCBOelNpemVMRFNUeXBlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IElucHV0Qm9vbGVhbiwgd3JhcEludG9PYnNlcnZhYmxlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuXG5pbXBvcnQge1xuICBOekFuaW1hdGVkSW50ZXJmYWNlLFxuICBOelRhYkNoYW5nZUV2ZW50LFxuICBOelRhYlBvc2l0aW9uLFxuICBOelRhYlBvc2l0aW9uTW9kZSxcbiAgTnpUYWJzQ2FuRGVhY3RpdmF0ZUZuLFxuICBOelRhYlNjcm9sbEV2ZW50LFxuICBOelRhYlR5cGVcbn0gZnJvbSAnLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IE56VGFiTmF2QmFyQ29tcG9uZW50IH0gZnJvbSAnLi90YWItbmF2LWJhci5jb21wb25lbnQnO1xuaW1wb3J0IHsgTnpUYWJDb21wb25lbnQsIE5aX1RBQl9TRVQgfSBmcm9tICcuL3RhYi5jb21wb25lbnQnO1xuXG5jb25zdCBOWl9DT05GSUdfTU9EVUxFX05BTUU6IE56Q29uZmlnS2V5ID0gJ3RhYnMnO1xuXG5sZXQgbmV4dElkID0gMDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbnotdGFic2V0JyxcbiAgZXhwb3J0QXM6ICduelRhYnNldCcsXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LkRlZmF1bHQsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5aX1RBQl9TRVQsXG4gICAgICB1c2VFeGlzdGluZzogTnpUYWJTZXRDb21wb25lbnRcbiAgICB9XG4gIF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPG56LXRhYnMtbmF2XG4gICAgICAqbmdJZj1cInRhYnMubGVuZ3RoIHx8IGFkZGFibGVcIlxuICAgICAgW25nU3R5bGVdPVwibnpUYWJCYXJTdHlsZVwiXG4gICAgICBbc2VsZWN0ZWRJbmRleF09XCJuelNlbGVjdGVkSW5kZXggfHwgMFwiXG4gICAgICBbaW5rQmFyQW5pbWF0ZWRdPVwiaW5rQmFyQW5pbWF0ZWRcIlxuICAgICAgW2FkZGFibGVdPVwiYWRkYWJsZVwiXG4gICAgICBbYWRkSWNvbl09XCJuekFkZEljb25cIlxuICAgICAgW2hpZGVCYXJdPVwibnpIaWRlQWxsXCJcbiAgICAgIFtwb3NpdGlvbl09XCJwb3NpdGlvblwiXG4gICAgICBbZXh0cmFUZW1wbGF0ZV09XCJuelRhYkJhckV4dHJhQ29udGVudFwiXG4gICAgICAodGFiU2Nyb2xsKT1cIm56VGFiTGlzdFNjcm9sbC5lbWl0KCRldmVudClcIlxuICAgICAgKHNlbGVjdEZvY3VzZWRJbmRleCk9XCJzZXRTZWxlY3RlZEluZGV4KCRldmVudClcIlxuICAgICAgKGFkZENsaWNrZWQpPVwib25BZGQoKVwiXG4gICAgPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImFudC10YWJzLXRhYlwiXG4gICAgICAgIFtzdHlsZS5tYXJnaW4tcmlnaHQucHhdPVwicG9zaXRpb24gPT09ICdob3Jpem9udGFsJyA/IG56VGFiQmFyR3V0dGVyIDogbnVsbFwiXG4gICAgICAgIFtzdHlsZS5tYXJnaW4tYm90dG9tLnB4XT1cInBvc2l0aW9uID09PSAndmVydGljYWwnID8gbnpUYWJCYXJHdXR0ZXIgOiBudWxsXCJcbiAgICAgICAgW2NsYXNzLmFudC10YWJzLXRhYi1hY3RpdmVdPVwibnpTZWxlY3RlZEluZGV4ID09PSBpXCJcbiAgICAgICAgW2NsYXNzLmFudC10YWJzLXRhYi1kaXNhYmxlZF09XCJ0YWIubnpEaXNhYmxlZFwiXG4gICAgICAgIChjbGljayk9XCJjbGlja05hdkl0ZW0odGFiLCBpLCAkZXZlbnQpXCJcbiAgICAgICAgKGNvbnRleHRtZW51KT1cImNvbnRleHRtZW51TmF2SXRlbSh0YWIsICRldmVudClcIlxuICAgICAgICAqbmdGb3I9XCJsZXQgdGFiIG9mIHRhYnM7IGxldCBpID0gaW5kZXhcIlxuICAgICAgPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgcm9sZT1cInRhYlwiXG4gICAgICAgICAgW2F0dHIudGFiSW5kZXhdPVwiZ2V0VGFiSW5kZXgodGFiLCBpKVwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1kaXNhYmxlZF09XCJ0YWIubnpEaXNhYmxlZFwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1zZWxlY3RlZF09XCJuelNlbGVjdGVkSW5kZXggPT09IGkgJiYgIW56SGlkZUFsbFwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1jb250cm9sc109XCJnZXRUYWJDb250ZW50SWQoaSlcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJ0YWIubnpEaXNhYmxlZFwiXG4gICAgICAgICAgW3RhYl09XCJ0YWJcIlxuICAgICAgICAgIFthY3RpdmVdPVwibnpTZWxlY3RlZEluZGV4ID09PSBpXCJcbiAgICAgICAgICBjbGFzcz1cImFudC10YWJzLXRhYi1idG5cIlxuICAgICAgICAgIG56VGFiTmF2SXRlbVxuICAgICAgICAgIGNka01vbml0b3JFbGVtZW50Rm9jdXNcbiAgICAgICAgPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJ0YWIubGFiZWw7IGNvbnRleHQ6IHsgdmlzaWJsZTogdHJ1ZSB9XCI+e3sgdGFiLmxhYmVsIH19PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgbnotdGFiLWNsb3NlLWJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJ0YWIubnpDbG9zYWJsZSAmJiBjbG9zYWJsZSAmJiAhdGFiLm56RGlzYWJsZWRcIlxuICAgICAgICAgICAgW2Nsb3NlSWNvbl09XCJ0YWIubnpDbG9zZUljb25cIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2xvc2UoaSwgJGV2ZW50KVwiXG4gICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbnotdGFicy1uYXY+XG4gICAgPGRpdiBjbGFzcz1cImFudC10YWJzLWNvbnRlbnQtaG9sZGVyXCI+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiYW50LXRhYnMtY29udGVudFwiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy1jb250ZW50LXRvcF09XCJuelRhYlBvc2l0aW9uID09PSAndG9wJ1wiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy1jb250ZW50LWJvdHRvbV09XCJuelRhYlBvc2l0aW9uID09PSAnYm90dG9tJ1wiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy1jb250ZW50LWxlZnRdPVwibnpUYWJQb3NpdGlvbiA9PT0gJ2xlZnQnXCJcbiAgICAgICAgW2NsYXNzLmFudC10YWJzLWNvbnRlbnQtcmlnaHRdPVwibnpUYWJQb3NpdGlvbiA9PT0gJ3JpZ2h0J1wiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy1jb250ZW50LWFuaW1hdGVkXT1cInRhYlBhbmVBbmltYXRlZFwiXG4gICAgICAgIFtzdHlsZS5tYXJnaW4tbGVmdF09XCJnZXRUYWJDb250ZW50TWFyZ2luTGVmdCgpXCJcbiAgICAgICAgW3N0eWxlLm1hcmdpbi1yaWdodF09XCJnZXRUYWJDb250ZW50TWFyZ2luUmlnaHQoKVwiXG4gICAgICA+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBuei10YWItYm9keVxuICAgICAgICAgICpuZ0Zvcj1cImxldCB0YWIgb2YgdGFiczsgbGV0IGkgPSBpbmRleFwiXG4gICAgICAgICAgW2FjdGl2ZV09XCJuelNlbGVjdGVkSW5kZXggPT09IGkgJiYgIW56SGlkZUFsbFwiXG4gICAgICAgICAgW2NvbnRlbnRdPVwidGFiLmNvbnRlbnRcIlxuICAgICAgICAgIFtmb3JjZVJlbmRlcl09XCJ0YWIubnpGb3JjZVJlbmRlclwiXG4gICAgICAgICAgW3RhYlBhbmVBbmltYXRlZF09XCJ0YWJQYW5lQW5pbWF0ZWRcIlxuICAgICAgICA+PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnYW50LXRhYnMnLFxuICAgICdbY2xhc3MuYW50LXRhYnMtY2FyZF0nOiBgbnpUeXBlID09PSAnY2FyZCcgfHwgbnpUeXBlID09PSAnZWRpdGFibGUtY2FyZCdgLFxuICAgICdbY2xhc3MuYW50LXRhYnMtZWRpdGFibGVdJzogYG56VHlwZSA9PT0gJ2VkaXRhYmxlLWNhcmQnYCxcbiAgICAnW2NsYXNzLmFudC10YWJzLWVkaXRhYmxlLWNhcmRdJzogYG56VHlwZSA9PT0gJ2VkaXRhYmxlLWNhcmQnYCxcbiAgICAnW2NsYXNzLmFudC10YWJzLWNlbnRlcmVkXSc6IGBuekNlbnRlcmVkYCxcbiAgICAnW2NsYXNzLmFudC10YWJzLXJ0bF0nOiBgZGlyID09PSAncnRsJ2AsXG4gICAgJ1tjbGFzcy5hbnQtdGFicy10b3BdJzogYG56VGFiUG9zaXRpb24gPT09ICd0b3AnYCxcbiAgICAnW2NsYXNzLmFudC10YWJzLWJvdHRvbV0nOiBgbnpUYWJQb3NpdGlvbiA9PT0gJ2JvdHRvbSdgLFxuICAgICdbY2xhc3MuYW50LXRhYnMtbGVmdF0nOiBgbnpUYWJQb3NpdGlvbiA9PT0gJ2xlZnQnYCxcbiAgICAnW2NsYXNzLmFudC10YWJzLXJpZ2h0XSc6IGBuelRhYlBvc2l0aW9uID09PSAncmlnaHQnYCxcbiAgICAnW2NsYXNzLmFudC10YWJzLWRlZmF1bHRdJzogYG56U2l6ZSA9PT0gJ2RlZmF1bHQnYCxcbiAgICAnW2NsYXNzLmFudC10YWJzLXNtYWxsXSc6IGBuelNpemUgPT09ICdzbWFsbCdgLFxuICAgICdbY2xhc3MuYW50LXRhYnMtbGFyZ2VdJzogYG56U2l6ZSA9PT0gJ2xhcmdlJ2BcbiAgfVxufSlcbmV4cG9ydCBjbGFzcyBOelRhYlNldENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJDb250ZW50Q2hlY2tlZCwgT25EZXN0cm95LCBBZnRlckNvbnRlbnRJbml0IHtcbiAgcmVhZG9ubHkgX256TW9kdWxlTmFtZTogTnpDb25maWdLZXkgPSBOWl9DT05GSUdfTU9EVUxFX05BTUU7XG5cbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256SGlkZUFkZDogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpIaWRlQWxsOiBCb29sZWFuSW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uekNlbnRlcmVkOiBCb29sZWFuSW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uekxpbmtSb3V0ZXI6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256TGlu