ngx-easy-table
Version:
Angular easy table
928 lines • 92.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { moveItemInArray } from '@angular/cdk/drag-drop';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, EventEmitter, HostListener, Input, Output, TemplateRef, ViewChild, } from '@angular/core';
import { API, Event } from '../..';
import { DefaultConfigService } from '../../services/config-service';
import { PaginationComponent } from '../pagination/pagination.component';
import { GroupRowsService } from '../../services/group-rows.service';
import { StyleService } from '../../services/style.service';
import { Subject } from 'rxjs';
import { CdkVirtualScrollViewport, ScrollDispatcher } from '@angular/cdk/scrolling';
import { filter, takeUntil, throttleTime } from 'rxjs/operators';
/**
* @record
*/
function RowContextMenuPosition() { }
if (false) {
/** @type {?} */
RowContextMenuPosition.prototype.top;
/** @type {?} */
RowContextMenuPosition.prototype.left;
/** @type {?} */
RowContextMenuPosition.prototype.value;
}
var BaseComponent = /** @class */ (function () {
function BaseComponent(cdr, scrollDispatcher, styleService) {
var _this = this;
this.cdr = cdr;
this.scrollDispatcher = scrollDispatcher;
this.styleService = styleService;
this.unsubscribe = new Subject();
this.filterCount = -1;
this.filteredCountSubject = new Subject();
this.tableClass = null;
this.grouped = [];
this.isSelected = false;
this.page = 1;
this.count = 0;
this.sortState = new Map();
this.sortKey = null;
this.rowContextMenuPosition = {
top: null,
left: null,
value: null,
};
this.sortBy = {
key: '',
order: 'asc',
};
this.selectedDetailsTemplateRowId = new Set();
this.selectedCheckboxes = new Set();
this.loadingHeight = '30px';
this.id = 'table';
this.event = new EventEmitter();
this.subscription = this.filteredCountSubject
.pipe(takeUntil(this.unsubscribe))
.subscribe((/**
* @param {?} count
* @return {?}
*/
function (count) {
_this.filterCount = count;
_this.cdr.detectChanges();
}));
}
/**
* @param {?} targetElement
* @return {?}
*/
BaseComponent.prototype.onContextMenuClick = /**
* @param {?} targetElement
* @return {?}
*/
function (targetElement) {
if (this.contextMenu && !this.contextMenu.nativeElement.contains(targetElement)) {
this.rowContextMenuPosition = {
top: null,
left: null,
value: null,
};
}
};
/**
* @return {?}
*/
BaseComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
if (!this.columns) {
console.error('[columns] property required!');
}
if (this.configuration) {
this.config = this.configuration;
}
else {
this.config = DefaultConfigService.config;
}
this.limit = this.config.rows;
if (this.groupRowsBy) {
this.grouped = GroupRowsService.doGroupRows(this.data, this.groupRowsBy);
}
this.doDecodePersistedState();
};
/**
* @return {?}
*/
BaseComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.unsubscribe.next();
this.unsubscribe.complete();
};
/**
* @return {?}
*/
BaseComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var throttleValue = this.config.infiniteScrollThrottleTime ?
this.config.infiniteScrollThrottleTime :
200;
this.scrollDispatcher.scrolled()
.pipe(takeUntil(this.unsubscribe), throttleTime(throttleValue), filter((/**
* @param {?} event
* @return {?}
*/
function (event) {
return !!event && _this.viewPort && _this.viewPort.getRenderedRange().end === _this.viewPort.getDataLength();
})))
.subscribe((/**
* @return {?}
*/
function () {
_this.emitEvent(Event.onInfiniteScrollEnd, null);
}));
};
/**
* @param {?} changes
* @return {?}
*/
BaseComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
var configuration = changes.configuration, data = changes.data, pagination = changes.pagination, groupRowsBy = changes.groupRowsBy;
this.toggleRowIndex = changes.toggleRowIndex;
if (configuration && configuration.currentValue) {
this.config = configuration.currentValue;
}
if (data && data.currentValue) {
this.doApplyData(data);
}
if (pagination && pagination.currentValue) {
var _a = (/** @type {?} */ (pagination.currentValue)), count = _a.count, limit = _a.limit, offset = _a.offset;
this.count = count;
this.limit = limit;
this.page = offset;
}
if (groupRowsBy && groupRowsBy.currentValue) {
this.grouped = GroupRowsService.doGroupRows(this.data, this.groupRowsBy);
}
if (this.toggleRowIndex && this.toggleRowIndex.currentValue) {
/** @type {?} */
var row = this.toggleRowIndex.currentValue;
this.collapseRow(row.index);
}
};
/**
* @param {?} column
* @return {?}
*/
BaseComponent.prototype.orderBy = /**
* @param {?} column
* @return {?}
*/
function (column) {
if (typeof column.orderEnabled !== 'undefined' && !column.orderEnabled) {
return;
}
this.sortKey = column.key;
if (!this.config.orderEnabled || this.sortKey === '') {
return;
}
this.setColumnOrder(this.sortKey);
if (!this.config.orderEventOnly && !column.orderEventOnly) {
this.sortBy.key = this.sortKey;
this.sortBy.order = this.sortState.get(this.sortKey);
}
else {
this.sortBy.key = '';
this.sortBy.order = '';
}
if (!this.config.serverPagination) {
this.data = tslib_1.__spread(this.data);
this.sortBy = tslib_1.__assign({}, this.sortBy);
}
/** @type {?} */
var value = {
key: this.sortKey,
order: this.sortState.get(this.sortKey),
};
this.emitEvent(Event.onOrder, value);
};
/**
* @param {?} $event
* @param {?} row
* @param {?} key
* @param {?} colIndex
* @param {?} rowIndex
* @return {?}
*/
BaseComponent.prototype.onClick = /**
* @param {?} $event
* @param {?} row
* @param {?} key
* @param {?} colIndex
* @param {?} rowIndex
* @return {?}
*/
function ($event, row, key, colIndex, rowIndex) {
if (this.config.selectRow) {
this.selectedRow = rowIndex;
}
if (this.config.selectCol && colIndex) {
this.selectedCol = colIndex;
}
if (this.config.selectCell && colIndex) {
this.selectedRow = rowIndex;
this.selectedCol = colIndex;
}
if (this.config.clickEvent) {
/** @type {?} */
var value = {
event: $event,
row: row,
key: key,
rowId: rowIndex,
colId: colIndex,
};
this.emitEvent(Event.onClick, value);
}
};
/**
* @param {?} $event
* @param {?} row
* @param {?} key
* @param {?} colIndex
* @param {?} rowIndex
* @return {?}
*/
BaseComponent.prototype.onDoubleClick = /**
* @param {?} $event
* @param {?} row
* @param {?} key
* @param {?} colIndex
* @param {?} rowIndex
* @return {?}
*/
function ($event, row, key, colIndex, rowIndex) {
/** @type {?} */
var value = {
event: $event,
row: row,
key: key,
rowId: rowIndex,
colId: colIndex,
};
this.emitEvent(Event.onDoubleClick, value);
};
/**
* @param {?} $event
* @param {?} row
* @param {?} rowIndex
* @return {?}
*/
BaseComponent.prototype.onCheckboxSelect = /**
* @param {?} $event
* @param {?} row
* @param {?} rowIndex
* @return {?}
*/
function ($event, row, rowIndex) {
/** @type {?} */
var value = {
event: $event,
row: row,
rowId: rowIndex,
};
this.emitEvent(Event.onCheckboxSelect, value);
};
/**
* @param {?} $event
* @param {?} row
* @param {?} rowIndex
* @return {?}
*/
BaseComponent.prototype.onRadioSelect = /**
* @param {?} $event
* @param {?} row
* @param {?} rowIndex
* @return {?}
*/
function ($event, row, rowIndex) {
/** @type {?} */
var value = {
event: $event,
row: row,
rowId: rowIndex,
};
this.emitEvent(Event.onRadioSelect, value);
};
/**
* @return {?}
*/
BaseComponent.prototype.onSelectAll = /**
* @return {?}
*/
function () {
this.isSelected = !this.isSelected;
this.emitEvent(Event.onSelectAll, this.isSelected);
};
/**
* @param {?} $event
* @return {?}
*/
BaseComponent.prototype.onSearch = /**
* @param {?} $event
* @return {?}
*/
function ($event) {
if (!this.config.serverPagination) {
this.term = $event;
}
this.emitEvent(Event.onSearch, $event);
};
/**
* @param {?} value
* @return {?}
*/
BaseComponent.prototype.onGlobalSearch = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (!this.config.serverPagination) {
this.globalSearchTerm = value;
}
this.emitEvent(Event.onGlobalSearch, value);
};
/**
* @param {?} pagination
* @return {?}
*/
BaseComponent.prototype.onPagination = /**
* @param {?} pagination
* @return {?}
*/
function (pagination) {
this.page = pagination.page;
this.limit = pagination.limit;
this.emitEvent(Event.onPagination, pagination);
};
/**
* @param {?} rowIndex
* @return {?}
*/
BaseComponent.prototype.toggleCheckbox = /**
* @param {?} rowIndex
* @return {?}
*/
function (rowIndex) {
this.selectedCheckboxes.has(rowIndex) ?
this.selectedCheckboxes.delete(rowIndex) :
this.selectedCheckboxes.add(rowIndex);
};
/**
* @param {?} rowIndex
* @return {?}
*/
BaseComponent.prototype.collapseRow = /**
* @param {?} rowIndex
* @return {?}
*/
function (rowIndex) {
if (this.selectedDetailsTemplateRowId.has(rowIndex)) {
this.selectedDetailsTemplateRowId.delete(rowIndex);
this.emitEvent(Event.onRowCollapsedHide, rowIndex);
}
else {
this.selectedDetailsTemplateRowId.add(rowIndex);
this.emitEvent(Event.onRowCollapsedShow, rowIndex);
}
};
/**
* @private
* @return {?}
*/
BaseComponent.prototype.doDecodePersistedState = /**
* @private
* @return {?}
*/
function () {
if (!this.config.persistState) {
return;
}
/** @type {?} */
var pagination = localStorage.getItem(Event.onPagination);
/** @type {?} */
var sort = localStorage.getItem(Event.onOrder);
/** @type {?} */
var search = localStorage.getItem(Event.onSearch);
if (pagination) {
this.onPagination(JSON.parse(pagination));
}
if (sort) {
var _a = JSON.parse(sort), key = _a.key, order = _a.order;
this.bindApi({
type: API.sortBy,
value: { column: key, order: order },
});
}
if (search) {
this.bindApi({
type: API.setInputValue,
value: JSON.parse(search),
});
}
};
/**
* @param {?} rowIndex
* @return {?}
*/
BaseComponent.prototype.isRowCollapsed = /**
* @param {?} rowIndex
* @return {?}
*/
function (rowIndex) {
if (this.config.collapseAllRows) {
return true;
}
return this.selectedDetailsTemplateRowId.has(rowIndex);
};
Object.defineProperty(BaseComponent.prototype, "isLoading", {
get: /**
* @return {?}
*/
function () {
/** @type {?} */
var table = (/** @type {?} */ (document.getElementById(this.id)));
if (table && table.rows && table.rows.length > 3) {
this.getLoadingHeight(table.rows);
}
return this.config.isLoading;
},
enumerable: true,
configurable: true
});
/**
* @param {?} rows
* @return {?}
*/
BaseComponent.prototype.getLoadingHeight = /**
* @param {?} rows
* @return {?}
*/
function (rows) {
/** @type {?} */
var searchEnabled = this.config.searchEnabled ? 1 : 0;
/** @type {?} */
var headerEnabled = this.config.headerEnabled ? 1 : 0;
/** @type {?} */
var borderTrHeight = 1;
/** @type {?} */
var borderDivHeight = 2;
this.loadingHeight = (rows.length - searchEnabled - headerEnabled) * (rows[3].offsetHeight - borderTrHeight) - borderDivHeight + 'px';
};
Object.defineProperty(BaseComponent.prototype, "arrowDefinition", {
get: /**
* @return {?}
*/
function () {
return this.config.showDetailsArrow || typeof this.config.showDetailsArrow === 'undefined';
},
enumerable: true,
configurable: true
});
/**
* @param {?} $event
* @param {?} row
* @param {?} key
* @param {?} colIndex
* @param {?} rowIndex
* @return {?}
*/
BaseComponent.prototype.onRowContextMenu = /**
* @param {?} $event
* @param {?} row
* @param {?} key
* @param {?} colIndex
* @param {?} rowIndex
* @return {?}
*/
function ($event, row, key, colIndex, rowIndex) {
if (!this.config.showContextMenu) {
return;
}
$event.preventDefault();
/** @type {?} */
var value = {
event: $event,
row: row,
key: key,
rowId: rowIndex,
colId: colIndex,
};
this.rowContextMenuPosition = {
top: $event.y - 10 + "px",
left: $event.x - 10 + "px",
value: value,
};
this.emitEvent(Event.onRowContextMenu, value);
};
/**
* @private
* @param {?} data
* @return {?}
*/
BaseComponent.prototype.doApplyData = /**
* @private
* @param {?} data
* @return {?}
*/
function (data) {
/** @type {?} */
var order = this.columns.find((/**
* @param {?} c
* @return {?}
*/
function (c) { return !!c.orderBy; }));
if (order) {
this.sortState.set(this.sortKey, (order.orderBy === 'asc') ? 'desc' : 'asc');
this.orderBy(order);
}
else {
this.data = tslib_1.__spread(data.currentValue);
}
};
/**
* @param {?} event
* @return {?}
*/
BaseComponent.prototype.onDrop = /**
* @param {?} event
* @return {?}
*/
function (event) {
this.emitEvent(Event.onRowDrop, event);
moveItemInArray(this.data, event.previousIndex, event.currentIndex);
};
// DO NOT REMOVE. It is called from parent component. See src/app/demo/api-doc/api-doc.component.ts
// DO NOT REMOVE. It is called from parent component. See src/app/demo/api-doc/api-doc.component.ts
/**
* @param {?} event
* @return {?}
*/
BaseComponent.prototype.apiEvent =
// DO NOT REMOVE. It is called from parent component. See src/app/demo/api-doc/api-doc.component.ts
/**
* @param {?} event
* @return {?}
*/
function (event) {
return this.bindApi(event);
};
// tslint:disable:no-big-function cognitive-complexity
// tslint:disable:no-big-function cognitive-complexity
/**
* @private
* @param {?} event
* @return {?}
*/
BaseComponent.prototype.bindApi =
// tslint:disable:no-big-function cognitive-complexity
/**
* @private
* @param {?} event
* @return {?}
*/
function (event) {
var _this = this;
switch (event.type) {
case API.rowContextMenuClicked:
this.rowContextMenuPosition = {
top: null,
left: null,
value: null,
};
break;
case API.toolPanelClicked:
// TODO
break;
case API.toggleRowIndex:
this.collapseRow(event.value);
break;
case API.toggleCheckbox:
this.toggleCheckbox(event.value);
break;
case API.setInputValue:
if (this.config.searchEnabled) {
event.value.forEach((/**
* @param {?} input
* @return {?}
*/
function (input) {
/** @type {?} */
var element = ((/** @type {?} */ (document.getElementById("search_" + input.key))));
if (!element) {
console.error("Column '" + input.key + "' not available in the DOM. Have you misspelled a name?");
}
else {
element.value = input.value;
}
}));
}
this.onSearch(event.value);
this.cdr.detectChanges();
break;
case API.onGlobalSearch:
this.onGlobalSearch(event.value);
this.cdr.detectChanges();
break;
case API.setRowClass:
if (Array.isArray(event.value)) {
event.value.forEach((/**
* @param {?} val
* @return {?}
*/
function (val) { return _this.styleService.setRowClass(val); }));
break;
}
this.styleService.setRowClass(event.value);
this.cdr.detectChanges();
break;
case API.setCellClass:
if (Array.isArray(event.value)) {
event.value.forEach((/**
* @param {?} val
* @return {?}
*/
function (val) { return _this.styleService.setCellClass(val); }));
break;
}
this.styleService.setCellClass(event.value);
break;
case API.setRowStyle:
if (Array.isArray(event.value)) {
event.value.forEach((/**
* @param {?} val
* @return {?}
*/
function (val) { return _this.styleService.setRowStyle(val); }));
break;
}
this.styleService.setRowStyle(event.value);
break;
case API.setCellStyle:
if (Array.isArray(event.value)) {
event.value.forEach((/**
* @param {?} val
* @return {?}
*/
function (val) { return _this.styleService.setCellStyle(val); }));
break;
}
this.styleService.setCellStyle(event.value);
break;
case API.setTableClass:
this.tableClass = event.value;
this.cdr.detectChanges();
break;
case API.getPaginationTotalItems:
return this.paginationComponent.paginationDirective.getTotalItems();
case API.getPaginationCurrentPage:
return this.paginationComponent.paginationDirective.getCurrent();
case API.getPaginationLastPage:
return this.paginationComponent.paginationDirective.getLastPage();
case API.getNumberOfRowsPerPage:
return this.paginationComponent.paginationDirective.isLastPage() ?
(this.paginationComponent.paginationDirective.getTotalItems() % this.limit) :
this.limit;
case API.setPaginationCurrentPage:
this.paginationComponent.paginationDirective.setCurrent(event.value);
break;
case API.setPaginationRange:
this.paginationComponent.ranges = event.value;
break;
case API.setPaginationPreviousLabel:
this.paginationComponent.previousLabel = event.value;
break;
case API.setPaginationNextLabel:
this.paginationComponent.nextLabel = event.value;
break;
case API.setPaginationDisplayLimit:
this.paginationComponent.changeLimit(event.value, true);
break;
case API.sortBy:
/** @type {?} */
var column = { title: '', key: event.value.column, orderBy: event.value.order };
this.orderBy(column);
this.cdr.detectChanges();
break;
default:
break;
}
};
/**
* @private
* @param {?} key
* @return {?}
*/
BaseComponent.prototype.setColumnOrder = /**
* @private
* @param {?} key
* @return {?}
*/
function (key) {
switch (this.sortState.get(key)) {
case '':
case undefined:
this.sortState.set(key, 'desc');
break;
case 'asc':
this.config.threeWaySort ?
this.sortState.set(key, '') :
this.sortState.set(key, 'desc');
break;
case 'desc':
this.sortState.set(key, 'asc');
break;
}
if (this.sortState.size > 1) {
/** @type {?} */
var temp = this.sortState.get(key);
this.sortState.clear();
this.sortState.set(key, temp);
}
};
/**
* @param {?} event
* @param {?} value
* @return {?}
*/
BaseComponent.prototype.emitEvent = /**
* @param {?} event
* @param {?} value
* @return {?}
*/
function (event, value) {
this.event.emit({ event: event, value: value });
if (this.config.persistState) {
localStorage.setItem(event, JSON.stringify(value));
}
if (this.config.logger) {
// tslint:disable-next-line:no-console
console.log({ event: event, value: value });
}
};
BaseComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-table',
providers: [
DefaultConfigService,
GroupRowsService,
StyleService,
],
template: "<div class=\"ngx-container\">\n <table [id]=\"id\"\n [ngClass]=\"(tableClass === null || tableClass === '') ? 'ngx-table' : tableClass\"\n [class.ngx-table__table--tiny]=\"config.tableLayout.style === 'tiny'\"\n [class.ngx-table__table--normal]=\"config.tableLayout.style === 'normal'\"\n [class.ngx-table__table--big]=\"config.tableLayout.style === 'big'\"\n [class.ngx-table__table--borderless]=\"config.tableLayout.borderless\"\n [class.ngx-table__table--dark]=\"config.tableLayout.theme === 'dark'\"\n [class.ngx-table__table--hoverable]=\"config.tableLayout.hover\"\n [class.ngx-table__table--striped]=\"config.tableLayout.striped\"\n [class.ngx-table__horizontal-scroll]=\"config.horizontalScroll && !isLoading\">\n <thead\n [class.ngx-infinite-scroll-viewport-thead]=\"config.infiniteScroll\"\n table-thead\n [config]=\"config\"\n [sortKey]=\"sortKey\"\n [sortState]=\"sortState\"\n [selectAllTemplate]=\"selectAllTemplate\"\n [filtersTemplate]=\"filtersTemplate\"\n [additionalActionsTemplate]=\"additionalActionsTemplate\"\n [columns]=\"columns\"\n (selectAll)=\"onSelectAll()\"\n (filter)=\"onSearch($event)\"\n (order)=\"orderBy($event)\"\n (event)=\"emitEvent($event.event, $event.value)\"\n >\n </thead>\n <tbody *ngIf=\"data && !isLoading && !config.rowReorder\">\n <ng-container *ngIf=\"rowTemplate\">\n <ul class=\"ngx-table__table-row-context-menu\"\n [ngStyle]=\"{'position': 'absolute', 'top': rowContextMenuPosition.top, 'left': rowContextMenuPosition.left }\"\n *ngIf=\"rowContextMenuPosition.top\">\n <ng-container\n [ngTemplateOutlet]=\"rowContextMenu\"\n [ngTemplateOutletContext]=\"{ $implicit: rowContextMenuPosition.value}\">\n </ng-container>\n </ul>\n <ng-container *ngIf=\"!config.infiniteScroll\">\n <ng-container *ngFor=\"let row of data | sort:sortBy | search:term:filteredCountSubject | global:globalSearchTerm:filteredCountSubject | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id };\n let rowIndex = index\">\n <tr\n (click)=\"onClick($event, row, '', null, rowIndex)\"\n #contextMenu\n (contextmenu)=\"onRowContextMenu($event, row, '', null, rowIndex)\"\n (dblclick)=\"onDoubleClick($event, row, '', null, rowIndex)\"\n [class.ngx-table__table-row--selected]=\"rowIndex === selectedRow && !config.selectCell\">\n <ng-container\n [ngTemplateOutlet]=\"rowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\">\n </ng-container>\n <td *ngIf=\"config.detailsTemplate\">\n <span class=\"ngx-icon\"\n *ngIf=\"arrowDefinition\"\n [ngClass]=\"isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\"\n (click)=\"collapseRow(rowIndex)\">\n </span>\n </td>\n </tr>\n <tr\n *ngIf=\"(config.detailsTemplate && selectedDetailsTemplateRowId.has(rowIndex)) || config.collapseAllRows\">\n <td [attr.colspan]=\"columns.length + 1\">\n <ng-container\n [ngTemplateOutlet]=\"detailsTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\">\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n <cdk-virtual-scroll-viewport\n itemSize=\"50\"\n *ngIf=\"config.infiniteScroll\"\n class=\"ngx-infinite-scroll-viewport\">\n <ng-container *cdkVirtualFor=\"let row of data | sort:sortBy | search:term:filteredCountSubject | global:globalSearchTerm:filteredCountSubject;\n let rowIndex = index\">\n <tr\n (click)=\"onClick($event, row, '', null, rowIndex)\"\n #contextMenu\n (contextmenu)=\"onRowContextMenu($event, row, '', null, rowIndex)\"\n (dblclick)=\"onDoubleClick($event, row, '', null, rowIndex)\"\n [class.ngx-table__table-row--selected]=\"rowIndex === selectedRow && !config.selectCell\">\n <ng-container\n [ngTemplateOutlet]=\"rowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\">\n </ng-container>\n <td *ngIf=\"config.detailsTemplate\">\n <span class=\"ngx-icon\"\n *ngIf=\"arrowDefinition\"\n [ngClass]=\"isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\"\n (click)=\"collapseRow(rowIndex)\">\n </span>\n </td>\n </tr>\n <tr\n *ngIf=\"(config.detailsTemplate && selectedDetailsTemplateRowId.has(rowIndex)) || config.collapseAllRows\">\n <td [attr.colspan]=\"columns.length + 1\">\n <ng-container\n [ngTemplateOutlet]=\"detailsTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\">\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n </ng-container>\n <ng-container *ngIf=\"!rowTemplate && !config.groupRows\">\n <ul class=\"ngx-table__table-row-context-menu\"\n [ngStyle]=\"{'position': 'absolute', 'top': rowContextMenuPosition.top, 'left': rowContextMenuPosition.left }\"\n *ngIf=\"rowContextMenuPosition.top\">\n <ng-container\n [ngTemplateOutlet]=\"rowContextMenu\"\n [ngTemplateOutletContext]=\"{ $implicit: rowContextMenuPosition.value}\">\n </ng-container>\n </ul>\n <ng-container *ngIf=\"!config.infiniteScroll\">\n <ng-container\n *ngFor=\"let row of data | sort:sortBy | search:term:filteredCountSubject | global:globalSearchTerm:filteredCountSubject | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id };\n let rowIndex = index\">\n <tr [class.ngx-table__table-row--selected]=\"rowIndex === selectedRow && !config.selectCell\">\n <td *ngIf=\"config.checkboxes\">\n <label class=\"ngx-form-checkbox\">\n <input type=\"checkbox\"\n id=\"checkbox-{{rowIndex}}\"\n [checked]=\"isSelected || selectedCheckboxes.has(rowIndex)\"\n (change)=\"onCheckboxSelect($event, row, rowIndex)\">\n <em class=\"ngx-form-icon\"></em>\n </label>\n </td>\n <td *ngIf=\"config.radio\">\n <label>\n <input type=\"radio\"\n id=\"radio-{{rowIndex}}\"\n name=\"radio\"\n (change)=\"onRadioSelect($event, row, rowIndex)\">\n </label>\n </td>\n <ng-container *ngFor=\"let column of columns; let colIndex = index\">\n <td (click)=\"onClick($event, row, column.key, colIndex, rowIndex)\"\n #contextMenu\n (contextmenu)=\"onRowContextMenu($event, row, column.key, colIndex, rowIndex)\"\n (dblclick)=\"onDoubleClick($event, row, column.key, colIndex, rowIndex)\"\n [class.pinned-left]=\"column.pinned\"\n [ngClass]=\"column.cssClass ? column.cssClass.name : ''\"\n [style.left]=\"styleService.pinnedWidth(column.pinned, colIndex)\"\n [class.ngx-table__table-col--selected]=\"colIndex === selectedCol && !config.selectCell\"\n [class.ngx-table__table-cell--selected]=\"colIndex === selectedCol && rowIndex === selectedRow && !config.selectCol && !config.selectRow\"\n >\n <div *ngIf=\"!column.cellTemplate\">{{ row | render:column.key }}</div>\n <ng-container\n *ngIf=\"column.cellTemplate\"\n [ngTemplateOutlet]=\"column.cellTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, rowIndex: rowIndex }\">\n </ng-container>\n </td>\n </ng-container>\n <td *ngIf=\"config.additionalActions || config.detailsTemplate\">\n <span class=\"ngx-icon\"\n *ngIf=\"arrowDefinition\"\n [ngClass]=\"isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\"\n (click)=\"collapseRow(rowIndex)\">\n </span>\n </td>\n </tr>\n <tr\n *ngIf=\"(config.detailsTemplate && selectedDetailsTemplateRowId.has(rowIndex)) || config.collapseAllRows\">\n <td *ngIf=\"config.checkboxes || config.radio\"></td>\n <td [attr.colspan]=\"columns.length + 1\">\n <ng-container\n [ngTemplateOutlet]=\"detailsTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\">\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </ng-container>\n <!-- infinite scroll -->\n <cdk-virtual-scroll-viewport\n itemSize=\"50\"\n *ngIf=\"config.infiniteScroll\"\n class=\"ngx-infinite-scroll-viewport\">\n <ng-container\n *cdkVirtualFor=\"let row of data | sort:sortBy | search:term:filteredCountSubject | global:globalSearchTerm:filteredCountSubject;\n let rowIndex = index\">\n <tr [class.ngx-table__table-row--selected]=\"rowIndex === selectedRow && !config.selectCell\">\n <td *ngIf=\"config.checkboxes\">\n <label class=\"ngx-form-checkbox\">\n <input type=\"checkbox\"\n id=\"checkbox-infinite-scroll-{{rowIndex}}\"\n [checked]=\"isSelected || selectedCheckboxes.has(rowIndex)\"\n (change)=\"onCheckboxSelect($event, row, rowIndex)\">\n <em class=\"ngx-form-icon\"></em>\n </label>\n </td>\n <td *ngIf=\"config.radio\">\n <label>\n <input type=\"radio\"\n id=\"radio-infinite-scroll-{{rowIndex}}\"\n name=\"radio\"\n (change)=\"onRadioSelect($event, row, rowIndex)\">\n </label>\n </td>\n <ng-container *ngFor=\"let column of columns; let colIndex = index\">\n <td (click)=\"onClick($event, row, column.key, colIndex, rowIndex)\"\n #contextMenu\n (contextmenu)=\"onRowContextMenu($event, row, column.key, colIndex, rowIndex)\"\n (dblclick)=\"onDoubleClick($event, row, column.key, colIndex, rowIndex)\"\n [class.pinned-left]=\"column.pinned\"\n [ngClass]=\"column.cssClass ? column.cssClass.name : ''\"\n [style.left]=\"styleService.pinnedWidth(column.pinned, colIndex)\"\n [class.ngx-table__table-col--selected]=\"colIndex === selectedCol && !config.selectCell\"\n [class.ngx-table__table-cell--selected]=\"colIndex === selectedCol && rowIndex === selectedRow && !config.selectCol && !config.selectRow\"\n >\n <div *ngIf=\"!column.cellTemplate\">{{ row | render:column.key }}</div>\n <ng-container\n *ngIf=\"column.cellTemplate\"\n [ngTemplateOutlet]=\"column.cellTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, rowIndex: rowIndex }\">\n </ng-container>\n </td>\n </ng-container>\n <td *ngIf=\"config.additionalActions || config.detailsTemplate\">\n <span class=\"ngx-icon\"\n *ngIf=\"arrowDefinition\"\n [ngClass]=\"isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\"\n (click)=\"collapseRow(rowIndex)\">\n </span>\n </td>\n </tr>\n <tr\n *ngIf=\"(config.detailsTemplate && selectedDetailsTemplateRowId.has(rowIndex)) || config.collapseAllRows\">\n <td *ngIf=\"config.checkboxes || config.radio\"></td>\n <td [attr.colspan]=\"columns.length + 1\">\n <ng-container\n [ngTemplateOutlet]=\"detailsTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: rowIndex }\">\n </ng-container>\n </td>\n </tr>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n </ng-container>\n <ng-container *ngIf=\"!rowTemplate && config.groupRows\">\n <ng-container\n *ngFor=\"let group of grouped | sort:sortBy:config | search:term:filteredCountSubject:config | global:globalSearchTerm:filteredCountSubject | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id };\n let rowIndex = index\">\n <tr>\n <ng-container *ngIf=\"!groupRowsHeaderTemplate\">\n <td [attr.colspan]=\"columns.length\">\n <div>{{group[0][groupRowsBy]}} ({{group.length}})</div>\n </td>\n </ng-container>\n <ng-container\n *ngIf=\"groupRowsHeaderTemplate\"\n [ngTemplateOutlet]=\"groupRowsHeaderTemplate\"\n [ngTemplateOutletContext]=\"{\n total: group.length,\n key: groupRowsBy,\n value: group[0] ? group[0][groupRowsBy] : '',\n group: group,\n index: rowIndex\n }\">\n </ng-container>\n <td>\n <span class=\"ngx-icon\"\n *ngIf=\"arrowDefinition\"\n [ngClass]=\"isRowCollapsed(rowIndex) ? 'ngx-icon-arrow-down' : 'ngx-icon-arrow-right'\"\n (click)=\"collapseRow(rowIndex)\">\n </span>\n </td>\n </tr>\n <ng-container *ngIf=\"selectedDetailsTemplateRowId.has(rowIndex)\">\n <tr *ngFor=\"let row of group\">\n <td *ngFor=\"let column of columns\">\n {{ row | render:column.key }}\n <!-- TODO allow users to add groupRowsTemplateRef -->\n </td>\n <td></td>\n </tr>\n </ng-container>\n </ng-container>\n </ng-container>\n </tbody>\n <tbody *ngIf=\"data && !config.isLoading && config.rowReorder\"\n class=\"ngx-draggable-row-area\"\n cdkDropList\n (cdkDropListDropped)=\"onDrop($event)\">\n <ng-container *ngIf=\"!rowTemplate && !config.groupRows\">\n <ng-container\n *ngFor=\"let row of data | sort:sortBy | search:term:filteredCountSubject | global:globalSearchTerm:filteredCountSubject | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id };\n let rowIndex = index\">\n <tr class=\"ngx-draggable-row\" cdkDrag cdkDragLockAxis=\"y\">\n <td *ngIf=\"config.checkboxes\">\n <label class=\"ngx-form-checkbox\">\n <input type=\"checkbox\"\n id=\"checkbox-draggable-{{rowIndex}}\"\n [checked]=\"isSelected || selectedCheckboxes.has(rowIndex)\"\n (change)=\"onCheckboxSelect($event, row, rowIndex)\">\n <em class=\"ngx-form-icon\"></em>\n </label>\n </td>\n <td *ngIf=\"config.radio\">\n <label>\n <input type=\"radio\"\n id=\"radio-draggable-{{rowIndex}}\"\n name=\"radio\"\n (change)=\"onRadioSelect($event, row, rowIndex)\">\n </label>\n </td>\n <ng-container *ngFor=\"let column of columns; let colIndex = index\">\n <td (click)=\"onClick($event, row, column.key, colIndex, rowIndex)\"\n (dblclick)=\"onDoubleClick($event, row, column.key, colIndex, rowIndex)\"\n [class.ngx-table__table-col--selected]=\"colIndex === selectedCol && !config.selectCell\"\n [class.ngx-table__table-cell--selected]=\"colIndex === selectedCol && rowIndex === selectedRow && !config.selectCol && !config.selectRow\"\n >\n <div>{{ row | render:column.key }}</div>\n </td>\n </ng-container>\n </tr>\n </ng-container>\n </ng-container>\n </tbody>\n <tbody *ngIf=\"filterCount === 0\">\n <tr class=\"ngx-table__body-empty\">\n <ng-container\n *ngIf=\"noResultsTemplate\"\n [ngTemplateOutlet]=\"noResultsTemplate\">\n </ng-container>\n <td [attr.colspan]=\"columns && columns.length + 1\" *ngIf=\"!noResultsTemplate\">\n <div class=\"ngx-table__table-no-results\">\n No results\n </div>\n </td>\n </tr>\n </tbody>\n <tbody *ngIf=\"isLoading\">\n <tr class=\"ngx-table__body-loading\">\n <ng-container\n *ngIf=\"loadingTemplate\"\n [ngTemplateOutlet]=\"loadingTemplate\">\n </ng-container>\n <td [attr.colspan]=\"columns && columns.length + 1\" *ngIf=\"!loadingTemplate\">\n <div [style.height]=\"loadingHeight\"\n class=\"ngx-table__table-loader-wrapper\">\n <div class=\"ngx-table__table-loader\"></div>\n </div>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"summaryTemplate\">\n <tr>\n <ng-container\n [ngTemplateOutlet]=\"summaryTemplate\"\n [ngTemplateOutletContext]=\"{ total: data.length, limit: limit, page: page }\">\n </ng-container>\n </tr>\n </tfoot>\n </table>\n <pagination\n [attr.id]=\"'pagination' + id\"\n [id]=\"id\"\n #paginationComponent\n [config]=\"config\"\n [pagination]=\"pagination\"\n (updateRange)=\"onPagination($event)\">\n </pagination>\n</div>\n",
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
/** @nocollapse */
BaseComponent.ctorParameters = function () { return [
{ type: ChangeDetectorRef },
{ type: ScrollDispatcher },
{ type: StyleService }
]; };
BaseComponent.propDecorators = {
configuration: [{ type: Input }],
data: [{ type: Input }],
pagination: [{ type: Input }],
groupRowsBy: [{ type: Input }],
id: [{ type: Input }],
toggleRowIndex: [{ type: Input }],
detailsTemplate: [{ type: Input }],
summaryTemplate: [{ type: Input }],
groupRowsHeaderTemplate: [{ type: Input }],
filtersTemplate: [{ type: Input }],
selectAllTemplate: [{ type: Input }],
noResultsTemplate: [{ type: Input }],
loadingTemplate: [{ type: Input }],
additionalActionsTemplate: [{ type: Input }],
rowContextMenu: [{ type: Input }],
columns: [{ type: Input }],
event: [{ type: Output }],
rowTemplate: [{ type: ContentChild, args: [TemplateRef, { static: true },] }],
paginationComponent: [{ type: ViewChild, args: ['paginationComponent', { static: false },] }],
contextMenu: [{ type: ViewChild, args: ['contextMenu', { static: false },] }],
viewPort: [{ type: ViewChild, args: [CdkVirtualScrollViewport, { static: false },] }],
onContextMenuClick: [{ type: HostListener, args: ['document:click', ['$event.target'],] }]
};
return BaseComponent;
}());
export { BaseComponent };
if (false) {
/**
* @type {?}
* @private
*/
BaseComponent.prototype.unsubscribe;
/** @type {?} */
BaseComponent.prototype.selectedRow;
/** @type {?} */
BaseComponent.prototype.selectedCol;
/** @type {?} */
BaseComponent.prototype.term;
/** @type {?} */
BaseComponent.prototype.filterCount;
/** @type {?} */
BaseComponent.prototype.filteredCountSubject;
/** @type {?} */
BaseComponent.prototype.subscription;
/** @type {?} */
BaseComponent.prototype.tableClass;
/** @type {?} */
BaseComponent.prototype.globalSearchTerm;
/** @type {?} */
BaseComponent.prototype.grouped;
/** @type {?} */
BaseComponent.prototype.isSelected;
/** @type {?} */
BaseComponent.prototype.page;
/** @type {?} */
BaseComponent.prototype.count;
/** @type {?} */
BaseComponent.prototype.sortState;
/** @type {?} */
BaseComponent.prototype.sortKey;
/** @type {?} */
BaseComponent.prototype.rowContextMenuPosition;
/** @type {?} */
BaseComponent.prototype.limit;
/** @type {?} */
BaseComponent.prototype.sortBy;
/** @type {?} */
BaseComponent.prototype.selectedDetailsTemplateRowId;
/** @type {?} */
BaseComponent.prototype.selectedCheckboxes;
/** @type {?} */
BaseComponent.prototype.loadingHeight;
/** @type {?} */
BaseComponent.prototype.config;
/** @type {?} */
BaseComponent.prototype.configuration;
/** @type {?} */
BaseComponent.prototype.data;
/** @type {?} */
BaseComponent.prototype.pagination;
/** @type {?} */
BaseComponent.prototype.groupRowsBy;
/** @type {?} */
BaseComponent.prototype.id;
/** @type {?} */
BaseComponent.prototype.toggleRowIndex;
/** @type {?} */
BaseComponent.prototype.detailsTemplate;
/** @type {?} */
BaseComponent.prototype.summaryTemplate;
/** @type {?} */
BaseComponent.prototype.groupRowsHeaderTemplate;
/** @type {?} */
BaseComponent.prototype.filtersTemplate;
/** @type {?} */
BaseComponent.prototype.selectAllTemplate;
/** @type {?} */
BaseComponent.prototype.noResultsTemplate;
/** @type {?} */
BaseComponent.prototype.loadingTemplate;
/** @type {?} */
BaseComponent.prototype.additionalActionsTemplate;
/** @type {?} */
BaseComponent.prototype.rowContextMenu;
/** @type {?} */
BaseComponent.prototype.columns;
/** @type {?} */
BaseComponent.prototype.event;
/** @type {?} */
BaseComponent.prototype.rowTemplate;
/**
* @type {?}
* @private
*/
BaseComponent.prototype.paginationComponent;
/** @type {?} */
BaseComponent.prototype.contextMenu;
/** @type {?} */
BaseComponent.prototype.viewPort;
/**
* @type {?}
* @private
*/
BaseComponent.prototype.cdr;
/**
* @type {?}
* @private
*/
BaseComponent.prototype.scrollDispatcher;
/** @type {?} */
BaseComponent.prototype.styleService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtZWFzeS10YWJsZS8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL2Jhc2UvYmFzZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQWUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEUsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFFRyxNQUFNLEVBRWQsV0FBVyxFQUNYLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsR0FBRyxFQUE0QixLQUFLLEVBQWMsTUFBTSxPQUFPLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDckUsT0FBTyxFQUFFLG1CQUFtQixFQUFtQixNQUFNLG9DQUFvQyxDQUFDO0FBQzFGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUM3QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNwRixPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQUlqRSxxQ0FJQzs7O0lBSEMscUNBQW1COztJQUNuQixzQ0FBb0I7O0lBQ3BCLHVDQUFrQjs7QUFHcEI7SUEwRUUsdUJBQ21CLEdBQXNCLEVBQ3RCLGdCQUFrQyxFQUNuQyxZQUEwQjtRQUg1QyxpQkFhQztRQVprQixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0QixxQkFBZ0IsR0FBaEIsZ0JBQWdC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QUFpQjs7SUFDakIsa0NBQTZCOztJQUM3QixnQ0FBcUM7O0lBQ3JDLCtDQUlFOztJQUNGLDhCQUFhOztJQUNiLCtCQUdFOztJQUNGLHFEQUF3RDs7SUFDeEQsMkNBQThDOztJQUM5QyxzQ0FBOEI7O0lBQzlCLCtCQUFzQjs7SUFFdEIsc0NBQStCOztJQUMvQiw2QkFBcUI7O0lBQ3JCLG1DQUFnQzs7SUFDaEMsb0NBQTZCOztJQUM3QiwyQkFBc0I7O0lBQ3RCLHVDQUF3Qjs7SUFDeEIsd0NBQTJDOztJQUMzQyx3Q0FBc0Y7O0lBQ3RGLGdEQUFtRDs7SUFDbkQsd0NBQTJDOztJQUMzQywwQ0FBNkM7O0lBQzdDLDBDQUE4Qzs7SUFDOUMsd0NBQTRDOztJQUM1QyxrREFBc0Q7O0lBQ3RELHVDQUEwQzs7SUFDMUMsZ0NBQTRCOztJQUM1Qiw4QkFBNkU7O0lBQzdFLG9DQUFrRjs7Ozs7SUFDbEYsNENBQXNHOztJQUN0RyxvQ0FBeUQ7O0lBQ3pELGlDQUEyRjs7Ozs7SUFjekYsNEJBQXVDOzs7OztJQUN2Qyx5Q0FBbUQ7O0lBQ25ELHFDQUEwQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENka0RyYWdEcm9wLCBtb3ZlSXRlbUluQXJyYXkgfSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksXG4gIE9uSW5pdCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2UsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBBUEksIEFwaVR5cGUsIENvbHVtbnMsIENvbmZpZywgRXZlbnQsIFBhZ2luYXRpb24gfSBmcm9tICcuLi8uLic7XG5pbXBvcnQgeyBEZWZhdWx0Q29uZmlnU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2NvbmZpZy1zZXJ2aWNlJztcbmltcG9ydCB7IFBhZ2luYXRpb25Db21wb25lbnQsIFBhZ2luYXRpb25SYW5nZSB9IGZyb20gJy4uL3BhZ2luYXRpb24vcGFnaW5hdGlvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgR3JvdXBSb3dzU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2dyb3VwLXJvd3Muc2VydmljZSc7XG5pbXBvcnQgeyBTdHlsZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9zdHlsZS5zZXJ2aWNlJztcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0LCBTY3JvbGxEaXNwYXRjaGVyIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3Njcm9sbGluZyc7XG5pbXBvcnQgeyBmaWx0ZXIsIHRha2VVbnRpbCwgdGhyb3R0bGVUaW1lIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG50eXBlIENvbHVtbktleVR5cGUgPSBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuO1xuXG5pbnRlcmZhY2UgUm93Q29udGV4dE1lbnVQb3NpdGlvbiB7XG4gIHRvcDogc3RyaW5nIHwgbnVsbDtcbiAgbGVmdDogc3RyaW5nIHwgbnVsbDtcbiAgdmFsdWU6IGFueSB8IG51bGw7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC10YWJsZScsXG4gIHByb3ZpZGVyczogW1xuICAgIERlZmF1bHRDb25maWdTZXJ2aWNlLFxuICAgIEdyb3VwUm93c1NlcnZpY2UsXG4gICAgU3R5bGVTZXJ2aWNlLFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vYmFzZS5jb21wb25lbnQuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBCYXNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgdW5zdWJzY3JpYmUgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwdWJsaWMgc2VsZWN0ZWRSb3c6IG51bWJlcjtcbiAgcHVibGljIHNlbGVjdGVkQ29sOiBudW1iZXI7XG4gIHB1YmxpYyB0ZXJtO1xuICBwdWJsaWMgZmlsdGVyQ291bnQgPSAtMTtcbiAgcHVibGljIGZpbHRlcmVkQ291bnRTdWJqZWN0ID0gbmV3IFN1YmplY3Q8bnVtYmVyPigpO1xuICBwdWJsaWMgc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gIHB1YmxpYyB0YWJsZUNsYXNzOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIGdsb2JhbFNlYXJjaFRlcm06IHN0cmluZztcbiAgcHVibGljIGdyb3VwZWQ6IGFueSA9IFtdO1xuICBwdWJsaWMgaXNTZWxlY3RlZCA9IGZhbHNlO1xuICBwdWJsaWMgcGFnZSA9IDE7XG4gIHB1YmxpYyBjb3VudCA9IDA7XG4gIHB1YmxpYyBzb3J0U3RhdGUgPSBuZXcgTWFwKCk7XG4gIHB1YmxpYyBzb3J0S2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIHJvd0NvbnRleHRNZW51UG9zaXRpb246IFJvd0NvbnRleHRNZW51UG9zaXRpb24gPSB7XG4gICAgdG9wOiBudWxsLFxuICAgIGxlZnQ6IG51bGwsXG4gICAgdmFsdWU6IG51bGwsXG4gIH07XG4gIHB1YmxpYyBsaW1pdDtcbiAgcHVibGljIHNvcnRCeTogeyBrZXk6IHN0cmluZyB9ICYgeyBvcmRlcjogc3RyaW5nIH0gPSB7XG4gICAga2V5OiAnJyxcbiAgICBvcmRlcjogJ2FzYycsXG4gIH07XG4gIHB1YmxpYyBzZWxlY3RlZERldGFpbHNUZW1wbGF0ZVJvd0lkID0gbmV3IFNldDxudW1iZXI+KCk7XG4gIHB1YmxpYyBzZWxlY3RlZENoZWNrYm94ZXMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgcHVibGljIGxvYWRpbmdIZWlnaHQgPSAnMzBweCc7XG4gIHB1YmxpYyBjb25maWc6IENvbmZpZztcblxuICBASW5wdXQoKSBjb25maWd1cmF0aW9uOiBDb25maWc7XG4gIEBJbnB1dCgpIGRhdGE6IGFueVtdO1xuICBASW5wdXQoKSBwYWdpbmF0aW9uOiBQYWdpbmF0aW9uO1xuICBASW5wdXQoKSBncm91cFJvd3NCeTogc3RyaW5nO1xuICBASW5wdXQoKSBpZCA9ICd0YWJsZSc7XG4gIEBJbnB1dCgpIHRvZ2dsZVJvd0luZGV4O1xuICBASW5wdXQoKSBkZXRhaWxzVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG4gIEBJbnB1dCgpIHN1bW1hcnlUZW1wbGF0ZTogVGVtcGxhdGVSZWY8eyB0b3RhbDogbnVtYmVyOyBsaW1pdDogbnVtYmVyOyBwYWdlOiBudW1iZXIgfT47XG4gIEBJbnB1dCgpIGdyb3VwUm93c0hlYWRlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuICBASW5wdXQoKSBmaWx0ZXJzVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG4gIEBJbnB1dCgpIHNlbGVjdEFsbFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuICBASW5wdXQoKSBub1Jlc3VsdHNUZW1wbGF0ZTogVGVtcGxhdGVSZWY8dm9pZD47XG4gIEBJbnB1dCgpIGxvYWRpbmdUZW1wbGF0ZTogVGVtcGxhdGVSZWY8dm9pZD47XG4gIEBJbnB1dCgpIGFkZGl0aW9uYWxBY3Rpb25zVGVtcGxhdGU6IFRlbXBsYXRlUmVmPHZvaWQ+O1xuICBASW5wdXQoKSByb3dDb250ZXh0TWVudTogVGVtcGxhdGVSZWY8YW55PjtcbiAgQElucHV0KCkgY29sdW1uczogQ29sdW1uc1tdO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgZXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgZXZlbnQ6IHN0cmluZywgdmFsdWU6IGFueSB9PigpO1xuICBAQ29udGVudENoaWxkKFRlbXBsYXRlUmVmLCB7IHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgcm93VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG4gIEBWaWV3Q2hpbGQoJ3BhZ2luYXRpb25Db21wb25lbnQnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBwYWdpbmF0aW9uQ29tcG9uZW50OiBQYWdpbmF0aW9uQ29tcG9uZW50O1xuICBAVmlld0NoaWxkKCdjb250ZXh0TWVudScsIHsgc3RhdGljOiBmYWxzZSB9KSBjb250ZXh0TWVudTtcbiAgQFZpZXdDaGlsZChDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQsIHsgc3RhdGljOiBmYWxzZSB9KSB2aWV3UG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0O1xuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQudGFyZ2V0J10pXG4gIHB1YmxpYyBvbkNvbnRleHRNZW51Q2xpY2sodGFyZ2V0RWxlbWVudDogYW55KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29udGV4dE1lbnUgJiYgIXRoaXMuY29udGV4dE1lbnUubmF0aXZlRWxlbWVudC5jb250YWlucyh0YXJnZXRFbGVtZW50KSkge1xuICAgICAgdGhpcy5yb3dDb250ZXh0TWVudVBvc2l0aW9uID0ge1xuICAgICAgICB0b3A6IG51bGwsXG4gICAgICAgIGxlZnQ6IG51bGwsXG4gICAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzY3JvbGxEaXNwYXRjaGVyOiBTY3JvbGxEaXNwYXRjaGVyLFxuICAgIHB1YmxpYyByZWFkb25seSBzdHlsZVNlcnZpY2U6IFN0eWxlU2VydmljZSxcbiAgKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24gPSB0aGlzLmZpbHRlcmVkQ291bnRTdWJqZWN0XG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZVVudGlsKHRoaXMudW5zdWJzY3JpYmUpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoY291bnQpID0+IHtcbiAgICAgICAgdGhpcy5maWx0ZXJDb3VudCA9IGNvdW50O1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb2x1bW5zKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbY29sdW1uc10gcHJvcGVydHkgcmVxdWlyZWQhJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHRoaXMuY29uZmlnID0gdGhpcy5jb25maWd1cmF0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbmZpZyA9IERlZmF1bHRDb25maWdTZXJ2aWNlLmNvbmZpZztcbiAgICB9XG4gICAgdGhpcy5saW1pdCA9IHRoaXMuY29uZmlnLnJvd3M7XG4gICAgaWYgKHRoaXMuZ3JvdXBSb3dzQnkpIHtcbiAgICAgIHRoaXMuZ3JvdXBlZCA9IEdyb3VwUm93c1NlcnZpY2UuZG9Hcm91cFJvd3ModGhpcy5kYXRhLCB0aGlzLmdyb3VwUm93c0J5KTtcbiAgICB9XG4gICAgdGhpcy5kb0RlY29kZVBlcnNpc3RlZFN0YXRlKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnVuc3Vic2NyaWJlLm5leHQoKTtcbiAgICB0aGlzLnVuc3Vic2NyaWJlLmNvbXBsZXRlKCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgY29uc3QgdGhyb3R0bGVWYWx1ZSA9IHRoaXMuY29uZmlnLmluZmluaXRlU2Nyb2xsVGhyb3R0bGVUaW1lID9cbiAgICAgIHRoaXMuY29uZmlnLmluZmluaXRlU2Nyb2xsVGhyb3R0bGVUaW1lIDpcbiAgICAgIDIwMDtcbiAgICB0aGlzLnNjcm9sbERpc3BhdGNoZXIuc2Nyb2xsZWQoKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLnVuc3Vic2NyaWJlKSxcbiAgICAgICAgdGhyb3R0bGVUaW1lKHRocm90dGxlVmFsdWUpLFxuICAgICAgICBmaWx0ZXIoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgcmV0dXJuICEhZXZlbnQgJiYgdGhpcy52aWV3UG9ydCAmJiB0aGlzLnZpZXdQb3J0LmdldFJlbmRlcmVkUmFuZ2UoKS5lbmQgPT09IHRoaXMudmlld1BvcnQuZ2V0RGF0YUxlbmd0aCgpO1xuICAgICAgICB9KSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vbkluZmluaXRlU2Nyb2xsRW5kLCBudWxsKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IHsgY29uZmlndXJhdGlvbiwgZGF0YSwgcGFnaW5hdGlvbiwgZ3JvdXBSb3dzQnkgfSA9IGNoYW5nZXM7XG4gICAgdGhpcy50b2dnbGVSb3dJbmRleCA9IGNoYW5nZXMudG9nZ2xlUm93SW5kZXg7XG4gICAgaWYgKGNvbmZpZ3VyYXRpb24gJiYgY29uZmlndXJhdGlvbi5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMuY29uZmlnID0gY29uZmlndXJhdGlvbi5jdXJyZW50VmFsdWU7XG4gICAgfVxuICAgIGlmIChkYXRhICYmIGRhdGEuY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLmRvQXBwbHlEYXRhKGRhdGEpO1xuICAgIH1cbiAgICBpZiAocGFnaW5hdGlvbiAmJiBwYWdpbmF0aW9uLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgY29uc3QgeyBjb3VudCwgbGltaXQsIG9mZnNldCB9ID0gcGFnaW5hdGlvbi5jdXJyZW50VmFsdWUgYXMgUGFnaW5hdGlvbjtcbiAgICAgIHRoaXMuY291bnQgPSBjb3VudDtcbiAgICAgIHRoaXMubGltaXQgPSBsaW1pdDtcbiAgICAgIHRoaXMucGFnZSA9IG9mZnNldDtcbiAgICB9XG4gICAgaWYgKGdyb3VwUm93c0J5ICYmIGdyb3VwUm93c0J5LmN1cnJlbnRWYWx1ZSkge1xuICAgICAgdGhpcy5ncm91cGVkID0gR3JvdXBSb3dzU2VydmljZS5kb0dyb3VwUm93cyh0aGlzLmRhdGEsIHRoaXMuZ3JvdXBSb3dzQnkpO1xuICAgIH1cbiAgICBpZiAodGhpcy50b2dnbGVSb3dJbmRleCAmJiB0aGlzLnRvZ2dsZVJvd0luZGV4LmN1cnJlbnRWYWx1ZSkge1xuICAgICAgY29uc3Qgcm93ID0gdGhpcy50b2dnbGVSb3dJbmRleC5jdXJyZW50VmFsdWU7XG4gICAgICB0aGlzLmNvbGxhcHNlUm93KHJvdy5pbmRleCk7XG4gICAgfVxuICB9XG5cbiAgb3JkZXJCeShjb2x1bW46IENvbHVtbnMpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIGNvbHVtbi5vcmRlckVuYWJsZWQgIT09ICd1bmRlZmluZWQnICYmICFjb2x1bW4ub3JkZXJFbmFibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc29ydEtleSA9IGNvbHVtbi5rZXk7XG4gICAgaWYgKCF0aGlzLmNvbmZpZy5vcmRlckVuYWJsZWQgfHwgdGhpcy5zb3J0S2V5ID09PSAnJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2V0Q29sdW1uT3JkZXIodGhpcy5zb3J0S2V5KTtcbiAgICBpZiAoIXRoaXMuY29uZmlnLm9yZGVyRXZlbnRPbmx5ICYmICFjb2x1bW4ub3JkZXJFdmVudE9ubHkpIHtcbiAgICAgIHRoaXMuc29ydEJ5LmtleSA9IHRoaXMuc29ydEtleTtcbiAgICAgIHRoaXMuc29ydEJ5Lm9yZGVyID0gdGhpcy5zb3J0U3RhdGUuZ2V0KHRoaXMuc29ydEtleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc29ydEJ5LmtleSA9ICcnO1xuICAgICAgdGhpcy5zb3J0Qnkub3JkZXIgPSAnJztcbiAgICB9XG4gICAgaWYgKCF0aGlzLmNvbmZpZy5zZXJ2ZXJQYWdpbmF0aW9uKSB7XG4gICAgICB0aGlzLmRhdGEgPSBbLi4udGhpcy5kYXRhXTtcbiAgICAgIHRoaXMuc29ydEJ5ID0geyAuLi50aGlzLnNvcnRCeSB9O1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0ge1xuICAgICAga2V5OiB0aGlzLnNvcnRLZXksXG4gICAgICBvcmRlcjogdGhpcy5zb3J0U3RhdGUuZ2V0KHRoaXMuc29ydEtleSksXG4gICAgfTtcbiAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vbk9yZGVyLCB2YWx1ZSk7XG4gIH1cblxuICBvbkNsaWNrKCRldmVudDogTW91c2VFdmVudCwgcm93OiBvYmplY3QsIGtleTogQ29sdW1uS2V5VHlwZSwgY29sSW5kZXg6IGFueSwgcm93SW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbmZpZy5zZWxlY3RSb3cpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRSb3cgPSByb3dJbmRleDtcbiAgICB9XG4gICAgaWYgKHRoaXMuY29uZmlnLnNlbGVjdENvbCAmJiBjb2xJbmRleCkge1xuICAgICAgdGhpcy5zZWxlY3RlZENvbCA9IGNvbEluZGV4O1xuICAgIH1cbiAgICBpZiAodGhpcy5jb25maWcuc2VsZWN0Q2VsbCAmJiBjb2xJbmRleCkge1xuICAgICAgdGhpcy5zZWxlY3RlZFJvdyA9IHJvd0luZGV4O1xuICAgICAgdGhpcy5zZWxlY3RlZENvbCA9IGNvbEluZGV4O1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5jbGlja0V2ZW50KSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHtcbiAgICAgICAgZXZlbnQ6ICRldmVudCxcbiAgICAgICAgcm93LFxuICAgICAgICBrZXksXG4gICAgICAgIHJvd0lkOiByb3dJbmRleCxcbiAgICAgICAgY29sSWQ6IGNvbEluZGV4LFxuICAgICAgfTtcbiAgICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uQ2xpY2ssIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBvbkRvdWJsZUNsaWNrKCRldmVudDogTW91c2VFdmVudCwgcm93OiBvYmplY3QsIGtleTogQ29sdW1uS2V5VHlwZSwgY29sSW5kZXg6IGFueSwgcm93SW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHZhbHVlID0ge1xuICAgICAgZXZlbnQ6ICRldmVudCxcbiAgICAgIHJvdyxcbiAgICAgIGtleSxcbiAgICAgIHJvd0lkOiByb3dJbmRleCxcbiAgICAgIGNvbElkOiBjb2xJbmRleCxcbiAgICB9O1xuICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uRG91YmxlQ2xpY2ssIHZhbHVlKTtcbiAgfVxuXG4gIG9uQ2hlY2tib3hTZWxlY3QoJGV2ZW50OiBvYmplY3QsIHJvdzogb2JqZWN0LCByb3dJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdmFsdWUgPSB7XG4gICAgICBldmVudDogJGV2ZW50LFxuICAgICAgcm93LFxuICAgICAgcm93SWQ6IHJvd0luZGV4LFxuICAgIH07XG4gICAgdGhpcy5lbWl0RXZlbnQoRXZlbnQub25DaGVja2JveFNlbGVjdCwgdmFsdWUpO1xuICB9XG5cbiAgb25SYWRpb1NlbGVjdCgkZXZlbnQ6IG9iamVjdCwgcm93OiBvYmplY3QsIHJvd0luZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZSA9IHtcbiAgICAgIGV2ZW50OiAkZXZlbnQsXG4gICAgICByb3csXG4gICAgICByb3dJZDogcm93SW5kZXgsXG4gICAgfTtcbiAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vblJhZGlvU2VsZWN0LCB2YWx1ZSk7XG4gIH1cblxuICBvblNlbGVjdEFsbCgpOiB2b2lkIHtcbiAgICB0aGlzLmlzU2VsZWN0ZWQgPSAhdGhpcy5pc1NlbGVjdGVkO1xuICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uU2VsZWN0QWxsLCB0aGlzLmlzU2VsZWN0ZWQpO1xuICB9XG5cbiAgb25TZWFyY2goJGV2ZW50OiBBcnJheTx7IGtleTogc3RyaW5nOyB2YWx1ZTogc3RyaW5nIH0+KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZy5zZXJ2ZXJQYWdpbmF0aW9uKSB7XG4gICAgICB0aGlzLnRlcm0gPSAkZXZlbnQ7XG4gICAgfVxuICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uU2VhcmNoLCAkZXZlbnQpO1xuICB9XG5cbiAgb25HbG9iYWxTZWFyY2godmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb25maWcuc2VydmVyUGFnaW5hdGlvbikge1xuICAgICAgdGhpcy5nbG9iYWxTZWFyY2hUZXJtID0gdmFsdWU7XG4gICAgfVxuICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uR2xvYmFsU2VhcmNoLCB2YWx1ZSk7XG4gIH1cblxuICBvblBhZ2luYXRpb24ocGFnaW5hdGlvbjogUGFnaW5hdGlvblJhbmdlKTogdm9pZCB7XG4gICAgdGhpcy5wYWdlID0gcGFnaW5hdGlvbi5wYWdlO1xuICAgIHRoaXMubGltaXQgPSBwYWdpbmF0aW9uLmxpbWl0O1xuICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uUGFnaW5hdGlvbiwgcGFnaW5hdGlvbik7XG4gIH1cblxuICB0b2dnbGVDaGVja2JveChyb3dJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZENoZWNrYm94ZXMuaGFzKHJvd0luZGV4KSA/XG4gICAgICB0aGlzLnNlbGVjdGVkQ2hlY2tib3hlcy5kZWxldGUocm93SW5kZXgpIDpcbiAgICAgIHRoaXMuc2VsZWN0ZWRDaGVja2JveGVzLmFkZChyb3dJbmRleCk7XG4gIH1cblxuICBjb2xsYXBzZVJvdyhyb3dJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWREZXRhaWxzVGVtcGxhdGVSb3dJZC5oYXMocm93SW5kZXgpKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGV0YWlsc1RlbXBsYXRlUm93SWQuZGVsZXRlKHJvd0luZGV4KTtcbiAgICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uUm93Q29sbGFwc2VkSGlkZSwgcm93SW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGV0YWlsc1RlbXBsYXRlUm93SWQuYWRkKHJvd0luZGV4KTtcbiAgICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uUm93Q29sbGFwc2VkU2hvdywgcm93SW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZG9EZWNvZGVQZXJzaXN0ZWRTdGF0ZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnLnBlcnNpc3RTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwYWdpbmF0aW9uID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oRXZlbnQub25QYWdpbmF0aW9uKTtcbiAgICBjb25zdCBzb3J0ID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oRXZlbnQub25PcmRlcik7XG4gICAgY29uc3Qgc2VhcmNoID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oRXZlbnQub25TZWFyY2gpO1xuICAgIGlmIChwYWdpbmF0aW9uKSB7XG4gICAgICB0aGlzLm9uUGFnaW5hdGlvbihKU09OLnBhcnNlKHBhZ2luYXRpb24pKTtcbiAgICB9XG4gICAgaWYgKHNvcnQpIHtcbiAgICAgIGNvbnN0IHsga2V5LCBvcmRlciB9ID0gSlNPTi5wYXJzZShzb3J0KTtcbiAgICAgIHRoaXMuYmluZEFwaSh7XG4gICAgICAgIHR5cGU6IEFQSS5zb3J0QnksXG4gICAgICAgIHZhbHVlOiB7IGNvbHVtbjoga2V5LCBvcmRlciB9LFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChzZWFyY2gpIHtcbiAgICAgIHRoaXMuYmluZEFwaSh7XG4gICAgICAgIHR5cGU6IEFQSS5zZXRJbnB1dFZhbHVlLFxuICAgICAgICB2YWx1ZTogSlNPTi5wYXJzZShzZWFyY2gpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgaXNSb3dDb2xsYXBzZWQocm93SW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmNvbmZpZy5jb2xsYXBzZUFsbFJvd3MpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZERldGFpbHNUZW1wbGF0ZVJvd0lkLmhhcyhyb3dJbmRleCk7XG4gIH1cblxuICBnZXQgaXNMb2FkaW5nKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHRhYmxlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5pZCkgYXMgSFRNTFRhYmxlRWxlbWVudDtcbiAgICBpZiAodGFibGUgJiYgdGFibGUucm93cyAmJiB0YWJsZS5yb3dzLmxlbmd0aCA+IDMpIHtcbiAgICAgIHRoaXMuZ2V0TG9hZGluZ0hlaWdodCh0YWJsZS5yb3dzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmlzTG9hZGluZztcbiAgfVxuXG4gIGdldExvYWRpbmdIZWlnaHQocm93czogYW55KTogdm9pZCB7XG4gICAgY29uc3Qgc2VhcmNoRW5hYmxlZCA9IHRoaXMuY29uZmlnLnNlYXJjaEVuYWJsZWQgPyAxIDogMDtcbiAgICBjb25zdCBoZWFkZXJFbmFibGVkID0gdGhpcy5jb25maWcuaGVhZGVyRW5hYmxlZCA/IDEgOiAwO1xuICAgIGNvbnN0IGJvcmRlclRySGVpZ2h0ID0gMTtcbiAgICBjb25zdCBib3JkZXJEaXZIZWlnaHQgPSAyO1xuICAgIHRoaXMubG9hZGluZ0hlaWdodCA9IChyb3dzLmxlbmd0aCAtIHNlYXJjaEVuYWJsZWQgLSBoZWFkZXJFbmFibGVkKSAqIChyb3dzWzNdLm9mZnNldEhlaWdodCAtIGJvcmRlclRySGVpZ2h0KSAtIGJvcmRlckRpdkhlaWdodCArICdweCc7XG4gIH1cblxuICBnZXQgYXJyb3dEZWZpbml0aW9uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5zaG93RGV0YWlsc0Fycm93IHx8IHR5cGVvZiB0aGlzLmNvbmZpZy5zaG93RGV0YWlsc0Fycm93ID09PSAndW5kZWZpbmVkJztcbiAgfVxuXG4gIG9uUm93Q29udGV4dE1lbnUoJGV2ZW50OiBNb3VzZUV2ZW50LCByb3c6IG9iamVjdCwga2V5OiBDb2x1bW5LZXlUeXBlLCBjb2xJbmRleDogYW55LCByb3dJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZy5zaG93Q29udGV4dE1lbnUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3QgdmFsdWUgPSB7XG4gICAgICBldmVudDogJGV2ZW50LFxuICAgICAgcm93LFxuICAgICAga2V5LFxuICAgICAgcm93SWQ6IHJvd0luZGV4LFxuICAgICAgY29sSWQ6IGNvbEluZGV4LFxuICAgIH07XG4gICAgdGhpcy5yb3dDb250ZXh0TWVudVBvc2l0aW9uID0ge1xuICAgICAgdG9wOiBgJHskZXZlbnQueSAtIDEwfXB4YCxcbiAgICAgIGxlZnQ6IGAkeyRldmVudC54IC0gMTB9cHhgLFxuICAgICAgdmFsdWUsXG4gICAgfTtcblxuICAgIHRoaXMuZW1pdEV2ZW50KEV2ZW50Lm9uUm93Q29udGV4dE1lbnUsIHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgZG9BcHBseURhdGEoZGF0YTogU2ltcGxlQ2hhbmdlKTogdm9pZCB7XG4gICAgY29uc3Qgb3JkZXIgPSB0aGlzLmNvbHVtbnMuZmluZCgoYykgPT4gISFjLm9yZGVyQnkpO1xuICAgIGlmIChvcmRlcikge1xuICAgICAgdGhpcy5zb3J0U3RhdGUuc2V0KHRoaXMuc29ydEtleSwgKG9yZGVyLm9yZGVyQnkgPT09ICdhc2MnKSA/ICdkZXNjJyA6ICdhc2MnKTtcbiAgICAgIHRoaXMub3JkZXJCeShvcmRlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGF0YSA9IFsuLi5kYXRhLmN1cnJlbnRWYWx1ZV07XG4gICAgfVxuICB9XG5cbiAgb25Ecm9wKGV2ZW50OiBDZGtEcmFnRHJvcDxzdHJpbmdbXT4pOiB2b2lkIHtcbiAgICB0aGlzLmVtaXRFdmVudChFdmVudC5vblJvd0Ryb3AsIGV2ZW50KTtcbiAgICBtb3ZlSXRlbUluQXJyYXkodGhpcy5kYXRhLCBldmVudC5wcmV2aW91c0luZGV4LCBldmVudC5jdXJyZW50SW5kZXgpO1xuICB9XG5cbiAgLy8gRE8gTk9UIFJFTU9WRS4gSXQgaXMgY2FsbGVkIGZyb20gcGFyZW50IGNvbXBvbmVudC4gU2VlIHNyYy9hcHAvZGVtby9hcGktZG9jL2FwaS1kb2MuY29tcG9uZW50LnRzXG4gIGFwaUV2ZW50KGV2ZW50OiBBcGlUeXBlKTogdm9pZCB8IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYmluZEFwaShldmVudCk7XG4gIH1cblxuICAvLyB0c2xpbnQ6ZGlzYWJsZTpuby1iaWctZnVuY3Rpb24gY29nbml0aXZlLWNvbXBsZXhpdHlcbiAgcHJpdmF0ZSBiaW5kQXBpKGV2ZW50OiBBcGlUeXBlKTogdm9pZCB8IG51bWJlciB7XG4gICAgc3dpdGNoIChldmVudC50eXBlKSB7XG4gICAgICBjYXNlIEFQSS5yb3dDb250ZXh0TWVudUNsaWNrZWQ6XG4gICAgICAgIHRoaXMucm93Q29udGV4dE1lbnVQb3NpdGlvbiA9IHtcbiAgICAgICAgICB0b3A6IG51bGwsXG4gICAgICAgICAgbGVmdDogbnVsbCxcbiAgICAgICAgICB2YWx1ZTogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEFQSS50b29sUGFuZWxDbGlja2VkOlxuICAgICAgICAvLyBUT0RPXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBUEkudG9nZ2xlUm93SW5kZXg6XG4gICAgICAgIHRoaXMuY29sbGFwc2VSb3coZXZlbnQudmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQVBJLnRvZ2dsZUNoZWNrYm94OlxuICAgICAgICB0aGlzLnRvZ2dsZUNoZWNrYm94KGV2ZW50LnZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEFQSS5zZXRJbnB1dFZhbHVlOlxuICAgICAgICBpZiAodGhpcy5jb25maWcuc2VhcmNoRW5hYmxlZCkge1xuICAgICAgICAgIGV2ZW50LnZhbHVlLmZvckVhY2goKGlucHV0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBzZWFyY2hfJHtpbnB1dC5rZXl9YCkgYXMgSFRNTElucHV0RWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQ29sdW1uICcke2lucHV0LmtleX0nIG5vdCBhdmFpbGFibGUgaW4gdGhlIERPTS4gSGF2ZSB5b3UgbWlzc3BlbGxlZCBhIG5hbWU/YCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBlbGVtZW50LnZhbHVlID0gaW5wdXQudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vblNlYXJjaChldmVudC52YWx1ZSk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEFQSS5vbkdsb2JhbFNlYXJjaDpcbiAgICAgICAgdGhpcy5vbkdsb2JhbFNlYXJjaChldmVudC52YWx1ZSk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEFQSS5zZXRSb3dDbGFzczpcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXZlbnQudmFsdWUpKSB7XG4gICAgICAgICAgZXZlbnQudmFsdWUuZm9yRWFjaCgodmFsKSA9PiB0aGlzLnN0eWxlU2VydmljZS5zZXRSb3dDbGFzcyh2YWwpKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0eWxlU2VydmljZS5zZXRSb3dDbGFzcyhldmVudC52YWx1ZSk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEFQSS5zZXRDZWxsQ2xhc3M6XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGV2ZW50LnZhbHVlKSkge1xuICAgICAgICAgIGV2ZW50LnZhbHVlLmZvckVhY2goKHZhbCkgPT4gdGhpcy5zdHlsZVNlcnZpY2Uuc2V0Q2VsbENsYXNzKHZhbCkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3R5bGVTZXJ2aWNlLnNldENlbGxDbGFzcyhldmVudC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBUEkuc2V0Um93U3R5bGU6XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGV2ZW50LnZhbHVlKSkge1xuICAgICAgICAgIGV2ZW50LnZhbHVlLmZvckVhY2goKHZhbCkgPT4gdGhpcy5zdHlsZVNlcnZpY2Uuc2V0Um93U3R5bGUodmFsKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHlsZVNlcnZpY2Uuc2V0Um93U3R5bGUoZXZlbnQudmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQVBJLnNldENlbGxTdHlsZTpcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZXZlbnQudmFsdWUpKSB7XG4gICAgICAgICAgZXZlbnQudmFsdWUuZm9yRWFjaCgodmFsKSA9PiB0aGlzLnN0eWxlU2VydmljZS5zZXRDZWxsU3R5bGUodmFsKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHlsZVNlcnZpY2Uuc2V0Q2VsbFN0eWxlKGV2ZW50LnZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEFQSS5zZXRUYWJsZUNsYXNzOlxuICAgICAgICB0aGlzLnRhYmxlQ2xhc3MgPSBldmVudC52YWx1ZTtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQVBJLmdldFBhZ2luYXRpb25Ub3RhbEl0ZW1zOlxuICAgICAgICByZXR1cm4gdGhpcy5wYWdpbmF0aW9uQ29tcG9uZW50LnBhZ2luYXRpb25EaXJlY3RpdmUuZ2V0VG90YWxJdGVtcygpO1xuICAgICAgY2FzZSBBUEkuZ2V0UGFnaW5hdGlvbkN1cnJlbnRQYWdlOlxuICAgICAgICByZXR1cm4gdGhpcy5wYWdpbmF0aW9uQ29tcG9uZW50LnBhZ2luYXRpb25EaXJlY3RpdmUuZ2V0Q3VycmVudCgpO1xuICAgICAgY2FzZSBBUEkuZ2V0UGFnaW5hdGlvbkxhc3RQYWdlOlxuICAgICAgICByZXR1cm4gdGhpcy5wYWdpbmF0aW9uQ29tcG9uZW50LnBhZ2luYXRpb25EaXJlY3RpdmUuZ2V0TGFzdFBhZ2UoKTtcbiAgICAgIGNhc2UgQVBJLmdldE51bWJlck9mUm93c1BlclBhZ2U6XG4gICAgICAgIHJldHVybiB0aGlzLnBhZ2luYXRpb25Db21wb25lbnQucGFnaW5hdGlvbkRpcmVjdGl2ZS5pc0xhc3RQYWdlKCkgP1xuICAgICAgICAgICh0aGlzLnBhZ2luYXRpb25Db21wb25lbnQucGFnaW5hdGlvbkRpcmVjdGl2ZS5nZXRUb3RhbEl0ZW1zKCkgJSB0aGlzLmxpbWl0KSA6XG4gICAgICAgICAgdGhpcy5saW1pdDtcbiAgICAgIGNhc2UgQVBJLnNldFBhZ2luYXRpb25DdXJyZW50UGFnZTpcbiAgICAgICAgdGhpcy5wYWdpbmF0aW9uQ29tcG9uZW50LnBhZ2luYXRpb25EaXJlY3RpdmUuc2V0Q3VycmVudChldmVudC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBUEkuc2V0UGFnaW5hdGlvblJhbmdlOlxuICAgICAgICB0aGlzLnBhZ2luYXRpb25Db21wb25lbnQucmFuZ2VzID0gZXZlbnQudmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBUEkuc2V0UGFnaW5hdGlvblByZXZpb3VzTGFiZWw6XG4gICAgICAgIHRoaXMucGFnaW5hdGlvbkNvbXBvbmVudC5wcmV2aW91c0xhYmVsID0gZXZlbnQudmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBUEkuc2V0UGFnaW5hdGlvbk5leHRMYWJlbDpcbiAgICAgICAgdGhpcy5wYWdpbmF0aW9uQ29tcG9uZW50Lm5leHRMYWJlbCA9IGV2ZW50LnZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQVBJLnNldFBhZ2luYXRpb25EaXNwbGF5TGltaXQ6XG4gICAgICAgIHRoaXMucGFnaW5hdGlvbkNvbXBvbmVudC5jaGFuZ2VMaW1pdChldmVudC52YWx1ZSwgdHJ1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBUEkuc29ydEJ5OlxuICAgICAgICBjb25zdCBjb2x1bW46IENvbHVtbnMgPSB7IHRpdGxlOiAnJywga2V5OiBldmVudC52YWx1ZS5jb2x1bW4sIG9yZGVyQnk6IGV2ZW50LnZhbHVlLm9yZGVyIH07XG4gICAgICAgIHRoaXMub3JkZXJCeShjb2x1bW4pO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXRDb2x1bW5PcmRlcihrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHN3aXRjaCAodGhpcy5zb3J0U3RhdGUuZ2V0KGtleSkpIHtcbiAgICAgIGNhc2UgJyc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgdGhpcy5zb3J0U3RhdGUuc2V0KGtleSwgJ2Rlc2MnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdhc2MnOlxuICAgICAgICB0aGlzLmNvbmZpZy50aHJlZVdheVNvcnQgP1xuICAgICAgICAgIHRoaXMuc29ydFN0YXRlLnNldChrZXksICcnKSA6XG4gICAgICAgICAgdGhpcy5zb3J0U3RhdGUuc2V0KGtleSwgJ2Rlc2MnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdkZXNjJzpcbiAgICAgICAgdGhpcy5zb3J0U3RhdGUuc2V0KGtleSwgJ2FzYycpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKHRoaXMuc29ydFN0YXRlLnNpemUgPiAxKSB7XG4gICAgICBjb25zdCB0ZW1wID0gdGhpcy5zb3J0U3RhdGUuZ2V0KGtleSk7XG4gICAgICB0aGlzLnNvcnRTdGF0ZS5jbGVhcigpO1xuICAgICAgdGhpcy5zb3J0U3RhdGUuc2V0KGtleSwgdGVtcCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGVtaXRFdmVudChldmVudDogc3RyaW5nLCB2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgdGhpcy5ldmVudC5lbWl0KHsgZXZlbnQsIHZhbHVlIH0pO1xuICAgIGlmICh0aGlzLmNvbmZpZy5wZXJzaXN0U3RhdGUpIHtcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGV2ZW50LCBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICAgIH1cbiAgICBpZiAodGhpcy5jb25maWcubG9nZ2VyKSB7XG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tY29uc29sZVxuICAgICAgY29uc29sZS5sb2coeyBldmVudCwgdmFsdWUgfSk7XG4gICAgfVxuICB9XG59XG4iXX0=