UNPKG

ng-zorro-antd

Version:

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

564 lines (562 loc) 47 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,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 */ import { LEFT_ARROW, RIGHT_ARROW } from '@angular/cdk/keycodes'; import { Platform } from '@angular/cdk/platform'; import { DOCUMENT } from '@angular/common'; import { isDevMode, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, Inject, Input, NgZone, Optional, Output, QueryList, Renderer2, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core'; import { fromEvent, Subject } from 'rxjs'; import { isTouchEvent, InputBoolean, InputNumber } from 'ng-zorro-antd/core'; import { takeUntil, throttleTime } from 'rxjs/operators'; import { NzCarouselContentDirective } from './nz-carousel-content.directive'; import { NZ_CAROUSEL_CUSTOM_STRATEGIES } from './nz-carousel-definitions'; import { NzCarouselOpacityStrategy } from './strategies/opacity-strategy'; import { NzCarouselTransformStrategy } from './strategies/transform-strategy'; export class NzCarouselComponent { /** * @param {?} elementRef * @param {?} renderer * @param {?} cdr * @param {?} ngZone * @param {?} platform * @param {?} document * @param {?} customStrategies */ constructor(elementRef, renderer, cdr, ngZone, platform, document, // tslint:disable-line:no-any customStrategies) { this.renderer = renderer; this.cdr = cdr; this.ngZone = ngZone; this.platform = platform; this.customStrategies = customStrategies; this.nzEffect = 'scrollx'; this.nzEnableSwipe = true; this.nzDots = true; this.nzAutoPlay = false; this.nzAutoPlaySpeed = 3000; this.nzTransitionSpeed = 500; this._dotPosition = 'bottom'; this.nzBeforeChange = new EventEmitter(); this.nzAfterChange = new EventEmitter(); this.activeIndex = 0; this.vertical = false; this.destroy$ = new Subject(); this.gestureRect = null; this.pointerDelta = null; this.pointerPosition = null; this.isTransiting = false; this.isDragging = false; this.pointerDown = (/** * @param {?} event * @return {?} */ (event) => { if (!this.isDragging && !this.isTransiting && this.nzEnableSwipe) { /** @type {?} */ const point = isTouchEvent(event) ? event.touches[0] || event.changedTouches[0] : event; this.isDragging = true; this.clearScheduledTransition(); this.gestureRect = this.slickListEl.getBoundingClientRect(); this.pointerPosition = { x: point.clientX, y: point.clientY }; this.document.addEventListener('mousemove', this.pointerMove); this.document.addEventListener('touchmove', this.pointerMove); this.document.addEventListener('mouseup', this.pointerUp); this.document.addEventListener('touchend', this.pointerUp); } }); this.pointerMove = (/** * @param {?} event * @return {?} */ (event) => { if (this.isDragging) { /** @type {?} */ const point = isTouchEvent(event) ? event.touches[0] || event.changedTouches[0] : event; this.pointerDelta = { x: point.clientX - (/** @type {?} */ (this.pointerPosition)).x, y: point.clientY - (/** @type {?} */ (this.pointerPosition)).y }; if (Math.abs(this.pointerDelta.x) > 5) { this.strategy.dragging(this.pointerDelta); } } }); this.pointerUp = (/** * @return {?} */ () => { if (this.isDragging && this.nzEnableSwipe) { /** @type {?} */ const delta = this.pointerDelta ? this.pointerDelta.x : 0; // Switch to another slide if delta is third of the width. if (Math.abs(delta) > (/** @type {?} */ (this.gestureRect)).width / 3) { this.goTo(delta > 0 ? this.activeIndex - 1 : this.activeIndex + 1); } else { this.goTo(this.activeIndex); } this.gestureRect = null; this.pointerDelta = null; this.isDragging = false; this.dispose(); } }); this.document = document; this.renderer.addClass(elementRef.nativeElement, 'ant-carousel'); this.el = elementRef.nativeElement; } /** * @return {?} */ get nzVertical() { return this.vertical; } /** * @param {?} value * @return {?} */ set nzVertical(value) { if (isDevMode()) { console.warn(`'nzVertical' is deprecated and will be removed in 9.0.0. Please use 'nzDotPosition' instead.`); } this.vertical = value; } /** * @param {?} value * @return {?} */ set nzDotPosition(value) { this._dotPosition = value; if (value === 'left' || value === 'right') { this.vertical = true; } else { this.vertical = false; } } /** * @return {?} */ get nzDotPosition() { return this._dotPosition; } /** * @return {?} */ ngAfterContentInit() { this.markContentActive(0); } /** * @return {?} */ ngAfterViewInit() { if (!this.platform.isBrowser) { return; } this.slickListEl = this.slickList.nativeElement; this.slickTrackEl = this.slickTrack.nativeElement; this.carouselContents.changes.pipe(takeUntil(this.destroy$)).subscribe((/** * @return {?} */ () => { this.markContentActive(0); this.syncStrategy(); })); this.ngZone.runOutsideAngular((/** * @return {?} */ () => { fromEvent(window, 'resize') .pipe(takeUntil(this.destroy$), throttleTime(16)) .subscribe((/** * @return {?} */ () => { this.syncStrategy(); })); })); this.switchStrategy(); this.markContentActive(0); this.syncStrategy(); // If embedded in an entry component, it may do initial render at a inappropriate time. // ngZone.onStable won't do this trick Promise.resolve().then((/** * @return {?} */ () => { this.syncStrategy(); })); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { const { nzEffect, nzDotPosition } = changes; if (nzEffect && !nzEffect.isFirstChange()) { this.switchStrategy(); this.markContentActive(0); this.syncStrategy(); } if (nzDotPosition && !nzDotPosition.isFirstChange()) { this.switchStrategy(); this.markContentActive(0); this.syncStrategy(); } if (!this.nzAutoPlay || !this.nzAutoPlaySpeed) { this.clearScheduledTransition(); } else { this.scheduleNextTransition(); } } /** * @return {?} */ ngOnDestroy() { this.clearScheduledTransition(); if (this.strategy) { this.strategy.dispose(); } this.dispose(); this.destroy$.next(); this.destroy$.complete(); } /** * @param {?} e * @return {?} */ onKeyDown(e) { if (e.keyCode === LEFT_ARROW) { e.preventDefault(); this.pre(); } else if (e.keyCode === RIGHT_ARROW) { this.next(); e.preventDefault(); } } /** * @return {?} */ next() { this.goTo(this.activeIndex + 1); } /** * @return {?} */ pre() { this.goTo(this.activeIndex - 1); } /** * @param {?} index * @return {?} */ goTo(index) { if (this.carouselContents && this.carouselContents.length && !this.isTransiting) { /** @type {?} */ const length = this.carouselContents.length; /** @type {?} */ const from = this.activeIndex; /** @type {?} */ const to = (index + length) % length; this.isTransiting = true; this.nzBeforeChange.emit({ from, to }); this.strategy.switch(this.activeIndex, index).subscribe((/** * @return {?} */ () => { this.scheduleNextTransition(); this.nzAfterChange.emit(index); this.isTransiting = false; })); this.markContentActive(to); this.cdr.markForCheck(); } } /** * @private * @return {?} */ switchStrategy() { if (this.strategy) { this.strategy.dispose(); } // Load custom strategies first. /** @type {?} */ const customStrategy = this.customStrategies ? this.customStrategies.find((/** * @param {?} s * @return {?} */ s => s.name === this.nzEffect)) : null; if (customStrategy) { // tslint:disable-next-line:no-any this.strategy = new ((/** @type {?} */ (customStrategy.strategy)))(this, this.cdr, this.renderer); return; } this.strategy = this.nzEffect === 'scrollx' ? new NzCarouselTransformStrategy(this, this.cdr, this.renderer) : new NzCarouselOpacityStrategy(this, this.cdr, this.renderer); } /** * @private * @return {?} */ scheduleNextTransition() { this.clearScheduledTransition(); if (this.nzAutoPlay && this.nzAutoPlaySpeed > 0 && this.platform.isBrowser) { this.transitionInProgress = setTimeout((/** * @return {?} */ () => { this.goTo(this.activeIndex + 1); }), this.nzAutoPlaySpeed); } } /** * @private * @return {?} */ clearScheduledTransition() { if (this.transitionInProgress) { clearTimeout(this.transitionInProgress); this.transitionInProgress = null; } } /** * @private * @param {?} index * @return {?} */ markContentActive(index) { this.activeIndex = index; if (this.carouselContents) { this.carouselContents.forEach((/** * @param {?} slide * @param {?} i * @return {?} */ (slide, i) => { slide.isActive = index === i; })); } this.cdr.markForCheck(); } /** * @private * @return {?} */ syncStrategy() { if (this.strategy) { this.strategy.withCarouselContents(this.carouselContents); } } /** * @private * @return {?} */ dispose() { this.document.removeEventListener('mousemove', this.pointerMove); this.document.removeEventListener('touchmove', this.pointerMove); this.document.removeEventListener('touchend', this.pointerMove); this.document.removeEventListener('mouseup', this.pointerMove); } } NzCarouselComponent.decorators = [ { type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, selector: 'nz-carousel', exportAs: 'nzCarousel', preserveWhitespaces: false, template: "<div class=\"slick-initialized slick-slider\" [class.slick-vertical]=\"nzVertical\">\n <div\n #slickList\n class=\"slick-list\"\n tabindex=\"-1\"\n (keydown)=\"onKeyDown($event)\"\n (mousedown)=\"pointerDown($event)\"\n (touchstart)=\"pointerDown($event)\"\n >\n <!-- Render carousel items. -->\n <div class=\"slick-track\" #slickTrack>\n <ng-content></ng-content>\n </div>\n </div>\n <!-- Render dots. -->\n <ul\n class=\"slick-dots\"\n *ngIf=\"nzDots\"\n [class.slick-dots-top]=\"nzDotPosition === 'top'\"\n [class.slick-dots-bottom]=\"nzDotPosition === 'bottom'\"\n [class.slick-dots-left]=\"nzDotPosition === 'left'\"\n [class.slick-dots-right]=\"nzDotPosition === 'right'\"\n >\n <li\n *ngFor=\"let content of carouselContents; let i = index\"\n [class.slick-active]=\"content.isActive\"\n (click)=\"goTo(i)\"\n >\n <ng-template [ngTemplateOutlet]=\"nzDotRender || renderDotTemplate\" [ngTemplateOutletContext]=\"{ $implicit: i }\">\n </ng-template>\n </li>\n </ul>\n</div>\n\n<ng-template #renderDotTemplate let-index>\n <button>{{ index + 1 }}</button>\n</ng-template>\n", host: { '[class.ant-carousel-vertical]': 'vertical' }, styles: [` nz-carousel { display: block; position: relative; overflow: hidden; width: 100%; height: 100%; } .slick-dots { display: block; } .slick-track { opacity: 1; } `] }] } ]; /** @nocollapse */ NzCarouselComponent.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: ChangeDetectorRef }, { type: NgZone }, { type: Platform }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: Array, decorators: [{ type: Optional }, { type: Inject, args: [NZ_CAROUSEL_CUSTOM_STRATEGIES,] }] } ]; NzCarouselComponent.propDecorators = { carouselContents: [{ type: ContentChildren, args: [NzCarouselContentDirective,] }], slickList: [{ type: ViewChild, args: ['slickList', { static: false },] }], slickTrack: [{ type: ViewChild, args: ['slickTrack', { static: false },] }], nzDotRender: [{ type: Input }], nzEffect: [{ type: Input }], nzEnableSwipe: [{ type: Input }], nzDots: [{ type: Input }], nzAutoPlay: [{ type: Input }], nzAutoPlaySpeed: [{ type: Input }], nzTransitionSpeed: [{ type: Input }], nzVertical: [{ type: Input }], nzDotPosition: [{ type: Input }], nzBeforeChange: [{ type: Output }], nzAfterChange: [{ type: Output }] }; tslib_1.__decorate([ InputBoolean(), tslib_1.__metadata("design:type", Object) ], NzCarouselComponent.prototype, "nzEnableSwipe", void 0); tslib_1.__decorate([ InputBoolean(), tslib_1.__metadata("design:type", Boolean) ], NzCarouselComponent.prototype, "nzDots", void 0); tslib_1.__decorate([ InputBoolean(), tslib_1.__metadata("design:type", Object) ], NzCarouselComponent.prototype, "nzAutoPlay", void 0); tslib_1.__decorate([ InputNumber(), tslib_1.__metadata("design:type", Object) ], NzCarouselComponent.prototype, "nzAutoPlaySpeed", void 0); tslib_1.__decorate([ InputNumber(), tslib_1.__metadata("design:type", Object) ], NzCarouselComponent.prototype, "nzTransitionSpeed", void 0); tslib_1.__decorate([ InputBoolean(), tslib_1.__metadata("design:type", Boolean), tslib_1.__metadata("design:paramtypes", [Boolean]) ], NzCarouselComponent.prototype, "nzVertical", null); if (false) { /** @type {?} */ NzCarouselComponent.prototype.carouselContents; /** @type {?} */ NzCarouselComponent.prototype.slickList; /** @type {?} */ NzCarouselComponent.prototype.slickTrack; /** @type {?} */ NzCarouselComponent.prototype.nzDotRender; /** @type {?} */ NzCarouselComponent.prototype.nzEffect; /** @type {?} */ NzCarouselComponent.prototype.nzEnableSwipe; /** @type {?} */ NzCarouselComponent.prototype.nzDots; /** @type {?} */ NzCarouselComponent.prototype.nzAutoPlay; /** @type {?} */ NzCarouselComponent.prototype.nzAutoPlaySpeed; /** @type {?} */ NzCarouselComponent.prototype.nzTransitionSpeed; /** * @type {?} * @private */ NzCarouselComponent.prototype._dotPosition; /** @type {?} */ NzCarouselComponent.prototype.nzBeforeChange; /** @type {?} */ NzCarouselComponent.prototype.nzAfterChange; /** @type {?} */ NzCarouselComponent.prototype.activeIndex; /** @type {?} */ NzCarouselComponent.prototype.el; /** @type {?} */ NzCarouselComponent.prototype.slickListEl; /** @type {?} */ NzCarouselComponent.prototype.slickTrackEl; /** @type {?} */ NzCarouselComponent.prototype.strategy; /** @type {?} */ NzCarouselComponent.prototype.vertical; /** @type {?} */ NzCarouselComponent.prototype.transitionInProgress; /** * @type {?} * @private */ NzCarouselComponent.prototype.destroy$; /** * @type {?} * @private */ NzCarouselComponent.prototype.document; /** * @type {?} * @private */ NzCarouselComponent.prototype.gestureRect; /** * @type {?} * @private */ NzCarouselComponent.prototype.pointerDelta; /** * @type {?} * @private */ NzCarouselComponent.prototype.pointerPosition; /** * @type {?} * @private */ NzCarouselComponent.prototype.isTransiting; /** * @type {?} * @private */ NzCarouselComponent.prototype.isDragging; /** @type {?} */ NzCarouselComponent.prototype.pointerDown; /** @type {?} */ NzCarouselComponent.prototype.pointerMove; /** @type {?} */ NzCarouselComponent.prototype.pointerUp; /** * @type {?} * @private */ NzCarouselComponent.prototype.renderer; /** * @type {?} * @private */ NzCarouselComponent.prototype.cdr; /** * @type {?} * @private */ NzCarouselComponent.prototype.ngZone; /** * @type {?} * @private */ NzCarouselComponent.prototype.platform; /** * @type {?} * @private */ NzCarouselComponent.prototype.customStrategies; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnotY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC9jYXJvdXNlbC8iLCJzb3VyY2VzIjpbIm56LWNhcm91c2VsLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFRQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUNMLFNBQVMsRUFHVCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFHTixRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBRVQsV0FBVyxFQUNYLFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFMUMsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDN0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM3RSxPQUFPLEVBS0wsNkJBQTZCLEVBRTlCLE1BQU0sMkJBQTJCLENBQUM7QUFFbkMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDMUUsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFnQzlFLE1BQU0sT0FBTyxtQkFBbUI7Ozs7Ozs7Ozs7SUE4RDlC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NUMsOENBQStDOztJQUMvQyxnREFBZ0Q7Ozs7O0lBNkJoRCwyQ0FBdUQ7O0lBRXZELDZDQUF3RTs7SUFDeEUsNENBQThEOztJQUU5RCwwQ0FBZ0I7O0lBQ2hCLGlDQUFnQjs7SUFDaEIsMENBQXlCOztJQUN6QiwyQ0FBMEI7O0lBQzFCLHVDQUFpQzs7SUFDakMsdUNBQWlCOztJQUNqQixtREFBb0M7Ozs7O0lBRXBDLHVDQUF1Qzs7Ozs7SUFDdkMsdUNBQTJCOzs7OztJQUMzQiwwQ0FBOEM7Ozs7O0lBQzlDLDJDQUFrRDs7Ozs7SUFDbEQsOENBQXFEOzs7OztJQUNyRCwyQ0FBNkI7Ozs7O0lBQzdCLHlDQUEyQjs7SUF5SzNCLDBDQWFFOztJQUVGLDBDQVFFOztJQUVGLHdDQWdCRTs7Ozs7SUE5TUEsdUNBQTJCOzs7OztJQUMzQixrQ0FBOEI7Ozs7O0lBQzlCLHFDQUFzQjs7Ozs7SUFDdEIsdUNBQTBCOzs7OztJQUUxQiwrQ0FBNkciLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgQWxpYmFiYS5jb20gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgTEVGVF9BUlJPVywgUklHSFRfQVJST1cgfSBmcm9tICdAYW5ndWxhci9jZGsva2V5Y29kZXMnO1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgaXNEZXZNb2RlLFxuICBBZnRlckNvbnRlbnRJbml0LFxuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgUmVuZGVyZXIyLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZyb21FdmVudCwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBpc1RvdWNoRXZlbnQsIElucHV0Qm9vbGVhbiwgSW5wdXROdW1iZXIgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsLCB0aHJvdHRsZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE56Q2Fyb3VzZWxDb250ZW50RGlyZWN0aXZlIH0gZnJvbSAnLi9uei1jYXJvdXNlbC1jb250ZW50LmRpcmVjdGl2ZSc7XG5pbXBvcnQge1xuICBGcm9tVG9JbnRlcmZhY2UsXG4gIE56Q2Fyb3VzZWxEb3RQb3NpdGlvbixcbiAgTnpDYXJvdXNlbEVmZmVjdHMsXG4gIE56Q2Fyb3VzZWxTdHJhdGVneVJlZ2lzdHJ5SXRlbSxcbiAgTlpfQ0FST1VTRUxfQ1VTVE9NX1NUUkFURUdJRVMsXG4gIFBvaW50ZXJWZWN0b3Jcbn0gZnJvbSAnLi9uei1jYXJvdXNlbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQgeyBOekNhcm91c2VsQmFzZVN0cmF0ZWd5IH0gZnJvbSAnLi9zdHJhdGVnaWVzL2Jhc2Utc3RyYXRlZ3knO1xuaW1wb3J0IHsgTnpDYXJvdXNlbE9wYWNpdHlTdHJhdGVneSB9IGZyb20gJy4vc3RyYXRlZ2llcy9vcGFjaXR5LXN0cmF0ZWd5JztcbmltcG9ydCB7IE56Q2Fyb3VzZWxUcmFuc2Zvcm1TdHJhdGVneSB9IGZyb20gJy4vc3RyYXRlZ2llcy90cmFuc2Zvcm0tc3RyYXRlZ3knO1xuXG5AQ29tcG9uZW50KHtcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHNlbGVjdG9yOiAnbnotY2Fyb3VzZWwnLFxuICBleHBvcnRBczogJ256Q2Fyb3VzZWwnLFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgdGVtcGxhdGVVcmw6ICcuL256LWNhcm91c2VsLmNvbXBvbmVudC5odG1sJyxcbiAgaG9zdDoge1xuICAgICdbY2xhc3MuYW50LWNhcm91c2VsLXZlcnRpY2FsXSc6ICd2ZXJ0aWNhbCdcbiAgfSxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgbnotY2Fyb3VzZWwge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgfVxuXG4gICAgICAuc2xpY2stZG90cyB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgfVxuXG4gICAgICAuc2xpY2stdHJhY2sge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgfVxuICAgIGBcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBOekNhcm91c2VsQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xuICBAQ29udGVudENoaWxkcmVuKE56Q2Fyb3VzZWxDb250ZW50RGlyZWN0aXZlKSBjYXJvdXNlbENvbnRlbnRzOiBRdWVyeUxpc3Q8TnpDYXJvdXNlbENvbnRlbnREaXJlY3RpdmU+O1xuXG4gIEBWaWV3Q2hpbGQoJ3NsaWNrTGlzdCcsIHsgc3RhdGljOiBmYWxzZSB9KSBzbGlja0xpc3Q6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ3NsaWNrVHJhY2snLCB7IHN0YXRpYzogZmFsc2UgfSkgc2xpY2tUcmFjazogRWxlbWVudFJlZjtcblxuICBASW5wdXQoKSBuekRvdFJlbmRlcjogVGVtcGxhdGVSZWY8eyAkaW1wbGljaXQ6IG51bWJlciB9PjtcbiAgQElucHV0KCkgbnpFZmZlY3Q6IE56Q2Fyb3VzZWxFZmZlY3RzID0gJ3Njcm9sbHgnO1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgbnpFbmFibGVTd2lwZSA9IHRydWU7XG4gIEBJbnB1dCgpIEBJbnB1dEJvb2xlYW4oKSBuekRvdHM6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgbnpBdXRvUGxheSA9IGZhbHNlO1xuICBASW5wdXQoKSBASW5wdXROdW1iZXIoKSBuekF1dG9QbGF5U3BlZWQgPSAzMDAwO1xuICBASW5wdXQoKSBASW5wdXROdW1iZXIoKSBuelRyYW5zaXRpb25TcGVlZCA9IDUwMDtcblxuICBASW5wdXQoKVxuICBASW5wdXRCb29sZWFuKClcbiAgZ2V0IG56VmVydGljYWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudmVydGljYWw7XG4gIH1cblxuICBzZXQgbnpWZXJ0aWNhbCh2YWx1ZTogYm9vbGVhbikge1xuICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgY29uc29sZS53YXJuKGAnbnpWZXJ0aWNhbCcgaXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDkuMC4wLiBQbGVhc2UgdXNlICduekRvdFBvc2l0aW9uJyBpbnN0ZWFkLmApO1xuICAgIH1cbiAgICB0aGlzLnZlcnRpY2FsID0gdmFsdWU7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgbnpEb3RQb3NpdGlvbih2YWx1ZTogTnpDYXJvdXNlbERvdFBvc2l0aW9uKSB7XG4gICAgdGhpcy5fZG90UG9zaXRpb24gPSB2YWx1ZTtcbiAgICBpZiAodmFsdWUgPT09ICdsZWZ0JyB8fCB2YWx1ZSA9PT0gJ3JpZ2h0Jykge1xuICAgICAgdGhpcy52ZXJ0aWNhbCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmVydGljYWwgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBnZXQgbnpEb3RQb3NpdGlvbigpOiBOekNhcm91c2VsRG90UG9zaXRpb24ge1xuICAgIHJldHVybiB0aGlzLl9kb3RQb3NpdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgX2RvdFBvc2l0aW9uOiBOekNhcm91c2VsRG90UG9zaXRpb24gPSAnYm90dG9tJztcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpCZWZvcmVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPEZyb21Ub0ludGVyZmFjZT4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IG56QWZ0ZXJDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICBhY3RpdmVJbmRleCA9IDA7XG4gIGVsOiBIVE1MRWxlbWVudDtcbiAgc2xpY2tMaXN0RWw6IEhUTUxFbGVtZW50O1xuICBzbGlja1RyYWNrRWw6IEhUTUxFbGVtZW50O1xuICBzdHJhdGVneTogTnpDYXJvdXNlbEJhc2VTdHJhdGVneTtcbiAgdmVydGljYWwgPSBmYWxzZTtcbiAgdHJhbnNpdGlvbkluUHJvZ3Jlc3M6IG51bWJlciB8IG51bGw7XG5cbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50O1xuICBwcml2YXRlIGdlc3R1cmVSZWN0OiBDbGllbnRSZWN0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcG9pbnRlckRlbHRhOiBQb2ludGVyVmVjdG9yIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcG9pbnRlclBvc2l0aW9uOiBQb2ludGVyVmVjdG9yIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaXNUcmFuc2l0aW5nID0gZmFsc2U7XG4gIHByaXZhdGUgaXNEcmFnZ2luZyA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIGRvY3VtZW50OiBhbnksIC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYW55XG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChOWl9DQVJPVVNFTF9DVVNUT01fU1RSQVRFR0lFUykgcHJpdmF0ZSBjdXN0b21TdHJhdGVnaWVzOiBOekNhcm91c2VsU3RyYXRlZ3lSZWdpc3RyeUl0ZW1bXVxuICApIHtcbiAgICB0aGlzLmRvY3VtZW50ID0gZG9jdW1lbnQ7XG4gICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdhbnQtY2Fyb3VzZWwnKTtcbiAgICB0aGlzLmVsID0gZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIHRoaXMubWFya0NvbnRlbnRBY3RpdmUoMCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnBsYXRmb3JtLmlzQnJvd3Nlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnNsaWNrTGlzdEVsID0gdGhpcy5zbGlja0xpc3QubmF0aXZlRWxlbWVudDtcbiAgICB0aGlzLnNsaWNrVHJhY2tFbCA9IHRoaXMuc2xpY2tUcmFjay5uYXRpdmVFbGVtZW50O1xuXG4gICAgdGhpcy5jYXJvdXNlbENvbnRlbnRzLmNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLm1hcmtDb250ZW50QWN0aXZlKDApO1xuICAgICAgdGhpcy5zeW5jU3RyYXRlZ3koKTtcbiAgICB9KTtcblxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGZyb21FdmVudCh3aW5kb3csICdyZXNpemUnKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JCksXG4gICAgICAgICAgdGhyb3R0bGVUaW1lKDE2KVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc3luY1N0cmF0ZWd5KCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zd2l0Y2hTdHJhdGVneSgpO1xuICAgIHRoaXMubWFya0NvbnRlbnRBY3RpdmUoMCk7XG4gICAgdGhpcy5zeW5jU3RyYXRlZ3koKTtcblxuICAgIC8vIElmIGVtYmVkZGVkIGluIGFuIGVudHJ5IGNvbXBvbmVudCwgaXQgbWF5IGRvIGluaXRpYWwgcmVuZGVyIGF0IGEgaW5hcHByb3ByaWF0ZSB0aW1lLlxuICAgIC8vIG5nWm9uZS5vblN0YWJsZSB3b24ndCBkbyB0aGlzIHRyaWNrXG4gICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLnN5bmNTdHJhdGVneSgpO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IHsgbnpFZmZlY3QsIG56RG90UG9zaXRpb24gfSA9IGNoYW5nZXM7XG5cbiAgICBpZiAobnpFZmZlY3QgJiYgIW56RWZmZWN0LmlzRmlyc3RDaGFuZ2UoKSkge1xuICAgICAgdGhpcy5zd2l0Y2hTdHJhdGVneSgpO1xuICAgICAgdGhpcy5tYXJrQ29udGVudEFjdGl2ZSgwKTtcbiAgICAgIHRoaXMuc3luY1N0cmF0ZWd5KCk7XG4gICAgfVxuXG4gICAgaWYgKG56RG90UG9zaXRpb24gJiYgIW56RG90UG9zaXRpb24uaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICB0aGlzLnN3aXRjaFN0cmF0ZWd5KCk7XG4gICAgICB0aGlzLm1hcmtDb250ZW50QWN0aXZlKDApO1xuICAgICAgdGhpcy5zeW5jU3RyYXRlZ3koKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubnpBdXRvUGxheSB8fCAhdGhpcy5uekF1dG9QbGF5U3BlZWQpIHtcbiAgICAgIHRoaXMuY2xlYXJTY2hlZHVsZWRUcmFuc2l0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2NoZWR1bGVOZXh0VHJhbnNpdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJTY2hlZHVsZWRUcmFuc2l0aW9uKCk7XG4gICAgaWYgKHRoaXMuc3RyYXRlZ3kpIHtcbiAgICAgIHRoaXMuc3RyYXRlZ3kuZGlzcG9zZSgpO1xuICAgIH1cbiAgICB0aGlzLmRpc3Bvc2UoKTtcblxuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIG9uS2V5RG93bihlOiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGUua2V5Q29kZSA9PT0gTEVGVF9BUlJPVykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5wcmUoKTtcbiAgICB9IGVsc2UgaWYgKGUua2V5Q29kZSA9PT0gUklHSFRfQVJST1cpIHtcbiAgICAgIHRoaXMubmV4dCgpO1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuXG4gIG5leHQoKTogdm9pZCB7XG4gICAgdGhpcy5nb1RvKHRoaXMuYWN0aXZlSW5kZXggKyAxKTtcbiAgfVxuXG4gIHByZSgpOiB2b2lkIHtcbiAgICB0aGlzLmdvVG8odGhpcy5hY3RpdmVJbmRleCAtIDEpO1xuICB9XG5cbiAgZ29UbyhpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2Fyb3VzZWxDb250ZW50cyAmJiB0aGlzLmNhcm91c2VsQ29udGVudHMubGVuZ3RoICYmICF0aGlzLmlzVHJhbnNpdGluZykge1xuICAgICAgY29uc3QgbGVuZ3RoID0gdGhpcy5jYXJvdXNlbENvbnRlbnRzLmxlbmd0aDtcbiAgICAgIGNvbnN0IGZyb20gPSB0aGlzLmFjdGl2ZUluZGV4O1xuICAgICAgY29uc3QgdG8gPSAoaW5kZXggKyBsZW5ndGgpICUgbGVuZ3RoO1xuICAgICAgdGhpcy5pc1RyYW5zaXRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5uekJlZm9yZUNoYW5nZS5lbWl0KHsgZnJvbSwgdG8gfSk7XG4gICAgICB0aGlzLnN0cmF0ZWd5LnN3aXRjaCh0aGlzLmFjdGl2ZUluZGV4LCBpbmRleCkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5zY2hlZHVsZU5leHRUcmFuc2l0aW9uKCk7XG4gICAgICAgIHRoaXMubnpBZnRlckNoYW5nZS5lbWl0KGluZGV4KTtcbiAgICAgICAgdGhpcy5pc1RyYW5zaXRpbmcgPSBmYWxzZTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5tYXJrQ29udGVudEFjdGl2ZSh0byk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN3aXRjaFN0cmF0ZWd5KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN0cmF0ZWd5KSB7XG4gICAgICB0aGlzLnN0cmF0ZWd5LmRpc3Bvc2UoKTtcbiAgICB9XG5cbiAgICAvLyBMb2FkIGN1c3RvbSBzdHJhdGVnaWVzIGZpcnN0LlxuICAgIGNvbnN0IGN1c3RvbVN0cmF0ZWd5ID0gdGhpcy5jdXN0b21TdHJhdGVnaWVzID8gdGhpcy5jdXN0b21TdHJhdGVnaWVzLmZpbmQocyA9PiBzLm5hbWUgPT09IHRoaXMubnpFZmZlY3QpIDogbnVsbDtcbiAgICBpZiAoY3VzdG9tU3RyYXRlZ3kpIHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgIHRoaXMuc3RyYXRlZ3kgPSBuZXcgKGN1c3RvbVN0cmF0ZWd5LnN0cmF0ZWd5IGFzIGFueSkodGhpcywgdGhpcy5jZHIsIHRoaXMucmVuZGVyZXIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc3RyYXRlZ3kgPVxuICAgICAgdGhpcy5uekVmZmVjdCA9PT0gJ3Njcm9sbHgnXG4gICAgICAgID8gbmV3IE56Q2Fyb3VzZWxUcmFuc2Zvcm1TdHJhdGVneSh0aGlzLCB0aGlzLmNkciwgdGhpcy5yZW5kZXJlcilcbiAgICAgICAgOiBuZXcgTnpDYXJvdXNlbE9wYWNpdHlTdHJhdGVneSh0aGlzLCB0aGlzLmNkciwgdGhpcy5yZW5kZXJlcik7XG4gIH1cblxuICBwcml2YXRlIHNjaGVkdWxlTmV4dFRyYW5zaXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhclNjaGVkdWxlZFRyYW5zaXRpb24oKTtcbiAgICBpZiAodGhpcy5uekF1dG9QbGF5ICYmIHRoaXMubnpBdXRvUGxheVNwZWVkID4gMCAmJiB0aGlzLnBsYXRmb3JtLmlzQnJvd3Nlcikge1xuICAgICAgdGhpcy50cmFuc2l0aW9uSW5Qcm9ncmVzcyA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmdvVG8odGhpcy5hY3RpdmVJbmRleCArIDEpO1xuICAgICAgfSwgdGhpcy5uekF1dG9QbGF5U3BlZWQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJTY2hlZHVsZWRUcmFuc2l0aW9uKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRyYW5zaXRpb25JblByb2dyZXNzKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy50cmFuc2l0aW9uSW5Qcm9ncmVzcyk7XG4gICAgICB0aGlzLnRyYW5zaXRpb25JblByb2dyZXNzID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1hcmtDb250ZW50QWN0aXZlKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZUluZGV4ID0gaW5kZXg7XG5cbiAgICBpZiAodGhpcy5jYXJvdXNlbENvbnRlbnRzKSB7XG4gICAgICB0aGlzLmNhcm91c2VsQ29udGVudHMuZm9yRWFjaCgoc2xpZGUsIGkpID0+IHtcbiAgICAgICAgc2xpZGUuaXNBY3RpdmUgPSBpbmRleCA9PT0gaTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcG9pbnRlckRvd24gPSAoZXZlbnQ6IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KSA9PiB7XG4gICAgaWYgKCF0aGlzLmlzRHJhZ2dpbmcgJiYgIXRoaXMuaXNUcmFuc2l0aW5nICYmIHRoaXMubnpFbmFibGVTd2lwZSkge1xuICAgICAgY29uc3QgcG9pbnQgPSBpc1RvdWNoRXZlbnQoZXZlbnQpID8gZXZlbnQudG91Y2hlc1swXSB8fCBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSA6IGV2ZW50O1xuICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuY2xlYXJTY2hlZHVsZWRUcmFuc2l0aW9uKCk7XG4gICAgICB0aGlzLmdlc3R1cmVSZWN0ID0gdGhpcy5zbGlja0xpc3RFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHRoaXMucG9pbnRlclBvc2l0aW9uID0geyB4OiBwb2ludC5jbGllbnRYLCB5OiBwb2ludC5jbGllbnRZIH07XG5cbiAgICAgIHRoaXMuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5wb2ludGVyTW92ZSk7XG4gICAgICB0aGlzLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMucG9pbnRlck1vdmUpO1xuICAgICAgdGhpcy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5wb2ludGVyVXApO1xuICAgICAgdGhpcy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRoaXMucG9pbnRlclVwKTtcbiAgICB9XG4gIH07XG5cbiAgcG9pbnRlck1vdmUgPSAoZXZlbnQ6IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KSA9PiB7XG4gICAgaWYgKHRoaXMuaXNEcmFnZ2luZykge1xuICAgICAgY29uc3QgcG9pbnQgPSBpc1RvdWNoRXZlbnQoZXZlbnQpID8gZXZlbnQudG91Y2hlc1swXSB8fCBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSA6IGV2ZW50O1xuICAgICAgdGhpcy5wb2ludGVyRGVsdGEgPSB7IHg6IHBvaW50LmNsaWVudFggLSB0aGlzLnBvaW50ZXJQb3NpdGlvbiEueCwgeTogcG9pbnQuY2xpZW50WSAtIHRoaXMucG9pbnRlclBvc2l0aW9uIS55IH07XG4gICAgICBpZiAoTWF0aC5hYnModGhpcy5wb2ludGVyRGVsdGEueCkgPiA1KSB7XG4gICAgICAgIHRoaXMuc3RyYXRlZ3kuZHJhZ2dpbmcodGhpcy5wb2ludGVyRGVsdGEpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwb2ludGVyVXAgPSAoKSA9PiB7XG4gICAgaWYgKHRoaXMuaXNEcmFnZ2luZyAmJiB0aGlzLm56RW5hYmxlU3dpcGUpIHtcbiAgICAgIGNvbnN0IGRlbHRhID0gdGhpcy5wb2ludGVyRGVsdGEgPyB0aGlzLnBvaW50ZXJEZWx0YS54IDogMDtcblxuICAgICAgLy8gU3dpdGNoIHRvIGFub3RoZXIgc2xpZGUgaWYgZGVsdGEgaXMgdGhpcmQgb2YgdGhlIHdpZHRoLlxuICAgICAgaWYgKE1hdGguYWJzKGRlbHRhKSA+IHRoaXMuZ2VzdHVyZVJlY3QhLndpZHRoIC8gMykge1xuICAgICAgICB0aGlzLmdvVG8oZGVsdGEgPiAwID8gdGhpcy5hY3RpdmVJbmRleCAtIDEgOiB0aGlzLmFjdGl2ZUluZGV4ICsgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmdvVG8odGhpcy5hY3RpdmVJbmRleCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZ2VzdHVyZVJlY3QgPSBudWxsO1xuICAgICAgdGhpcy5wb2ludGVyRGVsdGEgPSBudWxsO1xuICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmRpc3Bvc2UoKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzeW5jU3RyYXRlZ3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RyYXRlZ3kpIHtcbiAgICAgIHRoaXMuc3RyYXRlZ3kud2l0aENhcm91c2VsQ29udGVudHModGhpcy5jYXJvdXNlbENvbnRlbnRzKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLnBvaW50ZXJNb3ZlKTtcbiAgICB0aGlzLmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMucG9pbnRlck1vdmUpO1xuICAgIHRoaXMuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLnBvaW50ZXJNb3ZlKTtcbiAgICB0aGlzLmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLnBvaW50ZXJNb3ZlKTtcbiAgfVxufVxuIl19