@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
776 lines • 107 kB
JavaScript
import { __decorate, __extends, __metadata, __read, __spread } from "tslib";
import { ChangeDetectionStrategy, Component, HostBinding, Input, forwardRef, TemplateRef, ViewChild, ViewChildren, QueryList, ContentChildren, ElementRef, EventEmitter, Output } from '@angular/core';
import { IgxGridBaseDirective } from '../grid-base.directive';
import { GridBaseAPIService } from '../api.service';
import { IgxHierarchicalGridAPIService } from './hierarchical-grid-api.service';
import { IgxRowIslandComponent } from './row-island.component';
import { IgxChildGridRowComponent } from './child-grid-row.component';
import { IgxFilteringService } from '../filtering/grid-filtering.service';
import { DisplayDensity } from '../../core/displayDensity';
import { IgxHierarchicalGridNavigationService } from './hierarchical-grid-navigation.service';
import { IgxGridSummaryService } from '../summaries/grid-summary.service';
import { IgxHierarchicalGridBaseDirective } from './hierarchical-grid-base.directive';
import { takeUntil } from 'rxjs/operators';
import { IgxTemplateOutletDirective } from '../../directives/template-outlet/template_outlet.directive';
import { IgxGridSelectionService, IgxGridCRUDService } from '../selection/selection.service';
import { IgxTransactionService } from '../../services/index';
import { IgxForOfSyncService, IgxForOfScrollSyncService } from '../../directives/for-of/for_of.sync.service';
import { IgxRowIslandAPIService } from './row-island-api.service';
var NEXT_ID = 0;
var IgxHierarchicalGridComponent = /** @class */ (function (_super) {
__extends(IgxHierarchicalGridComponent, _super);
function IgxHierarchicalGridComponent() {
var _this = _super !== null && _super.apply(this, arguments) || this;
/**
*@hidden
*/
_this.hierarchicalStateChange = new EventEmitter();
/**
* @hidden
*/
_this.childLayoutKeys = [];
/**
* @hidden
*/
_this.highlightedRowID = null;
/**
* @hidden
*/
_this.updateOnRender = false;
/**
* @hidden
*/
_this.parent = null;
_this._hierarchicalState = [];
_this._filteredData = null;
_this.h_id = "igx-hierarchical-grid-" + NEXT_ID++;
_this.childGridTemplates = new Map();
_this.scrollTop = 0;
_this.scrollLeft = 0;
return _this;
}
IgxHierarchicalGridComponent_1 = IgxHierarchicalGridComponent;
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "id", {
/**
* Sets the value of the `id` attribute. If not provided it will be automatically generated.
* ```html
* <igx-hierarchical-grid [id]="'igx-hgrid-1'" [data]="Data" [autoGenerate]="true"></igx-hierarchical-grid>
* ```
* @memberof IgxHierarchicalGridComponent
*/
get: function () {
return this.h_id;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "data", {
/**
* Returns an array of data set to the `IgxHierarchicalGridComponent`.
* ```typescript
* let filteredData = this.grid.filteredData;
* ```
* @memberof IgxHierarchicalGridComponent
*/
get: function () {
return this._data;
},
/**
* An @Input property that lets you fill the `IgxHierarchicalGridComponent` with an array of data.
* ```html
* <igx-hierarchical-grid [data]="Data" [autoGenerate]="true"></igx-hierarchical-grid>
* ```
* @memberof IgxHierarchicalGridComponent
*/
set: function (value) {
this._data = value || [];
this.summaryService.clearSummaryCache();
if (this.shouldGenerate) {
this.setupColumns();
this.reflow();
}
this.cdr.markForCheck();
if (this.parent && (this.height === null || this.height.indexOf('%') !== -1)) {
// If the height will change based on how much data there is, recalculate sizes in igxForOf.
this.notifyChanges(true);
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "hierarchicalState", {
/**
* Sets the state of the `IgxHierarchicalGridComponent` containing which rows are expanded.
* ```typescript
* this.gridState = [{ rowID: 1 }, { rowID: 4}];
* ```
* ```html
* <igx-hierarchical-grid [primaryKey]="'ID'" [data]="Data" [autoGenerate]="false" [hierarchicalState]="hgridState">
* <igx-column field="ID" [dataType]='number'></igx-column>
* <igx-column field="Product" [dataType]='string'></igx-column>
* <igx-column field="Description" [dataType]='string'></igx-column>
* </igx-hierarchical-grid>
* ```
*
* Two-way data binding.
* ```html
* <igx-hierarchical-grid [primaryKey]="'ID'" [data]="Data" [autoGenerate]="false" [(hierarchicalState)]="hgridState">
* <igx-column field="ID" [dataType]='number'></igx-column>
* <igx-column field="Product" [dataType]='string'></igx-column>
* <igx-column field="Description" [dataType]='string'></igx-column>
* </igx-hierarchical-grid>
* ```
* @memberof IgxHierarchicalGridComponent
*/
get: function () {
return this._hierarchicalState;
},
set: function (val) {
var _this = this;
if (this._hierarchicalState !== val) {
this.hierarchicalStateChange.emit(val);
}
if (this.hasChildrenKey) {
val = val.filter(function (item) {
var rec = _this.primaryKey ? _this.data.find(function (x) { return x[_this.primaryKey] === item.rowID; }) : item.rowID;
return rec[_this.hasChildrenKey];
});
}
this._hierarchicalState = val;
if (this.parent) {
this.notifyChanges(true);
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "filteredData", {
/**
* Returns an array of objects containing the filtered data in the `IgxHierarchicalGridComponent`.
* ```typescript
* let filteredData = this.grid.filteredData;
* ```
* @memberof IgxHierarchicalGridComponent
*/
get: function () {
return this._filteredData;
},
/**
* Sets an array of objects containing the filtered data in the `IgxHierarchicalGridComponent`.
* ```typescript
* this.grid.filteredData = [{
* ID: 1,
* Name: "A"
* }];
* ```
* @memberof IgxHierarchicalGridComponent
*/
set: function (value) {
this._filteredData = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "expandChildren", {
/**
* Gets if all immediate children of the `IgxHierarchicalGridComponent` previously have been set to be expanded/collapsed.
* If previously set and some rows have been manually expanded/collapsed it will still return the last set value.
* ```typescript
* const expanded = this.grid.expandChildren;
* ```
* @memberof IgxHierarchicalGridComponent
*/
get: function () {
return this._expandChildren;
},
/**
* Sets if all immediate children of the `IgxHierarchicalGridComponent` should be expanded/collapsed.
* Defult value is false.
* ```html
* <igx-hierarchical-grid [id]="'igx-grid-1'" [data]="Data" [autoGenerate]="true" [expandChildren]="true"></igx-hierarchical-grid>
* ```
* @memberof IgxHierarchicalGridComponent
*/
set: function (value) {
var _this = this;
this._expandChildren = value;
if (value && this.data) {
this.hierarchicalState = this.data.map(function (rec) {
return { rowID: _this.primaryKey ? rec[_this.primaryKey] : rec };
});
}
else if (this.data) {
this.hierarchicalState = [];
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "foreignKey", {
/**
* Gets the unique identifier of the parent row. It may be a `string` or `number` if `primaryKey` of the
* parent grid is set or an object reference of the parent record otherwise.
* ```typescript
* const foreignKey = this.grid.foreignKey;
* ```
* @memberof IgxHierarchicalGridComponent
*/
get: function () {
if (!this.parent) {
return null;
}
return this.parent.hgridAPI.getParentRowId(this);
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "hasExpandableChildren", {
/**
* @hidden
*/
get: function () {
return !!this.childLayoutKeys.length;
},
enumerable: true,
configurable: true
});
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.ngOnInit = function () {
if (this._transactions instanceof IgxTransactionService) {
// transaction service cannot be injected in a derived class in a factory manner
this._transactions = new IgxTransactionService();
}
_super.prototype.ngOnInit.call(this);
};
IgxHierarchicalGridComponent.prototype.ngDoCheck = function () {
if (this._cdrRequestRepaint && !this._init) {
this.updateSizes();
}
_super.prototype.ngDoCheck.call(this);
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.ngAfterViewInit = function () {
var _this = this;
_super.prototype.ngAfterViewInit.call(this);
this.verticalScrollContainer.getScroll().addEventListener('scroll', this.hg_verticalScrollHandler.bind(this));
this.headerContainer.getScroll().addEventListener('scroll', this.hg_horizontalScrollHandler.bind(this));
if (this.expandChildren && this.data && this.hierarchicalState.length !== this.data.length) {
this.hierarchicalState = this.data.map(function (rec) {
return { rowID: _this.primaryKey ? rec[_this.primaryKey] : rec };
});
this.cdr.detectChanges();
}
this.verticalScrollContainer.onBeforeViewDestroyed.pipe(takeUntil(this.destroy$)).subscribe(function (view) {
var rowData = view.context.$implicit;
if (_this.isChildGridRecord(rowData)) {
var cachedData = _this.childGridTemplates.get(rowData.rowID);
if (cachedData) {
var tmlpOutlet = cachedData.owner;
tmlpOutlet._viewContainerRef.detach(0);
}
}
});
if (this.parent) {
this._displayDensity = this.rootGrid._displayDensity;
this.rootGrid.onDensityChanged.pipe(takeUntil(this.destroy$)).subscribe(function () {
_this._displayDensity = _this.rootGrid._displayDensity;
_this.notifyChanges(true);
_this.cdr.markForCheck();
});
this.childLayoutKeys = this.parentIsland.children.map(function (item) { return item.key; });
}
this.toolbarCustomContentTemplates = this.parentIsland ?
this.parentIsland.toolbarCustomContentTemplates :
this.toolbarCustomContentTemplates;
this.headSelectorsTemplates = this.parentIsland ?
this.parentIsland.headSelectorsTemplates :
this.headSelectorsTemplates;
this.rowSelectorsTemplates = this.parentIsland ?
this.parentIsland.rowSelectorsTemplates :
this.rowSelectorsTemplates;
this.dragIndicatorIconTemplate = this.parentIsland ?
this.parentIsland.dragIndicatorIconTemplate :
this.dragIndicatorIconTemplate;
this.rowExpandedIndicatorTemplate = this.rootGrid.rowExpandedIndicatorTemplate;
this.rowCollapsedIndicatorTemplate = this.rootGrid.rowCollapsedIndicatorTemplate;
this.headerCollapseIndicatorTemplate = this.rootGrid.headerCollapseIndicatorTemplate;
this.headerExpandIndicatorTemplate = this.rootGrid.headerExpandIndicatorTemplate;
this.hasChildrenKey = this.parentIsland ?
this.parentIsland.hasChildrenKey || this.rootGrid.hasChildrenKey :
this.rootGrid.hasChildrenKey;
this.showExpandAll = this.parentIsland ?
this.parentIsland.showExpandAll : this.rootGrid.showExpandAll;
};
IgxHierarchicalGridComponent.prototype.updateSizes = function () {
if (document.body.contains(this.nativeElement) && this.isPercentWidth) {
this.reflow();
this.hgridAPI.getChildGrids(false).forEach(function (grid) {
grid.updateSizes();
});
}
};
IgxHierarchicalGridComponent.prototype._shouldAutoSize = function (renderedHeight) {
if (this.isPercentHeight && this.parent) {
return true;
}
return _super.prototype._shouldAutoSize.call(this, renderedHeight);
};
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "outletDirective", {
get: function () {
return this.rootGrid._outletDirective;
},
enumerable: true,
configurable: true
});
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.ngAfterContentInit = function () {
var _this = this;
this.updateColumnList(false);
this.childLayoutKeys = this.parent ?
this.parentIsland.children.map(function (item) { return item.key; }) :
this.childLayoutKeys = this.childLayoutList.map(function (item) { return item.key; });
this.childLayoutList.notifyOnChanges();
this.childLayoutList.changes.pipe(takeUntil(this.destroy$))
.subscribe(function () { return _this.onRowIslandChange(); });
_super.prototype.ngAfterContentInit.call(this);
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.onRowIslandChange = function () {
if (this.parent) {
this.childLayoutKeys = this.parentIsland.children.filter(function (item) { return !item._destroyed; }).map(function (item) { return item.key; });
}
else {
this.childLayoutKeys = this.childLayoutList.filter(function (item) { return !item._destroyed; }).map(function (item) { return item.key; });
}
if (!this.cdr.destroyed) {
this.cdr.detectChanges();
}
};
IgxHierarchicalGridComponent.prototype.onColumnsChanged = function (change) {
var _this = this;
this.updateColumnList();
var cols = change.filter(function (c) { return c.gridAPI.grid === _this; });
if (cols.length > 0) {
this.columnList.reset(cols);
_super.prototype.onColumnsChanged.call(this, this.columnList);
}
};
IgxHierarchicalGridComponent.prototype.updateColumnList = function (recalcColSizes) {
if (recalcColSizes === void 0) { recalcColSizes = true; }
var childLayouts = this.parent ? this.childLayoutList : this.allLayoutList;
var nestedColumns = childLayouts.map(function (layout) {
return layout.columnList.toArray();
});
var colsArray = [].concat.apply([], nestedColumns);
var colLength = this.columnList.length;
if (colsArray.length > 0) {
var topCols = this.columnList.filter(function (item) {
return colsArray.indexOf(item) === -1;
});
this.columnList.reset(topCols);
if (recalcColSizes && this.columnList.length !== colLength) {
this.calculateGridSizes();
}
}
};
IgxHierarchicalGridComponent.prototype.ngOnDestroy = function () {
if (!this.parent) {
this.hgridAPI.getChildGrids(true).forEach(function (grid) {
if (!grid.childRow.cdr.destroyed) {
grid.childRow.cdr.destroy();
}
});
}
if (this.parent && this.selectionService.activeElement) {
// in case selection is in destroyed child grid, selection should be cleared.
this._clearSeletionHighlights();
}
_super.prototype.ngOnDestroy.call(this);
};
IgxHierarchicalGridComponent.prototype._clearSeletionHighlights = function () {
__spread([this.rootGrid], this.rootGrid.getChildGrids(true)).forEach(function (grid) {
grid.selectionService.clear();
grid.selectionService.activeElement = null;
grid.nativeElement.classList.remove('igx-grid__tr--highlighted');
grid.highlightedRowID = null;
grid.cdr.markForCheck();
});
};
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "template", {
/**
* @hidden
*/
get: function () {
if (this.filteredData && this.filteredData.length === 0) {
return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyFilteredGridTemplate;
}
if (this.isLoading && (!this.data || this.dataLength === 0)) {
return this.loadingGridTemplate ? this.loadingGridTemplate : this.loadingGridDefaultTemplate;
}
if (this.dataLength === 0) {
return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyGridDefaultTemplate;
}
},
enumerable: true,
configurable: true
});
/**
* @hidden
* Gets the combined width of the columns that are specific to the enabled grid features. They are fixed.
* TODO: Remove for Angular 8. Calling parent class getter using super is not supported for now.
*/
IgxHierarchicalGridComponent.prototype.getFeatureColumnsWidth = function () {
var width = _super.prototype.getFeatureColumnsWidth.call(this);
if (this.hasExpandableChildren) {
width += this.headerHierarchyExpander.nativeElement.offsetWidth || this.getDefaultExpanderWidth();
}
return width;
};
IgxHierarchicalGridComponent.prototype.getDefaultExpanderWidth = function () {
switch (this.displayDensity) {
case DisplayDensity.cosy:
return 57;
case DisplayDensity.compact:
return 49;
default:
return 72;
}
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.isRowHighlighted = function (rowData) {
return this.highlightedRowID === rowData.rowID;
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.isHierarchicalRecord = function (record) {
return this.childLayoutList.length !== 0 && record[this.childLayoutList.first.key];
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.isChildGridRecord = function (record) {
// Can be null when there is defined layout but no child data was found
return record.childGridsData !== undefined;
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.trackChanges = function (index, rec) {
if (rec.childGridsData !== undefined) {
// if is child rec
return rec.rowID;
}
return rec;
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.getContext = function (rowData) {
if (this.isChildGridRecord(rowData)) {
var cachedData = this.childGridTemplates.get(rowData.rowID);
if (cachedData) {
var view = cachedData.view;
var tmlpOutlet = cachedData.owner;
return {
$implicit: rowData,
moveView: view,
owner: tmlpOutlet,
index: this.dataView.indexOf(rowData)
};
}
else {
var rowID = this.primaryKey ? rowData.rowID : this.data.indexOf(rowData.rowID);
// child rows contain unique grids, hence should have unique templates
return {
$implicit: rowData,
templateID: 'childRow-' + rowID,
index: this.dataView.indexOf(rowData)
};
}
}
else {
return {
$implicit: rowData,
templateID: 'dataRow',
index: this.dataView.indexOf(rowData)
};
}
};
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "rootGrid", {
/**
* @hidden
*/
get: function () {
var currGrid = this;
while (currGrid.parent) {
currGrid = currGrid.parent;
}
return currGrid;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxHierarchicalGridComponent.prototype, "iconTemplate", {
/**
* @hidden
*/
get: function () {
var expanded = this.hierarchicalState.length > 0 && this.hasExpandableChildren;
if (!expanded && this.showExpandAll) {
return this.headerCollapseIndicatorTemplate || this.defaultCollapsedTemplate;
}
else {
return this.headerExpandIndicatorTemplate || this.defaultExpandedTemplate;
}
},
enumerable: true,
configurable: true
});
/**
* @hidden
* @internal
*/
IgxHierarchicalGridComponent.prototype.getDragGhostCustomTemplate = function () {
if (this.parentIsland) {
return this.parentIsland.getDragGhostCustomTemplate();
}
return _super.prototype.getDragGhostCustomTemplate.call(this);
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.initColumns = function (collection, cb) {
if (cb === void 0) { cb = null; }
if (this.hasColumnLayouts) {
// invalid configuration - hierarchical grid should not allow column layouts
// remove column layouts
var nonColumnLayoutColumns = this.columnList.filter(function (col) { return !col.columnLayout && !col.columnLayoutChild; });
this.columnList.reset(nonColumnLayoutColumns);
}
_super.prototype.initColumns.call(this, collection, cb);
};
/**
* @hidden
* Gets the visible content height that includes header + tbody + footer.
* For hierarchical child grid it may be scrolled and not fully visible.
*/
IgxHierarchicalGridComponent.prototype.getVisibleContentHeight = function () {
var height = _super.prototype.getVisibleContentHeight.call(this);
if (this.parent) {
var rootHeight = this.rootGrid.getVisibleContentHeight();
var topDiff = this.nativeElement.getBoundingClientRect().top - this.rootGrid.nativeElement.getBoundingClientRect().top;
height = rootHeight - topDiff > height ? height : rootHeight - topDiff;
}
return height;
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.toggleAll = function () {
var expanded = this.hierarchicalState.length > 0 && this.hasExpandableChildren;
if (!expanded && this.showExpandAll) {
this.expandAll();
}
else {
this.collapseAll();
}
};
/**
* Collapses all rows of the current hierarchical grid.
* ```typescript
* this.grid.collapseAll();
* ```
* @memberof IgxHierarchicalGridComponent
*/
IgxHierarchicalGridComponent.prototype.collapseAll = function () {
this.hierarchicalState = [];
};
/**
* Expands all rows of the current hierarchical grid.
* ```typescript
* this.grid.expandAll();
* ```
* @memberof IgxHierarchicalGridComponent
*/
IgxHierarchicalGridComponent.prototype.expandAll = function () {
var _this = this;
if (this.data) {
this.hierarchicalState = this.data.map(function (rec) {
return { rowID: _this.primaryKey ? rec[_this.primaryKey] : rec };
});
}
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.isExpanded = function (record) {
var _this = this;
var inState;
if (record.childGridsData !== undefined) {
inState = !!this.hierarchicalState.find(function (v) { return v.rowID === record.rowID; });
}
else {
inState = !!this.hierarchicalState.find(function (v) {
return _this.primaryKey ? v.rowID === record[_this.primaryKey] : v.rowID === record;
});
}
return inState && this.childLayoutList.length !== 0;
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.viewCreatedHandler = function (args) {
if (this.isChildGridRecord(args.context.$implicit)) {
var key = args.context.$implicit.rowID;
this.childGridTemplates.set(key, args);
}
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.viewMovedHandler = function (args) {
var _this = this;
if (this.isChildGridRecord(args.context.$implicit)) {
// view was moved, update owner in cache
var key = args.context.$implicit.rowID;
var cachedData = this.childGridTemplates.get(key);
cachedData.owner = args.owner;
this.childLayoutList.forEach(function (layout) {
var relatedGrid = _this.hgridAPI.getChildGridByID(layout.key, args.context.$implicit.rowID);
if (relatedGrid && relatedGrid.updateOnRender) {
// Detect changes if `expandChildren` has changed when the grid wasn't visible. This is for performance reasons.
relatedGrid.notifyChanges(true);
relatedGrid.updateOnRender = false;
}
});
var childGrids = this.getChildGrids(true);
childGrids.forEach(function (grid) {
if (grid.isPercentWidth) {
grid.notifyChanges(true);
}
grid.updateScrollPosition();
});
}
};
/**
* @hidden
*/
IgxHierarchicalGridComponent.prototype.updateScrollPosition = function () {
var vScr = this.verticalScrollContainer.getScroll();
var hScr = this.headerContainer.getScroll();
if (vScr) {
vScr.scrollTop = this.scrollTop;
}
if (hScr) {
hScr.scrollLeft = this.scrollLeft;
}
};
IgxHierarchicalGridComponent.prototype.getChildGrids = function (inDeph) {
return this.hgridAPI.getChildGrids(inDeph);
};
IgxHierarchicalGridComponent.prototype.generateDataFields = function (data) {
var _this = this;
return _super.prototype.generateDataFields.call(this, data).filter(function (field) {
var layoutsList = _this.parentIsland ? _this.parentIsland.children : _this.childLayoutList;
var keys = layoutsList.map(function (item) { return item.key; });
return keys.indexOf(field) === -1;
});
};
IgxHierarchicalGridComponent.prototype.hg_verticalScrollHandler = function (event) {
this.scrollTop = event.target.scrollTop;
};
IgxHierarchicalGridComponent.prototype.onContainerScroll = function () {
this.hideOverlays();
};
IgxHierarchicalGridComponent.prototype.hg_horizontalScrollHandler = function (event) {
this.scrollLeft = event.target.scrollLeft;
};
var IgxHierarchicalGridComponent_1;
__decorate([
HostBinding('attr.id'),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [])
], IgxHierarchicalGridComponent.prototype, "id", null);
__decorate([
Input(),
__metadata("design:type", Array),
__metadata("design:paramtypes", [Array])
], IgxHierarchicalGridComponent.prototype, "data", null);
__decorate([
Input(),
__metadata("design:type", Object),
__metadata("design:paramtypes", [Object])
], IgxHierarchicalGridComponent.prototype, "hierarchicalState", null);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxHierarchicalGridComponent.prototype, "hierarchicalStateChange", void 0);
__decorate([
Input(),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [Boolean])
], IgxHierarchicalGridComponent.prototype, "expandChildren", null);
__decorate([
ContentChildren(IgxRowIslandComponent, { read: IgxRowIslandComponent, descendants: false }),
__metadata("design:type", QueryList)
], IgxHierarchicalGridComponent.prototype, "childLayoutList", void 0);
__decorate([
ContentChildren(IgxRowIslandComponent, { read: IgxRowIslandComponent, descendants: true }),
__metadata("design:type", QueryList)
], IgxHierarchicalGridComponent.prototype, "allLayoutList", void 0);
__decorate([
ViewChild('hierarchical_record_template', { read: TemplateRef, static: true }),
__metadata("design:type", TemplateRef)
], IgxHierarchicalGridComponent.prototype, "hierarchicalRecordTemplate", void 0);
__decorate([
ViewChild('child_record_template', { read: TemplateRef, static: true }),
__metadata("design:type", TemplateRef)
], IgxHierarchicalGridComponent.prototype, "childTemplate", void 0);
__decorate([
ViewChild('headerHierarchyExpander', { read: ElementRef, static: true }),
__metadata("design:type", ElementRef)
], IgxHierarchicalGridComponent.prototype, "headerHierarchyExpander", void 0);
__decorate([
ViewChildren(IgxTemplateOutletDirective, { read: IgxTemplateOutletDirective }),
__metadata("design:type", QueryList)
], IgxHierarchicalGridComponent.prototype, "templateOutlets", void 0);
__decorate([
ViewChildren(IgxChildGridRowComponent, { read: IgxChildGridRowComponent }),
__metadata("design:type", QueryList)
], IgxHierarchicalGridComponent.prototype, "hierarchicalRows", void 0);
IgxHierarchicalGridComponent = IgxHierarchicalGridComponent_1 = __decorate([
Component({
changeDetection: ChangeDetectionStrategy.OnPush,
preserveWhitespaces: false,
selector: 'igx-hierarchical-grid',
template: "<igx-grid-toolbar role=\"rowgroup\" [style.flex-basis.px]=\"outerWidth\" *ngIf=\"showToolbar\" [gridID]=\"id\"\n [displayDensity]=\"displayDensity\" #toolbar>\n</igx-grid-toolbar>\n\n<div class=\"igx-grid__thead\">\n <div class=\"igx-grid__thead-wrapper\" role=\"rowgroup\" [style.width.px]='calcWidth' #theadRow>\n <div class=\"igx-grid__tr\" role=\"row\" [style.width.px]='calcWidth'>\n <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length <= 0\"\n [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n class=\"igx-grid__scroll-on-drag-left\"></span>\n <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length > 0\"\n [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n class=\"igx-grid__scroll-on-drag-pinned\" [style.left.px]=\"pinnedWidth\"></span>\n <div #headerHierarchyExpander (click)=\"toggleAll()\" [hidden]='!hasExpandableChildren || !hasVisibleColumns' [ngClass]=\"{\n 'igx-grid__hierarchical-expander igx-grid__hierarchical-expander--header': hasExpandableChildren,\n 'igx-grid__hierarchical-expander--push': filteringService.isFilterRowVisible,\n 'igx-grid__hierarchical-expander--no-border': isRowSelectable || rowDraggable\n }\">\n <ng-container *ngTemplateOutlet=\"iconTemplate; context: { $implicit: this }\"></ng-container>\n </div>\n <ng-container *ngIf=\"rowDraggable\">\n <div class=\"igx-grid__drag-indicator\" [ngClass]=\"{\n 'igx-grid__drag-indicator--header': !isRowSelectable\n }\" #headerDragContainer>\n <div style=\"visibility: hidden;\">\n <ng-container\n *ngTemplateOutlet=\"this.dragIndicatorIconTemplate ? this.dragIndicatorIconTemplate : this.dragIndicatorIconBase\">\n </ng-container>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"showRowSelectors\">\n <div class=\"igx-grid__cbx-selection\" (click)=\"onHeaderSelectorClick($event)\" #headerSelectorContainer [ngClass]=\"{\n 'igx-grid__cbx-selection--push': filteringService.isFilterRowVisible\n }\">\n <ng-template #headSelector\n *ngTemplateOutlet=\"\n this.headSelectorTemplate ? this.headSelectorTemplate : headSelectorBaseTemplate;\n context: { $implicit: {\n selectedCount: this.selectionService.filteredSelectedRowIds.length,\n totalCount: this.totalRowsCountAfterFilter,\n selectAll: selectAllRows.bind(this),\n deselectAll: deselectAllRows.bind(this) }}\">\n </ng-template>\n </div>\n </ng-container>\n <ng-container *ngIf=\"pinnedColumns.length > 0\">\n <ng-template ngFor let-col [ngForOf]=\"pinnedColumns | igxTopLevel\">\n <igx-grid-header-group [column]=\"col\" [gridID]=\"id\" [style.min-width]=\"getHeaderGroupWidth(col)\"\n [style.flex-basis]=\"getHeaderGroupWidth(col)\"></igx-grid-header-group>\n </ng-template>\n </ng-container>\n <ng-template igxGridFor let-col [igxGridForOf]=\"unpinnedColumns | igxTopLevel\"\n [igxForScrollOrientation]=\"'horizontal'\" [igxForScrollContainer]=\"parentVirtDir\"\n [igxForContainerSize]='unpinnedWidth' [igxForTrackBy]='trackColumnChanges'\n [igxForSizePropName]='\"calcPixelWidth\"' #hContainer>\n <igx-grid-header-group [column]=\"col\" [gridID]=\"id\" [style.min-width]=\"getHeaderGroupWidth(col)\"\n [style.flex-basis]=\"getHeaderGroupWidth(col)\"></igx-grid-header-group>\n </ng-template>\n </div>\n <igx-grid-filtering-row #filteringRow [style.width.px]='calcWidth' *ngIf=\"filteringService.isFilterRowVisible\"\n [column]=\"filteringService.filteredColumn\"></igx-grid-filtering-row>\n </div>\n <div [style.display]=\"shouldOverlayLoading ? 'flex' : 'none'\" #loadingOverlay>\n <igx-circular-bar [indeterminate]=\"true\">\n </igx-circular-bar>\n </div>\n <span *ngIf=\"hasMovableColumns && draggedColumn\" [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\"\n id=\"right\" class=\"igx-grid__scroll-on-drag-right\"></span>\n <div class=\"igx-grid__thead-thumb\" [hidden]='!hasVerticalSroll()' [style.width.px]=\"scrollWidth\"></div>\n</div>\n\n<div igxGridBody (keydown.control.c)=\"copyHandlerIE()\" (copy)=\"copyHandler($event)\" class=\"igx-grid__tbody\">\n <div class=\"igx-grid__tbody-content\" (onDragStop)=\"selectionService.dragMode = $event\"\n (onDragScroll)=\"dragScroll($event)\" [igxGridDragSelect]=\"selectionService.dragMode\" role=\"rowgroup\"\n [style.height.px]='calcHeight' [style.width.px]='calcWidth' #tbody (scroll)='scrollHandler($event)'>\n <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length <= 0\"\n [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n class=\"igx-grid__scroll-on-drag-left\"></span>\n <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length > 0\"\n [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n class=\"igx-grid__scroll-on-drag-pinned\" [style.left.px]=\"pinnedWidth\"></span>\n <ng-template igxGridFor let-rowData [igxGridForOf]=\"data\n | gridTransaction:id:pipeTrigger\n | visibleColumns:hasVisibleColumns\n | gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger\n | gridSort:sortingExpressions:sortStrategy:id:pipeTrigger\n | gridHierarchicalPaging:page:perPage:id:pipeTrigger\n | gridHierarchical:hierarchicalState:id:primaryKey:childLayoutKeys:pipeTrigger\" let-rowIndex=\"index\"\n [igxForScrollOrientation]=\"'vertical'\" [igxForScrollContainer]='verticalScroll'\n [igxForContainerSize]='calcHeight' [igxForItemSize]=\"renderedRowHeight\" [igxForTrackBy]='trackChanges'\n #verticalScrollContainer (onChunkPreload)=\"dataLoading($event)\">\n <ng-template #hierarchical_record_template>\n <igx-hierarchical-grid-row [gridID]=\"id\" [index]=\"rowIndex\" [rowData]=\"rowData\" #row>\n </igx-hierarchical-grid-row>\n </ng-template>\n <ng-template #child_record_template let-rowIndex=\"index\" let-rowData>\n <div style=\"overflow:auto;width: 100%;\" [attr.data-rowindex]='rowIndex' (scroll)='onContainerScroll()'\n [ngClass]=\"{\n 'igx-grid__tr-container': true,\n 'igx-grid__tr--highlighted':isRowHighlighted(rowData)\n }\">\n <igx-child-grid-row *ngFor=\"let layout of childLayoutList\" [parentGridID]=\"id\" [index]=\"rowIndex\"\n [rowData]=\"rowData\" [layout]='layout' #row>\n </igx-child-grid-row>\n </div>\n </ng-template>\n <ng-template\n [igxTemplateOutlet]='(isHierarchicalRecord(rowData) ? hierarchical_record_template : (isChildGridRecord(rowData) && isExpanded(rowData) ? child_record_template : hierarchical_record_template))'\n [igxTemplateOutletContext]='getContext(rowData)' (onViewCreated)='viewCreatedHandler($event)'\n (onViewMoved)='viewMovedHandler($event)' (onCachedViewLoaded)='cachedViewLoaded($event)'\n (onBeforeViewDetach)='viewDetachHandler($event)'></ng-template>\n <!-- <ng-container *igxTemplateOutlet=\"(isHierarchicalRecord(rowData) ? hierarchical_record_template : (isChildGridRecord(rowData) && isExpanded(rowData) ? child_record_template : hierarchical_record_template)); context: getContext(rowData)\"></ng-container> -->\n </ng-template>\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n <span *ngIf=\"hasMovableColumns && draggedColumn\" [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\"\n id=\"right\" class=\"igx-grid__scroll-on-drag-right\"></span>\n <div class=\"igx-grid__row-editing-outlet\" igxOverlayOutlet #igxRowEditingOverlayOutlet></div>\n </div>\n <span *ngIf=\"hasMovableColumns && draggedColumn\" [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\"\n id=\"right\" class=\"igx-grid__scroll-on-drag-right\"></span>\n <div [hidden]='!hasVerticalSroll()' class=\"igx-grid__tbody-scrollbar\" [style.width.px]=\"scrollWidth\"\n [style.height.px]='calcHeight'>\n <ng-template igxGridFor [igxGridForOf]='[]' #verticalScrollHolder></ng-template>\n </div>\n</div>\n\n\n<div class=\"igx-grid__tfoot\" role=\"rowgroup\" [style.height.px]='summariesHeight' #tfoot>\n <igx-grid-summary-row [style.width.px]='calcWidth' [style.height.px]='summariesHeight'\n *ngIf=\"hasSummarizedColumns && rootSummariesEnabled\" [gridID]=\"id\"\n [summaries]=\"id | igxGridSummaryDataPipe:summaryService.retriggerRootPipe\" [index]=\"0\"\n class=\"igx-grid__summaries\" #summaryRow>\n </igx-grid-summary-row>\n <div class=\"igx-grid__tfoot-thumb\" [hidden]='!hasVerticalSroll()' [style.height.px]='summariesHeight'\n [style.width.px]=\"scrollWidth\"></div>\n</div>\n\n<div class=\"igx-grid__scroll\" [style.height]=\"'18px'\" #scr [hidden]=\"isHorizontalScrollHidden\">\n <div class=\"igx-grid__scroll-start\" [style.width.px]='pinnedWidth' [hidden]=\"pinnedWidth === 0\"></div>\n <div class=\"igx-grid__scroll-main\" [style.width.px]='unpinnedWidth'>\n <ng-template igxGridFor [igxGridForOf]='[]' #scrollContainer>\n </ng-template>\n </div>\n</div>\n\n<div class=\"igx-grid__footer\" #footer>\n <ng-content select=\"igx-grid-footer\"></ng-content>\n <ng-container *ngIf=\"paging && totalRecords\">\n <ng-container\n *ngTemplateOutlet=\"paginationTemplate ? paginationTemplate : defaultPaginator; context: {$implicit: this}\">\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #defaultPaginator>\n <igx-paginator [displayDensity]=\"displayDensity\" [(page)]=\"page\" [totalRecords]=\"totalRecords\" [(perPage)]=\"perPage\">\n </igx-paginator>\n</ng-template>\n\n<ng-template #emptyFilteredGrid>\n <span class=\"igx-grid__tbody-message\">{{emptyFilteredGridMessage}}</span>\n</ng-template>\n\n<ng-template #defaultEmptyGrid>\n <span class=\"igx-grid__tbody-message\">{{emptyGridMessage}}</span>\n</ng-template>\n\n<ng-template #defaultLoadingGrid>\n <div class=\"igx-grid__loading\">\n <igx-circular-bar [indeterminate]=\"true\">\n </igx-circular-bar>\n </div>\n</ng-template>\n\n<ng-template #defaultCollapsedTemplate>\n <igx-icon role=\"button\" fontSet=\"material\">unfold_more</igx-icon>\n</ng-template>\n\n<ng-template #defaultExpandedTemplate>\n <igx-icon role=\"button\" [isActive]='hierarchicalState.length > 0 && hasExpandableChildren' [isActive]='true' fontSet=\"material\">unfold_less</igx-icon>\n</ng-template>\n\n<div *ngIf=\"rowEditable\" igxToggle>\n <div [className]=\"bannerClass\">\n <ng-container\n *ngTemplateOutlet=\"rowEditContainer; context: { rowChangesCount: rowChangesCount, endEdit: endEdit.bind(this) }\">\n </ng-container>\n </div>\n</div>\n<ng-template #defaultRowEditText>\n You have {{ rowChangesCount }} changes in this row\n</ng-template>\n<ng-template #defaultRowEditActions>\n <button igxButton igxRowEditTabStop (click)=\"endEdit(false, $event)\">Cancel</button>\n <button igxButton igxRowEditTabStop (click)=\"endEdit(true, $event)\">Done</button>\n</ng-template>\n<ng-template #defaultRowEditTemplate>\n <div class=\"igx-banner__message\">\n <span class=\"igx-banner__text\">\n <ng-container\n *ngTemplateOutlet=\"rowEditText ? rowEditText : defaultRowEditText; context: { $implicit: rowChangesCount }\">\n </ng-container>\n </span>\n </div>\n <div class=\"igx-banner__actions\">\n <div class=\"igx-banner__row\">\n <ng-container\n *ngTemplateOutlet=\"rowEditActions ? rowEditActions : defaultRowEditActions; context: { $implicit: endEdit.bind(this) }\">\n </ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dragIndicatorIconBase>\n <igx-icon fontSet=\"material\">drag_indicator</igx-icon>\n</ng-template>\n\n<ng-template #headSelectorBaseTemplate igxHeadSelector let-context>\n <div class=\"igx-grid__cbx-padding\">\n <igx-checkbox\n [readonly]=\"true\"\n [checked]=\"context.selectedCount > 0 && context.totalCount === context.selectedCount\"\n disableRipple=\"true\"\n [ngStyle]=\"{'visibility': isMultiRowSelectionEnabled? 'visible' : 'hidden' }\"\n [indeterminate]=\"context.selectedCount > 0 && context.selectedCount !== context.totalCount\"\n [aria-label]=\"headSelectorBaseAriaLabel\"\n #headerCheckbox>\n </igx-checkbox>\n </div>\n</ng-template>\n\n<igx-grid-column-resizer *ngIf=\"colResizingService.showResizer\"></igx-grid-column-resizer>\n<div class=\"igx-grid__loading-outlet\" #igxLoadingOverlayOutlet igxOverlayOutlet></div>\n<div class=\"igx-grid__outlet\" #igxFilteringOverlayOutlet igxOverlayOutlet></div>\n",
providers: [
IgxGridSelectionService,
IgxGridCRUDService,
{ provide: GridBaseAPIService, useClass: IgxHierarchicalGridAPIService },
{ provide: IgxGridBaseDirective, useExisting: forwardRef(function () { return IgxHierarchicalGridComponent_1; }) },
IgxGridSummaryService,
IgxFilteringService,
IgxHierarchicalGridNavigationService,
IgxForOfSyncService,
IgxForOfScrollSyncService,
IgxRowIslandAPIService
]
})
], IgxHierarchicalGridComponent);
return IgxHierarchicalGridComponent;
}(IgxHierarchicalGridBaseDirective));
export { IgxHierarchicalGridComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGllcmFyY2hpY2FsLWdyaWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vaWduaXRldWktYW5ndWxhci8iLCJzb3VyY2VzIjpbImxpYi9ncmlkcy9oaWVyYXJjaGljYWwtZ3JpZC9oaWVyYXJjaGljYWwtZ3JpZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFDSCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFdBQVcsRUFDWCxLQUFLLEVBQ0wsVUFBVSxFQUNWLFdBQVcsRUFDWCxTQUFTLEVBQ1QsWUFBWSxFQUNaLFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQU1WLFlBQVksRUFDWixNQUFNLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEQsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDL0QsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTNELE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQzlGLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxnQ0FBZ0MsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSw0REFBNEQsQ0FBQztBQUN4RyxPQUFPLEVB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IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDb21wb25lbnQsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSW5wdXQsXG4gICAgZm9yd2FyZFJlZixcbiAgICBUZW1wbGF0ZVJlZixcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0NoaWxkcmVuLFxuICAgIFF1ZXJ5TGlzdCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgRWxlbWVudFJlZixcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIEFmdGVyQ29udGVudEluaXQsXG4gICAgT25Jbml0LFxuICAgIE9uRGVzdHJveSxcbiAgICBEb0NoZWNrLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBPdXRwdXRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJZ3hHcmlkQmFzZURpcmVjdGl2ZSB9IGZyb20gJy4uL2dyaWQtYmFzZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgR3JpZEJhc2VBUElTZXJ2aWNlIH0gZnJvbSAnLi4vYXBpLnNlcnZpY2UnO1xuaW1wb3J0IHsgSWd4SGllcmFyY2hpY2FsR3JpZEFQSVNlcnZpY2UgfSBmcm9tICcuL2hpZXJhcmNoaWNhbC1ncmlkLWFwaS5zZXJ2aWNlJztcbmltcG9ydCB7IElneFJvd0lzbGFuZENvbXBvbmVudCB9IGZyb20gJy4vcm93LWlzbGFuZC5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWd4Q2hpbGRHcmlkUm93Q29tcG9uZW50IH0gZnJvbSAnLi9jaGlsZC1ncmlkLXJvdy5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWd4RmlsdGVyaW5nU2VydmljZSB9IGZyb20gJy4uL2ZpbHRlcmluZy9ncmlkLWZpbHRlcmluZy5zZXJ2aWNlJztcbmltcG9ydCB7IERpc3BsYXlEZW5zaXR5IH0gZnJvbSAnLi4vLi4vY29yZS9kaXNwbGF5RGVuc2l0eSc7XG5pbXBvcnQgeyBJZ3hDb2x1bW5Db21wb25lbnQsIH0gZnJvbSAnLi4vY29sdW1ucy9jb2x1bW4uY29tcG9uZW50JztcbmltcG9ydCB7IElneEhpZXJhcmNoaWNhbEdyaWROYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gJy4vaGllcmFyY2hpY2FsLWdyaWQtbmF2aWdhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IElneEdyaWRTdW1tYXJ5U2VydmljZSB9IGZyb20gJy4uL3N1bW1hcmllcy9ncmlkLXN1bW1hcnkuc2VydmljZSc7XG5pbXBvcnQgeyBJZ3hIaWVyYXJjaGljYWxHcmlkQmFzZURpcmVjdGl2ZSB9IGZyb20gJy4vaGllcmFyY2hpY2FsLWdyaWQtYmFzZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgSWd4VGVtcGxhdGVPdXRsZXREaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL3RlbXBsYXRlLW91dGxldC90ZW1wbGF0ZV9vdXRsZXQuZGlyZWN0aXZlJztcbmltcG9ydCB7IElneEdyaWRTZWxlY3Rpb25TZXJ2aWNlLCBJZ3hHcmlkQ1JVRFNlcnZpY2UgfSBmcm9tICcuLi9zZWxlY3Rpb24vc2VsZWN0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgSWd4VHJhbnNhY3Rpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvaW5kZXgnO1xuaW1wb3J0IHsgSWd4Rm9yT2ZTeW5jU2VydmljZSwgSWd4Rm9yT2ZTY3JvbGxTeW5jU2VydmljZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMvZm9yLW9mL2Zvcl9vZi5zeW5jLnNlcnZpY2UnO1xuaW1wb3J0IHsgR3JpZFR5cGUgfSBmcm9tICcuLi9jb21tb24vZ3JpZC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSWd4Um93SXNsYW5kQVBJU2VydmljZSB9IGZyb20gJy4vcm93LWlzbGFuZC1hcGkuc2VydmljZSc7XG5cbmxldCBORVhUX0lEID0gMDtcblxuZXhwb3J0IGludGVyZmFjZSBIaWVyYXJjaGljYWxTdGF0ZVJlY29yZCB7XG4gICAgcm93SUQ6IGFueTtcbn1cblxuQENvbXBvbmVudCh7XG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gICAgc2VsZWN0b3I6ICdpZ3gtaGllcmFyY2hpY2FsLWdyaWQnLFxuICAgIHRlbXBsYXRlVXJsOiAnaGllcmFyY2hpY2FsLWdyaWQuY29tcG9uZW50Lmh0bWwnLFxuICAgIHByb3ZpZGVyczogW1xuICAgICAgICBJZ3hHcmlkU2VsZWN0aW9uU2VydmljZSxcbiAgICAgICAgSWd4R3JpZENSVURTZXJ2aWNlLFxuICAgICAgICB7IHByb3ZpZGU6IEdyaWRCYXNlQVBJU2VydmljZSwgdXNlQ2xhc3M6IElneEhpZXJhcmNoaWNhbEdyaWRBUElTZXJ2aWNlIH0sXG4gICAgICAgIHsgcHJvdmlkZTogSWd4R3JpZEJhc2VEaXJlY3RpdmUsIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnQpIH0sXG4gICAgICAgIElneEdyaWRTdW1tYXJ5U2VydmljZSxcbiAgICAgICAgSWd4RmlsdGVyaW5nU2VydmljZSxcbiAgICAgICAgSWd4SGllcmFyY2hpY2FsR3JpZE5hdmlnYXRpb25TZXJ2aWNlLFxuICAgICAgICBJZ3hGb3JPZlN5bmNTZXJ2aWNlLFxuICAgICAgICBJZ3hGb3JPZlNjcm9sbFN5bmNTZXJ2aWNlLFxuICAgICAgICBJZ3hSb3dJc2xhbmRBUElTZXJ2aWNlXG4gICAgXVxufSlcbmV4cG9ydCBjbGFzcyBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50IGV4dGVuZHMgSWd4SGllcmFyY2hpY2FsR3JpZEJhc2VEaXJlY3RpdmVcbiAgICBpbXBsZW1lbnRzIEdyaWRUeXBlLCBBZnRlclZpZXdJbml0LCBBZnRlckNvbnRlbnRJbml0LCBPbkluaXQsIE9uRGVzdHJveSwgRG9DaGVjayB7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgYGlkYCBhdHRyaWJ1dGUuIElmIG5vdCBwcm92aWRlZCBpdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWhpZXJhcmNoaWNhbC1ncmlkIFtpZF09XCInaWd4LWhncmlkLTEnXCIgW2RhdGFdPVwiRGF0YVwiIFthdXRvR2VuZXJhdGVdPVwidHJ1ZVwiPjwvaWd4LWhpZXJhcmNoaWNhbC1ncmlkPlxuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmlkJylcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBnZXQgaWQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaF9pZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBsZXRzIHlvdSBmaWxsIHRoZSBgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudGAgd2l0aCBhbiBhcnJheSBvZiBkYXRhLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWhpZXJhcmNoaWNhbC1ncmlkIFtkYXRhXT1cIkRhdGFcIiBbYXV0b0dlbmVyYXRlXT1cInRydWVcIj48L2lneC1oaWVyYXJjaGljYWwtZ3JpZD5cbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCBkYXRhKHZhbHVlOiBhbnlbXSkge1xuICAgICAgICB0aGlzLl9kYXRhID0gdmFsdWUgfHwgW107XG4gICAgICAgIHRoaXMuc3VtbWFyeVNlcnZpY2UuY2xlYXJTdW1tYXJ5Q2FjaGUoKTtcbiAgICAgICAgaWYgKHRoaXMuc2hvdWxkR2VuZXJhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0dXBDb2x1bW5zKCk7XG4gICAgICAgICAgICB0aGlzLnJlZmxvdygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICBpZiAodGhpcy5wYXJlbnQgJiYgKHRoaXMuaGVpZ2h0ID09PSBudWxsIHx8IHRoaXMuaGVpZ2h0LmluZGV4T2YoJyUnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaGVpZ2h0IHdpbGwgY2hhbmdlIGJhc2VkIG9uIGhvdyBtdWNoIGRhdGEgdGhlcmUgaXMsIHJlY2FsY3VsYXRlIHNpemVzIGluIGlneEZvck9mLlxuICAgICAgICAgICAgdGhpcy5ub3RpZnlDaGFuZ2VzKHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBkYXRhIHNldCB0byB0aGUgYElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgZmlsdGVyZWREYXRhID0gdGhpcy5ncmlkLmZpbHRlcmVkRGF0YTtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZGF0YSgpOiBhbnlbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogU2V0cyB0aGUgc3RhdGUgb2YgdGhlIGBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50YCBjb250YWluaW5nIHdoaWNoIHJvd3MgYXJlIGV4cGFuZGVkLlxuICAgICogYGBgdHlwZXNjcmlwdFxuICAgICogdGhpcy5ncmlkU3RhdGUgPSBbeyByb3dJRDogMSB9LCB7IHJvd0lEOiA0fV07XG4gICAgKiBgYGBcbiAgICAqIGBgYGh0bWxcbiAgICAqIDxpZ3gtaGllcmFyY2hpY2FsLWdyaWQgW3ByaW1hcnlLZXldPVwiJ0lEJ1wiIFtkYXRhXT1cIkRhdGFcIiBbYXV0b0dlbmVyYXRlXT1cImZhbHNlXCIgW2hpZXJhcmNoaWNhbFN0YXRlXT1cImhncmlkU3RhdGVcIj5cbiAgICAqICAgICAgPGlneC1jb2x1bW4gZmllbGQ9XCJJRFwiICBbZGF0YVR5cGVdPSdudW1iZXInPjwvaWd4LWNvbHVtbj5cbiAgICAqICAgICAgPGlneC1jb2x1bW4gZmllbGQ9XCJQcm9kdWN0XCIgIFtkYXRhVHlwZV09J3N0cmluZyc+PC9pZ3gtY29sdW1uPlxuICAgICogICAgICA8aWd4LWNvbHVtbiBmaWVsZD1cIkRlc2NyaXB0aW9uXCIgIFtkYXRhVHlwZV09J3N0cmluZyc+PC9pZ3gtY29sdW1uPlxuICAgICogPC9pZ3gtaGllcmFyY2hpY2FsLWdyaWQ+XG4gICAgKiBgYGBcbiAgICAqXG4gICAgKiBUd28td2F5IGRhdGEgYmluZGluZy5cbiAgICAqIGBgYGh0bWxcbiAgICAqIDxpZ3gtaGllcmFyY2hpY2FsLWdyaWQgW3ByaW1hcnlLZXldPVwiJ0lEJ1wiIFtkYXRhXT1cIkRhdGFcIiBbYXV0b0dlbmVyYXRlXT1cImZhbHNlXCIgWyhoaWVyYXJjaGljYWxTdGF0ZSldPVwiaGdyaWRTdGF0ZVwiPlxuICAgICogICAgICA8aWd4LWNvbHVtbiBmaWVsZD1cIklEXCIgIFtkYXRhVHlwZV09J251bWJlcic+PC9pZ3gtY29sdW1uPlxuICAgICogICAgICA8aWd4LWNvbHVtbiBmaWVsZD1cIlByb2R1Y3RcIiAgW2RhdGFUeXBlXT0nc3RyaW5nJz48L2lneC1jb2x1bW4+XG4gICAgKiAgICAgIDxpZ3gtY29sdW1uIGZpZWxkPVwiRGVzY3JpcHRpb25cIiAgW2RhdGFUeXBlXT0nc3RyaW5nJz48L2lneC1jb2x1bW4+XG4gICAgKiA8L2lneC1oaWVyYXJjaGljYWwtZ3JpZD5cbiAgICAqIGBgYFxuICAgICogQG1lbWJlcm9mIElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnRcbiAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGdldCBoaWVyYXJjaGljYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hpZXJhcmNoaWNhbFN0YXRlO1xuICAgIH1cbiAgICBwdWJsaWMgc2V0IGhpZXJhcmNoaWNhbFN0YXRlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy5faGllcmFyY2hpY2FsU3RhdGUgIT09IHZhbCkge1xuICAgICAgICAgICAgdGhpcy5oaWVyYXJjaGljYWxTdGF0ZUNoYW5nZS5lbWl0KHZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaGFzQ2hpbGRyZW5LZXkpIHtcbiAgICAgICAgICAgIHZhbCA9IHZhbC5maWx0ZXIoaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVjID0gdGhpcy5wcmltYXJ5S2V5ID8gdGhpcy5kYXRhLmZpbmQoeCA9PiB4W3RoaXMucHJpbWFyeUtleV0gPT09IGl0ZW0ucm93SUQpIDogaXRlbS5yb3dJRDtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjW3RoaXMuaGFzQ2hpbGRyZW5LZXldO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faGllcmFyY2hpY2FsU3RhdGUgPSB2YWw7XG4gICAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgdGhpcy5ub3RpZnlDaGFuZ2VzKHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpAaGlkZGVuXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIGhpZXJhcmNoaWNhbFN0YXRlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIGFuIGFycmF5IG9mIG9iamVjdHMgY29udGFpbmluZyB0aGUgZmlsdGVyZWQgZGF0YSBpbiB0aGUgYElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnRgLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmdyaWQuZmlsdGVyZWREYXRhID0gW3tcbiAgICAgKiAgICAgICBJRDogMSxcbiAgICAgKiAgICAgICBOYW1lOiBcIkFcIlxuICAgICAqIH1dO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIHNldCBmaWx0ZXJlZERhdGEodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fZmlsdGVyZWREYXRhID0gdmFsdWU7XG5cblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2Ygb2JqZWN0cyBjb250YWluaW5nIHRoZSBmaWx0ZXJlZCBkYXRhIGluIHRoZSBgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudGAuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBmaWx0ZXJlZERhdGEgPSB0aGlzLmdyaWQuZmlsdGVyZWREYXRhO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIGdldCBmaWx0ZXJlZERhdGEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maWx0ZXJlZERhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBpZiBhbGwgaW1tZWRpYXRlIGNoaWxkcmVuIG9mIHRoZSBgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudGAgc2hvdWxkIGJlIGV4cGFuZGVkL2NvbGxhcHNlZC5cbiAgICAgKiBEZWZ1bHQgdmFsdWUgaXMgZmFsc2UuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtaGllcmFyY2hpY2FsLWdyaWQgW2lkXT1cIidpZ3gtZ3JpZC0xJ1wiIFtkYXRhXT1cIkRhdGFcIiBbYXV0b0dlbmVyYXRlXT1cInRydWVcIiBbZXhwYW5kQ2hpbGRyZW5dPVwidHJ1ZVwiPjwvaWd4LWhpZXJhcmNoaWNhbC1ncmlkPlxuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBzZXQgZXhwYW5kQ2hpbGRyZW4odmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fZXhwYW5kQ2hpbGRyZW4gPSB2YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlICYmIHRoaXMuZGF0YSkge1xuICAgICAgICAgICAgdGhpcy5oaWVyYXJjaGljYWxTdGF0ZSA9IHRoaXMuZGF0YS5tYXAoKHJlYykgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHJvd0lEOiB0aGlzLnByaW1hcnlLZXkgPyByZWNbdGhpcy5wcmltYXJ5S2V5XSA6IHJlYyB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhKSB7XG4gICAgICAgICAgICB0aGlzLmhpZXJhcmNoaWNhbFN0YXRlID0gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGlmIGFsbCBpbW1lZGlhdGUgY2hpbGRyZW4gb2YgdGhlIGBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50YCBwcmV2aW91c2x5IGhhdmUgYmVlbiBzZXQgdG8gYmUgZXhwYW5kZWQvY29sbGFwc2VkLlxuICAgICAqIElmIHByZXZpb3VzbHkgc2V0IGFuZCBzb21lIHJvd3MgaGF2ZSBiZWVuIG1hbnVhbGx5IGV4cGFuZGVkL2NvbGxhcHNlZCBpdCB3aWxsIHN0aWxsIHJldHVybiB0aGUgbGFzdCBzZXQgdmFsdWUuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGV4cGFuZGVkID0gdGhpcy5ncmlkLmV4cGFuZENoaWxkcmVuO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgZ2V0IGV4cGFuZENoaWxkcmVuKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhwYW5kQ2hpbGRyZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHBhcmVudCByb3cuIEl0IG1heSBiZSBhIGBzdHJpbmdgIG9yIGBudW1iZXJgIGlmIGBwcmltYXJ5S2V5YCBvZiB0aGVcbiAgICAgKiBwYXJlbnQgZ3JpZCBpcyBzZXQgb3IgYW4gb2JqZWN0IHJlZmVyZW5jZSBvZiB0aGUgcGFyZW50IHJlY29yZCBvdGhlcndpc2UuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IGZvcmVpZ25LZXkgPSB0aGlzLmdyaWQuZm9yZWlnbktleTtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4SGllcmFyY2hpY2FsR3JpZENvbXBvbmVudFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZm9yZWlnbktleSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmhncmlkQVBJLmdldFBhcmVudFJvd0lkKHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKElneFJvd0lzbGFuZENvbXBvbmVudCwgeyByZWFkOiBJZ3hSb3dJc2xhbmRDb21wb25lbnQsIGRlc2NlbmRhbnRzOiBmYWxzZSB9KVxuICAgIHB1YmxpYyBjaGlsZExheW91dExpc3Q6IFF1ZXJ5TGlzdDxJZ3hSb3dJc2xhbmRDb21wb25lbnQ+O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBDb250ZW50Q2hpbGRyZW4oSWd4Um93SXNsYW5kQ29tcG9uZW50LCB7IHJlYWQ6IElneFJvd0lzbGFuZENvbXBvbmVudCwgZGVzY2VuZGFudHM6IHRydWUgfSlcbiAgICBwdWJsaWMgYWxsTGF5b3V0TGlzdDogUXVlcnlMaXN0PElneFJvd0lzbGFuZENvbXBvbmVudD47XG5cbiAgICBAVmlld0NoaWxkKCdoaWVyYXJjaGljYWxfcmVjb3JkX3RlbXBsYXRlJywgeyByZWFkOiBUZW1wbGF0ZVJlZiwgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIGhpZXJhcmNoaWNhbFJlY29yZFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgQFZpZXdDaGlsZCgnY2hpbGRfcmVjb3JkX3RlbXBsYXRlJywgeyByZWFkOiBUZW1wbGF0ZVJlZiwgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIGNoaWxkVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICBAVmlld0NoaWxkKCdoZWFkZXJIaWVyYXJjaHlFeHBhbmRlcicsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIGhlYWRlckhpZXJhcmNoeUV4cGFuZGVyOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGRyZW4oSWd4VGVtcGxhdGVPdXRsZXREaXJlY3RpdmUsIHsgcmVhZDogSWd4VGVtcGxhdGVPdXRsZXREaXJlY3RpdmUgfSlcbiAgICBwdWJsaWMgdGVtcGxhdGVPdXRsZXRzOiBRdWVyeUxpc3Q8YW55PjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkcmVuKElneENoaWxkR3JpZFJvd0NvbXBvbmVudCwgeyByZWFkOiBJZ3hDaGlsZEdyaWRSb3dDb21wb25lbnQgfSlcbiAgICBwdWJsaWMgaGllcmFyY2hpY2FsUm93czogUXVlcnlMaXN0PElneENoaWxkR3JpZFJvd0NvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0IGhhc0V4cGFuZGFibGVDaGlsZHJlbigpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5jaGlsZExheW91dEtleXMubGVuZ3RoO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgY2hpbGRMYXlvdXRLZXlzID0gW107XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGhpZ2hsaWdodGVkUm93SUQgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB1cGRhdGVPblJlbmRlciA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBwYXJlbnQgPSBudWxsO1xuXG4gICAgcHJpdmF0ZSBfaGllcmFyY2hpY2FsU3RhdGUgPSBbXTtcbiAgICBwcml2YXRlIF9kYXRhO1xuICAgIHByaXZhdGUgX2ZpbHRlcmVkRGF0YSA9IG51bGw7XG4gICAgcHJpdmF0ZSBoX2lkID0gYGlneC1oaWVyYXJjaGljYWwtZ3JpZC0ke05FWFRfSUQrK31gO1xuICAgIHByaXZhdGUgY2hpbGRHcmlkVGVtcGxhdGVzOiBNYXA8YW55LCBhbnk+ID0gbmV3IE1hcCgpO1xuICAgIHByaXZhdGUgc2Nyb2xsVG9wID0gMDtcbiAgICBwcml2YXRlIHNjcm9sbExlZnQgPSAwO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG5nT25Jbml0KCkge1xuICAgICAgICBpZiAodGhpcy5fdHJhbnNhY3Rpb25zIGluc3RhbmNlb2YgSWd4VHJhbnNhY3Rpb25TZXJ2aWNlKSB7XG4gICAgICAgICAgICAvLyB0cmFuc2FjdGlvbiBzZXJ2aWNlIGNhbm5vdCBiZSBpbmplY3RlZCBpbiBhIGRlcml2ZWQgY2xhc3MgaW4gYSBmYWN0b3J5IG1hbm5lclxuICAgICAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25zID0gbmV3IElneFRyYW5zYWN0aW9uU2VydmljZSgpO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyLm5nT25Jbml0KCk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nRG9DaGVjaygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2NkclJlcXVlc3RSZXBhaW50ICYmICF0aGlzLl9pbml0KSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVNpemVzKCk7XG4gICAgICAgIH1cbiAgICAgICAgc3VwZXIubmdEb0NoZWNrKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgc3VwZXIubmdBZnRlclZpZXdJbml0KCk7XG4gICAgICAgIHRoaXMudmVydGljYWxTY3JvbGxDb250YWluZXIuZ2V0U2Nyb2xsKCkuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5oZ192ZXJ0aWNhbFNjcm9sbEhhbmRsZXIuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuaGVhZGVyQ29udGFpbmVyLmdldFNjcm9sbCgpLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuaGdfaG9yaXpvbnRhbFNjcm9sbEhhbmRsZXIuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKHRoaXMuZXhwYW5kQ2hpbGRyZW4gJiYgdGhpcy5kYXRhICYmIHRoaXMuaGllcmFyY2hpY2FsU3RhdGUubGVuZ3RoICE9PSB0aGlzLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmhpZXJhcmNoaWNhbFN0YXRlID0gdGhpcy5kYXRhLm1hcCgocmVjKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgcm93SUQ6IHRoaXMucHJpbWFyeUtleSA/IHJlY1t0aGlzLnByaW1hcnlLZXldIDogcmVjIH07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudmVydGljYWxTY3JvbGxDb250YWluZXIub25CZWZvcmVWaWV3RGVzdHJveWVkLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKHZpZXcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJvd0RhdGEgPSB2aWV3LmNvbnRleHQuJGltcGxpY2l0O1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNDaGlsZEdyaWRSZWNvcmQocm93RGF0YSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYWNoZWREYXRhID0gdGhpcy5jaGlsZEdyaWRUZW1wbGF0ZXMuZ2V0KHJvd0RhdGEucm93SUQpO1xuICAgICAgICAgICAgICAgIGlmIChjYWNoZWREYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRtbHBPdXRsZXQgPSBjYWNoZWREYXRhLm93bmVyO1xuICAgICAgICAgICAgICAgICAgICB0bWxwT3V0bGV0Ll92aWV3Q29udGFpbmVyUmVmLmRldGFjaCgwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgdGhpcy5fZGlzcGxheURlbnNpdHkgPSB0aGlzLnJvb3RHcmlkLl9kaXNwbGF5RGVuc2l0eTtcbiAgICAgICAgICAgIHRoaXMucm9vdEdyaWQub25EZW5zaXR5Q2hhbmdlZC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kaXNwbGF5RGVuc2l0eSA9IHRoaXMucm9vdEdyaWQuX2Rpc3BsYXlEZW5zaXR5O1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5Q2hhbmdlcyh0cnVlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5jaGlsZExheW91dEtleXMgPSB0aGlzLnBhcmVudElzbGFuZC5jaGlsZHJlbi5tYXAoKGl0ZW0pID0+IGl0ZW0ua2V5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudG9vbGJhckN1c3RvbUNvbnRlbnRUZW1wbGF0ZXMgPSB0aGlzLnBhcmVudElzbGFuZCA/XG4gICAgICAgICAgICB0aGlzLnBhcmVudElzbGFuZC50b29sYmFyQ3VzdG9tQ29udGVudFRlbXBsYXRlcyA6XG4gICAgICAgICAgICB0aGlzLnRvb2xiYXJDdXN0b21Db250ZW50VGVtcGxhdGVzO1xuXG4gICAgICAgIHRoaXMuaGVhZFNlbGVjdG9yc1RlbXBsYXRlcyA9IHRoaXMucGFyZW50SXNsYW5kID9cbiAgICAgICAgICAgIHRoaXMucGFyZW50SXNsYW5kLmhlYWRTZWxlY3RvcnNUZW1wbGF0ZXMgOlxuICAgICAgICAgICAgdGhpcy5oZWFkU2VsZWN0b3JzVGVtcGxhdGVzO1xuXG4gICAgICAgIHRoaXMucm93U2VsZWN0b3JzVGVtcGxhdGVzID0gdGhpcy5wYXJlbnRJc2xhbmQgP1xuICAgICAgICAgICAgdGhpcy5wYXJlbnRJc2xhbmQucm93U2VsZWN0b3JzVGVtcGxhdGVzIDpcbiAgICAgICAgICAgIHRoaXMucm93U2VsZWN0b3JzVGVtcGxhdGVzO1xuICAgICAgICB0aGlzLmRyYWdJbmRpY2F0b3JJY29uVGVtcGxhdGUgPSB0aGlzLnBhcmVudElzbGFuZCA/XG4gICAgICAgICAgICB0aGlzLnBhcmVudElzbGFuZC5kcmFnSW5kaWNhdG9ySWNvblRlbXBsYXRlIDpcbiAgICAgICAgICAgIHRoaXMuZHJhZ0luZGljYXRvckljb25UZW1wbGF0ZTtcbiAgICAgICAgdGhpcy5yb3dFeHBhbmRlZEluZGljYXRvclRlbXBsYXRlICA9IHRoaXMucm9vdEdyaWQucm93RXhwYW5kZWRJbmRpY2F0b3JUZW1wbGF0ZTtcbiAgICAgICAgdGhpcy5yb3dDb2xsYXBzZWRJbmRpY2F0b3JUZW1wbGF0ZSAgID0gdGhpcy5yb290R3JpZC5yb3dDb2xsYXBzZWRJbmRpY2F0b3JUZW1wbGF0ZTtcbiAgICAgICAgdGhpcy5oZWFkZXJDb2xsYXBzZUluZGljYXRvclRlbXBsYXRlID0gdGhpcy5yb290R3JpZC5oZWFkZXJDb2xsYXBzZUluZGljYXRvclRlbXBsYXRlO1xuICAgICAgICB0aGlzLmhlYWRlckV4cGFuZEluZGljYXRvclRlbXBsYXRlID0gdGhpcy5yb290R3JpZC5oZWFkZXJFeHBhbmRJbmRpY2F0b3JUZW1wbGF0ZTtcbiAgICAgICAgdGhpcy5oYXNDaGlsZHJlbktleSA9IHRoaXMucGFyZW50SXNsYW5kID9cbiAgICAgICAgIHRoaXMucGFyZW50SXNsYW5kLmhhc0NoaWxkcmVuS2V5IHx8IHRoaXMucm9vdEdyaWQuaGFzQ2hpbGRyZW5LZXkgOlxuICAgICAgICAgdGhpcy5yb290R3JpZC5oYXNDaGlsZHJlbktleTtcbiAgICAgICAgIHRoaXMuc2hvd0V4cGFuZEFsbCA9IHRoaXMucGFyZW50SXNsYW5kID9cbiAgICAgICAgIHRoaXMucGFyZW50SXNsYW5kLnNob3dFeHBhbmRBbGwgOiB0aGlzLnJvb3RHcmlkLnNob3dFeHBhbmRBbGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVTaXplcygpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LmJvZHkuY29udGFpbnModGhpcy5uYXRpdmVFbGVtZW50KSAmJiB0aGlzLmlzUGVyY2VudFdpZHRoKSB7XG4gICAgICAgICAgICB0aGlzLnJlZmxvdygpO1xuXG4gICAgICAgICAgICB0aGlzLmhncmlkQVBJLmdldENoaWxkR3JpZHMoZmFsc2UpLmZvckVhY2goKGdyaWQpID0+IHtcbiAgICAgICAgICAgICAgICBncmlkLnVwZGF0ZVNpemVzKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBfc2hvdWxkQXV0b1NpemUocmVuZGVyZWRIZWlnaHQpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNQZXJjZW50SGVpZ2h0ICYmIHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VwZXIuX3Nob3VsZEF1dG9TaXplKHJlbmRlcmVkSGVpZ2h0KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IG91dGxldERpcmVjdGl2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucm9vdEdyaWQuX291dGxldERpcmVjdGl2ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICB0aGlzLnVwZGF0ZUNvbHVtbkxpc3QoZmFsc2UpO1xuICAgICAgICB0aGlzLmNoaWxkTGF5b3V0S2V5cyA9IHRoaXMucGFyZW50ID9cbiAgICAgICAgdGhpcy5wYXJlbnRJc2xhbmQuY2hpbGRyZW4ubWFwKChpdGVtKSA9PiBpdGVtLmtleSkgOlxuICAgICAgICB0aGlzLmNoaWxkTGF5b3V0S2V5cyA9IHRoaXMuY2hpbGRMYXlvdXRMaXN0Lm1hcCgoaXRlbSkgPT4gaXRlbS5rZXkpO1xuICAgICAgICB0aGlzLmNoaWxkTGF5b3V0TGlzdC5ub3RpZnlPbkNoYW5nZXMoKTtcbiAgICAgICAgdGhpcy5jaGlsZExheW91dExpc3QuY2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uUm93SXNsYW5kQ2hhbmdlKCkpO1xuICAgICAgICBzdXBlci5uZ0FmdGVyQ29udGVudEluaXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAqIEBoaWRkZW5cbiAgICAqL1xuICAgIHB1YmxpYyBvblJvd0lzbGFuZENoYW5nZSgpIHtcbiAgICAgICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICB0aGlzLmNoaWxkTGF5b3V0S2V5cyA9IHRoaXMucGFyZW50SXNsYW5kLmNoaWxkcmVuLmZpbHRlcihpdGVtID0+ICEoaXRlbSBhcyBhbnkpLl9kZXN0cm95ZWQpLm1hcCgoaXRlbSkgPT4gaXRlbS5rZXkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jaGlsZExheW91dEtleXMgPSB0aGlzLmNoaWxkTGF5b3V0TGlzdC5maWx0ZXIoaXRlbSA9PiAhKGl0ZW0gYXMgYW55KS5fZGVzdHJveWVkKS5tYXAoKGl0ZW0pID0+IGl0ZW0ua2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISh0aGlzLmNkciBhcyBhbnkpLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIG9uQ29sdW1uc0NoYW5nZWQoY2hhbmdlOiBRdWVyeUxpc3Q8SWd4Q29sdW1uQ29tcG9uZW50Pikge1xuICAgICAgICB0aGlzLnVwZGF0ZUNvbHVtbkxpc3QoKTtcbiAgICAgICAgY29uc3QgY29scyA9IGNoYW5nZS5maWx0ZXIoYyA9PiBjLmdyaWRBUEkuZ3JpZCA9PT0gdGhpcyk7XG4gICAgICAgIGlmIChjb2xzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuY29sdW1uTGlzdC5yZXNldChjb2xzKTtcbiAgICAgICAgICAgIHN1cGVyLm9uQ29sdW1uc0NoYW5nZWQodGhpcy5jb2x1bW5MaXN0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlQ29sdW1uTGlzdChyZWNhbGNDb2xTaXplcyA9IHRydWUpIHtcbiAgICAgICAgY29uc3QgY2hpbGRMYXlvdXRzID0gdGhpcy5wYXJlbnQgPyB0aGlzLmNoaWxkTGF5b3V0TGlzdCA6IHRoaXMuYWxsTGF5b3V0TGlzdDtcbiAgICAgICAgY29uc3QgbmVzdGVkQ29sdW1ucyA9IGNoaWxkTGF5b3V0cy5tYXAoKGxheW91dCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGxheW91dC5jb2x1bW5MaXN0LnRvQXJyYXkoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNvbHNBcnJheSA9IFtdLmNvbmNhdC5hcHBseShbXSwgbmVzdGVkQ29sdW1ucyk7XG4gICAgICAgIGNvbnN0IGNvbExlbmd0aCA9IHRoaXMuY29sdW1uTGlzdC5sZW5ndGg7XG4gICAgICAgIGlmIChjb2xzQXJyYXkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgdG9wQ29scyA9IHRoaXMuY29sdW1uTGlzdC5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29sc0FycmF5LmluZGV4T2YoaXRlbSkgPT09IC0xO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbkxpc3QucmVzZXQodG9wQ29scyk7XG4gICAgICAgICAgICBpZiAocmVjYWxjQ29sU2l6ZXMgJiYgdGhpcy5jb2x1bW5MaXN0Lmxlbmd0aCAhPT0gY29sTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYWxjdWxhdGVHcmlkU2l6ZXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICBpZiAoIXRoaXMucGFyZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhncmlkQVBJLmdldENoaWxkR3JpZHModHJ1ZSkuZm9yRWFjaCgoZ3JpZCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZ3JpZC5jaGlsZFJvdy5jZHIuZGVzdHJveWVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGdyaWQuY2hpbGRSb3cuY2RyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXJlbnQgJiYgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmFjdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIC8vIGluIGNhc2Ugc2VsZWN0aW9uIGlzIGluIGRlc3Ryb3llZCBjaGlsZCBncmlkLCBzZWxlY3Rpb24gc2hvdWxkIGJlIGNsZWFyZWQuXG4gICAgICAgICAgICB0aGlzLl9jbGVhclNlbGV0aW9uSGlnaGxpZ2h0cygpO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY2xlYXJTZWxldGlvbkhpZ2hsaWdodHMoKSB7XG4gICAgICAgIFt0aGlzLnJvb3RHcmlkLCAuLi50aGlzLnJvb3RHcmlkLmdldENoaWxkR3JpZHModHJ1ZSldLmZvckVhY2goZ3JpZCA9PiB7XG4gICAgICAgICAgICBncmlkLnNlbGVjdGlvblNlcnZpY2UuY2xlYXIoKTtcbiAgICAgICAgICAgIGdyaWQuc2VsZWN0aW9uU2VydmljZS5hY3RpdmVFbGVtZW50ID0gbnVsbDtcbiAgICAgICAgICAgIGdyaWQubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdpZ3gtZ3JpZF9fdHItLWhpZ2hsaWdodGVkJyk7XG4gICAgICAgICAgICBncmlkLmhpZ2hsaWdodGVkUm93SUQgPSBudWxsO1xuICAgICAgICAgICAgZ3JpZC5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICogQGhpZGRlblxuICAgICovXG4gICAgcHVibGljIGdldCB0ZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcbiAgICAgICAgaWYgKHRoaXMuZmlsdGVyZWREYXRhICYmIHRoaXMuZmlsdGVyZWREYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1wdHlHcmlkVGVtcGxhdGUgPyB0aGlzLmVtcHR5R3JpZFRlbXBsYXRlIDogdGhpcy5lbXB0eUZpbHRlcmVkR3JpZFRlbXBsYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaXNMb2FkaW5nICYmICghdGhpcy5kYXRhIHx8IHRoaXMuZGF0YUxlbmd0aCA9PT0gMCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvYWRpbmdHcmlkVGVtcGxhdGUgPyB0aGlzLmxvYWRpbmdHcmlkVGVtcGxhdGUgOiB0aGlzLmxvYWRpbmdHcmlkRGVmYXVsdFRlbXBsYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0YUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1wdHlHcmlkVGVtcGxhdGUgPyB0aGlzLmVtcHR5R3JpZFRlbXBsYXRlIDogdGhpcy5lbXB0eUdyaWREZWZhdWx0VGVtcGxhdGU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogR2V0cyB0aGUgY29tYmluZWQgd2lkdGggb2YgdGhlIGNvbHVtbnMgdGhhdCBhcmUgc3BlY2lmaWMgdG8gdGhlIGVuYWJsZWQgZ3JpZCBmZWF0dXJlcy4gVGhleSBhcmUgZml4ZWQuXG4gICAgICogVE9ETzogUmVtb3ZlIGZvciBBbmd1bGFyIDguIENhbGxpbmcgcGFyZW50IGNsYXNzIGdldHRlciB1c2luZyBzdXBlciBpcyBub3Qgc3VwcG9ydGVkIGZvciBub3cuXG4gICAgICovXG4gICAgcHVibGljIGdldEZlYXR1cmVDb2x1bW5zV2lkdGgoKSB7XG4gICAgICAgIGxldCB3aWR0aCA9IHN1cGVyLmdldEZlYXR1cmVDb2x1bW5zV2lkdGgoKTtcblxuICAgICAgICBpZiAodGhpcy5oYXNFeHBhbmRhYmxlQ2hpbGRyZW4pIHtcbiAgICAgICAgICAgIHdpZHRoICs9IHRoaXMuaGVhZGVySGllcmFyY2h5RXhwYW5kZXIubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCB8fCB0aGlzLmdldERlZmF1bHRFeHBhbmRlcldpZHRoKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gd2lkdGg7XG4gICAgfVxuXG4gICAgIHByaXZhdGUgZ2V0RGVmYXVsdEV4cGFuZGVyV2lkdGgoKTogbnVtYmVyIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLmRpc3BsYXlEZW5zaXR5KSB7XG4gICAgICAgICAgICBjYXNlIERpc3BsYXlEZW5zaXR5LmNvc3k6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDU3O1xuICAgICAgICAgICAgY2FzZSBEaXNwbGF5RGVuc2l0eS5jb21wYWN0OlxuICAgICAgICAgICAgICAgIHJldHVybiA0OTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIDcyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc1Jvd0hpZ2hsaWdodGVkKHJvd0RhdGEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGlnaGxpZ2h0ZWRSb3dJRCA9PT0gcm93RGF0YS5yb3dJRDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzSGllcmFyY2hpY2FsUmVjb3JkKHJlY29yZDogYW55KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNoaWxkTGF5b3V0TGlzdC5sZW5ndGggIT09IDAgJiYgcmVjb3JkW3RoaXMuY2hpbGRMYXlvdXRMaXN0LmZpcnN0LmtleV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0NoaWxkR3JpZFJlY29yZChyZWNvcmQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBDYW4gYmUgbnVsbCB3aGVuIHRoZXJlIGlzIGRlZmluZWQgbGF5b3V0IGJ1dCBubyBjaGlsZCBkYXRhIHdhcyBmb3VuZFxuICAgICAgICByZXR1cm4gcmVjb3JkLmNoaWxkR3JpZHNEYXRhICE9PSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB0cmFja0NoYW5nZXMoaW5kZXgsIHJlYykge1xuICAgICAgICBpZiAocmVjLmNoaWxkR3JpZHNEYXRhICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIGlmIGlzIGNoaWxkIHJlY1xuICAgICAgICAgICAgcmV0dXJuIHJlYy5yb3dJRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVjO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0Q29udGV4dChyb3dEYXRhKTogYW55IHtcbiAgICAgICAgaWYgKHRoaXMuaXNDaGlsZEdyaWRSZWNvcmQocm93RGF0YSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlZERhdGEgPSB0aGlzLmNoaWxkR3JpZFRlbXBsYXRlcy5nZXQocm93RGF0YS5yb3dJRCk7XG4gICAgICAgICAgICBpZiAoY2FjaGVkRGF0YSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZpZXcgPSBjYWNoZWREYXRhLnZpZXc7XG4gICAgICAgICAgICAgICAgY29uc3QgdG1scE91dGxldCA9IGNhY2hlZERhdGEub3duZXI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgJGltcGxpY2l0OiByb3dEYXRhLFxuICAgICAgICAgICAgICAgICAgICBtb3ZlVmlldzogdmlldyxcbiAgICAgICAgICAgICAgICAgICAgb3duZXI6IHRtbHBPdXRsZXQsXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiB0aGlzLmRhdGFWaWV3LmluZGV4T2Yocm93RGF0YSlcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCByb3dJRCA9IHRoaXMucHJpbWFyeUtleSA/IHJvd0RhdGEucm93SUQgOiB0aGlzLmRhdGEuaW5kZXhPZihyb3dEYXRhLnJvd0lEKTtcbiAgICAgICAgICAgICAgICAvLyBjaGlsZCByb3dzIGNvbnRhaW4gdW5pcXVlIGdyaWRzLCBoZW5jZSBzaG91bGQgaGF2ZSB1bmlxdWUgdGVtcGxhdGVzXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgJGltcGxpY2l0OiByb3dEYXRhLFxuICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlEOiAnY2hpbGRSb3ctJyArIHJvd0lELFxuICAgICAgICAgICAgICAgICAgICBpbmRleDogdGhpcy5kYXRhVmlldy5pbmRleE9mKHJvd0RhdGEpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgJGltcGxpY2l0OiByb3dEYXRhLFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlSUQ6ICdkYXRhUm93JyxcbiAgICAgICAgICAgICAgICBpbmRleDogdGhpcy5kYXRhVmlldy5pbmRleE9mKHJvd0RhdGEpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICovXG4gICAgcHVibGljIGdldCByb290R3JpZCgpIHtcbiAgICAgICAgbGV0IGN1cnJHcmlkID0gdGhpcztcbiAgICAgICAgd2hpbGUgKGN1cnJHcmlkLnBhcmVudCkge1xuICAgICAgICAgICAgY3VyckdyaWQgPSBjdXJyR3JpZC5wYXJlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGN1cnJHcmlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAqL1xuICAgIHB1YmxpYyBnZXQgaWNvblRlbXBsYXRlKCkge1xuICAgICAgICBjb25zdCBleHBhbmRlZCA9IHRoaXMuaGllcmFyY2hpY2FsU3RhdGUubGVuZ3RoID4gMCAmJiB0aGlzLmhhc0V4cGFuZGFibGVDaGlsZHJlbjtcbiAgICAgICAgaWYgKCFleHBhbmRlZCAmJiB0aGlzLnNob3dFeHBhbmRBbGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmhlYWRlckNvbGxhcHNlSW5kaWNhdG9yVGVtcGxhdGUgfHwgdGhpcy5kZWZhdWx0Q29sbGFwc2VkVGVtcGxhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oZWFkZXJFeHBhbmRJbmRpY2F0b3JUZW1wbGF0ZSB8fCB0aGlzLmRlZmF1bHRFeHBhbmRlZFRlbXBsYXRlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXREcmFnR2hvc3RDdXN0b21UZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcbiAgICAgICAgaWYgKHRoaXMucGFyZW50SXNsYW5kKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnRJc2xhbmQuZ2V0RHJhZ0dob3N0Q3VzdG9tVGVtcGxhdGUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VwZXIuZ2V0RHJhZ0dob3N0Q3VzdG9tVGVtcGxhdGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgKi9cbiAgICBwcm90ZWN0ZWQgaW5pdENvbHVtbnMoY29sbGVjdGlvbjogUXVlcnlMaXN0PElneENvbHVtbkNvbXBvbmVudD4sIGNiOiBGdW5jdGlvbiA9IG51bGwpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQ29sdW1uTGF5b3V0cykge1xuICAgICAgICAgICAgLy8gaW52YWxpZCBjb25maWd1cmF0aW9uIC0gaGllcmFyY2hpY2FsIGdyaWQgc2hvdWxkIG5vdCBhbGxvdyBjb2x1bW4gbGF5b3V0c1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGNvbHVtbiBsYXlvdXRzXG4gICAgICAgICAgICBjb25zdCBub25Db2x1bW5MYXlvdXRDb2x1bW5zID0gdGhpcy5jb2x1bW5MaXN0LmZpbHRlcigoY29sKSA9PiAhY29sLmNvbHVtbkxheW91dCAmJiAhY29sLmNvbHVtbkxheW91dENoaWxkKTtcbiAgICAgICAgICAgIHRoaXMuY29sdW1uTGlzdC5yZXNldChub25Db2x1bW5MYXlvdXRDb2x1bW5zKTtcbiAgICAgICAgfVxuICAgICAgICBzdXBlci5pbml0Q29sdW1ucyhjb2xsZWN0aW9uLCBjYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIEdldHMgdGhlIHZpc2libGUgY29udGVudCBoZWlnaHQgdGhhdCBpbmNsdWRlcyBoZWFkZXIgKyB0Ym9keSArIGZvb3Rlci5cbiAgICAgKiBGb3IgaGllcmFyY2hpY2FsIGNoaWxkIGdyaWQgaXQgbWF5IGJlIHNjcm9sbGVkIGFuZCBub3QgZnVsbHkgdmlzaWJsZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0VmlzaWJsZUNvbnRlbnRIZWlnaHQoKSB7XG4gICAgICAgIGxldCBoZWlnaHQgPSBzdXBlci5nZXRWaXNpYmxlQ29udGVudEhlaWdodCgpO1xuICAgICAgICBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHJvb3RIZWlnaHQgPSB0aGlzLnJvb3RHcmlkLmdldFZpc2libGVDb250ZW50SGVpZ2h0KCk7XG4gICAgICAgICAgICBjb25zdCB0b3BEaWZmID0gdGhpcy5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAtIHRoaXMucm9vdEdyaWQubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3A7XG4gICAgICAgICAgICBoZWlnaHQgPSByb290SGVpZ2h0IC0gdG9wRGlmZiA+IGhlaWdodCA/IGhlaWdodCA6IHJvb3RIZWlnaHQgLSB0b3BEaWZmO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoZWlnaHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICovXG4gICB0b2dnbGVBbGwoKSB7XG4gICAgY29uc3QgZXhwYW5kZWQgPSB0aGlzLmhpZXJhcmNoaWNhbFN0YXRlLmxlbmd0aCA+IDAgJiYgdGhpcy5oYXNFeHBhbmRhYmxlQ2hpbGRyZW47XG4gICAgaWYgKCFleHBhbmRlZCAmJiB0aGlzLnNob3dFeHBhbmRBbGwpIHtcbiAgICAgICAgdGhpcy5leHBhbmRBbGwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNvbGxhcHNlQWxsKCk7XG4gICAgfVxuICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29sbGFwc2VzIGFsbCByb3dzIG9mIHRoZSBjdXJyZW50IGhpZXJhcmNoaWNhbCBncmlkLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmdyaWQuY29sbGFwc2VBbGwoKTtcbiAgICAgKiBgYGBcblx0ICogQG1lbWJlcm9mIElneEhpZXJhcmNoaWNhbEdyaWRDb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgY29sbGFwc2VBbGwoKSB7XG4gICAgICAgIHRoaXMuaGllcmFyY2hpY2FsU3RhdGUgPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHBhbmRzIGFsbCByb3dzIG9mIHRoZSBjdXJyZW50IGhpZXJhcmNoaWNhbCBncmlkLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmdyaWQuZXhwYW5kQWxsKCk7XG4gICAgICogYGBgXG5cdCAqIEBtZW1iZXJvZiBJZ3hIaWVyYXJjaGljYWxHcmlkQ29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIGV4cGFuZEFsbCgpIHtcbiAgICAgICAgaWYgKHRoaXMuZGF0YSkge1xuICAgICAgICAgICAgdGhpcy5oaWVyYXJjaGljYWxTdGF0ZSA9IHRoaXMuZGF0YS5tYXAoKHJlYykgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHJvd0lEOiB0aGlzLnByaW1hcnlLZXkgPyByZWNbdGhpcy5wcmltYXJ5S2V5XSA6IHJlYyB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzRXhwYW5kZWQocmVjb3JkOiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGluU3RhdGU7XG4gICAgICAgIGlmIChyZWNvcmQuY2hpbGRHcmlkc0RhdGEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaW5TdGF0ZSA9ICEhdGhpcy5oaWVyYXJjaGljYWxTdGF0ZS5maW5kKHYgPT4gdi5yb3dJRCA9PT0gcmVjb3JkLnJvd0lEKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluU3RhdGUgPSAhIXRoaXMuaGllcmFyY2hpY2FsU3RhdGUuZmluZCh2ID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wcmltYXJ5S2V5ID8gdi5yb3dJRCA9PT0gcmVjb3JkW3RoaXMucHJpbWFyeUtleV0gOiB2LnJvd0lEID09PSByZWNvcmQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5TdGF0ZSAmJiB0aGlzLmNoaWxkTGF5b3V0TGlzdC5sZW5ndGggIT09IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB2aWV3Q3JlYXRlZEhhbmRsZXIoYXJncykge1xuICAgICAgICBpZiAodGhpcy5pc0NoaWxkR3JpZFJlY29yZChhcmdzLmNvbnRleHQuJGltcGxpY2l0KSkge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gYXJncy5jb250ZXh0LiRpbXBsaWNpdC5yb3dJRDtcbiAgICAgICAgICAgIHRoaXMuY2hpbGRHcmlkVGVtcGxhdGVzLnNldChrZXksIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB2aWV3TW92ZWRIYW5kbGVyKGFyZ3MpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNDaGlsZEdyaWRSZWNvcmQoYXJncy5jb250ZXh0LiRpbXBsaWNpdCkpIHtcbiAgICAgICAgICAgIC8vIHZpZXcgd2FzIG1vdmVkLCB1cGRhdGUgb3duZXIgaW4gY2FjaGVcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGFyZ3MuY29udGV4dC4kaW1wbGljaXQucm93SUQ7XG4gICAgICAgICAgICBjb25zdCBjYWNoZWREYXRhID0gdGhpcy5jaGlsZEdyaWRUZW1wbGF0ZXMuZ2V0KGtleSk7XG4gICAgICAgICAgICBjYWNoZWREYXRhLm93bmVyID0gYXJncy5vd25lcjtcblxuICAgICAgICAgICAgdGhpcy5jaGlsZExheW91dExpc3QuZm9yRWFjaCgobGF5b3V0KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVsYXRlZEdyaWQgPSB0aGlzLmhncmlkQVBJLmdldENoaWxkR3JpZEJ5SUQobGF5b3V0LmtleSwgYXJncy5jb250ZXh0LiRpbXBsaWNpdC5yb3dJRCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbGF0ZWRHcmlkICYmIHJlbGF0ZWRHcmlkLnVwZGF0ZU9uUmVuZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIERldGVjdCBjaGFuZ2VzIGlmIGBleHBhbmRDaGlsZHJlbmAgaGFzIGNoYW5nZWQgd2hlbiB0aGUgZ3JpZCB3YXNuJ3QgdmlzaWJsZS4gVGhpcyBpcyBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucy5cbiAgICAgICAgICAgICAgICAgICAgcmVsYXRlZEdyaWQubm90aWZ5Q2hhbmdlcyh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVsYXRlZEdyaWQudXBkYXRlT25SZW5kZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY29uc3QgY2hpbGRHcmlkcyA9IHRoaXMuZ2V0Q2hpbGRHcmlkcyh0cnVlKTtcbiAgICAgICAgICAgIGNoaWxkR3JpZHMuZm9yRWFjaCgoZ3JpZCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChncmlkLmlzUGVyY2VudFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIGdyaWQubm90aWZ5Q2hhbmdlcyh0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZ3JpZC51cGRhdGVTY3JvbGxQb3NpdGlvbigpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHVwZGF0ZVNjcm9sbFBvc2l0aW9uKCkge1xuICAgICAgICBjb25zdCB2U2NyID0gdGhpcy52ZXJ0aWNhbFNjcm9sbENvbnRhaW5lci5nZXRTY3JvbGwoKTtcbiAgICAgICAgY29uc3QgaFNjciA9IHRoaXMuaGVhZGVyQ29udGFpbmVyLmdldFNjcm9sbCgpO1xuICAgICAgICBpZiAodlNjcikge1xuICAgICAgICAgICAgdlNjci5zY3JvbGxUb3AgPSB0aGlzLnNjcm9sbFRvcDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaFNjcikge1xuICAgICAgICAgICAgaFNjci5zY3JvbGxMZWZ0ID0gdGhpcy5zY3JvbGxMZWZ0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldENoaWxkR3JpZHMoaW5EZXBoPzogYm9vbGVhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5oZ3JpZEFQSS5nZXRDaGlsZEdyaWRzKGluRGVwaCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdlbmVyYXRlRGF0YUZpZWxkcyhkYXRhOiBhbnlbXSk6IHN0cmluZ1tdIHtcbiAgICAgICAgcmV0dXJuIHN1cGVyLmdlbmVyYXRlRGF0YUZpZWxkcyhkYXRhKS5maWx0ZXIoKGZpZWxkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBsYXlvdXRzTGlzdCA9IHRoaXMucGFyZW50SXNsYW5kID8gdGhpcy5wYXJlbnRJc2xhbmQuY2hpbGRyZW4gOiB0aGlzLmNoaWxkTGF5b3V0TGlzdDtcbiAgICAgICAgICAgIGNvbnN0IGtleXMgPSBsYXlvdXRzTGlzdC5tYXAoKGl0ZW0pID0+IGl0ZW0ua2V5KTtcbiAgICAgICAgICAgIHJldHVybiBrZXlzLmluZGV4T2YoZmllbGQpID09PSAtMTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICBwcml2YXRlIGhnX3ZlcnRpY2FsU2Nyb2xsSGFuZGxlcihldmVudCkge1xuICAgICAgICB0aGlzLnNjcm9sbFRvcCA9IGV2ZW50LnRhcmdldC5zY3JvbGxUb3A7XG4gICAgfVxuXG4gICAgcHVibGljIG9uQ29udGFpbmVyU2Nyb2xsKCkge1xuICAgICAgICB0aGlzLmhpZGVPdmVybGF5cygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGdfaG9yaXpvbnRhbFNjcm9sbEhhbmRsZXIoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5zY3JvbGxMZWZ0ID0gZXZlbnQudGFyZ2V0LnNjcm9sbExlZnQ7XG4gICAgfVxufVxuIl19