UNPKG

igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

667 lines • 69.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ 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 { IgxGridSortingPipe } from '../grid/grid.pipes'; import { IgxDatePipeComponent } from '../grid.common'; import { GridBaseAPIService } from '../api.service'; /** @type {?} */ const FILTERING_ICONS_FONT_SET = 'filtering-icons'; /** * @hidden */ export class ExpressionUI { constructor() { this.isSelected = false; this.isVisible = true; } } if (false) { /** @type {?} */ ExpressionUI.prototype.expression; /** @type {?} */ ExpressionUI.prototype.beforeOperator; /** @type {?} */ ExpressionUI.prototype.afterOperator; /** @type {?} */ ExpressionUI.prototype.isSelected; /** @type {?} */ ExpressionUI.prototype.isVisible; } /** * @hidden */ export class IgxFilteringService { /** * @param {?} gridAPI * @param {?} iconService */ constructor(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.isFilterRowVisible = false; this.filteredColumn = null; this.selectedExpression = null; this.columnToFocus = null; this.shouldFocusNext = false; this.columnToMoreIconHidden = new Map(); } /** * @return {?} */ ngOnDestroy() { this.destroy$.next(true); this.destroy$.complete(); } /** * @return {?} */ get displayContainerWidth() { return parseInt(this.grid.parentVirtDir.dc.instance._viewContainer.element.nativeElement.offsetWidth, 10); } /** * @return {?} */ get displayContainerScrollLeft() { return parseInt(this.grid.parentVirtDir.getHorizontalScroll().scrollLeft, 10); } /** * @return {?} */ get areAllColumnsInView() { return parseInt(this.grid.parentVirtDir.dc.instance._viewContainer.element.nativeElement.offsetWidth, 10) === 0; } /** * @return {?} */ get unpinnedFilterableColumns() { return this.grid.unpinnedColumns.filter(col => !col.columnGroup && col.filterable); } /** * @return {?} */ get unpinnedColumns() { return this.grid.unpinnedColumns.filter(col => !col.columnGroup); } /** * @return {?} */ get datePipe() { if (!this._datePipe) { this._datePipe = new IgxDatePipeComponent(this.grid.locale); } return this._datePipe; } /** * Subscribe to grid's events. * @return {?} */ subscribeToEvents() { if (!this.areEventsSubscribed) { this.areEventsSubscribed = true; this.grid.onColumnResized.pipe(takeUntil(this.destroy$)).subscribe((eventArgs) => { this.updateFilteringCell(eventArgs.column); }); this.grid.parentVirtDir.onChunkLoad.pipe(takeUntil(this.destroy$)).subscribe((eventArgs) => { if (eventArgs.startIndex !== this.columnStartIndex) { this.columnStartIndex = eventArgs.startIndex; this.grid.filterCellList.forEach((filterCell) => { filterCell.updateFilterCellArea(); }); } if (this.columnToFocus) { this.focusFilterCellChip(this.columnToFocus, false); this.columnToFocus = null; } }); this.grid.onColumnMovingEnd.pipe(takeUntil(this.destroy$)).subscribe(() => { this.grid.filterCellList.forEach((filterCell) => { filterCell.updateFilterCellArea(); }); }); } } /** * Internal method to create expressionsTree and filter grid used in both filter modes. * @param {?} field * @param {?=} expressions * @return {?} */ filterInternal(field, expressions = null) { this.isFiltering = true; /** @type {?} */ let 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. * @param {?} field * @param {?} value * @param {?=} conditionOrExpressionTree * @param {?=} ignoreCase * @return {?} */ filter(field, value, conditionOrExpressionTree, ignoreCase) { /** @type {?} */ const col = this.gridAPI.get_column_by_name(field); /** @type {?} */ const filteringIgnoreCase = ignoreCase || (col ? col.filteringIgnoreCase : false); if (conditionOrExpressionTree) { this.gridAPI.filter(field, value, conditionOrExpressionTree, filteringIgnoreCase); } else { /** @type {?} */ const 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 { /** @type {?} */ const expressionForColumn = (/** @type {?} */ (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(() => this.grid.onFilteringDone.emit(col.filteringExpressionsTree)); } /** * Clear the filter of a given column. * @param {?} field * @return {?} */ clearFilter(field) { if (field) { /** @type {?} */ const 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(() => this.grid.onFilteringDone.emit(null)); if (field) { /** @type {?} */ const expressions = this.getExpressions(field); expressions.length = 0; } this.isFiltering = false; } /** * Filters all the `IgxColumnComponent` in the `IgxGridComponent` with the same condition. * @param {?} value * @param {?} condition * @param {?=} ignoreCase * @return {?} */ filterGlobal(value, condition, ignoreCase) { 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(() => this.grid.onFilteringDone.emit(this.grid.filteringExpressionsTree)); } /** * Register filtering SVG icons in the icon service. * @return {?} */ registerSVGIcons() { for (const icon of icons) { if (!this.iconService.isSvgIconCached(icon.name, FILTERING_ICONS_FONT_SET)) { this.iconService.addSvgIconFromText(icon.name, icon.value, FILTERING_ICONS_FONT_SET); } } } /** * Returns the ExpressionUI array for a given column. * @param {?} columnId * @return {?} */ getExpressions(columnId) { if (!this.columnToExpressionsMap.has(columnId)) { /** @type {?} */ const column = this.grid.columns.find((col) => col.field === columnId); /** @type {?} */ const expressionUIs = new Array(); 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. * @return {?} */ refreshExpressions() { if (!this.isFiltering) { this.columnsWithComplexFilter.clear(); this.columnToExpressionsMap.forEach((value, key) => { /** @type {?} */ const column = this.grid.columns.find((col) => col.field === key); if (column) { value.length = 0; this.generateExpressionsList(column.filteringExpressionsTree, this.grid.filteringExpressionsTree.operator, value); /** @type {?} */ const 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. * @param {?} columnId * @param {?} indexToRemove * @return {?} */ removeExpression(columnId, indexToRemove) { /** @type {?} */ const 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. * @param {?} columnId * @param {?=} expressionUIList * @return {?} */ createSimpleFilteringTree(columnId, expressionUIList = null) { /** @type {?} */ const expressionsList = expressionUIList ? expressionUIList : this.getExpressions(columnId); /** @type {?} */ const expressionsTree = new FilteringExpressionsTree(FilteringLogic.Or, columnId); /** @type {?} */ let currAndBranch; /** @type {?} */ let currExpressionUI; for (let 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. * @param {?} columnId * @return {?} */ isFilterComplex(columnId) { if (this.columnsWithComplexFilter.has(columnId)) { return true; } /** @type {?} */ const column = this.grid.columns.find((col) => col.field === columnId); /** @type {?} */ const isComplex = this.isFilteringTreeComplex(column.filteringExpressionsTree); if (isComplex) { this.columnsWithComplexFilter.add(columnId); } return isComplex; } /** * Returns the string representation of the FilteringLogic operator. * @param {?} operator * @return {?} */ getOperatorAsString(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. * @param {?} expression * @return {?} */ getChipLabel(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. * @param {?} column * @return {?} */ updateFilteringCell(column) { /** @type {?} */ const filterCell = column.filterCell; if (filterCell) { filterCell.updateFilterCellArea(); } } /** * Focus a chip in a filterCell. * @param {?} column * @param {?} focusFirst * @return {?} */ focusFilterCellChip(column, focusFirst) { /** @type {?} */ const filterCell = column.filterCell; if (filterCell) { filterCell.focusChip(focusFirst); } } /** * Focus the close button in the filtering row. * @return {?} */ focusFilterRowCloseButton() { this.grid.filteringRow.closeButton.nativeElement.focus(); } /** * @return {?} */ get filteredData() { return this.grid.filteredData; } /** * @return {?} */ get sortedData() { /** @type {?} */ const sortData = new IgxGridSortingPipe(((/** @type {?} */ (this.grid))).gridAPI) .transform(this.grid.data, this.grid.sortingExpressions, this.gridId, 0); return sortData; } /** * Scrolls to a filterCell. * @param {?} column * @param {?} shouldFocusNext * @return {?} */ scrollToFilterCell(column, shouldFocusNext) { this.grid.nativeElement.focus({ preventScroll: true }); this.columnToFocus = column; this.shouldFocusNext = shouldFocusNext; /** @type {?} */ let currentColumnRight = 0; /** @type {?} */ let currentColumnLeft = 0; for (let 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; } } /** @type {?} */ const forOfDir = this.grid.headerContainer; /** @type {?} */ const width = this.displayContainerWidth + this.displayContainerScrollLeft; if (shouldFocusNext) { forOfDir.getHorizontalScroll().scrollLeft += currentColumnRight - width; } else { forOfDir.getHorizontalScroll().scrollLeft = currentColumnLeft; } } /** * @private * @param {?} expressions * @return {?} */ isFilteringTreeComplex(expressions) { if (!expressions) { return false; } if (expressions instanceof FilteringExpressionsTree) { /** @type {?} */ const expressionsTree = (/** @type {?} */ (expressions)); if (expressionsTree.operator === FilteringLogic.Or) { /** @type {?} */ const 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; } /** @type {?} */ let isComplex = false; for (let i = 0; i < expressionsTree.filteringOperands.length; i++) { isComplex = isComplex || this.isFilteringTreeComplex(expressionsTree.filteringOperands[i]); } return isComplex; } return false; } /** * @private * @param {?} expressions * @return {?} */ getChildAndOperatorsCount(expressions) { /** @type {?} */ let count = 0; /** @type {?} */ let operand; for (let 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; } /** * @param {?} expressions * @param {?} operator * @param {?} expressionsUIs * @return {?} */ generateExpressionsList(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; } } /** * @private * @param {?} expressions * @param {?} operator * @param {?} expressionsUIs * @return {?} */ generateExpressionsListRecursive(expressions, operator, expressionsUIs) { if (!expressions) { return; } if (expressions instanceof FilteringExpressionsTree) { /** @type {?} */ const expressionsTree = (/** @type {?} */ (expressions)); for (let 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 { /** @type {?} */ const exprUI = new ExpressionUI(); exprUI.expression = (/** @type {?} */ (expressions)); exprUI.afterOperator = operator; /** @type {?} */ const prevExprUI = expressionsUIs[expressionsUIs.length - 1]; if (prevExprUI) { exprUI.beforeOperator = prevExprUI.afterOperator; } expressionsUIs.push(exprUI); } } /** * @return {?} */ isFilteringExpressionsTreeEmpty() { /** @type {?} */ const expressionTree = this.grid.filteringExpressionsTree; if (!expressionTree.filteringOperands || !expressionTree.filteringOperands.length) { return true; } /** @type {?} */ let expr; for (let i = 0; i < expressionTree.filteringOperands.length; i++) { expr = expressionTree.filteringOperands[i]; if ((expr instanceof FilteringExpressionsTree)) { /** @type {?} */ const exprTree = (/** @type {?} */ (expr)); if (exprTree.filteringOperands && exprTree.filteringOperands.length) { return false; } } else { return false; } } return true; } } IgxFilteringService.decorators = [ { type: Injectable } ]; /** @nocollapse */ IgxFilteringService.ctorParameters = () => [ { type: GridBaseAPIService }, { type: IgxIconService } ]; if (false) { /** * @type {?} * @private */ IgxFilteringService.prototype.columnsWithComplexFilter; /** * @type {?} * @private */ IgxFilteringService.prototype.areEventsSubscribed; /** * @type {?} * @private */ IgxFilteringService.prototype.destroy$; /** * @type {?} * @private */ IgxFilteringService.prototype.isFiltering; /** * @type {?} * @private */ IgxFilteringService.prototype.columnToExpressionsMap; /** * @type {?} * @private */ IgxFilteringService.prototype._datePipe; /** * @type {?} * @private */ IgxFilteringService.prototype.columnStartIndex; /** @type {?} */ IgxFilteringService.prototype.gridId; /** @type {?} */ IgxFilteringService.prototype.isFilterRowVisible; /** @type {?} */ IgxFilteringService.prototype.filteredColumn; /** @type {?} */ IgxFilteringService.prototype.selectedExpression; /** @type {?} */ IgxFilteringService.prototype.columnToFocus; /** @type {?} */ IgxFilteringService.prototype.shouldFocusNext; /** @type {?} */ IgxFilteringService.prototype.columnToMoreIconHidden; /** @type {?} */ IgxFilteringService.prototype.grid; /** * @type {?} * @private */ IgxFilteringService.prototype.gridAPI; /** * @type {?} * @private */ IgxFilteringService.prototype.iconService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC1maWx0ZXJpbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZ3JpZHMvZmlsdGVyaW5nL2dyaWQtZmlsdGVyaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDdEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSx3QkFBd0IsRUFBNkIsTUFBTSxrREFBa0QsQ0FBQztBQUV2SCxPQUFPLEtBQUssTUFBTSxZQUFZLENBQUM7QUFDL0IsT0FBTyxFQUF3QixjQUFjLEVBQUUsTUFBTSxzREFBc0QsQ0FBQztBQUM1RyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUd0RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7TUFFOUMsd0JBQXdCLEdBQUcsaUJBQWlCOzs7O0FBS2xELE1BQU0sT0FBTyxZQUFZO0lBQXpCO1FBSVcsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUNuQixjQUFTLEdBQUcsSUFBSSxDQUFDO0lBQzVCLENBQUM7Q0FBQTs7O0lBTEcsa0NBQXdDOztJQUN4QyxzQ0FBc0M7O0lBQ3RDLHFDQUFxQzs7SUFDckMsa0NBQTBCOztJQUMxQixpQ0FBd0I7Ozs7O0FBTzVCLE1BQU0sT0FBTyxtQkFBbUI7Ozs7O0lBb0I1QixZQUFvQixPQUFxRSxFQUFVLFdBQTJCO1FBQTFHLFlBQU8sR0FBUCxPQUFPLENBQThEO1FBQVUsZ0JBQVcsR0FBWCxXQUFXLENB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LGlCQUFpQixJQUFJLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRTtZQUMvRSxPQUFPLElBQUksQ0FBQztTQUNmOztZQUVHLElBQVM7UUFFYixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsY0FBYyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUM5RCxJQUFJLEdBQUcsY0FBYyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRTNDLElBQUksQ0FBQyxJQUFJLFlBQVksd0JBQXdCLENBQUMsRUFBRTs7c0JBQ3RDLFFBQVEsR0FBRyxtQkFBQSxJQUFJLEVBQTRCO2dCQUNqRCxJQUFJLFFBQVEsQ0FBQyxpQkFBaUIsSUFBSSxRQUFRLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFO29CQUNqRSxPQUFPLEtBQUssQ0FBQztpQkFDaEI7YUFDSjtpQkFBTTtnQkFDSCxPQUFPLEtBQUssQ0FBQzthQUNoQjtTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQzs7O1lBNWVKLFVBQVU7Ozs7WUFsQkYsa0JBQWtCO1lBWmxCLGNBQWM7Ozs7Ozs7SUFpQ25CLHVEQUFxRDs7Ozs7SUFDckQsa0RBQW9DOzs7OztJQUNwQyx1Q0FBMEM7Ozs7O0lBQzFDLDBDQUE0Qjs7Ozs7SUFDNUIscURBQW1FOzs7OztJQUNuRSx3Q0FBd0M7Ozs7O0lBQ3hDLCtDQUE4Qjs7SUFFOUIscUNBQXNCOztJQUN0QixpREFBa0M7O0lBQ2xDLDZDQUFpRDs7SUFDakQsaURBQXVEOztJQUN2RCw0Q0FBZ0Q7O0lBQ2hELDhDQUErQjs7SUFDL0IscURBQTJEOztJQUUzRCxtQ0FBMkI7Ozs7O0lBRWYsc0NBQTZFOzs7OztJQUFFLDBDQUFtQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSWd4SWNvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9pY29uL2ljb24uc2VydmljZSc7XG5pbXBvcnQgeyBGaWx0ZXJpbmdFeHByZXNzaW9uc1RyZWUsIElGaWx0ZXJpbmdFeHByZXNzaW9uc1RyZWUgfSBmcm9tICcuLi8uLi9kYXRhLW9wZXJhdGlvbnMvZmlsdGVyaW5nLWV4cHJlc3Npb25zLXRyZWUnO1xuaW1wb3J0IHsgSWd4R3JpZEJhc2VDb21wb25lbnQsIElDb2x1bW5SZXNpemVFdmVudEFyZ3MsIElHcmlkRGF0YUJpbmRhYmxlIH0gZnJvbSAnLi4vZ3JpZC1iYXNlLmNvbXBvbmVudCc7XG5pbXBvcnQgaWNvbnMgZnJvbSAnLi9zdmdJY29ucyc7XG5pbXBvcnQgeyBJRmlsdGVyaW5nRXhwcmVzc2lvbiwgRmlsdGVyaW5nTG9naWMgfSBmcm9tICcuLi8uLi9kYXRhLW9wZXJhdGlvbnMvZmlsdGVyaW5nLWV4cHJlc3Npb24uaW50ZXJmYWNlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IElGb3JPZlN0YXRlIH0gZnJvbSAnLi4vLi4vZGlyZWN0aXZlcy9mb3Itb2YvZm9yX29mLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBJZ3hHcmlkU29ydGluZ1BpcGUgfSBmcm9tICcuLi9ncmlkL2dyaWQucGlwZXMnO1xuaW1wb3J0IHsgSWd4RGF0ZVBpcGVDb21wb25lbnQgfSBmcm9tICcuLi9ncmlkLmNvbW1vbic7XG5pbXBvcnQgeyBJZ3hDb2x1bW5Db21wb25lbnQgfSBmcm9tICcuLi9jb2x1bW4uY29tcG9uZW50JztcbmltcG9ydCB7IElGaWx0ZXJpbmdPcGVyYXRpb24gfSBmcm9tICcuLi8uLi9kYXRhLW9wZXJhdGlvbnMvZmlsdGVyaW5nLWNvbmRpdGlvbic7XG5pbXBvcnQgeyBHcmlkQmFzZUFQSVNlcnZpY2UgfSBmcm9tICcuLi9hcGkuc2VydmljZSc7XG5cbmNvbnN0IEZJTFRFUklOR19JQ09OU19GT05UX1NFVCA9ICdmaWx0ZXJpbmctaWNvbnMnO1xuXG4vKipcbiAqQGhpZGRlblxuICovXG5leHBvcnQgY2xhc3MgRXhwcmVzc2lvblVJIHtcbiAgICBwdWJsaWMgZXhwcmVzc2lvbjogSUZpbHRlcmluZ0V4cHJlc3Npb247XG4gICAgcHVibGljIGJlZm9yZU9wZXJhdG9yOiBGaWx0ZXJpbmdMb2dpYztcbiAgICBwdWJsaWMgYWZ0ZXJPcGVyYXRvcjogRmlsdGVyaW5nTG9naWM7XG4gICAgcHVibGljIGlzU2VsZWN0ZWQgPSBmYWxzZTtcbiAgICBwdWJsaWMgaXNWaXNpYmxlID0gdHJ1ZTtcbn1cblxuLyoqXG4gKkBoaWRkZW5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIElneEZpbHRlcmluZ1NlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuXG4gICAgcHJpdmF0ZSBjb2x1bW5zV2l0aENvbXBsZXhGaWx0ZXIgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIGFyZUV2ZW50c1N1YnNjcmliZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgICBwcml2YXRlIGlzRmlsdGVyaW5nID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBjb2x1bW5Ub0V4cHJlc3Npb25zTWFwID0gbmV3IE1hcDxzdHJpbmcsIEV4cHJlc3Npb25VSVtdPigpO1xuICAgIHByaXZhdGUgX2RhdGVQaXBlOiBJZ3hEYXRlUGlwZUNvbXBvbmVudDtcbiAgICBwcml2YXRlIGNvbHVtblN0YXJ0SW5kZXggPSAtMTtcblxuICAgIHB1YmxpYyBncmlkSWQ6IHN0cmluZztcbiAgICBwdWJsaWMgaXNGaWx0ZXJSb3dWaXNpYmxlID0gZmFsc2U7XG4gICAgcHVibGljIGZpbHRlcmVkQ29sdW1uOiBJZ3hDb2x1bW5Db21wb25lbnQgPSBudWxsO1xuICAgIHB1YmxpYyBzZWxlY3RlZEV4cHJlc3Npb246IElGaWx0ZXJpbmdFeHByZXNzaW9uID0gbnVsbDtcbiAgICBwdWJsaWMgY29sdW1uVG9Gb2N1czogSWd4Q29sdW1uQ29tcG9uZW50ID0gbnVsbDtcbiAgICBwdWJsaWMgc2hvdWxkRm9jdXNOZXh0ID0gZmFsc2U7XG4gICAgcHVibGljIGNvbHVtblRvTW9yZUljb25IaWRkZW4gPSBuZXcgTWFwPHN0cmluZywgYm9vbGVhbj4oKTtcblxuICAgIGdyaWQ6IElneEdyaWRCYXNlQ29tcG9uZW50O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBncmlkQVBJOiBHcmlkQmFzZUFQSVNlcnZpY2U8SWd4R3JpZEJhc2VDb21wb25lbnQgJiBJR3JpZERhdGFCaW5kYWJsZT4sIHByaXZhdGUgaWNvblNlcnZpY2U6IElneEljb25TZXJ2aWNlKSB7fVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGVzdHJveSQubmV4dCh0cnVlKTtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgZGlzcGxheUNvbnRhaW5lcldpZHRoKCkge1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5ncmlkLnBhcmVudFZpcnREaXIuZGMuaW5zdGFuY2UuX3ZpZXdDb250YWluZXIuZWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoLCAxMCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBkaXNwbGF5Q29udGFpbmVyU2Nyb2xsTGVmdCgpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuZ3JpZC5wYXJlbnRWaXJ0RGlyLmdldEhvcml6b250YWxTY3JvbGwoKS5zY3JvbGxMZWZ0LCAxMCk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBhcmVBbGxDb2x1bW5zSW5WaWV3KCkge1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5ncmlkLnBhcmVudFZpcnREaXIuZGMuaW5zdGFuY2UuX3ZpZXdDb250YWluZXIuZWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoLCAxMCkgPT09IDA7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCB1bnBpbm5lZEZpbHRlcmFibGVDb2x1bW5zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncmlkLnVucGlubmVkQ29sdW1ucy5maWx0ZXIoY29sID0+ICFjb2wuY29sdW1uR3JvdXAgJiYgY29sLmZpbHRlcmFibGUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgdW5waW5uZWRDb2x1bW5zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncmlkLnVucGlubmVkQ29sdW1ucy5maWx0ZXIoY29sID0+ICFjb2wuY29sdW1uR3JvdXApO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgZGF0ZVBpcGUoKTogSWd4RGF0ZVBpcGVDb21wb25lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX2RhdGVQaXBlKSB7XG4gICAgICAgICAgICB0aGlzLl9kYXRlUGlwZSA9IG5ldyBJZ3hEYXRlUGlwZUNvbXBvbmVudCh0aGlzLmdyaWQubG9jYWxlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0ZVBpcGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJlIHRvIGdyaWQncyBldmVudHMuXG4gICAgICovXG4gICAgcHVibGljIHN1YnNjcmliZVRvRXZlbnRzKCkge1xuICAgICAgICBpZiAoIXRoaXMuYXJlRXZlbnRzU3Vic2NyaWJlZCkge1xuICAgICAgICAgICAgdGhpcy5hcmVFdmVudHNTdWJzY3JpYmVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgdGhpcy5ncmlkLm9uQ29sdW1uUmVzaXplZC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChldmVudEFyZ3M6IElDb2x1bW5SZXNpemVFdmVudEFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUZpbHRlcmluZ0NlbGwoZXZlbnRBcmdzLmNvbHVtbik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5ncmlkLnBhcmVudFZpcnREaXIub25DaHVua0xvYWQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoZXZlbnRBcmdzOiBJRm9yT2ZTdGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChldmVudEFyZ3Muc3RhcnRJbmRleCAhPT0gdGhpcy5jb2x1bW5TdGFydEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uU3RhcnRJbmRleCA9IGV2ZW50QXJncy5zdGFydEluZGV4O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdyaWQuZmlsdGVyQ2VsbExpc3QuZm9yRWFjaCgoZmlsdGVyQ2VsbCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyQ2VsbC51cGRhdGVGaWx0ZXJDZWxsQXJlYSgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29sdW1uVG9Gb2N1cykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvY3VzRmlsdGVyQ2VsbENoaXAodGhpcy5jb2x1bW5Ub0ZvY3VzLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29sdW1uVG9Gb2N1cyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRoaXMuZ3JpZC5vbkNvbHVtbk1vdmluZ0VuZC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmdyaWQuZmlsdGVyQ2VsbExpc3QuZm9yRWFjaCgoZmlsdGVyQ2VsbCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBmaWx0ZXJDZWxsLnVwZGF0ZUZpbHRlckNlbGxBcmVhKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB0byBjcmVhdGUgZXhwcmVzc2lvbnNUcmVlIGFuZCBmaWx0ZXIgZ3JpZCB1c2VkIGluIGJvdGggZmlsdGVyIG1vZGVzLlxuICAgICAqL1xuICAgIHB1YmxpYyBmaWx0ZXJJbnRlcm5hbChmaWVsZDogc3RyaW5nLCBleHByZXNzaW9uczogRmlsdGVyaW5nRXhwcmVzc2lvbnNUcmVlIHwgQXJyYXk8RXhwcmVzc2lvblVJPiA9IG51bGwpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pc0ZpbHRlcmluZyA9IHRydWU7XG5cbiAgICAgICAgbGV0IGV4cHJlc3Npb25zVHJlZTtcbiAgICAgICAgaWYgKGV4cHJlc3Npb25zIGluc3RhbmNlb2YgRmlsdGVyaW5nRXhwcmVzc2lvbnNUcmVlKSB7XG4gICAgICAgICAgICBleHByZXNzaW9uc1RyZWUgPSBleHByZXNzaW9ucztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4cHJlc3Npb25zVHJlZSA9IHRoaXMuY3JlYXRlU2ltcGxlRmlsdGVyaW5nVHJlZShmaWVsZCwgZXhwcmVzc2lvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV4cHJlc3Npb25zVHJlZS5maWx0ZXJpbmdPcGVyYW5kcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuY2xlYXJGaWx0ZXIoZmllbGQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5maWx0ZXIoZmllbGQsIG51bGwsIGV4cHJlc3Npb25zVHJlZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmlzRmlsdGVyaW5nID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZSBmaWx0ZXJpbmcgb24gdGhlIGdyaWQuXG4gICAgICovXG4gICAgcHVibGljIGZpbHRlcihmaWVsZDogc3RyaW5nLCB2YWx1ZTogYW55LCBjb25kaXRpb25PckV4cHJlc3Npb25UcmVlPzogSUZpbHRlcmluZ09wZXJhdGlvbiB8IElGaWx0ZXJpbmdFeHByZXNzaW9uc1RyZWUsXG4gICAgICAgIGlnbm9yZUNhc2U/OiBib29sZWFuKSB7XG4gICAgICAgIGNvbnN0IGNvbCA9IHRoaXMuZ3JpZEFQSS5nZXRfY29sdW1uX2J5X25hbWUoZmllbGQpO1xuICAgICAgICBjb25zdCBmaWx0ZXJpbmdJZ25vcmVDYXNlID0gaWdub3JlQ2FzZSB8fCAoY29sID8gY29sLmZpbHRlcmluZ0lnbm9yZUNhc2UgOiBmYWxzZSk7XG5cbiAgICAgICAgaWYgKGNvbmRpdGlvbk9yRXhwcmVzc2lvblRyZWUpIHtcbiAgICAgICAgICAgIHRoaXMuZ3JpZEFQSS5maWx0ZXIoZmllbGQ