@ditojs/server 0.275.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/package.json +25 -43
  2. package/src/app/Application.js +105 -111
  3. package/src/app/Validator.js +6 -3
  4. package/src/app/index.js +2 -2
  5. package/src/cli/db/createMigration.js +1 -1
  6. package/src/cli/db/index.js +7 -7
  7. package/src/cli/db/listAssetConfig.js +1 -1
  8. package/src/cli/db/reset.js +1 -1
  9. package/src/cli/index.js +14 -5
  10. package/src/controllers/AdminController.js +181 -158
  11. package/src/controllers/CollectionController.js +8 -29
  12. package/src/controllers/Controller.js +71 -76
  13. package/src/controllers/ControllerAction.js +39 -17
  14. package/src/controllers/MemberAction.js +2 -2
  15. package/src/controllers/ModelController.js +4 -4
  16. package/src/controllers/RelationController.js +3 -3
  17. package/src/controllers/{UserController.js → UsersController.js} +8 -13
  18. package/src/controllers/index.js +5 -5
  19. package/src/decorators/action.js +3 -3
  20. package/src/decorators/authorize.js +1 -1
  21. package/src/decorators/index.js +6 -6
  22. package/src/decorators/parameters.js +1 -1
  23. package/src/decorators/returns.js +1 -1
  24. package/src/decorators/scope.js +1 -1
  25. package/src/decorators/transacted.js +1 -1
  26. package/src/errors/AssetError.js +1 -1
  27. package/src/errors/AuthenticationError.js +1 -1
  28. package/src/errors/AuthorizationError.js +1 -1
  29. package/src/errors/ControllerError.js +1 -1
  30. package/src/errors/DatabaseError.js +12 -3
  31. package/src/errors/GraphError.js +1 -1
  32. package/src/errors/ModelError.js +1 -1
  33. package/src/errors/NotFoundError.js +1 -1
  34. package/src/errors/NotImplementedError.js +1 -1
  35. package/src/errors/QueryBuilderError.js +1 -1
  36. package/src/errors/RelationError.js +1 -1
  37. package/src/errors/ValidationError.js +1 -1
  38. package/src/errors/WrappedError.js +1 -1
  39. package/src/errors/index.js +14 -14
  40. package/src/graph/DitoGraphProcessor.js +2 -1
  41. package/src/graph/graph.js +1 -1
  42. package/src/graph/index.js +3 -3
  43. package/src/index.js +11 -9
  44. package/src/lib/index.js +2 -2
  45. package/src/middleware/createTransaction.js +1 -1
  46. package/src/middleware/findRoute.js +3 -2
  47. package/src/middleware/handleConnectMiddleware.js +88 -0
  48. package/src/middleware/handleError.js +1 -1
  49. package/src/middleware/handleRoute.js +3 -3
  50. package/src/middleware/index.js +8 -7
  51. package/src/mixins/AssetMixin.js +1 -1
  52. package/src/mixins/UserMixin.js +1 -1
  53. package/src/mixins/index.js +4 -4
  54. package/src/models/AssetModel.js +2 -2
  55. package/src/models/Model.js +16 -12
  56. package/src/models/RelationAccessor.js +1 -1
  57. package/src/models/SessionModel.js +2 -2
  58. package/src/models/TimeStampedModel.js +2 -2
  59. package/src/models/UserModel.js +2 -2
  60. package/src/models/definitions/assets.js +1 -1
  61. package/src/models/definitions/filters.js +57 -44
  62. package/src/models/definitions/hooks.js +1 -1
  63. package/src/models/definitions/index.js +9 -9
  64. package/src/models/definitions/modifiers.js +1 -1
  65. package/src/models/definitions/options.js +1 -1
  66. package/src/models/definitions/properties.js +2 -2
  67. package/src/models/definitions/relations.js +1 -1
  68. package/src/models/definitions/schema.js +1 -1
  69. package/src/models/definitions/scopes.js +2 -2
  70. package/src/models/index.js +5 -5
  71. package/src/query/QueryBuilder.js +5 -5
  72. package/src/query/QueryFilters.js +50 -50
  73. package/src/query/QueryParameters.js +2 -2
  74. package/src/query/index.js +3 -3
  75. package/src/schema/formats/index.js +2 -2
  76. package/src/schema/index.js +4 -4
  77. package/src/schema/keywords/_relate.js +1 -1
  78. package/src/schema/keywords/index.js +12 -12
  79. package/src/schema/properties.test.js +1 -1
  80. package/src/schema/relations.js +1 -1
  81. package/src/schema/relations.test.js +2 -2
  82. package/src/services/index.js +1 -1
  83. package/src/storage/DiskStorage.js +1 -1
  84. package/src/storage/S3Storage.js +4 -4
  85. package/src/storage/Storage.js +1 -1
  86. package/src/storage/index.js +4 -4
  87. package/src/utils/function.test.js +1 -1
  88. package/src/utils/handler.js +17 -0
  89. package/src/utils/index.js +8 -7
  90. package/src/utils/object.test.js +1 -1
  91. package/lib/app/Application.js +0 -961
  92. package/lib/app/SessionStore.js +0 -40
  93. package/lib/app/Validator.js +0 -355
  94. package/lib/app/index.js +0 -26
  95. package/lib/cli/console.js +0 -175
  96. package/lib/cli/db/createMigration.js +0 -237
  97. package/lib/cli/db/index.js +0 -66
  98. package/lib/cli/db/listAssetConfig.js +0 -16
  99. package/lib/cli/db/migrate.js +0 -15
  100. package/lib/cli/db/reset.js +0 -27
  101. package/lib/cli/db/rollback.js +0 -15
  102. package/lib/cli/db/seed.js +0 -104
  103. package/lib/cli/db/unlock.js +0 -15
  104. package/lib/cli/index.js +0 -90
  105. package/lib/controllers/AdminController.js +0 -258
  106. package/lib/controllers/CollectionController.js +0 -263
  107. package/lib/controllers/Controller.js +0 -462
  108. package/lib/controllers/ControllerAction.js +0 -276
  109. package/lib/controllers/MemberAction.js +0 -22
  110. package/lib/controllers/ModelController.js +0 -64
  111. package/lib/controllers/RelationController.js +0 -82
  112. package/lib/controllers/UserController.js +0 -98
  113. package/lib/controllers/index.js +0 -50
  114. package/lib/decorators/action.js +0 -14
  115. package/lib/decorators/authorize.js +0 -13
  116. package/lib/decorators/index.js +0 -58
  117. package/lib/decorators/parameters.js +0 -35
  118. package/lib/decorators/returns.js +0 -26
  119. package/lib/decorators/scope.js +0 -14
  120. package/lib/decorators/transacted.js +0 -12
  121. package/lib/errors/AssetError.js +0 -19
  122. package/lib/errors/AuthenticationError.js +0 -19
  123. package/lib/errors/AuthorizationError.js +0 -19
  124. package/lib/errors/ControllerError.js +0 -24
  125. package/lib/errors/DatabaseError.js +0 -27
  126. package/lib/errors/GraphError.js +0 -19
  127. package/lib/errors/ModelError.js +0 -24
  128. package/lib/errors/NotFoundError.js +0 -19
  129. package/lib/errors/NotImplementedError.js +0 -19
  130. package/lib/errors/QueryBuilderError.js +0 -19
  131. package/lib/errors/RelationError.js +0 -36
  132. package/lib/errors/ResponseError.js +0 -46
  133. package/lib/errors/ValidationError.js +0 -19
  134. package/lib/errors/WrappedError.js +0 -24
  135. package/lib/errors/index.js +0 -122
  136. package/lib/graph/DitoGraphProcessor.js +0 -185
  137. package/lib/graph/expression.js +0 -76
  138. package/lib/graph/graph.js +0 -300
  139. package/lib/graph/index.js +0 -34
  140. package/lib/index.js +0 -82
  141. package/lib/lib/EventEmitter.js +0 -76
  142. package/lib/lib/KnexHelper.js +0 -40
  143. package/lib/lib/index.js +0 -26
  144. package/lib/middleware/attachLogger.js +0 -16
  145. package/lib/middleware/createTransaction.js +0 -36
  146. package/lib/middleware/findRoute.js +0 -35
  147. package/lib/middleware/handleError.js +0 -26
  148. package/lib/middleware/handleRoute.js +0 -29
  149. package/lib/middleware/handleUser.js +0 -36
  150. package/lib/middleware/index.js +0 -66
  151. package/lib/middleware/logRequests.js +0 -122
  152. package/lib/mixins/AssetMixin.js +0 -81
  153. package/lib/mixins/SessionMixin.js +0 -22
  154. package/lib/mixins/TimeStampedMixin.js +0 -47
  155. package/lib/mixins/UserMixin.js +0 -151
  156. package/lib/mixins/index.js +0 -42
  157. package/lib/models/AssetModel.js +0 -12
  158. package/lib/models/Model.js +0 -953
  159. package/lib/models/RelationAccessor.js +0 -41
  160. package/lib/models/SessionModel.js +0 -12
  161. package/lib/models/TimeStampedModel.js +0 -12
  162. package/lib/models/UserModel.js +0 -12
  163. package/lib/models/definitions/assets.js +0 -11
  164. package/lib/models/definitions/filters.js +0 -101
  165. package/lib/models/definitions/hooks.js +0 -11
  166. package/lib/models/definitions/index.js +0 -38
  167. package/lib/models/definitions/modifiers.js +0 -11
  168. package/lib/models/definitions/options.js +0 -11
  169. package/lib/models/definitions/properties.js +0 -87
  170. package/lib/models/definitions/relations.js +0 -11
  171. package/lib/models/definitions/schema.js +0 -11
  172. package/lib/models/definitions/scopes.js +0 -51
  173. package/lib/models/index.js +0 -50
  174. package/lib/query/QueryBuilder.js +0 -745
  175. package/lib/query/QueryFilters.js +0 -82
  176. package/lib/query/QueryParameters.js +0 -77
  177. package/lib/query/Registry.js +0 -40
  178. package/lib/query/index.js +0 -34
  179. package/lib/schema/formats/_empty.js +0 -10
  180. package/lib/schema/formats/_required.js +0 -10
  181. package/lib/schema/formats/index.js +0 -26
  182. package/lib/schema/index.js +0 -49
  183. package/lib/schema/keywords/_computed.js +0 -11
  184. package/lib/schema/keywords/_foreign.js +0 -11
  185. package/lib/schema/keywords/_hidden.js +0 -11
  186. package/lib/schema/keywords/_index.js +0 -11
  187. package/lib/schema/keywords/_instanceof.js +0 -49
  188. package/lib/schema/keywords/_primary.js +0 -11
  189. package/lib/schema/keywords/_range.js +0 -26
  190. package/lib/schema/keywords/_relate.js +0 -19
  191. package/lib/schema/keywords/_specificType.js +0 -11
  192. package/lib/schema/keywords/_unique.js +0 -11
  193. package/lib/schema/keywords/_unsigned.js +0 -11
  194. package/lib/schema/keywords/_validate.js +0 -80
  195. package/lib/schema/keywords/index.js +0 -106
  196. package/lib/schema/properties.js +0 -227
  197. package/lib/schema/properties.test.js +0 -573
  198. package/lib/schema/relations.js +0 -274
  199. package/lib/schema/relations.test.js +0 -155
  200. package/lib/services/Service.js +0 -34
  201. package/lib/services/index.js +0 -18
  202. package/lib/storage/AssetFile.js +0 -97
  203. package/lib/storage/DiskStorage.js +0 -125
  204. package/lib/storage/S3Storage.js +0 -171
  205. package/lib/storage/Storage.js +0 -209
  206. package/lib/storage/index.js +0 -34
  207. package/lib/utils/decorator.js +0 -16
  208. package/lib/utils/deprecate.js +0 -46
  209. package/lib/utils/emitter.js +0 -13
  210. package/lib/utils/function.js +0 -14
  211. package/lib/utils/function.test.js +0 -49
  212. package/lib/utils/index.js +0 -66
  213. package/lib/utils/json.js +0 -9
  214. package/lib/utils/object.js +0 -92
  215. package/lib/utils/object.test.js +0 -65
  216. package/lib/utils/scope.js +0 -14
@@ -1,953 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.Model = void 0;
5
-
6
- require("core-js/modules/esnext.async-iterator.for-each.js");
7
-
8
- require("core-js/modules/esnext.iterator.constructor.js");
9
-
10
- require("core-js/modules/esnext.iterator.for-each.js");
11
-
12
- require("core-js/modules/esnext.async-iterator.reduce.js");
13
-
14
- require("core-js/modules/esnext.iterator.reduce.js");
15
-
16
- require("core-js/modules/esnext.async-iterator.filter.js");
17
-
18
- require("core-js/modules/esnext.iterator.filter.js");
19
-
20
- require("core-js/modules/esnext.weak-map.delete-all.js");
21
-
22
- require("core-js/modules/esnext.weak-map.emplace.js");
23
-
24
- var _objection = _interopRequireDefault(require("objection"));
25
-
26
- var _query = require("../query");
27
-
28
- var _lib = require("../lib");
29
-
30
- var _schema = require("../schema");
31
-
32
- var _graph = require("../graph");
33
-
34
- var _utils = require("../utils");
35
-
36
- var _errors = require("../errors");
37
-
38
- var _utils2 = require("@ditojs/utils");
39
-
40
- var _RelationAccessor = _interopRequireDefault(require("./RelationAccessor"));
41
-
42
- var _definitions = _interopRequireDefault(require("./definitions"));
43
-
44
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
45
-
46
- class Model extends _objection.default.Model {
47
- constructor(json) {
48
- super();
49
-
50
- if (json) {
51
- this.$setJson(json);
52
- }
53
- }
54
-
55
- static setup(knex) {
56
- this.knex(knex);
57
-
58
- try {
59
- for (const relation of Object.values(this.getRelations())) {
60
- this.setupRelation(relation);
61
- }
62
- } catch (error) {
63
- throw error instanceof _errors.RelationError ? error : new _errors.RelationError(error);
64
- }
65
-
66
- this.referenceValidator = null;
67
- }
68
-
69
- static setupRelation(relation) {
70
- relation.relatedModelClass.getRelatedRelations().push(relation);
71
- const accessor = `$${relation.name}`;
72
-
73
- if (accessor in this.prototype) {
74
- throw new _errors.RelationError(`Model '${this.name}' already defines a property with name ` + `'${accessor}' that clashes with the relation accessor.`);
75
- }
76
-
77
- const defineAccessor = (target, isClass) => {
78
- Object.defineProperty(target, accessor, {
79
- get() {
80
- const value = new _RelationAccessor.default(relation, isClass ? this : null, isClass ? null : this);
81
- Object.defineProperty(this, accessor, {
82
- value,
83
- configurable: true,
84
- enumerable: false
85
- });
86
- return value;
87
- },
88
-
89
- configurable: true,
90
- enumerable: false
91
- });
92
- };
93
-
94
- defineAccessor(this, true);
95
- defineAccessor(this.prototype, false);
96
- }
97
-
98
- static initialize() {
99
- const {
100
- hooks,
101
- assets
102
- } = this.definition;
103
-
104
- this._setupEmitter(hooks);
105
-
106
- if (assets) {
107
- this._setupAssetsEvents(assets);
108
- }
109
- }
110
-
111
- $initialize() {}
112
-
113
- get $app() {
114
- return this.constructor.app;
115
- }
116
-
117
- $is(model) {
118
- return (model == null ? void 0 : model.constructor) === this.constructor && (model == null ? void 0 : model.id) === this.id;
119
- }
120
-
121
- $has(...properties) {
122
- for (const property of properties) {
123
- if (!(property in this)) return false;
124
- }
125
-
126
- return true;
127
- }
128
-
129
- $update(properties, trx) {
130
- return this.$query(trx).update(properties).runAfter((result, query) => query.has('update') ? this.$set(result) : result);
131
- }
132
-
133
- $patch(properties, trx) {
134
- return this.$query(trx).patch(properties).runAfter((result, query) => query.has('patch') ? this.$set(result) : result);
135
- }
136
-
137
- $transaction(trx, handler) {
138
- return this.constructor.transaction(trx, handler);
139
- }
140
-
141
- static transaction(trx, handler) {
142
- if (!handler) {
143
- handler = trx;
144
- trx = null;
145
- }
146
-
147
- if (handler) {
148
- return trx ? handler(trx) : this.knex().transaction(handler);
149
- } else {
150
- return super.transaction();
151
- }
152
- }
153
-
154
- $validate(json, options = {}) {
155
- if (options.skipValidation) {
156
- return json;
157
- }
158
-
159
- if (!options.graph && !options.async) {
160
- return super.$validate(json, options);
161
- }
162
-
163
- json = json || this;
164
- const inputJson = json;
165
- const shallow = json.$isObjectionModel && !options.graph;
166
-
167
- if (shallow) {
168
- json = json.clone({
169
- shallow: true
170
- });
171
- options = { ...options,
172
- mutable: true
173
- };
174
- }
175
-
176
- const validator = this.constructor.getValidator();
177
- const args = {
178
- options,
179
- model: this,
180
- json,
181
- ctx: Object.create(null)
182
- };
183
- validator.beforeValidate(args);
184
- const result = validator.validate(args);
185
-
186
- const handleResult = result => {
187
- validator.afterValidate(args);
188
- return shallow ? inputJson.$set(result) : result;
189
- };
190
-
191
- return (0, _utils2.isPromise)(result) ? result.then(handleResult) : handleResult(result);
192
- }
193
-
194
- async $validateGraph(options = {}) {
195
- await this.$validate(null, { ...options,
196
- graph: true,
197
- async: true
198
- });
199
- return this;
200
- }
201
-
202
- static fromJson(json, options = {}) {
203
- if (options.async && !options.skipValidation) {
204
- const model = new this();
205
- return model.$validate(json, options).then(json => model.$setJson(json, { ...options,
206
- skipValidation: true
207
- }));
208
- }
209
-
210
- return super.fromJson(json, options);
211
- }
212
-
213
- static query(trx) {
214
- return super.query(trx).onError(err => {
215
- err = err instanceof _errors.ResponseError ? err : err instanceof _objection.default.DBError ? this.app.createDatabaseError(err) : new _errors.WrappedError(err);
216
- return Promise.reject(err);
217
- });
218
- }
219
-
220
- static async count(...args) {
221
- const {
222
- count
223
- } = (await this.query().count(...args).first()) || {};
224
- return +count || 0;
225
- }
226
-
227
- static get tableName() {
228
- return this.name.match(/^(.*?)(?:Model|)$/)[1];
229
- }
230
-
231
- static get idColumn() {
232
- const {
233
- properties
234
- } = this;
235
- const ids = [];
236
-
237
- for (const [name, property] of Object.entries(properties || {})) {
238
- if (property != null && property.primary) {
239
- ids.push(name);
240
- }
241
- }
242
-
243
- const {
244
- length
245
- } = ids;
246
- return length > 1 ? ids : length > 0 ? ids[0] : super.idColumn;
247
- }
248
-
249
- static getReference(modelOrId, includeProperties) {
250
- const ref = new this();
251
- const idProperties = this.getIdPropertyArray();
252
-
253
- if ((0, _utils2.isObject)(modelOrId)) {
254
- const addProperty = key => {
255
- const value = modelOrId[key];
256
-
257
- if (value !== undefined) {
258
- ref[key] = value;
259
- }
260
- };
261
-
262
- addProperty(this.uidRefProp);
263
- idProperties.forEach(addProperty);
264
- includeProperties == null ? void 0 : includeProperties.forEach(addProperty);
265
- } else {
266
- const ids = (0, _utils2.asArray)(modelOrId);
267
-
268
- if (ids.length !== idProperties.length) {
269
- throw new _errors.ModelError(this, `Invalid amount of id values provided for reference: Unable to map ${(0, _utils.formatJson)(modelOrId, false)} to ${(0, _utils.formatJson)(idProperties, false)}.`);
270
- }
271
-
272
- idProperties.forEach((key, index) => {
273
- ref[key] = ids[index];
274
- });
275
- }
276
-
277
- return ref;
278
- }
279
-
280
- static isReference(obj) {
281
- let validator = this.referenceValidator;
282
-
283
- if (!validator) {
284
- validator = this.referenceValidator = this.app.compileValidator({
285
- oneOf: [{
286
- type: 'object',
287
- properties: this.getIdPropertyArray().reduce((idProperties, idProperty) => {
288
- idProperties[idProperty] = {
289
- type: this.definition.properties[idProperty].type
290
- };
291
- return idProperties;
292
- }, {}),
293
- additionalProperties: false
294
- }, {
295
- type: 'object',
296
- properties: {
297
- [this.uidRefProp]: {
298
- type: 'string'
299
- }
300
- },
301
- additionalProperties: false
302
- }]
303
- }, {
304
- throw: false
305
- });
306
- }
307
-
308
- return validator(obj);
309
- }
310
-
311
- static getScope(name) {
312
- return this.definition.scopes[name];
313
- }
314
-
315
- static hasScope(name) {
316
- return !!this.getScope(name);
317
- }
318
-
319
- static getModifiers() {
320
- return this.definition.modifiers;
321
- }
322
-
323
- static get relationMappings() {
324
- return this._getCached('relationMappings', () => (0, _schema.convertRelations)(this, this.definition.relations, this.app.models), {});
325
- }
326
-
327
- static get jsonSchema() {
328
- return this._getCached('jsonSchema', () => {
329
- const schema = (0, _schema.convertSchema)(this.definition.properties);
330
- (0, _schema.addRelationSchemas)(this, schema.properties);
331
- (0, _utils2.merge)(schema, this.definition.schema);
332
- return {
333
- $id: this.name,
334
- $schema: 'http://json-schema.org/draft-07/schema',
335
- ...schema
336
- };
337
- }, {});
338
- }
339
-
340
- static get virtualAttributes() {
341
- return this.computedAttributes;
342
- }
343
-
344
- static get jsonAttributes() {
345
- return this._getCached('jsonSchema:jsonAttributes', () => this.getAttributes(({
346
- type,
347
- specificType,
348
- computed
349
- }) => !computed && !specificType && (type === 'object' || type === 'array')), []);
350
- }
351
-
352
- static get booleanAttributes() {
353
- return this._getCached('jsonSchema:booleanAttributes', () => this.getAttributes(({
354
- type,
355
- computed
356
- }) => !computed && type === 'boolean'), []);
357
- }
358
-
359
- static get dateAttributes() {
360
- return this._getCached('jsonSchema:dateAttributes', () => this.getAttributes(({
361
- type,
362
- computed
363
- }) => !computed && ['date', 'datetime', 'timestamp'].includes(type)), []);
364
- }
365
-
366
- static get computedAttributes() {
367
- return this._getCached('jsonSchema:computedAttributes', () => this.getAttributes(({
368
- computed
369
- }) => computed), []);
370
- }
371
-
372
- static get hiddenAttributes() {
373
- return this._getCached('jsonSchema:hiddenAttributes', () => this.getAttributes(({
374
- hidden
375
- }) => hidden), []);
376
- }
377
-
378
- static getAttributes(filter) {
379
- const attributes = [];
380
- const {
381
- properties
382
- } = this.definition;
383
-
384
- for (const [name, property] of Object.entries(properties)) {
385
- if (filter(property)) {
386
- attributes.push(name);
387
- }
388
- }
389
-
390
- return attributes;
391
- }
392
-
393
- static _getCached(identifier, calculate, empty = {}) {
394
- var _entry, _entry2;
395
-
396
- let cache = getMeta(this, 'cache', {});
397
- let entry;
398
-
399
- for (const part of identifier.split(':')) {
400
- entry = cache[part] = cache[part] || {
401
- cache: {},
402
- value: undefined
403
- };
404
- cache = entry.cache;
405
- }
406
-
407
- if (((_entry = entry) == null ? void 0 : _entry.value) === undefined) {
408
- entry.value = empty;
409
- entry.value = calculate();
410
- entry.cache = {};
411
- }
412
-
413
- return (_entry2 = entry) == null ? void 0 : _entry2.value;
414
- }
415
-
416
- static getRelatedRelations() {
417
- return getMeta(this, 'relatedRelations', []);
418
- }
419
-
420
- static propertyNameToColumnName(propertyName) {
421
- return propertyName;
422
- }
423
-
424
- static columnNameToPropertyName(columnName) {
425
- return columnName;
426
- }
427
-
428
- $setJson(json, options) {
429
- options = options || {};
430
- const callInitialize = !options.patch && this.$initialize !== Model.prototype.$initialize && !this.constructor.isReference(json);
431
-
432
- if (!callInitialize || options.skipValidation) {
433
- super.$setJson(json, options);
434
-
435
- if (callInitialize) {
436
- this.$initialize();
437
- }
438
- } else {
439
- super.$setJson(json, { ...options,
440
- patch: true
441
- });
442
- this.$initialize();
443
- this.$validate(this, options);
444
- }
445
-
446
- return this;
447
- }
448
-
449
- $formatDatabaseJson(json) {
450
- const {
451
- constructor
452
- } = this;
453
-
454
- for (const key of constructor.dateAttributes) {
455
- const date = json[key];
456
-
457
- if (date != null && date.toISOString) {
458
- json[key] = date.toISOString();
459
- }
460
- }
461
-
462
- if (constructor.isSQLite()) {
463
- for (const key of constructor.booleanAttributes) {
464
- const bool = json[key];
465
-
466
- if (bool !== undefined) {
467
- json[key] = bool ? 1 : 0;
468
- }
469
- }
470
- }
471
-
472
- for (const key of constructor.computedAttributes) {
473
- delete json[key];
474
- }
475
-
476
- return super.$formatDatabaseJson(json);
477
- }
478
-
479
- $parseDatabaseJson(json) {
480
- const {
481
- constructor
482
- } = this;
483
- json = super.$parseDatabaseJson(json);
484
-
485
- if (constructor.isSQLite()) {
486
- for (const key of constructor.booleanAttributes) {
487
- const bool = json[key];
488
-
489
- if (bool !== undefined) {
490
- json[key] = !!bool;
491
- }
492
- }
493
- }
494
-
495
- return this.$parseJson(json);
496
- }
497
-
498
- $parseJson(json) {
499
- const {
500
- constructor
501
- } = this;
502
-
503
- for (const key of constructor.dateAttributes) {
504
- const date = json[key];
505
-
506
- if (date !== undefined) {
507
- json[key] = (0, _utils2.isString)(date) ? new Date(date) : date;
508
- }
509
- }
510
-
511
- const {
512
- assets
513
- } = constructor.definition;
514
-
515
- if (assets) {
516
- for (const dataPath in assets) {
517
- const storage = constructor.app.getStorage(assets[dataPath].storage);
518
- const data = (0, _utils2.getValueAtDataPath)(json, dataPath, () => null);
519
-
520
- if (data) {
521
- const convertToAssetFiles = data => {
522
- if (data) {
523
- if ((0, _utils2.isArray)(data)) {
524
- data.forEach(convertToAssetFiles);
525
- } else {
526
- storage.convertAssetFile(data);
527
- }
528
- }
529
- };
530
-
531
- convertToAssetFiles(data);
532
- }
533
- }
534
- }
535
-
536
- return json;
537
- }
538
-
539
- $formatJson(json) {
540
- const {
541
- constructor
542
- } = this;
543
-
544
- for (const key of constructor.computedAttributes) {
545
- if (!(key in json)) {
546
- const value = this[key];
547
-
548
- if (value !== undefined) {
549
- json[key] = value;
550
- }
551
- }
552
- }
553
-
554
- for (const key of constructor.hiddenAttributes) {
555
- delete json[key];
556
- }
557
-
558
- return json;
559
- }
560
-
561
- $filterGraph(modelGraph, expr) {
562
- return (0, _graph.filterGraph)(this.constructor, modelGraph, expr);
563
- }
564
-
565
- async $populateGraph(modelGraph, expr, trx) {
566
- return (0, _graph.populateGraph)(this.constructor, modelGraph, expr, trx);
567
- }
568
-
569
- static filterGraph(modelGraph, expr) {
570
- return (0, _graph.filterGraph)(this, modelGraph, expr);
571
- }
572
-
573
- static async populateGraph(modelGraph, expr, trx) {
574
- return (0, _graph.populateGraph)(this, modelGraph, expr, trx);
575
- }
576
-
577
- static getPropertyOrRelationAtDataPath(dataPath) {
578
- const parsedDataPath = (0, _utils2.parseDataPath)(dataPath);
579
- let index = 0;
580
-
581
- const getResult = (property = null, relation = null) => {
582
- const found = property || relation;
583
- const name = parsedDataPath[index];
584
- const next = index + 1;
585
- const dataPath = found ? (0, _utils2.normalizeDataPath)(parsedDataPath.slice(0, next)) : null;
586
- const nestedDataPath = found ? (0, _utils2.normalizeDataPath)(parsedDataPath.slice(next)) : null;
587
- const expression = found ? parsedDataPath.slice(0, relation ? next : index).join('.') + (property ? `(#${name})` : '') : null;
588
- return {
589
- property,
590
- relation,
591
- dataPath,
592
- nestedDataPath,
593
- name,
594
- expression,
595
- index
596
- };
597
- };
598
-
599
- const [firstToken, ...otherTokens] = parsedDataPath;
600
- const property = this.definition.properties[firstToken];
601
-
602
- if (property) {
603
- return getResult(property);
604
- } else {
605
- let relation = this.getRelations()[firstToken];
606
-
607
- if (relation) {
608
- let {
609
- relatedModelClass
610
- } = relation;
611
-
612
- for (const token of otherTokens) {
613
- index++;
614
- const property = relatedModelClass.definition.properties[token];
615
-
616
- if (property) {
617
- return getResult(property);
618
- } else if (token === '*') {
619
- if (relation.isOneToOne()) {
620
- return getResult();
621
- } else {
622
- continue;
623
- }
624
- } else {
625
- relation = relatedModelClass.getRelations()[token];
626
-
627
- if (relation) {
628
- relatedModelClass = relation.relatedModelClass;
629
- } else {
630
- return getResult();
631
- }
632
- }
633
- }
634
-
635
- if (relation) {
636
- return getResult(null, relation);
637
- }
638
- }
639
- }
640
-
641
- return getResult();
642
- }
643
-
644
- static relatedQuery(relationName, trx) {
645
- return super.relatedQuery(relationName, trx).alias(relationName);
646
- }
647
-
648
- static modifierNotFound(query, modifier) {
649
- if ((0, _utils2.isString)(modifier)) {
650
- if (query.modelClass().hasScope(modifier)) {
651
- return query.applyScope(modifier);
652
- }
653
-
654
- switch (modifier[0]) {
655
- case '^':
656
- return query.applyScope(modifier);
657
-
658
- case '-':
659
- return query.ignoreScope(modifier.slice(1));
660
-
661
- case '#':
662
- return query.select(modifier.slice(1));
663
- }
664
- }
665
-
666
- super.modifierNotFound(query, modifier);
667
- }
668
-
669
- static createNotFoundError(ctx, error) {
670
- return new _errors.NotFoundError(error || (ctx.byId ? `'${this.name}' model with id ${ctx.byId} not found` : `'${this.name}' model not found`));
671
- }
672
-
673
- static createValidator() {
674
- return this.app.validator;
675
- }
676
-
677
- static createValidationError({
678
- type,
679
- message,
680
- errors,
681
- options,
682
- json
683
- }) {
684
- switch (type) {
685
- case 'ModelValidation':
686
- return this.app.createValidationError({
687
- type,
688
- message: message || `The provided data for the ${this.name} model is not valid`,
689
- errors,
690
- options,
691
- json
692
- });
693
-
694
- case 'RelationExpression':
695
- case 'UnallowedRelation':
696
- return new _errors.RelationError({
697
- type,
698
- message,
699
- errors
700
- });
701
-
702
- case 'InvalidGraph':
703
- return new _errors.GraphError({
704
- type,
705
- message,
706
- errors
707
- });
708
-
709
- default:
710
- return new _errors.ResponseError({
711
- type,
712
- message,
713
- errors
714
- });
715
- }
716
- }
717
-
718
- static get definition() {
719
- return getMeta(this, 'definition', () => {
720
- const definition = {};
721
-
722
- const setDefinition = (name, property) => {
723
- Object.defineProperty(definition, name, { ...property,
724
- enumerable: true
725
- });
726
- };
727
-
728
- const getDefinition = name => {
729
- let modelClass = this;
730
- const values = [];
731
-
732
- while (modelClass !== _objection.default.Model) {
733
- if (name in modelClass) {
734
- const desc = Object.getOwnPropertyDescriptor(modelClass, name);
735
-
736
- if (desc) {
737
- var _desc$get;
738
-
739
- const value = ((_desc$get = desc.get) == null ? void 0 : _desc$get.call(this)) || desc.value;
740
-
741
- if (value) {
742
- values.push(value);
743
- }
744
- }
745
- }
746
-
747
- modelClass = Object.getPrototypeOf(modelClass);
748
- }
749
-
750
- setDefinition(name, {
751
- configurable: true,
752
- value: {}
753
- });
754
-
755
- try {
756
- const merged = _definitions.default[name].call(this, values);
757
-
758
- setDefinition(name, {
759
- configurable: false,
760
- value: merged
761
- });
762
- return merged;
763
- } catch (error) {
764
- throw new _errors.ModelError(this, error.message);
765
- }
766
- };
767
-
768
- for (const name in _definitions.default) {
769
- setDefinition(name, {
770
- configurable: true,
771
- get: () => getDefinition(name)
772
- });
773
- }
774
-
775
- return definition;
776
- });
777
- }
778
-
779
- $emit(event, ...args) {
780
- return this.constructor.emit(event, this, ...args);
781
- }
782
-
783
- static beforeFind(args) {
784
- return this._emitStaticHook('before:find', args);
785
- }
786
-
787
- static afterFind(args) {
788
- return this._emitStaticHook('after:find', args);
789
- }
790
-
791
- static beforeInsert(args) {
792
- return this._emitStaticHook('before:insert', args);
793
- }
794
-
795
- static afterInsert(args) {
796
- return this._emitStaticHook('after:insert', args);
797
- }
798
-
799
- static beforeUpdate(args) {
800
- return this._emitStaticHook('before:update', args);
801
- }
802
-
803
- static afterUpdate(args) {
804
- return this._emitStaticHook('after:update', args);
805
- }
806
-
807
- static beforeDelete(args) {
808
- return this._emitStaticHook('before:delete', args);
809
- }
810
-
811
- static afterDelete(args) {
812
- return this._emitStaticHook('after:delete', args);
813
- }
814
-
815
- static async _emitStaticHook(event, originalArgs) {
816
- const listeners = this.listeners(event);
817
-
818
- if (listeners.length > 0) {
819
- let {
820
- result
821
- } = originalArgs;
822
- const args = Object.create(originalArgs, {
823
- type: {
824
- value: event
825
- },
826
- result: {
827
- get() {
828
- return result;
829
- }
830
-
831
- }
832
- });
833
-
834
- for (const listener of listeners) {
835
- const res = await listener.call(this, args);
836
-
837
- if (res !== undefined) {
838
- result = res;
839
- }
840
- }
841
-
842
- if (result !== originalArgs.result) {
843
- return result;
844
- }
845
- }
846
- }
847
-
848
- static _setupAssetsEvents(assets) {
849
- const assetDataPaths = Object.keys(assets);
850
- this.on(['before:insert', 'before:update', 'before:delete'], async ({
851
- type,
852
- transaction,
853
- inputItems,
854
- asFindQuery
855
- }) => {
856
- const afterItems = type === 'before:delete' ? [] : inputItems;
857
- const dataPaths = afterItems.length > 0 ? assetDataPaths.filter(path => getValueAtAssetDataPath(afterItems[0], path) !== undefined) : assetDataPaths;
858
-
859
- if (dataPaths.length === 0) {
860
- return;
861
- }
862
-
863
- const beforeItems = type === 'before:insert' ? [] : await loadAssetDataPaths(asFindQuery(), dataPaths);
864
- const beforeFilesPerDataPath = getFilesPerAssetDataPath(beforeItems, dataPaths);
865
- const afterFilesPerDataPath = getFilesPerAssetDataPath(afterItems, dataPaths);
866
- const importedFiles = [];
867
- const modifiedFiles = [];
868
-
869
- if (transaction.rollback) {
870
- transaction.setMaxListeners(0);
871
- transaction.on('rollback', async error => {
872
- if (importedFiles.length > 0) {
873
- console.info(`Received '${error}', removing imported files again: ${importedFiles.map(file => `'${file.name}'`)}`);
874
- await Promise.all(importedFiles.map(file => file.storage.removeFile(file)));
875
- }
876
-
877
- if (modifiedFiles.length > 0) {
878
- console.info(`Unable to restore these already modified files: ${modifiedFiles.map(file => `'${file.name}'`)}`);
879
- }
880
- });
881
- }
882
-
883
- for (const dataPath of dataPaths) {
884
- const storage = this.app.getStorage(assets[dataPath].storage);
885
- const beforeFiles = beforeFilesPerDataPath[dataPath] || [];
886
- const afterFiles = afterFilesPerDataPath[dataPath] || [];
887
- const beforeByKey = mapFilesByKey(beforeFiles);
888
- const afterByKey = mapFilesByKey(afterFiles);
889
- const removedFiles = beforeFiles.filter(file => !afterByKey[file.key]);
890
- const addedFiles = afterFiles.filter(file => !beforeByKey[file.key]);
891
- const modifiedFiles = afterFiles.filter(file => file.data && beforeByKey[file.key]);
892
- importedFiles.push(...(await this.app.handleAdddedAndRemovedAssets(storage, addedFiles, removedFiles, transaction)));
893
- modifiedFiles.push(...(await this.app.handleModifiedAssets(storage, modifiedFiles, transaction)));
894
- }
895
- });
896
- }
897
-
898
- }
899
-
900
- exports.Model = Model;
901
- Model.QueryBuilder = _query.QueryBuilder;
902
- Model.cloneObjectAttributes = false;
903
- Model.pickJsonSchemaProperties = true;
904
- Model.useLimitInFirst = true;
905
-
906
- _lib.EventEmitter.mixin(Model);
907
-
908
- _lib.KnexHelper.mixin(Model);
909
-
910
- _query.QueryBuilder.mixin(Model);
911
-
912
- const metaMap = new WeakMap();
913
-
914
- function getMeta(modelClass, key, value) {
915
- let meta = metaMap.get(modelClass);
916
-
917
- if (!meta) {
918
- metaMap.set(modelClass, meta = {});
919
- }
920
-
921
- if (!(key in meta)) {
922
- meta[key] = (0, _utils2.isFunction)(value) ? value() : value;
923
- }
924
-
925
- return meta[key];
926
- }
927
-
928
- function loadAssetDataPaths(query, dataPaths) {
929
- return dataPaths.reduce((query, dataPath) => query.loadDataPath(dataPath), query);
930
- }
931
-
932
- function getValueAtAssetDataPath(item, path) {
933
- return (0, _utils2.getValueAtDataPath)(item, path, () => undefined);
934
- }
935
-
936
- function getFilesPerAssetDataPath(items, dataPaths) {
937
- return dataPaths.reduce((allFiles, dataPath) => {
938
- allFiles[dataPath] = (0, _utils2.asArray)(items).reduce((files, item) => {
939
- const data = (0, _utils2.asArray)(getValueAtAssetDataPath(item, dataPath));
940
- files.push(...(0, _utils2.flatten)(data).filter(file => !!file));
941
- return files;
942
- }, []);
943
- return allFiles;
944
- }, {});
945
- }
946
-
947
- function mapFilesByKey(files) {
948
- return files.reduce((map, file) => {
949
- map[file.key] = file;
950
- return map;
951
- }, {});
952
- }
953
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlbHMvTW9kZWwuanMiXSwibmFtZXMiOlsiTW9kZWwiLCJvYmplY3Rpb24iLCJjb25zdHJ1Y3RvciIsImpzb24iLCIkc2V0SnNvbiIsInNldHVwIiwia25leCIsInJlbGF0aW9uIiwiT2JqZWN0IiwidmFsdWVzIiwiZ2V0UmVsYXRpb25zIiwic2V0dXBSZWxhdGlvbiIsImVycm9yIiwiUmVsYXRpb25FcnJvciIsInJlZmVyZW5jZVZhbGlkYXRvciIsInJlbGF0ZWRNb2RlbENsYXNzIiwiZ2V0UmVsYXRlZFJlbGF0aW9ucyIsInB1c2giLCJhY2Nlc3NvciIsIm5hbWUiLCJwcm90b3R5cGUiLCJkZWZpbmVBY2Nlc3NvciIsInRhcmdldCIsImlzQ2xhc3MiLCJkZWZpbmVQcm9wZXJ0eSIsImdldCIsInZhbHVlIiwiUmVsYXRpb25BY2Nlc3NvciIsImNvbmZpZ3VyYWJsZSIsImVudW1lcmFibGUiLCJpbml0aWFsaXplIiwiaG9va3MiLCJhc3NldHMiLCJkZWZpbml0aW9uIiwiX3NldHVwRW1pdHRlciIsIl9zZXR1cEFzc2V0c0V2ZW50cyIsIiRpbml0aWFsaXplIiwiJGFwcCIsImFwcCIsIiRpcyIsIm1vZGVsIiwiaWQiLCIkaGFzIiwicHJvcGVydGllcyIsInByb3BlcnR5IiwiJHVwZGF0ZSIsInRyeCIsIiRxdWVyeSIsInVwZGF0ZSIsInJ1bkFmdGVyIiwicmVzdWx0IiwicXVlcnkiLCJoYXMiLCIkc2V0IiwiJHBhdGNoIiwicGF0Y2giLCIkdHJhbnNhY3Rpb24iLCJoYW5kbGVyIiwidHJhbnNhY3Rpb24iLCIkdmFsaWRhdGUiLCJvcHRpb25zIiwic2tpcFZhbGlkYXRpb24iLCJncmFwaCIsImFzeW5jIiwiaW5wdXRKc29uIiwic2hhbGxvdyIsIiRpc09iamVjdGlvbk1vZGVsIiwiY2xvbmUiLCJtdXRhYmxlIiwidmFsaWRhdG9yIiwiZ2V0VmFsaWRhdG9yIiwiYXJncyIsImN0eCIsImNyZWF0ZSIsImJlZm9yZVZhbGlkYXRlIiwidmFsaWRhdGUiLCJoYW5kbGVSZXN1bHQiLCJhZnRlclZhbGlkYXRlIiwidGhlbiIsIiR2YWxpZGF0ZUdyYXBoIiwiZnJvbUpzb24iLCJvbkVycm9yIiwiZXJyIiwiUmVzcG9uc2VFcnJvciIsIkRCRXJyb3IiLCJjcmVhdGVEYXRhYmFzZUVycm9yIiwiV3JhcHBlZEVycm9yIiwiUHJvbWlzZSIsInJlamVjdCIsImNvdW50IiwiZmlyc3QiLCJ0YWJsZU5hbWUiLCJtYXRjaCIsImlkQ29sdW1uIiwiaWRzIiwiZW50cmllcyIsInByaW1hcnkiLCJsZW5ndGgiLCJnZXRSZWZlcmVuY2UiLCJtb2RlbE9ySWQiLCJpbmNsdWRlUHJvcGVydGllcyIsInJlZiIsImlkUHJvcGVydGllcyIsImdldElkUHJvcGVydHlBcnJheSIsImFkZFByb3BlcnR5Iiwia2V5IiwidW5kZWZpbmVkIiwidWlkUmVmUHJvcCIsImZvckVhY2giLCJNb2RlbEVycm9yIiwiaW5kZXgiLCJpc1JlZmVyZW5jZSIsIm9iaiIsImNvbXBpbGVWYWxpZGF0b3IiLCJvbmVPZiIsInR5cGUiLCJyZWR1Y2UiLCJpZFByb3BlcnR5IiwiYWRkaXRpb25hbFByb3BlcnRpZXMiLCJ0aHJvdyIsImdldFNjb3BlIiwic2NvcGVzIiwiaGFzU2NvcGUiLCJnZXRNb2RpZmllcnMiLCJtb2RpZmllcnMiLCJyZWxhdGlvbk1hcHBpbmdzIiwiX2dldENhY2hlZCIsInJlbGF0aW9ucyIsIm1vZGVscyIsImpzb25TY2hlbWEiLCJzY2hlbWEiLCIkaWQiLCIkc2NoZW1hIiwidmlydHVhbEF0dHJpYnV0ZXMiLCJjb21wdXRlZEF0dHJpYnV0ZXMiLCJqc29uQXR0cmlidXRlcyIsImdldEF0dHJpYnV0ZXMiLCJzcGVjaWZpY1R5cGUiLCJjb21wdXRlZCIsImJvb2xlYW5BdHRyaWJ1dGVzIiwiZGF0ZUF0dHJpYnV0ZXMiLCJpbmNsdWRlcyIsImhpZGRlbkF0dHJpYnV0ZXMiLCJoaWRkZW4iLCJmaWx0ZXIiLCJhdHRyaWJ1dGVzIiwiaWRlbnRpZmllciIsImNhbGN1bGF0ZSIsImVtcHR5IiwiY2FjaGUiLCJnZXRNZXRhIiwiZW50cnkiLCJwYXJ0Iiwic3BsaXQiLCJwcm9wZXJ0eU5hbWVUb0NvbHVtbk5hbWUiLCJwcm9wZXJ0eU5hbWUiLCJjb2x1bW5OYW1lVG9Qcm9wZXJ0eU5hbWUiLCJjb2x1bW5OYW1lIiwiY2FsbEluaXRpYWxpemUiLCIkZm9ybWF0RGF0YWJhc2VKc29uIiwiZGF0ZSIsInRvSVNPU3RyaW5nIiwiaXNTUUxpdGUiLCJib29sIiwiJHBhcnNlRGF0YWJhc2VKc29uIiwiJHBhcnNlSnNvbiIsIkRhdGUiLCJkYXRhUGF0aCIsInN0b3JhZ2UiLCJnZXRTdG9yYWdlIiwiZGF0YSIsImNvbnZlcnRUb0Fzc2V0RmlsZXMiLCJjb252ZXJ0QXNzZXRGaWxlIiwiJGZvcm1hdEpzb24iLCIkZmlsdGVyR3JhcGgiLCJtb2RlbEdyYXBoIiwiZXhwciIsIiRwb3B1bGF0ZUdyYXBoIiwiZmlsdGVyR3JhcGgiLCJwb3B1bGF0ZUdyYXBoIiwiZ2V0UHJvcGVydHlPclJlbGF0aW9uQXREYXRhUGF0aCIsInBhcnNlZERhdGFQYXRoIiwiZ2V0UmVzdWx0IiwiZm91bmQiLCJuZXh0Iiwic2xpY2UiLCJuZXN0ZWREYXRhUGF0aCIsImV4cHJlc3Npb24iLCJqb2luIiwiZmlyc3RUb2tlbiIsIm90aGVyVG9rZW5zIiwidG9rZW4iLCJpc09uZVRvT25lIiwicmVsYXRlZFF1ZXJ5IiwicmVsYXRpb25OYW1lIiwiYWxpYXMiLCJtb2RpZmllck5vdEZvdW5kIiwibW9kaWZpZXIiLCJtb2RlbENsYXNzIiwiYXBwbHlTY29wZSIsImlnbm9yZVNjb3BlIiwic2VsZWN0IiwiY3JlYXRlTm90Rm91bmRFcnJvciIsIk5vdEZvdW5kRXJyb3IiLCJieUlkIiwiY3JlYXRlVmFsaWRhdG9yIiwiY3JlYXRlVmFsaWRhdGlvbkVycm9yIiwibWVzc2FnZSIsImVycm9ycyIsIkdyYXBoRXJyb3IiLCJzZXREZWZpbml0aW9uIiwiZ2V0RGVmaW5pdGlvbiIsImRlc2MiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJjYWxsIiwiZ2V0UHJvdG90eXBlT2YiLCJtZXJnZWQiLCJkZWZpbml0aW9ucyIsIiRlbWl0IiwiZXZlbnQiLCJlbWl0IiwiYmVmb3JlRmluZCIsIl9lbWl0U3RhdGljSG9vayIsImFmdGVyRmluZCIsImJlZm9yZUluc2VydCIsImFmdGVySW5zZXJ0IiwiYmVmb3JlVXBkYXRlIiwiYWZ0ZXJVcGRhdGUiLCJiZWZvcmVEZWxldGUiLCJhZnRlckRlbGV0ZSIsIm9yaWdpbmFsQXJncyIsImxpc3RlbmVycyIsImxpc3RlbmVyIiwicmVzIiwiYXNzZXREYXRhUGF0aHMiLCJrZXlzIiwib24iLCJpbnB1dEl0ZW1zIiwiYXNGaW5kUXVlcnkiLCJhZnRlckl0ZW1zIiwiZGF0YVBhdGhzIiwicGF0aCIsImdldFZhbHVlQXRBc3NldERhdGFQYXRoIiwiYmVmb3JlSXRlbXMiLCJsb2FkQXNzZXREYXRhUGF0aHMiLCJiZWZvcmVGaWxlc1BlckRhdGFQYXRoIiwiZ2V0RmlsZXNQZXJBc3NldERhdGFQYXRoIiwiYWZ0ZXJGaWxlc1BlckRhdGFQYXRoIiwiaW1wb3J0ZWRGaWxlcyIsIm1vZGlmaWVkRmlsZXMiLCJyb2xsYmFjayIsInNldE1heExpc3RlbmVycyIsImNvbnNvbGUiLCJpbmZvIiwibWFwIiwiZmlsZSIsImFsbCIsInJlbW92ZUZpbGUiLCJiZWZvcmVGaWxlcyIsImFmdGVyRmlsZXMiLCJiZWZvcmVCeUtleSIsIm1hcEZpbGVzQnlLZXkiLCJhZnRlckJ5S2V5IiwicmVtb3ZlZEZpbGVzIiwiYWRkZWRGaWxlcyIsImhhbmRsZUFkZGRlZEFuZFJlbW92ZWRBc3NldHMiLCJoYW5kbGVNb2RpZmllZEFzc2V0cyIsIlF1ZXJ5QnVpbGRlciIsImNsb25lT2JqZWN0QXR0cmlidXRlcyIsInBpY2tKc29uU2NoZW1hUHJvcGVydGllcyIsInVzZUxpbWl0SW5GaXJzdCIsIkV2ZW50RW1pdHRlciIsIm1peGluIiwiS25leEhlbHBlciIsIm1ldGFNYXAiLCJXZWFrTWFwIiwibWV0YSIsInNldCIsImxvYWREYXRhUGF0aCIsIml0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QVNwQixhQUFULENBQXVCcUIsS0FBdkIsRUFBOEI7QUFDNUIsU0FBT0EsS0FBSyxDQUFDdEssTUFBTixDQUNMLENBQUMwSSxHQUFELEVBQU1DLElBQU4sS0FBZTtBQUNiRCxJQUFBQSxHQUFHLENBQUNDLElBQUksQ0FBQ3RKLEdBQU4sQ0FBSCxHQUFnQnNKLElBQWhCO0FBQ0EsV0FBT0QsR0FBUDtBQUNELEdBSkksRUFLTCxFQUxLLENBQVA7QUFPRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBvYmplY3Rpb24gZnJvbSAnb2JqZWN0aW9uJ1xuaW1wb3J0IHsgUXVlcnlCdWlsZGVyIH0gZnJvbSAnQC9xdWVyeSdcbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgS25leEhlbHBlciB9IGZyb20gJ0AvbGliJ1xuaW1wb3J0IHsgY29udmVydFNjaGVtYSwgYWRkUmVsYXRpb25TY2hlbWFzLCBjb252ZXJ0UmVsYXRpb25zIH0gZnJvbSAnQC9zY2hlbWEnXG5pbXBvcnQgeyBwb3B1bGF0ZUdyYXBoLCBmaWx0ZXJHcmFwaCB9IGZyb20gJ0AvZ3JhcGgnXG5pbXBvcnQgeyBmb3JtYXRKc29uIH0gZnJvbSAnQC91dGlscydcbmltcG9ydCB7XG4gIFJlc3BvbnNlRXJyb3IsXG4gIEdyYXBoRXJyb3IsIE1vZGVsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIFJlbGF0aW9uRXJyb3IsXG4gIFdyYXBwZWRFcnJvclxufSBmcm9tICdAL2Vycm9ycydcbmltcG9ydCB7XG4gIGlzU3RyaW5nLCBpc09iamVjdCwgaXNBcnJheSwgaXNGdW5jdGlvbiwgaXNQcm9taXNlLCBhc0FycmF5LCBtZXJnZSwgZmxhdHRlbixcbiAgcGFyc2VEYXRhUGF0aCwgbm9ybWFsaXplRGF0YVBhdGgsIGdldFZhbHVlQXREYXRhUGF0aFxufSBmcm9tICdAZGl0b2pzL3V0aWxzJ1xuaW1wb3J0IFJlbGF0aW9uQWNjZXNzb3IgZnJvbSAnLi9SZWxhdGlvbkFjY2Vzc29yJ1xuaW1wb3J0IGRlZmluaXRpb25zIGZyb20gJy4vZGVmaW5pdGlvbnMnXG5cbmV4cG9ydCBjbGFzcyBNb2RlbCBleHRlbmRzIG9iamVjdGlvbi5Nb2RlbCB7XG4gIC8vIERlZmluZSBhIGRlZmF1bHQgY29uc3RydWN0b3IgdG8gYWxsb3cgbmV3IE1vZGVsKGpzb24pIGFzIGEgc2hvcnQtY3V0IHRvXG4gIC8vIGBNb2RlbC5mcm9tSnNvbihqc29uLCB7IHNraXBWYWxpZGF0aW9uOiB0cnVlIH0pYFxuICBjb25zdHJ1Y3Rvcihqc29uKSB7XG4gICAgc3VwZXIoKVxuICAgIGlmIChqc29uKSB7XG4gICAgICB0aGlzLiRzZXRKc29uKGpzb24pXG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHNldHVwKGtuZXgpIHtcbiAgICB0aGlzLmtuZXgoa25leClcbiAgICB0cnkge1xuICAgICAgZm9yIChjb25zdCByZWxhdGlvbiBvZiBPYmplY3QudmFsdWVzKHRoaXMuZ2V0UmVsYXRpb25zKCkpKSB7XG4gICAgICAgIHRoaXMuc2V0dXBSZWxhdGlvbihyZWxhdGlvbilcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgZXJyb3IgaW5zdGFuY2VvZiBSZWxhdGlvbkVycm9yID8gZXJyb3IgOiBuZXcgUmVsYXRpb25FcnJvcihlcnJvcilcbiAgICB9XG4gICAgdGhpcy5yZWZlcmVuY2VWYWxpZGF0b3IgPSBudWxsXG4gIH1cblxuICBzdGF0aWMgc2V0dXBSZWxhdGlvbihyZWxhdGlvbikge1xuICAgIC8vIEFkZCB0aGlzIHJlbGF0aW9uIHRvIHRoZSByZWxhdGVkIG1vZGVsJ3MgcmVsYXRlZFJlbGF0aW9ucywgc28gaXQgY2FuXG4gICAgLy8gcmVnaXN0ZXIgYWxsIHJlcXVpcmVkIGZvcmVpZ24ga2V5cyBpbiBpdHMgcHJvcGVydGllcy5cbiAgICByZWxhdGlvbi5yZWxhdGVkTW9kZWxDbGFzcy5nZXRSZWxhdGVkUmVsYXRpb25zKCkucHVzaChyZWxhdGlvbilcbiAgICAvLyBUT0RPOiBDaGVjayBgdGhyb3VnaGAgc2V0dGluZ3MgdG8gbWFrZSBzdXJlIHRoZXkncmUgY29ycmVjdD9cblxuICAgIC8vIEV4cG9zZSBSZWxhdGlvbkFjY2Vzc29yIGluc3RhbmNlcyBmb3IgZWFjaCByZWxhdGlvbiB1bmRlciBzaG9ydC1jdXQgJG5hbWVcbiAgICAvLyBmb3IgYWNjZXNzIHRvIHJlbGF0aW9ucyBhbmQgaW1wbGljaXQgY2FsbHMgdG8gJHJlbGF0ZWRRdWVyeShuYW1lKS5cbiAgICBjb25zdCBhY2Nlc3NvciA9IGAkJHtyZWxhdGlvbi5uYW1lfWBcbiAgICBpZiAoYWNjZXNzb3IgaW4gdGhpcy5wcm90b3R5cGUpIHtcbiAgICAgIHRocm93IG5ldyBSZWxhdGlvbkVycm9yKFxuICAgICAgICBgTW9kZWwgJyR7dGhpcy5uYW1lfScgYWxyZWFkeSBkZWZpbmVzIGEgcHJvcGVydHkgd2l0aCBuYW1lIGAgK1xuICAgICAgICBgJyR7YWNjZXNzb3J9JyB0aGF0IGNsYXNoZXMgd2l0aCB0aGUgcmVsYXRpb24gYWNjZXNzb3IuYClcbiAgICB9XG5cbiAgICAvLyBEZWZpbmUgYW4gYWNjZXNzb3Igb24gdGhlIGNsYXNzIGFzIHdlbGwgYXMgb24gdGhlIHByb3RvdHlwZSB0aGF0IHdoZW5cbiAgICAvLyBmaXJzdCBjYWxsZWQgY3JlYXRlcyBhIFJlbGF0aW9uQWNjZXNzb3IgaW5zdGFuY2UgYW5kIHRoZW4gb3ZlcnJpZGVzIHRoZVxuICAgIC8vIGFjY2Vzc29yIHdpdGggb25lIHRoYXQgdGhlbiBqdXN0IHJldHVybnMgdGhlIHNhbWUgdmFsdWUgYWZ0ZXJ3YXJkcy5cbiAgICBjb25zdCBkZWZpbmVBY2Nlc3NvciA9ICh0YXJnZXQsIGlzQ2xhc3MpID0+IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGFjY2Vzc29yLCB7XG4gICAgICAgIGdldCgpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBSZWxhdGlvbkFjY2Vzc29yKFxuICAgICAgICAgICAgcmVsYXRpb24sXG4gICAgICAgICAgICBpc0NsYXNzID8gdGhpcyA6IG51bGwsIC8vIG1vZGVsQ2xhc3NcbiAgICAgICAgICAgIGlzQ2xhc3MgPyBudWxsIDogdGhpcyAvLyBtb2RlbFxuICAgICAgICAgIClcbiAgICAgICAgICAvLyBPdmVycmlkZSBhY2Nlc3NvciB3aXRoIHZhbHVlIG9uIGZpcnN0IGNhbGwgZm9yIGNhY2hpbmcuXG4gICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGFjY2Vzc29yLCB7XG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlXG4gICAgICAgICAgfSlcbiAgICAgICAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBkZWZpbmVBY2Nlc3Nvcih0aGlzLCB0cnVlKVxuICAgIGRlZmluZUFjY2Vzc29yKHRoaXMucHJvdG90eXBlLCBmYWxzZSlcbiAgfVxuXG4gIC8vIEBvdmVycmlkYWJsZVxuICBzdGF0aWMgaW5pdGlhbGl6ZSgpIHtcbiAgICBjb25zdCB7IGhvb2tzLCBhc3NldHMgfSA9IHRoaXMuZGVmaW5pdGlvblxuICAgIHRoaXMuX3NldHVwRW1pdHRlcihob29rcylcbiAgICBpZiAoYXNzZXRzKSB7XG4gICAgICB0aGlzLl9zZXR1cEFzc2V0c0V2ZW50cyhhc3NldHMpXG4gICAgfVxuICB9XG5cbiAgLy8gQG92ZXJyaWRhYmxlXG4gICRpbml0aWFsaXplKCkge1xuICB9XG5cbiAgZ2V0ICRhcHAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IuYXBwXG4gIH1cblxuICAkaXMobW9kZWwpIHtcbiAgICByZXR1cm4gbW9kZWw/LmNvbnN0cnVjdG9yID09PSB0aGlzLmNvbnN0cnVjdG9yICYmIG1vZGVsPy5pZCA9PT0gdGhpcy5pZFxuICB9XG5cbiAgJGhhcyguLi5wcm9wZXJ0aWVzKSB7XG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBwcm9wZXJ0aWVzKSB7XG4gICAgICBpZiAoIShwcm9wZXJ0eSBpbiB0aGlzKSkgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAkdXBkYXRlKHByb3BlcnRpZXMsIHRyeCkge1xuICAgIHJldHVybiB0aGlzLiRxdWVyeSh0cngpXG4gICAgICAudXBkYXRlKHByb3BlcnRpZXMpXG4gICAgICAucnVuQWZ0ZXIoKHJlc3VsdCwgcXVlcnkpID0+XG4gICAgICAgIC8vIE9ubHkgcGVyZm9ybSBgJHNldCgpYCBhbmQgcmV0dXJuIGB0aGlzYCBpZiB0aGUgcXVlcnkgd2Fzbid0IG1vZGlmaWVkXG4gICAgICAgIC8vIGluIGEgd2F5IHRoYXQgd291bGQgcmVtb3ZlIHRoZSBgdXBkYXRlKClgIGNvbW1hbmQsIGUuZy4gdG9GaW5kUXVlcnkoKVxuICAgICAgICBxdWVyeS5oYXMoJ3VwZGF0ZScpID8gdGhpcy4kc2V0KHJlc3VsdCkgOiByZXN1bHRcbiAgICAgIClcbiAgfVxuXG4gICRwYXRjaChwcm9wZXJ0aWVzLCB0cngpIHtcbiAgICByZXR1cm4gdGhpcy4kcXVlcnkodHJ4KVxuICAgICAgLnBhdGNoKHByb3BlcnRpZXMpXG4gICAgICAucnVuQWZ0ZXIoKHJlc3VsdCwgcXVlcnkpID0+XG4gICAgICAgIC8vIE9ubHkgcGVyZm9ybSBgJHNldCgpYCBhbmQgcmV0dXJuIGB0aGlzYCBpZiB0aGUgcXVlcnkgd2Fzbid0IG1vZGlmaWVkXG4gICAgICAgIC8vIGluIGEgd2F5IHRoYXQgd291bGQgcmVtb3ZlIHRoZSBgcGF0Y2goKWAgY29tbWFuZCwgZS5nLiB0b0ZpbmRRdWVyeSgpXG4gICAgICAgIHF1ZXJ5LmhhcygncGF0Y2gnKSA/IHRoaXMuJHNldChyZXN1bHQpIDogcmVzdWx0XG4gICAgICApXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJHRyYW5zYWN0aW9uKHRyeCwgaGFuZGxlcikge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRyYW5zYWN0aW9uKHRyeCwgaGFuZGxlcilcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgdHJhbnNhY3Rpb24odHJ4LCBoYW5kbGVyKSB7XG4gICAgLy8gU3VwcG9ydCBib3RoIGB0cmFuc2FjdGlvbih0cngsIGhhbmRsZXIpYCAmIGB0cmFuc2FjdGlvbihoYW5kbGVyKWBcbiAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgIGhhbmRsZXIgPSB0cnhcbiAgICAgIHRyeCA9IG51bGxcbiAgICB9XG4gICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgIC8vIFVzZSBleGlzdGluZyB0cmFuc2FjdGlvbiwgb3IgY3JlYXRlIG5ldyBvbmUsIHRvIGV4ZWN1dGUgaGFuZGxlciB3aXRoOlxuICAgICAgcmV0dXJuIHRyeFxuICAgICAgICA/IGhhbmRsZXIodHJ4KVxuICAgICAgICA6IHRoaXMua25leCgpLnRyYW5zYWN0aW9uKGhhbmRsZXIpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIGFyZ3VtZW50cywgc2ltcGx5IGRlbGVnYXRlIHRvIG9iamVjdGlvbidzIHRyYW5zYWN0aW9uKClcbiAgICAgIHJldHVybiBzdXBlci50cmFuc2FjdGlvbigpXG4gICAgfVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gICR2YWxpZGF0ZShqc29uLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAob3B0aW9ucy5za2lwVmFsaWRhdGlvbikge1xuICAgICAgcmV0dXJuIGpzb25cbiAgICB9XG4gICAgaWYgKCFvcHRpb25zLmdyYXBoICYmICFvcHRpb25zLmFzeW5jKSB7XG4gICAgICAvLyBGYWxsIGJhY2sgdG8gT2JqZWN0aW9uJ3MgJHZhbGlkYXRlKCkgaWYgd2UgZG9uJ3QgbmVlZCBhbnkgb2Ygb3VyXG4gICAgICAvLyBleHRlbnNpb25zIChhc3luYyBhbmQgZ3JhcGggZm9yIG5vdyk6XG4gICAgICByZXR1cm4gc3VwZXIuJHZhbGlkYXRlKGpzb24sIG9wdGlvbnMpXG4gICAgfVxuICAgIGpzb24gPSBqc29uIHx8IHRoaXNcbiAgICBjb25zdCBpbnB1dEpzb24gPSBqc29uXG4gICAgY29uc3Qgc2hhbGxvdyA9IGpzb24uJGlzT2JqZWN0aW9uTW9kZWwgJiYgIW9wdGlvbnMuZ3JhcGhcbiAgICBpZiAoc2hhbGxvdykge1xuICAgICAgLy8gU3RyaXAgYXdheSByZWxhdGlvbnMgYW5kIG90aGVyIGludGVybmFsIHN0dWZmLlxuICAgICAganNvbiA9IGpzb24uY2xvbmUoeyBzaGFsbG93OiB0cnVlIH0pXG4gICAgICAvLyBXZSBjYW4gbXV0YXRlIGBqc29uYCBub3cgdGhhdCB3ZSB0b29rIGEgY29weSBvZiBpdC5cbiAgICAgIG9wdGlvbnMgPSB7IC4uLm9wdGlvbnMsIG11dGFibGU6IHRydWUgfVxuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkYXRvciA9IHRoaXMuY29uc3RydWN0b3IuZ2V0VmFsaWRhdG9yKClcbiAgICBjb25zdCBhcmdzID0ge1xuICAgICAgb3B0aW9ucyxcbiAgICAgIG1vZGVsOiB0aGlzLFxuICAgICAganNvbixcbiAgICAgIGN0eDogT2JqZWN0LmNyZWF0ZShudWxsKVxuICAgIH1cblxuICAgIHZhbGlkYXRvci5iZWZvcmVWYWxpZGF0ZShhcmdzKVxuICAgIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRvci52YWxpZGF0ZShhcmdzKVxuICAgIGNvbnN0IGhhbmRsZVJlc3VsdCA9IHJlc3VsdCA9PiB7XG4gICAgICB2YWxpZGF0b3IuYWZ0ZXJWYWxpZGF0ZShhcmdzKVxuICAgICAgLy8gSWYgYGpzb25gIHdhcyBzaGFsbG93LWNsb25lZCwgY29weSBvdmVyIHRoZSBwb3NzaWJsZSBkZWZhdWx0IHZhbHVlcy5cbiAgICAgIHJldHVybiBzaGFsbG93ID8gaW5wdXRKc29uLiRzZXQocmVzdWx0KSA6IHJlc3VsdFxuICAgIH1cbiAgICAvLyBIYW5kbGUgYm90aCBhc3luYyBhbmQgc3luYyB2YWxpZGF0aW9uIGhlcmU6XG4gICAgcmV0dXJuIGlzUHJvbWlzZShyZXN1bHQpXG4gICAgICA/IHJlc3VsdC50aGVuKGhhbmRsZVJlc3VsdClcbiAgICAgIDogaGFuZGxlUmVzdWx0KHJlc3VsdClcbiAgfVxuXG4gIGFzeW5jICR2YWxpZGF0ZUdyYXBoKG9wdGlvbnMgPSB7fSkge1xuICAgIGF3YWl0IHRoaXMuJHZhbGlkYXRlKG51bGwsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBncmFwaDogdHJ1ZSxcbiAgICAgIC8vIEFsd2F5cyB1c2UgYGFzeW5jOiB0cnVlYCBvcHRpb24gaGVyZSBmb3Igc2ltcGxpY2l0eTpcbiAgICAgIGFzeW5jOiB0cnVlXG4gICAgfSlcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIHN0YXRpYyBmcm9tSnNvbihqc29uLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAob3B0aW9ucy5hc3luYyAmJiAhb3B0aW9ucy5za2lwVmFsaWRhdGlvbikge1xuICAgICAgLy8gSGFuZGxlIGFzeW5jIHZhbGlkYXRpb24sIGFzIHN1cHBvcnRlZCBieSBEaXRvOlxuICAgICAgY29uc3QgbW9kZWwgPSBuZXcgdGhpcygpXG4gICAgICByZXR1cm4gbW9kZWwuJHZhbGlkYXRlKGpzb24sIG9wdGlvbnMpLnRoZW4oXG4gICAgICAgIGpzb24gPT4gbW9kZWwuJHNldEpzb24oanNvbiwge1xuICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgc2tpcFZhbGlkYXRpb246IHRydWVcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICB9XG4gICAgLy8gRmFsbCBiYWNrIHRvIE9iamVjdGlvbidzIGZyb21Kc29uKCkgaWYgd2UgZG9uJ3QgbmVlZCBhc3luYyBoYW5kbGluZzpcbiAgICByZXR1cm4gc3VwZXIuZnJvbUpzb24oanNvbiwgb3B0aW9ucylcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgcXVlcnkodHJ4KSB7XG4gICAgcmV0dXJuIHN1cGVyLnF1ZXJ5KHRyeCkub25FcnJvcihlcnIgPT4ge1xuICAgICAgLy8gVE9ETzogU2hvdWxkbid0IHRoaXMgd3JhcHBpbmcgaGFwcGVuIG9uIHRoZSBDb250cm9sbGVyIGxldmVsP1xuICAgICAgZXJyID0gZXJyIGluc3RhbmNlb2YgUmVzcG9uc2VFcnJvciA/IGVyclxuICAgICAgICA6IGVyciBpbnN0YW5jZW9mIG9iamVjdGlvbi5EQkVycm9yID8gdGhpcy5hcHAuY3JlYXRlRGF0YWJhc2VFcnJvcihlcnIpXG4gICAgICAgIDogbmV3IFdyYXBwZWRFcnJvcihlcnIpXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKVxuICAgIH0pXG4gIH1cblxuICBzdGF0aWMgYXN5bmMgY291bnQoLi4uYXJncykge1xuICAgIGNvbnN0IHsgY291bnQgfSA9IGF3YWl0IHRoaXMucXVlcnkoKS5jb3VudCguLi5hcmdzKS5maXJzdCgpIHx8IHt9XG4gICAgcmV0dXJuICtjb3VudCB8fCAwXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgLy8gSWYgdGhlIGNsYXNzIG5hbWUgZW5kcyBpbiAnTW9kZWwnLCByZW1vdmUgdGhhdCBmcm9tIHRoZSB0YWJsZSBuYW1lLlxuICAgIHJldHVybiB0aGlzLm5hbWUubWF0Y2goL14oLio/KSg/Ok1vZGVsfCkkLylbMV1cbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgZ2V0IGlkQ29sdW1uKCkge1xuICAgIC8vIFRyeSBleHRyYWN0aW5nIHRoZSBpZCBjb2x1bW4gbmFtZSBmcm9tIHRoZSByYXcgcHJvcGVydGllcyBkZWZpbml0aW9ucyxcbiAgICAvLyBub3QgdGhlIHJlc29sdmVkIGBkZWZpbml0aW9uLnByb3BlcnRpZXNgIHdoaWNoIGFyZW4ndCByZWFkeSBhdCB0aGlzIHBvaW50XG4gICAgLy8gd2l0aCBmYWxsLWJhY2sgb250byBkZWZhdWx0IE9iamVjdGlvbi5qcyBiZWhhdmlvci5cbiAgICBjb25zdCB7IHByb3BlcnRpZXMgfSA9IHRoaXNcbiAgICBjb25zdCBpZHMgPSBbXVxuICAgIGZvciAoY29uc3QgW25hbWUsIHByb3BlcnR5XSBvZiBPYmplY3QuZW50cmllcyhwcm9wZXJ0aWVzIHx8IHt9KSkge1xuICAgICAgaWYgKHByb3BlcnR5Py5wcmltYXJ5KSB7XG4gICAgICAgIGlkcy5wdXNoKG5hbWUpXG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHsgbGVuZ3RoIH0gPSBpZHNcbiAgICByZXR1cm4gbGVuZ3RoID4gMSA/IGlkcyA6IGxlbmd0aCA+IDAgPyBpZHNbMF0gOiBzdXBlci5pZENvbHVtblxuICB9XG5cbiAgc3RhdGljIGdldFJlZmVyZW5jZShtb2RlbE9ySWQsIGluY2x1ZGVQcm9wZXJ0aWVzKSB7XG4gICAgLy8gQ3JlYXRlcyBhIHJlZmVyZW5jZSBtb2RlbCB0aGF0IHRha2VzIG92ZXIgdGhlIGlkIC8gI3JlZiBwcm9wZXJ0aWVzIGZyb21cbiAgICAvLyB0aGUgcGFzc2VkIG1vZGVsIG9yIGlkIHZhbHVlL2FycmF5LCBvbWl0dGluZyBhbnkgb3RoZXIgcHJvcGVydGllcyBpbiBpdCxcbiAgICAvLyBleGNlcHQgZm9yIGFueXRoaW5nIG1lbnRpb25lZCBpbiB0aGUgb3B0aW9uYWwgYGluY2x1ZGVQcm9wZXJ0aWVzYCBhcmcuXG4gICAgY29uc3QgcmVmID0gbmV3IHRoaXMoKVxuICAgIGNvbnN0IGlkUHJvcGVydGllcyA9IHRoaXMuZ2V0SWRQcm9wZXJ0eUFycmF5KClcbiAgICBpZiAoaXNPYmplY3QobW9kZWxPcklkKSkge1xuICAgICAgY29uc3QgYWRkUHJvcGVydHkgPSBrZXkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG1vZGVsT3JJZFtrZXldXG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmVmW2tleV0gPSB2YWx1ZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBBbHNvIHN1cHBvcnQgT2JqZWN0aW9uJ3MgI3JlZiB0eXBlIHJlZmVyZW5jZXMgbmV4dCB0byBpZCBwcm9wZXJ0aWVzLlxuICAgICAgYWRkUHJvcGVydHkodGhpcy51aWRSZWZQcm9wKVxuICAgICAgaWRQcm9wZXJ0aWVzLmZvckVhY2goYWRkUHJvcGVydHkpXG4gICAgICBpbmNsdWRlUHJvcGVydGllcz8uZm9yRWFjaChhZGRQcm9wZXJ0eSlcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQW4gaWQgdmFsdWUvYXJyYXk6IE1hcCBpdCB0byB0aGUgcHJvcGVydGllcyBpbiBgZ2V0SWRQcm9wZXJ0eUFycmF5KClgOlxuICAgICAgY29uc3QgaWRzID0gYXNBcnJheShtb2RlbE9ySWQpXG4gICAgICBpZiAoaWRzLmxlbmd0aCAhPT0gaWRQcm9wZXJ0aWVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgTW9kZWxFcnJvcihcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGBJbnZhbGlkIGFtb3VudCBvZiBpZCB2YWx1ZXMgcHJvdmlkZWQgZm9yIHJlZmVyZW5jZTogVW5hYmxlIHRvIG1hcCAke1xuICAgICAgICAgICAgZm9ybWF0SnNvbihtb2RlbE9ySWQsIGZhbHNlKVxuICAgICAgICAgIH0gdG8gJHtcbiAgICAgICAgICAgIGZvcm1hdEpzb24oaWRQcm9wZXJ0aWVzLCBmYWxzZSlcbiAgICAgICAgICB9LmBcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgaWRQcm9wZXJ0aWVzLmZvckVhY2goKGtleSwgaW5kZXgpID0+IHtcbiAgICAgICAgcmVmW2tleV0gPSBpZHNbaW5kZXhdXG4gICAgICB9KVxuICAgIH1cbiAgICByZXR1cm4gcmVmXG4gIH1cblxuICBzdGF0aWMgaXNSZWZlcmVuY2Uob2JqKSB7XG4gICAgbGV0IHZhbGlkYXRvciA9IHRoaXMucmVmZXJlbmNlVmFsaWRhdG9yXG4gICAgaWYgKCF2YWxpZGF0b3IpIHtcbiAgICAgIC8vIEZvciBgZGF0YWAgdG8gYmUgY29uc2lkZXJlZCBhIHJlZmVyZW5jZSwgaXQgbmVlZHMgdG8gaG9sZCBvbmx5IG9uZVxuICAgICAgLy8gdmFsdWUgdGhhdCBpcyBlaXRoZXIgdGhlIHRhcmdldCdzIGlkLCBvciBhbiBPYmplY3Rpb24uanMgI3JlZiB2YWx1ZTpcbiAgICAgIHZhbGlkYXRvciA9IHRoaXMucmVmZXJlbmNlVmFsaWRhdG9yID0gdGhpcy5hcHAuY29tcGlsZVZhbGlkYXRvcihcbiAgICAgICAge1xuICAgICAgICAgIG9uZU9mOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICAvLyBTdXBwb3J0IGNvbXBvc2l0ZSBrZXlzIGFuZCBhZGQgYSBwcm9wZXJ0eSBmb3IgZWFjaCBrZXk6XG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHRoaXMuZ2V0SWRQcm9wZXJ0eUFycmF5KCkucmVkdWNlKFxuICAgICAgICAgICAgICAgIChpZFByb3BlcnRpZXMsIGlkUHJvcGVydHkpID0+IHtcbiAgICAgICAgICAgICAgICAgIGlkUHJvcGVydGllc1tpZFByb3BlcnR5XSA9IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdGhpcy5kZWZpbml0aW9uLnByb3BlcnRpZXNbaWRQcm9wZXJ0eV0udHlwZVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGlkUHJvcGVydGllc1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge31cbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIFt0aGlzLnVpZFJlZlByb3BdOiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgICAvLyBSZWNlaXZlIGBmYWxzZWAgaW5zdGVhZCBvZiB0aHJvd24gZXhjZXB0aW9ucyB3aGVuIHZhbGlkYXRpb24gZmFpbHM6XG4gICAgICAgIHsgdGhyb3c6IGZhbHNlIH1cbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIHZhbGlkYXRvcihvYmopXG4gIH1cblxuICBzdGF0aWMgZ2V0U2NvcGUobmFtZSkge1xuICAgIHJldHVybiB0aGlzLmRlZmluaXRpb24uc2NvcGVzW25hbWVdXG4gIH1cblxuICBzdGF0aWMgaGFzU2NvcGUobmFtZSkge1xuICAgIHJldHVybiAhIXRoaXMuZ2V0U2NvcGUobmFtZSlcbiAgfVxuXG4gIHN0YXRpYyBnZXRNb2RpZmllcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVmaW5pdGlvbi5tb2RpZmllcnNcbiAgfVxuXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0Q2FjaGVkKCdyZWxhdGlvbk1hcHBpbmdzJywgKCkgPT4gKFxuICAgICAgY29udmVydFJlbGF0aW9ucyh0aGlzLCB0aGlzLmRlZmluaXRpb24ucmVsYXRpb25zLCB0aGlzLmFwcC5tb2RlbHMpXG4gICAgKSwge30pXG4gIH1cblxuICBzdGF0aWMgZ2V0IGpzb25TY2hlbWEoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldENhY2hlZCgnanNvblNjaGVtYScsICgpID0+IHtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IGNvbnZlcnRTY2hlbWEodGhpcy5kZWZpbml0aW9uLnByb3BlcnRpZXMpXG4gICAgICBhZGRSZWxhdGlvblNjaGVtYXModGhpcywgc2NoZW1hLnByb3BlcnRpZXMpXG4gICAgICAvLyBNZXJnZSBpbiByb290LWxldmVsIHNjaGVtYSBhZGRpdGlvbnNcbiAgICAgIG1lcmdlKHNjaGVtYSwgdGhpcy5kZWZpbml0aW9uLnNjaGVtYSlcbiAgICAgIHJldHVybiB7XG4gICAgICAgICRpZDogdGhpcy5uYW1lLFxuICAgICAgICAkc2NoZW1hOiAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEnLFxuICAgICAgICAuLi5zY2hlbWFcbiAgICAgIH1cbiAgICB9LCB7fSlcbiAgfVxuXG4gIHN0YXRpYyBnZXQgdmlydHVhbEF0dHJpYnV0ZXMoKSB7XG4gICAgLy8gTGV2ZXJhZ2UgT2JqZWN0aW9uJ3Mgb3duIG1lY2hhbmlzbSBjYWxsZWQgYHZpcnR1YWxBdHRyaWJ1dGVzYCB0byBoYW5kbGVcbiAgICAvLyBgY29tcHV0ZWRBdHRyaWJ1dGVzYCB3aGVuIHNldHRpbmcgSlNPTiBkYXRhLlxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVkQXR0cmlidXRlc1xuICB9XG5cbiAgc3RhdGljIGdldCBqc29uQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0Q2FjaGVkKCdqc29uU2NoZW1hOmpzb25BdHRyaWJ1dGVzJywgKCkgPT4gKFxuICAgICAgdGhpcy5nZXRBdHRyaWJ1dGVzKCh7IHR5cGUsIHNwZWNpZmljVHlwZSwgY29tcHV0ZWQgfSkgPT5cbiAgICAgICAgIWNvbXB1dGVkICYmICFzcGVjaWZpY1R5cGUgJiYgKHR5cGUgPT09ICdvYmplY3QnIHx8IHR5cGUgPT09ICdhcnJheScpKVxuICAgICksIFtdKVxuICB9XG5cbiAgc3RhdGljIGdldCBib29sZWFuQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0Q2FjaGVkKCdqc29uU2NoZW1hOmJvb2xlYW5BdHRyaWJ1dGVzJywgKCkgPT4gKFxuICAgICAgdGhpcy5nZXRBdHRyaWJ1dGVzKCh7IHR5cGUsIGNvbXB1dGVkIH0pID0+XG4gICAgICAgICFjb21wdXRlZCAmJiB0eXBlID09PSAnYm9vbGVhbicpXG4gICAgKSwgW10pXG4gIH1cblxuICBzdGF0aWMgZ2V0IGRhdGVBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRDYWNoZWQoJ2pzb25TY2hlbWE6ZGF0ZUF0dHJpYnV0ZXMnLCAoKSA9PiAoXG4gICAgICB0aGlzLmdldEF0dHJpYnV0ZXMoKHsgdHlwZSwgY29tcHV0ZWQgfSkgPT5cbiAgICAgICAgIWNvbXB1dGVkICYmIFsnZGF0ZScsICdkYXRldGltZScsICd0aW1lc3RhbXAnXS5pbmNsdWRlcyh0eXBlKSlcbiAgICApLCBbXSlcbiAgfVxuXG4gIHN0YXRpYyBnZXQgY29tcHV0ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRDYWNoZWQoJ2pzb25TY2hlbWE6Y29tcHV0ZWRBdHRyaWJ1dGVzJywgKCkgPT4gKFxuICAgICAgdGhpcy5nZXRBdHRyaWJ1dGVzKCh7IGNvbXB1dGVkIH0pID0+IGNvbXB1dGVkKVxuICAgICksIFtdKVxuICB9XG5cbiAgc3RhdGljIGdldCBoaWRkZW5BdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRDYWNoZWQoJ2pzb25TY2hlbWE6aGlkZGVuQXR0cmlidXRlcycsICgpID0+IChcbiAgICAgIHRoaXMuZ2V0QXR0cmlidXRlcygoeyBoaWRkZW4gfSkgPT4gaGlkZGVuKVxuICAgICksIFtdKVxuICB9XG5cbiAgc3RhdGljIGdldEF0dHJpYnV0ZXMoZmlsdGVyKSB7XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IFtdXG4gICAgY29uc3QgeyBwcm9wZXJ0aWVzIH0gPSB0aGlzLmRlZmluaXRpb25cbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBwcm9wZXJ0eV0gb2YgT2JqZWN0LmVudHJpZXMocHJvcGVydGllcykpIHtcbiAgICAgIGlmIChmaWx0ZXIocHJvcGVydHkpKSB7XG4gICAgICAgIGF0dHJpYnV0ZXMucHVzaChuYW1lKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXR0cmlidXRlc1xuICB9XG5cbiAgc3RhdGljIF9nZXRDYWNoZWQoaWRlbnRpZmllciwgY2FsY3VsYXRlLCBlbXB0eSA9IHt9KSB7XG4gICAgbGV0IGNhY2hlID0gZ2V0TWV0YSh0aGlzLCAnY2FjaGUnLCB7fSlcbiAgICAvLyBVc2UgYSBzaW1wbGUgZGVwZW5kZW5jeSB0cmFja2luZyBtZWNoYW5pc20gd2l0aCBjYWNoZSBpZGVudGlmaWVycyB0aGF0XG4gICAgLy8gY2FuIGJlIGNoaWxkcmVuIG9mIG90aGVyIGNhY2hlZCB2YWx1ZXMsIGUuZy46XG4gICAgLy8gJ2pzb25TY2hlbWE6anNvbkF0dHJpYnV0ZXMnIGFzIGEgY2hpbGQgb2YgJ2pzb25TY2hlbWEnLCBzbyB0aGF0IHdoZW5ldmVyXG4gICAgLy8gJ2pzb25TY2hlbWEnIGNoYW5nZXMsIGFsbCBjYWNoZWQgY2hpbGQgdmFsdWVzICBhcmUgaW52YWxpZGF0ZWQuXG4gICAgbGV0IGVudHJ5XG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIGlkZW50aWZpZXIuc3BsaXQoJzonKSkge1xuICAgICAgZW50cnkgPSBjYWNoZVtwYXJ0XSA9IGNhY2hlW3BhcnRdIHx8IHtcbiAgICAgICAgY2FjaGU6IHt9LFxuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkXG4gICAgICB9XG4gICAgICBjYWNoZSA9IGVudHJ5LmNhY2hlXG4gICAgfVxuICAgIGlmIChlbnRyeT8udmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gVGVtcG9yYXJpbHkgc2V0IGNhY2hlIHRvIGFuIGVtcHR5IG9iamVjdCB0byBwcmV2ZW50IGVuZGxlc3NcbiAgICAgIC8vIHJlY3Vyc2lvbiB3aXRoIGludGVyZGVwZW5kZW50IGpzb25TY2hlbWEgcmVsYXRlZCBjYWxscy4uLlxuICAgICAgZW50cnkudmFsdWUgPSBlbXB0eVxuICAgICAgZW50cnkudmFsdWUgPSBjYWxjdWxhdGUoKVxuICAgICAgLy8gQ2xlYXIgY2hpbGQgZGVwZW5kZW5jaWVzIG9uY2UgcGFyZW50IHZhbHVlIGhhcyBjaGFuZ2VkOlxuICAgICAgZW50cnkuY2FjaGUgPSB7fVxuICAgIH1cbiAgICByZXR1cm4gZW50cnk/LnZhbHVlXG4gIH1cblxuICBzdGF0aWMgZ2V0UmVsYXRlZFJlbGF0aW9ucygpIHtcbiAgICByZXR1cm4gZ2V0TWV0YSh0aGlzLCAncmVsYXRlZFJlbGF0aW9ucycsIFtdKVxuICB9XG5cbiAgLy8gT3ZlcnJpZGUgcHJvcGVydHlOYW1lVG9Db2x1bW5OYW1lKCkgLyBjb2x1bW5OYW1lVG9Qcm9wZXJ0eU5hbWUoKSB0byBub3RcbiAgLy8gcmVseSBvbiAkZm9ybWF0RGF0YWJhc2VKc29uKCkgLyAgJHBhcnNlRGF0YWJhc2VKc29uKCkgZG8gZGV0ZWN0IG5hbWluZ1xuICAvLyBjb252ZW50aW9ucyBidXQgYXNzdW1lIHNpbXBseSB0aGF0IHRoZXkncmUgYWx3YXlzIHRoZSBzYW1lLlxuICAvLyBUaGlzIGlzIGZpbmUgc2luY2Ugd2UgY2FuIG5vdyBjaGFuZ2UgbmFtaW5nIGF0IEtuZXggbGV2ZWwuXG4gIC8vIFNlZSBrbmV4U25ha2VDYXNlTWFwcGVycygpXG5cbiAgLy8gQG92ZXJyaWRlXG4gIHN0YXRpYyBwcm9wZXJ0eU5hbWVUb0NvbHVtbk5hbWUocHJvcGVydHlOYW1lKSB7XG4gICAgcmV0dXJuIHByb3BlcnR5TmFtZVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIHN0YXRpYyBjb2x1bW5OYW1lVG9Qcm9wZXJ0eU5hbWUoY29sdW1uTmFtZSkge1xuICAgIHJldHVybiBjb2x1bW5OYW1lXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJHNldEpzb24oanNvbiwgb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG4gICAgY29uc3QgY2FsbEluaXRpYWxpemUgPSAoXG4gICAgICAvLyBPbmx5IGNhbGwgaW5pdGlhbGl6ZSB3aGVuOlxuICAgICAgLy8gMS4gd2UncmUgbm90IHBhcnRpYWxseSBwYXRjaGluZzpcbiAgICAgICFvcHRpb25zLnBhdGNoICYmXG4gICAgICAvLyAyLiAkaW5pdGlhbGl6ZSgpIGlzIGFjdHVhbGx5IGRvaW5nIHNvbWV0aGluZzpcbiAgICAgIHRoaXMuJGluaXRpYWxpemUgIT09IE1vZGVsLnByb3RvdHlwZS4kaW5pdGlhbGl6ZSAmJlxuICAgICAgLy8gMy4gdGhlIGRhdGEgaXMgbm90IGp1c3QgYSByZWZlcmVuY2U6XG4gICAgICAhdGhpcy5jb25zdHJ1Y3Rvci5pc1JlZmVyZW5jZShqc29uKVxuICAgIClcbiAgICBpZiAoIWNhbGxJbml0aWFsaXplIHx8IG9wdGlvbnMuc2tpcFZhbGlkYXRpb24pIHtcbiAgICAgIHN1cGVyLiRzZXRKc29uKGpzb24sIG9wdGlvbnMpXG4gICAgICBpZiAoY2FsbEluaXRpYWxpemUpIHtcbiAgICAgICAgdGhpcy4kaW5pdGlhbGl6ZSgpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHZhbGlkYXRpb24gaXNuJ3Qgc2tpcHBlZCBvciB0aGUgbW9kZWwgcHJvdmlkZXMgaXRzIG93biAkaW5pdGlhbGl6ZSgpXG4gICAgICAvLyBtZXRob2QsIGNhbGwgJHNldEpzb24oKSB3aXRoIHBhdGNoIHZhbGlkYXRpb24gZmlyc3QgdG8gbm90IGNvbXBsYWluXG4gICAgICAvLyBhYm91dCBtaXNzaW5nIGZpZWxkcywgdGhlbiBwZXJmb3JtIGEgZnVsbCB2YWxpZGF0aW9uIGFmdGVyIGNhbGxpbmdcbiAgICAgIC8vICRpbml0aWFsaXplKCksIHRvIGdpdmUgdGhlIG1vZGVsIGEgY2hhbmNlIHRvIGNvbmZpZ3VyZSBpdHNlbGYuXG4gICAgICBzdXBlci4kc2V0SnNvbihqc29uLCB7IC4uLm9wdGlvbnMsIHBhdGNoOiB0cnVlIH0pXG4gICAgICB0aGlzLiRpbml0aWFsaXplKClcbiAgICAgIHRoaXMuJHZhbGlkYXRlKHRoaXMsIG9wdGlvbnMpXG4gICAgfVxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJGZvcm1hdERhdGFiYXNlSnNvbihqc29uKSB7XG4gICAgY29uc3QgeyBjb25zdHJ1Y3RvciB9ID0gdGhpc1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGNvbnN0cnVjdG9yLmRhdGVBdHRyaWJ1dGVzKSB7XG4gICAgICBjb25zdCBkYXRlID0ganNvbltrZXldXG4gICAgICBpZiAoZGF0ZT8udG9JU09TdHJpbmcpIHtcbiAgICAgICAganNvbltrZXldID0gZGF0ZS50b0lTT1N0cmluZygpXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChjb25zdHJ1Y3Rvci5pc1NRTGl0ZSgpKSB7XG4gICAgICAvLyBTUUxpdGUgZG9lcyBub3Qgc3VwcG9ydCBib29sZWFuIG5hdGl2ZWx5IGFuZCBuZWVkcyBjb252ZXJzaW9uLi4uXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBjb25zdHJ1Y3Rvci5ib29sZWFuQXR0cmlidXRlcykge1xuICAgICAgICBjb25zdCBib29sID0ganNvbltrZXldXG4gICAgICAgIGlmIChib29sICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBqc29uW2tleV0gPSBib29sID8gMSA6IDBcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBSZW1vdmUgdGhlIGNvbXB1dGVkIHByb3BlcnRpZXMgc28gdGhleSBkb24ndCBhdHRlbXB0IHRvIGdldCBzZXQuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgY29uc3RydWN0b3IuY29tcHV0ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICBkZWxldGUganNvbltrZXldXG4gICAgfVxuICAgIC8vIE5PVEU6IE5vIG5lZWQgdG8gbm9ybWFsaXplIHRoZSBpZGVudGlmaWVycyBpbiB0aGUgSlNPTiBpbiBjYXNlIG9mXG4gICAgLy8gbm9ybWFsaXplRGJOYW1lcywgYXMgdGhpcyBhbHJlYWR5IGhhcHBlbnMgdGhyb3VnaFxuICAgIC8vIGtuZXguY29uZmlnLndyYXBJZGVudGlmaWVyKCksIHNlZSBBcHBsaWNhdGlvbi5qc1xuICAgIHJldHVybiBzdXBlci4kZm9ybWF0RGF0YWJhc2VKc29uKGpzb24pXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJHBhcnNlRGF0YWJhc2VKc29uKGpzb24pIHtcbiAgICBjb25zdCB7IGNvbnN0cnVjdG9yIH0gPSB0aGlzXG4gICAganNvbiA9IHN1cGVyLiRwYXJzZURhdGFiYXNlSnNvbihqc29uKVxuICAgIGlmIChjb25zdHJ1Y3Rvci5pc1NRTGl0ZSgpKSB7XG4gICAgICAvLyBTUUxpdGUgZG9lcyBub3Qgc3VwcG9ydCBib29sZWFuIG5hdGl2ZWx5IGFuZCBuZWVkcyBjb252ZXJzaW9uLi4uXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBjb25zdHJ1Y3Rvci5ib29sZWFuQXR0cmlidXRlcykge1xuICAgICAgICBjb25zdCBib29sID0ganNvbltrZXldXG4gICAgICAgIGlmIChib29sICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBqc29uW2tleV0gPSAhIWJvb2xcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBBbHNvIHJ1biB0aHJvdWdoIG5vcm1hbCAkcGFyc2VKc29uKCksIGZvciBoYW5kbGluZyBvZiBgRGF0ZWAgYW5kXG4gICAgLy8gYEFzc2V0RmlsZWAuXG4gICAgcmV0dXJuIHRoaXMuJHBhcnNlSnNvbihqc29uKVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gICRwYXJzZUpzb24oanNvbikge1xuICAgIGNvbnN0IHsgY29uc3RydWN0b3IgfSA9IHRoaXNcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBjb25zdHJ1Y3Rvci5kYXRlQXR0cmlidXRlcykge1xuICAgICAgY29uc3QgZGF0ZSA9IGpzb25ba2V5XVxuICAgICAgaWYgKGRhdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBqc29uW2tleV0gPSBpc1N0cmluZyhkYXRlKSA/IG5ldyBEYXRlKGRhdGUpIDogZGF0ZVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBDb252ZXJ0IHBsYWluIGFzc2V0IGZpbGVzIG9iamVjdHMgdG8gQXNzZXRGaWxlIGluc3RhbmNlcyB3aXRoIHJlZmVyZW5jZXNcbiAgICAvLyB0byB0aGUgbGlua2VkIHN0b3JhZ2UuXG4gICAgY29uc3QgeyBhc3NldHMgfSA9IGNvbnN0cnVjdG9yLmRlZmluaXRpb25cbiAgICBpZiAoYXNzZXRzKSB7XG4gICAgICBmb3IgKGNvbnN0IGRhdGFQYXRoIGluIGFzc2V0cykge1xuICAgICAgICBjb25zdCBzdG9yYWdlID0gY29uc3RydWN0b3IuYXBwLmdldFN0b3JhZ2UoYXNzZXRzW2RhdGFQYXRoXS5zdG9yYWdlKVxuICAgICAgICBjb25zdCBkYXRhID0gZ2V0VmFsdWVBdERhdGFQYXRoKGpzb24sIGRhdGFQYXRoLCAoKSA9PiBudWxsKVxuICAgICAgICBpZiAoZGF0YSkge1xuICAgICAgICAgIGNvbnN0IGNvbnZlcnRUb0Fzc2V0RmlsZXMgPSBkYXRhID0+IHtcbiAgICAgICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgICAgIGlmIChpc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgZGF0YS5mb3JFYWNoKGNvbnZlcnRUb0Fzc2V0RmlsZXMpXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RvcmFnZS5jb252ZXJ0QXNzZXRGaWxlKGRhdGEpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY29udmVydFRvQXNzZXRGaWxlcyhkYXRhKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBqc29uXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJGZvcm1hdEpzb24oanNvbikge1xuICAgIGNvbnN0IHsgY29uc3RydWN0b3IgfSA9IHRoaXNcbiAgICAvLyBDYWxjdWxhdGUgYW5kIHNldCB0aGUgY29tcHV0ZWQgcHJvcGVydGllcy5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBjb25zdHJ1Y3Rvci5jb21wdXRlZEF0dHJpYnV0ZXMpIHtcbiAgICAgIC8vIFBlcmhhcHMgdGhlIGNvbXB1dGVkIHByb3BlcnR5IGlzIHByb2R1Y2VkIGluIHRoZSBTUUwgc3RhdGVtZW50LFxuICAgICAgLy8gaW4gd2hpY2ggY2FzZSB3ZSBkb24ndCBoYXZlIHRvIGRvIGFueXRoaW5nIGFueW1vcmUgaGVyZS5cbiAgICAgIGlmICghKGtleSBpbiBqc29uKSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXNba2V5XVxuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGpzb25ba2V5XSA9IHZhbHVlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gUmVtb3ZlIGhpZGRlbiBhdHRyaWJ1dGVzLlxuICAgIGZvciAoY29uc3Qga2V5IG9mIGNvbnN0cnVjdG9yLmhpZGRlbkF0dHJpYnV0ZXMpIHtcbiAgICAgIGRlbGV0ZSBqc29uW2tleV1cbiAgICB9XG4gICAgcmV0dXJuIGpzb25cbiAgfVxuXG4gIC8vIEdyYXBoIGhhbmRsaW5nXG5cbiAgJGZpbHRlckdyYXBoKG1vZGVsR3JhcGgsIGV4cHIpIHtcbiAgICByZXR1cm4gZmlsdGVyR3JhcGgodGhpcy5jb25zdHJ1Y3RvciwgbW9kZWxHcmFwaCwgZXhwcilcbiAgfVxuXG4gIGFzeW5jICRwb3B1bGF0ZUdyYXBoKG1vZGVsR3JhcGgsIGV4cHIsIHRyeCkge1xuICAgIHJldHVybiBwb3B1bGF0ZUdyYXBoKHRoaXMuY29uc3RydWN0b3IsIG1vZGVsR3JhcGgsIGV4cHIsIHRyeClcbiAgfVxuXG4gIHN0YXRpYyBmaWx0ZXJHcmFwaChtb2RlbEdyYXBoLCBleHByKSB7XG4gICAgcmV0dXJuIGZpbHRlckdyYXBoKHRoaXMsIG1vZGVsR3JhcGgsIGV4cHIpXG4gIH1cblxuICBzdGF0aWMgYXN5bmMgcG9wdWxhdGVHcmFwaChtb2RlbEdyYXBoLCBleHByLCB0cngpIHtcbiAgICByZXR1cm4gcG9wdWxhdGVHcmFwaCh0aGlzLCBtb2RlbEdyYXBoLCBleHByLCB0cngpXG4gIH1cblxuICBzdGF0aWMgZ2V0UHJvcGVydHlPclJlbGF0aW9uQXREYXRhUGF0aChkYXRhUGF0aCkge1xuICAgIC8vIEZpbmRzIHRoZSBwcm9wZXJ0eSBvciByZWxhdGlvbiBhdCB0aGUgZ2l2ZW4gdGhlIGRhdGFQYXRoIG9mIHRoZSBtb2RlbCBieVxuICAgIC8vIHBhcnNpbmcgdGhlIGRhdGFQYXRoIGFuZCBtYXRjaGluZyBpdCB0byBpdHMgcmVsYXRpb25zIGFuZCBwcm9wZXJ0aWVzLlxuICAgIGNvbnN0IHBhcnNlZERhdGFQYXRoID0gcGFyc2VEYXRhUGF0aChkYXRhUGF0aClcbiAgICBsZXQgaW5kZXggPSAwXG5cbiAgICBjb25zdCBnZXRSZXN1bHQgPSAocHJvcGVydHkgPSBudWxsLCByZWxhdGlvbiA9IG51bGwpID0+IHtcbiAgICAgIGNvbnN0IGZvdW5kID0gcHJvcGVydHkgfHwgcmVsYXRpb25cbiAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZWREYXRhUGF0aFtpbmRleF1cbiAgICAgIGNvbnN0IG5leHQgPSBpbmRleCArIDFcbiAgICAgIGNvbnN0IGRhdGFQYXRoID0gZm91bmRcbiAgICAgICAgPyBub3JtYWxpemVEYXRhUGF0aChwYXJzZWREYXRhUGF0aC5zbGljZSgwLCBuZXh0KSlcbiAgICAgICAgOiBudWxsXG4gICAgICBjb25zdCBuZXN0ZWREYXRhUGF0aCA9IGZvdW5kXG4gICAgICAgID8gbm9ybWFsaXplRGF0YVBhdGgocGFyc2VkRGF0YVBhdGguc2xpY2UobmV4dCkpXG4gICAgICAgIDogbnVsbFxuICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IGZvdW5kXG4gICAgICAgID8gcGFyc2VkRGF0YVBhdGguc2xpY2UoMCwgcmVsYXRpb24gPyBuZXh0IDogaW5kZXgpLmpvaW4oJy4nKSArXG4gICAgICAgICAgKHByb3BlcnR5ID8gYCgjJHtuYW1lfSlgIDogJycpXG4gICAgICAgIDogbnVsbFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcHJvcGVydHksXG4gICAgICAgIHJlbGF0aW9uLFxuICAgICAgICBkYXRhUGF0aCxcbiAgICAgICAgbmVzdGVkRGF0YVBhdGgsXG4gICAgICAgIG5hbWUsXG4gICAgICAgIGV4cHJlc3Npb24sXG4gICAgICAgIGluZGV4XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgW2ZpcnN0VG9rZW4sIC4uLm90aGVyVG9rZW5zXSA9IHBhcnNlZERhdGFQYXRoXG4gICAgY29uc3QgcHJvcGVydHkgPSB0aGlzLmRlZmluaXRpb24ucHJvcGVydGllc1tmaXJzdFRva2VuXVxuICAgIGlmIChwcm9wZXJ0eSkge1xuICAgICAgcmV0dXJuIGdldFJlc3VsdChwcm9wZXJ0eSlcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHJlbGF0aW9uID0gdGhpcy5nZXRSZWxhdGlvbnMoKVtmaXJzdFRva2VuXVxuICAgICAgaWYgKHJlbGF0aW9uKSB7XG4gICAgICAgIGxldCB7IHJlbGF0ZWRNb2RlbENsYXNzIH0gPSByZWxhdGlvblxuICAgICAgICBmb3IgKGNvbnN0IHRva2VuIG9mIG90aGVyVG9rZW5zKSB7XG4gICAgICAgICAgaW5kZXgrK1xuICAgICAgICAgIGNvbnN0IHByb3BlcnR5ID0gcmVsYXRlZE1vZGVsQ2xhc3MuZGVmaW5pdGlvbi5wcm9wZXJ0aWVzW3Rva2VuXVxuICAgICAgICAgIGlmIChwcm9wZXJ0eSkge1xuICAgICAgICAgICAgcmV0dXJuIGdldFJlc3VsdChwcm9wZXJ0eSlcbiAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuID09PSAnKicpIHtcbiAgICAgICAgICAgIGlmIChyZWxhdGlvbi5pc09uZVRvT25lKCkpIHtcbiAgICAgICAgICAgICAgLy8gRG8gbm90IHN1cHBvcnQgd2lsZGNhcmRzIG9uIG9uZS10by1vbmUgcmVsYXRpb25zOlxuICAgICAgICAgICAgICByZXR1cm4gZ2V0UmVzdWx0KClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEZvdW5kIGEgcmVsYXRpb24/IEtlZXAgaXRlcmF0aW5nLlxuICAgICAgICAgICAgcmVsYXRpb24gPSByZWxhdGVkTW9kZWxDbGFzcy5nZXRSZWxhdGlvbnMoKVt0b2tlbl1cbiAgICAgICAgICAgIGlmIChyZWxhdGlvbikge1xuICAgICAgICAgICAgICByZWxhdGVkTW9kZWxDbGFzcyA9IHJlbGF0aW9uLnJlbGF0ZWRNb2RlbENsYXNzXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0UmVzdWx0KClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlbGF0aW9uKSB7XG4gICAgICAgICAgLy8gU3RpbGwgaGVyZT8gRm91bmQgYSByZWxhdGlvbiBhdCB0aGUgZW5kIG9mIHRoZSBkYXRhLXBhdGguXG4gICAgICAgICAgcmV0dXJuIGdldFJlc3VsdChudWxsLCByZWxhdGlvbilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZ2V0UmVzdWx0KClcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgcmVsYXRlZFF1ZXJ5KHJlbGF0aW9uTmFtZSwgdHJ4KSB7XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL1ZpbmNpdC9vYmplY3Rpb24uanMvaXNzdWVzLzE3MjBcbiAgICByZXR1cm4gc3VwZXIucmVsYXRlZFF1ZXJ5KHJlbGF0aW9uTmFtZSwgdHJ4KS5hbGlhcyhyZWxhdGlvbk5hbWUpXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc3RhdGljIG1vZGlmaWVyTm90Rm91bmQocXVlcnksIG1vZGlmaWVyKSB7XG4gICAgaWYgKGlzU3RyaW5nKG1vZGlmaWVyKSkge1xuICAgICAgaWYgKHF1ZXJ5Lm1vZGVsQ2xhc3MoKS5oYXNTY29wZShtb2RpZmllcikpIHtcbiAgICAgICAgcmV0dXJuIHF1ZXJ5LmFwcGx5U2NvcGUobW9kaWZpZXIpXG4gICAgICB9XG4gICAgICAvLyBOb3cgY2hlY2sgcG9zc2libGUgc2NvcGUgcHJlZml4ZXMgYW5kIGhhbmRsZSB0aGVtOlxuICAgICAgc3dpdGNoIChtb2RpZmllclswXSkge1xuICAgICAgY2FzZSAnXic6IC8vIEVhZ2VyLWFwcGxpZWQgc2NvcGU6XG4gICAgICAgIC8vIEFsd2F5cyBhcHBseSBlYWdlci1zY29wZXMsIGV2ZW4gaWYgdGhlIG1vZGVsIGl0c2VsZiBkb2Vzbid0IGtub3cgaXQuXG4gICAgICAgIC8vIFRoZSBzY29wZSBtYXkgc3RpbGwgYmUga25vd24gaW4gZWFnZXItbG9hZGVkIHJlbGF0aW9ucy5cbiAgICAgICAgLy8gTm90ZTogYGFwcGx5U2NvcGUoKWAgd2lsbCBoYW5kbGUgdGhlICdeJyBzaWduLlxuICAgICAgICByZXR1cm4gcXVlcnkuYXBwbHlTY29wZShtb2RpZmllcilcbiAgICAgIGNhc2UgJy0nOiAvLyBJZ25vcmUgc2NvcGU6XG4gICAgICAgIHJldHVybiBxdWVyeS5pZ25vcmVTY29wZShtb2RpZmllci5zbGljZSgxKSlcbiAgICAgIGNhc2UgJyMnOiAvLyBTZWxlY3QgY29sdW1uOlxuICAgICAgICByZXR1cm4gcXVlcnkuc2VsZWN0KG1vZGlmaWVyLnNsaWNlKDEpKVxuICAgICAgfVxuICAgIH1cbiAgICBzdXBlci5tb2RpZmllck5vdEZvdW5kKHF1ZXJ5LCBtb2RpZmllcilcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgY3JlYXRlTm90Rm91bmRFcnJvcihjdHgsIGVycm9yKSB7XG4gICAgcmV0dXJuIG5ldyBOb3RGb3VuZEVycm9yKFxuICAgICAgZXJyb3IgfHwgKFxuICAgICAgICBjdHguYnlJZFxuICAgICAgICAgID8gYCcke3RoaXMubmFtZX0nIG1vZGVsIHdpdGggaWQgJHtjdHguYnlJZH0gbm90IGZvdW5kYFxuICAgICAgICAgIDogYCcke3RoaXMubmFtZX0nIG1vZGVsIG5vdCBmb3VuZGBcbiAgICAgIClcbiAgICApXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc3RhdGljIGNyZWF0ZVZhbGlkYXRvcigpIHtcbiAgICAvLyBVc2UgYSBzaGFyZWQgdmFsaWRhdG9yIHBlciBhcHAsIHNvIG1vZGVsIHNjaGVtYSBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIuXG4gICAgLy8gTk9URTogVGhlIERpdG8gVmFsaWRhdG9yIGNsYXNzIGNyZWF0ZXMgYW5kIG1hbmFnZXMgdGhpcyBzaGFyZWQgT2JqZWN0aW9uXG4gICAgLy8gVmFsaWRhdG9yIGluc3RhbmNlIGZvciB1cywgd2UganVzdCBuZWVkIHRvIHJldHVybiBpdCBoZXJlOlxuICAgIHJldHVybiB0aGlzLmFwcC52YWxpZGF0b3JcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgY3JlYXRlVmFsaWRhdGlvbkVycm9yKHsgdHlwZSwgbWVzc2FnZSwgZXJyb3JzLCBvcHRpb25zLCBqc29uIH0pIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdNb2RlbFZhbGlkYXRpb24nOlxuICAgICAgcmV0dXJuIHRoaXMuYXBwLmNyZWF0ZVZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgIHR5cGUsXG4gICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgbWVzc2FnZSB8fCBgVGhlIHByb3ZpZGVkIGRhdGEgZm9yIHRoZSAke3RoaXMubmFtZX0gbW9kZWwgaXMgbm90IHZhbGlkYCxcbiAgICAgICAgZXJyb3JzLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICBqc29uXG4gICAgICB9KVxuICAgIGNhc2UgJ1JlbGF0aW9uRXhwcmVzc2lvbic6XG4gICAgY2FzZSAnVW5hbGxvd2VkUmVsYXRpb24nOlxuICAgICAgcmV0dXJuIG5ldyBSZWxhdGlvbkVycm9yKHsgdHlwZSwgbWVzc2FnZSwgZXJyb3JzIH0pXG4gICAgY2FzZSAnSW52YWxpZEdyYXBoJzpcbiAgICAgIHJldHVybiBuZXcgR3JhcGhFcnJvcih7IHR5cGUsIG1lc3NhZ2UsIGVycm9ycyB9KVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbmV3IFJlc3BvbnNlRXJyb3IoeyB0eXBlLCBtZXNzYWdlLCBlcnJvcnMgfSlcbiAgICB9XG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc3RhdGljIFF1ZXJ5QnVpbGRlciA9IFF1ZXJ5QnVpbGRlclxuXG4gIC8vIGh0dHBzOi8vdmluY2l0LmdpdGh1Yi5pby9vYmplY3Rpb24uanMvYXBpL21vZGVsL3N0YXRpYy1wcm9wZXJ0aWVzLmh0bWwjc3RhdGljLWNsb25lb2JqZWN0YXR0cmlidXRlc1xuICBzdGF0aWMgY2xvbmVPYmplY3RBdHRyaWJ1dGVzID0gZmFsc2VcblxuICAvLyBPbmx5IHBpY2sgcHJvcGVydGllcyBmb3IgZGF0YWJhc2UgSlNPTiB0aGF0IGlzIG1lbnRpb25lZCBpbiB0aGUgc2NoZW1hLlxuICBzdGF0aWMgcGlja0pzb25TY2hlbWFQcm9wZXJ0aWVzID0gdHJ1ZVxuXG4gIC8vIFNlZSBodHRwczovL2dpdHRlci5pbS9WaW5jaXQvb2JqZWN0aW9uLmpzP2F0PTVhODFmODU5Y2U2OGMzYmM3NDc5ZDY1YVxuICBzdGF0aWMgdXNlTGltaXRJbkZpcnN0ID0gdHJ1ZVxuXG4gIHN0YXRpYyBnZXQgZGVmaW5pdGlvbigpIHtcbiAgICAvLyBDaGVjayBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBkZWZpbml0aW9uIG9iamVjdCBmb3IgdGhpcyBjbGFzcyBhbmQgcmV0dXJuIGl0XG4gICAgcmV0dXJuIGdldE1ldGEodGhpcywgJ2RlZmluaXRpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCBkZWZpbml0aW9uID0ge31cblxuICAgICAgY29uc3Qgc2V0RGVmaW5pdGlvbiA9IChuYW1lLCBwcm9wZXJ0eSkgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGVmaW5pdGlvbiwgbmFtZSwge1xuICAgICAgICAgIC4uLnByb3BlcnR5LFxuICAgICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgY29uc3QgZ2V0RGVmaW5pdGlvbiA9IG5hbWUgPT4ge1xuICAgICAgICBsZXQgbW9kZWxDbGFzcyA9IHRoaXNcbiAgICAgICAgLy8gQ29sbGVjdCBhbmNlc3RvciB2YWx1ZXMgZm9yIHByb3BlciBpbmhlcml0YW5jZS5cbiAgICAgICAgLy8gTk9URTogdmFsdWVzIGFyZSBjb2xsZWN0ZWQgaW4gc2VxdWVuY2Ugb2YgaW5oZXJpdGFuY2UsIGZyb20gc3ViLWNsYXNzXG4gICAgICAgIC8vIHRvIHN1cGVyLWNsYXNzLiBUbyBnbyBmcm9tIHN1cGVyLWNsYXNzIHRvIHN1Yi1jbGFzcyB3aGVuIG1lcmdpbmcsXG4gICAgICAgIC8vIGBtZXJnZVJldmVyc2VkKClgIGlzIHVzZWQgdG8gcHJldmVudCB3cm9uZyBvdmVycmlkZXMuXG4gICAgICAgIC8vIGBtZXJnZUFzUmV2ZXJzZWRBcnJheXMoKWAgY2FuIGJlIHVzZWQgdG8ga2VlcCBhcnJheXMgb2YgaW5oZXJpdGVkXG4gICAgICAgIC8vIHZhbHVlcyBwZXIga2V5LCBzZWUgYGRlZmluaXRpb25zLmhvb2tzYC5cbiAgICAgICAgY29uc3QgdmFsdWVzID0gW11cbiAgICAgICAgd2hpbGUgKG1vZGVsQ2xhc3MgIT09IG9iamVjdGlvbi5Nb2RlbCkge1xuICAgICAgICAgIC8vIE9ubHkgY29uc2lkZXIgbW9kZWwgY2xhc3NlcyB0aGF0IGFjdHVhbGx5IGRlZmluZSBgbmFtZWAgcHJvcGVydHkuXG4gICAgICAgICAgaWYgKG5hbWUgaW4gbW9kZWxDbGFzcykge1xuICAgICAgICAgICAgLy8gVXNlIHJlZmxlY3Rpb24gdGhyb3VnaCBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoKSB0byBiZSBhYmxlIHRvXG4gICAgICAgICAgICAvLyBjYWxsIHRoZSBnZXR0ZXIgb24gYHRoaXNgIHJhdGhlciB0aGFuIG9uIGBtb2RlbENsYXNzYC4gVGhpcyBjYW5cbiAgICAgICAgICAgIC8vIGJlIHVzZWQgdG8gcHJvdmlkZSBhYnN0cmFjdCBiYXNlLWNsYXNzZXMgYW5kIGhhdmUgdGhlbSBjcmVhdGVcbiAgICAgICAgICAgIC8vIHRoZWlyIHJlbGF0aW9ucyBmb3IgYHRoaXNgIGluc2lkZSBgZ2V0IHJlbGF0aW9ucygpYCBhY2Nlc3NvcnMuXG4gICAgICAgICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtb2RlbENsYXNzLCBuYW1lKVxuICAgICAgICAgICAgaWYgKGRlc2MpIHtcbiAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBkZXNjLmdldD8uY2FsbCh0aGlzKSB8fCBkZXNjLnZhbHVlXG4gICAgICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHZhbHVlKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG1vZGVsQ2xhc3MgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YobW9kZWxDbGFzcylcbiAgICAgICAgfVxuICAgICAgICAvLyBUbyBwcmV2ZW50IGVuZGxlc3MgcmVjdXJzaW9uIHdpdGggaW50ZXJkZXBlbmRlbnQgY2FsbHMgcmVsYXRlZCB0b1xuICAgICAgICAvLyBwcm9wZXJ0aWVzLCBvdmVycmlkZSBkZWZpbml0aW9uIGJlZm9yZSBjYWxsaW5nIGhhbmRsZXIoKTpcbiAgICAgICAgc2V0RGVmaW5pdGlvbihuYW1lLCB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiB7fVxuICAgICAgICB9KVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG1lcmdlZCA9IGRlZmluaXRpb25zW25hbWVdLmNhbGwodGhpcywgdmFsdWVzKVxuICAgICAgICAgIC8vIE9uY2UgY2FsY3VsYXRlZCwgb3ZlcnJpZGUgZ2V0dGVyIHdpdGggZmluYWwgbWVyZ2VkIHZhbHVlLlxuICAgICAgICAgIHNldERlZmluaXRpb24obmFtZSwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBtZXJnZWRcbiAgICAgICAgICB9KVxuICAgICAgICAgIHJldHVybiBtZXJnZWRcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTW9kZWxFcnJvcih0aGlzLCBlcnJvci5tZXNzYWdlKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIElmIG5vIGRlZmluaXRpb24gb2JqZWN0IHdhcyBkZWZpbmVkIHlldCwgY3JlYXRlIG9uZSB3aXRoIGFjY2Vzc29ycyBmb3JcbiAgICAgIC8vIGVhY2ggZW50cnkgaW4gYGRlZmluaXRpb25zYC4gRWFjaCBvZiB0aGVzZSBnZXR0ZXJzIHdoZW4gY2FsbGVkIG1lcmdlXG4gICAgICAvLyBkZWZpbml0aW9ucyB1cCB0aGUgaW5oZXJpdGFuY2UgY2hhaW4gYW5kIHN0b3JlIHRoZSBtZXJnZWQgcmVzdWx0IGluXG4gICAgICAvLyBgbW9kZWxDbGFzcy5kZWZpbml0aW9uW25hbWVdYCBmb3IgZnVydGhlciBjYWNoaW5nLlxuICAgICAgZm9yIChjb25zdCBuYW1lIGluIGRlZmluaXRpb25zKSB7XG4gICAgICAgIHNldERlZmluaXRpb24obmFtZSwge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICBnZXQ6ICgpID0+IGdldERlZmluaXRpb24obmFtZSlcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWZpbml0aW9uXG4gICAgfSlcbiAgfVxuXG4gIC8vIEhvb2tzXG5cbiAgJGVtaXQoZXZlbnQsIC4uLmFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5lbWl0KGV2ZW50LCB0aGlzLCAuLi5hcmdzKVxuICB9XG5cbiAgc3RhdGljIGJlZm9yZUZpbmQoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYmVmb3JlOmZpbmQnLCBhcmdzKVxuICB9XG5cbiAgc3RhdGljIGFmdGVyRmluZChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VtaXRTdGF0aWNIb29rKCdhZnRlcjpmaW5kJywgYXJncylcbiAgfVxuXG4gIHN0YXRpYyBiZWZvcmVJbnNlcnQoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYmVmb3JlOmluc2VydCcsIGFyZ3MpXG4gIH1cblxuICBzdGF0aWMgYWZ0ZXJJbnNlcnQoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYWZ0ZXI6aW5zZXJ0JywgYXJncylcbiAgfVxuXG4gIHN0YXRpYyBiZWZvcmVVcGRhdGUoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYmVmb3JlOnVwZGF0ZScsIGFyZ3MpXG4gIH1cblxuICBzdGF0aWMgYWZ0ZXJVcGRhdGUoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYWZ0ZXI6dXBkYXRlJywgYXJncylcbiAgfVxuXG4gIHN0YXRpYyBiZWZvcmVEZWxldGUoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYmVmb3JlOmRlbGV0ZScsIGFyZ3MpXG4gIH1cblxuICBzdGF0aWMgYWZ0ZXJEZWxldGUoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYWZ0ZXI6ZGVsZXRlJywgYXJncylcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBfZW1pdFN0YXRpY0hvb2soZXZlbnQsIG9yaWdpbmFsQXJncykge1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzKGV2ZW50KVxuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gU3RhdGljIGhvb2tzIGFyZSBlbWl0dGVkIGluIHNlcXVlbmNlIChidXQgZWFjaCBldmVudCBjYW4gYmUgYXN5bmMpLCBhbmRcbiAgICAgIC8vIHJlc3VsdHMgYXJlIHBhc3NlZCB0aHJvdWdoIGFuZCByZXR1cm5lZCBpbiB0aGUgZW5kLlxuICAgICAgbGV0IHsgcmVzdWx0IH0gPSBvcmlnaW5hbEFyZ3NcbiAgICAgIC8vIFRoZSByZXN1bHQgb2YgYW55IGV2ZW50IGhhbmRsZXIgd2lsbCBvdmVycmlkZSBgYXJncy5yZXN1bHRgIGluIHRoZSBjYWxsXG4gICAgICAvLyBvZiB0aGUgbmV4dCBoYW5kbGVyIGluIHNlcXVlbmNlLiBBcyBgU3RhdGljSG9va0FyZ3VtZW50c2AgaW4gT2JqZWN0aW9uXG4gICAgICAvLyBpcyBwcml2YXRlLCB1c2UgYSBKUyBpbmhlcml0YW5jZSB0cmljayBoZXJlIHRvIG92ZXJyaWRlIGBhcmdzLnJlc3VsdGA6XG4gICAgICBjb25zdCBhcmdzID0gT2JqZWN0LmNyZWF0ZShvcmlnaW5hbEFyZ3MsIHtcbiAgICAgICAgdHlwZToge1xuICAgICAgICAgIHZhbHVlOiBldmVudFxuICAgICAgICB9LFxuICAgICAgICByZXN1bHQ6IHtcbiAgICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgbGlzdGVuZXIuY2FsbCh0aGlzLCBhcmdzKVxuICAgICAgICBpZiAocmVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXN1bHQgPSByZXNcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gVW5mb3J0dW5hdGVseSBgcmVzdWx0YCBpcyBhbHdheXMgYW4gYXJyYXksIGV2ZW4gd2hlbiB0aGUgYWN0dWFsIHJlc3VsdFxuICAgICAgLy8gaXMgYSBtb2RlbCBvYmplY3QuIEF2b2lkIHJldHVybmluZyBpdCB3aGVuIGl0J3Mgbm90IGFjdHVhbGx5IGNoYW5nZWQuXG4gICAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9WaW5jaXQvb2JqZWN0aW9uLmpzL2lzc3Vlcy8xODQyXG4gICAgICBpZiAocmVzdWx0ICE9PSBvcmlnaW5hbEFyZ3MucmVzdWx0KSB7XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBBc3NldHMgaGFuZGxpbmdcblxuICBzdGF0aWMgX3NldHVwQXNzZXRzRXZlbnRzKGFzc2V0cykge1xuICAgIGNvbnN0IGFzc2V0RGF0YVBhdGhzID0gT2JqZWN0LmtleXMoYXNzZXRzKVxuXG4gICAgdGhpcy5vbihbXG4gICAgICAnYmVmb3JlOmluc2VydCcsXG4gICAgICAnYmVmb3JlOnVwZGF0ZScsXG4gICAgICAnYmVmb3JlOmRlbGV0ZSdcbiAgICBdLCBhc3luYyAoeyB0eXBlLCB0cmFuc2FjdGlvbiwgaW5wdXRJdGVtcywgYXNGaW5kUXVlcnkgfSkgPT4ge1xuICAgICAgY29uc3QgYWZ0ZXJJdGVtcyA9IHR5cGUgPT09ICdiZWZvcmU6ZGVsZXRlJ1xuICAgICAgICA/IFtdXG4gICAgICAgIDogaW5wdXRJdGVtc1xuICAgICAgLy8gRmlndXJlIG91dCB3aGljaCBhc3NldCBkYXRhIHBhdGhzIHdoZXJlIGFjdHVhbGx5IHByZXNlbnQgaW4gdGhlXG4gICAgICAvLyBzdWJtaXR0ZWQgZGF0YSwgYW5kIG9ubHkgY29tcGFyZSB0aGVzZS4gQnV0IHdoZW4gZGVsZXRpbmcsIHVzZSBhbGwuXG4gICAgICBjb25zdCBkYXRhUGF0aHMgPSBhZnRlckl0ZW1zLmxlbmd0aCA+IDBcbiAgICAgICAgPyBhc3NldERhdGFQYXRocy5maWx0ZXIoXG4gICAgICAgICAgcGF0aCA9PiBnZXRWYWx1ZUF0QXNzZXREYXRhUGF0aChhZnRlckl0ZW1zWzBdLCBwYXRoKSAhPT0gdW5kZWZpbmVkXG4gICAgICAgIClcbiAgICAgICAgOiBhc3NldERhdGFQYXRoc1xuXG4gICAgICAvLyBgZGF0YVBhdGhzYCB3aWxsIGJlIGVtcHR5IGluIHRoZSBjYXNlIG9mIGFuIHVwZGF0ZS9pbnNlcnQgdGhhdCBkbyBub3RcbiAgICAgIC8vIGFmZmVjdCB0aGUgYXNzZXRzLlxuICAgICAgaWYgKGRhdGFQYXRocy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIC8vIExvYWQgdGhlIG1vZGVsJ3MgYXNzZXQgZmlsZXMgaW4gdGhlaXIgY3VycmVudCBzdGF0ZSBiZWZvcmUgdGhlIHF1ZXJ5IGlzXG4gICAgICAvLyBleGVjdXRlZC5cbiAgICAgIGNvbnN0IGJlZm9yZUl0ZW1zID0gdHlwZSA9PT0gJ2JlZm9yZTppbnNlcnQnXG4gICAgICAgID8gW11cbiAgICAgICAgOiBhd2FpdCBsb2FkQXNzZXREYXRhUGF0aHMoYXNGaW5kUXVlcnkoKSwgZGF0YVBhdGhzKVxuICAgICAgY29uc3QgYmVmb3JlRmlsZXNQZXJEYXRhUGF0aCA9IGdldEZpbGVzUGVyQXNzZXREYXRhUGF0aChcbiAgICAgICAgYmVmb3JlSXRlbXMsXG4gICAgICAgIGRhdGFQYXRoc1xuICAgICAgKVxuICAgICAgY29uc3QgYWZ0ZXJGaWxlc1BlckRhdGFQYXRoID0gZ2V0RmlsZXNQZXJBc3NldERhdGFQYXRoKFxuICAgICAgICBhZnRlckl0ZW1zLFxuICAgICAgICBkYXRhUGF0aHNcbiAgICAgIClcblxuICAgICAgY29uc3QgaW1wb3J0ZWRGaWxlcyA9IFtdXG4gICAgICBjb25zdCBtb2RpZmllZEZpbGVzID0gW11cblxuICAgICAgaWYgKHRyYW5zYWN0aW9uLnJvbGxiYWNrKSB7XG4gICAgICAgIC8vIFByZXZlbnQgd3JvbmcgbWVtb3J5IGxlYWsgZXJyb3IgbWVzc2FnZXMgd2hlbiBpbnN0YWxsaW5nIG1vcmUgdGhhbiAxMFxuICAgICAgICAvLyAncm9sbGJhY2snIGhhbmRsZXJzLCB3aGljaCBjYW4gaGFwcGVuIHdpdGggbW9yZSBjb21wbGV4IHF1ZXJpZXMuXG4gICAgICAgIHRyYW5zYWN0aW9uLnNldE1heExpc3RlbmVycygwKVxuICAgICAgICB0cmFuc2FjdGlvbi5vbigncm9sbGJhY2snLCBhc3luYyBlcnJvciA9PiB7XG4gICAgICAgICAgaWYgKGltcG9ydGVkRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFxuICAgICAgICAgICAgICBgUmVjZWl2ZWQgJyR7ZXJyb3J9JywgcmVtb3ZpbmcgaW1wb3J0ZWQgZmlsZXMgYWdhaW46ICR7XG4gICAgICAgICAgICAgICAgaW1wb3J0ZWRGaWxlcy5tYXAoZmlsZSA9PiBgJyR7ZmlsZS5uYW1lfSdgKVxuICAgICAgICAgICAgICB9YFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICAgIGltcG9ydGVkRmlsZXMubWFwKFxuICAgICAgICAgICAgICAgIGZpbGUgPT4gZmlsZS5zdG9yYWdlLnJlbW92ZUZpbGUoZmlsZSlcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobW9kaWZpZWRGaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBgbW9kaWZpZWRGaWxlc2Agc2hvdWxkIGJlIHJlc3RvcmVkIGFzIHdlbGwsIGJ1dCB0aGF0J3MgZmFyXG4gICAgICAgICAgICAvLyBmcm9tIHRyaXZpYWwgc2luY2Ugbm8gYmFja3VwIGlzIGtlcHQgaW4gYGhhbmRsZU1vZGlmaWVkQXNzZXRzYFxuICAgICAgICAgICAgY29uc29sZS5pbmZvKFxuICAgICAgICAgICAgICBgVW5hYmxlIHRvIHJlc3RvcmUgdGhlc2UgYWxyZWFkeSBtb2RpZmllZCBmaWxlczogJHtcbiAgICAgICAgICAgICAgICBtb2RpZmllZEZpbGVzLm1hcChmaWxlID0+IGAnJHtmaWxlLm5hbWV9J2ApXG4gICAgICAgICAgICAgIH1gXG4gICAgICAgICAgICApXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGRhdGFQYXRoIG9mIGRhdGFQYXRocykge1xuICAgICAgICBjb25zdCBzdG9yYWdlID0gdGhpcy5hcHAuZ2V0U3RvcmFnZShhc3NldHNbZGF0YVBhdGhdLnN0b3JhZ2UpXG4gICAgICAgIGNvbnN0IGJlZm9yZUZpbGVzID0gYmVmb3JlRmlsZXNQZXJEYXRhUGF0aFtkYXRhUGF0aF0gfHwgW11cbiAgICAgICAgY29uc3QgYWZ0ZXJGaWxlcyA9IGFmdGVyRmlsZXNQZXJEYXRhUGF0aFtkYXRhUGF0aF0gfHwgW11cbiAgICAgICAgY29uc3QgYmVmb3JlQnlLZXkgPSBtYXBGaWxlc0J5S2V5KGJlZm9yZUZpbGVzKVxuICAgICAgICBjb25zdCBhZnRlckJ5S2V5ID0gbWFwRmlsZXNCeUtleShhZnRlckZpbGVzKVxuICAgICAgICBjb25zdCByZW1vdmVkRmlsZXMgPSBiZWZvcmVGaWxlcy5maWx0ZXIoZmlsZSA9PiAhYWZ0ZXJCeUtleVtmaWxlLmtleV0pXG4gICAgICAgIGNvbnN0IGFkZGVkRmlsZXMgPSBhZnRlckZpbGVzLmZpbHRlcihmaWxlID0+ICFiZWZvcmVCeUtleVtmaWxlLmtleV0pXG4gICAgICAgIC8vIEFsc28gaGFuZGxlIG1vZGlmaWVkIGZpbGVzLCB3aGljaCBhcmUgZmlsZXMgd2hlcmUgdGhlIGRhdGEgcHJvcGVydHlcbiAgICAgICAgLy8gaXMgY2hhbmdlZCBiZWZvcmUgdXBkYXRlIC8gcGF0Y2gsIG1lYW50aW5nIHRoZSBmaWxlIGlzIGNoYW5nZWQuXG4gICAgICAgIC8vIE5PVEU6IFRoaXMgd2lsbCBjaGFuZ2UgdGhlIGNvbnRlbnQgZm9yIGFsbCB0aGUgcmVmZXJlbmNlcyB0byBpdCxcbiAgICAgICAgLy8gYW5kIHRodXMgc2hvdWxkIG9ubHkgcmVhbGx5IGJlIHVzZWQgd2hlbiB0aGVyZSdzIG9ubHkgb25lIHJlZmVyZW5jZS5cbiAgICAgICAgY29uc3QgbW9kaWZpZWRGaWxlcyA9IGFmdGVyRmlsZXMuZmlsdGVyKFxuICAgICAgICAgIGZpbGUgPT4gZmlsZS5kYXRhICYmIGJlZm9yZUJ5S2V5W2ZpbGUua2V5XVxuICAgICAgICApXG4gICAgICAgIGltcG9ydGVkRmlsZXMucHVzaChcbiAgICAgICAgICAuLi5hd2FpdCB0aGlzLmFwcC5oYW5kbGVBZGRkZWRBbmRSZW1vdmVkQXNzZXRzKFxuICAgICAgICAgICAgc3RvcmFnZSxcbiAgICAgICAgICAgIGFkZGVkRmlsZXMsXG4gICAgICAgICAgICByZW1vdmVkRmlsZXMsXG4gICAgICAgICAgICB0cmFuc2FjdGlvblxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgICBtb2RpZmllZEZpbGVzLnB1c2goXG4gICAgICAgICAgLi4uYXdhaXQgdGhpcy5hcHAuaGFuZGxlTW9kaWZpZWRBc3NldHMoXG4gICAgICAgICAgICBzdG9yYWdlLFxuICAgICAgICAgICAgbW9kaWZpZWRGaWxlcyxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICB9XG4gICAgfSlcbiAgfVxufVxuXG5FdmVudEVtaXR0ZXIubWl4aW4oTW9kZWwpXG5LbmV4SGVscGVyLm1peGluKE1vZGVsKVxuLy8gRXhwb3NlIGEgc2VsZWN0aW9uIG9mIFF1ZXJ5QnVpbGRlciBtZXRob2RzIGFzIHN0YXRpYyBtZXRob2RzIG9uIG1vZGVsIGNsYXNzZXNcblF1ZXJ5QnVpbGRlci5taXhpbihNb2RlbClcblxuY29uc3QgbWV0YU1hcCA9IG5ldyBXZWFrTWFwKClcblxuZnVuY3Rpb24gZ2V0TWV0YShtb2RlbENsYXNzLCBrZXksIHZhbHVlKSB7XG4gIGxldCBtZXRhID0gbWV0YU1hcC5nZXQobW9kZWxDbGFzcylcbiAgaWYgKCFtZXRhKSB7XG4gICAgbWV0YU1hcC5zZXQobW9kZWxDbGFzcywgbWV0YSA9IHt9KVxuICB9XG4gIGlmICghKGtleSBpbiBtZXRhKSkge1xuICAgIG1ldGFba2V5XSA9IGlzRnVuY3Rpb24odmFsdWUpID8gdmFsdWUoKSA6IHZhbHVlXG4gIH1cbiAgcmV0dXJuIG1ldGFba2V5XVxufVxuXG5mdW5jdGlvbiBsb2FkQXNzZXREYXRhUGF0aHMocXVlcnksIGRhdGFQYXRocykge1xuICByZXR1cm4gZGF0YVBhdGhzLnJlZHVjZShcbiAgICAocXVlcnksIGRhdGFQYXRoKSA9PiBxdWVyeS5sb2FkRGF0YVBhdGgoZGF0YVBhdGgpLFxuICAgIHF1ZXJ5XG4gIClcbn1cblxuZnVuY3Rpb24gZ2V0VmFsdWVBdEFzc2V0RGF0YVBhdGgoaXRlbSwgcGF0aCkge1xuICByZXR1cm4gZ2V0VmFsdWVBdERhdGFQYXRoKGl0ZW0sIHBhdGgsICgpID0+IHVuZGVmaW5lZClcbn1cblxuZnVuY3Rpb24gZ2V0RmlsZXNQZXJBc3NldERhdGFQYXRoKGl0ZW1zLCBkYXRhUGF0aHMpIHtcbiAgcmV0dXJuIGRhdGFQYXRocy5yZWR1Y2UoXG4gICAgKGFsbEZpbGVzLCBkYXRhUGF0aCkgPT4ge1xuICAgICAgYWxsRmlsZXNbZGF0YVBhdGhdID0gYXNBcnJheShpdGVtcykucmVkdWNlKFxuICAgICAgICAoZmlsZXMsIGl0ZW0pID0+IHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gYXNBcnJheShnZXRWYWx1ZUF0QXNzZXREYXRhUGF0aChpdGVtLCBkYXRhUGF0aCkpXG4gICAgICAgICAgLy8gVXNlIGZsYXR0ZW4oKSBhcyBkYXRhUGF0aCBtYXkgY29udGFpbiB3aWxkY2FyZHMsIHJlc3VsdGluZyBpblxuICAgICAgICAgIC8vIG5lc3RlZCBmaWxlcyBhcnJheXMuXG4gICAgICAgICAgZmlsZXMucHVzaCguLi5mbGF0dGVuKGRhdGEpLmZpbHRlcihmaWxlID0+ICEhZmlsZSkpXG4gICAgICAgICAgcmV0dXJuIGZpbGVzXG4gICAgICAgIH0sXG4gICAgICAgIFtdXG4gICAgICApXG4gICAgICByZXR1cm4gYWxsRmlsZXNcbiAgICB9LFxuICAgIHt9XG4gIClcbn1cblxuZnVuY3Rpb24gbWFwRmlsZXNCeUtleShmaWxlcykge1xuICByZXR1cm4gZmlsZXMucmVkdWNlKFxuICAgIChtYXAsIGZpbGUpID0+IHtcbiAgICAgIG1hcFtmaWxlLmtleV0gPSBmaWxlXG4gICAgICByZXR1cm4gbWFwXG4gICAgfSxcbiAgICB7fVxuICApXG59XG4iXX0=