@asoftwareworld/charts
Version:
`ASW Charts` helps you with the Highcharts library comes with all the tools you need to create reliable and secure data visualizations and Built on Angular.
296 lines • 40.1 kB
JavaScript
import { Component, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core';
import { AswChartConstants, ChartLegendTypeEnum, CurrencyCodeEnum, GridOptionsEnum, LegendLayoutEnum, LegendPositionEnum, } from '@asoftwareworld/charts/core';
import { ObjectUtils } from '@asoftwareworld/charts/utils';
import * as Highcharts from 'highcharts';
import { AswChartTypeEnum } from './enum/chart-type.enum';
import more from 'highcharts/highcharts-more';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@asoftwareworld/charts/core";
more(Highcharts);
export class AswGenericChart {
constructor(currencyPipe, aswCurrencyPipe) {
this.currencyPipe = currencyPipe;
this.aswCurrencyPipe = aswCurrencyPipe;
this.deviceSize = GridOptionsEnum.Large;
this.viewInitialized = false;
this.chartType = AswChartTypeEnum.Line;
this.isLegendSort = true;
this.isLegendDisplay = true;
this.currencyCode = CurrencyCodeEnum.Blank;
this.legendPosition = LegendPositionEnum.Right;
this.legendType = ChartLegendTypeEnum.Both;
this.legendWidthPx = 250;
this.legendLayout = LegendLayoutEnum.Vertical;
this.chartPointClick = new EventEmitter();
}
ngOnChanges() {
if (!this.viewInitialized) {
return;
}
this.initializeChart();
}
ngAfterViewInit() {
this.viewInitialized = true;
this.initializeChart();
}
initializeChart() {
if (this.config) {
this.cloneConfiguration = this.config;
const containerWidth = this.genericChart.nativeElement.clientWidth;
this.deviceSize = ObjectUtils.findDeviceSize(containerWidth);
this.removeChartCredit();
this.setChartTooltip();
const series = this.cloneConfiguration.series;
this.setChartSeriesOptions(series);
if (this.legendLayout === LegendLayoutEnum.Vertical) {
this.setChartLegendOption(this.legendWidthPx);
}
this.clickOnLinePoint();
Highcharts.chart(this.genericChart.nativeElement, this.cloneConfiguration);
}
}
onResize() {
this.initializeChart();
}
removeChartCredit() {
this.cloneConfiguration.credits = {
enabled: false
};
}
setChartTooltip() {
const this$ = this;
this.cloneConfiguration.tooltip = {
useHTML: true,
split: false,
backgroundColor: AswChartConstants.blackColor,
borderColor: AswChartConstants.blackColor,
style: {
color: AswChartConstants.whiteColor,
fontWeight: AswChartConstants.fontWeight
},
borderRadius: 0,
enabled: true,
formatter() {
return `
<div class="row">
<div class="col-md-12 text-end text-right">
<strong>${this.point.category}</strong>
</div>
<div class="col-md-12 text-end text-right">
<span style="color: ${this.point.color}">\u25A0</span>
<strong>${this.point.series.name}</strong>
</div>
<div class="col-md-12 text-end text-right">
${this$.currencyCode === CurrencyCodeEnum.Blank
? this.point.options.y : this$.currencyPipe.transform(this.point.options.y, this$.currencyCode)}
</div>
</div>
`;
}
};
}
clickOnLinePoint() {
if (this.cloneConfiguration.plotOptions) {
// tslint:disable-next-line:no-non-null-assertion
this.cloneConfiguration.plotOptions[this.chartType] = {
point: {
events: {
click: ((event) => {
const pointClickEvent = {
name: event.point.series.name,
index: event.point.index,
value: event.point.options.y,
category: event.point.category
};
this.chartPointClick.emit(pointClickEvent);
})
}
}
};
}
else {
this.cloneConfiguration.plotOptions = {
series: {
point: {
events: {
click: ((event) => {
const pointClickEvent = {
name: event.point.series.name,
index: event.point.index,
value: event.point.options.y,
category: event.point.category
};
this.chartPointClick.emit(pointClickEvent);
})
}
}
}
};
}
}
setChartSeriesOptions(series) {
series.forEach((seriesOption) => {
seriesOption.allowPointSelect = true;
seriesOption.showInLegend = true;
seriesOption.cursor = AswChartConstants.pointer;
const data = seriesOption.data;
// this.handleNegativeSeriesData(data);
// const sortedSeriesOptionData: PointOptionsObject[] = this.isLegendSort ? this.sortSeriesData(data) : data;
// seriesOption.data = sortedSeriesOptionData;
});
}
sortSeriesData(data) {
if (this.legendType === ChartLegendTypeEnum.Default) {
data.sort((a, b) => {
return ('' + a.name).localeCompare(b.name);
});
return data;
}
else {
data.sort((a, b) => {
if (a.y && b.y) {
return a.value - b.value;
}
else {
return 0;
}
});
data.reverse();
return data;
}
}
handleNegativeSeriesData(data) {
data.forEach((element) => {
element.value = element.y;
element.y = element.y ? Math.abs(element.y) : 0.001;
});
}
setChartLegendOption(legendWidthPx) {
const this$ = this;
this.cloneConfiguration.legend = {
useHTML: true,
enabled: this.isLegendDisplay,
floating: false,
align: this.setLegendAlignment(),
layout: 'vertical',
verticalAlign: this.setLegendVerticalAlignment(),
symbolHeight: 10,
symbolWidth: 10,
symbolRadius: 0,
itemMarginTop: 3,
itemMarginBottom: 3,
itemStyle: {
fontSize: this.deviceSize === GridOptionsEnum.ExtraSmall ? '12px' : '14px',
fontWeight: AswChartConstants.fontWeight
},
width: legendWidthPx + 15,
title: {
text: this$.setChartLegendWithHeader(legendWidthPx + 15),
style: {
fontSize: this.deviceSize === GridOptionsEnum.ExtraSmall
? AswChartConstants.fontSize12 : AswChartConstants.fontSize14,
color: '#6c757d',
fontWeight: AswChartConstants.fontWeight,
fontFamily: '500 14px/20px Google Sans Text,Arial,Helvetica,sans-serif'
}
},
labelFormatter() {
const point = this;
const value = point.yData.reduce((acc, cur) => acc + cur, 0);
return this$.setChartLegendWithHeader(legendWidthPx, point.name, value);
}
};
}
setLegendAlignment() {
if (this.deviceSize === GridOptionsEnum.ExtraSmall) {
return 'center';
}
else if (this.legendPosition === LegendPositionEnum.Right) {
return LegendPositionEnum.Right;
}
else if (this.legendPosition === LegendPositionEnum.Left) {
return LegendPositionEnum.Left;
}
else {
return 'center';
}
}
setLegendVerticalAlignment() {
if (this.deviceSize === GridOptionsEnum.ExtraSmall) {
return LegendPositionEnum.Bottom;
}
else if (this.legendPosition === LegendPositionEnum.Right) {
return 'middle';
}
else if (this.legendPosition === LegendPositionEnum.Left) {
return 'middle';
}
else {
return LegendPositionEnum.Bottom;
}
}
setChartLegendWithHeader(legendWidthPx, name, value) {
let legendCategoryWidthPx;
let legendValueWidthPx;
if (this.legendType === ChartLegendTypeEnum.Default) {
return `
<div style="width:${legendWidthPx}px">
<div class="row">
<div class="col-md-12 col-sm-12 col-12">
${name ? name : 'Category'}
</div>
</div>
</div>`;
}
else {
legendCategoryWidthPx = legendWidthPx * 0.5;
legendValueWidthPx = legendWidthPx * 0.5;
return `
<div style="width:${legendCategoryWidthPx + legendValueWidthPx}px">
<div class="row">
<div class="col-md-6 col-sm-6 col-6">
${name ? name : 'Category'}
</div>
<div class="col-md-6 col-sm-6 col-6 text-end text-right">
${value ? this.currencyCode === CurrencyCodeEnum.Blank
? value : this.currencyPipe.transform(value, this.currencyCode, 'symbol', '.2') : 'Total'}
</div>
</div>
</div>`;
}
}
}
AswGenericChart.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswGenericChart, deps: [{ token: i1.CurrencyPipe }, { token: i2.AswCurrencyPipe }], target: i0.ɵɵFactoryTarget.Component });
AswGenericChart.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: AswGenericChart, selector: "asw-generic-chart", inputs: { chartType: "chartType", config: "config", isLegendSort: "isLegendSort", isLegendDisplay: "isLegendDisplay", currencyCode: "currencyCode", legendPosition: "legendPosition", legendType: "legendType", legendWidthPx: "legendWidthPx", legendLayout: "legendLayout" }, outputs: { chartPointClick: "chartPointClick" }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "genericChart", first: true, predicate: ["genericChart"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #genericChart></div>" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswGenericChart, decorators: [{
type: Component,
args: [{ selector: 'asw-generic-chart', template: "<div #genericChart></div>" }]
}], ctorParameters: function () { return [{ type: i1.CurrencyPipe }, { type: i2.AswCurrencyPipe }]; }, propDecorators: { chartType: [{
type: Input
}], config: [{
type: Input
}], isLegendSort: [{
type: Input
}], isLegendDisplay: [{
type: Input
}], currencyCode: [{
type: Input
}], legendPosition: [{
type: Input
}], legendType: [{
type: Input
}], legendWidthPx: [{
type: Input
}], legendLayout: [{
type: Input
}], chartPointClick: [{
type: Output
}], genericChart: [{
type: ViewChild,
args: ['genericChart', { static: true }]
}], onResize: [{
type: HostListener,
args: ['window:resize']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1jaGFydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcHAvY29tcG9uZW50L2dlbmVyaWMtY2hhcnQvZ2VuZXJpYy1jaGFydC50cyIsIi4uLy4uLy4uL3NyYy9hcHAvY29tcG9uZW50L2dlbmVyaWMtY2hhcnQvZ2VuZXJpYy1jaGFydC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNBLE9BQU8sRUFFSCxTQUFTLEVBRVQsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0gsaUJBQWlCLEVBRWpCLG1CQUFtQixFQUVuQixnQkFBZ0IsRUFDaEIsZUFBZSxFQUNmLGdCQUFnQixFQUNoQixrQkFBa0IsR0FDckIsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDM0QsT0FBTyxLQUFLLFVBQVUsTUFBTSxZQUFZLENBQUM7QUFVekMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxJQUFJLE1BQU0sNEJBQTRCLENBQUM7Ozs7QUFDOUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBTWpCLE1BQU0sT0FBTyxlQUFlO0lBaUJ4QixZQUNZLFlBQTBCLEVBQzFCLGVBQWdDO1FBRGhDLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQWpCckMsZUFBVSxHQUFvQixlQUFlLENBQUMsS0FBSyxDQUFDO1FBQ25ELG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLGNBQVMsR0FBcUIsZ0JBQWdCLENBQUMsSUFBSSxDQUFDO1FBRXBELGlCQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLG9CQUFlLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLGlCQUFZLEdBQXFCLGdCQUFnQixDQUFDLEtBQUss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LENBQUMsT0FBTzs7O3VCQUdsRyxDQUFDO1NBQ2Y7SUFDTCxDQUFDOzs0R0ExUVEsZUFBZTtnR0FBZixlQUFlLG1rQkNqRDVCLDJCQUF5QjsyRkRpRFosZUFBZTtrQkFKM0IsU0FBUzsrQkFDSSxtQkFBbUI7aUlBT3BCLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBRUksZUFBZTtzQkFBeEIsTUFBTTtnQkFFc0MsWUFBWTtzQkFBeEQsU0FBUzt1QkFBQyxjQUFjLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQW1DM0MsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEFTVyAoQSBTb2Z0d2FyZSBXb3JsZCkgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cclxuICpcclxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcclxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IEN1cnJlbmN5UGlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7XHJcbiAgICBBZnRlclZpZXdJbml0LFxyXG4gICAgQ29tcG9uZW50LFxyXG4gICAgRWxlbWVudFJlZixcclxuICAgIEV2ZW50RW1pdHRlcixcclxuICAgIEhvc3RMaXN0ZW5lcixcclxuICAgIElucHV0LFxyXG4gICAgT25DaGFuZ2VzLFxyXG4gICAgT3V0cHV0LFxyXG4gICAgVmlld0NoaWxkXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgICBBc3dDaGFydENvbnN0YW50cyxcclxuICAgIEFzd0N1cnJlbmN5UGlwZSxcclxuICAgIENoYXJ0TGVnZW5kVHlwZUVudW0sXHJcbiAgICBDaGFydFBvaW50ZXJFdmVudCxcclxuICAgIEN1cnJlbmN5Q29kZUVudW0sXHJcbiAgICBHcmlkT3B0aW9uc0VudW0sXHJcbiAgICBMZWdlbmRMYXlvdXRFbnVtLFxyXG4gICAgTGVnZW5kUG9zaXRpb25FbnVtLFxyXG59IGZyb20gJ0Bhc29mdHdhcmV3b3JsZC9jaGFydHMvY29yZSc7XHJcbmltcG9ydCB7IE9iamVjdFV0aWxzIH0gZnJvbSAnQGFzb2Z0d2FyZXdvcmxkL2NoYXJ0cy91dGlscyc7XHJcbmltcG9ydCAqIGFzIEhpZ2hjaGFydHMgZnJvbSAnaGlnaGNoYXJ0cyc7XHJcbmltcG9ydCB7XHJcbiAgICBBbGlnblZhbHVlLFxyXG4gICAgT3B0aW9ucyxcclxuICAgIFBvaW50Q2xpY2tFdmVudE9iamVjdCxcclxuICAgIFBvaW50T3B0aW9uc09iamVjdCxcclxuICAgIFBvaW50LFxyXG4gICAgU2VyaWVzUGllT3B0aW9ucyxcclxuICAgIFZlcnRpY2FsQWxpZ25WYWx1ZVxyXG59IGZyb20gJ2hpZ2hjaGFydHMnO1xyXG5pbXBvcnQgeyBBc3dDaGFydFR5cGVFbnVtIH0gZnJvbSAnLi9lbnVtL2NoYXJ0LXR5cGUuZW51bSc7XHJcbmltcG9ydCBtb3JlIGZyb20gJ2hpZ2hjaGFydHMvaGlnaGNoYXJ0cy1tb3JlJztcclxubW9yZShIaWdoY2hhcnRzKTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdhc3ctZ2VuZXJpYy1jaGFydCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vZ2VuZXJpYy1jaGFydC5odG1sJyxcclxufSlcclxuZXhwb3J0IGNsYXNzIEFzd0dlbmVyaWNDaGFydCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCB7XHJcbiAgICBwcml2YXRlIGNsb25lQ29uZmlndXJhdGlvbiE6IE9wdGlvbnM7XHJcbiAgICBwdWJsaWMgZGV2aWNlU2l6ZTogR3JpZE9wdGlvbnNFbnVtID0gR3JpZE9wdGlvbnNFbnVtLkxhcmdlO1xyXG4gICAgcHJpdmF0ZSB2aWV3SW5pdGlhbGl6ZWQgPSBmYWxzZTtcclxuICAgIEBJbnB1dCgpIGNoYXJ0VHlwZTogQXN3Q2hhcnRUeXBlRW51bSA9IEFzd0NoYXJ0VHlwZUVudW0uTGluZTtcclxuICAgIEBJbnB1dCgpIGNvbmZpZyE6IE9wdGlvbnM7XHJcbiAgICBASW5wdXQoKSBpc0xlZ2VuZFNvcnQgPSB0cnVlO1xyXG4gICAgQElucHV0KCkgaXNMZWdlbmREaXNwbGF5ID0gdHJ1ZTtcclxuICAgIEBJbnB1dCgpIGN1cnJlbmN5Q29kZTogQ3VycmVuY3lDb2RlRW51bSA9IEN1cnJlbmN5Q29kZUVudW0uQmxhbms7XHJcbiAgICBASW5wdXQoKSBsZWdlbmRQb3NpdGlvbjogTGVnZW5kUG9zaXRpb25FbnVtID0gTGVnZW5kUG9zaXRpb25FbnVtLlJpZ2h0O1xyXG4gICAgQElucHV0KCkgbGVnZW5kVHlwZTogQ2hhcnRMZWdlbmRUeXBlRW51bSA9IENoYXJ0TGVnZW5kVHlwZUVudW0uQm90aDtcclxuICAgIEBJbnB1dCgpIGxlZ2VuZFdpZHRoUHggPSAyNTA7XHJcbiAgICBASW5wdXQoKSBsZWdlbmRMYXlvdXQ6IExlZ2VuZExheW91dEVudW0gPSBMZWdlbmRMYXlvdXRFbnVtLlZlcnRpY2FsO1xyXG5cclxuICAgIEBPdXRwdXQoKSBjaGFydFBvaW50Q2xpY2s6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gICAgQFZpZXdDaGlsZCgnZ2VuZXJpY0NoYXJ0JywgeyBzdGF0aWM6IHRydWUgfSkgZ2VuZXJpY0NoYXJ0ITogRWxlbWVudFJlZjtcclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgY3VycmVuY3lQaXBlOiBDdXJyZW5jeVBpcGUsXHJcbiAgICAgICAgcHJpdmF0ZSBhc3dDdXJyZW5jeVBpcGU6IEFzd0N1cnJlbmN5UGlwZSkgeyB9XHJcblxyXG4gICAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnZpZXdJbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUNoYXJ0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudmlld0luaXRpYWxpemVkID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmluaXRpYWxpemVDaGFydCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGluaXRpYWxpemVDaGFydCgpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5jb25maWcpIHtcclxuICAgICAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZztcclxuICAgICAgICAgICAgY29uc3QgY29udGFpbmVyV2lkdGggPSB0aGlzLmdlbmVyaWNDaGFydC5uYXRpdmVFbGVtZW50LmNsaWVudFdpZHRoO1xyXG4gICAgICAgICAgICB0aGlzLmRldmljZVNpemUgPSBPYmplY3RVdGlscy5maW5kRGV2aWNlU2l6ZShjb250YWluZXJXaWR0aCk7XHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2hhcnRDcmVkaXQoKTtcclxuICAgICAgICAgICAgdGhpcy5zZXRDaGFydFRvb2x0aXAoKTtcclxuICAgICAgICAgICAgY29uc3Qgc2VyaWVzOiBTZXJpZXNQaWVPcHRpb25zW10gPSB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5zZXJpZXMgYXMgU2VyaWVzUGllT3B0aW9uc1tdO1xyXG4gICAgICAgICAgICB0aGlzLnNldENoYXJ0U2VyaWVzT3B0aW9ucyhzZXJpZXMpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5sZWdlbmRMYXlvdXQgPT09IExlZ2VuZExheW91dEVudW0uVmVydGljYWwpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0Q2hhcnRMZWdlbmRPcHRpb24odGhpcy5sZWdlbmRXaWR0aFB4KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmNsaWNrT25MaW5lUG9pbnQoKTtcclxuICAgICAgICAgICAgSGlnaGNoYXJ0cy5jaGFydCh0aGlzLmdlbmVyaWNDaGFydC5uYXRpdmVFbGVtZW50LCB0aGlzLmNsb25lQ29uZmlndXJhdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxyXG4gICAgb25SZXNpemUoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ2hhcnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHJlbW92ZUNoYXJ0Q3JlZGl0KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY2xvbmVDb25maWd1cmF0aW9uLmNyZWRpdHMgPSB7XHJcbiAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNldENoYXJ0VG9vbHRpcCgpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCB0aGlzJDogdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24udG9vbHRpcCA9IHtcclxuICAgICAgICAgICAgdXNlSFRNTDogdHJ1ZSxcclxuICAgICAgICAgICAgc3BsaXQ6IGZhbHNlLFxyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IEFzd0NoYXJ0Q29uc3RhbnRzLmJsYWNrQ29sb3IsXHJcbiAgICAgICAgICAgIGJvcmRlckNvbG9yOiBBc3dDaGFydENvbnN0YW50cy5ibGFja0NvbG9yLFxyXG4gICAgICAgICAgICBzdHlsZToge1xyXG4gICAgICAgICAgICAgICAgY29sb3I6IEFzd0NoYXJ0Q29uc3RhbnRzLndoaXRlQ29sb3IsXHJcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiBBc3dDaGFydENvbnN0YW50cy5mb250V2VpZ2h0XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGJvcmRlclJhZGl1czogMCxcclxuICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcclxuICAgICAgICAgICAgZm9ybWF0dGVyKCk6IHN0cmluZyB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYFxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMiB0ZXh0LWVuZCB0ZXh0LXJpZ2h0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPiR7dGhpcy5wb2ludC5jYXRlZ29yeX08L3N0cm9uZz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMTIgdGV4dC1lbmQgdGV4dC1yaWdodFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJjb2xvcjogJHt0aGlzLnBvaW50LmNvbG9yfVwiPlxcdTI1QTA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPiR7dGhpcy5wb2ludC5zZXJpZXMubmFtZX08L3N0cm9uZz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMTIgdGV4dC1lbmQgdGV4dC1yaWdodFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt0aGlzJC5jdXJyZW5jeUNvZGUgPT09IEN1cnJlbmN5Q29kZUVudW0uQmxhbmtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMucG9pbnQub3B0aW9ucy55IDogdGhpcyQuY3VycmVuY3lQaXBlLnRyYW5zZm9ybSh0aGlzLnBvaW50Lm9wdGlvbnMueSwgdGhpcyQuY3VycmVuY3lDb2RlKX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICBgO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGNsaWNrT25MaW5lUG9pbnQoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2xvbmVDb25maWd1cmF0aW9uLnBsb3RPcHRpb25zKSB7XHJcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1ub24tbnVsbC1hc3NlcnRpb25cclxuICAgICAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24ucGxvdE9wdGlvbnMhW3RoaXMuY2hhcnRUeXBlXSA9IHtcclxuICAgICAgICAgICAgICAgIHBvaW50OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrOiAoKGV2ZW50OiBQb2ludENsaWNrRXZlbnRPYmplY3QpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvaW50Q2xpY2tFdmVudDogQ2hhcnRQb2ludGVyRXZlbnQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogZXZlbnQucG9pbnQuc2VyaWVzLm5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg6IGV2ZW50LnBvaW50LmluZGV4LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBldmVudC5wb2ludC5vcHRpb25zLnksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0ZWdvcnk6IGV2ZW50LnBvaW50LmNhdGVnb3J5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFydFBvaW50Q2xpY2suZW1pdChwb2ludENsaWNrRXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5wbG90T3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgICAgIHNlcmllczoge1xyXG4gICAgICAgICAgICAgICAgICAgIHBvaW50OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50czoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpY2s6ICgoZXZlbnQ6IFBvaW50Q2xpY2tFdmVudE9iamVjdCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvaW50Q2xpY2tFdmVudDogQ2hhcnRQb2ludGVyRXZlbnQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IGV2ZW50LnBvaW50LnNlcmllcy5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogZXZlbnQucG9pbnQuaW5kZXgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBldmVudC5wb2ludC5vcHRpb25zLnksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGVnb3J5OiBldmVudC5wb2ludC5jYXRlZ29yeVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFydFBvaW50Q2xpY2suZW1pdChwb2ludENsaWNrRXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzZXRDaGFydFNlcmllc09wdGlvbnMoc2VyaWVzOiBTZXJpZXNQaWVPcHRpb25zW10pOiB2b2lkIHtcclxuICAgICAgICBzZXJpZXMuZm9yRWFjaCgoc2VyaWVzT3B0aW9uOiBTZXJpZXNQaWVPcHRpb25zKSA9PiB7XHJcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5hbGxvd1BvaW50U2VsZWN0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgc2VyaWVzT3B0aW9uLnNob3dJbkxlZ2VuZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5jdXJzb3IgPSBBc3dDaGFydENvbnN0YW50cy5wb2ludGVyO1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSA9IHNlcmllc09wdGlvbi5kYXRhIGFzIFBvaW50T3B0aW9uc09iamVjdFtdO1xyXG4gICAgICAgICAgICAvLyB0aGlzLmhhbmRsZU5lZ2F0aXZlU2VyaWVzRGF0YShkYXRhKTtcclxuICAgICAgICAgICAgLy8gY29uc3Qgc29ydGVkU2VyaWVzT3B0aW9uRGF0YTogUG9pbnRPcHRpb25zT2JqZWN0W10gPSB0aGlzLmlzTGVnZW5kU29ydCA/IHRoaXMuc29ydFNlcmllc0RhdGEoZGF0YSkgOiBkYXRhO1xyXG4gICAgICAgICAgICAvLyBzZXJpZXNPcHRpb24uZGF0YSA9IHNvcnRlZFNlcmllc09wdGlvbkRhdGE7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzb3J0U2VyaWVzRGF0YShkYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSk6IFBvaW50T3B0aW9uc09iamVjdFtdIHtcclxuICAgICAgICBpZiAodGhpcy5sZWdlbmRUeXBlID09PSBDaGFydExlZ2VuZFR5cGVFbnVtLkRlZmF1bHQpIHtcclxuICAgICAgICAgICAgZGF0YS5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICgnJyArIGEubmFtZSkubG9jYWxlQ29tcGFyZShiLm5hbWUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZGF0YS5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGEueSAmJiBiLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYS52YWx1ZSAtIGIudmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgZGF0YS5yZXZlcnNlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZU5lZ2F0aXZlU2VyaWVzRGF0YShkYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSk6IHZvaWQge1xyXG4gICAgICAgIGRhdGEuZm9yRWFjaCgoZWxlbWVudDogUG9pbnRPcHRpb25zT2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQudmFsdWUgPSBlbGVtZW50Lnk7XHJcbiAgICAgICAgICAgIGVsZW1lbnQueSA9IGVsZW1lbnQueSA/IE1hdGguYWJzKGVsZW1lbnQueSkgOiAwLjAwMTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNldENoYXJ0TGVnZW5kT3B0aW9uKGxlZ2VuZFdpZHRoUHg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHRoaXMkOiB0aGlzID0gdGhpcztcclxuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5sZWdlbmQgPSB7XHJcbiAgICAgICAgICAgIHVzZUhUTUw6IHRydWUsXHJcbiAgICAgICAgICAgIGVuYWJsZWQ6IHRoaXMuaXNMZWdlbmREaXNwbGF5LFxyXG4gICAgICAgICAgICBmbG9hdGluZzogZmFsc2UsXHJcbiAgICAgICAgICAgIGFsaWduOiB0aGlzLnNldExlZ2VuZEFsaWdubWVudCgpLFxyXG4gICAgICAgICAgICBsYXlvdXQ6ICd2ZXJ0aWNhbCcsXHJcbiAgICAgICAgICAgIHZlcnRpY2FsQWxpZ246IHRoaXMuc2V0TGVnZW5kVmVydGljYWxBbGlnbm1lbnQoKSxcclxuICAgICAgICAgICAgc3ltYm9sSGVpZ2h0OiAxMCxcclxuICAgICAgICAgICAgc3ltYm9sV2lkdGg6IDEwLFxyXG4gICAgICAgICAgICBzeW1ib2xSYWRpdXM6IDAsXHJcbiAgICAgICAgICAgIGl0ZW1NYXJnaW5Ub3A6IDMsIC8vIFNwYWNlIGJldHdlZW4gZWFjaCBjYXRlZ29yeSBpbiB0aGUgbGVnZW5kXHJcbiAgICAgICAgICAgIGl0ZW1NYXJnaW5Cb3R0b206IDMsXHJcbiAgICAgICAgICAgIGl0ZW1TdHlsZToge1xyXG4gICAgICAgICAgICAgICAgZm9udFNpemU6IHRoaXMuZGV2aWNlU2l6ZSA9PT0gR3JpZE9wdGlvbnNFbnVtLkV4dHJhU21hbGwgPyAnMTJweCcgOiAnMTRweCcsXHJcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiBBc3dDaGFydENvbnN0YW50cy5mb250V2VpZ2h0XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHdpZHRoOiBsZWdlbmRXaWR0aFB4ICsgMTUsXHJcbiAgICAgICAgICAgIHRpdGxlOiB7XHJcbiAgICAgICAgICAgICAgICB0ZXh0OiB0aGlzJC5zZXRDaGFydExlZ2VuZFdpdGhIZWFkZXIobGVnZW5kV2lkdGhQeCArIDE1KSxcclxuICAgICAgICAgICAgICAgIHN0eWxlOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IHRoaXMuZGV2aWNlU2l6ZSA9PT0gR3JpZE9wdGlvbnNFbnVtLkV4dHJhU21hbGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBBc3dDaGFydENvbnN0YW50cy5mb250U2l6ZTEyIDogQXN3Q2hhcnRDb25zdGFudHMuZm9udFNpemUxNCxcclxuICAgICAgICAgICAgICAgICAgICBjb2xvcjogJyM2Yzc1N2QnLFxyXG4gICAgICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IEFzd0NoYXJ0Q29uc3RhbnRzLmZvbnRXZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgZm9udEZhbWlseTogJzUwMCAxNHB4LzIwcHggR29vZ2xlIFNhbnMgVGV4dCxBcmlhbCxIZWx2ZXRpY2Esc2Fucy1zZXJpZidcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbGFiZWxGb3JtYXR0ZXIoKTogc3RyaW5nIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBvaW50OiBhbnkgPSB0aGlzIGFzIFBvaW50O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwb2ludC55RGF0YS5yZWR1Y2UoKGFjYzogYW55LCBjdXI6IGFueSkgPT4gYWNjICsgY3VyLCAwKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzJC5zZXRDaGFydExlZ2VuZFdpdGhIZWFkZXIoXHJcbiAgICAgICAgICAgICAgICAgICAgbGVnZW5kV2lkdGhQeCxcclxuICAgICAgICAgICAgICAgICAgICBwb2ludC5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzZXRMZWdlbmRBbGlnbm1lbnQoKTogQWxpZ25WYWx1ZSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZGV2aWNlU2l6ZSA9PT0gR3JpZE9wdGlvbnNFbnVtLkV4dHJhU21hbGwpIHtcclxuICAgICAgICAgICAgcmV0dXJuICdjZW50ZXInO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5sZWdlbmRQb3NpdGlvbiA9PT0gTGVnZW5kUG9zaXRpb25FbnVtLlJpZ2h0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBMZWdlbmRQb3NpdGlvbkVudW0uUmlnaHQ7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmxlZ2VuZFBvc2l0aW9uID09PSBMZWdlbmRQb3NpdGlvbkVudW0uTGVmdCkge1xyXG4gICAgICAgICAgICByZXR1cm4gTGVnZW5kUG9zaXRpb25FbnVtLkxlZnQ7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuICdjZW50ZXInO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNldExlZ2VuZFZlcnRpY2FsQWxpZ25tZW50KCk6IFZlcnRpY2FsQWxpZ25WYWx1ZSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZGV2aWNlU2l6ZSA9PT0gR3JpZE9wdGlvbnNFbnVtLkV4dHJhU21hbGwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIExlZ2VuZFBvc2l0aW9uRW51bS5Cb3R0b207XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmxlZ2VuZFBvc2l0aW9uID09PSBMZWdlbmRQb3NpdGlvbkVudW0uUmlnaHQpIHtcclxuICAgICAgICAgICAgcmV0dXJuICdtaWRkbGUnO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5sZWdlbmRQb3NpdGlvbiA9PT0gTGVnZW5kUG9zaXRpb25FbnVtLkxlZnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuICdtaWRkbGUnO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBMZWdlbmRQb3NpdGlvbkVudW0uQm90dG9tO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNldENoYXJ0TGVnZW5kV2l0aEhlYWRlcihcclxuICAgICAgICBsZWdlbmRXaWR0aFB4OiBudW1iZXIsXHJcbiAgICAgICAgbmFtZT86IHN0cmluZyB8IG51bGwsXHJcbiAgICAgICAgdmFsdWU/OiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgbGVnZW5kQ2F0ZWdvcnlXaWR0aFB4OiBudW1iZXI7XHJcbiAgICAgICAgbGV0IGxlZ2VuZFZhbHVlV2lkdGhQeDogbnVtYmVyO1xyXG4gICAgICAgIGlmICh0aGlzLmxlZ2VuZFR5cGUgPT09IENoYXJ0TGVnZW5kVHlwZUVudW0uRGVmYXVsdCkge1xyXG4gICAgICAgICAgICByZXR1cm4gYFxyXG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cIndpZHRoOiR7bGVnZW5kV2lkdGhQeH1weFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMiBjb2wtc20tMTIgY29sLTEyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke25hbWUgPyBuYW1lIDogJ0NhdGVnb3J5J31cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGxlZ2VuZENhdGVnb3J5V2lkdGhQeCA9IGxlZ2VuZFdpZHRoUHggKiAwLjU7XHJcbiAgICAgICAgICAgIGxlZ2VuZFZhbHVlV2lkdGhQeCA9IGxlZ2VuZFdpZHRoUHggKiAwLjU7XHJcbiAgICAgICAgICAgIHJldHVybiBgXHJcbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwid2lkdGg6JHtsZWdlbmRDYXRlZ29yeVdpZHRoUHggKyBsZWdlbmRWYWx1ZVdpZHRoUHh9cHhcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBjb2wtc20tNiBjb2wtNlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtuYW1lID8gbmFtZSA6ICdDYXRlZ29yeSd9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgY29sLXNtLTYgY29sLTYgdGV4dC1lbmQgdGV4dC1yaWdodFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt2YWx1ZSA/IHRoaXMuY3VycmVuY3lDb2RlID09PSBDdXJyZW5jeUNvZGVFbnVtLkJsYW5rXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB2YWx1ZSA6IHRoaXMuY3VycmVuY3lQaXBlLnRyYW5zZm9ybSh2YWx1ZSwgdGhpcy5jdXJyZW5jeUNvZGUsICdzeW1ib2wnLCAnLjInKSA6ICdUb3RhbCd9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+YDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiPGRpdiAjZ2VuZXJpY0NoYXJ0PjwvZGl2PiJdfQ==