gamma-app-controller 1.0.1
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/README.md +24 -0
- package/esm2020/gamma-app-controller.mjs +2 -0
- package/esm2020/lib/application-controller/app.http.service.mjs +24 -0
- package/esm2020/lib/application-controller/application-content.service.mjs +482 -0
- package/esm2020/lib/application-controller/application-controller.module.mjs +324 -0
- package/esm2020/lib/application-controller/application-dataset-call.service.mjs +321 -0
- package/esm2020/lib/application-controller/application-dataset-component/application-dataset/application-dataset.component.mjs +390 -0
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset/create-dataset.component.mjs +349 -0
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset-json/create-dataset-json.component.mjs +148 -0
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset-sql/create-dataset-sql.component.mjs +167 -0
- package/esm2020/lib/application-controller/application-dataset-component/create-dataset-sql/sqlFormatter.mjs +17 -0
- package/esm2020/lib/application-controller/application-dataset-component/dataset-mongo/dataset-mongo.component.mjs +57 -0
- package/esm2020/lib/application-controller/application-dataset-component/dataset-query-bulder/dataset-query-bulder.component.mjs +409 -0
- package/esm2020/lib/application-controller/application-dataset-component/dataset-rest-api/dataset-rest-api.component.mjs +61 -0
- package/esm2020/lib/application-controller/application-filter/application-filter.component.mjs +186 -0
- package/esm2020/lib/application-controller/application-view-components/application-views/application-views.component.mjs +134 -0
- package/esm2020/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.mjs +559 -0
- package/esm2020/lib/application-controller/common-header/common-header.component.mjs +33 -0
- package/esm2020/lib/application-controller/common.mjs +1207 -0
- package/esm2020/lib/application-controller/environment.mjs +26 -0
- package/esm2020/lib/application-controller/kpi-comon-service.mjs +537 -0
- package/esm2020/lib/application-controller/kpi-service.mjs +108 -0
- package/esm2020/lib/application-controller/loading/loading.component.mjs +16 -0
- package/esm2020/lib/application-controller/loading/loadingModule.mjs +28 -0
- package/esm2020/lib/application-controller/moment-helper.mjs +4 -0
- package/esm2020/lib/application-controller/page-controller/page-config/page-config.component.mjs +977 -0
- package/esm2020/lib/application-controller/page-controller/page-controller/page-controller.component.mjs +172 -0
- package/esm2020/lib/application-controller/page-templates/cdr-config/cdr-config.component.mjs +227 -0
- package/esm2020/lib/application-controller/page-templates/dynamic-route-service.mjs +22 -0
- package/esm2020/lib/application-controller/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.mjs +118 -0
- package/esm2020/lib/application-controller/shared/advanced-component/app-advance-header/app-header.component.mjs +181 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.mjs +71 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.mjs +266 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.mjs +159 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.mjs +144 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.mjs +20 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.mjs +168 -0
- package/esm2020/lib/application-controller/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.mjs +74 -0
- package/esm2020/lib/application-controller/shared/advanced-component/google-geo-map/google-geo-map.component.mjs +118 -0
- package/esm2020/lib/application-controller/shared/api.service.mjs +117 -0
- package/esm2020/lib/application-controller/shared/app-title/app-title.component.mjs +67 -0
- package/esm2020/lib/application-controller/shared/gamam-widget/gamam-widget.component.mjs +37 -0
- package/esm2020/lib/application-controller/shared/gamma-advance-filter/gamma-advance-filter.component.mjs +229 -0
- package/esm2020/lib/application-controller/shared/gamma-bread-crumbs/bread-crumbs.component.mjs +144 -0
- package/esm2020/lib/application-controller/shared/kpi-comon-service.mjs +537 -0
- package/esm2020/lib/application-controller/shared/loader/loader.component.mjs +14 -0
- package/esm2020/lib/application-controller/shared/loading/loading.component.mjs +16 -0
- package/esm2020/lib/application-controller/shared/loading/loadingModule.mjs +28 -0
- package/esm2020/lib/application-controller/shared/safeHtmlPipe.mjs +20 -0
- package/esm2020/lib/application-controller/support-components/dash-chart/dash-chart.component.mjs +294 -0
- package/esm2020/lib/application-controller/support-components/dash-table/dash-table.component.mjs +287 -0
- package/esm2020/lib/application-controller/support-components/geo-map/geo-map.component.mjs +255 -0
- package/esm2020/lib/application-controller/support-components/table-with-bar/table-with-bar.component.mjs +269 -0
- package/esm2020/lib/gamma-app-controller.component.mjs +16 -0
- package/esm2020/lib/gamma-app-controller.module.mjs +43 -0
- package/esm2020/lib/gamma-app-controller.service.mjs +20 -0
- package/esm2020/lib/icons.module.mjs +23 -0
- package/esm2020/public-api.mjs +49 -0
- package/fesm2015/gamma-app-controller.mjs +10250 -0
- package/fesm2015/gamma-app-controller.mjs.map +1 -0
- package/fesm2020/gamma-app-controller.mjs +10248 -0
- package/fesm2020/gamma-app-controller.mjs.map +1 -0
- package/index.d.ts +2 -0
- package/lib/application-controller/app.http.service.d.ts +15 -0
- package/lib/application-controller/application-content.service.d.ts +79 -0
- package/lib/application-controller/application-controller.module.d.ts +51 -0
- package/lib/application-controller/application-dataset-call.service.d.ts +20 -0
- package/lib/application-controller/application-dataset-component/application-dataset/application-dataset.component.d.ts +55 -0
- package/lib/application-controller/application-dataset-component/create-dataset/create-dataset.component.d.ts +121 -0
- package/lib/application-controller/application-dataset-component/create-dataset-json/create-dataset-json.component.d.ts +38 -0
- package/lib/application-controller/application-dataset-component/create-dataset-sql/create-dataset-sql.component.d.ts +42 -0
- package/lib/application-controller/application-dataset-component/create-dataset-sql/sqlFormatter.d.ts +7 -0
- package/lib/application-controller/application-dataset-component/dataset-mongo/dataset-mongo.component.d.ts +21 -0
- package/lib/application-controller/application-dataset-component/dataset-query-bulder/dataset-query-bulder.component.d.ts +62 -0
- package/lib/application-controller/application-dataset-component/dataset-rest-api/dataset-rest-api.component.d.ts +22 -0
- package/lib/application-controller/application-filter/application-filter.component.d.ts +36 -0
- package/lib/application-controller/application-view-components/application-views/application-views.component.d.ts +47 -0
- package/lib/application-controller/application-view-components/create-comp-view/create-comp-view.component.d.ts +73 -0
- package/lib/application-controller/common-header/common-header.component.d.ts +15 -0
- package/lib/application-controller/common.d.ts +148 -0
- package/lib/application-controller/environment.d.ts +25 -0
- package/lib/application-controller/kpi-comon-service.d.ts +14 -0
- package/lib/application-controller/kpi-service.d.ts +6 -0
- package/lib/application-controller/loading/loading.component.d.ts +9 -0
- package/lib/application-controller/loading/loadingModule.d.ts +10 -0
- package/lib/application-controller/moment-helper.d.ts +3 -0
- package/lib/application-controller/page-controller/page-config/page-config.component.d.ts +188 -0
- package/lib/application-controller/page-controller/page-controller/page-controller.component.d.ts +47 -0
- package/lib/application-controller/page-templates/cdr-config/cdr-config.component.d.ts +44 -0
- package/lib/application-controller/page-templates/dynamic-route-service.d.ts +8 -0
- package/lib/application-controller/shared/advanced-component/advance-widget-header-filter/advance-widget-header-filter.component.d.ts +33 -0
- package/lib/application-controller/shared/advanced-component/app-advance-header/app-header.component.d.ts +43 -0
- package/lib/application-controller/shared/advanced-component/gamm-single-number-card/gamm-single-number-card.component.d.ts +20 -0
- package/lib/application-controller/shared/advanced-component/gamma-advance-chart/gamma-advance-chart.component.d.ts +51 -0
- package/lib/application-controller/shared/advanced-component/gamma-advance-operator-table/gamma-advance-operator-table.component.d.ts +32 -0
- package/lib/application-controller/shared/advanced-component/gamma-table-clumn-bar-chart/gamma-table-clumn-bar-chart.component.d.ts +31 -0
- package/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/contentSafeHtml.d.ts +10 -0
- package/lib/application-controller/shared/advanced-component/gamma-table-with-percentage/gamma-table-with-percentage.component.d.ts +26 -0
- package/lib/application-controller/shared/advanced-component/gamma-today-previous/gamma-today-previous.component.d.ts +21 -0
- package/lib/application-controller/shared/advanced-component/google-geo-map/google-geo-map.component.d.ts +29 -0
- package/lib/application-controller/shared/api.service.d.ts +26 -0
- package/lib/application-controller/shared/app-title/app-title.component.d.ts +28 -0
- package/lib/application-controller/shared/gamam-widget/gamam-widget.component.d.ts +20 -0
- package/lib/application-controller/shared/gamma-advance-filter/gamma-advance-filter.component.d.ts +45 -0
- package/lib/application-controller/shared/gamma-bread-crumbs/bread-crumbs.component.d.ts +32 -0
- package/lib/application-controller/shared/kpi-comon-service.d.ts +14 -0
- package/lib/application-controller/shared/loader/loader.component.d.ts +8 -0
- package/lib/application-controller/shared/loading/loading.component.d.ts +9 -0
- package/lib/application-controller/shared/loading/loadingModule.d.ts +10 -0
- package/lib/application-controller/shared/safeHtmlPipe.d.ts +10 -0
- package/lib/application-controller/support-components/dash-chart/dash-chart.component.d.ts +83 -0
- package/lib/application-controller/support-components/dash-table/dash-table.component.d.ts +67 -0
- package/lib/application-controller/support-components/geo-map/geo-map.component.d.ts +70 -0
- package/lib/application-controller/support-components/table-with-bar/table-with-bar.component.d.ts +70 -0
- package/lib/gamma-app-controller.component.d.ts +5 -0
- package/lib/gamma-app-controller.module.d.ts +10 -0
- package/lib/gamma-app-controller.service.d.ts +7 -0
- package/lib/icons.module.d.ts +11 -0
- package/package.json +33 -0
- package/public-api.d.ts +48 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import * as i1 from "../../common";
|
|
4
|
+
import * as i2 from "ngx-toastr";
|
|
5
|
+
import * as i3 from "../../application-content.service";
|
|
6
|
+
import * as i4 from "@angular/common";
|
|
7
|
+
import * as i5 from "devextreme-angular/ui/check-box";
|
|
8
|
+
import * as i6 from "devextreme-angular/ui/select-box";
|
|
9
|
+
import * as i7 from "devextreme-angular/ui/text-box";
|
|
10
|
+
import * as i8 from "@angular/forms";
|
|
11
|
+
export class DatasetQueryBulderComponent {
|
|
12
|
+
constructor(commonService, toastr, service) {
|
|
13
|
+
this.commonService = commonService;
|
|
14
|
+
this.toastr = toastr;
|
|
15
|
+
this.service = service;
|
|
16
|
+
this.reqFieldsDataSource = [];
|
|
17
|
+
this.isreqFields = false;
|
|
18
|
+
this.iscdrParams = false;
|
|
19
|
+
this.cdrFieldsDataSource = [];
|
|
20
|
+
this.kpi_function = ["sum", "count", "avg", "max", "min", "stddev", "count_distinct"];
|
|
21
|
+
this.kpi_operator = ["eq", "gte", "lte", "ne", "in", "notIn", "contains", "startsWith", "endsWith"];
|
|
22
|
+
this.kpi_enrichment_name = [];
|
|
23
|
+
this.reqShortDataSource = [];
|
|
24
|
+
this.filterMapingDatasource = [];
|
|
25
|
+
this.isModelVisible = false;
|
|
26
|
+
this.isSqlCopiedText = false;
|
|
27
|
+
this.isReconColume = false;
|
|
28
|
+
this.getQueryBulbderDataSet = new EventEmitter();
|
|
29
|
+
this.reconColumeDatasource = [];
|
|
30
|
+
this.isQueryTypeSelect = false;
|
|
31
|
+
}
|
|
32
|
+
set bulderDataset(value) {
|
|
33
|
+
if (value.queryConfig.reqFields && value.queryConfig.reqFields.length < 2) {
|
|
34
|
+
this.reqFieldsDataSource = [
|
|
35
|
+
{
|
|
36
|
+
"name": "pageNumber",
|
|
37
|
+
"value": 1,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "pageSize",
|
|
41
|
+
"value": 2010,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "dbConfig",
|
|
45
|
+
"value": "",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "databaseName",
|
|
49
|
+
"value": "",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "tableName",
|
|
53
|
+
"value": "",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "paginationRequired",
|
|
57
|
+
"value": "false",
|
|
58
|
+
}
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.reqFieldsDataSource = this.processParamsformatData(value.queryConfig.reqFields);
|
|
63
|
+
this.selectedDataSource = value.queryConfig.reqFields.find(item => item.dbConfig !== undefined)?.dbConfig;
|
|
64
|
+
this.isQueryTypeSelect = true;
|
|
65
|
+
}
|
|
66
|
+
if (value.queryConfig.mapedFilters == undefined) {
|
|
67
|
+
value.queryConfig.mapedFilters = [];
|
|
68
|
+
value.queryConfig.mapedFilters.push({ "localColumn": "", "serverColumn": "", "operatorName": "", "defaultValue": "", "dataType": "" });
|
|
69
|
+
}
|
|
70
|
+
if (value.queryConfig.sorters == undefined) {
|
|
71
|
+
value.queryConfig.sorters = [];
|
|
72
|
+
value.queryConfig.sorters.push({ "columnName": "", "descending": false });
|
|
73
|
+
}
|
|
74
|
+
if (value.queryConfig.columns == undefined) {
|
|
75
|
+
value.queryConfig.columns = [];
|
|
76
|
+
let obj = {
|
|
77
|
+
"measures": true,
|
|
78
|
+
"dataField": "",
|
|
79
|
+
"columnName": "",
|
|
80
|
+
"functionName": "",
|
|
81
|
+
"enrichFunction": "",
|
|
82
|
+
"advancedColumn": "",
|
|
83
|
+
"caption": "",
|
|
84
|
+
};
|
|
85
|
+
value.queryConfig.columns.push(obj);
|
|
86
|
+
}
|
|
87
|
+
if (value.queryConfig.havings == undefined) {
|
|
88
|
+
value.queryConfig.havings = [];
|
|
89
|
+
}
|
|
90
|
+
this.queryBulderDataset = value;
|
|
91
|
+
}
|
|
92
|
+
ngOnInit() {
|
|
93
|
+
this.service.listColumnEnrichmentFunctions().subscribe(data => {
|
|
94
|
+
this.kpi_enrichment_name = data;
|
|
95
|
+
});
|
|
96
|
+
this.reconColumeDatasource = [
|
|
97
|
+
{
|
|
98
|
+
"dataField": "",
|
|
99
|
+
"enrichFunction": "",
|
|
100
|
+
"columeOne": "",
|
|
101
|
+
"columeTwo": "",
|
|
102
|
+
"reconType": "",
|
|
103
|
+
"caption": ""
|
|
104
|
+
}
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
processParamsformatData(data) {
|
|
108
|
+
const formatted_data = data.map(item => {
|
|
109
|
+
const [name, value] = Object.entries(item)[0];
|
|
110
|
+
return {
|
|
111
|
+
name,
|
|
112
|
+
value: name === 'paginationRequired' ? value.toString() : value
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
return formatted_data;
|
|
116
|
+
}
|
|
117
|
+
addColumns() {
|
|
118
|
+
let obj = {
|
|
119
|
+
"measures": true,
|
|
120
|
+
"dataField": "",
|
|
121
|
+
"columnName": "",
|
|
122
|
+
"functionName": "",
|
|
123
|
+
"advancedColumn": "",
|
|
124
|
+
"enrichFunction": "",
|
|
125
|
+
"caption": "",
|
|
126
|
+
};
|
|
127
|
+
this.queryBulderDataset.queryConfig.columns.push(obj);
|
|
128
|
+
}
|
|
129
|
+
deleteColumns(i) {
|
|
130
|
+
this.queryBulderDataset.queryConfig.columns.splice(i, 1);
|
|
131
|
+
}
|
|
132
|
+
addReconColume() {
|
|
133
|
+
let obj = {
|
|
134
|
+
"dataField": "",
|
|
135
|
+
"columeOne": "",
|
|
136
|
+
"columeTwo": "",
|
|
137
|
+
"enrichFunction": "",
|
|
138
|
+
"reconType": "",
|
|
139
|
+
"caption": ""
|
|
140
|
+
};
|
|
141
|
+
this.reconColumeDatasource.push(obj);
|
|
142
|
+
}
|
|
143
|
+
deleteReconColume(i) {
|
|
144
|
+
this.reconColumeDatasource.splice(i, 1);
|
|
145
|
+
}
|
|
146
|
+
saveReconsColume() {
|
|
147
|
+
this.reconColumeDatasource.forEach(element => {
|
|
148
|
+
if (element.reconType == "variance") {
|
|
149
|
+
let columeString = "{'$subtract': ['$" + element.columeOne + "','$" + element.columeTwo + "']}";
|
|
150
|
+
let node = {
|
|
151
|
+
"measures": true,
|
|
152
|
+
"dataField": element.dataField,
|
|
153
|
+
"columnName": element.dataField,
|
|
154
|
+
"functionName": "",
|
|
155
|
+
"advancedColumn": columeString,
|
|
156
|
+
"enrichFunction": element.enrichFunction,
|
|
157
|
+
"caption": element.caption,
|
|
158
|
+
'deriveField': true
|
|
159
|
+
};
|
|
160
|
+
this.queryBulderDataset.queryConfig.columns.push(node);
|
|
161
|
+
console.log(columeString);
|
|
162
|
+
}
|
|
163
|
+
else if (element.reconType == "percentage") {
|
|
164
|
+
let columeString = "{'$cond': { if: { $eq: [ '$" + element.columeOne + "', 0 ] }, then: 0, else: {'$divide':[{'$subtract': ['$" + element.columeOne + "','$" + element.columeTwo + "']},'$" + element.columeOne + "']} }}";
|
|
165
|
+
let node = {
|
|
166
|
+
"measures": true,
|
|
167
|
+
"dataField": element.dataField,
|
|
168
|
+
"columnName": element.dataField,
|
|
169
|
+
"functionName": "",
|
|
170
|
+
"advancedColumn": columeString,
|
|
171
|
+
"enrichFunction": element.enrichFunction,
|
|
172
|
+
"caption": element.caption,
|
|
173
|
+
'deriveField': true
|
|
174
|
+
};
|
|
175
|
+
this.queryBulderDataset.queryConfig.columns.push(node);
|
|
176
|
+
}
|
|
177
|
+
else if (element.reconType == "absolute") {
|
|
178
|
+
let columeString = "{'$abs': {'$cond': { if: { $eq: [ '$" + element.columeOne + "', 0 ] }, then: 0, else: {'$divide': [{'$subtract': ['$" + element.columeOne + "', '$" + element.columeTwo + "']}, '$" + element.columeOne + "']}}}}";
|
|
179
|
+
let node = {
|
|
180
|
+
"measures": true,
|
|
181
|
+
"dataField": element.dataField,
|
|
182
|
+
"columnName": element.dataField,
|
|
183
|
+
"functionName": "",
|
|
184
|
+
"advancedColumn": columeString,
|
|
185
|
+
"enrichFunction": element.enrichFunction,
|
|
186
|
+
"caption": element.caption,
|
|
187
|
+
'deriveField': true
|
|
188
|
+
};
|
|
189
|
+
this.queryBulderDataset.queryConfig.columns.push(node);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
saveColumnsAndMasures() {
|
|
194
|
+
this.queryBulderDataset.queryConfig.measures = [];
|
|
195
|
+
this.queryBulderDataset.queryConfig.dimensions = [];
|
|
196
|
+
this.queryBulderDataset.queryConfig.columns.forEach(element => {
|
|
197
|
+
const advancedColumnValue = element.advancedColumn === "" ? null : element.advancedColumn;
|
|
198
|
+
if (element.measures) {
|
|
199
|
+
let obj = {
|
|
200
|
+
columnName: element.columnName,
|
|
201
|
+
functionName: element.functionName,
|
|
202
|
+
enrichFunction: element.enrichFunction,
|
|
203
|
+
advancedColumn: advancedColumnValue,
|
|
204
|
+
aliasName: element.dataField,
|
|
205
|
+
};
|
|
206
|
+
if (element.deriveField) {
|
|
207
|
+
obj['deriveField'] = element.deriveField;
|
|
208
|
+
}
|
|
209
|
+
this.queryBulderDataset.queryConfig.measures.push(obj);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
let obj = {
|
|
213
|
+
columnName: element.columnName,
|
|
214
|
+
enrichFunction: element.enrichFunction,
|
|
215
|
+
aliasName: element.dataField,
|
|
216
|
+
};
|
|
217
|
+
this.queryBulderDataset.queryConfig.dimensions.push(obj);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
this.toastr.success('Columns Saved Successfully');
|
|
221
|
+
}
|
|
222
|
+
saveDataToStore() {
|
|
223
|
+
const buildDate = localStorage.getItem('querybuilder');
|
|
224
|
+
if (buildDate) {
|
|
225
|
+
localStorage.removeItem(buildDate);
|
|
226
|
+
}
|
|
227
|
+
localStorage.setItem('querybuilder', JSON.stringify(this.queryBulderDataset));
|
|
228
|
+
}
|
|
229
|
+
transformColumnsForMesurs(inputColumns) {
|
|
230
|
+
const measure = [];
|
|
231
|
+
inputColumns.forEach(col => {
|
|
232
|
+
});
|
|
233
|
+
return measure;
|
|
234
|
+
}
|
|
235
|
+
addFilter() {
|
|
236
|
+
let obj = {
|
|
237
|
+
"type": "",
|
|
238
|
+
"value": "",
|
|
239
|
+
"key": "",
|
|
240
|
+
"display": "",
|
|
241
|
+
"placeholder": ""
|
|
242
|
+
};
|
|
243
|
+
this.queryBulderDataset.queryConfig.filter.push(obj);
|
|
244
|
+
}
|
|
245
|
+
deleteFilter(i) {
|
|
246
|
+
this.queryBulderDataset.queryConfig.filter.splice(i, 1);
|
|
247
|
+
}
|
|
248
|
+
addParams() {
|
|
249
|
+
let obj = {
|
|
250
|
+
"name": "",
|
|
251
|
+
"value": "",
|
|
252
|
+
};
|
|
253
|
+
this.reqFieldsDataSource.push(obj);
|
|
254
|
+
}
|
|
255
|
+
deleteParams(i) {
|
|
256
|
+
this.reqFieldsDataSource.splice(i, 1);
|
|
257
|
+
}
|
|
258
|
+
addShortColumns() {
|
|
259
|
+
this.queryBulderDataset.queryConfig.sorters.push({ "columnName": "", "descending": false });
|
|
260
|
+
}
|
|
261
|
+
deleteShortColumns(i) {
|
|
262
|
+
this.queryBulderDataset.queryConfig.sorters.splice(i, 1);
|
|
263
|
+
}
|
|
264
|
+
saveParams() {
|
|
265
|
+
let paginationRequiredExists = false;
|
|
266
|
+
this.queryBulderDataset.queryConfig.reqFields = this.reqFieldsDataSource.map(item => {
|
|
267
|
+
const newObj = {};
|
|
268
|
+
if (item.name === "paginationRequired") {
|
|
269
|
+
paginationRequiredExists = true;
|
|
270
|
+
newObj[item.name] = item.value === "true";
|
|
271
|
+
}
|
|
272
|
+
else if (typeof item.value === "string" && !isNaN(item.value) && item.value.trim() !== "") {
|
|
273
|
+
newObj[item.name] = Number(item.value);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
newObj[item.name] = item.value;
|
|
277
|
+
}
|
|
278
|
+
return newObj;
|
|
279
|
+
});
|
|
280
|
+
if (!paginationRequiredExists) {
|
|
281
|
+
this.queryBulderDataset.queryConfig.reqFields.push({ paginationRequired: "false" });
|
|
282
|
+
}
|
|
283
|
+
this.toastr.success('Pagination Request Params Saved Successfully');
|
|
284
|
+
}
|
|
285
|
+
addFilterMapingColumns() {
|
|
286
|
+
let obj = { "localColumn": "", "serverColumn": "", "operatorName": "", "defaultValue": "", "dataType": "" };
|
|
287
|
+
this.queryBulderDataset.queryConfig.mapedFilters.push(obj);
|
|
288
|
+
}
|
|
289
|
+
deleteFilterMapingColumns(i) {
|
|
290
|
+
this.queryBulderDataset.queryConfig.mapedFilters.splice(i, 1);
|
|
291
|
+
}
|
|
292
|
+
moveItemForColumns(index, direction) {
|
|
293
|
+
if (index < 0 || index >= this.queryBulderDataset.queryConfig.mapedFilters.length)
|
|
294
|
+
return;
|
|
295
|
+
const newPosition = direction === 'up' ? index - 1 : index + 1;
|
|
296
|
+
if (newPosition < 0 || newPosition >= this.queryBulderDataset.queryConfig.mapedFilters.length)
|
|
297
|
+
return;
|
|
298
|
+
const itemToMove = this.queryBulderDataset.queryConfig.mapedFilters[index];
|
|
299
|
+
this.queryBulderDataset.queryConfig.mapedFilters.splice(index, 1);
|
|
300
|
+
this.queryBulderDataset.queryConfig.mapedFilters.splice(newPosition, 0, itemToMove);
|
|
301
|
+
}
|
|
302
|
+
moveItemForMeasuresColumns(index, direction) {
|
|
303
|
+
if (index < 0 || index >= this.queryBulderDataset.queryConfig.columns.length)
|
|
304
|
+
return;
|
|
305
|
+
const newPosition = direction === 'up' ? index - 1 : index + 1;
|
|
306
|
+
if (newPosition < 0 || newPosition >= this.queryBulderDataset.queryConfig.columns.length)
|
|
307
|
+
return;
|
|
308
|
+
const itemToMove = this.queryBulderDataset.queryConfig.columns[index];
|
|
309
|
+
this.queryBulderDataset.queryConfig.columns.splice(index, 1);
|
|
310
|
+
this.queryBulderDataset.queryConfig.columns.splice(newPosition, 0, itemToMove);
|
|
311
|
+
}
|
|
312
|
+
checkForQuery() {
|
|
313
|
+
let transformedObject = {};
|
|
314
|
+
for (let item of this.queryBulderDataset.queryConfig.reqFields) {
|
|
315
|
+
const key = Object.keys(item)[0];
|
|
316
|
+
const value = Object.values(item)[0];
|
|
317
|
+
if (key === 'startDate') {
|
|
318
|
+
transformedObject.recordDate = value;
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
transformedObject[key] = value;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
transformedObject['dimensions'] = this.queryBulderDataset.queryConfig.dimensions;
|
|
325
|
+
transformedObject['measures'] = this.queryBulderDataset.queryConfig.measures;
|
|
326
|
+
transformedObject['filters'] = this.transformDataForMFilter(this.queryBulderDataset.queryConfig.mapedFilters);
|
|
327
|
+
;
|
|
328
|
+
transformedObject['sorters'] = this.queryBulderDataset.queryConfig.sorters;
|
|
329
|
+
transformedObject["paginationRequired"] = true;
|
|
330
|
+
console.log(transformedObject);
|
|
331
|
+
this.service.validateAggregatePaginatedQuery(transformedObject).subscribe(data => {
|
|
332
|
+
console.log(data);
|
|
333
|
+
this.query_data = data.query;
|
|
334
|
+
this.isModelVisible = true;
|
|
335
|
+
}, err => {
|
|
336
|
+
this.toastr.error('Unexpected Server Exception. Please contact System Admin.');
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
closeModalVisibleModal() {
|
|
340
|
+
this.isModelVisible = false;
|
|
341
|
+
this.query_data = '';
|
|
342
|
+
}
|
|
343
|
+
transformDataForMFilter(mapfilter) {
|
|
344
|
+
let result = [];
|
|
345
|
+
mapfilter.forEach(mapping => {
|
|
346
|
+
let resultObj = {
|
|
347
|
+
columnName: mapping.serverColumn,
|
|
348
|
+
dataType: mapping.dataType,
|
|
349
|
+
operator: mapping.operatorName,
|
|
350
|
+
value: mapping.defaultValue
|
|
351
|
+
};
|
|
352
|
+
result.push(resultObj);
|
|
353
|
+
});
|
|
354
|
+
return result;
|
|
355
|
+
}
|
|
356
|
+
copySqlFromModal() {
|
|
357
|
+
const listener = (e) => {
|
|
358
|
+
e.clipboardData.setData('text/plain', this.query_data);
|
|
359
|
+
e.preventDefault();
|
|
360
|
+
};
|
|
361
|
+
this.isSqlCopiedText = true;
|
|
362
|
+
document.addEventListener('copy', listener);
|
|
363
|
+
document.execCommand('copy');
|
|
364
|
+
document.removeEventListener('copy', listener);
|
|
365
|
+
}
|
|
366
|
+
createDataSet() {
|
|
367
|
+
this.getQueryBulbderDataSet.emit(this.queryBulderDataset);
|
|
368
|
+
}
|
|
369
|
+
getQueryForDetailsData(e) {
|
|
370
|
+
if (e.value == 'Basic') {
|
|
371
|
+
this.queryBulderDataset.api = '/kpi/genericDetailDataResponse';
|
|
372
|
+
this.queryBulderDataset.queryConfig.columns = [];
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
this.queryBulderDataset.api = '/kpi/genericAggregatePaginatedKpiServiceResponse';
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
getDataConfig(e) {
|
|
379
|
+
if (e.event) {
|
|
380
|
+
this.selectedDataSource = e.value;
|
|
381
|
+
this.isQueryTypeSelect = true;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
addHavingsColume() {
|
|
385
|
+
let obj = {
|
|
386
|
+
"columnName": "",
|
|
387
|
+
"advancedColumn": "",
|
|
388
|
+
"dataType": "",
|
|
389
|
+
"operator": "",
|
|
390
|
+
"value": ""
|
|
391
|
+
};
|
|
392
|
+
this.queryBulderDataset.queryConfig.havings.push(obj);
|
|
393
|
+
}
|
|
394
|
+
deleteHavingsColume(i) {
|
|
395
|
+
this.queryBulderDataset.queryConfig.havings.splice(i, 1);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
DatasetQueryBulderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: DatasetQueryBulderComponent, deps: [{ token: i1.CommonService }, { token: i2.ToastrService }, { token: i3.ApplicationContentService }], target: i0.ɵɵFactoryTarget.Component });
|
|
399
|
+
DatasetQueryBulderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.3", type: DatasetQueryBulderComponent, selector: "app-dataset-query-bulder", inputs: { bulderDataset: "bulderDataset" }, outputs: { getQueryBulbderDataSet: "getQueryBulbderDataSet" }, ngImport: i0, template: "<div class=\"m-2\">\n <div class=\"flex flex-row mb-2\">\n <div class=\"mx-2 w-1/3\">\n <div class=\"text-md mb-2\">End Point</div>\n <dx-text-box [(ngModel)]=\"queryBulderDataset.api\"></dx-text-box>\n </div>\n <div class=\"mx-2 w-1/3\">\n <div class=\"text-md mb-2\">Query Type</div>\n <dx-select-box [dataSource]=\"['Aggregate','Basic']\" (onValueChanged)=\"getQueryForDetailsData($event)\">\n </dx-select-box>\n </div>\n <div class=\"mx-2 w-1/3 mt-6\" *ngIf=\"selectedDataSource == 'mongo'\">\n <dx-check-box [(ngModel)]=\"isReconColume\" text='Recon Column'>\n </dx-check-box>\n </div>\n </div>\n\n <div class=\"flex flex-col flex-auto min-w-0 my-3\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Request Params\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"grid grid-cols-2 gap-4 w-full p-2\">\n <div class=\"my-2 flex flex-row px-2 border-r\" *ngFor=\"let item of reqFieldsDataSource; let i = index;\">\n <div class=\"px-2 mb-2\">\n <div class=\"text-md mb-2\"> Params Name</div>\n <dx-text-box [(ngModel)]=\"item.name\"></dx-text-box>\n\n </div>\n <div class=\"px-2 mb-2\">\n <div class=\"text-md mb-2\"> Params Value </div>\n <ng-container *ngIf=\"item.name == 'dbConfig'\">\n <dx-select-box [items]=\"['mongo','impala','postgres','mysql','bigquery']\"\n (onValueChanged)=\"getDataConfig($event)\" [(ngModel)]=\"item.value\"></dx-select-box>\n </ng-container>\n <ng-container *ngIf=\"item.name !== 'dbConfig'\">\n <dx-text-box [(ngModel)]=\"item.value\"></dx-text-box>\n </ng-container>\n\n </div>\n <div class=\"px-2 mb-2\">\n <div class=\"text-center mt-8\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\" (click)=\"deleteParams(i)\"><i\n class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"flex flex-row my-2 justify-end\">\n <p class=\"text-sm italic text-gray-300 mr-6\">** Please Save Request Params Before Submit\n Dataset\n </p>\n <button class=\"{{commonService.btn_success_sm}} cursor-pointer\" (click)=\"saveParams()\">Save\n Params</button>\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addParams()\">Add\n Params</button>\n\n </div>\n </div>\n </div>\n\n <ng-container *ngIf=\"isQueryTypeSelect\">\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Columns and Measures\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex justify-between\"\n *ngFor=\"let item of queryBulderDataset.queryConfig.columns; let i = index;\">\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Measures</div>\n <dx-check-box [value]=\"item.measures\" [(ngModel)]=\"item.measures\"></dx-check-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Value Field(aliasName)</div>\n <dx-text-box [(ngModel)]=\"item.dataField\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Server Column Name</div>\n <dx-text-box [(ngModel)]=\"item.columnName\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Function Name</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"kpi_function\"\n [(ngModel)]=\"item.functionName\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Enrich Name</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"kpi_enrichment_name\"\n [(ngModel)]=\"item.enrichFunction\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Advanced Column</div>\n <dx-text-box [(ngModel)]=\"item.advancedColumn\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Caption</div>\n <dx-text-box [(ngModel)]=\"item.caption\"></dx-text-box>\n </div>\n <div class=\"px-1 mt-8\">\n <div class=\"flex flex-row\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForMeasuresColumns(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button *ngIf=\"i !== queryBulderDataset.queryConfig.columns.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForMeasuresColumns(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"px-1 mt-8 text-center\">\n\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\" (click)=\"deleteColumns(i)\"><i\n class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n <div class=\"flex flex-row justify-end my-2\">\n <p class=\"text-sm italic text-gray-300 mr-6\">** Please Save Columns And Measures Before Submit\n Dataset\n </p>\n <button class=\"{{commonService.btn_success_sm}} cursor-pointer\"\n (click)=\"saveColumnsAndMasures()\">Save\n Columns</button>\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addColumns()\">Add\n Columns</button>\n </div>\n </div>\n </div>\n\n\n <ng-container *ngIf=\"isReconColume\">\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Add Recon Column\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex justify-between\" *ngFor=\"let item of reconColumeDatasource; let i = index;\">\n\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Value Field(aliasName)</div>\n <dx-text-box [(ngModel)]=\"item.dataField\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> First Key</div>\n <dx-text-box [(ngModel)]=\"item.columeOne\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Second Key</div>\n <dx-text-box [(ngModel)]=\"item.columeTwo\"></dx-text-box>\n </div>\n\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Enrich Name</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"kpi_enrichment_name\"\n [(ngModel)]=\"item.enrichFunction\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Recon Type</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"['variance','percentage','absolute']\"\n [(ngModel)]=\"item.reconType\"></dx-select-box>\n </div>\n\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Caption</div>\n <dx-text-box [(ngModel)]=\"item.caption\"></dx-text-box>\n </div>\n\n <div class=\"px-1 mt-8 text-center\">\n\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\"\n (click)=\"deleteReconColume(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"flex flex-row justify-end my-2\">\n <button class=\"{{commonService.btn_success_sm}} cursor-pointer\"\n (click)=\"saveReconsColume()\">Save To\n Columns</button>\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addReconColume()\">Add\n </button>\n </div>\n </div>\n </div>\n\n </ng-container>\n\n <ng-container>\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Add Having Column\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex justify-between\"\n *ngFor=\"let item of queryBulderDataset.queryConfig.havings; let i = index;\">\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Column Name</div>\n <dx-text-box [(ngModel)]=\"item.columnName\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Advanced Column</div>\n <dx-text-box [(ngModel)]=\"item.advancedColumn\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Data Type</div>\n <dx-text-box [(ngModel)]=\"item.dataType\"></dx-text-box>\n </div>\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Operator</div>\n <dx-select-box [items]=\"['get','lte']\" [(ngModel)]=\"item.operator\"></dx-select-box>\n </div>\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Value</div>\n <dx-text-box [(ngModel)]=\"item.value\"></dx-text-box>\n </div>\n\n <div class=\"px-1 mt-8 text-center\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\"\n (click)=\"deleteHavingsColume(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"flex flex-row justify-end my-2\">\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addHavingsColume()\">Add\n Havings\n </button>\n </div>\n </div>\n </div>\n\n </ng-container>\n\n <div class=\"flex flex-col flex-auto min-w-0 my-3\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Sort By\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"grid grid-cols-2 gap-4 w-full p-2\">\n <div class=\"my-2 flex flex-row px-2 border-r\"\n *ngFor=\"let item of queryBulderDataset.queryConfig.sorters; let i = index;\">\n <div class=\"px-2 mb-2\">\n <div class=\"text-md mb-2\"> Params Name</div>\n <dx-text-box [(ngModel)]=\"item.columnName\"></dx-text-box>\n\n </div>\n <div class=\"px-2 mt-8\">\n\n <dx-check-box text=\"Descending\" [(ngModel)]=\"item.descending\"></dx-check-box>\n </div>\n <div class=\"px-2 mb-2\">\n <div class=\"text-center mt-8\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\"\n (click)=\"deleteShortColumns(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"flex flex-row my-2 justify-end\">\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addShortColumns()\">Add\n Column</button>\n\n </div>\n </div>\n </div>\n\n\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Filter Maping\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex flex-row justify-between\"\n *ngFor=\"let item of queryBulderDataset.queryConfig.mapedFilters; let i = index;\">\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Local Column</div>\n <dx-text-box [(ngModel)]=\"item.localColumn\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Server Column</div>\n <dx-text-box [(ngModel)]=\"item.serverColumn\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Operator</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"kpi_operator\"\n [(ngModel)]=\"item.operatorName\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Datatype</div>\n <dx-select-box [searchEnabled]=\"true\"\n [items]=\"['date','string','timestamp','int', 'double', 'boolean']\"\n [(ngModel)]=\"item.dataType\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Default Value</div>\n <dx-text-box [(ngModel)]=\"item.defaultValue\"></dx-text-box>\n </div>\n <div class=\"px-1 mt-8\">\n <div class=\"flex flex-row\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForColumns(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button *ngIf=\"i !== queryBulderDataset.queryConfig.mapedFilters.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForColumns(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"px-1 mt-8 text-center\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\"\n (click)=\"deleteFilterMapingColumns(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n <div class=\"flex flex-row\">\n <div class=\"w-1/2\" *ngIf=\"selectedDataSource !== 'mongo'\">\n <div class=\"flex flex-row justify-start my-2\">\n <button class=\"{{commonService.btnOthersPurple}} cursor-pointer\" (click)=\"checkForQuery()\">Check\n Query</button>\n </div>\n </div>\n <div class=\"w-full\">\n <div class=\"flex flex-row justify-end my-2\">\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\"\n (click)=\"addFilterMapingColumns()\">Add\n Maping</button>\n </div>\n </div>\n </div>\n\n </div>\n <div class=\"flex w-full justify-end mt-5 border-t\">\n <button class=\"{{commonService.btn_success_md}} cursor-pointer mx-1 my-2\" (click)=\"createDataSet()\">\n Submit DataSet\n </button>\n </div>\n </ng-container>\n\n\n</div>\n\n\n<ng-container *ngIf=\"isModelVisible\">\n <div class=\"fixed inset-0 flex items-center justify-center z-50 bg-black bg-opacity-50\">\n <div class=\"relative p-4 w-full max-w-3xl max-h-full\">\n <div class=\"relative bg-white rounded-lg shadow \">\n <div class=\"flex items-center justify-between p-4 md:p-5 border-b rounded-t \">\n <h3 class=\"text-xl font-semibold text-gray-900 \">\n Query </h3>\n <button type=\"button\" (click)=\"closeModalVisibleModal()\"\n class=\"text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center \"\n data-modal-hide=\"static-modal\">\n <svg class=\"w-3 h-3\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\"\n viewBox=\"0 0 14 14\">\n <path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6\" />\n </svg>\n <span class=\"sr-only\">Close</span>\n </button>\n </div>\n <!-- Modal body -->\n <div class=\"w-69 p-5\">\n <div class=\"flex flex-row bg-gray-800 text-white text-lg p-4 rounded-md text-wrap\">\n <code>\n {{query_data}}\n </code>\n </div>\n </div>\n <div class=\"flex items-center border-t border-gray-200 rounded-b p-2 justify-end\">\n <span class=\"text-gray-700 px-2\" *ngIf=\"isSqlCopiedText\">Copied</span>\n <button data-modal-hide=\"static-modal\" type=\"button\" class=\"{{commonService.btn_success_sm}} py-2\"\n (click)=\"copySqlFromModal()\">Copy</button>\n </div>\n </div>\n </div>\n </div>\n</ng-container>", 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: "component", type: i5.DxCheckBoxComponent, selector: "dx-check-box", inputs: ["accessKey", "activeStateEnabled", "disabled", "elementAttr", "focusStateEnabled", "height", "hint", "hoverStateEnabled", "iconSize", "isValid", "name", "readOnly", "rtlEnabled", "tabIndex", "text", "validationError", "validationErrors", "validationMessageMode", "validationStatus", "value", "visible", "width"], outputs: ["onContentReady", "onDisposing", "onInitialized", "onOptionChanged", "onValueChanged", "accessKeyChange", "activeStateEnabledChange", "disabledChange", "elementAttrChange", "focusStateEnabledChange", "heightChange", "hintChange", "hoverStateEnabledChange", "iconSizeChange", "isValidChange", "nameChange", "readOnlyChange", "rtlEnabledChange", "tabIndexChange", "textChange", "validationErrorChange", "validationErrorsChange", "validationMessageModeChange", "validationStatusChange", "valueChange", "visibleChange", "widthChange", "onBlur"] }, { kind: "component", type: i6.DxSelectBoxComponent, selector: "dx-select-box", inputs: ["acceptCustomValue", "accessKey", "activeStateEnabled", "buttons", "dataSource", "deferRendering", "disabled", "displayExpr", "displayValue", "dropDownButtonTemplate", "dropDownOptions", "elementAttr", "fieldTemplate", "focusStateEnabled", "grouped", "groupTemplate", "height", "hint", "hoverStateEnabled", "inputAttr", "isValid", "items", "itemTemplate", "label", "labelMode", "maxLength", "minSearchLength", "name", "noDataText", "opened", "openOnFieldClick", "placeholder", "readOnly", "rtlEnabled", "searchEnabled", "searchExpr", "searchMode", "searchTimeout", "selectedItem", "showClearButton", "showDataBeforeSearch", "showDropDownButton", "showSelectionControls", "spellcheck", "stylingMode", "tabIndex", "text", "useItemTextAsTitle", "validationError", "validationErrors", "validationMessageMode", "validationStatus", "value", "valueChangeEvent", "valueExpr", "visible", "width", "wrapItemText"], outputs: ["onChange", "onClosed", "onContentReady", "onCopy", "onCustomItemCreating", "onCut", "onDisposing", "onEnterKey", "onFocusIn", "onFocusOut", "onInitialized", "onInput", "onItemClick", "onKeyDown", "onKeyUp", "onOpened", "onOptionChanged", "onPaste", "onSelectionChanged", "onValueChanged", "acceptCustomValueChange", "accessKeyChange", "activeStateEnabledChange", "buttonsChange", "dataSourceChange", "deferRenderingChange", "disabledChange", "displayExprChange", "displayValueChange", "dropDownButtonTemplateChange", "dropDownOptionsChange", "elementAttrChange", "fieldTemplateChange", "focusStateEnabledChange", "groupedChange", "groupTemplateChange", "heightChange", "hintChange", "hoverStateEnabledChange", "inputAttrChange", "isValidChange", "itemsChange", "itemTemplateChange", "labelChange", "labelModeChange", "maxLengthChange", "minSearchLengthChange", "nameChange", "noDataTextChange", "openedChange", "openOnFieldClickChange", "placeholderChange", "readOnlyChange", "rtlEnabledChange", "searchEnabledChange", "searchExprChange", "searchModeChange", "searchTimeoutChange", "selectedItemChange", "showClearButtonChange", "showDataBeforeSearchChange", "showDropDownButtonChange", "showSelectionControlsChange", "spellcheckChange", "stylingModeChange", "tabIndexChange", "textChange", "useItemTextAsTitleChange", "validationErrorChange", "validationErrorsChange", "validationMessageModeChange", "validationStatusChange", "valueChange", "valueChangeEventChange", "valueExprChange", "visibleChange", "widthChange", "wrapItemTextChange", "onBlur"] }, { kind: "component", type: i7.DxTextBoxComponent, selector: "dx-text-box", inputs: ["accessKey", "activeStateEnabled", "buttons", "disabled", "elementAttr", "focusStateEnabled", "height", "hint", "hoverStateEnabled", "inputAttr", "isValid", "label", "labelMode", "mask", "maskChar", "maskInvalidMessage", "maskRules", "maxLength", "mode", "name", "placeholder", "readOnly", "rtlEnabled", "showClearButton", "showMaskMode", "spellcheck", "stylingMode", "tabIndex", "text", "useMaskedValue", "validationError", "validationErrors", "validationMessageMode", "validationStatus", "value", "valueChangeEvent", "visible", "width"], outputs: ["onChange", "onContentReady", "onCopy", "onCut", "onDisposing", "onEnterKey", "onFocusIn", "onFocusOut", "onInitialized", "onInput", "onKeyDown", "onKeyUp", "onOptionChanged", "onPaste", "onValueChanged", "accessKeyChange", "activeStateEnabledChange", "buttonsChange", "disabledChange", "elementAttrChange", "focusStateEnabledChange", "heightChange", "hintChange", "hoverStateEnabledChange", "inputAttrChange", "isValidChange", "labelChange", "labelModeChange", "maskChange", "maskCharChange", "maskInvalidMessageChange", "maskRulesChange", "maxLengthChange", "modeChange", "nameChange", "placeholderChange", "readOnlyChange", "rtlEnabledChange", "showClearButtonChange", "showMaskModeChange", "spellcheckChange", "stylingModeChange", "tabIndexChange", "textChange", "useMaskedValueChange", "validationErrorChange", "validationErrorsChange", "validationMessageModeChange", "validationStatusChange", "valueChange", "valueChangeEventChange", "visibleChange", "widthChange", "onBlur"] }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
400
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: DatasetQueryBulderComponent, decorators: [{
|
|
401
|
+
type: Component,
|
|
402
|
+
args: [{ selector: 'app-dataset-query-bulder', template: "<div class=\"m-2\">\n <div class=\"flex flex-row mb-2\">\n <div class=\"mx-2 w-1/3\">\n <div class=\"text-md mb-2\">End Point</div>\n <dx-text-box [(ngModel)]=\"queryBulderDataset.api\"></dx-text-box>\n </div>\n <div class=\"mx-2 w-1/3\">\n <div class=\"text-md mb-2\">Query Type</div>\n <dx-select-box [dataSource]=\"['Aggregate','Basic']\" (onValueChanged)=\"getQueryForDetailsData($event)\">\n </dx-select-box>\n </div>\n <div class=\"mx-2 w-1/3 mt-6\" *ngIf=\"selectedDataSource == 'mongo'\">\n <dx-check-box [(ngModel)]=\"isReconColume\" text='Recon Column'>\n </dx-check-box>\n </div>\n </div>\n\n <div class=\"flex flex-col flex-auto min-w-0 my-3\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Request Params\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"grid grid-cols-2 gap-4 w-full p-2\">\n <div class=\"my-2 flex flex-row px-2 border-r\" *ngFor=\"let item of reqFieldsDataSource; let i = index;\">\n <div class=\"px-2 mb-2\">\n <div class=\"text-md mb-2\"> Params Name</div>\n <dx-text-box [(ngModel)]=\"item.name\"></dx-text-box>\n\n </div>\n <div class=\"px-2 mb-2\">\n <div class=\"text-md mb-2\"> Params Value </div>\n <ng-container *ngIf=\"item.name == 'dbConfig'\">\n <dx-select-box [items]=\"['mongo','impala','postgres','mysql','bigquery']\"\n (onValueChanged)=\"getDataConfig($event)\" [(ngModel)]=\"item.value\"></dx-select-box>\n </ng-container>\n <ng-container *ngIf=\"item.name !== 'dbConfig'\">\n <dx-text-box [(ngModel)]=\"item.value\"></dx-text-box>\n </ng-container>\n\n </div>\n <div class=\"px-2 mb-2\">\n <div class=\"text-center mt-8\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\" (click)=\"deleteParams(i)\"><i\n class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"flex flex-row my-2 justify-end\">\n <p class=\"text-sm italic text-gray-300 mr-6\">** Please Save Request Params Before Submit\n Dataset\n </p>\n <button class=\"{{commonService.btn_success_sm}} cursor-pointer\" (click)=\"saveParams()\">Save\n Params</button>\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addParams()\">Add\n Params</button>\n\n </div>\n </div>\n </div>\n\n <ng-container *ngIf=\"isQueryTypeSelect\">\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Columns and Measures\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex justify-between\"\n *ngFor=\"let item of queryBulderDataset.queryConfig.columns; let i = index;\">\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Measures</div>\n <dx-check-box [value]=\"item.measures\" [(ngModel)]=\"item.measures\"></dx-check-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Value Field(aliasName)</div>\n <dx-text-box [(ngModel)]=\"item.dataField\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Server Column Name</div>\n <dx-text-box [(ngModel)]=\"item.columnName\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Function Name</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"kpi_function\"\n [(ngModel)]=\"item.functionName\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Enrich Name</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"kpi_enrichment_name\"\n [(ngModel)]=\"item.enrichFunction\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Advanced Column</div>\n <dx-text-box [(ngModel)]=\"item.advancedColumn\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Caption</div>\n <dx-text-box [(ngModel)]=\"item.caption\"></dx-text-box>\n </div>\n <div class=\"px-1 mt-8\">\n <div class=\"flex flex-row\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForMeasuresColumns(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button *ngIf=\"i !== queryBulderDataset.queryConfig.columns.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForMeasuresColumns(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"px-1 mt-8 text-center\">\n\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\" (click)=\"deleteColumns(i)\"><i\n class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n <div class=\"flex flex-row justify-end my-2\">\n <p class=\"text-sm italic text-gray-300 mr-6\">** Please Save Columns And Measures Before Submit\n Dataset\n </p>\n <button class=\"{{commonService.btn_success_sm}} cursor-pointer\"\n (click)=\"saveColumnsAndMasures()\">Save\n Columns</button>\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addColumns()\">Add\n Columns</button>\n </div>\n </div>\n </div>\n\n\n <ng-container *ngIf=\"isReconColume\">\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Add Recon Column\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex justify-between\" *ngFor=\"let item of reconColumeDatasource; let i = index;\">\n\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Value Field(aliasName)</div>\n <dx-text-box [(ngModel)]=\"item.dataField\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> First Key</div>\n <dx-text-box [(ngModel)]=\"item.columeOne\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Second Key</div>\n <dx-text-box [(ngModel)]=\"item.columeTwo\"></dx-text-box>\n </div>\n\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Enrich Name</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"kpi_enrichment_name\"\n [(ngModel)]=\"item.enrichFunction\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Recon Type</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"['variance','percentage','absolute']\"\n [(ngModel)]=\"item.reconType\"></dx-select-box>\n </div>\n\n <div class=\"px-1 mb-2\">\n <div class=\"text-md mb-2\"> Caption</div>\n <dx-text-box [(ngModel)]=\"item.caption\"></dx-text-box>\n </div>\n\n <div class=\"px-1 mt-8 text-center\">\n\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\"\n (click)=\"deleteReconColume(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"flex flex-row justify-end my-2\">\n <button class=\"{{commonService.btn_success_sm}} cursor-pointer\"\n (click)=\"saveReconsColume()\">Save To\n Columns</button>\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addReconColume()\">Add\n </button>\n </div>\n </div>\n </div>\n\n </ng-container>\n\n <ng-container>\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Add Having Column\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex justify-between\"\n *ngFor=\"let item of queryBulderDataset.queryConfig.havings; let i = index;\">\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Column Name</div>\n <dx-text-box [(ngModel)]=\"item.columnName\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Advanced Column</div>\n <dx-text-box [(ngModel)]=\"item.advancedColumn\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Data Type</div>\n <dx-text-box [(ngModel)]=\"item.dataType\"></dx-text-box>\n </div>\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Operator</div>\n <dx-select-box [items]=\"['get','lte']\" [(ngModel)]=\"item.operator\"></dx-select-box>\n </div>\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Value</div>\n <dx-text-box [(ngModel)]=\"item.value\"></dx-text-box>\n </div>\n\n <div class=\"px-1 mt-8 text-center\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\"\n (click)=\"deleteHavingsColume(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"flex flex-row justify-end my-2\">\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addHavingsColume()\">Add\n Havings\n </button>\n </div>\n </div>\n </div>\n\n </ng-container>\n\n <div class=\"flex flex-col flex-auto min-w-0 my-3\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Sort By\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"grid grid-cols-2 gap-4 w-full p-2\">\n <div class=\"my-2 flex flex-row px-2 border-r\"\n *ngFor=\"let item of queryBulderDataset.queryConfig.sorters; let i = index;\">\n <div class=\"px-2 mb-2\">\n <div class=\"text-md mb-2\"> Params Name</div>\n <dx-text-box [(ngModel)]=\"item.columnName\"></dx-text-box>\n\n </div>\n <div class=\"px-2 mt-8\">\n\n <dx-check-box text=\"Descending\" [(ngModel)]=\"item.descending\"></dx-check-box>\n </div>\n <div class=\"px-2 mb-2\">\n <div class=\"text-center mt-8\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\"\n (click)=\"deleteShortColumns(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"flex flex-row my-2 justify-end\">\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\" (click)=\"addShortColumns()\">Add\n Column</button>\n\n </div>\n </div>\n </div>\n\n\n <div class=\"flex flex-col flex-auto min-w-0 my-2\">\n <div class=\"text-lg py-2 font-extrabold border-b bg-gray-700 text-white px-2\"> Filter Maping\n </div>\n <div class=\"pt-2 border-x border-b \">\n <div class=\"my-2 flex flex-row justify-between\"\n *ngFor=\"let item of queryBulderDataset.queryConfig.mapedFilters; let i = index;\">\n\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Local Column</div>\n <dx-text-box [(ngModel)]=\"item.localColumn\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Server Column</div>\n <dx-text-box [(ngModel)]=\"item.serverColumn\"></dx-text-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Operator</div>\n <dx-select-box [searchEnabled]=\"true\" [items]=\"kpi_operator\"\n [(ngModel)]=\"item.operatorName\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Datatype</div>\n <dx-select-box [searchEnabled]=\"true\"\n [items]=\"['date','string','timestamp','int', 'double', 'boolean']\"\n [(ngModel)]=\"item.dataType\"></dx-select-box>\n </div>\n <div class=\"px-1 mb-2 w-full\">\n <div class=\"text-md mb-2\"> Default Value</div>\n <dx-text-box [(ngModel)]=\"item.defaultValue\"></dx-text-box>\n </div>\n <div class=\"px-1 mt-8\">\n <div class=\"flex flex-row\">\n <button *ngIf=\"i !== 0\" class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForColumns(i, 'up')\">\n <i class=\"fa fa-arrow-up\" aria-hidden=\"true\"></i>\n </button>\n\n <button *ngIf=\"i !== queryBulderDataset.queryConfig.mapedFilters.length - 1\"\n class=\"{{commonService.btn_light_sm}} cursor-pointer mx-1\"\n (click)=\"moveItemForColumns(i, 'down')\">\n <i class=\"fa fa-arrow-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n <div class=\"px-1 mt-8 text-center\">\n <button class=\"{{commonService.btn_danger_sm}} cursor-pointer\"\n (click)=\"deleteFilterMapingColumns(i)\"><i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n <div class=\"flex flex-row\">\n <div class=\"w-1/2\" *ngIf=\"selectedDataSource !== 'mongo'\">\n <div class=\"flex flex-row justify-start my-2\">\n <button class=\"{{commonService.btnOthersPurple}} cursor-pointer\" (click)=\"checkForQuery()\">Check\n Query</button>\n </div>\n </div>\n <div class=\"w-full\">\n <div class=\"flex flex-row justify-end my-2\">\n <button class=\"{{commonService.btn_primary_sm}} cursor-pointer\"\n (click)=\"addFilterMapingColumns()\">Add\n Maping</button>\n </div>\n </div>\n </div>\n\n </div>\n <div class=\"flex w-full justify-end mt-5 border-t\">\n <button class=\"{{commonService.btn_success_md}} cursor-pointer mx-1 my-2\" (click)=\"createDataSet()\">\n Submit DataSet\n </button>\n </div>\n </ng-container>\n\n\n</div>\n\n\n<ng-container *ngIf=\"isModelVisible\">\n <div class=\"fixed inset-0 flex items-center justify-center z-50 bg-black bg-opacity-50\">\n <div class=\"relative p-4 w-full max-w-3xl max-h-full\">\n <div class=\"relative bg-white rounded-lg shadow \">\n <div class=\"flex items-center justify-between p-4 md:p-5 border-b rounded-t \">\n <h3 class=\"text-xl font-semibold text-gray-900 \">\n Query </h3>\n <button type=\"button\" (click)=\"closeModalVisibleModal()\"\n class=\"text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center \"\n data-modal-hide=\"static-modal\">\n <svg class=\"w-3 h-3\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\"\n viewBox=\"0 0 14 14\">\n <path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n d=\"m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6\" />\n </svg>\n <span class=\"sr-only\">Close</span>\n </button>\n </div>\n <!-- Modal body -->\n <div class=\"w-69 p-5\">\n <div class=\"flex flex-row bg-gray-800 text-white text-lg p-4 rounded-md text-wrap\">\n <code>\n {{query_data}}\n </code>\n </div>\n </div>\n <div class=\"flex items-center border-t border-gray-200 rounded-b p-2 justify-end\">\n <span class=\"text-gray-700 px-2\" *ngIf=\"isSqlCopiedText\">Copied</span>\n <button data-modal-hide=\"static-modal\" type=\"button\" class=\"{{commonService.btn_success_sm}} py-2\"\n (click)=\"copySqlFromModal()\">Copy</button>\n </div>\n </div>\n </div>\n </div>\n</ng-container>" }]
|
|
403
|
+
}], ctorParameters: function () { return [{ type: i1.CommonService }, { type: i2.ToastrService }, { type: i3.ApplicationContentService }]; }, propDecorators: { getQueryBulbderDataSet: [{
|
|
404
|
+
type: Output
|
|
405
|
+
}], bulderDataset: [{
|
|
406
|
+
type: Input,
|
|
407
|
+
args: ['bulderDataset']
|
|
408
|
+
}] } });
|
|
409
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNldC1xdWVyeS1idWxkZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2FtbWEtYXBwLWNvbnRyb2xsZXIvc3JjL2xpYi9hcHBsaWNhdGlvbi1jb250cm9sbGVyL2FwcGxpY2F0aW9uLWRhdGFzZXQtY29tcG9uZW50L2RhdGFzZXQtcXVlcnktYnVsZGVyL2RhdGFzZXQtcXVlcnktYnVsZGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2dhbW1hLWFwcC1jb250cm9sbGVyL3NyYy9saWIvYXBwbGljYXRpb24tY29udHJvbGxlci9hcHBsaWNhdGlvbi1kYXRhc2V0LWNvbXBvbmVudC9kYXRhc2V0LXF1ZXJ5LWJ1bGRlci9kYXRhc2V0LXF1ZXJ5LWJ1bGRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7Ozs7Ozs7O0FBVS9FLE1BQU0sT0FBTywyQkFBMkI7SUEwRnRDLFlBQW1CLGFBQTRCLEVBQVUsTUFBcUIsRUFBVSxPQUFrQztRQUF2RyxrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUFVLFdBQU0sR0FBTixNQUFNLENBQWU7UUFBVSxZQUFPLEdBQVAsT0FBTyxDQUEyQjtRQXZGMUgsd0JBQW1CLEdBQVEsRUFBRSxDQUFDO1FBQzlCLGdCQUFXLEdBQVksS0FBSyxDQUFDO1FBQzdCLGdCQUFXLEdBQVksS0FBSyxDQUFDO1FBQzdCLHdCQUFtQixHQUFRLEVBQUUsQ0FBQztRQUM5QixpQkFBWSxHQUFRLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQTtRQUNyRixpQkFBWSxHQUFRLENBQUMs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OlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVG9hc3RyU2VydmljZSB9IGZyb20gJ25neC10b2FzdHInO1xuaW1wb3J0IHsgQXBwbGljYXRpb25Db250ZW50U2VydmljZSB9IGZyb20gJy4uLy4uL2FwcGxpY2F0aW9uLWNvbnRlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBDb21tb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29tbW9uJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWRhdGFzZXQtcXVlcnktYnVsZGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2RhdGFzZXQtcXVlcnktYnVsZGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZGF0YXNldC1xdWVyeS1idWxkZXIuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBEYXRhc2V0UXVlcnlCdWxkZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIC8vIEBJbnB1dCgpIHF1ZXJ5QnVsZGVyRGF0YXNldDogYW55O1xuICByZXFGaWVsZHNEYXRhU291cmNlOiBhbnkgPSBbXTtcbiAgaXNyZXFGaWVsZHM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNjZHJQYXJhbXM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgY2RyRmllbGRzRGF0YVNvdXJjZTogYW55ID0gW107XG4gIGtwaV9mdW5jdGlvbjogYW55ID0gW1wic3VtXCIsIFwiY291bnRcIiwgXCJhdmdcIiwgXCJtYXhcIiwgXCJtaW5cIiwgXCJzdGRkZXZcIiwgXCJjb3VudF9kaXN0aW5jdFwiXVxuICBrcGlfb3BlcmF0b3I6IGFueSA9IFtcImVxXCIsIFwiZ3RlXCIsIFwibHRlXCIsIFwibmVcIiwgXCJpblwiLCBcIm5vdEluXCIsIFwiY29udGFpbnNcIiwgXCJzdGFydHNXaXRoXCIsIFwiZW5kc1dpdGhcIl1cbiAga3BpX2VucmljaG1lbnRfbmFtZTogYW55ID0gW107XG4gIHJlcVNob3J0RGF0YVNvdXJjZTogYW55ID0gW107XG4gIGZpbHRlck1hcGluZ0RhdGFzb3VyY2U6IGFueSA9IFtdO1xuICBxdWVyeV9kYXRhOiBhbnk7XG4gIGlzTW9kZWxWaXNpYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIGlzU3FsQ29waWVkVGV4dDogYm9vbGVhbiA9IGZhbHNlO1xuICBxdWVyeUJ1bGRlckRhdGFzZXQ6IGFueTtcbiAgaXNSZWNvbkNvbHVtZTogYm9vbGVhbiA9IGZhbHNlO1xuICBAT3V0cHV0KCkgcHVibGljIGdldFF1ZXJ5QnVsYmRlckRhdGFTZXQ6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHJlY29uQ29sdW1lRGF0YXNvdXJjZSA9IFtdO1xuXG4gIHNlbGVjdGVkRGF0YVNvdXJjZTogYW55O1xuICBpc1F1ZXJ5VHlwZVNlbGVjdDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBJbnB1dCgnYnVsZGVyRGF0YXNldCcpXG4gIHNldCBidWxkZXJEYXRhc2V0KHZhbHVlKSB7XG5cbiAgICBpZiAodmFsdWUucXVlcnlDb25maWcucmVxRmllbGRzICYmIHZhbHVlLnF1ZXJ5Q29uZmlnLnJlcUZpZWxkcy5sZW5ndGggPCAyKSB7XG4gICAgICB0aGlzLnJlcUZpZWxkc0RhdGFTb3VyY2UgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJwYWdlTnVtYmVyXCIsXG4gICAgICAgICAgXCJ2YWx1ZVwiOiAxLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgXCJuYW1lXCI6IFwicGFnZVNpemVcIixcbiAgICAgICAgICBcInZhbHVlXCI6IDIwMTAsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBcIm5hbWVcIjogXCJkYkNvbmZpZ1wiLFxuICAgICAgICAgIFwidmFsdWVcIjogXCJcIixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcImRhdGFiYXNlTmFtZVwiLFxuICAgICAgICAgIFwidmFsdWVcIjogXCJcIixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcInRhYmxlTmFtZVwiLFxuICAgICAgICAgIFwidmFsdWVcIjogXCJcIixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwibmFtZVwiOiBcInBhZ2luYXRpb25SZXF1aXJlZFwiLFxuICAgICAgICAgIFwidmFsdWVcIjogXCJmYWxzZVwiLFxuICAgICAgICB9XG4gICAgICBdXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVxRmllbGRzRGF0YVNvdXJjZSA9IHRoaXMucHJvY2Vzc1BhcmFtc2Zvcm1hdERhdGEodmFsdWUucXVlcnlDb25maWcucmVxRmllbGRzKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRhU291cmNlID0gdmFsdWUucXVlcnlDb25maWcucmVxRmllbGRzLmZpbmQoaXRlbSA9PiBpdGVtLmRiQ29uZmlnICE9PSB1bmRlZmluZWQpPy5kYkNvbmZpZztcbiAgICAgIHRoaXMuaXNRdWVyeVR5cGVTZWxlY3QgPSB0cnVlO1xuICAgIH1cbiAgICBpZiAodmFsdWUucXVlcnlDb25maWcubWFwZWRGaWx0ZXJzID09IHVuZGVmaW5lZCkge1xuICAgICAgdmFsdWUucXVlcnlDb25maWcubWFwZWRGaWx0ZXJzID0gW107XG4gICAgICB2YWx1ZS5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnMucHVzaCh7IFwibG9jYWxDb2x1bW5cIjogXCJcIiwgXCJzZXJ2ZXJDb2x1bW5cIjogXCJcIiwgXCJvcGVyYXRvck5hbWVcIjogXCJcIiwgXCJkZWZhdWx0VmFsdWVcIjogXCJcIiwgXCJkYXRhVHlwZVwiOiBcIlwiIH0pXG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLnF1ZXJ5Q29uZmlnLnNvcnRlcnMgPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YWx1ZS5xdWVyeUNvbmZpZy5zb3J0ZXJzID0gW107XG4gICAgICB2YWx1ZS5xdWVyeUNvbmZpZy5zb3J0ZXJzLnB1c2goeyBcImNvbHVtbk5hbWVcIjogXCJcIiwgXCJkZXNjZW5kaW5nXCI6IGZhbHNlIH0pXG4gICAgfVxuICAgIGlmICh2YWx1ZS5xdWVyeUNvbmZpZy5jb2x1bW5zID09IHVuZGVmaW5lZCkge1xuICAgICAgdmFsdWUucXVlcnlDb25maWcuY29sdW1ucyA9IFtdO1xuICAgICAgbGV0IG9iaiA9IHtcbiAgICAgICAgXCJtZWFzdXJlc1wiOiB0cnVlLFxuICAgICAgICBcImRhdGFGaWVsZFwiOiBcIlwiLFxuICAgICAgICBcImNvbHVtbk5hbWVcIjogXCJcIixcbiAgICAgICAgXCJmdW5jdGlvbk5hbWVcIjogXCJcIixcbiAgICAgICAgXCJlbnJpY2hGdW5jdGlvblwiOiBcIlwiLFxuICAgICAgICBcImFkdmFuY2VkQ29sdW1uXCI6IFwiXCIsXG4gICAgICAgIFwiY2FwdGlvblwiOiBcIlwiLFxuICAgICAgfVxuICAgICAgdmFsdWUucXVlcnlDb25maWcuY29sdW1ucy5wdXNoKG9iaik7XG4gICAgfVxuICAgIGlmICh2YWx1ZS5xdWVyeUNvbmZpZy5oYXZpbmdzID09IHVuZGVmaW5lZCkge1xuICAgICAgdmFsdWUucXVlcnlDb25maWcuaGF2aW5ncyA9IFtdO1xuICAgIH1cblxuXG4gICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQgPSB2YWx1ZTtcbiAgfVxuXG5cbiAgY29uc3RydWN0b3IocHVibGljIGNvbW1vblNlcnZpY2U6IENvbW1vblNlcnZpY2UsIHByaXZhdGUgdG9hc3RyOiBUb2FzdHJTZXJ2aWNlLCBwcml2YXRlIHNlcnZpY2U6IEFwcGxpY2F0aW9uQ29udGVudFNlcnZpY2UpIHsgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc2VydmljZS5saXN0Q29sdW1uRW5yaWNobWVudEZ1bmN0aW9ucygpLnN1YnNjcmliZShkYXRhID0+IHtcbiAgICAgIHRoaXMua3BpX2VucmljaG1lbnRfbmFtZSA9IGRhdGE7XG4gICAgfSlcblxuICAgIHRoaXMucmVjb25Db2x1bWVEYXRhc291cmNlID0gW1xuICAgICAge1xuICAgICAgICBcImRhdGFGaWVsZFwiOiBcIlwiLFxuICAgICAgICBcImVucmljaEZ1bmN0aW9uXCI6IFwiXCIsXG4gICAgICAgIFwiY29sdW1lT25lXCI6IFwiXCIsXG4gICAgICAgIFwiY29sdW1lVHdvXCI6IFwiXCIsXG4gICAgICAgIFwicmVjb25UeXBlXCI6IFwiXCIsXG4gICAgICAgIFwiY2FwdGlvblwiOiBcIlwiXG4gICAgICB9XG4gICAgXVxuICB9XG5cbiAgcHJvY2Vzc1BhcmFtc2Zvcm1hdERhdGEoZGF0YSkge1xuICAgIGNvbnN0IGZvcm1hdHRlZF9kYXRhID0gZGF0YS5tYXAoaXRlbSA9PiB7XG4gICAgICBjb25zdCBbbmFtZSwgdmFsdWVdID0gT2JqZWN0LmVudHJpZXMoaXRlbSlbMF07XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIHZhbHVlOiBuYW1lID09PSAncGFnaW5hdGlvblJlcXVpcmVkJyA/IHZhbHVlLnRvU3RyaW5nKCkgOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHJldHVybiBmb3JtYXR0ZWRfZGF0YTtcbiAgfVxuXG5cblxuICBhZGRDb2x1bW5zKCkge1xuICAgIGxldCBvYmogPSB7XG4gICAgICBcIm1lYXN1cmVzXCI6IHRydWUsXG4gICAgICBcImRhdGFGaWVsZFwiOiBcIlwiLFxuICAgICAgXCJjb2x1bW5OYW1lXCI6IFwiXCIsXG4gICAgICBcImZ1bmN0aW9uTmFtZVwiOiBcIlwiLFxuICAgICAgXCJhZHZhbmNlZENvbHVtblwiOiBcIlwiLFxuICAgICAgXCJlbnJpY2hGdW5jdGlvblwiOiBcIlwiLFxuICAgICAgXCJjYXB0aW9uXCI6IFwiXCIsXG4gICAgfVxuICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLmNvbHVtbnMucHVzaChvYmopO1xuICB9XG5cblxuICBkZWxldGVDb2x1bW5zKGkpIHtcbiAgICB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5jb2x1bW5zLnNwbGljZShpLCAxKVxuICB9XG5cbiAgYWRkUmVjb25Db2x1bWUoKSB7XG4gICAgbGV0IG9iaiA9IHtcbiAgICAgIFwiZGF0YUZpZWxkXCI6IFwiXCIsXG4gICAgICBcImNvbHVtZU9uZVwiOiBcIlwiLFxuICAgICAgXCJjb2x1bWVUd29cIjogXCJcIixcbiAgICAgIFwiZW5yaWNoRnVuY3Rpb25cIjogXCJcIixcbiAgICAgIFwicmVjb25UeXBlXCI6IFwiXCIsXG4gICAgICBcImNhcHRpb25cIjogXCJcIlxuICAgIH1cbiAgICB0aGlzLnJlY29uQ29sdW1lRGF0YXNvdXJjZS5wdXNoKG9iaik7XG4gIH1cblxuICBkZWxldGVSZWNvbkNvbHVtZShpKSB7XG4gICAgdGhpcy5yZWNvbkNvbHVtZURhdGFzb3VyY2Uuc3BsaWNlKGksIDEpXG4gIH1cblxuICBzYXZlUmVjb25zQ29sdW1lKCkge1xuICAgIC8vIHsgJyRkaXZpZGUnOiBbeyAnJHN1YnRyYWN0JzogWyckY2JzQ291bnQnLCAnJG1zY0NvdW50J10gfSwgJyRjYnNDb3VudCddIH1cbiAgICAvLyB7ICckc3VidHJhY3QnOiBbJyRjYnNNb3UnLCAnJG1zY01vdSddIH1cblxuICAgIHRoaXMucmVjb25Db2x1bWVEYXRhc291cmNlLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICBpZiAoZWxlbWVudC5yZWNvblR5cGUgPT0gXCJ2YXJpYW5jZVwiKSB7XG4gICAgICAgIGxldCBjb2x1bWVTdHJpbmcgPSBcInsnJHN1YnRyYWN0JzogWyckXCIgKyBlbGVtZW50LmNvbHVtZU9uZSArIFwiJywnJFwiICsgZWxlbWVudC5jb2x1bWVUd28gKyBcIiddfVwiO1xuICAgICAgICBsZXQgbm9kZSA9IHtcbiAgICAgICAgICBcIm1lYXN1cmVzXCI6IHRydWUsXG4gICAgICAgICAgXCJkYXRhRmllbGRcIjogZWxlbWVudC5kYXRhRmllbGQsXG4gICAgICAgICAgXCJjb2x1bW5OYW1lXCI6IGVsZW1lbnQuZGF0YUZpZWxkLFxuICAgICAgICAgIFwiZnVuY3Rpb25OYW1lXCI6IFwiXCIsXG4gICAgICAgICAgXCJhZHZhbmNlZENvbHVtblwiOiBjb2x1bWVTdHJpbmcsXG4gICAgICAgICAgXCJlbnJpY2hGdW5jdGlvblwiOiBlbGVtZW50LmVucmljaEZ1bmN0aW9uLFxuICAgICAgICAgIFwiY2FwdGlvblwiOiBlbGVtZW50LmNhcHRpb24sXG4gICAgICAgICAgJ2Rlcml2ZUZpZWxkJzogdHJ1ZVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLmNvbHVtbnMucHVzaChub2RlKVxuICAgICAgICBjb25zb2xlLmxvZyhjb2x1bWVTdHJpbmcpO1xuICAgICAgfSBlbHNlIGlmIChlbGVtZW50LnJlY29uVHlwZSA9PSBcInBlcmNlbnRhZ2VcIikge1xuICAgICAgICBsZXQgY29sdW1lU3RyaW5nID0gXCJ7JyRjb25kJzogeyBpZjogeyAkZXE6IFsgJyRcIiArIGVsZW1lbnQuY29sdW1lT25lICsgXCInLCAwIF0gfSwgdGhlbjogMCwgZWxzZTogeyckZGl2aWRlJzpbeyckc3VidHJhY3QnOiBbJyRcIiArIGVsZW1lbnQuY29sdW1lT25lICsgXCInLCckXCIgKyBlbGVtZW50LmNvbHVtZVR3byArIFwiJ119LCckXCIgKyBlbGVtZW50LmNvbHVtZU9uZSArIFwiJ119IH19XCI7XG4gICAgICAgIGxldCBub2RlID0ge1xuICAgICAgICAgIFwibWVhc3VyZXNcIjogdHJ1ZSxcbiAgICAgICAgICBcImRhdGFGaWVsZFwiOiBlbGVtZW50LmRhdGFGaWVsZCxcbiAgICAgICAgICBcImNvbHVtbk5hbWVcIjogZWxlbWVudC5kYXRhRmllbGQsXG4gICAgICAgICAgXCJmdW5jdGlvbk5hbWVcIjogXCJcIixcbiAgICAgICAgICBcImFkdmFuY2VkQ29sdW1uXCI6IGNvbHVtZVN0cmluZyxcbiAgICAgICAgICBcImVucmljaEZ1bmN0aW9uXCI6IGVsZW1lbnQuZW5yaWNoRnVuY3Rpb24sXG4gICAgICAgICAgXCJjYXB0aW9uXCI6IGVsZW1lbnQuY2FwdGlvbixcbiAgICAgICAgICAnZGVyaXZlRmllbGQnOiB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuY29sdW1ucy5wdXNoKG5vZGUpXG4gICAgICB9IGVsc2UgaWYgKGVsZW1lbnQucmVjb25UeXBlID09IFwiYWJzb2x1dGVcIikge1xuICAgICAgICBsZXQgY29sdW1lU3RyaW5nID0gXCJ7JyRhYnMnOiB7JyRjb25kJzogeyBpZjogeyAkZXE6IFsgJyRcIiArIGVsZW1lbnQuY29sdW1lT25lICsgXCInLCAwIF0gfSwgdGhlbjogMCwgZWxzZTogeyckZGl2aWRlJzogW3snJHN1YnRyYWN0JzogWyckXCIgKyBlbGVtZW50LmNvbHVtZU9uZSArIFwiJywgJyRcIiArIGVsZW1lbnQuY29sdW1lVHdvICsgXCInXX0sICckXCIgKyBlbGVtZW50LmNvbHVtZU9uZSArIFwiJ119fX19XCI7XG4gICAgICAgIGxldCBub2RlID0ge1xuICAgICAgICAgIFwibWVhc3VyZXNcIjogdHJ1ZSxcbiAgICAgICAgICBcImRhdGFGaWVsZFwiOiBlbGVtZW50LmRhdGFGaWVsZCxcbiAgICAgICAgICBcImNvbHVtbk5hbWVcIjogZWxlbWVudC5kYXRhRmllbGQsXG4gICAgICAgICAgXCJmdW5jdGlvbk5hbWVcIjogXCJcIixcbiAgICAgICAgICBcImFkdmFuY2VkQ29sdW1uXCI6IGNvbHVtZVN0cmluZyxcbiAgICAgICAgICBcImVucmljaEZ1bmN0aW9uXCI6IGVsZW1lbnQuZW5yaWNoRnVuY3Rpb24sXG4gICAgICAgICAgXCJjYXB0aW9uXCI6IGVsZW1lbnQuY2FwdGlvbixcbiAgICAgICAgICAnZGVyaXZlRmllbGQnOiB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuY29sdW1ucy5wdXNoKG5vZGUpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG5cbiAgc2F2ZUNvbHVtbnNBbmRNYXN1cmVzKCkge1xuICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLm1lYXN1cmVzID0gW107XG4gICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuZGltZW5zaW9ucyA9IFtdO1xuICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLmNvbHVtbnMuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgIC8vIENoZWNrIGlmIGVsZW1lbnQuYWR2YW5jZWRDb2x1bW4gaXMgYW4gZW1wdHkgc3RyaW5nIGFuZCBzZXQgaXQgdG8gbnVsbFxuICAgICAgY29uc3QgYWR2YW5jZWRDb2x1bW5WYWx1ZSA9IGVsZW1lbnQuYWR2YW5jZWRDb2x1bW4gPT09IFwiXCIgPyBudWxsIDogZWxlbWVudC5hZHZhbmNlZENvbHVtbjtcblxuICAgICAgaWYgKGVsZW1lbnQubWVhc3VyZXMpIHtcbiAgICAgICAgbGV0IG9iaiA9IHtcbiAgICAgICAgICBjb2x1bW5OYW1lOiBlbGVtZW50LmNvbHVtbk5hbWUsXG4gICAgICAgICAgZnVuY3Rpb25OYW1lOiBlbGVtZW50LmZ1bmN0aW9uTmFtZSxcbiAgICAgICAgICBlbnJpY2hGdW5jdGlvbjogZWxlbWVudC5lbnJpY2hGdW5jdGlvbixcbiAgICAgICAgICBhZHZhbmNlZENvbHVtbjogYWR2YW5jZWRDb2x1bW5WYWx1ZSxcbiAgICAgICAgICBhbGlhc05hbWU6IGVsZW1lbnQuZGF0YUZpZWxkLFxuICAgICAgICB9XG4gICAgICAgIGlmIChlbGVtZW50LmRlcml2ZUZpZWxkKSB7XG4gICAgICAgICAgb2JqWydkZXJpdmVGaWVsZCddID0gZWxlbWVudC5kZXJpdmVGaWVsZFxuICAgICAgICB9XG4gICAgICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLm1lYXN1cmVzLnB1c2gob2JqKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBvYmogPSB7XG4gICAgICAgICAgY29sdW1uTmFtZTogZWxlbWVudC5jb2x1bW5OYW1lLFxuICAgICAgICAgIGVucmljaEZ1bmN0aW9uOiBlbGVtZW50LmVucmljaEZ1bmN0aW9uLFxuICAgICAgICAgIGFsaWFzTmFtZTogZWxlbWVudC5kYXRhRmllbGQsXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuZGltZW5zaW9ucy5wdXNoKG9iaik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy50b2FzdHIuc3VjY2VzcygnQ29sdW1ucyBTYXZlZCBTdWNjZXNzZnVsbHknKTtcbiAgICAvLyB0aGlzLnNhdmVEYXRhVG9TdG9yZSgpXG4gIH1cblxuICBzYXZlRGF0YVRvU3RvcmUoKSB7XG4gICAgY29uc3QgYnVpbGREYXRlID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3F1ZXJ5YnVpbGRlcicpO1xuICAgIGlmIChidWlsZERhdGUpIHtcbiAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGJ1aWxkRGF0ZSk7XG4gICAgfVxuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdxdWVyeWJ1aWxkZXInLCBKU09OLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldCkpXG4gIH1cblxuICB0cmFuc2Zvcm1Db2x1bW5zRm9yTWVzdXJzKGlucHV0Q29sdW1ucykge1xuICAgIGNvbnN0IG1lYXN1cmUgPSBbXVxuICAgIGlucHV0Q29sdW1ucy5mb3JFYWNoKGNvbCA9PiB7XG5cblxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG1lYXN1cmU7XG4gIH1cblxuXG4gIGFkZEZpbHRlcigpIHtcbiAgICBsZXQgb2JqID0ge1xuICAgICAgXCJ0eXBlXCI6IFwiXCIsXG4gICAgICBcInZhbHVlXCI6IFwiXCIsXG4gICAgICBcImtleVwiOiBcIlwiLFxuICAgICAgXCJkaXNwbGF5XCI6IFwiXCIsXG4gICAgICBcInBsYWNlaG9sZGVyXCI6IFwiXCJcbiAgICB9XG4gICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuZmlsdGVyLnB1c2gob2JqKTtcbiAgfVxuXG4gIGRlbGV0ZUZpbHRlcihpKSB7XG4gICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuZmlsdGVyLnNwbGljZShpLCAxKTtcbiAgfVxuICBhZGRQYXJhbXMoKSB7XG4gICAgbGV0IG9iaiA9IHtcbiAgICAgIFwibmFtZVwiOiBcIlwiLFxuICAgICAgXCJ2YWx1ZVwiOiBcIlwiLFxuICAgIH1cbiAgICB0aGlzLnJlcUZpZWxkc0RhdGFTb3VyY2UucHVzaChvYmopO1xuICB9XG5cblxuICBkZWxldGVQYXJhbXMoaSkge1xuICAgIHRoaXMucmVxRmllbGRzRGF0YVNvdXJjZS5zcGxpY2UoaSwgMSlcbiAgfVxuXG4gIGFkZFNob3J0Q29sdW1ucygpIHtcbiAgICB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5zb3J0ZXJzLnB1c2goeyBcImNvbHVtbk5hbWVcIjogXCJcIiwgXCJkZXNjZW5kaW5nXCI6IGZhbHNlIH0pXG4gIH1cblxuXG4gIGRlbGV0ZVNob3J0Q29sdW1ucyhpKSB7XG4gICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuc29ydGVycy5zcGxpY2UoaSwgMSlcbiAgfVxuXG4gIHNhdmVQYXJhbXMoKSB7XG4gICAgbGV0IHBhZ2luYXRpb25SZXF1aXJlZEV4aXN0cyA9IGZhbHNlO1xuICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLnJlcUZpZWxkcyA9IHRoaXMucmVxRmllbGRzRGF0YVNvdXJjZS5tYXAoaXRlbSA9PiB7XG4gICAgICBjb25zdCBuZXdPYmo6IGFueSA9IHt9O1xuICAgICAgaWYgKGl0ZW0ubmFtZSA9PT0gXCJwYWdpbmF0aW9uUmVxdWlyZWRcIikge1xuICAgICAgICBwYWdpbmF0aW9uUmVxdWlyZWRFeGlzdHMgPSB0cnVlO1xuICAgICAgICBuZXdPYmpbaXRlbS5uYW1lXSA9IGl0ZW0udmFsdWUgPT09IFwidHJ1ZVwiO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaXRlbS52YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAhaXNOYU4oaXRlbS52YWx1ZSBhcyBhbnkpICYmIGl0ZW0udmFsdWUudHJpbSgpICE9PSBcIlwiKSB7XG4gICAgICAgIG5ld09ialtpdGVtLm5hbWVdID0gTnVtYmVyKGl0ZW0udmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3T2JqW2l0ZW0ubmFtZV0gPSBpdGVtLnZhbHVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3T2JqO1xuICAgIH0pO1xuXG4gICAgaWYgKCFwYWdpbmF0aW9uUmVxdWlyZWRFeGlzdHMpIHtcbiAgICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLnJlcUZpZWxkcy5wdXNoKHsgcGFnaW5hdGlvblJlcXVpcmVkOiBcImZhbHNlXCIgfSk7XG4gICAgfVxuXG4gICAgLy8gdGhpcy5zYXZlRGF0YVRvU3RvcmUoKTtcbiAgICB0aGlzLnRvYXN0ci5zdWNjZXNzKCdQYWdpbmF0aW9uIFJlcXVlc3QgUGFyYW1zIFNhdmVkIFN1Y2Nlc3NmdWxseScpO1xuICB9XG5cblxuICBhZGRGaWx0ZXJNYXBpbmdDb2x1bW5zKCkge1xuICAgIGxldCBvYmogPSB7IFwibG9jYWxDb2x1bW5cIjogXCJcIiwgXCJzZXJ2ZXJDb2x1bW5cIjogXCJcIiwgXCJvcGVyYXRvck5hbWVcIjogXCJcIiwgXCJkZWZhdWx0VmFsdWVcIjogXCJcIiwgXCJkYXRhVHlwZVwiOiBcIlwiIH1cbiAgICB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnMucHVzaChvYmopO1xuXG4gIH1cblxuICBkZWxldGVGaWx0ZXJNYXBpbmdDb2x1bW5zKGkpIHtcbiAgICB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnMuc3BsaWNlKGksIDEpXG4gIH1cblxuICBtb3ZlSXRlbUZvckNvbHVtbnMoaW5kZXg6IG51bWJlciwgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nKTogdm9pZCB7XG4gICAgLy8gUHJldmVudCBtb3ZpbmcgYmV5b25kIGFycmF5IGJvdW5kc1xuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcubWFwZWRGaWx0ZXJzLmxlbmd0aCkgcmV0dXJuO1xuICAgIGNvbnN0IG5ld1Bvc2l0aW9uID0gZGlyZWN0aW9uID09PSAndXAnID8gaW5kZXggLSAxIDogaW5kZXggKyAxO1xuICAgIC8vIFByZXZlbnQgbW92aW5nIGJleW9uZCBhcnJheSBib3VuZHNcbiAgICBpZiAobmV3UG9zaXRpb24gPCAwIHx8IG5ld1Bvc2l0aW9uID49IHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLm1hcGVkRmlsdGVycy5sZW5ndGgpIHJldHVybjtcblxuICAgIC8vIE1vdmUgaXRlbVxuICAgIGNvbnN0IGl0ZW1Ub01vdmUgPSB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnNbaW5kZXhdO1xuICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLm1hcGVkRmlsdGVycy5zcGxpY2UoaW5kZXgsIDEpOyAvLyBSZW1vdmUgaXRlbSBmcm9tIGN1cnJlbnQgcG9zaXRpb25cbiAgICB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnMuc3BsaWNlKG5ld1Bvc2l0aW9uLCAwLCBpdGVtVG9Nb3ZlKTsgLy8gSW5zZXJ0IGl0ZW0gaW4gbmV3IHBvc2l0aW9uXG4gIH1cbiAgbW92ZUl0ZW1Gb3JNZWFzdXJlc0NvbHVtbnMoaW5kZXg6IG51bWJlciwgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nKTogdm9pZCB7XG4gICAgLy8gUHJldmVudCBtb3ZpbmcgYmV5b25kIGFycmF5IGJvdW5kc1xuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuY29sdW1ucy5sZW5ndGgpIHJldHVybjtcbiAgICBjb25zdCBuZXdQb3NpdGlvbiA9IGRpcmVjdGlvbiA9PT0gJ3VwJyA/IGluZGV4IC0gMSA6IGluZGV4ICsgMTtcbiAgICAvLyBQcmV2ZW50IG1vdmluZyBiZXlvbmQgYXJyYXkgYm91bmRzXG4gICAgaWYgKG5ld1Bvc2l0aW9uIDwgMCB8fCBuZXdQb3NpdGlvbiA+PSB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5jb2x1bW5zLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgLy8gTW92ZSBpdGVtXG4gICAgY29uc3QgaXRlbVRvTW92ZSA9IHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLmNvbHVtbnNbaW5kZXhdO1xuICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLmNvbHVtbnMuc3BsaWNlKGluZGV4LCAxKTsgLy8gUmVtb3ZlIGl0ZW0gZnJvbSBjdXJyZW50IHBvc2l0aW9uXG4gICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuY29sdW1ucy5zcGxpY2UobmV3UG9zaXRpb24sIDAsIGl0ZW1Ub01vdmUpOyAvLyBJbnNlcnQgaXRlbSBpbiBuZXcgcG9zaXRpb25cbiAgfVxuXG5cblxuXG4gIGNoZWNrRm9yUXVlcnkoKSB7XG4gICAgbGV0IHRyYW5zZm9ybWVkT2JqZWN0OiBhbnkgPSB7fTtcblxuICAgIGZvciAobGV0IGl0ZW0gb2YgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcucmVxRmllbGRzKSB7XG4gICAgICBjb25zdCBrZXkgPSBPYmplY3Qua2V5cyhpdGVtKVswXTtcbiAgICAgIGNvbnN0IHZhbHVlID0gT2JqZWN0LnZhbHVlcyhpdGVtKVswXTtcblxuICAgICAgaWYgKGtleSA9PT0gJ3N0YXJ0RGF0ZScpIHtcbiAgICAgICAgdHJhbnNmb3JtZWRPYmplY3QucmVjb3JkRGF0ZSA9IHZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJhbnNmb3JtZWRPYmplY3Rba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgICB0cmFuc2Zvcm1lZE9iamVjdFsnZGltZW5zaW9ucyddID0gdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuZGltZW5zaW9ucztcbiAgICB0cmFuc2Zvcm1lZE9iamVjdFsnbWVhc3VyZXMnXSA9IHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLm1lYXN1cmVzO1xuICAgIHRyYW5zZm9ybWVkT2JqZWN0WydmaWx0ZXJzJ10gPSB0aGlzLnRyYW5zZm9ybURhdGFGb3JNRmlsdGVyKHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLm1hcGVkRmlsdGVycyk7O1xuICAgIHRyYW5zZm9ybWVkT2JqZWN0Wydzb3J0ZXJzJ10gPSB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5zb3J0ZXJzO1xuICAgIHRyYW5zZm9ybWVkT2JqZWN0W1wicGFnaW5hdGlvblJlcXVpcmVkXCJdID0gdHJ1ZTtcbiAgICBjb25zb2xlLmxvZyh0cmFuc2Zvcm1lZE9iamVjdCk7XG5cbiAgICB0aGlzLnNlcnZpY2UudmFsaWRhdGVBZ2dyZWdhdGVQYWdpbmF0ZWRRdWVyeSh0cmFuc2Zvcm1lZE9iamVjdCkuc3Vic2NyaWJlKGRhdGEgPT4ge1xuICAgICAgY29uc29sZS5sb2coZGF0YSk7XG4gICAgICB0aGlzLnF1ZXJ5X2RhdGEgPSBkYXRhLnF1ZXJ5XG4gICAgICB0aGlzLmlzTW9kZWxWaXNpYmxlID0gdHJ1ZTtcbiAgICB9LCBlcnIgPT4ge1xuICAgICAgdGhpcy50b2FzdHIuZXJyb3IoJ1VuZXhwZWN0ZWQgU2VydmVyIEV4Y2VwdGlvbi4gUGxlYXNlIGNvbnRhY3QgU3lzdGVtIEFkbWluLicpXG4gICAgfSlcbiAgfVxuXG4gIGNsb3NlTW9kYWxWaXNpYmxlTW9kYWwoKSB7XG4gICAgdGhpcy5pc01vZGVsVmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMucXVlcnlfZGF0YSA9ICcnO1xuICB9XG5cbiAgdHJhbnNmb3JtRGF0YUZvck1GaWx0ZXIobWFwZmlsdGVyKSB7XG4gICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgIG1hcGZpbHRlci5mb3JFYWNoKG1hcHBpbmcgPT4ge1xuICAgICAgbGV0IHJlc3VsdE9iaiA9IHtcbiAgICAgICAgY29sdW1uTmFtZTogbWFwcGluZy5zZXJ2ZXJDb2x1bW4sXG4gICAgICAgIGRhdGFUeXBlOiBtYXBwaW5nLmRhdGFUeXBlLFxuICAgICAgICBvcGVyYXRvcjogbWFwcGluZy5vcGVyYXRvck5hbWUsXG4gICAgICAgIHZhbHVlOiBtYXBwaW5nLmRlZmF1bHRWYWx1ZVxuICAgICAgfTtcbiAgICAgIHJlc3VsdC5wdXNoKHJlc3VsdE9iaik7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG5cbiAgY29weVNxbEZyb21Nb2RhbCgpIHtcbiAgICBjb25zdCBsaXN0ZW5lciA9IChlOiBDbGlwYm9hcmRFdmVudCkgPT4ge1xuICAgICAgZS5jbGlwYm9hcmREYXRhIS5zZXREYXRhKCd0ZXh0L3BsYWluJywgdGhpcy5xdWVyeV9kYXRhKTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9O1xuICAgIHRoaXMuaXNTcWxDb3BpZWRUZXh0ID0gdHJ1ZTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjb3B5JywgbGlzdGVuZXIpO1xuICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY29weScsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIGNyZWF0ZURhdGFTZXQoKSB7XG4gICAgdGhpcy5nZXRRdWVyeUJ1bGJkZXJEYXRhU2V0LmVtaXQodGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQpXG4gIH1cblxuICBnZXRRdWVyeUZvckRldGFpbHNEYXRhKGUpIHtcbiAgICBpZiAoZS52YWx1ZSA9PSAnQmFzaWMnKSB7XG4gICAgICB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5hcGkgPSAnL2twaS9nZW5lcmljRGV0YWlsRGF0YVJlc3BvbnNlJ1xuICAgICAgdGhpcy5xdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuY29sdW1ucyA9IFtdO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5hcGkgPSAnL2twaS9nZW5lcmljQWdncmVnYXRlUGFnaW5hdGVkS3BpU2VydmljZVJlc3BvbnNlJztcbiAgICB9XG4gIH1cblxuXG4gIGdldERhdGFDb25maWcoZSkge1xuXG4gICAgaWYgKGUuZXZlbnQpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRhU291cmNlID0gZS52YWx1ZTtcbiAgICAgIHRoaXMuaXNRdWVyeVR5cGVTZWxlY3QgPSB0cnVlO1xuICAgIH1cblxuICB9XG5cblxuICBhZGRIYXZpbmdzQ29sdW1lKCkge1xuICAgIGxldCBvYmogPSB7XG4gICAgICBcImNvbHVtbk5hbWVcIjogXCJcIixcbiAgICAgIFwiYWR2YW5jZWRDb2x1bW5cIjogXCJcIixcbiAgICAgIFwiZGF0YVR5cGVcIjogXCJcIixcbiAgICAgIFwib3BlcmF0b3JcIjogXCJcIixcbiAgICAgIFwidmFsdWVcIjogXCJcIlxuICAgIH1cbiAgICB0aGlzLnF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5oYXZpbmdzLnB1c2gob2JqKTtcbiAgfVxuXG4gIGRlbGV0ZUhhdmluZ3NDb2x1bWUoaSkge1xuICAgIHRoaXMucXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLmhhdmluZ3Muc3BsaWNlKGksIDEpO1xuICB9XG5cblxufVxuIiwiPGRpdiBjbGFzcz1cIm0tMlwiPlxuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IG1iLTJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm14LTIgdy0xLzNcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj5FbmQgUG9pbnQ8L2Rpdj5cbiAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cInF1ZXJ5QnVsZGVyRGF0YXNldC5hcGlcIj48L2R4LXRleHQtYm94PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm14LTIgdy0xLzNcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj5RdWVyeSBUeXBlPC9kaXY+XG4gICAgICAgICAgICA8ZHgtc2VsZWN0LWJveCBbZGF0YVNvdXJjZV09XCJbJ0FnZ3JlZ2F0ZScsJ0Jhc2ljJ11cIiAob25WYWx1ZUNoYW5nZWQpPVwiZ2V0UXVlcnlGb3JEZXRhaWxzRGF0YSgkZXZlbnQpXCI+XG4gICAgICAgICAgICA8L2R4LXNlbGVjdC1ib3g+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibXgtMiB3LTEvMyBtdC02XCIgKm5nSWY9XCJzZWxlY3RlZERhdGFTb3VyY2UgPT0gJ21vbmdvJ1wiPlxuICAgICAgICAgICAgPGR4LWNoZWNrLWJveCBbKG5nTW9kZWwpXT1cImlzUmVjb25Db2x1bWVcIiB0ZXh0PSdSZWNvbiBDb2x1bW4nPlxuICAgICAgICAgICAgPC9keC1jaGVjay1ib3g+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZmxleC1hdXRvIG1pbi13LTAgbXktM1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1sZyBweS0yIGZvbnQtZXh0cmFib2xkIGJvcmRlci1iIGJnLWdyYXktNzAwIHRleHQtd2hpdGUgcHgtMlwiPiBSZXF1ZXN0IFBhcmFtc1xuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInB0LTIgYm9yZGVyLXggYm9yZGVyLWIgXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZCBncmlkLWNvbHMtMiBnYXAtNCB3LWZ1bGwgcC0yXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm15LTIgZmxleCBmbGV4LXJvdyBweC0yIGJvcmRlci1yXCIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgcmVxRmllbGRzRGF0YVNvdXJjZTsgbGV0IGkgPSBpbmRleDtcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTIgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBQYXJhbXMgTmFtZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IFsobmdNb2RlbCldPVwiaXRlbS5uYW1lXCI+PC9keC10ZXh0LWJveD5cblxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTIgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBQYXJhbXMgVmFsdWUgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS5uYW1lID09ICdkYkNvbmZpZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtc2VsZWN0LWJveCBbaXRlbXNdPVwiWydtb25nbycsJ2ltcGFsYScsJ3Bvc3RncmVzJywnbXlzcWwnLCdiaWdxdWVyeSddXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uVmFsdWVDaGFuZ2VkKT1cImdldERhdGFDb25maWcoJGV2ZW50KVwiIFsobmdNb2RlbCldPVwiaXRlbS52YWx1ZVwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0ubmFtZSAhPT0gJ2RiQ29uZmlnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0udmFsdWVcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0yIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlciBtdC04XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fZGFuZ2VyX3NtfX0gY3Vyc29yLXBvaW50ZXJcIiAoY2xpY2spPVwiZGVsZXRlUGFyYW1zKGkpXCI+PGlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmEgZmEtdHJhc2gtb1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cgbXktMiBqdXN0aWZ5LWVuZFwiPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1zbSBpdGFsaWMgdGV4dC1ncmF5LTMwMCBtci02XCI+KiogUGxlYXNlIFNhdmUgUmVxdWVzdCBQYXJhbXMgQmVmb3JlIFN1Ym1pdFxuICAgICAgICAgICAgICAgICAgICBEYXRhc2V0XG4gICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX3N1Y2Nlc3Nfc219fSBjdXJzb3ItcG9pbnRlclwiIChjbGljayk9XCJzYXZlUGFyYW1zKClcIj5TYXZlXG4gICAgICAgICAgICAgICAgICAgIFBhcmFtczwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX3ByaW1hcnlfc219fSBjdXJzb3ItcG9pbnRlclwiIChjbGljayk9XCJhZGRQYXJhbXMoKVwiPkFkZFxuICAgICAgICAgICAgICAgICAgICBQYXJhbXM8L2J1dHRvbj5cblxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzUXVlcnlUeXBlU2VsZWN0XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGZsZXgtYXV0byBtaW4tdy0wIG15LTJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWxnIHB5LTIgZm9udC1leHRyYWJvbGQgYm9yZGVyLWIgYmctZ3JheS03MDAgdGV4dC13aGl0ZSBweC0yXCI+IENvbHVtbnMgYW5kIE1lYXN1cmVzXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwdC0yIGJvcmRlci14IGJvcmRlci1iIFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteS0yIGZsZXgganVzdGlmeS1iZXR3ZWVuXCJcbiAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgcXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLmNvbHVtbnM7IGxldCBpID0gaW5kZXg7XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj4gTWVhc3VyZXM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1jaGVjay1ib3ggW3ZhbHVlXT1cIml0ZW0ubWVhc3VyZXNcIiBbKG5nTW9kZWwpXT1cIml0ZW0ubWVhc3VyZXNcIj48L2R4LWNoZWNrLWJveD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj4gVmFsdWUgRmllbGQoYWxpYXNOYW1lKTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IFsobmdNb2RlbCldPVwiaXRlbS5kYXRhRmllbGRcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBTZXJ2ZXIgQ29sdW1uIE5hbWU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0uY29sdW1uTmFtZVwiPjwvZHgtdGV4dC1ib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IEZ1bmN0aW9uIE5hbWU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1zZWxlY3QtYm94IFtzZWFyY2hFbmFibGVkXT1cInRydWVcIiBbaXRlbXNdPVwia3BpX2Z1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIml0ZW0uZnVuY3Rpb25OYW1lXCI+PC9keC1zZWxlY3QtYm94PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBFbnJpY2ggTmFtZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXNlbGVjdC1ib3ggW3NlYXJjaEVuYWJsZWRdPVwidHJ1ZVwiIFtpdGVtc109XCJrcGlfZW5yaWNobWVudF9uYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIml0ZW0uZW5yaWNoRnVuY3Rpb25cIj48L2R4LXNlbGVjdC1ib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IEFkdmFuY2VkIENvbHVtbjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IFsobmdNb2RlbCldPVwiaXRlbS5hZHZhbmNlZENvbHVtblwiPjwvZHgtdGV4dC1ib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IENhcHRpb248L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0uY2FwdGlvblwiPjwvZHgtdGV4dC1ib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtdC04XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJpICE9PSAwXCIgY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2xpZ2h0X3NtfX0gY3Vyc29yLXBvaW50ZXIgbXgtMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJtb3ZlSXRlbUZvck1lYXN1cmVzQ29sdW1ucyhpLCAndXAnKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWFycm93LXVwXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImkgIT09IHF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5jb2x1bW5zLmxlbmd0aCAtIDFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fbGlnaHRfc219fSBjdXJzb3ItcG9pbnRlciBteC0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm1vdmVJdGVtRm9yTWVhc3VyZXNDb2x1bW5zKGksICdkb3duJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1hcnJvdy1kb3duXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtdC04IHRleHQtY2VudGVyXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2Rhbmdlcl9zbX19IGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cImRlbGV0ZUNvbHVtbnMoaSlcIj48aVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZhIGZhLXRyYXNoLW9cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCBteS0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1zbSBpdGFsaWMgdGV4dC1ncmF5LTMwMCBtci02XCI+KiogUGxlYXNlIFNhdmUgQ29sdW1ucyBBbmQgTWVhc3VyZXMgQmVmb3JlIFN1Ym1pdFxuICAgICAgICAgICAgICAgICAgICAgICAgRGF0YXNldFxuICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX3N1Y2Nlc3Nfc219fSBjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2F2ZUNvbHVtbnNBbmRNYXN1cmVzKClcIj5TYXZlXG4gICAgICAgICAgICAgICAgICAgICAgICBDb2x1bW5zPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX3ByaW1hcnlfc219fSBjdXJzb3ItcG9pbnRlclwiIChjbGljayk9XCJhZGRDb2x1bW5zKClcIj5BZGRcbiAgICAgICAgICAgICAgICAgICAgICAgIENvbHVtbnM8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1JlY29uQ29sdW1lXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LWF1dG8gbWluLXctMCBteS0yXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbGcgcHktMiBmb250LWV4dHJhYm9sZCBib3JkZXItYiBiZy1ncmF5LTcwMCB0ZXh0LXdoaXRlIHB4LTJcIj4gQWRkIFJlY29uIENvbHVtblxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwdC0yIGJvcmRlci14IGJvcmRlci1iIFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXktMiBmbGV4IGp1c3RpZnktYmV0d2VlblwiICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJlY29uQ29sdW1lRGF0YXNvdXJjZTsgbGV0IGkgPSBpbmRleDtcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj4gVmFsdWUgRmllbGQoYWxpYXNOYW1lKTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0uZGF0YUZpZWxkXCI+PC9keC10ZXh0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj4gRmlyc3QgS2V5PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IFsobmdNb2RlbCldPVwiaXRlbS5jb2x1bWVPbmVcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBTZWNvbmQgS2V5PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IFsobmdNb2RlbCldPVwiaXRlbS5jb2x1bWVUd29cIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IEVucmljaCBOYW1lPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXNlbGVjdC1ib3ggW3NlYXJjaEVuYWJsZWRdPVwidHJ1ZVwiIFtpdGVtc109XCJrcGlfZW5yaWNobWVudF9uYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJpdGVtLmVucmljaEZ1bmN0aW9uXCI+PC9keC1zZWxlY3QtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBSZWNvbiBUeXBlPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXNlbGVjdC1ib3ggW3NlYXJjaEVuYWJsZWRdPVwidHJ1ZVwiIFtpdGVtc109XCJbJ3ZhcmlhbmNlJywncGVyY2VudGFnZScsJ2Fic29sdXRlJ11cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIml0ZW0ucmVjb25UeXBlXCI+PC9keC1zZWxlY3QtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IENhcHRpb248L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtdGV4dC1ib3ggWyhuZ01vZGVsKV09XCJpdGVtLmNhcHRpb25cIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG10LTggdGV4dC1jZW50ZXJcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2Rhbmdlcl9zbX19IGN1cnNvci1wb2ludGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImRlbGV0ZVJlY29uQ29sdW1lKGkpXCI+PGkgY2xhc3M9XCJmYSBmYS10cmFzaC1vXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCBteS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9zdWNjZXNzX3NtfX0gY3Vyc29yLXBvaW50ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzYXZlUmVjb25zQ29sdW1lKClcIj5TYXZlIFRvXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sdW1uczwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fcHJpbWFyeV9zbX19IGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cImFkZFJlY29uQ29sdW1lKClcIj5BZGRcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LWF1dG8gbWluLXctMCBteS0yXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbGcgcHktMiBmb250LWV4dHJhYm9sZCBib3JkZXItYiBiZy1ncmF5LTcwMCB0ZXh0LXdoaXRlIHB4LTJcIj4gQWRkIEhhdmluZyBDb2x1bW5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMiBib3JkZXIteCBib3JkZXItYiBcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm15LTIgZmxleCBqdXN0aWZ5LWJldHdlZW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgcXVlcnlCdWxkZXJEYXRhc2V0LnF1ZXJ5Q29uZmlnLmhhdmluZ3M7IGxldCBpID0gaW5kZXg7XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTIgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBDb2x1bW4gTmFtZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0uY29sdW1uTmFtZVwiPjwvZHgtdGV4dC1ib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTIgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBBZHZhbmNlZCBDb2x1bW48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtdGV4dC1ib3ggWyhuZ01vZGVsKV09XCJpdGVtLmFkdmFuY2VkQ29sdW1uXCI+PC9keC10ZXh0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEgbWItMiB3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IERhdGEgVHlwZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0uZGF0YVR5cGVcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTIgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBPcGVyYXRvcjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC1zZWxlY3QtYm94IFtpdGVtc109XCJbJ2dldCcsJ2x0ZSddXCIgWyhuZ01vZGVsKV09XCJpdGVtLm9wZXJhdG9yXCI+PC9keC1zZWxlY3QtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTIgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbWQgbWItMlwiPiBWYWx1ZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0udmFsdWVcIj48L2R4LXRleHQtYm94PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG10LTggdGV4dC1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9kYW5nZXJfc219fSBjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkZWxldGVIYXZpbmdzQ29sdW1lKGkpXCI+PGkgY2xhc3M9XCJmYSBmYS10cmFzaC1vXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCBteS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9wcmltYXJ5X3NtfX0gY3Vyc29yLXBvaW50ZXJcIiAoY2xpY2spPVwiYWRkSGF2aW5nc0NvbHVtZSgpXCI+QWRkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSGF2aW5nc1xuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZmxleC1hdXRvIG1pbi13LTAgbXktM1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbGcgcHktMiBmb250LWV4dHJhYm9sZCBib3JkZXItYiBiZy1ncmF5LTcwMCB0ZXh0LXdoaXRlIHB4LTJcIj4gU29ydCBCeVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMiBib3JkZXIteCBib3JkZXItYiBcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZCBncmlkLWNvbHMtMiBnYXAtNCB3LWZ1bGwgcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJteS0yIGZsZXggZmxleC1yb3cgcHgtMiBib3JkZXItclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBxdWVyeUJ1bGRlckRhdGFzZXQucXVlcnlDb25maWcuc29ydGVyczsgbGV0IGkgPSBpbmRleDtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0yIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IFBhcmFtcyBOYW1lPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGR4LXRleHQtYm94IFsobmdNb2RlbCldPVwiaXRlbS5jb2x1bW5OYW1lXCI+PC9keC10ZXh0LWJveD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMiBtdC04XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZHgtY2hlY2stYm94IHRleHQ9XCJEZXNjZW5kaW5nXCIgWyhuZ01vZGVsKV09XCJpdGVtLmRlc2NlbmRpbmdcIj48L2R4LWNoZWNrLWJveD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTIgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlciBtdC04XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX2Rhbmdlcl9zbX19IGN1cnNvci1wb2ludGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkZWxldGVTaG9ydENvbHVtbnMoaSlcIj48aSBjbGFzcz1cImZhIGZhLXRyYXNoLW9cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IG15LTIganVzdGlmeS1lbmRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fcHJpbWFyeV9zbX19IGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cImFkZFNob3J0Q29sdW1ucygpXCI+QWRkXG4gICAgICAgICAgICAgICAgICAgICAgICBDb2x1bW48L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZmxleC1hdXRvIG1pbi13LTAgbXktMlwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbGcgcHktMiBmb250LWV4dHJhYm9sZCBib3JkZXItYiBiZy1ncmF5LTcwMCB0ZXh0LXdoaXRlIHB4LTJcIj4gRmlsdGVyIE1hcGluZ1xuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHQtMiBib3JkZXIteCBib3JkZXItYiBcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXktMiBmbGV4IGZsZXgtcm93IGp1c3RpZnktYmV0d2VlblwiXG4gICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIHF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnM7IGxldCBpID0gaW5kZXg7XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTEgbWItMiB3LWZ1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW1kIG1iLTJcIj4gTG9jYWwgQ29sdW1uPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZHgtdGV4dC1ib3ggWyhuZ01vZGVsKV09XCJpdGVtLmxvY2FsQ29sdW1uXCI+PC9keC10ZXh0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTIgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IFNlcnZlciBDb2x1bW48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0uc2VydmVyQ29sdW1uXCI+PC9keC10ZXh0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTIgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IE9wZXJhdG9yPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZHgtc2VsZWN0LWJveCBbc2VhcmNoRW5hYmxlZF09XCJ0cnVlXCIgW2l0ZW1zXT1cImtwaV9vcGVyYXRvclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJpdGVtLm9wZXJhdG9yTmFtZVwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTIgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IERhdGF0eXBlPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZHgtc2VsZWN0LWJveCBbc2VhcmNoRW5hYmxlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXRlbXNdPVwiWydkYXRlJywnc3RyaW5nJywndGltZXN0YW1wJywnaW50JywgJ2RvdWJsZScsICdib29sZWFuJ11cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaXRlbS5kYXRhVHlwZVwiPjwvZHgtc2VsZWN0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG1iLTIgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tZCBtYi0yXCI+IERlZmF1bHQgVmFsdWU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkeC10ZXh0LWJveCBbKG5nTW9kZWwpXT1cIml0ZW0uZGVmYXVsdFZhbHVlXCI+PC9keC10ZXh0LWJveD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xIG10LThcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImkgIT09IDBcIiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fbGlnaHRfc219fSBjdXJzb3ItcG9pbnRlciBteC0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm1vdmVJdGVtRm9yQ29sdW1ucyhpLCAndXAnKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWFycm93LXVwXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cImkgIT09IHF1ZXJ5QnVsZGVyRGF0YXNldC5xdWVyeUNvbmZpZy5tYXBlZEZpbHRlcnMubGVuZ3RoIC0gMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9saWdodF9zbX19IGN1cnNvci1wb2ludGVyIG14LTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwibW92ZUl0ZW1Gb3JDb2x1bW5zKGksICdkb3duJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1hcnJvdy1kb3duXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMSBtdC04IHRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9kYW5nZXJfc219fSBjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImRlbGV0ZUZpbHRlck1hcGluZ0NvbHVtbnMoaSlcIj48aSBjbGFzcz1cImZhIGZhLXRyYXNoLW9cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMS8yXCIgKm5nSWY9XCJzZWxlY3RlZERhdGFTb3VyY2UgIT09ICdtb25nbydcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cganVzdGlmeS1zdGFydCBteS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bk90aGVyc1B1cnBsZX19IGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cImNoZWNrRm9yUXVlcnkoKVwiPkNoZWNrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnk8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCBteS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwie3tjb21tb25TZXJ2aWNlLmJ0bl9wcmltYXJ5X3NtfX0gY3Vyc29yLXBvaW50ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRGaWx0ZXJNYXBpbmdDb2x1bW5zKClcIj5BZGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXBpbmc8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggdy1mdWxsIGp1c3RpZnktZW5kIG10LTUgYm9yZGVyLXRcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ7e2NvbW1vblNlcnZpY2UuYnRuX3N1Y2Nlc3NfbWR9fSBjdXJzb3ItcG9pbnRlciBteC0xIG15LTJcIiAoY2xpY2spPVwiY3JlYXRlRGF0YVNldCgpXCI+XG4gICAgICAgICAgICAgICAgU3VibWl0IERhdGFTZXRcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuXG48L2Rpdj5cblxuXG48bmctY29udGFpbmVyICpuZ0lmPVwiaXNNb2RlbFZpc2libGVcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZml4ZWQgaW5zZXQtMCBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciB6LTUwIGJnLWJsYWNrIGJnLW9wYWNpdHktNTBcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJlbGF0aXZlIHAtNCB3LWZ1bGwgbWF4LXctM3hsIG1heC1oLWZ1bGxcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZSBiZy13aGl0ZSByb3VuZGVkLWxnIHNoYWRvdyAgXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlbiBwLTQgbWQ6cC01IGJvcmRlci1iIHJvdW5kZWQtdCBcIj5cbiAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwidGV4dC14bCBmb250LXNlbWlib2xkIHRleHQtZ3JheS05MDAgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBRdWVyeSA8L2gzPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2xvc2VNb2RhbFZpc2libGVNb2RhbCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGV4dC1ncmF5LTQwMCBiZy10cmFuc3BhcmVudCBob3ZlcjpiZy1ncmF5LTIwMCBob3Zlcjp0ZXh0LWdyYXktOTAwIHJvdW5kZWQtbGcgdGV4dC1zbSB3LTggaC04IG1zLWF1dG8gaW5saW5lLWZsZXgganVzdGlmeS1jZW50ZXIgaXRlbXMtY2VudGVyIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLW1vZGFsLWhpZGU9XCJzdGF0aWMtbW9kYWxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJ3LTMgaC0zXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIGZpbGw9XCJub25lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDE0IDE0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgc3Ryb2tlLXdpZHRoPVwiMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJtMSAxIDYgNm0wIDAgNiA2TTcgN2w2LTZNNyA3bC02IDZcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyLW9ubHlcIj5DbG9zZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPCEtLSBNb2RhbCBib2R5IC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LTY5IHAtNVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBiZy1ncmF5LTgwMCB0ZXh0LXdoaXRlIHRleHQtbGcgcC00IHJvdW5kZWQtbWQgdGV4dC13cmFwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7cXVlcnlfZGF0YX19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2NvZGU+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBib3JkZXItdCBib3JkZXItZ3JheS0yMDAgcm91bmRlZC1iIHAtMiBqdXN0aWZ5LWVuZFwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtZ3JheS03MDAgcHgtMlwiICpuZ0lmPVwiaXNTcWxDb3BpZWRUZXh0XCI+Q29waWVkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGRhdGEtbW9kYWwtaGlkZT1cInN0YXRpYy1tb2RhbFwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInt7Y29tbW9uU2VydmljZS5idG5fc3VjY2Vzc19zbX19IHB5LTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvcHlTcWxGcm9tTW9kYWwoKVwiPkNvcHk8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPiJdfQ==
|