@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.
456 lines • 66.8 kB
JavaScript
import { Component, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core';
import { AswChartConstants, CurrencyCodeEnum, GridOptionsEnum, LegendLayoutEnum, LegendPositionEnum, PieLegendTypeEnum } from '@asoftwareworld/charts/core';
import { ObjectUtils } from '@asoftwareworld/charts/utils';
import * as Highcharts from 'highcharts';
import { ChartTypeEnum } from '../enum/chart-type.enum';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@asoftwareworld/charts/core";
export class AswPieDonut {
constructor(percentPipe, currencyPipe, aswCurrencyPipe) {
this.percentPipe = percentPipe;
this.currencyPipe = currencyPipe;
this.aswCurrencyPipe = aswCurrencyPipe;
this.deviceSize = GridOptionsEnum.Large;
this.viewInitialized = false;
this.isLegendSort = true;
this.isMute = false;
this.isLegendDisplay = true;
this.chartType = ChartTypeEnum.Donut;
this.currencyCode = CurrencyCodeEnum.Blank;
this.legendPosition = LegendPositionEnum.Right;
this.legendType = PieLegendTypeEnum.Both;
this.legendWidthPx = 250;
this.legendLayout = LegendLayoutEnum.Vertical;
this.donutSliceClick = 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.pieDonutChart.nativeElement.clientWidth;
this.deviceSize = ObjectUtils.findDeviceSize(containerWidth);
this.removeChartCredit();
this.setDonutChartTooltip();
const series = this.cloneConfiguration.series;
this.setDonutChartSeriesOptions(series);
if (series[0].data?.length) {
if (this.legendLayout === LegendLayoutEnum.Vertical) {
this.setDonutChartLegendOption(this.legendWidthPx);
}
if (this.chartType === ChartTypeEnum.Donut) {
this.setDonutChartInnerText();
}
this.donutChartSliceClick();
}
Highcharts.chart(this.pieDonutChart.nativeElement, this.cloneConfiguration);
}
}
onResize() {
this.initializeChart();
}
removeChartCredit() {
this.cloneConfiguration.credits = {
enabled: false
};
}
setDonutChartTooltip() {
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: this.isMute ? false : true,
formatter() {
const percentage = this.point.percentage;
return `
<div class="row">
<div class="col-md-12 text-end text-right">
<span style="color: ${this.point.color}">\u25A0</span>
<strong>${this.point.name}</strong>
</div>
<div class="col-md-12 text-end text-right">
${this$.percentPipe.transform(percentage / 100, '.2')}
</div>
<div class="col-md-12 text-end text-right">
${this$.currencyCode === CurrencyCodeEnum.Blank
? this.point.options.value : this$.currencyPipe.transform(this.point.options.value, this$.currencyCode)}
</div>
</div>
`;
}
};
}
donutChartSliceClick() {
if (this.isMute) {
return;
}
this.cloneConfiguration.plotOptions = {
series: {
dataLabels: {
enabled: false
},
point: {
events: {
click: ((event) => {
const pointClickEvent = {
name: event.point.name,
id: event.point.options.id,
percentage: event.point.percentage,
value: event.point.options.value,
target: event.point.options.target
};
this.donutSliceClick.emit(pointClickEvent);
})
}
}
}
};
}
setDonutChartSeriesOptions(series) {
series.forEach((seriesOption) => {
seriesOption.allowPointSelect = true;
seriesOption.showInLegend = true;
if (this.chartType === ChartTypeEnum.Donut) {
seriesOption.innerSize = AswChartConstants.innerSize;
}
else {
seriesOption.innerSize = '0%';
}
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 === PieLegendTypeEnum.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;
});
}
setDonutChartLegendOption(legendWidthPx) {
const this$ = this;
this.cloneConfiguration.legend = {
useHTML: true,
enabled: this.isMute ? false : 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$.setDonutChartLegendWithHeader(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;
return this$.setDonutChartLegendWithHeader(legendWidthPx, point.name, point.percentage, point.options.value);
}
};
}
setFontSize() {
return this.deviceSize === GridOptionsEnum.ExtraSmall ? AswChartConstants.fontSize14 : AswChartConstants.fontSize16;
}
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;
}
}
setDonutChartLegendWithHeader(legendWidthPx, name, percentage, value) {
let legendCategoryWidthPx;
let legendValueWidthPx;
let legendPercentageWidthPx;
switch (this.legendType) {
case PieLegendTypeEnum.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>
`;
case PieLegendTypeEnum.Percentage:
legendCategoryWidthPx = legendWidthPx * 0.9;
legendPercentageWidthPx = legendWidthPx * 0.1;
return `
<div style="width:${legendCategoryWidthPx + legendPercentageWidthPx}px">
<div class="row">
<div class="col-md-8 col-sm-8 col-8">
${name ? name : 'Category'}
</div>
<div class="col-md-4 col-sm-4 col-4 text-end text-right">
${percentage ? this.percentPipe.transform(percentage / 100, '.0') : '%'}
</div>
</div>
</div>
`;
case PieLegendTypeEnum.Value:
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) : 'Total'}
</div>
</div>
</div>
`;
default:
legendCategoryWidthPx = legendWidthPx * 0.5;
legendPercentageWidthPx = legendWidthPx * 0.1;
legendValueWidthPx = legendWidthPx * 0.4;
return `
<div style="width:${legendCategoryWidthPx + legendPercentageWidthPx + legendValueWidthPx}px">
<div class="row">
<div class="col-md-5 col-sm-5 col-5">
${name ? name : 'Category'}
</div>
<div class="col-md-2 col-xs-2 col-2 text-end text-right">
${percentage ? this.percentPipe.transform(percentage / 100) : '%'}
</div>
<div class="col-md-5 col-sm-5 col-5 text-end text-right">
${value ? this.currencyCode === CurrencyCodeEnum.Blank
? value : this.currencyPipe.transform(value, this.currencyCode, 'symbol', '.2') : 'Total'}
</div>
</div>
</div>
`;
}
}
setDonutChartInnerText() {
const this$ = this;
this.cloneConfiguration.chart = {
events: {
load() {
let centerX;
let centerY;
let itemWidth;
this.series.forEach((element) => {
const points = element.points.slice(0, 1);
points.forEach((point) => {
centerX = this.plotLeft + (point.shapeArgs.x - point.shapeArgs.innerR) + 8;
centerY = this.plotTop + point.shapeArgs.y - 14;
itemWidth = (point.shapeArgs.innerR * 2) - 20;
});
if (this$.icon) {
this.renderer.label(this$.setInnerTextIcon(itemWidth), centerX, this$.deviceSize === GridOptionsEnum.ExtraSmall ? centerY - 20 : centerY - 25, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
this.renderer.label(this$.setInnerTextLabel(itemWidth), centerX, centerY, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
this.renderer.label(this$.setInnerTextValue(itemWidth), centerX, this$.deviceSize === GridOptionsEnum.ExtraSmall ? centerY + 20 : centerY + 25, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
}
else {
this.renderer.label(this$.setInnerTextLabel(itemWidth), centerX, this$.deviceSize === GridOptionsEnum.ExtraSmall ? centerY - 20 : centerY - 25, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
this.renderer.label(this$.setInnerTextValue(itemWidth), centerX, centerY, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
this.renderer.label(this$.setInnerTextTarget(itemWidth), centerX, this$.deviceSize === GridOptionsEnum.ExtraSmall ? centerY + 20 : centerY + 25, undefined, 30, 30, true).css({
fontSize: this$.setFontSize(),
textAlign: AswChartConstants.centerAlign,
fontWeight: AswChartConstants.fontWeight
}).add();
}
});
}
}
};
}
setInnerTextLabel(width) {
return `
<div style="width: ${width}px; opacity: ${this.isMute ? 0.35 : 1}">
<div class="row">
<div class="col-md-12 text-truncate">
${this.label ? this.label : ''}
</div>
</div>
</div>
`;
}
setInnerTextIcon(width) {
return `
<div style="width: ${width}px; opacity: ${this.isMute ? 0.35 : 1}">
<div class="row">
<div class="col-md-12 text-truncate">
${this.icon ? this.icon : ''}
</div>
</div>
</div>
`;
}
setInnerTextValue(width) {
return `
<div style="width: ${width}px; opacity: ${this.isMute ? 0.35 : 1}">
<div class="row">
<div class="col-md-12 text-truncate">
<strong>${this.amount ? this.currencyCode === CurrencyCodeEnum.Blank
? this.amount : this.currencyPipe.transform(this.amount, this.currencyCode) : ''}</strong>
</div>
</div>
</div>
`;
}
setInnerTextTarget(width) {
return `
<div style="width: ${width}px; opacity: ${this.isMute ? 0.35 : 1}">
<div class="row">
<div class="col-md-12 text-truncate">
${this.target ? this.target : ''}
</div>
</div>
</div>
`;
}
}
AswPieDonut.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswPieDonut, deps: [{ token: i1.PercentPipe }, { token: i1.CurrencyPipe }, { token: i2.AswCurrencyPipe }], target: i0.ɵɵFactoryTarget.Component });
AswPieDonut.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: AswPieDonut, selector: "asw-pie-donut", inputs: { config: "config", isLegendSort: "isLegendSort", isMute: "isMute", isLegendDisplay: "isLegendDisplay", icon: "icon", label: "label", amount: "amount", target: "target", chartType: "chartType", currencyCode: "currencyCode", legendPosition: "legendPosition", legendType: "legendType", legendWidthPx: "legendWidthPx", legendLayout: "legendLayout" }, outputs: { donutSliceClick: "donutSliceClick" }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "pieDonutChart", first: true, predicate: ["pieDonutChart"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #pieDonutChart></div>", styles: [""] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswPieDonut, decorators: [{
type: Component,
args: [{ selector: 'asw-pie-donut', template: "<div #pieDonutChart></div>", styles: [""] }]
}], ctorParameters: function () { return [{ type: i1.PercentPipe }, { type: i1.CurrencyPipe }, { type: i2.AswCurrencyPipe }]; }, propDecorators: { config: [{
type: Input
}], isLegendSort: [{
type: Input
}], isMute: [{
type: Input
}], isLegendDisplay: [{
type: Input
}], icon: [{
type: Input
}], label: [{
type: Input
}], amount: [{
type: Input
}], target: [{
type: Input
}], chartType: [{
type: Input
}], currencyCode: [{
type: Input
}], legendPosition: [{
type: Input
}], legendType: [{
type: Input
}], legendWidthPx: [{
type: Input
}], legendLayout: [{
type: Input
}], donutSliceClick: [{
type: Output
}], pieDonutChart: [{
type: ViewChild,
args: ['pieDonutChart', { static: true }]
}], onResize: [{
type: HostListener,
args: ['window:resize']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGllLWRvbnV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9jb21wb25lbnQvcGllLWRvbnV0L2NvbXBvbmVudC9waWUtZG9udXQudHMiLCIuLi8uLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudC9waWUtZG9udXQvY29tcG9uZW50L3BpZS1kb251dC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNBLE9BQU8sRUFFSCxTQUFTLEVBRVQsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0gsaUJBQWlCLEVBRWpCLGdCQUFnQixFQUNoQixlQUFlLEVBQ2YsZ0JBQWdCLEVBQ2hCLGtCQUFrQixFQUNsQixpQkFBaUIsRUFFcEIsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDM0QsT0FBTyxLQUFLLFVBQVUsTUFBTSxZQUFZLENBQUM7QUFXekMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7O0FBT3hELE1BQU0sT0FBTyxXQUFXO0lBdUJwQixZQUNZLFdBQXdCLEVBQ3hCLFlBQTBCLEVBQzFCLGVBQWdDO1FBRmhDLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQXZCckMsZUFBVSxHQUFvQixlQUFlLENBQUMsS0FBSyxDQUFDO1FBQ25ELG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBRXZCLGlCQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLFdBQU0sR0FBRyxLQUFLLENBQUM7UUFDZixvQkFBZSxHQUFHLElBQUksQ0FBQztRQUt2QixjQUFTLEdBQWtCLGFBQWEsQ0FBQyxLQUFLLENBQUM7UUFDL0MsaUJBQVksR0FBcUIsZ0JBQWdCLENBQUMsS0FBSyxDQUFDO1FBQ3hELG1CQUFjLEdBQXVCLGtCQUFrQixDQUFDLEtBQUssQ0FBQztRQUM5RCxlQUFVLEdBQXNCLGlCQUFpQixDQUFDLElBQUksQ0FBQztRQUN2RCxrQkFBYSxHQUFHLEdBQUcsQ0FBQztRQUNwQixpQkFBWSxHQUFxQixnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7UUFFMUQsb0JBQWUsR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztJQU12QixDQUFDO0lBRWpELFdBQVc7UUFDUCxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN2QixPQUFPO1NBQ1Y7UUFDRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELGVBQWU7UUFDWCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztRQUM1QixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELGVBQWU7UUFDWCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDYixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUN0QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUM7WUFDcEUsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQzVCLE1BQU0sTUFBTSxHQUF1QixJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBNEIsQ0FBQztZQUN4RixJQUFJLENBQUMsMEJBQTBCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEMsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRTtnQkFDeEIsSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLGdCQUFnQixDQUFDLFFBQVEsRUFBRTtvQkFDakQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztpQkFDdEQ7Z0JBQ0QsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLGFBQWEsQ0FBQyxLQUFLLEVBQUU7b0JBQ3hDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO2lCQUNqQztnQkFDRCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQzthQUMvQjtZQUNELFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7U0FDL0U7SUFDTCxDQUFDO0lBR0QsUUFBUTtRQUNKLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8saUJBQWlCO1FBQ3JCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEdBQUc7WUFDOUIsT0FBTyxFQUFFLEtBQUs7U0FDakIsQ0FBQztJQUNOLENBQUM7SUFFTyxvQkFBb0I7UUFDeEIsTUFBTSxLQUFLLEdBQVMsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEdBQUc7WUFDOUIsT0FBTyxFQUFFLElBQUk7WUFDYixLQUFLLEVBQUUsS0FBSztZQUNaLGVBQWUsRUFBRSxpQkFBaUIsQ0FBQyxVQUFVO1lBQzdDLFdBQVcsRUFBRSxpQkFBaUIsQ0FBQyxVQUFVO1lBQ3pDLEtBQUssRUFBRTtnQkFDSCxLQUFLLEVBQUUsaUJBQWlCLENBQUMsVUFBVTtnQkFDbkMsVUFBVSxFQUFFLGlCQUFpQixDQUFDLFVBQVU7YUFDM0M7WUFDRCxZQUFZLEVBQUUsQ0FBQztZQUNmLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUk7WUFDbkMsU0FBUztnQkFDTCxNQUFNLFVBQVUsR0FBVyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQW9CLENBQUM7Z0JBQzNELE9BQU87OztrREFHMkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLO3NDQUM1QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUk7Ozs4QkFHdkIsS0FBSyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLEdBQUcsRUFBRSxJQUFJLENBQUM7Ozs4QkFHbkQsS0FBSyxDQUFDLFlBQVksS0FBSyxnQkFBZ0IsQ0FBQyxLQUFLO29CQUMzQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLFlBQVksQ0FBQzs7O2lCQUd0SCxDQUFDO1lBQ04sQ0FBQztTQUNKLENBQUM7SUFDTixDQUFDO0lBRU8sb0JBQW9CO1FBQ3hCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUFFLE9BQU87U0FBRTtRQUM1QixJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxHQUFHO1lBQ2xDLE1BQU0sRUFBRTtnQkFDSixVQUFVLEVBQUU7b0JBQ1IsT0FBTyxFQUFFLEtBQUs7aUJBQ2pCO2dCQUNELEtBQUssRUFBRTtvQkFDSCxNQUFNLEVBQUU7d0JBQ0osS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUE0QixFQUFFLEVBQUU7NEJBQ3JDLE1BQU0sZUFBZSxHQUFvQjtnQ0FDckMsSUFBSSxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSTtnQ0FDdEIsRUFBRSxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7Z0NBQzFCLFVBQVUsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLFVBQVU7Z0NBQ2xDLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLO2dDQUNoQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTTs2QkFDckMsQ0FBQzs0QkFDRixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQzt3QkFDL0MsQ0FBQyxDQUFDO3FCQUNMO2lCQUNKO2FBQ0o7U0FDSixDQUFDO0lBQ04sQ0FBQztJQUVPLDBCQUEwQixDQUFDLE1BQTBCO1FBQ3pELE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxZQUE4QixFQUFFLEVBQUU7WUFDOUMsWUFBWSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztZQUNyQyxZQUFZLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztZQUNqQyxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssYUFBYSxDQUFDLEtBQUssRUFBRTtnQkFDeEMsWUFBWSxDQUFDLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLENBQUM7YUFDeEQ7aUJBQU07Z0JBQ0gsWUFBWSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7YUFDakM7WUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ2IsWUFBWSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7Z0JBQzVCLFlBQVksQ0FBQyxNQUFNLEdBQUc7b0JBQ2xCLEtBQUssRUFBRTt3QkFDSCxPQUFPLEVBQUUsS0FBSztxQkFDakI7b0JBQ0QsUUFBUSxFQUFFO3dCQUNOLE9BQU8sRUFBRSxLQUFLO3FCQUNqQjtpQkFDSixDQUFDO2dCQUNGLFlBQVksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO2FBQ2pDO1lBQ0QsWUFBWSxDQUFDLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxPQUFPLENBQUM7WUFDaEQsTUFBTSxJQUFJLEdBQXlCLFlBQVksQ0FBQyxJQUE0QixDQUFDO1lBQzdFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwQyxNQUFNLHNCQUFzQixHQUF5QixJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDMUcsWUFBWSxDQUFDLElBQUksR0FBRyxzQkFBc0IsQ0FBQztRQUMvQyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyxjQUFjLENBQUMsSUFBMEI7UUFDN0MsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLGlCQUFpQixDQUFDLE9BQU8sRUFBRTtZQUMvQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxFQUFFO2dCQUN6QixPQUFPLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9DLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxJQUFJLENBQUM7U0FDZjthQUFNO1lBQ0gsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQU0sRUFBRSxDQUFNLEVBQUUsRUFBRTtnQkFDekIsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ1osT0FBTyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7aUJBQzVCO3FCQUFNO29CQUNILE9BQU8sQ0FBQyxDQUFDO2lCQUNaO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDZixPQUFPLElBQUksQ0FBQztTQUNmO0lBQ0wsQ0FBQztJQUVPLHdCQUF3QixDQUFDLElBQTBCO1FBQ3ZELElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUEyQixFQUFFLEVBQUU7WUFDekMsT0FBTyxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQzFCLE9BQU8sQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUN4RCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyx5QkFBeUIsQ0FBQyxhQUFxQjtRQUNuRCxNQUFNLEtBQUssR0FBUyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sR0FBRztZQUM3QixPQUFPLEVBQUUsSUFBSTtZQUNiLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlO1lBQ25ELFFBQVEsRUFBRSxLQUFLO1lBQ2YsS0FBSyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUNoQyxNQUFNLEVBQUUsVUFBVTtZQUNsQixhQUFhLEVBQUUsSUFBSSxDQUFDLDBCQUEwQixFQUFFO1lBQ2hELFlBQVksRUFBRSxFQUFFO1lBQ2hCLFdBQVcsRUFBRSxFQUFFO1lBQ2YsWUFBWSxFQUFFLENBQUM7WUFDZixhQUFhLEVBQUUsQ0FBQztZQUNoQixnQkFBZ0IsRUFBRSxDQUFDO1lBQ25CLFNBQVMsRUFBRTtnQkFDUCxRQUFRLEVBQUUsSUFBSSxDQUFDLFVBQVUsS0FBSyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU07Z0JBQzFFLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxVQUFVO2FBQzNDO1lBQ0QsS0FBSyxFQUFFLGFBQWEsR0FBRyxFQUFFO1lBQ3pCLEtBQUssRUFBRTtnQkFDSCxJQUFJLEVBQUUsS0FBSyxDQUFDLDZCQUE2QixDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7Z0JBQzdELEtBQUssRUFBRTtvQkFDSCxRQUFRLEVBQUUsSUFBSSxDQUFDLFVBQVUsS0FBSyxlQUFlLENBQUMsVUFBVTt3QkFDcEQsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsVUFBVTtvQkFDakUsS0FBSyxFQUFFLFNBQVM7b0JBQ2hCLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxVQUFVO29CQUN4QyxVQUFVLEVBQUUsMkRBQTJEO2lCQUMxRTthQUNKO1lBQ0QsY0FBYztnQkFDVixNQUFNLEtBQUssR0FBVSxJQUFhLENBQUM7Z0JBQ25DLE9BQU8sS0FBSyxDQUFDLDZCQUE2QixDQUN0QyxhQUFhLEVBQ2IsS0FBSyxDQUFDLElBQUksRUFDVixLQUFLLENBQUMsVUFBVSxFQUNoQixLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzdCLENBQUM7U0FDSixDQUFDO0lBQ04sQ0FBQztJQUVPLFdBQVc7UUFDZixPQUFPLElBQUksQ0FBQyxVQUFVLEtBQUssZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUM7SUFDeEgsQ0FBQztJQUVPLGtCQUFrQjtRQUN0QixJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssZUFBZSxDQUFDLFVBQVUsRUFBRTtZQUNoRCxPQUFPLFFBQVEsQ0FBQztTQUNuQjthQUFNLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7WUFDekQsT0FBTyxrQkFBa0IsQ0FBQyxLQUFLLENBQUM7U0FDbkM7YUFBTSxJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssa0JBQWtCLENBQUMsSUFBSSxFQUFFO1lBQ3hELE9BQU8sa0JBQWtCLENBQUMsSUFBSSxDQUFDO1NBQ2xDO2FBQU07WUFDSCxPQUFPLFFBQVEsQ0FBQztTQUNuQjtJQUNMLENBQUM7SUFFTywwQkFBMEI7UUFDOUIsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLGVBQWUsQ0FBQyxVQUFVLEVBQUU7WUFDaEQsT0FBTyxrQkFBa0IsQ0FBQyxNQUFNLENBQUM7U0FDcEM7YUFBTSxJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssa0JBQWtCLENBQUMsS0FBSyxFQUFFO1lBQ3pELE9BQU8sUUFBUSxDQUFDO1NBQ25CO2FBQU0sSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLGtCQUFrQixDQUFDLElBQUksRUFBRTtZQUN4RCxPQUFPLFFBQVEsQ0FBQztTQUNuQjthQUFNO1lBQ0gsT0FBTyxrQkFBa0IsQ0FBQyxNQUFNLENBQUM7U0FDcEM7SUFDTCxDQUFDO0lBRU8sNkJBQTZCLENBQ2pDLGFBQXFCLEVBQ3JCLElBQW9CLEVBQ3BCLFVBQStCLEVBQy9CLEtBQWlDO1FBQ2pDLElBQUkscUJBQTZCLENBQUM7UUFDbEMsSUFBSSxrQkFBMEIsQ0FBQztRQUMvQixJQUFJLHVCQUErQixDQUFDO1FBQ3BDLFFBQVEsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNyQixLQUFLLGlCQUFpQixDQUFDLE9BQU87Z0JBQzFCLE9BQU87b0NBQ2EsYUFBYTs7OzhCQUduQixJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVTs7OztpQkFJckMsQ0FBQztZQUNOLEtBQUssaUJBQWlCLENBQUMsVUFBVTtnQkFDN0IscUJBQXFCLEdBQUcsYUFBYSxHQUFHLEdBQUcsQ0FBQztnQkFDNUMsdUJBQXVCLEdBQUcsYUFBYSxHQUFHLEdBQUcsQ0FBQztnQkFDOUMsT0FBTztvQ0FDYSxxQkFBcUIsR0FBRyx1QkFBdUI7Ozs4QkFHckQsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVU7Ozs4QkFHeEIsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHOzs7O2lCQUlsRixDQUFDO1lBQ04sS0FBSyxpQkFBaUIsQ0FBQyxLQUFLO2dCQUN4QixxQkFBcUIsR0FBRyxhQUFhLEdBQUcsR0FBRyxDQUFDO2dCQUM1QyxrQkFBa0IsR0FBRyxhQUFhLEdBQUcsR0FBRyxDQUFDO2dCQUN6QyxPQUFPO29DQUNhLHFCQUFxQixHQUFHLGtCQUFrQjs7OzhCQUdoRCxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVTs7OzhCQUd4QixLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLEtBQUssZ0JBQWdCLENBQUMsS0FBSztvQkFDbEQsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTzs7OztpQkFJeEYsQ0FBQztZQUNOO2dCQUNJLHFCQUFxQixHQUFHLGFBQWEsR0FBRyxHQUFHLENBQUM7Z0JBQzVDLHVCQUF1QixHQUFHLGFBQWEsR0FBRyxHQUFHLENBQUM7Z0JBQzlDLGtCQUFrQixHQUFHLGFBQWEsR0FBRyxHQUFHLENBQUM7Z0JBQ3pDLE9BQU87b0NBQ2EscUJBQXFCLEdBQUcsdUJBQXVCLEdBQUcsa0JBQWtCOzs7OEJBRzFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVOzs7OEJBR3hCLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHOzs7OEJBRy9ELEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksS0FBSyxnQkFBZ0IsQ0FBQyxLQUFLO29CQUNsRCxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU87Ozs7aUJBSXhHLENBQUM7U0FDVDtJQUNMLENBQUM7SUFFTyxzQkFBc0I7UUFDMUIsTUFBTSxLQUFLLEdBQVMsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEdBQUc7WUFDNUIsTUFBTSxFQUFFO2dCQUNKLElBQUk7b0JBQ0EsSUFBSSxPQUFlLENBQUM7b0JBQ3BCLElBQUksT0FBZSxDQUFDO29CQUNwQixJQUFJLFNBQWlCLENBQUM7b0JBQ3RCLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBZSxFQUFFLEVBQUU7d0JBQ3BDLE1BQU0sTUFBTSxHQUFZLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzt3QkFDbkQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQVUsRUFBRSxFQUFFOzRCQUMxQixPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDOzRCQUMzRSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7NEJBQ2hELFNBQVMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDbEQsQ0FBQyxDQUFDLENBQUM7d0JBQ0gsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFOzRCQUNaLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsRUFDakQsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLEtBQUssZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEVBQUUsRUFDdEYsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDO2dDQUN6QixRQUFRLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRTtnQ0FDN0IsU0FBUyxFQUFFLGlCQUFpQixDQUFDLFdBQVc7Z0NBQ3hDLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxVQUFVOzZCQUMzQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7NEJBQ2IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxFQUNsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQ0FDM0MsUUFBUSxFQUFFLEtBQUssQ0FBQyxXQUFXLEVBQUU7Z0NBQzdCLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxXQUFXO2dDQUN4QyxVQUFVLEVBQUUsaUJBQWlCLENBQUMsVUFBVTs2QkFDM0MsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDOzRCQUNiLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsRUFDbEQsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLEtBQUssZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEVBQUUsRUFDdEYsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDO2dDQUN6QixRQUFRLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRTtnQ0FDN0IsU0FBUyxFQUFFLGlCQUFpQixDQUFDLFdBQVc7Z0NBQ3hDLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxVQUFVOzZCQUMzQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7eUJBQ2hCOzZCQUFNOzRCQUNILElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsRUFDbEQsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLEtBQUssZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEVBQUUsRUFDdEYsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDO2dDQUN6QixRQUFRLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRTtnQ0FDN0IsU0FBUyxFQUFFLGlCQUFpQixDQUFDLFdBQVc7Z0NBQ3hDLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxVQUFVOzZCQUMzQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7NEJBQ2IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxFQUNsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQ0FDM0MsUUFBUSxFQUFFLEtBQUssQ0FBQyxXQUFXLEVBQUU7Z0NBQzdCLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxXQUFXO2dDQUN4QyxVQUFVLEVBQUUsaUJBQWlCLENBQUMsVUFBVTs2QkFDM0MsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDOzRCQUNiLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsRUFDbkQsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLEtBQUssZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEVBQUUsRUFDdEYsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDO2dDQUN6QixRQUFRLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRTtnQ0FDN0IsU0FBUyxFQUFFLGlCQUFpQixDQUFDLFdBQVc7Z0NBQ3hDLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxVQUFVOzZCQUMzQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7eUJBQ2hCO29CQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUNQLENBQUM7YUFDSjtTQUNKLENBQUM7SUFDTixDQUFDO0lBRU8saUJBQWlCLENBQUMsS0FBYTtRQUNuQyxPQUFPOzZCQUNjLEtBQUssZ0JBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs7O3NCQUdsRCxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFOzs7O1NBSXpDLENBQUM7SUFDTixDQUFDO0lBRU8sZ0JBQWdCLENBQUMsS0FBYTtRQUNsQyxPQUFPOzZCQUNjLEtBQUssZ0JBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs7O3NCQUdsRCxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFOzs7O1NBSXZDLENBQUM7SUFDTixDQUFDO0lBRU8saUJBQWlCLENBQUMsS0FBYTtRQUNuQyxPQUFPOzZCQUNjLEtBQUssZ0JBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs7OzhCQUcxQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLGdCQUFnQixDQUFDLEtBQUs7WUFDaEUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFOzs7O1NBSS9GLENBQUM7SUFDTixDQUFDO0lBRU8sa0JBQWtCLENBQUMsS0FBYTtRQUNwQyxPQUFPOzZCQUNjLEtBQUssZ0JBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs7O3NCQUdsRCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFOzs7O1NBSTNDLENBQUM7SUFDTixDQUFDOzt3R0F2YlEsV0FBVzs0RkFBWCxXQUFXLHFwQkNqRHhCLDRCQUEwQjsyRkRpRGIsV0FBVztrQkFMdkIsU0FBUzsrQkFDSSxlQUFlOzJKQVNoQixNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBRUksZUFBZTtzQkFBeEIsTUFBTTtnQkFFdUMsYUFBYTtzQkFBMUQsU0FBUzt1QkFBQyxlQUFlLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQXlDNUMsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEFTVyAoQSBTb2Z0d2FyZSBXb3JsZCkgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cclxuICpcclxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcclxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IEN1cnJlbmN5UGlwZSwgUGVyY2VudFBpcGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQge1xyXG4gICAgQWZ0ZXJWaWV3SW5pdCxcclxuICAgIENvbXBvbmVudCxcclxuICAgIEVsZW1lbnRSZWYsXHJcbiAgICBFdmVudEVtaXR0ZXIsXHJcbiAgICBIb3N0TGlzdGVuZXIsXHJcbiAgICBJbnB1dCxcclxuICAgIE9uQ2hhbmdlcyxcclxuICAgIE91dHB1dCxcclxuICAgIFZpZXdDaGlsZFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gICAgQXN3Q2hhcnRDb25zdGFudHMsXHJcbiAgICBBc3dDdXJyZW5jeVBpcGUsXHJcbiAgICBDdXJyZW5jeUNvZGVFbnVtLFxyXG4gICAgR3JpZE9wdGlvbnNFbnVtLFxyXG4gICAgTGVnZW5kTGF5b3V0RW51bSxcclxuICAgIExlZ2VuZFBvc2l0aW9uRW51bSxcclxuICAgIFBpZUxlZ2VuZFR5cGVFbnVtLFxyXG4gICAgUG9pbnRDbGlja0V2ZW50XHJcbn0gZnJvbSAnQGFzb2Z0d2FyZXdvcmxkL2NoYXJ0cy9jb3JlJztcclxuaW1wb3J0IHsgT2JqZWN0VXRpbHMgfSBmcm9tICdAYXNvZnR3YXJld29ybGQvY2hhcnRzL3V0aWxzJztcclxuaW1wb3J0ICogYXMgSGlnaGNoYXJ0cyBmcm9tICdoaWdoY2hhcnRzJztcclxuaW1wb3J0IHtcclxuICAgIEFsaWduVmFsdWUsXHJcbiAgICBPcHRpb25zLFxyXG4gICAgUG9pbnRDbGlja0V2ZW50T2JqZWN0LFxyXG4gICAgUG9pbnRPcHRpb25zT2JqZWN0LFxyXG4gICAgUG9pbnQsXHJcbiAgICBTZXJpZXMsXHJcbiAgICBTZXJpZXNQaWVPcHRpb25zLFxyXG4gICAgVmVydGljYWxBbGlnblZhbHVlXHJcbn0gZnJvbSAnaGlnaGNoYXJ0cyc7XHJcbmltcG9ydCB7IENoYXJ0VHlwZUVudW0gfSBmcm9tICcuLi9lbnVtL2NoYXJ0LXR5cGUuZW51bSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnYXN3LXBpZS1kb251dCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vcGllLWRvbnV0Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vcGllLWRvbnV0LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXN3UGllRG9udXQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQge1xyXG5cclxuICAgIHByaXZhdGUgY2xvbmVDb25maWd1cmF0aW9uITogT3B0aW9ucztcclxuICAgIHB1YmxpYyBkZXZpY2VTaXplOiBHcmlkT3B0aW9uc0VudW0gPSBHcmlkT3B0aW9uc0VudW0uTGFyZ2U7XHJcbiAgICBwcml2YXRlIHZpZXdJbml0aWFsaXplZCA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgY29uZmlnITogT3B0aW9ucztcclxuICAgIEBJbnB1dCgpIGlzTGVnZW5kU29ydCA9IHRydWU7XHJcbiAgICBASW5wdXQoKSBpc011dGUgPSBmYWxzZTtcclxuICAgIEBJbnB1dCgpIGlzTGVnZW5kRGlzcGxheSA9IHRydWU7XHJcbiAgICBASW5wdXQoKSBpY29uITogc3RyaW5nO1xyXG4gICAgQElucHV0KCkgbGFiZWw6IHN0cmluZyB8IHVuZGVmaW5lZDtcclxuICAgIEBJbnB1dCgpIGFtb3VudDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcclxuICAgIEBJbnB1dCgpIHRhcmdldCE6IHN0cmluZztcclxuICAgIEBJbnB1dCgpIGNoYXJ0VHlwZTogQ2hhcnRUeXBlRW51bSA9IENoYXJ0VHlwZUVudW0uRG9udXQ7XHJcbiAgICBASW5wdXQoKSBjdXJyZW5jeUNvZGU6IEN1cnJlbmN5Q29kZUVudW0gPSBDdXJyZW5jeUNvZGVFbnVtLkJsYW5rO1xyXG4gICAgQElucHV0KCkgbGVnZW5kUG9zaXRpb246IExlZ2VuZFBvc2l0aW9uRW51bSA9IExlZ2VuZFBvc2l0aW9uRW51bS5SaWdodDtcclxuICAgIEBJbnB1dCgpIGxlZ2VuZFR5cGU6IFBpZUxlZ2VuZFR5cGVFbnVtID0gUGllTGVnZW5kVHlwZUVudW0uQm90aDtcclxuICAgIEBJbnB1dCgpIGxlZ2VuZFdpZHRoUHggPSAyNTA7XHJcbiAgICBASW5wdXQoKSBsZWdlbmRMYXlvdXQ6IExlZ2VuZExheW91dEVudW0gPSBMZWdlbmRMYXlvdXRFbnVtLlZlcnRpY2FsO1xyXG5cclxuICAgIEBPdXRwdXQoKSBkb251dFNsaWNlQ2xpY2s6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gICAgQFZpZXdDaGlsZCgncGllRG9udXRDaGFydCcsIHsgc3RhdGljOiB0cnVlIH0pIHBpZURvbnV0Q2hhcnQhOiBFbGVtZW50UmVmO1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSBwZXJjZW50UGlwZTogUGVyY2VudFBpcGUsXHJcbiAgICAgICAgcHJpdmF0ZSBjdXJyZW5jeVBpcGU6IEN1cnJlbmN5UGlwZSxcclxuICAgICAgICBwcml2YXRlIGFzd0N1cnJlbmN5UGlwZTogQXN3Q3VycmVuY3lQaXBlKSB7IH1cclxuXHJcbiAgICBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMudmlld0luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ2hhcnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy52aWV3SW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUNoYXJ0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdGlhbGl6ZUNoYXJ0KCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZykge1xyXG4gICAgICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlnO1xyXG4gICAgICAgICAgICBjb25zdCBjb250YWluZXJXaWR0aCA9IHRoaXMucGllRG9udXRDaGFydC5uYXRpdmVFbGVtZW50LmNsaWVudFdpZHRoO1xyXG4gICAgICAgICAgICB0aGlzLmRldmljZVNpemUgPSBPYmplY3RVdGlscy5maW5kRGV2aWNlU2l6ZShjb250YWluZXJXaWR0aCk7XHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2hhcnRDcmVkaXQoKTtcclxuICAgICAgICAgICAgdGhpcy5zZXREb251dENoYXJ0VG9vbHRpcCgpO1xyXG4gICAgICAgICAgICBjb25zdCBzZXJpZXM6IFNlcmllc1BpZU9wdGlvbnNbXSA9IHRoaXMuY2xvbmVDb25maWd1cmF0aW9uLnNlcmllcyBhcyBTZXJpZXNQaWVPcHRpb25zW107XHJcbiAgICAgICAgICAgIHRoaXMuc2V0RG9udXRDaGFydFNlcmllc09wdGlvbnMoc2VyaWVzKTtcclxuICAgICAgICAgICAgaWYgKHNlcmllc1swXS5kYXRhPy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxlZ2VuZExheW91dCA9PT0gTGVnZW5kTGF5b3V0RW51bS5WZXJ0aWNhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0RG9udXRDaGFydExlZ2VuZE9wdGlvbih0aGlzLmxlZ2VuZFdpZHRoUHgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY2hhcnRUeXBlID09PSBDaGFydFR5cGVFbnVtLkRvbnV0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXREb251dENoYXJ0SW5uZXJUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRvbnV0Q2hhcnRTbGljZUNsaWNrKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgSGlnaGNoYXJ0cy5jaGFydCh0aGlzLnBpZURvbnV0Q2hhcnQubmF0aXZlRWxlbWVudCwgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJylcclxuICAgIG9uUmVzaXplKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUNoYXJ0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZW1vdmVDaGFydENyZWRpdCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5jcmVkaXRzID0ge1xyXG4gICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzZXREb251dENoYXJ0VG9vbHRpcCgpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCB0aGlzJDogdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24udG9vbHRpcCA9IHtcclxuICAgICAgICAgICAgdXNlSFRNTDogdHJ1ZSxcclxuICAgICAgICAgICAgc3BsaXQ6IGZhbHNlLFxyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IEFzd0NoYXJ0Q29uc3RhbnRzLmJsYWNrQ29sb3IsXHJcbiAgICAgICAgICAgIGJvcmRlckNvbG9yOiBBc3dDaGFydENvbnN0YW50cy5ibGFja0NvbG9yLFxyXG4gICAgICAgICAgICBzdHlsZToge1xyXG4gICAgICAgICAgICAgICAgY29sb3I6IEFzd0NoYXJ0Q29uc3RhbnRzLndoaXRlQ29sb3IsXHJcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiBBc3dDaGFydENvbnN0YW50cy5mb250V2VpZ2h0XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGJvcmRlclJhZGl1czogMCxcclxuICAgICAgICAgICAgZW5hYmxlZDogdGhpcy5pc011dGUgPyBmYWxzZSA6IHRydWUsXHJcbiAgICAgICAgICAgIGZvcm1hdHRlcigpOiBzdHJpbmcge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcGVyY2VudGFnZTogbnVtYmVyID0gdGhpcy5wb2ludC5wZXJjZW50YWdlIGFzIG51bWJlcjtcclxuICAgICAgICAgICAgICAgIHJldHVybiBgXHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIHRleHQtZW5kIHRleHQtcmlnaHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6ICR7dGhpcy5wb2ludC5jb2xvcn1cIj5cXHUyNUEwPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz4ke3RoaXMucG9pbnQubmFtZX08L3N0cm9uZz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMTIgdGV4dC1lbmQgdGV4dC1yaWdodFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt0aGlzJC5wZXJjZW50UGlwZS50cmFuc2Zvcm0ocGVyY2VudGFnZSAvIDEwMCwgJy4yJyl9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIHRleHQtZW5kIHRleHQtcmlnaHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7dGhpcyQuY3VycmVuY3lDb2RlID09PSBDdXJyZW5jeUNvZGVFbnVtLkJsYW5rXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnBvaW50Lm9wdGlvbnMudmFsdWUgOiB0aGlzJC5jdXJyZW5jeVBpcGUudHJhbnNmb3JtKHRoaXMucG9pbnQub3B0aW9ucy52YWx1ZSwgdGhpcyQuY3VycmVuY3lDb2RlKX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICBgO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGRvbnV0Q2hhcnRTbGljZUNsaWNrKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmlzTXV0ZSkgeyByZXR1cm47IH1cclxuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5wbG90T3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgc2VyaWVzOiB7XHJcbiAgICAgICAgICAgICAgICBkYXRhTGFiZWxzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBwb2ludDoge1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50czoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGljazogKChldmVudDogUG9pbnRDbGlja0V2ZW50T2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwb2ludENsaWNrRXZlbnQ6IFBvaW50Q2xpY2tFdmVudCA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBldmVudC5wb2ludC5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBldmVudC5wb2ludC5vcHRpb25zLmlkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2U6IGV2ZW50LnBvaW50LnBlcmNlbnRhZ2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGV2ZW50LnBvaW50Lm9wdGlvbnMudmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0OiBldmVudC5wb2ludC5vcHRpb25zLnRhcmdldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZG9udXRTbGljZUNsaWNrLmVtaXQocG9pbnRDbGlja0V2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0RG9udXRDaGFydFNlcmllc09wdGlvbnMoc2VyaWVzOiBTZXJpZXNQaWVPcHRpb25zW10pOiB2b2lkIHtcclxuICAgICAgICBzZXJpZXMuZm9yRWFjaCgoc2VyaWVzT3B0aW9uOiBTZXJpZXNQaWVPcHRpb25zKSA9PiB7XHJcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5hbGxvd1BvaW50U2VsZWN0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgc2VyaWVzT3B0aW9uLnNob3dJbkxlZ2VuZCA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNoYXJ0VHlwZSA9PT0gQ2hhcnRUeXBlRW51bS5Eb251dCkge1xyXG4gICAgICAgICAgICAgICAgc2VyaWVzT3B0aW9uLmlubmVyU2l6ZSA9IEFzd0NoYXJ0Q29uc3RhbnRzLmlubmVyU2l6ZTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHNlcmllc09wdGlvbi5pbm5lclNpemUgPSAnMCUnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTXV0ZSkge1xyXG4gICAgICAgICAgICAgICAgc2VyaWVzT3B0aW9uLm9wYWNpdHkgPSAwLjM1O1xyXG4gICAgICAgICAgICAgICAgc2VyaWVzT3B0aW9uLnN0YXRlcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICBob3Zlcjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgc2VyaWVzT3B0aW9uLnNsaWNlZE9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2VyaWVzT3B0aW9uLmN1cnNvciA9IEFzd0NoYXJ0Q29uc3RhbnRzLnBvaW50ZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IGRhdGE6IFBvaW50T3B0aW9uc09iamVjdFtdID0gc2VyaWVzT3B0aW9uLmRhdGEgYXMgUG9pbnRPcHRpb25zT2JqZWN0W107XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlTmVnYXRpdmVTZXJpZXNEYXRhKGRhdGEpO1xyXG4gICAgICAgICAgICBjb25zdCBzb3J0ZWRTZXJpZXNPcHRpb25EYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSA9IHRoaXMuaXNMZWdlbmRTb3J0ID8gdGhpcy5zb3J0U2VyaWVzRGF0YShkYXRhKSA6IGRhdGE7XHJcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5kYXRhID0gc29ydGVkU2VyaWVzT3B0aW9uRGF0YTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNvcnRTZXJpZXNEYXRhKGRhdGE6IFBvaW50T3B0aW9uc09iamVjdFtdKTogUG9pbnRPcHRpb25zT2JqZWN0W10ge1xyXG4gICAgICAgIGlmICh0aGlzLmxlZ2VuZFR5cGUgPT09IFBpZUxlZ2VuZFR5cGVFbnVtLkRlZmF1bHQpIHtcclxuICAgICAgICAgICAgZGF0YS5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICgnJyArIGEubmFtZSkubG9jYWxlQ29tcGFyZShiLm5hbWUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZGF0YS5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGEueSAmJiBiLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYS52YWx1ZSAtIGIudmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgZGF0YS5yZXZlcnNlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZU5lZ2F0aXZlU2VyaWVzRGF0YShkYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSk6IHZvaWQge1xyXG4gICAgICAgIGRhdGEuZm9yRWFjaCgoZWxlbWVudDogUG9pbnRPcHRpb25zT2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQudmFsdWUgPSBlbGVtZW50Lnk7XHJcbiAgICAgICAgICAgIGVsZW1lbnQueSA9IGVsZW1lbnQueSA/IE1hdGguYWJzKGVsZW1lbnQueSkgOiAwLjAwMTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXH