UNPKG

@angular-generic-table/column-settings

Version:

angular-generic-table extension that makes it easy to toggle column visibility and reoder columns.

368 lines (367 loc) 35 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import * as tslib_1 from "tslib"; import { Component, Input, ViewChild, TemplateRef, ElementRef, Pipe, ChangeDetectorRef, HostListener, Output, EventEmitter } from '@angular/core'; import { GenericTableComponent } from '@angular-generic-table/core'; import { DragulaService } from 'ng2-dragula'; 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; }()); export { GtColumnPipe }; function GtColumnPipe_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ GtColumnPipe.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ GtColumnPipe.ctorParameters; } 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: tslib_1.__assign({}, column), settings: tslib_1.__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 = tslib_1.__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 = tslib_1.__spread(this._genericTable.gtSettings); this.changeDetectorRef.markForCheck(); this._genericTable.redraw(); this.gtEvent.emit({ name: 'gt-column-order-change', value: { settings: tslib_1.__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\">&times;</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; }()); export { GtColumnSettingsComponent }; function GtColumnSettingsComponent_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ GtColumnSettingsComponent.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ GtColumnSettingsComponent.ctorParameters; /** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */ GtColumnSettingsComponent.propDecorators; /** @type {?} */ GtColumnSettingsComponent.prototype.elementView; /** @type {?} */ GtColumnSettingsComponent.prototype.gtColumnSettingsHeader; /** @type {?} */ GtColumnSettingsComponent.prototype._genericTable; /** @type {?} */ GtColumnSettingsComponent.prototype.gtHeaderClasses; /** @type {?} */ GtColumnSettingsComponent.prototype.gtWrapperClasses; /** @type {?} */ GtColumnSettingsComponent.prototype.overlay; /** @type {?} */ GtColumnSettingsComponent.prototype.gtColumnItem; /** @type {?} */ GtColumnSettingsComponent.prototype.gtDefaultTexts; /** @type {?} */ GtColumnSettingsComponent.prototype.gtTexts; /** @type {?} */ GtColumnSettingsComponent.prototype.gtEvent; /** @type {?} */ GtColumnSettingsComponent.prototype.active; /** @type {?} */ GtColumnSettingsComponent.prototype.offset; /** @type {?} */ GtColumnSettingsComponent.prototype.heightAdjust; /** @type {?} */ GtColumnSettingsComponent.prototype.reordered; /** @type {?} */ GtColumnSettingsComponent.prototype.bagId; /** * Extend object function. * @type {?} */ GtColumnSettingsComponent.prototype.extend; /** @type {?} */ GtColumnSettingsComponent.prototype.dragulaService; /** @type {?} */ GtColumnSettingsComponent.prototype.changeDetectorRef; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3QtY29sdW1uLXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29sdW1uLXNldHRpbmdzLyIsInNvdXJjZXMiOlsiY29tcG9uZW50cy9ndC1jb2x1bW4tc2V0dGluZ3MuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNOLFNBQVMsRUFDVCxLQUFLLEVBQ0wsU0FBUyxFQUNULFdBQVcsRUFDWCxVQUFVLEVBQ1YsSUFBSSxFQUdKLGlCQUFpQixFQUNqQixZQUFZLEVBQ1osTUFBTSxFQUNOLFlBQVksRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ04scUJBQXFCLEVBR3JCLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQzs7Ozs7Ozs7OztJQVNwQyxxQ0FBYzs7Ozs7O2NBQUMsQ0FBTSxFQUFFLENBQU07UUFDcEMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDVjtRQUNELEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsQ0FBQyxXQUFXLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztZQUMzRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ1Q7UUFDRCxNQUFNLENBQUMsQ0FBQyxDQUFDOzs7Ozs7O0lBSUYsaUNBQVU7Ozs7O2NBQUMsTUFBdUI7UUFDekMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssSUFBSTtZQUM5RCxDQUFDLENBQUMsTUFBTTtZQUNSLENBQUMsQ0FBQyxJQUFJLENBQUM7Ozs7OztJQUdULGdDQUFTOzs7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OzRCQUtMLEtBQUs7NEJBRUwsTUFBTTs2QkFXTixZQUFZLFNBQUMsZUFBZSxFQUFFLEVBQUU7O29DQXBIbEM7O1NBK0VhLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0SW5wdXQsXG5cdFZpZXdDaGlsZCxcblx0VGVtcGxhdGVSZWYsXG5cdEVsZW1lbnRSZWYsXG5cdFBpcGUsXG5cdFBpcGVUcmFuc2Zvcm0sXG5cdE9uSW5pdCxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdEhvc3RMaXN0ZW5lcixcblx0T3V0cHV0LFxuXHRFdmVudEVtaXR0ZXJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuXHRHZW5lcmljVGFibGVDb21wb25lbnQsXG5cdEd0Um93LFxuXHRHdENvbmZpZ1NldHRpbmdcbn0gZnJvbSAnQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlJztcbmltcG9ydCB7IERyYWd1bGFTZXJ2aWNlIH0gZnJvbSAnbmcyLWRyYWd1bGEnO1xuaW1wb3J0IHsgR3RDb2x1bW5TZXR0aW5nc1RleHRzIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1jb2x1bW4tc2V0dGluZ3MtdGV4dHMnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndENvbHVtbidcbn0pXG5leHBvcnQgY2xhc3MgR3RDb2x1bW5QaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdC8vIFRPRE86IG1vdmUgdG8gaGVscGVyIGZ1bmN0aW9uc1xuXHQvKiogU29ydCBieSBjb2x1bW4gb3JkZXIgKi9cblx0cHJpdmF0ZSBnZXRDb2x1bW5PcmRlcihhOiBhbnksIGI6IGFueSkge1xuXHRcdGlmIChhLmNvbHVtbk9yZGVyIDwgYi5jb2x1bW5PcmRlcikge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoYS5jb2x1bW5PcmRlciA+IGIuY29sdW1uT3JkZXIgfHwgdHlwZW9mIGEuY29sdW1uT3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHQvKiogcmV0dXJuIGVuYWJsZWQgY29sdW1ucyB0aGF0IGFyZSBub3QgbG9ja2VkIGZvciBlZGl0aW5nICovXG5cdHByaXZhdGUgZ2V0RW5hYmxlZChjb2x1bW46IEd0Q29uZmlnU2V0dGluZykge1xuXHRcdHJldHVybiBjb2x1bW4uZW5hYmxlZCAhPT0gZmFsc2UgJiYgY29sdW1uLmxvY2tTZXR0aW5ncyAhPT0gdHJ1ZVxuXHRcdFx0PyBjb2x1bW5cblx0XHRcdDogbnVsbDtcblx0fVxuXG5cdHRyYW5zZm9ybShzZXR0aW5nczogQXJyYXk8R3RDb25maWdTZXR0aW5nPik6IEFycmF5PEd0Q29uZmlnU2V0dGluZz4ge1xuXHRcdHJldHVybiBzZXR0aW5ncy5maWx0ZXIodGhpcy5nZXRFbmFibGVkKS5zb3J0KHRoaXMuZ2V0Q29sdW1uT3JkZXIpO1xuXHR9XG59XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2d0LWNvbHVtbi1zZXR0aW5ncycsXG5cdHRlbXBsYXRlOiBgXG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjY29sdW1uSXRlbSBsZXQtY29sdW1uIGxldC1pbmRleD1cImluZGV4XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJhZGdlLXNlY29uZGFyeVwiPnt7aW5kZXh9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIChkYmxjbGljayk9XCJ0b2dnbGVDb2x1bW5WaXNpYmlsaXR5KGNvbHVtbilcIiBjbGFzcz1cImJhZGdlXCIgW25nQ2xhc3NdPVwieydiYWRnZS1zdWNjZXNzJzpjb2x1bW4udmlzaWJsZSAhPT0gZmFsc2UsICdiYWRnZS1kYW5nZXInOmNvbHVtbi52aXNpYmxlID09PSBmYWxzZX1cIj57e2dlbmVyaWNUYWJsZS5ndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZSd9fTwvc3Bhbj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImd0LWNvbHVtbi1zZXR0aW5nc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImd0LWNvbHVtbi1zZXR0aW5ncy1wYW5lbFwiICAqbmdJZj1cImFjdGl2ZVwiIFtzdHlsZS5wYWRkaW5nLXRvcF09XCJvZmZzZXRcIiBbc3R5bGUuaGVpZ2h0XT1cIidjYWxjKDEwMCUgLSAnK29mZnNldCsnKSdcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICNndENvbHVtblNldHRpbmdzSGVhZGVyIGNsYXNzPVwiZ3QtY29sdW1uLXNldHRpbmdzLWhlYWRlciBib3JkZXItYm90dG9tLTBcIiBbbmdDbGFzc109XCJndEhlYWRlckNsYXNzZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiIChjbGljayk9XCJ0b2dnbGVDb2x1bW5TZXR0aW5ncygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj4mdGltZXM7PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPGg2IGNsYXNzPVwiZ3QtY29sdW1uLXNldHRpbmdzLXRpdGxlXCIgKm5nSWY9XCJndFRleHRzLnRpdGxlXCI+e3tndFRleHRzLnRpdGxlfX08L2g2PlxuICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJndC1jb2x1bW4tc2V0dGluZ3MtaGVscCBmb3JtLXRleHQgdGV4dC1tdXRlZFwiICpuZ0lmPVwiZ3RUZXh0cy5oZWxwXCI+e3tndFRleHRzLmhlbHB9fTwvc21hbGw+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImd0LWNvbHVtbi1zZXR0aW5ncy1pdGVtLXdyYXBwZXJcIiBbbmdDbGFzc109XCJndFdyYXBwZXJDbGFzc2VzXCIgW2RyYWd1bGFdPSdiYWdJZCcgIGRhdGEtdmlzaWJsZT1cInRydWVcIiBbc3R5bGUubWF4LWhlaWdodF09XCInY2FsYygxMDAlIC0gJytoZWlnaHRBZGp1c3QrJyknXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJndC1jb2x1bW4tc2V0dGluZ3MtaXRlbSBwci0wIHByLXNtLTRcIiAqbmdGb3I9XCJsZXQgaSA9IGluZGV4O2xldCBjb2x1bW4gb2YgZ2VuZXJpY1RhYmxlLmd0U2V0dGluZ3MgfCBndENvbHVtblwiIFthdHRyLmRhdGEtb2JqZWN0LWtleV09XCJjb2x1bW4ub2JqZWN0S2V5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiZ3RDb2x1bW5JdGVtID8gZ3RDb2x1bW5JdGVtOmNvbHVtbkl0ZW1cIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogY29sdW1uLGluZGV4OiB0aGlzLnJlb3JkZXJlZCA/IGNvbHVtbi5jb2x1bW5PcmRlcisxOmkrMSwgbmFtZTogKGdlbmVyaWNUYWJsZS5ndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZScpfVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJndC1vdmVybGF5XCIgKm5nSWY9XCJhY3RpdmUgJiYgb3ZlcmxheVwiIChjbGljayk9XCJ0b2dnbGVDb2x1bW5TZXR0aW5ncygpXCIgW3N0eWxlLmhlaWdodF09XCInY2FsYygxMDAlIC0gLScrb2Zmc2V0KycpJ1wiPjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2dlbmVyaWNUYWJsZUVsZW1lbnQgW25nSWZdPVwiZ2VuZXJpY1RhYmxlXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgYFxufSlcbmV4cG9ydCBjbGFzcyBHdENvbHVtblNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblx0Z2V0IGdlbmVyaWNUYWJsZSgpOiBHZW5lcmljVGFibGVDb21wb25lbnQ8YW55LCBhbnk+IHtcblx0XHRyZXR1cm4gdGhpcy5fZ2VuZXJpY1RhYmxlO1xuXHR9XG5cblx0QElucHV0KClcblx0c2V0IGdlbmVyaWNUYWJsZSh2YWx1ZTogR2VuZXJpY1RhYmxlQ29tcG9uZW50PGFueSwgYW55Pikge1xuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZSA9IHZhbHVlO1xuXHR9XG5cblx0QFZpZXdDaGlsZCgnZ2VuZXJpY1RhYmxlRWxlbWVudCcpIGVsZW1lbnRWaWV3OiBUZW1wbGF0ZVJlZjxFbGVtZW50UmVmPjtcblx0QFZpZXdDaGlsZCgnZ3RDb2x1bW5TZXR0aW5nc0hlYWRlcicpIGd0Q29sdW1uU2V0dGluZ3NIZWFkZXI6IEVsZW1lbnRSZWY7XG5cblx0cHJpdmF0ZSBfZ2VuZXJpY1RhYmxlOiBHZW5lcmljVGFibGVDb21wb25lbnQ8R3RSb3csIGFueT47XG5cdEBJbnB1dCgpXG5cdGd0SGVhZGVyQ2xhc3NlcyA9ICdweC0zIHB0LTMgcGItMiB0YWJsZS1ib3JkZXJlZCBib3JkZXItbGVmdC0wIGJvcmRlci1yaWdodC0wIGJvcmRlci1ib3R0b20tMCBhbGVydC1pbmZvJztcblx0QElucHV0KClcblx0Z3RXcmFwcGVyQ2xhc3NlcyA9ICdweC0zIHBiLTMgdGFibGUtYm9yZGVyZWQgYm9yZGVyLWxlZnQtMCBib3JkZXItcmlnaHQtMCBib3JkZXItdG9wLTAgYWxlcnQtaW5mbyc7XG5cdEBJbnB1dCgpIG92ZXJsYXkgPSB0cnVlO1xuXHRASW5wdXQoKSBndENvbHVtbkl0ZW06IFRlbXBsYXRlUmVmPEVsZW1lbnRSZWY+O1xuXHRwdWJsaWMgZ3REZWZhdWx0VGV4dHM6IEd0Q29sdW1uU2V0dGluZ3NUZXh0cyA9IHtcblx0XHR0aXRsZTogJ0NvbHVtbnMnLFxuXHRcdGhlbHA6ICdEb3VibGUgY2xpY2sgdG8gdG9nZ2xlIHZpc2liaWxpdHksIGRyYWcgYW5kIGRyb3AgdG8gcmVvcmRlci4nXG5cdH07XG5cdEBJbnB1dCgpIGd0VGV4dHM6IEd0Q29sdW1uU2V0dGluZ3NUZXh0cyA9IHRoaXMuZ3REZWZhdWx0VGV4dHM7XG5cblx0QE91dHB1dCgpIHB1YmxpYyBndEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG5cdHB1YmxpYyBhY3RpdmUgPSBmYWxzZTtcblx0cHVibGljIG9mZnNldDogc3RyaW5nO1xuXHRwdWJsaWMgaGVpZ2h0QWRqdXN0OiBzdHJpbmc7XG5cdHB1YmxpYyByZW9yZGVyZWQgPSBmYWxzZTtcblx0cHVibGljIGJhZ0lkOiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIENoZWNrIG9mZnNldCBoZWlnaHQgb24gd2luZG93IHJlc2l6ZS5cblx0ICovXG5cdEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbXSlcblx0cHVibGljIG9uUmVzaXplKCkge1xuXHRcdHRoaXMub2Zmc2V0ID0gdGhpcy5fZ2V0VGFibGVIZWFkSGVpZ2h0KCk7XG5cdFx0dGhpcy5oZWlnaHRBZGp1c3QgPSB0aGlzLl9nZXRDb2x1bW5TZXR0aW5nc0hlYWRlckhlaWdodCgpO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSBkcmFndWxhU2VydmljZTogRHJhZ3VsYVNlcnZpY2UsXG5cdFx0cHJpdmF0ZSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWZcblx0KSB7XG5cdFx0ZHJhZ3VsYVNlcnZpY2UuZHJvcC5zdWJzY3JpYmUoKHZhbHVlOiBBcnJheTxhbnk+KSA9PiB7XG5cdFx0XHRpZiAodmFsdWVbMF0gPT09IHRoaXMuYmFnSWQpIHtcblx0XHRcdFx0dGhpcy5fb25Ecm9wKHZhbHVlLnNsaWNlKDEpKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdG5nT25Jbml0KCkge1xuXHRcdHRoaXMuYmFnSWQgPSB0aGlzLmdlbmVyYXRlSWQoKTtcblx0XHQvLyBzZXR1cCB0ZXh0c1xuXHRcdHRoaXMuZ3RUZXh0cyA9IDxHdENvbHVtblNldHRpbmdzVGV4dHM+dGhpcy5leHRlbmQoXG5cdFx0XHR0aGlzLmd0RGVmYXVsdFRleHRzLFxuXHRcdFx0dGhpcy5ndFRleHRzXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiAgRXh0ZW5kIG9iamVjdCBmdW5jdGlvbi5cblx0ICovXG5cdHByaXZhdGUgZXh0ZW5kID0gZnVuY3Rpb24oYTogT2JqZWN0LCBiOiBPYmplY3QpIHtcblx0XHRmb3IgKGNvbnN0IGtleSBpbiBiKSB7XG5cdFx0XHRpZiAoYi5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHRcdGFba2V5XSA9IGJba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGE7XG5cdH07XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSBjb2x1bW4gc2V0dGluZ3MgdmlzaWJpbGl0eS5cblx0ICovXG5cdHB1YmxpYyB0b2dnbGVDb2x1bW5TZXR0aW5ncygpIHtcblx0XHR0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcblxuXHRcdGlmICh0aGlzLmFjdGl2ZSkge1xuXHRcdFx0dGhpcy5vZmZzZXQgPSB0aGlzLl9nZXRUYWJsZUhlYWRIZWlnaHQoKTtcblxuXHRcdFx0Ly8gY2hlY2sgYW5kIGFkanVzdCBoZWlnaHQgb2Zmc2V0XG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0dGhpcy5oZWlnaHRBZGp1c3QgPSB0aGlzLl9nZXRDb2x1bW5TZXR0aW5nc0hlYWRlckhlaWdodCgpO1xuXHRcdFx0fSwgMCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSBjb2x1bW4gdmlzaWJpbGl0eS5cblx0ICogQHBhcmFtIGNvbHVtbiAtIGNvbHVtbiBvYmplY3QuXG5cdCAqL1xuXHRwdWJsaWMgdG9nZ2xlQ29sdW1uVmlzaWJpbGl0eShjb2x1bW46IGFueSkge1xuXHRcdC8vIHRvZ2dsZSBjb2x1bW4gdmlzaWJpbGl0eVxuXHRcdGNvbHVtbi52aXNpYmxlID1cblx0XHRcdHR5cGVvZiBjb2x1bW4udmlzaWJsZSA9PT0gJ3VuZGVmaW5lZCcgPyBmYWxzZSA6ICFjb2x1bW4udmlzaWJsZTtcblxuXHRcdC8vIHJlZHJhdyB0YWJsZVxuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZS5yZWRyYXcoKTtcblxuXHRcdC8vIGVtaXQgZXZlbnRcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3QtY29sdW1uLXZpc2liaWxpdHktY2hhbmdlJyxcblx0XHRcdHZhbHVlOiB7XG5cdFx0XHRcdGNvbHVtbjogeyAuLi5jb2x1bW4gfSxcblx0XHRcdFx0c2V0dGluZ3M6IFsuLi50aGlzLl9nZW5lcmljVGFibGUuZ3RTZXR0aW5nc11cblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIGNoZWNrIGFuZCByZXNldCBvZmZzZXRcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMub2Zmc2V0ID0gdGhpcy5fZ2V0VGFibGVIZWFkSGVpZ2h0KCk7XG5cdFx0fSwgMCk7XG5cdH1cblxuXHQvKipcblx0ICogT3JkZXIgdGFibGUgYnkgb2JqZWN0IGtleS5cblx0ICogQHBhcmFtIGFyZ3MgLSBuYW1lIG9mIGtleSB0byBzb3J0IG9uLlxuXHQgKi9cblx0cHJpdmF0ZSBfb25Ecm9wKGFyZ3M6IEFycmF5PGFueT4pIHtcblx0XHR0aGlzLnJlb3JkZXJlZCA9IHRydWU7XG5cdFx0Y29uc3QgW2UsIHRhcmdldF0gPSBhcmdzO1xuXHRcdGNvbnN0IG9yZGVyID0ge307XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcblx0XHRcdG9yZGVyW3RhcmdldC5jaGlsZHJlbltpXS5nZXRBdHRyaWJ1dGUoJ2RhdGEtb2JqZWN0LWtleScpXSA9IGk7XG5cdFx0fVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ2VuZXJpY1RhYmxlLmd0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuX2dlbmVyaWNUYWJsZS5ndFNldHRpbmdzW2ldLmNvbHVtbk9yZGVyID1cblx0XHRcdFx0b3JkZXJbdGhpcy5fZ2VuZXJpY1RhYmxlLmd0U2V0dGluZ3NbaV0ub2JqZWN0S2V5XTtcblx0XHR9XG5cblx0XHQvLyByZXNldCBhcnJheSB0byB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb25cblx0XHR0aGlzLl9nZW5lcmljVGFibGUuZ3RTZXR0aW5ncyA9IFsuLi50aGlzLl9nZW5lcmljVGFibGUuZ3RTZXR0aW5nc107XG5cdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblxuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZS5yZWRyYXcoKTtcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3QtY29sdW1uLW9yZGVyLWNoYW5nZScsXG5cdFx0XHR2YWx1ZToge1xuXHRcdFx0XHRzZXR0aW5nczogWy4uLnRoaXMuX2dlbmVyaWNUYWJsZS5ndFNldHRpbmdzXVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBoZWlnaHQgb2YgdGFibGUgaGVhZCBlbGVtZW50IGllLiBmaXJzdCByb3cgY29udGFpbmluZyB0YWJsZSBoZWFkZXJzLlxuXHQgKiBAcmV0dXJucyBvZmZzZXQgaGVpZ2h0IGZvciB0YWJsZSBoZWFkZXIgaW4gcHguXG5cdCAqL1xuXHRwcml2YXRlIF9nZXRUYWJsZUhlYWRIZWlnaHQoKTogc3RyaW5nIHtcblx0XHR0cnkge1xuXHRcdFx0aWYgKFxuXHRcdFx0XHR0aGlzLmVsZW1lbnRWaWV3LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5uZXh0RWxlbWVudFNpYmxpbmdcblx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQudGFnTmFtZSA9PT0gJ1RIRUFEJ1xuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiAoXG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50Vmlldy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nXG5cdFx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQub2Zmc2V0SGVpZ2h0ICsgJ3B4J1xuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKFxuXHRcdFx0XHR0aGlzLmVsZW1lbnRWaWV3LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5uZXh0RWxlbWVudFNpYmxpbmdcblx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQudGFnTmFtZSA9PT1cblx0XHRcdFx0J1RIRUFEJ1xuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiAoXG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50Vmlldy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nXG5cdFx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGRcblx0XHRcdFx0XHRcdC5vZmZzZXRIZWlnaHQgKyAncHgnXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gJzBweCc7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdHJldHVybiAnMHB4Jztcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogR2V0IGhlaWdodCBvZiB0YWJsZSBoZWFkIGVsZW1lbnQgaWUuIGZpcnN0IHJvdyBjb250YWluaW5nIHRhYmxlIGhlYWRlcnMuXG5cdCAqIEByZXR1cm5zIG9mZnNldCBoZWlnaHQgZm9yIHRhYmxlIGhlYWRlciBpbiBweC5cblx0ICovXG5cdHByaXZhdGUgX2dldENvbHVtblNldHRpbmdzSGVhZGVySGVpZ2h0KCk6IHN0cmluZyB7XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiB0aGlzLmd0Q29sdW1uU2V0dGluZ3NIZWFkZXIubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgKyAncHgnO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRyZXR1cm4gJzBweCc7XG5cdFx0fVxuXHR9XG5cblx0LyoqIGdlbmVyYXRlIGEgdW5pcXVlIGlkIGZvciBkcmFndWxhIGluc3RhbmNlIGkuZS4gYSB1bmlxdWUgYmFnIG5hbWUqL1xuXHQvKiB0c2xpbnQ6ZGlzYWJsZSAqL1xuXHRwcml2YXRlIGdlbmVyYXRlSWQoKSB7XG5cdFx0bGV0IGQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblx0XHRyZXR1cm4gJ3h4eHh4eHh4LXh4eHgtNHh4eC15eHh4LXh4eHh4eHh4eHh4eCcucmVwbGFjZSgvW3h5XS9nLCBmdW5jdGlvbihjKSB7XG5cdFx0XHRjb25zdCByID0gKChkICsgTWF0aC5yYW5kb20oKSAqIDE2KSAlIDE2KSB8IDA7XG5cdFx0XHRkID0gTWF0aC5mbG9vcihkIC8gMTYpO1xuXHRcdFx0cmV0dXJuIChjID09PSAneCcgPyByIDogKHIgJiAweDMpIHwgMHg4KS50b1N0cmluZygxNik7XG5cdFx0fSk7XG5cdH1cblx0LyogdHNsaW50OmVuYWJsZSAqL1xufVxuIl19