UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

637 lines 53.2 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; /** * @license * Copyright Alibaba.com All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ /** get some code from https://github.com/angular/material2 */ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, Input, Optional, Output, QueryList, Renderer2, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core'; import { NavigationEnd, Router } from '@angular/router'; import { merge, Subject, Subscription } from 'rxjs'; import { toNumber, InputBoolean, NzConfigService, NzUpdateHostClassService, PREFIX, WithConfig } from 'ng-zorro-antd/core'; import { filter, startWith, takeUntil } from 'rxjs/operators'; import { NzTabComponent } from './nz-tab.component'; import { NzTabsNavComponent } from './nz-tabs-nav.component'; /** * @record */ export function NzAnimatedInterface() { } if (false) { /** @type {?} */ NzAnimatedInterface.prototype.inkBar; /** @type {?} */ NzAnimatedInterface.prototype.tabPane; } var NzTabChangeEvent = /** @class */ (function () { function NzTabChangeEvent() { } return NzTabChangeEvent; }()); export { NzTabChangeEvent }; if (false) { /** @type {?} */ NzTabChangeEvent.prototype.index; /** @type {?} */ NzTabChangeEvent.prototype.tab; } var NzTabSetComponent = /** @class */ (function () { function NzTabSetComponent(nzConfigService, renderer, nzUpdateHostClassService, elementRef, cdr, router) { this.nzConfigService = nzConfigService; this.renderer = renderer; this.nzUpdateHostClassService = nzUpdateHostClassService; this.elementRef = elementRef; this.cdr = cdr; this.router = router; this.indexToSelect = 0; this.el = this.elementRef.nativeElement; this._selectedIndex = null; /** * Subscription to tabs being added/removed. */ this.tabsSubscription = Subscription.EMPTY; /** * Subscription to changes in the tab labels. */ this.tabLabelSubscription = Subscription.EMPTY; this.destroy$ = new Subject(); this.tabPositionMode = 'horizontal'; this.nzHideAll = false; this.nzTabPosition = 'top'; this.nzLinkRouter = false; this.nzLinkExact = true; this.nzOnNextClick = new EventEmitter(); this.nzOnPrevClick = new EventEmitter(); this.nzSelectChange = new EventEmitter(true); this.nzSelectedIndexChange = new EventEmitter(); } Object.defineProperty(NzTabSetComponent.prototype, "nzSelectedIndex", { get: /** * @return {?} */ function () { return this._selectedIndex; }, set: /** * @param {?} value * @return {?} */ function (value) { this.indexToSelect = value ? toNumber(value, null) : null; }, enumerable: true, configurable: true }); Object.defineProperty(NzTabSetComponent.prototype, "inkBarAnimated", { get: /** * @return {?} */ function () { return this.nzAnimated === true || ((/** @type {?} */ (this.nzAnimated))).inkBar === true; }, enumerable: true, configurable: true }); Object.defineProperty(NzTabSetComponent.prototype, "tabPaneAnimated", { get: /** * @return {?} */ function () { return this.nzAnimated === true || ((/** @type {?} */ (this.nzAnimated))).tabPane === true; }, enumerable: true, configurable: true }); /** * @param {?} value * @return {?} */ NzTabSetComponent.prototype.setPosition = /** * @param {?} value * @return {?} */ function (value) { if (this.tabContent) { if (value === 'bottom') { this.renderer.insertBefore(this.el, this.tabContent.nativeElement, this.nzTabsNavComponent.elementRef.nativeElement); } else { this.renderer.insertBefore(this.el, this.nzTabsNavComponent.elementRef.nativeElement, this.tabContent.nativeElement); } } }; /** * @return {?} */ NzTabSetComponent.prototype.setClassMap = /** * @return {?} */ function () { var _a; this.nzUpdateHostClassService.updateHostClass(this.el, (_a = {}, _a["ant-tabs"] = true, _a["ant-tabs-vertical"] = this.nzTabPosition === 'left' || this.nzTabPosition === 'right', _a["ant-tabs-" + this.nzTabPosition] = this.nzTabPosition, _a["ant-tabs-no-animation"] = this.nzAnimated === false || ((/** @type {?} */ (this.nzAnimated))).tabPane === false, _a["ant-tabs-" + this.nzType] = this.nzType, _a["ant-tabs-large"] = this.nzSize === 'large', _a["ant-tabs-small"] = this.nzSize === 'small', _a)); }; /** * @param {?} index * @param {?} disabled * @return {?} */ NzTabSetComponent.prototype.clickLabel = /** * @param {?} index * @param {?} disabled * @return {?} */ function (index, disabled) { if (!disabled) { /** @type {?} */ var tabs = this.listOfNzTabComponent.toArray(); this.nzSelectedIndex = index; tabs[index].nzClick.emit(); } }; /** * @param {?} index * @return {?} */ NzTabSetComponent.prototype.createChangeEvent = /** * @param {?} index * @return {?} */ function (index) { /** @type {?} */ var event = new NzTabChangeEvent(); event.index = index; if (this.listOfNzTabComponent && this.listOfNzTabComponent.length) { event.tab = this.listOfNzTabComponent.toArray()[index]; this.listOfNzTabComponent.forEach((/** * @param {?} item * @param {?} i * @return {?} */ function (item, i) { if (i !== index) { item.nzDeselect.emit(); } })); event.tab.nzSelect.emit(); } return event; }; /** Clamps the given index to the bounds of 0 and the tabs length. */ /** * Clamps the given index to the bounds of 0 and the tabs length. * @private * @param {?} index * @return {?} */ NzTabSetComponent.prototype.clampTabIndex = /** * Clamps the given index to the bounds of 0 and the tabs length. * @private * @param {?} index * @return {?} */ function (index) { // Note the `|| 0`, which ensures that values like NaN can't get through // and which would otherwise throw the component into an infinite loop // (since Math.max(NaN, 0) === NaN). return Math.min(this.listOfNzTabComponent.length - 1, Math.max(index || 0, 0)); }; /** * @private * @return {?} */ NzTabSetComponent.prototype.subscribeToTabLabels = /** * @private * @return {?} */ function () { var _this = this; if (this.tabLabelSubscription) { this.tabLabelSubscription.unsubscribe(); } this.tabLabelSubscription = merge.apply(void 0, tslib_1.__spread(this.listOfNzTabComponent.map((/** * @param {?} tab * @return {?} */ function (tab) { return tab.stateChanges; })))).subscribe((/** * @return {?} */ function () { return _this.cdr.markForCheck(); })); }; /** * @param {?} changes * @return {?} */ NzTabSetComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { if (changes.nzTabPosition) { if (this.nzTabPosition === 'top' || this.nzTabPosition === 'bottom') { this.tabPositionMode = 'horizontal'; } else { this.tabPositionMode = 'vertical'; } this.setPosition(this.nzTabPosition); } if (changes.nzType) { if (this.nzType === 'card') { this.nzAnimated = false; } } if (changes.nzSize || changes.nzAnimated || changes.nzTabPosition || changes.nzType) { this.setClassMap(); } }; /** * @return {?} */ NzTabSetComponent.prototype.ngOnInit = /** * @return {?} */ function () { this.setClassMap(); }; /** * @return {?} */ NzTabSetComponent.prototype.ngAfterContentChecked = /** * @return {?} */ function () { var _this = this; if (this.listOfNzTabComponent && this.listOfNzTabComponent.length) { // Don't clamp the `indexToSelect` immediately in the setter because it can happen that // the amount of tabs changes before the actual change detection runs. /** @type {?} */ var indexToSelect_1 = (this.indexToSelect = this.clampTabIndex(this.indexToSelect)); // If there is a change in selected index, emit a change event. Should not trigger if // the selected index has not yet been initialized. if (this._selectedIndex !== indexToSelect_1) { /** @type {?} */ var isFirstRun_1 = this._selectedIndex == null; if (!isFirstRun_1) { this.nzSelectChange.emit(this.createChangeEvent(indexToSelect_1)); } // Changing these values after change detection has run // since the checked content may contain references to them. Promise.resolve().then((/** * @return {?} */ function () { _this.listOfNzTabComponent.forEach((/** * @param {?} tab * @param {?} index * @return {?} */ function (tab, index) { return (tab.isActive = index === indexToSelect_1); })); if (!isFirstRun_1) { _this.nzSelectedIndexChange.emit(indexToSelect_1); } })); } // Setup the position for each tab and optionally setup an origin on the next selected tab. this.listOfNzTabComponent.forEach((/** * @param {?} tab * @param {?} index * @return {?} */ function (tab, index) { tab.position = index - indexToSelect_1; // If there is already a selected tab, then set up an origin for the next selected tab // if it doesn't have one already. if (_this._selectedIndex != null && tab.position === 0 && !tab.origin) { tab.origin = indexToSelect_1 - _this._selectedIndex; } })); if (this._selectedIndex !== indexToSelect_1) { this._selectedIndex = indexToSelect_1; this.cdr.markForCheck(); } } }; /** * @return {?} */ NzTabSetComponent.prototype.ngAfterContentInit = /** * @return {?} */ function () { var _this = this; this.subscribeToTabLabels(); // Subscribe to changes in the amount of tabs, in order to be // able to re-render the content as new tabs are added or removed. this.tabsSubscription = this.listOfNzTabComponent.changes.subscribe((/** * @return {?} */ function () { /** @type {?} */ var indexToSelect = _this.clampTabIndex(_this.indexToSelect); // Maintain the previously-selected tab if a new tab is added or removed and there is no // explicit change that selects a different tab. if (indexToSelect === _this._selectedIndex) { /** @type {?} */ var tabs = _this.listOfNzTabComponent.toArray(); for (var i = 0; i < tabs.length; i++) { if (tabs[i].isActive) { // Assign both to the `_indexToSelect` and `_selectedIndex` so we don't fire a changed // event, otherwise the consumer may end up in an infinite loop in some edge cases like // adding a tab within the `selectedIndexChange` event. _this.indexToSelect = _this._selectedIndex = i; break; } } } _this.subscribeToTabLabels(); _this.cdr.markForCheck(); })); }; /** * @return {?} */ NzTabSetComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { this.tabsSubscription.unsubscribe(); this.tabLabelSubscription.unsubscribe(); this.destroy$.next(); this.destroy$.complete(); }; /** * @return {?} */ NzTabSetComponent.prototype.ngAfterViewInit = /** * @return {?} */ function () { var _this = this; this.setPosition(this.nzTabPosition); if (this.nzLinkRouter) { if (!this.router) { throw new Error(PREFIX + " you should import 'RouterModule' if you want to use 'nzLinkRouter'!"); } this.router.events .pipe(takeUntil(this.destroy$), filter((/** * @param {?} e * @return {?} */ function (e) { return e instanceof NavigationEnd; })), startWith(true)) .subscribe((/** * @return {?} */ function () { _this.updateRouterActive(); _this.cdr.markForCheck(); })); } }; /** * @private * @return {?} */ NzTabSetComponent.prototype.updateRouterActive = /** * @private * @return {?} */ function () { if (this.router.navigated) { /** @type {?} */ var index = this.findShouldActiveTabIndex(); if (index !== this._selectedIndex) { this.nzSelectedIndex = index; this.nzSelectedIndexChange.emit(index); } this.nzHideAll = index === -1; } }; /** * @private * @return {?} */ NzTabSetComponent.prototype.findShouldActiveTabIndex = /** * @private * @return {?} */ function () { /** @type {?} */ var tabs = this.listOfNzTabComponent.toArray(); /** @type {?} */ var isActive = this.isLinkActive(this.router); return tabs.findIndex((/** * @param {?} tab * @return {?} */ function (tab) { /** @type {?} */ var c = tab.linkDirective; return c ? isActive(c.routerLink) || isActive(c.routerLinkWithHref) : false; })); }; /** * @private * @param {?} router * @return {?} */ NzTabSetComponent.prototype.isLinkActive = /** * @private * @param {?} router * @return {?} */ function (router) { var _this = this; return (/** * @param {?=} link * @return {?} */ function (link) { return (link ? router.isActive(link.urlTree, _this.nzLinkExact) : false); }); }; NzTabSetComponent.decorators = [ { type: Component, args: [{ selector: 'nz-tabset', exportAs: 'nzTabset', preserveWhitespaces: false, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [NzUpdateHostClassService], template: "<ng-container *ngIf=\"listOfNzTabComponent\">\n <div nz-tabs-nav\n role=\"tablist\"\n tabindex=\"0\"\n class=\"ant-tabs-bar\"\n [class.ant-tabs-card-bar]=\"nzType === 'card'\"\n [class.ant-tabs-top-bar]=\"nzTabPosition === 'top'\"\n [class.ant-tabs-bottom-bar]=\"nzTabPosition === 'bottom'\"\n [class.ant-tabs-left-bar]=\"nzTabPosition === 'left'\"\n [class.ant-tabs-right-bar]=\"nzTabPosition === 'right'\"\n [class.ant-tabs-small-bar]=\"nzSize === 'small'\"\n [class.ant-tabs-default-bar]=\"nzSize === 'default'\"\n [class.ant-tabs-large-bar]=\"nzSize === 'large'\"\n [nzType]=\"nzType\"\n [nzShowPagination]=\"nzShowPagination\"\n [nzPositionMode]=\"tabPositionMode\"\n [nzAnimated]=\"inkBarAnimated\"\n [ngStyle]=\"nzTabBarStyle\"\n [nzHideBar]=\"nzHideAll\"\n [nzTabBarExtraContent]=\"nzTabBarExtraContent\"\n [selectedIndex]=\"nzSelectedIndex\"\n (nzOnNextClick)=\"nzOnNextClick.emit()\"\n (nzOnPrevClick)=\"nzOnPrevClick.emit()\">\n <div nz-tab-label\n role=\"tab\"\n [style.margin-right.px]=\"nzTabBarGutter\"\n [class.ant-tabs-tab-active]=\"(nzSelectedIndex == i) && !nzHideAll\"\n [disabled]=\"tab.nzDisabled\"\n (click)=\"clickLabel(i,tab.nzDisabled)\"\n *ngFor=\"let tab of listOfNzTabComponent; let i = index\">\n <ng-container *nzStringTemplateOutlet=\"tab.nzTitle || tab.title\">{{ tab.nzTitle }}</ng-container>\n </div>\n </div>\n <div #tabContent\n class=\"ant-tabs-content\"\n [class.ant-tabs-top-content]=\"nzTabPosition === 'top'\"\n [class.ant-tabs-bottom-content]=\"nzTabPosition === 'bottom'\"\n [class.ant-tabs-left-content]=\"nzTabPosition === 'left'\"\n [class.ant-tabs-right-content]=\"nzTabPosition === 'right'\"\n [class.ant-tabs-content-animated]=\"tabPaneAnimated\"\n [class.ant-tabs-card-content]=\"nzType === 'card'\"\n [class.ant-tabs-content-no-animated]=\"!tabPaneAnimated\"\n [style.margin-left.%]=\"(tabPositionMode === 'horizontal') && tabPaneAnimated && (-(nzSelectedIndex || 0 ) * 100)\">\n <div nz-tab-body\n class=\"ant-tabs-tabpane\"\n *ngFor=\"let tab of listOfNzTabComponent; let i = index\"\n [active]=\"(nzSelectedIndex == i) && !nzHideAll\"\n [forceRender]=\"tab.nzForceRender\"\n [content]=\"tab.template || tab.content\">\n </div>\n </div>\n</ng-container>", styles: ["\n nz-tabset {\n display: block;\n }\n "] }] } ]; /** @nocollapse */ NzTabSetComponent.ctorParameters = function () { return [ { type: NzConfigService }, { type: Renderer2 }, { type: NzUpdateHostClassService }, { type: ElementRef }, { type: ChangeDetectorRef }, { type: Router, decorators: [{ type: Optional }] } ]; }; NzTabSetComponent.propDecorators = { listOfNzTabComponent: [{ type: ContentChildren, args: [NzTabComponent,] }], nzTabsNavComponent: [{ type: ViewChild, args: [NzTabsNavComponent, { static: false },] }], tabContent: [{ type: ViewChild, args: ['tabContent', { static: false },] }], nzTabBarExtraContent: [{ type: Input }], nzShowPagination: [{ type: Input }], nzAnimated: [{ type: Input }], nzHideAll: [{ type: Input }], nzTabPosition: [{ type: Input }], nzSize: [{ type: Input }], nzTabBarGutter: [{ type: Input }], nzTabBarStyle: [{ type: Input }], nzType: [{ type: Input }], nzLinkRouter: [{ type: Input }], nzLinkExact: [{ type: Input }], nzOnNextClick: [{ type: Output }], nzOnPrevClick: [{ type: Output }], nzSelectChange: [{ type: Output }], nzSelectedIndexChange: [{ type: Output }], nzSelectedIndex: [{ type: Input }] }; tslib_1.__decorate([ WithConfig(true), tslib_1.__metadata("design:type", Boolean) ], NzTabSetComponent.prototype, "nzShowPagination", void 0); tslib_1.__decorate([ WithConfig(true), tslib_1.__metadata("design:type", Object) ], NzTabSetComponent.prototype, "nzAnimated", void 0); tslib_1.__decorate([ WithConfig('default'), tslib_1.__metadata("design:type", String) ], NzTabSetComponent.prototype, "nzSize", void 0); tslib_1.__decorate([ WithConfig(), tslib_1.__metadata("design:type", Number) ], NzTabSetComponent.prototype, "nzTabBarGutter", void 0); tslib_1.__decorate([ WithConfig('line'), tslib_1.__metadata("design:type", String) ], NzTabSetComponent.prototype, "nzType", void 0); tslib_1.__decorate([ InputBoolean(), tslib_1.__metadata("design:type", Object) ], NzTabSetComponent.prototype, "nzLinkRouter", void 0); tslib_1.__decorate([ InputBoolean(), tslib_1.__metadata("design:type", Object) ], NzTabSetComponent.prototype, "nzLinkExact", void 0); return NzTabSetComponent; }()); export { NzTabSetComponent }; if (false) { /** * @type {?} * @private */ NzTabSetComponent.prototype.indexToSelect; /** * @type {?} * @private */ NzTabSetComponent.prototype.el; /** * @type {?} * @private */ NzTabSetComponent.prototype._selectedIndex; /** * Subscription to tabs being added/removed. * @type {?} * @private */ NzTabSetComponent.prototype.tabsSubscription; /** * Subscription to changes in the tab labels. * @type {?} * @private */ NzTabSetComponent.prototype.tabLabelSubscription; /** * @type {?} * @private */ NzTabSetComponent.prototype.destroy$; /** @type {?} */ NzTabSetComponent.prototype.tabPositionMode; /** @type {?} */ NzTabSetComponent.prototype.listOfNzTabComponent; /** @type {?} */ NzTabSetComponent.prototype.nzTabsNavComponent; /** @type {?} */ NzTabSetComponent.prototype.tabContent; /** @type {?} */ NzTabSetComponent.prototype.nzTabBarExtraContent; /** @type {?} */ NzTabSetComponent.prototype.nzShowPagination; /** @type {?} */ NzTabSetComponent.prototype.nzAnimated; /** @type {?} */ NzTabSetComponent.prototype.nzHideAll; /** @type {?} */ NzTabSetComponent.prototype.nzTabPosition; /** @type {?} */ NzTabSetComponent.prototype.nzSize; /** @type {?} */ NzTabSetComponent.prototype.nzTabBarGutter; /** @type {?} */ NzTabSetComponent.prototype.nzTabBarStyle; /** @type {?} */ NzTabSetComponent.prototype.nzType; /** @type {?} */ NzTabSetComponent.prototype.nzLinkRouter; /** @type {?} */ NzTabSetComponent.prototype.nzLinkExact; /** @type {?} */ NzTabSetComponent.prototype.nzOnNextClick; /** @type {?} */ NzTabSetComponent.prototype.nzOnPrevClick; /** @type {?} */ NzTabSetComponent.prototype.nzSelectChange; /** @type {?} */ NzTabSetComponent.prototype.nzSelectedIndexChange; /** @type {?} */ NzTabSetComponent.prototype.nzConfigService; /** * @type {?} * @private */ NzTabSetComponent.prototype.renderer; /** * @type {?} * @private */ NzTabSetComponent.prototype.nzUpdateHostClassService; /** * @type {?} * @private */ NzTabSetComponent.prototype.elementRef; /** * @type {?} * @private */ NzTabSetComponent.prototype.cdr; /** * @type {?} * @private */ NzTabSetComponent.prototype.router; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnotdGFic2V0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLXpvcnJvLWFudGQvdGFicy8iLCJzb3VyY2VzIjpbIm56LXRhYnNldC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQVVBLE9BQU8sRUFJTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixLQUFLLEVBSUwsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUVULFdBQVcsRUFDWCxTQUFTLEVBQ1QsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFrQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3hGLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVwRCxPQUFPLEVBQ0wsUUFBUSxFQUNSLFlBQVksRUFDWixlQUFlLEVBR2Ysd0JBQXdCLEVBQ3hCLE1BQU0sRUFDTixVQUFVLEVBQ1gsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7Ozs7QUFFN0QseUNBR0M7OztJQUZDLHFDQUFnQjs7SUFDaEIsc0NBQWlCOztBQUduQjtJQUFBO0lBR0EsQ0FBQztJQUFELHVCQUFDO0FBQUQsQ0FBQyxBQUhELElBR0M7Ozs7SUFGQyxpQ0FBYzs7SUFDZCwrQkFBb0I7O0FBT3RCO0lBMklFLDJCQUNTLGVBQWdDLEVBQy9CLFFBQW1CLEVBQ25CLHdCQUFrRCxFQUNsRCxVQUFzQixFQUN0QixHQUFzQixFQUNW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TixNQUFNO2lDQUNOLE1BQU07d0NBQ04sTUFBTTtrQ0FFTixLQUFLOztJQWpCcUI7UUFBakIsVUFBVSxDQUFDLElBQUksQ0FBQzs7K0RBQTJCO0lBQzFCO1FBQWpCLFVBQVUsQ0FBQyxJQUFJLENBQUM7O3lEQUEyQztJQUdyQztRQUF0QixVQUFVLENBQUMsU0FBUyxDQUFDOztxREFBdUI7SUFDL0I7UUFBYixVQUFVLEVBQUU7OzZEQUF3QjtJQUVqQjtRQUFuQixVQUFVLENBQUMsTUFBTSxDQUFDOztxREFBbUI7SUFFdEI7UUFBZixZQUFZLEVBQUU7OzJEQUFzQjtJQUNyQjtRQUFmLFlBQVksRUFBRTs7MERBQW9CO0lBMFA5Qyx3QkFBQztDQUFBLEFBdFNELElBc1NDO1NBdFJZLGlCQUFpQjs7Ozs7O0lBRTVCLDBDQUF5Qzs7Ozs7SUFDekMsK0JBQXdEOzs7OztJQUN4RCwyQ0FBNkM7Ozs7OztJQUU3Qyw2Q0FBOEM7Ozs7OztJQUU5QyxpREFBa0Q7Ozs7O0lBRWxELHFDQUF1Qzs7SUFFdkMsNENBQWtEOztJQUNsRCxpREFBaUY7O0lBQ2pGLCtDQUF5Rjs7SUFDekYsdUNBQW1FOztJQUVuRSxpREFBaUQ7O0lBQ2pELDZDQUFxRDs7SUFDckQsdUNBQXFFOztJQUNyRSxzQ0FBMkI7O0lBQzNCLDBDQUE4Qzs7SUFDOUMsbUNBQXNEOztJQUN0RCwyQ0FBOEM7O0lBQzlDLDBDQUFrRDs7SUFDbEQsbUNBQStDOztJQUUvQyx5Q0FBOEM7O0lBQzlDLHdDQUE0Qzs7SUFFNUMsMENBQTREOztJQUM1RCwwQ0FBNEQ7O0lBQzVELDJDQUE2Rzs7SUFDN0csa0RBQTRGOztJQTJGMUYsNENBQXVDOzs7OztJQUN2QyxxQ0FBMkI7Ozs7O0lBQzNCLHFEQUEwRDs7Ozs7SUFDMUQsdUNBQThCOzs7OztJQUM5QixnQ0FBOEI7Ozs7O0lBQzlCLG1DQUFrQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBBbGliYWJhLmNvbSBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG4vKiogZ2V0IHNvbWUgY29kZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL21hdGVyaWFsMiAqL1xuXG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRDaGVja2VkLFxuICBBZnRlckNvbnRlbnRJbml0LFxuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFJlbmRlcmVyMixcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uRW5kLCBSb3V0ZXIsIFJvdXRlckxpbmssIFJvdXRlckxpbmtXaXRoSHJlZiB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBtZXJnZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7XG4gIHRvTnVtYmVyLFxuICBJbnB1dEJvb2xlYW4sXG4gIE56Q29uZmlnU2VydmljZSxcbiAgTnpGb3VyRGlyZWN0aW9uVHlwZSxcbiAgTnpTaXplTERTVHlwZSxcbiAgTnpVcGRhdGVIb3N0Q2xhc3NTZXJ2aWNlLFxuICBQUkVGSVgsXG4gIFdpdGhDb25maWdcbn0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlJztcbmltcG9ydCB7IGZpbHRlciwgc3RhcnRXaXRoLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE56VGFiQ29tcG9uZW50IH0gZnJvbSAnLi9uei10YWIuY29tcG9uZW50JztcbmltcG9ydCB7IE56VGFic05hdkNvbXBvbmVudCB9IGZyb20gJy4vbnotdGFicy1uYXYuY29tcG9uZW50JztcblxuZXhwb3J0IGludGVyZmFjZSBOekFuaW1hdGVkSW50ZXJmYWNlIHtcbiAgaW5rQmFyOiBib29sZWFuO1xuICB0YWJQYW5lOiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgTnpUYWJDaGFuZ2VFdmVudCB7XG4gIGluZGV4OiBudW1iZXI7XG4gIHRhYjogTnpUYWJDb21wb25lbnQ7XG59XG5cbmV4cG9ydCB0eXBlIE56VGFiUG9zaXRpb24gPSBOekZvdXJEaXJlY3Rpb25UeXBlO1xuZXhwb3J0IHR5cGUgTnpUYWJQb3NpdGlvbk1vZGUgPSAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnO1xuZXhwb3J0IHR5cGUgTnpUYWJUeXBlID0gJ2xpbmUnIHwgJ2NhcmQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei10YWJzZXQnLFxuICBleHBvcnRBczogJ256VGFic2V0JyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtOelVwZGF0ZUhvc3RDbGFzc1NlcnZpY2VdLFxuICB0ZW1wbGF0ZVVybDogJy4vbnotdGFic2V0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgbnotdGFic2V0IHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICB9XG4gICAgYFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIE56VGFiU2V0Q29tcG9uZW50XG4gIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50Q2hlY2tlZCwgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgaW5kZXhUb1NlbGVjdDogbnVtYmVyIHwgbnVsbCA9IDA7XG4gIHByaXZhdGUgZWw6IEhUTUxFbGVtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gIHByaXZhdGUgX3NlbGVjdGVkSW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAvKiogU3Vic2NyaXB0aW9uIHRvIHRhYnMgYmVpbmcgYWRkZWQvcmVtb3ZlZC4gKi9cbiAgcHJpdmF0ZSB0YWJzU3Vic2NyaXB0aW9uID0gU3Vic2NyaXB0aW9uLkVNUFRZO1xuICAvKiogU3Vic2NyaXB0aW9uIHRvIGNoYW5nZXMgaW4gdGhlIHRhYiBsYWJlbHMuICovXG4gIHByaXZhdGUgdGFiTGFiZWxTdWJzY3JpcHRpb24gPSBTdWJzY3JpcHRpb24uRU1QVFk7XG5cbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgdGFiUG9zaXRpb25Nb2RlOiBOelRhYlBvc2l0aW9uTW9kZSA9ICdob3Jpem9udGFsJztcbiAgQENvbnRlbnRDaGlsZHJlbihOelRhYkNvbXBvbmVudCkgbGlzdE9mTnpUYWJDb21wb25lbnQ6IFF1ZXJ5TGlzdDxOelRhYkNvbXBvbmVudD47XG4gIEBWaWV3Q2hpbGQoTnpUYWJzTmF2Q29tcG9uZW50LCB7IHN0YXRpYzogZmFsc2UgfSkgbnpUYWJzTmF2Q29tcG9uZW50OiBOelRhYnNOYXZDb21wb25lbnQ7XG4gIEBWaWV3Q2hpbGQoJ3RhYkNvbnRlbnQnLCB7IHN0YXRpYzogZmFsc2UgfSkgdGFiQ29udGVudDogRWxlbWVudFJlZjtcblxuICBASW5wdXQoKSBuelRhYkJhckV4dHJhQ29udGVudDogVGVtcGxhdGVSZWY8dm9pZD47XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKHRydWUpIG56U2hvd1BhZ2luYXRpb246IGJvb2xlYW47XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKHRydWUpIG56QW5pbWF0ZWQ6IE56QW5pbWF0ZWRJbnRlcmZhY2UgfCBib29sZWFuO1xuICBASW5wdXQoKSBuekhpZGVBbGwgPSBmYWxzZTtcbiAgQElucHV0KCkgbnpUYWJQb3NpdGlvbjogTnpUYWJQb3NpdGlvbiA9ICd0b3AnO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygnZGVmYXVsdCcpIG56U2l6ZTogTnpTaXplTERTVHlwZTtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelRhYkJhckd1dHRlcjogbnVtYmVyO1xuICBASW5wdXQoKSBuelRhYkJhclN0eWxlOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygnbGluZScpIG56VHlwZTogTnpUYWJUeXBlO1xuXG4gIEBJbnB1dCgpIEBJbnB1dEJvb2xlYW4oKSBuekxpbmtSb3V0ZXIgPSBmYWxzZTtcbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56TGlua0V4YWN0ID0gdHJ1ZTtcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpPbk5leHRDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IG56T25QcmV2Q2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuelNlbGVjdENoYW5nZTogRXZlbnRFbWl0dGVyPE56VGFiQ2hhbmdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxOelRhYkNoYW5nZUV2ZW50Pih0cnVlKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IG56U2VsZWN0ZWRJbmRleENoYW5nZTogRXZlbnRFbWl0dGVyPG51bWJlcj4gPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICBASW5wdXQoKVxuICBzZXQgbnpTZWxlY3RlZEluZGV4KHZhbHVlOiBudW1iZXIgfCBudWxsKSB7XG4gICAgdGhpcy5pbmRleFRvU2VsZWN0ID0gdmFsdWUgPyB0b051bWJlcih2YWx1ZSwgbnVsbCkgOiBudWxsO1xuICB9XG5cbiAgZ2V0IG56U2VsZWN0ZWRJbmRleCgpOiBudW1iZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRJbmRleDtcbiAgfVxuXG4gIGdldCBpbmtCYXJBbmltYXRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uekFuaW1hdGVkID09PSB0cnVlIHx8ICh0aGlzLm56QW5pbWF0ZWQgYXMgTnpBbmltYXRlZEludGVyZmFjZSkuaW5rQmFyID09PSB0cnVlO1xuICB9XG5cbiAgZ2V0IHRhYlBhbmVBbmltYXRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uekFuaW1hdGVkID09PSB0cnVlIHx8ICh0aGlzLm56QW5pbWF0ZWQgYXMgTnpBbmltYXRlZEludGVyZmFjZSkudGFiUGFuZSA9PT0gdHJ1ZTtcbiAgfVxuXG4gIHNldFBvc2l0aW9uKHZhbHVlOiBOelRhYlBvc2l0aW9uKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudGFiQ29udGVudCkge1xuICAgICAgaWYgKHZhbHVlID09PSAnYm90dG9tJykge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLmluc2VydEJlZm9yZShcbiAgICAgICAgICB0aGlzLmVsLFxuICAgICAgICAgIHRoaXMudGFiQ29udGVudC5uYXRpdmVFbGVtZW50LFxuICAgICAgICAgIHRoaXMubnpUYWJzTmF2Q29tcG9uZW50LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5pbnNlcnRCZWZvcmUoXG4gICAgICAgICAgdGhpcy5lbCxcbiAgICAgICAgICB0aGlzLm56VGFic05hdkNvbXBvbmVudC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgdGhpcy50YWJDb250ZW50Lm5hdGl2ZUVsZW1lbnRcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzZXRDbGFzc01hcCgpOiB2b2lkIHtcbiAgICB0aGlzLm56VXBkYXRlSG9zdENsYXNzU2VydmljZS51cGRhdGVIb3N0Q2xhc3ModGhpcy5lbCwge1xuICAgICAgW2BhbnQtdGFic2BdOiB0cnVlLFxuICAgICAgW2BhbnQtdGFicy12ZXJ0aWNhbGBdOiB0aGlzLm56VGFiUG9zaXRpb24gPT09ICdsZWZ0JyB8fCB0aGlzLm56VGFiUG9zaXRpb24gPT09ICdyaWdodCcsXG4gICAgICBbYGFudC10YWJzLSR7dGhpcy5uelRhYlBvc2l0aW9ufWBdOiB0aGlzLm56VGFiUG9zaXRpb24sXG4gICAgICBbYGFudC10YWJzLW5vLWFuaW1hdGlvbmBdOlxuICAgICAgICB0aGlzLm56QW5pbWF0ZWQgPT09IGZhbHNlIHx8ICh0aGlzLm56QW5pbWF0ZWQgYXMgTnpBbmltYXRlZEludGVyZmFjZSkudGFiUGFuZSA9PT0gZmFsc2UsXG4gICAgICBbYGFudC10YWJzLSR7dGhpcy5uelR5cGV9YF06IHRoaXMubnpUeXBlLFxuICAgICAgW2BhbnQtdGFicy1sYXJnZWBdOiB0aGlzLm56U2l6ZSA9PT0gJ2xhcmdlJyxcbiAgICAgIFtgYW50LXRhYnMtc21hbGxgXTogdGhpcy5uelNpemUgPT09ICdzbWFsbCdcbiAgICB9KTtcbiAgfVxuXG4gIGNsaWNrTGFiZWwoaW5kZXg6IG51bWJlciwgZGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoIWRpc2FibGVkKSB7XG4gICAgICBjb25zdCB0YWJzID0gdGhpcy5saXN0T2ZOelRhYkNvbXBvbmVudC50b0FycmF5KCk7XG4gICAgICB0aGlzLm56U2VsZWN0ZWRJbmRleCA9IGluZGV4O1xuICAgICAgdGFic1tpbmRleF0ubnpDbGljay5lbWl0KCk7XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlQ2hhbmdlRXZlbnQoaW5kZXg6IG51bWJlcik6IE56VGFiQ2hhbmdlRXZlbnQge1xuICAgIGNvbnN0IGV2ZW50ID0gbmV3IE56VGFiQ2hhbmdlRXZlbnQoKTtcbiAgICBldmVudC5pbmRleCA9IGluZGV4O1xuICAgIGlmICh0aGlzLmxpc3RPZk56VGFiQ29tcG9uZW50ICYmIHRoaXMubGlzdE9mTnpUYWJDb21wb25lbnQubGVuZ3RoKSB7XG4gICAgICBldmVudC50YWIgPSB0aGlzLmxpc3RPZk56VGFiQ29tcG9uZW50LnRvQXJyYXkoKVtpbmRleF07XG4gICAgICB0aGlzLmxpc3RPZk56VGFiQ29tcG9uZW50LmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICAgICAgaWYgKGkgIT09IGluZGV4KSB7XG4gICAgICAgICAgaXRlbS5uekRlc2VsZWN0LmVtaXQoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBldmVudC50YWIubnpTZWxlY3QuZW1pdCgpO1xuICAgIH1cbiAgICByZXR1cm4gZXZlbnQ7XG4gIH1cblxuICAvKiogQ2xhbXBzIHRoZSBnaXZlbiBpbmRleCB0byB0aGUgYm91bmRzIG9mIDAgYW5kIHRoZSB0YWJzIGxlbmd0aC4gKi9cbiAgcHJpdmF0ZSBjbGFtcFRhYkluZGV4KGluZGV4OiBudW1iZXIgfCBudWxsKTogbnVtYmVyIHtcbiAgICAvLyBOb3RlIHRoZSBgfHwgMGAsIHdoaWNoIGVuc3VyZXMgdGhhdCB2YWx1ZXMgbGlrZSBOYU4gY2FuJ3QgZ2V0IHRocm91Z2hcbiAgICAvLyBhbmQgd2hpY2ggd291bGQgb3RoZXJ3aXNlIHRocm93IHRoZSBjb21wb25lbnQgaW50byBhbiBpbmZpbml0ZSBsb29wXG4gICAgLy8gKHNpbmNlIE1hdGgubWF4KE5hTiwgMCkgPT09IE5hTikuXG4gICAgcmV0dXJuIE1hdGgubWluKHRoaXMubGlzdE9mTnpUYWJDb21wb25lbnQubGVuZ3RoIC0gMSwgTWF0aC5tYXgoaW5kZXggfHwgMCwgMCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdWJzY3JpYmVUb1RhYkxhYmVscygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy50YWJMYWJlbFN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy50YWJMYWJlbFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICB0aGlzLnRhYkxhYmVsU3Vic2NyaXB0aW9uID0gbWVyZ2UoLi4udGhpcy5saXN0T2ZOelRhYkNvbXBvbmVudC5tYXAodGFiID0+IHRhYi5zdGF0ZUNoYW5nZXMpKS5zdWJzY3JpYmUoKCkgPT5cbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBuekNvbmZpZ1NlcnZpY2U6IE56Q29uZmlnU2VydmljZSxcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBuelVwZGF0ZUhvc3RDbGFzc1NlcnZpY2U6IE56VXBkYXRlSG9zdENsYXNzU2VydmljZSxcbiAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgcm91dGVyOiBSb3V0ZXJcbiAgKSB7fVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlcy5uelRhYlBvc2l0aW9uKSB7XG4gICAgICBpZiAodGhpcy5uelRhYlBvc2l0aW9uID09PSAndG9wJyB8fCB0aGlzLm56VGFiUG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICAgIHRoaXMudGFiUG9zaXRpb25Nb2RlID0gJ2hvcml6b250YWwnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy50YWJQb3NpdGlvbk1vZGUgPSAndmVydGljYWwnO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRQb3NpdGlvbih0aGlzLm56VGFiUG9zaXRpb24pO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcy5uelR5cGUpIHtcbiAgICAgIGlmICh0aGlzLm56VHlwZSA9PT0gJ2NhcmQnKSB7XG4gICAgICAgIHRoaXMubnpBbmltYXRlZCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoY2hhbmdlcy5uelNpemUgfHwgY2hhbmdlcy5uekFuaW1hdGVkIHx8IGNoYW5nZXMubnpUYWJQb3NpdGlvbiB8fCBjaGFuZ2VzLm56VHlwZSkge1xuICAgICAgdGhpcy5zZXRDbGFzc01hcCgpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc2V0Q2xhc3NNYXAoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5saXN0T2ZOelRhYkNvbXBvbmVudCAmJiB0aGlzLmxpc3RPZk56VGFiQ29tcG9uZW50Lmxlbmd0aCkge1xuICAgICAgLy8gRG9uJ3QgY2xhbXAgdGhlIGBpbmRleFRvU2VsZWN0YCBpbW1lZGlhdGVseSBpbiB0aGUgc2V0dGVyIGJlY2F1c2UgaXQgY2FuIGhhcHBlbiB0aGF0XG4gICAgICAvLyB0aGUgYW1vdW50IG9mIHRhYnMgY2hhbmdlcyBiZWZvcmUgdGhlIGFjdHVhbCBjaGFuZ2UgZGV0ZWN0aW9uIHJ1bnMuXG4gICAgICBjb25zdCBpbmRleFRvU2VsZWN0ID0gKHRoaXMuaW5kZXhUb1NlbGVjdCA9IHRoaXMuY2xhbXBUYWJJbmRleCh0aGlzLmluZGV4VG9TZWxlY3QpKTtcbiAgICAgIC8vIElmIHRoZXJlIGlzIGEgY2hhbmdlIGluIHNlbGVjdGVkIGluZGV4LCBlbWl0IGEgY2hhbmdlIGV2ZW50LiBTaG91bGQgbm90IHRyaWdnZXIgaWZcbiAgICAgIC8vIHRoZSBzZWxlY3RlZCBpbmRleCBoYXMgbm90IHlldCBiZWVuIGluaXRpYWxpemVkLlxuICAgICAgaWYgKHRoaXMuX3NlbGVjdGVkSW5kZXggIT09IGluZGV4VG9TZWxlY3QpIHtcbiAgICAgICAgY29uc3QgaXNGaXJzdFJ1biA9IHRoaXMuX3NlbGVjdGVkSW5kZXggPT0gbnVsbDtcbiAgICAgICAgaWYgKCFpc0ZpcnN0UnVuKSB7XG4gICAgICAgICAgdGhpcy5uelNlbGVjdENoYW5nZS5lbWl0KHRoaXMuY3JlYXRlQ2hhbmdlRXZlbnQoaW5kZXhUb1NlbGVjdCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hhbmdpbmcgdGhlc2UgdmFsdWVzIGFmdGVyIGNoYW5nZSBkZXRlY3Rpb24gaGFzIHJ1blxuICAgICAgICAvLyBzaW5jZSB0aGUgY2hlY2tlZCBjb250ZW50IG1heSBjb250YWluIHJlZmVyZW5jZXMgdG8gdGhlbS5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgdGhpcy5saXN0T2ZOelRhYkNvbXBvbmVudC5mb3JFYWNoKCh0YWIsIGluZGV4KSA9PiAodGFiLmlzQWN0aXZlID0gaW5kZXggPT09IGluZGV4VG9TZWxlY3QpKTtcblxuICAgICAgICAgIGlmICghaXNGaXJzdFJ1bikge1xuICAgICAgICAgICAgdGhpcy5uelNlbGVjdGVkSW5kZXhDaGFuZ2UuZW1pdChpbmRleFRvU2VsZWN0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBTZXR1cCB0aGUgcG9zaXRpb24gZm9yIGVhY2ggdGFiIGFuZCBvcHRpb25hbGx5IHNldHVwIGFuIG9yaWdpbiBvbiB0aGUgbmV4dCBzZWxlY3RlZCB0YWIuXG4gICAgICB0aGlzLmxpc3RPZk56VGFiQ29tcG9uZW50LmZvckVhY2goKHRhYjogTnpUYWJDb21wb25lbnQsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgdGFiLnBvc2l0aW9uID0gaW5kZXggLSBpbmRleFRvU2VsZWN0O1xuXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIGFscmVhZHkgYSBzZWxlY3RlZCB0YWIsIHRoZW4gc2V0IHVwIGFuIG9yaWdpbiBmb3IgdGhlIG5leHQgc2VsZWN0ZWQgdGFiXG4gICAgICAgIC8vIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmUgYWxyZWFkeS5cbiAgICAgICAgaWYgKHRoaXMuX3NlbGVjdGVkSW5kZXggIT0gbnVsbCAmJiB0YWIucG9zaXRpb24gPT09IDAgJiYgIXRhYi5vcmlnaW4pIHtcbiAgICAgICAgICB0YWIub3JpZ2luID0gaW5kZXhUb1NlbGVjdCAtIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAodGhpcy5fc2VsZWN0ZWRJbmRleCAhPT0gaW5kZXhUb1NlbGVjdCkge1xuICAgICAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gaW5kZXhUb1NlbGVjdDtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaWJlVG9UYWJMYWJlbHMoKTtcblxuICAgIC8vIFN1YnNjcmliZSB0byBjaGFuZ2VzIGluIHRoZSBhbW91bnQgb2YgdGFicywgaW4gb3JkZXIgdG8gYmVcbiAgICAvLyBhYmxlIHRvIHJlLXJlbmRlciB0aGUgY29udGVudCBhcyBuZXcgdGFicyBhcmUgYWRkZWQgb3IgcmVtb3ZlZC5cbiAgICB0aGlzLnRhYnNTdWJzY3JpcHRpb24gPSB0aGlzLmxpc3RPZk56VGFiQ29tcG9uZW50LmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGNvbnN0IGluZGV4VG9TZWxlY3QgPSB0aGlzLmNsYW1wVGFiSW5kZXgodGhpcy5pbmRleFRvU2VsZWN0KTtcblxuICAgICAgLy8gTWFpbnRhaW4gdGh