@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,263 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.CollectionController = void 0;
5
-
6
- require("core-js/modules/esnext.async-iterator.find.js");
7
-
8
- require("core-js/modules/esnext.iterator.constructor.js");
9
-
10
- require("core-js/modules/esnext.iterator.find.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.map.js");
17
-
18
- require("core-js/modules/esnext.iterator.map.js");
19
-
20
- var _Controller = require("./Controller");
21
-
22
- var _errors = require("../errors");
23
-
24
- var _utils = require("@ditojs/utils");
25
-
26
- class CollectionController extends _Controller.Controller {
27
- constructor(app, namespace) {
28
- super(app, namespace);
29
- this.collection = this.toCoreActions({
30
- async find(ctx, modify) {
31
- const result = await this.execute(ctx, (query, trx) => {
32
- query.find(ctx.query, this.allowParam).modify(getModify(modify, trx));
33
- return this.isOneToOne ? query.first() : query;
34
- });
35
- return result || null;
36
- },
37
-
38
- async delete(ctx, modify) {
39
- const count = await this.execute(ctx, (query, trx) => query.ignoreScope().find(ctx.query, this.allowParam).modify(query => this.isOneToOne && query.throwIfNotFound()).modify(getModify(modify, trx)).modify(query => this.unrelate ? query.unrelate() : query.delete()));
40
- return {
41
- count
42
- };
43
- },
44
-
45
- async insert(ctx, modify) {
46
- const result = this.relate ? await this.execute(ctx, (query, trx) => query.patchDitoGraphAndFetch(ctx.request.body, {
47
- relate: true
48
- }).modify(getModify(modify, trx))) : await this.executeAndFetch('insert', ctx, modify);
49
- ctx.status = 201;
50
-
51
- if ((0, _utils.isObject)(result)) {
52
- ctx.set('Location', this.getUrl('collection', result.id));
53
- }
54
-
55
- return result;
56
- },
57
-
58
- async update(ctx, modify) {
59
- return this.executeAndFetch('update', ctx, modify);
60
- },
61
-
62
- async patch(ctx, modify) {
63
- return this.executeAndFetch('patch', ctx, modify);
64
- }
65
-
66
- });
67
- this.member = this.toCoreActions({
68
- async find(ctx, modify) {
69
- return this.execute(ctx, (query, trx) => query.findById(ctx.memberId).find(ctx.query, this.allowParam).throwIfNotFound().modify(getModify(modify, trx)));
70
- },
71
-
72
- async delete(ctx, modify) {
73
- const count = await this.execute(ctx, (query, trx) => query.ignoreScope().findById(ctx.memberId).find(ctx.query, this.allowParam).throwIfNotFound().modify(getModify(modify, trx)).modify(query => this.unrelate ? query.unrelate() : query.delete()));
74
- return {
75
- count
76
- };
77
- },
78
-
79
- async update(ctx, modify) {
80
- return this.executeAndFetchById('update', ctx, modify);
81
- },
82
-
83
- async patch(ctx, modify) {
84
- return this.executeAndFetchById('patch', ctx, modify);
85
- }
86
-
87
- });
88
- this.modelClass = null;
89
- this.isOneToOne = false;
90
- this.relate = false;
91
- this.unrelate = false;
92
- }
93
-
94
- setup(isRoot) {
95
- super.setup(isRoot, false);
96
- this.idParam = this.level ? `id${this.level}` : 'id';
97
- this.graph = !!this.graph;
98
- this.transacted = !!this.transacted;
99
- this.scope = this.scope || null;
100
- this.collection = this.setupActions('collection');
101
- this.member = this.isOneToOne ? {} : this.setupActions('member');
102
- this.idValidator = new this.modelClass();
103
- }
104
-
105
- setupAction(type, actions, name, handler, authorize, verb, path) {
106
- if (name in actionToVerb) {
107
- verb = actionToVerb[name];
108
- path = '';
109
- }
110
-
111
- return super.setupAction(type, actions, name, handler, authorize, verb, path);
112
- }
113
-
114
- setupAssets() {
115
- const {
116
- modelClass
117
- } = this;
118
-
119
- if (this.assets === true) {
120
- this.assets = modelClass.definition.assets || null;
121
- } else if ((0, _utils.isObject)(this.assets)) {
122
- this.assets = { ...modelClass.definition.assets,
123
- ...this.assets
124
- };
125
- } else {
126
- this.assets = null;
127
- }
128
-
129
- return super.setupAssets();
130
- }
131
-
132
- getPath(type, path) {
133
- return type === 'member' ? path ? `:${this.idParam}/${path}` : `:${this.idParam}` : path;
134
- }
135
-
136
- extendContext(ctx, object) {
137
- return Object.setPrototypeOf(object, ctx);
138
- }
139
-
140
- getMemberId(ctx) {
141
- return this.validateId(ctx.params[this.idParam]);
142
- }
143
-
144
- getContextWithMemberId(ctx, memberId = this.getMemberId(ctx)) {
145
- return this.extendContext(ctx, {
146
- memberId
147
- });
148
- }
149
-
150
- getCollectionIds(ctx) {
151
- const idProperty = this.modelClass.getIdProperty();
152
- const getId = (0, _utils.isArray)(idProperty) ? model => idProperty.reduce((id, key) => {
153
- id.push(model[key]);
154
- return id;
155
- }, []) : model => model[idProperty];
156
- return (0, _utils.asArray)(ctx.request.body).map(model => this.validateId(getId(model)));
157
- }
158
-
159
- getIds(ctx) {
160
- const {
161
- type
162
- } = ctx.action;
163
- return type === 'member' ? [this.getMemberId(ctx)] : type === 'collection' ? this.getCollectionIds(ctx) : [];
164
- }
165
-
166
- validateId(id) {
167
- const reference = this.modelClass.getReference(id);
168
- this.idValidator.$validate(reference, {
169
- coerceTypes: true,
170
- patch: true
171
- });
172
- const values = Object.values(reference);
173
- return values.length > 1 ? values : values[0];
174
- }
175
-
176
- async getMember(ctx, base = this, {
177
- query = {},
178
- modify = null,
179
- forUpdate = false
180
- } = {}) {
181
- return this.member.find.call(this, this.extendContext(ctx, {
182
- query
183
- }), (query, trx) => {
184
- this.setupQuery(query, base);
185
- query.modify(modify);
186
-
187
- if (forUpdate) {
188
- if (!trx) {
189
- throw new _errors.ControllerError(this, 'Using `forUpdate()` without a transaction is invalid');
190
- }
191
-
192
- query.forUpdate();
193
- }
194
- });
195
- }
196
-
197
- query(trx) {
198
- return this.setupQuery(this.modelClass.query(trx));
199
- }
200
-
201
- setupQuery(query, base = this) {
202
- const {
203
- scope
204
- } = base;
205
- const {
206
- allowScope,
207
- allowFilter
208
- } = this;
209
-
210
- const asAllowArray = value => value === false ? [] : (0, _utils.asArray)(value);
211
-
212
- if (allowScope !== undefined && allowScope !== true) {
213
- query.allowScope(...asAllowArray(allowScope), ...(0, _utils.asArray)(scope));
214
- }
215
-
216
- if (allowFilter !== undefined && allowFilter !== true) {
217
- query.allowFilter(...asAllowArray(allowFilter));
218
- }
219
-
220
- if (scope) {
221
- query.withScope(...(0, _utils.asArray)(scope));
222
- }
223
-
224
- return query;
225
- }
226
-
227
- async execute() {}
228
-
229
- async executeAndFetch(action, ctx, modify, body = ctx.request.body) {
230
- const name = `${action}${this.graph ? 'DitoGraph' : ''}AndFetch`;
231
- return this.execute(ctx, (query, trx) => query[name](body).modify(getModify(modify, trx)));
232
- }
233
-
234
- async executeAndFetchById(action, ctx, modify, body = ctx.request.body) {
235
- const name = `${action}${this.graph ? 'DitoGraph' : ''}AndFetchById`;
236
- return this.execute(ctx, (query, trx) => query[name](ctx.memberId, body).throwIfNotFound().modify(getModify(modify, trx)));
237
- }
238
-
239
- toCoreActions(actions) {
240
- for (const action of Object.values(actions)) {
241
- action.core = true;
242
- }
243
-
244
- actions.$core = true;
245
- return actions;
246
- }
247
-
248
- }
249
-
250
- exports.CollectionController = CollectionController;
251
-
252
- function getModify(modify, trx) {
253
- return modify ? query => modify(query, trx) : null;
254
- }
255
-
256
- const actionToVerb = {
257
- find: 'get',
258
- delete: 'delete',
259
- insert: 'post',
260
- update: 'put',
261
- patch: 'patch'
262
- };
263
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb250cm9sbGVycy9Db2xsZWN0aW9uQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJDb2xsZWN0aW9uQ29udHJvbGxlciIsIkNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFwcCIsIm5hbWVzcGFjZSIsImNvbGxlY3Rpb24iLCJ0b0NvcmVBY3Rpb25zIiwiZmluZCIsImN0eCIsIm1vZGlmeSIsInJlc3VsdCIsImV4ZWN1dGUiLCJxdWVyeSIsInRyeCIsImFsbG93UGFyYW0iLCJnZXRNb2RpZnkiLCJpc09uZVRvT25lIiwiZmlyc3QiLCJkZWxldGUiLCJjb3VudCIsImlnbm9yZVNjb3BlIiwidGhyb3dJZk5vdEZvdW5kIiwidW5yZWxhdGUiLCJpbnNlcnQiLCJyZWxhdGUiLCJwYXRjaERpdG9HcmFwaEFuZEZldGNoIiwicmVxdWVzdCIsImJvZHkiLCJleGVjdXRlQW5kRmV0Y2giLCJzdGF0dXMiLCJzZXQiLCJnZXRVcmwiLCJpZCIsInVwZGF0ZSIsInBhdGNoIiwibWVtYmVyIiwiZmluZEJ5SWQiLCJtZW1iZXJJZCIsImV4ZWN1dGVBbmRGZXRjaEJ5SWQiLCJtb2RlbENsYXNzIiwic2V0dXAiLCJpc1Jvb3QiLCJpZFBhcmFtIiwibGV2ZWwiLCJncmFwaCIsInRyYW5zYWN0ZWQiLCJzY29wZSIsInNldHVwQWN0aW9ucyIsImlkVmFsaWRhdG9yIiwic2V0dXBBY3Rpb24iLCJ0eXBlIiwiYWN0aW9ucyIsIm5hbWUiLCJoYW5kbGVyIiwiYXV0aG9yaXplIiwidmVyYiIsInBhdGgiLCJhY3Rpb25Ub1ZlcmIiLCJzZXR1cEFzc2V0cyIsImFzc2V0cyIsImRlZmluaXRpb24iLCJnZXRQYXRoIiwiZXh0ZW5kQ29udGV4dCIsIm9iamVjdCIsIk9iamVjdCIsInNldFByb3RvdHlwZU9mIiwiZ2V0TWVtYmVySWQiLCJ2YWxpZGF0ZUlkIiwicGFyYW1zIiwiZ2V0Q29udGV4dFdpdGhNZW1iZXJJZCIsImdldENvbGxlY3Rpb25JZHMiLCJpZFByb3BlcnR5IiwiZ2V0SWRQcm9wZXJ0eSIsImdldElkIiwibW9kZWwiLCJyZWR1Y2UiLCJrZXkiLCJwdXNoIiwibWFwIiwiZ2V0SWRzIiwiYWN0aW9uIiwicmVmZXJlbmNlIiwiZ2V0UmVmZXJlbmNlIiwiJHZhbGlkYXRlIiwiY29lcmNlVHlwZXMiLCJ2YWx1ZXMiLCJsZW5ndGgiLCJnZXRNZW1iZXIiLCJiYXNlIiwiZm9yVXBkYXRlIiwiY2FsbCIsInNldHVwUXVlcnkiLCJDb250cm9sbGVyRXJyb3IiLCJhbGxvd1Njb3BlIiwiYWxsb3dGaWx0ZXIiLCJhc0FsbG93QXJyYXkiLCJ2YWx1ZSIsInVuZGVmaW5lZCIsIndpdGhTY29wZSIsImNvcmUiLCIkY29yZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUdPLE1BQU1BLG9CQUFOLFNBQW1DQyxzQkFBbkMsQ0FBOEM7QUFDbkRDLEVBQUFBLFdBQVcsQ0FBQ0MsR0FBRCxFQUFNQyxTQUFOLEVBQWlCO0FBQzFCLFVBQU1ELEdBQU4sRUFBV0MsU0FBWDtBQUQwQixTQXFNNUJDLFVBck00QixHQXFNZixLQUFLQyxhQUFMLENBQW1CO0FBQzlCLFlBQU1DLElBQU4sQ0FBV0MsR0FBWCxFQUFnQkMsTUFBaEIsRUFBd0I7QUFDdEIsY0FBTUMsTUFBTSxHQUFHLE1BQU0sS0FBS0MsT0FBTCxDQUFhSCxHQUFiLEVBQWtCLENBQUNJLEtBQUQsRUFBUUMsR0FBUixLQUFnQjtBQUNyREQsVUFBQUEsS0FBSyxDQUFDTCxJQUFOLENBQVdDLEdBQUcsQ0FBQ0ksS0FBZixFQUFzQixLQUFLRSxVQUEzQixFQUF1Q0wsTUFBdkMsQ0FBOENNLFNBQVMsQ0FBQ04sTUFBRCxFQUFTSSxHQUFULENBQXZEO0FBQ0EsaUJBQU8sS0FBS0csVUFBTCxHQUFrQkosS0FBSyxDQUFDSyxLQUFOLEVBQWxCLEdBQWtDTCxLQUF6QztBQUNELFNBSG9CLENBQXJCO0FBT0EsZUFBT0YsTUFBTSxJQUFJLElBQWpCO0FBQ0QsT0FWNkI7O0FBWTlCLFlBQU1RLE1B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LEdBQWEsV0FBYixHQUEyQixFQUFHLGNBQXZEO0FBQ0EsV0FBTyxLQUFLakMsT0FBTCxDQUFhSCxHQUFiLEVBQWtCLENBQUNJLEtBQUQsRUFBUUMsR0FBUixLQUN2QkQsS0FBSyxDQUFDd0MsSUFBRCxDQUFMLENBQVk1QyxHQUFHLENBQUM2QixRQUFoQixFQUEwQlYsSUFBMUIsRUFDR04sZUFESCxHQUVHWixNQUZILENBRVVNLFNBQVMsQ0FBQ04sTUFBRCxFQUFTSSxHQUFULENBRm5CLENBREssQ0FBUDtBQUtEOztBQUVEUCxFQUFBQSxhQUFhLENBQUM2QyxPQUFELEVBQVU7QUFHckIsU0FBSyxNQUFNNkIsTUFBWCxJQUFxQmhCLE1BQU0sQ0FBQ3FCLE1BQVAsQ0FBY2xDLE9BQWQsQ0FBckIsRUFBNkM7QUFHM0M2QixNQUFBQSxNQUFNLENBQUNtQixJQUFQLEdBQWMsSUFBZDtBQUNEOztBQUNEaEQsSUFBQUEsT0FBTyxDQUFDaUQsS0FBUixHQUFnQixJQUFoQjtBQUNBLFdBQU9qRCxPQUFQO0FBQ0Q7O0FBcE1rRDs7OztBQXFSckQsU0FBU3BDLFNBQVQsQ0FBbUJOLE1BQW5CLEVBQTJCSSxHQUEzQixFQUFnQztBQUM5QixTQUFPSixNQUFNLEdBQ1RHLEtBQUssSUFBSUgsTUFBTSxDQUFDRyxLQUFELEVBQVFDLEdBQVIsQ0FETixHQUVULElBRko7QUFHRDs7QUFFRCxNQUFNNEMsWUFBWSxHQUFHO0FBQ25CbEQsRUFBQUEsSUFBSSxFQUFFLEtBRGE7QUFFbkJXLEVBQUFBLE1BQU0sRUFBRSxRQUZXO0FBR25CSyxFQUFBQSxNQUFNLEVBQUUsTUFIVztBQUluQlUsRUFBQUEsTUFBTSxFQUFFLEtBSlc7QUFLbkJDLEVBQUFBLEtBQUssRUFBRTtBQUxZLENBQXJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29udHJvbGxlciB9IGZyb20gJy4vQ29udHJvbGxlcidcbmltcG9ydCB7IENvbnRyb2xsZXJFcnJvciB9IGZyb20gJ0AvZXJyb3JzJ1xuaW1wb3J0IHsgaXNPYmplY3QsIGlzQXJyYXksIGFzQXJyYXkgfSBmcm9tICdAZGl0b2pzL3V0aWxzJ1xuXG4vLyBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBNb2RlbENvbnRyb2xsZXIgYW5kIFJlbGF0aW9uQ29udHJvbGxlclxuZXhwb3J0IGNsYXNzIENvbGxlY3Rpb25Db250cm9sbGVyIGV4dGVuZHMgQ29udHJvbGxlciB7XG4gIGNvbnN0cnVjdG9yKGFwcCwgbmFtZXNwYWNlKSB7XG4gICAgc3VwZXIoYXBwLCBuYW1lc3BhY2UpXG4gICAgdGhpcy5tb2RlbENsYXNzID0gbnVsbCAvLyBUbyBiZSBkZWZpbmVkIGJ5IHN1Yi1jbGFzc2VzXG4gICAgdGhpcy5pc09uZVRvT25lID0gZmFsc2VcbiAgICB0aGlzLnJlbGF0ZSA9IGZhbHNlXG4gICAgdGhpcy51bnJlbGF0ZSA9IGZhbHNlXG4gIH1cblxuICBzZXR1cChpc1Jvb3QpIHtcbiAgICBzdXBlci5zZXR1cChpc1Jvb3QsIGZhbHNlKVxuICAgIHRoaXMuaWRQYXJhbSA9IHRoaXMubGV2ZWwgPyBgaWQke3RoaXMubGV2ZWx9YCA6ICdpZCdcbiAgICB0aGlzLmdyYXBoID0gISF0aGlzLmdyYXBoXG4gICAgdGhpcy50cmFuc2FjdGVkID0gISF0aGlzLnRyYW5zYWN0ZWRcbiAgICB0aGlzLnNjb3BlID0gdGhpcy5zY29wZSB8fCBudWxsXG4gICAgdGhpcy5jb2xsZWN0aW9uID0gdGhpcy5zZXR1cEFjdGlvbnMoJ2NvbGxlY3Rpb24nKVxuICAgIHRoaXMubWVtYmVyID0gdGhpcy5pc09uZVRvT25lID8ge30gOiB0aGlzLnNldHVwQWN0aW9ucygnbWVtYmVyJylcbiAgICAvLyBDcmVhdGUgYSBkdW1teSBtb2RlbCBpbnN0YW5jZSB0byB2YWxpZGF0ZSB0aGUgcmVxdWVzdGVkIGlkIGFnYWluc3QuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5ldy1jYXBcbiAgICB0aGlzLmlkVmFsaWRhdG9yID0gbmV3IHRoaXMubW9kZWxDbGFzcygpXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc2V0dXBBY3Rpb24odHlwZSwgYWN0aW9ucywgbmFtZSwgaGFuZGxlciwgYXV0aG9yaXplLCB2ZXJiLCBwYXRoKSB7XG4gICAgLy8gVGhlc2UgZGVmYXVsdCBhY3Rpb25zIGhhcHBlbiBkaXJlY3RseSBvbiB0aGUgY29sbGVjdGlvbiAvIG1lbWJlciByb3V0ZVxuICAgIC8vIGFuZCBhcmUgZGlzdGluZ3Vpc2hlZCBieSB0aGVpciB2ZXJicywgbm90IGJ5IG5lc3RlZCBwYXRocy5cbiAgICBpZiAobmFtZSBpbiBhY3Rpb25Ub1ZlcmIpIHtcbiAgICAgIHZlcmIgPSBhY3Rpb25Ub1ZlcmJbbmFtZV1cbiAgICAgIHBhdGggPSAnJ1xuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuc2V0dXBBY3Rpb24oXG4gICAgICB0eXBlLCBhY3Rpb25zLCBuYW1lLCBoYW5kbGVyLCBhdXRob3JpemUsIHZlcmIsIHBhdGhcbiAgICApXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc2V0dXBBc3NldHMoKSB7XG4gICAgY29uc3QgeyBtb2RlbENsYXNzIH0gPSB0aGlzXG4gICAgaWYgKHRoaXMuYXNzZXRzID09PSB0cnVlKSB7XG4gICAgICB0aGlzLmFzc2V0cyA9IG1vZGVsQ2xhc3MuZGVmaW5pdGlvbi5hc3NldHMgfHwgbnVsbFxuICAgIH0gZWxzZSBpZiAoaXNPYmplY3QodGhpcy5hc3NldHMpKSB7XG4gICAgICAvLyBNZXJnZSBpbiB0aGUgYXNzZXRzIGRlZmluaXRpb24gZnJvbSB0aGUgbW9kZWwgaW50byB0aGUgYXNzZXRzIGNvbmZpZy5cbiAgICAgIC8vIFRoYXQgd2F5LCB3ZSBjYW4gc3RpbGwgdXNlIGBhbGxvd2AgYW5kIGBhdXRob3JpemVgIHRvIGNvbnRyb2xsIHRoZVxuICAgICAgLy8gdXBsb2FkIGFjY2Vzcywgd2hpbGUga2VlcGluZyB0aGUgYXNzZXRzIGRlZmluaXRpb25zIGluIG9uZSBjZW50cmFsXG4gICAgICAvLyBsb2NhdGlvbiBvbiB0aGUgbW9kZWwuXG4gICAgICB0aGlzLmFzc2V0cyA9IHtcbiAgICAgICAgLi4ubW9kZWxDbGFzcy5kZWZpbml0aW9uLmFzc2V0cyxcbiAgICAgICAgLi4udGhpcy5hc3NldHNcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hc3NldHMgPSBudWxsXG4gICAgfVxuICAgIC8vIE5vdyBjYWxsIGBzdXBlci5zZXR1cEFzc2V0cygpYCB3aGljaCBwZXJmb3JtcyB0aGUgdXN1YWwgaW5oZXJpdGFuY2UgL1xuICAgIC8vIGFsbG93IC8gYXV0aG9yaXplIHRyaWNrczpcbiAgICByZXR1cm4gc3VwZXIuc2V0dXBBc3NldHMoKVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIGdldFBhdGgodHlwZSwgcGF0aCkge1xuICAgIHJldHVybiB0eXBlID09PSAnbWVtYmVyJ1xuICAgICAgPyBwYXRoID8gYDoke3RoaXMuaWRQYXJhbX0vJHtwYXRofWAgOiBgOiR7dGhpcy5pZFBhcmFtfWBcbiAgICAgIDogcGF0aFxuICB9XG5cbiAgZXh0ZW5kQ29udGV4dChjdHgsIG9iamVjdCkge1xuICAgIC8vIENyZWF0ZSBhIGNvcHkgb2YgYGN0eGAgdGhhdCBpbmhlcml0cyBmcm9tIHRoZSByZWFsIG9uZSwgYnV0IG92ZXJyaWRlc1xuICAgIC8vIHNvbWUgcHJvcGVydGllcyB3aXRoIHRoZSBvbmVzIGZyb20gdGhlIHBhc3NlZCBgb2JqZWN0YC5cbiAgICByZXR1cm4gT2JqZWN0LnNldFByb3RvdHlwZU9mKG9iamVjdCwgY3R4KVxuICB9XG5cbiAgZ2V0TWVtYmVySWQoY3R4KSB7XG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdGVJZChjdHgucGFyYW1zW3RoaXMuaWRQYXJhbV0pXG4gIH1cblxuICBnZXRDb250ZXh0V2l0aE1lbWJlcklkKGN0eCwgbWVtYmVySWQgPSB0aGlzLmdldE1lbWJlcklkKGN0eCkpIHtcbiAgICByZXR1cm4gdGhpcy5leHRlbmRDb250ZXh0KGN0eCwgeyBtZW1iZXJJZCB9KVxuICB9XG5cbiAgZ2V0Q29sbGVjdGlvbklkcyhjdHgpIHtcbiAgICBjb25zdCBpZFByb3BlcnR5ID0gdGhpcy5tb2RlbENsYXNzLmdldElkUHJvcGVydHkoKVxuICAgIC8vIEhhbmRsZSBib3RoIGNvbXBvc2l0ZSBrZXlzIGFuZCBub3JtYWwgb25lcy5cbiAgICBjb25zdCBnZXRJZCA9IGlzQXJyYXkoaWRQcm9wZXJ0eSlcbiAgICAgID8gbW9kZWwgPT4gaWRQcm9wZXJ0eS5yZWR1Y2UoXG4gICAgICAgIChpZCwga2V5KSA9PiB7XG4gICAgICAgICAgaWQucHVzaChtb2RlbFtrZXldKVxuICAgICAgICAgIHJldHVybiBpZFxuICAgICAgICB9LCBbXSlcbiAgICAgIDogbW9kZWwgPT4gbW9kZWxbaWRQcm9wZXJ0eV1cbiAgICByZXR1cm4gYXNBcnJheShjdHgucmVxdWVzdC5ib2R5KS5tYXAobW9kZWwgPT4gdGhpcy52YWxpZGF0ZUlkKGdldElkKG1vZGVsKSkpXG4gIH1cblxuICBnZXRJZHMoY3R4KSB7XG4gICAgLy8gUmV0dXJucyB0aGUgbW9kZWwgaWRzIHRoYXQgdGhpcyByZXF1ZXN0IGNvbmNlcm5zLCByZWFkIGZyb20gdGhlIHBhcmFtXG4gICAgLy8gZm9yIG1lbWJlciBpZHMsIGFuZCBmcm9tIHRoZSBwYXlsb2FkIGZvciBjb2xsZWN0aW9uIGlkczpcbiAgICBjb25zdCB7IHR5cGUgfSA9IGN0eC5hY3Rpb25cbiAgICByZXR1cm4gdHlwZSA9PT0gJ21lbWJlcicgPyBbdGhpcy5nZXRNZW1iZXJJZChjdHgpXVxuICAgICAgOiB0eXBlID09PSAnY29sbGVjdGlvbicgPyB0aGlzLmdldENvbGxlY3Rpb25JZHMoY3R4KVxuICAgICAgOiBbXVxuICB9XG5cbiAgdmFsaWRhdGVJZChpZCkge1xuICAgIGNvbnN0IHJlZmVyZW5jZSA9IHRoaXMubW9kZWxDbGFzcy5nZXRSZWZlcmVuY2UoaWQpXG4gICAgLy8gVGhpcyB2YWxpZGF0ZXMgYW5kIGNvZXJjZXMgYXQgdGhlIHNhbWUgdGltZSwgc28gZXh0cmFjdCB0aGUgY29lcmNlZCBpZFxuICAgIC8vIGZyb20gYHJlZmVyZW5jZWAgYWdhaW4gYWZ0ZXJ3YXJkcy5cbiAgICB0aGlzLmlkVmFsaWRhdG9yLiR2YWxpZGF0ZShyZWZlcmVuY2UsIHtcbiAgICAgIGNvZXJjZVR5cGVzOiB0cnVlLFxuICAgICAgcGF0Y2g6IHRydWVcbiAgICB9KVxuICAgIGNvbnN0IHZhbHVlcyA9IE9iamVjdC52YWx1ZXMocmVmZXJlbmNlKVxuICAgIHJldHVybiB2YWx1ZXMubGVuZ3RoID4gMSA/IHZhbHVlcyA6IHZhbHVlc1swXVxuICB9XG5cbiAgYXN5bmMgZ2V0TWVtYmVyKFxuICAgIGN0eCxcbiAgICBiYXNlID0gdGhpcyxcbiAgICB7IHF1ZXJ5ID0ge30sIG1vZGlmeSA9IG51bGwsIGZvclVwZGF0ZSA9IGZhbHNlIH0gPSB7fVxuICApIHtcbiAgICByZXR1cm4gdGhpcy5tZW1iZXIuZmluZC5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgIC8vIEV4dGVuZCBgY3R4YCB3aXRoIGEgbmV3IGBxdWVyeWAgb2JqZWN0LCB3aGlsZSBpbmhlcml0aW5nIHRoZSByb3V0ZVxuICAgICAgLy8gcGFyYW1zIGluIGBjdHgucGFyYW1zYCwgc28gZmluaW5nIHRoZSBtZW1iZXIgYnkgaWQgc3RpbGwgd29ya3MuXG4gICAgICB0aGlzLmV4dGVuZENvbnRleHQoY3R4LCB7IHF1ZXJ5IH0pLFxuICAgICAgKHF1ZXJ5LCB0cngpID0+IHtcbiAgICAgICAgdGhpcy5zZXR1cFF1ZXJ5KHF1ZXJ5LCBiYXNlKVxuICAgICAgICBxdWVyeS5tb2RpZnkobW9kaWZ5KVxuICAgICAgICBpZiAoZm9yVXBkYXRlKSB7XG4gICAgICAgICAgaWYgKCF0cngpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBDb250cm9sbGVyRXJyb3IoXG4gICAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICAgICdVc2luZyBgZm9yVXBkYXRlKClgIHdpdGhvdXQgYSB0cmFuc2FjdGlvbiBpcyBpbnZhbGlkJ1xuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cbiAgICAgICAgICBxdWVyeS5mb3JVcGRhdGUoKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgKVxuICB9XG5cbiAgcXVlcnkodHJ4KSB7XG4gICAgcmV0dXJuIHRoaXMuc2V0dXBRdWVyeSh0aGlzLm1vZGVsQ2xhc3MucXVlcnkodHJ4KSlcbiAgfVxuXG4gIHNldHVwUXVlcnkocXVlcnksIGJhc2UgPSB0aGlzKSB7XG4gICAgY29uc3QgeyBzY29wZSB9ID0gYmFzZVxuICAgIGNvbnN0IHsgYWxsb3dTY29wZSwgYWxsb3dGaWx0ZXIgfSA9IHRoaXNcblxuICAgIGNvbnN0IGFzQWxsb3dBcnJheSA9IHZhbHVlID0+IHZhbHVlID09PSBmYWxzZSA/IFtdIDogYXNBcnJheSh2YWx1ZSlcblxuICAgIGlmIChhbGxvd1Njb3BlICE9PSB1bmRlZmluZWQgJiYgYWxsb3dTY29wZSAhPT0gdHJ1ZSkge1xuICAgICAgcXVlcnkuYWxsb3dTY29wZShcbiAgICAgICAgLi4uYXNBbGxvd0FycmF5KGFsbG93U2NvcGUpLFxuICAgICAgICAvLyBBbHNvIGluY2x1ZGUgdGhlIHNjb3BlcyBkZWZpbmVkIGJ5IHNjb3BlIHNvIHRoZXNlIGNhbiBwYXNzIHRocm91Z2guXG4gICAgICAgIC4uLmFzQXJyYXkoc2NvcGUpXG4gICAgICApXG4gICAgfVxuICAgIGlmIChhbGxvd0ZpbHRlciAhPT0gdW5kZWZpbmVkICYmIGFsbG93RmlsdGVyICE9PSB0cnVlKSB7XG4gICAgICBxdWVyeS5hbGxvd0ZpbHRlciguLi5hc0FsbG93QXJyYXkoYWxsb3dGaWx0ZXIpKVxuICAgIH1cbiAgICBpZiAoc2NvcGUpIHtcbiAgICAgIHF1ZXJ5LndpdGhTY29wZSguLi5hc0FycmF5KHNjb3BlKSlcbiAgICB9XG4gICAgcmV0dXJuIHF1ZXJ5XG4gIH1cblxuICBhc3luYyBleGVjdXRlKC8qIGN0eCwgZXhlY3V0ZShxdWVyeSwgdHJ4KSB7fSAqLykge1xuICAgIC8vIERvZXMgbm90aGluZyBpbiBiYXNlIGNsYXNzLlxuICAgIC8vIE92ZXJyaWRlcyBhcmUgaW4gTW9kZWxDb250cm9sbGVyIGFuZCBSZWxhdGlvbkNvbnRyb2xsZXIuXG4gIH1cblxuICBhc3luYyBleGVjdXRlQW5kRmV0Y2goYWN0aW9uLCBjdHgsIG1vZGlmeSwgYm9keSA9IGN0eC5yZXF1ZXN0LmJvZHkpIHtcbiAgICBjb25zdCBuYW1lID0gYCR7YWN0aW9ufSR7dGhpcy5ncmFwaCA/ICdEaXRvR3JhcGgnIDogJyd9QW5kRmV0Y2hgXG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZShjdHgsIChxdWVyeSwgdHJ4KSA9PlxuICAgICAgcXVlcnlbbmFtZV0oYm9keSlcbiAgICAgICAgLm1vZGlmeShnZXRNb2RpZnkobW9kaWZ5LCB0cngpKVxuICAgIClcbiAgfVxuXG4gIGFzeW5jIGV4ZWN1dGVBbmRGZXRjaEJ5SWQoYWN0aW9uLCBjdHgsIG1vZGlmeSwgYm9keSA9IGN0eC5yZXF1ZXN0LmJvZHkpIHtcbiAgICBjb25zdCBuYW1lID0gYCR7YWN0aW9ufSR7dGhpcy5ncmFwaCA/ICdEaXRvR3JhcGgnIDogJyd9QW5kRmV0Y2hCeUlkYFxuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoY3R4LCAocXVlcnksIHRyeCkgPT5cbiAgICAgIHF1ZXJ5W25hbWVdKGN0eC5tZW1iZXJJZCwgYm9keSlcbiAgICAgICAgLnRocm93SWZOb3RGb3VuZCgpXG4gICAgICAgIC5tb2RpZnkoZ2V0TW9kaWZ5KG1vZGlmeSwgdHJ4KSlcbiAgICApXG4gIH1cblxuICB0b0NvcmVBY3Rpb25zKGFjdGlvbnMpIHtcbiAgICAvLyBNYXJrIGFjdGlvbiBvYmplY3QgYW5kIG1ldGhvZHMgYXMgY29yZSwgc28gYENvbnRyb2xsZXIucHJvY2Vzc1ZhbHVlcygpYFxuICAgIC8vIGNhbiBmaWx0ZXIgY29ycmVjdGx5LlxuICAgIGZvciAoY29uc3QgYWN0aW9uIG9mIE9iamVjdC52YWx1ZXMoYWN0aW9ucykpIHtcbiAgICAgIC8vIE1hcmsgYWN0aW9uIGZ1bmN0aW9ucyBhbHNvLCBzbyBDb250cm9sbGVyQWN0aW9uIGNhbiB1c2UgaXQgdG8gZGV0ZXJtaW5lXG4gICAgICAvLyB2YWx1ZSBmb3IgYHRyYW5zYWN0ZWRgLlxuICAgICAgYWN0aW9uLmNvcmUgPSB0cnVlXG4gICAgfVxuICAgIGFjdGlvbnMuJGNvcmUgPSB0cnVlXG4gICAgcmV0dXJuIGFjdGlvbnNcbiAgfVxuXG4gIGNvbGxlY3Rpb24gPSB0aGlzLnRvQ29yZUFjdGlvbnMoe1xuICAgIGFzeW5jIGZpbmQoY3R4LCBtb2RpZnkpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZShjdHgsIChxdWVyeSwgdHJ4KSA9PiB7XG4gICAgICAgIHF1ZXJ5LmZpbmQoY3R4LnF1ZXJ5LCB0aGlzLmFsbG93UGFyYW0pLm1vZGlmeShnZXRNb2RpZnkobW9kaWZ5LCB0cngpKVxuICAgICAgICByZXR1cm4gdGhpcy5pc09uZVRvT25lID8gcXVlcnkuZmlyc3QoKSA6IHF1ZXJ5XG4gICAgICB9KVxuICAgICAgLy8gVGhpcyBtZXRob2QgZG9lc24ndCBhbHdheXMgcmV0dXJuIGFuIGFycmF5OlxuICAgICAgLy8gRm9yIFJlbGF0aW9uQ29udHJvbGxlcnMgd2hlcmUgYGlzT25lVG9PbmVgIGlzIHRydWUsIGl0IGNhbiByZXR1cm5cbiAgICAgIC8vIGB1bmRlZmluZWRgLiBDYXN0IHRvIGBudWxsYCBmb3Igc3VjaCBjYXNlczpcbiAgICAgIHJldHVybiByZXN1bHQgfHwgbnVsbFxuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGUoY3R4LCBtb2RpZnkpIHtcbiAgICAgIGNvbnN0IGNvdW50ID0gYXdhaXQgdGhpcy5leGVjdXRlKGN0eCwgKHF1ZXJ5LCB0cngpID0+IHF1ZXJ5XG4gICAgICAgIC5pZ25vcmVTY29wZSgpXG4gICAgICAgIC5maW5kKGN0eC5xdWVyeSwgdGhpcy5hbGxvd1BhcmFtKVxuICAgICAgICAubW9kaWZ5KHF1ZXJ5ID0+IHRoaXMuaXNPbmVUb09uZSAmJiBxdWVyeS50aHJvd0lmTm90Rm91bmQoKSlcbiAgICAgICAgLm1vZGlmeShnZXRNb2RpZnkobW9kaWZ5LCB0cngpKVxuICAgICAgICAubW9kaWZ5KHF1ZXJ5ID0+IHRoaXMudW5yZWxhdGUgPyBxdWVyeS51bnJlbGF0ZSgpIDogcXVlcnkuZGVsZXRlKCkpXG4gICAgICApXG4gICAgICByZXR1cm4geyBjb3VudCB9XG4gICAgfSxcblxuICAgIGFzeW5jIGluc2VydChjdHgsIG1vZGlmeSkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5yZWxhdGVcbiAgICAgICAgLy8gVXNlIHBhdGNoRGl0b0dyYXBoQW5kRmV0Y2goKSB0byBoYW5kbGUgcmVsYXRlcyBmb3IgdXMuXG4gICAgICAgID8gYXdhaXQgdGhpcy5leGVjdXRlKGN0eCwgKHF1ZXJ5LCB0cngpID0+IHF1ZXJ5XG4gICAgICAgICAgLnBhdGNoRGl0b0dyYXBoQW5kRmV0Y2goY3R4LnJlcXVlc3QuYm9keSwgeyByZWxhdGU6IHRydWUgfSlcbiAgICAgICAgICAubW9kaWZ5KGdldE1vZGlmeShtb2RpZnksIHRyeCkpXG4gICAgICAgIClcbiAgICAgICAgOiBhd2FpdCB0aGlzLmV4ZWN1dGVBbmRGZXRjaCgnaW5zZXJ0JywgY3R4LCBtb2RpZnkpXG4gICAgICBjdHguc3RhdHVzID0gMjAxXG4gICAgICBpZiAoaXNPYmplY3QocmVzdWx0KSkge1xuICAgICAgICBjdHguc2V0KCdMb2NhdGlvbicsIHRoaXMuZ2V0VXJsKCdjb2xsZWN0aW9uJywgcmVzdWx0LmlkKSlcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHRcbiAgICB9LFxuXG4gICAgYXN5bmMgdXBkYXRlKGN0eCwgbW9kaWZ5KSB7XG4gICAgICByZXR1cm4gdGhpcy5leGVjdXRlQW5kRmV0Y2goJ3VwZGF0ZScsIGN0eCwgbW9kaWZ5KVxuICAgIH0sXG5cbiAgICBhc3luYyBwYXRjaChjdHgsIG1vZGlmeSkge1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZUFuZEZldGNoKCdwYXRjaCcsIGN0eCwgbW9kaWZ5KVxuICAgIH1cbiAgfSlcblxuICBtZW1iZXIgPSB0aGlzLnRvQ29yZUFjdGlvbnMoe1xuICAgIGFzeW5jIGZpbmQoY3R4LCBtb2RpZnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoY3R4LCAocXVlcnksIHRyeCkgPT4gcXVlcnlcbiAgICAgICAgLmZpbmRCeUlkKGN0eC5tZW1iZXJJZClcbiAgICAgICAgLmZpbmQoY3R4LnF1ZXJ5LCB0aGlzLmFsbG93UGFyYW0pXG4gICAgICAgIC50aHJvd0lmTm90Rm91bmQoKVxuICAgICAgICAubW9kaWZ5KGdldE1vZGlmeShtb2RpZnksIHRyeCkpXG4gICAgICApXG4gICAgfSxcblxuICAgIGFzeW5jIGRlbGV0ZShjdHgsIG1vZGlmeSkge1xuICAgICAgY29uc3QgY291bnQgPSBhd2FpdCB0aGlzLmV4ZWN1dGUoY3R4LCAocXVlcnksIHRyeCkgPT4gcXVlcnlcbiAgICAgICAgLmlnbm9yZVNjb3BlKClcbiAgICAgICAgLmZpbmRCeUlkKGN0eC5tZW1iZXJJZClcbiAgICAgICAgLmZpbmQoY3R4LnF1ZXJ5LCB0aGlzLmFsbG93UGFyYW0pXG4gICAgICAgIC50aHJvd0lmTm90Rm91bmQoKVxuICAgICAgICAubW9kaWZ5KGdldE1vZGlmeShtb2RpZnksIHRyeCkpXG4gICAgICAgIC5tb2RpZnkocXVlcnkgPT4gdGhpcy51bnJlbGF0ZSA/IHF1ZXJ5LnVucmVsYXRlKCkgOiBxdWVyeS5kZWxldGUoKSlcbiAgICAgIClcbiAgICAgIHJldHVybiB7IGNvdW50IH1cbiAgICB9LFxuXG4gICAgYXN5bmMgdXBkYXRlKGN0eCwgbW9kaWZ5KSB7XG4gICAgICByZXR1cm4gdGhpcy5leGVjdXRlQW5kRmV0Y2hCeUlkKCd1cGRhdGUnLCBjdHgsIG1vZGlmeSlcbiAgICB9LFxuXG4gICAgYXN5bmMgcGF0Y2goY3R4LCBtb2RpZnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGVBbmRGZXRjaEJ5SWQoJ3BhdGNoJywgY3R4LCBtb2RpZnkpXG4gICAgfVxuICB9KVxufVxuXG5mdW5jdGlvbiBnZXRNb2RpZnkobW9kaWZ5LCB0cngpIHtcbiAgcmV0dXJuIG1vZGlmeVxuICAgID8gcXVlcnkgPT4gbW9kaWZ5KHF1ZXJ5LCB0cngpXG4gICAgOiBudWxsXG59XG5cbmNvbnN0IGFjdGlvblRvVmVyYiA9IHtcbiAgZmluZDogJ2dldCcsXG4gIGRlbGV0ZTogJ2RlbGV0ZScsXG4gIGluc2VydDogJ3Bvc3QnLFxuICB1cGRhdGU6ICdwdXQnLFxuICBwYXRjaDogJ3BhdGNoJ1xufVxuIl19