ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
433 lines (431 loc) • 48.7 kB
JavaScript
import { __decorate } from "tslib";
import { LEFT_ARROW, RIGHT_ARROW } from '@angular/cdk/keycodes';
import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Inject, Input, Optional, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { fromEvent, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { WithConfig } from 'ng-zorro-antd/core/config';
import { InputBoolean, InputNumber } from 'ng-zorro-antd/core/util';
import { NzCarouselContentDirective } from './carousel-content.directive';
import { NzCarouselOpacityStrategy } from './strategies/opacity-strategy';
import { NzCarouselTransformStrategy } from './strategies/transform-strategy';
import { NZ_CAROUSEL_CUSTOM_STRATEGIES } from './typings';
import * as i0 from "@angular/core";
import * as i1 from "ng-zorro-antd/core/config";
import * as i2 from "@angular/cdk/platform";
import * as i3 from "ng-zorro-antd/core/services";
import * as i4 from "@angular/cdk/bidi";
import * as i5 from "@angular/common";
const NZ_CONFIG_MODULE_NAME = 'carousel';
export class NzCarouselComponent {
set nzDotPosition(value) {
this._dotPosition = value;
if (value === 'left' || value === 'right') {
this.vertical = true;
}
else {
this.vertical = false;
}
}
get nzDotPosition() {
return this._dotPosition;
}
constructor(elementRef, nzConfigService, ngZone, renderer, cdr, platform, resizeService, nzDragService, directionality, customStrategies) {
this.nzConfigService = nzConfigService;
this.ngZone = ngZone;
this.renderer = renderer;
this.cdr = cdr;
this.platform = platform;
this.resizeService = resizeService;
this.nzDragService = nzDragService;
this.directionality = directionality;
this.customStrategies = customStrategies;
this._nzModuleName = NZ_CONFIG_MODULE_NAME;
this.nzEffect = 'scrollx';
this.nzEnableSwipe = true;
this.nzDots = true;
this.nzAutoPlay = false;
this.nzAutoPlaySpeed = 3000;
this.nzTransitionSpeed = 500;
this.nzLoop = true;
/**
* this property is passed directly to an NzCarouselBaseStrategy
*/
this.nzStrategyOptions = undefined;
this._dotPosition = 'bottom';
this.nzBeforeChange = new EventEmitter();
this.nzAfterChange = new EventEmitter();
this.activeIndex = 0;
this.vertical = false;
this.transitionInProgress = null;
this.dir = 'ltr';
this.destroy$ = new Subject();
this.gestureRect = null;
this.pointerDelta = null;
this.isTransiting = false;
this.isDragging = false;
this.onLiClick = (index) => {
if (this.dir === 'rtl') {
this.goTo(this.carouselContents.length - 1 - index);
}
else {
this.goTo(index);
}
};
/**
* Drag carousel.
*/
this.pointerDown = (event) => {
if (!this.isDragging && !this.isTransiting && this.nzEnableSwipe) {
this.clearScheduledTransition();
this.gestureRect = this.slickListEl.getBoundingClientRect();
this.nzDragService.requestDraggingSequence(event).subscribe(delta => {
this.pointerDelta = delta;
this.isDragging = true;
this.strategy?.dragging(this.pointerDelta);
}, () => { }, () => {
if (this.nzEnableSwipe && this.isDragging) {
const xDelta = this.pointerDelta ? this.pointerDelta.x : 0;
// Switch to another slide if delta is bigger than third of the width.
if (Math.abs(xDelta) > this.gestureRect.width / 3 &&
(this.nzLoop ||
(xDelta <= 0 && this.activeIndex + 1 < this.carouselContents.length) ||
(xDelta > 0 && this.activeIndex > 0))) {
this.goTo(xDelta > 0 ? this.activeIndex - 1 : this.activeIndex + 1);
}
else {
this.goTo(this.activeIndex);
}
this.gestureRect = null;
this.pointerDelta = null;
}
this.isDragging = false;
});
}
};
this.nzDotPosition = 'bottom';
this.el = elementRef.nativeElement;
}
ngOnInit() {
this.slickListEl = this.slickList.nativeElement;
this.slickTrackEl = this.slickTrack.nativeElement;
this.dir = this.directionality.value;
this.directionality.change.pipe(takeUntil(this.destroy$)).subscribe((direction) => {
this.dir = direction;
this.markContentActive(this.activeIndex);
this.cdr.detectChanges();
});
this.ngZone.runOutsideAngular(() => {
fromEvent(this.slickListEl, 'keydown')
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
const { keyCode } = event;
if (keyCode !== LEFT_ARROW && keyCode !== RIGHT_ARROW) {
return;
}
event.preventDefault();
this.ngZone.run(() => {
if (keyCode === LEFT_ARROW) {
this.pre();
}
else {
this.next();
}
this.cdr.markForCheck();
});
});
});
}
ngAfterContentInit() {
this.markContentActive(0);
}
ngAfterViewInit() {
this.carouselContents.changes.subscribe(() => {
this.markContentActive(0);
this.layout();
});
this.resizeService
.subscribe()
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
this.layout();
});
this.switchStrategy();
this.markContentActive(0);
this.layout();
// If embedded in an entry component, it may do initial render at an inappropriate time.
// ngZone.onStable won't do this trick
// TODO: need to change this.
Promise.resolve().then(() => {
this.layout();
});
}
ngOnChanges(changes) {
const { nzEffect, nzDotPosition } = changes;
if (nzEffect && !nzEffect.isFirstChange()) {
this.switchStrategy();
this.markContentActive(0);
this.layout();
}
if (nzDotPosition && !nzDotPosition.isFirstChange()) {
this.switchStrategy();
this.markContentActive(0);
this.layout();
}
if (!this.nzAutoPlay || !this.nzAutoPlaySpeed) {
this.clearScheduledTransition();
}
else {
this.scheduleNextTransition();
}
}
ngOnDestroy() {
this.clearScheduledTransition();
if (this.strategy) {
this.strategy.dispose();
}
this.destroy$.next();
this.destroy$.complete();
}
next() {
this.goTo(this.activeIndex + 1);
}
pre() {
this.goTo(this.activeIndex - 1);
}
goTo(index) {
if (this.carouselContents &&
this.carouselContents.length &&
!this.isTransiting &&
(this.nzLoop || (index >= 0 && index < this.carouselContents.length))) {
const length = this.carouselContents.length;
const from = this.activeIndex;
const to = (index + length) % length;
this.isTransiting = true;
this.nzBeforeChange.emit({ from, to });
this.strategy.switch(this.activeIndex, index).subscribe(() => {
this.scheduleNextTransition();
this.nzAfterChange.emit(to);
this.isTransiting = false;
});
this.markContentActive(to);
this.cdr.markForCheck();
}
}
switchStrategy() {
if (this.strategy) {
this.strategy.dispose();
}
// Load custom strategies first.
const customStrategy = this.customStrategies ? this.customStrategies.find(s => s.name === this.nzEffect) : null;
if (customStrategy) {
this.strategy = new customStrategy.strategy(this, this.cdr, this.renderer, this.platform);
return;
}
this.strategy =
this.nzEffect === 'scrollx'
? new NzCarouselTransformStrategy(this, this.cdr, this.renderer, this.platform)
: new NzCarouselOpacityStrategy(this, this.cdr, this.renderer, this.platform);
}
scheduleNextTransition() {
this.clearScheduledTransition();
if (this.nzAutoPlay && this.nzAutoPlaySpeed > 0 && this.platform.isBrowser) {
this.transitionInProgress = setTimeout(() => {
this.goTo(this.activeIndex + 1);
}, this.nzAutoPlaySpeed);
}
}
clearScheduledTransition() {
if (this.transitionInProgress) {
clearTimeout(this.transitionInProgress);
this.transitionInProgress = null;
}
}
markContentActive(index) {
this.activeIndex = index;
if (this.carouselContents) {
this.carouselContents.forEach((slide, i) => {
if (this.dir === 'rtl') {
slide.isActive = index === this.carouselContents.length - 1 - i;
}
else {
slide.isActive = index === i;
}
});
}
this.cdr.markForCheck();
}
layout() {
if (this.strategy) {
this.strategy.withCarouselContents(this.carouselContents);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NzCarouselComponent, deps: [{ token: i0.ElementRef }, { token: i1.NzConfigService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i2.Platform }, { token: i3.NzResizeService }, { token: i3.NzDragService }, { token: i4.Directionality, optional: true }, { token: NZ_CAROUSEL_CUSTOM_STRATEGIES, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.3", type: NzCarouselComponent, selector: "nz-carousel", inputs: { nzDotRender: "nzDotRender", nzEffect: "nzEffect", nzEnableSwipe: "nzEnableSwipe", nzDots: "nzDots", nzAutoPlay: "nzAutoPlay", nzAutoPlaySpeed: "nzAutoPlaySpeed", nzTransitionSpeed: "nzTransitionSpeed", nzLoop: "nzLoop", nzStrategyOptions: "nzStrategyOptions", nzDotPosition: "nzDotPosition" }, outputs: { nzBeforeChange: "nzBeforeChange", nzAfterChange: "nzAfterChange" }, host: { properties: { "class.ant-carousel-vertical": "vertical", "class.ant-carousel-rtl": "dir ==='rtl'" }, classAttribute: "ant-carousel" }, queries: [{ propertyName: "carouselContents", predicate: NzCarouselContentDirective }], viewQueries: [{ propertyName: "slickList", first: true, predicate: ["slickList"], descendants: true, static: true }, { propertyName: "slickTrack", first: true, predicate: ["slickTrack"], descendants: true, static: true }], exportAs: ["nzCarousel"], usesOnChanges: true, ngImport: i0, template: `
<div
class="slick-initialized slick-slider"
[class.slick-vertical]="nzDotPosition === 'left' || nzDotPosition === 'right'"
>
<div
#slickList
class="slick-list"
tabindex="-1"
(mousedown)="pointerDown($event)"
(touchstart)="pointerDown($event)"
>
<!-- Render carousel items. -->
<div class="slick-track" #slickTrack>
<ng-content></ng-content>
</div>
</div>
<!-- Render dots. -->
<ul
class="slick-dots"
*ngIf="nzDots"
[class.slick-dots-top]="nzDotPosition === 'top'"
[class.slick-dots-bottom]="nzDotPosition === 'bottom'"
[class.slick-dots-left]="nzDotPosition === 'left'"
[class.slick-dots-right]="nzDotPosition === 'right'"
>
<li
*ngFor="let content of carouselContents; let i = index"
[class.slick-active]="i === activeIndex"
(click)="onLiClick(i)"
>
<ng-template
[ngTemplateOutlet]="nzDotRender || renderDotTemplate"
[ngTemplateOutletContext]="{ $implicit: i }"
></ng-template>
</li>
</ul>
</div>
<ng-template #renderDotTemplate let-index>
<button>{{ index + 1 }}</button>
</ng-template>
`, isInline: true, dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
__decorate([
WithConfig()
], NzCarouselComponent.prototype, "nzEffect", void 0);
__decorate([
WithConfig(),
InputBoolean()
], NzCarouselComponent.prototype, "nzEnableSwipe", void 0);
__decorate([
WithConfig(),
InputBoolean()
], NzCarouselComponent.prototype, "nzDots", void 0);
__decorate([
WithConfig(),
InputBoolean()
], NzCarouselComponent.prototype, "nzAutoPlay", void 0);
__decorate([
WithConfig(),
InputNumber()
], NzCarouselComponent.prototype, "nzAutoPlaySpeed", void 0);
__decorate([
InputNumber()
], NzCarouselComponent.prototype, "nzTransitionSpeed", void 0);
__decorate([
WithConfig()
], NzCarouselComponent.prototype, "nzLoop", void 0);
__decorate([
WithConfig()
], NzCarouselComponent.prototype, "nzDotPosition", null);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: 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]="nzDotPosition === 'left' || nzDotPosition === 'right'"
>
<div
#slickList
class="slick-list"
tabindex="-1"
(mousedown)="pointerDown($event)"
(touchstart)="pointerDown($event)"
>
<!-- Render carousel items. -->
<div class="slick-track" #slickTrack>
<ng-content></ng-content>
</div>
</div>
<!-- Render dots. -->
<ul
class="slick-dots"
*ngIf="nzDots"
[class.slick-dots-top]="nzDotPosition === 'top'"
[class.slick-dots-bottom]="nzDotPosition === 'bottom'"
[class.slick-dots-left]="nzDotPosition === 'left'"
[class.slick-dots-right]="nzDotPosition === 'right'"
>
<li
*ngFor="let content of carouselContents; let i = index"
[class.slick-active]="i === activeIndex"
(click)="onLiClick(i)"
>
<ng-template
[ngTemplateOutlet]="nzDotRender || renderDotTemplate"
[ngTemplateOutletContext]="{ $implicit: i }"
></ng-template>
</li>
</ul>
</div>
<ng-template #renderDotTemplate let-index>
<button>{{ index + 1 }}</button>
</ng-template>
`,
host: {
class: 'ant-carousel',
'[class.ant-carousel-vertical]': 'vertical',
'[class.ant-carousel-rtl]': `dir ==='rtl'`
}
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.NzConfigService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i2.Platform }, { type: i3.NzResizeService }, { type: i3.NzDragService }, { type: i4.Directionality, decorators: [{
type: Optional
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [NZ_CAROUSEL_CUSTOM_STRATEGIES]
}] }], propDecorators: { carouselContents: [{
type: ContentChildren,
args: [NzCarouselContentDirective]
}], slickList: [{
type: ViewChild,
args: ['slickList', { static: true }]
}], slickTrack: [{
type: ViewChild,
args: ['slickTrack', { static: true }]
}], nzDotRender: [{
type: Input
}], nzEffect: [{
type: Input
}], nzEnableSwipe: [{
type: Input
}], nzDots: [{
type: Input
}], nzAutoPlay: [{
type: Input
}], nzAutoPlaySpeed: [{
type: Input
}], nzTransitionSpeed: [{
type: Input
}], nzLoop: [{
type: Input
}], nzStrategyOptions: [{
type: Input
}], nzDotPosition: [{
type: Input
}], nzBeforeChange: [{
type: Output
}], nzAfterChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy9jYXJvdXNlbC9jYXJvdXNlbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQU1BLE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFaEUsT0FBTyxFQUdMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsZUFBZSxFQUVmLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUtMLFFBQVEsRUFDUixNQUFNLEVBS04sU0FBUyxFQUNULGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0MsT0FBTyxFQUFnQyxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUdyRixPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTFFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzFFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzlFLE9BQU8sRUFLTCw2QkFBNkIsRUFFOUIsTUFBTSxXQUFXLENBQUM7Ozs7Ozs7QUFFbkIsTUFBTSxxQkFBcUIsR0FBZ0IsVUFBVSxDQUFDO0FBeUR0RCxNQUFNLE9BQU8sbUJBQW1CO0lBOEI5QixJQUFJLGFBQWEsQ0FBQyxLQUE0QjtRQUM1QyxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLEtBQUssS0FBSyxNQUFNLElBQUksS0FBSyxLQUFLLE9BQU8sRUFBRTtZQUN6QyxJQUFJLENB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QkFBNUIsS0FBSztnQkFLRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBS0YsYUFBYTtzQkFIaEIsS0FBSztnQkFrQmEsY0FBYztzQkFBaEMsTUFBTTtnQkFDWSxhQUFhO3NCQUEvQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgRGlyZWN0aW9uLCBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7IExFRlRfQVJST1csIFJJR0hUX0FSUk9XIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BsYXRmb3JtJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFJlbmRlcmVyMixcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTnpDb25maWdLZXksIE56Q29uZmlnU2VydmljZSwgV2l0aENvbmZpZyB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9jb25maWcnO1xuaW1wb3J0IHsgTnpEcmFnU2VydmljZSwgTnpSZXNpemVTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3NlcnZpY2VzJztcbmltcG9ydCB7IEJvb2xlYW5JbnB1dCwgTnVtYmVySW5wdXQsIE56U2FmZUFueSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBJbnB1dEJvb2xlYW4sIElucHV0TnVtYmVyIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuXG5pbXBvcnQgeyBOekNhcm91c2VsQ29udGVudERpcmVjdGl2ZSB9IGZyb20gJy4vY2Fyb3VzZWwtY29udGVudC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTnpDYXJvdXNlbEJhc2VTdHJhdGVneSB9IGZyb20gJy4vc3RyYXRlZ2llcy9iYXNlLXN0cmF0ZWd5JztcbmltcG9ydCB7IE56Q2Fyb3VzZWxPcGFjaXR5U3RyYXRlZ3kgfSBmcm9tICcuL3N0cmF0ZWdpZXMvb3BhY2l0eS1zdHJhdGVneSc7XG5pbXBvcnQgeyBOekNhcm91c2VsVHJhbnNmb3JtU3RyYXRlZ3kgfSBmcm9tICcuL3N0cmF0ZWdpZXMvdHJhbnNmb3JtLXN0cmF0ZWd5JztcbmltcG9ydCB7XG4gIEZyb21Ub0ludGVyZmFjZSxcbiAgTnpDYXJvdXNlbERvdFBvc2l0aW9uLFxuICBOekNhcm91c2VsRWZmZWN0cyxcbiAgTnpDYXJvdXNlbFN0cmF0ZWd5UmVnaXN0cnlJdGVtLFxuICBOWl9DQVJPVVNFTF9DVVNUT01fU1RSQVRFR0lFUyxcbiAgUG9pbnRlclZlY3RvclxufSBmcm9tICcuL3R5cGluZ3MnO1xuXG5jb25zdCBOWl9DT05GSUdfTU9EVUxFX05BTUU6IE56Q29uZmlnS2V5ID0gJ2Nhcm91c2VsJztcblxuQENvbXBvbmVudCh7XG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBzZWxlY3RvcjogJ256LWNhcm91c2VsJyxcbiAgZXhwb3J0QXM6ICduekNhcm91c2VsJyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJzbGljay1pbml0aWFsaXplZCBzbGljay1zbGlkZXJcIlxuICAgICAgW2NsYXNzLnNsaWNrLXZlcnRpY2FsXT1cIm56RG90UG9zaXRpb24gPT09ICdsZWZ0JyB8fCBuekRvdFBvc2l0aW9uID09PSAncmlnaHQnXCJcbiAgICA+XG4gICAgICA8ZGl2XG4gICAgICAgICNzbGlja0xpc3RcbiAgICAgICAgY2xhc3M9XCJzbGljay1saXN0XCJcbiAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICAgIChtb3VzZWRvd24pPVwicG9pbnRlckRvd24oJGV2ZW50KVwiXG4gICAgICAgICh0b3VjaHN0YXJ0KT1cInBvaW50ZXJEb3duKCRldmVudClcIlxuICAgICAgPlxuICAgICAgICA8IS0tIFJlbmRlciBjYXJvdXNlbCBpdGVtcy4gLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzbGljay10cmFja1wiICNzbGlja1RyYWNrPlxuICAgICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDwhLS0gUmVuZGVyIGRvdHMuIC0tPlxuICAgICAgPHVsXG4gICAgICAgIGNsYXNzPVwic2xpY2stZG90c1wiXG4gICAgICAgICpuZ0lmPVwibnpEb3RzXCJcbiAgICAgICAgW2NsYXNzLnNsaWNrLWRvdHMtdG9wXT1cIm56RG90UG9zaXRpb24gPT09ICd0b3AnXCJcbiAgICAgICAgW2NsYXNzLnNsaWNrLWRvdHMtYm90dG9tXT1cIm56RG90UG9zaXRpb24gPT09ICdib3R0b20nXCJcbiAgICAgICAgW2NsYXNzLnNsaWNrLWRvdHMtbGVmdF09XCJuekRvdFBvc2l0aW9uID09PSAnbGVmdCdcIlxuICAgICAgICBbY2xhc3Muc2xpY2stZG90cy1yaWdodF09XCJuekRvdFBvc2l0aW9uID09PSAncmlnaHQnXCJcbiAgICAgID5cbiAgICAgICAgPGxpXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGNvbnRlbnQgb2YgY2Fyb3VzZWxDb250ZW50czsgbGV0IGkgPSBpbmRleFwiXG4gICAgICAgICAgW2NsYXNzLnNsaWNrLWFjdGl2ZV09XCJpID09PSBhY3RpdmVJbmRleFwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uTGlDbGljayhpKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIm56RG90UmVuZGVyIHx8IHJlbmRlckRvdFRlbXBsYXRlXCJcbiAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogaSB9XCJcbiAgICAgICAgICA+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvdWw+XG4gICAgPC9kaXY+XG5cbiAgICA8bmctdGVtcGxhdGUgI3JlbmRlckRvdFRlbXBsYXRlIGxldC1pbmRleD5cbiAgICAgIDxidXR0b24+e3sgaW5kZXggKyAxIH19PC9idXR0b24+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgYCxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnYW50LWNhcm91c2VsJyxcbiAgICAnW2NsYXNzLmFudC1jYXJvdXNlbC12ZXJ0aWNhbF0nOiAndmVydGljYWwnLFxuICAgICdbY2xhc3MuYW50LWNhcm91c2VsLXJ0bF0nOiBgZGlyID09PSdydGwnYFxuICB9XG59KVxuZXhwb3J0IGNsYXNzIE56Q2Fyb3VzZWxDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcywgT25Jbml0IHtcbiAgcmVhZG9ubHkgX256TW9kdWxlTmFtZTogTnpDb25maWdLZXkgPSBOWl9DT05GSUdfTU9EVUxFX05BTUU7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uekVuYWJsZVN3aXBlOiBCb29sZWFuSW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uekRvdHM6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256QXV0b1BsYXk6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256QXV0b1BsYXlTcGVlZDogTnVtYmVySW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uelRyYW5zaXRpb25TcGVlZDogTnVtYmVySW5wdXQ7XG5cbiAgQENvbnRlbnRDaGlsZHJlbihOekNhcm91c2VsQ29udGVudERpcmVjdGl2ZSkgY2Fyb3VzZWxDb250ZW50cyE6IFF1ZXJ5TGlzdDxOekNhcm91c2VsQ29udGVudERpcmVjdGl2ZT47XG5cbiAgQFZpZXdDaGlsZCgnc2xpY2tMaXN0JywgeyBzdGF0aWM6IHRydWUgfSkgc2xpY2tMaXN0ITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ3NsaWNrVHJhY2snLCB7IHN0YXRpYzogdHJ1ZSB9KSBzbGlja1RyYWNrITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgQElucHV0KCkgbnpEb3RSZW5kZXI/OiBUZW1wbGF0ZVJlZjx7ICRpbXBsaWNpdDogbnVtYmVyIH0+O1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIG56RWZmZWN0OiBOekNhcm91c2VsRWZmZWN0cyA9ICdzY3JvbGx4JztcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBASW5wdXRCb29sZWFuKCkgbnpFbmFibGVTd2lwZTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKCkgQElucHV0Qm9vbGVhbigpIG56RG90czogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKCkgQElucHV0Qm9vbGVhbigpIG56QXV0b1BsYXk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBASW5wdXROdW1iZXIoKSBuekF1dG9QbGF5U3BlZWQ6IG51bWJlciA9IDMwMDA7XG4gIEBJbnB1dCgpIEBJbnB1dE51bWJlcigpIG56VHJhbnNpdGlvblNwZWVkID0gNTAwO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIG56TG9vcDogYm9vbGVhbiA9IHRydWU7XG5cbiAgLyoqXG4gICAqIHRoaXMgcHJvcGVydHkgaXMgcGFzc2VkIGRpcmVjdGx5IHRvIGFuIE56Q2Fyb3VzZWxCYXNlU3RyYXRlZ3lcbiAgICovXG4gIEBJbnB1dCgpIG56U3RyYXRlZ3lPcHRpb25zOiBOelNhZmVBbnkgPSB1bmRlZmluZWQ7XG5cbiAgQElucHV0KClcbiAgLy8gQHRzLWlnbm9yZVxuICBAV2l0aENvbmZpZygpXG4gIHNldCBuekRvdFBvc2l0aW9uKHZhbHVlOiBOekNhcm91c2VsRG90UG9zaXRpb24pIHtcbiAgICB0aGlzLl9kb3RQb3NpdGlvbiA9IHZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gJ2xlZnQnIHx8IHZhbHVlID09PSAncmlnaHQnKSB7XG4gICAgICB0aGlzLnZlcnRpY2FsID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy52ZXJ0aWNhbCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGdldCBuekRvdFBvc2l0aW9uKCk6IE56Q2Fyb3VzZWxEb3RQb3NpdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuX2RvdFBvc2l0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBfZG90UG9zaXRpb246IE56Q2Fyb3VzZWxEb3RQb3NpdGlvbiA9ICdib3R0b20nO1xuXG4gIEBPdXRwdXQoKSByZWFkb25seSBuekJlZm9yZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8RnJvbVRvSW50ZXJmYWNlPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpBZnRlckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gIGFjdGl2ZUluZGV4ID0gMDtcbiAgZWw6IEhUTUxFbGVtZW50O1xuICBzbGlja0xpc3RFbCE6IEhUTUxFbGVtZW50O1xuICBzbGlja1RyYWNrRWwhOiBIVE1MRWxlbWVudDtcbiAgc3RyYXRlZ3k/OiBOekNhcm91c2VsQmFzZVN0cmF0ZWd5O1xuICB2ZXJ0aWNhbCA9IGZhbHNlO1xuICB0cmFuc2l0aW9uSW5Qcm9ncmVzczogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGRpcjogRGlyZWN0aW9uID0gJ2x0cic7XG5cbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgZ2VzdHVyZVJlY3Q6IENsaWVudFJlY3QgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBwb2ludGVyRGVsdGE6IFBvaW50ZXJWZWN0b3IgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBpc1RyYW5zaXRpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBpc0RyYWdnaW5nID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwdWJsaWMgcmVhZG9ubHkgbnpDb25maWdTZXJ2aWNlOiBOekNvbmZpZ1NlcnZpY2UsXG4gICAgcHVibGljIHJlYWRvbmx5IG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwbGF0Zm9ybTogUGxhdGZvcm0sXG4gICAgcHJpdmF0ZSByZWFkb25seSByZXNpemVTZXJ2aWNlOiBOelJlc2l6ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBuekRyYWdTZXJ2aWNlOiBOekRyYWdTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZGlyZWN0aW9uYWxpdHk6IERpcmVjdGlvbmFsaXR5LFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTlpfQ0FST1VTRUxfQ1VTVE9NX1NUUkFURUdJRVMpIHByaXZhdGUgY3VzdG9tU3RyYXRlZ2llczogTnpDYXJvdXNlbFN0cmF0ZWd5UmVnaXN0cnlJdGVtW11cbiAgKSB7XG4gICAgdGhpcy5uekRvdFBvc2l0aW9uID0gJ2JvdHRvbSc7XG4gICAgdGhpcy5lbCA9IGVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgfVxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnNsaWNrTGlzdEVsID0gdGhpcy5zbGlja0xpc3QhLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5zbGlja1RyYWNrRWwgPSB0aGlzLnNsaWNrVHJhY2shLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICB0aGlzLmRpciA9IHRoaXMuZGlyZWN0aW9uYWxpdHkudmFsdWU7XG5cbiAgICB0aGlzLmRpcmVjdGlvbmFsaXR5LmNoYW5nZS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChkaXJlY3Rpb246IERpcmVjdGlvbikgPT4ge1xuICAgICAgdGhpcy5kaXIgPSBkaXJlY3Rpb247XG4gICAgICB0aGlzLm1hcmtDb250ZW50QWN0aXZlKHRoaXMuYWN0aXZlSW5kZXgpO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KHRoaXMuc2xpY2tMaXN0RWwsICdrZXlkb3duJylcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKGV2ZW50ID0+IHtcbiAgICAgICAgICBjb25zdCB7IGtleUNvZGUgfSA9IGV2ZW50O1xuXG4gICAgICAgICAgaWYgKGtleUNvZGUgIT09IExFRlRfQVJST1cgJiYga2V5Q29kZSAhPT0gUklHSFRfQVJST1cpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgIGlmIChrZXlDb2RlID09PSBMRUZUX0FSUk9XKSB7XG4gICAgICAgICAgICAgIHRoaXMucHJlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLm5leHQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLm1hcmtDb250ZW50QWN0aXZlKDApO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuY2Fyb3VzZWxDb250ZW50cy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLm1hcmtDb250ZW50QWN0aXZlKDApO1xuICAgICAgdGhpcy5sYXlvdXQoKTtcbiAgICB9KTtcblxuICAgIHRoaXMucmVzaXplU2VydmljZVxuICAgICAgLnN1YnNjcmliZSgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5sYXlvdXQoKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5zd2l0Y2hTdHJhdGVneSgpO1xuICAgIHRoaXMubWFya0NvbnRlbnRBY3RpdmUoMCk7XG4gICAgdGhpcy5sYXlvdXQoKTtcblxuICAgIC8vIElmIGVtYmVkZGVkIGluIGFuIGVudHJ5IGNvbXBvbmVudCwgaXQgbWF5IGRvIGluaXRpYWwgcmVuZGVyIGF0IGFuIGluYXBwcm9wcmlhdGUgdGltZS5cbiAgICAvLyBuZ1pvbmUub25TdGFibGUgd29uJ3QgZG8gdGhpcyB0cmlja1xuICAgIC8vIFRPRE86IG5lZWQgdG8gY2hhbmdlIHRoaXMuXG4gICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLmxheW91dCgpO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IHsgbnpFZmZlY3QsIG56RG90UG9zaXRpb24gfSA9IGNoYW5nZXM7XG5cbiAgICBpZiAobnpFZmZlY3QgJiYgIW56RWZmZWN0LmlzRmlyc3RDaGFuZ2UoKSkge1xuICAgICAgdGhpcy5zd2l0Y2hTdHJhdGVneSgpO1xuICAgICAgdGhpcy5tYXJrQ29udGVudEFjdGl2ZSgwKTtcbiAgICAgIHRoaXMubGF5b3V0KCk7XG4gICAgfVxuXG4gICAgaWYgKG56RG90UG9zaXRpb24gJiYgIW56RG90UG9zaXRpb24uaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICB0aGlzLnN3aXRjaFN0cmF0ZWd5KCk7XG4gICAgICB0aGlzLm1hcmtDb250ZW50QWN0aXZlKDApO1xuICAgICAgdGhpcy5sYXlvdXQoKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubnpBdXRvUGxheSB8fCAhdGhpcy5uekF1dG9QbGF5U3BlZWQpIHtcbiAgICAgIHRoaXMuY2xlYXJTY2hlZHVsZWRUcmFuc2l0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2NoZWR1bGVOZXh0VHJhbnNpdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJTY2hlZHVsZWRUcmFuc2l0aW9uKCk7XG4gICAgaWYgKHRoaXMuc3RyYXRlZ3kpIHtcbiAgICAgIHRoaXMuc3RyYXRlZ3kuZGlzcG9zZSgpO1xuICAgIH1cblxuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIG9uTGlDbGljayA9IChpbmRleDogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuZGlyID09PSAncnRsJykge1xuICAgICAgdGhpcy5nb1RvKHRoaXMuY2Fyb3VzZWxDb250ZW50cy5sZW5ndGggLSAxIC0gaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmdvVG8oaW5kZXgpO1xuICAgIH1cbiAgfTtcblxuICBuZXh0KCk6IHZvaWQge1xuICAgIHRoaXMuZ29Ubyh0aGlzLmFjdGl2ZUluZGV4ICsgMSk7XG4gIH1cblxuICBwcmUoKTogdm9pZCB7XG4gICAgdGhpcy5nb1RvKHRoaXMuYWN0aXZlSW5kZXggLSAxKTtcbiAgfVxuXG4gIGdvVG8oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChcbiAgICAgIHRoaXMuY2Fyb3VzZWxDb250ZW50cyAmJlxuICAgICAgdGhpcy5jYXJvdXNlbENvbnRlbnRzLmxlbmd0aCAmJlxuICAgICAgIXRoaXMuaXNUcmFuc2l0aW5nICYmXG4gICAgICAodGhpcy5uekxvb3AgfHwgKGluZGV4ID49IDAgJiYgaW5kZXggPCB0aGlzLmNhcm91c2VsQ29udGVudHMubGVuZ3RoKSlcbiAgICApIHtcbiAgICAgIGNvbnN0IGxlbmd0aCA9IHRoaXMuY2Fyb3VzZWxDb250ZW50cy5sZW5ndGg7XG4gICAgICBjb25zdCBmcm9tID0gdGhpcy5hY3RpdmVJbmRleDtcbiAgICAgIGNvbnN0IHRvID0gKGluZGV4ICsgbGVuZ3RoKSAlIGxlbmd0aDtcbiAgICAgIHRoaXMuaXNUcmFuc2l0aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMubnpCZWZvcmVDaGFuZ2UuZW1pdCh7IGZyb20sIHRvIH0pO1xuICAgICAgdGhpcy5zdHJhdGVneSEuc3dpdGNoKHRoaXMuYWN0aXZlSW5kZXgsIGluZGV4KS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLnNjaGVkdWxlTmV4dFRyYW5zaXRpb24oKTtcbiAgICAgICAgdGhpcy5uekFmdGVyQ2hhbmdlLmVtaXQodG8pO1xuICAgICAgICB0aGlzLmlzVHJhbnNpdGluZyA9IGZhbHNlO1xuICAgICAgfSk7XG4gICAgICB0aGlzLm1hcmtDb250ZW50QWN0aXZlKHRvKTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3dpdGNoU3RyYXRlZ3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RyYXRlZ3kpIHtcbiAgICAgIHRoaXMuc3RyYXRlZ3kuZGlzcG9zZSgpO1xuICAgIH1cblxuICAgIC8vIExvYWQgY3VzdG9tIHN0cmF0ZWdpZXMgZmlyc3QuXG4gICAgY29uc3QgY3VzdG9tU3RyYXRlZ3kgPSB0aGlzLmN1c3RvbVN0cmF0ZWdpZXMgPyB0aGlzLmN1c3RvbVN0cmF0ZWdpZXMuZmluZChzID0+IHMubmFtZSA9PT0gdGhpcy5uekVmZmVjdCkgOiBudWxsO1xuICAgIGlmIChjdXN0b21TdHJhdGVneSkge1xuICAgICAgdGhpcy5zdHJhdGVneSA9IG5ldyAoY3VzdG9tU3RyYXRlZ3kuc3RyYXRlZ3kgYXMgTnpTYWZlQW55KSh0aGlzLCB0aGlzLmNkciwgdGhpcy5yZW5kZXJlciwgdGhpcy5wbGF0Zm9ybSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zdHJhdGVneSA9XG4gICAgICB0aGlzLm56RWZmZWN0ID09PSAnc2Nyb2xseCdcbiAgICAgICAgPyBuZXcgTnpDYXJvdXNlbFRyYW5zZm9ybVN0cmF0ZWd5KHRoaXMsIHRoaXMuY2RyLCB0aGlzLnJlbmRlcmVyLCB0aGlzLnBsYXRmb3JtKVxuICAgICAgICA6IG5ldyBOekNhcm91c2VsT3BhY2l0eVN0cmF0ZWd5KHRoaXMsIHRoaXMuY2RyLCB0aGlzLnJlbmRlcmVyLCB0aGlzLnBsYXRmb3JtKTtcbiAgfVxuXG4gIHByaXZhdGUgc2NoZWR1bGVOZXh0VHJhbnNpdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFyU2NoZWR1bGVkVHJhbnNpdGlvbigpO1xuICAgIGlmICh0aGlzLm56QXV0b1BsYXkgJiYgdGhpcy5uekF1dG9QbGF5U3BlZWQgPiAwICYmIHRoaXMucGxhdGZvcm0uaXNCcm93c2VyKSB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25JblByb2dyZXNzID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZ29Ubyh0aGlzLmFjdGl2ZUluZGV4ICsgMSk7XG4gICAgICB9LCB0aGlzLm56QXV0b1BsYXlTcGVlZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclNjaGVkdWxlZFRyYW5zaXRpb24oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudHJhbnNpdGlvbkluUHJvZ3Jlc3MpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRyYW5zaXRpb25JblByb2dyZXNzKTtcbiAgICAgIHRoaXMudHJhbnNpdGlvbkluUHJvZ3Jlc3MgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWFya0NvbnRlbnRBY3RpdmUoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuYWN0aXZlSW5kZXggPSBpbmRleDtcblxuICAgIGlmICh0aGlzLmNhcm91c2VsQ29udGVudHMpIHtcbiAgICAgIHRoaXMuY2Fyb3VzZWxDb250ZW50cy5mb3JFYWNoKChzbGlkZSwgaSkgPT4ge1xuICAgICAgICBpZiAodGhpcy5kaXIgPT09ICdydGwnKSB7XG4gICAgICAgICAgc2xpZGUuaXNBY3RpdmUgPSBpbmRleCA9PT0gdGhpcy5jYXJvdXNlbENvbnRlbnRzLmxlbmd0aCAtIDEgLSBpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNsaWRlLmlzQWN0aXZlID0gaW5kZXggPT09IGk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYWcgY2Fyb3VzZWwuXG4gICAqL1xuICBwb2ludGVyRG93biA9IChldmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAoIXRoaXMuaXNEcmFnZ2luZyAmJiAhdGhpcy5pc1RyYW5zaXRpbmcgJiYgdGhpcy5uekVuYWJsZVN3aXBlKSB7XG4gICAgICB0aGlzLmNsZWFyU2NoZWR1bGVkVHJhbnNpdGlvbigpO1xuICAgICAgdGhpcy5nZXN0dXJlUmVjdCA9IHRoaXMuc2xpY2tMaXN0RWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgIHRoaXMubnpEcmFnU2VydmljZS5yZXF1ZXN0RHJhZ2dpbmdTZXF1ZW5jZShldmVudCkuc3Vic2NyaWJlKFxuICAgICAgICBkZWx0YSA9PiB7XG4gICAgICAgICAgdGhpcy5wb2ludGVyRGVsdGEgPSBkZWx0YTtcbiAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuc3RyYXRlZ3k/LmRyYWdnaW5nKHRoaXMucG9pbnRlckRlbHRhKTtcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge30sXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5uekVuYWJsZVN3aXBlICYmIHRoaXMuaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgY29uc3QgeERlbHRhID0gdGhpcy5wb2ludGVyRGVsdGEgPyB0aGlzLnBvaW50ZXJEZWx0YS54IDogMDtcblxuICAgICAgICAgICAgLy8gU3dpdGNoIHRvIGFub3RoZXIgc2xpZGUgaWYgZGVsdGEgaXMgYmlnZ2VyIHRoYW4gdGhpcmQgb2YgdGhlIHdpZHRoLlxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBNYXRoLmFicyh4RGVsdGEpID4gdGhpcy5nZXN0dXJlUmVjdCEud2lkdGggLyAzICYmXG4gICAgICAgICAgICAgICh0aGlzLm56TG9vcCB8fFxuICAgICAgICAgICAgICAgICh4RGVsdGEgPD0gMCAmJiB0aGlzLmFjdGl2ZUluZGV4ICsgMSA8IHRoaXMuY2Fyb3VzZWxDb250ZW50cy5sZW5ndGgpIHx8XG4gICAgICAgICAgICAgICAgKHhEZWx0YSA+IDAgJiYgdGhpcy5hY3RpdmVJbmRleCA+IDApKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuZ29Ubyh4RGVsdGEgPiAwID8gdGhpcy5hY3RpdmVJbmRleCAtIDEgOiB0aGlzLmFjdGl2ZUluZGV4ICsgMSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmdvVG8odGhpcy5hY3RpdmVJbmRleCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuZ2VzdHVyZVJlY3QgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5wb2ludGVyRGVsdGEgPSBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBsYXlvdXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RyYXRlZ3kpIHtcbiAgICAgIHRoaXMuc3RyYXRlZ3kud2l0aENhcm91c2VsQ29udGVudHModGhpcy5jYXJvdXNlbENvbnRlbnRzKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==