@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.
310 lines • 40.7 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 HighchartsSankey from 'highcharts/modules/sankey';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
HighchartsSankey(Highcharts);
export class AswSankeyChart {
constructor(currencyPipe) {
this.currencyPipe = currencyPipe;
this.deviceSize = GridOptionsEnum.Large;
this.viewInitialized = false;
this.isLegendSort = true;
this.currencyCode = CurrencyCodeEnum.Blank;
this.legendPosition = LegendPositionEnum.Right;
this.legendType = ChartLegendTypeEnum.Both;
this.legendWidthPx = 250;
this.legendLayout = LegendLayoutEnum.Vertical;
this.sankeyClick = 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.sankeyChart.nativeElement.clientWidth;
this.deviceSize = ObjectUtils.findDeviceSize(containerWidth);
this.removeChartCredit();
this.setSankeyChartTooltip();
const series = this.cloneConfiguration.series;
if (this.legendLayout === LegendLayoutEnum.Vertical) {
// this.setSankeyChartLegendOption(this.legendWidthPx);
}
this.clickOnSankey();
Highcharts.chart(this.sankeyChart.nativeElement, this.cloneConfiguration);
}
}
onResize() {
this.initializeChart();
}
removeChartCredit() {
this.cloneConfiguration.credits = {
enabled: false
};
}
setSankeyChartTooltip() {
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() {
const point = this.point;
return `
<div class="row">
<div class="col-md-12 text-end text-right">
<span style="color: ${point.color}">\u25A0</span>
<strong>${point.series.name}</strong>
</div>
<div class="col-md-12 text-end text-right">
${point.options.weight
? point.options.from + ' → ' + point.options.to + ': ' + point.options.weight
: point.options.id + ': ' + point.sum}
</div>
</div>
`;
}
};
}
clickOnSankey() {
if (this.cloneConfiguration.plotOptions) {
// tslint:disable-next-line:no-non-null-assertion
this.cloneConfiguration.plotOptions.sankey.point = {
events: {
click: ((event) => {
const pointClickEvent = {
name: event.point.series.name,
from: event.point.options.from ?? event.point.id,
to: event.point.options.to,
weight: event.point.options.weight,
sum: event.point.sum
};
this.sankeyClick.emit(pointClickEvent);
})
}
};
}
else {
this.cloneConfiguration.plotOptions = {
sankey: {
point: {
events: {
click: ((event) => {
const pointClickEvent = {
name: event.point.series.name,
from: event.point.options.from ?? event.point.id,
to: event.point.options.to,
weight: event.point.options.weight,
sum: event.point.sum
};
this.sankeyClick.emit(pointClickEvent);
})
}
}
}
};
}
}
setDonutChartSeriesOptions(series) {
series.forEach((seriesOption) => {
seriesOption.allowPointSelect = true;
seriesOption.showInLegend = true;
// if (this.chartType === ChartTypeEnum.Donut) {
// seriesOption.innerSize = AswChartConstants.innerSize;
// }
// if (this.isMute) {
// seriesOption.opacity = 0.35;
// seriesOption.states = {
// hover: {
// enabled: false
// },
// inactive: {
// enabled: false
// }
// };
// seriesOption.slicedOffset = 0;
// }
seriesOption.cursor = AswChartConstants.pointer;
const data = seriesOption.data;
this.handleNegativeSeriesData(data);
const sortedSeriesOptionData = 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;
});
}
setFontSize() {
return this.deviceSize === GridOptionsEnum.ExtraSmall ? AswChartConstants.fontSize14 : AswChartConstants.fontSize16;
}
setSankeyChartLegendOption(legendWidthPx) {
const this$ = this;
this.cloneConfiguration.legend = {
useHTML: true,
enabled: true,
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$.setLineChartLegendWithHeader(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$.setLineChartLegendWithHeader(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;
}
}
setLineChartLegendWithHeader(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.currencyPipe.transform(value, this.currencyCode, 'symbol', '.2') : 'Total'}
</div>
</div>
</div>`;
}
}
}
AswSankeyChart.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswSankeyChart, deps: [{ token: i1.CurrencyPipe }], target: i0.ɵɵFactoryTarget.Component });
AswSankeyChart.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: AswSankeyChart, selector: "asw-sankey-chart", inputs: { config: "config", isLegendSort: "isLegendSort", icon: "icon", label: "label", amount: "amount", target: "target", currencyCode: "currencyCode", legendPosition: "legendPosition", legendType: "legendType", legendWidthPx: "legendWidthPx", legendLayout: "legendLayout" }, outputs: { sankeyClick: "sankeyClick" }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "sankeyChart", first: true, predicate: ["sankeyChart"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #sankeyChart></div>", styles: [""] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswSankeyChart, decorators: [{
type: Component,
args: [{ selector: 'asw-sankey-chart', template: "<div #sankeyChart></div>", styles: [""] }]
}], ctorParameters: function () { return [{ type: i1.CurrencyPipe }]; }, propDecorators: { config: [{
type: Input
}], isLegendSort: [{
type: Input
}], icon: [{
type: Input
}], label: [{
type: Input
}], amount: [{
type: Input
}], target: [{
type: Input
}], currencyCode: [{
type: Input
}], legendPosition: [{
type: Input
}], legendType: [{
type: Input
}], legendWidthPx: [{
type: Input
}], legendLayout: [{
type: Input
}], sankeyClick: [{
type: Output
}], sankeyChart: [{
type: ViewChild,
args: ['sankeyChart', { static: true }]
}], onResize: [{
type: HostListener,
args: ['window:resize']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Fua2V5LWNoYXJ0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9jb21wb25lbnQvc2Fua2V5LWNoYXJ0L2NvbXBvbmVudC9zYW5rZXktY2hhcnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudC9zYW5rZXktY2hhcnQvY29tcG9uZW50L3NhbmtleS1jaGFydC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFFSCxTQUFTLEVBRVQsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0gsaUJBQWlCLEVBQ2pCLG1CQUFtQixFQUVuQixnQkFBZ0IsRUFDaEIsZUFBZSxFQUNmLGdCQUFnQixFQUNoQixrQkFBa0IsR0FDckIsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDM0QsT0FBTyxLQUFLLFVBQVUsTUFBTSxZQUFZLENBQUM7QUFDekMsT0FBTyxnQkFBZ0IsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBWXpELGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBTzdCLE1BQU0sT0FBTyxjQUFjO0lBb0J2QixZQUNZLFlBQTBCO1FBQTFCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBbEIvQixlQUFVLEdBQW9CLGVBQWUsQ0FBQyxLQUFLLENBQUM7UUFDbkQsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFFdkIsaUJBQVksR0FBRyxJQUFJLENBQUM7UUFLcEIsaUJBQVksR0FBcUIsZ0JBQWdCLENBQUMsS0FBSyxDQUFDO1FBQ3hELG1CQUFjLEdBQXVCLGtCQUFrQixDQUFDLEtBQUssQ0FBQztRQUM5RCxlQUFVLEdBQXdCLG1CQUFtQixDQUFDLElBQUksQ0FBQztRQUMzRCxrQkFBYSxHQUFHLEdBQUcsQ0FBQztRQUNwQixpQkFBWSxHQUFx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QUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVU7Ozt1QkFHL0IsQ0FBQztTQUNmO2FBQU07WUFDSCxxQkFBcUIsR0FBRyxhQUFhLEdBQUcsR0FBRyxDQUFDO1lBQzVDLGtCQUFrQixHQUFHLGFBQWEsR0FBRyxHQUFHLENBQUM7WUFDekMsT0FBTztvQ0FDaUIscUJBQXFCLEdBQUcsa0JBQWtCOzs7OEJBR2hELElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVOzs7OEJBR3hCLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPOzs7dUJBRzlGLENBQUM7U0FDZjtJQUNMLENBQUM7OzJHQTdSUSxjQUFjOytGQUFkLGNBQWMsOGpCQzFDM0IsMEJBQXdCOzJGRDBDWCxjQUFjO2tCQUwxQixTQUFTOytCQUNJLGtCQUFrQjttR0FTbkIsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFFSSxXQUFXO3NCQUFwQixNQUFNO2dCQUVxQyxXQUFXO3NCQUF0RCxTQUFTO3VCQUFDLGFBQWEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBaUMxQyxRQUFRO3NCQURQLFlBQVk7dUJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEN1cnJlbmN5UGlwZSwgUGVyY2VudFBpcGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBIb3N0TGlzdGVuZXIsXG4gICAgSW5wdXQsXG4gICAgT25DaGFuZ2VzLFxuICAgIE91dHB1dCxcbiAgICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICAgIEFzd0NoYXJ0Q29uc3RhbnRzLFxuICAgIENoYXJ0TGVnZW5kVHlwZUVudW0sXG4gICAgQ2hhcnRQb2ludGVyRXZlbnQsXG4gICAgQ3VycmVuY3lDb2RlRW51bSxcbiAgICBHcmlkT3B0aW9uc0VudW0sXG4gICAgTGVnZW5kTGF5b3V0RW51bSxcbiAgICBMZWdlbmRQb3NpdGlvbkVudW0sXG59IGZyb20gJ0Bhc29mdHdhcmV3b3JsZC9jaGFydHMvY29yZSc7XG5pbXBvcnQgeyBPYmplY3RVdGlscyB9IGZyb20gJ0Bhc29mdHdhcmV3b3JsZC9jaGFydHMvdXRpbHMnO1xuaW1wb3J0ICogYXMgSGlnaGNoYXJ0cyBmcm9tICdoaWdoY2hhcnRzJztcbmltcG9ydCBIaWdoY2hhcnRzU2Fua2V5IGZyb20gJ2hpZ2hjaGFydHMvbW9kdWxlcy9zYW5rZXknO1xuaW1wb3J0IHtcbiAgICBBbGlnblZhbHVlLFxuICAgIE9wdGlvbnMsXG4gICAgUG9pbnRDbGlja0V2ZW50T2JqZWN0LFxuICAgIFBvaW50T3B0aW9uc09iamVjdCxcbiAgICBQb2ludCxcbiAgICBTZXJpZXMsXG4gICAgU2VyaWVzUGllT3B0aW9ucyxcbiAgICBWZXJ0aWNhbEFsaWduVmFsdWVcbn0gZnJvbSAnaGlnaGNoYXJ0cyc7XG5pbXBvcnQgeyBTYW5rZXlDaGFydFBvaW50ZXJFdmVudCB9IGZyb20gJy4vLi4vaW50ZXJmYWNlL3NhbmtleS1wb2ludGVyLWV2ZW50JztcbkhpZ2hjaGFydHNTYW5rZXkoSGlnaGNoYXJ0cyk7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYXN3LXNhbmtleS1jaGFydCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3NhbmtleS1jaGFydC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9zYW5rZXktY2hhcnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIEFzd1NhbmtleUNoYXJ0IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcblxuICAgIHByaXZhdGUgY2xvbmVDb25maWd1cmF0aW9uITogT3B0aW9ucztcbiAgICBwdWJsaWMgZGV2aWNlU2l6ZTogR3JpZE9wdGlvbnNFbnVtID0gR3JpZE9wdGlvbnNFbnVtLkxhcmdlO1xuICAgIHByaXZhdGUgdmlld0luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgQElucHV0KCkgY29uZmlnITogT3B0aW9ucztcbiAgICBASW5wdXQoKSBpc0xlZ2VuZFNvcnQgPSB0cnVlO1xuICAgIEBJbnB1dCgpIGljb24hOiBzdHJpbmc7XG4gICAgQElucHV0KCkgbGFiZWw6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBASW5wdXQoKSBhbW91bnQ6IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQ7XG4gICAgQElucHV0KCkgdGFyZ2V0ITogc3RyaW5nO1xuICAgIEBJbnB1dCgpIGN1cnJlbmN5Q29kZTogQ3VycmVuY3lDb2RlRW51bSA9IEN1cnJlbmN5Q29kZUVudW0uQmxhbms7XG4gICAgQElucHV0KCkgbGVnZW5kUG9zaXRpb246IExlZ2VuZFBvc2l0aW9uRW51bSA9IExlZ2VuZFBvc2l0aW9uRW51bS5SaWdodDtcbiAgICBASW5wdXQoKSBsZWdlbmRUeXBlOiBDaGFydExlZ2VuZFR5cGVFbnVtID0gQ2hhcnRMZWdlbmRUeXBlRW51bS5Cb3RoO1xuICAgIEBJbnB1dCgpIGxlZ2VuZFdpZHRoUHggPSAyNTA7XG4gICAgQElucHV0KCkgbGVnZW5kTGF5b3V0OiBMZWdlbmRMYXlvdXRFbnVtID0gTGVnZW5kTGF5b3V0RW51bS5WZXJ0aWNhbDtcblxuICAgIEBPdXRwdXQoKSBzYW5rZXlDbGljazogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICAgIEBWaWV3Q2hpbGQoJ3NhbmtleUNoYXJ0JywgeyBzdGF0aWM6IHRydWUgfSkgc2Fua2V5Q2hhcnQhOiBFbGVtZW50UmVmO1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGN1cnJlbmN5UGlwZTogQ3VycmVuY3lQaXBlKSB7IH1cblxuICAgIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMudmlld0luaXRpYWxpemVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ2hhcnQoKTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudmlld0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ2hhcnQoKTtcbiAgICB9XG5cbiAgICBpbml0aWFsaXplQ2hhcnQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZykge1xuICAgICAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZztcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lcldpZHRoID0gdGhpcy5zYW5rZXlDaGFydC5uYXRpdmVFbGVtZW50LmNsaWVudFdpZHRoO1xuICAgICAgICAgICAgdGhpcy5kZXZpY2VTaXplID0gT2JqZWN0VXRpbHMuZmluZERldmljZVNpemUoY29udGFpbmVyV2lkdGgpO1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVDaGFydENyZWRpdCgpO1xuICAgICAgICAgICAgdGhpcy5zZXRTYW5rZXlDaGFydFRvb2x0aXAoKTtcbiAgICAgICAgICAgIGNvbnN0IHNlcmllczogU2VyaWVzUGllT3B0aW9uc1tdID0gdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24uc2VyaWVzIGFzIFNlcmllc1BpZU9wdGlvbnNbXTtcbiAgICAgICAgICAgIGlmICh0aGlzLmxlZ2VuZExheW91dCA9PT0gTGVnZW5kTGF5b3V0RW51bS5WZXJ0aWNhbCkge1xuICAgICAgICAgICAgICAgLy8gdGhpcy5zZXRTYW5rZXlDaGFydExlZ2VuZE9wdGlvbih0aGlzLmxlZ2VuZFdpZHRoUHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jbGlja09uU2Fua2V5KCk7XG4gICAgICAgICAgICBIaWdoY2hhcnRzLmNoYXJ0KHRoaXMuc2Fua2V5Q2hhcnQubmF0aXZlRWxlbWVudCwgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScpXG4gICAgb25SZXNpemUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUNoYXJ0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW1vdmVDaGFydENyZWRpdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24uY3JlZGl0cyA9IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRTYW5rZXlDaGFydFRvb2x0aXAoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHRoaXMkOiB0aGlzID0gdGhpcztcbiAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24udG9vbHRpcCA9IHtcbiAgICAgICAgICAgIHVzZUhUTUw6IHRydWUsXG4gICAgICAgICAgICBzcGxpdDogZmFsc2UsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IEFzd0NoYXJ0Q29uc3RhbnRzLmJsYWNrQ29sb3IsXG4gICAgICAgICAgICBib3JkZXJDb2xvcjogQXN3Q2hhcnRDb25zdGFudHMuYmxhY2tDb2xvcixcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgY29sb3I6IEFzd0NoYXJ0Q29uc3RhbnRzLndoaXRlQ29sb3IsXG4gICAgICAgICAgICAgICAgZm9udFdlaWdodDogQXN3Q2hhcnRDb25zdGFudHMuZm9udFdlaWdodFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJvcmRlclJhZGl1czogMCxcbiAgICAgICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgICAgICBmb3JtYXR0ZXIoKTogc3RyaW5nIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwb2ludDogYW55ID0gdGhpcy5wb2ludDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIHRleHQtZW5kIHRleHQtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiAke3BvaW50LmNvbG9yfVwiPlxcdTI1QTA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz4ke3BvaW50LnNlcmllcy5uYW1lfTwvc3Ryb25nPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIHRleHQtZW5kIHRleHQtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3BvaW50Lm9wdGlvbnMud2VpZ2h0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcG9pbnQub3B0aW9ucy5mcm9tICsgJyDihpIgJyArIHBvaW50Lm9wdGlvbnMudG8gKyAnOiAnICsgcG9pbnQub3B0aW9ucy53ZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBwb2ludC5vcHRpb25zLmlkICsgJzogJyArIHBvaW50LnN1bVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgY2xpY2tPblNhbmtleSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuY2xvbmVDb25maWd1cmF0aW9uLnBsb3RPcHRpb25zKSB7XG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5wbG90T3B0aW9ucyEuc2Fua2V5IS5wb2ludCA9IHtcbiAgICAgICAgICAgICAgICBldmVudHM6IHtcbiAgICAgICAgICAgICAgICAgICAgY2xpY2s6ICgoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9pbnRDbGlja0V2ZW50OiBTYW5rZXlDaGFydFBvaW50ZXJFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBldmVudC5wb2ludC5zZXJpZXMubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tOiBldmVudC5wb2ludC5vcHRpb25zLmZyb20gPz8gZXZlbnQucG9pbnQuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG86IGV2ZW50LnBvaW50Lm9wdGlvbnMudG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VpZ2h0OiBldmVudC5wb2ludC5vcHRpb25zLndlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW06IGV2ZW50LnBvaW50LnN1bVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Fua2V5Q2xpY2suZW1pdChwb2ludENsaWNrRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5wbG90T3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBzYW5rZXk6IHtcbiAgICAgICAgICAgICAgICAgICAgcG9pbnQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50czoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrOiAoKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9pbnRDbGlja0V2ZW50OiBTYW5rZXlDaGFydFBvaW50ZXJFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IGV2ZW50LnBvaW50LnNlcmllcy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbTogZXZlbnQucG9pbnQub3B0aW9ucy5mcm9tID8/IGV2ZW50LnBvaW50LmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG86IGV2ZW50LnBvaW50Lm9wdGlvbnMudG8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWlnaHQ6IGV2ZW50LnBvaW50Lm9wdGlvbnMud2VpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtOiBldmVudC5wb2ludC5zdW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zYW5rZXlDbGljay5lbWl0KHBvaW50Q2xpY2tFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNldERvbnV0Q2hhcnRTZXJpZXNPcHRpb25zKHNlcmllczogU2VyaWVzUGllT3B0aW9uc1tdKTogdm9pZCB7XG4gICAgICAgIHNlcmllcy5mb3JFYWNoKChzZXJpZXNPcHRpb246IFNlcmllc1BpZU9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5hbGxvd1BvaW50U2VsZWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5zaG93SW5MZWdlbmQgPSB0cnVlO1xuICAgICAgICAgICAgLy8gaWYgKHRoaXMuY2hhcnRUeXBlID09PSBDaGFydFR5cGVFbnVtLkRvbnV0KSB7XG4gICAgICAgICAgICAvLyAgICAgc2VyaWVzT3B0aW9uLmlubmVyU2l6ZSA9IEFzd0NoYXJ0Q29uc3RhbnRzLmlubmVyU2l6ZTtcbiAgICAgICAgICAgIC8vIH1cbiAgICAgICAgICAgIC8vIGlmICh0aGlzLmlzTXV0ZSkge1xuICAgICAgICAgICAgLy8gICAgIHNlcmllc09wdGlvbi5vcGFjaXR5ID0gMC4zNTtcbiAgICAgICAgICAgIC8vICAgICBzZXJpZXNPcHRpb24uc3RhdGVzID0ge1xuICAgICAgICAgICAgLy8gICAgICAgICBob3Zlcjoge1xuICAgICAgICAgICAgLy8gICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcbiAgICAgICAgICAgIC8vICAgICAgICAgfSxcbiAgICAgICAgICAgIC8vICAgICAgICAgaW5hY3RpdmU6IHtcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICAgICAgICAvLyAgICAgICAgIH1cbiAgICAgICAgICAgIC8vICAgICB9O1xuICAgICAgICAgICAgLy8gICAgIHNlcmllc09wdGlvbi5zbGljZWRPZmZzZXQgPSAwO1xuICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgc2VyaWVzT3B0aW9uLmN1cnNvciA9IEFzd0NoYXJ0Q29uc3RhbnRzLnBvaW50ZXI7XG4gICAgICAgICAgICBjb25zdCBkYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSA9IHNlcmllc09wdGlvbi5kYXRhIGFzIFBvaW50T3B0aW9uc09iamVjdFtdO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVOZWdhdGl2ZVNlcmllc0RhdGEoZGF0YSk7XG4gICAgICAgICAgICBjb25zdCBzb3J0ZWRTZXJpZXNPcHRpb25EYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSA9IHRoaXMuaXNMZWdlbmRTb3J0ID8gdGhpcy5zb3J0U2VyaWVzRGF0YShkYXRhKSA6IGRhdGE7XG4gICAgICAgICAgICBzZXJpZXNPcHRpb24uZGF0YSA9IHNvcnRlZFNlcmllc09wdGlvbkRhdGE7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc29ydFNlcmllc0RhdGEoZGF0YTogUG9pbnRPcHRpb25zT2JqZWN0W10pOiBQb2ludE9wdGlvbnNPYmplY3RbXSB7XG4gICAgICAgIGlmICh0aGlzLmxlZ2VuZFR5cGUgPT09IENoYXJ0TGVnZW5kVHlwZUVudW0uRGVmYXVsdCkge1xuICAgICAgICAgICAgZGF0YS5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAoJycgKyBhLm5hbWUpLmxvY2FsZUNvbXBhcmUoYi5uYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkYXRhLnNvcnQoKGE6IGFueSwgYjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGEueSAmJiBiLnkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGEudmFsdWUgLSBiLnZhbHVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGF0YS5yZXZlcnNlKCk7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlTmVnYXRpdmVTZXJpZXNEYXRhKGRhdGE6IFBvaW50T3B0aW9uc09iamVjdFtdKTogdm9pZCB7XG4gICAgICAgIGRhdGEuZm9yRWFjaCgoZWxlbWVudDogUG9pbnRPcHRpb25zT2JqZWN0KSA9PiB7XG4gICAgICAgICAgICBlbGVtZW50LnZhbHVlID0gZWxlbWVudC55O1xuICAgICAgICAgICAgZWxlbWVudC55ID0gZWxlbWVudC55ID8gTWF0aC5hYnMoZWxlbWVudC55KSA6IDAuMDAxO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldEZvbnRTaXplKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmRldmljZVNpemUgPT09IEdyaWRPcHRpb25zRW51bS5FeHRyYVNtYWxsID8gQXN3Q2hhcnRDb25zdGFudHMuZm9udFNpemUxNCA6IEFzd0NoYXJ0Q29uc3RhbnRzLmZvbnRTaXplMTY7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRTYW5rZXlDaGFydExlZ2VuZE9wdGlvbihsZWdlbmRXaWR0aFB4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGhpcyQ6IHRoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5sZWdlbmQgPSB7XG4gICAgICAgICAgICB1c2VIVE1MOiB0cnVlLFxuICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgIGZsb2F0aW5nOiBmYWxzZSxcbiAgICAgICAgICAgIGFsaWduOiB0aGlzLnNldExlZ2VuZEFsaWdubWVudCgpLFxuICAgICAgICAgICAgbGF5b3V0OiAndmVydGljYWwnLFxuICAgICAgICAgICAgdmVydGljYWxBbGlnbjogdGhpcy5zZXRMZWdlbmRWZXJ0aWNhbEFsaWdubWVudCgpLFxuICAgICAgICAgICAgc3ltYm9sSGVpZ2h0OiAxMCxcbiAgICAgICAgICAgIHN5bWJvbFdpZHRoOiAxMCxcbiAgICAgICAgICAgIHN5bWJvbFJhZGl1czogMCxcbiAgICAgICAgICAgIGl0ZW1NYXJnaW5Ub3A6IDMsIC8vIFNwYWNlIGJldHdlZW4gZWFjaCBjYXRlZ29yeSBpbiB0aGUgbGVnZW5kXG4gICAgICAgICAgICBpdGVtTWFyZ2luQm90dG9tOiAzLFxuICAgICAgICAgICAgaXRlbVN0eWxlOiB7XG4gICAgICAgICAgICAgICAgZm9udFNpemU6IHRoaXMuZGV2aWNlU2l6ZSA9PT0gR3JpZE9wdGlvbnNFbnVtLkV4dHJhU21hbGwgPyAnMTJweCcgOiAnMTRweCcsXG4gICAgICAgICAgICAgICAgZm9udFdlaWdodDogQXN3Q2hhcnRDb25zdGFudHMuZm9udFdlaWdodFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdpZHRoOiBsZWdlbmRXaWR0aFB4ICsgMTUsXG4gICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICAgIHRleHQ6IHRoaXMkLnNldExpbmVDaGFydExlZ2VuZFdpdGhIZWFkZXIobGVnZW5kV2lkdGhQeCArIDE1KSxcbiAgICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmb250U2l6ZTogdGhpcy5kZXZpY2VTaXplID09PSBHcmlkT3B0aW9uc0VudW0uRXh0cmFTbWFsbFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBBc3dDaGFydENvbnN0YW50cy5mb250U2l6ZTEyIDogQXN3Q2hhcnRDb25zdGFudHMuZm9udFNpemUxNCxcbiAgICAgICAgICAgICAgICAgICAgY29sb3I6ICcjNmM3NTdkJyxcbiAgICAgICAgICAgICAgICAgICAgZm9udFdlaWdodDogQXN3Q2hhcnRDb25zdGFudHMuZm9udFdlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgZm9udEZhbWlseTogJzUwMCAxNHB4LzIwcHggR29vZ2xlIFNhbnMgVGV4dCxBcmlhbCxIZWx2ZXRpY2Esc2Fucy1zZXJpZidcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWxGb3JtYXR0ZXIoKTogc3RyaW5nIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwb2ludDogYW55ID0gdGhpcyBhcyBQb2ludDtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHBvaW50LnlEYXRhLnJlZHVjZSgoYWNjOiBhbnksIGN1cjogYW55KSA9PiBhY2MgKyBjdXIsIDApO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzJC5zZXRMaW5lQ2hhcnRMZWdlbmRXaXRoSGVhZGVyKFxuICAgICAgICAgICAgICAgICAgICBsZWdlbmRXaWR0aFB4LFxuICAgICAgICAgICAgICAgICAgICBwb2ludC5uYW1lLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRMZWdlbmRBbGlnbm1lbnQoKTogQWxpZ25WYWx1ZSB7XG4gICAgICAgIGlmICh0aGlzLmRldmljZVNpemUgPT09IEdyaWRPcHRpb25zRW51bS5FeHRyYVNtYWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gJ2NlbnRlcic7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5sZWdlbmRQb3NpdGlvbiA9PT0gTGVnZW5kUG9zaXRpb25FbnVtLlJpZ2h0KSB7XG4gICAgICAgICAgICByZXR1cm4gTGVnZW5kUG9zaXRpb25FbnVtLlJpZ2h0O1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMubGVnZW5kUG9zaXRpb24gPT09IExlZ2VuZFBvc2l0aW9uRW51bS5MZWZ0KSB7XG4gICAgICAgICAgICByZXR1cm4gTGVnZW5kUG9zaXRpb25FbnVtLkxlZnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gJ2NlbnRlcic7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNldExlZ2VuZFZlcnRpY2FsQWxpZ25tZW50KCk6IFZlcnRpY2FsQWxpZ25WYWx1ZSB7XG4gICAgICAgIGlmICh0aGlzLmRldmljZVNpemUgPT09IEdyaWRPcHRpb25zRW51bS5FeHRyYVNtYWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gTGVnZW5kUG9zaXRpb25FbnVtLkJvdHRvbTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmxlZ2VuZFBvc2l0aW9uID09PSBMZWdlbmRQb3NpdGlvbkVudW0uUmlnaHQpIHtcbiAgICAgICAgICAgIHJldHVybiAnbWlkZGxlJztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmxlZ2VuZFBvc2l0aW9uID09PSBMZWdlbmRQb3NpdGlvbkVudW0uTGVmdCkge1xuICAgICAgICAgICAgcmV0dXJuICdtaWRkbGUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIExlZ2VuZFBvc2l0aW9uRW51bS5Cb3R0b207XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNldExpbmVDaGFydExlZ2VuZFdpdGhIZWFkZXIoXG4gICAgICAgIGxlZ2VuZFdpZHRoUHg6IG51bWJlcixcbiAgICAgICAgbmFtZT86IHN0cmluZyB8IG51bGwsXG4gICAgICAgIHZhbHVlPzogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gICAgICAgIGxldCBsZWdlbmRDYXRlZ29yeVdpZHRoUHg6IG51bWJlcjtcbiAgICAgICAgbGV0IGxlZ2VuZFZhbHVlV2lkdGhQeDogbnVtYmVyO1xuICAgICAgICBpZiAodGhpcy5sZWdlbmRUeXBlID09PSBDaGFydExlZ2VuZFR5cGVFbnVtLkRlZmF1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cIndpZHRoOiR7bGVnZW5kV2lkdGhQeH1weFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIGNvbC1zbS0xMiBjb2wtMTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke25hbWUgPyBuYW1lIDogJ0NhdGVnb3J5J31cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGVnZW5kQ2F0ZWdvcnlXaWR0aFB4ID0gbGVnZW5kV2lkdGhQeCAqIDAuNTtcbiAgICAgICAgICAgIGxlZ2VuZFZhbHVlV2lkdGhQeCA9IGxlZ2VuZFdpZHRoUHggKiAwLjU7XG4gICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJ3aWR0aDoke2xlZ2VuZENhdGVnb3J5V2lkdGhQeCArIGxlZ2VuZFZhbHVlV2lkdGhQeH1weFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgY29sLXNtLTYgY29sLTZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke25hbWUgPyBuYW1lIDogJ0NhdGVnb3J5J31cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGNvbC1zbS02IGNvbC02IHRleHQtZW5kIHRleHQtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAke3ZhbHVlID8gdGhpcy5jdXJyZW5jeVBpcGUudHJhbnNmb3JtKHZhbHVlLCB0aGlzLmN1cnJlbmN5Q29kZSwgJ3N5bWJvbCcsICcuMicpIDogJ1RvdGFsJ31cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5gO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiPGRpdiAjc2Fua2V5Q2hhcnQ+PC9kaXY+Il19