@decaf-ts/db-decorators 0.4.34 → 0.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.
Files changed (151) hide show
  1. package/dist/db-decorators.cjs +1823 -0
  2. package/dist/db-decorators.esm.cjs +1761 -0
  3. package/lib/esm/identity/decorators.js +1 -2
  4. package/lib/esm/identity/index.js +1 -2
  5. package/lib/esm/identity/utils.js +1 -2
  6. package/lib/esm/index.js +1 -2
  7. package/lib/esm/interfaces/BulkCrudOperator.js +1 -2
  8. package/lib/esm/interfaces/Contextual.js +1 -2
  9. package/lib/esm/interfaces/CrudOperator.js +1 -2
  10. package/lib/esm/interfaces/IRepository.js +1 -2
  11. package/lib/esm/interfaces/index.js +1 -2
  12. package/lib/esm/model/constants.js +1 -2
  13. package/lib/esm/model/decorators.js +1 -2
  14. package/lib/esm/model/index.js +1 -2
  15. package/lib/esm/model/model.js +1 -2
  16. package/lib/esm/model/validation.js +1 -2
  17. package/lib/esm/operations/Operations.js +1 -2
  18. package/lib/esm/operations/OperationsRegistry.js +1 -2
  19. package/lib/esm/operations/constants.js +1 -2
  20. package/lib/esm/operations/decorators.js +1 -2
  21. package/lib/esm/operations/index.js +1 -2
  22. package/lib/esm/operations/types.js +1 -2
  23. package/lib/esm/repository/BaseRepository.js +1 -2
  24. package/lib/esm/repository/Context.js +1 -2
  25. package/lib/esm/repository/DataCache.js +1 -2
  26. package/lib/esm/repository/Repository.js +1 -2
  27. package/lib/esm/repository/errors.js +1 -2
  28. package/lib/esm/repository/index.js +1 -2
  29. package/lib/esm/repository/utils.js +1 -2
  30. package/lib/esm/repository/wrappers.js +1 -2
  31. package/lib/esm/validation/constants.js +1 -2
  32. package/lib/esm/validation/decorators.js +1 -2
  33. package/lib/esm/validation/index.js +1 -2
  34. package/lib/esm/validation/validation.js +1 -2
  35. package/lib/esm/validation/validators/ReadOnlyValidator.js +1 -2
  36. package/lib/esm/validation/validators/TimestampValidator.js +1 -2
  37. package/lib/esm/validation/validators/UpdateValidator.js +1 -2
  38. package/lib/esm/validation/validators/index.js +1 -2
  39. package/lib/identity/decorators.cjs +1 -2
  40. package/lib/identity/decorators.d.ts +1 -0
  41. package/lib/identity/index.cjs +1 -2
  42. package/lib/identity/index.d.ts +2 -0
  43. package/lib/identity/utils.cjs +1 -2
  44. package/lib/identity/utils.d.ts +34 -0
  45. package/lib/index.cjs +1 -2
  46. package/lib/index.d.ts +33 -0
  47. package/lib/interfaces/BulkCrudOperator.cjs +1 -2
  48. package/lib/interfaces/BulkCrudOperator.d.ts +7 -0
  49. package/lib/interfaces/Contextual.cjs +1 -2
  50. package/lib/interfaces/Contextual.d.ts +6 -0
  51. package/lib/interfaces/CrudOperator.cjs +1 -2
  52. package/lib/interfaces/CrudOperator.d.ts +42 -0
  53. package/lib/interfaces/IRepository.cjs +1 -2
  54. package/lib/interfaces/IRepository.d.ts +11 -0
  55. package/lib/interfaces/index.cjs +1 -2
  56. package/lib/interfaces/index.d.ts +4 -0
  57. package/lib/model/constants.cjs +1 -2
  58. package/lib/model/constants.d.ts +37 -0
  59. package/lib/model/decorators.cjs +1 -2
  60. package/lib/model/decorators.d.ts +50 -0
  61. package/lib/model/index.cjs +1 -2
  62. package/lib/model/index.d.ts +4 -0
  63. package/lib/model/model.cjs +1 -2
  64. package/lib/model/model.d.ts +112 -0
  65. package/lib/model/validation.cjs +1 -2
  66. package/lib/model/validation.d.ts +14 -0
  67. package/lib/operations/Operations.cjs +1 -2
  68. package/lib/operations/Operations.d.ts +19 -0
  69. package/lib/operations/OperationsRegistry.cjs +1 -2
  70. package/lib/operations/OperationsRegistry.d.ts +34 -0
  71. package/lib/operations/constants.cjs +1 -2
  72. package/lib/operations/constants.d.ts +24 -0
  73. package/lib/operations/decorators.cjs +1 -2
  74. package/lib/operations/decorators.d.ts +193 -0
  75. package/lib/operations/index.cjs +1 -2
  76. package/lib/operations/index.d.ts +5 -0
  77. package/lib/operations/types.cjs +1 -2
  78. package/lib/operations/types.d.ts +29 -0
  79. package/lib/repository/BaseRepository.cjs +1 -2
  80. package/lib/repository/BaseRepository.d.ts +36 -0
  81. package/lib/repository/Context.cjs +1 -2
  82. package/lib/repository/Context.d.ts +17 -0
  83. package/lib/repository/DataCache.cjs +1 -2
  84. package/lib/repository/DataCache.d.ts +9 -0
  85. package/lib/repository/Repository.cjs +1 -2
  86. package/lib/repository/Repository.d.ts +10 -0
  87. package/lib/repository/errors.cjs +1 -2
  88. package/lib/repository/errors.d.ts +69 -0
  89. package/lib/repository/index.cjs +1 -2
  90. package/lib/repository/index.d.ts +7 -0
  91. package/lib/repository/utils.cjs +1 -2
  92. package/lib/repository/utils.d.ts +62 -0
  93. package/lib/repository/wrappers.cjs +1 -2
  94. package/lib/repository/wrappers.d.ts +38 -0
  95. package/lib/validation/constants.cjs +1 -2
  96. package/lib/validation/constants.d.ts +30 -0
  97. package/lib/validation/decorators.cjs +1 -2
  98. package/lib/validation/decorators.d.ts +58 -0
  99. package/lib/validation/index.cjs +1 -2
  100. package/lib/validation/index.d.ts +4 -0
  101. package/lib/validation/validation.cjs +1 -2
  102. package/lib/validation/validation.d.ts +41 -0
  103. package/lib/validation/validators/ReadOnlyValidator.cjs +1 -2
  104. package/lib/validation/validators/ReadOnlyValidator.d.ts +23 -0
  105. package/lib/validation/validators/TimestampValidator.cjs +1 -2
  106. package/lib/validation/validators/TimestampValidator.d.ts +14 -0
  107. package/lib/validation/validators/UpdateValidator.cjs +1 -2
  108. package/lib/validation/validators/UpdateValidator.d.ts +23 -0
  109. package/lib/validation/validators/index.cjs +1 -2
  110. package/lib/validation/validators/index.d.ts +3 -0
  111. package/package.json +23 -36
  112. package/dist/db-decorators.js +0 -2
  113. package/dist/db-decorators.js.LICENSE.txt +0 -14
  114. package/dist/esm/db-decorators.js +0 -2
  115. package/dist/esm/db-decorators.js.LICENSE.txt +0 -14
  116. /package/{dist/types → lib/esm}/identity/decorators.d.ts +0 -0
  117. /package/{dist/types → lib/esm}/identity/index.d.ts +0 -0
  118. /package/{dist/types → lib/esm}/identity/utils.d.ts +0 -0
  119. /package/{dist/types → lib/esm}/index.d.ts +0 -0
  120. /package/{dist/types → lib/esm}/interfaces/BulkCrudOperator.d.ts +0 -0
  121. /package/{dist/types → lib/esm}/interfaces/Contextual.d.ts +0 -0
  122. /package/{dist/types → lib/esm}/interfaces/CrudOperator.d.ts +0 -0
  123. /package/{dist/types → lib/esm}/interfaces/IRepository.d.ts +0 -0
  124. /package/{dist/types → lib/esm}/interfaces/index.d.ts +0 -0
  125. /package/{dist/types → lib/esm}/model/constants.d.ts +0 -0
  126. /package/{dist/types → lib/esm}/model/decorators.d.ts +0 -0
  127. /package/{dist/types → lib/esm}/model/index.d.ts +0 -0
  128. /package/{dist/types → lib/esm}/model/model.d.ts +0 -0
  129. /package/{dist/types → lib/esm}/model/validation.d.ts +0 -0
  130. /package/{dist/types → lib/esm}/operations/Operations.d.ts +0 -0
  131. /package/{dist/types → lib/esm}/operations/OperationsRegistry.d.ts +0 -0
  132. /package/{dist/types → lib/esm}/operations/constants.d.ts +0 -0
  133. /package/{dist/types → lib/esm}/operations/decorators.d.ts +0 -0
  134. /package/{dist/types → lib/esm}/operations/index.d.ts +0 -0
  135. /package/{dist/types → lib/esm}/operations/types.d.ts +0 -0
  136. /package/{dist/types → lib/esm}/repository/BaseRepository.d.ts +0 -0
  137. /package/{dist/types → lib/esm}/repository/Context.d.ts +0 -0
  138. /package/{dist/types → lib/esm}/repository/DataCache.d.ts +0 -0
  139. /package/{dist/types → lib/esm}/repository/Repository.d.ts +0 -0
  140. /package/{dist/types → lib/esm}/repository/errors.d.ts +0 -0
  141. /package/{dist/types → lib/esm}/repository/index.d.ts +0 -0
  142. /package/{dist/types → lib/esm}/repository/utils.d.ts +0 -0
  143. /package/{dist/types → lib/esm}/repository/wrappers.d.ts +0 -0
  144. /package/{dist/types → lib/esm}/validation/constants.d.ts +0 -0
  145. /package/{dist/types → lib/esm}/validation/decorators.d.ts +0 -0
  146. /package/{dist/types → lib/esm}/validation/index.d.ts +0 -0
  147. /package/{dist/types → lib/esm}/validation/validation.d.ts +0 -0
  148. /package/{dist/types → lib/esm}/validation/validators/ReadOnlyValidator.d.ts +0 -0
  149. /package/{dist/types → lib/esm}/validation/validators/TimestampValidator.d.ts +0 -0
  150. /package/{dist/types → lib/esm}/validation/validators/UpdateValidator.d.ts +0 -0
  151. /package/{dist/types → lib/esm}/validation/validators/index.d.ts +0 -0
@@ -0,0 +1,1761 @@
1
+ import { ModelKeys, validator, Validator, DEFAULT_ERROR_MESSAGES as DEFAULT_ERROR_MESSAGES$1, Hashing, propMetadata, sf, Validation, date, required, type, ValidationKeys, ReservedModels, ModelErrorDefinition, Model, validate } from '@decaf-ts/decorator-validation';
2
+ import { isEqual, apply, Reflection, metadata } from '@decaf-ts/reflection';
3
+
4
+ /******************************************************************************
5
+ Copyright (c) Microsoft Corporation.
6
+
7
+ Permission to use, copy, modify, and/or distribute this software for any
8
+ purpose with or without fee is hereby granted.
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
11
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
13
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
15
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16
+ PERFORMANCE OF THIS SOFTWARE.
17
+ ***************************************************************************** */
18
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
19
+
20
+
21
+ function __decorate(decorators, target, key, desc) {
22
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
23
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
24
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
25
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
26
+ }
27
+
28
+ function __metadata(metadataKey, metadataValue) {
29
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
30
+ }
31
+
32
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
33
+ var e = new Error(message);
34
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
35
+ };
36
+
37
+ /**
38
+ * @summary Holds the Model reflection keys
39
+ * @const DBKeys
40
+ *
41
+ * @memberOf module:db-decorators.Model
42
+ */
43
+ const DBKeys = {
44
+ REFLECT: `${ModelKeys.REFLECT}persistence.`,
45
+ REPOSITORY: "repository",
46
+ CLASS: "_class",
47
+ ID: "id",
48
+ INDEX: "index",
49
+ UNIQUE: "unique",
50
+ SERIALIZE: "serialize",
51
+ READONLY: "readonly",
52
+ TIMESTAMP: "timestamp",
53
+ HASH: "hash",
54
+ COMPOSED: "composed",
55
+ VERSION: "version",
56
+ ORIGINAL: "__originalObj",
57
+ };
58
+ /**
59
+ * @summary The default separator when concatenating indexes
60
+ *
61
+ * @const DefaultIndexSeparator
62
+ *
63
+ * @category Managers
64
+ * @subcategory Constants
65
+ */
66
+ const DefaultSeparator = "_";
67
+ /**
68
+ * @summary Holds the default timestamp date format
69
+ * @constant DEFAULT_TIMESTAMP_FORMAT
70
+ *
71
+ * @memberOf module:db-decorators.Model
72
+ */
73
+ const DEFAULT_TIMESTAMP_FORMAT = "dd/MM/yyyy HH:mm:ss:S";
74
+
75
+ /**
76
+ * @summary holds the default error messages
77
+ * @const DEFAULT_ERROR_MESSAGES
78
+ *
79
+ * @memberOf module:db-decorators.Model
80
+ */
81
+ const DEFAULT_ERROR_MESSAGES = {
82
+ ID: {
83
+ INVALID: "This Id is invalid",
84
+ REQUIRED: "The Id is mandatory",
85
+ },
86
+ READONLY: {
87
+ INVALID: "This cannot be updated",
88
+ },
89
+ TIMESTAMP: {
90
+ REQUIRED: "Timestamp is Mandatory",
91
+ DATE: "The Timestamp must the a valid date",
92
+ INVALID: "This value must always increase",
93
+ },
94
+ };
95
+ /**
96
+ * @summary Update reflection keys
97
+ * @const UpdateValidationKeys
98
+ * @memberOf module:db-decorators.Operations
99
+ */
100
+ const UpdateValidationKeys = {
101
+ REFLECT: "db.update.validation.",
102
+ TIMESTAMP: DBKeys.TIMESTAMP,
103
+ READONLY: DBKeys.READONLY,
104
+ };
105
+
106
+ /**
107
+ * @summary Validator for the {@link readonly} decorator
108
+ *
109
+ * @class ReadOnlyValidator
110
+ * @extends Validator
111
+ *
112
+ * @category Validators
113
+ */
114
+ let ReadOnlyValidator = class ReadOnlyValidator extends Validator {
115
+ constructor() {
116
+ super(DEFAULT_ERROR_MESSAGES.READONLY.INVALID);
117
+ }
118
+ /**
119
+ * @inheritDoc
120
+ */
121
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
122
+ hasErrors(value, ...args) {
123
+ return undefined;
124
+ }
125
+ /**
126
+ * @summary Validates a value has not changed
127
+ * @param {any} value
128
+ * @param {any} oldValue
129
+ * @param {string} [message] the error message override
130
+ */
131
+ updateHasErrors(value, oldValue, message) {
132
+ if (value === undefined)
133
+ return;
134
+ return isEqual(value, oldValue)
135
+ ? undefined
136
+ : this.getMessage(message || this.message);
137
+ }
138
+ };
139
+ ReadOnlyValidator = __decorate([
140
+ validator(UpdateValidationKeys.READONLY),
141
+ __metadata("design:paramtypes", [])
142
+ ], ReadOnlyValidator);
143
+
144
+ /**
145
+ * @summary Validates the update of a timestamp
146
+ *
147
+ * @class TimestampValidator
148
+ * @extends Validator
149
+ *
150
+ * @category Validators
151
+ */
152
+ let TimestampValidator = class TimestampValidator extends Validator {
153
+ constructor() {
154
+ super(DEFAULT_ERROR_MESSAGES.TIMESTAMP.INVALID);
155
+ }
156
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
157
+ hasErrors(value, ...args) {
158
+ return undefined;
159
+ }
160
+ updateHasErrors(value, oldValue, message) {
161
+ if (value === undefined)
162
+ return;
163
+ message = message || this.getMessage(message || this.message);
164
+ try {
165
+ value = new Date(value);
166
+ oldValue = new Date(oldValue);
167
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
168
+ }
169
+ catch (e) {
170
+ return message;
171
+ }
172
+ return value <= oldValue ? message : undefined;
173
+ }
174
+ };
175
+ TimestampValidator = __decorate([
176
+ validator(UpdateValidationKeys.TIMESTAMP),
177
+ __metadata("design:paramtypes", [])
178
+ ], TimestampValidator);
179
+
180
+ /**
181
+ * @summary Base class for an Update validator
182
+ *
183
+ * @param {string} [message] error message. defaults to {@link DecoratorMessages#DEFAULT}
184
+ * @param {string[]} [acceptedTypes] the accepted value types by the decorator
185
+ *
186
+ * @class UpdateValidator
187
+ * @abstract
188
+ * @extends Validator
189
+ *
190
+ * @category Validators
191
+ */
192
+ class UpdateValidator extends Validator {
193
+ constructor(message = DEFAULT_ERROR_MESSAGES$1.DEFAULT, ...acceptedTypes) {
194
+ super(message, ...acceptedTypes);
195
+ }
196
+ }
197
+
198
+ /**
199
+ * @summary Set of constants to define db CRUD operations and their equivalent 'on' and 'after' phases
200
+ * @const OperationKeys
201
+ *
202
+ * @memberOf module:db-decorators.Operations
203
+ */
204
+ var OperationKeys;
205
+ (function (OperationKeys) {
206
+ OperationKeys["REFLECT"] = "decaf.model.db.operations.";
207
+ OperationKeys["CREATE"] = "create";
208
+ OperationKeys["READ"] = "read";
209
+ OperationKeys["UPDATE"] = "update";
210
+ OperationKeys["DELETE"] = "delete";
211
+ OperationKeys["ON"] = "on.";
212
+ OperationKeys["AFTER"] = "after.";
213
+ })(OperationKeys || (OperationKeys = {}));
214
+ /**
215
+ * @summary Maps out groups of CRUD operations for easier mapping of decorators
216
+ *
217
+ * @constant DBOperations
218
+ *
219
+ * @memberOf module:db-decorators.Operations
220
+ */
221
+ const DBOperations = {
222
+ CREATE: [OperationKeys.CREATE],
223
+ READ: [OperationKeys.READ],
224
+ UPDATE: [OperationKeys.UPDATE],
225
+ DELETE: [OperationKeys.DELETE],
226
+ CREATE_UPDATE: [OperationKeys.CREATE, OperationKeys.UPDATE],
227
+ READ_CREATE: [OperationKeys.READ, OperationKeys.CREATE],
228
+ ALL: [
229
+ OperationKeys.CREATE,
230
+ OperationKeys.READ,
231
+ OperationKeys.UPDATE,
232
+ OperationKeys.DELETE,
233
+ ],
234
+ };
235
+
236
+ /**
237
+ * @summary Holds the registered operation handlers
238
+ *
239
+ * @class OperationsRegistry
240
+ * @implements IRegistry<OperationHandler<any>>
241
+ *
242
+ * @see OperationHandler
243
+ *
244
+ * @category Operations
245
+ */
246
+ class OperationsRegistry {
247
+ constructor() {
248
+ this.cache = {};
249
+ }
250
+ /**
251
+ * @summary retrieves an {@link OperationHandler} if it exists
252
+ * @param {string} target
253
+ * @param {string} propKey
254
+ * @param {string} operation
255
+ * @param accum
256
+ * @return {OperationHandler | undefined}
257
+ */
258
+ get(target, propKey, operation, accum) {
259
+ accum = accum || [];
260
+ let name;
261
+ try {
262
+ name = typeof target === "string" ? target : target.constructor.name;
263
+ accum.unshift(...Object.values(this.cache[name][propKey][operation] || []));
264
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
265
+ }
266
+ catch (e) {
267
+ if (typeof target === "string" ||
268
+ target === Object.prototype ||
269
+ Object.getPrototypeOf(target) === Object.prototype)
270
+ return accum;
271
+ }
272
+ let proto = Object.getPrototypeOf(target);
273
+ if (proto.constructor.name === name)
274
+ proto = Object.getPrototypeOf(proto);
275
+ return this.get(proto, propKey, operation, accum);
276
+ }
277
+ /**
278
+ * @summary Registers an {@link OperationHandler}
279
+ * @param {OperationHandler} handler
280
+ * @param {string} operation
281
+ * @param {{}} target
282
+ * @param {string | symbol} propKey
283
+ */
284
+ register(handler, operation, target, propKey) {
285
+ const name = target.constructor.name;
286
+ const handlerName = Operations.getHandlerName(handler);
287
+ if (!this.cache[name])
288
+ this.cache[name] = {};
289
+ if (!this.cache[name][propKey])
290
+ this.cache[name][propKey] = {};
291
+ if (!this.cache[name][propKey][operation])
292
+ this.cache[name][propKey][operation] = {};
293
+ if (this.cache[name][propKey][operation][handlerName])
294
+ return;
295
+ this.cache[name][propKey][operation][handlerName] = handler;
296
+ }
297
+ }
298
+
299
+ /**
300
+ * @summary Static class holding common Operation Functionality
301
+ *
302
+ * @class Operations
303
+ *
304
+ * @category Operations
305
+ */
306
+ class Operations {
307
+ constructor() { }
308
+ static getHandlerName(handler) {
309
+ if (handler.name)
310
+ return handler.name;
311
+ console.warn("Handler name not defined. A name will be generated, but this is not desirable. please avoid using anonymous functions");
312
+ return Hashing.hash(handler.toString());
313
+ }
314
+ static key(str) {
315
+ return OperationKeys.REFLECT + str;
316
+ }
317
+ static get(targetName, propKey, operation) {
318
+ return Operations.registry.get(targetName, propKey, operation);
319
+ }
320
+ static getOpRegistry() {
321
+ if (!Operations.registry)
322
+ Operations.registry = new OperationsRegistry();
323
+ return Operations.registry;
324
+ }
325
+ static register(handler, operation, target, propKey) {
326
+ Operations.getOpRegistry().register(handler, operation, target, propKey);
327
+ }
328
+ }
329
+
330
+ function handle(op, handler) {
331
+ return (target, propertyKey) => {
332
+ Operations.register(handler, op, target, propertyKey);
333
+ };
334
+ }
335
+ /**
336
+ * @summary Defines a behaviour to set on the defined {@link DBOperations.CREATE_UPDATE}
337
+ *
338
+ * @param {OnOperationHandler<any>} handler The method called upon the operation
339
+ * @param data
340
+ * @param {any[]} [args] Arguments that will be passed in order to the handler method
341
+ *
342
+ * @see on
343
+ *
344
+ * @function onCreateUpdate
345
+ *
346
+ * @category Decorators
347
+ */
348
+ function onCreateUpdate(handler, data) {
349
+ return on(DBOperations.CREATE_UPDATE, handler, data);
350
+ }
351
+ /**
352
+ * @summary Defines a behaviour to set on the defined {@link DBOperations.UPDATE}
353
+ *
354
+ * @param {OnOperationHandler<any>} handler The method called upon the operation
355
+ * @param data
356
+ * @param {any[]} [args] Arguments that will be passed in order to the handler method
357
+ *
358
+ * @see on
359
+ *
360
+ * @function onUpdate
361
+ *
362
+ * @category Decorators
363
+ */
364
+ function onUpdate(handler, data) {
365
+ return on(DBOperations.UPDATE, handler, data);
366
+ }
367
+ /**
368
+ * @summary Defines a behaviour to set on the defined {@link DBOperations.CREATE}
369
+ *
370
+ * @param {OnOperationHandler<any>} handler The method called upon the operation
371
+ * @param data
372
+ *
373
+ * @see on
374
+ *
375
+ * @function onCreate
376
+ *
377
+ * @category Decorators
378
+ */
379
+ function onCreate(handler, data) {
380
+ return on(DBOperations.CREATE, handler, data);
381
+ }
382
+ /**
383
+ * @summary Defines a behaviour to set on the defined {@link DBOperations.READ}
384
+ *
385
+ * @param {OnOperationHandler<any>} handler The method called upon the operation
386
+ * @param data
387
+ *
388
+ * @see on
389
+ *
390
+ * @function onRead
391
+ *
392
+ * @category Decorators
393
+ */
394
+ function onRead(handler, data) {
395
+ return on(DBOperations.READ, handler, data);
396
+ }
397
+ /**
398
+ * @summary Defines a behaviour to set on the defined {@link DBOperations.DELETE}
399
+ *
400
+ * @param {OnOperationHandler<any>} handler The method called upon the operation
401
+ * @param data
402
+ *
403
+ * @see on
404
+ *
405
+ * @function onDelete
406
+ *
407
+ * @category Decorators
408
+ */
409
+ function onDelete(handler, data) {
410
+ return on(DBOperations.DELETE, handler, data);
411
+ }
412
+ /**
413
+ * @summary Defines a behaviour to set on the defined {@link DBOperations.DELETE}
414
+ *
415
+ * @param {OnOperationHandler<any>} handler The method called upon the operation
416
+ * @param data
417
+ *
418
+ * @see on
419
+ *
420
+ * @function onAny
421
+ *
422
+ * @category Decorators
423
+ */
424
+ function onAny(handler, data) {
425
+ return on(DBOperations.ALL, handler, data);
426
+ }
427
+ /**
428
+ * @summary Defines a behaviour to set on the defined {@link DBOperations}
429
+ *
430
+ * @param {OperationKeys[] | DBOperations} op One of {@link DBOperations}
431
+ * @param {OnOperationHandler<any>} handler The method called upon the operation
432
+ * @param data
433
+ *
434
+ * ex: handler(...args, ...props.map(p => target[p]))
435
+ *
436
+ * @function on
437
+ *
438
+ * @category Decorators
439
+ */
440
+ function on(op = DBOperations.ALL, handler, data) {
441
+ return operation(OperationKeys.ON, op, handler, data);
442
+ }
443
+ /**
444
+ * @summary Defines a behaviour to set after the defined {@link DBOperations.CREATE_UPDATE}
445
+ *
446
+ * @param {AfterOperationHandler<any>} handler The method called upon the operation
447
+ * @param data
448
+ *
449
+ * @see after
450
+ *
451
+ * @function afterCreateUpdate
452
+ *
453
+ * @category Decorators
454
+ */
455
+ function afterCreateUpdate(handler, data) {
456
+ return after(DBOperations.CREATE_UPDATE, handler, data);
457
+ }
458
+ /**
459
+ * @summary Defines a behaviour to set after the defined {@link DBOperations.UPDATE}
460
+ *
461
+ * @param {AfterOperationHandler<any>} handler The method called upon the operation
462
+ * @param data
463
+ *
464
+ * @see after
465
+ *
466
+ * @function afterUpdate
467
+ *
468
+ * @category Decorators
469
+ */
470
+ function afterUpdate(handler, data) {
471
+ return after(DBOperations.UPDATE, handler, data);
472
+ }
473
+ /**
474
+ * @summary Defines a behaviour to set after the defined {@link DBOperations.CREATE}
475
+ *
476
+ * @param {AfterOperationHandler<any>} handler The method called upon the operation
477
+ * @param data
478
+ *
479
+ * @see after
480
+ *
481
+ * @function afterCreate
482
+ *
483
+ * @category Decorators
484
+ */
485
+ function afterCreate(handler, data) {
486
+ return after(DBOperations.CREATE, handler, data);
487
+ }
488
+ /**
489
+ * @summary Defines a behaviour to set after the defined {@link DBOperations.READ}
490
+ *
491
+ * @param {AfterOperationHandler<any>} handler The method called upon the operation
492
+ * @param data
493
+ * @param {any[]} [args] Arguments that will be passed in order to the handler method
494
+ *
495
+ * @see after
496
+ *
497
+ * @function afterRead
498
+ *
499
+ * @category Decorators
500
+ */
501
+ function afterRead(handler, data) {
502
+ return after(DBOperations.READ, handler, data);
503
+ }
504
+ /**
505
+ * @summary Defines a behaviour to set after the defined {@link DBOperations.DELETE}
506
+ *
507
+ * @param {AfterOperationHandler<any>} handler The method called upon the operation
508
+ * @param data
509
+ * @param {any[]} [args] Arguments that will be passed in order to the handler method
510
+ *
511
+ * @see after
512
+ *
513
+ * @function afterDelete
514
+ *
515
+ * @category Decorators
516
+ */
517
+ function afterDelete(handler, data) {
518
+ return after(DBOperations.DELETE, handler, data);
519
+ }
520
+ /**
521
+ * @summary Defines a behaviour to set after the defined {@link DBOperations.DELETE}
522
+ *
523
+ * @param {AfterOperationHandler<any>} handler The method called upon the operation
524
+ * @param data
525
+ * @param {any[]} [args] Arguments that will be passed in order to the handler method
526
+ *
527
+ * @see after
528
+ *
529
+ * @function afterAny
530
+ *
531
+ * @category Decorators
532
+ */
533
+ function afterAny(handler, data) {
534
+ return after(DBOperations.ALL, handler, data);
535
+ }
536
+ /**
537
+ * @summary Defines a behaviour to set on the defined {@link DBOperations}
538
+ *
539
+ * @param {OperationKeys[] | DBOperations} op One of {@link DBOperations}
540
+ * @param {AfterOperationHandler<any>} handler The method called upon the operation
541
+ *
542
+ * ex: handler(...args, ...props.map(p => target[p]))
543
+ *
544
+ * @param data
545
+ * @param args
546
+ * @function after
547
+ *
548
+ * @category Decorators
549
+ */
550
+ function after(op = DBOperations.ALL, handler, data) {
551
+ return operation(OperationKeys.AFTER, op, handler, data);
552
+ }
553
+ function operation(baseOp, operation = DBOperations.ALL, handler, dataToAdd) {
554
+ return (target, propertyKey) => {
555
+ const name = target.constructor.name;
556
+ const decorators = operation.reduce((accum, op) => {
557
+ const compoundKey = baseOp + op;
558
+ let data = Reflect.getMetadata(Operations.key(compoundKey), target, propertyKey);
559
+ if (!data)
560
+ data = {
561
+ operation: op,
562
+ handlers: {},
563
+ };
564
+ const handlerKey = Operations.getHandlerName(handler);
565
+ if (!data.handlers[name] ||
566
+ !data.handlers[name][propertyKey] ||
567
+ !(handlerKey in data.handlers[name][propertyKey])) {
568
+ data.handlers[name] = data.handlers[name] || {};
569
+ data.handlers[name][propertyKey] =
570
+ data.handlers[name][propertyKey] || {};
571
+ data.handlers[name][propertyKey][handlerKey] = {
572
+ data: dataToAdd,
573
+ };
574
+ accum.push(handle(compoundKey, handler), propMetadata(Operations.key(compoundKey), data));
575
+ }
576
+ return accum;
577
+ }, []);
578
+ return apply(...decorators)(target, propertyKey);
579
+ };
580
+ }
581
+
582
+ /**
583
+ * @summary Base Error
584
+ *
585
+ * @param {string} msg the error message
586
+ *
587
+ * @class BaseDLTError
588
+ * @extends Error
589
+ */
590
+ class BaseError extends Error {
591
+ constructor(name, msg) {
592
+ if (msg instanceof BaseError)
593
+ return msg;
594
+ const message = `[${name}] ${msg instanceof Error ? msg.message : msg}`;
595
+ super(message);
596
+ if (msg instanceof Error)
597
+ this.stack = msg.stack;
598
+ }
599
+ }
600
+ /**
601
+ * @summary Represents a failure in the Model details
602
+ *
603
+ * @param {string} msg the error message
604
+ *
605
+ * @class ValidationError
606
+ * @extends BaseError
607
+ */
608
+ class ValidationError extends BaseError {
609
+ constructor(msg) {
610
+ super(ValidationError.name, msg);
611
+ }
612
+ }
613
+ /**
614
+ * @summary Represents an internal failure (should mean an error in code)
615
+ *
616
+ * @param {string} msg the error message
617
+ *
618
+ * @class InternalError
619
+ * @extends BaseError
620
+ */
621
+ class InternalError extends BaseError {
622
+ constructor(msg) {
623
+ super(InternalError.name, msg);
624
+ }
625
+ }
626
+ /**
627
+ * @summary Represents a failure in the Model de/serialization
628
+ *
629
+ * @param {string} msg the error message
630
+ *
631
+ * @class SerializationError
632
+ * @extends BaseError
633
+ *
634
+ */
635
+ class SerializationError extends BaseError {
636
+ constructor(msg) {
637
+ super(SerializationError.name, msg);
638
+ }
639
+ }
640
+ /**
641
+ * @summary Represents a failure in finding a model
642
+ *
643
+ * @param {string} msg the error message
644
+ *
645
+ * @class NotFoundError
646
+ * @extends BaseError
647
+ *
648
+ */
649
+ class NotFoundError extends BaseError {
650
+ constructor(msg) {
651
+ super(NotFoundError.name, msg);
652
+ }
653
+ }
654
+ /**
655
+ * @summary Represents a conflict in the storage
656
+ *
657
+ * @param {string} msg the error message
658
+ *
659
+ * @class ConflictError
660
+ * @extends BaseError
661
+ *
662
+ */
663
+ class ConflictError extends BaseError {
664
+ constructor(msg) {
665
+ super(ConflictError.name, msg);
666
+ }
667
+ }
668
+
669
+ /**
670
+ * @summary retrieves the arguments for the handler
671
+ * @param {any} dec the decorator
672
+ * @param {string} prop the property name
673
+ * @param {{}} m the model
674
+ * @param {{}} [accum] accumulator used for internal recursiveness
675
+ *
676
+ * @function getHandlerArgs
677
+ * @memberOf module:db-decorators.Repository
678
+ */
679
+ const getHandlerArgs = function (dec, prop, m, accum) {
680
+ const name = m.constructor.name;
681
+ if (!name)
682
+ throw new InternalError("Could not determine model class");
683
+ accum = accum || {};
684
+ if (dec.props.handlers[name] && dec.props.handlers[name][prop])
685
+ accum = { ...dec.props.handlers[name][prop], ...accum };
686
+ let proto = Object.getPrototypeOf(m);
687
+ if (proto === Object.prototype)
688
+ return accum;
689
+ if (proto.constructor.name === name)
690
+ proto = Object.getPrototypeOf(proto);
691
+ return getHandlerArgs(dec, prop, proto, accum);
692
+ };
693
+ /**
694
+ *
695
+ * @param {IRepository<T>} repo
696
+ * @param context
697
+ * @param {T} model
698
+ * @param operation
699
+ * @param prefix
700
+ *
701
+ * @param oldModel
702
+ * @function enforceDBPropertyDecoratorsAsync
703
+ *
704
+ * @memberOf db-decorators.utils
705
+ */
706
+ async function enforceDBDecorators(repo, context, model, operation, prefix, oldModel) {
707
+ const decorators = getDbDecorators(model, operation, prefix);
708
+ if (!decorators)
709
+ return;
710
+ for (const prop in decorators) {
711
+ const decs = decorators[prop];
712
+ for (const dec of decs) {
713
+ const { key } = dec;
714
+ const handlers = Operations.get(model, prop, prefix + key);
715
+ if (!handlers || !handlers.length)
716
+ throw new InternalError(`Could not find registered handler for the operation ${prefix + key} under property ${prop}`);
717
+ const handlerArgs = getHandlerArgs(dec, prop, model);
718
+ if (!handlerArgs || Object.values(handlerArgs).length !== handlers.length)
719
+ throw new InternalError(sf("Args and handlers length do not match"));
720
+ let handler;
721
+ let data;
722
+ for (let i = 0; i < handlers.length; i++) {
723
+ handler = handlers[i];
724
+ data = Object.values(handlerArgs)[i];
725
+ const args = [context, data.data, prop, model];
726
+ if (operation === OperationKeys.UPDATE && prefix === OperationKeys.ON) {
727
+ if (!oldModel)
728
+ throw new InternalError("Missing old model for update operation");
729
+ args.push(oldModel);
730
+ }
731
+ await handler.apply(repo, args);
732
+ }
733
+ }
734
+ }
735
+ }
736
+ /**
737
+ * Specific for DB Decorators
738
+ * @param {T} model
739
+ * @param {string} operation CRUD {@link OperationKeys}
740
+ * @param {string} [extraPrefix]
741
+ *
742
+ * @function getDbPropertyDecorators
743
+ *
744
+ * @memberOf db-decorators.utils
745
+ */
746
+ function getDbDecorators(model, operation, extraPrefix) {
747
+ const decorators = Reflection.getAllPropertyDecorators(model,
748
+ // undefined,
749
+ OperationKeys.REFLECT + (extraPrefix ? extraPrefix : ""));
750
+ if (!decorators)
751
+ return;
752
+ return Object.keys(decorators).reduce((accum, decorator) => {
753
+ const dec = decorators[decorator].filter((d) => d.key === operation);
754
+ if (dec && dec.length) {
755
+ if (!accum)
756
+ accum = {};
757
+ accum[decorator] = dec;
758
+ }
759
+ return accum;
760
+ }, undefined);
761
+ }
762
+ /**
763
+ * @summary Retrieves the decorators for an object's properties prefixed by {@param prefixes} recursively
764
+ * @param model
765
+ * @param accum
766
+ * @param prefixes
767
+ *
768
+ * @function getAllPropertyDecoratorsRecursive
769
+ * @memberOf module:db-decorators.Repository
770
+ */
771
+ const getAllPropertyDecoratorsRecursive = function (model, accum, ...prefixes) {
772
+ const accumulator = accum || {};
773
+ const mergeDecorators = function (decs) {
774
+ const pushOrSquash = (key, ...values) => {
775
+ values.forEach((val) => {
776
+ let match;
777
+ if (!(match = accumulator[key].find((e) => e.key === val.key)) ||
778
+ match.props.operation !== val.props.operation) {
779
+ accumulator[key].push(val);
780
+ return;
781
+ }
782
+ if (val.key === ModelKeys.TYPE)
783
+ return;
784
+ const { handlers, operation } = val.props;
785
+ if (!operation ||
786
+ !operation.match(new RegExp(`^(:?${OperationKeys.ON}|${OperationKeys.AFTER})(:?${OperationKeys.CREATE}|${OperationKeys.READ}|${OperationKeys.UPDATE}|${OperationKeys.DELETE})$`))) {
787
+ accumulator[key].push(val);
788
+ return;
789
+ }
790
+ const accumHandlers = match.props.handlers;
791
+ Object.entries(handlers).forEach(([clazz, handlerDef]) => {
792
+ if (!(clazz in accumHandlers)) {
793
+ accumHandlers[clazz] = handlerDef;
794
+ return;
795
+ }
796
+ Object.entries(handlerDef).forEach(([handlerProp, handler]) => {
797
+ if (!(handlerProp in accumHandlers[clazz])) {
798
+ accumHandlers[clazz][handlerProp] = handler;
799
+ return;
800
+ }
801
+ Object.entries(handler).forEach(([handlerKey, argsObj]) => {
802
+ if (!(handlerKey in accumHandlers[clazz][handlerProp])) {
803
+ accumHandlers[clazz][handlerProp][handlerKey] = argsObj;
804
+ return;
805
+ }
806
+ console.warn(sf("Skipping handler registration for {0} under prop {0} because handler is the same", clazz, handlerProp));
807
+ });
808
+ });
809
+ });
810
+ });
811
+ };
812
+ Object.entries(decs).forEach(([key, value]) => {
813
+ accumulator[key] = accumulator[key] || [];
814
+ pushOrSquash(key, ...value);
815
+ });
816
+ };
817
+ const decs = Reflection.getAllPropertyDecorators(model, ...prefixes);
818
+ if (decs)
819
+ mergeDecorators(decs);
820
+ if (Object.getPrototypeOf(model) === Object.prototype)
821
+ return accumulator;
822
+ // const name = model.constructor.name;
823
+ const proto = Object.getPrototypeOf(model);
824
+ if (!proto)
825
+ return accumulator;
826
+ // if (proto.constructor && proto.constructor.name === name)
827
+ // proto = Object.getPrototypeOf(proto)
828
+ return getAllPropertyDecoratorsRecursive(proto, accumulator, ...prefixes);
829
+ };
830
+
831
+ class DataCache {
832
+ constructor() {
833
+ this.cache = {};
834
+ }
835
+ async get(key) {
836
+ if (!(key in this.cache))
837
+ throw new NotFoundError(`Key ${key} not in dataStore`);
838
+ return this.cache[key];
839
+ }
840
+ async push(key, value) {
841
+ if (key in this.cache)
842
+ throw new ConflictError(`Key ${key} already in dataStore`);
843
+ this.cache[key] = value;
844
+ }
845
+ async put(key, value) {
846
+ this.cache[key] = value;
847
+ }
848
+ async pop(key) {
849
+ const res = this.get(key);
850
+ delete this.cache[key];
851
+ return res;
852
+ }
853
+ async filter(filter) {
854
+ if (typeof filter === "string")
855
+ filter = new RegExp(filter);
856
+ return Object.keys(this.cache)
857
+ .filter((k) => !!filter.exec(k))
858
+ .map((k) => this.cache[k]);
859
+ }
860
+ async purge(key) {
861
+ if (!key)
862
+ this.cache = {};
863
+ else
864
+ await this.pop(key);
865
+ }
866
+ }
867
+
868
+ class Context extends DataCache {
869
+ constructor(operation, model, parent) {
870
+ super();
871
+ this.operation = operation;
872
+ this.model = model;
873
+ this.parent = parent;
874
+ }
875
+ get timestamp() {
876
+ return new Date();
877
+ }
878
+ async get(key) {
879
+ try {
880
+ return super.get(key);
881
+ }
882
+ catch (e) {
883
+ if (this.parent)
884
+ return this.parent.get(key);
885
+ throw e;
886
+ }
887
+ }
888
+ async pop(key) {
889
+ if (key in this.cache)
890
+ return super.pop(key);
891
+ if (!this.parent)
892
+ throw new NotFoundError(`Key ${key} not in dataStore`);
893
+ return this.parent.pop(key);
894
+ }
895
+ child(operation, model) {
896
+ return this.constructor(operation, model, this);
897
+ }
898
+ static async from(operation, model,
899
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
900
+ ...args) {
901
+ return new Context(operation, model);
902
+ }
903
+ static async args(operation, model, args, contextual) {
904
+ const last = args.pop();
905
+ async function getContext() {
906
+ if (contextual)
907
+ return contextual.context(operation, model, ...args);
908
+ return new Context(operation, model);
909
+ }
910
+ let c;
911
+ if (last) {
912
+ if (last instanceof Context) {
913
+ c = last;
914
+ args.push(last);
915
+ }
916
+ else {
917
+ c = await getContext();
918
+ args.push(last, c);
919
+ }
920
+ }
921
+ else {
922
+ c = await getContext();
923
+ args.push(c);
924
+ }
925
+ return { context: c, args: args };
926
+ }
927
+ }
928
+
929
+ /**
930
+ * @summary Util method to change a method of an object prefixing it with another
931
+ * @param {any} obj The Base Object
932
+ * @param {Function} after The original method
933
+ * @param {Function} prefix The Prefix method. The output will be used as arguments in the original method
934
+ * @param {string} [afterName] When the after function anme cannot be extracted, pass it here
935
+ *
936
+ * @function prefixMethod
937
+ *
938
+ * @memberOf module:db-decorators.Repository
939
+ */
940
+ function prefixMethod(obj, after, prefix, afterName) {
941
+ async function wrapper(...args) {
942
+ const results = await Promise.resolve(prefix.call(this, ...args));
943
+ return Promise.resolve(after.apply(this, results));
944
+ }
945
+ const wrapped = wrapper.bind(obj);
946
+ const name = afterName ? afterName : after.name;
947
+ Object.defineProperty(wrapped, "name", {
948
+ enumerable: true,
949
+ configurable: true,
950
+ writable: false,
951
+ value: name,
952
+ });
953
+ obj[name] = wrapped;
954
+ }
955
+ /**
956
+ * @summary Util method to change a method of an object suffixing it with another
957
+ * @param {any} obj The Base Object
958
+ * @param {Function} before The original method
959
+ * @param {Function} suffix The Prefix method. The output will be used as arguments in the original method
960
+ * @param {string} [beforeName] When the after function anme cannot be extracted, pass it here
961
+ *
962
+ * @function suffixMethod
963
+ *
964
+ * @memberOf module:db-decorators.Repository
965
+ */
966
+ function suffixMethod(obj, before, suffix, beforeName) {
967
+ async function wrapper(...args) {
968
+ const results = await Promise.resolve(before.call(this, ...args));
969
+ return suffix.call(this, ...results);
970
+ }
971
+ const wrapped = wrapper.bind(obj);
972
+ const name = beforeName ? beforeName : before.name;
973
+ Object.defineProperty(wrapped, "name", {
974
+ enumerable: true,
975
+ configurable: true,
976
+ writable: false,
977
+ value: name,
978
+ });
979
+ obj[name] = wrapped;
980
+ }
981
+ /**
982
+ * @summary Util method to wrap a method of an object with additional logic
983
+ *
984
+ * @param {any} obj The Base Object
985
+ * @param {Function} before the method to be prefixed
986
+ * @param {Function} method the method to be wrapped
987
+ * @param {Function} after The method to be suffixed
988
+ * @param {string} [methodName] When the after function anme cannot be extracted, pass it here
989
+ *
990
+ * @function wrapMethodWithContext
991
+ *
992
+ * @memberOf module:db-decorators.Repository
993
+ */
994
+ function wrapMethodWithContext(obj, before, method, after, methodName) {
995
+ async function wrapper(...args) {
996
+ let transformedArgs = before.call(obj, ...args);
997
+ if (transformedArgs instanceof Promise)
998
+ transformedArgs = await transformedArgs;
999
+ const context = transformedArgs[transformedArgs.length - 1];
1000
+ if (!(context instanceof Context))
1001
+ throw new InternalError("Missing a context");
1002
+ let results = await method.call(obj, ...transformedArgs);
1003
+ if (results instanceof Promise)
1004
+ results = await results;
1005
+ results = after.call(this, results, context);
1006
+ if (results instanceof Promise)
1007
+ results = await results;
1008
+ return results;
1009
+ }
1010
+ const wrapped = wrapper.bind(obj);
1011
+ const name = methodName ? methodName : method.name;
1012
+ Object.defineProperty(wrapped, "name", {
1013
+ enumerable: true,
1014
+ configurable: true,
1015
+ writable: false,
1016
+ value: name,
1017
+ });
1018
+ obj[name] = wrapped;
1019
+ }
1020
+
1021
+ /**
1022
+ * @summary Returns the primary key attribute for a {@link Model}
1023
+ * @description searches in all the properties in the object for an {@link id} decorated property
1024
+ *
1025
+ * @param {Model} model
1026
+ *
1027
+ * @throws {InternalError} if no property or more than one properties are {@link id} decorated
1028
+ * or no value is set in that property
1029
+ *
1030
+ * @function findPrimaryKey
1031
+ *
1032
+ * @category managers
1033
+ */
1034
+ function findPrimaryKey(model) {
1035
+ const decorators = getAllPropertyDecoratorsRecursive(model, undefined, DBKeys.REFLECT + DBKeys.ID);
1036
+ const idDecorators = Object.entries(decorators).reduce((accum, [prop, decs]) => {
1037
+ const filtered = decs.filter((d) => d.key !== ModelKeys.TYPE);
1038
+ if (filtered && filtered.length) {
1039
+ accum[prop] = accum[prop] || [];
1040
+ accum[prop].push(...filtered);
1041
+ }
1042
+ return accum;
1043
+ }, {});
1044
+ if (!idDecorators || !Object.keys(idDecorators).length)
1045
+ throw new InternalError("Could not find ID decorated Property");
1046
+ if (Object.keys(idDecorators).length > 1)
1047
+ throw new InternalError(sf(Object.keys(idDecorators).join(", ")));
1048
+ const idProp = Object.keys(idDecorators)[0];
1049
+ if (!idProp)
1050
+ throw new InternalError("Could not find ID decorated Property");
1051
+ return {
1052
+ id: idProp,
1053
+ props: idDecorators[idProp][0].props,
1054
+ };
1055
+ }
1056
+ /**
1057
+ * @summary Returns the primary key value for a {@link Model}
1058
+ * @description searches in all the properties in the object for an {@link pk} decorated property
1059
+ *
1060
+ * @param {Model} model
1061
+ * @param {boolean} [returnEmpty]
1062
+ * @return {string} primary key
1063
+ *
1064
+ * @throws {InternalError} if no property or more than one properties are {@link pk} decorated
1065
+ * @throws {NotFoundError} returnEmpty is false and no value is set on the {@link pk} decorated property
1066
+ *
1067
+ * @function findModelID
1068
+ *
1069
+ * @category managers
1070
+ */
1071
+ function findModelId(model, returnEmpty = false) {
1072
+ const idProp = findPrimaryKey(model).id;
1073
+ const modelId = model[idProp];
1074
+ if (!modelId && !returnEmpty)
1075
+ throw new InternalError(sf("No value for the Id is defined under the property {0}", idProp));
1076
+ return modelId;
1077
+ }
1078
+
1079
+ class BaseRepository {
1080
+ get class() {
1081
+ if (!this._class)
1082
+ throw new InternalError(`No class definition found for this repository`);
1083
+ return this._class;
1084
+ }
1085
+ get pk() {
1086
+ if (!this._pk)
1087
+ this._pk = findPrimaryKey(new this.class()).id;
1088
+ return this._pk;
1089
+ }
1090
+ constructor(clazz) {
1091
+ if (clazz)
1092
+ this._class = clazz;
1093
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
1094
+ const self = this;
1095
+ [this.create, this.read, this.update, this.delete].forEach((m) => {
1096
+ const name = m.name;
1097
+ wrapMethodWithContext(self, self[name + "Prefix"], m, self[name + "Suffix"]);
1098
+ });
1099
+ }
1100
+ async createAll(models, ...args) {
1101
+ return Promise.all(models.map((m) => this.create(m, ...args)));
1102
+ }
1103
+ async createPrefix(model, ...args) {
1104
+ const contextArgs = await Context.args(OperationKeys.CREATE, this.class, args);
1105
+ model = new this.class(model);
1106
+ await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.CREATE, OperationKeys.ON);
1107
+ return [model, ...contextArgs.args];
1108
+ }
1109
+ async createSuffix(model, context) {
1110
+ await enforceDBDecorators(this, context, model, OperationKeys.CREATE, OperationKeys.AFTER);
1111
+ return model;
1112
+ }
1113
+ async createAllPrefix(models, ...args) {
1114
+ const contextArgs = await Context.args(OperationKeys.CREATE, this.class, args);
1115
+ await Promise.all(models.map(async (m) => {
1116
+ m = new this.class(m);
1117
+ await enforceDBDecorators(this, contextArgs.context, m, OperationKeys.CREATE, OperationKeys.ON);
1118
+ return m;
1119
+ }));
1120
+ return [models, ...contextArgs.args];
1121
+ }
1122
+ async createAllSuffix(models, context) {
1123
+ await Promise.all(models.map((m) => enforceDBDecorators(this, context, m, OperationKeys.CREATE, OperationKeys.AFTER)));
1124
+ return models;
1125
+ }
1126
+ async readAll(keys, ...args) {
1127
+ return await Promise.all(keys.map((id) => this.read(id, ...args)));
1128
+ }
1129
+ async readSuffix(model, context) {
1130
+ await enforceDBDecorators(this, context, model, OperationKeys.READ, OperationKeys.AFTER);
1131
+ return model;
1132
+ }
1133
+ async readPrefix(key, ...args) {
1134
+ const contextArgs = await Context.args(OperationKeys.READ, this.class, args);
1135
+ const model = new this.class();
1136
+ model[this.pk] = key;
1137
+ await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.READ, OperationKeys.ON);
1138
+ return [key, ...contextArgs.args];
1139
+ }
1140
+ async readAllPrefix(keys, ...args) {
1141
+ const contextArgs = await Context.args(OperationKeys.READ, this.class, args);
1142
+ await Promise.all(keys.map(async (k) => {
1143
+ const m = new this.class();
1144
+ m[this.pk] = k;
1145
+ return enforceDBDecorators(this, contextArgs.context, m, OperationKeys.READ, OperationKeys.ON);
1146
+ }));
1147
+ return [keys, ...contextArgs.args];
1148
+ }
1149
+ async readAllSuffix(models, context) {
1150
+ await Promise.all(models.map((m) => enforceDBDecorators(this, context, m, OperationKeys.READ, OperationKeys.AFTER)));
1151
+ return models;
1152
+ }
1153
+ async updateAll(models, ...args) {
1154
+ return Promise.all(models.map((m) => this.update(m, ...args)));
1155
+ }
1156
+ async updateSuffix(model, context) {
1157
+ await enforceDBDecorators(this, context, model, OperationKeys.UPDATE, OperationKeys.AFTER);
1158
+ return model;
1159
+ }
1160
+ async updatePrefix(model, ...args) {
1161
+ const contextArgs = await Context.args(OperationKeys.UPDATE, this.class, args);
1162
+ const id = model[this.pk];
1163
+ if (!id)
1164
+ throw new InternalError(`No value for the Id is defined under the property ${this.pk}`);
1165
+ const oldModel = await this.read(id);
1166
+ await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.UPDATE, OperationKeys.ON, oldModel);
1167
+ return [model, ...contextArgs.args];
1168
+ }
1169
+ async updateAllPrefix(models, ...args) {
1170
+ const contextArgs = await Context.args(OperationKeys.UPDATE, this.class, args);
1171
+ await Promise.all(models.map((m) => {
1172
+ m = new this.class(m);
1173
+ enforceDBDecorators(this, contextArgs.context, m, OperationKeys.UPDATE, OperationKeys.ON);
1174
+ return m;
1175
+ }));
1176
+ return [models, ...contextArgs.args];
1177
+ }
1178
+ async updateAllSuffix(models, context) {
1179
+ await Promise.all(models.map((m) => enforceDBDecorators(this, context, m, OperationKeys.UPDATE, OperationKeys.AFTER)));
1180
+ return models;
1181
+ }
1182
+ async deleteAll(keys, ...args) {
1183
+ return Promise.all(keys.map((k) => this.delete(k, ...args)));
1184
+ }
1185
+ async deleteSuffix(model, context) {
1186
+ await enforceDBDecorators(this, context, model, OperationKeys.DELETE, OperationKeys.AFTER);
1187
+ return model;
1188
+ }
1189
+ async deletePrefix(key, ...args) {
1190
+ const contextArgs = await Context.args(OperationKeys.DELETE, this.class, args);
1191
+ const model = await this.read(key, ...contextArgs.args);
1192
+ await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.DELETE, OperationKeys.ON);
1193
+ return [key, ...contextArgs.args];
1194
+ }
1195
+ async deleteAllPrefix(keys, ...args) {
1196
+ const contextArgs = await Context.args(OperationKeys.DELETE, this.class, args);
1197
+ const models = await this.readAll(keys, ...contextArgs.args);
1198
+ await Promise.all(models.map(async (m) => {
1199
+ return enforceDBDecorators(this, contextArgs.context, m, OperationKeys.DELETE, OperationKeys.ON);
1200
+ }));
1201
+ return [keys, ...contextArgs.args];
1202
+ }
1203
+ async deleteAllSuffix(models, context) {
1204
+ await Promise.all(models.map((m) => enforceDBDecorators(this, context, m, OperationKeys.DELETE, OperationKeys.AFTER)));
1205
+ return models;
1206
+ }
1207
+ merge(oldModel, model) {
1208
+ const extract = (model) => Object.entries(model).reduce((accum, [key, val]) => {
1209
+ if (typeof val !== "undefined")
1210
+ accum[key] = val;
1211
+ return accum;
1212
+ }, {});
1213
+ return new this.class(Object.assign({}, extract(oldModel), extract(model)));
1214
+ }
1215
+ toString() {
1216
+ return sf("[{0}] - Repository for {1}", this.constructor.name, this.class.name);
1217
+ }
1218
+ }
1219
+
1220
+ class Repository extends BaseRepository {
1221
+ constructor(clazz) {
1222
+ super(clazz);
1223
+ }
1224
+ async createPrefix(model, ...args) {
1225
+ const contextArgs = await Context.args(OperationKeys.CREATE, this.class, args);
1226
+ model = new this.class(model);
1227
+ await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.CREATE, OperationKeys.ON);
1228
+ const errors = model.hasErrors();
1229
+ if (errors)
1230
+ throw new ValidationError(errors.toString());
1231
+ return [model, ...contextArgs.args];
1232
+ }
1233
+ async createAllPrefix(models, ...args) {
1234
+ const contextArgs = await Context.args(OperationKeys.CREATE, this.class, args);
1235
+ await Promise.all(models.map(async (m) => {
1236
+ m = new this.class(m);
1237
+ await enforceDBDecorators(this, contextArgs.context, m, OperationKeys.CREATE, OperationKeys.ON);
1238
+ return m;
1239
+ }));
1240
+ const errors = models
1241
+ .map((m) => m.hasErrors())
1242
+ .reduce((accum, e, i) => {
1243
+ if (e)
1244
+ accum =
1245
+ typeof accum === "string"
1246
+ ? accum + `\n - ${i}: ${e.toString()}`
1247
+ : ` - ${i}: ${e.toString()}`;
1248
+ return accum;
1249
+ }, undefined);
1250
+ if (errors)
1251
+ throw new ValidationError(errors);
1252
+ return [models, ...contextArgs.args];
1253
+ }
1254
+ async updatePrefix(model, ...args) {
1255
+ const contextArgs = await Context.args(OperationKeys.UPDATE, this.class, args);
1256
+ const pk = model[this.pk];
1257
+ if (!pk)
1258
+ throw new InternalError(`No value for the Id is defined under the property ${this.pk}`);
1259
+ const oldModel = await this.read(pk);
1260
+ model = this.merge(oldModel, model);
1261
+ await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.UPDATE, OperationKeys.ON, oldModel);
1262
+ const errors = model.hasErrors(oldModel);
1263
+ if (errors)
1264
+ throw new ValidationError(errors.toString());
1265
+ return [model, ...contextArgs.args];
1266
+ }
1267
+ async updateAllPrefix(models, ...args) {
1268
+ const contextArgs = await Context.args(OperationKeys.UPDATE, this.class, args);
1269
+ const ids = models.map((m) => {
1270
+ const id = m[this.pk];
1271
+ if (!id)
1272
+ throw new InternalError(`No value for the Id is defined under the property ${this.pk}`);
1273
+ return id;
1274
+ });
1275
+ const oldModels = await this.readAll(ids, ...contextArgs.args);
1276
+ models = models.map((m, i) => this.merge(oldModels[i], m));
1277
+ await Promise.all(models.map((m, i) => enforceDBDecorators(this, contextArgs.context, m, OperationKeys.UPDATE, OperationKeys.ON, oldModels[i])));
1278
+ const errors = models
1279
+ .map((m, i) => m.hasErrors(oldModels[i], m))
1280
+ .reduce((accum, e, i) => {
1281
+ if (e)
1282
+ accum =
1283
+ typeof accum === "string"
1284
+ ? accum + `\n - ${i}: ${e.toString()}`
1285
+ : ` - ${i}: ${e.toString()}`;
1286
+ return accum;
1287
+ }, undefined);
1288
+ if (errors)
1289
+ throw new ValidationError(errors);
1290
+ return [models, ...contextArgs.args];
1291
+ }
1292
+ static key(key) {
1293
+ return DBKeys.REFLECT + key;
1294
+ }
1295
+ }
1296
+
1297
+ /**
1298
+ * Marks the property as readonly.
1299
+ *
1300
+ * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES.READONLY.INVALID}
1301
+ *
1302
+ * @decorator readonly
1303
+ *
1304
+ * @category Decorators
1305
+ */
1306
+ function readonly(message = DEFAULT_ERROR_MESSAGES.READONLY.INVALID) {
1307
+ return propMetadata(Validation.updateKey(DBKeys.READONLY), {
1308
+ message: message,
1309
+ });
1310
+ }
1311
+ async function timestampHandler(context, data, key, model) {
1312
+ model[key] = context.timestamp;
1313
+ }
1314
+ /**
1315
+ * Marks the property as timestamp.
1316
+ * Makes it {@link required}
1317
+ * Makes it a {@link date}
1318
+ *
1319
+ * Date Format:
1320
+ *
1321
+ * <pre>
1322
+ * Using similar formatting as Moment.js, Class DateTimeFormatter (Java), and Class SimpleDateFormat (Java),
1323
+ * I implemented a comprehensive solution formatDate(date, patternStr) where the code is easy to read and modify.
1324
+ * You can display date, time, AM/PM, etc.
1325
+ *
1326
+ * Date and Time Patterns
1327
+ * yy = 2-digit year; yyyy = full year
1328
+ * M = digit month; MM = 2-digit month; MMM = short month name; MMMM = full month name
1329
+ * EEEE = full weekday name; EEE = short weekday name
1330
+ * d = digit day; dd = 2-digit day
1331
+ * h = hours am/pm; hh = 2-digit hours am/pm; H = hours; HH = 2-digit hours
1332
+ * m = minutes; mm = 2-digit minutes; aaa = AM/PM
1333
+ * s = seconds; ss = 2-digit seconds
1334
+ * S = miliseconds
1335
+ * </pre>
1336
+ *
1337
+ * @param {string[]} operation The {@link DBOperations} to act on. Defaults to {@link DBOperations.CREATE_UPDATE}
1338
+ * @param {string} [format] The TimeStamp format. defaults to {@link DEFAULT_TIMESTAMP_FORMAT}
1339
+ * @param {{new: UpdateValidator}} [validator] defaults to {@link TimestampValidator}
1340
+ *
1341
+ * @decorator timestamp
1342
+ *
1343
+ * @category Decorators
1344
+ */
1345
+ function timestamp(operation = DBOperations.CREATE_UPDATE, format = DEFAULT_TIMESTAMP_FORMAT) {
1346
+ const decorators = [
1347
+ date(format, DEFAULT_ERROR_MESSAGES.TIMESTAMP.DATE),
1348
+ required(DEFAULT_ERROR_MESSAGES.TIMESTAMP.REQUIRED),
1349
+ on(operation, timestampHandler),
1350
+ ];
1351
+ if (operation.indexOf(OperationKeys.UPDATE) !== -1)
1352
+ decorators.push(propMetadata(Validation.updateKey(DBKeys.TIMESTAMP), {
1353
+ message: DEFAULT_ERROR_MESSAGES.TIMESTAMP.INVALID,
1354
+ }));
1355
+ return apply(...decorators);
1356
+ }
1357
+ async function serializeOnCreateUpdate(data, key, model, oldModel) {
1358
+ if (!model[key])
1359
+ return;
1360
+ try {
1361
+ model[key] = JSON.stringify(model[key]);
1362
+ }
1363
+ catch (e) {
1364
+ throw new SerializationError(sf("Failed to serialize {0} property on {1} model: {2}", key, model.constructor.name, e.message));
1365
+ }
1366
+ }
1367
+ async function serializeAfterAll(data, key, model) {
1368
+ if (!model[key])
1369
+ return;
1370
+ if (typeof model[key] !== "string")
1371
+ return;
1372
+ try {
1373
+ model[key] = JSON.parse(model[key]);
1374
+ }
1375
+ catch (e) {
1376
+ throw new SerializationError(sf("Failed to deserialize {0} property on {1} model: {2}", key, model.constructor.name, e.message));
1377
+ }
1378
+ }
1379
+ /**
1380
+ * @summary Serialize Decorator
1381
+ * @description properties decorated will the serialized before stored in the db
1382
+ *
1383
+ * @function serialize
1384
+ *
1385
+ * @memberOf module:wallet-db.Decorators
1386
+ */
1387
+ function serialize() {
1388
+ return apply(onCreateUpdate(serializeOnCreateUpdate), after(DBOperations.ALL, serializeAfterAll), type([String.name, Object.name]), metadata(Repository.key(DBKeys.SERIALIZE), {}));
1389
+ }
1390
+ //
1391
+ // /**
1392
+ // * @summary One To One relation Decorators
1393
+ // *
1394
+ // * @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
1395
+ // * @param {CascadeMetadata} [cascadeOptions]
1396
+ // * @param {boolean} _populate If true, replaces the specified key in the document with the corresponding record from the database
1397
+ // *
1398
+ // * @function onToOne
1399
+ // *
1400
+ // * @memberOf module:wallet-db.Decorators
1401
+ // *
1402
+ // * @see oneToMany
1403
+ // * @see manyToOne
1404
+ // */
1405
+ // export function oneToOne(
1406
+ // clazz: Constructor<any>,
1407
+ // cascadeOptions: CascadeMetadata = DefaultCascade,
1408
+ // _populate: boolean = true,
1409
+ // ) {
1410
+ // Model.register(clazz);
1411
+ // return (target: any, propertyKey: string) => {
1412
+ // type([clazz.name, String.name])(target, propertyKey);
1413
+ // onCreate(oneToOneOnCreate)(target, propertyKey);
1414
+ // onUpdate(oneToOneOnUpdate, cascadeOptions as any)(target, propertyKey);
1415
+ // onDelete(oneToOneOnDelete, cascadeOptions)(target, propertyKey);
1416
+ //
1417
+ // afterCreate(populate, _populate)(target, propertyKey);
1418
+ // afterUpdate(populate, _populate)(target, propertyKey);
1419
+ // afterRead(populate, _populate)(target, propertyKey);
1420
+ // afterDelete(populate, _populate)(target, propertyKey);
1421
+ //
1422
+ // Reflect.defineMetadata(
1423
+ // getDBKey(WalletDbKeys.ONE_TO_ONE),
1424
+ // {
1425
+ // constructor: clazz.name,
1426
+ // cascade: cascadeOptions,
1427
+ // populate: _populate,
1428
+ // },
1429
+ // target,
1430
+ // propertyKey,
1431
+ // );
1432
+ // };
1433
+ // }
1434
+ //
1435
+ // /**
1436
+ // * @summary One To Many relation Decorators
1437
+ // *
1438
+ // * @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
1439
+ // * @param {CascadeMetadata} [cascadeOptions]
1440
+ // *
1441
+ // * @function onToMany
1442
+ // *
1443
+ // * @memberOf module:wallet-db.Decorators
1444
+ // *
1445
+ // * @see oneToOne
1446
+ // * @see manyToOne
1447
+ // */
1448
+ // export function oneToMany(
1449
+ // clazz: Constructor<any>,
1450
+ // cascadeOptions: CascadeMetadata = DefaultCascade,
1451
+ // _populate: boolean = true,
1452
+ // ) {
1453
+ // Model.register(clazz);
1454
+ // return (target: any, propertyKey: string) => {
1455
+ // list([clazz, String])(target, propertyKey);
1456
+ // onCreate(oneToManyOnCreate)(target, propertyKey);
1457
+ // onUpdate(oneToManyOnUpdate, cascadeOptions)(target, propertyKey);
1458
+ // onDelete(oneToManyOnDelete, cascadeOptions)(target, propertyKey);
1459
+ //
1460
+ // afterCreate(populate, _populate)(target, propertyKey);
1461
+ // afterUpdate(populate, _populate)(target, propertyKey);
1462
+ // afterRead(populate, _populate)(target, propertyKey);
1463
+ // afterDelete(populate, _populate)(target, propertyKey);
1464
+ //
1465
+ // Reflect.defineMetadata(
1466
+ // getDBKey(WalletDbKeys.ONE_TO_MANY),
1467
+ // {
1468
+ // constructor: clazz.name,
1469
+ // cascade: cascadeOptions,
1470
+ // },
1471
+ // target,
1472
+ // propertyKey,
1473
+ // );
1474
+ // };
1475
+ // }
1476
+ //
1477
+ // /**
1478
+ // * @summary Many To One relation Decorators
1479
+ // *
1480
+ // * @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
1481
+ // * @param {CascadeMetadata} [cascadeOptions]
1482
+ // *
1483
+ // * @function manyToOne
1484
+ // *
1485
+ // * @memberOf module:wallet-db.Decorators
1486
+ // *
1487
+ // * @see oneToMany
1488
+ // * @see oneToOne
1489
+ // */
1490
+ // export function manyToOne(
1491
+ // clazz: Constructor<any>,
1492
+ // cascadeOptions: CascadeMetadata = DefaultCascade,
1493
+ // ) {
1494
+ // Model.register(clazz);
1495
+ // return (target: any, propertyKey: string) => {
1496
+ // Reflect.defineMetadata(
1497
+ // getDBKey(WalletDbKeys.MANY_TO_ONE),
1498
+ // {
1499
+ // constructor: clazz.name,
1500
+ // cascade: cascadeOptions,
1501
+ // },
1502
+ // target,
1503
+ // propertyKey,
1504
+ // );
1505
+ // };
1506
+ // }
1507
+
1508
+ Validation.updateKey = function (key) {
1509
+ return UpdateValidationKeys.REFLECT + key;
1510
+ };
1511
+
1512
+ // // eslint-disable-next-line @typescript-eslint/no-unused-vars
1513
+ // import * as Validation from "../validation/validation";
1514
+ function id() {
1515
+ return apply(required(), readonly(), propMetadata(Repository.key(DBKeys.ID), {}));
1516
+ }
1517
+
1518
+ /**
1519
+ * @summary Validates the update of a model
1520
+ *
1521
+ * @param {T} oldModel
1522
+ * @param {T} newModel
1523
+ * @param {string[]} [exceptions]
1524
+ *
1525
+ * @function validateCompare
1526
+ * @return {ModelErrorDefinition | undefined}
1527
+ *
1528
+ * @memberOf module:db-decorators.Model
1529
+ */
1530
+ function validateCompare(oldModel, newModel, ...exceptions) {
1531
+ const decoratedProperties = [];
1532
+ for (const prop in newModel)
1533
+ if (Object.prototype.hasOwnProperty.call(newModel, prop) &&
1534
+ exceptions.indexOf(prop) === -1)
1535
+ decoratedProperties.push(Reflection.getPropertyDecorators(UpdateValidationKeys.REFLECT, newModel, prop));
1536
+ let result = undefined;
1537
+ for (const decoratedProperty of decoratedProperties) {
1538
+ const { prop, decorators } = decoratedProperty;
1539
+ decorators.shift(); // remove the design:type decorator, since the type will already be checked
1540
+ if (!decorators || !decorators.length)
1541
+ continue;
1542
+ let errs = undefined;
1543
+ for (const decorator of decorators) {
1544
+ const validator = Validation.get(decorator.key);
1545
+ if (!validator) {
1546
+ console.error(`Could not find Matching validator for ${decorator.key} for property ${String(decoratedProperty.prop)}`);
1547
+ continue;
1548
+ }
1549
+ const err = validator.updateHasErrors(newModel[prop.toString()], oldModel[prop.toString()], ...Object.values(decorator.props));
1550
+ if (err) {
1551
+ errs = errs || {};
1552
+ errs[decorator.key] = err;
1553
+ }
1554
+ }
1555
+ if (errs) {
1556
+ result = result || {};
1557
+ result[decoratedProperty.prop.toString()] = errs;
1558
+ }
1559
+ }
1560
+ // tests nested classes
1561
+ for (const prop of Object.keys(newModel).filter((k) => {
1562
+ if (exceptions.includes(k))
1563
+ return false;
1564
+ return !result || !result[k];
1565
+ })) {
1566
+ let err;
1567
+ // if a nested Model
1568
+ const allDecorators = Reflection.getPropertyDecorators(ValidationKeys.REFLECT, newModel, prop).decorators;
1569
+ const decorators = Reflection.getPropertyDecorators(ValidationKeys.REFLECT, newModel, prop).decorators.filter((d) => [ModelKeys.TYPE, ValidationKeys.TYPE].indexOf(d.key) !== -1);
1570
+ if (!decorators || !decorators.length)
1571
+ continue;
1572
+ const dec = decorators.pop();
1573
+ const clazz = dec.props.name
1574
+ ? [dec.props.name]
1575
+ : Array.isArray(dec.props.customTypes)
1576
+ ? dec.props.customTypes
1577
+ : [dec.props.customTypes];
1578
+ const reserved = Object.values(ReservedModels).map((v) => v.toLowerCase());
1579
+ for (const c of clazz) {
1580
+ if (reserved.indexOf(c.toLowerCase()) === -1) {
1581
+ switch (c) {
1582
+ case Array.name:
1583
+ case Set.name:
1584
+ if (allDecorators.length) {
1585
+ const listDec = allDecorators.find((d) => d.key === ValidationKeys.LIST);
1586
+ if (listDec) {
1587
+ let currentList, oldList;
1588
+ switch (c) {
1589
+ case Array.name:
1590
+ currentList = newModel[prop];
1591
+ oldList = oldModel[prop];
1592
+ break;
1593
+ case Set.name:
1594
+ currentList = newModel[prop].values();
1595
+ oldList = oldModel[prop].values();
1596
+ break;
1597
+ default:
1598
+ throw new Error(`Invalid attribute type ${c}`);
1599
+ }
1600
+ err = currentList
1601
+ .map((v) => {
1602
+ const id = findModelId(v, true);
1603
+ if (!id)
1604
+ return "Failed to find model id";
1605
+ const oldModel = oldList.find((el) => id === findModelId(el, true));
1606
+ if (!oldModel)
1607
+ return; // nothing to compare with
1608
+ return v.hasErrors(oldModel);
1609
+ })
1610
+ .filter((e) => !!e);
1611
+ if (!err?.length) {
1612
+ // if the result is an empty list...
1613
+ err = undefined;
1614
+ }
1615
+ }
1616
+ }
1617
+ break;
1618
+ default:
1619
+ try {
1620
+ if (newModel[prop] &&
1621
+ oldModel[prop])
1622
+ err = newModel[prop].hasErrors(oldModel[prop]);
1623
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1624
+ }
1625
+ catch (e) {
1626
+ console.warn(sf("Model should be validatable but its not"));
1627
+ }
1628
+ }
1629
+ }
1630
+ if (err) {
1631
+ result = result || {};
1632
+ result[prop] = err;
1633
+ }
1634
+ }
1635
+ }
1636
+ return result ? new ModelErrorDefinition(result) : undefined;
1637
+ }
1638
+
1639
+ /**
1640
+ *
1641
+ * @param {str} str
1642
+ * @memberOf db-decorators.model
1643
+ */
1644
+ function hashOnCreateUpdate(data, key, model, oldModel) {
1645
+ if (!model[key])
1646
+ return;
1647
+ const hash = Hashing.hash(model[key]);
1648
+ if (oldModel && model[key] === hash)
1649
+ return;
1650
+ model[key] = hash;
1651
+ }
1652
+ function hash() {
1653
+ return apply(onCreateUpdate(hashOnCreateUpdate), propMetadata(Repository.key(DBKeys.HASH), {}));
1654
+ }
1655
+ function composedFromCreateUpdate(context, data, key, model) {
1656
+ try {
1657
+ const { args, type, prefix, suffix, separator } = data;
1658
+ const composed = args.map((arg) => {
1659
+ if (!(arg in model))
1660
+ throw new InternalError(sf("Property {0} not found to compose from", arg));
1661
+ if (type === "keys")
1662
+ return arg;
1663
+ if (typeof model[arg] === "undefined")
1664
+ throw new InternalError(sf("Property {0} does not contain a value to compose from", arg));
1665
+ return model[arg].toString();
1666
+ });
1667
+ if (prefix)
1668
+ composed.unshift(prefix);
1669
+ if (suffix)
1670
+ composed.push(suffix);
1671
+ model[key] = composed.join(separator);
1672
+ }
1673
+ catch (e) {
1674
+ throw new InternalError(`Failed to compose value: ${e}`);
1675
+ }
1676
+ }
1677
+ function composedFrom(args, hashResult = false, separator = DefaultSeparator, type = "values", prefix = "", suffix = "") {
1678
+ const data = {
1679
+ args: args,
1680
+ hashResult: hashResult,
1681
+ separator: separator,
1682
+ type: type,
1683
+ prefix: prefix,
1684
+ suffix: suffix,
1685
+ };
1686
+ const decorators = [
1687
+ onCreateUpdate(composedFromCreateUpdate, data),
1688
+ propMetadata(Repository.key(DBKeys.COMPOSED), data),
1689
+ ];
1690
+ if (hashResult)
1691
+ decorators.push(hash());
1692
+ return apply(...decorators);
1693
+ }
1694
+ function composedFromKeys(args, separator = DefaultSeparator, hash = false, prefix = "", suffix = "") {
1695
+ return composedFrom(args, hash, separator, "keys", prefix, suffix);
1696
+ }
1697
+ function composed(args, separator = DefaultSeparator, hash = false, prefix = "", suffix = "") {
1698
+ return composedFrom(args, hash, separator, "values", prefix, suffix);
1699
+ }
1700
+ /**
1701
+ * Creates a decorator function that updates the version of a model during create or update operations.
1702
+ *
1703
+ * @param {CrudOperations} operation - The type of operation being performed (CREATE or UPDATE).
1704
+ * @returns {function} A function that updates the version of the model based on the operation type.
1705
+ *
1706
+ * @template M - Type extending Model
1707
+ * @template V - Type extending IRepository<M>
1708
+ *
1709
+ * @this {V} - The repository instance
1710
+ * @param {Context<M>} context - The context of the operation
1711
+ * @param {unknown} data - Additional data for the operation (not used in this function)
1712
+ * @param {string} key - The key of the version property in the model
1713
+ * @param {M} model - The model being updated
1714
+ * @throws {InternalError} If an invalid operation is provided or if version update fails
1715
+ */
1716
+ function versionCreateUpdate(operation) {
1717
+ return function versionCreateUpdate(context, data, key, model) {
1718
+ try {
1719
+ switch (operation) {
1720
+ case OperationKeys.CREATE:
1721
+ model[key] = 1;
1722
+ break;
1723
+ case OperationKeys.UPDATE:
1724
+ model[key]++;
1725
+ break;
1726
+ default:
1727
+ throw new InternalError(`Invalid operation: ${operation}`);
1728
+ }
1729
+ }
1730
+ catch (e) {
1731
+ throw new InternalError(`Failed to update version: ${e}`);
1732
+ }
1733
+ };
1734
+ }
1735
+ /**
1736
+ * @description Creates a decorator for versioning a property in a model.
1737
+ * @summary This decorator applies multiple sub-decorators to handle version management during create and update operations.
1738
+ *
1739
+ * @returns {Function} A composite decorator that:
1740
+ * - Sets the type of the property to Number
1741
+ * - Applies a version update on create operations
1742
+ * - Applies a version update on update operations
1743
+ * - Adds metadata indicating this property is used for versioning
1744
+ */
1745
+ function version() {
1746
+ return apply(type(Number.name), onCreate(versionCreateUpdate(OperationKeys.CREATE)), onUpdate(versionCreateUpdate(OperationKeys.UPDATE)), propMetadata(Repository.key(DBKeys.VERSION), true));
1747
+ }
1748
+
1749
+ Model.prototype.hasErrors = function (previousVersion, ...exclusions) {
1750
+ if (previousVersion && !(previousVersion instanceof Model)) {
1751
+ exclusions.unshift(previousVersion);
1752
+ previousVersion = undefined;
1753
+ }
1754
+ const errs = validate(this, ...exclusions);
1755
+ if (errs || !previousVersion)
1756
+ return errs;
1757
+ return validateCompare(previousVersion, this, ...exclusions);
1758
+ };
1759
+
1760
+ export { BaseError, BaseRepository, ConflictError, Context, DBKeys, DBOperations, DEFAULT_ERROR_MESSAGES, DEFAULT_TIMESTAMP_FORMAT, DataCache, DefaultSeparator, InternalError, NotFoundError, OperationKeys, Operations, OperationsRegistry, ReadOnlyValidator, Repository, SerializationError, TimestampValidator, UpdateValidationKeys, UpdateValidator, ValidationError, after, afterAny, afterCreate, afterCreateUpdate, afterDelete, afterRead, afterUpdate, composed, composedFromCreateUpdate, composedFromKeys, enforceDBDecorators, findModelId, findPrimaryKey, getAllPropertyDecoratorsRecursive, getDbDecorators, getHandlerArgs, hash, hashOnCreateUpdate, id, on, onAny, onCreate, onCreateUpdate, onDelete, onRead, onUpdate, operation, prefixMethod, readonly, serialize, serializeAfterAll, serializeOnCreateUpdate, suffixMethod, timestamp, timestampHandler, validateCompare, version, versionCreateUpdate, wrapMethodWithContext };
1761
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGItZGVjb3JhdG9ycy5lc20uY2pzIiwic291cmNlcyI6WyIuLi9ub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuZXM2LmpzIiwiLi4vc3JjL21vZGVsL2NvbnN0YW50cy50cyIsIi4uL3NyYy92YWxpZGF0aW9uL2NvbnN0YW50cy50cyIsIi4uL3NyYy92YWxpZGF0aW9uL3ZhbGlkYXRvcnMvUmVhZE9ubHlWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi92YWxpZGF0b3JzL1RpbWVzdGFtcFZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL3ZhbGlkYXRvcnMvVXBkYXRlVmFsaWRhdG9yLnRzIiwiLi4vc3JjL29wZXJhdGlvbnMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL29wZXJhdGlvbnMvT3BlcmF0aW9uc1JlZ2lzdHJ5LnRzIiwiLi4vc3JjL29wZXJhdGlvbnMvT3BlcmF0aW9ucy50cyIsIi4uL3NyYy9vcGVyYXRpb25zL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS9lcnJvcnMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS91dGlscy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L0RhdGFDYWNoZS50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L0NvbnRleHQudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS93cmFwcGVycy50cyIsIi4uL3NyYy9pZGVudGl0eS91dGlscy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L0Jhc2VSZXBvc2l0b3J5LnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvUmVwb3NpdG9yeS50cyIsIi4uL3NyYy92YWxpZGF0aW9uL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi92YWxpZGF0aW9uLnRzIiwiLi4vc3JjL2lkZW50aXR5L2RlY29yYXRvcnMudHMiLCIuLi9zcmMvbW9kZWwvdmFsaWRhdGlvbi50cyIsIi4uL3NyYy9tb2RlbC9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL21vZGVsL21vZGVsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSwgU3VwcHJlc3NlZEVycm9yLCBTeW1ib2wsIEl0ZXJhdG9yICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2VzRGVjb3JhdGUoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcclxuICAgIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lkIDAgJiYgdHlwZW9mIGYgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZ1bmN0aW9uIGV4cGVjdGVkXCIpOyByZXR1cm4gZjsgfVxyXG4gICAgdmFyIGtpbmQgPSBjb250ZXh0SW4ua2luZCwga2V5ID0ga2luZCA9PT0gXCJnZXR0ZXJcIiA/IFwiZ2V0XCIgOiBraW5kID09PSBcInNldHRlclwiID8gXCJzZXRcIiA6IFwidmFsdWVcIjtcclxuICAgIHZhciB0YXJnZXQgPSAhZGVzY3JpcHRvckluICYmIGN0b3IgPyBjb250ZXh0SW5bXCJzdGF0aWNcIl0gPyBjdG9yIDogY3Rvci5wcm90b3R5cGUgOiBudWxsO1xyXG4gICAgdmFyIGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9ySW4gfHwgKHRhcmdldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSkgOiB7fSk7XHJcbiAgICB2YXIgXywgZG9uZSA9IGZhbHNlO1xyXG4gICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgY29udGV4dCA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluKSBjb250ZXh0W3BdID0gcCA9PT0gXCJhY2Nlc3NcIiA/IHt9IDogY29udGV4dEluW3BdO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluLmFjY2VzcykgY29udGV4dC5hY2Nlc3NbcF0gPSBjb250ZXh0SW4uYWNjZXNzW3BdO1xyXG4gICAgICAgIGNvbnRleHQuYWRkSW5pdGlhbGl6ZXIgPSBmdW5jdGlvbiAoZikgeyBpZiAoZG9uZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBhZGQgaW5pdGlhbGl6ZXJzIGFmdGVyIGRlY29yYXRpb24gaGFzIGNvbXBsZXRlZFwiKTsgZXh0cmFJbml0aWFsaXplcnMucHVzaChhY2NlcHQoZiB8fCBudWxsKSk7IH07XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9ICgwLCBkZWNvcmF0b3JzW2ldKShraW5kID09PSBcImFjY2Vzc29yXCIgPyB7IGdldDogZGVzY3JpcHRvci5nZXQsIHNldDogZGVzY3JpcHRvci5zZXQgfSA6IGRlc2NyaXB0b3Jba2V5XSwgY29udGV4dCk7XHJcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYWNjZXNzb3JcIikge1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHR5cGVvZiByZXN1bHQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWRcIik7XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5nZXQpKSBkZXNjcmlwdG9yLmdldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5zZXQpKSBkZXNjcmlwdG9yLnNldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5pbml0KSkgaW5pdGlhbGl6ZXJzLnVuc2hpZnQoXyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKF8gPSBhY2NlcHQocmVzdWx0KSkge1xyXG4gICAgICAgICAgICBpZiAoa2luZCA9PT0gXCJmaWVsZFwiKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICAgICAgZWxzZSBkZXNjcmlwdG9yW2tleV0gPSBfO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0YXJnZXQpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGNvbnRleHRJbi5uYW1lLCBkZXNjcmlwdG9yKTtcclxuICAgIGRvbmUgPSB0cnVlO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcnVuSW5pdGlhbGl6ZXJzKHRoaXNBcmcsIGluaXRpYWxpemVycywgdmFsdWUpIHtcclxuICAgIHZhciB1c2VWYWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbml0aWFsaXplcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB2YWx1ZSA9IHVzZVZhbHVlID8gaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZywgdmFsdWUpIDogaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdXNlVmFsdWUgPyB2YWx1ZSA6IHZvaWQgMDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Byb3BLZXkoeCkge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc2V0RnVuY3Rpb25OYW1lKGYsIG5hbWUsIHByZWZpeCkge1xyXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN5bWJvbFwiKSBuYW1lID0gbmFtZS5kZXNjcmlwdGlvbiA/IFwiW1wiLmNvbmNhdChuYW1lLmRlc2NyaXB0aW9uLCBcIl1cIikgOiBcIlwiO1xyXG4gICAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmLCBcIm5hbWVcIiwgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBwcmVmaXggPyBcIlwiLmNvbmNhdChwcmVmaXgsIFwiIFwiLCBuYW1lKSA6IG5hbWUgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnID0gT2JqZWN0LmNyZWF0ZSgodHlwZW9mIEl0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKTtcclxuICAgIHJldHVybiBnLm5leHQgPSB2ZXJiKDApLCBnW1widGhyb3dcIl0gPSB2ZXJiKDEpLCBnW1wicmV0dXJuXCJdID0gdmVyYigyKSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChnICYmIChnID0gMCwgb3BbMF0gJiYgKF8gPSAwKSksIF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xyXG4gICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcclxuICAgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xyXG4gICAgfVxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgQXN5bmNJdGVyYXRvciA9PT0gXCJmdW5jdGlvblwiID8gQXN5bmNJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiLCBhd2FpdFJldHVybiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIGF3YWl0UmV0dXJuKGYpIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUodikudGhlbihmLCByZWplY3QpOyB9OyB9XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaWYgKGdbbl0pIHsgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgaWYgKGYpIGlbbl0gPSBmKGlbbl0pOyB9IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBmYWxzZSB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxufSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbn07XHJcblxyXG52YXIgb3duS2V5cyA9IGZ1bmN0aW9uKG8pIHtcclxuICAgIG93bktleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB8fCBmdW5jdGlvbiAobykge1xyXG4gICAgICAgIHZhciBhciA9IFtdO1xyXG4gICAgICAgIGZvciAodmFyIGsgaW4gbykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBrKSkgYXJbYXIubGVuZ3RoXSA9IGs7XHJcbiAgICAgICAgcmV0dXJuIGFyO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBvd25LZXlzKG8pO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgPSBvd25LZXlzKG1vZCksIGkgPSAwOyBpIDwgay5sZW5ndGg7IGkrKykgaWYgKGtbaV0gIT09IFwiZGVmYXVsdFwiKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGtbaV0pO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xyXG4gICAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XHJcbiAgICByZXR1cm4gdHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciA9PT0gc3RhdGUgOiBzdGF0ZS5oYXMocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hZGREaXNwb3NhYmxlUmVzb3VyY2UoZW52LCB2YWx1ZSwgYXN5bmMpIHtcclxuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdm9pZCAwKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZC5cIik7XHJcbiAgICAgICAgdmFyIGRpc3Bvc2UsIGlubmVyO1xyXG4gICAgICAgIGlmIChhc3luYykge1xyXG4gICAgICAgICAgICBpZiAoIVN5bWJvbC5hc3luY0Rpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNEaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5hc3luY0Rpc3Bvc2VdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZGlzcG9zZSA9PT0gdm9pZCAwKSB7XHJcbiAgICAgICAgICAgIGlmICghU3ltYm9sLmRpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuZGlzcG9zZSBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICAgICAgICAgIGRpc3Bvc2UgPSB2YWx1ZVtTeW1ib2wuZGlzcG9zZV07XHJcbiAgICAgICAgICAgIGlmIChhc3luYykgaW5uZXIgPSBkaXNwb3NlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHlwZW9mIGRpc3Bvc2UgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBub3QgZGlzcG9zYWJsZS5cIik7XHJcbiAgICAgICAgaWYgKGlubmVyKSBkaXNwb3NlID0gZnVuY3Rpb24oKSB7IHRyeSB7IGlubmVyLmNhbGwodGhpcyk7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpOyB9IH07XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyB2YWx1ZTogdmFsdWUsIGRpc3Bvc2U6IGRpc3Bvc2UsIGFzeW5jOiBhc3luYyB9KTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyBhc3luYzogdHJ1ZSB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB2YWx1ZTtcclxuXHJcbn1cclxuXHJcbnZhciBfU3VwcHJlc3NlZEVycm9yID0gdHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gXCJmdW5jdGlvblwiID8gU3VwcHJlc3NlZEVycm9yIDogZnVuY3Rpb24gKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7XHJcbiAgICB2YXIgZSA9IG5ldyBFcnJvcihtZXNzYWdlKTtcclxuICAgIHJldHVybiBlLm5hbWUgPSBcIlN1cHByZXNzZWRFcnJvclwiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kaXNwb3NlUmVzb3VyY2VzKGVudikge1xyXG4gICAgZnVuY3Rpb24gZmFpbChlKSB7XHJcbiAgICAgICAgZW52LmVycm9yID0gZW52Lmhhc0Vycm9yID8gbmV3IF9TdXBwcmVzc2VkRXJyb3IoZSwgZW52LmVycm9yLCBcIkFuIGVycm9yIHdhcyBzdXBwcmVzc2VkIGR1cmluZyBkaXNwb3NhbC5cIikgOiBlO1xyXG4gICAgICAgIGVudi5oYXNFcnJvciA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB2YXIgciwgcyA9IDA7XHJcbiAgICBmdW5jdGlvbiBuZXh0KCkge1xyXG4gICAgICAgIHdoaWxlIChyID0gZW52LnN0YWNrLnBvcCgpKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXIuYXN5bmMgJiYgcyA9PT0gMSkgcmV0dXJuIHMgPSAwLCBlbnYuc3RhY2sucHVzaChyKSwgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihuZXh0KTtcclxuICAgICAgICAgICAgICAgIGlmIChyLmRpc3Bvc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gci5kaXNwb3NlLmNhbGwoci52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHIuYXN5bmMpIHJldHVybiBzIHw9IDIsIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLnRoZW4obmV4dCwgZnVuY3Rpb24oZSkgeyBmYWlsKGUpOyByZXR1cm4gbmV4dCgpOyB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgcyB8PSAxO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBmYWlsKGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzID09PSAxKSByZXR1cm4gZW52Lmhhc0Vycm9yID8gUHJvbWlzZS5yZWplY3QoZW52LmVycm9yKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIGlmIChlbnYuaGFzRXJyb3IpIHRocm93IGVudi5lcnJvcjtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXh0KCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbihwYXRoLCBwcmVzZXJ2ZUpzeCkge1xyXG4gICAgaWYgKHR5cGVvZiBwYXRoID09PSBcInN0cmluZ1wiICYmIC9eXFwuXFwuP1xcLy8udGVzdChwYXRoKSkge1xyXG4gICAgICAgIHJldHVybiBwYXRoLnJlcGxhY2UoL1xcLih0c3gpJHwoKD86XFwuZCk/KSgoPzpcXC5bXi4vXSs/KT8pXFwuKFtjbV0/KXRzJC9pLCBmdW5jdGlvbiAobSwgdHN4LCBkLCBleHQsIGNtKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0c3ggPyBwcmVzZXJ2ZUpzeCA/IFwiLmpzeFwiIDogXCIuanNcIiA6IGQgJiYgKCFleHQgfHwgIWNtKSA/IG0gOiAoZCArIGV4dCArIFwiLlwiICsgY20udG9Mb3dlckNhc2UoKSArIFwianNcIik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGF0aDtcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgX19leHRlbmRzOiBfX2V4dGVuZHMsXHJcbiAgICBfX2Fzc2lnbjogX19hc3NpZ24sXHJcbiAgICBfX3Jlc3Q6IF9fcmVzdCxcclxuICAgIF9fZGVjb3JhdGU6IF9fZGVjb3JhdGUsXHJcbiAgICBfX3BhcmFtOiBfX3BhcmFtLFxyXG4gICAgX19lc0RlY29yYXRlOiBfX2VzRGVjb3JhdGUsXHJcbiAgICBfX3J1bkluaXRpYWxpemVyczogX19ydW5Jbml0aWFsaXplcnMsXHJcbiAgICBfX3Byb3BLZXk6IF9fcHJvcEtleSxcclxuICAgIF9fc2V0RnVuY3Rpb25OYW1lOiBfX3NldEZ1bmN0aW9uTmFtZSxcclxuICAgIF9fbWV0YWRhdGE6IF9fbWV0YWRhdGEsXHJcbiAgICBfX2F3YWl0ZXI6IF9fYXdhaXRlcixcclxuICAgIF9fZ2VuZXJhdG9yOiBfX2dlbmVyYXRvcixcclxuICAgIF9fY3JlYXRlQmluZGluZzogX19jcmVhdGVCaW5kaW5nLFxyXG4gICAgX19leHBvcnRTdGFyOiBfX2V4cG9ydFN0YXIsXHJcbiAgICBfX3ZhbHVlczogX192YWx1ZXMsXHJcbiAgICBfX3JlYWQ6IF9fcmVhZCxcclxuICAgIF9fc3ByZWFkOiBfX3NwcmVhZCxcclxuICAgIF9fc3ByZWFkQXJyYXlzOiBfX3NwcmVhZEFycmF5cyxcclxuICAgIF9fc3ByZWFkQXJyYXk6IF9fc3ByZWFkQXJyYXksXHJcbiAgICBfX2F3YWl0OiBfX2F3YWl0LFxyXG4gICAgX19hc3luY0dlbmVyYXRvcjogX19hc3luY0dlbmVyYXRvcixcclxuICAgIF9fYXN5bmNEZWxlZ2F0b3I6IF9fYXN5bmNEZWxlZ2F0b3IsXHJcbiAgICBfX2FzeW5jVmFsdWVzOiBfX2FzeW5jVmFsdWVzLFxyXG4gICAgX19tYWtlVGVtcGxhdGVPYmplY3Q6IF9fbWFrZVRlbXBsYXRlT2JqZWN0LFxyXG4gICAgX19pbXBvcnRTdGFyOiBfX2ltcG9ydFN0YXIsXHJcbiAgICBfX2ltcG9ydERlZmF1bHQ6IF9faW1wb3J0RGVmYXVsdCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRHZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0OiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEluOiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4sXHJcbiAgICBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZTogX19hZGREaXNwb3NhYmxlUmVzb3VyY2UsXHJcbiAgICBfX2Rpc3Bvc2VSZXNvdXJjZXM6IF9fZGlzcG9zZVJlc291cmNlcyxcclxuICAgIF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uOiBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbixcclxufTtcclxuIiwiaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEhvbGRzIHRoZSBNb2RlbCByZWZsZWN0aW9uIGtleXNcbiAqIEBjb25zdCBEQktleXNcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuTW9kZWxcbiAqL1xuZXhwb3J0IGNvbnN0IERCS2V5cyA9IHtcbiAgUkVGTEVDVDogYCR7TW9kZWxLZXlzLlJFRkxFQ1R9cGVyc2lzdGVuY2UuYCxcbiAgUkVQT1NJVE9SWTogXCJyZXBvc2l0b3J5XCIsXG4gIENMQVNTOiBcIl9jbGFzc1wiLFxuICBJRDogXCJpZFwiLFxuICBJTkRFWDogXCJpbmRleFwiLFxuICBVTklRVUU6IFwidW5pcXVlXCIsXG4gIFNFUklBTElaRTogXCJzZXJpYWxpemVcIixcbiAgUkVBRE9OTFk6IFwicmVhZG9ubHlcIixcbiAgVElNRVNUQU1QOiBcInRpbWVzdGFtcFwiLFxuICBIQVNIOiBcImhhc2hcIixcbiAgQ09NUE9TRUQ6IFwiY29tcG9zZWRcIixcbiAgVkVSU0lPTjogXCJ2ZXJzaW9uXCIsXG4gIE9SSUdJTkFMOiBcIl9fb3JpZ2luYWxPYmpcIixcbn07XG5cbi8qKlxuICogQHN1bW1hcnkgVGhlIGRlZmF1bHQgc2VwYXJhdG9yIHdoZW4gY29uY2F0ZW5hdGluZyBpbmRleGVzXG4gKlxuICogQGNvbnN0IERlZmF1bHRJbmRleFNlcGFyYXRvclxuICpcbiAqIEBjYXRlZ29yeSBNYW5hZ2Vyc1xuICogQHN1YmNhdGVnb3J5IENvbnN0YW50c1xuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdFNlcGFyYXRvciA9IFwiX1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEhvbGRzIHRoZSBkZWZhdWx0IHRpbWVzdGFtcCBkYXRlIGZvcm1hdFxuICogQGNvbnN0YW50IERFRkFVTFRfVElNRVNUQU1QX0ZPUk1BVFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5Nb2RlbFxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9USU1FU1RBTVBfRk9STUFUID0gXCJkZC9NTS95eXl5IEhIOm1tOnNzOlNcIjtcbiIsImltcG9ydCB7IERCS2V5cyB9IGZyb20gXCIuLi9tb2RlbC9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBob2xkcyB0aGUgZGVmYXVsdCBlcnJvciBtZXNzYWdlc1xuICogQGNvbnN0IERFRkFVTFRfRVJST1JfTUVTU0FHRVNcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuTW9kZWxcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRVJST1JfTUVTU0FHRVMgPSB7XG4gIElEOiB7XG4gICAgSU5WQUxJRDogXCJUaGlzIElkIGlzIGludmFsaWRcIixcbiAgICBSRVFVSVJFRDogXCJUaGUgSWQgaXMgbWFuZGF0b3J5XCIsXG4gIH0sXG4gIFJFQURPTkxZOiB7XG4gICAgSU5WQUxJRDogXCJUaGlzIGNhbm5vdCBiZSB1cGRhdGVkXCIsXG4gIH0sXG4gIFRJTUVTVEFNUDoge1xuICAgIFJFUVVJUkVEOiBcIlRpbWVzdGFtcCBpcyBNYW5kYXRvcnlcIixcbiAgICBEQVRFOiBcIlRoZSBUaW1lc3RhbXAgbXVzdCB0aGUgYSB2YWxpZCBkYXRlXCIsXG4gICAgSU5WQUxJRDogXCJUaGlzIHZhbHVlIG11c3QgYWx3YXlzIGluY3JlYXNlXCIsXG4gIH0sXG59O1xuXG4vKipcbiAqIEBzdW1tYXJ5IFVwZGF0ZSByZWZsZWN0aW9uIGtleXNcbiAqIEBjb25zdCBVcGRhdGVWYWxpZGF0aW9uS2V5c1xuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzLk9wZXJhdGlvbnNcbiAqL1xuZXhwb3J0IGNvbnN0IFVwZGF0ZVZhbGlkYXRpb25LZXlzID0ge1xuICBSRUZMRUNUOiBcImRiLnVwZGF0ZS52YWxpZGF0aW9uLlwiLFxuICBUSU1FU1RBTVA6IERCS2V5cy5USU1FU1RBTVAsXG4gIFJFQURPTkxZOiBEQktleXMuUkVBRE9OTFksXG59O1xuIiwiaW1wb3J0IHsgdmFsaWRhdG9yLCBWYWxpZGF0b3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBVcGRhdGVWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IGlzRXF1YWwgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBWYWxpZGF0b3IgZm9yIHRoZSB7QGxpbmsgcmVhZG9ubHl9IGRlY29yYXRvclxuICpcbiAqIEBjbGFzcyBSZWFkT25seVZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihVcGRhdGVWYWxpZGF0aW9uS2V5cy5SRUFET05MWSlcbmV4cG9ydCBjbGFzcyBSZWFkT25seVZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUkVBRE9OTFkuSU5WQUxJRCk7XG4gIH1cblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgaGFzRXJyb3JzKHZhbHVlOiBhbnksIC4uLmFyZ3M6IGFueVtdKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIHZhbHVlIGhhcyBub3QgY2hhbmdlZFxuICAgKiBAcGFyYW0ge2FueX0gdmFsdWVcbiAgICogQHBhcmFtIHthbnl9IG9sZFZhbHVlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gdGhlIGVycm9yIG1lc3NhZ2Ugb3ZlcnJpZGVcbiAgICovXG4gIHB1YmxpYyB1cGRhdGVIYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvbGRWYWx1ZTogYW55LFxuICAgIG1lc3NhZ2U/OiBzdHJpbmcsXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgIHJldHVybiBpc0VxdWFsKHZhbHVlLCBvbGRWYWx1ZSlcbiAgICAgID8gdW5kZWZpbmVkXG4gICAgICA6IHRoaXMuZ2V0TWVzc2FnZShtZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IHZhbGlkYXRvciwgVmFsaWRhdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVXBkYXRlVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoZSB1cGRhdGUgb2YgYSB0aW1lc3RhbXBcbiAqXG4gKiBAY2xhc3MgVGltZXN0YW1wVmFsaWRhdG9yXG4gKiBAZXh0ZW5kcyBWYWxpZGF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFVwZGF0ZVZhbGlkYXRpb25LZXlzLlRJTUVTVEFNUClcbmV4cG9ydCBjbGFzcyBUaW1lc3RhbXBWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihERUZBVUxUX0VSUk9SX01FU1NBR0VTLlRJTUVTVEFNUC5JTlZBTElEKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgaGFzRXJyb3JzKHZhbHVlOiBhbnksIC4uLmFyZ3M6IGFueVtdKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIHVwZGF0ZUhhc0Vycm9ycyhcbiAgICB2YWx1ZTogRGF0ZSB8IHN0cmluZyB8IG51bWJlcixcbiAgICBvbGRWYWx1ZTogRGF0ZSB8IHN0cmluZyB8IG51bWJlcixcbiAgICBtZXNzYWdlPzogc3RyaW5nXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgIG1lc3NhZ2UgPSBtZXNzYWdlIHx8IHRoaXMuZ2V0TWVzc2FnZShtZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG5cbiAgICB0cnkge1xuICAgICAgdmFsdWUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICBvbGRWYWx1ZSA9IG5ldyBEYXRlKG9sZFZhbHVlKTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUgPD0gb2xkVmFsdWUgPyBtZXNzYWdlIDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBERUZBVUxUX0VSUk9SX01FU1NBR0VTIGFzIERlY29yYXRvck1lc3NhZ2VzLFxuICBWYWxpZGF0b3IsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBCYXNlIGNsYXNzIGZvciBhbiBVcGRhdGUgdmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSBlcnJvciBtZXNzYWdlLiBkZWZhdWx0cyB0byB7QGxpbmsgRGVjb3JhdG9yTWVzc2FnZXMjREVGQVVMVH1cbiAqIEBwYXJhbSB7c3RyaW5nW119IFthY2NlcHRlZFR5cGVzXSB0aGUgYWNjZXB0ZWQgdmFsdWUgdHlwZXMgYnkgdGhlIGRlY29yYXRvclxuICpcbiAqIEBjbGFzcyBVcGRhdGVWYWxpZGF0b3JcbiAqIEBhYnN0cmFjdFxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFVwZGF0ZVZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvciB7XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlOiBzdHJpbmcgPSBEZWNvcmF0b3JNZXNzYWdlcy5ERUZBVUxULFxuICAgIC4uLmFjY2VwdGVkVHlwZXM6IHN0cmluZ1tdXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIC4uLmFjY2VwdGVkVHlwZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHZhbGlkYXRlcyBhIHZhbHVlIGJ5IGNvbXBhcmluZyB0byBpdHMgb2xkIHZlcnNpb25cbiAgICogQHBhcmFtIHthbnl9IHZhbHVlXG4gICAqIEBwYXJhbSB7YW55fSBvbGRWYWx1ZVxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgdXBkYXRlSGFzRXJyb3JzKFxuICAgIHZhbHVlOiBhbnksXG4gICAgb2xkVmFsdWU6IGFueSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG4iLCIvKipcbiAqIEBzdW1tYXJ5IFNldCBvZiBjb25zdGFudHMgdG8gZGVmaW5lIGRiIENSVUQgb3BlcmF0aW9ucyBhbmQgdGhlaXIgZXF1aXZhbGVudCAnb24nIGFuZCAnYWZ0ZXInIHBoYXNlc1xuICogQGNvbnN0IE9wZXJhdGlvbktleXNcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuT3BlcmF0aW9uc1xuICovXG5leHBvcnQgZW51bSBPcGVyYXRpb25LZXlzIHtcbiAgUkVGTEVDVCA9IFwiZGVjYWYubW9kZWwuZGIub3BlcmF0aW9ucy5cIixcbiAgQ1JFQVRFID0gXCJjcmVhdGVcIixcbiAgUkVBRCA9IFwicmVhZFwiLFxuICBVUERBVEUgPSBcInVwZGF0ZVwiLFxuICBERUxFVEUgPSBcImRlbGV0ZVwiLFxuICBPTiA9IFwib24uXCIsXG4gIEFGVEVSID0gXCJhZnRlci5cIixcbn1cblxuZXhwb3J0IHR5cGUgQ3J1ZE9wZXJhdGlvbnMgPVxuICB8IE9wZXJhdGlvbktleXMuQ1JFQVRFXG4gIHwgT3BlcmF0aW9uS2V5cy5SRUFEXG4gIHwgT3BlcmF0aW9uS2V5cy5VUERBVEVcbiAgfCBPcGVyYXRpb25LZXlzLkRFTEVURTtcblxuLyoqXG4gKiBAc3VtbWFyeSBNYXBzIG91dCBncm91cHMgb2YgQ1JVRCBvcGVyYXRpb25zIGZvciBlYXNpZXIgbWFwcGluZyBvZiBkZWNvcmF0b3JzXG4gKlxuICogQGNvbnN0YW50IERCT3BlcmF0aW9uc1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5PcGVyYXRpb25zXG4gKi9cbmV4cG9ydCBjb25zdCBEQk9wZXJhdGlvbnM6IFJlY29yZDxzdHJpbmcsIENydWRPcGVyYXRpb25zW10+ID0ge1xuICBDUkVBVEU6IFtPcGVyYXRpb25LZXlzLkNSRUFURV0sXG4gIFJFQUQ6IFtPcGVyYXRpb25LZXlzLlJFQURdLFxuICBVUERBVEU6IFtPcGVyYXRpb25LZXlzLlVQREFURV0sXG4gIERFTEVURTogW09wZXJhdGlvbktleXMuREVMRVRFXSxcbiAgQ1JFQVRFX1VQREFURTogW09wZXJhdGlvbktleXMuQ1JFQVRFLCBPcGVyYXRpb25LZXlzLlVQREFURV0sXG4gIFJFQURfQ1JFQVRFOiBbT3BlcmF0aW9uS2V5cy5SRUFELCBPcGVyYXRpb25LZXlzLkNSRUFURV0sXG4gIEFMTDogW1xuICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgXSxcbn07XG4iLCJpbXBvcnQgeyBPcGVyYXRpb25IYW5kbGVyIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IE9wZXJhdGlvbktleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IElSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvSVJlcG9zaXRvcnlcIjtcbmltcG9ydCB7IE9wZXJhdGlvbnMgfSBmcm9tIFwiLi9PcGVyYXRpb25zXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBIb2xkcyB0aGUgcmVnaXN0ZXJlZCBvcGVyYXRpb24gaGFuZGxlcnNcbiAqXG4gKiBAY2xhc3MgT3BlcmF0aW9uc1JlZ2lzdHJ5XG4gKiBAaW1wbGVtZW50cyBJUmVnaXN0cnk8T3BlcmF0aW9uSGFuZGxlcjxhbnk+PlxuICpcbiAqIEBzZWUgT3BlcmF0aW9uSGFuZGxlclxuICpcbiAqIEBjYXRlZ29yeSBPcGVyYXRpb25zXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVyYXRpb25zUmVnaXN0cnkge1xuICBwcml2YXRlIHJlYWRvbmx5IGNhY2hlOiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIFJlY29yZDxcbiAgICAgIHN0cmluZyB8IHN5bWJvbCxcbiAgICAgIFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIGFueT4+PlxuICAgID5cbiAgPiA9IHt9O1xuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSByZXRyaWV2ZXMgYW4ge0BsaW5rIE9wZXJhdGlvbkhhbmRsZXJ9IGlmIGl0IGV4aXN0c1xuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFyZ2V0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wS2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRpb25cbiAgICogQHBhcmFtIGFjY3VtXG4gICAqIEByZXR1cm4ge09wZXJhdGlvbkhhbmRsZXIgfCB1bmRlZmluZWR9XG4gICAqL1xuICBnZXQ8VCBleHRlbmRzIE1vZGVsLCBWIGV4dGVuZHMgSVJlcG9zaXRvcnk8VD4sIFk+KFxuICAgIHRhcmdldDogc3RyaW5nIHwgUmVjb3JkPHN0cmluZywgYW55PixcbiAgICBwcm9wS2V5OiBzdHJpbmcsXG4gICAgb3BlcmF0aW9uOiBzdHJpbmcsXG4gICAgYWNjdW0/OiBPcGVyYXRpb25IYW5kbGVyPFQsIFYsIFk+W11cbiAgKTogT3BlcmF0aW9uSGFuZGxlcjxULCBWLCBZPltdIHwgdW5kZWZpbmVkIHtcbiAgICBhY2N1bSA9IGFjY3VtIHx8IFtdO1xuICAgIGxldCBuYW1lO1xuICAgIHRyeSB7XG4gICAgICBuYW1lID0gdHlwZW9mIHRhcmdldCA9PT0gXCJzdHJpbmdcIiA/IHRhcmdldCA6IHRhcmdldC5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgYWNjdW0udW5zaGlmdChcbiAgICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldW29wZXJhdGlvbl0gfHwgW10pXG4gICAgICApO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIHRhcmdldCA9PT0gXCJzdHJpbmdcIiB8fFxuICAgICAgICB0YXJnZXQgPT09IE9iamVjdC5wcm90b3R5cGUgfHxcbiAgICAgICAgT2JqZWN0LmdldFByb3RvdHlwZU9mKHRhcmdldCkgPT09IE9iamVjdC5wcm90b3R5cGVcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH1cblxuICAgIGxldCBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih0YXJnZXQpO1xuICAgIGlmIChwcm90by5jb25zdHJ1Y3Rvci5uYW1lID09PSBuYW1lKSBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG5cbiAgICByZXR1cm4gdGhpcy5nZXQ8VCwgViwgWT4ocHJvdG8sIHByb3BLZXksIG9wZXJhdGlvbiwgYWNjdW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJlZ2lzdGVycyBhbiB7QGxpbmsgT3BlcmF0aW9uSGFuZGxlcn1cbiAgICogQHBhcmFtIHtPcGVyYXRpb25IYW5kbGVyfSBoYW5kbGVyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRpb25cbiAgICogQHBhcmFtIHt7fX0gdGFyZ2V0XG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgc3ltYm9sfSBwcm9wS2V5XG4gICAqL1xuICByZWdpc3RlcjxUIGV4dGVuZHMgTW9kZWwsIFYgZXh0ZW5kcyBJUmVwb3NpdG9yeTxUPiwgWT4oXG4gICAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxULCBWLCBZPixcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgdGFyZ2V0OiBULFxuICAgIHByb3BLZXk6IHN0cmluZyB8IHN5bWJvbFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBuYW1lID0gdGFyZ2V0LmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgY29uc3QgaGFuZGxlck5hbWUgPSBPcGVyYXRpb25zLmdldEhhbmRsZXJOYW1lKGhhbmRsZXIpO1xuXG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdKSB0aGlzLmNhY2hlW25hbWVdID0ge307XG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldKSB0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldID0ge307XG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldW29wZXJhdGlvbl0pXG4gICAgICB0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldW29wZXJhdGlvbl0gPSB7fTtcbiAgICBpZiAodGhpcy5jYWNoZVtuYW1lXVtwcm9wS2V5XVtvcGVyYXRpb25dW2hhbmRsZXJOYW1lXSkgcmV0dXJuO1xuICAgIHRoaXMuY2FjaGVbbmFtZV1bcHJvcEtleV1bb3BlcmF0aW9uXVtoYW5kbGVyTmFtZV0gPSBoYW5kbGVyO1xuICB9XG59XG4iLCJpbXBvcnQgeyBIYXNoaW5nLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IE9wZXJhdGlvbkhhbmRsZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgT3BlcmF0aW9uc1JlZ2lzdHJ5IH0gZnJvbSBcIi4vT3BlcmF0aW9uc1JlZ2lzdHJ5XCI7XG5pbXBvcnQgeyBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgU3RhdGljIGNsYXNzIGhvbGRpbmcgY29tbW9uIE9wZXJhdGlvbiBGdW5jdGlvbmFsaXR5XG4gKlxuICogQGNsYXNzIE9wZXJhdGlvbnNcbiAqXG4gKiBAY2F0ZWdvcnkgT3BlcmF0aW9uc1xuICovXG5leHBvcnQgY2xhc3MgT3BlcmF0aW9ucyB7XG4gIHByaXZhdGUgc3RhdGljIHJlZ2lzdHJ5OiBPcGVyYXRpb25zUmVnaXN0cnk7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgc3RhdGljIGdldEhhbmRsZXJOYW1lKGhhbmRsZXI6IE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIGFueT4pIHtcbiAgICBpZiAoaGFuZGxlci5uYW1lKSByZXR1cm4gaGFuZGxlci5uYW1lO1xuXG4gICAgY29uc29sZS53YXJuKFxuICAgICAgXCJIYW5kbGVyIG5hbWUgbm90IGRlZmluZWQuIEEgbmFtZSB3aWxsIGJlIGdlbmVyYXRlZCwgYnV0IHRoaXMgaXMgbm90IGRlc2lyYWJsZS4gcGxlYXNlIGF2b2lkIHVzaW5nIGFub255bW91cyBmdW5jdGlvbnNcIlxuICAgICk7XG4gICAgcmV0dXJuIEhhc2hpbmcuaGFzaChoYW5kbGVyLnRvU3RyaW5nKCkpO1xuICB9XG5cbiAgc3RhdGljIGtleShzdHI6IHN0cmluZykge1xuICAgIHJldHVybiBPcGVyYXRpb25LZXlzLlJFRkxFQ1QgKyBzdHI7XG4gIH1cblxuICBzdGF0aWMgZ2V0KFxuICAgIHRhcmdldE5hbWU6IHN0cmluZyB8IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgcHJvcEtleTogc3RyaW5nLFxuICAgIG9wZXJhdGlvbjogc3RyaW5nXG4gICkge1xuICAgIHJldHVybiBPcGVyYXRpb25zLnJlZ2lzdHJ5LmdldCh0YXJnZXROYW1lLCBwcm9wS2V5LCBvcGVyYXRpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0T3BSZWdpc3RyeSgpIHtcbiAgICBpZiAoIU9wZXJhdGlvbnMucmVnaXN0cnkpIE9wZXJhdGlvbnMucmVnaXN0cnkgPSBuZXcgT3BlcmF0aW9uc1JlZ2lzdHJ5KCk7XG4gICAgcmV0dXJuIE9wZXJhdGlvbnMucmVnaXN0cnk7XG4gIH1cblxuICBzdGF0aWMgcmVnaXN0ZXI8ViBleHRlbmRzIE1vZGVsPihcbiAgICBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPFYsIGFueSwgYW55PixcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgdGFyZ2V0OiBWLFxuICAgIHByb3BLZXk6IHN0cmluZyB8IHN5bWJvbFxuICApIHtcbiAgICBPcGVyYXRpb25zLmdldE9wUmVnaXN0cnkoKS5yZWdpc3RlcihcbiAgICAgIGhhbmRsZXIgYXMgYW55LFxuICAgICAgb3BlcmF0aW9uLFxuICAgICAgdGFyZ2V0LFxuICAgICAgcHJvcEtleVxuICAgICk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIElkT3BlcmF0aW9uSGFuZGxlcixcbiAgT3BlcmF0aW9uSGFuZGxlcixcbiAgU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyLFxuICBVcGRhdGVPcGVyYXRpb25IYW5kbGVyLFxufSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgREJPcGVyYXRpb25zLCBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBPcGVyYXRpb25zIH0gZnJvbSBcIi4vT3BlcmF0aW9uc1wiO1xuaW1wb3J0IHsgYXBwbHkgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IHByb3BNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuZnVuY3Rpb24gaGFuZGxlKFxuICBvcDogT3BlcmF0aW9uS2V5cyxcbiAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgYW55LCBhbnk+XG4pIHtcbiAgcmV0dXJuICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZykgPT4ge1xuICAgIE9wZXJhdGlvbnMucmVnaXN0ZXIoaGFuZGxlciwgb3AsIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICB9O1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvdXIgdG8gc2V0IG9uIHRoZSBkZWZpbmVkIHtAbGluayBEQk9wZXJhdGlvbnMuQ1JFQVRFX1VQREFURX1cbiAqXG4gKiBAcGFyYW0ge09uT3BlcmF0aW9uSGFuZGxlcjxhbnk+fSBoYW5kbGVyIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIGRhdGFcbiAqIEBwYXJhbSB7YW55W119IFthcmdzXSBBcmd1bWVudHMgdGhhdCB3aWxsIGJlIHBhc3NlZCBpbiBvcmRlciB0byB0aGUgaGFuZGxlciBtZXRob2RcbiAqXG4gKiBAc2VlIG9uXG4gKlxuICogQGZ1bmN0aW9uIG9uQ3JlYXRlVXBkYXRlXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQ3JlYXRlVXBkYXRlPFQ+KFxuICBoYW5kbGVyOlxuICAgIHwgU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBULCBhbnk+XG4gICAgfCBVcGRhdGVPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBULCBhbnk+LFxuICBkYXRhPzogVFxuKSB7XG4gIHJldHVybiBvbihEQk9wZXJhdGlvbnMuQ1JFQVRFX1VQREFURSwgaGFuZGxlciwgZGF0YSk7XG59XG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvdXIgdG8gc2V0IG9uIHRoZSBkZWZpbmVkIHtAbGluayBEQk9wZXJhdGlvbnMuVVBEQVRFfVxuICpcbiAqIEBwYXJhbSB7T25PcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIEFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIGluIG9yZGVyIHRvIHRoZSBoYW5kbGVyIG1ldGhvZFxuICpcbiAqIEBzZWUgb25cbiAqXG4gKiBAZnVuY3Rpb24gb25VcGRhdGVcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25VcGRhdGU8VD4oXG4gIGhhbmRsZXI6IFVwZGF0ZU9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFQsIGFueT4sXG4gIGRhdGE/OiBUXG4pIHtcbiAgcmV0dXJuIG9uKERCT3BlcmF0aW9ucy5VUERBVEUsIGhhbmRsZXIsIGRhdGEpO1xufVxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3VyIHRvIHNldCBvbiB0aGUgZGVmaW5lZCB7QGxpbmsgREJPcGVyYXRpb25zLkNSRUFURX1cbiAqXG4gKiBAcGFyYW0ge09uT3BlcmF0aW9uSGFuZGxlcjxhbnk+fSBoYW5kbGVyIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIGRhdGFcbiAqXG4gKiBAc2VlIG9uXG4gKlxuICogQGZ1bmN0aW9uIG9uQ3JlYXRlXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQ3JlYXRlPFQ+KFxuICBoYW5kbGVyOiBTdGFuZGFyZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFQsIGFueT4sXG4gIGRhdGE/OiBUXG4pIHtcbiAgcmV0dXJuIG9uKERCT3BlcmF0aW9ucy5DUkVBVEUsIGhhbmRsZXIsIGRhdGEpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvdXIgdG8gc2V0IG9uIHRoZSBkZWZpbmVkIHtAbGluayBEQk9wZXJhdGlvbnMuUkVBRH1cbiAqXG4gKiBAcGFyYW0ge09uT3BlcmF0aW9uSGFuZGxlcjxhbnk+fSBoYW5kbGVyIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIGRhdGFcbiAqXG4gKiBAc2VlIG9uXG4gKlxuICogQGZ1bmN0aW9uIG9uUmVhZFxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvblJlYWQ8VD4oXG4gIGhhbmRsZXI6IElkT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgVCwgYW55PixcbiAgZGF0YTogVFxuKSB7XG4gIHJldHVybiBvbihEQk9wZXJhdGlvbnMuUkVBRCwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgb24gdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5ERUxFVEV9XG4gKlxuICogQHBhcmFtIHtPbk9wZXJhdGlvbkhhbmRsZXI8YW55Pn0gaGFuZGxlciBUaGUgbWV0aG9kIGNhbGxlZCB1cG9uIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSBkYXRhXG4gKlxuICogQHNlZSBvblxuICpcbiAqIEBmdW5jdGlvbiBvbkRlbGV0ZVxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkRlbGV0ZTxUPihcbiAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgVCwgYW55PixcbiAgZGF0YTogVFxuKSB7XG4gIHJldHVybiBvbihEQk9wZXJhdGlvbnMuREVMRVRFLCBoYW5kbGVyLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3VyIHRvIHNldCBvbiB0aGUgZGVmaW5lZCB7QGxpbmsgREJPcGVyYXRpb25zLkRFTEVURX1cbiAqXG4gKiBAcGFyYW0ge09uT3BlcmF0aW9uSGFuZGxlcjxhbnk+fSBoYW5kbGVyIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIGRhdGFcbiAqXG4gKiBAc2VlIG9uXG4gKlxuICogQGZ1bmN0aW9uIG9uQW55XG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQW55PFQ+KGhhbmRsZXI6IE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFQsIGFueT4sIGRhdGE6IFQpIHtcbiAgcmV0dXJuIG9uKERCT3BlcmF0aW9ucy5BTEwsIGhhbmRsZXIsIGRhdGEpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvdXIgdG8gc2V0IG9uIHRoZSBkZWZpbmVkIHtAbGluayBEQk9wZXJhdGlvbnN9XG4gKlxuICogQHBhcmFtIHtPcGVyYXRpb25LZXlzW10gfCBEQk9wZXJhdGlvbnN9IG9wIE9uZSBvZiB7QGxpbmsgREJPcGVyYXRpb25zfVxuICogQHBhcmFtIHtPbk9wZXJhdGlvbkhhbmRsZXI8YW55Pn0gaGFuZGxlciBUaGUgbWV0aG9kIGNhbGxlZCB1cG9uIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSBkYXRhXG4gKlxuICogZXg6IGhhbmRsZXIoLi4uYXJncywgLi4ucHJvcHMubWFwKHAgPT4gdGFyZ2V0W3BdKSlcbiAqXG4gKiBAZnVuY3Rpb24gb25cbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gb248VD4oXG4gIG9wOiBPcGVyYXRpb25LZXlzW10gPSBEQk9wZXJhdGlvbnMuQUxMLFxuICBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBULCBhbnk+LFxuICBkYXRhPzogVFxuKSB7XG4gIHJldHVybiBvcGVyYXRpb24oT3BlcmF0aW9uS2V5cy5PTiwgb3AsIGhhbmRsZXIsIGRhdGEpO1xufVxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3VyIHRvIHNldCBhZnRlciB0aGUgZGVmaW5lZCB7QGxpbmsgREJPcGVyYXRpb25zLkNSRUFURV9VUERBVEV9XG4gKlxuICogQHBhcmFtIHtBZnRlck9wZXJhdGlvbkhhbmRsZXI8YW55Pn0gaGFuZGxlciBUaGUgbWV0aG9kIGNhbGxlZCB1cG9uIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSBkYXRhXG4gKlxuICogQHNlZSBhZnRlclxuICpcbiAqIEBmdW5jdGlvbiBhZnRlckNyZWF0ZVVwZGF0ZVxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlckNyZWF0ZVVwZGF0ZTxUPihcbiAgaGFuZGxlcjpcbiAgICB8IFN0YW5kYXJkT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgVCwgYW55PlxuICAgIHwgVXBkYXRlT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgVCwgYW55PixcbiAgZGF0YTogVFxuKSB7XG4gIHJldHVybiBhZnRlcihEQk9wZXJhdGlvbnMuQ1JFQVRFX1VQREFURSwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgYWZ0ZXIgdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5VUERBVEV9XG4gKlxuICogQHBhcmFtIHtBZnRlck9wZXJhdGlvbkhhbmRsZXI8YW55Pn0gaGFuZGxlciBUaGUgbWV0aG9kIGNhbGxlZCB1cG9uIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSBkYXRhXG4gKlxuICogQHNlZSBhZnRlclxuICpcbiAqIEBmdW5jdGlvbiBhZnRlclVwZGF0ZVxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlclVwZGF0ZTxUPihcbiAgaGFuZGxlcjogVXBkYXRlT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgVCwgYW55PixcbiAgZGF0YTogVFxuKSB7XG4gIHJldHVybiBhZnRlcihEQk9wZXJhdGlvbnMuVVBEQVRFLCBoYW5kbGVyLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3VyIHRvIHNldCBhZnRlciB0aGUgZGVmaW5lZCB7QGxpbmsgREJPcGVyYXRpb25zLkNSRUFURX1cbiAqXG4gKiBAcGFyYW0ge0FmdGVyT3BlcmF0aW9uSGFuZGxlcjxhbnk+fSBoYW5kbGVyIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIGRhdGFcbiAqXG4gKiBAc2VlIGFmdGVyXG4gKlxuICogQGZ1bmN0aW9uIGFmdGVyQ3JlYXRlXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFmdGVyQ3JlYXRlPFQ+KFxuICBoYW5kbGVyOiBTdGFuZGFyZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFQsIGFueT4sXG4gIGRhdGE6IFRcbikge1xuICByZXR1cm4gYWZ0ZXIoREJPcGVyYXRpb25zLkNSRUFURSwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgYWZ0ZXIgdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5SRUFEfVxuICpcbiAqIEBwYXJhbSB7QWZ0ZXJPcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIEFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIGluIG9yZGVyIHRvIHRoZSBoYW5kbGVyIG1ldGhvZFxuICpcbiAqIEBzZWUgYWZ0ZXJcbiAqXG4gKiBAZnVuY3Rpb24gYWZ0ZXJSZWFkXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFmdGVyUmVhZDxUPihcbiAgaGFuZGxlcjogU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBULCBhbnk+LFxuICBkYXRhPzogVFxuKSB7XG4gIHJldHVybiBhZnRlcihEQk9wZXJhdGlvbnMuUkVBRCwgaGFuZGxlciwgZGF0YSk7XG59XG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvdXIgdG8gc2V0IGFmdGVyIHRoZSBkZWZpbmVkIHtAbGluayBEQk9wZXJhdGlvbnMuREVMRVRFfVxuICpcbiAqIEBwYXJhbSB7QWZ0ZXJPcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIEFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIGluIG9yZGVyIHRvIHRoZSBoYW5kbGVyIG1ldGhvZFxuICpcbiAqIEBzZWUgYWZ0ZXJcbiAqXG4gKiBAZnVuY3Rpb24gYWZ0ZXJEZWxldGVcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWZ0ZXJEZWxldGU8VD4oXG4gIGhhbmRsZXI6IFN0YW5kYXJkT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgVCwgYW55PixcbiAgZGF0YT86IFRcbikge1xuICByZXR1cm4gYWZ0ZXIoREJPcGVyYXRpb25zLkRFTEVURSwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgYWZ0ZXIgdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5ERUxFVEV9XG4gKlxuICogQHBhcmFtIHtBZnRlck9wZXJhdGlvbkhhbmRsZXI8YW55Pn0gaGFuZGxlciBUaGUgbWV0aG9kIGNhbGxlZCB1cG9uIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSBkYXRhXG4gKiBAcGFyYW0ge2FueVtdfSBbYXJnc10gQXJndW1lbnRzIHRoYXQgd2lsbCBiZSBwYXNzZWQgaW4gb3JkZXIgdG8gdGhlIGhhbmRsZXIgbWV0aG9kXG4gKlxuICogQHNlZSBhZnRlclxuICpcbiAqIEBmdW5jdGlvbiBhZnRlckFueVxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlckFueTxUPihcbiAgaGFuZGxlcjogU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBULCBhbnk+LFxuICBkYXRhPzogVFxuKSB7XG4gIHJldHVybiBhZnRlcihEQk9wZXJhdGlvbnMuQUxMLCBoYW5kbGVyLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3VyIHRvIHNldCBvbiB0aGUgZGVmaW5lZCB7QGxpbmsgREJPcGVyYXRpb25zfVxuICpcbiAqIEBwYXJhbSB7T3BlcmF0aW9uS2V5c1tdIHwgREJPcGVyYXRpb25zfSBvcCBPbmUgb2Yge0BsaW5rIERCT3BlcmF0aW9uc31cbiAqIEBwYXJhbSB7QWZ0ZXJPcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKlxuICogZXg6IGhhbmRsZXIoLi4uYXJncywgLi4ucHJvcHMubWFwKHAgPT4gdGFyZ2V0W3BdKSlcbiAqXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIGFyZ3NcbiAqIEBmdW5jdGlvbiBhZnRlclxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlcjxUPihcbiAgb3A6IE9wZXJhdGlvbktleXNbXSA9IERCT3BlcmF0aW9ucy5BTEwsXG4gIGhhbmRsZXI6IE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFQsIGFueT4sXG4gIGRhdGE/OiBUXG4pIHtcbiAgcmV0dXJuIG9wZXJhdGlvbihPcGVyYXRpb25LZXlzLkFGVEVSLCBvcCwgaGFuZGxlciwgZGF0YSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBvcGVyYXRpb248VD4oXG4gIGJhc2VPcDogT3BlcmF0aW9uS2V5cy5PTiB8IE9wZXJhdGlvbktleXMuQUZURVIsXG4gIG9wZXJhdGlvbjogT3BlcmF0aW9uS2V5c1tdID0gREJPcGVyYXRpb25zLkFMTCxcbiAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgVCwgYW55PixcbiAgZGF0YVRvQWRkPzogVFxuKSB7XG4gIHJldHVybiAodGFyZ2V0OiBvYmplY3QsIHByb3BlcnR5S2V5PzogYW55KSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IHRhcmdldC5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgIGNvbnN0IGRlY29yYXRvcnMgPSBvcGVyYXRpb24ucmVkdWNlKChhY2N1bTogYW55W10sIG9wKSA9PiB7XG4gICAgICBjb25zdCBjb21wb3VuZEtleSA9IGJhc2VPcCArIG9wO1xuICAgICAgbGV0IGRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICBPcGVyYXRpb25zLmtleShjb21wb3VuZEtleSksXG4gICAgICAgIHRhcmdldCxcbiAgICAgICAgcHJvcGVydHlLZXlcbiAgICAgICk7XG4gICAgICBpZiAoIWRhdGEpXG4gICAgICAgIGRhdGEgPSB7XG4gICAgICAgICAgb3BlcmF0aW9uOiBvcCxcbiAgICAgICAgICBoYW5kbGVyczoge30sXG4gICAgICAgIH07XG5cbiAgICAgIGNvbnN0IGhhbmRsZXJLZXkgPSBPcGVyYXRpb25zLmdldEhhbmRsZXJOYW1lKGhhbmRsZXIpO1xuXG4gICAgICBpZiAoXG4gICAgICAgICFkYXRhLmhhbmRsZXJzW25hbWVdIHx8XG4gICAgICAgICFkYXRhLmhhbmRsZXJzW25hbWVdW3Byb3BlcnR5S2V5XSB8fFxuICAgICAgICAhKGhhbmRsZXJLZXkgaW4gZGF0YS5oYW5kbGVyc1tuYW1lXVtwcm9wZXJ0eUtleV0pXG4gICAgICApIHtcbiAgICAgICAgZGF0YS5oYW5kbGVyc1tuYW1lXSA9IGRhdGEuaGFuZGxlcnNbbmFtZV0gfHwge307XG4gICAgICAgIGRhdGEuaGFuZGxlcnNbbmFtZV1bcHJvcGVydHlLZXldID1cbiAgICAgICAgICBkYXRhLmhhbmRsZXJzW25hbWVdW3Byb3BlcnR5S2V5XSB8fCB7fTtcbiAgICAgICAgZGF0YS5oYW5kbGVyc1tuYW1lXVtwcm9wZXJ0eUtleV1baGFuZGxlcktleV0gPSB7XG4gICAgICAgICAgZGF0YTogZGF0YVRvQWRkLFxuICAgICAgICB9O1xuXG4gICAgICAgIGFjY3VtLnB1c2goXG4gICAgICAgICAgaGFuZGxlKGNvbXBvdW5kS2V5IGFzIE9wZXJhdGlvbktleXMsIGhhbmRsZXIpLFxuICAgICAgICAgIHByb3BNZXRhZGF0YShPcGVyYXRpb25zLmtleShjb21wb3VuZEtleSksIGRhdGEpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwgW10pO1xuICAgIHJldHVybiBhcHBseSguLi5kZWNvcmF0b3JzKSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgfTtcbn1cbiIsIi8qKlxuICogQHN1bW1hcnkgQmFzZSBFcnJvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtc2cgdGhlIGVycm9yIG1lc3NhZ2VcbiAqXG4gKiBAY2xhc3MgQmFzZURMVEVycm9yXG4gKiBAZXh0ZW5kcyBFcnJvclxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IobmFtZTogc3RyaW5nLCBtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgaWYgKG1zZyBpbnN0YW5jZW9mIEJhc2VFcnJvcikgcmV0dXJuIG1zZztcbiAgICBjb25zdCBtZXNzYWdlID0gYFske25hbWV9XSAke21zZyBpbnN0YW5jZW9mIEVycm9yID8gbXNnLm1lc3NhZ2UgOiBtc2d9YDtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBpZiAobXNnIGluc3RhbmNlb2YgRXJyb3IpIHRoaXMuc3RhY2sgPSBtc2cuc3RhY2s7XG4gIH1cbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGEgZmFpbHVyZSBpbiB0aGUgTW9kZWwgZGV0YWlsc1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtc2cgdGhlIGVycm9yIG1lc3NhZ2VcbiAqXG4gKiBAY2xhc3MgVmFsaWRhdGlvbkVycm9yXG4gKiBAZXh0ZW5kcyBCYXNlRXJyb3JcbiAqL1xuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihWYWxpZGF0aW9uRXJyb3IubmFtZSwgbXNnKTtcbiAgfVxufVxuLyoqXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGFuIGludGVybmFsIGZhaWx1cmUgKHNob3VsZCBtZWFuIGFuIGVycm9yIGluIGNvZGUpXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1zZyB0aGUgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjbGFzcyBJbnRlcm5hbEVycm9yXG4gKiBAZXh0ZW5kcyBCYXNlRXJyb3JcbiAqL1xuZXhwb3J0IGNsYXNzIEludGVybmFsRXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoSW50ZXJuYWxFcnJvci5uYW1lLCBtc2cpO1xuICB9XG59XG4vKipcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBmYWlsdXJlIGluIHRoZSBNb2RlbCBkZS9zZXJpYWxpemF0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1zZyB0aGUgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjbGFzcyBTZXJpYWxpemF0aW9uRXJyb3JcbiAqIEBleHRlbmRzIEJhc2VFcnJvclxuICpcbiAqL1xuZXhwb3J0IGNsYXNzIFNlcmlhbGl6YXRpb25FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihTZXJpYWxpemF0aW9uRXJyb3IubmFtZSwgbXNnKTtcbiAgfVxufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBmYWlsdXJlIGluIGZpbmRpbmcgYSBtb2RlbFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtc2cgdGhlIGVycm9yIG1lc3NhZ2VcbiAqXG4gKiBAY2xhc3MgTm90Rm91bmRFcnJvclxuICogQGV4dGVuZHMgQmFzZUVycm9yXG4gKlxuICovXG5leHBvcnQgY2xhc3MgTm90Rm91bmRFcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihOb3RGb3VuZEVycm9yLm5hbWUsIG1zZyk7XG4gIH1cbn1cbi8qKlxuICogQHN1bW1hcnkgUmVwcmVzZW50cyBhIGNvbmZsaWN0IGluIHRoZSBzdG9yYWdlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1zZyB0aGUgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjbGFzcyBDb25mbGljdEVycm9yXG4gKiBAZXh0ZW5kcyBCYXNlRXJyb3JcbiAqXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25mbGljdEVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKENvbmZsaWN0RXJyb3IubmFtZSwgbXNnKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgT3BlcmF0aW9ucyB9IGZyb20gXCIuLi9vcGVyYXRpb25zL09wZXJhdGlvbnNcIjtcbmltcG9ydCB7IE9wZXJhdGlvbkhhbmRsZXIsIFVwZGF0ZU9wZXJhdGlvbkhhbmRsZXIgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy90eXBlc1wiO1xuaW1wb3J0IHsgSVJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9JUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgRGVjb3JhdG9yTWV0YWRhdGEsIFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBNb2RlbCxcbiAgTW9kZWxLZXlzLFxuICBzZixcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuL0NvbnRleHRcIjtcblxuZXhwb3J0IHR5cGUgQ29udGV4dEFyZ3M8TSBleHRlbmRzIE1vZGVsPiA9IHtcbiAgY29udGV4dDogQ29udGV4dDxNPjtcbiAgYXJnczogYW55W107XG59O1xuXG4vKipcbiAqIEBzdW1tYXJ5IHJldHJpZXZlcyB0aGUgYXJndW1lbnRzIGZvciB0aGUgaGFuZGxlclxuICogQHBhcmFtIHthbnl9IGRlYyB0aGUgZGVjb3JhdG9yXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcCB0aGUgcHJvcGVydHkgbmFtZVxuICogQHBhcmFtIHt7fX0gbSB0aGUgbW9kZWxcbiAqIEBwYXJhbSB7e319IFthY2N1bV0gYWNjdW11bGF0b3IgdXNlZCBmb3IgaW50ZXJuYWwgcmVjdXJzaXZlbmVzc1xuICpcbiAqIEBmdW5jdGlvbiBnZXRIYW5kbGVyQXJnc1xuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzLlJlcG9zaXRvcnlcbiAqL1xuZXhwb3J0IGNvbnN0IGdldEhhbmRsZXJBcmdzID0gZnVuY3Rpb24gKFxuICBkZWM6IGFueSxcbiAgcHJvcDogc3RyaW5nLFxuICBtOiBDb25zdHJ1Y3Rvcjxhbnk+LFxuICBhY2N1bT86IFJlY29yZDxzdHJpbmcsIHsgYXJnczogc3RyaW5nW10gfT5cbik6IFJlY29yZDxzdHJpbmcsIHsgYXJnczogc3RyaW5nW10gfT4gfCB2b2lkIHtcbiAgY29uc3QgbmFtZSA9IG0uY29uc3RydWN0b3IubmFtZTtcbiAgaWYgKCFuYW1lKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkNvdWxkIG5vdCBkZXRlcm1pbmUgbW9kZWwgY2xhc3NcIik7XG4gIGFjY3VtID0gYWNjdW0gfHwge307XG5cbiAgaWYgKGRlYy5wcm9wcy5oYW5kbGVyc1tuYW1lXSAmJiBkZWMucHJvcHMuaGFuZGxlcnNbbmFtZV1bcHJvcF0pXG4gICAgYWNjdW0gPSB7IC4uLmRlYy5wcm9wcy5oYW5kbGVyc1tuYW1lXVtwcm9wXSwgLi4uYWNjdW0gfTtcblxuICBsZXQgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YobSk7XG4gIGlmIChwcm90byA9PT0gT2JqZWN0LnByb3RvdHlwZSkgcmV0dXJuIGFjY3VtO1xuICBpZiAocHJvdG8uY29uc3RydWN0b3IubmFtZSA9PT0gbmFtZSkgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuXG4gIHJldHVybiBnZXRIYW5kbGVyQXJncyhkZWMsIHByb3AsIHByb3RvLCBhY2N1bSk7XG59O1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge0lSZXBvc2l0b3J5PFQ+fSByZXBvXG4gKiBAcGFyYW0gY29udGV4dFxuICogQHBhcmFtIHtUfSBtb2RlbFxuICogQHBhcmFtIG9wZXJhdGlvblxuICogQHBhcmFtIHByZWZpeFxuICpcbiAqIEBwYXJhbSBvbGRNb2RlbFxuICogQGZ1bmN0aW9uIGVuZm9yY2VEQlByb3BlcnR5RGVjb3JhdG9yc0FzeW5jXG4gKlxuICogQG1lbWJlck9mIGRiLWRlY29yYXRvcnMudXRpbHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuZm9yY2VEQkRlY29yYXRvcnM8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgWSBleHRlbmRzIElSZXBvc2l0b3J5PE0+LFxuICBWLFxuPihcbiAgcmVwbzogWSxcbiAgY29udGV4dDogQ29udGV4dDxNPixcbiAgbW9kZWw6IE0sXG4gIG9wZXJhdGlvbjogc3RyaW5nLFxuICBwcmVmaXg6IHN0cmluZyxcbiAgb2xkTW9kZWw/OiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgZGVjb3JhdG9yczogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGFbXT4gfCB1bmRlZmluZWQgPVxuICAgIGdldERiRGVjb3JhdG9ycyhtb2RlbCwgb3BlcmF0aW9uLCBwcmVmaXgpO1xuXG4gIGlmICghZGVjb3JhdG9ycykgcmV0dXJuO1xuXG4gIGZvciAoY29uc3QgcHJvcCBpbiBkZWNvcmF0b3JzKSB7XG4gICAgY29uc3QgZGVjczogRGVjb3JhdG9yTWV0YWRhdGFbXSA9IGRlY29yYXRvcnNbcHJvcF07XG4gICAgZm9yIChjb25zdCBkZWMgb2YgZGVjcykge1xuICAgICAgY29uc3QgeyBrZXkgfSA9IGRlYztcbiAgICAgIGNvbnN0IGhhbmRsZXJzOiBPcGVyYXRpb25IYW5kbGVyPE0sIFksIFY+W10gfCB1bmRlZmluZWQgPSBPcGVyYXRpb25zLmdldChcbiAgICAgICAgbW9kZWwsXG4gICAgICAgIHByb3AsXG4gICAgICAgIHByZWZpeCArIGtleVxuICAgICAgKTtcbiAgICAgIGlmICghaGFuZGxlcnMgfHwgIWhhbmRsZXJzLmxlbmd0aClcbiAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgYENvdWxkIG5vdCBmaW5kIHJlZ2lzdGVyZWQgaGFuZGxlciBmb3IgdGhlIG9wZXJhdGlvbiAke3ByZWZpeCArIGtleX0gdW5kZXIgcHJvcGVydHkgJHtwcm9wfWBcbiAgICAgICAgKTtcblxuICAgICAgY29uc3QgaGFuZGxlckFyZ3MgPSBnZXRIYW5kbGVyQXJncyhkZWMsIHByb3AsIG1vZGVsIGFzIGFueSk7XG5cbiAgICAgIGlmICghaGFuZGxlckFyZ3MgfHwgT2JqZWN0LnZhbHVlcyhoYW5kbGVyQXJncykubGVuZ3RoICE9PSBoYW5kbGVycy5sZW5ndGgpXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKHNmKFwiQXJncyBhbmQgaGFuZGxlcnMgbGVuZ3RoIGRvIG5vdCBtYXRjaFwiKSk7XG5cbiAgICAgIGxldCBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBhbnk+O1xuICAgICAgbGV0IGRhdGE6IGFueTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGFuZGxlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaGFuZGxlciA9IGhhbmRsZXJzW2ldO1xuICAgICAgICBkYXRhID0gT2JqZWN0LnZhbHVlcyhoYW5kbGVyQXJncylbaV07XG5cbiAgICAgICAgY29uc3QgYXJnczogYW55W10gPSBbY29udGV4dCwgZGF0YS5kYXRhLCBwcm9wLCBtb2RlbF07XG5cbiAgICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gT3BlcmF0aW9uS2V5cy5VUERBVEUgJiYgcHJlZml4ID09PSBPcGVyYXRpb25LZXlzLk9OKSB7XG4gICAgICAgICAgaWYgKCFvbGRNb2RlbClcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzc2luZyBvbGQgbW9kZWwgZm9yIHVwZGF0ZSBvcGVyYXRpb25cIik7XG4gICAgICAgICAgYXJncy5wdXNoKG9sZE1vZGVsKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCAoaGFuZGxlciBhcyBVcGRhdGVPcGVyYXRpb25IYW5kbGVyPE0sIFksIFY+KS5hcHBseShcbiAgICAgICAgICByZXBvLFxuICAgICAgICAgIGFyZ3MgYXMgW0NvbnRleHQ8TT4sIFYsIGFueSwgTSwgTV1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBTcGVjaWZpYyBmb3IgREIgRGVjb3JhdG9yc1xuICogQHBhcmFtIHtUfSBtb2RlbFxuICogQHBhcmFtIHtzdHJpbmd9IG9wZXJhdGlvbiBDUlVEIHtAbGluayBPcGVyYXRpb25LZXlzfVxuICogQHBhcmFtIHtzdHJpbmd9IFtleHRyYVByZWZpeF1cbiAqXG4gKiBAZnVuY3Rpb24gZ2V0RGJQcm9wZXJ0eURlY29yYXRvcnNcbiAqXG4gKiBAbWVtYmVyT2YgZGItZGVjb3JhdG9ycy51dGlsc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGJEZWNvcmF0b3JzPFQgZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBULFxuICBvcGVyYXRpb246IHN0cmluZyxcbiAgZXh0cmFQcmVmaXg/OiBzdHJpbmdcbik6IFJlY29yZDxzdHJpbmcsIERlY29yYXRvck1ldGFkYXRhW10+IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZGVjb3JhdG9yczogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGFbXT4gfCB1bmRlZmluZWQgPVxuICAgIFJlZmxlY3Rpb24uZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgbW9kZWwsXG4gICAgICAvLyB1bmRlZmluZWQsXG4gICAgICBPcGVyYXRpb25LZXlzLlJFRkxFQ1QgKyAoZXh0cmFQcmVmaXggPyBleHRyYVByZWZpeCA6IFwiXCIpXG4gICAgKTtcbiAgaWYgKCFkZWNvcmF0b3JzKSByZXR1cm47XG4gIHJldHVybiBPYmplY3Qua2V5cyhkZWNvcmF0b3JzKS5yZWR1Y2UoXG4gICAgKGFjY3VtOiBSZWNvcmQ8c3RyaW5nLCBEZWNvcmF0b3JNZXRhZGF0YVtdPiB8IHVuZGVmaW5lZCwgZGVjb3JhdG9yKSA9PiB7XG4gICAgICBjb25zdCBkZWMgPSBkZWNvcmF0b3JzW2RlY29yYXRvcl0uZmlsdGVyKChkKSA9PiBkLmtleSA9PT0gb3BlcmF0aW9uKTtcbiAgICAgIGlmIChkZWMgJiYgZGVjLmxlbmd0aCkge1xuICAgICAgICBpZiAoIWFjY3VtKSBhY2N1bSA9IHt9O1xuICAgICAgICBhY2N1bVtkZWNvcmF0b3JdID0gZGVjO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sXG4gICAgdW5kZWZpbmVkXG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBkZWNvcmF0b3JzIGZvciBhbiBvYmplY3QncyBwcm9wZXJ0aWVzIHByZWZpeGVkIGJ5IHtAcGFyYW0gcHJlZml4ZXN9IHJlY3Vyc2l2ZWx5XG4gKiBAcGFyYW0gbW9kZWxcbiAqIEBwYXJhbSBhY2N1bVxuICogQHBhcmFtIHByZWZpeGVzXG4gKlxuICogQGZ1bmN0aW9uIGdldEFsbFByb3BlcnR5RGVjb3JhdG9yc1JlY3Vyc2l2ZVxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzLlJlcG9zaXRvcnlcbiAqL1xuZXhwb3J0IGNvbnN0IGdldEFsbFByb3BlcnR5RGVjb3JhdG9yc1JlY3Vyc2l2ZSA9IGZ1bmN0aW9uIDxUIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogVCxcbiAgYWNjdW06IHsgW2luZGV4ZXI6IHN0cmluZ106IGFueVtdIH0gfCB1bmRlZmluZWQsXG4gIC4uLnByZWZpeGVzOiBzdHJpbmdbXVxuKTogeyBbaW5kZXhlcjogc3RyaW5nXTogYW55W10gfSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGFjY3VtdWxhdG9yID0gYWNjdW0gfHwge307XG4gIGNvbnN0IG1lcmdlRGVjb3JhdG9ycyA9IGZ1bmN0aW9uIChkZWNzOiB7IFtpbmRleGVyOiBzdHJpbmddOiBhbnlbXSB9KSB7XG4gICAgY29uc3QgcHVzaE9yU3F1YXNoID0gKGtleTogc3RyaW5nLCAuLi52YWx1ZXM6IGFueVtdKSA9PiB7XG4gICAgICB2YWx1ZXMuZm9yRWFjaCgodmFsKSA9PiB7XG4gICAgICAgIGxldCBtYXRjaDogYW55O1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIShtYXRjaCA9IGFjY3VtdWxhdG9yW2tleV0uZmluZCgoZSkgPT4gZS5rZXkgPT09IHZhbC5rZXkpKSB8fFxuICAgICAgICAgIG1hdGNoLnByb3BzLm9wZXJhdGlvbiAhPT0gdmFsLnByb3BzLm9wZXJhdGlvblxuICAgICAgICApIHtcbiAgICAgICAgICBhY2N1bXVsYXRvcltrZXldLnB1c2godmFsKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsLmtleSA9PT0gTW9kZWxLZXlzLlRZUEUpIHJldHVybjtcblxuICAgICAgICBjb25zdCB7IGhhbmRsZXJzLCBvcGVyYXRpb24gfSA9IHZhbC5wcm9wcztcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgIW9wZXJhdGlvbiB8fFxuICAgICAgICAgICFvcGVyYXRpb24ubWF0Y2goXG4gICAgICAgICAgICBuZXcgUmVnRXhwKFxuICAgICAgICAgICAgICBgXig6PyR7T3BlcmF0aW9uS2V5cy5PTn18JHtPcGVyYXRpb25LZXlzLkFGVEVSfSkoOj8ke09wZXJhdGlvbktleXMuQ1JFQVRFfXwke09wZXJhdGlvbktleXMuUkVBRH18JHtPcGVyYXRpb25LZXlzLlVQREFURX18JHtPcGVyYXRpb25LZXlzLkRFTEVURX0pJGBcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgIGFjY3VtdWxhdG9yW2tleV0ucHVzaCh2YWwpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFjY3VtSGFuZGxlcnMgPSBtYXRjaC5wcm9wcy5oYW5kbGVycztcblxuICAgICAgICBPYmplY3QuZW50cmllcyhoYW5kbGVycykuZm9yRWFjaCgoW2NsYXp6LCBoYW5kbGVyRGVmXSkgPT4ge1xuICAgICAgICAgIGlmICghKGNsYXp6IGluIGFjY3VtSGFuZGxlcnMpKSB7XG4gICAgICAgICAgICBhY2N1bUhhbmRsZXJzW2NsYXp6XSA9IGhhbmRsZXJEZWY7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgT2JqZWN0LmVudHJpZXMoaGFuZGxlckRlZiBhcyBvYmplY3QpLmZvckVhY2goXG4gICAgICAgICAgICAoW2hhbmRsZXJQcm9wLCBoYW5kbGVyXSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoIShoYW5kbGVyUHJvcCBpbiBhY2N1bUhhbmRsZXJzW2NsYXp6XSkpIHtcbiAgICAgICAgICAgICAgICBhY2N1bUhhbmRsZXJzW2NsYXp6XVtoYW5kbGVyUHJvcF0gPSBoYW5kbGVyO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGhhbmRsZXIgYXMgb2JqZWN0KS5mb3JFYWNoKFxuICAgICAgICAgICAgICAgIChbaGFuZGxlcktleSwgYXJnc09ial0pID0+IHtcbiAgICAgICAgICAgICAgICAgIGlmICghKGhhbmRsZXJLZXkgaW4gYWNjdW1IYW5kbGVyc1tjbGF6el1baGFuZGxlclByb3BdKSkge1xuICAgICAgICAgICAgICAgICAgICBhY2N1bUhhbmRsZXJzW2NsYXp6XVtoYW5kbGVyUHJvcF1baGFuZGxlcktleV0gPSBhcmdzT2JqO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgICAgIHNmKFxuICAgICAgICAgICAgICAgICAgICAgIFwiU2tpcHBpbmcgaGFuZGxlciByZWdpc3RyYXRpb24gZm9yIHswfSB1bmRlciBwcm9wIHswfSBiZWNhdXNlIGhhbmRsZXIgaXMgdGhlIHNhbWVcIixcbiAgICAgICAgICAgICAgICAgICAgICBjbGF6eixcbiAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyUHJvcFxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBPYmplY3QuZW50cmllcyhkZWNzKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGFjY3VtdWxhdG9yW2tleV0gPSBhY2N1bXVsYXRvcltrZXldIHx8IFtdO1xuICAgICAgcHVzaE9yU3F1YXNoKGtleSwgLi4udmFsdWUpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGRlY3M6IHsgW2luZGV4ZXI6IHN0cmluZ106IGFueVtdIH0gfCB1bmRlZmluZWQgPVxuICAgIFJlZmxlY3Rpb24uZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzKG1vZGVsLCAuLi5wcmVmaXhlcyk7XG4gIGlmIChkZWNzKSBtZXJnZURlY29yYXRvcnMoZGVjcyk7XG5cbiAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihtb2RlbCkgPT09IE9iamVjdC5wcm90b3R5cGUpIHJldHVybiBhY2N1bXVsYXRvcjtcblxuICAvLyBjb25zdCBuYW1lID0gbW9kZWwuY29uc3RydWN0b3IubmFtZTtcbiAgY29uc3QgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YobW9kZWwpO1xuICBpZiAoIXByb3RvKSByZXR1cm4gYWNjdW11bGF0b3I7XG4gIC8vIGlmIChwcm90by5jb25zdHJ1Y3RvciAmJiBwcm90by5jb25zdHJ1Y3Rvci5uYW1lID09PSBuYW1lKVxuICAvLyAgICAgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pXG4gIHJldHVybiBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUocHJvdG8sIGFjY3VtdWxhdG9yLCAuLi5wcmVmaXhlcyk7XG59O1xuIiwiaW1wb3J0IHsgQ29uZmxpY3RFcnJvciwgTm90Rm91bmRFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuXG5leHBvcnQgY2xhc3MgRGF0YUNhY2hlIHtcbiAgcHJvdGVjdGVkIGNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG5cbiAgYXN5bmMgZ2V0KGtleTogc3RyaW5nKSB7XG4gICAgaWYgKCEoa2V5IGluIHRoaXMuY2FjaGUpKVxuICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXJyb3IoYEtleSAke2tleX0gbm90IGluIGRhdGFTdG9yZWApO1xuICAgIHJldHVybiB0aGlzLmNhY2hlW2tleV07XG4gIH1cblxuICBhc3luYyBwdXNoKGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmNhY2hlKVxuICAgICAgdGhyb3cgbmV3IENvbmZsaWN0RXJyb3IoYEtleSAke2tleX0gYWxyZWFkeSBpbiBkYXRhU3RvcmVgKTtcbiAgICB0aGlzLmNhY2hlW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIGFzeW5jIHB1dChrZXk6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICAgIHRoaXMuY2FjaGVba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgYXN5bmMgcG9wKGtleTogc3RyaW5nKSB7XG4gICAgY29uc3QgcmVzID0gdGhpcy5nZXQoa2V5KTtcbiAgICBkZWxldGUgdGhpcy5jYWNoZVtrZXldO1xuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBhc3luYyBmaWx0ZXIoZmlsdGVyOiBzdHJpbmcgfCBSZWdFeHApIHtcbiAgICBpZiAodHlwZW9mIGZpbHRlciA9PT0gXCJzdHJpbmdcIikgZmlsdGVyID0gbmV3IFJlZ0V4cChmaWx0ZXIpO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmNhY2hlKVxuICAgICAgLmZpbHRlcigoaykgPT4gISFmaWx0ZXIuZXhlYyhrKSlcbiAgICAgIC5tYXAoKGspID0+IHRoaXMuY2FjaGVba10pO1xuICB9XG5cbiAgYXN5bmMgcHVyZ2Uoa2V5Pzogc3RyaW5nKSB7XG4gICAgaWYgKCFrZXkpIHRoaXMuY2FjaGUgPSB7fTtcbiAgICBlbHNlIGF3YWl0IHRoaXMucG9wKGtleSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IERhdGFDYWNoZSB9IGZyb20gXCIuL0RhdGFDYWNoZVwiO1xuaW1wb3J0IHsgQ29udGV4dEFyZ3MgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgQ29udGV4dHVhbCB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL0NvbnRleHR1YWxcIjtcbmltcG9ydCB7IE5vdEZvdW5kRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IE9wZXJhdGlvbktleXMgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy9jb25zdGFudHNcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuZXhwb3J0IGNsYXNzIENvbnRleHQ8TSBleHRlbmRzIE1vZGVsPiBleHRlbmRzIERhdGFDYWNoZSB7XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgb3BlcmF0aW9uOiBPcGVyYXRpb25LZXlzLFxuICAgIHByb3RlY3RlZCBtb2RlbD86IENvbnN0cnVjdG9yPE0+LFxuICAgIHByb3RlY3RlZCBwYXJlbnQ/OiBDb250ZXh0PGFueT5cbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIGdldCB0aW1lc3RhbXAoKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKCk7XG4gIH1cblxuICBhc3luYyBnZXQoa2V5OiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gc3VwZXIuZ2V0KGtleSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAodGhpcy5wYXJlbnQpIHJldHVybiB0aGlzLnBhcmVudC5nZXQoa2V5KTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgcG9wKGtleTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICBpZiAoa2V5IGluIHRoaXMuY2FjaGUpIHJldHVybiBzdXBlci5wb3Aoa2V5KTtcbiAgICBpZiAoIXRoaXMucGFyZW50KSB0aHJvdyBuZXcgTm90Rm91bmRFcnJvcihgS2V5ICR7a2V5fSBub3QgaW4gZGF0YVN0b3JlYCk7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50LnBvcChrZXkpO1xuICB9XG5cbiAgY2hpbGQ8TiBleHRlbmRzIE1vZGVsPihcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgbW9kZWw/OiBDb25zdHJ1Y3RvcjxOPlxuICApOiBDb250ZXh0PE4+IHtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3RvcihvcGVyYXRpb24sIG1vZGVsLCB0aGlzKTtcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBmcm9tPE0gZXh0ZW5kcyBNb2RlbCwgQyBleHRlbmRzIENvbnRleHQ8TT4+KFxuICAgIG9wZXJhdGlvbjpcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5DUkVBVEVcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5SRUFEXG4gICAgICB8IE9wZXJhdGlvbktleXMuVVBEQVRFXG4gICAgICB8IE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxDPiB7XG4gICAgcmV0dXJuIG5ldyBDb250ZXh0KG9wZXJhdGlvbiwgbW9kZWwpIGFzIEM7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgYXJnczxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG9wZXJhdGlvbjpcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5DUkVBVEVcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5SRUFEXG4gICAgICB8IE9wZXJhdGlvbktleXMuVVBEQVRFXG4gICAgICB8IE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBhcmdzOiBhbnlbXSxcbiAgICBjb250ZXh0dWFsPzogQ29udGV4dHVhbDxNPlxuICApOiBQcm9taXNlPENvbnRleHRBcmdzPE0+PiB7XG4gICAgY29uc3QgbGFzdCA9IGFyZ3MucG9wKCk7XG5cbiAgICBhc3luYyBmdW5jdGlvbiBnZXRDb250ZXh0KCkge1xuICAgICAgaWYgKGNvbnRleHR1YWwpIHJldHVybiBjb250ZXh0dWFsLmNvbnRleHQob3BlcmF0aW9uLCBtb2RlbCwgLi4uYXJncyk7XG4gICAgICByZXR1cm4gbmV3IENvbnRleHQob3BlcmF0aW9uLCBtb2RlbCk7XG4gICAgfVxuXG4gICAgbGV0IGM6IENvbnRleHQ8TT47XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIGlmIChsYXN0IGluc3RhbmNlb2YgQ29udGV4dCkge1xuICAgICAgICBjID0gbGFzdDtcbiAgICAgICAgYXJncy5wdXNoKGxhc3QpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYyA9IGF3YWl0IGdldENvbnRleHQoKTtcbiAgICAgICAgYXJncy5wdXNoKGxhc3QsIGMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjID0gYXdhaXQgZ2V0Q29udGV4dCgpO1xuICAgICAgYXJncy5wdXNoKGMpO1xuICAgIH1cblxuICAgIHJldHVybiB7IGNvbnRleHQ6IGMsIGFyZ3M6IGFyZ3MgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuL0NvbnRleHRcIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBVdGlsIG1ldGhvZCB0byBjaGFuZ2UgYSBtZXRob2Qgb2YgYW4gb2JqZWN0IHByZWZpeGluZyBpdCB3aXRoIGFub3RoZXJcbiAqIEBwYXJhbSB7YW55fSBvYmogVGhlIEJhc2UgT2JqZWN0XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBhZnRlciBUaGUgb3JpZ2luYWwgbWV0aG9kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVmaXggVGhlIFByZWZpeCBtZXRob2QuIFRoZSBvdXRwdXQgd2lsbCBiZSB1c2VkIGFzIGFyZ3VtZW50cyBpbiB0aGUgb3JpZ2luYWwgbWV0aG9kXG4gKiBAcGFyYW0ge3N0cmluZ30gW2FmdGVyTmFtZV0gV2hlbiB0aGUgYWZ0ZXIgZnVuY3Rpb24gYW5tZSBjYW5ub3QgYmUgZXh0cmFjdGVkLCBwYXNzIGl0IGhlcmVcbiAqXG4gKiBAZnVuY3Rpb24gcHJlZml4TWV0aG9kXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzLlJlcG9zaXRvcnlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZWZpeE1ldGhvZChcbiAgb2JqOiBhbnksXG4gIGFmdGVyOiAoLi4uYXJnczogYW55W10pID0+IGFueSxcbiAgcHJlZml4OiAoLi4uYXJnczogYW55W10pID0+IGFueSxcbiAgYWZ0ZXJOYW1lPzogc3RyaW5nXG4pIHtcbiAgYXN5bmMgZnVuY3Rpb24gd3JhcHBlcih0aGlzOiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UucmVzb2x2ZShwcmVmaXguY2FsbCh0aGlzLCAuLi5hcmdzKSk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShhZnRlci5hcHBseSh0aGlzLCByZXN1bHRzKSk7XG4gIH1cbiAgY29uc3Qgd3JhcHBlZCA9IHdyYXBwZXIuYmluZChvYmopO1xuICBjb25zdCBuYW1lID0gYWZ0ZXJOYW1lID8gYWZ0ZXJOYW1lIDogYWZ0ZXIubmFtZTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdyYXBwZWQsIFwibmFtZVwiLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICAgIHZhbHVlOiBuYW1lLFxuICB9KTtcbiAgb2JqW25hbWVdID0gd3JhcHBlZDtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBVdGlsIG1ldGhvZCB0byBjaGFuZ2UgYSBtZXRob2Qgb2YgYW4gb2JqZWN0IHN1ZmZpeGluZyBpdCB3aXRoIGFub3RoZXJcbiAqIEBwYXJhbSB7YW55fSBvYmogVGhlIEJhc2UgT2JqZWN0XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBiZWZvcmUgVGhlIG9yaWdpbmFsIG1ldGhvZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3VmZml4IFRoZSBQcmVmaXggbWV0aG9kLiBUaGUgb3V0cHV0IHdpbGwgYmUgdXNlZCBhcyBhcmd1bWVudHMgaW4gdGhlIG9yaWdpbmFsIG1ldGhvZFxuICogQHBhcmFtIHtzdHJpbmd9IFtiZWZvcmVOYW1lXSBXaGVuIHRoZSBhZnRlciBmdW5jdGlvbiBhbm1lIGNhbm5vdCBiZSBleHRyYWN0ZWQsIHBhc3MgaXQgaGVyZVxuICpcbiAqIEBmdW5jdGlvbiBzdWZmaXhNZXRob2RcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuUmVwb3NpdG9yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3VmZml4TWV0aG9kKFxuICBvYmo6IGFueSxcbiAgYmVmb3JlOiAoLi4uYXJnczogYW55W10pID0+IGFueSxcbiAgc3VmZml4OiAoLi4uYXJnczogYW55W10pID0+IGFueSxcbiAgYmVmb3JlTmFtZT86IHN0cmluZ1xuKSB7XG4gIGFzeW5jIGZ1bmN0aW9uIHdyYXBwZXIodGhpczogYW55LCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoYmVmb3JlLmNhbGwodGhpcywgLi4uYXJncykpO1xuICAgIHJldHVybiBzdWZmaXguY2FsbCh0aGlzLCAuLi5yZXN1bHRzKTtcbiAgfVxuICBjb25zdCB3cmFwcGVkID0gd3JhcHBlci5iaW5kKG9iaik7XG4gIGNvbnN0IG5hbWUgPSBiZWZvcmVOYW1lID8gYmVmb3JlTmFtZSA6IGJlZm9yZS5uYW1lO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkod3JhcHBlZCwgXCJuYW1lXCIsIHtcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IG5hbWUsXG4gIH0pO1xuICBvYmpbbmFtZV0gPSB3cmFwcGVkO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgbWV0aG9kIHRvIHdyYXAgYSBtZXRob2Qgb2YgYW4gb2JqZWN0IHdpdGggYWRkaXRpb25hbCBsb2dpY1xuICpcbiAqIEBwYXJhbSB7YW55fSBvYmogVGhlIEJhc2UgT2JqZWN0XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBiZWZvcmUgdGhlIG1ldGhvZCB0byBiZSBwcmVmaXhlZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gbWV0aG9kIHRoZSBtZXRob2QgdG8gYmUgd3JhcHBlZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gYWZ0ZXIgVGhlIG1ldGhvZCB0byBiZSBzdWZmaXhlZFxuICogQHBhcmFtIHtzdHJpbmd9IFttZXRob2ROYW1lXSBXaGVuIHRoZSBhZnRlciBmdW5jdGlvbiBhbm1lIGNhbm5vdCBiZSBleHRyYWN0ZWQsIHBhc3MgaXQgaGVyZVxuICpcbiAqIEBmdW5jdGlvbiB3cmFwTWV0aG9kV2l0aENvbnRleHRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuUmVwb3NpdG9yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JhcE1ldGhvZFdpdGhDb250ZXh0KFxuICBvYmo6IGFueSxcbiAgYmVmb3JlOiAoLi4uYXJnczogYW55W10pID0+IGFueSxcbiAgbWV0aG9kOiAoLi4uYXJnczogYW55W10pID0+IGFueSxcbiAgYWZ0ZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBtZXRob2ROYW1lPzogc3RyaW5nXG4pIHtcbiAgYXN5bmMgZnVuY3Rpb24gd3JhcHBlcih0aGlzOiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgbGV0IHRyYW5zZm9ybWVkQXJncyA9IGJlZm9yZS5jYWxsKG9iaiwgLi4uYXJncyk7XG4gICAgaWYgKHRyYW5zZm9ybWVkQXJncyBpbnN0YW5jZW9mIFByb21pc2UpXG4gICAgICB0cmFuc2Zvcm1lZEFyZ3MgPSBhd2FpdCB0cmFuc2Zvcm1lZEFyZ3M7XG4gICAgY29uc3QgY29udGV4dCA9IHRyYW5zZm9ybWVkQXJnc1t0cmFuc2Zvcm1lZEFyZ3MubGVuZ3RoIC0gMV0gYXMgYW55O1xuICAgIGlmICghKGNvbnRleHQgaW5zdGFuY2VvZiBDb250ZXh0KSlcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzc2luZyBhIGNvbnRleHRcIik7XG4gICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBtZXRob2QuY2FsbChvYmosIC4uLnRyYW5zZm9ybWVkQXJncyk7XG4gICAgaWYgKHJlc3VsdHMgaW5zdGFuY2VvZiBQcm9taXNlKSByZXN1bHRzID0gYXdhaXQgcmVzdWx0cztcbiAgICByZXN1bHRzID0gYWZ0ZXIuY2FsbCh0aGlzLCByZXN1bHRzLCBjb250ZXh0KTtcbiAgICBpZiAocmVzdWx0cyBpbnN0YW5jZW9mIFByb21pc2UpIHJlc3VsdHMgPSBhd2FpdCByZXN1bHRzO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG4gIGNvbnN0IHdyYXBwZWQgPSB3cmFwcGVyLmJpbmQob2JqKTtcbiAgY29uc3QgbmFtZSA9IG1ldGhvZE5hbWUgPyBtZXRob2ROYW1lIDogbWV0aG9kLm5hbWU7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3cmFwcGVkLCBcIm5hbWVcIiwge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogbmFtZSxcbiAgfSk7XG4gIG9ialtuYW1lXSA9IHdyYXBwZWQ7XG59XG4iLCJpbXBvcnQgeyBEQktleXMgfSBmcm9tIFwiLi4vbW9kZWwvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS91dGlsc1wiO1xuaW1wb3J0IHsgTW9kZWwsIE1vZGVsS2V5cywgc2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvZXJyb3JzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgUmV0dXJucyB0aGUgcHJpbWFyeSBrZXkgYXR0cmlidXRlIGZvciBhIHtAbGluayBNb2RlbH1cbiAqIEBkZXNjcmlwdGlvbiBzZWFyY2hlcyBpbiBhbGwgdGhlIHByb3BlcnRpZXMgaW4gdGhlIG9iamVjdCBmb3IgYW4ge0BsaW5rIGlkfSBkZWNvcmF0ZWQgcHJvcGVydHlcbiAqXG4gKiBAcGFyYW0ge01vZGVsfSBtb2RlbFxuICpcbiAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IGlmIG5vIHByb3BlcnR5IG9yIG1vcmUgdGhhbiBvbmUgcHJvcGVydGllcyBhcmUge0BsaW5rIGlkfSBkZWNvcmF0ZWRcbiAqIG9yIG5vIHZhbHVlIGlzIHNldCBpbiB0aGF0IHByb3BlcnR5XG4gKlxuICogQGZ1bmN0aW9uIGZpbmRQcmltYXJ5S2V5XG4gKlxuICogQGNhdGVnb3J5IG1hbmFnZXJzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kUHJpbWFyeUtleTxUIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBUKSB7XG4gIGNvbnN0IGRlY29yYXRvcnMgPSBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUoXG4gICAgbW9kZWwsXG4gICAgdW5kZWZpbmVkLFxuICAgIERCS2V5cy5SRUZMRUNUICsgREJLZXlzLklEXG4gICk7XG4gIGNvbnN0IGlkRGVjb3JhdG9ycyA9IE9iamVjdC5lbnRyaWVzKGRlY29yYXRvcnMgYXMgb2JqZWN0KS5yZWR1Y2UoXG4gICAgKGFjY3VtOiB7IFtpbmRleGVyOiBzdHJpbmddOiBhbnlbXSB9LCBbcHJvcCwgZGVjc10pID0+IHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkID0gKGRlY3MgYXMgeyBrZXk6IHN0cmluZyB9W10pLmZpbHRlcihcbiAgICAgICAgKGQpID0+IGQua2V5ICE9PSBNb2RlbEtleXMuVFlQRVxuICAgICAgKTtcbiAgICAgIGlmIChmaWx0ZXJlZCAmJiBmaWx0ZXJlZC5sZW5ndGgpIHtcbiAgICAgICAgYWNjdW1bcHJvcF0gPSBhY2N1bVtwcm9wXSB8fCBbXTtcbiAgICAgICAgYWNjdW1bcHJvcF0ucHVzaCguLi5maWx0ZXJlZCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSxcbiAgICB7fVxuICApO1xuXG4gIGlmICghaWREZWNvcmF0b3JzIHx8ICFPYmplY3Qua2V5cyhpZERlY29yYXRvcnMpLmxlbmd0aClcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkNvdWxkIG5vdCBmaW5kIElEIGRlY29yYXRlZCBQcm9wZXJ0eVwiKTtcbiAgaWYgKE9iamVjdC5rZXlzKGlkRGVjb3JhdG9ycykubGVuZ3RoID4gMSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihzZihPYmplY3Qua2V5cyhpZERlY29yYXRvcnMpLmpvaW4oXCIsIFwiKSkpO1xuICBjb25zdCBpZFByb3AgPSBPYmplY3Qua2V5cyhpZERlY29yYXRvcnMpWzBdO1xuICBpZiAoIWlkUHJvcCkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJDb3VsZCBub3QgZmluZCBJRCBkZWNvcmF0ZWQgUHJvcGVydHlcIik7XG4gIHJldHVybiB7XG4gICAgaWQ6IGlkUHJvcCxcbiAgICBwcm9wczogaWREZWNvcmF0b3JzW2lkUHJvcF1bMF0ucHJvcHMsXG4gIH07XG59XG5cbi8qKlxuICogQHN1bW1hcnkgUmV0dXJucyB0aGUgcHJpbWFyeSBrZXkgdmFsdWUgZm9yIGEge0BsaW5rIE1vZGVsfVxuICogQGRlc2NyaXB0aW9uIHNlYXJjaGVzIGluIGFsbCB0aGUgcHJvcGVydGllcyBpbiB0aGUgb2JqZWN0IGZvciBhbiB7QGxpbmsgcGt9IGRlY29yYXRlZCBwcm9wZXJ0eVxuICpcbiAqIEBwYXJhbSB7TW9kZWx9IG1vZGVsXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXR1cm5FbXB0eV1cbiAqIEByZXR1cm4ge3N0cmluZ30gcHJpbWFyeSBrZXlcbiAqXG4gKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBpZiBubyBwcm9wZXJ0eSBvciBtb3JlIHRoYW4gb25lIHByb3BlcnRpZXMgYXJlIHtAbGluayBwa30gZGVjb3JhdGVkXG4gKiBAdGhyb3dzIHtOb3RGb3VuZEVycm9yfSByZXR1cm5FbXB0eSBpcyBmYWxzZSBhbmQgbm8gdmFsdWUgaXMgc2V0IG9uIHRoZSB7QGxpbmsgcGt9IGRlY29yYXRlZCBwcm9wZXJ0eVxuICpcbiAqIEBmdW5jdGlvbiBmaW5kTW9kZWxJRFxuICpcbiAqIEBjYXRlZ29yeSBtYW5hZ2Vyc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZE1vZGVsSWQobW9kZWw6IE1vZGVsLCByZXR1cm5FbXB0eSA9IGZhbHNlKSB7XG4gIGNvbnN0IGlkUHJvcCA9IGZpbmRQcmltYXJ5S2V5KG1vZGVsKS5pZDtcbiAgY29uc3QgbW9kZWxJZCA9IChtb2RlbCBhcyBhbnkpW2lkUHJvcF07XG4gIGlmICghbW9kZWxJZCAmJiAhcmV0dXJuRW1wdHkpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBzZihcIk5vIHZhbHVlIGZvciB0aGUgSWQgaXMgZGVmaW5lZCB1bmRlciB0aGUgcHJvcGVydHkgezB9XCIsIGlkUHJvcClcbiAgICApO1xuICByZXR1cm4gbW9kZWxJZDtcbn1cbiIsImltcG9ydCB7IElSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvSVJlcG9zaXRvcnlcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCwgc2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBlbmZvcmNlREJEZWNvcmF0b3JzIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IE9wZXJhdGlvbktleXMgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy9jb25zdGFudHNcIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IHdyYXBNZXRob2RXaXRoQ29udGV4dCB9IGZyb20gXCIuL3dyYXBwZXJzXCI7XG5pbXBvcnQgeyBmaW5kUHJpbWFyeUtleSB9IGZyb20gXCIuLi9pZGVudGl0eS91dGlsc1wiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuL0NvbnRleHRcIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VSZXBvc2l0b3J5PE0gZXh0ZW5kcyBNb2RlbD5cbiAgaW1wbGVtZW50cyBJUmVwb3NpdG9yeTxNPlxue1xuICBwcml2YXRlIHJlYWRvbmx5IF9jbGFzcyE6IENvbnN0cnVjdG9yPE0+O1xuICBwcml2YXRlIF9wayE6IHN0cmluZztcblxuICBnZXQgY2xhc3MoKSB7XG4gICAgaWYgKCF0aGlzLl9jbGFzcylcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBObyBjbGFzcyBkZWZpbml0aW9uIGZvdW5kIGZvciB0aGlzIHJlcG9zaXRvcnlgKTtcbiAgICByZXR1cm4gdGhpcy5fY2xhc3M7XG4gIH1cblxuICBnZXQgcGsoKSB7XG4gICAgaWYgKCF0aGlzLl9waykgdGhpcy5fcGsgPSBmaW5kUHJpbWFyeUtleShuZXcgdGhpcy5jbGFzcygpKS5pZDtcbiAgICByZXR1cm4gdGhpcy5fcGs7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xheno/OiBDb25zdHJ1Y3RvcjxNPikge1xuICAgIGlmIChjbGF6eikgdGhpcy5fY2xhc3MgPSBjbGF6ejtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBbdGhpcy5jcmVhdGUsIHRoaXMucmVhZCwgdGhpcy51cGRhdGUsIHRoaXMuZGVsZXRlXS5mb3JFYWNoKChtKSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gbS5uYW1lO1xuICAgICAgd3JhcE1ldGhvZFdpdGhDb250ZXh0KFxuICAgICAgICBzZWxmLFxuICAgICAgICAoc2VsZiBhcyBhbnkpW25hbWUgKyBcIlByZWZpeFwiXSxcbiAgICAgICAgbSxcbiAgICAgICAgKHNlbGYgYXMgYW55KVtuYW1lICsgXCJTdWZmaXhcIl1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBhYnN0cmFjdCBjcmVhdGUobW9kZWw6IE0sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNPjtcblxuICBhc3luYyBjcmVhdGVBbGwobW9kZWxzOiBNW10sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNW10+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwobW9kZWxzLm1hcCgobSkgPT4gdGhpcy5jcmVhdGUobSwgLi4uYXJncykpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBjcmVhdGVQcmVmaXgobW9kZWw6IE0sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBtb2RlbCA9IG5ldyB0aGlzLmNsYXNzKG1vZGVsKTtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICk7XG4gICAgcmV0dXJuIFttb2RlbCwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDb250ZXh0PE0+KSB7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICApO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBjcmVhdGVBbGxQcmVmaXgobW9kZWxzOiBNW10sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoYXN5bmMgKG0pID0+IHtcbiAgICAgICAgbSA9IG5ldyB0aGlzLmNsYXNzKG0pO1xuICAgICAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIG07XG4gICAgICB9KVxuICAgICk7XG4gICAgcmV0dXJuIFttb2RlbHMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGNyZWF0ZUFsbFN1ZmZpeChtb2RlbHM6IE1bXSwgY29udGV4dDogQ29udGV4dDxNPikge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcCgobSkgPT5cbiAgICAgICAgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkFGVEVSXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuICAgIHJldHVybiBtb2RlbHM7XG4gIH1cblxuICBhYnN0cmFjdCByZWFkKGtleTogc3RyaW5nIHwgbnVtYmVyLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT47XG5cbiAgYXN5bmMgcmVhZEFsbChrZXlzOiBzdHJpbmdbXSB8IG51bWJlcltdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKGtleXMubWFwKChpZCkgPT4gdGhpcy5yZWFkKGlkLCAuLi5hcmdzKSkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHJlYWRTdWZmaXgobW9kZWw6IE0sIGNvbnRleHQ6IENvbnRleHQ8TT4pIHtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICApO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyByZWFkUHJlZml4KGtleTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3NcbiAgICApO1xuICAgIGNvbnN0IG1vZGVsOiBNID0gbmV3IHRoaXMuY2xhc3MoKTtcbiAgICAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbdGhpcy5wa10gPSBrZXk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgKTtcbiAgICByZXR1cm4gW2tleSwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgcmVhZEFsbFByZWZpeChrZXlzOiBzdHJpbmdbXSB8IG51bWJlcltdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3NcbiAgICApO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAga2V5cy5tYXAoYXN5bmMgKGspID0+IHtcbiAgICAgICAgY29uc3QgbSA9IG5ldyB0aGlzLmNsYXNzKCk7XG4gICAgICAgIChtIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3RoaXMucGtdID0gaztcbiAgICAgICAgcmV0dXJuIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gW2tleXMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHJlYWRBbGxTdWZmaXgobW9kZWxzOiBNW10sIGNvbnRleHQ6IENvbnRleHQ8TT4pIHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoKG0pID0+XG4gICAgICAgIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICAgICAgKVxuICAgICAgKVxuICAgICk7XG4gICAgcmV0dXJuIG1vZGVscztcbiAgfVxuXG4gIGFic3RyYWN0IHVwZGF0ZShtb2RlbDogTSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+O1xuXG4gIGFzeW5jIHVwZGF0ZUFsbChtb2RlbHM6IE1bXSwgLi4uYXJnczogYW55KTogUHJvbWlzZTxNW10+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwobW9kZWxzLm1hcCgobSkgPT4gdGhpcy51cGRhdGUobSwgLi4uYXJncykpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB1cGRhdGVTdWZmaXgobW9kZWw6IE0sIGNvbnRleHQ6IENvbnRleHQ8TT4pIHtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgT3BlcmF0aW9uS2V5cy5BRlRFUlxuICAgICk7XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHVwZGF0ZVByZWZpeChtb2RlbDogTSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3NcbiAgICApO1xuICAgIGNvbnN0IGlkID0gKG1vZGVsIGFzIGFueSlbdGhpcy5wa107XG4gICAgaWYgKCFpZClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgTm8gdmFsdWUgZm9yIHRoZSBJZCBpcyBkZWZpbmVkIHVuZGVyIHRoZSBwcm9wZXJ0eSAke3RoaXMucGt9YFxuICAgICAgKTtcbiAgICBjb25zdCBvbGRNb2RlbCA9IGF3YWl0IHRoaXMucmVhZChpZCk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT04sXG4gICAgICBvbGRNb2RlbFxuICAgICk7XG4gICAgcmV0dXJuIFttb2RlbCwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgdXBkYXRlQWxsUHJlZml4KG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKChtKSA9PiB7XG4gICAgICAgIG0gPSBuZXcgdGhpcy5jbGFzcyhtKTtcbiAgICAgICAgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBtO1xuICAgICAgfSlcbiAgICApO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB1cGRhdGVBbGxTdWZmaXgobW9kZWxzOiBNW10sIGNvbnRleHQ6IENvbnRleHQ8TT4pIHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoKG0pID0+XG4gICAgICAgIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5BRlRFUlxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcbiAgICByZXR1cm4gbW9kZWxzO1xuICB9XG5cbiAgYWJzdHJhY3QgZGVsZXRlKGtleTogc3RyaW5nIHwgbnVtYmVyLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT47XG5cbiAgYXN5bmMgZGVsZXRlQWxsKGtleXM6IHN0cmluZ1tdIHwgbnVtYmVyW10sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNW10+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoa2V5cy5tYXAoKGspID0+IHRoaXMuZGVsZXRlKGssIC4uLmFyZ3MpKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZGVsZXRlU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDb250ZXh0PE0+KSB7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICApO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBkZWxldGVQcmVmaXgoa2V5OiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMucmVhZChrZXksIC4uLmNvbnRleHRBcmdzLmFyZ3MpO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgKTtcbiAgICByZXR1cm4gW2tleSwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZGVsZXRlQWxsUHJlZml4KGtleXM6IHN0cmluZ1tdIHwgbnVtYmVyW10sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCB0aGlzLnJlYWRBbGwoa2V5cywgLi4uY29udGV4dEFyZ3MuYXJncyk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKGFzeW5jIChtKSA9PiB7XG4gICAgICAgIHJldHVybiBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gW2tleXMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGRlbGV0ZUFsbFN1ZmZpeChtb2RlbHM6IE1bXSwgY29udGV4dDogQ29udGV4dDxNPikge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcCgobSkgPT5cbiAgICAgICAgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkFGVEVSXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuICAgIHJldHVybiBtb2RlbHM7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWVyZ2Uob2xkTW9kZWw6IE0sIG1vZGVsOiBNKTogTSB7XG4gICAgY29uc3QgZXh0cmFjdCA9IChtb2RlbDogTSkgPT5cbiAgICAgIE9iamVjdC5lbnRyaWVzKG1vZGVsKS5yZWR1Y2UoKGFjY3VtOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBba2V5LCB2YWxdKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsICE9PSBcInVuZGVmaW5lZFwiKSBhY2N1bVtrZXldID0gdmFsO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB7fSk7XG5cbiAgICByZXR1cm4gbmV3IHRoaXMuY2xhc3MoT2JqZWN0LmFzc2lnbih7fSwgZXh0cmFjdChvbGRNb2RlbCksIGV4dHJhY3QobW9kZWwpKSk7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gc2YoXG4gICAgICBcIlt7MH1dIC0gUmVwb3NpdG9yeSBmb3IgezF9XCIsXG4gICAgICB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICB0aGlzLmNsYXNzLm5hbWVcbiAgICApO1xuICB9XG59XG4iLCJpbXBvcnQgeyBlbmZvcmNlREJEZWNvcmF0b3JzIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IE9wZXJhdGlvbktleXMgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy9jb25zdGFudHNcIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IsIFZhbGlkYXRpb25FcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgQmFzZVJlcG9zaXRvcnkgfSBmcm9tIFwiLi9CYXNlUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgREJLZXlzIH0gZnJvbSBcIi4uL21vZGVsL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuL0NvbnRleHRcIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFJlcG9zaXRvcnk8TSBleHRlbmRzIE1vZGVsPiBleHRlbmRzIEJhc2VSZXBvc2l0b3J5PE0+IHtcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGNsYXp6PzogQ29uc3RydWN0b3I8TT4pIHtcbiAgICBzdXBlcihjbGF6eik7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgY3JlYXRlUHJlZml4KFxuICAgIG1vZGVsOiBNLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8W00sIC4uLmFueVtdXT4ge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgbW9kZWwgPSBuZXcgdGhpcy5jbGFzcyhtb2RlbCk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICApO1xuXG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWwuaGFzRXJyb3JzKCk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMudG9TdHJpbmcoKSk7XG5cbiAgICByZXR1cm4gW21vZGVsLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBjcmVhdGVBbGxQcmVmaXgobW9kZWxzOiBNW10sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxhbnlbXT4ge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKGFzeW5jIChtKSA9PiB7XG4gICAgICAgIG0gPSBuZXcgdGhpcy5jbGFzcyhtKTtcbiAgICAgICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBtO1xuICAgICAgfSlcbiAgICApO1xuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsc1xuICAgICAgLm1hcCgobSkgPT4gbS5oYXNFcnJvcnMoKSlcbiAgICAgIC5yZWR1Y2UoKGFjY3VtOiBzdHJpbmcgfCB1bmRlZmluZWQsIGUsIGkpID0+IHtcbiAgICAgICAgaWYgKGUpXG4gICAgICAgICAgYWNjdW0gPVxuICAgICAgICAgICAgdHlwZW9mIGFjY3VtID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgID8gYWNjdW0gKyBgXFxuIC0gJHtpfTogJHtlLnRvU3RyaW5nKCl9YFxuICAgICAgICAgICAgICA6IGAgLSAke2l9OiAke2UudG9TdHJpbmcoKX1gO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB1bmRlZmluZWQpO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzKTtcbiAgICByZXR1cm4gW21vZGVscywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgdXBkYXRlUHJlZml4KFxuICAgIG1vZGVsOiBNLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8W00sIC4uLmFyZ3M6IGFueVtdXT4ge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgY29uc3QgcGsgPSAobW9kZWwgYXMgYW55KVt0aGlzLnBrXTtcbiAgICBpZiAoIXBrKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBObyB2YWx1ZSBmb3IgdGhlIElkIGlzIGRlZmluZWQgdW5kZXIgdGhlIHByb3BlcnR5ICR7dGhpcy5wa31gXG4gICAgICApO1xuXG4gICAgY29uc3Qgb2xkTW9kZWwgPSBhd2FpdCB0aGlzLnJlYWQocGspO1xuXG4gICAgbW9kZWwgPSB0aGlzLm1lcmdlKG9sZE1vZGVsLCBtb2RlbCk7XG5cbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTixcbiAgICAgIG9sZE1vZGVsXG4gICAgKTtcblxuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsLmhhc0Vycm9ycyhvbGRNb2RlbCk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMudG9TdHJpbmcoKSk7XG4gICAgcmV0dXJuIFttb2RlbCwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgdXBkYXRlQWxsUHJlZml4KG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgY29uc3QgaWRzID0gbW9kZWxzLm1hcCgobSkgPT4ge1xuICAgICAgY29uc3QgaWQgPSAobSBhcyBhbnkpW3RoaXMucGtdO1xuICAgICAgaWYgKCFpZClcbiAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgYE5vIHZhbHVlIGZvciB0aGUgSWQgaXMgZGVmaW5lZCB1bmRlciB0aGUgcHJvcGVydHkgJHt0aGlzLnBrfWBcbiAgICAgICAgKTtcbiAgICAgIHJldHVybiBpZDtcbiAgICB9KTtcbiAgICBjb25zdCBvbGRNb2RlbHMgPSBhd2FpdCB0aGlzLnJlYWRBbGwoaWRzLCAuLi5jb250ZXh0QXJncy5hcmdzKTtcbiAgICBtb2RlbHMgPSBtb2RlbHMubWFwKChtLCBpKSA9PiB0aGlzLm1lcmdlKG9sZE1vZGVsc1tpXSwgbSkpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcCgobSwgaSkgPT5cbiAgICAgICAgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OLFxuICAgICAgICAgIG9sZE1vZGVsc1tpXVxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcblxuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsc1xuICAgICAgLm1hcCgobSwgaSkgPT4gbS5oYXNFcnJvcnMob2xkTW9kZWxzW2ldLCBtKSlcbiAgICAgIC5yZWR1Y2UoKGFjY3VtOiBzdHJpbmcgfCB1bmRlZmluZWQsIGUsIGkpID0+IHtcbiAgICAgICAgaWYgKGUpXG4gICAgICAgICAgYWNjdW0gPVxuICAgICAgICAgICAgdHlwZW9mIGFjY3VtID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgID8gYWNjdW0gKyBgXFxuIC0gJHtpfTogJHtlLnRvU3RyaW5nKCl9YFxuICAgICAgICAgICAgICA6IGAgLSAke2l9OiAke2UudG9TdHJpbmcoKX1gO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB1bmRlZmluZWQpO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzKTtcbiAgICByZXR1cm4gW21vZGVscywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBzdGF0aWMga2V5KGtleTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIERCS2V5cy5SRUZMRUNUICsga2V5O1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBkYXRlLFxuICBNb2RlbCxcbiAgcHJvcE1ldGFkYXRhLFxuICByZXF1aXJlZCxcbiAgc2YsXG4gIHR5cGUsXG4gIFZhbGlkYXRpb24sXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IERCS2V5cywgREVGQVVMVF9USU1FU1RBTVBfRk9STUFUIH0gZnJvbSBcIi4uL21vZGVsL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgREJPcGVyYXRpb25zLCBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4uL29wZXJhdGlvbnMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBhZnRlciwgb24sIG9uQ3JlYXRlVXBkYXRlIH0gZnJvbSBcIi4uL29wZXJhdGlvbnMvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgSVJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9JUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgU2VyaWFsaXphdGlvbkVycm9yIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvZXJyb3JzXCI7XG5pbXBvcnQgeyBhcHBseSwgbWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L0NvbnRleHRcIjtcblxuLyoqXG4gKiBNYXJrcyB0aGUgcHJvcGVydHkgYXMgcmVhZG9ubHkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSB0aGUgZXJyb3IgbWVzc2FnZS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUkVBRE9OTFkuSU5WQUxJRH1cbiAqXG4gKiBAZGVjb3JhdG9yIHJlYWRvbmx5XG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRvbmx5KFxuICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlJFQURPTkxZLklOVkFMSURcbikge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhKFZhbGlkYXRpb24udXBkYXRlS2V5KERCS2V5cy5SRUFET05MWSksIHtcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICB9KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRpbWVzdGFtcEhhbmRsZXI8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgViBleHRlbmRzIElSZXBvc2l0b3J5PE0+LFxuICBZID0gYW55LFxuPih0aGlzOiBWLCBjb250ZXh0OiBDb250ZXh0PE0+LCBkYXRhOiBZLCBrZXk6IHN0cmluZywgbW9kZWw6IE0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IGNvbnRleHQudGltZXN0YW1wO1xufVxuXG4vKipcbiAqIE1hcmtzIHRoZSBwcm9wZXJ0eSBhcyB0aW1lc3RhbXAuXG4gKiBNYWtlcyBpdCB7QGxpbmsgcmVxdWlyZWR9XG4gKiBNYWtlcyBpdCBhIHtAbGluayBkYXRlfVxuICpcbiAqIERhdGUgRm9ybWF0OlxuICpcbiAqIDxwcmU+XG4gKiAgICAgIFVzaW5nIHNpbWlsYXIgZm9ybWF0dGluZyBhcyBNb21lbnQuanMsIENsYXNzIERhdGVUaW1lRm9ybWF0dGVyIChKYXZhKSwgYW5kIENsYXNzIFNpbXBsZURhdGVGb3JtYXQgKEphdmEpLFxuICogICAgICBJIGltcGxlbWVudGVkIGEgY29tcHJlaGVuc2l2ZSBzb2x1dGlvbiBmb3JtYXREYXRlKGRhdGUsIHBhdHRlcm5TdHIpIHdoZXJlIHRoZSBjb2RlIGlzIGVhc3kgdG8gcmVhZCBhbmQgbW9kaWZ5LlxuICogICAgICBZb3UgY2FuIGRpc3BsYXkgZGF0ZSwgdGltZSwgQU0vUE0sIGV0Yy5cbiAqXG4gKiAgICAgIERhdGUgYW5kIFRpbWUgUGF0dGVybnNcbiAqICAgICAgeXkgPSAyLWRpZ2l0IHllYXI7IHl5eXkgPSBmdWxsIHllYXJcbiAqICAgICAgTSA9IGRpZ2l0IG1vbnRoOyBNTSA9IDItZGlnaXQgbW9udGg7IE1NTSA9IHNob3J0IG1vbnRoIG5hbWU7IE1NTU0gPSBmdWxsIG1vbnRoIG5hbWVcbiAqICAgICAgRUVFRSA9IGZ1bGwgd2Vla2RheSBuYW1lOyBFRUUgPSBzaG9ydCB3ZWVrZGF5IG5hbWVcbiAqICAgICAgZCA9IGRpZ2l0IGRheTsgZGQgPSAyLWRpZ2l0IGRheVxuICogICAgICBoID0gaG91cnMgYW0vcG07IGhoID0gMi1kaWdpdCBob3VycyBhbS9wbTsgSCA9IGhvdXJzOyBISCA9IDItZGlnaXQgaG91cnNcbiAqICAgICAgbSA9IG1pbnV0ZXM7IG1tID0gMi1kaWdpdCBtaW51dGVzOyBhYWEgPSBBTS9QTVxuICogICAgICBzID0gc2Vjb25kczsgc3MgPSAyLWRpZ2l0IHNlY29uZHNcbiAqICAgICAgUyA9IG1pbGlzZWNvbmRzXG4gKiA8L3ByZT5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBvcGVyYXRpb24gVGhlIHtAbGluayBEQk9wZXJhdGlvbnN9IHRvIGFjdCBvbi4gRGVmYXVsdHMgdG8ge0BsaW5rIERCT3BlcmF0aW9ucy5DUkVBVEVfVVBEQVRFfVxuICogQHBhcmFtIHtzdHJpbmd9IFtmb3JtYXRdIFRoZSBUaW1lU3RhbXAgZm9ybWF0LiBkZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9USU1FU1RBTVBfRk9STUFUfVxuICogQHBhcmFtIHt7bmV3OiBVcGRhdGVWYWxpZGF0b3J9fSBbdmFsaWRhdG9yXSBkZWZhdWx0cyB0byB7QGxpbmsgVGltZXN0YW1wVmFsaWRhdG9yfVxuICpcbiAqIEBkZWNvcmF0b3IgdGltZXN0YW1wXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRpbWVzdGFtcChcbiAgb3BlcmF0aW9uOiBPcGVyYXRpb25LZXlzW10gPSBEQk9wZXJhdGlvbnMuQ1JFQVRFX1VQREFURSBhcyB1bmtub3duIGFzIE9wZXJhdGlvbktleXNbXSxcbiAgZm9ybWF0OiBzdHJpbmcgPSBERUZBVUxUX1RJTUVTVEFNUF9GT1JNQVRcbikge1xuICBjb25zdCBkZWNvcmF0b3JzOiBhbnlbXSA9IFtcbiAgICBkYXRlKGZvcm1hdCwgREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5USU1FU1RBTVAuREFURSksXG4gICAgcmVxdWlyZWQoREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5USU1FU1RBTVAuUkVRVUlSRUQpLFxuICAgIG9uKG9wZXJhdGlvbiwgdGltZXN0YW1wSGFuZGxlciksXG4gIF07XG5cbiAgaWYgKG9wZXJhdGlvbi5pbmRleE9mKE9wZXJhdGlvbktleXMuVVBEQVRFKSAhPT0gLTEpXG4gICAgZGVjb3JhdG9ycy5wdXNoKFxuICAgICAgcHJvcE1ldGFkYXRhKFZhbGlkYXRpb24udXBkYXRlS2V5KERCS2V5cy5USU1FU1RBTVApLCB7XG4gICAgICAgIG1lc3NhZ2U6IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVElNRVNUQU1QLklOVkFMSUQsXG4gICAgICB9KVxuICAgICk7XG5cbiAgcmV0dXJuIGFwcGx5KC4uLmRlY29yYXRvcnMpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2VyaWFsaXplT25DcmVhdGVVcGRhdGU8XG4gIFQgZXh0ZW5kcyBNb2RlbCxcbiAgViBleHRlbmRzIElSZXBvc2l0b3J5PFQ+LFxuICBZID0gYW55LFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4+KHRoaXM6IFYsIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogVCwgb2xkTW9kZWw6IFQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCEobW9kZWwgYXMgYW55KVtrZXldKSByZXR1cm47XG4gIHRyeSB7XG4gICAgKG1vZGVsIGFzIGFueSlba2V5XSA9IEpTT04uc3RyaW5naWZ5KChtb2RlbCBhcyBhbnkpW2tleV0pO1xuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgc2YoXG4gICAgICAgIFwiRmFpbGVkIHRvIHNlcmlhbGl6ZSB7MH0gcHJvcGVydHkgb24gezF9IG1vZGVsOiB7Mn1cIixcbiAgICAgICAga2V5LFxuICAgICAgICBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgICAgICBlLm1lc3NhZ2VcbiAgICAgIClcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXJpYWxpemVBZnRlckFsbDxcbiAgVCBleHRlbmRzIE1vZGVsLFxuICBWIGV4dGVuZHMgSVJlcG9zaXRvcnk8VD4sXG4gIFkgPSBhbnksXG4+KHRoaXM6IFYsIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogVCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIShtb2RlbCBhcyBhbnkpW2tleV0pIHJldHVybjtcbiAgaWYgKHR5cGVvZiAobW9kZWwgYXMgYW55KVtrZXldICE9PSBcInN0cmluZ1wiKSByZXR1cm47XG5cbiAgdHJ5IHtcbiAgICAobW9kZWwgYXMgYW55KVtrZXldID0gSlNPTi5wYXJzZSgobW9kZWwgYXMgYW55KVtrZXldKTtcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgIHNmKFxuICAgICAgICBcIkZhaWxlZCB0byBkZXNlcmlhbGl6ZSB7MH0gcHJvcGVydHkgb24gezF9IG1vZGVsOiB7Mn1cIixcbiAgICAgICAga2V5LFxuICAgICAgICBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgICAgICBlLm1lc3NhZ2VcbiAgICAgIClcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogQHN1bW1hcnkgU2VyaWFsaXplIERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIHByb3BlcnRpZXMgZGVjb3JhdGVkIHdpbGwgdGhlIHNlcmlhbGl6ZWQgYmVmb3JlIHN0b3JlZCBpbiB0aGUgZGJcbiAqXG4gKiBAZnVuY3Rpb24gc2VyaWFsaXplXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp3YWxsZXQtZGIuRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplKCkge1xuICByZXR1cm4gYXBwbHkoXG4gICAgb25DcmVhdGVVcGRhdGUoc2VyaWFsaXplT25DcmVhdGVVcGRhdGUpLFxuICAgIGFmdGVyKERCT3BlcmF0aW9ucy5BTEwsIHNlcmlhbGl6ZUFmdGVyQWxsKSxcbiAgICB0eXBlKFtTdHJpbmcubmFtZSwgT2JqZWN0Lm5hbWVdKSxcbiAgICBtZXRhZGF0YShSZXBvc2l0b3J5LmtleShEQktleXMuU0VSSUFMSVpFKSwge30pXG4gICk7XG59XG5cbi8vXG4vLyAvKipcbi8vICAqIEBzdW1tYXJ5IE9uZSBUbyBPbmUgcmVsYXRpb24gRGVjb3JhdG9yc1xuLy8gICpcbi8vICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8YW55Pn0gY2xhenogdGhlIHtAbGluayBTZXF1ZW5jZX0gdG8gdXNlLiBEZWZhdWx0cyB0byB7QGxpbmsgTm9uZVNlcXVlbmNlfVxuLy8gICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9uc11cbi8vICAqIEBwYXJhbSB7Ym9vbGVhbn0gX3BvcHVsYXRlIElmIHRydWUsIHJlcGxhY2VzIHRoZSBzcGVjaWZpZWQga2V5IGluIHRoZSBkb2N1bWVudCB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIHJlY29yZCBmcm9tIHRoZSBkYXRhYmFzZVxuLy8gICpcbi8vICAqIEBmdW5jdGlvbiBvblRvT25lXG4vLyAgKlxuLy8gICogQG1lbWJlck9mIG1vZHVsZTp3YWxsZXQtZGIuRGVjb3JhdG9yc1xuLy8gICpcbi8vICAqIEBzZWUgb25lVG9NYW55XG4vLyAgKiBAc2VlIG1hbnlUb09uZVxuLy8gICovXG4vLyBleHBvcnQgZnVuY3Rpb24gb25lVG9PbmUoXG4vLyAgIGNsYXp6OiBDb25zdHJ1Y3Rvcjxhbnk+LFxuLy8gICBjYXNjYWRlT3B0aW9uczogQ2FzY2FkZU1ldGFkYXRhID0gRGVmYXVsdENhc2NhZGUsXG4vLyAgIF9wb3B1bGF0ZTogYm9vbGVhbiA9IHRydWUsXG4vLyApIHtcbi8vICAgTW9kZWwucmVnaXN0ZXIoY2xhenopO1xuLy8gICByZXR1cm4gKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogc3RyaW5nKSA9PiB7XG4vLyAgICAgdHlwZShbY2xhenoubmFtZSwgU3RyaW5nLm5hbWVdKSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbi8vICAgICBvbkNyZWF0ZShvbmVUb09uZU9uQ3JlYXRlKSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbi8vICAgICBvblVwZGF0ZShvbmVUb09uZU9uVXBkYXRlLCBjYXNjYWRlT3B0aW9ucyBhcyBhbnkpKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuLy8gICAgIG9uRGVsZXRlKG9uZVRvT25lT25EZWxldGUsIGNhc2NhZGVPcHRpb25zKSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbi8vXG4vLyAgICAgYWZ0ZXJDcmVhdGUocG9wdWxhdGUsIF9wb3B1bGF0ZSkodGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4vLyAgICAgYWZ0ZXJVcGRhdGUocG9wdWxhdGUsIF9wb3B1bGF0ZSkodGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4vLyAgICAgYWZ0ZXJSZWFkKHBvcHVsYXRlLCBfcG9wdWxhdGUpKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuLy8gICAgIGFmdGVyRGVsZXRlKHBvcHVsYXRlLCBfcG9wdWxhdGUpKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuLy9cbi8vICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFxuLy8gICAgICAgZ2V0REJLZXkoV2FsbGV0RGJLZXlzLk9ORV9UT19PTkUpLFxuLy8gICAgICAge1xuLy8gICAgICAgICBjb25zdHJ1Y3RvcjogY2xhenoubmFtZSxcbi8vICAgICAgICAgY2FzY2FkZTogY2FzY2FkZU9wdGlvbnMsXG4vLyAgICAgICAgIHBvcHVsYXRlOiBfcG9wdWxhdGUsXG4vLyAgICAgICB9LFxuLy8gICAgICAgdGFyZ2V0LFxuLy8gICAgICAgcHJvcGVydHlLZXksXG4vLyAgICAgKTtcbi8vICAgfTtcbi8vIH1cbi8vXG4vLyAvKipcbi8vICAqIEBzdW1tYXJ5IE9uZSBUbyBNYW55IHJlbGF0aW9uIERlY29yYXRvcnNcbi8vICAqXG4vLyAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPGFueT59IGNsYXp6IHRoZSB7QGxpbmsgU2VxdWVuY2V9IHRvIHVzZS4gRGVmYXVsdHMgdG8ge0BsaW5rIE5vbmVTZXF1ZW5jZX1cbi8vICAqIEBwYXJhbSB7Q2FzY2FkZU1ldGFkYXRhfSBbY2FzY2FkZU9wdGlvbnNdXG4vLyAgKlxuLy8gICogQGZ1bmN0aW9uIG9uVG9NYW55XG4vLyAgKlxuLy8gICogQG1lbWJlck9mIG1vZHVsZTp3YWxsZXQtZGIuRGVjb3JhdG9yc1xuLy8gICpcbi8vICAqIEBzZWUgb25lVG9PbmVcbi8vICAqIEBzZWUgbWFueVRvT25lXG4vLyAgKi9cbi8vIGV4cG9ydCBmdW5jdGlvbiBvbmVUb01hbnkoXG4vLyAgIGNsYXp6OiBDb25zdHJ1Y3Rvcjxhbnk+LFxuLy8gICBjYXNjYWRlT3B0aW9uczogQ2FzY2FkZU1ldGFkYXRhID0gRGVmYXVsdENhc2NhZGUsXG4vLyAgIF9wb3B1bGF0ZTogYm9vbGVhbiA9IHRydWUsXG4vLyApIHtcbi8vICAgTW9kZWwucmVnaXN0ZXIoY2xhenopO1xuLy8gICByZXR1cm4gKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogc3RyaW5nKSA9PiB7XG4vLyAgICAgbGlzdChbY2xhenosIFN0cmluZ10pKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuLy8gICAgIG9uQ3JlYXRlKG9uZVRvTWFueU9uQ3JlYXRlKSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbi8vICAgICBvblVwZGF0ZShvbmVUb01hbnlPblVwZGF0ZSwgY2FzY2FkZU9wdGlvbnMpKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuLy8gICAgIG9uRGVsZXRlKG9uZVRvTWFueU9uRGVsZXRlLCBjYXNjYWRlT3B0aW9ucykodGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4vL1xuLy8gICAgIGFmdGVyQ3JlYXRlKHBvcHVsYXRlLCBfcG9wdWxhdGUpKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuLy8gICAgIGFmdGVyVXBkYXRlKHBvcHVsYXRlLCBfcG9wdWxhdGUpKHRhcmdldCwgcHJvcGVydHlLZXkpO1xuLy8gICAgIGFmdGVyUmVhZChwb3B1bGF0ZSwgX3BvcHVsYXRlKSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbi8vICAgICBhZnRlckRlbGV0ZShwb3B1bGF0ZSwgX3BvcHVsYXRlKSh0YXJnZXQsIHByb3BlcnR5S2V5KTtcbi8vXG4vLyAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbi8vICAgICAgIGdldERCS2V5KFdhbGxldERiS2V5cy5PTkVfVE9fTUFOWSksXG4vLyAgICAgICB7XG4vLyAgICAgICAgIGNvbnN0cnVjdG9yOiBjbGF6ei5uYW1lLFxuLy8gICAgICAgICBjYXNjYWRlOiBjYXNjYWRlT3B0aW9ucyxcbi8vICAgICAgIH0sXG4vLyAgICAgICB0YXJnZXQsXG4vLyAgICAgICBwcm9wZXJ0eUtleSxcbi8vICAgICApO1xuLy8gICB9O1xuLy8gfVxuLy9cbi8vIC8qKlxuLy8gICogQHN1bW1hcnkgTWFueSBUbyBPbmUgcmVsYXRpb24gRGVjb3JhdG9yc1xuLy8gICpcbi8vICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8YW55Pn0gY2xhenogdGhlIHtAbGluayBTZXF1ZW5jZX0gdG8gdXNlLiBEZWZhdWx0cyB0byB7QGxpbmsgTm9uZVNlcXVlbmNlfVxuLy8gICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9uc11cbi8vICAqXG4vLyAgKiBAZnVuY3Rpb24gbWFueVRvT25lXG4vLyAgKlxuLy8gICogQG1lbWJlck9mIG1vZHVsZTp3YWxsZXQtZGIuRGVjb3JhdG9yc1xuLy8gICpcbi8vICAqIEBzZWUgb25lVG9NYW55XG4vLyAgKiBAc2VlIG9uZVRvT25lXG4vLyAgKi9cbi8vIGV4cG9ydCBmdW5jdGlvbiBtYW55VG9PbmUoXG4vLyAgIGNsYXp6OiBDb25zdHJ1Y3Rvcjxhbnk+LFxuLy8gICBjYXNjYWRlT3B0aW9uczogQ2FzY2FkZU1ldGFkYXRhID0gRGVmYXVsdENhc2NhZGUsXG4vLyApIHtcbi8vICAgTW9kZWwucmVnaXN0ZXIoY2xhenopO1xuLy8gICByZXR1cm4gKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogc3RyaW5nKSA9PiB7XG4vLyAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbi8vICAgICAgIGdldERCS2V5KFdhbGxldERiS2V5cy5NQU5ZX1RPX09ORSksXG4vLyAgICAgICB7XG4vLyAgICAgICAgIGNvbnN0cnVjdG9yOiBjbGF6ei5uYW1lLFxuLy8gICAgICAgICBjYXNjYWRlOiBjYXNjYWRlT3B0aW9ucyxcbi8vICAgICAgIH0sXG4vLyAgICAgICB0YXJnZXQsXG4vLyAgICAgICBwcm9wZXJ0eUtleSxcbi8vICAgICApO1xuLy8gICB9O1xuLy8gfVxuIiwiaW1wb3J0IHtcbiAgVmFsaWRhdG9yLFxuICBWYWxpZGF0aW9uLFxuICBWYWxpZGF0b3JEZWZpbml0aW9uLFxuICBJVmFsaWRhdG9yUmVnaXN0cnksXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFVwZGF0ZVZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cblZhbGlkYXRpb24udXBkYXRlS2V5ID0gZnVuY3Rpb24gKGtleTogc3RyaW5nKSB7XG4gIHJldHVybiBVcGRhdGVWYWxpZGF0aW9uS2V5cy5SRUZMRUNUICsga2V5O1xufTtcblxuZGVjbGFyZSBtb2R1bGUgXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnRcbiAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICBkZWNsYXJlIGNsYXNzIFZhbGlkYXRpb24ge1xuICAgIHByaXZhdGUgc3RhdGljIGFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5PztcbiAgICBwcml2YXRlIGNvbnN0cnVjdG9yKCk7XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgYWN0aW5nIFZhbGlkYXRvclJlZ2lzdHJ5XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0lWYWxpZGF0b3JSZWdpc3RyeX0gdmFsaWRhdG9yUmVnaXN0cnkgdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgdmFsaWRhdG9yIFJlZ2lzdHJ5XG4gICAgICogQHBhcmFtIHtmdW5jdGlvbihWYWxpZGF0b3IpOiBWYWxpZGF0b3J9IFttaWdyYXRpb25IYW5kbGVyXSB0aGUgbWV0aG9kIHRvIG1hcCB0aGUgdmFsaWRhdG9yIGlmIHJlcXVpcmVkO1xuICAgICAqL1xuICAgIHN0YXRpYyBzZXRSZWdpc3RyeShcbiAgICAgIHZhbGlkYXRvclJlZ2lzdHJ5OiBJVmFsaWRhdG9yUmVnaXN0cnk8VmFsaWRhdG9yPixcbiAgICAgIG1pZ3JhdGlvbkhhbmRsZXI/OiAodmFsaWRhdG9yOiBWYWxpZGF0b3IpID0+IFZhbGlkYXRvclxuICAgICk6IHZvaWQ7XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgY3VycmVudCBWYWxpZGF0b3JSZWdpc3RyeVxuICAgICAqXG4gICAgICogQHJldHVybiBJVmFsaWRhdG9yUmVnaXN0cnksIGRlZmF1bHRzIHRvIHtAbGluayBWYWxpZGF0b3JSZWdpc3RyeX1cbiAgICAgKi9cbiAgICBwcml2YXRlIHN0YXRpYyBnZXRSZWdpc3RyeTtcbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYSB2YWxpZGF0b3JcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB2YWxpZGF0b3JLZXkgb25lIG9mIHRoZSB7QGxpbmsgVmFsaWRhdGlvbktleXN9XG4gICAgICogQHJldHVybiB7VmFsaWRhdG9yIHwgdW5kZWZpbmVkfSB0aGUgcmVnaXN0ZXJlZCBWYWxpZGF0b3Igb3IgdW5kZWZpbmVkIGlmIHRoZXJlIGlzIG5vbm8gbWF0Y2hpbmcgdGhlIHByb3ZpZGVkIGtleVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQ8VCBleHRlbmRzIFZhbGlkYXRvcj4odmFsaWRhdG9yS2V5OiBzdHJpbmcpOiBUIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IFJlZ2lzdGVycyB0aGUgcHJvdmlkZWQgdmFsaWRhdG9ycyBvbnRvIHRoZSByZWdpc3RyeVxuICAgICAqXG4gICAgICogQHBhcmFtIHtUW10gfCBWYWxpZGF0b3JEZWZpbml0aW9uW119IHZhbGlkYXRvclxuICAgICAqL1xuICAgIHN0YXRpYyByZWdpc3RlcjxUIGV4dGVuZHMgVmFsaWRhdG9yPihcbiAgICAgIC4uLnZhbGlkYXRvcjogKFZhbGlkYXRvckRlZmluaXRpb24gfCBUKVtdXG4gICAgKTogdm9pZDtcbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBCdWlsZHMgdGhlIGtleSB0byBzdG9yZSBhcyBNZXRhZGF0YSB1bmRlciBSZWZsZWN0aW9uc1xuICAgICAqIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZXMge0BsaW5rIFZhbGlkYXRpb25LZXlzI1JFRkxFQ1R9IHdpdGggdGhlIHByb3ZpZGVkIGtleVxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICAgICAqL1xuICAgIHN0YXRpYyBrZXkoa2V5OiBzdHJpbmcpOiBzdHJpbmc7XG5cbiAgICBzdGF0aWMgdXBkYXRlS2V5KGtleTogc3RyaW5nKTogc3RyaW5nO1xuICB9XG59XG4iLCJpbXBvcnQgeyBwcm9wTWV0YWRhdGEsIHJlcXVpcmVkIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgYXBwbHkgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IHJlYWRvbmx5IH0gZnJvbSBcIi4uL3ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IERCS2V5cyB9IGZyb20gXCIuLi9tb2RlbC9jb25zdGFudHNcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeVwiO1xuLy8gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuLy8gaW1wb3J0ICogYXMgVmFsaWRhdGlvbiBmcm9tIFwiLi4vdmFsaWRhdGlvbi92YWxpZGF0aW9uXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBpZCgpIHtcbiAgcmV0dXJuIGFwcGx5KFxuICAgIHJlcXVpcmVkKCksXG4gICAgcmVhZG9ubHkoKSxcbiAgICBwcm9wTWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLklEKSwge30pXG4gICk7XG59XG4iLCJpbXBvcnQge1xuICBNb2RlbCxcbiAgTW9kZWxFcnJvckRlZmluaXRpb24sXG4gIE1vZGVsRXJyb3JzLFxuICBNb2RlbEtleXMsXG4gIFJlc2VydmVkTW9kZWxzLFxuICBzZixcbiAgVmFsaWRhdGFibGUsXG4gIFZhbGlkYXRpb24sXG4gIFZhbGlkYXRpb25LZXlzLFxuICBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBEZWNvcmF0b3JNZXRhZGF0YSwgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgVXBkYXRlVmFsaWRhdGlvbktleXMsIFVwZGF0ZVZhbGlkYXRvciB9IGZyb20gXCIuLi92YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBmaW5kTW9kZWxJZCB9IGZyb20gXCIuLi9pZGVudGl0eVwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGUgdXBkYXRlIG9mIGEgbW9kZWxcbiAqXG4gKiBAcGFyYW0ge1R9IG9sZE1vZGVsXG4gKiBAcGFyYW0ge1R9IG5ld01vZGVsXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbZXhjZXB0aW9uc11cbiAqXG4gKiBAZnVuY3Rpb24gdmFsaWRhdGVDb21wYXJlXG4gKiBAcmV0dXJuIHtNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZH1cbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuTW9kZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ29tcGFyZTxUIGV4dGVuZHMgTW9kZWw+KFxuICBvbGRNb2RlbDogVCxcbiAgbmV3TW9kZWw6IFQsXG4gIC4uLmV4Y2VwdGlvbnM6IHN0cmluZ1tdXG4pOiBNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGRlY29yYXRlZFByb3BlcnRpZXM6IFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb25bXSA9IFtdO1xuICBmb3IgKGNvbnN0IHByb3AgaW4gbmV3TW9kZWwpXG4gICAgaWYgKFxuICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG5ld01vZGVsLCBwcm9wKSAmJlxuICAgICAgZXhjZXB0aW9ucy5pbmRleE9mKHByb3ApID09PSAtMVxuICAgIClcbiAgICAgIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChcbiAgICAgICAgUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgVXBkYXRlVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgICAgICBuZXdNb2RlbCxcbiAgICAgICAgICBwcm9wXG4gICAgICAgICkgYXMgVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvblxuICAgICAgKTtcblxuICBsZXQgcmVzdWx0OiBNb2RlbEVycm9ycyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBmb3IgKGNvbnN0IGRlY29yYXRlZFByb3BlcnR5IG9mIGRlY29yYXRlZFByb3BlcnRpZXMpIHtcbiAgICBjb25zdCB7IHByb3AsIGRlY29yYXRvcnMgfSA9IGRlY29yYXRlZFByb3BlcnR5O1xuXG4gICAgZGVjb3JhdG9ycy5zaGlmdCgpOyAvLyByZW1vdmUgdGhlIGRlc2lnbjp0eXBlIGRlY29yYXRvciwgc2luY2UgdGhlIHR5cGUgd2lsbCBhbHJlYWR5IGJlIGNoZWNrZWRcblxuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuICAgIGxldCBlcnJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgZGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdG9yOiBVcGRhdGVWYWxpZGF0b3IgPSBWYWxpZGF0aW9uLmdldChcbiAgICAgICAgZGVjb3JhdG9yLmtleVxuICAgICAgKSBhcyBVcGRhdGVWYWxpZGF0b3I7XG4gICAgICBpZiAoIXZhbGlkYXRvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgIGBDb3VsZCBub3QgZmluZCBNYXRjaGluZyB2YWxpZGF0b3IgZm9yICR7ZGVjb3JhdG9yLmtleX0gZm9yIHByb3BlcnR5ICR7U3RyaW5nKGRlY29yYXRlZFByb3BlcnR5LnByb3ApfWBcbiAgICAgICAgKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdmFsaWRhdG9yLnVwZGF0ZUhhc0Vycm9ycyhcbiAgICAgICAgKG5ld01vZGVsIGFzIGFueSlbcHJvcC50b1N0cmluZygpXSxcbiAgICAgICAgKG9sZE1vZGVsIGFzIGFueSlbcHJvcC50b1N0cmluZygpXSxcbiAgICAgICAgLi4uT2JqZWN0LnZhbHVlcyhkZWNvcmF0b3IucHJvcHMpXG4gICAgICApO1xuXG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGVycnMgPSBlcnJzIHx8IHt9O1xuICAgICAgICBlcnJzW2RlY29yYXRvci5rZXldID0gZXJyO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlcnJzKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQgfHwge307XG4gICAgICByZXN1bHRbZGVjb3JhdGVkUHJvcGVydHkucHJvcC50b1N0cmluZygpXSA9IGVycnM7XG4gICAgfVxuICB9XG4gIC8vIHRlc3RzIG5lc3RlZCBjbGFzc2VzXG4gIGZvciAoY29uc3QgcHJvcCBvZiBPYmplY3Qua2V5cyhuZXdNb2RlbCkuZmlsdGVyKChrKSA9PiB7XG4gICAgaWYgKGV4Y2VwdGlvbnMuaW5jbHVkZXMoaykpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gIXJlc3VsdCB8fCAhcmVzdWx0W2tdO1xuICB9KSkge1xuICAgIGxldCBlcnI6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAvLyBpZiBhIG5lc3RlZCBNb2RlbFxuICAgIGNvbnN0IGFsbERlY29yYXRvcnMgPSBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICBuZXdNb2RlbCxcbiAgICAgIHByb3BcbiAgICApLmRlY29yYXRvcnM7XG4gICAgY29uc3QgZGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgIG5ld01vZGVsLFxuICAgICAgcHJvcFxuICAgICkuZGVjb3JhdG9ycy5maWx0ZXIoXG4gICAgICAoZCkgPT4gW01vZGVsS2V5cy5UWVBFLCBWYWxpZGF0aW9uS2V5cy5UWVBFXS5pbmRleE9mKGQua2V5IGFzIGFueSkgIT09IC0xXG4gICAgKTtcbiAgICBpZiAoIWRlY29yYXRvcnMgfHwgIWRlY29yYXRvcnMubGVuZ3RoKSBjb250aW51ZTtcbiAgICBjb25zdCBkZWMgPSBkZWNvcmF0b3JzLnBvcCgpIGFzIERlY29yYXRvck1ldGFkYXRhO1xuICAgIGNvbnN0IGNsYXp6ID0gZGVjLnByb3BzLm5hbWVcbiAgICAgID8gW2RlYy5wcm9wcy5uYW1lXVxuICAgICAgOiBBcnJheS5pc0FycmF5KGRlYy5wcm9wcy5jdXN0b21UeXBlcylcbiAgICAgICAgPyBkZWMucHJvcHMuY3VzdG9tVHlwZXNcbiAgICAgICAgOiBbZGVjLnByb3BzLmN1c3RvbVR5cGVzXTtcbiAgICBjb25zdCByZXNlcnZlZCA9IE9iamVjdC52YWx1ZXMoUmVzZXJ2ZWRNb2RlbHMpLm1hcCgodikgPT5cbiAgICAgIHYudG9Mb3dlckNhc2UoKVxuICAgICkgYXMgc3RyaW5nW107XG5cbiAgICBmb3IgKGNvbnN0IGMgb2YgY2xhenopIHtcbiAgICAgIGlmIChyZXNlcnZlZC5pbmRleE9mKGMudG9Mb3dlckNhc2UoKSkgPT09IC0xKSB7XG4gICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgIGNhc2UgQXJyYXkubmFtZTpcbiAgICAgICAgICBjYXNlIFNldC5uYW1lOlxuICAgICAgICAgICAgaWYgKGFsbERlY29yYXRvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGxpc3REZWMgPSBhbGxEZWNvcmF0b3JzLmZpbmQoXG4gICAgICAgICAgICAgICAgKGQpID0+IGQua2V5ID09PSBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmIChsaXN0RGVjKSB7XG4gICAgICAgICAgICAgICAgbGV0IGN1cnJlbnRMaXN0LCBvbGRMaXN0O1xuXG4gICAgICAgICAgICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIEFycmF5Lm5hbWU6XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRMaXN0ID0gKG5ld01vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdO1xuICAgICAgICAgICAgICAgICAgICBvbGRMaXN0ID0gKG9sZE1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgU2V0Lm5hbWU6XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRMaXN0ID0gKG5ld01vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW1xuICAgICAgICAgICAgICAgICAgICAgIHByb3BcbiAgICAgICAgICAgICAgICAgICAgXS52YWx1ZXMoKTtcbiAgICAgICAgICAgICAgICAgICAgb2xkTGlzdCA9IChvbGRNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXS52YWx1ZXMoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXR0cmlidXRlIHR5cGUgJHtjfWApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGVyciA9IGN1cnJlbnRMaXN0XG4gICAgICAgICAgICAgICAgICAubWFwKCh2OiBWYWxpZGF0YWJsZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IGZpbmRNb2RlbElkKHYgYXMgYW55LCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpZCkgcmV0dXJuIFwiRmFpbGVkIHRvIGZpbmQgbW9kZWwgaWRcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkTW9kZWwgPSBvbGRMaXN0LmZpbmQoXG4gICAgICAgICAgICAgICAgICAgICAgKGVsOiBhbnkpID0+IGlkID09PSBmaW5kTW9kZWxJZChlbCwgdHJ1ZSlcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoIW9sZE1vZGVsKSByZXR1cm47IC8vIG5vdGhpbmcgdG8gY29tcGFyZSB3aXRoXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2Lmhhc0Vycm9ycyhvbGRNb2RlbCk7XG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgLmZpbHRlcigoZTogYW55KSA9PiAhIWUpIGFzIGFueTtcblxuICAgICAgICAgICAgICAgIGlmICghZXJyPy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSByZXN1bHQgaXMgYW4gZW1wdHkgbGlzdC4uLlxuICAgICAgICAgICAgICAgICAgZXJyID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAobmV3TW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gJiZcbiAgICAgICAgICAgICAgICAob2xkTW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF1cbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGVyciA9IChuZXdNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXS5oYXNFcnJvcnMoXG4gICAgICAgICAgICAgICAgICAob2xkTW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKHNmKFwiTW9kZWwgc2hvdWxkIGJlIHZhbGlkYXRhYmxlIGJ1dCBpdHMgbm90XCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQgfHwge307XG4gICAgICAgIHJlc3VsdFtwcm9wXSA9IGVyciBhcyBhbnk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQgPyBuZXcgTW9kZWxFcnJvckRlZmluaXRpb24ocmVzdWx0KSA6IHVuZGVmaW5lZDtcbn1cbiIsImltcG9ydCB7IERCS2V5cywgRGVmYXVsdFNlcGFyYXRvciB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgYXBwbHkgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7XG4gIEhhc2hpbmcsXG4gIE1vZGVsLFxuICBwcm9wTWV0YWRhdGEsXG4gIHNmLFxuICB0eXBlLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBvbkNyZWF0ZSwgb25DcmVhdGVVcGRhdGUsIG9uVXBkYXRlIH0gZnJvbSBcIi4uL29wZXJhdGlvbnMvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgSVJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9JUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgSW50ZXJuYWxFcnJvciB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L2Vycm9yc1wiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L1JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9Db250ZXh0XCI7XG5pbXBvcnQgeyBDcnVkT3BlcmF0aW9ucywgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCIuLi9vcGVyYXRpb25zXCI7XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7c3RyfSBzdHJcbiAqIEBtZW1iZXJPZiBkYi1kZWNvcmF0b3JzLm1vZGVsXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc2hPbkNyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TT4sXG4gIFkgPSBhbnksXG4+KHRoaXM6IFIsIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogTSwgb2xkTW9kZWw/OiBNKTogdm9pZCB7XG4gIGlmICghKG1vZGVsIGFzIGFueSlba2V5XSkgcmV0dXJuO1xuICBjb25zdCBoYXNoID0gSGFzaGluZy5oYXNoKChtb2RlbCBhcyBhbnkpW2tleV0pO1xuICBpZiAob2xkTW9kZWwgJiYgKG1vZGVsIGFzIGFueSlba2V5XSA9PT0gaGFzaCkgcmV0dXJuO1xuICAobW9kZWwgYXMgYW55KVtrZXldID0gaGFzaDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc2goKSB7XG4gIHJldHVybiBhcHBseShcbiAgICBvbkNyZWF0ZVVwZGF0ZShoYXNoT25DcmVhdGVVcGRhdGUpLFxuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShEQktleXMuSEFTSCksIHt9KVxuICApO1xufVxuXG5leHBvcnQgdHlwZSBDb21wb3NlZEZyb21NZXRhZGF0YSA9IHtcbiAgYXJnczogc3RyaW5nW107XG4gIHNlcGFyYXRvcjogc3RyaW5nO1xuICBoYXNoUmVzdWx0OiBib29sZWFuO1xuICB0eXBlOiBcImtleXNcIiB8IFwidmFsdWVzXCI7XG4gIHByZWZpeD86IHN0cmluZztcbiAgc3VmZml4Pzogc3RyaW5nO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvc2VkRnJvbUNyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBWIGV4dGVuZHMgSVJlcG9zaXRvcnk8TT4sXG4+KFxuICB0aGlzOiBWLFxuICBjb250ZXh0OiBDb250ZXh0PE0+LFxuICBkYXRhOiBDb21wb3NlZEZyb21NZXRhZGF0YSxcbiAga2V5OiBzdHJpbmcsXG4gIG1vZGVsOiBNXG4pIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7IGFyZ3MsIHR5cGUsIHByZWZpeCwgc3VmZml4LCBzZXBhcmF0b3IgfSA9IGRhdGE7XG4gICAgY29uc3QgY29tcG9zZWQgPSBhcmdzLm1hcCgoYXJnOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmICghKGFyZyBpbiBtb2RlbCkpXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgIHNmKFwiUHJvcGVydHkgezB9IG5vdCBmb3VuZCB0byBjb21wb3NlIGZyb21cIiwgYXJnKVxuICAgICAgICApO1xuICAgICAgaWYgKHR5cGUgPT09IFwia2V5c1wiKSByZXR1cm4gYXJnO1xuICAgICAgaWYgKHR5cGVvZiAobW9kZWwgYXMgYW55KVthcmddID09PSBcInVuZGVmaW5lZFwiKVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICBzZihcIlByb3BlcnR5IHswfSBkb2VzIG5vdCBjb250YWluIGEgdmFsdWUgdG8gY29tcG9zZSBmcm9tXCIsIGFyZylcbiAgICAgICAgKTtcbiAgICAgIHJldHVybiAoKG1vZGVsIGFzIGFueSlbYXJnXSBhcyBhbnkpLnRvU3RyaW5nKCk7XG4gICAgfSk7XG5cbiAgICBpZiAocHJlZml4KSBjb21wb3NlZC51bnNoaWZ0KHByZWZpeCk7XG4gICAgaWYgKHN1ZmZpeCkgY29tcG9zZWQucHVzaChzdWZmaXgpO1xuXG4gICAgKG1vZGVsIGFzIGFueSlba2V5XSA9IGNvbXBvc2VkLmpvaW4oc2VwYXJhdG9yKTtcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYEZhaWxlZCB0byBjb21wb3NlIHZhbHVlOiAke2V9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tcG9zZWRGcm9tKFxuICBhcmdzOiBzdHJpbmdbXSxcbiAgaGFzaFJlc3VsdDogYm9vbGVhbiA9IGZhbHNlLFxuICBzZXBhcmF0b3I6IHN0cmluZyA9IERlZmF1bHRTZXBhcmF0b3IsXG4gIHR5cGU6IFwia2V5c1wiIHwgXCJ2YWx1ZXNcIiA9IFwidmFsdWVzXCIsXG4gIHByZWZpeCA9IFwiXCIsXG4gIHN1ZmZpeCA9IFwiXCJcbikge1xuICBjb25zdCBkYXRhOiBDb21wb3NlZEZyb21NZXRhZGF0YSA9IHtcbiAgICBhcmdzOiBhcmdzLFxuICAgIGhhc2hSZXN1bHQ6IGhhc2hSZXN1bHQsXG4gICAgc2VwYXJhdG9yOiBzZXBhcmF0b3IsXG4gICAgdHlwZTogdHlwZSxcbiAgICBwcmVmaXg6IHByZWZpeCxcbiAgICBzdWZmaXg6IHN1ZmZpeCxcbiAgfTtcblxuICBjb25zdCBkZWNvcmF0b3JzID0gW1xuICAgIG9uQ3JlYXRlVXBkYXRlKGNvbXBvc2VkRnJvbUNyZWF0ZVVwZGF0ZSwgZGF0YSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KERCS2V5cy5DT01QT1NFRCksIGRhdGEpLFxuICBdO1xuICBpZiAoaGFzaFJlc3VsdCkgZGVjb3JhdG9ycy5wdXNoKGhhc2goKSk7XG4gIHJldHVybiBhcHBseSguLi5kZWNvcmF0b3JzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvc2VkRnJvbUtleXMoXG4gIGFyZ3M6IHN0cmluZ1tdLFxuICBzZXBhcmF0b3I6IHN0cmluZyA9IERlZmF1bHRTZXBhcmF0b3IsXG4gIGhhc2g6IGJvb2xlYW4gPSBmYWxzZSxcbiAgcHJlZml4ID0gXCJcIixcbiAgc3VmZml4ID0gXCJcIlxuKSB7XG4gIHJldHVybiBjb21wb3NlZEZyb20oYXJncywgaGFzaCwgc2VwYXJhdG9yLCBcImtleXNcIiwgcHJlZml4LCBzdWZmaXgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tcG9zZWQoXG4gIGFyZ3M6IHN0cmluZ1tdLFxuICBzZXBhcmF0b3I6IHN0cmluZyA9IERlZmF1bHRTZXBhcmF0b3IsXG4gIGhhc2g6IGJvb2xlYW4gPSBmYWxzZSxcbiAgcHJlZml4ID0gXCJcIixcbiAgc3VmZml4ID0gXCJcIlxuKSB7XG4gIHJldHVybiBjb21wb3NlZEZyb20oYXJncywgaGFzaCwgc2VwYXJhdG9yLCBcInZhbHVlc1wiLCBwcmVmaXgsIHN1ZmZpeCk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IHVwZGF0ZXMgdGhlIHZlcnNpb24gb2YgYSBtb2RlbCBkdXJpbmcgY3JlYXRlIG9yIHVwZGF0ZSBvcGVyYXRpb25zLlxuICpcbiAqIEBwYXJhbSB7Q3J1ZE9wZXJhdGlvbnN9IG9wZXJhdGlvbiAtIFRoZSB0eXBlIG9mIG9wZXJhdGlvbiBiZWluZyBwZXJmb3JtZWQgKENSRUFURSBvciBVUERBVEUpLlxuICogQHJldHVybnMge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRoYXQgdXBkYXRlcyB0aGUgdmVyc2lvbiBvZiB0aGUgbW9kZWwgYmFzZWQgb24gdGhlIG9wZXJhdGlvbiB0eXBlLlxuICpcbiAqIEB0ZW1wbGF0ZSBNIC0gVHlwZSBleHRlbmRpbmcgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBleHRlbmRpbmcgSVJlcG9zaXRvcnk8TT5cbiAqXG4gKiBAdGhpcyB7Vn0gLSBUaGUgcmVwb3NpdG9yeSBpbnN0YW5jZVxuICogQHBhcmFtIHtDb250ZXh0PE0+fSBjb250ZXh0IC0gVGhlIGNvbnRleHQgb2YgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHt1bmtub3dufSBkYXRhIC0gQWRkaXRpb25hbCBkYXRhIGZvciB0aGUgb3BlcmF0aW9uIChub3QgdXNlZCBpbiB0aGlzIGZ1bmN0aW9uKVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBrZXkgb2YgdGhlIHZlcnNpb24gcHJvcGVydHkgaW4gdGhlIG1vZGVsXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGJlaW5nIHVwZGF0ZWRcbiAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IElmIGFuIGludmFsaWQgb3BlcmF0aW9uIGlzIHByb3ZpZGVkIG9yIGlmIHZlcnNpb24gdXBkYXRlIGZhaWxzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJzaW9uQ3JlYXRlVXBkYXRlKG9wZXJhdGlvbjogQ3J1ZE9wZXJhdGlvbnMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHZlcnNpb25DcmVhdGVVcGRhdGU8XG4gICAgTSBleHRlbmRzIE1vZGVsLFxuICAgIFYgZXh0ZW5kcyBJUmVwb3NpdG9yeTxNPixcbiAgPih0aGlzOiBWLCBjb250ZXh0OiBDb250ZXh0PE0+LCBkYXRhOiB1bmtub3duLCBrZXk6IHN0cmluZywgbW9kZWw6IE0pIHtcbiAgICB0cnkge1xuICAgICAgc3dpdGNoIChvcGVyYXRpb24pIHtcbiAgICAgICAgY2FzZSBPcGVyYXRpb25LZXlzLkNSRUFURTpcbiAgICAgICAgICAobW9kZWwgYXMgYW55KVtrZXldID0gMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBPcGVyYXRpb25LZXlzLlVQREFURTpcbiAgICAgICAgICAobW9kZWwgYXMgYW55KVtrZXldKys7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYEludmFsaWQgb3BlcmF0aW9uOiAke29wZXJhdGlvbn1gKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgRmFpbGVkIHRvIHVwZGF0ZSB2ZXJzaW9uOiAke2V9YCk7XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZGVjb3JhdG9yIGZvciB2ZXJzaW9uaW5nIGEgcHJvcGVydHkgaW4gYSBtb2RlbC5cbiAqIEBzdW1tYXJ5IFRoaXMgZGVjb3JhdG9yIGFwcGxpZXMgbXVsdGlwbGUgc3ViLWRlY29yYXRvcnMgdG8gaGFuZGxlIHZlcnNpb24gbWFuYWdlbWVudCBkdXJpbmcgY3JlYXRlIGFuZCB1cGRhdGUgb3BlcmF0aW9ucy5cbiAqXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IEEgY29tcG9zaXRlIGRlY29yYXRvciB0aGF0OlxuICogICAtIFNldHMgdGhlIHR5cGUgb2YgdGhlIHByb3BlcnR5IHRvIE51bWJlclxuICogICAtIEFwcGxpZXMgYSB2ZXJzaW9uIHVwZGF0ZSBvbiBjcmVhdGUgb3BlcmF0aW9uc1xuICogICAtIEFwcGxpZXMgYSB2ZXJzaW9uIHVwZGF0ZSBvbiB1cGRhdGUgb3BlcmF0aW9uc1xuICogICAtIEFkZHMgbWV0YWRhdGEgaW5kaWNhdGluZyB0aGlzIHByb3BlcnR5IGlzIHVzZWQgZm9yIHZlcnNpb25pbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcnNpb24oKSB7XG4gIHJldHVybiBhcHBseShcbiAgICB0eXBlKE51bWJlci5uYW1lKSxcbiAgICBvbkNyZWF0ZSh2ZXJzaW9uQ3JlYXRlVXBkYXRlKE9wZXJhdGlvbktleXMuQ1JFQVRFKSksXG4gICAgb25VcGRhdGUodmVyc2lvbkNyZWF0ZVVwZGF0ZShPcGVyYXRpb25LZXlzLlVQREFURSkpLFxuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShEQktleXMuVkVSU0lPTiksIHRydWUpXG4gICk7XG59XG4iLCJpbXBvcnQge1xuICBDb21wYXJhYmxlLFxuICBIYXNoYWJsZSxcbiAgTW9kZWxBcmcsXG4gIE1vZGVsRXJyb3JEZWZpbml0aW9uLFxuICBTZXJpYWxpemFibGUsXG4gIFZhbGlkYXRhYmxlLFxuICBNb2RlbCxcbiAgdmFsaWRhdGUsXG4gIENvbnN0cnVjdG9yLFxuICBNb2RlbEJ1aWxkZXJGdW5jdGlvbixcbiAgQnVpbGRlclJlZ2lzdHJ5LFxuICBNb2RlbENvbnN0cnVjdG9yLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUNvbXBhcmUgfSBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5cbk1vZGVsLnByb3RvdHlwZS5oYXNFcnJvcnMgPSBmdW5jdGlvbiA8TSBleHRlbmRzIE1vZGVsPihcbiAgdGhpczogTSxcbiAgcHJldmlvdXNWZXJzaW9uPzogTSB8IGFueSxcbiAgLi4uZXhjbHVzaW9uczogYW55W11cbik6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHByZXZpb3VzVmVyc2lvbiAmJiAhKHByZXZpb3VzVmVyc2lvbiBpbnN0YW5jZW9mIE1vZGVsKSkge1xuICAgIGV4Y2x1c2lvbnMudW5zaGlmdChwcmV2aW91c1ZlcnNpb24pO1xuICAgIHByZXZpb3VzVmVyc2lvbiA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGVycnMgPSB2YWxpZGF0ZSh0aGlzLCAuLi5leGNsdXNpb25zKTtcbiAgaWYgKGVycnMgfHwgIXByZXZpb3VzVmVyc2lvbikgcmV0dXJuIGVycnM7XG5cbiAgcmV0dXJuIHZhbGlkYXRlQ29tcGFyZShwcmV2aW91c1ZlcnNpb24sIHRoaXMsIC4uLmV4Y2x1c2lvbnMpO1xufTtcblxuZGVjbGFyZSBtb2R1bGUgXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnRcbiAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICBkZWNsYXJlIGFic3RyYWN0IGNsYXNzIE1vZGVsXG4gICAgaW1wbGVtZW50cyBWYWxpZGF0YWJsZSwgU2VyaWFsaXphYmxlLCBIYXNoYWJsZSwgQ29tcGFyYWJsZTxNb2RlbD5cbiAge1xuICAgIHByb3RlY3RlZCBjb25zdHJ1Y3Rvcihhcmc/OiBNb2RlbEFyZzxNb2RlbD4pO1xuXG4gICAgaGFzRXJyb3JzKC4uLmV4Y2x1c2lvbnM6IGFueVtdKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQ7XG4gICAgaGFzRXJyb3JzKFxuICAgICAgcHJldmlvdXNWZXJzaW9uPzogTW9kZWwgfCBhbnksXG4gICAgICAuLi5leGNsdXNpb25zOiBhbnlbXVxuICAgICk6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQ29tcGFyZSBvYmplY3QgZXF1YWxpdHkgcmVjdXJzaXZlbHlcbiAgICAgKiBAcGFyYW0ge2FueX0gb2JqIG9iamVjdCB0byBjb21wYXJlIHRvXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtleGNlcHRpb25zXSBwcm9wZXJ0eSBuYW1lcyB0byBiZSBleGNsdWRlZCBmcm9tIHRoZSBjb21wYXJpc29uXG4gICAgICovXG4gICAgZXF1YWxzKG9iajogYW55LCAuLi5leGNlcHRpb25zOiBzdHJpbmdbXSk6IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgc2VyaWFsaXplZCBtb2RlbCBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnRseSBkZWZpbmVkIHtAbGluayBTZXJpYWxpemVyfVxuICAgICAqL1xuICAgIHNlcmlhbGl6ZSgpOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgT3ZlcnJpZGUgdGhlIGltcGxlbWVudGF0aW9uIGZvciBqcydzICd0b1N0cmluZygpJyB3aGljaCBzdWNrcy4uLlxuICAgICAqIEBvdmVycmlkZVxuICAgICAqL1xuICAgIHRvU3RyaW5nKCk6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBEZWZpbmVzIGEgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3Igb2JqZWN0IGhhc2guIFJlbGllcyBvbiBhIHZlcnkgYmFzaWMgaW1wbGVtZW50YXRpb24gYmFzZWQgb24gSmF2YSdzIHN0cmluZyBoYXNoO1xuICAgICAqL1xuICAgIGhhc2goKTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IERlc2VyaWFsaXplcyBhIE1vZGVsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICAgICAqXG4gICAgICogQHBhcmFtIGFyZ3NcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgaXQgZmFpbHMgdG8gcGFyc2UgdGhlIHN0cmluZywgb3IgaWYgaXQgZmFpbHMgdG8gYnVpbGQgdGhlIG1vZGVsXG4gICAgICovXG4gICAgc3RhdGljIGRlc2VyaWFsaXplKHN0cjogc3RyaW5nKTogYW55O1xuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IFJlcG9wdWxhdGVzIHRoZSBPYmplY3QgcHJvcGVydGllcyB3aXRoIHRoZSBvbmVzIGZyb20gdGhlIG5ldyBvYmplY3RcbiAgICAgKiBAZGVzY3JpcHRpb24gSXRlcmF0ZXMgYWxsIGNvbW1vbiBwcm9wZXJ0aWVzIG9mIG9iaiAoaWYgZXhpc3RpbmcpIGFuZCBzZWxmLCBhbmQgY29waWVzIHRoZW0gb250byBzZWxmXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1R9IHNlbGZcbiAgICAgKiBAcGFyYW0ge1QgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbb2JqXVxuICAgICAqXG4gICAgICovXG4gICAgc3RhdGljIGZyb21PYmplY3Q8VCBleHRlbmRzIE1vZGVsPihcbiAgICAgIHNlbGY6IFQsXG4gICAgICBvYmo/OiBUIHwgUmVjb3JkPHN0cmluZywgYW55PlxuICAgICk6IFQ7XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgUmVwb3B1bGF0ZXMgdGhlIGluc3RhbmNlIHdpdGggdGhlIG9uZXMgZnJvbSB0aGUgbmV3IE1vZGVsIE9iamVjdFxuICAgICAqIEBkZXNjcmlwdGlvbiBJdGVyYXRlcyBhbGwgY29tbW9uIHByb3BlcnRpZXMgb2Ygb2JqIChpZiBleGlzdGluZykgYW5kIHNlbGYsIGFuZCBjb3BpZXMgdGhlbSBvbnRvIHNlbGYuXG4gICAgICogSXMgYXdhcmUgb2YgbmVzdGVkIE1vZGVsIE9iamVjdHMgYW5kIHJlYnVpbGRzIHRoZW0gYWxzby5cbiAgICAgKiBXaGVuIExpc3QgcHJvcGVydGllcyBhcmUgZGVjb3JhdGVkIHdpdGgge0BsaW5rIGxpc3R9LCB0aGV5IGxpc3QgaXRlbXMgd2lsbCBhbHNvIGJlIHJlYnVpbHRcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7VH0gc2VsZlxuICAgICAqIEBwYXJhbSB7VCB8IFJlY29yZDxzdHJpbmcsIGFueT59IFtvYmpdXG4gICAgICpcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbU1vZGVsPFQgZXh0ZW5kcyBNb2RlbD4oXG4gICAgICBzZWxmOiBULFxuICAgICAgb2JqPzogVCB8IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICApOiBUO1xuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IFNldHMgdGhlIEdsb2JhbCB7QGxpbmsgTW9kZWxCdWlsZGVyRnVuY3Rpb259XG4gICAgICogQHBhcmFtIHtNb2RlbEJ1aWxkZXJGdW5jdGlvbn0gW2J1aWxkZXJdXG4gICAgICovXG4gICAgc3RhdGljIHNldEJ1aWxkZXIoYnVpbGRlcj86IE1vZGVsQnVpbGRlckZ1bmN0aW9uKTogdm9pZDtcbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIGN1cnJlbnQgZ2xvYmFsIHtAbGluayBNb2RlbEJ1aWxkZXJGdW5jdGlvbn1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0QnVpbGRlcigpOiBNb2RlbEJ1aWxkZXJGdW5jdGlvbiB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHtAbGluayBNb2RlbFJlZ2lzdHJ5TWFuYWdlcn1cbiAgICAgKlxuICAgICAqIEByZXR1cm4gTW9kZWxSZWdpc3RyeSwgZGVmYXVsdHMgdG8ge0BsaW5rIE1vZGVsUmVnaXN0cnlNYW5hZ2VyfVxuICAgICAqL1xuICAgIHByaXZhdGUgc3RhdGljIGdldFJlZ2lzdHJ5O1xuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgYWN0aW5nTW9kZWxSZWdpc3RyeVxuICAgICAqXG4gICAgICogQHBhcmFtIHtCdWlsZGVyUmVnaXN0cnl9IG1vZGVsUmVnaXN0cnkgdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiBvZiBSZWdpc3RyeVxuICAgICAqL1xuICAgIHN0YXRpYyBzZXRSZWdpc3RyeShtb2RlbFJlZ2lzdHJ5OiBCdWlsZGVyUmVnaXN0cnk8YW55Pik6IHZvaWQ7XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgcmVnaXN0ZXIgbmV3IE1vZGVsc1xuICAgICAqIEBwYXJhbSB7YW55fSBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZV0gd2hlbiBub3QgZGVmaW5lZCwgdGhlIG5hbWUgb2YgdGhlIGNvbnN0cnVjdG9yIHdpbGwgYmUgdXNlZFxuICAgICAqXG4gICAgICogQHNlZSBNb2RlbFJlZ2lzdHJ5XG4gICAgICovXG4gICAgc3RhdGljIHJlZ2lzdGVyPFQgZXh0ZW5kcyBNb2RlbD4oXG4gICAgICBjb25zdHJ1Y3RvcjogTW9kZWxDb25zdHJ1Y3RvcjxUPixcbiAgICAgIG5hbWU/OiBzdHJpbmdcbiAgICApOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IEdldHMgYSByZWdpc3RlcmVkIE1vZGVsIHtAbGluayBNb2RlbENvbnN0cnVjdG9yfVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICpcbiAgICAgKiBAc2VlIE1vZGVsUmVnaXN0cnlcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0PFQgZXh0ZW5kcyBNb2RlbD4obmFtZTogc3RyaW5nKTogTW9kZWxDb25zdHJ1Y3RvcjxUPiB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG9ialxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2xhenpdIHdoZW4gcHJvdmlkZWQsIGl0IHdpbGwgYXR0ZW1wdCB0byBmaW5kIHRoZSBtYXRjaGluZyBjb25zdHJ1Y3RvclxuICAgICAqXG4gICAgICogQHRocm93cyBFcnJvciBJZiBjbGF6eiBpcyBub3QgZm91bmQsIG9yIG9iaiBpcyBub3QgYSB7QGxpbmsgTW9kZWx9IG1lYW5pbmcgaXQgaGFzIG5vIHtAbGluayBNb2RlbEtleXMuQU5DSE9SfSBwcm9wZXJ0eVxuICAgICAqXG4gICAgICogQHNlZSBNb2RlbFJlZ2lzdHJ5XG4gICAgICovXG4gICAgc3RhdGljIGJ1aWxkPFQgZXh0ZW5kcyBNb2RlbD4ob2JqPzogUmVjb3JkPHN0cmluZywgYW55PiwgY2xheno/OiBzdHJpbmcpOiBUO1xuICAgIHN0YXRpYyBnZXRNZXRhZGF0YTxWIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBWKTogYW55O1xuICAgIHN0YXRpYyBnZXRBdHRyaWJ1dGVzPFYgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IENvbnN0cnVjdG9yPFY+IHwgVik6IHN0cmluZ1tdO1xuICAgIHN0YXRpYyBlcXVhbHM8ViBleHRlbmRzIE1vZGVsPihcbiAgICAgIG9iajE6IFYsXG4gICAgICBvYmoyOiBWLFxuICAgICAgLi4uZXhjZXB0aW9uczogYW55W11cbiAgICApOiBib29sZWFuO1xuICAgIHN0YXRpYyBoYXNFcnJvcnM8ViBleHRlbmRzIE1vZGVsPihcbiAgICAgIG1vZGVsOiBWLFxuICAgICAgLi4uZXhjZXB0aW9uczogYW55W11cbiAgICApOiBNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZDtcbiAgICBzdGF0aWMgc2VyaWFsaXplPFYgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IFYpOiBhbnk7XG4gICAgc3RhdGljIGhhc2g8ViBleHRlbmRzIE1vZGVsPihtb2RlbDogVik6IGFueTtcbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBCdWlsZHMgdGhlIGtleSB0byBzdG9yZSBhcyBNZXRhZGF0YSB1bmRlciBSZWZsZWN0aW9uc1xuICAgICAqIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZXMge0BsaW5rIE1vZGVsS2V5cyNSRUZMRUNUfSB3aXRoIHRoZSBwcm92aWRlZCBrZXlcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gICAgICovXG4gICAgc3RhdGljIGtleShzdHI6IHN0cmluZyk6IHN0cmluZztcbiAgfVxufVxuIl0sIm5hbWVzIjpbIkRlY29yYXRvck1lc3NhZ2VzIl0sIm1hcHBpbmdzIjoiOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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