gamma-app-controller 1.1.25 → 1.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/application-controller/application-controller.module.mjs +20 -20
- package/esm2020/lib/application-controller/application-dataset-component/application-dataset/application-dataset.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset/create-dataset.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-filter/application-filter.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-menu-controller/application-menus/application-menus.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-metric-config/all-metrics-config/all-metrics-config.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-metric-config/create-metrics/create-metrics.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-view-components/application-views/application-views.component.mjs +1 -1
- package/esm2020/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.mjs +1 -1
- package/esm2020/lib/application-controller/page-controller/page-config/page-config.component.mjs +11 -11
- package/esm2020/lib/application-controller/page-controller/page-config-multi-layout/page-config-multi-layout.component.mjs +10 -10
- package/esm2020/lib/application-controller/page-controller/page-controller/page-controller.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/dash-chart/dash-chart.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/dash-table/dash-table.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/dash-today-previous/dash-today-previous.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/geo-map/geo-map.component.mjs +2 -2
- package/esm2020/lib/application-controller/support-components/heat-map/heat-map.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/single-card/single-card.component.mjs +1 -1
- package/esm2020/lib/application-controller/support-components/table-with-bar/table-with-bar.component.mjs +2 -2
- package/esm2020/lib/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.mjs +116 -0
- package/esm2020/lib/shared/advanced-component/app-advance-header/app-header.component.mjs +306 -0
- package/esm2020/lib/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.mjs +80 -0
- package/esm2020/lib/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.mjs +379 -0
- package/esm2020/lib/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +188 -0
- package/esm2020/lib/shared/advanced-component/gamma-geo-chart/gamma-geo-chart.component.mjs +435 -0
- package/esm2020/lib/shared/advanced-component/gamma-heatmap/gamma-heatmap.component.mjs +334 -0
- package/esm2020/lib/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.mjs +155 -0
- package/esm2020/lib/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.mjs +20 -0
- package/esm2020/lib/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.mjs +187 -0
- package/esm2020/lib/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.mjs +86 -0
- package/esm2020/lib/shared/advanced-component/google-geo-map/google-geo-map.component.mjs +439 -0
- package/esm2020/lib/shared/app-title/app-title.component.mjs +67 -0
- package/esm2020/lib/shared/gamam-widget/gamam-widget.component.mjs +35 -0
- package/esm2020/lib/shared/gamma-advance-filter/gamma-advance-filter.component.mjs +273 -0
- package/esm2020/lib/shared/gamma-bread-crumbs/bread-crumbs.component.mjs +142 -0
- package/esm2020/lib/shared/kpi-comon-service.mjs +537 -0
- package/esm2020/lib/{application-controller/shared → shared}/loader/loader.component.mjs +1 -1
- package/esm2020/lib/{application-controller/shared → shared}/loading/loading.component.mjs +1 -1
- package/esm2020/lib/shared/loading/loadingModule.mjs +28 -0
- package/esm2020/lib/shared/safeHtmlPipe.mjs +20 -0
- package/esm2020/lib/template-module/KpiCreationModule/create-kpi-tree.component.mjs +381 -0
- package/esm2020/lib/template-module/KpiCreationModule/createKpi.service.mjs +90 -0
- package/esm2020/lib/template-module/KpiCreationModule/kpiCreation.module.mjs +184 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animation.mjs +15 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/defaults.mjs +12 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/expand-collapse.mjs +16 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/fade.mjs +160 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/shake.mjs +58 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/slide.mjs +116 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/animations/zoom.mjs +36 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/aside/aside.component.mjs +85 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/basic/basic.component.mjs +118 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/collapsable/collapsable.component.mjs +159 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/divider/divider.component.mjs +27 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/group/group.component.mjs +37 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/components/spacer/spacer.component.mjs +27 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/moment-helper.mjs +4 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/treeview-navigation.service.mjs +2 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/treeview-shared.service.mjs +16 -0
- package/esm2020/lib/template-module/KpiCreationModule/treeview/treeview.component.mjs +134 -0
- package/esm2020/lib/template-module/bookmarked-template/bookmarked-template.component.mjs +816 -0
- package/esm2020/lib/template-module/bookmarked-template/bookmarkedTemplate.module.mjs +149 -0
- package/esm2020/lib/template-module/cdrConfigModule/cdr-config.component.mjs +1 -1
- package/esm2020/lib/template-module/cdrConfigModule/cdrConfig.module.mjs +2 -2
- package/esm2020/lib/template-module/defaulLandingComponent/defaultLandingComponent.module.mjs +149 -0
- package/esm2020/lib/template-module/defaulLandingComponent/landing-component.component.mjs +870 -0
- package/esm2020/lib/template-module/exceptionConfigModule/exception-operation.component.mjs +1 -1
- package/esm2020/lib/template-module/exceptionConfigModule/exceptionConfig.module.mjs +2 -2
- package/esm2020/lib/template-module/kpiWithMultiLayout/dynamin-modal-multi.component.mjs +180 -0
- package/esm2020/lib/template-module/kpiWithMultiLayout/kpi-with-multilayout.component.mjs +992 -0
- package/esm2020/lib/template-module/kpiWithMultiLayout/kpiWithMultiayout.module.mjs +154 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/dynamin-modal.component.mjs +180 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/kpi-with-dataset.component.mjs +1046 -0
- package/esm2020/lib/template-module/kpiWithSingleLayout/kpiWithSingleLayout.module.mjs +154 -0
- package/esm2020/public-api.mjs +39 -20
- package/fesm2015/gamma-app-controller.mjs +6750 -475
- package/fesm2015/gamma-app-controller.mjs.map +1 -1
- package/fesm2020/gamma-app-controller.mjs +6709 -475
- package/fesm2020/gamma-app-controller.mjs.map +1 -1
- package/lib/application-controller/application-controller.module.d.ts +19 -19
- package/lib/application-controller/page-controller/page-config/page-config.component.d.ts +9 -9
- package/lib/application-controller/page-controller/page-config-multi-layout/page-config-multi-layout.component.d.ts +8 -8
- package/lib/{application-controller/shared → shared}/advanced-component/app-advance-header/app-header.component.d.ts +18 -2
- package/lib/{application-controller/shared → shared}/advanced-component/gamm-single-number-card/gamm-single-number-card.component.d.ts +3 -5
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-advance-chart/gamma-advance-chart.component.d.ts +3 -1
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.d.ts +4 -2
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-geo-chart/gamma-geo-chart.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-heatmap/gamma-heatmap.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.d.ts +6 -2
- package/lib/{application-controller/shared → shared}/advanced-component/gamma-today-previous/gamma-today-previous.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/advanced-component/google-geo-map/google-geo-map.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/app-title/app-title.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/gamam-widget/gamam-widget.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/gamma-advance-filter/gamma-advance-filter.component.d.ts +3 -2
- package/lib/{application-controller/shared → shared}/gamma-bread-crumbs/bread-crumbs.component.d.ts +1 -1
- package/lib/{application-controller/shared → shared}/kpi-comon-service.d.ts +1 -1
- package/lib/template-module/KpiCreationModule/create-kpi-tree.component.d.ts +75 -0
- package/lib/template-module/KpiCreationModule/createKpi.service.d.ts +32 -0
- package/lib/template-module/KpiCreationModule/kpiCreation.module.d.ts +23 -0
- package/lib/template-module/KpiCreationModule/treeview/animation.d.ts +1 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/defaults.d.ts +11 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/expand-collapse.d.ts +2 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/fade.d.ts +11 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/shake.d.ts +2 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/slide.d.ts +9 -0
- package/lib/template-module/KpiCreationModule/treeview/animations/zoom.d.ts +3 -0
- package/lib/template-module/KpiCreationModule/treeview/components/aside/aside.component.d.ts +26 -0
- package/lib/template-module/KpiCreationModule/treeview/components/basic/basic.component.d.ts +29 -0
- package/lib/template-module/KpiCreationModule/treeview/components/collapsable/collapsable.component.d.ts +37 -0
- package/lib/template-module/KpiCreationModule/treeview/components/divider/divider.component.d.ts +13 -0
- package/lib/template-module/KpiCreationModule/treeview/components/group/group.component.d.ts +17 -0
- package/lib/template-module/KpiCreationModule/treeview/components/spacer/spacer.component.d.ts +13 -0
- package/lib/template-module/KpiCreationModule/treeview/moment-helper.d.ts +3 -0
- package/lib/template-module/KpiCreationModule/treeview/treeview-navigation.service.d.ts +39 -0
- package/lib/template-module/KpiCreationModule/treeview/treeview-shared.service.d.ts +8 -0
- package/lib/template-module/KpiCreationModule/treeview/treeview.component.d.ts +52 -0
- package/lib/template-module/bookmarked-template/bookmarked-template.component.d.ts +109 -0
- package/lib/template-module/bookmarked-template/bookmarkedTemplate.module.d.ts +16 -0
- package/lib/template-module/cdrConfigModule/cdrConfig.module.d.ts +1 -1
- package/lib/template-module/defaulLandingComponent/defaultLandingComponent.module.d.ts +16 -0
- package/lib/template-module/defaulLandingComponent/landing-component.component.d.ts +109 -0
- package/lib/template-module/exceptionConfigModule/exceptionConfig.module.d.ts +1 -1
- package/lib/template-module/kpiWithMultiLayout/dynamin-modal-multi.component.d.ts +42 -0
- package/lib/template-module/kpiWithMultiLayout/kpi-with-multilayout.component.d.ts +117 -0
- package/lib/template-module/kpiWithMultiLayout/kpiWithMultiayout.module.d.ts +17 -0
- package/lib/template-module/kpiWithSingleLayout/dynamin-modal.component.d.ts +42 -0
- package/lib/template-module/kpiWithSingleLayout/kpi-with-dataset.component.d.ts +122 -0
- package/lib/template-module/kpiWithSingleLayout/kpiWithSingleLayout.module.d.ts +17 -0
- package/package.json +1 -1
- package/public-api.d.ts +38 -19
- package/esm2020/lib/application-controller/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.mjs +0 -124
- package/esm2020/lib/application-controller/shared/advanced-component/app-advance-header/app-header.component.mjs +0 -220
- package/esm2020/lib/application-controller/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.mjs +0 -95
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.mjs +0 -362
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +0 -177
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-geo-chart/gamma-geo-chart.component.mjs +0 -441
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-heatmap/gamma-heatmap.component.mjs +0 -328
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.mjs +0 -155
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.mjs +0 -20
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.mjs +0 -157
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.mjs +0 -85
- package/esm2020/lib/application-controller/shared/advanced-component/google-geo-map/google-geo-map.component.mjs +0 -439
- package/esm2020/lib/application-controller/shared/app-title/app-title.component.mjs +0 -67
- package/esm2020/lib/application-controller/shared/gamam-widget/gamam-widget.component.mjs +0 -35
- package/esm2020/lib/application-controller/shared/gamma-advance-filter/gamma-advance-filter.component.mjs +0 -237
- package/esm2020/lib/application-controller/shared/gamma-bread-crumbs/bread-crumbs.component.mjs +0 -142
- package/esm2020/lib/application-controller/shared/kpi-comon-service.mjs +0 -537
- package/esm2020/lib/application-controller/shared/loading/loadingModule.mjs +0 -28
- package/esm2020/lib/application-controller/shared/safeHtmlPipe.mjs +0 -20
- /package/lib/{application-controller/shared → shared}/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/advanced-component/gamma-table-with-percentage/contentSafeHtml.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/loader/loader.component.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/loading/loading.component.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/loading/loadingModule.d.ts +0 -0
- /package/lib/{application-controller/shared → shared}/safeHtmlPipe.d.ts +0 -0
|
@@ -1,362 +0,0 @@
|
|
|
1
|
-
import { Component, Input } from '@angular/core';
|
|
2
|
-
import moment from './../../../moment-helper';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
import * as i1 from "../../../common";
|
|
5
|
-
import * as i2 from "ngx-toastr";
|
|
6
|
-
import * as i3 from "../../kpi-comon-service";
|
|
7
|
-
import * as i4 from "@angular/common";
|
|
8
|
-
import * as i5 from "devextreme-angular/core";
|
|
9
|
-
import * as i6 from "devextreme-angular/ui/nested";
|
|
10
|
-
import * as i7 from "devextreme-angular/ui/chart";
|
|
11
|
-
import * as i8 from "devextreme-angular/ui/funnel";
|
|
12
|
-
import * as i9 from "devextreme-angular/ui/pie-chart";
|
|
13
|
-
import * as i10 from "@angular/material/tooltip";
|
|
14
|
-
import * as i11 from "../../app-title/app-title.component";
|
|
15
|
-
import * as i12 from "../../loader/loader.component";
|
|
16
|
-
export class GammaAdvanceChartComponent {
|
|
17
|
-
constructor(commonService, toastr, kpiService, renderer, el, cdr) {
|
|
18
|
-
this.commonService = commonService;
|
|
19
|
-
this.toastr = toastr;
|
|
20
|
-
this.kpiService = kpiService;
|
|
21
|
-
this.renderer = renderer;
|
|
22
|
-
this.el = el;
|
|
23
|
-
this.cdr = cdr;
|
|
24
|
-
this.chartConfig = {};
|
|
25
|
-
this.page_config = {};
|
|
26
|
-
this.isLoader = true;
|
|
27
|
-
this.creatChartDataSource = undefined;
|
|
28
|
-
this.finalChartDataSource = [];
|
|
29
|
-
this.isFullScreen = false;
|
|
30
|
-
this.customizeTooltip = (info) => ({
|
|
31
|
-
html: `<table width=100% height=30 border=0 style=\'font-size: 13px\'>
|
|
32
|
-
<tr><td style=\'text-align: left; color: white\'> ${this.commonService.convertToTitleCase(this.chartConfig.argumentField)} : ${info.argumentText} </td></tr>
|
|
33
|
-
<tr><td style=\'text-align: left; color: white; padding-top: 5px\'> ${info.seriesName} :
|
|
34
|
-
${this.getValue(info.seriesName, info.value)} </td></tr>
|
|
35
|
-
</table>`,
|
|
36
|
-
});
|
|
37
|
-
this.customizeText = ({ percentText, item: { argument } }) => `<span style='font-size: 28px'>${percentText}</span><br/>${argument}`;
|
|
38
|
-
}
|
|
39
|
-
set chartDataSource(value) {
|
|
40
|
-
this.creatChartDataSource = value;
|
|
41
|
-
if (this.creatChartDataSource === undefined || this.creatChartDataSource.length === 0) {
|
|
42
|
-
this.isChartvisible = false;
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
this.isLoader = true;
|
|
47
|
-
this.page_config = value;
|
|
48
|
-
if (value.kpiConfig.dataSource && value.kpiConfig.dataSource.length !== 0) {
|
|
49
|
-
this.chartConfig = value.kpiConfig.dataConfig;
|
|
50
|
-
if (value.kpiConfig.formate == "daily") {
|
|
51
|
-
const sortedData = value.kpiConfig.dataSource
|
|
52
|
-
.filter(record => record.recordDate)
|
|
53
|
-
.sort((a, b) => moment(b.recordDate).diff(moment(a.recordDate)));
|
|
54
|
-
const mostRecentRecord = sortedData[0];
|
|
55
|
-
const filteredObjects = sortedData.filter(data => data.recordDate === value.endDate);
|
|
56
|
-
if (this.chartConfig.chartType == 'funnel') {
|
|
57
|
-
if (filteredObjects && filteredObjects.length !== 0) {
|
|
58
|
-
this.finalChartDataSource = Object.keys(filteredObjects[0]).filter(key => key !== 'recordDate').map(key => ({
|
|
59
|
-
argument: key,
|
|
60
|
-
value: Math.abs(parseInt(filteredObjects[0][key]))
|
|
61
|
-
}));
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
this.finalChartDataSource = [];
|
|
65
|
-
}
|
|
66
|
-
console.log(this.finalChartDataSource);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
this.getDailyChart(filteredObjects, value.kpiConfig.dataConfig);
|
|
70
|
-
}
|
|
71
|
-
this.isLoader = false;
|
|
72
|
-
}
|
|
73
|
-
else if (value.kpiConfig.formate == "monthly") {
|
|
74
|
-
if (this.chartConfig.chartType == 'bubble') {
|
|
75
|
-
this.bubbleChartData = value.kpiConfig.dataSource;
|
|
76
|
-
this.getBubbleChartData();
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
this.getMonthlyChart(value.kpiConfig.dataSource, value.kpiConfig.dataConfig);
|
|
80
|
-
this.isChartvisible == true;
|
|
81
|
-
}
|
|
82
|
-
this.isLoader = false;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
setTimeout(() => {
|
|
87
|
-
this.isLoader = false;
|
|
88
|
-
}, 200);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
ngOnInit() {
|
|
93
|
-
}
|
|
94
|
-
getHourChart(data, dataConfig) {
|
|
95
|
-
if (data) {
|
|
96
|
-
data.forEach(val => {
|
|
97
|
-
if (val[dataConfig.argumentField].toString().length == 1) {
|
|
98
|
-
val[dataConfig.argumentField] = '0' + val[dataConfig.argumentField];
|
|
99
|
-
}
|
|
100
|
-
let label = val[dataConfig.argumentField].toString();
|
|
101
|
-
val[dataConfig.argumentField] = label;
|
|
102
|
-
});
|
|
103
|
-
setTimeout(() => {
|
|
104
|
-
this.finalChartDataSource = data;
|
|
105
|
-
}, 500);
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
this.toastr.error(this.kpi_name + 'Chart Error');
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
getMonthlyChart(data, dataConfig) {
|
|
112
|
-
const valueFields = dataConfig.chart_config.map(config => config.valueField);
|
|
113
|
-
data.forEach((entry) => {
|
|
114
|
-
valueFields.forEach((field) => {
|
|
115
|
-
if (entry.hasOwnProperty(field)) {
|
|
116
|
-
if (typeof entry[field] === "string") {
|
|
117
|
-
entry[field] = Number(entry[field]);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
if (data) {
|
|
123
|
-
let content = this.chartConfig.argumentField.toLowerCase();
|
|
124
|
-
if (content.includes('date')) {
|
|
125
|
-
const dataSource = data.map(obj => {
|
|
126
|
-
const newObj = { ...obj };
|
|
127
|
-
if (newObj.hasOwnProperty(this.chartConfig.argumentField)) {
|
|
128
|
-
newObj[this.chartConfig.argumentField] = moment(newObj[this.chartConfig.argumentField]).format("MM-DD");
|
|
129
|
-
}
|
|
130
|
-
return newObj;
|
|
131
|
-
});
|
|
132
|
-
this.finalChartDataSource = dataSource;
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
this.finalChartDataSource = data;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
this.toastr.error(this.kpi_name + 'Chart Error');
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
getDailyChart(data, dataConfig) {
|
|
143
|
-
const valueFields = dataConfig.chart_config.map(config => config.valueField);
|
|
144
|
-
if (data) {
|
|
145
|
-
let content = this.chartConfig.argumentField.toLowerCase();
|
|
146
|
-
if (content.includes('date')) {
|
|
147
|
-
const dataSource = data.map(obj => {
|
|
148
|
-
const newObj = { ...obj };
|
|
149
|
-
Object.keys(newObj).forEach(key => {
|
|
150
|
-
if (key !== this.chartConfig.argumentField && !isNaN(newObj[key])) {
|
|
151
|
-
newObj[key] = Number(newObj[key]);
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
if (newObj.hasOwnProperty(this.chartConfig.argumentField)) {
|
|
155
|
-
newObj[this.chartConfig.argumentField] = moment(newObj[this.chartConfig.argumentField]).format("MM-DD");
|
|
156
|
-
}
|
|
157
|
-
return newObj;
|
|
158
|
-
});
|
|
159
|
-
this.finalChartDataSource = dataSource;
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
this.finalChartDataSource = data;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
this.toastr.error(this.kpi_name + ' Chart Error');
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
getReconDailyChart(data, dataConfig) {
|
|
170
|
-
this.finalChartDataSource = [];
|
|
171
|
-
const recon_key = dataConfig.reconKey;
|
|
172
|
-
const recon_column = dataConfig.reconColumns;
|
|
173
|
-
this.finalChartDataSource = this.getFinalData(data, recon_column);
|
|
174
|
-
}
|
|
175
|
-
getFinalData(mainData, reconColumn) {
|
|
176
|
-
mainData.forEach(data => {
|
|
177
|
-
reconColumn.forEach(column => {
|
|
178
|
-
const firstKeyValue = data[column.firstKey];
|
|
179
|
-
const secondKeyValue = data[column.secondKey];
|
|
180
|
-
const mouDiff = Math.abs(firstKeyValue - secondKeyValue);
|
|
181
|
-
data[column.finalKey] = mouDiff;
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
return mainData;
|
|
185
|
-
}
|
|
186
|
-
calculateTotal(pieChart) {
|
|
187
|
-
const totalValue = pieChart.getAllSeries()[0].getVisiblePoints().reduce((s, p) => s + p.originalValue, 0);
|
|
188
|
-
return this.formatNumber(totalValue);
|
|
189
|
-
}
|
|
190
|
-
formatNumber(value) {
|
|
191
|
-
if (value >= 1e9) {
|
|
192
|
-
return (value / 1e9).toFixed(2) + 'B';
|
|
193
|
-
}
|
|
194
|
-
else if (value >= 1e6) {
|
|
195
|
-
return (value / 1e6).toFixed(2) + 'M';
|
|
196
|
-
}
|
|
197
|
-
else if (value >= 1e3) {
|
|
198
|
-
return (value / 1e3).toFixed(2) + 'K';
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
return value.toFixed(2);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
pointClickHandler(arg) {
|
|
205
|
-
arg.target.select();
|
|
206
|
-
}
|
|
207
|
-
getValue(contextKey, value) {
|
|
208
|
-
let context_data;
|
|
209
|
-
const sml_key = contextKey.toLowerCase();
|
|
210
|
-
if (typeof value === "number") {
|
|
211
|
-
if (sml_key === "count" || sml_key === "hour" || sml_key === "denomination" || sml_key.includes("count")) {
|
|
212
|
-
context_data = this.commonService.reformatNumberWithThousandSeparatorV3(value, 0);
|
|
213
|
-
}
|
|
214
|
-
else if (sml_key.includes('volume') || sml_key.includes('upload') || sml_key.includes('download')) {
|
|
215
|
-
if (sml_key == 'billablevolume') {
|
|
216
|
-
context_data = this.commonService.formatBytsToGb(value * 1024, 2);
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
context_data = this.commonService.formatBytsToGb(value * 1024, 2);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
else if (sml_key == "uplink" || sml_key == "downlink") {
|
|
223
|
-
context_data = this.commonService.formatBytsToGb(value, 2);
|
|
224
|
-
}
|
|
225
|
-
else if (this.hasDecimal(value)) {
|
|
226
|
-
context_data = this.commonService.reformatNumberWithThousandSeparatorV3(value, 2);
|
|
227
|
-
}
|
|
228
|
-
else if (!this.hasDecimal(value)) {
|
|
229
|
-
context_data = this.commonService.reformatNumberWithThousandSeparatorV3(value, 0);
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
context_data = this.commonService.reformatNumberWithThousandSeparatorV3(value, 2);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
context_data = value;
|
|
237
|
-
}
|
|
238
|
-
return context_data;
|
|
239
|
-
}
|
|
240
|
-
hasDecimal(number) {
|
|
241
|
-
return number % 1 !== 0;
|
|
242
|
-
}
|
|
243
|
-
toggleFullScreen() {
|
|
244
|
-
this.isLoader = true;
|
|
245
|
-
this.isFullScreen = !this.isFullScreen;
|
|
246
|
-
const div = this.el.nativeElement.querySelector('.not-full-screen');
|
|
247
|
-
if (this.isFullScreen) {
|
|
248
|
-
this.renderer.addClass(div, 'full-screen');
|
|
249
|
-
setTimeout(() => {
|
|
250
|
-
this.isLoader = false;
|
|
251
|
-
}, 10);
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
this.renderer.removeClass(div, 'full-screen');
|
|
255
|
-
setTimeout(() => {
|
|
256
|
-
this.isLoader = false;
|
|
257
|
-
}, 10);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
getBubbleChartData() {
|
|
261
|
-
this.heatChartDataSource = {};
|
|
262
|
-
const { result, uniqueDates } = this.generateData(this.bubbleChartData, this.chartConfig);
|
|
263
|
-
this.heatChartDataSource["dataSet"] = result;
|
|
264
|
-
this.heatChartDataSource["argumentValue"] = uniqueDates;
|
|
265
|
-
}
|
|
266
|
-
generateData(data, chartConfig) {
|
|
267
|
-
const result = [];
|
|
268
|
-
const uniqueDates = new Set();
|
|
269
|
-
const dataSourceMap = {};
|
|
270
|
-
const sourceField = chartConfig.sourceField;
|
|
271
|
-
const argumentField = chartConfig.argumentField;
|
|
272
|
-
const valueField = chartConfig.chart_config[0].valueField;
|
|
273
|
-
const minBubbleSize = (this.chartConfig.minBubbleSize) ? parseInt(this.chartConfig.minBubbleSize) : 8;
|
|
274
|
-
const maxBubbleSize = (this.chartConfig.maxBubbleSize) ? parseInt(this.chartConfig.maxBubbleSize) : 20;
|
|
275
|
-
data.forEach(item => {
|
|
276
|
-
const sourceFieldValue = item[sourceField];
|
|
277
|
-
const argumentFieldValue = item[argumentField];
|
|
278
|
-
const { [sourceField]: _, [argumentField]: __, ...rest } = item;
|
|
279
|
-
if (!dataSourceMap[sourceFieldValue]) {
|
|
280
|
-
dataSourceMap[sourceFieldValue] = {
|
|
281
|
-
datasource: sourceFieldValue,
|
|
282
|
-
dataset: []
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
dataSourceMap[sourceFieldValue].dataset.push({
|
|
286
|
-
...rest,
|
|
287
|
-
[argumentField]: moment(argumentFieldValue).format('YYYY-MM-DD')
|
|
288
|
-
});
|
|
289
|
-
uniqueDates.add(moment(argumentFieldValue).format('YYYY-MM-DD'));
|
|
290
|
-
});
|
|
291
|
-
const uniqueDatesArray = Array.from(uniqueDates);
|
|
292
|
-
for (const key in dataSourceMap) {
|
|
293
|
-
const dataset = dataSourceMap[key].dataset;
|
|
294
|
-
const formattedDataset = this.getFormateDataByColorCode(dataset, valueField, minBubbleSize, maxBubbleSize);
|
|
295
|
-
const dateToItemMap = {};
|
|
296
|
-
formattedDataset.forEach(item => {
|
|
297
|
-
dateToItemMap[item[argumentField]] = item;
|
|
298
|
-
});
|
|
299
|
-
const completeDataset = uniqueDatesArray.map((date) => {
|
|
300
|
-
if (dateToItemMap[date]) {
|
|
301
|
-
return dateToItemMap[date];
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
return {
|
|
305
|
-
fileCount: 0,
|
|
306
|
-
[argumentField]: date,
|
|
307
|
-
[valueField]: 0,
|
|
308
|
-
color: "rgb(242, 118, 109)"
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
result.push({
|
|
313
|
-
datasource: key,
|
|
314
|
-
dataset: completeDataset
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
return {
|
|
318
|
-
result: result,
|
|
319
|
-
uniqueDates: uniqueDatesArray
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
getFormateDataByColorCode(filedata, valueField, minBubbleSize, maxBubbleSize) {
|
|
323
|
-
filedata.forEach(item => {
|
|
324
|
-
item[valueField] = parseFloat(item[valueField]);
|
|
325
|
-
});
|
|
326
|
-
let maxRechargeCount = Math.max(...filedata.map(item => item[valueField]));
|
|
327
|
-
let minRechargeCount = Math.min(...filedata.map(item => item[valueField]));
|
|
328
|
-
let minColor = [43, 224, 91];
|
|
329
|
-
let maxColor = [65, 135, 24];
|
|
330
|
-
let hover = [135, 184, 106];
|
|
331
|
-
filedata.forEach(item => {
|
|
332
|
-
let size = this.mapRange(item[valueField], minRechargeCount, maxRechargeCount, minBubbleSize, maxBubbleSize);
|
|
333
|
-
item.size = size;
|
|
334
|
-
item.toolTip = (item[valueField]) ? item[valueField] : '0';
|
|
335
|
-
item.hover = `rgb(${hover.join(',')})`;
|
|
336
|
-
if (item[valueField] == 0 || item[valueField] == undefined) {
|
|
337
|
-
item.color = `rgb(${minColor.join(',')})`;
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
item.color = `rgb(${maxColor.join(',')})`;
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
return filedata;
|
|
344
|
-
}
|
|
345
|
-
mapRange(value, inMin, inMax, outMin, outMax) {
|
|
346
|
-
return ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
GammaAdvanceChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: GammaAdvanceChartComponent, deps: [{ token: i1.CommonService }, { token: i2.ToastrService }, { token: i3.kpicommonService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
350
|
-
GammaAdvanceChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: GammaAdvanceChartComponent, selector: "app-gamma-advance-chart", inputs: { componentId: "componentId", kpi_name: "kpi_name", chartDataSource: "chartDataSource" }, ngImport: i0, template: "<div class=\"not-full-screen\" (dblclick)=\"toggleFullScreen()\">\n <ng-container *ngIf=\"page_config?.widGetConfig?.display\">\n <app-title [title]=\"page_config.widGetConfig.widgetTitle\" [operators]=\"page_config.operations\"\n [displayType]=\"'chart'\"></app-title>\n </ng-container>\n <div class=\"mx-2 p-2 bg-gray-800\">\n <app-loader *ngIf=\"isLoader\"></app-loader>\n \n <ng-container *ngIf=\"chartConfig.chartType !== 'doughnut' && chartConfig.chartType !== 'funnel' && chartConfig.chartType !== 'pie'\" >\n <dx-chart id=\"chart\" [dataSource]=\"finalChartDataSource\"\n [title]=\"{ text: chartConfig.caption, font: { size: 14 } }\" *ngIf=\"!isLoader\"\n [valueAxis]=\"chartConfig.valueAxisConfig\">\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item && item.axis\">\n <dxi-value-axis name=\"{{item.axis}}\" position=\"{{item.position}}\">\n <dxo-title text=\"{{item.name}}\"></dxo-title>\n </dxi-value-axis>\n </ng-container>\n\n </ng-container>\n <dxo-argument-axis>\n <dxo-label overlappingBehavior=\"rotate\" [rotationAngle]=\"270\"></dxo-label>\n </dxo-argument-axis>\n <dxo-tooltip [enabled]=\"true\" [shared]=\"true\" [customizeTooltip]=\"customizeTooltip\">\n </dxo-tooltip>\n <dxo-common-series-settings argumentField=\"{{chartConfig.argumentField}}\">\n </dxo-common-series-settings>\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item && item.color\">\n <dxi-series type=\"{{item.type}}\" valueField=\"{{item.valueField}}\" axis=\"{{item.axis}}\"\n name=\"{{item.name}}\" color=\"{{item.color}}\">\n </dxi-series>\n </ng-container>\n <ng-container *ngIf=\"item && !item.color\">\n <dxi-series type=\"{{item.type}}\" valueField=\"{{item.valueField}}\" axis=\"{{item.axis}}\"\n name=\"{{item.name}}\">\n </dxi-series>\n </ng-container>\n\n </ng-container>\n <dxo-size [height]=\"chartHeight\">\n </dxo-size>\n <dxo-legend [visible]=\"chartConfig.legendDisplay\" verticalAlignment=\"{{chartConfig.verticalAlignment}}\"\n horizontalAlignment=\"{{chartConfig.horizontalAlignment}}\">\n </dxo-legend>\n </dx-chart>\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'doughnut' || chartConfig.chartType == 'pie'\">\n\n <dx-pie-chart id=\"pie\" [type]=\"chartConfig.chartType\" [title]=\"{ text: chartConfig.caption, font: { size: 14 } }\"\n palette=\"Soft Pastel\" [dataSource]=\"finalChartDataSource\" centerTemplate=\"centerTemplate\"\n (onPointClick)=\"pointClickHandler($event)\" [palette]=\"chartConfig.palette\">\n\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item.color\">\n <dxi-series argumentField={{chartConfig.argumentField}} valueField=\"{{item.valueField}}\"\n name=\"{{item.name}}\" color=\"{{item.color}}\">\n <dxo-label [visible]=\"chartConfig.labelDisplay\" format=\"currency\">\n <dxo-connector [visible]=\"true\"></dxo-connector>\n </dxo-label>\n </dxi-series>\n </ng-container>\n <ng-container *ngIf=\"!item.color\">\n <dxi-series argumentField={{chartConfig.argumentField}} valueField=\"{{item.valueField}}\"\n name=\"{{item.name}}\">\n <dxo-label [visible]=\"chartConfig.labelDisplay\" format=\"currency\">\n <dxo-connector [visible]=\"true\"></dxo-connector>\n </dxo-label>\n </dxi-series>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n <dxo-legend [visible]=\"chartConfig.legendDisplay\"\n horizontalAlignment=\"{{chartConfig.horizontalAlignment}}\"\n verticalAlignment=\"{{chartConfig.verticalAlignment}}\"></dxo-legend>\n <!-- <dxo-export [enabled]=\"true\"></dxo-export> -->\n <dxo-tooltip [enabled]=\"true\" [customizeTooltip]=\"customizeTooltip\" format=\"currency\">\n </dxo-tooltip>\n <ng-container *ngIf=\"chartConfig.chartType == 'doughnut'\">\n <svg *dxTemplate=\"let pieChart of 'centerTemplate'\">\n <circle cx=\"100\" cy=\"100\" [attr.r]=\"pieChart.getInnerRadius() - 6\" fill=\"gray\" opacity=\"0.0001\">\n </circle>\n \n <text text-anchor=\"middle\" style=\"font-size: 15px\" x=\"100\" y=\"100\" fill=\"#eee\">\n <tspan x=\"100\">{{ calculateTotal(pieChart) }}</tspan>\n <!-- display: inline -->\n <!-- <tspan x=\"100\" dy=\"20px\" style=\"font-weight: 600\"></tspan> -->\n </text>\n </svg>\n </ng-container>\n \n </dx-pie-chart>\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'funnel'\">\n <dx-funnel id=\"funnel\" [dataSource]=\"finalChartDataSource\" argumentField=\"argument\" valueField=\"value\"\n palette=\"Soft Pastel\">\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n <dxo-export [enabled]=\"false\"></dxo-export>\n <dxo-tooltip [enabled]=\"true\"> </dxo-tooltip>\n <dxo-item>\n <dxo-border [visible]=\"true\"> </dxo-border>\n </dxo-item>\n <dxo-label [visible]=\"true\" position=\"inside\" backgroundColor=\"none\"\n [customizeText]=\"customizeText\"></dxo-label>\n </dx-funnel>\n\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'bubble'\">\n <div class=\"mx-5 overflow-x-auto\">\n <ng-container *ngFor=\"let item of heatChartDataSource.dataSet\">\n <div class=\"flex flex-row\">\n <div class=\"h-10 text-sm items-center min-w-12 max-w-[30%] justify-center flex\">\n {{item.datasource}}\n </div>\n <div class=\"inline-block \">\n <div class=\"flex flex-nowrap justify-center \">\n <ng-container *ngFor=\"let box of item.dataset\">\n <div class=\"flex-shrink-0 min-w-10 max-w-[20%] h-10 text-sm cursor-pointer flex items-center justify-center text-gray-800\"\n [matTooltip]=\"'Record Date: ' + box.recordDate + '\\nRecharge Count: ' + box.toolTip\"\n matTooltipClass=\"custom-tooltip\">\n <div class=\"rounded-full\" [ngStyle]=\"{\n 'background-color': box.isHovered ? 'rgb(135, 184, 106)' : box.color,\n 'width.px': box.size,\n 'hover': box.hover,\n 'height.px': box.size\n }\" (mouseenter)=\"box.isHovered = true\"\n (mouseleave)=\"box.isHovered = false\">\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-12 max-w-[20%] h-full flex items-center justify-center\"></div>\n <div *ngFor=\"let item of heatChartDataSource.argumentValue\"\n class=\"flex-shrink-0 w-10 max-w-[20%] min-h-14 flex text-sm items-center justify-center my-1\"\n [ngStyle]=\"{'height': 'auto'}\">\n <span class=\"text-rotate\">\n {{item}}\n </span>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <button *ngIf=\"isFullScreen\" class=\"close-button\" (click)=\"toggleFullScreen()\">Close</button>\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i5.DxTemplateDirective, selector: "[dxTemplate]", inputs: ["dxTemplateOf"] }, { kind: "component", type: i6.DxoExportComponent, selector: "dxo-export", inputs: ["backgroundColor", "enabled", "fileName", "formats", "margin", "printingEnabled", "proxyUrl", "svgToCanvas", "allowExportSelectedData", "customizeExcelCell", "excelFilterEnabled", "excelWrapTextEnabled", "ignoreExcelErrors", "texts"] }, { kind: "component", type: i6.DxoLabelComponent, selector: "dxo-label", inputs: ["connectorColor", "connectorWidth", "customizeText", "font", "format", "indent", "visible", "horizontalAlignment", "position", "text", "verticalAlignment", "alignment", "customizeHint", "displayMode", "indentFromAxis", "overlappingBehavior", "rotationAngle", "staggeringSpacing", "template", "textOverflow", "wordWrap", "argumentFormat", "backgroundColor", "border", "connector", "displayFormat", "horizontalOffset", "showForZeroValues", "verticalOffset", "hideFirstOrLast", "indentFromTick", "useRangeColors", "location", "showColon", "radialOffset", "topIndent", "shadow", "useNodeColors", "dataField", "enabled"] }, { kind: "component", type: i6.DxoLegendComponent, selector: "dxo-legend", inputs: ["backgroundColor", "border", "columnCount", "columnItemSpacing", "customizeHint", "customizeItems", "customizeText", "font", "horizontalAlignment", "itemsAlignment", "itemTextFormat", "itemTextPosition", "margin", "markerSize", "markerTemplate", "orientation", "paddingLeftRight", "paddingTopBottom", "rowCount", "rowItemSpacing", "title", "verticalAlignment", "visible", "hoverMode", "position"] }, { kind: "component", type: i6.DxoBorderComponent, selector: "dxo-border", inputs: ["color", "cornerRadius", "dashStyle", "opacity", "visible", "width", "bottom", "left", "right", "top"] }, { kind: "component", type: i6.DxoTitleComponent, selector: "dxo-title", inputs: ["font", "horizontalAlignment", "margin", "placeholderSize", "subtitle", "text", "verticalAlignment", "textOverflow", "wordWrap", "alignment"] }, { kind: "component", type: i6.DxoSizeComponent, selector: "dxo-size", inputs: ["height", "width"] }, { kind: "component", type: i6.DxoTooltipComponent, selector: "dxo-tooltip", inputs: ["arrowLength", "border", "color", "container", "contentTemplate", "cornerRadius", "customizeTooltip", "enabled", "font", "format", "interactive", "opacity", "paddingLeftRight", "paddingTopBottom", "shadow", "zIndex", "argumentFormat", "location", "shared", "isShown", "text", "position", "showMode", "customizeLinkTooltip", "customizeNodeTooltip", "linkTooltipTemplate", "nodeTooltipTemplate"] }, { kind: "component", type: i7.DxChartComponent, selector: "dx-chart", inputs: ["adaptiveLayout", "adjustOnZoom", "animation", "annotations", "argumentAxis", "autoHidePointMarkers", "barGroupPadding", "barGroupWidth", "commonAnnotationSettings", "commonAxisSettings", "commonPaneSettings", "commonSeriesSettings", "containerBackgroundColor", "crosshair", "customizeAnnotation", "customizeLabel", "customizePoint", "dataPrepareSettings", "dataSource", "defaultPane", "disabled", "elementAttr", "export", "legend", "loadingIndicator", "margin", "maxBubbleSize", "minBubbleSize", "negativesAsZeroes", "palette", "paletteExtensionMode", "panes", "pathModified", "pointSelectionMode", "redrawOnResize", "resizePanesOnZoom", "resolveLabelOverlapping", "rotated", "rtlEnabled", "scrollBar", "series", "seriesSelectionMode", "seriesTemplate", "size", "stickyHovering", "synchronizeMultiAxes", "theme", "title", "tooltip", "valueAxis", "zoomAndPan"], outputs: ["onArgumentAxisClick", "onDisposing", "onDone", "onDrawn", "onExported", "onExporting", "onFileSaving", "onIncidentOccurred", "onInitialized", "onLegendClick", "onOptionChanged", "onPointClick", "onPointHoverChanged", "onPointSelectionChanged", "onSeriesClick", "onSeriesHoverChanged", "onSeriesSelectionChanged", "onTooltipHidden", "onTooltipShown", "onZoomEnd", "onZoomStart", "adaptiveLayoutChange", "adjustOnZoomChange", "animationChange", "annotationsChange", "argumentAxisChange", "autoHidePointMarkersChange", "barGroupPaddingChange", "barGroupWidthChange", "commonAnnotationSettingsChange", "commonAxisSettingsChange", "commonPaneSettingsChange", "commonSeriesSettingsChange", "containerBackgroundColorChange", "crosshairChange", "customizeAnnotationChange", "customizeLabelChange", "customizePointChange", "dataPrepareSettingsChange", "dataSourceChange", "defaultPaneChange", "disabledChange", "elementAttrChange", "exportChange", "legendChange", "loadingIndicatorChange", "marginChange", "maxBubbleSizeChange", "minBubbleSizeChange", "negativesAsZeroesChange", "paletteChange", "paletteExtensionModeChange", "panesChange", "pathModifiedChange", "pointSelectionModeChange", "redrawOnResizeChange", "resizePanesOnZoomChange", "resolveLabelOverlappingChange", "rotatedChange", "rtlEnabledChange", "scrollBarChange", "seriesChange", "seriesSelectionModeChange", "seriesTemplateChange", "sizeChange", "stickyHoveringChange", "synchronizeMultiAxesChange", "themeChange", "titleChange", "tooltipChange", "valueAxisChange", "zoomAndPanChange"] }, { kind: "component", type: i6.DxoArgumentAxisComponent, selector: "dxo-argument-axis", inputs: ["aggregateByCategory", "aggregatedPointsPosition", "aggregationGroupWidth", "aggregationInterval", "allowDecimals", "argumentType", "axisDivisionFactor", "breaks", "breakStyle", "categories", "color", "constantLines", "constantLineStyle", "customPosition", "customPositionAxis", "discreteAxisDivisionMode", "endOnTick", "grid", "holidays", "hoverMode", "inverted", "label", "linearThreshold", "logarithmBase", "maxValueMargin", "minorGrid", "minorTick", "minorTickCount", "minorTickInterval", "minValueMargin", "minVisualRangeLength", "offset", "opacity", "placeholderSize", "position", "singleWorkdays", "strips", "stripStyle", "tick", "tickInterval", "title", "type", "valueMarginsEnabled", "visible", "visualRange", "visualRangeUpdateMode", "wholeRange", "width", "workdaysOnly", "workWeek", "firstPointOnStartAngle", "originValue", "period", "startAngle"], outputs: ["visualRangeChange"] }, { kind: "component", type: i6.DxoCommonSeriesSettingsComponent, selector: "dxo-common-series-settings", inputs: ["aggregation", "area", "argumentField", "axis", "bar", "barOverlapGroup", "barPadding", "barWidth", "border", "bubble", "candlestick", "closeValueField", "color", "cornerRadius", "dashStyle", "fullstackedarea", "fullstackedbar", "fullstackedline", "fullstackedspline", "fullstackedsplinearea", "highValueField", "hoverMode", "hoverStyle", "ignoreEmptyPoints", "innerColor", "label", "line", "lowValueField", "maxLabelCount", "minBarSize", "opacity", "openValueField", "pane", "point", "rangearea", "rangebar", "rangeValue1Field", "rangeValue2Field", "reduction", "scatter", "selectionMode", "selectionStyle", "showInLegend", "sizeField", "spline", "splinearea", "stack", "stackedarea", "stackedbar", "stackedline", "stackedspline", "stackedsplinearea", "steparea", "stepline", "stock", "tagField", "type", "valueErrorBar", "valueField", "visible", "width", "argumentType", "minSegmentSize", "smallValuesGrouping", "closed"] }, { kind: "component", type: i6.DxoConnectorComponent, selector: "dxo-connector", inputs: ["color", "visible", "width", "opacity"] }, { kind: "component", type: i6.DxiSeriesComponent, selector: "dxi-series", inputs: ["aggregation", "argumentField", "axis", "barOverlapGroup", "barPadding", "barWidth", "border", "closeValueField", "color", "cornerRadius", "dashStyle", "highValueField", "hoverMode", "hoverStyle", "ignoreEmptyPoints", "innerColor", "label", "lowValueField", "maxLabelCount", "minBarSize", "name", "opacity", "openValueField", "pane", "point", "rangeValue1Field", "rangeValue2Field", "reduction", "selectionMode", "selectionStyle", "showInLegend", "sizeField", "stack", "tag", "tagField", "type", "valueErrorBar", "valueField", "visible", "width", "argumentType", "minSegmentSize", "smallValuesGrouping", "closed"] }, { kind: "component", type: i6.DxiValueAxisComponent, selector: "dxi-value-axis", inputs: ["aggregatedPointsPosition", "allowDecimals", "autoBreaksEnabled", "axisDivisionFactor", "breaks", "breakStyle", "categories", "color", "constantLines", "constantLineStyle", "customPosition", "discreteAxisDivisionMode", "endOnTick", "grid", "inverted", "label", "linearThreshold", "logarithmBase", "maxAutoBreakCount", "maxValueMargin", "minorGrid", "minorTick", "minorTickCount", "minorTickInterval", "minValueMargin", "minVisualRangeLength", "multipleAxesSpacing", "name", "offset", "opacity", "pane", "placeholderSize", "position", "showZero", "strips", "stripStyle", "synchronizedValue", "tick", "tickInterval", "title", "type", "valueMarginsEnabled", "valueType", "visible", "visualRange", "visualRangeUpdateMode", "wholeRange", "width"], outputs: ["visualRangeChange"] }, { kind: "component", type: i8.DxFunnelComponent, selector: "dx-funnel", inputs: ["adaptiveLayout", "algorithm", "argumentField", "colorField", "dataSource", "disabled", "elementAttr", "export", "hoverEnabled", "inverted", "item", "label", "legend", "loadingIndicator", "margin", "neckHeight", "neckWidth", "palette", "paletteExtensionMode", "pathModified", "redrawOnResize", "resolveLabelOverlapping", "rtlEnabled", "selectionMode", "size", "sortData", "theme", "title", "tooltip", "valueField"], outputs: ["onDisposing", "onDrawn", "onExported", "onExporting", "onFileSaving", "onHoverChanged", "onIncidentOccurred", "onInitialized", "onItemClick", "onLegendClick", "onOptionChanged", "onSelectionChanged", "adaptiveLayoutChange", "algorithmChange", "argumentFieldChange", "colorFieldChange", "dataSourceChange", "disabledChange", "elementAttrChange", "exportChange", "hoverEnabledChange", "invertedChange", "itemChange", "labelChange", "legendChange", "loadingIndicatorChange", "marginChange", "neckHeightChange", "neckWidthChange", "paletteChange", "paletteExtensionModeChange", "pathModifiedChange", "redrawOnResizeChange", "resolveLabelOverlappingChange", "rtlEnabledChange", "selectionModeChange", "sizeChange", "sortDataChange", "themeChange", "titleChange", "tooltipChange", "valueFieldChange"] }, { kind: "component", type: i6.DxoItemComponent, selector: "dxo-item", inputs: ["border", "hoverStyle", "selectionStyle"] }, { kind: "component", type: i9.DxPieChartComponent, selector: "dx-pie-chart", inputs: ["adaptiveLayout", "animation", "annotations", "centerTemplate", "commonAnnotationSettings", "commonSeriesSettings", "customizeAnnotation", "customizeLabel", "customizePoint", "dataSource", "diameter", "disabled", "elementAttr", "export", "innerRadius", "legend", "loadingIndicator", "margin", "minDiameter", "palette", "paletteExtensionMode", "pathModified", "pointSelectionMode", "redrawOnResize", "resolveLabelOverlapping", "rtlEnabled", "segmentsDirection", "series", "seriesTemplate", "size", "sizeGroup", "startAngle", "theme", "title", "tooltip", "type"], outputs: ["onDisposing", "onDone", "onDrawn", "onExported", "onExporting", "onFileSaving", "onIncidentOccurred", "onInitialized", "onLegendClick", "onOptionChanged", "onPointClick", "onPointHoverChanged", "onPointSelectionChanged", "onTooltipHidden", "onTooltipShown", "adaptiveLayoutChange", "animationChange", "annotationsChange", "centerTemplateChange", "commonAnnotationSettingsChange", "commonSeriesSettingsChange", "customizeAnnotationChange", "customizeLabelChange", "customizePointChange", "dataSourceChange", "diameterChange", "disabledChange", "elementAttrChange", "exportChange", "innerRadiusChange", "legendChange", "loadingIndicatorChange", "marginChange", "minDiameterChange", "paletteChange", "paletteExtensionModeChange", "pathModifiedChange", "pointSelectionModeChange", "redrawOnResizeChange", "resolveLabelOverlappingChange", "rtlEnabledChange", "segmentsDirectionChange", "seriesChange", "seriesTemplateChange", "sizeChange", "sizeGroupChange", "startAngleChange", "themeChange", "titleChange", "tooltipChange", "typeChange"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i11.AppTitleComponent, selector: "app-title", inputs: ["title", "multiple", "isFilterDisplay", "icon", "iconName", "displayType", "keyToPass", "fixOperationLevles", "operators"], outputs: ["onOperatorClick"] }, { kind: "component", type: i12.LoaderComponent, selector: "app-loader" }] });
|
|
351
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: GammaAdvanceChartComponent, decorators: [{
|
|
352
|
-
type: Component,
|
|
353
|
-
args: [{ selector: 'app-gamma-advance-chart', template: "<div class=\"not-full-screen\" (dblclick)=\"toggleFullScreen()\">\n <ng-container *ngIf=\"page_config?.widGetConfig?.display\">\n <app-title [title]=\"page_config.widGetConfig.widgetTitle\" [operators]=\"page_config.operations\"\n [displayType]=\"'chart'\"></app-title>\n </ng-container>\n <div class=\"mx-2 p-2 bg-gray-800\">\n <app-loader *ngIf=\"isLoader\"></app-loader>\n \n <ng-container *ngIf=\"chartConfig.chartType !== 'doughnut' && chartConfig.chartType !== 'funnel' && chartConfig.chartType !== 'pie'\" >\n <dx-chart id=\"chart\" [dataSource]=\"finalChartDataSource\"\n [title]=\"{ text: chartConfig.caption, font: { size: 14 } }\" *ngIf=\"!isLoader\"\n [valueAxis]=\"chartConfig.valueAxisConfig\">\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item && item.axis\">\n <dxi-value-axis name=\"{{item.axis}}\" position=\"{{item.position}}\">\n <dxo-title text=\"{{item.name}}\"></dxo-title>\n </dxi-value-axis>\n </ng-container>\n\n </ng-container>\n <dxo-argument-axis>\n <dxo-label overlappingBehavior=\"rotate\" [rotationAngle]=\"270\"></dxo-label>\n </dxo-argument-axis>\n <dxo-tooltip [enabled]=\"true\" [shared]=\"true\" [customizeTooltip]=\"customizeTooltip\">\n </dxo-tooltip>\n <dxo-common-series-settings argumentField=\"{{chartConfig.argumentField}}\">\n </dxo-common-series-settings>\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item && item.color\">\n <dxi-series type=\"{{item.type}}\" valueField=\"{{item.valueField}}\" axis=\"{{item.axis}}\"\n name=\"{{item.name}}\" color=\"{{item.color}}\">\n </dxi-series>\n </ng-container>\n <ng-container *ngIf=\"item && !item.color\">\n <dxi-series type=\"{{item.type}}\" valueField=\"{{item.valueField}}\" axis=\"{{item.axis}}\"\n name=\"{{item.name}}\">\n </dxi-series>\n </ng-container>\n\n </ng-container>\n <dxo-size [height]=\"chartHeight\">\n </dxo-size>\n <dxo-legend [visible]=\"chartConfig.legendDisplay\" verticalAlignment=\"{{chartConfig.verticalAlignment}}\"\n horizontalAlignment=\"{{chartConfig.horizontalAlignment}}\">\n </dxo-legend>\n </dx-chart>\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'doughnut' || chartConfig.chartType == 'pie'\">\n\n <dx-pie-chart id=\"pie\" [type]=\"chartConfig.chartType\" [title]=\"{ text: chartConfig.caption, font: { size: 14 } }\"\n palette=\"Soft Pastel\" [dataSource]=\"finalChartDataSource\" centerTemplate=\"centerTemplate\"\n (onPointClick)=\"pointClickHandler($event)\" [palette]=\"chartConfig.palette\">\n\n <ng-container *ngFor=\"let item of chartConfig.chart_config\">\n <ng-container *ngIf=\"item.color\">\n <dxi-series argumentField={{chartConfig.argumentField}} valueField=\"{{item.valueField}}\"\n name=\"{{item.name}}\" color=\"{{item.color}}\">\n <dxo-label [visible]=\"chartConfig.labelDisplay\" format=\"currency\">\n <dxo-connector [visible]=\"true\"></dxo-connector>\n </dxo-label>\n </dxi-series>\n </ng-container>\n <ng-container *ngIf=\"!item.color\">\n <dxi-series argumentField={{chartConfig.argumentField}} valueField=\"{{item.valueField}}\"\n name=\"{{item.name}}\">\n <dxo-label [visible]=\"chartConfig.labelDisplay\" format=\"currency\">\n <dxo-connector [visible]=\"true\"></dxo-connector>\n </dxo-label>\n </dxi-series>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n <dxo-legend [visible]=\"chartConfig.legendDisplay\"\n horizontalAlignment=\"{{chartConfig.horizontalAlignment}}\"\n verticalAlignment=\"{{chartConfig.verticalAlignment}}\"></dxo-legend>\n <!-- <dxo-export [enabled]=\"true\"></dxo-export> -->\n <dxo-tooltip [enabled]=\"true\" [customizeTooltip]=\"customizeTooltip\" format=\"currency\">\n </dxo-tooltip>\n <ng-container *ngIf=\"chartConfig.chartType == 'doughnut'\">\n <svg *dxTemplate=\"let pieChart of 'centerTemplate'\">\n <circle cx=\"100\" cy=\"100\" [attr.r]=\"pieChart.getInnerRadius() - 6\" fill=\"gray\" opacity=\"0.0001\">\n </circle>\n \n <text text-anchor=\"middle\" style=\"font-size: 15px\" x=\"100\" y=\"100\" fill=\"#eee\">\n <tspan x=\"100\">{{ calculateTotal(pieChart) }}</tspan>\n <!-- display: inline -->\n <!-- <tspan x=\"100\" dy=\"20px\" style=\"font-weight: 600\"></tspan> -->\n </text>\n </svg>\n </ng-container>\n \n </dx-pie-chart>\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'funnel'\">\n <dx-funnel id=\"funnel\" [dataSource]=\"finalChartDataSource\" argumentField=\"argument\" valueField=\"value\"\n palette=\"Soft Pastel\">\n <ng-container *ngIf=\"chartConfig.size\">\n <dxo-size [height]=\"chartConfig.size\">\n </dxo-size>\n </ng-container>\n <dxo-export [enabled]=\"false\"></dxo-export>\n <dxo-tooltip [enabled]=\"true\"> </dxo-tooltip>\n <dxo-item>\n <dxo-border [visible]=\"true\"> </dxo-border>\n </dxo-item>\n <dxo-label [visible]=\"true\" position=\"inside\" backgroundColor=\"none\"\n [customizeText]=\"customizeText\"></dxo-label>\n </dx-funnel>\n\n </ng-container>\n\n <ng-container *ngIf=\"chartConfig.chartType == 'bubble'\">\n <div class=\"mx-5 overflow-x-auto\">\n <ng-container *ngFor=\"let item of heatChartDataSource.dataSet\">\n <div class=\"flex flex-row\">\n <div class=\"h-10 text-sm items-center min-w-12 max-w-[30%] justify-center flex\">\n {{item.datasource}}\n </div>\n <div class=\"inline-block \">\n <div class=\"flex flex-nowrap justify-center \">\n <ng-container *ngFor=\"let box of item.dataset\">\n <div class=\"flex-shrink-0 min-w-10 max-w-[20%] h-10 text-sm cursor-pointer flex items-center justify-center text-gray-800\"\n [matTooltip]=\"'Record Date: ' + box.recordDate + '\\nRecharge Count: ' + box.toolTip\"\n matTooltipClass=\"custom-tooltip\">\n <div class=\"rounded-full\" [ngStyle]=\"{\n 'background-color': box.isHovered ? 'rgb(135, 184, 106)' : box.color,\n 'width.px': box.size,\n 'hover': box.hover,\n 'height.px': box.size\n }\" (mouseenter)=\"box.isHovered = true\"\n (mouseleave)=\"box.isHovered = false\">\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"inline-block\">\n <div class=\"flex flex-nowrap justify-center\">\n <div class=\"flex-shrink-0 w-12 max-w-[20%] h-full flex items-center justify-center\"></div>\n <div *ngFor=\"let item of heatChartDataSource.argumentValue\"\n class=\"flex-shrink-0 w-10 max-w-[20%] min-h-14 flex text-sm items-center justify-center my-1\"\n [ngStyle]=\"{'height': 'auto'}\">\n <span class=\"text-rotate\">\n {{item}}\n </span>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <button *ngIf=\"isFullScreen\" class=\"close-button\" (click)=\"toggleFullScreen()\">Close</button>\n</div>" }]
|
|
354
|
-
}], ctorParameters: function () { return [{ type: i1.CommonService }, { type: i2.ToastrService }, { type: i3.kpicommonService }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { componentId: [{
|
|
355
|
-
type: Input
|
|
356
|
-
}], kpi_name: [{
|
|
357
|
-
type: Input
|
|
358
|
-
}], chartDataSource: [{
|
|
359
|
-
type: Input,
|
|
360
|
-
args: ['chartDataSource']
|
|
361
|
-
}] } });
|
|
362
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FtbWEtYWR2YW5jZS1jaGFydC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9nYW1tYS1hcHAtY29udHJvbGxlci9zcmMvbGliL2FwcGxpY2F0aW9uLWNvbnRyb2xsZXIvc2hhcmVkL2FkdmFuY2VkLWNvbXBvbmVudC9nYW1tYS1hZHZhbmNlLWNoYXJ0L2dhbW1hLWFkdmFuY2UtY2hhcnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2FtbWEtYXBwLWNvbnRyb2xsZXIvc3JjL2xpYi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL3NoYXJlZC9hZHZhbmNlZC1jb21wb25lbnQvZ2FtbWEtYWR2YW5jZS1jaGFydC9nYW1tYS1hZHZhbmNlLWNoYXJ0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBb0MsU0FBUyxFQUFjLEtBQUssRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDbEgsT0FBTyxNQUFNLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7Ozs7Ozs7O0FBVTlDLE1BQU0sT0FBTywwQkFBMEI7SUFvQnJDLFlBQ1UsYUFBNEIsRUFDNUIsTUFBcUIsRUFDckIsVUFBNEIsRUFDNUIsUUFBbUIsRUFBVSxFQUFjLEVBQzNDLEdBQXNCO1FBSnRCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLFdBQU0sR0FBTixNQUFNLENBQWU7UUFDckIsZUFBVSxHQUFWLFVBQVUsQ0FBa0I7UUFDNUIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUFVLE9BQUUsR0FBRixFQUFFLENBQVk7UUFDM0MsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUF4QmhDLGdCQUFXLEdBQVEsRUFBRSxDQUFDO1FBQ3RCLGdCQUFXLEdBQVEsRUFBRSxDQUFDO1FBQ3RCLGFBQVEsR0FBWSxJQUFJLENBQUM7UUFPekIseUJBQW9CLEdBQUcsU0FBUyxD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QUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDM0QsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztZQUN2QyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLFNBQVMsRUFBRTtnQkFDMUQsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQzthQUMzQztpQkFBTTtnQkFDTCxJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO2FBQzNDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNO1FBQzFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLE1BQU0sQ0FBQztJQUMxRSxDQUFDOzt1SEExWlUsMEJBQTBCOzJHQUExQiwwQkFBMEIsaUtDWnZDLDRsVEFxS007MkZEekpPLDBCQUEwQjtrQkFMdEMsU0FBUzsrQkFDRSx5QkFBeUI7Z1BBUTFCLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkEyQkYsZUFBZTtzQkFEbEIsS0FBSzt1QkFBQyxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCB7IEFmdGVyVmlld0luaXQsIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIElucHV0LCBPbkluaXQsIFJlbmRlcmVyMiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IG1vbWVudCBmcm9tICcuLy4uLy4uLy4uL21vbWVudC1oZWxwZXInO1xuaW1wb3J0IHsgVG9hc3RyU2VydmljZSB9IGZyb20gJ25neC10b2FzdHInO1xuaW1wb3J0IHsga3BpY29tbW9uU2VydmljZSB9IGZyb20gJy4uLy4uL2twaS1jb21vbi1zZXJ2aWNlJztcbmltcG9ydCB7IENvbW1vblNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9jb21tb24nO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtZ2FtbWEtYWR2YW5jZS1jaGFydCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9nYW1tYS1hZHZhbmNlLWNoYXJ0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZ2FtbWEtYWR2YW5jZS1jaGFydC5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIEdhbW1hQWR2YW5jZUNoYXJ0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgY2hhcnRDb25maWc6IGFueSA9IHt9O1xuICBwYWdlX2NvbmZpZzogYW55ID0ge307XG4gIGlzTG9hZGVyOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgY29tcG9uZW50SWQ6IGFueTtcbiAgLy8gQElucHV0KCkgY2FwdGlvbjogYW55O1xuICBASW5wdXQoKSBrcGlfbmFtZTogYW55O1xuICAvLyBASW5wdXQoKSBjaGFydERhdGFTb3VyY2U6YW55O1xuICBjYXB0aW9uOiBhbnk7XG4gIGlzQ2hhcnR2aXNpYmxlOiBib29sZWFuO1xuICBjcmVhdENoYXJ0RGF0YVNvdXJjZSA9IHVuZGVmaW5lZDtcbiAgZmluYWxDaGFydERhdGFTb3VyY2U6IGFueSA9IFtdO1xuICBjaGFydEhlaWdodDogYW55O1xuXG4gIGlzRnVsbFNjcmVlbjogYm9vbGVhbiA9IGZhbHNlO1xuXG5cbiAgaGVhdENoYXJ0RGF0YVNvdXJjZTogYW55O1xuICBidWJibGVDaGFydERhdGE6IGFueTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNvbW1vblNlcnZpY2U6IENvbW1vblNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0b2FzdHI6IFRvYXN0clNlcnZpY2UsXG4gICAgcHJpdmF0ZSBrcGlTZXJ2aWNlOiBrcGljb21tb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMiwgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7XG5cbiAgfVxuXG4gIC8vIGNoYXJ0X2F0dHIubGVnZW5kWzBdXG5cbiAgQElucHV0KCdjaGFydERhdGFTb3VyY2UnKVxuICBzZXQgY2hhcnREYXRhU291cmNlKHZhbHVlKSB7XG4gICAgdGhpcy5jcmVhdENoYXJ0RGF0YVNvdXJjZSA9IHZhbHVlO1xuICAgIC8vIGNvbnNvbGUubG9nKHZhbHVlKTtcbiAgICBpZiAodGhpcy5jcmVhdENoYXJ0RGF0YVNvdXJjZSA9PT0gdW5kZWZpbmVkIHx8IHRoaXMuY3JlYXRDaGFydERhdGFTb3VyY2UubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmlzQ2hhcnR2aXNpYmxlID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXNMb2FkZXIgPSB0cnVlO1xuICAgICAgdGhpcy5wYWdlX2NvbmZpZyA9IHZhbHVlO1xuXG4gICAgICBpZiAodmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2UgJiYgdmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2UubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIHRoaXMuY2hhcnRDb25maWcgPSB2YWx1ZS5rcGlDb25maWcuZGF0YUNvbmZpZztcbiAgICAgICAgaWYgKHZhbHVlLmtwaUNvbmZpZy5mb3JtYXRlID09IFwiZGFpbHlcIikge1xuXG4gICAgICAgICAgY29uc3Qgc29ydGVkRGF0YSA9IHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlXG4gICAgICAgICAgICAuZmlsdGVyKHJlY29yZCA9PiByZWNvcmQucmVjb3JkRGF0ZSlcbiAgICAgICAgICAgIC5zb3J0KChhLCBiKSA9PiBtb21lbnQoYi5yZWNvcmREYXRlKS5kaWZmKG1vbWVudChhLnJlY29yZERhdGUpKSk7XG5cbiAgICAgICAgICBjb25zdCBtb3N0UmVjZW50UmVjb3JkID0gc29ydGVkRGF0YVswXTtcbiAgICAgICAgICBjb25zdCBmaWx0ZXJlZE9iamVjdHMgPSBzb3J0ZWREYXRhLmZpbHRlcihkYXRhID0+IGRhdGEucmVjb3JkRGF0ZSA9PT0gdmFsdWUuZW5kRGF0ZSk7XG5cblxuICAgICAgICAgIGlmICh0aGlzLmNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSA9PSAnZnVubmVsJykge1xuXG4gICAgICAgICAgICBpZiAoZmlsdGVyZWRPYmplY3RzICYmIGZpbHRlcmVkT2JqZWN0cy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgICAgdGhpcy5maW5hbENoYXJ0RGF0YVNvdXJjZSA9IE9iamVjdC5rZXlzKGZpbHRlcmVkT2JqZWN0c1swXSkuZmlsdGVyKGtleSA9PiBrZXkgIT09ICdyZWNvcmREYXRlJykubWFwKGtleSA9PiAoe1xuICAgICAgICAgICAgICAgIGFyZ3VtZW50OiBrZXksXG4gICAgICAgICAgICAgICAgdmFsdWU6IE1hdGguYWJzKHBhcnNlSW50KGZpbHRlcmVkT2JqZWN0c1swXVtrZXldKSlcbiAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5maW5hbENoYXJ0RGF0YVNvdXJjZSA9IFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLmZpbmFsQ2hhcnREYXRhU291cmNlKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmdldERhaWx5Q2hhcnQoZmlsdGVyZWRPYmplY3RzLCB2YWx1ZS5rcGlDb25maWcuZGF0YUNvbmZpZyk7XG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmlzTG9hZGVyID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUua3BpQ29uZmlnLmZvcm1hdGUgPT0gXCJtb250aGx5XCIpIHtcblxuICAgICAgICAgIGlmICh0aGlzLmNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSA9PSAnYnViYmxlJykge1xuICAgICAgICAgICAgdGhpcy5idWJibGVDaGFydERhdGEgPSB2YWx1ZS5rcGlDb25maWcuZGF0YVNvdXJjZTtcbiAgICAgICAgICAgIHRoaXMuZ2V0QnViYmxlQ2hhcnREYXRhKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlID0gdmFsdWUua3BpQ29uZmlnLmRhdGFTb3VyY2VcbiAgICAgICAgICAgIC8vICAgLmZpbHRlcihyZWNvcmQgPT4gcmVjb3JkW3ZhbHVlLmtwaUNvbmZpZy5kYXRhQ29uZmlnWydhcmd1bWVudEZpZWxkJ11dKVxuICAgICAgICAgICAgLy8gICAuc29ydCgoYSwgYikgPT4gbW9tZW50KGFbdmFsdWUua3BpQ29uZmlnLmRhdGFDb25maWdbJ2FyZ3VtZW50RmllbGQnXV0pLmRpZmYobW9tZW50KGJbdmFsdWUua3BpQ29uZmlnLmRhdGFDb25maWdbJ2FyZ3VtZW50RmllbGQnXV0pKSk7XG5cbiAgICAgICAgICAgIHRoaXMuZ2V0TW9udGhseUNoYXJ0KHZhbHVlLmtwaUNvbmZpZy5kYXRhU291cmNlLCB2YWx1ZS5rcGlDb25maWcuZGF0YUNvbmZpZylcbiAgICAgICAgICAgIHRoaXMuaXNDaGFydHZpc2libGUgPT0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5pc0xvYWRlciA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuXG4gICAgICAgICAgdGhpcy5pc0xvYWRlciA9IGZhbHNlO1xuICAgICAgICB9LCAyMDApO1xuICAgICAgfVxuICAgIH1cblxuXG5cbiAgfVxuXG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG5cbiAgfVxuXG4gIGdldEhvdXJDaGFydChkYXRhLCBkYXRhQ29uZmlnKSB7XG4gICAgLy8gY29uc3QgdmFsdWVGaWVsZHMgPSBkYXRhQ29uZmlnLmNoYXJ0X2NvbmZpZy5tYXAoY29uZmlnID0+IGNvbmZpZy52YWx1ZUZpZWxkKTtcbiAgICBpZiAoZGF0YSkge1xuICAgICAgZGF0YS5mb3JFYWNoKHZhbCA9PiB7XG4gICAgICAgIGlmICh2YWxbZGF0YUNvbmZpZy5hcmd1bWVudEZpZWxkXS50b1N0cmluZygpLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgICAgdmFsW2RhdGFDb25maWcuYXJndW1lbnRGaWVsZF0gPSAnMCcgKyB2YWxbZGF0YUNvbmZpZy5hcmd1bWVudEZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbGFiZWwgPSB2YWxbZGF0YUNvbmZpZy5hcmd1bWVudEZpZWxkXS50b1N0cmluZygpO1xuICAgICAgICB2YWxbZGF0YUNvbmZpZy5hcmd1bWVudEZpZWxkXSA9IGxhYmVsXG4gICAgICB9KTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmZpbmFsQ2hhcnREYXRhU291cmNlID0gZGF0YTtcbiAgICAgIH0sIDUwMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudG9hc3RyLmVycm9yKHRoaXMua3BpX25hbWUgKyAnQ2hhcnQgRXJyb3InKTtcblxuICAgIH1cbiAgfVxuICBnZXRNb250aGx5Q2hhcnQoZGF0YSwgZGF0YUNvbmZpZykge1xuICAgICAgY29uc3QgdmFsdWVGaWVsZHMgPSBkYXRhQ29uZmlnLmNoYXJ0X2NvbmZpZy5tYXAoY29uZmlnID0+IGNvbmZpZy52YWx1ZUZpZWxkKTtcbiAgICAgICBkYXRhLmZvckVhY2goKGVudHJ5OmFueSkgPT4ge1xuICAgICAgICAgIHZhbHVlRmllbGRzLmZvckVhY2goKGZpZWxkOmFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKGVudHJ5Lmhhc093blByb3BlcnR5KGZpZWxkKSkge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIGVudHJ5W2ZpZWxkXSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIGVudHJ5W2ZpZWxkXSA9IE51bWJlcihlbnRyeVtmaWVsZF0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICBsZXQgY29udGVudCA9IHRoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoJ2RhdGUnKSkge1xuICAgICAgICAgICBjb25zdCBkYXRhU291cmNlID0gZGF0YS5tYXAob2JqID0+IHtcbiAgICAgICAgICAgICBjb25zdCBuZXdPYmogPSB7IC4uLm9iaiB9O1xuICAgICAgICAgICAgIGlmIChuZXdPYmouaGFzT3duUHJvcGVydHkodGhpcy5jaGFydENvbmZpZy5hcmd1bWVudEZpZWxkKSkge1xuICAgICAgICAgICAgICAgbmV3T2JqW3RoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZF0gPSBtb21lbnQobmV3T2JqW3RoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZF0pLmZvcm1hdChcIk1NLUREXCIpO1xuICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICByZXR1cm4gbmV3T2JqO1xuICAgICAgICAgICB9KTtcbiAgICAgICAgICAgdGhpcy5maW5hbENoYXJ0RGF0YVNvdXJjZSA9IGRhdGFTb3VyY2U7XG4gICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICB0aGlzLmZpbmFsQ2hhcnREYXRhU291cmNlID0gZGF0YTtcbiAgICAgICAgIH1cbiAgICAgICB9IGVsc2Uge1xuICAgICAgICAgdGhpcy50b2FzdHIuZXJyb3IodGhpcy5rcGlfbmFtZSArICdDaGFydCBFcnJvcicpO1xuICAgICAgIH1cbiAgfVxuXG4gIFxuICBnZXREYWlseUNoYXJ0KGRhdGEsIGRhdGFDb25maWcpIHtcbiAgICBjb25zdCB2YWx1ZUZpZWxkcyA9IGRhdGFDb25maWcuY2hhcnRfY29uZmlnLm1hcChjb25maWcgPT4gY29uZmlnLnZhbHVlRmllbGQpO1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBsZXQgY29udGVudCA9IHRoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZC50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoJ2RhdGUnKSkge1xuICAgICAgICBjb25zdCBkYXRhU291cmNlID0gZGF0YS5tYXAob2JqID0+IHtcbiAgICAgICAgICBjb25zdCBuZXdPYmogPSB7IC4uLm9iaiB9O1xuICAgICAgICAgIE9iamVjdC5rZXlzKG5ld09iaikuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgaWYgKGtleSAhPT0gdGhpcy5jaGFydENvbmZpZy5hcmd1bWVudEZpZWxkICYmICFpc05hTihuZXdPYmpba2V5XSkpIHtcbiAgICAgICAgICAgICAgbmV3T2JqW2tleV0gPSBOdW1iZXIobmV3T2JqW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChuZXdPYmouaGFzT3duUHJvcGVydHkodGhpcy5jaGFydENvbmZpZy5hcmd1bWVudEZpZWxkKSkge1xuICAgICAgICAgICAgbmV3T2JqW3RoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZF0gPSBtb21lbnQobmV3T2JqW3RoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZF0pLmZvcm1hdChcIk1NLUREXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbmV3T2JqO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5maW5hbENoYXJ0RGF0YVNvdXJjZSA9IGRhdGFTb3VyY2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmZpbmFsQ2hhcnREYXRhU291cmNlID0gZGF0YTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50b2FzdHIuZXJyb3IodGhpcy5rcGlfbmFtZSArICcgQ2hhcnQgRXJyb3InKTtcbiAgICB9XG4gIH1cblxuXG5cbiAgZ2V0UmVjb25EYWlseUNoYXJ0KGRhdGEsIGRhdGFDb25maWcpIHtcblxuICAgIHRoaXMuZmluYWxDaGFydERhdGFTb3VyY2UgPSBbXTtcbiAgICBjb25zdCByZWNvbl9rZXkgPSBkYXRhQ29uZmlnLnJlY29uS2V5O1xuICAgIGNvbnN0IHJlY29uX2NvbHVtbiA9IGRhdGFDb25maWcucmVjb25Db2x1bW5zO1xuICAgIHRoaXMuZmluYWxDaGFydERhdGFTb3VyY2UgPSB0aGlzLmdldEZpbmFsRGF0YShkYXRhLCByZWNvbl9jb2x1bW4pO1xuXG4gIH1cblxuICBnZXRGaW5hbERhdGEobWFpbkRhdGE6IGFueVtdLCByZWNvbkNvbHVtbjogYW55W10pOiBhbnlbXSB7XG4gICAgbWFpbkRhdGEuZm9yRWFjaChkYXRhID0+IHtcbiAgICAgIHJlY29uQ29sdW1uLmZvckVhY2goY29sdW1uID0+IHtcbiAgICAgICAgY29uc3QgZmlyc3RLZXlWYWx1ZSA9IGRhdGFbY29sdW1uLmZpcnN0S2V5XTtcbiAgICAgICAgY29uc3Qgc2Vjb25kS2V5VmFsdWUgPSBkYXRhW2NvbHVtbi5zZWNvbmRLZXldO1xuICAgICAgICBjb25zdCBtb3VEaWZmID0gTWF0aC5hYnMoZmlyc3RLZXlWYWx1ZSAtIHNlY29uZEtleVZhbHVlKTtcbiAgICAgICAgZGF0YVtjb2x1bW4uZmluYWxLZXldID0gbW91RGlmZjtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG1haW5EYXRhO1xuICB9XG5cbiAgY3VzdG9taXplVG9vbHRpcCA9IChpbmZvOiBhbnkpID0+IChcbiAgICB7XG5cbiAgICAgIGh0bWw6IGA8dGFibGUgd2lkdGg9MTAwJSBoZWlnaHQ9MzAgYm9yZGVyPTAgIHN0eWxlPVxcJ2ZvbnQtc2l6ZTogMTNweFxcJz5cbiAgICA8dHI+PHRkIHN0eWxlPVxcJ3RleHQtYWxpZ246IGxlZnQ7IGNvbG9yOiB3aGl0ZVxcJz4gJHt0aGlzLmNvbW1vblNlcnZpY2UuY29udmVydFRvVGl0bGVDYXNlKHRoaXMuY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZCl9IDogICR7aW5mby5hcmd1bWVudFRleHR9IDwvdGQ+PC90cj5cbiAgICA8dHI+PHRkIHN0eWxlPVxcJ3RleHQtYWxpZ246IGxlZnQ7IGNvbG9yOiB3aGl0ZTsgcGFkZGluZy10b3A6IDVweFxcJz4gJHtpbmZvLnNlcmllc05hbWV9IDpcbiAgICAke3RoaXMuZ2V0VmFsdWUoaW5mby5zZXJpZXNOYW1lLCBpbmZvLnZhbHVlKX0gIDwvdGQ+PC90cj5cbiAgICA8L3RhYmxlPmAsXG4gICAgfSk7XG5cbiAgLy8gY3VzdG9taXplVG9vbHRpcChhcmcpIHtcbiAgLy8gICByZXR1cm4geyB0ZXh0OiBgJHthcmcuYXJndW1lbnRUZXh0fTxicj4ke2FyZy5zZXJpZXNOYW1lfTogJHthcmcudmFsdWVUZXh0fUJgIH07XG4gIC8vIH1cblxuICBjYWxjdWxhdGVUb3RhbChwaWVDaGFydCkge1xuICAgIGNvbnN0IHRvdGFsVmFsdWUgPSBwaWVDaGFydC5nZXRBbGxTZXJpZXMoKVswXS5nZXRWaXNpYmxlUG9pbnRzKCkucmVkdWNlKChzLCBwKSA9PiBzICsgcC5vcmlnaW5hbFZhbHVlLCAwKTtcbiAgICByZXR1cm4gdGhpcy5mb3JtYXROdW1iZXIodG90YWxWYWx1ZSk7XG4gIH1cblxuICBmb3JtYXROdW1iZXIodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPj0gMWU5KSB7XG4gICAgICByZXR1cm4gKHZhbHVlIC8gMWU5KS50b0ZpeGVkKDIpICsgJ0InO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPj0gMWU2KSB7XG4gICAgICByZXR1cm4gKHZhbHVlIC8gMWU2KS50b0ZpeGVkKDIpICsgJ00nO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPj0gMWUzKSB7XG4gICAgICByZXR1cm4gKHZhbHVlIC8gMWUzKS50b0ZpeGVkKDIpICsgJ0snO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdmFsdWUudG9GaXhlZCgyKTtcbiAgICB9XG4gIH1cblxuICBwb2ludENsaWNrSGFuZGxlcihhcmcpIHtcbiAgICBhcmcudGFyZ2V0LnNlbGVjdCgpO1xuICB9XG5cbiAgZ2V0VmFsdWUoY29udGV4dEtleSwgdmFsdWUpIHtcblxuICAgIGxldCBjb250ZXh0X2RhdGE6IGFueTtcbiAgICBjb25zdCBzbWxfa2V5ID0gY29udGV4dEtleS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgaWYgKHNtbF9rZXkgPT09IFwiY291bnRcIiB8fCBzbWxfa2V5ID09PSBcImhvdXJcIiB8fCBzbWxfa2V5ID09PSBcImRlbm9taW5hdGlvblwiIHx8IHNtbF9rZXkuaW5jbHVkZXMoXCJjb3VudFwiKSkge1xuICAgICAgICBjb250ZXh0X2RhdGEgPSB0aGlzLmNvbW1vblNlcnZpY2UucmVmb3JtYXROdW1iZXJXaXRoVGhvdXNhbmRTZXBhcmF0b3JWMyh2YWx1ZSwgMCk7XG4gICAgICB9IGVsc2UgaWYgKHNtbF9rZXkuaW5jbHVkZXMoJ3ZvbHVtZScpIHx8IHNtbF9rZXkuaW5jbHVkZXMoJ3VwbG9hZCcpIHx8IHNtbF9rZXkuaW5jbHVkZXMoJ2Rvd25sb2FkJykpIHtcbiAgICAgICAgaWYgKHNtbF9rZXkgPT0gJ2JpbGxhYmxldm9sdW1lJykge1xuICAgICAgICAgIGNvbnRleHRfZGF0YSA9IHRoaXMuY29tbW9uU2VydmljZS5mb3JtYXRCeXRzVG9HYih2YWx1ZSAqIDEwMjQsIDIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29udGV4dF9kYXRhID0gdGhpcy5jb21tb25TZXJ2aWNlLmZvcm1hdEJ5dHNUb0diKHZhbHVlICogMTAyNCwgMik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc21sX2tleSA9PSBcInVwbGlua1wiIHx8IHNtbF9rZXkgPT0gXCJkb3dubGlua1wiKSB7XG4gICAgICAgIGNvbnRleHRfZGF0YSA9IHRoaXMuY29tbW9uU2VydmljZS5mb3JtYXRCeXRzVG9HYih2YWx1ZSwgMik7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuaGFzRGVjaW1hbCh2YWx1ZSkpIHtcbiAgICAgICAgY29udGV4dF9kYXRhID0gdGhpcy5jb21tb25TZXJ2aWNlLnJlZm9ybWF0TnVtYmVyV2l0aFRob3VzYW5kU2VwYXJhdG9yVjModmFsdWUsIDIpO1xuICAgICAgfSBlbHNlIGlmICghdGhpcy5oYXNEZWNpbWFsKHZhbHVlKSkge1xuICAgICAgICBjb250ZXh0X2RhdGEgPSB0aGlzLmNvbW1vblNlcnZpY2UucmVmb3JtYXROdW1iZXJXaXRoVGhvdXNhbmRTZXBhcmF0b3JWMyh2YWx1ZSwgMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZXh0X2RhdGEgPSB0aGlzLmNvbW1vblNlcnZpY2UucmVmb3JtYXROdW1iZXJXaXRoVGhvdXNhbmRTZXBhcmF0b3JWMyh2YWx1ZSwgMik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRleHRfZGF0YSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBjb250ZXh0X2RhdGE7XG4gIH1cblxuXG4gIGhhc0RlY2ltYWwobnVtYmVyKSB7XG4gICAgcmV0dXJuIG51bWJlciAlIDEgIT09IDA7XG4gIH1cblxuICB0b2dnbGVGdWxsU2NyZWVuKCkge1xuICAgIHRoaXMuaXNMb2FkZXIgPSB0cnVlO1xuICAgIHRoaXMuaXNGdWxsU2NyZWVuID0gIXRoaXMuaXNGdWxsU2NyZWVuO1xuICAgIGNvbnN0IGRpdiA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcubm90LWZ1bGwtc2NyZWVuJyk7XG4gICAgaWYgKHRoaXMuaXNGdWxsU2NyZWVuKSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKGRpdiwgJ2Z1bGwtc2NyZWVuJyk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5pc0xvYWRlciA9IGZhbHNlO1xuICAgICAgfSwgMTApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKGRpdiwgJ2Z1bGwtc2NyZWVuJyk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5pc0xvYWRlciA9IGZhbHNlO1xuICAgICAgfSwgMTApO1xuICAgIH1cbiAgfVxuXG5cblxuXG5cbiAgY3VzdG9taXplVGV4dCA9ICh7IHBlcmNlbnRUZXh0LCBpdGVtOiB7IGFyZ3VtZW50IH0gfSkgPT4gYDxzcGFuIHN0eWxlPSdmb250LXNpemU6IDI4cHgnPiR7cGVyY2VudFRleHR9PC9zcGFuPjxici8+JHthcmd1bWVudH1gO1xuXG5cblxuICAvLyBidWJibGUgY2hhcnRcblxuICBnZXRCdWJibGVDaGFydERhdGEoKSB7XG4gICAgdGhpcy5oZWF0Q2hhcnREYXRhU291cmNlID0ge307XG4gICAgY29uc3QgeyByZXN1bHQsIHVuaXF1ZURhdGVzIH0gPSB0aGlzLmdlbmVyYXRlRGF0YSh0aGlzLmJ1YmJsZUNoYXJ0RGF0YSwgdGhpcy5jaGFydENvbmZpZylcbiAgICAvLyByZXN1bHQuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAvLyAgIGVsZW1lbnQuZGF0YXNldC5zb3J0KChhLCBiKSA9PiBtb21lbnQoYS5yZWNvcmREYXRlLCAnWVlZWU1NREQnKS5kaWZmKG1vbWVudChiLnJlY29yZERhdGUsICdZWVlZTU1ERCcpKSk7XG4gICAgLy8gfSk7XG4gICAgLy8gdW5pcXVlRGF0ZXMuc29ydCgpO1xuICAgIHRoaXMuaGVhdENoYXJ0RGF0YVNvdXJjZVtcImRhdGFTZXRcIl0gPSByZXN1bHQ7XG4gICAgdGhpcy5oZWF0Q2hhcnREYXRhU291cmNlW1wiYXJndW1lbnRWYWx1ZVwiXSA9IHVuaXF1ZURhdGVzO1xuICB9XG5cbiAgZ2VuZXJhdGVEYXRhKGRhdGEsIGNoYXJ0Q29uZmlnKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgY29uc3QgdW5pcXVlRGF0ZXMgPSBuZXcgU2V0KCk7XG4gICAgY29uc3QgZGF0YVNvdXJjZU1hcCA9IHt9O1xuXG4gICAgY29uc3Qgc291cmNlRmllbGQgPSBjaGFydENvbmZpZy5zb3VyY2VGaWVsZDtcbiAgICBjb25zdCBhcmd1bWVudEZpZWxkID0gY2hhcnRDb25maWcuYXJndW1lbnRGaWVsZDtcbiAgICBjb25zdCB2YWx1ZUZpZWxkID0gY2hhcnRDb25maWcuY2hhcnRfY29uZmlnWzBdLnZhbHVlRmllbGQ7XG4gICAgY29uc3QgbWluQnViYmxlU2l6ZSA9ICh0aGlzLmNoYXJ0Q29uZmlnLm1pbkJ1YmJsZVNpemUpID8gcGFyc2VJbnQodGhpcy5jaGFydENvbmZpZy5taW5CdWJibGVTaXplKSA6IDg7XG4gICAgY29uc3QgbWF4QnViYmxlU2l6ZSA9ICh0aGlzLmNoYXJ0Q29uZmlnLm1heEJ1YmJsZVNpemUpID8gcGFyc2VJbnQodGhpcy5jaGFydENvbmZpZy5tYXhCdWJibGVTaXplKSA6IDIwO1xuXG4gICAgZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgY29uc3Qgc291cmNlRmllbGRWYWx1ZSA9IGl0ZW1bc291cmNlRmllbGRdO1xuICAgICAgY29uc3QgYXJndW1lbnRGaWVsZFZhbHVlID0gaXRlbVthcmd1bWVudEZpZWxkXTtcbiAgICAgIGNvbnN0IHsgW3NvdXJjZUZpZWxkXTogXywgW2FyZ3VtZW50RmllbGRdOiBfXywgLi4ucmVzdCB9ID0gaXRlbTtcblxuICAgICAgaWYgKCFkYXRhU291cmNlTWFwW3NvdXJjZUZpZWxkVmFsdWVdKSB7XG4gICAgICAgIGRhdGFTb3VyY2VNYXBbc291cmNlRmllbGRWYWx1ZV0gPSB7XG4gICAgICAgICAgZGF0YXNvdXJjZTogc291cmNlRmllbGRWYWx1ZSxcbiAgICAgICAgICBkYXRhc2V0OiBbXVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgZGF0YVNvdXJjZU1hcFtzb3VyY2VGaWVsZFZhbHVlXS5kYXRhc2V0LnB1c2goe1xuICAgICAgICAuLi5yZXN0LFxuICAgICAgICBbYXJndW1lbnRGaWVsZF06IG1vbWVudChhcmd1bWVudEZpZWxkVmFsdWUpLmZvcm1hdCgnWVlZWS1NTS1ERCcpXG4gICAgICB9KTtcbiAgICAgIHVuaXF1ZURhdGVzLmFkZChtb21lbnQoYXJndW1lbnRGaWVsZFZhbHVlKS5mb3JtYXQoJ1lZWVktTU0tREQnKSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCB1bmlxdWVEYXRlc0FycmF5ID0gQXJyYXkuZnJvbSh1bmlxdWVEYXRlcyk7XG5cbiAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhU291cmNlTWFwKSB7XG4gICAgICBjb25zdCBkYXRhc2V0ID0gZGF0YVNvdXJjZU1hcFtrZXldLmRhdGFzZXQ7XG4gICAgICBjb25zdCBmb3JtYXR0ZWREYXRhc2V0ID0gdGhpcy5nZXRGb3JtYXRlRGF0YUJ5Q29sb3JDb2RlKGRhdGFzZXQsIHZhbHVlRmllbGQsIG1pbkJ1YmJsZVNpemUsIG1heEJ1YmJsZVNpemUpO1xuXG4gICAgICBjb25zdCBkYXRlVG9JdGVtTWFwID0ge307XG4gICAgICBmb3JtYXR0ZWREYXRhc2V0LmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgIGRhdGVUb0l0ZW1NYXBbaXRlbVthcmd1bWVudEZpZWxkXV0gPSBpdGVtO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGNvbXBsZXRlRGF0YXNldCA9IHVuaXF1ZURhdGVzQXJyYXkubWFwKChkYXRlOiBhbnkpID0+IHtcblxuICAgICAgICBpZiAoZGF0ZVRvSXRlbU1hcFtkYXRlXSkge1xuICAgICAgICAgIHJldHVybiBkYXRlVG9JdGVtTWFwW2RhdGVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBmaWxlQ291bnQ6IDAsXG4gICAgICAgICAgICBbYXJndW1lbnRGaWVsZF06IGRhdGUsXG4gICAgICAgICAgICBbdmFsdWVGaWVsZF06IDAsXG4gICAgICAgICAgICBjb2xvcjogXCJyZ2IoMjQyLCAxMTgsIDEwOSlcIlxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXN1bHQucHVzaCh7XG4gICAgICAgIGRhdGFzb3VyY2U6IGtleSxcbiAgICAgICAgZGF0YXNldDogY29tcGxldGVEYXRhc2V0XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVzdWx0OiByZXN1bHQsXG4gICAgICB1bmlxdWVEYXRlczogdW5pcXVlRGF0ZXNBcnJheVxuICAgIH07XG4gIH1cblxuXG5cbiAgZ2V0Rm9ybWF0ZURhdGFCeUNvbG9yQ29kZShmaWxlZGF0YSwgdmFsdWVGaWVsZCwgbWluQnViYmxlU2l6ZSwgbWF4QnViYmxlU2l6ZSkge1xuICAgIGZpbGVkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBpdGVtW3ZhbHVlRmllbGRdID0gcGFyc2VGbG9hdChpdGVtW3ZhbHVlRmllbGRdKTtcbiAgICB9KTtcblxuICAgIGxldCBtYXhSZWNoYXJnZUNvdW50ID0gTWF0aC5tYXgoLi4uZmlsZWRhdGEubWFwKGl0ZW0gPT4gaXRlbVt2YWx1ZUZpZWxkXSkpO1xuICAgIGxldCBtaW5SZWNoYXJnZUNvdW50ID0gTWF0aC5taW4oLi4uZmlsZWRhdGEubWFwKGl0ZW0gPT4gaXRlbVt2YWx1ZUZpZWxkXSkpO1xuXG4gICAgbGV0IG1pbkNvbG9yID0gWzQzLCAyMjQsIDkxXTtcbiAgICBsZXQgbWF4Q29sb3IgPSBbNjUsIDEzNSwgMjRdO1xuICAgIGxldCBob3ZlciA9IFsxMzUsIDE4NCwgMTA2XTtcblxuICAgIGZpbGVkYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBsZXQgc2l6ZSA9IHRoaXMubWFwUmFuZ2UoaXRlbVt2YWx1ZUZpZWxkXSwgbWluUmVjaGFyZ2VDb3VudCwgbWF4UmVjaGFyZ2VDb3VudCwgbWluQnViYmxlU2l6ZSwgbWF4QnViYmxlU2l6ZSk7XG4gICAgICBpdGVtLnNpemUgPSBzaXplO1xuICAgICAgaXRlbS50b29sVGlwID0gKGl0ZW1bdmFsdWVGaWVsZF0pID8gaXRlbVt2YWx1ZUZpZWxkXSA6ICcwJztcbiAgICAgIGl0ZW0uaG92ZXIgPSBgcmdiKCR7aG92ZXIuam9pbignLCcpfSlgO1xuICAgICAgaWYgKGl0ZW1bdmFsdWVGaWVsZF0gPT0gMCB8fCBpdGVtW3ZhbHVlRmllbGRdID09IHVuZGVmaW5lZCkge1xuICAgICAgICBpdGVtLmNvbG9yID0gYHJnYigke21pbkNvbG9yLmpvaW4oJywnKX0pYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGl0ZW0uY29sb3IgPSBgcmdiKCR7bWF4Q29sb3Iuam9pbignLCcpfSlgO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZpbGVkYXRhO1xuICB9XG5cbiAgbWFwUmFuZ2UodmFsdWUsIGluTWluLCBpbk1heCwgb3V0TWluLCBvdXRNYXgpIHtcbiAgICByZXR1cm4gKCh2YWx1ZSAtIGluTWluKSAqIChvdXRNYXggLSBvdXRNaW4pKSAvIChpbk1heCAtIGluTWluKSArIG91dE1pbjtcbiAgfVxuXG5cblxuICAvLyBjdXN0b21pemVMYWJlbFRleHQgPSAoaW5mbzogYW55KSA9PiBgJHtpbmZvLnZhbHVlVGV4dH1gO1xuXG5cbn1cbiIsIjxkaXYgY2xhc3M9XCJub3QtZnVsbC1zY3JlZW5cIiAoZGJsY2xpY2spPVwidG9nZ2xlRnVsbFNjcmVlbigpXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhZ2VfY29uZmlnPy53aWRHZXRDb25maWc/LmRpc3BsYXlcIj5cbiAgICAgICAgPGFwcC10aXRsZSBbdGl0bGVdPVwicGFnZV9jb25maWcud2lkR2V0Q29uZmlnLndpZGdldFRpdGxlXCIgW29wZXJhdG9yc109XCJwYWdlX2NvbmZpZy5vcGVyYXRpb25zXCJcbiAgICAgICAgICAgIFtkaXNwbGF5VHlwZV09XCInY2hhcnQnXCI+PC9hcHAtdGl0bGU+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPGRpdiBjbGFzcz1cIm14LTIgcC0yIGJnLWdyYXktODAwXCI+XG4gICAgICAgIDxhcHAtbG9hZGVyICpuZ0lmPVwiaXNMb2FkZXJcIj48L2FwcC1sb2FkZXI+XG4gICAgICAgIFxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2hhcnRDb25maWcuY2hhcnRUeXBlICE9PSAnZG91Z2hudXQnICYmIGNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSAhPT0gJ2Z1bm5lbCcgJiYgY2hhcnRDb25maWcuY2hhcnRUeXBlICE9PSAncGllJ1wiID5cbiAgICAgICAgICAgIDxkeC1jaGFydCBpZD1cImNoYXJ0XCIgW2RhdGFTb3VyY2VdPVwiZmluYWxDaGFydERhdGFTb3VyY2VcIlxuICAgICAgICAgICAgICAgIFt0aXRsZV09XCJ7IHRleHQ6IGNoYXJ0Q29uZmlnLmNhcHRpb24sIGZvbnQ6IHsgc2l6ZTogMTQgfSB9XCIgKm5nSWY9XCIhaXNMb2FkZXJcIlxuICAgICAgICAgICAgICAgIFt2YWx1ZUF4aXNdPVwiY2hhcnRDb25maWcudmFsdWVBeGlzQ29uZmlnXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoYXJ0Q29uZmlnLnNpemVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGR4by1zaXplIFtoZWlnaHRdPVwiY2hhcnRDb25maWcuc2l6ZVwiPlxuICAgICAgICAgICAgICAgICAgICA8L2R4by1zaXplPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBjaGFydENvbmZpZy5jaGFydF9jb25maWdcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0gJiYgaXRlbS5heGlzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZHhpLXZhbHVlLWF4aXMgbmFtZT1cInt7aXRlbS5heGlzfX1cIiBwb3NpdGlvbj1cInt7aXRlbS5wb3NpdGlvbn19XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4by10aXRsZSB0ZXh0PVwie3tpdGVtLm5hbWV9fVwiPjwvZHhvLXRpdGxlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9keGktdmFsdWUtYXhpcz5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8ZHhvLWFyZ3VtZW50LWF4aXM+XG4gICAgICAgICAgICAgICAgICAgIDxkeG8tbGFiZWwgb3ZlcmxhcHBpbmdCZWhhdmlvcj1cInJvdGF0ZVwiIFtyb3RhdGlvbkFuZ2xlXT1cIjI3MFwiPjwvZHhvLWxhYmVsPlxuICAgICAgICAgICAgICAgIDwvZHhvLWFyZ3VtZW50LWF4aXM+XG4gICAgICAgICAgICAgICAgPGR4by10b29sdGlwIFtlbmFibGVkXT1cInRydWVcIiBbc2hhcmVkXT1cInRydWVcIiBbY3VzdG9taXplVG9vbHRpcF09XCJjdXN0b21pemVUb29sdGlwXCI+XG4gICAgICAgICAgICAgICAgPC9keG8tdG9vbHRpcD5cbiAgICAgICAgICAgICAgICA8ZHhvLWNvbW1vbi1zZXJpZXMtc2V0dGluZ3MgYXJndW1lbnRGaWVsZD1cInt7Y2hhcnRDb25maWcuYXJndW1lbnRGaWVsZH19XCI+XG4gICAgICAgICAgICAgICAgPC9keG8tY29tbW9uLXNlcmllcy1zZXR0aW5ncz5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGNoYXJ0Q29uZmlnLmNoYXJ0X2NvbmZpZ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbSAmJiBpdGVtLmNvbG9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZHhpLXNlcmllcyB0eXBlPVwie3tpdGVtLnR5cGV9fVwiIHZhbHVlRmllbGQ9XCJ7e2l0ZW0udmFsdWVGaWVsZH19XCIgYXhpcz1cInt7aXRlbS5heGlzfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ7e2l0ZW0ubmFtZX19XCIgY29sb3I9XCJ7e2l0ZW0uY29sb3J9fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9keGktc2VyaWVzPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0gJiYgIWl0ZW0uY29sb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkeGktc2VyaWVzIHR5cGU9XCJ7e2l0ZW0udHlwZX19XCIgdmFsdWVGaWVsZD1cInt7aXRlbS52YWx1ZUZpZWxkfX1cIiBheGlzPVwie3tpdGVtLmF4aXN9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInt7aXRlbS5uYW1lfX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZHhpLXNlcmllcz5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8ZHhvLXNpemUgW2hlaWdodF09XCJjaGFydEhlaWdodFwiPlxuICAgICAgICAgICAgICAgIDwvZHhvLXNpemU+XG4gICAgICAgICAgICAgICAgPGR4by1sZWdlbmQgW3Zpc2libGVdPVwiY2hhcnRDb25maWcubGVnZW5kRGlzcGxheVwiIHZlcnRpY2FsQWxpZ25tZW50PVwie3tjaGFydENvbmZpZy52ZXJ0aWNhbEFsaWdubWVudH19XCJcbiAgICAgICAgICAgICAgICAgICAgaG9yaXpvbnRhbEFsaWdubWVudD1cInt7Y2hhcnRDb25maWcuaG9yaXpvbnRhbEFsaWdubWVudH19XCI+XG4gICAgICAgICAgICAgICAgPC9keG8tbGVnZW5kPlxuICAgICAgICAgICAgPC9keC1jaGFydD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSA9PSAnZG91Z2hudXQnIHx8IGNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSA9PSAncGllJ1wiPlxuXG4gICAgICAgICAgICA8ZHgtcGllLWNoYXJ0IGlkPVwicGllXCIgW3R5cGVdPVwiY2hhcnRDb25maWcuY2hhcnRUeXBlXCIgW3RpdGxlXT1cInsgdGV4dDogY2hhcnRDb25maWcuY2FwdGlvbiwgZm9udDogeyBzaXplOiAxNCB9IH1cIlxuICAgICAgICAgICAgICAgIHBhbGV0dGU9XCJTb2Z0IFBhc3RlbFwiIFtkYXRhU291cmNlXT1cImZpbmFsQ2hhcnREYXRhU291cmNlXCIgY2VudGVyVGVtcGxhdGU9XCJjZW50ZXJUZW1wbGF0ZVwiXG4gICAgICAgICAgICAgICAgKG9uUG9pbnRDbGljayk9XCJwb2ludENsaWNrSGFuZGxlcigkZXZlbnQpXCIgW3BhbGV0dGVdPVwiY2hhcnRDb25maWcucGFsZXR0ZVwiPlxuXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBjaGFydENvbmZpZy5jaGFydF9jb25maWdcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0uY29sb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkeGktc2VyaWVzIGFyZ3VtZW50RmllbGQ9e3tjaGFydENvbmZpZy5hcmd1bWVudEZpZWxkfX0gdmFsdWVGaWVsZD1cInt7aXRlbS52YWx1ZUZpZWxkfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ7e2l0ZW0ubmFtZX19XCIgY29sb3I9XCJ7e2l0ZW0uY29sb3J9fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeG8tbGFiZWwgW3Zpc2libGVdPVwiY2hhcnRDb25maWcubGFiZWxEaXNwbGF5XCIgZm9ybWF0PVwiY3VycmVuY3lcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4by1jb25uZWN0b3IgW3Zpc2libGVdPVwidHJ1ZVwiPjwvZHhvLWNvbm5lY3Rvcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2R4by1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZHhpLXNlcmllcz5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXRlbS5jb2xvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGR4aS1zZXJpZXMgYXJndW1lbnRGaWVsZD17e2NoYXJ0Q29uZmlnLmFyZ3VtZW50RmllbGR9fSB2YWx1ZUZpZWxkPVwie3tpdGVtLnZhbHVlRmllbGR9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInt7aXRlbS5uYW1lfX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHhvLWxhYmVsIFt2aXNpYmxlXT1cImNoYXJ0Q29uZmlnLmxhYmVsRGlzcGxheVwiIGZvcm1hdD1cImN1cnJlbmN5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeG8tY29ubmVjdG9yIFt2aXNpYmxlXT1cInRydWVcIj48L2R4by1jb25uZWN0b3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9keG8tbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2R4aS1zZXJpZXM+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjaGFydENvbmZpZy5zaXplXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkeG8tc2l6ZSBbaGVpZ2h0XT1cImNoYXJ0Q29uZmlnLnNpemVcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9keG8tc2l6ZT5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8ZHhvLWxlZ2VuZCBbdmlzaWJsZV09XCJjaGFydENvbmZpZy5sZWdlbmREaXNwbGF5XCJcbiAgICAgICAgICAgICAgICAgICAgaG9yaXpvbnRhbEFsaWdubWVudD1cInt7Y2hhcnRDb25maWcuaG9yaXpvbnRhbEFsaWdubWVudH19XCJcbiAgICAgICAgICAgICAgICAgICAgdmVydGljYWxBbGlnbm1lbnQ9XCJ7e2NoYXJ0Q29uZmlnLnZlcnRpY2FsQWxpZ25tZW50fX1cIj48L2R4by1sZWdlbmQ+XG4gICAgICAgICAgICAgICAgPCEtLSA8ZHhvLWV4cG9ydCBbZW5hYmxlZF09XCJ0cnVlXCI+PC9keG8tZXhwb3J0PiAtLT5cbiAgICAgICAgICAgICAgICA8ZHhvLXRvb2x0aXAgW2VuYWJsZWRdPVwidHJ1ZVwiIFtjdXN0b21pemVUb29sdGlwXT1cImN1c3RvbWl6ZVRvb2x0aXBcIiBmb3JtYXQ9XCJjdXJyZW5jeVwiPlxuICAgICAgICAgICAgICAgIDwvZHhvLXRvb2x0aXA+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoYXJ0Q29uZmlnLmNoYXJ0VHlwZSA9PSAnZG91Z2hudXQnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzdmcgKmR4VGVtcGxhdGU9XCJsZXQgcGllQ2hhcnQgb2YgJ2NlbnRlclRlbXBsYXRlJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD1cIjEwMFwiIGN5PVwiMTAwXCIgW2F0dHIucl09XCJwaWVDaGFydC5nZXRJbm5lclJhZGl1cygpIC0gNlwiIGZpbGw9XCJncmF5XCIgb3BhY2l0eT1cIjAuMDAwMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGU+XG4gICAgXG4gICAgICAgICAgICAgICAgICAgICAgICA8dGV4dCB0ZXh0LWFuY2hvcj1cIm1pZGRsZVwiIHN0eWxlPVwiZm9udC1zaXplOiAxNXB4XCIgeD1cIjEwMFwiIHk9XCIxMDBcIiBmaWxsPVwiI2VlZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0c3BhbiB4PVwiMTAwXCI+e3sgY2FsY3VsYXRlVG90YWwocGllQ2hhcnQpIH19PC90c3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGRpc3BsYXk6IGlubGluZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDx0c3BhbiB4PVwiMTAwXCIgZHk9XCIyMHB4XCIgc3R5bGU9XCJmb250LXdlaWdodDogNjAwXCI+PC90c3Bhbj4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RleHQ+XG4gICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICBcbiAgICAgICAgICAgIDwvZHgtcGllLWNoYXJ0PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2hhcnRDb25maWcuY2hhcnRUeXBlID09ICdmdW5uZWwnXCI+XG4gICAgICAgICAgICA8ZHgtZnVubmVsIGlkPVwiZnVubmVsXCIgW2RhdGFTb3VyY2VdPVwiZmluYWxDaGFydERhdGFTb3VyY2VcIiBhcmd1bWVudEZpZWxkPVwiYXJndW1lbnRcIiB2YWx1ZUZpZWxkPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgIHBhbGV0dGU9XCJTb2Z0IFBhc3RlbFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjaGFydENvbmZpZy5zaXplXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkeG8tc2l6ZSBbaGVpZ2h0XT1cImNoYXJ0Q29uZmlnLnNpemVcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9keG8tc2l6ZT5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8ZHhvLWV4cG9ydCBbZW5hYmxlZF09XCJmYWxzZVwiPjwvZHhvLWV4cG9ydD5cbiAgICAgICAgICAgICAgICA8ZHhvLXRvb2x0aXAgW2VuYWJsZWRdPVwidHJ1ZVwiPiA8L2R4by10b29sdGlwPlxuICAgICAgICAgICAgICAgIDxkeG8taXRlbT5cbiAgICAgICAgICAgICAgICAgICAgPGR4by1ib3JkZXIgW3Zpc2libGVdPVwidHJ1ZVwiPiA8L2R4by1ib3JkZXI+XG4gICAgICAgICAgICAgICAgPC9keG8taXRlbT5cbiAgICAgICAgICAgICAgICA8ZHhvLWxhYmVsIFt2aXNpYmxlXT1cInRydWVcIiBwb3NpdGlvbj1cImluc2lkZVwiIGJhY2tncm91bmRDb2xvcj1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgICBbY3VzdG9taXplVGV4dF09XCJjdXN0b21pemVUZXh0XCI+PC9keG8tbGFiZWw+XG4gICAgICAgICAgICA8L2R4LWZ1bm5lbD5cblxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2hhcnRDb25maWcuY2hhcnRUeXBlID09ICdidWJibGUnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXgtNSBvdmVyZmxvdy14LWF1dG9cIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGhlYXRDaGFydERhdGFTb3VyY2UuZGF0YVNldFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtMTAgdGV4dC1zbSBpdGVtcy1jZW50ZXIgbWluLXctMTIgbWF4LXctWzMwJV0ganVzdGlmeS1jZW50ZXIgZmxleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7aXRlbS5kYXRhc291cmNlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlubGluZS1ibG9jayBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LW5vd3JhcCBqdXN0aWZ5LWNlbnRlciBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYm94IG9mIGl0ZW0uZGF0YXNldFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtc2hyaW5rLTAgbWluLXctMTAgbWF4LXctWzIwJV0gaC0xMCB0ZXh0LXNtIGN1cnNvci1wb2ludGVyIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHRleHQtZ3JheS04MDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIidSZWNvcmQgRGF0ZTogJyArIGJveC5yZWNvcmREYXRlICsgJ1xcblJlY2hhcmdlIENvdW50OiAnICsgYm94LnRvb2xUaXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBDbGFzcz1cImN1c3RvbS10b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvdW5kZWQtZnVsbFwiIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLWNvbG9yJzogYm94LmlzSG92ZXJlZCA/ICdyZ2IoMTM1LCAxODQsIDEwNiknIDogYm94LmNvbG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dpZHRoLnB4JzogYm94LnNpemUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaG92ZXInOiBib3guaG92ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaGVpZ2h0LnB4JzogYm94LnNpemVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCIgKG1vdXNlZW50ZXIpPVwiYm94LmlzSG92ZXJlZCA9IHRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobW91c2VsZWF2ZSk9XCJib3guaXNIb3ZlcmVkID0gZmFsc2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5saW5lLWJsb2NrXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtbm93cmFwIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1zaHJpbmstMCB3LTEyIG1heC13LVsyMCVdIGgtZnVsbCBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBoZWF0Q2hhcnREYXRhU291cmNlLmFyZ3VtZW50VmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxleC1zaHJpbmstMCB3LTEwIG1heC13LVsyMCVdIG1pbi1oLTE0IGZsZXggdGV4dC1zbSBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgbXktMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nU3R5bGVdPVwieydoZWlnaHQnOiAnYXV0byd9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXJvdGF0ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2l0ZW19fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cblxuICAgIDxidXR0b24gKm5nSWY9XCJpc0Z1bGxTY3JlZW5cIiBjbGFzcz1cImNsb3NlLWJ1dHRvblwiIChjbGljayk9XCJ0b2dnbGVGdWxsU2NyZWVuKClcIj5DbG9zZTwvYnV0dG9uPlxuPC9kaXY+Il19
|