UNPKG

igniteui-angular

Version:

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

662 lines • 51.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { ChangeDetectorRef, Component, Directive, HostBinding, Input, Optional, ViewChild, Inject, TemplateRef } from '@angular/core'; import { DisplayDensityToken, DisplayDensityBase } from '../core/displayDensity'; import { CsvFileTypes, IgxCsvExporterOptions, IgxCsvExporterService, IgxExcelExporterOptions, IgxExcelExporterService, AbsoluteScrollStrategy } from '../services/index'; import { GridBaseAPIService } from './api.service'; import { IgxDropDownComponent } from '../drop-down/drop-down.component'; import { IgxColumnHidingComponent } from './column-hiding.component'; import { IgxColumnPinningComponent } from './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) { tslib_1.__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: /** * Gets the default text shown in the filtering box. * ```typescript * const filterPrompt = this.grid.toolbar.filterColumnsPrompt; * ``` * @return {?} */ function () { return this._filterColumnsPrompt; }, /** * Sets the default text shown in the filtering box. * ```typescript * this.grid.toolbar.filterColumnsPrompt('Filter columns ...'); * ``` */ set: /** * Sets the default text shown in the filtering box. * ```typescript * this.grid.toolbar.filterColumnsPrompt('Filter columns ...'); * ``` * @param {?} value * @return {?} */ 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: /** * Gets the height for the `IgxGridToolbarComponent`'s drop down panels. * ```typescript * const dropdownHeight = this.grid.toolbar.defaultDropDownsMaxHeight; * ``` * @return {?} */ function () { /** @type {?} */ 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: /** * Returns a reference to the `IgxGridComponent` component, hosting the `IgxGridToolbarComponent`. * ```typescript * const grid = this.igxGrid1.toolbar.grid; * ``` * @return {?} */ 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: /** * Returns whether the `IgxGridComponent` renders an export button. * ```typescript * const exportButton = this.igxGrid1.toolbar.shouldShowExportButton; * ``` * @return {?} */ 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: /** * Returns whether the `IgxGridComponent` renders an Excel export button. * ```typescript * const exportExcelButton = this.igxGrid1.toolbar.shouldShowExportExcelButton; * ``` * @return {?} */ 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: /** * Returns whether the `IgxGridComponent` renders an CSV export button. * ```typescript * const exportCSVButton = this.igxGrid1.toolbar.shouldShowExportCsvButton; * ``` * @return {?} */ 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: /** * Returns how many columns are pinned. * ```typescript * const pinnedCount = this.igxGrid1.toolbar.pinnedColumnsCount; * ``` * @return {?} */ function () { return this.grid.pinnedColumns.length; }, enumerable: true, configurable: true }); Object.defineProperty(IgxGridToolbarComponent.prototype, "hostClass", { /** * Returns the theme of the `IgxGridToolbarComponent`. * ```typescript * const toolbarTheme = this.grid.toolbar.hostClass; * ``` */ get: /** * Returns the theme of the `IgxGridToolbarComponent`. * ```typescript * const toolbarTheme = this.grid.toolbar.hostClass; * ``` * @return {?} */ function () { return this.getComponentDensityClass('igx-grid-toolbar'); }, enumerable: true, configurable: true }); /** * Returns the title of `IgxGridToolbarComponent`. * ```typescript * const toolbarTitle = this.igxGrid1.toolbar.getTitle(); * ``` */ /** * Returns the title of `IgxGridToolbarComponent`. * ```typescript * const toolbarTitle = this.igxGrid1.toolbar.getTitle(); * ``` * @return {?} */ IgxGridToolbarComponent.prototype.getTitle = /** * Returns the title of `IgxGridToolbarComponent`. * ```typescript * const toolbarTitle = this.igxGrid1.toolbar.getTitle(); * ``` * @return {?} */ 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(); * ``` */ /** * Returns the text of the export button of the `IgxGridToolbarComponent`. * ```typescript * const toolbarExportText = this.igxGrid1.toolbar.getTitle(); * ``` * @return {?} */ IgxGridToolbarComponent.prototype.getExportText = /** * Returns the text of the export button of the `IgxGridToolbarComponent`. * ```typescript * const toolbarExportText = this.igxGrid1.toolbar.getTitle(); * ``` * @return {?} */ 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(); * ``` */ /** * Returns the text of the Excel export button of the `IgxGridToolbarComponent`. * ```typescript * const toolbarExcelText = this.igxGrid1.toolbar.getExportExcelText(); * ``` * @return {?} */ IgxGridToolbarComponent.prototype.getExportExcelText = /** * Returns the text of the Excel export button of the `IgxGridToolbarComponent`. * ```typescript * const toolbarExcelText = this.igxGrid1.toolbar.getExportExcelText(); * ``` * @return {?} */ 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(); * ``` */ /** * Returns the text of the CSV export button of the `IgxGridToolbarComponent`. * ```typescript * const toolbarCSVText = this.igxGrid1.toolbar.getExportCsvText(); * ``` * @return {?} */ IgxGridToolbarComponent.prototype.getExportCsvText = /** * Returns the text of the CSV export button of the `IgxGridToolbarComponent`. * ```typescript * const toolbarCSVText = this.igxGrid1.toolbar.getExportCsvText(); * ``` * @return {?} */ function () { return this.grid != null ? this.grid.exportCsvText : ''; }; /** * Toggles the export button's dropdown menu. * ```typescript * this.igxGrid1.toolbar.exportClicked(); * ``` */ /** * Toggles the export button's dropdown menu. * ```typescript * this.igxGrid1.toolbar.exportClicked(); * ``` * @return {?} */ IgxGridToolbarComponent.prototype.exportClicked = /** * Toggles the export button's dropdown menu. * ```typescript * this.igxGrid1.toolbar.exportClicked(); * ``` * @return {?} */ 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(); * ``` */ /** * Exports the grid to excel. * ```typescript * this.igxGrid1.toolbar.exportToExcelClicked(); * ``` * @return {?} */ IgxGridToolbarComponent.prototype.exportToExcelClicked = /** * Exports the grid to excel. * ```typescript * this.igxGrid1.toolbar.exportToExcelClicked(); * ``` * @return {?} */ function () { this.performExport(this.excelExporter, 'excel'); }; /** * Exports the grid to CSV. * ```typescript * this.igxGrid1.toolbar.exportToCsvClicked(); * ``` */ /** * Exports the grid to CSV. * ```typescript * this.igxGrid1.toolbar.exportToCsvClicked(); * ``` * @return {?} */ IgxGridToolbarComponent.prototype.exportToCsvClicked = /** * Exports the grid to CSV. * ```typescript * this.igxGrid1.toolbar.exportToCsvClicked(); * ``` * @return {?} */ function () { this.performExport(this.csvExporter, 'csv'); }; /** * @private * @param {?} exp * @param {?} exportType * @return {?} */ IgxGridToolbarComponent.prototype.performExport = /** * @private * @param {?} exp * @param {?} exportType * @return {?} */ function (exp, exportType) { this.exportClicked(); /** @type {?} */ var fileName = 'ExportedData'; /** @type {?} */ var options = exportType === 'excel' ? new IgxExcelExporterOptions(fileName) : new IgxCsvExporterOptions(fileName, CsvFileTypes.CSV); /** @type {?} */ 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(); * ``` */ /** * Toggles the Column Hiding UI. * ```typescript * this.grid1.toolbar.toggleColumnHidingUI(); * ``` * @return {?} */ IgxGridToolbarComponent.prototype.toggleColumnHidingUI = /** * Toggles the Column Hiding UI. * ```typescript * this.grid1.toolbar.toggleColumnHidingUI(); * ``` * @return {?} */ 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(); * ``` */ /** * Toggles the Column Pinning UI. * ```typescript * this.grid1.toolbar.toggleColumnPinningUI(); * ``` * @return {?} */ IgxGridToolbarComponent.prototype.toggleColumnPinningUI = /** * Toggles the Column Pinning UI. * ```typescript * this.grid1.toolbar.toggleColumnPinningUI(); * ``` * @return {?} */ function () { this._overlaySettings.positionStrategy.settings.target = this.columnPinningButton.nativeElement; this._overlaySettings.outlet = this.grid.outletDirective; this.columnPinningDropdown.toggle(this._overlaySettings); }; 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: /** * 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; * ``` * @return {?} */ function () { return { // $implicit: this grid: this.grid, toolbar: this }; }, enumerable: true, configurable: true }); Object.defineProperty(IgxGridToolbarComponent.prototype, "customContentTemplate", { /** @hidden */ get: /** * @hidden * @return {?} */ function () { if (this.grid != null && this.grid.toolbarCustomContentTemplate != null) { return this.grid.toolbarCustomContentTemplate.template; } else { return null; } }, enumerable: true, configurable: true }); IgxGridToolbarComponent.decorators = [ { type: Component, args: [{ 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.columnHiding\">\n <button igxButton=\"flat\" #columnHidingButton name=\"btnColumnHiding\" igxButton 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=\"flat\" #columnPinningButton name=\"btnColumnPinning\" igxButton 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\n <div class=\"igx-grid-toolbar__dropdown\" *ngIf=\"shouldShowExportButton\" id=\"btnExport\">\n <button igxButton=\"flat\" 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" }] } ]; /** @nocollapse */ 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,] }] } ]; }; IgxGridToolbarComponent.propDecorators = { gridID: [{ type: HostBinding, args: ['class.igx-grid-toolbar',] }, { type: Input }], filterColumnsPrompt: [{ type: Input }], defaultDropDownsMaxHeight: [{ type: Input }], columnHidingDropdown: [{ type: ViewChild, args: ['columnHidingDropdown', { read: IgxDropDownComponent },] }], columnHidingUI: [{ type: ViewChild, args: [IgxColumnHidingComponent,] }], columnHidingButton: [{ type: ViewChild, args: ['columnHidingButton',] }], exportDropdown: [{ type: ViewChild, args: ['exportDropdown', { read: IgxDropDownComponent },] }], exportButton: [{ type: ViewChild, args: ['btnExport',] }], columnPinningDropdown: [{ type: ViewChild, args: ['columnPinningDropdown', { read: IgxDropDownComponent },] }], columnPinningUI: [{ type: ViewChild, args: [IgxColumnPinningComponent,] }], columnPinningButton: [{ type: ViewChild, args: ['columnPinningButton',] }], hostClass: [{ type: HostBinding, args: ['attr.class',] }] }; return IgxGridToolbarComponent; }(DisplayDensityBase)); export { IgxGridToolbarComponent }; if (false) { /** * @hidden * @type {?} */ IgxGridToolbarComponent.prototype.gridID; /** * @type {?} * @private */ IgxGridToolbarComponent.prototype._filterColumnsPrompt; /** * Provides a reference to the `IgxDropDownComponent` of the Column Hiding UI. * ```typescript * const dropdownHiding = this.grid.toolbar.columnHidingDropdown; * ``` * @type {?} */ IgxGridToolbarComponent.prototype.columnHidingDropdown; /** * Provides a reference to the `IgxColumnHidingComponent`. * ```typescript * const hidingUI = this.grid.toolbar.columnHidingUI; * ``` * @type {?} */ IgxGridToolbarComponent.prototype.columnHidingUI; /** * Provides a reference to the Column Hiding button. * ```typescript * const hidingButton = this.grid.toolbar.columnHidingButton; * ``` * @type {?} */ IgxGridToolbarComponent.prototype.columnHidingButton; /** * Provides a reference to the `IgxDropDownComponent` of the Export button. * ```typescript * const exportDropdown = this.grid.toolbar.exportDropdown; * ``` * @type {?} */ IgxGridToolbarComponent.prototype.exportDropdown; /** * Provides a reference to the Export button. * ```typescript * const exportBtn = this.grid.toolbar.exportButton; * ``` * @type {?} */ IgxGridToolbarComponent.prototype.exportButton; /** * Provides a reference to the `IgxDropDownComponent` of the Column Pinning UI. * ```typescript * const dropdownPinning = this.grid.toolbar.columnPinningDropdown; * ``` * @type {?} */ IgxGridToolbarComponent.prototype.columnPinningDropdown; /** * Provides a reference to the `IgxColumnPinningComponent`. * ```typescript * const pinningUI = this.grid.toolbar.columnPinningDropdown; * ``` * @type {?} */ IgxGridToolbarComponent.prototype.columnPinningUI; /** * Provides a reference to the Column Pinning button. * ```typescript * const pinningButton = this.grid.toolbar.columnPinningButton; * ``` * @type {?} */ IgxGridToolbarComponent.prototype.columnPinningButton; /** * @type {?} * @private */ IgxGridToolbarComponent.prototype._positionSettings; /** * @type {?} * @private */ IgxGridToolbarComponent.prototype._overlaySettings; /** @type {?} */ IgxGridToolbarComponent.prototype.gridAPI; /** @type {?} */ IgxGridToolbarComponent.prototype.cdr; /** @type {?} */ IgxGridToolbarComponent.prototype.excelExporter; /** @type {?} */ IgxGridToolbarComponent.prototype.csvExporter; /** * @type {?} * @protected */ IgxGridToolbarComponent.prototype._displayDensityOptions; } /** * The IgxGridToolbarCustomContentDirective directive is used to mark an 'ng-template' (with * the 'igxToolbarCustomContent' selector) defined in the IgxGrid which is used to provide * custom content for cener part of the IgxGridToolbar. */ var IgxGridToolbarCustomContentDirective = /** @class */ (function () { function IgxGridToolbarCustomContentDirective(template) { this.template = template; } IgxGridToolbarCustomContentDirective.decorators = [ { type: Directive, args: [{ selector: '[igxToolbarCustomContent]' },] } ]; /** @nocollapse */ IgxGridToolbarCustomContentDirective.ctorParameters = function () { return [ { type: TemplateRef } ]; }; return IgxGridToolbarCustomContentDirective; }()); export { IgxGridToolbarCustomContentDirective }; if (false) { /** @type {?} */ IgxGridToolbarCustomContentDirective.prototype.template; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC10b29sYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZ3JpZHMvZ3JpZC10b29sYmFyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFDSCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULFNBQVMsRUFDVCxXQUFXLEVBQ1gsS0FBSyxFQUNMLFFBQVEsRUFDUixTQUFTLEVBQ1QsTUFBTSxFQUNOLFdBQVcsRUFDZCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQTBCLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekcsT0FBTyxFQUNILFlBQVksRUFFWixxQkFBcUIsRUFDckIscUJBQXFCLEVBQ3JCLHVCQUF1QixFQUN2Qix1QkFBdUIsRUFDdkIsc0JBQXNCLEVBQ3pCLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5ELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3ZFLE9BQU8sRUFBcUMsbUJBQW1CLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMxSCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQzs7Ozs7QUFNNUU7SUFJNkMsbURBQWtCO0lBa0wzRCxpQ0FBbUIsT0FBcUUsRUFDN0UsR0FBc0IsRUFDVixhQUFzQyxFQUN0QyxXQUFrQyxFQUNGLHNCQUE4QztRQUpyRyxZQUtRLGtCQUFNLHNCQUFzQixDQUFDLFNBQ3BDO1FBTmtCLGFBQU8sR0FBUCxPQUFPLENBQThEO1FBQzdFLFNBQUcsR0FB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Y3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgRGlyZWN0aXZlLFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LFxuICAgIE9wdGlvbmFsLFxuICAgIFZpZXdDaGlsZCxcbiAgICBJbmplY3QsXG4gICAgVGVtcGxhdGVSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IElEaXNwbGF5RGVuc2l0eU9wdGlvbnMsIERpc3BsYXlEZW5zaXR5VG9rZW4sIERpc3BsYXlEZW5zaXR5QmFzZSB9IGZyb20gJy4uL2NvcmUvZGlzcGxheURlbnNpdHknO1xuaW1wb3J0IHtcbiAgICBDc3ZGaWxlVHlwZXMsXG4gICAgSWd4QmFzZUV4cG9ydGVyLFxuICAgIElneENzdkV4cG9ydGVyT3B0aW9ucyxcbiAgICBJZ3hDc3ZFeHBvcnRlclNlcnZpY2UsXG4gICAgSWd4RXhjZWxFeHBvcnRlck9wdGlvbnMsXG4gICAgSWd4RXhjZWxFeHBvcnRlclNlcnZpY2UsXG4gICAgQWJzb2x1dGVTY3JvbGxTdHJhdGVneVxufSBmcm9tICcuLi9zZXJ2aWNlcy9pbmRleCc7XG5pbXBvcnQgeyBHcmlkQmFzZUFQSVNlcnZpY2UgfSBmcm9tICcuL2FwaS5zZXJ2aWNlJztcbmltcG9ydCB7IElneEdyaWRCYXNlQ29tcG9uZW50LCBJR3JpZERhdGFCaW5kYWJsZSB9IGZyb20gJy4vZ3JpZC1iYXNlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hEcm9wRG93bkNvbXBvbmVudCB9IGZyb20gJy4uL2Ryb3AtZG93bi9kcm9wLWRvd24uY29tcG9uZW50JztcbmltcG9ydCB7IElneENvbHVtbkhpZGluZ0NvbXBvbmVudCB9IGZyb20gJy4vY29sdW1uLWhpZGluZy5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWd4Q29sdW1uUGlubmluZ0NvbXBvbmVudCB9IGZyb20gJy4vY29sdW1uLXBpbm5pbmcuY29tcG9uZW50JztcbmltcG9ydCB7IE92ZXJsYXlTZXR0aW5ncywgUG9zaXRpb25TZXR0aW5ncywgSG9yaXpvbnRhbEFsaWdubWVudCwgVmVydGljYWxBbGlnbm1lbnQgfSBmcm9tICcuLi9zZXJ2aWNlcy9vdmVybGF5L3V0aWxpdGllcyc7XG5pbXBvcnQgeyBDb25uZWN0ZWRQb3NpdGlvbmluZ1N0cmF0ZWd5IH0gZnJvbSAnLi4vc2VydmljZXMvb3ZlcmxheS9wb3NpdGlvbic7XG5cbi8qKlxuICogVGhpcyBjbGFzcyBlbmNhcHN1bGF0ZXMgdGhlIFRvb2xiYXIncyBsb2dpYyBhbmQgaXMgaW50ZXJuYWxseSB1c2VkIGJ5XG4gKiB0aGUgYElneEdyaWRDb21wb25lbnRgLCBgSWd4VHJlZUdyaWRDb21wb25lbnRgIGFuZCBgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudGAuXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnaWd4LWdyaWQtdG9vbGJhcicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2dyaWQtdG9vbGJhci5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgSWd4R3JpZFRvb2xiYXJDb21wb25lbnQgZXh0ZW5kcyBEaXNwbGF5RGVuc2l0eUJhc2Uge1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MuaWd4LWdyaWQtdG9vbGJhcicpXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZ3JpZElEOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkZWZhdWx0IHRleHQgc2hvd24gaW4gdGhlIGZpbHRlcmluZyBib3guXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGZpbHRlclByb21wdCA9IHRoaXMuZ3JpZC50b29sYmFyLmZpbHRlckNvbHVtbnNQcm9tcHQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZ2V0IGZpbHRlckNvbHVtbnNQcm9tcHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maWx0ZXJDb2x1bW5zUHJvbXB0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGRlZmF1bHQgdGV4dCBzaG93biBpbiB0aGUgZmlsdGVyaW5nIGJveC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5ncmlkLnRvb2xiYXIuZmlsdGVyQ29sdW1uc1Byb21wdCgnRmlsdGVyIGNvbHVtbnMgLi4uJyk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIHNldCBmaWx0ZXJDb2x1bW5zUHJvbXB0KHZhbHVlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fZmlsdGVyQ29sdW1uc1Byb21wdCA9IHZhbHVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2ZpbHRlckNvbHVtbnNQcm9tcHQgPSAnRmlsdGVyIGNvbHVtbnMgbGlzdCAuLi4nO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgaGVpZ2h0IGZvciB0aGUgYElneEdyaWRUb29sYmFyQ29tcG9uZW50YCdzIGRyb3AgZG93biBwYW5lbHMuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGRyb3Bkb3duSGVpZ2h0ID0gdGhpcy5ncmlkLnRvb2xiYXIuZGVmYXVsdERyb3BEb3duc01heEhlaWdodDtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBkZWZhdWx0RHJvcERvd25zTWF4SGVpZ2h0KCkge1xuICAgICAgICBjb25zdCBncmlkSGVpZ2h0ID0gdGhpcy5ncmlkLmNhbGNIZWlnaHQ7XG4gICAgICAgIHJldHVybiAoZ3JpZEhlaWdodCkgPyBncmlkSGVpZ2h0ICogMC43ICsgJ3B4JyA6ICcxMDAlJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlcyBhIHJlZmVyZW5jZSB0byB0aGUgYElneERyb3BEb3duQ29tcG9uZW50YCBvZiB0aGUgQ29sdW1uIEhpZGluZyBVSS5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZHJvcGRvd25IaWRpbmcgPSB0aGlzLmdyaWQudG9vbGJhci5jb2x1bW5IaWRpbmdEcm9wZG93bjtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdjb2x1bW5IaWRpbmdEcm9wZG93bicsIHsgcmVhZDogSWd4RHJvcERvd25Db21wb25lbnQgfSlcbiAgICBwdWJsaWMgY29sdW1uSGlkaW5nRHJvcGRvd246IElneERyb3BEb3duQ29tcG9uZW50O1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYSByZWZlcmVuY2UgdG8gdGhlIGBJZ3hDb2x1bW5IaWRpbmdDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBoaWRpbmdVSSA9IHRoaXMuZ3JpZC50b29sYmFyLmNvbHVtbkhpZGluZ1VJO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoSWd4Q29sdW1uSGlkaW5nQ29tcG9uZW50KVxuICAgIHB1YmxpYyBjb2x1bW5IaWRpbmdVSTogSWd4Q29sdW1uSGlkaW5nQ29tcG9uZW50O1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYSByZWZlcmVuY2UgdG8gdGhlIENvbHVtbiBIaWRpbmcgYnV0dG9uLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBoaWRpbmdCdXR0b24gPSB0aGlzLmdyaWQudG9vbGJhci5jb2x1bW5IaWRpbmdCdXR0b247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnY29sdW1uSGlkaW5nQnV0dG9uJylcbiAgICBwdWJsaWMgY29sdW1uSGlkaW5nQnV0dG9uO1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYSByZWZlcmVuY2UgdG8gdGhlIGBJZ3hEcm9wRG93bkNvbXBvbmVudGAgb2YgdGhlIEV4cG9ydCBidXR0b24uXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGV4cG9ydERyb3Bkb3duID0gdGhpcy5ncmlkLnRvb2xiYXIuZXhwb3J0RHJvcGRvd247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnZXhwb3J0RHJvcGRvd24nLCB7IHJlYWQ6IElneERyb3BEb3duQ29tcG9uZW50IH0pXG4gICAgcHVibGljIGV4cG9ydERyb3Bkb3duOiBJZ3hEcm9wRG93bkNvbXBvbmVudDtcblxuICAgIC8qKlxuICAgICAqIFByb3ZpZGVzIGEgcmVmZXJlbmNlIHRvIHRoZSBFeHBvcnQgYnV0dG9uLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBleHBvcnRCdG4gPSB0aGlzLmdyaWQudG9vbGJhci5leHBvcnRCdXR0b247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnYnRuRXhwb3J0JylcbiAgICBwdWJsaWMgZXhwb3J0QnV0dG9uO1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYSByZWZlcmVuY2UgdG8gdGhlIGBJZ3hEcm9wRG93bkNvbXBvbmVudGAgb2YgdGhlIENvbHVtbiBQaW5uaW5nIFVJLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBkcm9wZG93blBpbm5pbmcgPSB0aGlzLmdyaWQudG9vbGJhci5jb2x1bW5QaW5uaW5nRHJvcGRvd247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnY29sdW1uUGlubmluZ0Ryb3Bkb3duJywgeyByZWFkOiBJZ3hEcm9wRG93bkNvbXBvbmVudCB9KVxuICAgIHB1YmxpYyBjb2x1bW5QaW5uaW5nRHJvcGRvd246IElneERyb3BEb3duQ29tcG9uZW50O1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYSByZWZlcmVuY2UgdG8gdGhlIGBJZ3hDb2x1bW5QaW5uaW5nQ29tcG9uZW50YC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgcGlubmluZ1VJID0gdGhpcy5ncmlkLnRvb2xiYXIuY29sdW1uUGlubmluZ0Ryb3Bkb3duO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoSWd4Q29sdW1uUGlubmluZ0NvbXBvbmVudClcbiAgICBwdWJsaWMgY29sdW1uUGlubmluZ1VJOiBJZ3hDb2x1bW5QaW5uaW5nQ29tcG9uZW50O1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYSByZWZlcmVuY2UgdG8gdGhlIENvbHVtbiBQaW5uaW5nIGJ1dHRvbi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgcGlubmluZ0J1dHRvbiA9IHRoaXMuZ3JpZC50b29sYmFyLmNvbHVtblBpbm5pbmdCdXR0b247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnY29sdW1uUGlubmluZ0J1dHRvbicpXG4gICAgcHVibGljIGNvbHVtblBpbm5pbmdCdXR0b247XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBgSWd4R3JpZENvbXBvbmVudGAgY29tcG9uZW50LCBob3N0aW5nIHRoZSBgSWd4R3JpZFRvb2xiYXJDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBncmlkID0gdGhpcy5pZ3hHcmlkMS50b29sYmFyLmdyaWQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBncmlkKCk6IElneEdyaWRCYXNlQ29tcG9uZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZEFQSS5ncmlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgYElneEdyaWRDb21wb25lbnRgIHJlbmRlcnMgYW4gZXhwb3J0IGJ1dHRvbi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZXhwb3J0QnV0dG9uID0gdGhpcy5pZ3hHcmlkMS50b29sYmFyLnNob3VsZFNob3dFeHBvcnRCdXR0b247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBzaG91bGRTaG93RXhwb3J0QnV0dG9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKHRoaXMuZ3JpZCAhPSBudWxsICYmICh0aGlzLmdyaWQuZXhwb3J0RXhjZWwgfHwgdGhpcy5ncmlkLmV4cG9ydENzdikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgYElneEdyaWRDb21wb25lbnRgIHJlbmRlcnMgYW4gRXhjZWwgZXhwb3J0IGJ1dHRvbi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZXhwb3J0RXhjZWxCdXR0b24gPSB0aGlzLmlneEdyaWQxLnRvb2xiYXIuc2hvdWxkU2hvd0V4cG9ydEV4Y2VsQnV0dG9uO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgc2hvdWxkU2hvd0V4cG9ydEV4Y2VsQnV0dG9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKHRoaXMuZ3JpZCAhPSBudWxsICYmIHRoaXMuZ3JpZC5leHBvcnRFeGNlbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBgSWd4R3JpZENvbXBvbmVudGAgcmVuZGVycyBhbiBDU1YgZXhwb3J0IGJ1dHRvbi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgZXhwb3J0Q1NWQnV0dG9uID0gdGhpcy5pZ3hHcmlkMS50b29sYmFyLnNob3VsZFNob3dFeHBvcnRDc3ZCdXR0b247XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBzaG91bGRTaG93RXhwb3J0Q3N2QnV0dG9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKHRoaXMuZ3JpZCAhPSBudWxsICYmIHRoaXMuZ3JpZC5leHBvcnRDc3YpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaG93IG1hbnkgY29sdW1ucyBhcmUgcGlubmVkLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBwaW5uZWRDb3VudCA9IHRoaXMuaWd4R3JpZDEudG9vbGJhci5waW5uZWRDb2x1bW5zQ291bnQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBwaW5uZWRDb2x1bW5zQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyaWQucGlubmVkQ29sdW1ucy5sZW5ndGg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGhlbWUgb2YgdGhlIGBJZ3hHcmlkVG9vbGJhckNvbXBvbmVudGAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IHRvb2xiYXJUaGVtZSA9IHRoaXMuZ3JpZC50b29sYmFyLmhvc3RDbGFzcztcbiAgICAgKiBgYGBcbiAgICAgKi9cblxuICAgIEBIb3N0QmluZGluZygnYXR0ci5jbGFzcycpXG4gICAgZ2V0IGhvc3RDbGFzcygpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDb21wb25lbnREZW5zaXR5Q2xhc3MoJ2lneC1ncmlkLXRvb2xiYXInKTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgZ3JpZEFQSTogR3JpZEJhc2VBUElTZXJ2aWNlPElneEdyaWRCYXNlQ29tcG9uZW50ICYgSUdyaWREYXRhQmluZGFibGU+LFxuICAgICAgICBwdWJsaWMgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICAgICAgQE9wdGlvbmFsKCkgcHVibGljIGV4Y2VsRXhwb3J0ZXI6IElneEV4Y2VsRXhwb3J0ZXJTZXJ2aWNlLFxuICAgICAgICBAT3B0aW9uYWwoKSBwdWJsaWMgY3N2RXhwb3J0ZXI6IElneENzdkV4cG9ydGVyU2VydmljZSxcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChEaXNwbGF5RGVuc2l0eVRva2VuKSBwcm90ZWN0ZWQgX2Rpc3BsYXlEZW5zaXR5T3B0aW9uczogSURpc3BsYXlEZW5zaXR5T3B0aW9ucykge1xuICAgICAgICAgICAgc3VwZXIoX2Rpc3BsYXlEZW5zaXR5T3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcG9zaXRpb25TZXR0aW5nczogUG9zaXRpb25TZXR0aW5ncyA9IHtcbiAgICAgICAgaG9yaXpvbnRhbERpcmVjdGlvbjogSG9yaXpvbnRhbEFsaWdubWVudC5MZWZ0LFxuICAgICAgICBob3Jpem9udGFsU3RhcnRQb2ludDogSG9yaXpvbnRhbEFsaWdubWVudC5SaWdodCxcbiAgICAgICAgdmVydGljYWxEaXJlY3Rpb246IFZlcnRpY2FsQWxpZ25tZW50LkJvdHRvbSxcbiAgICAgICAgdmVydGljYWxTdGFydFBvaW50OiBWZXJ0aWNhbEFsaWdubWVudC5Cb3R0b21cbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBfb3ZlcmxheVNldHRpbmdzOiBPdmVybGF5U2V0dGluZ3MgPSB7XG4gICAgICAgIHBvc2l0aW9uU3RyYXRlZ3k6IG5ldyBDb25uZWN0ZWRQb3NpdGlvbmluZ1N0cmF0ZWd5KHRoaXMuX3Bvc2l0aW9uU2V0dGluZ3MpLFxuICAgICAgICBzY3JvbGxTdHJhdGVneTogbmV3IEFic29sdXRlU2Nyb2xsU3RyYXRlZ3koKSxcbiAgICAgICAgbW9kYWw6IGZhbHNlLFxuICAgICAgICBjbG9zZU9uT3V0c2lkZUNsaWNrOiB0cnVlLFxuICAgICAgICBleGNsdWRlUG9zaXRpb25UYXJnZXQ6IHRydWVcbiAgICB9O1xuXG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aXRsZSBvZiBgSWd4R3JpZFRvb2xiYXJDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCB0b29sYmFyVGl0bGUgPSB0aGlzLmlneEdyaWQxLnRvb2xiYXIuZ2V0VGl0bGUoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0VGl0bGUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZCAhPSBudWxsID8gdGhpcy5ncmlkLnRvb2xiYXJUaXRsZSA6ICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHRleHQgb2YgdGhlIGV4cG9ydCBidXR0b24gb2YgdGhlIGBJZ3hHcmlkVG9vbGJhckNvbXBvbmVudGAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IHRvb2xiYXJFeHBvcnRUZXh0ID0gdGhpcy5pZ3hHcmlkMS50b29sYmFyLmdldFRpdGxlKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldEV4cG9ydFRleHQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZCAhPSBudWxsID8gdGhpcy5ncmlkLmV4cG9ydFRleHQgOiAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0ZXh0IG9mIHRoZSBFeGNlbCBleHBvcnQgYnV0dG9uIG9mIHRoZSBgSWd4R3JpZFRvb2xiYXJDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCB0b29sYmFyRXhjZWxUZXh0ID0gdGhpcy5pZ3hHcmlkMS50b29sYmFyLmdldEV4cG9ydEV4Y2VsVGV4dCgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRFeHBvcnRFeGNlbFRleHQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZCAhPSBudWxsID8gdGhpcy5ncmlkLmV4cG9ydEV4Y2VsVGV4dCA6ICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHRleHQgb2YgdGhlIENTViBleHBvcnQgYnV0dG9uIG9mIHRoZSBgSWd4R3JpZFRvb2xiYXJDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCB0b29sYmFyQ1NWVGV4dCA9IHRoaXMuaWd4R3JpZDEudG9vbGJhci5nZXRFeHBvcnRDc3ZUZXh0KCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldEV4cG9ydENzdlRleHQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JpZCAhPSBudWxsID8gdGhpcy5ncmlkLmV4cG9ydENzdlRleHQgOiAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUb2dnbGVzIHRoZSBleHBvcnQgYnV0dG9uJ3MgZHJvcGRvd24gbWVudS5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5pZ3hHcmlkMS50b29sYmFyLmV4cG9ydENsaWNrZWQoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZXhwb3J0Q2xpY2tlZCgpIHtcbiAgICAgICAgdGhpcy5fb3ZlcmxheVNldHRpbmdzLnBvc2l0aW9uU3RyYXRlZ3kuc2V0dGluZ3MudGFyZ2V0ID0gdGhpcy5leHBvcnRCdXR0b24ubmF0aXZlRWxlbWVudDtcbiAgICAgICAgdGhpcy5fb3ZlcmxheVNldHRpbmdzLm91dGxldCA9IHRoaXMuZ3JpZC5vdXRsZXREaXJlY3RpdmU7XG4gICAgICAgIHRoaXMuZXhwb3J0RHJvcGRvd24udG9nZ2xlKHRoaXMuX292ZXJsYXlTZXR0aW5ncyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhwb3J0cyB0aGUgZ3JpZCB0byBleGNlbC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5pZ3hHcmlkMS50b29sYmFyLmV4cG9ydFRvRXhjZWxDbGlja2VkKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGV4cG9ydFRvRXhjZWxDbGlja2VkKCkge1xuICAgICAgICB0aGlzLnBlcmZvcm1FeHBvcnQodGhpcy5leGNlbEV4cG9ydGVyLCAnZXhjZWwnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHBvcnRzIHRoZSBncmlkIHRvIENTVi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5pZ3hHcmlkMS50b29sYmFyLmV4cG9ydFRvQ3N2Q2xpY2tlZCgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBleHBvcnRUb0NzdkNsaWNrZWQoKSB7XG4gICAgICAgIHRoaXMucGVyZm9ybUV4cG9ydCh0aGlzLmNzdkV4cG9ydGVyLCAnY3N2Jyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwZXJmb3JtRXhwb3J0KGV4cDogSWd4QmFzZUV4cG9ydGVyLCBleHBvcnRUeXBlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5leHBvcnRDbGlja2VkKCk7XG5cbiAgICAgICAgY29uc3QgZmlsZU5hbWUgPSAnRXhwb3J0ZWREYXRhJztcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGV4cG9ydFR5cGUgPT09ICdleGNlbCcgP1xuICAgICAgICAgICAgbmV3IElneEV4Y2VsRXhwb3J0ZXJPcHRpb25zKGZpbGVOYW1lKSA6XG4gICAgICAgICAgICBuZXcgSWd4Q3N2RXhwb3J0ZXJPcHRpb25zKGZpbGVOYW1lLCBDc3ZGaWxlVHlwZXMuQ1NWKTtcblxuICAgICAgICBjb25zdCBhcmdzID0geyBncmlkOiB0aGlzLmdyaWQsIGV4cG9ydGVyOiBleHAsIG9wdGlvbnM6IG9wdGlvbnMsIGNhbmNlbDogZmFsc2UgfTtcblxuICAgICAgICB0aGlzLmdyaWQub25Ub29sYmFyRXhwb3J0aW5nLmVtaXQoYXJncyk7XG4gICAgICAgIGlmIChhcmdzLmNhbmNlbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGV4cC5leHBvcnQodGhpcy5ncmlkLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUb2dnbGVzIHRoZSBDb2x1bW4gSGlkaW5nIFVJLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmdyaWQxLnRvb2xiYXIudG9nZ2xlQ29sdW1uSGlkaW5nVUkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgdG9nZ2xlQ29sdW1uSGlkaW5nVUkoKSB7XG4gICAgICAgIHRoaXMuX292ZXJsYXlTZXR0aW5ncy5wb3NpdGlvblN0cmF0ZWd5LnNldHRpbmdzLnRhcmdldCA9IHRoaXMuY29sdW1uSGlkaW5nQnV0dG9uLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIHRoaXMuX292ZXJsYXlTZXR0aW5ncy5vdXRsZXQgPSB0aGlzLmdyaWQub3V0bGV0RGlyZWN0aXZlO1xuICAgICAgICB0aGlzLmNvbHVtbkhpZGluZ0Ryb3Bkb3duLnRvZ2dsZSh0aGlzLl9vdmVybGF5U2V0dGluZ3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRvZ2dsZXMgdGhlIENvbHVtbiBQaW5uaW5nIFVJLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmdyaWQxLnRvb2xiYXIudG9nZ2xlQ29sdW1uUGlubmluZ1VJKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIHRvZ2dsZUNvbHVtblBpbm5pbmdVSSgpIHtcbiAgICAgICAgdGhpcy5fb3ZlcmxheVNldHRpbmdzLnBvc2l0aW9uU3RyYXRlZ3kuc2V0dGluZ3MudGFyZ2V0ID0gdGhpcy5jb2x1bW5QaW5uaW5nQnV0dG9uLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIHRoaXMuX292ZXJsYXlTZXR0aW5ncy5vdXRsZXQgPSB0aGlzLmdyaWQub3V0bGV0RGlyZWN0aXZlO1xuICAgICAgICB0aGlzLmNvbHVtblBpbm5pbmdEcm9wZG93bi50b2dnbGUodGhpcy5fb3ZlcmxheVNldHRpbmdzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgY29udGV4dGAgb2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIGB0ZW1wbGF0ZSBjb250ZXh0YCBiaW5kaW5nIGludG8gdGhlXG4gICAgICogYHRvb2xiYXIgY3VzdG9t