@ng-formworks/core 17.2.7 → 17.4.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.
Files changed (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +836 -0
  3. package/esm2022/lib/framework-library/framework-library.service.mjs +175 -0
  4. package/esm2022/lib/framework-library/framework.mjs +15 -0
  5. package/esm2022/lib/framework-library/no-framework.component.mjs +18 -0
  6. package/esm2022/lib/framework-library/no-framework.module.mjs +27 -0
  7. package/esm2022/lib/framework-library/no.framework.mjs +19 -0
  8. package/esm2022/lib/json-schema-form.component.mjs +765 -0
  9. package/esm2022/lib/json-schema-form.module.mjs +26 -0
  10. package/esm2022/lib/json-schema-form.service.mjs +679 -0
  11. package/esm2022/lib/locale/de-validation-messages.mjs +60 -0
  12. package/esm2022/lib/locale/en-validation-messages.mjs +60 -0
  13. package/esm2022/lib/locale/es-validation-messages.mjs +57 -0
  14. package/esm2022/lib/locale/fr-validation-messages.mjs +60 -0
  15. package/esm2022/lib/locale/index.mjs +8 -0
  16. package/esm2022/lib/locale/it-validation-messages.mjs +60 -0
  17. package/esm2022/lib/locale/pt-validation-messages.mjs +60 -0
  18. package/esm2022/lib/locale/zh-validation-messages.mjs +60 -0
  19. package/esm2022/lib/shared/convert-schema-to-draft6.function.mjs +300 -0
  20. package/esm2022/lib/shared/form-group.functions.mjs +442 -0
  21. package/esm2022/lib/shared/format-regex.constants.mjs +54 -0
  22. package/esm2022/lib/shared/index.mjs +12 -0
  23. package/esm2022/lib/shared/json-schema.functions.mjs +784 -0
  24. package/esm2022/lib/shared/json.validators.mjs +884 -0
  25. package/esm2022/lib/shared/jsonpointer.functions.mjs +1026 -0
  26. package/esm2022/lib/shared/layout.functions.mjs +1154 -0
  27. package/esm2022/lib/shared/merge-schemas.function.mjs +345 -0
  28. package/esm2022/lib/shared/utility.functions.mjs +380 -0
  29. package/esm2022/lib/shared/validator.functions.mjs +584 -0
  30. package/esm2022/lib/widget-library/add-reference.component.mjs +61 -0
  31. package/esm2022/lib/widget-library/button.component.mjs +72 -0
  32. package/esm2022/lib/widget-library/checkbox.component.mjs +105 -0
  33. package/esm2022/lib/widget-library/checkboxes.component.mjs +147 -0
  34. package/esm2022/lib/widget-library/file.component.mjs +35 -0
  35. package/esm2022/lib/widget-library/hidden.component.mjs +54 -0
  36. package/esm2022/lib/widget-library/index.mjs +55 -0
  37. package/esm2022/lib/widget-library/input.component.mjs +119 -0
  38. package/esm2022/lib/widget-library/message.component.mjs +38 -0
  39. package/esm2022/lib/widget-library/none.component.mjs +21 -0
  40. package/esm2022/lib/widget-library/number.component.mjs +123 -0
  41. package/esm2022/lib/widget-library/one-of.component.mjs +35 -0
  42. package/esm2022/lib/widget-library/orderable.directive.mjs +123 -0
  43. package/esm2022/lib/widget-library/radios.component.mjs +153 -0
  44. package/esm2022/lib/widget-library/root.component.mjs +79 -0
  45. package/esm2022/lib/widget-library/section.component.mjs +199 -0
  46. package/esm2022/lib/widget-library/select-framework.component.mjs +51 -0
  47. package/esm2022/lib/widget-library/select-widget.component.mjs +46 -0
  48. package/esm2022/lib/widget-library/select.component.mjs +150 -0
  49. package/esm2022/lib/widget-library/submit.component.mjs +82 -0
  50. package/esm2022/lib/widget-library/tab.component.mjs +41 -0
  51. package/esm2022/lib/widget-library/tabs.component.mjs +108 -0
  52. package/esm2022/lib/widget-library/template.component.mjs +46 -0
  53. package/esm2022/lib/widget-library/textarea.component.mjs +104 -0
  54. package/esm2022/lib/widget-library/widget-library.module.mjs +42 -0
  55. package/esm2022/lib/widget-library/widget-library.service.mjs +226 -0
  56. package/esm2022/ng-formworks-core.mjs +5 -0
  57. package/esm2022/public_api.mjs +13 -0
  58. package/fesm2022/ng-formworks-core.mjs +10149 -0
  59. package/fesm2022/ng-formworks-core.mjs.map +1 -0
  60. package/index.d.ts +5 -0
  61. package/lib/framework-library/framework-library.service.d.ts +55 -0
  62. package/lib/framework-library/framework.d.ts +13 -0
  63. package/lib/framework-library/no-framework.component.d.ts +8 -0
  64. package/lib/framework-library/no-framework.module.d.ts +9 -0
  65. package/lib/framework-library/no.framework.d.ts +10 -0
  66. package/lib/json-schema-form.component.d.ts +218 -0
  67. package/lib/json-schema-form.module.d.ts +11 -0
  68. package/lib/json-schema-form.service.d.ts +115 -0
  69. package/lib/locale/de-validation-messages.d.ts +1 -0
  70. package/lib/locale/en-validation-messages.d.ts +1 -0
  71. package/lib/locale/es-validation-messages.d.ts +1 -0
  72. package/lib/locale/fr-validation-messages.d.ts +1 -0
  73. package/{src/lib/locale/index.ts → lib/locale/index.d.ts} +7 -7
  74. package/lib/locale/it-validation-messages.d.ts +1 -0
  75. package/lib/locale/pt-validation-messages.d.ts +1 -0
  76. package/lib/locale/zh-validation-messages.d.ts +1 -0
  77. package/lib/shared/convert-schema-to-draft6.function.d.ts +21 -0
  78. package/lib/shared/form-group.functions.d.ts +100 -0
  79. package/lib/shared/format-regex.constants.d.ts +19 -0
  80. package/lib/shared/index.d.ts +9 -0
  81. package/lib/shared/json-schema.functions.d.ts +193 -0
  82. package/lib/shared/json.validators.d.ts +441 -0
  83. package/lib/shared/jsonpointer.functions.d.ts +416 -0
  84. package/lib/shared/layout.functions.d.ts +83 -0
  85. package/lib/shared/merge-schemas.function.d.ts +19 -0
  86. package/lib/shared/utility.functions.d.ts +165 -0
  87. package/{src/lib/shared/validator.functions.ts → lib/shared/validator.functions.d.ts} +364 -601
  88. package/lib/widget-library/add-reference.component.d.ts +20 -0
  89. package/lib/widget-library/button.component.d.ts +21 -0
  90. package/lib/widget-library/checkbox.component.d.ts +24 -0
  91. package/lib/widget-library/checkboxes.component.d.ts +24 -0
  92. package/lib/widget-library/file.component.d.ts +21 -0
  93. package/lib/widget-library/hidden.component.d.ts +19 -0
  94. package/{src/lib/widget-library/index.ts → lib/widget-library/index.d.ts} +47 -56
  95. package/lib/widget-library/input.component.d.ts +22 -0
  96. package/lib/widget-library/message.component.d.ts +15 -0
  97. package/lib/widget-library/none.component.d.ts +8 -0
  98. package/lib/widget-library/number.component.d.ts +25 -0
  99. package/lib/widget-library/one-of.component.d.ts +21 -0
  100. package/lib/widget-library/orderable.directive.d.ts +41 -0
  101. package/lib/widget-library/radios.component.d.ts +23 -0
  102. package/lib/widget-library/root.component.d.ts +17 -0
  103. package/lib/widget-library/section.component.d.ts +19 -0
  104. package/lib/widget-library/select-framework.component.d.ts +18 -0
  105. package/lib/widget-library/select-widget.component.d.ts +18 -0
  106. package/lib/widget-library/select.component.d.ts +24 -0
  107. package/lib/widget-library/submit.component.d.ts +24 -0
  108. package/lib/widget-library/tab.component.d.ts +14 -0
  109. package/lib/widget-library/tabs.component.d.ts +20 -0
  110. package/lib/widget-library/template.component.d.ts +18 -0
  111. package/lib/widget-library/textarea.component.d.ts +21 -0
  112. package/lib/widget-library/widget-library.module.d.ts +31 -0
  113. package/lib/widget-library/widget-library.service.d.ts +22 -0
  114. package/package.json +64 -53
  115. package/{src/public_api.ts → public_api.d.ts} +9 -21
  116. package/karma.conf.js +0 -46
  117. package/ng-package.json +0 -11
  118. package/src/lib/framework-library/framework-library.service.ts +0 -195
  119. package/src/lib/framework-library/framework.ts +0 -11
  120. package/src/lib/framework-library/no-framework.component.html +0 -2
  121. package/src/lib/framework-library/no-framework.component.ts +0 -11
  122. package/src/lib/framework-library/no-framework.module.ts +0 -18
  123. package/src/lib/framework-library/no.framework.ts +0 -11
  124. package/src/lib/json-schema-form.component.html +0 -7
  125. package/src/lib/json-schema-form.component.ts +0 -809
  126. package/src/lib/json-schema-form.module.ts +0 -17
  127. package/src/lib/json-schema-form.service.ts +0 -907
  128. package/src/lib/locale/de-validation-messages.ts +0 -58
  129. package/src/lib/locale/en-validation-messages.ts +0 -58
  130. package/src/lib/locale/es-validation-messages.ts +0 -55
  131. package/src/lib/locale/fr-validation-messages.ts +0 -58
  132. package/src/lib/locale/it-validation-messages.ts +0 -58
  133. package/src/lib/locale/pt-validation-messages.ts +0 -58
  134. package/src/lib/locale/zh-validation-messages.ts +0 -58
  135. package/src/lib/locale-dates/en-US.ts +0 -5
  136. package/src/lib/shared/convert-schema-to-draft6.function.ts +0 -321
  137. package/src/lib/shared/form-group.functions.ts +0 -522
  138. package/src/lib/shared/format-regex.constants.ts +0 -73
  139. package/src/lib/shared/index.ts +0 -40
  140. package/src/lib/shared/json-schema.functions.ts +0 -788
  141. package/src/lib/shared/json.validators.ts +0 -878
  142. package/src/lib/shared/jsonpointer.functions.ts +0 -1012
  143. package/src/lib/shared/jspointer.functions.json.spec.ts +0 -103
  144. package/src/lib/shared/layout.functions.ts +0 -1233
  145. package/src/lib/shared/merge-schemas.function.ts +0 -329
  146. package/src/lib/shared/utility.functions.ts +0 -373
  147. package/src/lib/shared/validator.functions.spec.ts +0 -55
  148. package/src/lib/widget-library/add-reference.component.ts +0 -59
  149. package/src/lib/widget-library/button.component.ts +0 -54
  150. package/src/lib/widget-library/checkbox.component.ts +0 -74
  151. package/src/lib/widget-library/checkboxes.component.ts +0 -104
  152. package/src/lib/widget-library/file.component.ts +0 -36
  153. package/src/lib/widget-library/hidden.component.ts +0 -39
  154. package/src/lib/widget-library/input.component.ts +0 -76
  155. package/src/lib/widget-library/message.component.ts +0 -29
  156. package/src/lib/widget-library/none.component.ts +0 -12
  157. package/src/lib/widget-library/number.component.ts +0 -79
  158. package/src/lib/widget-library/one-of.component.ts +0 -36
  159. package/src/lib/widget-library/orderable.directive.ts +0 -130
  160. package/src/lib/widget-library/radios.component.ts +0 -101
  161. package/src/lib/widget-library/root.component.ts +0 -78
  162. package/src/lib/widget-library/section.component.ts +0 -133
  163. package/src/lib/widget-library/select-framework.component.ts +0 -50
  164. package/src/lib/widget-library/select-widget.component.ts +0 -46
  165. package/src/lib/widget-library/select.component.ts +0 -96
  166. package/src/lib/widget-library/submit.component.ts +0 -68
  167. package/src/lib/widget-library/tab.component.ts +0 -29
  168. package/src/lib/widget-library/tabs.component.ts +0 -83
  169. package/src/lib/widget-library/template.component.ts +0 -52
  170. package/src/lib/widget-library/textarea.component.ts +0 -68
  171. package/src/lib/widget-library/widget-library.module.ts +0 -13
  172. package/src/lib/widget-library/widget-library.service.ts +0 -234
  173. package/src/test.ts +0 -18
  174. package/tsconfig.lib.json +0 -25
  175. package/tsconfig.lib.prod.json +0 -9
  176. package/tsconfig.spec.json +0 -17
  177. package/tslint.json +0 -11
@@ -0,0 +1,784 @@
1
+ import cloneDeep from 'lodash/cloneDeep';
2
+ import { JsonPointer } from './jsonpointer.functions';
3
+ import { mergeSchemas } from './merge-schemas.function';
4
+ import { forEach, hasOwn, mergeFilteredObject } from './utility.functions';
5
+ import { getType, hasValue, inArray, isArray, isNumber, isObject, isString } from './validator.functions';
6
+ /**
7
+ * JSON Schema function library:
8
+ *
9
+ * buildSchemaFromLayout: TODO: Write this function
10
+ *
11
+ * buildSchemaFromData:
12
+ *
13
+ * getFromSchema:
14
+ *
15
+ * removeRecursiveReferences:
16
+ *
17
+ * getInputType:
18
+ *
19
+ * checkInlineType:
20
+ *
21
+ * isInputRequired:
22
+ *
23
+ * updateInputOptions:
24
+ *
25
+ * getTitleMapFromOneOf:
26
+ *
27
+ * getControlValidators:
28
+ *
29
+ * resolveSchemaReferences:
30
+ *
31
+ * getSubSchema:
32
+ *
33
+ * combineAllOf:
34
+ *
35
+ * fixRequiredArrayProperties:
36
+ */
37
+ /**
38
+ * 'buildSchemaFromLayout' function
39
+ *
40
+ * TODO: Build a JSON Schema from a JSON Form layout
41
+ *
42
+ * // layout - The JSON Form layout
43
+ * // - The new JSON Schema
44
+ */
45
+ export function buildSchemaFromLayout(layout) {
46
+ return;
47
+ // let newSchema: any = { };
48
+ // const walkLayout = (layoutItems: any[], callback: Function): any[] => {
49
+ // let returnArray: any[] = [];
50
+ // for (let layoutItem of layoutItems) {
51
+ // const returnItem: any = callback(layoutItem);
52
+ // if (returnItem) { returnArray = returnArray.concat(callback(layoutItem)); }
53
+ // if (layoutItem.items) {
54
+ // returnArray = returnArray.concat(walkLayout(layoutItem.items, callback));
55
+ // }
56
+ // }
57
+ // return returnArray;
58
+ // };
59
+ // walkLayout(layout, layoutItem => {
60
+ // let itemKey: string;
61
+ // if (typeof layoutItem === 'string') {
62
+ // itemKey = layoutItem;
63
+ // } else if (layoutItem.key) {
64
+ // itemKey = layoutItem.key;
65
+ // }
66
+ // if (!itemKey) { return; }
67
+ // //
68
+ // });
69
+ }
70
+ /**
71
+ * 'buildSchemaFromData' function
72
+ *
73
+ * Build a JSON Schema from a data object
74
+ *
75
+ * // data - The data object
76
+ * // { boolean = false } requireAllFields - Require all fields?
77
+ * // { boolean = true } isRoot - is root
78
+ * // - The new JSON Schema
79
+ */
80
+ export function buildSchemaFromData(data, requireAllFields = false, isRoot = true) {
81
+ const newSchema = {};
82
+ const getFieldType = (value) => {
83
+ const fieldType = getType(value, 'strict');
84
+ return { integer: 'number', null: 'string' }[fieldType] || fieldType;
85
+ };
86
+ const buildSubSchema = (value) => buildSchemaFromData(value, requireAllFields, false);
87
+ if (isRoot) {
88
+ newSchema.$schema = 'http://json-schema.org/draft-06/schema#';
89
+ }
90
+ newSchema.type = getFieldType(data);
91
+ if (newSchema.type === 'object') {
92
+ newSchema.properties = {};
93
+ if (requireAllFields) {
94
+ newSchema.required = [];
95
+ }
96
+ for (const key of Object.keys(data)) {
97
+ newSchema.properties[key] = buildSubSchema(data[key]);
98
+ if (requireAllFields) {
99
+ newSchema.required.push(key);
100
+ }
101
+ }
102
+ }
103
+ else if (newSchema.type === 'array') {
104
+ newSchema.items = data.map(buildSubSchema);
105
+ // If all items are the same type, use an object for items instead of an array
106
+ if ((new Set(data.map(getFieldType))).size === 1) {
107
+ newSchema.items = newSchema.items.reduce((a, b) => ({ ...a, ...b }), {});
108
+ }
109
+ if (requireAllFields) {
110
+ newSchema.minItems = 1;
111
+ }
112
+ }
113
+ return newSchema;
114
+ }
115
+ /**
116
+ * 'getFromSchema' function
117
+ *
118
+ * Uses a JSON Pointer for a value within a data object to retrieve
119
+ * the schema for that value within schema for the data object.
120
+ *
121
+ * The optional third parameter can also be set to return something else:
122
+ * 'schema' (default): the schema for the value indicated by the data pointer
123
+ * 'parentSchema': the schema for the value's parent object or array
124
+ * 'schemaPointer': a pointer to the value's schema within the object's schema
125
+ * 'parentSchemaPointer': a pointer to the schema for the value's parent object or array
126
+ *
127
+ * // schema - The schema to get the sub-schema from
128
+ * // { Pointer } dataPointer - JSON Pointer (string or array)
129
+ * // { string = 'schema' } returnType - what to return?
130
+ * // - The located sub-schema
131
+ */
132
+ export function getFromSchema(schema, dataPointer, returnType = 'schema') {
133
+ const dataPointerArray = JsonPointer.parse(dataPointer);
134
+ if (dataPointerArray === null) {
135
+ console.error(`getFromSchema error: Invalid JSON Pointer: ${dataPointer}`);
136
+ return null;
137
+ }
138
+ let subSchema = schema;
139
+ const schemaPointer = [];
140
+ const length = dataPointerArray.length;
141
+ if (returnType.slice(0, 6) === 'parent') {
142
+ dataPointerArray.length--;
143
+ }
144
+ for (let i = 0; i < length; ++i) {
145
+ const parentSchema = subSchema;
146
+ const key = dataPointerArray[i];
147
+ let subSchemaFound = false;
148
+ if (typeof subSchema !== 'object') {
149
+ console.error(`getFromSchema error: Unable to find "${key}" key in schema.`);
150
+ console.error(schema);
151
+ console.error(dataPointer);
152
+ return null;
153
+ }
154
+ if (subSchema.type === 'array' && (!isNaN(key) || key === '-')) {
155
+ if (hasOwn(subSchema, 'items')) {
156
+ if (isObject(subSchema.items)) {
157
+ subSchemaFound = true;
158
+ subSchema = subSchema.items;
159
+ schemaPointer.push('items');
160
+ }
161
+ else if (isArray(subSchema.items)) {
162
+ if (!isNaN(key) && subSchema.items.length >= +key) {
163
+ subSchemaFound = true;
164
+ subSchema = subSchema.items[+key];
165
+ schemaPointer.push('items', key);
166
+ }
167
+ }
168
+ }
169
+ if (!subSchemaFound && isObject(subSchema.additionalItems)) {
170
+ subSchemaFound = true;
171
+ subSchema = subSchema.additionalItems;
172
+ schemaPointer.push('additionalItems');
173
+ }
174
+ else if (subSchema.additionalItems !== false) {
175
+ subSchemaFound = true;
176
+ subSchema = {};
177
+ schemaPointer.push('additionalItems');
178
+ }
179
+ }
180
+ else if (subSchema.type === 'object') {
181
+ if (isObject(subSchema.properties) && hasOwn(subSchema.properties, key)) {
182
+ subSchemaFound = true;
183
+ subSchema = subSchema.properties[key];
184
+ schemaPointer.push('properties', key);
185
+ }
186
+ else if (isObject(subSchema.additionalProperties)) {
187
+ subSchemaFound = true;
188
+ subSchema = subSchema.additionalProperties;
189
+ schemaPointer.push('additionalProperties');
190
+ }
191
+ else if (subSchema.additionalProperties !== false) {
192
+ subSchemaFound = true;
193
+ subSchema = {};
194
+ schemaPointer.push('additionalProperties');
195
+ }
196
+ }
197
+ if (!subSchemaFound) {
198
+ console.error(`getFromSchema error: Unable to find "${key}" item in schema.`);
199
+ console.error(schema);
200
+ console.error(dataPointer);
201
+ return;
202
+ }
203
+ }
204
+ return returnType.slice(-7) === 'Pointer' ? schemaPointer : subSchema;
205
+ }
206
+ /**
207
+ * 'removeRecursiveReferences' function
208
+ *
209
+ * Checks a JSON Pointer against a map of recursive references and returns
210
+ * a JSON Pointer to the shallowest equivalent location in the same object.
211
+ *
212
+ * Using this functions enables an object to be constructed with unlimited
213
+ * recursion, while maintaing a fixed set of metadata, such as field data types.
214
+ * The object can grow as large as it wants, and deeply recursed nodes can
215
+ * just refer to the metadata for their shallow equivalents, instead of having
216
+ * to add additional redundant metadata for each recursively added node.
217
+ *
218
+ * Example:
219
+ *
220
+ * pointer: '/stuff/and/more/and/more/and/more/and/more/stuff'
221
+ * recursiveRefMap: [['/stuff/and/more/and/more', '/stuff/and/more/']]
222
+ * returned: '/stuff/and/more/stuff'
223
+ *
224
+ * // { Pointer } pointer -
225
+ * // { Map<string, string> } recursiveRefMap -
226
+ * // { Map<string, number> = new Map() } arrayMap - optional
227
+ * // { string } -
228
+ */
229
+ export function removeRecursiveReferences(pointer, recursiveRefMap, arrayMap = new Map()) {
230
+ if (!pointer) {
231
+ return '';
232
+ }
233
+ let genericPointer = JsonPointer.toGenericPointer(JsonPointer.compile(pointer), arrayMap);
234
+ if (genericPointer.indexOf('/') === -1) {
235
+ return genericPointer;
236
+ }
237
+ let possibleReferences = true;
238
+ while (possibleReferences) {
239
+ possibleReferences = false;
240
+ recursiveRefMap.forEach((toPointer, fromPointer) => {
241
+ if (JsonPointer.isSubPointer(toPointer, fromPointer)) {
242
+ while (JsonPointer.isSubPointer(fromPointer, genericPointer, true)) {
243
+ genericPointer = JsonPointer.toGenericPointer(toPointer + genericPointer.slice(fromPointer.length), arrayMap);
244
+ possibleReferences = true;
245
+ }
246
+ }
247
+ });
248
+ }
249
+ return genericPointer;
250
+ }
251
+ /**
252
+ * 'getInputType' function
253
+ *
254
+ * // schema
255
+ * // { any = null } layoutNode
256
+ * // { string }
257
+ */
258
+ export function getInputType(schema, layoutNode = null) {
259
+ // x-schema-form = Angular Schema Form compatibility
260
+ // widget & component = React Jsonschema Form compatibility
261
+ const controlType = JsonPointer.getFirst([
262
+ [schema, '/x-schema-form/type'],
263
+ [schema, '/x-schema-form/widget/component'],
264
+ [schema, '/x-schema-form/widget'],
265
+ [schema, '/widget/component'],
266
+ [schema, '/widget']
267
+ ]);
268
+ if (isString(controlType)) {
269
+ return checkInlineType(controlType, schema, layoutNode);
270
+ }
271
+ let schemaType = schema.type;
272
+ if (schemaType) {
273
+ if (isArray(schemaType)) { // If multiple types listed, use most inclusive type
274
+ schemaType =
275
+ inArray('object', schemaType) && hasOwn(schema, 'properties') ? 'object' :
276
+ inArray('array', schemaType) && hasOwn(schema, 'items') ? 'array' :
277
+ inArray('array', schemaType) && hasOwn(schema, 'additionalItems') ? 'array' :
278
+ inArray('string', schemaType) ? 'string' :
279
+ inArray('number', schemaType) ? 'number' :
280
+ inArray('integer', schemaType) ? 'integer' :
281
+ inArray('boolean', schemaType) ? 'boolean' : 'unknown';
282
+ }
283
+ if (schemaType === 'boolean') {
284
+ return 'checkbox';
285
+ }
286
+ if (schemaType === 'object') {
287
+ if (hasOwn(schema, 'properties') || hasOwn(schema, 'additionalProperties')) {
288
+ return 'section';
289
+ }
290
+ // TODO: Figure out how to handle additionalProperties
291
+ if (hasOwn(schema, '$ref')) {
292
+ return '$ref';
293
+ }
294
+ }
295
+ if (schemaType === 'array') {
296
+ const itemsObject = JsonPointer.getFirst([
297
+ [schema, '/items'],
298
+ [schema, '/additionalItems']
299
+ ]) || {};
300
+ return hasOwn(itemsObject, 'enum') && schema.maxItems !== 1 ?
301
+ checkInlineType('checkboxes', schema, layoutNode) : 'array';
302
+ }
303
+ if (schemaType === 'null') {
304
+ return 'none';
305
+ }
306
+ if (JsonPointer.has(layoutNode, '/options/titleMap') ||
307
+ hasOwn(schema, 'enum') || getTitleMapFromOneOf(schema, null, true)) {
308
+ return 'select';
309
+ }
310
+ if (schemaType === 'number' || schemaType === 'integer') {
311
+ return (schemaType === 'integer' || hasOwn(schema, 'multipleOf')) &&
312
+ hasOwn(schema, 'maximum') && hasOwn(schema, 'minimum') ? 'range' : schemaType;
313
+ }
314
+ if (schemaType === 'string') {
315
+ return {
316
+ 'color': 'color',
317
+ 'date': 'date',
318
+ 'date-time': 'datetime-local',
319
+ 'email': 'email',
320
+ 'uri': 'url',
321
+ }[schema.format] || 'text';
322
+ }
323
+ }
324
+ if (hasOwn(schema, '$ref')) {
325
+ return '$ref';
326
+ }
327
+ if (isArray(schema.oneOf) || isArray(schema.anyOf)) {
328
+ return 'one-of';
329
+ }
330
+ console.error(`getInputType error: Unable to determine input type for ${schemaType}`);
331
+ console.error('schema', schema);
332
+ if (layoutNode) {
333
+ console.error('layoutNode', layoutNode);
334
+ }
335
+ return 'none';
336
+ }
337
+ /**
338
+ * 'checkInlineType' function
339
+ *
340
+ * Checks layout and schema nodes for 'inline: true', and converts
341
+ * 'radios' or 'checkboxes' to 'radios-inline' or 'checkboxes-inline'
342
+ *
343
+ * // { string } controlType -
344
+ * // schema -
345
+ * // { any = null } layoutNode -
346
+ * // { string }
347
+ */
348
+ export function checkInlineType(controlType, schema, layoutNode = null) {
349
+ if (!isString(controlType) || (controlType.slice(0, 8) !== 'checkbox' && controlType.slice(0, 5) !== 'radio')) {
350
+ return controlType;
351
+ }
352
+ if (JsonPointer.getFirst([
353
+ [layoutNode, '/inline'],
354
+ [layoutNode, '/options/inline'],
355
+ [schema, '/inline'],
356
+ [schema, '/x-schema-form/inline'],
357
+ [schema, '/x-schema-form/options/inline'],
358
+ [schema, '/x-schema-form/widget/inline'],
359
+ [schema, '/x-schema-form/widget/component/inline'],
360
+ [schema, '/x-schema-form/widget/component/options/inline'],
361
+ [schema, '/widget/inline'],
362
+ [schema, '/widget/component/inline'],
363
+ [schema, '/widget/component/options/inline'],
364
+ ]) === true) {
365
+ return controlType.slice(0, 5) === 'radio' ?
366
+ 'radios-inline' : 'checkboxes-inline';
367
+ }
368
+ else {
369
+ return controlType;
370
+ }
371
+ }
372
+ /**
373
+ * 'isInputRequired' function
374
+ *
375
+ * Checks a JSON Schema to see if an item is required
376
+ *
377
+ * // schema - the schema to check
378
+ * // { string } schemaPointer - the pointer to the item to check
379
+ * // { boolean } - true if the item is required, false if not
380
+ */
381
+ export function isInputRequired(schema, schemaPointer) {
382
+ if (!isObject(schema)) {
383
+ console.error('isInputRequired error: Input schema must be an object.');
384
+ return false;
385
+ }
386
+ const listPointerArray = JsonPointer.parse(schemaPointer);
387
+ if (isArray(listPointerArray)) {
388
+ if (!listPointerArray.length) {
389
+ return schema.required === true;
390
+ }
391
+ const keyName = listPointerArray.pop();
392
+ const nextToLastKey = listPointerArray[listPointerArray.length - 1];
393
+ if (['properties', 'additionalProperties', 'patternProperties', 'items', 'additionalItems']
394
+ .includes(nextToLastKey)) {
395
+ listPointerArray.pop();
396
+ }
397
+ const parentSchema = JsonPointer.get(schema, listPointerArray) || {};
398
+ if (isArray(parentSchema.required)) {
399
+ return parentSchema.required.includes(keyName);
400
+ }
401
+ if (parentSchema.type === 'array') {
402
+ return hasOwn(parentSchema, 'minItems') &&
403
+ isNumber(keyName) &&
404
+ +parentSchema.minItems > +keyName;
405
+ }
406
+ }
407
+ return false;
408
+ }
409
+ /**
410
+ * 'updateInputOptions' function
411
+ *
412
+ * // layoutNode
413
+ * // schema
414
+ * // jsf
415
+ * // { void }
416
+ */
417
+ export function updateInputOptions(layoutNode, schema, jsf) {
418
+ if (!isObject(layoutNode) || !isObject(layoutNode.options)) {
419
+ return;
420
+ }
421
+ // Set all option values in layoutNode.options
422
+ const newOptions = {};
423
+ const fixUiKeys = key => key.slice(0, 3).toLowerCase() === 'ui:' ? key.slice(3) : key;
424
+ mergeFilteredObject(newOptions, jsf.formOptions.defaultWidgetOptions, [], fixUiKeys);
425
+ [[JsonPointer.get(schema, '/ui:widget/options'), []],
426
+ [JsonPointer.get(schema, '/ui:widget'), []],
427
+ [schema, [
428
+ 'additionalProperties', 'additionalItems', 'properties', 'items',
429
+ 'required', 'type', 'x-schema-form', '$ref'
430
+ ]],
431
+ [JsonPointer.get(schema, '/x-schema-form/options'), []],
432
+ [JsonPointer.get(schema, '/x-schema-form'), ['items', 'options']],
433
+ [layoutNode, [
434
+ '_id', '$ref', 'arrayItem', 'arrayItemType', 'dataPointer', 'dataType',
435
+ 'items', 'key', 'name', 'options', 'recursiveReference', 'type', 'widget'
436
+ ]],
437
+ [layoutNode.options, []],
438
+ ].forEach(([object, excludeKeys]) => mergeFilteredObject(newOptions, object, excludeKeys, fixUiKeys));
439
+ if (!hasOwn(newOptions, 'titleMap')) {
440
+ let newTitleMap = null;
441
+ newTitleMap = getTitleMapFromOneOf(schema, newOptions.flatList);
442
+ if (newTitleMap) {
443
+ newOptions.titleMap = newTitleMap;
444
+ }
445
+ if (!hasOwn(newOptions, 'titleMap') && !hasOwn(newOptions, 'enum') && hasOwn(schema, 'items')) {
446
+ if (JsonPointer.has(schema, '/items/titleMap')) {
447
+ newOptions.titleMap = schema.items.titleMap;
448
+ }
449
+ else if (JsonPointer.has(schema, '/items/enum')) {
450
+ newOptions.enum = schema.items.enum;
451
+ if (!hasOwn(newOptions, 'enumNames') && JsonPointer.has(schema, '/items/enumNames')) {
452
+ newOptions.enumNames = schema.items.enumNames;
453
+ }
454
+ }
455
+ else if (JsonPointer.has(schema, '/items/oneOf')) {
456
+ newTitleMap = getTitleMapFromOneOf(schema.items, newOptions.flatList);
457
+ if (newTitleMap) {
458
+ newOptions.titleMap = newTitleMap;
459
+ }
460
+ }
461
+ }
462
+ }
463
+ // If schema type is integer, enforce by setting multipleOf = 1
464
+ if (schema.type === 'integer' && !hasValue(newOptions.multipleOf)) {
465
+ newOptions.multipleOf = 1;
466
+ }
467
+ // Copy any typeahead word lists to options.typeahead.source
468
+ if (JsonPointer.has(newOptions, '/autocomplete/source')) {
469
+ newOptions.typeahead = newOptions.autocomplete;
470
+ }
471
+ else if (JsonPointer.has(newOptions, '/tagsinput/source')) {
472
+ newOptions.typeahead = newOptions.tagsinput;
473
+ }
474
+ else if (JsonPointer.has(newOptions, '/tagsinput/typeahead/source')) {
475
+ newOptions.typeahead = newOptions.tagsinput.typeahead;
476
+ }
477
+ layoutNode.options = newOptions;
478
+ }
479
+ /**
480
+ * 'getTitleMapFromOneOf' function
481
+ *
482
+ * // { schema } schema
483
+ * // { boolean = null } flatList
484
+ * // { boolean = false } validateOnly
485
+ * // { validators }
486
+ */
487
+ export function getTitleMapFromOneOf(schema = {}, flatList = null, validateOnly = false) {
488
+ let titleMap = null;
489
+ const oneOf = schema.oneOf || schema.anyOf || null;
490
+ if (isArray(oneOf) && oneOf.every(item => item.title)) {
491
+ if (oneOf.every(item => isArray(item.enum) && item.enum.length === 1)) {
492
+ if (validateOnly) {
493
+ return true;
494
+ }
495
+ titleMap = oneOf.map(item => ({ name: item.title, value: item.enum[0] }));
496
+ }
497
+ else if (oneOf.every(item => item.const)) {
498
+ if (validateOnly) {
499
+ return true;
500
+ }
501
+ titleMap = oneOf.map(item => ({ name: item.title, value: item.const }));
502
+ }
503
+ // if flatList !== false and some items have colons, make grouped map
504
+ if (flatList !== false && (titleMap || [])
505
+ .filter(title => ((title || {}).name || '').indexOf(': ')).length > 1) {
506
+ // Split name on first colon to create grouped map (name -> group: name)
507
+ const newTitleMap = titleMap.map(title => {
508
+ const [group, name] = title.name.split(/: (.+)/);
509
+ return group && name ? { ...title, group, name } : title;
510
+ });
511
+ // If flatList === true or at least one group has multiple items, use grouped map
512
+ if (flatList === true || newTitleMap.some((title, index) => index &&
513
+ hasOwn(title, 'group') && title.group === newTitleMap[index - 1].group)) {
514
+ titleMap = newTitleMap;
515
+ }
516
+ }
517
+ }
518
+ return validateOnly ? false : titleMap;
519
+ }
520
+ /**
521
+ * 'getControlValidators' function
522
+ *
523
+ * // schema
524
+ * // { validators }
525
+ */
526
+ export function getControlValidators(schema) {
527
+ if (!isObject(schema)) {
528
+ return null;
529
+ }
530
+ const validators = {};
531
+ if (hasOwn(schema, 'type')) {
532
+ switch (schema.type) {
533
+ case 'string':
534
+ forEach(['pattern', 'format', 'minLength', 'maxLength'], (prop) => {
535
+ if (hasOwn(schema, prop)) {
536
+ validators[prop] = [schema[prop]];
537
+ }
538
+ });
539
+ break;
540
+ case 'number':
541
+ case 'integer':
542
+ forEach(['Minimum', 'Maximum'], (ucLimit) => {
543
+ const eLimit = 'exclusive' + ucLimit;
544
+ const limit = ucLimit.toLowerCase();
545
+ if (hasOwn(schema, limit)) {
546
+ const exclusive = hasOwn(schema, eLimit) && schema[eLimit] === true;
547
+ validators[limit] = [schema[limit], exclusive];
548
+ }
549
+ });
550
+ forEach(['multipleOf', 'type'], (prop) => {
551
+ if (hasOwn(schema, prop)) {
552
+ validators[prop] = [schema[prop]];
553
+ }
554
+ });
555
+ break;
556
+ case 'object':
557
+ forEach(['minProperties', 'maxProperties', 'dependencies'], (prop) => {
558
+ if (hasOwn(schema, prop)) {
559
+ validators[prop] = [schema[prop]];
560
+ }
561
+ });
562
+ break;
563
+ case 'array':
564
+ forEach(['minItems', 'maxItems', 'uniqueItems'], (prop) => {
565
+ if (hasOwn(schema, prop)) {
566
+ validators[prop] = [schema[prop]];
567
+ }
568
+ });
569
+ break;
570
+ }
571
+ }
572
+ if (hasOwn(schema, 'enum')) {
573
+ validators.enum = [schema.enum];
574
+ }
575
+ return validators;
576
+ }
577
+ /**
578
+ * 'resolveSchemaReferences' function
579
+ *
580
+ * Find all $ref links in schema and save links and referenced schemas in
581
+ * schemaRefLibrary, schemaRecursiveRefMap, and dataRecursiveRefMap
582
+ *
583
+ * // schema
584
+ * // schemaRefLibrary
585
+ * // { Map<string, string> } schemaRecursiveRefMap
586
+ * // { Map<string, string> } dataRecursiveRefMap
587
+ * // { Map<string, number> } arrayMap
588
+ * //
589
+ */
590
+ export function resolveSchemaReferences(schema, schemaRefLibrary, schemaRecursiveRefMap, dataRecursiveRefMap, arrayMap) {
591
+ if (!isObject(schema)) {
592
+ console.error('resolveSchemaReferences error: schema must be an object.');
593
+ return;
594
+ }
595
+ const refLinks = new Set();
596
+ const refMapSet = new Set();
597
+ const refMap = new Map();
598
+ const recursiveRefMap = new Map();
599
+ const refLibrary = {};
600
+ // Search schema for all $ref links, and build full refLibrary
601
+ JsonPointer.forEachDeep(schema, (subSchema, subSchemaPointer) => {
602
+ if (hasOwn(subSchema, '$ref') && isString(subSchema['$ref'])) {
603
+ const refPointer = JsonPointer.compile(subSchema['$ref']);
604
+ refLinks.add(refPointer);
605
+ refMapSet.add(subSchemaPointer + '~~' + refPointer);
606
+ refMap.set(subSchemaPointer, refPointer);
607
+ }
608
+ });
609
+ refLinks.forEach(ref => refLibrary[ref] = getSubSchema(schema, ref));
610
+ // Follow all ref links and save in refMapSet,
611
+ // to find any multi-link recursive refernces
612
+ let checkRefLinks = true;
613
+ while (checkRefLinks) {
614
+ checkRefLinks = false;
615
+ Array.from(refMap).forEach(([fromRef1, toRef1]) => Array.from(refMap)
616
+ .filter(([fromRef2, toRef2]) => JsonPointer.isSubPointer(toRef1, fromRef2, true) &&
617
+ !JsonPointer.isSubPointer(toRef2, toRef1, true) &&
618
+ !refMapSet.has(fromRef1 + fromRef2.slice(toRef1.length) + '~~' + toRef2))
619
+ .forEach(([fromRef2, toRef2]) => {
620
+ refMapSet.add(fromRef1 + fromRef2.slice(toRef1.length) + '~~' + toRef2);
621
+ checkRefLinks = true;
622
+ }));
623
+ }
624
+ // Build full recursiveRefMap
625
+ // First pass - save all internally recursive refs from refMapSet
626
+ Array.from(refMapSet)
627
+ .map(refLink => refLink.split('~~'))
628
+ .filter(([fromRef, toRef]) => JsonPointer.isSubPointer(toRef, fromRef))
629
+ .forEach(([fromRef, toRef]) => recursiveRefMap.set(fromRef, toRef));
630
+ // Second pass - create recursive versions of any other refs that link to recursive refs
631
+ Array.from(refMap)
632
+ .filter(([fromRef1, toRef1]) => Array.from(recursiveRefMap.keys())
633
+ .every(fromRef2 => !JsonPointer.isSubPointer(fromRef1, fromRef2, true)))
634
+ .forEach(([fromRef1, toRef1]) => Array.from(recursiveRefMap)
635
+ .filter(([fromRef2, toRef2]) => !recursiveRefMap.has(fromRef1 + fromRef2.slice(toRef1.length)) &&
636
+ JsonPointer.isSubPointer(toRef1, fromRef2, true) &&
637
+ !JsonPointer.isSubPointer(toRef1, fromRef1, true))
638
+ .forEach(([fromRef2, toRef2]) => recursiveRefMap.set(fromRef1 + fromRef2.slice(toRef1.length), fromRef1 + toRef2.slice(toRef1.length))));
639
+ // Create compiled schema by replacing all non-recursive $ref links with
640
+ // thieir linked schemas and, where possible, combining schemas in allOf arrays.
641
+ let compiledSchema = { ...schema };
642
+ delete compiledSchema.definitions;
643
+ compiledSchema =
644
+ getSubSchema(compiledSchema, '', refLibrary, recursiveRefMap);
645
+ // Make sure all remaining schema $refs are recursive, and build final
646
+ // schemaRefLibrary, schemaRecursiveRefMap, dataRecursiveRefMap, & arrayMap
647
+ JsonPointer.forEachDeep(compiledSchema, (subSchema, subSchemaPointer) => {
648
+ if (isString(subSchema['$ref'])) {
649
+ let refPointer = JsonPointer.compile(subSchema['$ref']);
650
+ if (!JsonPointer.isSubPointer(refPointer, subSchemaPointer, true)) {
651
+ refPointer = removeRecursiveReferences(subSchemaPointer, recursiveRefMap);
652
+ JsonPointer.set(compiledSchema, subSchemaPointer, { $ref: `#${refPointer}` });
653
+ }
654
+ if (!hasOwn(schemaRefLibrary, 'refPointer')) {
655
+ schemaRefLibrary[refPointer] = !refPointer.length ? compiledSchema :
656
+ getSubSchema(compiledSchema, refPointer, schemaRefLibrary, recursiveRefMap);
657
+ }
658
+ if (!schemaRecursiveRefMap.has(subSchemaPointer)) {
659
+ schemaRecursiveRefMap.set(subSchemaPointer, refPointer);
660
+ }
661
+ const fromDataRef = JsonPointer.toDataPointer(subSchemaPointer, compiledSchema);
662
+ if (!dataRecursiveRefMap.has(fromDataRef)) {
663
+ const toDataRef = JsonPointer.toDataPointer(refPointer, compiledSchema);
664
+ dataRecursiveRefMap.set(fromDataRef, toDataRef);
665
+ }
666
+ }
667
+ if (subSchema.type === 'array' &&
668
+ (hasOwn(subSchema, 'items') || hasOwn(subSchema, 'additionalItems'))) {
669
+ const dataPointer = JsonPointer.toDataPointer(subSchemaPointer, compiledSchema);
670
+ if (!arrayMap.has(dataPointer)) {
671
+ const tupleItems = isArray(subSchema.items) ? subSchema.items.length : 0;
672
+ arrayMap.set(dataPointer, tupleItems);
673
+ }
674
+ }
675
+ }, true);
676
+ return compiledSchema;
677
+ }
678
+ /**
679
+ * 'getSubSchema' function
680
+ *
681
+ * // schema
682
+ * // { Pointer } pointer
683
+ * // { object } schemaRefLibrary
684
+ * // { Map<string, string> } schemaRecursiveRefMap
685
+ * // { string[] = [] } usedPointers
686
+ * //
687
+ */
688
+ export function getSubSchema(schema, pointer, schemaRefLibrary = null, schemaRecursiveRefMap = null, usedPointers = []) {
689
+ if (!schemaRefLibrary || !schemaRecursiveRefMap) {
690
+ return JsonPointer.getCopy(schema, pointer);
691
+ }
692
+ if (typeof pointer !== 'string') {
693
+ pointer = JsonPointer.compile(pointer);
694
+ }
695
+ usedPointers = [...usedPointers, pointer];
696
+ let newSchema = null;
697
+ if (pointer === '') {
698
+ newSchema = cloneDeep(schema);
699
+ }
700
+ else {
701
+ const shortPointer = removeRecursiveReferences(pointer, schemaRecursiveRefMap);
702
+ if (shortPointer !== pointer) {
703
+ usedPointers = [...usedPointers, shortPointer];
704
+ }
705
+ newSchema = JsonPointer.getFirstCopy([
706
+ [schemaRefLibrary, [shortPointer]],
707
+ [schema, pointer],
708
+ [schema, shortPointer]
709
+ ]);
710
+ }
711
+ return JsonPointer.forEachDeepCopy(newSchema, (subSchema, subPointer) => {
712
+ if (isObject(subSchema)) {
713
+ // Replace non-recursive $ref links with referenced schemas
714
+ if (isString(subSchema.$ref)) {
715
+ const refPointer = JsonPointer.compile(subSchema.$ref);
716
+ if (refPointer.length && usedPointers.every(ptr => !JsonPointer.isSubPointer(refPointer, ptr, true))) {
717
+ const refSchema = getSubSchema(schema, refPointer, schemaRefLibrary, schemaRecursiveRefMap, usedPointers);
718
+ if (Object.keys(subSchema).length === 1) {
719
+ return refSchema;
720
+ }
721
+ else {
722
+ const extraKeys = { ...subSchema };
723
+ delete extraKeys.$ref;
724
+ return mergeSchemas(refSchema, extraKeys);
725
+ }
726
+ }
727
+ }
728
+ // TODO: Convert schemas with 'type' arrays to 'oneOf'
729
+ // Combine allOf subSchemas
730
+ if (isArray(subSchema.allOf)) {
731
+ return combineAllOf(subSchema);
732
+ }
733
+ // Fix incorrectly placed array object required lists
734
+ if (subSchema.type === 'array' && isArray(subSchema.required)) {
735
+ return fixRequiredArrayProperties(subSchema);
736
+ }
737
+ }
738
+ return subSchema;
739
+ }, true, pointer);
740
+ }
741
+ /**
742
+ * 'combineAllOf' function
743
+ *
744
+ * Attempt to convert an allOf schema object into
745
+ * a non-allOf schema object with equivalent rules.
746
+ *
747
+ * // schema - allOf schema object
748
+ * // - converted schema object
749
+ */
750
+ export function combineAllOf(schema) {
751
+ if (!isObject(schema) || !isArray(schema.allOf)) {
752
+ return schema;
753
+ }
754
+ let mergedSchema = mergeSchemas(...schema.allOf);
755
+ if (Object.keys(schema).length > 1) {
756
+ const extraKeys = { ...schema };
757
+ delete extraKeys.allOf;
758
+ mergedSchema = mergeSchemas(mergedSchema, extraKeys);
759
+ }
760
+ return mergedSchema;
761
+ }
762
+ /**
763
+ * 'fixRequiredArrayProperties' function
764
+ *
765
+ * Fixes an incorrectly placed required list inside an array schema, by moving
766
+ * it into items.properties or additionalItems.properties, where it belongs.
767
+ *
768
+ * // schema - allOf schema object
769
+ * // - converted schema object
770
+ */
771
+ export function fixRequiredArrayProperties(schema) {
772
+ if (schema.type === 'array' && isArray(schema.required)) {
773
+ const itemsObject = hasOwn(schema.items, 'properties') ? 'items' :
774
+ hasOwn(schema.additionalItems, 'properties') ? 'additionalItems' : null;
775
+ if (itemsObject && !hasOwn(schema[itemsObject], 'required') && (hasOwn(schema[itemsObject], 'additionalProperties') ||
776
+ schema.required.every(key => hasOwn(schema[itemsObject].properties, key)))) {
777
+ schema = cloneDeep(schema);
778
+ schema[itemsObject].required = schema.required;
779
+ delete schema.required;
780
+ }
781
+ }
782
+ return schema;
783
+ }
784
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zY2hlbWEuZnVuY3Rpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctZm9ybXdvcmtzLWNvcmUvc3JjL2xpYi9zaGFyZWQvanNvbi1zY2hlbWEuZnVuY3Rpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sU0FBUyxNQUFNLGtCQUFrQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDeEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMzRSxPQUFPLEVBQ0gsT0FBTyxFQUNQLFFBQVEsRUFDUixPQUFPLEVBQ1AsT0FBTyxFQUNQLFFBQVEsRUFDUixRQUFRLEVBQ1IsUUFBUSxFQUNYLE1BQU0sdUJBQXVCLENBQUM7QUFHL0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQThCRztBQUVIOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQUMsTUFBTTtJQUMxQyxPQUFPO0lBQ1AsNEJBQTRCO0lBQzVCLDBFQUEwRTtJQUMxRSxpQ0FBaUM7SUFDakMsMENBQTBDO0lBQzFDLG9EQUFvRDtJQUNwRCxrRkFBa0Y7SUFDbEYsOEJBQThCO0lBQzlCLGtGQUFrRjtJQUNsRixRQUFRO0lBQ1IsTUFBTTtJQUNOLHdCQUF3QjtJQUN4QixLQUFLO0lBQ0wscUNBQXFDO0lBQ3JDLHlCQUF5QjtJQUN6QiwwQ0FBMEM7SUFDMUMsNEJBQTRCO0lBQzVCLGlDQUFpQztJQUNqQyxnQ0FBZ0M7SUFDaEMsTUFBTTtJQUNOLDhCQUE4QjtJQUM5QixPQUFPO0lBQ1AsTUFBTTtBQUNSLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQ2pDLElBQUks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LENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDaEUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDMUUsSUFBSSxXQUFXLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQzdELE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsc0JBQXNCLENBQUM7WUFDbkQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUMxRSxFQUFFO1lBQ0QsTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMzQixNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFDL0MsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDO1NBQ3hCO0tBQ0Y7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNsb25lRGVlcCBmcm9tICdsb2Rhc2gvY2xvbmVEZWVwJztcclxuaW1wb3J0IHsgSnNvblBvaW50ZXIgfSBmcm9tICcuL2pzb25wb2ludGVyLmZ1bmN0aW9ucyc7XHJcbmltcG9ydCB7IG1lcmdlU2NoZW1hcyB9IGZyb20gJy4vbWVyZ2Utc2NoZW1hcy5mdW5jdGlvbic7XHJcbmltcG9ydCB7IGZvckVhY2gsIGhhc093biwgbWVyZ2VGaWx0ZXJlZE9iamVjdCB9IGZyb20gJy4vdXRpbGl0eS5mdW5jdGlvbnMnO1xyXG5pbXBvcnQge1xyXG4gICAgZ2V0VHlwZSxcclxuICAgIGhhc1ZhbHVlLFxyXG4gICAgaW5BcnJheSxcclxuICAgIGlzQXJyYXksXHJcbiAgICBpc051bWJlcixcclxuICAgIGlzT2JqZWN0LFxyXG4gICAgaXNTdHJpbmdcclxufSBmcm9tICcuL3ZhbGlkYXRvci5mdW5jdGlvbnMnO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBKU09OIFNjaGVtYSBmdW5jdGlvbiBsaWJyYXJ5OlxyXG4gKlxyXG4gKiBidWlsZFNjaGVtYUZyb21MYXlvdXQ6ICAgVE9ETzogV3JpdGUgdGhpcyBmdW5jdGlvblxyXG4gKlxyXG4gKiBidWlsZFNjaGVtYUZyb21EYXRhOlxyXG4gKlxyXG4gKiBnZXRGcm9tU2NoZW1hOlxyXG4gKlxyXG4gKiByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzOlxyXG4gKlxyXG4gKiBnZXRJbnB1dFR5cGU6XHJcbiAqXHJcbiAqIGNoZWNrSW5saW5lVHlwZTpcclxuICpcclxuICogaXNJbnB1dFJlcXVpcmVkOlxyXG4gKlxyXG4gKiB1cGRhdGVJbnB1dE9wdGlvbnM6XHJcbiAqXHJcbiAqIGdldFRpdGxlTWFwRnJvbU9uZU9mOlxyXG4gKlxyXG4gKiBnZXRDb250cm9sVmFsaWRhdG9yczpcclxuICpcclxuICogcmVzb2x2ZVNjaGVtYVJlZmVyZW5jZXM6XHJcbiAqXHJcbiAqIGdldFN1YlNjaGVtYTpcclxuICpcclxuICogY29tYmluZUFsbE9mOlxyXG4gKlxyXG4gKiBmaXhSZXF1aXJlZEFycmF5UHJvcGVydGllczpcclxuICovXHJcblxyXG4vKipcclxuICogJ2J1aWxkU2NoZW1hRnJvbUxheW91dCcgZnVuY3Rpb25cclxuICpcclxuICogVE9ETzogQnVpbGQgYSBKU09OIFNjaGVtYSBmcm9tIGEgSlNPTiBGb3JtIGxheW91dFxyXG4gKlxyXG4gKiAvLyAgIGxheW91dCAtIFRoZSBKU09OIEZvcm0gbGF5b3V0XHJcbiAqIC8vICAtIFRoZSBuZXcgSlNPTiBTY2hlbWFcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBidWlsZFNjaGVtYUZyb21MYXlvdXQobGF5b3V0KSB7XHJcbiAgcmV0dXJuO1xyXG4gIC8vIGxldCBuZXdTY2hlbWE6IGFueSA9IHsgfTtcclxuICAvLyBjb25zdCB3YWxrTGF5b3V0ID0gKGxheW91dEl0ZW1zOiBhbnlbXSwgY2FsbGJhY2s6IEZ1bmN0aW9uKTogYW55W10gPT4ge1xyXG4gIC8vICAgbGV0IHJldHVybkFycmF5OiBhbnlbXSA9IFtdO1xyXG4gIC8vICAgZm9yIChsZXQgbGF5b3V0SXRlbSBvZiBsYXlvdXRJdGVtcykge1xyXG4gIC8vICAgICBjb25zdCByZXR1cm5JdGVtOiBhbnkgPSBjYWxsYmFjayhsYXlvdXRJdGVtKTtcclxuICAvLyAgICAgaWYgKHJldHVybkl0ZW0pIHsgcmV0dXJuQXJyYXkgPSByZXR1cm5BcnJheS5jb25jYXQoY2FsbGJhY2sobGF5b3V0SXRlbSkpOyB9XHJcbiAgLy8gICAgIGlmIChsYXlvdXRJdGVtLml0ZW1zKSB7XHJcbiAgLy8gICAgICAgcmV0dXJuQXJyYXkgPSByZXR1cm5BcnJheS5jb25jYXQod2Fsa0xheW91dChsYXlvdXRJdGVtLml0ZW1zLCBjYWxsYmFjaykpO1xyXG4gIC8vICAgICB9XHJcbiAgLy8gICB9XHJcbiAgLy8gICByZXR1cm4gcmV0dXJuQXJyYXk7XHJcbiAgLy8gfTtcclxuICAvLyB3YWxrTGF5b3V0KGxheW91dCwgbGF5b3V0SXRlbSA9PiB7XHJcbiAgLy8gICBsZXQgaXRlbUtleTogc3RyaW5nO1xyXG4gIC8vICAgaWYgKHR5cGVvZiBsYXlvdXRJdGVtID09PSAnc3RyaW5nJykge1xyXG4gIC8vICAgICBpdGVtS2V5ID0gbGF5b3V0SXRlbTtcclxuICAvLyAgIH0gZWxzZSBpZiAobGF5b3V0SXRlbS5rZXkpIHtcclxuICAvLyAgICAgaXRlbUtleSA9IGxheW91dEl0ZW0ua2V5O1xyXG4gIC8vICAgfVxyXG4gIC8vICAgaWYgKCFpdGVtS2V5KSB7IHJldHVybjsgfVxyXG4gIC8vICAgLy9cclxuICAvLyB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqICdidWlsZFNjaGVtYUZyb21EYXRhJyBmdW5jdGlvblxyXG4gKlxyXG4gKiBCdWlsZCBhIEpTT04gU2NoZW1hIGZyb20gYSBkYXRhIG9iamVjdFxyXG4gKlxyXG4gKiAvLyAgIGRhdGEgLSBUaGUgZGF0YSBvYmplY3RcclxuICogLy8gIHsgYm9vbGVhbiA9IGZhbHNlIH0gcmVxdWlyZUFsbEZpZWxkcyAtIFJlcXVpcmUgYWxsIGZpZWxkcz9cclxuICogLy8gIHsgYm9vbGVhbiA9IHRydWUgfSBpc1Jvb3QgLSBpcyByb290XHJcbiAqIC8vICAtIFRoZSBuZXcgSlNPTiBTY2hlbWFcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBidWlsZFNjaGVtYUZyb21EYXRhKFxyXG4gIGRhdGEsIHJlcXVpcmVBbGxGaWVsZHMgPSBmYWxzZSwgaXNSb290ID0gdHJ1ZVxyXG4pIHtcclxuICBjb25zdCBuZXdTY2hlbWE6IGFueSA9IHt9O1xyXG4gIGNvbnN0IGdldEZpZWxkVHlwZSA9ICh2YWx1ZTogYW55KTogc3RyaW5nID0+IHtcclxuICAgIGNvbnN0IGZpZWxkVHlwZSA9IGdldFR5cGUodmFsdWUsICdzdHJpY3QnKTtcclxuICAgIHJldHVybiB7IGludGVnZXI6ICdudW1iZXInLCBudWxsOiAnc3RyaW5nJyB9W2ZpZWxkVHlwZV0gfHwgZmllbGRUeXBlO1xyXG4gIH07XHJcbiAgY29uc3QgYnVpbGRTdWJTY2hlbWEgPSAodmFsdWUpID0+XHJcbiAgICBidWlsZFNjaGVtYUZyb21EYXRhKHZhbHVlLCByZXF1aXJlQWxsRmllbGRzLCBmYWxzZSk7XHJcbiAgaWYgKGlzUm9vdCkgeyBuZXdTY2hlbWEuJHNjaGVtYSA9ICdodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA2L3NjaGVtYSMnOyB9XHJcbiAgbmV3U2NoZW1hLnR5cGUgPSBnZXRGaWVsZFR5cGUoZGF0YSk7XHJcbiAgaWYgKG5ld1NjaGVtYS50eXBlID09PSAnb2JqZWN0Jykge1xyXG4gICAgbmV3U2NoZW1hLnByb3BlcnRpZXMgPSB7fTtcclxuICAgIGlmIChyZXF1aXJlQWxsRmllbGRzKSB7IG5ld1NjaGVtYS5yZXF1aXJlZCA9IFtdOyB9XHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhkYXRhKSkge1xyXG4gICAgICBuZXdTY2hlbWEucHJvcGVydGllc1trZXldID0gYnVpbGRTdWJTY2hlbWEoZGF0YVtrZXldKTtcclxuICAgICAgaWYgKHJlcXVpcmVBbGxGaWVsZHMpIHsgbmV3U2NoZW1hLnJlcXVpcmVkLnB1c2goa2V5KTsgfVxyXG4gICAgfVxyXG4gIH0gZWxzZSBpZiAobmV3U2NoZW1hLnR5cGUgPT09ICdhcnJheScpIHtcclxuICAgIG5ld1NjaGVtYS5pdGVtcyA9IGRhdGEubWFwKGJ1aWxkU3ViU2NoZW1hKTtcclxuICAgIC8vIElmIGFsbCBpdGVtcyBhcmUgdGhlIHNhbWUgdHlwZSwgdXNlIGFuIG9iamVjdCBmb3IgaXRlbXMgaW5zdGVhZCBvZiBhbiBhcnJheVxyXG4gICAgaWYgKChuZXcgU2V0KGRhdGEubWFwKGdldEZpZWxkVHlwZSkpKS5zaXplID09PSAxKSB7XHJcbiAgICAgIG5ld1NjaGVtYS5pdGVtcyA9IG5ld1NjaGVtYS5pdGVtcy5yZWR1Y2UoKGEsIGIpID0+ICh7IC4uLmEsIC4uLmIgfSksIHt9KTtcclxuICAgIH1cclxuICAgIGlmIChyZXF1aXJlQWxsRmllbGRzKSB7IG5ld1NjaGVtYS5taW5JdGVtcyA9IDE7IH1cclxuICB9XHJcbiAgcmV0dXJuIG5ld1NjaGVtYTtcclxufVxyXG5cclxuLyoqXHJcbiAqICdnZXRGcm9tU2NoZW1hJyBmdW5jdGlvblxyXG4gKlxyXG4gKiBVc2VzIGEgSlNPTiBQb2ludGVyIGZvciBhIHZhbHVlIHdpdGhpbiBhIGRhdGEgb2JqZWN0IHRvIHJldHJpZXZlXHJcbiAqIHRoZSBzY2hlbWEgZm9yIHRoYXQgdmFsdWUgd2l0aGluIHNjaGVtYSBmb3IgdGhlIGRhdGEgb2JqZWN0LlxyXG4gKlxyXG4gKiBUaGUgb3B0aW9uYWwgdGhpcmQgcGFyYW1ldGVyIGNhbiBhbHNvIGJlIHNldCB0byByZXR1cm4gc29tZXRoaW5nIGVsc2U6XHJcbiAqICdzY2hlbWEnIChkZWZhdWx0KTogdGhlIHNjaGVtYSBmb3IgdGhlIHZhbHVlIGluZGljYXRlZCBieSB0aGUgZGF0YSBwb2ludGVyXHJcbiAqICdwYXJlbnRTY2hlbWEnOiB0aGUgc2NoZW1hIGZvciB0aGUgdmFsdWUncyBwYXJlbnQgb2JqZWN0IG9yIGFycmF5XHJcbiAqICdzY2hlbWFQb2ludGVyJzogYSBwb2ludGVyIHRvIHRoZSB2YWx1ZSdzIHNjaGVtYSB3aXRoaW4gdGhlIG9iamVjdCdzIHNjaGVtYVxyXG4gKiAncGFyZW50U2NoZW1hUG9pbnRlcic6IGEgcG9pbnRlciB0byB0aGUgc2NoZW1hIGZvciB0aGUgdmFsdWUncyBwYXJlbnQgb2JqZWN0IG9yIGFycmF5XHJcbiAqXHJcbiAqIC8vICAgc2NoZW1hIC0gVGhlIHNjaGVtYSB0byBnZXQgdGhlIHN1Yi1zY2hlbWEgZnJvbVxyXG4gKiAvLyAgeyBQb2ludGVyIH0gZGF0YVBvaW50ZXIgLSBKU09OIFBvaW50ZXIgKHN0cmluZyBvciBhcnJheSlcclxuICogLy8gIHsgc3RyaW5nID0gJ3NjaGVtYScgfSByZXR1cm5UeXBlIC0gd2hhdCB0byByZXR1cm4/XHJcbiAqIC8vICAtIFRoZSBsb2NhdGVkIHN1Yi1zY2hlbWFcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGcm9tU2NoZW1hKHNjaGVtYSwgZGF0YVBvaW50ZXIsIHJldHVyblR5cGUgPSAnc2NoZW1hJykge1xyXG4gIGNvbnN0IGRhdGFQb2ludGVyQXJyYXk6IGFueVtdID0gSnNvblBvaW50ZXIucGFyc2UoZGF0YVBvaW50ZXIpO1xyXG4gIGlmIChkYXRhUG9pbnRlckFycmF5ID09PSBudWxsKSB7XHJcbiAgICBjb25zb2xlLmVycm9yKGBnZXRGcm9tU2NoZW1hIGVycm9yOiBJbnZhbGlkIEpTT04gUG9pbnRlcjogJHtkYXRhUG9pbnRlcn1gKTtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuICBsZXQgc3ViU2NoZW1hID0gc2NoZW1hO1xyXG4gIGNvbnN0IHNjaGVtYVBvaW50ZXIgPSBbXTtcclxuICBjb25zdCBsZW5ndGggPSBkYXRhUG9pbnRlckFycmF5Lmxlbmd0aDtcclxuICBpZiAocmV0dXJuVHlwZS5zbGljZSgwLCA2KSA9PT0gJ3BhcmVudCcpIHsgZGF0YVBvaW50ZXJBcnJheS5sZW5ndGgtLTsgfVxyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcclxuICAgIGNvbnN0IHBhcmVudFNjaGVtYSA9IHN1YlNjaGVtYTtcclxuICAgIGNvbnN0IGtleSA9IGRhdGFQb2ludGVyQXJyYXlbaV07XHJcbiAgICBsZXQgc3ViU2NoZW1hRm91bmQgPSBmYWxzZTtcclxuICAgIGlmICh0eXBlb2Ygc3ViU2NoZW1hICE9PSAnb2JqZWN0Jykge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBnZXRGcm9tU2NoZW1hIGVycm9yOiBVbmFibGUgdG8gZmluZCBcIiR7a2V5fVwiIGtleSBpbiBzY2hlbWEuYCk7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3Ioc2NoZW1hKTtcclxuICAgICAgY29uc29sZS5lcnJvcihkYXRhUG9pbnRlcik7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgaWYgKHN1YlNjaGVtYS50eXBlID09PSAnYXJyYXknICYmICghaXNOYU4oa2V5KSB8fCBrZXkgPT09ICctJykpIHtcclxuICAgICAgaWYgKGhhc093bihzdWJTY2hlbWEsICdpdGVtcycpKSB7XHJcbiAgICAgICAgaWYgKGlzT2JqZWN0KHN1YlNjaGVtYS5pdGVtcykpIHtcclxuICAgICAgICAgIHN1YlNjaGVtYUZvdW5kID0gdHJ1ZTtcclxuICAgICAgICAgIHN1YlNjaGVtYSA9IHN1YlNjaGVtYS5pdGVtcztcclxuICAgICAgICAgIHNjaGVtYVBvaW50ZXIucHVzaCgnaXRlbXMnKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoc3ViU2NoZW1hLml0ZW1zKSkge1xyXG4gICAgICAgICAgaWYgKCFpc05hTihrZXkpICYmIHN1YlNjaGVtYS5pdGVtcy5sZW5ndGggPj0gK2tleSkge1xyXG4gICAgICAgICAgICBzdWJTY2hlbWFGb3VuZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHN1YlNjaGVtYSA9IHN1YlNjaGVtYS5pdGVtc1sra2V5XTtcclxuICAgICAgICAgICAgc2NoZW1hUG9pbnRlci5wdXNoKCdpdGVtcycsIGtleSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmICghc3ViU2NoZW1hRm91bmQgJiYgaXNPYmplY3Qoc3ViU2NoZW1hLmFkZGl0aW9uYWxJdGVtcykpIHtcclxuICAgICAgICBzdWJTY2hlbWFGb3VuZCA9IHRydWU7XHJcbiAgICAgICAgc3ViU2NoZW1hID0gc3ViU2NoZW1hLmFkZGl0aW9uYWxJdGVtcztcclxuICAgICAgICBzY2hlbWFQb2ludGVyLnB1c2goJ2FkZGl0aW9uYWxJdGVtcycpO1xyXG4gICAgICB9IGVsc2UgaWYgKHN1YlNjaGVtYS5hZGRpdGlvbmFsSXRlbXMgIT09IGZhbHNlKSB7XHJcbiAgICAgICAgc3ViU2NoZW1hRm91bmQgPSB0cnVlO1xyXG4gICAgICAgIHN1YlNjaGVtYSA9IHsgfTtcclxuICAgICAgICBzY2hlbWFQb2ludGVyLnB1c2goJ2FkZGl0aW9uYWxJdGVtcycpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKHN1YlNjaGVtYS50eXBlID09PSAnb2JqZWN0Jykge1xyXG4gICAgICBpZiAoaXNPYmplY3Qoc3ViU2NoZW1hLnByb3BlcnRpZXMpICYmIGhhc093bihzdWJTY2hlbWEucHJvcGVydGllcywga2V5KSkge1xyXG4gICAgICAgIHN1YlNjaGVtYUZvdW5kID0gdHJ1ZTtcclxuICAgICAgICBzdWJTY2hlbWEgPSBzdWJTY2hlbWEucHJvcGVydGllc1trZXldO1xyXG4gICAgICAgIHNjaGVtYVBvaW50ZXIucHVzaCgncHJvcGVydGllcycsIGtleSk7XHJcbiAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3Qoc3ViU2NoZW1hLmFkZGl0aW9uYWxQcm9wZXJ0aWVzKSkge1xyXG4gICAgICAgIHN1YlNjaGVtYUZvdW5kID0gdHJ1ZTtcclxuICAgICAgICBzdWJTY2hlbWEgPSBzdWJTY2hlbWEuYWRkaXRpb25hbFByb3BlcnRpZXM7XHJcbiAgICAgICAgc2NoZW1hUG9pbnRlci5wdXNoKCdhZGRpdGlvbmFsUHJvcGVydGllcycpO1xyXG4gICAgICB9IGVsc2UgaWYgKHN1YlNjaGVtYS5hZGRpdGlvbmFsUHJvcGVydGllcyAhPT0gZmFsc2UpIHtcclxuICAgICAgICBzdWJTY2hlbWFGb3VuZCA9IHRydWU7XHJcbiAgICAgICAgc3ViU2NoZW1hID0geyB9O1xyXG4gICAgICAgIHNjaGVtYVBvaW50ZXIucHVzaCgnYWRkaXRpb25hbFByb3BlcnRpZXMnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKCFzdWJTY2hlbWFGb3VuZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBnZXRGcm9tU2NoZW1hIGVycm9yOiBVbmFibGUgdG8gZmluZCBcIiR7a2V5fVwiIGl0ZW0gaW4gc2NoZW1hLmApO1xyXG4gICAgICBjb25zb2xlLmVycm9yKHNjaGVtYSk7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YVBvaW50ZXIpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiByZXR1cm5UeXBlLnNsaWNlKC03KSA9PT0gJ1BvaW50ZXInID8gc2NoZW1hUG9pbnRlciA6IHN1YlNjaGVtYTtcclxufVxyXG5cclxuLyoqXHJcbiAqICdyZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzJyBmdW5jdGlvblxyXG4gKlxyXG4gKiBDaGVja3MgYSBKU09OIFBvaW50ZXIgYWdhaW5zdCBhIG1hcCBvZiByZWN1cnNpdmUgcmVmZXJlbmNlcyBhbmQgcmV0dXJuc1xyXG4gKiBhIEpTT04gUG9pbnRlciB0byB0aGUgc2hhbGxvd2VzdCBlcXVpdmFsZW50IGxvY2F0aW9uIGluIHRoZSBzYW1lIG9iamVjdC5cclxuICpcclxuICogVXNpbmcgdGhpcyBmdW5jdGlvbnMgZW5hYmxlcyBhbiBvYmplY3QgdG8gYmUgY29uc3RydWN0ZWQgd2l0aCB1bmxpbWl0ZWRcclxuICogcmVjdXJzaW9uLCB3aGlsZSBtYWludGFpbmcgYSBmaXhlZCBzZXQgb2YgbWV0YWRhdGEsIHN1Y2ggYXMgZmllbGQgZGF0YSB0eXBlcy5cclxuICogVGhlIG9iamVjdCBjYW4gZ3JvdyBhcyBsYXJnZSBhcyBpdCB3YW50cywgYW5kIGRlZXBseSByZWN1cnNlZCBub2RlcyBjYW5cclxuICoganVzdCByZWZlciB0byB0aGUgbWV0YWRhdGEgZm9yIHRoZWlyIHNoYWxsb3cgZXF1aXZhbGVudHMsIGluc3RlYWQgb2YgaGF2aW5nXHJcbiAqIHRvIGFkZCBhZGRpdGlvbmFsIHJlZHVuZGFudCBtZXRhZGF0YSBmb3IgZWFjaCByZWN1cnNpdmVseSBhZGRlZCBub2RlLlxyXG4gKlxyXG4gKiBFeGFtcGxlOlxyXG4gKlxyXG4gKiBwb2ludGVyOiAgICAgICAgICcvc3R1ZmYvYW5kL21vcmUvYW5kL21vcmUvYW5kL21vcmUvYW5kL21vcmUvc3R1ZmYnXHJcbiAqIHJlY3Vyc2l2ZVJlZk1hcDogW1snL3N0dWZmL2FuZC9tb3JlL2FuZC9tb3JlJywgJy9zdHVmZi9hbmQvbW9yZS8nXV1cclxuICogcmV0dXJuZWQ6ICAgICAgICAnL3N0dWZmL2FuZC9tb3JlL3N0dWZmJ1xyXG4gKlxyXG4gKiAvLyAgeyBQb2ludGVyIH0gcG9pbnRlciAtXHJcbiAqIC8vICB7IE1hcDxzdHJpbmcsIHN0cmluZz4gfSByZWN1cnNpdmVSZWZNYXAgLVxyXG4gKiAvLyAgeyBNYXA8c3RyaW5nLCBudW1iZXI+ID0gbmV3IE1hcCgpIH0gYXJyYXlNYXAgLSBvcHRpb25hbFxyXG4gKiAvLyB7IHN0cmluZyB9IC1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVSZWN1cnNpdmVSZWZlcmVuY2VzKFxyXG4gIHBvaW50ZXIsIHJlY3Vyc2l2ZVJlZk1hcCwgYXJyYXlNYXAgPSBuZXcgTWFwKClcclxuKSB7XHJcbiAgaWYgKCFwb2ludGVyKSB7IHJldHVybiAnJzsgfVxyXG4gIGxldCBnZW5lcmljUG9pbnRlciA9XHJcbiAgICBKc29uUG9pbnRlci50b0dlbmVyaWNQb2ludGVyKEpzb25Qb2ludGVyLmNvbXBpbGUocG9pbnRlciksIGFycmF5TWFwKTtcclxuICBpZiAoZ2VuZXJpY1BvaW50ZXIuaW5kZXhPZignLycpID09PSAtMSkgeyByZXR1cm4gZ2VuZXJpY1BvaW50ZXI7IH1cclxuICBsZXQgcG9zc2libGVSZWZlcmVuY2VzID0gdHJ1ZTtcclxuICB3aGlsZSAocG9zc2libGVSZWZlcmVuY2VzKSB7XHJcbiAgICBwb3NzaWJsZVJlZmVyZW5jZXMgPSBmYWxzZTtcclxuICAgIHJlY3Vyc2l2ZVJlZk1hcC5mb3JFYWNoKCh0b1BvaW50ZXIsIGZyb21Qb2ludGVyKSA9PiB7XHJcbiAgICAgIGlmIChKc29uUG9pbnRlci5pc1N1YlBvaW50ZXIodG9Qb2ludGVyLCBmcm9tUG9pbnRlcikpIHtcclxuICAgICAgICB3aGlsZSAoSnNvblBvaW50ZXIuaXNTdWJQb2ludGVyKGZyb21Qb2ludGVyLCBnZW5lcmljUG9pbnRlciwgdHJ1ZSkpIHtcclxuICAgICAgICAgIGdlbmVyaWNQb2ludGVyID0gSnNvblBvaW50ZXIudG9HZW5lcmljUG9pbnRlcihcclxuICAgICAgICAgICAgdG9Qb2ludGVyICsgZ2VuZXJpY1BvaW50ZXIuc2xpY2UoZnJvbVBvaW50ZXIubGVuZ3RoKSwgYXJyYXlNYXBcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBwb3NzaWJsZVJlZmVyZW5jZXMgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIHJldHVybiBnZW5lcmljUG9pbnRlcjtcclxufVxyXG5cclxuLyoqXHJcbiAqICdnZXRJbnB1dFR5cGUnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIC8vICAgc2NoZW1hXHJcbiAqIC8vICB7IGFueSA9IG51bGwgfSBsYXlvdXROb2RlXHJcbiAqIC8vIHsgc3RyaW5nIH1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRJbnB1dFR5cGUoc2NoZW1hLCBsYXlvdXROb2RlOiBhbnkgPSBudWxsKSB7XHJcbiAgLy8geC1zY2hlbWEtZm9ybSA9IEFuZ3VsYXIgU2NoZW1hIEZvcm0gY29tcGF0aWJpbGl0eVxyXG4gIC8vIHdpZGdldCAmIGNvbXBvbmVudCA9IFJlYWN0IEpzb25zY2hlbWEgRm9ybSBjb21wYXRpYmlsaXR5XHJcbiAgY29uc3QgY29udHJvbFR5cGUgPSBKc29uUG9pbnRlci5nZXRGaXJzdChbXHJcbiAgICBbc2NoZW1hLCAnL3gtc2NoZW1hLWZvcm0vdHlwZSddLFxyXG4gICAgW3NjaGVtYSwgJy94LXNjaGVtYS1mb3JtL3dpZGdldC9jb21wb25lbnQnXSxcclxuICAgIFtzY2hlbWEsICcveC1zY2hlbWEtZm9ybS93aWRnZXQnXSxcclxuICAgIFtzY2hlbWEsICcvd2lkZ2V0L2NvbXBvbmVudCddLFxyXG4gICAgW3NjaGVtYSwgJy93aWRnZXQnXVxyXG4gIF0pO1xyXG4gIGlmIChpc1N0cmluZyhjb250cm9sVHlwZSkpIHsgcmV0dXJuIGNoZWNrSW5saW5lVHlwZShjb250cm9sVHlwZSwgc2NoZW1hLCBsYXlvdXROb2RlKTsgfVxyXG4gIGxldCBzY2hlbWFUeXBlID0gc2NoZW1hLnR5cGU7XHJcbiAgaWYgKHNjaGVtYVR5cGUpIHtcclxuICAgIGlmIChpc0FycmF5KHNjaGVtYVR5cGUpKSB7IC8vIElmIG11bHRpcGxlIHR5cGVzIGxpc3RlZCwgdXNlIG1vc3QgaW5jbHVzaXZlIHR5cGVcclxuICAgICAgc2NoZW1hVHlwZSA9XHJcbiAgICAgICAgaW5BcnJheSgnb2JqZWN0Jywgc2NoZW1hVHlwZSkgJiYgaGFzT3duKHNjaGVtYSwgJ3Byb3BlcnRpZXMnKSA/ICdvYmplY3QnIDpcclxuICAgICAgICBpbkFycmF5KCdhcnJheScsIHNjaGVtYVR5cGUpICYmIGhhc093bihzY2hlbWEsICdpdGVtcycpID8gJ2FycmF5JyA6XHJcbiAgICAgICAgaW5BcnJheSgnYXJyYXknLCBzY2hlbWFUeXBlKSAmJiBoYXNPd24oc2NoZW1hLCAnYWRkaXRpb25hbEl0ZW1zJykgPyAnYXJyYXknIDpcclxuICAgICAgICBpbkFycmF5KCdzdHJpbmcnLCBzY2hlbWFUeXBlKSA/ICdzdHJpbmcnIDpcclxuICAgICAgICBpbkFycmF5KCdudW1iZXInLCBzY2hlbWFUeXBlKSA/ICdudW1iZXInIDpcclxuICAgICAgICBpbkFycmF5KCdpbnRlZ2VyJywgc2NoZW1hVHlwZSkgPyAnaW50ZWdlcicgOlxyXG4gICAgICAgIGluQXJyYXkoJ2Jvb2xlYW4nLCBzY2hlbWFUeXBlKSA/ICdib29sZWFuJyA6ICd1bmtub3duJztcclxuICAgIH1cclxuICAgIGlmIChzY2hlbWFUeXBlID09PSAnYm9vbGVhbicpIHsgcmV0dXJuICdjaGVja2JveCc7IH1cclxuICAgIGlmIChzY2hlbWFUeXBlID09PSAnb2JqZWN0Jykge1xyXG4gICAgICBpZiAoaGFzT3duKHNjaGVtYSwgJ3Byb3BlcnRpZXMnKSB8fCBoYXNPd24oc2NoZW1hLCAnYWRkaXRpb25hbFByb3BlcnRpZXMnKSkge1xyXG4gICAgICAgIHJldHVybiAnc2VjdGlvbic7XHJcbiAgICAgIH1cclxuICAgICAgLy8gVE9ETzogRmlndXJlIG91dCBob3cgdG8gaGFuZGxlIGFkZGl0aW9uYWxQcm9wZXJ0aWVzXHJcbiAgICAgIGlmIChoYXNPd24oc2NoZW1hLCAnJHJlZicpKSB7IHJldHVybiAnJHJlZic7IH1cclxuICAgIH1cclxuICAgIGlmIChzY2hlbWFUeXBlID09PSAnYXJyYXknKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW1zT2JqZWN0ID0gSnNvblBvaW50ZXIuZ2V0Rmlyc3QoW1xyXG4gICAgICAgIFtzY2hlbWEsICcvaXRlbXMnXSxcclxuICAgICAgICBbc2NoZW1hLCAnL2FkZGl0aW9uYWxJdGVtcyddXHJcbiAgICAgIF0pIHx8IHt9O1xyXG4gICAgICByZXR1cm4gaGFzT3duKGl0ZW1zT2JqZWN0LCAnZW51bScpICYmIHNjaGVtYS5tYXhJdGVtcyAhPT0gMSA/XHJcbiAgICAgICAgY2hlY2tJbmxpbmVUeXBlKCdjaGVja2JveGVzJywgc2NoZW1hLCBsYXlvdXROb2RlKSA6ICdhcnJheSc7XHJcbiAgICB9XHJcbiAgICBpZiAoc2NoZW1hVHlwZSA9PT0gJ251bGwnKSB7IHJldHVybiAnbm9uZSc7IH1cclxuICAgIGlmIChKc29uUG9pbnRlci5oYXMobGF5b3V0Tm9kZSwgJy9vcHRpb25zL3RpdGxlTWFwJykgfHxcclxuICAgICAgaGFzT3duKHNjaGVtYSwgJ2VudW0nKSB8fCBnZXRUaXRsZU1hcEZyb21PbmVPZihzY2hlbWEsIG51bGwsIHRydWUpXHJcbiAgICApIHsgcmV0dXJuICdzZWxlY3QnOyB9XHJcbiAgICBpZiAoc2NoZW1hVHlwZSA9PT0gJ251bWJlcicgfHwgc2NoZW1hVHlwZSA9PT0gJ2ludGVnZXInKSB7XHJcbiAgICAgIHJldHVybiAoc2NoZW1hVHlwZSA9PT0gJ2ludGVnZXInIHx8IGhhc093bihzY2hlbWEsICdtdWx0aXBsZU9mJykpICYmXHJcbiAgICAgICAgaGFzT3duKHNjaGVtYSwgJ21heGltdW0nKSAmJiBoYXNPd24oc2NoZW1hLCAnbWluaW11bScpID8gJ3JhbmdlJyA6IHNjaGVtYVR5cGU7XHJcbiAgICB9XHJcbiAgICBpZiAoc2NoZW1hVHlwZSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICAnY29sb3InOiAnY29sb3InLFxyXG4gICAgICAgICdkYXRlJzogJ2RhdGUnLFxyXG4gICAgICAgICdkYXRlLXRpbWUnOiAnZGF0ZXRpbWUtbG9jYWwnLFxyXG4gICAgICAgICdlbWFpbCc6ICdlbWFpbCcsXHJcbiAgICAgICAgJ3VyaSc6ICd1cmwnLFxyXG4gICAgICB9W3NjaGVtYS5mb3JtYXRdIHx8ICd0ZXh0JztcclxuICAgIH1cclxuICB9XHJcbiAgaWYgKGhhc093bihzY2hlbWEsICckcmVmJykpIHsgcmV0dXJuICckcmVmJzsgfVxyXG4gIGlmIChpc0FycmF5KHNjaGVtYS5vbmVPZikgfHwgaXNBcnJheShzY2hlbWEuYW55T2YpKSB7IHJldHVybiAnb25lLW9mJzsgfVxyXG4gIGNvbnNvbGUuZXJyb3IoYGdldElucHV0VHlwZSBlcnJvcjogVW5hYmxlIHRvIGRldGVybWluZSBpbnB1dCB0eXBlIGZvciAke3NjaGVtYVR5cGV9YCk7XHJcbiAgY29uc29sZS5lcnJvcignc2NoZW1hJywgc2NoZW1hKTtcclxuICBpZiAobGF5b3V0Tm9kZSkgeyBjb25zb2xlLmVycm9yKCdsYXlvdXROb2RlJywgbGF5b3V0Tm9kZSk7IH1cclxuICByZXR1cm4gJ25vbmUnO1xyXG59XHJcblxyXG4vKipcclxuICogJ2NoZWNrSW5saW5lVHlwZScgZnVuY3Rpb25cclxuICpcclxuICogQ2hlY2tzIGxheW91dCBhbmQgc2NoZW1hIG5vZGVzIGZvciAnaW5saW5lOiB0cnVlJywgYW5kIGNvbnZlcnRzXHJcbiAqICdyYWRpb3MnIG9yICdjaGVja2JveGVzJyB0byAncmFkaW9zLWlubGluZScgb3IgJ2NoZWNrYm94ZXMtaW5saW5lJ1xyXG4gKlxyXG4gKiAvLyAgeyBzdHJpbmcgfSBjb250cm9sVHlwZSAtXHJcbiAqIC8vICAgc2NoZW1hIC1cclxuICogLy8gIHsgYW55ID0gbnVsbCB9IGxheW91dE5vZGUgLVxyXG4gKiAvLyB7IHN0cmluZyB9XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tJbmxpbmVUeXBlKGNvbnRyb2xUeXBlLCBzY2hlbWEsIGxheW91dE5vZGU6IGFueSA9IG51bGwpIHtcclxuICBpZiAoIWlzU3RyaW5nKGNvbnRyb2xUeXBlKSB8fCAoXHJcbiAgICBjb250cm9sVHlwZS5zbGljZSgwLCA4KSAhPT0gJ2NoZWNrYm94JyAmJiBjb250cm9sVHlwZS5zbGljZSgwLCA1KSAhPT0gJ3JhZGlvJ1xyXG4gICkpIHtcclxuICAgIHJldHVybiBjb250cm9sVHlwZTtcclxuICB9XHJcbiAgaWYgKFxyXG4gICAgSnNvblBvaW50ZXIuZ2V0Rmlyc3QoW1xyXG4gICAgICBbbGF5b3V0Tm9kZSwgJy9pbmxpbmUnXSxcclxuICAgICAgW2xheW91dE5vZGUsICcvb3B0aW9ucy9pbmxpbmUnXSxcclxuICAgICAgW3NjaGVtYSwgJy9pbmxpbmUnXSxcclxuICAgICAgW3NjaGVtYSwgJy94LXNjaGVtYS1mb3JtL2lubGluZSddLFxyXG4gICAgICBbc2NoZW1hLCAnL3gtc2NoZW1hLWZvcm0vb3B0aW9ucy9pbmxpbmUnXSxcclxuICAgICAgW3NjaGVtYSwgJy94LXNjaGVtYS1mb3JtL3dpZGdldC9pbmxpbmUnXSxcclxuICAgICAgW3NjaGVtYSwgJy94LXNjaGVtYS1mb3JtL3dpZGdldC9jb21wb25lbnQvaW5saW5lJ10sXHJcbiAgICAgIFtzY2hlbWEsICcveC1zY2hlbWEtZm9ybS93aWRnZXQvY29tcG9uZW50L29wdGlvbnMvaW5saW5lJ10sXHJcbiAgICAgIFtzY2hlbWEsICcvd2lkZ2V0L2lubGluZSddLFxyXG4gICAgICBbc2NoZW1hLCAnL3dpZGdldC9jb21wb25lbnQvaW5saW5lJ10sXHJcbiAgICAgIFtzY2hlbWEsICcvd2lkZ2V0L2NvbXBvbmVudC9vcHRpb25zL2lubGluZSddLFxyXG4gICAgXSkgPT09IHRydWVcclxuICApIHtcclxuICAgIHJldHVybiBjb250cm9sVHlwZS5zbGljZSgwLCA1KSA9PT0gJ3JhZGlvJyA/XHJcbiAgICAgICdyYWRpb3MtaW5saW5lJyA6ICdjaGVja2JveGVzLWlubGluZSc7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBjb250cm9sVHlwZTtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnaXNJbnB1dFJlcXVpcmVkJyBmdW5jdGlvblxyXG4gKlxyXG4gKiBDaGVja3MgYSBKU09OIFNjaGVtYSB0byBzZWUgaWYgYW4gaXRlbSBpcyByZXF1aXJlZFxyXG4gKlxyXG4gKiAvLyAgIHNjaGVtYSAtIHRoZSBzY2hlbWEgdG8gY2hlY2tcclxuICogLy8gIHsgc3RyaW5nIH0gc2NoZW1hUG9pbnRlciAtIHRoZSBwb2ludGVyIHRvIHRoZSBpdGVtIHRvIGNoZWNrXHJcbiAqIC8vIHsgYm9vbGVhbiB9IC0gdHJ1ZSBpZiB0aGUgaXRlbSBpcyByZXF1aXJlZCwgZmFsc2UgaWYgbm90XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNJbnB1dFJlcXVpcmVkKHNjaGVtYSwgc2NoZW1hUG9pbnRlcikge1xyXG4gIGlmICghaXNPYmplY3Qoc2NoZW1hKSkge1xyXG4gICAgY29uc29sZS5lcnJvcignaXNJbnB1dFJlcXVpcmVkIGVycm9yOiBJbnB1dCBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3QuJyk7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG4gIGNvbnN0IGxpc3RQb2ludGVyQXJyYXkgPSBKc29uUG9pbnRlci5wYXJzZShzY2hlbWFQb2ludGVyKTtcclxuICBpZiAoaXNBcnJheShsaXN0UG9pbnRlckFycmF5KSkge1xyXG4gICAgaWYgKCFsaXN0UG9pbnRlckFycmF5Lmxlbmd0aCkgeyByZXR1cm4gc2NoZW1hLnJlcXVpcmVkID09PSB0cnVlOyB9XHJcbiAgICBjb25zdCBrZXlOYW1lID0gbGlzdFBvaW50ZXJBcnJheS5wb3AoKTtcclxuICAgIGNvbnN0IG5leHRUb0xhc3RLZXkgPSBsaXN0UG9pbnRlckFycmF5W2xpc3RQb2ludGVyQXJyYXkubGVuZ3RoIC0gMV07XHJcbiAgICBpZiAoWydwcm9wZXJ0aWVzJywgJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJywgJ3BhdHRlcm5Qcm9wZXJ0aWVzJywgJ2l0ZW1zJywgJ2FkZGl0aW9uYWxJdGVtcyddXHJcbiAgICAgIC5pbmNsdWRlcyhuZXh0VG9MYXN0S2V5KVxyXG4gICAgKSB7XHJcbiAgICAgIGxpc3RQb2ludGVyQXJyYXkucG9wKCk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBwYXJlbnRTY2hlbWEgPSBKc29uUG9pbnRlci5nZXQoc2NoZW1hLCBsaXN0UG9pbnRlckFycmF5KSB8fCB7fTtcclxuICAgIGlmIChpc0FycmF5KHBhcmVudFNjaGVtYS5yZXF1aXJlZCkpIHtcclxuICAgICAgcmV0dXJuIHBhcmVudFNjaGVtYS5yZXF1aXJlZC5pbmNsdWRlcyhrZXlOYW1lKTtcclxuICAgIH1cclxuICAgIGlmIChwYXJlbnRTY2hlbWEudHlwZSA9PT0gJ2FycmF5Jykge1xyXG4gICAgICByZXR1cm4gaGFzT3duKHBhcmVudFNjaGVtYSwgJ21pbkl0ZW1zJykgJiZcclxuICAgICAgICBpc051bWJlcihrZXlOYW1lKSAmJlxyXG4gICAgICAgICtwYXJlbnRTY2hlbWEubWluSXRlbXMgPiAra2V5TmFtZTtcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIGZhbHNlO1xyXG59XHJcblxyXG4vKipcclxuICogJ3VwZGF0ZUlucHV0T3B0aW9ucycgZnVuY3Rpb25cclxuICpcclxuICogLy8gICBsYXlvdXROb2RlXHJcbiAqIC8vICAgc2NoZW1hXHJcbiAqIC8vICAganNmXHJcbiAqIC8vIHsgdm9pZCB9XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlSW5wdXRPcHRpb25zKGxheW91dE5vZGUsIHNjaGVtYSwganNmKSB7XHJcbiAgaWYgKCFpc09iamVjdChsYXlvdXROb2RlKSB8fCAhaXNPYmplY3QobGF5b3V0Tm9kZS5vcHRpb25zKSkgeyByZXR1cm47IH1cclxuXHJcbiAgLy8gU2V0IGFsbCBvcHRpb24gdmFsdWVzIGluIGxheW91dE5vZGUub3B0aW9uc1xyXG4gIGNvbnN0IG5ld09wdGlvbnM6IGFueSA9IHsgfTtcclxuICBjb25zdCBmaXhVaUtleXMgPSBrZXkgPT4ga2V5LnNsaWNlKDAsIDMpLnRvTG93ZXJDYXNlKCkgPT09ICd1aTonID8ga2V5LnNsaWNlKDMpIDoga2V5O1xyXG4gIG1lcmdlRmlsdGVyZWRPYmplY3QobmV3T3B0aW9ucywganNmLmZvcm1PcHRpb25zLmRlZmF1bHRXaWRnZXRPcHRpb25zLCBbXSwgZml4VWlLZXlzKTtcclxuICBbIFsgSnNvblBvaW50ZXIuZ2V0KHNjaGVtYSwgJy91aTp3aWRnZXQvb3B0aW9ucycpLCBbXSBdLFxyXG4gICAgWyBKc29uUG9pbnRlci5nZXQoc2NoZW1hLCAnL3VpOndpZGdldCcpLCBbXSBdLFxyXG4gICAgWyBzY2hlbWEsIFtcclxuICAgICAgJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJywgJ2FkZGl0aW9uYWxJdGVtcycsICdwcm9wZXJ0aWVzJywgJ2l0ZW1zJyxcclxuICAgICAgJ3JlcXVpcmVkJywgJ3R5cGUnLCAneC1zY2hlbWEtZm9ybScsICckcmVmJ1xyXG4gICAgXSBdLFxyXG4gICAgWyBKc29uUG9pbnRlci5nZXQoc2NoZW1hLCAnL3gtc2NoZW1hLWZvcm0vb3B0aW9ucycpLCBbXSBdLFxyXG4gICAgWyBKc29uUG9pbnRlci5nZXQoc2NoZW1hLCAnL3gtc2NoZW1hLWZvcm0nKSwgWydpdGVtcycsICdvcHRpb25zJ10gXSxcclxuICAgIFsgbGF5b3V0Tm9kZSwgW1xyXG4gICAgICAnX2lkJywgJyRyZWYnLCAnYXJyYXlJdGVtJywgJ2FycmF5SXRlbVR5cGUnLCAnZGF0YVBvaW50ZXInLCAnZGF0YVR5cGUnLFxyXG4gICAgICAnaXRlbXMnLCAna2V5JywgJ25hbWUnLCAnb3B0aW9ucycsICdyZWN1cnNpdmVSZWZlcmVuY2UnLCAndHlwZScsICd3aWRnZXQnXHJcbiAgICBdIF0sXHJcbiAgICBbIGxheW91dE5vZGUub3B0aW9ucywgW10gXSxcclxuICBdLmZvckVhY2goKFsgb2JqZWN0LCBleGNsdWRlS2V5cyBdKSA9PlxyXG4gICAgbWVyZ2VGaWx0ZXJlZE9iamVjdChuZXdPcHRpb25zLCBvYmplY3QsIGV4Y2x1ZGVLZXlzLCBmaXhVaUtleXMpXHJcbiAgKTtcclxuICBpZiAoIWhhc093bihuZXdPcHRpb25zLCAndGl0bGVNYXAnKSkge1xyXG4gICAgbGV0IG5ld1RpdGxlTWFwOiBhbnkgPSBudWxsO1xyXG4gICAgbmV3VGl0bGVNYXAgPSBnZXRUaXRsZU1hcEZyb21PbmVPZihzY2hlbWEsIG5ld09wdGlvbnMuZmxhdExpc3QpO1xyXG4gICAgaWYgKG5ld1RpdGxlTWFwKSB7IG5ld09wdGlvbnMudGl0bGVNYXAgPSBuZXdUaXRsZU1hcDsgfVxyXG4gICAgaWYgKCFoYXNPd24obmV3T3B0aW9ucywgJ3RpdGxlTWFwJykgJiYgIWhhc093bihuZXdPcHRpb25zLCAnZW51bScpICYmIGhhc093bihzY2hlbWEsICdpdGVtcycpKSB7XHJcbiAgICAgIGlmIChKc29uUG9pbnRlci5oYXMoc2NoZW1hLCAnL2l0ZW1zL3RpdGxlTWFwJykpIHtcclxuICAgICAgICBuZXdPcHRpb25zLnRpdGxlTWFwID0gc2NoZW1hLml0ZW1zLnRpdGxlTWFwO1xyXG4gICAgICB9IGVsc2UgaWYgKEpzb25Qb2ludGVyLmhhcyhzY2hlbWEsICcvaXRlbXMvZW51bScpKSB7XHJcbiAgICAgICAgbmV3T3B0aW9ucy5lbnVtID0gc2NoZW1hLml0ZW1zLmVudW07XHJcbiAgICAgICAgaWYgKCFoYXNPd24obmV3T3B0aW9ucywgJ2VudW1OYW1lcycpICYmIEpzb25Qb2ludGVyLmhhcyhzY2hlbWEsICcvaXRlbXMvZW51bU5hbWVzJykpIHtcclxuICAgICAgICAgIG5ld09wdGlvbnMuZW51bU5hbWVzID0gc2NoZW1hLml0ZW1zLmVudW1OYW1lcztcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSBpZiAoSnNvblBvaW50ZXIuaGFzKHNjaGVtYSwgJy9pdGVtcy9vbmVPZicpKSB7XHJcbiAgICAgICAgbmV3VGl0bGVNYXAgPSBnZXRUaXRsZU1hcEZyb21PbmVPZihzY2hlbWEuaXRlbXMsIG5ld09wdGlvbnMuZmxhdExpc3QpO1xyXG4gICAgICAgIGlmIChuZXdUaXRsZU1hcCkgeyBuZXdPcHRpb25zLnRpdGxlTWFwID0gbmV3VGl0bGVNYXA7IH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gSWYgc2NoZW1hIHR5cGUgaXMgaW50ZWdlciwgZW5mb3JjZSBieSBzZXR0aW5nIG11bHRpcGxlT2YgPSAxXHJcbiAgaWYgKHNjaGVtYS50eXBlID09PSAnaW50ZWdlcicgJiYgIWhhc1ZhbHVlKG5ld09wdGlvbnMubXVsdGlwbGVPZikpIHtcclxuICAgIG5ld09wdGlvbnMubXVsdGlwbGVPZiA9IDE7XHJcbiAgfVxyXG5cclxuICAvLyBDb3B5IGFueSB0eXBlYWhlYWQgd29yZCBsaXN0cyB0byBvcHRpb25zLnR5cGVhaGVhZC5zb3VyY2VcclxuICBpZiAoSnNvblBvaW50ZXIuaGFzKG5ld09wdGlvbnMsICcvYXV0b2NvbXBsZXRlL3NvdXJjZScpKSB7XHJcbiAgICBuZXdPcHRpb25zLnR5cGVhaGVhZCA9IG5ld09wdGlvbnMuYXV0b2NvbXBsZXRlO1xyXG4gIH0gZWxzZSBpZiAoSnNvblBvaW50ZXIuaGFzKG5ld09wdGlvbnMsICcvdGFnc2lucHV0L3NvdXJjZScpKSB7XHJcbiAgICBuZXdPcHRpb25zLnR5cGVhaGVhZCA9IG5ld09wdGlvbnMudGFnc2lucHV0O1xyXG4gIH0gZWxzZSBpZiAoSnNvblBvaW50ZXIuaGFzKG5ld09wdGlvbnMsICcvdGFnc2lucHV0L3R5cGVhaGVhZC9zb3VyY2UnKSkge1xyXG4gICAgbmV3T3B0aW9ucy50eXBlYWhlYWQgPSBuZXdPcHRpb25zLnRhZ3NpbnB1dC50eXBlYWhlYWQ7XHJcbiAgfVxyXG5cclxuICBsYXlvdXROb2RlLm9wdGlvbnMgPSBuZXdPcHRpb25zO1xyXG59XHJcblxyXG4vKipcclxuICogJ2dldFRpdGxlTWFwRnJvbU9uZU9mJyBmdW5jdGlvblxyXG4gKlxyXG4gKiAvLyAgeyBzY2hlbWEgfSBzY2hlbWFcclxuICogLy8gIHsgYm9vbGVhbiA9IG51bGwgfSBmbGF0TGlzdFxyXG4gKiAvLyAgeyBib29sZWFuID0gZmFsc2UgfSB2YWxpZGF0ZU9ubHlcclxuICogLy8geyB2YWxpZGF0b3JzIH1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRUaXRsZU1hcEZyb21PbmVPZihcclxuICBzY2hlbWE6IGFueSA9IHt9LCBmbGF0TGlzdDogYm9vbGVhbiA9IG51bGwsIHZhbGlkYXRlT25seSA9IGZhbHNlXHJcbikge1xyXG4gIGxldCB0aXRsZU1hcCA9IG51bGw7XHJcbiAgY29uc3Qgb25lT2YgPSBzY2hlbWEub25lT2YgfHwgc2NoZW1hLmFueU9mIHx8IG51bGw7XHJcbiAgaWYgKGlzQXJyYXkob25lT2YpICYmIG9uZU9mLmV2ZXJ5KGl0ZW0gPT4gaXRlbS50aXRsZSkpIHtcclxuICAgIGlmIChvbmVPZi5ldmVyeShpdGVtID0+IGlzQXJyYXkoaXRlbS5lbnVtKSAmJiBpdGVtLmVudW0ubGVuZ3RoID09PSAxKSkge1xyXG4gICAgICBpZiAodmFsaWRhdGVPbmx5KSB7IHJldHVybiB0cnVlOyB9XHJcbiAgICAgIHRpdGxlTWFwID0gb25lT2YubWFwKGl0ZW0gPT4gKHsgbmFtZTogaXRlbS50aXRsZSwgdmFsdWU6IGl0ZW0uZW51bVswXSB9KSk7XHJcbiAgICB9IGVsc2UgaWYgKG9uZU9mLmV2ZXJ5KGl0ZW0gPT4gaXRlbS5jb25zdCkpIHtcclxuICAgICAgaWYgKHZhbGlkYXRlT25seSkgeyByZXR1cm4gdHJ1ZTsgfVxyXG4gICAgICB0aXRsZU1hcCA9IG9uZU9mLm1hcChpdGVtID0+ICh7IG5hbWU6IGl0ZW0udGl0bGUsIHZhbHVlOiBpdGVtLmNvbnN0IH0pKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBpZiBmbGF0TGlzdCAhPT0gZmFsc2UgYW5kIHNvbWUgaXRlbXMgaGF2ZSBjb2xvbnMsIG1ha2UgZ3JvdXBlZCBtYXBcclxuICAgIGlmIChmbGF0TGlzdCAhPT0gZmFsc2UgJiYgKHRpdGxlTWFwIHx8IFtdKVxyXG4gICAgICAuZmlsdGVyKHRpdGxlID0+ICgodGl0bGUgfHwge30pLm5hbWUgfHwgJycpLmluZGV4T2YoJzogJykpLmxlbmd0aCA+IDFcclxuICAgICkge1xyXG5cclxuICAgICAgLy8gU3BsaXQgbmFtZSBvbiBmaXJzdCBjb2xvbiB0byBjcmVhdGUgZ3JvdXBlZCBtYXAgKG5hbWUgLT4gZ3JvdXA6IG5hbWUpXHJcbiAgICAgIGNvbnN0IG5ld1RpdGxlTWFwID0gdGl0bGVNYXAubWFwKHRpdGxlID0+IHtcclxuICAgICAgICBjb25zdCBbZ3JvdXAsIG5hbWVdID0gdGl0bGUubmFtZS5zcGxpdCgvOiAoLispLyk7XHJcbiAgICAgICAgcmV0dXJuIGdyb3VwICYmIG5hbWUgPyB7IC4uLnRpdGxlLCBncm91cCwgbmFtZSB9IDogdGl0bGU7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gSWYgZmxhdExpc3QgPT09IHRydWUgb3IgYXQgbGVhc3Qgb25lIGdyb3VwIGhhcyBtdWx0aXBsZSBpdGVtcywgdXNlIGdyb3VwZWQgbWFwXHJcbiAgICAgIGlmIChmbGF0TGlzdCA9PT0gdHJ1ZSB8fCBuZXdUaXRsZU1hcC5zb21lKCh0aXRsZSwgaW5kZXgpID0+IGluZGV4ICYmXHJcbiAgICAgICAgaGFzT3duKHRpdGxlLCAnZ3JvdXAnKSAmJiB0aXRsZS5ncm91cCA9PT0gbmV3VGl0bGVNYXBbaW5kZXggLSAxXS5ncm91cFxyXG4gICAgICApKSB7XHJcbiAgICAgICAgdGl0bGVNYXAgPSBuZXdUaXRsZU1hcDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gdmFsaWRhdGVPbmx5ID8gZmFsc2UgOiB0aXRsZU1hcDtcclxufVxyXG5cclxuLyoqXHJcbiAqICdnZXRDb250cm9sVmFsaWRhdG9ycycgZnVuY3Rpb25cclxuICpcclxuICogLy8gIHNjaGVtYVxyXG4gKiAvLyB7IHZhbGlkYXRvcnMgfVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbnRyb2xWYWxpZGF0b3JzKHNjaGVtYSkge1xyXG4gIGlmICghaXNPYmplY3Qoc2NoZW1hKSkgeyByZXR1cm4gbnVsbDsgfVxyXG4gIGNvbnN0IHZhbGlkYXRvcnM6IGFueSA9IHsgfTtcclxuICBpZiAoaGFzT3duKHNjaGVtYSwgJ3R5cGUnKSkge1xyXG4gICAgc3dpdGNoIChzY2hlbWEudHlwZSkge1xyXG4gICAgICBjYXNlICdzdHJpbmcnOlxyXG4gICAgICAgIGZvckVhY2goWydwYXR0ZXJuJywgJ2Zvcm1hdCcsICdtaW5MZW5ndGgnLCAnbWF4TGVuZ3RoJ10sIChwcm9wKSA9PiB7XHJcbiAgICAgICAgICBpZiAoaGFzT3duKHNjaGVtYSwgcHJvcCkpIHsgdmFsaWRhdG9yc1twcm9wXSA9IFtzY2hlbWFbcHJvcF1dOyB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdudW1iZXInOiBjYXNlICdpbnRlZ2VyJzpcclxuICAgICAgICBmb3JFYWNoKFsnTWluaW11bScsICdNYXhpbXVtJ10sICh1Y0xpbWl0KSA9PiB7XHJcbiAgICAgICAgICBjb25zdCBlTGltaXQgPSAnZXhjbHVzaXZlJyArIHVjTGltaXQ7XHJcbiAgICAgICAgICBjb25zdCBsaW1pdCA9IHVjTGltaXQudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICAgIGlmIChoYXNPd24oc2NoZW1hLCBsaW1pdCkpIHtcclxuICAgICAgICAgICAgY29uc3QgZXhjbHVzaXZlID0gaGFzT3duKHNjaGVtYSwgZUxpbWl0KSAmJiBzY2hlbWFbZUxpbWl0XSA9PT0gdHJ1ZTtcclxuICAgICAgICAgICAgdmFsaWRhdG9yc1tsaW1pdF0gPSBbc2NoZW1hW2xpbWl0XSwgZXhjbHVzaXZlXTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBmb3JFYWNoKFsnbXVsdGlwbGVPZicsICd0eXBlJ10sIChwcm9wKSA9PiB7XHJcbiAgICAgICAgICBpZiAoaGFzT3duKHNjaGVtYSwgcHJvcCkpIHsgdmFsaWRhdG9yc1twcm9wXSA9IFtzY2hlbWFbcHJvcF1dOyB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdvYmplY3QnOlxyXG4gICAgICAgIGZvckVhY2goWydtaW5Qcm9wZXJ0aWVzJywgJ21heFByb3BlcnRpZXMnLCAnZGVwZW5kZW5jaWVzJ10sIChwcm9wKSA9PiB7XHJcbiAgICAgICAgICBpZiAoaGFzT3duKHNjaGVtYSwgcHJvcCkpIHsgdmFsaWRhdG9yc1twcm9wXSA9IFtzY2hlbWFbcHJvcF1dOyB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdhcnJheSc6XHJcbiAgICAgICAgZm9yRWFjaChbJ21pbkl0ZW1zJywgJ21heEl0ZW1zJywgJ3VuaXF1ZUl0ZW1zJ10sIChwcm9wKSA9PiB7XHJcbiAgICAgICAgICBpZiAoaGFzT3duKHNjaGVtYSwgcHJvcCkpIHsgdmFsaWRhdG9yc1twcm9wXSA9IFtzY2hlbWFbcHJvcF1dOyB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gIH1cclxuICBpZiAoaGFzT3duKHNjaGVtYSwgJ2VudW0nKSkgeyB2YWxpZGF0b3JzLmVudW0gPSBbc2NoZW1hLmVudW1dOyB9XHJcbiAgcmV0dXJuIHZhbGlkYXRvcnM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAncmVzb2x2ZVNjaGVtYVJlZmVyZW5jZXMnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIEZpbmQgYWxsICRyZWYgbGlua3MgaW4gc2NoZW1hIGFuZCBzYXZlIGxpbmtzIGFuZCByZWZlcmVuY2VkIHNjaGVtYXMgaW5cclxuICogc2NoZW1hUmVmTGlicmFyeSwgc2NoZW1hUmVjdXJzaXZlUmVmTWFwLCBhbmQgZGF0YVJlY3Vyc2l2ZVJlZk1hcFxyXG4gKlxyXG4gKiAvLyAgc2NoZW1hXHJcbiAqIC8vICBzY2hlbWFSZWZMaWJyYXJ5XHJcbiAqIC8vIHsgTWFwPHN0cmluZywgc3RyaW5nPiB9IHNjaGVtYVJlY3Vyc2l2ZVJlZk1hcFxyXG4gKiAvLyB7IE1hcDxzdHJpbmcsIHN0cmluZz4gfSBkYXRhUmVjdXJzaXZlUmVmTWFwXHJcbiAqIC8vIHsgTWFwPHN0cmluZywgbnVtYmVyPiB9IGFycmF5TWFwXHJcbiAqIC8vXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVNjaGVtYVJlZmVyZW5jZXMoXHJcbiAgc2NoZW1hLCBzY2hlbWFSZWZMaWJyYXJ5LCBzY2hlbWFSZWN1cnNpdmVSZWZNYXAsIGRhdGFSZWN1cnNpdmVSZWZNYXAsIGFycmF5TWFwXHJcbikge1xyXG4gIGlmICghaXNPYmplY3Qoc2NoZW1hKSkge1xyXG4gICAgY29uc29sZS5lcnJvcigncmVzb2x2ZVNjaGVtYVJlZmVyZW5jZXMgZXJyb3I6IHNjaGVtYSBtdXN0IGJlIGFuIG9iamVjdC4nKTtcclxuICAgIHJldHVybjtcclxuICB9XHJcbiAgY29uc3QgcmVmTGlua3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuICBjb25zdCByZWZNYXBTZXQgPSBuZXcgU2V0PHN0cmluZz4oKTtcclxuICBjb25zdCByZWZNYXAgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xyXG4gIGNvbnN0IHJlY3Vyc2l2ZVJlZk1hcCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XHJcbiAgY29uc3QgcmVmTGlicmFyeTogYW55ID0ge307XHJcblxyXG4gIC8vIFNlYXJjaCBzY2hlbWEgZm9yIGFsbCAkcmVmIGxpbmtzLCBhbmQgYnVpbGQgZnVsbCByZWZMaWJyYXJ5XHJcbiAgSnNvblBvaW50ZXIuZm9yRWFjaERlZXAoc2NoZW1hLCAoc3ViU2NoZW1hLCBzdWJTY2hlbWFQb2ludGVyKSA9PiB7XHJcbiAgICBpZiAoaGFzT3duKHN1YlNjaGVtYSwgJyRyZWYnKSAmJiBpc1N0cmluZyhzdWJTY2hlbWFbJyRyZWYnXSkpIHtcclxuICAgICAgY29uc3QgcmVmUG9pbnRlciA9IEpzb25Qb2ludGVyLmNvbXBpbGUoc3ViU2NoZW1hWyckcmVmJ10pO1xyXG4gICAgICByZWZMaW5rcy5hZGQocmVmUG9pbnRlcik7XHJcbiAgICAgIHJlZk1hcFNldC5hZGQoc3ViU2NoZW1hUG9pbnRlciArICd+ficgKyByZWZQb2ludGVyKTtcclxuICAgICAgcmVmTWFwLnNldChzdWJTY2hlbWFQb2ludGVyLCByZWZQb2ludGVyKTtcclxuICAgIH1cclxuICB9KTtcclxuICByZWZMaW5rcy5mb3JFYWNoKHJlZiA9PiByZWZMaWJyYXJ5W3JlZl0gPSBnZXRTdWJTY2hlbWEoc2NoZW1hLCByZWYpKTtcclxuXHJcbiAgLy8gRm9sbG93IGFsbCByZWYgbGlua3MgYW5kIHNhdmUgaW4gcmVmTWFwU2V0LFxyXG4gIC8vIHRvIGZpbmQgYW55IG11bHRpLWxpbmsgcmVjdXJzaXZlIHJlZmVybmNlc1xyXG4gIGxldCBjaGVja1JlZkxpbmtzID0gdHJ1ZTtcclxuICB3aGlsZSAoY2hlY2tSZWZMaW5rcykge1xyXG4gICAgY2hlY2tSZWZMaW5rcyA9IGZhbHNlO1xyXG4gICAgQXJyYXkuZnJvbShyZWZNYXApLmZvckVhY2goKFtmcm9tUmVmMSwgdG9SZWYxXSkgPT4gQXJyYXkuZnJvbShyZWZNYXApXHJcbiAgICAgIC5maWx0ZXIoKFtmcm9tUmVmMiwgdG9SZWYyXSkgPT5cclxuICAgICAgICBKc29uUG9pbnRlci5pc1N1YlBvaW50ZXIodG9SZWYxLCBmcm9tUmVmMiwgdHJ1ZSkgJiZcclxuICAgICAgICAhSnNvblBvaW50ZXIuaXNTdWJQb2ludGVyKHRvUmVmMiwgdG9SZWYxLCB0cnVlKSAmJlxyXG4gICAgICAgICFyZWZNYXBTZXQuaGFzKGZyb21SZWYxICsgZnJvbVJlZjIuc2xpY2UodG9SZWYxLmxlbmd0aCkgKyAnfn4nICsgdG9SZWYyKVxyXG4gICAgICApXHJcbiAgICAgIC5mb3JFYWNoKChbZnJvbVJlZjIsIHRvUmVmMl0pID0+IHtcclxuICAgICAgICByZWZNYXBTZXQuYWRkKGZyb21SZWYxICsgZnJvbVJlZjIuc2xpY2UodG9SZWYxLmxlbmd0aCkgKyAnfn4nICsgdG9SZWYyKTtcclxuICAgICAgICBjaGVja1JlZkxpbmtzID0gdHJ1ZTtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvLyBCdWlsZCBmdWxsIHJlY3Vyc2l2ZVJlZk1hcFxyXG4gIC8vIEZpcnN0IHBhc3MgLSBzYXZlIGFsbCBpbnRlcm5hbGx5IHJlY3Vyc2l2ZSByZWZzIGZyb20gcmVmTWFwU2V0XHJcbiAgQXJyYXkuZnJvbShyZWZNYXBTZXQpXHJcbiAgICAubWFwKHJlZkxpbmsgPT4gcmVmTGluay5zcGxpdCgnfn4nKSlcclxuICAgIC5maWx0ZXIoKFtmcm9tUmVmLCB0b1JlZl0pID0+IEpzb25Qb2ludGVyLmlzU3ViUG9pbnRlcih0b1JlZiwgZnJvbVJlZikpXHJcbiAgICAuZm9yRWFjaCgoW2Zyb21SZWYsIHRvUmVmXSkgPT4gcmVjdXJzaXZlUmVmTWFwLnNldChmcm9tUmVmLCB0b1JlZikpO1xyXG4gIC8vIFNlY29uZCBwYXNzIC0gY3JlYXRlIHJlY3Vyc2l2ZSB2ZXJzaW9ucyBvZiBhbnkgb3RoZXIgcmVmcyB0aGF0IGxpbmsgdG8gcmVjdXJzaXZlIHJlZnNcclxuICBBcnJheS5mcm9tKHJlZk1hcClcclxuICAgIC5maWx0ZXIoKFtmcm9tUmVmMSwgdG9SZWYxXSkgPT4gQXJyYXkuZnJvbShyZWN1cnNpdmVSZWZNYXAua2V5cygpKVxyXG4gICAgICAuZXZlcnkoZnJvbVJlZjIgPT4gIUpzb25Qb2ludGVyLmlzU3ViUG9pbnRlcihmcm9tUmVmMSwgZnJvbVJlZjIsIHRydWUpKVxyXG4gICAgKVxyXG4gICAgLmZvckVhY2goKFtmcm9tUmVmMSwgdG9SZWYxXSkgPT4gQXJyYXkuZnJvbShyZWN1cnNpdmVSZWZNYXApXHJcbiAgICAgIC5maWx0ZXIoKFtmcm9tUmVmMiwgdG9SZWYyXSkgPT5cclxuICAgICAgICAhcmVjdXJzaXZlUmVmTWFwLmhhcyhmcm9tUmVmMSArIGZyb21SZWYyLnNsaWNlKHRvUmVmMS5sZW5ndGgpKSAmJlxyXG4gICAgICAgIEpzb25Qb2ludGVyLmlzU3ViUG9pbnRlcih0b1JlZjEsIGZyb21SZWYyLCB0cnVlKSAmJlxyXG4gICAgICAgICFKc29uUG9pbnRlci5pc1N1YlBvaW50ZXIodG9SZWYxLCBmcm9tUmVmMSwgdHJ1ZSlcclxuICAgICAgKVxyXG4gICAgICAuZm9yRWFjaCgoW2Zyb21SZWYyLCB0b1JlZjJdKSA9PiByZWN1cnNpdmVSZWZNYXAuc2V0KFxyXG4gICAgICAgIGZyb21SZWYxICsgZnJvbVJlZjIuc2xpY2UodG9SZWYxLmxlbmd0aCksXHJcbiAgICAgICAgZnJvbVJlZjEgKyB0b1JlZjIuc2xpY2UodG9SZWYxLmxlbmd0aClcclxuICAgICAgKSlcclxuICAgICk7XHJcblxyXG4gIC8vIENyZWF0ZSBjb21waWxlZCBzY2hlbWEgYnkgcmVwbGFjaW5nIGFsbCBub24tcmVjdXJzaXZlICRyZWYgbGlua3Mgd2l0aFxyXG4gIC8vIHRoaWVpciBsaW5rZWQgc2NoZW1hcyBhbmQsIHdoZXJlIHBvc3NpYmxlLCBjb21iaW5pbmcgc2NoZW1hcyBpbiBhbGxPZiBhcnJheXMuXHJcbiAgbGV0IGNvbXBpbGVkU2NoZW1hID0geyAuLi5zY2hlbWEgfTtcclxuICBkZWxldGUgY29tcGlsZWRTY2hlbWEuZGVmaW5pdGlvbnM7XHJcbiAgY29tcGlsZWRTY2hlbWEgPVxyXG4gICAgZ2V0U3ViU2NoZW1hKGNvbXBpbGVkU2NoZW1hLCAnJywgcmVmTGlicmFyeSwgcmVjdXJzaXZlUmVmTWFwKTtcclxuXHJcbiAgLy8gTWFrZSBzdXJlIGFsbCByZW1haW5pbmcgc2NoZW1hICRyZWZzIGFyZSByZWN1cnNpdmUsIGFuZCBidWlsZCBmaW5hbFxyXG4gIC8vIHNjaGVtYVJlZkxpYnJhcnksIHNjaGVtYVJlY3Vyc2l2ZVJlZk1hcCwgZGF0YVJlY3Vyc2l2ZVJlZk1hcCwgJiBhcnJheU1hcFxyXG4gIEpzb25Qb2ludGVyLmZvckVhY2hEZWVwKGNvbXBpbGVkU2NoZW1hLCAoc3ViU2NoZW1hLCBzdWJTY2hlbWFQb2ludGVyKSA9PiB7XHJcbiAgICBpZiAoaXNTdHJpbmcoc3ViU2NoZW1hWyckcmVmJ10pKSB7XHJcbiAgICAgIGxldCByZWZQb2ludGVyID0gSnNvblBvaW50ZXIuY29tcGlsZShzdWJTY2hlbWFbJyRyZWYnXSk7XHJcbiAgICAgIGlmICghSnNvblBvaW50ZXIuaXNTdWJQb2ludGVyKHJlZlBvaW50ZXIsIHN1YlNjaGVtYVBvaW50ZXIsIHRydWUpKSB7XHJcbiAgICAgICAgcmVmUG9pbnRlciA9IHJlbW92ZVJlY3Vyc2l2ZVJlZmVyZW5jZXMoc3ViU2NoZW1hUG9pbnRlciwgcmVjdXJzaXZlUmVmTWFwKTtcclxuICAgICAgICBKc29uUG9pbnRlci5zZXQoY29tcGlsZWRTY2hlbWEsIHN1YlNjaGVtYVBvaW50ZXIsIHsgJHJlZjogYCMke3JlZlBvaW50ZXJ9YCB9KTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoIWhhc093bihzY2hlbWFSZWZMaWJyYXJ5LCAncmVmUG9pbnRlcicpKSB7XHJcbiAgICAgICAgc2NoZW1hUmVmTGlicmFyeVtyZWZQb2ludGVyXSA9ICFyZWZQb2ludGVyLmxlbmd0aCA/IGNvbXBpbGVkU2NoZW1hIDpcclxuICAgICAgICAgIGdldFN1YlNjaGVtYShjb21waWxlZFNjaGVtYSwgcmVmUG9pbnRlciwgc2NoZW1hUmVmTGlicmFyeSwgcmVjdXJzaXZlUmVmTWFwKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoIXNjaGVtYVJlY3Vyc2l2ZVJlZk1hcC5oYXMoc3ViU2NoZW1hUG9pbnRlcikpIHtcclxuICAgICAgICBzY2hlbWFSZWN1cnNpdmVSZWZNYXAuc2V0KHN1YlNjaGVtYVBvaW50ZXIsIHJlZlBvaW50ZXIpO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IGZyb21EYXRhUmVmID0gSnNvblBvaW50ZXIudG9EYXRhUG9pbnRlcihzdWJTY2hlbWFQb2ludGVyLCBjb21waWxlZFNjaGVtYSk7XHJcbiAgICAgIGlmICghZGF0YVJlY3Vyc2l2ZVJlZk1hcC5oYXMoZnJvbURhdGFSZWYpKSB7XHJcbiAgICAgICAgY29uc3QgdG9EYXRhUmVmID0gSnNvblBvaW50ZXIudG9EYXRhUG9pbnRlcihyZWZQb2ludGVyLCBjb21waWxlZFNjaGVtYSk7XHJcbiAgICAgICAgZGF0YVJlY3Vyc2l2ZVJlZk1hcC5zZXQoZnJvbURhdGFSZWYsIHRvRGF0YVJlZik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChzdWJTY2hlbWEudHlwZSA9PT0gJ2FycmF5JyAmJlxyXG4gICAgICAoaGFzT3duKHN1YlNjaGVtYSwgJ2l0ZW1zJykgfHwgaGFzT3duKHN1YlNjaGVtYSwgJ2FkZGl0aW9uYWxJdGVtcycpKVxyXG4gICAgKSB7XHJcbiAgICAgIGNvbnN0IGRhdGFQb2ludGVyID0gSnNvblBvaW50ZXIudG9EYXRhUG9pbnRlcihzdWJTY2hlbWFQb2ludGVyLCBjb21waWxlZFNjaGVtYSk7XHJcbiAgICAgIGlmICghYXJyYXlNYXAuaGFzKGRhdGFQb2ludGVyKSkge1xyXG4gICAgICAgIGNvbnN0IHR1cGxlSXRlbXMgPSBpc0FycmF5KHN1YlNjaGVtYS5pdGVtcykgPyBzdWJTY2hlbWEuaXRlbXMubGVuZ3RoIDogMDtcclxuICAgICAgICBhcnJheU1hcC5zZXQoZGF0YVBvaW50ZXIsIHR1cGxlSXRlbXMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSwgdHJ1ZSk7XHJcbiAgcmV0dXJuIGNvbXBpbGVkU2NoZW1hO1xyXG59XHJcblxyXG4vKipcclxuICogJ2dldFN1YlNjaGVtYScgZnVuY3Rpb25cclxuICpcclxuICogLy8gICBzY2hlbWFcclxuICogLy8gIHsgUG9pbnRlciB9IHBvaW50ZXJcclxuICogLy8gIHsgb2JqZWN0IH0gc2NoZW1hUmVmTGlicmFyeVxyXG4gKiAvLyAgeyBNYXA8c3RyaW5nLCBzdHJpbmc+IH0gc2NoZW1hUmVjdXJzaXZlUmVmTWFwXHJcbiAqIC8vICB7IHN0cmluZ1tdID0gW10gfSB1c2VkUG9pbnRlcnNcclxuICogLy9cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRTdWJTY2hlbWEoXHJcbiAgc2NoZW1hLCBwb2ludGVyLCBzY2hlbWFSZWZMaWJyYXJ5ID0gbnVsbCxcclxuICBzY2hlbWFSZWN1cnNpdmVSZWZNYXA6IE1hcDxzdHJpbmcsIHN0cmluZz4gPSBudWxsLCB1c2VkUG9pbnRlcnM6IHN0cmluZ1tdID0gW11cclxuKSB7XHJcbiAgaWYgKCFzY2hlbWFSZWZMaWJyYXJ5IHx8ICFzY2hlbWFSZWN1cnNpdmVSZWZNYXApIHtcclxuICAgIHJldHVybiBKc29uUG9pbnRlci5nZXRDb3B5KHNjaGVtYSwgcG9pbnRlcik7XHJcbiAgfVxyXG4gIGlmICh0eXBlb2YgcG9pbnRlciAhPT0gJ3N0cmluZycpIHsgcG9pbnRlciA9IEpzb25Qb2ludGVyLmNvbXBpbGUocG9pbnRlcik7IH1cclxuICB1c2VkUG9pbnRlcnMgPSBbIC4uLnVzZWRQb2ludGVycywgcG9pbnRlciBdO1xyXG4gIGxldCBuZXdTY2hlbWE6IGFueSA9IG51bGw7XHJcbiAgaWYgKHBvaW50ZXIgPT09ICcnKSB7XHJcbiAgICBuZXdTY2hlbWEgPSBjbG9uZURlZXAoc2NoZW1hKTtcclxuICB9IGVsc2Uge1xyXG4gICAgY29uc3Qgc2hvcnRQb2ludGVyID0gcmVtb3ZlUmVjdXJzaXZlUmVmZXJlbmNlcyhwb2ludGVyLCBzY2hlbWFSZWN1cnNpdmVSZWZNYXApO1xyXG4gICAgaWYgKHNob3J0UG9pbnRlciAhPT0gcG9pbnRlcikgeyB1c2VkUG9pbnRlcnMgPSBbIC4uLnVzZWRQb2ludGVycywgc2hvcnRQb2ludGVyIF07IH1cclxuICAgIG5ld1NjaGVtYSA9IEpzb25Qb2ludGVyLmdldEZpcnN0Q29weShbXHJcbiAgICAgIFtzY2hlbWFSZWZMaWJyYXJ5LCBbc2hvcnRQb2ludGVyXV0sXHJcbiAgICAgIFtzY2hlbWEsIHBvaW50ZXJdLFxyXG4gICAgICBbc2NoZW1hLCBzaG9ydFBvaW50ZXJdXHJcbiAgICBdKTtcclxuICB9XHJcbiAgcmV0dXJuIEpzb25Qb2ludGVyLmZvckVhY2hEZWVwQ29weShuZXdTY2hlbWEsIChzdWJTY2hlbWEsIHN1YlBvaW50ZXIpID0+IHtcclxuICAgIGlmIChpc09iamVjdChzdWJTY2hlbWEpKSB7XHJcblxyXG4gICAgICAvLyBSZXBsYWNlIG5vbi1yZWN1cnNpdmUgJHJlZiBsaW5rcyB3aXRoIHJlZmVyZW5jZWQgc2NoZW1hc1xyXG4gICAgICBpZiAoaXNTdHJpbmcoc3ViU2NoZW1hLiRyZWYpKSB7XHJcbiAgICAgICAgY29uc3QgcmVmUG9pbnRlciA9IEpzb25Qb2ludGVyLmNvbXBpbGUoc3ViU2NoZW1hLiRyZWYpO1xyXG4gICAgICAgIGlmIChyZWZQb2ludGVyLmxlbmd0aCAmJiB1c2VkUG9pbnRlcnMuZXZlcnkocHRyID0+XHJcbiAgICAgICAgICAhSnNvblBvaW50ZXIuaXNTdWJQb2ludGVyKHJlZlBvaW50ZXIsIHB0ciwgdHJ1ZSlcclxuICAgICAgICApKSB7XHJcbiAgICAgICAgICBjb25zdCByZWZTY2hlbWEgPSBnZXRTdWJTY2hlbWEoXHJcbiAgICAgICAgICAgIHNjaGVtYSwgcmVmUG9pbnRlciwgc2NoZW1hUmVmTGlicmFyeSwgc2NoZW1hUmVjdXJzaXZlUmVmTWFwLCB1c2VkUG9pbnRlcnNcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoc3ViU2NoZW1hKS5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHJlZlNjaGVtYTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGV4dHJhS2V5cyA9IHsgLi4uc3ViU2NoZW1hIH07XHJcbiAgICAgICAgICAgIGRlbGV0ZSBleHRyYUtleXMuJHJlZjtcclxuICAgICAgICAgICAgcmV0dXJuIG1lcmdlU2NoZW1hcyhyZWZTY2hlbWEsIGV4dHJhS2V5cyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBUT0RPOiBDb252ZXJ0IHNjaGVtYXMgd2l0aCAndHlwZScgYXJyYXlzIHRvICdvbmVPZidcclxuXHJcbiAgICAgIC8vIENvbWJpbmUgYWxsT2Ygc3ViU2NoZW1hc1xyXG4gICAgICBpZiAoaXNBcnJheShzdWJTY2hlbWEuYWxsT2YpKSB7IHJldHVybiBjb21iaW5lQWxsT2Yoc3ViU2NoZW1hKTsgfVxyXG5cclxuICAgICAgLy8gRml4IGluY29ycmVjdGx5IHBsYWNlZCBhcnJheSBvYmplY3QgcmVxdWlyZWQgbGlzdHNcclxuICAgICAgaWYgKHN1YlNjaGVtYS50eXBlID09PSAnYXJyYXknICYmIGlzQXJyYXkoc3ViU2NoZW1hLnJlcXVpcmVkKSkge1xyXG4gICAgICAgIHJldHVybiBmaXhSZXF1aXJlZEFycmF5UHJvcGVydGllcyhzdWJTY2hlbWEpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gc3ViU2NoZW1hO1xyXG4gIH0sIHRydWUsIDxzdHJpbmc+cG9pbnRlcik7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnY29tYmluZUFsbE9mJyBmdW5jdGlvblxyXG4gKlxyXG4gKiBBdHRlbXB0IHRvIGNvbnZlcnQgYW4gYWxsT2Ygc2NoZW1hIG9iamVjdCBpbnRvXHJcbiAqIGEgbm9uLWFsbE9mIHNjaGVtYSBvYmplY3Qgd2l0aCBlcXVpdmFsZW50IHJ1bGVzLlxyXG4gKlxyXG4gKiAvLyAgIHNjaGVtYSAtIGFsbE9mIHNjaGVtYSBvYmplY3RcclxuICogLy8gIC0gY29udmVydGVkIHNjaGVtYSBvYmplY3RcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjb21iaW5lQWxsT2Yoc2NoZW1hKSB7XHJcbiAgaWYgKCFpc09iamVjdChzY2hlbWEpIHx8ICFpc0FycmF5KHNjaGVtYS5hbGxPZikpIHsgcmV0dXJuIHNjaGVtYTsgfVxyXG4gIGxldCBtZXJnZWRTY2hlbWEgPSBtZXJnZVNjaGVtYXMoLi4uc2NoZW1hLmFsbE9mKTtcclxuICBpZiAoT2JqZWN0LmtleXMoc2NoZW1hKS5sZW5ndGggPiAxKSB7XHJcbiAgICBjb25zdCBleHRyYUtleXMgPSB7IC4uLnNjaGVtYSB9O1xyXG4gICAgZGVsZXRlIGV4dHJhS2V5cy5hbGxPZjtcclxuICAgIG1lcmdlZFNjaGVtYSA9IG1lcmdlU2NoZW1hcyhtZXJnZWRTY2hlbWEsIGV4dHJhS2V5cyk7XHJcbiAgfVxyXG4gIHJldHVybiBtZXJnZWRTY2hlbWE7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnZml4UmVxdWlyZWRBcnJheVByb3BlcnRpZXMnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIEZpeGVzIGFuIGluY29ycmVjdGx5IHBsYWNlZCByZXF1aXJlZCBsaXN0IGluc2lkZSBhbiBhcnJheSBzY2hlbWEsIGJ5IG1vdmluZ1xyXG4gKiBpdCBpbnRvIGl0ZW1zLnByb3BlcnRpZXMgb3IgYWRkaXRpb25hbEl0ZW1zLnByb3BlcnRpZXMsIHdoZXJlIGl0IGJlbG9uZ3MuXHJcbiAqXHJcbiAqIC8vICAgc2NoZW1hIC0gYWxsT2Ygc2NoZW1hIG9iamVjdFxyXG4gKiAvLyAgLSBjb252ZXJ0ZWQgc2NoZW1hIG9iamVjdFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGZpeFJlcXVpcmVkQXJyYXlQcm9wZXJ0aWVzKHNjaGVtYSkge1xyXG4gIGlmIChzY2hlbWEudHlwZSA9PT0gJ2FycmF5JyAmJiBpc0FycmF5KHNjaGVtYS5yZXF1aXJlZCkpIHtcclxuICAgIGNvbnN0IGl0ZW1zT2JqZWN0ID0gaGFzT3duKHNjaGVtYS5pdGVtcywgJ3Byb3BlcnRpZXMnKSA/ICdpdGVtcycgOlxyXG4gICAgICBoYXNPd24oc2NoZW1hLmFkZGl0aW9uYWxJdGVtcywgJ3Byb3BlcnRpZXMnKSA/ICdhZGRpdGlvbmFsSXRlbXMnIDogbnVsbDtcclxuICAgIGlmIChpdGVtc09iamVjdCAmJiAhaGFzT3duKHNjaGVtYVtpdGVtc09iamVjdF0sICdyZXF1aXJlZCcpICYmIChcclxuICAgICAgaGFzT3duKHNjaGVtYVtpdGVtc09iamVjdF0sICdhZGRpdGlvbmFsUHJvcGVydGllcycpIHx8XHJcbiAgICAgIHNjaGVtYS5yZXF1aXJlZC5ldmVyeShrZXkgPT4gaGFzT3duKHNjaGVtYVtpdGVtc09iamVjdF0ucHJvcGVydGllcywga2V5KSlcclxuICAgICkpIHtcclxuICAgICAgc2NoZW1hID0gY2xvbmVEZWVwKHNjaGVtYSk7XHJcbiAgICAgIHNjaGVtYVtpdGVtc09iamVjdF0ucmVxdWlyZWQgPSBzY2hlbWEucmVxdWlyZWQ7XHJcbiAgICAgIGRlbGV0ZSBzY2hlbWEucmVxdWlyZWQ7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBzY2hlbWE7XHJcbn1cclxuIl19