UNPKG

@alfiob/ng-datatable

Version:

ng-datatable - fully customizable & easy to use datatable library

231 lines (223 loc) 27.1 kB
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@angular/forms"; import * as i3 from "./column-filter"; import * as i4 from "./icon-check"; import * as i5 from "./icon-dash"; import * as i6 from "./icon-filter"; export class ColumnHeaderComponent { constructor(viewContainerRef) { this.viewContainerRef = viewContainerRef; this.selectAll = new EventEmitter(); this.sortChange = new EventEmitter(); this.filterChange = new EventEmitter(); this.isOpenFilter = null; } ngOnInit() { this.viewContainerRef.createEmbeddedView(this.template); this.checkboxChange(); } checkboxChange() { if (this.selectedAll) { this.selectedAll.nativeElement.indeterminate = this.checkAll !== 0 ? !this.checkAll : false; this.selectedAll.nativeElement.checked = this.checkAll; } } toggleFilterMenu(col) { if (col) { if (this.isOpenFilter === col.field) { this.isOpenFilter = null; } else { this.isOpenFilter = col.field; } } else { this.isOpenFilter = null; } } } ColumnHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ColumnHeaderComponent, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); ColumnHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ColumnHeaderComponent, selector: "column-header", inputs: { all: "all", isFooter: "isFooter", checkAll: "checkAll" }, outputs: { selectAll: "selectAll", sortChange: "sortChange", filterChange: "filterChange" }, viewQueries: [{ propertyName: "template", first: true, predicate: ["template"], descendants: true, static: true }, { propertyName: "selectedAll", first: true, predicate: ["selectedAll"], descendants: true }], ngImport: i0, template: ` <ng-template #template> <tr> <th *ngIf="all.hasCheckbox" [class]="'bh-w-px'" [ngClass]="{ 'bh-sticky bh-bg-blue-light bh-z-[1]': all.stickyHeader || all.stickyFirstColumn, 'bh-top-0': all.stickyHeader, 'bh-left-0': all.stickyFirstColumn }" > <div class="bh-checkbox"> <input #selectedAll type="checkbox" (click)="selectAll.emit(selectedAll.checked); $event.stopPropagation()" /> <div> <icon-check class="check"></icon-check> <icon-dash class="intermediate"></icon-dash> </div> </div> </th> <ng-container *ngFor="let col of all.columns; let j = index"> <th *ngIf="!col.hide" [ngStyle]="{ 'width': col.width, 'min-width': col.minWidth, 'max-width': col.maxWidth }" [class]="'bh-select-none bh-z-[1]'" [ngClass]="[ all.sortable && col.sort ? 'bh-cursor-pointer' : '', j === 0 && all.stickyFirstColumn ? 'bh-sticky bh-left-0 bh-bg-blue-light' : '', all.hasCheckbox && j === 0 && all.stickyFirstColumn ? 'bh-left-[52px]' : '' ]" [style]="{ width: col.width, 'min-width': col.minWidth, 'max-width': col.maxWidth }" > <div class="bh-flex bh-items-center" [ngClass]="[col.headerClass ? col.headerClass : '']" (click)="all.sortable && col.sort && sortChange.emit(col.field)"> {{ col.title }} <span *ngIf="all.sortable && col.sort" class="bh-ml-3 bh-sort bh-flex bh-items-center" [ngClass]="[all.sortColumn, all.sortDirection]"> <svg width="16" height="16" viewBox="0 0 14 14" fill="none"> <polygon points="3.11,6.25 10.89,6.25 7,1.75" fill="currentColor" class="bh-text-black/20" [ngClass]="[all.sortColumn === col.field && all.sortDirection === 'asc' ? '!bh-text-primary' : '']" ></polygon> <polygon points="7,12.25 10.89,7.75 3.11,7.75" fill="currentColor" class="bh-text-black/20" [ngClass]="[all.sortColumn === col.field && all.sortDirection === 'desc' ? '!bh-text-primary' : '']" ></polygon> </svg> </span> </div> <ng-container *ngIf="all.columnFilter && !isFooter"> <div *ngIf="col.filter" class="bh-filter bh-relative"> <input *ngIf="col.type === 'string'" [(ngModel)]="col.value" type="text" class="bh-form-control" (keyup)="filterChange.emit()" /> <input *ngIf="col.type === 'number'" [(ngModel)]="col.value" type="number" class="bh-form-control" (keyup)="filterChange.emit()" /> <input *ngIf="col.type === 'date'" [(ngModel)]="col.value" type="date" class="bh-form-control" (change)="filterChange.emit()" /> <select *ngIf="col.type === 'bool'" [(ngModel)]="col.value" class="bh-form-control" (change)="filterChange.emit()" (click)="isOpenFilter = null"> <option [ngValue]="undefined">All</option> <option [ngValue]="true">True</option> <option [ngValue]="false">False</option> </select> <button *ngIf="col.type !== 'bool'" type="button" (click)="toggleFilterMenu(col); $event.stopPropagation()"> <icon-filter class="bh-w-4"></icon-filter> </button> <column-filter [ngClass]="{ 'bh-hidden': isOpenFilter !== col.field }" [column]="col" (close)="toggleFilterMenu()" (filterChange)="filterChange.emit()" ></column-filter> </div> </ng-container> </th> </ng-container> </tr> </ng-template> `, 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.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.ColumnFilterComponent, selector: "column-filter", inputs: ["column"], outputs: ["close", "filterChange"] }, { kind: "component", type: i4.IconCheckComponent, selector: "icon-check", inputs: ["class"] }, { kind: "component", type: i5.IconDashComponent, selector: "icon-dash", inputs: ["class"] }, { kind: "component", type: i6.IconFilterComponent, selector: "icon-filter", inputs: ["class"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ColumnHeaderComponent, decorators: [{ type: Component, args: [{ selector: 'column-header', template: ` <ng-template #template> <tr> <th *ngIf="all.hasCheckbox" [class]="'bh-w-px'" [ngClass]="{ 'bh-sticky bh-bg-blue-light bh-z-[1]': all.stickyHeader || all.stickyFirstColumn, 'bh-top-0': all.stickyHeader, 'bh-left-0': all.stickyFirstColumn }" > <div class="bh-checkbox"> <input #selectedAll type="checkbox" (click)="selectAll.emit(selectedAll.checked); $event.stopPropagation()" /> <div> <icon-check class="check"></icon-check> <icon-dash class="intermediate"></icon-dash> </div> </div> </th> <ng-container *ngFor="let col of all.columns; let j = index"> <th *ngIf="!col.hide" [ngStyle]="{ 'width': col.width, 'min-width': col.minWidth, 'max-width': col.maxWidth }" [class]="'bh-select-none bh-z-[1]'" [ngClass]="[ all.sortable && col.sort ? 'bh-cursor-pointer' : '', j === 0 && all.stickyFirstColumn ? 'bh-sticky bh-left-0 bh-bg-blue-light' : '', all.hasCheckbox && j === 0 && all.stickyFirstColumn ? 'bh-left-[52px]' : '' ]" [style]="{ width: col.width, 'min-width': col.minWidth, 'max-width': col.maxWidth }" > <div class="bh-flex bh-items-center" [ngClass]="[col.headerClass ? col.headerClass : '']" (click)="all.sortable && col.sort && sortChange.emit(col.field)"> {{ col.title }} <span *ngIf="all.sortable && col.sort" class="bh-ml-3 bh-sort bh-flex bh-items-center" [ngClass]="[all.sortColumn, all.sortDirection]"> <svg width="16" height="16" viewBox="0 0 14 14" fill="none"> <polygon points="3.11,6.25 10.89,6.25 7,1.75" fill="currentColor" class="bh-text-black/20" [ngClass]="[all.sortColumn === col.field && all.sortDirection === 'asc' ? '!bh-text-primary' : '']" ></polygon> <polygon points="7,12.25 10.89,7.75 3.11,7.75" fill="currentColor" class="bh-text-black/20" [ngClass]="[all.sortColumn === col.field && all.sortDirection === 'desc' ? '!bh-text-primary' : '']" ></polygon> </svg> </span> </div> <ng-container *ngIf="all.columnFilter && !isFooter"> <div *ngIf="col.filter" class="bh-filter bh-relative"> <input *ngIf="col.type === 'string'" [(ngModel)]="col.value" type="text" class="bh-form-control" (keyup)="filterChange.emit()" /> <input *ngIf="col.type === 'number'" [(ngModel)]="col.value" type="number" class="bh-form-control" (keyup)="filterChange.emit()" /> <input *ngIf="col.type === 'date'" [(ngModel)]="col.value" type="date" class="bh-form-control" (change)="filterChange.emit()" /> <select *ngIf="col.type === 'bool'" [(ngModel)]="col.value" class="bh-form-control" (change)="filterChange.emit()" (click)="isOpenFilter = null"> <option [ngValue]="undefined">All</option> <option [ngValue]="true">True</option> <option [ngValue]="false">False</option> </select> <button *ngIf="col.type !== 'bool'" type="button" (click)="toggleFilterMenu(col); $event.stopPropagation()"> <icon-filter class="bh-w-4"></icon-filter> </button> <column-filter [ngClass]="{ 'bh-hidden': isOpenFilter !== col.field }" [column]="col" (close)="toggleFilterMenu()" (filterChange)="filterChange.emit()" ></column-filter> </div> </ng-container> </th> </ng-container> </tr> </ng-template> `, }] }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }]; }, propDecorators: { template: [{ type: ViewChild, args: ['template', { static: true }] }], selectedAll: [{ type: ViewChild, args: ['selectedAll'] }], all: [{ type: Input }], isFooter: [{ type: Input }], checkAll: [{ type: Input }], selectAll: [{ type: Output, args: ['selectAll'] }], sortChange: [{ type: Output, args: ['sortChange'] }], filterChange: [{ type: Output, args: ['filterChange'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sdW1uLWhlYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYi9jb2x1bW4taGVhZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFvQixNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7QUF1RnBHLE1BQU0sT0FBTyxxQkFBcUI7SUFjOUIsWUFBb0IsZ0JBQWtDO1FBQWxDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFOakMsY0FBUyxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ3RELGVBQVUsR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUN0RCxpQkFBWSxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBRWxGLGlCQUFZLEdBQVEsSUFBSSxDQUFDO0lBRWdDLENBQUM7SUFFMUQsUUFBUTtRQUNKLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRCxjQUFjO1FBQ1YsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ2xCLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsUUFBUSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7WUFDNUYsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7U0FDMUQ7SUFDTCxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsR0FBWTtRQUN6QixJQUFJLEdBQUcsRUFBRTtZQUNMLElBQUksSUFBSSxDQUFDLFlBQVksS0FBSyxHQUFHLENBQUMsS0FBSyxFQUFFO2dCQUNqQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQzthQUM1QjtpQkFBTTtnQkFDSCxJQUFJLENBQUMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUM7YUFDakM7U0FDSjthQUFNO1lBQ0gsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDNUI7SUFDTCxDQUFDOzttSEF0Q1EscUJBQXFCO3VHQUFyQixxQkFBcUIsdWFBbEZwQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0FnRlQ7NEZBRVEscUJBQXFCO2tCQXBGakMsU0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUsZUFBZTtvQkFDekIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztLQWdGVDtpQkFDSjt1R0FFNEMsUUFBUTtzQkFBaEQsU0FBUzt1QkFBQyxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNiLFdBQVc7c0JBQXBDLFNBQVM7dUJBQUMsYUFBYTtnQkFFZixHQUFHO3NCQUFYLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVlLFNBQVM7c0JBQTdCLE1BQU07dUJBQUMsV0FBVztnQkFDRyxVQUFVO3NCQUEvQixNQUFNO3VCQUFDLFlBQVk7Z0JBQ0ksWUFBWTtzQkFBbkMsTUFBTTt1QkFBQyxjQUFjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIFZpZXdDaGlsZCwgVmlld0NvbnRhaW5lclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBjb2xEZWYgfSBmcm9tICcuL21vZGFscyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnY29sdW1uLWhlYWRlcicsXHJcbiAgICB0ZW1wbGF0ZTogYFxyXG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjdGVtcGxhdGU+XHJcbiAgICAgICAgICAgIDx0cj5cclxuICAgICAgICAgICAgICAgIDx0aFxyXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiYWxsLmhhc0NoZWNrYm94XCJcclxuICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiJ2JoLXctcHgnXCJcclxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdiaC1zdGlja3kgYmgtYmctYmx1ZS1saWdodCBiaC16LVsxXSc6IGFsbC5zdGlja3lIZWFkZXIgfHwgYWxsLnN0aWNreUZpcnN0Q29sdW1uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnYmgtdG9wLTAnOiBhbGwuc3RpY2t5SGVhZGVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnYmgtbGVmdC0wJzogYWxsLnN0aWNreUZpcnN0Q29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJoLWNoZWNrYm94XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAjc2VsZWN0ZWRBbGwgdHlwZT1cImNoZWNrYm94XCIgKGNsaWNrKT1cInNlbGVjdEFsbC5lbWl0KHNlbGVjdGVkQWxsLmNoZWNrZWQpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGljb24tY2hlY2sgY2xhc3M9XCJjaGVja1wiPjwvaWNvbi1jaGVjaz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpY29uLWRhc2ggY2xhc3M9XCJpbnRlcm1lZGlhdGVcIj48L2ljb24tZGFzaD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L3RoPlxyXG5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbCBvZiBhbGwuY29sdW1uczsgbGV0IGogPSBpbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFjb2wuaGlkZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ3dpZHRoJzogY29sLndpZHRoLCAnbWluLXdpZHRoJzogY29sLm1pbldpZHRoLCAnbWF4LXdpZHRoJzogY29sLm1heFdpZHRoIH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiJ2JoLXNlbGVjdC1ub25lIGJoLXotWzFdJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIltcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbC5zb3J0YWJsZSAmJiBjb2wuc29ydCA/ICdiaC1jdXJzb3ItcG9pbnRlcicgOiAnJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGogPT09IDAgJiYgYWxsLnN0aWNreUZpcnN0Q29sdW1uID8gJ2JoLXN0aWNreSBiaC1sZWZ0LTAgYmgtYmctYmx1ZS1saWdodCcgOiAnJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbC5oYXNDaGVja2JveCAmJiBqID09PSAwICYmIGFsbC5zdGlja3lGaXJzdENvbHVtbiA/ICdiaC1sZWZ0LVs1MnB4XScgOiAnJ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlXT1cInsgd2lkdGg6IGNvbC53aWR0aCwgJ21pbi13aWR0aCc6IGNvbC5taW5XaWR0aCwgJ21heC13aWR0aCc6IGNvbC5tYXhXaWR0aCB9XCJcclxuICAgICAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiaC1mbGV4IGJoLWl0ZW1zLWNlbnRlclwiIFtuZ0NsYXNzXT1cIltjb2wuaGVhZGVyQ2xhc3MgPyBjb2wuaGVhZGVyQ2xhc3MgOiAnJ11cIiAoY2xpY2spPVwiYWxsLnNvcnRhYmxlICYmIGNvbC5zb3J0ICYmIHNvcnRDaGFuZ2UuZW1pdChjb2wuZmllbGQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb2wudGl0bGUgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiYWxsLnNvcnRhYmxlICYmIGNvbC5zb3J0XCIgY2xhc3M9XCJiaC1tbC0zIGJoLXNvcnQgYmgtZmxleCBiaC1pdGVtcy1jZW50ZXJcIiBbbmdDbGFzc109XCJbYWxsLnNvcnRDb2x1bW4sIGFsbC5zb3J0RGlyZWN0aW9uXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgdmlld0JveD1cIjAgMCAxNCAxNFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwb2x5Z29uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludHM9XCIzLjExLDYuMjUgMTAuODksNi4yNSA3LDEuNzVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJoLXRleHQtYmxhY2svMjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiW2FsbC5zb3J0Q29sdW1uID09PSBjb2wuZmllbGQgJiYgYWxsLnNvcnREaXJlY3Rpb24gPT09ICdhc2MnID8gJyFiaC10ZXh0LXByaW1hcnknIDogJyddXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvcG9seWdvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBvbHlnb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cz1cIjcsMTIuMjUgMTAuODksNy43NSAzLjExLDcuNzVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJoLXRleHQtYmxhY2svMjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiW2FsbC5zb3J0Q29sdW1uID09PSBjb2wuZmllbGQgJiYgYWxsLnNvcnREaXJlY3Rpb24gPT09ICdkZXNjJyA/ICchYmgtdGV4dC1wcmltYXJ5JyA6ICcnXVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L3BvbHlnb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImFsbC5jb2x1bW5GaWx0ZXIgJiYgIWlzRm9vdGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY29sLmZpbHRlclwiIGNsYXNzPVwiYmgtZmlsdGVyIGJoLXJlbGF0aXZlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwiY29sLnR5cGUgPT09ICdzdHJpbmcnXCIgWyhuZ01vZGVsKV09XCJjb2wudmFsdWVcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiYmgtZm9ybS1jb250cm9sXCIgKGtleXVwKT1cImZpbHRlckNoYW5nZS5lbWl0KClcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cImNvbC50eXBlID09PSAnbnVtYmVyJ1wiIFsobmdNb2RlbCldPVwiY29sLnZhbHVlXCIgdHlwZT1cIm51bWJlclwiIGNsYXNzPVwiYmgtZm9ybS1jb250cm9sXCIgKGtleXVwKT1cImZpbHRlckNoYW5nZS5lbWl0KClcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cImNvbC50eXBlID09PSAnZGF0ZSdcIiBbKG5nTW9kZWwpXT1cImNvbC52YWx1ZVwiIHR5cGU9XCJkYXRlXCIgY2xhc3M9XCJiaC1mb3JtLWNvbnRyb2xcIiAoY2hhbmdlKT1cImZpbHRlckNoYW5nZS5lbWl0KClcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgKm5nSWY9XCJjb2wudHlwZSA9PT0gJ2Jvb2wnXCIgWyhuZ01vZGVsKV09XCJjb2wudmFsdWVcIiBjbGFzcz1cImJoLWZvcm0tY29udHJvbFwiIChjaGFuZ2UpPVwiZmlsdGVyQ2hhbmdlLmVtaXQoKVwiIChjbGljayk9XCJpc09wZW5GaWx0ZXIgPSBudWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwidW5kZWZpbmVkXCI+QWxsPC9vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwidHJ1ZVwiPlRydWU8L29wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCJmYWxzZVwiPkZhbHNlPC9vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJjb2wudHlwZSAhPT0gJ2Jvb2wnXCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJ0b2dnbGVGaWx0ZXJNZW51KGNvbCk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aWNvbi1maWx0ZXIgY2xhc3M9XCJiaC13LTRcIj48L2ljb24tZmlsdGVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29sdW1uLWZpbHRlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdiaC1oaWRkZW4nOiBpc09wZW5GaWx0ZXIgIT09IGNvbC5maWVsZCB9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbHVtbl09XCJjb2xcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xvc2UpPVwidG9nZ2xlRmlsdGVyTWVudSgpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZpbHRlckNoYW5nZSk9XCJmaWx0ZXJDaGFuZ2UuZW1pdCgpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9jb2x1bW4tZmlsdGVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPC90cj5cclxuICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgYCxcclxufSlcclxuZXhwb3J0IGNsYXNzIENvbHVtbkhlYWRlckNvbXBvbmVudCB7XHJcbiAgICBAVmlld0NoaWxkKCd0ZW1wbGF0ZScsIHsgc3RhdGljOiB0cnVlIH0pIHRlbXBsYXRlOiBhbnk7XHJcbiAgICBAVmlld0NoaWxkKCdzZWxlY3RlZEFsbCcpIHNlbGVjdGVkQWxsOiBhbnk7XHJcblxyXG4gICAgQElucHV0KCkgYWxsOiBhbnk7XHJcbiAgICBASW5wdXQoKSBpc0Zvb3RlcjogYW55O1xyXG4gICAgQElucHV0KCkgY2hlY2tBbGw6IGFueTtcclxuXHJcbiAgICBAT3V0cHV0KCdzZWxlY3RBbGwnKSBzZWxlY3RBbGw6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgICBAT3V0cHV0KCdzb3J0Q2hhbmdlJykgc29ydENoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAgIEBPdXRwdXQoJ2ZpbHRlckNoYW5nZScpIGZpbHRlckNoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgICBpc09wZW5GaWx0ZXI6IGFueSA9IG51bGw7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmKSB7fVxyXG5cclxuICAgIG5nT25Jbml0KCkge1xyXG4gICAgICAgIHRoaXMudmlld0NvbnRhaW5lclJlZi5jcmVhdGVFbWJlZGRlZFZpZXcodGhpcy50ZW1wbGF0ZSk7XHJcbiAgICAgICAgdGhpcy5jaGVja2JveENoYW5nZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGNoZWNrYm94Q2hhbmdlKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkQWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRBbGwubmF0aXZlRWxlbWVudC5pbmRldGVybWluYXRlID0gdGhpcy5jaGVja0FsbCAhPT0gMCA/ICF0aGlzLmNoZWNrQWxsIDogZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRBbGwubmF0aXZlRWxlbWVudC5jaGVja2VkID0gdGhpcy5jaGVja0FsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdG9nZ2xlRmlsdGVyTWVudShjb2w/OiBjb2xEZWYpIHtcclxuICAgICAgICBpZiAoY29sKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzT3BlbkZpbHRlciA9PT0gY29sLmZpZWxkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzT3BlbkZpbHRlciA9IG51bGw7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzT3BlbkZpbHRlciA9IGNvbC5maWVsZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuaXNPcGVuRmlsdGVyID0gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIl19