@angular-generic-table/column-settings
Version:
angular-generic-table extension that makes it easy to toggle column visibility and reoder columns.
338 lines (332 loc) • 33.7 kB
JavaScript
import { __assign, __spread, __read } from 'tslib';
import { Component, Input, ViewChild, Pipe, ChangeDetectorRef, HostListener, Output, EventEmitter, NgModule } from '@angular/core';
import { GenericTableModule } from '@angular-generic-table/core';
import { DragulaService, DragulaModule } from 'ng2-dragula';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var GtColumnPipe = /** @class */ (function () {
function GtColumnPipe() {
}
/**
* Sort by column order
* @param {?} a
* @param {?} b
* @return {?}
*/
GtColumnPipe.prototype.getColumnOrder = /**
* Sort by column order
* @param {?} a
* @param {?} b
* @return {?}
*/
function (a, b) {
if (a.columnOrder < b.columnOrder) {
return -1;
}
if (a.columnOrder > b.columnOrder || typeof a.columnOrder === 'undefined') {
return 1;
}
return 0;
};
/**
* return enabled columns that are not locked for editing
* @param {?} column
* @return {?}
*/
GtColumnPipe.prototype.getEnabled = /**
* return enabled columns that are not locked for editing
* @param {?} column
* @return {?}
*/
function (column) {
return column.enabled !== false && column.lockSettings !== true
? column
: null;
};
/**
* @param {?} settings
* @return {?}
*/
GtColumnPipe.prototype.transform = /**
* @param {?} settings
* @return {?}
*/
function (settings) {
return settings.filter(this.getEnabled).sort(this.getColumnOrder);
};
GtColumnPipe.decorators = [
{ type: Pipe, args: [{
name: 'gtColumn'
},] },
];
return GtColumnPipe;
}());
var GtColumnSettingsComponent = /** @class */ (function () {
function GtColumnSettingsComponent(dragulaService, changeDetectorRef) {
var _this = this;
this.dragulaService = dragulaService;
this.changeDetectorRef = changeDetectorRef;
this.gtHeaderClasses = 'px-3 pt-3 pb-2 table-bordered border-left-0 border-right-0 border-bottom-0 alert-info';
this.gtWrapperClasses = 'px-3 pb-3 table-bordered border-left-0 border-right-0 border-top-0 alert-info';
this.overlay = true;
this.gtDefaultTexts = {
title: 'Columns',
help: 'Double click to toggle visibility, drag and drop to reorder.'
};
this.gtTexts = this.gtDefaultTexts;
this.gtEvent = new EventEmitter();
this.active = false;
this.reordered = false;
/**
* Extend object function.
*/
this.extend = function (a, b) {
for (var /** @type {?} */ key in b) {
if (b.hasOwnProperty(key)) {
a[key] = b[key];
}
}
return a;
};
dragulaService.drop.subscribe(function (value) {
if (value[0] === _this.bagId) {
_this._onDrop(value.slice(1));
}
});
}
Object.defineProperty(GtColumnSettingsComponent.prototype, "genericTable", {
get: /**
* @return {?}
*/
function () {
return this._genericTable;
},
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this._genericTable = value;
},
enumerable: true,
configurable: true
});
/**
* Check offset height on window resize.
* @return {?}
*/
GtColumnSettingsComponent.prototype.onResize = /**
* Check offset height on window resize.
* @return {?}
*/
function () {
this.offset = this._getTableHeadHeight();
this.heightAdjust = this._getColumnSettingsHeaderHeight();
};
/**
* @return {?}
*/
GtColumnSettingsComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.bagId = this.generateId();
// setup texts
this.gtTexts = /** @type {?} */ (this.extend(this.gtDefaultTexts, this.gtTexts));
};
/**
* Toggle column settings visibility.
* @return {?}
*/
GtColumnSettingsComponent.prototype.toggleColumnSettings = /**
* Toggle column settings visibility.
* @return {?}
*/
function () {
var _this = this;
this.active = !this.active;
if (this.active) {
this.offset = this._getTableHeadHeight();
// check and adjust height offset
setTimeout(function () {
_this.heightAdjust = _this._getColumnSettingsHeaderHeight();
}, 0);
}
};
/**
* Toggle column visibility.
* @param {?} column - column object.
* @return {?}
*/
GtColumnSettingsComponent.prototype.toggleColumnVisibility = /**
* Toggle column visibility.
* @param {?} column - column object.
* @return {?}
*/
function (column) {
var _this = this;
// toggle column visibility
column.visible =
typeof column.visible === 'undefined' ? false : !column.visible;
// redraw table
this._genericTable.redraw();
// emit event
this.gtEvent.emit({
name: 'gt-column-visibility-change',
value: {
column: __assign({}, column),
settings: __spread(this._genericTable.gtSettings)
}
});
// check and reset offset
setTimeout(function () {
_this.offset = _this._getTableHeadHeight();
}, 0);
};
/**
* Order table by object key.
* @param {?} args - name of key to sort on.
* @return {?}
*/
GtColumnSettingsComponent.prototype._onDrop = /**
* Order table by object key.
* @param {?} args - name of key to sort on.
* @return {?}
*/
function (args) {
this.reordered = true;
var _a = __read(args, 2), e = _a[0], target = _a[1];
var /** @type {?} */ order = {};
for (var /** @type {?} */ i = 0; i < target.children.length; i++) {
order[target.children[i].getAttribute('data-object-key')] = i;
}
for (var /** @type {?} */ i = 0; i < this._genericTable.gtSettings.length; i++) {
this._genericTable.gtSettings[i].columnOrder =
order[this._genericTable.gtSettings[i].objectKey];
}
// reset array to trigger change detection
this._genericTable.gtSettings = __spread(this._genericTable.gtSettings);
this.changeDetectorRef.markForCheck();
this._genericTable.redraw();
this.gtEvent.emit({
name: 'gt-column-order-change',
value: {
settings: __spread(this._genericTable.gtSettings)
}
});
};
/**
* Get height of table head element ie. first row containing table headers.
* @return {?} offset height for table header in px.
*/
GtColumnSettingsComponent.prototype._getTableHeadHeight = /**
* Get height of table head element ie. first row containing table headers.
* @return {?} offset height for table header in px.
*/
function () {
try {
if (this.elementView.elementRef.nativeElement.nextElementSibling
.firstElementChild.firstElementChild.tagName === 'THEAD') {
return (this.elementView.elementRef.nativeElement.nextElementSibling
.firstElementChild.firstElementChild.offsetHeight + 'px');
}
if (this.elementView.elementRef.nativeElement.nextElementSibling
.firstElementChild.firstElementChild.firstElementChild.tagName ===
'THEAD') {
return (this.elementView.elementRef.nativeElement.nextElementSibling
.firstElementChild.firstElementChild.firstElementChild
.offsetHeight + 'px');
}
return '0px';
}
catch (/** @type {?} */ error) {
return '0px';
}
};
/**
* Get height of table head element ie. first row containing table headers.
* @return {?} offset height for table header in px.
*/
GtColumnSettingsComponent.prototype._getColumnSettingsHeaderHeight = /**
* Get height of table head element ie. first row containing table headers.
* @return {?} offset height for table header in px.
*/
function () {
try {
return this.gtColumnSettingsHeader.nativeElement.offsetHeight + 'px';
}
catch (/** @type {?} */ error) {
return '0px';
}
};
/**
* generate a unique id for dragula instance i.e. a unique bag name
* @return {?}
*/
GtColumnSettingsComponent.prototype.generateId = /**
* generate a unique id for dragula instance i.e. a unique bag name
* @return {?}
*/
function () {
var /** @type {?} */ d = new Date().getTime();
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var /** @type {?} */ r = ((d + Math.random() * 16) % 16) | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
});
};
GtColumnSettingsComponent.decorators = [
{ type: Component, args: [{
selector: 'gt-column-settings',
template: "\n <ng-template #columnItem let-column let-index=\"index\">\n <span class=\"badge badge-secondary\">{{index}}</span>\n <span (dblclick)=\"toggleColumnVisibility(column)\" class=\"badge\" [ngClass]=\"{'badge-success':column.visible !== false, 'badge-danger':column.visible === false}\">{{genericTable.gtFields | gtProperty:column.objectKey:'name'}}</span>\n </ng-template>\n <div class=\"gt-column-settings\">\n <div class=\"gt-column-settings-panel\" *ngIf=\"active\" [style.padding-top]=\"offset\" [style.height]=\"'calc(100% - '+offset+')'\">\n <div #gtColumnSettingsHeader class=\"gt-column-settings-header border-bottom-0\" [ngClass]=\"gtHeaderClasses\">\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"toggleColumnSettings()\">\n <span aria-hidden=\"true\">×</span>\n </button>\n <h6 class=\"gt-column-settings-title\" *ngIf=\"gtTexts.title\">{{gtTexts.title}}</h6>\n <small class=\"gt-column-settings-help form-text text-muted\" *ngIf=\"gtTexts.help\">{{gtTexts.help}}</small>\n </div>\n <div class=\"gt-column-settings-item-wrapper\" [ngClass]=\"gtWrapperClasses\" [dragula]='bagId' data-visible=\"true\" [style.max-height]=\"'calc(100% - '+heightAdjust+')'\">\n <div class=\"gt-column-settings-item pr-0 pr-sm-4\" *ngFor=\"let i = index;let column of genericTable.gtSettings | gtColumn\" [attr.data-object-key]=\"column.objectKey\">\n <ng-template [ngTemplateOutlet]=\"gtColumnItem ? gtColumnItem:columnItem\" [ngTemplateOutletContext]=\"{$implicit: column,index: this.reordered ? column.columnOrder+1:i+1, name: (genericTable.gtFields | gtProperty:column.objectKey:'name')}\"></ng-template>\n </div>\n </div>\n <div class=\"gt-overlay\" *ngIf=\"active && overlay\" (click)=\"toggleColumnSettings()\" [style.height]=\"'calc(100% - -'+offset+')'\"></div>\n </div>\n <ng-template #genericTableElement [ngIf]=\"genericTable\">\n <ng-content></ng-content>\n </ng-template>\n </div>\n "
},] },
];
/* tslint:enable */
/** @nocollapse */
GtColumnSettingsComponent.ctorParameters = function () { return [
{ type: DragulaService, },
{ type: ChangeDetectorRef, },
]; };
GtColumnSettingsComponent.propDecorators = {
"genericTable": [{ type: Input },],
"elementView": [{ type: ViewChild, args: ['genericTableElement',] },],
"gtColumnSettingsHeader": [{ type: ViewChild, args: ['gtColumnSettingsHeader',] },],
"gtHeaderClasses": [{ type: Input },],
"gtWrapperClasses": [{ type: Input },],
"overlay": [{ type: Input },],
"gtColumnItem": [{ type: Input },],
"gtTexts": [{ type: Input },],
"gtEvent": [{ type: Output },],
"onResize": [{ type: HostListener, args: ['window:resize', [],] },],
};
return GtColumnSettingsComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var ColumnSettingsModule = /** @class */ (function () {
function ColumnSettingsModule() {
}
ColumnSettingsModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule, GenericTableModule, DragulaModule],
declarations: [GtColumnSettingsComponent, GtColumnPipe],
exports: [GtColumnSettingsComponent, GtColumnPipe]
},] },
];
return ColumnSettingsModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
export { ColumnSettingsModule, GtColumnPipe as ɵa, GtColumnSettingsComponent as ɵb };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1nZW5lcmljLXRhYmxlLWNvbHVtbi1zZXR0aW5ncy5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb2x1bW4tc2V0dGluZ3MvY29tcG9uZW50cy9ndC1jb2x1bW4tc2V0dGluZ3MuY29tcG9uZW50LnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvbHVtbi1zZXR0aW5ncy9jb2x1bW4tc2V0dGluZ3MubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0SW5wdXQsXG5cdFZpZXdDaGlsZCxcblx0VGVtcGxhdGVSZWYsXG5cdEVsZW1lbnRSZWYsXG5cdFBpcGUsXG5cdFBpcGVUcmFuc2Zvcm0sXG5cdE9uSW5pdCxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdEhvc3RMaXN0ZW5lcixcblx0T3V0cHV0LFxuXHRFdmVudEVtaXR0ZXJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuXHRHZW5lcmljVGFibGVDb21wb25lbnQsXG5cdEd0Um93LFxuXHRHdENvbmZpZ1NldHRpbmdcbn0gZnJvbSAnQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlJztcbmltcG9ydCB7IERyYWd1bGFTZXJ2aWNlIH0gZnJvbSAnbmcyLWRyYWd1bGEnO1xuaW1wb3J0IHsgR3RDb2x1bW5TZXR0aW5nc1RleHRzIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1jb2x1bW4tc2V0dGluZ3MtdGV4dHMnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndENvbHVtbidcbn0pXG5leHBvcnQgY2xhc3MgR3RDb2x1bW5QaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdC8vIFRPRE86IG1vdmUgdG8gaGVscGVyIGZ1bmN0aW9uc1xuXHQvKiogU29ydCBieSBjb2x1bW4gb3JkZXIgKi9cblx0cHJpdmF0ZSBnZXRDb2x1bW5PcmRlcihhOiBhbnksIGI6IGFueSkge1xuXHRcdGlmIChhLmNvbHVtbk9yZGVyIDwgYi5jb2x1bW5PcmRlcikge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoYS5jb2x1bW5PcmRlciA+IGIuY29sdW1uT3JkZXIgfHwgdHlwZW9mIGEuY29sdW1uT3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHQvKiogcmV0dXJuIGVuYWJsZWQgY29sdW1ucyB0aGF0IGFyZSBub3QgbG9ja2VkIGZvciBlZGl0aW5nICovXG5cdHByaXZhdGUgZ2V0RW5hYmxlZChjb2x1bW46IEd0Q29uZmlnU2V0dGluZykge1xuXHRcdHJldHVybiBjb2x1bW4uZW5hYmxlZCAhPT0gZmFsc2UgJiYgY29sdW1uLmxvY2tTZXR0aW5ncyAhPT0gdHJ1ZVxuXHRcdFx0PyBjb2x1bW5cblx0XHRcdDogbnVsbDtcblx0fVxuXG5cdHRyYW5zZm9ybShzZXR0aW5nczogQXJyYXk8R3RDb25maWdTZXR0aW5nPik6IEFycmF5PEd0Q29uZmlnU2V0dGluZz4ge1xuXHRcdHJldHVybiBzZXR0aW5ncy5maWx0ZXIodGhpcy5nZXRFbmFibGVkKS5zb3J0KHRoaXMuZ2V0Q29sdW1uT3JkZXIpO1xuXHR9XG59XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2d0LWNvbHVtbi1zZXR0aW5ncycsXG5cdHRlbXBsYXRlOiBgXG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjY29sdW1uSXRlbSBsZXQtY29sdW1uIGxldC1pbmRleD1cImluZGV4XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJhZGdlLXNlY29uZGFyeVwiPnt7aW5kZXh9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIChkYmxjbGljayk9XCJ0b2dnbGVDb2x1bW5WaXNpYmlsaXR5KGNvbHVtbilcIiBjbGFzcz1cImJhZGdlXCIgW25nQ2xhc3NdPVwieydiYWRnZS1zdWNjZXNzJzpjb2x1bW4udmlzaWJsZSAhPT0gZmFsc2UsICdiYWRnZS1kYW5nZXInOmNvbHVtbi52aXNpYmxlID09PSBmYWxzZX1cIj57e2dlbmVyaWNUYWJsZS5ndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZSd9fTwvc3Bhbj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImd0LWNvbHVtbi1zZXR0aW5nc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImd0LWNvbHVtbi1zZXR0aW5ncy1wYW5lbFwiICAqbmdJZj1cImFjdGl2ZVwiIFtzdHlsZS5wYWRkaW5nLXRvcF09XCJvZmZzZXRcIiBbc3R5bGUuaGVpZ2h0XT1cIidjYWxjKDEwMCUgLSAnK29mZnNldCsnKSdcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICNndENvbHVtblNldHRpbmdzSGVhZGVyIGNsYXNzPVwiZ3QtY29sdW1uLXNldHRpbmdzLWhlYWRlciBib3JkZXItYm90dG9tLTBcIiBbbmdDbGFzc109XCJndEhlYWRlckNsYXNzZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiIChjbGljayk9XCJ0b2dnbGVDb2x1bW5TZXR0aW5ncygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj4mdGltZXM7PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPGg2IGNsYXNzPVwiZ3QtY29sdW1uLXNldHRpbmdzLXRpdGxlXCIgKm5nSWY9XCJndFRleHRzLnRpdGxlXCI+e3tndFRleHRzLnRpdGxlfX08L2g2PlxuICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJndC1jb2x1bW4tc2V0dGluZ3MtaGVscCBmb3JtLXRleHQgdGV4dC1tdXRlZFwiICpuZ0lmPVwiZ3RUZXh0cy5oZWxwXCI+e3tndFRleHRzLmhlbHB9fTwvc21hbGw+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImd0LWNvbHVtbi1zZXR0aW5ncy1pdGVtLXdyYXBwZXJcIiBbbmdDbGFzc109XCJndFdyYXBwZXJDbGFzc2VzXCIgW2RyYWd1bGFdPSdiYWdJZCcgIGRhdGEtdmlzaWJsZT1cInRydWVcIiBbc3R5bGUubWF4LWhlaWdodF09XCInY2FsYygxMDAlIC0gJytoZWlnaHRBZGp1c3QrJyknXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJndC1jb2x1bW4tc2V0dGluZ3MtaXRlbSBwci0wIHByLXNtLTRcIiAqbmdGb3I9XCJsZXQgaSA9IGluZGV4O2xldCBjb2x1bW4gb2YgZ2VuZXJpY1RhYmxlLmd0U2V0dGluZ3MgfCBndENvbHVtblwiIFthdHRyLmRhdGEtb2JqZWN0LWtleV09XCJjb2x1bW4ub2JqZWN0S2V5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiZ3RDb2x1bW5JdGVtID8gZ3RDb2x1bW5JdGVtOmNvbHVtbkl0ZW1cIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogY29sdW1uLGluZGV4OiB0aGlzLnJlb3JkZXJlZCA/IGNvbHVtbi5jb2x1bW5PcmRlcisxOmkrMSwgbmFtZTogKGdlbmVyaWNUYWJsZS5ndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZScpfVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJndC1vdmVybGF5XCIgKm5nSWY9XCJhY3RpdmUgJiYgb3ZlcmxheVwiIChjbGljayk9XCJ0b2dnbGVDb2x1bW5TZXR0aW5ncygpXCIgW3N0eWxlLmhlaWdodF09XCInY2FsYygxMDAlIC0gLScrb2Zmc2V0KycpJ1wiPjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2dlbmVyaWNUYWJsZUVsZW1lbnQgW25nSWZdPVwiZ2VuZXJpY1RhYmxlXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgYFxufSlcbmV4cG9ydCBjbGFzcyBHdENvbHVtblNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblx0Z2V0IGdlbmVyaWNUYWJsZSgpOiBHZW5lcmljVGFibGVDb21wb25lbnQ8YW55LCBhbnk+IHtcblx0XHRyZXR1cm4gdGhpcy5fZ2VuZXJpY1RhYmxlO1xuXHR9XG5cblx0QElucHV0KClcblx0c2V0IGdlbmVyaWNUYWJsZSh2YWx1ZTogR2VuZXJpY1RhYmxlQ29tcG9uZW50PGFueSwgYW55Pikge1xuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZSA9IHZhbHVlO1xuXHR9XG5cblx0QFZpZXdDaGlsZCgnZ2VuZXJpY1RhYmxlRWxlbWVudCcpIGVsZW1lbnRWaWV3OiBUZW1wbGF0ZVJlZjxFbGVtZW50UmVmPjtcblx0QFZpZXdDaGlsZCgnZ3RDb2x1bW5TZXR0aW5nc0hlYWRlcicpIGd0Q29sdW1uU2V0dGluZ3NIZWFkZXI6IEVsZW1lbnRSZWY7XG5cblx0cHJpdmF0ZSBfZ2VuZXJpY1RhYmxlOiBHZW5lcmljVGFibGVDb21wb25lbnQ8R3RSb3csIGFueT47XG5cdEBJbnB1dCgpXG5cdGd0SGVhZGVyQ2xhc3NlcyA9ICdweC0zIHB0LTMgcGItMiB0YWJsZS1ib3JkZXJlZCBib3JkZXItbGVmdC0wIGJvcmRlci1yaWdodC0wIGJvcmRlci1ib3R0b20tMCBhbGVydC1pbmZvJztcblx0QElucHV0KClcblx0Z3RXcmFwcGVyQ2xhc3NlcyA9ICdweC0zIHBiLTMgdGFibGUtYm9yZGVyZWQgYm9yZGVyLWxlZnQtMCBib3JkZXItcmlnaHQtMCBib3JkZXItdG9wLTAgYWxlcnQtaW5mbyc7XG5cdEBJbnB1dCgpIG92ZXJsYXkgPSB0cnVlO1xuXHRASW5wdXQoKSBndENvbHVtbkl0ZW06IFRlbXBsYXRlUmVmPEVsZW1lbnRSZWY+O1xuXHRwdWJsaWMgZ3REZWZhdWx0VGV4dHM6IEd0Q29sdW1uU2V0dGluZ3NUZXh0cyA9IHtcblx0XHR0aXRsZTogJ0NvbHVtbnMnLFxuXHRcdGhlbHA6ICdEb3VibGUgY2xpY2sgdG8gdG9nZ2xlIHZpc2liaWxpdHksIGRyYWcgYW5kIGRyb3AgdG8gcmVvcmRlci4nXG5cdH07XG5cdEBJbnB1dCgpIGd0VGV4dHM6IEd0Q29sdW1uU2V0dGluZ3NUZXh0cyA9IHRoaXMuZ3REZWZhdWx0VGV4dHM7XG5cblx0QE91dHB1dCgpIHB1YmxpYyBndEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG5cdHB1YmxpYyBhY3RpdmUgPSBmYWxzZTtcblx0cHVibGljIG9mZnNldDogc3RyaW5nO1xuXHRwdWJsaWMgaGVpZ2h0QWRqdXN0OiBzdHJpbmc7XG5cdHB1YmxpYyByZW9yZGVyZWQgPSBmYWxzZTtcblx0cHVibGljIGJhZ0lkOiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIENoZWNrIG9mZnNldCBoZWlnaHQgb24gd2luZG93IHJlc2l6ZS5cblx0ICovXG5cdEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbXSlcblx0cHVibGljIG9uUmVzaXplKCkge1xuXHRcdHRoaXMub2Zmc2V0ID0gdGhpcy5fZ2V0VGFibGVIZWFkSGVpZ2h0KCk7XG5cdFx0dGhpcy5oZWlnaHRBZGp1c3QgPSB0aGlzLl9nZXRDb2x1bW5TZXR0aW5nc0hlYWRlckhlaWdodCgpO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSBkcmFndWxhU2VydmljZTogRHJhZ3VsYVNlcnZpY2UsXG5cdFx0cHJpdmF0ZSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWZcblx0KSB7XG5cdFx0ZHJhZ3VsYVNlcnZpY2UuZHJvcC5zdWJzY3JpYmUoKHZhbHVlOiBBcnJheTxhbnk+KSA9PiB7XG5cdFx0XHRpZiAodmFsdWVbMF0gPT09IHRoaXMuYmFnSWQpIHtcblx0XHRcdFx0dGhpcy5fb25Ecm9wKHZhbHVlLnNsaWNlKDEpKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdG5nT25Jbml0KCkge1xuXHRcdHRoaXMuYmFnSWQgPSB0aGlzLmdlbmVyYXRlSWQoKTtcblx0XHQvLyBzZXR1cCB0ZXh0c1xuXHRcdHRoaXMuZ3RUZXh0cyA9IDxHdENvbHVtblNldHRpbmdzVGV4dHM+dGhpcy5leHRlbmQoXG5cdFx0XHR0aGlzLmd0RGVmYXVsdFRleHRzLFxuXHRcdFx0dGhpcy5ndFRleHRzXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiAgRXh0ZW5kIG9iamVjdCBmdW5jdGlvbi5cblx0ICovXG5cdHByaXZhdGUgZXh0ZW5kID0gZnVuY3Rpb24oYTogT2JqZWN0LCBiOiBPYmplY3QpIHtcblx0XHRmb3IgKGNvbnN0IGtleSBpbiBiKSB7XG5cdFx0XHRpZiAoYi5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHRcdGFba2V5XSA9IGJba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGE7XG5cdH07XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSBjb2x1bW4gc2V0dGluZ3MgdmlzaWJpbGl0eS5cblx0ICovXG5cdHB1YmxpYyB0b2dnbGVDb2x1bW5TZXR0aW5ncygpIHtcblx0XHR0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcblxuXHRcdGlmICh0aGlzLmFjdGl2ZSkge1xuXHRcdFx0dGhpcy5vZmZzZXQgPSB0aGlzLl9nZXRUYWJsZUhlYWRIZWlnaHQoKTtcblxuXHRcdFx0Ly8gY2hlY2sgYW5kIGFkanVzdCBoZWlnaHQgb2Zmc2V0XG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0dGhpcy5oZWlnaHRBZGp1c3QgPSB0aGlzLl9nZXRDb2x1bW5TZXR0aW5nc0hlYWRlckhlaWdodCgpO1xuXHRcdFx0fSwgMCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSBjb2x1bW4gdmlzaWJpbGl0eS5cblx0ICogQHBhcmFtIGNvbHVtbiAtIGNvbHVtbiBvYmplY3QuXG5cdCAqL1xuXHRwdWJsaWMgdG9nZ2xlQ29sdW1uVmlzaWJpbGl0eShjb2x1bW46IGFueSkge1xuXHRcdC8vIHRvZ2dsZSBjb2x1bW4gdmlzaWJpbGl0eVxuXHRcdGNvbHVtbi52aXNpYmxlID1cblx0XHRcdHR5cGVvZiBjb2x1bW4udmlzaWJsZSA9PT0gJ3VuZGVmaW5lZCcgPyBmYWxzZSA6ICFjb2x1bW4udmlzaWJsZTtcblxuXHRcdC8vIHJlZHJhdyB0YWJsZVxuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZS5yZWRyYXcoKTtcblxuXHRcdC8vIGVtaXQgZXZlbnRcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3QtY29sdW1uLXZpc2liaWxpdHktY2hhbmdlJyxcblx0XHRcdHZhbHVlOiB7XG5cdFx0XHRcdGNvbHVtbjogeyAuLi5jb2x1bW4gfSxcblx0XHRcdFx0c2V0dGluZ3M6IFsuLi50aGlzLl9nZW5lcmljVGFibGUuZ3RTZXR0aW5nc11cblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIGNoZWNrIGFuZCByZXNldCBvZmZzZXRcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMub2Zmc2V0ID0gdGhpcy5fZ2V0VGFibGVIZWFkSGVpZ2h0KCk7XG5cdFx0fSwgMCk7XG5cdH1cblxuXHQvKipcblx0ICogT3JkZXIgdGFibGUgYnkgb2JqZWN0IGtleS5cblx0ICogQHBhcmFtIGFyZ3MgLSBuYW1lIG9mIGtleSB0byBzb3J0IG9uLlxuXHQgKi9cblx0cHJpdmF0ZSBfb25Ecm9wKGFyZ3M6IEFycmF5PGFueT4pIHtcblx0XHR0aGlzLnJlb3JkZXJlZCA9IHRydWU7XG5cdFx0Y29uc3QgW2UsIHRhcmdldF0gPSBhcmdzO1xuXHRcdGNvbnN0IG9yZGVyID0ge307XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcblx0XHRcdG9yZGVyW3RhcmdldC5jaGlsZHJlbltpXS5nZXRBdHRyaWJ1dGUoJ2RhdGEtb2JqZWN0LWtleScpXSA9IGk7XG5cdFx0fVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ2VuZXJpY1RhYmxlLmd0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuX2dlbmVyaWNUYWJsZS5ndFNldHRpbmdzW2ldLmNvbHVtbk9yZGVyID1cblx0XHRcdFx0b3JkZXJbdGhpcy5fZ2VuZXJpY1RhYmxlLmd0U2V0dGluZ3NbaV0ub2JqZWN0S2V5XTtcblx0XHR9XG5cblx0XHQvLyByZXNldCBhcnJheSB0byB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb25cblx0XHR0aGlzLl9nZW5lcmljVGFibGUuZ3RTZXR0aW5ncyA9IFsuLi50aGlzLl9nZW5lcmljVGFibGUuZ3RTZXR0aW5nc107XG5cdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblxuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZS5yZWRyYXcoKTtcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3QtY29sdW1uLW9yZGVyLWNoYW5nZScsXG5cdFx0XHR2YWx1ZToge1xuXHRcdFx0XHRzZXR0aW5nczogWy4uLnRoaXMuX2dlbmVyaWNUYWJsZS5ndFNldHRpbmdzXVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBoZWlnaHQgb2YgdGFibGUgaGVhZCBlbGVtZW50IGllLiBmaXJzdCByb3cgY29udGFpbmluZyB0YWJsZSBoZWFkZXJzLlxuXHQgKiBAcmV0dXJucyBvZmZzZXQgaGVpZ2h0IGZvciB0YWJsZSBoZWFkZXIgaW4gcHguXG5cdCAqL1xuXHRwcml2YXRlIF9nZXRUYWJsZUhlYWRIZWlnaHQoKTogc3RyaW5nIHtcblx0XHR0cnkge1xuXHRcdFx0aWYgKFxuXHRcdFx0XHR0aGlzLmVsZW1lbnRWaWV3LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5uZXh0RWxlbWVudFNpYmxpbmdcblx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQudGFnTmFtZSA9PT0gJ1RIRUFEJ1xuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiAoXG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50Vmlldy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nXG5cdFx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQub2Zmc2V0SGVpZ2h0ICsgJ3B4J1xuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKFxuXHRcdFx0XHR0aGlzLmVsZW1lbnRWaWV3LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5uZXh0RWxlbWVudFNpYmxpbmdcblx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQudGFnTmFtZSA9PT1cblx0XHRcdFx0J1RIRUFEJ1xuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiAoXG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50Vmlldy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nXG5cdFx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGRcblx0XHRcdFx0XHRcdC5vZmZzZXRIZWlnaHQgKyAncHgnXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gJzBweCc7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdHJldHVybiAnMHB4Jztcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogR2V0IGhlaWdodCBvZiB0YWJsZSBoZWFkIGVsZW1lbnQgaWUuIGZpcnN0IHJvdyBjb250YWluaW5nIHRhYmxlIGhlYWRlcnMuXG5cdCAqIEByZXR1cm5zIG9mZnNldCBoZWlnaHQgZm9yIHRhYmxlIGhlYWRlciBpbiBweC5cblx0ICovXG5cdHByaXZhdGUgX2dldENvbHVtblNldHRpbmdzSGVhZGVySGVpZ2h0KCk6IHN0cmluZyB7XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiB0aGlzLmd0Q29sdW1uU2V0dGluZ3NIZWFkZXIubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgKyAncHgnO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRyZXR1cm4gJzBweCc7XG5cdFx0fVxuXHR9XG5cblx0LyoqIGdlbmVyYXRlIGEgdW5pcXVlIGlkIGZvciBkcmFndWxhIGluc3RhbmNlIGkuZS4gYSB1bmlxdWUgYmFnIG5hbWUqL1xuXHQvKiB0c2xpbnQ6ZGlzYWJsZSAqL1xuXHRwcml2YXRlIGdlbmVyYXRlSWQoKSB7XG5cdFx0bGV0IGQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblx0XHRyZXR1cm4gJ3h4eHh4eHh4LXh4eHgtNHh4eC15eHh4LXh4eHh4eHh4eHh4eCcucmVwbGFjZSgvW3h5XS9nLCBmdW5jdGlvbihjKSB7XG5cdFx0XHRjb25zdCByID0gKChkICsgTWF0aC5yYW5kb20oKSAqIDE2KSAlIDE2KSB8IDA7XG5cdFx0XHRkID0gTWF0aC5mbG9vcihkIC8gMTYpO1xuXHRcdFx0cmV0dXJuIChjID09PSAneCcgPyByIDogKHIgJiAweDMpIHwgMHg4KS50b1N0cmluZygxNik7XG5cdFx0fSk7XG5cdH1cblx0LyogdHNsaW50OmVuYWJsZSAqL1xufVxuIiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuXHRHdENvbHVtblBpcGUsXG5cdEd0Q29sdW1uU2V0dGluZ3NDb21wb25lbnRcbn0gZnJvbSAnLi9jb21wb25lbnRzL2d0LWNvbHVtbi1zZXR0aW5ncy5jb21wb25lbnQnO1xuaW1wb3J0IHsgR2VuZXJpY1RhYmxlTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlJztcbmltcG9ydCB7IERyYWd1bGFNb2R1bGUgfSBmcm9tICduZzItZHJhZ3VsYSc7XG5cbkBOZ01vZHVsZSh7XG5cdGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEdlbmVyaWNUYWJsZU1vZHVsZSwgRHJhZ3VsYU1vZHVsZV0sXG5cdGRlY2xhcmF0aW9uczogW0d0Q29sdW1uU2V0dGluZ3NDb21wb25lbnQsIEd0Q29sdW1uUGlwZV0sXG5cdGV4cG9ydHM6IFtHdENvbHVtblNldHRpbmdzQ29tcG9uZW50LCBHdENvbHVtblBpcGVdXG59KVxuZXhwb3J0IGNsYXNzIENvbHVtblNldHRpbmdzTW9kdWxlIHt9XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQTRCUyxxQ0FBYzs7Ozs7O2NBQUMsQ0FBTSxFQUFFLENBQU07UUFDcEMsSUFBSSxDQUFDLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUU7WUFDbEMsT0FBTyxDQUFDLENBQUMsQ0FBQztTQUNWO1FBQ0QsSUFBSSxDQUFDLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLENBQUMsV0FBVyxLQUFLLFdBQVcsRUFBRTtZQUMxRSxPQUFPLENBQUMsQ0FBQztTQUNUO1FBQ0QsT0FBTyxDQUFDLENBQUM7Ozs7Ozs7SUFJRixpQ0FBVTs7Ozs7Y0FBQyxNQUF1QjtRQUN6QyxPQUFPLE1BQU0sQ0FBQyxPQUFPLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssSUFBSTtjQUM1RCxNQUFNO2NBQ04sSUFBSSxDQUFDOzs7Ozs7SUFHVCxnQ0FBUzs7OztJQUFULFVBQVUsUUFBZ0M7UUFDekMsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0tBQ2xFOztnQkF6QkQs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