parse-server 2.8.4 → 8.6.2

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 (240) hide show
  1. package/LICENSE +167 -25
  2. package/NOTICE +10 -0
  3. package/README.md +929 -278
  4. package/lib/AccountLockout.js +47 -30
  5. package/lib/Adapters/AdapterLoader.js +21 -6
  6. package/lib/Adapters/Analytics/AnalyticsAdapter.js +15 -12
  7. package/lib/Adapters/Auth/AuthAdapter.js +116 -13
  8. package/lib/Adapters/Auth/BaseCodeAuthAdapter.js +99 -0
  9. package/lib/Adapters/Auth/OAuth1Client.js +27 -46
  10. package/lib/Adapters/Auth/apple.js +123 -0
  11. package/lib/Adapters/Auth/facebook.js +162 -35
  12. package/lib/Adapters/Auth/gcenter.js +217 -0
  13. package/lib/Adapters/Auth/github.js +118 -48
  14. package/lib/Adapters/Auth/google.js +160 -51
  15. package/lib/Adapters/Auth/gpgames.js +125 -0
  16. package/lib/Adapters/Auth/httpsRequest.js +6 -7
  17. package/lib/Adapters/Auth/index.js +170 -62
  18. package/lib/Adapters/Auth/instagram.js +114 -40
  19. package/lib/Adapters/Auth/janraincapture.js +52 -23
  20. package/lib/Adapters/Auth/janrainengage.js +19 -36
  21. package/lib/Adapters/Auth/keycloak.js +148 -0
  22. package/lib/Adapters/Auth/ldap.js +167 -0
  23. package/lib/Adapters/Auth/line.js +125 -0
  24. package/lib/Adapters/Auth/linkedin.js +111 -55
  25. package/lib/Adapters/Auth/meetup.js +24 -34
  26. package/lib/Adapters/Auth/mfa.js +324 -0
  27. package/lib/Adapters/Auth/microsoft.js +111 -0
  28. package/lib/Adapters/Auth/oauth2.js +97 -162
  29. package/lib/Adapters/Auth/phantauth.js +53 -0
  30. package/lib/Adapters/Auth/qq.js +108 -49
  31. package/lib/Adapters/Auth/spotify.js +107 -55
  32. package/lib/Adapters/Auth/twitter.js +188 -48
  33. package/lib/Adapters/Auth/utils.js +28 -0
  34. package/lib/Adapters/Auth/vkontakte.js +26 -39
  35. package/lib/Adapters/Auth/wechat.js +106 -44
  36. package/lib/Adapters/Auth/weibo.js +132 -58
  37. package/lib/Adapters/Cache/CacheAdapter.js +13 -8
  38. package/lib/Adapters/Cache/InMemoryCache.js +3 -13
  39. package/lib/Adapters/Cache/InMemoryCacheAdapter.js +5 -13
  40. package/lib/Adapters/Cache/LRUCache.js +13 -27
  41. package/lib/Adapters/Cache/NullCacheAdapter.js +3 -8
  42. package/lib/Adapters/Cache/RedisCacheAdapter.js +85 -76
  43. package/lib/Adapters/Cache/SchemaCache.js +25 -0
  44. package/lib/Adapters/Email/MailAdapter.js +10 -8
  45. package/lib/Adapters/Files/FilesAdapter.js +83 -25
  46. package/lib/Adapters/Files/GridFSBucketAdapter.js +231 -0
  47. package/lib/Adapters/Files/GridStoreAdapter.js +4 -91
  48. package/lib/Adapters/Logger/LoggerAdapter.js +18 -14
  49. package/lib/Adapters/Logger/WinstonLogger.js +69 -88
  50. package/lib/Adapters/Logger/WinstonLoggerAdapter.js +7 -16
  51. package/lib/Adapters/MessageQueue/EventEmitterMQ.js +8 -26
  52. package/lib/Adapters/PubSub/EventEmitterPubSub.js +12 -25
  53. package/lib/Adapters/PubSub/PubSubAdapter.js +34 -0
  54. package/lib/Adapters/PubSub/RedisPubSub.js +42 -19
  55. package/lib/Adapters/Push/PushAdapter.js +14 -7
  56. package/lib/Adapters/Storage/Mongo/MongoCollection.js +137 -45
  57. package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +158 -63
  58. package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +320 -168
  59. package/lib/Adapters/Storage/Mongo/MongoTransform.js +279 -306
  60. package/lib/Adapters/Storage/Postgres/PostgresClient.js +14 -10
  61. package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +47 -21
  62. package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +854 -468
  63. package/lib/Adapters/Storage/Postgres/sql/index.js +4 -6
  64. package/lib/Adapters/Storage/StorageAdapter.js +1 -1
  65. package/lib/Adapters/WebSocketServer/WSAdapter.js +35 -0
  66. package/lib/Adapters/WebSocketServer/WSSAdapter.js +66 -0
  67. package/lib/Auth.js +488 -125
  68. package/lib/ClientSDK.js +2 -6
  69. package/lib/Config.js +525 -94
  70. package/lib/Controllers/AdaptableController.js +5 -25
  71. package/lib/Controllers/AnalyticsController.js +22 -23
  72. package/lib/Controllers/CacheController.js +10 -31
  73. package/lib/Controllers/DatabaseController.js +767 -313
  74. package/lib/Controllers/FilesController.js +49 -54
  75. package/lib/Controllers/HooksController.js +80 -84
  76. package/lib/Controllers/LiveQueryController.js +35 -22
  77. package/lib/Controllers/LoggerController.js +22 -58
  78. package/lib/Controllers/ParseGraphQLController.js +293 -0
  79. package/lib/Controllers/PushController.js +58 -49
  80. package/lib/Controllers/SchemaController.js +916 -422
  81. package/lib/Controllers/UserController.js +265 -180
  82. package/lib/Controllers/index.js +90 -125
  83. package/lib/Controllers/types.js +1 -1
  84. package/lib/Deprecator/Deprecations.js +30 -0
  85. package/lib/Deprecator/Deprecator.js +127 -0
  86. package/lib/Error.js +48 -0
  87. package/lib/GraphQL/ParseGraphQLSchema.js +375 -0
  88. package/lib/GraphQL/ParseGraphQLServer.js +214 -0
  89. package/lib/GraphQL/helpers/objectsMutations.js +30 -0
  90. package/lib/GraphQL/helpers/objectsQueries.js +246 -0
  91. package/lib/GraphQL/loaders/configMutations.js +87 -0
  92. package/lib/GraphQL/loaders/configQueries.js +79 -0
  93. package/lib/GraphQL/loaders/defaultGraphQLMutations.js +21 -0
  94. package/lib/GraphQL/loaders/defaultGraphQLQueries.js +23 -0
  95. package/lib/GraphQL/loaders/defaultGraphQLTypes.js +1098 -0
  96. package/lib/GraphQL/loaders/defaultRelaySchema.js +53 -0
  97. package/lib/GraphQL/loaders/filesMutations.js +107 -0
  98. package/lib/GraphQL/loaders/functionsMutations.js +78 -0
  99. package/lib/GraphQL/loaders/parseClassMutations.js +268 -0
  100. package/lib/GraphQL/loaders/parseClassQueries.js +127 -0
  101. package/lib/GraphQL/loaders/parseClassTypes.js +493 -0
  102. package/lib/GraphQL/loaders/schemaDirectives.js +62 -0
  103. package/lib/GraphQL/loaders/schemaMutations.js +162 -0
  104. package/lib/GraphQL/loaders/schemaQueries.js +81 -0
  105. package/lib/GraphQL/loaders/schemaTypes.js +341 -0
  106. package/lib/GraphQL/loaders/usersMutations.js +433 -0
  107. package/lib/GraphQL/loaders/usersQueries.js +90 -0
  108. package/lib/GraphQL/parseGraphQLUtils.js +63 -0
  109. package/lib/GraphQL/transformers/className.js +14 -0
  110. package/lib/GraphQL/transformers/constraintType.js +53 -0
  111. package/lib/GraphQL/transformers/inputType.js +51 -0
  112. package/lib/GraphQL/transformers/mutation.js +274 -0
  113. package/lib/GraphQL/transformers/outputType.js +51 -0
  114. package/lib/GraphQL/transformers/query.js +237 -0
  115. package/lib/GraphQL/transformers/schemaFields.js +99 -0
  116. package/lib/KeyPromiseQueue.js +48 -0
  117. package/lib/LiveQuery/Client.js +25 -33
  118. package/lib/LiveQuery/Id.js +2 -5
  119. package/lib/LiveQuery/ParseCloudCodePublisher.js +26 -23
  120. package/lib/LiveQuery/ParseLiveQueryServer.js +560 -285
  121. package/lib/LiveQuery/ParsePubSub.js +7 -16
  122. package/lib/LiveQuery/ParseWebSocketServer.js +42 -39
  123. package/lib/LiveQuery/QueryTools.js +76 -15
  124. package/lib/LiveQuery/RequestSchema.js +111 -97
  125. package/lib/LiveQuery/SessionTokenCache.js +23 -36
  126. package/lib/LiveQuery/Subscription.js +8 -17
  127. package/lib/LiveQuery/equalObjects.js +2 -3
  128. package/lib/Options/Definitions.js +1355 -382
  129. package/lib/Options/docs.js +301 -62
  130. package/lib/Options/index.js +11 -1
  131. package/lib/Options/parsers.js +14 -10
  132. package/lib/Page.js +44 -0
  133. package/lib/ParseMessageQueue.js +6 -13
  134. package/lib/ParseServer.js +474 -235
  135. package/lib/ParseServerRESTController.js +102 -40
  136. package/lib/PromiseRouter.js +39 -50
  137. package/lib/Push/PushQueue.js +24 -30
  138. package/lib/Push/PushWorker.js +32 -56
  139. package/lib/Push/utils.js +22 -35
  140. package/lib/RestQuery.js +361 -139
  141. package/lib/RestWrite.js +713 -344
  142. package/lib/Routers/AggregateRouter.js +97 -71
  143. package/lib/Routers/AnalyticsRouter.js +8 -14
  144. package/lib/Routers/AudiencesRouter.js +16 -35
  145. package/lib/Routers/ClassesRouter.js +86 -72
  146. package/lib/Routers/CloudCodeRouter.js +28 -37
  147. package/lib/Routers/FeaturesRouter.js +22 -25
  148. package/lib/Routers/FilesRouter.js +266 -171
  149. package/lib/Routers/FunctionsRouter.js +87 -103
  150. package/lib/Routers/GlobalConfigRouter.js +94 -33
  151. package/lib/Routers/GraphQLRouter.js +41 -0
  152. package/lib/Routers/HooksRouter.js +43 -47
  153. package/lib/Routers/IAPValidationRouter.js +57 -70
  154. package/lib/Routers/InstallationsRouter.js +17 -25
  155. package/lib/Routers/LogsRouter.js +10 -25
  156. package/lib/Routers/PagesRouter.js +647 -0
  157. package/lib/Routers/PublicAPIRouter.js +104 -112
  158. package/lib/Routers/PurgeRouter.js +19 -29
  159. package/lib/Routers/PushRouter.js +14 -28
  160. package/lib/Routers/RolesRouter.js +7 -14
  161. package/lib/Routers/SchemasRouter.js +63 -42
  162. package/lib/Routers/SecurityRouter.js +34 -0
  163. package/lib/Routers/SessionsRouter.js +25 -38
  164. package/lib/Routers/UsersRouter.js +463 -190
  165. package/lib/SchemaMigrations/DefinedSchemas.js +379 -0
  166. package/lib/SchemaMigrations/Migrations.js +30 -0
  167. package/lib/Security/Check.js +109 -0
  168. package/lib/Security/CheckGroup.js +44 -0
  169. package/lib/Security/CheckGroups/CheckGroupDatabase.js +44 -0
  170. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +96 -0
  171. package/lib/Security/CheckGroups/CheckGroups.js +21 -0
  172. package/lib/Security/CheckRunner.js +213 -0
  173. package/lib/SharedRest.js +29 -0
  174. package/lib/StatusHandler.js +96 -93
  175. package/lib/TestUtils.js +70 -14
  176. package/lib/Utils.js +468 -0
  177. package/lib/batch.js +74 -40
  178. package/lib/cache.js +8 -8
  179. package/lib/cli/definitions/parse-live-query-server.js +4 -3
  180. package/lib/cli/definitions/parse-server.js +4 -3
  181. package/lib/cli/parse-live-query-server.js +9 -17
  182. package/lib/cli/parse-server.js +49 -47
  183. package/lib/cli/utils/commander.js +20 -29
  184. package/lib/cli/utils/runner.js +31 -32
  185. package/lib/cloud-code/Parse.Cloud.js +711 -36
  186. package/lib/cloud-code/Parse.Server.js +21 -0
  187. package/lib/cryptoUtils.js +6 -11
  188. package/lib/defaults.js +21 -15
  189. package/lib/deprecated.js +1 -1
  190. package/lib/index.js +78 -67
  191. package/lib/logger.js +12 -20
  192. package/lib/middlewares.js +484 -160
  193. package/lib/password.js +10 -6
  194. package/lib/request.js +175 -0
  195. package/lib/requiredParameter.js +4 -3
  196. package/lib/rest.js +157 -82
  197. package/lib/triggers.js +627 -185
  198. package/lib/vendor/README.md +3 -3
  199. package/lib/vendor/mongodbUrl.js +224 -137
  200. package/package.json +135 -57
  201. package/postinstall.js +38 -50
  202. package/public_html/invalid_verification_link.html +3 -3
  203. package/types/@types/@parse/fs-files-adapter/index.d.ts +5 -0
  204. package/types/@types/deepcopy/index.d.ts +5 -0
  205. package/types/LiveQuery/ParseLiveQueryServer.d.ts +40 -0
  206. package/types/Options/index.d.ts +301 -0
  207. package/types/ParseServer.d.ts +65 -0
  208. package/types/eslint.config.mjs +30 -0
  209. package/types/index.d.ts +21 -0
  210. package/types/logger.d.ts +2 -0
  211. package/types/tests.ts +44 -0
  212. package/types/tsconfig.json +24 -0
  213. package/CHANGELOG.md +0 -1246
  214. package/PATENTS +0 -37
  215. package/bin/dev +0 -37
  216. package/lib/.DS_Store +0 -0
  217. package/lib/Adapters/Auth/common.js +0 -2
  218. package/lib/Adapters/Auth/facebookaccountkit.js +0 -69
  219. package/lib/Controllers/SchemaCache.js +0 -97
  220. package/lib/LiveQuery/.DS_Store +0 -0
  221. package/lib/cli/utils/parsers.js +0 -77
  222. package/lib/cloud-code/.DS_Store +0 -0
  223. package/lib/cloud-code/HTTPResponse.js +0 -57
  224. package/lib/cloud-code/Untitled-1 +0 -123
  225. package/lib/cloud-code/httpRequest.js +0 -102
  226. package/lib/cloud-code/team.html +0 -123
  227. package/lib/graphql/ParseClass.js +0 -234
  228. package/lib/graphql/Schema.js +0 -197
  229. package/lib/graphql/index.js +0 -1
  230. package/lib/graphql/types/ACL.js +0 -35
  231. package/lib/graphql/types/Date.js +0 -25
  232. package/lib/graphql/types/File.js +0 -24
  233. package/lib/graphql/types/GeoPoint.js +0 -35
  234. package/lib/graphql/types/JSONObject.js +0 -30
  235. package/lib/graphql/types/NumberInput.js +0 -43
  236. package/lib/graphql/types/NumberQuery.js +0 -42
  237. package/lib/graphql/types/Pointer.js +0 -35
  238. package/lib/graphql/types/QueryConstraint.js +0 -61
  239. package/lib/graphql/types/StringQuery.js +0 -39
  240. package/lib/graphql/types/index.js +0 -110
package/lib/triggers.js CHANGED
@@ -1,51 +1,66 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.Types = undefined;
6
+ exports.Types = void 0;
7
+ exports._unregisterAll = _unregisterAll;
8
+ exports.addConnectTrigger = addConnectTrigger;
7
9
  exports.addFunction = addFunction;
8
10
  exports.addJob = addJob;
9
- exports.addTrigger = addTrigger;
10
11
  exports.addLiveQueryEventHandler = addLiveQueryEventHandler;
11
- exports.removeFunction = removeFunction;
12
- exports.removeTrigger = removeTrigger;
13
- exports._unregisterAll = _unregisterAll;
14
- exports.getTrigger = getTrigger;
15
- exports.triggerExists = triggerExists;
12
+ exports.addTrigger = addTrigger;
13
+ exports.getClassName = getClassName;
16
14
  exports.getFunction = getFunction;
15
+ exports.getFunctionNames = getFunctionNames;
17
16
  exports.getJob = getJob;
18
17
  exports.getJobs = getJobs;
19
- exports.getValidator = getValidator;
18
+ exports.getRequestFileObject = getRequestFileObject;
20
19
  exports.getRequestObject = getRequestObject;
21
20
  exports.getRequestQueryObject = getRequestQueryObject;
22
21
  exports.getResponseObject = getResponseObject;
22
+ exports.getTrigger = getTrigger;
23
+ exports.getValidator = getValidator;
24
+ exports.inflate = inflate;
23
25
  exports.maybeRunAfterFindTrigger = maybeRunAfterFindTrigger;
26
+ exports.maybeRunFileTrigger = maybeRunFileTrigger;
27
+ exports.maybeRunGlobalConfigTrigger = maybeRunGlobalConfigTrigger;
24
28
  exports.maybeRunQueryTrigger = maybeRunQueryTrigger;
25
29
  exports.maybeRunTrigger = maybeRunTrigger;
26
- exports.inflate = inflate;
30
+ exports.maybeRunValidator = maybeRunValidator;
31
+ exports.removeFunction = removeFunction;
32
+ exports.removeTrigger = removeTrigger;
33
+ exports.resolveError = resolveError;
27
34
  exports.runLiveQueryEventHandlers = runLiveQueryEventHandlers;
28
-
29
- var _node = require('parse/node');
30
-
31
- var _node2 = _interopRequireDefault(_node);
32
-
33
- var _logger = require('./logger');
34
-
35
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
36
-
35
+ exports.runTrigger = runTrigger;
36
+ exports.toJSONwithObjects = toJSONwithObjects;
37
+ exports.triggerExists = triggerExists;
38
+ var _node = _interopRequireDefault(require("parse/node"));
39
+ var _logger = require("./logger");
40
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
37
41
  // triggers.js
42
+
38
43
  const Types = exports.Types = {
44
+ beforeLogin: 'beforeLogin',
45
+ afterLogin: 'afterLogin',
46
+ afterLogout: 'afterLogout',
47
+ beforePasswordResetRequest: 'beforePasswordResetRequest',
39
48
  beforeSave: 'beforeSave',
40
49
  afterSave: 'afterSave',
41
50
  beforeDelete: 'beforeDelete',
42
51
  afterDelete: 'afterDelete',
43
52
  beforeFind: 'beforeFind',
44
- afterFind: 'afterFind'
53
+ afterFind: 'afterFind',
54
+ beforeConnect: 'beforeConnect',
55
+ beforeSubscribe: 'beforeSubscribe',
56
+ afterEvent: 'afterEvent'
45
57
  };
46
-
58
+ const ConnectClassName = '@Connect';
47
59
  const baseStore = function () {
48
- const Validators = {};
60
+ const Validators = Object.keys(Types).reduce(function (base, key) {
61
+ base[key] = {};
62
+ return base;
63
+ }, {});
49
64
  const Functions = {};
50
65
  const Jobs = {};
51
66
  const LiveQuery = [];
@@ -53,7 +68,6 @@ const baseStore = function () {
53
68
  base[key] = {};
54
69
  return base;
55
70
  }, {});
56
-
57
71
  return Object.freeze({
58
72
  Functions,
59
73
  Jobs,
@@ -62,94 +76,180 @@ const baseStore = function () {
62
76
  LiveQuery
63
77
  });
64
78
  };
65
-
66
- function validateClassNameForTriggers(className, type) {
67
- const restrictedClassNames = ['_Session'];
68
- if (restrictedClassNames.indexOf(className) != -1) {
69
- throw `Triggers are not supported for ${className} class.`;
79
+ function getClassName(parseClass) {
80
+ if (parseClass && parseClass.className) {
81
+ return parseClass.className;
82
+ }
83
+ if (parseClass && parseClass.name) {
84
+ return parseClass.name.replace('Parse', '@');
70
85
  }
86
+ return parseClass;
87
+ }
88
+ function validateClassNameForTriggers(className, type) {
71
89
  if (type == Types.beforeSave && className === '_PushStatus') {
72
90
  // _PushStatus uses undocumented nested key increment ops
73
91
  // allowing beforeSave would mess up the objects big time
74
92
  // TODO: Allow proper documented way of using nested increment ops
75
93
  throw 'Only afterSave is allowed on _PushStatus';
76
94
  }
95
+ if ((type === Types.beforeLogin || type === Types.afterLogin || type === Types.beforePasswordResetRequest) && className !== '_User') {
96
+ // TODO: check if upstream code will handle `Error` instance rather
97
+ // than this anti-pattern of throwing strings
98
+ throw 'Only the _User class is allowed for the beforeLogin, afterLogin, and beforePasswordResetRequest triggers';
99
+ }
100
+ if (type === Types.afterLogout && className !== '_Session') {
101
+ // TODO: check if upstream code will handle `Error` instance rather
102
+ // than this anti-pattern of throwing strings
103
+ throw 'Only the _Session class is allowed for the afterLogout trigger.';
104
+ }
105
+ if (className === '_Session' && type !== Types.afterLogout) {
106
+ // TODO: check if upstream code will handle `Error` instance rather
107
+ // than this anti-pattern of throwing strings
108
+ throw 'Only the afterLogout trigger is allowed for the _Session class.';
109
+ }
77
110
  return className;
78
111
  }
79
-
80
112
  const _triggerStore = {};
81
-
82
- function addFunction(functionName, handler, validationHandler, applicationId) {
83
- applicationId = applicationId || _node2.default.applicationId;
113
+ const Category = {
114
+ Functions: 'Functions',
115
+ Validators: 'Validators',
116
+ Jobs: 'Jobs',
117
+ Triggers: 'Triggers'
118
+ };
119
+ function getStore(category, name, applicationId) {
120
+ const invalidNameRegex = /['"`]/;
121
+ if (invalidNameRegex.test(name)) {
122
+ // Prevent a malicious user from injecting properties into the store
123
+ return {};
124
+ }
125
+ const path = name.split('.');
126
+ path.splice(-1); // remove last component
127
+ applicationId = applicationId || _node.default.applicationId;
84
128
  _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
85
- _triggerStore[applicationId].Functions[functionName] = handler;
86
- _triggerStore[applicationId].Validators[functionName] = validationHandler;
129
+ let store = _triggerStore[applicationId][category];
130
+ for (const component of path) {
131
+ store = store[component];
132
+ if (!store) {
133
+ return {};
134
+ }
135
+ }
136
+ return store;
137
+ }
138
+ function add(category, name, handler, applicationId) {
139
+ const lastComponent = name.split('.').splice(-1);
140
+ const store = getStore(category, name, applicationId);
141
+ if (store[lastComponent]) {
142
+ _logger.logger.warn(`Warning: Duplicate cloud functions exist for ${lastComponent}. Only the last one will be used and the others will be ignored.`);
143
+ }
144
+ store[lastComponent] = handler;
145
+ }
146
+ function remove(category, name, applicationId) {
147
+ const lastComponent = name.split('.').splice(-1);
148
+ const store = getStore(category, name, applicationId);
149
+ delete store[lastComponent];
150
+ }
151
+ function get(category, name, applicationId) {
152
+ const lastComponent = name.split('.').splice(-1);
153
+ const store = getStore(category, name, applicationId);
154
+ return store[lastComponent];
155
+ }
156
+ function addFunction(functionName, handler, validationHandler, applicationId) {
157
+ add(Category.Functions, functionName, handler, applicationId);
158
+ add(Category.Validators, functionName, validationHandler, applicationId);
87
159
  }
88
-
89
160
  function addJob(jobName, handler, applicationId) {
90
- applicationId = applicationId || _node2.default.applicationId;
91
- _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
92
- _triggerStore[applicationId].Jobs[jobName] = handler;
161
+ add(Category.Jobs, jobName, handler, applicationId);
93
162
  }
94
-
95
- function addTrigger(type, className, handler, applicationId) {
163
+ function addTrigger(type, className, handler, applicationId, validationHandler) {
96
164
  validateClassNameForTriggers(className, type);
97
- applicationId = applicationId || _node2.default.applicationId;
98
- _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
99
- _triggerStore[applicationId].Triggers[type][className] = handler;
165
+ add(Category.Triggers, `${type}.${className}`, handler, applicationId);
166
+ add(Category.Validators, `${type}.${className}`, validationHandler, applicationId);
167
+ }
168
+ function addConnectTrigger(type, handler, applicationId, validationHandler) {
169
+ add(Category.Triggers, `${type}.${ConnectClassName}`, handler, applicationId);
170
+ add(Category.Validators, `${type}.${ConnectClassName}`, validationHandler, applicationId);
100
171
  }
101
-
102
172
  function addLiveQueryEventHandler(handler, applicationId) {
103
- applicationId = applicationId || _node2.default.applicationId;
173
+ applicationId = applicationId || _node.default.applicationId;
104
174
  _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
105
175
  _triggerStore[applicationId].LiveQuery.push(handler);
106
176
  }
107
-
108
177
  function removeFunction(functionName, applicationId) {
109
- applicationId = applicationId || _node2.default.applicationId;
110
- delete _triggerStore[applicationId].Functions[functionName];
178
+ remove(Category.Functions, functionName, applicationId);
111
179
  }
112
-
113
180
  function removeTrigger(type, className, applicationId) {
114
- applicationId = applicationId || _node2.default.applicationId;
115
- delete _triggerStore[applicationId].Triggers[type][className];
181
+ remove(Category.Triggers, `${type}.${className}`, applicationId);
116
182
  }
117
-
118
183
  function _unregisterAll() {
119
184
  Object.keys(_triggerStore).forEach(appId => delete _triggerStore[appId]);
120
185
  }
121
-
186
+ function toJSONwithObjects(object, className) {
187
+ if (!object || !object.toJSON) {
188
+ return {};
189
+ }
190
+ const toJSON = object.toJSON();
191
+ const stateController = _node.default.CoreManager.getObjectStateController();
192
+ const [pending] = stateController.getPendingOps(object._getStateIdentifier());
193
+ for (const key in pending) {
194
+ const val = object.get(key);
195
+ if (!val || !val._toFullJSON) {
196
+ toJSON[key] = val;
197
+ continue;
198
+ }
199
+ toJSON[key] = val._toFullJSON();
200
+ }
201
+ // Preserve original object's className if no override className is provided
202
+ if (className) {
203
+ toJSON.className = className;
204
+ } else if (object.className && !toJSON.className) {
205
+ toJSON.className = object.className;
206
+ }
207
+ return toJSON;
208
+ }
122
209
  function getTrigger(className, triggerType, applicationId) {
123
210
  if (!applicationId) {
124
- throw "Missing ApplicationID";
211
+ throw 'Missing ApplicationID';
125
212
  }
126
- var manager = _triggerStore[applicationId];
127
- if (manager && manager.Triggers && manager.Triggers[triggerType] && manager.Triggers[triggerType][className]) {
128
- return manager.Triggers[triggerType][className];
213
+ return get(Category.Triggers, `${triggerType}.${className}`, applicationId);
214
+ }
215
+ async function runTrigger(trigger, name, request, auth) {
216
+ if (!trigger) {
217
+ return;
129
218
  }
130
- return undefined;
219
+ await maybeRunValidator(request, name, auth);
220
+ if (request.skipWithMasterKey) {
221
+ return;
222
+ }
223
+ return await trigger(request);
131
224
  }
132
-
133
225
  function triggerExists(className, type, applicationId) {
134
226
  return getTrigger(className, type, applicationId) != undefined;
135
227
  }
136
-
137
228
  function getFunction(functionName, applicationId) {
138
- var manager = _triggerStore[applicationId];
139
- if (manager && manager.Functions) {
140
- return manager.Functions[functionName];
141
- }
142
- return undefined;
229
+ return get(Category.Functions, functionName, applicationId);
230
+ }
231
+ function getFunctionNames(applicationId) {
232
+ const store = _triggerStore[applicationId] && _triggerStore[applicationId][Category.Functions] || {};
233
+ const functionNames = [];
234
+ const extractFunctionNames = (namespace, store) => {
235
+ Object.keys(store).forEach(name => {
236
+ const value = store[name];
237
+ if (namespace) {
238
+ name = `${namespace}.${name}`;
239
+ }
240
+ if (typeof value === 'function') {
241
+ functionNames.push(name);
242
+ } else {
243
+ extractFunctionNames(name, value);
244
+ }
245
+ });
246
+ };
247
+ extractFunctionNames(null, store);
248
+ return functionNames;
143
249
  }
144
-
145
250
  function getJob(jobName, applicationId) {
146
- var manager = _triggerStore[applicationId];
147
- if (manager && manager.Jobs) {
148
- return manager.Jobs[jobName];
149
- }
150
- return undefined;
251
+ return get(Category.Jobs, jobName, applicationId);
151
252
  }
152
-
153
253
  function getJobs(applicationId) {
154
254
  var manager = _triggerStore[applicationId];
155
255
  if (manager && manager.Jobs) {
@@ -157,29 +257,29 @@ function getJobs(applicationId) {
157
257
  }
158
258
  return undefined;
159
259
  }
160
-
161
260
  function getValidator(functionName, applicationId) {
162
- var manager = _triggerStore[applicationId];
163
- if (manager && manager.Validators) {
164
- return manager.Validators[functionName];
165
- }
166
- return undefined;
261
+ return get(Category.Validators, functionName, applicationId);
167
262
  }
168
-
169
- function getRequestObject(triggerType, auth, parseObject, originalParseObject, config) {
170
- var request = {
263
+ function getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context, isGet) {
264
+ const request = {
171
265
  triggerName: triggerType,
172
266
  object: parseObject,
173
267
  master: false,
174
268
  log: config.loggerController,
175
269
  headers: config.headers,
176
- ip: config.ip
270
+ ip: config.ip,
271
+ config
177
272
  };
178
-
273
+ if (isGet !== undefined) {
274
+ request.isGet = !!isGet;
275
+ }
179
276
  if (originalParseObject) {
180
277
  request.original = originalParseObject;
181
278
  }
182
-
279
+ if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete || triggerType === Types.beforeLogin || triggerType === Types.afterLogin || triggerType === Types.beforePasswordResetRequest || triggerType === Types.afterFind) {
280
+ // Set a copy of the context on the request object.
281
+ request.context = Object.assign({}, context);
282
+ }
183
283
  if (!auth) {
184
284
  return request;
185
285
  }
@@ -194,10 +294,8 @@ function getRequestObject(triggerType, auth, parseObject, originalParseObject, c
194
294
  }
195
295
  return request;
196
296
  }
197
-
198
- function getRequestQueryObject(triggerType, auth, query, count, config, isGet) {
297
+ function getRequestQueryObject(triggerType, auth, query, count, config, context, isGet) {
199
298
  isGet = !!isGet;
200
-
201
299
  var request = {
202
300
  triggerName: triggerType,
203
301
  query,
@@ -206,9 +304,10 @@ function getRequestQueryObject(triggerType, auth, query, count, config, isGet) {
206
304
  log: config.loggerController,
207
305
  isGet,
208
306
  headers: config.headers,
209
- ip: config.ip
307
+ ip: config.ip,
308
+ context: context || {},
309
+ config
210
310
  };
211
-
212
311
  if (!auth) {
213
312
  return request;
214
313
  }
@@ -236,102 +335,139 @@ function getResponseObject(request, resolve, reject) {
236
335
  response = request.objects;
237
336
  }
238
337
  response = response.map(object => {
239
- return object.toJSON();
338
+ return toJSONwithObjects(object);
240
339
  });
241
340
  return resolve(response);
242
341
  }
243
342
  // Use the JSON response
244
- if (response && !request.object.equals(response) && request.triggerName === Types.beforeSave) {
343
+ if (response && typeof response === 'object' && !request.object.equals(response) && request.triggerName === Types.beforeSave) {
344
+ return resolve(response);
345
+ }
346
+ if (response && typeof response === 'object' && request.triggerName === Types.afterSave) {
245
347
  return resolve(response);
246
348
  }
349
+ if (request.triggerName === Types.afterSave) {
350
+ return resolve();
351
+ }
247
352
  response = {};
248
353
  if (request.triggerName === Types.beforeSave) {
249
354
  response['object'] = request.object._getSaveJSON();
355
+ response['object']['objectId'] = request.object.id;
250
356
  }
251
357
  return resolve(response);
252
358
  },
253
- error: function (code, message) {
254
- if (!message) {
255
- if (code instanceof _node2.default.Error) {
256
- return reject(code);
257
- }
258
- message = code;
259
- code = _node2.default.Error.SCRIPT_FAILED;
260
- }
261
- var scriptError = new _node2.default.Error(code, message);
262
- return reject(scriptError);
359
+ error: function (error) {
360
+ const e = resolveError(error, {
361
+ code: _node.default.Error.SCRIPT_FAILED,
362
+ message: 'Script failed. Unknown error.'
363
+ });
364
+ reject(e);
263
365
  }
264
366
  };
265
367
  }
266
-
267
368
  function userIdForLog(auth) {
268
369
  return auth && auth.user ? auth.user.id : undefined;
269
370
  }
270
-
271
- function logTriggerAfterHook(triggerType, className, input, auth) {
371
+ function logTriggerAfterHook(triggerType, className, input, auth, logLevel) {
372
+ if (logLevel === 'silent') {
373
+ return;
374
+ }
272
375
  const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input));
273
- _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, {
376
+ _logger.logger[logLevel](`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, {
274
377
  className,
275
378
  triggerType,
276
379
  user: userIdForLog(auth)
277
380
  });
278
381
  }
279
-
280
- function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) {
382
+ function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth, logLevel) {
383
+ if (logLevel === 'silent') {
384
+ return;
385
+ }
281
386
  const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input));
282
387
  const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result));
283
- _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, {
388
+ _logger.logger[logLevel](`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, {
284
389
  className,
285
390
  triggerType,
286
391
  user: userIdForLog(auth)
287
392
  });
288
393
  }
289
-
290
- function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) {
394
+ function logTriggerErrorBeforeHook(triggerType, className, input, auth, error, logLevel) {
395
+ if (logLevel === 'silent') {
396
+ return;
397
+ }
291
398
  const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input));
292
- _logger.logger.error(`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, {
399
+ _logger.logger[logLevel](`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, {
293
400
  className,
294
401
  triggerType,
295
402
  error,
296
403
  user: userIdForLog(auth)
297
404
  });
298
405
  }
299
-
300
- function maybeRunAfterFindTrigger(triggerType, auth, className, objects, config) {
406
+ function maybeRunAfterFindTrigger(triggerType, auth, classNameQuery, objectsInput, config, query, context, isGet) {
301
407
  return new Promise((resolve, reject) => {
302
- const trigger = getTrigger(className, triggerType, config.applicationId);
408
+ const trigger = getTrigger(classNameQuery, triggerType, config.applicationId);
303
409
  if (!trigger) {
304
- return resolve();
410
+ if (objectsInput && objectsInput.length > 0 && objectsInput[0] instanceof _node.default.Object) {
411
+ return resolve(objectsInput.map(obj => toJSONwithObjects(obj)));
412
+ }
413
+ return resolve(objectsInput || []);
305
414
  }
306
- const request = getRequestObject(triggerType, auth, null, null, config);
307
- const response = getResponseObject(request, object => {
308
- resolve(object);
309
- }, error => {
310
- reject(error);
415
+ const request = getRequestObject(triggerType, auth, null, null, config, context, isGet);
416
+ // Convert query parameter to Parse.Query instance
417
+ if (query instanceof _node.default.Query) {
418
+ request.query = query;
419
+ } else if (typeof query === 'object' && query !== null) {
420
+ const parseQueryInstance = new _node.default.Query(classNameQuery);
421
+ if (query.where) {
422
+ parseQueryInstance.withJSON(query);
423
+ }
424
+ request.query = parseQueryInstance;
425
+ } else {
426
+ request.query = new _node.default.Query(classNameQuery);
427
+ }
428
+ const {
429
+ success,
430
+ error
431
+ } = getResponseObject(request, processedObjectsJSON => {
432
+ resolve(processedObjectsJSON);
433
+ }, errorData => {
434
+ reject(errorData);
311
435
  });
312
- logTriggerSuccessBeforeHook(triggerType, className, 'AfterFind', JSON.stringify(objects), auth);
313
- request.objects = objects.map(object => {
314
- //setting the class name to transform into parse object
315
- object.className = className;
316
- return _node2.default.Object.fromJSON(object);
436
+ logTriggerSuccessBeforeHook(triggerType, classNameQuery, 'AfterFind Input (Pre-Transform)', JSON.stringify(objectsInput.map(o => o instanceof _node.default.Object ? o.id + ':' + o.className : o)), auth, config.logLevels.triggerBeforeSuccess);
437
+
438
+ // Convert plain objects to Parse.Object instances for trigger
439
+ request.objects = objectsInput.map(currentObject => {
440
+ if (currentObject instanceof _node.default.Object) {
441
+ return currentObject;
442
+ }
443
+ // Preserve the original className if it exists, otherwise use the query className
444
+ const originalClassName = currentObject.className || classNameQuery;
445
+ const tempObjectWithClassName = {
446
+ ...currentObject,
447
+ className: originalClassName
448
+ };
449
+ return _node.default.Object.fromJSON(tempObjectWithClassName);
317
450
  });
318
- const triggerPromise = trigger(request, response);
319
- if (triggerPromise && typeof triggerPromise.then === "function") {
320
- return triggerPromise.then(promiseResults => {
321
- if (promiseResults) {
322
- resolve(promiseResults);
323
- } else {
324
- return reject(new _node2.default.Error(_node2.default.Error.SCRIPT_FAILED, "AfterFind expect results to be returned in the promise"));
325
- }
326
- });
327
- }
328
- }).then(results => {
329
- logTriggerAfterHook(triggerType, className, JSON.stringify(results), auth);
330
- return results;
451
+ return Promise.resolve().then(() => {
452
+ return maybeRunValidator(request, `${triggerType}.${classNameQuery}`, auth);
453
+ }).then(() => {
454
+ if (request.skipWithMasterKey) {
455
+ return request.objects;
456
+ }
457
+ const responseFromTrigger = trigger(request);
458
+ if (responseFromTrigger && typeof responseFromTrigger.then === 'function') {
459
+ return responseFromTrigger.then(results => {
460
+ return results;
461
+ });
462
+ }
463
+ return responseFromTrigger;
464
+ }).then(success, error);
465
+ }).then(resultsAsJSON => {
466
+ logTriggerAfterHook(triggerType, classNameQuery, JSON.stringify(resultsAsJSON), auth, config.logLevels.triggerAfter);
467
+ return resultsAsJSON;
331
468
  });
332
469
  }
333
-
334
- function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth, isGet) {
470
+ function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth, context, isGet) {
335
471
  const trigger = getTrigger(className, triggerType, config.applicationId);
336
472
  if (!trigger) {
337
473
  return Promise.resolve({
@@ -339,30 +475,25 @@ function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, co
339
475
  restOptions
340
476
  });
341
477
  }
342
-
343
- const parseQuery = new _node2.default.Query(className);
344
- if (restWhere) {
345
- parseQuery._where = restWhere;
346
- }
478
+ const json = Object.assign({}, restOptions);
479
+ json.where = restWhere;
480
+ const parseQuery = new _node.default.Query(className);
481
+ parseQuery.withJSON(json);
347
482
  let count = false;
348
483
  if (restOptions) {
349
- if (restOptions.include && restOptions.include.length > 0) {
350
- parseQuery._include = restOptions.include.split(',');
351
- }
352
- if (restOptions.skip) {
353
- parseQuery._skip = restOptions.skip;
354
- }
355
- if (restOptions.limit) {
356
- parseQuery._limit = restOptions.limit;
357
- }
358
484
  count = !!restOptions.count;
359
485
  }
360
- const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, count, config, isGet);
486
+ const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, count, config, context, isGet);
361
487
  return Promise.resolve().then(() => {
488
+ return maybeRunValidator(requestObject, `${triggerType}.${className}`, auth);
489
+ }).then(() => {
490
+ if (requestObject.skipWithMasterKey) {
491
+ return requestObject.query;
492
+ }
362
493
  return trigger(requestObject);
363
494
  }).then(result => {
364
495
  let queryResult = parseQuery;
365
- if (result && result instanceof _node2.default.Query) {
496
+ if (result && result instanceof _node.default.Query) {
366
497
  queryResult = result;
367
498
  }
368
499
  const jsonQuery = queryResult.toJSON();
@@ -381,6 +512,14 @@ function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, co
381
512
  restOptions = restOptions || {};
382
513
  restOptions.include = jsonQuery.include;
383
514
  }
515
+ if (jsonQuery.excludeKeys) {
516
+ restOptions = restOptions || {};
517
+ restOptions.excludeKeys = jsonQuery.excludeKeys;
518
+ }
519
+ if (jsonQuery.explain) {
520
+ restOptions = restOptions || {};
521
+ restOptions.explain = jsonQuery.explain;
522
+ }
384
523
  if (jsonQuery.keys) {
385
524
  restOptions = restOptions || {};
386
525
  restOptions.keys = jsonQuery.keys;
@@ -389,6 +528,14 @@ function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, co
389
528
  restOptions = restOptions || {};
390
529
  restOptions.order = jsonQuery.order;
391
530
  }
531
+ if (jsonQuery.hint) {
532
+ restOptions = restOptions || {};
533
+ restOptions.hint = jsonQuery.hint;
534
+ }
535
+ if (jsonQuery.comment) {
536
+ restOptions = restOptions || {};
537
+ restOptions.comment = jsonQuery.comment;
538
+ }
392
539
  if (requestObject.readPreference) {
393
540
  restOptions = restOptions || {};
394
541
  restOptions.readPreference = requestObject.readPreference;
@@ -401,75 +548,370 @@ function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, co
401
548
  restOptions = restOptions || {};
402
549
  restOptions.subqueryReadPreference = requestObject.subqueryReadPreference;
403
550
  }
551
+ let objects = undefined;
552
+ if (result instanceof _node.default.Object) {
553
+ objects = [result];
554
+ } else if (Array.isArray(result) && (!result.length || result.every(obj => obj instanceof _node.default.Object))) {
555
+ objects = result;
556
+ }
404
557
  return {
405
558
  restWhere,
406
- restOptions
559
+ restOptions,
560
+ objects
407
561
  };
408
562
  }, err => {
409
- if (typeof err === 'string') {
410
- throw new _node2.default.Error(1, err);
411
- } else {
412
- throw err;
413
- }
563
+ const error = resolveError(err, {
564
+ code: _node.default.Error.SCRIPT_FAILED,
565
+ message: 'Script failed. Unknown error.'
566
+ });
567
+ throw error;
414
568
  });
415
569
  }
570
+ function resolveError(message, defaultOpts) {
571
+ if (!defaultOpts) {
572
+ defaultOpts = {};
573
+ }
574
+ if (!message) {
575
+ return new _node.default.Error(defaultOpts.code || _node.default.Error.SCRIPT_FAILED, defaultOpts.message || 'Script failed.');
576
+ }
577
+ if (message instanceof _node.default.Error) {
578
+ return message;
579
+ }
580
+ const code = defaultOpts.code || _node.default.Error.SCRIPT_FAILED;
581
+ // If it's an error, mark it as a script failed
582
+ if (typeof message === 'string') {
583
+ return new _node.default.Error(code, message);
584
+ }
585
+ const error = new _node.default.Error(code, message.message || message);
586
+ if (message instanceof Error) {
587
+ error.stack = message.stack;
588
+ }
589
+ return error;
590
+ }
591
+ function maybeRunValidator(request, functionName, auth) {
592
+ const theValidator = getValidator(functionName, _node.default.applicationId);
593
+ if (!theValidator) {
594
+ return;
595
+ }
596
+ if (typeof theValidator === 'object' && theValidator.skipWithMasterKey && request.master) {
597
+ request.skipWithMasterKey = true;
598
+ }
599
+ return new Promise((resolve, reject) => {
600
+ return Promise.resolve().then(() => {
601
+ return typeof theValidator === 'object' ? builtInTriggerValidator(theValidator, request, auth) : theValidator(request);
602
+ }).then(() => {
603
+ resolve();
604
+ }).catch(e => {
605
+ const error = resolveError(e, {
606
+ code: _node.default.Error.VALIDATION_ERROR,
607
+ message: 'Validation failed.'
608
+ });
609
+ reject(error);
610
+ });
611
+ });
612
+ }
613
+ async function builtInTriggerValidator(options, request, auth) {
614
+ if (request.master && !options.validateMasterKey) {
615
+ return;
616
+ }
617
+ let reqUser = request.user;
618
+ if (!reqUser && request.object && request.object.className === '_User' && !request.object.existed()) {
619
+ reqUser = request.object;
620
+ }
621
+ if ((options.requireUser || options.requireAnyUserRoles || options.requireAllUserRoles) && !reqUser) {
622
+ throw 'Validation failed. Please login to continue.';
623
+ }
624
+ if (options.requireMaster && !request.master) {
625
+ throw 'Validation failed. Master key is required to complete this request.';
626
+ }
627
+ let params = request.params || {};
628
+ if (request.object) {
629
+ params = request.object.toJSON();
630
+ }
631
+ const requiredParam = key => {
632
+ const value = params[key];
633
+ if (value == null) {
634
+ throw `Validation failed. Please specify data for ${key}.`;
635
+ }
636
+ };
637
+ const validateOptions = async (opt, key, val) => {
638
+ let opts = opt.options;
639
+ if (typeof opts === 'function') {
640
+ try {
641
+ const result = await opts(val);
642
+ if (!result && result != null) {
643
+ throw opt.error || `Validation failed. Invalid value for ${key}.`;
644
+ }
645
+ } catch (e) {
646
+ if (!e) {
647
+ throw opt.error || `Validation failed. Invalid value for ${key}.`;
648
+ }
649
+ throw opt.error || e.message || e;
650
+ }
651
+ return;
652
+ }
653
+ if (!Array.isArray(opts)) {
654
+ opts = [opt.options];
655
+ }
656
+ if (!opts.includes(val)) {
657
+ throw opt.error || `Validation failed. Invalid option for ${key}. Expected: ${opts.join(', ')}`;
658
+ }
659
+ };
660
+ const getType = fn => {
661
+ const match = fn && fn.toString().match(/^\s*function (\w+)/);
662
+ return (match ? match[1] : '').toLowerCase();
663
+ };
664
+ if (Array.isArray(options.fields)) {
665
+ for (const key of options.fields) {
666
+ requiredParam(key);
667
+ }
668
+ } else {
669
+ const optionPromises = [];
670
+ for (const key in options.fields) {
671
+ const opt = options.fields[key];
672
+ let val = params[key];
673
+ if (typeof opt === 'string') {
674
+ requiredParam(opt);
675
+ }
676
+ if (typeof opt === 'object') {
677
+ if (opt.default != null && val == null) {
678
+ val = opt.default;
679
+ params[key] = val;
680
+ if (request.object) {
681
+ request.object.set(key, val);
682
+ }
683
+ }
684
+ if (opt.constant && request.object) {
685
+ if (request.original) {
686
+ request.object.revert(key);
687
+ } else if (opt.default != null) {
688
+ request.object.set(key, opt.default);
689
+ }
690
+ }
691
+ if (opt.required) {
692
+ requiredParam(key);
693
+ }
694
+ const optional = !opt.required && val === undefined;
695
+ if (!optional) {
696
+ if (opt.type) {
697
+ const type = getType(opt.type);
698
+ const valType = Array.isArray(val) ? 'array' : typeof val;
699
+ if (valType !== type) {
700
+ throw `Validation failed. Invalid type for ${key}. Expected: ${type}`;
701
+ }
702
+ }
703
+ if (opt.options) {
704
+ optionPromises.push(validateOptions(opt, key, val));
705
+ }
706
+ }
707
+ }
708
+ }
709
+ await Promise.all(optionPromises);
710
+ }
711
+ let userRoles = options.requireAnyUserRoles;
712
+ let requireAllRoles = options.requireAllUserRoles;
713
+ const promises = [Promise.resolve(), Promise.resolve(), Promise.resolve()];
714
+ if (userRoles || requireAllRoles) {
715
+ promises[0] = auth.getUserRoles();
716
+ }
717
+ if (typeof userRoles === 'function') {
718
+ promises[1] = userRoles();
719
+ }
720
+ if (typeof requireAllRoles === 'function') {
721
+ promises[2] = requireAllRoles();
722
+ }
723
+ const [roles, resolvedUserRoles, resolvedRequireAll] = await Promise.all(promises);
724
+ if (resolvedUserRoles && Array.isArray(resolvedUserRoles)) {
725
+ userRoles = resolvedUserRoles;
726
+ }
727
+ if (resolvedRequireAll && Array.isArray(resolvedRequireAll)) {
728
+ requireAllRoles = resolvedRequireAll;
729
+ }
730
+ if (userRoles) {
731
+ const hasRole = userRoles.some(requiredRole => roles.includes(`role:${requiredRole}`));
732
+ if (!hasRole) {
733
+ throw `Validation failed. User does not match the required roles.`;
734
+ }
735
+ }
736
+ if (requireAllRoles) {
737
+ for (const requiredRole of requireAllRoles) {
738
+ if (!roles.includes(`role:${requiredRole}`)) {
739
+ throw `Validation failed. User does not match all the required roles.`;
740
+ }
741
+ }
742
+ }
743
+ const userKeys = options.requireUserKeys || [];
744
+ if (Array.isArray(userKeys)) {
745
+ for (const key of userKeys) {
746
+ if (!reqUser) {
747
+ throw 'Please login to make this request.';
748
+ }
749
+ if (reqUser.get(key) == null) {
750
+ throw `Validation failed. Please set data for ${key} on your account.`;
751
+ }
752
+ }
753
+ } else if (typeof userKeys === 'object') {
754
+ const optionPromises = [];
755
+ for (const key in options.requireUserKeys) {
756
+ const opt = options.requireUserKeys[key];
757
+ if (opt.options) {
758
+ optionPromises.push(validateOptions(opt, key, reqUser.get(key)));
759
+ }
760
+ }
761
+ await Promise.all(optionPromises);
762
+ }
763
+ }
416
764
 
417
765
  // To be used as part of the promise chain when saving/deleting an object
418
766
  // Will resolve successfully if no trigger is configured
419
767
  // Resolves to an object, empty or containing an object key. A beforeSave
420
768
  // trigger will set the object key to the rest format object to save.
421
769
  // originalParseObject is optional, we only need that for before/afterSave functions
422
- function maybeRunTrigger(triggerType, auth, parseObject, originalParseObject, config) {
770
+ function maybeRunTrigger(triggerType, auth, parseObject, originalParseObject, config, context) {
423
771
  if (!parseObject) {
424
772
  return Promise.resolve({});
425
773
  }
426
774
  return new Promise(function (resolve, reject) {
427
775
  var trigger = getTrigger(parseObject.className, triggerType, config.applicationId);
428
- if (!trigger) return resolve();
429
- var request = getRequestObject(triggerType, auth, parseObject, originalParseObject, config);
430
- var response = getResponseObject(request, object => {
431
- logTriggerSuccessBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), object, auth);
776
+ if (!trigger) {
777
+ return resolve();
778
+ }
779
+ var request = getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context);
780
+ var {
781
+ success,
782
+ error
783
+ } = getResponseObject(request, object => {
784
+ logTriggerSuccessBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), object, auth, triggerType.startsWith('after') ? config.logLevels.triggerAfter : config.logLevels.triggerBeforeSuccess);
785
+ if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete) {
786
+ Object.assign(context, request.context);
787
+ }
432
788
  resolve(object);
433
789
  }, error => {
434
- logTriggerErrorBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), auth, error);
790
+ logTriggerErrorBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), auth, error, config.logLevels.triggerBeforeError);
435
791
  reject(error);
436
792
  });
437
- // Force the current Parse app before the trigger
438
- _node2.default.applicationId = config.applicationId;
439
- _node2.default.javascriptKey = config.javascriptKey || '';
440
- _node2.default.masterKey = config.masterKey;
441
793
 
442
794
  // AfterSave and afterDelete triggers can return a promise, which if they
443
795
  // do, needs to be resolved before this promise is resolved,
444
796
  // so trigger execution is synced with RestWrite.execute() call.
445
797
  // If triggers do not return a promise, they can run async code parallel
446
798
  // to the RestWrite.execute() call.
447
- var triggerPromise = trigger(request, response);
448
- if (triggerType === Types.afterSave || triggerType === Types.afterDelete) {
449
- logTriggerAfterHook(triggerType, parseObject.className, parseObject.toJSON(), auth);
450
- if (triggerPromise && typeof triggerPromise.then === "function") {
451
- return triggerPromise.then(resolve, resolve);
452
- } else {
453
- return resolve();
799
+ return Promise.resolve().then(() => {
800
+ return maybeRunValidator(request, `${triggerType}.${parseObject.className}`, auth);
801
+ }).then(() => {
802
+ if (request.skipWithMasterKey) {
803
+ return Promise.resolve();
454
804
  }
455
- }
805
+ const promise = trigger(request);
806
+ if (triggerType === Types.afterSave || triggerType === Types.afterDelete || triggerType === Types.afterLogin) {
807
+ logTriggerAfterHook(triggerType, parseObject.className, parseObject.toJSON(), auth, config.logLevels.triggerAfter);
808
+ }
809
+ // beforeSave is expected to return null (nothing)
810
+ if (triggerType === Types.beforeSave) {
811
+ if (promise && typeof promise.then === 'function') {
812
+ return promise.then(response => {
813
+ // response.object may come from express routing before hook
814
+ if (response && response.object) {
815
+ return response;
816
+ }
817
+ return null;
818
+ });
819
+ }
820
+ return null;
821
+ }
822
+ return promise;
823
+ }).then(success, error);
456
824
  });
457
825
  }
458
826
 
459
827
  // Converts a REST-format object to a Parse.Object
460
828
  // data is either className or an object
461
829
  function inflate(data, restObject) {
462
- var copy = typeof data == 'object' ? data : { className: data };
830
+ var copy = typeof data == 'object' ? data : {
831
+ className: data
832
+ };
463
833
  for (var key in restObject) {
464
834
  copy[key] = restObject[key];
465
835
  }
466
- return _node2.default.Object.fromJSON(copy);
836
+ return _node.default.Object.fromJSON(copy);
467
837
  }
468
-
469
- function runLiveQueryEventHandlers(data, applicationId = _node2.default.applicationId) {
838
+ function runLiveQueryEventHandlers(data, applicationId = _node.default.applicationId) {
470
839
  if (!_triggerStore || !_triggerStore[applicationId] || !_triggerStore[applicationId].LiveQuery) {
471
840
  return;
472
841
  }
473
842
  _triggerStore[applicationId].LiveQuery.forEach(handler => handler(data));
474
843
  }
475
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90cmlnZ2Vycy5qcyJdLCJuYW1lcyI6WyJhZGRGdW5jdGlvbiIsImFkZEpvYiIsImFkZFRyaWdnZXIiLCJhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIiLCJyZW1vdmVGdW5jdGlvbiIsInJlbW92ZVRyaWdnZXIiLCJfdW5yZWdpc3RlckFsbCIsImdldFRyaWdnZXIiLCJ0cmlnZ2VyRXhpc3RzIiwiZ2V0RnVuY3Rpb24iLCJnZXRKb2IiLCJnZXRKb2JzIiwiZ2V0VmFsaWRhdG9yIiwiZ2V0UmVxdWVzdE9iamVjdCIsImdldFJlcXVlc3RRdWVyeU9iamVjdCIsImdldFJlc3BvbnNlT2JqZWN0IiwibWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyIiwibWF5YmVSdW5RdWVyeVRyaWdnZXIiLCJtYXliZVJ1blRyaWdnZXIiLCJpbmZsYXRlIiwicnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyIsIlR5cGVzIiwiYmVmb3JlU2F2ZSIsImFmdGVyU2F2ZSIsImJlZm9yZURlbGV0ZSIsImFmdGVyRGVsZXRlIiwiYmVmb3JlRmluZCIsImFmdGVyRmluZCIsImJhc2VTdG9yZSIsIlZhbGlkYXRvcnMiLCJGdW5jdGlvbnMiLCJKb2JzIiwiTGl2ZVF1ZXJ5IiwiVHJpZ2dlcnMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiYmFzZSIsImtleSIsImZyZWV6ZSIsInZhbGlkYXRlQ2xhc3NOYW1lRm9yVHJpZ2dlcnMiLCJjbGFzc05hbWUiLCJ0eXBlIiwicmVzdHJpY3RlZENsYXNzTmFtZXMiLCJpbmRleE9mIiwiX3RyaWdnZXJTdG9yZSIsImZ1bmN0aW9uTmFtZSIsImhhbmRsZXIiLCJ2YWxpZGF0aW9uSGFuZGxlciIsImFwcGxpY2F0aW9uSWQiLCJQYXJzZSIsImpvYk5hbWUiLCJwdXNoIiwiZm9yRWFjaCIsImFwcElkIiwidHJpZ2dlclR5cGUiLCJtYW5hZ2VyIiwidW5kZWZpbmVkIiwiYXV0aCIsInBhcnNlT2JqZWN0Iiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImNvbmZpZyIsInJlcXVlc3QiLCJ0cmlnZ2VyTmFtZSIsIm9iamVjdCIsIm1hc3RlciIsImxvZyIsImxvZ2dlckNvbnRyb2xsZXIiLCJoZWFkZXJzIiwiaXAiLCJvcmlnaW5hbCIsImlzTWFzdGVyIiwidXNlciIsImluc3RhbGxhdGlvbklkIiwicXVlcnkiLCJjb3VudCIsImlzR2V0IiwicmVzb2x2ZSIsInJlamVjdCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsIm9iamVjdHMiLCJtYXAiLCJ0b0pTT04iLCJlcXVhbHMiLCJfZ2V0U2F2ZUpTT04iLCJlcnJvciIsImNvZGUiLCJtZXNzYWdlIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwic2NyaXB0RXJyb3IiLCJ1c2VySWRGb3JMb2ciLCJpZCIsImxvZ1RyaWdnZXJBZnRlckhvb2siLCJpbnB1dCIsImNsZWFuSW5wdXQiLCJsb2dnZXIiLCJ0cnVuY2F0ZUxvZ01lc3NhZ2UiLCJKU09OIiwic3RyaW5naWZ5IiwiaW5mbyIsImxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayIsInJlc3VsdCIsImNsZWFuUmVzdWx0IiwibG9nVHJpZ2dlckVycm9yQmVmb3JlSG9vayIsIlByb21pc2UiLCJ0cmlnZ2VyIiwiZnJvbUpTT04iLCJ0cmlnZ2VyUHJvbWlzZSIsInRoZW4iLCJwcm9taXNlUmVzdWx0cyIsInJlc3VsdHMiLCJyZXN0V2hlcmUiLCJyZXN0T3B0aW9ucyIsInBhcnNlUXVlcnkiLCJRdWVyeSIsIl93aGVyZSIsImluY2x1ZGUiLCJsZW5ndGgiLCJfaW5jbHVkZSIsInNwbGl0Iiwic2tpcCIsIl9za2lwIiwibGltaXQiLCJfbGltaXQiLCJyZXF1ZXN0T2JqZWN0IiwicXVlcnlSZXN1bHQiLCJqc29uUXVlcnkiLCJ3aGVyZSIsIm9yZGVyIiwicmVhZFByZWZlcmVuY2UiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwiZXJyIiwiamF2YXNjcmlwdEtleSIsIm1hc3RlcktleSIsImRhdGEiLCJyZXN0T2JqZWN0IiwiY29w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QUFaLEVBQXhELEVBQThFekIsSUFBOUU7QUFDQSxVQUFHbUQsa0JBQWtCLE9BQU9BLGVBQWVDLElBQXRCLEtBQStCLFVBQXBELEVBQWdFO0FBQzlELGVBQU9ELGVBQWVDLElBQWYsQ0FBb0JqQyxPQUFwQixFQUE2QkEsT0FBN0IsQ0FBUDtBQUNELE9BRkQsTUFHSztBQUNILGVBQU9BLFNBQVA7QUFDRDtBQUNGO0FBQ0YsR0FsQ00sQ0FBUDtBQW1DRDs7QUFFRDtBQUNBO0FBQ08sU0FBUzFELE9BQVQsQ0FBaUJzSCxJQUFqQixFQUF1QkMsVUFBdkIsRUFBbUM7QUFDeEMsTUFBSUMsT0FBTyxPQUFPRixJQUFQLElBQWUsUUFBZixHQUEwQkEsSUFBMUIsR0FBaUMsRUFBQ2hHLFdBQVdnRyxJQUFaLEVBQTVDO0FBQ0EsT0FBSyxJQUFJbkcsR0FBVCxJQUFnQm9HLFVBQWhCLEVBQTRCO0FBQzFCQyxTQUFLckcsR0FBTCxJQUFZb0csV0FBV3BHLEdBQVgsQ0FBWjtBQUNEO0FBQ0QsU0FBT1ksZUFBTWhCLE1BQU4sQ0FBYTBFLFFBQWIsQ0FBc0IrQixJQUF0QixDQUFQO0FBQ0Q7O0FBRU0sU0FBU3ZILHlCQUFULENBQW1DcUgsSUFBbkMsRUFBeUN4RixnQkFBZ0JDLGVBQU1ELGFBQS9ELEVBQThFO0FBQ25GLE1BQUksQ0FBQ0osYUFBRCxJQUFrQixDQUFDQSxjQUFjSSxhQUFkLENBQW5CLElBQW1ELENBQUNKLGNBQWNJLGFBQWQsRUFBNkJqQixTQUFyRixFQUFnRztBQUFFO0FBQVM7QUFDM0dhLGdCQUFjSSxhQUFkLEVBQTZCakIsU0FBN0IsQ0FBdUNxQixPQUF2QyxDQUFnRE4sT0FBRCxJQUFhQSxRQUFRMEYsSUFBUixDQUE1RDtBQUNEIiwiZmlsZSI6InRyaWdnZXJzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHJpZ2dlcnMuanNcbmltcG9ydCBQYXJzZSAgICBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcblxuZXhwb3J0IGNvbnN0IFR5cGVzID0ge1xuICBiZWZvcmVTYXZlOiAnYmVmb3JlU2F2ZScsXG4gIGFmdGVyU2F2ZTogJ2FmdGVyU2F2ZScsXG4gIGJlZm9yZURlbGV0ZTogJ2JlZm9yZURlbGV0ZScsXG4gIGFmdGVyRGVsZXRlOiAnYWZ0ZXJEZWxldGUnLFxuICBiZWZvcmVGaW5kOiAnYmVmb3JlRmluZCcsXG4gIGFmdGVyRmluZDogJ2FmdGVyRmluZCdcbn07XG5cbmNvbnN0IGJhc2VTdG9yZSA9IGZ1bmN0aW9uKCkge1xuICBjb25zdCBWYWxpZGF0b3JzID0ge307XG4gIGNvbnN0IEZ1bmN0aW9ucyA9IHt9O1xuICBjb25zdCBKb2JzID0ge307XG4gIGNvbnN0IExpdmVRdWVyeSA9IFtdO1xuICBjb25zdCBUcmlnZ2VycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24oYmFzZSwga2V5KXtcbiAgICBiYXNlW2tleV0gPSB7fTtcbiAgICByZXR1cm4gYmFzZTtcbiAgfSwge30pO1xuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBGdW5jdGlvbnMsXG4gICAgSm9icyxcbiAgICBWYWxpZGF0b3JzLFxuICAgIFRyaWdnZXJzLFxuICAgIExpdmVRdWVyeSxcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSkge1xuICBjb25zdCByZXN0cmljdGVkQ2xhc3NOYW1lcyA9IFsgJ19TZXNzaW9uJyBdO1xuICBpZiAocmVzdHJpY3RlZENsYXNzTmFtZXMuaW5kZXhPZihjbGFzc05hbWUpICE9IC0xKSB7XG4gICAgdGhyb3cgYFRyaWdnZXJzIGFyZSBub3Qgc3VwcG9ydGVkIGZvciAke2NsYXNzTmFtZX0gY2xhc3MuYDtcbiAgfVxuICBpZiAodHlwZSA9PSBUeXBlcy5iZWZvcmVTYXZlICYmIGNsYXNzTmFtZSA9PT0gJ19QdXNoU3RhdHVzJykge1xuICAgIC8vIF9QdXNoU3RhdHVzIHVzZXMgdW5kb2N1bWVudGVkIG5lc3RlZCBrZXkgaW5jcmVtZW50IG9wc1xuICAgIC8vIGFsbG93aW5nIGJlZm9yZVNhdmUgd291bGQgbWVzcyB1cCB0aGUgb2JqZWN0cyBiaWcgdGltZVxuICAgIC8vIFRPRE86IEFsbG93IHByb3BlciBkb2N1bWVudGVkIHdheSBvZiB1c2luZyBuZXN0ZWQgaW5jcmVtZW50IG9wc1xuICAgIHRocm93ICdPbmx5IGFmdGVyU2F2ZSBpcyBhbGxvd2VkIG9uIF9QdXNoU3RhdHVzJztcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lO1xufVxuXG5jb25zdCBfdHJpZ2dlclN0b3JlID0ge307XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFwcGxpY2F0aW9uSWQgPSBhcHBsaWNhdGlvbklkIHx8IFBhcnNlLmFwcGxpY2F0aW9uSWQ7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gPSAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5GdW5jdGlvbnNbZnVuY3Rpb25OYW1lXSA9IGhhbmRsZXI7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0uVmFsaWRhdG9yc1tmdW5jdGlvbk5hbWVdID0gdmFsaWRhdGlvbkhhbmRsZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRKb2Ioam9iTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gfHwgYmFzZVN0b3JlKCk7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0uSm9ic1tqb2JOYW1lXSA9IGhhbmRsZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRUcmlnZ2VyKHR5cGUsIGNsYXNzTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSk7XG4gIGFwcGxpY2F0aW9uSWQgPSBhcHBsaWNhdGlvbklkIHx8IFBhcnNlLmFwcGxpY2F0aW9uSWQ7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gPSAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5UcmlnZ2Vyc1t0eXBlXVtjbGFzc05hbWVdID0gaGFuZGxlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZExpdmVRdWVyeUV2ZW50SGFuZGxlcihoYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFwcGxpY2F0aW9uSWQgPSBhcHBsaWNhdGlvbklkIHx8IFBhcnNlLmFwcGxpY2F0aW9uSWQ7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gPSAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkucHVzaChoYW5kbGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBkZWxldGUgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5GdW5jdGlvbnNbZnVuY3Rpb25OYW1lXVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJpZ2dlcih0eXBlLCBjbGFzc05hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgYXBwbGljYXRpb25JZCA9IGFwcGxpY2F0aW9uSWQgfHwgUGFyc2UuYXBwbGljYXRpb25JZDtcbiAgZGVsZXRlIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0uVHJpZ2dlcnNbdHlwZV1bY2xhc3NOYW1lXVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX3VucmVnaXN0ZXJBbGwoKSB7XG4gIE9iamVjdC5rZXlzKF90cmlnZ2VyU3RvcmUpLmZvckVhY2goYXBwSWQgPT4gZGVsZXRlIF90cmlnZ2VyU3RvcmVbYXBwSWRdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgYXBwbGljYXRpb25JZCkge1xuICBpZiAoIWFwcGxpY2F0aW9uSWQpIHtcbiAgICB0aHJvdyBcIk1pc3NpbmcgQXBwbGljYXRpb25JRFwiO1xuICB9XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXVxuICBpZiAobWFuYWdlclxuICAgICYmIG1hbmFnZXIuVHJpZ2dlcnNcbiAgICAmJiBtYW5hZ2VyLlRyaWdnZXJzW3RyaWdnZXJUeXBlXVxuICAgICYmIG1hbmFnZXIuVHJpZ2dlcnNbdHJpZ2dlclR5cGVdW2NsYXNzTmFtZV0pIHtcbiAgICByZXR1cm4gbWFuYWdlci5UcmlnZ2Vyc1t0cmlnZ2VyVHlwZV1bY2xhc3NOYW1lXTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJpZ2dlckV4aXN0cyhjbGFzc05hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nLCBhcHBsaWNhdGlvbklkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIChnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHlwZSwgYXBwbGljYXRpb25JZCkgIT0gdW5kZWZpbmVkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICB2YXIgbWFuYWdlciA9IF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF07XG4gIGlmIChtYW5hZ2VyICYmIG1hbmFnZXIuRnVuY3Rpb25zKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuRnVuY3Rpb25zW2Z1bmN0aW9uTmFtZV07XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEpvYihqb2JOYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5Kb2JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuSm9ic1tqb2JOYW1lXTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Sm9icyhhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5Kb2JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuSm9icztcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWYWxpZGF0b3IoZnVuY3Rpb25OYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5WYWxpZGF0b3JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuVmFsaWRhdG9yc1tmdW5jdGlvbk5hbWVdO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0T2JqZWN0KHRyaWdnZXJUeXBlLCBhdXRoLCBwYXJzZU9iamVjdCwgb3JpZ2luYWxQYXJzZU9iamVjdCwgY29uZmlnKSB7XG4gIHZhciByZXF1ZXN0ID0ge1xuICAgIHRyaWdnZXJOYW1lOiB0cmlnZ2VyVHlwZSxcbiAgICBvYmplY3Q6IHBhcnNlT2JqZWN0LFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICB9O1xuXG4gIGlmIChvcmlnaW5hbFBhcnNlT2JqZWN0KSB7XG4gICAgcmVxdWVzdC5vcmlnaW5hbCA9IG9yaWdpbmFsUGFyc2VPYmplY3Q7XG4gIH1cblxuICBpZiAoIWF1dGgpIHtcbiAgICByZXR1cm4gcmVxdWVzdDtcbiAgfVxuICBpZiAoYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcXVlc3RbJ21hc3RlciddID0gdHJ1ZTtcbiAgfVxuICBpZiAoYXV0aC51c2VyKSB7XG4gICAgcmVxdWVzdFsndXNlciddID0gYXV0aC51c2VyO1xuICB9XG4gIGlmIChhdXRoLmluc3RhbGxhdGlvbklkKSB7XG4gICAgcmVxdWVzdFsnaW5zdGFsbGF0aW9uSWQnXSA9IGF1dGguaW5zdGFsbGF0aW9uSWQ7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0UXVlcnlPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHF1ZXJ5LCBjb3VudCwgY29uZmlnLCBpc0dldCkge1xuICBpc0dldCA9ICEhaXNHZXQ7XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIHF1ZXJ5LFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgY291bnQsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBpc0dldCxcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuLy8gQ3JlYXRlcyB0aGUgcmVzcG9uc2Ugb2JqZWN0LCBhbmQgdXNlcyB0aGUgcmVxdWVzdCBvYmplY3QgdG8gcGFzcyBkYXRhXG4vLyBUaGUgQVBJIHdpbGwgY2FsbCB0aGlzIHdpdGggUkVTVCBBUEkgZm9ybWF0dGVkIG9iamVjdHMsIHRoaXMgd2lsbFxuLy8gdHJhbnNmb3JtIHRoZW0gdG8gUGFyc2UuT2JqZWN0IGluc3RhbmNlcyBleHBlY3RlZCBieSBDbG91ZCBDb2RlLlxuLy8gQW55IGNoYW5nZXMgbWFkZSB0byB0aGUgb2JqZWN0IGluIGEgYmVmb3JlU2F2ZSB3aWxsIGJlIGluY2x1ZGVkLlxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsIHJlc29sdmUsIHJlamVjdCkge1xuICByZXR1cm4ge1xuICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYWZ0ZXJGaW5kKSB7XG4gICAgICAgIGlmKCFyZXNwb25zZSl7XG4gICAgICAgICAgcmVzcG9uc2UgPSByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZS5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0LnRvSlNPTigpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHRoZSBKU09OIHJlc3BvbnNlXG4gICAgICBpZiAocmVzcG9uc2UgJiYgIXJlcXVlc3Qub2JqZWN0LmVxdWFscyhyZXNwb25zZSlcbiAgICAgICAgICAmJiByZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5iZWZvcmVTYXZlKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSkge1xuICAgICAgICByZXNwb25zZVsnb2JqZWN0J10gPSByZXF1ZXN0Lm9iamVjdC5fZ2V0U2F2ZUpTT04oKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICB9LFxuICAgIGVycm9yOiBmdW5jdGlvbihjb2RlLCBtZXNzYWdlKSB7XG4gICAgICBpZiAoIW1lc3NhZ2UpIHtcbiAgICAgICAgaWYgKGNvZGUgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgICAgIHJldHVybiByZWplY3QoY29kZSlcbiAgICAgICAgfVxuICAgICAgICBtZXNzYWdlID0gY29kZTtcbiAgICAgICAgY29kZSA9IFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQ7XG4gICAgICB9XG4gICAgICB2YXIgc2NyaXB0RXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoY29kZSwgbWVzc2FnZSk7XG4gICAgICByZXR1cm4gcmVqZWN0KHNjcmlwdEVycm9yKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXNlcklkRm9yTG9nKGF1dGgpIHtcbiAgcmV0dXJuIChhdXRoICYmIGF1dGgudXNlcikgPyBhdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIGF1dGgpIHtcbiAgY29uc3QgY2xlYW5JbnB1dCA9IGxvZ2dlci50cnVuY2F0ZUxvZ01lc3NhZ2UoSlNPTi5zdHJpbmdpZnkoaW5wdXQpKTtcbiAgbG9nZ2VyLmluZm8oYCR7dHJpZ2dlclR5cGV9IHRyaWdnZXJlZCBmb3IgJHtjbGFzc05hbWV9IGZvciB1c2VyICR7dXNlcklkRm9yTG9nKGF1dGgpfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9YCwge1xuICAgIGNsYXNzTmFtZSxcbiAgICB0cmlnZ2VyVHlwZSxcbiAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aClcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBpbnB1dCwgcmVzdWx0LCBhdXRoKSB7XG4gIGNvbnN0IGNsZWFuSW5wdXQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KGlucHV0KSk7XG4gIGNvbnN0IGNsZWFuUmVzdWx0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgbG9nZ2VyLmluZm8oYCR7dHJpZ2dlclR5cGV9IHRyaWdnZXJlZCBmb3IgJHtjbGFzc05hbWV9IGZvciB1c2VyICR7dXNlcklkRm9yTG9nKGF1dGgpfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9XFxuICBSZXN1bHQ6ICR7Y2xlYW5SZXN1bHR9YCwge1xuICAgIGNsYXNzTmFtZSxcbiAgICB0cmlnZ2VyVHlwZSxcbiAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aClcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIGF1dGgsIGVycm9yKSB7XG4gIGNvbnN0IGNsZWFuSW5wdXQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KGlucHV0KSk7XG4gIGxvZ2dlci5lcnJvcihgJHt0cmlnZ2VyVHlwZX0gZmFpbGVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coYXV0aCl9OlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1cXG4gIEVycm9yOiAke0pTT04uc3RyaW5naWZ5KGVycm9yKX1gLCB7XG4gICAgY2xhc3NOYW1lLFxuICAgIHRyaWdnZXJUeXBlLFxuICAgIGVycm9yLFxuICAgIHVzZXI6IHVzZXJJZEZvckxvZyhhdXRoKVxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuQWZ0ZXJGaW5kVHJpZ2dlcih0cmlnZ2VyVHlwZSwgYXV0aCwgY2xhc3NOYW1lLCBvYmplY3RzLCBjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgbnVsbCwgbnVsbCwgY29uZmlnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsXG4gICAgICBvYmplY3QgPT4ge1xuICAgICAgICByZXNvbHZlKG9iamVjdCk7XG4gICAgICB9LFxuICAgICAgZXJyb3IgPT4ge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsICdBZnRlckZpbmQnLCBKU09OLnN0cmluZ2lmeShvYmplY3RzKSwgYXV0aCk7XG4gICAgcmVxdWVzdC5vYmplY3RzID0gb2JqZWN0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgIC8vc2V0dGluZyB0aGUgY2xhc3MgbmFtZSB0byB0cmFuc2Zvcm0gaW50byBwYXJzZSBvYmplY3RcbiAgICAgIG9iamVjdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICByZXR1cm4gUGFyc2UuT2JqZWN0LmZyb21KU09OKG9iamVjdCk7XG4gICAgfSk7XG4gICAgY29uc3QgdHJpZ2dlclByb21pc2UgPSB0cmlnZ2VyKHJlcXVlc3QsIHJlc3BvbnNlKTtcbiAgICBpZiAodHJpZ2dlclByb21pc2UgJiYgdHlwZW9mIHRyaWdnZXJQcm9taXNlLnRoZW4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgcmV0dXJuIHRyaWdnZXJQcm9taXNlLnRoZW4ocHJvbWlzZVJlc3VsdHMgPT4ge1xuICAgICAgICBpZihwcm9taXNlUmVzdWx0cykge1xuICAgICAgICAgIHJlc29sdmUocHJvbWlzZVJlc3VsdHMpO1xuICAgICAgICB9ZWxzZXtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVELCBcIkFmdGVyRmluZCBleHBlY3QgcmVzdWx0cyB0byBiZSByZXR1cm5lZCBpbiB0aGUgcHJvbWlzZVwiKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfSkudGhlbigocmVzdWx0cykgPT4ge1xuICAgIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgSlNPTi5zdHJpbmdpZnkocmVzdWx0cyksIGF1dGgpO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuUXVlcnlUcmlnZ2VyKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9wdGlvbnMsIGNvbmZpZywgYXV0aCwgaXNHZXQpIHtcbiAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICBpZiAoIXRyaWdnZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHJlc3RXaGVyZSxcbiAgICAgIHJlc3RPcHRpb25zXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBwYXJzZVF1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KGNsYXNzTmFtZSk7XG4gIGlmIChyZXN0V2hlcmUpIHtcbiAgICBwYXJzZVF1ZXJ5Ll93aGVyZSA9IHJlc3RXaGVyZTtcbiAgfVxuICBsZXQgY291bnQgPSBmYWxzZTtcbiAgaWYgKHJlc3RPcHRpb25zKSB7XG4gICAgaWYgKHJlc3RPcHRpb25zLmluY2x1ZGUgJiYgcmVzdE9wdGlvbnMuaW5jbHVkZS5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJzZVF1ZXJ5Ll9pbmNsdWRlID0gcmVzdE9wdGlvbnMuaW5jbHVkZS5zcGxpdCgnLCcpO1xuICAgIH1cbiAgICBpZiAocmVzdE9wdGlvbnMuc2tpcCkge1xuICAgICAgcGFyc2VRdWVyeS5fc2tpcCA9IHJlc3RPcHRpb25zLnNraXA7XG4gICAgfVxuICAgIGlmIChyZXN0T3B0aW9ucy5saW1pdCkge1xuICAgICAgcGFyc2VRdWVyeS5fbGltaXQgPSByZXN0T3B0aW9ucy5saW1pdDtcbiAgICB9XG4gICAgY291bnQgPSAhIXJlc3RPcHRpb25zLmNvdW50O1xuICB9XG4gIGNvbnN0IHJlcXVlc3RPYmplY3QgPSBnZXRSZXF1ZXN0UXVlcnlPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHBhcnNlUXVlcnksIGNvdW50LCBjb25maWcsIGlzR2V0KTtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xuICAgIHJldHVybiB0cmlnZ2VyKHJlcXVlc3RPYmplY3QpO1xuICB9KS50aGVuKChyZXN1bHQpID0+IHtcbiAgICBsZXQgcXVlcnlSZXN1bHQgPSBwYXJzZVF1ZXJ5O1xuICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0IGluc3RhbmNlb2YgUGFyc2UuUXVlcnkpIHtcbiAgICAgIHF1ZXJ5UmVzdWx0ID0gcmVzdWx0O1xuICAgIH1cbiAgICBjb25zdCBqc29uUXVlcnkgPSBxdWVyeVJlc3VsdC50b0pTT04oKTtcbiAgICBpZiAoanNvblF1ZXJ5LndoZXJlKSB7XG4gICAgICByZXN0V2hlcmUgPSBqc29uUXVlcnkud2hlcmU7XG4gICAgfVxuICAgIGlmIChqc29uUXVlcnkubGltaXQpIHtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICByZXN0T3B0aW9ucy5saW1pdCA9IGpzb25RdWVyeS5saW1pdDtcbiAgICB9XG4gICAgaWYgKGpzb25RdWVyeS5za2lwKSB7XG4gICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgcmVzdE9wdGlvbnMuc2tpcCA9IGpzb25RdWVyeS5za2lwO1xuICAgIH1cbiAgICBpZiAoanNvblF1ZXJ5LmluY2x1ZGUpIHtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICByZXN0T3B0aW9ucy5pbmNsdWRlID0ganNvblF1ZXJ5LmluY2x1ZGU7XG4gICAgfVxuICAgIGlmIChqc29uUXVlcnkua2V5cykge1xuICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgIHJlc3RPcHRpb25zLmtleXMgPSBqc29uUXVlcnkua2V5cztcbiAgICB9XG4gICAgaWYgKGpzb25RdWVyeS5vcmRlcikge1xuICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgIHJlc3RPcHRpb25zLm9yZGVyID0ganNvblF1ZXJ5Lm9yZGVyO1xuICAgIH1cbiAgICBpZiAocmVxdWVzdE9iamVjdC5yZWFkUHJlZmVyZW5jZSkge1xuICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgIHJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5yZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgaWYgKHJlcXVlc3RPYmplY3QuaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5pbmNsdWRlUmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmIChyZXF1ZXN0T2JqZWN0LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICByZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgcmVzdFdoZXJlLFxuICAgICAgcmVzdE9wdGlvbnNcbiAgICB9O1xuICB9LCAoZXJyKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMSwgZXJyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfSk7XG59XG5cbi8vIFRvIGJlIHVzZWQgYXMgcGFydCBvZiB0aGUgcHJvbWlzZSBjaGFpbiB3aGVuIHNhdmluZy9kZWxldGluZyBhbiBvYmplY3Rcbi8vIFdpbGwgcmVzb2x2ZSBzdWNjZXNzZnVsbHkgaWYgbm8gdHJpZ2dlciBpcyBjb25maWd1cmVkXG4vLyBSZXNvbHZlcyB0byBhbiBvYmplY3QsIGVtcHR5IG9yIGNvbnRhaW5pbmcgYW4gb2JqZWN0IGtleS4gQSBiZWZvcmVTYXZlXG4vLyB0cmlnZ2VyIHdpbGwgc2V0IHRoZSBvYmplY3Qga2V5IHRvIHRoZSByZXN0IGZvcm1hdCBvYmplY3QgdG8gc2F2ZS5cbi8vIG9yaWdpbmFsUGFyc2VPYmplY3QgaXMgb3B0aW9uYWwsIHdlIG9ubHkgbmVlZCB0aGF0IGZvciBiZWZvcmUvYWZ0ZXJTYXZlIGZ1bmN0aW9uc1xuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuVHJpZ2dlcih0cmlnZ2VyVHlwZSwgYXV0aCwgcGFyc2VPYmplY3QsIG9yaWdpbmFsUGFyc2VPYmplY3QsIGNvbmZpZykge1xuICBpZiAoIXBhcnNlT2JqZWN0KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgdHJpZ2dlciA9IGdldFRyaWdnZXIocGFyc2VPYmplY3QuY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICAgIGlmICghdHJpZ2dlcikgcmV0dXJuIHJlc29sdmUoKTtcbiAgICB2YXIgcmVxdWVzdCA9IGdldFJlcXVlc3RPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHBhcnNlT2JqZWN0LCBvcmlnaW5hbFBhcnNlT2JqZWN0LCBjb25maWcpO1xuICAgIHZhciByZXNwb25zZSA9IGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsIChvYmplY3QpID0+IHtcbiAgICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSwgcGFyc2VPYmplY3QudG9KU09OKCksIG9iamVjdCwgYXV0aCk7XG4gICAgICByZXNvbHZlKG9iamVjdCk7XG4gICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICBsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rKFxuICAgICAgICB0cmlnZ2VyVHlwZSwgcGFyc2VPYmplY3QuY2xhc3NOYW1lLCBwYXJzZU9iamVjdC50b0pTT04oKSwgYXV0aCwgZXJyb3IpO1xuICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICB9KTtcbiAgICAvLyBGb3JjZSB0aGUgY3VycmVudCBQYXJzZSBhcHAgYmVmb3JlIHRoZSB0cmlnZ2VyXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCA9IGNvbmZpZy5hcHBsaWNhdGlvbklkO1xuICAgIFBhcnNlLmphdmFzY3JpcHRLZXkgPSBjb25maWcuamF2YXNjcmlwdEtleSB8fCAnJztcbiAgICBQYXJzZS5tYXN0ZXJLZXkgPSBjb25maWcubWFzdGVyS2V5O1xuXG4gICAgLy8gQWZ0ZXJTYXZlIGFuZCBhZnRlckRlbGV0ZSB0cmlnZ2VycyBjYW4gcmV0dXJuIGEgcHJvbWlzZSwgd2hpY2ggaWYgdGhleVxuICAgIC8vIGRvLCBuZWVkcyB0byBiZSByZXNvbHZlZCBiZWZvcmUgdGhpcyBwcm9taXNlIGlzIHJlc29sdmVkLFxuICAgIC8vIHNvIHRyaWdnZXIgZXhlY3V0aW9uIGlzIHN5bmNlZCB3aXRoIFJlc3RXcml0ZS5leGVjdXRlKCkgY2FsbC5cbiAgICAvLyBJZiB0cmlnZ2VycyBkbyBub3QgcmV0dXJuIGEgcHJvbWlzZSwgdGhleSBjYW4gcnVuIGFzeW5jIGNvZGUgcGFyYWxsZWxcbiAgICAvLyB0byB0aGUgUmVzdFdyaXRlLmV4ZWN1dGUoKSBjYWxsLlxuICAgIHZhciB0cmlnZ2VyUHJvbWlzZSA9IHRyaWdnZXIocmVxdWVzdCwgcmVzcG9uc2UpO1xuICAgIGlmKHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlclNhdmUgfHwgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyRGVsZXRlKVxuICAgIHtcbiAgICAgIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSwgcGFyc2VPYmplY3QudG9KU09OKCksIGF1dGgpO1xuICAgICAgaWYodHJpZ2dlclByb21pc2UgJiYgdHlwZW9mIHRyaWdnZXJQcm9taXNlLnRoZW4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gdHJpZ2dlclByb21pc2UudGhlbihyZXNvbHZlLCByZXNvbHZlKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbi8vIENvbnZlcnRzIGEgUkVTVC1mb3JtYXQgb2JqZWN0IHRvIGEgUGFyc2UuT2JqZWN0XG4vLyBkYXRhIGlzIGVpdGhlciBjbGFzc05hbWUgb3IgYW4gb2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gaW5mbGF0ZShkYXRhLCByZXN0T2JqZWN0KSB7XG4gIHZhciBjb3B5ID0gdHlwZW9mIGRhdGEgPT0gJ29iamVjdCcgPyBkYXRhIDoge2NsYXNzTmFtZTogZGF0YX07XG4gIGZvciAodmFyIGtleSBpbiByZXN0T2JqZWN0KSB7XG4gICAgY29weVtrZXldID0gcmVzdE9iamVjdFtrZXldO1xuICB9XG4gIHJldHVybiBQYXJzZS5PYmplY3QuZnJvbUpTT04oY29weSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKGRhdGEsIGFwcGxpY2F0aW9uSWQgPSBQYXJzZS5hcHBsaWNhdGlvbklkKSB7XG4gIGlmICghX3RyaWdnZXJTdG9yZSB8fCAhX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCAhX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkpIHsgcmV0dXJuOyB9XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0uTGl2ZVF1ZXJ5LmZvckVhY2goKGhhbmRsZXIpID0+IGhhbmRsZXIoZGF0YSkpO1xufVxuIl19
844
+ function getRequestFileObject(triggerType, auth, fileObject, config) {
845
+ const request = {
846
+ ...fileObject,
847
+ triggerName: triggerType,
848
+ master: false,
849
+ log: config.loggerController,
850
+ headers: config.headers,
851
+ ip: config.ip,
852
+ config
853
+ };
854
+ if (!auth) {
855
+ return request;
856
+ }
857
+ if (auth.isMaster) {
858
+ request['master'] = true;
859
+ }
860
+ if (auth.user) {
861
+ request['user'] = auth.user;
862
+ }
863
+ if (auth.installationId) {
864
+ request['installationId'] = auth.installationId;
865
+ }
866
+ return request;
867
+ }
868
+ async function maybeRunFileTrigger(triggerType, fileObject, config, auth) {
869
+ const FileClassName = getClassName(_node.default.File);
870
+ const fileTrigger = getTrigger(FileClassName, triggerType, config.applicationId);
871
+ if (typeof fileTrigger === 'function') {
872
+ try {
873
+ const request = getRequestFileObject(triggerType, auth, fileObject, config);
874
+ await maybeRunValidator(request, `${triggerType}.${FileClassName}`, auth);
875
+ if (request.skipWithMasterKey) {
876
+ return fileObject;
877
+ }
878
+ const result = await fileTrigger(request);
879
+ if (request.forceDownload) {
880
+ fileObject.forceDownload = true;
881
+ }
882
+ logTriggerSuccessBeforeHook(triggerType, 'Parse.File', {
883
+ ...fileObject.file.toJSON(),
884
+ fileSize: fileObject.fileSize
885
+ }, result, auth, config.logLevels.triggerBeforeSuccess);
886
+ return result || fileObject;
887
+ } catch (error) {
888
+ logTriggerErrorBeforeHook(triggerType, 'Parse.File', {
889
+ ...fileObject.file.toJSON(),
890
+ fileSize: fileObject.fileSize
891
+ }, auth, error, config.logLevels.triggerBeforeError);
892
+ throw error;
893
+ }
894
+ }
895
+ return fileObject;
896
+ }
897
+ async function maybeRunGlobalConfigTrigger(triggerType, auth, configObject, originalConfigObject, config, context) {
898
+ const GlobalConfigClassName = getClassName(_node.default.Config);
899
+ const configTrigger = getTrigger(GlobalConfigClassName, triggerType, config.applicationId);
900
+ if (typeof configTrigger === 'function') {
901
+ try {
902
+ const request = getRequestObject(triggerType, auth, configObject, originalConfigObject, config, context);
903
+ await maybeRunValidator(request, `${triggerType}.${GlobalConfigClassName}`, auth);
904
+ if (request.skipWithMasterKey) {
905
+ return configObject;
906
+ }
907
+ const result = await configTrigger(request);
908
+ logTriggerSuccessBeforeHook(triggerType, 'Parse.Config', configObject, result, auth, config.logLevels.triggerBeforeSuccess);
909
+ return result || configObject;
910
+ } catch (error) {
911
+ logTriggerErrorBeforeHook(triggerType, 'Parse.Config', configObject, auth, error, config.logLevels.triggerBeforeError);
912
+ throw error;
913
+ }
914
+ }
915
+ return configObject;
916
+ }
917
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbm9kZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2xvZ2dlciIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsIlR5cGVzIiwiZXhwb3J0cyIsImJlZm9yZUxvZ2luIiwiYWZ0ZXJMb2dpbiIsImFmdGVyTG9nb3V0IiwiYmVmb3JlUGFzc3dvcmRSZXNldFJlcXVlc3QiLCJiZWZvcmVTYXZlIiwiYWZ0ZXJTYXZlIiwiYmVmb3JlRGVsZXRlIiwiYWZ0ZXJEZWxldGUiLCJiZWZvcmVGaW5kIiwiYWZ0ZXJGaW5kIiwiYmVmb3JlQ29ubmVjdCIsImJlZm9yZVN1YnNjcmliZSIsImFmdGVyRXZlbnQiLCJDb25uZWN0Q2xhc3NOYW1lIiwiYmFzZVN0b3JlIiwiVmFsaWRhdG9ycyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJiYXNlIiwia2V5IiwiRnVuY3Rpb25zIiwiSm9icyIsIkxpdmVRdWVyeSIsIlRyaWdnZXJzIiwiZnJlZXplIiwiZ2V0Q2xhc3NOYW1lIiwicGFyc2VDbGFzcyIsImNsYXNzTmFtZSIsIm5hbWUiLCJyZXBsYWNlIiwidmFsaWRhdGVDbGFzc05hbWVGb3JUcmlnZ2VycyIsInR5cGUiLCJfdHJpZ2dlclN0b3JlIiwiQ2F0ZWdvcnkiLCJnZXRTdG9yZSIsImNhdGVnb3J5IiwiYXBwbGljYXRpb25JZCIsImludmFsaWROYW1lUmVnZXgiLCJ0ZXN0IiwicGF0aCIsInNwbGl0Iiwic3BsaWNlIiwiUGFyc2UiLCJzdG9yZSIsImNvbXBvbmVudCIsImFkZCIsImhhbmRsZXIiLCJsYXN0Q29tcG9uZW50IiwibG9nZ2VyIiwid2FybiIsInJlbW92ZSIsImdldCIsImFkZEZ1bmN0aW9uIiwiZnVuY3Rpb25OYW1lIiwidmFsaWRhdGlvbkhhbmRsZXIiLCJhZGRKb2IiLCJqb2JOYW1lIiwiYWRkVHJpZ2dlciIsImFkZENvbm5lY3RUcmlnZ2VyIiwiYWRkTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVyIiwicHVzaCIsInJlbW92ZUZ1bmN0aW9uIiwicmVtb3ZlVHJpZ2dlciIsIl91bnJlZ2lzdGVyQWxsIiwiZm9yRWFjaCIsImFwcElkIiwidG9KU09Od2l0aE9iamVjdHMiLCJvYmplY3QiLCJ0b0pTT04iLCJzdGF0ZUNvbnRyb2xsZXIiLCJDb3JlTWFuYWdlciIsImdldE9iamVjdFN0YXRlQ29udHJvbGxlciIsInBlbmRpbmciLCJnZXRQZW5kaW5nT3BzIiwiX2dldFN0YXRlSWRlbnRpZmllciIsInZhbCIsIl90b0Z1bGxKU09OIiwiZ2V0VHJpZ2dlciIsInRyaWdnZXJUeXBlIiwicnVuVHJpZ2dlciIsInRyaWdnZXIiLCJyZXF1ZXN0IiwiYXV0aCIsIm1heWJlUnVuVmFsaWRhdG9yIiwic2tpcFdpdGhNYXN0ZXJLZXkiLCJ0cmlnZ2VyRXhpc3RzIiwidW5kZWZpbmVkIiwiZ2V0RnVuY3Rpb24iLCJnZXRGdW5jdGlvbk5hbWVzIiwiZnVuY3Rpb25OYW1lcyIsImV4dHJhY3RGdW5jdGlvbk5hbWVzIiwibmFtZXNwYWNlIiwidmFsdWUiLCJnZXRKb2IiLCJnZXRKb2JzIiwibWFuYWdlciIsImdldFZhbGlkYXRvciIsImdldFJlcXVlc3RPYmplY3QiLCJwYXJzZU9iamVjdCIsIm9yaWdpbmFsUGFyc2VPYmplY3QiLCJjb25maWciLCJjb250ZXh0IiwiaXNHZXQiLCJ0cmlnZ2VyTmFtZSIsIm1hc3RlciIsImxvZyIsImxvZ2dlckNvbnRyb2xsZXIiLCJoZWFkZXJzIiwiaXAiLCJvcmlnaW5hbCIsImFzc2lnbiIsImlzTWFzdGVyIiwidXNlciIsImluc3RhbGxhdGlvbklkIiwiZ2V0UmVxdWVzdFF1ZXJ5T2JqZWN0IiwicXVlcnkiLCJjb3VudCIsImdldFJlc3BvbnNlT2JqZWN0IiwicmVzb2x2ZSIsInJlamVjdCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsIm9iamVjdHMiLCJtYXAiLCJlcXVhbHMiLCJfZ2V0U2F2ZUpTT04iLCJpZCIsImVycm9yIiwicmVzb2x2ZUVycm9yIiwiY29kZSIsIkVycm9yIiwiU0NSSVBUX0ZBSUxFRCIsIm1lc3NhZ2UiLCJ1c2VySWRGb3JMb2ciLCJsb2dUcmlnZ2VyQWZ0ZXJIb29rIiwiaW5wdXQiLCJsb2dMZXZlbCIsImNsZWFuSW5wdXQiLCJ0cnVuY2F0ZUxvZ01lc3NhZ2UiLCJKU09OIiwic3RyaW5naWZ5IiwibG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rIiwicmVzdWx0IiwiY2xlYW5SZXN1bHQiLCJsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rIiwibWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyIiwiY2xhc3NOYW1lUXVlcnkiLCJvYmplY3RzSW5wdXQiLCJQcm9taXNlIiwibGVuZ3RoIiwib2JqIiwiUXVlcnkiLCJwYXJzZVF1ZXJ5SW5zdGFuY2UiLCJ3aGVyZSIsIndpdGhKU09OIiwicHJvY2Vzc2VkT2JqZWN0c0pTT04iLCJlcnJvckRhdGEiLCJvIiwibG9nTGV2ZWxzIiwidHJpZ2dlckJlZm9yZVN1Y2Nlc3MiLCJjdXJyZW50T2JqZWN0Iiwib3JpZ2luYWxDbGFzc05hbWUiLCJ0ZW1wT2JqZWN0V2l0aENsYXNzTmFtZSIsImZyb21KU09OIiwidGhlbiIsInJlc3BvbnNlRnJvbVRyaWdnZXIiLCJyZXN1bHRzIiwicmVzdWx0c0FzSlNPTiIsInRyaWdnZXJBZnRlciIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJqc29uIiwicGFyc2VRdWVyeSIsInJlcXVlc3RPYmplY3QiLCJxdWVyeVJlc3VsdCIsImpzb25RdWVyeSIsImxpbWl0Iiwic2tpcCIsImluY2x1ZGUiLCJleGNsdWRlS2V5cyIsImV4cGxhaW4iLCJvcmRlciIsImhpbnQiLCJjb21tZW50IiwicmVhZFByZWZlcmVuY2UiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwiQXJyYXkiLCJpc0FycmF5IiwiZXZlcnkiLCJlcnIiLCJkZWZhdWx0T3B0cyIsInN0YWNrIiwidGhlVmFsaWRhdG9yIiwiYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IiLCJjYXRjaCIsIlZBTElEQVRJT05fRVJST1IiLCJvcHRpb25zIiwidmFsaWRhdGVNYXN0ZXJLZXkiLCJyZXFVc2VyIiwiZXhpc3RlZCIsInJlcXVpcmVVc2VyIiwicmVxdWlyZUFueVVzZXJSb2xlcyIsInJlcXVpcmVBbGxVc2VyUm9sZXMiLCJyZXF1aXJlTWFzdGVyIiwicGFyYW1zIiwicmVxdWlyZWRQYXJhbSIsInZhbGlkYXRlT3B0aW9ucyIsIm9wdCIsIm9wdHMiLCJpbmNsdWRlcyIsImpvaW4iLCJnZXRUeXBlIiwiZm4iLCJtYXRjaCIsInRvU3RyaW5nIiwidG9Mb3dlckNhc2UiLCJmaWVsZHMiLCJvcHRpb25Qcm9taXNlcyIsInNldCIsImNvbnN0YW50IiwicmV2ZXJ0IiwicmVxdWlyZWQiLCJvcHRpb25hbCIsInZhbFR5cGUiLCJhbGwiLCJ1c2VyUm9sZXMiLCJyZXF1aXJlQWxsUm9sZXMiLCJwcm9taXNlcyIsImdldFVzZXJSb2xlcyIsInJvbGVzIiwicmVzb2x2ZWRVc2VyUm9sZXMiLCJyZXNvbHZlZFJlcXVpcmVBbGwiLCJoYXNSb2xlIiwic29tZSIsInJlcXVpcmVkUm9sZSIsInVzZXJLZXlzIiwicmVxdWlyZVVzZXJLZXlzIiwibWF5YmVSdW5UcmlnZ2VyIiwic3RhcnRzV2l0aCIsInRyaWdnZXJCZWZvcmVFcnJvciIsInByb21pc2UiLCJpbmZsYXRlIiwiZGF0YSIsInJlc3RPYmplY3QiLCJjb3B5IiwicnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyIsImdldFJlcXVlc3RGaWxlT2JqZWN0IiwiZmlsZU9iamVjdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJGaWxlQ2xhc3NOYW1lIiwiRmlsZSIsImZpbGVUcmlnZ2VyIiwiZm9yY2VEb3dubG9hZCIsImZpbGUiLCJmaWxlU2l6ZSIsIm1heWJlUnVuR2xvYmFsQ29uZmlnVHJpZ2dlciIsImNvbmZpZ09iamVjdCIsIm9yaWdpbmFsQ29uZmlnT2JqZWN0IiwiR2xvYmFsQ29uZmlnQ2xhc3NOYW1lIiwiQ29uZmlnIiwiY29uZmlnVHJpZ2dlciJdLCJzb3VyY2VzIjpbIi4uL3NyYy90cmlnZ2Vycy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmlnZ2Vycy5qc1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuXG5leHBvcnQgY29uc3QgVHlwZXMgPSB7XG4gIGJlZm9yZUxvZ2luOiAnYmVmb3JlTG9naW4nLFxuICBhZnRlckxvZ2luOiAnYWZ0ZXJMb2dpbicsXG4gIGFmdGVyTG9nb3V0OiAnYWZ0ZXJMb2dvdXQnLFxuICBiZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdDogJ2JlZm9yZVBhc3N3b3JkUmVzZXRSZXF1ZXN0JyxcbiAgYmVmb3JlU2F2ZTogJ2JlZm9yZVNhdmUnLFxuICBhZnRlclNhdmU6ICdhZnRlclNhdmUnLFxuICBiZWZvcmVEZWxldGU6ICdiZWZvcmVEZWxldGUnLFxuICBhZnRlckRlbGV0ZTogJ2FmdGVyRGVsZXRlJyxcbiAgYmVmb3JlRmluZDogJ2JlZm9yZUZpbmQnLFxuICBhZnRlckZpbmQ6ICdhZnRlckZpbmQnLFxuICBiZWZvcmVDb25uZWN0OiAnYmVmb3JlQ29ubmVjdCcsXG4gIGJlZm9yZVN1YnNjcmliZTogJ2JlZm9yZVN1YnNjcmliZScsXG4gIGFmdGVyRXZlbnQ6ICdhZnRlckV2ZW50Jyxcbn07XG5cbmNvbnN0IENvbm5lY3RDbGFzc05hbWUgPSAnQENvbm5lY3QnO1xuXG5jb25zdCBiYXNlU3RvcmUgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IFZhbGlkYXRvcnMgPSBPYmplY3Qua2V5cyhUeXBlcykucmVkdWNlKGZ1bmN0aW9uIChiYXNlLCBrZXkpIHtcbiAgICBiYXNlW2tleV0gPSB7fTtcbiAgICByZXR1cm4gYmFzZTtcbiAgfSwge30pO1xuICBjb25zdCBGdW5jdGlvbnMgPSB7fTtcbiAgY29uc3QgSm9icyA9IHt9O1xuICBjb25zdCBMaXZlUXVlcnkgPSBbXTtcbiAgY29uc3QgVHJpZ2dlcnMgPSBPYmplY3Qua2V5cyhUeXBlcykucmVkdWNlKGZ1bmN0aW9uIChiYXNlLCBrZXkpIHtcbiAgICBiYXNlW2tleV0gPSB7fTtcbiAgICByZXR1cm4gYmFzZTtcbiAgfSwge30pO1xuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBGdW5jdGlvbnMsXG4gICAgSm9icyxcbiAgICBWYWxpZGF0b3JzLFxuICAgIFRyaWdnZXJzLFxuICAgIExpdmVRdWVyeSxcbiAgfSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpIHtcbiAgaWYgKHBhcnNlQ2xhc3MgJiYgcGFyc2VDbGFzcy5jbGFzc05hbWUpIHtcbiAgICByZXR1cm4gcGFyc2VDbGFzcy5jbGFzc05hbWU7XG4gIH1cbiAgaWYgKHBhcnNlQ2xhc3MgJiYgcGFyc2VDbGFzcy5uYW1lKSB7XG4gICAgcmV0dXJuIHBhcnNlQ2xhc3MubmFtZS5yZXBsYWNlKCdQYXJzZScsICdAJyk7XG4gIH1cbiAgcmV0dXJuIHBhcnNlQ2xhc3M7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ2xhc3NOYW1lRm9yVHJpZ2dlcnMoY2xhc3NOYW1lLCB0eXBlKSB7XG4gIGlmICh0eXBlID09IFR5cGVzLmJlZm9yZVNhdmUgJiYgY2xhc3NOYW1lID09PSAnX1B1c2hTdGF0dXMnKSB7XG4gICAgLy8gX1B1c2hTdGF0dXMgdXNlcyB1bmRvY3VtZW50ZWQgbmVzdGVkIGtleSBpbmNyZW1lbnQgb3BzXG4gICAgLy8gYWxsb3dpbmcgYmVmb3JlU2F2ZSB3b3VsZCBtZXNzIHVwIHRoZSBvYmplY3RzIGJpZyB0aW1lXG4gICAgLy8gVE9ETzogQWxsb3cgcHJvcGVyIGRvY3VtZW50ZWQgd2F5IG9mIHVzaW5nIG5lc3RlZCBpbmNyZW1lbnQgb3BzXG4gICAgdGhyb3cgJ09ubHkgYWZ0ZXJTYXZlIGlzIGFsbG93ZWQgb24gX1B1c2hTdGF0dXMnO1xuICB9XG4gIGlmICgodHlwZSA9PT0gVHlwZXMuYmVmb3JlTG9naW4gfHwgdHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpbiB8fCB0eXBlID09PSBUeXBlcy5iZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdCkgJiYgY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgLy8gVE9ETzogY2hlY2sgaWYgdXBzdHJlYW0gY29kZSB3aWxsIGhhbmRsZSBgRXJyb3JgIGluc3RhbmNlIHJhdGhlclxuICAgIC8vIHRoYW4gdGhpcyBhbnRpLXBhdHRlcm4gb2YgdGhyb3dpbmcgc3RyaW5nc1xuICAgIHRocm93ICdPbmx5IHRoZSBfVXNlciBjbGFzcyBpcyBhbGxvd2VkIGZvciB0aGUgYmVmb3JlTG9naW4sIGFmdGVyTG9naW4sIGFuZCBiZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdCB0cmlnZ2Vycyc7XG4gIH1cbiAgaWYgKHR5cGUgPT09IFR5cGVzLmFmdGVyTG9nb3V0ICYmIGNsYXNzTmFtZSAhPT0gJ19TZXNzaW9uJykge1xuICAgIC8vIFRPRE86IGNoZWNrIGlmIHVwc3RyZWFtIGNvZGUgd2lsbCBoYW5kbGUgYEVycm9yYCBpbnN0YW5jZSByYXRoZXJcbiAgICAvLyB0aGFuIHRoaXMgYW50aS1wYXR0ZXJuIG9mIHRocm93aW5nIHN0cmluZ3NcbiAgICB0aHJvdyAnT25seSB0aGUgX1Nlc3Npb24gY2xhc3MgaXMgYWxsb3dlZCBmb3IgdGhlIGFmdGVyTG9nb3V0IHRyaWdnZXIuJztcbiAgfVxuICBpZiAoY2xhc3NOYW1lID09PSAnX1Nlc3Npb24nICYmIHR5cGUgIT09IFR5cGVzLmFmdGVyTG9nb3V0KSB7XG4gICAgLy8gVE9ETzogY2hlY2sgaWYgdXBzdHJlYW0gY29kZSB3aWxsIGhhbmRsZSBgRXJyb3JgIGluc3RhbmNlIHJhdGhlclxuICAgIC8vIHRoYW4gdGhpcyBhbnRpLXBhdHRlcm4gb2YgdGhyb3dpbmcgc3RyaW5nc1xuICAgIHRocm93ICdPbmx5IHRoZSBhZnRlckxvZ291dCB0cmlnZ2VyIGlzIGFsbG93ZWQgZm9yIHRoZSBfU2Vzc2lvbiBjbGFzcy4nO1xuICB9XG4gIHJldHVybiBjbGFzc05hbWU7XG59XG5cbmNvbnN0IF90cmlnZ2VyU3RvcmUgPSB7fTtcblxuY29uc3QgQ2F0ZWdvcnkgPSB7XG4gIEZ1bmN0aW9uczogJ0Z1bmN0aW9ucycsXG4gIFZhbGlkYXRvcnM6ICdWYWxpZGF0b3JzJyxcbiAgSm9iczogJ0pvYnMnLFxuICBUcmlnZ2VyczogJ1RyaWdnZXJzJyxcbn07XG5cbmZ1bmN0aW9uIGdldFN0b3JlKGNhdGVnb3J5LCBuYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIGNvbnN0IGludmFsaWROYW1lUmVnZXggPSAvWydcImBdLztcbiAgaWYgKGludmFsaWROYW1lUmVnZXgudGVzdChuYW1lKSkge1xuICAgIC8vIFByZXZlbnQgYSBtYWxpY2lvdXMgdXNlciBmcm9tIGluamVjdGluZyBwcm9wZXJ0aWVzIGludG8gdGhlIHN0b3JlXG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgY29uc3QgcGF0aCA9IG5hbWUuc3BsaXQoJy4nKTtcbiAgcGF0aC5zcGxpY2UoLTEpOyAvLyByZW1vdmUgbGFzdCBjb21wb25lbnRcbiAgYXBwbGljYXRpb25JZCA9IGFwcGxpY2F0aW9uSWQgfHwgUGFyc2UuYXBwbGljYXRpb25JZDtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSA9IF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gfHwgYmFzZVN0b3JlKCk7XG4gIGxldCBzdG9yZSA9IF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF1bY2F0ZWdvcnldO1xuICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiBwYXRoKSB7XG4gICAgc3RvcmUgPSBzdG9yZVtjb21wb25lbnRdO1xuICAgIGlmICghc3RvcmUpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0b3JlO1xufVxuXG5mdW5jdGlvbiBhZGQoY2F0ZWdvcnksIG5hbWUsIGhhbmRsZXIsIGFwcGxpY2F0aW9uSWQpIHtcbiAgY29uc3QgbGFzdENvbXBvbmVudCA9IG5hbWUuc3BsaXQoJy4nKS5zcGxpY2UoLTEpO1xuICBjb25zdCBzdG9yZSA9IGdldFN0b3JlKGNhdGVnb3J5LCBuYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgaWYgKHN0b3JlW2xhc3RDb21wb25lbnRdKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICBgV2FybmluZzogRHVwbGljYXRlIGNsb3VkIGZ1bmN0aW9ucyBleGlzdCBmb3IgJHtsYXN0Q29tcG9uZW50fS4gT25seSB0aGUgbGFzdCBvbmUgd2lsbCBiZSB1c2VkIGFuZCB0aGUgb3RoZXJzIHdpbGwgYmUgaWdub3JlZC5gXG4gICAgKTtcbiAgfVxuICBzdG9yZVtsYXN0Q29tcG9uZW50XSA9IGhhbmRsZXI7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICBkZWxldGUgc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmZ1bmN0aW9uIGdldChjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICByZXR1cm4gc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5GdW5jdGlvbnMsIGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBmdW5jdGlvbk5hbWUsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEpvYihqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5Kb2JzLCBqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRyaWdnZXIodHlwZSwgY2xhc3NOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSk7XG4gIGFkZChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHlwZX0uJHtjbGFzc05hbWV9YCwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb25uZWN0VHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIoaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkucHVzaChoYW5kbGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZW1vdmUoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJpZ2dlcih0eXBlLCBjbGFzc05hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmVtb3ZlKENhdGVnb3J5LlRyaWdnZXJzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF91bnJlZ2lzdGVyQWxsKCkge1xuICBPYmplY3Qua2V5cyhfdHJpZ2dlclN0b3JlKS5mb3JFYWNoKGFwcElkID0+IGRlbGV0ZSBfdHJpZ2dlclN0b3JlW2FwcElkXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b0pTT053aXRoT2JqZWN0cyhvYmplY3QsIGNsYXNzTmFtZSkge1xuICBpZiAoIW9iamVjdCB8fCAhb2JqZWN0LnRvSlNPTikge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBjb25zdCB0b0pTT04gPSBvYmplY3QudG9KU09OKCk7XG4gIGNvbnN0IHN0YXRlQ29udHJvbGxlciA9IFBhcnNlLkNvcmVNYW5hZ2VyLmdldE9iamVjdFN0YXRlQ29udHJvbGxlcigpO1xuICBjb25zdCBbcGVuZGluZ10gPSBzdGF0ZUNvbnRyb2xsZXIuZ2V0UGVuZGluZ09wcyhvYmplY3QuX2dldFN0YXRlSWRlbnRpZmllcigpKTtcbiAgZm9yIChjb25zdCBrZXkgaW4gcGVuZGluZykge1xuICAgIGNvbnN0IHZhbCA9IG9iamVjdC5nZXQoa2V5KTtcbiAgICBpZiAoIXZhbCB8fCAhdmFsLl90b0Z1bGxKU09OKSB7XG4gICAgICB0b0pTT05ba2V5XSA9IHZhbDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0b0pTT05ba2V5XSA9IHZhbC5fdG9GdWxsSlNPTigpO1xuICB9XG4gIC8vIFByZXNlcnZlIG9yaWdpbmFsIG9iamVjdCdzIGNsYXNzTmFtZSBpZiBubyBvdmVycmlkZSBjbGFzc05hbWUgaXMgcHJvdmlkZWRcbiAgaWYgKGNsYXNzTmFtZSkge1xuICAgIHRvSlNPTi5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gIH0gZWxzZSBpZiAob2JqZWN0LmNsYXNzTmFtZSAmJiAhdG9KU09OLmNsYXNzTmFtZSkge1xuICAgIHRvSlNPTi5jbGFzc05hbWUgPSBvYmplY3QuY2xhc3NOYW1lO1xuICB9XG4gIHJldHVybiB0b0pTT047XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFhcHBsaWNhdGlvbklkKSB7XG4gICAgdGhyb3cgJ01pc3NpbmcgQXBwbGljYXRpb25JRCc7XG4gIH1cbiAgcmV0dXJuIGdldChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWAsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuVHJpZ2dlcih0cmlnZ2VyLCBuYW1lLCByZXF1ZXN0LCBhdXRoKSB7XG4gIGlmICghdHJpZ2dlcikge1xuICAgIHJldHVybjtcbiAgfVxuICBhd2FpdCBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBuYW1lLCBhdXRoKTtcbiAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIGF3YWl0IHRyaWdnZXIocmVxdWVzdCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmlnZ2VyRXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nLCB0eXBlOiBzdHJpbmcsIGFwcGxpY2F0aW9uSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHR5cGUsIGFwcGxpY2F0aW9uSWQpICE9IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LkZ1bmN0aW9ucywgZnVuY3Rpb25OYW1lLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bmN0aW9uTmFtZXMoYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBzdG9yZSA9XG4gICAgKF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gJiYgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXVtDYXRlZ29yeS5GdW5jdGlvbnNdKSB8fCB7fTtcbiAgY29uc3QgZnVuY3Rpb25OYW1lcyA9IFtdO1xuICBjb25zdCBleHRyYWN0RnVuY3Rpb25OYW1lcyA9IChuYW1lc3BhY2UsIHN0b3JlKSA9PiB7XG4gICAgT2JqZWN0LmtleXMoc3RvcmUpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHN0b3JlW25hbWVdO1xuICAgICAgaWYgKG5hbWVzcGFjZSkge1xuICAgICAgICBuYW1lID0gYCR7bmFtZXNwYWNlfS4ke25hbWV9YDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZnVuY3Rpb25OYW1lcy5wdXNoKG5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXh0cmFjdEZ1bmN0aW9uTmFtZXMobmFtZSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuICBleHRyYWN0RnVuY3Rpb25OYW1lcyhudWxsLCBzdG9yZSk7XG4gIHJldHVybiBmdW5jdGlvbk5hbWVzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Sm9iKGpvYk5hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmV0dXJuIGdldChDYXRlZ29yeS5Kb2JzLCBqb2JOYW1lLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEpvYnMoYXBwbGljYXRpb25JZCkge1xuICB2YXIgbWFuYWdlciA9IF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF07XG4gIGlmIChtYW5hZ2VyICYmIG1hbmFnZXIuSm9icykge1xuICAgIHJldHVybiBtYW5hZ2VyLkpvYnM7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbGlkYXRvcihmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmV0dXJuIGdldChDYXRlZ29yeS5WYWxpZGF0b3JzLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVxdWVzdE9iamVjdChcbiAgdHJpZ2dlclR5cGUsXG4gIGF1dGgsXG4gIHBhcnNlT2JqZWN0LFxuICBvcmlnaW5hbFBhcnNlT2JqZWN0LFxuICBjb25maWcsXG4gIGNvbnRleHQsXG4gIGlzR2V0XG4pIHtcbiAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICB0cmlnZ2VyTmFtZTogdHJpZ2dlclR5cGUsXG4gICAgb2JqZWN0OiBwYXJzZU9iamVjdCxcbiAgICBtYXN0ZXI6IGZhbHNlLFxuICAgIGxvZzogY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIsXG4gICAgaGVhZGVyczogY29uZmlnLmhlYWRlcnMsXG4gICAgaXA6IGNvbmZpZy5pcCxcbiAgICBjb25maWcsXG4gIH07XG5cbiAgaWYgKGlzR2V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXF1ZXN0LmlzR2V0ID0gISFpc0dldDtcbiAgfVxuXG4gIGlmIChvcmlnaW5hbFBhcnNlT2JqZWN0KSB7XG4gICAgcmVxdWVzdC5vcmlnaW5hbCA9IG9yaWdpbmFsUGFyc2VPYmplY3Q7XG4gIH1cbiAgaWYgKFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVTYXZlIHx8XG4gICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyU2F2ZSB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVEZWxldGUgfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJEZWxldGUgfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlTG9naW4gfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpbiB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdCB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckZpbmRcbiAgKSB7XG4gICAgLy8gU2V0IGEgY29weSBvZiB0aGUgY29udGV4dCBvbiB0aGUgcmVxdWVzdCBvYmplY3QuXG4gICAgcmVxdWVzdC5jb250ZXh0ID0gT2JqZWN0LmFzc2lnbih7fSwgY29udGV4dCk7XG4gIH1cblxuICBpZiAoIWF1dGgpIHtcbiAgICByZXR1cm4gcmVxdWVzdDtcbiAgfVxuICBpZiAoYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcXVlc3RbJ21hc3RlciddID0gdHJ1ZTtcbiAgfVxuICBpZiAoYXV0aC51c2VyKSB7XG4gICAgcmVxdWVzdFsndXNlciddID0gYXV0aC51c2VyO1xuICB9XG4gIGlmIChhdXRoLmluc3RhbGxhdGlvbklkKSB7XG4gICAgcmVxdWVzdFsnaW5zdGFsbGF0aW9uSWQnXSA9IGF1dGguaW5zdGFsbGF0aW9uSWQ7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0UXVlcnlPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHF1ZXJ5LCBjb3VudCwgY29uZmlnLCBjb250ZXh0LCBpc0dldCkge1xuICBpc0dldCA9ICEhaXNHZXQ7XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIHF1ZXJ5LFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgY291bnQsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBpc0dldCxcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICAgIGNvbnRleHQ6IGNvbnRleHQgfHwge30sXG4gICAgY29uZmlnLFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuLy8gQ3JlYXRlcyB0aGUgcmVzcG9uc2Ugb2JqZWN0LCBhbmQgdXNlcyB0aGUgcmVxdWVzdCBvYmplY3QgdG8gcGFzcyBkYXRhXG4vLyBUaGUgQVBJIHdpbGwgY2FsbCB0aGlzIHdpdGggUkVTVCBBUEkgZm9ybWF0dGVkIG9iamVjdHMsIHRoaXMgd2lsbFxuLy8gdHJhbnNmb3JtIHRoZW0gdG8gUGFyc2UuT2JqZWN0IGluc3RhbmNlcyBleHBlY3RlZCBieSBDbG91ZCBDb2RlLlxuLy8gQW55IGNoYW5nZXMgbWFkZSB0byB0aGUgb2JqZWN0IGluIGEgYmVmb3JlU2F2ZSB3aWxsIGJlIGluY2x1ZGVkLlxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsIHJlc29sdmUsIHJlamVjdCkge1xuICByZXR1cm4ge1xuICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgaWYgKHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmFmdGVyRmluZCkge1xuICAgICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgICAgcmVzcG9uc2UgPSByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZS5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICByZXR1cm4gdG9KU09Od2l0aE9iamVjdHMob2JqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgSlNPTiByZXNwb25zZVxuICAgICAgaWYgKFxuICAgICAgICByZXNwb25zZSAmJlxuICAgICAgICB0eXBlb2YgcmVzcG9uc2UgPT09ICdvYmplY3QnICYmXG4gICAgICAgICFyZXF1ZXN0Lm9iamVjdC5lcXVhbHMocmVzcG9uc2UpICYmXG4gICAgICAgIHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmJlZm9yZVNhdmVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICB9XG4gICAgICBpZiAocmVzcG9uc2UgJiYgdHlwZW9mIHJlc3BvbnNlID09PSAnb2JqZWN0JyAmJiByZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5hZnRlclNhdmUpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfVxuICAgICAgaWYgKHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmFmdGVyU2F2ZSkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgIGlmIChyZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5iZWZvcmVTYXZlKSB7XG4gICAgICAgIHJlc3BvbnNlWydvYmplY3QnXSA9IHJlcXVlc3Qub2JqZWN0Ll9nZXRTYXZlSlNPTigpO1xuICAgICAgICByZXNwb25zZVsnb2JqZWN0J11bJ29iamVjdElkJ10gPSByZXF1ZXN0Lm9iamVjdC5pZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICB9LFxuICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGUgPSByZXNvbHZlRXJyb3IoZXJyb3IsIHtcbiAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgbWVzc2FnZTogJ1NjcmlwdCBmYWlsZWQuIFVua25vd24gZXJyb3IuJyxcbiAgICAgIH0pO1xuICAgICAgcmVqZWN0KGUpO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIHVzZXJJZEZvckxvZyhhdXRoKSB7XG4gIHJldHVybiBhdXRoICYmIGF1dGgudXNlciA/IGF1dGgudXNlci5pZCA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gbG9nVHJpZ2dlckFmdGVySG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBpbnB1dCwgYXV0aCwgbG9nTGV2ZWwpIHtcbiAgaWYgKGxvZ0xldmVsID09PSAnc2lsZW50Jykge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBsb2dnZXJbbG9nTGV2ZWxdKFxuICAgIGAke3RyaWdnZXJUeXBlfSB0cmlnZ2VyZWQgZm9yICR7Y2xhc3NOYW1lfSBmb3IgdXNlciAke3VzZXJJZEZvckxvZyhcbiAgICAgIGF1dGhcbiAgICApfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9YCxcbiAgICB7XG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIHVzZXI6IHVzZXJJZEZvckxvZyhhdXRoKSxcbiAgICB9XG4gICk7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBpbnB1dCwgcmVzdWx0LCBhdXRoLCBsb2dMZXZlbCkge1xuICBpZiAobG9nTGV2ZWwgPT09ICdzaWxlbnQnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IGNsZWFuSW5wdXQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KGlucHV0KSk7XG4gIGNvbnN0IGNsZWFuUmVzdWx0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgbG9nZ2VyW2xvZ0xldmVsXShcbiAgICBgJHt0cmlnZ2VyVHlwZX0gdHJpZ2dlcmVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coXG4gICAgICBhdXRoXG4gICAgKX06XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgUmVzdWx0OiAke2NsZWFuUmVzdWx0fWAsXG4gICAge1xuICAgICAgY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aCksXG4gICAgfVxuICApO1xufVxuXG5mdW5jdGlvbiBsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIGlucHV0LCBhdXRoLCBlcnJvciwgbG9nTGV2ZWwpIHtcbiAgaWYgKGxvZ0xldmVsID09PSAnc2lsZW50Jykge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBsb2dnZXJbbG9nTGV2ZWxdKFxuICAgIGAke3RyaWdnZXJUeXBlfSBmYWlsZWQgZm9yICR7Y2xhc3NOYW1lfSBmb3IgdXNlciAke3VzZXJJZEZvckxvZyhcbiAgICAgIGF1dGhcbiAgICApfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9XFxuICBFcnJvcjogJHtKU09OLnN0cmluZ2lmeShlcnJvcil9YCxcbiAgICB7XG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIGVycm9yLFxuICAgICAgdXNlcjogdXNlcklkRm9yTG9nKGF1dGgpLFxuICAgIH1cbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuQWZ0ZXJGaW5kVHJpZ2dlcihcbiAgdHJpZ2dlclR5cGUsXG4gIGF1dGgsXG4gIGNsYXNzTmFtZVF1ZXJ5LFxuICBvYmplY3RzSW5wdXQsXG4gIGNvbmZpZyxcbiAgcXVlcnksXG4gIGNvbnRleHQsXG4gIGlzR2V0XG4pIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWVRdWVyeSwgdHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcblxuICAgIGlmICghdHJpZ2dlcikge1xuICAgICAgaWYgKG9iamVjdHNJbnB1dCAmJiBvYmplY3RzSW5wdXQubGVuZ3RoID4gMCAmJiBvYmplY3RzSW5wdXRbMF0gaW5zdGFuY2VvZiBQYXJzZS5PYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUob2JqZWN0c0lucHV0Lm1hcChvYmogPT4gdG9KU09Od2l0aE9iamVjdHMob2JqKSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc29sdmUob2JqZWN0c0lucHV0IHx8IFtdKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgbnVsbCwgbnVsbCwgY29uZmlnLCBjb250ZXh0LCBpc0dldCk7XG4gICAgLy8gQ29udmVydCBxdWVyeSBwYXJhbWV0ZXIgdG8gUGFyc2UuUXVlcnkgaW5zdGFuY2VcbiAgICBpZiAocXVlcnkgaW5zdGFuY2VvZiBQYXJzZS5RdWVyeSkge1xuICAgICAgcmVxdWVzdC5xdWVyeSA9IHF1ZXJ5O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHF1ZXJ5ID09PSAnb2JqZWN0JyAmJiBxdWVyeSAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgcGFyc2VRdWVyeUluc3RhbmNlID0gbmV3IFBhcnNlLlF1ZXJ5KGNsYXNzTmFtZVF1ZXJ5KTtcbiAgICAgIGlmIChxdWVyeS53aGVyZSkge1xuICAgICAgICBwYXJzZVF1ZXJ5SW5zdGFuY2Uud2l0aEpTT04ocXVlcnkpO1xuICAgICAgfVxuICAgICAgcmVxdWVzdC5xdWVyeSA9IHBhcnNlUXVlcnlJbnN0YW5jZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVxdWVzdC5xdWVyeSA9IG5ldyBQYXJzZS5RdWVyeShjbGFzc05hbWVRdWVyeSk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBzdWNjZXNzLCBlcnJvciB9ID0gZ2V0UmVzcG9uc2VPYmplY3QoXG4gICAgICByZXF1ZXN0LFxuICAgICAgcHJvY2Vzc2VkT2JqZWN0c0pTT04gPT4ge1xuICAgICAgICByZXNvbHZlKHByb2Nlc3NlZE9iamVjdHNKU09OKTtcbiAgICAgIH0sXG4gICAgICBlcnJvckRhdGEgPT4ge1xuICAgICAgICByZWplY3QoZXJyb3JEYXRhKTtcbiAgICAgIH1cbiAgICApO1xuICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayhcbiAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgY2xhc3NOYW1lUXVlcnksXG4gICAgICAnQWZ0ZXJGaW5kIElucHV0IChQcmUtVHJhbnNmb3JtKScsXG4gICAgICBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgb2JqZWN0c0lucHV0Lm1hcChvID0+IChvIGluc3RhbmNlb2YgUGFyc2UuT2JqZWN0ID8gby5pZCArICc6JyArIG8uY2xhc3NOYW1lIDogbykpXG4gICAgICApLFxuICAgICAgYXV0aCxcbiAgICAgIGNvbmZpZy5sb2dMZXZlbHMudHJpZ2dlckJlZm9yZVN1Y2Nlc3NcbiAgICApO1xuXG4gICAgLy8gQ29udmVydCBwbGFpbiBvYmplY3RzIHRvIFBhcnNlLk9iamVjdCBpbnN0YW5jZXMgZm9yIHRyaWdnZXJcbiAgICByZXF1ZXN0Lm9iamVjdHMgPSBvYmplY3RzSW5wdXQubWFwKGN1cnJlbnRPYmplY3QgPT4ge1xuICAgICAgaWYgKGN1cnJlbnRPYmplY3QgaW5zdGFuY2VvZiBQYXJzZS5PYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRPYmplY3Q7XG4gICAgICB9XG4gICAgICAvLyBQcmVzZXJ2ZSB0aGUgb3JpZ2luYWwgY2xhc3NOYW1lIGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIHVzZSB0aGUgcXVlcnkgY2xhc3NOYW1lXG4gICAgICBjb25zdCBvcmlnaW5hbENsYXNzTmFtZSA9IGN1cnJlbnRPYmplY3QuY2xhc3NOYW1lIHx8IGNsYXNzTmFtZVF1ZXJ5O1xuICAgICAgY29uc3QgdGVtcE9iamVjdFdpdGhDbGFzc05hbWUgPSB7IC4uLmN1cnJlbnRPYmplY3QsIGNsYXNzTmFtZTogb3JpZ2luYWxDbGFzc05hbWUgfTtcbiAgICAgIHJldHVybiBQYXJzZS5PYmplY3QuZnJvbUpTT04odGVtcE9iamVjdFdpdGhDbGFzc05hbWUpO1xuICAgIH0pO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lUXVlcnl9YCwgYXV0aCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgICAgICAgIHJldHVybiByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzcG9uc2VGcm9tVHJpZ2dlciA9IHRyaWdnZXIocmVxdWVzdCk7XG4gICAgICAgIGlmIChyZXNwb25zZUZyb21UcmlnZ2VyICYmIHR5cGVvZiByZXNwb25zZUZyb21UcmlnZ2VyLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2VGcm9tVHJpZ2dlci50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlRnJvbVRyaWdnZXI7XG4gICAgICB9KVxuICAgICAgLnRoZW4oc3VjY2VzcywgZXJyb3IpO1xuICB9KS50aGVuKHJlc3VsdHNBc0pTT04gPT4ge1xuICAgIGxvZ1RyaWdnZXJBZnRlckhvb2soXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIGNsYXNzTmFtZVF1ZXJ5LFxuICAgICAgSlNPTi5zdHJpbmdpZnkocmVzdWx0c0FzSlNPTiksXG4gICAgICBhdXRoLFxuICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQWZ0ZXJcbiAgICApO1xuICAgIHJldHVybiByZXN1bHRzQXNKU09OO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuUXVlcnlUcmlnZ2VyKFxuICB0cmlnZ2VyVHlwZSxcbiAgY2xhc3NOYW1lLFxuICByZXN0V2hlcmUsXG4gIHJlc3RPcHRpb25zLFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGNvbnRleHQsXG4gIGlzR2V0XG4pIHtcbiAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICBpZiAoIXRyaWdnZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHJlc3RXaGVyZSxcbiAgICAgIHJlc3RPcHRpb25zLFxuICAgIH0pO1xuICB9XG4gIGNvbnN0IGpzb24gPSBPYmplY3QuYXNzaWduKHt9LCByZXN0T3B0aW9ucyk7XG4gIGpzb24ud2hlcmUgPSByZXN0V2hlcmU7XG5cbiAgY29uc3QgcGFyc2VRdWVyeSA9IG5ldyBQYXJzZS5RdWVyeShjbGFzc05hbWUpO1xuICBwYXJzZVF1ZXJ5LndpdGhKU09OKGpzb24pO1xuXG4gIGxldCBjb3VudCA9IGZhbHNlO1xuICBpZiAocmVzdE9wdGlvbnMpIHtcbiAgICBjb3VudCA9ICEhcmVzdE9wdGlvbnMuY291bnQ7XG4gIH1cbiAgY29uc3QgcmVxdWVzdE9iamVjdCA9IGdldFJlcXVlc3RRdWVyeU9iamVjdChcbiAgICB0cmlnZ2VyVHlwZSxcbiAgICBhdXRoLFxuICAgIHBhcnNlUXVlcnksXG4gICAgY291bnQsXG4gICAgY29uZmlnLFxuICAgIGNvbnRleHQsXG4gICAgaXNHZXRcbiAgKTtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3RPYmplY3QsIGAke3RyaWdnZXJUeXBlfS4ke2NsYXNzTmFtZX1gLCBhdXRoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIGlmIChyZXF1ZXN0T2JqZWN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgICAgIHJldHVybiByZXF1ZXN0T2JqZWN0LnF1ZXJ5O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRyaWdnZXIocmVxdWVzdE9iamVjdCk7XG4gICAgfSlcbiAgICAudGhlbihcbiAgICAgIHJlc3VsdCA9PiB7XG4gICAgICAgIGxldCBxdWVyeVJlc3VsdCA9IHBhcnNlUXVlcnk7XG4gICAgICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0IGluc3RhbmNlb2YgUGFyc2UuUXVlcnkpIHtcbiAgICAgICAgICBxdWVyeVJlc3VsdCA9IHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBqc29uUXVlcnkgPSBxdWVyeVJlc3VsdC50b0pTT04oKTtcbiAgICAgICAgaWYgKGpzb25RdWVyeS53aGVyZSkge1xuICAgICAgICAgIHJlc3RXaGVyZSA9IGpzb25RdWVyeS53aGVyZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmxpbWl0KSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5saW1pdCA9IGpzb25RdWVyeS5saW1pdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LnNraXApIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLnNraXAgPSBqc29uUXVlcnkuc2tpcDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmluY2x1ZGUpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmluY2x1ZGUgPSBqc29uUXVlcnkuaW5jbHVkZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmV4Y2x1ZGVLZXlzKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5leGNsdWRlS2V5cyA9IGpzb25RdWVyeS5leGNsdWRlS2V5cztcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmV4cGxhaW4pIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmV4cGxhaW4gPSBqc29uUXVlcnkuZXhwbGFpbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmtleXMpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmtleXMgPSBqc29uUXVlcnkua2V5cztcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5Lm9yZGVyKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5vcmRlciA9IGpzb25RdWVyeS5vcmRlcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmhpbnQpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmhpbnQgPSBqc29uUXVlcnkuaGludDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmNvbW1lbnQpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmNvbW1lbnQgPSBqc29uUXVlcnkuY29tbWVudDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxdWVzdE9iamVjdC5yZWFkUHJlZmVyZW5jZSkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZXF1ZXN0T2JqZWN0LnJlYWRQcmVmZXJlbmNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXF1ZXN0T2JqZWN0LmluY2x1ZGVSZWFkUHJlZmVyZW5jZSkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5pbmNsdWRlUmVhZFByZWZlcmVuY2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlcXVlc3RPYmplY3Quc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IHJlcXVlc3RPYmplY3Quc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgb2JqZWN0cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFBhcnNlLk9iamVjdCkge1xuICAgICAgICAgIG9iamVjdHMgPSBbcmVzdWx0XTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBBcnJheS5pc0FycmF5KHJlc3VsdCkgJiZcbiAgICAgICAgICAoIXJlc3VsdC5sZW5ndGggfHwgcmVzdWx0LmV2ZXJ5KG9iaiA9PiBvYmogaW5zdGFuY2VvZiBQYXJzZS5PYmplY3QpKVxuICAgICAgICApIHtcbiAgICAgICAgICBvYmplY3RzID0gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzdFdoZXJlLFxuICAgICAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgICAgIG9iamVjdHMsXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZXJyID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSByZXNvbHZlRXJyb3IoZXJyLCB7XG4gICAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgICBtZXNzYWdlOiAnU2NyaXB0IGZhaWxlZC4gVW5rbm93biBlcnJvci4nLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVFcnJvcihtZXNzYWdlLCBkZWZhdWx0T3B0cykge1xuICBpZiAoIWRlZmF1bHRPcHRzKSB7XG4gICAgZGVmYXVsdE9wdHMgPSB7fTtcbiAgfVxuICBpZiAoIW1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFxuICAgICAgZGVmYXVsdE9wdHMuY29kZSB8fCBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVELFxuICAgICAgZGVmYXVsdE9wdHMubWVzc2FnZSB8fCAnU2NyaXB0IGZhaWxlZC4nXG4gICAgKTtcbiAgfVxuICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgcmV0dXJuIG1lc3NhZ2U7XG4gIH1cblxuICBjb25zdCBjb2RlID0gZGVmYXVsdE9wdHMuY29kZSB8fCBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVEO1xuICAvLyBJZiBpdCdzIGFuIGVycm9yLCBtYXJrIGl0IGFzIGEgc2NyaXB0IGZhaWxlZFxuICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihjb2RlLCBtZXNzYWdlKTtcbiAgfVxuICBjb25zdCBlcnJvciA9IG5ldyBQYXJzZS5FcnJvcihjb2RlLCBtZXNzYWdlLm1lc3NhZ2UgfHwgbWVzc2FnZSk7XG4gIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICBlcnJvci5zdGFjayA9IG1lc3NhZ2Uuc3RhY2s7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGZ1bmN0aW9uTmFtZSwgYXV0aCkge1xuICBjb25zdCB0aGVWYWxpZGF0b3IgPSBnZXRWYWxpZGF0b3IoZnVuY3Rpb25OYW1lLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0aGVWYWxpZGF0b3IpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHR5cGVvZiB0aGVWYWxpZGF0b3IgPT09ICdvYmplY3QnICYmIHRoZVZhbGlkYXRvci5za2lwV2l0aE1hc3RlcktleSAmJiByZXF1ZXN0Lm1hc3Rlcikge1xuICAgIHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkgPSB0cnVlO1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdGhlVmFsaWRhdG9yID09PSAnb2JqZWN0J1xuICAgICAgICAgID8gYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IodGhlVmFsaWRhdG9yLCByZXF1ZXN0LCBhdXRoKVxuICAgICAgICAgIDogdGhlVmFsaWRhdG9yKHJlcXVlc3QpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSByZXNvbHZlRXJyb3IoZSwge1xuICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsXG4gICAgICAgICAgbWVzc2FnZTogJ1ZhbGlkYXRpb24gZmFpbGVkLicsXG4gICAgICAgIH0pO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gIH0pO1xufVxuYXN5bmMgZnVuY3Rpb24gYnVpbHRJblRyaWdnZXJWYWxpZGF0b3Iob3B0aW9ucywgcmVxdWVzdCwgYXV0aCkge1xuICBpZiAocmVxdWVzdC5tYXN0ZXIgJiYgIW9wdGlvbnMudmFsaWRhdGVNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IHJlcVVzZXIgPSByZXF1ZXN0LnVzZXI7XG4gIGlmIChcbiAgICAhcmVxVXNlciAmJlxuICAgIHJlcXVlc3Qub2JqZWN0ICYmXG4gICAgcmVxdWVzdC5vYmplY3QuY2xhc3NOYW1lID09PSAnX1VzZXInICYmXG4gICAgIXJlcXVlc3Qub2JqZWN0LmV4aXN0ZWQoKVxuICApIHtcbiAgICByZXFVc2VyID0gcmVxdWVzdC5vYmplY3Q7XG4gIH1cbiAgaWYgKFxuICAgIChvcHRpb25zLnJlcXVpcmVVc2VyIHx8IG9wdGlvbnMucmVxdWlyZUFueVVzZXJSb2xlcyB8fCBvcHRpb25zLnJlcXVpcmVBbGxVc2VyUm9sZXMpICYmXG4gICAgIXJlcVVzZXJcbiAgKSB7XG4gICAgdGhyb3cgJ1ZhbGlkYXRpb24gZmFpbGVkLiBQbGVhc2UgbG9naW4gdG8gY29udGludWUuJztcbiAgfVxuICBpZiAob3B0aW9ucy5yZXF1aXJlTWFzdGVyICYmICFyZXF1ZXN0Lm1hc3Rlcikge1xuICAgIHRocm93ICdWYWxpZGF0aW9uIGZhaWxlZC4gTWFzdGVyIGtleSBpcyByZXF1aXJlZCB0byBjb21wbGV0ZSB0aGlzIHJlcXVlc3QuJztcbiAgfVxuICBsZXQgcGFyYW1zID0gcmVxdWVzdC5wYXJhbXMgfHwge307XG4gIGlmIChyZXF1ZXN0Lm9iamVjdCkge1xuICAgIHBhcmFtcyA9IHJlcXVlc3Qub2JqZWN0LnRvSlNPTigpO1xuICB9XG4gIGNvbnN0IHJlcXVpcmVkUGFyYW0gPSBrZXkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gcGFyYW1zW2tleV07XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgIHRocm93IGBWYWxpZGF0aW9uIGZhaWxlZC4gUGxlYXNlIHNwZWNpZnkgZGF0YSBmb3IgJHtrZXl9LmA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHZhbGlkYXRlT3B0aW9ucyA9IGFzeW5jIChvcHQsIGtleSwgdmFsKSA9PiB7XG4gICAgbGV0IG9wdHMgPSBvcHQub3B0aW9ucztcbiAgICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9wdHModmFsKTtcbiAgICAgICAgaWYgKCFyZXN1bHQgJiYgcmVzdWx0ICE9IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHZhbHVlIGZvciAke2tleX0uYDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoIWUpIHtcbiAgICAgICAgICB0aHJvdyBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHZhbHVlIGZvciAke2tleX0uYDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG9wdC5lcnJvciB8fCBlLm1lc3NhZ2UgfHwgZTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wdHMpKSB7XG4gICAgICBvcHRzID0gW29wdC5vcHRpb25zXTtcbiAgICB9XG5cbiAgICBpZiAoIW9wdHMuaW5jbHVkZXModmFsKSkge1xuICAgICAgdGhyb3cgKFxuICAgICAgICBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIG9wdGlvbiBmb3IgJHtrZXl9LiBFeHBlY3RlZDogJHtvcHRzLmpvaW4oJywgJyl9YFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgZ2V0VHlwZSA9IGZuID0+IHtcbiAgICBjb25zdCBtYXRjaCA9IGZuICYmIGZuLnRvU3RyaW5nKCkubWF0Y2goL15cXHMqZnVuY3Rpb24gKFxcdyspLyk7XG4gICAgcmV0dXJuIChtYXRjaCA/IG1hdGNoWzFdIDogJycpLnRvTG93ZXJDYXNlKCk7XG4gIH07XG4gIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuZmllbGRzKSkge1xuICAgIGZvciAoY29uc3Qga2V5IG9mIG9wdGlvbnMuZmllbGRzKSB7XG4gICAgICByZXF1aXJlZFBhcmFtKGtleSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNvbnN0IG9wdGlvblByb21pc2VzID0gW107XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucy5maWVsZHMpIHtcbiAgICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMuZmllbGRzW2tleV07XG4gICAgICBsZXQgdmFsID0gcGFyYW1zW2tleV07XG4gICAgICBpZiAodHlwZW9mIG9wdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmVxdWlyZWRQYXJhbShvcHQpO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChvcHQuZGVmYXVsdCAhPSBudWxsICYmIHZhbCA9PSBudWxsKSB7XG4gICAgICAgICAgdmFsID0gb3B0LmRlZmF1bHQ7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSB2YWw7XG4gICAgICAgICAgaWYgKHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgICAgICAgICByZXF1ZXN0Lm9iamVjdC5zZXQoa2V5LCB2YWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LmNvbnN0YW50ICYmIHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgICAgICAgaWYgKHJlcXVlc3Qub3JpZ2luYWwpIHtcbiAgICAgICAgICAgIHJlcXVlc3Qub2JqZWN0LnJldmVydChrZXkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAob3B0LmRlZmF1bHQgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmVxdWVzdC5vYmplY3Quc2V0KGtleSwgb3B0LmRlZmF1bHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LnJlcXVpcmVkKSB7XG4gICAgICAgICAgcmVxdWlyZWRQYXJhbShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbmFsID0gIW9wdC5yZXF1aXJlZCAmJiB2YWwgPT09IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCFvcHRpb25hbCkge1xuICAgICAgICAgIGlmIChvcHQudHlwZSkge1xuICAgICAgICAgICAgY29uc3QgdHlwZSA9IGdldFR5cGUob3B0LnR5cGUpO1xuICAgICAgICAgICAgY29uc3QgdmFsVHlwZSA9IEFycmF5LmlzQXJyYXkodmFsKSA/ICdhcnJheScgOiB0eXBlb2YgdmFsO1xuICAgICAgICAgICAgaWYgKHZhbFR5cGUgIT09IHR5cGUpIHtcbiAgICAgICAgICAgICAgdGhyb3cgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHR5cGUgZm9yICR7a2V5fS4gRXhwZWN0ZWQ6ICR7dHlwZX1gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAob3B0Lm9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdGlvblByb21pc2VzLnB1c2godmFsaWRhdGVPcHRpb25zKG9wdCwga2V5LCB2YWwpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwob3B0aW9uUHJvbWlzZXMpO1xuICB9XG4gIGxldCB1c2VyUm9sZXMgPSBvcHRpb25zLnJlcXVpcmVBbnlVc2VyUm9sZXM7XG4gIGxldCByZXF1aXJlQWxsUm9sZXMgPSBvcHRpb25zLnJlcXVpcmVBbGxVc2VyUm9sZXM7XG4gIGNvbnN0IHByb21pc2VzID0gW1Byb21pc2UucmVzb2x2ZSgpLCBQcm9taXNlLnJlc29sdmUoKSwgUHJvbWlzZS5yZXNvbHZlKCldO1xuICBpZiAodXNlclJvbGVzIHx8IHJlcXVpcmVBbGxSb2xlcykge1xuICAgIHByb21pc2VzWzBdID0gYXV0aC5nZXRVc2VyUm9sZXMoKTtcbiAgfVxuICBpZiAodHlwZW9mIHVzZXJSb2xlcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHByb21pc2VzWzFdID0gdXNlclJvbGVzKCk7XG4gIH1cbiAgaWYgKHR5cGVvZiByZXF1aXJlQWxsUm9sZXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBwcm9taXNlc1syXSA9IHJlcXVpcmVBbGxSb2xlcygpO1xuICB9XG4gIGNvbnN0IFtyb2xlcywgcmVzb2x2ZWRVc2VyUm9sZXMsIHJlc29sdmVkUmVxdWlyZUFsbF0gPSBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gIGlmIChyZXNvbHZlZFVzZXJSb2xlcyAmJiBBcnJheS5pc0FycmF5KHJlc29sdmVkVXNlclJvbGVzKSkge1xuICAgIHVzZXJSb2xlcyA9IHJlc29sdmVkVXNlclJvbGVzO1xuICB9XG4gIGlmIChyZXNvbHZlZFJlcXVpcmVBbGwgJiYgQXJyYXkuaXNBcnJheShyZXNvbHZlZFJlcXVpcmVBbGwpKSB7XG4gICAgcmVxdWlyZUFsbFJvbGVzID0gcmVzb2x2ZWRSZXF1aXJlQWxsO1xuICB9XG4gIGlmICh1c2VyUm9sZXMpIHtcbiAgICBjb25zdCBoYXNSb2xlID0gdXNlclJvbGVzLnNvbWUocmVxdWlyZWRSb2xlID0+IHJvbGVzLmluY2x1ZGVzKGByb2xlOiR7cmVxdWlyZWRSb2xlfWApKTtcbiAgICBpZiAoIWhhc1JvbGUpIHtcbiAgICAgIHRocm93IGBWYWxpZGF0aW9uIGZhaWxlZC4gVXNlciBkb2VzIG5vdCBtYXRjaCB0aGUgcmVxdWlyZWQgcm9sZXMuYDtcbiAgICB9XG4gIH1cbiAgaWYgKHJlcXVpcmVBbGxSb2xlcykge1xuICAgIGZvciAoY29uc3QgcmVxdWlyZWRSb2xlIG9mIHJlcXVpcmVBbGxSb2xlcykge1xuICAgICAgaWYgKCFyb2xlcy5pbmNsdWRlcyhgcm9sZToke3JlcXVpcmVkUm9sZX1gKSkge1xuICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIFVzZXIgZG9lcyBub3QgbWF0Y2ggYWxsIHRoZSByZXF1aXJlZCByb2xlcy5gO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCB1c2VyS2V5cyA9IG9wdGlvbnMucmVxdWlyZVVzZXJLZXlzIHx8IFtdO1xuICBpZiAoQXJyYXkuaXNBcnJheSh1c2VyS2V5cykpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiB1c2VyS2V5cykge1xuICAgICAgaWYgKCFyZXFVc2VyKSB7XG4gICAgICAgIHRocm93ICdQbGVhc2UgbG9naW4gdG8gbWFrZSB0aGlzIHJlcXVlc3QuJztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcVVzZXIuZ2V0KGtleSkgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIFBsZWFzZSBzZXQgZGF0YSBmb3IgJHtrZXl9IG9uIHlvdXIgYWNjb3VudC5gO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdXNlcktleXMgPT09ICdvYmplY3QnKSB7XG4gICAgY29uc3Qgb3B0aW9uUHJvbWlzZXMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvcHRpb25zLnJlcXVpcmVVc2VyS2V5cykge1xuICAgICAgY29uc3Qgb3B0ID0gb3B0aW9ucy5yZXF1aXJlVXNlcktleXNba2V5XTtcbiAgICAgIGlmIChvcHQub3B0aW9ucykge1xuICAgICAgICBvcHRpb25Qcm9taXNlcy5wdXNoKHZhbGlkYXRlT3B0aW9ucyhvcHQsIGtleSwgcmVxVXNlci5nZXQoa2V5KSkpO1xuICAgICAgfVxuICAgIH1cbiAgICBhd2FpdCBQcm9taXNlLmFsbChvcHRpb25Qcm9taXNlcyk7XG4gIH1cbn1cblxuLy8gVG8gYmUgdXNlZCBhcyBwYXJ0IG9mIHRoZSBwcm9taXNlIGNoYWluIHdoZW4gc2F2aW5nL2RlbGV0aW5nIGFuIG9iamVjdFxuLy8gV2lsbCByZXNvbHZlIHN1Y2Nlc3NmdWxseSBpZiBubyB0cmlnZ2VyIGlzIGNvbmZpZ3VyZWRcbi8vIFJlc29sdmVzIHRvIGFuIG9iamVjdCwgZW1wdHkgb3IgY29udGFpbmluZyBhbiBvYmplY3Qga2V5LiBBIGJlZm9yZVNhdmVcbi8vIHRyaWdnZXIgd2lsbCBzZXQgdGhlIG9iamVjdCBrZXkgdG8gdGhlIHJlc3QgZm9ybWF0IG9iamVjdCB0byBzYXZlLlxuLy8gb3JpZ2luYWxQYXJzZU9iamVjdCBpcyBvcHRpb25hbCwgd2Ugb25seSBuZWVkIHRoYXQgZm9yIGJlZm9yZS9hZnRlclNhdmUgZnVuY3Rpb25zXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVSdW5UcmlnZ2VyKFxuICB0cmlnZ2VyVHlwZSxcbiAgYXV0aCxcbiAgcGFyc2VPYmplY3QsXG4gIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gIGNvbmZpZyxcbiAgY29udGV4dFxuKSB7XG4gIGlmICghcGFyc2VPYmplY3QpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihwYXJzZU9iamVjdC5jbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCF0cmlnZ2VyKSB7IHJldHVybiByZXNvbHZlKCk7IH1cbiAgICB2YXIgcmVxdWVzdCA9IGdldFJlcXVlc3RPYmplY3QoXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIGF1dGgsXG4gICAgICBwYXJzZU9iamVjdCxcbiAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICBjb25maWcsXG4gICAgICBjb250ZXh0XG4gICAgKTtcbiAgICB2YXIgeyBzdWNjZXNzLCBlcnJvciB9ID0gZ2V0UmVzcG9uc2VPYmplY3QoXG4gICAgICByZXF1ZXN0LFxuICAgICAgb2JqZWN0ID0+IHtcbiAgICAgICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKFxuICAgICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgICBwYXJzZU9iamVjdC50b0pTT04oKSxcbiAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICB0cmlnZ2VyVHlwZS5zdGFydHNXaXRoKCdhZnRlcicpXG4gICAgICAgICAgICA/IGNvbmZpZy5sb2dMZXZlbHMudHJpZ2dlckFmdGVyXG4gICAgICAgICAgICA6IGNvbmZpZy5sb2dMZXZlbHMudHJpZ2dlckJlZm9yZVN1Y2Nlc3NcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVTYXZlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyU2F2ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVEZWxldGUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJEZWxldGVcbiAgICAgICAgKSB7XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihjb250ZXh0LCByZXF1ZXN0LmNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUob2JqZWN0KTtcbiAgICAgIH0sXG4gICAgICBlcnJvciA9PiB7XG4gICAgICAgIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2soXG4gICAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICAgcGFyc2VPYmplY3QuY2xhc3NOYW1lLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LnRvSlNPTigpLFxuICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQmVmb3JlRXJyb3JcbiAgICAgICAgKTtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gQWZ0ZXJTYXZlIGFuZCBhZnRlckRlbGV0ZSB0cmlnZ2VycyBjYW4gcmV0dXJuIGEgcHJvbWlzZSwgd2hpY2ggaWYgdGhleVxuICAgIC8vIGRvLCBuZWVkcyB0byBiZSByZXNvbHZlZCBiZWZvcmUgdGhpcyBwcm9taXNlIGlzIHJlc29sdmVkLFxuICAgIC8vIHNvIHRyaWdnZXIgZXhlY3V0aW9uIGlzIHN5bmNlZCB3aXRoIFJlc3RXcml0ZS5leGVjdXRlKCkgY2FsbC5cbiAgICAvLyBJZiB0cmlnZ2VycyBkbyBub3QgcmV0dXJuIGEgcHJvbWlzZSwgdGhleSBjYW4gcnVuIGFzeW5jIGNvZGUgcGFyYWxsZWxcbiAgICAvLyB0byB0aGUgUmVzdFdyaXRlLmV4ZWN1dGUoKSBjYWxsLlxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7cGFyc2VPYmplY3QuY2xhc3NOYW1lfWAsIGF1dGgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRyaWdnZXIocmVxdWVzdCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyRGVsZXRlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyTG9naW5cbiAgICAgICAgKSB7XG4gICAgICAgICAgbG9nVHJpZ2dlckFmdGVySG9vayhcbiAgICAgICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAgICAgcGFyc2VPYmplY3QuY2xhc3NOYW1lLFxuICAgICAgICAgICAgcGFyc2VPYmplY3QudG9KU09OKCksXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQWZ0ZXJcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIC8vIGJlZm9yZVNhdmUgaXMgZXhwZWN0ZWQgdG8gcmV0dXJuIG51bGwgKG5vdGhpbmcpXG4gICAgICAgIGlmICh0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSkge1xuICAgICAgICAgIGlmIChwcm9taXNlICYmIHR5cGVvZiBwcm9taXNlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAvLyByZXNwb25zZS5vYmplY3QgbWF5IGNvbWUgZnJvbSBleHByZXNzIHJvdXRpbmcgYmVmb3JlIGhvb2tcbiAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLm9iamVjdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHN1Y2Nlc3MsIGVycm9yKTtcbiAgfSk7XG59XG5cbi8vIENvbnZlcnRzIGEgUkVTVC1mb3JtYXQgb2JqZWN0IHRvIGEgUGFyc2UuT2JqZWN0XG4vLyBkYXRhIGlzIGVpdGhlciBjbGFzc05hbWUgb3IgYW4gb2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gaW5mbGF0ZShkYXRhLCByZXN0T2JqZWN0KSB7XG4gIHZhciBjb3B5ID0gdHlwZW9mIGRhdGEgPT0gJ29iamVjdCcgPyBkYXRhIDogeyBjbGFzc05hbWU6IGRhdGEgfTtcbiAgZm9yICh2YXIga2V5IGluIHJlc3RPYmplY3QpIHtcbiAgICBjb3B5W2tleV0gPSByZXN0T2JqZWN0W2tleV07XG4gIH1cbiAgcmV0dXJuIFBhcnNlLk9iamVjdC5mcm9tSlNPTihjb3B5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoZGF0YSwgYXBwbGljYXRpb25JZCA9IFBhcnNlLmFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFfdHJpZ2dlclN0b3JlIHx8ICFfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdIHx8ICFfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdLkxpdmVRdWVyeSkge1xuICAgIHJldHVybjtcbiAgfVxuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdLkxpdmVRdWVyeS5mb3JFYWNoKGhhbmRsZXIgPT4gaGFuZGxlcihkYXRhKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0RmlsZU9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgZmlsZU9iamVjdCwgY29uZmlnKSB7XG4gIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgLi4uZmlsZU9iamVjdCxcbiAgICB0cmlnZ2VyTmFtZTogdHJpZ2dlclR5cGUsXG4gICAgbWFzdGVyOiBmYWxzZSxcbiAgICBsb2c6IGNvbmZpZy5sb2dnZXJDb250cm9sbGVyLFxuICAgIGhlYWRlcnM6IGNvbmZpZy5oZWFkZXJzLFxuICAgIGlwOiBjb25maWcuaXAsXG4gICAgY29uZmlnLFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuRmlsZVRyaWdnZXIodHJpZ2dlclR5cGUsIGZpbGVPYmplY3QsIGNvbmZpZywgYXV0aCkge1xuICBjb25zdCBGaWxlQ2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKFBhcnNlLkZpbGUpO1xuICBjb25zdCBmaWxlVHJpZ2dlciA9IGdldFRyaWdnZXIoRmlsZUNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKHR5cGVvZiBmaWxlVHJpZ2dlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdEZpbGVPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIGZpbGVPYmplY3QsIGNvbmZpZyk7XG4gICAgICBhd2FpdCBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtGaWxlQ2xhc3NOYW1lfWAsIGF1dGgpO1xuICAgICAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3Q7XG4gICAgICB9XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmaWxlVHJpZ2dlcihyZXF1ZXN0KTtcbiAgICAgIGlmIChyZXF1ZXN0LmZvcmNlRG93bmxvYWQpIHtcbiAgICAgICAgZmlsZU9iamVjdC5mb3JjZURvd25sb2FkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICdQYXJzZS5GaWxlJyxcbiAgICAgICAgeyAuLi5maWxlT2JqZWN0LmZpbGUudG9KU09OKCksIGZpbGVTaXplOiBmaWxlT2JqZWN0LmZpbGVTaXplIH0sXG4gICAgICAgIHJlc3VsdCxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQmVmb3JlU3VjY2Vzc1xuICAgICAgKTtcbiAgICAgIHJldHVybiByZXN1bHQgfHwgZmlsZU9iamVjdDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nVHJpZ2dlckVycm9yQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICdQYXJzZS5GaWxlJyxcbiAgICAgICAgeyAuLi5maWxlT2JqZWN0LmZpbGUudG9KU09OKCksIGZpbGVTaXplOiBmaWxlT2JqZWN0LmZpbGVTaXplIH0sXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBjb25maWcubG9nTGV2ZWxzLnRyaWdnZXJCZWZvcmVFcnJvclxuICAgICAgKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmlsZU9iamVjdDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuR2xvYmFsQ29uZmlnVHJpZ2dlcih0cmlnZ2VyVHlwZSwgYXV0aCwgY29uZmlnT2JqZWN0LCBvcmlnaW5hbENvbmZpZ09iamVjdCwgY29uZmlnLCBjb250ZXh0KSB7XG4gIGNvbnN0IEdsb2JhbENvbmZpZ0NsYXNzTmFtZSA9IGdldENsYXNzTmFtZShQYXJzZS5Db25maWcpO1xuICBjb25zdCBjb25maWdUcmlnZ2VyID0gZ2V0VHJpZ2dlcihHbG9iYWxDb25maWdDbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gIGlmICh0eXBlb2YgY29uZmlnVHJpZ2dlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgY29uZmlnT2JqZWN0LCBvcmlnaW5hbENvbmZpZ09iamVjdCwgY29uZmlnLCBjb250ZXh0KTtcbiAgICAgIGF3YWl0IG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGAke3RyaWdnZXJUeXBlfS4ke0dsb2JhbENvbmZpZ0NsYXNzTmFtZX1gLCBhdXRoKTtcbiAgICAgIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgICAgIHJldHVybiBjb25maWdPYmplY3Q7XG4gICAgICB9XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb25maWdUcmlnZ2VyKHJlcXVlc3QpO1xuICAgICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKFxuICAgICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgICAgJ1BhcnNlLkNvbmZpZycsXG4gICAgICAgIGNvbmZpZ09iamVjdCxcbiAgICAgICAgcmVzdWx0LFxuICAgICAgICBhdXRoLFxuICAgICAgICBjb25maWcubG9nTGV2ZWxzLnRyaWdnZXJCZWZvcmVTdWNjZXNzXG4gICAgICApO1xuICAgICAgcmV0dXJuIHJlc3VsdCB8fCBjb25maWdPYmplY3Q7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2soXG4gICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAnUGFyc2UuQ29uZmlnJyxcbiAgICAgICAgY29uZmlnT2JqZWN0LFxuICAgICAgICBhdXRoLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQmVmb3JlRXJyb3JcbiAgICAgICk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvbmZpZ09iamVjdDtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLElBQUFBLEtBQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLE9BQUEsR0FBQUQsT0FBQTtBQUFrQyxTQUFBRCx1QkFBQUcsQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9B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