UNPKG

ng-zorro-antd

Version:

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

351 lines 36.3 kB
/** * 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 { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, Output, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core'; import { fromEvent, merge, Observable } from 'rxjs'; import { startWith, switchMap } from 'rxjs/operators'; import { NzCheckboxComponent } from 'ng-zorro-antd/checkbox'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "ng-zorro-antd/checkbox"; import * as i3 from "ng-zorro-antd/empty"; import * as i4 from "./transfer-search.component"; export class NzTransferListComponent { // #endregion constructor(ngZone, cdr) { this.ngZone = ngZone; this.cdr = cdr; // #region fields this.direction = 'left'; this.titleText = ''; this.showSelectAll = true; this.dataSource = []; this.itemUnit = ''; this.itemsUnit = ''; this.filter = ''; this.disabled = false; this.renderList = null; this.render = null; this.footer = null; // events this.handleSelectAll = new EventEmitter(); this.handleSelect = new EventEmitter(); this.filterChange = new EventEmitter(); this.stat = { checkAll: false, checkHalf: false, checkCount: 0, shownCount: 0 }; this.onItemSelect = (item) => { if (this.disabled || item.disabled) { return; } item.checked = !item.checked; this.updateCheckStatus(); this.handleSelect.emit(item); }; this.onItemSelectAll = (status) => { this.dataSource.forEach(item => { if (!item.disabled && !item.hide) { item.checked = status; } }); this.updateCheckStatus(); this.handleSelectAll.emit(status); }; } get validData() { return this.dataSource.filter(w => !w.hide); } trackByHide(_index, item) { // The `validData` is a getter which returns new array each time the property is read. // This may lead to unexpected re-renders, tho the array hasn't been updated. return item.hide; } updateCheckStatus() { const validCount = this.dataSource.filter(w => !w.disabled).length; this.stat.checkCount = this.dataSource.filter(w => w.checked && !w.disabled).length; this.stat.shownCount = this.validData.length; this.stat.checkAll = validCount > 0 && validCount === this.stat.checkCount; this.stat.checkHalf = this.stat.checkCount > 0 && !this.stat.checkAll; // Note: this is done explicitly since the internal `nzChecked` value may not be updated in edge cases. // Consider the following flow: // 1) the initial value of `stat.checkAll` is `false` // 2) the user filters items // 3) the user clicks "Select All" checkbox // 4) the `NzCheckboxComponent` sets `nzChecked` to `true` internally // 5) the user clicks "Move to right" // 6) items are moved and the `updateCheckStatus` is invoked // 7) the `stat.checkAll` value has never been updated in this flow, it's always been `false` // 8) the `nzChecked` is still `true` and the checkbox is not unchecked // This is because Angular checks bindings and it checked that `[nzChecked]="stat.checkAll"` has // never been updated, so Angular did not set new `nzChecked` value on the checkbox. this.headerCheckbox && (this.headerCheckbox.nzChecked = this.stat.checkAll); } // #endregion // #region search handleFilter(value) { this.filter = value; this.dataSource.forEach(item => { item.hide = value.length > 0 && !this.matchFilter(value, item); }); this.stat.shownCount = this.validData.length; this.filterChange.emit({ direction: this.direction, value }); } handleClear() { this.handleFilter(''); } matchFilter(text, item) { if (this.filterOption) { return this.filterOption(text, item); } return item.title.includes(text); } markForCheck() { this.updateCheckStatus(); this.cdr.markForCheck(); } ngAfterViewInit() { this.checkboxes.changes .pipe(startWith(this.checkboxes), switchMap(() => { const checkboxes = this.checkboxes.toArray(); // Caretaker note: we explicitly should call `subscribe()` within the root zone. // `runOutsideAngular(() => fromEvent(...))` will just create an observable within the root zone, // but `addEventListener` is called when the `fromEvent` is subscribed. return new Observable(subscriber => this.ngZone.runOutsideAngular(() => merge(...checkboxes.map(checkbox => fromEvent(checkbox.nativeElement, 'click'))).subscribe(subscriber))); })) .subscribe(event => { event.stopPropagation(); }); } } NzTransferListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: NzTransferListComponent, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); NzTransferListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.0", type: NzTransferListComponent, selector: "nz-transfer-list", inputs: { direction: "direction", titleText: "titleText", showSelectAll: "showSelectAll", dataSource: "dataSource", itemUnit: "itemUnit", itemsUnit: "itemsUnit", filter: "filter", disabled: "disabled", showSearch: "showSearch", searchPlaceholder: "searchPlaceholder", notFoundContent: "notFoundContent", filterOption: "filterOption", renderList: "renderList", render: "render", footer: "footer" }, outputs: { handleSelectAll: "handleSelectAll", handleSelect: "handleSelect", filterChange: "filterChange" }, host: { properties: { "class.ant-transfer-list-with-footer": "!!footer" }, classAttribute: "ant-transfer-list" }, viewQueries: [{ propertyName: "headerCheckbox", first: true, predicate: ["headerCheckbox"], descendants: true, read: NzCheckboxComponent }, { propertyName: "checkboxes", predicate: ["checkboxes"], descendants: true, read: ElementRef }], exportAs: ["nzTransferList"], ngImport: i0, template: ` <ng-template #defaultRenderList> <ul *ngIf="stat.shownCount > 0" class="ant-transfer-list-content"> <li *ngFor="let item of validData; trackBy: trackByHide" (click)="onItemSelect(item)" class="ant-transfer-list-content-item" [ngClass]="{ 'ant-transfer-list-content-item-disabled': disabled || item.disabled }" > <label #checkboxes nz-checkbox [nzChecked]="item.checked" (nzCheckedChange)="onItemSelect(item)" [nzDisabled]="disabled || item.disabled" > <ng-container *ngIf="!render; else renderContainer">{{ item.title }}</ng-container> <ng-template #renderContainer [ngTemplateOutlet]="render" [ngTemplateOutletContext]="{ $implicit: item }" ></ng-template> </label> </li> </ul> <div *ngIf="stat.shownCount === 0" class="ant-transfer-list-body-not-found"> <nz-embed-empty [nzComponentName]="'transfer'" [specificContent]="notFoundContent"></nz-embed-empty> </div> </ng-template> <div class="ant-transfer-list-header"> <label *ngIf="showSelectAll" class="ant-transfer-list-checkbox" nz-checkbox #headerCheckbox [nzChecked]="stat.checkAll" (nzCheckedChange)="onItemSelectAll($event)" [nzIndeterminate]="stat.checkHalf" [nzDisabled]="stat.shownCount === 0 || disabled" ></label> <span class="ant-transfer-list-header-selected"> <span> {{ (stat.checkCount > 0 ? stat.checkCount + '/' : '') + stat.shownCount }} {{ validData.length > 1 ? itemsUnit : itemUnit }} </span> </span> <span *ngIf="titleText" class="ant-transfer-list-header-title">{{ titleText }}</span> </div> <div class="{{ showSearch ? 'ant-transfer-list-body ant-transfer-list-body-with-search' : 'ant-transfer-list-body' }}" [ngClass]="{ 'ant-transfer__nodata': stat.shownCount === 0 }" > <div *ngIf="showSearch" class="ant-transfer-list-body-search-wrapper"> <span nz-transfer-search class="ant-input-affix-wrapper ant-transfer-list-search" (valueChanged)="handleFilter($event)" (valueClear)="handleClear()" [placeholder]="searchPlaceholder" [disabled]="disabled" [value]="filter" ></span> </div> <ng-container *ngIf="renderList; else defaultRenderList"> <div class="ant-transfer-list-body-customize-wrapper"> <ng-container *ngTemplateOutlet=" renderList; context: { $implicit: validData, direction: direction, disabled: disabled, onItemSelectAll: onItemSelectAll, onItemSelect: onItemSelect, stat: stat } " ></ng-container> </div> </ng-container> </div> <div *ngIf="footer" class="ant-transfer-list-footer"> <ng-template [ngTemplateOutlet]="footer" [ngTemplateOutletContext]="{ $implicit: direction }"></ng-template> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }, { kind: "component", type: i3.NzEmbedEmptyComponent, selector: "nz-embed-empty", inputs: ["nzComponentName", "specificContent"], exportAs: ["nzEmbedEmpty"] }, { kind: "component", type: i4.NzTransferSearchComponent, selector: "[nz-transfer-search]", inputs: ["placeholder", "value", "disabled"], outputs: ["valueChanged", "valueClear"], exportAs: ["nzTransferSearch"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: NzTransferListComponent, decorators: [{ type: Component, args: [{ selector: 'nz-transfer-list', exportAs: 'nzTransferList', preserveWhitespaces: false, template: ` <ng-template #defaultRenderList> <ul *ngIf="stat.shownCount > 0" class="ant-transfer-list-content"> <li *ngFor="let item of validData; trackBy: trackByHide" (click)="onItemSelect(item)" class="ant-transfer-list-content-item" [ngClass]="{ 'ant-transfer-list-content-item-disabled': disabled || item.disabled }" > <label #checkboxes nz-checkbox [nzChecked]="item.checked" (nzCheckedChange)="onItemSelect(item)" [nzDisabled]="disabled || item.disabled" > <ng-container *ngIf="!render; else renderContainer">{{ item.title }}</ng-container> <ng-template #renderContainer [ngTemplateOutlet]="render" [ngTemplateOutletContext]="{ $implicit: item }" ></ng-template> </label> </li> </ul> <div *ngIf="stat.shownCount === 0" class="ant-transfer-list-body-not-found"> <nz-embed-empty [nzComponentName]="'transfer'" [specificContent]="notFoundContent"></nz-embed-empty> </div> </ng-template> <div class="ant-transfer-list-header"> <label *ngIf="showSelectAll" class="ant-transfer-list-checkbox" nz-checkbox #headerCheckbox [nzChecked]="stat.checkAll" (nzCheckedChange)="onItemSelectAll($event)" [nzIndeterminate]="stat.checkHalf" [nzDisabled]="stat.shownCount === 0 || disabled" ></label> <span class="ant-transfer-list-header-selected"> <span> {{ (stat.checkCount > 0 ? stat.checkCount + '/' : '') + stat.shownCount }} {{ validData.length > 1 ? itemsUnit : itemUnit }} </span> </span> <span *ngIf="titleText" class="ant-transfer-list-header-title">{{ titleText }}</span> </div> <div class="{{ showSearch ? 'ant-transfer-list-body ant-transfer-list-body-with-search' : 'ant-transfer-list-body' }}" [ngClass]="{ 'ant-transfer__nodata': stat.shownCount === 0 }" > <div *ngIf="showSearch" class="ant-transfer-list-body-search-wrapper"> <span nz-transfer-search class="ant-input-affix-wrapper ant-transfer-list-search" (valueChanged)="handleFilter($event)" (valueClear)="handleClear()" [placeholder]="searchPlaceholder" [disabled]="disabled" [value]="filter" ></span> </div> <ng-container *ngIf="renderList; else defaultRenderList"> <div class="ant-transfer-list-body-customize-wrapper"> <ng-container *ngTemplateOutlet=" renderList; context: { $implicit: validData, direction: direction, disabled: disabled, onItemSelectAll: onItemSelectAll, onItemSelect: onItemSelect, stat: stat } " ></ng-container> </div> </ng-container> </div> <div *ngIf="footer" class="ant-transfer-list-footer"> <ng-template [ngTemplateOutlet]="footer" [ngTemplateOutletContext]="{ $implicit: direction }"></ng-template> </div> `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'ant-transfer-list', '[class.ant-transfer-list-with-footer]': '!!footer' } }] }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { direction: [{ type: Input }], titleText: [{ type: Input }], showSelectAll: [{ type: Input }], dataSource: [{ type: Input }], itemUnit: [{ type: Input }], itemsUnit: [{ type: Input }], filter: [{ type: Input }], disabled: [{ type: Input }], showSearch: [{ type: Input }], searchPlaceholder: [{ type: Input }], notFoundContent: [{ type: Input }], filterOption: [{ type: Input }], renderList: [{ type: Input }], render: [{ type: Input }], footer: [{ type: Input }], handleSelectAll: [{ type: Output }], handleSelect: [{ type: Output }], filterChange: [{ type: Output }], headerCheckbox: [{ type: ViewChild, args: ['headerCheckbox', { read: NzCheckboxComponent }] }], checkboxes: [{ type: ViewChildren, args: ['checkboxes', { read: ElementRef }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmZXItbGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL3RyYW5zZmVyL3RyYW5zZmVyLWxpc3QuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFFTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFHTixTQUFTLEVBQ1QsWUFBWSxFQUNaLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7Ozs7O0FBb0c3RCxNQUFNLE9BQU8sdUJBQXVCO0lBaUhsQyxhQUFhO0lBRWIsWUFBb0IsTUFBYyxFQUFVLEdBQXNCO1FBQTlDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQWxIbEUsaUJBQWlCO1FBRVIsY0FBUyxHQUFzQixNQUFNLENBQUM7UUFDdEMsY0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNmLGtCQUFhLEdBQUcsSUFBSSxDQUFDO1FBRXJCLGVBQVUsR0FBbUIsRUFBRSxDQUFDO1FBRWhDLGFBQVEsR0FBdUIsRUFBRSxDQUFDO1FBQ2xDLGNBQVMsR0FBdUIsRUFBRSxDQUFDO1FBQ25DLFdBQU0sR0FBRyxFQUFFLENBQUM7UUFDWixhQUFRLEdBQVksS0FBSyxDQUFDO1FBTTFCLGVBQVUsR0FBNkIsSUFBSSxDQUFDO1FBQzVDLFdBQU0sR0FBNkIsSUFBSSxDQUFDO1FBQ3hDLFdBQU0sR0FBNkIsSUFBSSxDQUFDO1FBRWpELFNBQVM7UUFDVSxvQkFB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QUUsbUJBQW1CO3dCQUMxQix1Q0FBdUMsRUFBRSxVQUFVO3FCQUNwRDtpQkFDRjs2SEFJVSxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUdhLGVBQWU7c0JBQWpDLE1BQU07Z0JBQ1ksWUFBWTtzQkFBOUIsTUFBTTtnQkFDWSxZQUFZO3NCQUE5QixNQUFNO2dCQUVxRCxjQUFjO3NCQUF6RSxTQUFTO3VCQUFDLGdCQUFnQixFQUFFLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixFQUFFO2dCQUVSLFVBQVU7c0JBQTNELFlBQVk7dUJBQUMsWUFBWSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3Q2hpbGRyZW4sXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBtZXJnZSwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3RhcnRXaXRoLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE56Q2hlY2tib3hDb21wb25lbnQgfSBmcm9tICduZy16b3Jyby1hbnRkL2NoZWNrYm94JztcblxuaW1wb3J0IHsgVHJhbnNmZXJEaXJlY3Rpb24sIFRyYW5zZmVySXRlbSB9IGZyb20gJy4vaW50ZXJmYWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbnotdHJhbnNmZXItbGlzdCcsXG4gIGV4cG9ydEFzOiAnbnpUcmFuc2Zlckxpc3QnLFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRSZW5kZXJMaXN0PlxuICAgICAgPHVsICpuZ0lmPVwic3RhdC5zaG93bkNvdW50ID4gMFwiIGNsYXNzPVwiYW50LXRyYW5zZmVyLWxpc3QtY29udGVudFwiPlxuICAgICAgICA8bGlcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiB2YWxpZERhdGE7IHRyYWNrQnk6IHRyYWNrQnlIaWRlXCJcbiAgICAgICAgICAoY2xpY2spPVwib25JdGVtU2VsZWN0KGl0ZW0pXCJcbiAgICAgICAgICBjbGFzcz1cImFudC10cmFuc2Zlci1saXN0LWNvbnRlbnQtaXRlbVwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwieyAnYW50LXRyYW5zZmVyLWxpc3QtY29udGVudC1pdGVtLWRpc2FibGVkJzogZGlzYWJsZWQgfHwgaXRlbS5kaXNhYmxlZCB9XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgI2NoZWNrYm94ZXNcbiAgICAgICAgICAgIG56LWNoZWNrYm94XG4gICAgICAgICAgICBbbnpDaGVja2VkXT1cIml0ZW0uY2hlY2tlZFwiXG4gICAgICAgICAgICAobnpDaGVja2VkQ2hhbmdlKT1cIm9uSXRlbVNlbGVjdChpdGVtKVwiXG4gICAgICAgICAgICBbbnpEaXNhYmxlZF09XCJkaXNhYmxlZCB8fCBpdGVtLmRpc2FibGVkXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXJlbmRlcjsgZWxzZSByZW5kZXJDb250YWluZXJcIj57eyBpdGVtLnRpdGxlIH19PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgI3JlbmRlckNvbnRhaW5lclxuICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJyZW5kZXJcIlxuICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IGl0ZW0gfVwiXG4gICAgICAgICAgICA+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8L2xpPlxuICAgICAgPC91bD5cbiAgICAgIDxkaXYgKm5nSWY9XCJzdGF0LnNob3duQ291bnQgPT09IDBcIiBjbGFzcz1cImFudC10cmFuc2Zlci1saXN0LWJvZHktbm90LWZvdW5kXCI+XG4gICAgICAgIDxuei1lbWJlZC1lbXB0eSBbbnpDb21wb25lbnROYW1lXT1cIid0cmFuc2ZlcidcIiBbc3BlY2lmaWNDb250ZW50XT1cIm5vdEZvdW5kQ29udGVudFwiPjwvbnotZW1iZWQtZW1wdHk+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICAgIDxkaXYgY2xhc3M9XCJhbnQtdHJhbnNmZXItbGlzdC1oZWFkZXJcIj5cbiAgICAgIDxsYWJlbFxuICAgICAgICAqbmdJZj1cInNob3dTZWxlY3RBbGxcIlxuICAgICAgICBjbGFzcz1cImFudC10cmFuc2Zlci1saXN0LWNoZWNrYm94XCJcbiAgICAgICAgbnotY2hlY2tib3hcbiAgICAgICAgI2hlYWRlckNoZWNrYm94XG4gICAgICAgIFtuekNoZWNrZWRdPVwic3RhdC5jaGVja0FsbFwiXG4gICAgICAgIChuekNoZWNrZWRDaGFuZ2UpPVwib25JdGVtU2VsZWN0QWxsKCRldmVudClcIlxuICAgICAgICBbbnpJbmRldGVybWluYXRlXT1cInN0YXQuY2hlY2tIYWxmXCJcbiAgICAgICAgW256RGlzYWJsZWRdPVwic3RhdC5zaG93bkNvdW50ID09PSAwIHx8IGRpc2FibGVkXCJcbiAgICAgID48L2xhYmVsPlxuICAgICAgPHNwYW4gY2xhc3M9XCJhbnQtdHJhbnNmZXItbGlzdC1oZWFkZXItc2VsZWN0ZWRcIj5cbiAgICAgICAgPHNwYW4+XG4gICAgICAgICAge3sgKHN0YXQuY2hlY2tDb3VudCA+IDAgPyBzdGF0LmNoZWNrQ291bnQgKyAnLycgOiAnJykgKyBzdGF0LnNob3duQ291bnQgfX1cbiAgICAgICAgICB7eyB2YWxpZERhdGEubGVuZ3RoID4gMSA/IGl0ZW1zVW5pdCA6IGl0ZW1Vbml0IH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxzcGFuICpuZ0lmPVwidGl0bGVUZXh0XCIgY2xhc3M9XCJhbnQtdHJhbnNmZXItbGlzdC1oZWFkZXItdGl0bGVcIj57eyB0aXRsZVRleHQgfX08L3NwYW4+XG4gICAgPC9kaXY+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJ7eyBzaG93U2VhcmNoID8gJ2FudC10cmFuc2Zlci1saXN0LWJvZHkgYW50LXRyYW5zZmVyLWxpc3QtYm9keS13aXRoLXNlYXJjaCcgOiAnYW50LXRyYW5zZmVyLWxpc3QtYm9keScgfX1cIlxuICAgICAgW25nQ2xhc3NdPVwieyAnYW50LXRyYW5zZmVyX19ub2RhdGEnOiBzdGF0LnNob3duQ291bnQgPT09IDAgfVwiXG4gICAgPlxuICAgICAgPGRpdiAqbmdJZj1cInNob3dTZWFyY2hcIiBjbGFzcz1cImFudC10cmFuc2Zlci1saXN0LWJvZHktc2VhcmNoLXdyYXBwZXJcIj5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICBuei10cmFuc2Zlci1zZWFyY2hcbiAgICAgICAgICBjbGFzcz1cImFudC1pbnB1dC1hZmZpeC13cmFwcGVyIGFudC10cmFuc2Zlci1saXN0LXNlYXJjaFwiXG4gICAgICAgICAgKHZhbHVlQ2hhbmdlZCk9XCJoYW5kbGVGaWx0ZXIoJGV2ZW50KVwiXG4gICAgICAgICAgKHZhbHVlQ2xlYXIpPVwiaGFuZGxlQ2xlYXIoKVwiXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInNlYXJjaFBsYWNlaG9sZGVyXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgIFt2YWx1ZV09XCJmaWx0ZXJcIlxuICAgICAgICA+PC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicmVuZGVyTGlzdDsgZWxzZSBkZWZhdWx0UmVuZGVyTGlzdFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LXRyYW5zZmVyLWxpc3QtYm9keS1jdXN0b21pemUtd3JhcHBlclwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgICAgIHJlbmRlckxpc3Q7XG4gICAgICAgICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICAgICAgICAkaW1wbGljaXQ6IHZhbGlkRGF0YSxcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb246IGRpcmVjdGlvbixcbiAgICAgICAgICAgICAgICBkaXNhYmxlZDogZGlzYWJsZWQsXG4gICAgICAgICAgICAgICAgb25JdGVtU2VsZWN0QWxsOiBvbkl0ZW1TZWxlY3RBbGwsXG4gICAgICAgICAgICAgICAgb25JdGVtU2VsZWN0OiBvbkl0ZW1TZWxlY3QsXG4gICAgICAgICAgICAgICAgc3RhdDogc3RhdFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBcIlxuICAgICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ0lmPVwiZm9vdGVyXCIgY2xhc3M9XCJhbnQtdHJhbnNmZXItbGlzdC1mb290ZXJcIj5cbiAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJmb290ZXJcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IGRpcmVjdGlvbiB9XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ2FudC10cmFuc2Zlci1saXN0JyxcbiAgICAnW2NsYXNzLmFudC10cmFuc2Zlci1saXN0LXdpdGgtZm9vdGVyXSc6ICchIWZvb3RlcidcbiAgfVxufSlcbmV4cG9ydCBjbGFzcyBOelRyYW5zZmVyTGlzdENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuICAvLyAjcmVnaW9uIGZpZWxkc1xuXG4gIEBJbnB1dCgpIGRpcmVjdGlvbjogVHJhbnNmZXJEaXJlY3Rpb24gPSAnbGVmdCc7XG4gIEBJbnB1dCgpIHRpdGxlVGV4dCA9ICcnO1xuICBASW5wdXQoKSBzaG93U2VsZWN0QWxsID0gdHJ1ZTtcblxuICBASW5wdXQoKSBkYXRhU291cmNlOiBUcmFuc2Zlckl0ZW1bXSA9IFtdO1xuXG4gIEBJbnB1dCgpIGl0ZW1Vbml0OiBzdHJpbmcgfCB1bmRlZmluZWQgPSAnJztcbiAgQElucHV0KCkgaXRlbXNVbml0OiBzdHJpbmcgfCB1bmRlZmluZWQgPSAnJztcbiAgQElucHV0KCkgZmlsdGVyID0gJyc7XG4gIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHNob3dTZWFyY2g/OiBib29sZWFuO1xuICBASW5wdXQoKSBzZWFyY2hQbGFjZWhvbGRlcj86IHN0cmluZztcbiAgQElucHV0KCkgbm90Rm91bmRDb250ZW50Pzogc3RyaW5nO1xuICBASW5wdXQoKSBmaWx0ZXJPcHRpb24/OiAoaW5wdXRWYWx1ZTogc3RyaW5nLCBpdGVtOiBUcmFuc2Zlckl0ZW0pID0+IGJvb2xlYW47XG5cbiAgQElucHV0KCkgcmVuZGVyTGlzdDogVGVtcGxhdGVSZWY8dm9pZD4gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgcmVuZGVyOiBUZW1wbGF0ZVJlZjx2b2lkPiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBmb290ZXI6IFRlbXBsYXRlUmVmPHZvaWQ+IHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gZXZlbnRzXG4gIEBPdXRwdXQoKSByZWFkb25seSBoYW5kbGVTZWxlY3RBbGw6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IGhhbmRsZVNlbGVjdDogRXZlbnRFbWl0dGVyPFRyYW5zZmVySXRlbT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBmaWx0ZXJDaGFuZ2U6IEV2ZW50RW1pdHRlcjx7IGRpcmVjdGlvbjogVHJhbnNmZXJEaXJlY3Rpb247IHZhbHVlOiBzdHJpbmcgfT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgQFZpZXdDaGlsZCgnaGVhZGVyQ2hlY2tib3gnLCB7IHJlYWQ6IE56Q2hlY2tib3hDb21wb25lbnQgfSkgaGVhZGVyQ2hlY2tib3g/OiBOekNoZWNrYm94Q29tcG9uZW50O1xuXG4gIEBWaWV3Q2hpbGRyZW4oJ2NoZWNrYm94ZXMnLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSkgY2hlY2tib3hlcyE6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPEhUTUxMYWJlbEVsZW1lbnQ+PjtcblxuICBzdGF0ID0ge1xuICAgIGNoZWNrQWxsOiBmYWxzZSxcbiAgICBjaGVja0hhbGY6IGZhbHNlLFxuICAgIGNoZWNrQ291bnQ6IDAsXG4gICAgc2hvd25Db3VudDogMFxuICB9O1xuXG4gIGdldCB2YWxpZERhdGEoKTogVHJhbnNmZXJJdGVtW10ge1xuICAgIHJldHVybiB0aGlzLmRhdGFTb3VyY2UuZmlsdGVyKHcgPT4gIXcuaGlkZSk7XG4gIH1cblxuICB0cmFja0J5SGlkZShfaW5kZXg6IG51bWJlciwgaXRlbTogVHJhbnNmZXJJdGVtKTogYm9vbGVhbiB8IHVuZGVmaW5lZCB7XG4gICAgLy8gVGhlIGB2YWxpZERhdGFgIGlzIGEgZ2V0dGVyIHdoaWNoIHJldHVybnMgbmV3IGFycmF5IGVhY2ggdGltZSB0aGUgcHJvcGVydHkgaXMgcmVhZC5cbiAgICAvLyBUaGlzIG1heSBsZWFkIHRvIHVuZXhwZWN0ZWQgcmUtcmVuZGVycywgdGhvIHRoZSBhcnJheSBoYXNuJ3QgYmVlbiB1cGRhdGVkLlxuICAgIHJldHVybiBpdGVtLmhpZGU7XG4gIH1cblxuICBvbkl0ZW1TZWxlY3QgPSAoaXRlbTogVHJhbnNmZXJJdGVtKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQgfHwgaXRlbS5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpdGVtLmNoZWNrZWQgPSAhaXRlbS5jaGVja2VkO1xuICAgIHRoaXMudXBkYXRlQ2hlY2tTdGF0dXMoKTtcbiAgICB0aGlzLmhhbmRsZVNlbGVjdC5lbWl0KGl0ZW0pO1xuICB9O1xuXG4gIG9uSXRlbVNlbGVjdEFsbCA9IChzdGF0dXM6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICB0aGlzLmRhdGFTb3VyY2UuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGlmICghaXRlbS5kaXNhYmxlZCAmJiAhaXRlbS5oaWRlKSB7XG4gICAgICAgIGl0ZW0uY2hlY2tlZCA9IHN0YXR1cztcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMudXBkYXRlQ2hlY2tTdGF0dXMoKTtcbiAgICB0aGlzLmhhbmRsZVNlbGVjdEFsbC5lbWl0KHN0YXR1cyk7XG4gIH07XG5cbiAgcHJpdmF0ZSB1cGRhdGVDaGVja1N0YXR1cygpOiB2b2lkIHtcbiAgICBjb25zdCB2YWxpZENvdW50ID0gdGhpcy5kYXRhU291cmNlLmZpbHRlcih3ID0+ICF3LmRpc2FibGVkKS5sZW5ndGg7XG4gICAgdGhpcy5zdGF0LmNoZWNrQ291bnQgPSB0aGlzLmRhdGFTb3VyY2UuZmlsdGVyKHcgPT4gdy5jaGVja2VkICYmICF3LmRpc2FibGVkKS5sZW5ndGg7XG4gICAgdGhpcy5zdGF0LnNob3duQ291bnQgPSB0aGlzLnZhbGlkRGF0YS5sZW5ndGg7XG4gICAgdGhpcy5zdGF0LmNoZWNrQWxsID0gdmFsaWRDb3VudCA+IDAgJiYgdmFsaWRDb3VudCA9PT0gdGhpcy5zdGF0LmNoZWNrQ291bnQ7XG4gICAgdGhpcy5zdGF0LmNoZWNrSGFsZiA9IHRoaXMuc3RhdC5jaGVja0NvdW50ID4gMCAmJiAhdGhpcy5zdGF0LmNoZWNrQWxsO1xuICAgIC8vIE5vdGU6IHRoaXMgaXMgZG9uZSBleHBsaWNpdGx5IHNpbmNlIHRoZSBpbnRlcm5hbCBgbnpDaGVja2VkYCB2YWx1ZSBtYXkgbm90IGJlIHVwZGF0ZWQgaW4gZWRnZSBjYXNlcy5cbiAgICAvLyBDb25zaWRlciB0aGUgZm9sbG93aW5nIGZsb3c6XG4gICAgLy8gMSkgdGhlIGluaXRpYWwgdmFsdWUgb2YgYHN0YXQuY2hlY2tBbGxgIGlzIGBmYWxzZWBcbiAgICAvLyAyKSB0aGUgdXNlciBmaWx0ZXJzIGl0ZW1zXG4gICAgLy8gMykgdGhlIHVzZXIgY2xpY2tzIFwiU2VsZWN0IEFsbFwiIGNoZWNrYm94XG4gICAgLy8gNCkgdGhlIGBOekNoZWNrYm94Q29tcG9uZW50YCBzZXRzIGBuekNoZWNrZWRgIHRvIGB0cnVlYCBpbnRlcm5hbGx5XG4gICAgLy8gNSkgdGhlIHVzZXIgY2xpY2tzIFwiTW92ZSB0byByaWdodFwiXG4gICAgLy8gNikgaXRlbXMgYXJlIG1vdmVkIGFuZCB0aGUgYHVwZGF0ZUNoZWNrU3RhdHVzYCBpcyBpbnZva2VkXG4gICAgLy8gNykgdGhlIGBzdGF0LmNoZWNrQWxsYCB2YWx1ZSBoYXMgbmV2ZXIgYmVlbiB1cGRhdGVkIGluIHRoaXMgZmxvdywgaXQncyBhbHdheXMgYmVlbiBgZmFsc2VgXG4gICAgLy8gOCkgdGhlIGBuekNoZWNrZWRgIGlzIHN0aWxsIGB0cnVlYCBhbmQgdGhlIGNoZWNrYm94IGlzIG5vdCB1bmNoZWNrZWRcbiAgICAvLyBUaGlzIGlzIGJlY2F1c2UgQW5ndWxhciBjaGVja3MgYmluZGluZ3MgYW5kIGl0IGNoZWNrZWQgdGhhdCBgW256Q2hlY2tlZF09XCJzdGF0LmNoZWNrQWxsXCJgIGhhc1xuICAgIC8vIG5ldmVyIGJlZW4gdXBkYXRlZCwgc28gQW5ndWxhciBkaWQgbm90IHNldCBuZXcgYG56Q2hlY2tlZGAgdmFsdWUgb24gdGhlIGNoZWNrYm94LlxuICAgIHRoaXMuaGVhZGVyQ2hlY2tib3ggJiYgKHRoaXMuaGVhZGVyQ2hlY2tib3gubnpDaGVja2VkID0gdGhpcy5zdGF0LmNoZWNrQWxsKTtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHNlYXJjaFxuXG4gIGhhbmRsZUZpbHRlcih2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5maWx0ZXIgPSB2YWx1ZTtcbiAgICB0aGlzLmRhdGFTb3VyY2UuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGl0ZW0uaGlkZSA9IHZhbHVlLmxlbmd0aCA+IDAgJiYgIXRoaXMubWF0Y2hGaWx0ZXIodmFsdWUsIGl0ZW0pO1xuICAgIH0pO1xuICAgIHRoaXMuc3RhdC5zaG93bkNvdW50ID0gdGhpcy52YWxpZERhdGEubGVuZ3RoO1xuICAgIHRoaXMuZmlsdGVyQ2hhbmdlLmVtaXQoeyBkaXJlY3Rpb246IHRoaXMuZGlyZWN0aW9uLCB2YWx1ZSB9KTtcbiAgfVxuXG4gIGhhbmRsZUNsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlRmlsdGVyKCcnKTtcbiAgfVxuXG4gIHByaXZhdGUgbWF0Y2hGaWx0ZXIodGV4dDogc3RyaW5nLCBpdGVtOiBUcmFuc2Zlckl0ZW0pOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5maWx0ZXJPcHRpb24pIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbHRlck9wdGlvbih0ZXh0LCBpdGVtKTtcbiAgICB9XG4gICAgcmV0dXJuIGl0ZW0udGl0bGUuaW5jbHVkZXModGV4dCk7XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSwgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIG1hcmtGb3JDaGVjaygpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUNoZWNrU3RhdHVzKCk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5jaGVja2JveGVzLmNoYW5nZXNcbiAgICAgIC5waXBlKFxuICAgICAgICBzdGFydFdpdGgodGhpcy5jaGVja2JveGVzKSxcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBjaGVja2JveGVzID0gdGhpcy5jaGVja2JveGVzLnRvQXJyYXkoKTtcbiAgICAgICAgICAvLyBDYXJldGFrZXIgbm90ZTogd2UgZXhwbGljaXRseSBzaG91bGQgY2FsbCBgc3Vic2NyaWJlKClgIHdpdGhpbiB0aGUgcm9vdCB6b25lLlxuICAgICAgICAgIC8vIGBydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBmcm9tRXZlbnQoLi4uKSlgIHdpbGwganVzdCBjcmVhdGUgYW4gb2JzZXJ2YWJsZSB3aXRoaW4gdGhlIHJvb3Qgem9uZSxcbiAgICAgICAgICAvLyBidXQgYGFkZEV2ZW50TGlzdGVuZXJgIGlzIGNhbGxlZCB3aGVuIHRoZSBgZnJvbUV2ZW50YCBpcyBzdWJzY3JpYmVkLlxuICAgICAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PihzdWJzY3JpYmVyID0+XG4gICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PlxuICAgICAgICAgICAgICBtZXJnZSguLi5jaGVja2JveGVzLm1hcChjaGVja2JveCA9PiBmcm9tRXZlbnQ8TW91c2VFdmVudD4oY2hlY2tib3gubmF0aXZlRWxlbWVudCwgJ2NsaWNrJykpKS5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlclxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIH0pO1xuICB9XG59XG4iXX0=