ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
332 lines • 37.8 kB
JavaScript
/**
* 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
*/
import { BACKSPACE } from '@angular/cdk/keycodes';
import { NgFor, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, Host, Input, Optional, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { fromEvent, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { NzSelectItemComponent } from './select-item.component';
import { NzSelectPlaceholderComponent } from './select-placeholder.component';
import { NzSelectSearchComponent } from './select-search.component';
import * as i0 from "@angular/core";
import * as i1 from "ng-zorro-antd/core/no-animation";
export class NzSelectTopControlComponent {
updateTemplateVariable() {
const isSelectedValueEmpty = this.listOfTopItem.length === 0;
this.isShowPlaceholder = isSelectedValueEmpty && !this.isComposing && !this.inputValue;
this.isShowSingleLabel = !isSelectedValueEmpty && !this.isComposing && !this.inputValue;
}
isComposingChange(isComposing) {
this.isComposing = isComposing;
this.updateTemplateVariable();
}
onInputValueChange(value) {
if (value !== this.inputValue) {
this.inputValue = value;
this.updateTemplateVariable();
this.inputValueChange.emit(value);
this.tokenSeparate(value, this.tokenSeparators);
}
}
tokenSeparate(inputValue, tokenSeparators) {
const includesSeparators = (str, separators) => {
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < separators.length; ++i) {
if (str.lastIndexOf(separators[i]) > 0) {
return true;
}
}
return false;
};
const splitBySeparators = (str, separators) => {
const reg = new RegExp(`[${separators.join()}]`);
const array = str.split(reg).filter(token => token);
return [...new Set(array)];
};
if (inputValue &&
inputValue.length &&
tokenSeparators.length &&
this.mode !== 'default' &&
includesSeparators(inputValue, tokenSeparators)) {
const listOfLabel = splitBySeparators(inputValue, tokenSeparators);
this.tokenize.next(listOfLabel);
}
}
clearInputValue() {
if (this.nzSelectSearchComponent) {
this.nzSelectSearchComponent.clearInputValue();
}
}
focus() {
if (this.nzSelectSearchComponent) {
this.nzSelectSearchComponent.focus();
}
}
blur() {
if (this.nzSelectSearchComponent) {
this.nzSelectSearchComponent.blur();
}
}
trackValue(_index, option) {
return option.nzValue;
}
onDeleteItem(item) {
if (!this.disabled && !item.nzDisabled) {
this.deleteItem.next(item);
}
}
constructor(elementRef, ngZone, noAnimation) {
this.elementRef = elementRef;
this.ngZone = ngZone;
this.noAnimation = noAnimation;
this.nzId = null;
this.showSearch = false;
this.placeHolder = null;
this.open = false;
this.maxTagCount = Infinity;
this.autofocus = false;
this.disabled = false;
this.mode = 'default';
this.customTemplate = null;
this.maxTagPlaceholder = null;
this.removeIcon = null;
this.listOfTopItem = [];
this.tokenSeparators = [];
this.tokenize = new EventEmitter();
this.inputValueChange = new EventEmitter();
this.deleteItem = new EventEmitter();
this.listOfSlicedItem = [];
this.isShowPlaceholder = true;
this.isShowSingleLabel = false;
this.isComposing = false;
this.inputValue = null;
this.destroy$ = new Subject();
}
ngOnChanges(changes) {
const { listOfTopItem, maxTagCount, customTemplate, maxTagPlaceholder } = changes;
if (listOfTopItem) {
this.updateTemplateVariable();
}
if (listOfTopItem || maxTagCount || customTemplate || maxTagPlaceholder) {
const listOfSlicedItem = this.listOfTopItem.slice(0, this.maxTagCount).map(o => ({
nzLabel: o.nzLabel,
nzValue: o.nzValue,
nzDisabled: o.nzDisabled,
contentTemplateOutlet: this.customTemplate,
contentTemplateOutletContext: o
}));
if (this.listOfTopItem.length > this.maxTagCount) {
const exceededLabel = `+ ${this.listOfTopItem.length - this.maxTagCount} ...`;
const listOfSelectedValue = this.listOfTopItem.map(item => item.nzValue);
const exceededItem = {
nzLabel: exceededLabel,
nzValue: '$$__nz_exceeded_item',
nzDisabled: true,
contentTemplateOutlet: this.maxTagPlaceholder,
contentTemplateOutletContext: listOfSelectedValue.slice(this.maxTagCount)
};
listOfSlicedItem.push(exceededItem);
}
this.listOfSlicedItem = listOfSlicedItem;
}
}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
fromEvent(this.elementRef.nativeElement, 'click')
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
// `HTMLElement.focus()` is a native DOM API which doesn't require Angular to run change detection.
if (event.target !== this.nzSelectSearchComponent.inputElement.nativeElement) {
this.nzSelectSearchComponent.focus();
}
});
fromEvent(this.elementRef.nativeElement, 'keydown')
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
if (event.target instanceof HTMLInputElement) {
const inputValue = event.target.value;
if (event.keyCode === BACKSPACE &&
this.mode !== 'default' &&
!inputValue &&
this.listOfTopItem.length > 0) {
event.preventDefault();
// Run change detection only if the user has pressed the `Backspace` key and the following condition is met.
this.ngZone.run(() => this.onDeleteItem(this.listOfTopItem[this.listOfTopItem.length - 1]));
}
}
});
});
}
ngOnDestroy() {
this.destroy$.next();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: NzSelectTopControlComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i1.NzNoAnimationDirective, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.7", type: NzSelectTopControlComponent, isStandalone: true, selector: "nz-select-top-control", inputs: { nzId: "nzId", showSearch: "showSearch", placeHolder: "placeHolder", open: "open", maxTagCount: "maxTagCount", autofocus: "autofocus", disabled: "disabled", mode: "mode", customTemplate: "customTemplate", maxTagPlaceholder: "maxTagPlaceholder", removeIcon: "removeIcon", listOfTopItem: "listOfTopItem", tokenSeparators: "tokenSeparators" }, outputs: { tokenize: "tokenize", inputValueChange: "inputValueChange", deleteItem: "deleteItem" }, host: { classAttribute: "ant-select-selector" }, viewQueries: [{ propertyName: "nzSelectSearchComponent", first: true, predicate: NzSelectSearchComponent, descendants: true }], exportAs: ["nzSelectTopControl"], usesOnChanges: true, ngImport: i0, template: `
<!--single mode-->
<ng-container [ngSwitch]="mode">
<ng-container *ngSwitchCase="'default'">
<nz-select-search
[nzId]="nzId"
[disabled]="disabled"
[value]="inputValue!"
[showInput]="showSearch"
[mirrorSync]="false"
[autofocus]="autofocus"
[focusTrigger]="open"
(isComposingChange)="isComposingChange($event)"
(valueChange)="onInputValueChange($event)"
></nz-select-search>
<nz-select-item
*ngIf="isShowSingleLabel"
[deletable]="false"
[disabled]="false"
[removeIcon]="removeIcon"
[label]="listOfTopItem[0].nzLabel"
[contentTemplateOutlet]="customTemplate"
[contentTemplateOutletContext]="listOfTopItem[0]"
></nz-select-item>
</ng-container>
<ng-container *ngSwitchDefault>
<!--multiple or tags mode-->
<nz-select-item
*ngFor="let item of listOfSlicedItem; trackBy: trackValue"
[removeIcon]="removeIcon"
[label]="item.nzLabel"
[disabled]="item.nzDisabled || disabled"
[contentTemplateOutlet]="item.contentTemplateOutlet"
[deletable]="true"
[contentTemplateOutletContext]="item.contentTemplateOutletContext"
(delete)="onDeleteItem(item.contentTemplateOutletContext)"
></nz-select-item>
<nz-select-search
[nzId]="nzId"
[disabled]="disabled"
[value]="inputValue!"
[autofocus]="autofocus"
[showInput]="true"
[mirrorSync]="true"
[focusTrigger]="open"
(isComposingChange)="isComposingChange($event)"
(valueChange)="onInputValueChange($event)"
></nz-select-search>
</ng-container>
</ng-container>
<nz-select-placeholder *ngIf="isShowPlaceholder" [placeholder]="placeHolder"></nz-select-placeholder>
`, isInline: true, dependencies: [{ kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "component", type: NzSelectSearchComponent, selector: "nz-select-search", inputs: ["nzId", "disabled", "mirrorSync", "showInput", "focusTrigger", "value", "autofocus"], outputs: ["valueChange", "isComposingChange"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: NzSelectItemComponent, selector: "nz-select-item", inputs: ["disabled", "label", "deletable", "removeIcon", "contentTemplateOutletContext", "contentTemplateOutlet"], outputs: ["delete"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NzSelectPlaceholderComponent, selector: "nz-select-placeholder", inputs: ["placeholder"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.7", ngImport: i0, type: NzSelectTopControlComponent, decorators: [{
type: Component,
args: [{
selector: 'nz-select-top-control',
exportAs: 'nzSelectTopControl',
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
template: `
<!--single mode-->
<ng-container [ngSwitch]="mode">
<ng-container *ngSwitchCase="'default'">
<nz-select-search
[nzId]="nzId"
[disabled]="disabled"
[value]="inputValue!"
[showInput]="showSearch"
[mirrorSync]="false"
[autofocus]="autofocus"
[focusTrigger]="open"
(isComposingChange)="isComposingChange($event)"
(valueChange)="onInputValueChange($event)"
></nz-select-search>
<nz-select-item
*ngIf="isShowSingleLabel"
[deletable]="false"
[disabled]="false"
[removeIcon]="removeIcon"
[label]="listOfTopItem[0].nzLabel"
[contentTemplateOutlet]="customTemplate"
[contentTemplateOutletContext]="listOfTopItem[0]"
></nz-select-item>
</ng-container>
<ng-container *ngSwitchDefault>
<!--multiple or tags mode-->
<nz-select-item
*ngFor="let item of listOfSlicedItem; trackBy: trackValue"
[removeIcon]="removeIcon"
[label]="item.nzLabel"
[disabled]="item.nzDisabled || disabled"
[contentTemplateOutlet]="item.contentTemplateOutlet"
[deletable]="true"
[contentTemplateOutletContext]="item.contentTemplateOutletContext"
(delete)="onDeleteItem(item.contentTemplateOutletContext)"
></nz-select-item>
<nz-select-search
[nzId]="nzId"
[disabled]="disabled"
[value]="inputValue!"
[autofocus]="autofocus"
[showInput]="true"
[mirrorSync]="true"
[focusTrigger]="open"
(isComposingChange)="isComposingChange($event)"
(valueChange)="onInputValueChange($event)"
></nz-select-search>
</ng-container>
</ng-container>
<nz-select-placeholder *ngIf="isShowPlaceholder" [placeholder]="placeHolder"></nz-select-placeholder>
`,
host: { class: 'ant-select-selector' },
imports: [
NgSwitch,
NzSelectSearchComponent,
NgSwitchCase,
NzSelectItemComponent,
NgIf,
NgSwitchDefault,
NgFor,
NzSelectPlaceholderComponent
],
standalone: true
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i1.NzNoAnimationDirective, decorators: [{
type: Host
}, {
type: Optional
}] }], propDecorators: { nzId: [{
type: Input
}], showSearch: [{
type: Input
}], placeHolder: [{
type: Input
}], open: [{
type: Input
}], maxTagCount: [{
type: Input
}], autofocus: [{
type: Input
}], disabled: [{
type: Input
}], mode: [{
type: Input
}], customTemplate: [{
type: Input
}], maxTagPlaceholder: [{
type: Input
}], removeIcon: [{
type: Input
}], listOfTopItem: [{
type: Input
}], tokenSeparators: [{
type: Input
}], tokenize: [{
type: Output
}], inputValueChange: [{
type: Output
}], deleteItem: [{
type: Output
}], nzSelectSearchComponent: [{
type: ViewChild,
args: [NzSelectSearchComponent]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LXRvcC1jb250cm9sLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvc2VsZWN0L3NlbGVjdC10b3AtY29udHJvbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xELE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkYsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBRVQsWUFBWSxFQUNaLElBQUksRUFDSixLQUFLLEVBS0wsUUFBUSxFQUNSLE1BQU0sRUFHTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUszQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM5RSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBMEVwRSxNQUFNLE9BQU8sMkJBQTJCO0lBMEJ0QyxzQkFBc0I7UUFDcEIsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLGlCQUFpQixHQUFHLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDdkYsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsb0JBQW9CLElBQUksQ0FB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LFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDYSxRQUFRO3NCQUExQixNQUFNO2dCQUNZLGdCQUFnQjtzQkFBbEMsTUFBTTtnQkFDWSxVQUFVO3NCQUE1QixNQUFNO2dCQUM2Qix1QkFBdUI7c0JBQTFELFNBQVM7dUJBQUMsdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgQkFDS1NQQUNFIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7IE5nRm9yLCBOZ0lmLCBOZ1N3aXRjaCwgTmdTd2l0Y2hDYXNlLCBOZ1N3aXRjaERlZmF1bHQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZyb21FdmVudCwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBOek5vQW5pbWF0aW9uRGlyZWN0aXZlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL25vLWFuaW1hdGlvbic7XG5pbXBvcnQgeyBOelNhZmVBbnkgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuXG5pbXBvcnQgeyBOelNlbGVjdEl0ZW1Db21wb25lbnQgfSBmcm9tICcuL3NlbGVjdC1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOelNlbGVjdFBsYWNlaG9sZGVyQ29tcG9uZW50IH0gZnJvbSAnLi9zZWxlY3QtcGxhY2Vob2xkZXIuY29tcG9uZW50JztcbmltcG9ydCB7IE56U2VsZWN0U2VhcmNoQ29tcG9uZW50IH0gZnJvbSAnLi9zZWxlY3Qtc2VhcmNoLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOelNlbGVjdEl0ZW1JbnRlcmZhY2UsIE56U2VsZWN0TW9kZVR5cGUsIE56U2VsZWN0VG9wQ29udHJvbEl0ZW1UeXBlIH0gZnJvbSAnLi9zZWxlY3QudHlwZXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei1zZWxlY3QtdG9wLWNvbnRyb2wnLFxuICBleHBvcnRBczogJ256U2VsZWN0VG9wQ29udHJvbCcsXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8IS0tc2luZ2xlIG1vZGUtLT5cbiAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJtb2RlXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInZGVmYXVsdCdcIj5cbiAgICAgICAgPG56LXNlbGVjdC1zZWFyY2hcbiAgICAgICAgICBbbnpJZF09XCJueklkXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgIFt2YWx1ZV09XCJpbnB1dFZhbHVlIVwiXG4gICAgICAgICAgW3Nob3dJbnB1dF09XCJzaG93U2VhcmNoXCJcbiAgICAgICAgICBbbWlycm9yU3luY109XCJmYWxzZVwiXG4gICAgICAgICAgW2F1dG9mb2N1c109XCJhdXRvZm9jdXNcIlxuICAgICAgICAgIFtmb2N1c1RyaWdnZXJdPVwib3BlblwiXG4gICAgICAgICAgKGlzQ29tcG9zaW5nQ2hhbmdlKT1cImlzQ29tcG9zaW5nQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJvbklucHV0VmFsdWVDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgID48L256LXNlbGVjdC1zZWFyY2g+XG4gICAgICAgIDxuei1zZWxlY3QtaXRlbVxuICAgICAgICAgICpuZ0lmPVwiaXNTaG93U2luZ2xlTGFiZWxcIlxuICAgICAgICAgIFtkZWxldGFibGVdPVwiZmFsc2VcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJmYWxzZVwiXG4gICAgICAgICAgW3JlbW92ZUljb25dPVwicmVtb3ZlSWNvblwiXG4gICAgICAgICAgW2xhYmVsXT1cImxpc3RPZlRvcEl0ZW1bMF0ubnpMYWJlbFwiXG4gICAgICAgICAgW2NvbnRlbnRUZW1wbGF0ZU91dGxldF09XCJjdXN0b21UZW1wbGF0ZVwiXG4gICAgICAgICAgW2NvbnRlbnRUZW1wbGF0ZU91dGxldENvbnRleHRdPVwibGlzdE9mVG9wSXRlbVswXVwiXG4gICAgICAgID48L256LXNlbGVjdC1pdGVtPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaERlZmF1bHQ+XG4gICAgICAgIDwhLS1tdWx0aXBsZSBvciB0YWdzIG1vZGUtLT5cbiAgICAgICAgPG56LXNlbGVjdC1pdGVtXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgbGlzdE9mU2xpY2VkSXRlbTsgdHJhY2tCeTogdHJhY2tWYWx1ZVwiXG4gICAgICAgICAgW3JlbW92ZUljb25dPVwicmVtb3ZlSWNvblwiXG4gICAgICAgICAgW2xhYmVsXT1cIml0ZW0ubnpMYWJlbFwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIml0ZW0ubnpEaXNhYmxlZCB8fCBkaXNhYmxlZFwiXG4gICAgICAgICAgW2NvbnRlbnRUZW1wbGF0ZU91dGxldF09XCJpdGVtLmNvbnRlbnRUZW1wbGF0ZU91dGxldFwiXG4gICAgICAgICAgW2RlbGV0YWJsZV09XCJ0cnVlXCJcbiAgICAgICAgICBbY29udGVudFRlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJpdGVtLmNvbnRlbnRUZW1wbGF0ZU91dGxldENvbnRleHRcIlxuICAgICAgICAgIChkZWxldGUpPVwib25EZWxldGVJdGVtKGl0ZW0uY29udGVudFRlbXBsYXRlT3V0bGV0Q29udGV4dClcIlxuICAgICAgICA+PC9uei1zZWxlY3QtaXRlbT5cbiAgICAgICAgPG56LXNlbGVjdC1zZWFyY2hcbiAgICAgICAgICBbbnpJZF09XCJueklkXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgIFt2YWx1ZV09XCJpbnB1dFZhbHVlIVwiXG4gICAgICAgICAgW2F1dG9mb2N1c109XCJhdXRvZm9jdXNcIlxuICAgICAgICAgIFtzaG93SW5wdXRdPVwidHJ1ZVwiXG4gICAgICAgICAgW21pcnJvclN5bmNdPVwidHJ1ZVwiXG4gICAgICAgICAgW2ZvY3VzVHJpZ2dlcl09XCJvcGVuXCJcbiAgICAgICAgICAoaXNDb21wb3NpbmdDaGFuZ2UpPVwiaXNDb21wb3NpbmdDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uSW5wdXRWYWx1ZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgPjwvbnotc2VsZWN0LXNlYXJjaD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuei1zZWxlY3QtcGxhY2Vob2xkZXIgKm5nSWY9XCJpc1Nob3dQbGFjZWhvbGRlclwiIFtwbGFjZWhvbGRlcl09XCJwbGFjZUhvbGRlclwiPjwvbnotc2VsZWN0LXBsYWNlaG9sZGVyPlxuICBgLFxuICBob3N0OiB7IGNsYXNzOiAnYW50LXNlbGVjdC1zZWxlY3RvcicgfSxcbiAgaW1wb3J0czogW1xuICAgIE5nU3dpdGNoLFxuICAgIE56U2VsZWN0U2VhcmNoQ29tcG9uZW50LFxuICAgIE5nU3dpdGNoQ2FzZSxcbiAgICBOelNlbGVjdEl0ZW1Db21wb25lbnQsXG4gICAgTmdJZixcbiAgICBOZ1N3aXRjaERlZmF1bHQsXG4gICAgTmdGb3IsXG4gICAgTnpTZWxlY3RQbGFjZWhvbGRlckNvbXBvbmVudFxuICBdLFxuICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIE56U2VsZWN0VG9wQ29udHJvbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBueklkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgc2hvd1NlYXJjaCA9IGZhbHNlO1xuICBASW5wdXQoKSBwbGFjZUhvbGRlcjogc3RyaW5nIHwgVGVtcGxhdGVSZWY8TnpTYWZlQW55PiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBvcGVuID0gZmFsc2U7XG4gIEBJbnB1dCgpIG1heFRhZ0NvdW50OiBudW1iZXIgPSBJbmZpbml0eTtcbiAgQElucHV0KCkgYXV0b2ZvY3VzID0gZmFsc2U7XG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIG1vZGU6IE56U2VsZWN0TW9kZVR5cGUgPSAnZGVmYXVsdCc7XG4gIEBJbnB1dCgpIGN1c3RvbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogTnpTZWxlY3RJdGVtSW50ZXJmYWNlIH0+IHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIG1heFRhZ1BsYWNlaG9sZGVyOiBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogTnpTYWZlQW55W10gfT4gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgcmVtb3ZlSWNvbjogVGVtcGxhdGVSZWY8TnpTYWZlQW55PiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBsaXN0T2ZUb3BJdGVtOiBOelNlbGVjdEl0ZW1JbnRlcmZhY2VbXSA9IFtdO1xuICBASW5wdXQoKSB0b2tlblNlcGFyYXRvcnM6IHN0cmluZ1tdID0gW107XG4gIEBPdXRwdXQoKSByZWFkb25seSB0b2tlbml6ZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nW10+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBpbnB1dFZhbHVlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBkZWxldGVJdGVtID0gbmV3IEV2ZW50RW1pdHRlcjxOelNlbGVjdEl0ZW1JbnRlcmZhY2U+KCk7XG4gIEBWaWV3Q2hpbGQoTnpTZWxlY3RTZWFyY2hDb21wb25lbnQpIG56U2VsZWN0U2VhcmNoQ29tcG9uZW50ITogTnpTZWxlY3RTZWFyY2hDb21wb25lbnQ7XG4gIGxpc3RPZlNsaWNlZEl0ZW06IE56U2VsZWN0VG9wQ29udHJvbEl0ZW1UeXBlW10gPSBbXTtcbiAgaXNTaG93UGxhY2Vob2xkZXIgPSB0cnVlO1xuICBpc1Nob3dTaW5nbGVMYWJlbCA9IGZhbHNlO1xuICBpc0NvbXBvc2luZyA9IGZhbHNlO1xuICBpbnB1dFZhbHVlOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICB1cGRhdGVUZW1wbGF0ZVZhcmlhYmxlKCk6IHZvaWQge1xuICAgIGNvbnN0IGlzU2VsZWN0ZWRWYWx1ZUVtcHR5ID0gdGhpcy5saXN0T2ZUb3BJdGVtLmxlbmd0aCA9PT0gMDtcbiAgICB0aGlzLmlzU2hvd1BsYWNlaG9sZGVyID0gaXNTZWxlY3RlZFZhbHVlRW1wdHkgJiYgIXRoaXMuaXNDb21wb3NpbmcgJiYgIXRoaXMuaW5wdXRWYWx1ZTtcbiAgICB0aGlzLmlzU2hvd1NpbmdsZUxhYmVsID0gIWlzU2VsZWN0ZWRWYWx1ZUVtcHR5ICYmICF0aGlzLmlzQ29tcG9zaW5nICYmICF0aGlzLmlucHV0VmFsdWU7XG4gIH1cblxuICBpc0NvbXBvc2luZ0NoYW5nZShpc0NvbXBvc2luZzogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuaXNDb21wb3NpbmcgPSBpc0NvbXBvc2luZztcbiAgICB0aGlzLnVwZGF0ZVRlbXBsYXRlVmFyaWFibGUoKTtcbiAgfVxuXG4gIG9uSW5wdXRWYWx1ZUNoYW5nZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHZhbHVlICE9PSB0aGlzLmlucHV0VmFsdWUpIHtcbiAgICAgIHRoaXMuaW5wdXRWYWx1ZSA9IHZhbHVlO1xuICAgICAgdGhpcy51cGRhdGVUZW1wbGF0ZVZhcmlhYmxlKCk7XG4gICAgICB0aGlzLmlucHV0VmFsdWVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gICAgICB0aGlzLnRva2VuU2VwYXJhdGUodmFsdWUsIHRoaXMudG9rZW5TZXBhcmF0b3JzKTtcbiAgICB9XG4gIH1cblxuICB0b2tlblNlcGFyYXRlKGlucHV0VmFsdWU6IHN0cmluZywgdG9rZW5TZXBhcmF0b3JzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGluY2x1ZGVzU2VwYXJhdG9ycyA9IChzdHI6IHN0cmluZywgc2VwYXJhdG9yczogc3RyaW5nW10pOiBib29sZWFuID0+IHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvcHJlZmVyLWZvci1vZlxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZXBhcmF0b3JzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmIChzdHIubGFzdEluZGV4T2Yoc2VwYXJhdG9yc1tpXSkgPiAwKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIGNvbnN0IHNwbGl0QnlTZXBhcmF0b3JzID0gKHN0cjogc3RyaW5nLCBzZXBhcmF0b3JzOiBzdHJpbmdbXSk6IHN0cmluZ1tdID0+IHtcbiAgICAgIGNvbnN0IHJlZyA9IG5ldyBSZWdFeHAoYFske3NlcGFyYXRvcnMuam9pbigpfV1gKTtcbiAgICAgIGNvbnN0IGFycmF5ID0gc3RyLnNwbGl0KHJlZykuZmlsdGVyKHRva2VuID0+IHRva2VuKTtcbiAgICAgIHJldHVybiBbLi4ubmV3IFNldChhcnJheSldO1xuICAgIH07XG4gICAgaWYgKFxuICAgICAgaW5wdXRWYWx1ZSAmJlxuICAgICAgaW5wdXRWYWx1ZS5sZW5ndGggJiZcbiAgICAgIHRva2VuU2VwYXJhdG9ycy5sZW5ndGggJiZcbiAgICAgIHRoaXMubW9kZSAhPT0gJ2RlZmF1bHQnICYmXG4gICAgICBpbmNsdWRlc1NlcGFyYXRvcnMoaW5wdXRWYWx1ZSwgdG9rZW5TZXBhcmF0b3JzKVxuICAgICkge1xuICAgICAgY29uc3QgbGlzdE9mTGFiZWwgPSBzcGxpdEJ5U2VwYXJhdG9ycyhpbnB1dFZhbHVlLCB0b2tlblNlcGFyYXRvcnMpO1xuICAgICAgdGhpcy50b2tlbml6ZS5uZXh0KGxpc3RPZkxhYmVsKTtcbiAgICB9XG4gIH1cblxuICBjbGVhcklucHV0VmFsdWUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubnpTZWxlY3RTZWFyY2hDb21wb25lbnQpIHtcbiAgICAgIHRoaXMubnpTZWxlY3RTZWFyY2hDb21wb25lbnQuY2xlYXJJbnB1dFZhbHVlKCk7XG4gICAgfVxuICB9XG5cbiAgZm9jdXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubnpTZWxlY3RTZWFyY2hDb21wb25lbnQpIHtcbiAgICAgIHRoaXMubnpTZWxlY3RTZWFyY2hDb21wb25lbnQuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBibHVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm56U2VsZWN0U2VhcmNoQ29tcG9uZW50KSB7XG4gICAgICB0aGlzLm56U2VsZWN0U2VhcmNoQ29tcG9uZW50LmJsdXIoKTtcbiAgICB9XG4gIH1cblxuICB0cmFja1ZhbHVlKF9pbmRleDogbnVtYmVyLCBvcHRpb246IE56U2VsZWN0VG9wQ29udHJvbEl0ZW1UeXBlKTogTnpTYWZlQW55IHtcbiAgICByZXR1cm4gb3B0aW9uLm56VmFsdWU7XG4gIH1cblxuICBvbkRlbGV0ZUl0ZW0oaXRlbTogTnpTZWxlY3RJdGVtSW50ZXJmYWNlKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVkICYmICFpdGVtLm56RGlzYWJsZWQpIHtcbiAgICAgIHRoaXMuZGVsZXRlSXRlbS5uZXh0KGl0ZW0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBASG9zdCgpIEBPcHRpb25hbCgpIHB1YmxpYyBub0FuaW1hdGlvbjogTnpOb0FuaW1hdGlvbkRpcmVjdGl2ZSB8IG51bGxcbiAgKSB7fVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB7IGxpc3RPZlRvcEl0ZW0sIG1heFRhZ0NvdW50LCBjdXN0b21UZW1wbGF0ZSwgbWF4VGFnUGxhY2Vob2xkZXIgfSA9IGNoYW5nZXM7XG4gICAgaWYgKGxpc3RPZlRvcEl0ZW0pIHtcbiAgICAgIHRoaXMudXBkYXRlVGVtcGxhdGVWYXJpYWJsZSgpO1xuICAgIH1cbiAgICBpZiAobGlzdE9mVG9wSXRlbSB8fCBtYXhUYWdDb3VudCB8fCBjdXN0b21UZW1wbGF0ZSB8fCBtYXhUYWdQbGFjZWhvbGRlcikge1xuICAgICAgY29uc3QgbGlzdE9mU2xpY2VkSXRlbTogTnpTZWxlY3RUb3BDb250cm9sSXRlbVR5cGVbXSA9IHRoaXMubGlzdE9mVG9wSXRlbS5zbGljZSgwLCB0aGlzLm1heFRhZ0NvdW50KS5tYXAobyA9PiAoe1xuICAgICAgICBuekxhYmVsOiBvLm56TGFiZWwsXG4gICAgICAgIG56VmFsdWU6IG8ubnpWYWx1ZSxcbiAgICAgICAgbnpEaXNhYmxlZDogby5uekRpc2FibGVkLFxuICAgICAgICBjb250ZW50VGVtcGxhdGVPdXRsZXQ6IHRoaXMuY3VzdG9tVGVtcGxhdGUsXG4gICAgICAgIGNvbnRlbnRUZW1wbGF0ZU91dGxldENvbnRleHQ6IG9cbiAgICAgIH0pKTtcbiAgICAgIGlmICh0aGlzLmxpc3RPZlRvcEl0ZW0ubGVuZ3RoID4gdGhpcy5tYXhUYWdDb3VudCkge1xuICAgICAgICBjb25zdCBleGNlZWRlZExhYmVsID0gYCsgJHt0aGlzLmxpc3RPZlRvcEl0ZW0ubGVuZ3RoIC0gdGhpcy5tYXhUYWdDb3VudH0gLi4uYDtcbiAgICAgICAgY29uc3QgbGlzdE9mU2VsZWN0ZWRWYWx1ZSA9IHRoaXMubGlzdE9mVG9wSXRlbS5tYXAoaXRlbSA9PiBpdGVtLm56VmFsdWUpO1xuICAgICAgICBjb25zdCBleGNlZWRlZEl0ZW0gPSB7XG4gICAgICAgICAgbnpMYWJlbDogZXhjZWVkZWRMYWJlbCxcbiAgICAgICAgICBuelZhbHVlOiAnJCRfX256X2V4Y2VlZGVkX2l0ZW0nLFxuICAgICAgICAgIG56RGlzYWJsZWQ6IHRydWUsXG4gICAgICAgICAgY29udGVudFRlbXBsYXRlT3V0bGV0OiB0aGlzLm1heFRhZ1BsYWNlaG9sZGVyLFxuICAgICAgICAgIGNvbnRlbnRUZW1wbGF0ZU91dGxldENvbnRleHQ6IGxpc3RPZlNlbGVjdGVkVmFsdWUuc2xpY2UodGhpcy5tYXhUYWdDb3VudClcbiAgICAgICAgfTtcbiAgICAgICAgbGlzdE9mU2xpY2VkSXRlbS5wdXNoKGV4Y2VlZGVkSXRlbSk7XG4gICAgICB9XG4gICAgICB0aGlzLmxpc3RPZlNsaWNlZEl0ZW0gPSBsaXN0T2ZTbGljZWRJdGVtO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGZyb21FdmVudDxNb3VzZUV2ZW50Pih0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ2NsaWNrJylcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKGV2ZW50ID0+IHtcbiAgICAgICAgICAvLyBgSFRNTEVsZW1lbnQuZm9jdXMoKWAgaXMgYSBuYXRpdmUgRE9NIEFQSSB3aGljaCBkb2Vzbid0IHJlcXVpcmUgQW5ndWxhciB0byBydW4gY2hhbmdlIGRldGVjdGlvbi5cbiAgICAgICAgICBpZiAoZXZlbnQudGFyZ2V0ICE9PSB0aGlzLm56U2VsZWN0U2VhcmNoQ29tcG9uZW50LmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLm56U2VsZWN0U2VhcmNoQ29tcG9uZW50LmZvY3VzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAna2V5ZG93bicpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZShldmVudCA9PiB7XG4gICAgICAgICAgaWYgKGV2ZW50LnRhcmdldCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGlucHV0VmFsdWUgPSBldmVudC50YXJnZXQudmFsdWU7XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgZXZlbnQua2V5Q29kZSA9PT0gQkFDS1NQQUNFICYmXG4gICAgICAgICAgICAgIHRoaXMubW9kZSAhPT0gJ2RlZmF1bHQnICYmXG4gICAgICAgICAgICAgICFpbnB1dFZhbHVlICYmXG4gICAgICAgICAgICAgIHRoaXMubGlzdE9mVG9wSXRlbS5sZW5ndGggPiAwXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgLy8gUnVuIGNoYW5nZSBkZXRlY3Rpb24gb25seSBpZiB0aGUgdXNlciBoYXMgcHJlc3NlZCB0aGUgYEJhY2tzcGFjZWAga2V5IGFuZCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbiBpcyBtZXQuXG4gICAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLm9uRGVsZXRlSXRlbSh0aGlzLmxpc3RPZlRvcEl0ZW1bdGhpcy5saXN0T2ZUb3BJdGVtLmxlbmd0aCAtIDFdKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICB9XG59XG4iXX0=