ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
496 lines (492 loc) • 53.1 kB
JavaScript
import { __decorate } from "tslib";
import { NgClass, NgForOf, NgIf, NgStyle, NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, Input, Optional, ViewEncapsulation } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { WithConfig } from 'ng-zorro-antd/core/config';
import { NzOutletModule } from 'ng-zorro-antd/core/outlet';
import { InputNumber, isNotNil } from 'ng-zorro-antd/core/util';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { handleCircleGradient, handleLinearGradient } from './utils';
import * as i0 from "@angular/core";
import * as i1 from "ng-zorro-antd/core/config";
import * as i2 from "@angular/cdk/bidi";
import * as i3 from "ng-zorro-antd/icon";
import * as i4 from "ng-zorro-antd/core/outlet";
let gradientIdSeed = 0;
const NZ_CONFIG_MODULE_NAME = 'progress';
const statusIconNameMap = new Map([
['success', 'check'],
['exception', 'close']
]);
const statusColorMap = new Map([
['normal', '#108ee9'],
['exception', '#ff5500'],
['success', '#87d068']
]);
const defaultFormatter = (p) => `${p}%`;
export class NzProgressComponent {
get formatter() {
return this.nzFormat || defaultFormatter;
}
get status() {
return this.nzStatus || this.inferredStatus;
}
get strokeWidth() {
return this.nzStrokeWidth || (this.nzType === 'line' && this.nzSize !== 'small' ? 8 : 6);
}
get isCircleStyle() {
return this.nzType === 'circle' || this.nzType === 'dashboard';
}
constructor(cdr, nzConfigService, directionality) {
this.cdr = cdr;
this.nzConfigService = nzConfigService;
this.directionality = directionality;
this._nzModuleName = NZ_CONFIG_MODULE_NAME;
this.nzShowInfo = true;
this.nzWidth = 132;
this.nzStrokeColor = undefined;
this.nzSize = 'default';
this.nzPercent = 0;
this.nzStrokeWidth = undefined;
this.nzGapDegree = undefined;
this.nzType = 'line';
this.nzGapPosition = 'top';
this.nzStrokeLinecap = 'round';
this.nzSteps = 0;
this.steps = [];
/** Gradient style when `nzType` is `line`. */
this.lineGradient = null;
/** If user uses gradient color. */
this.isGradient = false;
/** If the linear progress is a step progress. */
this.isSteps = false;
/**
* Each progress whose `nzType` is circle or dashboard should have unique id to
* define `<linearGradient>`.
*/
this.gradientId = gradientIdSeed++;
/** Paths to rendered in the template. */
this.progressCirclePath = [];
this.trailPathStyle = null;
this.dir = 'ltr';
this.trackByFn = (index) => `${index}`;
this.cachedStatus = 'normal';
this.inferredStatus = 'normal';
this.destroy$ = new Subject();
}
ngOnChanges(changes) {
const { nzSteps, nzGapPosition, nzStrokeLinecap, nzStrokeColor, nzGapDegree, nzType, nzStatus, nzPercent, nzSuccessPercent, nzStrokeWidth } = changes;
if (nzStatus) {
this.cachedStatus = this.nzStatus || this.cachedStatus;
}
if (nzPercent || nzSuccessPercent) {
const fillAll = parseInt(this.nzPercent.toString(), 10) >= 100;
if (fillAll) {
if ((isNotNil(this.nzSuccessPercent) && this.nzSuccessPercent >= 100) || this.nzSuccessPercent === undefined) {
this.inferredStatus = 'success';
}
}
else {
this.inferredStatus = this.cachedStatus;
}
}
if (nzStatus || nzPercent || nzSuccessPercent || nzStrokeColor) {
this.updateIcon();
}
if (nzStrokeColor) {
this.setStrokeColor();
}
if (nzGapPosition || nzStrokeLinecap || nzGapDegree || nzType || nzPercent || nzStrokeColor || nzStrokeColor) {
this.getCirclePaths();
}
if (nzPercent || nzSteps || nzStrokeWidth) {
this.isSteps = this.nzSteps > 0;
if (this.isSteps) {
this.getSteps();
}
}
}
ngOnInit() {
this.nzConfigService
.getConfigChangeEventForComponent(NZ_CONFIG_MODULE_NAME)
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
this.updateIcon();
this.setStrokeColor();
this.getCirclePaths();
});
this.directionality.change?.pipe(takeUntil(this.destroy$)).subscribe((direction) => {
this.dir = direction;
this.cdr.detectChanges();
});
this.dir = this.directionality.value;
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
updateIcon() {
const ret = statusIconNameMap.get(this.status);
this.icon = ret ? ret + (this.isCircleStyle ? '-o' : '-circle-fill') : '';
}
/**
* Calculate step render configs.
*/
getSteps() {
const current = Math.floor(this.nzSteps * (this.nzPercent / 100));
const stepWidth = this.nzSize === 'small' ? 2 : 14;
const steps = [];
for (let i = 0; i < this.nzSteps; i++) {
let color;
if (i <= current - 1) {
color = this.nzStrokeColor;
}
const stepStyle = {
backgroundColor: `${color}`,
width: `${stepWidth}px`,
height: `${this.strokeWidth}px`
};
steps.push(stepStyle);
}
this.steps = steps;
}
/**
* Calculate paths when the type is circle or dashboard.
*/
getCirclePaths() {
if (!this.isCircleStyle) {
return;
}
const values = isNotNil(this.nzSuccessPercent) ? [this.nzSuccessPercent, this.nzPercent] : [this.nzPercent];
// Calculate shared styles.
const radius = 50 - this.strokeWidth / 2;
const gapPosition = this.nzGapPosition || (this.nzType === 'circle' ? 'top' : 'bottom');
const len = Math.PI * 2 * radius;
const gapDegree = this.nzGapDegree || (this.nzType === 'circle' ? 0 : 75);
let beginPositionX = 0;
let beginPositionY = -radius;
let endPositionX = 0;
let endPositionY = radius * -2;
switch (gapPosition) {
case 'left':
beginPositionX = -radius;
beginPositionY = 0;
endPositionX = radius * 2;
endPositionY = 0;
break;
case 'right':
beginPositionX = radius;
beginPositionY = 0;
endPositionX = radius * -2;
endPositionY = 0;
break;
case 'bottom':
beginPositionY = radius;
endPositionY = radius * 2;
break;
default:
}
this.pathString = `M 50,50 m ${beginPositionX},${beginPositionY}
a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}
a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`;
this.trailPathStyle = {
strokeDasharray: `${len - gapDegree}px ${len}px`,
strokeDashoffset: `-${gapDegree / 2}px`,
transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s'
};
// Calculate styles for each path.
this.progressCirclePath = values
.map((value, index) => {
const isSuccessPercent = values.length === 2 && index === 0;
return {
stroke: this.isGradient && !isSuccessPercent ? `url(#gradient-${this.gradientId})` : null,
strokePathStyle: {
stroke: !this.isGradient
? isSuccessPercent
? statusColorMap.get('success')
: this.nzStrokeColor
: null,
transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s',
strokeDasharray: `${((value || 0) / 100) * (len - gapDegree)}px ${len}px`,
strokeDashoffset: `-${gapDegree / 2}px`
}
};
})
.reverse();
}
setStrokeColor() {
const color = this.nzStrokeColor;
const isGradient = (this.isGradient = !!color && typeof color !== 'string');
if (isGradient && !this.isCircleStyle) {
this.lineGradient = handleLinearGradient(color);
}
else if (isGradient && this.isCircleStyle) {
this.circleGradient = handleCircleGradient(this.nzStrokeColor);
}
else {
this.lineGradient = null;
this.circleGradient = [];
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NzProgressComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.NzConfigService }, { token: i2.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.1", type: NzProgressComponent, isStandalone: true, selector: "nz-progress", inputs: { nzShowInfo: "nzShowInfo", nzWidth: "nzWidth", nzStrokeColor: "nzStrokeColor", nzSize: "nzSize", nzFormat: "nzFormat", nzSuccessPercent: "nzSuccessPercent", nzPercent: "nzPercent", nzStrokeWidth: "nzStrokeWidth", nzGapDegree: "nzGapDegree", nzStatus: "nzStatus", nzType: "nzType", nzGapPosition: "nzGapPosition", nzStrokeLinecap: "nzStrokeLinecap", nzSteps: "nzSteps" }, exportAs: ["nzProgress"], usesOnChanges: true, ngImport: i0, template: `
<ng-template #progressInfoTemplate>
<span class="ant-progress-text" *ngIf="nzShowInfo">
<ng-container *ngIf="(status === 'exception' || status === 'success') && !nzFormat; else formatTemplate">
<span nz-icon [nzType]="icon"></span>
</ng-container>
<ng-template #formatTemplate>
<ng-container *nzStringTemplateOutlet="formatter; context: { $implicit: nzPercent }; let formatter">
{{ formatter(nzPercent) }}
</ng-container>
</ng-template>
</span>
</ng-template>
<div
[ngClass]="'ant-progress ant-progress-status-' + status"
[class.ant-progress-line]="nzType === 'line'"
[class.ant-progress-small]="nzSize === 'small'"
[class.ant-progress-default]="nzSize === 'default'"
[class.ant-progress-show-info]="nzShowInfo"
[class.ant-progress-circle]="isCircleStyle"
[class.ant-progress-steps]="isSteps"
[class.ant-progress-rtl]="dir === 'rtl'"
>
<!-- line progress -->
<div *ngIf="nzType === 'line'">
<!-- normal line style -->
<ng-container *ngIf="!isSteps">
<div class="ant-progress-outer" *ngIf="!isSteps">
<div class="ant-progress-inner">
<div
class="ant-progress-bg"
[style.width.%]="nzPercent"
[style.border-radius]="nzStrokeLinecap === 'round' ? '100px' : '0'"
[style.background]="!isGradient ? nzStrokeColor : null"
[style.background-image]="isGradient ? lineGradient : null"
[style.height.px]="strokeWidth"
></div>
<div
*ngIf="nzSuccessPercent || nzSuccessPercent === 0"
class="ant-progress-success-bg"
[style.width.%]="nzSuccessPercent"
[style.border-radius]="nzStrokeLinecap === 'round' ? '100px' : '0'"
[style.height.px]="strokeWidth"
></div>
</div>
</div>
<ng-template [ngTemplateOutlet]="progressInfoTemplate"></ng-template>
</ng-container>
<!-- step style -->
<div class="ant-progress-steps-outer" *ngIf="isSteps">
<div *ngFor="let step of steps; let i = index" class="ant-progress-steps-item" [ngStyle]="step"></div>
<ng-template [ngTemplateOutlet]="progressInfoTemplate"></ng-template>
</div>
</div>
<!-- circle / dashboard progress -->
<div
[style.width.px]="this.nzWidth"
[style.height.px]="this.nzWidth"
[style.fontSize.px]="this.nzWidth * 0.15 + 6"
class="ant-progress-inner"
[class.ant-progress-circle-gradient]="isGradient"
*ngIf="isCircleStyle"
>
<svg class="ant-progress-circle " viewBox="0 0 100 100">
<defs *ngIf="isGradient">
<linearGradient [id]="'gradient-' + gradientId" x1="100%" y1="0%" x2="0%" y2="0%">
<stop *ngFor="let i of circleGradient" [attr.offset]="i.offset" [attr.stop-color]="i.color"></stop>
</linearGradient>
</defs>
<path
class="ant-progress-circle-trail"
stroke="#f3f3f3"
fill-opacity="0"
[attr.stroke-width]="strokeWidth"
[attr.d]="pathString"
[ngStyle]="trailPathStyle"
></path>
<path
*ngFor="let p of progressCirclePath; trackBy: trackByFn"
class="ant-progress-circle-path"
fill-opacity="0"
[attr.d]="pathString"
[attr.stroke-linecap]="nzStrokeLinecap"
[attr.stroke]="p.stroke"
[attr.stroke-width]="nzPercent ? strokeWidth : 0"
[ngStyle]="p.strokePathStyle"
></path>
</svg>
<ng-template [ngTemplateOutlet]="progressInfoTemplate"></ng-template>
</div>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i3.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzOutletModule }, { kind: "directive", type: i4.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
__decorate([
WithConfig()
], NzProgressComponent.prototype, "nzShowInfo", void 0);
__decorate([
WithConfig()
], NzProgressComponent.prototype, "nzStrokeColor", void 0);
__decorate([
WithConfig()
], NzProgressComponent.prototype, "nzSize", void 0);
__decorate([
InputNumber()
], NzProgressComponent.prototype, "nzSuccessPercent", void 0);
__decorate([
InputNumber()
], NzProgressComponent.prototype, "nzPercent", void 0);
__decorate([
WithConfig(),
InputNumber()
], NzProgressComponent.prototype, "nzStrokeWidth", void 0);
__decorate([
WithConfig(),
InputNumber()
], NzProgressComponent.prototype, "nzGapDegree", void 0);
__decorate([
WithConfig()
], NzProgressComponent.prototype, "nzGapPosition", void 0);
__decorate([
WithConfig()
], NzProgressComponent.prototype, "nzStrokeLinecap", void 0);
__decorate([
InputNumber()
], NzProgressComponent.prototype, "nzSteps", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: NzProgressComponent, decorators: [{
type: Component,
args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
selector: 'nz-progress',
exportAs: 'nzProgress',
preserveWhitespaces: false,
standalone: true,
imports: [NgIf, NzIconModule, NzOutletModule, NgClass, NgTemplateOutlet, NgForOf, NgStyle],
template: `
<ng-template #progressInfoTemplate>
<span class="ant-progress-text" *ngIf="nzShowInfo">
<ng-container *ngIf="(status === 'exception' || status === 'success') && !nzFormat; else formatTemplate">
<span nz-icon [nzType]="icon"></span>
</ng-container>
<ng-template #formatTemplate>
<ng-container *nzStringTemplateOutlet="formatter; context: { $implicit: nzPercent }; let formatter">
{{ formatter(nzPercent) }}
</ng-container>
</ng-template>
</span>
</ng-template>
<div
[ngClass]="'ant-progress ant-progress-status-' + status"
[class.ant-progress-line]="nzType === 'line'"
[class.ant-progress-small]="nzSize === 'small'"
[class.ant-progress-default]="nzSize === 'default'"
[class.ant-progress-show-info]="nzShowInfo"
[class.ant-progress-circle]="isCircleStyle"
[class.ant-progress-steps]="isSteps"
[class.ant-progress-rtl]="dir === 'rtl'"
>
<!-- line progress -->
<div *ngIf="nzType === 'line'">
<!-- normal line style -->
<ng-container *ngIf="!isSteps">
<div class="ant-progress-outer" *ngIf="!isSteps">
<div class="ant-progress-inner">
<div
class="ant-progress-bg"
[style.width.%]="nzPercent"
[style.border-radius]="nzStrokeLinecap === 'round' ? '100px' : '0'"
[style.background]="!isGradient ? nzStrokeColor : null"
[style.background-image]="isGradient ? lineGradient : null"
[style.height.px]="strokeWidth"
></div>
<div
*ngIf="nzSuccessPercent || nzSuccessPercent === 0"
class="ant-progress-success-bg"
[style.width.%]="nzSuccessPercent"
[style.border-radius]="nzStrokeLinecap === 'round' ? '100px' : '0'"
[style.height.px]="strokeWidth"
></div>
</div>
</div>
<ng-template [ngTemplateOutlet]="progressInfoTemplate"></ng-template>
</ng-container>
<!-- step style -->
<div class="ant-progress-steps-outer" *ngIf="isSteps">
<div *ngFor="let step of steps; let i = index" class="ant-progress-steps-item" [ngStyle]="step"></div>
<ng-template [ngTemplateOutlet]="progressInfoTemplate"></ng-template>
</div>
</div>
<!-- circle / dashboard progress -->
<div
[style.width.px]="this.nzWidth"
[style.height.px]="this.nzWidth"
[style.fontSize.px]="this.nzWidth * 0.15 + 6"
class="ant-progress-inner"
[class.ant-progress-circle-gradient]="isGradient"
*ngIf="isCircleStyle"
>
<svg class="ant-progress-circle " viewBox="0 0 100 100">
<defs *ngIf="isGradient">
<linearGradient [id]="'gradient-' + gradientId" x1="100%" y1="0%" x2="0%" y2="0%">
<stop *ngFor="let i of circleGradient" [attr.offset]="i.offset" [attr.stop-color]="i.color"></stop>
</linearGradient>
</defs>
<path
class="ant-progress-circle-trail"
stroke="#f3f3f3"
fill-opacity="0"
[attr.stroke-width]="strokeWidth"
[attr.d]="pathString"
[ngStyle]="trailPathStyle"
></path>
<path
*ngFor="let p of progressCirclePath; trackBy: trackByFn"
class="ant-progress-circle-path"
fill-opacity="0"
[attr.d]="pathString"
[attr.stroke-linecap]="nzStrokeLinecap"
[attr.stroke]="p.stroke"
[attr.stroke-width]="nzPercent ? strokeWidth : 0"
[ngStyle]="p.strokePathStyle"
></path>
</svg>
<ng-template [ngTemplateOutlet]="progressInfoTemplate"></ng-template>
</div>
</div>
`
}]
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.NzConfigService }, { type: i2.Directionality, decorators: [{
type: Optional
}] }], propDecorators: { nzShowInfo: [{
type: Input
}], nzWidth: [{
type: Input
}], nzStrokeColor: [{
type: Input
}], nzSize: [{
type: Input
}], nzFormat: [{
type: Input
}], nzSuccessPercent: [{
type: Input
}], nzPercent: [{
type: Input
}], nzStrokeWidth: [{
type: Input
}], nzGapDegree: [{
type: Input
}], nzStatus: [{
type: Input
}], nzType: [{
type: Input
}], nzGapPosition: [{
type: Input
}], nzStrokeLinecap: [{
type: Input
}], nzSteps: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZ3Jlc3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy9wcm9ncmVzcy9wcm9ncmVzcy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQU1BLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRixPQUFPLEVBQ0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxLQUFLLEVBSUwsUUFBUSxFQUVSLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQWdDLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JGLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUUzRCxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQWNsRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxTQUFTLENBQUM7Ozs7OztBQUVyRSxJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUM7QUFFdkIsTUFBTSxxQkFBcUIsR0FBZ0IsVUFBVSxDQUFDO0FBQ3RELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDaEMsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDO0lBQ3BCLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQztDQUN2QixDQUFDLENBQUM7QUFDSCxNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUM3QixDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUM7SUFDckIs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S0FBSztnQkFDaUIsZUFBZTtzQkFBckMsS0FBSztnQkFFa0IsT0FBTztzQkFBOUIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IERpcmVjdGlvbiwgRGlyZWN0aW9uYWxpdHkgfSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQgeyBOZ0NsYXNzLCBOZ0Zvck9mLCBOZ0lmLCBOZ1N0eWxlLCBOZ1RlbXBsYXRlT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBOekNvbmZpZ0tleSwgTnpDb25maWdTZXJ2aWNlLCBXaXRoQ29uZmlnIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2NvbmZpZyc7XG5pbXBvcnQgeyBOek91dGxldE1vZHVsZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9vdXRsZXQnO1xuaW1wb3J0IHsgTmdTdHlsZUludGVyZmFjZSwgTnVtYmVySW5wdXQgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgSW5wdXROdW1iZXIsIGlzTm90TmlsIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuaW1wb3J0IHsgTnpJY29uTW9kdWxlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9pY29uJztcblxuaW1wb3J0IHtcbiAgTnpQcm9ncmVzc0NpcmNsZVBhdGgsXG4gIE56UHJvZ3Jlc3NDb2xvckdyYWRpZW50LFxuICBOelByb2dyZXNzRm9ybWF0dGVyLFxuICBOelByb2dyZXNzR2FwUG9zaXRpb25UeXBlLFxuICBOelByb2dyZXNzR3JhZGllbnRQcm9ncmVzcyxcbiAgTnpQcm9ncmVzc1N0YXR1c1R5cGUsXG4gIE56UHJvZ3Jlc3NTdGVwSXRlbSxcbiAgTnpQcm9ncmVzc1N0cm9rZUNvbG9yVHlwZSxcbiAgTnpQcm9ncmVzc1N0cm9rZUxpbmVjYXBUeXBlLFxuICBOelByb2dyZXNzVHlwZVR5cGVcbn0gZnJvbSAnLi90eXBpbmdzJztcbmltcG9ydCB7IGhhbmRsZUNpcmNsZUdyYWRpZW50LCBoYW5kbGVMaW5lYXJHcmFkaWVudCB9IGZyb20gJy4vdXRpbHMnO1xuXG5sZXQgZ3JhZGllbnRJZFNlZWQgPSAwO1xuXG5jb25zdCBOWl9DT05GSUdfTU9EVUxFX05BTUU6IE56Q29uZmlnS2V5ID0gJ3Byb2dyZXNzJztcbmNvbnN0IHN0YXR1c0ljb25OYW1lTWFwID0gbmV3IE1hcChbXG4gIFsnc3VjY2VzcycsICdjaGVjayddLFxuICBbJ2V4Y2VwdGlvbicsICdjbG9zZSddXG5dKTtcbmNvbnN0IHN0YXR1c0NvbG9yTWFwID0gbmV3IE1hcChbXG4gIFsnbm9ybWFsJywgJyMxMDhlZTknXSxcbiAgWydleGNlcHRpb24nLCAnI2ZmNTUwMCddLFxuICBbJ3N1Y2Nlc3MnLCAnIzg3ZDA2OCddXG5dKTtcbmNvbnN0IGRlZmF1bHRGb3JtYXR0ZXI6IE56UHJvZ3Jlc3NGb3JtYXR0ZXIgPSAocDogbnVtYmVyKTogc3RyaW5nID0+IGAke3B9JWA7XG5cbkBDb21wb25lbnQoe1xuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc2VsZWN0b3I6ICduei1wcm9ncmVzcycsXG4gIGV4cG9ydEFzOiAnbnpQcm9ncmVzcycsXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbTmdJZiwgTnpJY29uTW9kdWxlLCBOek91dGxldE1vZHVsZSwgTmdDbGFzcywgTmdUZW1wbGF0ZU91dGxldCwgTmdGb3JPZiwgTmdTdHlsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPG5nLXRlbXBsYXRlICNwcm9ncmVzc0luZm9UZW1wbGF0ZT5cbiAgICAgIDxzcGFuIGNsYXNzPVwiYW50LXByb2dyZXNzLXRleHRcIiAqbmdJZj1cIm56U2hvd0luZm9cIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIihzdGF0dXMgPT09ICdleGNlcHRpb24nIHx8IHN0YXR1cyA9PT0gJ3N1Y2Nlc3MnKSAmJiAhbnpGb3JtYXQ7IGVsc2UgZm9ybWF0VGVtcGxhdGVcIj5cbiAgICAgICAgICA8c3BhbiBuei1pY29uIFtuelR5cGVdPVwiaWNvblwiPjwvc3Bhbj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjZm9ybWF0VGVtcGxhdGU+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbnpTdHJpbmdUZW1wbGF0ZU91dGxldD1cImZvcm1hdHRlcjsgY29udGV4dDogeyAkaW1wbGljaXQ6IG56UGVyY2VudCB9OyBsZXQgZm9ybWF0dGVyXCI+XG4gICAgICAgICAgICB7eyBmb3JtYXR0ZXIobnpQZXJjZW50KSB9fVxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9zcGFuPlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8ZGl2XG4gICAgICBbbmdDbGFzc109XCInYW50LXByb2dyZXNzIGFudC1wcm9ncmVzcy1zdGF0dXMtJyArIHN0YXR1c1wiXG4gICAgICBbY2xhc3MuYW50LXByb2dyZXNzLWxpbmVdPVwibnpUeXBlID09PSAnbGluZSdcIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1zbWFsbF09XCJuelNpemUgPT09ICdzbWFsbCdcIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1kZWZhdWx0XT1cIm56U2l6ZSA9PT0gJ2RlZmF1bHQnXCJcbiAgICAgIFtjbGFzcy5hbnQtcHJvZ3Jlc3Mtc2hvdy1pbmZvXT1cIm56U2hvd0luZm9cIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1jaXJjbGVdPVwiaXNDaXJjbGVTdHlsZVwiXG4gICAgICBbY2xhc3MuYW50LXByb2dyZXNzLXN0ZXBzXT1cImlzU3RlcHNcIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1ydGxdPVwiZGlyID09PSAncnRsJ1wiXG4gICAgPlxuICAgICAgPCEtLSBsaW5lIHByb2dyZXNzIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cIm56VHlwZSA9PT0gJ2xpbmUnXCI+XG4gICAgICAgIDwhLS0gbm9ybWFsIGxpbmUgc3R5bGUgLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNTdGVwc1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhbnQtcHJvZ3Jlc3Mtb3V0ZXJcIiAqbmdJZj1cIiFpc1N0ZXBzXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LXByb2dyZXNzLWlubmVyXCI+XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjbGFzcz1cImFudC1wcm9ncmVzcy1iZ1wiXG4gICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoLiVdPVwibnpQZXJjZW50XCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuYm9yZGVyLXJhZGl1c109XCJuelN0cm9rZUxpbmVjYXAgPT09ICdyb3VuZCcgPyAnMTAwcHgnIDogJzAnXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZF09XCIhaXNHcmFkaWVudCA/IG56U3Ryb2tlQ29sb3IgOiBudWxsXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1pbWFnZV09XCJpc0dyYWRpZW50ID8gbGluZUdyYWRpZW50IDogbnVsbFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodC5weF09XCJzdHJva2VXaWR0aFwiXG4gICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICpuZ0lmPVwibnpTdWNjZXNzUGVyY2VudCB8fCBuelN1Y2Nlc3NQZXJjZW50ID09PSAwXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImFudC1wcm9ncmVzcy1zdWNjZXNzLWJnXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGguJV09XCJuelN1Y2Nlc3NQZXJjZW50XCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuYm9yZGVyLXJhZGl1c109XCJuelN0cm9rZUxpbmVjYXAgPT09ICdyb3VuZCcgPyAnMTAwcHgnIDogJzAnXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cInN0cm9rZVdpZHRoXCJcbiAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInByb2dyZXNzSW5mb1RlbXBsYXRlXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwhLS0gc3RlcCBzdHlsZSAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFudC1wcm9ncmVzcy1zdGVwcy1vdXRlclwiICpuZ0lmPVwiaXNTdGVwc1wiPlxuICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHN0ZXAgb2Ygc3RlcHM7IGxldCBpID0gaW5kZXhcIiBjbGFzcz1cImFudC1wcm9ncmVzcy1zdGVwcy1pdGVtXCIgW25nU3R5bGVdPVwic3RlcFwiPjwvZGl2PlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJwcm9ncmVzc0luZm9UZW1wbGF0ZVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gY2lyY2xlIC8gZGFzaGJvYXJkIHByb2dyZXNzIC0tPlxuICAgICAgPGRpdlxuICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwidGhpcy5ueldpZHRoXCJcbiAgICAgICAgW3N0eWxlLmhlaWdodC5weF09XCJ0aGlzLm56V2lkdGhcIlxuICAgICAgICBbc3R5bGUuZm9udFNpemUucHhdPVwidGhpcy5ueldpZHRoICogMC4xNSArIDZcIlxuICAgICAgICBjbGFzcz1cImFudC1wcm9ncmVzcy1pbm5lclwiXG4gICAgICAgIFtjbGFzcy5hbnQtcHJvZ3Jlc3MtY2lyY2xlLWdyYWRpZW50XT1cImlzR3JhZGllbnRcIlxuICAgICAgICAqbmdJZj1cImlzQ2lyY2xlU3R5bGVcIlxuICAgICAgPlxuICAgICAgICA8c3ZnIGNsYXNzPVwiYW50LXByb2dyZXNzLWNpcmNsZSBcIiB2aWV3Qm94PVwiMCAwIDEwMCAxMDBcIj5cbiAgICAgICAgICA8ZGVmcyAqbmdJZj1cImlzR3JhZGllbnRcIj5cbiAgICAgICAgICAgIDxsaW5lYXJHcmFkaWVudCBbaWRdPVwiJ2dyYWRpZW50LScgKyBncmFkaWVudElkXCIgeDE9XCIxMDAlXCIgeTE9XCIwJVwiIHgyPVwiMCVcIiB5Mj1cIjAlXCI+XG4gICAgICAgICAgICAgIDxzdG9wICpuZ0Zvcj1cImxldCBpIG9mIGNpcmNsZUdyYWRpZW50XCIgW2F0dHIub2Zmc2V0XT1cImkub2Zmc2V0XCIgW2F0dHIuc3RvcC1jb2xvcl09XCJpLmNvbG9yXCI+PC9zdG9wPlxuICAgICAgICAgICAgPC9saW5lYXJHcmFkaWVudD5cbiAgICAgICAgICA8L2RlZnM+XG4gICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgIGNsYXNzPVwiYW50LXByb2dyZXNzLWNpcmNsZS10cmFpbFwiXG4gICAgICAgICAgICBzdHJva2U9XCIjZjNmM2YzXCJcbiAgICAgICAgICAgIGZpbGwtb3BhY2l0eT1cIjBcIlxuICAgICAgICAgICAgW2F0dHIuc3Ryb2tlLXdpZHRoXT1cInN0cm9rZVdpZHRoXCJcbiAgICAgICAgICAgIFthdHRyLmRdPVwicGF0aFN0cmluZ1wiXG4gICAgICAgICAgICBbbmdTdHlsZV09XCJ0cmFpbFBhdGhTdHlsZVwiXG4gICAgICAgICAgPjwvcGF0aD5cbiAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IHAgb2YgcHJvZ3Jlc3NDaXJjbGVQYXRoOyB0cmFja0J5OiB0cmFja0J5Rm5cIlxuICAgICAgICAgICAgY2xhc3M9XCJhbnQtcHJvZ3Jlc3MtY2lyY2xlLXBhdGhcIlxuICAgICAgICAgICAgZmlsbC1vcGFjaXR5PVwiMFwiXG4gICAgICAgICAgICBbYXR0ci5kXT1cInBhdGhTdHJpbmdcIlxuICAgICAgICAgICAgW2F0dHIuc3Ryb2tlLWxpbmVjYXBdPVwibnpTdHJva2VMaW5lY2FwXCJcbiAgICAgICAgICAgIFthdHRyLnN0cm9rZV09XCJwLnN0cm9rZVwiXG4gICAgICAgICAgICBbYXR0ci5zdHJva2Utd2lkdGhdPVwibnpQZXJjZW50ID8gc3Ryb2tlV2lkdGggOiAwXCJcbiAgICAgICAgICAgIFtuZ1N0eWxlXT1cInAuc3Ryb2tlUGF0aFN0eWxlXCJcbiAgICAgICAgICA+PC9wYXRoPlxuICAgICAgICA8L3N2Zz5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInByb2dyZXNzSW5mb1RlbXBsYXRlXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgXG59KVxuZXhwb3J0IGNsYXNzIE56UHJvZ3Jlc3NDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcmVhZG9ubHkgX256TW9kdWxlTmFtZTogTnpDb25maWdLZXkgPSBOWl9DT05GSUdfTU9EVUxFX05BTUU7XG5cbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256U3VjY2Vzc1BlcmNlbnQ6IE51bWJlcklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpQZXJjZW50OiBOdW1iZXJJbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256U3Ryb2tlV2lkdGg6IE51bWJlcklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpHYXBEZWdyZWU6IE51bWJlcklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpTdGVwczogTnVtYmVySW5wdXQ7XG5cbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelNob3dJbmZvOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgbnpXaWR0aCA9IDEzMjtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelN0cm9rZUNvbG9yPzogTnpQcm9ncmVzc1N0cm9rZUNvbG9yVHlwZSA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelNpemU6ICdkZWZhdWx0JyB8ICdzbWFsbCcgPSAnZGVmYXVsdCc7XG4gIEBJbnB1dCgpIG56Rm9ybWF0PzogTnpQcm9ncmVzc0Zvcm1hdHRlcjtcbiAgQElucHV0KCkgQElucHV0TnVtYmVyKCkgbnpTdWNjZXNzUGVyY2VudD86IG51bWJlcjtcbiAgQElucHV0KCkgQElucHV0TnVtYmVyKCkgbnpQZXJjZW50OiBudW1iZXIgPSAwO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIEBJbnB1dE51bWJlcigpIG56U3Ryb2tlV2lkdGg/OiBudW1iZXIgPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKCkgQElucHV0TnVtYmVyKCkgbnpHYXBEZWdyZWU/OiBudW1iZXIgPSB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIG56U3RhdHVzPzogTnpQcm9ncmVzc1N0YXR1c1R5cGU7XG4gIEBJbnB1dCgpIG56VHlwZTogTnpQcm9ncmVzc1R5cGVUeXBlID0gJ2xpbmUnO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIG56R2FwUG9zaXRpb246IE56UHJvZ3Jlc3NHYXBQb3NpdGlvblR5cGUgPSAndG9wJztcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelN0cm9rZUxpbmVjYXA6IE56UHJvZ3Jlc3NTdHJva2VMaW5lY2FwVHlwZSA9ICdyb3VuZCc7XG5cbiAgQElucHV0KCkgQElucHV0TnVtYmVyKCkgbnpTdGVwczogbnVtYmVyID0gMDtcblxuICBzdGVwczogTnpQcm9ncmVzc1N0ZXBJdGVtW10gPSBbXTtcblxuICAvKiogR3JhZGllbnQgc3R5bGUgd2hlbiBgbnpUeXBlYCBpcyBgbGluZWAuICovXG4gIGxpbmVHcmFkaWVudDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIElmIHVzZXIgdXNlcyBncmFkaWVudCBjb2xvci4gKi9cbiAgaXNHcmFkaWVudCA9IGZhbHNlO1xuXG4gIC8qKiBJZiB0aGUgbGluZWFyIHByb2dyZXNzIGlzIGEgc3RlcCBwcm9ncmVzcy4gKi9cbiAgaXNTdGVwcyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBFYWNoIHByb2dyZXNzIHdob3NlIGBuelR5cGVgIGlzIGNpcmNsZSBvciBkYXNoYm9hcmQgc2hvdWxkIGhhdmUgdW5pcXVlIGlkIHRvXG4gICAqIGRlZmluZSBgPGxpbmVhckdyYWRpZW50PmAuXG4gICAqL1xuICBncmFkaWVudElkID0gZ3JhZGllbnRJZFNlZWQrKztcblxuICAvKiogUGF0aHMgdG8gcmVuZGVyZWQgaW4gdGhlIHRlbXBsYXRlLiAqL1xuICBwcm9ncmVzc0NpcmNsZVBhdGg6IE56UHJvZ3Jlc3NDaXJjbGVQYXRoW10gPSBbXTtcbiAgY2lyY2xlR3JhZGllbnQ/OiBBcnJheTx7IG9mZnNldDogc3RyaW5nOyBjb2xvcjogc3RyaW5nIH0+O1xuICB0cmFpbFBhdGhTdHlsZTogTmdTdHlsZUludGVyZmFjZSB8IG51bGwgPSBudWxsO1xuICBwYXRoU3RyaW5nPzogc3RyaW5nO1xuICBpY29uITogc3RyaW5nO1xuXG4gIGRpcjogRGlyZWN0aW9uID0gJ2x0cic7XG5cbiAgdHJhY2tCeUZuID0gKGluZGV4OiBudW1iZXIpOiBzdHJpbmcgPT4gYCR7aW5kZXh9YDtcblxuICBnZXQgZm9ybWF0dGVyKCk6IE56UHJvZ3Jlc3NGb3JtYXR0ZXIge1xuICAgIHJldHVybiB0aGlzLm56Rm9ybWF0IHx8IGRlZmF1bHRGb3JtYXR0ZXI7XG4gIH1cblxuICBnZXQgc3RhdHVzKCk6IE56UHJvZ3Jlc3NTdGF0dXNUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5uelN0YXR1cyB8fCB0aGlzLmluZmVycmVkU3RhdHVzO1xuICB9XG5cbiAgZ2V0IHN0cm9rZVdpZHRoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMubnpTdHJva2VXaWR0aCB8fCAodGhpcy5uelR5cGUgPT09ICdsaW5lJyAmJiB0aGlzLm56U2l6ZSAhPT0gJ3NtYWxsJyA/IDggOiA2KTtcbiAgfVxuXG4gIGdldCBpc0NpcmNsZVN0eWxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm56VHlwZSA9PT0gJ2NpcmNsZScgfHwgdGhpcy5uelR5cGUgPT09ICdkYXNoYm9hcmQnO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWNoZWRTdGF0dXM6IE56UHJvZ3Jlc3NTdGF0dXNUeXBlID0gJ25vcm1hbCc7XG4gIHByaXZhdGUgaW5mZXJyZWRTdGF0dXM6IE56UHJvZ3Jlc3NTdGF0dXNUeXBlID0gJ25vcm1hbCc7XG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwdWJsaWMgbnpDb25maWdTZXJ2aWNlOiBOekNvbmZpZ1NlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBkaXJlY3Rpb25hbGl0eTogRGlyZWN0aW9uYWxpdHlcbiAgKSB7fVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB7XG4gICAgICBuelN0ZXBzLFxuICAgICAgbnpHYXBQb3NpdGlvbixcbiAgICAgIG56U3Ryb2tlTGluZWNhcCxcbiAgICAgIG56U3Ryb2tlQ29sb3IsXG4gICAgICBuekdhcERlZ3JlZSxcbiAgICAgIG56VHlwZSxcbiAgICAgIG56U3RhdHVzLFxuICAgICAgbnpQZXJjZW50LFxuICAgICAgbnpTdWNjZXNzUGVyY2VudCxcbiAgICAgIG56U3Ryb2tlV2lkdGhcbiAgICB9ID0gY2hhbmdlcztcblxuICAgIGlmIChuelN0YXR1cykge1xuICAgICAgdGhpcy5jYWNoZWRTdGF0dXMgPSB0aGlzLm56U3RhdHVzIHx8IHRoaXMuY2FjaGVkU3RhdHVzO1xuICAgIH1cblxuICAgIGlmIChuelBlcmNlbnQgfHwgbnpTdWNjZXNzUGVyY2VudCkge1xuICAgICAgY29uc3QgZmlsbEFsbCA9IHBhcnNlSW50KHRoaXMubnpQZXJjZW50LnRvU3RyaW5nKCksIDEwKSA+PSAxMDA7XG4gICAgICBpZiAoZmlsbEFsbCkge1xuICAgICAgICBpZiAoKGlzTm90TmlsKHRoaXMubnpTdWNjZXNzUGVyY2VudCkgJiYgdGhpcy5uelN1Y2Nlc3NQZXJjZW50ISA+PSAxMDApIHx8IHRoaXMubnpTdWNjZXNzUGVyY2VudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5pbmZlcnJlZFN0YXR1cyA9ICdzdWNjZXNzJztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pbmZlcnJlZFN0YXR1cyA9IHRoaXMuY2FjaGVkU3RhdHVzO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChuelN0YXR1cyB8fCBuelBlcmNlbnQgfHwgbnpTdWNjZXNzUGVyY2VudCB8fCBuelN0cm9rZUNvbG9yKSB7XG4gICAgICB0aGlzLnVwZGF0ZUljb24oKTtcbiAgICB9XG5cbiAgICBpZiAobnpTdHJva2VDb2xvcikge1xuICAgICAgdGhpcy5zZXRTdHJva2VDb2xvcigpO1xuICAgIH1cblxuICAgIGlmIChuekdhcFBvc2l0aW9uIHx8IG56U3Ryb2tlTGluZWNhcCB8fCBuekdhcERlZ3JlZSB8fCBuelR5cGUgfHwgbnpQZXJjZW50IHx8IG56U3Ryb2tlQ29sb3IgfHwgbnpTdHJva2VDb2xvcikge1xuICAgICAgdGhpcy5nZXRDaXJjbGVQYXRocygpO1xuICAgIH1cblxuICAgIGlmIChuelBlcmNlbnQgfHwgbnpTdGVwcyB8fCBuelN0cm9rZVdpZHRoKSB7XG4gICAgICB0aGlzLmlzU3RlcHMgPSB0aGlzLm56U3RlcHMgPiAwO1xuICAgICAgaWYgKHRoaXMuaXNTdGVwcykge1xuICAgICAgICB0aGlzLmdldFN0ZXBzKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5uekNvbmZpZ1NlcnZpY2VcbiAgICAgIC5nZXRDb25maWdDaGFuZ2VFdmVudEZvckNvbXBvbmVudChOWl9DT05GSUdfTU9EVUxFX05BTUUpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy51cGRhdGVJY29uKCk7XG4gICAgICAgIHRoaXMuc2V0U3Ryb2tlQ29sb3IoKTtcbiAgICAgICAgdGhpcy5nZXRDaXJjbGVQYXRocygpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLmRpcmVjdGlvbmFsaXR5LmNoYW5nZT8ucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoZGlyZWN0aW9uOiBEaXJlY3Rpb24pID0+IHtcbiAgICAgIHRoaXMuZGlyID0gZGlyZWN0aW9uO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5kaXIgPSB0aGlzLmRpcmVjdGlvbmFsaXR5LnZhbHVlO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVJY29uKCk6IHZvaWQge1xuICAgIGNvbnN0IHJldCA9IHN0YXR1c0ljb25OYW1lTWFwLmdldCh0aGlzLnN0YXR1cyk7XG4gICAgdGhpcy5pY29uID0gcmV0ID8gcmV0ICsgKHRoaXMuaXNDaXJjbGVTdHlsZSA/ICctbycgOiAnLWNpcmNsZS1maWxsJykgOiAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgc3RlcCByZW5kZXIgY29uZmlncy5cbiAgICovXG4gIHByaXZhdGUgZ2V0U3RlcHMoKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudCA9IE1hdGguZmxvb3IodGhpcy5uelN0ZXBzICogKHRoaXMubnpQZXJjZW50IC8gMTAwKSk7XG4gICAgY29uc3Qgc3RlcFdpZHRoID0gdGhpcy5uelNpemUgPT09ICdzbWFsbCcgPyAyIDogMTQ7XG5cbiAgICBjb25zdCBzdGVwcyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm56U3RlcHM7IGkrKykge1xuICAgICAgbGV0IGNvbG9yO1xuICAgICAgaWYgKGkgPD0gY3VycmVudCAtIDEpIHtcbiAgICAgICAgY29sb3IgPSB0aGlzLm56U3Ryb2tlQ29sb3I7XG4gICAgICB9XG4gICAgICBjb25zdCBzdGVwU3R5bGUgPSB7XG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogYCR7Y29sb3J9YCxcbiAgICAgICAgd2lkdGg6IGAke3N0ZXBXaWR0aH1weGAsXG4gICAgICAgIGhlaWdodDogYCR7dGhpcy5zdHJva2VXaWR0aH1weGBcbiAgICAgIH07XG4gICAgICBzdGVwcy5wdXNoKHN0ZXBTdHlsZSk7XG4gICAgfVxuXG4gICAgdGhpcy5zdGVwcyA9IHN0ZXBzO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBwYXRocyB3aGVuIHRoZSB0eXBlIGlzIGNpcmNsZSBvciBkYXNoYm9hcmQuXG4gICAqL1xuICBwcml2YXRlIGdldENpcmNsZVBhdGhzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0NpcmNsZVN0eWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWVzID0gaXNOb3ROaWwodGhpcy5uelN1Y2Nlc3NQZXJjZW50KSA/IFt0aGlzLm56U3VjY2Vzc1BlcmNlbnQhLCB0aGlzLm56UGVyY2VudF0gOiBbdGhpcy5uelBlcmNlbnRdO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHNoYXJlZCBzdHlsZXMuXG4gICAgY29uc3QgcmFkaXVzID0gNTAgLSB0aGlzLnN0cm9rZVdpZHRoIC8gMjtcbiAgICBjb25zdCBnYXBQb3NpdGlvbiA9IHRoaXMubnpHYXBQb3NpdGlvbiB8fCAodGhpcy5uelR5cGUgPT09ICdjaXJjbGUnID8gJ3RvcCcgOiAnYm90dG9tJyk7XG4gICAgY29uc3QgbGVuID0gTWF0aC5QSSAqIDIgKiByYWRpdXM7XG4gICAgY29uc3QgZ2FwRGVncmVlID0gdGhpcy5uekdhcERlZ3JlZSB8fCAodGhpcy5uelR5cGUgPT09ICdjaXJjbGUnID8gMCA6IDc1KTtcblxuICAgIGxldCBiZWdpblBvc2l0aW9uWCA9IDA7XG4gICAgbGV0IGJlZ2luUG9zaXRpb25ZID0gLXJhZGl1cztcbiAgICBsZXQgZW5kUG9zaXRpb25YID0gMDtcbiAgICBsZXQgZW5kUG9zaXRpb25ZID0gcmFkaXVzICogLTI7XG5cbiAgICBzd2l0Y2ggKGdhcFBvc2l0aW9uKSB7XG4g