@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,745 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.QueryBuilder = void 0;
5
-
6
- require("core-js/modules/esnext.async-iterator.reduce.js");
7
-
8
- require("core-js/modules/esnext.iterator.constructor.js");
9
-
10
- require("core-js/modules/esnext.iterator.reduce.js");
11
-
12
- require("core-js/modules/esnext.async-iterator.map.js");
13
-
14
- require("core-js/modules/esnext.iterator.map.js");
15
-
16
- var _objection = _interopRequireDefault(require("objection"));
17
-
18
- var _lib = require("../lib");
19
-
20
- var _errors = require("../errors");
21
-
22
- var _QueryParameters = require("./QueryParameters");
23
-
24
- var _graph = require("../graph");
25
-
26
- var _utils = require("@ditojs/utils");
27
-
28
- var _utils2 = require("../utils");
29
-
30
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
-
32
- const SYMBOL_ALL = Symbol('all');
33
-
34
- class QueryBuilder extends _objection.default.QueryBuilder {
35
- constructor(modelClass) {
36
- super(modelClass);
37
- this._ignoreGraph = false;
38
- this._graphAlgorithm = 'fetch';
39
- this._allowFilters = null;
40
- this._allowScopes = null;
41
- this._ignoreScopes = {};
42
- this._appliedScopes = {};
43
- this._executeFirst = null;
44
-
45
- this._clearScopes(true);
46
- }
47
-
48
- clone() {
49
- const copy = super.clone();
50
- copy._ignoreGraph = this._ignoreGraph;
51
- copy._graphAlgorithm = this._graphAlgorithm;
52
- copy._appliedScopes = { ...this._appliedScopes
53
- };
54
- copy._allowFilters = this._allowFilters ? { ...this._allowFilters
55
- } : null;
56
-
57
- copy._copyScopes(this);
58
-
59
- return copy;
60
- }
61
-
62
- async execute() {
63
- var _this$_executeFirst;
64
-
65
- if (!this._ignoreScopes[SYMBOL_ALL]) {
66
- const isNormalFind = this.isFind() && !this.hasSpecialSelects();
67
- this._ignoreGraph = !isNormalFind;
68
- const {
69
- _allowScopes
70
- } = this;
71
- this._allowScopes = null;
72
- const collectedScopes = {};
73
- let scopes = Object.entries(this._scopes);
74
-
75
- while (scopes.length > 0) {
76
- this._scopes = {};
77
-
78
- for (const [scope, graph] of scopes) {
79
- if (scope !== 'default' || isNormalFind) {
80
- this._applyScope(scope, graph);
81
-
82
- collectedScopes[scope] || (collectedScopes[scope] = graph);
83
- }
84
- }
85
-
86
- scopes = Object.entries(this._scopes);
87
- }
88
-
89
- this._scopes = collectedScopes;
90
- this._allowScopes = _allowScopes;
91
- this._ignoreGraph = false;
92
- }
93
-
94
- await ((_this$_executeFirst = this._executeFirst) == null ? void 0 : _this$_executeFirst.call(this));
95
- return super.execute();
96
- }
97
-
98
- hasNormalSelects() {
99
- return this.has(/^(select|columns?)$/);
100
- }
101
-
102
- hasSpecialSelects() {
103
- return this.hasSelects() && !this.hasNormalSelects();
104
- }
105
-
106
- childQueryOf(query, options) {
107
- super.childQueryOf(query, options);
108
-
109
- if (this.isInternal()) {
110
- this._clearScopes(false);
111
- } else {
112
- this._copyScopes(query, true);
113
- }
114
-
115
- return this;
116
- }
117
-
118
- toFindQuery() {
119
- return super.toFindQuery().clear('runAfter');
120
- }
121
-
122
- withScope(...scopes) {
123
- for (const expr of scopes) {
124
- if (expr) {
125
- var _this$_scopes;
126
-
127
- const {
128
- scope,
129
- graph
130
- } = (0, _utils2.getScope)(expr);
131
-
132
- if (this._allowScopes && !this._allowScopes[scope]) {
133
- throw new _errors.QueryBuilderError(`Query scope '${scope}' is not allowed.`);
134
- }
135
-
136
- (_this$_scopes = this._scopes)[scope] || (_this$_scopes[scope] = graph);
137
- }
138
- }
139
-
140
- return this;
141
- }
142
-
143
- clearWithScope() {
144
- return this._clearScopes(true);
145
- }
146
-
147
- ignoreScope(...scopes) {
148
- if (!this._ignoreScopes[SYMBOL_ALL]) {
149
- this._ignoreScopes = scopes.length > 0 ? { ...this._ignoreScopes,
150
- ...(0, _utils2.createLookup)(scopes)
151
- } : {
152
- [SYMBOL_ALL]: true
153
- };
154
- }
155
-
156
- return this;
157
- }
158
-
159
- applyScope(...scopes) {
160
- this.withScope(...scopes);
161
-
162
- for (const expr of scopes) {
163
- if (expr) {
164
- const {
165
- scope,
166
- graph
167
- } = (0, _utils2.getScope)(expr);
168
-
169
- this._applyScope(scope, graph);
170
- }
171
- }
172
-
173
- return this;
174
- }
175
-
176
- allowScope(...scopes) {
177
- this._allowScopes = this._allowScopes || {
178
- default: true
179
- };
180
-
181
- for (const expr of scopes) {
182
- if (expr) {
183
- const {
184
- scope
185
- } = (0, _utils2.getScope)(expr);
186
- this._allowScopes[scope] = true;
187
- }
188
- }
189
- }
190
-
191
- clearAllowScope() {
192
- this._allowScopes = null;
193
- }
194
-
195
- scope(...scopes) {
196
- (0, _utils2.deprecate)(`QueryBuilder#scope() is deprecated. Use #withScope() instead.`);
197
- return this.clearWithScope().withScope(...scopes);
198
- }
199
-
200
- mergeScope(...scopes) {
201
- (0, _utils2.deprecate)(`QueryBuilder#mergeScope() is deprecated. Use #withScope() instead.`);
202
- return this.withScope(...scopes);
203
- }
204
-
205
- clearScope() {
206
- (0, _utils2.deprecate)(`QueryBuilder#clearScope() is deprecated. Use #clearWithScope() or #ignoreScope() instead.`);
207
- return this.clearWithScope();
208
- }
209
-
210
- _clearScopes(addDefault) {
211
- this._scopes = addDefault ? {
212
- default: true
213
- } : {};
214
- return this;
215
- }
216
-
217
- _copyScopes(query, isChildQuery = false) {
218
- const isSameModelClass = this.modelClass() === query.modelClass();
219
-
220
- if (isSameModelClass) {
221
- this._allowScopes = query._allowScopes ? { ...query._allowScopes
222
- } : null;
223
- this._ignoreScopes = { ...query._ignoreScopes
224
- };
225
- }
226
-
227
- const copyAllScopes = isSameModelClass && isChildQuery && query.has(/GraphAndFetch$/);
228
- this._scopes = this._filterScopes(query._scopes, (scope, graph) => copyAllScopes || graph);
229
- }
230
-
231
- _filterScopes(scopes, callback) {
232
- return Object.entries(scopes).reduce((scopes, [scope, graph]) => {
233
- if (callback(scope, graph)) {
234
- scopes[scope] = graph;
235
- }
236
-
237
- return scopes;
238
- }, {});
239
- }
240
-
241
- _applyScope(scope, graph) {
242
- if (!this._ignoreScopes[SYMBOL_ALL] && !this._ignoreScopes[scope]) {
243
- if (!this._appliedScopes[scope]) {
244
- const func = this.modelClass().getScope(scope);
245
-
246
- if (func) {
247
- func.call(this, this);
248
- }
249
-
250
- this._appliedScopes[scope] = true;
251
- }
252
-
253
- if (graph) {
254
- const expr = this.graphExpressionObject();
255
-
256
- if (expr) {
257
- const name = `^${scope}`;
258
- const modifiers = {
259
- [name]: query => query._applyScope(scope, graph)
260
- };
261
- this.withGraph(addGraphScope(this.modelClass(), expr, [name], modifiers, true)).modifiers(modifiers);
262
- }
263
- }
264
- }
265
- }
266
-
267
- applyFilter(name, ...args) {
268
- if (this._allowFilters && !this._allowFilters[name]) {
269
- throw new _errors.QueryBuilderError(`Query filter '${name}' is not allowed.`);
270
- }
271
-
272
- const filter = this.modelClass().definition.filters[name];
273
-
274
- if (!filter) {
275
- throw new _errors.QueryBuilderError(`Query filter '${name}' is not defined.`);
276
- }
277
-
278
- return this.andWhere(query => filter(query, ...args));
279
- }
280
-
281
- allowFilter(...filters) {
282
- this._allowFilters = this._allowFilters || {};
283
-
284
- for (const filter of filters) {
285
- this._allowFilters[filter] = true;
286
- }
287
- }
288
-
289
- withGraph(expr, options = {}) {
290
- const {
291
- algorithm = this._graphAlgorithm
292
- } = options;
293
- const method = {
294
- fetch: 'withGraphFetched',
295
- join: 'withGraphJoined'
296
- }[algorithm];
297
-
298
- if (!method) {
299
- throw new _errors.QueryBuilderError(`Graph algorithm '${algorithm}' is unsupported.`);
300
- }
301
-
302
- if (!this._ignoreGraph) {
303
- this._graphAlgorithm = algorithm;
304
- super[method](expr, options);
305
- }
306
-
307
- return this;
308
- }
309
-
310
- withGraphFetched(expr, options) {
311
- return this.withGraph(expr, { ...options,
312
- algorithm: 'fetch'
313
- });
314
- }
315
-
316
- withGraphJoined(expr, options) {
317
- return this.withGraph(expr, { ...options,
318
- algorithm: 'join'
319
- });
320
- }
321
-
322
- toSQL() {
323
- return this.toKnexQuery().toSQL();
324
- }
325
-
326
- raw(...args) {
327
- return _objection.default.raw(...args).toKnexRaw(this);
328
- }
329
-
330
- selectRaw(...args) {
331
- return this.select(_objection.default.raw(...args));
332
- }
333
-
334
- pluck(key) {
335
- return this.runAfter(result => (0, _utils.isArray)(result) ? result.map(it => it == null ? void 0 : it[key]) : (0, _utils.isObject)(result) ? result[key] : result);
336
- }
337
-
338
- loadDataPath(dataPath, options) {
339
- const parsedDataPath = (0, _utils.parseDataPath)(dataPath);
340
- const {
341
- property,
342
- expression,
343
- nestedDataPath,
344
- name,
345
- index
346
- } = this.modelClass().getPropertyOrRelationAtDataPath(parsedDataPath);
347
-
348
- if (nestedDataPath) {
349
- if (!(property && ['object', 'array'].includes(property.type))) {
350
- throw new _errors.QueryBuilderError(`Unable to load full data-path '${dataPath}' (Unmatched: '${nestedDataPath}').`);
351
- }
352
- }
353
-
354
- if (property && index === 0) {
355
- this.select(name);
356
- } else {
357
- this.withGraph(expression, options);
358
- }
359
-
360
- return this;
361
- }
362
-
363
- truncate({
364
- restart = true,
365
- cascade = false
366
- } = {}) {
367
- if (this.isPostgreSQL()) {
368
- return this.raw(`truncate table ??${restart ? ' restart identity' : ''}${cascade ? ' cascade' : ''}`, this.modelClass().tableName);
369
- }
370
-
371
- return super.truncate();
372
- }
373
-
374
- insert(data) {
375
- return !this.isPostgreSQL() && (0, _utils.isArray)(data) && data.length > 1 ? this.insertGraph(data) : super.insert(data);
376
- }
377
-
378
- upsert(data, options = {}) {
379
- let mainQuery;
380
- return this.runBefore((result, builder) => {
381
- if (!builder.context().isMainQuery) {
382
- mainQuery = builder.clone().context({
383
- isMainQuery: true
384
- });
385
- builder[options.update ? 'update' : 'patch'](data);
386
- }
387
-
388
- return result;
389
- }).runAfter((result, builder) => {
390
- if (!builder.context().isMainQuery) {
391
- return result === 0 ? mainQuery[options.fetch ? 'insertAndFetch' : 'insert'](data) : mainQuery.first();
392
- }
393
-
394
- return result;
395
- });
396
- }
397
-
398
- find(query, allowParam) {
399
- if (!query) return this;
400
- const allowed = !allowParam ? _QueryParameters.QueryParameters.allowed() : (0, _utils.isPlainObject)(allowParam) ? allowParam : (0, _utils2.createLookup)(allowParam);
401
-
402
- for (const [key, value] of Object.entries(query)) {
403
- const param = key.endsWith('[]') ? key.slice(0, -2) : key;
404
-
405
- if (!allowed[param]) {
406
- throw new _errors.QueryBuilderError(`Query parameter '${key}' is not allowed.`);
407
- }
408
-
409
- const paramHandler = _QueryParameters.QueryParameters.get(param);
410
-
411
- if (!paramHandler) {
412
- throw new _errors.QueryBuilderError(`Invalid query parameter '${param}' in '${key}=${value}'.`);
413
- }
414
-
415
- paramHandler(this, key, value);
416
- }
417
-
418
- return this;
419
- }
420
-
421
- findById(id) {
422
- this.context({
423
- byId: id
424
- });
425
- return super.findById(id);
426
- }
427
-
428
- patchAndFetchById(id, data) {
429
- this.context({
430
- byId: id
431
- });
432
- return super.patchAndFetchById(id, data);
433
- }
434
-
435
- updateAndFetchById(id, data) {
436
- this.context({
437
- byId: id
438
- });
439
- return super.updateAndFetchById(id, data);
440
- }
441
-
442
- deleteById(id) {
443
- this.context({
444
- byId: id
445
- });
446
- return super.deleteById(id);
447
- }
448
-
449
- patchById(id, data) {
450
- return this.findById(id).patch(data);
451
- }
452
-
453
- updateById(id, data) {
454
- return this.findById(id).update(data);
455
- }
456
-
457
- patchAndFetch(data) {
458
- return (0, _utils.isArray)(data) ? this._upsertAndFetch(data) : super.patchAndFetch(data);
459
- }
460
-
461
- updateAndFetch(data) {
462
- return (0, _utils.isArray)(data) ? this._upsertAndFetch(data, {
463
- update: true
464
- }) : super.updateAndFetch(data);
465
- }
466
-
467
- upsertAndFetch(data) {
468
- return this._upsertAndFetch(data, {
469
- insertMissing: true,
470
- noInsert: this.modelClass().getRelationNames()
471
- });
472
- }
473
-
474
- _upsertAndFetch(data, options) {
475
- return this.upsertGraphAndFetch(data, {
476
- fetchStrategy: 'OnlyNeeded',
477
- noInset: true,
478
- noDelete: true,
479
- noRelate: true,
480
- noUnrelate: true,
481
- ...options
482
- });
483
- }
484
-
485
- insertDitoGraph(data, options) {
486
- return this._handleDitoGraph('insertGraph', data, options, insertDitoGraphOptions);
487
- }
488
-
489
- insertDitoGraphAndFetch(data, options) {
490
- return this._handleDitoGraph('insertGraphAndFetch', data, options, insertDitoGraphOptions);
491
- }
492
-
493
- upsertDitoGraph(data, options) {
494
- return this._handleDitoGraph('upsertGraph', data, options, upsertDitoGraphOptions);
495
- }
496
-
497
- upsertDitoGraphAndFetch(data, options) {
498
- return this._handleDitoGraph('upsertGraphAndFetch', data, options, upsertDitoGraphOptions);
499
- }
500
-
501
- patchDitoGraph(data, options) {
502
- return this._handleDitoGraph('upsertGraph', data, options, patchDitoGraphOptions);
503
- }
504
-
505
- patchDitoGraphAndFetch(data, options) {
506
- return this._handleDitoGraph('upsertGraphAndFetch', data, options, patchDitoGraphOptions);
507
- }
508
-
509
- updateDitoGraph(data, options) {
510
- return this._handleDitoGraph('upsertGraph', data, options, updateDitoGraphOptions);
511
- }
512
-
513
- updateDitoGraphAndFetch(data, options) {
514
- return this._handleDitoGraph('upsertGraphAndFetch', data, options, updateDitoGraphOptions);
515
- }
516
-
517
- upsertDitoGraphAndFetchById(id, data, options) {
518
- this.context({
519
- byId: id
520
- });
521
- return this.upsertDitoGraphAndFetch({ ...data,
522
- ...this.modelClass().getReference(id)
523
- }, options);
524
- }
525
-
526
- patchDitoGraphAndFetchById(id, data, options) {
527
- this.context({
528
- byId: id
529
- });
530
- return this.patchDitoGraphAndFetch({ ...data,
531
- ...this.modelClass().getReference(id)
532
- }, options);
533
- }
534
-
535
- updateDitoGraphAndFetchById(id, data, options) {
536
- this.context({
537
- byId: id
538
- });
539
- return this.updateDitoGraphAndFetch({ ...data,
540
- ...this.modelClass().getReference(id)
541
- }, options);
542
- }
543
-
544
- _handleDitoGraph(method, data, options, defaultOptions) {
545
- const handleGraph = data => {
546
- const graphProcessor = new _graph.DitoGraphProcessor(this.modelClass(), data, { ...defaultOptions,
547
- ...options
548
- }, {
549
- processOverrides: true,
550
- processRelates: true
551
- });
552
- this[method](graphProcessor.getData(), graphProcessor.getOptions());
553
- };
554
-
555
- if (options != null && options.cyclic && method.startsWith('upsert')) {
556
- this._executeFirst = async () => {
557
- this._executeFirst = null;
558
- handleGraph(await this.clone()._upsertCyclicDitoGraphAndFetch(data, options));
559
- };
560
- } else {
561
- handleGraph(data);
562
- }
563
-
564
- return this;
565
- }
566
-
567
- async _upsertCyclicDitoGraphAndFetch(data, options) {
568
- const identifiers = {};
569
- const references = {};
570
- const {
571
- uidProp,
572
- uidRefProp
573
- } = this.modelClass();
574
- (0, _graph.walkGraph)(data, (value, path) => {
575
- if ((0, _utils.isObject)(value)) {
576
- const {
577
- [uidProp]: id,
578
- [uidRefProp]: ref
579
- } = value;
580
-
581
- if (id) {
582
- identifiers[id] = path.join('/');
583
- } else if (ref) {
584
- references[path.join('/')] = ref;
585
- }
586
- }
587
- });
588
- const cloned = (0, _utils.clone)(data);
589
-
590
- for (const path of Object.keys(references)) {
591
- const parts = (0, _utils.parseDataPath)(path);
592
- const key = parts.pop();
593
- const parent = (0, _utils.getValueAtDataPath)(cloned, parts);
594
- delete parent[key];
595
- }
596
-
597
- const {
598
- cyclic,
599
- ...opts
600
- } = options;
601
- const model = await this.upsertDitoGraphAndFetch(cloned, opts);
602
- const links = {};
603
-
604
- for (const [identifier, path] of Object.entries(identifiers)) {
605
- const {
606
- id
607
- } = (0, _utils.getValueAtDataPath)(model, path);
608
- links[identifier] = {
609
- id
610
- };
611
- }
612
-
613
- for (const [path, reference] of Object.entries(references)) {
614
- const link = links[reference];
615
-
616
- if (link) {
617
- (0, _utils.setValueAtDataPath)(model, path, link);
618
- }
619
- }
620
-
621
- return model;
622
- }
623
-
624
- static mixin(target) {
625
- for (const method of mixinMethods) {
626
- if (method in target) {
627
- console.warn(`There is already a property named '${method}' on '${target}'`);
628
- } else {
629
- Object.defineProperty(target, method, {
630
- value(...args) {
631
- return this.query()[method](...args);
632
- },
633
-
634
- configurable: true,
635
- enumerable: false
636
- });
637
- }
638
- }
639
- }
640
-
641
- }
642
-
643
- exports.QueryBuilder = QueryBuilder;
644
-
645
- _lib.KnexHelper.mixin(QueryBuilder.prototype);
646
-
647
- for (const key of ['eager', 'joinEager', 'naiveEager', 'mergeEager', 'mergeJoinEager', 'mergeNaiveEager']) {
648
- const method = QueryBuilder.prototype[key];
649
-
650
- QueryBuilder.prototype[key] = function (...args) {
651
- if (!this._ignoreGraph) {
652
- this._graphAlgorithm = /join/i.test(key) ? 'join' : 'fetch';
653
- method.call(this, ...args);
654
- }
655
-
656
- return this;
657
- };
658
- }
659
-
660
- for (const key of ['where', 'andWhere', 'orWhere', 'whereNot', 'orWhereNot', 'whereIn', 'orWhereIn', 'whereNotIn', 'orWhereNotIn', 'whereNull', 'orWhereNull', 'whereNotNull', 'orWhereNotNull', 'whereBetween', 'andWhereBetween', 'orWhereBetween', 'whereNotBetween', 'andWhereNotBetween', 'orWhereNotBetween', 'whereColumn', 'andWhereColumn', 'orWhereColumn', 'whereNotColumn', 'andWhereNotColumn', 'orWhereNotColumn', 'whereComposite', 'andWhereComposite', 'orWhereComposite', 'whereInComposite', 'whereNotInComposite', 'having', 'orHaving', 'havingIn', 'orHavingIn', 'havingNotIn', 'orHavingNotIn', 'havingNull', 'orHavingNull', 'havingNotNull', 'orHavingNotNull', 'havingBetween', 'orHavingBetween', 'havingNotBetween', 'orHavingNotBetween', 'select', 'column', 'columns', 'first', 'groupBy', 'orderBy']) {
661
- const method = QueryBuilder.prototype[key];
662
-
663
- QueryBuilder.prototype[key] = function (...args) {
664
- const modelClass = this.modelClass();
665
- const {
666
- properties
667
- } = modelClass.definition;
668
-
669
- const expandIdentifier = identifier => {
670
- const alias = (0, _utils.isString)(identifier) && identifier.match(/^\s*([a-z][\w_]+)(\s+AS\s+.*)$/i);
671
- return alias ? `${expandIdentifier(alias[1])}${alias[2]}` : identifier === '*' || identifier in properties ? `${this.tableRefFor(modelClass)}.${identifier}` : identifier;
672
- };
673
-
674
- const convertArgument = arg => {
675
- if ((0, _utils.isString)(arg)) {
676
- arg = expandIdentifier(arg);
677
- } else if ((0, _utils.isArray)(arg)) {
678
- arg = arg.map(expandIdentifier);
679
- } else if ((0, _utils.isPlainObject)(arg)) {
680
- arg = (0, _utils.mapKeys)(arg, expandIdentifier);
681
- }
682
-
683
- return arg;
684
- };
685
-
686
- const length = ['select', 'column', 'columns', 'first'].includes(key) ? args.length : 1;
687
-
688
- for (let i = 0; i < length; i++) {
689
- args[i] = convertArgument(args[i]);
690
- }
691
-
692
- return method.call(this, ...args);
693
- };
694
- }
695
-
696
- const insertDitoGraphOptions = {
697
- fetchStrategy: 'OnlyNeeded',
698
- relate: true,
699
- allowRefs: true
700
- };
701
- const upsertDitoGraphOptions = { ...insertDitoGraphOptions,
702
- insertMissing: true,
703
- unrelate: true
704
- };
705
- const patchDitoGraphOptions = { ...upsertDitoGraphOptions,
706
- insertMissing: false
707
- };
708
- const updateDitoGraphOptions = { ...patchDitoGraphOptions,
709
- insertMissing: false,
710
- update: true
711
- };
712
-
713
- function addGraphScope(modelClass, expr, scopes, modifiers, isRoot = false) {
714
- if (isRoot) {
715
- expr = (0, _utils.clone)(expr);
716
- } else {
717
- for (const scope of scopes) {
718
- var _expr$$modify;
719
-
720
- if (!((_expr$$modify = expr.$modify) != null && _expr$$modify.includes(scope)) && (modelClass.hasScope(scope) || modifiers[scope])) {
721
- expr.$modify.push(scope);
722
- }
723
- }
724
- }
725
-
726
- const relations = modelClass.getRelations();
727
-
728
- for (const key in expr) {
729
- if (key[0] !== '$') {
730
- const childExpr = expr[key];
731
- const relation = relations[childExpr.$relation || key];
732
-
733
- if (!relation) {
734
- throw new _errors.RelationError(`Invalid child expression: '${key}'`);
735
- }
736
-
737
- addGraphScope(relation.relatedModelClass, childExpr, scopes, modifiers);
738
- }
739
- }
740
-
741
- return expr;
742
- }
743
-
744
- const mixinMethods = ['first', 'find', 'findOne', 'findById', 'withGraph', 'withGraphFetched', 'withGraphJoined', 'clearWithGraph', 'withScope', 'applyScope', 'clearWithScope', 'clear', 'pick', 'omit', 'select', 'insert', 'upsert', 'update', 'patch', 'delete', 'updateById', 'patchById', 'deleteById', 'truncate', 'insertAndFetch', 'upsertAndFetch', 'updateAndFetch', 'patchAndFetch', 'updateAndFetchById', 'patchAndFetchById', 'insertGraph', 'upsertGraph', 'insertGraphAndFetch', 'upsertGraphAndFetch', 'insertDitoGraph', 'upsertDitoGraph', 'updateDitoGraph', 'patchDitoGraph', 'insertDitoGraphAndFetch', 'upsertDitoGraphAndFetch', 'updateDitoGraphAndFetch', 'patchDitoGraphAndFetch', 'upsertDitoGraphAndFetchById', 'updateDitoGraphAndFetchById', 'patchDitoGraphAndFetchById', 'where', 'whereNot', 'whereRaw', 'whereWrapped', 'whereExists', 'whereNotExists', 'whereIn', 'whereNotIn', 'whereNull', 'whereNotNull', 'whereBetween', 'whereNotBetween', 'whereColumn', 'whereNotColumn', 'whereComposite', 'whereInComposite', 'whereNotInComposite', 'whereJsonHasAny', 'whereJsonHasAll', 'whereJsonIsArray', 'whereJsonNotArray', 'whereJsonIsObject', 'whereJsonNotObject', 'whereJsonSubsetOf', 'whereJsonNotSubsetOf', 'whereJsonSupersetOf', 'whereJsonNotSupersetOf', 'having', 'havingIn', 'havingNotIn', 'havingNull', 'havingNotNull', 'havingExists', 'havingNotExists', 'havingBetween', 'havingNotBetween', 'havingRaw', 'havingWrapped', 'eager', 'joinEager', 'naiveEager', 'mergeEager', 'mergeJoinEager', 'mergeNaiveEager', 'clearEager', 'scope', 'mergeScope', 'clearScope'];
745
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9xdWVyeS9RdWVyeUJ1aWxkZXIuanMiXSwibmFtZXMiOlsiU1lNQk9MX0FMTCIsIlN5bWJvbCIsIlF1ZXJ5QnVpbGRlciIsIm9iamVjdGlvbiIsImNvbnN0cnVjdG9yIiwibW9kZWxDbGFzcyIsIl9pZ25vcmVHcmFwaCIsIl9ncmFwaEFsZ29yaXRobSIsIl9hbGxvd0ZpbHRlcnMiLCJfYWxsb3dTY29wZXMiLCJfaWdub3JlU2NvcGVzIiwiX2FwcGxpZWRTY29wZXMiLCJfZXhlY3V0ZUZpcnN0IiwiX2NsZWFyU2NvcGVzIiwiY2xvbmUiLCJjb3B5IiwiX2NvcHlTY29wZXMiLCJleGVjdXRlIiwiaXNOb3JtYWxGaW5kIiwiaXNGaW5kIiwiaGFzU3BlY2lhbFNlbGVjdHMiLCJjb2xsZWN0ZWRTY29wZXMiLCJzY29wZXMiLCJPYmplY3QiLCJlbnRyaWVzIiwiX3Njb3BlcyIsImxlbmd0aCIsInNjb3BlIiwiZ3JhcGgiLCJfYXBwbHlTY29wZSIsImhhc05vcm1hbFNlbGVjdHMiLCJoYXMiLCJoYXNTZWxlY3RzIiwiY2hpbGRRdWVyeU9mIiwicXVlcnkiLCJvcHRpb25zIiwiaXNJbnRlcm5hbCIsInRvRmluZFF1ZXJ5IiwiY2xlYXIiLCJ3aXRoU2NvcGUiLCJleHByIiwiUXVlcnlCdWlsZGVyRXJyb3IiLCJjbGVhcldpdGhTY29wZSIsImlnbm9yZVNjb3BlIiwiYXBwbHlTY29wZSIsImFsbG93U2NvcGUiLCJkZWZhdWx0IiwiY2xlYXJBbGxvd1Njb3BlIiwibWVyZ2VTY29wZSIsImNsZWFyU2NvcGUiLCJhZGREZWZhdWx0IiwiaXNDaGlsZFF1ZXJ5IiwiaXNTYW1lTW9kZWxDbGFzcyIsImNvcHlBbGxTY29wZXMiLCJfZmlsdGVyU2NvcGVzIiwiY2FsbGJhY2siLCJyZWR1Y2UiLCJmdW5jIiwiZ2V0U2NvcGUiLCJjYWxsIiwiZ3JhcGhFeHByZXNzaW9uT2JqZWN0IiwibmFtZSIsIm1vZGlmaWVycyIsIndpdGhHcmFwaCIsImFkZEdyYXBoU2NvcGUiLCJhcHBseUZpbHRlciIsImFyZ3MiLCJmaWx0ZXIiLCJkZWZpbml0aW9uIiwiZmlsdGVycyIsImFuZFdoZXJlIiwiYWxsb3dGaWx0ZXIiLCJhbGdvcml0aG0iLCJtZXRob2QiLCJmZXRjaCIsImpvaW4iLCJ3aXRoR3JhcGhGZXRjaGVkIiwid2l0aEdyYXBoSm9pbmVkIiwidG9TUUwiLCJ0b0tuZXhRdWVyeSIsInJhdyIsInRvS25leFJhdyIsInNlbGVjdFJhdyIsInNlbGVjdCIsInBsdWNrIiwia2V5IiwicnVuQWZ0ZXIiLCJyZXN1bHQiLCJtYXAiLCJpdCIsImxvYWREYXRhUGF0aCIsImRhdGFQYXRoIiwicGFyc2VkRGF0YVBhdGgiLCJwcm9wZXJ0eSIsImV4cHJlc3Npb24iLCJuZXN0ZWREYXRhUGF0aCIsImluZGV4IiwiZ2V0UHJvcGVydHlPclJlbGF0aW9uQXREYXRhUGF0aCIsImluY2x1ZGVzIiwidHlwZSIsInRydW5jYXRlIiwicmVzdGFydCIsImNhc2NhZGUiLCJpc1Bvc3RncmVTUUwiLCJ0YWJsZU5hbWUiLCJpbnNlcnQiLCJkYXRhIiwiaW5zZXJ0R3JhcGgiLCJ1cHNlcnQiLCJtYWluUXVlcnkiLCJydW5CZWZvcmUiLCJidWlsZGVyIiwiY29udGV4dCIsImlzTWFpblF1ZXJ5IiwidXBkYXRlIiwiZmlyc3QiLCJmaW5kIiwiYWxsb3dQYXJhbSIsImFsbG93ZWQiLCJRdWVyeVBhcmFtZXRlcnMiLCJ2YWx1ZSIsInBhcmFtIiwiZW5kc1dpdGgiLCJzbGljZSIsInBhcmFtSGFuZGxlciIsImdldCIsImZpbmRCeUlkIiwiaWQiLCJieUlkIiwicGF0Y2hBbmRGZXRjaEJ5SWQiLCJ1cGRhdGVBbmRGZXRjaEJ5SWQiLCJkZWxldGVCeUlkIiwicGF0Y2hCeUlkIiwicGF0Y2giLCJ1cGRhdGVCeUlkIiwicGF0Y2hBbmRGZXRjaCIsIl91cHNlcnRBbmRGZXRjaCIsInVwZGF0ZUFuZEZldGNoIiwidXBzZXJ0QW5kRmV0Y2giLCJpbnNlcnRNaXNzaW5nIiwibm9JbnNlcnQiLCJnZXRSZWxhdGlvbk5hbWVzIiwidXBzZXJ0R3JhcGhBbmRGZXRjaCIsImZldGNoU3RyYXRlZ3kiLCJub0luc2V0Iiwibm9EZWxldGUiLCJub1JlbGF0ZSIsIm5vVW5yZWxhdGUiLCJpbnNlcnREaXRvR3JhcGgiLCJfaGFuZGxlRGl0b0dyYXBoIiwiaW5zZXJ0RGl0b0dyYXBoT3B0aW9ucyIsImluc2VydERpdG9HcmFwaEFuZEZldGNoIiwidXBzZXJ0RGl0b0dyYXBoIiwidXBzZXJ0RGl0b0dyYXBoT3B0aW9ucyIsInVwc2VydERpdG9HcmFwaEFuZEZldGNoIiwicGF0Y2hEaXRvR3JhcGgiLCJwYXRjaERpdG9HcmFwaE9wdGlvbnMiLCJwYXRjaERpdG9HcmFwaEFuZEZldGNoIiwidXBkYXRlRGl0b0dyYXBoIiwidXBkYXRlRGl0b0dyYXBoT3B0aW9ucyIsInVwZGF0ZURpdG9HcmFwaEFuZEZldGNoIiwidXBzZXJ0RGl0b0dyYXBoQW5kRmV0Y2hCeUlkIiwiZ2V0UmVmZXJlbmNlIiwicGF0Y2hEaXRvR3JhcGhBbmRGZXRjaEJ5SWQiLCJ1cGRhdGVEaXRvR3JhcGhBbmRGZXRjaEJ5SWQiLCJkZWZhdWx0T3B0aW9ucyIsImhhbmRsZUdyYXBoIiwiZ3JhcGhQcm9jZXNzb3IiLCJEaXRvR3JhcGhQcm9jZXNzb3IiLCJwcm9jZXNzT3ZlcnJpZGVzIiwicHJvY2Vzc1JlbGF0ZXMiLCJnZXREYXRhIiwiZ2V0T3B0aW9ucyIsImN5Y2xpYyIsInN0YXJ0c1dpdGgiLCJfdXBzZXJ0Q3ljbGljRGl0b0dyYXBoQW5kRmV0Y2giLCJpZGVudGlmaWVycyIsInJlZmVyZW5jZXMiLCJ1aWRQcm9wIiwidWlkUmVmUHJvcCIsInBhdGgiLCJyZWYiLCJjbG9uZWQiLCJrZXlzIiwicGFydHMiLCJwb3AiLCJwYXJlbnQiLCJvcHRzIiwibW9kZWwiLCJsaW5rcyIsImlkZW50aWZpZXIiLCJyZWZlcmVuY2UiLCJsaW5rIiwibWl4aW4iLCJ0YXJnZXQiLCJtaXhpbk1ldGhvZHMiLCJjb25zb2xlIiwid2FybiIsImRlZmluZVByb3BlcnR5IiwiY29uZmlndXJhYmxlIiwiZW51bWVyYWJsZSIsIktuZXhIZWxwZXIiLCJwcm90b3R5cGUiLCJ0ZXN0IiwicHJvcGVydGllcyIsImV4cGFuZElkZW50aWZpZXIiLCJhbGlhcyIsIm1hdGNoIiwidGFibGVSZWZGb3IiLCJjb252ZXJ0QXJndW1lbnQiLCJhcmciLCJpIiwicmVsYXRlIiwiYWxsb3dSZWZzIiwidW5yZWxhdGUiLCJpc1Jvb3QiLCIkbW9kaWZ5IiwiaGFzU2NvcGUiLCJwdXNoIiwicmVsYXRpb25zIiwiZ2V0UmVsYXRpb25zIiwiY2hpbGRFeHByIiwicmVsYXRpb24iLCIkcmVsYXRpb24iLCJSZWxhdGlvbkVycm9yIiwicmVsYXRlZE1vZGVsQ2xhc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUlBOzs7O0FBRUEsTUFBTUEsVUFBVSxHQUFHQyxNQUFNLENBQUMsS0FBRCxDQUF6Qjs7QUFFTyxNQUFNQyxZQUFOLFNBQTJCQyxtQkFBVUQsWUFBckMsQ0FBa0Q7QUFDdkRFLEVBQUFBLFdBQVcsQ0FBQ0MsVUFBRCxFQUFhO0FBQ3RCLFVBQU1BLFVBQU47QUFDQSxTQUFLQyxZQUFMLEdBQW9CLEtBQXBCO0FBQ0EsU0FBS0MsZUFBTCxHQUF1QixPQUF2QjtBQUNBLFNBQUtDLGFBQUwsR0FBcUIsSUFBckI7QUFDQSxTQUFLQyxZQUFMLEdBQW9CLElBQXBCO0FBQ0EsU0FBS0MsYUFBTCxHQUFxQixFQUFyQjtBQUNBLFNBQUtDLGNBQUwsR0FBc0IsRUFBdEI7QUFDQSxTQUFLQyxhQUFMLEdBQXFCLElBQXJCOztBQUNBLFNBQUtDLFlBQUwsQ0FBa0IsSUFBbEI7QUFDRDs7QUFHREMsRUFBQUEsS0FBSyxHQUFHO0FBQ04sVUFBTUMsSUFBSSxHQUFHLE1BQU1ELEtBQU4sRUFBYjtBQUNBQyxJQUFBQSxJQUFJLENBQUNULFlBQUwsR0FBb0IsS0FBS0EsWUFBekI7QUFDQVMsSUFBQUEsSUFBSSxDQUFDUixlQUFMLEdBQXVCLEtBQUtBLGVBQTVCO0FBQ0FR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NkJBeERtQixFQXlEbkIsNEJBekRtQixFQTJEbkIsT0EzRG1CLEVBNERuQixVQTVEbUIsRUE2RG5CLFVBN0RtQixFQThEbkIsY0E5RG1CLEVBK0RuQixhQS9EbUIsRUFnRW5CLGdCQWhFbUIsRUFpRW5CLFNBakVtQixFQWtFbkIsWUFsRW1CLEVBbUVuQixXQW5FbUIsRUFvRW5CLGNBcEVtQixFQXFFbkIsY0FyRW1CLEVBc0VuQixpQkF0RW1CLEVBdUVuQixhQXZFbUIsRUF3RW5CLGdCQXhFbUIsRUF5RW5CLGdCQXpFbUIsRUEwRW5CLGtCQTFFbUIsRUEyRW5CLHFCQTNFbUIsRUE0RW5CLGlCQTVFbUIsRUE2RW5CLGlCQTdFbUIsRUE4RW5CLGtCQTlFbUIsRUErRW5CLG1CQS9FbUIsRUFnRm5CLG1CQWhGbUIsRUFpRm5CLG9CQWpGbUIsRUFrRm5CLG1CQWxGbUIsRUFtRm5CLHNCQW5GbUIsRUFvRm5CLHFCQXBGbUIsRUFxRm5CLHdCQXJGbUIsRUF1Rm5CLFFBdkZtQixFQXdGbkIsVUF4Rm1CLEVBeUZuQixhQXpGbUIsRUEwRm5CLFlBMUZtQixFQTJGbkIsZUEzRm1CLEVBNEZuQixjQTVGbUIsRUE2Rm5CLGlCQTdGbUIsRUE4Rm5CLGVBOUZtQixFQStGbkIsa0JBL0ZtQixFQWdHbkIsV0FoR21CLEVBaUduQixlQWpHbUIsRUFxR25CLE9BckdtQixFQXNHbkIsV0F0R21CLEVBdUduQixZQXZHbUIsRUF3R25CLFlBeEdtQixFQXlHbkIsZ0JBekdtQixFQTBHbkIsaUJBMUdtQixFQTJHbkIsWUEzR21CLEVBNkduQixPQTdHbUIsRUE4R25CLFlBOUdtQixFQStHbkIsWUEvR21CLENBQXJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG9iamVjdGlvbiBmcm9tICdvYmplY3Rpb24nXG5pbXBvcnQgeyBLbmV4SGVscGVyIH0gZnJvbSAnQC9saWInXG5pbXBvcnQgeyBRdWVyeUJ1aWxkZXJFcnJvciwgUmVsYXRpb25FcnJvciB9IGZyb20gJ0AvZXJyb3JzJ1xuaW1wb3J0IHsgUXVlcnlQYXJhbWV0ZXJzIH0gZnJvbSAnLi9RdWVyeVBhcmFtZXRlcnMnXG5pbXBvcnQgeyBEaXRvR3JhcGhQcm9jZXNzb3IsIHdhbGtHcmFwaCB9IGZyb20gJ0AvZ3JhcGgnXG5pbXBvcnQge1xuICBpc09iamVjdCwgaXNQbGFpbk9iamVjdCwgaXNTdHJpbmcsIGlzQXJyYXksIGNsb25lLCBtYXBLZXlzLFxuICBnZXRWYWx1ZUF0RGF0YVBhdGgsIHNldFZhbHVlQXREYXRhUGF0aCwgcGFyc2VEYXRhUGF0aFxufSBmcm9tICdAZGl0b2pzL3V0aWxzJ1xuaW1wb3J0IHsgY3JlYXRlTG9va3VwLCBnZXRTY29wZSwgZGVwcmVjYXRlIH0gZnJvbSAnQC91dGlscydcblxuY29uc3QgU1lNQk9MX0FMTCA9IFN5bWJvbCgnYWxsJylcblxuZXhwb3J0IGNsYXNzIFF1ZXJ5QnVpbGRlciBleHRlbmRzIG9iamVjdGlvbi5RdWVyeUJ1aWxkZXIge1xuICBjb25zdHJ1Y3Rvcihtb2RlbENsYXNzKSB7XG4gICAgc3VwZXIobW9kZWxDbGFzcylcbiAgICB0aGlzLl9pZ25vcmVHcmFwaCA9IGZhbHNlXG4gICAgdGhpcy5fZ3JhcGhBbGdvcml0aG0gPSAnZmV0Y2gnXG4gICAgdGhpcy5fYWxsb3dGaWx0ZXJzID0gbnVsbFxuICAgIHRoaXMuX2FsbG93U2NvcGVzID0gbnVsbFxuICAgIHRoaXMuX2lnbm9yZVNjb3BlcyA9IHt9XG4gICAgdGhpcy5fYXBwbGllZFNjb3BlcyA9IHt9XG4gICAgdGhpcy5fZXhlY3V0ZUZpcnN0ID0gbnVsbCAvLyBQYXJ0IG9mIGEgd29yay1hcm91bmQgZm9yIGN5Y2xpYyBncmFwaHNcbiAgICB0aGlzLl9jbGVhclNjb3Blcyh0cnVlKVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIGNsb25lKCkge1xuICAgIGNvbnN0IGNvcHkgPSBzdXBlci5jbG9uZSgpXG4gICAgY29weS5faWdub3JlR3JhcGggPSB0aGlzLl9pZ25vcmVHcmFwaFxuICAgIGNvcHkuX2dyYXBoQWxnb3JpdGhtID0gdGhpcy5fZ3JhcGhBbGdvcml0aG1cbiAgICBjb3B5Ll9hcHBsaWVkU2NvcGVzID0geyAuLi50aGlzLl9hcHBsaWVkU2NvcGVzIH1cbiAgICBjb3B5Ll9hbGxvd0ZpbHRlcnMgPSB0aGlzLl9hbGxvd0ZpbHRlcnMgPyB7IC4uLnRoaXMuX2FsbG93RmlsdGVycyB9IDogbnVsbFxuICAgIGNvcHkuX2NvcHlTY29wZXModGhpcylcbiAgICByZXR1cm4gY29weVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIGFzeW5jIGV4ZWN1dGUoKSB7XG4gICAgaWYgKCF0aGlzLl9pZ25vcmVTY29wZXNbU1lNQk9MX0FMTF0pIHtcbiAgICAgIC8vIE9ubHkgYXBwbHkgZGVmYXVsdCBzY29wZXMgaWYgdGhpcyBpcyBhIG5vcm1hbCBmaW5kIHF1ZXJ5LCBtZWFuaW5nIGl0XG4gICAgICAvLyBkb2VzIG5vdCBkZWZpbmUgYW55IHdyaXRlIG9wZXJhdGlvbnMgb3Igc3BlY2lhbCBzZWxlY3RzLCBlLmcuIGBjb3VudGA6XG4gICAgICBjb25zdCBpc05vcm1hbEZpbmQgPSAoXG4gICAgICAgIHRoaXMuaXNGaW5kKCkgJiZcbiAgICAgICAgIXRoaXMuaGFzU3BlY2lhbFNlbGVjdHMoKVxuICAgICAgKVxuICAgICAgLy8gSWYgdGhpcyBpc24ndCBhIG5vcm1hbCBmaW5kIHF1ZXJ5LCBpZ25vcmUgYWxsIGdyYXBoIG9wZXJhdGlvbnMsXG4gICAgICAvLyB0byBub3QgbWVzcyB3aXRoIHNwZWNpYWwgc2VsZWN0cyBzdWNoIGFzIGBjb3VudGAsIGV0YzpcbiAgICAgIHRoaXMuX2lnbm9yZUdyYXBoID0gIWlzTm9ybWFsRmluZFxuICAgICAgLy8gQWxsIHNjb3BlcyBpbiBgX3Njb3Blc2Agd2VyZSBhbHJlYWR5IGNoZWNrZWQgYWdhaW5zdCBgX2FsbG93U2NvcGVzYC5cbiAgICAgIC8vIFRoZXkgdGhlbWVzZWx2ZXMgYXJlIGFsbG93ZWQgdG8gYXBwbHkgLyByZXF1ZXN0IG90aGVyIHNjb3BlcyB0aGF0XG4gICAgICAvLyBhcmVuJ3QgbGlzdGVkLCBzbyBjbGVhciBgX2FwcGx5U2NvcGVgIGFuZCByZXN0b3JlIGFnYWluIGFmdGVyOlxuICAgICAgY29uc3QgeyBfYWxsb3dTY29wZXMgfSA9IHRoaXNcbiAgICAgIHRoaXMuX2FsbG93U2NvcGVzID0gbnVsbFxuICAgICAgY29uc3QgY29sbGVjdGVkU2NvcGVzID0ge31cbiAgICAgIC8vIFNjb3BlcyBjYW4gdGhlbXNlbHZlcyByZXF1ZXN0IG1vcmUgc2NvcGVzIGJ5IGNhbGxpbmcgYHdpdGhTY29wZSgpYFxuICAgICAgLy8gSW4gb3JkZXIgdG8gcHJldmVudCB0aGF0IGZyb20gY2F1c2luZyBwcm9ibGVtcyB3aGlsZSBsb29waW5nIG92ZXJcbiAgICAgIC8vIGBfc2NvcGVzYCwgY3JlYXRlIGEgbG9jYWwgY29weSBvZiB0aGUgZW50cmllcywgc2V0IGBfc2NvcGVzYCB0byBhblxuICAgICAgLy8gZW1wdHkgb2JqZWN0IGR1cmluZyBpdGVyYXRpb24gYW5kIGNoZWNrIGlmIHRoZXJlIGFyZSBuZXcgZW50cmllcyBhZnRlclxuICAgICAgLy8gb25lIGZ1bGwgbG9vcC4gS2VlcCBkb2luZyB0aGlzIHVudGlsIHRoZXJlJ3Mgbm90aGluZyBsZWZ0LCBidXQga2VlcFxuICAgICAgLy8gdHJhY2sgb2YgYWxsIHRoZSBhcHBsaWVkIHNjb3Blcywgc28gYF9zY29wZXNgIGNhbiBiZSBzZXQgdG8gdGhlIHRoZVxuICAgICAgLy8gdGhhdCBpbiB0aGUgZW5kLiBUaGlzIGlzIG5lZWRlZCBmb3IgY2hpbGQgcXVlcmllcywgc2VlIGBjaGlsZFF1ZXJ5T2YoKWBcbiAgICAgIGxldCBzY29wZXMgPSBPYmplY3QuZW50cmllcyh0aGlzLl9zY29wZXMpXG4gICAgICB3aGlsZSAoc2NvcGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5fc2NvcGVzID0ge31cbiAgICAgICAgZm9yIChjb25zdCBbc2NvcGUsIGdyYXBoXSBvZiBzY29wZXMpIHtcbiAgICAgICAgICAvLyBEb24ndCBhcHBseSBgZGVmYXVsdGAgc2NvcGVzIG9uIGFueXRoaW5nIGVsc2UgdGhhbiBhIG5vcm1hbCBmaW5kXG4gICAgICAgICAgLy8gcXVlcnk6XG4gICAgICAgICAgaWYgKHNjb3BlICE9PSAnZGVmYXVsdCcgfHwgaXNOb3JtYWxGaW5kKSB7XG4gICAgICAgICAgICB0aGlzLl9hcHBseVNjb3BlKHNjb3BlLCBncmFwaClcbiAgICAgICAgICAgIGNvbGxlY3RlZFNjb3Blc1tzY29wZV0gfHw9IGdyYXBoXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHNjb3BlcyA9IE9iamVjdC5lbnRyaWVzKHRoaXMuX3Njb3BlcylcbiAgICAgIH1cbiAgICAgIHRoaXMuX3Njb3BlcyA9IGNvbGxlY3RlZFNjb3Blc1xuICAgICAgdGhpcy5fYWxsb3dTY29wZXMgPSBfYWxsb3dTY29wZXNcbiAgICAgIHRoaXMuX2lnbm9yZUdyYXBoID0gZmFsc2VcbiAgICB9XG4gICAgLy8gSW4gY2FzZSBvZiBjeWNsaWMgZ3JhcGhzLCBydW4gYF9leGVjdXRlRmlyc3QoKWAgbm93OlxuICAgIGF3YWl0IHRoaXMuX2V4ZWN1dGVGaXJzdD8uKClcbiAgICByZXR1cm4gc3VwZXIuZXhlY3V0ZSgpXG4gIH1cblxuICBoYXNOb3JtYWxTZWxlY3RzKCkge1xuICAgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgcXVlcnkgZGVmaW5lcyBub3JtYWwgc2VsZWN0czpcbiAgICAvLyAgIHNlbGVjdCgpLCBjb2x1bW4oKSwgY29sdW1ucygpXG4gICAgcmV0dXJuIHRoaXMuaGFzKC9eKHNlbGVjdHxjb2x1bW5zPykkLylcbiAgfVxuXG4gIGhhc1NwZWNpYWxTZWxlY3RzKCkge1xuICAgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgcXVlcnkgZGVmaW5lcyBzcGVjaWFsIHNlbGVjdHM6XG4gICAgLy8gICBkaXN0aW5jdCgpLCBjb3VudCgpLCBjb3VudERpc3RpbmN0KCksIG1pbigpLCBtYXgoKSxcbiAgICAvLyAgIHN1bSgpLCBzdW1EaXN0aW5jdCgpLCBhdmcoKSwgYXZnRGlzdGluY3QoKVxuICAgIHJldHVybiB0aGlzLmhhc1NlbGVjdHMoKSAmJiAhdGhpcy5oYXNOb3JtYWxTZWxlY3RzKClcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBjaGlsZFF1ZXJ5T2YocXVlcnksIG9wdGlvbnMpIHtcbiAgICBzdXBlci5jaGlsZFF1ZXJ5T2YocXVlcnksIG9wdGlvbnMpXG4gICAgaWYgKHRoaXMuaXNJbnRlcm5hbCgpKSB7XG4gICAgICAvLyBJbnRlcm5hbCBxdWVyaWVzIHNob3VsZG4ndCBhcHBseSBvciBpbmhlcml0IGFueSBzY29wZXMsIG5vdCBldmVuIHRoZVxuICAgICAgLy8gZGVmYXVsdCBzY29wZS5cbiAgICAgIHRoaXMuX2NsZWFyU2NvcGVzKGZhbHNlKVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJbmhlcml0IHRoZSBncmFwaCBzY29wZXMgZnJvbSB0aGUgcGFyZW50IHF1ZXJ5LlxuICAgICAgdGhpcy5fY29weVNjb3BlcyhxdWVyeSwgdHJ1ZSlcbiAgICB9XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICB0b0ZpbmRRdWVyeSgpIHtcbiAgICAvLyBUZW1wb3Jhcnkgd29ya2Fyb3VuZCB0byBmaXggdGhpcyBpc3N1ZSB1bnRpbCBpdCBpcyByZXNvbHZlZCBpbiBPYmplY3Rpb246XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL1ZpbmNpdC9vYmplY3Rpb24uanMvaXNzdWVzLzIwOTNcbiAgICByZXR1cm4gc3VwZXIudG9GaW5kUXVlcnkoKS5jbGVhcigncnVuQWZ0ZXInKVxuICB9XG5cbiAgd2l0aFNjb3BlKC4uLnNjb3Blcykge1xuICAgIGZvciAoY29uc3QgZXhwciBvZiBzY29wZXMpIHtcbiAgICAgIGlmIChleHByKSB7XG4gICAgICAgIGNvbnN0IHsgc2NvcGUsIGdyYXBoIH0gPSBnZXRTY29wZShleHByKVxuICAgICAgICBpZiAodGhpcy5fYWxsb3dTY29wZXMgJiYgIXRoaXMuX2FsbG93U2NvcGVzW3Njb3BlXSkge1xuICAgICAgICAgIHRocm93IG5ldyBRdWVyeUJ1aWxkZXJFcnJvcihcbiAgICAgICAgICAgIGBRdWVyeSBzY29wZSAnJHtzY29wZX0nIGlzIG5vdCBhbGxvd2VkLmBcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc2NvcGVzW3Njb3BlXSB8fD0gZ3JhcGhcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8vIENsZWFyIGFsbCBzY29wZXMgZGVmaW5lZCB3aXRoIGB3aXRoU2NvcGUoKWAgc3RhdGVtZW50cywgcHJlc2VydmluZyB0aGVcbiAgLy8gZGVmYXVsdCBzY29wZS5cbiAgY2xlYXJXaXRoU2NvcGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NsZWFyU2NvcGVzKHRydWUpXG4gIH1cblxuICBpZ25vcmVTY29wZSguLi5zY29wZXMpIHtcbiAgICBpZiAoIXRoaXMuX2lnbm9yZVNjb3Blc1tTWU1CT0xfQUxMXSkge1xuICAgICAgdGhpcy5faWdub3JlU2NvcGVzID0gc2NvcGVzLmxlbmd0aCA+IDBcbiAgICAgICAgPyB7XG4gICAgICAgICAgLi4udGhpcy5faWdub3JlU2NvcGVzLFxuICAgICAgICAgIC4uLmNyZWF0ZUxvb2t1cChzY29wZXMpXG4gICAgICAgIH1cbiAgICAgICAgLy8gRW1wdHkgYXJndW1lbnRzID0gaWdub3JlIGFsbCBzY29wZXNcbiAgICAgICAgOiB7XG4gICAgICAgICAgW1NZTUJPTF9BTExdOiB0cnVlXG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIGFwcGx5U2NvcGUoLi4uc2NvcGVzKSB7XG4gICAgLy8gV2hlbiBkaXJlY3RseSBhcHBseWluZyBhIHNjb3BlLCBzdGlsbCBtZXJnZSBpdCBpbnRvIGB0aGlzLl9zY29wZXNgLFxuICAgIC8vIHNvIGl0IGNhbiBzdGlsbCBiZSBwYXNzZWQgb24gdG8gZm9ya2VkIGNoaWxkIHF1ZXJpZXMuIFRoaXMgYWxzbyBoYW5kbGVzXG4gICAgLy8gdGhlIGNoZWNrcyBhZ2FpbnN0IGBfYWxsb3dTY29wZXNgLlxuICAgIHRoaXMud2l0aFNjb3BlKC4uLnNjb3BlcylcbiAgICBmb3IgKGNvbnN0IGV4cHIgb2Ygc2NvcGVzKSB7XG4gICAgICBpZiAoZXhwcikge1xuICAgICAgICBjb25zdCB7IHNjb3BlLCBncmFwaCB9ID0gZ2V0U2NvcGUoZXhwcilcbiAgICAgICAgdGhpcy5fYXBwbHlTY29wZShzY29wZSwgZ3JhcGgpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBhbGxvd1Njb3BlKC4uLnNjb3Blcykge1xuICAgIHRoaXMuX2FsbG93U2NvcGVzID0gdGhpcy5fYWxsb3dTY29wZXMgfHwge1xuICAgICAgZGVmYXVsdDogdHJ1ZSAvLyBUaGUgZGVmYXVsdCBzY29wZSBpcyBhbHdheXMgYWxsb3dlZC5cbiAgICB9XG4gICAgZm9yIChjb25zdCBleHByIG9mIHNjb3Blcykge1xuICAgICAgaWYgKGV4cHIpIHtcbiAgICAgICAgY29uc3QgeyBzY29wZSB9ID0gZ2V0U2NvcGUoZXhwcilcbiAgICAgICAgdGhpcy5fYWxsb3dTY29wZXNbc2NvcGVdID0gdHJ1ZVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNsZWFyQWxsb3dTY29wZSgpIHtcbiAgICB0aGlzLl9hbGxvd1Njb3BlcyA9IG51bGxcbiAgfVxuXG4gIHNjb3BlKC4uLnNjb3Blcykge1xuICAgIGRlcHJlY2F0ZShgUXVlcnlCdWlsZGVyI3Njb3BlKCkgaXMgZGVwcmVjYXRlZC4gVXNlICN3aXRoU2NvcGUoKSBpbnN0ZWFkLmApXG5cbiAgICByZXR1cm4gdGhpcy5jbGVhcldpdGhTY29wZSgpLndpdGhTY29wZSguLi5zY29wZXMpXG4gIH1cblxuICBtZXJnZVNjb3BlKC4uLnNjb3Blcykge1xuICAgIGRlcHJlY2F0ZShgUXVlcnlCdWlsZGVyI21lcmdlU2NvcGUoKSBpcyBkZXByZWNhdGVkLiBVc2UgI3dpdGhTY29wZSgpIGluc3RlYWQuYClcblxuICAgIHJldHVybiB0aGlzLndpdGhTY29wZSguLi5zY29wZXMpXG4gIH1cblxuICBjbGVhclNjb3BlKCkge1xuICAgIGRlcHJlY2F0ZShgUXVlcnlCdWlsZGVyI2NsZWFyU2NvcGUoKSBpcyBkZXByZWNhdGVkLiBVc2UgI2NsZWFyV2l0aFNjb3BlKCkgb3IgI2lnbm9yZVNjb3BlKCkgaW5zdGVhZC5gKVxuXG4gICAgcmV0dXJuIHRoaXMuY2xlYXJXaXRoU2NvcGUoKVxuICB9XG5cbiAgX2NsZWFyU2NvcGVzKGFkZERlZmF1bHQpIHtcbiAgICAvLyBgX3Njb3Blc2AgaXMgYW4gb2JqZWN0IHdoZXJlIHRoZSBrZXlzIGFyZSB0aGUgc2NvcGVzIGFuZCB0aGUgdmFsdWVzXG4gICAgLy8gaW5kaWNhdGUgaWYgdGhlIHNjb3BlIHNob3VsZCBiZSBlYWdlci1hcHBsaWVkIG9yIG5vdDpcbiAgICB0aGlzLl9zY29wZXMgPSBhZGREZWZhdWx0XG4gICAgICA/IHsgZGVmYXVsdDogdHJ1ZSB9IC8vIGVhZ2VyLWFwcGx5IHRoZSBkZWZhdWx0IHNjb3BlXG4gICAgICA6IHt9XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIF9jb3B5U2NvcGVzKHF1ZXJ5LCBpc0NoaWxkUXVlcnkgPSBmYWxzZSkge1xuICAgIGNvbnN0IGlzU2FtZU1vZGVsQ2xhc3MgPSB0aGlzLm1vZGVsQ2xhc3MoKSA9PT0gcXVlcnkubW9kZWxDbGFzcygpXG4gICAgLy8gT25seSBjb3B5IGBfYWxsb3dTY29wZXNgIGFuZCBgX2lnbm9yZVNjb3Blc2AgaWYgaXQncyBmb3IgdGhlIHNhbWUgbW9kZWwuXG4gICAgaWYgKGlzU2FtZU1vZGVsQ2xhc3MpIHtcbiAgICAgIHRoaXMuX2FsbG93U2NvcGVzID0gcXVlcnkuX2FsbG93U2NvcGVzID8geyAuLi5xdWVyeS5fYWxsb3dTY29wZXMgfSA6IG51bGxcbiAgICAgIHRoaXMuX2lnbm9yZVNjb3BlcyA9IHsgLi4ucXVlcnkuX2lnbm9yZVNjb3BlcyB9XG4gICAgfVxuICAgIC8vIElmIGhlIHRhcmdldCBpcyBhIGNoaWxkIHF1ZXJ5IG9mIGEgZ3JhcGggcXVlcnksIGNvcHkgYWxsIHNjb3BlcywgZ3JhcGhcbiAgICAvLyBhbmQgbm9uLWdyYXBoLiBJZiBpdCBpcyBhIGNoaWxkIHF1ZXJ5IG9mIGEgcmVsYXRlZCBvciBlYWdlciBxdWVyeSxcbiAgICAvLyBjb3B5IG9ubHkgdGhlIGdyYXBoIHNjb3Blcy5cbiAgICBjb25zdCBjb3B5QWxsU2NvcGVzID1cbiAgICAgIGlzU2FtZU1vZGVsQ2xhc3MgJiYgaXNDaGlsZFF1ZXJ5ICYmIHF1ZXJ5LmhhcygvR3JhcGhBbmRGZXRjaCQvKVxuICAgIHRoaXMuX3Njb3BlcyA9IHRoaXMuX2ZpbHRlclNjb3BlcyhxdWVyeS5fc2NvcGVzLCAoc2NvcGUsIGdyYXBoKSA9PlxuICAgICAgY29weUFsbFNjb3BlcyB8fCBncmFwaClcbiAgfVxuXG4gIF9maWx0ZXJTY29wZXMoc2NvcGVzLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhzY29wZXMpLnJlZHVjZShcbiAgICAgIChzY29wZXMsIFtzY29wZSwgZ3JhcGhdKSA9PiB7XG4gICAgICAgIGlmIChjYWxsYmFjayhzY29wZSwgZ3JhcGgpKSB7XG4gICAgICAgICAgc2NvcGVzW3Njb3BlXSA9IGdyYXBoXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjb3Blc1xuICAgICAgfSxcbiAgICAgIHt9XG4gICAgKVxuICB9XG5cbiAgX2FwcGx5U2NvcGUoc2NvcGUsIGdyYXBoKSB7XG4gICAgaWYgKCF0aGlzLl9pZ25vcmVTY29wZXNbU1lNQk9MX0FMTF0gJiYgIXRoaXMuX2lnbm9yZVNjb3Blc1tzY29wZV0pIHtcbiAgICAgIC8vIFByZXZlbnQgbXVsdGlwbGUgYXBwbGljYXRpb24gb2Ygc2NvcGVzLiBUaGlzIGNhbiBlYXNpbHkgb2NjdXJcbiAgICAgIC8vIHdpdGggdGhlIG5lc3RpbmcgYW5kIGVhZ2VyLWFwcGxpY2F0aW9uIG9mIGdyYXBoLXNjb3Blcywgc2VlIGJlbG93LlxuICAgICAgaWYgKCF0aGlzLl9hcHBsaWVkU2NvcGVzW3Njb3BlXSkge1xuICAgICAgICAvLyBPbmx5IGFwcGx5IGdyYXBoLXNjb3BlcyB0aGF0IGFyZSBhY3R1YWxseSBkZWZpbmVkIG9uIHRoZSBtb2RlbDpcbiAgICAgICAgY29uc3QgZnVuYyA9IHRoaXMubW9kZWxDbGFzcygpLmdldFNjb3BlKHNjb3BlKVxuICAgICAgICBpZiAoZnVuYykge1xuICAgICAgICAgIGZ1bmMuY2FsbCh0aGlzLCB0aGlzKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2FwcGxpZWRTY29wZXNbc2NvcGVdID0gdHJ1ZVxuICAgICAgfVxuICAgICAgaWYgKGdyYXBoKSB7XG4gICAgICAgIC8vIEFsc28gYmFrZSB0aGUgc2NvcGUgaW50byBhbnkgZ3JhcGggZXhwcmVzc2lvbiB0aGF0IG1heSBoYXZlIGJlZW5cbiAgICAgICAgLy8gc2V0IGFscmVhZHkgdXNpbmcgYHdpdGhHcmFwaCgpYCAmIGNvLlxuICAgICAgICBjb25zdCBleHByID0gdGhpcy5ncmFwaEV4cHJlc3Npb25PYmplY3QoKVxuICAgICAgICBpZiAoZXhwcikge1xuICAgICAgICAgIC8vIEFkZCBhIG5ldyBtb2RpZmllciB0byB0aGUgZXhpc3RpbmcgZ3JhcGggZXhwcmVzc2lvbiB0aGF0XG4gICAgICAgICAgLy8gcmVjdXJzaXZlbHkgYXBwbGllcyB0aGUgZ3JhcGgtc2NvcGUgdG8gdGhlIHJlc3VsdGluZyBxdWVyaWVzLlxuICAgICAgICAgIC8vIFRoaXMgZXZlbiB3b3JrcyBpZiBuZXN0ZWQgc2NvcGVzIGV4cGFuZCB0aGUgZ3JhcGggZXhwcmVzc2lvbixcbiAgICAgICAgICAvLyBiZWNhdXNlIGl0IHJlLWFwcGxpZXMgaXRzZWxmIHRvIHRoZSByZXN1bHQuXG4gICAgICAgICAgY29uc3QgbmFtZSA9IGBeJHtzY29wZX1gXG4gICAgICAgICAgY29uc3QgbW9kaWZpZXJzID0ge1xuICAgICAgICAgICAgW25hbWVdOiBxdWVyeSA9PiBxdWVyeS5fYXBwbHlTY29wZShzY29wZSwgZ3JhcGgpXG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMud2l0aEdyYXBoKFxuICAgICAgICAgICAgYWRkR3JhcGhTY29wZSh0aGlzLm1vZGVsQ2xhc3MoKSwgZXhwciwgW25hbWVdLCBtb2RpZmllcnMsIHRydWUpXG4gICAgICAgICAgKS5tb2RpZmllcnMobW9kaWZpZXJzKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXBwbHlGaWx0ZXIobmFtZSwgLi4uYXJncykge1xuICAgIGlmICh0aGlzLl9hbGxvd0ZpbHRlcnMgJiYgIXRoaXMuX2FsbG93RmlsdGVyc1tuYW1lXSkge1xuICAgICAgdGhyb3cgbmV3IFF1ZXJ5QnVpbGRlckVycm9yKGBRdWVyeSBmaWx0ZXIgJyR7bmFtZX0nIGlzIG5vdCBhbGxvd2VkLmApXG4gICAgfVxuICAgIGNvbnN0IGZpbHRlciA9IHRoaXMubW9kZWxDbGFzcygpLmRlZmluaXRpb24uZmlsdGVyc1tuYW1lXVxuICAgIGlmICghZmlsdGVyKSB7XG4gICAgICB0aHJvdyBuZXcgUXVlcnlCdWlsZGVyRXJyb3IoYFF1ZXJ5IGZpbHRlciAnJHtuYW1lfScgaXMgbm90IGRlZmluZWQuYClcbiAgICB9XG4gICAgLy8gTk9URTogRmlsdGVycyBhcmUgYXV0b21hdGljYWxseSBjb21iaW5lIHdpdGggYW5kIG9wZXJhdGlvbnMhXG4gICAgcmV0dXJuIHRoaXMuYW5kV2hlcmUocXVlcnkgPT4gZmlsdGVyKHF1ZXJ5LCAuLi5hcmdzKSlcbiAgfVxuXG4gIGFsbG93RmlsdGVyKC4uLmZpbHRlcnMpIHtcbiAgICB0aGlzLl9hbGxvd0ZpbHRlcnMgPSB0aGlzLl9hbGxvd0ZpbHRlcnMgfHwge31cbiAgICBmb3IgKGNvbnN0IGZpbHRlciBvZiBmaWx0ZXJzKSB7XG4gICAgICB0aGlzLl9hbGxvd0ZpbHRlcnNbZmlsdGVyXSA9IHRydWVcbiAgICB9XG4gIH1cblxuICAvLyBBIGFsZ29yaXRobS1hZ25vc3RpYyB2ZXJzaW9uIG9mIGB3aXRoR3JhcGhGZXRjaGVkKClgIC8gYHdpdGhHcmFwaEpvaW5lZCgpYCxcbiAgLy8gd2l0aCB0aGUgYWxnb3JpdGhtIHNwZWNpZmlhYmxlIGluIHRoZSBvcHRpb25zLiBBZGRpdGlvbmFsbHksIGl0IGhhbmRsZXNcbiAgLy8gYF9pZ25vcmVHcmFwaGAgYW5kIGBfZ3JhcGhBbGdvcml0aG1gOlxuICB3aXRoR3JhcGgoZXhwciwgb3B0aW9ucyA9IHt9KSB7XG4gICAgLy8gVG8gbWFrZSBtZXJnaW5nIGVhc2llciwga2VlcCB0aGUgY3VycmVudCBhbGdvcml0aG0gaWYgbm9uZSBpcyBzcGVjaWZpZWQ6XG4gICAgY29uc3QgeyBhbGdvcml0aG0gPSB0aGlzLl9ncmFwaEFsZ29yaXRobSB9ID0gb3B0aW9uc1xuICAgIGNvbnN0IG1ldGhvZCA9IHtcbiAgICAgIGZldGNoOiAnd2l0aEdyYXBoRmV0Y2hlZCcsXG4gICAgICBqb2luOiAnd2l0aEdyYXBoSm9pbmVkJ1xuICAgIH1bYWxnb3JpdGhtXVxuICAgIGlmICghbWV0aG9kKSB7XG4gICAgICB0aHJvdyBuZXcgUXVlcnlCdWlsZGVyRXJyb3IoXG4gICAgICAgIGBHcmFwaCBhbGdvcml0aG0gJyR7YWxnb3JpdGhtfScgaXMgdW5zdXBwb3J0ZWQuYFxuICAgICAgKVxuICAgIH1cbiAgICBpZiAoIXRoaXMuX2lnbm9yZUdyYXBoKSB7XG4gICAgICB0aGlzLl9ncmFwaEFsZ29yaXRobSA9IGFsZ29yaXRobVxuICAgICAgc3VwZXJbbWV0aG9kXShleHByLCBvcHRpb25zKVxuICAgIH1cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIHdpdGhHcmFwaEZldGNoZWQoZXhwciwgb3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLndpdGhHcmFwaChleHByLCB7IC4uLm9wdGlvbnMsIGFsZ29yaXRobTogJ2ZldGNoJyB9KVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIHdpdGhHcmFwaEpvaW5lZChleHByLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMud2l0aEdyYXBoKGV4cHIsIHsgLi4ub3B0aW9ucywgYWxnb3JpdGhtOiAnam9pbicgfSlcbiAgfVxuXG4gIHRvU1FMKCkge1xuICAgIHJldHVybiB0aGlzLnRvS25leFF1ZXJ5KCkudG9TUUwoKVxuICB9XG5cbiAgcmF3KC4uLmFyZ3MpIHtcbiAgICAvLyBUT0RPOiBGaWd1cmUgb3V0IGEgd2F5IHRvIHN1cHBvcnQgYG9iamVjdC5yYXcoKWAgc3ludGF4IGFuZCByZXR1cm4gYSBrbmV4XG4gICAgLy8gcmF3IGV4cHJlc3Npb24gd2l0aG91dCBhY2Nlc3NpbmcgdGhlIHByaXZhdGUgYFJhd0J1aWxkZXIudG9LbmV4UmF3KClgOlxuICAgIHJldHVybiBvYmplY3Rpb24ucmF3KC4uLmFyZ3MpLnRvS25leFJhdyh0aGlzKVxuICB9XG5cbiAgc2VsZWN0UmF3KC4uLmFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Qob2JqZWN0aW9uLnJhdyguLi5hcmdzKSlcbiAgfVxuXG4gIC8vIE5vbi1kZXByZWNhdGVkIHZlcnNpb24gb2YgT2JqZWN0aW9uJ3MgYHBsdWNrKClgXG4gIHBsdWNrKGtleSkge1xuICAgIHJldHVybiB0aGlzLnJ1bkFmdGVyKHJlc3VsdCA9PlxuICAgICAgaXNBcnJheShyZXN1bHQpXG4gICAgICAgID8gcmVzdWx0Lm1hcChpdCA9PiBpdD8uW2tleV0pXG4gICAgICAgIDogaXNPYmplY3QocmVzdWx0KVxuICAgICAgICAgID8gcmVzdWx0W2tleV1cbiAgICAgICAgICA6IHJlc3VsdFxuICAgIClcbiAgfVxuXG4gIGxvYWREYXRhUGF0aChkYXRhUGF0aCwgb3B0aW9ucykge1xuICAgIGNvbnN0IHBhcnNlZERhdGFQYXRoID0gcGFyc2VEYXRhUGF0aChkYXRhUGF0aClcblxuICAgIGNvbnN0IHtcbiAgICAgIHByb3BlcnR5LFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIG5lc3RlZERhdGFQYXRoLFxuICAgICAgbmFtZSxcbiAgICAgIGluZGV4XG4gICAgfSA9IHRoaXMubW9kZWxDbGFzcygpLmdldFByb3BlcnR5T3JSZWxhdGlvbkF0RGF0YVBhdGgocGFyc2VkRGF0YVBhdGgpXG5cbiAgICBpZiAobmVzdGVkRGF0YVBhdGgpIHtcbiAgICAgIC8vIE9uY2UgYSBKU09OIGRhdGEgdHlwZSBpcyByZWFjaGVkLCBldmVuIGlmIGl0J3Mgbm90IGF0IHRoZSBlbmQgb2YgdGhlXG4gICAgICAvLyBwcm92aWRlZCBwYXRoLCBsb2FkIGl0IGFuZCBhc3N1bWUgd2UncmUgZG9uZSB3aXRoIHRoZSBsb2FkaW5nIHBhcnQuXG4gICAgICBpZiAoIShwcm9wZXJ0eSAmJiBbJ29iamVjdCcsICdhcnJheSddLmluY2x1ZGVzKHByb3BlcnR5LnR5cGUpKSkge1xuICAgICAgICB0aHJvdyBuZXcgUXVlcnlCdWlsZGVyRXJyb3IoXG4gICAgICAgICAgYFVuYWJsZSB0byBsb2FkIGZ1bGwgZGF0YS1wYXRoICcke1xuICAgICAgICAgICAgZGF0YVBhdGhcbiAgICAgICAgICB9JyAoVW5tYXRjaGVkOiAnJHtcbiAgICAgICAgICAgIG5lc3RlZERhdGFQYXRoXG4gICAgICAgICAgfScpLmBcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSB0aGUgc3BlY2lhbCBjYXNlIG9mIHJvb3QtbGV2ZWwgcHJvcGVydHkgc2VwYXJhdGVseSxcbiAgICAvLyBiZWNhdXNlIGB3aXRoR3JhcGgoJygjcHJvcGVydHlOYW1lKScpYCBpcyBub3Qgc3VwcG9ydGVkLlxuICAgIGlmIChwcm9wZXJ0eSAmJiBpbmRleCA9PT0gMCkge1xuICAgICAgdGhpcy5zZWxlY3QobmFtZSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy53aXRoR3JhcGgoZXhwcmVzc2lvbiwgb3B0aW9ucylcbiAgICB9XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICB0cnVuY2F0ZSh7IHJlc3RhcnQgPSB0cnVlLCBjYXNjYWRlID0gZmFsc2UgfSA9IHt9KSB7XG4gICAgaWYgKHRoaXMuaXNQb3N0Z3JlU1FMKCkpIHtcbiAgICAgIC8vIFN1cHBvcnQgYHJlc3RhcnRgIGFuZCBgY2FzY2FkZWAgaW4gUG9zdGdyZVNRTCB0cnVuY2F0ZSBxdWVyaWVzLlxuICAgICAgcmV0dXJuIHRoaXMucmF3KFxuICAgICAgICBgdHJ1bmNhdGUgdGFibGUgPz8ke1xuICAgICAgICAgIHJlc3RhcnQgPyAnIHJlc3RhcnQgaWRlbnRpdHknIDogJyd9JHtcbiAgICAgICAgICBjYXNjYWRlID8gJyBjYXNjYWRlJyA6ICcnXG4gICAgICAgIH1gLFxuICAgICAgICB0aGlzLm1vZGVsQ2xhc3MoKS50YWJsZU5hbWVcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIHN1cGVyLnRydW5jYXRlKClcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBpbnNlcnQoZGF0YSkge1xuICAgIC8vIE9ubHkgUG9zdGdyZVNRTCBpcyBhYmxlIHRvIGluc2VydCBtdWx0aXBsZSBlbnRyaWVzIGF0IG9uY2UgaXQgc2VlbXMsXG4gICAgLy8gYWxsIG90aGVycyBoYXZlIHRvIGZhbGwgYmFjayBvbiBpbnNlcnRHcmFwaCgpIHRvIGRvIHNvIGZvciBub3c6XG4gICAgcmV0dXJuICF0aGlzLmlzUG9zdGdyZVNRTCgpICYmIGlzQXJyYXkoZGF0YSkgJiYgZGF0YS5sZW5ndGggPiAxXG4gICAgICA/IHRoaXMuaW5zZXJ0R3JhcGgoZGF0YSlcbiAgICAgIDogc3VwZXIuaW5zZXJ0KGRhdGEpXG4gIH1cblxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vVmluY2l0L29iamVjdGlvbi5qcy9pc3N1ZXMvMTAxI2lzc3VlY29tbWVudC0yMDAzNjM2NjdcbiAgdXBzZXJ0KGRhdGEsIG9wdGlvbnMgPSB7fSkge1xuICAgIGxldCBtYWluUXVlcnlcbiAgICByZXR1cm4gdGhpc1xuICAgICAgLnJ1bkJlZm9yZSgocmVzdWx0LCBidWlsZGVyKSA9PiB7XG4gICAgICAgIGlmICghYnVpbGRlci5jb250ZXh0KCkuaXNNYWluUXVlcnkpIHtcbiAgICAgICAgICAvLyBBdCB0aGlzIHBvaW50IHRoZSBidWlsZGVyIHNob3VsZCBvbmx5IGNvbnRhaW4gYSBidW5jaCBvZiBgd2hlcmUqYFxuICAgICAgICAgIC8vIG9wZXJhdGlvbnMuIFN0b3JlIHRoaXMgcXVlcnkgZm9yIGxhdGVyIHVzZSBpbiBydW5BZnRlcigpLiBBbHNvIG1hcmtcbiAgICAgICAgICAvLyB0aGUgcXVlcnkgd2l0aCBgaXNNYWluUXVlcnk6IHRydWVgIHNvIHdlIGNhbiBza2lwIGFsbCB0aGlzIHdoZW5cbiAgICAgICAgICAvLyB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmb3IgdGhlIGBtYWluUXVlcnlgLlxuICAgICAgICAgIG1haW5RdWVyeSA9IGJ1aWxkZXIuY2xvbmUoKS5jb250ZXh0KHsgaXNNYWluUXVlcnk6IHRydWUgfSlcbiAgICAgICAgICAvLyBDYWxsIHVwZGF0ZSgpIG9uIHRoZSBvcmlnaW5hbCBxdWVyeSwgdHVybmluZyBpdCBpbnRvIGFuIHVwZGF0ZS5cbiAgICAgICAgICBidWlsZGVyW29wdGlvbnMudXBkYXRlID8gJ3VwZGF0ZScgOiAncGF0Y2gnXShkYXRhKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgIH0pXG4gICAgICAucnVuQWZ0ZXIoKHJlc3VsdCwgYnVpbGRlcikgPT4ge1xuICAgICAgICBpZiAoIWJ1aWxkZXIuY29udGV4dCgpLmlzTWFpblF1ZXJ5KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gMFxuICAgICAgICAgICAgPyBtYWluUXVlcnlbb3B0aW9ucy5mZXRjaCA/ICdpbnNlcnRBbmRGZXRjaCcgOiAnaW5zZXJ0J10oZGF0YSlcbiAgICAgICAgICAgIC8vIFdlIGNhbiB1c2UgdGhlIGBtYWluUXVlcnlgIHdlIHNhdmVkIGluIHJ1bkJlZm9yZSgpIHRvIGZldGNoIHRoZVxuICAgICAgICAgICAgLy8gaW5zZXJ0ZWQgcmVzdWx0cy4gSXQgaXMgbm90ZXdvcnRoeSB0aGF0IHRoaXMgcXVlcnkgd2lsbCByZXR1cm5cbiAgICAgICAgICAgIC8vIHRoZSB3cm9uZyByZXN1bHRzIGlmIHRoZSB1cGRhdGUgY2hhbmdlZCBhbnkgb2YgdGhlIGNvbHVtbnMgdGhlXG4gICAgICAgICAgICAvLyB3aGVyZSBvcGVyYXRlcyB3aXRoLiBUaGlzIGFsc28gcmV0dXJucyBhbGwgdXBkYXRlZCBtb2RlbHMuXG4gICAgICAgICAgICA6IG1haW5RdWVyeS5maXJzdCgpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgfSlcbiAgfVxuXG4gIGZpbmQocXVlcnksIGFsbG93UGFyYW0pIHtcbiAgICBpZiAoIXF1ZXJ5KSByZXR1cm4gdGhpc1xuICAgIGNvbnN0IGFsbG93ZWQgPSAhYWxsb3dQYXJhbVxuICAgICAgPyBRdWVyeVBhcmFtZXRlcnMuYWxsb3dlZCgpXG4gICAgICAvLyBJZiBpdCdzIGFscmVhZHkgYSBsb29rdXAgb2JqZWN0IGp1c3QgdXNlIGl0LCBvdGhlcndpc2UgY29udmVydCBpdDpcbiAgICAgIDogaXNQbGFpbk9iamVjdChhbGxvd1BhcmFtKSA/IGFsbG93UGFyYW0gOiBjcmVhdGVMb29rdXAoYWxsb3dQYXJhbSlcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhxdWVyeSkpIHtcbiAgICAgIC8vIFN1cHBvcnQgYXJyYXkgbm90YXRpb24gZm9yIG11bHRpcGxlIHBhcmFtZXRlcnMsIGFzIHNlbnQgYnkgYXhpb3M6XG4gICAgICBjb25zdCBwYXJhbSA9IGtleS5lbmRzV2l0aCgnW10nKSA/IGtleS5zbGljZSgwLCAtMikgOiBrZXlcbiAgICAgIGlmICghYWxsb3dlZFtwYXJhbV0pIHtcbiAgICAgICAgdGhyb3cgbmV3IFF1ZXJ5QnVpbGRlckVycm9yKGBRdWVyeSBwYXJhbWV0ZXIgJyR7a2V5fScgaXMgbm90IGFsbG93ZWQuYClcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBhcmFtSGFuZGxlciA9IFF1ZXJ5UGFyYW1ldGVycy5nZXQocGFyYW0pXG4gICAgICBpZiAoIXBhcmFtSGFuZGxlcikge1xuICAgICAgICB0aHJvdyBuZXcgUXVlcnlCdWlsZGVyRXJyb3IoXG4gICAgICAgICAgYEludmFsaWQgcXVlcnkgcGFyYW1ldGVyICcke3BhcmFtfScgaW4gJyR7a2V5fT0ke3ZhbHVlfScuYClcbiAgICAgIH1cbiAgICAgIHBhcmFtSGFuZGxlcih0aGlzLCBrZXksIHZhbHVlKVxuICAgIH1cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIGZpbmRCeUlkKGlkKSB7XG4gICAgLy8gUmVtZW1iZXIgaWQgc28gTW9kZWwuY3JlYXRlTm90Rm91bmRFcnJvcigpIGNhbiByZXBvcnQgaXQ6XG4gICAgdGhpcy5jb250ZXh0KHsgYnlJZDogaWQgfSlcbiAgICByZXR1cm4gc3VwZXIuZmluZEJ5SWQoaWQpXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgcGF0Y2hBbmRGZXRjaEJ5SWQoaWQsIGRhdGEpIHtcbiAgICB0aGlzLmNvbnRleHQoeyBieUlkOiBpZCB9KVxuICAgIHJldHVybiBzdXBlci5wYXRjaEFuZEZldGNoQnlJZChpZCwgZGF0YSlcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICB1cGRhdGVBbmRGZXRjaEJ5SWQoaWQsIGRhdGEpIHtcbiAgICB0aGlzLmNvbnRleHQoeyBieUlkOiBpZCB9KVxuICAgIHJldHVybiBzdXBlci51cGRhdGVBbmRGZXRjaEJ5SWQoaWQsIGRhdGEpXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgZGVsZXRlQnlJZChpZCkge1xuICAgIHRoaXMuY29udGV4dCh7IGJ5SWQ6IGlkIH0pXG4gICAgcmV0dXJuIHN1cGVyLmRlbGV0ZUJ5SWQoaWQpXG4gIH1cblxuICBwYXRjaEJ5SWQoaWQsIGRhdGEpIHtcbiAgICByZXR1cm4gdGhpcy5maW5kQnlJZChpZCkucGF0Y2goZGF0YSlcbiAgfVxuXG4gIHVwZGF0ZUJ5SWQoaWQsIGRhdGEpIHtcbiAgICByZXR1cm4gdGhpcy5maW5kQnlJZChpZCkudXBkYXRlKGRhdGEpXG4gIH1cblxuICAvLyBFeHRlbmQgT2JqZWN0aW9uJ3MgYHBhdGNoQW5kRmV0Y2goKWAgYW5kIGB1cGRhdGVBbmRGZXRjaCgpYCB0byBhbHNvIHN1cHBvcnRcbiAgLy8gYXJyYXlzIG9mIG1vZGVscywgbm90IG9ubHkgc2luZ2xlIGluc3RhbmNlcy5cbiAgLy8gU2VlOiBodHRwczovL2dpdHRlci5pbS9WaW5jaXQvb2JqZWN0aW9uLmpzP2F0PTVmOTk0YTU5MDBhMGYzMzY5ZDM2NmQ2ZlxuXG4gIHBhdGNoQW5kRmV0Y2goZGF0YSkge1xuICAgIHJldHVybiBpc0FycmF5KGRhdGEpXG4gICAgICA/IHRoaXMuX3Vwc2VydEFuZEZldGNoKGRhdGEpXG4gICAgICA6IHN1cGVyLnBhdGNoQW5kRmV0Y2goZGF0YSlcbiAgfVxuXG4gIHVwZGF0ZUFuZEZldGNoKGRhdGEpIHtcbiAgICByZXR1cm4gaXNBcnJheShkYXRhKVxuICAgICAgPyB0aGlzLl91cHNlcnRBbmRGZXRjaChkYXRhLCB7IHVwZGF0ZTogdHJ1ZSB9KVxuICAgICAgOiBzdXBlci51cGRhdGVBbmRGZXRjaChkYXRhKVxuICB9XG5cbiAgdXBzZXJ0QW5kRmV0Y2goZGF0YSkge1xuICAgIHJldHVybiB0aGlzLl91cHNlcnRBbmRGZXRjaChkYXRhLCB7XG4gICAgICAvLyBJbnNlcnQgbWlzc2luZyBub2RlcyBvbmx5IGF0IHJvb3QgYnkgYWxsb3dpbmcgYGluc2VydE1pc3NpbmdgLFxuICAgICAgLy8gYnV0IHNldCBgbm9JbnNlcnRgIGZvciBhbGwgcmVsYXRpb25zOlxuICAgICAgaW5zZXJ0TWlzc2luZzogdHJ1ZSxcbiAgICAgIG5vSW5zZXJ0OiB0aGlzLm1vZGVsQ2xhc3MoKS5nZXRSZWxhdGlvbk5hbWVzKClcbiAgICB9KVxuICB9XG5cbiAgX3Vwc2VydEFuZEZldGNoKGRhdGEsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy51cHNlcnRHcmFwaEFuZEZldGNoKGRhdGEsIHtcbiAgICAgIGZldGNoU3RyYXRlZ3k6ICdPbmx5TmVlZGVkJyxcbiAgICAgIG5vSW5zZXQ6IHRydWUsXG4gICAgICBub0RlbGV0ZTogdHJ1ZSxcbiAgICAgIG5vUmVsYXRlOiB0cnVlLFxuICAgICAgbm9VbnJlbGF0ZTogdHJ1ZSxcbiAgICAgIC4uLm9wdGlvbnNcbiAgICB9KVxuICB9XG5cbiAgaW5zZXJ0RGl0b0dyYXBoKGRhdGEsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5faGFuZGxlRGl0b0dyYXBoKCdpbnNlcnRHcmFwaCcsXG4gICAgICBkYXRhLCBvcHRpb25zLCBpbnNlcnREaXRvR3JhcGhPcHRpb25zKVxuICB9XG5cbiAgaW5zZXJ0RGl0b0dyYXBoQW5kRmV0Y2goZGF0YSwgb3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLl9oYW5kbGVEaXRvR3JhcGgoJ2luc2VydEdyYXBoQW5kRmV0Y2gnLFxuICAgICAgZGF0YSwgb3B0aW9ucywgaW5zZXJ0RGl0b0dyYXBoT3B0aW9ucylcbiAgfVxuXG4gIHVwc2VydERpdG9HcmFwaChkYXRhLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuX2hhbmRsZURpdG9HcmFwaCgndXBzZXJ0R3JhcGgnLFxuICAgICAgZGF0YSwgb3B0aW9ucywgdXBzZXJ0RGl0b0dyYXBoT3B0aW9ucylcbiAgfVxuXG4gIHVwc2VydERpdG9HcmFwaEFuZEZldGNoKGRhdGEsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5faGFuZGxlRGl0b0dyYXBoKCd1cHNlcnRHcmFwaEFuZEZldGNoJyxcbiAgICAgIGRhdGEsIG9wdGlvbnMsIHVwc2VydERpdG9HcmFwaE9wdGlvbnMpXG4gIH1cblxuICBwYXRjaERpdG9HcmFwaChkYXRhLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuX2hhbmRsZURpdG9HcmFwaCgndXBzZXJ0R3JhcGgnLFxuICAgICAgZGF0YSwgb3B0aW9ucywgcGF0Y2hEaXRvR3JhcGhPcHRpb25zKVxuICB9XG5cbiAgcGF0Y2hEaXRvR3JhcGhBbmRGZXRjaChkYXRhLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuX2hhbmRsZURpdG9HcmFwaCgndXBzZXJ0R3JhcGhBbmRGZXRjaCcsXG4gICAgICBkYXRhLCBvcHRpb25zLCBwYXRjaERpdG9HcmFwaE9wdGlvbnMpXG4gIH1cblxuICB1cGRhdGVEaXRvR3JhcGgoZGF0YSwgb3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLl9oYW5kbGVEaXRvR3JhcGgoJ3Vwc2VydEdyYXBoJyxcbiAgICAgIGRhdGEsIG9wdGlvbnMsIHVwZGF0ZURpdG9HcmFwaE9wdGlvbnMpXG4gIH1cblxuICB1cGRhdGVEaXRvR3JhcGhBbmRGZXRjaChkYXRhLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuX2hhbmRsZURpdG9HcmFwaCgndXBzZXJ0R3JhcGhBbmRGZXRjaCcsXG4gICAgICBkYXRhLCBvcHRpb25zLCB1cGRhdGVEaXRvR3JhcGhPcHRpb25zKVxuICB9XG5cbiAgdXBzZXJ0RGl0b0dyYXBoQW5kRmV0Y2hCeUlkKGlkLCBkYXRhLCBvcHRpb25zKSB7XG4gICAgdGhpcy5jb250ZXh0KHsgYnlJZDogaWQgfSlcbiAgICByZXR1cm4gdGhpcy51cHNlcnREaXRvR3JhcGhBbmRGZXRjaCh7XG4gICAgICAuLi5kYXRhLFxuICAgICAgLi4udGhpcy5tb2RlbENsYXNzKCkuZ2V0UmVmZXJlbmNlKGlkKVxuICAgIH0sIG9wdGlvbnMpXG4gIH1cblxuICBwYXRjaERpdG9HcmFwaEFuZEZldGNoQnlJZChpZCwgZGF0YSwgb3B0aW9ucykge1xuICAgIHRoaXMuY29udGV4dCh7IGJ5SWQ6IGlkIH0pXG4gICAgcmV0dXJuIHRoaXMucGF0Y2hEaXRvR3JhcGhBbmRGZXRjaCh7XG4gICAgICAuLi5kYXRhLFxuICAgICAgLi4udGhpcy5tb2RlbENsYXNzKCkuZ2V0UmVmZXJlbmNlKGlkKVxuICAgIH0sIG9wdGlvbnMpXG4gIH1cblxuICB1cGRhdGVEaXRvR3JhcGhBbmRGZXRjaEJ5SWQoaWQsIGRhdGEsIG9wdGlvbnMpIHtcbiAgICB0aGlzLmNvbnRleHQoeyBieUlkOiBpZCB9KVxuICAgIHJldHVybiB0aGlzLnVwZGF0ZURpdG9HcmFwaEFuZEZldGNoKHtcbiAgICAgIC4uLmRhdGEsXG4gICAgICAuLi50aGlzLm1vZGVsQ2xhc3MoKS5nZXRSZWZlcmVuY2UoaWQpXG4gICAgfSwgb3B0aW9ucylcbiAgfVxuXG4gIF9oYW5kbGVEaXRvR3JhcGgobWV0aG9kLCBkYXRhLCBvcHRpb25zLCBkZWZhdWx0T3B0aW9ucykge1xuICAgIGNvbnN0IGhhbmRsZUdyYXBoID0gZGF0YSA9PiB7XG4gICAgICBjb25zdCBncmFwaFByb2Nlc3NvciA9IG5ldyBEaXRvR3JhcGhQcm9jZXNzb3IoXG4gICAgICAgIHRoaXMubW9kZWxDbGFzcygpLFxuICAgICAgICBkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgLi4uZGVmYXVsdE9wdGlvbnMsXG4gICAgICAgICAgLi4ub3B0aW9uc1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcHJvY2Vzc092ZXJyaWRlczogdHJ1ZSxcbiAgICAgICAgICBwcm9jZXNzUmVsYXRlczogdHJ1ZVxuICAgICAgICB9XG4gICAgICApXG4gICAgICB0aGlzW21ldGhvZF0oZ3JhcGhQcm9jZXNzb3IuZ2V0RGF0YSgpLCBncmFwaFByb2Nlc3Nvci5nZXRPcHRpb25zKCkpXG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnM/LmN5Y2xpYyAmJiBtZXRob2Quc3RhcnRzV2l0aCgndXBzZXJ0JykpIHtcbiAgICAgIC8vIGBfdXBzZXJ0Q3ljbGljRGl0b0dyYXBoQW5kRmV0Y2goKWAgbmVlZHMgdG8gcnVuIGFzeW5jaHJvbm91c2x5LFxuICAgICAgLy8gYnV0IHdlIGNhbid0IGRvIHNvIGhlcmUgYW5kIGBydW5CZWZvcmUoKWAgZXhlY3V0ZXMgdG9vIGxhdGUsXG4gICAgICAvLyBzbyB1c2UgYF9leGVjdXRlRmlyc3QoKWAgdG8gd29yayBhcm91bmQgaXQuXG4gICAgICB0aGlzLl9leGVjdXRlRmlyc3QgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRoaXMuX2V4ZWN1dGVGaXJzdCA9IG51bGxcbiAgICAgICAgaGFuZGxlR3JhcGgoXG4gICAgICAgICAgYXdhaXQgdGhpcy5jbG9uZSgpLl91cHNlcnRDeWNsaWNEaXRvR3JhcGhBbmRGZXRjaChkYXRhLCBvcHRpb25zKVxuICAgICAgICApXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGhhbmRsZUdyYXBoKGRhdGEpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIGFzeW5jIF91cHNlcnRDeWNsaWNEaXRvR3JhcGhBbmRGZXRjaChkYXRhLCBvcHRpb25zKSB7XG4gICAgLy8gVE9ETzogVGhpcyBpcyBwYXJ0IG9mIGEgd29ya2Fyb3VuZCBmb3IgdGhlIGZvbGxvd2luZyBPYmplY3Rpb24uanMgaXNzdWUuXG4gICAgLy8gUmVwbGFjZSB3aXRoIGEgbm9ybWFsIGB1cHNlcnRHcmFwaEFuZEZldGNoKClgIG9uY2UgaXQgaXMgZml4ZWQ6XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL1ZpbmNpdC9vYmplY3Rpb24uanMvaXNzdWVzLzE0ODJcblxuICAgIC8vIEZpcnN0LCBjb2xsZWN0IGFsbCAjaWQgaWRlbnRpZmllcnMgYW5kICNyZWYgcmVmZXJlbmNlcyBpbiB0aGUgZ3JhcGgsXG4gICAgLy8gYWxvbmcgd2l0aCB0aGVpciBkYXRhIHBhdGhzLlxuICAgIGNvbnN0IGlkZW50aWZpZXJzID0ge31cbiAgICBjb25zdCByZWZlcmVuY2VzID0ge31cblxuICAgIGNvbnN0IHsgdWlkUHJvcCwgdWlkUmVmUHJvcCB9ID0gdGhpcy5tb2RlbENsYXNzKClcblxuICAgIHdhbGtHcmFwaChkYXRhLCAodmFsdWUsIHBhdGgpID0+IHtcbiAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgY29uc3QgeyBbdWlkUHJvcF06IGlkLCBbdWlkUmVmUHJvcF06IHJlZiB9ID0gdmFsdWVcbiAgICAgICAgaWYgKGlkKSB7XG4gICAgICAgICAgLy8gVE9ETzogQWxzbyBzdG9yZSB0aGUgY29ycmVjdCBgaWRDb2x1bW5gIHByb3BlcnR5IGZvciB0aGUgZ2l2ZW4gcGF0aFxuICAgICAgICAgIGlkZW50aWZpZXJzW2lkXSA9IHBhdGguam9pbignLycpXG4gICAgICAgIH0gZWxzZSBpZiAocmVmKSB7XG4gICAgICAgICAgcmVmZXJlbmNlc1twYXRoLmpvaW4oJy8nKV0gPSByZWZcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG5cbiAgICAvLyBOb3cgY2xvbmUgdGhlIGRhdGEgYW5kIGRlbGV0ZSBhbGwgcmVmZXJlbmNlcyBmcm9tIGl0LCBmb3IgdGhlIGluaXRpYWxcbiAgICAvLyB1cHNlcnQuXG4gICAgY29uc3QgY2xvbmVkID0gY2xvbmUoZGF0YSlcbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgT2JqZWN0LmtleXMocmVmZXJlbmNlcykpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gcGFyc2VEYXRhUGF0aChwYXRoKVxuICAgICAgY29uc3Qga2V5ID0gcGFydHMucG9wKClcbiAgICAgIGNvbnN0IHBhcmVudCA9IGdldFZhbHVlQXREYXRhUGF0aChjbG9uZWQsIHBhcnRzKVxuICAgICAgZGVsZXRlIHBhcmVudFtrZXldXG4gICAgfVxuXG4gICAgLy8gVE9ETzogVGhlIG1vZGVsIGlzbid0IG5lY2Vzc2FyaWx5IGZldGNoZWQgd2l0aCBkYXRhIGluIHRoZSBzYW1lIG9yZGVyIGFzXG4gICAgLy8gYGNsb25lZGAgZGVmaW5lcywgZS5nLiBpZiB0aGVyZSBpcyBzb3J0aW5nIGluIHRoZSBkYXRhYmFzZS4gQSBzb2xpZFxuICAgIC8vIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgd291bGQgdGFrZSBjYXJlIG9mIHRoYXQgYW5kIG1hcCBlbnRyaWVzIGZyb21cbiAgICAvLyBgbW9kZWxgIGJhY2sgdG8gYGNsb25lZGAsIHNvIHRoYXQgdGhlIGBzZXREYXRhUGF0aGAgY2FsbHMgYmVsb3cgd291bGRcbiAgICAvLyBzdGlsbCB3b3JrIGluIHN1Y2ggY2FzZXMuXG4gICAgY29uc3QgeyBjeWNsaWMsIC4uLm9wdHMgfSA9IG9wdGlvbnNcbiAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMudXBzZXJ0RGl0b0dyYXBoQW5kRmV0Y2goY2xvbmVkLCBvcHRzKVxuXG4gICAgLy8gTm93IGZvciBlYWNoIGlkZW50aWZpZXIsIGNyZWF0ZSBhbiBvYmplY3QgY29udGFpbmluZyBvbmx5IHRoZSBmaW5hbCBpZCBpblxuICAgIC8vIHRoZSBmZXRjaGVkIG1vZGVsIGRhdGE6XG4gICAgY29uc3QgbGlua3MgPSB7fVxuICAgIGZvciAoY29uc3QgW2lkZW50aWZpZXIsIHBhdGhdIG9mIE9iamVjdC5lbnRyaWVzKGlkZW50aWZpZXJzKSkge1xuICAgICAgLy8gVE9ETzogVXNlIHRoZSBjb3JyZWN0IGBpZENvbHVtbmAgcHJvcGVydHkgZm9yIHRoZSBnaXZlbiBwYXRoXG4gICAgICBjb25zdCB7IGlkIH0gPSBnZXRWYWx1ZUF0RGF0YVBhdGgobW9kZWwsIHBhdGgpXG4gICAgICBsaW5rc1tpZGVudGlmaWVyXSA9IHsgaWQgfVxuICAgIH1cblxuICAgIC8vIEFuZCBmaW5hbGx5IHJlcGxhY2UgYWxsIHJlZmVyZW5jZXMgd2l0aCB0aGUgZmluYWwgaWRzLCBiZWZvcmUgdXBzZXJ0aW5nXG4gICAgLy8gb25jZSBhZ2FpbjpcbiAgICBmb3IgKGNvbnN0IFtwYXRoLCByZWZlcmVuY2VdIG9mIE9iamVjdC5lbnRyaWVzKHJlZmVyZW5jZXMpKSB7XG4gICAgICBjb25zdCBsaW5rID0gbGlua3NbcmVmZXJlbmNlXVxuICAgICAgaWYgKGxpbmspIHtcbiAgICAgICAgc2V0VmFsdWVBdERhdGFQYXRoKG1vZGVsLCBwYXRoLCBsaW5rKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtb2RlbFxuICB9XG5cbiAgc3RhdGljIG1peGluKHRhcmdldCkge1xuICAgIC8vIEV4cG9zZSBhIHNlbGVjdGlvbiBvZiBRdWVyeUJ1aWxkZXIgbWV0aG9kcyBkaXJlY3RseSBvbiB0aGUgdGFyZ2V0LFxuICAgIC8vIHJlZGlyZWN0aW5nIHRoZSBjYWxscyB0byBgdGhpcy5xdWVyeSgpW21ldGhvZF0oLi4uKWBcbiAgICBmb3IgKGNvbnN0IG1ldGhvZCBvZiBtaXhpbk1ldGhvZHMpIHtcbiAgICAgIGlmIChtZXRob2QgaW4gdGFyZ2V0KSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICBgVGhlcmUgaXMgYWxyZWFkeSBhIHByb3BlcnR5IG5hbWVkICcke21ldGhvZH0nIG9uICcke3RhcmdldH0nYClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIG1ldGhvZCwge1xuICAgICAgICAgIHZhbHVlKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnF1ZXJ5KClbbWV0aG9kXSguLi5hcmdzKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbktuZXhIZWxwZXIubWl4aW4oUXVlcnlCdWlsZGVyLnByb3RvdHlwZSlcblxuLy8gT3ZlcnJpZGUgYWxsIGRlcHJlY2F0ZWQgZWFnZXIgbWV0aG9kcyB0byByZXNwZWN0IHRoZSBgX2lnbm9yZUdyYXBoYCBmbGFnLFxuLy8gYW5kIGFsc28ga2VlcCB0cmFjayBvZiBgX2dyYXBoQWxnb3JpdGhtYCwgYXMgcmVxdWlyZWQgYnkgYHdpdGhHcmFwaCgpYFxuLy8gVE9ETzogUmVtb3ZlIG9uY2Ugd2UgbW92ZSB0byBPYmplY3Rpb24gMy4wXG5mb3IgKGNvbnN0IGtleSBvZiBbXG4gICdlYWdlcicsICdqb2luRWFnZXInLCAnbmFpdmVFYWdlcicsXG4gICdtZXJnZUVhZ2VyJywgJ21lcmdlSm9pbkVhZ2VyJywgJ21lcmdlTmFpdmVFYWdlcidcbl0pIHtcbiAgY29uc3QgbWV0aG9kID0gUXVlcnlCdWlsZGVyLnByb3RvdHlwZVtrZXldXG4gIFF1ZXJ5QnVpbGRlci5wcm90b3R5cGVba2V5XSA9IGZ1bmN0aW9uKC4uLmFyZ3MpIHtcbiAgICBpZiAoIXRoaXMuX2lnbm9yZUdyYXBoKSB7XG4gICAgICB0aGlzLl9ncmFwaEFsZ29yaXRobSA9IC9qb2luL2kudGVzdChrZXkpID8gJ2pvaW4nIDogJ2ZldGNoJ1xuICAgICAgbWV0aG9kLmNhbGwodGhpcywgLi4uYXJncylcbiAgICB9XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxufVxuXG4vLyBBZGQgY29udmVyc2lvbiBvZiBpZGVudGlmaWVycyB0byBhbGwgYHdoZXJlYCBzdGF0ZW1lbnRzLCBhcyB3ZWxsIGFzIHRvXG4vLyBgc2VsZWN0YCBhbmQgYG9yZGVyQnlgLCBieSBkZXRlY3RpbmcgdXNlIG9mIG1vZGVsIHByb3BlcnRpZXMgYW5kIGV4cGFuZGluZ1xuLy8gdGhlbSB0byBgJHt0YWJsZVJlZkZvcihtb2RlbENsYXNzfS4ke3Byb3BlcnR5TmFtZX1gLCBmb3IgdW5hbWJpZ3VvdXNcbi8vIGlkZW50aWZpY2F0aW9uIG9mIHVzZWQgcHJvcGVydGllcyBpbiBjb21wbGV4IHN0YXRlbWVudHMuXG5mb3IgKGNvbnN0IGtleSBvZiBbXG4gICd3aGVyZScsICdhbmRXaGVyZScsICdvcldoZXJlJyxcbiAgJ3doZXJlTm90JywgJ29yV2hlcmVOb3QnLFxuICAnd2hlcmVJbicsICdvcldoZXJlSW4nLFxuICAnd2hlcmVOb3RJbicsICdvcldoZXJlTm90SW4nLFxuICAnd2hlcmVOdWxsJywgJ29yV2hlcmVOdWxsJyxcbiAgJ3doZXJlTm90TnVsbCcsICdvcldoZXJlTm90TnVsbCcsXG4gICd3aGVyZUJldHdlZW4nLCAnYW5kV2hlcmVCZXR3ZWVuJywgJ29yV2hlcmVCZXR3ZWVuJyxcbiAgJ3doZXJlTm90QmV0d2VlbicsICdhbmRXaGVyZU5vdEJldHdlZW4nLCAnb3JXaGVyZU5vdEJldHdlZW4nLFxuICAnd2hlcmVDb2x1bW4nLCAnYW5kV2hlcmVDb2x1bW4nLCAnb3JXaGVyZUNvbHVtbicsXG4gICd3aGVyZU5vdENvbHVtbicsICdhbmRXaGVyZU5vdENvbHVtbicsICdvcldoZXJlTm90Q29sdW1uJyxcbiAgJ3doZXJlQ29tcG9zaXRlJywgJ2FuZFdoZXJlQ29tcG9zaXRlJywgJ29yV2hlcmVDb21wb3NpdGUnLFxuICAnd2hlcmVJbkNvbXBvc2l0ZScsXG4gICd3aGVyZU5vdEluQ29tcG9zaXRlJyxcblxuICAnaGF2aW5nJywgJ29ySGF2aW5nJyxcbiAgJ2hhdmluZ0luJywgJ29ySGF2aW5nSW4nLFxuICAnaGF2aW5nTm90SW4nLCAnb3JIYXZpbmdOb3RJbicsXG4gICdoYXZpbmdOdWxsJywgJ29ySGF2aW5nTnVsbCcsXG4gICdoYXZpbmdOb3ROdWxsJywgJ29ySGF2aW5nTm90TnVsbCcsXG4gICdoYXZpbmdCZXR3ZWVuJywgJ29ySGF2aW5nQmV0d2VlbicsXG4gICdoYXZpbmdOb3RCZXR3ZWVuJywgJ29ySGF2aW5nTm90QmV0d2VlbicsXG5cbiAgJ3NlbGVjdCcsICdjb2x1bW4nLCAnY29sdW1ucycsICdmaXJzdCcsXG5cbiAgJ2dyb3VwQnknLCAnb3JkZXJCeSdcbl0pIHtcbiAgY29uc3QgbWV0aG9kID0gUXVlcnlCdWlsZGVyLnByb3RvdHlwZVtrZXldXG4gIFF1ZXJ5QnVpbGRlci5wcm90b3R5cGVba2V5XSA9IGZ1bmN0aW9uKC4uLmFyZ3MpIHtcbiAgICBjb25zdCBtb2RlbENsYXNzID0gdGhpcy5tb2RlbENsYXNzKClcbiAgICBjb25zdCB7IHByb3BlcnRpZXMgfSA9IG1vZGVsQ2xhc3MuZGVmaW5pdGlvblxuXG4gICAgLy8gRXhwYW5kcyBhbGwgaWRlbnRpZmllcnMga25vd24gdG8gdGhlIG1vZGVsIHRvIHRoZWlyIGV4dGVuZGVkIHZlcnNpb25zLlxuICAgIGNvbnN0IGV4cGFuZElkZW50aWZpZXIgPSBpZGVudGlmaWVyID0+IHtcbiAgICAgIC8vIFN1cHBvcnQgZXhwYW5zaW9uIG9mIGlkZW50aWZpZXJzIHdpdGggYWxpYXNlcywgZS5nLiBgbmFtZSBBUyBuZXdOYW1lYFxuICAgICAgY29uc3QgYWxpYXMgPVxuICAgICAgICBpc1N0cmluZyhpZGVudGlmaWVyKSAmJlxuICAgICAgICBpZGVudGlmaWVyLm1hdGNoKC9eXFxzKihbYS16XVtcXHdfXSspKFxccytBU1xccysuKikkL2kpXG4gICAgICByZXR1cm4gYWxpYXNcbiAgICAgICAgPyBgJHtleHBhbmRJZGVudGlmaWVyKGFsaWFzWzFdKX0ke2FsaWFzWzJdfWBcbiAgICAgICAgOiBpZGVudGlmaWVyID09PSAnKicgfHwgaWRlbnRpZmllciBpbiBwcm9wZXJ0aWVzXG4gICAgICAgICAgPyBgJHt0aGlzLnRhYmxlUmVmRm9yKG1vZGVsQ2xhc3MpfS4ke2lkZW50aWZpZXJ9YFxuICAgICAgICAgIDogaWRlbnRpZmllclxuICAgIH1cblxuICAgIGNvbnN0IGNvbnZlcnRBcmd1bWVudCA9IGFyZyA9PiB7XG4gICAgICBpZiAoaXNTdHJpbmcoYXJnKSkge1xuICAgICAgICBhcmcgPSBleHBhbmRJZGVudGlmaWVyKGFyZylcbiAgICAgIH0gZWxzZSBpZiAoaXNBcnJheShhcmcpKSB7XG4gICAgICAgIGFyZyA9IGFyZy5tYXAoZXhwYW5kSWRlbnRpZmllcilcbiAgICAgIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdChhcmcpKSB7XG4gICAgICAgIGFyZyA9IG1hcEtleXMoYXJnLCBleHBhbmRJZGVudGlmaWVyKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGFyZ1xuICAgIH1cblxuICAgIGNvbnN0IGxlbmd0aCA9IFsnc2VsZWN0JywgJ2NvbHVtbicsICdjb2x1bW5zJywgJ2ZpcnN0J10uaW5jbHVkZXMoa2V5KVxuICAgICAgPyBhcmdzLmxlbmd0aFxuICAgICAgOiAxXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgYXJnc1tpXSA9IGNvbnZlcnRBcmd1bWVudChhcmdzW2ldKVxuICAgIH1cbiAgICByZXR1cm4gbWV0aG9kLmNhbGwodGhpcywgLi4uYXJncylcbiAgfVxufVxuXG4vLyBUaGUgZGVmYXVsdCBvcHRpb25zIGZvciBpbnNlcnREaXRvR3JhcGgoKSwgdXBzZXJ0RGl0b0dyYXBoKCksXG4vLyB1cGRhdGVEaXRvR3JhcGgoKSBhbmQgcGF0Y2hEaXRvR3JhcGgoKVxuY29uc3QgaW5zZXJ0RGl0b0dyYXBoT3B0aW9ucyA9IHtcbiAgLy8gV2hlbiB3b3JraW5nIHdpdGggbGFyZ2UgZ3JhcGhzLCB1c2luZyB0aGUgJ09ubHlOZWVkZWQnIGZldGNoLXN0cmF0ZWd5XG4gIC8vIHdpbGwgcmVkdWNlIHRoZSBudW1iZXIgb2YgdXBkYXRlIHF1ZXJpZXMgZnJvbSBhIGxvdCB0byBvbmx5IHRob3NlXG4gIC8vIHJvd3MgdGhhdCBoYXZlIGNoYW5nZXMuXG4gIGZldGNoU3RyYXRlZ3k6ICdPbmx5TmVlZGVkJyxcbiAgcmVsYXRlOiB0cnVlLFxuICBhbGxvd1JlZnM6IHRydWVcbn1cblxuY29uc3QgdXBzZXJ0RGl0b0dyYXBoT3B0aW9ucyA9IHtcbiAgLi4uaW5zZXJ0RGl0b0dyYXBoT3B0aW9ucyxcbiAgaW5zZXJ0TWlzc2luZzogdHJ1ZSxcbiAgdW5yZWxhdGU6IHRydWVcbn1cblxuY29uc3QgcGF0Y2hEaXRvR3JhcGhPcHRpb25zID0ge1xuICAuLi51cHNlcnREaXRvR3JhcGhPcHRpb25zLFxuICBpbnNlcnRNaXNzaW5nOiBmYWxzZVxufVxuXG5jb25zdCB1cGRhdGVEaXRvR3JhcGhPcHRpb25zID0ge1xuICAuLi5wYXRjaERpdG9HcmFwaE9wdGlvbnMsXG4gIGluc2VydE1pc3Npbmc6IGZhbHNlLFxuICB1cGRhdGU6IHRydWVcbn1cblxuZnVuY3Rpb24gYWRkR3JhcGhTY29wZShtb2RlbENsYXNzLCBleHByLCBzY29wZXMsIG1vZGlmaWVycywgaXNSb290ID0gZmFsc2UpIHtcbiAgaWYgKGlzUm9vdCkge1xuICAgIGV4cHIgPSBjbG9uZShleHByKVxuICB9IGVsc2Uge1xuICAgIC8vIE9ubHkgYWRkIHRoZSBzY29wZSBpZiBpdCdzIG5vdCBhbHJlYWR5IGRlZmluZWQgYnkgdGhlIGdyYXBoIGV4cHJlc3Npb25cbiAgICAvLyBhbmQgaWYgaXQncyBhY3R1YWxseSBhdmFpbGFibGUgaW4gdGhlIG1vZGVsJ3MgbGlzdCBvZiBtb2RpZmllcnMuXG4gICAgZm9yIChjb25zdCBzY29wZSBvZiBzY29wZXMpIHtcbiAgICAgIGlmIChcbiAgICAgICAgIWV4cHIuJG1vZGlmeT8uaW5jbHVkZXMoc2NvcGUpICYmIChcbiAgICAgICAgICBtb2RlbENsYXNzLmhhc1Njb3BlKHNjb3BlKSB8fFxuICAgICAgICAgIG1vZGlmaWVyc1tzY29wZV1cbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIGV4cHIuJG1vZGlmeS5wdXNoKHNjb3BlKVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCByZWxhdGlvbnMgPSBtb2RlbENsYXNzLmdldFJlbGF0aW9ucygpXG4gIGZvciAoY29uc3Qga2V5IGluIGV4cHIpIHtcbiAgICAvLyBBbGwgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIHRoYXQgZG9uJ3Qgc3RhcnQgd2l0aCAnJCcgYXJlIGNoaWxkIG5vZGVzLlxuICAgIGlmIChrZXlbMF0gIT09ICckJykge1xuICAgICAgY29uc3QgY2hpbGRFeHByID0gZXhwcltrZXldXG4gICAgICBjb25zdCByZWxhdGlvbiA9IHJlbGF0aW9uc1tjaGlsZEV4cHIuJHJlbGF0aW9uIHx8IGtleV1cbiAgICAgIGlmICghcmVsYXRpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IFJlbGF0aW9uRXJyb3IoYEludmFsaWQgY2hpbGQgZXhwcmVzc2lvbjogJyR7a2V5fSdgKVxuICAgICAgfVxuICAgICAgYWRkR3JhcGhTY29wZShyZWxhdGlvbi5yZWxhdGVkTW9kZWxDbGFzcywgY2hpbGRFeHByLCBzY29wZXMsIG1vZGlmaWVycylcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGV4cHJcbn1cblxuLy8gTGlzdCBvZiBhbGwgYFF1ZXJ5QnVpbGRlcmAgbWV0aG9kcyB0byBiZSBtaXhlZCBpbnRvIGBNb2RlbGAgYXMgYSBzaG9ydC1jdXRcbi8vIGZvciBgbW9kZWwucXVlcnkoKS5NRVRIT0QoKWBcbi8vXG4vLyBVc2UgdGhpcyBjb2RlIHRvIGZpbmQgYWxsIGBRdWVyeUJ1aWxkZXJgIG1ldGhvZHM6XG4vL1xuLy8gZnVuY3Rpb24gZ2V0QWxsUHJvcGVydHlOYW1lcyhvYmopIHtcbi8vICAgY29uc3QgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKVxuLy8gICBjb25zdCBpbmhlcml0ZWQgPSBwcm90byA/IGdldEFsbFByb3BlcnR5TmFtZXMocHJvdG8pIDogW11cbi8vICAgcmV0dXJuIFsuLi5uZXcgU2V0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iaikuY29uY2F0KGluaGVyaXRlZCkpXVxuLy8gfVxuLy9cbi8vIGNvbnNvbGUuZGlyKGdldEFsbFByb3BlcnR5TmFtZXMoUXVlcnlCdWlsZGVyLnByb3RvdHlwZSkuc29ydCgpLCB7XG4vLyAgIGNvbG9yczogdHJ1ZSxcbi8vICAgZGVwdGg6IG51bGwsXG4vLyAgIG1heEFycmF5TGVuZ3RoOiBudWxsXG4vLyB9KVxuXG5jb25zdCBtaXhpbk1ldGhvZHMgPSBbXG4gICdmaXJzdCcsXG4gICdmaW5kJyxcbiAgJ2ZpbmRPbmUnLFxuICAnZmluZEJ5SWQnLFxuXG4gICd3aXRoR3JhcGgnLFxuICAnd2l0aEdyYXBoRmV0Y2hlZCcsXG4gICd3aXRoR3JhcGhKb2luZWQnLFxuICAnY2xlYXJXaXRoR3JhcGgnLFxuXG4gICd3aXRoU2NvcGUnLFxuICAnYXBwbHlTY29wZScsXG4gICdjbGVhcldpdGhTY29wZScsXG5cbiAgJ2NsZWFyJyxcbiAgJ3BpY2snLFxuICAnb21pdCcsXG4gICdzZWxlY3QnLFxuXG4gICdpbnNlcnQnLFxuICAndXBzZXJ0JyxcblxuICAndXBkYXRlJyxcbiAgJ3BhdGNoJyxcbiAgJ2RlbGV0ZScsXG5cbiAgJ3VwZGF0ZUJ5SWQnLFxuICAncGF0Y2hCeUlkJyxcbiAgJ2RlbGV0ZUJ5SWQnLFxuXG4gICd0cnVuY2F0ZScsXG5cbiAgJ2luc2VydEFuZEZldGNoJyxcbiAgJ3Vwc2VydEFuZEZldGNoJyxcbiAgJ3VwZGF0ZUFuZEZldGNoJyxcbiAgJ3BhdGNoQW5kRmV0Y2gnLFxuXG4gICd1cGRhdGVBbmRGZXRjaEJ5SWQnLFxuICAncGF0Y2hBbmRGZXRjaEJ5SWQnLFxuXG4gICdpbnNlcnRHcmFwaCcsXG4gICd1cHNlcnRHcmFwaCcsXG4gICdpbnNlcnRHcmFwaEFuZEZldGNoJyxcbiAgJ3Vwc2VydEdyYXBoQW5kRmV0Y2gnLFxuXG4gICdpbnNlcnREaXRvR3JhcGgnLFxuICAndXBzZXJ0RGl0b0dyYXBoJyxcbiAgJ3VwZGF0ZURpdG9HcmFwaCcsXG4gICdwYXRjaERpdG9HcmFwaCcsXG4gICdpbnNlcnREaXRvR3JhcGhBbmRGZXRjaCcsXG4gICd1cHNlcnREaXRvR3JhcGhBbmRGZXRjaCcsXG4gICd1cGRhdGVEaXRvR3JhcGhBbmRGZXRjaCcsXG4gICdwYXRjaERpdG9HcmFwaEFuZEZldGNoJyxcblxuICAndXBzZXJ0RGl0b0dyYXBoQW5kRmV0Y2hCeUlkJyxcbiAgJ3VwZGF0ZURpdG9HcmFwaEFuZEZldGNoQnlJZCcsXG4gICdwYXRjaERpdG9HcmFwaEFuZEZldGNoQnlJZCcsXG5cbiAgJ3doZXJlJyxcbiAgJ3doZXJlTm90JyxcbiAgJ3doZXJlUmF3JyxcbiAgJ3doZXJlV3JhcHBlZCcsXG4gICd3aGVyZUV4aXN0cycsXG4gICd3aGVyZU5vdEV4aXN0cycsXG4gICd3aGVyZUluJyxcbiAgJ3doZXJlTm90SW4nLFxuICAnd2hlcmVOdWxsJyxcbiAgJ3doZXJlTm90TnVsbCcsXG4gICd3aGVyZUJldHdlZW4nLFxuICAnd2hlcmVOb3RCZXR3ZWVuJyxcbiAgJ3doZXJlQ29sdW1uJyxcbiAgJ3doZXJlTm90Q29sdW1uJyxcbiAgJ3doZXJlQ29tcG9zaXRlJyxcbiAgJ3doZXJlSW5Db21wb3NpdGUnLFxuICAnd2hlcmVOb3RJbkNvbXBvc2l0ZScsXG4gICd3aGVyZUpzb25IYXNBbnknLFxuICAnd2hlcmVKc29uSGFzQWxsJyxcbiAgJ3doZXJlSnNvbklzQXJyYXknLFxuICAnd2hlcmVKc29uTm90QXJyYXknLFxuICAnd2hlcmVKc29uSXNPYmplY3QnLFxuICAnd2hlcmVKc29uTm90T2JqZWN0JyxcbiAgJ3doZXJlSnNvblN1YnNldE9mJyxcbiAgJ3doZXJlSnNvbk5vdFN1YnNldE9mJyxcbiAgJ3doZXJlSnNvblN1cGVyc2V0T2YnLFxuICAnd2hlcmVKc29uTm90U3VwZXJzZXRPZicsXG5cbiAgJ2hhdmluZycsXG4gICdoYXZpbmdJbicsXG4gICdoYXZpbmdOb3RJbicsXG4gICdoYXZpbmdOdWxsJyxcbiAgJ2hhdmluZ05vdE51bGwnLFxuICAnaGF2aW5nRXhpc3RzJyxcbiAgJ2hhdmluZ05vdEV4aXN0cycsXG4gICdoYXZpbmdCZXR3ZWVuJyxcbiAgJ2hhdmluZ05vdEJldHdlZW4nLFxuICAnaGF2aW5nUmF3JyxcbiAgJ2hhdmluZ1dyYXBwZWQnLFxuXG4gIC8vIGRlcHJlY2F0ZWQgbWV0aG9kcyB0aGF0IGFyZSBzdGlsbCBzdXBwb3J0ZWQgYXQgdGhlIG1vbWVudC5cbiAgLy8gVE9ETzogUmVtb3ZlIG9uY2Ugd2UgbW92ZSB0byBPYmplY3Rpb24gMy4wXG4gICdlYWdlcicsXG4gICdqb2luRWFnZXInLFxuICAnbmFpdmVFYWdlcicsXG4gICdtZXJnZUVhZ2VyJyxcbiAgJ21lcmdlSm9pbkVhZ2VyJyxcbiAgJ21lcmdlTmFpdmVFYWdlcicsXG4gICdjbGVhckVhZ2VyJyxcblxuICAnc2NvcGUnLFxuICAnbWVyZ2VTY29wZScsXG4gICdjbGVhclNjb3BlJ1xuXVxuIl19