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.

267 lines 34.7 kB
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 * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@asoftwareworld/charts/core"; export class AswLine { constructor(currencyPipe, aswCurrencyPipe) { this.currencyPipe = currencyPipe; this.aswCurrencyPipe = aswCurrencyPipe; this.deviceSize = GridOptionsEnum.Large; this.viewInitialized = false; this.isLegendSort = true; this.isLegendDisplay = true; this.currencyCode = CurrencyCodeEnum.INR; this.legendPosition = LegendPositionEnum.Right; this.legendType = ChartLegendTypeEnum.Both; this.legendWidthPx = 250; this.legendLayout = LegendLayoutEnum.Vertical; this.linePointClick = 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.lineChart.nativeElement.clientWidth; this.deviceSize = ObjectUtils.findDeviceSize(containerWidth); this.removeChartCredit(); this.setLineChartTooltip(); const series = this.cloneConfiguration.series; this.setLineChartSeriesOptions(series); if (this.legendLayout === LegendLayoutEnum.Vertical) { this.setLineChartLegendOption(this.legendWidthPx); } this.clickOnLinePoint(); Highcharts.chart(this.lineChart.nativeElement, this.cloneConfiguration); } } onResize() { this.initializeChart(); } removeChartCredit() { this.cloneConfiguration.credits = { enabled: false }; } setLineChartTooltip() { const this$ = this; this.cloneConfiguration.tooltip = { useHTML: true, split: false, backgroundColor: AswChartConstants.blackColor, borderColor: AswChartConstants.blackColor, style: { color: AswChartConstants.whiteColor, fontWeight: AswChartConstants.fontWeight }, borderRadius: 0, enabled: true, formatter() { return ` <div class="row"> <div class="col-md-12 text-end text-right"> <strong>${this.point.category}</strong> </div> <div class="col-md-12 text-end text-right"> <span style="color: ${this.point.color}">\u25A0</span> <strong>${this.point.series.name}</strong> </div> <div class="col-md-12 text-end text-right"> ${this$.currencyPipe.transform(this.point.options.y, this$.currencyCode)} </div> </div> `; } }; } clickOnLinePoint() { // tslint:disable-next-line:no-non-null-assertion this.cloneConfiguration.plotOptions.line = { point: { events: { click: ((event) => { const pointClickEvent = { name: event.point.series.name, index: event.point.index, value: event.point.options.y, category: event.point.category }; this.linePointClick.emit(pointClickEvent); }) } } }; } setLineChartSeriesOptions(series) { series.forEach((seriesOption) => { seriesOption.allowPointSelect = true; seriesOption.showInLegend = true; seriesOption.cursor = AswChartConstants.pointer; const data = seriesOption.data; // this.handleNegativeSeriesData(data); // const sortedSeriesOptionData: PointOptionsObject[] = this.isLegendSort ? this.sortSeriesData(data) : data; // seriesOption.data = sortedSeriesOptionData; }); } sortSeriesData(data) { if (this.legendType === ChartLegendTypeEnum.Default) { data.sort((a, b) => { return ('' + a.name).localeCompare(b.name); }); return data; } else { data.sort((a, b) => { if (a.y && b.y) { return a.value - b.value; } else { return 0; } }); data.reverse(); return data; } } handleNegativeSeriesData(data) { data.forEach((element) => { element.value = element.y; element.y = element.y ? Math.abs(element.y) : 0.001; }); } setLineChartLegendOption(legendWidthPx) { const this$ = this; this.cloneConfiguration.legend = { useHTML: true, enabled: this.isLegendDisplay, floating: false, align: this.setLegendAlignment(), layout: 'vertical', verticalAlign: this.setLegendVerticalAlignment(), symbolHeight: 10, symbolWidth: 10, symbolRadius: 0, itemMarginTop: 3, itemMarginBottom: 3, itemStyle: { fontSize: this.deviceSize === GridOptionsEnum.ExtraSmall ? '12px' : '14px', fontWeight: AswChartConstants.fontWeight }, width: legendWidthPx + 15, title: { text: this$.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>`; } } } AswLine.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswLine, deps: [{ token: i1.CurrencyPipe }, { token: i2.AswCurrencyPipe }], target: i0.ɵɵFactoryTarget.Component }); AswLine.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: AswLine, selector: "asw-line", inputs: { config: "config", isLegendSort: "isLegendSort", isLegendDisplay: "isLegendDisplay", currencyCode: "currencyCode", legendPosition: "legendPosition", legendType: "legendType", legendWidthPx: "legendWidthPx", legendLayout: "legendLayout" }, outputs: { linePointClick: "linePointClick" }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "lineChart", first: true, predicate: ["lineChart"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #lineChart></div>", styles: [""] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: AswLine, decorators: [{ type: Component, args: [{ selector: 'asw-line', template: "<div #lineChart></div>", styles: [""] }] }], ctorParameters: function () { return [{ type: i1.CurrencyPipe }, { type: i2.AswCurrencyPipe }]; }, propDecorators: { config: [{ type: Input }], isLegendSort: [{ type: Input }], isLegendDisplay: [{ type: Input }], currencyCode: [{ type: Input }], legendPosition: [{ type: Input }], legendType: [{ type: Input }], legendWidthPx: [{ type: Input }], legendLayout: [{ type: Input }], linePointClick: [{ type: Output }], lineChart: [{ type: ViewChild, args: ['lineChart', { static: true }] }], onResize: [{ type: HostListener, args: ['window:resize'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvY29tcG9uZW50L2xpbmUvY29tcG9uZW50L2xpbmUudHMiLCIuLi8uLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudC9saW5lL2NvbXBvbmVudC9saW5lLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUVILFNBQVMsRUFFVCxZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDSCxpQkFBaUIsRUFFakIsbUJBQW1CLEVBRW5CLGdCQUFnQixFQUNoQixlQUFlLEVBQ2YsZ0JBQWdCLEVBQ2hCLGtCQUFrQixHQUNyQixNQUFNLDZCQUE2QixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMzRCxPQUFPLEtBQUssVUFBVSxNQUFNLFlBQVksQ0FBQzs7OztBQWlCekMsTUFBTSxPQUFPLE9BQU87SUFpQmhCLFlBQ1ksWUFBMEIsRUFDMUIsZUFBZ0M7UUFEaEMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBaEJyQyxlQUFVLEdBQW9CLGVBQWUsQ0FBQyxLQUFLLENBQUM7UUFDbkQsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFFdkIsaUJBQVksR0FBRyxJQUFJLENBQUM7UUFDcEIsb0JBQWUsR0FBRyxJQUFJLENBQUM7UUFDdkIsaUJBQVksR0FBcUIsZ0JBQWdCLENBQUMsR0FBRyxDQUFDO1FBQ3RELG1CQUFjLEdBQXVCLGtCQUFrQixDQUFDLEtBQUssQ0FBQztRQUM5RCxlQUFVLEdBQXdCLG1CQUFtQixDQUFDLElBQUksQ0FBQztRQUMzRCxrQkFBYSxHQUFHLEdBQUcsQ0FBQztRQUNwQixpQkFBWSxHQUFxQixnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7UUFFMUQsbUJBQWMsR0FB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QUFZLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPOzs7dUJBRzlGLENBQUM7U0FDZjtJQUNMLENBQUM7O29HQXBQUSxPQUFPO3dGQUFQLE9BQU8sMGhCQ3hDcEIsd0JBQXNCOzJGRHdDVCxPQUFPO2tCQUxuQixTQUFTOytCQUNJLFVBQVU7aUlBU1gsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBRUksY0FBYztzQkFBdkIsTUFBTTtnQkFFbUMsU0FBUztzQkFBbEQsU0FBUzt1QkFBQyxXQUFXLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQW1DeEMsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDdXJyZW5jeVBpcGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBIb3N0TGlzdGVuZXIsXG4gICAgSW5wdXQsXG4gICAgT25DaGFuZ2VzLFxuICAgIE91dHB1dCxcbiAgICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICAgIEFzd0NoYXJ0Q29uc3RhbnRzLFxuICAgIEFzd0N1cnJlbmN5UGlwZSxcbiAgICBDaGFydExlZ2VuZFR5cGVFbnVtLFxuICAgIENoYXJ0UG9pbnRlckV2ZW50LFxuICAgIEN1cnJlbmN5Q29kZUVudW0sXG4gICAgR3JpZE9wdGlvbnNFbnVtLFxuICAgIExlZ2VuZExheW91dEVudW0sXG4gICAgTGVnZW5kUG9zaXRpb25FbnVtLFxufSBmcm9tICdAYXNvZnR3YXJld29ybGQvY2hhcnRzL2NvcmUnO1xuaW1wb3J0IHsgT2JqZWN0VXRpbHMgfSBmcm9tICdAYXNvZnR3YXJld29ybGQvY2hhcnRzL3V0aWxzJztcbmltcG9ydCAqIGFzIEhpZ2hjaGFydHMgZnJvbSAnaGlnaGNoYXJ0cyc7XG5pbXBvcnQge1xuICAgIEFsaWduVmFsdWUsXG4gICAgT3B0aW9ucyxcbiAgICBQb2ludENsaWNrRXZlbnRPYmplY3QsXG4gICAgUG9pbnRPcHRpb25zT2JqZWN0LFxuICAgIFBvaW50LFxuICAgIFNlcmllcyxcbiAgICBTZXJpZXNQaWVPcHRpb25zLFxuICAgIFZlcnRpY2FsQWxpZ25WYWx1ZVxufSBmcm9tICdoaWdoY2hhcnRzJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhc3ctbGluZScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2xpbmUuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vbGluZS5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQXN3TGluZSBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCB7XG5cbiAgICBwcml2YXRlIGNsb25lQ29uZmlndXJhdGlvbiE6IE9wdGlvbnM7XG4gICAgcHVibGljIGRldmljZVNpemU6IEdyaWRPcHRpb25zRW51bSA9IEdyaWRPcHRpb25zRW51bS5MYXJnZTtcbiAgICBwcml2YXRlIHZpZXdJbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIGNvbmZpZyE6IE9wdGlvbnM7XG4gICAgQElucHV0KCkgaXNMZWdlbmRTb3J0ID0gdHJ1ZTtcbiAgICBASW5wdXQoKSBpc0xlZ2VuZERpc3BsYXkgPSB0cnVlO1xuICAgIEBJbnB1dCgpIGN1cnJlbmN5Q29kZTogQ3VycmVuY3lDb2RlRW51bSA9IEN1cnJlbmN5Q29kZUVudW0uSU5SO1xuICAgIEBJbnB1dCgpIGxlZ2VuZFBvc2l0aW9uOiBMZWdlbmRQb3NpdGlvbkVudW0gPSBMZWdlbmRQb3NpdGlvbkVudW0uUmlnaHQ7XG4gICAgQElucHV0KCkgbGVnZW5kVHlwZTogQ2hhcnRMZWdlbmRUeXBlRW51bSA9IENoYXJ0TGVnZW5kVHlwZUVudW0uQm90aDtcbiAgICBASW5wdXQoKSBsZWdlbmRXaWR0aFB4ID0gMjUwO1xuICAgIEBJbnB1dCgpIGxlZ2VuZExheW91dDogTGVnZW5kTGF5b3V0RW51bSA9IExlZ2VuZExheW91dEVudW0uVmVydGljYWw7XG5cbiAgICBAT3V0cHV0KCkgbGluZVBvaW50Q2xpY2s6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgICBAVmlld0NoaWxkKCdsaW5lQ2hhcnQnLCB7IHN0YXRpYzogdHJ1ZSB9KSBsaW5lQ2hhcnQhOiBFbGVtZW50UmVmO1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGN1cnJlbmN5UGlwZTogQ3VycmVuY3lQaXBlLFxuICAgICAgICBwcml2YXRlIGFzd0N1cnJlbmN5UGlwZTogQXN3Q3VycmVuY3lQaXBlKSB7IH1cblxuICAgIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMudmlld0luaXRpYWxpemVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ2hhcnQoKTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudmlld0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplQ2hhcnQoKTtcbiAgICB9XG5cbiAgICBpbml0aWFsaXplQ2hhcnQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZykge1xuICAgICAgICAgICAgdGhpcy5jbG9uZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZztcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lcldpZHRoID0gdGhpcy5saW5lQ2hhcnQubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aDtcbiAgICAgICAgICAgIHRoaXMuZGV2aWNlU2l6ZSA9IE9iamVjdFV0aWxzLmZpbmREZXZpY2VTaXplKGNvbnRhaW5lcldpZHRoKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2hhcnRDcmVkaXQoKTtcbiAgICAgICAgICAgIHRoaXMuc2V0TGluZUNoYXJ0VG9vbHRpcCgpO1xuICAgICAgICAgICAgY29uc3Qgc2VyaWVzOiBTZXJpZXNQaWVPcHRpb25zW10gPSB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5zZXJpZXMgYXMgU2VyaWVzUGllT3B0aW9uc1tdO1xuICAgICAgICAgICAgdGhpcy5zZXRMaW5lQ2hhcnRTZXJpZXNPcHRpb25zKHNlcmllcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5sZWdlbmRMYXlvdXQgPT09IExlZ2VuZExheW91dEVudW0uVmVydGljYWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldExpbmVDaGFydExlZ2VuZE9wdGlvbih0aGlzLmxlZ2VuZFdpZHRoUHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jbGlja09uTGluZVBvaW50KCk7XG4gICAgICAgICAgICBIaWdoY2hhcnRzLmNoYXJ0KHRoaXMubGluZUNoYXJ0Lm5hdGl2ZUVsZW1lbnQsIHRoaXMuY2xvbmVDb25maWd1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxuICAgIG9uUmVzaXplKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmluaXRpYWxpemVDaGFydCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlQ2hhcnRDcmVkaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2xvbmVDb25maWd1cmF0aW9uLmNyZWRpdHMgPSB7XG4gICAgICAgICAgICBlbmFibGVkOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0TGluZUNoYXJ0VG9vbHRpcCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGhpcyQ6IHRoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi50b29sdGlwID0ge1xuICAgICAgICAgICAgdXNlSFRNTDogdHJ1ZSxcbiAgICAgICAgICAgIHNwbGl0OiBmYWxzZSxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogQXN3Q2hhcnRDb25zdGFudHMuYmxhY2tDb2xvcixcbiAgICAgICAgICAgIGJvcmRlckNvbG9yOiBBc3dDaGFydENvbnN0YW50cy5ibGFja0NvbG9yLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBjb2xvcjogQXN3Q2hhcnRDb25zdGFudHMud2hpdGVDb2xvcixcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiBBc3dDaGFydENvbnN0YW50cy5mb250V2VpZ2h0XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAwLFxuICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgIGZvcm1hdHRlcigpOiBzdHJpbmcge1xuICAgICAgICAgICAgICAgIHJldHVybiBgXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMTIgdGV4dC1lbmQgdGV4dC1yaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+JHt0aGlzLnBvaW50LmNhdGVnb3J5fTwvc3Ryb25nPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIHRleHQtZW5kIHRleHQtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImNvbG9yOiAke3RoaXMucG9pbnQuY29sb3J9XCI+XFx1MjVBMDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPiR7dGhpcy5wb2ludC5zZXJpZXMubmFtZX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMiB0ZXh0LWVuZCB0ZXh0LXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt0aGlzJC5jdXJyZW5jeVBpcGUudHJhbnNmb3JtKHRoaXMucG9pbnQub3B0aW9ucy55LCB0aGlzJC5jdXJyZW5jeUNvZGUpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIGA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGlja09uTGluZVBvaW50KCk6IHZvaWQge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgIHRoaXMuY2xvbmVDb25maWd1cmF0aW9uLnBsb3RPcHRpb25zIS5saW5lID0ge1xuICAgICAgICAgICAgcG9pbnQ6IHtcbiAgICAgICAgICAgICAgICBldmVudHM6IHtcbiAgICAgICAgICAgICAgICAgICAgY2xpY2s6ICgoZXZlbnQ6IFBvaW50Q2xpY2tFdmVudE9iamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9pbnRDbGlja0V2ZW50OiBDaGFydFBvaW50ZXJFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBldmVudC5wb2ludC5zZXJpZXMubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogZXZlbnQucG9pbnQuaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGV2ZW50LnBvaW50Lm9wdGlvbnMueSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeTogZXZlbnQucG9pbnQuY2F0ZWdvcnlcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxpbmVQb2ludENsaWNrLmVtaXQocG9pbnRDbGlja0V2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRMaW5lQ2hhcnRTZXJpZXNPcHRpb25zKHNlcmllczogU2VyaWVzUGllT3B0aW9uc1tdKTogdm9pZCB7XG4gICAgICAgIHNlcmllcy5mb3JFYWNoKChzZXJpZXNPcHRpb246IFNlcmllc1BpZU9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5hbGxvd1BvaW50U2VsZWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgIHNlcmllc09wdGlvbi5zaG93SW5MZWdlbmQgPSB0cnVlO1xuICAgICAgICAgICAgc2VyaWVzT3B0aW9uLmN1cnNvciA9IEFzd0NoYXJ0Q29uc3RhbnRzLnBvaW50ZXI7XG4gICAgICAgICAgICBjb25zdCBkYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSA9IHNlcmllc09wdGlvbi5kYXRhIGFzIFBvaW50T3B0aW9uc09iamVjdFtdO1xuICAgICAgICAgICAgLy8gdGhpcy5oYW5kbGVOZWdhdGl2ZVNlcmllc0RhdGEoZGF0YSk7XG4gICAgICAgICAgICAvLyBjb25zdCBzb3J0ZWRTZXJpZXNPcHRpb25EYXRhOiBQb2ludE9wdGlvbnNPYmplY3RbXSA9IHRoaXMuaXNMZWdlbmRTb3J0ID8gdGhpcy5zb3J0U2VyaWVzRGF0YShkYXRhKSA6IGRhdGE7XG4gICAgICAgICAgICAvLyBzZXJpZXNPcHRpb24uZGF0YSA9IHNvcnRlZFNlcmllc09wdGlvbkRhdGE7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc29ydFNlcmllc0RhdGEoZGF0YTogUG9pbnRPcHRpb25zT2JqZWN0W10pOiBQb2ludE9wdGlvbnNPYmplY3RbXSB7XG4gICAgICAgIGlmICh0aGlzLmxlZ2VuZFR5cGUgPT09IENoYXJ0TGVnZW5kVHlwZUVudW0uRGVmYXVsdCkge1xuICAgICAgICAgICAgZGF0YS5zb3J0KChhOiBhbnksIGI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAoJycgKyBhLm5hbWUpLmxvY2FsZUNvbXBhcmUoYi5uYW1lKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkYXRhLnNvcnQoKGE6IGFueSwgYjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGEueSAmJiBiLnkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGEudmFsdWUgLSBiLnZhbHVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGF0YS5yZXZlcnNlKCk7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlTmVnYXRpdmVTZXJpZXNEYXRhKGRhdGE6IFBvaW50T3B0aW9uc09iamVjdFtdKTogdm9pZCB7XG4gICAgICAgIGRhdGEuZm9yRWFjaCgoZWxlbWVudDogUG9pbnRPcHRpb25zT2JqZWN0KSA9PiB7XG4gICAgICAgICAgICBlbGVtZW50LnZhbHVlID0gZWxlbWVudC55O1xuICAgICAgICAgICAgZWxlbWVudC55ID0gZWxlbWVudC55ID8gTWF0aC5hYnMoZWxlbWVudC55KSA6IDAuMDAxO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldExpbmVDaGFydExlZ2VuZE9wdGlvbihsZWdlbmRXaWR0aFB4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGhpcyQ6IHRoaXMgPSB0aGlzO1xuICAgICAgICB0aGlzLmNsb25lQ29uZmlndXJhdGlvbi5sZWdlbmQgPSB7XG4gICAgICAgICAgICB1c2VIVE1MOiB0cnVlLFxuICAgICAgICAgICAgZW5hYmxlZDogdGhpcy5pc0xlZ2VuZERpc3BsYXksXG4gICAgICAgICAgICBmbG9hdGluZzogZmFsc2UsXG4gICAgICAgICAgICBhbGlnbjogdGhpcy5zZXRMZWdlbmRBbGlnbm1lbnQoKSxcbiAgICAgICAgICAgIGxheW91dDogJ3ZlcnRpY2FsJyxcbiAgICAgICAgICAgIHZlcnRpY2FsQWxpZ246IHRoaXMuc2V0TGVnZW5kVmVydGljYWxBbGlnbm1lbnQoKSxcbiAgICAgICAgICAgIHN5bWJvbEhlaWdodDogMTAsXG4gICAgICAgICAgICBzeW1ib2xXaWR0aDogMTAsXG4gICAgICAgICAgICBzeW1ib2xSYWRpdXM6IDAsXG4gICAgICAgICAgICBpdGVtTWFyZ2luVG9wOiAzLCAvLyBTcGFjZSBiZXR3ZWVuIGVhY2ggY2F0ZWdvcnkgaW4gdGhlIGxlZ2VuZFxuICAgICAgICAgICAgaXRlbU1hcmdpbkJvdHRvbTogMyxcbiAgICAgICAgICAgIGl0ZW1TdHlsZToge1xuICAgICAgICAgICAgICAgIGZvbnRTaXplOiB0aGlzLmRldmljZVNpemUgPT09IEdyaWRPcHRpb25zRW51bS5FeHRyYVNtYWxsID8gJzEycHgnIDogJzE0cHgnLFxuICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IEFzd0NoYXJ0Q29uc3RhbnRzLmZvbnRXZWlnaHRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB3aWR0aDogbGVnZW5kV2lkdGhQeCArIDE1LFxuICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgICB0ZXh0OiB0aGlzJC5zZXRMaW5lQ2hhcnRMZWdlbmRXaXRoSGVhZGVyKGxlZ2VuZFdpZHRoUHggKyAxNSksXG4gICAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IHRoaXMuZGV2aWNlU2l6ZSA9PT0gR3JpZE9wdGlvbnNFbnVtLkV4dHJhU21hbGxcbiAgICAgICAgICAgICAgICAgICAgICAgID8gQXN3Q2hhcnRDb25zdGFudHMuZm9udFNpemUxMiA6IEFzd0NoYXJ0Q29uc3RhbnRzLmZvbnRTaXplMTQsXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yOiAnIzZjNzU3ZCcsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IEFzd0NoYXJ0Q29uc3RhbnRzLmZvbnRXZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHk6ICc1MDAgMTRweC8yMHB4IEdvb2dsZSBTYW5zIFRleHQsQXJpYWwsSGVsdmV0aWNhLHNhbnMtc2VyaWYnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxhYmVsRm9ybWF0dGVyKCk6IHN0cmluZyB7XG4gICAgICAgICAgICAgICAgY29uc3QgcG9pbnQ6IGFueSA9IHRoaXMgYXMgUG9pbnQ7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwb2ludC55RGF0YS5yZWR1Y2UoKGFjYzogYW55LCBjdXI6IGFueSkgPT4gYWNjICsgY3VyLCAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcyQuc2V0TGluZUNoYXJ0TGVnZW5kV2l0aEhlYWRlcihcbiAgICAgICAgICAgICAgICAgICAgbGVnZW5kV2lkdGhQeCxcbiAgICAgICAgICAgICAgICAgICAgcG9pbnQubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0TGVnZW5kQWxpZ25tZW50KCk6IEFsaWduVmFsdWUge1xuICAgICAgICBpZiAodGhpcy5kZXZpY2VTaXplID09PSBHcmlkT3B0aW9uc0VudW0uRXh0cmFTbWFsbCkge1xuICAgICAgICAgICAgcmV0dXJuICdjZW50ZXInO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMubGVnZW5kUG9zaXRpb24gPT09IExlZ2VuZFBvc2l0aW9uRW51bS5SaWdodCkge1xuICAgICAgICAgICAgcmV0dXJuIExlZ2VuZFBvc2l0aW9uRW51bS5SaWdodDtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmxlZ2VuZFBvc2l0aW9uID09PSBMZWdlbmRQb3NpdGlvbkVudW0uTGVmdCkge1xuICAgICAgICAgICAgcmV0dXJuIExlZ2VuZFBvc2l0aW9uRW51bS5MZWZ0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuICdjZW50ZXInO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRMZWdlbmRWZXJ0aWNhbEFsaWdubWVudCgpOiBWZXJ0aWNhbEFsaWduVmFsdWUge1xuICAgICAgICBpZiAodGhpcy5kZXZpY2VTaXplID09PSBHcmlkT3B0aW9uc0VudW0uRXh0cmFTbWFsbCkge1xuICAgICAgICAgICAgcmV0dXJuIExlZ2VuZFBvc2l0aW9uRW51bS5Cb3R0b207XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5sZWdlbmRQb3NpdGlvbiA9PT0gTGVnZW5kUG9zaXRpb25FbnVtLlJpZ2h0KSB7XG4gICAgICAgICAgICByZXR1cm4gJ21pZGRsZSc7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5sZWdlbmRQb3NpdGlvbiA9PT0gTGVnZW5kUG9zaXRpb25FbnVtLkxlZnQpIHtcbiAgICAgICAgICAgIHJldHVybiAnbWlkZGxlJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBMZWdlbmRQb3NpdGlvbkVudW0uQm90dG9tO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRMaW5lQ2hhcnRMZWdlbmRXaXRoSGVhZGVyKFxuICAgICAgICBsZWdlbmRXaWR0aFB4OiBudW1iZXIsXG4gICAgICAgIG5hbWU/OiBzdHJpbmcgfCBudWxsLFxuICAgICAgICB2YWx1ZT86IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICAgICAgICBsZXQgbGVnZW5kQ2F0ZWdvcnlXaWR0aFB4OiBudW1iZXI7XG4gICAgICAgIGxldCBsZWdlbmRWYWx1ZVdpZHRoUHg6IG51bWJlcjtcbiAgICAgICAgaWYgKHRoaXMubGVnZW5kVHlwZSA9PT0gQ2hhcnRMZWdlbmRUeXBlRW51bS5EZWZhdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJ3aWR0aDoke2xlZ2VuZFdpZHRoUHh9cHhcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMiBjb2wtc20tMTIgY29sLTEyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtuYW1lID8gbmFtZSA6ICdDYXRlZ29yeSd9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxlZ2VuZENhdGVnb3J5V2lkdGhQeCA9IGxlZ2VuZFdpZHRoUHggKiAwLjU7XG4gICAgICAgICAgICBsZWdlbmRWYWx1ZVdpZHRoUHggPSBsZWdlbmRXaWR0aFB4ICogMC41O1xuICAgICAgICAgICAgcmV0dXJuIGBcbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwid2lkdGg6JHtsZWdlbmRDYXRlZ29yeVdpZHRoUHggKyBsZWdlbmRWYWx1ZVdpZHRoUHh9cHhcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGNvbC1zbS02IGNvbC02XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtuYW1lID8gbmFtZSA6ICdDYXRlZ29yeSd9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBjb2wtc20tNiBjb2wtNiB0ZXh0LWVuZCB0ZXh0LXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt2YWx1ZSA/IHRoaXMuY3VycmVuY3lQaXBlLnRyYW5zZm9ybSh2YWx1ZSwgdGhpcy5jdXJyZW5jeUNvZGUsICdzeW1ib2wnLCAnLjInKSA6ICdUb3RhbCd9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIjxkaXYgI2xpbmVDaGFydD48L2Rpdj4iXX0=