kre-form
Version:
本项目由 Angular8+ 编写的表单设计器和表单应用,所有的配置都是 JSON 结构体组成,PC 端是基于 ANT 组件库封装
515 lines • 54.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Output, EventEmitter, Input, } from "@angular/core";
import { NzModalService } from "ng-zorro-antd/modal";
import { NzMessageService } from "ng-zorro-antd/message";
import * as _ from "lodash";
import { ChartsService } from "../../service/charts.service";
import { ChartConditionService } from "../../service/chart-condition.service";
import { ModalColorComponent } from "../modal-color/modal-color.component";
// import { stringify } from "querystring";
export class EchartOptionsDomComponent {
/**
* @param {?} chartConditionService
* @param {?} chartsService
* @param {?} modalService
* @param {?} message
*/
constructor(chartConditionService, chartsService, modalService, message) {
this.chartConditionService = chartConditionService;
this.chartsService = chartsService;
this.modalService = modalService;
this.message = message;
this.echartOptionsChange = new EventEmitter(); // echart只是内部参数稍做变化
// echart只是内部参数稍做变化
this.echartShapeChange = new EventEmitter(); // echart改变形状
// echart改变形状
this.chartConditionChange = new EventEmitter();
this.chartsType = [
{ title: "指标", type: "data", icon: "" },
{ title: "透视", type: "data", icon: "" },
{ title: "柱状", type: "bar", icon: "" },
{ title: "条形", type: "barY", icon: "" },
{ title: "折线", type: "line", icon: "" },
{ title: "雷达", type: "radar", icon: "" },
{ title: "饼状", type: "pie", icon: "" },
{ title: "地图", type: "map", icon: "" },
];
this.childChartsType = [
{
type: "line",
title: "折线",
children: [
{ title: "折线", type: "line", icon: "" },
{ title: "面积", type: "area", icon: "" },
],
},
{
type: "pie",
title: "饼状",
children: [
{ title: "饼状", type: "pie", icon: "" },
{ title: "环形", type: "doughnut", icon: "" },
],
},
];
this.input = {
nzTabPosition: "setting",
lineSmooth: "0",
xAxisrRotate: "0",
axisLabelInterval: false,
title: "",
yAxisMax: null,
yAxisMin: null,
dataLabeChecked: true,
isLegend: true,
legend: "top",
currentColorType: "1",
inside: 40,
outside: 50,
titleX: 0,
titleY: 0,
};
this.selectedValue = "lucy";
}
/**
* @return {?}
*/
ngOnInit() {
this.formatterPercent = (/**
* @param {?} value
* @return {?}
*/
(value) => `${value} %`);
this.parserPercent = (/**
* @param {?} value
* @return {?}
*/
(value) => value.replace(" %", ""));
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
for (const propName in changes) {
/** @type {?} */
const chng = changes[propName];
if (propName === "chartCondition" && chng.currentValue) {
/** @type {?} */
const option = this.getChartOption(chng.currentValue.type);
this.lineSmoothChange();
this.xAxisrRotateChange();
this.intervalChange();
this.isLegendShow();
this.legendChange();
this.titleChange();
this.yAxisMaxBlur();
this.yAxisMinBlur();
this.radiusChange();
this.echartShapeChange.emit({
chartOption: option,
});
this.currentChildChartsType = _.find(this.childChartsType, {
type: chng.currentValue.charttype,
});
this.currentChartType = chng.currentValue.type;
}
}
}
/**
* @param {?} type
* @return {?}
*/
choiceChart(type) {
if (this.currentChartType == type)
return;
if (this.echartsList.length <= 0) {
this.message.create("error", "请先选择数据");
return;
}
if (type === "data")
return;
this.currentChildChartsType = _.find(this.childChartsType, { type: type });
if (!this.currentChildChartsType) {
this.changeOptions(type);
}
}
/**
* @param {?} type
* @return {?}
*/
choiceSubChart(type) {
if (this.currentChartType == type)
return;
this.changeOptions(type);
}
/**
* @param {?} type
* @return {?}
*/
changeOptions(type) {
if (this.currentChartType) {
this.modalService.confirm({
nzTitle: "更改图形",
nzContent: "更改图形将清空当前图形配置,是否确认修改?",
nzOnOk: (/**
* @return {?}
*/
() => {
this.choiceType(type);
}),
nzOnCancel: (/**
* @return {?}
*/
() => { }),
});
}
else {
this.choiceType(type);
}
}
/**
* @param {?} type
* @return {?}
*/
choiceType(type) {
/** @type {?} */
const condition = this.chartConditionService.chartCondition();
this.chartCondition = _.find(condition, {
type: type,
});
this.chartCondition.input = _.cloneDeep(this.input);
this.chartConditionChange.emit(this.chartCondition);
this.currentChartType = type;
}
/**
* @param {?} type
* @return {?}
*/
getChartOption(type) {
/** @type {?} */
let options;
if (type === "pie") {
options = this.chartsService.pieOptions();
}
else if (type === "doughnut") {
options = this.chartsService.doughnutOptions();
}
else if (type === "radar") {
options = this.chartsService.radarOptions();
}
else if (type === "bar") {
options = this.chartsService.barOptions();
}
else if (type === "barY") {
options = this.chartsService.barYOptions();
}
else if (type === "area") {
options = this.chartsService.areaOptions();
}
else if (type === "line") {
options = this.chartsService.lineOptions();
}
else {
options = {
series: [
{
type: type,
},
],
};
}
this.chartsService.options.color = this.totalColor();
return options;
}
/**
* @param {?=} change
* @return {?}
*/
lineSmoothChange(change) {
/** @type {?} */
let options = this.chartsService.options;
options.series.forEach((/**
* @param {?} item
* @return {?}
*/
(item) => {
if (item.type === "line") {
item["smooth"] = Number(this.chartCondition.input.lineSmooth);
}
}));
if (change) {
this.echartOptionsChange.emit(options);
}
}
/**
* @param {?=} change
* @return {?}
*/
xAxisrRotateChange(change) {
/** @type {?} */
let options = this.chartsService.options;
if (options && options.xAxis) {
if (options.xAxis.axisLabel) {
}
else {
options.xAxis.axisLabel = {};
}
Object.assign(options.xAxis.axisLabel, {
rotate: this.chartCondition.input.xAxisrRotate,
});
if (change) {
this.echartOptionsChange.emit(options);
}
}
}
/**
* @param {?=} change
* @return {?}
*/
intervalChange(change) {
/** @type {?} */
let options = this.chartsService.options;
if (options.xAxis) {
options.xAxis.axisLabel = options.xAxis.axisLabel
? options.xAxis.axisLabel
: {};
Object.assign(options.xAxis.axisLabel, {
interval: this.chartCondition.input.axisLabelInterval ? 0 : "auto",
});
if (change) {
this.echartOptionsChange.emit(options);
}
}
}
/**
* @param {?=} change
* @return {?}
*/
titleChange(change) {
/** @type {?} */
let options = this.chartsService.options;
options.title = {
text: this.chartCondition.input.title,
left: this.chartCondition.input.titleX + "%",
top: this.chartCondition.input.titleY + "%",
textStyle: {
fontSize: this.chartCondition.input.titleSize,
},
};
if (typeof change !== "undefined") {
this.echartOptionsChange.emit(options);
}
}
/**
* @param {?=} change
* @return {?}
*/
yAxisMaxBlur(change) {
/** @type {?} */
let options = this.chartsService.options;
if (options.yAxis) {
options.yAxis.max = this.chartCondition.input.yAxisMax;
if (change) {
this.echartOptionsChange.emit(options);
}
}
}
/**
* @param {?=} change
* @return {?}
*/
yAxisMinBlur(change) {
/** @type {?} */
let options = this.chartsService.options;
if (options.yAxis) {
options.yAxis.min = this.chartCondition.input.yAxisMin;
if (change) {
this.echartOptionsChange.emit(options);
}
}
}
/**
* @param {?=} change
* @return {?}
*/
isLegendShow(change) {
/** @type {?} */
let options = this.chartsService.options;
options["legend"] = {
show: this.chartCondition.input.isLegend ? true : false,
[this.chartCondition.input.legend]: "0",
};
if (change) {
this.echartOptionsChange.emit(options);
}
}
/**
* @param {?=} change
* @return {?}
*/
legendChange(change) {
/** @type {?} */
let options = this.chartsService.options;
options["legend"] = {
[this.chartCondition.input.legend]: "0",
show: this.chartCondition.input.isLegend,
};
if (change) {
this.echartOptionsChange.emit(options);
}
}
/**
* @param {?=} change
* @return {?}
*/
radiusChange(change) {
/** @type {?} */
let options = this.chartsService.options;
if (!options.series[0].radius ||
Object.prototype.toString.call(options.series[0].radius) !==
"[object Array]")
return;
/** @type {?} */
let inside = this.chartCondition.input.inside + "%";
/** @type {?} */
let outside = this.chartCondition.input.outside + "%";
options.series[0].radius.splice(0, 1, inside);
options.series[0].radius.splice(1, 1, outside);
if (change) {
this.echartOptionsChange.emit(options);
}
}
/**
* @return {?}
*/
changeColor() {
/** @type {?} */
const modal = this.modalService.create({
nzContent: ModalColorComponent,
nzComponentParams: {
echartsList: this.echartsList,
colorList: this.colorList,
currentColorType: this.chartCondition.input.currentColorType,
},
nzOnOk: (/**
* @param {?} componentInstance
* @return {?}
*/
(componentInstance) => {
this.chartCondition.input.currentColorType =
componentInstance.currentColorType;
// if (
// !(
// this.currentChartType == "doughnut" ||
// this.currentChartType == "pie"
// )
// ) {
// Object.assign(this.chartsService.options, {
// color: this.totalColor(),
// visualMap: {
// show: false,
// categories: _.map(componentInstance.echartsColorList, "value"),
// inRange: {
// color: _.map(componentInstance.echartsColorList, "color"),
// },
// },
// });
// } else {
// this.chartsService.options.color = this.totalColor();
// }
this.chartsService.options.color = this.totalColor();
this.echartOptionsChange.emit(this.chartsService.options);
}),
});
}
/**
* @return {?}
*/
totalColor() {
return this.colorList[Number(this.chartCondition.input.currentColorType) - 1];
}
/**
* @return {?}
*/
changeCurrentColor() {
this.chartsService.options.color = this.totalColor();
this.echartOptionsChange.emit(this.chartsService.options);
}
}
EchartOptionsDomComponent.decorators = [
{ type: Component, args: [{
selector: "echart-options-dom",
template: "<h2>\u56FE\u6807\u7C7B\u578B</h2>\n<div class=\"chart-wrap\">\n <ng-container *ngFor=\"let item of chartsType\">\n <div (click)=\"choiceChart(item.type)\" class=\"chart-type\">\n {{ item.title }}\n </div>\n </ng-container>\n</div>\n<ng-container *ngIf=\"currentChildChartsType\">\n <div>{{ currentChildChartsType.title }}\u7C7B\u578B</div>\n <div class=\"chart-wrap\">\n <ng-container *ngFor=\"let item of currentChildChartsType.children\">\n <div (click)=\"choiceSubChart(item.type)\" class=\"chart-type\">\n {{ item.title }}\n </div>\n </ng-container>\n </div>\n</ng-container>\n<ng-container *ngIf=\"chartCondition\">\n <nz-radio-group\n [(ngModel)]=\"chartCondition.input.nzTabPosition\"\n name=\"nzTabPosition\"\n >\n <label nz-radio-button [nzValue]=\"'setting'\">\u529F\u80FD\u914D\u7F6E</label>\n <label nz-radio-button [nzValue]=\"'style'\">\u7EC4\u4EF6\u6837\u5F0F</label>\n </nz-radio-group>\n\n <div *ngIf=\"chartCondition.input.nzTabPosition === 'setting'\">\n <div *ngIf=\"chartCondition?.condition\">\n <!-- \u6298\u7EBF\u56FE \u9762\u79EF\u56FE -->\n <ng-container *ngIf=\"chartCondition?.condition.lineStyle\">\n <h4>\u7EBF\u6761\u6837\u5F0F</h4>\n <div>\n <nz-radio-group\n name=\"lineSmooth\"\n [(ngModel)]=\"chartCondition.input.lineSmooth\"\n (ngModelChange)=\"lineSmoothChange('event')\"\n >\n <label nz-radio nzValue=\"0\">\u666E\u901A</label>\n <label nz-radio nzValue=\"1\">\u66F2\u7EBF</label>\n </nz-radio-group>\n </div>\n <!-- <div>\n \u6807\u8BB0\u70B9 <label nz-checkbox [(ngModel)]=\"checked\">\u663E\u793A\u6570\u636E\u6807\u8BB0\u70B9</label>\n </div> -->\n <hr />\n </ng-container>\n <ng-container *ngIf=\"chartCondition?.condition.x\">\n <h4>\u5750\u6807x\u8F74</h4>\n \u6807\u7B7E\u6587\u5B57\u663E\u793A\u65B9\u5411\n <nz-select\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"chartCondition.input.xAxisrRotate\"\n (ngModelChange)=\"xAxisrRotateChange($event)\"\n nzAllowClear\n nzPlaceHolder=\"Choose\"\n >\n <nz-option nzValue=\"0\" nzLabel=\"\u6A2A\u5411\"></nz-option>\n <nz-option nzValue=\"90\" nzLabel=\"\u7AD6\u5411\"></nz-option>\n <nz-option nzValue=\"30\" nzLabel=\"\u5DE6\u503E\u659C\"></nz-option>\n <nz-option nzValue=\"-30\" nzLabel=\"\u53F3\u503E\u659C\"></nz-option>\n </nz-select>\n\n <div>\n <label\n nz-checkbox\n name=\"axisLabelInterval\"\n [(ngModel)]=\"chartCondition.input.axisLabelInterval\"\n (ngModelChange)=\"intervalChange('event')\"\n >\u5F3A\u5236\u663E\u793A\u6240\u6709\u6807\u7B7E</label\n >\n </div>\n\n <hr />\n </ng-container>\n <h4>\u6807\u9898</h4>\n <!-- <label\n nz-checkbox\n name=\"dataLabeChecked\"\n [(ngModel)]=\"chartCondition.condition.title\"\n (ngModelChange)=\"isShowTitle($event)\"\n >\u663E\u793A\u6807\u9898</label\n > -->\n <ng-container>\n <input\n nz-input\n placeholder=\"\u6807\u9898\"\n name=\"title\"\n [(ngModel)]=\"chartCondition.input.title\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"titleChange($event)\"\n />\n\n <div>\n <span class=\"label\">\u6807\u9898\u5750\u6807X\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.titleX\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [nzFormatter]=\"formatterPercent\"\n [nzParser]=\"parserPercent\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"titleChange($event)\"\n ></nz-input-number>\n </div>\n <div>\n <span class=\"label\">\u6807\u9898\u5750\u6807Y\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.titleY\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [nzFormatter]=\"formatterPercent\"\n [nzParser]=\"parserPercent\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"titleChange($event)\"\n ></nz-input-number>\n </div>\n <div>\n <span class=\"label\">\u6807\u9898\u5927\u5C0F\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.titleSize\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"titleChange($event)\"\n ></nz-input-number>\n </div>\n </ng-container>\n\n <hr />\n <ng-container *ngIf=\"chartCondition?.condition.y\">\n <h4>\u5750\u6807y\u8F74</h4>\n\n <input\n nz-input\n placeholder=\"\u6700\u5927\u503C\"\n name=\"yAxisMax\"\n [(ngModel)]=\"chartCondition.input.yAxisMax\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"yAxisMaxBlur($event)\"\n />\n <input\n nz-input\n placeholder=\"\u6700\u5C0F\u503C\"\n name=\"yAxisMin\"\n [(ngModel)]=\"chartCondition.input.yAxisMin\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"yAxisMinBlur($event)\"\n />\n <hr />\n </ng-container>\n\n <ng-container *ngIf=\"chartCondition?.condition.dataLabe\">\n <h4>\u6570\u636E\u6807\u7B7E</h4>\n <label\n nz-checkbox\n name=\"dataLabeChecked\"\n [(ngModel)]=\"chartCondition.input.dataLabeChecked\"\n >\u663E\u793A\u6570\u636E\u6807\u7B7E</label\n >\n <hr />\n </ng-container>\n <ng-container *ngIf=\"chartCondition.condition.radius\">\n <h4>\u534A\u5F84\u8BBE\u7F6E</h4>\n <div>\n <span class=\"label\">\u5185\u5F84\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.inside\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [nzFormatter]=\"formatterPercent\"\n [nzParser]=\"parserPercent\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"radiusChange($event)\"\n ></nz-input-number>\n </div>\n <div>\n <span class=\"label\">\u5916\u5F84\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.outside\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [nzFormatter]=\"formatterPercent\"\n [nzParser]=\"parserPercent\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"radiusChange($event)\"\n ></nz-input-number>\n </div>\n <hr />\n </ng-container>\n <ng-container *ngIf=\"chartCondition?.condition.legend\">\n <h4>\u56FE\u4F8B</h4>\n <label\n nz-checkbox\n name=\"isLegend\"\n [(ngModel)]=\"chartCondition.input.isLegend\"\n (ngModelChange)=\"isLegendShow('event')\"\n >\u56FE\u4F8B\u663E\u793A</label\n >\n <div>\n \u56FE\u4F8B\u663E\u793A\u5728\u56FE\u8868\n <nz-select\n name=\"legend\"\n [(ngModel)]=\"chartCondition.input.legend\"\n (ngModelChange)=\"legendChange($event)\"\n nzAllowClear\n nzPlaceHolder=\"Choose\"\n >\n <nz-option nzValue=\"bottom\" nzLabel=\"\u5E95\u90E8\"></nz-option>\n <nz-option nzValue=\"top\" nzLabel=\"\u5934\u90E8\"></nz-option>\n </nz-select>\n </div>\n <hr />\n </ng-container>\n\n <h4>\u6570\u636E\u9884\u8B66</h4>\n <div>\u6DFB\u52A0\u9884\u8B66</div>\n </div>\n </div>\n <div *ngIf=\"chartCondition.input.nzTabPosition === 'style'\">\n <h4>\u6574\u4F53\u6837\u5F0F</h4>\n <div>\u80CC\u666F</div>\n <div>\u6807\u9898\u6837\u5F0F</div>\n\n <hr />\n <h4>\u56FE\u8868\u914D\u8272</h4>\n\n <div class=\"select-color\" (click)=\"changeColor()\">\n \u914D\u8272\u65B9\u6848 {{ chartCondition.input.currentColorType\n }}<i class=\"icon-KT-Close\"></i>\n </div>\n\n <nz-select\n [(ngModel)]=\"chartCondition.input.currentColorType\"\n (ngModelChange)=\"changeCurrentColor()\"\n >\n <nz-option\n *ngFor=\"let item of colorList; let i = index\"\n nzCustomContent\n nzLabel=\"\u914D\u8272\u65B9\u6848{{ i + 1 }}\"\n nzValue=\"{{ i + 1 }}\"\n >\n <div>\n <ng-container *ngFor=\"let element of item; let ii = index\">\n <ng-container *ngIf=\"ii < 9\">\n <span [ngStyle]=\"{ 'background-color': element, color: element }\">\n -\n </span>\n </ng-container>\n </ng-container>\n \u914D\u8272\u65B9\u6848{{ i + 1 }}\n </div>\n </nz-option>\n </nz-select>\n </div>\n</ng-container>\n",
styles: [":host{padding:10px 20px;border-left:1px solid #e9e9e9}:host .chart-wrap{display:flex;flex-wrap:wrap}:host .chart-wrap .chart-type{width:44px;height:44px;line-height:44px;text-align:center;cursor:pointer;border:2px solid #0db3a6;vertical-align:middle;margin:0 10px 10px 0}:host .select-color{border:1px solid #d9d9d9;border-radius:4px;height:32px;padding:4px 11px;background-color:#fff;display:flex;justify-content:space-between;align-items:center}:host .ant-input,:host .ant-input-number{margin-bottom:5px}:host span.label{width:80px;display:inline-block}"]
}] }
];
/** @nocollapse */
EchartOptionsDomComponent.ctorParameters = () => [
{ type: ChartConditionService },
{ type: ChartsService },
{ type: NzModalService },
{ type: NzMessageService }
];
EchartOptionsDomComponent.propDecorators = {
colorList: [{ type: Input }],
echartsList: [{ type: Input }],
chartCondition: [{ type: Input }],
echartOptionsChange: [{ type: Output }],
echartShapeChange: [{ type: Output }],
chartConditionChange: [{ type: Output }]
};
if (false) {
/** @type {?} */
EchartOptionsDomComponent.prototype.colorList;
/** @type {?} */
EchartOptionsDomComponent.prototype.echartsList;
/** @type {?} */
EchartOptionsDomComponent.prototype.chartCondition;
/** @type {?} */
EchartOptionsDomComponent.prototype.echartOptionsChange;
/** @type {?} */
EchartOptionsDomComponent.prototype.echartShapeChange;
/** @type {?} */
EchartOptionsDomComponent.prototype.chartConditionChange;
/** @type {?} */
EchartOptionsDomComponent.prototype.chartsType;
/** @type {?} */
EchartOptionsDomComponent.prototype.childChartsType;
/** @type {?} */
EchartOptionsDomComponent.prototype.currentChildChartsType;
/** @type {?} */
EchartOptionsDomComponent.prototype.input;
/** @type {?} */
EchartOptionsDomComponent.prototype.selectedValue;
/** @type {?} */
EchartOptionsDomComponent.prototype.currentChartType;
/** @type {?} */
EchartOptionsDomComponent.prototype.formatterPercent;
/** @type {?} */
EchartOptionsDomComponent.prototype.parserPercent;
/**
* @type {?}
* @private
*/
EchartOptionsDomComponent.prototype.chartConditionService;
/**
* @type {?}
* @private
*/
EchartOptionsDomComponent.prototype.chartsService;
/**
* @type {?}
* @private
*/
EchartOptionsDomComponent.prototype.modalService;
/**
* @type {?}
* @private
*/
EchartOptionsDomComponent.prototype.message;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNoYXJ0LW9wdGlvbnMtZG9tLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BrcmUtZm9ybS9hYmMvIiwic291cmNlcyI6WyJsaWIvYm9hcmQvY29tcG9uZW50cy9lY2hhcnQtb3B0aW9ucy1kb20vZWNoYXJ0LW9wdGlvbnMtZG9tLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxNQUFNLEVBQ04sWUFBWSxFQUNaLEtBQUssR0FHTixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQWMsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDekQsT0FBTyxLQUFLLENBQUMsTUFBTSxRQUFRLENBQUM7QUFFNUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzdELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDOztBQVEzRSxNQUFNLE9BQU8seUJBQXlCOzs7Ozs7O0lBNkRwQyxZQUNVLHFCQUE0QyxFQUM1QyxhQUE0QixFQUM1QixZQUE0QixFQUM1QixPQUF5QjtRQUh6QiwwQkFBcUIsR0FBckIscUJBQXFCLENBQXVCO1FBQzVDLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLGlCQUFZLEdBQVosWUFBWSxDQUFnQjtRQUM1QixZQUFPLEdBQVAsT0FBTyxDQUFrQjtRQTVEbkMsd0JBQW1CLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQyxDQUFDLG1CQUFtQjs7UUFFN0Qsc0JBQWlCLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQyxDQUFDLGFBQWE7O1FBQzNDLHlCQUFvQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDcEQsZUFBVSxHQUFHO1lBQ1gsRUFBRSxLQUFLLEVB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LE9BQU8sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3JELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM1RCxDQUFDOzs7WUFsVkYsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxvQkFBb0I7Z0JBQzlCLDZtU0FBa0Q7O2FBRW5EOzs7O1lBUlEscUJBQXFCO1lBRHJCLGFBQWE7WUFKRCxjQUFjO1lBQzFCLGdCQUFnQjs7O3dCQWN0QixLQUFLOzBCQUNMLEtBQUs7NkJBQ0wsS0FBSztrQ0FDTCxNQUFNO2dDQUVOLE1BQU07bUNBRU4sTUFBTTs7OztJQVBQLDhDQUF3Qjs7SUFDeEIsZ0RBQTBCOztJQUMxQixtREFBNkI7O0lBQzdCLHdEQUN5Qzs7SUFDekMsc0RBQ3VDOztJQUN2Qyx5REFBb0Q7O0lBQ3BELCtDQVNFOztJQUNGLG9EQWlCRTs7SUFDRiwyREFBNEI7O0lBQzVCLDBDQWdCRTs7SUFFRixrREFBdUI7O0lBQ3ZCLHFEQUF5Qjs7SUFDekIscURBQXNCOztJQUN0QixrREFBbUI7Ozs7O0lBR2pCLDBEQUFvRDs7Ozs7SUFDcEQsa0RBQW9DOzs7OztJQUNwQyxpREFBb0M7Ozs7O0lBQ3BDLDRDQUFpQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIEFmdGVyVmlld0luaXQsXG4gIE9uQ2hhbmdlcyxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcblxuaW1wb3J0IHsgTnpNb2RhbFJlZiwgTnpNb2RhbFNlcnZpY2UgfSBmcm9tIFwibmctem9ycm8tYW50ZC9tb2RhbFwiO1xuaW1wb3J0IHsgTnpNZXNzYWdlU2VydmljZSB9IGZyb20gXCJuZy16b3Jyby1hbnRkL21lc3NhZ2VcIjtcbmltcG9ydCAqIGFzIF8gZnJvbSBcImxvZGFzaFwiO1xuXG5pbXBvcnQgeyBDaGFydHNTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uL3NlcnZpY2UvY2hhcnRzLnNlcnZpY2VcIjtcbmltcG9ydCB7IENoYXJ0Q29uZGl0aW9uU2VydmljZSB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlL2NoYXJ0LWNvbmRpdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBNb2RhbENvbG9yQ29tcG9uZW50IH0gZnJvbSBcIi4uL21vZGFsLWNvbG9yL21vZGFsLWNvbG9yLmNvbXBvbmVudFwiO1xuLy8gaW1wb3J0IHsgc3RyaW5naWZ5IH0gZnJvbSBcInF1ZXJ5c3RyaW5nXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJlY2hhcnQtb3B0aW9ucy1kb21cIixcbiAgdGVtcGxhdGVVcmw6IFwiLi9lY2hhcnQtb3B0aW9ucy1kb20uY29tcG9uZW50Lmh0bWxcIixcbiAgc3R5bGVVcmxzOiBbXCIuL2VjaGFydC1vcHRpb25zLWRvbS5jb21wb25lbnQubGVzc1wiXSxcbn0pXG5leHBvcnQgY2xhc3MgRWNoYXJ0T3B0aW9uc0RvbUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgY29sb3JMaXN0OiBhbnk7XG4gIEBJbnB1dCgpIGVjaGFydHNMaXN0OiBhbnk7XG4gIEBJbnB1dCgpIGNoYXJ0Q29uZGl0aW9uOiBhbnk7XG4gIEBPdXRwdXQoKVxuICBlY2hhcnRPcHRpb25zQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpOyAvLyBlY2hhcnTlj6rmmK/lhoXpg6jlj4LmlbDnqI3lgZrlj5jljJZcbiAgQE91dHB1dCgpXG4gIGVjaGFydFNoYXBlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpOyAvLyBlY2hhcnTmlLnlj5jlvaLnirZcbiAgQE91dHB1dCgpIGNoYXJ0Q29uZGl0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBjaGFydHNUeXBlID0gW1xuICAgIHsgdGl0bGU6IFwi5oyH5qCHXCIsIHR5cGU6IFwiZGF0YVwiLCBpY29uOiBcIlwiIH0sXG4gICAgeyB0aXRsZTogXCLpgI/op4ZcIiwgdHlwZTogXCJkYXRhXCIsIGljb246IFwiXCIgfSxcbiAgICB7IHRpdGxlOiBcIuafseeKtlwiLCB0eXBlOiBcImJhclwiLCBpY29uOiBcIlwiIH0sXG4gICAgeyB0aXRsZTogXCLmnaHlvaJcIiwgdHlwZTogXCJiYXJZXCIsIGljb246IFwiXCIgfSxcbiAgICB7IHRpdGxlOiBcIuaKmOe6v1wiLCB0eXBlOiBcImxpbmVcIiwgaWNvbjogXCJcIiB9LFxuICAgIHsgdGl0bGU6IFwi6Zu36L6+XCIsIHR5cGU6IFwicmFkYXJcIiwgaWNvbjogXCJcIiB9LFxuICAgIHsgdGl0bGU6IFwi6aW854q2XCIsIHR5cGU6IFwicGllXCIsIGljb246IFwiXCIgfSxcbiAgICB7IHRpdGxlOiBcIuWcsOWbvlwiLCB0eXBlOiBcIm1hcFwiLCBpY29uOiBcIlwiIH0sXG4gIF07XG4gIGNoaWxkQ2hhcnRzVHlwZSA9IFtcbiAgICB7XG4gICAgICB0eXBlOiBcImxpbmVcIixcbiAgICAgIHRpdGxlOiBcIuaKmOe6v1wiLFxuICAgICAgY2hpbGRyZW46IFtcbiAgICAgICAgeyB0aXRsZTogXCLmipjnur9cIiwgdHlwZTogXCJsaW5lXCIsIGljb246IFwiXCIgfSxcbiAgICAgICAgeyB0aXRsZTogXCLpnaLnp69cIiwgdHlwZTogXCJhcmVhXCIsIGljb246IFwiXCIgfSxcbiAgICAgIF0sXG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiBcInBpZVwiLFxuICAgICAgdGl0bGU6IFwi6aW854q2XCIsXG4gICAgICBjaGlsZHJlbjogW1xuICAgICAgICB7IHRpdGxlOiBcIumlvOeKtlwiLCB0eXBlOiBcInBpZVwiLCBpY29uOiBcIlwiIH0sXG4gICAgICAgIHsgdGl0bGU6IFwi546v5b2iXCIsIHR5cGU6IFwiZG91Z2hudXRcIiwgaWNvbjogXCJcIiB9LFxuICAgICAgXSxcbiAgICB9LFxuICBdO1xuICBjdXJyZW50Q2hpbGRDaGFydHNUeXBlOiBhbnk7XG4gIGlucHV0ID0ge1xuICAgIG56VGFiUG9zaXRpb246IFwic2V0dGluZ1wiLFxuICAgIGxpbmVTbW9vdGg6IFwiMFwiLFxuICAgIHhBeGlzclJvdGF0ZTogXCIwXCIsXG4gICAgYXhpc0xhYmVsSW50ZXJ2YWw6IGZhbHNlLFxuICAgIHRpdGxlOiBcIlwiLFxuICAgIHlBeGlzTWF4OiBudWxsLFxuICAgIHlBeGlzTWluOiBudWxsLFxuICAgIGRhdGFMYWJlQ2hlY2tlZDogdHJ1ZSxcbiAgICBpc0xlZ2VuZDogdHJ1ZSxcbiAgICBsZWdlbmQ6IFwidG9wXCIsXG4gICAgY3VycmVudENvbG9yVHlwZTogXCIxXCIsXG4gICAgaW5zaWRlOiA0MCxcbiAgICBvdXRzaWRlOiA1MCxcbiAgICB0aXRsZVg6IDAsXG4gICAgdGl0bGVZOiAwLFxuICB9O1xuXG4gIHNlbGVjdGVkVmFsdWUgPSBcImx1Y3lcIjtcbiAgY3VycmVudENoYXJ0VHlwZTogc3RyaW5nO1xuICBmb3JtYXR0ZXJQZXJjZW50OiBhbnk7XG4gIHBhcnNlclBlcmNlbnQ6IGFueTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNoYXJ0Q29uZGl0aW9uU2VydmljZTogQ2hhcnRDb25kaXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgY2hhcnRzU2VydmljZTogQ2hhcnRzU2VydmljZSxcbiAgICBwcml2YXRlIG1vZGFsU2VydmljZTogTnpNb2RhbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBtZXNzYWdlOiBOek1lc3NhZ2VTZXJ2aWNlXG4gICkge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmZvcm1hdHRlclBlcmNlbnQgPSAodmFsdWU6IG51bWJlcikgPT4gYCR7dmFsdWV9ICVgO1xuICAgIHRoaXMucGFyc2VyUGVyY2VudCA9ICh2YWx1ZTogc3RyaW5nKSA9PiB2YWx1ZS5yZXBsYWNlKFwiICVcIiwgXCJcIik7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBhbnkpIHtcbiAgICBmb3IgKGNvbnN0IHByb3BOYW1lIGluIGNoYW5nZXMpIHtcbiAgICAgIGNvbnN0IGNobmcgPSBjaGFuZ2VzW3Byb3BOYW1lXTtcbiAgICAgIGlmIChwcm9wTmFtZSA9PT0gXCJjaGFydENvbmRpdGlvblwiICYmIGNobmcuY3VycmVudFZhbHVlKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuZ2V0Q2hhcnRPcHRpb24oY2huZy5jdXJyZW50VmFsdWUudHlwZSk7XG4gICAgICAgIHRoaXMubGluZVNtb290aENoYW5nZSgpO1xuICAgICAgICB0aGlzLnhBeGlzclJvdGF0ZUNoYW5nZSgpO1xuICAgICAgICB0aGlzLmludGVydmFsQ2hhbmdlKCk7XG4gICAgICAgIHRoaXMuaXNMZWdlbmRTaG93KCk7XG4gICAgICAgIHRoaXMubGVnZW5kQ2hhbmdlKCk7XG4gICAgICAgIHRoaXMudGl0bGVDaGFuZ2UoKTtcbiAgICAgICAgdGhpcy55QXhpc01heEJsdXIoKTtcbiAgICAgICAgdGhpcy55QXhpc01pbkJsdXIoKTtcbiAgICAgICAgdGhpcy5yYWRpdXNDaGFuZ2UoKTtcbiAgICAgICAgdGhpcy5lY2hhcnRTaGFwZUNoYW5nZS5lbWl0KHtcbiAgICAgICAgICBjaGFydE9wdGlvbjogb3B0aW9uLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jdXJyZW50Q2hpbGRDaGFydHNUeXBlID0gXy5maW5kKHRoaXMuY2hpbGRDaGFydHNUeXBlLCB7XG4gICAgICAgICAgdHlwZTogY2huZy5jdXJyZW50VmFsdWUuY2hhcnR0eXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jdXJyZW50Q2hhcnRUeXBlID0gY2huZy5jdXJyZW50VmFsdWUudHlwZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjaG9pY2VDaGFydCh0eXBlOiBhbnkpIHtcbiAgICBpZiAodGhpcy5jdXJyZW50Q2hhcnRUeXBlID09IHR5cGUpIHJldHVybjtcbiAgICBpZiAodGhpcy5lY2hhcnRzTGlzdC5sZW5ndGggPD0gMCkge1xuICAgICAgdGhpcy5tZXNzYWdlLmNyZWF0ZShcImVycm9yXCIsIFwi6K+35YWI6YCJ5oup5pWw5o2uXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gXCJkYXRhXCIpIHJldHVybjtcblxuICAgIHRoaXMuY3VycmVudENoaWxkQ2hhcnRzVHlwZSA9IF8uZmluZCh0aGlzLmNoaWxkQ2hhcnRzVHlwZSwgeyB0eXBlOiB0eXBlIH0pO1xuXG4gICAgaWYgKCF0aGlzLmN1cnJlbnRDaGlsZENoYXJ0c1R5cGUpIHtcbiAgICAgIHRoaXMuY2hhbmdlT3B0aW9ucyh0eXBlKTtcbiAgICB9XG4gIH1cblxuICBjaG9pY2VTdWJDaGFydCh0eXBlOiBhbnkpIHtcbiAgICBpZiAodGhpcy5jdXJyZW50Q2hhcnRUeXBlID09IHR5cGUpIHJldHVybjtcbiAgICB0aGlzLmNoYW5nZU9wdGlvbnModHlwZSk7XG4gIH1cblxuICBjaGFuZ2VPcHRpb25zKHR5cGU6IGFueSkge1xuICAgIGlmICh0aGlzLmN1cnJlbnRDaGFydFR5cGUpIHtcbiAgICAgIHRoaXMubW9kYWxTZXJ2aWNlLmNvbmZpcm0oe1xuICAgICAgICBuelRpdGxlOiBcIuabtOaUueWbvuW9olwiLFxuICAgICAgICBuekNvbnRlbnQ6IFwi5pu05pS55Zu+5b2i5bCG5riF56m65b2T5YmN5Zu+5b2i6YWN572u77yM5piv5ZCm56Gu6K6k5L+u5pS577yfXCIsXG4gICAgICAgIG56T25PazogKCkgPT4ge1xuICAgICAgICAgIHRoaXMuY2hvaWNlVHlwZSh0eXBlKTtcbiAgICAgICAgfSxcbiAgICAgICAgbnpPbkNhbmNlbDogKCkgPT4ge30sXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jaG9pY2VUeXBlKHR5cGUpO1xuICAgIH1cbiAgfVxuXG4gIGNob2ljZVR5cGUodHlwZTogYW55KSB7XG4gICAgY29uc3QgY29uZGl0aW9uID0gdGhpcy5jaGFydENvbmRpdGlvblNlcnZpY2UuY2hhcnRDb25kaXRpb24oKTtcbiAgICB0aGlzLmNoYXJ0Q29uZGl0aW9uID0gXy5maW5kKGNvbmRpdGlvbiwge1xuICAgICAgdHlwZTogdHlwZSxcbiAgICB9KTtcbiAgICB0aGlzLmNoYXJ0Q29uZGl0aW9uLmlucHV0ID0gXy5jbG9uZURlZXAodGhpcy5pbnB1dCk7XG4gICAgdGhpcy5jaGFydENvbmRpdGlvbkNoYW5nZS5lbWl0KHRoaXMuY2hhcnRDb25kaXRpb24pO1xuICAgIHRoaXMuY3VycmVudENoYXJ0VHlwZSA9IHR5cGU7XG4gIH1cblxuICBnZXRDaGFydE9wdGlvbih0eXBlOiBhbnkpIHtcbiAgICBsZXQgb3B0aW9ucztcbiAgICBpZiAodHlwZSA9PT0gXCJwaWVcIikge1xuICAgICAgb3B0aW9ucyA9IHRoaXMuY2hhcnRzU2VydmljZS5waWVPcHRpb25zKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcImRvdWdobnV0XCIpIHtcbiAgICAgIG9wdGlvbnMgPSB0aGlzLmNoYXJ0c1NlcnZpY2UuZG91Z2hudXRPcHRpb25zKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcInJhZGFyXCIpIHtcbiAgICAgIG9wdGlvbnMgPSB0aGlzLmNoYXJ0c1NlcnZpY2UucmFkYXJPcHRpb25zKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcImJhclwiKSB7XG4gICAgICBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLmJhck9wdGlvbnMoKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiYmFyWVwiKSB7XG4gICAgICBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLmJhcllPcHRpb25zKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcImFyZWFcIikge1xuICAgICAgb3B0aW9ucyA9IHRoaXMuY2hhcnRzU2VydmljZS5hcmVhT3B0aW9ucygpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJsaW5lXCIpIHtcbiAgICAgIG9wdGlvbnMgPSB0aGlzLmNoYXJ0c1NlcnZpY2UubGluZU9wdGlvbnMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgc2VyaWVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG4gICAgdGhpcy5jaGFydHNTZXJ2aWNlLm9wdGlvbnMuY29sb3IgPSB0aGlzLnRvdGFsQ29sb3IoKTtcbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfVxuXG4gIGxpbmVTbW9vdGhDaGFuZ2UoY2hhbmdlPzogYW55KSB7XG4gICAgbGV0IG9wdGlvbnMgPSB0aGlzLmNoYXJ0c1NlcnZpY2Uub3B0aW9ucztcbiAgICBvcHRpb25zLnNlcmllcy5mb3JFYWNoKChpdGVtOiBhbnkpID0+IHtcbiAgICAgIGlmIChpdGVtLnR5cGUgPT09IFwibGluZVwiKSB7XG4gICAgICAgIGl0ZW1bXCJzbW9vdGhcIl0gPSBOdW1iZXIodGhpcy5jaGFydENvbmRpdGlvbi5pbnB1dC5saW5lU21vb3RoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoY2hhbmdlKSB7XG4gICAgICB0aGlzLmVjaGFydE9wdGlvbnNDaGFuZ2UuZW1pdChvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICB4QXhpc3JSb3RhdGVDaGFuZ2UoY2hhbmdlPzogYW55KSB7XG4gICAgbGV0IG9wdGlvbnMgPSB0aGlzLmNoYXJ0c1NlcnZpY2Uub3B0aW9ucztcbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnhBeGlzKSB7XG4gICAgICBpZiAob3B0aW9ucy54QXhpcy5heGlzTGFiZWwpIHtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wdGlvbnMueEF4aXMuYXhpc0xhYmVsID0ge307XG4gICAgICB9XG4gICAgICBPYmplY3QuYXNzaWduKG9wdGlvbnMueEF4aXMuYXhpc0xhYmVsLCB7XG4gICAgICAgIHJvdGF0ZTogdGhpcy5jaGFydENvbmRpdGlvbi5pbnB1dC54QXhpc3JSb3RhdGUsXG4gICAgICB9KTtcbiAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgdGhpcy5lY2hhcnRPcHRpb25zQ2hhbmdlLmVtaXQob3B0aW9ucyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaW50ZXJ2YWxDaGFuZ2UoY2hhbmdlPzogYW55KSB7XG4gICAgbGV0IG9wdGlvbnMgPSB0aGlzLmNoYXJ0c1NlcnZpY2Uub3B0aW9ucztcbiAgICBpZiAob3B0aW9ucy54QXhpcykge1xuICAgICAgb3B0aW9ucy54QXhpcy5heGlzTGFiZWwgPSBvcHRpb25zLnhBeGlzLmF4aXNMYWJlbFxuICAgICAgICA/IG9wdGlvbnMueEF4aXMuYXhpc0xhYmVsXG4gICAgICAgIDoge307XG4gICAgICBPYmplY3QuYXNzaWduKG9wdGlvbnMueEF4aXMuYXhpc0xhYmVsLCB7XG4gICAgICAgIGludGVydmFsOiB0aGlzLmNoYXJ0Q29uZGl0aW9uLmlucHV0LmF4aXNMYWJlbEludGVydmFsID8gMCA6IFwiYXV0b1wiLFxuICAgICAgfSk7XG4gICAgICBpZiAoY2hhbmdlKSB7XG4gICAgICAgIHRoaXMuZWNoYXJ0T3B0aW9uc0NoYW5nZS5lbWl0KG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRpdGxlQ2hhbmdlKGNoYW5nZT86IGFueSkge1xuICAgIGxldCBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLm9wdGlvbnM7XG4gICAgb3B0aW9ucy50aXRsZSA9IHtcbiAgICAgIHRleHQ6IHRoaXMuY2hhcnRDb25kaXRpb24uaW5wdXQudGl0bGUsXG4gICAgICBsZWZ0OiB0aGlzLmNoYXJ0Q29uZGl0aW9uLmlucHV0LnRpdGxlWCArIFwiJVwiLFxuICAgICAgdG9wOiB0aGlzLmNoYXJ0Q29uZGl0aW9uLmlucHV0LnRpdGxlWSArIFwiJVwiLFxuICAgICAgdGV4dFN0eWxlOiB7XG4gICAgICAgIGZvbnRTaXplOiB0aGlzLmNoYXJ0Q29uZGl0aW9uLmlucHV0LnRpdGxlU2l6ZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBpZiAodHlwZW9mIGNoYW5nZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgdGhpcy5lY2hhcnRPcHRpb25zQ2hhbmdlLmVtaXQob3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgeUF4aXNNYXhCbHVyKGNoYW5nZT86IGFueSkge1xuICAgIGxldCBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLm9wdGlvbnM7XG4gICAgaWYgKG9wdGlvbnMueUF4aXMpIHt