UNPKG

@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
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGllLWRvbnV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9jb21wb25lbnQvcGllLWRvbnV0L2NvbXBvbmVudC9waWUtZG9udXQudHMiLCIuLi8uLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudC9waWUtZG9udXQvY29tcG9uZW50L3BpZS1kb251dC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNBLE9BQU8sRUFFSCxTQUFTLEVBRVQsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0gsaUJBQWlCLEVBRWpCLGdCQUFnQixFQUNoQixlQUFlLEVBQ2YsZ0JBQWdCLEVBQ2hCLGtCQUFrQixFQUNsQixpQkFBaUIsRUFFcEIsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDM0QsT0FBTyxLQUFLLFVBQVUsTUFBTSxZQUFZLENBQUM7QUFXekMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7O0FBT3hELE1BQU0sT0FBTyxXQUFXO0lBdUJwQixZQUNZLFdBQXdCLEVBQ3hCLFlBQTBCLEVBQzFCLGVBQWdDO1FBRmhDLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQXZCckMsZUFBVSxHQUFvQixlQUFlLENBQUMsS0FBSyxDQUFDO1FBQ25ELG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBRXZCLGlCQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLFdBQU0sR0FBRyxLQUFLLENBQUM7UUFDZixvQkFBZSxHQUFHLElBQUksQ0FBQztRQUt2QixjQUFTLEdBQWtCLGFBQWEsQ0FBQyxLQUFLLENBQUM7UUFDL0MsaUJBQVksR0FBcUIsZ0JBQWdCLENBQUMsS0FB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QkFBcEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBRUksZUFBZTtzQkFBeEIsTUFBTTtnQkFFdUMsYUFBYTtzQkFBMUQsU0FBUzt1QkFBQyxlQUFlLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQXlDNUMsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEFTVyAoQSBTb2Z0d2FyZSBXb3JsZCkgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cclxuICpcclxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcclxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IEN1cnJlbmN5UGlwZSwgUGVyY2VudFBpcGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQge1xyXG4gICAgQWZ0ZXJWaWV3SW5pdCxcclxuICAgIENvbXBvbmVudCxcclxuICAgIEVsZW1lbnRSZWYsXHJcbiAgICBFdmVudEVtaXR0ZXIsXHJcbiAgICBIb3N0TGlzdGVuZXIsXHJcbiAgICBJbnB1dCxcclxuICAgIE9uQ2hhbmdlcyxcclxuICAgIE91dHB1dCxcclxuICAgIFZpZXdDaGlsZFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gICAgQXN3Q2hhcnRDb25zdGFudHMsXHJcbiAgICBBc3dDdXJyZW5jeVBpcGUsXHJcbiAgICBDdXJyZW5jeUNvZGVFbnVtLFxyXG4gICAgR3JpZE9wdGlvbnNFbnVtLFxyXG4gICAgTGVnZW5kTGF5b3V0RW51bSxcclxuICAgIExlZ2VuZFBvc2l0aW9uRW51bSxcclxuICAgIFBpZUxlZ2VuZFR5cGVFbnVtLFxyXG4gICAgUG9pbnRDbGlja0V2ZW50XHJcbn0gZnJvbSAnQGFzb2Z0d2FyZXdvcmxkL2NoYXJ0cy9jb3JlJztcclxuaW1wb3J0IHsgT2JqZWN0VXRpbHMgfSBmcm9tICdAYXNvZnR3YXJld29ybGQvY2hhcnRzL3V0aWxzJztcclxuaW1wb3J0ICogYXMgSGlnaGNoYXJ0cyBmcm9tICdoaWdoY2hhcnRzJztcclxuaW1wb3J0IHtcclxuICAgIEFsaWduVmFsdWUsXHJcbiAgICBPcHRpb25zLFxyXG4gICAgUG9pbnRDbGlja0V2ZW50T2JqZWN0LFxyXG4gICAgUG9pbnRPcHRpb25zT2JqZWN0LFxyXG4gICAgUG9pbnQsXHJcbiAgICBTZXJpZXMsXHJcbiAgICBTZXJpZXNQaWVPcHRpb25zLFxyXG4gICAgVmVydGljYWxBbGlnblZhbHVlXHJcbn0gZnJvbSAnaGlnaGNoYXJ0cyc7XHJcbmltcG9ydCB7IENoYXJ0VHlwZUVudW0gfSBmcm9tICcuLi9lbnVtL2NoYXJ0LXR5cGUuZW51bSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnYXN3LXBpZS1kb251dCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vcGllLWRvbnV0Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vcGllLWRvbnV0LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXN3UGllRG9udXQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQge1xyXG5cclxuICAgIHByaXZhdGUgY2xvbmVDb25maWd1cmF0aW9uITogT3B0aW9ucztcclxuICAgIHB1YmxpYyBkZXZpY2VTaXplOiBHcmlkT3B0aW9uc0VudW0gPSBHcmlkT3B0aW9uc0VudW0uTGFyZ2U7XHJcbiAgICBwcml2YXRlIHZpZXdJbml0aWFsaXplZCA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgY29uZmlnITogT3B0aW9ucztcclxuICAgIEBJbnB1dCgpIGlzTGVnZW5kU29ydCA9IHRydWU7XHJcbiAgICBASW5wdXQoKSBpc011dGUgPSBmYWxzZTtcclxuICAgIEBJbnB1dCgpIGlzTGVnZW5kRGlzcGxheSA9IHRydWU7XHJcbiAgICBASW5wdXQoKSBpY29uITogc3RyaW5nO1xyXG4gICAgQElucHV0KCkgbGFiZWw6IHN0cmluZyB8IHVuZGVmaW5lZDtcclxuICAgIEBJbnB1dCgpIGFtb3VudDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcclxuICAgIEBJbnB1dCgpIHRhcmdldCE6IHN0cmluZztcclxuICAgIEBJbnB1dCgpIGNoYXJ0VHlwZTogQ2hhcnRUeXBlRW51bSA9IENoYXJ0VHlwZUVudW0uRG9udXQ7XHJcbiAgICBASW5wdXQoKSBjdXJyZW5jeUNvZGU6IEN1cnJlbmN5Q29kZUVudW0gPSBDdXJyZW5jeUNvZGVFbnVtLkJsYW5rO1xyXG4gICAgQElucHV0KCkgbGVnZW5kUG9zaXRpb246IExlZ2VuZFBvc2l0aW9uRW51bSA9IExlZ2VuZFBvc2l0aW9uRW51bS5SaWdodDtcclxuICAgIEBJbnB1dCgpIGxlZ2VuZFR5cGU6IFBpZUxlZ2VuZFR5cGVFbnVtID0gUGllTGVnZW5kVHlwZUVudW0uQm90aDtcclxuICAgIEBJbnB1dCgpIGxlZ2VuZFdpZHRoUHggPSAyNTA7XHJcbiAgICBASW5wdXQoKSBsZWdlbmRMYXlvdXQ6IExlZ2VuZExheW91dEVudW0gPSBMZWdlbmRMYXlvdXRFbnVtLlZlcnRpY2FsO1xyXG5cclxuICAgIEBPdXRwdXQoKSBkb251dFNsaWNlQ2xpY2s6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gICAgQFZpZXdDaGlsZCgncGllRG9udXRDaGFydCcsIHsgc3RhdGljOiB0cnVlIH0pIHBpZURvbnV0Q2hhcnQhOiBFbGVtZW50UmVmO1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSBwZXJjZW50UGlwZTogUGVyY2VudFBpcGUsXHJcbiAgICAgICAgcHJpdmF0ZSBjdXJyZW5jeVBpcGU6IEN1cnJlbmN5UGlwZSxcclxuICAgICAgICBwcml2YXRlIGFzd0N1cnJlbmN5UGlwZTogQXN3Q3VycmVuY3lQaXBlKSB7IH1cclxuXHJcbiAgICBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMudmlld0luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ2hhcnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy52aWV3SW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUNoYXJ0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdGlhbGl6ZUNoYXJ0KCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZykge1xyXG4gICAgICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlnO1xyXG4gICAgICAgICAgICBjb25zdCBjb250YWluZXJXaWR0aCA9IHRoaXMucGllRG9udXRDaGFydC5uYXRpdmVFbGVtZW50LmNsaWVudFdpZHRoO1xyXG4gICAgICAgICAgICB0aGlzLmRldmljZVNpemUgPSBPYmplY3RVdGlscy5maW5kRGV2aWNlU2l6ZShjb250YWluZXJXaWR0aCk7XHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2hhcnRDcmVkaXQoKTtcclxuICAgICAgICAgICAgdGhpcy5zZXREb251dENoYXJ0VG9vbHRpcCgpO1xyXG4gICAgICAgICAgICBjb25zdCBzZXJpZXM6IFNlcmllc1BpZU9wdGlvbnNbXSA9IHRoaXMuY2xvbmVDb25maWd1cmF0aW9uLnNlcmllcyBhcyBTZXJpZXNQaWVPcHRpb25zW107XHJcbiAgICAgICAgICAgIHRoaXMuc2V0RG9udXRDaGFydFNlcmllc09wdGlvbnMoc2VyaWVzKTtcclxuICAgICAgICAgICAgaWYgKHNlcmllc1swXS5kYXRhPy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxlZ2VuZExheW91dCA9PT0gTGVnZW5kTGF5b3V0RW51bS5WZXJ0aWNhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0RG9udXRDaGFydExlZ2VuZE9wdGlvbih0aGlzLmxlZ2VuZFdpZHRoUHgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY2hhcnRUeXBlID09PSBDaGFydFR5cGVFbnVtLkRvbnV0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXREb251dENoYXJ0SW5uZXJUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRvbnV0Q2hhcnRTbGljZUNsaWNrKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgSGlnaGNoYXJ0cy5jaGFydCh0aGlzLnBpZURvbnV0Q2hhcnQubmF0aXZlRWxlbWVudCwgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJylcclxuICAgIG9uUmVzaXplKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUNoYXJ0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZW1vdmVDaGFydENyZWRpdCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5jcmVkaXRzID0ge1xyXG4gICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzZXREb251dENoYXJ0VG9vbHRpcCgpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCB0aGlzJDogdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24udG9vbHRpcCA9IHtcclxuICAgICAgICAgICAgdXNlSFRNTDogdHJ1ZSxcclxuICAgICAgICAgICAgc3BsaXQ6IGZhbHNlLFxyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IEFzd0NoYXJ0Q29uc3RhbnRzLmJsYWNrQ29sb3IsXHJcbiAgICAgICAgICAgIGJvcmRlckNvbG9yOiBBc3dDaGFydENvbnN0YW50cy5ibGFja0NvbG9yLFxyXG4gICAgICAgICAgICBzdHlsZToge1xyXG4gICAgICAgICAgICAgICAgY29sb3I6IEFzd0NoYXJ0Q29uc3RhbnRzLndoaXRlQ29sb3IsXHJcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiBBc3dDaGFydENvbnN0YW50cy5mb250V2VpZ2h0XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGJvcmRlclJhZGl1czogMCxcclxuICAgICAgICAgICAgZW5hYmxlZDogdGhpcy5pc011dGUgPyBmYWxzZSA6IHRydWUsXHJcbiAgICAgICAgICAgIGZvcm1hdHRlcigpOiBzdHJpbmcge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcGVyY2VudGFnZTogbnVtYmVyID0gdGhpcy5wb2ludC5wZXJjZW50YWdlIGFzIG51bWJlcjtcclxuICAgICAgICAgICAgICAgIHJldHVybiBgXHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIHRleHQtZW5kIHRleHQtcmlnaHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiY29sb3I6ICR7dGhpcy5wb2ludC5jb2xvcn1cIj5cXHUyNUEwPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz4ke3RoaXMucG9pbnQubmFtZX08L3N0cm9uZz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMTIgdGV4dC1lbmQgdGV4dC1yaWdodFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt0aGlzJC5wZXJjZW50UGlwZS50cmFuc2Zvcm0ocGVyY2VudGFnZSAvIDEwMCwgJy4yJyl9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIHRleHQtZW5kIHRleHQtcmlnaHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7dGhpcyQuY3VycmVuY3lDb2RlID09PSBDdXJyZW5jeUNvZGVFbnVtLkJsYW5rXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnBvaW50Lm9wdGlvbnMudmFsdWUgOiB0aGlzJC5jdXJyZW5jeVBpcGUudHJhbnNmb3JtKHRoaXMucG9pbnQub3B0aW9ucy52YWx1ZSwgdGhpcyQuY3VycmVuY3lDb2RlKX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICBgO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGRvbnV0Q2hhcnRTbGljZUNsaWNrKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmlzTXV0ZSkgeyByZXR1cm47IH1cclxuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5wbG90T3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgc2VyaWVzOiB7XHJcbiAgICAgICAgICAgICAgICBkYXRhTGFiZWxzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBwb2ludDoge1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50czoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGljazogKChldmVudDogUG9pbnRDbGlja0V2ZW50T2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwb2ludENsaWNrRXZlbnQ6IFBvaW50Q2xpY2tFdmVudCA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBldmVudC5wb2ludC5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBldmVudC5wb2ludC5vcHRpb25zLmlkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2U6IGV2ZW50LnBvaW50LnBlcmNlbnRhZ2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGV2ZW50LnBvaW50Lm9wdGlvbnMudmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0OiBldmVudC5wb2ludC5vcHRpb25zLnRhcmdldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZG9udXRTbGljZUNsaWNrLmVtaXQocG9pbnRDbGlja0V2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0RG9udXRDaGFydFNlcmllc09wdGlvbnMoc2VyaWVzOiBTZXJpZXNQaWVPcHRpb25zW10pOiB2b2lkIHtcclxuICAgICAgICBzZXJpZXMuZm9yRWFjaCgoc2VyaWVzT3B0aW9uOiBTZXJpZXNQaWVPcHRpb25zKSA9PiB7XHJcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5hbGxvd1BvaW50U2VsZWN0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgc2VyaWVzT3B0aW9uLnNob3dJbkxlZ2VuZCA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNoYXJ0VHlwZSA9PT0gQ2hhcnRUeXBlRW51bS5Eb251dCkge1xyXG4gICAgICAgICAgICAgICAgc2VyaWVzT3B0aW9uLmlubmVyU2l6ZSA9IEFzd0NoYXJ0Q29uc3RhbnRzLmlubmVyU2l6ZTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHNlcmllc09wdGlvbi5pbm5lclNpemUgPSAnMCUnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTXV0ZSkge1xyXG4gICAgICAgICAgICAgICAgc2VyaWVzT3B0aW9uLm9wYWNpdHkgPSAwLjM1O1xyXG4gICAgICAgICAgICAgICAgc2VyaWVzT3B0aW9uLnN0YXRlcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICBob3Zlcjoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgaW5hY3RpdmU6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgc2VyaWVzT3B0aW9uLnNsaWNlZE9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2VyaWVzT3B0aW9uLmN1cnNvciA9IEFzd0NoYXJ0Q29uc3RhbnRzLnBvaW50ZXI7XHJcbiAgICAgICAgICAgIGNvbnN0IGRhdGE6IFBvaW50T3B0aW9uc09iamVjdFtdID0gc2VyaWVzT3B0aW9uLmRhdGEgYXMgUG9pbnRPcHRpb25zT2JqZWN0W107XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlTmVnYXRpdmVTZXJpZXNEYXRhKGRhdGEpO1xyXG4gICAgICAgICAgICBjb25zdCBzb3J0ZWRTZXJpZXNPcHRpb25EYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSA9IHRoaXMuaXNMZWdlbmRTb3J0ID8gdGhpcy5zb3J0U2VyaWVzRGF0YShkYXRhKSA6IGRhdGE7XHJcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5kYXRhID0gc29ydGVkU2VyaWVzT3B0aW9uRGF0YTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNvcnRTZXJpZXNEYXRhKGRhdGE6IFBvaW50T3B0aW9uc09iamVjdFtdKTogUG9pbnRPcHRpb25zT2JqZWN0W10ge1xyXG4gICAgICAgIGlmICh0aGlzLmxlZ2VuZFR5cGUgPT09IFBpZUxlZ2VuZFR5cGVFbnVtLkRlZmF1bHQpIHtcclxuICAgICAgICAgICAgZGF0YS5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICgnJyArIGEubmFtZSkubG9jYWxlQ29tcGFyZShiLm5hbWUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZGF0YS5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGEueSAmJiBiLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYS52YWx1ZSAtIGIudmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgZGF0YS5yZXZlcnNlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGhhbmRsZU5lZ2F0aXZlU2VyaWVzRGF0YShkYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSk6IHZvaWQge1xyXG4gICAgICAgIGRhdGEuZm9yRWFjaCgoZWxlbWVudDogUG9pbnRPcHRpb25zT2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQudmFsdWUgPSBlbGVtZW50Lnk7XHJcbiAgICAgICAgICAgIGVsZW1lbnQueSA9IGVsZW1lbnQueSA/IE1hdGguYWJzKGVsZW1lbnQueSkgOiAwLjAwMTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXH