@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,462 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.Controller = void 0;
5
-
6
- require("core-js/modules/esnext.async-iterator.for-each.js");
7
-
8
- require("core-js/modules/esnext.iterator.constructor.js");
9
-
10
- require("core-js/modules/esnext.iterator.for-each.js");
11
-
12
- require("core-js/modules/esnext.async-iterator.map.js");
13
-
14
- require("core-js/modules/esnext.iterator.map.js");
15
-
16
- require("core-js/modules/esnext.async-iterator.filter.js");
17
-
18
- require("core-js/modules/esnext.iterator.filter.js");
19
-
20
- require("core-js/modules/esnext.async-iterator.reduce.js");
21
-
22
- require("core-js/modules/esnext.iterator.reduce.js");
23
-
24
- require("core-js/modules/esnext.async-iterator.find.js");
25
-
26
- require("core-js/modules/esnext.iterator.find.js");
27
-
28
- require("core-js/modules/esnext.weak-map.delete-all.js");
29
-
30
- require("core-js/modules/esnext.weak-map.emplace.js");
31
-
32
- var _picocolors = _interopRequireDefault(require("picocolors"));
33
-
34
- var _utils = require("../utils");
35
-
36
- var _lib = require("../lib");
37
-
38
- var _ControllerAction = _interopRequireDefault(require("./ControllerAction"));
39
-
40
- var _MemberAction = _interopRequireDefault(require("./MemberAction"));
41
-
42
- var _errors = require("../errors");
43
-
44
- var _utils2 = require("@ditojs/utils");
45
-
46
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
47
-
48
- class Controller {
49
- constructor(app, namespace) {
50
- this.app = app;
51
- this.namespace = this.namespace || namespace;
52
- this.logging = this.app.config.log.routes;
53
- this.level = 0;
54
- }
55
-
56
- initialize() {}
57
-
58
- setup(isRoot = true, setupActionsObject = true) {
59
- this._setupEmitter(this.hooks, {
60
- wildcard: true
61
- });
62
-
63
- this.name = this.name || this.constructor.name.match(/^(.*?)(?:Controller|)$/)[1];
64
-
65
- if (this.path === undefined) {
66
- this.path = this.app.normalizePath(this.name);
67
- }
68
-
69
- this.transacted = !!this.transacted;
70
-
71
- if (isRoot) {
72
- const {
73
- path,
74
- namespace
75
- } = this;
76
- const url = path ? `/${path}` : '';
77
- this.url = namespace ? `/${namespace}${url}` : url;
78
- this.log(`${namespace ? _picocolors.default.green(`/${namespace}/`) : ''}${_picocolors.default.cyan(path)}${_picocolors.default.white(':')}`, this.level);
79
-
80
- if (setupActionsObject) {
81
- this.actions = this.actions || this.reflectActionsObject();
82
- this.actions = this.setupActions('actions');
83
- }
84
-
85
- this.assets = this.setupAssets();
86
- }
87
- }
88
-
89
- reflectActionsObject() {
90
- const {
91
- allow
92
- } = this;
93
- const controller = allow ? {
94
- allow
95
- } : {};
96
-
97
- const addAction = key => {
98
- const value = this[key];
99
-
100
- if (value != null && value.verb) {
101
- controller[key] = value;
102
- }
103
- };
104
-
105
- const proto = Object.getPrototypeOf(this);
106
- Object.getOwnPropertyNames(proto).forEach(addAction);
107
- Object.getOwnPropertyNames(this).forEach(addAction);
108
- return controller;
109
- }
110
-
111
- setupRoute(verb, url, transacted, authorize, action, handlers) {
112
- this.log(`${_picocolors.default.magenta(verb.toUpperCase())} ${_picocolors.default.green(this.url)}${_picocolors.default.cyan(url.slice(this.url.length))} ${_picocolors.default.white(this.describeAuthorize(authorize))}`, this.level + 1);
113
- this.app.addRoute(verb, url, transacted, handlers, this, action);
114
- }
115
-
116
- setupActions(type) {
117
- const {
118
- values: actions,
119
- authorize
120
- } = this.processValues(this.inheritValues(type));
121
-
122
- for (const [name, handler] of Object.entries(actions)) {
123
- this.setupAction(type, actions, name, handler, authorize[name]);
124
- }
125
-
126
- return actions;
127
- }
128
-
129
- setupAction(type, actions, name, handler, authorize, verb = 'get', path = this.app.normalizePath(name)) {
130
- if (!(0, _utils2.isFunction)(handler)) {
131
- handler = setupHandlerFromObject(handler, actions);
132
- }
133
-
134
- const actionClass = type === 'member' ? _MemberAction.default : _ControllerAction.default;
135
- this.setupActionRoute(type, new actionClass(this, handler, type, name, verb, path, authorize));
136
- }
137
-
138
- setupActionRoute(type, action) {
139
- const url = this.getUrl(type, action.path);
140
- const {
141
- verb,
142
- transacted,
143
- authorize
144
- } = action;
145
- this.setupRoute(verb, url, transacted, authorize, action, [async ctx => {
146
- try {
147
- const res = await action.callAction(ctx);
148
-
149
- if (res !== undefined) {
150
- ctx.body = res;
151
- }
152
- } catch (err) {
153
- throw err instanceof _errors.ResponseError ? err : new _errors.WrappedError(err);
154
- }
155
- }]);
156
- }
157
-
158
- setupAssets() {
159
- const {
160
- values: assets,
161
- authorize
162
- } = this.processValues(this.inheritValues('assets'));
163
-
164
- for (const [dataPath, config] of Object.entries(assets || {})) {
165
- this.setupAssetRoute(dataPath, config, authorize[dataPath]);
166
- }
167
-
168
- return assets;
169
- }
170
-
171
- setupAssetRoute(dataPath, config, authorize) {
172
- const {
173
- storage: storageName,
174
- transacted,
175
- ...settings
176
- } = config;
177
- const storage = this.app.getStorage(storageName);
178
-
179
- if (!storage) {
180
- throw new _errors.ControllerError(this, `Unknown storage configuration: '${storageName}'`);
181
- }
182
-
183
- const tokens = (0, _utils2.parseDataPath)(dataPath);
184
-
185
- const getDataPath = callback => (0, _utils2.normalizeDataPath)(tokens.map(callback));
186
-
187
- let index = 0;
188
- const multipleWildcards = tokens.filter(token => token === '*').length > 1;
189
- const normalizedPath = getDataPath(token => token === '*' ? multipleWildcards ? `:index${++index}` : ':index' : this.app.normalizePath(token));
190
- const matchDataPath = new RegExp(`^${getDataPath(token => token === '*' ? '\\w+' : token)}$`);
191
- const url = this.getUrl('controller', `upload/${normalizedPath}`);
192
- const upload = storage.getUploadHandler({ ...settings,
193
- fileFilter: (req, file, cb) => {
194
- cb(null, matchDataPath.test(file.fieldname));
195
- }
196
- });
197
- const authorization = this.processAuthorize(authorize);
198
- this.setupRoute('post', url, transacted, authorize, null, [async (ctx, next) => {
199
- await this.handleAuthorization(authorization, ctx);
200
- return next();
201
- }, upload, async (ctx, next) => {
202
- const files = storage.convertStorageFiles(ctx.request.files);
203
- await this.app.createAssets(storage, files, 0, ctx.transaction);
204
- ctx.body = files;
205
- return next();
206
- }]);
207
- }
208
-
209
- compose() {}
210
-
211
- getPath(type, path) {
212
- return path;
213
- }
214
-
215
- getUrl(type, path) {
216
- path = this.getPath(type, path);
217
- return path && path !== '.' ? `${this.url}/${path}` : this.url;
218
- }
219
-
220
- inheritValues(type) {
221
- const parentClass = Object.getPrototypeOf(this.constructor);
222
-
223
- if (!inheritanceMap.has(parentClass)) {
224
- inheritanceMap.set(parentClass, {
225
- instance: new parentClass(this.app, this.namespace)
226
- });
227
- }
228
-
229
- const entry = inheritanceMap.get(parentClass);
230
-
231
- if (!entry[type]) {
232
- const parent = entry.instance;
233
- let values = parent[type];
234
-
235
- if (parentClass !== Controller) {
236
- values = parent.inheritValues(type);
237
- }
238
-
239
- entry[type] = values;
240
- }
241
-
242
- const parentValues = entry[type];
243
- let currentValues = this[type];
244
-
245
- if (currentValues && currentValues === parentValues) {
246
- currentValues = this[type] = {};
247
- }
248
-
249
- return (0, _utils2.isObject)(parentValues) && (0, _utils2.isObject)(currentValues) ? Object.setPrototypeOf(currentValues, parentValues) : currentValues;
250
- }
251
-
252
- processValues(values) {
253
- if (!values) return {};
254
- const mergedAllow = {};
255
- const mergedAuthorize = {};
256
- let hasOwnAllow = false;
257
-
258
- const excludeKey = key => ['allow', 'authorize'].includes(key);
259
-
260
- const handleAllow = (allow, current) => {
261
- if (allow) {
262
- allow = (0, _utils2.asArray)(allow);
263
- hasOwnAllow = true;
264
- } else if (!hasOwnAllow) {
265
- allow = Object.keys(current);
266
- }
267
-
268
- if (allow) {
269
- if (allow.includes('*')) {
270
- allow = (0, _utils.getAllKeys)(current);
271
- }
272
-
273
- for (const key of allow) {
274
- if (!excludeKey(key)) {
275
- mergedAllow[key] = true;
276
- }
277
- }
278
- }
279
- };
280
-
281
- const handleAuthorize = authorize => {
282
- const add = (key, value) => {
283
- if (key in values && !(key in mergedAuthorize) && !excludeKey(key)) {
284
- mergedAuthorize[key] = value;
285
- }
286
- };
287
-
288
- if ((0, _utils2.isObject)(authorize)) {
289
- for (const key in authorize) {
290
- add(key, authorize[key]);
291
- }
292
- } else if (authorize != null) {
293
- for (const key in values) {
294
- add(key, authorize);
295
- }
296
- }
297
- };
298
-
299
- let current = values;
300
-
301
- while (current !== Object.prototype && !current.hasOwnProperty('$core')) {
302
- handleAllow((0, _utils.getOwnProperty)(current, 'allow'), current);
303
- handleAuthorize((0, _utils.getOwnProperty)(current, 'authorize'));
304
- current = Object.getPrototypeOf(current);
305
- }
306
-
307
- if (this.allow) {
308
- handleAllow(this.allow, values);
309
- }
310
-
311
- if (this.authorize) {
312
- handleAuthorize(this.authorize);
313
- }
314
-
315
- return {
316
- values: (0, _utils.getAllKeys)(values).reduce((result, key) => {
317
- if (mergedAllow[key]) {
318
- result[key] = values[key];
319
- }
320
-
321
- return result;
322
- }, Object.create(Object.getPrototypeOf(values))),
323
- allow: Object.keys(mergedAllow),
324
- authorize: mergedAuthorize
325
- };
326
- }
327
-
328
- async emitHook(type, handleResult, ctx, ...args) {
329
- let result = handleResult ? args.shift() : undefined;
330
-
331
- for (const handler of this.listeners(type)) {
332
- if (handleResult) {
333
- const res = await handler.call(this, ctx, result, ...args);
334
-
335
- if (res !== undefined) {
336
- result = res;
337
- }
338
- } else {
339
- await handler.call(this, ctx, ...args);
340
- }
341
- }
342
-
343
- return result;
344
- }
345
-
346
- async getMember() {
347
- return null;
348
- }
349
-
350
- processAuthorize(authorize) {
351
- if (authorize == null) {
352
- return () => true;
353
- } else if ((0, _utils2.isBoolean)(authorize)) {
354
- return () => authorize;
355
- } else if ((0, _utils2.isFunction)(authorize)) {
356
- return async (ctx, member) => {
357
- const res = await authorize(ctx, member);
358
- return this.processAuthorize(res)(ctx, member);
359
- };
360
- } else if ((0, _utils2.isString)(authorize) || (0, _utils2.isArray)(authorize)) {
361
- return async (ctx, member) => {
362
- const {
363
- user
364
- } = ctx.state;
365
-
366
- if (!user) {
367
- return false;
368
- }
369
-
370
- const values = (0, _utils2.asArray)(authorize);
371
-
372
- if (!member && values.includes('$owner')) {
373
- member = await this.getMember(ctx);
374
- }
375
-
376
- return !!values.find(value => {
377
- var _member;
378
-
379
- return value === '$self' ? user.constructor === this.modelClass && (0, _utils2.equals)(user.$id(), ctx.memberId) : value === '$owner' ? (_member = member) == null ? void 0 : _member.$hasOwner == null ? void 0 : _member.$hasOwner(user) : user.$hasRole(value);
380
- });
381
- };
382
- } else {
383
- throw new _errors.ControllerError(this, `Unsupported authorize setting: '${authorize}'`);
384
- }
385
- }
386
-
387
- describeAuthorize(authorize) {
388
- return (0, _utils2.isFunction)(authorize) ? (0, _utils.describeFunction)(authorize) : (0, _utils2.isString)(authorize) ? `'${authorize}'` : (0, _utils2.isArray)(authorize) ? `[${authorize.map(value => `'${value}'`).join(', ')}]` : '';
389
- }
390
-
391
- async handleAuthorization(authorization, ctx, member) {
392
- const ok = await authorization(ctx, member);
393
-
394
- if (ok !== true) {
395
- throw new _errors.AuthorizationError();
396
- }
397
- }
398
-
399
- log(str, indent = 0) {
400
- if (this.logging) {
401
- console.info(`${' '.repeat(indent)}${str}`);
402
- }
403
- }
404
-
405
- }
406
-
407
- exports.Controller = Controller;
408
-
409
- _lib.EventEmitter.mixin(Controller.prototype);
410
-
411
- const inheritanceMap = new WeakMap();
412
-
413
- function setupHandlerFromObject(object, actions) {
414
- const {
415
- handler,
416
- action,
417
- authorize,
418
- parameters,
419
- returns,
420
- scope,
421
- transacted
422
- } = object;
423
- Object.setPrototypeOf(object, Object.getPrototypeOf(actions));
424
- handler.authorize = authorize;
425
- handler.transacted = transacted;
426
-
427
- if (action) {
428
- const [verb, path] = (0, _utils2.asArray)(action);
429
- handler.verb = verb;
430
- handler.path = path;
431
- }
432
-
433
- if (parameters) {
434
- const [_parameters, options] = parameters;
435
- const hasOptions = (0, _utils2.isArray)(_parameters);
436
- handler.parameters = hasOptions ? _parameters : parameters;
437
-
438
- if (hasOptions) {
439
- handler.options = { ...handler.options,
440
- parameters: options
441
- };
442
- }
443
- }
444
-
445
- if (returns) {
446
- const [_returns, options] = (0, _utils2.asArray)(returns);
447
- handler.returns = _returns;
448
-
449
- if (options) {
450
- handler.options = { ...handler.options,
451
- parameters: options
452
- };
453
- }
454
- }
455
-
456
- if (scope) {
457
- handler.scope = (0, _utils2.asArray)(scope);
458
- }
459
-
460
- return handler;
461
- }
462
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb250cm9sbGVycy9Db250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFwcCIsIm5hbWVzcGFjZSIsImxvZ2dpbmciLCJjb25maWciLCJsb2ciLCJyb3V0ZXMiLCJsZXZlbCIsImluaXRpYWxpemUiLCJzZXR1cCIsImlzUm9vdCIsInNldHVwQWN0aW9uc09iamVjdCIsIl9zZXR1cEVtaXR0ZXIiLCJob29rcyIsIndpbGRjYXJkIiwibmFtZSIsIm1hdGNoIiwicGF0aCIsInVuZGVmaW5lZCIsIm5vcm1hbGl6ZVBhdGgiLCJ0cmFuc2FjdGVkIiwidXJsIiwicGljbyIsImdyZWVuIiwiY3lhbiIsIndoaXRlIiwiYWN0aW9ucyIsInJlZmxlY3RBY3Rpb25zT2JqZWN0Iiwic2V0dXBBY3Rpb25zIiwiYXNzZXRzIiwic2V0dXBBc3NldHMiLCJhbGxvdyIsImNvbnRyb2xsZXIiLCJhZGRBY3Rpb24iLCJrZXkiLCJ2YWx1ZSIsInZlcmIiLCJwcm90byIsIk9iamVjdCIsImdldFByb3RvdHlwZU9mIiwiZ2V0T3duUHJvcGVydHlOYW1lcyIsImZvckVhY2giLCJzZXR1cFJvdXRlIiwiYXV0aG9yaXplIiwiYWN0aW9uIiwiaGFuZGxlcnMiLCJtYWdlbnRhIiwidG9VcHBlckNhc2UiLCJzbGljZSIsImxlbmd0aCIsImRlc2NyaWJlQXV0aG9yaXplIiwiYWRkUm91dGUiLCJ0eXBlIiwidmFsdWVzIiwicHJvY2Vzc1ZhbHVlcyIsImluaGVyaXRWYWx1ZXMiLCJoYW5kbGVyIiwiZW50cmllcyIsInNldHVwQWN0aW9uIiwic2V0dXBIYW5kbGVyRnJvbU9iamVjdCIsImFjdGlvbkNsYXNzIiwiTWVtYmVyQWN0aW9uIiwiQ29udHJvbGxlckFjdGlvbiIsInNldHVwQWN0aW9uUm91dGUiLCJnZXRVcmwiLCJjdHgiLCJyZXMiLCJjYWxsQWN0aW9uIiwiYm9keSIsImVyciIsIlJlc3BvbnNlRXJyb3IiLCJXcmFwcGVkRXJyb3IiLCJkYXRhUGF0aCIsInNldHVwQXNzZXRSb3V0ZSIsInN0b3JhZ2UiLCJzdG9yYWdlTmFtZSIsInNldHRpbmdzIiwiZ2V0U3RvcmFnZSIsIkNvbnRyb2xsZXJFcnJvciIsInRva2VucyIsImdldERhdGFQYXRoIiwiY2FsbGJhY2siLCJtYXAiLCJpbmRleCIsIm11bHRpcGxlV2lsZGNhcmRzIiwiZmlsdGVyIiwidG9rZW4iLCJub3JtYWxpemVkUGF0aCIsIm1hdGNoRGF0YVBhdGgiLCJSZWdFeHAiLCJ1cGxvYWQiLCJnZXRVcGxvYWRIYW5kbGVyIiwiZmlsZUZpbHRlciIsInJlcSIsImZpbGUiLCJjYiIsInRlc3QiLCJmaWVsZG5hbWUiLCJhdXRob3JpemF0aW9uIiwicHJvY2Vzc0F1dGhvcml6ZSIsIm5leHQiLCJoYW5kbGVBdXRob3JpemF0aW9uIiwiZmlsZXMiLCJjb252ZXJ0U3RvcmFnZUZpbGVzIiwicmVxdWVzdCIsImNyZWF0ZUFzc2V0cyIsInRyYW5zYWN0aW9uIiwiY29tcG9zZSIsImdldFBhdGgiLCJwYXJlbnRDbGFzcyIsImluaGVyaXRhbmNlTWFwIiwiaGFzIiwic2V0IiwiaW5zdGFuY2UiLCJlbnRyeSIsImdldCIsInBhcmVudCIsInBhcmVudFZhbHVlcyIsImN1cnJlbnRWYWx1ZXMiLCJzZXRQcm90b3R5cGVPZiIsIm1lcmdlZEFsbG93IiwibWVyZ2VkQXV0aG9yaXplIiwiaGFzT3duQWxsb3ciLCJleGNsdWRlS2V5IiwiaW5jbHVkZXMiLCJoYW5kbGVBbGxvdyIsImN1cnJlbnQiLCJrZXlzIiwiaGFuZGxlQXV0aG9yaXplIiwiYWRkIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJyZWR1Y2UiLCJyZXN1bHQiLCJjcmVhdGUiLCJlbWl0SG9vayIsImhhbmRsZVJlc3VsdCIsImFyZ3MiLCJzaGlmdCIsImxpc3RlbmVycyIsImNhbGwiLCJnZXRNZW1iZXIiLCJtZW1iZXIiLCJ1c2VyIiwic3RhdGUiLCJmaW5kIiwibW9kZWxDbGFzcyIsIiRpZCIsIm1lbWJlcklkIiwiJGhhc093bmVyIiwiJGhhc1JvbGUiLCJqb2luIiwib2siLCJBdXRob3JpemF0aW9uRXJyb3IiLCJzdHIiLCJpbmRlbnQiLCJjb25zb2xlIiwiaW5mbyIsInJlcGVhdCIsIkV2ZW50RW1pdHRlciIsIm1peGluIiwiV2Vha01hcCIsIm9iamVjdCIsInBhcmFtZXRlcnMiLCJyZXR1cm5zIiwic2NvcGUiLCJfcGFyYW1ldGVycyIsIm9wdGlvbnMiLCJoYXNPcHRpb25zIiwiX3JldHVybnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFHQTs7OztBQUtPLE1BQU1BLFVBQU4sQ0FBaUI7QUFDdEJDLEVBQUFBLFdBQVcsQ0FBQ0MsR0FBRCxFQUFNQyxTQUFOLEVBQWlCO0FBQzFCLFNBQUtELEdBQUwsR0FBV0EsR0FBWDtBQUNBLFNBQUtDLFNBQUwsR0FBaUIsS0FBS0EsU0FBTCxJQUFrQkEsU0FBbkM7QUFDQSxTQUFLQyxPQUFMLEdBQWUsS0FBS0YsR0FBTCxDQUFTRyxNQUFULENBQWdCQyxHQUFoQixDQUFvQkMsTUFBbkM7QUFDQSxTQUFLQyxLQUFMLEdBQWEsQ0FBYjtBQUNEOztBQUdEQyxFQUFBQSxVQUFVLEdBQUcsQ0FDWjs7QUFFREMsRUFBQUEsS0FBSyxDQUFDQyxNQUFNLEdBQUcsSUFBVixFQUFnQkMsa0JBQWtCLEdBQUcsSUFBckMsRUFBMkM7QUFDOUMsU0FBS0MsYUFBTCxDQUFtQixLQUFLQyxLQUF4QixFQUErQjtBQUU3QkMsTUFBQUEsUUFBUSxFQUFFO0FBRm1CLEtBQS9COztBQUtBLFNBQUtDLElBQUwsR0FBWSxLQUFLQSxJQUFMLElBQ1YsS0FBS2YsV0FBTCxDQUFpQmUsSUFBakIsQ0FBc0JDLEtBQXRCLENBQTRCLHdCQUE1QixFQUFzRCxDQUF0RCxDQURGOztBQUVBLFFBQUksS0FBS0MsSUFBTCxLQUFjQyxTQUFsQixFQUE2QjtBQUMzQixXQUFLRCxJQUFMLEdBQVksS0FBS2hCLEdBQUwsQ0FB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Q0FBQ3ZDLElBQVIsR0FBZUEsSUFBZjtBQUNEOztBQUVELE1BQUlrSixVQUFKLEVBQWdCO0FBQ2QsVUFBTSxDQUFDRyxXQUFELEVBQWNDLE9BQWQsSUFBeUJKLFVBQS9CO0FBQ0EsVUFBTUssVUFBVSxHQUFHLHFCQUFRRixXQUFSLENBQW5CO0FBQ0E5RyxJQUFBQSxPQUFPLENBQUMyRyxVQUFSLEdBQXFCSyxVQUFVLEdBQUdGLFdBQUgsR0FBaUJILFVBQWhEOztBQUlBLFFBQUlLLFVBQUosRUFBZ0I7QUFDZGhILE1BQUFBLE9BQU8sQ0FBQytHLE9BQVIsR0FBa0IsRUFDaEIsR0FBRy9HLE9BQU8sQ0FBQytHLE9BREs7QUFFaEJKLFFBQUFBLFVBQVUsRUFBRUk7QUFGSSxPQUFsQjtBQUlEO0FBQ0Y7O0FBRUQsTUFBSUgsT0FBSixFQUFhO0FBQ1gsVUFBTSxDQUFDSyxRQUFELEVBQVdGLE9BQVgsSUFBc0IscUJBQVFILE9BQVIsQ0FBNUI7QUFDQTVHLElBQUFBLE9BQU8sQ0FBQzRHLE9BQVIsR0FBa0JLLFFBQWxCOztBQUlBLFFBQUlGLE9BQUosRUFBYTtBQUNYL0csTUFBQUEsT0FBTyxDQUFDK0csT0FBUixHQUFrQixFQUNoQixHQUFHL0csT0FBTyxDQUFDK0csT0FESztBQUVoQkosUUFBQUEsVUFBVSxFQUFFSTtBQUZJLE9BQWxCO0FBSUQ7QUFDRjs7QUFFRCxNQUFJRixLQUFKLEVBQVc7QUFDVDdHLElBQUFBLE9BQU8sQ0FBQzZHLEtBQVIsR0FBZ0IscUJBQVFBLEtBQVIsQ0FBaEI7QUFDRDs7QUFFRCxTQUFPN0csT0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHBpY28gZnJvbSAncGljb2NvbG9ycydcbmltcG9ydCB7IGdldE93blByb3BlcnR5LCBnZXRBbGxLZXlzLCBkZXNjcmliZUZ1bmN0aW9uIH0gZnJvbSAnQC91dGlscydcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ0AvbGliJ1xuaW1wb3J0IENvbnRyb2xsZXJBY3Rpb24gZnJvbSAnLi9Db250cm9sbGVyQWN0aW9uJ1xuaW1wb3J0IE1lbWJlckFjdGlvbiBmcm9tICcuL01lbWJlckFjdGlvbidcbmltcG9ydCB7XG4gIFJlc3BvbnNlRXJyb3IsIFdyYXBwZWRFcnJvciwgQ29udHJvbGxlckVycm9yLCBBdXRob3JpemF0aW9uRXJyb3Jcbn0gZnJvbSAnQC9lcnJvcnMnXG5pbXBvcnQge1xuICBpc09iamVjdCwgaXNTdHJpbmcsIGlzQXJyYXksIGlzQm9vbGVhbiwgaXNGdW5jdGlvbiwgYXNBcnJheSwgZXF1YWxzLFxuICBwYXJzZURhdGFQYXRoLCBub3JtYWxpemVEYXRhUGF0aFxufSBmcm9tICdAZGl0b2pzL3V0aWxzJ1xuXG5leHBvcnQgY2xhc3MgQ29udHJvbGxlciB7XG4gIGNvbnN0cnVjdG9yKGFwcCwgbmFtZXNwYWNlKSB7XG4gICAgdGhpcy5hcHAgPSBhcHBcbiAgICB0aGlzLm5hbWVzcGFjZSA9IHRoaXMubmFtZXNwYWNlIHx8IG5hbWVzcGFjZVxuICAgIHRoaXMubG9nZ2luZyA9IHRoaXMuYXBwLmNvbmZpZy5sb2cucm91dGVzXG4gICAgdGhpcy5sZXZlbCA9IDBcbiAgfVxuXG4gIC8vIEBvdmVycmlkYWJsZVxuICBpbml0aWFsaXplKCkge1xuICB9XG5cbiAgc2V0dXAoaXNSb290ID0gdHJ1ZSwgc2V0dXBBY3Rpb25zT2JqZWN0ID0gdHJ1ZSkge1xuICAgIHRoaXMuX3NldHVwRW1pdHRlcih0aGlzLmhvb2tzLCB7XG4gICAgICAvLyBTdXBwb3J0IHdpbGRjYXJkIGhvb2tzIG9ubHkgb24gY29udHJvbGxlcnM6XG4gICAgICB3aWxkY2FyZDogdHJ1ZVxuICAgIH0pXG4gICAgLy8gSWYgdGhlIGNsYXNzIG5hbWUgZW5kcyBpbiAnQ29udHJvbGxlcicsIHJlbW92ZSBpdCBmcm9tIGNvbnRyb2xsZXIgbmFtZS5cbiAgICB0aGlzLm5hbWUgPSB0aGlzLm5hbWUgfHxcbiAgICAgIHRoaXMuY29uc3RydWN0b3IubmFtZS5tYXRjaCgvXiguKj8pKD86Q29udHJvbGxlcnwpJC8pWzFdXG4gICAgaWYgKHRoaXMucGF0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnBhdGggPSB0aGlzLmFwcC5ub3JtYWxpemVQYXRoKHRoaXMubmFtZSlcbiAgICB9XG4gICAgdGhpcy50cmFuc2FjdGVkID0gISF0aGlzLnRyYW5zYWN0ZWRcbiAgICBpZiAoaXNSb290KSB7XG4gICAgICBjb25zdCB7IHBhdGgsIG5hbWVzcGFjZSB9ID0gdGhpc1xuICAgICAgLy8gVE9ETzogVGhlIGRpc3RpbmN0aW9uIGJldHdlZW4gIGB1cmxgIGFuZCBgcGF0aGAgaXMgYSBiaXQgdHJpY2t5LCBzaW5jZVxuICAgICAgLy8gd2hhdCB3ZSBjYWxsIGB1cmxgIGhlcmUgaXMgY2FsbGVkIGBwYXRoYCBpbiBSb3V0ZXIsIGFuZCBtYXkgY29udGFpblxuICAgICAgLy8gbWFwcGVkIHBhcmFtZXRlcnMgb3Igd2lsZGNhcmRzLiBDb25zaWRlciBgcGF0aGAgLyBgcm91dGVgIGluc3RlYWQ/XG4gICAgICBjb25zdCB1cmwgPSBwYXRoID8gYC8ke3BhdGh9YCA6ICcnXG4gICAgICB0aGlzLnVybCA9IG5hbWVzcGFjZSA/IGAvJHtuYW1lc3BhY2V9JHt1cmx9YCA6IHVybFxuICAgICAgdGhpcy5sb2coXG4gICAgICAgIGAke1xuICAgICAgICAgIG5hbWVzcGFjZSA/IHBpY28uZ3JlZW4oYC8ke25hbWVzcGFjZX0vYCkgOiAnJ1xuICAgICAgICB9JHtcbiAgICAgICAgICBwaWNvLmN5YW4ocGF0aClcbiAgICAgICAgfSR7XG4gICAgICAgICAgcGljby53aGl0ZSgnOicpXG4gICAgICAgIH1gLFxuICAgICAgICB0aGlzLmxldmVsXG4gICAgICApXG4gICAgICBpZiAoc2V0dXBBY3Rpb25zT2JqZWN0KSB7XG4gICAgICAgIHRoaXMuYWN0aW9ucyA9IHRoaXMuYWN0aW9ucyB8fCB0aGlzLnJlZmxlY3RBY3Rpb25zT2JqZWN0KClcbiAgICAgICAgLy8gTm93IHRoYXQgdGhlIGluc3RhbmNlIGZpZWxkcyBhcmUgcmVmbGVjdGVkIGluIHRoZSBgY29udHJvbGxlcmAgb2JqZWN0XG4gICAgICAgIC8vIHdlIGNhbiB1c2UgdGhlIG5vcm1hbCBpbmhlcml0YW5jZSBtZWNoYW5pc20gdGhyb3VnaCBgc2V0dXBBY3Rpb25zKClgOlxuICAgICAgICB0aGlzLmFjdGlvbnMgPSB0aGlzLnNldHVwQWN0aW9ucygnYWN0aW9ucycpXG4gICAgICB9XG4gICAgICB0aGlzLmFzc2V0cyA9IHRoaXMuc2V0dXBBc3NldHMoKVxuICAgIH1cbiAgfVxuXG4gIHJlZmxlY3RBY3Rpb25zT2JqZWN0KCkge1xuICAgIC8vIE9uIGJhc2UgY29udHJvbGxlcnMsIHRoZSBhY3Rpb25zIGNhbiBiZSBkZWZpbmVkIGRpcmVjdGx5IGluIHRoZSBjbGFzc1xuICAgIC8vIGluc3RlYWQgb2YgaW5zaWRlIGFuIGFjdGlvbnMgb2JqZWN0LCBhcyBpcyBkb25lIHdpdGggbW9kZWwgYW5kIHJlbGF0aW9uXG4gICAgLy8gY29udHJvbGxlcnMuIEJ1dCBpbiBvcmRlciB0byB1c2UgdGhlIHNhbWUgc3RydWN0dXJlIGZvciBpbmhlcml0YW5jZSBhc1xuICAgIC8vIHRoZXNlIG90aGVyIGNvbnRyb2xsZXJzLCB3ZSByZWZsZWN0IHRoZXNlIGluc3RhbmNlIGZpZWxkcyBpbiBhIHNlcGFyYXRlXG4gICAgLy8gYGFjdGlvbnNgIG9iamVjdC5cbiAgICBjb25zdCB7IGFsbG93IH0gPSB0aGlzXG4gICAgY29uc3QgY29udHJvbGxlciA9IGFsbG93ID8geyBhbGxvdyB9IDoge31cblxuICAgIGNvbnN0IGFkZEFjdGlvbiA9IGtleSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXNba2V5XVxuICAgICAgLy8gTk9URTogT25seSBhZGQgaW5zdGFuY2UgbWV0aG9kcyB0aGF0IGhhdmUgYSBAYWN0aW9uKCkgZGVjb3JhdG9yLFxuICAgICAgLy8gd2hpY2ggaW4gdHVybiBzZXRzIHRoZSBgdmVyYmAgcHJvcGVydHkgb24gdGhlIG1ldGhvZCwgb3IgYWN0aW9uIG9iamVjdHNcbiAgICAgIC8vIHdoaWNoIGhhdmUgdGhlIGB2ZXJiYCBwcm9wZXJ0eTpcbiAgICAgIGlmICh2YWx1ZT8udmVyYikge1xuICAgICAgICBjb250cm9sbGVyW2tleV0gPSB2YWx1ZVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBVc2UgYE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKClgIHRvIGdldCB0aGUgZmllbGRzLCBpbiBvcmRlciB0b1xuICAgIC8vIG5vdCBhbHNvIHJlY2VpdmUgdmFsdWVzIGZyb20gcGFyZW50cyAodGhvc2UgYXJlIGZldGNoZWQgbGF0ZXIgaW5cbiAgICAvLyBgaW5oZXJpdFZhbHVlcygpYCwgc2VlIGBnZXRQYXJlbnRWYWx1ZXMoKWApLlxuICAgIGNvbnN0IHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpXG4gICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocHJvdG8pLmZvckVhY2goYWRkQWN0aW9uKVxuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMpLmZvckVhY2goYWRkQWN0aW9uKVxuICAgIHJldHVybiBjb250cm9sbGVyXG4gIH1cblxuICBzZXR1cFJvdXRlKHZlcmIsIHVybCwgdHJhbnNhY3RlZCwgYXV0aG9yaXplLCBhY3Rpb24sIGhhbmRsZXJzKSB7XG4gICAgdGhpcy5sb2coXG4gICAgICBgJHtcbiAgICAgICAgcGljby5tYWdlbnRhKHZlcmIudG9VcHBlckNhc2UoKSlcbiAgICAgIH0gJHtcbiAgICAgICAgcGljby5ncmVlbih0aGlzLnVybClcbiAgICAgIH0ke1xuICAgICAgICBwaWNvLmN5YW4odXJsLnNsaWNlKHRoaXMudXJsLmxlbmd0aCkpXG4gICAgICB9ICR7XG4gICAgICAgIHBpY28ud2hpdGUodGhpcy5kZXNjcmliZUF1dGhvcml6ZShhdXRob3JpemUpKVxuICAgICAgfWAsXG4gICAgICB0aGlzLmxldmVsICsgMVxuICAgIClcbiAgICB0aGlzLmFwcC5hZGRSb3V0ZSh2ZXJiLCB1cmwsIHRyYW5zYWN0ZWQsIGhhbmRsZXJzLCB0aGlzLCBhY3Rpb24pXG4gIH1cblxuICBzZXR1cEFjdGlvbnModHlwZSkge1xuICAgIGNvbnN0IHtcbiAgICAgIHZhbHVlczogYWN0aW9ucyxcbiAgICAgIGF1dGhvcml6ZVxuICAgIH0gPSB0aGlzLnByb2Nlc3NWYWx1ZXModGhpcy5pbmhlcml0VmFsdWVzKHR5cGUpKVxuICAgIGZvciAoY29uc3QgW25hbWUsIGhhbmRsZXJdIG9mIE9iamVjdC5lbnRyaWVzKGFjdGlvbnMpKSB7XG4gICAgICB0aGlzLnNldHVwQWN0aW9uKHR5cGUsIGFjdGlvbnMsIG5hbWUsIGhhbmRsZXIsIGF1dGhvcml6ZVtuYW1lXSlcbiAgICB9XG4gICAgcmV0dXJuIGFjdGlvbnNcbiAgfVxuXG4gIHNldHVwQWN0aW9uKFxuICAgIHR5cGUsXG4gICAgYWN0aW9ucyxcbiAgICBuYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgYXV0aG9yaXplLFxuICAgIC8vIFRoZXNlIHZhbHVlcyBhcmUgb25seSBjaGFuZ2VkIHdoZW4gY2FsbGVkIGZyb21cbiAgICAvLyBgQ29sbGVjdGlvbkNvbnRyb2xsZXIuc2V0dXBBY3Rpb24oKWA6XG4gICAgdmVyYiA9ICdnZXQnLFxuICAgIC8vIFRoZSBkZWZhdWx0IHBhdGggZm9yIGFjdGlvbnMgaXMgdGhlIG5vcm1hbGl6ZWQgbmFtZS5cbiAgICBwYXRoID0gdGhpcy5hcHAubm9ybWFsaXplUGF0aChuYW1lKVxuICApIHtcbiAgICBpZiAoIWlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICAgIGhhbmRsZXIgPSBzZXR1cEhhbmRsZXJGcm9tT2JqZWN0KGhhbmRsZXIsIGFjdGlvbnMpXG4gICAgfVxuICAgIC8vIEN1c3RvbSBtZW1iZXIgYWN0aW9ucyBoYXZlIHRoZWlyIG93biBjbGFzcyBzbyB0aGV5IGNhbiBmZXRjaCB0aGUgbWVtYmVyc1xuICAgIC8vIGFoZWFkIG9mIHRoZWlyIGNhbGwuXG4gICAgY29uc3QgYWN0aW9uQ2xhc3MgPSB0eXBlID09PSAnbWVtYmVyJyA/IE1lbWJlckFjdGlvbiA6IENvbnRyb2xsZXJBY3Rpb25cbiAgICB0aGlzLnNldHVwQWN0aW9uUm91dGUoXG4gICAgICB0eXBlLFxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5ldy1jYXBcbiAgICAgIG5ldyBhY3Rpb25DbGFzcyh0aGlzLCBoYW5kbGVyLCB0eXBlLCBuYW1lLCB2ZXJiLCBwYXRoLCBhdXRob3JpemUpXG4gICAgKVxuICB9XG5cbiAgc2V0dXBBY3Rpb25Sb3V0ZSh0eXBlLCBhY3Rpb24pIHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldFVybCh0eXBlLCBhY3Rpb24ucGF0aClcbiAgICBjb25zdCB7IHZlcmIsIHRyYW5zYWN0ZWQsIGF1dGhvcml6ZSB9ID0gYWN0aW9uXG4gICAgdGhpcy5zZXR1cFJvdXRlKHZlcmIsIHVybCwgdHJhbnNhY3RlZCwgYXV0aG9yaXplLCBhY3Rpb24sIFtcbiAgICAgIGFzeW5jIGN0eCA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYWN0aW9uLmNhbGxBY3Rpb24oY3R4KVxuICAgICAgICAgIGlmIChyZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY3R4LmJvZHkgPSByZXNcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIHRocm93IGVyciBpbnN0YW5jZW9mIFJlc3BvbnNlRXJyb3IgPyBlcnIgOiBuZXcgV3JhcHBlZEVycm9yKGVycilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIF0pXG4gIH1cblxuICBzZXR1cEFzc2V0cygpIHtcbiAgICBjb25zdCB7XG4gICAgICB2YWx1ZXM6IGFzc2V0cyxcbiAgICAgIGF1dGhvcml6ZVxuICAgIH0gPSB0aGlzLnByb2Nlc3NWYWx1ZXModGhpcy5pbmhlcml0VmFsdWVzKCdhc3NldHMnKSlcbiAgICBmb3IgKGNvbnN0IFtkYXRhUGF0aCwgY29uZmlnXSBvZiBPYmplY3QuZW50cmllcyhhc3NldHMgfHwge30pKSB7XG4gICAgICB0aGlzLnNldHVwQXNzZXRSb3V0ZShkYXRhUGF0aCwgY29uZmlnLCBhdXRob3JpemVbZGF0YVBhdGhdKVxuICAgIH1cbiAgICByZXR1cm4gYXNzZXRzXG4gIH1cblxuICBzZXR1cEFzc2V0Um91dGUoZGF0YVBhdGgsIGNvbmZpZywgYXV0aG9yaXplKSB7XG4gICAgY29uc3Qge1xuICAgICAgc3RvcmFnZTogc3RvcmFnZU5hbWUsXG4gICAgICAvLyBUT0RPOiBXaGF0IGV4YWN0bHkgc2hvdWxkIGNvbnRyb2wgdGhlIHVzZSBvZiBgdHJhbnNhY3RlZGA/XG4gICAgICB0cmFuc2FjdGVkLFxuICAgICAgLi4uc2V0dGluZ3NcbiAgICB9ID0gY29uZmlnXG4gICAgY29uc3Qgc3RvcmFnZSA9IHRoaXMuYXBwLmdldFN0b3JhZ2Uoc3RvcmFnZU5hbWUpXG4gICAgaWYgKCFzdG9yYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgQ29udHJvbGxlckVycm9yKHRoaXMsXG4gICAgICAgIGBVbmtub3duIHN0b3JhZ2UgY29uZmlndXJhdGlvbjogJyR7c3RvcmFnZU5hbWV9J2BcbiAgICAgIClcbiAgICB9XG4gICAgY29uc3QgdG9rZW5zID0gcGFyc2VEYXRhUGF0aChkYXRhUGF0aClcbiAgICBjb25zdCBnZXREYXRhUGF0aCA9IGNhbGxiYWNrID0+IG5vcm1hbGl6ZURhdGFQYXRoKHRva2Vucy5tYXAoY2FsbGJhY2spKVxuXG4gICAgLy8gUmVwbGFjZSB3aWxkY2FyZHMgd2l0aCBudW1iZXJlZCBpbmRpY2VzIGFuZCBjb252ZXJ0IHRvICcvJy1ub3RhdGlvbjpcbiAgICBsZXQgaW5kZXggPSAwXG4gICAgY29uc3QgbXVsdGlwbGVXaWxkY2FyZHMgPSB0b2tlbnMuZmlsdGVyKHRva2VuID0+IHRva2VuID09PSAnKicpLmxlbmd0aCA+IDFcbiAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IGdldERhdGFQYXRoKFxuICAgICAgdG9rZW4gPT4gdG9rZW4gPT09ICcqJ1xuICAgICAgICA/IG11bHRpcGxlV2lsZGNhcmRzXG4gICAgICAgICAgPyBgOmluZGV4JHsrK2luZGV4fWBcbiAgICAgICAgICA6ICc6aW5kZXgnXG4gICAgICAgIDogdGhpcy5hcHAubm9ybWFsaXplUGF0aCh0b2tlbilcbiAgICApXG5cbiAgICAvLyBDb252ZXJ0IGBkYXRhUGF0aGAgdG8gYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWF0Y2ggZmllbGQgbmFtZXNcbiAgICAvLyBhZ2FpbnN0LCBidXQgY29udmVydCB3aWxkY2FyZHMgKCopIHRvIG1hdGNoIGJvdGggbnVtZXJpYyBpZHMgYW5kIHdvcmRzLFxuICAgIC8vIGUuZy4gJ2NyZWF0ZSc6XG4gICAgY29uc3QgbWF0Y2hEYXRhUGF0aCA9IG5ldyBSZWdFeHAoXG4gICAgICBgXiR7Z2V0RGF0YVBhdGgodG9rZW4gPT4gdG9rZW4gPT09ICcqJyA/ICdcXFxcdysnIDogdG9rZW4pfSRgXG4gICAgKVxuXG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRVcmwoJ2NvbnRyb2xsZXInLCBgdXBsb2FkLyR7bm9ybWFsaXplZFBhdGh9YClcbiAgICBjb25zdCB1cGxvYWQgPSBzdG9yYWdlLmdldFVwbG9hZEhhbmRsZXIoe1xuICAgICAgLi4uc2V0dGluZ3MsXG4gICAgICAvLyBPbmx5IGxldCB1cGxvYWRzIHBhc3MgdGhhdCBtYXRjaCB0aGUgbm9ybWFsaXplUGF0aCArIHdpbGRjYXJkczpcbiAgICAgIGZpbGVGaWx0ZXI6IChyZXEsIGZpbGUsIGNiKSA9PiB7XG4gICAgICAgIGNiKG51bGwsIG1hdGNoRGF0YVBhdGgudGVzdChmaWxlLmZpZWxkbmFtZSkpXG4gICAgICB9XG4gICAgfSlcblxuICAgIGNvbnN0IGF1dGhvcml6YXRpb24gPSB0aGlzLnByb2Nlc3NBdXRob3JpemUoYXV0aG9yaXplKVxuICAgIHRoaXMuc2V0dXBSb3V0ZSgncG9zdCcsIHVybCwgdHJhbnNhY3RlZCwgYXV0aG9yaXplLCBudWxsLCBbXG4gICAgICBhc3luYyAoY3R4LCBuZXh0KSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQXV0aG9yaXphdGlvbihhdXRob3JpemF0aW9uLCBjdHgpXG4gICAgICAgIHJldHVybiBuZXh0KClcbiAgICAgIH0sXG5cbiAgICAgIHVwbG9hZCxcblxuICAgICAgYXN5bmMgKGN0eCwgbmV4dCkgPT4ge1xuICAgICAgICBjb25zdCBmaWxlcyA9IHN0b3JhZ2UuY29udmVydFN0b3JhZ2VGaWxlcyhjdHgucmVxdWVzdC5maWxlcylcbiAgICAgICAgYXdhaXQgdGhpcy5hcHAuY3JlYXRlQXNzZXRzKHN0b3JhZ2UsIGZpbGVzLCAwLCBjdHgudHJhbnNhY3Rpb24pXG4gICAgICAgIC8vIFNlbmQgdGhlIGZpbGUgb2JqZWN0cyBiYWNrIGZvciB0aGUgdXBsb2FkIGNvbXBvbmVudCB0byBzdG9yZSBpbiB0aGVcbiAgICAgICAgLy8gZGF0YS5cbiAgICAgICAgY3R4LmJvZHkgPSBmaWxlc1xuICAgICAgICByZXR1cm4gbmV4dCgpXG4gICAgICB9XG4gICAgXSlcbiAgfVxuXG4gIGNvbXBvc2UoKSB7XG4gICAgLy8gVG8gYmUgb3ZlcnJpZGRlbiBpbiBzdWItY2xhc3NlcywgaWYgdGhlIGNvbnRyb2xsZXIgbmVlZHMgdG8gaW5zdGFsbFxuICAgIC8vIG1pZGRsZXdhcmUuIEZvciBub3JtYWwgcm91dGVzLCB1c2UgYHRoaXMuYXBwLmFkZFJvdXRlKClgIGluc3RlYWQuXG4gIH1cblxuICBnZXRQYXRoKHR5cGUsIHBhdGgpIHtcbiAgICAvLyBUbyBiZSBvdmVycmlkZGVuIGJ5IHN1Yi1jbGFzc2VzLlxuICAgIHJldHVybiBwYXRoXG4gIH1cblxuICBnZXRVcmwodHlwZSwgcGF0aCkge1xuICAgIHBhdGggPSB0aGlzLmdldFBhdGgodHlwZSwgcGF0aClcbiAgICAvLyBVc2UgJy4nIGFzIHRoZSBwYXRoIGZvciB0aGUgY29udHJvbGxlcidzIFwiaW5kZXhcIiBhY3Rpb24uXG4gICAgcmV0dXJuIHBhdGggJiYgcGF0aCAhPT0gJy4nID8gYCR7dGhpcy51cmx9LyR7cGF0aH1gIDogdGhpcy51cmxcbiAgfVxuXG4gIGluaGVyaXRWYWx1ZXModHlwZSkge1xuICAgIC8vIEdldHMgdGhlIGNvbnRyb2xsZXIgY2xhc3MncyBpbnN0YW5jZSBmaWVsZCBmb3IgYSBnaXZlbiBhY3Rpb24gdHlwZSwgZS5nLlxuICAgIC8vIGBjb250cm9sbGVyYCAoQ29udHJvbGxlciksIGBjb2xsZWN0aW9uYCwgYG1lbWJlcmAgKE1vZGVsQ29udHJvbGxlcixcbiAgICAvLyBSZWxhdGlvbkNvbnRyb2xsZXIpLCBgcmVsYXRpb25gIChSZWxhdGlvbkNvbnRyb2xsZXIpLCBhbmQgc2V0cyB1cCBhblxuICAgIC8vIGluaGVyaXRhbmNlIGNoYWluIGZvciBpdCB0aGF0IGdvZXMgYWxsIHRoZSB3YXkgdXAgdG8gaXQgYmFzZSBjbGFzcyAoZS5nLlxuICAgIC8vIENvbGxlY3Rpb25Db250cm9sbGVyKSwgc28gdGhhdCB0aGUgZGVmYXVsdCBkZWZpbml0aW9ucyBmb3IgYWxsIGh0dHAgdmVyYnNcbiAgICAvLyBjYW4gYmUgY29ycmVjdGx5IGluaGVyaXRlZCBhbmQgb3ZlcnJpZGRlbiB3aGlsZSB1c2luZyBgc3VwZXIuPGFjdGlvbj4oKWAuXG4gICAgY29uc3QgcGFyZW50Q2xhc3MgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcy5jb25zdHJ1Y3RvcilcbiAgICAvLyBDcmVhdGUgb25lIGluc3RhbmNlIG9mIGVhY2ggY29udHJvbGxlciBjbGFzcyB1cCB0aGUgY2hhaW4gaW4gb3JkZXIgdG9cbiAgICAvLyBnZXQgdG8gdGhlaXIgZGVmaW5pdGlvbnMgb2YgdGhlIGluaGVyaXRhYmxlIHZhbHVlcy4gQ2FjaGUgYm90aCBpbnN0YW5jZVxuICAgIC8vIGFuZCByZXNvbHZlZCB2YWx1ZXMgcGVyIHBhcmVudENsYXNzIGluIGFuIGluaGVyaXRhbmNlTWFwLlxuICAgIGlmICghaW5oZXJpdGFuY2VNYXAuaGFzKHBhcmVudENsYXNzKSkge1xuICAgICAgaW5oZXJpdGFuY2VNYXAuc2V0KHBhcmVudENsYXNzLCB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuZXctY2FwXG4gICAgICAgIGluc3RhbmNlOiBuZXcgcGFyZW50Q2xhc3ModGhpcy5hcHAsIHRoaXMubmFtZXNwYWNlKVxuICAgICAgfSlcbiAgICB9XG4gICAgY29uc3QgZW50cnkgPSBpbmhlcml0YW5jZU1hcC5nZXQocGFyZW50Q2xhc3MpXG4gICAgaWYgKCFlbnRyeVt0eXBlXSkge1xuICAgICAgY29uc3QgcGFyZW50ID0gZW50cnkuaW5zdGFuY2VcbiAgICAgIGxldCB2YWx1ZXMgPSBwYXJlbnRbdHlwZV1cbiAgICAgIGlmIChwYXJlbnRDbGFzcyAhPT0gQ29udHJvbGxlcikge1xuICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXQgdXAgaW5oZXJpdGFuY2UgY2hhaW5zLlxuICAgICAgICB2YWx1ZXMgPSBwYXJlbnQuaW5oZXJpdFZhbHVlcyh0eXBlKVxuICAgICAgfVxuICAgICAgZW50cnlbdHlwZV0gPSB2YWx1ZXNcbiAgICB9XG4gICAgLy8gSWYgdGhlcmUgYXJlIG5vIHZhbHVlcyBkZWZpbmVkIG9uIGB0aGlzYCB0aGF0IGRpZmZlciBmcm9tIHRoZSBwYXJlbnQsXG4gICAgLy8gc2V0IHRvIGFuIGVtcHR5IG9iamVjdCBzbyBpbmhlcml0YW5jZSBjYW4gYmUgc2V0IHVwIGFuZCBgcHJvY2Vzc1ZhbHVlcygpYFxuICAgIC8vIGNhbiBzdGlsbCBiZSBjYWxsZWQuXG4gICAgLy8gTk9URTogV2UgY2FuJ3QgY2hlY2sgd2l0aCBgdGhpcy5oYXNPd25Qcm9wZXJ0eSh0eXBlKWAgYmVjYXVzZSB0aGVcbiAgICAvLyBmaWVsZCBjYW4gYmUgb24gdGhlIGNsYXNzIHByb3RvdHlwZSBhcyB3ZWxsLCBpbiBjYXNlIG9mIGFjY2Vzc29ycy5cbiAgICBjb25zdCBwYXJlbnRWYWx1ZXMgPSBlbnRyeVt0eXBlXVxuICAgIGxldCBjdXJyZW50VmFsdWVzID0gdGhpc1t0eXBlXVxuICAgIGlmIChjdXJyZW50VmFsdWVzICYmIGN1cnJlbnRWYWx1ZXMgPT09IHBhcmVudFZhbHVlcykge1xuICAgICAgY3VycmVudFZhbHVlcyA9IHRoaXNbdHlwZV0gPSB7fVxuICAgIH1cbiAgICAvLyBDb21iaW5lIHBhcmVudFZhbHVlcyBhbmQgY3VycmVudFZhbHVlcyB3aXRoIGNvcnJlY3QgaW5oZXJpdGFuY2UuXG4gICAgcmV0dXJuIGlzT2JqZWN0KHBhcmVudFZhbHVlcykgJiYgaXNPYmplY3QoY3VycmVudFZhbHVlcylcbiAgICAgID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKGN1cnJlbnRWYWx1ZXMsIHBhcmVudFZhbHVlcylcbiAgICAgIDogY3VycmVudFZhbHVlc1xuICB9XG5cbiAgcHJvY2Vzc1ZhbHVlcyh2YWx1ZXMpIHtcbiAgICBpZiAoIXZhbHVlcykgcmV0dXJuIHt9XG4gICAgLy8gUmVzcGVjdCBgYWxsb3dgIHNldHRpbmdzIGFuZCBjbGVhciBlbnRyaWVzIHRoYXQgYXJlbid0IGFsbG93ZWQuXG4gICAgLy8gQWxzbyBjb2xsZWN0IGFuZCBleHBhbmQgYGF1dGhvcml6ZWAgc2V0dGluZ3Mgc28gdGhhdCBpbiB0aGUgZW5kLCBhblxuICAgIC8vIGBhdXRob3JpemVgIG9iamVjdCBjYW4gYmUgcmV0dXJuZWQgd2l0aCB2YWxpZCBzZXR0aW5ncyBmb3IgYWxsIHZhbHVlcy5cbiAgICAvL1xuICAgIC8vIFJ1bGVzOlxuICAgIC8vIC0gT3duIHZhbHVlcyBvbiBvYmplY3RzIHRoYXQgZG9uJ3QgZGVmaW5lIGFuIGBhbGxvd2AgYXJyYXkgYXJlXG4gICAgLy8gICBhdXRvbWF0aWNhbGx5IGFsbG93ZWQuIElmIGFuIGBhbGxvd2AgYXJyYXkgaXMgZGVmaW5lZCBhcyB3ZWxsLCB0aGVuXG4gICAgLy8gICB0aGVzZSBvd24gdmFsdWVzIG5lZWQgdG8gYmUgZXhwbGljaXRseSBsaXN0ZWQuXG4gICAgLy8gLSBJZiBubyBgYWxsb3dgIGFycmF5cyBhcmUgZGVmaW5lZCBpbiB0aGUgcHJvdG90eXBhbCBoaWVyYXJjaHksIGVhY2hcbiAgICAvLyAgIGxldmVsIGFsbG93cyBpdHMgb3duIHZhbHVlcywgYW5kIHRoZXNlIGFyZSBtZXJnZWQsIGV4Y2VwdCBmb3IgdGhvc2VcbiAgICAvLyAgIG1hcmtlZCBhcyBgJGNvcmVgLCB3aGljaCBuZWVkIHRvIGJlIGV4cGxpY2l0bHkgbGlzdGVkIGluIGBhbGxvd2AuXG5cbiAgICAvLyBOT1RFOiBgaGFuZGxlQWxsb3coKWAgYW5kIGBoYW5kbGVBdXRob3JpemUoKWAgYXJlIGFwcGxpZWQgaW4gc2VxdWVuY2Ugb2ZcbiAgICAvLyB0aGUgYHZhbHVlc2AgaW5oZXJpdGFuY2UsIGZyb20gc3ViLWNsYXNzIHRvIGJhc2UtY2xhc3MuXG5cbiAgICBjb25zdCBtZXJnZWRBbGxvdyA9IHt9XG4gICAgY29uc3QgbWVyZ2VkQXV0aG9yaXplID0ge31cbiAgICBsZXQgaGFzT3duQWxsb3cgPSBmYWxzZVxuXG4gICAgY29uc3QgZXhjbHVkZUtleSA9IGtleSA9PiBbJ2FsbG93JywgJ2F1dGhvcml6ZSddLmluY2x1ZGVzKGtleSlcblxuICAgIGNvbnN0IGhhbmRsZUFsbG93ID0gKGFsbG93LCBjdXJyZW50KSA9PiB7XG4gICAgICBpZiAoYWxsb3cpIHtcbiAgICAgICAgYWxsb3cgPSBhc0FycmF5KGFsbG93KVxuICAgICAgICBoYXNPd25BbGxvdyA9IHRydWVcbiAgICAgIH0gZWxzZSBpZiAoIWhhc093bkFsbG93KSB7XG4gICAgICAgIC8vIE9ubHkga2VlcCBhZGRpbmcgdG8gdGhlIG1lcmdlZCBgYWxsb3dgIGlmIHdlIGRpZG4ndCBhbHJlYWR5IGVuY291bnRlclxuICAgICAgICAvLyBhbiBvd24gYGFsbG93YCBvYmplY3QgZnVydGhlciB1cCB0aGUgY2hhaW4uXG4gICAgICAgIGFsbG93ID0gT2JqZWN0LmtleXMoY3VycmVudClcbiAgICAgIH1cbiAgICAgIGlmIChhbGxvdykge1xuICAgICAgICBpZiAoYWxsb3cuaW5jbHVkZXMoJyonKSkge1xuICAgICAgICAgIGFsbG93ID0gZ2V0QWxsS2V5cyhjdXJyZW50KVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGFsbG93KSB7XG4gICAgICAgICAgaWYgKCFleGNsdWRlS2V5KGtleSkpIHtcbiAgICAgICAgICAgIG1lcmdlZEFsbG93W2tleV0gPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaGFuZGxlQXV0aG9yaXplID0gYXV0aG9yaXplID0+IHtcbiAgICAgIGNvbnN0IGFkZCA9IChrZXksIHZhbHVlKSA9PiB7XG4gICAgICAgIC8vIFNpbmNlIHdlJ3JlIHdhbGtpbmcgdXAgaW4gdGhlIGluaGVyaXRhbmNlIGNoYWluLCBvbmx5IHRha2Ugb24gYW5cbiAgICAgICAgLy8gYXV0aG9yaXplIHNldHRpbmcgZm9yIGEgZ2l2ZW4ga2V5IGlmIGl0IHdhc24ndCBhbHJlYWR5IGRlZmluZWQgYmVmb3JlXG4gICAgICAgIGlmIChcbiAgICAgICAgICBrZXkgaW4gdmFsdWVzICYmXG4gICAgICAgICAgIShrZXkgaW4gbWVyZ2VkQXV0aG9yaXplKSAmJlxuICAgICAgICAgICFleGNsdWRlS2V5KGtleSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgbWVyZ2VkQXV0aG9yaXplW2tleV0gPSB2YWx1ZVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChpc09iamVjdChhdXRob3JpemUpKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGF1dGhvcml6ZSkge1xuICAgICAgICAgIGFkZChrZXksIGF1dGhvcml6ZVtrZXldKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGF1dGhvcml6ZSAhPSBudWxsKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgYSB2YWx1ZXMtd2lkZSBzZXR0aW5nLiBMb29wIHRocm91Z2ggYWxsIHZhbHVlcywgbm90IGp1c3RcbiAgICAgICAgLy8gY3VycmVudCBvbmVzLCBhbmQgYXBwbHkgdG8gYW55IGFjdGlvbiB0aGF0IGRvZXNuJ3QgYWxyZWFkeSBoYXZlIG9uZTpcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdmFsdWVzKSB7XG4gICAgICAgICAgYWRkKGtleSwgYXV0aG9yaXplKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUHJvY2VzcyB0aGUgYGFsbG93YCBhbmQgYGF1dGhvcml6ZWAgc2V0dGluZ3MgaW4gc2VxdWVuY2Ugb2YgdGhlIGB2YWx1ZXNgXG4gICAgLy8gaW5oZXJpdGFuY2UsIGZyb20gc3ViLWNsYXNzIHRvIGJhc2UtY2xhc3MuXG4gICAgbGV0IGN1cnJlbnQgPSB2YWx1ZXNcbiAgICB3aGlsZSAoY3VycmVudCAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiAhY3VycmVudC5oYXNPd25Qcm9wZXJ0eSgnJGNvcmUnKSkge1xuICAgICAgaGFuZGxlQWxsb3coZ2V0T3duUHJvcGVydHkoY3VycmVudCwgJ2FsbG93JyksIGN1cnJlbnQpXG4gICAgICBoYW5kbGVBdXRob3JpemUoZ2V0T3duUHJvcGVydHkoY3VycmVudCwgJ2F1dGhvcml6ZScpKVxuICAgICAgY3VycmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihjdXJyZW50KVxuICAgIH1cblxuICAgIC8vIEF0IHRoZSBlbmQgb2YgdGhlIGNoYWluLCBhbHNvIHN1cHBvcnQgYm90aCBzZXR0aW5ncyBvbiB0aGUgY29udHJvbGxlci1cbiAgICAvLyBsZXZlbCwgYW5kIHRodXMgYXBwbGllZCB0byBhbGwgYWN0aW9uIG9iamVjdHMgaW4gdGhlIGNvbnRyb2xsZXIuXG4gICAgaWYgKHRoaXMuYWxsb3cpIHtcbiAgICAgIGhhbmRsZUFsbG93KHRoaXMuYWxsb3csIHZhbHVlcylcbiAgICB9XG4gICAgaWYgKHRoaXMuYXV0aG9yaXplKSB7XG4gICAgICBoYW5kbGVBdXRob3JpemUodGhpcy5hdXRob3JpemUpXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIENyZWF0ZSBhIGZpbHRlcmVkIGB2YWx1ZXNgIG9iamVjdCB0aGF0IG9ubHkgY29udGFpbnMgdGhlIGFsbG93ZWQgZmllbGRzXG4gICAgICB2YWx1ZXM6IGdldEFsbEtleXModmFsdWVzKS5yZWR1Y2UoXG4gICAgICAgIChyZXN1bHQsIGtleSkgPT4ge1xuICAgICAgICAgIGlmIChtZXJnZWRBbGxvd1trZXldKSB7XG4gICAgICAgICAgICByZXN1bHRba2V5XSA9IHZhbHVlc1trZXldXG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgfSxcbiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IG9iamVjdCBmb3IgdGhlIGZpbHRlcmVkIGB2YWx1ZXNgIHRoYXQga2VlcHMgaW5oZXJpdGFuY2VcbiAgICAgICAgLy8gaW50YWN0LiBUaGlzIGlzIHJlcXVpcmVkIGJ5IGBzZXR1cEhhbmRsZXJGcm9tT2JqZWN0KClgLCB0byBzdXBwb3J0XG4gICAgICAgIC8vIGBzdXBlcmAgaW4gaGFuZGxlciBmdW5jdGlvbnMuXG4gICAgICAgIE9iamVjdC5jcmVhdGUoT2JqZWN0LmdldFByb3RvdHlwZU9mKHZhbHVlcykpXG4gICAgICApLFxuICAgICAgYWxsb3c6IE9iamVjdC5rZXlzKG1lcmdlZEFsbG93KSxcbiAgICAgIGF1dGhvcml6ZTogbWVyZ2VkQXV0aG9yaXplXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZW1pdEhvb2sodHlwZSwgaGFuZGxlUmVzdWx0LCBjdHgsIC4uLmFyZ3MpIHtcbiAgICBsZXQgcmVzdWx0ID0gaGFuZGxlUmVzdWx0ID8gYXJncy5zaGlmdCgpIDogdW5kZWZpbmVkXG4gICAgZm9yIChjb25zdCBoYW5kbGVyIG9mIHRoaXMubGlzdGVuZXJzKHR5cGUpKSB7XG4gICAgICBpZiAoaGFuZGxlUmVzdWx0KSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGhhbmRsZXIuY2FsbCh0aGlzLCBjdHgsIHJlc3VsdCwgLi4uYXJncylcbiAgICAgICAgaWYgKHJlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmVzdWx0ID0gcmVzXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IGhhbmRsZXIuY2FsbCh0aGlzLCBjdHgsIC4uLmFyZ3MpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIGFzeW5jIGdldE1lbWJlcigvKiBjdHgsIGJhc2UgPSB0aGlzLCBwYXJhbSA9IHsgLi4uIH0gKi8pIHtcbiAgICAvLyBUaGlzIGlzIG9ubHkgZGVmaW5lZCBpbiBgQ29sbGVjdGlvbkNvbnRyb2xsZXJgLCB3aGVyZSBpdCByZXNvbHZlcyB0byB0aGVcbiAgICAvLyBtZW1iZXIgcmVwcmVzZW50ZWQgYnkgdGhlIGdpdmVuIHJvdXRlLlxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIGF1dGhvcml6ZSBjb25maWcgc2V0dGluZ3MgaW50byBhbiBhdXRob3JpemF0aW9uIGZ1bmN0aW9uIHRoYXRcbiAgICogY2FuIGJlIHBhc3NlZCB0byBgaGFuZGxlQXV0aG9yaXphdGlvbigpYC5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufGZ1bmN0aW9ufHN0cmluZ3xzdHJpbmdbXX0gYXV0aG9yaXplIHRoZSBhdXRob3JpemUgY29uZmlnXG4gICAqIHNldHRpbmdzXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9ufSB0aGUgYXV0aG9yaXphdGlvbiBmdW5jdGlvblxuICAgKi9cbiAgcHJvY2Vzc0F1dGhvcml6ZShhdXRob3JpemUpIHtcbiAgICBpZiAoYXV0aG9yaXplID09IG51bGwpIHtcbiAgICAgIHJldHVybiAoKSA9PiB0cnVlXG4gICAgfSBlbHNlIGlmIChpc0Jvb2xlYW4oYXV0aG9yaXplKSkge1xuICAgICAgcmV0dXJuICgpID0+IGF1dGhvcml6ZVxuICAgIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihhdXRob3JpemUpKSB7XG4gICAgICByZXR1cm4gYXN5bmMgKGN0eCwgbWVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGF1dGhvcml6ZShjdHgsIG1lbWJlcilcbiAgICAgICAgLy8gUGFzcyByZXMgdGhyb3VnaCBgcHJvY2Vzc0F1dGhvcml6ZSgpYCB0byBzdXBwb3J0IHN0cmluZ3MgJiBhcnJheXMuXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NBdXRob3JpemUocmVzKShjdHgsIG1lbWJlcilcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzU3RyaW5nKGF1dGhvcml6ZSkgfHwgaXNBcnJheShhdXRob3JpemUpKSB7XG4gICAgICByZXR1cm4gYXN5bmMgKGN0eCwgbWVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgdXNlciB9ID0gY3R4LnN0YXRlXG4gICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IGFzQXJyYXkoYXV0aG9yaXplKVxuICAgICAgICAvLyBGb3IgJyRvd25lcicsIGZldGNoIGBtZW1iZXJgIG5vdyBpbiBjYXNlIHRoZSBhY3Rpb24gcGFyYW1ldGVyc1xuICAgICAgICAvLyBkaWRuJ3QgYWxyZWFkeSByZXF1ZXN0IGl0OlxuICAgICAgICBpZiAoIW1lbWJlciAmJiB2YWx1ZXMuaW5jbHVkZXMoJyRvd25lcicpKSB7XG4gICAgICAgICAgbWVtYmVyID0gYXdhaXQgdGhpcy5nZXRNZW1iZXIoY3R4KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXZhbHVlcy5maW5kKFxuICAgICAgICAvLyBTdXBwb3J0IDMgc2NlbmFyaW9zOlxuICAgICAgICAvLyAtICckc2VsZic6IFRoZSByZXF1ZXN0ZWQgbWVtYmVyIGlzIGNoZWNrZWQgYWdhaW5zdCBgY3R4LnN0YXRlLnVzZXJgXG4gICAgICAgIC8vICAgYW5kIHRoZSBhY3Rpb24gaXMgb25seSBhdXRob3JpemVkIGlmIGl0IG1hdGNoZXMgdGhlIG1lbWJlci5cbiAgICAgICAgLy8gLSAnJG93bmVyJzogVGhlIG1lbWJlciBpcyBhc2tlZCBpZiBpdCBpcyBvd25lZCBieSBgY3R4LnN0YXRlLnVzZXJgXG4gICAgICAgIC8vICAgdGhyb3VnaCB0aGUgb3B0aW9uYWwgYE1vZGVsLiRoYXNPd25lcigpYCBtZXRob2QuXG4gICAgICAgIC8vIC0gYW55IHN0cmluZzogIGBjdHguc3RhdGUudXNlcmAgaXMgY2hlY2tlZCBmb3IgdGhpcyByb2xlIHRocm91Z2hcbiAgICAgICAgLy8gICB0aGUgb3ZlcnJpZGFibGUgYFVzZXJNb2RlbC5oYXNSb2xlKClgIG1ldGhvZC5cbiAgICAgICAgICB2YWx1ZSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgPT09ICckc2VsZidcbiAgICAgICAgICAgICAgPyB1c2VyLmNvbnN0cnVjdG9yID09PSB0aGlzLm1vZGVsQ2xhc3MgJiZcbiAgICAgICAgICAgICAgZXF1YWxzKHVzZXIuJGlkKCksIGN0eC5tZW1iZXJJZClcbiAgICAgICAgICAgICAgOiB2YWx1ZSA9PT0gJyRvd25lcidcbiAgICAgICAgICAgICAgICA/IG1lbWJlcj8uJGhhc093bmVyPy4odXNlcilcbiAgICAgICAgICAgICAgICA6IHVzZXIuJGhhc1JvbGUodmFsdWUpXG4gICAgICAgICAgfVxuICAgICAgICApXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBDb250cm9sbGVyRXJyb3IodGhpcyxcbiAgICAgICAgYFVuc3VwcG9ydGVkIGF1dGhvcml6ZSBzZXR0aW5nOiAnJHthdXRob3JpemV9J2BcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICBkZXNjcmliZUF1dGhvcml6ZShhdXRob3JpemUpIHtcbiAgICByZXR1cm4gaXNGdW5jdGlvbihhdXRob3JpemUpXG4gICAgICA/IGRlc2NyaWJlRnVuY3Rpb24oYXV0aG9yaXplKVxuICAgICAgOiBpc1N0cmluZyhhdXRob3JpemUpXG4gICAgICAgID8gYCcke2F1dGhvcml6ZX0nYFxuICAgICAgICA6IGlzQXJyYXkoYXV0aG9yaXplKVxuICAgICAgICAgID8gYFske2F1dGhvcml6ZS5tYXAodmFsdWUgPT4gYCcke3ZhbHVlfSdgKS5qb2luKCcsICcpfV1gXG4gICAgICAgICAgOiAnJ1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQXV0aG9yaXphdGlvbihhdXRob3JpemF0aW9uLCBjdHgsIG1lbWJlcikge1xuICAgIGNvbnN0IG9rID0gYXdhaXQgYXV0aG9yaXphdGlvbihjdHgsIG1lbWJlcilcbiAgICBpZiAob2sgIT09IHRydWUpIHtcbiAgICAgIHRocm93IG5ldyBBdXRob3JpemF0aW9uRXJyb3IoKVxuICAgIH1cbiAgfVxuXG4gIGxvZyhzdHIsIGluZGVudCA9IDApIHtcbiAgICBpZiAodGhpcy5sb2dnaW5nKSB7XG4gICAgICBjb25zb2xlLmluZm8oYCR7JyAgJy5yZXBlYXQoaW5kZW50KX0ke3N0cn1gKVxuICAgIH1cbiAgfVxufVxuXG5FdmVudEVtaXR0ZXIubWl4aW4oQ29udHJvbGxlci5wcm90b3R5cGUpXG5cbmNvbnN0IGluaGVyaXRhbmNlTWFwID0gbmV3IFdlYWtNYXAoKVxuXG5mdW5jdGlvbiBzZXR1cEhhbmRsZXJGcm9tT2JqZWN0KG9iamVjdCwgYWN0aW9ucykge1xuICBjb25zdCB7XG4gICAgaGFuZGxlcixcbiAgICBhY3Rpb24sXG4gICAgYXV0aG9yaXplLFxuICAgIHBhcmFtZXRlcnMsXG4gICAgcmV0dXJucyxcbiAgICBzY29wZSxcbiAgICB0cmFuc2FjdGVkXG4gIH0gPSBvYmplY3RcblxuICAvLyBJbiBvcmRlciB0byBzdXBvcnQgYHN1cGVyYCBjYWxscyBpbiB0aGUgYGhhbmRsZXJgIGZ1bmN0aW9uIGluIG9iamVjdFxuICAvLyBub3RhdGlvbiwgZGVwbG95IHRoaXMgY3JhenkgSlMgc29yY2VyeTpcbiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG9iamVjdCwgT2JqZWN0LmdldFByb3RvdHlwZU9mKGFjdGlvbnMpKVxuXG4gIGhhbmRsZXIuYXV0aG9yaXplID0gYXV0aG9yaXplXG4gIGhhbmRsZXIudHJhbnNhY3RlZCA9IHRyYW5zYWN0ZWRcblxuICBpZiAoYWN0aW9uKSB7XG4gICAgY29uc3QgW3ZlcmIsIHBhdGhdID0gYXNBcnJheShhY3Rpb24pXG4gICAgaGFuZGxlci52ZXJiID0gdmVyYlxuICAgIGhhbmRsZXIucGF0aCA9IHBhdGhcbiAgfVxuXG4gIGlmIChwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgW19wYXJhbWV0ZXJzLCBvcHRpb25zXSA9IHBhcmFtZXRlcnNcbiAgICBjb25zdCBoYXNPcHRpb25zID0gaXNBcnJheShfcGFyYW1ldGVycylcbiAgICBoYW5kbGVyLnBhcmFtZXRlcnMgPSBoYXNPcHRpb25zID8gX3BhcmFtZXRlcnMgOiBwYXJhbWV0ZXJzXG5cbiAgICAvLyBJZiB2YWxpZGF0aW9uIG9wdGlvbnMgYXJlIHByb3ZpZGVkLCBleHBvc2UgdGhlbSB0aHJvdWdoXG4gICAgLy8gYGhhbmRsZXIub3B0aW9ucy5wYXJhbWV0ZXJzYCwgc2VlIENvbnRyb2xsZXJBY3Rpb25cbiAgICBpZiAoaGFzT3B0aW9ucykge1xuICAgICAgaGFuZGxlci5vcHRpb25zID0ge1xuICAgICAgICAuLi5oYW5kbGVyLm9wdGlvbnMsXG4gICAgICAgIHBhcmFtZXRlcnM6IG9wdGlvbnNcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAocmV0dXJucykge1xuICAgIGNvbnN0IFtfcmV0dXJucywgb3B0aW9uc10gPSBhc0FycmF5KHJldHVybnMpXG4gICAgaGFuZGxlci5yZXR1cm5zID0gX3JldHVybnNcblxuICAgIC8vIElmIHZhbGlkYXRpb24gb3B0aW9ucyBhcmUgcHJvdmlkZWQsIGV4cG9zZSB0aGVtIHRocm91Z2hcbiAgICAvLyBgaGFuZGxlci5vcHRpb25zLnJldHVybnNgLCBzZWUgQ29udHJvbGxlckFjdGlvblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBoYW5kbGVyLm9wdGlvbnMgPSB7XG4gICAgICAgIC4uLmhhbmRsZXIub3B0aW9ucyxcbiAgICAgICAgcGFyYW1ldGVyczogb3B0aW9uc1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChzY29wZSkge1xuICAgIGhhbmRsZXIuc2NvcGUgPSBhc0FycmF5KHNjb3BlKVxuICB9XG5cbiAgcmV0dXJuIGhhbmRsZXJcbn1cbiJdfQ==