@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
493 lines • 55.8 kB
JavaScript
import { __decorate, __metadata, __values } from "tslib";
import { CommonModule } from '@angular/common';
import { AfterViewInit, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, HostBinding, Input, NgModule, Output, QueryList, ViewChild, ViewChildren, OnDestroy, NgZone } from '@angular/core';
import { IgxBadgeModule } from '../badge/badge.component';
import { IgxRippleModule } from '../directives/ripple/ripple.directive';
import { IgxIconModule } from '../icon/index';
import { IgxTabItemComponent } from './tab-item.component';
import { IgxTabsGroupComponent } from './tabs-group.component';
import { IgxLeftButtonStyleDirective, IgxRightButtonStyleDirective, IgxTabItemTemplateDirective } from './tabs.directives';
import { IgxTabsBase } from './tabs.common';
import ResizeObserver from 'resize-observer-polyfill';
export var TabsType;
(function (TabsType) {
TabsType["FIXED"] = "fixed";
TabsType["CONTENTFIT"] = "contentfit";
})(TabsType || (TabsType = {}));
var IgxTabsComponent = /** @class */ (function () {
function IgxTabsComponent(_element, _ngZone) {
this._element = _element;
this._ngZone = _ngZone;
/**
*@hidden
*/
this.selectedIndexChange = new EventEmitter();
/**
* Defines the tab header sizing mode. You can choose between `contentfit` or `fixed`.
* By default the header sizing mode is `contentfit`.
* ```html
* <igx-tabs tabsType="fixed">
* <igx-tabs-group label="HOME">Home</igx-tabs-group>
* </igx-tabs>
* ```
*/
this.tabsType = 'contentfit';
/**
* @hidden
*/
this.class = '';
/**
* Emitted when a tab item is deselected.
* ```html
* <igx-tabs (onTabItemDeselected)="itemDeselected($event)">
* <igx-tabs-group label="Tab 1">This is Tab 1 content.</igx-tabs-group>
* <igx-tabs-group label="Tab 2">This is Tab 2 content.</igx-tabs-group>
* </igx-tabs>
* ```
* ```typescript
* itemDeselected(e){
* const tabGroup = e.group;
* const tabItem = e.tab;
* }
* ```
*/
this.onTabItemDeselected = new EventEmitter();
/**
* Emitted when a tab item is selected.
* ```html
* <igx-tabs (onTabItemSelected)="itemSelected($event)">
* <igx-tabs-group label="Tab 1">This is Tab 1 content.</igx-tabs-group>
* <igx-tabs-group label="Tab 2">This is Tab 2 content.</igx-tabs-group>
* </igx-tabs>
* ```
* ```typescript
* itemSelected(e){
* const tabGroup = e.group;
* const tabItem = e.tab;
* }
* ```
*/
this.onTabItemSelected = new EventEmitter();
/**
* @hidden
*/
this.offset = 0;
this._selectedIndex = -1;
}
IgxTabsComponent_1 = IgxTabsComponent;
Object.defineProperty(IgxTabsComponent.prototype, "selectedIndex", {
/**
* An @Input property that sets the value of the `selectedIndex`.
* Default value is 0.
* ```html
* <igx-tabs selectedIndex="1">
* ```
*
* Two-way data binding.
* ```html
* <igx-tabs [(selectedIndex)]="model.selectedIndex">
* ```
*/
get: function () {
return this._selectedIndex;
},
set: function (index) {
var newIndex = typeof index !== 'number' ? parseInt(index, 10) : index;
if (this._selectedIndex !== newIndex) {
if (this.tabs && this.tabs.length > 0) {
var newTab = this.tabs.toArray()[newIndex];
if (newTab) {
this.performSelectionChange(newTab);
}
}
else {
this._selectedIndex = newIndex;
}
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxTabsComponent.prototype, "tabs", {
/**
* Provides an observable collection of all `IgxTabItemComponent`s.
* First try to get them as content children if not available get them as view children.
* ```typescript
* const tabItems = this.myTabComponent.tabs;
* ```
*/
get: function () {
if (this.hasContentTabs) {
return this.contentTabs;
}
return this.viewTabs;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxTabsComponent.prototype, "hasContentTabs", {
/**
*@hidden
*/
get: function () {
return (this.contentTabs && this.contentTabs.length > 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxTabsComponent.prototype, "cssClass", {
/**
* @hidden
*/
get: function () {
var defaultStyle = "igx-tabs";
var fixedStyle = "igx-tabs--fixed";
var iconStyle = "igx-tabs--icons";
var iconLabelFoundInGroups = this.groups.find(function (group) { return group.icon != null && group.label != null; });
var iconLabelFoundInTabs = this.contentTabs.find(function (tab) { return tab.icon != null && tab.label != null; });
var css;
switch (TabsType[this.tabsType.toUpperCase()]) {
case TabsType.FIXED: {
css = fixedStyle;
break;
}
default: {
css = defaultStyle;
break;
}
}
// Layout fix for items with icons
if (iconLabelFoundInGroups !== undefined || iconLabelFoundInTabs !== undefined) {
css = css + " " + iconStyle;
}
return css + " " + this.class;
},
enumerable: true,
configurable: true
});
/**
* @hidden
*/
IgxTabsComponent.prototype.scrollLeft = function (event) {
this.scroll(false);
};
/**
* @hidden
*/
IgxTabsComponent.prototype.scrollRight = function (event) {
this.scroll(true);
};
/**
* @hidden
*/
IgxTabsComponent.prototype.scrollElement = function (element, scrollRight) {
var viewPortWidth = this.viewPort.nativeElement.offsetWidth;
this.offset = (scrollRight) ? element.offsetWidth + element.offsetLeft - viewPortWidth : element.offsetLeft;
this.itemsContainer.nativeElement.style.transform = "translate(" + -this.offset + "px)";
};
Object.defineProperty(IgxTabsComponent.prototype, "selectedTabItem", {
/**
* Gets the selected `IgxTabItemComponent`.
* ```
* const selectedItem = this.myTabComponent.selectedTabItem;
* ```
*/
get: function () {
if (this.tabs && this.selectedIndex !== undefined) {
return this.tabs.toArray()[this.selectedIndex];
}
},
enumerable: true,
configurable: true
});
/**
* @hidden
*/
IgxTabsComponent.prototype.ngAfterViewInit = function () {
var _this = this;
if (this._selectedIndex === -1) {
this.tabs.forEach(function (t) {
if (t.isSelected) {
_this._selectedIndex = t.index;
}
});
}
if (!this.hasContentTabs && (this.selectedIndex < 0 || this.selectedIndex >= this.groups.length)) {
this._selectedIndex = 0;
}
requestAnimationFrame(function () {
var newTab = _this.tabs.toArray()[_this._selectedIndex];
if (newTab) {
_this.performSelection(newTab);
}
else {
_this.hideIndicator();
}
});
this._groupChanges$ = this.groups.changes.subscribe(function () {
_this.resetSelectionOnCollectionChanged();
});
this._ngZone.runOutsideAngular(function () {
_this._resizeObserver = new ResizeObserver(function () {
if (!_this.hasContentTabs && _this._selectedIndex >= 0 && _this._selectedIndex < _this.tabs.length) {
var newTab = _this.tabs.toArray()[_this._selectedIndex];
_this.transformContentAnimation(newTab, 0);
}
});
_this._resizeObserver.observe(_this.tabsContainer.nativeElement);
});
};
/**
* @hidden
*/
IgxTabsComponent.prototype.ngOnDestroy = function () {
var _this = this;
if (this._groupChanges$) {
this._groupChanges$.unsubscribe();
}
this._ngZone.runOutsideAngular(function () {
_this._resizeObserver.disconnect();
});
};
IgxTabsComponent.prototype.resetSelectionOnCollectionChanged = function () {
var _this = this;
requestAnimationFrame(function () {
var currentTab = _this.tabs.toArray()[_this.selectedIndex];
if (currentTab) {
_this.performSelectionChange(currentTab);
}
else if (_this.selectedIndex >= _this.tabs.length) {
_this.performSelectionChange(_this.tabs.last);
}
else {
_this.hideIndicator();
}
});
};
IgxTabsComponent.prototype.scroll = function (scrollRight) {
var e_1, _a;
var tabsArray = this.tabs.toArray();
try {
for (var tabsArray_1 = __values(tabsArray), tabsArray_1_1 = tabsArray_1.next(); !tabsArray_1_1.done; tabsArray_1_1 = tabsArray_1.next()) {
var tab = tabsArray_1_1.value;
var element = tab.nativeTabItem.nativeElement;
if (scrollRight) {
if (element.offsetWidth + element.offsetLeft > this.viewPort.nativeElement.offsetWidth + this.offset) {
this.scrollElement(element, scrollRight);
break;
}
}
else {
if (element.offsetWidth + element.offsetLeft >= this.offset) {
this.scrollElement(element, scrollRight);
break;
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (tabsArray_1_1 && !tabsArray_1_1.done && (_a = tabsArray_1.return)) _a.call(tabsArray_1);
}
finally { if (e_1) throw e_1.error; }
}
};
/**
* @hidden
*/
IgxTabsComponent.prototype.performSelectionChange = function (newTab) {
var oldTab = this.selectedTabItem;
if (oldTab) {
this.performDeselection(oldTab);
}
if (newTab) {
this.performSelection(newTab);
}
else {
// if there is no new selected tab hide the selection indicator
this.hideIndicator();
}
this.selectedIndexChange.emit(this._selectedIndex);
};
IgxTabsComponent.prototype.performDeselection = function (oldTab) {
oldTab.setSelectedInternal(false);
var oldTabRelatedGroup = this.groups.toArray()[oldTab.index];
if (oldTabRelatedGroup) {
oldTabRelatedGroup.setSelectedInternal(false);
}
this._selectedIndex = -1;
this.onTabItemDeselected.emit({ tab: oldTab, group: oldTabRelatedGroup });
};
IgxTabsComponent.prototype.performSelection = function (newTab) {
var _this = this;
newTab.setSelectedInternal(true);
this._selectedIndex = newTab.index;
var newTabRelatedGroup = null;
if (!this.hasContentTabs && this.groups) {
newTabRelatedGroup = this.groups.toArray()[newTab.index];
if (newTabRelatedGroup) {
newTabRelatedGroup.setSelectedInternal(true);
}
}
this.onTabItemSelected.emit({ tab: newTab, group: newTabRelatedGroup });
requestAnimationFrame(function () {
// bring the new selected tab into view if it is not
_this.bringNewTabIntoView(newTab);
// animate the new selection indicator
_this.transformIndicatorAnimation(newTab.nativeTabItem.nativeElement);
// animate the new tab's group content
if (!_this.hasContentTabs) {
_this.transformContentAnimation(newTab, 0.2);
}
});
};
IgxTabsComponent.prototype.bringNewTabIntoView = function (newTab) {
var tabNativeElement = newTab.nativeTabItem.nativeElement;
// Scroll left if there is need
if (tabNativeElement.offsetLeft < this.offset) {
this.scrollElement(tabNativeElement, false);
}
// Scroll right if there is need
var viewPortOffsetWidth = this.viewPort.nativeElement.offsetWidth;
var delta = (tabNativeElement.offsetLeft + tabNativeElement.offsetWidth) - (viewPortOffsetWidth + this.offset);
// Fix for IE 11, a difference is accumulated from the widths calculations
if (delta > 1) {
this.scrollElement(tabNativeElement, true);
}
};
/**
* @hidden
*/
// animation for the new panel/group (not needed for tab only mode)
IgxTabsComponent.prototype.transformContentAnimation = function (tab, duration) {
var contentOffset = this.tabsContainer.nativeElement.offsetWidth * tab.index;
this.contentsContainer.nativeElement.style.transitionDuration = duration > 0 ? duration + "s" : 'initial';
this.contentsContainer.nativeElement.style.transform = "translate(" + -contentOffset + "px)";
};
/**
* @hidden
*/
IgxTabsComponent.prototype.transformIndicatorAnimation = function (element, duration) {
if (duration === void 0) { duration = 0.3; }
if (this.selectedIndicator) {
this.selectedIndicator.nativeElement.style.visibility = 'visible';
this.selectedIndicator.nativeElement.style.transitionDuration = duration > 0 ? duration + "s" : 'initial';
this.selectedIndicator.nativeElement.style.width = element.offsetWidth + "px";
this.selectedIndicator.nativeElement.style.transform = "translate(" + element.offsetLeft + "px)";
}
};
IgxTabsComponent.prototype.hideIndicator = function () {
if (this.selectedIndicator) {
this.selectedIndicator.nativeElement.style.visibility = 'hidden';
}
};
var IgxTabsComponent_1;
IgxTabsComponent.ctorParameters = function () { return [
{ type: ElementRef },
{ type: NgZone }
]; };
__decorate([
ContentChildren(forwardRef(function () { return IgxTabsGroupComponent; })),
__metadata("design:type", QueryList)
], IgxTabsComponent.prototype, "groups", void 0);
__decorate([
ContentChildren(forwardRef(function () { return IgxTabItemComponent; })),
__metadata("design:type", QueryList)
], IgxTabsComponent.prototype, "contentTabs", void 0);
__decorate([
Input(),
__metadata("design:type", Number),
__metadata("design:paramtypes", [Number])
], IgxTabsComponent.prototype, "selectedIndex", null);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxTabsComponent.prototype, "selectedIndexChange", void 0);
__decorate([
Input('tabsType'),
__metadata("design:type", String)
], IgxTabsComponent.prototype, "tabsType", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxTabsComponent.prototype, "class", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxTabsComponent.prototype, "onTabItemDeselected", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxTabsComponent.prototype, "onTabItemSelected", void 0);
__decorate([
ViewChild('contentsContainer', { static: true }),
__metadata("design:type", ElementRef)
], IgxTabsComponent.prototype, "contentsContainer", void 0);
__decorate([
ViewChild('headerContainer', { static: true }),
__metadata("design:type", ElementRef)
], IgxTabsComponent.prototype, "headerContainer", void 0);
__decorate([
ViewChild('itemsContainer', { static: true }),
__metadata("design:type", ElementRef)
], IgxTabsComponent.prototype, "itemsContainer", void 0);
__decorate([
ViewChild('selectedIndicator'),
__metadata("design:type", ElementRef)
], IgxTabsComponent.prototype, "selectedIndicator", void 0);
__decorate([
ViewChild('tabsContainer', { static: true }),
__metadata("design:type", ElementRef)
], IgxTabsComponent.prototype, "tabsContainer", void 0);
__decorate([
ViewChild('viewPort', { static: true }),
__metadata("design:type", ElementRef)
], IgxTabsComponent.prototype, "viewPort", void 0);
__decorate([
ViewChildren(forwardRef(function () { return IgxTabItemComponent; })),
__metadata("design:type", QueryList)
], IgxTabsComponent.prototype, "viewTabs", void 0);
__decorate([
HostBinding('attr.class'),
__metadata("design:type", Object),
__metadata("design:paramtypes", [])
], IgxTabsComponent.prototype, "cssClass", null);
IgxTabsComponent = IgxTabsComponent_1 = __decorate([
Component({
selector: 'igx-tabs',
template: "<!-- TODO Remove tab container from here -->\n<div #tabsContainer>\n <div class=\"igx-tabs__header\" #headerContainer>\n <button igxRipple class=\"igx-tabs__header-button\" igxButton=\"icon\" (click)=\"scrollLeft($event)\" igxLeftButtonStyle>\n <igx-icon fontSet=\"material\">navigate_before</igx-icon>\n </button>\n <div class=\"igx-tabs__header-wrapper-fixed\" #viewPort>\n <div #itemsContainer class=\"igx-tabs__header-wrapper-fluid\">\n <ng-container *ngIf=\"!hasContentTabs\">\n <igx-tab-item igxRipple *ngFor=\"let group of groups\" [relatedGroup]=\"group\">\n </igx-tab-item>\n </ng-container>\n <ng-content select=\"igx-tab-item\"></ng-content>\n <div #selectedIndicator *ngIf=\"groups.length > 0 || contentTabs.length > 0\" class=\"igx-tabs__header-menu-item-indicator\"></div>\n </div>\n </div>\n <button igxRipple class=\"igx-tabs__header-button\" igxButton=\"icon\" (click)=\"scrollRight($event)\" igxRightButtonStyle>\n <igx-icon fontSet=\"material\">navigate_next</igx-icon>\n </button>\n </div>\n <div class=\"igx-tabs__content-fixed\">\n <div #contentsContainer class=\"igx-tabs__content-fluid\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>",
providers: [{ provide: IgxTabsBase, useExisting: IgxTabsComponent_1 }]
}),
__metadata("design:paramtypes", [ElementRef, NgZone])
], IgxTabsComponent);
return IgxTabsComponent;
}());
export { IgxTabsComponent };
/**
* @hidden
*/
var IgxTabsModule = /** @class */ (function () {
function IgxTabsModule() {
}
IgxTabsModule = __decorate([
NgModule({
declarations: [IgxTabsComponent,
IgxTabsGroupComponent,
IgxTabItemComponent,
IgxTabItemTemplateDirective,
IgxRightButtonStyleDirective,
IgxLeftButtonStyleDirective],
exports: [IgxTabsComponent,
IgxTabsGroupComponent,
IgxTabItemComponent,
IgxTabItemTemplateDirective,
IgxRightButtonStyleDirective,
IgxLeftButtonStyleDirective],
imports: [CommonModule, IgxBadgeModule, IgxIconModule, IgxRippleModule]
})
], IgxTabsModule);
return IgxTabsModule;
}());
export { IgxTabsModule };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL3RhYnMvdGFicy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0gsYUFBYSxFQUNiLFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLEtBQUssRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1QsWUFBWSxFQUNaLFNBQVMsRUFDVCxNQUFNLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUN4RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzNELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQy9ELE9BQU8sRUFBRSwyQkFBMkIsRUFBRSw0QkFBNEIsRUFBRSwyQkFBMkIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNILE9BQU8sRUFBRSxXQUFXLEVBQWtCLE1BQU0sZUFBZSxDQUFDO0FBQzVELE9BQU8sY0FBYyxNQUFNLDBCQUEwQixDQUFDO0FBRXRELE1BQU0sQ0FBTixJQUFZLFFBR1g7QUFIRCxXQUFZLFFBQVE7SUFDaEIsMkJBQWUsQ0FBQTtJQUNmLHFDQUF5QixDQUFBO0FBQzdCLENBQUMsRUFIVyxRQUFRLEtBQVIsUUFBUSxRQUduQjtBQVFEO0lBcVFJLDBCQUFvQixRQUFvQixFQUFVLE9BQWU7UUFBN0MsYUFBUSxHQUFSLFFBQVEsQ0FBWTtR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O2tDQUN2QixVQUFVO3NEQUFDO0lBUzVCO1FBREMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxjQUFNLE9BQUEsbUJBQW1CLEVBQW5CLENBQW1CLENBQUMsQ0FBQztrQ0FDbkMsU0FBUztzREFBc0I7SUE4Q2hEO1FBREMsV0FBVyxDQUFDLFlBQVksQ0FBQzs7O29EQXlCekI7SUEvTlEsZ0JBQWdCO1FBTjVCLFNBQVMsQ0FBQztZQUNQLFFBQVEsRUFBRSxVQUFVO1lBQ3BCLHUzQ0FBa0M7WUFDbEMsU0FBUyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxrQkFBZ0IsRUFBRSxDQUFDO1NBQ3ZFLENBQUM7eUNBdVFnQyxVQUFVLEVBQW1CLE1BQU07T0FyUXhELGdCQUFnQixDQWdjNUI7SUFBRCx1QkFBQztDQUFBLEFBaGNELElBZ2NDO1NBaGNZLGdCQUFnQjtBQWtjN0I7O0dBRUc7QUFpQkg7SUFBQTtJQUNBLENBQUM7SUFEWSxhQUFhO1FBaEJ6QixRQUFRLENBQUM7WUFDTixZQUFZLEVBQUUsQ0FBQyxnQkFBZ0I7Z0JBQzNCLHFCQUFxQjtnQkFDckIsbUJBQW1CO2dCQUNuQiwyQkFBMkI7Z0JBQzNCLDRCQUE0QjtnQkFDNUIsMkJBQTJCLENBQUM7WUFDaEMsT0FBTyxFQUFFLENBQUMsZ0JBQWdCO2dCQUN0QixxQkFBcUI7Z0JBQ3JCLG1CQUFtQjtnQkFDbkIsMkJBQTJCO2dCQUMzQiw0QkFBNEI7Z0JBQzVCLDJCQUEyQixDQUFDO1lBQ2hDLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLGVBQWUsQ0FBQztTQUMxRSxDQUFDO09BRVcsYUFBYSxDQUN6QjtJQUFELG9CQUFDO0NBQUEsQUFERCxJQUNDO1NBRFksYUFBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBmb3J3YXJkUmVmLFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LFxuICAgIE5nTW9kdWxlLFxuICAgIE91dHB1dCxcbiAgICBRdWVyeUxpc3QsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdDaGlsZHJlbixcbiAgICBPbkRlc3Ryb3ksXG4gICAgTmdab25lXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBJZ3hCYWRnZU1vZHVsZSB9IGZyb20gJy4uL2JhZGdlL2JhZGdlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hSaXBwbGVNb2R1bGUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL3JpcHBsZS9yaXBwbGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IElneEljb25Nb2R1bGUgfSBmcm9tICcuLi9pY29uL2luZGV4JztcbmltcG9ydCB7IElneFRhYkl0ZW1Db21wb25lbnQgfSBmcm9tICcuL3RhYi1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hUYWJzR3JvdXBDb21wb25lbnQgfSBmcm9tICcuL3RhYnMtZ3JvdXAuY29tcG9uZW50JztcbmltcG9ydCB7IElneExlZnRCdXR0b25TdHlsZURpcmVjdGl2ZSwgSWd4UmlnaHRCdXR0b25TdHlsZURpcmVjdGl2ZSwgSWd4VGFiSXRlbVRlbXBsYXRlRGlyZWN0aXZlIH0gZnJvbSAnLi90YWJzLmRpcmVjdGl2ZXMnO1xuaW1wb3J0IHsgSWd4VGFic0Jhc2UsIElneFRhYkl0ZW1CYXNlIH0gZnJvbSAnLi90YWJzLmNvbW1vbic7XG5pbXBvcnQgUmVzaXplT2JzZXJ2ZXIgZnJvbSAncmVzaXplLW9ic2VydmVyLXBvbHlmaWxsJztcblxuZXhwb3J0IGVudW0gVGFic1R5cGUge1xuICAgIEZJWEVEID0gJ2ZpeGVkJyxcbiAgICBDT05URU5URklUID0gJ2NvbnRlbnRmaXQnXG59XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnaWd4LXRhYnMnLFxuICAgIHRlbXBsYXRlVXJsOiAndGFicy5jb21wb25lbnQuaHRtbCcsXG4gICAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBJZ3hUYWJzQmFzZSwgdXNlRXhpc3Rpbmc6IElneFRhYnNDb21wb25lbnQgfV1cbn0pXG5cbmV4cG9ydCBjbGFzcyBJZ3hUYWJzQ29tcG9uZW50IGltcGxlbWVudHMgSWd4VGFic0Jhc2UsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gICAgLyoqXG4gICAgKiBQcm92aWRlcyBhbiBvYnNlcnZhYmxlIGNvbGxlY3Rpb24gb2YgYWxsIGBJZ3hUYWJzR3JvdXBDb21wb25lbnRgcy5cbiAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAqIGNvbnN0IGdyb3VwSXRlbXMgPSB0aGlzLm15VGFiQ29tcG9uZW50Lmdyb3VwcztcbiAgICAqIGBgYFxuICAgICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IElneFRhYnNHcm91cENvbXBvbmVudCkpXG4gICAgcHVibGljIGdyb3VwczogUXVlcnlMaXN0PElneFRhYnNHcm91cENvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAqIFByb3ZpZGVzIGFuIG9ic2VydmFibGUgY29sbGVjdGlvbiBvZiBhbGwgYElneFRhYkl0ZW1Db21wb25lbnRgcyBkZWZpbmVkIGluIHRoZSBwYWdlLlxuICAgICogYGBgdHlwZXNjcmlwdFxuICAgICogY29uc3QgdGFiSXRlbXMgPSB0aGlzLm15VGFiQ29tcG9uZW50LmNvbnRlbnRUYWJzO1xuICAgICogYGBgXG4gICAgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gSWd4VGFiSXRlbUNvbXBvbmVudCkpXG4gICAgcHVibGljIGNvbnRlbnRUYWJzOiBRdWVyeUxpc3Q8SWd4VGFiSXRlbUNvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IHNldHMgdGhlIHZhbHVlIG9mIHRoZSBgc2VsZWN0ZWRJbmRleGAuXG4gICAgKiBEZWZhdWx0IHZhbHVlIGlzIDAuXG4gICAgKiBgYGBodG1sXG4gICAgKiA8aWd4LXRhYnMgc2VsZWN0ZWRJbmRleD1cIjFcIj5cbiAgICAqIGBgYFxuICAgICpcbiAgICAqIFR3by13YXkgZGF0YSBiaW5kaW5nLlxuICAgICogYGBgaHRtbFxuICAgICogPGlneC10YWJzIFsoc2VsZWN0ZWRJbmRleCldPVwibW9kZWwuc2VsZWN0ZWRJbmRleFwiPlxuICAgICogYGBgXG4gICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBnZXQgc2VsZWN0ZWRJbmRleCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRJbmRleDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IHNlbGVjdGVkSW5kZXgoaW5kZXg6IG51bWJlcikge1xuICAgICAgICBjb25zdCBuZXdJbmRleCA9IHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicgPyBwYXJzZUludChpbmRleCwgMTApIDogaW5kZXg7XG4gICAgICAgIGlmICh0aGlzLl9zZWxlY3RlZEluZGV4ICE9PSBuZXdJbmRleCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudGFicyAmJiB0aGlzLnRhYnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1RhYiA9IHRoaXMudGFicy50b0FycmF5KClbbmV3SW5kZXhdO1xuICAgICAgICAgICAgICAgIGlmIChuZXdUYWIpIHtcbiAgICAgICAgICAgICAgICAgICB0aGlzLnBlcmZvcm1TZWxlY3Rpb25DaGFuZ2UobmV3VGFiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSBuZXdJbmRleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqQGhpZGRlblxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBzZWxlY3RlZEluZGV4Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIHRoZSB0YWIgaGVhZGVyIHNpemluZyBtb2RlLiBZb3UgY2FuIGNob29zZSBiZXR3ZWVuIGBjb250ZW50Zml0YCBvciBgZml4ZWRgLlxuICAgICAqIEJ5IGRlZmF1bHQgdGhlIGhlYWRlciBzaXppbmcgbW9kZSBpcyBgY29udGVudGZpdGAuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtdGFicyB0YWJzVHlwZT1cImZpeGVkXCI+XG4gICAgICogICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIkhPTUVcIj5Ib21lPC9pZ3gtdGFicy1ncm91cD5cbiAgICAgKiA8L2lneC10YWJzPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgndGFic1R5cGUnKVxuICAgIHB1YmxpYyB0YWJzVHlwZTogc3RyaW5nIHwgVGFic1R5cGUgPSAnY29udGVudGZpdCc7XG5cbiAgICAvKipcbiAgICAqIEBoaWRkZW5cbiAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGNsYXNzID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIHdoZW4gYSB0YWIgaXRlbSBpcyBkZXNlbGVjdGVkLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LXRhYnMgKG9uVGFiSXRlbURlc2VsZWN0ZWQpPVwiaXRlbURlc2VsZWN0ZWQoJGV2ZW50KVwiPlxuICAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDFcIj5UaGlzIGlzIFRhYiAxIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAgKiAgICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIlRhYiAyXCI+VGhpcyBpcyBUYWIgMiBjb250ZW50LjwvaWd4LXRhYnMtZ3JvdXA+XG4gICAgICogPC9pZ3gtdGFicz5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogaXRlbURlc2VsZWN0ZWQoZSl7XG4gICAgICogICAgICBjb25zdCB0YWJHcm91cCA9IGUuZ3JvdXA7XG4gICAgICogICAgICBjb25zdCB0YWJJdGVtID0gZS50YWI7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvblRhYkl0ZW1EZXNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgLyoqXG4gICAgKiBFbWl0dGVkIHdoZW4gYSB0YWIgaXRlbSBpcyBzZWxlY3RlZC5cbiAgICAqIGBgYGh0bWxcbiAgICAqIDxpZ3gtdGFicyAob25UYWJJdGVtU2VsZWN0ZWQpPVwiaXRlbVNlbGVjdGVkKCRldmVudClcIj5cbiAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDFcIj5UaGlzIGlzIFRhYiAxIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDJcIj5UaGlzIGlzIFRhYiAyIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAqIDwvaWd4LXRhYnM+XG4gICAgKiBgYGBcbiAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAqIGl0ZW1TZWxlY3RlZChlKXtcbiAgICAqICAgICAgY29uc3QgdGFiR3JvdXAgPSBlLmdyb3VwO1xuICAgICogICAgICBjb25zdCB0YWJJdGVtID0gZS50YWI7XG4gICAgKiB9XG4gICAgKiBgYGBcbiAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvblRhYkl0ZW1TZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdjb250ZW50c0NvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHVibGljIGNvbnRlbnRzQ29udGFpbmVyOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ2hlYWRlckNvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHVibGljIGhlYWRlckNvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdpdGVtc0NvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHVibGljIGl0ZW1zQ29udGFpbmVyOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ3NlbGVjdGVkSW5kaWNhdG9yJylcbiAgICBwdWJsaWMgc2VsZWN0ZWRJbmRpY2F0b3I6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAqIEBoaWRkZW5cbiAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ3RhYnNDb250YWluZXInLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHB1YmxpYyB0YWJzQ29udGFpbmVyOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ3ZpZXdQb3J0JywgeyBzdGF0aWM6IHRydWUgfSlcbiAgICBwdWJsaWMgdmlld1BvcnQ6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlcyBhbiBvYnNlcnZhYmxlIGNvbGxlY3Rpb24gb2YgYWxsIGBJZ3hUYWJJdGVtQ29tcG9uZW50YHMuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IHRhYkl0ZW1zID0gdGhpcy5teVRhYkNvbXBvbmVudC52aWV3VGFicztcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gSWd4VGFiSXRlbUNvbXBvbmVudCkpXG4gICAgcHVibGljIHZpZXdUYWJzOiBRdWVyeUxpc3Q8SWd4VGFiSXRlbUNvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlcyBhbiBvYnNlcnZhYmxlIGNvbGxlY3Rpb24gb2YgYWxsIGBJZ3hUYWJJdGVtQ29tcG9uZW50YHMuXG4gICAgICogRmlyc3QgdHJ5IHRvIGdldCB0aGVtIGFzIGNvbnRlbnQgY2hpbGRyZW4gaWYgbm90IGF2YWlsYWJsZSBnZXQgdGhlbSBhcyB2aWV3IGNoaWxkcmVuLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCB0YWJJdGVtcyA9IHRoaXMubXlUYWJDb21wb25lbnQudGFicztcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHRhYnMoKTogUXVlcnlMaXN0PElneFRhYkl0ZW1Db21wb25lbnQ+IHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQ29udGVudFRhYnMpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRlbnRUYWJzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZpZXdUYWJzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgaGFzQ29udGVudFRhYnMoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAodGhpcy5jb250ZW50VGFicyAmJiB0aGlzLmNvbnRlbnRUYWJzLmxlbmd0aCA+IDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgY2FsY3VsYXRlZFdpZHRoOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHZpc2libGVJdGVtc1dpZHRoOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG9mZnNldCA9IDA7XG5cbiAgICBwcml2YXRlIF9ncm91cENoYW5nZXMkOiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSBfc2VsZWN0ZWRJbmRleCA9IC0xO1xuICAgIHByaXZhdGUgX3Jlc2l6ZU9ic2VydmVyOiBSZXNpemVPYnNlcnZlcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuY2xhc3MnKVxuICAgIHB1YmxpYyBnZXQgY3NzQ2xhc3MoKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRTdHlsZSA9IGBpZ3gtdGFic2A7XG4gICAgICAgIGNvbnN0IGZpeGVkU3R5bGUgPSBgaWd4LXRhYnMtLWZpeGVkYDtcbiAgICAgICAgY29uc3QgaWNvblN0eWxlID0gYGlneC10YWJzLS1pY29uc2A7XG4gICAgICAgIGNvbnN0IGljb25MYWJlbEZvdW5kSW5Hcm91cHMgPSB0aGlzLmdyb3Vwcy5maW5kKChncm91cCkgPT4gZ3JvdXAuaWNvbiAhPSBudWxsICYmIGdyb3VwLmxhYmVsICE9IG51bGwpO1xuICAgICAgICBjb25zdCBpY29uTGFiZWxGb3VuZEluVGFicyA9IHRoaXMuY29udGVudFRhYnMuZmluZCgodGFiKSA9PiB0YWIuaWNvbiAhPSBudWxsICYmIHRhYi5sYWJlbCAhPSBudWxsKTtcbiAgICAgICAgbGV0IGNzcztcbiAgICAgICAgc3dpdGNoIChUYWJzVHlwZVt0aGlzLnRhYnNUeXBlLnRvVXBwZXJDYXNlKCldKSB7XG4gICAgICAgICAgICBjYXNlIFRhYnNUeXBlLkZJWEVEOiB7XG4gICAgICAgICAgICAgICAgY3NzID0gZml4ZWRTdHlsZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBjc3MgPSBkZWZhdWx0U3R5bGU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMYXlvdXQgZml4IGZvciBpdGVtcyB3aXRoIGljb25zXG4gICAgICAgIGlmIChpY29uTGFiZWxGb3VuZEluR3JvdXBzICE9PSB1bmRlZmluZWQgfHwgaWNvbkxhYmVsRm91bmRJblRhYnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY3NzID0gYCR7Y3NzfSAke2ljb25TdHlsZX1gO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGAke2Nzc30gJHt0aGlzLmNsYXNzfWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBzY3JvbGxMZWZ0KGV2ZW50KTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2Nyb2xsKGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHNjcm9sbFJpZ2h0KGV2ZW50KTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2Nyb2xsKHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2Nyb2xsRWxlbWVudChlbGVtZW50OiBhbnksIHNjcm9sbFJpZ2h0OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHZpZXdQb3J0V2lkdGggPSB0aGlzLnZpZXdQb3J0Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XG5cbiAgICAgICAgdGhpcy5vZmZzZXQgPSAoc2Nyb2xsUmlnaHQpID8gZWxlbWVudC5vZmZzZXRXaWR0aCArIGVsZW1lbnQub2Zmc2V0TGVmdCAtIHZpZXdQb3J0V2lkdGggOiBlbGVtZW50Lm9mZnNldExlZnQ7XG4gICAgICAgIHRoaXMuaXRlbXNDb250YWluZXIubmF0aXZlRWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7LXRoaXMub2Zmc2V0fXB4KWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgc2VsZWN0ZWQgYElneFRhYkl0ZW1Db21wb25lbnRgLlxuICAgICAqIGBgYFxuICAgICAqIGNvbnN0IHNlbGVjdGVkSXRlbSA9IHRoaXMubXlUYWJDb21wb25lbnQuc2VsZWN0ZWRUYWJJdGVtO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldCBzZWxlY3RlZFRhYkl0ZW0oKTogSWd4VGFiSXRlbUNvbXBvbmVudCB7XG4gICAgICAgIGlmICh0aGlzLnRhYnMgJiYgdGhpcy5zZWxlY3RlZEluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRhYnMudG9BcnJheSgpW3RoaXMuc2VsZWN0ZWRJbmRleF07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9lbGVtZW50OiBFbGVtZW50UmVmLCBwcml2YXRlIF9uZ1pvbmU6IE5nWm9uZSkge1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xuICAgICAgICBpZiAodGhpcy5fc2VsZWN0ZWRJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMudGFicy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHQuaXNTZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gdC5pbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5oYXNDb250ZW50VGFicyAmJiAodGhpcy5zZWxlY3RlZEluZGV4IDwgMCB8fCB0aGlzLnNlbGVjdGVkSW5kZXggPj0gdGhpcy5ncm91cHMubGVuZ3RoKSkge1xuICAgICAgICAgICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV3VGFiID0gdGhpcy50YWJzLnRvQXJyYXkoKVt0aGlzLl9zZWxlY3RlZEluZGV4XTtcbiAgICAgICAgICAgIGlmIChuZXdUYWIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBlcmZvcm1TZWxlY3Rpb24obmV3VGFiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSW5kaWNhdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuX2dyb3VwQ2hhbmdlcyQgPSB0aGlzLmdyb3Vwcy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0U2VsZWN0aW9uT25Db2xsZWN0aW9uQ2hhbmdlZCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5oYXNDb250ZW50VGFicyAmJiB0aGlzLl9zZWxlY3RlZEluZGV4ID49IDAgJiYgdGhpcy5fc2VsZWN0ZWRJbmRleCA8IHRoaXMudGFicy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3VGFiID0gdGhpcy50YWJzLnRvQXJyYXkoKVt0aGlzLl9zZWxlY3RlZEluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm1Db250ZW50QW5pbWF0aW9uKG5ld1RhYiwgMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy50YWJzQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5fZ3JvdXBDaGFuZ2VzJCkge1xuICAgICAgICAgICAgdGhpcy5fZ3JvdXBDaGFuZ2VzJC51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZU9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXNldFNlbGVjdGlvbk9uQ29sbGVjdGlvbkNoYW5nZWQoKTogdm9pZCB7XG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50VGFiID0gdGhpcy50YWJzLnRvQXJyYXkoKVt0aGlzLnNlbGVjdGVkSW5kZXhdO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRUYWIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBlcmZvcm1TZWxlY3Rpb25DaGFuZ2UoY3VycmVudFRhYik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRJbmRleCA+PSB0aGlzLnRhYnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wZXJmb3JtU2VsZWN0aW9uQ2hhbmdlKHRoaXMudGFicy5sYXN0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSW5kaWNhdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2Nyb2xsKHNjcm9sbFJpZ2h0OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHRhYnNBcnJheSA9IHRoaXMudGFicy50b0FycmF5KCk7XG4gICAgICAgIGZvciAoY29uc3QgdGFiIG9mIHRhYnNBcnJheSkge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRhYi5uYXRpdmVUYWJJdGVtLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBpZiAoc2Nyb2xsUmlnaHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5vZmZzZXRXaWR0aCArIGVsZW1lbnQub2Zmc2V0TGVmdCA+IHRoaXMudmlld1BvcnQubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCArIHRoaXMub2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudChlbGVtZW50LCBzY3JvbGxSaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQub2Zmc2V0V2lkdGggKyBlbGVtZW50Lm9mZnNldExlZnQgPj0gdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxFbGVtZW50KGVsZW1lbnQsIHNjcm9sbFJpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBwZXJmb3JtU2VsZWN0aW9uQ2hhbmdlKG5ld1RhYjogSWd4VGFiSXRlbUJhc2UpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb2xkVGFiID0gdGhpcy5zZWxlY3RlZFRhYkl0ZW07XG4gICAgICAgIGlmIChvbGRUYWIpI