@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
510 lines • 69.4 kB
JavaScript
import { __decorate, __metadata, __values } from "tslib";
import { Injectable } from '@angular/core';
import { IgxIconService } from '../../icon/icon.service';
import { FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree';
import icons from './svgIcons';
import { FilteringLogic } from '../../data-operations/filtering-expression.interface';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { GridBaseAPIService } from '../api.service';
import { IgxDatePipeComponent } from '../common/pipes';
var FILTERING_ICONS_FONT_SET = 'filtering-icons';
/**
*@hidden
*/
var ExpressionUI = /** @class */ (function () {
function ExpressionUI() {
this.isSelected = false;
this.isVisible = true;
}
return ExpressionUI;
}());
export { ExpressionUI };
/**
*@hidden
*/
var IgxFilteringService = /** @class */ (function () {
function IgxFilteringService(gridAPI, iconService) {
this.gridAPI = gridAPI;
this.iconService = iconService;
this.columnsWithComplexFilter = new Set();
this.areEventsSubscribed = false;
this.destroy$ = new Subject();
this.isFiltering = false;
this.columnToExpressionsMap = new Map();
this.columnStartIndex = -1;
this._filterIconsRegistered = false;
this.isFilterRowVisible = false;
this.filteredColumn = null;
this.selectedExpression = null;
this.columnToFocus = null;
this.shouldFocusNext = false;
this.columnToMoreIconHidden = new Map();
}
IgxFilteringService.prototype.ngOnDestroy = function () {
this.destroy$.next(true);
this.destroy$.complete();
};
Object.defineProperty(IgxFilteringService.prototype, "displayContainerWidth", {
get: function () {
return parseInt(this.grid.parentVirtDir.dc.instance._viewContainer.element.nativeElement.offsetWidth, 10);
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxFilteringService.prototype, "displayContainerScrollLeft", {
get: function () {
return this.grid.headerContainer.scrollPosition;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxFilteringService.prototype, "areAllColumnsInView", {
get: function () {
return parseInt(this.grid.parentVirtDir.dc.instance._viewContainer.element.nativeElement.offsetWidth, 10) === 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxFilteringService.prototype, "unpinnedFilterableColumns", {
get: function () {
return this.grid.unpinnedColumns.filter(function (col) { return !col.columnGroup && col.filterable; });
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxFilteringService.prototype, "unpinnedColumns", {
get: function () {
return this.grid.unpinnedColumns.filter(function (col) { return !col.columnGroup; });
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxFilteringService.prototype, "datePipe", {
get: function () {
if (!this._datePipe) {
this._datePipe = new IgxDatePipeComponent(this.grid.locale);
}
return this._datePipe;
},
enumerable: true,
configurable: true
});
/**
* Subscribe to grid's events.
*/
IgxFilteringService.prototype.subscribeToEvents = function () {
var _this = this;
if (!this.areEventsSubscribed) {
this.areEventsSubscribed = true;
this.grid.onColumnResized.pipe(takeUntil(this.destroy$)).subscribe(function (eventArgs) {
_this.updateFilteringCell(eventArgs.column);
});
this.grid.parentVirtDir.onChunkLoad.pipe(takeUntil(this.destroy$)).subscribe(function (eventArgs) {
if (eventArgs.startIndex !== _this.columnStartIndex) {
_this.columnStartIndex = eventArgs.startIndex;
_this.grid.filterCellList.forEach(function (filterCell) {
filterCell.updateFilterCellArea();
});
}
if (_this.columnToFocus) {
_this.focusFilterCellChip(_this.columnToFocus, false);
_this.columnToFocus = null;
}
});
this.grid.onColumnMovingEnd.pipe(takeUntil(this.destroy$)).subscribe(function () {
_this.grid.filterCellList.forEach(function (filterCell) {
filterCell.updateFilterCellArea();
});
});
this.grid.onColumnVisibilityChanged.pipe(takeUntil(this.destroy$)).subscribe(function (eventArgs) {
if (_this.grid.filteringRow && _this.grid.filteringRow.column === eventArgs.column) {
_this.grid.filteringRow.close();
}
});
}
};
/**
* Internal method to create expressionsTree and filter grid used in both filter modes.
*/
IgxFilteringService.prototype.filterInternal = function (field, expressions) {
if (expressions === void 0) { expressions = null; }
this.isFiltering = true;
var expressionsTree;
if (expressions instanceof FilteringExpressionsTree) {
expressionsTree = expressions;
}
else {
expressionsTree = this.createSimpleFilteringTree(field, expressions);
}
if (expressionsTree.filteringOperands.length === 0) {
this.clearFilter(field);
}
else {
this.filter(field, null, expressionsTree);
}
this.isFiltering = false;
};
/**
* Execute filtering on the grid.
*/
IgxFilteringService.prototype.filter = function (field, value, conditionOrExpressionTree, ignoreCase) {
var _this = this;
var col = this.gridAPI.get_column_by_name(field);
var filteringIgnoreCase = ignoreCase || (col ? col.filteringIgnoreCase : false);
if (conditionOrExpressionTree) {
this.gridAPI.filter(field, value, conditionOrExpressionTree, filteringIgnoreCase);
}
else {
var expressionsTreeForColumn = this.grid.filteringExpressionsTree.find(field);
if (!expressionsTreeForColumn) {
throw new Error('Invalid condition or Expression Tree!');
}
else if (expressionsTreeForColumn instanceof FilteringExpressionsTree) {
this.gridAPI.filter(field, value, expressionsTreeForColumn, filteringIgnoreCase);
}
else {
var expressionForColumn = expressionsTreeForColumn;
this.gridAPI.filter(field, value, expressionForColumn.condition, filteringIgnoreCase);
}
}
// Wait for the change detection to update filtered data through the pipes and then emit the event.
requestAnimationFrame(function () { return _this.grid.onFilteringDone.emit(col.filteringExpressionsTree); });
};
/**
* Clear the filter of a given column.
*/
IgxFilteringService.prototype.clearFilter = function (field) {
var _this = this;
if (field) {
var column = this.gridAPI.get_column_by_name(field);
if (!column) {
return;
}
}
this.isFiltering = true;
this.gridAPI.clear_filter(field);
// Wait for the change detection to update filtered data through the pipes and then emit the event.
requestAnimationFrame(function () { return _this.grid.onFilteringDone.emit(null); });
if (field) {
var expressions = this.getExpressions(field);
expressions.length = 0;
}
this.isFiltering = false;
};
/**
* Filters all the `IgxColumnComponent` in the `IgxGridComponent` with the same condition.
*/
IgxFilteringService.prototype.filterGlobal = function (value, condition, ignoreCase) {
var _this = this;
this.gridAPI.filter_global(value, condition, ignoreCase);
// Wait for the change detection to update filtered data through the pipes and then emit the event.
requestAnimationFrame(function () { return _this.grid.onFilteringDone.emit(_this.grid.filteringExpressionsTree); });
};
/**
* Register filtering SVG icons in the icon service.
*/
IgxFilteringService.prototype.registerSVGIcons = function () {
var e_1, _a;
if (!this._filterIconsRegistered) {
try {
for (var icons_1 = __values(icons), icons_1_1 = icons_1.next(); !icons_1_1.done; icons_1_1 = icons_1.next()) {
var icon = icons_1_1.value;
if (!this.iconService.isSvgIconCached(icon.name, FILTERING_ICONS_FONT_SET)) {
this.iconService.addSvgIconFromText(icon.name, icon.value, FILTERING_ICONS_FONT_SET);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (icons_1_1 && !icons_1_1.done && (_a = icons_1.return)) _a.call(icons_1);
}
finally { if (e_1) throw e_1.error; }
}
this._filterIconsRegistered = true;
}
};
/**
* Returns the ExpressionUI array for a given column.
*/
IgxFilteringService.prototype.getExpressions = function (columnId) {
if (!this.columnToExpressionsMap.has(columnId)) {
var column = this.grid.columns.find(function (col) { return col.field === columnId; });
var expressionUIs = new Array();
if (column) {
this.generateExpressionsList(column.filteringExpressionsTree, this.grid.filteringExpressionsTree.operator, expressionUIs);
this.columnToExpressionsMap.set(columnId, expressionUIs);
}
return expressionUIs;
}
return this.columnToExpressionsMap.get(columnId);
};
/**
* Recreates all ExpressionUIs for all columns. Executed after filtering to refresh the cache.
*/
IgxFilteringService.prototype.refreshExpressions = function () {
var _this = this;
if (!this.isFiltering) {
this.columnsWithComplexFilter.clear();
this.columnToExpressionsMap.forEach(function (value, key) {
var column = _this.grid.columns.find(function (col) { return col.field === key; });
if (column) {
value.length = 0;
_this.generateExpressionsList(column.filteringExpressionsTree, _this.grid.filteringExpressionsTree.operator, value);
var isComplex = _this.isFilteringTreeComplex(column.filteringExpressionsTree);
if (isComplex) {
_this.columnsWithComplexFilter.add(key);
}
_this.updateFilteringCell(column);
}
else {
_this.columnToExpressionsMap.delete(key);
}
});
}
};
/**
* Remove an ExpressionUI for a given column.
*/
IgxFilteringService.prototype.removeExpression = function (columnId, indexToRemove) {
var expressionsList = this.getExpressions(columnId);
if (indexToRemove === 0 && expressionsList.length > 1) {
expressionsList[1].beforeOperator = null;
}
else if (indexToRemove === expressionsList.length - 1) {
expressionsList[indexToRemove - 1].afterOperator = null;
}
else {
expressionsList[indexToRemove - 1].afterOperator = expressionsList[indexToRemove + 1].beforeOperator;
expressionsList[0].beforeOperator = null;
expressionsList[expressionsList.length - 1].afterOperator = null;
}
expressionsList.splice(indexToRemove, 1);
};
/**
* Generate filtering tree for a given column from existing ExpressionUIs.
*/
IgxFilteringService.prototype.createSimpleFilteringTree = function (columnId, expressionUIList) {
if (expressionUIList === void 0) { expressionUIList = null; }
var expressionsList = expressionUIList ? expressionUIList : this.getExpressions(columnId);
var expressionsTree = new FilteringExpressionsTree(FilteringLogic.Or, columnId);
var currAndBranch;
var currExpressionUI;
for (var i = 0; i < expressionsList.length; i++) {
currExpressionUI = expressionsList[i];
if (!currExpressionUI.expression.condition.isUnary && currExpressionUI.expression.searchVal === null) {
if (currExpressionUI.afterOperator === FilteringLogic.And && !currAndBranch) {
currAndBranch = new FilteringExpressionsTree(FilteringLogic.And, columnId);
expressionsTree.filteringOperands.push(currAndBranch);
}
continue;
}
if ((currExpressionUI.beforeOperator === undefined || currExpressionUI.beforeOperator === null ||
currExpressionUI.beforeOperator === FilteringLogic.Or) &&
currExpressionUI.afterOperator === FilteringLogic.And) {
currAndBranch = new FilteringExpressionsTree(FilteringLogic.And, columnId);
expressionsTree.filteringOperands.push(currAndBranch);
currAndBranch.filteringOperands.push(currExpressionUI.expression);
}
else if (currExpressionUI.beforeOperator === FilteringLogic.And) {
currAndBranch.filteringOperands.push(currExpressionUI.expression);
}
else {
expressionsTree.filteringOperands.push(currExpressionUI.expression);
currAndBranch = null;
}
}
return expressionsTree;
};
/**
* Returns whether a complex filter is applied to a given column.
*/
IgxFilteringService.prototype.isFilterComplex = function (columnId) {
if (this.columnsWithComplexFilter.has(columnId)) {
return true;
}
var column = this.grid.columns.find(function (col) { return col.field === columnId; });
var isComplex = column && this.isFilteringTreeComplex(column.filteringExpressionsTree);
if (isComplex) {
this.columnsWithComplexFilter.add(columnId);
}
return isComplex;
};
/**
* Returns the string representation of the FilteringLogic operator.
*/
IgxFilteringService.prototype.getOperatorAsString = function (operator) {
if (operator === 0) {
return this.grid.resourceStrings.igx_grid_filter_operator_and;
}
else {
return this.grid.resourceStrings.igx_grid_filter_operator_or;
}
};
/**
* Generate the label of a chip from a given filtering expression.
*/
IgxFilteringService.prototype.getChipLabel = function (expression) {
if (expression.condition.isUnary) {
return this.grid.resourceStrings["igx_grid_filter_" + expression.condition.name] || expression.condition.name;
}
else if (expression.searchVal instanceof Date) {
return this.datePipe.transform(expression.searchVal, this.grid.locale);
}
else {
return expression.searchVal;
}
};
/**
* Updates the content of a filterCell.
*/
IgxFilteringService.prototype.updateFilteringCell = function (column) {
var filterCell = column.filterCell;
if (filterCell) {
filterCell.updateFilterCellArea();
}
};
/**
* Focus a chip in a filterCell.
*/
IgxFilteringService.prototype.focusFilterCellChip = function (column, focusFirst) {
var filterCell = column.filterCell;
if (filterCell) {
filterCell.focusChip(focusFirst);
}
};
/**
* Focus the close button in the filtering row.
*/
IgxFilteringService.prototype.focusFilterRowCloseButton = function () {
this.grid.filteringRow.closeButton.nativeElement.focus();
};
Object.defineProperty(IgxFilteringService.prototype, "filteredData", {
get: function () {
return this.grid.filteredData;
},
enumerable: true,
configurable: true
});
/**
* Scrolls to a filterCell.
*/
IgxFilteringService.prototype.scrollToFilterCell = function (column, shouldFocusNext) {
this.grid.nativeElement.focus({ preventScroll: true });
this.columnToFocus = column;
this.shouldFocusNext = shouldFocusNext;
var currentColumnRight = 0;
var currentColumnLeft = 0;
for (var index = 0; index < this.unpinnedColumns.length; index++) {
currentColumnRight += parseInt(this.unpinnedColumns[index].width, 10);
if (this.unpinnedColumns[index] === column) {
currentColumnLeft = currentColumnRight - parseInt(this.unpinnedColumns[index].width, 10);
break;
}
}
var forOfDir = this.grid.headerContainer;
var width = this.displayContainerWidth + this.displayContainerScrollLeft;
if (shouldFocusNext) {
forOfDir.scrollPosition += currentColumnRight - width;
}
else {
forOfDir.scrollPosition = currentColumnLeft;
}
};
IgxFilteringService.prototype.isFilteringTreeComplex = function (expressions) {
if (!expressions) {
return false;
}
if (expressions instanceof FilteringExpressionsTree) {
var expressionsTree = expressions;
if (expressionsTree.operator === FilteringLogic.Or) {
var andOperatorsCount = this.getChildAndOperatorsCount(expressionsTree);
// having more that 'And' and operator in the sub-tree means that the filter could not be represented without parentheses.
return andOperatorsCount > 1;
}
var isComplex = false;
for (var i = 0; i < expressionsTree.filteringOperands.length; i++) {
isComplex = isComplex || this.isFilteringTreeComplex(expressionsTree.filteringOperands[i]);
}
return isComplex;
}
return false;
};
IgxFilteringService.prototype.getChildAndOperatorsCount = function (expressions) {
var count = 0;
var operand;
for (var i = 0; i < expressions.filteringOperands.length; i++) {
operand = expressions[i];
if (operand instanceof FilteringExpressionsTree) {
if (operand.operator === FilteringLogic.And) {
count++;
}
count = count + this.getChildAndOperatorsCount(operand);
}
}
return count;
};
IgxFilteringService.prototype.generateExpressionsList = function (expressions, operator, expressionsUIs) {
this.generateExpressionsListRecursive(expressions, operator, expressionsUIs);
// The beforeOperator of the first expression and the afterOperator of the last expression should be null
if (expressionsUIs.length) {
expressionsUIs[expressionsUIs.length - 1].afterOperator = null;
}
};
IgxFilteringService.prototype.generateExpressionsListRecursive = function (expressions, operator, expressionsUIs) {
if (!expressions) {
return;
}
if (expressions instanceof FilteringExpressionsTree) {
var expressionsTree = expressions;
for (var i = 0; i < expressionsTree.filteringOperands.length; i++) {
this.generateExpressionsListRecursive(expressionsTree.filteringOperands[i], expressionsTree.operator, expressionsUIs);
}
if (expressionsUIs.length) {
expressionsUIs[expressionsUIs.length - 1].afterOperator = operator;
}
}
else {
var exprUI = new ExpressionUI();
exprUI.expression = expressions;
exprUI.afterOperator = operator;
var prevExprUI = expressionsUIs[expressionsUIs.length - 1];
if (prevExprUI) {
exprUI.beforeOperator = prevExprUI.afterOperator;
}
expressionsUIs.push(exprUI);
}
};
IgxFilteringService.prototype.isFilteringExpressionsTreeEmpty = function () {
var expressionTree = this.grid.filteringExpressionsTree;
if (FilteringExpressionsTree.empty(expressionTree)) {
return true;
}
var expr;
for (var i = 0; i < expressionTree.filteringOperands.length; i++) {
expr = expressionTree.filteringOperands[i];
if ((expr instanceof FilteringExpressionsTree)) {
var exprTree = expr;
if (exprTree.filteringOperands && exprTree.filteringOperands.length) {
return false;
}
}
else {
return false;
}
}
return true;
};
IgxFilteringService.ctorParameters = function () { return [
{ type: GridBaseAPIService },
{ type: IgxIconService }
]; };
IgxFilteringService = __decorate([
Injectable(),
__metadata("design:paramtypes", [GridBaseAPIService, IgxIconService])
], IgxFilteringService);
return IgxFilteringService;
}());
export { IgxFilteringService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC1maWx0ZXJpbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZ3JpZHMvZmlsdGVyaW5nL2dyaWQtZmlsdGVyaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDdEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSx3QkFBd0IsRUFBNkIsTUFBTSxrREFBa0QsQ0FBQztBQUV2SCxPQUFPLEtBQUssTUFBTSxZQUFZLENBQUM7QUFDL0IsT0FBTyxFQUF3QixjQUFjLEVBQUUsTUFBTSxzREFBc0QsQ0FBQztBQUM1RyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUkzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUlwRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUV2RCxJQUFNLHdCQUF3QixHQUFHLGlCQUFpQixDQUFDO0FBRW5EOztHQUVHO0FBQ0g7SUFBQTtRQUlXLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsY0FBUyxHQUFHLElBQUksQ0FBQztJQUM1QixDQUFDO0lBQUQsbUJBQUM7QUFBRCxDQUFDLEFBTkQsSUFNQzs7QUFFRDs7R0FFRztBQUVIO0lBcUJJLDZCQUFvQixPQUE0RCxFQUFVLFdBQTJCO1FBQWpHLFlBQU8sR0FBUCxPQUFPLENBQXFEO1FBQVUsZ0JBQVcsR0FBWCxXQUFXLENBQWdCO1FBbkI3Ryw2QkFBd0IsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBQzdDLHdCQUFtQixHQUFHLEtBQUssQ0FBQztRQUM1QixhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FB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QyxDQUFDLENBQUM7WUFFM0MsSUFBSSxDQUFDLElBQUksWUFBWSx3QkFBd0IsQ0FBQyxFQUFFO2dCQUM1QyxJQUFNLFFBQVEsR0FBRyxJQUFnQyxDQUFDO2dCQUNsRCxJQUFJLFFBQVEsQ0FBQyxpQkFBaUIsSUFBSSxRQUFRLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFO29CQUNqRSxPQUFPLEtBQUssQ0FBQztpQkFDaEI7YUFDSjtpQkFBTTtnQkFDSCxPQUFPLEtBQUssQ0FBQzthQUNoQjtTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQzs7Z0JBM2Q0QixrQkFBa0I7Z0JBQXdELGNBQWM7O0lBckI1RyxtQkFBbUI7UUFEL0IsVUFBVSxFQUFFO3lDQXNCb0Isa0JBQWtCLEVBQXdELGNBQWM7T0FyQjVHLG1CQUFtQixDQWlmL0I7SUFBRCwwQkFBQztDQUFBLEFBamZELElBaWZDO1NBamZZLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSWd4SWNvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9pY29uL2ljb24uc2VydmljZSc7XG5pbXBvcnQgeyBGaWx0ZXJpbmdFeHByZXNzaW9uc1RyZWUsIElGaWx0ZXJpbmdFeHByZXNzaW9uc1RyZWUgfSBmcm9tICcuLi8uLi9kYXRhLW9wZXJhdGlvbnMvZmlsdGVyaW5nLWV4cHJlc3Npb25zLXRyZWUnO1xuaW1wb3J0IHsgSWd4R3JpZEJhc2VEaXJlY3RpdmUgfSBmcm9tICcuLi9ncmlkLWJhc2UuZGlyZWN0aXZlJztcbmltcG9ydCBpY29ucyBmcm9tICcuL3N2Z0ljb25zJztcbmltcG9ydCB7IElGaWx0ZXJpbmdFeHByZXNzaW9uLCBGaWx0ZXJpbmdMb2dpYyB9IGZyb20gJy4uLy4uL2RhdGEtb3BlcmF0aW9ucy9maWx0ZXJpbmctZXhwcmVzc2lvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgSUZvck9mU3RhdGUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2Zvci1vZi9mb3Jfb2YuZGlyZWN0aXZlJztcbmltcG9ydCB7IElneENvbHVtbkNvbXBvbmVudCB9IGZyb20gJy4uL2NvbHVtbnMvY29sdW1uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJRmlsdGVyaW5nT3BlcmF0aW9uIH0gZnJvbSAnLi4vLi4vZGF0YS1vcGVyYXRpb25zL2ZpbHRlcmluZy1jb25kaXRpb24nO1xuaW1wb3J0IHsgR3JpZEJhc2VBUElTZXJ2aWNlIH0gZnJvbSAnLi4vYXBpLnNlcnZpY2UnO1xuaW1wb3J0IHsgSUNvbHVtblZpc2liaWxpdHlDaGFuZ2VkRXZlbnRBcmdzIH0gZnJvbSAnLi4vZ3JpZCc7XG5pbXBvcnQgeyBJQ29sdW1uUmVzaXplRXZlbnRBcmdzIH0gZnJvbSAnLi4vY29tbW9uL2V2ZW50cyc7XG5pbXBvcnQgeyBHcmlkVHlwZSB9IGZyb20gJy4uL2NvbW1vbi9ncmlkLmludGVyZmFjZSc7XG5pbXBvcnQgeyBJZ3hEYXRlUGlwZUNvbXBvbmVudCB9IGZyb20gJy4uL2NvbW1vbi9waXBlcyc7XG5cbmNvbnN0IEZJTFRFUklOR19JQ09OU19GT05UX1NFVCA9ICdmaWx0ZXJpbmctaWNvbnMnO1xuXG4vKipcbiAqQGhpZGRlblxuICovXG5leHBvcnQgY2xhc3MgRXhwcmVzc2lvblVJIHtcbiAgICBwdWJsaWMgZXhwcmVzc2lvbjogSUZpbHRlcmluZ0V4cHJlc3Npb247XG4gICAgcHVibGljIGJlZm9yZU9wZXJhdG9yOiBGaWx0ZXJpbmdMb2dpYztcbiAgICBwdWJsaWMgYWZ0ZXJPcGVyYXRvcjogRmlsdGVyaW5nTG9naWM7XG4gICAgcHVibGljIGlzU2VsZWN0ZWQgPSBmYWxzZTtcbiAgICBwdWJsaWMgaXNWaXNpYmxlID0gdHJ1ZTtcbn1cblxuLyoqXG4gKkBoaWRkZW5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIElneEZpbHRlcmluZ1NlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuXG4gICAgcHJpdmF0ZSBjb2x1bW5zV2l0aENvbXBsZXhGaWx0ZXIgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIGFyZUV2ZW50c1N1YnNjcmliZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgICBwcml2YXRlIGlzRmlsdGVyaW5nID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBjb2x1bW5Ub0V4cHJlc3Npb25zTWFwID0gbmV3IE1hcDxzdHJpbmcsIEV4cHJlc3Npb25VSVtdPigpO1xuICAgIHByaXZhdGUgX2RhdGVQaXBlOiBJZ3hEYXRlUGlwZUNvbXBvbmVudDtcbiAgICBwcml2YXRlIGNvbHVtblN0YXJ0SW5kZXggPSAtMTtcbiAgICBwcml2YXRlIF9maWx0ZXJJY29uc1JlZ2lzdGVyZWQgPSBmYWxzZTtcblxuICAgIHB1YmxpYyBncmlkSWQ6IHN0cmluZztcbiAgICBwdWJsaWMgaXNGaWx0ZXJSb3dWaXNpYmxlID0gZmFsc2U7XG4gICAgcHVibGljIGZpbHRlcmVkQ29sdW1uOiBJZ3hDb2x1bW5Db21wb25lbnQgPSBudWxsO1xuICAgIHB1YmxpYyBzZWxlY3RlZEV4cHJlc3Npb246IElGaWx0ZXJpbmdFeHByZXNzaW9uID0gbnVsbDtcbiAgICBwdWJsaWMgY29sdW1uVG9Gb2N1czogSWd4Q29sdW1uQ29tcG9uZW50ID0gbnVsbDtcbiAgICBwdWJsaWMgc2hvdWxkRm9jdXNOZXh0ID0gZmFsc2U7XG4gICAgcHVibGljIGNvbHVtblRvTW9yZUljb25IaWRkZW4gPSBuZXcgTWFwPHN0cmluZywgYm9vbGVhbj4oKTtcblxuICAgIGdyaWQ6IElneEdyaWRCYXNlRGlyZWN0aXZlO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBncmlkQVBJOiBHcmlkQmFzZUFQSVNlcnZpY2U8SWd4R3JpZEJhc2VEaXJlY3RpdmUgJiBHcmlkVHlwZT4sIHByaXZhdGUgaWNvblNlcnZpY2U6IElneEljb25TZXJ2aWNlKSB7fVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGVzdHJveSQubmV4dCh0cnVlKTtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgZGlzcGxheUNvbnRhaW5lcldpZHRoKCkge1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5ncmlkLnBhcmVudFZpcnREaXIuZGMuaW5zdGFuY2UuX3ZpZXdDb250YWluZXIuZWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoLCAxMCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBkaXNwbGF5Q29udGFpbmVyU2Nyb2xsTGVmdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZC5oZWFkZXJDb250YWluZXIuc2Nyb2xsUG9zaXRpb247XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBhcmVBbGxDb2x1bW5zSW5WaWV3KCkge1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5ncmlkLnBhcmVudFZpcnREaXIuZGMuaW5zdGFuY2UuX3ZpZXdDb250YWluZXIuZWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoLCAxMCkgPT09IDA7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCB1bnBpbm5lZEZpbHRlcmFibGVDb2x1bW5zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncmlkLnVucGlubmVkQ29sdW1ucy5maWx0ZXIoY29sID0+ICFjb2wuY29sdW1uR3JvdXAgJiYgY29sLmZpbHRlcmFibGUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgdW5waW5uZWRDb2x1bW5zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncmlkLnVucGlubmVkQ29sdW1ucy5maWx0ZXIoY29sID0+ICFjb2wuY29sdW1uR3JvdXApO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgZGF0ZVBpcGUoKTogSWd4RGF0ZVBpcGVDb21wb25lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX2RhdGVQaXBlKSB7XG4gICAgICAgICAgICB0aGlzLl9kYXRlUGlwZSA9IG5ldyBJZ3hEYXRlUGlwZUNvbXBvbmVudCh0aGlzLmdyaWQubG9jYWxlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0ZVBpcGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJlIHRvIGdyaWQncyBldmVudHMuXG4gICAgICovXG4gICAgcHVibGljIHN1YnNjcmliZVRvRXZlbnRzKCkge1xuICAgICAgICBpZiAoIXRoaXMuYXJlRXZlbnRzU3Vic2NyaWJlZCkge1xuICAgICAgICAgICAgdGhpcy5hcmVFdmVudHNTdWJzY3JpYmVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgdGhpcy5ncmlkLm9uQ29sdW1uUmVzaXplZC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChldmVudEFyZ3M6IElDb2x1bW5SZXNpemVFdmVudEFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUZpbHRlcmluZ0NlbGwoZXZlbnRBcmdzLmNvbHVtbik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5ncmlkLnBhcmVudFZpcnREaXIub25DaHVua0xvYWQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoZXZlbnRBcmdzOiBJRm9yT2ZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChldmVudEFyZ3Muc3RhcnRJbmRleCAhPT0gdGhpcy5jb2x1bW5TdGFydEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uU3RhcnRJbmRleCA9IGV2ZW50QXJncy5zdGFydEluZGV4O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdyaWQuZmlsdGVyQ2VsbExpc3QuZm9yRWFjaCgoZmlsdGVyQ2VsbCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyQ2VsbC51cGRhdGVGaWx0ZXJDZWxsQXJlYSgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29sdW1uVG9Gb2N1cykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvY3VzRmlsdGVyQ2VsbENoaXAodGhpcy5jb2x1bW5Ub0ZvY3VzLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uVG9Gb2N1cyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRoaXMuZ3JpZC5vbkNvbHVtbk1vdmluZ0VuZC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdyaWQuZmlsdGVyQ2VsbExpc3QuZm9yRWFjaCgoZmlsdGVyQ2VsbCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBmaWx0ZXJDZWxsLnVwZGF0ZUZpbHRlckNlbGxBcmVhKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5ncmlkLm9uQ29sdW1uVmlzaWJpbGl0eUNoYW5nZWQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoZXZlbnRBcmdzOiBJQ29sdW1uVmlzaWJpbGl0eUNoYW5nZWRFdmVudEFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5ncmlkLmZpbHRlcmluZ1JvdyAmJiB0aGlzLmdyaWQuZmlsdGVyaW5nUm93LmNvbHVtbiA9PT0gZXZlbnRBcmdzLmNvbHVtbiApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ncmlkLmZpbHRlcmluZ1Jvdy5jbG9zZSgpO1xuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBtZXRob2QgdG8gY3JlYXRlIGV4cHJlc3Npb25zVHJlZSBhbmQgZmlsdGVyIGdyaWQgdXNlZCBpbiBib3RoIGZpbHRlciBtb2Rlcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgZmlsdGVySW50ZXJuYWwoZmllbGQ6IHN0cmluZywgZXhwcmVzc2lvbnM6IEZpbHRlcmluZ0V4cHJlc3Npb25zVHJlZSB8IEFycmF5PEV4cHJlc3Npb25VST4gPSBudWxsKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNGaWx0ZXJpbmcgPSB0cnVlO1xuXG4gICAgICAgIGxldCBleHByZXNzaW9uc1RyZWU7XG4gICAgICAgIGlmIChleHByZXNzaW9ucyBpbnN0YW5jZW9mIEZpbHRlcmluZ0V4cHJlc3Npb25zVHJlZSkge1xuICAgICAgICAgICAgZXhwcmVzc2lvbnNUcmVlID0gZXhwcmVzc2lvbnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHByZXNzaW9uc1RyZWUgPSB0aGlzLmNyZWF0ZVNpbXBsZUZpbHRlcmluZ1RyZWUoZmllbGQsIGV4cHJlc3Npb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChleHByZXNzaW9uc1RyZWUuZmlsdGVyaW5nT3BlcmFuZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmNsZWFyRmlsdGVyKGZpZWxkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZmlsdGVyKGZpZWxkLCBudWxsLCBleHByZXNzaW9uc1RyZWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pc0ZpbHRlcmluZyA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGUgZmlsdGVyaW5nIG9uIHRoZSBncmlkLlxuICAgICAqL1xuICAgIHB1YmxpYyBmaWx0ZXIoZmllbGQ6IHN0cmluZywgdmFsdWU6IGFueSwgY29uZGl0aW9uT3JFeHByZXNzaW9uVHJlZT86IElGaWx0ZXJpbmdPcGVyYXRpb24gfCBJRmlsdGVyaW5nRXhwcmVzc2lvbnNUcmVlLFxuICAgICAgICBpZ25vcmVDYXNlPzogYm9vbGVhbikge1xuICAgICAgICBjb25zdCBjb2wgPSB0aGlzLmdyaWRBUEkuZ2V0X2NvbHVtbl9ieV9uYW1lKGZpZWxkKTtcbiAgICAgICAgY29uc3QgZmlsdGVyaW5nSWdub3JlQ2FzZSA9IGlnbm9yZUNhc2UgfHwgKGNvbCA/IGNvbC5maWx0ZXJpbmdJZ25vcmVDYXNlIDogZmFsc2UpO1xuXG4gICAgICAgIGlmIChjb25kaXRpb25PckV4cHJlc3Npb25UcmVlKSB7XG4gICAgICAgICAgICB0aGlzLmdyaWRBUEkuZmlsdGVyKGZpZWxkLCB2YWx1ZSwgY29uZGl0aW9uT3JFeHByZXNzaW9uVHJlZSwgZmlsdGVyaW5nSWdub3JlQ2FzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBleHByZXNzaW9uc1RyZWVGb3JDb2x1bW4gPSB0aGlzLmdyaWQuZmlsdGVyaW5nRX