ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
513 lines (505 loc) • 52.9 kB
JavaScript
import { __decorate } from "tslib";
import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation, numberAttribute } 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 { isNotNil, numberAttributeWithZeroFallback } 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.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.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: "18.1.2", ngImport: i0, type: NzProgressComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.NzConfigService }, { token: i2.Directionality }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.2", type: NzProgressComponent, isStandalone: true, selector: "nz-progress", inputs: { nzShowInfo: "nzShowInfo", nzWidth: "nzWidth", nzStrokeColor: "nzStrokeColor", nzSize: "nzSize", nzFormat: "nzFormat", nzSuccessPercent: ["nzSuccessPercent", "nzSuccessPercent", numberAttributeWithZeroFallback], nzPercent: ["nzPercent", "nzPercent", numberAttribute], nzStrokeWidth: ["nzStrokeWidth", "nzStrokeWidth", numberAttributeWithZeroFallback], nzGapDegree: ["nzGapDegree", "nzGapDegree", numberAttributeWithZeroFallback], nzStatus: "nzStatus", nzType: "nzType", nzGapPosition: "nzGapPosition", nzStrokeLinecap: "nzStrokeLinecap", nzSteps: ["nzSteps", "nzSteps", numberAttribute] }, exportAs: ["nzProgress"], usesOnChanges: true, ngImport: i0, template: `
<ng-template #progressInfoTemplate>
@if (nzShowInfo) {
<span class="ant-progress-text">
@if ((status === 'exception' || status === 'success') && !nzFormat) {
<span nz-icon [nzType]="icon"></span>
} @else {
<ng-container *nzStringTemplateOutlet="formatter; context: { $implicit: nzPercent }; let formatter">
{{ formatter(nzPercent) }}
</ng-container>
}
</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'"
>
@if (nzType === 'line') {
<div>
<!-- normal line style -->
@if (isSteps) {
<div class="ant-progress-steps-outer">
@for (step of steps; track step) {
<div class="ant-progress-steps-item" [ngStyle]="step"></div>
}
<ng-template [ngTemplateOutlet]="progressInfoTemplate" />
</div>
} @else {
<div class="ant-progress-outer">
<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>
@if (nzSuccessPercent || nzSuccessPercent === 0) {
<div
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" />
}
</div>
}
<!-- line progress -->
<!-- circle / dashboard progress -->
@if (isCircleStyle) {
<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"
>
<svg class="ant-progress-circle " viewBox="0 0 100 100">
@if (isGradient) {
<defs>
<linearGradient [id]="'gradient-' + gradientId" x1="100%" y1="0%" x2="0%" y2="0%">
@for (i of circleGradient; track i) {
<stop [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>
@for (p of progressCirclePath; track p) {
<path
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" />
</div>
}
</div>
`, isInline: true, dependencies: [{ 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: 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([
WithConfig()
], NzProgressComponent.prototype, "nzStrokeWidth", void 0);
__decorate([
WithConfig()
], NzProgressComponent.prototype, "nzGapDegree", void 0);
__decorate([
WithConfig()
], NzProgressComponent.prototype, "nzGapPosition", void 0);
__decorate([
WithConfig()
], NzProgressComponent.prototype, "nzStrokeLinecap", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzProgressComponent, decorators: [{
type: Component,
args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
selector: 'nz-progress',
exportAs: 'nzProgress',
preserveWhitespaces: false,
standalone: true,
imports: [NzIconModule, NzOutletModule, NgClass, NgTemplateOutlet, NgStyle],
template: `
<ng-template #progressInfoTemplate>
@if (nzShowInfo) {
<span class="ant-progress-text">
@if ((status === 'exception' || status === 'success') && !nzFormat) {
<span nz-icon [nzType]="icon"></span>
} @else {
<ng-container *nzStringTemplateOutlet="formatter; context: { $implicit: nzPercent }; let formatter">
{{ formatter(nzPercent) }}
</ng-container>
}
</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'"
>
@if (nzType === 'line') {
<div>
<!-- normal line style -->
@if (isSteps) {
<div class="ant-progress-steps-outer">
@for (step of steps; track step) {
<div class="ant-progress-steps-item" [ngStyle]="step"></div>
}
<ng-template [ngTemplateOutlet]="progressInfoTemplate" />
</div>
} @else {
<div class="ant-progress-outer">
<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>
@if (nzSuccessPercent || nzSuccessPercent === 0) {
<div
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" />
}
</div>
}
<!-- line progress -->
<!-- circle / dashboard progress -->
@if (isCircleStyle) {
<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"
>
<svg class="ant-progress-circle " viewBox="0 0 100 100">
@if (isGradient) {
<defs>
<linearGradient [id]="'gradient-' + gradientId" x1="100%" y1="0%" x2="0%" y2="0%">
@for (i of circleGradient; track i) {
<stop [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>
@for (p of progressCirclePath; track p) {
<path
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" />
</div>
}
</div>
`
}]
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.NzConfigService }, { type: i2.Directionality }], propDecorators: { nzShowInfo: [{
type: Input
}], nzWidth: [{
type: Input
}], nzStrokeColor: [{
type: Input
}], nzSize: [{
type: Input
}], nzFormat: [{
type: Input
}], nzSuccessPercent: [{
type: Input,
args: [{ transform: numberAttributeWithZeroFallback }]
}], nzPercent: [{
type: Input,
args: [{ transform: numberAttribute }]
}], nzStrokeWidth: [{
type: Input,
args: [{ transform: numberAttributeWithZeroFallback }]
}], nzGapDegree: [{
type: Input,
args: [{ transform: numberAttributeWithZeroFallback }]
}], nzStatus: [{
type: Input
}], nzType: [{
type: Input
}], nzGapPosition: [{
type: Input
}], nzStrokeLinecap: [{
type: Input
}], nzSteps: [{
type: Input,
args: [{ transform: numberAttribute }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZ3Jlc3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy9wcm9ncmVzcy9wcm9ncmVzcy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQU1BLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDckUsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsS0FBSyxFQUtMLGlCQUFpQixFQUNqQixlQUFlLEVBQ2hCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFBZ0MsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDckYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTNELE9BQU8sRUFBRSxRQUFRLEVBQUUsK0JBQStCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFjbEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sU0FBUyxDQUFDOzs7Ozs7QUFFckUsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDO0FBRXZCLE1BQU0scUJBQXFCLEdBQWdCLFVBQVUsQ0FBQztBQUN0RCxNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQ2hDLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQztJQUNwQixDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUM7Q0FDdkIsQ0FBQyxDQUFDO0FBQ0gsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDN0IsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLENBQUMsV0FBVyxFQUFFLFNB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RSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IERpcmVjdGlvbiwgRGlyZWN0aW9uYWxpdHkgfSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQgeyBOZ0NsYXNzLCBOZ1N0eWxlLCBOZ1RlbXBsYXRlT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIG51bWJlckF0dHJpYnV0ZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTnpDb25maWdLZXksIE56Q29uZmlnU2VydmljZSwgV2l0aENvbmZpZyB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9jb25maWcnO1xuaW1wb3J0IHsgTnpPdXRsZXRNb2R1bGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvb3V0bGV0JztcbmltcG9ydCB7IE5nU3R5bGVJbnRlcmZhY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgaXNOb3ROaWwsIG51bWJlckF0dHJpYnV0ZVdpdGhaZXJvRmFsbGJhY2sgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdXRpbCc7XG5pbXBvcnQgeyBOekljb25Nb2R1bGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2ljb24nO1xuXG5pbXBvcnQge1xuICBOelByb2dyZXNzQ2lyY2xlUGF0aCxcbiAgTnpQcm9ncmVzc0NvbG9yR3JhZGllbnQsXG4gIE56UHJvZ3Jlc3NGb3JtYXR0ZXIsXG4gIE56UHJvZ3Jlc3NHYXBQb3NpdGlvblR5cGUsXG4gIE56UHJvZ3Jlc3NHcmFkaWVudFByb2dyZXNzLFxuICBOelByb2dyZXNzU3RhdHVzVHlwZSxcbiAgTnpQcm9ncmVzc1N0ZXBJdGVtLFxuICBOelByb2dyZXNzU3Ryb2tlQ29sb3JUeXBlLFxuICBOelByb2dyZXNzU3Ryb2tlTGluZWNhcFR5cGUsXG4gIE56UHJvZ3Jlc3NUeXBlVHlwZVxufSBmcm9tICcuL3R5cGluZ3MnO1xuaW1wb3J0IHsgaGFuZGxlQ2lyY2xlR3JhZGllbnQsIGhhbmRsZUxpbmVhckdyYWRpZW50IH0gZnJvbSAnLi91dGlscyc7XG5cbmxldCBncmFkaWVudElkU2VlZCA9IDA7XG5cbmNvbnN0IE5aX0NPTkZJR19NT0RVTEVfTkFNRTogTnpDb25maWdLZXkgPSAncHJvZ3Jlc3MnO1xuY29uc3Qgc3RhdHVzSWNvbk5hbWVNYXAgPSBuZXcgTWFwKFtcbiAgWydzdWNjZXNzJywgJ2NoZWNrJ10sXG4gIFsnZXhjZXB0aW9uJywgJ2Nsb3NlJ11cbl0pO1xuY29uc3Qgc3RhdHVzQ29sb3JNYXAgPSBuZXcgTWFwKFtcbiAgWydub3JtYWwnLCAnIzEwOGVlOSddLFxuICBbJ2V4Y2VwdGlvbicsICcjZmY1NTAwJ10sXG4gIFsnc3VjY2VzcycsICcjODdkMDY4J11cbl0pO1xuY29uc3QgZGVmYXVsdEZvcm1hdHRlcjogTnpQcm9ncmVzc0Zvcm1hdHRlciA9IChwOiBudW1iZXIpOiBzdHJpbmcgPT4gYCR7cH0lYDtcblxuQENvbXBvbmVudCh7XG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBzZWxlY3RvcjogJ256LXByb2dyZXNzJyxcbiAgZXhwb3J0QXM6ICduelByb2dyZXNzJyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtOekljb25Nb2R1bGUsIE56T3V0bGV0TW9kdWxlLCBOZ0NsYXNzLCBOZ1RlbXBsYXRlT3V0bGV0LCBOZ1N0eWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8bmctdGVtcGxhdGUgI3Byb2dyZXNzSW5mb1RlbXBsYXRlPlxuICAgICAgQGlmIChuelNob3dJbmZvKSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiYW50LXByb2dyZXNzLXRleHRcIj5cbiAgICAgICAgICBAaWYgKChzdGF0dXMgPT09ICdleGNlcHRpb24nIHx8IHN0YXR1cyA9PT0gJ3N1Y2Nlc3MnKSAmJiAhbnpGb3JtYXQpIHtcbiAgICAgICAgICAgIDxzcGFuIG56LWljb24gW256VHlwZV09XCJpY29uXCI+PC9zcGFuPlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbnpTdHJpbmdUZW1wbGF0ZU91dGxldD1cImZvcm1hdHRlcjsgY29udGV4dDogeyAkaW1wbGljaXQ6IG56UGVyY2VudCB9OyBsZXQgZm9ybWF0dGVyXCI+XG4gICAgICAgICAgICAgIHt7IGZvcm1hdHRlcihuelBlcmNlbnQpIH19XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIH1cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPGRpdlxuICAgICAgW25nQ2xhc3NdPVwiJ2FudC1wcm9ncmVzcyBhbnQtcHJvZ3Jlc3Mtc3RhdHVzLScgKyBzdGF0dXNcIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1saW5lXT1cIm56VHlwZSA9PT0gJ2xpbmUnXCJcbiAgICAgIFtjbGFzcy5hbnQtcHJvZ3Jlc3Mtc21hbGxdPVwibnpTaXplID09PSAnc21hbGwnXCJcbiAgICAgIFtjbGFzcy5hbnQtcHJvZ3Jlc3MtZGVmYXVsdF09XCJuelNpemUgPT09ICdkZWZhdWx0J1wiXG4gICAgICBbY2xhc3MuYW50LXByb2dyZXNzLXNob3ctaW5mb109XCJuelNob3dJbmZvXCJcbiAgICAgIFtjbGFzcy5hbnQtcHJvZ3Jlc3MtY2lyY2xlXT1cImlzQ2lyY2xlU3R5bGVcIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1zdGVwc109XCJpc1N0ZXBzXCJcbiAgICAgIFtjbGFzcy5hbnQtcHJvZ3Jlc3MtcnRsXT1cImRpciA9PT0gJ3J0bCdcIlxuICAgID5cbiAgICAgIEBpZiAobnpUeXBlID09PSAnbGluZScpIHtcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8IS0tIG5vcm1hbCBsaW5lIHN0eWxlIC0tPlxuICAgICAgICAgIEBpZiAoaXNTdGVwcykge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1wcm9ncmVzcy1zdGVwcy1vdXRlclwiPlxuICAgICAgICAgICAgICBAZm9yIChzdGVwIG9mIHN0ZXBzOyB0cmFjayBzdGVwKSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1wcm9ncmVzcy1zdGVwcy1pdGVtXCIgW25nU3R5bGVdPVwic3RlcFwiPjwvZGl2PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJwcm9ncmVzc0luZm9UZW1wbGF0ZVwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhbnQtcHJvZ3Jlc3Mtb3V0ZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1wcm9ncmVzcy1pbm5lclwiPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYW50LXByb2dyZXNzLWJnXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aC4lXT1cIm56UGVyY2VudFwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUuYm9yZGVyLXJhZGl1c109XCJuelN0cm9rZUxpbmVjYXAgPT09ICdyb3VuZCcgPyAnMTAwcHgnIDogJzAnXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cIiFpc0dyYWRpZW50ID8gbnpTdHJva2VDb2xvciA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtaW1hZ2VdPVwiaXNHcmFkaWVudCA/IGxpbmVHcmFkaWVudCA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodC5weF09XCJzdHJva2VXaWR0aFwiXG4gICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgIEBpZiAobnpTdWNjZXNzUGVyY2VudCB8fCBuelN1Y2Nlc3NQZXJjZW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYW50LXByb2dyZXNzLXN1Y2Nlc3MtYmdcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGguJV09XCJuelN1Y2Nlc3NQZXJjZW50XCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLmJvcmRlci1yYWRpdXNdPVwibnpTdHJva2VMaW5lY2FwID09PSAncm91bmQnID8gJzEwMHB4JyA6ICcwJ1wiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwic3Ryb2tlV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJwcm9ncmVzc0luZm9UZW1wbGF0ZVwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cbiAgICAgIDwhLS0gbGluZSBwcm9ncmVzcyAtLT5cblxuICAgICAgPCEtLSBjaXJjbGUgLyBkYXNoYm9hcmQgcHJvZ3Jlc3MgLS0+XG5cbiAgICAgIEBpZiAoaXNDaXJjbGVTdHlsZSkge1xuICAgICAgICA8ZGl2XG4gICAgICAgICAgW3N0eWxlLndpZHRoLnB4XT1cInRoaXMubnpXaWR0aFwiXG4gICAgICAgICAgW3N0eWxlLmhlaWdodC5weF09XCJ0aGlzLm56V2lkdGhcIlxuICAgICAgICAgIFtzdHlsZS5mb250U2l6ZS5weF09XCJ0aGlzLm56V2lkdGggKiAwLjE1ICsgNlwiXG4gICAgICAgICAgY2xhc3M9XCJhbnQtcHJvZ3Jlc3MtaW5uZXJcIlxuICAgICAgICAgIFtjbGFzcy5hbnQtcHJvZ3Jlc3MtY2lyY2xlLWdyYWRpZW50XT1cImlzR3JhZGllbnRcIlxuICAgICAgICA+XG4gICAgICAgICAgPHN2ZyBjbGFzcz1cImFudC1wcm9ncmVzcy1jaXJjbGUgXCIgdmlld0JveD1cIjAgMCAxMDAgMTAwXCI+XG4gICAgICAgICAgICBAaWYgKGlzR3JhZGllbnQpIHtcbiAgICAgICAgICAgICAgPGRlZnM+XG4gICAgICAgICAgICAgICAgPGxpbmVhckdyYWRpZW50IFtpZF09XCInZ3JhZGllbnQtJyArIGdyYWRpZW50SWRcIiB4MT1cIjEwMCVcIiB5MT1cIjAlXCIgeDI9XCIwJVwiIHkyPVwiMCVcIj5cbiAgICAgICAgICAgICAgICAgIEBmb3IgKGkgb2YgY2lyY2xlR3JhZGllbnQ7IHRyYWNrIGkpIHtcbiAgICAgICAgICAgICAgICAgICAgPHN0b3AgW2F0dHIub2Zmc2V0XT1cImkub2Zmc2V0XCIgW2F0dHIuc3RvcC1jb2xvcl09XCJpLmNvbG9yXCI+PC9zdG9wPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvbGluZWFyR3JhZGllbnQ+XG4gICAgICAgICAgICAgIDwvZGVmcz5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgY2xhc3M9XCJhbnQtcHJvZ3Jlc3MtY2lyY2xlLXRyYWlsXCJcbiAgICAgICAgICAgICAgc3Ryb2tlPVwiI2YzZjNmM1wiXG4gICAgICAgICAgICAgIGZpbGwtb3BhY2l0eT1cIjBcIlxuICAgICAgICAgICAgICBbYXR0ci5zdHJva2Utd2lkdGhdPVwic3Ryb2tlV2lkdGhcIlxuICAgICAgICAgICAgICBbYXR0ci5kXT1cInBhdGhTdHJpbmdcIlxuICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ0cmFpbFBhdGhTdHlsZVwiXG4gICAgICAgICAgICA+PC9wYXRoPlxuICAgICAgICAgICAgQGZvciAocCBvZiBwcm9ncmVzc0NpcmNsZVBhdGg7IHRyYWNrIHApIHtcbiAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICBjbGFzcz1cImFudC1wcm9ncmVzcy1jaXJjbGUtcGF0aFwiXG4gICAgICAgICAgICAgICAgZmlsbC1vcGFjaXR5PVwiMFwiXG4gICAgICAgICAgICAgICAgW2F0dHIuZF09XCJwYXRoU3RyaW5nXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5zdHJva2UtbGluZWNhcF09XCJuelN0cm9rZUxpbmVjYXBcIlxuICAgICAgICAgICAgICAgIFthdHRyLnN0cm9rZV09XCJwLnN0cm9rZVwiXG4gICAgICAgICAgICAgICAgW2F0dHIuc3Ryb2tlLXdpZHRoXT1cIm56UGVyY2VudCA/IHN0cm9rZVdpZHRoIDogMFwiXG4gICAgICAgICAgICAgICAgW25nU3R5bGVdPVwicC5zdHJva2VQYXRoU3R5bGVcIlxuICAgICAgICAgICAgICA+PC9wYXRoPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJwcm9ncmVzc0luZm9UZW1wbGF0ZVwiIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgXG59KVxuZXhwb3J0IGNsYXNzIE56UHJvZ3Jlc3NDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcmVhZG9ubHkgX256TW9kdWxlTmFtZTogTnpDb25maWdLZXkgPSBOWl9DT05GSUdfTU9EVUxFX05BTUU7XG5cbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelNob3dJbmZvOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgbnpXaWR0aCA9IDEzMjtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelN0cm9rZUNvbG9yPzogTnpQcm9ncmVzc1N0cm9rZUNvbG9yVHlwZSA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelNpemU6ICdkZWZhdWx0JyB8ICdzbWFsbCcgPSAnZGVmYXVsdCc7XG4gIEBJbnB1dCgpIG56Rm9ybWF0PzogTnpQcm9ncmVzc0Zvcm1hdHRlcjtcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGVXaXRoWmVyb0ZhbGxiYWNrIH0pIG56U3VjY2Vzc1BlcmNlbnQ/OiBudW1iZXI7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogbnVtYmVyQXR0cmlidXRlIH0pIG56UGVyY2VudDogbnVtYmVyID0gMDtcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGVXaXRoWmVyb0ZhbGxiYWNrIH0pIEBXaXRoQ29uZmlnKCkgbnpTdHJva2VXaWR0aD86IG51bWJlcjtcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGVXaXRoWmVyb0ZhbGxiYWNrIH0pIEBXaXRoQ29uZmlnKCkgbnpHYXBEZWdyZWU/OiBudW1iZXI7XG4gIEBJbnB1dCgpIG56U3RhdHVzPzogTnpQcm9ncmVzc1N0YXR1c1R5cGU7XG4gIEBJbnB1dCgpIG56VHlwZTogTnpQcm9ncmVzc1R5cGVUeXBlID0gJ2xpbmUnO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIG56R2FwUG9zaXRpb246IE56UHJvZ3Jlc3NHYXBQb3NpdGlvblR5cGUgPSAndG9wJztcbiAgQElucHV0KCkgQFdpdGhDb25maWcoKSBuelN0cm9rZUxpbmVjYXA6IE56UHJvZ3Jlc3NTdHJva2VMaW5lY2FwVHlwZSA9ICdyb3VuZCc7XG5cbiAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUgfSkgbnpTdGVwczogbnVtYmVyID0gMDtcblxuICBzdGVwczogTnpQcm9ncmVzc1N0ZXBJdGVtW10gPSBbXTtcblxuICAvKiogR3JhZGllbnQgc3R5bGUgd2hlbiBgbnpUeXBlYCBpcyBgbGluZWAuICovXG4gIGxpbmVHcmFkaWVudDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIElmIHVzZXIgdXNlcyBncmFkaWVudCBjb2xvci4gKi9cbiAgaXNHcmFkaWVudCA9IGZhbHNlO1xuXG4gIC8qKiBJZiB0aGUgbGluZWFyIHByb2dyZXNzIGlzIGEgc3RlcCBwcm9ncmVzcy4gKi9cbiAgaXNTdGVwcyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBFYWNoIHByb2dyZXNzIHdob3NlIGBuelR5cGVgIGlzIGNpcmNsZSBvciBkYXNoYm9hcmQgc2hvdWxkIGhhdmUgdW5pcXVlIGlkIHRvXG4gICAqIGRlZmluZSBgPGxpbmVhckdyYWRpZW50PmAuXG4gICAqL1xuICBncmFkaWVudElkID0gZ3JhZGllbnRJZFNlZWQrKztcblxuICAvKiogUGF0aHMgdG8gcmVuZGVyZWQgaW4gdGhlIHRlbXBsYXRlLiAqL1xuICBwcm9ncmVzc0NpcmNsZVBhdGg6IE56UHJvZ3Jlc3NDaXJjbGVQYXRoW10gPSBbXTtcbiAgY2lyY2xlR3JhZGllbnQ/OiBBcnJheTx7IG9mZnNldDogc3RyaW5nOyBjb2xvcjogc3RyaW5nIH0+O1xuICB0cmFpbFBhdGhTdHlsZTogTmdTdHlsZUludGVyZmFjZSB8IG51bGwgPSBudWxsO1xuICBwYXRoU3RyaW5nPzogc3RyaW5nO1xuICBpY29uITogc3RyaW5nO1xuXG4gIGRpcjogRGlyZWN0aW9uID0gJ2x0cic7XG5cbiAgZ2V0IGZvcm1hdHRlcigpOiBOelByb2dyZXNzRm9ybWF0dGVyIHtcbiAgICByZXR1cm4gdGhpcy5uekZvcm1hdCB8fCBkZWZhdWx0Rm9ybWF0dGVyO1xuICB9XG5cbiAgZ2V0IHN0YXR1cygpOiBOelByb2dyZXNzU3RhdHVzVHlwZSB7XG4gICAgcmV0dXJuIHRoaXMubnpTdGF0dXMgfHwgdGhpcy5pbmZlcnJlZFN0YXR1cztcbiAgfVxuXG4gIGdldCBzdHJva2VXaWR0aCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm56U3Ryb2tlV2lkdGggfHwgKHRoaXMubnpUeXBlID09PSAnbGluZScgJiYgdGhpcy5uelNpemUgIT09ICdzbWFsbCcgPyA4IDogNik7XG4gIH1cblxuICBnZXQgaXNDaXJjbGVTdHlsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uelR5cGUgPT09ICdjaXJjbGUnIHx8IHRoaXMubnpUeXBlID09PSAnZGFzaGJvYXJkJztcbiAgfVxuXG4gIHByaXZhdGUgY2FjaGVkU3RhdHVzOiBOelByb2dyZXNzU3RhdHVzVHlwZSA9ICdub3JtYWwnO1xuICBwcml2YXRlIGluZmVycmVkU3RhdHVzOiBOelByb2dyZXNzU3RhdHVzVHlwZSA9ICdub3JtYWwnO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHVibGljIG56Q29uZmlnU2VydmljZTogTnpDb25maWdTZXJ2aWNlLFxuICAgIHByaXZhdGUgZGlyZWN0aW9uYWxpdHk6IERpcmVjdGlvbmFsaXR5XG4gICkge31cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3Qge1xuICAgICAgbnpTdGVwcyxcbiAgICAgIG56R2FwUG9zaXRpb24sXG4gICAgICBuelN0cm9rZUxpbmVjYXAsXG4gICAgICBuelN0cm9rZUNvbG9yLFxuICAgICAgbnpHYXBEZWdyZWUsXG4gICAgICBuelR5cGUsXG4gICAgICBuelN0YXR1cyxcbiAgICAgIG56UGVyY2VudCxcbiAgICAgIG56U3VjY2Vzc1BlcmNlbnQsXG4gICAgICBuelN0cm9rZVdpZHRoXG4gICAgfSA9IGNoYW5nZXM7XG5cbiAgICBpZiAobnpTdGF0dXMpIHtcbiAgICAgIHRoaXMuY2FjaGVkU3RhdHVzID0gdGhpcy5uelN0YXR1cyB8fCB0aGlzLmNhY2hlZFN0YXR1cztcbiAgICB9XG5cbiAgICBpZiAobnpQZXJjZW50IHx8IG56U3VjY2Vzc1BlcmNlbnQpIHtcbiAgICAgIGNvbnN0IGZpbGxBbGwgPSBwYXJzZUludCh0aGlzLm56UGVyY2VudC50b1N0cmluZygpLCAxMCkgPj0gMTAwO1xuICAgICAgaWYgKGZpbGxBbGwpIHtcbiAgICAgICAgaWYgKChpc05vdE5pbCh0aGlzLm56U3VjY2Vzc1BlcmNlbnQpICYmIHRoaXMubnpTdWNjZXNzUGVyY2VudCEgPj0gMTAwKSB8fCB0aGlzLm56U3VjY2Vzc1BlcmNlbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMuaW5mZXJyZWRTdGF0dXMgPSAnc3VjY2Vzcyc7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaW5mZXJyZWRTdGF0dXMgPSB0aGlzLmNhY2hlZFN0YXR1cztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobnpTdGF0dXMgfHwgbnpQZXJjZW50IHx8IG56U3VjY2Vzc1BlcmNlbnQgfHwgbnpTdHJva2VDb2xvcikge1xuICAgICAgdGhpcy51cGRhdGVJY29uKCk7XG4gICAgfVxuXG4gICAgaWYgKG56U3Ryb2tlQ29sb3IpIHtcbiAgICAgIHRoaXMuc2V0U3Ryb2tlQ29sb3IoKTtcbiAgICB9XG5cbiAgICBpZiAobnpHYXBQb3NpdGlvbiB8fCBuelN0cm9rZUxpbmVjYXAgfHwgbnpHYXBEZWdyZWUgfHwgbnpUeXBlIHx8IG56UGVyY2VudCB8fCBuelN0cm9rZUNvbG9yIHx8IG56U3Ryb2tlQ29sb3IpIHtcbiAgICAgIHRoaXMuZ2V0Q2lyY2xlUGF0aHMoKTtcbiAgICB9XG5cbiAgICBpZiAobnpQZXJjZW50IHx8IG56U3RlcHMgfHwgbnpTdHJva2VXaWR0aCkge1xuICAgICAgdGhpcy5pc1N0ZXBzID0gdGhpcy5uelN0ZXBzID4gMDtcbiAgICAgIGlmICh0aGlzLmlzU3RlcHMpIHtcbiAgICAgICAgdGhpcy5nZXRTdGVwcygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubnpDb25maWdTZXJ2aWNlXG4gICAgICAuZ2V0Q29uZmlnQ2hhbmdlRXZlbnRGb3JDb21wb25lbnQoTlpfQ09ORklHX01PRFVMRV9OQU1FKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMudXBkYXRlSWNvbigpO1xuICAgICAgICB0aGlzLnNldFN0cm9rZUNvbG9yKCk7XG4gICAgICAgIHRoaXMuZ2V0Q2lyY2xlUGF0aHMoKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5kaXJlY3Rpb25hbGl0eS5jaGFuZ2U/LnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGRpcmVjdGlvbjogRGlyZWN0aW9uKSA9PiB7XG4gICAgICB0aGlzLmRpciA9IGRpcmVjdGlvbjtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZGlyID0gdGhpcy5kaXJlY3Rpb25hbGl0eS52YWx1ZTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlSWNvbigpOiB2b2lkIHtcbiAgICBjb25zdCByZXQgPSBzdGF0dXNJY29uTmFtZU1hcC5nZXQodGhpcy5zdGF0dXMpO1xuICAgIHRoaXMuaWNvbiA9IHJldCA/IHJldCArICh0aGlzLmlzQ2lyY2xlU3R5bGUgPyAnLW8nIDogJy1jaXJjbGUtZmlsbCcpIDogJyc7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHN0ZXAgcmVuZGVyIGNvbmZpZ3MuXG4gICAqL1xuICBwcml2YXRlIGdldFN0ZXBzKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBNYXRoLmZsb29yKHRoaXMubnpTdGVwcyAqICh0aGlzLm56UGVyY2VudCAvIDEwMCkpO1xuICAgIGNvbnN0IHN0ZXBXaWR0aCA9IHRoaXMubnpTaXplID09PSAnc21hbGwnID8gMiA6IDE0O1xuXG4gICAgY29uc3Qgc3RlcHMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uelN0ZXBzOyBpKyspIHtcbiAgICAgIGxldCBjb2xvcjtcbiAgICAgIGlmIChpIDw9IGN1cnJlbnQgLSAxKSB7XG4gICAgICAgIGNvbG9yID0gdGhpcy5uelN0cm9rZUNvbG9yO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RlcFN0eWxlID0ge1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGAke2NvbG9yfWAsXG4gICAgICAgIHdpZHRoOiBgJHtzdGVwV2lkdGh9cHhgLFxuICAgICAgICBoZWlnaHQ6IGAke3RoaXMuc3Ryb2tlV2lkdGh9cHhgXG4gICAgICB9O1xuICAgICAgc3RlcHMucHVzaChzdGVwU3R5bGUpO1xuICAgIH1cblxuICAgIHRoaXMuc3RlcHMgPSBzdGVwcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgcGF0aHMgd2hlbiB0aGUgdHlwZSBpcyBjaXJjbGUgb3IgZGFzaGJvYXJkLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRDaXJjbGVQYXRocygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNDaXJjbGVTdHlsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlcyA9IGlzTm90TmlsKHRoaXMubnpTdWNjZXNzUGVyY2VudCkgPyBbdGhpcy5uelN1Y2Nlc3NQZXJjZW50ISwgdGhpcy5uelBlcmNlbnRdIDogW3RoaXMubnpQZXJjZW50XTtcblxuICAgIC8vIENhbGN1bGF0ZSBzaGFyZWQgc3R5bGVzLlxuICAgIGNvbnN0IHJhZGl1cyA9IDUwIC0gdGhpcy5zdHJva2VXaWR0aCAvIDI7XG4gICAgY29uc3QgZ2FwUG9zaXRpb24gPSB0aGlzLm56R2FwUG9zaXRpb24gfHwgKHRoaXMubnpUeXBlID09PSAnY2lyY2xlJyA/ICd0b3AnIDogJ2JvdHRvbScpO1xuICAgIGNvbnN0IGxlbiA9IE1hdGguUEkgKiAyICogcmFkaXVzO1xuICAgIGNvbnN0IGdhcERlZ3JlZSA9IHRoaXMubnpHYXBEZWdyZWUgfHwgKHRoaXMubnpUeXBlID09PSAnY2lyY2xlJyA/IDAgOiA3NSk7XG5cbiAgICBsZXQgYmVnaW5Qb3NpdGlvblggPSAwO1xuICAgIGxldCBiZWdpblBvc2l0aW9uWSA9IC1yYWRpdXM7XG4gICAgbGV0IGVuZFBvc2l0aW9uWCA9IDA7XG4gICAgbGV0IGVuZFBvc2l0aW9uWSA9IHJhZGl1cyAqIC0yO1xuXG4gICAgc3dpdGNoIChnYXBQb3NpdGlvbikge1xuICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgIGJlZ2luUG9zaXRpb25YID0gLXJhZGl1cztcbiAgICAgICAgYmVnaW5Qb3NpdGlvblkgPSAwO1xuICAgICAgICBlbmRQb3NpdGlvblggPSByYWRpdXMgKiAyO1xuI