mmhglobal-dynamicform 2.2.0 → 2.3.0

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.
@@ -0,0 +1,361 @@
1
+ /********** Angular **********/
2
+ import { Component, Input, ViewChild } from '@angular/core';
3
+ /********** Ionic **********/
4
+ /********** Plugin **********/
5
+ import { delay, ignoreElements, map, switchMap, tap } from 'rxjs/operators';
6
+ /********** Component & Service **********/
7
+ import { ZComponentHelper, ZComponentProperties, DefaultPageSettingParams } from 'mmhglobal-zcore';
8
+ import { of } from 'rxjs';
9
+ import { DropDownList, MultiSelect } from '@syncfusion/ej2-dropdowns';
10
+ import { getComponent, createElement } from '@syncfusion/ej2-base';
11
+ import { CheckBox } from '@syncfusion/ej2-buttons';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "mmhglobal-zcore";
14
+ import * as i2 from "@ionic/angular";
15
+ import * as i3 from "@syncfusion/ej2-angular-querybuilder";
16
+ import * as i4 from "@angular/common";
17
+ export class SfquerybuilderComponent {
18
+ constructor(fieldService, resourceApiService, webApiService) {
19
+ this.fieldService = fieldService;
20
+ this.resourceApiService = resourceApiService;
21
+ this.webApiService = webApiService;
22
+ this.qbItems = {};
23
+ this.componentProperties = new ZComponentProperties();
24
+ this.currentConfig = {
25
+ fields: {},
26
+ allowEmptyRulesets: true
27
+ };
28
+ this.allowRuleset = true;
29
+ this.allowCollapse = false;
30
+ this.persistValueOnFieldChange = false;
31
+ this.isDisabled = false;
32
+ this.issfLoaded = false;
33
+ this.displayRule = '';
34
+ this.loadedDropdownOptions = [];
35
+ //@ViewChild('querybuilder') qryBldrObj: QueryBuilderComponent;
36
+ this.sdFilter = [];
37
+ this.inOperators = ['in', 'notin'];
38
+ this.selectionComponentList = [];
39
+ }
40
+ ngOnInit() {
41
+ ZComponentHelper.setComponentProperties(this);
42
+ ZComponentHelper.registerComponent(this);
43
+ of(true).pipe(switchMap(cont => {
44
+ return this.beforeLoadField(this.data);
45
+ }), switchMap(cont2 => {
46
+ return this.loadQueryBuilder();
47
+ })).subscribe(() => {
48
+ // Where to update operator syntax
49
+ // 1. E1 - queryBuilderTemplate2
50
+ // 2. shared folder > helper > querybuilder-fieldinfo-helper.ts
51
+ // 3. patch db data with small capital letter
52
+ //this.issfLoaded = true;
53
+ });
54
+ }
55
+ loadQueryBuilder() {
56
+ if (this.data['AllowCollapse'] === true) {
57
+ this.allowCollapse = this.data['AllowCollapse'];
58
+ }
59
+ if (this.data['AllowRuleset'] === false) {
60
+ this.allowRuleset = this.data['AllowRuleset'];
61
+ }
62
+ if (this.data['Filters']) {
63
+ this.filters = ZComponentHelper.getGroupEvalValue.call(this, this.data['Filters'], this.group);
64
+ }
65
+ this.fields = this.fieldService.getFormFieldCode(this.data.Value, "FormField", null, null);
66
+ try {
67
+ return this.fields.pipe(tap((data) => {
68
+ data.forEach(async (field) => {
69
+ //sf //todo: later change to base on other attribute single or multi select for field element
70
+ if (field.Type == 'category' || field.Type == 'multiselect') {
71
+ this.sdFilter.push({
72
+ field: field.Value,
73
+ label: field.Name,
74
+ type: 'string',
75
+ template: await this.generateColumnSelection(field),
76
+ });
77
+ }
78
+ else if (field.Type === 'string') {
79
+ this.sdFilter.push({
80
+ field: field.Value,
81
+ label: field.Name,
82
+ type: 'string'
83
+ });
84
+ }
85
+ else if (field.Type === 'date') {
86
+ this.sdFilter.push({
87
+ field: field.Value,
88
+ label: field.Name,
89
+ type: 'date'
90
+ });
91
+ }
92
+ else if (field.Type === 'number') {
93
+ this.sdFilter.push({
94
+ field: field.Value,
95
+ label: field.Name,
96
+ type: 'number'
97
+ });
98
+ }
99
+ else if (field.Value === 'boolean') {
100
+ this.sdFilter.push({
101
+ field: field.Value,
102
+ label: field.Name,
103
+ type: 'boolean',
104
+ template: await this.generateColumnCheckbox(field.Name, false)
105
+ });
106
+ }
107
+ else {
108
+ this.sdFilter.push({
109
+ field: field.Value,
110
+ label: field.Name,
111
+ type: 'string'
112
+ });
113
+ }
114
+ }); //end foreach
115
+ this.issfLoaded = true;
116
+ }));
117
+ //});
118
+ return of(true);
119
+ }
120
+ catch (error) {
121
+ console.error("error: ", error);
122
+ return of(false);
123
+ }
124
+ }
125
+ //#region checkbox
126
+ generateColumnCheckbox(label, value) {
127
+ return {
128
+ create: () => {
129
+ return createElement('input', { attrs: { 'type': 'checkbox' } });
130
+ },
131
+ destroy: (args) => {
132
+ getComponent(document.getElementById(args.elementId), 'checkbox').destroy();
133
+ },
134
+ write: (args) => {
135
+ const boxObj = new CheckBox({
136
+ label: label,
137
+ checked: value,
138
+ change: (e) => {
139
+ this.qryBldrObj.notifyChange(value, e.event.target);
140
+ }
141
+ });
142
+ boxObj.appendTo('#' + args.elements.id);
143
+ }
144
+ };
145
+ }
146
+ //#endregion
147
+ //#region dropdown/multiselect
148
+ generateColumnSelection(fieldElementData) {
149
+ return {
150
+ // Creates the custom component
151
+ create: () => {
152
+ // Additional filter set in the page
153
+ if (this.data['Filters']) {
154
+ this.filters = ZComponentHelper.getGroupEvalValue.call(this, this.data['Filters'], this.group);
155
+ }
156
+ return createElement('input', { attrs: { 'type': 'text', 'style': 'display: none' } }); //createElement('input', { attrs: { 'type': 'text' } });
157
+ },
158
+ // Destroy the custom component
159
+ destroy: (args) => {
160
+ if (args['elements']) {
161
+ let multiSelect = getComponent(document.getElementById(args.elementId), 'multiselect');
162
+ if (multiSelect) {
163
+ multiSelect.destroy();
164
+ }
165
+ let dropdown = getComponent(document.getElementById(args.elementId), 'dropdownlist');
166
+ if (dropdown) {
167
+ dropdown.destroy();
168
+ }
169
+ const selectOptions = fieldElementData['SelectOptions'];
170
+ if (selectOptions) {
171
+ const selectOptionsResourceURL = selectOptions['ResourceURL'];
172
+ const prefixResourceURLChecking = selectOptionsResourceURL + '_' + args.elementId;
173
+ if (this.loadedDropdownOptions.includes(prefixResourceURLChecking)) {
174
+ this.loadedDropdownOptions = this.removeArrayItem(this.loadedDropdownOptions, prefixResourceURLChecking);
175
+ }
176
+ }
177
+ }
178
+ },
179
+ // Wire events for the custom component.
180
+ write: (args) => {
181
+ //origin
182
+ if (fieldElementData['ValueOptions']) {
183
+ // convert to property name used in the component rendering
184
+ const optionList = [];
185
+ fieldElementData['ValueOptions'].forEach((item) => {
186
+ optionList.push({
187
+ text: item['Name'],
188
+ value: item['Value']
189
+ });
190
+ });
191
+ const selectionComponent = this.generateSelectionComponent(args, optionList);
192
+ selectionComponent.appendTo('#' + args.elements.id);
193
+ }
194
+ else {
195
+ const selectOptions = fieldElementData['SelectOptions'];
196
+ const selectOptionsResourceURL = selectOptions['ResourceURL'];
197
+ const prefixResourceURLChecking = selectOptionsResourceURL + '_' + args.elements.id;
198
+ if (!this.loadedDropdownOptions.includes(prefixResourceURLChecking)) {
199
+ this.loadedDropdownOptions.push(prefixResourceURLChecking);
200
+ if (this.filters) {
201
+ selectOptions['Filters'] = this.filters;
202
+ }
203
+ const param = Object.assign({}, DefaultPageSettingParams);
204
+ param.pageSize = selectOptions['PageSize'];
205
+ param.columns = selectOptions['Columns'];
206
+ param.filters += selectOptions['Filters'];
207
+ param.sortColumnName = selectOptions['SortColumnName'];
208
+ param.sortOrder = selectOptions['SortOrder'];
209
+ this.webApiService.httpPost$(this.resourceApiService.getPageUrl(selectOptionsResourceURL), param).pipe(delay(300), map((resp) => {
210
+ const optionList = [];
211
+ resp.dataSet.forEach((item) => {
212
+ optionList.push({
213
+ text: item[selectOptions['Name']],
214
+ value: item[selectOptions['Value']]
215
+ });
216
+ });
217
+ const selectionComponent = this.generateSelectionComponent(args, optionList);
218
+ selectionComponent.appendTo('#' + args.elements.id);
219
+ const xxx = document.getElementById(args.elements.id);
220
+ //xxx.appendChild(inputElement);
221
+ xxx.style.display = 'block';
222
+ //#region used for updateSelectionOption
223
+ const existingIndex = this.selectionComponentList.findIndex((item) => item.componentId === args.elements.id);
224
+ if (existingIndex !== -1) {
225
+ // Object with the same componentId exists, replace resourceUrl
226
+ this.selectionComponentList[existingIndex].resourceUrl = selectOptionsResourceURL;
227
+ }
228
+ else {
229
+ // Object with componentId doesn't exist, push a new object
230
+ this.selectionComponentList.push({
231
+ resourceUrl: selectOptionsResourceURL,
232
+ componentId: args.elements.id
233
+ });
234
+ }
235
+ //#endregion
236
+ })).subscribe();
237
+ }
238
+ }
239
+ } //end write
240
+ };
241
+ }
242
+ updateSelectionOption(resourceUrl, data) {
243
+ this.selectionComponentList.forEach(selectionComponent => {
244
+ let multiSelect = getComponent(document.getElementById(selectionComponent.componentId), 'multiselect');
245
+ if (multiSelect) {
246
+ multiSelect.value = data;
247
+ }
248
+ let dropdown = getComponent(document.getElementById(selectionComponent.componentId), 'dropdownlist');
249
+ if (dropdown) {
250
+ this.fieldService.dataFormFields[this.data.Value].forEach(async (field) => {
251
+ if (field.SelectOptions.ResourceURL === selectionComponent.resourceUrl) {
252
+ const selectOptions = field['SelectOptions'];
253
+ const selectOptionsResourceURL = selectOptions['ResourceURL'];
254
+ const param = Object.assign({}, DefaultPageSettingParams);
255
+ if (this.data['Filters']) {
256
+ this.filters = ZComponentHelper.getGroupEvalValue.call(this, this.data['Filters'], this.group);
257
+ }
258
+ if (this.filters) {
259
+ selectOptions['Filters'] = this.filters;
260
+ }
261
+ param.pageSize = selectOptions['PageSize'];
262
+ param.columns = selectOptions['Columns'];
263
+ param.filters += selectOptions['Filters'];
264
+ param.sortColumnName = selectOptions['SortColumnName'];
265
+ param.sortOrder = selectOptions['SortOrder'];
266
+ this.webApiService.httpPost$(this.resourceApiService.getPageUrl(selectOptionsResourceURL), param).pipe(map((resp) => {
267
+ const optionList = [];
268
+ resp.dataSet.forEach((item) => {
269
+ optionList.push({
270
+ text: item[selectOptions['Name']],
271
+ value: item[selectOptions['Value']]
272
+ });
273
+ });
274
+ dropdown.dataSource = optionList;
275
+ })).subscribe();
276
+ }
277
+ });
278
+ }
279
+ });
280
+ }
281
+ removeArrayItem(arr, value) {
282
+ const index = arr.indexOf(value);
283
+ if (index > -1) {
284
+ arr.splice(index, 1);
285
+ }
286
+ return arr;
287
+ }
288
+ generateSelectionComponent(args, optionList) {
289
+ if (this.inOperators.indexOf(args.operator) > -1) {
290
+ return new MultiSelect({
291
+ dataSource: optionList,
292
+ fields: { text: 'text', value: 'value' },
293
+ value: args.values,
294
+ mode: 'CheckBox',
295
+ change: (e) => {
296
+ this.qryBldrObj.notifyChange(e.value, e.element);
297
+ }
298
+ });
299
+ }
300
+ else {
301
+ return new DropDownList({
302
+ dataSource: optionList,
303
+ fields: { text: 'text', value: 'value' },
304
+ value: args.values,
305
+ change: (e) => {
306
+ e.value !== null ? this.qryBldrObj.notifyChange(e.itemData.value, e.element) : ignoreElements;
307
+ }
308
+ });
309
+ }
310
+ }
311
+ //#endregion
312
+ setQueryValue(savedData) {
313
+ //if (!this.qryBldrObj) {
314
+ // console.warn('query builder object is null.');
315
+ // return;
316
+ //}
317
+ if (savedData) {
318
+ this.qryBldrObj.setRules(savedData);
319
+ this.updateRule({ rule: savedData });
320
+ }
321
+ }
322
+ getResult() {
323
+ return this.qryBldrObj.getRules();
324
+ }
325
+ updateRule(args) {
326
+ this.displayRule = JSON.stringify(args.rule, null, 12);
327
+ }
328
+ onChange() {
329
+ this.updateRule({ rule: this.qryBldrObj.getValidRules(this.qryBldrObj.rule) });
330
+ }
331
+ beforeLoadField(fieldElementData) {
332
+ let beforeLoadField = fieldElementData['BeforeLoadField'];
333
+ if (beforeLoadField) {
334
+ beforeLoadField = beforeLoadField.replace('modalGroup.', 'group.');
335
+ const callFunc = eval('this.' + beforeLoadField);
336
+ if (typeof callFunc === "function") {
337
+ const newFunc = callFunc.bind(this);
338
+ return newFunc(event, this);
339
+ }
340
+ }
341
+ return of(true);
342
+ }
343
+ }
344
+ SfquerybuilderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SfquerybuilderComponent, deps: [{ token: i1.FieldService }, { token: i1.ResourceApiService }, { token: i1.WebApiService }], target: i0.ɵɵFactoryTarget.Component });
345
+ SfquerybuilderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: SfquerybuilderComponent, selector: "app-sfquerybuilder", inputs: { classNames: "classNames", data: "data", group: "group", form: "form" }, viewQueries: [{ propertyName: "qryBldrObj", first: true, predicate: ["querybuilder"], descendants: true }], ngImport: i0, template: "<ion-item *ngIf=\"(!!componentProperties.isVisibleField ? group[componentProperties.isVisibleField] : componentProperties.isVisible)\">\r\n <!--<ejs-querybuilder *ngIf=\"issfLoaded && !data.ShowQueryResult\"\r\n #querybuilder\r\n width=\"100%\"\r\n [dataSource]=\"sfData\"\r\n [columns]=\"sdFilter\"\r\n [rule]=\"importRules\"\r\n (ruleChange)=\"updateRule($event)\"\r\n (created)=\"onChange()\">\r\n </ejs-querybuilder>-->\r\n\r\n\r\n <div class=\"qbcontainer\" >\r\n <ejs-querybuilder *ngIf=\"issfLoaded\"\r\n #querybuilder\r\n width=\"100%\"\r\n [dataSource]=\"sfData\"\r\n [columns]=\"sdFilter\"\r\n [rule]=\"importRules\"\r\n (ruleChange)=\"updateRule($event)\"\r\n (created)=\"onChange()\">\r\n </ejs-querybuilder>\r\n\r\n <div>\r\n <br>\r\n <ion-label>Result</ion-label>\r\n <textarea class=\"output\"\r\n resizable=\"none\"\r\n [rows]=\"10\"\r\n style=\"border: 1px solid #d3d3d3; width: 100%;\">{{displayRule}}</textarea>\r\n </div>\r\n </div>\r\n</ion-item>\r\n", styles: [".qbcontainer{border-radius:5px;border:1px solid rgba(0,0,0,.08);padding:10px;margin:10px 0;width:100%}#querybuilder .e-slider-container.e-control-wrapper{height:0}ejs-querybuilder{display:block}.e-query-builder{margin:0 auto;display:block}.highcontrast textarea#ruleContent{background-color:#000}\n"], components: [{ type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { type: i3.QueryBuilderComponent, selector: "ejs-querybuilder", inputs: ["allowValidation", "columns", "cssClass", "dataSource", "displayMode", "enableNotCondition", "enablePersistence", "enableRtl", "fieldMode", "fieldModel", "headerTemplate", "height", "immediateModeDelay", "locale", "matchCase", "maxGroupCount", "operatorModel", "readonly", "rule", "separator", "showButtons", "sortDirection", "summaryView", "valueModel", "width"], outputs: ["actionBegin", "beforeChange", "change", "created", "dataBound", "ruleChange"] }, { type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
346
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SfquerybuilderComponent, decorators: [{
347
+ type: Component,
348
+ args: [{ selector: 'app-sfquerybuilder', template: "<ion-item *ngIf=\"(!!componentProperties.isVisibleField ? group[componentProperties.isVisibleField] : componentProperties.isVisible)\">\r\n <!--<ejs-querybuilder *ngIf=\"issfLoaded && !data.ShowQueryResult\"\r\n #querybuilder\r\n width=\"100%\"\r\n [dataSource]=\"sfData\"\r\n [columns]=\"sdFilter\"\r\n [rule]=\"importRules\"\r\n (ruleChange)=\"updateRule($event)\"\r\n (created)=\"onChange()\">\r\n </ejs-querybuilder>-->\r\n\r\n\r\n <div class=\"qbcontainer\" >\r\n <ejs-querybuilder *ngIf=\"issfLoaded\"\r\n #querybuilder\r\n width=\"100%\"\r\n [dataSource]=\"sfData\"\r\n [columns]=\"sdFilter\"\r\n [rule]=\"importRules\"\r\n (ruleChange)=\"updateRule($event)\"\r\n (created)=\"onChange()\">\r\n </ejs-querybuilder>\r\n\r\n <div>\r\n <br>\r\n <ion-label>Result</ion-label>\r\n <textarea class=\"output\"\r\n resizable=\"none\"\r\n [rows]=\"10\"\r\n style=\"border: 1px solid #d3d3d3; width: 100%;\">{{displayRule}}</textarea>\r\n </div>\r\n </div>\r\n</ion-item>\r\n", styles: [".qbcontainer{border-radius:5px;border:1px solid rgba(0,0,0,.08);padding:10px;margin:10px 0;width:100%}#querybuilder .e-slider-container.e-control-wrapper{height:0}ejs-querybuilder{display:block}.e-query-builder{margin:0 auto;display:block}.highcontrast textarea#ruleContent{background-color:#000}\n"] }]
349
+ }], ctorParameters: function () { return [{ type: i1.FieldService }, { type: i1.ResourceApiService }, { type: i1.WebApiService }]; }, propDecorators: { qryBldrObj: [{
350
+ type: ViewChild,
351
+ args: ['querybuilder']
352
+ }], classNames: [{
353
+ type: Input
354
+ }], data: [{
355
+ type: Input
356
+ }], group: [{
357
+ type: Input
358
+ }], form: [{
359
+ type: Input
360
+ }] } });
361
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2ZxdWVyeWJ1aWxkZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbW1oZ2xvYmFsLWR5bmFtaWNmb3JtL3NyYy9saWIvc2ZxdWVyeWJ1aWxkZXIvc2ZxdWVyeWJ1aWxkZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbW1oZ2xvYmFsLWR5bmFtaWNmb3JtL3NyYy9saWIvc2ZxdWVyeWJ1aWxkZXIvc2ZxdWVyeWJ1aWxkZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0JBQStCO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLFNBQVMsRUFBb0IsTUFBTSxlQUFlLENBQUM7QUFHdEYsNkJBQTZCO0FBRTdCLDhCQUE4QjtBQUM5QixPQUFPLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRzVFLDJDQUEyQztBQUMzQyxPQUFPLEVBQ1MsZ0JBQWdCLEVBQUUsb0JBQW9CLEVBQ2hDLHdCQUF3QixFQUM3QyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFMUIsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7O0FBU25ELE1BQU0sT0FBTyx1QkFBdUI7SUF1Q2xDLFlBQ1UsWUFBMEIsRUFDMUIsa0JBQXNDLEVBQ3RDLGFBQTRCO1FBRjVCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMsa0JBQWEs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QUFJLGVBQWUsR0FBRyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzFELElBQUksZUFBZSxFQUFFO1lBQ25CLGVBQWUsR0FBRyxlQUFlLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUNuRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLGVBQWUsQ0FBQyxDQUFDO1lBRWpELElBQUksT0FBTyxRQUFRLEtBQUssVUFBVSxFQUFFO2dCQUNsQyxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNwQyxPQUFPLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDN0I7U0FDRjtRQUNELE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xCLENBQUM7O3FIQTVaVSx1QkFBdUI7eUdBQXZCLHVCQUF1Qix3UEM1QnBDLGl6Q0FpQ0E7NEZETGEsdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNFLG9CQUFvQjtnS0FLSCxVQUFVO3NCQUFwQyxTQUFTO3VCQUFDLGNBQWM7Z0JBRWhCLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKiBBbmd1bGFyICoqKioqKioqKiovXHJcbmltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgVmlld0NoaWxkLCBWaWV3Q29udGFpbmVyUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcblxyXG4vKioqKioqKioqKiBJb25pYyAqKioqKioqKioqL1xyXG5cclxuLyoqKioqKioqKiogUGx1Z2luICoqKioqKioqKiovXHJcbmltcG9ydCB7IGRlbGF5LCBpZ25vcmVFbGVtZW50cywgbWFwLCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgUXVlcnlCdWlsZGVyQ29uZmlnLCBRdWVyeUJ1aWxkZXJDbGFzc05hbWVzIH0gZnJvbSAnYW5ndWxhcjItcXVlcnktYnVpbGRlcic7XHJcblxyXG4vKioqKioqKioqKiBDb21wb25lbnQgJiBTZXJ2aWNlICoqKioqKioqKiovXHJcbmltcG9ydCB7XHJcbiAgRmllbGRTZXJ2aWNlLCBaQ29tcG9uZW50SGVscGVyLCBaQ29tcG9uZW50UHJvcGVydGllcywgWkZpZWxkLCBaR3JvdXAsXHJcbiAgRm9udEF3ZVNvbWVTZXJ2aWNlLCBEZWZhdWx0UGFnZVNldHRpbmdQYXJhbXMsIFdlYkFwaVNlcnZpY2UsIFJlc291cmNlQXBpU2VydmljZVxyXG59IGZyb20gJ21taGdsb2JhbC16Y29yZSc7XHJcbmltcG9ydCB7IG9mIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IFJ1bGVNb2RlbCwgUXVlcnlCdWlsZGVyQ29tcG9uZW50LCBDb2x1bW5zTW9kZWwsIFRlbXBsYXRlQ29sdW1uLCBSdWxlQ2hhbmdlRXZlbnRBcmdzIH0gZnJvbSAnQHN5bmNmdXNpb24vZWoyLWFuZ3VsYXItcXVlcnlidWlsZGVyJztcclxuaW1wb3J0IHsgRHJvcERvd25MaXN0LCBNdWx0aVNlbGVjdCB9IGZyb20gJ0BzeW5jZnVzaW9uL2VqMi1kcm9wZG93bnMnO1xyXG5pbXBvcnQgeyBnZXRDb21wb25lbnQsIGNyZWF0ZUVsZW1lbnQgfSBmcm9tICdAc3luY2Z1c2lvbi9lajItYmFzZSc7XHJcbmltcG9ydCB7IENoZWNrQm94IH0gZnJvbSAnQHN5bmNmdXNpb24vZWoyLWJ1dHRvbnMnO1xyXG5cclxuZGVjbGFyZSB2YXIgJDogYW55XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC1zZnF1ZXJ5YnVpbGRlcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3NmcXVlcnlidWlsZGVyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9zZnF1ZXJ5YnVpbGRlci5jb21wb25lbnQuc2NzcyddLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2ZxdWVyeWJ1aWxkZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIEBWaWV3Q2hpbGQoJ3F1ZXJ5YnVpbGRlcicpIHFyeUJsZHJPYmo6IFF1ZXJ5QnVpbGRlckNvbXBvbmVudDtcclxuXHJcbiAgQElucHV0KCkgY2xhc3NOYW1lczogUXVlcnlCdWlsZGVyQ2xhc3NOYW1lcztcclxuICBASW5wdXQoKSBkYXRhOiBaRmllbGQ7XHJcbiAgQElucHV0KCkgZ3JvdXA6IFpHcm91cDtcclxuICBASW5wdXQoKSBmb3JtOiBGb3JtR3JvdXA7XHJcblxyXG4gIHFiSXRlbXMgPSB7fTtcclxuXHJcbiAgcHVibGljIGNvbXBvbmVudFByb3BlcnRpZXMgPSBuZXcgWkNvbXBvbmVudFByb3BlcnRpZXMoKTtcclxuICBwdWJsaWMgcXVlcnlDdHJsOiBhbnk7XHJcbiAgcHVibGljIGN1cnJlbnRDb25maWc6IFF1ZXJ5QnVpbGRlckNvbmZpZyA9IHtcclxuICAgIGZpZWxkczoge30sXHJcbiAgICBhbGxvd0VtcHR5UnVsZXNldHM6IHRydWVcclxuICB9O1xyXG4gIHB1YmxpYyBhbGxvd1J1bGVzZXQ6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIHB1YmxpYyBhbGxvd0NvbGxhcHNlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgcHVibGljIHBlcnNpc3RWYWx1ZU9uRmllbGRDaGFuZ2U6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwdWJsaWMgaXNEaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHB1YmxpYyBydWxlOiBhbnk7XHJcbiAgcHVibGljIGZpbHRlcnM6IGFueTtcclxuXHJcbiAgcHVibGljIGlzc2ZMb2FkZWQ6IGJvb2xlYW4gPSBmYWxzZTsgXHJcbiAgcHJpdmF0ZSBmaWVsZHM6IGFueTtcclxuICBwdWJsaWMgZGlzcGxheVJ1bGU6IGFueSA9ICcnO1xyXG5cclxuICBwcml2YXRlIGxvYWRlZERyb3Bkb3duT3B0aW9ucyA9IFtdO1xyXG5cclxuICAvL3NmXHJcbiAgcHVibGljIHNmRGF0YTogT2JqZWN0W107XHJcbiAgcHVibGljIGltcG9ydFJ1bGVzOiBSdWxlTW9kZWw7XHJcbiAgLy9AVmlld0NoaWxkKCdxdWVyeWJ1aWxkZXInKSBxcnlCbGRyT2JqOiBRdWVyeUJ1aWxkZXJDb21wb25lbnQ7XHJcbiAgcHVibGljIHNkRmlsdGVyOiBDb2x1bW5zTW9kZWxbXSA9IFtdO1xyXG4gIHB1YmxpYyBzZlFCVGVtcGxhdGU6IFRlbXBsYXRlQ29sdW1uO1xyXG4gIHB1YmxpYyBpbk9wZXJhdG9yczogc3RyaW5nW10gPSBbJ2luJywgJ25vdGluJ107XHJcblxyXG4gIHB1YmxpYyBzZWxlY3Rpb25Db21wb25lbnRMaXN0ID0gW107XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBmaWVsZFNlcnZpY2U6IEZpZWxkU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVzb3VyY2VBcGlTZXJ2aWNlOiBSZXNvdXJjZUFwaVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHdlYkFwaVNlcnZpY2U6IFdlYkFwaVNlcnZpY2VcclxuICApIHtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgWkNvbXBvbmVudEhlbHBlci5zZXRDb21wb25lbnRQcm9wZXJ0aWVzKHRoaXMpO1xyXG4gICAgWkNvbXBvbmVudEhlbHBlci5yZWdpc3RlckNvbXBvbmVudCh0aGlzKTtcclxuXHJcbiAgICBvZih0cnVlKS5waXBlKFxyXG4gICAgICBzd2l0Y2hNYXAoY29udCA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYmVmb3JlTG9hZEZpZWxkKHRoaXMuZGF0YSk7XHJcbiAgICAgIH0pLFxyXG4gICAgICBzd2l0Y2hNYXAoY29udDIgPT4geyBcclxuICAgICAgICByZXR1cm4gdGhpcy5sb2FkUXVlcnlCdWlsZGVyKCk7XHJcbiAgICAgIH0pXHJcbiAgICApLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgIC8vIFdoZXJlIHRvIHVwZGF0ZSBvcGVyYXRvciBzeW50YXhcclxuICAgICAgLy8gMS4gRTEgLSBxdWVyeUJ1aWxkZXJUZW1wbGF0ZTJcclxuICAgICAgLy8gMi4gc2hhcmVkIGZvbGRlciA+IGhlbHBlciA+IHF1ZXJ5YnVpbGRlci1maWVsZGluZm8taGVscGVyLnRzXHJcbiAgICAgIC8vIDMuIHBhdGNoIGRiIGRhdGEgd2l0aCBzbWFsbCBjYXBpdGFsIGxldHRlclxyXG4gICAgICBcclxuICAgICAgLy90aGlzLmlzc2ZMb2FkZWQgPSB0cnVlOyAgXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgbG9hZFF1ZXJ5QnVpbGRlcigpIHtcclxuICAgIGlmICh0aGlzLmRhdGFbJ0FsbG93Q29sbGFwc2UnXSA9PT0gdHJ1ZSkge1xyXG4gICAgICB0aGlzLmFsbG93Q29sbGFwc2UgPSB0aGlzLmRhdGFbJ0FsbG93Q29sbGFwc2UnXTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5kYXRhWydBbGxvd1J1bGVzZXQnXSA9PT0gZmFsc2UpIHtcclxuICAgICAgdGhpcy5hbGxvd1J1bGVzZXQgPSB0aGlzLmRhdGFbJ0FsbG93UnVsZXNldCddO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmRhdGFbJ0ZpbHRlcnMnXSkge1xyXG4gICAgICB0aGlzLmZpbHRlcnMgPSBaQ29tcG9uZW50SGVscGVyLmdldEdyb3VwRXZhbFZhbHVlLmNhbGwoXHJcbiAgICAgICAgdGhpcyxcclxuICAgICAgICB0aGlzLmRhdGFbJ0ZpbHRlcnMnXSxcclxuICAgICAgICB0aGlzLmdyb3VwXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5maWVsZHMgPSB0aGlzLmZpZWxkU2VydmljZS5nZXRGb3JtRmllbGRDb2RlKHRoaXMuZGF0YS5WYWx1ZSwgXCJGb3JtRmllbGRcIiwgbnVsbCwgbnVsbCk7XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgcmV0dXJuIHRoaXMuZmllbGRzLnBpcGUoXHJcbiAgICAgICAgdGFwKChkYXRhOiBbXSkgPT4ge1xyXG4gICAgICAgICAgZGF0YS5mb3JFYWNoKGFzeW5jIChmaWVsZDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIC8vc2YgLy90b2RvOiBsYXRlciBjaGFuZ2UgdG8gYmFzZSBvbiBvdGhlciBhdHRyaWJ1dGUgc2luZ2xlIG9yIG11bHRpIHNlbGVjdCBmb3IgZmllbGQgZWxlbWVudFxyXG4gICAgICAgICAgICBpZiAoZmllbGQuVHlwZSA9PSAnY2F0ZWdvcnknIHx8IGZpZWxkLlR5cGUgPT0gJ211bHRpc2VsZWN0Jykge1xyXG4gICAgICAgICAgICAgIHRoaXMuc2RGaWx0ZXIucHVzaCh7XHJcbiAgICAgICAgICAgICAgICBmaWVsZDogZmllbGQuVmFsdWUsXHJcbiAgICAgICAgICAgICAgICBsYWJlbDogZmllbGQuTmFtZSxcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxyXG4gICAgICAgICAgICAgICAgdGVtcGxhdGU6IGF3YWl0IHRoaXMuZ2VuZXJhdGVDb2x1bW5TZWxlY3Rpb24oZmllbGQpLFxyXG4gICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoZmllbGQuVHlwZSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgICB0aGlzLnNkRmlsdGVyLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgZmllbGQ6IGZpZWxkLlZhbHVlLFxyXG4gICAgICAgICAgICAgICAgbGFiZWw6IGZpZWxkLk5hbWUsXHJcbiAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xyXG4gICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoZmllbGQuVHlwZSA9PT0gJ2RhdGUnKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5zZEZpbHRlci5wdXNoKHtcclxuICAgICAgICAgICAgICAgIGZpZWxkOiBmaWVsZC5WYWx1ZSxcclxuICAgICAgICAgICAgICAgIGxhYmVsOiBmaWVsZC5OYW1lLFxyXG4gICAgICAgICAgICAgICAgdHlwZTogJ2RhdGUnXHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChmaWVsZC5UeXBlID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgICAgICAgIHRoaXMuc2RGaWx0ZXIucHVzaCh7XHJcbiAgICAgICAgICAgICAgICBmaWVsZDogZmllbGQuVmFsdWUsXHJcbiAgICAgICAgICAgICAgICBsYWJlbDogZmllbGQuTmFtZSxcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdudW1iZXInXHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChmaWVsZC5WYWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5zZEZpbHRlci5wdXNoKHtcclxuICAgICAgICAgICAgICAgIGZpZWxkOiBmaWVsZC5WYWx1ZSxcclxuICAgICAgICAgICAgICAgIGxhYmVsOiBmaWVsZC5OYW1lLFxyXG4gICAgICAgICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxyXG4gICAgICAgICAgICAgICAgdGVtcGxhdGU6IGF3YWl0IHRoaXMuZ2VuZXJhdGVDb2x1bW5DaGVja2JveChmaWVsZC5OYW1lLCBmYWxzZSlcclxuICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMuc2RGaWx0ZXIucHVzaCh7XHJcbiAgICAgICAgICAgICAgICBmaWVsZDogZmllbGQuVmFsdWUsXHJcbiAgICAgICAgICAgICAgICBsYWJlbDogZmllbGQuTmFtZSxcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnXHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSk7Ly9lbmQgZm9yZWFjaFxyXG4gICAgICAgICAgdGhpcy5pc3NmTG9hZGVkID0gdHJ1ZTtcclxuICAgICAgICB9KVxyXG4gICAgICApXHJcbiAgICAgIC8vfSk7XHJcblxyXG4gICAgICByZXR1cm4gb2YodHJ1ZSk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmVycm9yKFwiZXJyb3I6IFwiLCBlcnJvcik7XHJcbiAgICAgIHJldHVybiBvZihmYWxzZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyNyZWdpb24gY2hlY2tib3hcclxuICBwcml2YXRlIGdlbmVyYXRlQ29sdW1uQ2hlY2tib3gobGFiZWw6IHN0cmluZywgdmFsdWU6IGJvb2xlYW4pOiBUZW1wbGF0ZUNvbHVtbiB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBjcmVhdGU6ICgpID0+IHtcclxuICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudCgnaW5wdXQnLCB7IGF0dHJzOiB7ICd0eXBlJzogJ2NoZWNrYm94JyB9IH0pO1xyXG4gICAgICB9LFxyXG4gICAgICBkZXN0cm95OiAoYXJnczogeyBlbGVtZW50SWQ6IHN0cmluZyB9KSA9PiB7XHJcbiAgICAgICAgKGdldENvbXBvbmVudChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhcmdzLmVsZW1lbnRJZCksICdjaGVja2JveCcpIGFzIENoZWNrQm94KS5kZXN0cm95KCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIHdyaXRlOiAoYXJnczogeyBlbGVtZW50czogRWxlbWVudCwgdmFsdWVzOiBzdHJpbmcgfSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGJveE9iajogQ2hlY2tCb3ggPSBuZXcgQ2hlY2tCb3goe1xyXG4gICAgICAgICAgbGFiZWw6IGxhYmVsLFxyXG4gICAgICAgICAgY2hlY2tlZDogdmFsdWUsXHJcbiAgICAgICAgICBjaGFuZ2U6IChlOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5xcnlCbGRyT2JqLm5vdGlmeUNoYW5nZSh2YWx1ZSwgZS5ldmVudC50YXJnZXQpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGJveE9iai5hcHBlbmRUbygnIycgKyBhcmdzLmVsZW1lbnRzLmlkKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuICB9XHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG4gIC8vI3JlZ2lvbiBkcm9wZG93bi9tdWx0aXNlbGVjdFxyXG4gIHByaXZhdGUgZ2VuZXJhdGVDb2x1bW5TZWxlY3Rpb24oZmllbGRFbGVtZW50RGF0YTogYW55KTogVGVtcGxhdGVDb2x1bW4ge1xyXG4gICAgcmV0dXJuIHtcclxuXHJcbiAgICAgIC8vIENyZWF0ZXMgdGhlIGN1c3RvbSBjb21wb25lbnRcclxuICAgICAgY3JlYXRlOiAoKSA9PiB7XHJcbiAgICAgICAgLy8gQWRkaXRpb25hbCBmaWx0ZXIgc2V0IGluIHRoZSBwYWdlXHJcbiAgICAgICAgaWYgKHRoaXMuZGF0YVsnRmlsdGVycyddKSB7XHJcbiAgICAgICAgICB0aGlzLmZpbHRlcnMgPSBaQ29tcG9uZW50SGVscGVyLmdldEdyb3VwRXZhbFZhbHVlLmNhbGwoXHJcbiAgICAgICAgICAgIHRoaXMsXHJcbiAgICAgICAgICAgIHRoaXMuZGF0YVsnRmlsdGVycyddLFxyXG4gICAgICAgICAgICB0aGlzLmdyb3VwXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUVsZW1lbnQoJ2lucHV0JywgeyBhdHRyczogeyAndHlwZSc6ICd0ZXh0JywgJ3N0eWxlJzogJ2Rpc3BsYXk6IG5vbmUnIH0gfSk7IC8vY3JlYXRlRWxlbWVudCgnaW5wdXQnLCB7IGF0dHJzOiB7ICd0eXBlJzogJ3RleHQnIH0gfSk7XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICAvLyBEZXN0cm95IHRoZSBjdXN0b20gY29tcG9uZW50XHJcbiAgICAgIGRlc3Ryb3k6IChhcmdzOiB7IGVsZW1lbnRJZDogc3RyaW5nIH0pID0+IHtcclxuICAgICAgICBpZiAoYXJnc1snZWxlbWVudHMnXSkge1xyXG4gICAgICAgICAgbGV0IG11bHRpU2VsZWN0OiBNdWx0aVNlbGVjdCA9IChnZXRDb21wb25lbnQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYXJncy5lbGVtZW50SWQpLCAnbXVsdGlzZWxlY3QnKSBhcyBNdWx0aVNlbGVjdCk7XHJcbiAgICAgICAgICBpZiAobXVsdGlTZWxlY3QpIHtcclxuICAgICAgICAgICAgbXVsdGlTZWxlY3QuZGVzdHJveSgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgbGV0IGRyb3Bkb3duOiBEcm9wRG93bkxpc3QgPSAoZ2V0Q29tcG9uZW50KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGFyZ3MuZWxlbWVudElkKSwgJ2Ryb3Bkb3dubGlzdCcpIGFzIERyb3BEb3duTGlzdCk7XHJcbiAgICAgICAgICBpZiAoZHJvcGRvd24pIHtcclxuICAgICAgICAgICAgZHJvcGRvd24uZGVzdHJveSgpO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGNvbnN0IHNlbGVjdE9wdGlvbnMgPSBmaWVsZEVsZW1lbnREYXRhWydTZWxlY3RPcHRpb25zJ107XHJcbiAgICAgICAgICBpZiAoc2VsZWN0T3B0aW9ucykge1xyXG4gICAgICAgICAgICBjb25zdCBzZWxlY3RPcHRpb25zUmVzb3VyY2VVUkwgPSBzZWxlY3RPcHRpb25zWydSZXNvdXJjZVVSTCddO1xyXG4gICAgICAgICAgICBjb25zdCBwcmVmaXhSZXNvdXJjZVVSTENoZWNraW5nID0gc2VsZWN0T3B0aW9uc1Jlc291cmNlVVJMICsgJ18nICsgYXJncy5lbGVtZW50SWQ7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5sb2FkZWREcm9wZG93bk9wdGlvbnMuaW5jbHVkZXMocHJlZml4UmVzb3VyY2VVUkxDaGVja2luZykpIHtcclxuICAgICAgICAgICAgICB0aGlzLmxvYWRlZERyb3Bkb3duT3B0aW9ucyA9IHRoaXMucmVtb3ZlQXJyYXlJdGVtKHRoaXMubG9hZGVkRHJvcGRvd25PcHRpb25zLCBwcmVmaXhSZXNvdXJjZVVSTENoZWNraW5nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuXHJcbiAgICAgIC8vIFdpcmUgZXZlbnRzIGZvciB0aGUgY3VzdG9tIGNvbXBvbmVudC5cclxuICAgICAgd3JpdGU6IChhcmdzOiB7IGVsZW1lbnRzOiBFbGVtZW50LCB2YWx1ZXM6IHN0cmluZ1tdIHwgc3RyaW5nLCBvcGVyYXRvcjogc3RyaW5nIH0pID0+IHtcclxuICAgICAgICAvL29yaWdpblxyXG4gICAgICAgIGlmIChmaWVsZEVsZW1lbnREYXRhWydWYWx1ZU9wdGlvbnMnXSkge1xyXG4gICAgICAgICAgLy8gY29udmVydCB0byBwcm9wZXJ0eSBuYW1lIHVzZWQgaW4gdGhlIGNvbXBvbmVudCByZW5kZXJpbmdcclxuICAgICAgICAgIGNvbnN0IG9wdGlvbkxpc3Q6IHsgW25hbWU6IHN0cmluZ106IE9iamVjdCB9W10gPSBbXTtcclxuICAgICAgICAgIGZpZWxkRWxlbWVudERhdGFbJ1ZhbHVlT3B0aW9ucyddLmZvckVhY2goKGl0ZW06IGFueSkgPT4ge1xyXG4gICAgICAgICAgICBvcHRpb25MaXN0LnB1c2goe1xyXG4gICAgICAgICAgICAgIHRleHQ6IGl0ZW1bJ05hbWUnXSxcclxuICAgICAgICAgICAgICB2YWx1ZTogaXRlbVsnVmFsdWUnXVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH0pXHJcblxyXG4gICAgICAgICAgY29uc3Qgc2VsZWN0aW9uQ29tcG9uZW50ID0gdGhpcy5nZW5lcmF0ZVNlbGVjdGlvbkNvbXBvbmVudChhcmdzLCBvcHRpb25MaXN0KTtcclxuICAgICAgICAgIHNlbGVjdGlvbkNvbXBvbmVudC5hcHBlbmRUbygnIycgKyBhcmdzLmVsZW1lbnRzLmlkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICBjb25zdCBzZWxlY3RPcHRpb25zID0gZmllbGRFbGVtZW50RGF0YVsnU2VsZWN0T3B0aW9ucyddO1xyXG4gICAgICAgICAgY29uc3Qgc2VsZWN0T3B0aW9uc1Jlc291cmNlVVJMID0gc2VsZWN0T3B0aW9uc1snUmVzb3VyY2VVUkwnXTtcclxuICAgICAgICAgIGNvbnN0IHByZWZpeFJlc291cmNlVVJMQ2hlY2tpbmcgPSBzZWxlY3RPcHRpb25zUmVzb3VyY2VVUkwgKyAnXycgKyBhcmdzLmVsZW1lbnRzLmlkO1xyXG5cclxuICAgICAgICAgIGlmICghdGhpcy5sb2FkZWREcm9wZG93bk9wdGlvbnMuaW5jbHVkZXMocHJlZml4UmVzb3VyY2VVUkxDaGVja2luZykpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2FkZWREcm9wZG93bk9wdGlvbnMucHVzaChwcmVmaXhSZXNvdXJjZVVSTENoZWNraW5nKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmZpbHRlcnMpIHtcclxuICAgICAgICAgICAgICBzZWxlY3RPcHRpb25zWydGaWx0ZXJzJ10gPSB0aGlzLmZpbHRlcnM7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtID0gT2JqZWN0LmFzc2lnbih7fSwgRGVmYXVsdFBhZ2VTZXR0aW5nUGFyYW1zKTtcclxuICAgICAgICAgICAgcGFyYW0ucGFnZVNpemUgPSBzZWxlY3RPcHRpb25zWydQYWdlU2l6ZSddO1xyXG4gICAgICAgICAgICBwYXJhbS5jb2x1bW5zID0gc2VsZWN0T3B0aW9uc1snQ29sdW1ucyddO1xyXG4gICAgICAgICAgICBwYXJhbS5maWx0ZXJzICs9IHNlbGVjdE9wdGlvbnNbJ0ZpbHRlcnMnXTtcclxuICAgICAgICAgICAgcGFyYW0uc29ydENvbHVtbk5hbWUgPSBzZWxlY3RPcHRpb25zWydTb3J0Q29sdW1uTmFtZSddO1xyXG4gICAgICAgICAgICBwYXJhbS5zb3J0T3JkZXIgPSBzZWxlY3RPcHRpb25zWydTb3J0T3JkZXInXTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMud2ViQXBpU2VydmljZS5odHRwUG9zdCQodGhpcy5yZXNvdXJjZUFwaVNlcnZpY2UuZ2V0UGFnZVVybChzZWxlY3RPcHRpb25zUmVzb3VyY2VVUkwpLCBwYXJhbSkucGlwZShcclxuICAgICAgICAgICAgICBkZWxheSgzMDApLFxyXG4gICAgICAgICAgICAgIG1hcCgocmVzcCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9uTGlzdCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgcmVzcC5kYXRhU2V0LmZvckVhY2goKGl0ZW06IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICBvcHRpb25MaXN0LnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IGl0ZW1bc2VsZWN0T3B0aW9uc1snTmFtZSddXSxcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaXRlbVtzZWxlY3RPcHRpb25zWydWYWx1ZSddXVxyXG4gICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pXHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2VsZWN0aW9uQ29tcG9uZW50ID0gdGhpcy5nZW5lcmF0ZVNlbGVjdGlvbkNvbXBvbmVudChhcmdzLCBvcHRpb25MaXN0KTtcclxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbkNvbXBvbmVudC5hcHBlbmRUbygnIycgKyBhcmdzLmVsZW1lbnRzLmlkKTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCB4eHggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhcmdzLmVsZW1lbnRzLmlkKTtcclxuICAgICAgICAgICAgICAgIC8veHh4LmFwcGVuZENoaWxkKGlucHV0RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICB4eHguc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8jcmVnaW9uIHVzZWQgZm9yIHVwZGF0ZVNlbGVjdGlvbk9wdGlvblxyXG4gICAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdJbmRleCA9IHRoaXMuc2VsZWN0aW9uQ29tcG9uZW50TGlzdC5maW5kSW5kZXgoXHJcbiAgICAgICAgICAgICAgICAgIChpdGVtKSA9PiBpdGVtLmNvbXBvbmVudElkID09PSBhcmdzLmVsZW1lbnRzLmlkXHJcbiAgICAgICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ0luZGV4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAvLyBPYmplY3Qgd2l0aCB0aGUgc2FtZSBjb21wb25lbnRJZCBleGlzdHMsIHJlcGxhY2UgcmVzb3VyY2VVcmxcclxuICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25Db21wb25lbnRMaXN0W2V4aXN0aW5nSW5kZXhdLnJlc291cmNlVXJsID0gc2VsZWN0T3B0aW9uc1Jlc291cmNlVVJMO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgLy8gT2JqZWN0IHdpdGggY29tcG9uZW50SWQgZG9lc24ndCBleGlzdCwgcHVzaCBhIG5ldyBvYmplY3RcclxuICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25Db21wb25lbnRMaXN0LnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc291cmNlVXJsOiBzZWxlY3RPcHRpb25zUmVzb3VyY2VVUkwsXHJcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50SWQ6IGFyZ3MuZWxlbWVudHMuaWRcclxuICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyNlbmRyZWdpb25cclxuICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfS8vZW5kIHdyaXRlXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdXBkYXRlU2VsZWN0aW9uT3B0aW9uKHJlc291cmNlVXJsOiBzdHJpbmcsIGRhdGE6IGFueSkge1xyXG4gICAgdGhpcy5zZWxlY3Rpb25Db21wb25lbnRMaXN0LmZvckVhY2goc2VsZWN0aW9uQ29tcG9uZW50ID0+IHtcclxuICAgICAgbGV0IG11bHRpU2VsZWN0OiBNdWx0aVNlbGVjdCA9IChnZXRDb21wb25lbnQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc2VsZWN0aW9uQ29tcG9uZW50LmNvbXBvbmVudElkKSwgJ211bHRpc2VsZWN0JykgYXMgTXVsdGlTZWxlY3QpO1xyXG4gICAgICBpZiAobXVsdGlTZWxlY3QpIHtcclxuICAgICAgICBtdWx0aVNlbGVjdC52YWx1ZSA9IGRhdGE7XHJcbiAgICAgIH1cclxuICAgICAgbGV0IGRyb3Bkb3duOiBEcm9wRG93bkxpc3QgPSAoZ2V0Q29tcG9uZW50KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHNlbGVjdGlvbkNvbXBvbmVudC5jb21wb25lbnRJZCksICdkcm9wZG93bmxpc3QnKSBhcyBEcm9wRG93bkxpc3QpO1xyXG4gICAgICBpZiAoZHJvcGRvd24pIHtcclxuICAgICAgICB0aGlzLmZpZWxkU2VydmljZS5kYXRhRm9ybUZpZWxkc1t0aGlzLmRhdGEuVmFsdWVdLmZvckVhY2goYXN5bmMgKGZpZWxkOiBhbnkpID0+IHtcclxuICAgICAgICAgIGlmIChmaWVsZC5TZWxlY3RPcHRpb25zLlJlc291cmNlVVJMID09PSBzZWxlY3Rpb25Db21wb25lbnQucmVzb3VyY2VVcmwpIHtcclxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0T3B0aW9ucyA9IGZpZWxkWydTZWxlY3RPcHRpb25zJ107XHJcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdE9wdGlvbnNSZXNvdXJjZVVSTCA9IHNlbGVjdE9wdGlvbnNbJ1Jlc291cmNlVVJMJ107XHJcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtID0gT2JqZWN0LmFzc2lnbih7fSwgRGVmYXVsdFBhZ2VTZXR0aW5nUGFyYW1zKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGFbJ0ZpbHRlcnMnXSkge1xyXG4gICAgICAgICAgICAgIHRoaXMuZmlsdGVycyA9IFpDb21wb25lbnRIZWxwZXIuZ2V0R3JvdXBFdmFsVmFsdWUuY2FsbChcclxuICAgICAgICAgICAgICAgIHRoaXMsXHJcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFbJ0ZpbHRlcnMnXSxcclxuICAgICAgICAgICAgICAgIHRoaXMuZ3JvdXBcclxuICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5maWx0ZXJzKSB7XHJcbiAgICAgICAgICAgICAgc2VsZWN0T3B0aW9uc1snRmlsdGVycyddID0gdGhpcy5maWx0ZXJzO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBwYXJhbS5wYWdlU2l6ZSA9IHNlbGVjdE9wdGlvbnNbJ1BhZ2VTaXplJ107XHJcbiAgICAgICAgICAgIHBhcmFtLmNvbHVtbnMgPSBzZWxlY3RPcHRpb25zWydDb2x1bW5zJ107XHJcbiAgICAgICAgICAgIHBhcmFtLmZpbHRlcnMgKz0gc2VsZWN0T3B0aW9uc1snRmlsdGVycyddO1xyXG4gICAgICAgICAgICBwYXJhbS5zb3J0Q29sdW1uTmFtZSA9IHNlbGVjdE9wdGlvbnNbJ1NvcnRDb2x1bW5OYW1lJ107XHJcbiAgICAgICAgICAgIHBhcmFtLnNvcnRPcmRlciA9IHNlbGVjdE9wdGlvbnNbJ1NvcnRPcmRlciddO1xyXG5cclxuICAgICAgICAgICAgdGhpcy53ZWJBcGlTZXJ2aWNlLmh0dHBQb3N0JCh0aGlzLnJlc291cmNlQXBpU2VydmljZS5nZXRQYWdlVXJsKHNlbGVjdE9wdGlvbnNSZXNvdXJjZVVSTCksIHBhcmFtKS5waXBlKFxyXG4gICAgICAgICAgICAgIG1hcCgocmVzcCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9uTGlzdCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgcmVzcC5kYXRhU2V0LmZvckVhY2goKGl0ZW06IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICBvcHRpb25MaXN0LnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IGl0ZW1bc2VsZWN0T3B0aW9uc1snTmFtZSddXSxcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaXRlbVtzZWxlY3RPcHRpb25zWydWYWx1ZSddXVxyXG4gICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pXHJcblxyXG4gICAgICAgICAgICAgICAgZHJvcGRvd24uZGF0YVNvdXJjZSA9IG9wdGlvbkxpc3Q7XHJcbiAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSlcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVtb3ZlQXJyYXlJdGVtPFQ+KGFycjogQXJyYXk8VD4sIHZhbHVlOiBUKTogQXJyYXk8VD4ge1xyXG4gICAgY29uc3QgaW5kZXggPSBhcnIuaW5kZXhPZih2YWx1ZSk7XHJcbiAgICBpZiAoaW5kZXggPiAtMSkge1xyXG4gICAgICBhcnIuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIH1cclxuICAgIHJldHVybiBhcnI7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdlbmVyYXRlU2VsZWN0aW9uQ29tcG9uZW50KGFyZ3M6IGFueSwgb3B0aW9uTGlzdDogYW55KSB7XHJcbiAgICBpZiAodGhpcy5pbk9wZXJhdG9ycy5pbmRleE9mKGFyZ3Mub3BlcmF0b3IpID4gLTEpIHtcclxuICAgICAgcmV0dXJuIG5ldyBNdWx0aVNlbGVjdCh7XHJcbiAgICAgICAgZGF0YVNvdXJjZTogb3B0aW9uTGlzdCxcclxuICAgICAgICBmaWVsZHM6IHsgdGV4dDogJ3RleHQnLCB2YWx1ZTogJ3ZhbHVlJyB9LFxyXG4gICAgICAgIHZhbHVlOiBhcmdzLnZhbHVlcyBhcyBzdHJpbmdbXSxcclxuICAgICAgICBtb2RlOiAnQ2hlY2tCb3gnLFxyXG4gICAgICAgIGNoYW5nZTogKGU6IGFueSkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5xcnlCbGRyT2JqLm5vdGlmeUNoYW5nZShlLnZhbHVlLCBlLmVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgcmV0dXJuIG5ldyBEcm9wRG93bkxpc3Qoe1xyXG4gICAgICAgIGRhdGFTb3VyY2U6IG9wdGlvbkxpc3QsXHJcbiAgICAgICAgZmllbGRzOiB7IHRleHQ6ICd0ZXh0JywgdmFsdWU6ICd2YWx1ZScgfSxcclxuICAgICAgICB2YWx1ZTogYXJncy52YWx1ZXMgYXMgc3RyaW5nLFxyXG4gICAgICAgIGNoYW5nZTogKGU6IGFueSkgPT4ge1xyXG4gICAgICAgICAgZS52YWx1ZSAhPT0gbnVsbCA/IHRoaXMucXJ5Qmxkck9iai5ub3RpZnlDaGFuZ2UoZS5pdGVtRGF0YS52YWx1ZSwgZS5lbGVtZW50KSA6IGlnbm9yZUVsZW1lbnRzO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuICBwdWJsaWMgc2V0UXVlcnlWYWx1ZShzYXZlZERhdGE6IGFueSkge1xyXG4gICAgLy9pZiAoIXRoaXMucXJ5Qmxkck9iaikge1xyXG4gICAgLy8gIGNvbnNvbGUud2FybigncXVlcnkgYnVpbGRlciBvYmplY3QgaXMgbnVsbC4nKTtcclxuICAgIC8vICByZXR1cm47XHJcbiAgICAvL31cclxuXHJcbiAgICBpZiAoc2F2ZWREYXRhKSB7XHJcbiAgICAgIHRoaXMucXJ5Qmxkck9iai5zZXRSdWxlcyhzYXZlZERhdGEpO1xyXG4gICAgICB0aGlzLnVwZGF0ZVJ1bGUoeyBydWxlOiBzYXZlZERhdGEgfSk7XHJcblxyXG5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRSZXN1bHQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5xcnlCbGRyT2JqLmdldFJ1bGVzKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdXBkYXRlUnVsZShhcmdzOiBSdWxlQ2hhbmdlRXZlbnRBcmdzKTogdm9pZCB7XHJcbiAgICB0aGlzLmRpc3BsYXlSdWxlID0gSlNPTi5zdHJpbmdpZnkoYXJncy5ydWxlLCBudWxsLCAxMik7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25DaGFuZ2UoKTogdm9pZCB7XHJcbiAgICB0aGlzLnVwZGF0ZVJ1bGUoeyBydWxlOiB0aGlzLnFyeUJsZHJPYmouZ2V0VmFsaWRSdWxlcyh0aGlzLnFyeUJsZHJPYmoucnVsZSkgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYmVmb3JlTG9hZEZpZWxkKGZpZWxkRWxlbWVudERhdGE6IGFueSkge1xyXG4gICAgbGV0IGJlZm9yZUxvYWRGaWVsZCA9IGZpZWxkRWxlbWVudERhdGFbJ0JlZm9yZUxvYWRGaWVsZCddO1xyXG4gICAgaWYgKGJlZm9yZUxvYWRGaWVsZCkge1xyXG4gICAgICBiZWZvcmVMb2FkRmllbGQgPSBiZWZvcmVMb2FkRmllbGQucmVwbGFjZSgnbW9kYWxHcm91cC4nLCAnZ3JvdXAuJyk7XHJcbiAgICAgIGNvbnN0IGNhbGxGdW5jID0gZXZhbCgndGhpcy4nICsgYmVmb3JlTG9hZEZpZWxkKTtcclxuXHJcbiAgICAgIGlmICh0eXBlb2YgY2FsbEZ1bmMgPT09IFwiZnVuY3Rpb25cIikge1xyXG4gICAgICAgIGNvbnN0IG5ld0Z1bmMgPSBjYWxsRnVuYy5iaW5kKHRoaXMpO1xyXG4gICAgICAgIHJldHVybiBuZXdGdW5jKGV2ZW50LCB0aGlzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG9mKHRydWUpO1xyXG4gIH1cclxufVxyXG5cclxuLy9leHBvcnQgZW51bSBvcGVyYXRvcnMge1xyXG4vLyAgSW4gPSAnaW4nLFxyXG4vL31cclxuXHJcblxyXG4vL2V4cG9ydCBpbnRlcmZhY2UgUXVlcnlSdWxlIHtcclxuLy8gIGNvbmRpdGlvbjogc3RyaW5nO1xyXG4vLyAgcnVsZXM6IFF1ZXJ5UnVsZVtdO1xyXG4vLyAgZmllbGQ6IHN0cmluZztcclxuLy8gIHR5cGU6IHN0cmluZztcclxuLy8gIG9wZXJhdG9yOiBzdHJpbmc7XHJcbi8vICB2YWx1ZTogc3RyaW5nW107XHJcbi8vfVxyXG5cclxuLy9leHBvcnQgZnVuY3Rpb24gdG9RdWVyeVJ1bGUocXVlcnlCdWlsZGVyTW9kZWw6IGFueSk6IFF1ZXJ5UnVsZSB7XHJcbi8vICBsZXQgcnVsZSA9IDxRdWVyeVJ1bGU+e307XHJcbi8vICBpZiAocXVlcnlCdWlsZGVyTW9kZWwuY29uZGl0aW9uKSB7XHJcbi8vICAgIHJ1bGUuY29uZGl0aW9uID0gcXVlcnlCdWlsZGVyTW9kZWwuY29uZGl0aW9uO1xyXG4vLyAgICBydWxlLnJ1bGVzID0gcXVlcnlCdWlsZGVyTW9kZWwucnVsZXMubWFwKHEgPT4gdG9RdWVyeVJ1bGUocSkpO1xyXG4vLyAgfVxyXG4vLyAgZWxzZSB7XHJcbi8vICAgIHJ1bGUuZmllbGQgPSBxdWVyeUJ1aWxkZXJNb2RlbC5maWVsZDtcclxuLy8gICAgcnVsZS50eXBlID0gJ3N0cmluZyc7XHJcbi8vICAgIHJ1bGUub3BlcmF0b3IgPSAnZXF1YWwnO1xyXG4vLyAgICBydWxlLnZhbHVlID0gcXVlcnlCdWlsZGVyTW9kZWwudmFsdWUgaW5zdGFuY2VvZiBBcnJheVxyXG4vLyAgICAgID8gcXVlcnlCdWlsZGVyTW9kZWwudHlwZSA9PT0gJ2RhdGUnID8gbmV3IERhdGUocXVlcnlCdWlsZGVyTW9kZWwudmFsdWUpIDogcXVlcnlCdWlsZGVyTW9kZWwudmFsdWVcclxuLy8gICAgICA6IFtxdWVyeUJ1aWxkZXJNb2RlbC50eXBlID09PSAnZGF0ZScgPyBuZXcgRGF0ZShxdWVyeUJ1aWxkZXJNb2RlbC52YWx1ZSkgOiBxdWVyeUJ1aWxkZXJNb2RlbC52YWx1ZV07XHJcbi8vICB9XHJcbi8vICByZXR1cm4gcnVsZTtcclxuLy99XHJcbiIsIjxpb24taXRlbSAqbmdJZj1cIighIWNvbXBvbmVudFByb3BlcnRpZXMuaXNWaXNpYmxlRmllbGQgPyBncm91cFtjb21wb25lbnRQcm9wZXJ0aWVzLmlzVmlzaWJsZUZpZWxkXSA6IGNvbXBvbmVudFByb3BlcnRpZXMuaXNWaXNpYmxlKVwiPlxyXG4gIDwhLS08ZWpzLXF1ZXJ5YnVpbGRlciAqbmdJZj1cImlzc2ZMb2FkZWQgJiYgIWRhdGEuU2hvd1F1ZXJ5UmVzdWx0XCJcclxuICAgICAgICAgICAgICAgICAgICAjcXVlcnlidWlsZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg9XCIxMDAlXCJcclxuICAgICAgICAgICAgICAgICAgICBbZGF0YVNvdXJjZV09XCJzZkRhdGFcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtjb2x1bW5zXT1cInNkRmlsdGVyXCJcclxuICAgICAgICAgICAgICAgICAgICBbcnVsZV09XCJpbXBvcnRSdWxlc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgKHJ1bGVDaGFuZ2UpPVwidXBkYXRlUnVsZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAoY3JlYXRlZCk9XCJvbkNoYW5nZSgpXCI+XHJcbiAgPC9lanMtcXVlcnlidWlsZGVyPi0tPlxyXG5cclxuXHJcbiAgPGRpdiBjbGFzcz1cInFiY29udGFpbmVyXCIgPlxyXG4gICAgPGVqcy1xdWVyeWJ1aWxkZXIgKm5nSWY9XCJpc3NmTG9hZGVkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICNxdWVyeWJ1aWxkZXJcclxuICAgICAgICAgICAgICAgICAgICAgIHdpZHRoPVwiMTAwJVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICBbZGF0YVNvdXJjZV09XCJzZkRhdGFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgW2NvbHVtbnNdPVwic2RGaWx0ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgW3J1bGVdPVwiaW1wb3J0UnVsZXNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgKHJ1bGVDaGFuZ2UpPVwidXBkYXRlUnVsZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgIChjcmVhdGVkKT1cIm9uQ2hhbmdlKClcIj5cclxuICAgIDwvZWpzLXF1ZXJ5YnVpbGRlcj5cclxuXHJcbiAgICA8ZGl2PlxyXG4gICAgICA8YnI+XHJcbiAgICAgIDxpb24tbGFiZWw+UmVzdWx0PC9pb24tbGFiZWw+XHJcbiAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cIm91dHB1dFwiXHJcbiAgICAgICAgICAgICAgICByZXNpemFibGU9XCJub25lXCJcclxuICAgICAgICAgICAgICAgIFtyb3dzXT1cIjEwXCJcclxuICAgICAgICAgICAgICAgIHN0eWxlPVwiYm9yZGVyOiAxcHggc29saWQgI2QzZDNkMzsgd2lkdGg6IDEwMCU7XCI+e3tkaXNwbGF5UnVsZX19PC90ZXh0YXJlYT5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG48L2lvbi1pdGVtPlxyXG4iXX0=