@ng-formworks/core 18.5.1 → 19.5.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 +2 -1
- package/fesm2022/ng-formworks-core.mjs +130 -110
- package/fesm2022/ng-formworks-core.mjs.map +1 -1
- package/package.json +3 -3
- package/esm2022/lib/framework-library/framework-library.service.mjs +0 -172
- package/esm2022/lib/framework-library/framework.mjs +0 -15
- package/esm2022/lib/framework-library/no-framework.component.mjs +0 -17
- package/esm2022/lib/framework-library/no-framework.module.mjs +0 -27
- package/esm2022/lib/framework-library/no.framework.mjs +0 -19
- package/esm2022/lib/json-schema-form.component.mjs +0 -759
- package/esm2022/lib/json-schema-form.module.mjs +0 -26
- package/esm2022/lib/json-schema-form.service.mjs +0 -695
- package/esm2022/lib/locale/de-validation-messages.mjs +0 -60
- package/esm2022/lib/locale/en-validation-messages.mjs +0 -60
- package/esm2022/lib/locale/es-validation-messages.mjs +0 -57
- package/esm2022/lib/locale/fr-validation-messages.mjs +0 -60
- package/esm2022/lib/locale/index.mjs +0 -8
- package/esm2022/lib/locale/it-validation-messages.mjs +0 -60
- package/esm2022/lib/locale/pt-validation-messages.mjs +0 -60
- package/esm2022/lib/locale/zh-validation-messages.mjs +0 -60
- package/esm2022/lib/shared/convert-schema-to-draft6.function.mjs +0 -300
- package/esm2022/lib/shared/form-group.functions.mjs +0 -444
- package/esm2022/lib/shared/format-regex.constants.mjs +0 -54
- package/esm2022/lib/shared/index.mjs +0 -12
- package/esm2022/lib/shared/json-schema.functions.mjs +0 -784
- package/esm2022/lib/shared/json.validators.mjs +0 -884
- package/esm2022/lib/shared/jsonpointer.functions.mjs +0 -1026
- package/esm2022/lib/shared/layout.functions.mjs +0 -1158
- package/esm2022/lib/shared/merge-schemas.function.mjs +0 -345
- package/esm2022/lib/shared/utility.functions.mjs +0 -380
- package/esm2022/lib/shared/validator.functions.mjs +0 -584
- package/esm2022/lib/widget-library/add-reference.component.mjs +0 -58
- package/esm2022/lib/widget-library/button.component.mjs +0 -69
- package/esm2022/lib/widget-library/checkbox.component.mjs +0 -102
- package/esm2022/lib/widget-library/checkboxes.component.mjs +0 -145
- package/esm2022/lib/widget-library/file.component.mjs +0 -32
- package/esm2022/lib/widget-library/hidden.component.mjs +0 -51
- package/esm2022/lib/widget-library/index.mjs +0 -55
- package/esm2022/lib/widget-library/input.component.mjs +0 -116
- package/esm2022/lib/widget-library/message.component.mjs +0 -35
- package/esm2022/lib/widget-library/none.component.mjs +0 -20
- package/esm2022/lib/widget-library/number.component.mjs +0 -120
- package/esm2022/lib/widget-library/one-of.component.mjs +0 -32
- package/esm2022/lib/widget-library/orderable.directive.mjs +0 -120
- package/esm2022/lib/widget-library/radios.component.mjs +0 -151
- package/esm2022/lib/widget-library/root.component.mjs +0 -73
- package/esm2022/lib/widget-library/section.component.mjs +0 -196
- package/esm2022/lib/widget-library/select-framework.component.mjs +0 -44
- package/esm2022/lib/widget-library/select-widget.component.mjs +0 -42
- package/esm2022/lib/widget-library/select.component.mjs +0 -147
- package/esm2022/lib/widget-library/submit.component.mjs +0 -79
- package/esm2022/lib/widget-library/tab.component.mjs +0 -38
- package/esm2022/lib/widget-library/tabs.component.mjs +0 -106
- package/esm2022/lib/widget-library/template.component.mjs +0 -43
- package/esm2022/lib/widget-library/textarea.component.mjs +0 -101
- package/esm2022/lib/widget-library/widget-library.module.mjs +0 -42
- package/esm2022/lib/widget-library/widget-library.service.mjs +0 -226
- package/esm2022/ng-formworks-core.mjs +0 -5
- package/esm2022/public_api.mjs +0 -13
|
@@ -1,695 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
//import Ajv, { ErrorObject, Options } from 'ajv';
|
|
3
|
-
import Ajv2019 from 'ajv/dist/2019';
|
|
4
|
-
import jsonDraft6 from 'ajv/lib/refs/json-schema-draft-06.json';
|
|
5
|
-
import jsonDraft7 from 'ajv/lib/refs/json-schema-draft-07.json';
|
|
6
|
-
import cloneDeep from 'lodash/cloneDeep';
|
|
7
|
-
import { Subject } from 'rxjs';
|
|
8
|
-
import { deValidationMessages, enValidationMessages, esValidationMessages, frValidationMessages, itValidationMessages, ptValidationMessages, zhValidationMessages } from './locale';
|
|
9
|
-
import { JsonPointer, buildFormGroup, buildFormGroupTemplate, buildLayout, buildSchemaFromData, buildSchemaFromLayout, fixTitle, forEach, formatFormData, getControl, getLayoutNode, hasOwn, hasValue, isArray, isDefined, isEmpty, isObject, removeRecursiveReferences, toTitleCase } from './shared';
|
|
10
|
-
import _isEqual from 'lodash/isEqual';
|
|
11
|
-
import * as i0 from "@angular/core";
|
|
12
|
-
export class JsonSchemaFormService {
|
|
13
|
-
constructor() {
|
|
14
|
-
this.JsonFormCompatibility = false;
|
|
15
|
-
this.ReactJsonSchemaFormCompatibility = false;
|
|
16
|
-
this.AngularSchemaFormCompatibility = false;
|
|
17
|
-
this.tpldata = {};
|
|
18
|
-
this.ajvOptions = {
|
|
19
|
-
allErrors: true,
|
|
20
|
-
validateFormats: false,
|
|
21
|
-
strict: false
|
|
22
|
-
};
|
|
23
|
-
this.ajv = new Ajv2019(this.ajvOptions); // AJV: Another JSON Schema Validator
|
|
24
|
-
this.validateFormData = null; // Compiled AJV function to validate active form's schema
|
|
25
|
-
this.formValues = {}; // Internal form data (may not have correct types)
|
|
26
|
-
this.data = {}; // Output form data (formValues, formatted with correct data types)
|
|
27
|
-
this.schema = {}; // Internal JSON Schema
|
|
28
|
-
this.layout = []; // Internal form layout
|
|
29
|
-
this.formGroupTemplate = {}; // Template used to create formGroup
|
|
30
|
-
this.formGroup = null; // Angular formGroup, which powers the reactive form
|
|
31
|
-
this.framework = null; // Active framework component
|
|
32
|
-
this.validData = null; // Valid form data (or null) (=== isValid ? data : null)
|
|
33
|
-
this.isValid = null; // Is current form data valid?
|
|
34
|
-
this.ajvErrors = null; // Ajv errors for current data
|
|
35
|
-
this.validationErrors = null; // Any validation errors for current data
|
|
36
|
-
this.dataErrors = new Map(); //
|
|
37
|
-
this.formValueSubscription = null; // Subscription to formGroup.valueChanges observable (for un- and re-subscribing)
|
|
38
|
-
this.dataChanges = new Subject(); // Form data observable
|
|
39
|
-
this.isValidChanges = new Subject(); // isValid observable
|
|
40
|
-
this.validationErrorChanges = new Subject(); // validationErrors observable
|
|
41
|
-
this.arrayMap = new Map(); // Maps arrays in data object and number of tuple values
|
|
42
|
-
this.dataMap = new Map(); // Maps paths in form data to schema and formGroup paths
|
|
43
|
-
this.dataRecursiveRefMap = new Map(); // Maps recursive reference points in form data
|
|
44
|
-
this.schemaRecursiveRefMap = new Map(); // Maps recursive reference points in schema
|
|
45
|
-
this.schemaRefLibrary = {}; // Library of schemas for resolving schema $refs
|
|
46
|
-
this.layoutRefLibrary = { '': null }; // Library of layout nodes for adding to form
|
|
47
|
-
this.templateRefLibrary = {}; // Library of formGroup templates for adding to form
|
|
48
|
-
this.hasRootReference = false; // Does the form include a recursive reference to itself?
|
|
49
|
-
this.language = 'en-US'; // Does the form include a recursive reference to itself?
|
|
50
|
-
// Default global form options
|
|
51
|
-
this.defaultFormOptions = {
|
|
52
|
-
autocomplete: true, // Allow the web browser to remember previous form submission values as defaults
|
|
53
|
-
addSubmit: 'auto', // Add a submit button if layout does not have one?
|
|
54
|
-
// for addSubmit: true = always, false = never,
|
|
55
|
-
// 'auto' = only if layout is undefined (form is built from schema alone)
|
|
56
|
-
debug: false, // Show debugging output?
|
|
57
|
-
disableInvalidSubmit: true, // Disable submit if form invalid?
|
|
58
|
-
formDisabled: false, // Set entire form as disabled? (not editable, and disables outputs)
|
|
59
|
-
formReadonly: false, // Set entire form as read only? (not editable, but outputs still enabled)
|
|
60
|
-
fieldsRequired: false, // (set automatically) Are there any required fields in the form?
|
|
61
|
-
framework: 'no-framework', // The framework to load
|
|
62
|
-
loadExternalAssets: false, // Load external css and JavaScript for framework?
|
|
63
|
-
pristine: { errors: true, success: true },
|
|
64
|
-
supressPropertyTitles: false,
|
|
65
|
-
setSchemaDefaults: 'auto', // Set fefault values from schema?
|
|
66
|
-
// true = always set (unless overridden by layout default or formValues)
|
|
67
|
-
// false = never set
|
|
68
|
-
// 'auto' = set in addable components, and everywhere if formValues not set
|
|
69
|
-
setLayoutDefaults: 'auto', // Set fefault values from layout?
|
|
70
|
-
// true = always set (unless overridden by formValues)
|
|
71
|
-
// false = never set
|
|
72
|
-
// 'auto' = set in addable components, and everywhere if formValues not set
|
|
73
|
-
validateOnRender: 'auto', // Validate fields immediately, before they are touched?
|
|
74
|
-
// true = validate all fields immediately
|
|
75
|
-
// false = only validate fields after they are touched by user
|
|
76
|
-
// 'auto' = validate fields with values immediately, empty fields after they are touched
|
|
77
|
-
widgets: {}, // Any custom widgets to load
|
|
78
|
-
defaultWidgetOptions: {
|
|
79
|
-
// Default options for form control widgets
|
|
80
|
-
listItems: 1, // Number of list items to initially add to arrays with no default value
|
|
81
|
-
addable: true, // Allow adding items to an array or $ref point?
|
|
82
|
-
orderable: true, // Allow reordering items within an array?
|
|
83
|
-
removable: true, // Allow removing items from an array or $ref point?
|
|
84
|
-
enableErrorState: true, // Apply 'has-error' class when field fails validation?
|
|
85
|
-
// disableErrorState: false, // Don't apply 'has-error' class when field fails validation?
|
|
86
|
-
enableSuccessState: true, // Apply 'has-success' class when field validates?
|
|
87
|
-
// disableSuccessState: false, // Don't apply 'has-success' class when field validates?
|
|
88
|
-
feedback: false, // Show inline feedback icons?
|
|
89
|
-
feedbackOnRender: false, // Show errorMessage on Render?
|
|
90
|
-
notitle: false, // Hide title?
|
|
91
|
-
disabled: false, // Set control as disabled? (not editable, and excluded from output)
|
|
92
|
-
readonly: false, // Set control as read only? (not editable, but included in output)
|
|
93
|
-
returnEmptyFields: true, // return values for fields that contain no data?
|
|
94
|
-
validationMessages: {} // set by setLanguage()
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
this.setLanguage(this.language);
|
|
98
|
-
this.ajv.addMetaSchema(jsonDraft6);
|
|
99
|
-
this.ajv.addMetaSchema(jsonDraft7);
|
|
100
|
-
}
|
|
101
|
-
ngOnDestroy() {
|
|
102
|
-
this.fcValueChangesSubs?.unsubscribe();
|
|
103
|
-
this.fcStatusChangesSubs?.unsubscribe();
|
|
104
|
-
this.formValueSubscription?.unsubscribe();
|
|
105
|
-
this.fcValueChangesSubs = null;
|
|
106
|
-
this.fcStatusChangesSubs = null;
|
|
107
|
-
this.formValueSubscription = null;
|
|
108
|
-
}
|
|
109
|
-
setLanguage(language = 'en-US') {
|
|
110
|
-
this.language = language;
|
|
111
|
-
const languageValidationMessages = {
|
|
112
|
-
de: deValidationMessages,
|
|
113
|
-
en: enValidationMessages,
|
|
114
|
-
es: esValidationMessages,
|
|
115
|
-
fr: frValidationMessages,
|
|
116
|
-
it: itValidationMessages,
|
|
117
|
-
pt: ptValidationMessages,
|
|
118
|
-
zh: zhValidationMessages,
|
|
119
|
-
};
|
|
120
|
-
const languageCode = language.slice(0, 2);
|
|
121
|
-
const validationMessages = languageValidationMessages[languageCode];
|
|
122
|
-
this.defaultFormOptions.defaultWidgetOptions.validationMessages = cloneDeep(validationMessages);
|
|
123
|
-
}
|
|
124
|
-
getData() {
|
|
125
|
-
return this.data;
|
|
126
|
-
}
|
|
127
|
-
getSchema() {
|
|
128
|
-
return this.schema;
|
|
129
|
-
}
|
|
130
|
-
getLayout() {
|
|
131
|
-
return this.layout;
|
|
132
|
-
}
|
|
133
|
-
resetAllValues() {
|
|
134
|
-
this.JsonFormCompatibility = false;
|
|
135
|
-
this.ReactJsonSchemaFormCompatibility = false;
|
|
136
|
-
this.AngularSchemaFormCompatibility = false;
|
|
137
|
-
this.tpldata = {};
|
|
138
|
-
this.validateFormData = null;
|
|
139
|
-
this.formValues = {};
|
|
140
|
-
this.schema = {};
|
|
141
|
-
this.layout = [];
|
|
142
|
-
this.formGroupTemplate = {};
|
|
143
|
-
this.formGroup = null;
|
|
144
|
-
this.framework = null;
|
|
145
|
-
this.data = {};
|
|
146
|
-
this.validData = null;
|
|
147
|
-
this.isValid = null;
|
|
148
|
-
this.validationErrors = null;
|
|
149
|
-
this.arrayMap = new Map();
|
|
150
|
-
this.dataMap = new Map();
|
|
151
|
-
this.dataRecursiveRefMap = new Map();
|
|
152
|
-
this.schemaRecursiveRefMap = new Map();
|
|
153
|
-
this.layoutRefLibrary = {};
|
|
154
|
-
this.schemaRefLibrary = {};
|
|
155
|
-
this.templateRefLibrary = {};
|
|
156
|
-
this.formOptions = cloneDeep(this.defaultFormOptions);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* 'buildRemoteError' function
|
|
160
|
-
*
|
|
161
|
-
* Example errors:
|
|
162
|
-
* {
|
|
163
|
-
* last_name: [ {
|
|
164
|
-
* message: 'Last name must by start with capital letter.',
|
|
165
|
-
* code: 'capital_letter'
|
|
166
|
-
* } ],
|
|
167
|
-
* email: [ {
|
|
168
|
-
* message: 'Email must be from example.com domain.',
|
|
169
|
-
* code: 'special_domain'
|
|
170
|
-
* }, {
|
|
171
|
-
* message: 'Email must contain an @ symbol.',
|
|
172
|
-
* code: 'at_symbol'
|
|
173
|
-
* } ]
|
|
174
|
-
* }
|
|
175
|
-
* //{ErrorMessages} errors
|
|
176
|
-
*/
|
|
177
|
-
buildRemoteError(errors) {
|
|
178
|
-
forEach(errors, (value, key) => {
|
|
179
|
-
if (key in this.formGroup.controls) {
|
|
180
|
-
for (const error of value) {
|
|
181
|
-
const err = {};
|
|
182
|
-
err[error['code']] = error['message'];
|
|
183
|
-
this.formGroup.get(key).setErrors(err, { emitEvent: true });
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
validateData(newValue, updateSubscriptions = true) {
|
|
189
|
-
// Format raw form data to correct data types
|
|
190
|
-
this.data = formatFormData(newValue, this.dataMap, this.dataRecursiveRefMap, this.arrayMap, this.formOptions.returnEmptyFields);
|
|
191
|
-
this.isValid = this.validateFormData(this.data);
|
|
192
|
-
this.validData = this.isValid ? this.data : null;
|
|
193
|
-
const compileErrors = (errors) => {
|
|
194
|
-
const compiledErrors = {};
|
|
195
|
-
(errors || []).forEach(error => {
|
|
196
|
-
//TODO review-seems to be a change in newer versions
|
|
197
|
-
//of ajv giving '' as instancePath for root objects
|
|
198
|
-
let errorPath = error.instancePath || "ROOT";
|
|
199
|
-
if (!compiledErrors[errorPath]) {
|
|
200
|
-
compiledErrors[errorPath] = [];
|
|
201
|
-
}
|
|
202
|
-
compiledErrors[errorPath].push(error.message);
|
|
203
|
-
});
|
|
204
|
-
return compiledErrors;
|
|
205
|
-
};
|
|
206
|
-
this.ajvErrors = this.validateFormData.errors;
|
|
207
|
-
this.validationErrors = compileErrors(this.validateFormData.errors);
|
|
208
|
-
if (updateSubscriptions) {
|
|
209
|
-
this.dataChanges.next(this.data);
|
|
210
|
-
this.isValidChanges.next(this.isValid);
|
|
211
|
-
this.validationErrorChanges.next(this.ajvErrors);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
buildFormGroupTemplate(formValues = null, setValues = true) {
|
|
215
|
-
this.formGroupTemplate = buildFormGroupTemplate(this, formValues, setValues);
|
|
216
|
-
}
|
|
217
|
-
buildFormGroup() {
|
|
218
|
-
this.formGroup = buildFormGroup(this.formGroupTemplate);
|
|
219
|
-
if (this.formGroup) {
|
|
220
|
-
this.compileAjvSchema();
|
|
221
|
-
this.validateData(this.formGroup.value);
|
|
222
|
-
// Set up observables to emit data and validation info when form data changes
|
|
223
|
-
if (this.formValueSubscription) {
|
|
224
|
-
this.formValueSubscription.unsubscribe();
|
|
225
|
-
}
|
|
226
|
-
this.formValueSubscription = this.formGroup.valueChanges.subscribe(formValue => this.validateData(formValue));
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
buildLayout(widgetLibrary) {
|
|
230
|
-
this.layout = buildLayout(this, widgetLibrary);
|
|
231
|
-
}
|
|
232
|
-
setOptions(newOptions) {
|
|
233
|
-
if (isObject(newOptions)) {
|
|
234
|
-
const addOptions = cloneDeep(newOptions);
|
|
235
|
-
// Backward compatibility for 'defaultOptions' (renamed 'defaultWidgetOptions')
|
|
236
|
-
if (isObject(addOptions.defaultOptions)) {
|
|
237
|
-
Object.assign(this.formOptions.defaultWidgetOptions, addOptions.defaultOptions);
|
|
238
|
-
delete addOptions.defaultOptions;
|
|
239
|
-
}
|
|
240
|
-
if (isObject(addOptions.defaultWidgetOptions)) {
|
|
241
|
-
Object.assign(this.formOptions.defaultWidgetOptions, addOptions.defaultWidgetOptions);
|
|
242
|
-
delete addOptions.defaultWidgetOptions;
|
|
243
|
-
}
|
|
244
|
-
Object.assign(this.formOptions, addOptions);
|
|
245
|
-
// convert disableErrorState / disableSuccessState to enable...
|
|
246
|
-
const globalDefaults = this.formOptions.defaultWidgetOptions;
|
|
247
|
-
['ErrorState', 'SuccessState']
|
|
248
|
-
.filter(suffix => hasOwn(globalDefaults, 'disable' + suffix))
|
|
249
|
-
.forEach(suffix => {
|
|
250
|
-
globalDefaults['enable' + suffix] = !globalDefaults['disable' + suffix];
|
|
251
|
-
delete globalDefaults['disable' + suffix];
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
compileAjvSchema() {
|
|
256
|
-
if (!this.validateFormData) {
|
|
257
|
-
// if 'ui:order' exists in properties, move it to root before compiling with ajv
|
|
258
|
-
if (Array.isArray(this.schema.properties['ui:order'])) {
|
|
259
|
-
this.schema['ui:order'] = this.schema.properties['ui:order'];
|
|
260
|
-
delete this.schema.properties['ui:order'];
|
|
261
|
-
}
|
|
262
|
-
this.ajv.removeSchema(this.schema);
|
|
263
|
-
this.validateFormData = this.ajv.compile(this.schema);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
buildSchemaFromData(data, requireAllFields = false) {
|
|
267
|
-
if (data) {
|
|
268
|
-
return buildSchemaFromData(data, requireAllFields);
|
|
269
|
-
}
|
|
270
|
-
this.schema = buildSchemaFromData(this.formValues, requireAllFields);
|
|
271
|
-
}
|
|
272
|
-
buildSchemaFromLayout(layout) {
|
|
273
|
-
if (layout) {
|
|
274
|
-
return buildSchemaFromLayout(layout);
|
|
275
|
-
}
|
|
276
|
-
this.schema = buildSchemaFromLayout(this.layout);
|
|
277
|
-
}
|
|
278
|
-
setTpldata(newTpldata = {}) {
|
|
279
|
-
this.tpldata = newTpldata;
|
|
280
|
-
}
|
|
281
|
-
parseText(text = '', value = {}, values = {}, key = null) {
|
|
282
|
-
if (!text || !/{{.+?}}/.test(text)) {
|
|
283
|
-
return text;
|
|
284
|
-
}
|
|
285
|
-
return text.replace(/{{(.+?)}}/g, (...a) => this.parseExpression(a[1], value, values, key, this.tpldata));
|
|
286
|
-
}
|
|
287
|
-
parseExpression(expression = '', value = {}, values = {}, key = null, tpldata = null) {
|
|
288
|
-
if (typeof expression !== 'string') {
|
|
289
|
-
return '';
|
|
290
|
-
}
|
|
291
|
-
const index = typeof key === 'number' ? key + 1 + '' : key || '';
|
|
292
|
-
expression = expression.trim();
|
|
293
|
-
if ((expression[0] === "'" || expression[0] === '"') &&
|
|
294
|
-
expression[0] === expression[expression.length - 1] &&
|
|
295
|
-
expression.slice(1, expression.length - 1).indexOf(expression[0]) === -1) {
|
|
296
|
-
return expression.slice(1, expression.length - 1);
|
|
297
|
-
}
|
|
298
|
-
if (expression === 'idx' || expression === '$index') {
|
|
299
|
-
return index;
|
|
300
|
-
}
|
|
301
|
-
if (expression === 'value' && !hasOwn(values, 'value')) {
|
|
302
|
-
return value;
|
|
303
|
-
}
|
|
304
|
-
if (['"', "'", ' ', '||', '&&', '+'].every(delim => expression.indexOf(delim) === -1)) {
|
|
305
|
-
const pointer = JsonPointer.parseObjectPath(expression);
|
|
306
|
-
return pointer[0] === 'value' && JsonPointer.has(value, pointer.slice(1))
|
|
307
|
-
? JsonPointer.get(value, pointer.slice(1))
|
|
308
|
-
: pointer[0] === 'values' && JsonPointer.has(values, pointer.slice(1))
|
|
309
|
-
? JsonPointer.get(values, pointer.slice(1))
|
|
310
|
-
: pointer[0] === 'tpldata' && JsonPointer.has(tpldata, pointer.slice(1))
|
|
311
|
-
? JsonPointer.get(tpldata, pointer.slice(1))
|
|
312
|
-
: JsonPointer.has(values, pointer)
|
|
313
|
-
? JsonPointer.get(values, pointer)
|
|
314
|
-
: '';
|
|
315
|
-
}
|
|
316
|
-
if (expression.indexOf('[idx]') > -1) {
|
|
317
|
-
expression = expression.replace(/\[idx\]/g, index);
|
|
318
|
-
}
|
|
319
|
-
if (expression.indexOf('[$index]') > -1) {
|
|
320
|
-
expression = expression.replace(/\[$index\]/g, index);
|
|
321
|
-
}
|
|
322
|
-
// TODO: Improve expression evaluation by parsing quoted strings first
|
|
323
|
-
// let expressionArray = expression.match(/([^"']+|"[^"]+"|'[^']+')/g);
|
|
324
|
-
if (expression.indexOf('||') > -1) {
|
|
325
|
-
return expression
|
|
326
|
-
.split('||')
|
|
327
|
-
.reduce((all, term) => all || this.parseExpression(term, value, values, key, tpldata), '');
|
|
328
|
-
}
|
|
329
|
-
if (expression.indexOf('&&') > -1) {
|
|
330
|
-
return expression
|
|
331
|
-
.split('&&')
|
|
332
|
-
.reduce((all, term) => all && this.parseExpression(term, value, values, key, tpldata), ' ')
|
|
333
|
-
.trim();
|
|
334
|
-
}
|
|
335
|
-
if (expression.indexOf('+') > -1) {
|
|
336
|
-
return expression
|
|
337
|
-
.split('+')
|
|
338
|
-
.map(term => this.parseExpression(term, value, values, key, tpldata))
|
|
339
|
-
.join('');
|
|
340
|
-
}
|
|
341
|
-
return '';
|
|
342
|
-
}
|
|
343
|
-
setArrayItemTitle(parentCtx = {}, childNode = null, index = null) {
|
|
344
|
-
//for legacy compatibility, parentCtx.layoutNode could either be a value
|
|
345
|
-
//or have been converted to use Signals
|
|
346
|
-
let parentCtxAsSignals = {
|
|
347
|
-
layoutNode: () => {
|
|
348
|
-
if (isObject(parentCtx.layoutNode)) {
|
|
349
|
-
return parentCtx.layoutNode;
|
|
350
|
-
}
|
|
351
|
-
return parentCtx.layoutNode();
|
|
352
|
-
},
|
|
353
|
-
dataIndex: () => {
|
|
354
|
-
if (isObject(parentCtx.dataIndex)) {
|
|
355
|
-
return parentCtx.dataIndex;
|
|
356
|
-
}
|
|
357
|
-
return parentCtx.dataIndex();
|
|
358
|
-
}
|
|
359
|
-
};
|
|
360
|
-
const parentNode = parentCtxAsSignals.layoutNode();
|
|
361
|
-
const parentValues = this.getFormControlValue(parentCtxAsSignals);
|
|
362
|
-
const isArrayItem = (parentNode.type || '').slice(-5) === 'array' && isArray(parentValues);
|
|
363
|
-
const text = JsonPointer.getFirst(isArrayItem && childNode.type !== '$ref'
|
|
364
|
-
? [
|
|
365
|
-
[childNode, '/options/legend'],
|
|
366
|
-
[childNode, '/options/title'],
|
|
367
|
-
[parentNode, '/options/title'],
|
|
368
|
-
[parentNode, '/options/legend']
|
|
369
|
-
]
|
|
370
|
-
: [
|
|
371
|
-
[childNode, '/options/title'],
|
|
372
|
-
[childNode, '/options/legend'],
|
|
373
|
-
[parentNode, '/options/title'],
|
|
374
|
-
[parentNode, '/options/legend']
|
|
375
|
-
]);
|
|
376
|
-
if (!text) {
|
|
377
|
-
return text;
|
|
378
|
-
}
|
|
379
|
-
const childValue = isArray(parentValues) && index < parentValues.length
|
|
380
|
-
? parentValues[index]
|
|
381
|
-
: parentValues;
|
|
382
|
-
return this.parseText(text, childValue, parentValues, index);
|
|
383
|
-
}
|
|
384
|
-
setItemTitle(ctx) {
|
|
385
|
-
return !ctx.options.title && /^(\d+|-)$/.test(ctx.layoutNode().name)
|
|
386
|
-
? null
|
|
387
|
-
: this.parseText(ctx.options.title || toTitleCase(ctx.layoutNode().name), this.getFormControlValue(ctx), (this.getFormControlGroup(ctx) || {}).value, ctx.dataIndex()[ctx.dataIndex().length - 1]);
|
|
388
|
-
}
|
|
389
|
-
evaluateCondition(layoutNode, dataIndex) {
|
|
390
|
-
const arrayIndex = dataIndex && dataIndex[dataIndex.length - 1];
|
|
391
|
-
let result = true;
|
|
392
|
-
if (hasValue((layoutNode.options || {}).condition)) {
|
|
393
|
-
if (typeof layoutNode.options.condition === 'string') {
|
|
394
|
-
let pointer = layoutNode.options.condition;
|
|
395
|
-
if (hasValue(arrayIndex)) {
|
|
396
|
-
pointer = pointer.replace('[arrayIndex]', `[${arrayIndex}]`);
|
|
397
|
-
}
|
|
398
|
-
pointer = JsonPointer.parseObjectPath(pointer);
|
|
399
|
-
result = !!JsonPointer.get(this.data, pointer);
|
|
400
|
-
if (!result && pointer[0] === 'model') {
|
|
401
|
-
result = !!JsonPointer.get({ model: this.data }, pointer);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
else if (typeof layoutNode.options.condition === 'function') {
|
|
405
|
-
result = layoutNode.options.condition(this.data);
|
|
406
|
-
}
|
|
407
|
-
else if (typeof layoutNode.options.condition.functionBody === 'string') {
|
|
408
|
-
try {
|
|
409
|
-
const dynFn = new Function('model', 'arrayIndices', layoutNode.options.condition.functionBody);
|
|
410
|
-
result = dynFn(this.data, dataIndex);
|
|
411
|
-
}
|
|
412
|
-
catch (e) {
|
|
413
|
-
result = true;
|
|
414
|
-
console.error('condition functionBody errored out on evaluation: ' +
|
|
415
|
-
layoutNode.options.condition.functionBody);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
return result;
|
|
420
|
-
}
|
|
421
|
-
initializeControl(ctx, bind = true) {
|
|
422
|
-
if (!isObject(ctx)) {
|
|
423
|
-
return false;
|
|
424
|
-
}
|
|
425
|
-
if (isEmpty(ctx.options)) {
|
|
426
|
-
ctx.options = !isEmpty((ctx.layoutNode() || {}).options)
|
|
427
|
-
? ctx.layoutNode().options
|
|
428
|
-
: cloneDeep(this.formOptions);
|
|
429
|
-
}
|
|
430
|
-
ctx.formControl = this.getFormControl(ctx);
|
|
431
|
-
ctx.boundControl = bind && !!ctx.formControl;
|
|
432
|
-
if (ctx.formControl) {
|
|
433
|
-
ctx.controlName = this.getFormControlName(ctx);
|
|
434
|
-
ctx.controlValue = ctx.formControl.value;
|
|
435
|
-
ctx.controlDisabled = ctx.formControl.disabled;
|
|
436
|
-
ctx.options.errorMessage =
|
|
437
|
-
ctx.formControl.status === 'VALID'
|
|
438
|
-
? null
|
|
439
|
-
: this.formatErrors(ctx.formControl.errors, ctx.options.validationMessages);
|
|
440
|
-
ctx.options.showErrors =
|
|
441
|
-
this.formOptions.validateOnRender === true ||
|
|
442
|
-
(this.formOptions.validateOnRender === 'auto' &&
|
|
443
|
-
hasValue(ctx.controlValue));
|
|
444
|
-
this.fcStatusChangesSubs = ctx.formControl.statusChanges.subscribe(status => (ctx.options.errorMessage =
|
|
445
|
-
status === 'VALID'
|
|
446
|
-
? null
|
|
447
|
-
: this.formatErrors(ctx.formControl.errors, ctx.options.validationMessages)));
|
|
448
|
-
this.fcValueChangesSubs = ctx.formControl.valueChanges.subscribe(value => {
|
|
449
|
-
//commented out to revert back to previous commits
|
|
450
|
-
//as seems to be causing some issues
|
|
451
|
-
/*
|
|
452
|
-
if (!!value) {
|
|
453
|
-
ctx.controlValue = value;
|
|
454
|
-
}
|
|
455
|
-
*/
|
|
456
|
-
//TODO-test,this is the original code
|
|
457
|
-
if (!_isEqual(ctx.controlValue, value)) {
|
|
458
|
-
ctx.controlValue = value;
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
ctx.controlName = ctx.layoutNode().name;
|
|
464
|
-
ctx.controlValue = ctx.layoutNode().value || null;
|
|
465
|
-
const dataPointer = this.getDataPointer(ctx);
|
|
466
|
-
if (bind && dataPointer) {
|
|
467
|
-
console.error(`warning: control "${dataPointer}" is not bound to the Angular FormGroup.`);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
return ctx.boundControl;
|
|
471
|
-
}
|
|
472
|
-
formatErrors(errors, validationMessages = {}) {
|
|
473
|
-
if (isEmpty(errors)) {
|
|
474
|
-
return null;
|
|
475
|
-
}
|
|
476
|
-
if (!isObject(validationMessages)) {
|
|
477
|
-
validationMessages = {};
|
|
478
|
-
}
|
|
479
|
-
const addSpaces = string => string[0].toUpperCase() +
|
|
480
|
-
(string.slice(1) || '')
|
|
481
|
-
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
482
|
-
.replace(/_/g, ' ');
|
|
483
|
-
const formatError = error => typeof error === 'object'
|
|
484
|
-
? Object.keys(error)
|
|
485
|
-
.map(key => error[key] === true
|
|
486
|
-
? addSpaces(key)
|
|
487
|
-
: error[key] === false
|
|
488
|
-
? 'Not ' + addSpaces(key)
|
|
489
|
-
: addSpaces(key) + ': ' + formatError(error[key]))
|
|
490
|
-
.join(', ')
|
|
491
|
-
: addSpaces(error.toString());
|
|
492
|
-
const messages = [];
|
|
493
|
-
return (Object.keys(errors)
|
|
494
|
-
// Hide 'required' error, unless it is the only one
|
|
495
|
-
.filter(errorKey => errorKey !== 'required' || Object.keys(errors).length === 1)
|
|
496
|
-
.map(errorKey =>
|
|
497
|
-
// If validationMessages is a string, return it
|
|
498
|
-
typeof validationMessages === 'string'
|
|
499
|
-
? validationMessages
|
|
500
|
-
: // If custom error message is a function, return function result
|
|
501
|
-
typeof validationMessages[errorKey] === 'function'
|
|
502
|
-
? validationMessages[errorKey](errors[errorKey])
|
|
503
|
-
: // If custom error message is a string, replace placeholders and return
|
|
504
|
-
typeof validationMessages[errorKey] === 'string'
|
|
505
|
-
? // Does error message have any {{property}} placeholders?
|
|
506
|
-
!/{{.+?}}/.test(validationMessages[errorKey])
|
|
507
|
-
? validationMessages[errorKey]
|
|
508
|
-
: // Replace {{property}} placeholders with values
|
|
509
|
-
Object.keys(errors[errorKey]).reduce((errorMessage, errorProperty) => errorMessage.replace(new RegExp('{{' + errorProperty + '}}', 'g'), errors[errorKey][errorProperty]), validationMessages[errorKey])
|
|
510
|
-
: // If no custom error message, return formatted error data instead
|
|
511
|
-
addSpaces(errorKey) + ' Error: ' + formatError(errors[errorKey]))
|
|
512
|
-
.join('<br>'));
|
|
513
|
-
}
|
|
514
|
-
updateValue(ctx, value) {
|
|
515
|
-
// Set value of current control
|
|
516
|
-
ctx.controlValue = value;
|
|
517
|
-
if (ctx.boundControl) {
|
|
518
|
-
ctx.formControl.setValue(value);
|
|
519
|
-
ctx.formControl.markAsDirty();
|
|
520
|
-
}
|
|
521
|
-
ctx.layoutNode().value = value;
|
|
522
|
-
// Set values of any related controls in copyValueTo array
|
|
523
|
-
if (isArray(ctx.options.copyValueTo)) {
|
|
524
|
-
for (const item of ctx.options.copyValueTo) {
|
|
525
|
-
const targetControl = getControl(this.formGroup, item);
|
|
526
|
-
if (isObject(targetControl) &&
|
|
527
|
-
typeof targetControl.setValue === 'function') {
|
|
528
|
-
targetControl.setValue(value);
|
|
529
|
-
targetControl.markAsDirty();
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
updateArrayCheckboxList(ctx, checkboxList) {
|
|
535
|
-
const formArray = this.getFormControl(ctx);
|
|
536
|
-
// Remove all existing items
|
|
537
|
-
while (formArray.value.length) {
|
|
538
|
-
formArray.removeAt(0);
|
|
539
|
-
}
|
|
540
|
-
// Re-add an item for each checked box
|
|
541
|
-
const refPointer = removeRecursiveReferences(ctx.layoutNode().dataPointer + '/-', this.dataRecursiveRefMap, this.arrayMap);
|
|
542
|
-
for (const checkboxItem of checkboxList) {
|
|
543
|
-
if (checkboxItem.checked) {
|
|
544
|
-
const newFormControl = buildFormGroup(this.templateRefLibrary[refPointer]);
|
|
545
|
-
newFormControl.setValue(checkboxItem.value);
|
|
546
|
-
formArray.push(newFormControl);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
formArray.markAsDirty();
|
|
550
|
-
}
|
|
551
|
-
getFormControl(ctx) {
|
|
552
|
-
if (!ctx || !ctx.layoutNode ||
|
|
553
|
-
!isDefined(ctx.layoutNode().dataPointer) ||
|
|
554
|
-
ctx.layoutNode().type === '$ref') {
|
|
555
|
-
return null;
|
|
556
|
-
}
|
|
557
|
-
return getControl(this.formGroup, this.getDataPointer(ctx));
|
|
558
|
-
}
|
|
559
|
-
getFormControlValue(ctx) {
|
|
560
|
-
if (!ctx || !ctx.layoutNode ||
|
|
561
|
-
!isDefined(ctx.layoutNode().dataPointer) ||
|
|
562
|
-
ctx.layoutNode().type === '$ref') {
|
|
563
|
-
return null;
|
|
564
|
-
}
|
|
565
|
-
const control = getControl(this.formGroup, this.getDataPointer(ctx));
|
|
566
|
-
return control ? control.value : null;
|
|
567
|
-
}
|
|
568
|
-
getFormControlGroup(ctx) {
|
|
569
|
-
if (!ctx || !ctx.layoutNode || !isDefined(ctx.layoutNode().dataPointer)) {
|
|
570
|
-
return null;
|
|
571
|
-
}
|
|
572
|
-
return getControl(this.formGroup, this.getDataPointer(ctx), true);
|
|
573
|
-
}
|
|
574
|
-
getFormControlName(ctx) {
|
|
575
|
-
if (!ctx || !ctx.layoutNode ||
|
|
576
|
-
!isDefined(ctx.layoutNode().dataPointer) ||
|
|
577
|
-
!hasValue(ctx.dataIndex())) {
|
|
578
|
-
return null;
|
|
579
|
-
}
|
|
580
|
-
return JsonPointer.toKey(this.getDataPointer(ctx));
|
|
581
|
-
}
|
|
582
|
-
getLayoutArray(ctx) {
|
|
583
|
-
return JsonPointer.get(this.layout, this.getLayoutPointer(ctx), 0, -1);
|
|
584
|
-
}
|
|
585
|
-
getParentNode(ctx) {
|
|
586
|
-
return JsonPointer.get(this.layout, this.getLayoutPointer(ctx), 0, -2);
|
|
587
|
-
}
|
|
588
|
-
getDataPointer(ctx) {
|
|
589
|
-
if (!ctx || !ctx.layoutNode ||
|
|
590
|
-
!isDefined(ctx.layoutNode().dataPointer) ||
|
|
591
|
-
!hasValue(ctx.dataIndex())) {
|
|
592
|
-
return null;
|
|
593
|
-
}
|
|
594
|
-
return JsonPointer.toIndexedPointer(ctx.layoutNode().dataPointer, ctx.dataIndex(), this.arrayMap);
|
|
595
|
-
}
|
|
596
|
-
getLayoutPointer(ctx) {
|
|
597
|
-
if (!hasValue(ctx.layoutIndex())) {
|
|
598
|
-
return null;
|
|
599
|
-
}
|
|
600
|
-
return '/' + ctx.layoutIndex().join('/items/');
|
|
601
|
-
}
|
|
602
|
-
isControlBound(ctx) {
|
|
603
|
-
if (!ctx || !ctx.layoutNode ||
|
|
604
|
-
!isDefined(ctx.layoutNode().dataPointer) ||
|
|
605
|
-
!hasValue(ctx.dataIndex())) {
|
|
606
|
-
return false;
|
|
607
|
-
}
|
|
608
|
-
const controlGroup = this.getFormControlGroup(ctx);
|
|
609
|
-
const name = this.getFormControlName(ctx);
|
|
610
|
-
return controlGroup ? hasOwn(controlGroup.controls, name) : false;
|
|
611
|
-
}
|
|
612
|
-
addItem(ctx, name) {
|
|
613
|
-
if (!ctx || !ctx.layoutNode ||
|
|
614
|
-
!isDefined(ctx.layoutNode().$ref) ||
|
|
615
|
-
!hasValue(ctx.dataIndex()) ||
|
|
616
|
-
!hasValue(ctx.layoutIndex())) {
|
|
617
|
-
return false;
|
|
618
|
-
}
|
|
619
|
-
// Create a new Angular form control from a template in templateRefLibrary
|
|
620
|
-
const newFormGroup = buildFormGroup(this.templateRefLibrary[ctx.layoutNode().$ref]);
|
|
621
|
-
// Add the new form control to the parent formArray or formGroup
|
|
622
|
-
if (ctx.layoutNode().arrayItem) {
|
|
623
|
-
// Add new array item to formArray
|
|
624
|
-
this.getFormControlGroup(ctx).push(newFormGroup);
|
|
625
|
-
}
|
|
626
|
-
else {
|
|
627
|
-
// Add new $ref item to formGroup
|
|
628
|
-
this.getFormControlGroup(ctx).addControl(name || this.getFormControlName(ctx), newFormGroup);
|
|
629
|
-
}
|
|
630
|
-
// Copy a new layoutNode from layoutRefLibrary
|
|
631
|
-
const newLayoutNode = getLayoutNode(ctx.layoutNode(), this);
|
|
632
|
-
newLayoutNode.arrayItem = ctx.layoutNode().arrayItem;
|
|
633
|
-
if (ctx.layoutNode().arrayItemType) {
|
|
634
|
-
newLayoutNode.arrayItemType = ctx.layoutNode().arrayItemType;
|
|
635
|
-
}
|
|
636
|
-
else {
|
|
637
|
-
delete newLayoutNode.arrayItemType;
|
|
638
|
-
}
|
|
639
|
-
if (name) {
|
|
640
|
-
newLayoutNode.name = name;
|
|
641
|
-
newLayoutNode.dataPointer += '/' + JsonPointer.escape(name);
|
|
642
|
-
newLayoutNode.options.title = fixTitle(name);
|
|
643
|
-
}
|
|
644
|
-
// Add the new layoutNode to the form layout
|
|
645
|
-
JsonPointer.insert(this.layout, this.getLayoutPointer(ctx), newLayoutNode);
|
|
646
|
-
return true;
|
|
647
|
-
}
|
|
648
|
-
moveArrayItem(ctx, oldIndex, newIndex) {
|
|
649
|
-
if (!ctx || !ctx.layoutNode ||
|
|
650
|
-
!isDefined(ctx.layoutNode().dataPointer) ||
|
|
651
|
-
!hasValue(ctx.dataIndex()) ||
|
|
652
|
-
!hasValue(ctx.layoutIndex()) ||
|
|
653
|
-
!isDefined(oldIndex) ||
|
|
654
|
-
!isDefined(newIndex) ||
|
|
655
|
-
oldIndex === newIndex) {
|
|
656
|
-
return false;
|
|
657
|
-
}
|
|
658
|
-
// Move item in the formArray
|
|
659
|
-
const formArray = this.getFormControlGroup(ctx);
|
|
660
|
-
const arrayItem = formArray.at(oldIndex);
|
|
661
|
-
formArray.removeAt(oldIndex);
|
|
662
|
-
formArray.insert(newIndex, arrayItem);
|
|
663
|
-
formArray.updateValueAndValidity();
|
|
664
|
-
// Move layout item
|
|
665
|
-
const layoutArray = this.getLayoutArray(ctx);
|
|
666
|
-
layoutArray.splice(newIndex, 0, layoutArray.splice(oldIndex, 1)[0]);
|
|
667
|
-
return true;
|
|
668
|
-
}
|
|
669
|
-
removeItem(ctx) {
|
|
670
|
-
if (!ctx || !ctx.layoutNode ||
|
|
671
|
-
!isDefined(ctx.layoutNode().dataPointer) ||
|
|
672
|
-
!hasValue(ctx.dataIndex()) ||
|
|
673
|
-
!hasValue(ctx.layoutIndex())) {
|
|
674
|
-
return false;
|
|
675
|
-
}
|
|
676
|
-
// Remove the Angular form control from the parent formArray or formGroup
|
|
677
|
-
if (ctx.layoutNode().arrayItem) {
|
|
678
|
-
// Remove array item from formArray
|
|
679
|
-
this.getFormControlGroup(ctx).removeAt(ctx.dataIndex()[ctx.dataIndex().length - 1]);
|
|
680
|
-
}
|
|
681
|
-
else {
|
|
682
|
-
// Remove $ref item from formGroup
|
|
683
|
-
this.getFormControlGroup(ctx).removeControl(this.getFormControlName(ctx));
|
|
684
|
-
}
|
|
685
|
-
// Remove layoutNode from layout
|
|
686
|
-
JsonPointer.remove(this.layout, this.getLayoutPointer(ctx));
|
|
687
|
-
return true;
|
|
688
|
-
}
|
|
689
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: JsonSchemaFormService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
690
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: JsonSchemaFormService }); }
|
|
691
|
-
}
|
|
692
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: JsonSchemaFormService, decorators: [{
|
|
693
|
-
type: Injectable
|
|
694
|
-
}], ctorParameters: () => [] });
|
|
695
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zY2hlbWEtZm9ybS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctZm9ybXdvcmtzLWNvcmUvc3JjL2xpYi9qc29uLXNjaGVtYS1mb3JtLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFFOUQsa0RBQWtEO0FBQ2xELE9BQU8sT0FBaUMsTUFBTSxlQUFlLENBQUM7QUFFOUQsT0FBTyxVQUFVLE1BQU0sd0NBQXdDLENBQUM7QUFDaEUsT0FBTyxVQUFVLE1BQU0sd0NBQXdDLENBQUM7QUFDaEUsT0FBTyxTQUFTLE1BQU0sa0JBQWtCLENBQUM7QUFDekMsT0FBTyxFQUFFLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDN0MsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixvQkFBb0IsRUFDcEIsb0JBQW9CLEVBQ3BCLG9CQUFvQixFQUNwQixvQkFBb0IsRUFDcEIsb0JBQW9CLEVBQ3BCLG9CQUFvQixFQUNyQixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQ0wsV0FBVyxFQUNYLGNBQWMsRUFDZCxzQkFBc0IsRUFDdEIsV0FBVyxFQUNYLG1CQUFtQixFQUNuQixxQkFBcUIsRUFDckIsUUFBUSxFQUNSLE9BQU8sRUFDUCxjQUFjLEVBQ2QsVUFBVSxFQUNWLGFBQWEsRUFDYixNQUFNLEVBQ04sUUFBUSxFQUNSLE9BQU8sRUFDUCxTQUFTLEVBQ1QsT0FBTyxFQUNQLFFBQVEsRUFDUix5QkFBeUIsRUFDekIsV0FBVyxFQUNaLE1BQU0sVUFBVSxDQUFDO0FBRWxCLE9BQU8sUUFBUSxNQUFNLGdCQUFnQixDQUFDOztBQThCdEMsTUFBTSxPQUFPLHFCQUFxQjtJQWdHaEM7UUEvRkEsMEJBQXFCLEdBQUcsS0FBSyxDQUFDO1FBQzlCLHFDQUFnQyxHQUFHLEtBQUssQ0FBQztRQUN6QyxtQ0FBOEIsR0FB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O0lBQ2QsQ0FBQztJQUVELFVBQVUsQ0FBQyxHQUFrQjtRQUMzQixJQUNFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVU7WUFDdkIsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLFdBQVcsQ0FBQztZQUN4QyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDMUIsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQzVCLENBQUM7WUFDRCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCx5RUFBeUU7UUFDekUsSUFBSSxHQUFHLENBQUMsVUFBVSxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDL0IsbUNBQW1DO1lBQ2hCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUUsQ0FBQyxRQUFRLENBQ3hELEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUM1QyxDQUFDO1FBQ0osQ0FBQzthQUFNLENBQUM7WUFDTixrQ0FBa0M7WUFDZixJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFFLENBQUMsYUFBYSxDQUM3RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLENBQzdCLENBQUM7UUFDSixDQUFDO1FBRUQsZ0NBQWdDO1FBQ2hDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM1RCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7K0dBbjJCVSxxQkFBcUI7bUhBQXJCLHFCQUFxQjs7NEZBQXJCLHFCQUFxQjtrQkFEakMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIE9uRGVzdHJveSwgU2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgVW50eXBlZEZvcm1BcnJheSwgVW50eXBlZEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuLy9pbXBvcnQgQWp2LCB7IEVycm9yT2JqZWN0LCBPcHRpb25zIH0gZnJvbSAnYWp2JztcclxuaW1wb3J0IEFqdjIwMTksIHsgRXJyb3JPYmplY3QsIE9wdGlvbnMgfSBmcm9tICdhanYvZGlzdC8yMDE5JztcclxuXHJcbmltcG9ydCBqc29uRHJhZnQ2IGZyb20gJ2Fqdi9saWIvcmVmcy9qc29uLXNjaGVtYS1kcmFmdC0wNi5qc29uJztcclxuaW1wb3J0IGpzb25EcmFmdDcgZnJvbSAnYWp2L2xpYi9yZWZzL2pzb24tc2NoZW1hLWRyYWZ0LTA3Lmpzb24nO1xyXG5pbXBvcnQgY2xvbmVEZWVwIGZyb20gJ2xvZGFzaC9jbG9uZURlZXAnO1xyXG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtcclxuICBkZVZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBlblZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBlc1ZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBmclZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBpdFZhbGlkYXRpb25NZXNzYWdlcyxcclxuICBwdFZhbGlkYXRpb25NZXNzYWdlcyxcclxuICB6aFZhbGlkYXRpb25NZXNzYWdlc1xyXG59IGZyb20gJy4vbG9jYWxlJztcclxuaW1wb3J0IHtcclxuICBKc29uUG9pbnRlcixcclxuICBidWlsZEZvcm1Hcm91cCxcclxuICBidWlsZEZvcm1Hcm91cFRlbXBsYXRlLFxyXG4gIGJ1aWxkTGF5b3V0LFxyXG4gIGJ1aWxkU2NoZW1hRnJvbURhdGEsXHJcbiAgYnVpbGRTY2hlbWFGcm9tTGF5b3V0LFxyXG4gIGZpeFRpdGxlLFxyXG4gIGZvckVhY2gsXHJcbiAgZm9ybWF0Rm9ybURhdGEsXHJcbiAgZ2V0Q29udHJvbCxcclxuICBnZXRMYXlvdXROb2RlLFxyXG4gIGhhc093bixcclxuICBoYXNWYWx1ZSxcclxuICBpc0FycmF5LFxyXG4gIGlzRGVmaW5lZCxcclxuICBpc0VtcHR5LFxyXG4gIGlzT2JqZWN0LFxyXG4gIHJlbW92ZVJlY3Vyc2l2ZVJlZmVyZW5jZXMsXHJcbiAgdG9UaXRsZUNhc2VcclxufSBmcm9tICcuL3NoYXJlZCc7XHJcblxyXG5pbXBvcnQgX2lzRXF1YWwgZnJvbSAnbG9kYXNoL2lzRXF1YWwnO1xyXG5cclxuXHJcbmV4cG9ydCB0eXBlIFdpZGdldENvbnRleHQ9e1xyXG4gIGZvcm1Db250cm9sPzpBYnN0cmFjdENvbnRyb2w7XHJcbiAgbGF5b3V0Tm9kZT86IFNpZ25hbDxhbnk+O1xyXG4gIGxheW91dEluZGV4PzogU2lnbmFsPG51bWJlcltdPjtcclxuICBkYXRhSW5kZXg/OiBTaWduYWw8bnVtYmVyW10+O1xyXG4gIG9wdGlvbnM/OmFueTtcclxuICBjb250cm9sVmFsdWU/OmFueTtcclxuICBib3VuZENvbnRyb2w/OmJvb2xlYW47XHJcbiAgY29udHJvbE5hbWU/OnN0cmluZztcclxuICBjb250cm9sRGlzYWJsZWQ/OmJvb2xlYW5cclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBUaXRsZU1hcEl0ZW0ge1xyXG4gIG5hbWU/OiBzdHJpbmc7XHJcbiAgdmFsdWU/OiBhbnk7XHJcbiAgY2hlY2tlZD86IGJvb2xlYW47XHJcbiAgZ3JvdXA/OiBzdHJpbmc7XHJcbiAgaXRlbXM/OiBUaXRsZU1hcEl0ZW1bXTtcclxufVxyXG5leHBvcnQgaW50ZXJmYWNlIEVycm9yTWVzc2FnZXMge1xyXG4gIFtjb250cm9sX25hbWU6IHN0cmluZ106IHtcclxuICAgIG1lc3NhZ2U6IHN0cmluZyB8IEZ1bmN0aW9uIHwgT2JqZWN0O1xyXG4gICAgY29kZTogc3RyaW5nO1xyXG4gIH1bXTtcclxufVxyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgSnNvblNjaGVtYUZvcm1TZXJ2aWNlIGltcGxlbWVudHMgT25EZXN0cm95IHtcclxuICBKc29uRm9ybUNvbXBhdGliaWxpdHkgPSBmYWxzZTtcclxuICBSZWFjdEpzb25TY2hlbWFGb3JtQ29tcGF0aWJpbGl0eSA9IGZhbHNlO1xyXG4gIEFuZ3VsYXJTY2hlbWFGb3JtQ29tcGF0aWJpbGl0eSA9IGZhbHNlO1xyXG4gIHRwbGRhdGE6IGFueSA9IHt9O1xyXG5cclxuICBhanZPcHRpb25zOiBPcHRpb25zID0ge1xyXG4gICAgYWxsRXJyb3JzOiB0cnVlLFxyXG4gICAgdmFsaWRhdGVGb3JtYXRzOmZhbHNlLFxyXG4gICAgc3RyaWN0OmZhbHNlXHJcbiAgXHJcbiAgfTtcclxuICBhanY6YW55ID0gbmV3IEFqdjIwMTkodGhpcy5hanZPcHRpb25zKTsgLy8gQUpWOiBBbm90aGVyIEpTT04gU2NoZW1hIFZhbGlkYXRvclxyXG4gIFxyXG4gIHZhbGlkYXRlRm9ybURhdGE6IGFueSA9IG51bGw7IC8vIENvbXBpbGVkIEFKViBmdW5jdGlvbiB0byB2YWxpZGF0ZSBhY3RpdmUgZm9ybSdzIHNjaGVtYVxyXG5cclxuICBmb3JtVmFsdWVzOiBhbnkgPSB7fTsgLy8gSW50ZXJuYWwgZm9ybSBkYXRhIChtYXkgbm90IGhhdmUgY29ycmVjdCB0eXBlcylcclxuICBkYXRhOiBhbnkgPSB7fTsgLy8gT3V0cHV0IGZvcm0gZGF0YSAoZm9ybVZhbHVlcywgZm9ybWF0dGVkIHdpdGggY29ycmVjdCBkYXRhIHR5cGVzKVxyXG4gIHNjaGVtYTogYW55ID0ge307IC8vIEludGVybmFsIEpTT04gU2NoZW1hXHJcbiAgbGF5b3V0OiBhbnlbXSA9IFtdOyAvLyBJbnRlcm5hbCBmb3JtIGxheW91dFxyXG4gIGZvcm1Hcm91cFRlbXBsYXRlOiBhbnkgPSB7fTsgLy8gVGVtcGxhdGUgdXNlZCB0byBjcmVhdGUgZm9ybUdyb3VwXHJcbiAgZm9ybUdyb3VwOiBhbnkgPSBudWxsOyAvLyBBbmd1bGFyIGZvcm1Hcm91cCwgd2hpY2ggcG93ZXJzIHRoZSByZWFjdGl2ZSBmb3JtXHJcbiAgZnJhbWV3b3JrOiBhbnkgPSBudWxsOyAvLyBBY3RpdmUgZnJhbWV3b3JrIGNvbXBvbmVudFxyXG4gIGZvcm1PcHRpb25zOiBhbnk7IC8vIEFjdGl2ZSBvcHRpb25zLCB1c2VkIHRvIGNvbmZpZ3VyZSB0aGUgZm9ybVxyXG5cclxuICB2YWxpZERhdGE6IGFueSA9IG51bGw7IC8vIFZhbGlkIGZvcm0gZGF0YSAob3IgbnVsbCkgKD09PSBpc1ZhbGlkID8gZGF0YSA6IG51bGwpXHJcbiAgaXNWYWxpZDogYm9vbGVhbiA9IG51bGw7IC8vIElzIGN1cnJlbnQgZm9ybSBkYXRhIHZhbGlkP1xyXG4gIGFqdkVycm9yczogRXJyb3JPYmplY3RbXSA9IG51bGw7IC8vIEFqdiBlcnJvcnMgZm9yIGN1cnJlbnQgZGF0YVxyXG4gIHZhbGlkYXRpb25FcnJvcnM6IGFueSA9IG51bGw7IC8vIEFueSB2YWxpZGF0aW9uIGVycm9ycyBmb3IgY3VycmVudCBkYXRhXHJcbiAgZGF0YUVycm9yczogYW55ID0gbmV3IE1hcCgpOyAvL1xyXG4gIGZvcm1WYWx1ZVN1YnNjcmlwdGlvbjogYW55ID0gbnVsbDsgLy8gU3Vic2NyaXB0aW9uIHRvIGZvcm1Hcm91cC52YWx1ZUNoYW5nZXMgb2JzZXJ2YWJsZSAoZm9yIHVuLSBhbmQgcmUtc3Vic2NyaWJpbmcpXHJcbiAgZGF0YUNoYW5nZXM6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KCk7IC8vIEZvcm0gZGF0YSBvYnNlcnZhYmxlXHJcbiAgaXNWYWxpZENoYW5nZXM6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KCk7IC8vIGlzVmFsaWQgb2JzZXJ2YWJsZVxyXG4gIHZhbGlkYXRpb25FcnJvckNoYW5nZXM6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KCk7IC8vIHZhbGlkYXRpb25FcnJvcnMgb2JzZXJ2YWJsZVxyXG5cclxuICBhcnJheU1hcDogTWFwPHN0cmluZywgbnVtYmVyPiA9IG5ldyBNYXAoKTsgLy8gTWFwcyBhcnJheXMgaW4gZGF0YSBvYmplY3QgYW5kIG51bWJlciBvZiB0dXBsZSB2YWx1ZXNcclxuICBkYXRhTWFwOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpOyAvLyBNYXBzIHBhdGhzIGluIGZvcm0gZGF0YSB0byBzY2hlbWEgYW5kIGZvcm1Hcm91cCBwYXRoc1xyXG4gIGRhdGFSZWN1cnNpdmVSZWZNYXA6IE1hcDxzdHJpbmcsIHN0cmluZz4gPSBuZXcgTWFwKCk7IC8vIE1hcHMgcmVjdXJzaXZlIHJlZmVyZW5jZSBwb2ludHMgaW4gZm9ybSBkYXRhXHJcbiAgc2NoZW1hUmVjdXJzaXZlUmVmTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpOyAvLyBNYXBzIHJlY3Vyc2l2ZSByZWZlcmVuY2UgcG9pbnRzIGluIHNjaGVtYVxyXG4gIHNjaGVtYVJlZkxpYnJhcnk6IGFueSA9IHt9OyAvLyBMaWJyYXJ5IG9mIHNjaGVtYXMgZm9yIHJlc29sdmluZyBzY2hlbWEgJHJlZnNcclxuICBsYXlvdXRSZWZMaWJyYXJ5OiBhbnkgPSB7ICcnOiBudWxsIH07IC8vIExpYnJhcnkgb2YgbGF5b3V0IG5vZGVzIGZvciBhZGRpbmcgdG8gZm9ybVxyXG4gIHRlbXBsYXRlUmVmTGlicmFyeTogYW55ID0ge307IC8vIExpYnJhcnkgb2YgZm9ybUdyb3VwIHRlbXBsYXRlcyBmb3IgYWRkaW5nIHRvIGZvcm1cclxuICBoYXNSb290UmVmZXJlbmNlID0gZmFsc2U7IC8vIERvZXMgdGhlIGZvcm0gaW5jbHVkZSBhIHJlY3Vyc2l2ZSByZWZlcmVuY2UgdG8gaXRzZWxmP1xyXG5cclxuICBsYW5ndWFnZSA9ICdlbi1VUyc7IC8vIERvZXMgdGhlIGZvcm0gaW5jbHVkZSBhIHJlY3Vyc2l2ZSByZWZlcmVuY2UgdG8gaXRzZWxmP1xyXG5cclxuICAvLyBEZWZhdWx0IGdsb2JhbCBmb3JtIG9wdGlvbnNcclxuICBkZWZhdWx0Rm9ybU9wdGlvbnM6IGFueSA9IHtcclxuICAgIGF1dG9jb21wbGV0ZTogdHJ1ZSwgLy8gQWxsb3cgdGhlIHdlYiBicm93c2VyIHRvIHJlbWVtYmVyIHByZXZpb3VzIGZvcm0gc3VibWlzc2lvbiB2YWx1ZXMgYXMgZGVmYXVsdHNcclxuICAgIGFkZFN1Ym1pdDogJ2F1dG8nLCAvLyBBZGQgYSBzdWJtaXQgYnV0dG9uIGlmIGxheW91dCBkb2VzIG5vdCBoYXZlIG9uZT9cclxuICAgIC8vIGZvciBhZGRTdWJtaXQ6IHRydWUgPSBhbHdheXMsIGZhbHNlID0gbmV2ZXIsXHJcbiAgICAvLyAnYXV0bycgPSBvbmx5IGlmIGxheW91dCBpcyB1bmRlZmluZWQgKGZvcm0gaXMgYnVpbHQgZnJvbSBzY2hlbWEgYWxvbmUpXHJcbiAgICBkZWJ1ZzogZmFsc2UsIC8vIFNob3cgZGVidWdnaW5nIG91dHB1dD9cclxuICAgIGRpc2FibGVJbnZhbGlkU3VibWl0OiB0cnVlLCAvLyBEaXNhYmxlIHN1Ym1pdCBpZiBmb3JtIGludmFsaWQ/XHJcbiAgICBmb3JtRGlzYWJsZWQ6IGZhbHNlLCAvLyBTZXQgZW50aXJlIGZvcm0gYXMgZGlzYWJsZWQ/IChub3QgZWRpdGFibGUsIGFuZCBkaXNhYmxlcyBvdXRwdXRzKVxyXG4gICAgZm9ybVJlYWRvbmx5OiBmYWxzZSwgLy8gU2V0IGVudGlyZSBmb3JtIGFzIHJlYWQgb25seT8gKG5vdCBlZGl0YWJsZSwgYnV0IG91dHB1dHMgc3RpbGwgZW5hYmxlZClcclxuICAgIGZpZWxkc1JlcXVpcmVkOiBmYWxzZSwgLy8gKHNldCBhdXRvbWF0aWNhbGx5KSBBcmUgdGhlcmUgYW55IHJlcXVpcmVkIGZpZWxkcyBpbiB0aGUgZm9ybT9cclxuICAgIGZyYW1ld29yazogJ25vLWZyYW1ld29yaycsIC8vIFRoZSBmcmFtZXdvcmsgdG8gbG9hZFxyXG4gICAgbG9hZEV4dGVybmFsQXNzZXRzOiBmYWxzZSwgLy8gTG9hZCBleHRlcm5hbCBjc3MgYW5kIEphdmFTY3JpcHQgZm9yIGZyYW1ld29yaz9cclxuICAgIHByaXN0aW5lOiB7IGVycm9yczogdHJ1ZSwgc3VjY2VzczogdHJ1ZSB9LFxyXG4gICAgc3VwcmVzc1Byb3BlcnR5VGl0bGVzOiBmYWxzZSxcclxuICAgIHNldFNjaGVtYURlZmF1bHRzOiAnYXV0bycsIC8vIFNldCBmZWZhdWx0IHZhbHVlcyBmcm9tIHNjaGVtYT9cclxuICAgIC8vIHRydWUgPSBhbHdheXMgc2V0ICh1bmxlc3Mgb3ZlcnJpZGRlbiBieSBsYXlvdXQgZGVmYXVsdCBvciBmb3JtVmFsdWVzKVxyXG4gICAgLy8gZmFsc2UgPSBuZXZlciBzZXRcclxuICAgIC8vICdhdXRvJyA9IHNldCBpbiBhZGRhYmxlIGNvbXBvbmVudHMsIGFuZCBldmVyeXdoZXJlIGlmIGZvcm1WYWx1ZXMgbm90IHNldFxyXG4gICAgc2V0TGF5b3V0RGVmYXVsdHM6ICdhdXRvJywgLy8gU2V0IGZlZmF1bHQgdmFsdWVzIGZyb20gbGF5b3V0P1xyXG4gICAgLy8gdHJ1ZSA9IGFsd2F5cyBzZXQgKHVubGVzcyBvdmVycmlkZGVuIGJ5IGZvcm1WYWx1ZXMpXHJcbiAgICAvLyBmYWxzZSA9IG5ldmVyIHNldFxyXG4gICAgLy8gJ2F1dG8nID0gc2V0IGluIGFkZGFibGUgY29tcG9uZW50cywgYW5kIGV2ZXJ5d2hlcmUgaWYgZm9ybVZhbHVlcyBub3Qgc2V0XHJcbiAgICB2YWxpZGF0ZU9uUmVuZGVyOiAnYXV0bycsIC8vIFZhbGlkYXRlIGZpZWxkcyBpbW1lZGlhdGVseSwgYmVmb3JlIHRoZXkgYXJlIHRvdWNoZWQ/XHJcbiAgICAvLyB0cnVlID0gdmFsaWRhdGUgYWxsIGZpZWxkcyBpbW1lZGlhdGVseVxyXG4gICAgLy8gZmFsc2UgPSBvbmx5IHZhbGlkYXRlIGZpZWxkcyBhZnRlciB0aGV5IGFyZSB0b3VjaGVkIGJ5IHVzZXJcclxuICAgIC8vICdhdXRvJyA9IHZhbGlkYXRlIGZpZWxkcyB3aXRoIHZhbHVlcyBpbW1lZGlhdGVseSwgZW1wdHkgZmllbGRzIGFmdGVyIHRoZXkgYXJlIHRvdWNoZWRcclxuICAgIHdpZGdldHM6IHt9LCAvLyBBbnkgY3VzdG9tIHdpZGdldHMgdG8gbG9hZFxyXG4gICAgZGVmYXVsdFdpZGdldE9wdGlvbnM6IHtcclxuICAgICAgLy8gRGVmYXVsdCBvcHRpb25zIGZvciBmb3JtIGNvbnRyb2wgd2lkZ2V0c1xyXG4gICAgICBsaXN0SXRlbXM6IDEsIC8vIE51bWJlciBvZiBsaXN0IGl0ZW1zIHRvIGluaXRpYWxseSBhZGQgdG8gYXJyYXlzIHdpdGggbm8gZGVmYXVsdCB2YWx1ZVxyXG4gICAgICBhZGRhYmxlOiB0cnVlLCAvLyBBbGxvdyBhZGRpbmcgaXRlbXMgdG8gYW4gYXJyYXkgb3IgJHJlZiBwb2ludD9cclxuICAgICAgb3JkZXJhYmxlOiB0cnVlLCAvLyBBbGxvdyByZW9yZGVyaW5nIGl0ZW1zIHdpdGhpbiBhbiBhcnJheT9cclxuICAgICAgcmVtb3ZhYmxlOiB0cnVlLCAvLyBBbGxvdyByZW1vdmluZyBpdGVtcyBmcm9tIGFuIGFycmF5IG9yICRyZWYgcG9pbnQ/XHJcbiAgICAgIGVuYWJsZUVycm9yU3RhdGU6IHRydWUsIC8vIEFwcGx5ICdoYXMtZXJyb3InIGNsYXNzIHdoZW4gZmllbGQgZmFpbHMgdmFsaWRhdGlvbj9cclxuICAgICAgLy8gZGlzYWJsZUVycm9yU3RhdGU6IGZhbHNlLCAvLyBEb24ndCBhcHBseSAnaGFzLWVycm9yJyBjbGFzcyB3aGVuIGZpZWxkIGZhaWxzIHZhbGlkYXRpb24/XHJcbiAgICAgIGVuYWJsZVN1Y2Nlc3NTdGF0ZTogdHJ1ZSwgLy8gQXBwbHkgJ2hhcy1zdWNjZXNzJyBjbGFzcyB3aGVuIGZpZWxkIHZhbGlkYXRlcz9cclxuICAgICAgLy8gZGlzYWJsZVN1Y2Nlc3NTdGF0ZTogZmFsc2UsIC8vIERvbid0IGFwcGx5ICdoYXMtc3VjY2VzcycgY2xhc3Mgd2hlbiBmaWVsZCB2YWxpZGF0ZXM/XHJcbiAgICAgIGZlZWRiYWNrOiBmYWxzZSwgLy8gU2hvdyBpbmxpbmUgZmVlZGJhY2sgaWNvbnM/XHJcbiAgICAgIGZlZWRiYWNrT25SZW5kZXI6IGZhbHNlLCAvLyBTaG93IGVycm9yTWVzc2FnZSBvbiBSZW5kZXI/XHJcbiAgICAgIG5vdGl0bGU6IGZhbHNlLCAvLyBIaWRlIHRpdGxlP1xyXG4gICAgICBkaXNhYmxlZDogZmFsc2UsIC8vIFNldCBjb250cm9sIGFzIGRpc2FibGVkPyAobm90IGVkaXRhYmxlLCBhbmQgZXhjbHVkZWQgZnJvbSBvdXRwdXQpXHJcbiAgICAgIHJlYWRvbmx5OiBmYWxzZSwgLy8gU2V0IGNvbnRyb2wgYXMgcmVhZCBvbmx5PyAobm90IGVkaXRhYmxlLCBidXQgaW5jbHVkZWQgaW4gb3V0cHV0KVxyXG4gICAgICByZXR1cm5FbXB0eUZpZWxkczogdHJ1ZSwgLy8gcmV0dXJuIHZhbHVlcyBmb3IgZmllbGRzIHRoYXQgY29udGFpbiBubyBkYXRhP1xyXG4gICAgICB2YWxpZGF0aW9uTWVzc2FnZXM6IHt9IC8vIHNldCBieSBzZXRMYW5ndWFnZSgpXHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgZmNWYWx1ZUNoYW5nZXNTdWJzOlN1YnNjcmlwdGlvbjtcclxuICBmY1N0YXR1c0NoYW5nZXNTdWJzOlN1YnNjcmlwdGlvbjtcclxuICBjb25zdHJ1Y3RvcigpIHtcclxuICAgIHRoaXMuc2V0TGFuZ3VhZ2UodGhpcy5sYW5ndWFnZSk7XHJcbiAgICB0aGlzLmFqdi5hZGRNZXRhU2NoZW1hKGpzb25EcmFmdDYpO1xyXG4gICAgdGhpcy5hanYuYWRkTWV0YVNjaGVtYShqc29uRHJhZnQ3KTtcclxuICB9XHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLmZjVmFsdWVDaGFuZ2VzU3Vicz8udW5zdWJzY3JpYmUoKTtcclxuICAgIHRoaXMuZmNTdGF0dXNDaGFuZ2VzU3Vicz8udW5zdWJzY3JpYmUoKTtcclxuICAgIHRoaXMuZm9ybVZhbHVlU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xyXG4gICAgdGhpcy5mY1ZhbHVlQ2hhbmdlc1N1YnM9bnVsbDtcclxuICAgIHRoaXMuZmNTdGF0dXNDaGFuZ2VzU3Vicz1udWxsO1xyXG4gICAgdGhpcy5mb3JtVmFsdWVTdWJzY3JpcHRpb249bnVsbDtcclxuXHJcbiAgfVxyXG5cclxuICBzZXRMYW5ndWFnZShsYW5ndWFnZTogc3RyaW5nID0gJ2VuLVVTJykge1xyXG4gICAgdGhpcy5sYW5ndWFnZSA9IGxhbmd1YWdlO1xyXG4gICAgY29uc3QgbGFuZ3VhZ2VWYWxpZGF0aW9uTWVzc2FnZXMgPSB7XHJcbiAgICAgIGRlOiBkZVZhbGlkYXRpb25NZXNzYWdlcyxcclxuICAgICAgZW46IGVuVmFsaWRhdGlvbk1lc3NhZ2VzLFxyXG4gICAgICBlczogZXNWYWxpZGF0aW9uTWVzc2FnZXMsXHJcbiAgICAgIGZyOiBmclZhbGlkYXRpb25NZXNzYWdlcyxcclxuICAgICAgaXQ6IGl0VmFsaWRhdGlvbk1lc3NhZ2VzLFxyXG4gICAgICBwdDogcHRWYWxpZGF0aW9uTWVzc2FnZXMsXHJcbiAgICAgIHpoOiB6aFZhbGlkYXRpb25NZXNzYWdlcyxcclxuICAgIH07XHJcbiAgICBjb25zdCBsYW5ndWFnZUNvZGUgPSBsYW5ndWFnZS5zbGljZSgwLCAyKTtcclxuXHJcbiAgICBjb25zdCB2YWxpZGF0aW9uTWVzc2FnZXMgPSBsYW5ndWFnZVZhbGlkYXRpb25NZXNzYWdlc1tsYW5ndWFnZUNvZGVdO1xyXG5cclxuICAgIHRoaXMuZGVmYXVsdEZvcm1PcHRpb25zLmRlZmF1bHRXaWRnZXRPcHRpb25zLnZhbGlkYXRpb25NZXNzYWdlcyA9IGNsb25lRGVlcChcclxuICAgICAgdmFsaWRhdGlvbk1lc3NhZ2VzXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgZ2V0RGF0YSgpIHtcclxuICAgIHJldHVybiB0aGlzLmRhdGE7XHJcbiAgfVxyXG5cclxuICBnZXRTY2hlbWEoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zY2hlbWE7XHJcbiAgfVxyXG5cclxuICBnZXRMYXlvdXQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5sYXlvdXQ7XHJcbiAgfVxyXG5cclxuICByZXNldEFsbFZhbHVlcygpIHtcclxuICAgIHRoaXMuSnNvbkZvcm1Db21wYXRpYmlsaXR5ID0gZmFsc2U7XHJcbiAgICB0aGlzLlJlYWN0SnNvblNjaGVtYUZvcm1Db21wYXRpYmlsaXR5ID0gZmFsc2U7XHJcbiAgICB0aGlzLkFuZ3VsYXJTY2hlbWFGb3JtQ29tcGF0aWJpbGl0eSA9IGZhbHNlO1xyXG4gICAgdGhpcy50cGxkYXRhID0ge307XHJcbiAgICB0aGlzLnZhbGlkYXRlRm9ybURhdGEgPSBudWxsO1xyXG4gICAgdGhpcy5mb3JtVmFsdWVzID0ge307XHJcbiAgICB0aGlzLnNjaGVtYSA9IHt9O1xyXG4gICAgdGhpcy5sYXlvdXQgPSBbXTtcclxuICAgIHRoaXMuZm9ybUdyb3VwVGVtcGxhdGUgPSB7fTtcclxuICAgIHRoaXMuZm9ybUdyb3VwID0gbnVsbDtcclxuICAgIHRoaXMuZnJhbWV3b3JrID0gbnVsbDtcclxuICAgIHRoaXMuZGF0YSA9IHt9O1xyXG4gICAgdGhpcy52YWxpZERhdGEgPSBudWxsO1xyXG4gICAgdGhpcy5pc1ZhbGlkID0gbnVsbDtcclxuICAgIHRoaXMudmFsaWRhdGlvbkVycm9ycyA9IG51bGw7XHJcbiAgICB0aGlzLmFycmF5TWFwID0gbmV3IE1hcCgpO1xyXG4gICAgdGhpcy5kYXRhTWFwID0gbmV3IE1hcCgpO1xyXG4gICAgdGhpcy5kYXRhUmVjdXJzaXZlUmVmTWFwID0gbmV3IE1hcCgpO1xyXG4gICAgdGhpcy5zY2hlbWFSZWN1cnNpdmVSZWZNYXAgPSBuZXcgTWFwKCk7XHJcbiAgICB0aGlzLmxheW91dFJlZkxpYnJhcnkgPSB7fTtcclxuICAgIHRoaXMuc2NoZW1hUmVmTGlicmFyeSA9IHt9O1xyXG4gICAgdGhpcy50ZW1wbGF0ZVJlZkxpYnJhcnkgPSB7fTtcclxuICAgIHRoaXMuZm9ybU9wdGlvbnMgPSBjbG9uZURlZXAodGhpcy5kZWZhdWx0Rm9ybU9wdGlvbnMpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ2J1aWxkUmVtb3RlRXJyb3InIGZ1bmN0aW9uXHJcbiAgICpcclxuICAgKiBFeGFtcGxlIGVycm9yczpcclxuICAgKiB7XHJcbiAgICogICBsYXN0X25hbWU6IFsge1xyXG4gICAqICAgICBtZXNzYWdlOiAnTGFzdCBuYW1lIG11c3QgYnkgc3RhcnQgd2l0aCBjYXBpdGFsIGxldHRlci4nLFxyXG4gICAqICAgICBjb2RlOiAnY2FwaXRhbF9sZXR0ZXInXHJcbiAgICogICB9IF0sXHJcbiAgICogICBlbWFpbDogWyB7XHJcbiAgICogICAgIG1lc3NhZ2U6ICdFbWFpbCBtdXN0IGJlIGZyb20gZXhhbXBsZS5jb20gZG9tYWluLicsXHJcbiAgICogICAgIGNvZGU6ICdzcGVjaWFsX2RvbWFpbidcclxuICAgKiAgIH0sIHtcclxuICAgKiAgICAgbWVzc2FnZTogJ0VtYWlsIG11c3QgY29udGFpbiBhbiBAIHN5bWJvbC4nLFxyXG4gICAqICAgICBjb2RlOiAnYXRfc3ltYm9sJ1xyXG4gICAqICAgfSBdXHJcbiAgICogfVxyXG4gICAqIC8ve0Vycm9yTWVzc2FnZXN9IGVycm9yc1xyXG4gICAqL1xyXG4gIGJ1aWxkUmVtb3RlRXJyb3IoZXJyb3JzOiBFcnJvck1lc3NhZ2VzKSB7XHJcbiAgICBmb3JFYWNoKGVycm9ycywgKHZhbHVlLCBrZXkpID0+IHtcclxuICAgICAgaWYgKGtleSBpbiB0aGlzLmZvcm1Hcm91cC5jb250cm9scykge1xyXG4gICAgICAgIGZvciAoY29uc3QgZXJyb3Igb2YgdmFsdWUpIHtcclxuICAgICAgICAgIGNvbnN0IGVyciA9IHt9O1xyXG4gICAgICAgICAgZXJyW2Vycm9yWydjb2RlJ11dID0gZXJyb3JbJ21lc3NhZ2UnXTtcclxuICAgICAgICAgIHRoaXMuZm9ybUdyb3VwLmdldChrZXkpLnNldEVycm9ycyhlcnIsIHsgZW1pdEV2ZW50OiB0cnVlIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICB2YWxpZGF0ZURhdGEobmV3VmFsdWU6IGFueSwgdXBkYXRlU3Vic2NyaXB0aW9ucyA9IHRydWUpOiB2b2lkIHtcclxuICAgIC8vIEZvcm1hdCByYXcgZm9ybSBkYXRhIHRvIGNvcnJlY3QgZGF0YSB0eXBlc1xyXG4gICAgdGhpcy5kYXRhID0gZm9ybWF0Rm9ybURhdGEoXHJcbiAgICAgIG5ld1ZhbHVlLFxyXG4gICAgICB0aGlzLmRhdGFNYXAsXHJcbiAgICAgIHRoaXMuZGF0YVJlY3Vyc2l2ZVJlZk1hcCxcclxuICAgICAgdGhpcy5hcnJheU1hcCxcclxuICAgICAgdGhpcy5mb3JtT3B0aW9ucy5yZXR1cm5FbXB0eUZpZWxkc1xyXG4gICAgKTtcclxuICAgIHRoaXMuaXNWYWxpZCA9IHRoaXMudmFsaWRhdGVGb3JtRGF0YSh0aGlzLmRhdGEpO1xyXG4gICAgdGhpcy52YWxpZERhdGEgPSB0aGlzLmlzVmFsaWQgPyB0aGlzLmRhdGEgOiBudWxsO1xyXG4gICAgY29uc3QgY29tcGlsZUVycm9ycyA9IChlcnJvcnM6RXJyb3JPYmplY3RbXSkgPT4ge1xyXG4gICAgICBjb25zdCBjb21waWxlZEVycm9ycyA9IHt9O1xyXG4gICAgICAoZXJyb3JzIHx8IFtdKS5mb3JFYWNoKGVycm9yID0+IHtcclxuICAgICAgICAvL1RPRE8gcmV2aWV3LXNlZW1zIHRvIGJlIGEgY2hhbmdlIGluIG5ld2VyIHZlcnNpb25zXHJcbiAgICAgICAgLy9vZiBhanYgZ2l2aW5nICcnIGFzIGluc3RhbmNlUGF0aCBmb3Igcm9vdCBvYmplY3RzXHJcbiAgICAgICAgbGV0IGVycm9yUGF0aD1lcnJvci5pbnN0YW5jZVBhdGh8fFwiUk9PVFwiO1xyXG4gICAgICAgIGlmICghY29tcGlsZWRFcnJvcnNbZXJyb3JQYXRoXSkge1xyXG4gICAgICAgICAgY29tcGlsZWRFcnJvcnNbZXJyb3JQYXRoXSA9IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb21waWxlZEVycm9yc1tlcnJvclBhdGhdLnB1c2goZXJyb3IubWVzc2FnZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgICByZXR1cm4gY29tcGlsZWRFcnJvcnM7XHJcbiAgICB9O1xyXG4gICAgdGhpcy5hanZFcnJvcnMgPSB0aGlzLnZhbGlkYXRlRm9ybURhdGEuZXJyb3JzO1xyXG4gICAgdGhpcy52YWxpZGF0aW9uRXJyb3JzID0gY29tcGlsZUVycm9ycyh0aGlzLnZhbGlkYXRlRm9ybURhdGEuZXJyb3JzKTtcclxuICAgIGlmICh1cGRhdGVTdWJzY3JpcHRpb25zKSB7XHJcbiAgICAgIHRoaXMuZGF0YUNoYW5nZXMubmV4dCh0aGlzLmRhdGEpO1xyXG4gICAgICB0aGlzLmlzVmFsaWRDaGFuZ2VzLm5leHQodGhpcy5pc1ZhbGlkKTtcclxuICAgICAgdGhpcy52YWxpZGF0aW9uRXJyb3JDaGFuZ2VzLm5leHQodGhpcy5hanZFcnJvcnMpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYnVpbGRGb3JtR3JvdXBUZW1wbGF0ZShmb3JtVmFsdWVzOiBhbnkgPSBudWxsLCBzZXRWYWx1ZXMgPSB0cnVlKSB7XHJcbiAgICB0aGlzLmZvcm1Hcm91cFRlbXBsYXRlID0gYnVpbGRGb3JtR3JvdXBUZW1wbGF0ZShcclxuICAgICAgdGhpcyxcclxuICAgICAgZm9ybVZhbHVlcyxcclxuICAgICAgc2V0VmFsdWVzXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgYnVpbGRGb3JtR3JvdXAoKSB7XHJcbiAgICB0aGlzLmZvcm1Hcm91cCA9IDxVbnR5cGVkRm9ybUdyb3VwPmJ1aWxkRm9ybUdyb3VwKHRoaXMuZm9ybUdyb3VwVGVtcGxhdGUpO1xyXG4gICAgaWYgKHRoaXMuZm9ybUdyb3VwKSB7XHJcbiAgICAgIHRoaXMuY29tcGlsZUFqdlNjaGVtYSgpO1xyXG4gICAgICB0aGlzLnZhbGlkYXRlRGF0YSh0aGlzLmZvcm1Hcm91cC52YWx1ZSk7XHJcblxyXG4gICAgICAvLyBTZXQgdXAgb2JzZXJ2YWJsZXMgdG8gZW1pdCBkYXRhIGFuZCB2YWxpZGF0aW9uIGluZm8gd2hlbiBmb3JtIGRhdGEgY2hhbmdlc1xyXG4gICAgICBpZiAodGhpcy5mb3JtVmFsdWVTdWJzY3JpcHRpb24pIHtcclxuICAgICAgICB0aGlzLmZvcm1WYWx1ZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZm9ybVZhbHVlU3Vic2NyaXB0aW9uID0gdGhpcy5mb3JtR3JvdXAudmFsdWVDaGFuZ2VzLnN1YnNjcmliZShcclxuICAgICAgICBmb3JtVmFsdWUgPT4gdGhpcy52YWxpZGF0ZURhdGEoZm9ybVZhbHVlKVxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYnVpbGRMYXlvdXQod2lkZ2V0TGlicmFyeTogYW55KSB7XHJcbiAgICB0aGlzLmxheW91dCA9IGJ1aWxkTGF5b3V0KHRoaXMsIHdpZGdldExpYnJhcnkpO1xyXG4gIH1cclxuXHJcbiAgc2V0T3B0aW9ucyhuZXdPcHRpb25zOiBhbnkpIHtcclxuICAgIGlmIChpc09iamVjdChuZXdPcHRpb25zKSkge1xyXG4gICAgICBjb25zdCBhZGRPcHRpb25zID0gY2xvbmVEZWVwKG5ld09wdGlvbnMpO1xyXG4gICAgICAvLyBCYWNrd2FyZCBjb21wYXRpYmlsaXR5IGZvciAnZGVmYXVsdE9wdGlvbnMnIChyZW5hbWVkICdkZWZhdWx0V2lkZ2V0T3B0aW9ucycpXHJcbiAgICAgIGlmIChpc09iamVjdChhZGRPcHRpb25zLmRlZmF1bHRPcHRpb25zKSkge1xyXG4gICAgICAgIE9iamVjdC5hc3NpZ24oXHJcbiAgICAgICAgICB0aGlzLmZvcm1PcHRpb25zLmRlZmF1bHRXaWRnZXRPcHRpb25zLFxyXG4gICAgICAgICAgYWRkT3B0aW9ucy5kZWZhdWx0T3B0aW9uc1xyXG4gICAgICAgICk7XHJcbiAgICAgICAgZGVsZXRlIGFkZE9wdGlvbnMuZGVmYXVsdE9wdGlvbnM7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGlzT2JqZWN0KGFkZE9wdGlvbnMuZGVmYXVsdFdpZGdldE9wdGlvbnMpKSB7XHJcbiAgICAgICAgT2JqZWN0LmFzc2lnbihcclxuICAgICAgICAgIHRoaXMuZm9ybU9wdGlvbnMuZGVmYXVsdFdpZGdldE9wdGlvbnMsXHJcbiAgICAgICAgICBhZGRPcHRpb25zLmRlZmF1bHRXaWRnZXRPcHRpb25zXHJcbiAgICAgICAgKTtcclxuICAgICAgICBkZWxldGUgYWRkT3B0aW9ucy5kZWZhdWx0V2lkZ2V0T3B0aW9ucztcclxuICAgICAgfVxyXG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMuZm9ybU9wdGlvbnMsIGFkZE9wdGlvbnMpO1xyXG5cclxuICAgICAgLy8gY29udmVydCBkaXNhYmxlRXJyb3JTdGF0ZSAvIGRpc2FibGVTdWNjZXNzU3RhdGUgdG8gZW5hYmxlLi4uXHJcbiAgICAgIGNvbnN0IGdsb2JhbERlZmF1bHRzID0gdGhpcy5mb3JtT3B0aW9ucy5kZWZhdWx0V2lkZ2V0T3B0aW9ucztcclxuICAgICAgWydFcnJvclN0YXRlJywgJ1N1Y2Nlc3NTdGF0ZSddXHJcbiAgICAgICAgLmZpbHRlcihzdWZmaXggPT4gaGFzT3duKGdsb2JhbERlZmF1bHRzLCAnZGlzYWJsZScgKyBzdWZmaXgpKVxyXG4gICAgICAgIC5mb3JFYWNoKHN1ZmZpeCA9PiB7XHJcbiAgICAgICAgICBnbG9iYWxEZWZhdWx0c1snZW5hYmxlJyArIHN1ZmZpeF0gPSAhZ2xvYmFsRGVmYXVsdHNbXHJcbiAgICAgICAgICAgICdkaXNhYmxlJyArIHN1ZmZpeFxyXG4gICAgICAgICAgXTtcclxuICAgICAgICAgIGRlbGV0ZSBnbG9iYWxEZWZhdWx0c1snZGlzYWJsZScgKyBzdWZmaXhdO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29tcGlsZUFqdlNjaGVtYSgpIHtcclxuICAgIGlmICghdGhpcy52YWxpZGF0ZUZvcm1EYXRhKSB7XHJcbiAgICAgIC8vIGlmICd1aTpvcmRlcicgZXhpc3RzIGluIHByb3BlcnRpZXMsIG1vdmUgaXQgdG8gcm9vdCBiZWZvcmUgY29tcGlsaW5nIHdpdGggYWp2XHJcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMuc2NoZW1hLnByb3BlcnRpZXNbJ3VpOm9yZGVyJ10pKSB7XHJcbiAgICAgICAgdGhpcy5zY2hlbWFbJ3VpOm9yZGVyJ10gPSB0aGlzLnNjaGVtYS5wcm9wZXJ0aWVzWyd1aTpvcmRlciddO1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLnNjaGVtYS5wcm9wZXJ0aWVzWyd1aTpvcmRlciddO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuYWp2LnJlbW92ZVNjaGVtYSh0aGlzLnNjaGVtYSk7XHJcbiAgICAgIHRoaXMudmFsaWRhdGVGb3JtRGF0YSA9IHRoaXMuYWp2LmNvbXBpbGUodGhpcy5zY2hlbWEpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYnVpbGRTY2hlbWFGcm9tRGF0YShkYXRhPzogYW55LCByZXF1aXJlQWxsRmllbGRzID0gZmFsc2UpOiBhbnkge1xyXG4gICAgaWYgKGRhdGEpIHtcclxuICAgICAgcmV0dXJuIGJ1aWxkU2NoZW1hRnJvbURhdGEoZGF0YSwgcmVxdWlyZUFsbEZpZWxkcyk7XHJcbiAgICB9XHJcbiAgICB0aGlzLnNjaGVtYSA9IGJ1aWxkU2NoZW1hRnJvbURhdGEodGhpcy5mb3JtVmFsdWVzLCByZXF1aXJlQWxsRmllbGRzKTtcclxuICB9XHJcblxyXG4gIGJ1aWxkU2NoZW1hRnJvbUxheW91dChsYXlvdXQ/OiBhbnkpOiBhbnkge1xyXG4gICAgaWYgKGxheW91dCkge1xyXG4gICAgICByZXR1cm4gYnVpbGRTY2hlbWFGcm9tTGF5b3V0KGxheW91dCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLnNjaGVtYSA9IGJ1aWxkU2NoZW1hRnJvbUxheW91dCh0aGlzLmxheW91dCk7XHJcbiAgfVxyXG5cclxuICBzZXRUcGxkYXRhKG5ld1RwbGRhdGE6IGFueSA9IHt9KTogdm9pZCB7XHJcbiAgICB0aGlzLnRwbGRhdGEgPSBuZXdUcGxkYXRhO1xyXG4gIH1cclxuXHJcbiAgcGFyc2VUZXh0KFxyXG4gICAgdGV4dCA9ICcnLFxyXG4gICAgdmFsdWU6IGFueSA9IHt9LFxyXG4gICAgdmFsdWVzOiBhbnkgPSB7fSxcclxuICAgIGtleTogbnVtYmVyIHwgc3RyaW5nID0gbnVsbFxyXG4gICk6IHN0cmluZyB7XHJcbiAgICBpZiAoIXRleHQgfHwgIS97ey4rP319Ly50ZXN0KHRleHQpKSB7XHJcbiAgICAgIHJldHVybiB0ZXh0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRleHQucmVwbGFjZSgve3soLis/KX19L2csICguLi5hKSA9PlxyXG4gICAgICB0aGlzLnBhcnNlRXhwcmVzc2lvbihhWzFdLCB2YWx1ZSwgdmFsdWVzLCBrZXksIHRoaXMudHBsZGF0YSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwYXJzZUV4cHJlc3Npb24oXHJcbiAgICBleHByZXNzaW9uID0gJycsXHJcbiAgICB2YWx1ZTogYW55ID0ge30sXHJcbiAgICB2YWx1ZXM6IGFueSA9IHt9LFxyXG4gICAga2V5OiBudW1iZXIgfCBzdHJpbmcgPSBudWxsLFxyXG4gICAgdHBsZGF0YTogYW55ID0gbnVsbFxyXG4gICkge1xyXG4gICAgaWYgKHR5cGVvZiBleHByZXNzaW9uICE9PSAnc3RyaW5nJykge1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICBjb25zdCBpbmRleCA9IHR5cGVvZiBrZXkgPT09ICdudW1iZXInID8ga2V5ICsgMSArICcnIDoga2V5IHx8ICcnO1xyXG4gICAgZXhwcmVzc2lvbiA9IGV4cHJlc3Npb24udHJpbSgpO1xyXG4gICAgaWYgKFxyXG4gICAgICAoZXhwcmVzc2lvblswXSA9PT0gXCInXCIgfHwgZXhwcmVzc2lvblswXSA9PT0gJ1wiJykgJiZcclxuICAgICAgZXhwcmVzc2lvblswXSA9PT0gZXhwcmVzc2lvbltleHByZXNzaW9uLmxlbmd0aCAtIDFdICYmXHJcbiAgICAgIGV4cHJlc3Npb24uc2xpY2UoMSwgZXhwcmVzc2lvbi5sZW5ndGggLSAxKS5pbmRleE9mKGV4cHJlc3Npb25bMF0pID09PSAtMVxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBleHByZXNzaW9uLnNsaWNlKDEsIGV4cHJlc3Npb24ubGVuZ3RoIC0gMSk7XHJcbiAgICB9XHJcbiAgICBpZiAoZXhwcmVzc2lvbiA9PT0gJ2lkeCcgfHwgZXhwcmVzc2lvbiA9PT0gJyRpbmRleCcpIHtcclxuICAgICAgcmV0dXJuIGluZGV4O1xyXG4gICAgfVxyXG4gICAgaWYgKGV4cHJlc3Npb24gPT09ICd2YWx1ZScgJiYgIWhhc093bih2YWx1ZXMsICd2YWx1ZScpKSB7XHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuICAgIGlmIChcclxuICAgICAgWydcIicsIFwiJ1wiLCAnICcsICd8fCcsICcmJicsICcrJ10uZXZlcnkoXHJcbiAgICAgICAgZGVsaW0gPT4gZXhwcmVzc2lvbi5pbmRleE9mKGRlbGltKSA9PT0gLTFcclxuICAgICAgKVxyXG4gICAgKSB7XHJcbiAgICAgIGNvbnN0IHBvaW50ZXIgPSBKc29uUG9pbnRlci5wYXJzZU9iamVjdFBhdGgoZXhwcmVzc2lvbik7XHJcbiAgICAgIHJldHVybiBwb2ludGVyWzBdID09PSAndmFsdWUnICYmIEpzb25Qb2ludGVyLmhhcyh2YWx1ZSwgcG9pbnRlci5zbGljZSgxKSlcclxuICAgICAgICA/IEpzb25Qb2ludGVyLmdldCh2YWx1ZSwgcG9pbnRlci5zbGljZSgxKSlcclxuICAgICAgICA6IHBvaW50ZXJbMF0gPT09ICd2YWx1ZXMnICYmIEpzb25Qb2ludGVyLmhhcyh2YWx1ZXMsIHBvaW50ZXIuc2xpY2UoMSkpXHJcbiAgICAgICAgICA/IEpzb25Qb2ludGVyLmdldCh2YWx1ZXMsIHBvaW50ZXIuc2xpY2UoMSkpXHJcbiAgICAgICAgICA6IHBvaW50ZXJbMF0gPT09ICd0cGxkYXRhJyAmJiBKc29uUG9pbnRlci5oYXModHBsZGF0YSwgcG9pbnRlci5zbGljZSgxKSlcclxuICAgICAgICAgICAgPyBKc29uUG9pbnRlci5nZXQodHBsZGF0YSwgcG9pbnRlci5zbGljZSgxKSlcclxuICAgICAgICAgICAgOiBKc29uUG9pbnRlci5oYXModmFsdWVzLCBwb2ludGVyKVxyXG4gICAgICAgICAgICAgID8gSnNvblBvaW50ZXIuZ2V0KHZhbHVlcywgcG9pbnRlcilcclxuICAgICAgICAgICAgICA6ICcnO1xyXG4gICAgfVxyXG4gICAgaWYgKGV4cHJlc3Npb24uaW5kZXhPZignW2lkeF0nKSA+IC0xKSB7XHJcbiAgICAgIGV4cHJlc3Npb24gPSBleHByZXNzaW9uLnJlcGxhY2UoL1xcW2lkeFxcXS9nLCA8c3RyaW5nPmluZGV4KTtcclxuICAgIH1cclxuICAgIGlmIChleHByZXNzaW9uLmluZGV4T2YoJ1skaW5kZXhdJykgPiAtMSkge1xyXG4gICAgICBleHByZXNzaW9uID0gZXhwcmVzc2lvbi5yZXBsYWNlKC9cXFskaW5kZXhcXF0vZywgPHN0cmluZz5pbmRleCk7XHJcbiAgICB9XHJcbiAgICAvLyBUT0RPOiBJbXByb3ZlIGV4cHJlc3Npb24gZXZhbHVhdGlvbiBieSBwYXJzaW5nIHF1b3RlZCBzdHJpbmdzIGZpcnN0XHJcbiAgICAvLyBsZXQgZXhwcmVzc2lvbkFycmF5ID0gZXhwcmVzc2lvbi5tYXRjaCgvKFteXCInXSt8XCJbXlwiXStcInwnW14nXSsnKS9nKTtcclxuICAgIGlmIChleHByZXNzaW9uLmluZGV4T2YoJ3x8JykgPiAtMSkge1xyXG4gICAgICByZXR1cm4gZXhwcmVzc2lvblxyXG4gICAgICAgIC5zcGxpdCgnfHwnKVxyXG4gICAgICAgIC5yZWR1Y2UoXHJcbiAgICAgICAgICAoYWxsLCB0ZXJtKSA9PlxyXG4gICAgICAgICAgICBhbGwgfHwgdGhpcy5wYXJzZUV4cHJlc3Npb24odGVybSwgdmFsdWUsIHZhbHVlcywga2V5LCB0cGxkYXRhKSxcclxuICAgICAgICAgICcnXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuICAgIGlmIChleHByZXNzaW9uLmluZGV4T2YoJyYmJykgPiAtMSkge1xyXG4gICAgICByZXR1cm4gZXhwcmVzc2lvblxyXG4gICAgICAgIC5zcGxpdCgnJiYnKVxyXG4gICAgICAgIC5yZWR1Y2UoXHJcbiAgICAgICAgICAoYWxsLCB0ZXJtKSA9PlxyXG4gICAgICAgICAgICBhbGwgJiYgdGhpcy5wYXJzZUV4cHJlc3Npb24odGVybSwgdmFsdWUsIHZhbHVlcywga2V5LCB0cGxkYXRhKSxcclxuICAgICAgICAgICcgJ1xyXG4gICAgICAgIClcclxuICAgICAgICAudHJpbSgpO1xyXG4gICAgfVxyXG4gICAgaWYgKGV4cHJlc3Npb24uaW5kZXhPZignKycpID4gLTEpIHtcclxuICAgICAgcmV0dXJuIGV4cHJlc3Npb25cclxuICAgICAgICAuc3BsaXQoJysnKVxyXG4gICAgICAgIC5tYXAodGVybSA9PiB0aGlzLnBhcnNlRXhwcmVzc2lvbih0ZXJtLCB2YWx1ZSwgdmFsdWVzLCBrZXksIHRwbGRhdGEpKVxyXG4gICAgICAgIC5qb2luKCcnKTtcclxuICAgIH1cclxuICAgIHJldHVybiAnJztcclxuICB9XHJcblxyXG4gIHNldEFycmF5SXRlbVRpdGxlKFxyXG4gICAgcGFyZW50Q3R4OiBhbnkgPSB7fSxcclxuICAgIGNoaWxkTm9kZTogYW55ID0gbnVsbCxcclxuICAgIGluZGV4OiBudW1iZXIgPSBudWxsXHJcbiAgKTogc3RyaW5nIHtcclxuICAgIC8vZm9yIGxlZ2FjeSBjb21wYXRpYmlsaXR5LCBwYXJlbnRDdHgubGF5b3V0Tm9kZSBjb3VsZCBlaXRoZXIgYmUgYSB2YWx1ZVxyXG4gICAgLy9vciBoYXZlIGJlZW4gY29udmVydGVkIHRvIHVzZSBTaWduYWxzXHJcbiAgICBsZXQgcGFyZW50Q3R4QXNTaWduYWxzOmFueT17XHJcbiAgICAgIGxheW91dE5vZGU6KCk9PntcclxuICAgICAgICBpZihpc09iamVjdChwYXJlbnRDdHgubGF5b3V0Tm9kZSkpe1xyXG4gICAgICAgICAgcmV0dXJuIHBhcmVudEN0eC5sYXlvdXROb2RlXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwYXJlbnRDdHgubGF5b3V0Tm9kZSgpO1xyXG4gICAgICB9LFxyXG4gICAgICBkYXRhSW5kZXg6KCk9PntcclxuICAgICAgICBpZihpc09iamVjdChwYXJlbnRDdHguZGF0YUluZGV4KSl7XHJcbiAgICAgICAgICByZXR1cm4gcGFyZW50Q3R4LmRhdGFJbmRleFxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcGFyZW50Q3R4LmRhdGFJbmRleCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBjb25zdCBwYXJlbnROb2RlID0gcGFyZW50Q3R4QXNTaWduYWxzLmxheW91dE5vZGUoKTtcclxuICAgIGNvbnN0IHBhcmVudFZhbHVlczogYW55ID0gdGhpcy5nZXRGb3JtQ29udHJvbFZhbHVlKHBhcmVudEN0eEFzU2lnbmFscyk7XHJcbiAgICBjb25zdCBpc0FycmF5SXRlbSA9XHJcbiAgICAgIChwYXJlbnROb2RlLnR5cGUgfHwgJycpLnNsaWNlKC01KSA9PT0gJ2FycmF5JyAmJiBpc0FycmF5KHBhcmVudFZhbHVlcyk7XHJcbiAgICBjb25zdCB0ZXh0ID0gSnNvblBvaW50ZXIuZ2V0Rmlyc3QoXHJcbiAgICAgIGlzQXJyYXlJdGVtICYmIGNoaWxkTm9kZS50eXBlICE9PSAnJHJlZidcclxuICAgICAgICA/IFtcclxuICAgICAgICAgIFtjaGlsZE5vZGUsICcvb3B0aW9ucy9sZWdlbmQnXSxcclxuICAgICAgICAgIFtjaGlsZE5vZGUsICcvb3B0aW9ucy90aXRsZSddLFxyXG4gICAgICAgICAgW3BhcmVudE5vZGUsICcvb3B0aW9ucy90aXRsZSddLFxyXG4gICAgICAgICAgW3BhcmVudE5vZGUsICcvb3B0aW9ucy9sZWdlbmQnXVxyXG4gICAgICAgIF1cclxuICAgICAgICA6IFtcclxuICAgICAgICAgIFtjaGlsZE5vZGUsICcvb3B0aW9ucy90aXRsZSddLFxyXG4gICAgICAgICAgW2NoaWxkTm9kZSwgJy9vcHRpb25zL2xlZ2VuZCddLFxyXG4gICAgICAgICAgW3BhcmVudE5vZGUsICcvb3B0aW9ucy90aXRsZSddLFxyXG4gICAgICAgICAgW3BhcmVudE5vZGUsICcvb3B0aW9ucy9sZWdlbmQnXVxyXG4gICAgICAgIF1cclxuICAgICk7XHJcbiAgICBpZiAoIXRleHQpIHtcclxuICAgICAgcmV0dXJuIHRleHQ7XHJcbiAgICB9XHJcbiAgICBjb25zdCBjaGlsZFZhbHVlID1cclxuICAgICAgaXNBcnJheShwYXJlbnRWYWx1ZXMpICYmIGluZGV4IDwgcGFyZW50VmFsdWVzLmxlbmd0aFxyXG4gICAgICAgID8gcGFyZW50VmFsdWVzW2luZGV4XVxyXG4gICAgICAgIDogcGFyZW50VmFsdWVzO1xyXG4gICAgcmV0dXJuIHRoaXMucGFyc2VUZXh0KHRleHQsIGNoaWxkVmFsdWUsIHBhcmVudFZhbHVlcywgaW5kZXgpO1xyXG4gIH1cclxuXHJcbiAgc2V0SXRlbVRpdGxlKGN0eDogV2lkZ2V0Q29udGV4dCkge1xyXG4gICAgcmV0dXJuICFjdHgub3B0aW9ucy50aXRsZSAmJiAvXihcXGQrfC0pJC8udGVzdChjdHgubGF5b3V0Tm9kZSgpLm5hbWUpXHJcbiAgICAgID8gbnVsbFxyXG4gICAgICA6IHRoaXMucGFyc2VUZXh0KFxyXG4gICAgICAgIGN0eC5vcHRpb25zLnRpdGxlIHx8IHRvVGl0bGVDYXNlKGN0eC5sYXlvdXROb2RlKCkubmFtZSksXHJcbiAgICAgICAgdGhpcy5nZXRGb3JtQ29udHJvbFZhbHVlKGN0eCksXHJcbiAgICAgICAgKHRoaXMuZ2V0Rm9ybUNvbnRyb2xHcm91cChjdHgpIHx8IDxhbnk+e30pLnZhbHVlLFxyXG4gICAgICAgIGN0eC5kYXRhSW5kZXgoKVtjdHguZGF0YUluZGV4KCkubGVuZ3RoIC0gMV1cclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIGV2YWx1YXRlQ29uZGl0aW9uKGxheW91dE5vZGU6IGFueSwgZGF0YUluZGV4OiBudW1iZXJbXSk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgYXJyYXlJbmRleCA9IGRhdGFJbmRleCAmJiBkYXRhSW5kZXhbZGF0YUluZGV4Lmxlbmd0aCAtIDFdO1xyXG4gICAgbGV0IHJlc3VsdCA9IHRydWU7XHJcbiAgICBpZiAoaGFzVmFsdWUoKGxheW91dE5vZGUub3B0aW9ucyB8fCB7fSkuY29uZGl0aW9uKSkge1xyXG4gICAgICBpZiAodHlwZW9mIGxheW91dE5vZGUub3B0aW9ucy5jb25kaXRpb24gPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgbGV0IHBvaW50ZXIgPSBsYXlvdXROb2RlLm9wdGlvbnMuY29uZGl0aW9uO1xyXG4gICAgICAgIGlmIChoYXNWYWx1ZShhcnJheUluZGV4KSkge1xyXG4gICAgICAgICAgcG9pbnRlciA9IHBvaW50ZXIucmVwbGFjZSgnW2FycmF5SW5kZXhdJywgYFske2FycmF5SW5kZXh9XWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwb2ludGVyID0gSnNvblBvaW50ZXIucGFyc2VPYmplY3RQYXRoKHBvaW50ZXIpO1xyXG4gICAgICAgIHJlc3VsdCA9ICEhSnNvblBvaW50ZXIuZ2V0KHRoaXMuZGF0YSwgcG9pbnRlcik7XHJcbiAgICAgICAgaWYgKCFyZXN1bHQgJiYgcG9pbnRlclswXSA9PT0gJ21vZGVsJykge1xyXG4gICAgICAgICAgcmVzdWx0ID0gISFKc29uUG9pbnRlci5nZXQoeyBtb2RlbDogdGhpcy5kYXRhIH0sIHBvaW50ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGF5b3V0Tm9kZS5vcHRpb25zLmNvbmRpdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIHJlc3VsdCA9IGxheW91dE5vZGUub3B0aW9ucy5jb25kaXRpb24odGhpcy5kYXRhKTtcclxuICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICB0eXBlb2YgbGF5b3V0Tm9kZS5vcHRpb25zLmNvbmRpdGlvbi5mdW5jdGlvbkJvZHkgPT09ICdzdHJpbmcnXHJcbiAgICAgICkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBjb25zdCBkeW5GbiA9IG5ldyBGdW5jdGlvbihcclxuICAgICAgICAgICAgJ21vZGVsJyxcclxuICAgICAgICAgICAgJ2FycmF5SW5kaWNlcycsXHJcbiAgICAgICAgICAgIGxheW91dE5vZGUub3B0aW9ucy5jb25kaXRpb24uZnVuY3Rpb25Cb2R5XHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmVzdWx0ID0gZHluRm4odGhpcy5kYXRhLCBkYXRhSW5kZXgpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgIHJlc3VsdCA9IHRydWU7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFxyXG4gICAgICAgICAgICAnY29uZGl0aW9uIGZ1bmN0aW9uQm9keSBlcnJvcmVkIG91dCBvbiBldmFsdWF0aW9uOiAnICtcclxuICAgICAgICAgICAgbGF5b3V0Tm9kZS5vcHRpb25zLmNvbmRpdGlvbi5mdW5jdGlvbkJvZHlcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgaW5pdGlhbGl6ZUNvbnRyb2woY3R4OiBXaWRnZXRDb250ZXh0LCBiaW5kID0gdHJ1ZSk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKCFpc09iamVjdChjdHgpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmIChpc0VtcHR5KGN0eC5vcHRpb25zKSkge1xyXG4gICAgICBjdHgub3B0aW9ucyA9ICFpc0VtcHR5KChjdHgubGF5b3V0Tm9kZSgpIHx8IHt9KS5vcHRpb25zKVxyXG4gICAgICAgID8gY3R4LmxheW91dE5vZGUoKS5vcHRpb25zXHJcbiAgICAgICAgOiBjbG9uZURlZXAodGhpcy5mb3JtT3B0aW9ucyk7XHJcbiAgICB9XHJcbiAgICBjdHguZm9ybUNvbnRyb2wgPSB0aGlzLmdldEZvcm1Db250cm9sKGN0eCk7XHJcbiAgICBjdHguYm91bmRDb250cm9sID0gYmluZCAmJiAhIWN0eC5mb3JtQ29udHJvbDtcclxuICAgIGlmIChjdHguZm9ybUNvbnRyb2wpIHtcclxuICAgICAgY3R4LmNvbnRyb2xOYW1lID0gdGhpcy5nZXRGb3JtQ29udHJvbE5hbWUoY3R4KTtcclxuICAgICAgY3R4LmNvbnRyb2xWYWx1ZSA9IGN0eC5mb3JtQ29udHJvbC52YWx1ZTtcclxuICAgICAgY3R4LmNvbnRyb2xEaXNhYmxlZCA9IGN0eC5mb3JtQ29udHJvbC5kaXNhYmxlZDtcclxuICAgICAgY3R4Lm9wdGlvbnMuZXJyb3JNZXNzYWdlID1cclxuICAgICAgICBjdHguZm9ybUNvbnRyb2wuc3RhdHVzID09PSAnVkFMSUQnXHJcbiAgICAgICAgICA/IG51bGxcclxuICAgICAgICAgIDogdGhpcy5mb3JtYXRFcnJvcnMoXHJcbiAgICAgICAgICAgIGN0eC5mb3JtQ29udHJvbC5lcnJvcnMsXHJcbiAgICAgICAgICAgIGN0eC5vcHRpb25zLnZhbGlkYXRpb25NZXNzYWdlc1xyXG4gICAgICAgICAgKTtcclxuICAgICAgY3R4Lm9wdGlvbnMuc2hvd0Vycm9ycyA9XHJcbiAgICAgICAgdGhpcy5mb3JtT3B0aW9ucy52YWxpZGF0ZU9uUmVuZGVyID09PSB0cnVlIHx8XHJcbiAgICAgICAgKHRoaXMuZm9ybU9wdGlvbnMudmFsaWRhdGVPblJlbmRlciA9PT0gJ2F1dG8nICYmXHJcbiAgICAgICAgICBoYXNWYWx1ZShjdHguY29udHJvbFZhbHVlKSk7XHJcbiAgICAgIHRoaXMuZmNTdGF0dXNDaGFuZ2VzU3Vicz1jdHguZm9ybUNvbnRyb2wuc3RhdHVzQ2hhbmdlcy5zdWJzY3JpYmUoXHJcbiAgICAgICAgc3RhdHVzID0+XHJcbiAgICAgICAgICAoY3R4Lm9wdGlvbnMuZXJyb3JNZXNzYWdlID1cclxuICAgICAgICAgICAgc3RhdHVzID09PSAnVkFMSUQnXHJcbiAgICAgICAgICAgICAgPyBudWxsXHJcbiAgICAgICAgICAgICAgOiB0aGlzLmZvcm1hdEVycm9ycyhcclxuICAgICAgICAgICAgICAgIGN0eC5mb3JtQ29udHJvbC5lcnJvcnMsXHJcbiAgICAgICAgICAgICAgICBjdHgub3B0aW9ucy52YWxpZGF0aW9uTWVzc2FnZXNcclxuICAgICAgICAgICAgICApKVxyXG4gICAgICApO1xyXG4gICAgICB0aGlzLmZjVmFsdWVDaGFuZ2VzU3Vicz1jdHguZm9ybUNvbnRyb2wudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSh2YWx1ZSA9PiB7XHJcbiAgICAgICAgIC8vY29tbWVudGVkIG91dCB0byByZXZlcnQgYmFjayB0byBwcmV2aW91cyBjb21taXRzXHJcbiAgICAgICAgIC8vYXMgc2VlbXMgdG8gYmUgY2F1c2luZyBzb21lIGlzc3Vlc1xyXG4gICAgICAgICAvKlxyXG4gICAgICAgIGlmICghIXZhbHVlKSB7XHJcbiAgICAgICAgICBjdHguY29udHJvbFZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgICovXHJcbiAgICAgICAgLy9UT0RPLXRlc3QsdGhpcyBpcyB0aGUgb3JpZ2luYWwgY29kZVxyXG4gICAgICAgIGlmICghX2lzRXF1YWwoY3R4LmNvbnRyb2xWYWx1ZSwgdmFsdWUpKSB7IGN0eC5jb250cm9sVmFsdWUgPSB2YWx1ZSB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY3R4LmNvbnRyb2xOYW1lID0gY3R4LmxheW91dE5vZGUoKS5uYW1lO1xyXG4gICAgICBjdHguY29udHJvbFZhbHVlID0gY3R4LmxheW91dE5vZGUoKS52YWx1ZSB8fCBudWxsO1xyXG4gICAgICBjb25zdCBkYXRhUG9pbnRlciA9IHRoaXMuZ2V0RGF0YVBvaW50ZXIoY3R4KTtcclxuICAgICAgaWYgKGJpbmQgJiYgZGF0YVBvaW50ZXIpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKFxyXG4gICAgICAgICAgYHdhcm5pbmc6IGNvbnRyb2wgXCIke2RhdGFQb2ludGVyfVwiIGlzIG5vdCBib3VuZCB0byB0aGUgQW5ndWxhciBGb3JtR3JvdXAuYFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjdHguYm91bmRDb250cm9sO1xyXG4gIH1cclxuXHJcbiAgZm9ybWF0RXJyb3JzKGVycm9yczogYW55LCB2YWxpZGF0aW9uTWVzc2FnZXM6IGFueSA9IHt9KTogc3RyaW5nIHtcclxuICAgIGlmIChpc0VtcHR5KGVycm9ycykpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICBpZiAoIWlzT2JqZWN0KHZhbGlkYXRpb25NZXNzYWdlcykpIHtcclxuICAgICAgdmFsaWRhdGlvbk1lc3NhZ2VzID0ge307XHJcbiAgICB9XHJcbiAgICBjb25zdCBhZGRTcGFjZXMgPSBzdHJpbmcgPT5cclxuICAgICAgc3RyaW5nWzBdLnRvVXBwZXJDYXNlKCkgK1xyXG4gICAgICAoc3RyaW5nLnNsaWNlKDEpIHx8ICcnKVxyXG4gICAgICAgIC5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCAnJDEgJDInKVxyXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcgJyk7XHJcbiAgICBjb25zdCBmb3JtYXRFcnJvciA9IGVycm9yID0+XHJcbiAgICAgIHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCdcclxuICAgICAgICA/IE9iamVjdC5rZXlzKGVycm9yKVxyXG4gICAgICAgICAgLm1hcChrZXkgPT5cclxuICAgICAgICAgICAgZXJyb3Jba2V5XSA9PT0gdHJ1ZVxyXG4gICAgICAgICAgICAgID8gYWRkU3BhY2VzKGtleSlcclxuICAgICAgICAgICAgICA6IGVycm9yW2tleV0gPT09IGZhbHNlXHJcbiAgICAgICAgICAgICAgICA/ICdOb3QgJyArIGFkZFNwYWNlcyhrZXkpXHJcbiAgICAgICAgICAgICAgICA6IGFkZFNwYWNlcyhrZXkpICsgJzogJyArIGZvcm1hdEVycm9yKGVycm9yW2tleV0pXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgICAuam9pbignLCAnKVxyXG4gICAgICAgIDogYWRkU3BhY2VzKGVycm9yLnRvU3RyaW5nKCkpO1xyXG4gICAgY29uc3QgbWVzc2FnZXMgPSBbXTtcclxuICAgIHJldHVybiAoXHJcbiAgICAgIE9iamVjdC5rZXlzKGVycm9ycylcclxuICAgICAgICAvLyBIaWRlICdyZXF1aXJlZCcgZXJyb3IsIHVubGVzcyBpdCBpcyB0aGUgb25seSBvbmVcclxuICAgICAgICAuZmlsdGVyKFxyXG4gICAgICAgICAgZXJyb3JLZXkgPT5cclxuICAgICAgICAgICAgZXJyb3JLZXkgIT09ICdyZXF1aXJlZCcgfHwgT2JqZWN0LmtleXMoZXJyb3JzKS5sZW5ndGggPT09IDFcclxuICAgICAgICApXHJcbiAgICAgICAgLm1hcChlcnJvcktleSA9PlxyXG4gICAgICAgICAgLy8gSWYgdmFsaWRhdGlvbk1lc3NhZ2VzIGlzIGEgc3RyaW5nLCByZXR1cm4gaXRcclxuICAgICAgICAgIHR5cGVvZiB2YWxpZGF0aW9uTWVzc2FnZXMgPT09ICdzdHJpbmcnXHJcbiAgICAgICAgICAgID8gdmFsaWRhdGlvbk1lc3NhZ2VzXHJcbiAgICAgICAgICAgIDogLy8gSWYgY3VzdG9tIGVycm9yIG1lc3NhZ2UgaXMgYSBmdW5jdGlvbiwgcmV0dXJuIGZ1bmN0aW9uIHJlc3VsdFxyXG4gICAgICAgICAgICB0eXBlb2YgdmFsaWRhdGlvbk1lc3NhZ2VzW2Vycm9yS2V5XSA9PT0gJ2Z1bmN0aW9uJ1xyXG4gICAgICAgICAgICAgID8gdmFsaWRhdGlvbk1lc3NhZ2VzW2Vycm9yS2V5XShlcnJvcnNbZXJyb3JLZXldKVxyXG4gICAgICAgICAgICAgIDogLy8gSWYgY3VzdG9tIGVycm9yIG1lc3NhZ2UgaXMgYSBzdHJpbmcsIHJlcGxhY2UgcGxhY2Vob2xkZXJzIGFuZCByZXR1cm5cclxuICAgICAgICAgICAgICB0eXBlb2YgdmFsaWRhdGlvbk1lc3NhZ2VzW2Vycm9yS2V5XSA9PT0gJ3N0cmluZydcclxuICAgICAgICAgICAgICAgID8gLy8gRG9lcyBlcnJvciBtZXNzYWdlIGhhdmUgYW55IHt7cHJvcGVydHl9fSBwbGFjZWhvbGRlcnM/XHJcbiAgICAgICAgICAgICAgICAhL3t7Lis/fX0vLnRlc3QodmFsaWRhdGlvbk1lc3NhZ2VzW2Vycm9yS2V5XSlcclxuICAgICAgICAgICAgICAgICAgPyB2YWxpZGF0aW9uTWVzc2FnZXNbZXJyb3JLZXldXHJcbiAgICAgICAgICAgICAgICAgIDogLy8gUmVwbGFjZSB7e3Byb3BlcnR5fX0gcGxhY2Vob2xkZXJzIHdpdGggdmFsdWVzXHJcbiAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGVycm9yc1tlcnJvcktleV0pLnJlZHVjZShcclxuICAgICAgICAgICAgICAgICAgICAoZXJyb3JNZXNzYWdlLCBlcnJvclByb3BlcnR5KSA9PlxyXG4gICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlLnJlcGxhY2UoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZWdFeHAoJ3t7JyArIGVycm9yUHJvcGVydHkgKyAnfX0nLCAnZycpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnNbZXJyb3JLZXldW2Vycm9yUHJvcGVydHldXHJcbiAgICAgICAgICAgICAgICAgICAgICApLFxyXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25NZXNzYWdlc1tlcnJvcktleV1cclxuICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgOiAvLyBJZiBubyBjdXN0b20gZXJyb3IgbWVzc2FnZSwgcmV0dXJuIGZvcm1hdHRlZCBlcnJvciBkYXRhIGluc3RlYWRcclxuICAgICAgICAgICAgICAgIGFkZFNwYWNlcyhlcnJvcktleSkgKyAnIEVycm9yOiAnICsgZm9ybWF0RXJyb3IoZXJyb3JzW2Vycm9yS2V5XSlcclxuICAgICAgICApXHJcbiAgICAgICAgLmpvaW4oJzxicj4nKVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZVZhbHVlKGN0eDogV2lkZ2V0Q29udGV4dCwgdmFsdWU6IGFueSk6IHZvaWQge1xyXG4gICAgLy8gU2V0IHZhbHVlIG9mIGN1cnJlbnQgY29udHJvbFxyXG4gICAgY3R4LmNvbnRyb2xWYWx1ZSA9IHZhbHVlO1xyXG4gICAgaWYgKGN0eC5ib3VuZENvbnRyb2wpIHtcclxuICAgICAgY3R4LmZvcm1Db250cm9sLnNldFZhbHVlKHZhbHVlKTtcclxuICAgICAgY3R4LmZvcm1Db250cm9sLm1hcmtBc0RpcnR5KCk7XHJcbiAgICB9XHJcbiAgICBjdHgubGF5b3V0Tm9kZSgpLnZhbHVlID0gdmFsdWU7XHJcblxyXG4gICAgLy8gU2V0IHZhbHVlcyBvZiBhbnkgcmVsYXRlZCBjb250cm9scyBpbiBjb3B5VmFsdWVUbyBhcnJheVxyXG4gICAgaWYgKGlzQXJyYXkoY3R4Lm9wdGlvbnMuY29weVZhbHVlVG8pKSB7XHJcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBjdHgub3B0aW9ucy5jb3B5VmFsdWVUbykge1xyXG4gICAgICAgIGNvbnN0IHRhcmdldENvbnRyb2wgPSBnZXRDb250cm9sKHRoaXMuZm9ybUdyb3VwLCBpdGVtKTtcclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgICBpc09iamVjdCh0YXJnZXRDb250cm9sKSAmJlxyXG4gICAgICAgICAgdHlwZW9mIHRhcmdldENvbnRyb2wuc2V0VmFsdWUgPT09ICdmdW5jdGlvbidcclxuICAgICAgICApIHtcclxuICAgICAgICAgIHRhcmdldENvbnRyb2wuc2V0VmFsdWUodmFsdWUpO1xyXG4gICAgICAgICAgdGFyZ2V0Q29udHJvbC5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlQXJyYXlDaGVja2JveExpc3QoY3R4OiBXaWRnZXRDb250ZXh0LCBjaGVja2JveExpc3Q6IFRpdGxlTWFwSXRlbVtdKTogdm9pZCB7XHJcbiAgICBjb25zdCBmb3JtQXJyYXkgPSA8VW50eXBlZEZvcm1BcnJheT50aGlzLmdldEZvcm1Db250cm9sKGN0eCk7XHJcblxyXG4gICAgLy8gUmVtb3ZlIGFsbCBleGlzdGluZyBpdGVtc1xyXG4gICAgd2hpbGUgKGZvcm1BcnJheS52YWx1ZS5sZW5ndGgpIHtcclxuICAgICAgZm9ybUFycmF5LnJlbW92ZUF0KDApO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJlLWFkZCBhbiBpdGVtIGZvciBlYWNoIGNoZWNrZWQgYm94XHJcbiAgICBjb25zdCByZWZQb2ludGVyID0gcmVtb3ZlUmVjdXJzaXZlUmVmZXJlbmNlcyhcclxuICAgICAgY3R4LmxheW91dE5vZGUoKS5kYXRhUG9pbnRlciArICcvLScsXHJcbiAgICAgIHRoaXMuZGF0YVJlY3Vyc2l2ZVJlZk1hcCxcclxuICAgICAgdGhpcy5hcnJheU1hcFxyXG4gICAgKTtcclxuICAgIGZvciAoY29uc3QgY2hlY2tib3hJdGVtIG9mIGNoZWNrYm94TGlzdCkge1xyXG4gICAgICBpZiAoY2hlY2tib3hJdGVtLmNoZWNrZWQpIHtcclxuICAgICAgICBjb25zdCBuZXdGb3JtQ29udHJvbCA9IGJ1aWxkRm9ybUdyb3VwKFxyXG4gICAgICAgICAgdGhpcy50ZW1wbGF0ZVJlZkxpYnJhcnlbcmVmUG9pbnRlcl1cclxuICAgICAgICApO1xyXG4gICAgICAgIG5ld0Zvcm1Db250cm9sLnNldFZhbHVlKGNoZWNrYm94SXRlbS52YWx1ZSk7XHJcbiAgICAgICAgZm9ybUFycmF5LnB1c2gobmV3Rm9ybUNvbnRyb2wpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBmb3JtQXJyYXkubWFya0FzRGlydHkoKTtcclxuICB9XHJcblxyXG4gIGdldEZvcm1Db250cm9sKGN0eDogV2lkZ2V0Q29udGV4dCk6IEFic3RyYWN0Q29udHJvbCB7XHJcbiAgICBpZiAoXHJcbiAgICAgICFjdHggfHwgIWN0eC5sYXlvdXROb2RlIHx8XHJcbiAgICAgICFpc0RlZmluZWQoY3R4LmxheW91dE5vZGUoKS5kYXRhUG9pbnRlcikgfHxcclxuICAgICAgY3R4LmxheW91dE5vZGUoKS50eXBlID09PSAnJHJlZidcclxuICAgICkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiBnZXRDb250cm9sKHRoaXMuZm9ybUdyb3VwLCB0aGlzLmdldERhdGFQb2ludGVyKGN0eCkpO1xyXG4gIH1cclxuXHJcbiAgZ2V0Rm9ybUNvbnRyb2xWYWx1ZShjdHg6IFdpZGdldENvbnRleHQpOiBBYnN0cmFjdENvbnRyb2wge1xyXG5cclxuICAgIGlmICghY3R4IHx8ICFjdHgubGF5b3V0Tm9kZSB8fCBcclxuICAgICAgIWlzRGVmaW5lZChjdHgubGF5b3V0Tm9kZSgpLmRhdGFQb2ludGVyKSB8fFxyXG4gICAgICBjdHgubGF5b3V0Tm9kZSgpLnR5cGUgPT09ICckcmVmJ1xyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgY29uc3QgY29udHJvbCA9IGdldENvbnRyb2wodGhpcy5mb3JtR3JvdXAsIHRoaXMuZ2V0RGF0YVBvaW50ZXIoY3R4KSk7XHJcbiAgICByZXR1cm4gY29udHJvbCA/IGNvbnRyb2wudmFsdWUgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0Rm9ybUNvbnRyb2xHcm91cChjdHg6IFdpZGdldENvbnRleHQpOiBVbnR5cGVkRm9ybUFycmF5IHwgVW50eXBlZEZvcm1Hcm91cCB7XHJcbiAgICBpZiAoIWN0eCB8fCAhY3R4LmxheW91dE5vZGUgfHwgIWlzRGVmaW5lZChjdHgubGF5b3V0Tm9kZSgpLmRhdGFQb2ludGVyKSkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiBnZXRDb250cm9sKHRoaXMuZm9ybUdyb3VwLCB0aGlzLmdldERhdGFQb2ludGVyKGN0eCksIHRydWUpO1xyXG4gIH1cclxuXHJcbiAgZ2V0Rm9ybUNvbnRyb2xOYW1lKGN0eDogV2lkZ2V0Q29udGV4dCk6IHN0cmluZyB7XHJcbiAgICBpZiAoXHJcbiAgICAgICFjdHggfHwgIWN0eC5sYXlvdXROb2RlIHx8XHJcbiAgICAgICFpc0RlZmluZWQoY3R4LmxheW91dE5vZGUoKS5kYXRhUG9pbnRlcikgfHxcclxuICAgICAgIWhhc1ZhbHVlKGN0eC5kYXRhSW5kZXgoKSlcclxuICAgICkge1xyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIHJldHVybiBKc29uUG9pbnRlci50b0tleSh0aGlzLmdldERhdGFQb2ludGVyKGN0eCkpO1xyXG4gIH1cclxuXHJcbiAgZ2V0TGF5b3V0QXJyYXkoY3R4OiBXaWRnZXRDb250ZXh0KTogYW55W10ge1xyXG4gICAgcmV0dXJuIEpzb25Qb2ludGVyLmdldCh0aGlzLmxheW91dCwgdGhpcy5nZXRMYXlvdXRQb2ludGVyKGN0eCksIDAsIC0xKTtcclxuICB9XHJcblxyXG4gIGdldFBhcmVudE5vZGUoY3R4OiBXaWRnZXRDb250ZXh0KTogYW55IHtcclxuICAgIHJldHVybiBKc29uUG9pbnRlci5nZXQodGhpcy5sYXlvdXQsIHRoaXMuZ2V0TGF5b3V0UG9pbnRlcihjdHgpLCAwLCAtMik7XHJcbiAgfVxyXG5cclxuICBnZXREYXRhUG9pbnRlcihjdHg6IFdpZGdldENvbnRleHQpOiBzdHJpbmcge1xyXG4gICAgaWYgKFxyXG4gICAgICAhY3R4IHx8ICFjdHgubGF5b3V0Tm9kZSB8fFxyXG4gICAgICAhaXNEZWZpbmVkKGN0eC5sYXlvdXROb2RlKCkuZGF0YVBvaW50ZXIpIHx8XHJcbiAgICAgICFoYXNWYWx1ZShjdHguZGF0YUluZGV4KCkpXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gSnNvblBvaW50ZXIudG9JbmRleGVkUG9pbnRlcihcclxuICAgICAgY3R4LmxheW91dE5vZGUoKS5kYXRhUG9pbnRlcixcclxuICAgICAgY3R4LmRhdGFJbmRleCgpLFxyXG4gICAgICB0aGlzLmFycmF5TWFwXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgZ2V0TGF5b3V0UG9pbnRlcihjdHg6IFdpZGdldENvbnRleHQpOiBzdHJpbmcge1xyXG4gICAgaWYgKCFoYXNWYWx1ZShjdHgubGF5b3V0SW5kZXgoKSkpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJy8nICsgY3R4LmxheW91dEluZGV4KCkuam9pbignL2l0ZW1zLycpO1xyXG4gIH1cclxuXHJcbiAgaXNDb250cm9sQm91bmQoY3R4OiBXaWRnZXRDb250ZXh0KTogYm9vbGVhbiB7XHJcbiAgICBpZiAoXHJcbiAgICAgICFjdHggfHwgIWN0eC5sYXlvdXROb2RlIHx8XHJcbiAgICAgICFpc0RlZmluZWQoY3R4LmxheW91dE5vZGUoKS5kYXRhUG9pbnRlcikgfHxcclxuICAgICAgIWhhc1ZhbHVlKGN0eC5kYXRhSW5kZXgoKSlcclxuICAgICkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBjb25zdCBjb250cm9sR3JvdXAgPSB0aGlzLmdldEZvcm1Db250cm9sR3JvdXAoY3R4KTtcclxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmdldEZvcm1Db250cm9sTmFtZShjdHgpO1xyXG4gICAgcmV0dXJuIGNvbnRyb2xHcm91cCA/IGhhc093bihjb250cm9sR3JvdXAuY29udHJvbHMsIG5hbWUpIDogZmFsc2U7XHJcbiAgfVxyXG5cclxuICBhZGRJdGVtKGN0eDogV2lkZ2V0Q29udGV4dCwgbmFtZT86IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKFxyXG4gICAgICAhY3R4IHx8ICFjdHgubGF5b3V0Tm9kZSB8fFxyXG4gICAgICAhaXNEZWZpbmVkKGN0eC5sYXlvdXROb2RlKCkuJHJlZikgfHxcclxuICAgICAgIWhhc1ZhbHVlKGN0eC5kYXRhSW5kZXgoKSkgfHxcclxuICAgICAgIWhhc1ZhbHVlKGN0eC5sYXlvdXRJbmRleCgpKVxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDcmVhdGUgYSBuZXcgQW5ndWxhciBmb3JtIGNvbnRyb2wgZnJvbSBhIHRlbXBsYXRlIGluIHRlbXBsYXRlUmVmTGlicmFyeVxyXG4gICAgY29uc3QgbmV3Rm9ybUdyb3VwID0gYnVpbGRGb3JtR3JvdXAoXHJcbiAgICAgIHRoaXMudGVtcGxhdGVSZWZMaWJyYXJ5W2N0eC5sYXlvdXROb2RlKCkuJHJlZl1cclxuICAgICk7XHJcblxyXG4gICAgLy8gQWRkIHRoZSBuZXcgZm9ybSBjb250cm9sIHRvIHRoZSBwYXJlbnQgZm9ybUFycmF5IG9yIGZvcm1Hcm91cFxyXG4gICAgaWYgKGN0eC5sYXlvdXROb2RlKCkuYXJyYXlJdGVtKSB7XHJcbiAgICAgIC8vIEFkZCBuZXcgYXJyYXkgaXRlbSB0byBmb3JtQXJyYXlcclxuICAgICAgKDxVbnR5cGVkRm9ybUFycmF5PnRoaXMuZ2V0Rm9ybUNvbnRyb2xHcm91cChjdHgpKS5wdXNoKG5ld0Zvcm1Hcm91cCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBBZGQgbmV3ICRyZWYgaXRlbSB0byBmb3JtR3JvdXBcclxuICAgICAgKDxVbnR5cGVkRm9ybUdyb3VwPnRoaXMuZ2V0Rm9ybUNvbnRyb2xHcm91cChjdHgpKS5hZGRDb250cm9sKFxyXG4gICAgICAgIG5hbWUgfHwgdGhpcy5nZXRGb3JtQ29udHJvbE5hbWUoY3R4KSxcclxuICAgICAgICBuZXdGb3JtR3JvdXBcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDb3B5IGEgbmV3IGxheW91dE5vZGUgZnJvbSBsYXlvdXRSZWZMaWJyYXJ5XHJcbiAgICBjb25zdCBuZXdMYXlvdXROb2RlID0gZ2V0TGF5b3V0Tm9kZShjdHgubGF5b3V0Tm9kZSgpLCB0aGlzKTtcclxuICAgIG5ld0xheW91dE5vZGUuYXJyYXlJdGVtID0gY3R4LmxheW91dE5vZGUoKS5hcnJheUl0ZW07XHJcbiAgICBpZiAoY3R4LmxheW91dE5vZGUoKS5hcnJheUl0ZW1UeXBlKSB7XHJcbiAgICAgIG5ld0xheW91dE5vZGUuYXJyYXlJdGVtVHlwZSA9IGN0eC5sYXlvdXROb2RlKCkuYXJyYXlJdGVtVHlwZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGRlbGV0ZSBuZXdMYXlvdXROb2RlLmFycmF5SXRlbVR5cGU7XHJcbiAgICB9XHJcbiAgICBpZiAobmFtZSkge1xyXG4gICAgICBuZXdMYXlvdXROb2RlLm5hbWUgPSBuYW1lO1xyXG4gICAgICBuZXdMYXlvdXROb2RlLmRhdGFQb2ludGVyICs9ICcvJyArIEpzb25Qb2ludGVyLmVzY2FwZShuYW1lKTtcclxuICAgICAgbmV3TGF5b3V0Tm9kZS5vcHRpb25zLnRpdGxlID0gZml4VGl0bGUobmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWRkIHRoZSBuZXcgbGF5b3V0Tm9kZSB0byB0aGUgZm9ybSBsYXlvdXRcclxuICAgIEpzb25Qb2ludGVyLmluc2VydCh0aGlzLmxheW91dCwgdGhpcy5nZXRMYXlvdXRQb2ludGVyKGN0eCksIG5ld0xheW91dE5vZGUpO1xyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgbW92ZUFycmF5SXRlbShjdHg6IFdpZGdldENvbnRleHQsIG9sZEluZGV4OiBudW1iZXIsIG5ld0luZGV4OiBudW1iZXIpOiBib29sZWFuIHtcclxuICAgIGlmIChcclxuICAgICAgIWN0eCB8fCAhY3R4LmxheW91dE5vZGUgfHxcclxuICAgICAgIWlzRGVmaW5lZChjdHgubGF5b3V0Tm9kZSgpLmRhdGFQb2ludGVyKSB8fFxyXG4gICAgICAhaGFzVmFsdWUoY3R4LmRhdGFJbmRleCgpKSB8fFxyXG4gICAgICAhaGFzVmFsdWUoY3R4LmxheW91dEluZGV4KCkpIHx8XHJcbiAgICAgICFpc0RlZmluZWQob2xkSW5kZXgpIHx8XHJcbiAgICAgICFpc0RlZmluZWQobmV3SW5kZXgpIHx8XHJcbiAgICAgIG9sZEluZGV4ID09PSBuZXdJbmRleFxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBNb3ZlIGl0ZW0gaW4gdGhlIGZvcm1BcnJheVxyXG4gICAgY29uc3QgZm9ybUFycmF5ID0gPFVudHlwZWRGb3JtQXJyYXk+dGhpcy5nZXRGb3JtQ29udHJvbEdyb3VwKGN0eCk7XHJcbiAgICBjb25zdCBhcnJheUl0ZW0gPSBmb3JtQXJyYXkuYXQob2xkSW5kZXgpO1xyXG4gICAgZm9ybUFycmF5LnJlbW92ZUF0KG9sZEluZGV4KTtcclxuICAgIGZvcm1BcnJheS5pbnNlcnQobmV3SW5kZXgsIGFycmF5SXRlbSk7XHJcbiAgICBmb3JtQXJyYXkudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG5cclxuICAgIC8vIE1vdmUgbGF5b3V0IGl0ZW1cclxuICAgIGNvbnN0IGxheW91dEFycmF5ID0gdGhpcy5nZXRMYXlvdXRBcnJheShjdHgpO1xyXG4gICAgbGF5b3V0QXJyYXkuc3BsaWNlKG5ld0luZGV4LCAwLCBsYXlvdXRBcnJheS5zcGxpY2Uob2xkSW5kZXgsIDEpWzBdKTtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgcmVtb3ZlSXRlbShjdHg6IFdpZGdldENvbnRleHQpOiBib29sZWFuIHtcclxuICAgIGlmIChcclxuICAgICAgIWN0eCB8fCAhY3R4LmxheW91dE5vZGUgfHxcclxuICAgICAgIWlzRGVmaW5lZChjdHgubGF5b3V0Tm9kZSgpLmRhdGFQb2ludGVyKSB8fFxyXG4gICAgICAhaGFzVmFsdWUoY3R4LmRhdGFJbmRleCgpKSB8fFxyXG4gICAgICAhaGFzVmFsdWUoY3R4LmxheW91dEluZGV4KCkpXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJlbW92ZSB0aGUgQW5ndWxhciBmb3JtIGNvbnRyb2wgZnJvbSB0aGUgcGFyZW50IGZvcm1BcnJheSBvciBmb3JtR3JvdXBcclxuICAgIGlmIChjdHgubGF5b3V0Tm9kZSgpLmFycmF5SXRlbSkge1xyXG4gICAgICAvLyBSZW1vdmUgYXJyYXkgaXRlbSBmcm9tIGZvcm1BcnJheVxyXG4gICAgICAoPFVudHlwZWRGb3JtQXJyYXk+dGhpcy5nZXRGb3JtQ29udHJvbEdyb3VwKGN0eCkpLnJlbW92ZUF0KFxyXG4gICAgICAgIGN0eC5kYXRhSW5kZXgoKVtjdHguZGF0YUluZGV4KCkubGVuZ3RoIC0gMV1cclxuICAgICAgKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIFJlbW92ZSAkcmVmIGl0ZW0gZnJvbSBmb3JtR3JvdXBcclxuICAgICAgKDxVbnR5cGVkRm9ybUdyb3VwPnRoaXMuZ2V0Rm9ybUNvbnRyb2xHcm91cChjdHgpKS5yZW1vdmVDb250cm9sKFxyXG4gICAgICAgIHRoaXMuZ2V0Rm9ybUNvbnRyb2xOYW1lKGN0eClcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZW1vdmUgbGF5b3V0Tm9kZSBmcm9tIGxheW91dFxyXG4gICAgSnNvblBvaW50ZXIucmVtb3ZlKHRoaXMubGF5b3V0LCB0aGlzLmdldExheW91dFBvaW50ZXIoY3R4KSk7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcbn1cclxuIl19
|