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
@@ -1,9 +1,8 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  var https = require('https'),
4
- crypto = require('crypto');
4
+ crypto = require('crypto');
5
5
  var Parse = require('parse/node').Parse;
6
-
7
6
  var OAuth = function (options) {
8
7
  if (!options) {
9
8
  throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'No options passed to OAuth');
@@ -15,9 +14,7 @@ var OAuth = function (options) {
15
14
  this.host = options.host;
16
15
  this.oauth_params = options.oauth_params || {};
17
16
  };
18
-
19
17
  OAuth.prototype.send = function (method, path, params, body) {
20
-
21
18
  var request = this.buildRequest(method, path, params, body);
22
19
  // Encode the body properly, the current Parse Implementation don't do it properly
23
20
  return new Promise(function (resolve, reject) {
@@ -39,41 +36,34 @@ OAuth.prototype.send = function (method, path, params, body) {
39
36
  httpRequest.end();
40
37
  });
41
38
  };
42
-
43
39
  OAuth.prototype.buildRequest = function (method, path, params, body) {
44
- if (path.indexOf("/") != 0) {
45
- path = "/" + path;
40
+ if (path.indexOf('/') != 0) {
41
+ path = '/' + path;
46
42
  }
47
43
  if (params && Object.keys(params).length > 0) {
48
- path += "?" + OAuth.buildParameterString(params);
44
+ path += '?' + OAuth.buildParameterString(params);
49
45
  }
50
-
51
46
  var request = {
52
47
  host: this.host,
53
48
  path: path,
54
49
  method: method.toUpperCase()
55
50
  };
56
-
57
51
  var oauth_params = this.oauth_params || {};
58
52
  oauth_params.oauth_consumer_key = this.consumer_key;
59
53
  if (this.auth_token) {
60
- oauth_params["oauth_token"] = this.auth_token;
54
+ oauth_params['oauth_token'] = this.auth_token;
61
55
  }
62
-
63
56
  request = OAuth.signRequest(request, oauth_params, this.consumer_secret, this.auth_token_secret);
64
-
65
57
  if (body && Object.keys(body).length > 0) {
66
58
  request.body = OAuth.buildParameterString(body);
67
59
  }
68
60
  return request;
69
61
  };
70
-
71
62
  OAuth.prototype.get = function (path, params) {
72
- return this.send("GET", path, params);
63
+ return this.send('GET', path, params);
73
64
  };
74
-
75
65
  OAuth.prototype.post = function (path, params, body) {
76
- return this.send("POST", path, params, body);
66
+ return this.send('POST', path, params, body);
77
67
  };
78
68
 
79
69
  /*
@@ -107,22 +97,20 @@ OAuth.encode = function (str) {
107
97
  // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
108
98
  return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A');
109
99
  };
110
-
111
- OAuth.signatureMethod = "HMAC-SHA1";
112
- OAuth.version = "1.0";
100
+ OAuth.signatureMethod = 'HMAC-SHA1';
101
+ OAuth.version = '1.0';
113
102
 
114
103
  /*
115
104
  Generate a nonce
116
105
  */
117
106
  OAuth.nonce = function () {
118
- var text = "";
119
- var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
120
-
121
- for (var i = 0; i < 30; i++) text += possible.charAt(Math.floor(Math.random() * possible.length));
122
-
107
+ var text = '';
108
+ var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
109
+ for (var i = 0; i < 30; i++) {
110
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
111
+ }
123
112
  return text;
124
113
  };
125
-
126
114
  OAuth.buildParameterString = function (obj) {
127
115
  // Sort keys and encode values
128
116
  if (obj) {
@@ -130,11 +118,10 @@ OAuth.buildParameterString = function (obj) {
130
118
 
131
119
  // Map key=value, join them by &
132
120
  return keys.map(function (key) {
133
- return key + "=" + OAuth.encode(obj[key]);
134
- }).join("&");
121
+ return key + '=' + OAuth.encode(obj[key]);
122
+ }).join('&');
135
123
  }
136
-
137
- return "";
124
+ return '';
138
125
  };
139
126
 
140
127
  /*
@@ -142,17 +129,16 @@ OAuth.buildParameterString = function (obj) {
142
129
  */
143
130
 
144
131
  OAuth.buildSignatureString = function (method, url, parameters) {
145
- return [method.toUpperCase(), OAuth.encode(url), OAuth.encode(parameters)].join("&");
132
+ return [method.toUpperCase(), OAuth.encode(url), OAuth.encode(parameters)].join('&');
146
133
  };
147
134
 
148
135
  /*
149
136
  Retuns encoded HMAC-SHA1 from key and text
150
137
  */
151
138
  OAuth.signature = function (text, key) {
152
- crypto = require("crypto");
139
+ crypto = require('crypto');
153
140
  return OAuth.encode(crypto.createHmac('sha1', key).update(text).digest('base64'));
154
141
  };
155
-
156
142
  OAuth.signRequest = function (request, oauth_parameters, consumer_secret, auth_token_secret) {
157
143
  oauth_parameters = oauth_parameters || {};
158
144
 
@@ -169,13 +155,12 @@ OAuth.signRequest = function (request, oauth_parameters, consumer_secret, auth_t
169
155
  if (!oauth_parameters.oauth_version) {
170
156
  oauth_parameters.oauth_version = OAuth.version;
171
157
  }
172
-
173
158
  if (!auth_token_secret) {
174
- auth_token_secret = "";
159
+ auth_token_secret = '';
175
160
  }
176
161
  // Force GET method if unset
177
162
  if (!request.method) {
178
- request.method = "GET";
163
+ request.method = 'GET';
179
164
  }
180
165
 
181
166
  // Collect all the parameters in one signatureParameters object
@@ -192,12 +177,10 @@ OAuth.signRequest = function (request, oauth_parameters, consumer_secret, auth_t
192
177
  var parameterString = OAuth.buildParameterString(signatureParams);
193
178
 
194
179
  // Build the signature string
195
- var url = "https://" + request.host + "" + request.path;
196
-
180
+ var url = 'https://' + request.host + '' + request.path;
197
181
  var signatureString = OAuth.buildSignatureString(request.method, url, parameterString);
198
182
  // Hash the signature string
199
- var signatureKey = [OAuth.encode(consumer_secret), OAuth.encode(auth_token_secret)].join("&");
200
-
183
+ var signatureKey = [OAuth.encode(consumer_secret), OAuth.encode(auth_token_secret)].join('&');
201
184
  var signature = OAuth.signature(signatureString, signatureKey);
202
185
 
203
186
  // Set the signature in the params
@@ -210,14 +193,12 @@ OAuth.signRequest = function (request, oauth_parameters, consumer_secret, auth_t
210
193
  var authHeader = Object.keys(oauth_parameters).sort().map(function (key) {
211
194
  var value = oauth_parameters[key];
212
195
  return key + '="' + value + '"';
213
- }).join(", ");
214
-
196
+ }).join(', ');
215
197
  request.headers.Authorization = 'OAuth ' + authHeader;
216
198
 
217
199
  // Set the content type header
218
- request.headers["Content-Type"] = "application/x-www-form-urlencoded";
200
+ request.headers['Content-Type'] = 'application/x-www-form-urlencoded';
219
201
  return request;
220
202
  };
221
-
222
203
  module.exports = OAuth;
223
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL09BdXRoMUNsaWVudC5qcyJdLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJjcnlwdG8iLCJQYXJzZSIsIk9BdXRoIiwib3B0aW9ucyIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiY29uc3VtZXJfa2V5IiwiY29uc3VtZXJfc2VjcmV0IiwiYXV0aF90b2tlbiIsImF1dGhfdG9rZW5fc2VjcmV0IiwiaG9zdCIsIm9hdXRoX3BhcmFtcyIsInByb3RvdHlwZSIsInNlbmQiLCJtZXRob2QiLCJwYXRoIiwicGFyYW1zIiwiYm9keSIsInJlcXVlc3QiLCJidWlsZFJlcXVlc3QiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImh0dHBSZXF1ZXN0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJ3cml0ZSIsImVuZCIsImluZGV4T2YiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiYnVpbGRQYXJhbWV0ZXJTdHJpbmciLCJ0b1VwcGVyQ2FzZSIsIm9hdXRoX2NvbnN1bWVyX2tleSIsInNpZ25SZXF1ZXN0IiwiZ2V0IiwicG9zdCIsImVuY29kZSIsInN0ciIsInRvU3RyaW5nIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwicmVwbGFjZSIsInNpZ25hdHVyZU1ldGhvZCIsInZlcnNpb24iLCJub25jZSIsInRleHQiLCJwb3NzaWJsZSIsImkiLCJjaGFyQXQiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJvYmoiLCJzb3J0IiwibWFwIiwia2V5Iiwiam9pbiIsImJ1aWxkU2lnbmF0dXJlU3RyaW5nIiwidXJsIiwicGFyYW1ldGVycyIsInNpZ25hdHVyZSIsImNyZWF0ZUhtYWMiLCJ1cGRhdGUiLCJkaWdlc3QiLCJvYXV0aF9wYXJhbWV0ZXJzIiwib2F1dGhfbm9uY2UiLCJvYXV0aF90aW1lc3RhbXAiLCJEYXRlIiwiZ2V0VGltZSIsIm9hdXRoX3NpZ25hdHVyZV9tZXRob2QiLCJvYXV0aF92ZXJzaW9uIiwic2lnbmF0dXJlUGFyYW1zIiwicGFyYW1ldGVyc1RvTWVyZ2UiLCJrIiwicGFyYW1ldGVyU3RyaW5nIiwic2lnbmF0dXJlU3RyaW5nIiwic2lnbmF0dXJlS2V5Iiwib2F1dGhfc2lnbmF0dXJlIiwiaGVhZGVycyIsImF1dGhIZWFkZXIiLCJ2YWx1ZSIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLFFBQVFDLFFBQVEsT0FBUixDQUFaO0FBQUEsSUFDRUMsU0FBU0QsUUFBUSxRQUFSLENBRFg7QUFFQSxJQUFJRSxRQUFRRixRQUFRLFlBQVIsRUFBc0JFLEtBQWxDOztBQUVBLElBQUlDLFFBQVEsVUFBU0MsT0FBVCxFQUFrQjtBQUM1QixNQUFHLENBQUNBLE9BQUosRUFBYTtBQUNYLFVBQU0sSUFBSUYsTUFBTUcsS0FBVixDQUFnQkgsTUFBTUcsS0FBTixDQUFZQyxxQkFBNUIsRUFBbUQsNEJBQW5ELENBQU47QUFDRDtBQUNELE9BQUtDLFlBQUwsR0FBb0JILFFBQVFHLFlBQTVCO0FBQ0EsT0FBS0MsZUFBTCxHQUF1QkosUUFBUUksZUFBL0I7QUFDQSxPQUFLQyxVQUFMLEdBQWtCTCxRQUFRSyxVQUExQjtBQUNBLE9BQUtDLGlCQUFMLEdBQXlCTixRQUFRTSxpQkFBakM7QUFDQSxPQUFLQyxJQUFMLEdBQVlQLFFBQVFPLElBQXBCO0FBQ0EsT0FBS0MsWUFBTCxHQUFvQlIsUUFBUVEsWUFBUixJQUF3QixFQUE1QztBQUNELENBVkQ7O0FBWUFULE1BQU1VLFNBQU4sQ0FBZ0JDLElBQWhCLEdBQXVCLFVBQVNDLE1BQVQsRUFBaUJDLElBQWpCLEVBQXVCQyxNQUF2QixFQUErQkMsSUFBL0IsRUFBb0M7O0FBRXpELE1BQUlDLFVBQVUsS0FBS0MsWUFBTCxDQUFrQkwsTUFBbEIsRUFBMEJDLElBQTFCLEVBQWdDQyxNQUFoQyxFQUF3Q0MsSUFBeEMsQ0FBZDtBQUNBO0FBQ0EsU0FBTyxJQUFJRyxPQUFKLENBQVks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bEJqRSxZQUFRaUUsT0FBUixHQUFrQixFQUFsQjtBQUNEOztBQUVEO0FBQ0EsTUFBSUMsYUFBYW5ELE9BQU9DLElBQVAsQ0FBWW1DLGdCQUFaLEVBQThCWCxJQUE5QixHQUFxQ0MsR0FBckMsQ0FBeUMsVUFBU0MsR0FBVCxFQUFhO0FBQ3JFLFFBQUl5QixRQUFRaEIsaUJBQWlCVCxHQUFqQixDQUFaO0FBQ0EsV0FBT0EsTUFBTSxJQUFOLEdBQWF5QixLQUFiLEdBQXFCLEdBQTVCO0FBQ0QsR0FIZ0IsRUFHZHhCLElBSGMsQ0FHVCxJQUhTLENBQWpCOztBQUtBM0MsVUFBUWlFLE9BQVIsQ0FBZ0JHLGFBQWhCLEdBQWdDLFdBQVdGLFVBQTNDOztBQUVBO0FBQ0FsRSxVQUFRaUUsT0FBUixDQUFnQixjQUFoQixJQUFrQyxtQ0FBbEM7QUFDQSxTQUFPakUsT0FBUDtBQUVELENBakVEOztBQW1FQXFFLE9BQU9DLE9BQVAsR0FBaUJ0RixLQUFqQiIsImZpbGUiOiJPQXV0aDFDbGllbnQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxudmFyIE9BdXRoID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICBpZighb3B0aW9ucykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdObyBvcHRpb25zIHBhc3NlZCB0byBPQXV0aCcpO1xuICB9XG4gIHRoaXMuY29uc3VtZXJfa2V5ID0gb3B0aW9ucy5jb25zdW1lcl9rZXk7XG4gIHRoaXMuY29uc3VtZXJfc2VjcmV0ID0gb3B0aW9ucy5jb25zdW1lcl9zZWNyZXQ7XG4gIHRoaXMuYXV0aF90b2tlbiA9IG9wdGlvbnMuYXV0aF90b2tlbjtcbiAgdGhpcy5hdXRoX3Rva2VuX3NlY3JldCA9IG9wdGlvbnMuYXV0aF90b2tlbl9zZWNyZXQ7XG4gIHRoaXMuaG9zdCA9IG9wdGlvbnMuaG9zdDtcbiAgdGhpcy5vYXV0aF9wYXJhbXMgPSBvcHRpb25zLm9hdXRoX3BhcmFtcyB8fCB7fTtcbn07XG5cbk9BdXRoLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24obWV0aG9kLCBwYXRoLCBwYXJhbXMsIGJvZHkpe1xuXG4gIHZhciByZXF1ZXN0ID0gdGhpcy5idWlsZFJlcXVlc3QobWV0aG9kLCBwYXRoLCBwYXJhbXMsIGJvZHkpO1xuICAvLyBFbmNvZGUgdGhlIGJvZHkgcHJvcGVybHksIHRoZSBjdXJyZW50IFBhcnNlIEltcGxlbWVudGF0aW9uIGRvbid0IGRvIGl0IHByb3Blcmx5XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgaHR0cFJlcXVlc3QgPSBodHRwcy5yZXF1ZXN0KHJlcXVlc3QsIGZ1bmN0aW9uKHJlcykge1xuICAgICAgdmFyIGRhdGEgPSAnJztcbiAgICAgIHJlcy5vbignZGF0YScsIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICAgIGRhdGEgKz0gY2h1bms7XG4gICAgICB9KTtcbiAgICAgIHJlcy5vbignZW5kJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgfSk7XG4gICAgfSkub24oJ2Vycm9yJywgZnVuY3Rpb24oKSB7XG4gICAgICByZWplY3QoJ0ZhaWxlZCB0byBtYWtlIGFuIE9BdXRoIHJlcXVlc3QnKTtcbiAgICB9KTtcbiAgICBpZiAocmVxdWVzdC5ib2R5KSB7XG4gICAgICBodHRwUmVxdWVzdC53cml0ZShyZXF1ZXN0LmJvZHkpO1xuICAgIH1cbiAgICBodHRwUmVxdWVzdC5lbmQoKTtcbiAgfSk7XG59O1xuXG5PQXV0aC5wcm90b3R5cGUuYnVpbGRSZXF1ZXN0ID0gZnVuY3Rpb24obWV0aG9kLCBwYXRoLCBwYXJhbXMsIGJvZHkpIHtcbiAgaWYgKHBhdGguaW5kZXhPZihcIi9cIikgIT0gMCkge1xuICAgIHBhdGggPSBcIi9cIiArIHBhdGg7XG4gIH1cbiAgaWYgKHBhcmFtcyAmJiBPYmplY3Qua2V5cyhwYXJhbXMpLmxlbmd0aCA+IDApIHtcbiAgICBwYXRoICs9IFwiP1wiICsgT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcocGFyYW1zKTtcbiAgfVxuXG4gIHZhciByZXF1ZXN0ID0ge1xuICAgIGhvc3Q6ICAgdGhpcy5ob3N0LFxuICAgIHBhdGg6IFx0cGF0aCxcbiAgICBtZXRob2Q6IG1ldGhvZC50b1VwcGVyQ2FzZSgpXG4gIH07XG5cbiAgdmFyIG9hdXRoX3BhcmFtcyA9IHRoaXMub2F1dGhfcGFyYW1zIHx8IHt9O1xuICBvYXV0aF9wYXJhbXMub2F1dGhfY29uc3VtZXJfa2V5ID0gdGhpcy5jb25zdW1lcl9rZXk7XG4gIGlmKHRoaXMuYXV0aF90b2tlbil7XG4gICAgb2F1dGhfcGFyYW1zW1wib2F1dGhfdG9rZW5cIl0gPSB0aGlzLmF1dGhfdG9rZW47XG4gIH1cblxuICByZXF1ZXN0ID0gT0F1dGguc2lnblJlcXVlc3QocmVxdWVzdCwgb2F1dGhfcGFyYW1zLCB0aGlzLmNvbnN1bWVyX3NlY3JldCwgIHRoaXMuYXV0aF90b2tlbl9zZWNyZXQpO1xuXG4gIGlmIChib2R5ICYmIE9iamVjdC5rZXlzKGJvZHkpLmxlbmd0aCA+IDApIHtcbiAgICByZXF1ZXN0LmJvZHkgPSBPQXV0aC5idWlsZFBhcmFtZXRlclN0cmluZyhib2R5KTtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuT0F1dGgucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHBhdGgsIHBhcmFtcykge1xuICByZXR1cm4gdGhpcy5zZW5kKFwiR0VUXCIsIHBhdGgsIHBhcmFtcyk7XG59XG5cbk9BdXRoLnByb3RvdHlwZS5wb3N0ID0gZnVuY3Rpb24ocGF0aCwgcGFyYW1zLCBib2R5KSB7XG4gIHJldHVybiB0aGlzLnNlbmQoXCJQT1NUXCIsIHBhdGgsIHBhcmFtcywgYm9keSk7XG59XG5cbi8qXG5cdFByb3BlciBzdHJpbmcgJWVzY2FwZSBlbmNvZGluZ1xuKi9cbk9BdXRoLmVuY29kZSA9IGZ1bmN0aW9uKHN0cikge1xuICAvLyAgICAgICBkaXNjdXNzIGF0OiBodHRwOi8vcGhwanMub3JnL2Z1bmN0aW9ucy9yYXd1cmxlbmNvZGUvXG4gIC8vICAgICAgb3JpZ2luYWwgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IHRyYXZjXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IE1pY2hhZWwgR3JpZXJcbiAgLy8gICAgICAgICBpbnB1dCBieTogUmF0aGVvdXNcbiAgLy8gICAgICBidWdmaXhlZCBieTogS2V2aW4gdmFuIFpvbm5ldmVsZCAoaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQpXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEpvcmlzXG4gIC8vIHJlaW1wbGVtZW50ZWQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vIHJlaW1wbGVtZW50ZWQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgICAgICAgIG5vdGU6IFRoaXMgcmVmbGVjdHMgUEhQIDUuMy82LjArIGJlaGF2aW9yXG4gIC8vICAgICAgICAgICAgIG5vdGU6IFBsZWFzZSBiZSBhd2FyZSB0aGF0IHRoaXMgZnVuY3Rpb24gZXhwZWN0cyB0byBlbmNvZGUgaW50byBVVEYtOCBlbmNvZGVkIHN0cmluZ3MsIGFzIGZvdW5kIG9uXG4gIC8vICAgICAgICAgICAgIG5vdGU6IHBhZ2VzIHNlcnZlZCBhcyBVVEYtOFxuICAvLyAgICAgICAgZXhhbXBsZSAxOiByYXd1cmxlbmNvZGUoJ0tldmluIHZhbiBab25uZXZlbGQhJyk7XG4gIC8vICAgICAgICByZXR1cm5zIDE6ICdLZXZpbiUyMHZhbiUyMFpvbm5ldmVsZCUyMSdcbiAgLy8gICAgICAgIGV4YW1wbGUgMjogcmF3dXJsZW5jb2RlKCdodHRwOi8va2V2aW4udmFuem9ubmV2ZWxkLm5ldC8nKTtcbiAgLy8gICAgICAgIHJldHVybnMgMjogJ2h0dHAlM0ElMkYlMkZrZXZpbi52YW56b25uZXZlbGQubmV0JTJGJ1xuICAvLyAgICAgICAgZXhhbXBsZSAzOiByYXd1cmxlbmNvZGUoJ2h0dHA6Ly93d3cuZ29vZ2xlLm5sL3NlYXJjaD9xPXBocC5qcyZpZT11dGYtOCZvZT11dGYtOCZhcT10JnJscz1jb20udWJ1bnR1OmVuLVVTOnVub2ZmaWNpYWwmY2xpZW50PWZpcmVmb3gtYScpO1xuICAvLyAgICAgICAgcmV0dXJucyAzOiAnaHR0cCUzQSUyRiUyRnd3dy5nb29nbGUubmwlMkZzZWFyY2glM0ZxJTNEcGhwLmpzJTI2aWUlM0R1dGYtOCUyNm9lJTNEdXRmLTglMjZhcSUzRHQlMjZybHMlM0Rjb20udWJ1bnR1JTNBZW4tVVMlM0F1bm9mZmljaWFsJTI2Y2xpZW50JTNEZmlyZWZveC1hJ1xuXG4gIHN0ciA9IChzdHIgKyAnJylcbiAgICAudG9TdHJpbmcoKTtcblxuICAvLyBUaWxkZSBzaG91bGQgYmUgYWxsb3dlZCB1bmVzY2FwZWQgaW4gZnV0dXJlIHZlcnNpb25zIG9mIFBIUCAoYXMgcmVmbGVjdGVkIGJlbG93KSwgYnV0IGlmIHlvdSB3YW50IHRvIHJlZmxlY3QgY3VycmVudFxuICAvLyBQSFAgYmVoYXZpb3IsIHlvdSB3b3VsZCBuZWVkIHRvIGFkZCBcIi5yZXBsYWNlKC9+L2csICclN0UnKTtcIiB0byB0aGUgZm9sbG93aW5nLlxuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHN0cilcbiAgICAucmVwbGFjZSgvIS9nLCAnJTIxJylcbiAgICAucmVwbGFjZSgvJy9nLCAnJTI3JylcbiAgICAucmVwbGFjZSgvXFwoL2csICclMjgnKVxuICAgIC5yZXBsYWNlKC9cXCkvZywgJyUyOScpXG4gICAgLnJlcGxhY2UoL1xcKi9nLCAnJTJBJyk7XG59XG5cbk9BdXRoLnNpZ25hdHVyZU1ldGhvZCA9IFwiSE1BQy1TSEExXCI7XG5PQXV0aC52ZXJzaW9uID0gXCIxLjBcIjtcblxuLypcblx0R2VuZXJhdGUgYSBub25jZVxuKi9cbk9BdXRoLm5vbmNlID0gZnVuY3Rpb24oKXtcbiAgdmFyIHRleHQgPSBcIlwiO1xuICB2YXIgcG9zc2libGUgPSBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5XCI7XG5cbiAgZm9yKHZhciBpID0gMDsgaSA8IDMwOyBpKyspXG4gICAgdGV4dCArPSBwb3NzaWJsZS5jaGFyQXQoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcG9zc2libGUubGVuZ3RoKSk7XG5cbiAgcmV0dXJuIHRleHQ7XG59XG5cbk9BdXRoLmJ1aWxkUGFyYW1ldGVyU3RyaW5nID0gZnVuY3Rpb24ob2JqKXtcbiAgLy8gU29ydCBrZXlzIGFuZCBlbmNvZGUgdmFsdWVzXG4gIGlmIChvYmopIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaikuc29ydCgpO1xuXG4gICAgLy8gTWFwIGtleT12YWx1ZSwgam9pbiB0aGVtIGJ5ICZcbiAgICByZXR1cm4ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KXtcbiAgICAgIHJldHVybiBrZXkgKyBcIj1cIiArIE9BdXRoLmVuY29kZShvYmpba2V5XSk7XG4gICAgfSkuam9pbihcIiZcIik7XG4gIH1cblxuICByZXR1cm4gXCJcIjtcbn1cblxuLypcblx0QnVpbGQgdGhlIHNpZ25hdHVyZSBzdHJpbmcgZnJvbSB0aGUgb2JqZWN0XG4qL1xuXG5PQXV0aC5idWlsZFNpZ25hdHVyZVN0cmluZyA9IGZ1bmN0aW9uKG1ldGhvZCwgdXJsLCBwYXJhbWV0ZXJzKXtcbiAgcmV0dXJuIFttZXRob2QudG9VcHBlckNhc2UoKSwgT0F1dGguZW5jb2RlKHVybCksIE9BdXRoLmVuY29kZShwYXJhbWV0ZXJzKV0uam9pbihcIiZcIik7XG59XG5cbi8qXG5cdFJldHVucyBlbmNvZGVkIEhNQUMtU0hBMSBmcm9tIGtleSBhbmQgdGV4dFxuKi9cbk9BdXRoLnNpZ25hdHVyZSA9IGZ1bmN0aW9uKHRleHQsIGtleSl7XG4gIGNyeXB0byA9IHJlcXVpcmUoXCJjcnlwdG9cIik7XG4gIHJldHVybiBPQXV0aC5lbmNvZGUoY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTEnLCBrZXkpLnVwZGF0ZSh0ZXh0KS5kaWdlc3QoJ2Jhc2U2NCcpKTtcbn1cblxuT0F1dGguc2lnblJlcXVlc3QgPSBmdW5jdGlvbihyZXF1ZXN0LCBvYXV0aF9wYXJhbWV0ZXJzLCBjb25zdW1lcl9zZWNyZXQsIGF1dGhfdG9rZW5fc2VjcmV0KXtcbiAgb2F1dGhfcGFyYW1ldGVycyA9IG9hdXRoX3BhcmFtZXRlcnMgfHwge307XG5cbiAgLy8gU2V0IGRlZmF1bHQgdmFsdWVzXG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9ub25jZSkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfbm9uY2UgPSBPQXV0aC5ub25jZSgpO1xuICB9XG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF90aW1lc3RhbXApIHtcbiAgICBvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3RpbWVzdGFtcCA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCA9IE9BdXRoLnNpZ25hdHVyZU1ldGhvZDtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbikge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbiA9IE9BdXRoLnZlcnNpb247XG4gIH1cblxuICBpZighYXV0aF90b2tlbl9zZWNyZXQpe1xuICAgIGF1dGhfdG9rZW5fc2VjcmV0ID0gXCJcIjtcbiAgfVxuICAvLyBGb3JjZSBHRVQgbWV0aG9kIGlmIHVuc2V0XG4gIGlmICghcmVxdWVzdC5tZXRob2QpIHtcbiAgICByZXF1ZXN0Lm1ldGhvZCA9IFwiR0VUXCJcbiAgfVxuXG4gIC8vIENvbGxlY3QgIGFsbCB0aGUgcGFyYW1ldGVycyBpbiBvbmUgc2lnbmF0dXJlUGFyYW1ldGVycyBvYmplY3RcbiAgdmFyIHNpZ25hdHVyZVBhcmFtcyA9IHt9O1xuICB2YXIgcGFyYW1ldGVyc1RvTWVyZ2UgPSBbcmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QuYm9keSwgb2F1dGhfcGFyYW1ldGVyc107XG4gIGZvcih2YXIgaSBpbiBwYXJhbWV0ZXJzVG9NZXJnZSkge1xuICAgIHZhciBwYXJhbWV0ZXJzID0gcGFyYW1ldGVyc1RvTWVyZ2VbaV07XG4gICAgZm9yKHZhciBrIGluIHBhcmFtZXRlcnMpIHtcbiAgICAgIHNpZ25hdHVyZVBhcmFtc1trXSA9IHBhcmFtZXRlcnNba107XG4gICAgfVxuICB9XG5cbiAgLy8gQ3JlYXRlIGEgc3RyaW5nIGJhc2VkIG9uIHRoZSBwYXJhbWV0ZXJzXG4gIHZhciBwYXJhbWV0ZXJTdHJpbmcgPSBPQXV0aC5idWlsZFBhcmFtZXRlclN0cmluZyhzaWduYXR1cmVQYXJhbXMpO1xuXG4gIC8vIEJ1aWxkIHRoZSBzaWduYXR1cmUgc3RyaW5nXG4gIHZhciB1cmwgPSBcImh0dHBzOi8vXCIgKyByZXF1ZXN0Lmhvc3QgKyBcIlwiICsgcmVxdWVzdC5wYXRoO1xuXG4gIHZhciBzaWduYXR1cmVTdHJpbmcgPSBPQXV0aC5idWlsZFNpZ25hdHVyZVN0cmluZyhyZXF1ZXN0Lm1ldGhvZCwgdXJsLCBwYXJhbWV0ZXJTdHJpbmcpO1xuICAvLyBIYXNoIHRoZSBzaWduYXR1cmUgc3RyaW5nXG4gIHZhciBzaWduYXR1cmVLZXkgPSBbT0F1dGguZW5jb2RlKGNvbnN1bWVyX3NlY3JldCksIE9BdXRoLmVuY29kZShhdXRoX3Rva2VuX3NlY3JldCldLmpvaW4oXCImXCIpO1xuXG4gIHZhciBzaWduYXR1cmUgPSBPQXV0aC5zaWduYXR1cmUoc2lnbmF0dXJlU3RyaW5nLCBzaWduYXR1cmVLZXkpO1xuXG4gIC8vIFNldCB0aGUgc2lnbmF0dXJlIGluIHRoZSBwYXJhbXNcbiAgb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9zaWduYXR1cmUgPSBzaWduYXR1cmU7XG4gIGlmKCFyZXF1ZXN0LmhlYWRlcnMpe1xuICAgIHJlcXVlc3QuaGVhZGVycyA9IHt9O1xuICB9XG5cbiAgLy8gU2V0IHRoZSBhdXRob3JpemF0aW9uIGhlYWRlclxuICB2YXIgYXV0aEhlYWRlciA9IE9iamVjdC5rZXlzKG9hdXRoX3BhcmFtZXRlcnMpLnNvcnQoKS5tYXAoZnVuY3Rpb24oa2V5KXtcbiAgICB2YXIgdmFsdWUgPSBvYXV0aF9wYXJhbWV0ZXJzW2tleV07XG4gICAgcmV0dXJuIGtleSArICc9XCInICsgdmFsdWUgKyAnXCInO1xuICB9KS5qb2luKFwiLCBcIilcblxuICByZXF1ZXN0LmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdPQXV0aCAnICsgYXV0aEhlYWRlcjtcblxuICAvLyBTZXQgdGhlIGNvbnRlbnQgdHlwZSBoZWFkZXJcbiAgcmVxdWVzdC5oZWFkZXJzW1wiQ29udGVudC1UeXBlXCJdID0gXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIjtcbiAgcmV0dXJuIHJlcXVlc3Q7XG5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBPQXV0aDtcbiJdfQ==
204
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJjcnlwdG8iLCJQYXJzZSIsIk9BdXRoIiwib3B0aW9ucyIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiY29uc3VtZXJfa2V5IiwiY29uc3VtZXJfc2VjcmV0IiwiYXV0aF90b2tlbiIsImF1dGhfdG9rZW5fc2VjcmV0IiwiaG9zdCIsIm9hdXRoX3BhcmFtcyIsInByb3RvdHlwZSIsInNlbmQiLCJtZXRob2QiLCJwYXRoIiwicGFyYW1zIiwiYm9keSIsInJlcXVlc3QiLCJidWlsZFJlcXVlc3QiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImh0dHBSZXF1ZXN0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJ3cml0ZSIsImVuZCIsImluZGV4T2YiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiYnVpbGRQYXJhbWV0ZXJTdHJpbmciLCJ0b1VwcGVyQ2FzZSIsIm9hdXRoX2NvbnN1bWVyX2tleSIsInNpZ25SZXF1ZXN0IiwiZ2V0IiwicG9zdCIsImVuY29kZSIsInN0ciIsInRvU3RyaW5nIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwicmVwbGFjZSIsInNpZ25hdHVyZU1ldGhvZCIsInZlcnNpb24iLCJub25jZSIsInRleHQiLCJwb3NzaWJsZSIsImkiLCJjaGFyQXQiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJvYmoiLCJzb3J0IiwibWFwIiwia2V5Iiwiam9pbiIsImJ1aWxkU2lnbmF0dXJlU3RyaW5nIiwidXJsIiwicGFyYW1ldGVycyIsInNpZ25hdHVyZSIsImNyZWF0ZUhtYWMiLCJ1cGRhdGUiLCJkaWdlc3QiLCJvYXV0aF9wYXJhbWV0ZXJzIiwib2F1dGhfbm9uY2UiLCJvYXV0aF90aW1lc3RhbXAiLCJEYXRlIiwiZ2V0VGltZSIsIm9hdXRoX3NpZ25hdHVyZV9tZXRob2QiLCJvYXV0aF92ZXJzaW9uIiwic2lnbmF0dXJlUGFyYW1zIiwicGFyYW1ldGVyc1RvTWVyZ2UiLCJrIiwicGFyYW1ldGVyU3RyaW5nIiwic2lnbmF0dXJlU3RyaW5nIiwic2lnbmF0dXJlS2V5Iiwib2F1dGhfc2lnbmF0dXJlIiwiaGVhZGVycyIsImF1dGhIZWFkZXIiLCJ2YWx1ZSIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvT0F1dGgxQ2xpZW50LmpzIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG52YXIgT0F1dGggPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnTm8gb3B0aW9ucyBwYXNzZWQgdG8gT0F1dGgnKTtcbiAgfVxuICB0aGlzLmNvbnN1bWVyX2tleSA9IG9wdGlvbnMuY29uc3VtZXJfa2V5O1xuICB0aGlzLmNvbnN1bWVyX3NlY3JldCA9IG9wdGlvbnMuY29uc3VtZXJfc2VjcmV0O1xuICB0aGlzLmF1dGhfdG9rZW4gPSBvcHRpb25zLmF1dGhfdG9rZW47XG4gIHRoaXMuYXV0aF90b2tlbl9zZWNyZXQgPSBvcHRpb25zLmF1dGhfdG9rZW5fc2VjcmV0O1xuICB0aGlzLmhvc3QgPSBvcHRpb25zLmhvc3Q7XG4gIHRoaXMub2F1dGhfcGFyYW1zID0gb3B0aW9ucy5vYXV0aF9wYXJhbXMgfHwge307XG59O1xuXG5PQXV0aC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhdGgsIHBhcmFtcywgYm9keSkge1xuICB2YXIgcmVxdWVzdCA9IHRoaXMuYnVpbGRSZXF1ZXN0KG1ldGhvZCwgcGF0aCwgcGFyYW1zLCBib2R5KTtcbiAgLy8gRW5jb2RlIHRoZSBib2R5IHByb3Blcmx5LCB0aGUgY3VycmVudCBQYXJzZSBJbXBsZW1lbnRhdGlvbiBkb24ndCBkbyBpdCBwcm9wZXJseVxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciBodHRwUmVxdWVzdCA9IGh0dHBzXG4gICAgICAucmVxdWVzdChyZXF1ZXN0LCBmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgIHZhciBkYXRhID0gJyc7XG4gICAgICAgIHJlcy5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgICAgICAgIGRhdGEgKz0gY2h1bms7XG4gICAgICAgIH0pO1xuICAgICAgICByZXMub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAub24oJ2Vycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICByZWplY3QoJ0ZhaWxlZCB0byBtYWtlIGFuIE9BdXRoIHJlcXVlc3QnKTtcbiAgICAgIH0pO1xuICAgIGlmIChyZXF1ZXN0LmJvZHkpIHtcbiAgICAgIGh0dHBSZXF1ZXN0LndyaXRlKHJlcXVlc3QuYm9keSk7XG4gICAgfVxuICAgIGh0dHBSZXF1ZXN0LmVuZCgpO1xuICB9KTtcbn07XG5cbk9BdXRoLnByb3RvdHlwZS5idWlsZFJlcXVlc3QgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXRoLCBwYXJhbXMsIGJvZHkpIHtcbiAgaWYgKHBhdGguaW5kZXhPZignLycpICE9IDApIHtcbiAgICBwYXRoID0gJy8nICsgcGF0aDtcbiAgfVxuICBpZiAocGFyYW1zICYmIE9iamVjdC5rZXlzKHBhcmFtcykubGVuZ3RoID4gMCkge1xuICAgIHBhdGggKz0gJz8nICsgT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcocGFyYW1zKTtcbiAgfVxuXG4gIHZhciByZXF1ZXN0ID0ge1xuICAgIGhvc3Q6IHRoaXMuaG9zdCxcbiAgICBwYXRoOiBwYXRoLFxuICAgIG1ldGhvZDogbWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gIH07XG5cbiAgdmFyIG9hdXRoX3BhcmFtcyA9IHRoaXMub2F1dGhfcGFyYW1zIHx8IHt9O1xuICBvYXV0aF9wYXJhbXMub2F1dGhfY29uc3VtZXJfa2V5ID0gdGhpcy5jb25zdW1lcl9rZXk7XG4gIGlmICh0aGlzLmF1dGhfdG9rZW4pIHtcbiAgICBvYXV0aF9wYXJhbXNbJ29hdXRoX3Rva2VuJ10gPSB0aGlzLmF1dGhfdG9rZW47XG4gIH1cblxuICByZXF1ZXN0ID0gT0F1dGguc2lnblJlcXVlc3QocmVxdWVzdCwgb2F1dGhfcGFyYW1zLCB0aGlzLmNvbnN1bWVyX3NlY3JldCwgdGhpcy5hdXRoX3Rva2VuX3NlY3JldCk7XG5cbiAgaWYgKGJvZHkgJiYgT2JqZWN0LmtleXMoYm9keSkubGVuZ3RoID4gMCkge1xuICAgIHJlcXVlc3QuYm9keSA9IE9BdXRoLmJ1aWxkUGFyYW1ldGVyU3RyaW5nKGJvZHkpO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufTtcblxuT0F1dGgucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChwYXRoLCBwYXJhbXMpIHtcbiAgcmV0dXJuIHRoaXMuc2VuZCgnR0VUJywgcGF0aCwgcGFyYW1zKTtcbn07XG5cbk9BdXRoLnByb3RvdHlwZS5wb3N0ID0gZnVuY3Rpb24gKHBhdGgsIHBhcmFtcywgYm9keSkge1xuICByZXR1cm4gdGhpcy5zZW5kKCdQT1NUJywgcGF0aCwgcGFyYW1zLCBib2R5KTtcbn07XG5cbi8qXG5cdFByb3BlciBzdHJpbmcgJWVzY2FwZSBlbmNvZGluZ1xuKi9cbk9BdXRoLmVuY29kZSA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgLy8gICAgICAgZGlzY3VzcyBhdDogaHR0cDovL3BocGpzLm9yZy9mdW5jdGlvbnMvcmF3dXJsZW5jb2RlL1xuICAvLyAgICAgIG9yaWdpbmFsIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgIGlucHV0IGJ5OiB0cmF2Y1xuICAvLyAgICAgICAgIGlucHV0IGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgIGlucHV0IGJ5OiBNaWNoYWVsIEdyaWVyXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IFJhdGhlb3VzXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEtldmluIHZhbiBab25uZXZlbGQgKGh0dHA6Ly9rZXZpbi52YW56b25uZXZlbGQubmV0KVxuICAvLyAgICAgIGJ1Z2ZpeGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgIGJ1Z2ZpeGVkIGJ5OiBKb3Jpc1xuICAvLyByZWltcGxlbWVudGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyByZWltcGxlbWVudGVkIGJ5OiBCcmV0dCBaYW1pciAoaHR0cDovL2JyZXR0LXphbWlyLm1lKVxuICAvLyAgICAgICAgICAgICBub3RlOiBUaGlzIHJlZmxlY3RzIFBIUCA1LjMvNi4wKyBiZWhhdmlvclxuICAvLyAgICAgICAgICAgICBub3RlOiBQbGVhc2UgYmUgYXdhcmUgdGhhdCB0aGlzIGZ1bmN0aW9uIGV4cGVjdHMgdG8gZW5jb2RlIGludG8gVVRGLTggZW5jb2RlZCBzdHJpbmdzLCBhcyBmb3VuZCBvblxuICAvLyAgICAgICAgICAgICBub3RlOiBwYWdlcyBzZXJ2ZWQgYXMgVVRGLThcbiAgLy8gICAgICAgIGV4YW1wbGUgMTogcmF3dXJsZW5jb2RlKCdLZXZpbiB2YW4gWm9ubmV2ZWxkIScpO1xuICAvLyAgICAgICAgcmV0dXJucyAxOiAnS2V2aW4lMjB2YW4lMjBab25uZXZlbGQlMjEnXG4gIC8vICAgICAgICBleGFtcGxlIDI6IHJhd3VybGVuY29kZSgnaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQvJyk7XG4gIC8vICAgICAgICByZXR1cm5zIDI6ICdodHRwJTNBJTJGJTJGa2V2aW4udmFuem9ubmV2ZWxkLm5ldCUyRidcbiAgLy8gICAgICAgIGV4YW1wbGUgMzogcmF3dXJsZW5jb2RlKCdodHRwOi8vd3d3Lmdvb2dsZS5ubC9zZWFyY2g/cT1waHAuanMmaWU9dXRmLTgmb2U9dXRmLTgmYXE9dCZybHM9Y29tLnVidW50dTplbi1VUzp1bm9mZmljaWFsJmNsaWVudD1maXJlZm94LWEnKTtcbiAgLy8gICAgICAgIHJldHVybnMgMzogJ2h0dHAlM0ElMkYlMkZ3d3cuZ29vZ2xlLm5sJTJGc2VhcmNoJTNGcSUzRHBocC5qcyUyNmllJTNEdXRmLTglMjZvZSUzRHV0Zi04JTI2YXElM0R0JTI2cmxzJTNEY29tLnVidW50dSUzQWVuLVVTJTNBdW5vZmZpY2lhbCUyNmNsaWVudCUzRGZpcmVmb3gtYSdcblxuICBzdHIgPSAoc3RyICsgJycpLnRvU3RyaW5nKCk7XG5cbiAgLy8gVGlsZGUgc2hvdWxkIGJlIGFsbG93ZWQgdW5lc2NhcGVkIGluIGZ1dHVyZSB2ZXJzaW9ucyBvZiBQSFAgKGFzIHJlZmxlY3RlZCBiZWxvdyksIGJ1dCBpZiB5b3Ugd2FudCB0byByZWZsZWN0IGN1cnJlbnRcbiAgLy8gUEhQIGJlaGF2aW9yLCB5b3Ugd291bGQgbmVlZCB0byBhZGQgXCIucmVwbGFjZSgvfi9nLCAnJTdFJyk7XCIgdG8gdGhlIGZvbGxvd2luZy5cbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpXG4gICAgLnJlcGxhY2UoLyEvZywgJyUyMScpXG4gICAgLnJlcGxhY2UoLycvZywgJyUyNycpXG4gICAgLnJlcGxhY2UoL1xcKC9nLCAnJTI4JylcbiAgICAucmVwbGFjZSgvXFwpL2csICclMjknKVxuICAgIC5yZXBsYWNlKC9cXCovZywgJyUyQScpO1xufTtcblxuT0F1dGguc2lnbmF0dXJlTWV0aG9kID0gJ0hNQUMtU0hBMSc7XG5PQXV0aC52ZXJzaW9uID0gJzEuMCc7XG5cbi8qXG5cdEdlbmVyYXRlIGEgbm9uY2VcbiovXG5PQXV0aC5ub25jZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRleHQgPSAnJztcbiAgdmFyIHBvc3NpYmxlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5JztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDMwOyBpKyspIHsgdGV4dCArPSBwb3NzaWJsZS5jaGFyQXQoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcG9zc2libGUubGVuZ3RoKSk7IH1cblxuICByZXR1cm4gdGV4dDtcbn07XG5cbk9BdXRoLmJ1aWxkUGFyYW1ldGVyU3RyaW5nID0gZnVuY3Rpb24gKG9iaikge1xuICAvLyBTb3J0IGtleXMgYW5kIGVuY29kZSB2YWx1ZXNcbiAgaWYgKG9iaikge1xuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKS5zb3J0KCk7XG5cbiAgICAvLyBNYXAga2V5PXZhbHVlLCBqb2luIHRoZW0gYnkgJlxuICAgIHJldHVybiBrZXlzXG4gICAgICAubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSArICc9JyArIE9BdXRoLmVuY29kZShvYmpba2V5XSk7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJyYnKTtcbiAgfVxuXG4gIHJldHVybiAnJztcbn07XG5cbi8qXG5cdEJ1aWxkIHRoZSBzaWduYXR1cmUgc3RyaW5nIGZyb20gdGhlIG9iamVjdFxuKi9cblxuT0F1dGguYnVpbGRTaWduYXR1cmVTdHJpbmcgPSBmdW5jdGlvbiAobWV0aG9kLCB1cmwsIHBhcmFtZXRlcnMpIHtcbiAgcmV0dXJuIFttZXRob2QudG9VcHBlckNhc2UoKSwgT0F1dGguZW5jb2RlKHVybCksIE9BdXRoLmVuY29kZShwYXJhbWV0ZXJzKV0uam9pbignJicpO1xufTtcblxuLypcblx0UmV0dW5zIGVuY29kZWQgSE1BQy1TSEExIGZyb20ga2V5IGFuZCB0ZXh0XG4qL1xuT0F1dGguc2lnbmF0dXJlID0gZnVuY3Rpb24gKHRleHQsIGtleSkge1xuICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbiAgcmV0dXJuIE9BdXRoLmVuY29kZShjcnlwdG8uY3JlYXRlSG1hYygnc2hhMScsIGtleSkudXBkYXRlKHRleHQpLmRpZ2VzdCgnYmFzZTY0JykpO1xufTtcblxuT0F1dGguc2lnblJlcXVlc3QgPSBmdW5jdGlvbiAocmVxdWVzdCwgb2F1dGhfcGFyYW1ldGVycywgY29uc3VtZXJfc2VjcmV0LCBhdXRoX3Rva2VuX3NlY3JldCkge1xuICBvYXV0aF9wYXJhbWV0ZXJzID0gb2F1dGhfcGFyYW1ldGVycyB8fCB7fTtcblxuICAvLyBTZXQgZGVmYXVsdCB2YWx1ZXNcbiAgaWYgKCFvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX25vbmNlKSB7XG4gICAgb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9ub25jZSA9IE9BdXRoLm5vbmNlKCk7XG4gIH1cbiAgaWYgKCFvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3RpbWVzdGFtcCkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdGltZXN0YW1wID0gTWF0aC5mbG9vcihuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApO1xuICB9XG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9zaWduYXR1cmVfbWV0aG9kKSB7XG4gICAgb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9zaWduYXR1cmVfbWV0aG9kID0gT0F1dGguc2lnbmF0dXJlTWV0aG9kO1xuICB9XG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF92ZXJzaW9uKSB7XG4gICAgb2F1dGhfcGFyYW1ldGVycy5vYXV0aF92ZXJzaW9uID0gT0F1dGgudmVyc2lvbjtcbiAgfVxuXG4gIGlmICghYXV0aF90b2tlbl9zZWNyZXQpIHtcbiAgICBhdXRoX3Rva2VuX3NlY3JldCA9ICcnO1xuICB9XG4gIC8vIEZvcmNlIEdFVCBtZXRob2QgaWYgdW5zZXRcbiAgaWYgKCFyZXF1ZXN0Lm1ldGhvZCkge1xuICAgIHJlcXVlc3QubWV0aG9kID0gJ0dFVCc7XG4gIH1cblxuICAvLyBDb2xsZWN0ICBhbGwgdGhlIHBhcmFtZXRlcnMgaW4gb25lIHNpZ25hdHVyZVBhcmFtZXRlcnMgb2JqZWN0XG4gIHZhciBzaWduYXR1cmVQYXJhbXMgPSB7fTtcbiAgdmFyIHBhcmFtZXRlcnNUb01lcmdlID0gW3JlcXVlc3QucGFyYW1zLCByZXF1ZXN0LmJvZHksIG9hdXRoX3BhcmFtZXRlcnNdO1xuICBmb3IgKHZhciBpIGluIHBhcmFtZXRlcnNUb01lcmdlKSB7XG4gICAgdmFyIHBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzVG9NZXJnZVtpXTtcbiAgICBmb3IgKHZhciBrIGluIHBhcmFtZXRlcnMpIHtcbiAgICAgIHNpZ25hdHVyZVBhcmFtc1trXSA9IHBhcmFtZXRlcnNba107XG4gICAgfVxuICB9XG5cbiAgLy8gQ3JlYXRlIGEgc3RyaW5nIGJhc2VkIG9uIHRoZSBwYXJhbWV0ZXJzXG4gIHZhciBwYXJhbWV0ZXJTdHJpbmcgPSBPQXV0aC5idWlsZFBhcmFtZXRlclN0cmluZyhzaWduYXR1cmVQYXJhbXMpO1xuXG4gIC8vIEJ1aWxkIHRoZSBzaWduYXR1cmUgc3RyaW5nXG4gIHZhciB1cmwgPSAnaHR0cHM6Ly8nICsgcmVxdWVzdC5ob3N0ICsgJycgKyByZXF1ZXN0LnBhdGg7XG5cbiAgdmFyIHNpZ25hdHVyZVN0cmluZyA9IE9BdXRoLmJ1aWxkU2lnbmF0dXJlU3RyaW5nKHJlcXVlc3QubWV0aG9kLCB1cmwsIHBhcmFtZXRlclN0cmluZyk7XG4gIC8vIEhhc2ggdGhlIHNpZ25hdHVyZSBzdHJpbmdcbiAgdmFyIHNpZ25hdHVyZUtleSA9IFtPQXV0aC5lbmNvZGUoY29uc3VtZXJfc2VjcmV0KSwgT0F1dGguZW5jb2RlKGF1dGhfdG9rZW5fc2VjcmV0KV0uam9pbignJicpO1xuXG4gIHZhciBzaWduYXR1cmUgPSBPQXV0aC5zaWduYXR1cmUoc2lnbmF0dXJlU3RyaW5nLCBzaWduYXR1cmVLZXkpO1xuXG4gIC8vIFNldCB0aGUgc2lnbmF0dXJlIGluIHRoZSBwYXJhbXNcbiAgb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9zaWduYXR1cmUgPSBzaWduYXR1cmU7XG4gIGlmICghcmVxdWVzdC5oZWFkZXJzKSB7XG4gICAgcmVxdWVzdC5oZWFkZXJzID0ge307XG4gIH1cblxuICAvLyBTZXQgdGhlIGF1dGhvcml6YXRpb24gaGVhZGVyXG4gIHZhciBhdXRoSGVhZGVyID0gT2JqZWN0LmtleXMob2F1dGhfcGFyYW1ldGVycylcbiAgICAuc29ydCgpXG4gICAgLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICB2YXIgdmFsdWUgPSBvYXV0aF9wYXJhbWV0ZXJzW2tleV07XG4gICAgICByZXR1cm4ga2V5ICsgJz1cIicgKyB2YWx1ZSArICdcIic7XG4gICAgfSlcbiAgICAuam9pbignLCAnKTtcblxuICByZXF1ZXN0LmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdPQXV0aCAnICsgYXV0aEhlYWRlcjtcblxuICAvLyBTZXQgdGhlIGNvbnRlbnQgdHlwZSBoZWFkZXJcbiAgcmVxdWVzdC5oZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnO1xuICByZXR1cm4gcmVxdWVzdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT0F1dGg7XG4iXSwibWFwcGluZ3MiOiI7O0FBQUEsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsT0FBTyxDQUFDO0VBQzFCQyxNQUFNLEdBQUdELE9BQU8sQ0FBQyxRQUFRLENBQUM7QUFDNUIsSUFBSUUsS0FBSyxHQUFHRixPQUFPLENBQUMsWUFBWSxDQUFDLENBQUNFLEtBQUs7QUFFdkMsSUFBSUMsS0FBSyxHQUFHLFNBQUFBLENBQVVDLE9BQU8sRUFBRTtFQUM3QixJQUFJLENBQUNBLE9BQU8sRUFBRTtJQUNaLE1BQU0sSUFBSUYsS0FBSyxDQUFDRyxLQUFLLENBQUNILEtBQUssQ0FBQ0csS0FBSyxDQUFDQyxxQkFBcUIsRUFBRSw0QkFBNEIsQ0FBQztFQUN4RjtFQUNBLElBQUksQ0FBQ0MsWUFBWSxHQUFHSCxPQUFPLENBQUNHLFlBQVk7RUFDeEMsSUFBSSxDQUFDQyxl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
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Parse Server authentication adapter for Apple.
5
+ *
6
+ * @class AppleAdapter
7
+ * @param {Object} options - Configuration options for the adapter.
8
+ * @param {string} options.clientId - Your Apple App ID.
9
+ *
10
+ * @param {Object} authData - The authentication data provided by the client.
11
+ * @param {string} authData.id - The user ID obtained from Apple.
12
+ * @param {string} authData.token - The token obtained from Apple.
13
+ *
14
+ * @description
15
+ * ## Parse Server Configuration
16
+ * To configure Parse Server for Apple authentication, use the following structure:
17
+ * ```json
18
+ * {
19
+ * "auth": {
20
+ * "apple": {
21
+ * "clientId": "12345"
22
+ * }
23
+ * }
24
+ * }
25
+ * ```
26
+ *
27
+ * ## Expected `authData` from the Client
28
+ * The adapter expects the client to provide the following `authData` payload:
29
+ * - `authData.id` (**string**, required): The user ID obtained from Apple.
30
+ * - `authData.token` (**string**, required): The token obtained from Apple.
31
+ *
32
+ * Parse Server stores the required authentication data in the database.
33
+ *
34
+ * ### Example AuthData from Apple
35
+ * ```json
36
+ * {
37
+ * "apple": {
38
+ * "id": "1234567",
39
+ * "token": "xxxxx.yyyyy.zzzzz"
40
+ * }
41
+ * }
42
+ * ```
43
+ *
44
+ * @see {@link https://developer.apple.com/documentation/signinwithapplerestapi Sign in with Apple REST API Documentation}
45
+ */
46
+
47
+ // Apple SignIn Auth
48
+ // https://developer.apple.com/documentation/signinwithapplerestapi
49
+
50
+ const Parse = require('parse/node').Parse;
51
+ const jwksClient = require('jwks-rsa');
52
+ const jwt = require('jsonwebtoken');
53
+ const authUtils = require('./utils');
54
+ const TOKEN_ISSUER = 'https://appleid.apple.com';
55
+ const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => {
56
+ const client = jwksClient({
57
+ jwksUri: `${TOKEN_ISSUER}/auth/keys`,
58
+ cache: true,
59
+ cacheMaxEntries,
60
+ cacheMaxAge
61
+ });
62
+ let key;
63
+ try {
64
+ key = await authUtils.getSigningKey(client, keyId);
65
+ } catch {
66
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unable to find matching key for Key ID: ${keyId}`);
67
+ }
68
+ return key;
69
+ };
70
+ const verifyIdToken = async ({
71
+ token,
72
+ id
73
+ }, {
74
+ clientId,
75
+ cacheMaxEntries,
76
+ cacheMaxAge
77
+ }) => {
78
+ if (!token) {
79
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`);
80
+ }
81
+ const {
82
+ kid: keyId,
83
+ alg: algorithm
84
+ } = authUtils.getHeaderFromToken(token);
85
+ const ONE_HOUR_IN_MS = 3600000;
86
+ let jwtClaims;
87
+ cacheMaxAge = cacheMaxAge || ONE_HOUR_IN_MS;
88
+ cacheMaxEntries = cacheMaxEntries || 5;
89
+ const appleKey = await getAppleKeyByKeyId(keyId, cacheMaxEntries, cacheMaxAge);
90
+ const signingKey = appleKey.publicKey || appleKey.rsaPublicKey;
91
+ try {
92
+ jwtClaims = jwt.verify(token, signingKey, {
93
+ algorithms: algorithm,
94
+ // the audience can be checked against a string, a regular expression or a list of strings and/or regular expressions.
95
+ audience: clientId
96
+ });
97
+ } catch (exception) {
98
+ const message = exception.message;
99
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`);
100
+ }
101
+ if (jwtClaims.iss !== TOKEN_ISSUER) {
102
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct OpenID provider - expected: ${TOKEN_ISSUER} | from: ${jwtClaims.iss}`);
103
+ }
104
+ if (jwtClaims.sub !== id) {
105
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`);
106
+ }
107
+ return jwtClaims;
108
+ };
109
+
110
+ // Returns a promise that fulfills if this id token is valid
111
+ function validateAuthData(authData, options = {}) {
112
+ return verifyIdToken(authData, options);
113
+ }
114
+
115
+ // Returns a promise that fulfills if this app id is valid.
116
+ function validateAppId() {
117
+ return Promise.resolve();
118
+ }
119
+ module.exports = {
120
+ validateAppId,
121
+ validateAuthData
122
+ };
123
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJqd2tzQ2xpZW50Iiwiand0IiwiYXV0aFV0aWxzIiwiVE9LRU5fSVNTVUVSIiwiZ2V0QXBwbGVLZXlCeUtleUlkIiwia2V5SWQiLCJjYWNoZU1heEVudHJpZXMiLCJjYWNoZU1heEFnZSIsImNsaWVudCIsImp3a3NVcmkiLCJjYWNoZSIsImtleSIsImdldFNpZ25pbmdLZXkiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2ZXJpZnlJZFRva2VuIiwidG9rZW4iLCJpZCIsImNsaWVudElkIiwia2lkIiwiYWxnIiwiYWxnb3JpdGhtIiwiZ2V0SGVhZGVyRnJvbVRva2VuIiwiT05FX0hPVVJfSU5fTVMiLCJqd3RDbGFpbXMiLCJhcHBsZUtleSIsInNpZ25pbmdLZXkiLCJwdWJsaWNLZXkiLCJyc2FQdWJsaWNLZXkiLCJ2ZXJpZnkiLCJhbGdvcml0aG1zIiwiYXVkaWVuY2UiLCJleGNlcHRpb24iLCJtZXNzYWdlIiwiaXNzIiwic3ViIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvQWRhcHRlcnMvQXV0aC9hcHBsZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBhcnNlIFNlcnZlciBhdXRoZW50aWNhdGlvbiBhZGFwdGVyIGZvciBBcHBsZS5cbiAqXG4gKiBAY2xhc3MgQXBwbGVBZGFwdGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIGFkYXB0ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5jbGllbnRJZCAtIFlvdXIgQXBwbGUgQXBwIElELlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBhdXRoRGF0YSAtIFRoZSBhdXRoZW50aWNhdGlvbiBkYXRhIHByb3ZpZGVkIGJ5IHRoZSBjbGllbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gYXV0aERhdGEuaWQgLSBUaGUgdXNlciBJRCBvYnRhaW5lZCBmcm9tIEFwcGxlLlxuICogQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLnRva2VuIC0gVGhlIHRva2VuIG9idGFpbmVkIGZyb20gQXBwbGUuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiAjIyBQYXJzZSBTZXJ2ZXIgQ29uZmlndXJhdGlvblxuICogVG8gY29uZmlndXJlIFBhcnNlIFNlcnZlciBmb3IgQXBwbGUgYXV0aGVudGljYXRpb24sIHVzZSB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAqIGBgYGpzb25cbiAqIHtcbiAqICAgXCJhdXRoXCI6IHtcbiAqICAgICBcImFwcGxlXCI6IHtcbiAqICAgICAgIFwiY2xpZW50SWRcIjogXCIxMjM0NVwiXG4gKiAgICAgfVxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyBFeHBlY3RlZCBgYXV0aERhdGFgIGZyb20gdGhlIENsaWVudFxuICogVGhlIGFkYXB0ZXIgZXhwZWN0cyB0aGUgY2xpZW50IHRvIHByb3ZpZGUgdGhlIGZvbGxvd2luZyBgYXV0aERhdGFgIHBheWxvYWQ6XG4gKiAtIGBhdXRoRGF0YS5pZGAgKCoqc3RyaW5nKiosIHJlcXVpcmVkKTogVGhlIHVzZXIgSUQgb2J0YWluZWQgZnJvbSBBcHBsZS5cbiAqIC0gYGF1dGhEYXRhLnRva2VuYCAoKipzdHJpbmcqKiwgcmVxdWlyZWQpOiBUaGUgdG9rZW4gb2J0YWluZWQgZnJvbSBBcHBsZS5cbiAqXG4gKiBQYXJzZSBTZXJ2ZXIgc3RvcmVzIHRoZSByZXF1aXJlZCBhdXRoZW50aWNhdGlvbiBkYXRhIGluIHRoZSBkYXRhYmFzZS5cbiAqXG4gKiAjIyMgRXhhbXBsZSBBdXRoRGF0YSBmcm9tIEFwcGxlXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwiYXBwbGVcIjoge1xuICogICAgIFwiaWRcIjogXCIxMjM0NTY3XCIsXG4gKiAgICAgXCJ0b2tlblwiOiBcInh4eHh4Lnl5eXl5Lnp6enp6XCJcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIuYXBwbGUuY29tL2RvY3VtZW50YXRpb24vc2lnbmlud2l0aGFwcGxlcmVzdGFwaSBTaWduIGluIHdpdGggQXBwbGUgUkVTVCBBUEkgRG9jdW1lbnRhdGlvbn1cbiAqL1xuXG4vLyBBcHBsZSBTaWduSW4gQXV0aFxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIuYXBwbGUuY29tL2RvY3VtZW50YXRpb24vc2lnbmlud2l0aGFwcGxlcmVzdGFwaVxuXG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGp3a3NDbGllbnQgPSByZXF1aXJlKCdqd2tzLXJzYScpO1xuY29uc3Qgand0ID0gcmVxdWlyZSgnanNvbndlYnRva2VuJyk7XG5jb25zdCBhdXRoVXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cbmNvbnN0IFRPS0VOX0lTU1VFUiA9ICdodHRwczovL2FwcGxlaWQuYXBwbGUuY29tJztcblxuY29uc3QgZ2V0QXBwbGVLZXlCeUtleUlkID0gYXN5bmMgKGtleUlkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlKSA9PiB7XG4gIGNvbnN0IGNsaWVudCA9IGp3a3NDbGllbnQoe1xuICAgIGp3a3NVcmk6IGAke1RPS0VOX0lTU1VFUn0vYXV0aC9rZXlzYCxcbiAgICBjYWNoZTogdHJ1ZSxcbiAgICBjYWNoZU1heEVudHJpZXMsXG4gICAgY2FjaGVNYXhBZ2UsXG4gIH0pO1xuXG4gIGxldCBrZXk7XG4gIHRyeSB7XG4gICAga2V5ID0gYXdhaXQgYXV0aFV0aWxzLmdldFNpZ25pbmdLZXkoY2xpZW50LCBrZXlJZCk7XG4gIH0gY2F0Y2gge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgVW5hYmxlIHRvIGZpbmQgbWF0Y2hpbmcga2V5IGZvciBLZXkgSUQ6ICR7a2V5SWR9YFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGtleTtcbn07XG5cbmNvbnN0IHZlcmlmeUlkVG9rZW4gPSBhc3luYyAoeyB0b2tlbiwgaWQgfSwgeyBjbGllbnRJZCwgY2FjaGVNYXhFbnRyaWVzLCBjYWNoZU1heEFnZSB9KSA9PiB7XG4gIGlmICghdG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYGlkIHRva2VuIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci5gKTtcbiAgfVxuXG4gIGNvbnN0IHsga2lkOiBrZXlJZCwgYWxnOiBhbGdvcml0aG0gfSA9IGF1dGhVdGlscy5nZXRIZWFkZXJGcm9tVG9rZW4odG9rZW4pO1xuICBjb25zdCBPTkVfSE9VUl9JTl9NUyA9IDM2MDAwMDA7XG4gIGxldCBqd3RDbGFpbXM7XG5cbiAgY2FjaGVNYXhBZ2UgPSBjYWNoZU1heEFnZSB8fCBPTkVfSE9VUl9JTl9NUztcbiAgY2FjaGVNYXhFbnRyaWVzID0gY2FjaGVNYXhFbnRyaWVzIHx8IDU7XG5cbiAgY29uc3QgYXBwbGVLZXkgPSBhd2FpdCBnZXRBcHBsZUtleUJ5S2V5SWQoa2V5SWQsIGNhY2hlTWF4RW50cmllcywgY2FjaGVNYXhBZ2UpO1xuICBjb25zdCBzaWduaW5nS2V5ID0gYXBwbGVLZXkucHVibGljS2V5IHx8IGFwcGxlS2V5LnJzYVB1YmxpY0tleTtcblxuICB0cnkge1xuICAgIGp3dENsYWltcyA9IGp3dC52ZXJpZnkodG9rZW4sIHNpZ25pbmdLZXksIHtcbiAgICAgIGFsZ29yaXRobXM6IGFsZ29yaXRobSxcbiAgICAgIC8vIHRoZSBhdWRpZW5jZSBjYW4gYmUgY2hlY2tlZCBhZ2FpbnN0IGEgc3RyaW5nLCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBvciBhIGxpc3Qgb2Ygc3RyaW5ncyBhbmQvb3IgcmVndWxhciBleHByZXNzaW9ucy5cbiAgICAgIGF1ZGllbmNlOiBjbGllbnRJZCxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGV4Y2VwdGlvbi5tZXNzYWdlO1xuXG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIGAke21lc3NhZ2V9YCk7XG4gIH1cblxuICBpZiAoand0Q2xhaW1zLmlzcyAhPT0gVE9LRU5fSVNTVUVSKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBpZCB0b2tlbiBub3QgaXNzdWVkIGJ5IGNvcnJlY3QgT3BlbklEIHByb3ZpZGVyIC0gZXhwZWN0ZWQ6ICR7VE9LRU5fSVNTVUVSfSB8IGZyb206ICR7and0Q2xhaW1zLmlzc31gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChqd3RDbGFpbXMuc3ViICE9PSBpZCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgYXV0aCBkYXRhIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci5gKTtcbiAgfVxuICByZXR1cm4gand0Q2xhaW1zO1xufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGlkIHRva2VuIGlzIHZhbGlkXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zID0ge30pIHtcbiAgcmV0dXJuIHZlcmlmeUlkVG9rZW4oYXV0aERhdGEsIG9wdGlvbnMpO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXSwibWFwcGluZ3MiOiI7O0FB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