@alfiob/ng-datatable
Version:
ng-datatable - fully customizable & easy to use datatable library
231 lines (223 loc) • 27.1 kB
JavaScript
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