UNPKG

ng-zorro-antd

Version:

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

622 lines 53.6 kB
/** * @fileoverview added by tsickle * Generated from: nz-tabs-nav.component.ts * @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 */ /** code from https://github.com/angular/material2 */ import { Directionality } from '@angular/cdk/bidi'; import { Platform } from '@angular/cdk/platform'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, Input, NgZone, Optional, Output, QueryList, Renderer2, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core'; import { pxToNumber, InputBoolean, NzDomEventService } from 'ng-zorro-antd/core'; import { merge, of as observableOf, Subject } from 'rxjs'; import { finalize, startWith, takeUntil } from 'rxjs/operators'; import { NzTabLabelDirective } from './nz-tab-label.directive'; import { NzTabsInkBarDirective } from './nz-tabs-ink-bar.directive'; /** @type {?} */ var EXAGGERATED_OVERSCROLL = 64; var NzTabsNavComponent = /** @class */ (function () { function NzTabsNavComponent(elementRef, ngZone, renderer, cdr, platform, nzDomEventService, dir) { this.elementRef = elementRef; this.ngZone = ngZone; this.renderer = renderer; this.cdr = cdr; this.platform = platform; this.nzDomEventService = nzDomEventService; this.dir = dir; this._tabPositionMode = 'horizontal'; this._scrollDistance = 0; this._selectedIndex = 0; this.destroy$ = new Subject(); this.showPaginationControls = false; this.disableScrollAfter = true; this.disableScrollBefore = true; this.selectedIndexChanged = false; this.realignInkBar = null; this.nzOnNextClick = new EventEmitter(); this.nzOnPrevClick = new EventEmitter(); this.nzAnimated = true; this.nzHideBar = false; this.nzShowPagination = true; this.nzType = 'line'; } Object.defineProperty(NzTabsNavComponent.prototype, "nzPositionMode", { get: /** * @return {?} */ function () { return this._tabPositionMode; }, set: /** * @param {?} value * @return {?} */ function (value) { var _this = this; this._tabPositionMode = value; this.alignInkBarToSelectedTab(); if (this.nzShowPagination) { Promise.resolve().then((/** * @return {?} */ function () { _this.updatePagination(); })); } }, enumerable: true, configurable: true }); Object.defineProperty(NzTabsNavComponent.prototype, "selectedIndex", { get: /** * @return {?} */ function () { return this._selectedIndex; }, set: /** * @param {?} value * @return {?} */ function (value) { this.selectedIndexChanged = this._selectedIndex !== value; this._selectedIndex = value; }, enumerable: true, configurable: true }); /** * @return {?} */ NzTabsNavComponent.prototype.onContentChanges = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var textContent = this.elementRef.nativeElement.textContent; // We need to diff the text content of the header, because the MutationObserver callback // will fire even if the text content didn't change which is inefficient and is prone // to infinite loops if a poorly constructed expression is passed in (see #14249). if (textContent !== this.currentTextContent) { this.currentTextContent = textContent; this.ngZone.run((/** * @return {?} */ function () { if (_this.nzShowPagination) { _this.updatePagination(); } _this.alignInkBarToSelectedTab(); _this.cdr.markForCheck(); })); } }; /** * @param {?} scrollDir * @return {?} */ NzTabsNavComponent.prototype.scrollHeader = /** * @param {?} scrollDir * @return {?} */ function (scrollDir) { if (scrollDir === 'before' && !this.disableScrollBefore) { this.nzOnPrevClick.emit(); } else if (scrollDir === 'after' && !this.disableScrollAfter) { this.nzOnNextClick.emit(); } // Move the scroll distance one-third the length of the tab list's viewport. this.scrollDistance += ((scrollDir === 'before' ? -1 : 1) * this.viewWidthHeightPix) / 3; }; /** * @return {?} */ NzTabsNavComponent.prototype.ngAfterContentChecked = /** * @return {?} */ function () { if (this.tabLabelCount !== this.listOfNzTabLabelDirective.length) { if (this.nzShowPagination) { this.updatePagination(); } this.tabLabelCount = this.listOfNzTabLabelDirective.length; this.cdr.markForCheck(); } if (this.selectedIndexChanged) { this.scrollToLabel(this._selectedIndex); if (this.nzShowPagination) { this.checkScrollingControls(); } this.alignInkBarToSelectedTab(); this.selectedIndexChanged = false; this.cdr.markForCheck(); } if (this.scrollDistanceChanged) { if (this.nzShowPagination) { this.updateTabScrollPosition(); } this.scrollDistanceChanged = false; this.cdr.markForCheck(); } }; /** * @return {?} */ NzTabsNavComponent.prototype.ngAfterContentInit = /** * @return {?} */ function () { var _this = this; this.realignInkBar = this.ngZone.runOutsideAngular((/** * @return {?} */ function () { /** @type {?} */ var dirChange = _this.dir ? _this.dir.change : observableOf(null); /** @type {?} */ var resize = typeof window !== 'undefined' ? _this.nzDomEventService.registerResizeListener().pipe(takeUntil(_this.destroy$), finalize((/** * @return {?} */ function () { return _this.nzDomEventService.unregisterResizeListener(); }))) : observableOf(null); return merge(dirChange, resize) .pipe(startWith(null)) .subscribe((/** * @return {?} */ function () { if (_this.nzShowPagination) { _this.updatePagination(); } _this.alignInkBarToSelectedTab(); })); })); }; /** * @return {?} */ NzTabsNavComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { this.destroy$.next(); this.destroy$.complete(); if (this.realignInkBar) { this.realignInkBar.unsubscribe(); } }; /** * @return {?} */ NzTabsNavComponent.prototype.updateTabScrollPosition = /** * @return {?} */ function () { /** @type {?} */ var scrollDistance = this.scrollDistance; if (this.nzPositionMode === 'horizontal') { /** @type {?} */ var translateX = this.getLayoutDirection() === 'ltr' ? -scrollDistance : scrollDistance; this.renderer.setStyle(this.navListElement.nativeElement, 'transform', "translate3d(" + translateX + "px, 0, 0)"); } else { this.renderer.setStyle(this.navListElement.nativeElement, 'transform', "translate3d(0," + -scrollDistance + "px, 0)"); } }; /** * @return {?} */ NzTabsNavComponent.prototype.updatePagination = /** * @return {?} */ function () { this.checkPaginationEnabled(); this.checkScrollingControls(); this.updateTabScrollPosition(); }; /** * @return {?} */ NzTabsNavComponent.prototype.checkPaginationEnabled = /** * @return {?} */ function () { /** @type {?} */ var isEnabled = this.tabListScrollWidthHeightPix > this.tabListScrollOffSetWidthHeight; if (!isEnabled) { this.scrollDistance = 0; } if (isEnabled !== this.showPaginationControls) { this.cdr.markForCheck(); } this.showPaginationControls = isEnabled; }; /** * @param {?} labelIndex * @return {?} */ NzTabsNavComponent.prototype.scrollToLabel = /** * @param {?} labelIndex * @return {?} */ function (labelIndex) { /** @type {?} */ var selectedLabel = this.listOfNzTabLabelDirective ? this.listOfNzTabLabelDirective.toArray()[labelIndex] : null; if (selectedLabel) { // The view length is the visible width of the tab labels. /** @type {?} */ var labelBeforePos = void 0; /** @type {?} */ var labelAfterPos = void 0; if (this.nzPositionMode === 'horizontal') { if (this.getLayoutDirection() === 'ltr') { labelBeforePos = selectedLabel.getOffsetLeft(); labelAfterPos = labelBeforePos + selectedLabel.getOffsetWidth(); } else { labelAfterPos = this.navListElement.nativeElement.offsetWidth - selectedLabel.getOffsetLeft(); labelBeforePos = labelAfterPos - selectedLabel.getOffsetWidth(); } } else { labelBeforePos = selectedLabel.getOffsetTop(); labelAfterPos = labelBeforePos + selectedLabel.getOffsetHeight(); } /** @type {?} */ var beforeVisiblePos = this.scrollDistance; /** @type {?} */ var afterVisiblePos = this.scrollDistance + this.viewWidthHeightPix; if (labelBeforePos < beforeVisiblePos) { // Scroll header to move label to the before direction this.scrollDistance -= beforeVisiblePos - labelBeforePos + EXAGGERATED_OVERSCROLL; } else if (labelAfterPos > afterVisiblePos) { // Scroll header to move label to the after direction this.scrollDistance += labelAfterPos - afterVisiblePos + EXAGGERATED_OVERSCROLL; } } }; /** * @return {?} */ NzTabsNavComponent.prototype.checkScrollingControls = /** * @return {?} */ function () { // Check if the pagination arrows should be activated. this.disableScrollBefore = this.scrollDistance === 0; this.disableScrollAfter = this.scrollDistance === this.getMaxScrollDistance(); this.cdr.markForCheck(); }; /** * Determines what is the maximum length in pixels that can be set for the scroll distance. This * is equal to the difference in width between the tab list container and tab header container. * * This is an expensive call that forces a layout reflow to compute box and scroll metrics and * should be called sparingly. */ /** * Determines what is the maximum length in pixels that can be set for the scroll distance. This * is equal to the difference in width between the tab list container and tab header container. * * This is an expensive call that forces a layout reflow to compute box and scroll metrics and * should be called sparingly. * @return {?} */ NzTabsNavComponent.prototype.getMaxScrollDistance = /** * Determines what is the maximum length in pixels that can be set for the scroll distance. This * is equal to the difference in width between the tab list container and tab header container. * * This is an expensive call that forces a layout reflow to compute box and scroll metrics and * should be called sparingly. * @return {?} */ function () { return this.tabListScrollWidthHeightPix - this.viewWidthHeightPix || 0; }; Object.defineProperty(NzTabsNavComponent.prototype, "scrollDistance", { get: /** * @return {?} */ function () { return this._scrollDistance; }, /** Sets the distance in pixels that the tab header should be transformed in the X-axis. */ set: /** * Sets the distance in pixels that the tab header should be transformed in the X-axis. * @param {?} v * @return {?} */ function (v) { this._scrollDistance = Math.max(0, Math.min(this.getMaxScrollDistance(), v)); // Mark that the scroll distance has changed so that after the view is checked, the CSS // transformation can move the header. this.scrollDistanceChanged = true; this.checkScrollingControls(); }, enumerable: true, configurable: true }); Object.defineProperty(NzTabsNavComponent.prototype, "viewWidthHeightPix", { get: /** * @return {?} */ function () { /** @type {?} */ var PAGINATION_PIX = 0; if (this.showPaginationControls) { PAGINATION_PIX = this.navContainerScrollPaddingPix; } if (this.nzPositionMode === 'horizontal') { return this.navContainerElement.nativeElement.offsetWidth - PAGINATION_PIX; } else { return this.navContainerElement.nativeElement.offsetHeight - PAGINATION_PIX; } }, enumerable: true, configurable: true }); Object.defineProperty(NzTabsNavComponent.prototype, "navContainerScrollPaddingPix", { get: /** * @return {?} */ function () { if (this.platform.isBrowser) { /** @type {?} */ var navContainer = this.navContainerElement.nativeElement; // tslint:disable: no-any /** @type {?} */ var originStyle = window.getComputedStyle ? window.getComputedStyle(navContainer) : ((/** @type {?} */ (navContainer))).currentStyle; if (this.nzPositionMode === 'horizontal') { return pxToNumber(originStyle.paddingLeft) + pxToNumber(originStyle.paddingRight); } else { return pxToNumber(originStyle.paddingTop) + pxToNumber(originStyle.paddingBottom); } } else { return 0; } }, enumerable: true, configurable: true }); Object.defineProperty(NzTabsNavComponent.prototype, "tabListScrollWidthHeightPix", { get: /** * @return {?} */ function () { if (this.nzPositionMode === 'horizontal') { return this.navListElement.nativeElement.scrollWidth; } else { return this.navListElement.nativeElement.scrollHeight; } }, enumerable: true, configurable: true }); Object.defineProperty(NzTabsNavComponent.prototype, "tabListScrollOffSetWidthHeight", { get: /** * @return {?} */ function () { if (this.nzPositionMode === 'horizontal') { return this.scrollListElement.nativeElement.offsetWidth; } else { return this.elementRef.nativeElement.offsetHeight; } }, enumerable: true, configurable: true }); /** * @return {?} */ NzTabsNavComponent.prototype.getLayoutDirection = /** * @return {?} */ function () { return this.dir && this.dir.value === 'rtl' ? 'rtl' : 'ltr'; }; /** * @return {?} */ NzTabsNavComponent.prototype.alignInkBarToSelectedTab = /** * @return {?} */ function () { if (this.nzType === 'line') { /** @type {?} */ var selectedLabelWrapper = this.listOfNzTabLabelDirective && this.listOfNzTabLabelDirective.length ? this.listOfNzTabLabelDirective.toArray()[this.selectedIndex].elementRef.nativeElement : null; if (this.nzTabsInkBarDirective) { this.nzTabsInkBarDirective.alignToElement(selectedLabelWrapper); } } }; NzTabsNavComponent.decorators = [ { type: Component, args: [{ selector: '[nz-tabs-nav]', exportAs: 'nzTabsNav', preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div style=\"float:right;\" *ngIf=\"nzTabBarExtraContent\" class=\"ant-tabs-extra-content\">\n <ng-template [ngTemplateOutlet]=\"nzTabBarExtraContent\"></ng-template>\n</div>\n<div class=\"ant-tabs-nav-container\"\n [class.ant-tabs-nav-container-scrolling]=\"showPaginationControls\"\n #navContainerElement>\n <span class=\"ant-tabs-tab-prev\"\n (click)=\"scrollHeader('before')\"\n [class.ant-tabs-tab-btn-disabled]=\"disableScrollBefore\"\n [class.ant-tabs-tab-arrow-show]=\"showPaginationControls\">\n <span class=\"ant-tabs-tab-prev-icon\">\n <i nz-icon [nzType]=\"nzPositionMode === 'horizontal' ? 'left' : 'up'\" class=\"ant-tabs-tab-prev-icon-target\"></i>\n </span>\n </span>\n <span class=\"ant-tabs-tab-next\"\n (click)=\"scrollHeader('after')\"\n [class.ant-tabs-tab-btn-disabled]=\"disableScrollAfter\"\n [class.ant-tabs-tab-arrow-show]=\"showPaginationControls\">\n <span class=\"ant-tabs-tab-next-icon\">\n <i nz-icon [nzType]=\"nzPositionMode === 'horizontal' ? 'right' : 'down'\" class=\"ant-tabs-tab-next-icon-target\"></i>\n </span>\n </span>\n <div class=\"ant-tabs-nav-wrap\">\n <div class=\"ant-tabs-nav-scroll\" #scrollListElement>\n <div class=\"ant-tabs-nav\"\n [class.ant-tabs-nav-animated]=\"nzAnimated\"\n #navListElement\n (cdkObserveContent)=\"onContentChanges()\">\n <div>\n <ng-content></ng-content>\n </div>\n <div nz-tabs-ink-bar [hidden]=\"nzHideBar\" [nzAnimated]=\"nzAnimated\" [nzPositionMode]=\"nzPositionMode\" style=\"display: block;\"></div>\n </div>\n </div>\n </div>\n</div>" }] } ]; /** @nocollapse */ NzTabsNavComponent.ctorParameters = function () { return [ { type: ElementRef }, { type: NgZone }, { type: Renderer2 }, { type: ChangeDetectorRef }, { type: Platform }, { type: NzDomEventService }, { type: Directionality, decorators: [{ type: Optional }] } ]; }; NzTabsNavComponent.propDecorators = { listOfNzTabLabelDirective: [{ type: ContentChildren, args: [NzTabLabelDirective,] }], nzTabsInkBarDirective: [{ type: ViewChild, args: [NzTabsInkBarDirective, { static: true },] }], navContainerElement: [{ type: ViewChild, args: ['navContainerElement', { static: true },] }], navListElement: [{ type: ViewChild, args: ['navListElement', { static: true },] }], scrollListElement: [{ type: ViewChild, args: ['scrollListElement', { static: true },] }], nzOnNextClick: [{ type: Output }], nzOnPrevClick: [{ type: Output }], nzTabBarExtraContent: [{ type: Input }], nzAnimated: [{ type: Input }], nzHideBar: [{ type: Input }], nzShowPagination: [{ type: Input }], nzType: [{ type: Input }], nzPositionMode: [{ type: Input }], selectedIndex: [{ type: Input }] }; tslib_1.__decorate([ InputBoolean(), tslib_1.__metadata("design:type", Object) ], NzTabsNavComponent.prototype, "nzAnimated", void 0); tslib_1.__decorate([ InputBoolean(), tslib_1.__metadata("design:type", Object) ], NzTabsNavComponent.prototype, "nzHideBar", void 0); tslib_1.__decorate([ InputBoolean(), tslib_1.__metadata("design:type", Object) ], NzTabsNavComponent.prototype, "nzShowPagination", void 0); return NzTabsNavComponent; }()); export { NzTabsNavComponent }; if (false) { /** * @type {?} * @private */ NzTabsNavComponent.prototype._tabPositionMode; /** * @type {?} * @private */ NzTabsNavComponent.prototype._scrollDistance; /** * @type {?} * @private */ NzTabsNavComponent.prototype._selectedIndex; /** * Cached text content of the header. * @type {?} * @private */ NzTabsNavComponent.prototype.currentTextContent; /** * @type {?} * @private */ NzTabsNavComponent.prototype.destroy$; /** @type {?} */ NzTabsNavComponent.prototype.showPaginationControls; /** @type {?} */ NzTabsNavComponent.prototype.disableScrollAfter; /** @type {?} */ NzTabsNavComponent.prototype.disableScrollBefore; /** @type {?} */ NzTabsNavComponent.prototype.selectedIndexChanged; /** @type {?} */ NzTabsNavComponent.prototype.realignInkBar; /** @type {?} */ NzTabsNavComponent.prototype.tabLabelCount; /** @type {?} */ NzTabsNavComponent.prototype.scrollDistanceChanged; /** @type {?} */ NzTabsNavComponent.prototype.listOfNzTabLabelDirective; /** @type {?} */ NzTabsNavComponent.prototype.nzTabsInkBarDirective; /** @type {?} */ NzTabsNavComponent.prototype.navContainerElement; /** @type {?} */ NzTabsNavComponent.prototype.navListElement; /** @type {?} */ NzTabsNavComponent.prototype.scrollListElement; /** @type {?} */ NzTabsNavComponent.prototype.nzOnNextClick; /** @type {?} */ NzTabsNavComponent.prototype.nzOnPrevClick; /** @type {?} */ NzTabsNavComponent.prototype.nzTabBarExtraContent; /** @type {?} */ NzTabsNavComponent.prototype.nzAnimated; /** @type {?} */ NzTabsNavComponent.prototype.nzHideBar; /** @type {?} */ NzTabsNavComponent.prototype.nzShowPagination; /** @type {?} */ NzTabsNavComponent.prototype.nzType; /** @type {?} */ NzTabsNavComponent.prototype.elementRef; /** * @type {?} * @private */ NzTabsNavComponent.prototype.ngZone; /** * @type {?} * @private */ NzTabsNavComponent.prototype.renderer; /** * @type {?} * @private */ NzTabsNavComponent.prototype.cdr; /** * @type {?} * @private */ NzTabsNavComponent.prototype.platform; /** * @type {?} * @private */ NzTabsNavComponent.prototype.nzDomEventService; /** * @type {?} * @private */ NzTabsNavComponent.prototype.dir; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnotdGFicy1uYXYuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC90YWJzLyIsInNvdXJjZXMiOlsibnotdGFicy1uYXYuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBU0EsT0FBTyxFQUFhLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBR0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sRUFFTixRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1QsV0FBVyxFQUNYLFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNqRixPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsSUFBSSxZQUFZLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUN4RSxPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7SUFHOUQsc0JBQXNCLEdBQUcsRUFBRTtBQUdqQztJQTRERSw0QkFDUyxVQUFzQixFQUNyQixNQUFjLEVBQ2QsUUFBbUIsRUFDbkIsR0FBc0IsRUFDdEIsUUFBa0IsRUFDbEIsaUJBQW9DLEVBQ3hCLEdBQW1CO1FBTmhDLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDckIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtR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QzdCLG9DQUFzQjs7Ozs7SUFDdEIsc0NBQTJCOzs7OztJQUMzQixpQ0FBOEI7Ozs7O0lBQzlCLHNDQUEwQjs7Ozs7SUFDMUIsK0NBQTRDOzs7OztJQUM1QyxpQ0FBdUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgQWxpYmFiYS5jb20gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuLyoqIGNvZGUgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9tYXRlcmlhbDIgKi9cbmltcG9ydCB7IERpcmVjdGlvbiwgRGlyZWN0aW9uYWxpdHkgfSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wbGF0Zm9ybSc7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRDaGVja2VkLFxuICBBZnRlckNvbnRlbnRJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uRGVzdHJveSxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBSZW5kZXJlcjIsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgcHhUb051bWJlciwgSW5wdXRCb29sZWFuLCBOekRvbUV2ZW50U2VydmljZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZSc7XG5pbXBvcnQgeyBtZXJnZSwgb2YgYXMgb2JzZXJ2YWJsZU9mLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbmFsaXplLCBzdGFydFdpdGgsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTnpUYWJMYWJlbERpcmVjdGl2ZSB9IGZyb20gJy4vbnotdGFiLWxhYmVsLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBOelRhYnNJbmtCYXJEaXJlY3RpdmUgfSBmcm9tICcuL256LXRhYnMtaW5rLWJhci5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTnpUYWJQb3NpdGlvbk1vZGUgfSBmcm9tICcuL256LXRhYnNldC5jb21wb25lbnQnO1xuXG5jb25zdCBFWEFHR0VSQVRFRF9PVkVSU0NST0xMID0gNjQ7XG5leHBvcnQgdHlwZSBTY3JvbGxEaXJlY3Rpb24gPSAnYWZ0ZXInIHwgJ2JlZm9yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ1tuei10YWJzLW5hdl0nLFxuICBleHBvcnRBczogJ256VGFic05hdicsXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgdGVtcGxhdGVVcmw6ICcuL256LXRhYnMtbmF2LmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBOelRhYnNOYXZDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRDaGVja2VkLCBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIF90YWJQb3NpdGlvbk1vZGU6IE56VGFiUG9zaXRpb25Nb2RlID0gJ2hvcml6b250YWwnO1xuICBwcml2YXRlIF9zY3JvbGxEaXN0YW5jZSA9IDA7XG4gIHByaXZhdGUgX3NlbGVjdGVkSW5kZXggPSAwO1xuICAvKiogQ2FjaGVkIHRleHQgY29udGVudCBvZiB0aGUgaGVhZGVyLiAqL1xuICBwcml2YXRlIGN1cnJlbnRUZXh0Q29udGVudDogc3RyaW5nO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgc2hvd1BhZ2luYXRpb25Db250cm9scyA9IGZhbHNlO1xuICBkaXNhYmxlU2Nyb2xsQWZ0ZXIgPSB0cnVlO1xuICBkaXNhYmxlU2Nyb2xsQmVmb3JlID0gdHJ1ZTtcbiAgc2VsZWN0ZWRJbmRleENoYW5nZWQgPSBmYWxzZTtcbiAgcmVhbGlnbklua0JhcjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG4gIHRhYkxhYmVsQ291bnQ6IG51bWJlcjtcbiAgc2Nyb2xsRGlzdGFuY2VDaGFuZ2VkOiBib29sZWFuO1xuICBAQ29udGVudENoaWxkcmVuKE56VGFiTGFiZWxEaXJlY3RpdmUpIGxpc3RPZk56VGFiTGFiZWxEaXJlY3RpdmU6IFF1ZXJ5TGlzdDxOelRhYkxhYmVsRGlyZWN0aXZlPjtcbiAgQFZpZXdDaGlsZChOelRhYnNJbmtCYXJEaXJlY3RpdmUsIHsgc3RhdGljOiB0cnVlIH0pIG56VGFic0lua0JhckRpcmVjdGl2ZTogTnpUYWJzSW5rQmFyRGlyZWN0aXZlO1xuICBAVmlld0NoaWxkKCduYXZDb250YWluZXJFbGVtZW50JywgeyBzdGF0aWM6IHRydWUgfSkgbmF2Q29udGFpbmVyRWxlbWVudDogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ25hdkxpc3RFbGVtZW50JywgeyBzdGF0aWM6IHRydWUgfSkgbmF2TGlzdEVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuICBAVmlld0NoaWxkKCdzY3JvbGxMaXN0RWxlbWVudCcsIHsgc3RhdGljOiB0cnVlIH0pIHNjcm9sbExpc3RFbGVtZW50OiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IG56T25OZXh0Q2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuek9uUHJldkNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBASW5wdXQoKSBuelRhYkJhckV4dHJhQ29udGVudDogVGVtcGxhdGVSZWY8dm9pZD47XG4gIEBJbnB1dCgpIEBJbnB1dEJvb2xlYW4oKSBuekFuaW1hdGVkID0gdHJ1ZTtcbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56SGlkZUJhciA9IGZhbHNlO1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgbnpTaG93UGFnaW5hdGlvbiA9IHRydWU7XG4gIEBJbnB1dCgpIG56VHlwZSA9ICdsaW5lJztcblxuICBASW5wdXQoKVxuICBzZXQgbnpQb3NpdGlvbk1vZGUodmFsdWU6IE56VGFiUG9zaXRpb25Nb2RlKSB7XG4gICAgdGhpcy5fdGFiUG9zaXRpb25Nb2RlID0gdmFsdWU7XG4gICAgdGhpcy5hbGlnbklua0JhclRvU2VsZWN0ZWRUYWIoKTtcbiAgICBpZiAodGhpcy5uelNob3dQYWdpbmF0aW9uKSB7XG4gICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy51cGRhdGVQYWdpbmF0aW9uKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgbnpQb3NpdGlvbk1vZGUoKTogTnpUYWJQb3NpdGlvbk1vZGUge1xuICAgIHJldHVybiB0aGlzLl90YWJQb3NpdGlvbk1vZGU7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgc2VsZWN0ZWRJbmRleCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5zZWxlY3RlZEluZGV4Q2hhbmdlZCA9IHRoaXMuX3NlbGVjdGVkSW5kZXggIT09IHZhbHVlO1xuICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBzZWxlY3RlZEluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBwbGF0Zm9ybTogUGxhdGZvcm0sXG4gICAgcHJpdmF0ZSBuekRvbUV2ZW50U2VydmljZTogTnpEb21FdmVudFNlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBkaXI6IERpcmVjdGlvbmFsaXR5XG4gICkge31cblxuICBvbkNvbnRlbnRDaGFuZ2VzKCk6IHZvaWQge1xuICAgIGNvbnN0IHRleHRDb250ZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQudGV4dENvbnRlbnQ7XG4gICAgLy8gV2UgbmVlZCB0byBkaWZmIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIGhlYWRlciwgYmVjYXVzZSB0aGUgTXV0YXRpb25PYnNlcnZlciBjYWxsYmFja1xuICAgIC8vIHdpbGwgZmlyZSBldmVuIGlmIHRoZSB0ZXh0IGNvbnRlbnQgZGlkbid0IGNoYW5nZSB3aGljaCBpcyBpbmVmZmljaWVudCBhbmQgaXMgcHJvbmVcbiAgICAvLyB0byBpbmZpbml0ZSBsb29wcyBpZiBhIHBvb3JseSBjb25zdHJ1Y3RlZCBleHByZXNzaW9uIGlzIHBhc3NlZCBpbiAoc2VlICMxNDI0OSkuXG4gICAgaWYgKHRleHRDb250ZW50ICE9PSB0aGlzLmN1cnJlbnRUZXh0Q29udGVudCkge1xuICAgICAgdGhpcy5jdXJyZW50VGV4dENvbnRlbnQgPSB0ZXh0Q29udGVudDtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLm56U2hvd1BhZ2luYXRpb24pIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVBhZ2luYXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFsaWduSW5rQmFyVG9TZWxlY3RlZFRhYigpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHNjcm9sbEhlYWRlcihzY3JvbGxEaXI6IFNjcm9sbERpcmVjdGlvbik6IHZvaWQge1xuICAgIGlmIChzY3JvbGxEaXIgPT09ICdiZWZvcmUnICYmICF0aGlzLmRpc2FibGVTY3JvbGxCZWZvcmUpIHtcbiAgICAgIHRoaXMubnpPblByZXZDbGljay5lbWl0KCk7XG4gICAgfSBlbHNlIGlmIChzY3JvbGxEaXIgPT09ICdhZnRlcicgJiYgIXRoaXMuZGlzYWJsZVNjcm9sbEFmdGVyKSB7XG4gICAgICB0aGlzLm56T25OZXh0Q2xpY2suZW1pdCgpO1xuICAgIH1cbiAgICAvLyBNb3ZlIHRoZSBzY3JvbGwgZGlzdGFuY2Ugb25lLXRoaXJkIHRoZSBsZW5ndGggb2YgdGhlIHRhYiBsaXN0J3Mgdmlld3BvcnQuXG4gICAgdGhpcy5zY3JvbGxEaXN0YW5jZSArPSAoKHNjcm9sbERpciA9PT0gJ2JlZm9yZScgPyAtMSA6IDEpICogdGhpcy52aWV3V2lkdGhIZWlnaHRQaXgpIC8gMztcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy50YWJMYWJlbENvdW50ICE9PSB0aGlzLmxpc3RPZk56VGFiTGFiZWxEaXJlY3RpdmUubGVuZ3RoKSB7XG4gICAgICBpZiAodGhpcy5uelNob3dQYWdpbmF0aW9uKSB7XG4gICAgICAgIHRoaXMudXBkYXRlUGFnaW5hdGlvbigpO1xuICAgICAgfVxuICAgICAgdGhpcy50YWJMYWJlbENvdW50ID0gdGhpcy5saXN0T2ZOelRhYkxhYmVsRGlyZWN0aXZlLmxlbmd0aDtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgICBpZiAodGhpcy5zZWxlY3RlZEluZGV4Q2hhbmdlZCkge1xuICAgICAgdGhpcy5zY3JvbGxUb0xhYmVsKHRoaXMuX3NlbGVjdGVkSW5kZXgpO1xuICAgICAgaWYgKHRoaXMubnpTaG93UGFnaW5hdGlvbikge1xuICAgICAgICB0aGlzLmNoZWNrU2Nyb2xsaW5nQ29udHJvbHMoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWxpZ25JbmtCYXJUb1NlbGVjdGVkVGFiKCk7XG4gICAgICB0aGlzLnNlbGVjdGVkSW5kZXhDaGFuZ2VkID0gZmFsc2U7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2Nyb2xsRGlzdGFuY2VDaGFuZ2VkKSB7XG4gICAgICBpZiAodGhpcy5uelNob3dQYWdpbmF0aW9uKSB7XG4gICAgICAgIHRoaXMudXBkYXRlVGFiU2Nyb2xsUG9zaXRpb24oKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2Nyb2xsRGlzdGFuY2VDaGFuZ2VkID0gZmFsc2U7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZWFsaWduSW5rQmFyID0gdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgZGlyQ2hhbmdlID0gdGhpcy5kaXIgPyB0aGlzLmRpci5jaGFuZ2UgOiBvYnNlcnZhYmxlT2YobnVsbCk7XG4gICAgICBjb25zdCByZXNpemUgPVxuICAgICAgICB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgID8gdGhpcy5uekRvbUV2ZW50U2VydmljZS5yZWdpc3RlclJlc2l6ZUxpc3RlbmVyKCkucGlwZShcbiAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpLFxuICAgICAgICAgICAgICBmaW5hbGl6ZSgoKSA9PiB0aGlzLm56RG9tRXZlbnRTZXJ2aWNlLnVucmVnaXN0ZXJSZXNpemVMaXN0ZW5lcigpKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogb2JzZXJ2YWJsZU9mKG51bGwpO1xuICAgICAgcmV0dXJuIG1lcmdlKGRpckNoYW5nZSwgcmVzaXplKVxuICAgICAgICAucGlwZShzdGFydFdpdGgobnVsbCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLm56U2hvd1BhZ2luYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlUGFnaW5hdGlvbigpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmFsaWduSW5rQmFyVG9TZWxlY3RlZFRhYigpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcblxuICAgIGlmICh0aGlzLnJlYWxpZ25JbmtCYXIpIHtcbiAgICAgIHRoaXMucmVhbGlnbklua0Jhci51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZVRhYlNjcm9sbFBvc2l0aW9uKCk6IHZvaWQge1xuICAgIGNvbnN0IHNjcm9sbERpc3RhbmNlID0gdGhpcy5zY3JvbGxEaXN0YW5jZTtcbiAgICBpZiAodGhpcy5uelBvc2l0aW9uTW9kZSA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICBjb25zdCB0cmFuc2xhdGVYID0gdGhpcy5nZXRMYXlvdXREaXJlY3Rpb24oKSA9PT0gJ2x0cicgPyAtc2Nyb2xsRGlzdGFuY2UgOiBzY3JvbGxEaXN0YW5jZTtcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5uYXZMaXN0RWxlbWVudC5uYXRpdmVFbGVtZW50LCAndHJhbnNmb3JtJywgYHRyYW5zbGF0ZTNkKCR7dHJhbnNsYXRlWH1weCwgMCwgMClgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLm5hdkxpc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsICd0cmFuc2Zvcm0nLCBgdHJhbnNsYXRlM2QoMCwkey1zY3JvbGxEaXN0YW5jZX1weCwgMClgKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVQYWdpbmF0aW9uKCk6IHZvaWQge1xuICAgIHRoaXMuY2hlY2tQYWdpbmF0aW9uRW5hYmxlZCgpO1xuICAgIHRoaXMuY2hlY2tTY3JvbGxpbmdDb250cm9scygpO1xuICAgIHRoaXMudXBkYXRlVGFiU2Nyb2xsUG9zaXRpb24oKTtcbiAgfVxuXG4gIGNoZWNrUGFnaW5hdGlvbkVuYWJsZWQoKTogdm9pZCB7XG4gICAgY29uc3QgaXNFbmFibGVkID0gdGhpcy50YWJMaXN0U2Nyb2xsV2lkdGhIZWlnaHRQaXggPiB0aGlzLnRhYkxpc3RTY3JvbGxPZmZTZXRXaWR0aEhlaWdodDtcbiAgICBpZiAoIWlzRW5hYmxlZCkge1xuICAgICAgdGhpcy5zY3JvbGxEaXN0YW5jZSA9IDA7XG4gICAgfVxuICAgIGlmIChpc0VuYWJsZWQgIT09IHRoaXMuc2hvd1BhZ2luYXRpb25Db250cm9scykge1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICAgIHRoaXMuc2hvd1BhZ2luYXRpb25Db250cm9scyA9IGlzRW5hYmxlZDtcbiAgfVxuXG4gIHNjcm9sbFRvTGFiZWwobGFiZWxJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRMYWJlbCA9IHRoaXMubGlzdE9mTnpUYWJMYWJlbERpcmVjdGl2ZSA/IHRoaXMubGlzdE9mTnpUYWJMYWJlbERpcmVjdGl2ZS50b0FycmF5KClbbGFiZWxJbmRleF0gOiBudWxsO1xuXG4gICAgaWYgKHNlbGVjdGVkTGFiZWwpIHtcbiAgICAgIC8vIFRoZSB2aWV3IGxlbmd0aCBpcyB0aGUgdmlzaWJsZSB3aWR0aCBvZiB0aGUgdGFiIGxhYmVscy5cblxuICAgICAgbGV0IGxhYmVsQmVmb3JlUG9zOiBudW1iZXI7XG4gICAgICBsZXQgbGFiZWxBZnRlclBvczogbnVtYmVyO1xuICAgICAgaWYgKHRoaXMubnpQb3NpdGlvbk1vZGUgPT09ICdob3Jpem9udGFsJykge1xuICAgICAgICBpZiAodGhpcy5nZXRMYXlvdXREaXJlY3Rpb24oKSA9PT0gJ2x0cicpIHtcbiAgICAgICAgICBsYWJlbEJlZm9yZVBvcyA9IHNlbGVjdGVkTGFiZWwuZ2V0T2Zmc2V0TGVmdCgpO1xuICAgICAgICAgIGxhYmVsQWZ0ZXJQb3MgPSBsYWJlbEJlZm9yZVBvcyArIHNlbGVjdGVkTGFiZWwuZ2V0T2Zmc2V0V2lkdGgoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsYWJlbEFmdGVyUG9zID0gdGhpcy5uYXZMaXN0RWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoIC0gc2VsZWN0ZWRMYWJlbC5nZXRPZmZzZXRMZWZ0KCk7XG4gICAgICAgICAgbGFiZWxCZWZvcmVQb3MgPSBsYWJlbEFmdGVyUG9zIC0gc2VsZWN0ZWRMYWJlbC5nZXRPZmZzZXRXaWR0aCgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsYWJlbEJlZm9yZVBvcyA9IHNlbGVjdGVkTGFiZWwuZ2V0T2Zmc2V0VG9wKCk7XG4gICAgICAgIGxhYmVsQWZ0ZXJQb3MgPSBsYWJlbEJlZm9yZVBvcyArIHNlbGVjdGVkTGFiZWwuZ2V0T2Zmc2V0SGVpZ2h0KCk7XG4gICAgICB9XG4gICAgICBjb25zdCBiZWZvcmVWaXNpYmxlUG9zID0gdGhpcy5zY3JvbGxEaXN0YW5jZTtcbiAgICAgIGNvbnN0IGFmdGVyVmlzaWJsZVBvcyA9IHRoaXMuc2Nyb2xsRGlzdGFuY2UgKyB0aGlzLnZpZXdXaWR0aEhlaWdodFBpeDtcblxuICAgICAgaWYgKGxhYmVsQmVmb3JlUG9zIDwgYmVmb3JlVmlzaWJsZVBvcykge1xuICAgICAgICAvLyBTY3JvbGwgaGVhZGVyIHRvIG1vdmUgbGFiZWwgdG8gdGhlIGJlZm9yZSBkaXJlY3Rpb25cbiAgICAgICAgdGhpcy5zY3JvbGxEaXN0YW5jZSAtPSBiZWZvcmVWaXNpYmxlUG9zIC0gbGFiZWxCZWZvcmVQb3MgKyBFWEFHR0VSQVRFRF9PVkVSU0NST0xMO1xuICAgICAgfSBlbHNlIGlmIChsYWJlbEFmdGVyUG9zID4gYWZ0ZXJWaXNpYmxlUG9zKSB7XG4gICAgICAgIC8vIFNjcm9sbCBoZWFkZXIgdG8gbW92ZSBsYWJlbCB0byB0aGUgYWZ0ZXIgZGlyZWN0aW9uXG4gICAgICAgIHRoaXMuc2Nyb2xsRGlzdGFuY2UgKz0gbGFiZWxBZnRlclBvcyAtIGFmdGVyVmlzaWJsZVBvcyArIEVYQUdHRVJBVEVEX09WRVJTQ1JPTEw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY2hlY2tTY3JvbGxpbmdDb250cm9scygpOiB2b2lkIHtcbiAgICAvLyBDaGVjayBpZiB0aGUgcGFnaW5hdGlvbiBhcnJvd3Mgc2hvdWxkIGJlIGFjdGl2YXRlZC5cbiAgICB0aGlzLmRpc2FibGVTY3JvbGxCZWZvcmUgPSB0aGlzLnNjcm9sbERpc3RhbmNlID09PSAwO1xuICAgIHRoaXMuZGlzYWJsZVNjcm9sbEFmdGVyID0gdGhpcy5zY3JvbGxEaXN0YW5jZSA9PT0gdGhpcy5nZXRNYXhTY3JvbGxEaXN0YW5jZSgpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgd2hhdCBpcyB0aGUgbWF4aW11bSBsZW5ndGggaW4gcGl4ZWxzIHRoYXQgY2FuIGJlIHNldCBmb3IgdGhlIHNjcm9sbCBkaXN0YW5jZS4gVGhpc1xuICAgKiBpcyBlcXVhbCB0byB0aGUgZGlmZmVyZW5jZSBpbiB3aWR0aCBiZXR3ZWVuIHRoZSB0YWIgbGlzdCBjb250YWluZXIgYW5kIHRhYiBoZWFkZXIgY29udGFpbmVyLlxuICAgKlxuICAgKiBUaGlzIGlzIGFuIGV4cGVuc2l2ZSBjYWxsIHRoYXQgZm9yY2VzIGEgbGF5b3V0IHJlZmxvdyB0byBjb21wdXRlIGJveCBhbmQgc2Nyb2xsIG1ldHJpY3MgYW5kXG4gICAqIHNob3VsZCBiZSBjYWxsZWQgc3BhcmluZ2x5LlxuICAgKi9cbiAgZ2V0TWF4U2Nyb2xsRGlzdGFuY2UoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50YWJMaXN0U2Nyb