@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
367 lines • 44.5 kB
JavaScript
import { __decorate, __extends, __metadata, __param } from "tslib";
import { ChangeDetectorRef, Component, HostBinding, Input, Optional, ViewChild, Inject, TemplateRef } from '@angular/core';
import { DisplayDensityToken, DisplayDensityBase } from '../../core/displayDensity';
import { CsvFileTypes, IgxBaseExporter, IgxCsvExporterOptions, IgxCsvExporterService, IgxExcelExporterOptions, IgxExcelExporterService, AbsoluteScrollStrategy } from '../../services/index';
import { GridBaseAPIService } from '../api.service';
import { IgxButtonDirective } from '../../directives/button/button.directive';
import { IgxDropDownComponent } from '../../drop-down/drop-down.component';
import { IgxColumnHidingComponent } from '../hiding/column-hiding.component';
import { IgxColumnPinningComponent } from '../pinning/column-pinning.component';
import { HorizontalAlignment, VerticalAlignment } from '../../services/overlay/utilities';
import { ConnectedPositioningStrategy } from '../../services/overlay/position';
/**
* This class encapsulates the Toolbar's logic and is internally used by
* the `IgxGridComponent`, `IgxTreeGridComponent` and `IgxHierarchicalGridComponent`.
*/
var IgxGridToolbarComponent = /** @class */ (function (_super) {
__extends(IgxGridToolbarComponent, _super);
function IgxGridToolbarComponent(gridAPI, cdr, excelExporter, csvExporter, _displayDensityOptions) {
var _this = _super.call(this, _displayDensityOptions) || this;
_this.gridAPI = gridAPI;
_this.cdr = cdr;
_this.excelExporter = excelExporter;
_this.csvExporter = csvExporter;
_this._displayDensityOptions = _displayDensityOptions;
_this._filterColumnsPrompt = 'Filter columns list ...';
_this._positionSettings = {
horizontalDirection: HorizontalAlignment.Left,
horizontalStartPoint: HorizontalAlignment.Right,
verticalDirection: VerticalAlignment.Bottom,
verticalStartPoint: VerticalAlignment.Bottom
};
_this._overlaySettings = {
positionStrategy: new ConnectedPositioningStrategy(_this._positionSettings),
scrollStrategy: new AbsoluteScrollStrategy(),
modal: false,
closeOnOutsideClick: true,
excludePositionTarget: true
};
return _this;
}
Object.defineProperty(IgxGridToolbarComponent.prototype, "filterColumnsPrompt", {
/**
* Gets the default text shown in the filtering box.
* ```typescript
* const filterPrompt = this.grid.toolbar.filterColumnsPrompt;
* ```
*/
get: function () {
return this._filterColumnsPrompt;
},
/**
* Sets the default text shown in the filtering box.
* ```typescript
* this.grid.toolbar.filterColumnsPrompt('Filter columns ...');
* ```
*/
set: function (value) {
this._filterColumnsPrompt = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxGridToolbarComponent.prototype, "defaultDropDownsMaxHeight", {
/**
* Gets the height for the `IgxGridToolbarComponent`'s drop down panels.
* ```typescript
* const dropdownHeight = this.grid.toolbar.defaultDropDownsMaxHeight;
* ```
*/
get: function () {
var gridHeight = this.grid.calcHeight;
return (gridHeight) ? gridHeight * 0.7 + 'px' : '100%';
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxGridToolbarComponent.prototype, "grid", {
/**
* Returns a reference to the `IgxGridComponent` component, hosting the `IgxGridToolbarComponent`.
* ```typescript
* const grid = this.igxGrid1.toolbar.grid;
* ```
*/
get: function () {
return this.gridAPI.grid;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxGridToolbarComponent.prototype, "shouldShowExportButton", {
/**
* Returns whether the `IgxGridComponent` renders an export button.
* ```typescript
* const exportButton = this.igxGrid1.toolbar.shouldShowExportButton;
* ```
*/
get: function () {
return (this.grid != null && (this.grid.exportExcel || this.grid.exportCsv));
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxGridToolbarComponent.prototype, "shouldShowExportExcelButton", {
/**
* Returns whether the `IgxGridComponent` renders an Excel export button.
* ```typescript
* const exportExcelButton = this.igxGrid1.toolbar.shouldShowExportExcelButton;
* ```
*/
get: function () {
return (this.grid != null && this.grid.exportExcel);
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxGridToolbarComponent.prototype, "shouldShowExportCsvButton", {
/**
* Returns whether the `IgxGridComponent` renders an CSV export button.
* ```typescript
* const exportCSVButton = this.igxGrid1.toolbar.shouldShowExportCsvButton;
* ```
*/
get: function () {
return (this.grid != null && this.grid.exportCsv);
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxGridToolbarComponent.prototype, "pinnedColumnsCount", {
/**
* Returns how many columns are pinned.
* ```typescript
* const pinnedCount = this.igxGrid1.toolbar.pinnedColumnsCount;
* ```
*/
get: function () {
return this.grid.pinnedColumns.filter(function (col) { return !col.columnLayout; }).length;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxGridToolbarComponent.prototype, "hostClass", {
/**
* Returns the theme of the `IgxGridToolbarComponent`.
* ```typescript
* const toolbarTheme = this.grid.toolbar.hostClass;
* ```
*/
get: function () {
return this.getComponentDensityClass('igx-grid-toolbar');
},
enumerable: true,
configurable: true
});
/**
* Returns the title of `IgxGridToolbarComponent`.
* ```typescript
* const toolbarTitle = this.igxGrid1.toolbar.getTitle();
* ```
*/
IgxGridToolbarComponent.prototype.getTitle = function () {
return this.grid != null ? this.grid.toolbarTitle : '';
};
/**
* Returns the text of the export button of the `IgxGridToolbarComponent`.
* ```typescript
* const toolbarExportText = this.igxGrid1.toolbar.getTitle();
* ```
*/
IgxGridToolbarComponent.prototype.getExportText = function () {
return this.grid != null ? this.grid.exportText : '';
};
/**
* Returns the text of the Excel export button of the `IgxGridToolbarComponent`.
* ```typescript
* const toolbarExcelText = this.igxGrid1.toolbar.getExportExcelText();
* ```
*/
IgxGridToolbarComponent.prototype.getExportExcelText = function () {
return this.grid != null ? this.grid.exportExcelText : '';
};
/**
* Returns the text of the CSV export button of the `IgxGridToolbarComponent`.
* ```typescript
* const toolbarCSVText = this.igxGrid1.toolbar.getExportCsvText();
* ```
*/
IgxGridToolbarComponent.prototype.getExportCsvText = function () {
return this.grid != null ? this.grid.exportCsvText : '';
};
/**
* Toggles the export button's dropdown menu.
* ```typescript
* this.igxGrid1.toolbar.exportClicked();
* ```
*/
IgxGridToolbarComponent.prototype.exportClicked = function () {
this._overlaySettings.positionStrategy.settings.target = this.exportButton.nativeElement;
this._overlaySettings.outlet = this.grid.outletDirective;
this.exportDropdown.toggle(this._overlaySettings);
};
/**
* Exports the grid to excel.
* ```typescript
* this.igxGrid1.toolbar.exportToExcelClicked();
* ```
*/
IgxGridToolbarComponent.prototype.exportToExcelClicked = function () {
this.performExport(this.excelExporter, 'excel');
};
/**
* Exports the grid to CSV.
* ```typescript
* this.igxGrid1.toolbar.exportToCsvClicked();
* ```
*/
IgxGridToolbarComponent.prototype.exportToCsvClicked = function () {
this.performExport(this.csvExporter, 'csv');
};
IgxGridToolbarComponent.prototype.performExport = function (exp, exportType) {
this.exportClicked();
var fileName = 'ExportedData';
var options = exportType === 'excel' ?
new IgxExcelExporterOptions(fileName) :
new IgxCsvExporterOptions(fileName, CsvFileTypes.CSV);
var args = { grid: this.grid, exporter: exp, options: options, cancel: false };
this.grid.onToolbarExporting.emit(args);
if (args.cancel) {
return;
}
exp.export(this.grid, options);
};
/**
* Toggles the Column Hiding UI.
* ```typescript
* this.grid1.toolbar.toggleColumnHidingUI();
* ```
*/
IgxGridToolbarComponent.prototype.toggleColumnHidingUI = function () {
this._overlaySettings.positionStrategy.settings.target = this.columnHidingButton.nativeElement;
this._overlaySettings.outlet = this.grid.outletDirective;
this.columnHidingDropdown.toggle(this._overlaySettings);
};
/**
* Toggles the Column Pinning UI.
* ```typescript
* this.grid1.toolbar.toggleColumnPinningUI();
* ```
*/
IgxGridToolbarComponent.prototype.toggleColumnPinningUI = function () {
this._overlaySettings.positionStrategy.settings.target = this.columnPinningButton.nativeElement;
this._overlaySettings.outlet = this.grid.outletDirective;
this.columnPinningDropdown.toggle(this._overlaySettings);
};
/**
* @hidden @internal
*/
IgxGridToolbarComponent.prototype.showAdvancedFilteringUI = function () {
this.grid.openAdvancedFilteringDialog();
};
Object.defineProperty(IgxGridToolbarComponent.prototype, "context", {
/**
* Returns the `context` object which represents the `template context` binding into the
* `toolbar custom container` by providing references to the parent IgxGird and the toolbar itself.
* ```typescript
* const context = this.igxGrid.toolbar.context;
* ```
*/
get: function () {
return {
// $implicit: this
grid: this.grid,
toolbar: this
};
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxGridToolbarComponent.prototype, "customContentTemplate", {
/** @hidden */
get: function () {
if (this.grid != null && this.grid.toolbarCustomContentTemplate != null) {
return this.grid.toolbarCustomContentTemplate.template;
}
else {
return null;
}
},
enumerable: true,
configurable: true
});
IgxGridToolbarComponent.ctorParameters = function () { return [
{ type: GridBaseAPIService },
{ type: ChangeDetectorRef },
{ type: IgxExcelExporterService, decorators: [{ type: Optional }] },
{ type: IgxCsvExporterService, decorators: [{ type: Optional }] },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] }
]; };
__decorate([
HostBinding('class.igx-grid-toolbar'),
Input(),
__metadata("design:type", String)
], IgxGridToolbarComponent.prototype, "gridID", void 0);
__decorate([
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], IgxGridToolbarComponent.prototype, "filterColumnsPrompt", null);
__decorate([
Input(),
__metadata("design:type", Object),
__metadata("design:paramtypes", [])
], IgxGridToolbarComponent.prototype, "defaultDropDownsMaxHeight", null);
__decorate([
ViewChild('columnHidingDropdown', { read: IgxDropDownComponent }),
__metadata("design:type", IgxDropDownComponent)
], IgxGridToolbarComponent.prototype, "columnHidingDropdown", void 0);
__decorate([
ViewChild(IgxColumnHidingComponent),
__metadata("design:type", IgxColumnHidingComponent)
], IgxGridToolbarComponent.prototype, "columnHidingUI", void 0);
__decorate([
ViewChild('columnHidingButton', { read: IgxButtonDirective }),
__metadata("design:type", IgxButtonDirective)
], IgxGridToolbarComponent.prototype, "columnHidingButton", void 0);
__decorate([
ViewChild('exportDropdown', { read: IgxDropDownComponent }),
__metadata("design:type", IgxDropDownComponent)
], IgxGridToolbarComponent.prototype, "exportDropdown", void 0);
__decorate([
ViewChild('btnExport', { read: IgxButtonDirective }),
__metadata("design:type", IgxButtonDirective)
], IgxGridToolbarComponent.prototype, "exportButton", void 0);
__decorate([
ViewChild('columnPinningDropdown', { read: IgxDropDownComponent }),
__metadata("design:type", IgxDropDownComponent)
], IgxGridToolbarComponent.prototype, "columnPinningDropdown", void 0);
__decorate([
ViewChild(IgxColumnPinningComponent),
__metadata("design:type", IgxColumnPinningComponent)
], IgxGridToolbarComponent.prototype, "columnPinningUI", void 0);
__decorate([
ViewChild('columnPinningButton', { read: IgxButtonDirective }),
__metadata("design:type", IgxButtonDirective)
], IgxGridToolbarComponent.prototype, "columnPinningButton", void 0);
__decorate([
HostBinding('attr.class'),
__metadata("design:type", String),
__metadata("design:paramtypes", [])
], IgxGridToolbarComponent.prototype, "hostClass", null);
IgxGridToolbarComponent = __decorate([
Component({
selector: 'igx-grid-toolbar',
template: "<span class=\"igx-grid-toolbar__title\" *ngIf=\"getTitle()\">\n {{ getTitle() }}\n</span>\n\n<div class=\"igx-grid-toolbar__custom-content\" *ngIf=\"customContentTemplate != null\">\n <ng-container *ngTemplateOutlet=\"customContentTemplate; context: context\">\n </ng-container>\n</div>\n\n<div class=\"igx-grid-toolbar__actions\">\n <div *ngIf=\"grid.allowAdvancedFiltering\">\n <button igxButton=\"outlined\" [displayDensity]=\"grid.displayDensity\" #advancedFilteringButton name=\"btnAdvancedFiltering\" igxRipple\n (click)=\"showAdvancedFilteringUI()\"\n [ngClass]=\"grid.advancedFilteringExpressionsTree ? 'igx-grid-toolbar__adv-filter--filtered' : 'igx-grid-toolbar__adv-filter'\">\n <div class=\"igx-grid-toolbar__button-space\">\n <igx-icon>\n filter_list\n </igx-icon>\n <span>{{grid.resourceStrings.igx_grid_advanced_filter_title}}</span>\n </div>\n </button>\n </div>\n\n <div *ngIf=\"grid.columnHiding\">\n <button igxButton=\"outlined\" [displayDensity]=\"grid.displayDensity\" #columnHidingButton name=\"btnColumnHiding\" igxRipple\n (click)=\"toggleColumnHidingUI()\">\n <div class=\"igx-grid-toolbar__button-space\">\n <igx-icon *ngIf=\"grid.hiddenColumnsCount > 0\">visibility_off</igx-icon>\n <igx-icon *ngIf=\"grid.hiddenColumnsCount === 0\">visibility</igx-icon>\n <span>{{ grid.hiddenColumnsCount }}</span>\n <span>{{ grid.hiddenColumnsText }}</span>\n </div>\n </button>\n <igx-drop-down #columnHidingDropdown>\n <igx-column-hiding\n [columns]=\"grid.columns\"\n [title]=\"grid.columnHidingTitle\"\n [filterColumnsPrompt]=\"filterColumnsPrompt\"\n [columnsAreaMaxHeight]=\"defaultDropDownsMaxHeight\"\n (onColumnVisibilityChanged)=\"grid.toggleColumnVisibility($event)\">\n </igx-column-hiding>\n </igx-drop-down>\n </div>\n <div *ngIf=\"grid.columnPinning\">\n <button igxButton=\"outlined\" [displayDensity]=\"grid.displayDensity\" #columnPinningButton name=\"btnColumnPinning\" igxRipple\n (click)=\"toggleColumnPinningUI()\">\n <div class=\"igx-grid-toolbar__button-space\">\n <igx-icon *ngIf=\"pinnedColumnsCount > 0\">lock</igx-icon>\n <igx-icon *ngIf=\"pinnedColumnsCount === 0\">lock_open</igx-icon>\n <span>{{ pinnedColumnsCount }}</span>\n <span>{{ grid.pinnedColumnsText }}</span>\n <span></span>\n </div>\n </button>\n <igx-drop-down #columnPinningDropdown>\n <igx-column-pinning\n [columns]=\"grid.columns\"\n [title]=\"grid.columnPinningTitle\"\n [filterColumnsPrompt]=\"filterColumnsPrompt\"\n [columnsAreaMaxHeight]=\"defaultDropDownsMaxHeight\"></igx-column-pinning>\n </igx-drop-down>\n </div>\n\n <div class=\"igx-grid-toolbar__dropdown\" *ngIf=\"shouldShowExportButton\" id=\"btnExport\">\n <button igxButton=\"outlined\" [displayDensity]=\"grid.displayDensity\" igxRipple #btnExport\n (click)=\"exportClicked()\">\n <span class=\"igx-grid-toolbar__button-space\">\n <igx-icon fontSet=\"material\">import_export</igx-icon>\n <span>{{ getExportText() }}</span>\n <igx-icon fontSet=\"material\">arrow_drop_down</igx-icon>\n </span>\n </button>\n\n <igx-drop-down #exportDropdown>\n <ul class=\"igx-grid-toolbar__dd-list\">\n <li class=\"igx-grid-toolbar__dd-list-items\" igxRipple *ngIf=\"shouldShowExportExcelButton\" id=\"btnExportExcel\"\n (click)=\"exportToExcelClicked()\">{{ getExportExcelText() }}</li>\n <li class=\"igx-grid-toolbar__dd-list-items\" igxRipple *ngIf=\"shouldShowExportCsvButton\" id=\"btnExportCsv\"\n (click)=\"exportToCsvClicked()\">{{ getExportCsvText() }}</li>\n </ul>\n </igx-drop-down>\n </div>\n</div>\n"
}),
__param(2, Optional()),
__param(3, Optional()),
__param(4, Optional()), __param(4, Inject(DisplayDensityToken)),
__metadata("design:paramtypes", [GridBaseAPIService,
ChangeDetectorRef,
IgxExcelExporterService,
IgxCsvExporterService, Object])
], IgxGridToolbarComponent);
return IgxGridToolbarComponent;
}(DisplayDensityBase));
export { IgxGridToolbarComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC10b29sYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZ3JpZHMvdG9vbGJhci9ncmlkLXRvb2xiYXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQ0gsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxXQUFXLEVBQ1gsS0FBSyxFQUNMLFFBQVEsRUFDUixTQUFTLEVBQ1QsTUFBTSxFQUNOLFdBQVcsRUFDZCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQTBCLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDNUcsT0FBTyxFQUNILFlBQVksRUFDWixlQUFlLEVBQ2YscUJBQXFCLEVBQ3JCLHFCQUFxQixFQUNyQix1QkFBdUIsRUFDdkIsdUJBQXVCLEVBQ3ZCLHNCQUFzQixFQUN6QixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBRTlFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzdFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ2hGLE9BQU8sRUFBcUMsbUJBQW1CLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUM3SCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUcvRTs7O0dBR0c7QUFLSDtJQUE2QywyQ0FBa0I7SUFpTDNELGlDQUFtQixPQUE0RCxFQUNwRSxHQUFzQixFQUNWLGFBQXNDLEVBQ3RDLFdBQWtDLEVBQ0Ysc0JBQThDO1FBSnJHLFlBS1Esa0JBQU0s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QjtZQUM5QixpQkFBaUI7WUFDSyx1QkFBdUI7WUFDekIscUJBQXFCO09BcExoRCx1QkFBdUIsQ0F1Vm5DO0lBQUQsOEJBQUM7Q0FBQSxBQXZWRCxDQUE2QyxrQkFBa0IsR0F1VjlEO1NBdlZZLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LFxuICAgIE9wdGlvbmFsLFxuICAgIFZpZXdDaGlsZCxcbiAgICBJbmplY3QsXG4gICAgVGVtcGxhdGVSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IElEaXNwbGF5RGVuc2l0eU9wdGlvbnMsIERpc3BsYXlEZW5zaXR5VG9rZW4sIERpc3BsYXlEZW5zaXR5QmFzZSB9IGZyb20gJy4uLy4uL2NvcmUvZGlzcGxheURlbnNpdHknO1xuaW1wb3J0IHtcbiAgICBDc3ZGaWxlVHlwZXMsXG4gICAgSWd4QmFzZUV4cG9ydGVyLFxuICAgIElneENzdkV4cG9ydGVyT3B0aW9ucyxcbiAgICBJZ3hDc3ZFeHBvcnRlclNlcnZpY2UsXG4gICAgSWd4RXhjZWxFeHBvcnRlck9wdGlvbnMsXG4gICAgSWd4RXhjZWxFeHBvcnRlclNlcnZpY2UsXG4gICAgQWJzb2x1dGVTY3JvbGxTdHJhdGVneVxufSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9pbmRleCc7XG5pbXBvcnQgeyBHcmlkQmFzZUFQSVNlcnZpY2UgfSBmcm9tICcuLi9hcGkuc2VydmljZSc7XG5pbXBvcnQgeyBJZ3hCdXR0b25EaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2J1dHRvbi9idXR0b24uZGlyZWN0aXZlJztcbmltcG9ydCB7IElneEdyaWRCYXNlRGlyZWN0aXZlIH0gZnJvbSAnLi4vZ3JpZC1iYXNlLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBJZ3hEcm9wRG93bkNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2Ryb3AtZG93bi9kcm9wLWRvd24uY29tcG9uZW50JztcbmltcG9ydCB7IElneENvbHVtbkhpZGluZ0NvbXBvbmVudCB9IGZyb20gJy4uL2hpZGluZy9jb2x1bW4taGlkaW5nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hDb2x1bW5QaW5uaW5nQ29tcG9uZW50IH0gZnJvbSAnLi4vcGlubmluZy9jb2x1bW4tcGlubmluZy5jb21wb25lbnQnO1xuaW1wb3J0IHsgT3ZlcmxheVNldHRpbmdzLCBQb3NpdGlvblNldHRpbmdzLCBIb3Jpem9udGFsQWxpZ25tZW50LCBWZXJ0aWNhbEFsaWdubWVudCB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL292ZXJsYXkvdXRpbGl0aWVzJztcbmltcG9ydCB7IENvbm5lY3RlZFBvc2l0aW9uaW5nU3RyYXRlZ3kgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9vdmVybGF5L3Bvc2l0aW9uJztcbmltcG9ydCB7IEdyaWRUeXBlIH0gZnJvbSAnLi4vY29tbW9uL2dyaWQuaW50ZXJmYWNlJztcblxuLyoqXG4gKiBUaGlzIGNsYXNzIGVuY2Fwc3VsYXRlcyB0aGUgVG9vbGJhcidzIGxvZ2ljIGFuZCBpcyBpbnRlcm5hbGx5IHVzZWQgYnlcbiAqIHRoZSBgSWd4R3JpZENvbXBvbmVudGAsIGBJZ3hUcmVlR3JpZENvbXBvbmVudGAgYW5kIGBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50YC5cbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdpZ3gtZ3JpZC10b29sYmFyJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vZ3JpZC10b29sYmFyLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBJZ3hHcmlkVG9vbGJhckNvbXBvbmVudCBleHRlbmRzIERpc3BsYXlEZW5zaXR5QmFzZSB7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MuaWd4LWdyaWQtdG9vbGJhcicpXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZ3JpZElEOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHRleHQgc2hvd24gaW4gdGhlIGZpbHRlcmluZyBib3guXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGZpbHRlclByb21wdCA9IHRoaXMuZ3JpZC50b29sYmFyLmZpbHRlckNvbHVtbnNQcm9tcHQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZ2V0IGZpbHRlckNvbHVtbnNQcm9tcHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maWx0ZXJDb2x1bW5zUHJvbXB0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGRlZmF1bHQgdGV4dCBzaG93biBpbiB0aGUgZmlsdGVyaW5nIGJveC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5ncmlkLnRvb2xiYXIuZmlsdGVyQ29sdW1uc1Byb21wdCgnRmlsdGVyIGNvbHVtbnMgLi4uJyk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIHNldCBmaWx0ZXJDb2x1bW5zUHJvbXB0KHZhbHVlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fZmlsdGVyQ29sdW1uc1Byb21wdCA9IHZhbHVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2ZpbHRlckNvbHVtbnNQcm9tcHQgPSAnRmlsdGVyIGNvbHVtbnMgbGlzdCAuLi4nO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgaGVpZ2h0IGZvciB0aGUgYElneEdyaWRUb29sYmFyQ29tcG9uZW50YCdzIGRyb3AgZG93biBwYW5lbHMuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGRyb3Bkb3duSGVpZ2h0ID0gdGhpcy5ncmlkLnRvb2xiYXIuZGVmYXVsdERyb3BEb3duc01heEhlaWdodDtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBkZWZhdWx0RHJvcERvd25zTWF4SGVpZ2h0KCkge1xuICAgICAgICBjb25zdCBncmlkSGVpZ2h0ID0gdGhpcy5ncmlkLmNhbGNIZWlnaHQ7XG4gICAgICAgIHJldHVybiAoZ3JpZEhlaWdodCkgPyBncmlkSGVpZ2h0ICogMC43ICsgJ3B4JyA6ICcxMDAlJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlcyBhIHJlZmVyZW5jZSB0byB0aGUgYElneERyb3BEb3duQ29tcG9uZW50YCBvZiB0aGUgQ29sdW1uIEhpZGluZyBVSS5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZHJvcGRvd25IaWRpbmcgPSB0aGlzLmdyaWQudG9vbGJhci5jb2x1bW5IaWRpbmdEcm9wZG93bjtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdjb2x1bW5IaWRpbmdEcm9wZG93bicsIHsgcmVhZDogSWd4RHJvcERvd25Db21wb25lbnQgfSlcbiAgICBwdWJsaWMgY29sdW1uSGlkaW5nRHJvcGRvd246IElneERyb3BEb3duQ29tcG9uZW50O1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYSByZWZlcmVuY2UgdG8gdGhlIGBJZ3hDb2x1bW5IaWRpbmdDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBoaWRpbmdVSSA9IHRoaXMuZ3JpZC50b29sYmFyLmNvbHVtbkhpZGluZ1VJO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoSWd4Q29sdW1uSGlkaW5nQ29tcG9uZW50KVxuICAgIHB1YmxpYyBjb2x1bW5IaWRpbmdVSTogSWd4Q29sdW1uSGlkaW5nQ29tcG9uZW50O1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYSByZWZlcmVuY2UgdG8gdGhlIENvbHVtbiBIaWRpbmcgYnV0dG9uLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBoaWRpbmdCdXR0b24gPSB0aGlzLmdyaWQudG9vbGJhci5jb2x1bW5IaWRpbmdCdXR0b247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnY29sdW1uSGlkaW5nQnV0dG9uJywgeyByZWFkOiBJZ3hCdXR0b25EaXJlY3RpdmUgfSlcbiAgICBwdWJsaWMgY29sdW1uSGlkaW5nQnV0dG9uOiBJZ3hCdXR0b25EaXJlY3RpdmU7XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlcyBhIHJlZmVyZW5jZSB0byB0aGUgYElneERyb3BEb3duQ29tcG9uZW50YCBvZiB0aGUgRXhwb3J0IGJ1dHRvbi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZXhwb3J0RHJvcGRvd24gPSB0aGlzLmdyaWQudG9vbGJhci5leHBvcnREcm9wZG93bjtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdleHBvcnREcm9wZG93bicsIHsgcmVhZDogSWd4RHJvcERvd25Db21wb25lbnQgfSlcbiAgICBwdWJsaWMgZXhwb3J0RHJvcGRvd246IElneERyb3BEb3duQ29tcG9uZW50O1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYSByZWZlcmVuY2UgdG8gdGhlIEV4cG9ydCBidXR0b24uXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGV4cG9ydEJ0biA9IHRoaXMuZ3JpZC50b29sYmFyLmV4cG9ydEJ1dHRvbjtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdidG5FeHBvcnQnLCB7IHJlYWQ6IElneEJ1dHRvbkRpcmVjdGl2ZSB9KVxuICAgIHB1YmxpYyBleHBvcnRCdXR0b246IElneEJ1dHRvbkRpcmVjdGl2ZTtcblxuICAgIC8qKlxuICAgICAqIFByb3ZpZGVzIGEgcmVmZXJlbmNlIHRvIHRoZSBgSWd4RHJvcERvd25Db21wb25lbnRgIG9mIHRoZSBDb2x1bW4gUGlubmluZyBVSS5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZHJvcGRvd25QaW5uaW5nID0gdGhpcy5ncmlkLnRvb2xiYXIuY29sdW1uUGlubmluZ0Ryb3Bkb3duO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ2NvbHVtblBpbm5pbmdEcm9wZG93bicsIHsgcmVhZDogSWd4RHJvcERvd25Db21wb25lbnQgfSlcbiAgICBwdWJsaWMgY29sdW1uUGlubmluZ0Ryb3Bkb3duOiBJZ3hEcm9wRG93bkNvbXBvbmVudDtcblxuICAgIC8qKlxuICAgICAqIFByb3ZpZGVzIGEgcmVmZXJlbmNlIHRvIHRoZSBgSWd4Q29sdW1uUGlubmluZ0NvbXBvbmVudGAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IHBpbm5pbmdVSSA9IHRoaXMuZ3JpZC50b29sYmFyLmNvbHVtblBpbm5pbmdEcm9wZG93bjtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKElneENvbHVtblBpbm5pbmdDb21wb25lbnQpXG4gICAgcHVibGljIGNvbHVtblBpbm5pbmdVSTogSWd4Q29sdW1uUGlubmluZ0NvbXBvbmVudDtcblxuICAgIC8qKlxuICAgICAqIFByb3ZpZGVzIGEgcmVmZXJlbmNlIHRvIHRoZSBDb2x1bW4gUGlubmluZyBidXR0b24uXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IHBpbm5pbmdCdXR0b24gPSB0aGlzLmdyaWQudG9vbGJhci5jb2x1bW5QaW5uaW5nQnV0dG9uO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ2NvbHVtblBpbm5pbmdCdXR0b24nLCB7IHJlYWQ6IElneEJ1dHRvbkRpcmVjdGl2ZSB9KVxuICAgIHB1YmxpYyBjb2x1bW5QaW5uaW5nQnV0dG9uOiBJZ3hCdXR0b25EaXJlY3RpdmU7XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBgSWd4R3JpZENvbXBvbmVudGAgY29tcG9uZW50LCBob3N0aW5nIHRoZSBgSWd4R3JpZFRvb2xiYXJDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBncmlkID0gdGhpcy5pZ3hHcmlkMS50b29sYmFyLmdyaWQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBncmlkKCk6IElneEdyaWRCYXNlRGlyZWN0aXZlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZEFQSS5ncmlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgYElneEdyaWRDb21wb25lbnRgIHJlbmRlcnMgYW4gZXhwb3J0IGJ1dHRvbi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZXhwb3J0QnV0dG9uID0gdGhpcy5pZ3hHcmlkMS50b29sYmFyLnNob3VsZFNob3dFeHBvcnRCdXR0b247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBzaG91bGRTaG93RXhwb3J0QnV0dG9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKHRoaXMuZ3JpZCAhPSBudWxsICYmICh0aGlzLmdyaWQuZXhwb3J0RXhjZWwgfHwgdGhpcy5ncmlkLmV4cG9ydENzdikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgYElneEdyaWRDb21wb25lbnRgIHJlbmRlcnMgYW4gRXhjZWwgZXhwb3J0IGJ1dHRvbi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZXhwb3J0RXhjZWxCdXR0b24gPSB0aGlzLmlneEdyaWQxLnRvb2xiYXIuc2hvdWxkU2hvd0V4cG9ydEV4Y2VsQnV0dG9uO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgc2hvdWxkU2hvd0V4cG9ydEV4Y2VsQnV0dG9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKHRoaXMuZ3JpZCAhPSBudWxsICYmIHRoaXMuZ3JpZC5leHBvcnRFeGNlbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBgSWd4R3JpZENvbXBvbmVudGAgcmVuZGVycyBhbiBDU1YgZXhwb3J0IGJ1dHRvbi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZXhwb3J0Q1NWQnV0dG9uID0gdGhpcy5pZ3hHcmlkMS50b29sYmFyLnNob3VsZFNob3dFeHBvcnRDc3ZCdXR0b247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBzaG91bGRTaG93RXhwb3J0Q3N2QnV0dG9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKHRoaXMuZ3JpZCAhPSBudWxsICYmIHRoaXMuZ3JpZC5leHBvcnRDc3YpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaG93IG1hbnkgY29sdW1ucyBhcmUgcGlubmVkLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBwaW5uZWRDb3VudCA9IHRoaXMuaWd4R3JpZDEudG9vbGJhci5waW5uZWRDb2x1bW5zQ291bnQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBwaW5uZWRDb2x1bW5zQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyaWQucGlubmVkQ29sdW1ucy5maWx0ZXIoY29sID0+ICFjb2wuY29sdW1uTGF5b3V0KS5sZW5ndGg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGhlbWUgb2YgdGhlIGBJZ3hHcmlkVG9vbGJhckNvbXBvbmVudGAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IHRvb2xiYXJUaGVtZSA9IHRoaXMuZ3JpZC50b29sYmFyLmhvc3RDbGFzcztcbiAgICAgKiBgYGBcbiAgICAgKi9cblxuICAgIEBIb3N0QmluZGluZygnYXR0ci5jbGFzcycpXG4gICAgZ2V0IGhvc3RDbGFzcygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDb21wb25lbnREZW5zaXR5Q2xhc3MoJ2lneC1ncmlkLXRvb2xiYXInKTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgZ3JpZEFQSTogR3JpZEJhc2VBUElTZXJ2aWNlPElneEdyaWRCYXNlRGlyZWN0aXZlICYgR3JpZFR5cGU+LFxuICAgICAgICBwdWJsaWMgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICAgICAgQE9wdGlvbmFsKCkgcHVibGljIGV4Y2VsRXhwb3J0ZXI6IElneEV4Y2VsRXhwb3J0ZXJTZXJ2aWNlLFxuICAgICAgICBAT3B0aW9uYWwoKSBwdWJsaWMgY3N2RXhwb3J0ZXI6IElneENzdkV4cG9ydGVyU2VydmljZSxcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChEaXNwbGF5RGVuc2l0eVRva2VuKSBwcm90ZWN0ZWQgX2Rpc3BsYXlEZW5zaXR5T3B0aW9uczogSURpc3BsYXlEZW5zaXR5T3B0aW9ucykge1xuICAgICAgICAgICAgc3VwZXIoX2Rpc3BsYXlEZW5zaXR5T3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcG9zaXRpb25TZXR0aW5nczogUG9zaXRpb25TZXR0aW5ncyA9IHtcbiAgICAgICAgaG9yaXpvbnRhbERpcmVjdGlvbjogSG9yaXpvbnRhbEFsaWdubWVudC5MZWZ0LFxuICAgICAgICBob3Jpem9udGFsU3RhcnRQb2ludDogSG9yaXpvbnRhbEFsaWdubWVudC5SaWdodCxcbiAgICAgICAgdmVydGljYWxEaXJlY3Rpb246IFZlcnRpY2FsQWxpZ25tZW50LkJvdHRvbSxcbiAgICAgICAgdmVydGljYWxTdGFydFBvaW50OiBWZXJ0aWNhbEFsaWdubWVudC5Cb3R0b21cbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBfb3ZlcmxheVNldHRpbmdzOiBPdmVybGF5U2V0dGluZ3MgPSB7XG4gICAgICAgIHBvc2l0aW9uU3RyYXRlZ3k6IG5ldyBDb25uZWN0ZWRQb3NpdGlvbmluZ1N0cmF0ZWd5KHRoaXMuX3Bvc2l0aW9uU2V0dGluZ3MpLFxuICAgICAgICBzY3JvbGxTdHJhdGVneTogbmV3IEFic29sdXRlU2Nyb2xsU3RyYXRlZ3koKSxcbiAgICAgICAgbW9kYWw6IGZhbHNlLFxuICAgICAgICBjbG9zZU9uT3V0c2lkZUNsaWNrOiB0cnVlLFxuICAgICAgICBleGNsdWRlUG9zaXRpb25UYXJnZXQ6IHRydWVcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGl0bGUgb2YgYElneEdyaWRUb29sYmFyQ29tcG9uZW50YC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgdG9vbGJhclRpdGxlID0gdGhpcy5pZ3hHcmlkMS50b29sYmFyLmdldFRpdGxlKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldFRpdGxlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyaWQgIT0gbnVsbCA/IHRoaXMuZ3JpZC50b29sYmFyVGl0bGUgOiAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0ZXh0IG9mIHRoZSBleHBvcnQgYnV0dG9uIG9mIHRoZSBgSWd4R3JpZFRvb2xiYXJDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCB0b29sYmFyRXhwb3J0VGV4dCA9IHRoaXMuaWd4R3JpZDEudG9vbGJhci5nZXRUaXRsZSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRFeHBvcnRUZXh0KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyaWQgIT0gbnVsbCA/IHRoaXMuZ3JpZC5leHBvcnRUZXh0IDogJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGV4dCBvZiB0aGUgRXhjZWwgZXhwb3J0IGJ1dHRvbiBvZiB0aGUgYElneEdyaWRUb29sYmFyQ29tcG9uZW50YC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgdG9vbGJhckV4Y2VsVGV4dCA9IHRoaXMuaWd4R3JpZDEudG9vbGJhci5nZXRFeHBvcnRFeGNlbFRleHQoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0RXhwb3J0RXhjZWxUZXh0KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyaWQgIT0gbnVsbCA/IHRoaXMuZ3JpZC5leHBvcnRFeGNlbFRleHQgOiAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0ZXh0IG9mIHRoZSBDU1YgZXhwb3J0IGJ1dHRvbiBvZiB0aGUgYElneEdyaWRUb29sYmFyQ29tcG9uZW50YC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgdG9vbGJhckNTVlRleHQgPSB0aGlzLmlneEdyaWQxLnRvb2xiYXIuZ2V0RXhwb3J0Q3N2VGV4dCgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRFeHBvcnRDc3ZUZXh0KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyaWQgIT0gbnVsbCA/IHRoaXMuZ3JpZC5leHBvcnRDc3ZUZXh0IDogJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVG9nZ2xlcyB0aGUgZXhwb3J0IGJ1dHRvbidzIGRyb3Bkb3duIG1lbnUuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMuaWd4R3JpZDEudG9vbGJhci5leHBvcnRDbGlja2VkKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGV4cG9ydENsaWNrZWQoKSB7XG4gICAgICAgIHRoaXMuX292ZXJsYXlTZXR0aW5ncy5wb3NpdGlvblN0cmF0ZWd5LnNldHRpbmdzLnRhcmdldCA9IHRoaXMuZXhwb3J0QnV0dG9uLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIHRoaXMuX292ZXJsYXlTZXR0aW5ncy5vdXRsZXQgPSB0aGlzLmdyaWQub3V0bGV0RGlyZWN0aXZlO1xuICAgICAgICB0aGlzLmV4cG9ydERyb3Bkb3duLnRvZ2dsZSh0aGlzLl9vdmVybGF5U2V0dGluZ3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4cG9ydHMgdGhlIGdyaWQgdG8gZXhjZWwuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMuaWd4R3JpZDEudG9vbGJhci5leHBvcnRUb0V4Y2VsQ2xpY2tlZCgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBleHBvcnRUb0V4Y2VsQ2xpY2tlZCgpIHtcbiAgICAgICAgdGhpcy5wZXJmb3JtRXhwb3J0KHRoaXMuZXhjZWxFeHBvcnRlciwgJ2V4Y2VsJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhwb3J0cyB0aGUgZ3JpZCB0byBDU1YuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMuaWd4R3JpZDEudG9vbGJhci5leHBvcnRUb0NzdkNsaWNrZWQoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZXhwb3J0VG9Dc3ZDbGlja2VkKCkge1xuICAgICAgICB0aGlzLnBlcmZvcm1FeHBvcnQodGhpcy5jc3ZFeHBvcnRlciwgJ2NzdicpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcGVyZm9ybUV4cG9ydChleHA6IElneEJhc2VFeHBvcnRlciwgZXhwb3J0VHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuZXhwb3J0Q2xpY2tlZCgpO1xuXG4gICAgICAgIGNvbnN0IGZpbGVOYW1lID0gJ0V4cG9ydGVkRGF0YSc7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBleHBvcnRUeXBlID09PSAnZXhjZWwnID9cbiAgICAgICAgICAgIG5ldyBJZ3hFeGNlbEV4cG9ydGVyT3B0aW9ucyhmaWxlTmFtZSkgOlxuICAgICAgICAgICAgbmV3IElneENzdkV4cG9ydGVyT3B0aW9ucyhmaWxlTmFtZSwgQ3N2RmlsZVR5cGVzLkNTVik7XG5cbiAgICAgICAgY29uc3QgYXJncyA9IHsgZ3JpZDogdGhpcy5ncmlkLCBleHBvcnRlcjogZXhwLCBvcHRpb25zOiBvcHRpb25zLCBjYW5jZWw6IGZhbHNlIH07XG5cbiAgICAgICAgdGhpcy5ncmlkLm9uVG9vbGJhckV4cG9ydGluZy5lbWl0KGFyZ3MpO1xuICAgICAgICBpZiAoYXJncy5jYW5jZWwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBleHAuZXhwb3J0KHRoaXMuZ3JpZCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVG9nZ2xlcyB0aGUgQ29sdW1uIEhpZGluZyBVSS5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5ncmlkMS50b29sYmFyLnRvZ2dsZUNvbHVtbkhpZGluZ1VJKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIHRvZ2dsZUNvbHVtbkhpZGluZ1VJKCkge1xuICAgICAgICB0aGlzLl9vdmVybGF5U2V0dGluZ3MucG9zaXRpb25TdHJhdGVneS5zZXR0aW5ncy50YXJnZXQgPSB0aGlzLmNvbHVtbkhpZGluZ0J1dHRvbi5uYXRpdmVFbGVtZW50O1xuICAgICAgICB0aGlzLl9vdmVybGF5U2V0dGluZ3Mub3V0bGV0ID0gdGhpcy5ncmlkLm91dGxldERpcmVjdGl2ZTtcbiAgICAgICAgdGhpcy5jb2x1bW5IaWRpbmdEcm9wZG93bi50b2dnbGUodGhpcy5fb3ZlcmxheVNldHRpbmdzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUb2dnbGVzIHRoZSBDb2x1bW4gUGlubmluZyBVSS5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5ncmlkMS50b29sYmFyLnRvZ2dsZUNvbHVtblBpbm5pbmdVSSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyB0b2dnbGVDb2x1bW5QaW5uaW5nVUkoKSB7XG4gICAgICAgIHRoaXMuX292ZXJsYXlTZXR0aW5ncy5wb3NpdGlvblN0cmF0ZWd5LnNldHRpbmdzLnRhcmdldCA9IHRoaXMuY29sdW1uUGlubmluZ0J1dHRvbi5uYXRpdmVFbGVtZW50O1xuICAgICAgICB0aGlzLl9vdmVybGF5U2V0dGluZ3Mub3V0bGV0ID0gdGhpcy5ncmlkLm91dGxldERpcmVjdGl2ZTtcbiAgICAgICAgdGhpcy5jb2x1bW5QaW5uaW5nRHJvcGRvd24udG9nZ2xlKHRoaXMuX292ZXJsYXlTZXR0aW5ncyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlbiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc2hvd0FkdmFuY2VkRmlsdGVyaW5nVUkoKSB7XG4gICAgICAgIHRoaXMuZ3JpZC5vcGVuQWR2YW5jZWRGaWx0ZXJpbmdEaWFsb2coKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgY29udGV4dGAgb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGB0ZW1wbGF0ZSBjb250ZXh0YCBiaW5kaW5nIGludG8gdGhlXG4gICAgICogYHRvb2xiYXIgY3VzdG9tIGNvbnRhaW5lcmAgYnkgcHJvdmlkaW5nIHJlZmVyZW5jZXMgdG8gdGhlIHBhcmVudCBJZ3hHaXJkIGFuZCB0aGUgdG9vbGJhciBpdHNlbGYuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGNvbnRleHQgPSAgdGhpcy5pZ3hHcmlkLnRvb2xiYXIuY29udGV4dDtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGNvbnRleHQoKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8vICRpbXBsaWNpdDogdGhpc1xuICAgICAgICAgICAgZ3JpZDogdGhpcy5ncmlkLFxuICAgICAgICAgICAgdG9vbGJhcjogdGhpc1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgcHVibGljIGdldCBjdXN0b21Db250ZW50VGVtcGxhdGUoKTogVGVtcGxhdGVSZWY8YW55PiB7XG4gICAgICAgIGlmICh0aGlzLmdyaWQgIT0gbnVsbCAmJiB0aGlzLmdyaWQudG9vbGJhckN1c3RvbUNvbnRlbnRUZW1wbGF0ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ncmlkLnRvb2xiYXJDdXN0b21Db250ZW50VGVtcGxhdGUudGVtcGxhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==